[
  {
    "path": ".gitignore",
    "content": "# Created by .ignore support plugin (hsz.mobi)\n### Python template\n\n*.env\n*.pyc\n#*.log\n.idea/\n*.DS_Store\n\napp_frontend/static/uploads/*\n!app_frontend/static/uploads/index.html\n\n# 数据\ndocker/mariadb/backup/*\n\n# 日志\napp_wechat/\ndb/backup/\ndocker/mariadb/backup/\ndocker/mariadb/data/\ndocker/mongodb/data/\ndocker/nginx/log/\ndocker/rabbitmq/data/\ndocker/redis/data/\nlogs/\n"
  },
  {
    "path": "README.md",
    "content": "## Flask 项目模拟\n\n\n- product 生产环境\n- develop 开发环境\n\n### 项目演示步骤\n\n虚拟环境 部署方式\n```\n$ cd flask_project                  # 进入项目目录\n$ virtualenv flask.env              # 新建虚拟环境\n$ source flask.env/bin/activate     # 进入虚拟环境\n$ pip install -r requirements.txt   # 安装环境依赖\n$ python run_frontend.py            # 开启前台服务\n$ python run_backend.py             # 开启后台服务\n```\n\n也可以 docker 方式部署\n```\n$ cd flask_project/docker           # 进入Docker脚本目录\n$ sh docker/docker_build.sh         # 创建本地Docker镜像\n$ sh docker/docker_run.sh           # 运行本地Docker容器\n```\n\n\n### 安装 flask 以及扩展\n\n创建并进入虚拟环境\n```\n$ virtualenv flask.env\n$ source flask.env/bin/activate\n```\n\n项目服务依赖\n```\nNginx\nRedis\nMariaDB\nRabbitMQ\nMongoDB\n```\n\n\n项目扩展依赖\n```\n$ pip install Flask\n$ pip install Flask-Login\n$ pip install Flask-Mail\n$ pip install Flask-SQLAlchemy\n$ pip install Flask-WTF\n$ pip install Flask-OAuthlib\n$ pip install Flask-Excel\n$ pip install Flask-Moment\n$ pip install Flask-Uploads\n$ pip install Flask-Principal\n$ pip install Flask-Babel\n$ pip install sqlacodegen\n$ pip install gunicorn\n$ pip install schedule\n$ pip install supervisor\n$ pip install redis\n$ pip install requests\n$ pip install celery\n$ pip install librabbitmq\n$ pip install pika\n$ pip install Pillow\n$ pip install sshtunnel\n$ pip install MySQL-python\n$ pip freeze > requirements.txt\n```\n\n服务部署安装方式\n```\n$ pip install -r requirements.txt\n```\n\n\n### 创建目录结构\n\n```\n$ mkdir app\n$ mkdir app/static\n$ mkdir app/templates\n$ mkdir tmp\n```\n\n在 Pycharm 中设置 templates 目录\n```\napp/templates 目录右键 >> Mark Directory As >> Template Folder\nFile >> Settings >> Languages & Frameworks >> Python Template Languages >> Template Language: jinja2\n```\n\n\n### 引入 Bootstrap\n\nBootstrap 是最受欢迎的 HTML、CSS 和 JS 框架，用于开发响应式布局、移动设备优先的 WEB 项目。\n\n项目地址：https://github.com/twbs/bootstrap\n\nBootstrap 英文官网：http://getbootstrap.com/\n\nBootstrap 中文网：http://www.bootcss.com/\n\nBootstrap CDN\n```\n<!-- Latest compiled and minified CSS -->\n<link rel=\"stylesheet\" href=\"https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css\" integrity=\"sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u\" crossorigin=\"anonymous\">\n\n<!-- Optional theme -->\n<link rel=\"stylesheet\" href=\"https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap-theme.min.css\" integrity=\"sha384-rHyoN1iRsVXV4nD0JutlnGaslCJuC7uwjduW9SVrLvRYooPp2bWYgmgJQIXwl/Sp\" crossorigin=\"anonymous\">\n\n<!-- Latest compiled and minified JavaScript -->\n<script src=\"https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js\" integrity=\"sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa\" crossorigin=\"anonymous\"></script>\n```\n\n### 启动 web 服务\n```\n$ chmod a+x run.py\n$ ./run.py\n# 可以 Ctrl-C 来终止服务\n```\n\n浏览器访问：\n\n[http://localhost:5000](http://localhost:5000)\n\n[http://localhost:5000/index](http://localhost:5000/index)\n\n\n\n### 如何生成强壮的密钥\n```\nIn [1]: import os\nIn [2]: os.urandom(24)\nOut[2]: '\\x03\\xabjR\\xbbg\\x82\\x0b{\\x96f\\xca\\xa8\\xbdM\\xb0x\\xdbK%\\xf2\\x07\\r\\x8c'\n```\n\n\n### 创建数据库\n\n模拟数据\n```\nINSERT INTO author(name, email) VALUES('Mark', 'mark@gmail.com');\nINSERT INTO author(name, email) VALUES('Jacob', 'jacob@gmail.com');\nINSERT INTO author(name, email) VALUES('Larry', 'larry@gmail.com');\nINSERT INTO author(name, email) VALUES('Tom', 'tom@gmail.com');\nINSERT INTO author(name, email) VALUES('Lily', 'lily@gmail.com');\n```\n```\nINSERT INTO blog(author, title, pub_date) VALUES('Mark', 'The old man and the sea', '2016-01-11 11:01:05');\nINSERT INTO blog(author, title, pub_date) VALUES('Jacob', 'The fault in our stars', '2016-01-11 20:23:27');\nINSERT INTO blog(author, title, pub_date) VALUES('Larry', 'The Great Gatsby', '2016-01-11 23:15:18');\nINSERT INTO blog(author, title, pub_date) VALUES('Tom', 'Sense and Sensibility', '2016-01-12 12:25:34');\nINSERT INTO blog(author, title, pub_date) VALUES('Tom', 'Pride and Prejudice', '2016-01-12 13:17:25');\nINSERT INTO blog(author, title, pub_date) VALUES('Lily', 'Game of Thrones', '2016-01-12 14:53:01');\nINSERT INTO blog(author, title, pub_date) VALUES('Mark', 'Charlie and the Chocolate Factory', '2016-01-12 15:13:17');\nINSERT INTO blog(author, title, pub_date) VALUES('Larry', 'Harry Potter and the Sorcerer''s Stone', '2016-01-12 19:32:15');\nINSERT INTO blog(author, title, pub_date) VALUES('Larry', 'The house on mango street', '2016-01-12 01:43:42');\nINSERT INTO blog(author, title, pub_date) VALUES('Jacob', 'And then there were none', '2016-01-13 16:17:32');\n```\n\n注意：插入内容中如果存在半角单引号（'），需要替换为2个单引号（''）\n前提是插入内容在两个单引号之间，存入数据库会自动转义为1个单引号\n\n\n生成建表语句（备份）\n```\n$ sqlite3 flask.db \".dump\" > schema.sql\n```\n\n\n创建数据库（恢复）:\n```\n$ sqlite3 flask.db < schema.sql\n```\n\netc 目录下已经创建好脚本（初始化数据，备份数据）\n```\n$ chmod a+x db_init.sh\n$ chmod a+x db_dump.sh\n$ ./db_init.sh\n```\n\n\n### SQLAlchemy\n\npython 的一种 ORM 框架\n\nORM：Object-Relational Mapping\n\n把关系数据库的表结构映射到对象上\n\n使用 Flask-SQLAlchemy 进行数据库管理\n```\nDatabase engine     URL\n---------------     ---\nMySQL               mysql://username:password@hostname/database\nPostgres            postgresql://username:password@hostname/database\nSQLite (Unix)       sqlite:////absolute/path/to/database\nSQLite (Windows)    sqlite:///c:/absolute/path/to/database\n```\n\n最常用的 SQLAlchemy 列类型如下：\n```\nType name       Python Type         Python type Description\n---------       -------             -----------------------\nInteger         int                 Integerint Regular integer, typically 32 bits\nSmallInteger    int                 Short-range integer, typically 16 bits\nBigInteger      int or long         Unlimited precision integer\nFloat           float               Floating-point number\nNumeric         decimal.Decimal     Fixed-point number\nString          str                 Variable-length string\nText            str                 Variable-length string, optimized for large or unbound length\nUnicode         unicode             Variable-length Unicode string\nUnicodeText     unicode             Variable-length Unicode string, optimized for large or unbound length\nBoolean         bool                Boolean value\nDate            datetime.date       Date value\nTime            datetime.time       Time value\nDateTime        datetime.datetime   Date and time value\nInterval        datetime.timedelta  Time interval\nEnum            str                 List of string values\nPickleType      Any Python object   Automatic Pickle serialization\nLargeBinary     str                 Binary blob\n```\n模型可以（没有强制要求）定义 __repr()__ 方法，返回一个具有可读性的字符串表示模型，可在调试和测试时使用。\n\n最常见的 SQLAlchemy 选项：\n```\nOption name     Description\n-----------     -----------\nprimary_key     If set to True , the column is the table’s primary key.\nunique          If set to True , do not allow duplicate values for this column.\nindex           If set to True , create an index for this column, so that queries are more efficient.\nnullable        If set to True , allow empty values for this column. If set to False , the column will not allow null values.\ndefault         Define a default value for the column.\n```\n\n官方文档:\n[SQLAlchemy 1.0 Documentation](http://docs.sqlalchemy.org/en/rel_1_0/orm/tutorial.html)\n\n[常见的过滤器运算符 Common Filter Operators](http://docs.sqlalchemy.org/en/rel_1_0/orm/tutorial.html#common-filter-operators)\n\n[动态获取 Model 对象的主键](http://docs.sqlalchemy.org/en/latest/orm/internals.html#sqlalchemy.orm.state.InstanceState.identity)\n\n\n打开自动提交\n```\nfrom flask.ext.sqlalchemy import SQLAlchemy\ndb = SQLAlchemy(session_options={'autocommit': True})\n后者:\nSQLALCHEMY_COMMIT_ON_TEARDOWN = True  # 打开自动提交\n```\n\n联表(内联)分页查询\n```\npaginate = User.query.join(UserProfile, User.id == UserProfile.user_id).add_entity(UserProfile).order_by(User.id.desc()).paginate(1, 10, False)\n\nprint paginate.items\n    for (user, user_profile) in paginate.items:\n        print user.id, user_profile.user_id\n```\n如果需要外联，join 替换为 outerjoin 即可\n\n\n### sqlacodegen\n\n安装\n```\n$ pip install sqlacodegen\n```\n\n生成 model\n```\n$ sqlacodegen sqlite:///flask.db --outfile app/models.py\n```\n\n参考例子：\n```\n$ sqlacodegen postgresql:///some_local_db\n$ sqlacodegen mysql+oursql://user:password@localhost/db_name\n$ sqlacodegen sqlite:///database.db\n$ sqlacodegen mysql://root:root@127.0.0.1:3306/db_name > models.py\n$ sqlacodegen mysql://root:root@127.0.0.1:3306/db_name --outfile models.py\n```\n\n修改 models 文件：\n\n    from sqlalchemy.ext.declarative import declarative_base\n    \n    \n    Base = declarative_base()\n\n替换为：\n\n    from flask.ext.sqlalchemy import SQLAlchemy\n    from app import app\n    db = SQLAlchemy(app)\n    Base = db.Model\n\n\n[http://docs.sqlalchemy.org/en/latest/core/engines.html](http://docs.sqlalchemy.org/en/latest/core/engines.html)\n\n注意：\n\n添加选项 --noinflect 否则工具默认会将表名后缀s去掉\n\n\n### 存入数据库中文乱码\n\nSQLALCHEMY_DATABASE_URI = 'mysql://[用户]:[密码]@[IP]/[库名]?charset=utf8'\n\n注意是 utf8 ，不是 utf-8\n> show variables like 'character%';\nmysql 里的 charset 是 utf8\n\n\n### 关于分页\n\n错误写法：\n```\nrows = db_session.query(Author).filter_by(**kwargs).paginate(page, per_page, False)\n```\n\n报错如下：\n```\nAttributeError: 'Query' object has no attribute 'paginate'\n```\n\n失败原因：\n```\n\"Query\" refers to the SQLAlchemy Query object. \n\"BaseQuery\" refers to the Flask-SQLALchemy BaseQuery object, which is a subclass of Query. \nThis subclass includes helpers such as first_or_404() and paginate().\nHowever, this means that a Query object does NOT have the paginate() function.\nHow you actually build the object you are calling your \"Query\" object depends on whether you are dealing with a Query or BaseQuery object.\n```\n\n参考：[http://stackoverflow.com/questions/18468887/flask-sqlalchemy-pagination-error](http://stackoverflow.com/questions/18468887/flask-sqlalchemy-pagination-error)\n\n正确写法：\n```\nrows = Author.query.filter_by(**kwargs).paginate(page, per_page, False)\n```\n\n模板中遍历 item，单页 item 序号用 loop.index 表示\n\n\n### 表单\n\nWTForms 标准 HTML 表单域\n```\n表单域类型               描述\n---------               ----\nStringField             文本框\nTextAreaField           多行文本框\nPasswordField           密码输入框\nHiddenField             隐藏文本框\nDateField               接收给定格式datetime.date型的文本框\nDateTimeField           接收给定格式datetime.datetime型的文本框\nIntegerField            接收整型的文本框\nDecimalField            接收decimal.Decimal型的文本框\nFloadField              接收浮点型的文本框\nBooleanField            带有True和False的复选框\nRadioField              一组单选框\nSelectField             下拉选择框\nSelectMultipleField     下拉多选框\nFieldField              文件上传框\nSubmitField             表单提交按钮\nFormField               将一个表单作为表单域嵌入到容器表单中\nFieldList               给定类型的表单域列表\n```\n\nWTForms 验证\n```\n验证程序         描述\n-------         ----\nEmail           验证邮箱地址\nEqualTo         比较两个域的值；在要求输入两次密码进行确认的时候非常有用\nIPAddress       验证IPv4网络地址\nLength          验证输入字符串的长度\nNumberRange     验证输入的值在数值范围内\nOptional        允许输入为空；忽略额外的验证\nRequired        验证表单域包含数据\nRegexp          验证输入的正则表达式\nURL             验证一个URL\nAnyOf           验证输入是一组可能值中的一个\nNoneOf          验证输入不是一组可能值中的一个\n```\n\n自定义表单验证\n\n参考官方文档：[http://wtforms.readthedocs.org/en/latest/validators.html#custom-validators](http://wtforms.readthedocs.org/en/latest/validators.html#custom-validators)\n\n注意事项：\nNumberRange 校验只对数值类型（IntegerField，FloadField，DecimalField）生效；字符串类型（StringField）不生效\n\nDataRequired, InputRequired 的区别\n\n- DataRequired 检查类型转换后的值，是否为真（即 if field.data）\n- InputRequired 检查原始输入的值，是否为真\n\n\n### CSRF\n跨站请求伪造\n\n攻击方式：\n    利用用户身份执行非法请求（在用户浏览器端发起特定请求）\n防御策略：\n    通常使用csrf_token防御\n\nhttp://flask-wtf.readthedocs.io/en/stable/csrf.html\n\nAny view using FlaskForm to process the request is already getting CSRF protection. \n也就是使用FlaskForm的表单默认都会受到保护\n\nHTML Forms\n```html\n<form method=\"post\">\n    {{ form.csrf_token }}\n</form>\n```\n\n```html\n<form method=\"post\">\n    <input type=\"hidden\" name=\"csrf_token\" value=\"{{ csrf_token() }}\"/>\n</form>\n```\n\nJavaScript Requests\n```html\n<script type=\"text/javascript\">\n    var csrf_token = \"{{ csrf_token() }}\";\n\n    $.ajaxSetup({\n        beforeSend: function(xhr, settings) {\n            if (!/^(GET|HEAD|OPTIONS|TRACE)$/i.test(settings.type) && !this.crossDomain) {\n                xhr.setRequestHeader(\"X-CSRFToken\", csrf_token);\n            }\n        }\n    });\n</script>\n```\n\n### Message Flashing\n\n闪现消息 定义4种类型 success info warning danger\n\n参考：[http://flask.pocoo.org/docs/0.10/patterns/flashing/#flashing-with-categories](http://flask.pocoo.org/docs/0.10/patterns/flashing/#flashing-with-categories)\n\n\n如果需要自动关闭\n```\n$(\"#success-alert\").fadeTo(2000, 500).slideUp(500, function(){\n    $(\"#success-alert\").slideUp(500);\n});\n```\n\n### 关于时间\n\npython 中：\ntimestamp=datetime.datetime.utcnow()\n\nsql 模式下：\nCURRENT_TIMESTAMP\n\n均为 UTC 时间（非系统本地时间）\n\n把时间设置为 UTC 时区，所有的存储在数据库里的时间将是 UTC 格式，用户可能在世界各地写微博，因此我们需要使用统一的时间单位。\n\n另外，sqlite 并不支持像 mysql 有这种 DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP 触发器的简单语法。\n其实更新时间完全可以在程序中控制。\n\n若缺省值是 CURRENT_TIME、CURRENT_DATE 或 CURRENT_TIMESTAMP，则当前 UTC 日期和/或时间被插入字段。\n\nCURRENT_TIME 的格式为 “HH:MM:SS”\n\nCURRENT_DATE 为 “YYYY-MM-DD”\n\n而 CURRENT_TIMESTAMP 是 “YYYY-MM-DD HH:MM:SS”\n\n注意：\n数据库表中的创建时间字段一般会设置缺省当前时间。\n保存数据时，如果程序中，创建时间为空，创建时间字段存储的是数据库服务器的当前时间；\n如果程序中直接设置好创建时间为当前时间，则保存的创建时间字段是代码服务器的当前时间。\n生产环境通常 web 与 db 是分开的，时钟往往不同步。\n不同开发人员程序中如果不统一的话，会造成麻烦。\n\nFlask-Moment 本地化日期和时间\n\nhttps://github.com/miguelgrinberg/Flask-Moment\n\n[http://momentjs.com/](http://momentjs.com/)\n\n例子\n```\n{{ moment().fromNow(refresh=True).format('LLLL') }}\n```\n\n页面配置\n\n本地加载：\n```\n<script src=\"{{ url_for('static', filename='plugin/moment-2.18.1/min/moment-with-locales.min.js') }}\"></script>\n<script>\n    moment.locale(\"zh-cn\");\n    function flask_moment_render(elem) {\n        $(elem).text(eval('moment(\"' + $(elem).data('timestamp') + '\").' + $(elem).data('format') + ';'));\n        $(elem).removeClass('flask-moment').show();\n    }\n    function flask_moment_render_all() {\n        $('.flask-moment').each(function () {\n            flask_moment_render(this);\n            if ($(this).data('refresh')) {\n                (function (elem, interval) {\n                    setInterval(function () {\n                        flask_moment_render(elem)\n                    }, interval);\n                })(this, $(this).data('refresh'));\n            }\n        })\n    }\n    $(document).ready(function () {\n        flask_moment_render_all();\n    });\n</script>\n```\n\ncdn方案：\n```\n{{ moment.include_moment() }}\n{{ moment.locale('zh-cn') }}\n```\n\n\n### 用户登陆\n\nFlask-Login 扩展需要在我们 model 的 User 类里实现一些方法。：\n\n    def is_authenticated(self):\n            return True\n    \n    def is_active(self):\n        return True\n    \n    def is_anonymous(self):\n        return False\n    \n    def get_id(self):\n        try:\n            return unicode(self.id)  # python 2\n        except NameError:\n            return str(self.id)  # python 3\n\n\n[https://flask-login.readthedocs.io/en/latest/](https://flask-login.readthedocs.io/en/latest/)\n\n\n### 用 jQuery 实现 Ajax\n\n[http://www.pythondoc.com/flask/patterns/jquery.html](http://www.pythondoc.com/flask/patterns/jquery.html)\n\n\n### Bootstrap 轮播（Carousel）插件\n\n[http://www.runoob.com/bootstrap/bootstrap-carousel-plugin.html](http://www.runoob.com/bootstrap/bootstrap-carousel-plugin.html)\n\n\n### 轮播大图样式\n\n- 选择 宽度1920 高度610 的高画质图片\n- 主要图像内容信息集中在中间1024的区域\n\n\n### Swiper 移动端触摸滑动插件\n\n[http://www.swiper.com.cn/](http://www.swiper.com.cn/)\n\n\n### Slideout.js 侧滑插件\n\n[https://github.com/mango/slideout](https://github.com/mango/slideout)\n\n\n### LightBox 插件\n\n参考: [LightBox.md](doc/LightBox.md)\n\n\n### Chart.js 图表插件\n\n[http://www.bootcss.com/p/chart.js/docs/](http://www.bootcss.com/p/chart.js/docs/)\n\n响应式辅助参数：\nresponsive: true\n\n\n## clipboard.js 剪贴板插件\n\nhttps://github.com/zenorocha/clipboard.js/\n\n\n## Flask-Excel\n\nhttp://flask-excel.readthedocs.io/en/latest/\n\n支持 csv tsv 导出\n如果需要导出 xls 格式，需要安装 pyexcel-xls\n\n\n## Flask-Uploads\n\nhttps://pythonhosted.org/Flask-Uploads/\n\n\n## Flask-Principal\n\nhttp://pythonhosted.org/Flask-Principal/\nhttp://flask-principal-cn.readthedocs.io/zh_CN/latest/\n\n\n\n## Flask-DebugToolbar\nhttps://flask-debugtoolbar.readthedocs.io/en/latest/\n\n\n## 部署方案( Nginx + Gunicorn + Supervisor )\n\n生产环境下，flask 自带的 服务器，无法满足性能要求。我们这里采用 gunicorn 做 wsgi 容器，用来部署 python。\n\nGunicorn 官网：[http://gunicorn.org/](http://gunicorn.org/)\n\n参考：[virtualenv 环境下 Flask + Nginx + Gunicorn+ Supervisor 搭建 Python Web](http://www.ituring.com.cn/article/201045?utm_source=tuicool)\n\nSupervisor 重启 Gunicorn 时，有时会碰到 Gunicorn 起不来的情况\n查看端口占用情况\n```\n# netstat -tulpn\nActive Internet connections (only servers)\nProto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name\ntcp        0      0 0.0.0.0:8000            0.0.0.0:*               LISTEN      1722/python\ntcp        0      0 127.0.0.1:9001          0.0.0.0:*               LISTEN      1/python\ntcp        0      0 0.0.0.0:8010            0.0.0.0:*               LISTEN      647/python\n# kill -9 PID\n```\n\n安装\n```\n$ pip install gunicorn\n```\n用 gunicorn 启动 flask\n```\n$ gunicorn -w4 -b0.0.0.0:8000 app:app\n[2016-03-02 15:22:44 +0000] [14362] [INFO] Starting gunicorn 19.4.5\n[2016-03-02 15:22:44 +0000] [14362] [INFO] Listening at: http://0.0.0.0:8000 (14362)\n[2016-03-02 15:22:44 +0000] [14362] [INFO] Using worker: sync\n[2016-03-02 15:22:44 +0000] [14367] [INFO] Booting worker with pid: 14367\n[2016-03-02 15:22:44 +0000] [14370] [INFO] Booting worker with pid: 14370\n[2016-03-02 15:22:45 +0000] [14373] [INFO] Booting worker with pid: 14373\n[2016-03-02 15:22:45 +0000] [14374] [INFO] Booting worker with pid: 14374\n```\n此时，我们需要用 8000 的端口进行访问，原先的5000并没有启用。\n\n进程数的推荐配置：\nworkers = multiprocessing.cpu_count() * 2 + 1\n\n安装 supervisor\n```\n$ pip install supervisor\n$ echo_supervisord_conf > etc/supervisord.conf\n```\n\n新增如下配置\n```\n[program:app]\ncommand=\"gunicorn -w 4 -b 0.0.0.0:8000 app:app\"\nstartsecs=0\nstopwaitsecs=0\nautostart=false\nautorestart=false\nstdout_logfile=log/gunicorn.log\nstderr_logfile=log/gunicorn.err\n```\n\n启动 supervisord 服务\n```\n$ supervisord -c etc/supervisord.conf\n```\n\n常用命令\n```\nsupervisord -c etc/supervisord.conf\nsupervisorctl -c etc/supervisord.conf status                  查看supervisor的状态\nsupervisorctl -c etc/supervisord.conf reload                  重新载入 配置文件\nsupervisorctl -c etc/supervisord.conf start [all]|[appname]   启动指定/所有 supervisor 管理的程序进程\nsupervisorctl -c etc/supervisord.conf stop [all]|[appname]    关闭指定/所有 supervisor 管理的程序进程\nsupervisorctl -c etc/supervisord.conf restart [all]|[appname] 重启指定/所有 supervisor 管理的程序进程\n```\n\nsupervisor 还有一个 web 的管理界面，可以激活。更改下配置：\n```\n[inet_http_server]         ; inet (TCP) server disabled by default\nport=127.0.0.1:9001        ; (ip_address:port specifier, *:port for all iface)\nusername=admin             ; (default is no username (open server))\npassword=123456            ; (default is no password (open server))\n```\n```\n[supervisorctl]\nserverurl=unix:///tmp/supervisor.sock ; use a unix:// URL  for a unix socket\nserverurl=http://127.0.0.1:9001       ; use an http:// url to specify an inet socket\nusername=admin                        ; should be same as http_username if set\npassword=123456                       ; should be same as http_password if set\n;prompt=mysupervisor                  ; cmd line prompt (default \"supervisor\")\n;history_file=~/.sc_history           ; use readline history if available\n```\n用户名 和 密码 必须一致，也可以同时注释掉。\n\n重新加载配置 并 重启服务\n```\n$ supervisorctl -c etc/supervisord.conf reload\n$ supervisorctl -c etc/supervisord.conf restart all\n```\n\n浏览器访问 [http://127.0.0.1:9001](http://127.0.0.1:9001) 可以得到 supervisor 的 web 管理界面，\n访问 [http://127.0.0.1:8000](http://127.0.0.1:8000) 可以看见 gunicorn 启动的返回的页面。\n\nnginx 服务\n```\nsudo service nginx start\nsudo service nginx stop\nsudo service nginx restart\n```\n\n```\n进入项目目录\n$ sudo ln -s `pwd`/etc/nginx.conf /etc/nginx/conf.d/flask_app_nginx.conf\n$ sudo nginx -s reload  # 平滑重启\n$ sudo subl /etc/hosts\n# 127.0.0.1    www.flask-app.com\n```\n\n查看 ip 地址\n```\n$ ifconfig eth0 | grep 'inet ' | awk '{print $2}'\n```\n\nnginx 静态资源目录配置\n```\n$ sudo mkdir -p /data/static\n$ sudo chown nginx. /data -R\n$ sudo ln -s /data/static /home/zhanghe/code/flask_project/app/static\n```\n\n为了保证网站安全（避免上传漏洞），需要正确权限配置（目录755，静态文件644权限）\n```\n$ cd /data/\n$ find ./ -type d -print | xargs chmod 755\n$ find ./ -type f -print | xargs chmod 644\n```\n\n不建议以下为方便而设置的777权限\n```\n$ sudo chmod 777 -R /data/static/\n```\n\n新增 nginx 配置信息\n```\nlocation ~ ^/static/ {\n    root /data/;\n    #过期30天，静态文件不怎么更新，过期可以设大一点，如果频繁更新，则可以设置得小一点。\n    expires 30d;\n}\n```\n\nNginx https 部署\n\n参考: [https.md](doc/https.md)\n\n\n## 上传目录权限设置\n```\n$ chmod 777 /data/uploads\n```\n\n## 统计代码行数(包含注释)\n\n查看项目python代码行数\n```\n$ find ./app -type f -name \"*.py\" | xargs wc -l\n```\n\n查看项目模板文件行数\n```\n$ find ./app -type f -name \"*.html\" | xargs wc -l\n```\n\n\n## 调试\n\n在 Python 应用程序中设置断点\n```\nimport pdb; pdb.set_trace()\n```\n\n\n## 远程调试\n```\n$ pip install remote-pdb\n```\n\n远程调试配置代码（添加web服务启动之前）：\n```\nimport signal\nimport os\n\n\ndef handle_pdb(sig, frame):\n    from remote_pdb import RemotePdb\n    print sig, frame\n    RemotePdb('0.0.0.0', 48110).set_trace()  # 如将ip地址设置为127.0.0.1，只能本机调试\n\nsignal.signal(signal.SIGUSR1, handle_pdb)\nprint('pid:%s' % os.getpid())\n```\n\n调试过程：\n\n一、服务启动\n```\n$ ./run.py \npid:7892\n * Running on http://0.0.0.0:5000/ (Press CTRL+C to quit)\n10 <frame object at 0x7fb9010259d8>\nCRITICAL:root:RemotePdb session open at 127.0.0.1:48110, waiting for connection ...\nRemotePdb session open at 0.0.0.0:48110, waiting for connection ...\nCRITICAL:root:RemotePdb accepted connection from ('127.0.0.1', 41497).\nRemotePdb accepted connection from ('127.0.0.1', 41497).\n```\n终端输出的进程id 为 7892\n\n二、给进程7892 发送终止信号\n```\n$ kill -10 7892\n```\n\n三、远程登陆\n```\n$ telnet 127.0.0.1 48110\nTrying 127.0.0.1...\nConnected to 127.0.0.1.\nEscape character is '^]'.\n--Return--\n> /home/zhanghe/code/flask_project/run.py(21)handle_pdb()->None\n-> RemotePdb('127.0.0.1', 48110).set_trace()\n(Pdb) \n```\n\n四、退出调试(2步)：\nCtrl + ], q\n```\n(Pdb) ^]\n\ntelnet> q\nConnection closed.\n```\n此时，程序继续运行（web继续提供服务）\n\npdb 可以执行命令：\n直接回车是重复前一条命令！\np(print) 查看一个变量值\nn(next) 下一步\ns(step) 单步,可进入函数\nc(continue)继续前进\nl(list)看源代码\n\n查看系统支持的信号列表\n```\n$ kill -l\n 1) SIGHUP\t 2) SIGINT\t 3) SIGQUIT\t 4) SIGILL\t 5) SIGTRAP\n 6) SIGABRT\t 7) SIGBUS\t 8) SIGFPE\t 9) SIGKILL\t10) SIGUSR1\n11) SIGSEGV\t12) SIGUSR2\t13) SIGPIPE\t14) SIGALRM\t15) SIGTERM\n16) SIGSTKFLT\t17) SIGCHLD\t18) SIGCONT\t19) SIGSTOP\t20) SIGTSTP\n21) SIGTTIN\t22) SIGTTOU\t23) SIGURG\t24) SIGXCPU\t25) SIGXFSZ\n26) SIGVTALRM\t27) SIGPROF\t28) SIGWINCH\t29) SIGIO\t30) SIGPWR\n31) SIGSYS\t34) SIGRTMIN\t35) SIGRTMIN+1\t36) SIGRTMIN+2\t37) SIGRTMIN+3\n38) SIGRTMIN+4\t39) SIGRTMIN+5\t40) SIGRTMIN+6\t41) SIGRTMIN+7\t42) SIGRTMIN+8\n43) SIGRTMIN+9\t44) SIGRTMIN+10\t45) SIGRTMIN+11\t46) SIGRTMIN+12\t47) SIGRTMIN+13\n48) SIGRTMIN+14\t49) SIGRTMIN+15\t50) SIGRTMAX-14\t51) SIGRTMAX-13\t52) SIGRTMAX-12\n53) SIGRTMAX-11\t54) SIGRTMAX-10\t55) SIGRTMAX-9\t56) SIGRTMAX-8\t57) SIGRTMAX-7\n58) SIGRTMAX-6\t59) SIGRTMAX-5\t60) SIGRTMAX-4\t61) SIGRTMAX-3\t62) SIGRTMAX-2\n63) SIGRTMAX-1\t64) SIGRTMAX\n```\n\n以上程序使用的 SIGUSR1 是终止进程信号，为用户定义信号1\n\n\n参考文档\n[https://pypi.python.org/pypi/remote-pdb](https://pypi.python.org/pypi/remote-pdb)\n\n\n## 参考资料：\n\n[Flask 代码模式](http://docs.jinkan.org/docs/flask/patterns/index.html)\n\n\n## 安全设置\n\n- 路由参数 校验参数类型，格式\n\n例如：\n```\n@app.route('/blog/edit/<int:blog_id>/', methods=['GET', 'POST'])\n```\n防止 XSS 漏洞\n\n- 主键设置为整型（为方便底层操作，统一命名为 id）\n\n好处：安全（防止因代码疏忽而导致的 XSS 漏洞），效率\n\n- 链接中的重定向参数(next)不能为外链\n\n防止 URL 重定向/跳转漏洞\nredirect=<script>alert('XSS')</script>\n\n\n## GitHub 操作\n\n…or create a new repository on the command line\n```\necho \"# flask_project\" >> README.md\ngit init\ngit add README.md\ngit commit -m \"first commit\"\ngit remote add origin git@github.com:zhanghe06/flask_project.git\ngit push -u origin master\n```\n\n…or push an existing repository from the command line\n```\ngit remote add origin git@github.com:zhanghe06/flask_project.git\ngit push -u origin master\n```\n\n\n## Fix SNIMissingWarning\n\n机器环境:\n```\n$ python --version\nPython 2.7.6\n```\n\n虚拟环境:\n```\n$ pip freeze | grep requests\nrequests==2.9.1\nrequests-oauthlib==0.6.1\n```\n\n执行 pip freeze 命令后有报错信息:\n```\n/home/zhanghe/code/flask_project/flask.env/local/lib/python2.7/site-packages/pip/_vendor/requests/packages/urllib3/util/ssl_.py:315: SNIMissingWarning: An HTTPS request has been made, but the SNI (Subject Name Indication) extension to TLS is not available on this platform. This may cause the server to present an incorrect TLS certificate, which can cause validation failures. For more information, see https://urllib3.readthedocs.org/en/latest/security.html#snimissingwarning.\n```\n原因: [requests 2.6 以后的版本, pyopenssl.inject_into_urllib3()](https://github.com/kennethreitz/requests/blob/a57c87a459d51c5b17d20285109e901b8aa95752/requests/__init__.py#L54)\n\npython-2.7.9 以前的版本都会有这个问题\n\n如果不想升级 python 版本, 可以选择降级 requests 版本, 例如: requests==2.5.3\n\n最佳解决方案:\n```\n$ sudo apt-get install python-dev libffi-dev libssl-dev\n$ pip install 'requests[security]'\n```\n相应的依赖都会被装上:\n```\nInstalling collected packages: idna, pyasn1, six, enum34, ipaddress, pycparser, cffi, cryptography, pyOpenSSL, ndg-httpsclient\nSuccessfully installed cffi-1.5.2 cryptography-1.3.1 enum34-1.1.3 idna-2.1 ipaddress-1.0.16 ndg-httpsclient-0.4.0 pyOpenSSL-16.0.0 pyasn1-0.1.9 pycparser-2.14 six-1.10.0\n```\n\n\n## UUID\n\n[https://docs.python.org/2/library/uuid.html#example](https://docs.python.org/2/library/uuid.html#example)\n\n\n## SendCloud\n\n[http://sendcloud.sohu.com/](http://sendcloud.sohu.com/)\n\n## QiNiu\n\n安装\n```\n$ pip install qiniu\n```\n\n[http://www.qiniu.com/](http://www.qiniu.com/)\n\n[python SDK 官方版](https://github.com/qiniu/python-sdk)\n\n[python SDK 社区版](https://github.com/yueyoum/seven-cow)\n\n[Flask 扩展](https://github.com/csuzhangxc/Flask-QiniuStorage)\n\n\n## 注册邮箱验证\n\n主要验证两点：\n- 邮箱是否可达\n- 是否本人操作\n\n验证方式：\n- 一、验证 token：https://www.***.com/email/signup/token\n- 二、验证签名：https://www.***.com/email/signup/sign\n\n显然第二种方式更好，不需要生成一个一次性的 token 并把它们存到数据库中\n\n参考：[http://itsdangerous.readthedocs.io/en/latest/](http://itsdangerous.readthedocs.io/en/latest/)\n\n\n## 签名模块\n\n中文文档：[http://itsdangerous.readthedocs.io/en/latest/](http://itsdangerous.readthedocs.io/en/latest/)\n\n\n## 常用链接的处理\n\n添加锚点： url_for('end_points', _anchor='part_id')\n\n_external=True 绝对路径\n\n\n## 编码规范（建议）\n\n新增表单\n```\n@app.route('/add/', methods=['GET', 'POST'])\n@login_required\ndef add():\n    \"\"\"\n    添加\n    \"\"\"\n    form = AddForm(request.form)\n    if request.method == 'POST':\n        if form.validate_on_submit():\n            from datetime import datetime\n            current_time = datetime.utcnow()\n            info = {\n                'author': form.author.data,\n                'title': form.title.data,\n                'pub_date': form.pub_date.data,\n                'add_time': current_time,\n                'edit_time': current_time,\n            }\n            result = add(info)\n            if result:\n                flash(u'Add Success', 'success')\n            else:\n                flash(u'Add Failed', 'warning')\n    return render_template('add.html', form=form)\n```\n\n编辑表单\n```\n@app.route('/edit/<int:id>/', methods=['GET', 'POST'])\n@login_required\ndef edit(id):\n    \"\"\"\n    编辑\n    \"\"\"\n    form = EditForm(request.form)\n    if request.method == 'GET':\n        info = get_info(id)\n        if blog_info:\n            form.author.data = info.author\n            form.title.data = info.title\n            form.pub_date.data = info.pub_date\n        else:\n            return redirect(url_for('index'))\n    if request.method == 'POST':\n        if form.validate_on_submit():\n            from datetime import datetime\n            info = {\n                'author': form.author.data,\n                'title': form.title.data,\n                'pub_date': form.pub_date.data,\n                'edit_time': datetime.utcnow(),\n            }\n            result = edit(id, info)\n            if result:\n                flash(u'Edit Success', 'success')\n            else:\n                flash(u'Edit Failed', 'warning')\n    return render_template('edit.html', id=id, form=form)\n```\n\n\n## 模板引擎\n\n[https://github.com/aui/artTemplate](https://github.com/aui/artTemplate)\n\n[https://github.com/wycats/handlebars.js](https://github.com/wycats/handlebars.js)\n\n模板引擎与jinja结合\n```\n{% raw %}\n...\n{% endraw %}\n```\n\n\n## 模块导入更新\n\n旧模块 | 新模块\n| --- | --- |\nflask.ext.login | flask_login\nflask.ext.wtf | flask_wtf\nflask.ext.sqlalchemy | flask_sqlalchemy\nflask.ext.mail | flask_mail\n\n表单里，用 FlaskForm 替代历史版本 Form\n```\nfrom flask.ext.wtf import Form\n替换为\nfrom flask_wtf import FlaskForm\n```\n\n\n## 过滤器\n\n注册自定义过滤器\n```\n方式一：\n@app.template_filter('reverse')\ndef reverse_filter(s):\n    return s[::-1]\n\n方式二：\ndef reverse_filter(s):\n    return s[::-1]\napp.jinja_env.filters['reverse'] = reverse_filter\n```\n\n过滤器使用\n```\n{% for x in mylist | reverse %}\n{% endfor %}\n```\n\n\n## 用户注册\n\n注册方式 | 校验方式\n| --- | --- |\n手机号码 | 短信验证码\n邮箱 | 发送带身份信息加密的链接，点击校验通过后即确认身份\n第三方 | oauth\n\n注意：如果需要兼容国际手机号码注册，需要添加国家区号\n\n平台内先注册，后绑定第三方账号\n\n\n## 手机注册\n\n检查手机号码\n检查图形码\n获取短信验证码\n    1、前台页面60S倒计时，60S后恢复\n    2、后台生成短信码 session存储\n    3、发送短信\n提交注册（校验 表单与session 短信验证码）\n\n\n## 忘记密码\n\n\n## 页面全选功能设计\n```\n$(\"#check_all\").change(function(){ \n    $('.check_children').prop(\"checked\",this.checked); \n}); \n```\n\n\n## 业务逻辑确认外键还是数据库设置外键\n\n效率与一致性的权衡\n\n主外键只是一种保持数据一致性的手段之一，如果有别的方式来保持数据一致性（业务逻辑保持数据一致性），那么数据库不设置主外键也是可以的。\n\n\n## 数据库设计 NOT NULL 与 DEFAULT(默认非null值)\n\n1、NOT NULL DEFAULT 同时设置，可以不插入字段，但是不能插入 null 值\n2、仅仅设置 DEFAULT，可以不插入字段，也可插入 null 值\n3、仅仅设置 NOT NULL，可以不插入字段，不可插入 null 值\n\n通常，DEFAULT 的设置会简化代码的设计，\n同时考虑索引效率，会将需要建立索引的字段添加 DEFAULT，因为 null是无法比较的\n```\nMariaDB [(none)]> select 2=2, 'a'='a', NULL=NULL;\n+-----+---------+-----------+\n| 2=2 | 'a'='a' | NULL=NULL |\n+-----+---------+-----------+\n|   1 |       1 |      NULL |\n+-----+---------+-----------+\n1 row in set (0.00 sec)\n```\n\n## 关于数据库索引优化\n\n索引的类型\n\n索引名称 | 定义 | 描述\n| --- | --- | --- |\n普通索引 | key | 唯一的作用就是加快查询的速度\n主键索引 | primary key | 字段具备唯一性 一张数据表中只有一个\n唯一索引 | unique key | 保证数据唯一性\n联合索引 | key(a,b,c) | 实际上是建立3个索引(a,b,c;a,b;a)，每个索引都包含a\n外键索引 | - | 就是用来维护数据表之间的相关性的，并且会导致数据的写入等操作的速度过慢，所以好像没啥用（对于较大的项目）\n全文索引 | FULLTEXT(column1, column2) | mysql5.6以前的InnoDB表不支持。使用：WHERE MATCH(column) AGAINST('search_content')\n\n\n能否用到索引 | 操作符\n| --- | --- |\n可以用到 | <, <=, =, >, >=, BETWEEN, IN, LIKE _%\n不能用到 | <>, !=, not in, LIKE %_\n\n对于比较长的字符串比如varchar(255)类型字段，可为该字段的前n个值建立索引，可用以下语句确定索引的长度\n```\nselect count(distinct substring(字段,1,结束位置)) from 表\n```\n\nEXPLAIN 测试SQL执行计划\n\n\n## 基于 redisde 会话管理\n\n登陆成功后，即可看到session信息\n```\n127.0.0.1:6379> keys *\n1) \"session:.eJw9kF1vgjAYhf_K0msvsOASTbww1jkMbwmk1bU3RD5caWUoyNAa__uIS8y5PMnz5Jw7Sg5N0So0uzRdMUJJmaPZHb2laIbAZhMgEYZqY8CKnla8D5nxQGc3uhYerMEBZjDV2VhYvwcilcDcBcxxSGJDdV5KkpchiVzBVi7stlpqH0vmX0PiO0C4pYxWYI0n7JAq1oPHEXp1kyxWIVGGDsxwxz2h1VGyaHBFPeBoAhZcsaNHqmHosjl6jFDWNofkUpvi5zVBEo6BDWjsD6rMk-x7TK1UgGMDjA_z-I3q1QS070itNCXGkYv5E3c-J_W-u6imyMvmRdx_xk5G6t_ALjpYen2gF-8hWfSwnLYpzk9pOVX5V1yn7uZUVFsTuB_XoP8ndm3RPA9GLnr8AWDyey8.C58cvw._6DL2RmlQ9oqsw8IlGuX0FvLGts\"\n127.0.0.1:6379> type \"session:.eJw9kF1vgjAYhf_K0msvsOASTbww1jkMbwmk1bU3RD5caWUoyNAa__uIS8y5PMnz5Jw7Sg5N0So0uzRdMUJJmaPZHb2laIbAZhMgEYZqY8CKnla8D5nxQGc3uhYerMEBZjDV2VhYvwcilcDcBcxxSGJDdV5KkpchiVzBVi7stlpqH0vmX0PiO0C4pYxWYI0n7JAq1oPHEXp1kyxWIVGGDsxwxz2h1VGyaHBFPeBoAhZcsaNHqmHosjl6jFDWNofkUpvi5zVBEo6BDWjsD6rMk-x7TK1UgGMDjA_z-I3q1QS070itNCXGkYv5E3c-J_W-u6imyMvmRdx_xk5G6t_ALjpYen2gF-8hWfSwnLYpzk9pOVX5V1yn7uZUVFsTuB_XoP8ndm3RPA9GLnr8AWDyey8.C58cvw._6DL2RmlQ9oqsw8IlGuX0FvLGts\"\nstring\n127.0.0.1:6379> get \"session:.eJw9kF1vgjAYhf_K0msvsOASTbww1jkMbwmk1bU3RD5caWUoyNAa__uIS8y5PMnz5Jw7Sg5N0So0uzRdMUJJmaPZHb2laIbAZhMgEYZqY8CKnla8D5nxQGc3uhYerMEBZjDV2VhYvwcilcDcBcxxSGJDdV5KkpchiVzBVi7stlpqH0vmX0PiO0C4pYxWYI0n7JAq1oPHEXp1kyxWIVGGDsxwxz2h1VGyaHBFPeBoAhZcsaNHqmHosjl6jFDWNofkUpvi5zVBEo6BDWjsD6rMk-x7TK1UgGMDjA_z-I3q1QS070itNCXGkYv5E3c-J_W-u6imyMvmRdx_xk5G6t_ALjpYen2gF-8hWfSwnLYpzk9pOVX5V1yn7uZUVFsTuB_XoP8ndm3RPA9GLnr8AWDyey8.C58cvw._6DL2RmlQ9oqsw8IlGuX0FvLGts\"\n\"(dp0\\nS'csrf_token'\\np1\\nS'c44590d3e1d7be4250ff8c88e1b807832939b8ab'\\np2\\nsS'_fresh'\\np3\\nI01\\nsS'user_id'\\np4\\nV3\\np5\\nsS'_id'\\np6\\nS'3790462bd3606e09982724f80c4196675c2006ace73e684d67bd7b847a171ecf26e2182405353f398c63bdc364b12e4a88d46a9e8b8ee466403d9337ace638b7'\\np7\\ns.\"\n127.0.0.1:6379>\n```\n\n\n## 并发测试\n\nflask 自带的 BaseHTTPServer 性能太差，测试过程中，连续刷新10次左右竟然报错\n```\nIOError: [Errno 32] Broken pipe\n```\n\n测试图形验证码并发\n```\n✗ ab -n 1000 -c 100 http://127.0.0.1:8000/captcha/get_code/reg/\n```\n\n\n## 事务一致性\n\n分布式架构下，无法做到跨服务事务，只能通过逻辑事务，回滚采用补偿方案处理\n\n\n## ajax 前后端规范\n\n后端返回结构\n```\njson.dumps({'result': True})\njson.dumps({'result': False, 'msg': u'错误消息'})\njson.dumps({'result': False, 'msg': u'错误消息', 'location': 'http://www.baidu.com'})\n```\n\n前端处理逻辑\n```\n\n```\n\n## sqlalchemy.exc.OperationalError\nOperationalError: (_mysql_exceptions.OperationalError) (2006, 'MySQL server has gone away')\n\n\n## sqlalchemy.exc.InvalidRequestError\nStatementError: (sqlalchemy.exc.InvalidRequestError) Can't reconnect until invalid transaction is rolled back\n\n检查配置\n```\nMariaDB [flask_project]> show global variables like \"%timeout%\";\n+-----------------------------+----------+\n| Variable_name               | Value    |\n+-----------------------------+----------+\n| connect_timeout             | 5        |\n| deadlock_timeout_long       | 50000000 |\n| deadlock_timeout_short      | 10000    |\n| delayed_insert_timeout      | 300      |\n| innodb_flush_log_at_timeout | 1        |\n| innodb_lock_wait_timeout    | 50       |\n| innodb_rollback_on_timeout  | OFF      |\n| interactive_timeout         | 28800    |\n| lock_wait_timeout           | 31536000 |\n| net_read_timeout            | 30       |\n| net_write_timeout           | 60       |\n| slave_net_timeout           | 3600     |\n| thread_pool_idle_timeout    | 60       |\n| wait_timeout                | 600      |\n+-----------------------------+----------+\n14 rows in set (0.00 sec)\n```\n\n查看连接情况\n```\nMariaDB [flask_project]> show processlist;\n+-----+------+------------------+---------------+---------+------+-------+------------------+----------+\n| Id  | User | Host             | db            | Command | Time | State | Info             | Progress |\n+-----+------+------------------+---------------+---------+------+-------+------------------+----------+\n| 176 | root | 172.17.0.5:46672 | flask_project | Query   |    0 | init  | show processlist |    0.000 |\n| 180 | root | 172.17.0.1:39592 | flask_project | Sleep   |  284 |       | NULL             |    0.000 |\n+-----+------+------------------+---------------+---------+------+-------+------------------+----------+\n2 rows in set (0.00 sec)\n```\n\n查看当前打开的连接的数量\n```\nMariaDB [flask_project]> show status like '%Threads_connected%';\n+-------------------+-------+\n| Variable_name     | Value |\n+-------------------+-------+\n| Threads_connected | 2     |\n+-------------------+-------+\n1 row in set (0.01 sec)\n```\n\n修改连接超时时间（测试）\n```\nMariaDB [flask_project]> set global wait_timeout=6;\n```\n\n```\nMariaDB [flask_project]> show global variables like 'wait_timeout';\n+---------------+-------+\n| Variable_name | Value |\n+---------------+-------+\n| wait_timeout  | 600   |\n+---------------+-------+\n1 row in set (0.00 sec)\nMariaDB [flask_project]> show variables like 'wait_timeout';\n+---------------+-------+\n| Variable_name | Value |\n+---------------+-------+\n| wait_timeout  | 28800 |\n+---------------+-------+\n1 row in set (0.00 sec)\nMariaDB [flask_project]> show global status like 'uptime';\n+---------------+--------+\n| Variable_name | Value  |\n+---------------+--------+\n| Uptime        | 204519 |\n+---------------+--------+\n1 row in set (0.00 sec)\n\nMariaDB [flask_project]> show global variables like 'max_allowed_packet';\n+--------------------+----------+\n| Variable_name      | Value    |\n+--------------------+----------+\n| max_allowed_packet | 16777216 |\n+--------------------+----------+\n1 row in set (0.00 sec)\n```\n\n\n错误重现:\n\n当有事务没有提交或者没有回滚时，sqlalchemy 的连接回收时间（SQLALCHEMY_POOL_RECYCLE）大于数据库关闭等待连接时间（global wait_timeout）；\n\n一旦数据库连接超时自动断开，此时 sqlalchemy 尝试连接数据库，会出现 OperationalError: (_mysql_exceptions.OperationalError) (2006, 'MySQL server has gone away')\n\n处理方案:\n1. sqlalchemy 的超时时间 小于 数据库的超时时间\n2. 代码操作数据库，立即提交事务，错误回滚\n\n官方说明:\n\nhttp://flask-sqlalchemy.pocoo.org/2.2/config/#timeouts\n\n\n## gunicorn [CRITICAL] WORKER TIMEOUT\n\n\n## jinja 模板递归\n\n关键词 recursive\n\n```\n{% for item in [8,[[10,11,34],2],[3,4,5,[6,7,8]]] recursive %}\n    {% if loop.first %}\n        <br/>{{ '----'*loop.depth }}开始{{ loop.depth }}<br/>\n    {% endif %}\n    {{ '----'*loop.depth }}Depth: {{ loop.depth }}\n    {% if item[0] %}\n        {{ loop(item) }}\n    {% else %}\n        Number: {{ item }} ;<br/>\n    {% endif %}\n    {% if loop.last %}\n        {{ '----'*loop.depth }}结束{{ loop.depth }}<br/>\n    {% endif %}\n{% endfor %}\n```\n\n递归循环结果：\n```\n----开始1\n----Depth: 1 Number: 8 ;\n----Depth: 1\n--------开始2\n--------Depth: 2\n------------开始3\n------------Depth: 3 Number: 10 ;\n------------Depth: 3 Number: 11 ;\n------------Depth: 3 Number: 34 ;\n------------结束3\n--------Depth: 2 Number: 2 ;\n--------结束2\n----Depth: 1\n--------开始2\n--------Depth: 2 Number: 3 ;\n--------Depth: 2 Number: 4 ;\n--------Depth: 2 Number: 5 ;\n--------Depth: 2\n------------开始3\n------------Depth: 3 Number: 6 ;\n------------Depth: 3 Number: 7 ;\n------------Depth: 3 Number: 8 ;\n------------结束3\n--------结束2\n----结束1\n```\n\n## 在 jinja2 macro 使用 current_user\n\n需要带使用上下文参数（with context）\n```\n{% from \"macros/comments.html\" import comment_form with context %}\n```\n\n\n## 银行卡验证接口\n\nhttp://www.apistore.cn/\n\nhttp://v.gotoway.com/api/v4/bankCard?key=0341749f1adc9e4f47f6a936e7ed9b46&bankcard=123456\n\n\n```\n{\n\"error_code\": 0,\n\"reason\": \"Succes\",\n\"result\": {\n    \"abbreviation\": \"ABC\",\n    \"bankimage\": \"http://auth.apis.la/bank/3_ABC.png\",\n    \"bankname\": \"农业银行\",\n    \"banknum\": \"1030000\",\n    \"bankurl\": \"http://www.abchina.com/\",\n    \"cardlength\": \"19\",\n    \"cardname\": \"金穗通宝卡(银联卡)\",\n    \"cardprefixlength\": \"6\",\n    \"cardprefixnum\": \"622848\",\n    \"cardtype\": \"银联借记卡\",\n    \"enbankname\": \"Agricultural Bank of China\",\n    \"isLuhn\": true,\n    \"iscreditcard\": 1,\n    \"servicephone\": \"95599\"\n},\n\"ordersign\": \"20170621091044215952509756\"\n}\n```\n\n认证类型：\n- 实名认证 （姓名、身份证号码）\n- 银行卡三要素认证 （银行卡姓名/卡号/身份证）\n- 银行卡四要素认证 （银行卡姓名/卡号/身份证/手机号）\n\n\n## 参数优化\n\n连接池大小 == web进程数 == CPU核心数\n\nSQLALCHEMY_POOL_RECYCLE < wait_timeout\n\n\n```\nMariaDB [flask_project]> show global variables like 'max_connections';\n+-----------------+-------+\n| Variable_name   | Value |\n+-----------------+-------+\n| max_connections | 100   |\n+-----------------+-------+\n1 row in set (0.00 sec)\nMariaDB [flask_project]> set global max_connections=1000;\n```\nset global max_connections=1000;\n\n\n## 流式处理的几种方式\n\n- HTML5 Server-Sent Events\n- Flask-SSE\n\nhttp://dormousehole.readthedocs.io/en/latest/patterns/streaming.html\n\nhttp://flask.pocoo.org/snippets/118/\n\nhttp://www.python-requests.org/en/master/user/advanced/#streaming-requests\n\nhttp://flask-sse.readthedocs.io/en/latest/quickstart.html\n\n\n## 日志\n\n使用 supervisor 管理进程，终端输出的日志信息，被supervisor截获后，写入stderr_logfile，一直想不通\n\n查看 logging 模块源码\n\n```\nclass StreamHandler(Handler):\n    \"\"\"\n    A handler class which writes logging records, appropriately formatted,\n    to a stream. Note that this class does not close the stream, as\n    sys.stdout or sys.stderr may be used.\n    \"\"\"\n\n    def __init__(self, stream=None):\n        \"\"\"\n        Initialize the handler.\n\n        If stream is not specified, sys.stderr is used.\n        \"\"\"\n        Handler.__init__(self)\n        if stream is None:\n            stream = sys.stderr\n        self.stream = stream\n```\n\nStreamHandler 默认是按照标准错误输出处理\n\nprint 则使用的是标准输出\n\n\n## 分库分表\n\n垂直分库\n\n水平分表\n\n- 分库\n\nhttp://flask-sqlalchemy.pocoo.org/2.1/binds/\n```\nSQLALCHEMY_DATABASE_URI = 'postgres://localhost/main'\nSQLALCHEMY_BINDS = {\n    'users':        'mysqldb://localhost/users',\n    'appmeta':      'sqlite:////path/to/appmeta.db'\n}\n```\n\n```\nclass User(db.Model):\n    __bind_key__ = 'users'\n    id = db.Column(db.Integer, primary_key=True)\n    username = db.Column(db.String(80), unique=True)\n```\n\n使用 SQLALCHEMY_BINDS（） 和 **\\_\\_bind_key__**\n\n- 分表\n\n网友方案，先拿来\n```\nclass GoodsDesc(object):\n\n    _mapper = {}\n\n    @staticmethod\n    def model(goods_id):\n        table_index = goods_id%100\n        class_name = 'GoodsDesc_%d' % table_index\n\n        ModelClass = GoodsDesc._mapper.get(class_name, None)\n        if ModelClass is None:\n            ModelClass = type(class_name, (db.Model,), {\n                '__module__' : __name__,\n                '__name__' : class_name,\n                '__tablename__' : 'goods_desc_%d' % table_index,\n\n                'goods_id' : db.Column(db.Integer, primary_key=True),\n                'goods_desc' : db.Column(db.Text, default=None),\n            })\n            GoodsDesc._mapper[class_name] = ModelClass\n\n        cls = ModelClass()\n        cls.goods_id = goods_id\n        return cls\n\n# 外部代码调用如例如下：\n# -----------------------\n\n# 新增插入\ngdm = GoodsDesc.model(goods_id)\ngdm.goods_desc = 'desc'\ndb.session.add(gd)\n\n# 查询\ngdm = GoodsDesc.model(goods_id)\ngd = gdm.query.filter_by(goods_id=goods_id).first()\n```\n\n待改进\n```\n_mapper = {}\n\n\ndef shard(self, pk_id):\n    \"\"\"\n    分表\n    :param self:\n    :param pk_id:\n    :return:\n    \"\"\"\n    table_index = pk_id % 16\n    class_name = '%s_%02d' % (self.name, table_index)\n\n    model_class = _mapper.get(class_name, None)\n    if model_class is None:\n        model_class = type(class_name, (Base,), {\n            '__module__': __name__,\n            '__name__': class_name,\n            '__tablename__': '%s_%d' % (self.__table__.name, table_index),\n\n            'goods_id': db.Column(db.Integer, primary_key=True),\n            'goods_desc': db.Column(db.Text, default=None),\n        })\n        _mapper[class_name] = model_class\n\n    cls = model_class()\n    cls.id = pk_id\n    return cls\n```\n\n\n## 单一架构 VS 微服务架构\n\n\n## 信息修改\n账号修改\n密码修改\n\n\n## Todo：\n\n- 第三方登陆\n\n- 第三方支付\n\n- 邮件列表的绑定和解绑\n\n- 找回密码安全设置\n参考：[密码找回功能可能存在的问题](http://drops.wooyun.org/web/3295)\n\n- 接口参数签名校验的必要性\n参考：[在线支付逻辑漏洞总结](http://drops.wooyun.org/papers/345)\n\n- 检查数据重复, 处理效率问题\n\n- 页面导出csv\n\n- 各大搜索引擎提交入口\n\n- 用户推广，注册邀请\n"
  },
  {
    "path": "app_api/README.md",
    "content": "## App 专用\n"
  },
  {
    "path": "app_api/__init__.py",
    "content": "#!/usr/bin/env python\n# encoding: utf-8\n\n\"\"\"\n@author: zhanghe\n@software: PyCharm\n@file: __init__.py.py\n@time: 2017/4/19 下午2:24\n\"\"\"\n\n\ndef func():\n    pass\n\n\nclass Main(object):\n    def __init__(self):\n        pass\n\n\nif __name__ == '__main__':\n    pass\n"
  },
  {
    "path": "app_backend/README.md",
    "content": "## 运营后台\n"
  },
  {
    "path": "app_backend/__init__.py",
    "content": "#!/usr/bin/env python\n# encoding: utf-8\n\n\"\"\"\n@author: zhanghe\n@software: PyCharm\n@file: __init__.py\n@time: 2017/4/9 上午10:11\n\"\"\"\n\nfrom logging.config import dictConfig\nfrom config import current_config\n\nfrom flask import Flask\nfrom flask_login import LoginManager\nfrom flask_moment import Moment\nfrom flask_oauthlib.client import OAuth\nfrom flask_principal import Principal\n\nfrom app_backend.lib.qiniu_store import QiNiuClient\nfrom app_backend.lib.redis_session import RedisSessionInterface\nfrom app_backend.lib.sendcloud import SendCloudClient\nfrom app_backend.lib.sms_chuanglan_iso import SmsChuangLanIsoApi\n\n\napp = Flask(__name__)\napp.config.from_object(current_config)\napp.config['REMEMBER_COOKIE_NAME'] = 'r_a'\napp.session_cookie_name = 's_a'\napp.session_interface = RedisSessionInterface(prefix='s:a:', **app.config['REDIS'])\n\nlogin_manager = LoginManager()\nlogin_manager.init_app(app)  # setup_app 方法已淘汰\nlogin_manager.login_view = 'login'\nlogin_manager.login_message = u'请登录后操作'  # 设置登录提示消息\nlogin_manager.login_message_category = 'info'  # 设置消息分类\n\n# 权限管理插件\nprincipals = Principal(app)\n\n# Moment 时间插件\nmoment = Moment(app)\n\n# 短信通道\nsms_client = SmsChuangLanIsoApi(app.config['SMS']['UN'], app.config['SMS']['PW'])\n\n# SendCloud 邮件\nsend_cloud_client = SendCloudClient(app)\n\n# 七牛云存储\nqi_niu_client = QiNiuClient(app)\n\n# 第三方开放授权登录\noauth = OAuth(app)\n\n# GitHub\noauth_github = oauth.remote_app(\n    'github',\n    **app.config['GITHUB_OAUTH']\n)\n\n# QQ\noauth_qq = oauth.remote_app(\n    'qq',\n    **app.config['QQ_OAUTH']\n)\n\n# WeiBo\noauth_weibo = oauth.remote_app(\n    'weibo',\n    **app.config['WEIBO_OAUTH']\n)\n\n# Google\n# 要银子，妹的\n\n\n# 配置日志\ndictConfig(app.config['LOG_CONFIG'])\n\nif not app.config['DEBUG']:\n    import logging\n    from logging.handlers import SMTPHandler\n    credentials = None\n    if app.config['MAIL_USERNAME'] or app.config['MAIL_PASSWORD']:\n        credentials = (app.config['MAIL_USERNAME'], app.config['MAIL_PASSWORD'])\n    mail_handler = SMTPHandler(\n        (app.config['MAIL_SERVER'], app.config['MAIL_PORT']),\n        app.config['MAIL_DEFAULT_SENDER'][1],\n        app.config['ADMINS'],\n        'App Error Message',\n        credentials\n    )\n    mail_handler.setLevel(logging.DEBUG)\n    app.logger.addHandler(mail_handler)\n\n\n# 这个 import 语句放在这里, 防止views, models import发生循环import\nfrom app_backend import models, tasks\n\n# 导入视图（不使用蓝图的单模式方式）\nfrom app_backend import views\n\n# 导入视图（不使用蓝图的多模块方式）\n# from application.views import auth\n# from application.views import blog\n# from application.views import reg\n# from application.views import site\n# from application.views import user\n\n# 导入蓝图（使用蓝图的多模块方式）\nfrom app_backend.views.admin import bp_admin\nfrom app_backend.views.apply_get import bp_apply_get\nfrom app_backend.views.apply_put import bp_apply_put\nfrom app_backend.views.order import bp_order\nfrom app_backend.views.score import bp_score\nfrom app_backend.views.wallet import bp_wallet\n# from app_backend.views.blog import bp_blog\n# from app_backend.views.file import bp_file\n# from app_backend.views.reg import bp_reg\nfrom app_backend.views.user import bp_user\nfrom app_backend.views.settings import bp_settings\nfrom app_backend.views.complaint import bp_complaint\nfrom app_backend.views.message import bp_message\nfrom app_backend.views.stats import bp_stats\nfrom app_backend.views.active import bp_active\nfrom app_backend.views.scheduling import bp_scheduling\n\n\n# 注册蓝图\napp.register_blueprint(bp_admin)\napp.register_blueprint(bp_apply_get)\napp.register_blueprint(bp_apply_put)\napp.register_blueprint(bp_order)\napp.register_blueprint(bp_score)\napp.register_blueprint(bp_wallet)\n# app.register_blueprint(bp_blog)\n# app.register_blueprint(bp_file)\n# app.register_blueprint(bp_reg)\napp.register_blueprint(bp_user)\napp.register_blueprint(bp_settings)\napp.register_blueprint(bp_complaint)\napp.register_blueprint(bp_message)\napp.register_blueprint(bp_stats)\napp.register_blueprint(bp_active)\napp.register_blueprint(bp_scheduling)\n\n# 导入自定义过滤器\nfrom app_backend import filters\n"
  },
  {
    "path": "app_backend/api/__init__.py",
    "content": "#!/usr/bin/env python\n# encoding: utf-8\n\n\"\"\"\n@author: zhanghe\n@software: PyCharm\n@file: __init__.py.py\n@time: 2017/3/10 下午11:32\n\"\"\"\n\n\ndef func():\n    pass\n\n\nclass Main(object):\n    def __init__(self):\n        pass\n\n\nif __name__ == '__main__':\n    pass\n"
  },
  {
    "path": "app_backend/api/active.py",
    "content": "#!/usr/bin/env python\n# encoding: utf-8\n\n\"\"\"\n@author: zhanghe\n@software: PyCharm\n@file: active.py\n@time: 2017/5/14 上午1:42\n\"\"\"\n\n\nfrom datetime import datetime\nfrom app_backend.database import db\nfrom app_backend.models import Active, ActiveItem, User\nfrom app_backend.tools.db import get_row, get_rows, get_row_by_id, add, edit, delete\nfrom app_common.maps.status_audit import *\nfrom app_common.maps.type_active import *\nfrom app_common.maps.status_active import *\n\n\ndef get_active_row_by_id(active_id):\n    \"\"\"\n    通过 id 获取激活信息\n    :param active_id:\n    :return: None/object\n    \"\"\"\n    return get_row_by_id(Active, active_id)\n\n\ndef get_active_row(*args, **kwargs):\n    \"\"\"\n    获取激活信息\n    :param args:\n    :param kwargs:\n    :return: None/object\n    \"\"\"\n    return get_row(Active, *args, **kwargs)\n\n\ndef add_active(active_data):\n    \"\"\"\n    添加激活信息\n    :param active_data:\n    :return: None/Value of active.id\n    \"\"\"\n    return add(Active, active_data)\n\n\ndef edit_active(active_id, active_data):\n    \"\"\"\n    修改激活信息\n    :param active_id:\n    :param active_data:\n    :return: Number of affected rows (Example: 0/1)\n    \"\"\"\n    return edit(Active, active_id, active_data)\n\n\ndef delete_active(active_id):\n    \"\"\"\n    删除激活信息\n    :param active_id:\n    :return: Number of affected rows (Example: 0/1)\n    \"\"\"\n    return delete(Active, active_id)\n\n\ndef get_active_rows(page=1, per_page=10, *args, **kwargs):\n    \"\"\"\n    获取激活列表（分页）\n    Usage:\n        items: 信息列表\n        has_next: 如果本页之后还有超过一个分页，则返回True\n        has_prev: 如果本页之前还有超过一个分页，则返回True\n        next_num: 返回下一页的页码\n        prev_num: 返回上一页的页码\n        iter_pages(): 页码列表\n        iter_pages(left_edge=2, left_current=2, right_current=5, right_edge=2) 页码列表默认参数\n    :param page:\n    :param per_page:\n    :param args:\n    :param kwargs:\n    :return:\n    \"\"\"\n    rows = get_rows(Active, page, per_page, *args, **kwargs)\n    return rows\n\n\ndef give_active(user_id_active, amount=1):\n    \"\"\"\n    赠送激活数量\n    :param user_id_active:\n    :param amount:\n    :return:\n    \"\"\"\n    try:\n\n        current_time = datetime.utcnow()\n\n        # 添加激活码消费明细\n        active_item_data = {\n            'user_id': 0,\n            'type': TYPE_ACTIVE_GIVE,\n            'amount': amount,\n            'sc_id': user_id_active,\n            'status_audit': STATUS_AUDIT_SUCCESS,\n            'audit_time': current_time,\n            'create_time': current_time,\n            'update_time': current_time,\n        }\n        db.session.add(ActiveItem(**active_item_data))\n\n        # 新增接收用户激活码总数量\n        active_obj = db.session.query(Active).filter(Active.user_id == user_id_active)\n        active_info = active_obj.first()\n        if active_info:\n            active_data = {\n                'user_id': user_id_active,\n                'amount': active_info.amount + amount,\n                'update_time': current_time,\n            }\n            active_obj.update(active_data)\n        else:\n            active_data = {\n                'user_id': user_id_active,\n                'amount': amount,\n                'create_time': current_time,\n                'update_time': current_time,\n            }\n            db.session.add(Active(**active_data))\n\n        db.session.commit()\n        return True\n    except Exception as e:\n        db.session.rollback()\n        raise e\n"
  },
  {
    "path": "app_backend/api/active_item.py",
    "content": "#!/usr/bin/env python\n# encoding: utf-8\n\n\"\"\"\n@author: zhanghe\n@software: PyCharm\n@file: active_item.py\n@time: 2017/5/20 下午6:29\n\"\"\"\n\n\nfrom app_backend.models import ActiveItem\nfrom app_backend.tools.db import get_row, get_rows, get_row_by_id, add, edit, delete\n\n\ndef get_active_item_row_by_id(active_item_id):\n    \"\"\"\n    通过 id 获取激活信息\n    :param active_item_id:\n    :return: None/object\n    \"\"\"\n    return get_row_by_id(ActiveItem, active_item_id)\n\n\ndef get_active_item_row(*args, **kwargs):\n    \"\"\"\n    获取激活信息\n    :param args:\n    :param kwargs:\n    :return: None/object\n    \"\"\"\n    return get_row(ActiveItem, *args, **kwargs)\n\n\ndef add_active_item(active_item_data):\n    \"\"\"\n    添加激活信息\n    :param active_item_data:\n    :return: None/Value of active.id\n    \"\"\"\n    return add(ActiveItem, active_item_data)\n\n\ndef edit_active_item(active_item_id, active_item_data):\n    \"\"\"\n    修改激活信息\n    :param active_item_id:\n    :param active_item_data:\n    :return: Number of affected rows (Example: 0/1)\n    \"\"\"\n    return edit(ActiveItem, active_item_id, active_item_data)\n\n\ndef delete_active_item(active_item_id):\n    \"\"\"\n    删除激活信息\n    :param active_item_id:\n    :return: Number of affected rows (Example: 0/1)\n    \"\"\"\n    return delete(ActiveItem, active_item_id)\n\n\ndef get_active_item_rows(page=1, per_page=10, *args, **kwargs):\n    \"\"\"\n    获取激活列表（分页）\n    Usage:\n        items: 信息列表\n        has_next: 如果本页之后还有超过一个分页，则返回True\n        has_prev: 如果本页之前还有超过一个分页，则返回True\n        next_num: 返回下一页的页码\n        prev_num: 返回上一页的页码\n        iter_pages(): 页码列表\n        iter_pages(left_edge=2, left_current=2, right_current=5, right_edge=2) 页码列表默认参数\n    :param page:\n    :param per_page:\n    :param args:\n    :param kwargs:\n    :return:\n    \"\"\"\n    rows = get_rows(ActiveItem, page, per_page, *args, **kwargs)\n    return rows\n"
  },
  {
    "path": "app_backend/api/admin.py",
    "content": "#!/usr/bin/env python\n# encoding: utf-8\n\n\"\"\"\n@author: zhanghe\n@software: PyCharm\n@file: admin.py\n@time: 17-4-20 下午10:04\n\"\"\"\n\n\nfrom app_backend.login import LoginUser\nfrom app_backend.tools.db import get_row, get_rows, get_row_by_id, add, edit, delete, update_rows\n\n\ndef get_admin_row_by_id(user_auth_id):\n    \"\"\"\n    通过 id 获取用户信息\n    :param user_auth_id:\n    :return: None/object\n    \"\"\"\n    return get_row_by_id(LoginUser, user_auth_id)\n\n\ndef get_admin_row(*args, **kwargs):\n    \"\"\"\n    获取用户信息\n    :param args:\n    :param kwargs:\n    :return: None/object\n    \"\"\"\n    return get_row(LoginUser, *args, **kwargs)\n\n\ndef add_admin(user_auth_data):\n    \"\"\"\n    添加用户信息\n    :param user_auth_data:\n    :return: None/Value of user.id\n    \"\"\"\n    return add(LoginUser, user_auth_data)\n\n\ndef edit_admin(user_auth_id, user_auth_data):\n    \"\"\"\n    修改用户信息\n    :param user_auth_id:\n    :param user_auth_data:\n    :return: Number of affected rows (Example: 0/1)\n    \"\"\"\n    return edit(LoginUser, user_auth_id, user_auth_data)\n\n\ndef delete_admin(user_auth_id):\n    \"\"\"\n    删除用户信息\n    :param user_auth_id:\n    :return: Number of affected rows (Example: 0/1)\n    \"\"\"\n    return delete(LoginUser, user_auth_id)\n\n\ndef get_admin_rows(page=1, per_page=10, *args, **kwargs):\n    \"\"\"\n    获取用户列表（分页）\n    Usage:\n        items: 信息列表\n        has_next: 如果本页之后还有超过一个分页，则返回True\n        has_prev: 如果本页之前还有超过一个分页，则返回True\n        next_num: 返回下一页的页码\n        prev_num: 返回上一页的页码\n        iter_pages(): 页码列表\n        iter_pages(left_edge=2, left_current=2, right_current=5, right_edge=2) 页码列表默认参数\n    :param page:\n    :param per_page:\n    :param args:\n    :param kwargs:\n    :return:\n    \"\"\"\n    rows = get_rows(LoginUser, page, per_page, *args, **kwargs)\n    return rows\n\n\ndef update_admin_rows(data, *args, **kwargs):\n    \"\"\"\n    批量更新用户信息\n    \"\"\"\n    return update_rows(LoginUser, data, *args, **kwargs)\n"
  },
  {
    "path": "app_backend/api/admin_role.py",
    "content": "#!/usr/bin/env python\n# encoding: utf-8\n\n\"\"\"\n@author: zhanghe\n@software: PyCharm\n@file: admin_role.py\n@time: 2017/6/14 上午11:07\n\"\"\"\n\n\nfrom app_backend.models import AdminRole\nfrom app_backend.tools.db import get_row, get_rows, get_row_by_id, add, edit, delete, get_lists\n\n\ndef get_admin_role_row_by_id(admin_role_id):\n    \"\"\"\n    通过 id 获取角色信息\n    :param admin_role_id:\n    :return: None/object\n    \"\"\"\n    return get_row_by_id(AdminRole, admin_role_id)\n\n\ndef get_admin_role_row(*args, **kwargs):\n    \"\"\"\n    获取角色信息\n    :param args:\n    :param kwargs:\n    :return: None/object\n    \"\"\"\n    return get_row(AdminRole, *args, **kwargs)\n\n\ndef add_admin_role(admin_role_data):\n    \"\"\"\n    添加角色信息\n    :param admin_role_data:\n    :return: None/Value of author.id\n    \"\"\"\n    return add(AdminRole, admin_role_data)\n\n\ndef edit_admin_role(admin_role_id, admin_role_data):\n    \"\"\"\n    修改角色信息\n    :param admin_role_id:\n    :param admin_role_data:\n    :return: Number of affected rows (Example: 0/1)\n    \"\"\"\n    return edit(AdminRole, admin_role_id, admin_role_data)\n\n\ndef delete_admin_role(admin_role_id):\n    \"\"\"\n    删除角色信息\n    :param admin_role_id:\n    :return: Number of affected rows (Example: 0/1)\n    \"\"\"\n    return delete(AdminRole, admin_role_id)\n\n\ndef get_admin_role_rows(page=1, per_page=10, *args, **kwargs):\n    \"\"\"\n    获取角色列表（分页）\n    Usage:\n        items: 信息列表\n        has_next: 如果本页之后还有超过一个分页，则返回True\n        has_prev: 如果本页之前还有超过一个分页，则返回True\n        next_num: 返回下一页的页码\n        prev_num: 返回上一页的页码\n        iter_pages(): 页码列表\n        iter_pages(left_edge=2, left_current=2, right_current=5, right_edge=2) 页码列表默认参数\n    :param page:\n    :param per_page:\n    :param args:\n    :param kwargs:\n    :return:\n    \"\"\"\n    rows = get_rows(AdminRole, page, per_page, *args, **kwargs)\n    return rows\n\n\ndef get_admin_role_lists(*args, **kwargs):\n    \"\"\"\n    获取角色列表\n    :param args:\n    :param kwargs:\n    :return: None/list\n    \"\"\"\n    return get_lists(AdminRole, *args, **kwargs)\n"
  },
  {
    "path": "app_backend/api/apply_get.py",
    "content": "#!/usr/bin/env python\n# encoding: utf-8\n\n\"\"\"\n@author: zhanghe\n@software: PyCharm\n@file: apply_get.py\n@time: 2017/4/13 上午11:27\n\"\"\"\n\n\nfrom datetime import datetime\nimport traceback\n\nfrom sqlalchemy import func\n\nfrom app_backend.database import db\nfrom app_backend.models import ApplyGet, Order, ApplyPut\nfrom app_backend.tools.db import get_row, get_rows_by_ids, get_lists, get_rows, get_row_by_id, add, edit, delete\nfrom app_common.maps.status_audit import STATUS_AUDIT_SUCCESS\nfrom app_common.maps.status_order import STATUS_ORDER_COMPLETED, STATUS_ORDER_PROCESSING\nfrom app_common.tools.date_time import get_current_day_time_ends, get_hours, time_local_to_utc, \\\n    get_current_month_time_ends, get_days, get_current_year_time_ends, get_months\n\n\ndef get_apply_get_row_by_id(apply_get_id):\n    \"\"\"\n    通过 id 获取提现申请信息\n    :param apply_get_id:\n    :return: None/object\n    \"\"\"\n    return get_row_by_id(ApplyGet, apply_get_id)\n\n\ndef get_apply_get_row(*args, **kwargs):\n    \"\"\"\n    获取提现申请信息\n    :param args:\n    :param kwargs:\n    :return: None/object\n    \"\"\"\n    return get_row(ApplyGet, *args, **kwargs)\n\n\ndef add_apply_get(apply_get_data):\n    \"\"\"\n    添加提现申请信息\n    :param apply_get_data:\n    :return: None/Value of apply_get.id\n    \"\"\"\n    return add(ApplyGet, apply_get_data)\n\n\ndef edit_apply_get(apply_get_id, apply_get_data):\n    \"\"\"\n    修改提现申请信息\n    :param apply_get_id:\n    :param apply_get_data:\n    :return: Number of affected rows (Example: 0/1)\n    \"\"\"\n    return edit(ApplyGet, apply_get_id, apply_get_data)\n\n\ndef delete_apply_get(apply_get_id):\n    \"\"\"\n    删除提现申请信息\n    :param apply_get_id:\n    :return: Number of affected rows (Example: 0/1)\n    \"\"\"\n    return delete(ApplyGet, apply_get_id)\n\n\ndef get_apply_get_rows_by_ids(ids):\n    \"\"\"\n    获取提现申请列表通过主键列表\n    :param ids:\n    :return: list\n    \"\"\"\n    return get_rows_by_ids(ApplyGet, ids)\n\n\ndef get_apply_get_lists(*args, **kwargs):\n    \"\"\"\n    获取提现申请列表\n    :param args:\n    :param kwargs:\n    :return: None/list\n    \"\"\"\n    return get_lists(ApplyGet, *args, **kwargs)\n\n\ndef get_apply_get_rows(page=1, per_page=10, *args, **kwargs):\n    \"\"\"\n    获取提现申请列表（分页）\n    Usage:\n        items: 信息列表\n        has_next: 如果本页之后还有超过一个分页，则返回True\n        has_prev: 如果本页之前还有超过一个分页，则返回True\n        next_num: 返回下一页的页码\n        prev_num: 返回上一页的页码\n        iter_pages(): 页码列表\n        iter_pages(left_edge=2, left_current=2, right_current=5, right_edge=2) 页码列表默认参数\n    :param page:\n    :param per_page:\n    :param args:\n    :param kwargs:\n    :return:\n    \"\"\"\n    rows = get_rows(ApplyGet, page, per_page, *args, **kwargs)\n    return rows\n\n\ndef apply_get_match(apply_get_id, apply_put_ids, accept_split=0):\n    \"\"\"\n    提现申请匹配\n    :param apply_get_id:\n    :param apply_put_ids:\n    :param accept_split:\n    :return:\n    \"\"\"\n    from app_backend.api.apply_put import get_apply_put_rows_by_ids\n\n    apply_get_info = get_apply_get_row_by_id(apply_get_id)\n\n    # 判断是否已经匹配\n    if apply_get_info.status_order == int(STATUS_ORDER_COMPLETED):\n        raise Exception(u'不能重复匹配')\n    apply_put_list = get_apply_put_rows_by_ids(apply_put_ids)\n\n    # 判断是否同一个人\n    apply_put_user_ids = [apply_put_item.user_id for apply_put_item in apply_put_list]\n    if apply_get_info.user_id in apply_put_user_ids:\n        raise Exception(u'不能匹配给自己')\n\n    # 判断金额\n    money_need_match = apply_get_info.money_apply - apply_get_info.money_order\n\n    apply_put_amount = sum([apply_put_item.money_apply-apply_put_item.money_order for apply_put_item in apply_put_list])\n    # 如果接收拆分，判断被拆金额是否大于被匹配金额\n    if accept_split:\n        if money_need_match < apply_put_amount:\n            raise Exception(u'选择金额太大')\n    elif money_need_match != apply_put_amount:\n        raise Exception(u'金额不匹配')\n\n    # 循环投资申请，生成对应的订单\n    try:\n        money_order = 0\n        for apply_put_item in apply_put_list:\n            money_match = apply_put_item.money_apply - apply_put_item.money_order\n            current_time = datetime.utcnow()\n\n            order_data = {\n                'apply_put_id': apply_put_item.id,\n                'apply_get_id': apply_get_id,\n                'apply_put_uid': apply_put_item.user_id,\n                'apply_get_uid': apply_get_info.user_id,\n                'money': money_match,\n                'status_audit': STATUS_AUDIT_SUCCESS,\n                'audit_time': current_time,\n                'create_time': current_time,\n                'update_time': current_time,\n            }\n            db.session.add(Order(**order_data))\n\n            # 更新投资申请状态\n            apply_put_update_info = {\n                'money_order': apply_put_item.money_order + money_match,\n                'status_order': STATUS_ORDER_COMPLETED,\n                'update_time': current_time,\n            }\n            apply_put_obj = db.session.query(ApplyPut).filter(ApplyPut.id == apply_put_item.id)\n            apply_put_obj.update(apply_put_update_info)\n\n            money_order += money_match\n\n        # 更新提现订单金额和申请状态\n        current_time = datetime.utcnow()\n        apply_get_update_data = {\n            'money_order': ApplyGet.money_order + money_order,\n            'status_order': STATUS_ORDER_COMPLETED if money_order == money_need_match else STATUS_ORDER_PROCESSING,\n            'update_time': current_time,\n        }\n        # result = edit_apply_get(apply_get_id, apply_get_update_info)\n        apply_get_obj = db.session.query(ApplyGet).filter(ApplyGet.id == apply_get_id)\n        result = apply_get_obj.update(apply_get_update_data)\n\n        db.session.commit()\n        return result\n    except Exception as e:\n        print traceback.print_exc()\n        db.session.rollback()\n        raise e\n\n\ndef apply_get_stats(time_based='hour'):\n    \"\"\"\n    提现申请统计\n    :return:\n    \"\"\"\n    # 按小时统计\n    if time_based == 'hour':\n        start_time, end_time = get_current_day_time_ends()\n        hours = get_hours(False)\n        hours_zerofill = get_hours()\n        result = dict(zip(hours, [0] * len(hours)))\n        rows = db.session \\\n            .query(func.hour(ApplyGet.create_time).label('hour'), func.sum(ApplyGet.money_apply)) \\\n            .filter(ApplyGet.create_time >= time_local_to_utc(start_time),\n                    ApplyGet.create_time <= time_local_to_utc(end_time)) \\\n            .group_by('hour') \\\n            .limit(len(hours)) \\\n            .all()\n        result.update(dict(rows))\n        return [(hours_zerofill[i], result[hour]) for i, hour in enumerate(hours)]\n    # 按日期统计\n    if time_based == 'date':\n        start_time, end_time = get_current_month_time_ends()\n        today = datetime.today()\n        days = get_days(year=today.year, month=today.month, zerofill=False)\n        days_zerofill = get_days(year=today.year, month=today.month)\n        result = dict(zip(days, [0] * len(days)))\n        rows = db.session \\\n            .query(func.day(ApplyGet.create_time).label('date'), func.sum(ApplyGet.money_apply)) \\\n            .filter(ApplyGet.create_time >= time_local_to_utc(start_time),\n                    ApplyGet.create_time <= time_local_to_utc(end_time)) \\\n            .group_by('date') \\\n            .limit(len(days)) \\\n            .all()\n        result.update(dict(rows))\n        return [(days_zerofill[i], result[day]) for i, day in enumerate(days)]\n    # 按月份统计\n    if time_based == 'month':\n        start_time, end_time = get_current_year_time_ends()\n        months = get_months(False)\n        months_zerofill = get_months()\n        result = dict(zip(months, [0] * len(months)))\n        rows = db.session \\\n            .query(func.month(ApplyGet.create_time).label('month'), func.sum(ApplyGet.money_apply)) \\\n            .filter(ApplyGet.create_time >= time_local_to_utc(start_time),\n                    ApplyGet.create_time <= time_local_to_utc(end_time)) \\\n            .group_by('month') \\\n            .limit(len(months)) \\\n            .all()\n        result.update(dict(rows))\n        return [(months_zerofill[i], result[month]) for i, month in enumerate(months)]\n"
  },
  {
    "path": "app_backend/api/apply_put.py",
    "content": "#!/usr/bin/env python\n# encoding: utf-8\n\n\"\"\"\n@author: zhanghe\n@software: PyCharm\n@file: apply_put.py\n@time: 2017/4/13 下午9:45\n\"\"\"\n\n\nfrom datetime import datetime\nimport traceback\n\nfrom sqlalchemy import func\n\nfrom app_backend.models import ApplyGet, Order, ApplyPut\nfrom app_backend.tools.db import get_row, get_rows_by_ids, get_lists, get_rows, get_row_by_id, add, edit, delete\nfrom app_backend.database import db\nfrom app_common.maps.status_audit import STATUS_AUDIT_SUCCESS\nfrom app_common.maps.status_order import STATUS_ORDER_COMPLETED, STATUS_ORDER_PROCESSING\nfrom app_common.tools.date_time import get_current_day_time_ends, get_hours, time_local_to_utc, \\\n    get_current_month_time_ends, get_days, get_current_year_time_ends, get_months\n\n\ndef get_apply_put_row_by_id(apply_put_id):\n    \"\"\"\n    通过 id 获取投资申请信息\n    :param apply_put_id:\n    :return: None/object\n    \"\"\"\n    return get_row_by_id(ApplyPut, apply_put_id)\n\n\ndef get_apply_put_row(*args, **kwargs):\n    \"\"\"\n    获取投资申请信息\n    :param args:\n    :param kwargs:\n    :return: None/object\n    \"\"\"\n    return get_row(ApplyPut, *args, **kwargs)\n\n\ndef add_apply_put(apply_put_data):\n    \"\"\"\n    添加投资申请信息\n    :param apply_put_data:\n    :return: None/Value of apply_put.id\n    \"\"\"\n    return add(ApplyPut, apply_put_data)\n\n\ndef edit_apply_put(apply_put_id, apply_put_data):\n    \"\"\"\n    修改投资申请信息\n    :param apply_put_id:\n    :param apply_put_data:\n    :return: Number of affected rows (Example: 0/1)\n    \"\"\"\n    return edit(ApplyPut, apply_put_id, apply_put_data)\n\n\ndef delete_apply_put(apply_put_id):\n    \"\"\"\n    删除投资申请信息\n    :param apply_put_id:\n    :return: Number of affected rows (Example: 0/1)\n    \"\"\"\n    return delete(ApplyPut, apply_put_id)\n\n\ndef get_apply_put_rows_by_ids(ids):\n    \"\"\"\n    获取投资申请列表\n    :param ids:\n    :return: list\n    \"\"\"\n    return get_rows_by_ids(ApplyPut, ids)\n\n\ndef get_apply_put_lists(*args, **kwargs):\n    \"\"\"\n    获取投资申请列表\n    :param args:\n    :param kwargs:\n    :return: None/list\n    \"\"\"\n    return get_lists(ApplyPut, *args, **kwargs)\n\n\ndef get_apply_put_rows(page=1, per_page=10, *args, **kwargs):\n    \"\"\"\n    获取投资申请列表（分页）\n    Usage:\n        items: 信息列表\n        has_next: 如果本页之后还有超过一个分页，则返回True\n        has_prev: 如果本页之前还有超过一个分页，则返回True\n        next_num: 返回下一页的页码\n        prev_num: 返回上一页的页码\n        iter_pages(): 页码列表\n        iter_pages(left_edge=2, left_current=2, right_current=5, right_edge=2) 页码列表默认参数\n    :param page:\n    :param per_page:\n    :param args:\n    :param kwargs:\n    :return:\n    \"\"\"\n    rows = get_rows(ApplyPut, page, per_page, *args, **kwargs)\n    return rows\n\n\ndef apply_put_match(apply_put_id, apply_get_ids, accept_split=0):\n    \"\"\"\n    投资申请匹配\n    :param apply_put_id:\n    :param apply_get_ids:\n    :param accept_split:\n    :return:\n    \"\"\"\n    from app_backend.api.apply_get import get_apply_get_rows_by_ids\n\n    apply_put_info = get_apply_put_row_by_id(apply_put_id)\n\n    # 判断是否已经匹配\n    if apply_put_info.status_order == int(STATUS_ORDER_COMPLETED):\n        raise Exception(u'不能重复匹配')\n    apply_get_list = get_apply_get_rows_by_ids(apply_get_ids)\n\n    # 判断是否同一个人\n    apply_get_user_ids = [apply_get_item.user_id for apply_get_item in apply_get_list]\n    if apply_put_info.user_id in apply_get_user_ids:\n        raise Exception(u'不能匹配给自己')\n\n    # 判断金额\n    money_need_match = apply_put_info.money_apply - apply_put_info.money_order\n\n    apply_get_amount = sum(\n        [apply_get_item.money_apply - apply_get_item.money_order for apply_get_item in apply_get_list])\n    # 如果接收拆分，判断被拆金额是否大于被匹配金额\n    if accept_split:\n        if money_need_match < apply_get_amount:\n            raise Exception(u'选择金额太大')\n    elif money_need_match != apply_get_amount:\n        raise Exception(u'金额不匹配')\n\n    # 循环提现申请，生成对应的订单\n    try:\n        money_order = 0\n        for apply_get_item in apply_get_list:\n            money_match = apply_get_item.money_apply - apply_get_item.money_order\n            current_time = datetime.utcnow()\n\n            order_data = {\n                'apply_put_id': apply_put_id,\n                'apply_get_id': apply_get_item.id,\n                'apply_put_uid': apply_put_info.user_id,\n                'apply_get_uid': apply_get_item.user_id,\n                'money': money_match,\n                'status_audit': STATUS_AUDIT_SUCCESS,\n                'audit_time': current_time,\n                'create_time': current_time,\n                'update_time': current_time,\n            }\n            db.session.add(Order(**order_data))\n\n            # 更新提现申请状态\n            apply_get_update_info = {\n                'money_order': apply_get_item.money_order + money_match,\n                'status_order': STATUS_ORDER_COMPLETED,\n                'update_time': current_time,\n            }\n            apply_get_obj = db.session.query(ApplyGet).filter(ApplyGet.id == apply_get_item.id)\n            apply_get_obj.update(apply_get_update_info)\n\n            money_order += money_match\n\n        # 更新投资订单金额和申请状态\n        current_time = datetime.utcnow()\n        apply_put_update_data = {\n            'money_order': ApplyPut.money_order + money_order,\n            'status_order': STATUS_ORDER_COMPLETED if money_order == money_need_match else STATUS_ORDER_PROCESSING,\n            'update_time': current_time,\n        }\n        # result = edit_apply_get(apply_get_id, apply_get_update_info)\n        apply_put_obj = db.session.query(ApplyPut).filter(ApplyPut.id == apply_put_id)\n        result = apply_put_obj.update(apply_put_update_data)\n\n        db.session.commit()\n        return result\n    except Exception as e:\n        print traceback.print_exc()\n        db.session.rollback()\n        raise e\n\n\ndef apply_put_stats(time_based='hour'):\n    \"\"\"\n    投资申请统计\n    :return:\n    \"\"\"\n    # 按小时统计\n    if time_based == 'hour':\n        start_time, end_time = get_current_day_time_ends()\n        hours = get_hours(False)\n        hours_zerofill = get_hours()\n        result = dict(zip(hours, [0] * len(hours)))\n        rows = db.session \\\n            .query(func.hour(ApplyPut.create_time).label('hour'), func.sum(ApplyPut.money_apply)) \\\n            .filter(ApplyPut.create_time >= time_local_to_utc(start_time), ApplyPut.create_time <= time_local_to_utc(end_time)) \\\n            .group_by('hour') \\\n            .limit(len(hours)) \\\n            .all()\n        result.update(dict(rows))\n        return [(hours_zerofill[i], result[hour]) for i, hour in enumerate(hours)]\n    # 按日期统计\n    if time_based == 'date':\n        start_time, end_time = get_current_month_time_ends()\n        today = datetime.today()\n        days = get_days(year=today.year, month=today.month, zerofill=False)\n        days_zerofill = get_days(year=today.year, month=today.month)\n        result = dict(zip(days, [0] * len(days)))\n        rows = db.session \\\n            .query(func.day(ApplyPut.create_time).label('date'), func.sum(ApplyPut.money_apply)) \\\n            .filter(ApplyPut.create_time >= time_local_to_utc(start_time), ApplyPut.create_time <= time_local_to_utc(end_time)) \\\n            .group_by('date') \\\n            .limit(len(days)) \\\n            .all()\n        result.update(dict(rows))\n        return [(days_zerofill[i], result[day]) for i, day in enumerate(days)]\n    # 按月份统计\n    if time_based == 'month':\n        start_time, end_time = get_current_year_time_ends()\n        months = get_months(False)\n        months_zerofill = get_months()\n        result = dict(zip(months, [0] * len(months)))\n        rows = db.session \\\n            .query(func.month(ApplyPut.create_time).label('month'), func.sum(ApplyPut.money_apply)) \\\n            .filter(ApplyPut.create_time >= time_local_to_utc(start_time), ApplyPut.create_time <= time_local_to_utc(end_time)) \\\n            .group_by('month') \\\n            .limit(len(months)) \\\n            .all()\n        result.update(dict(rows))\n        return [(months_zerofill[i], result[month]) for i, month in enumerate(months)]\n"
  },
  {
    "path": "app_backend/api/author.py",
    "content": "#!/usr/bin/env python\n# encoding: utf-8\n\n\"\"\"\n@author: zhanghe\n@software: PyCharm\n@file: author.py\n@time: 16-1-17 上午12:05\n\"\"\"\n\n\nfrom app_backend.models import Author\nfrom app_backend.tools.db import get_row, get_rows, get_row_by_id, add, edit, delete\n\n\ndef get_author_row_by_id(author_id):\n    \"\"\"\n    通过 id 获取博客信息\n    :param author_id:\n    :return: None/object\n    \"\"\"\n    return get_row_by_id(Author, author_id)\n\n\ndef get_author_row(*args, **kwargs):\n    \"\"\"\n    获取博客信息\n    :param args:\n    :param kwargs:\n    :return: None/object\n    \"\"\"\n    return get_row(Author, *args, **kwargs)\n\n\ndef add_author(author_data):\n    \"\"\"\n    添加博客信息\n    :param author_data:\n    :return: None/Value of author.id\n    \"\"\"\n    return add(Author, author_data)\n\n\ndef edit_author(author_id, author_data):\n    \"\"\"\n    修改博客信息\n    :param author_id:\n    :param author_data:\n    :return: Number of affected rows (Example: 0/1)\n    \"\"\"\n    return edit(Author, author_id, author_data)\n\n\ndef delete_author(author_id):\n    \"\"\"\n    删除博客信息\n    :param author_id:\n    :return: Number of affected rows (Example: 0/1)\n    \"\"\"\n    return delete(Author, author_id)\n\n\ndef get_author_rows(page=1, per_page=10, *args, **kwargs):\n    \"\"\"\n    获取博客列表（分页）\n    Usage:\n        items: 信息列表\n        has_next: 如果本页之后还有超过一个分页，则返回True\n        has_prev: 如果本页之前还有超过一个分页，则返回True\n        next_num: 返回下一页的页码\n        prev_num: 返回上一页的页码\n        iter_pages(): 页码列表\n        iter_pages(left_edge=2, left_current=2, right_current=5, right_edge=2) 页码列表默认参数\n    :param page:\n    :param per_page:\n    :param args:\n    :param kwargs:\n    :return:\n    \"\"\"\n    rows = get_rows(Author, page, per_page, *args, **kwargs)\n    return rows\n"
  },
  {
    "path": "app_backend/api/blog.py",
    "content": "#!/usr/bin/env python\n# encoding: utf-8\n\n\"\"\"\n@blog: zhanghe\n@software: PyCharm\n@file: blog.py\n@time: 16-1-21 上午10:24\n\"\"\"\n\n\nfrom app_backend.models import Blog\nfrom app_backend.tools.db import get_row, get_rows, get_row_by_id, add, edit, delete\nfrom app_backend.lib.counter import Counter\nfrom app_backend.lib.container import Container\n\n\ndef get_blog_row_by_id(blog_id):\n    \"\"\"\n    通过 id 获取博客信息\n    :param blog_id:\n    :return: None/object\n    \"\"\"\n    return get_row_by_id(Blog, blog_id)\n\n\ndef get_blog_row(*args, **kwargs):\n    \"\"\"\n    获取博客信息\n    :param args:\n    :param kwargs:\n    :return: None/object\n    \"\"\"\n    return get_row(Blog, *args, **kwargs)\n\n\ndef add_blog(blog_data):\n    \"\"\"\n    添加博客信息\n    :param blog_data:\n    :return: None/Value of blog.id\n    \"\"\"\n    return add(Blog, blog_data)\n\n\ndef edit_blog(blog_id, blog_data):\n    \"\"\"\n    修改博客信息\n    :param blog_id:\n    :param blog_data:\n    :return: Number of affected rows (Example: 0/1)\n    \"\"\"\n    return edit(Blog, blog_id, blog_data)\n\n\ndef delete_blog(blog_id):\n    \"\"\"\n    删除博客信息\n    :param blog_id:\n    :return: Number of affected rows (Example: 0/1)\n    \"\"\"\n    return delete(Blog, blog_id)\n\n\ndef get_blog_rows(page=1, per_page=10, *args, **kwargs):\n    \"\"\"\n    获取博客列表（分页）\n    Usage:\n        items: 信息列表\n        has_next: 如果本页之后还有超过一个分页，则返回True\n        has_prev: 如果本页之前还有超过一个分页，则返回True\n        next_num: 返回下一页的页码\n        prev_num: 返回上一页的页码\n        iter_pages(): 页码列表\n        iter_pages(left_edge=2, left_current=2, right_current=5, right_edge=2) 页码列表默认参数\n    :param page:\n    :param per_page:\n    :param args:\n    :param kwargs:\n    :return:\n    \"\"\"\n    rows = get_rows(Blog, page, per_page, *args, **kwargs)\n    return rows\n\n\ndef get_blog_counter(blog_id):\n    \"\"\"\n    获取blog计数器\n    :param blog_id:\n    :return:\n    \"\"\"\n    blog_cnt_obj = Counter('blog')\n    return blog_cnt_obj.counter_blog_item(blog_id)\n\n\ndef set_blog_counter(blog_id, stat_type, num):\n    \"\"\"\n    设置blog计数器\n    :param blog_id:\n    :param stat_type:\n    :param num:\n    :return:\n    \"\"\"\n    blog_cnt_obj = Counter('blog')\n    return blog_cnt_obj.set_blog_counter(blog_id, stat_type, num)\n\n\ndef get_blog_list_counter(blog_id_list):\n    \"\"\"\n    获取blog计数器\n    :param blog_id_list:\n    :return:\n    \"\"\"\n    blog_cnt_obj = Counter('blog')\n    return blog_cnt_obj.counter_blog_list(blog_id_list)\n\n\ndef get_blog_container_status(blog_id, uid):\n    \"\"\"\n    获取blog容器状态\n    :param blog_id:\n    :param uid:\n    :return:\n    \"\"\"\n    blog_container_obj = Container('blog')\n    return blog_container_obj.get_item_container_status(blog_id, uid)\n\n\ndef get_blog_list_container_status(blog_id_list, uid):\n    \"\"\"\n    获取blog容器状态\n    :param blog_id_list:\n    :param uid:\n    :return:\n    \"\"\"\n    blog_container_obj = Container('blog')\n    return blog_container_obj.get_item_list_container_status(blog_id_list, uid)\n\n\ndef add_blog_stat_item(stat_type, blog_id, uid):\n    \"\"\"\n    添加blog统计明细\n    :param stat_type:\n    :param blog_id:\n    :param uid:\n    :return:\n    \"\"\"\n    blog_container_obj = Container('blog')\n    return blog_container_obj.add_item(stat_type, blog_id, uid)\n\nif __name__ == '__main__':\n    blog_rows = get_blog_rows(1, 10)\n    if blog_rows:\n        for item in blog_rows.items:\n            print item.id, item.author, item.title, item.pub_date\n\n    import json\n    print json.dumps(get_blog_counter(['1', '2', '3']), indent=4, ensure_ascii=False)\n"
  },
  {
    "path": "app_backend/api/complaint.py",
    "content": "#!/usr/bin/env python\n# encoding: utf-8\n\n\"\"\"\n@author: zhanghe\n@software: PyCharm\n@file: complaint.py\n@time: 2017/4/29 下午2:30\n\"\"\"\n\n\nfrom app_backend.models import Complaint\nfrom app_backend.tools.db import get_row, get_rows, get_row_by_id, add, edit, delete\n\n\ndef get_complaint_row_by_id(complaint_id):\n    \"\"\"\n    通过 id 获取投诉信息\n    :param complaint_id:\n    :return: None/object\n    \"\"\"\n    return get_row_by_id(Complaint, complaint_id)\n\n\ndef get_complaint_row(*args, **kwargs):\n    \"\"\"\n    获取投诉信息\n    :param args:\n    :param kwargs:\n    :return: None/object\n    \"\"\"\n    return get_row(Complaint, *args, **kwargs)\n\n\ndef add_complaint(complaint_data):\n    \"\"\"\n    添加投诉信息\n    :param complaint_data:\n    :return: None/Value of complaint.id\n    \"\"\"\n    return add(Complaint, complaint_data)\n\n\ndef edit_complaint(complaint_id, complaint_data):\n    \"\"\"\n    修改投诉信息\n    :param complaint_id:\n    :param complaint_data:\n    :return: Number of affected rows (Example: 0/1)\n    \"\"\"\n    return edit(Complaint, complaint_id, complaint_data)\n\n\ndef delete_complaint(complaint_id):\n    \"\"\"\n    删除投诉信息\n    :param complaint_id:\n    :return: Number of affected rows (Example: 0/1)\n    \"\"\"\n    return delete(Complaint, complaint_id)\n\n\ndef get_complaint_rows(page=1, per_page=10, *args, **kwargs):\n    \"\"\"\n    获取投诉列表（分页）\n    Usage:\n        items: 信息列表\n        has_next: 如果本页之后还有超过一个分页，则返回True\n        has_prev: 如果本页之前还有超过一个分页，则返回True\n        next_num: 返回下一页的页码\n        prev_num: 返回上一页的页码\n        iter_pages(): 页码列表\n        iter_pages(left_edge=2, left_current=2, right_current=5, right_edge=2) 页码列表默认参数\n    :param page:\n    :param per_page:\n    :param args:\n    :param kwargs:\n    :return:\n    \"\"\"\n    rows = get_rows(Complaint, page, per_page, *args, **kwargs)\n    return rows\n\n"
  },
  {
    "path": "app_backend/api/message.py",
    "content": "#!/usr/bin/env python\n# encoding: utf-8\n\n\"\"\"\n@author: zhanghe\n@software: PyCharm\n@file: message.py\n@time: 2017/6/24 下午10:20\n\"\"\"\n\n\nfrom app_backend.models import Message\nfrom app_backend.tools.db import get_row, get_rows, get_row_by_id, add, edit, delete\n\n\ndef get_message_row_by_id(message_id):\n    \"\"\"\n    通过 id 获取留言信息\n    :param message_id:\n    :return: None/object\n    \"\"\"\n    return get_row_by_id(Message, message_id)\n\n\ndef get_message_row(*args, **kwargs):\n    \"\"\"\n    获取留言信息\n    :param args:\n    :param kwargs:\n    :return: None/object\n    \"\"\"\n    return get_row(Message, *args, **kwargs)\n\n\ndef add_message(message_data):\n    \"\"\"\n    添加留言信息\n    :param message_data:\n    :return: None/Value of message.id\n    \"\"\"\n    return add(Message, message_data)\n\n\ndef edit_message(message_id, message_data):\n    \"\"\"\n    修改留言信息\n    :param message_id:\n    :param message_data:\n    :return: Number of affected rows (Example: 0/1)\n    \"\"\"\n    return edit(Message, message_id, message_data)\n\n\ndef delete_message(message_id):\n    \"\"\"\n    删除留言信息\n    :param message_id:\n    :return: Number of affected rows (Example: 0/1)\n    \"\"\"\n    return delete(Message, message_id)\n\n\ndef get_message_rows(page=1, per_page=10, *args, **kwargs):\n    \"\"\"\n    获取留言列表（分页）\n    Usage:\n        items: 信息列表\n        has_next: 如果本页之后还有超过一个分页，则返回True\n        has_prev: 如果本页之前还有超过一个分页，则返回True\n        next_num: 返回下一页的页码\n        prev_num: 返回上一页的页码\n        iter_pages(): 页码列表\n        iter_pages(left_edge=2, left_current=2, right_current=5, right_edge=2) 页码列表默认参数\n    :param page:\n    :param per_page:\n    :param args:\n    :param kwargs:\n    :return:\n    \"\"\"\n    rows = get_rows(Message, page, per_page, *args, **kwargs)\n    return rows\n"
  },
  {
    "path": "app_backend/api/order.py",
    "content": "#!/usr/bin/env python\n# encoding: utf-8\n\n\"\"\"\n@author: zhanghe\n@software: PyCharm\n@file: order.py\n@time: 2017/4/13 下午9:45\n\"\"\"\n\n\nfrom datetime import datetime\nfrom sqlalchemy import func\n\nfrom app_backend.models import Order, ApplyGet, ApplyPut\nfrom app_backend.tools.db import get_row, get_lists, get_rows, get_row_by_id, add, edit, delete\nfrom app_backend.database import db\nfrom app_common.maps.status_audit import STATUS_AUDIT_SUCCESS\nfrom app_common.maps.status_order import STATUS_ORDER_COMPLETED, STATUS_ORDER_PROCESSING\nfrom app_common.tools.date_time import get_hours, get_current_day_time_ends, time_local_to_utc, \\\n    get_current_month_time_ends, get_days, get_current_year_time_ends, get_months\n\n\ndef get_order_row_by_id(order_id):\n    \"\"\"\n    通过 id 获取订单信息\n    :param order_id:\n    :return: None/object\n    \"\"\"\n    return get_row_by_id(Order, order_id)\n\n\ndef get_order_row(*args, **kwargs):\n    \"\"\"\n    获取订单信息\n    :param args:\n    :param kwargs:\n    :return: None/object\n    \"\"\"\n    return get_row(Order, *args, **kwargs)\n\n\ndef add_order(order_data):\n    \"\"\"\n    添加订单信息\n    :param order_data:\n    :return: None/Value of order.id\n    \"\"\"\n    return add(Order, order_data)\n\n\ndef edit_order(order_id, order_data):\n    \"\"\"\n    修改订单信息\n    :param order_id:\n    :param order_data:\n    :return: Number of affected rows (Example: 0/1)\n    \"\"\"\n    return edit(Order, order_id, order_data)\n\n\ndef delete_order(order_id):\n    \"\"\"\n    删除订单信息\n    :param order_id:\n    :return: Number of affected rows (Example: 0/1)\n    \"\"\"\n    return delete(Order, order_id)\n\n\ndef get_order_lists(*args, **kwargs):\n    \"\"\"\n    获取订单列表\n    :param args:\n    :param kwargs:\n    :return: None/list\n    \"\"\"\n    return get_lists(Order, *args, **kwargs)\n\n\ndef get_order_rows(page=1, per_page=10, *args, **kwargs):\n    \"\"\"\n    获取订单列表（分页）\n    Usage:\n        items: 信息列表\n        has_next: 如果本页之后还有超过一个分页，则返回True\n        has_prev: 如果本页之前还有超过一个分页，则返回True\n        next_num: 返回下一页的页码\n        prev_num: 返回上一页的页码\n        iter_pages(): 页码列表\n        iter_pages(left_edge=2, left_current=2, right_current=5, right_edge=2) 页码列表默认参数\n    :param page:\n    :param per_page:\n    :param args:\n    :param kwargs:\n    :return:\n    \"\"\"\n    rows = get_rows(Order, page, per_page, *args, **kwargs)\n    return rows\n\n\ndef get_put_match_order_rows(apply_put_id):\n    \"\"\"\n    获取投资匹配订单列表\n    :param apply_put_id:\n    :return: list\n    \"\"\"\n    try:\n        rows = db.session.query(Order, ApplyGet). \\\n            filter(Order.apply_put_id == apply_put_id, ApplyGet.id == Order.apply_get_id). \\\n            all()\n        db.session.commit()\n        return rows\n    except Exception as e:\n        db.session.rollback()\n        raise e\n\n\ndef get_get_match_order_rows(apply_get_id):\n    \"\"\"\n    获取提现匹配订单列表\n    :param apply_get_id:\n    :return: list\n    \"\"\"\n    try:\n        rows = db.session.query(Order, ApplyPut). \\\n            filter(Order.apply_get_id == apply_get_id, ApplyPut.id == Order.apply_put_id). \\\n            all()\n        db.session.commit()\n        return rows\n    except Exception as e:\n        db.session.rollback()\n        raise e\n\n\ndef flow(order_id, next_uid):\n    \"\"\"\n    订单流转\n    :param order_id:\n    :param next_uid:\n    :return:\n    \"\"\"\n    # 获取订单信息\n    # 新增投资\n    # 新增匹配订单（流转类型）\n    # 修改原始订单（流转状态）\n    # 新增订单流转记录\n\n\ndef order_stats(time_based='hour'):\n    \"\"\"\n    订单金额统计\n    :return:\n    \"\"\"\n    # 按小时统计\n    if time_based == 'hour':\n        start_time, end_time = get_current_day_time_ends()\n        hours = get_hours(False)\n        hours_zerofill = get_hours()\n        result = dict(zip(hours, [0] * len(hours)))\n        rows = db.session \\\n            .query(func.hour(Order.create_time).label('hour'), func.sum(Order.money)) \\\n            .filter(Order.create_time >= time_local_to_utc(start_time),\n                    Order.create_time <= time_local_to_utc(end_time)) \\\n            .group_by('hour') \\\n            .limit(len(hours)) \\\n            .all()\n        result.update(dict(rows))\n        return [(hours_zerofill[i], result[hour]) for i, hour in enumerate(hours)]\n    # 按日期统计\n    if time_based == 'date':\n        start_time, end_time = get_current_month_time_ends()\n        today = datetime.today()\n        days = get_days(year=today.year, month=today.month, zerofill=False)\n        days_zerofill = get_days(year=today.year, month=today.month)\n        result = dict(zip(days, [0] * len(days)))\n        rows = db.session \\\n            .query(func.day(Order.create_time).label('date'), func.sum(Order.money)) \\\n            .filter(Order.create_time >= time_local_to_utc(start_time),\n                    Order.create_time <= time_local_to_utc(end_time)) \\\n            .group_by('date') \\\n            .limit(len(days)) \\\n            .all()\n        result.update(dict(rows))\n        return [(days_zerofill[i], result[day]) for i, day in enumerate(days)]\n    # 按月份统计\n    if time_based == 'month':\n        start_time, end_time = get_current_year_time_ends()\n        months = get_months(False)\n        months_zerofill = get_months()\n        result = dict(zip(months, [0] * len(months)))\n        rows = db.session \\\n            .query(func.month(Order.create_time).label('month'), func.sum(Order.money)) \\\n            .filter(Order.create_time >= time_local_to_utc(start_time),\n                    Order.create_time <= time_local_to_utc(end_time)) \\\n            .group_by('month') \\\n            .limit(len(months)) \\\n            .all()\n        result.update(dict(rows))\n        return [(months_zerofill[i], result[month]) for i, month in enumerate(months)]\n"
  },
  {
    "path": "app_backend/api/scheduling.py",
    "content": "#!/usr/bin/env python\n# encoding: utf-8\n\n\"\"\"\n@author: zhanghe\n@software: PyCharm\n@file: scheduling.py\n@time: 2017/6/29 下午8:46\n\"\"\"\n\n\nfrom datetime import datetime\n\nfrom app_backend.database import db\nfrom app_backend.models import Scheduling, SchedulingItem\nfrom app_backend.tools.db import get_row, get_rows, get_row_by_id, add, edit, delete\nfrom app_common.maps.status_audit import STATUS_AUDIT_SUCCESS\nfrom app_common.maps.type_scheduling import TYPE_SCHEDULING_GIVE\n\n\ndef get_scheduling_row_by_id(scheduling_id):\n    \"\"\"\n    通过 id 获取排单信息\n    :param scheduling_id:\n    :return: None/object\n    \"\"\"\n    return get_row_by_id(Scheduling, scheduling_id)\n\n\ndef get_scheduling_row(*args, **kwargs):\n    \"\"\"\n    获取排单信息\n    :param args:\n    :param kwargs:\n    :return: None/object\n    \"\"\"\n    return get_row(Scheduling, *args, **kwargs)\n\n\ndef add_scheduling(scheduling_data):\n    \"\"\"\n    添加排单信息\n    :param scheduling_data:\n    :return: None/Value of score.id\n    \"\"\"\n    return add(Scheduling, scheduling_data)\n\n\ndef edit_scheduling(scheduling_id, scheduling_data):\n    \"\"\"\n    修改排单信息\n    :param scheduling_id:\n    :param scheduling_data:\n    :return: Number of affected rows (Example: 0/1)\n    \"\"\"\n    return edit(Scheduling, scheduling_id, scheduling_data)\n\n\ndef delete_scheduling(scheduling_id):\n    \"\"\"\n    删除排单信息\n    :param scheduling_id:\n    :return: Number of affected rows (Example: 0/1)\n    \"\"\"\n    return delete(Scheduling, scheduling_id)\n\n\ndef get_scheduling_rows(page=1, per_page=10, *args, **kwargs):\n    \"\"\"\n    获取排单列表（分页）\n    Usage:\n        items: 信息列表\n        has_next: 如果本页之后还有超过一个分页，则返回True\n        has_prev: 如果本页之前还有超过一个分页，则返回True\n        next_num: 返回下一页的页码\n        prev_num: 返回上一页的页码\n        iter_pages(): 页码列表\n        iter_pages(left_edge=2, left_current=2, right_current=5, right_edge=2) 页码列表默认参数\n    :param page:\n    :param per_page:\n    :param args:\n    :param kwargs:\n    :return:\n    \"\"\"\n    rows = get_rows(Scheduling, page, per_page, *args, **kwargs)\n    return rows\n\n\ndef give_scheduling(user_id_scheduling, amount=1):\n    \"\"\"\n    赠送排单数量\n    :param user_id_scheduling:\n    :param amount:\n    :return:\n    \"\"\"\n    try:\n        current_time = datetime.utcnow()\n\n        # 添加排单币消费明细\n        scheduling_item_data = {\n            'user_id': 0,\n            'type': TYPE_SCHEDULING_GIVE,\n            'amount': amount,\n            'sc_id': user_id_scheduling,\n            'status_audit': STATUS_AUDIT_SUCCESS,\n            'audit_time': current_time,\n            'create_time': current_time,\n            'update_time': current_time,\n        }\n        db.session.add(SchedulingItem(**scheduling_item_data))\n\n        # 新增接收用户排单币总数量\n        scheduling_obj = db.session.query(Scheduling).filter(Scheduling.user_id == user_id_scheduling)\n        scheduling_info = scheduling_obj.first()\n        if scheduling_info:\n            scheduling_data = {\n                'user_id': user_id_scheduling,\n                'amount': scheduling_info.amount + amount,\n                'update_time': current_time,\n            }\n            scheduling_obj.update(scheduling_data)\n        else:\n            scheduling_data = {\n                'user_id': user_id_scheduling,\n                'amount': amount,\n                'create_time': current_time,\n                'update_time': current_time,\n            }\n            db.session.add(Scheduling(**scheduling_data))\n\n        db.session.commit()\n        return True\n    except Exception as e:\n        db.session.rollback()\n        raise e\n"
  },
  {
    "path": "app_backend/api/scheduling_item.py",
    "content": "#!/usr/bin/env python\n# encoding: utf-8\n\n\"\"\"\n@author: zhanghe\n@software: PyCharm\n@file: scheduling_item.py\n@time: 2017/6/29 下午8:46\n\"\"\"\n\n\nfrom app_backend.models import SchedulingItem\nfrom app_backend.tools.db import get_row, get_rows, get_row_by_id, add, edit, delete\n\n\ndef get_scheduling_item_item_row_by_id(scheduling_item_item_id):\n    \"\"\"\n    通过 id 获取排单明细信息\n    :param scheduling_item_item_id:\n    :return: None/object\n    \"\"\"\n    return get_row_by_id(SchedulingItem, scheduling_item_item_id)\n\n\ndef get_scheduling_item_item_row(*args, **kwargs):\n    \"\"\"\n    获取排单明细信息\n    :param args:\n    :param kwargs:\n    :return: None/object\n    \"\"\"\n    return get_row(SchedulingItem, *args, **kwargs)\n\n\ndef add_scheduling_item(scheduling_item_item_data):\n    \"\"\"\n    添加排单明细信息\n    :param scheduling_item_item_data:\n    :return: None/Value of score.id\n    \"\"\"\n    return add(SchedulingItem, scheduling_item_item_data)\n\n\ndef edit_scheduling_item(scheduling_item_item_id, scheduling_item_item_data):\n    \"\"\"\n    修改排单明细信息\n    :param scheduling_item_item_id:\n    :param scheduling_item_item_data:\n    :return: Number of affected rows (Example: 0/1)\n    \"\"\"\n    return edit(SchedulingItem, scheduling_item_item_id, scheduling_item_item_data)\n\n\ndef delete_scheduling_item(scheduling_item_item_id):\n    \"\"\"\n    删除排单明细信息\n    :param scheduling_item_item_id:\n    :return: Number of affected rows (Example: 0/1)\n    \"\"\"\n    return delete(SchedulingItem, scheduling_item_item_id)\n\n\ndef get_scheduling_item_item_rows(page=1, per_page=10, *args, **kwargs):\n    \"\"\"\n    获取排单明细列表（分页）\n    Usage:\n        items: 信息列表\n        has_next: 如果本页之后还有超过一个分页，则返回True\n        has_prev: 如果本页之前还有超过一个分页，则返回True\n        next_num: 返回下一页的页码\n        prev_num: 返回上一页的页码\n        iter_pages(): 页码列表\n        iter_pages(left_edge=2, left_current=2, right_current=5, right_edge=2) 页码列表默认参数\n    :param page:\n    :param per_page:\n    :param args:\n    :param kwargs:\n    :return:\n    \"\"\"\n    rows = get_rows(SchedulingItem, page, per_page, *args, **kwargs)\n    return rows\n"
  },
  {
    "path": "app_backend/api/score.py",
    "content": "#!/usr/bin/env python\n# encoding: utf-8\n\n\"\"\"\n@author: zhanghe\n@software: PyCharm\n@file: score.py\n@time: 2017/4/25 下午1:29\n\"\"\"\n\n\nfrom app_backend.models import Score\nfrom app_backend.tools.db import get_row, get_rows, get_row_by_id, add, edit, delete\n\n\ndef get_score_row_by_id(score_id):\n    \"\"\"\n    通过 id 获取积分信息\n    :param score_id:\n    :return: None/object\n    \"\"\"\n    return get_row_by_id(Score, score_id)\n\n\ndef get_score_row(*args, **kwargs):\n    \"\"\"\n    获取积分信息\n    :param args:\n    :param kwargs:\n    :return: None/object\n    \"\"\"\n    return get_row(Score, *args, **kwargs)\n\n\ndef add_score(score_data):\n    \"\"\"\n    添加积分信息\n    :param score_data:\n    :return: None/Value of score.id\n    \"\"\"\n    return add(Score, score_data)\n\n\ndef edit_score(score_id, score_data):\n    \"\"\"\n    修改积分信息\n    :param score_id:\n    :param score_data:\n    :return: Number of affected rows (Example: 0/1)\n    \"\"\"\n    return edit(Score, score_id, score_data)\n\n\ndef delete_score(score_id):\n    \"\"\"\n    删除积分信息\n    :param score_id:\n    :return: Number of affected rows (Example: 0/1)\n    \"\"\"\n    return delete(Score, score_id)\n\n\ndef get_score_rows(page=1, per_page=10, *args, **kwargs):\n    \"\"\"\n    获取积分列表（分页）\n    Usage:\n        items: 信息列表\n        has_next: 如果本页之后还有超过一个分页，则返回True\n        has_prev: 如果本页之前还有超过一个分页，则返回True\n        next_num: 返回下一页的页码\n        prev_num: 返回上一页的页码\n        iter_pages(): 页码列表\n        iter_pages(left_edge=2, left_current=2, right_current=5, right_edge=2) 页码列表默认参数\n    :param page:\n    :param per_page:\n    :param args:\n    :param kwargs:\n    :return:\n    \"\"\"\n    rows = get_rows(Score, page, per_page, *args, **kwargs)\n    return rows\n"
  },
  {
    "path": "app_backend/api/user.py",
    "content": "#!/usr/bin/env python\n# encoding: utf-8\n\n\"\"\"\n@user: zhanghe\n@software: PyCharm\n@file: user.py\n@time: 17-4-21 下午10:42\n\"\"\"\n\n\nfrom datetime import datetime\nfrom sqlalchemy.sql import func\n\nfrom app_backend.database import db\nfrom app_backend import app\nfrom app_backend.models import User\nfrom app_backend.models import UserBank\nfrom app_backend.models import UserProfile\nfrom app_backend.tools.db import get_row, get_rows, get_row_by_id, add, edit, delete\nfrom app_common.maps.status_lock import *\nfrom app_common.maps.status_active import *\nfrom app_common.tools.date_time import get_hours, get_days, get_months, time_local_to_utc\nfrom app_common.tools.date_time import get_current_day_time_ends\nfrom app_common.tools.date_time import get_current_month_time_ends\nfrom app_common.tools.date_time import get_current_year_time_ends\n\nPER_PAGE_BACKEND = app.config['PER_PAGE_BACKEND']\n\n\ndef get_user_row_by_id(user_id):\n    \"\"\"\n    通过 id 获取用户信息\n    :param user_id:\n    :return: None/object\n    \"\"\"\n    return get_row_by_id(User, user_id)\n\n\ndef get_user_row(*args, **kwargs):\n    \"\"\"\n    获取用户信息\n    :param args:\n    :param kwargs:\n    :return: None/object\n    \"\"\"\n    return get_row(User, *args, **kwargs)\n\n\ndef add_user(user_data):\n    \"\"\"\n    添加用户信息\n    :param user_data:\n    :return: None/Value of user.id\n    \"\"\"\n    return add(User, user_data)\n\n\ndef edit_user(user_id, user_data):\n    \"\"\"\n    修改用户信息\n    :param user_id:\n    :param user_data:\n    :return: Number of affected rows (Example: 0/1)\n    \"\"\"\n    return edit(User, user_id, user_data)\n\n\ndef delete_user(user_id):\n    \"\"\"\n    删除用户信息\n    :param user_id:\n    :return: Number of affected rows (Example: 0/1)\n    \"\"\"\n    return delete(User, user_id)\n\n\ndef get_user_rows(page=1, per_page=10, *args, **kwargs):\n    \"\"\"\n    获取用户列表（分页）\n    Usage:\n        items: 信息列表\n        has_next: 如果本页之后还有超过一个分页，则返回True\n        has_prev: 如果本页之前还有超过一个分页，则返回True\n        next_num: 返回下一页的页码\n        prev_num: 返回上一页的页码\n        iter_pages(): 页码列表\n        iter_pages(left_edge=2, left_current=2, right_current=5, right_edge=2) 页码列表默认参数\n    :param page:\n    :param per_page:\n    :param args:\n    :param kwargs:\n    :return:\n    \"\"\"\n    rows = get_rows(User, page, per_page, *args, **kwargs)\n    return rows\n\n\ndef get_user_detail_rows(page=1, per_page=10, *args, **kwargs):\n    \"\"\"\n    获取用户详细信息列表（分页）\n        User\n        UserProfile\n    Usage:\n        items: 信息列表\n        has_next: 如果本页之后还有超过一个分页，则返回True\n        has_prev: 如果本页之前还有超过一个分页，则返回True\n        next_num: 返回下一页的页码\n        prev_num: 返回上一页的页码\n        iter_pages(): 页码列表\n        iter_pages(left_edge=2, left_current=2, right_current=5, right_edge=2) 页码列表默认参数\n    :param page:\n    :param per_page:\n    :param args:\n    :param kwargs:\n    :return:\n    \"\"\"\n    try:\n        rows = User.query. \\\n            outerjoin(UserProfile, User.id == UserProfile.user_id). \\\n            outerjoin(UserBank, User.id == UserBank.user_id). \\\n            add_entity(UserProfile). \\\n            add_entity(UserBank). \\\n            filter(*args). \\\n            filter_by(**kwargs). \\\n            paginate(page, PER_PAGE_BACKEND, False)\n        db.session.commit()\n        return rows\n    except Exception as e:\n        db.session.rollback()\n        raise e\n\n\ndef lock(user_id):\n    \"\"\"\n    锁定用户\n    :param user_id:\n    :return: Number of affected rows (Example: 0/1)\n    \"\"\"\n    current_time = datetime.utcnow()\n    user_data = {\n        'status_lock': STATUS_LOCK_OK,\n        'lock_time': current_time,\n        'update_time': current_time\n    }\n    result = edit_user(user_id, user_data)\n    return result\n\n\ndef unlock(user_id):\n    \"\"\"\n    解锁用户\n    :param user_id:\n    :return: Number of affected rows (Example: 0/1)\n    \"\"\"\n    current_time = datetime.utcnow()\n    user_data = {\n        'status_lock': STATUS_LOCK_NO,\n        'update_time': current_time\n    }\n    result = edit_user(user_id, user_data)\n    return result\n\n\ndef user_reg_stats(time_based='hour'):\n    \"\"\"\n    用户注册统计\n    :return:\n    \"\"\"\n    # 按小时统计\n    if time_based == 'hour':\n        start_time, end_time = get_current_day_time_ends()\n        hours = get_hours(False)\n        hours_zerofill = get_hours()\n        result = dict(zip(hours, [0] * len(hours)))\n        rows = db.session \\\n            .query(func.hour(User.create_time).label('hour'), func.count(User.id)) \\\n            .filter(User.create_time >= time_local_to_utc(start_time),\n                    User.create_time <= time_local_to_utc(end_time)) \\\n            .group_by('hour') \\\n            .limit(len(hours)) \\\n            .all()\n        result.update(dict(rows))\n        return [(hours_zerofill[i], result[hour]) for i, hour in enumerate(hours)]\n    # 按日期统计\n    if time_based == 'date':\n        start_time, end_time = get_current_month_time_ends()\n        today = datetime.today()\n        days = get_days(year=today.year, month=today.month, zerofill=False)\n        days_zerofill = get_days(year=today.year, month=today.month)\n        result = dict(zip(days, [0] * len(days)))\n        rows = db.session \\\n            .query(func.day(User.create_time).label('date'), func.count(User.id)) \\\n            .filter(User.create_time >= time_local_to_utc(start_time),\n                    User.create_time <= time_local_to_utc(end_time)) \\\n            .group_by('date') \\\n            .limit(len(days)) \\\n            .all()\n        result.update(dict(rows))\n        return [(days_zerofill[i], result[day]) for i, day in enumerate(days)]\n    # 按月份统计\n    if time_based == 'month':\n        start_time, end_time = get_current_year_time_ends()\n        months = get_months(False)\n        months_zerofill = get_months()\n        result = dict(zip(months, [0] * len(months)))\n        rows = db.session \\\n            .query(func.month(User.create_time).label('month'), func.count(User.id)) \\\n            .filter(User.create_time >= time_local_to_utc(start_time),\n                    User.create_time <= time_local_to_utc(end_time)) \\\n            .group_by('month') \\\n            .limit(len(months)) \\\n            .all()\n        result.update(dict(rows))\n        return [(months_zerofill[i], result[month]) for i, month in enumerate(months)]\n\n\ndef user_active_stats(time_based='hour'):\n    \"\"\"\n    用户激活统计\n    :return:\n    \"\"\"\n    # 按小时统计\n    if time_based == 'hour':\n        start_time, end_time = get_current_day_time_ends()\n        hours = get_hours(False)\n        hours_zerofill = get_hours()\n        result = dict(zip(hours, [0] * len(hours)))\n        rows = db.session \\\n            .query(func.hour(User.create_time).label('hour'), func.count(User.id)) \\\n            .filter(User.create_time >= time_local_to_utc(start_time),\n                    User.create_time <= time_local_to_utc(end_time),\n                    User.status_active == STATUS_ACTIVE_OK) \\\n            .group_by('hour') \\\n            .limit(len(hours)) \\\n            .all()\n        result.update(dict(rows))\n        return [(hours_zerofill[i], result[hour]) for i, hour in enumerate(hours)]\n    # 按日期统计\n    if time_based == 'date':\n        start_time, end_time = get_current_month_time_ends()\n        today = datetime.today()\n        days = get_days(year=today.year, month=today.month, zerofill=False)\n        days_zerofill = get_days(year=today.year, month=today.month)\n        result = dict(zip(days, [0] * len(days)))\n        rows = db.session \\\n            .query(func.day(User.create_time).label('date'), func.count(User.id)) \\\n            .filter(User.create_time >= time_local_to_utc(start_time),\n                    User.create_time <= time_local_to_utc(end_time),\n                    User.status_active == STATUS_ACTIVE_OK) \\\n            .group_by('date') \\\n            .limit(len(days)) \\\n            .all()\n        result.update(dict(rows))\n        return [(days_zerofill[i], result[day]) for i, day in enumerate(days)]\n    # 按月份统计\n    if time_based == 'month':\n        start_time, end_time = get_current_year_time_ends()\n        months = get_months(False)\n        months_zerofill = get_months()\n        result = dict(zip(months, [0] * len(months)))\n        rows = db.session \\\n            .query(func.month(User.create_time).label('month'), func.count(User.id)) \\\n            .filter(User.create_time >= time_local_to_utc(start_time),\n                    User.create_time <= time_local_to_utc(end_time),\n                    User.status_active == STATUS_ACTIVE_OK) \\\n            .group_by('month') \\\n            .limit(len(months)) \\\n            .all()\n        result.update(dict(rows))\n        return [(months_zerofill[i], result[month]) for i, month in enumerate(months)]\n"
  },
  {
    "path": "app_backend/api/user_auth.py",
    "content": "#!/usr/bin/env python\n# encoding: utf-8\n\n\"\"\"\n@author: zhanghe\n@software: PyCharm\n@file: user_auth.py\n@time: 16-4-28 上午1:04\n\"\"\"\n\n\nfrom app_backend.models import UserAuth\nfrom app_backend.tools.db import get_row, get_rows, get_row_by_id, add, edit, delete, update_rows\n\n\ndef get_user_auth_row_by_id(user_auth_id):\n    \"\"\"\n    通过 id 获取用户信息\n    :param user_auth_id:\n    :return: None/object\n    \"\"\"\n    return get_row_by_id(UserAuth, user_auth_id)\n\n\ndef get_user_auth_row(*args, **kwargs):\n    \"\"\"\n    获取用户信息\n    :param args:\n    :param kwargs:\n    :return: None/object\n    \"\"\"\n    return get_row(UserAuth, *args, **kwargs)\n\n\ndef add_user_auth(user_auth_data):\n    \"\"\"\n    添加用户信息\n    :param user_auth_data:\n    :return: None/Value of user.id\n    \"\"\"\n    return add(UserAuth, user_auth_data)\n\n\ndef edit_user_auth(user_auth_id, user_auth_data):\n    \"\"\"\n    修改用户信息\n    :param user_auth_id:\n    :param user_auth_data:\n    :return: Number of affected rows (Example: 0/1)\n    \"\"\"\n    return edit(UserAuth, user_auth_id, user_auth_data)\n\n\ndef delete_user_auth(user_auth_id):\n    \"\"\"\n    删除用户信息\n    :param user_auth_id:\n    :return: Number of affected rows (Example: 0/1)\n    \"\"\"\n    return delete(UserAuth, user_auth_id)\n\n\ndef get_user_auth_rows(page=1, per_page=10, *args, **kwargs):\n    \"\"\"\n    获取用户列表（分页）\n    Usage:\n        items: 信息列表\n        has_next: 如果本页之后还有超过一个分页，则返回True\n        has_prev: 如果本页之前还有超过一个分页，则返回True\n        next_num: 返回下一页的页码\n        prev_num: 返回上一页的页码\n        iter_pages(): 页码列表\n        iter_pages(left_edge=2, left_current=2, right_current=5, right_edge=2) 页码列表默认参数\n    :param page:\n    :param per_page:\n    :param args:\n    :param kwargs:\n    :return:\n    \"\"\"\n    rows = get_rows(UserAuth, page, per_page, *args, **kwargs)\n    return rows\n\n\ndef update_user_auth_rows(data, *args, **kwargs):\n    \"\"\"\n    批量更新用户信息\n    \"\"\"\n    return update_rows(UserAuth, data, *args, **kwargs)\n"
  },
  {
    "path": "app_backend/api/user_bank.py",
    "content": "#!/usr/bin/env python\n# encoding: utf-8\n\n\"\"\"\n@author: zhanghe\n@software: PyCharm\n@file: user_bank.py\n@time: 2017/4/26 下午1:46\n\"\"\"\n\n\nfrom app_backend.models import UserBank\nfrom app_backend.tools.db import get_row, get_rows, get_row_by_id, add, edit, delete, update_rows\n\n\ndef get_user_bank_row_by_id(user_bank_id):\n    \"\"\"\n    通过 id 获取用户银行信息\n    :param user_bank_id:\n    :return: None/object\n    \"\"\"\n    return get_row_by_id(UserBank, user_bank_id)\n\n\ndef get_user_bank_row(*args, **kwargs):\n    \"\"\"\n    获取用户银行信息\n    :param args:\n    :param kwargs:\n    :return: None/object\n    \"\"\"\n    return get_row(UserBank, *args, **kwargs)\n\n\ndef add_user_bank(user_bank_data):\n    \"\"\"\n    添加用户银行信息\n    :param user_bank_data:\n    :return: None/Value of user.id\n    \"\"\"\n    return add(UserBank, user_bank_data)\n\n\ndef edit_user_bank(user_bank_id, user_bank_data):\n    \"\"\"\n    修改用户银行信息\n    :param user_bank_id:\n    :param user_bank_data:\n    :return: Number of affected rows (Example: 0/1)\n    \"\"\"\n    return edit(UserBank, user_bank_id, user_bank_data)\n\n\ndef delete_user_bank(user_bank_id):\n    \"\"\"\n    删除用户银行信息\n    :param user_bank_id:\n    :return: Number of affected rows (Example: 0/1)\n    \"\"\"\n    return delete(UserBank, user_bank_id)\n\n\ndef get_user_bank_rows(page=1, per_page=10, *args, **kwargs):\n    \"\"\"\n    获取用户银行列表（分页）\n    Usage:\n        items: 信息列表\n        has_next: 如果本页之后还有超过一个分页，则返回True\n        has_prev: 如果本页之前还有超过一个分页，则返回True\n        next_num: 返回下一页的页码\n        prev_num: 返回上一页的页码\n        iter_pages(): 页码列表\n        iter_pages(left_edge=2, left_current=2, right_current=5, right_edge=2) 页码列表默认参数\n    :param page:\n    :param per_page:\n    :param args:\n    :param kwargs:\n    :return:\n    \"\"\"\n    rows = get_rows(UserBank, page, per_page, *args, **kwargs)\n    return rows\n\n\ndef update_user_bank_rows(data, *args, **kwargs):\n    \"\"\"\n    批量更新用户银行信息\n    \"\"\"\n    return update_rows(UserBank, data, *args, **kwargs)\n"
  },
  {
    "path": "app_backend/api/user_config.py",
    "content": "#!/usr/bin/env python\n# encoding: utf-8\n\n\"\"\"\n@author: zhanghe\n@software: PyCharm\n@file: user_config.py\n@time: 2017/6/29 上午11:41\n\"\"\"\n\n\nfrom app_backend.models import UserConfig\nfrom app_backend.tools.db import get_row, get_rows, get_row_by_id, add, edit, merge, delete\n\n\ndef get_user_config_row_by_id(user_config_id):\n    \"\"\"\n    通过 id 获取用户配置信息\n    :param user_config_id:\n    :return: None/object\n    \"\"\"\n    return get_row_by_id(UserConfig, user_config_id)\n\n\ndef get_user_config_row(*args, **kwargs):\n    \"\"\"\n    获取用户配置信息\n    :param args:\n    :param kwargs:\n    :return: None/object\n    \"\"\"\n    return get_row(UserConfig, *args, **kwargs)\n\n\ndef add_user_config(user_config_data):\n    \"\"\"\n    添加用户配置信息\n    :param user_config_data:\n    :return: None/Value of wallet.id\n    \"\"\"\n    return add(UserConfig, user_config_data)\n\n\ndef edit_user_config(user_config_id, user_config_data):\n    \"\"\"\n    修改用户配置信息\n    :param user_config_id:\n    :param user_config_data:\n    :return: Number of affected rows (Example: 0/1)\n    \"\"\"\n    return edit(UserConfig, user_config_id, user_config_data)\n\n\ndef merge_user_config(user_config_data):\n    \"\"\"\n    填充用户配置信息\n    :param user_config_data:\n    :return: Value of PK\n    \"\"\"\n    return merge(UserConfig, user_config_data)\n\n\ndef delete_user_config(user_config_id):\n    \"\"\"\n    删除用户配置信息\n    :param user_config_id:\n    :return: Number of affected rows (Example: 0/1)\n    \"\"\"\n    return delete(UserConfig, user_config_id)\n\n\ndef get_user_config_rows(page=1, per_page=10, *args, **kwargs):\n    \"\"\"\n    获取用户配置列表（分页）\n    Usage:\n        items: 信息列表\n        has_next: 如果本页之后还有超过一个分页，则返回True\n        has_prev: 如果本页之前还有超过一个分页，则返回True\n        next_num: 返回下一页的页码\n        prev_num: 返回上一页的页码\n        iter_pages(): 页码列表\n        iter_pages(left_edge=2, left_current=2, right_current=5, right_edge=2) 页码列表默认参数\n    :param page:\n    :param per_page:\n    :param args:\n    :param kwargs:\n    :return:\n    \"\"\"\n    rows = get_rows(UserConfig, page, per_page, *args, **kwargs)\n    return rows\n\n"
  },
  {
    "path": "app_backend/api/user_profile.py",
    "content": "#!/usr/bin/env python\n# encoding: utf-8\n\n\"\"\"\n@user: zhanghe\n@software: PyCharm\n@file: user_profile.py\n@time: 17-4-29 下午16:36\n\"\"\"\n\n\nfrom app_backend.models import UserProfile\nfrom app_backend.tools.db import get_row, get_rows, get_lists, get_row_by_id, add, edit, delete\nfrom app_common.tools.tree import tree\n\n\ndef get_user_profile_row_by_id(user_id):\n    \"\"\"\n    通过 id 获取用户信息\n    :param user_id:\n    :return: None/object\n    \"\"\"\n    return get_row_by_id(UserProfile, user_id)\n\n\ndef get_user_profile_row(*args, **kwargs):\n    \"\"\"\n    获取用户信息\n    :param args:\n    :param kwargs:\n    :return: None/object\n    \"\"\"\n    return get_row(UserProfile, *args, **kwargs)\n\n\ndef add_user_profile(user_data):\n    \"\"\"\n    添加用户信息\n    :param user_data:\n    :return: None/Value of user.id\n    \"\"\"\n    return add(UserProfile, user_data)\n\n\ndef edit_user_profile(user_id, user_data):\n    \"\"\"\n    修改用户信息\n    :param user_id:\n    :param user_data:\n    :return: Number of affected rows (Example: 0/1)\n    \"\"\"\n    return edit(UserProfile, user_id, user_data)\n\n\ndef delete_user_profile(user_id):\n    \"\"\"\n    删除用户信息\n    :param user_id:\n    :return: Number of affected rows (Example: 0/1)\n    \"\"\"\n    return delete(UserProfile, user_id)\n\n\ndef get_user_profile_rows(page=1, per_page=10, *args, **kwargs):\n    \"\"\"\n    获取用户列表（分页）\n    Usage:\n        items: 信息列表\n        has_next: 如果本页之后还有超过一个分页，则返回True\n        has_prev: 如果本页之前还有超过一个分页，则返回True\n        next_num: 返回下一页的页码\n        prev_num: 返回上一页的页码\n        iter_pages(): 页码列表\n        iter_pages(left_edge=2, left_current=2, right_current=5, right_edge=2) 页码列表默认参数\n    :param page:\n    :param per_page:\n    :param args:\n    :param kwargs:\n    :return:\n    \"\"\"\n    rows = get_rows(UserProfile, page, per_page, *args, **kwargs)\n    return rows\n\n\ndef get_child_users(user_id):\n    \"\"\"\n    获取子节点\n    :param user_id:\n    :return:\n    \"\"\"\n    condition = {\n        'user_pid': user_id\n    }\n    rows = get_lists(UserProfile, **condition)\n    return [(row.user_id, row.nickname, row.type_level) for row in rows]\n\n\ndef get_team_tree_recursion(user_id, team=None, node=None):\n    \"\"\"\n    递归获取用户团队树形结构(深度优先)\n    :param user_id:\n    :param team:\n    :param node:\n    :return:\n    \"\"\"\n    # print '-'*10, user_id, team\n    if not team:\n        team = tree()\n        node = team\n    child_users = get_child_users(user_id)\n    for child_user in child_users:   # 遍历当前所有子节点\n        node[child_user] = {}  # 子节点加入树\n        user_id_next = child_user[0]\n        get_team_tree_recursion(user_id_next, team, node[child_user])  # 递归下一个子节点\n    return team\n"
  },
  {
    "path": "app_backend/api/wallet.py",
    "content": "#!/usr/bin/env python\n# encoding: utf-8\n\n\"\"\"\n@author: zhanghe\n@software: PyCharm\n@file: wallet.py\n@time: 2017/4/25 下午1:29\n\"\"\"\n\n\nfrom app_backend.models import Wallet\nfrom app_backend.tools.db import get_row, get_rows, get_row_by_id, add, edit, delete\n\n\ndef get_wallet_row_by_id(wallet_id):\n    \"\"\"\n    通过 id 获取钱包信息\n    :param wallet_id:\n    :return: None/object\n    \"\"\"\n    return get_row_by_id(Wallet, wallet_id)\n\n\ndef get_wallet_row(*args, **kwargs):\n    \"\"\"\n    获取钱包信息\n    :param args:\n    :param kwargs:\n    :return: None/object\n    \"\"\"\n    return get_row(Wallet, *args, **kwargs)\n\n\ndef add_wallet(wallet_data):\n    \"\"\"\n    添加钱包信息\n    :param wallet_data:\n    :return: None/Value of wallet.id\n    \"\"\"\n    return add(Wallet, wallet_data)\n\n\ndef edit_wallet(wallet_id, wallet_data):\n    \"\"\"\n    修改钱包信息\n    :param wallet_id:\n    :param wallet_data:\n    :return: Number of affected rows (Example: 0/1)\n    \"\"\"\n    return edit(Wallet, wallet_id, wallet_data)\n\n\ndef delete_wallet(wallet_id):\n    \"\"\"\n    删除钱包信息\n    :param wallet_id:\n    :return: Number of affected rows (Example: 0/1)\n    \"\"\"\n    return delete(Wallet, wallet_id)\n\n\ndef get_wallet_rows(page=1, per_page=10, *args, **kwargs):\n    \"\"\"\n    获取钱包列表（分页）\n    Usage:\n        items: 信息列表\n        has_next: 如果本页之后还有超过一个分页，则返回True\n        has_prev: 如果本页之前还有超过一个分页，则返回True\n        next_num: 返回下一页的页码\n        prev_num: 返回上一页的页码\n        iter_pages(): 页码列表\n        iter_pages(left_edge=2, left_current=2, right_current=5, right_edge=2) 页码列表默认参数\n    :param page:\n    :param per_page:\n    :param args:\n    :param kwargs:\n    :return:\n    \"\"\"\n    rows = get_rows(Wallet, page, per_page, *args, **kwargs)\n    return rows\n"
  },
  {
    "path": "app_backend/database.py",
    "content": "#!/usr/bin/env python\n# encoding: utf-8\n\n\"\"\"\n@author: zhanghe\n@software: PyCharm\n@file: database.py\n@time: 17-4-20 下午13:44\n\"\"\"\n\n\nfrom flask_sqlalchemy import SQLAlchemy\nfrom app_backend import app\ndb = SQLAlchemy(app)\n"
  },
  {
    "path": "app_backend/filters.py",
    "content": "#!/usr/bin/env python\n# encoding: utf-8\n\n\"\"\"\n@author: zhanghe\n@software: PyCharm\n@file: filters.py\n@time: 2017/4/13 下午2:33\n@desc: 自定义过滤器\n\"\"\"\n\nimport time\n\nfrom app_backend.api.active import get_active_row_by_id\nfrom app_backend.api.scheduling import get_scheduling_row_by_id\nfrom app_common.maps.role_admin import ROLE_ADMIN_DICT\nfrom app_common.maps.type_active import TYPE_ACTIVE_DICT\nfrom app_common.maps.type_apply import TYPE_APPLY_DICT\nfrom app_common.maps.type_auth import TYPE_AUTH_DICT\nfrom app_common.maps.type_scheduling import TYPE_SCHEDULING_DICT\nfrom app_common.maps.status_audit import STATUS_AUDIT_DICT\nfrom app_common.maps.status_apply import STATUS_APPLY_DICT\nfrom app_common.maps.status_order import STATUS_ORDER_DICT\nfrom app_common.maps.status_delete import STATUS_DEL_DICT\nfrom app_common.maps.status_pay import STATUS_PAY_DICT\nfrom app_common.maps.status_rec import STATUS_REC_DICT\nfrom app_common.maps.type_level import TYPE_LEVEL_DICT\nfrom app_common.maps.status_active import STATUS_ACTIVE_DICT\nfrom app_common.maps.status_lock import STATUS_LOCK_DICT\nfrom app_backend import app\nfrom app_backend.views.user import get_user_profile_row_by_id\nfrom app_common.maps.type_order import TYPE_ORDER_DICT\n\n\n@app.template_filter('reverse')\ndef reverse_filter(s):\n    return s[::-1]\n\n\n@app.template_filter('url_t')\ndef url_t_filter(s):\n    return '%s?t=%s' % (s, time.time())\n\n\n@app.template_filter('time_diff_pretty')\ndef time_diff_pretty_filter(delta_s):\n    \"\"\"\n    时间差友好显示\n    {{ 1234 | time_diff_pretty }} >> 2分34秒\n    :param delta_s:\n    :return:\n    \"\"\"\n    delta_s *= 1.00\n    result = u''\n    if delta_s >= (365 * 24 * 60 * 60):\n        count = int(delta_s / (365 * 24 * 60 * 60))\n        result += u'%s年' % count\n        delta_s -= count * 365 * 24 * 60 * 60\n    if delta_s >= (30 * 24 * 60 * 60):\n        count = int(delta_s / (30 * 24 * 60 * 60))\n        result += u'%s月' % count\n        delta_s -= count * 30 * 24 * 60 * 60\n    if delta_s >= (24 * 60 * 60):\n        count = int(delta_s / (24 * 60 * 60))\n        result += u'%s天' % count\n        delta_s -= count * 24 * 60 * 60\n    if delta_s >= (60 * 60):\n        count = int(delta_s / (60 * 60))\n        result += u'%s小时' % count\n        delta_s -= count * 60 * 60\n    if delta_s >= 60:\n        count = int(delta_s / 60)\n        result += u'%s分' % count\n        delta_s -= count * 60\n    if delta_s > 0:\n        count = int(delta_s)\n        result += u'%s秒' % count\n    return result\n\n\n@app.template_filter('nickname')\ndef filter_nickname(user_id):\n    \"\"\"\n    显示用户名称\n    :param user_id:\n    :return:\n    \"\"\"\n    user_info = get_user_profile_row_by_id(user_id)\n    return user_info.nickname if user_info else u'系统用户'\n\n\n@app.template_filter('user_active')\ndef filter_user_active(user_id):\n    \"\"\"\n    用户激活码量\n    :param user_id:\n    :return:\n    \"\"\"\n    if not user_id:\n        return 0\n    row = get_active_row_by_id(user_id)\n    return row.amount if row else 0\n\n\n@app.template_filter('role_admin')\ndef filter_role_admin(role_admin_id):\n    \"\"\"\n    管理后台显示管理账号角色\n    :param role_admin_id:\n    :return:\n    \"\"\"\n    return ROLE_ADMIN_DICT.get(role_admin_id, u'')\n\n\n@app.template_filter('type_apply')\ndef filter_type_apply(type_apply_id):\n    \"\"\"\n    申请类型\n    :param type_apply_id:\n    :return:\n    \"\"\"\n    return TYPE_APPLY_DICT.get(type_apply_id, u'')\n\n\n@app.template_filter('type_order')\ndef filter_type_order(type_order_id):\n    \"\"\"\n    订单类型\n    :param type_order_id:\n    :return:\n    \"\"\"\n    return TYPE_ORDER_DICT.get(type_order_id, u'')\n\n\n@app.template_filter('type_auth')\ndef filter_type_auth(type_auth_id):\n    \"\"\"\n    认证类型\n    :param type_auth_id:\n    :return:\n    \"\"\"\n    return TYPE_AUTH_DICT.get(type_auth_id, u'')\n\n\n@app.template_filter('type_active')\ndef filter_type_active(type_active_id):\n    \"\"\"\n    激活类型\n    :param type_active_id:\n    :return:\n    \"\"\"\n    return TYPE_ACTIVE_DICT.get(type_active_id, u'')\n\n\n@app.template_filter('type_scheduling')\ndef filter_type_scheduling(type_scheduling_id):\n    \"\"\"\n    排单类型\n    :param type_scheduling_id:\n    :return:\n    \"\"\"\n    return TYPE_SCHEDULING_DICT.get(type_scheduling_id, u'')\n\n\n@app.template_filter('status_apply')\ndef filter_status_apply(status_apply_id):\n    \"\"\"\n    申请状态\n    :param status_apply_id:\n    :return:\n    \"\"\"\n    return STATUS_APPLY_DICT.get(status_apply_id, u'')\n\n\n@app.template_filter('status_audit')\ndef filter_status_audit(status_audit_id):\n    \"\"\"\n    审核状态\n    :param status_audit_id:\n    :return:\n    \"\"\"\n    return STATUS_AUDIT_DICT.get(status_audit_id, u'')\n\n\n@app.template_filter('status_order')\ndef filter_status_order(status_order_id):\n    \"\"\"\n    订单状态\n    :param status_order_id:\n    :return:\n    \"\"\"\n    return STATUS_ORDER_DICT.get(status_order_id, u'')\n\n\n@app.template_filter('status_delete')\ndef filter_status_delete(status_delete_id):\n    \"\"\"\n    删除状态\n    :param status_delete_id:\n    :return:\n    \"\"\"\n    return STATUS_DEL_DICT.get(status_delete_id, u'')\n\n\n@app.template_filter('status_pay')\ndef filter_status_pay(status_pay_id):\n    \"\"\"\n    支付状态\n    :param status_pay_id:\n    :return:\n    \"\"\"\n    return STATUS_PAY_DICT.get(status_pay_id, u'')\n\n\n@app.template_filter('status_rec')\ndef filter_status_rec(status_rec_id):\n    \"\"\"\n    收款状态\n    :param status_rec_id:\n    :return:\n    \"\"\"\n    return STATUS_REC_DICT.get(status_rec_id, u'')\n\n\n@app.template_filter('type_level')\ndef filter_type_level(type_level_id):\n    \"\"\"\n    等级类型\n    :param type_level_id:\n    :return:\n    \"\"\"\n    return TYPE_LEVEL_DICT.get(type_level_id, u'')\n\n\n@app.template_filter('status_active')\ndef filter_status_active(status_active_id):\n    \"\"\"\n    激活状态\n    :param status_active_id:\n    :return:\n    \"\"\"\n    return STATUS_ACTIVE_DICT.get(status_active_id, u'')\n\n\n@app.template_filter('status_lock')\ndef filter_status_lock(status_lock_id):\n    \"\"\"\n    锁定状态\n    :param status_lock_id:\n    :return:\n    \"\"\"\n    return STATUS_LOCK_DICT.get(status_lock_id, u'')\n\n\n@app.template_filter('scheduling_amount')\ndef filter_scheduling_amount(user_id):\n    \"\"\"\n    排单剩余次数\n    :param user_id:\n    :return:\n    \"\"\"\n    if not user_id:\n        return 0\n    row = get_scheduling_row_by_id(user_id)\n    return row.amount if row else 0\n"
  },
  {
    "path": "app_backend/forms/__init__.py",
    "content": "#!/usr/bin/env python\n# encoding: utf-8\n\n\"\"\"\n@author: zhanghe\n@software: PyCharm\n@file: __init__.py.py\n@time: 2017/4/9 上午10:13\n\"\"\"\n\n\nfrom wtforms import SelectField, BooleanField\nfrom wtforms.widgets import HTMLString\nfrom wtforms.compat import text_type, iteritems\nfrom wtforms.widgets import html_params\n\n\ndef select_multi_checkbox(field, ul_class='', **kwargs):\n    \"\"\"\n    多选框控件\n    :param field:\n    :param ul_class:\n    :param kwargs:\n    :return:\n    \"\"\"\n    kwargs.setdefault('type', 'checkbox')\n    field_id = kwargs.pop('id', field.id)\n    html = [u'<ul %s>' % html_params(id=field_id, class_=ul_class)]\n    for value, label, checked in field.iter_choices():\n        choice_id = u'%s-%s' % (field_id, value)\n        options = dict(kwargs, name=field.name, value=value, id=choice_id)\n        if checked:\n            options['checked'] = 'checked'\n        html.append(u'<li><input %s /> ' % html_params(**options))\n        html.append(u'<label for=\"%s\">%s</label></li>' % (field_id, label))\n    html.append(u'</ul>')\n    return u''.join(html)\n\n\nclass SelectBSWidget(object):\n    \"\"\"\n    自定义选择组件\n    \"\"\"\n    def __call__(self, field, **kwargs):\n        params = {\n            'id': field.id,\n            'name': field.id,\n            'class': 'selectpicker show-tick',\n            # 'data-live-search': 'true',\n            'title': kwargs.pop('placeholder', 'Choose one of the following...'),\n            'data-header': kwargs.pop('data_header', 'Select a condiment'),\n            'data-width': kwargs.pop('data_width', 'auto')\n        }\n        html = ['<select %s>' % html_params(**params)]\n        for k, v in field.choices:\n            html.append('<option value=\"%s\" data-subtext=\"[%s]\">%s</option>' % (k, k, v))\n        html.append('</select>')\n        return HTMLString('\\n'.join(html))\n\n\nclass SelectBS(SelectField):\n    \"\"\"\n    自定义选择表单控件\n    \"\"\"\n    widget = SelectBSWidget()\n\n    def pre_validate(self, form):\n        \"\"\"\n        校验表单传值是否合法\n        \"\"\"\n        for v, _ in self.choices:\n            # print self.data, v, type(self.data), type(v)\n            if str(self.data) == str(v):\n                break\n        else:\n            raise ValueError(self.gettext('Not a valid choice'))\n\n\nclass CheckBoxBSWidget(object):\n    \"\"\"\n    自定义复选框组件\n    \"\"\"\n    input_type = 'checkbox'\n\n    def __call__(self, field, **kwargs):\n        if getattr(field, 'checked', field.data):\n            kwargs['checked'] = True\n        kwargs.setdefault('id', field.id)\n        kwargs.setdefault('type', self.input_type)\n        if 'value' not in kwargs:\n            kwargs['value'] = 1\n        html = [\n            '<div class=\"checkbox\">',\n            '<label>',\n            '<input %s>' % html_params(name=field.name, **kwargs),\n            '</label>',\n            '</div>'\n        ]\n        return HTMLString('\\n'.join(html))\n\n\nclass CheckBoxBS(BooleanField):\n    \"\"\"\n    自定义复选框控件\n    \"\"\"\n    widget = CheckBoxBSWidget()\n\n\nclass SelectAreaCodeWidget(object):\n    \"\"\"\n    自定义选择组件 - 区号\n    \"\"\"\n    def __call__(self, field, **kwargs):\n        params = {\n            'id': field.id,\n            'name': field.id,\n            'class': 'selectpicker show-tick',\n            'data-live-search': 'true',\n            'title': kwargs.pop('title', 'Choose one of the following...'),\n            'data-header': kwargs.pop('data-header', 'Select a condiment'),\n        }\n        html = ['<select %s>' % html_params(**params)]\n        for _, area_data in field.choices:\n            for area_name, area_list in area_data.items():\n                html.append('\\t<optgroup label=\"%s\">' % area_name)\n                for country_data in area_list:\n                    # html.append('\\t\\t<option value=\"%s\" data-subtext=\"%s(%s)\">[%s] %s</option>' % (country_data['id'], country_data['name_c'], country_data['name_e'], country_data['short_code'], country_data['phone_pre']))\n                    html.append('\\t\\t<option value=\"%s\" data-subtext=\"%s\">[%s] %s</option>' % (country_data['id'], country_data['name_c'], country_data['short_code'], country_data['phone_pre']))\n                html.append('\\t</optgroup>')\n        html.append('</select>')\n        return HTMLString('\\n'.join(html))\n\n\nclass SelectAreaCode(SelectField):\n    \"\"\"\n    自定义选择表单控件\n    \"\"\"\n    widget = SelectAreaCodeWidget()\n\n    def pre_validate(self, form):\n        \"\"\"\n        校验表单传值是否合法\n        \"\"\"\n        is_find = False\n        for _, area_data in self.choices:\n            for area_list in area_data.values():\n                if self.data in [str(i['id']) for i in area_list]:\n                    is_find = True\n                    break\n            if is_find:\n                break\n        else:\n            raise ValueError(self.gettext('Not a valid choice'))\n"
  },
  {
    "path": "app_backend/forms/active.py",
    "content": "#!/usr/bin/env python\n# encoding: utf-8\n\n\"\"\"\n@author: zhanghe\n@software: PyCharm\n@file: active.py\n@time: 2017/6/1 下午2:42\n\"\"\"\n\n\nfrom flask_login import current_user\nfrom flask_wtf import FlaskForm\nfrom wtforms import StringField, PasswordField, BooleanField, DateField, DateTimeField, DecimalField, IntegerField\nfrom wtforms.validators import DataRequired, Length, NumberRange, EqualTo, Email, ValidationError, IPAddress\n\nfrom app_common.maps.status_delete import *\nfrom app_common.maps.type_auth import *\nfrom app_backend.api.user import get_user_row_by_id\nfrom app_backend.api.user_auth import get_user_auth_row\nfrom app_backend.api.user_profile import get_user_profile_row_by_id\n\n\nclass UserRightValidate(object):\n    \"\"\"\n    用户权限校验\n    \"\"\"\n    def __init__(self, message=None):\n        self.message = message\n\n    def __call__(self, form, field):\n        # 用户异常处理\n        user_info = get_user_row_by_id(field.data)\n\n        if not user_info:\n            raise ValidationError(u'异常操作，此用户不存在')\n        if user_info.status_delete == int(STATUS_DEL_OK):\n            raise ValidationError(u'异常操作，此用户已删除')\n\n        user_profile_info = get_user_profile_row_by_id(field.data)\n        if not user_profile_info:\n            raise ValidationError(u'异常操作，此用户不存在')\n\n\nclass ActiveAddForm(FlaskForm):\n    \"\"\"\n    激活添加表单\n    \"\"\"\n    user_id = StringField(u'赠送用户ID', validators=[\n        DataRequired(message=u'赠送用户ID不能为空'),\n        UserRightValidate()\n    ])\n    amount = IntegerField(u'赠送数量', validators=[\n        DataRequired(message=u'赠送数量必须为整数'),\n        NumberRange(min=1, message=u'赠送数量必须为整数')\n    ])\n\n\n"
  },
  {
    "path": "app_backend/forms/admin.py",
    "content": "#!/usr/bin/env python\n# encoding: utf-8\n\n\"\"\"\n@author: zhanghe\n@software: PyCharm\n@file: user.py\n@time: 2017/3/17 下午11:49\n\"\"\"\n\n\nfrom flask_wtf import FlaskForm\nfrom wtforms import StringField, PasswordField, BooleanField, DateField, DateTimeField, HiddenField\nfrom wtforms.validators import DataRequired, Length, NumberRange, EqualTo, Email, ValidationError, IPAddress\n\nfrom app_common.maps import area_code_list, role_admin_list\nfrom app_backend.api.admin import get_admin_row\nfrom app_backend.forms import SelectAreaCode, SelectBS\n\n\ndef reg_username_repeat(form, field):\n    \"\"\"\n    登录账号重复校验\n    \"\"\"\n    condition = {\n        'username': field.data\n    }\n    row = get_admin_row(**condition)\n    if row:\n        raise ValidationError(u'登录账号重复')\n\n\ndef password_edit_validator(form, field):\n    \"\"\"\n    密码修改表单校验\n    :param form:\n    :param field:\n    :return:\n    \"\"\"\n    field_data_length = len(field.data) if field.data else 0\n    if field_data_length > 0 and (field_data_length < 6 or field_data_length > 20):\n        raise ValidationError(u'密码长度不符')\n\n\nclass AdminProfileForm(FlaskForm):\n    \"\"\"\n    管理员基本信息表单\n    \"\"\"\n    id = HiddenField('Id')\n    username = StringField(u'管理账号', validators=[DataRequired(), Length(min=2, max=20)])\n    password = StringField(u'登录密码', validators=[password_edit_validator])\n    area_code_choices = []\n    for m, n in enumerate(area_code_list):\n        area_code_choices.append((m, n))\n    area_id = SelectAreaCode(u'手机区号', default='0', choices=area_code_choices, validators=[DataRequired()])\n    phone = StringField(u'手机号码')\n    role_id = SelectBS(u'管理角色', default='', choices=role_admin_list, validators=[DataRequired(u'管理角色不能为空')])\n    login_ip = StringField(u'登录IP')\n    login_time = DateTimeField(u'登录时间')\n    create_time = DateTimeField(u'创建时间')\n    update_time = DateTimeField(u'更新时间')\n\n\nclass AdminAddForm(FlaskForm):\n    \"\"\"\n    管理员添加表单\n    \"\"\"\n    username = StringField(u'管理账号', validators=[DataRequired(), Length(min=2, max=20)])\n    password = StringField(u'登录密码', validators=[DataRequired(), Length(min=6, max=20)])\n    area_code_choices = []\n    for m, n in enumerate(area_code_list):\n        area_code_choices.append((m, n))\n    area_id = SelectAreaCode(u'手机区号', default='0', choices=area_code_choices, validators=[DataRequired()])\n    phone = StringField(u'手机号码')\n    role_id = SelectBS(u'管理角色', default='', choices=role_admin_list, validators=[DataRequired(u'管理角色不能为空')])\n    login_ip = StringField(u'登录IP')\n    login_time = DateTimeField(u'Login Time')\n\n\nclass AdminEditForm(FlaskForm):\n    \"\"\"\n    管理员编辑表单\n    \"\"\"\n    id = HiddenField('Id')\n    username = StringField(u'管理账号', validators=[DataRequired(), Length(min=2, max=20)])\n    password = StringField(u'登录密码', validators=[password_edit_validator])\n    area_code_choices = []\n    for m, n in enumerate(area_code_list):\n        area_code_choices.append((m, n))\n    area_id = SelectAreaCode(u'手机区号', default='0', choices=area_code_choices, validators=[DataRequired()])\n    phone = StringField(u'手机号码')\n    role_id = SelectBS(u'管理角色', default='', choices=role_admin_list, validators=[DataRequired(u'管理角色不能为空')])\n    login_ip = StringField(u'登录IP')\n    login_time = DateTimeField(u'登录时间')\n    create_time = DateTimeField(u'创建时间')\n    update_time = DateTimeField(u'更新时间')\n\n\nclass AdminRoleForm(FlaskForm):\n    \"\"\"\n    管理员角色表单\n    \"\"\"\n    role_id = SelectBS(u'管理角色', default='', choices=role_admin_list, validators=[DataRequired(u'管理角色不能为空')])\n    name = StringField(u'模块权限')\n    note = StringField(u'权限备注')\n    module = StringField(u'模块权限')\n    create_time = DateTimeField(u'创建时间')\n    update_time = DateTimeField(u'更新时间')\n\n\nclass EditPassword(FlaskForm):\n    \"\"\"\n    修改用户密码\n    \"\"\"\n    password = PasswordField('New Password', validators=[\n        DataRequired(),\n        Length(min=6, max=40),\n        EqualTo('confirm', message='Passwords must match')\n    ])\n    confirm = PasswordField('Repeat Password', validators=[\n        DataRequired(),\n        Length(min=6, max=40)\n    ])\n\n"
  },
  {
    "path": "app_backend/forms/apply_get.py",
    "content": "#!/usr/bin/env python\n# encoding: utf-8\n\n\"\"\"\n@author: zhanghe\n@software: PyCharm\n@file: apply_get.py\n@time: 2017/4/13 下午9:31\n\"\"\"\n\n\nfrom flask_wtf import FlaskForm\nfrom wtforms import StringField, PasswordField, BooleanField, DateField, DateTimeField\nfrom wtforms.validators import DataRequired, Length, NumberRange, EqualTo, Email, ValidationError, IPAddress\nfrom app_backend.api.user_auth import get_user_auth_row\nfrom app_backend.forms import SelectBS\nfrom app_common.maps import type_apply_list\nfrom app_common.maps import status_apply_list\nfrom app_common.maps import status_order_list\nfrom app_common.maps import status_delete_list\n\n\nclass ApplyGetSearchForm(FlaskForm):\n    \"\"\"\n    提现申请搜索表单\n    \"\"\"\n    apply_get_id = StringField('Apply Get Id')\n    user_id = StringField('User Id')\n    type_apply = SelectBS('Type Apply', default='', choices=type_apply_list)\n    money_apply = StringField('Type Apply')\n    status_apply = SelectBS('Type Apply', default='', choices=status_apply_list)\n    status_order = SelectBS('Status Order', default='', choices=status_order_list)\n    status_delete = SelectBS('Status Delete', default='', choices=status_delete_list)\n    min_money = StringField(u'最小金额')\n    max_money = StringField(u'最大金额')\n    start_time = StringField(u'开始时间')\n    end_time = StringField(u'结束时间')\n"
  },
  {
    "path": "app_backend/forms/apply_put.py",
    "content": "#!/usr/bin/env python\n# encoding: utf-8\n\n\"\"\"\n@author: zhanghe\n@software: PyCharm\n@file: apply_put.py\n@time: 2017/4/13 下午9:31\n\"\"\"\n\n\nfrom flask_wtf import FlaskForm\nfrom wtforms import StringField, PasswordField, BooleanField, DateField, DateTimeField\nfrom wtforms.validators import DataRequired, Length, NumberRange, EqualTo, Email, ValidationError, IPAddress\nfrom app_backend.api.user_auth import get_user_auth_row\nfrom app_backend.forms import SelectBS\nfrom app_common.maps import type_apply_list\nfrom app_common.maps import status_apply_list\nfrom app_common.maps import status_order_list\nfrom app_common.maps import status_delete_list\n\n\nclass ApplyPutSearchForm(FlaskForm):\n    \"\"\"\n    投资申请搜索表单\n    \"\"\"\n    apply_put_id = StringField('Apply Put Id')\n    user_id = StringField('User Id')\n    type_apply = SelectBS('Type Apply', default='', choices=type_apply_list)\n    money_apply = StringField('Type Apply')\n    status_apply = SelectBS('Type Apply', default='', choices=status_apply_list)\n    status_order = SelectBS('Status Order', default='', choices=status_order_list)\n    status_delete = SelectBS('Status Delete', default='', choices=status_delete_list)\n    min_money = StringField(u'最小金额')\n    max_money = StringField(u'最大金额')\n    start_time = StringField(u'开始时间')\n    end_time = StringField(u'结束时间')\n"
  },
  {
    "path": "app_backend/forms/blog.py",
    "content": "#!/usr/bin/env python\n# encoding: utf-8\n\n\"\"\"\n@author: zhanghe\n@software: PyCharm\n@file: blog.py\n@time: 2017/3/10 下午11:00\n\"\"\"\n\n\nfrom flask_wtf import FlaskForm\nfrom wtforms import StringField, PasswordField, BooleanField, DateField, DateTimeField\nfrom wtforms.validators import DataRequired, Length, NumberRange, EqualTo, Email, ValidationError, IPAddress\n\n\nclass BlogAddForm(FlaskForm):\n    \"\"\"\n    Blog 添加表单\n    \"\"\"\n    author = StringField('Author', validators=[DataRequired()])\n    title = StringField('Title', validators=[DataRequired(), Length(max=40)])\n    pub_date = DateField('Pub Date', validators=[DataRequired()])\n\n\nclass BlogEditForm(FlaskForm):\n    \"\"\"\n    Blog 编辑表单\n    \"\"\"\n    author = StringField('Author', validators=[DataRequired()])\n    title = StringField('Title', validators=[DataRequired(), Length(max=40)])\n    pub_date = DateField('Pub Date', validators=[DataRequired()])\n"
  },
  {
    "path": "app_backend/forms/complaint.py",
    "content": "#!/usr/bin/env python\n# encoding: utf-8\n\n\"\"\"\n@author: zhanghe\n@software: PyCharm\n@file: complaint.py\n@time: 2017/6/24 下午11:13\n\"\"\"\n\n\nfrom flask_login import current_user\nfrom flask_wtf import FlaskForm\nfrom wtforms import StringField, TextAreaField, PasswordField, BooleanField, DateField, DateTimeField, DecimalField, IntegerField, HiddenField\nfrom wtforms.validators import DataRequired, Length, NumberRange, EqualTo, Email, ValidationError, IPAddress\n\n\nclass ComplaintReplyForm(FlaskForm):\n    \"\"\"\n    投诉回复表单\n    \"\"\"\n    id = StringField(u'投诉明细ID')\n    send_user_id = StringField(u'投诉用户')\n    receive_user_id = StringField(u'被投诉用户')\n    content = TextAreaField(u'投诉内容', validators=[\n        DataRequired(message=u'投诉内容不能为空'),\n        Length(min=2, message=u'请输入有效的投诉内容'),\n        Length(max=512, message=u'投诉内容超出长度限制'),\n    ])\n    content_reply = TextAreaField(u'回复内容', validators=[\n        DataRequired(message=u'回复内容不能为空'),\n        Length(min=2, message=u'请输入有效的回复内容'),\n        Length(max=512, message=u'回复内容超出长度限制'),\n    ])\n"
  },
  {
    "path": "app_backend/forms/login.py",
    "content": "#!/usr/bin/env python\n# encoding: utf-8\n\n\"\"\"\n@author: zhanghe\n@software: PyCharm\n@file: login.py\n@time: 2017/3/10 下午10:49\n\"\"\"\n\n\nimport re\nfrom flask import session\nfrom flask_wtf import FlaskForm\nfrom wtforms import StringField, PasswordField, BooleanField, DateField, DateTimeField\nfrom wtforms.validators import DataRequired, Length, NumberRange, EqualTo, Email, ValidationError, IPAddress\nfrom app_backend.api.user_auth import get_user_auth_row\nfrom app_backend import app\n\n\nclass SmsCodeValidate(object):\n    \"\"\"\n    短信验证码校验\n    \"\"\"\n    def __init__(self, message=None):\n        self.message = message\n\n        self._reg = re.compile(ur'^\\d{6}$')\n\n    def __call__(self, form, field):\n        data = field.data\n        if not self._reg.match(data):\n            raise ValidationError(self.message or u\"短信验证码格式错误\")\n\n        code_key = '%s:%s' % ('sms_code', 'login')\n        # print session.get(code_key), type(session.get(code_key)), data, type(data)\n        # 测试模式下，跳过验证\n        if not app.config.get('TEST') and session.get(code_key) != data:\n            raise ValidationError(self.message or u\"短信验证码校验错误\")\n\n\nclass LoginForm(FlaskForm):\n    \"\"\"\n    账号登录表单\n    \"\"\"\n    account = StringField(u'登录账号', validators=[\n        DataRequired(u'登录账号不能为空'),\n        Length(min=2, max=20, message=u'登录账号长度不符')\n    ])\n    password = PasswordField(u'登录密码', validators=[\n        DataRequired(u'密码不能为空'),\n        Length(min=6, max=20, message=u'密码长度不符')\n    ])\n    sms = StringField(u'短信验证码', validators=[\n        DataRequired(u'短信验证码不能为空'),\n        Length(min=6, max=6, message=u'短信验证码长度不符'),\n        SmsCodeValidate()\n    ])\n    remember = BooleanField('Remember Me', default=False)\n"
  },
  {
    "path": "app_backend/forms/order.py",
    "content": "#!/usr/bin/env python\n# encoding: utf-8\n\n\"\"\"\n@author: zhanghe\n@software: PyCharm\n@file: order.py\n@time: 2017/4/13 下午9:32\n\"\"\"\n\n\nfrom flask_wtf import FlaskForm\nfrom wtforms import StringField, PasswordField, BooleanField, DateField, DateTimeField\nfrom wtforms.validators import DataRequired, Length, NumberRange, EqualTo, Email, ValidationError, IPAddress\nfrom app_backend.api.user_auth import get_user_auth_row\nfrom app_backend.forms import SelectBS\nfrom app_common.maps import status_audit_list\nfrom app_common.maps import status_pay_list\nfrom app_common.maps import status_rec_list\n\n\nclass OrderSearchForm(FlaskForm):\n    \"\"\"\n    订单搜索表单\n    \"\"\"\n    order_id = StringField(U'订单ID')\n    apply_put_id = StringField(u'申请投资ID')      # 申请投资Id\n    apply_get_id = StringField(u'申请提现ID')      # 申请提现Id\n    apply_put_uid = StringField(u'申请投资用户ID')    # 申请投资用户Id\n    apply_get_uid = StringField(u'申请提现用户ID')    # 申请提现用户Id\n    status_audit = SelectBS('Status Audit', default='', choices=status_audit_list)      # 审核状态:0:待审核，1:审核通过，2:审核失败\n    status_pay = SelectBS('Status Pay', default='', choices=status_pay_list)            # 支付状态:0:待支付，1:支付成功，2:支付失败\n    status_rec = SelectBS('Status Rec', default='', choices=status_rec_list)            # 收款状态:0:待收款，1:收款成功，2:收款失败\n    start_time = StringField('Start Time')\n    end_time = StringField('End Time')\n"
  },
  {
    "path": "app_backend/forms/pay.py",
    "content": "#!/usr/bin/env python\n# encoding: utf-8\n\n\"\"\"\n@author: zhanghe\n@software: PyCharm\n@file: pay.py\n@time: 2017/3/18 上午12:29\n\"\"\"\n\n\ndef func():\n    pass\n\n\nclass Main(object):\n    def __init__(self):\n        pass\n\n\nif __name__ == '__main__':\n    pass\n"
  },
  {
    "path": "app_backend/forms/scheduling.py",
    "content": "#!/usr/bin/env python\n# encoding: utf-8\n\n\"\"\"\n@author: zhanghe\n@software: PyCharm\n@file: scheduling.py\n@time: 2017/6/29 下午8:46\n\"\"\"\n\n\nfrom flask_login import current_user\nfrom flask_wtf import FlaskForm\nfrom wtforms import StringField, PasswordField, BooleanField, DateField, DateTimeField, DecimalField, IntegerField\nfrom wtforms.validators import DataRequired, Length, NumberRange, EqualTo, Email, ValidationError, IPAddress\n\nfrom app_common.maps.status_delete import *\nfrom app_common.maps.type_auth import *\nfrom app_backend.api.user import get_user_row_by_id\nfrom app_backend.api.user_auth import get_user_auth_row\nfrom app_backend.api.user_profile import get_user_profile_row_by_id\n\n\nclass UserRightValidate(object):\n    \"\"\"\n    用户权限校验\n    \"\"\"\n    def __init__(self, message=None):\n        self.message = message\n\n    def __call__(self, form, field):\n        # 用户异常处理\n        user_info = get_user_row_by_id(field.data)\n\n        if not user_info:\n            raise ValidationError(u'异常操作，此用户不存在')\n        if user_info.status_delete == int(STATUS_DEL_OK):\n            raise ValidationError(u'异常操作，此用户已删除')\n\n        user_profile_info = get_user_profile_row_by_id(field.data)\n        if not user_profile_info:\n            raise ValidationError(u'异常操作，此用户不存在')\n\n\nclass SchedulingAddForm(FlaskForm):\n    \"\"\"\n    排单币添加表单\n    \"\"\"\n    user_id = StringField(u'用户ID', validators=[\n        DataRequired(message=u'用户ID不能为空'),\n        UserRightValidate()\n    ])\n    amount = IntegerField(u'添加数量', validators=[\n        DataRequired(message=u'添加数量必须为整数'),\n        NumberRange(min=1, message=u'添加数量必须为整数')\n    ])\n"
  },
  {
    "path": "app_backend/forms/score.py",
    "content": "#!/usr/bin/env python\n# encoding: utf-8\n\n\"\"\"\n@author: zhanghe\n@software: PyCharm\n@file: score.py\n@time: 2017/4/25 下午1:25\n\"\"\"\n\n\ndef func():\n    pass\n\n\nclass Main(object):\n    def __init__(self):\n        pass\n\n\nif __name__ == '__main__':\n    pass\n"
  },
  {
    "path": "app_backend/forms/settings.py",
    "content": "#!/usr/bin/env python\n# encoding: utf-8\n\n\"\"\"\n@author: zhanghe\n@software: PyCharm\n@file: settings.py\n@time: 2017/6/4 上午11:53\n\"\"\"\n\n\nfrom flask_wtf import FlaskForm\nfrom wtforms import StringField, PasswordField, BooleanField, DateField, DateTimeField, HiddenField, IntegerField, DecimalField\nfrom wtforms.validators import DataRequired, InputRequired, Length, NumberRange, EqualTo, Email, ValidationError, IPAddress, AnyOf\n\nfrom app_backend.forms import SelectAreaCode, CheckBoxBS\n\n\nclass SwitchForm(FlaskForm):\n    \"\"\"\n    开关配置表单\n    SWITCH_EXPORT = OFF         # 导出\n\n    SWITCH_REG_ACCOUNT = ON     # 用户账号注册\n    SWITCH_REG_PHONE = OFF      # 用户手机注册\n    SWITCH_REG_EMAIL = OFF      # 用户邮箱注册\n\n    SWITCH_REG_THREE_PART = OFF     # 第三方平台注册\n\n    SWITCH_LOGIN_ACCOUNT = ON   # 用户账号登录\n    SWITCH_LOGIN_PHONE = ON     # 用户手机登录\n    SWITCH_LOGIN_EMAIL = ON     # 用户邮箱登录\n\n    SWITCH_LOGIN_THREE_PART = OFF     # 第三方平台登录\n    \"\"\"\n    SWITCH_EXPORT = CheckBoxBS(u'导出开关')\n\n    SWITCH_REG_ACCOUNT = CheckBoxBS(u'用户账号注册')\n    SWITCH_REG_PHONE = CheckBoxBS(u'用户手机注册')\n    SWITCH_REG_EMAIL = CheckBoxBS(u'用户邮箱注册')\n    SWITCH_REG_THREE_PART = CheckBoxBS(u'第三方平台注册')\n\n    SWITCH_LOGIN_ACCOUNT = CheckBoxBS(u'用户账号登录')\n    SWITCH_LOGIN_PHONE = CheckBoxBS(u'用户手机登录')\n    SWITCH_LOGIN_EMAIL = CheckBoxBS(u'用户邮箱登录')\n    SWITCH_LOGIN_THREE_PART = CheckBoxBS(u'第三方平台登录')\n\n\nclass UserForm(FlaskForm):\n    \"\"\"\n    用户配置表单\n    LOCK_REG_NOT_ACTIVE_TTL = 3600*24*3     # 注册后3天内未激活\n    LOCK_ACTIVE_NOT_PUT_TTL = 3600*24*3     # 激活后3天内未排单\n    LOCK_ORDER_NOT_PAY_TTL = 3600*48        # 匹配后超过48小时不打款\n    LOCK_PAY_NOT_REC_TTL = 3600*48          # 收款后48小时不确认\n    \"\"\"\n    LOCK_REG_NOT_ACTIVE_TTL = IntegerField(u'注册未激活时间', validators=[\n        DataRequired(u'时间不能为空'),\n        NumberRange(min=0, message=u'时间必须为正数')\n    ])\n    LOCK_ACTIVE_NOT_PUT_TTL = IntegerField(u'激活未排单时间', validators=[\n        DataRequired(u'时间不能为空'),\n        NumberRange(min=0, message=u'时间必须为正数')\n    ])\n    LOCK_ORDER_NOT_PAY_TTL = IntegerField(u'匹配未付款时间', validators=[\n        DataRequired(u'时间不能为空'),\n        NumberRange(min=0, message=u'时间必须为正数')\n    ])\n    LOCK_PAY_NOT_REC_TTL = IntegerField(u'收款未确认时间', validators=[\n        DataRequired(u'时间不能为空'),\n        NumberRange(min=0, message=u'时间必须为正数')\n    ])\n\n\nclass OrderForm(FlaskForm):\n    \"\"\"\n    订单配置\n    # 订单限制\n    ORDER_MAX_AMOUNT = 10000  # 订单最大金额\n    ORDER_MAX_COUNT = 100  # 订单最大数量\n\n    # 推广奖励\n\n    BONUS_DIRECT = 0.03  # 直接推荐奖励\n\n    BONUS_LEVEL_FIRST = 0.05        # 一级推荐奖励\n    BONUS_LEVEL_SECOND = 0.05       # 二级推荐奖励\n    BONUS_LEVEL_THIRD = 0.03        # 三级推荐奖励\n    \"\"\"\n    # 订单限制\n    ORDER_MAX_AMOUNT = IntegerField(u'订单最大金额', validators=[\n        DataRequired(u'金额不能为空'),\n        NumberRange(min=0, message=u'金额必须为正数')\n    ])\n    ORDER_MAX_COUNT = IntegerField(u'订单最大数量', validators=[\n        DataRequired(u'数量不能为空'),\n        NumberRange(min=0, message=u'数量必须为正数')\n    ])\n\n    # 推广奖励\n    BONUS_DIRECT = DecimalField(u'直接推荐奖励', validators=[\n        DataRequired(u'利息不能为空'),\n        NumberRange(min=0, message=u'利息必须为正数')\n    ])\n    BONUS_LEVEL_FIRST = DecimalField(u'一级推荐奖励', validators=[\n        DataRequired(u'利息不能为空'),\n        NumberRange(min=0, max=1, message=u'奖励利息范围：0-1')\n    ])\n    BONUS_LEVEL_SECOND = DecimalField(u'二级推荐奖励', validators=[\n        DataRequired(u'利息不能为空'),\n        NumberRange(min=0, max=1, message=u'奖励利息范围：0-1')\n    ])\n    BONUS_LEVEL_THIRD = DecimalField(u'三级推荐奖励', validators=[\n        DataRequired(u'利息不能为空'),\n        NumberRange(min=0, max=1, message=u'奖励利息范围：0-1')\n    ])\n\n\nclass ApplyPutForm(FlaskForm):\n    \"\"\"\n    投资配置\n    # 单次投资金额范围\n    APPLY_PUT_MIN_EACH = 2000               # 最小值\n    APPLY_PUT_MAX_EACH = 20000              # 最大值\n    APPLY_PUT_STEP = 1000                   # 投资金额步长（基数）\n\n    # 单个用户投资限制\n    APPLY_PUT_USER_MAX_AMOUNT = 30000       # 单个用户投资最大交易中金额\n    APPLY_PUT_USER_MAX_COUNT = 1            # 单个用户投资最大交易中单数(0 表示不限制)\n\n    # 每日投资限制\n    APPLY_PUT_MAX_AMOUNT_DAILY = 1000000    # 最大金额\n    APPLY_PUT_MAX_COUNT_DAILY = 0           # 最大数量(0 表示不限制)\n\n    # 每月投资限制\n    APPLY_PUT_MAX_AMOUNT_MONTHLY = 30000000 # 最大值\n    APPLY_PUT_MAX_COUNT_MONTHLY = 0         # 最大数量(0 表示不限制)\n\n    # 投资时间配置\n    APPLY_PUT_TIME_START = '00:00:00'       # 每天投资申请开始时间\n    APPLY_PUT_TIME_END = '59:00:00'         # 每天投资申请结束时间\n\n    # 分红配置\n    APPLY_PUT_DAYS_BONUS = 15               # 分红计算天数\n    APPLY_PUT_DAYS_LOCK = 15                # 投资锁定天数、提现冻结天数\n\n    APPLY_PUT_INTEREST_ON_PRINCIPAL_TTL = 3600*24*15     # 投资申请后15天完成的订单执行回收本息\n    \"\"\"\n    # 单次投资金额范围\n    APPLY_PUT_MIN_EACH = IntegerField(u'单次投资最小金额', validators=[\n        DataRequired(u'金额不能为空'),\n        NumberRange(min=0, message=u'金额必须为正数')\n    ])\n    APPLY_PUT_MAX_EACH = IntegerField(u'单次投资最大金额', validators=[\n        DataRequired(u'金额不能为空'),\n        NumberRange(min=0, message=u'金额必须为正数')\n    ])\n    APPLY_PUT_STEP = IntegerField(u'投资金额调整基数', validators=[\n        DataRequired(u'金额不能为空'),\n        NumberRange(min=0, message=u'金额必须为正数')\n    ])\n\n    # 单个用户投资限制\n    APPLY_PUT_USER_MAX_AMOUNT = IntegerField(u'单个用户投资最大金额', validators=[\n        DataRequired(u'金额不能为空'),\n        NumberRange(min=0, message=u'金额必须为正数')\n    ])\n    APPLY_PUT_USER_MAX_COUNT = IntegerField(u'单个用户投资最大单数', validators=[\n        InputRequired(u'数量不能为空'),\n        NumberRange(min=0, message=u'数量必须为正数')\n    ])\n\n    # 每日投资限制\n    APPLY_PUT_MAX_AMOUNT_DAILY = IntegerField(u'每日投资最大金额', validators=[\n        DataRequired(u'金额不能为空'),\n        NumberRange(min=0, message=u'金额必须为正数')\n    ])\n    APPLY_PUT_MAX_COUNT_DAILY = IntegerField(u'每日投资最大单数', validators=[\n        DataRequired(u'数量不能为空'),\n        NumberRange(min=0, message=u'数量必须为正数')\n    ])\n\n    # 每月投资限制\n    APPLY_PUT_MAX_AMOUNT_MONTHLY = IntegerField(u'每月投资最大金额', validators=[\n        DataRequired(u'金额不能为空'),\n        NumberRange(min=0, message=u'金额必须为正数')\n    ])\n    APPLY_PUT_MAX_COUNT_MONTHLY = IntegerField(u'每月投资最大单数', validators=[\n        DataRequired(u'数量不能为空'),\n        NumberRange(min=0, message=u'数量必须为正数')\n    ])\n\n    # 投资时间配置\n    APPLY_PUT_TIME_START = StringField(u'每天投资申请开始时间', validators=[\n        DataRequired(u'时间不能为空')\n    ])\n    APPLY_PUT_TIME_END = StringField(u'每天投资申请结束时间', validators=[\n        DataRequired(u'时间不能为空')\n    ])\n\n\nclass ApplyGetForm(FlaskForm):\n    \"\"\"\n    提现配置\n\n    # 单次提现金额范围\n    APPLY_GET_MIN_EACH = 2000               # 最小值\n    APPLY_GET_MAX_EACH = 20000              # 最大值\n    APPLY_GET_STEP = 1000                   # 投资金额步长（基数）\n\n    # 单个用户提现限制\n    APPLY_GET_USER_MAX_AMOUNT = 30000       # 单个用户提现最大交易中金额\n    APPLY_GET_USER_MAX_COUNT = 1            # 单个用户提现最大交易中单数(0 表示不限制)\n\n    # 每日提现限制\n    APPLY_GET_MAX_AMOUNT_DAILY = 1000000    # 最大金额\n    APPLY_GET_MAX_COUNT_DAILY = 0           # 最大数量(0 表示不限制)\n\n    # 每月提现限制\n    APPLY_GET_MAX_AMOUNT_MONTHLY = 30000000 # 最大值\n    APPLY_GET_MAX_COUNT_MONTHLY = 0         # 最大数量(0 表示不限制)\n\n    # 提现时间配置\n    APPLY_GET_TIME_START = '00:00:00'       # 每天提现申请开始时间\n    APPLY_GET_TIME_END = '59:00:00'         # 每天提现申请结束时间\n    \"\"\"\n    # 单次投资金额范围\n    APPLY_GET_MIN_EACH = IntegerField(u'单次提现最小金额', validators=[\n        DataRequired(u'金额不能为空'),\n        NumberRange(min=0, message=u'金额必须为正数')\n    ])\n    APPLY_GET_MAX_EACH = IntegerField(u'单次提现最大金额', validators=[\n        DataRequired(u'金额不能为空'),\n        NumberRange(min=0, message=u'金额必须为正数')\n    ])\n    APPLY_GET_STEP = IntegerField(u'提现金额调整基数', validators=[\n        DataRequired(u'金额不能为空'),\n        NumberRange(min=0, message=u'金额必须为正数')\n    ])\n\n    # 单个用户提现限制\n    APPLY_GET_USER_MAX_AMOUNT = IntegerField(u'单个用户提现最大金额', validators=[\n        DataRequired(u'金额不能为空'),\n        NumberRange(min=0, message=u'金额必须为正数')\n    ])\n    APPLY_GET_USER_MAX_COUNT = IntegerField(u'单个用户提现最大单数', validators=[\n        InputRequired(u'数量不能为空'),\n        NumberRange(min=0, message=u'数量必须为正数')\n    ])\n\n    # 每日提现限制\n    APPLY_GET_MAX_AMOUNT_DAILY = IntegerField(u'每日提现最大金额', validators=[\n        DataRequired(u'金额不能为空'),\n        NumberRange(min=0, message=u'金额必须为正数')\n    ])\n    APPLY_GET_MAX_COUNT_DAILY = IntegerField(u'每日提现最大单数', validators=[\n        DataRequired(u'数量不能为空'),\n        NumberRange(min=0, message=u'数量必须为正数')\n    ])\n\n    # 每月提现限制\n    APPLY_GET_MAX_AMOUNT_MONTHLY = IntegerField(u'每月提现最大金额', validators=[\n        DataRequired(u'金额不能为空'),\n        NumberRange(min=0, message=u'金额必须为正数')\n    ])\n    APPLY_GET_MAX_COUNT_MONTHLY = IntegerField(u'每月提现最大单数', validators=[\n        DataRequired(u'数量不能为空'),\n        NumberRange(min=0, message=u'数量必须为正数')\n    ])\n\n    # 提现时间配置\n    APPLY_GET_TIME_START = StringField(u'每天提现申请开始时间', validators=[\n        DataRequired(u'时间不能为空')\n    ])\n    APPLY_GET_TIME_END = StringField(u'每天提现申请结束时间', validators=[\n        DataRequired(u'时间不能为空')\n    ])\n\n\nclass InterestForm(FlaskForm):\n    \"\"\"\n    利息配置\n\n    INTEREST_PUT = 0.01  # 投资利息（日息）\n\n    # 支付奖惩比例\n    INTEREST_PAY_AHEAD = 0.02  # 提前支付奖金比例\n    INTEREST_PAY_DELAY = 0.02  # 延迟支付罚金比例\n\n    # 支付时间差\n    DIFF_TIME_PAY_AHEAD = 60*60*1   # 提前支付奖金时间差\n    DIFF_TIME_PAY_DELAY = 60*60*24  # 延迟支付罚金时间差\n\n    # 确认奖惩比例\n    INTEREST_REC_AHEAD = 0.02  # 提前确认奖金比例\n    INTEREST_REC_DELAY = 0.02  # 延迟确认罚金比例\n\n    # 确认时间差\n    DIFF_TIME_REC_AHEAD = 60*60*1   # 提前确认奖金时间差\n    DIFF_TIME_REC_DELAY = 60*60*24  # 延迟确认罚金时间差\n    \"\"\"\n    # 利息配置\n    INTEREST_PUT = DecimalField(u'投资利息（日息）', validators=[\n        DataRequired(u'利息不能为空'),\n        NumberRange(min=0, message=u'利息必须为正数')\n    ])\n\n    # 支付奖惩比例\n    INTEREST_PAY_AHEAD = DecimalField(u'提前支付奖金比例', validators=[\n        DataRequired(u'奖金比例不能为空'),\n        NumberRange(min=0, message=u'奖金比例必须为正数')\n    ])\n    INTEREST_PAY_DELAY = DecimalField(u'延迟支付罚金比例', validators=[\n        DataRequired(u'罚金比例不能为空'),\n        NumberRange(min=0, message=u'罚金比例必须为正数')\n    ])\n\n    # 支付时间差\n    DIFF_TIME_PAY_AHEAD = IntegerField(u'提前支付奖金时间', validators=[\n        DataRequired(u'时间不能为空'),\n        NumberRange(min=0, message=u'时间必须为正数')\n    ])\n    DIFF_TIME_PAY_DELAY = IntegerField(u'延迟支付罚金时间', validators=[\n        DataRequired(u'时间不能为空'),\n        NumberRange(min=0, message=u'时间必须为正数')\n    ])\n\n    # 确认奖惩比例\n    INTEREST_REC_AHEAD = DecimalField(u'提前确认奖金比例', validators=[\n        DataRequired(u'奖金比例不能为空'),\n        NumberRange(min=0, message=u'奖金比例必须为正数')\n    ])\n    INTEREST_REC_DELAY = DecimalField(u'延迟确认罚金比例', validators=[\n        DataRequired(u'罚金比例不能为空'),\n        NumberRange(min=0, message=u'罚金比例必须为正数')\n    ])\n\n    # 确认时间差\n    DIFF_TIME_REC_AHEAD = IntegerField(u'提前确认奖金时间', validators=[\n        DataRequired(u'时间不能为空'),\n        NumberRange(min=0, message=u'时间必须为正数')\n    ])\n    DIFF_TIME_REC_DELAY = IntegerField(u'延迟确认罚金时间', validators=[\n        DataRequired(u'时间不能为空'),\n        NumberRange(min=0, message=u'时间必须为正数')\n    ])\n"
  },
  {
    "path": "app_backend/forms/user.py",
    "content": "#!/usr/bin/env python\n# encoding: utf-8\n\n\"\"\"\n@author: zhanghe\n@software: PyCharm\n@file: user.py\n@time: 2017/3/17 下午11:49\n\"\"\"\n\n\nfrom flask_wtf import FlaskForm\nfrom wtforms import StringField, PasswordField, BooleanField, DateField, DateTimeField, HiddenField, IntegerField\nfrom wtforms.validators import DataRequired, Length, NumberRange, EqualTo, Email, ValidationError, IPAddress, \\\n    InputRequired\nfrom flask_login import current_user\n\nfrom app_backend.api.user import get_user_row_by_id\nfrom app_backend.models import UserProfile, UserAuth\nfrom app_backend.forms import SelectBS, CheckBoxBS\nfrom app_common.maps import status_lock_list\nfrom app_common.maps import status_active_list\nfrom app_common.maps import area_code_list\nfrom app_backend.api.user_auth import get_user_auth_row\n\nfrom app_backend.api.user_profile import get_user_profile_row\nfrom app_backend.forms import SelectAreaCode, CheckBoxBS\nfrom app_common.maps.status_delete import STATUS_DEL_OK\nfrom app_common.maps.type_auth import TYPE_AUTH_ACCOUNT\n\n\ndef reg_email_repeat(form, field):\n    \"\"\"\n    邮箱重复校验\n    \"\"\"\n    condition = {\n        'auth_type': 'email',\n        'auth_key': field.data\n    }\n    row = get_user_auth_row(**condition)\n    if row:\n        raise ValidationError(u'注册邮箱重复')\n\n\nclass PhoneFormatValidate(object):\n    \"\"\"\n    手机号码格式校验\n    \"\"\"\n    def __init__(self, message=None):\n        self.message = message\n\n    def __call__(self, form, field):\n        phone_len = len(field.data)\n        if phone_len < 6 or phone_len > 11:\n            raise ValidationError(u'手机号码长度不符')\n        # 中国手机号码格式校验\n        if form.area_id.data == '0' and phone_len != 11:\n            raise ValidationError(u'手机号码长度不符')\n        if field.data.startswith('0'):\n            raise ValidationError(u'手机号码格式不符')\n\n\nclass PhoneRepeatValidate(object):\n    \"\"\"\n    手机重复校验\n    (编辑重复校验排除当前用户)\n    \"\"\"\n    def __init__(self, message=None):\n        self.message = message\n\n    def __call__(self, form, field):\n        condition = [\n            UserProfile.area_id == form.area_id.data,\n            UserProfile.phone == field.data,\n            UserProfile.user_id != form.user_id.data\n        ]\n        row = get_user_profile_row(*condition)\n\n        if row:\n            raise ValidationError(self.message or u'手机号码重复')\n\n\nclass IdCardRepeatValidate(object):\n    \"\"\"\n    身份证号重复校验\n    (编辑重复校验排除当前用户)\n    \"\"\"\n    def __init__(self, message=None):\n        self.message = message\n\n    def __call__(self, form, field):\n        condition = [\n            UserProfile.area_id == form.area_id.data,\n            UserProfile.id_card == field.data,\n            UserProfile.user_id != form.user_id.data\n        ]\n        row = get_user_profile_row(*condition)\n\n        if row:\n            raise ValidationError(self.message or u'身份证号重复')\n\n\nclass RegAccountRepeatValidate(object):\n    \"\"\"\n    登录账号重复校验\n    \"\"\"\n    def __init__(self, message=None):\n        self.message = message\n\n    def __call__(self, form, field):\n        condition = [\n            UserAuth.type_auth == TYPE_AUTH_ACCOUNT,\n            UserAuth.auth_key == field.data,\n            UserAuth.user_id != form.user_id.data\n        ]\n        row = get_user_auth_row(*condition)\n        if row:\n            raise ValidationError(self.message or u'登录账号重复')\n\n\nclass PasswordFormatValidate(object):\n    \"\"\"\n    密码格式校验\n    \"\"\"\n    def __init__(self, message=None):\n        self.message = message\n\n    def __call__(self, form, field):\n        password_len = len(field.data)\n        if password_len > 0 and (password_len < 6 or password_len > 20):\n            raise ValidationError(self.message or u'密码长度不符')\n\n\nclass UserProfileForm(FlaskForm):\n    \"\"\"\n    用户基本信息表单\n    \"\"\"\n    user_id = HiddenField('User Id', validators=[DataRequired()])\n    user_pid = StringField(u'推荐人ID', validators=[InputRequired()])\n    nickname = StringField(u'用户名称')\n    avatar_url = StringField(u'用户头像')\n    email = StringField(u'电子邮箱')\n    area_code_choices = []\n    for m, n in enumerate(area_code_list):\n        area_code_choices.append((m, n))\n    area_id = SelectAreaCode(u'手机区号', default='0', choices=area_code_choices, validators=[DataRequired()])\n    area_code = StringField('Area Code')\n    phone = StringField(u'手机号码', validators=[\n        DataRequired(u'手机号码不能为空'),\n        PhoneFormatValidate(),\n        PhoneRepeatValidate()\n    ])\n    birthday = DateField(u'出生日期')\n    real_name = StringField(u'真实姓名', validators=[\n        DataRequired(u'真实姓名不能为空'),\n        Length(min=2, max=20, message=u'真实姓名长度不符')\n    ])\n    id_card = StringField(u'身份证号', validators=[\n        DataRequired(u'身份证号不能为空'),\n        Length(min=18, max=18, message=u'身份证号长度不符'),\n        IdCardRepeatValidate()\n    ])\n    create_time = DateTimeField(u'创建时间')\n    update_time = DateTimeField(u'修改时间')\n\n\nclass UserAuthForm(FlaskForm):\n    \"\"\"\n    用户登录认证信息表单\n    \"\"\"\n    id = HiddenField('Id', validators=[DataRequired()])\n    user_id = HiddenField('User Id', validators=[DataRequired()])\n    type_auth = StringField(u'账号类型')\n    auth_key = StringField(u'登录账号', validators=[\n        DataRequired(u'登录账号不能为空'),\n        Length(min=2, max=20, message=u'登录账号长度不符'),\n        RegAccountRepeatValidate()\n    ])\n    auth_secret = PasswordField(u'登录密码', validators=[\n        PasswordFormatValidate()\n    ])\n    status_verified = CheckBoxBS(u'认证状态')\n    create_time = DateTimeField(u'创建时间')\n    update_time = DateTimeField(u'更新时间')\n\n\nclass UserBankForm(FlaskForm):\n    \"\"\"\n    用户基本银行信息表单\n    \"\"\"\n    user_id = HiddenField(u'用户ID', validators=[DataRequired()])\n    account_name = StringField(u'账户姓名', validators=[\n        DataRequired(u'账户姓名不能为空'),\n        Length(min=2, max=20, message=u'账户姓名长度不符'),\n    ])\n    bank_name = StringField(u'银行名称', validators=[DataRequired(u'银行名称不能为空')])\n    bank_address = StringField(u'支行名称', validators=[DataRequired(u'支行名称不能为空')])\n    bank_account = StringField(u'银行卡号', validators=[DataRequired(u'银行卡号不能为空')])\n    status_verified = CheckBoxBS(u'认证状态')\n    status_delete = StringField(u'删除状态')\n    create_time = DateTimeField(u'创建时间')\n    update_time = DateTimeField(u'更新时间')\n\n\nclass EditPassword(FlaskForm):\n    \"\"\"\n    修改用户密码\n    \"\"\"\n    password = PasswordField('New Password', validators=[\n        DataRequired(),\n        Length(min=6, max=40),\n        EqualTo('confirm', message='Passwords must match')\n    ])\n    confirm = PasswordField('Repeat Password', validators=[\n        DataRequired(),\n        Length(min=6, max=40)\n    ])\n\n\nclass UserSearchForm(FlaskForm):\n    \"\"\"\n    用户搜索表单\n    \"\"\"\n    user_id = StringField(u'用户ID')\n    user_name = StringField(u'用户名称')\n    start_time = StringField('Start Time')\n    end_time = StringField('End Time')\n    status_active = SelectBS('Status Active', default='', choices=status_active_list)\n    status_lock = SelectBS('Status Lock', default='', choices=status_lock_list)\n\n\nclass UserRightValidate(object):\n    \"\"\"\n    用户权限校验\n    \"\"\"\n    def __init__(self, message=None):\n        self.message = message\n\n    def __call__(self, form, field):\n        # 用户异常处理\n        user_info = get_user_row_by_id(field.data)\n\n        if not user_info:\n            raise ValidationError(u'异常操作，此用户不存在')\n        if user_info.status_delete == int(STATUS_DEL_OK):\n            raise ValidationError(u'异常操作，此用户已删除')\n\n\nclass UserConfigForm(FlaskForm):\n    \"\"\"\n    用户配置表单\n    \"\"\"\n    user_id = StringField(u'用户ID', validators=[\n        DataRequired(message=u'用户ID不能为空'),\n        UserRightValidate()\n    ])\n    team_bonus = StringField(u'团队奖金配置')\n"
  },
  {
    "path": "app_backend/forms/wallet.py",
    "content": "#!/usr/bin/env python\n# encoding: utf-8\n\n\"\"\"\n@author: zhanghe\n@software: PyCharm\n@file: wallet.py\n@time: 2017/4/25 下午1:26\n\"\"\"\n\n\ndef func():\n    pass\n\n\nclass Main(object):\n    def __init__(self):\n        pass\n\n\nif __name__ == '__main__':\n    pass\n"
  },
  {
    "path": "app_backend/lib/__init__.py",
    "content": "#!/usr/bin/env python\n# encoding: utf-8\n\n\"\"\"\n@author: zhanghe\n@software: PyCharm\n@file: __init__.py\n@time: 16-1-27 上午10:26\n\"\"\"\n\n\ndef func():\n    pass\n\n\nclass Main(object):\n    def __init__(self):\n        pass\n\n\nif __name__ == '__main__':\n    pass\n"
  },
  {
    "path": "app_backend/lib/captcha.py",
    "content": "#!/usr/bin/env python\n# encoding: utf-8\n\n\"\"\"\n@author: zhanghe\n@software: PyCharm\n@file: captcha.py\n@time: 16-4-11 下午9:23\n\"\"\"\n\n\nimport random\nfrom PIL import Image, ImageDraw, ImageFont, ImageFilter\nfrom config import BASE_DIR\n\n\nclass Captcha(object):\n    \"\"\"\n    验证码（生成）\n    \"\"\"\n    # map:将str函数作用于后面序列的每一个元素\n    _letter_cases = \"abcdefghjkmnpqrstuvwxy\"  # 小写字母, 去除可能干扰的i, l, o, z\n    _upper_cases = _letter_cases.upper()  # 大写字母\n    _numbers = ''.join(map(str, range(3, 10)))  # 数字, 去除可能干扰的0, 1, 2\n    init_chars = ''.join((_upper_cases, _numbers))\n\n    def __init__(self,\n                 size=(120, 30),\n                 chars=init_chars,\n                 mode=\"RGB\",\n                 bg_color=(255, 255, 255),\n                 fg_color=(255, 0, 0),\n                 line_color=(255, 0, 0),\n                 point_color=(255, 0, 0),\n                 font_type='%s/%s' % (BASE_DIR, 'app_backend/static/fonts/Ubuntu-B.ttf'),\n                 font_size=18,\n                 length=4,\n                 draw_lines=True,\n                 n_lines=(1, 2),\n                 draw_points=True,\n                 point_chance=2):\n        \"\"\"\n        :param size: 图片的大小，格式（宽，高），默认为(120, 30)\n        :param chars: 允许的字符集合，格式字符串\n        :param mode: 图片模式，默认为RGB\n        :param bg_color: 背景颜色，默认为白色\n        :param fg_color: 前景色，验证码字符颜色\n        :param font_type: 验证码字体\n        :param font_size: 验证码字体大小\n        :param length: 验证码字符个数\n        :param draw_lines: 是否划干扰线\n        :param n_lines: 干扰线的条数范围，格式元组，默认为(1, 2)，只有draw_lines为True时有效\n        :param draw_points: 是否画干扰点\n        :param point_chance: 干扰点出现的概率，大小范围[0, 50]\n        :return:\n        \"\"\"\n        self.size = size\n        self.width, self.height = size\n        self.chars = chars\n        self.bg_color, self.fg_color, self.line_color, self.point_color = bg_color, fg_color, line_color, point_color\n        self.font_type, self.font_size = font_type, font_size\n        self.length = length\n        self.draw_lines, self.n_lines, self.draw_points = draw_lines, n_lines, draw_points\n        self.point_chance = point_chance\n        self.img = Image.new(mode, size, bg_color)  # 创建图形\n        self.draw = ImageDraw.Draw(self.img)  # 创建画笔\n\n    def _get_chars(self):\n        \"\"\"\n        生成给定长度的字符串，返回列表格式\n        \"\"\"\n        return random.sample(self.chars, self.length)\n\n    def _create_lines(self):\n        \"\"\"\n        绘制干扰线\n        \"\"\"\n        line_num = random.randint(*self.n_lines)  # 干扰线条数\n\n        for i in range(line_num):\n            # 起始点\n            begin = (random.randint(0, self.size[0]), random.randint(0, self.size[1]))\n            # 结束点\n            end = (random.randint(0, self.size[0]), random.randint(0, self.size[1]))\n            self.draw.line([begin, end], fill=self.line_color)\n\n    def _create_points(self):\n        \"\"\"\n        绘制干扰点\n        \"\"\"\n        chance = min(50, max(0, int(self.point_chance)))  # 大小限制在[0, 50]\n\n        for w in xrange(self.width):\n            for h in xrange(self.height):\n                tmp = random.randint(0, 50)\n                if tmp > 50 - chance:\n                    self.draw.point((w, h), fill=self.point_color)\n\n    def _create_code_str(self):\n        \"\"\"\n        绘制验证码字符\n        \"\"\"\n        c_chars = self._get_chars()\n        c_str = '%s' % ''.join(c_chars)\n\n        font = ImageFont.truetype(self.font_type, self.font_size)\n        font_width, font_height = font.getsize(c_str)\n\n        self.draw.text(((self.width - font_width) / 3, (self.height - font_height) / 4),\n                       c_str, font=font, fill=self.fg_color)\n        return c_str\n\n    def get(self):\n        if self.draw_lines:\n            self._create_lines()\n        if self.draw_points:\n            self._create_points()\n        code_str = self._create_code_str()\n\n        # 图形扭曲参数\n        params = [1 - float(random.randint(1, 2)) / 100,\n                  0,\n                  0,\n                  0,\n                  1 - float(random.randint(1, 10)) / 100,\n                  float(random.randint(1, 2)) / 500,\n                  0.001,\n                  float(random.randint(1, 2)) / 500\n                  ]\n        img = self.img.transform(self.size, Image.PERSPECTIVE, params)  # 创建扭曲\n\n        img = img.filter(ImageFilter.EDGE_ENHANCE_MORE)  # 滤镜，边界加强（阈值更大）\n\n        return img, code_str\n\n\nif __name__ == '__main__':\n    pass\n"
  },
  {
    "path": "app_backend/lib/cart.py",
    "content": "#!/usr/bin/env python\n# encoding: utf-8\n\n\"\"\"\n@author: zhanghe\n@software: PyCharm\n@file: cart.py\n@time: 16-1-27 上午10:27\n\"\"\"\n\n\nimport redis\n\n\nredis_client = redis.StrictRedis(host='localhost', port=6379, db=0)\n\n\nclass Cart(object):\n    \"\"\"\n    购物车\n    \"\"\"\n    uid = ''\n    prefix = ''\n\n    def __init__(self, uid, prefix='cart'):\n        self.uid = uid\n        self.prefix = prefix\n\n    def add_item(self, pid, num=1):\n        \"\"\"\n        添加物品\n        :param pid:\n        :param num:\n        :return:\n        \"\"\"\n        key = \"%s:%s:%s\" % (self.prefix, self.uid, pid)\n        # 判断物品是否存在\n        if redis_client.exists(key):\n            redis_client.hincrby(key, 'num', num)\n        else:\n            # 如果不存在，添加物品至购物车\n            redis_client.hmset(key, {'pid': pid, 'num': num})\n        return True\n\n    def del_item(self, pid):\n        \"\"\"\n        删除物品\n        :param pid:\n        :return:\n        \"\"\"\n        key = \"%s:%s:%s\" % (self.prefix, self.uid, pid)\n        # 判断物品是否存在\n        if redis_client.exists(key):\n            redis_client.delete(key)\n        return True\n\n    def edit_item(self, pid, num):\n        \"\"\"\n        编辑物品\n        :param pid:\n        :param num:\n        :return: True/False\n        \"\"\"\n        key = \"%s:%s:%s\" % (self.prefix, self.uid, pid)\n        # 判断物品是否存在\n        if redis_client.exists(key):\n            redis_client.hmset(key, {'pid': pid, 'num': num})\n            return True\n        return False\n\n    def increase(self, pid, num=1):\n        \"\"\"\n        增加物品数量\n        :param pid:\n        :param num:\n        :return:\n        \"\"\"\n        key = \"%s:%s:%s\" % (self.prefix, self.uid, pid)\n        # 判断物品是否存在\n        if redis_client.exists(key):\n            redis_client.hincrby(key, 'num', num)\n        else:\n            # 如果不存在，添加物品至购物车\n            redis_client.hmset(key, {'pid': pid, 'num': num})\n        return True\n\n    def decrease(self, pid, num=1):\n        \"\"\"\n        减少物品数量\n        :param pid:\n        :param num:\n        :return:\n        \"\"\"\n        key = \"%s:%s:%s\" % (self.prefix, self.uid, pid)\n        # 判断物品是否存在\n        if redis_client.exists(key):\n            if num >= int(redis_client.hget(key, 'num')):\n                # 如果超过，设置默认最小数量\n                redis_client.hmset(key, {'num': 1})\n            else:\n                redis_client.hincrby(key, 'num', -num)\n        return True\n\n    def cart_list(self):\n        \"\"\"\n        显示购物车\n        :return: list\n        \"\"\"\n        key = \"%s:%s:*\" % (self.prefix, self.uid)\n        car_key_list = redis_client.keys(key)\n        return [redis_client.hgetall(item) for item in car_key_list]\n\n    def clean(self):\n        \"\"\"\n        清空购物车\n        :return: 0/int\n        \"\"\"\n        key = \"%s:%s:*\" % (self.prefix, self.uid)\n        car_key_list = redis_client.keys(key)\n        return redis_client.delete(*car_key_list) if car_key_list else 0\n\n\ndef test():\n    obj = Cart('02')\n    print obj.cart_list()\n    obj.add_item('3')\n    print obj.cart_list()\n    obj.del_item('4')\n    print obj.cart_list()\n    obj.increase('3')\n    print obj.cart_list()\n    obj.decrease('3')\n    print obj.cart_list()\n    obj.add_item('4')\n    print obj.cart_list()\n    obj.add_item('5', 10)\n    print obj.cart_list()\n    obj.edit_item('5', 9)\n    print obj.cart_list()\n    obj.decrease('4', 10)\n    print obj.cart_list()\n\n\nif __name__ == '__main__':\n    test()\n\n\n\"\"\"\n测试结果\n[]\n[{'num': '1', 'pid': '3'}]\n[{'num': '1', 'pid': '3'}]\n[{'num': '2', 'pid': '3'}]\n[{'num': '1', 'pid': '3'}]\n[{'num': '1', 'pid': '4'}, {'num': '1', 'pid': '3'}]\n[{'num': '10', 'pid': '5'}, {'num': '1', 'pid': '4'}, {'num': '1', 'pid': '3'}]\n[{'num': '10', 'pid': '5'}, {'num': '1', 'pid': '4'}, {'num': '1', 'pid': '3'}]\n\"\"\"\n"
  },
  {
    "path": "app_backend/lib/container.py",
    "content": "#!/usr/bin/env python\n# encoding: utf-8\n\n\"\"\"\n@author: zhanghe\n@software: PyCharm\n@file: container.py\n@time: 16-2-17 下午3:46\n\"\"\"\n\n\nimport redis\nimport time\nfrom copy import deepcopy\n\n\nredis_client = redis.StrictRedis(host='localhost', port=6379, db=0)\n\n\nclass Container(object):\n    \"\"\"\n    容器（数据结构：有序集合）\n    \"\"\"\n    # 定义支持的实体类型\n    entity_name_list = ['user', 'blog', 'topic', 'subject', 'product']\n\n    # 定义支持的统计类型\n    stat_type_list = [\n        'favor',  # 支持数\n        'decry',  # 反对数\n        'follow',  # 关注数\n        'fans',  # 粉丝数\n        'view',  # 点击数\n        'collect',  # 收藏数\n        'flag'  # 举报数\n    ]\n\n    # 定义项目容器状态结构\n    container_status_dict = {\n        'favor': False,  # 支持\n        'flag': False,  # 举报\n        'collect': False  # 收藏\n    }\n\n    def __init__(self, entity_name, prefix='container'):\n        if entity_name not in self.entity_name_list:\n            raise TypeError(u'类型错误')\n        self.entity_name = entity_name\n        self.prefix = prefix\n\n    def add_item(self, stat_type, key_id, item_id):\n        \"\"\"\n        添加统计项目\n        :param stat_type:\n        :param key_id:\n        :param item_id:\n        :return:0/1\n        \"\"\"\n        key = \"%s:%s:%s:%s\" % (self.prefix, self.entity_name, stat_type, key_id)\n        return redis_client.zadd(key, time.time(), item_id)\n\n    def del_item(self, stat_type, key_id, item_id):\n        \"\"\"\n        删除统计项目\n        :param stat_type:\n        :param key_id:\n        :param item_id:\n        :return:0/1\n        \"\"\"\n        key = \"%s:%s:%s:%s\" % (self.prefix, self.entity_name, stat_type, key_id)\n        return redis_client.zrem(key, item_id)\n\n    def count_item(self, stat_type, key_id):\n        \"\"\"\n        统计相关项目的总数\n        :param stat_type:\n        :param key_id:\n        :return:\n        \"\"\"\n        key = \"%s:%s:%s:%s\" % (self.prefix, self.entity_name, stat_type, key_id)\n        return redis_client.zcount(key, 0, time.time())\n\n    def get_items(self, stat_type, key_id, page=1, pagesize=10):\n        \"\"\"\n        分页获取相关项目列表(根据时间降序)\n        :param stat_type:\n        :param key_id:\n        :param page:\n        :param pagesize:\n        :return:[]\n        \"\"\"\n        offset = 0\n        if page > 1:\n            offset = (page - 1) * pagesize\n        max_count = (page * pagesize) - 1\n        key = \"%s:%s:%s:%s\" % (self.prefix, self.entity_name, stat_type, key_id)\n        item_ids = redis_client.zrevrange(key, offset, max_count)  # 倒序取值\n        # item_ids = redis_client.zrange(key, offset, max_count)  # 顺序取值\n        return item_ids\n\n    def get_all_items(self, stat_type, key_id):\n        \"\"\"\n        获取所有相关项目列表\n        :param stat_type:\n        :param key_id:\n        :return:[]\n        \"\"\"\n        key = \"%s:%s:%s:%s\" % (self.prefix, self.entity_name, stat_type, key_id)\n        total = redis_client.zcard(key)\n        item_ids = redis_client.zrevrange(key, 0, total - 1, True)\n        return item_ids\n\n    def get_item_container_status(self, key_id, item_id):\n        \"\"\"\n        获取容器状态\n        :param key_id:\n        :param item_id:\n        :return:\n        \"\"\"\n        container_status = deepcopy(self.container_status_dict)\n        for stat_type in container_status.keys():\n            key = \"%s:%s:%s:%s\" % (self.prefix, self.entity_name, stat_type, key_id)\n            # 无序集合sismember； 有序用 zscore 返回值：None\n            if redis_client.zscore(key, item_id):\n                container_status[stat_type] = True\n        return container_status\n\n    def get_item_list_container_status(self, key_ids, item_id):\n        \"\"\"\n        显示列表容器状态\n        按原 item_ids 列表顺序返回结果\n        :param key_ids:\n        :param item_id:\n        :return:\n        \"\"\"\n        container_list = []\n        for key_id in key_ids:\n            container_status = self.get_item_container_status(key_id, item_id)\n            container_list.append(container_status)\n        return container_list\n\n\ndef test_blog_favor():\n    \"\"\"\n    测试 blog favor\n    \"\"\"\n    obj = Container('blog')\n    print obj.add_item('favor', 2, 5)  # 1\n    print obj.add_item('favor', 2, 5)  # 0\n    print obj.add_item('favor', 2, 6)  # 1\n    print obj.get_items('favor', 2)  # ['6', '5']\n    print obj.get_items('favor', 3)  # []\n    print obj.count_item('favor', 2)  # 2\n    print obj.del_item('favor', 3, 5)  # 0\n    print obj.count_item('favor', 3)  # 0\n    print obj.del_item('favor', 2, 5)  # 1\n    print obj.count_item('favor', 2)  # 1\n    print obj.del_item('favor', 2, 6)  # 1\n    print obj.count_item('favor', 2)  # 0\n\n\nif __name__ == '__main__':\n    test_blog_favor()\n"
  },
  {
    "path": "app_backend/lib/counter.py",
    "content": "#!/usr/bin/env python\n# encoding: utf-8\n\n\"\"\"\n@author: zhanghe\n@software: PyCharm\n@file: count.py\n@time: 16-1-27 下午3:03\n\"\"\"\n\n\nimport redis\nfrom copy import deepcopy\n\n\nredis_client = redis.StrictRedis(host='localhost', port=6379, db=0)\nredis_pipeline = redis_client.pipeline()\n\n\nclass Counter(object):\n    \"\"\"\n    计数器\n    \"\"\"\n    # 定义支持的实体类型\n    entity_name_list = ['user', 'blog', 'topic', 'subject', 'product']\n\n    # 定义支持的统计类型\n    stat_type_list = [\n        'favor',  # 支持\n        'decry',  # 反对\n        'follow',  # 关注\n        'fans',  # 粉丝\n        'view',  # 点击\n        'collect',  # 收藏\n        'flag'  # 举报\n    ]\n\n    # 定义用户计数器结构\n    user_counter_dict = {\n        'favor': '0',  # 支持数\n        'decry': '0',  # 反对数\n        'follow': '0',  # 关注数\n        'fans': '0'  # 粉丝数\n    }\n\n    # 定义话题计数器结构\n    topic_counter_dict = {\n        'favor': '0',  # 支持数\n        'decry': '0',  # 反对数\n        'view': '0',  # 点击数\n        'collect': '0'  # 收藏数\n    }\n\n    # 定义博客计数器结构\n    blog_counter_dict = {\n        'favor': '0',  # 支持数\n        'flag': '0',  # 举报数\n        'view': '0',  # 点击数\n        'collect': '0'  # 收藏数\n    }\n\n    def __init__(self, entity_name, prefix='counter'):\n        if entity_name not in self.entity_name_list:\n            raise TypeError(u'类型错误')\n        self.entity_name = entity_name\n        self.prefix = prefix\n\n    def increase(self, item_id, stat_type, num=1):\n        \"\"\"\n        增加次数\n        :param item_id:\n        :param stat_type:\n        :param num:\n        :return:\n        \"\"\"\n        if stat_type not in self.stat_type_list:\n            raise TypeError(u'类型错误')\n        key = \"%s:%s:%s\" % (self.prefix, self.entity_name, item_id)\n        # 判断物品是否存在\n        if redis_client.exists(key):\n            redis_client.hincrby(key, stat_type, num)\n        else:\n            # 如果不存在，添加物品至购物车\n            redis_client.hmset(key, {stat_type: num})\n        return True\n\n    def decrease(self, item_id, stat_type, num=1):\n        \"\"\"\n        减少次数\n        :param item_id:\n        :param stat_type:\n        :param num:\n        :return:\n        \"\"\"\n        key = \"%s:%s:%s\" % (self.prefix, self.entity_name, item_id)\n        # 判断物品是否存在\n        if redis_client.exists(key):\n            if num >= int(redis_client.hget(key, stat_type)):\n                # 如果超过，设置默认最小数量\n                redis_client.hmset(key, {stat_type: 1})\n            else:\n                redis_client.hincrby(key, stat_type, -num)\n        return True\n\n    def del_item(self, item_id):\n        \"\"\"\n        删除物品\n        :param item_id:\n        :return:\n        \"\"\"\n        key = \"%s:%s:%s\" % (self.prefix, self.entity_name, item_id)\n        # 判断物品是否存在\n        if redis_client.exists(key):\n            redis_client.delete(key)\n        return True\n\n    def counter_blog_item(self, blog_id):\n        \"\"\"\n        显示 blog 计数器\n        :param blog_id:\n        :return:\n        \"\"\"\n        key = \"%s:%s:%s\" % (self.prefix, self.entity_name, blog_id)\n        # 判断物品是否存在\n        blog_dict = deepcopy(self.blog_counter_dict)\n        if redis_client.exists(key):\n            redis_result = redis_client.hgetall(key)\n            blog_dict.update(redis_result)\n        return blog_dict\n\n    def counter_user_list_all(self):\n        \"\"\"\n        显示全部用户计数器\n        :return:\n        \"\"\"\n        key = \"%s:%s:*\" % (self.prefix, self.entity_name)\n        cnt_key_list = redis_client.keys(key)\n        cnt_list = []\n        for item in cnt_key_list:\n            user_dict = deepcopy(self.user_counter_dict)  # 注意是深度复制，不能写成 user_dict = self.user_counter_dict\n            user_dict.update(redis_client.hgetall(item))\n            cnt_list.append(user_dict)\n        return cnt_list\n\n    def counter_user_list(self, uid_list):\n        \"\"\"\n        显示用户计数器\n        按原 uid_list 列表顺序返回结果\n        :param uid_list:\n        :return:\n        \"\"\"\n        cnt_list = []\n        for uid in uid_list:\n            key = \"%s:%s:%s\" % (self.prefix, self.entity_name, uid)\n            if redis_client.exists(key):\n                user_dict = deepcopy(self.user_counter_dict)\n                redis_result = redis_client.hgetall(key)\n                user_dict.update(redis_result)\n                cnt_list.append(user_dict)\n        return cnt_list\n\n    def counter_topic_list(self, topic_list):\n        \"\"\"\n        显示话题计数器\n        按原 uid_list 列表顺序返回结果\n        :param topic_list:\n        :return:\n        \"\"\"\n        cnt_list = []\n        for topic in topic_list:\n            key = \"%s:%s:%s\" % (self.prefix, self.entity_name, topic)\n            user_dict = deepcopy(self.topic_counter_dict)\n            if redis_client.exists(key):\n                redis_result = redis_client.hgetall(key)\n                user_dict.update(redis_result)\n            cnt_list.append(user_dict)\n        return cnt_list\n\n    def counter_blog_list(self, blog_list):\n        \"\"\"\n        显示 blog 计数器\n        按原 blog_list 列表顺序返回结果\n        :param blog_list:\n        :return:\n        \"\"\"\n        cnt_list = []\n        for blog in blog_list:\n            key = \"%s:%s:%s\" % (self.prefix, self.entity_name, blog)\n            blog_dict = deepcopy(self.blog_counter_dict)\n            if redis_client.exists(key):\n                redis_result = redis_client.hgetall(key)\n                blog_dict.update(redis_result)\n            cnt_list.append(blog_dict)\n        return cnt_list\n\n    def set_blog_counter(self, blog_id, stat_type, num=1):\n        \"\"\"\n        设置 blog 计数器\n        :param blog_id:\n        :param stat_type:\n        :param num:\n        :return:\n        \"\"\"\n        self.increase(blog_id, stat_type, num)\n        return self.counter_blog_item(blog_id)\n\n\ndef test_user():\n    import json\n    user_cnt_obj = Counter('user')\n    user_cnt_obj.del_item(12)\n    user_cnt_obj.del_item(13)\n    user_cnt_obj.increase(12, 'favor')\n    user_cnt_obj.increase(13, 'fans', 5)\n    user_cnt_obj.increase(14, 'fans', 4)\n    user_cnt_obj.increase(14, 'follow', 3)\n    print json.dumps(user_cnt_obj.counter_user_list(['12', '13']), indent=4, ensure_ascii=False)\n    print json.dumps(user_cnt_obj.counter_user_list_all(), indent=4, ensure_ascii=False)\n\n\ndef test_topic():\n    import json\n    topic_cnt_obj = Counter('topic')\n    print json.dumps(topic_cnt_obj.counter_topic_list(['1', '2', '3']), indent=4, ensure_ascii=False)\n    topic_cnt_obj.increase(4, 'fans', 4)\n    print topic_cnt_obj.counter_blog_item(4)\n    print topic_cnt_obj.set_blog_counter(4, 'flag')\n\n\nif __name__ == '__main__':\n    # test_user()\n    test_topic()\n"
  },
  {
    "path": "app_backend/lib/mongo.py",
    "content": "#!/usr/bin/env python\n# encoding: utf-8\n\n\"\"\"\n@author: zhanghe\n@software: PyCharm\n@file: mongo.py\n@time: 2017/4/10 下午11:44\n\"\"\"\n\n\nfrom pymongo import MongoClient\nfrom pymongo import errors\nimport json\nfrom datetime import date, datetime\nimport logging\n\nlogger = logging.getLogger(__name__)\n\n\nclass Mongodb(object):\n    \"\"\"\n    自定义mongodb工具\n    \"\"\"\n    def __init__(self, db_config, db_name=None):\n        self.db_config = db_config\n        if db_name is not None:\n            self.db_config['database'] = db_name\n        try:\n            # 实例化mongodb\n            self.conn = MongoClient(self.db_config['host'], self.db_config['port'])\n            # 获取数据库对象(选择/切换)\n            self.db = self.conn.get_database(self.db_config['database'])\n        except errors.ServerSelectionTimeoutError, e:\n            logger.error('连接超时：%s' % e)\n        except Exception, e:\n            logger.error(e)\n\n    @staticmethod\n    def __default(obj):\n        \"\"\"\n        支持datetime的json encode\n        TypeError: datetime.datetime(2015, 10, 21, 8, 42, 54) is not JSON serializable\n        :param obj:\n        :return:\n        \"\"\"\n        if isinstance(obj, datetime):\n            return obj.strftime('%Y-%m-%d %H:%M:%S')\n        elif isinstance(obj, date):\n            return obj.strftime('%Y-%m-%d')\n        else:\n            raise TypeError('%r is not JSON serializable' % obj)\n\n    def close_conn(self):\n        \"\"\"\n        关闭连接\n        关闭所有套接字的连接池和停止监控线程。\n        如果这个实例再次使用它将自动重启和重新启动线程\n        \"\"\"\n        self.conn.close()\n\n    def find_one(self, table_name, condition=None):\n        \"\"\"\n        查询单条记录\n        :param table_name:\n        :param condition:\n        :return:\n        \"\"\"\n        return self.db.get_collection(table_name).find_one(condition)\n\n    def find_all(self, table_name, condition=None):\n        \"\"\"\n        查询多条记录\n        :param table_name:\n        :param condition:\n        :return:\n        \"\"\"\n        return self.db.get_collection(table_name).find(condition)\n\n    def count(self, table_name, condition=None):\n        \"\"\"\n        查询记录总数\n        :param table_name:\n        :param condition:\n        :return:\n        \"\"\"\n        return self.db.get_collection(table_name).count(condition)\n\n    def distinct(self, table_name, field_name):\n        \"\"\"\n        查询某字段去重后值的范围\n        :param table_name:\n        :param field_name:\n        :return:\n        \"\"\"\n        return self.db.get_collection(table_name).distinct(field_name)\n\n    def insert(self, table_name, data):\n        \"\"\"\n        插入数据\n        :param table_name:\n        :param data:\n        :return:\n        \"\"\"\n        try:\n            ids = self.db.get_collection(table_name).insert(data)\n            return ids\n        except Exception, e:\n            logger.error('插入失败：%s' % e)\n            return None\n\n    def update(self, table_name, condition, update_data, update_type='set'):\n        \"\"\"\n        批量更新数据\n        upsert : 如果不存在update的记录，是否插入；true为插入，默认是false，不插入。\n        :param table_name:\n        :param condition:\n        :param update_data:\n        :param update_type: 范围：['inc', 'set', 'unset', 'push', 'pushAll', 'addToSet', 'pop', 'pull', 'pullAll', 'rename']\n        :return:\n        \"\"\"\n        if update_type not in ['inc', 'set', 'unset', 'push', 'pushAll', 'addToSet', 'pop', 'pull', 'pullAll', 'rename']:\n            logger.error('更新失败，类型错误：%s' % update_type)\n            return None\n        try:\n            result = self.db.get_collection(table_name).update_many(condition, {'$%s' % update_type: update_data})\n            logger.info('更新成功，匹配数量：%s；更新数量：%s' % (result.matched_count, result.modified_count))\n            return result.modified_count  # 返回更新数量，仅支持MongoDB 2.6及以上版本\n        except Exception, e:\n            logger.error('更新失败：%s' % e)\n            return None\n\n    def remove(self, table_name, condition=None):\n        \"\"\"\n        删除文档记录\n        :param table_name:\n        :param condition:\n        :return:\n        \"\"\"\n        result = self.db.get_collection(table_name).remove(condition)\n        if result.get('err') is None:\n            logger.info('删除成功，删除行数%s' % result.get('n', 0))\n            return result.get('n', 0)\n        else:\n            logger.error('删除失败：%s' % result.get('err'))\n            return None\n\n    def output_row(self, table_name, condition=None, style=0):\n        \"\"\"\n        格式化输出单个记录\n        style=0 键值对齐风格\n        style=1 JSON缩进风格\n        :param table_name:\n        :param condition:\n        :param style:\n        :return:\n        \"\"\"\n        row = self.find_one(table_name, condition)\n        if style == 0:\n            # 获取KEY最大的长度作为缩进依据\n            max_len_key = max([len(each_key) for each_key in row.keys()])\n            str_format = '{0: >%s}' % max_len_key\n            keys = [str_format.format(each_key) for each_key in row.keys()]\n            result = dict(zip(keys, row.values()))\n            print '**********  表名[%s]  **********' % table_name\n            for key, item in result.items():\n                print key, ':', item\n        else:\n            print json.dumps(row, indent=4, ensure_ascii=False, default=self.__default)\n\n    def output_rows(self, table_name, condition=None, style=0):\n        \"\"\"\n        格式化输出批量记录\n        style=0 键值对齐风格\n        style=1 JSON缩进风格\n        :param table_name:\n        :param condition:\n        :param style:\n        :return:\n        \"\"\"\n        rows = self.find_all(table_name, condition)\n        total = self.count(table_name, condition)\n        if style == 0:\n            count = 0\n            for row in rows:\n                # 获取KEY最大的长度作为缩进依据\n                max_len_key = max([len(each_key) for each_key in row.keys()])\n                str_format = '{0: >%s}' % max_len_key\n                keys = [str_format.format(each_key) for each_key in row.keys()]\n                result = dict(zip(keys, row.values()))\n                count += 1\n                print '**********  表名[%s]  [%d/%d]  **********' % (table_name, count, total)\n                for key, item in result.items():\n                    print key, ':', item\n        else:\n            for row in rows:\n                print json.dumps(row, indent=4, ensure_ascii=False, default=self.__default)\n\n"
  },
  {
    "path": "app_backend/lib/qiniu_store.py",
    "content": "#!/usr/bin/env python\n# encoding: utf-8\n\n\"\"\"\n@author: zhanghe\n@software: PyCharm\n@file: qiniu.py\n@time: 16-5-2 下午1:41\n\"\"\"\n\n\nfrom urlparse import urljoin\nimport qiniu\n\n\nclass QiNiuClient(object):\n    \"\"\"\n    七牛云存储\n    \"\"\"\n    def __init__(self, app=None):\n        \"\"\"\n        初始化应用\n        \"\"\"\n        if app is not None:\n            self._access_key = app.config.get('QINIU_ACCESS_KEY', '')\n            self._secret_key = app.config.get('QINIU_SECRET_KEY', '')\n            self._bucket_name = app.config.get('QINIU_BUCKET_NAME', '')\n            domain = app.config.get('QINIU_BUCKET_DOMAIN')\n            if not domain:\n                self._base_url = 'http://' + self._bucket_name + '.qiniudn.com'\n            else:\n                self._base_url = 'http://' + domain\n\n    def save(self, data, filename=None):\n        \"\"\"\n        保存\n        \"\"\"\n        auth = qiniu.Auth(self._access_key, self._secret_key)\n        token = auth.upload_token(self._bucket_name)\n        return qiniu.put_data(token, filename, data)\n\n    def delete(self, filename):\n        \"\"\"\n        删除\n        \"\"\"\n        auth = qiniu.Auth(self._access_key, self._secret_key)\n        bucket = qiniu.BucketManager(auth)\n        return bucket.delete(self._bucket_name, filename)\n\n    def url(self, filename):\n        \"\"\"\n        链接\n        \"\"\"\n        return urljoin(self._base_url, filename)\n\n\nif __name__ == '__main__':\n    pass\n"
  },
  {
    "path": "app_backend/lib/rabbit_mq.py",
    "content": "#!/usr/bin/env python\n# encoding: utf-8\n\n\"\"\"\n@author: zhanghe\n@software: PyCharm\n@file: rabbit_mq.py\n@time: 2017/4/1 上午9:55\n\"\"\"\n\n\nimport pika\nimport json\nimport traceback\n\n\nfrom config import current_config\n\nRABBIT_MQ = current_config.RABBIT_MQ\n\n_client_conn = {'conn': None}\n\n\ndef get_conn():\n    \"\"\"\n    获取连接\n    :return:\n    \"\"\"\n    if not _client_conn.get('conn'):\n        conn_mq = pika.BlockingConnection(\n            pika.ConnectionParameters(\n                host=RABBIT_MQ.get('host', '127.0.0.1'),\n                port=RABBIT_MQ.get('port', 5672),\n                virtual_host=RABBIT_MQ.get('virtual_host', '/'),\n                heartbeat_interval=RABBIT_MQ.get('heartbeat_interval', 0),\n                retry_delay=RABBIT_MQ.get('retry_delay', 3)\n            )\n        )\n        _client_conn['conn'] = conn_mq\n        return conn_mq\n    else:\n        return _client_conn['conn']\n\n\nclass RabbitQueue(object):\n    \"\"\"\n    队列\n    \"\"\"\n    def __init__(self, exchange, queue_name, exchange_type='direct', durable=True, **arguments):\n        self.exchange = exchange\n        self.queue_name = queue_name\n        self.exchange_type = exchange_type\n        self.durable = durable\n        self.arguments = arguments\n        # print u'实例化附加参数:', arguments\n        self.conn = get_conn()\n        self.channel = self.conn.channel()\n        self.declare()\n\n    def close_conn(self):\n        \"\"\"\n        关闭连接\n        :return:\n        \"\"\"\n        if _client_conn.get('conn'):\n            self.conn.close()\n            _client_conn.pop('conn')\n\n    def declare(self):\n        \"\"\"\n        声明队列\n        \"\"\"\n        self.channel.exchange_declare(exchange=self.exchange, exchange_type=self.exchange_type, durable=self.durable)\n        self.channel.queue_declare(queue=self.queue_name, durable=self.durable, arguments=self.arguments)\n        self.channel.queue_bind(exchange=self.exchange,\n                                queue=self.queue_name,\n                                routing_key=self.queue_name)\n        self.channel.basic_qos(prefetch_count=1)\n\n    def put(self, message):\n        \"\"\"\n        推送队列消息\n        :param message:\n        :return:\n        \"\"\"\n        if isinstance(message, dict):\n            message = json.dumps(message)\n        self.channel.basic_publish(exchange=self.exchange,\n                                   routing_key=self.queue_name,\n                                   body=message,\n                                   properties=pika.BasicProperties(\n                                       delivery_mode=2 if self.durable else 1,  # make message persistent\n                                   ))\n        print \" [x] Sent %r\" % (message,)\n\n    def get(self):\n        \"\"\"\n        获取队列消息\n        :return:\n        \"\"\"\n        # data = self.channel.basic_get(self.queue_name)\n        # print data\n        method_frame, header_frame, body = self.channel.basic_get(self.queue_name)\n        if method_frame:\n            print \" [x]  Get %r\" % (body,)\n            print method_frame, header_frame, body\n            self.channel.basic_ack(method_frame.delivery_tag)\n        else:\n            print('No message returned')\n\n    def get_block(self):\n        \"\"\"\n        获取队列消息(阻塞)\n        direct 模式下多进程消费，进程轮流获取单个消息\n        :return:\n        \"\"\"\n        def callback(ch, method, properties, body):\n            try:\n                print \" [x]  Get %r\" % (body,)\n                # raise Exception('test')\n                ch.basic_ack(delivery_tag=method.delivery_tag)\n            except Exception as e:\n                print traceback.print_exc()\n                raise e\n\n        self.consume(callback)\n\n    def consume(self, callback):\n        \"\"\"\n        消费\n        \"\"\"\n        # 处理队列\n        self.channel.basic_consume(consumer_callback=callback, queue=self.queue_name)\n        try:\n            self.channel.start_consuming()\n        except KeyboardInterrupt:\n            self.channel.stop_consuming()\n        self.close_conn()\n\n\nclass RabbitPubSub(object):\n    \"\"\"\n    订阅\n    \"\"\"\n    def __init__(self, exchange, exchange_type='fanout', durable=True, **arguments):\n        self.exchange = exchange\n        self.exchange_type = exchange_type\n        self.durable = durable\n        self.arguments = arguments\n        # print u'实例化附加参数:', arguments\n        self.conn = get_conn()\n        self.channel = self.conn.channel()\n        self.channel.exchange_declare(exchange=self.exchange, exchange_type=self.exchange_type, durable=self.durable)\n\n    def close_conn(self):\n        \"\"\"\n        关闭连接\n        :return:\n        \"\"\"\n        if _client_conn.get('conn'):\n            self.conn.close()\n            _client_conn.pop('conn')\n\n    def pub(self, message):\n        \"\"\"\n        推送队列消息\n        :param message:\n        :return:\n        \"\"\"\n        if isinstance(message, dict):\n            message = json.dumps(message)\n        self.channel.basic_publish(exchange=self.exchange,\n                                   body=message,\n                                   routing_key='',\n                                   properties=pika.BasicProperties(\n                                       delivery_mode=2 if self.durable else 1,  # make message persistent\n                                   ))\n        print \" [x] Pub %r\" % (message,)\n\n    def sub(self):\n        \"\"\"\n        订阅队列消息\n        exchange_type='fanout'\n        fanout 模式下多进程消费，进程同时同步获取消息\n        :return:\n        \"\"\"\n        result = self.channel.queue_declare(exclusive=True)\n        queue_name = result.method.queue\n\n        self.channel.queue_bind(exchange=self.exchange, queue=queue_name)\n\n        print ' [*] Waiting for logs. To exit press CTRL+C'\n\n        def callback(ch, method, properties, body):\n            print \" [x] Sub %r\" % (body,)\n\n        self.channel.basic_consume(callback,\n                                   queue=queue_name,\n                                   no_ack=True\n                                   )\n\n        self.channel.start_consuming()\n\n\nclass RabbitDelayQueue(object):\n    \"\"\"\n    延时队列\n    q_d_client = RabbitDelayQueue('amq.direct', q_name, ttl=3600*24)\n    \"\"\"\n    def __init__(self, exchange, queue_name, exchange_type='direct', durable=True, **arguments):\n        self.exchange = exchange\n        self.queue_name = queue_name\n        self.delay_queue_name = '%s_delay' % queue_name\n        self.exchange_type = exchange_type\n        self.durable = durable\n        self.arguments = arguments\n        # print u'实例化附加参数:', arguments\n        self.conn = get_conn()\n\n        self.channel = self.conn.channel()\n        self.channel.confirm_delivery()\n        self.channel.queue_declare(queue=queue_name, durable=durable)\n\n        # We need to bind this channel to an exchange, that will be used to transfer\n        # messages from our delay queue.\n        self.channel.queue_bind(exchange=self.exchange,\n                                queue=queue_name)\n\n        # 延时队列定义\n        self.delay_channel = self.conn.channel()\n        self.delay_channel.confirm_delivery()\n\n        # This is where we declare the delay, and routing for our delay channel.\n        self.delay_channel.queue_declare(queue=self.delay_queue_name, durable=durable, arguments={\n            'x-message-ttl': arguments.get('ttl', 5)*1000,  # Delay until the message is transferred in milliseconds.\n            'x-dead-letter-exchange': self.exchange,  # Exchange used to transfer the message from A to B.\n            'x-dead-letter-routing-key': self.queue_name  # Name of the queue we want the message transferred to.\n        })\n\n    def close_conn(self):\n        \"\"\"\n        关闭连接\n        :return:\n        \"\"\"\n        if _client_conn.get('conn'):\n            self.conn.close()\n            _client_conn.pop('conn')\n\n    def put(self, message):\n        \"\"\"\n        推送队列消息\n        :param message:\n        :return:\n        \"\"\"\n        if isinstance(message, dict):\n            message = json.dumps(message)\n        self.delay_channel.basic_publish(exchange='',\n                                         routing_key=self.delay_queue_name,\n                                         body=message,\n                                         properties=pika.BasicProperties(\n                                             delivery_mode=2 if self.durable else 1,  # make message persistent\n                                         ))\n        print \" [x] Sent %r\" % (message,)\n\n    def get(self):\n        \"\"\"\n        获取队列消息\n        :return:\n        \"\"\"\n        # data = self.channel.basic_get(self.queue_name)\n        # print data\n        method_frame, header_frame, body = self.channel.basic_get(self.queue_name)\n        if method_frame:\n            print \" [x]  Get %r\" % (body,)\n            print method_frame, header_frame, body\n            self.channel.basic_ack(method_frame.delivery_tag)\n        else:\n            print('No message returned')\n\n    def get_block(self):\n        \"\"\"\n        获取队列消息(阻塞)\n        direct 模式下多进程消费，进程轮流获取单个消息\n        :return:\n        \"\"\"\n        def callback(ch, method, properties, body):\n            try:\n                print \" [x]  Get %r\" % (body,)\n                # raise Exception('test')\n                ch.basic_ack(delivery_tag=method.delivery_tag)\n            except Exception as e:\n                print traceback.print_exc()\n                raise e\n\n        self.consume(callback)\n\n    def consume(self, callback):\n        \"\"\"\n        消费\n        \"\"\"\n        # 处理队列\n        self.channel.basic_consume(consumer_callback=callback, queue=self.queue_name)\n        try:\n            self.channel.start_consuming()\n        except KeyboardInterrupt:\n            self.channel.stop_consuming()\n        self.close_conn()\n\n\nclass RabbitPriorityQueue(RabbitQueue):\n    \"\"\"\n    优先级队列\n    max_priority=255\n    \"\"\"\n    def __init__(self, exchange, queue_name, exchange_type='direct', durable=True, **arguments):\n        super(RabbitPriorityQueue, self).__init__(exchange, queue_name, exchange_type, durable, **arguments)\n\n    def declare(self):\n        \"\"\"\n        声明队列\n        \"\"\"\n        self.channel.exchange_declare(exchange=self.exchange, exchange_type=self.exchange_type, durable=self.durable)\n        self.channel.queue_declare(\n            queue=self.queue_name,\n            durable=self.durable,\n            arguments={\n                'x-max-priority': self.arguments.get('max_priority', 255)\n            }\n        )\n        self.channel.queue_bind(exchange=self.exchange,\n                                queue=self.queue_name,\n                                routing_key=self.queue_name)\n        self.channel.basic_qos(prefetch_count=1)\n\n    def put(self, message, priority=0):\n        \"\"\"\n        推送队列消息\n        :param message:\n        :param priority:\n        :return:\n        \"\"\"\n        print '--priority:', priority\n        if isinstance(message, dict):\n            message = json.dumps(message)\n        self.channel.basic_publish(exchange=self.exchange,\n                                   routing_key=self.queue_name,\n                                   body=message,\n                                   properties=pika.BasicProperties(\n                                       delivery_mode=2 if self.durable else 1,  # make message persistent\n                                       priority=priority\n                                   ))\n        print \" [x] Sent %r\" % (message,)\n\n\ndef test_queue():\n    \"\"\"\n    队列测试\n    参数：方法 队列名称 消息\n    :return:\n    \"\"\"\n    import sys\n    print sys.argv\n    if len(sys.argv) < 3:\n        print u'参数：方法 队列名称 消息'\n        print u'python rabbit_mq.py put q_task 123456'\n        print u'python rabbit_mq.py get q_task'\n        return\n    method, q_name, msg = sys.argv[1], sys.argv[2], ''.join(sys.argv[3:4])\n    q_client = RabbitQueue('e_test', q_name)\n    print u'连接id:%s' % id(q_client.conn)\n    # 获取消息\n    if method == 'get':\n        q_client.get()\n    # 推送消息\n    if method == 'put':\n        q_client.put(msg)\n    # 阻塞获取消息\n    if method == 'get_block':\n        q_client.get_block()\n    q_client.close_conn()\n\n\ndef test_pub_sub():\n    \"\"\"\n    队列pub/sub\n    参数：方法 队列名称 消息\n    :return:\n    \"\"\"\n    import sys\n    print sys.argv\n    if len(sys.argv) < 3:\n        print u'参数：方法 队列名称 消息'\n        print u'python rabbit_mq.py pub q_task 123456'\n        print u'python rabbit_mq.py sub q_task'\n        return\n    method, q_name, msg = sys.argv[1], sys.argv[2], ''.join(sys.argv[3:4])\n    q_client = RabbitPubSub(q_name)\n    print u'连接id:%s' % id(q_client.conn)\n    # 获取消息\n    if method == 'sub':\n        q_client.sub()\n    # 推送消息\n    if method == 'pub':\n        q_client.pub(msg)\n    q_client.close_conn()\n\n\ndef test_delay_queue():\n    \"\"\"\n    延时队列测试\n    参数：方法 队列名称 消息\n    :return:\n    \"\"\"\n    import sys\n    print sys.argv\n    if len(sys.argv) < 3:\n        print u'参数：方法 队列名称 消息'\n        print u'python rabbit_mq.py put q_delay_task 123456'\n        print u'python rabbit_mq.py get q_delay_task'\n        return\n    method, q_name, msg = sys.argv[1], sys.argv[2], ''.join(sys.argv[3:4])\n    q_client = RabbitDelayQueue('amq.direct', q_name)\n    print u'连接id:%s' % id(q_client.conn)\n    # 获取消息\n    if method == 'get':\n        q_client.get()\n    # 推送消息\n    if method == 'put':\n        q_client.put(msg)\n    # 阻塞获取消息\n    if method == 'get_block':\n        q_client.get_block()\n    q_client.close_conn()\n\n\ndef test_priority_queue():\n    \"\"\"\n    优先级队列测试\n    参数：方法 队列名称 消息\n    :return:\n    \"\"\"\n    import sys\n    print sys.argv\n    if len(sys.argv) < 3:\n        print u'参数：方法 队列名称 消息'\n        print u'python rabbit_mq.py put q_priority_task 111 100'\n        print u'python rabbit_mq.py put q_priority_task 222 200'\n        print u'python rabbit_mq.py put q_priority_task 333 150'\n        print u'python rabbit_mq.py get q_priority_task'  # 222\n        print u'python rabbit_mq.py get q_priority_task'  # 333\n        print u'python rabbit_mq.py get q_priority_task'  # 111\n        return\n    method, q_name, msg, priority = sys.argv[1], sys.argv[2], ''.join(sys.argv[3:4]), ''.join(sys.argv[4:5])\n    q_client = RabbitPriorityQueue('amq.direct', q_name)\n    print u'连接id:%s' % id(q_client.conn)\n    # 获取消息\n    if method == 'get':\n        q_client.get()\n    # 推送消息\n    if method == 'put':\n        q_client.put(msg, int(priority) if priority else 0)\n    # 阻塞获取消息\n    if method == 'get_block':\n        q_client.get_block()\n    q_client.close_conn()\n\n\nif __name__ == '__main__':\n    # test_queue()\n    # test_pub_sub()\n    # test_delay_queue()\n    test_priority_queue()\n\n"
  },
  {
    "path": "app_backend/lib/redis_session.py",
    "content": "#!/usr/bin/env python\n# encoding: utf-8\n\n\"\"\"\n@author: zhanghe\n@software: PyCharm\n@file: redis_session.py\n@time: 2017/3/7 上午12:41\n\"\"\"\n\n\n# import pickle\nimport json\nfrom datetime import timedelta\nfrom uuid import uuid4\nfrom redis import Redis\nfrom werkzeug.datastructures import CallbackDict\nfrom flask.sessions import SessionInterface, SessionMixin\n\n\nclass RedisSession(CallbackDict, SessionMixin):\n\n    def __init__(self, initial=None, sid=None, new=False):\n        def on_update(self):\n            self.modified = True\n        CallbackDict.__init__(self, initial, on_update)\n        self.sid = sid\n        self.new = new\n        self.modified = False\n\n\nclass RedisSessionInterface(SessionInterface):\n    # serializer = pickle\n    serializer = json\n    session_class = RedisSession\n\n    def __init__(self, redis=None, prefix='session:', **kwargs):\n        if redis is None:\n            redis = Redis(**kwargs)\n        self.redis = redis\n        self.prefix = prefix\n\n    @staticmethod\n    def generate_sid():\n        return str(uuid4())\n\n    @staticmethod\n    def get_redis_expiration_time(app, session):\n        if session.permanent:\n            return app.permanent_session_lifetime\n        # return timedelta(days=1)\n        return timedelta(minutes=20)\n\n    def open_session(self, app, request):\n        sid = request.cookies.get(app.session_cookie_name)\n        if not sid:\n            sid = self.generate_sid()\n            return self.session_class(sid=sid, new=True)\n        val = self.redis.get(self.prefix + sid)\n        if val is not None:\n            data = self.serializer.loads(val)\n            return self.session_class(data, sid=sid)\n        return self.session_class(sid=sid, new=True)\n\n    def save_session(self, app, session, response):\n        domain = self.get_cookie_domain(app)\n        if not session:\n            self.redis.delete(self.prefix + session.sid)\n            if session.modified:\n                response.delete_cookie(app.session_cookie_name,\n                                       domain=domain)\n            return\n        redis_exp = self.get_redis_expiration_time(app, session)\n        cookie_exp = self.get_expiration_time(app, session)\n        val = self.serializer.dumps(dict(session))\n        self.redis.setex(self.prefix + session.sid, val,\n                         int(redis_exp.total_seconds()))\n        response.set_cookie(app.session_cookie_name, session.sid,\n                            expires=cookie_exp, httponly=True,\n                            domain=domain)\n\n\nif __name__ == '__main__':\n    pass\n"
  },
  {
    "path": "app_backend/lib/sendcloud.py",
    "content": "#!/usr/bin/env python\n# encoding: utf-8\n\n\"\"\"\n@author: zhanghe\n@software: PyCharm\n@file: sendcloud.py\n@time: 16-5-2 下午12:30\n\"\"\"\n\n\nimport requests\nimport json\n\n\nclass SendCloudClient(object):\n    \"\"\"\n    SendCloud 邮件发送平台\n    以下方法采用 API v2 (区别：请求地址，参数命名规则)\n    link: http://sendcloud.sohu.com/doc/email_v2/\n    仅列出常用接口，实际使用中定制\n    \"\"\"\n    def __init__(self, app=None):\n        \"\"\"\n        初始化应用\n        \"\"\"\n        if app is not None:\n            self._api_key = app.config.get('SENDCLOUD_API_KEY', '')\n            self._api_user = app.config.get('SENDCLOUD_API_USER', '')\n\n    def userinfo_get(self):\n        \"\"\"\n        用户信息 查询\n        \"\"\"\n        api_url = 'http://api.sendcloud.net/apiv2/userinfo/get'\n        params = {\n            'apiUser': self._api_user,\n            'apiKey': self._api_key\n        }\n        return requests.get(api_url, params=params).json()\n\n    def mail_send(self, mail_from, mail_to, mail_subject, mail_html):\n        \"\"\"\n        普通发送\n        \"\"\"\n        api_url = 'http://api.sendcloud.net/apiv2/mail/send'\n        params = {\n            'apiUser': self._api_user,      # API_USER\n            'apiKey': self._api_key,        # API_KEY\n            'from': mail_from,              # 发件人地址\n            'to': mail_to,                  # 收件人地址. 多个地址使用';'分隔\n            'subject': mail_subject,        # 邮件标题\n            'html': mail_html,              # 邮件的内容. 邮件格式为 text/html\n        }\n        return requests.post(api_url, data=params).json()\n\n    def mail_sendtemplate(self, mail_from, xsmtpapi, mail_subject, template_name):\n        \"\"\"\n        模板发送 不用地址列表\n        xsmtpapi = {\n            'to': ['test1@ifaxin.com', 'test2@ifaxin.com'],\n            'sub': {\n                '%name%': ['user1', 'user2'],\n                '%money%': ['1000', '2000'],\n            }\n        }\n        \"\"\"\n        api_url = 'http://api.sendcloud.net/apiv2/mail/sendtemplate'\n        params = {\n            'apiUser': self._api_user,              # API_USER\n            'apiKey': self._api_key,                # API_KEY\n            'from': mail_from,                      # 发件人地址\n            'xsmtpapi': json.dumps(xsmtpapi),       # SMTP 扩展字段\n            'subject': mail_subject,                # 邮件标题\n            'templateInvokeName': template_name,    # 邮件模板调用名称\n        }\n        return requests.post(api_url, data=params).json()\n\n    def label_list(self, query, start=0, limit=100):\n        \"\"\"\n        邮件标签 查询 ( 批量查询 )\n        \"\"\"\n        api_url = 'http://api.sendcloud.net/apiv2/label/list'\n        params = {\n            'apiUser': self._api_user,\n            'apiKey': self._api_key,\n            'query': query,\n            'start': start,\n            'limit': limit\n        }\n        return requests.get(api_url, params=params).json()\n\n    def addresslist_list(self, address, start=0, limit=100):\n        \"\"\"\n        查询地址列表 ( 批量查询 )\n        \"\"\"\n        api_url = 'http://api.sendcloud.net/apiv2/addresslist/list'\n        params = {\n            'apiUser': self._api_user,\n            'apiKey': self._api_key,\n            'address': address,\n            'start': start,\n            'limit': limit\n        }\n        return requests.get(api_url, params=params).json()\n\n\nif __name__ == '__main__':\n    pass\n"
  },
  {
    "path": "app_backend/lib/session.py",
    "content": "#!/usr/bin/env python\n# encoding: utf-8\n\n\"\"\"\n@author: zhanghe\n@software: PyCharm\n@file: session.py\n@time: 16-8-3 下午5:56\n\"\"\"\n\n\nimport redis\nimport json\nfrom datetime import timedelta\nfrom itsdangerous import TimestampSigner, SignatureExpired, BadTimeSignature\n\n\nredis_client = redis.StrictRedis(host='localhost', port=6379, db=0)\n\n\nclass Session(object):\n    \"\"\"\n    基于redis的会话管理 数据结构：字符串（用户信息序列化）\n    \"\"\"\n    # 定义支持的实体类型\n    entity_name_list = ['web', 'app']\n    # 设置 key 生命周期\n    time_out = 7200\n    ttl = timedelta(seconds=time_out)\n    # 设置签名密钥\n    _sign_key = '121e65bfbc1012625643b21b0a5cecdd'\n\n    def __init__(self, entity_name, prefix='session'):\n        if entity_name not in self.entity_name_list:\n            raise TypeError(u'类型错误')\n        self.entity_name = entity_name\n        self.prefix = prefix\n\n    @staticmethod\n    def generate_sign_key(length=32):\n        \"\"\"\n        生成签名密钥\n        121e65bfbc1012625643b21b0a5cecdd\n        \"\"\"\n        import os\n        import binascii\n        sk = os.urandom(length/2)\n        # print sk\n        # print binascii.b2a_hex(sk)\n        return binascii.b2a_hex(sk)\n\n    def sign(self, session_id):\n        \"\"\"\n        签名 session_id\n        :param session_id: 通常是uuid\n        :return:\n        \"\"\"\n        s = TimestampSigner(self._sign_key)\n        return s.sign(session_id)\n\n    def un_sign(self, sign_session_id):\n        \"\"\"\n        校验签名 session_id\n        :param sign_session_id:\n        :return:\n        \"\"\"\n        s = TimestampSigner(self._sign_key)\n        try:\n            session_id = s.unsign(sign_session_id, max_age=self.time_out)\n            return session_id\n        except SignatureExpired as e:\n            # 处理签名超时\n            raise Exception(e.message)\n        except BadTimeSignature as e:\n            # 处理签名错误\n            raise Exception(e.message)\n\n    def add_item(self, key_id, item):\n        \"\"\"\n        添加 item\n        :param key_id:\n        :param item:\n        :return:0/1\n        \"\"\"\n        key = \"%s:%s:%s\" % (self.prefix, self.entity_name, key_id)\n        return redis_client.set(key, item, ex=self.ttl)\n\n    def get_item(self, key_id):\n        \"\"\"\n        获取 item\n        :param key_id:\n        :return:None/String\n        \"\"\"\n        key = \"%s:%s:%s\" % (self.prefix, self.entity_name, key_id)\n        return redis_client.get(key)\n\n    def del_item(self, key_id):\n        \"\"\"\n        删除 item\n        :param key_id:\n        :return:0/1\n        \"\"\"\n        key = \"%s:%s:%s\" % (self.prefix, self.entity_name, key_id)\n        return redis_client.delete(key)\n\n\ndef test_session():\n    \"\"\"\n    测试\n    a1282b2e1e2791b639f99417e7bbfe74\n    sdf54657dry0wetwete34.CoNfJA.LafZyL4wc77gmry9P7PPjgLGMlw\n    sdf54657dry0wetwete34\n    True\n    {\"province\": \"\\u4e0a\\u6d77\", \"openid\": \"o9XD1weif6-0g_5MvZa7Bx6OkwxA\", \"headimgurl\": \"http://wx.qlogo.cn/mmopen/ALImIJLVKZtPiaaVkcKFR58xpgibiaxabiaStZYcwVNIfz4Tl8VkqzqpV5fKiaibbRGfkY2lDR9SlibQvVm2ClHD6AIhBYQeuy32qaj/0\", \"language\": \"zh_CN\", \"city\": \"\\u95f8\\u5317\", \"privilege\": [], \"country\": \"\\u4e2d\\u56fd\", \"nickname\": \"\\u788eping\\u5b50\", \"sex\": 1}\n    碎ping子\n    \"\"\"\n    session_app = Session('app')\n    print session_app.generate_sign_key()\n    session_id = 'sdf54657dry0wetwete34'\n    session_id_sign = session_app.sign(session_id)\n    print session_id_sign\n    print session_app.un_sign(session_id_sign)\n    user_info = {\n        \"province\": \"上海\",\n        \"openid\": \"o9XD1weif6-0g_5MvZa7Bx6OkwxA\",\n        \"headimgurl\": \"http://wx.qlogo.cn/mmopen/ALImIJLVKZtPiaaVkcKFR58xpgibiaxabiaStZYcwVNIfz4Tl8VkqzqpV5fKiaibbRGfkY2lDR9SlibQvVm2ClHD6AIhBYQeuy32qaj/0\",\n        \"language\": \"zh_CN\",\n        \"city\": \"闸北\",\n        \"privilege\": [],\n        \"country\": \"中国\",\n        \"nickname\": \"碎ping子\",\n        \"sex\": 1\n    }\n    user_info_str = json.dumps(user_info)\n    print session_app.add_item(session_id, user_info_str)\n    user_info_str = session_app.get_item(session_id)\n    print user_info_str\n    print json.loads(user_info_str).get('nickname')\n\n\nif __name__ == '__main__':\n    test_session()\n"
  },
  {
    "path": "app_backend/lib/sms_chuanglan.py",
    "content": "#!/usr/bin/env python\r\n# encoding: utf-8\r\n\r\n\"\"\"\r\n@author: zhanghe\r\n@software: PyCharm\r\n@file: cart.py\r\n@time: 16-1-27 上午10:27\r\n\"\"\"\r\n\r\n\r\nimport requests\r\n\r\n\r\n# 服务地址\r\nhost = \"sms.253.com\"\r\n\r\n# 端口号\r\nport = 80\r\n\r\n# 版本号\r\nversion = \"v1.1\"\r\n\r\n# 查账户信息的URI\r\nbalance_get_uri = \"/msg/balance\"\r\n\r\n# 智能匹配模版短信接口的URI\r\nsms_send_uri = \"/msg/send\"\r\n\r\n# 创蓝账号\r\nun = \"xxxx\"\r\n\r\n# 创蓝密码\r\npw = \"xxxx\"\r\n\r\n\r\ndef get_user_balance():\r\n    \"\"\"\r\n    取账户余额\r\n    \"\"\"\r\n    url = 'http://%s%s' % (host, balance_get_uri)\r\n    params = {\r\n        'un': un,  # 账号\r\n        'pw': pw,  # 密码\r\n    }\r\n    return requests.get(url, params).text\r\n\r\n\r\ndef send_sms(msg, phone):\r\n    \"\"\"\r\n    接口发短信\r\n    \"\"\"\r\n    url = 'http://%s%s' % (host, sms_send_uri)\r\n    params = {\r\n        'un': un,           # 账号\r\n        'pw': pw,           # 密码\r\n        'msg': msg,         # 消息\r\n        'phone': phone,     # 手机\r\n        'rd': 1,            # 是否需要状态报告\r\n    }\r\n    headers = {\"Content-type\": \"application/x-www-form-urlencoded\", \"Accept\": \"text/plain\"}\r\n    return requests.post(url, data=params, headers=headers, timeout=30).text\r\n\r\n\r\nif __name__ == '__main__':\r\n    user_phone = \"188xxxxxxxx\"\r\n    user_msg = \"【您的签名】您的验证码是1234\"\r\n\r\n    # 查账户余额\r\n    print(get_user_balance())\r\n\r\n    # 调用智能匹配模版接口发短信\r\n    print(send_sms(user_msg, user_phone))\r\n"
  },
  {
    "path": "app_backend/lib/sms_chuanglan_iso.py",
    "content": "#!/usr/bin/env python\n# encoding: utf-8\n\n\"\"\"\n@author: zhanghe\n@software: PyCharm\n@file: sms_chuanglan_iso.py.py\n@time: 2017/3/3 下午10:03\n\"\"\"\n\n\nimport requests\n\n\nfrom config import current_config\n\nREQUESTS_TIME_OUT = current_config.REQUESTS_TIME_OUT\n\n\nclass SmsChuangLanIsoApi(object):\n    \"\"\"\n    创蓝国际短信接口\n    \"\"\"\n    ISENDURL = 'http://222.73.117.140:8044/mt'  # 单发接口\n    IQUERYURL = 'http://222.73.117.140:8044/bi'  # 查询余额接口\n    BAT_SENDURL = 'http://222.73.117.140:8044/batchmt'  # 群发接口\n\n    ERROR_DICT = {\n        '0': u'提交成功',\n        '101': u'无此用户',\n        '102': u'密码错',\n        '103': u'提交过快（提交速度超过流速限制）',\n        '104': u'系统忙（因平台侧原因，暂时无法处理提交的短信）',\n        '105': u'敏感短信（短信内容包含敏感词）',\n        '106': u'消息长度错（>536或<=0）',\n        '107': u'包含错误的手机号码',\n        '108': u'手机号码个数错（群发>50000或<=0）',\n        '109': u'无发送额度（该用户可用短信数已使用完）',\n        '110': u'不在发送时间内',\n        '113': u'extno格式错（非数字或者长度不对）',\n        '116': u'签名不合法或未带签名（用户必须带签名的前提下）',\n        '117': u'IP地址认证错,请求调用的IP地址不是系统登记的IP地址',\n        '118': u'用户没有相应的发送权限（账号被禁止发送）',\n        '119': u'用户已过期',\n        '120': u'违反放盗用策略(日发限制) --自定义添加',\n        '121': u'必填参数。是否需要状态报告，取值true或false',\n        '122': u'5分钟内相同账号提交相同消息内容过多',\n        '123': u'发送类型错误',\n        '124': u'白模板匹配错误',\n        '125': u'匹配驳回模板，提交失败',\n        '126': u'审核通过模板匹配错误',\n    }\n\n    def __init__(self, account, password):\n        self._sendUrl = ''  # 发送短信接口url\n        self._queryBalanceUrl = ''  # 查询余额接口url\n        self._un = account  # 接口账号\n        self._pw = password  # 接口密码\n\n    def send_international(self, phone, content, is_report=0):\n        \"\"\"\n        发送国际短信\n        :param phone:\n        :param content:\n        :param is_report:\n        :return:\n        \"\"\"\n        params = {\n            'un': self._un,\n            'pw': self._pw,\n            'sm': content,\n            'da': phone,\n            'rd': is_report,\n            'rf': 2,\n            'tf': 3,\n        }\n        result = requests.get(self.ISENDURL, params, timeout=REQUESTS_TIME_OUT or 30).json()\n        return result\n\n    def query_balance_international(self):\n        \"\"\"\n        查询余额\n        :return:\n        \"\"\"\n        params = {\n            'un': self._un,\n            'pw': self._pw,\n            'rf': 2,\n        }\n        result = requests.get(self.IQUERYURL, params, timeout=REQUESTS_TIME_OUT or 30).json()\n        return result\n\n\nif __name__ == '__main__':\n    sms_client = SmsChuangLanIsoApi('接口账号', '接口账号')\n    # print sms_client.send_international('8613800000000', '欢迎您注册九重天会员，此次注册验证码为1234，请在2分钟内进入验证。【九重天】', 1)\n    print sms_client.query_balance_international()\n\n\n\"\"\"\n账号错误：\n{u'r': u'101', u'success': False}\n密码错误：\n{u'r': u'102', u'success': False}\n国内号码不加86，收不到短信，但是返回True\n{u'id': u'17030322181000000859', u'success': True}\n国内号码添加86，收到短信，也返回True\n{u'id': u'17030322211000000868', u'success': True}\n国内错误号码\n\"\"\"\n"
  },
  {
    "path": "app_backend/lib/token.py",
    "content": "#!/usr/bin/env python\n# encoding: utf-8\n\n\"\"\"\n@author: zhanghe\n@software: PyCharm\n@file: token.py\n@time: 16-4-4 下午9:31\n\"\"\"\n\n\nimport redis\nimport hashlib\nfrom base64 import urlsafe_b64encode, urlsafe_b64decode\nfrom datetime import timedelta\n\n\nredis_client = redis.StrictRedis(host='localhost', port=6379, db=0)\n\n\nclass Token(object):\n    \"\"\"\n    token（数据结构：字符串）\n    应用场景：\n    1）用户id为key, 存储token为值\n    2）用户id为key, 存储验证码为值\n    \"\"\"\n    # 定义支持的实体类型\n    entity_name_list = ['reg', 'login']\n    # 设置 key 生命周期\n    ttl = timedelta(seconds=60)\n    # 设置签名密钥\n    _sign_key = '05bed70ae968e133a86e3ce388f4509838bd7cbf753f01c3'\n\n    def __init__(self, entity_name, prefix='token'):\n        if entity_name not in self.entity_name_list:\n            raise TypeError(u'类型错误')\n        self.entity_name = entity_name\n        self.prefix = prefix\n\n    @staticmethod\n    def generate_sign_key():\n        \"\"\"\n        生成签名密钥\n        05bed70ae968e133a86e3ce388f4509838bd7cbf753f01c3\n        \"\"\"\n        import os\n        import binascii\n        sk = os.urandom(24)\n        # print sk\n        # print binascii.b2a_hex(sk)\n        return binascii.b2a_hex(sk)\n\n    def create_token(self):\n        \"\"\"\n        生成 token (基于 uuid)\n        \"\"\"\n        from uuid import uuid1\n        from itsdangerous import TimestampSigner\n        s = TimestampSigner(self._sign_key)\n        return s.sign(str(uuid1()))\n\n    def check_token(self, token_sign):\n        \"\"\"\n        校验 token, 返回解密后的 token\n        \"\"\"\n        from itsdangerous import TimestampSigner, SignatureExpired, BadTimeSignature\n        s = TimestampSigner(self._sign_key)\n        try:\n            token = s.unsign(token_sign, max_age=60)  # 60秒过期\n            return {'success': token}\n        except SignatureExpired as e:\n            # 处理签名超时\n            return {'error': e.message}\n        except BadTimeSignature as e:\n            # 处理签名错误\n            return {'error': e.message}\n\n    def add_item(self, key_id, item):\n        \"\"\"\n        添加 item\n        :param key_id:\n        :param item:\n        :return:0/1\n        \"\"\"\n        key = \"%s:%s:%s\" % (self.prefix, self.entity_name, key_id)\n        return redis_client.set(key, item, ex=self.ttl)\n\n    def get_item(self, key_id):\n        \"\"\"\n        获取 item\n        :param key_id:\n        :return:None/String\n        \"\"\"\n        key = \"%s:%s:%s\" % (self.prefix, self.entity_name, key_id)\n        return redis_client.get(key)\n\n    def del_item(self, key_id):\n        \"\"\"\n        删除 item\n        :param key_id:\n        :return:0/1\n        \"\"\"\n        key = \"%s:%s:%s\" % (self.prefix, self.entity_name, key_id)\n        return redis_client.delete(key)\n\n\ndef test_token():\n    \"\"\"\n    测试\n    127.0.0.1:6379> get \"token:reg:0020\"\n    \"9B6E\"\n    \"\"\"\n    token_reg = Token('reg')\n    # print token_reg.add_item('0020', '9B6E')\n    print token_reg.get_item('0020')\n    print token_reg.del_item('0021')\n    # print token_reg.del_item('0020')\n\nif __name__ == '__main__':\n    test_token()\n    # print urlsafe_b64encode('05bed70ae968e133a86e3ce388f4509838bd7cbf753f01c3')\n"
  },
  {
    "path": "app_backend/login.py",
    "content": "#!/usr/bin/env python\n# encoding: utf-8\n\n\"\"\"\n@author: zhanghe\n@software: PyCharm\n@file: login.py\n@time: 17-4-20 下午1:46\n\"\"\"\n\n\nfrom app_backend.models import Admin\nfrom flask_login import UserMixin\n\n\nclass LoginUser(Admin, UserMixin):\n    \"\"\"\n    用户登录类\n    \"\"\"\n"
  },
  {
    "path": "app_backend/models.py",
    "content": "# coding: utf-8\nfrom sqlalchemy import Column, Date, DateTime, Index, Integer, Numeric, String, text\nfrom database import db\n\n\nBase = db.Model\nmetadata = Base.metadata\n\n\ndef to_dict(self):\n    \"\"\"\n    model 对象转 字典\n    model_obj.to_dict()\n    \"\"\"\n    return {c.name: getattr(self, c.name, None) for c in self.__table__.columns}\n\nBase.to_dict = to_dict\n\n\nclass Active(Base):\n    __tablename__ = 'active'\n\n    user_id = Column(Integer, primary_key=True)\n    amount = Column(Numeric(10, 0), nullable=False, server_default=text(\"'0'\"))\n    create_time = Column(DateTime, nullable=False, server_default=text(\"CURRENT_TIMESTAMP\"))\n    update_time = Column(DateTime, nullable=False, server_default=text(\"CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP\"))\n\n\nclass ActiveItem(Base):\n    __tablename__ = 'active_item'\n\n    id = Column(Integer, primary_key=True)\n    user_id = Column(Integer, nullable=False, index=True)\n    type = Column(Integer, nullable=False, server_default=text(\"'0'\"))\n    amount = Column(Numeric(8, 0), nullable=False, server_default=text(\"'0'\"))\n    sc_id = Column(Integer, nullable=False, index=True, server_default=text(\"'0'\"))\n    note = Column(String(256), nullable=False, server_default=text(\"''\"))\n    status_audit = Column(Integer, nullable=False, server_default=text(\"'0'\"))\n    status_delete = Column(Integer, nullable=False, server_default=text(\"'0'\"))\n    audit_time = Column(DateTime)\n    delete_time = Column(DateTime)\n    create_time = Column(DateTime, nullable=False, server_default=text(\"CURRENT_TIMESTAMP\"))\n    update_time = Column(DateTime, nullable=False, server_default=text(\"CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP\"))\n\n\nclass Admin(Base):\n    __tablename__ = 'admin'\n\n    id = Column(Integer, primary_key=True)\n    username = Column(String(20), nullable=False, unique=True, server_default=text(\"''\"))\n    password = Column(String(60), nullable=False, server_default=text(\"''\"))\n    area_id = Column(Integer, nullable=False, server_default=text(\"'0'\"))\n    area_code = Column(String(4), nullable=False, server_default=text(\"''\"))\n    phone = Column(String(20), nullable=False, server_default=text(\"''\"))\n    role_id = Column(Integer, nullable=False, server_default=text(\"'1'\"))\n    status_delete = Column(Integer, nullable=False, server_default=text(\"'0'\"))\n    delete_time = Column(DateTime)\n    login_time = Column(DateTime)\n    login_ip = Column(String(20))\n    create_time = Column(DateTime, nullable=False, server_default=text(\"CURRENT_TIMESTAMP\"))\n    update_time = Column(DateTime, nullable=False, server_default=text(\"CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP\"))\n\n\nclass AdminRole(Base):\n    __tablename__ = 'admin_role'\n\n    id = Column(Integer, primary_key=True)\n    name = Column(String(20), nullable=False, unique=True, server_default=text(\"''\"))\n    note = Column(String(256), nullable=False, server_default=text(\"''\"))\n    module = Column(String(256), nullable=False, server_default=text(\"''\"))\n    create_time = Column(DateTime, nullable=False, server_default=text(\"CURRENT_TIMESTAMP\"))\n    update_time = Column(DateTime, nullable=False, server_default=text(\"CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP\"))\n\n\nclass ApplyGet(Base):\n    __tablename__ = 'apply_get'\n\n    id = Column(Integer, primary_key=True)\n    user_id = Column(Integer, nullable=False, index=True)\n    type_apply = Column(Integer, nullable=False, server_default=text(\"'0'\"))\n    type_pay = Column(Integer, nullable=False, server_default=text(\"'0'\"))\n    type_withdraw = Column(Integer, nullable=False, server_default=text(\"'0'\"))\n    money_apply = Column(Numeric(8, 2), nullable=False, server_default=text(\"'0.00'\"))\n    money_order = Column(Numeric(8, 2), nullable=False, server_default=text(\"'0.00'\"))\n    status_apply = Column(Integer, nullable=False, server_default=text(\"'0'\"))\n    status_order = Column(Integer, nullable=False, server_default=text(\"'0'\"))\n    status_delete = Column(Integer, nullable=False, server_default=text(\"'0'\"))\n    delete_time = Column(DateTime)\n    create_time = Column(DateTime, nullable=False, server_default=text(\"CURRENT_TIMESTAMP\"))\n    update_time = Column(DateTime, nullable=False, server_default=text(\"CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP\"))\n\n\nclass ApplyPut(Base):\n    __tablename__ = 'apply_put'\n\n    id = Column(Integer, primary_key=True)\n    user_id = Column(Integer, nullable=False, index=True)\n    type_apply = Column(Integer, nullable=False, server_default=text(\"'0'\"))\n    type_pay = Column(Integer, nullable=False, server_default=text(\"'0'\"))\n    money_apply = Column(Numeric(8, 2), nullable=False, server_default=text(\"'0.00'\"))\n    money_order = Column(Numeric(8, 2), nullable=False, server_default=text(\"'0.00'\"))\n    status_apply = Column(Integer, nullable=False, server_default=text(\"'0'\"))\n    status_order = Column(Integer, nullable=False, server_default=text(\"'0'\"))\n    status_delete = Column(Integer, nullable=False, server_default=text(\"'0'\"))\n    delete_time = Column(DateTime)\n    create_time = Column(DateTime, nullable=False, server_default=text(\"CURRENT_TIMESTAMP\"))\n    update_time = Column(DateTime, nullable=False, server_default=text(\"CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP\"))\n\n\nclass AreaCode(Base):\n    __tablename__ = 'area_code'\n\n    id = Column(Integer, primary_key=True)\n    short_code = Column(String(2), nullable=False, server_default=text(\"''\"))\n    area_code = Column(String(4), nullable=False, server_default=text(\"''\"))\n    phone_pre = Column(String(7), nullable=False, server_default=text(\"''\"))\n    name_c = Column(String(20), nullable=False, server_default=text(\"''\"))\n    name_e = Column(String(20), nullable=False, server_default=text(\"''\"))\n    country_area = Column(String(20), nullable=False, server_default=text(\"''\"))\n    create_time = Column(DateTime, nullable=False, server_default=text(\"CURRENT_TIMESTAMP\"))\n    update_time = Column(DateTime, nullable=False, server_default=text(\"CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP\"))\n\n\nclass BitCoin(Base):\n    __tablename__ = 'bit_coin'\n\n    user_id = Column(Integer, primary_key=True)\n    amount = Column(Numeric(10, 2), nullable=False, server_default=text(\"'0.00'\"))\n    create_time = Column(DateTime, nullable=False, server_default=text(\"CURRENT_TIMESTAMP\"))\n    update_time = Column(DateTime, nullable=False, server_default=text(\"CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP\"))\n\n\nclass BitCoinItem(Base):\n    __tablename__ = 'bit_coin_item'\n\n    id = Column(Integer, primary_key=True)\n    user_id = Column(Integer, nullable=False, index=True)\n    type = Column(Integer, nullable=False, server_default=text(\"'0'\"))\n    amount = Column(Numeric(8, 2), nullable=False, server_default=text(\"'0.00'\"))\n    sc_id = Column(Integer, nullable=False, index=True, server_default=text(\"'0'\"))\n    note = Column(String(256), nullable=False, server_default=text(\"''\"))\n    status_audit = Column(Integer, nullable=False, server_default=text(\"'0'\"))\n    status_delete = Column(Integer, nullable=False, server_default=text(\"'0'\"))\n    audit_time = Column(DateTime)\n    delete_time = Column(DateTime)\n    create_time = Column(DateTime, nullable=False, server_default=text(\"CURRENT_TIMESTAMP\"))\n    update_time = Column(DateTime, nullable=False, server_default=text(\"CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP\"))\n\n\nclass Bonus(Base):\n    __tablename__ = 'bonus'\n\n    user_id = Column(Integer, primary_key=True)\n    amount = Column(Numeric(10, 2), nullable=False, server_default=text(\"'0.00'\"))\n    create_time = Column(DateTime, nullable=False, server_default=text(\"CURRENT_TIMESTAMP\"))\n    update_time = Column(DateTime, nullable=False, server_default=text(\"CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP\"))\n\n\nclass BonusItem(Base):\n    __tablename__ = 'bonus_item'\n\n    id = Column(Integer, primary_key=True)\n    user_id = Column(Integer, nullable=False, index=True)\n    type = Column(Integer, nullable=False, server_default=text(\"'0'\"))\n    amount = Column(Numeric(8, 2), nullable=False, server_default=text(\"'0.00'\"))\n    sc_id = Column(Integer, nullable=False, index=True, server_default=text(\"'0'\"))\n    note = Column(String(256), nullable=False, server_default=text(\"''\"))\n    status_audit = Column(Integer, nullable=False, server_default=text(\"'0'\"))\n    status_delete = Column(Integer, nullable=False, server_default=text(\"'0'\"))\n    audit_time = Column(DateTime)\n    delete_time = Column(DateTime)\n    create_time = Column(DateTime, nullable=False, server_default=text(\"CURRENT_TIMESTAMP\"))\n    update_time = Column(DateTime, nullable=False, server_default=text(\"CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP\"))\n\n\nclass Complaint(Base):\n    __tablename__ = 'complaint'\n\n    id = Column(Integer, primary_key=True)\n    send_user_id = Column(Integer, nullable=False, index=True)\n    receive_user_id = Column(Integer, nullable=False, index=True)\n    reply_admin_id = Column(Integer, nullable=False, index=True, server_default=text(\"'0'\"))\n    content = Column(String(512), nullable=False, server_default=text(\"''\"))\n    content_reply = Column(String(512), nullable=False, server_default=text(\"''\"))\n    status_reply = Column(Integer, nullable=False, server_default=text(\"'0'\"))\n    reply_time = Column(DateTime)\n    status_delete = Column(Integer, nullable=False, server_default=text(\"'0'\"))\n    delete_time = Column(DateTime)\n    create_time = Column(DateTime, nullable=False, server_default=text(\"CURRENT_TIMESTAMP\"))\n    update_time = Column(DateTime, nullable=False, server_default=text(\"CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP\"))\n\n\nclass Credit(Base):\n    __tablename__ = 'credit'\n\n    user_id = Column(Integer, primary_key=True)\n    behavior = Column(Numeric(3, 0), nullable=False, server_default=text(\"'0'\"))\n    characteristics = Column(Numeric(3, 0), nullable=False, server_default=text(\"'0'\"))\n    connections = Column(Numeric(3, 0), nullable=False, server_default=text(\"'0'\"))\n    history = Column(Numeric(3, 0), nullable=False, server_default=text(\"'0'\"))\n    performance = Column(Numeric(3, 0), nullable=False, server_default=text(\"'0'\"))\n    credit = Column(Numeric(3, 0), nullable=False, server_default=text(\"'0'\"))\n    create_time = Column(DateTime, nullable=False, server_default=text(\"CURRENT_TIMESTAMP\"))\n    update_time = Column(DateTime, nullable=False, server_default=text(\"CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP\"))\n\n\nclass Message(Base):\n    __tablename__ = 'message'\n\n    id = Column(Integer, primary_key=True)\n    send_user_id = Column(Integer, nullable=False, index=True)\n    receive_user_id = Column(Integer, nullable=False, index=True)\n    content = Column(String(512), nullable=False, server_default=text(\"''\"))\n    status_delete = Column(Integer, nullable=False, server_default=text(\"'0'\"))\n    delete_time = Column(DateTime)\n    create_time = Column(DateTime, nullable=False, server_default=text(\"CURRENT_TIMESTAMP\"))\n    update_time = Column(DateTime, nullable=False, server_default=text(\"CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP\"))\n\n\nclass Order(Base):\n    __tablename__ = 'order'\n\n    id = Column(Integer, primary_key=True)\n    apply_put_id = Column(Integer, nullable=False, index=True)\n    apply_get_id = Column(Integer, nullable=False, index=True)\n    apply_put_uid = Column(Integer, nullable=False, index=True)\n    apply_get_uid = Column(Integer, nullable=False, index=True)\n    type = Column(Integer, nullable=False, server_default=text(\"'0'\"))\n    money = Column(Numeric(8, 2), nullable=False, server_default=text(\"'0.00'\"))\n    status_audit = Column(Integer, nullable=False, server_default=text(\"'0'\"))\n    status_flow = Column(Integer, nullable=False, server_default=text(\"'0'\"))\n    status_pay = Column(Integer, nullable=False, server_default=text(\"'0'\"))\n    status_rec = Column(Integer, nullable=False, server_default=text(\"'0'\"))\n    status_delete = Column(Integer, nullable=False, server_default=text(\"'0'\"))\n    audit_time = Column(DateTime)\n    pay_time = Column(DateTime)\n    rec_time = Column(DateTime)\n    delete_time = Column(DateTime)\n    create_time = Column(DateTime, nullable=False, server_default=text(\"CURRENT_TIMESTAMP\"))\n    update_time = Column(DateTime, nullable=False, server_default=text(\"CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP\"))\n\n\nclass OrderBill(Base):\n    __tablename__ = 'order_bill'\n\n    id = Column(Integer, primary_key=True)\n    order_id = Column(Integer, nullable=False, index=True)\n    bill_img = Column(String(255))\n    status_audit = Column(Integer, nullable=False, server_default=text(\"'0'\"))\n    status_delete = Column(Integer, nullable=False, server_default=text(\"'0'\"))\n    audit_time = Column(DateTime)\n    delete_time = Column(DateTime)\n    create_time = Column(DateTime, nullable=False, server_default=text(\"CURRENT_TIMESTAMP\"))\n    update_time = Column(DateTime, nullable=False, server_default=text(\"CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP\"))\n\n\nclass OrderFlow(Base):\n    __tablename__ = 'order_flow'\n\n    order_id = Column(Integer, primary_key=True)\n    flow_order_id = Column(Integer, nullable=False, index=True)\n    apply_put_id = Column(Integer, nullable=False, index=True)\n    apply_get_id = Column(Integer, nullable=False, index=True)\n    apply_put_uid = Column(Integer, nullable=False, index=True)\n    apply_get_uid = Column(Integer, nullable=False, index=True)\n    create_time = Column(DateTime, nullable=False, server_default=text(\"CURRENT_TIMESTAMP\"))\n    update_time = Column(DateTime, nullable=False, server_default=text(\"CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP\"))\n\n\nclass Scheduling(Base):\n    __tablename__ = 'scheduling'\n\n    user_id = Column(Integer, primary_key=True)\n    amount = Column(Numeric(10, 2), nullable=False, server_default=text(\"'0.00'\"))\n    create_time = Column(DateTime, nullable=False, server_default=text(\"CURRENT_TIMESTAMP\"))\n    update_time = Column(DateTime, nullable=False, server_default=text(\"CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP\"))\n\n\nclass SchedulingItem(Base):\n    __tablename__ = 'scheduling_item'\n\n    id = Column(Integer, primary_key=True)\n    user_id = Column(Integer, nullable=False, index=True)\n    type = Column(Integer, nullable=False, server_default=text(\"'0'\"))\n    amount = Column(Numeric(8, 2), nullable=False, server_default=text(\"'0.00'\"))\n    sc_id = Column(Integer, nullable=False, index=True, server_default=text(\"'0'\"))\n    note = Column(String(256), nullable=False, server_default=text(\"''\"))\n    status_audit = Column(Integer, nullable=False, server_default=text(\"'0'\"))\n    status_delete = Column(Integer, nullable=False, server_default=text(\"'0'\"))\n    audit_time = Column(DateTime)\n    delete_time = Column(DateTime)\n    create_time = Column(DateTime, nullable=False, server_default=text(\"CURRENT_TIMESTAMP\"))\n    update_time = Column(DateTime, nullable=False, server_default=text(\"CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP\"))\n\n\nclass Score(Base):\n    __tablename__ = 'score'\n\n    user_id = Column(Integer, primary_key=True)\n    amount = Column(Numeric(10, 2), nullable=False, server_default=text(\"'0.00'\"))\n    create_time = Column(DateTime, nullable=False, server_default=text(\"CURRENT_TIMESTAMP\"))\n    update_time = Column(DateTime, nullable=False, server_default=text(\"CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP\"))\n\n\nclass ScoreCharity(Base):\n    __tablename__ = 'score_charity'\n\n    user_id = Column(Integer, primary_key=True)\n    amount = Column(Numeric(10, 2), nullable=False, server_default=text(\"'0.00'\"))\n    create_time = Column(DateTime, nullable=False, server_default=text(\"CURRENT_TIMESTAMP\"))\n    update_time = Column(DateTime, nullable=False, server_default=text(\"CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP\"))\n\n\nclass ScoreCharityItem(Base):\n    __tablename__ = 'score_charity_item'\n\n    id = Column(Integer, primary_key=True)\n    user_id = Column(Integer, nullable=False, index=True)\n    type = Column(Integer, nullable=False, server_default=text(\"'0'\"))\n    amount = Column(Numeric(8, 2), nullable=False, server_default=text(\"'0.00'\"))\n    sc_id = Column(Integer, nullable=False, index=True, server_default=text(\"'0'\"))\n    note = Column(String(256), nullable=False, server_default=text(\"''\"))\n    status_audit = Column(Integer, nullable=False, server_default=text(\"'0'\"))\n    status_delete = Column(Integer, nullable=False, server_default=text(\"'0'\"))\n    audit_time = Column(DateTime)\n    delete_time = Column(DateTime)\n    create_time = Column(DateTime, nullable=False, server_default=text(\"CURRENT_TIMESTAMP\"))\n    update_time = Column(DateTime, nullable=False, server_default=text(\"CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP\"))\n\n\nclass ScoreDigital(Base):\n    __tablename__ = 'score_digital'\n\n    user_id = Column(Integer, primary_key=True)\n    amount = Column(Numeric(10, 2), nullable=False, server_default=text(\"'0.00'\"))\n    create_time = Column(DateTime, nullable=False, server_default=text(\"CURRENT_TIMESTAMP\"))\n    update_time = Column(DateTime, nullable=False, server_default=text(\"CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP\"))\n\n\nclass ScoreDigitalItem(Base):\n    __tablename__ = 'score_digital_item'\n\n    id = Column(Integer, primary_key=True)\n    user_id = Column(Integer, nullable=False, index=True)\n    type = Column(Integer, nullable=False, server_default=text(\"'0'\"))\n    amount = Column(Numeric(8, 2), nullable=False, server_default=text(\"'0.00'\"))\n    sc_id = Column(Integer, nullable=False, index=True, server_default=text(\"'0'\"))\n    note = Column(String(256), nullable=False, server_default=text(\"''\"))\n    status_audit = Column(Integer, nullable=False, server_default=text(\"'0'\"))\n    status_delete = Column(Integer, nullable=False, server_default=text(\"'0'\"))\n    audit_time = Column(DateTime)\n    delete_time = Column(DateTime)\n    create_time = Column(DateTime, nullable=False, server_default=text(\"CURRENT_TIMESTAMP\"))\n    update_time = Column(DateTime, nullable=False, server_default=text(\"CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP\"))\n\n\nclass ScoreExpense(Base):\n    __tablename__ = 'score_expense'\n\n    user_id = Column(Integer, primary_key=True)\n    amount = Column(Numeric(10, 2), nullable=False, server_default=text(\"'0.00'\"))\n    create_time = Column(DateTime, nullable=False, server_default=text(\"CURRENT_TIMESTAMP\"))\n    update_time = Column(DateTime, nullable=False, server_default=text(\"CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP\"))\n\n\nclass ScoreExpenseItem(Base):\n    __tablename__ = 'score_expense_item'\n\n    id = Column(Integer, primary_key=True)\n    user_id = Column(Integer, nullable=False, index=True)\n    type = Column(Integer, nullable=False, server_default=text(\"'0'\"))\n    amount = Column(Numeric(8, 2), nullable=False, server_default=text(\"'0.00'\"))\n    sc_id = Column(Integer, nullable=False, index=True, server_default=text(\"'0'\"))\n    note = Column(String(256), nullable=False, server_default=text(\"''\"))\n    status_audit = Column(Integer, nullable=False, server_default=text(\"'0'\"))\n    status_delete = Column(Integer, nullable=False, server_default=text(\"'0'\"))\n    audit_time = Column(DateTime)\n    delete_time = Column(DateTime)\n    create_time = Column(DateTime, nullable=False, server_default=text(\"CURRENT_TIMESTAMP\"))\n    update_time = Column(DateTime, nullable=False, server_default=text(\"CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP\"))\n\n\nclass ScoreItem(Base):\n    __tablename__ = 'score_item'\n\n    id = Column(Integer, primary_key=True)\n    user_id = Column(Integer, nullable=False, index=True)\n    type = Column(Integer, nullable=False, server_default=text(\"'0'\"))\n    amount = Column(Numeric(8, 2), nullable=False, server_default=text(\"'0.00'\"))\n    sc_id = Column(Integer, nullable=False, index=True, server_default=text(\"'0'\"))\n    note = Column(String(256), nullable=False, server_default=text(\"''\"))\n    status_audit = Column(Integer, nullable=False, server_default=text(\"'0'\"))\n    status_delete = Column(Integer, nullable=False, server_default=text(\"'0'\"))\n    audit_time = Column(DateTime)\n    delete_time = Column(DateTime)\n    create_time = Column(DateTime, nullable=False, server_default=text(\"CURRENT_TIMESTAMP\"))\n    update_time = Column(DateTime, nullable=False, server_default=text(\"CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP\"))\n\n\nclass User(Base):\n    __tablename__ = 'user'\n\n    id = Column(Integer, primary_key=True)\n    status_active = Column(Integer, nullable=False, server_default=text(\"'0'\"))\n    status_lock = Column(Integer, nullable=False, server_default=text(\"'0'\"))\n    status_real_name = Column(Integer, nullable=False, server_default=text(\"'0'\"))\n    status_delete = Column(Integer, nullable=False, server_default=text(\"'0'\"))\n    active_time = Column(DateTime)\n    lock_time = Column(DateTime)\n    delete_time = Column(DateTime)\n    reg_ip = Column(String(20))\n    login_ip = Column(String(20))\n    login_time = Column(DateTime)\n    create_time = Column(DateTime, nullable=False, server_default=text(\"CURRENT_TIMESTAMP\"))\n    update_time = Column(DateTime, nullable=False, server_default=text(\"CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP\"))\n\n\nclass UserAuth(Base):\n    __tablename__ = 'user_auth'\n    __table_args__ = (\n        Index('type_auth', 'type_auth', 'auth_key', unique=True),\n    )\n\n    id = Column(Integer, primary_key=True)\n    user_id = Column(Integer, nullable=False, index=True, server_default=text(\"'0'\"))\n    type_auth = Column(Integer, nullable=False, server_default=text(\"'0'\"))\n    auth_key = Column(String(60), nullable=False, server_default=text(\"''\"))\n    auth_secret = Column(String(60), nullable=False, server_default=text(\"''\"))\n    status_verified = Column(Integer, nullable=False, server_default=text(\"'0'\"))\n    create_time = Column(DateTime, nullable=False, server_default=text(\"CURRENT_TIMESTAMP\"))\n    update_time = Column(DateTime, nullable=False, server_default=text(\"CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP\"))\n\n\nclass UserBank(Base):\n    __tablename__ = 'user_bank'\n\n    user_id = Column(Integer, primary_key=True)\n    account_name = Column(String(60), nullable=False, server_default=text(\"'0'\"))\n    bank_name = Column(String(60), nullable=False, server_default=text(\"''\"))\n    bank_address = Column(String(60), nullable=False, server_default=text(\"''\"))\n    bank_account = Column(String(32), nullable=False, server_default=text(\"''\"))\n    status_verified = Column(Integer, nullable=False, server_default=text(\"'0'\"))\n    status_delete = Column(Integer, nullable=False, server_default=text(\"'0'\"))\n    create_time = Column(DateTime, nullable=False, server_default=text(\"CURRENT_TIMESTAMP\"))\n    update_time = Column(DateTime, nullable=False, server_default=text(\"CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP\"))\n\n\nclass UserConfig(Base):\n    __tablename__ = 'user_config'\n\n    user_id = Column(Integer, primary_key=True)\n    team_bonus = Column(String(100), server_default=text(\"''\"))\n    create_time = Column(DateTime, nullable=False, server_default=text(\"CURRENT_TIMESTAMP\"))\n    update_time = Column(DateTime, nullable=False, server_default=text(\"CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP\"))\n\n\nclass UserProfile(Base):\n    __tablename__ = 'user_profile'\n    __table_args__ = (\n        Index('ind_phone', 'area_id', 'phone'),\n        Index('ind_id_card', 'area_id', 'id_card')\n    )\n\n    user_id = Column(Integer, primary_key=True)\n    user_pid = Column(Integer, nullable=False, server_default=text(\"'0'\"))\n    nickname = Column(String(20), nullable=False, server_default=text(\"''\"))\n    type_level = Column(Integer, nullable=False, server_default=text(\"'0'\"))\n    avatar_url = Column(String(60))\n    email = Column(String(60), nullable=False, server_default=text(\"''\"))\n    area_id = Column(Integer, nullable=False, server_default=text(\"'0'\"))\n    area_code = Column(String(4), nullable=False, server_default=text(\"''\"))\n    phone = Column(String(20), nullable=False, server_default=text(\"''\"))\n    birthday = Column(Date, nullable=False, server_default=text(\"'1900-01-01'\"))\n    real_name = Column(String(20), nullable=False, server_default=text(\"''\"))\n    id_card = Column(String(32), nullable=False, server_default=text(\"''\"))\n    create_time = Column(DateTime, nullable=False, server_default=text(\"CURRENT_TIMESTAMP\"))\n    update_time = Column(DateTime, nullable=False, server_default=text(\"CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP\"))\n\n\nclass Wallet(Base):\n    __tablename__ = 'wallet'\n\n    user_id = Column(Integer, primary_key=True)\n    amount_initial = Column(Numeric(10, 2), nullable=False, server_default=text(\"'0.00'\"))\n    amount_current = Column(Numeric(10, 2), nullable=False, server_default=text(\"'0.00'\"))\n    amount_lock = Column(Numeric(10, 2), nullable=False, server_default=text(\"'0.00'\"))\n    create_time = Column(DateTime, nullable=False, server_default=text(\"CURRENT_TIMESTAMP\"))\n    update_time = Column(DateTime, nullable=False, server_default=text(\"CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP\"))\n\n\nclass WalletItem(Base):\n    __tablename__ = 'wallet_item'\n\n    id = Column(Integer, primary_key=True)\n    user_id = Column(Integer, nullable=False, index=True)\n    type = Column(Integer, nullable=False, server_default=text(\"'0'\"))\n    amount = Column(Numeric(8, 2), nullable=False, server_default=text(\"'0.00'\"))\n    sc_id = Column(Integer, nullable=False, index=True, server_default=text(\"'0'\"))\n    note = Column(String(256), nullable=False, server_default=text(\"''\"))\n    status_audit = Column(Integer, nullable=False, server_default=text(\"'0'\"))\n    status_delete = Column(Integer, nullable=False, server_default=text(\"'0'\"))\n    audit_time = Column(DateTime)\n    delete_time = Column(DateTime)\n    create_time = Column(DateTime, nullable=False, server_default=text(\"CURRENT_TIMESTAMP\"))\n    update_time = Column(DateTime, nullable=False, server_default=text(\"CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP\"))\n"
  },
  {
    "path": "app_backend/pages/blank.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n\n<head>\n\n    <meta charset=\"utf-8\">\n    <meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\">\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">\n    <meta name=\"description\" content=\"\">\n    <meta name=\"author\" content=\"\">\n\n    <title>SB Admin 2 - Bootstrap Admin Theme</title>\n\n    <!-- Bootstrap Core CSS -->\n    <link href=\"../static/css/bootstrap.min.css\" rel=\"stylesheet\">\n\n    <!-- MetisMenu CSS -->\n    <link href=\"../vendor/metisMenu/metisMenu.min.css\" rel=\"stylesheet\">\n\n    <!-- Custom CSS -->\n    <link href=\"../dist/css/sb-admin-2.css\" rel=\"stylesheet\">\n\n    <!-- Custom Fonts -->\n    <link href=\"../vendor/font-awesome/css/font-awesome.min.css\" rel=\"stylesheet\" type=\"text/css\">\n\n    <!-- HTML5 Shim and Respond.js IE8 support of HTML5 elements and media queries -->\n    <!-- WARNING: Respond.js doesn't work if you view the page via file:// -->\n    <!--[if lt IE 9]>\n        <script src=\"https://oss.maxcdn.com/libs/html5shiv/3.7.0/html5shiv.js\"></script>\n        <script src=\"https://oss.maxcdn.com/libs/respond.js/1.4.2/respond.min.js\"></script>\n    <![endif]-->\n\n</head>\n\n<body>\n\n    <div id=\"wrapper\">\n\n        <!-- Navigation -->\n        <nav class=\"navbar navbar-default navbar-static-top\" role=\"navigation\" style=\"margin-bottom: 0\">\n            <div class=\"navbar-header\">\n                <button type=\"button\" class=\"navbar-toggle\" data-toggle=\"collapse\" data-target=\".navbar-collapse\">\n                    <span class=\"sr-only\">Toggle navigation</span>\n                    <span class=\"icon-bar\"></span>\n                    <span class=\"icon-bar\"></span>\n                    <span class=\"icon-bar\"></span>\n                </button>\n                <a class=\"navbar-brand\" href=\"index.html\">SB Admin v2.0</a>\n            </div>\n            <!-- /.navbar-header -->\n\n            <ul class=\"nav navbar-top-links navbar-right\">\n                <li class=\"dropdown\">\n                    <a class=\"dropdown-toggle\" data-toggle=\"dropdown\" href=\"#\">\n                        <i class=\"fa fa-envelope fa-fw\"></i> <i class=\"fa fa-caret-down\"></i>\n                    </a>\n                    <ul class=\"dropdown-menu dropdown-messages\">\n                        <li>\n                            <a href=\"#\">\n                                <div>\n                                    <strong>John Smith</strong>\n                                    <span class=\"pull-right text-muted\">\n                                        <em>Yesterday</em>\n                                    </span>\n                                </div>\n                                <div>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque eleifend...</div>\n                            </a>\n                        </li>\n                        <li class=\"divider\"></li>\n                        <li>\n                            <a href=\"#\">\n                                <div>\n                                    <strong>John Smith</strong>\n                                    <span class=\"pull-right text-muted\">\n                                        <em>Yesterday</em>\n                                    </span>\n                                </div>\n                                <div>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque eleifend...</div>\n                            </a>\n                        </li>\n                        <li class=\"divider\"></li>\n                        <li>\n                            <a href=\"#\">\n                                <div>\n                                    <strong>John Smith</strong>\n                                    <span class=\"pull-right text-muted\">\n                                        <em>Yesterday</em>\n                                    </span>\n                                </div>\n                                <div>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque eleifend...</div>\n                            </a>\n                        </li>\n                        <li class=\"divider\"></li>\n                        <li>\n                            <a class=\"text-center\" href=\"#\">\n                                <strong>Read All Messages</strong>\n                                <i class=\"fa fa-angle-right\"></i>\n                            </a>\n                        </li>\n                    </ul>\n                    <!-- /.dropdown-messages -->\n                </li>\n                <!-- /.dropdown -->\n                <li class=\"dropdown\">\n                    <a class=\"dropdown-toggle\" data-toggle=\"dropdown\" href=\"#\">\n                        <i class=\"fa fa-tasks fa-fw\"></i> <i class=\"fa fa-caret-down\"></i>\n                    </a>\n                    <ul class=\"dropdown-menu dropdown-tasks\">\n                        <li>\n                            <a href=\"#\">\n                                <div>\n                                    <p>\n                                        <strong>Task 1</strong>\n                                        <span class=\"pull-right text-muted\">40% Complete</span>\n                                    </p>\n                                    <div class=\"progress progress-striped active\">\n                                        <div class=\"progress-bar progress-bar-success\" role=\"progressbar\" aria-valuenow=\"40\" aria-valuemin=\"0\" aria-valuemax=\"100\" style=\"width: 40%\">\n                                            <span class=\"sr-only\">40% Complete (success)</span>\n                                        </div>\n                                    </div>\n                                </div>\n                            </a>\n                        </li>\n                        <li class=\"divider\"></li>\n                        <li>\n                            <a href=\"#\">\n                                <div>\n                                    <p>\n                                        <strong>Task 2</strong>\n                                        <span class=\"pull-right text-muted\">20% Complete</span>\n                                    </p>\n                                    <div class=\"progress progress-striped active\">\n                                        <div class=\"progress-bar progress-bar-info\" role=\"progressbar\" aria-valuenow=\"20\" aria-valuemin=\"0\" aria-valuemax=\"100\" style=\"width: 20%\">\n                                            <span class=\"sr-only\">20% Complete</span>\n                                        </div>\n                                    </div>\n                                </div>\n                            </a>\n                        </li>\n                        <li class=\"divider\"></li>\n                        <li>\n                            <a href=\"#\">\n                                <div>\n                                    <p>\n                                        <strong>Task 3</strong>\n                                        <span class=\"pull-right text-muted\">60% Complete</span>\n                                    </p>\n                                    <div class=\"progress progress-striped active\">\n                                        <div class=\"progress-bar progress-bar-warning\" role=\"progressbar\" aria-valuenow=\"60\" aria-valuemin=\"0\" aria-valuemax=\"100\" style=\"width: 60%\">\n                                            <span class=\"sr-only\">60% Complete (warning)</span>\n                                        </div>\n                                    </div>\n                                </div>\n                            </a>\n                        </li>\n                        <li class=\"divider\"></li>\n                        <li>\n                            <a href=\"#\">\n                                <div>\n                                    <p>\n                                        <strong>Task 4</strong>\n                                        <span class=\"pull-right text-muted\">80% Complete</span>\n                                    </p>\n                                    <div class=\"progress progress-striped active\">\n                                        <div class=\"progress-bar progress-bar-danger\" role=\"progressbar\" aria-valuenow=\"80\" aria-valuemin=\"0\" aria-valuemax=\"100\" style=\"width: 80%\">\n                                            <span class=\"sr-only\">80% Complete (danger)</span>\n                                        </div>\n                                    </div>\n                                </div>\n                            </a>\n                        </li>\n                        <li class=\"divider\"></li>\n                        <li>\n                            <a class=\"text-center\" href=\"#\">\n                                <strong>See All Tasks</strong>\n                                <i class=\"fa fa-angle-right\"></i>\n                            </a>\n                        </li>\n                    </ul>\n                    <!-- /.dropdown-tasks -->\n                </li>\n                <!-- /.dropdown -->\n                <li class=\"dropdown\">\n                    <a class=\"dropdown-toggle\" data-toggle=\"dropdown\" href=\"#\">\n                        <i class=\"fa fa-bell fa-fw\"></i> <i class=\"fa fa-caret-down\"></i>\n                    </a>\n                    <ul class=\"dropdown-menu dropdown-alerts\">\n                        <li>\n                            <a href=\"#\">\n                                <div>\n                                    <i class=\"fa fa-comment fa-fw\"></i> New Comment\n                                    <span class=\"pull-right text-muted small\">4 minutes ago</span>\n                                </div>\n                            </a>\n                        </li>\n                        <li class=\"divider\"></li>\n                        <li>\n                            <a href=\"#\">\n                                <div>\n                                    <i class=\"fa fa-twitter fa-fw\"></i> 3 New Followers\n                                    <span class=\"pull-right text-muted small\">12 minutes ago</span>\n                                </div>\n                            </a>\n                        </li>\n                        <li class=\"divider\"></li>\n                        <li>\n                            <a href=\"#\">\n                                <div>\n                                    <i class=\"fa fa-envelope fa-fw\"></i> Message Sent\n                                    <span class=\"pull-right text-muted small\">4 minutes ago</span>\n                                </div>\n                            </a>\n                        </li>\n                        <li class=\"divider\"></li>\n                        <li>\n                            <a href=\"#\">\n                                <div>\n                                    <i class=\"fa fa-tasks fa-fw\"></i> New Task\n                                    <span class=\"pull-right text-muted small\">4 minutes ago</span>\n                                </div>\n                            </a>\n                        </li>\n                        <li class=\"divider\"></li>\n                        <li>\n                            <a href=\"#\">\n                                <div>\n                                    <i class=\"fa fa-upload fa-fw\"></i> Server Rebooted\n                                    <span class=\"pull-right text-muted small\">4 minutes ago</span>\n                                </div>\n                            </a>\n                        </li>\n                        <li class=\"divider\"></li>\n                        <li>\n                            <a class=\"text-center\" href=\"#\">\n                                <strong>See All Alerts</strong>\n                                <i class=\"fa fa-angle-right\"></i>\n                            </a>\n                        </li>\n                    </ul>\n                    <!-- /.dropdown-alerts -->\n                </li>\n                <!-- /.dropdown -->\n                <li class=\"dropdown\">\n                    <a class=\"dropdown-toggle\" data-toggle=\"dropdown\" href=\"#\">\n                        <i class=\"fa fa-user fa-fw\"></i> <i class=\"fa fa-caret-down\"></i>\n                    </a>\n                    <ul class=\"dropdown-menu dropdown-user\">\n                        <li><a href=\"#\"><i class=\"fa fa-user fa-fw\"></i> User Profile</a>\n                        </li>\n                        <li><a href=\"#\"><i class=\"fa fa-gear fa-fw\"></i> Settings</a>\n                        </li>\n                        <li class=\"divider\"></li>\n                        <li><a href=\"login.html\"><i class=\"fa fa-sign-out fa-fw\"></i> Logout</a>\n                        </li>\n                    </ul>\n                    <!-- /.dropdown-user -->\n                </li>\n                <!-- /.dropdown -->\n            </ul>\n            <!-- /.navbar-top-links -->\n\n            <div class=\"navbar-default sidebar\" role=\"navigation\">\n                <div class=\"sidebar-nav navbar-collapse\">\n                    <ul class=\"nav\" id=\"side-menu\">\n                        <li class=\"sidebar-search\">\n                            <div class=\"input-group custom-search-form\">\n                                <input type=\"text\" class=\"form-control\" placeholder=\"Search...\">\n                                <span class=\"input-group-btn\">\n                                    <button class=\"btn btn-default\" type=\"button\">\n                                        <i class=\"fa fa-search\"></i>\n                                    </button>\n                                </span>\n                            </div>\n                            <!-- /input-group -->\n                        </li>\n                        <li>\n                            <a href=\"index.html\"><i class=\"fa fa-dashboard fa-fw\"></i> Dashboard</a>\n                        </li>\n                        <li>\n                            <a href=\"#\"><i class=\"fa fa-bar-chart-o fa-fw\"></i> Charts<span class=\"fa arrow\"></span></a>\n                            <ul class=\"nav nav-second-level\">\n                                <li>\n                                    <a href=\"flot.html\">Flot Charts</a>\n                                </li>\n                                <li>\n                                    <a href=\"morris.html\">Morris.js Charts</a>\n                                </li>\n                            </ul>\n                            <!-- /.nav-second-level -->\n                        </li>\n                        <li>\n                            <a href=\"tables.html\"><i class=\"fa fa-table fa-fw\"></i> Tables</a>\n                        </li>\n                        <li>\n                            <a href=\"forms.html\"><i class=\"fa fa-edit fa-fw\"></i> Forms</a>\n                        </li>\n                        <li>\n                            <a href=\"#\"><i class=\"fa fa-wrench fa-fw\"></i> UI Elements<span class=\"fa arrow\"></span></a>\n                            <ul class=\"nav nav-second-level\">\n                                <li>\n                                    <a href=\"panels-wells.html\">Panels and Wells</a>\n                                </li>\n                                <li>\n                                    <a href=\"buttons.html\">Buttons</a>\n                                </li>\n                                <li>\n                                    <a href=\"notifications.html\">Notifications</a>\n                                </li>\n                                <li>\n                                    <a href=\"typography.html\">Typography</a>\n                                </li>\n                                <li>\n                                    <a href=\"icons.html\"> Icons</a>\n                                </li>\n                                <li>\n                                    <a href=\"grid.html\">Grid</a>\n                                </li>\n                            </ul>\n                            <!-- /.nav-second-level -->\n                        </li>\n                        <li>\n                            <a href=\"#\"><i class=\"fa fa-sitemap fa-fw\"></i> Multi-Level Dropdown<span class=\"fa arrow\"></span></a>\n                            <ul class=\"nav nav-second-level\">\n                                <li>\n                                    <a href=\"#\">Second Level Item</a>\n                                </li>\n                                <li>\n                                    <a href=\"#\">Second Level Item</a>\n                                </li>\n                                <li>\n                                    <a href=\"#\">Third Level <span class=\"fa arrow\"></span></a>\n                                    <ul class=\"nav nav-third-level\">\n                                        <li>\n                                            <a href=\"#\">Third Level Item</a>\n                                        </li>\n                                        <li>\n                                            <a href=\"#\">Third Level Item</a>\n                                        </li>\n                                        <li>\n                                            <a href=\"#\">Third Level Item</a>\n                                        </li>\n                                        <li>\n                                            <a href=\"#\">Third Level Item</a>\n                                        </li>\n                                    </ul>\n                                    <!-- /.nav-third-level -->\n                                </li>\n                            </ul>\n                            <!-- /.nav-second-level -->\n                        </li>\n                        <li class=\"active\">\n                            <a href=\"#\"><i class=\"fa fa-files-o fa-fw\"></i> Sample Pages<span class=\"fa arrow\"></span></a>\n                            <ul class=\"nav nav-second-level\">\n                                <li>\n                                    <a class=\"active\" href=\"blank.html\">Blank Page</a>\n                                </li>\n                                <li>\n                                    <a href=\"login.html\">Login Page</a>\n                                </li>\n                            </ul>\n                            <!-- /.nav-second-level -->\n                        </li>\n                    </ul>\n                </div>\n                <!-- /.sidebar-collapse -->\n            </div>\n            <!-- /.navbar-static-side -->\n        </nav>\n\n        <!-- Page Content -->\n        <div id=\"page-wrapper\">\n            <div class=\"container-fluid\">\n                <div class=\"row\">\n                    <div class=\"col-lg-12\">\n                        <h1 class=\"page-header\">Blank</h1>\n                    </div>\n                    <!-- /.col-lg-12 -->\n                </div>\n                <!-- /.row -->\n            </div>\n            <!-- /.container-fluid -->\n        </div>\n        <!-- /#page-wrapper -->\n\n    </div>\n    <!-- /#wrapper -->\n\n    <!-- jQuery -->\n    <script src=\"../static/js/jquery-1.11.3.min.js\"></script>\n\n    <!-- Bootstrap Core JavaScript -->\n    <script src=\"../vendor/bootstrap/js/bootstrap.min.js\"></script>\n\n    <!-- Metis Menu Plugin JavaScript -->\n    <script src=\"../vendor/metisMenu/metisMenu.min.js\"></script>\n\n    <!-- Custom Theme JavaScript -->\n    <script src=\"../dist/js/sb-admin-2.js\"></script>\n\n</body>\n\n</html>\n"
  },
  {
    "path": "app_backend/pages/buttons.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n\n<head>\n\n    <meta charset=\"utf-8\">\n    <meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\">\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">\n    <meta name=\"description\" content=\"\">\n    <meta name=\"author\" content=\"\">\n\n    <title>SB Admin 2 - Bootstrap Admin Theme</title>\n\n    <!-- Bootstrap Core CSS -->\n    <link href=\"../vendor/bootstrap/css/bootstrap.min.css\" rel=\"stylesheet\">\n\n    <!-- MetisMenu CSS -->\n    <link href=\"../vendor/metisMenu/metisMenu.min.css\" rel=\"stylesheet\">\n\n    <!-- Social Buttons CSS -->\n    <link href=\"../vendor/bootstrap-social/bootstrap-social.css\" rel=\"stylesheet\">\n\n    <!-- Custom CSS -->\n    <link href=\"../dist/css/sb-admin-2.css\" rel=\"stylesheet\">\n\n    <!-- Custom Fonts -->\n    <link href=\"../vendor/font-awesome/css/font-awesome.min.css\" rel=\"stylesheet\" type=\"text/css\">\n\n    <!-- HTML5 Shim and Respond.js IE8 support of HTML5 elements and media queries -->\n    <!-- WARNING: Respond.js doesn't work if you view the page via file:// -->\n    <!--[if lt IE 9]>\n        <script src=\"https://oss.maxcdn.com/libs/html5shiv/3.7.0/html5shiv.js\"></script>\n        <script src=\"https://oss.maxcdn.com/libs/respond.js/1.4.2/respond.min.js\"></script>\n    <![endif]-->\n\n</head>\n\n<body>\n\n    <div id=\"wrapper\">\n\n        <!-- Navigation -->\n        <nav class=\"navbar navbar-default navbar-static-top\" role=\"navigation\" style=\"margin-bottom: 0\">\n            <div class=\"navbar-header\">\n                <button type=\"button\" class=\"navbar-toggle\" data-toggle=\"collapse\" data-target=\".navbar-collapse\">\n                    <span class=\"sr-only\">Toggle navigation</span>\n                    <span class=\"icon-bar\"></span>\n                    <span class=\"icon-bar\"></span>\n                    <span class=\"icon-bar\"></span>\n                </button>\n                <a class=\"navbar-brand\" href=\"index.html\">SB Admin v2.0</a>\n            </div>\n            <!-- /.navbar-header -->\n\n            <ul class=\"nav navbar-top-links navbar-right\">\n                <li class=\"dropdown\">\n                    <a class=\"dropdown-toggle\" data-toggle=\"dropdown\" href=\"#\">\n                        <i class=\"fa fa-envelope fa-fw\"></i> <i class=\"fa fa-caret-down\"></i>\n                    </a>\n                    <ul class=\"dropdown-menu dropdown-messages\">\n                        <li>\n                            <a href=\"#\">\n                                <div>\n                                    <strong>John Smith</strong>\n                                    <span class=\"pull-right text-muted\">\n                                        <em>Yesterday</em>\n                                    </span>\n                                </div>\n                                <div>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque eleifend...</div>\n                            </a>\n                        </li>\n                        <li class=\"divider\"></li>\n                        <li>\n                            <a href=\"#\">\n                                <div>\n                                    <strong>John Smith</strong>\n                                    <span class=\"pull-right text-muted\">\n                                        <em>Yesterday</em>\n                                    </span>\n                                </div>\n                                <div>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque eleifend...</div>\n                            </a>\n                        </li>\n                        <li class=\"divider\"></li>\n                        <li>\n                            <a href=\"#\">\n                                <div>\n                                    <strong>John Smith</strong>\n                                    <span class=\"pull-right text-muted\">\n                                        <em>Yesterday</em>\n                                    </span>\n                                </div>\n                                <div>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque eleifend...</div>\n                            </a>\n                        </li>\n                        <li class=\"divider\"></li>\n                        <li>\n                            <a class=\"text-center\" href=\"#\">\n                                <strong>Read All Messages</strong>\n                                <i class=\"fa fa-angle-right\"></i>\n                            </a>\n                        </li>\n                    </ul>\n                    <!-- /.dropdown-messages -->\n                </li>\n                <!-- /.dropdown -->\n                <li class=\"dropdown\">\n                    <a class=\"dropdown-toggle\" data-toggle=\"dropdown\" href=\"#\">\n                        <i class=\"fa fa-tasks fa-fw\"></i> <i class=\"fa fa-caret-down\"></i>\n                    </a>\n                    <ul class=\"dropdown-menu dropdown-tasks\">\n                        <li>\n                            <a href=\"#\">\n                                <div>\n                                    <p>\n                                        <strong>Task 1</strong>\n                                        <span class=\"pull-right text-muted\">40% Complete</span>\n                                    </p>\n                                    <div class=\"progress progress-striped active\">\n                                        <div class=\"progress-bar progress-bar-success\" role=\"progressbar\" aria-valuenow=\"40\" aria-valuemin=\"0\" aria-valuemax=\"100\" style=\"width: 40%\">\n                                            <span class=\"sr-only\">40% Complete (success)</span>\n                                        </div>\n                                    </div>\n                                </div>\n                            </a>\n                        </li>\n                        <li class=\"divider\"></li>\n                        <li>\n                            <a href=\"#\">\n                                <div>\n                                    <p>\n                                        <strong>Task 2</strong>\n                                        <span class=\"pull-right text-muted\">20% Complete</span>\n                                    </p>\n                                    <div class=\"progress progress-striped active\">\n                                        <div class=\"progress-bar progress-bar-info\" role=\"progressbar\" aria-valuenow=\"20\" aria-valuemin=\"0\" aria-valuemax=\"100\" style=\"width: 20%\">\n                                            <span class=\"sr-only\">20% Complete</span>\n                                        </div>\n                                    </div>\n                                </div>\n                            </a>\n                        </li>\n                        <li class=\"divider\"></li>\n                        <li>\n                            <a href=\"#\">\n                                <div>\n                                    <p>\n                                        <strong>Task 3</strong>\n                                        <span class=\"pull-right text-muted\">60% Complete</span>\n                                    </p>\n                                    <div class=\"progress progress-striped active\">\n                                        <div class=\"progress-bar progress-bar-warning\" role=\"progressbar\" aria-valuenow=\"60\" aria-valuemin=\"0\" aria-valuemax=\"100\" style=\"width: 60%\">\n                                            <span class=\"sr-only\">60% Complete (warning)</span>\n                                        </div>\n                                    </div>\n                                </div>\n                            </a>\n                        </li>\n                        <li class=\"divider\"></li>\n                        <li>\n                            <a href=\"#\">\n                                <div>\n                                    <p>\n                                        <strong>Task 4</strong>\n                                        <span class=\"pull-right text-muted\">80% Complete</span>\n                                    </p>\n                                    <div class=\"progress progress-striped active\">\n                                        <div class=\"progress-bar progress-bar-danger\" role=\"progressbar\" aria-valuenow=\"80\" aria-valuemin=\"0\" aria-valuemax=\"100\" style=\"width: 80%\">\n                                            <span class=\"sr-only\">80% Complete (danger)</span>\n                                        </div>\n                                    </div>\n                                </div>\n                            </a>\n                        </li>\n                        <li class=\"divider\"></li>\n                        <li>\n                            <a class=\"text-center\" href=\"#\">\n                                <strong>See All Tasks</strong>\n                                <i class=\"fa fa-angle-right\"></i>\n                            </a>\n                        </li>\n                    </ul>\n                    <!-- /.dropdown-tasks -->\n                </li>\n                <!-- /.dropdown -->\n                <li class=\"dropdown\">\n                    <a class=\"dropdown-toggle\" data-toggle=\"dropdown\" href=\"#\">\n                        <i class=\"fa fa-bell fa-fw\"></i> <i class=\"fa fa-caret-down\"></i>\n                    </a>\n                    <ul class=\"dropdown-menu dropdown-alerts\">\n                        <li>\n                            <a href=\"#\">\n                                <div>\n                                    <i class=\"fa fa-comment fa-fw\"></i> New Comment\n                                    <span class=\"pull-right text-muted small\">4 minutes ago</span>\n                                </div>\n                            </a>\n                        </li>\n                        <li class=\"divider\"></li>\n                        <li>\n                            <a href=\"#\">\n                                <div>\n                                    <i class=\"fa fa-twitter fa-fw\"></i> 3 New Followers\n                                    <span class=\"pull-right text-muted small\">12 minutes ago</span>\n                                </div>\n                            </a>\n                        </li>\n                        <li class=\"divider\"></li>\n                        <li>\n                            <a href=\"#\">\n                                <div>\n                                    <i class=\"fa fa-envelope fa-fw\"></i> Message Sent\n                                    <span class=\"pull-right text-muted small\">4 minutes ago</span>\n                                </div>\n                            </a>\n                        </li>\n                        <li class=\"divider\"></li>\n                        <li>\n                            <a href=\"#\">\n                                <div>\n                                    <i class=\"fa fa-tasks fa-fw\"></i> New Task\n                                    <span class=\"pull-right text-muted small\">4 minutes ago</span>\n                                </div>\n                            </a>\n                        </li>\n                        <li class=\"divider\"></li>\n                        <li>\n                            <a href=\"#\">\n                                <div>\n                                    <i class=\"fa fa-upload fa-fw\"></i> Server Rebooted\n                                    <span class=\"pull-right text-muted small\">4 minutes ago</span>\n                                </div>\n                            </a>\n                        </li>\n                        <li class=\"divider\"></li>\n                        <li>\n                            <a class=\"text-center\" href=\"#\">\n                                <strong>See All Alerts</strong>\n                                <i class=\"fa fa-angle-right\"></i>\n                            </a>\n                        </li>\n                    </ul>\n                    <!-- /.dropdown-alerts -->\n                </li>\n                <!-- /.dropdown -->\n                <li class=\"dropdown\">\n                    <a class=\"dropdown-toggle\" data-toggle=\"dropdown\" href=\"#\">\n                        <i class=\"fa fa-user fa-fw\"></i> <i class=\"fa fa-caret-down\"></i>\n                    </a>\n                    <ul class=\"dropdown-menu dropdown-user\">\n                        <li><a href=\"#\"><i class=\"fa fa-user fa-fw\"></i> User Profile</a>\n                        </li>\n                        <li><a href=\"#\"><i class=\"fa fa-gear fa-fw\"></i> Settings</a>\n                        </li>\n                        <li class=\"divider\"></li>\n                        <li><a href=\"login.html\"><i class=\"fa fa-sign-out fa-fw\"></i> Logout</a>\n                        </li>\n                    </ul>\n                    <!-- /.dropdown-user -->\n                </li>\n                <!-- /.dropdown -->\n            </ul>\n            <!-- /.navbar-top-links -->\n\n            <div class=\"navbar-default sidebar\" role=\"navigation\">\n                <div class=\"sidebar-nav navbar-collapse\">\n                    <ul class=\"nav\" id=\"side-menu\">\n                        <li class=\"sidebar-search\">\n                            <div class=\"input-group custom-search-form\">\n                                <input type=\"text\" class=\"form-control\" placeholder=\"Search...\">\n                                <span class=\"input-group-btn\">\n                                <button class=\"btn btn-default\" type=\"button\">\n                                    <i class=\"fa fa-search\"></i>\n                                </button>\n                            </span>\n                            </div>\n                            <!-- /input-group -->\n                        </li>\n                        <li>\n                            <a href=\"index.html\"><i class=\"fa fa-dashboard fa-fw\"></i> Dashboard</a>\n                        </li>\n                        <li>\n                            <a href=\"#\"><i class=\"fa fa-bar-chart-o fa-fw\"></i> Charts<span class=\"fa arrow\"></span></a>\n                            <ul class=\"nav nav-second-level\">\n                                <li>\n                                    <a href=\"flot.html\">Flot Charts</a>\n                                </li>\n                                <li>\n                                    <a href=\"morris.html\">Morris.js Charts</a>\n                                </li>\n                            </ul>\n                            <!-- /.nav-second-level -->\n                        </li>\n                        <li>\n                            <a href=\"tables.html\"><i class=\"fa fa-table fa-fw\"></i> Tables</a>\n                        </li>\n                        <li>\n                            <a href=\"forms.html\"><i class=\"fa fa-edit fa-fw\"></i> Forms</a>\n                        </li>\n                        <li>\n                            <a href=\"#\"><i class=\"fa fa-wrench fa-fw\"></i> UI Elements<span class=\"fa arrow\"></span></a>\n                            <ul class=\"nav nav-second-level\">\n                                <li>\n                                    <a href=\"panels-wells.html\">Panels and Wells</a>\n                                </li>\n                                <li>\n                                    <a href=\"buttons.html\">Buttons</a>\n                                </li>\n                                <li>\n                                    <a href=\"notifications.html\">Notifications</a>\n                                </li>\n                                <li>\n                                    <a href=\"typography.html\">Typography</a>\n                                </li>\n                                <li>\n                                    <a href=\"icons.html\"> Icons</a>\n                                </li>\n                                <li>\n                                    <a href=\"grid.html\">Grid</a>\n                                </li>\n                            </ul>\n                            <!-- /.nav-second-level -->\n                        </li>\n                        <li>\n                            <a href=\"#\"><i class=\"fa fa-sitemap fa-fw\"></i> Multi-Level Dropdown<span class=\"fa arrow\"></span></a>\n                            <ul class=\"nav nav-second-level\">\n                                <li>\n                                    <a href=\"#\">Second Level Item</a>\n                                </li>\n                                <li>\n                                    <a href=\"#\">Second Level Item</a>\n                                </li>\n                                <li>\n                                    <a href=\"#\">Third Level <span class=\"fa arrow\"></span></a>\n                                    <ul class=\"nav nav-third-level\">\n                                        <li>\n                                            <a href=\"#\">Third Level Item</a>\n                                        </li>\n                                        <li>\n                                            <a href=\"#\">Third Level Item</a>\n                                        </li>\n                                        <li>\n                                            <a href=\"#\">Third Level Item</a>\n                                        </li>\n                                        <li>\n                                            <a href=\"#\">Third Level Item</a>\n                                        </li>\n                                    </ul>\n                                    <!-- /.nav-third-level -->\n                                </li>\n                            </ul>\n                            <!-- /.nav-second-level -->\n                        </li>\n                        <li>\n                            <a href=\"#\"><i class=\"fa fa-files-o fa-fw\"></i> Sample Pages<span class=\"fa arrow\"></span></a>\n                            <ul class=\"nav nav-second-level\">\n                                <li>\n                                    <a href=\"blank.html\">Blank Page</a>\n                                </li>\n                                <li>\n                                    <a href=\"login.html\">Login Page</a>\n                                </li>\n                            </ul>\n                            <!-- /.nav-second-level -->\n                        </li>\n                    </ul>\n                </div>\n                <!-- /.sidebar-collapse -->\n            </div>\n            <!-- /.navbar-static-side -->\n        </nav>\n\n        <!-- Page Content -->\n        <div id=\"page-wrapper\">\n            <div class=\"row\">\n                <div class=\"col-lg-12\">\n                    <h1 class=\"page-header\">Buttons</h1>\n                </div>\n                <!-- /.col-lg-12 -->\n            </div>\n            <!-- /.row -->\n            <div class=\"row\">\n                <div class=\"col-lg-6\">\n                    <div class=\"panel panel-default\">\n                        <div class=\"panel-heading\">\n                            Default Buttons\n                        </div>\n                        <!-- /.panel-heading -->\n                        <div class=\"panel-body\">\n                            <h4>Normal Buttons</h4>\n                            <p>\n                                <button type=\"button\" class=\"btn btn-default\">Default</button>\n                                <button type=\"button\" class=\"btn btn-primary\">Primary</button>\n                                <button type=\"button\" class=\"btn btn-success\">Success</button>\n                                <button type=\"button\" class=\"btn btn-info\">Info</button>\n                                <button type=\"button\" class=\"btn btn-warning\">Warning</button>\n                                <button type=\"button\" class=\"btn btn-danger\">Danger</button>\n                                <button type=\"button\" class=\"btn btn-link\">Link</button>\n                            </p>\n                            <br>\n                            <h4>Disabled Buttons</h4>\n                            <p>\n                                <button type=\"button\" class=\"btn btn-default disabled\">Default</button>\n                                <button type=\"button\" class=\"btn btn-primary disabled\">Primary</button>\n                                <button type=\"button\" class=\"btn btn-success disabled\">Success</button>\n                                <button type=\"button\" class=\"btn btn-info disabled\">Info</button>\n                                <button type=\"button\" class=\"btn btn-warning disabled\">Warning</button>\n                                <button type=\"button\" class=\"btn btn-danger disabled\">Danger</button>\n                                <button type=\"button\" class=\"btn btn-link disabled\">Link</button>\n                            </p>\n                            <br>\n                            <h4>Button Sizes</h4>\n                            <p>\n                                <button type=\"button\" class=\"btn btn-primary btn-lg\">Large button</button>\n                                <button type=\"button\" class=\"btn btn-primary\">Default button</button>\n                                <button type=\"button\" class=\"btn btn-primary btn-sm\">Small button</button>\n                                <button type=\"button\" class=\"btn btn-primary btn-xs\">Mini button</button>\n                                <br>\n                                <br>\n                                <button type=\"button\" class=\"btn btn-primary btn-lg btn-block\">Block level button</button>\n                            </p>\n                        </div>\n                        <!-- /.panel-body -->\n                    </div>\n                    <!-- /.panel -->\n                    <div class=\"panel panel-default\">\n                        <div class=\"panel-heading\">\n                            Circle Icon Buttons with Font Awesome Icons\n                        </div>\n                        <!-- /.panel-heading -->\n                        <div class=\"panel-body\">\n                            <h4>Normal Circle Buttons</h4>\n                            <button type=\"button\" class=\"btn btn-default btn-circle\"><i class=\"fa fa-check\"></i>\n                            </button>\n                            <button type=\"button\" class=\"btn btn-primary btn-circle\"><i class=\"fa fa-list\"></i>\n                            </button>\n                            <button type=\"button\" class=\"btn btn-success btn-circle\"><i class=\"fa fa-link\"></i>\n                            </button>\n                            <button type=\"button\" class=\"btn btn-info btn-circle\"><i class=\"fa fa-check\"></i>\n                            </button>\n                            <button type=\"button\" class=\"btn btn-warning btn-circle\"><i class=\"fa fa-times\"></i>\n                            </button>\n                            <button type=\"button\" class=\"btn btn-danger btn-circle\"><i class=\"fa fa-heart\"></i>\n                            </button>\n                            <br>\n                            <br>\n                            <h4>Large Circle Buttons</h4>\n                            <button type=\"button\" class=\"btn btn-default btn-circle btn-lg\"><i class=\"fa fa-check\"></i>\n                            </button>\n                            <button type=\"button\" class=\"btn btn-primary btn-circle btn-lg\"><i class=\"fa fa-list\"></i>\n                            </button>\n                            <button type=\"button\" class=\"btn btn-success btn-circle btn-lg\"><i class=\"fa fa-link\"></i>\n                            </button>\n                            <button type=\"button\" class=\"btn btn-info btn-circle btn-lg\"><i class=\"fa fa-check\"></i>\n                            </button>\n                            <button type=\"button\" class=\"btn btn-warning btn-circle btn-lg\"><i class=\"fa fa-times\"></i>\n                            </button>\n                            <button type=\"button\" class=\"btn btn-danger btn-circle btn-lg\"><i class=\"fa fa-heart\"></i>\n                            </button>\n                            <br>\n                            <br>\n                            <h4>Extra Large Circle Buttons</h4>\n                            <button type=\"button\" class=\"btn btn-default btn-circle btn-xl\"><i class=\"fa fa-check\"></i>\n                            </button>\n                            <button type=\"button\" class=\"btn btn-primary btn-circle btn-xl\"><i class=\"fa fa-list\"></i>\n                            </button>\n                            <button type=\"button\" class=\"btn btn-success btn-circle btn-xl\"><i class=\"fa fa-link\"></i>\n                            </button>\n                            <button type=\"button\" class=\"btn btn-info btn-circle btn-xl\"><i class=\"fa fa-check\"></i>\n                            </button>\n                            <button type=\"button\" class=\"btn btn-warning btn-circle btn-xl\"><i class=\"fa fa-times\"></i>\n                            </button>\n                            <button type=\"button\" class=\"btn btn-danger btn-circle btn-xl\"><i class=\"fa fa-heart\"></i>\n                            </button>\n                        </div>\n                        <!-- /.panel-body -->\n                    </div>\n                    <!-- /.panel -->\n                </div>\n                <!-- /.col-lg-6 -->\n                <div class=\"col-lg-6\">\n                    <div class=\"panel panel-default\">\n                        <div class=\"panel-heading\">\n                            Outline Buttons with Smooth Transition\n                        </div>\n                        <!-- /.panel-heading -->\n                        <div class=\"panel-body\">\n                            <h4>Outline Buttons</h4>\n                            <p>\n                                <button type=\"button\" class=\"btn btn-outline btn-default\">Default</button>\n                                <button type=\"button\" class=\"btn btn-outline btn-primary\">Primary</button>\n                                <button type=\"button\" class=\"btn btn-outline btn-success\">Success</button>\n                                <button type=\"button\" class=\"btn btn-outline btn-info\">Info</button>\n                                <button type=\"button\" class=\"btn btn-outline btn-warning\">Warning</button>\n                                <button type=\"button\" class=\"btn btn-outline btn-danger\">Danger</button>\n                                <button type=\"button\" class=\"btn btn-outline btn-link\">Link</button>\n                            </p>\n                            <br>\n                            <h4>Outline Button Sizes</h4>\n                            <p>\n                                <button type=\"button\" class=\"btn btn-outline btn-primary btn-lg\">Large button</button>\n                                <button type=\"button\" class=\"btn btn-outline btn-primary\">Default button</button>\n                                <button type=\"button\" class=\"btn btn-outline btn-primary btn-sm\">Small button</button>\n                                <button type=\"button\" class=\"btn btn-outline btn-primary btn-xs\">Mini button</button>\n                                <br>\n                                <br>\n                                <button type=\"button\" class=\"btn btn-outline btn-primary btn-lg btn-block\">Block level button</button>\n                            </p>\n                        </div>\n                        <!-- /.panel-body -->\n                    </div>\n                    <!-- /.panel -->\n                    <div class=\"panel panel-default\">\n                        <div class=\"panel-heading\">\n                            Social Buttons with Font Awesome Icons\n                        </div>\n                        <!-- /.panel-heading -->\n                        <div class=\"panel-body\">\n                            <h4>Social Buttons</h4>\n                            <a class=\"btn btn-block btn-social btn-bitbucket\">\n                                <i class=\"fa fa-bitbucket\"></i> Sign in with Bitbucket\n                            </a>\n                            <a class=\"btn btn-block btn-social btn-dropbox\">\n                                <i class=\"fa fa-dropbox\"></i> Sign in with Dropbox\n                            </a>\n                            <a class=\"btn btn-block btn-social btn-facebook\">\n                                <i class=\"fa fa-facebook\"></i> Sign in with Facebook\n                            </a>\n                            <a class=\"btn btn-block btn-social btn-flickr\">\n                                <i class=\"fa fa-flickr\"></i> Sign in with Flickr\n                            </a>\n                            <a class=\"btn btn-block btn-social btn-github\">\n                                <i class=\"fa fa-github\"></i> Sign in with GitHub\n                            </a>\n                            <a class=\"btn btn-block btn-social btn-google-plus\">\n                                <i class=\"fa fa-google-plus\"></i> Sign in with Google\n                            </a>\n                            <a class=\"btn btn-block btn-social btn-instagram\">\n                                <i class=\"fa fa-instagram\"></i> Sign in with Instagram\n                            </a>\n                            <a class=\"btn btn-block btn-social btn-linkedin\">\n                                <i class=\"fa fa-linkedin\"></i> Sign in with LinkedIn\n                            </a>\n                            <a class=\"btn btn-block btn-social btn-pinterest\">\n                                <i class=\"fa fa-pinterest\"></i> Sign in with Pinterest\n                            </a>\n                            <a class=\"btn btn-block btn-social btn-tumblr\">\n                                <i class=\"fa fa-tumblr\"></i> Sign in with Tumblr\n                            </a>\n                            <a class=\"btn btn-block btn-social btn-twitter\">\n                                <i class=\"fa fa-twitter\"></i> Sign in with Twitter\n                            </a>\n                            <a class=\"btn btn-block btn-social btn-vk\">\n                                <i class=\"fa fa-vk\"></i> Sign in with VK\n                            </a>\n\n                            <hr>\n\n                            <div class=\"text-center\">\n                                <a class=\"btn btn-social-icon btn-bitbucket\"><i class=\"fa fa-bitbucket\"></i></a>\n                                <a class=\"btn btn-social-icon btn-dropbox\"><i class=\"fa fa-dropbox\"></i></a>\n                                <a class=\"btn btn-social-icon btn-facebook\"><i class=\"fa fa-facebook\"></i></a>\n                                <a class=\"btn btn-social-icon btn-flickr\"><i class=\"fa fa-flickr\"></i></a>\n                                <a class=\"btn btn-social-icon btn-github\"><i class=\"fa fa-github\"></i></a>\n                                <a class=\"btn btn-social-icon btn-google-plus\"><i class=\"fa fa-google-plus\"></i></a>\n                                <a class=\"btn btn-social-icon btn-instagram\"><i class=\"fa fa-instagram\"></i></a>\n                                <a class=\"btn btn-social-icon btn-linkedin\"><i class=\"fa fa-linkedin\"></i></a>\n                                <a class=\"btn btn-social-icon btn-pinterest\"><i class=\"fa fa-pinterest\"></i></a>\n                                <a class=\"btn btn-social-icon btn-tumblr\"><i class=\"fa fa-tumblr\"></i></a>\n                                <a class=\"btn btn-social-icon btn-twitter\"><i class=\"fa fa-twitter\"></i></a>\n                                <a class=\"btn btn-social-icon btn-vk\"><i class=\"fa fa-vk\"></i></a>\n                            </div>\n                        </div>\n                        <!-- /.panel-body -->\n                    </div>\n                    <!-- /.panel -->\n                </div>\n                <!-- /.col-lg-6 -->\n            </div>\n            <!-- /.row -->\n        </div>\n        <!-- /#page-wrapper -->\n\n    </div>\n    <!-- /#wrapper -->\n\n    <!-- jQuery -->\n    <script src=\"../vendor/jquery/jquery.min.js\"></script>\n\n    <!-- Bootstrap Core JavaScript -->\n    <script src=\"../vendor/bootstrap/js/bootstrap.min.js\"></script>\n\n    <!-- Metis Menu Plugin JavaScript -->\n    <script src=\"../vendor/metisMenu/metisMenu.min.js\"></script>\n\n    <!-- Custom Theme JavaScript -->\n    <script src=\"../dist/js/sb-admin-2.js\"></script>\n\n</body>\n\n</html>\n"
  },
  {
    "path": "app_backend/pages/flot.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n\n<head>\n\n    <meta charset=\"utf-8\">\n    <meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\">\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">\n    <meta name=\"description\" content=\"\">\n    <meta name=\"author\" content=\"\">\n\n    <title>SB Admin 2 - Bootstrap Admin Theme</title>\n\n    <!-- Bootstrap Core CSS -->\n    <link href=\"../vendor/bootstrap/css/bootstrap.min.css\" rel=\"stylesheet\">\n\n    <!-- MetisMenu CSS -->\n    <link href=\"../vendor/metisMenu/metisMenu.min.css\" rel=\"stylesheet\">\n\n    <!-- Custom CSS -->\n    <link href=\"../dist/css/sb-admin-2.css\" rel=\"stylesheet\">\n\n    <!-- Morris Charts CSS -->\n    <link href=\"../vendor/morrisjs/morris.css\" rel=\"stylesheet\">\n\n    <!-- Custom Fonts -->\n    <link href=\"../vendor/font-awesome/css/font-awesome.min.css\" rel=\"stylesheet\" type=\"text/css\">\n\n    <!-- HTML5 Shim and Respond.js IE8 support of HTML5 elements and media queries -->\n    <!-- WARNING: Respond.js doesn't work if you view the page via file:// -->\n    <!--[if lt IE 9]>\n        <script src=\"https://oss.maxcdn.com/libs/html5shiv/3.7.0/html5shiv.js\"></script>\n        <script src=\"https://oss.maxcdn.com/libs/respond.js/1.4.2/respond.min.js\"></script>\n    <![endif]-->\n\n</head>\n\n<body>\n\n    <div id=\"wrapper\">\n\n        <!-- Navigation -->\n        <nav class=\"navbar navbar-default navbar-static-top\" role=\"navigation\" style=\"margin-bottom: 0\">\n            <div class=\"navbar-header\">\n                <button type=\"button\" class=\"navbar-toggle\" data-toggle=\"collapse\" data-target=\".navbar-collapse\">\n                    <span class=\"sr-only\">Toggle navigation</span>\n                    <span class=\"icon-bar\"></span>\n                    <span class=\"icon-bar\"></span>\n                    <span class=\"icon-bar\"></span>\n                </button>\n                <a class=\"navbar-brand\" href=\"index.html\">SB Admin v2.0</a>\n            </div>\n            <!-- /.navbar-header -->\n\n            <ul class=\"nav navbar-top-links navbar-right\">\n                <li class=\"dropdown\">\n                    <a class=\"dropdown-toggle\" data-toggle=\"dropdown\" href=\"#\">\n                        <i class=\"fa fa-envelope fa-fw\"></i> <i class=\"fa fa-caret-down\"></i>\n                    </a>\n                    <ul class=\"dropdown-menu dropdown-messages\">\n                        <li>\n                            <a href=\"#\">\n                                <div>\n                                    <strong>John Smith</strong>\n                                    <span class=\"pull-right text-muted\">\n                                        <em>Yesterday</em>\n                                    </span>\n                                </div>\n                                <div>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque eleifend...</div>\n                            </a>\n                        </li>\n                        <li class=\"divider\"></li>\n                        <li>\n                            <a href=\"#\">\n                                <div>\n                                    <strong>John Smith</strong>\n                                    <span class=\"pull-right text-muted\">\n                                        <em>Yesterday</em>\n                                    </span>\n                                </div>\n                                <div>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque eleifend...</div>\n                            </a>\n                        </li>\n                        <li class=\"divider\"></li>\n                        <li>\n                            <a href=\"#\">\n                                <div>\n                                    <strong>John Smith</strong>\n                                    <span class=\"pull-right text-muted\">\n                                        <em>Yesterday</em>\n                                    </span>\n                                </div>\n                                <div>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque eleifend...</div>\n                            </a>\n                        </li>\n                        <li class=\"divider\"></li>\n                        <li>\n                            <a class=\"text-center\" href=\"#\">\n                                <strong>Read All Messages</strong>\n                                <i class=\"fa fa-angle-right\"></i>\n                            </a>\n                        </li>\n                    </ul>\n                    <!-- /.dropdown-messages -->\n                </li>\n                <!-- /.dropdown -->\n                <li class=\"dropdown\">\n                    <a class=\"dropdown-toggle\" data-toggle=\"dropdown\" href=\"#\">\n                        <i class=\"fa fa-tasks fa-fw\"></i> <i class=\"fa fa-caret-down\"></i>\n                    </a>\n                    <ul class=\"dropdown-menu dropdown-tasks\">\n                        <li>\n                            <a href=\"#\">\n                                <div>\n                                    <p>\n                                        <strong>Task 1</strong>\n                                        <span class=\"pull-right text-muted\">40% Complete</span>\n                                    </p>\n                                    <div class=\"progress progress-striped active\">\n                                        <div class=\"progress-bar progress-bar-success\" role=\"progressbar\" aria-valuenow=\"40\" aria-valuemin=\"0\" aria-valuemax=\"100\" style=\"width: 40%\">\n                                            <span class=\"sr-only\">40% Complete (success)</span>\n                                        </div>\n                                    </div>\n                                </div>\n                            </a>\n                        </li>\n                        <li class=\"divider\"></li>\n                        <li>\n                            <a href=\"#\">\n                                <div>\n                                    <p>\n                                        <strong>Task 2</strong>\n                                        <span class=\"pull-right text-muted\">20% Complete</span>\n                                    </p>\n                                    <div class=\"progress progress-striped active\">\n                                        <div class=\"progress-bar progress-bar-info\" role=\"progressbar\" aria-valuenow=\"20\" aria-valuemin=\"0\" aria-valuemax=\"100\" style=\"width: 20%\">\n                                            <span class=\"sr-only\">20% Complete</span>\n                                        </div>\n                                    </div>\n                                </div>\n                            </a>\n                        </li>\n                        <li class=\"divider\"></li>\n                        <li>\n                            <a href=\"#\">\n                                <div>\n                                    <p>\n                                        <strong>Task 3</strong>\n                                        <span class=\"pull-right text-muted\">60% Complete</span>\n                                    </p>\n                                    <div class=\"progress progress-striped active\">\n                                        <div class=\"progress-bar progress-bar-warning\" role=\"progressbar\" aria-valuenow=\"60\" aria-valuemin=\"0\" aria-valuemax=\"100\" style=\"width: 60%\">\n                                            <span class=\"sr-only\">60% Complete (warning)</span>\n                                        </div>\n                                    </div>\n                                </div>\n                            </a>\n                        </li>\n                        <li class=\"divider\"></li>\n                        <li>\n                            <a href=\"#\">\n                                <div>\n                                    <p>\n                                        <strong>Task 4</strong>\n                                        <span class=\"pull-right text-muted\">80% Complete</span>\n                                    </p>\n                                    <div class=\"progress progress-striped active\">\n                                        <div class=\"progress-bar progress-bar-danger\" role=\"progressbar\" aria-valuenow=\"80\" aria-valuemin=\"0\" aria-valuemax=\"100\" style=\"width: 80%\">\n                                            <span class=\"sr-only\">80% Complete (danger)</span>\n                                        </div>\n                                    </div>\n                                </div>\n                            </a>\n                        </li>\n                        <li class=\"divider\"></li>\n                        <li>\n                            <a class=\"text-center\" href=\"#\">\n                                <strong>See All Tasks</strong>\n                                <i class=\"fa fa-angle-right\"></i>\n                            </a>\n                        </li>\n                    </ul>\n                    <!-- /.dropdown-tasks -->\n                </li>\n                <!-- /.dropdown -->\n                <li class=\"dropdown\">\n                    <a class=\"dropdown-toggle\" data-toggle=\"dropdown\" href=\"#\">\n                        <i class=\"fa fa-bell fa-fw\"></i> <i class=\"fa fa-caret-down\"></i>\n                    </a>\n                    <ul class=\"dropdown-menu dropdown-alerts\">\n                        <li>\n                            <a href=\"#\">\n                                <div>\n                                    <i class=\"fa fa-comment fa-fw\"></i> New Comment\n                                    <span class=\"pull-right text-muted small\">4 minutes ago</span>\n                                </div>\n                            </a>\n                        </li>\n                        <li class=\"divider\"></li>\n                        <li>\n                            <a href=\"#\">\n                                <div>\n                                    <i class=\"fa fa-twitter fa-fw\"></i> 3 New Followers\n                                    <span class=\"pull-right text-muted small\">12 minutes ago</span>\n                                </div>\n                            </a>\n                        </li>\n                        <li class=\"divider\"></li>\n                        <li>\n                            <a href=\"#\">\n                                <div>\n                                    <i class=\"fa fa-envelope fa-fw\"></i> Message Sent\n                                    <span class=\"pull-right text-muted small\">4 minutes ago</span>\n                                </div>\n                            </a>\n                        </li>\n                        <li class=\"divider\"></li>\n                        <li>\n                            <a href=\"#\">\n                                <div>\n                                    <i class=\"fa fa-tasks fa-fw\"></i> New Task\n                                    <span class=\"pull-right text-muted small\">4 minutes ago</span>\n                                </div>\n                            </a>\n                        </li>\n                        <li class=\"divider\"></li>\n                        <li>\n                            <a href=\"#\">\n                                <div>\n                                    <i class=\"fa fa-upload fa-fw\"></i> Server Rebooted\n                                    <span class=\"pull-right text-muted small\">4 minutes ago</span>\n                                </div>\n                            </a>\n                        </li>\n                        <li class=\"divider\"></li>\n                        <li>\n                            <a class=\"text-center\" href=\"#\">\n                                <strong>See All Alerts</strong>\n                                <i class=\"fa fa-angle-right\"></i>\n                            </a>\n                        </li>\n                    </ul>\n                    <!-- /.dropdown-alerts -->\n                </li>\n                <!-- /.dropdown -->\n                <li class=\"dropdown\">\n                    <a class=\"dropdown-toggle\" data-toggle=\"dropdown\" href=\"#\">\n                        <i class=\"fa fa-user fa-fw\"></i> <i class=\"fa fa-caret-down\"></i>\n                    </a>\n                    <ul class=\"dropdown-menu dropdown-user\">\n                        <li><a href=\"#\"><i class=\"fa fa-user fa-fw\"></i> User Profile</a>\n                        </li>\n                        <li><a href=\"#\"><i class=\"fa fa-gear fa-fw\"></i> Settings</a>\n                        </li>\n                        <li class=\"divider\"></li>\n                        <li><a href=\"login.html\"><i class=\"fa fa-sign-out fa-fw\"></i> Logout</a>\n                        </li>\n                    </ul>\n                    <!-- /.dropdown-user -->\n                </li>\n                <!-- /.dropdown -->\n            </ul>\n            <!-- /.navbar-top-links -->\n\n            <div class=\"navbar-default sidebar\" role=\"navigation\">\n                <div class=\"sidebar-nav navbar-collapse\">\n                    <ul class=\"nav\" id=\"side-menu\">\n                        <li class=\"sidebar-search\">\n                            <div class=\"input-group custom-search-form\">\n                                <input type=\"text\" class=\"form-control\" placeholder=\"Search...\">\n                                <span class=\"input-group-btn\">\n                                <button class=\"btn btn-default\" type=\"button\">\n                                    <i class=\"fa fa-search\"></i>\n                                </button>\n                            </span>\n                            </div>\n                            <!-- /input-group -->\n                        </li>\n                        <li>\n                            <a href=\"index.html\"><i class=\"fa fa-dashboard fa-fw\"></i> Dashboard</a>\n                        </li>\n                        <li>\n                            <a href=\"#\"><i class=\"fa fa-bar-chart-o fa-fw\"></i> Charts<span class=\"fa arrow\"></span></a>\n                            <ul class=\"nav nav-second-level\">\n                                <li>\n                                    <a href=\"flot.html\">Flot Charts</a>\n                                </li>\n                                <li>\n                                    <a href=\"morris.html\">Morris.js Charts</a>\n                                </li>\n                            </ul>\n                            <!-- /.nav-second-level -->\n                        </li>\n                        <li>\n                            <a href=\"tables.html\"><i class=\"fa fa-table fa-fw\"></i> Tables</a>\n                        </li>\n                        <li>\n                            <a href=\"forms.html\"><i class=\"fa fa-edit fa-fw\"></i> Forms</a>\n                        </li>\n                        <li>\n                            <a href=\"#\"><i class=\"fa fa-wrench fa-fw\"></i> UI Elements<span class=\"fa arrow\"></span></a>\n                            <ul class=\"nav nav-second-level\">\n                                <li>\n                                    <a href=\"panels-wells.html\">Panels and Wells</a>\n                                </li>\n                                <li>\n                                    <a href=\"buttons.html\">Buttons</a>\n                                </li>\n                                <li>\n                                    <a href=\"notifications.html\">Notifications</a>\n                                </li>\n                                <li>\n                                    <a href=\"typography.html\">Typography</a>\n                                </li>\n                                <li>\n                                    <a href=\"icons.html\"> Icons</a>\n                                </li>\n                                <li>\n                                    <a href=\"grid.html\">Grid</a>\n                                </li>\n                            </ul>\n                            <!-- /.nav-second-level -->\n                        </li>\n                        <li>\n                            <a href=\"#\"><i class=\"fa fa-sitemap fa-fw\"></i> Multi-Level Dropdown<span class=\"fa arrow\"></span></a>\n                            <ul class=\"nav nav-second-level\">\n                                <li>\n                                    <a href=\"#\">Second Level Item</a>\n                                </li>\n                                <li>\n                                    <a href=\"#\">Second Level Item</a>\n                                </li>\n                                <li>\n                                    <a href=\"#\">Third Level <span class=\"fa arrow\"></span></a>\n                                    <ul class=\"nav nav-third-level\">\n                                        <li>\n                                            <a href=\"#\">Third Level Item</a>\n                                        </li>\n                                        <li>\n                                            <a href=\"#\">Third Level Item</a>\n                                        </li>\n                                        <li>\n                                            <a href=\"#\">Third Level Item</a>\n                                        </li>\n                                        <li>\n                                            <a href=\"#\">Third Level Item</a>\n                                        </li>\n                                    </ul>\n                                    <!-- /.nav-third-level -->\n                                </li>\n                            </ul>\n                            <!-- /.nav-second-level -->\n                        </li>\n                        <li>\n                            <a href=\"#\"><i class=\"fa fa-files-o fa-fw\"></i> Sample Pages<span class=\"fa arrow\"></span></a>\n                            <ul class=\"nav nav-second-level\">\n                                <li>\n                                    <a href=\"blank.html\">Blank Page</a>\n                                </li>\n                                <li>\n                                    <a href=\"login.html\">Login Page</a>\n                                </li>\n                            </ul>\n                            <!-- /.nav-second-level -->\n                        </li>\n                    </ul>\n                </div>\n                <!-- /.sidebar-collapse -->\n            </div>\n            <!-- /.navbar-static-side -->\n        </nav>\n\n        <div id=\"page-wrapper\">\n            <div class=\"row\">\n                <div class=\"col-lg-12\">\n                    <h1 class=\"page-header\">Flot</h1>\n                </div>\n                <!-- /.col-lg-12 -->\n            </div>\n            <!-- /.row -->\n            <div class=\"row\">\n                <div class=\"col-lg-12\">\n                    <div class=\"panel panel-default\">\n                        <div class=\"panel-heading\">\n                            Line Chart Example\n                        </div>\n                        <!-- /.panel-heading -->\n                        <div class=\"panel-body\">\n                            <div class=\"flot-chart\">\n                                <div class=\"flot-chart-content\" id=\"flot-line-chart\"></div>\n                            </div>\n                        </div>\n                        <!-- /.panel-body -->\n                    </div>\n                    <!-- /.panel -->\n                </div>\n                <!-- /.col-lg-12 -->\n                <div class=\"col-lg-6\">\n                    <div class=\"panel panel-default\">\n                        <div class=\"panel-heading\">\n                            Pie Chart Example\n                        </div>\n                        <!-- /.panel-heading -->\n                        <div class=\"panel-body\">\n                            <div class=\"flot-chart\">\n                                <div class=\"flot-chart-content\" id=\"flot-pie-chart\"></div>\n                            </div>\n                        </div>\n                        <!-- /.panel-body -->\n                    </div>\n                    <!-- /.panel -->\n                </div>\n                <!-- /.col-lg-6 -->\n                <div class=\"col-lg-6\">\n                    <div class=\"panel panel-default\">\n                        <div class=\"panel-heading\">\n                            Multiple Axes Line Chart Example\n                        </div>\n                        <!-- /.panel-heading -->\n                        <div class=\"panel-body\">\n                            <div class=\"flot-chart\">\n                                <div class=\"flot-chart-content\" id=\"flot-line-chart-multi\"></div>\n                            </div>\n                        </div>\n                        <!-- /.panel-body -->\n                    </div>\n                    <!-- /.panel -->\n                </div>\n                <!-- /.col-lg-6 -->\n                <div class=\"col-lg-6\">\n                    <div class=\"panel panel-default\">\n                        <div class=\"panel-heading\">\n                            Moving Line Chart Example\n                        </div>\n                        <!-- /.panel-heading -->\n                        <div class=\"panel-body\">\n                            <div class=\"flot-chart\">\n                                <div class=\"flot-chart-content\" id=\"flot-line-chart-moving\"></div>\n                            </div>\n                        </div>\n                        <!-- /.panel-body -->\n                    </div>\n                    <!-- /.panel -->\n                </div>\n                <!-- /.col-lg-6 -->\n                <div class=\"col-lg-6\">\n                    <div class=\"panel panel-default\">\n                        <div class=\"panel-heading\">\n                            Bar Chart Example\n                        </div>\n                        <!-- /.panel-heading -->\n                        <div class=\"panel-body\">\n                            <div class=\"flot-chart\">\n                                <div class=\"flot-chart-content\" id=\"flot-bar-chart\"></div>\n                            </div>\n                        </div>\n                        <!-- /.panel-body -->\n                    </div>\n                    <!-- /.panel -->\n                </div>\n                <!-- /.col-lg-6 -->\n                <div class=\"col-lg-12\">\n                    <div class=\"panel panel-default\">\n                        <div class=\"panel-heading\">\n                            Flot Charts Usage\n                        </div>\n                        <!-- /.panel-heading -->\n                        <div class=\"panel-body\">\n                            <p>Flot is a pure JavaScript plotting library for jQuery, with a focus on simple usage, attractive looks, and interactive features. In SB Admin, we are using the most recent version of Flot along with a few plugins to enhance the user experience. The Flot plugins being used are the tooltip plugin for hoverable tooltips, and the resize plugin for fully responsive charts. The documentation for Flot Charts is available on their website, <a target=\"_blank\" href=\"http://www.flotcharts.org/\">http://www.flotcharts.org/</a>.</p>\n                            <a target=\"_blank\" class=\"btn btn-default btn-lg btn-block\" href=\"http://www.flotcharts.org/\">View Flot Charts Documentation</a>\n                        </div>\n                        <!-- /.panel-body -->\n                    </div>\n                    <!-- /.panel -->\n                </div>\n                <!-- /.col-lg-6 -->\n            </div>\n            <!-- /.row -->\n        </div>\n        <!-- /#page-wrapper -->\n\n    </div>\n    <!-- /#wrapper -->\n\n    <!-- jQuery -->\n    <script src=\"../vendor/jquery/jquery.min.js\"></script>\n\n    <!-- Bootstrap Core JavaScript -->\n    <script src=\"../vendor/bootstrap/js/bootstrap.min.js\"></script>\n\n    <!-- Metis Menu Plugin JavaScript -->\n    <script src=\"../vendor/metisMenu/metisMenu.min.js\"></script>\n\n    <!-- Flot Charts JavaScript -->\n    <script src=\"../vendor/flot/excanvas.min.js\"></script>\n    <script src=\"../vendor/flot/jquery.flot.js\"></script>\n    <script src=\"../vendor/flot/jquery.flot.pie.js\"></script>\n    <script src=\"../vendor/flot/jquery.flot.resize.js\"></script>\n    <script src=\"../vendor/flot/jquery.flot.time.js\"></script>\n    <script src=\"../vendor/flot-tooltip/jquery.flot.tooltip.min.js\"></script>\n    <script src=\"../data/flot-data.js\"></script>\n\n    <!-- Custom Theme JavaScript -->\n    <script src=\"../dist/js/sb-admin-2.js\"></script>\n\n</body>\n\n</html>\n"
  },
  {
    "path": "app_backend/pages/forms.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n\n<head>\n\n    <meta charset=\"utf-8\">\n    <meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\">\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">\n    <meta name=\"description\" content=\"\">\n    <meta name=\"author\" content=\"\">\n\n    <title>SB Admin 2 - Bootstrap Admin Theme</title>\n\n    <!-- Bootstrap Core CSS -->\n    <link href=\"../vendor/bootstrap/css/bootstrap.min.css\" rel=\"stylesheet\">\n\n    <!-- MetisMenu CSS -->\n    <link href=\"../vendor/metisMenu/metisMenu.min.css\" rel=\"stylesheet\">\n\n    <!-- Custom CSS -->\n    <link href=\"../dist/css/sb-admin-2.css\" rel=\"stylesheet\">\n\n    <!-- Custom Fonts -->\n    <link href=\"../vendor/font-awesome/css/font-awesome.min.css\" rel=\"stylesheet\" type=\"text/css\">\n\n    <!-- HTML5 Shim and Respond.js IE8 support of HTML5 elements and media queries -->\n    <!-- WARNING: Respond.js doesn't work if you view the page via file:// -->\n    <!--[if lt IE 9]>\n        <script src=\"https://oss.maxcdn.com/libs/html5shiv/3.7.0/html5shiv.js\"></script>\n        <script src=\"https://oss.maxcdn.com/libs/respond.js/1.4.2/respond.min.js\"></script>\n    <![endif]-->\n\n</head>\n\n<body>\n\n    <div id=\"wrapper\">\n\n        <!-- Navigation -->\n        <nav class=\"navbar navbar-default navbar-static-top\" role=\"navigation\" style=\"margin-bottom: 0\">\n            <div class=\"navbar-header\">\n                <button type=\"button\" class=\"navbar-toggle\" data-toggle=\"collapse\" data-target=\".navbar-collapse\">\n                    <span class=\"sr-only\">Toggle navigation</span>\n                    <span class=\"icon-bar\"></span>\n                    <span class=\"icon-bar\"></span>\n                    <span class=\"icon-bar\"></span>\n                </button>\n                <a class=\"navbar-brand\" href=\"index.html\">SB Admin v2.0</a>\n            </div>\n            <!-- /.navbar-header -->\n\n            <ul class=\"nav navbar-top-links navbar-right\">\n                <li class=\"dropdown\">\n                    <a class=\"dropdown-toggle\" data-toggle=\"dropdown\" href=\"#\">\n                        <i class=\"fa fa-envelope fa-fw\"></i> <i class=\"fa fa-caret-down\"></i>\n                    </a>\n                    <ul class=\"dropdown-menu dropdown-messages\">\n                        <li>\n                            <a href=\"#\">\n                                <div>\n                                    <strong>John Smith</strong>\n                                    <span class=\"pull-right text-muted\">\n                                        <em>Yesterday</em>\n                                    </span>\n                                </div>\n                                <div>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque eleifend...</div>\n                            </a>\n                        </li>\n                        <li class=\"divider\"></li>\n                        <li>\n                            <a href=\"#\">\n                                <div>\n                                    <strong>John Smith</strong>\n                                    <span class=\"pull-right text-muted\">\n                                        <em>Yesterday</em>\n                                    </span>\n                                </div>\n                                <div>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque eleifend...</div>\n                            </a>\n                        </li>\n                        <li class=\"divider\"></li>\n                        <li>\n                            <a href=\"#\">\n                                <div>\n                                    <strong>John Smith</strong>\n                                    <span class=\"pull-right text-muted\">\n                                        <em>Yesterday</em>\n                                    </span>\n                                </div>\n                                <div>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque eleifend...</div>\n                            </a>\n                        </li>\n                        <li class=\"divider\"></li>\n                        <li>\n                            <a class=\"text-center\" href=\"#\">\n                                <strong>Read All Messages</strong>\n                                <i class=\"fa fa-angle-right\"></i>\n                            </a>\n                        </li>\n                    </ul>\n                    <!-- /.dropdown-messages -->\n                </li>\n                <!-- /.dropdown -->\n                <li class=\"dropdown\">\n                    <a class=\"dropdown-toggle\" data-toggle=\"dropdown\" href=\"#\">\n                        <i class=\"fa fa-tasks fa-fw\"></i> <i class=\"fa fa-caret-down\"></i>\n                    </a>\n                    <ul class=\"dropdown-menu dropdown-tasks\">\n                        <li>\n                            <a href=\"#\">\n                                <div>\n                                    <p>\n                                        <strong>Task 1</strong>\n                                        <span class=\"pull-right text-muted\">40% Complete</span>\n                                    </p>\n                                    <div class=\"progress progress-striped active\">\n                                        <div class=\"progress-bar progress-bar-success\" role=\"progressbar\" aria-valuenow=\"40\" aria-valuemin=\"0\" aria-valuemax=\"100\" style=\"width: 40%\">\n                                            <span class=\"sr-only\">40% Complete (success)</span>\n                                        </div>\n                                    </div>\n                                </div>\n                            </a>\n                        </li>\n                        <li class=\"divider\"></li>\n                        <li>\n                            <a href=\"#\">\n                                <div>\n                                    <p>\n                                        <strong>Task 2</strong>\n                                        <span class=\"pull-right text-muted\">20% Complete</span>\n                                    </p>\n                                    <div class=\"progress progress-striped active\">\n                                        <div class=\"progress-bar progress-bar-info\" role=\"progressbar\" aria-valuenow=\"20\" aria-valuemin=\"0\" aria-valuemax=\"100\" style=\"width: 20%\">\n                                            <span class=\"sr-only\">20% Complete</span>\n                                        </div>\n                                    </div>\n                                </div>\n                            </a>\n                        </li>\n                        <li class=\"divider\"></li>\n                        <li>\n                            <a href=\"#\">\n                                <div>\n                                    <p>\n                                        <strong>Task 3</strong>\n                                        <span class=\"pull-right text-muted\">60% Complete</span>\n                                    </p>\n                                    <div class=\"progress progress-striped active\">\n                                        <div class=\"progress-bar progress-bar-warning\" role=\"progressbar\" aria-valuenow=\"60\" aria-valuemin=\"0\" aria-valuemax=\"100\" style=\"width: 60%\">\n                                            <span class=\"sr-only\">60% Complete (warning)</span>\n                                        </div>\n                                    </div>\n                                </div>\n                            </a>\n                        </li>\n                        <li class=\"divider\"></li>\n                        <li>\n                            <a href=\"#\">\n                                <div>\n                                    <p>\n                                        <strong>Task 4</strong>\n                                        <span class=\"pull-right text-muted\">80% Complete</span>\n                                    </p>\n                                    <div class=\"progress progress-striped active\">\n                                        <div class=\"progress-bar progress-bar-danger\" role=\"progressbar\" aria-valuenow=\"80\" aria-valuemin=\"0\" aria-valuemax=\"100\" style=\"width: 80%\">\n                                            <span class=\"sr-only\">80% Complete (danger)</span>\n                                        </div>\n                                    </div>\n                                </div>\n                            </a>\n                        </li>\n                        <li class=\"divider\"></li>\n                        <li>\n                            <a class=\"text-center\" href=\"#\">\n                                <strong>See All Tasks</strong>\n                                <i class=\"fa fa-angle-right\"></i>\n                            </a>\n                        </li>\n                    </ul>\n                    <!-- /.dropdown-tasks -->\n                </li>\n                <!-- /.dropdown -->\n                <li class=\"dropdown\">\n                    <a class=\"dropdown-toggle\" data-toggle=\"dropdown\" href=\"#\">\n                        <i class=\"fa fa-bell fa-fw\"></i> <i class=\"fa fa-caret-down\"></i>\n                    </a>\n                    <ul class=\"dropdown-menu dropdown-alerts\">\n                        <li>\n                            <a href=\"#\">\n                                <div>\n                                    <i class=\"fa fa-comment fa-fw\"></i> New Comment\n                                    <span class=\"pull-right text-muted small\">4 minutes ago</span>\n                                </div>\n                            </a>\n                        </li>\n                        <li class=\"divider\"></li>\n                        <li>\n                            <a href=\"#\">\n                                <div>\n                                    <i class=\"fa fa-twitter fa-fw\"></i> 3 New Followers\n                                    <span class=\"pull-right text-muted small\">12 minutes ago</span>\n                                </div>\n                            </a>\n                        </li>\n                        <li class=\"divider\"></li>\n                        <li>\n                            <a href=\"#\">\n                                <div>\n                                    <i class=\"fa fa-envelope fa-fw\"></i> Message Sent\n                                    <span class=\"pull-right text-muted small\">4 minutes ago</span>\n                                </div>\n                            </a>\n                        </li>\n                        <li class=\"divider\"></li>\n                        <li>\n                            <a href=\"#\">\n                                <div>\n                                    <i class=\"fa fa-tasks fa-fw\"></i> New Task\n                                    <span class=\"pull-right text-muted small\">4 minutes ago</span>\n                                </div>\n                            </a>\n                        </li>\n                        <li class=\"divider\"></li>\n                        <li>\n                            <a href=\"#\">\n                                <div>\n                                    <i class=\"fa fa-upload fa-fw\"></i> Server Rebooted\n                                    <span class=\"pull-right text-muted small\">4 minutes ago</span>\n                                </div>\n                            </a>\n                        </li>\n                        <li class=\"divider\"></li>\n                        <li>\n                            <a class=\"text-center\" href=\"#\">\n                                <strong>See All Alerts</strong>\n                                <i class=\"fa fa-angle-right\"></i>\n                            </a>\n                        </li>\n                    </ul>\n                    <!-- /.dropdown-alerts -->\n                </li>\n                <!-- /.dropdown -->\n                <li class=\"dropdown\">\n                    <a class=\"dropdown-toggle\" data-toggle=\"dropdown\" href=\"#\">\n                        <i class=\"fa fa-user fa-fw\"></i> <i class=\"fa fa-caret-down\"></i>\n                    </a>\n                    <ul class=\"dropdown-menu dropdown-user\">\n                        <li><a href=\"#\"><i class=\"fa fa-user fa-fw\"></i> User Profile</a>\n                        </li>\n                        <li><a href=\"#\"><i class=\"fa fa-gear fa-fw\"></i> Settings</a>\n                        </li>\n                        <li class=\"divider\"></li>\n                        <li><a href=\"login.html\"><i class=\"fa fa-sign-out fa-fw\"></i> Logout</a>\n                        </li>\n                    </ul>\n                    <!-- /.dropdown-user -->\n                </li>\n                <!-- /.dropdown -->\n            </ul>\n            <!-- /.navbar-top-links -->\n\n            <div class=\"navbar-default sidebar\" role=\"navigation\">\n                <div class=\"sidebar-nav navbar-collapse\">\n                    <ul class=\"nav\" id=\"side-menu\">\n                        <li class=\"sidebar-search\">\n                            <div class=\"input-group custom-search-form\">\n                                <input type=\"text\" class=\"form-control\" placeholder=\"Search...\">\n                                <span class=\"input-group-btn\">\n                                <button class=\"btn btn-default\" type=\"button\">\n                                    <i class=\"fa fa-search\"></i>\n                                </button>\n                            </span>\n                            </div>\n                            <!-- /input-group -->\n                        </li>\n                        <li>\n                            <a href=\"index.html\"><i class=\"fa fa-dashboard fa-fw\"></i> Dashboard</a>\n                        </li>\n                        <li>\n                            <a href=\"#\"><i class=\"fa fa-bar-chart-o fa-fw\"></i> Charts<span class=\"fa arrow\"></span></a>\n                            <ul class=\"nav nav-second-level\">\n                                <li>\n                                    <a href=\"flot.html\">Flot Charts</a>\n                                </li>\n                                <li>\n                                    <a href=\"morris.html\">Morris.js Charts</a>\n                                </li>\n                            </ul>\n                            <!-- /.nav-second-level -->\n                        </li>\n                        <li>\n                            <a href=\"tables.html\"><i class=\"fa fa-table fa-fw\"></i> Tables</a>\n                        </li>\n                        <li>\n                            <a href=\"forms.html\"><i class=\"fa fa-edit fa-fw\"></i> Forms</a>\n                        </li>\n                        <li>\n                            <a href=\"#\"><i class=\"fa fa-wrench fa-fw\"></i> UI Elements<span class=\"fa arrow\"></span></a>\n                            <ul class=\"nav nav-second-level\">\n                                <li>\n                                    <a href=\"panels-wells.html\">Panels and Wells</a>\n                                </li>\n                                <li>\n                                    <a href=\"buttons.html\">Buttons</a>\n                                </li>\n                                <li>\n                                    <a href=\"notifications.html\">Notifications</a>\n                                </li>\n                                <li>\n                                    <a href=\"typography.html\">Typography</a>\n                                </li>\n                                <li>\n                                    <a href=\"icons.html\"> Icons</a>\n                                </li>\n                                <li>\n                                    <a href=\"grid.html\">Grid</a>\n                                </li>\n                            </ul>\n                            <!-- /.nav-second-level -->\n                        </li>\n                        <li>\n                            <a href=\"#\"><i class=\"fa fa-sitemap fa-fw\"></i> Multi-Level Dropdown<span class=\"fa arrow\"></span></a>\n                            <ul class=\"nav nav-second-level\">\n                                <li>\n                                    <a href=\"#\">Second Level Item</a>\n                                </li>\n                                <li>\n                                    <a href=\"#\">Second Level Item</a>\n                                </li>\n                                <li>\n                                    <a href=\"#\">Third Level <span class=\"fa arrow\"></span></a>\n                                    <ul class=\"nav nav-third-level\">\n                                        <li>\n                                            <a href=\"#\">Third Level Item</a>\n                                        </li>\n                                        <li>\n                                            <a href=\"#\">Third Level Item</a>\n                                        </li>\n                                        <li>\n                                            <a href=\"#\">Third Level Item</a>\n                                        </li>\n                                        <li>\n                                            <a href=\"#\">Third Level Item</a>\n                                        </li>\n                                    </ul>\n                                    <!-- /.nav-third-level -->\n                                </li>\n                            </ul>\n                            <!-- /.nav-second-level -->\n                        </li>\n                        <li>\n                            <a href=\"#\"><i class=\"fa fa-files-o fa-fw\"></i> Sample Pages<span class=\"fa arrow\"></span></a>\n                            <ul class=\"nav nav-second-level\">\n                                <li>\n                                    <a href=\"blank.html\">Blank Page</a>\n                                </li>\n                                <li>\n                                    <a href=\"login.html\">Login Page</a>\n                                </li>\n                            </ul>\n                            <!-- /.nav-second-level -->\n                        </li>\n                    </ul>\n                </div>\n                <!-- /.sidebar-collapse -->\n            </div>\n            <!-- /.navbar-static-side -->\n        </nav>\n\n        <div id=\"page-wrapper\">\n            <div class=\"row\">\n                <div class=\"col-lg-12\">\n                    <h1 class=\"page-header\">Forms</h1>\n                </div>\n                <!-- /.col-lg-12 -->\n            </div>\n            <!-- /.row -->\n            <div class=\"row\">\n                <div class=\"col-lg-12\">\n                    <div class=\"panel panel-default\">\n                        <div class=\"panel-heading\">\n                            Basic Form Elements\n                        </div>\n                        <div class=\"panel-body\">\n                            <div class=\"row\">\n                                <div class=\"col-lg-6\">\n                                    <form role=\"form\">\n                                        <div class=\"form-group\">\n                                            <label>Text Input</label>\n                                            <input class=\"form-control\">\n                                            <p class=\"help-block\">Example block-level help text here.</p>\n                                        </div>\n                                        <div class=\"form-group\">\n                                            <label>Text Input with Placeholder</label>\n                                            <input class=\"form-control\" placeholder=\"Enter text\">\n                                        </div>\n                                        <div class=\"form-group\">\n                                            <label>Static Control</label>\n                                            <p class=\"form-control-static\">email@example.com</p>\n                                        </div>\n                                        <div class=\"form-group\">\n                                            <label>File input</label>\n                                            <input type=\"file\">\n                                        </div>\n                                        <div class=\"form-group\">\n                                            <label>Text area</label>\n                                            <textarea class=\"form-control\" rows=\"3\"></textarea>\n                                        </div>\n                                        <div class=\"form-group\">\n                                            <label>Checkboxes</label>\n                                            <div class=\"checkbox\">\n                                                <label>\n                                                    <input type=\"checkbox\" value=\"\">Checkbox 1\n                                                </label>\n                                            </div>\n                                            <div class=\"checkbox\">\n                                                <label>\n                                                    <input type=\"checkbox\" value=\"\">Checkbox 2\n                                                </label>\n                                            </div>\n                                            <div class=\"checkbox\">\n                                                <label>\n                                                    <input type=\"checkbox\" value=\"\">Checkbox 3\n                                                </label>\n                                            </div>\n                                        </div>\n                                        <div class=\"form-group\">\n                                            <label>Inline Checkboxes</label>\n                                            <label class=\"checkbox-inline\">\n                                                <input type=\"checkbox\">1\n                                            </label>\n                                            <label class=\"checkbox-inline\">\n                                                <input type=\"checkbox\">2\n                                            </label>\n                                            <label class=\"checkbox-inline\">\n                                                <input type=\"checkbox\">3\n                                            </label>\n                                        </div>\n                                        <div class=\"form-group\">\n                                            <label>Radio Buttons</label>\n                                            <div class=\"radio\">\n                                                <label>\n                                                    <input type=\"radio\" name=\"optionsRadios\" id=\"optionsRadios1\" value=\"option1\" checked>Radio 1\n                                                </label>\n                                            </div>\n                                            <div class=\"radio\">\n                                                <label>\n                                                    <input type=\"radio\" name=\"optionsRadios\" id=\"optionsRadios2\" value=\"option2\">Radio 2\n                                                </label>\n                                            </div>\n                                            <div class=\"radio\">\n                                                <label>\n                                                    <input type=\"radio\" name=\"optionsRadios\" id=\"optionsRadios3\" value=\"option3\">Radio 3\n                                                </label>\n                                            </div>\n                                        </div>\n                                        <div class=\"form-group\">\n                                            <label>Inline Radio Buttons</label>\n                                            <label class=\"radio-inline\">\n                                                <input type=\"radio\" name=\"optionsRadiosInline\" id=\"optionsRadiosInline1\" value=\"option1\" checked>1\n                                            </label>\n                                            <label class=\"radio-inline\">\n                                                <input type=\"radio\" name=\"optionsRadiosInline\" id=\"optionsRadiosInline2\" value=\"option2\">2\n                                            </label>\n                                            <label class=\"radio-inline\">\n                                                <input type=\"radio\" name=\"optionsRadiosInline\" id=\"optionsRadiosInline3\" value=\"option3\">3\n                                            </label>\n                                        </div>\n                                        <div class=\"form-group\">\n                                            <label>Selects</label>\n                                            <select class=\"form-control\">\n                                                <option>1</option>\n                                                <option>2</option>\n                                                <option>3</option>\n                                                <option>4</option>\n                                                <option>5</option>\n                                            </select>\n                                        </div>\n                                        <div class=\"form-group\">\n                                            <label>Multiple Selects</label>\n                                            <select multiple class=\"form-control\">\n                                                <option>1</option>\n                                                <option>2</option>\n                                                <option>3</option>\n                                                <option>4</option>\n                                                <option>5</option>\n                                            </select>\n                                        </div>\n                                        <button type=\"submit\" class=\"btn btn-default\">Submit Button</button>\n                                        <button type=\"reset\" class=\"btn btn-default\">Reset Button</button>\n                                    </form>\n                                </div>\n                                <!-- /.col-lg-6 (nested) -->\n                                <div class=\"col-lg-6\">\n                                    <h1>Disabled Form States</h1>\n                                    <form role=\"form\">\n                                        <fieldset disabled>\n                                            <div class=\"form-group\">\n                                                <label for=\"disabledSelect\">Disabled input</label>\n                                                <input class=\"form-control\" id=\"disabledInput\" type=\"text\" placeholder=\"Disabled input\" disabled>\n                                            </div>\n                                            <div class=\"form-group\">\n                                                <label for=\"disabledSelect\">Disabled select menu</label>\n                                                <select id=\"disabledSelect\" class=\"form-control\">\n                                                    <option>Disabled select</option>\n                                                </select>\n                                            </div>\n                                            <div class=\"checkbox\">\n                                                <label>\n                                                    <input type=\"checkbox\">Disabled Checkbox\n                                                </label>\n                                            </div>\n                                            <button type=\"submit\" class=\"btn btn-primary\">Disabled Button</button>\n                                        </fieldset>\n                                    </form>\n                                    <h1>Form Validation States</h1>\n                                    <form role=\"form\">\n                                        <div class=\"form-group has-success\">\n                                            <label class=\"control-label\" for=\"inputSuccess\">Input with success</label>\n                                            <input type=\"text\" class=\"form-control\" id=\"inputSuccess\">\n                                        </div>\n                                        <div class=\"form-group has-warning\">\n                                            <label class=\"control-label\" for=\"inputWarning\">Input with warning</label>\n                                            <input type=\"text\" class=\"form-control\" id=\"inputWarning\">\n                                        </div>\n                                        <div class=\"form-group has-error\">\n                                            <label class=\"control-label\" for=\"inputError\">Input with error</label>\n                                            <input type=\"text\" class=\"form-control\" id=\"inputError\">\n                                        </div>\n                                    </form>\n                                    <h1>Input Groups</h1>\n                                    <form role=\"form\">\n                                        <div class=\"form-group input-group\">\n                                            <span class=\"input-group-addon\">@</span>\n                                            <input type=\"text\" class=\"form-control\" placeholder=\"Username\">\n                                        </div>\n                                        <div class=\"form-group input-group\">\n                                            <input type=\"text\" class=\"form-control\">\n                                            <span class=\"input-group-addon\">.00</span>\n                                        </div>\n                                        <div class=\"form-group input-group\">\n                                            <span class=\"input-group-addon\"><i class=\"fa fa-eur\"></i>\n                                            </span>\n                                            <input type=\"text\" class=\"form-control\" placeholder=\"Font Awesome Icon\">\n                                        </div>\n                                        <div class=\"form-group input-group\">\n                                            <span class=\"input-group-addon\">$</span>\n                                            <input type=\"text\" class=\"form-control\">\n                                            <span class=\"input-group-addon\">.00</span>\n                                        </div>\n                                        <div class=\"form-group input-group\">\n                                            <input type=\"text\" class=\"form-control\">\n                                            <span class=\"input-group-btn\">\n                                                <button class=\"btn btn-default\" type=\"button\"><i class=\"fa fa-search\"></i>\n                                                </button>\n                                            </span>\n                                        </div>\n                                    </form>\n                                </div>\n                                <!-- /.col-lg-6 (nested) -->\n                            </div>\n                            <!-- /.row (nested) -->\n                        </div>\n                        <!-- /.panel-body -->\n                    </div>\n                    <!-- /.panel -->\n                </div>\n                <!-- /.col-lg-12 -->\n            </div>\n            <!-- /.row -->\n        </div>\n        <!-- /#page-wrapper -->\n\n    </div>\n    <!-- /#wrapper -->\n\n    <!-- jQuery -->\n    <script src=\"../vendor/jquery/jquery.min.js\"></script>\n\n    <!-- Bootstrap Core JavaScript -->\n    <script src=\"../vendor/bootstrap/js/bootstrap.min.js\"></script>\n\n    <!-- Metis Menu Plugin JavaScript -->\n    <script src=\"../vendor/metisMenu/metisMenu.min.js\"></script>\n\n    <!-- Custom Theme JavaScript -->\n    <script src=\"../dist/js/sb-admin-2.js\"></script>\n\n</body>\n\n</html>\n"
  },
  {
    "path": "app_backend/pages/grid.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n\n<head>\n\n    <meta charset=\"utf-8\">\n    <meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\">\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">\n    <meta name=\"description\" content=\"\">\n    <meta name=\"author\" content=\"\">\n\n    <title>SB Admin 2 - Bootstrap Admin Theme</title>\n\n    <!-- Bootstrap Core CSS -->\n    <link href=\"../vendor/bootstrap/css/bootstrap.min.css\" rel=\"stylesheet\">\n\n    <!-- MetisMenu CSS -->\n    <link href=\"../vendor/metisMenu/metisMenu.min.css\" rel=\"stylesheet\">\n\n    <!-- Custom CSS -->\n    <link href=\"../dist/css/sb-admin-2.css\" rel=\"stylesheet\">\n\n    <!-- Custom Fonts -->\n    <link href=\"../vendor/font-awesome/css/font-awesome.min.css\" rel=\"stylesheet\" type=\"text/css\">\n\n    <!-- HTML5 Shim and Respond.js IE8 support of HTML5 elements and media queries -->\n    <!-- WARNING: Respond.js doesn't work if you view the page via file:// -->\n    <!--[if lt IE 9]>\n        <script src=\"https://oss.maxcdn.com/libs/html5shiv/3.7.0/html5shiv.js\"></script>\n        <script src=\"https://oss.maxcdn.com/libs/respond.js/1.4.2/respond.min.js\"></script>\n    <![endif]-->\n\n</head>\n\n<body>\n\n    <div id=\"wrapper\">\n\n        <!-- Navigation -->\n        <nav class=\"navbar navbar-default navbar-static-top\" role=\"navigation\" style=\"margin-bottom: 0\">\n            <div class=\"navbar-header\">\n                <button type=\"button\" class=\"navbar-toggle\" data-toggle=\"collapse\" data-target=\".navbar-collapse\">\n                    <span class=\"sr-only\">Toggle navigation</span>\n                    <span class=\"icon-bar\"></span>\n                    <span class=\"icon-bar\"></span>\n                    <span class=\"icon-bar\"></span>\n                </button>\n                <a class=\"navbar-brand\" href=\"index.html\">SB Admin v2.0</a>\n            </div>\n            <!-- /.navbar-header -->\n\n            <ul class=\"nav navbar-top-links navbar-right\">\n                <li class=\"dropdown\">\n                    <a class=\"dropdown-toggle\" data-toggle=\"dropdown\" href=\"#\">\n                        <i class=\"fa fa-envelope fa-fw\"></i> <i class=\"fa fa-caret-down\"></i>\n                    </a>\n                    <ul class=\"dropdown-menu dropdown-messages\">\n                        <li>\n                            <a href=\"#\">\n                                <div>\n                                    <strong>John Smith</strong>\n                                    <span class=\"pull-right text-muted\">\n                                        <em>Yesterday</em>\n                                    </span>\n                                </div>\n                                <div>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque eleifend...</div>\n                            </a>\n                        </li>\n                        <li class=\"divider\"></li>\n                        <li>\n                            <a href=\"#\">\n                                <div>\n                                    <strong>John Smith</strong>\n                                    <span class=\"pull-right text-muted\">\n                                        <em>Yesterday</em>\n                                    </span>\n                                </div>\n                                <div>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque eleifend...</div>\n                            </a>\n                        </li>\n                        <li class=\"divider\"></li>\n                        <li>\n                            <a href=\"#\">\n                                <div>\n                                    <strong>John Smith</strong>\n                                    <span class=\"pull-right text-muted\">\n                                        <em>Yesterday</em>\n                                    </span>\n                                </div>\n                                <div>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque eleifend...</div>\n                            </a>\n                        </li>\n                        <li class=\"divider\"></li>\n                        <li>\n                            <a class=\"text-center\" href=\"#\">\n                                <strong>Read All Messages</strong>\n                                <i class=\"fa fa-angle-right\"></i>\n                            </a>\n                        </li>\n                    </ul>\n                    <!-- /.dropdown-messages -->\n                </li>\n                <!-- /.dropdown -->\n                <li class=\"dropdown\">\n                    <a class=\"dropdown-toggle\" data-toggle=\"dropdown\" href=\"#\">\n                        <i class=\"fa fa-tasks fa-fw\"></i> <i class=\"fa fa-caret-down\"></i>\n                    </a>\n                    <ul class=\"dropdown-menu dropdown-tasks\">\n                        <li>\n                            <a href=\"#\">\n                                <div>\n                                    <p>\n                                        <strong>Task 1</strong>\n                                        <span class=\"pull-right text-muted\">40% Complete</span>\n                                    </p>\n                                    <div class=\"progress progress-striped active\">\n                                        <div class=\"progress-bar progress-bar-success\" role=\"progressbar\" aria-valuenow=\"40\" aria-valuemin=\"0\" aria-valuemax=\"100\" style=\"width: 40%\">\n                                            <span class=\"sr-only\">40% Complete (success)</span>\n                                        </div>\n                                    </div>\n                                </div>\n                            </a>\n                        </li>\n                        <li class=\"divider\"></li>\n                        <li>\n                            <a href=\"#\">\n                                <div>\n                                    <p>\n                                        <strong>Task 2</strong>\n                                        <span class=\"pull-right text-muted\">20% Complete</span>\n                                    </p>\n                                    <div class=\"progress progress-striped active\">\n                                        <div class=\"progress-bar progress-bar-info\" role=\"progressbar\" aria-valuenow=\"20\" aria-valuemin=\"0\" aria-valuemax=\"100\" style=\"width: 20%\">\n                                            <span class=\"sr-only\">20% Complete</span>\n                                        </div>\n                                    </div>\n                                </div>\n                            </a>\n                        </li>\n                        <li class=\"divider\"></li>\n                        <li>\n                            <a href=\"#\">\n                                <div>\n                                    <p>\n                                        <strong>Task 3</strong>\n                                        <span class=\"pull-right text-muted\">60% Complete</span>\n                                    </p>\n                                    <div class=\"progress progress-striped active\">\n                                        <div class=\"progress-bar progress-bar-warning\" role=\"progressbar\" aria-valuenow=\"60\" aria-valuemin=\"0\" aria-valuemax=\"100\" style=\"width: 60%\">\n                                            <span class=\"sr-only\">60% Complete (warning)</span>\n                                        </div>\n                                    </div>\n                                </div>\n                            </a>\n                        </li>\n                        <li class=\"divider\"></li>\n                        <li>\n                            <a href=\"#\">\n                                <div>\n                                    <p>\n                                        <strong>Task 4</strong>\n                                        <span class=\"pull-right text-muted\">80% Complete</span>\n                                    </p>\n                                    <div class=\"progress progress-striped active\">\n                                        <div class=\"progress-bar progress-bar-danger\" role=\"progressbar\" aria-valuenow=\"80\" aria-valuemin=\"0\" aria-valuemax=\"100\" style=\"width: 80%\">\n                                            <span class=\"sr-only\">80% Complete (danger)</span>\n                                        </div>\n                                    </div>\n                                </div>\n                            </a>\n                        </li>\n                        <li class=\"divider\"></li>\n                        <li>\n                            <a class=\"text-center\" href=\"#\">\n                                <strong>See All Tasks</strong>\n                                <i class=\"fa fa-angle-right\"></i>\n                            </a>\n                        </li>\n                    </ul>\n                    <!-- /.dropdown-tasks -->\n                </li>\n                <!-- /.dropdown -->\n                <li class=\"dropdown\">\n                    <a class=\"dropdown-toggle\" data-toggle=\"dropdown\" href=\"#\">\n                        <i class=\"fa fa-bell fa-fw\"></i> <i class=\"fa fa-caret-down\"></i>\n                    </a>\n                    <ul class=\"dropdown-menu dropdown-alerts\">\n                        <li>\n                            <a href=\"#\">\n                                <div>\n                                    <i class=\"fa fa-comment fa-fw\"></i> New Comment\n                                    <span class=\"pull-right text-muted small\">4 minutes ago</span>\n                                </div>\n                            </a>\n                        </li>\n                        <li class=\"divider\"></li>\n                        <li>\n                            <a href=\"#\">\n                                <div>\n                                    <i class=\"fa fa-twitter fa-fw\"></i> 3 New Followers\n                                    <span class=\"pull-right text-muted small\">12 minutes ago</span>\n                                </div>\n                            </a>\n                        </li>\n                        <li class=\"divider\"></li>\n                        <li>\n                            <a href=\"#\">\n                                <div>\n                                    <i class=\"fa fa-envelope fa-fw\"></i> Message Sent\n                                    <span class=\"pull-right text-muted small\">4 minutes ago</span>\n                                </div>\n                            </a>\n                        </li>\n                        <li class=\"divider\"></li>\n                        <li>\n                            <a href=\"#\">\n                                <div>\n                                    <i class=\"fa fa-tasks fa-fw\"></i> New Task\n                                    <span class=\"pull-right text-muted small\">4 minutes ago</span>\n                                </div>\n                            </a>\n                        </li>\n                        <li class=\"divider\"></li>\n                        <li>\n                            <a href=\"#\">\n                                <div>\n                                    <i class=\"fa fa-upload fa-fw\"></i> Server Rebooted\n                                    <span class=\"pull-right text-muted small\">4 minutes ago</span>\n                                </div>\n                            </a>\n                        </li>\n                        <li class=\"divider\"></li>\n                        <li>\n                            <a class=\"text-center\" href=\"#\">\n                                <strong>See All Alerts</strong>\n                                <i class=\"fa fa-angle-right\"></i>\n                            </a>\n                        </li>\n                    </ul>\n                    <!-- /.dropdown-alerts -->\n                </li>\n                <!-- /.dropdown -->\n                <li class=\"dropdown\">\n                    <a class=\"dropdown-toggle\" data-toggle=\"dropdown\" href=\"#\">\n                        <i class=\"fa fa-user fa-fw\"></i> <i class=\"fa fa-caret-down\"></i>\n                    </a>\n                    <ul class=\"dropdown-menu dropdown-user\">\n                        <li><a href=\"#\"><i class=\"fa fa-user fa-fw\"></i> User Profile</a>\n                        </li>\n                        <li><a href=\"#\"><i class=\"fa fa-gear fa-fw\"></i> Settings</a>\n                        </li>\n                        <li class=\"divider\"></li>\n                        <li><a href=\"login.html\"><i class=\"fa fa-sign-out fa-fw\"></i> Logout</a>\n                        </li>\n                    </ul>\n                    <!-- /.dropdown-user -->\n                </li>\n                <!-- /.dropdown -->\n            </ul>\n            <!-- /.navbar-top-links -->\n\n            <div class=\"navbar-default sidebar\" role=\"navigation\">\n                <div class=\"sidebar-nav navbar-collapse\">\n                    <ul class=\"nav\" id=\"side-menu\">\n                        <li class=\"sidebar-search\">\n                            <div class=\"input-group custom-search-form\">\n                                <input type=\"text\" class=\"form-control\" placeholder=\"Search...\">\n                                <span class=\"input-group-btn\">\n                                <button class=\"btn btn-default\" type=\"button\">\n                                    <i class=\"fa fa-search\"></i>\n                                </button>\n                            </span>\n                            </div>\n                            <!-- /input-group -->\n                        </li>\n                        <li>\n                            <a href=\"index.html\"><i class=\"fa fa-dashboard fa-fw\"></i> Dashboard</a>\n                        </li>\n                        <li>\n                            <a href=\"#\"><i class=\"fa fa-bar-chart-o fa-fw\"></i> Charts<span class=\"fa arrow\"></span></a>\n                            <ul class=\"nav nav-second-level\">\n                                <li>\n                                    <a href=\"flot.html\">Flot Charts</a>\n                                </li>\n                                <li>\n                                    <a href=\"morris.html\">Morris.js Charts</a>\n                                </li>\n                            </ul>\n                            <!-- /.nav-second-level -->\n                        </li>\n                        <li>\n                            <a href=\"tables.html\"><i class=\"fa fa-table fa-fw\"></i> Tables</a>\n                        </li>\n                        <li>\n                            <a href=\"forms.html\"><i class=\"fa fa-edit fa-fw\"></i> Forms</a>\n                        </li>\n                        <li>\n                            <a href=\"#\"><i class=\"fa fa-wrench fa-fw\"></i> UI Elements<span class=\"fa arrow\"></span></a>\n                            <ul class=\"nav nav-second-level\">\n                                <li>\n                                    <a href=\"panels-wells.html\">Panels and Wells</a>\n                                </li>\n                                <li>\n                                    <a href=\"buttons.html\">Buttons</a>\n                                </li>\n                                <li>\n                                    <a href=\"notifications.html\">Notifications</a>\n                                </li>\n                                <li>\n                                    <a href=\"typography.html\">Typography</a>\n                                </li>\n                                <li>\n                                    <a href=\"icons.html\"> Icons</a>\n                                </li>\n                                <li>\n                                    <a href=\"grid.html\">Grid</a>\n                                </li>\n                            </ul>\n                            <!-- /.nav-second-level -->\n                        </li>\n                        <li>\n                            <a href=\"#\"><i class=\"fa fa-sitemap fa-fw\"></i> Multi-Level Dropdown<span class=\"fa arrow\"></span></a>\n                            <ul class=\"nav nav-second-level\">\n                                <li>\n                                    <a href=\"#\">Second Level Item</a>\n                                </li>\n                                <li>\n                                    <a href=\"#\">Second Level Item</a>\n                                </li>\n                                <li>\n                                    <a href=\"#\">Third Level <span class=\"fa arrow\"></span></a>\n                                    <ul class=\"nav nav-third-level\">\n                                        <li>\n                                            <a href=\"#\">Third Level Item</a>\n                                        </li>\n                                        <li>\n                                            <a href=\"#\">Third Level Item</a>\n                                        </li>\n                                        <li>\n                                            <a href=\"#\">Third Level Item</a>\n                                        </li>\n                                        <li>\n                                            <a href=\"#\">Third Level Item</a>\n                                        </li>\n                                    </ul>\n                                    <!-- /.nav-third-level -->\n                                </li>\n                            </ul>\n                            <!-- /.nav-second-level -->\n                        </li>\n                        <li>\n                            <a href=\"#\"><i class=\"fa fa-files-o fa-fw\"></i> Sample Pages<span class=\"fa arrow\"></span></a>\n                            <ul class=\"nav nav-second-level\">\n                                <li>\n                                    <a href=\"blank.html\">Blank Page</a>\n                                </li>\n                                <li>\n                                    <a href=\"login.html\">Login Page</a>\n                                </li>\n                            </ul>\n                            <!-- /.nav-second-level -->\n                        </li>\n                    </ul>\n                </div>\n                <!-- /.sidebar-collapse -->\n            </div>\n            <!-- /.navbar-static-side -->\n        </nav>\n\n        <div id=\"page-wrapper\">\n            <div class=\"row\">\n                <div class=\"col-lg-12\">\n                    <h1 class=\"page-header\">Grid</h1>\n                </div>\n                <!-- /.col-lg-12 -->\n            </div>\n            <!-- /.row -->\n            <div class=\"row\">\n                <div class=\"col-lg-12\">\n                    <div class=\"panel panel-default\">\n                        <div class=\"panel-body\">\n                            <h3>Grid options</h3>\n                            <p>See how aspects of the Bootstrap grid system work across multiple devices with a handy table.</p>\n                            <div class=\"table-responsive\">\n                                <table class=\"table table-bordered table-striped\">\n                                    <thead>\n                                        <tr>\n                                            <th></th>\n                                            <th>\n                                                Extra small devices\n                                                <small>Phones (&lt;768px)</small>\n                                            </th>\n                                            <th>\n                                                Small devices\n                                                <small>Tablets (&ge;768px)</small>\n                                            </th>\n                                            <th>\n                                                Medium devices\n                                                <small>Desktops (&ge;992px)</small>\n                                            </th>\n                                            <th>\n                                                Large devices\n                                                <small>Desktops (&ge;1200px)</small>\n                                            </th>\n                                        </tr>\n                                    </thead>\n                                    <tbody>\n                                        <tr>\n                                            <th>Grid behavior</th>\n                                            <td>Horizontal at all times</td>\n                                            <td colspan=\"3\">Collapsed to start, horizontal above breakpoints</td>\n                                        </tr>\n                                        <tr>\n                                            <th>Max container width</th>\n                                            <td>None (auto)</td>\n                                            <td>750px</td>\n                                            <td>970px</td>\n                                            <td>1170px</td>\n                                        </tr>\n                                        <tr>\n                                            <th>Class prefix</th>\n                                            <td>\n                                                <code>.col-xs-</code>\n                                            </td>\n                                            <td>\n                                                <code>.col-sm-</code>\n                                            </td>\n                                            <td>\n                                                <code>.col-md-</code>\n                                            </td>\n                                            <td>\n                                                <code>.col-lg-</code>\n                                            </td>\n                                        </tr>\n                                        <tr>\n                                            <th># of columns</th>\n                                            <td colspan=\"4\">12</td>\n                                        </tr>\n                                        <tr>\n                                            <th>Max column width</th>\n                                            <td class=\"text-muted\">Auto</td>\n                                            <td>60px</td>\n                                            <td>78px</td>\n                                            <td>95px</td>\n                                        </tr>\n                                        <tr>\n                                            <th>Gutter width</th>\n                                            <td colspan=\"4\">30px (15px on each side of a column)</td>\n                                        </tr>\n                                        <tr>\n                                            <th>Nestable</th>\n                                            <td colspan=\"4\">Yes</td>\n                                        </tr>\n                                        <tr>\n                                            <th>Offsets</th>\n                                            <td colspan=\"4\">Yes</td>\n                                        </tr>\n                                        <tr>\n                                            <th>Column ordering</th>\n                                            <td colspan=\"4\">Yes</td>\n                                        </tr>\n                                    </tbody>\n                                </table>\n                            </div>\n                            <p>Grid classes apply to devices with screen widths greater than or equal to the breakpoint sizes, and override grid classes targeted at smaller devices. Therefore, applying any\n                                <code>.col-md-</code> class to an element will not only affect its styling on medium devices but also on large devices if a\n                                <code>.col-lg-</code> class is not present.</p>\n                        </div>\n                    </div>\n                </div>\n                <!-- /.col-lg-12 -->\n            </div>\n            <!-- /.row -->\n\n            <div class=\"row\">\n                <div class=\"col-lg-12\">\n                    <div class=\"panel panel-default\">\n                        <div class=\"panel-body\">\n                            <h3>Example: Stacked-to-horizontal</h3>\n                            <p>Using a single set of\n                                <code>.col-md-*</code> grid classes, you can create a default grid system that starts out stacked on mobile devices and tablet devices (the extra small to small range) before becoming horizontal on desktop (medium) devices. Place grid columns in any\n                                <code>.row</code>.</p>\n                            <div class=\"row show-grid\">\n                                <div class=\"col-md-1\">.col-md-1</div>\n                                <div class=\"col-md-1\">.col-md-1</div>\n                                <div class=\"col-md-1\">.col-md-1</div>\n                                <div class=\"col-md-1\">.col-md-1</div>\n                                <div class=\"col-md-1\">.col-md-1</div>\n                                <div class=\"col-md-1\">.col-md-1</div>\n                                <div class=\"col-md-1\">.col-md-1</div>\n                                <div class=\"col-md-1\">.col-md-1</div>\n                                <div class=\"col-md-1\">.col-md-1</div>\n                                <div class=\"col-md-1\">.col-md-1</div>\n                                <div class=\"col-md-1\">.col-md-1</div>\n                                <div class=\"col-md-1\">.col-md-1</div>\n                            </div>\n                            <div class=\"row show-grid\">\n                                <div class=\"col-md-8\">.col-md-8</div>\n                                <div class=\"col-md-4\">.col-md-4</div>\n                            </div>\n                            <div class=\"row show-grid\">\n                                <div class=\"col-md-4\">.col-md-4</div>\n                                <div class=\"col-md-4\">.col-md-4</div>\n                                <div class=\"col-md-4\">.col-md-4</div>\n                            </div>\n                            <div class=\"row show-grid\">\n                                <div class=\"col-md-6\">.col-md-6</div>\n                                <div class=\"col-md-6\">.col-md-6</div>\n                            </div>\n                        </div>\n                    </div>\n                </div>\n                <!-- /.col-lg-12 -->\n            </div>\n            <!-- /.row -->\n\n            <div class=\"row\">\n                <div class=\"col-lg-12\">\n                    <div class=\"panel panel-default\">\n                        <div class=\"panel-body\">\n                            <h3>Example: Mobile and desktop</h3>\n                            <p>Don't want your columns to simply stack in smaller devices? Use the extra small and medium device grid classes by adding\n                                <code>.col-xs-*</code>\n                                <code>.col-md-*</code> to your columns. See the example below for a better idea of how it all works.</p>\n                            <div class=\"row show-grid\">\n                                <div class=\"col-xs-12 col-md-8\">.col-xs-12 .col-md-8</div>\n                                <div class=\"col-xs-6 col-md-4\">.col-xs-6 .col-md-4</div>\n                            </div>\n                            <div class=\"row show-grid\">\n                                <div class=\"col-xs-6 col-md-4\">.col-xs-6 .col-md-4</div>\n                                <div class=\"col-xs-6 col-md-4\">.col-xs-6 .col-md-4</div>\n                                <div class=\"col-xs-6 col-md-4\">.col-xs-6 .col-md-4</div>\n                            </div>\n                            <div class=\"row show-grid\">\n                                <div class=\"col-xs-6\">.col-xs-6</div>\n                                <div class=\"col-xs-6\">.col-xs-6</div>\n                            </div>\n                        </div>\n                    </div>\n                </div>\n                <!-- /.col-lg-12 -->\n            </div>\n            <!-- /.row -->\n\n            <div class=\"row\">\n                <div class=\"col-lg-12\">\n                    <div class=\"panel panel-default\">\n                        <div class=\"panel-body\">\n                            <h3>Example: Mobile, tablet, desktops</h3>\n                            <p>Build on the previous example by creating even more dynamic and powerful layouts with tablet\n                                <code>.col-sm-*</code> classes.</p>\n                            <div class=\"row show-grid\">\n                                <div class=\"col-xs-12 col-sm-6 col-md-8\">.col-xs-12 .col-sm-6 .col-md-8</div>\n                                <div class=\"col-xs-6 col-md-4\">.col-xs-6 .col-md-4</div>\n                            </div>\n                            <div class=\"row show-grid\">\n                                <div class=\"col-xs-6 col-sm-4\">.col-xs-6 .col-sm-4</div>\n                                <div class=\"col-xs-6 col-sm-4\">.col-xs-6 .col-sm-4</div>\n                                <!-- Optional: clear the XS cols if their content doesn't match in height -->\n                                <div class=\"clearfix visible-xs\"></div>\n                                <div class=\"col-xs-6 col-sm-4\">.col-xs-6 .col-sm-4</div>\n                            </div>\n                        </div>\n                    </div>\n                </div>\n                <!-- /.col-lg-12 -->\n            </div>\n            <!-- /.row -->\n\n            <div class=\"row\">\n                <div class=\"col-lg-12\">\n                    <div class=\"panel panel-default\">\n                        <div class=\"panel-body\">\n                            <h3 id=\"grid-responsive-resets\">Responsive column resets</h3>\n                            <p>With the four tiers of grids available you're bound to run into issues where, at certain breakpoints, your columns don't clear quite right as one is taller than the other. To fix that, use a combination of a\n                                <code>.clearfix</code> and our <a href=\"#responsive-utilities\">responsive utility classes</a>.</p>\n                            <div class=\"row show-grid\">\n                                <div class=\"col-xs-6 col-sm-3\">\n                                    .col-xs-6 .col-sm-3\n                                    <br>Resize your viewport or check it out on your phone for an example.\n                                </div>\n                                <div class=\"col-xs-6 col-sm-3\">.col-xs-6 .col-sm-3</div>\n\n                                <!-- Add the extra clearfix for only the required viewport -->\n                                <div class=\"clearfix visible-xs\"></div>\n\n                                <div class=\"col-xs-6 col-sm-3\">.col-xs-6 .col-sm-3</div>\n                                <div class=\"col-xs-6 col-sm-3\">.col-xs-6 .col-sm-3</div>\n                            </div>\n                        </div>\n                    </div>\n                </div>\n                <!-- /.col-lg-12 -->\n            </div>\n            <!-- /.row -->\n\n            <div class=\"row\">\n                <div class=\"col-lg-12\">\n                    <div class=\"panel panel-default\">\n                        <div class=\"panel-body\">\n                            <h3 id=\"grid-offsetting\">Offsetting columns</h3>\n                            <p>Move columns to the right using\n                                <code>.col-md-offset-*</code> classes. These classes increase the left margin of a column by\n                                <code>*</code> columns. For example,\n                                <code>.col-md-offset-4</code> moves\n                                <code>.col-md-4</code> over four columns.</p>\n                            <div class=\"row show-grid\">\n                                <div class=\"col-md-4\">.col-md-4</div>\n                                <div class=\"col-md-4 col-md-offset-4\">.col-md-4 .col-md-offset-4</div>\n                            </div>\n                            <div class=\"row show-grid\">\n                                <div class=\"col-md-3 col-md-offset-3\">.col-md-3 .col-md-offset-3</div>\n                                <div class=\"col-md-3 col-md-offset-3\">.col-md-3 .col-md-offset-3</div>\n                            </div>\n                            <div class=\"row show-grid\">\n                                <div class=\"col-md-6 col-md-offset-3\">.col-md-6 .col-md-offset-3</div>\n                            </div>\n                        </div>\n                    </div>\n                </div>\n                <!-- /.col-lg-12 -->\n            </div>\n            <!-- /.row -->\n\n            <div class=\"row\">\n                <div class=\"col-lg-12\">\n                    <div class=\"panel panel-default\">\n                        <div class=\"panel-body\">\n                            <h3 id=\"grid-nesting\">Nesting columns</h3>\n                            <p>To nest your content with the default grid, add a new\n                                <code>.row</code> and set of\n                                <code>.col-md-*</code> columns within an existing\n                                <code>.col-md-*</code> column. Nested rows should include a set of columns that add up to 12.</p>\n                            <div class=\"row show-grid\">\n                                <div class=\"col-md-9\">\n                                    Level 1: .col-md-9\n                                    <div class=\"row show-grid\">\n                                        <div class=\"col-md-6\">\n                                            Level 2: .col-md-6\n                                        </div>\n                                        <div class=\"col-md-6\">\n                                            Level 2: .col-md-6\n                                        </div>\n                                    </div>\n                                </div>\n                            </div>\n                        </div>\n                    </div>\n                </div>\n                <!-- /.col-lg-12 -->\n            </div>\n            <!-- /.row -->\n\n            <div class=\"row\">\n                <div class=\"col-lg-12\">\n                    <div class=\"panel panel-default\">\n                        <div class=\"panel-body\">\n                            <h3 id=\"grid-column-ordering\">Column ordering</h3>\n                            <p>Easily change the order of our built-in grid columns with\n                                <code>.col-md-push-*</code> and\n                                <code>.col-md-pull-*</code> modifier classes.</p>\n                            <div class=\"row show-grid\">\n                                <div class=\"col-md-9 col-md-push-3\">.col-md-9 .col-md-push-3</div>\n                                <div class=\"col-md-3 col-md-pull-9\">.col-md-3 .col-md-pull-9</div>\n                            </div>\n                        </div>\n                    </div>\n                </div>\n                <!-- /.col-lg-12 -->\n            </div>\n            <!-- /.row -->\n\n        </div>\n        <!-- /#page-wrapper -->\n\n    </div>\n    <!-- /#wrapper -->\n\n    <!-- jQuery -->\n    <script src=\"../vendor/jquery/jquery.min.js\"></script>\n\n    <!-- Bootstrap Core JavaScript -->\n    <script src=\"../vendor/bootstrap/js/bootstrap.min.js\"></script>\n\n    <!-- Metis Menu Plugin JavaScript -->\n    <script src=\"../vendor/metisMenu/metisMenu.min.js\"></script>\n\n    <!-- Custom Theme JavaScript -->\n    <script src=\"../dist/js/sb-admin-2.js\"></script>\n\n</body>\n\n</html>\n"
  },
  {
    "path": "app_backend/pages/icons.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n\n<head>\n\n    <meta charset=\"utf-8\">\n    <meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\">\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">\n    <meta name=\"description\" content=\"\">\n    <meta name=\"author\" content=\"\">\n\n    <title>SB Admin 2 - Bootstrap Admin Theme</title>\n\n    <!-- Bootstrap Core CSS -->\n    <link href=\"../vendor/bootstrap/css/bootstrap.min.css\" rel=\"stylesheet\">\n\n    <!-- MetisMenu CSS -->\n    <link href=\"../vendor/metisMenu/metisMenu.min.css\" rel=\"stylesheet\">\n\n    <!-- Custom CSS -->\n    <link href=\"../dist/css/sb-admin-2.css\" rel=\"stylesheet\">\n\n    <!-- Custom Fonts -->\n    <link href=\"../vendor/font-awesome/css/font-awesome.min.css\" rel=\"stylesheet\" type=\"text/css\">\n\n    <!-- HTML5 Shim and Respond.js IE8 support of HTML5 elements and media queries -->\n    <!-- WARNING: Respond.js doesn't work if you view the page via file:// -->\n    <!--[if lt IE 9]>\n        <script src=\"https://oss.maxcdn.com/libs/html5shiv/3.7.0/html5shiv.js\"></script>\n        <script src=\"https://oss.maxcdn.com/libs/respond.js/1.4.2/respond.min.js\"></script>\n    <![endif]-->\n\n</head>\n\n<body>\n\n    <div id=\"wrapper\">\n\n        <!-- Navigation -->\n        <nav class=\"navbar navbar-default navbar-static-top\" role=\"navigation\" style=\"margin-bottom: 0\">\n            <div class=\"navbar-header\">\n                <button type=\"button\" class=\"navbar-toggle\" data-toggle=\"collapse\" data-target=\".navbar-collapse\">\n                    <span class=\"sr-only\">Toggle navigation</span>\n                    <span class=\"icon-bar\"></span>\n                    <span class=\"icon-bar\"></span>\n                    <span class=\"icon-bar\"></span>\n                </button>\n                <a class=\"navbar-brand\" href=\"index.html\">SB Admin v2.0</a>\n            </div>\n            <!-- /.navbar-header -->\n\n            <ul class=\"nav navbar-top-links navbar-right\">\n                <li class=\"dropdown\">\n                    <a class=\"dropdown-toggle\" data-toggle=\"dropdown\" href=\"#\">\n                        <i class=\"fa fa-envelope fa-fw\"></i> <i class=\"fa fa-caret-down\"></i>\n                    </a>\n                    <ul class=\"dropdown-menu dropdown-messages\">\n                        <li>\n                            <a href=\"#\">\n                                <div>\n                                    <strong>John Smith</strong>\n                                    <span class=\"pull-right text-muted\">\n                                            <em>Yesterday</em>\n                                        </span>\n                                </div>\n                                <div>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque eleifend...</div>\n                            </a>\n                        </li>\n                        <li class=\"divider\"></li>\n                        <li>\n                            <a href=\"#\">\n                                <div>\n                                    <strong>John Smith</strong>\n                                    <span class=\"pull-right text-muted\">\n                                            <em>Yesterday</em>\n                                        </span>\n                                </div>\n                                <div>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque eleifend...</div>\n                            </a>\n                        </li>\n                        <li class=\"divider\"></li>\n                        <li>\n                            <a href=\"#\">\n                                <div>\n                                    <strong>John Smith</strong>\n                                    <span class=\"pull-right text-muted\">\n                                            <em>Yesterday</em>\n                                        </span>\n                                </div>\n                                <div>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque eleifend...</div>\n                            </a>\n                        </li>\n                        <li class=\"divider\"></li>\n                        <li>\n                            <a class=\"text-center\" href=\"#\">\n                                <strong>Read All Messages</strong>\n                                <i class=\"fa fa-angle-right\"></i>\n                            </a>\n                        </li>\n                    </ul>\n                    <!-- /.dropdown-messages -->\n                </li>\n                <!-- /.dropdown -->\n                <li class=\"dropdown\">\n                    <a class=\"dropdown-toggle\" data-toggle=\"dropdown\" href=\"#\">\n                        <i class=\"fa fa-tasks fa-fw\"></i> <i class=\"fa fa-caret-down\"></i>\n                    </a>\n                    <ul class=\"dropdown-menu dropdown-tasks\">\n                        <li>\n                            <a href=\"#\">\n                                <div>\n                                    <p>\n                                        <strong>Task 1</strong>\n                                        <span class=\"pull-right text-muted\">40% Complete</span>\n                                    </p>\n                                    <div class=\"progress progress-striped active\">\n                                        <div class=\"progress-bar progress-bar-success\" role=\"progressbar\" aria-valuenow=\"40\" aria-valuemin=\"0\" aria-valuemax=\"100\" style=\"width: 40%\">\n                                            <span class=\"sr-only\">40% Complete (success)</span>\n                                        </div>\n                                    </div>\n                                </div>\n                            </a>\n                        </li>\n                        <li class=\"divider\"></li>\n                        <li>\n                            <a href=\"#\">\n                                <div>\n                                    <p>\n                                        <strong>Task 2</strong>\n                                        <span class=\"pull-right text-muted\">20% Complete</span>\n                                    </p>\n                                    <div class=\"progress progress-striped active\">\n                                        <div class=\"progress-bar progress-bar-info\" role=\"progressbar\" aria-valuenow=\"20\" aria-valuemin=\"0\" aria-valuemax=\"100\" style=\"width: 20%\">\n                                            <span class=\"sr-only\">20% Complete</span>\n                                        </div>\n                                    </div>\n                                </div>\n                            </a>\n                        </li>\n                        <li class=\"divider\"></li>\n                        <li>\n                            <a href=\"#\">\n                                <div>\n                                    <p>\n                                        <strong>Task 3</strong>\n                                        <span class=\"pull-right text-muted\">60% Complete</span>\n                                    </p>\n                                    <div class=\"progress progress-striped active\">\n                                        <div class=\"progress-bar progress-bar-warning\" role=\"progressbar\" aria-valuenow=\"60\" aria-valuemin=\"0\" aria-valuemax=\"100\" style=\"width: 60%\">\n                                            <span class=\"sr-only\">60% Complete (warning)</span>\n                                        </div>\n                                    </div>\n                                </div>\n                            </a>\n                        </li>\n                        <li class=\"divider\"></li>\n                        <li>\n                            <a href=\"#\">\n                                <div>\n                                    <p>\n                                        <strong>Task 4</strong>\n                                        <span class=\"pull-right text-muted\">80% Complete</span>\n                                    </p>\n                                    <div class=\"progress progress-striped active\">\n                                        <div class=\"progress-bar progress-bar-danger\" role=\"progressbar\" aria-valuenow=\"80\" aria-valuemin=\"0\" aria-valuemax=\"100\" style=\"width: 80%\">\n                                            <span class=\"sr-only\">80% Complete (danger)</span>\n                                        </div>\n                                    </div>\n                                </div>\n                            </a>\n                        </li>\n                        <li class=\"divider\"></li>\n                        <li>\n                            <a class=\"text-center\" href=\"#\">\n                                <strong>See All Tasks</strong>\n                                <i class=\"fa fa-angle-right\"></i>\n                            </a>\n                        </li>\n                    </ul>\n                    <!-- /.dropdown-tasks -->\n                </li>\n                <!-- /.dropdown -->\n                <li class=\"dropdown\">\n                    <a class=\"dropdown-toggle\" data-toggle=\"dropdown\" href=\"#\">\n                        <i class=\"fa fa-bell fa-fw\"></i> <i class=\"fa fa-caret-down\"></i>\n                    </a>\n                    <ul class=\"dropdown-menu dropdown-alerts\">\n                        <li>\n                            <a href=\"#\">\n                                <div>\n                                    <i class=\"fa fa-comment fa-fw\"></i> New Comment\n                                    <span class=\"pull-right text-muted small\">4 minutes ago</span>\n                                </div>\n                            </a>\n                        </li>\n                        <li class=\"divider\"></li>\n                        <li>\n                            <a href=\"#\">\n                                <div>\n                                    <i class=\"fa fa-twitter fa-fw\"></i> 3 New Followers\n                                    <span class=\"pull-right text-muted small\">12 minutes ago</span>\n                                </div>\n                            </a>\n                        </li>\n                        <li class=\"divider\"></li>\n                        <li>\n                            <a href=\"#\">\n                                <div>\n                                    <i class=\"fa fa-envelope fa-fw\"></i> Message Sent\n                                    <span class=\"pull-right text-muted small\">4 minutes ago</span>\n                                </div>\n                            </a>\n                        </li>\n                        <li class=\"divider\"></li>\n                        <li>\n                            <a href=\"#\">\n                                <div>\n                                    <i class=\"fa fa-tasks fa-fw\"></i> New Task\n                                    <span class=\"pull-right text-muted small\">4 minutes ago</span>\n                                </div>\n                            </a>\n                        </li>\n                        <li class=\"divider\"></li>\n                        <li>\n                            <a href=\"#\">\n                                <div>\n                                    <i class=\"fa fa-upload fa-fw\"></i> Server Rebooted\n                                    <span class=\"pull-right text-muted small\">4 minutes ago</span>\n                                </div>\n                            </a>\n                        </li>\n                        <li class=\"divider\"></li>\n                        <li>\n                            <a class=\"text-center\" href=\"#\">\n                                <strong>See All Alerts</strong>\n                                <i class=\"fa fa-angle-right\"></i>\n                            </a>\n                        </li>\n                    </ul>\n                    <!-- /.dropdown-alerts -->\n                </li>\n                <!-- /.dropdown -->\n                <li class=\"dropdown\">\n                    <a class=\"dropdown-toggle\" data-toggle=\"dropdown\" href=\"#\">\n                        <i class=\"fa fa-user fa-fw\"></i> <i class=\"fa fa-caret-down\"></i>\n                    </a>\n                    <ul class=\"dropdown-menu dropdown-user\">\n                        <li><a href=\"#\"><i class=\"fa fa-user fa-fw\"></i> User Profile</a>\n                        </li>\n                        <li><a href=\"#\"><i class=\"fa fa-gear fa-fw\"></i> Settings</a>\n                        </li>\n                        <li class=\"divider\"></li>\n                        <li><a href=\"login.html\"><i class=\"fa fa-sign-out fa-fw\"></i> Logout</a>\n                        </li>\n                    </ul>\n                    <!-- /.dropdown-user -->\n                </li>\n                <!-- /.dropdown -->\n            </ul>\n            <!-- /.navbar-top-links -->\n\n            <div class=\"navbar-default sidebar\" role=\"navigation\">\n                <div class=\"sidebar-nav navbar-collapse\">\n                    <ul class=\"nav\" id=\"side-menu\">\n                        <li class=\"sidebar-search\">\n                            <div class=\"input-group custom-search-form\">\n                                <input type=\"text\" class=\"form-control\" placeholder=\"Search...\">\n                                <span class=\"input-group-btn\">\n                                    <button class=\"btn btn-default\" type=\"button\">\n                                        <i class=\"fa fa-search\"></i>\n                                    </button>\n                                </span>\n                            </div>\n                            <!-- /input-group -->\n                        </li>\n                        <li>\n                            <a href=\"index.html\"><i class=\"fa fa-dashboard fa-fw\"></i> Dashboard</a>\n                        </li>\n                        <li>\n                            <a href=\"#\"><i class=\"fa fa-bar-chart-o fa-fw\"></i> Charts<span class=\"fa arrow\"></span></a>\n                            <ul class=\"nav nav-second-level\">\n                                <li>\n                                    <a href=\"flot.html\">Flot Charts</a>\n                                </li>\n                                <li>\n                                    <a href=\"morris.html\">Morris.js Charts</a>\n                                </li>\n                            </ul>\n                            <!-- /.nav-second-level -->\n                        </li>\n                        <li>\n                            <a href=\"tables.html\"><i class=\"fa fa-table fa-fw\"></i> Tables</a>\n                        </li>\n                        <li>\n                            <a href=\"forms.html\"><i class=\"fa fa-edit fa-fw\"></i> Forms</a>\n                        </li>\n                        <li>\n                            <a href=\"#\"><i class=\"fa fa-wrench fa-fw\"></i> UI Elements<span class=\"fa arrow\"></span></a>\n                            <ul class=\"nav nav-second-level\">\n                                <li>\n                                    <a href=\"panels-wells.html\">Panels and Wells</a>\n                                </li>\n                                <li>\n                                    <a href=\"buttons.html\">Buttons</a>\n                                </li>\n                                <li>\n                                    <a href=\"notifications.html\">Notifications</a>\n                                </li>\n                                <li>\n                                    <a href=\"typography.html\">Typography</a>\n                                </li>\n                                <li>\n                                    <a href=\"icons.html\"> Icons</a>\n                                </li>\n                                <li>\n                                    <a href=\"grid.html\">Grid</a>\n                                </li>\n                            </ul>\n                            <!-- /.nav-second-level -->\n                        </li>\n                        <li>\n                            <a href=\"#\"><i class=\"fa fa-sitemap fa-fw\"></i> Multi-Level Dropdown<span class=\"fa arrow\"></span></a>\n                            <ul class=\"nav nav-second-level\">\n                                <li>\n                                    <a href=\"#\">Second Level Item</a>\n                                </li>\n                                <li>\n                                    <a href=\"#\">Second Level Item</a>\n                                </li>\n                                <li>\n                                    <a href=\"#\">Third Level <span class=\"fa arrow\"></span></a>\n                                    <ul class=\"nav nav-third-level\">\n                                        <li>\n                                            <a href=\"#\">Third Level Item</a>\n                                        </li>\n                                        <li>\n                                            <a href=\"#\">Third Level Item</a>\n                                        </li>\n                                        <li>\n                                            <a href=\"#\">Third Level Item</a>\n                                        </li>\n                                        <li>\n                                            <a href=\"#\">Third Level Item</a>\n                                        </li>\n                                    </ul>\n                                    <!-- /.nav-third-level -->\n                                </li>\n                            </ul>\n                            <!-- /.nav-second-level -->\n                        </li>\n                        <li>\n                            <a href=\"#\"><i class=\"fa fa-files-o fa-fw\"></i> Sample Pages<span class=\"fa arrow\"></span></a>\n                            <ul class=\"nav nav-second-level\">\n                                <li>\n                                    <a href=\"blank.html\">Blank Page</a>\n                                </li>\n                                <li>\n                                    <a href=\"login.html\">Login Page</a>\n                                </li>\n                            </ul>\n                            <!-- /.nav-second-level -->\n                        </li>\n                    </ul>\n                </div>\n                <!-- /.sidebar-collapse -->\n            </div>\n            <!-- /.navbar-static-side -->\n        </nav>\n\n        <div id=\"page-wrapper\">\n            <div class=\"row\">\n                <div class=\"col-lg-12\">\n                    <h1 class=\"page-header\">Icons</h1>\n                </div>\n                <!-- /.col-lg-12 -->\n            </div>\n            <!-- /.row -->\n            <div class=\"row\">\n                <div class=\"col-lg-12\">\n                    <div class=\"panel panel-default\">\n                        <div class=\"panel-heading\">\n                            All available icons (font-awesome)\n                        </div>\n                        <div class=\"panel-body\">\n                            <div class=\"row\">\n                                <div class=\"fa col-lg-3\">\n                                    <p class=\"fa fa-glass\"> fa-glass </p>\n                                    <br/>\n                                    <p class=\"fa fa-music\"> fa-music </p>\n                                    <br/>\n                                    <p class=\"fa fa-search\"> fa-search </p>\n                                    <br/>\n                                    <p class=\"fa fa-envelope-o\"> fa-envelope-o </p>\n                                    <br/>\n                                    <p class=\"fa fa-heart\"> fa-heart </p>\n                                    <br/>\n                                    <p class=\"fa fa-star\"> fa-star </p>\n                                    <br/>\n                                    <p class=\"fa fa-star-o\"> fa-star-o </p>\n                                    <br/>\n                                    <p class=\"fa fa-user\"> fa-user </p>\n                                    <br/>\n                                    <p class=\"fa fa-film\"> fa-film </p>\n                                    <br/>\n                                    <p class=\"fa fa-th-large\"> fa-th-large </p>\n                                    <br/>\n                                    <p class=\"fa fa-th\"> fa-th </p>\n                                    <br/>\n                                    <p class=\"fa fa-th-list\"> fa-th-list </p>\n                                    <br/>\n                                    <p class=\"fa fa-check\"> fa-check </p>\n                                    <br/>\n                                    <p class=\"fa fa-times\"> fa-times </p>\n                                    <br/>\n                                    <p class=\"fa fa-search-plus\"> fa-search-plus </p>\n                                    <br/>\n                                    <p class=\"fa fa-search-minus\"> fa-search-minus </p>\n                                    <br/>\n                                    <p class=\"fa fa-power-off\"> fa-power-off </p>\n                                    <br/>\n                                    <p class=\"fa fa-signal\"> fa-signal </p>\n                                    <br/>\n                                    <p class=\"fa fa-gear\"> fa-gear </p>\n                                    <br/>\n                                    <p class=\"fa fa-cog\"> fa-cog </p>\n                                    <br/>\n                                    <p class=\"fa fa-trash-o\"> fa-trash-o </p>\n                                    <br/>\n                                    <p class=\"fa fa-home\"> fa-home </p>\n                                    <br/>\n                                    <p class=\"fa fa-file-o\"> fa-file-o </p>\n                                    <br/>\n                                    <p class=\"fa fa-clock-o\"> fa-clock-o </p>\n                                    <br/>\n                                    <p class=\"fa fa-road\"> fa-road </p>\n                                    <br/>\n                                    <p class=\"fa fa-download\"> fa-download </p>\n                                    <br/>\n                                    <p class=\"fa fa-arrow-circle-o-down\"> fa-arrow-circle-o-down </p>\n                                    <br/>\n                                    <p class=\"fa fa-arrow-circle-o-up\"> fa-arrow-circle-o-up </p>\n                                    <br/>\n                                    <p class=\"fa fa-inbox\"> fa-inbox </p>\n                                    <br/>\n                                    <p class=\"fa fa-play-circle-o\"> fa-play-circle-o </p>\n                                    <br/>\n                                    <p class=\"fa fa-rotate-right\"> fa-rotate-right </p>\n                                    <br/>\n                                    <p class=\"fa fa-repeat\"> fa-repeat </p>\n                                    <br/>\n                                    <p class=\"fa fa-refresh\"> fa-refresh </p>\n                                    <br/>\n                                    <p class=\"fa fa-list-alt\"> fa-list-alt </p>\n                                    <br/>\n                                    <p class=\"fa fa-lock\"> fa-lock </p>\n                                    <br/>\n                                    <p class=\"fa fa-flag\"> fa-flag </p>\n                                    <br/>\n                                    <p class=\"fa fa-headphones\"> fa-headphones </p>\n                                    <br/>\n                                    <p class=\"fa fa-volume-off\"> fa-volume-off </p>\n                                    <br/>\n                                    <p class=\"fa fa-volume-down\"> fa-volume-down </p>\n                                    <br/>\n                                    <p class=\"fa fa-volume-up\"> fa-volume-up </p>\n                                    <br/>\n                                    <p class=\"fa fa-qrcode\"> fa-qrcode </p>\n                                    <br/>\n                                    <p class=\"fa fa-barcode\"> fa-barcode </p>\n                                    <br/>\n                                    <p class=\"fa fa-tag\"> fa-tag </p>\n                                    <br/>\n                                    <p class=\"fa fa-tags\"> fa-tags </p>\n                                    <br/>\n                                    <p class=\"fa fa-book\"> fa-book </p>\n                                    <br/>\n                                    <p class=\"fa fa-bookmark\"> fa-bookmark </p>\n                                    <br/>\n                                    <p class=\"fa fa-print\"> fa-print </p>\n                                    <br/>\n                                    <p class=\"fa fa-camera\"> fa-camera </p>\n                                    <br/>\n                                    <p class=\"fa fa-font\"> fa-font </p>\n                                    <br/>\n                                    <p class=\"fa fa-bold\"> fa-bold </p>\n                                    <br/>\n                                    <p class=\"fa fa-italic\"> fa-italic </p>\n                                    <br/>\n                                    <p class=\"fa fa-text-height\"> fa-text-height </p>\n                                    <br/>\n                                    <p class=\"fa fa-text-width\"> fa-text-width </p>\n                                    <br/>\n                                    <p class=\"fa fa-align-left\"> fa-align-left </p>\n                                    <br/>\n                                    <p class=\"fa fa-align-center\"> fa-align-center </p>\n                                    <br/>\n                                    <p class=\"fa fa-align-right\"> fa-align-right </p>\n                                    <br/>\n                                    <p class=\"fa fa-align-justify\"> fa-align-justify </p>\n                                    <br/>\n                                    <p class=\"fa fa-list\"> fa-list </p>\n                                    <br/>\n                                    <p class=\"fa fa-dedent\"> fa-dedent </p>\n                                    <br/>\n                                    <p class=\"fa fa-outdent\"> fa-outdent </p>\n                                    <br/>\n                                    <p class=\"fa fa-indent\"> fa-indent </p>\n                                    <br/>\n                                    <p class=\"fa fa-video-camera\"> fa-video-camera </p>\n                                    <br/>\n                                    <p class=\"fa fa-photo\"> fa-photo </p>\n                                    <br/>\n                                    <p class=\"fa fa-image\"> fa-image </p>\n                                    <br/>\n                                    <p class=\"fa fa-picture-o\"> fa-picture-o </p>\n                                    <br/>\n                                    <p class=\"fa fa-pencil\"> fa-pencil </p>\n                                    <br/>\n                                    <p class=\"fa fa-map-marker\"> fa-map-marker </p>\n                                    <br/>\n                                    <p class=\"fa fa-adjust\"> fa-adjust </p>\n                                    <br/>\n                                    <p class=\"fa fa-tint\"> fa-tint </p>\n                                    <br/>\n                                    <p class=\"fa fa-edit\"> fa-edit </p>\n                                    <br/>\n                                    <p class=\"fa fa-pencil-square-o\"> fa-pencil-square-o </p>\n                                    <br/>\n                                    <p class=\"fa fa-share-square-o\"> fa-share-square-o </p>\n                                    <br/>\n                                    <p class=\"fa fa-check-square-o\"> fa-check-square-o </p>\n                                    <br/>\n                                    <p class=\"fa fa-arrows\"> fa-arrows </p>\n                                    <br/>\n                                    <p class=\"fa fa-step-backward\"> fa-step-backward </p>\n                                    <br/>\n                                    <p class=\"fa fa-fast-backward\"> fa-fast-backward </p>\n                                    <br/>\n                                    <p class=\"fa fa-backward\"> fa-backward </p>\n                                    <br/>\n                                    <p class=\"fa fa-play\"> fa-play </p>\n                                    <br/>\n                                    <p class=\"fa fa-pause\"> fa-pause </p>\n                                    <br/>\n                                    <p class=\"fa fa-stop\"> fa-stop </p>\n                                    <br/>\n                                    <p class=\"fa fa-forward\"> fa-forward </p>\n                                    <br/>\n                                    <p class=\"fa fa-fast-forward\"> fa-fast-forward </p>\n                                    <br/>\n                                    <p class=\"fa fa-step-forward\"> fa-step-forward </p>\n                                    <br/>\n                                    <p class=\"fa fa-eject\"> fa-eject </p>\n                                    <br/>\n                                    <p class=\"fa fa-chevron-left\"> fa-chevron-left </p>\n                                    <br/>\n                                    <p class=\"fa fa-chevron-right\"> fa-chevron-right </p>\n                                    <br/>\n                                    <p class=\"fa fa-plus-circle\"> fa-plus-circle </p>\n                                    <br/>\n                                    <p class=\"fa fa-minus-circle\"> fa-minus-circle </p>\n                                    <br/>\n                                    <p class=\"fa fa-times-circle\"> fa-times-circle </p>\n                                    <br/>\n                                    <p class=\"fa fa-check-circle\"> fa-check-circle </p>\n                                    <br/>\n                                    <p class=\"fa fa-question-circle\"> fa-question-circle </p>\n                                    <br/>\n                                    <p class=\"fa fa-info-circle\"> fa-info-circle </p>\n                                    <br/>\n                                    <p class=\"fa fa-crosshairs\"> fa-crosshairs </p>\n                                    <br/>\n                                    <p class=\"fa fa-times-circle-o\"> fa-times-circle-o </p>\n                                    <br/>\n                                    <p class=\"fa fa-check-circle-o\"> fa-check-circle-o </p>\n                                    <br/>\n                                    <p class=\"fa fa-ban\"> fa-ban </p>\n                                    <br/>\n                                    <p class=\"fa fa-arrow-left\"> fa-arrow-left </p>\n                                    <br/>\n                                    <p class=\"fa fa-arrow-right\"> fa-arrow-right </p>\n                                    <br/>\n                                    <p class=\"fa fa-arrow-up\"> fa-arrow-up </p>\n                                    <br/>\n                                    <p class=\"fa fa-arrow-down\"> fa-arrow-down </p>\n                                    <br/>\n                                    <p class=\"fa fa-mail-forward\"> fa-mail-forward </p>\n                                    <br/>\n                                    <p class=\"fa fa-share\"> fa-share </p>\n                                    <br/>\n                                    <p class=\"fa fa-expand\"> fa-expand </p>\n                                    <br/>\n                                    <p class=\"fa fa-compress\"> fa-compress </p>\n                                    <br/>\n                                    <p class=\"fa fa-plus\"> fa-plus </p>\n                                    <br/>\n                                    <p class=\"fa fa-minus\"> fa-minus </p>\n                                    <br/>\n                                    <p class=\"fa fa-asterisk\"> fa-asterisk </p>\n                                    <br/>\n                                    <p class=\"fa fa-exclamation-circle\"> fa-exclamation-circle </p>\n                                    <br/>\n                                    <p class=\"fa fa-gift\"> fa-gift </p>\n                                    <br/>\n                                    <p class=\"fa fa-leaf\"> fa-leaf </p>\n                                    <br/>\n                                    <p class=\"fa fa-fire\"> fa-fire </p>\n                                    <br/>\n                                    <p class=\"fa fa-eye\"> fa-eye </p>\n                                    <br/>\n                                    <p class=\"fa fa-eye-slash\"> fa-eye-slash </p>\n                                    <br/>\n                                    <p class=\"fa fa-warning\"> fa-warning </p>\n                                    <br/>\n                                    <p class=\"fa fa-exclamation-triangle\"> fa-exclamation-triangle </p>\n                                    <br/>\n                                    <p class=\"fa fa-plane\"> fa-plane </p>\n                                    <br/>\n                                    <p class=\"fa fa-calendar\"> fa-calendar </p>\n                                    <br/>\n                                    <p class=\"fa fa-random\"> fa-random </p>\n                                    <br/>\n                                    <p class=\"fa fa-comment\"> fa-comment </p>\n                                    <br/>\n                                    <p class=\"fa fa-magnet\"> fa-magnet </p>\n                                    <br/>\n                                    <p class=\"fa fa-chevron-up\"> fa-chevron-up </p>\n                                    <br/>\n                                    <p class=\"fa fa-chevron-down\"> fa-chevron-down </p>\n                                    <br/>\n                                    <p class=\"fa fa-retweet\"> fa-retweet </p>\n                                    <br/>\n                                    <p class=\"fa fa-shopping-cart\"> fa-shopping-cart </p>\n                                    <br/>\n                                    <p class=\"fa fa-folder\"> fa-folder </p>\n                                    <br/>\n                                    <p class=\"fa fa-folder-open\"> fa-folder-open </p>\n                                    <br/>\n                                </div>\n                                <!-- /.col-lg-6 (nested) -->\n                                <div class=\"fa col-lg-3\">\n                                    <p class=\"fa fa-arrows-v\"> fa-arrows-v </p>\n                                    <br/>\n                                    <p class=\"fa fa-arrows-h\"> fa-arrows-h </p>\n                                    <br/>\n                                    <p class=\"fa fa-bar-chart-o\"> fa-bar-chart-o </p>\n                                    <br/>\n                                    <p class=\"fa fa-twitter-square\"> fa-twitter-square </p>\n                                    <br/>\n                                    <p class=\"fa fa-facebook-square\"> fa-facebook-square </p>\n                                    <br/>\n                                    <p class=\"fa fa-camera-retro\"> fa-camera-retro </p>\n                                    <br/>\n                                    <p class=\"fa fa-key\"> fa-key </p>\n                                    <br/>\n                                    <p class=\"fa fa-gears\"> fa-gears </p>\n                                    <br/>\n                                    <p class=\"fa fa-cogs\"> fa-cogs </p>\n                                    <br/>\n                                    <p class=\"fa fa-comments\"> fa-comments </p>\n                                    <br/>\n                                    <p class=\"fa fa-thumbs-o-up\"> fa-thumbs-o-up </p>\n                                    <br/>\n                                    <p class=\"fa fa-thumbs-o-down\"> fa-thumbs-o-down </p>\n                                    <br/>\n                                    <p class=\"fa fa-star-half\"> fa-star-half </p>\n                                    <br/>\n                                    <p class=\"fa fa-heart-o\"> fa-heart-o </p>\n                                    <br/>\n                                    <p class=\"fa fa-sign-out\"> fa-sign-out </p>\n                                    <br/>\n                                    <p class=\"fa fa-linkedin-square\"> fa-linkedin-square </p>\n                                    <br/>\n                                    <p class=\"fa fa-thumb-tack\"> fa-thumb-tack </p>\n                                    <br/>\n                                    <p class=\"fa fa-external-link\"> fa-external-link </p>\n                                    <br/>\n                                    <p class=\"fa fa-sign-in\"> fa-sign-in </p>\n                                    <br/>\n                                    <p class=\"fa fa-trophy\"> fa-trophy </p>\n                                    <br/>\n                                    <p class=\"fa fa-github-square\"> fa-github-square </p>\n                                    <br/>\n                                    <p class=\"fa fa-upload\"> fa-upload </p>\n                                    <br/>\n                                    <p class=\"fa fa-lemon-o\"> fa-lemon-o </p>\n                                    <br/>\n                                    <p class=\"fa fa-phone\"> fa-phone </p>\n                                    <br/>\n                                    <p class=\"fa fa-square-o\"> fa-square-o </p>\n                                    <br/>\n                                    <p class=\"fa fa-bookmark-o\"> fa-bookmark-o </p>\n                                    <br/>\n                                    <p class=\"fa fa-phone-square\"> fa-phone-square </p>\n                                    <br/>\n                                    <p class=\"fa fa-twitter\"> fa-twitter </p>\n                                    <br/>\n                                    <p class=\"fa fa-facebook\"> fa-facebook </p>\n                                    <br/>\n                                    <p class=\"fa fa-github\"> fa-github </p>\n                                    <br/>\n                                    <p class=\"fa fa-unlock\"> fa-unlock </p>\n                                    <br/>\n                                    <p class=\"fa fa-credit-card\"> fa-credit-card </p>\n                                    <br/>\n                                    <p class=\"fa fa-rss\"> fa-rss </p>\n                                    <br/>\n                                    <p class=\"fa fa-hdd-o\"> fa-hdd-o </p>\n                                    <br/>\n                                    <p class=\"fa fa-bullhorn\"> fa-bullhorn </p>\n                                    <br/>\n                                    <p class=\"fa fa-bell\"> fa-bell </p>\n                                    <br/>\n                                    <p class=\"fa fa-certificate\"> fa-certificate </p>\n                                    <br/>\n                                    <p class=\"fa fa-hand-o-right\"> fa-hand-o-right </p>\n                                    <br/>\n                                    <p class=\"fa fa-hand-o-left\"> fa-hand-o-left </p>\n                                    <br/>\n                                    <p class=\"fa fa-hand-o-up\"> fa-hand-o-up </p>\n                                    <br/>\n                                    <p class=\"fa fa-hand-o-down\"> fa-hand-o-down </p>\n                                    <br/>\n                                    <p class=\"fa fa-arrow-circle-left\"> fa-arrow-circle-left </p>\n                                    <br/>\n                                    <p class=\"fa fa-arrow-circle-right\"> fa-arrow-circle-right </p>\n                                    <br/>\n                                    <p class=\"fa fa-arrow-circle-up\"> fa-arrow-circle-up </p>\n                                    <br/>\n                                    <p class=\"fa fa-arrow-circle-down\"> fa-arrow-circle-down </p>\n                                    <br/>\n                                    <p class=\"fa fa-globe\"> fa-globe </p>\n                                    <br/>\n                                    <p class=\"fa fa-wrench\"> fa-wrench </p>\n                                    <br/>\n                                    <p class=\"fa fa-tasks\"> fa-tasks </p>\n                                    <br/>\n                                    <p class=\"fa fa-filter\"> fa-filter </p>\n                                    <br/>\n                                    <p class=\"fa fa-briefcase\"> fa-briefcase </p>\n                                    <br/>\n                                    <p class=\"fa fa-arrows-alt\"> fa-arrows-alt </p>\n                                    <br/>\n                                    <p class=\"fa fa-group\"> fa-group </p>\n                                    <br/>\n                                    <p class=\"fa fa-users\"> fa-users </p>\n                                    <br/>\n                                    <p class=\"fa fa-chain\"> fa-chain </p>\n                                    <br/>\n                                    <p class=\"fa fa-link\"> fa-link </p>\n                                    <br/>\n                                    <p class=\"fa fa-cloud\"> fa-cloud </p>\n                                    <br/>\n                                    <p class=\"fa fa-flask\"> fa-flask </p>\n                                    <br/>\n                                    <p class=\"fa fa-cut\"> fa-cut </p>\n                                    <br/>\n                                    <p class=\"fa fa-scissors\"> fa-scissors </p>\n                                    <br/>\n                                    <p class=\"fa fa-copy\"> fa-copy </p>\n                                    <br/>\n                                    <p class=\"fa fa-files-o\"> fa-files-o </p>\n                                    <br/>\n                                    <p class=\"fa fa-paperclip\"> fa-paperclip </p>\n                                    <br/>\n                                    <p class=\"fa fa-save\"> fa-save </p>\n                                    <br/>\n                                    <p class=\"fa fa-floppy-o\"> fa-floppy-o </p>\n                                    <br/>\n                                    <p class=\"fa fa-square\"> fa-square </p>\n                                    <br/>\n                                    <p class=\"fa fa-navicon\"> fa-navicon </p>\n                                    <br/>\n                                    <p class=\"fa fa-reorder\"> fa-reorder </p>\n                                    <br/>\n                                    <p class=\"fa fa-bars\"> fa-bars </p>\n                                    <br/>\n                                    <p class=\"fa fa-list-ul\"> fa-list-ul </p>\n                                    <br/>\n                                    <p class=\"fa fa-list-ol\"> fa-list-ol </p>\n                                    <br/>\n                                    <p class=\"fa fa-strikethrough\"> fa-strikethrough </p>\n                                    <br/>\n                                    <p class=\"fa fa-underline\"> fa-underline </p>\n                                    <br/>\n                                    <p class=\"fa fa-table\"> fa-table </p>\n                                    <br/>\n                                    <p class=\"fa fa-magic\"> fa-magic </p>\n                                    <br/>\n                                    <p class=\"fa fa-truck\"> fa-truck </p>\n                                    <br/>\n                                    <p class=\"fa fa-pinterest\"> fa-pinterest </p>\n                                    <br/>\n                                    <p class=\"fa fa-pinterest-square\"> fa-pinterest-square </p>\n                                    <br/>\n                                    <p class=\"fa fa-google-plus-square\"> fa-google-plus-square </p>\n                                    <br/>\n                                    <p class=\"fa fa-google-plus\"> fa-google-plus </p>\n                                    <br/>\n                                    <p class=\"fa fa-money\"> fa-money </p>\n                                    <br/>\n                                    <p class=\"fa fa-caret-down\"> fa-caret-down </p>\n                                    <br/>\n                                    <p class=\"fa fa-caret-up\"> fa-caret-up </p>\n                                    <br/>\n                                    <p class=\"fa fa-caret-left\"> fa-caret-left </p>\n                                    <br/>\n                                    <p class=\"fa fa-caret-right\"> fa-caret-right </p>\n                                    <br/>\n                                    <p class=\"fa fa-columns\"> fa-columns </p>\n                                    <br/>\n                                    <p class=\"fa fa-unsorted\"> fa-unsorted </p>\n                                    <br/>\n                                    <p class=\"fa fa-sort\"> fa-sort </p>\n                                    <br/>\n                                    <p class=\"fa fa-sort-down\"> fa-sort-down </p>\n                                    <br/>\n                                    <p class=\"fa fa-sort-desc\"> fa-sort-desc </p>\n                                    <br/>\n                                    <p class=\"fa fa-sort-up\"> fa-sort-up </p>\n                                    <br/>\n                                    <p class=\"fa fa-sort-asc\"> fa-sort-asc </p>\n                                    <br/>\n                                    <p class=\"fa fa-envelope\"> fa-envelope </p>\n                                    <br/>\n                                    <p class=\"fa fa-linkedin\"> fa-linkedin </p>\n                                    <br/>\n                                    <p class=\"fa fa-rotate-left\"> fa-rotate-left </p>\n                                    <br/>\n                                    <p class=\"fa fa-undo\"> fa-undo </p>\n                                    <br/>\n                                    <p class=\"fa fa-legal\"> fa-legal </p>\n                                    <br/>\n                                    <p class=\"fa fa-gavel\"> fa-gavel </p>\n                                    <br/>\n                                    <p class=\"fa fa-dashboard\"> fa-dashboard </p>\n                                    <br/>\n                                    <p class=\"fa fa-tachometer\"> fa-tachometer </p>\n                                    <br/>\n                                    <p class=\"fa fa-comment-o\"> fa-comment-o </p>\n                                    <br/>\n                                    <p class=\"fa fa-comments-o\"> fa-comments-o </p>\n                                    <br/>\n                                    <p class=\"fa fa-flash\"> fa-flash </p>\n                                    <br/>\n                                    <p class=\"fa fa-bolt\"> fa-bolt </p>\n                                    <br/>\n                                    <p class=\"fa fa-sitemap\"> fa-sitemap </p>\n                                    <br/>\n                                    <p class=\"fa fa-umbrella\"> fa-umbrella </p>\n                                    <br/>\n                                    <p class=\"fa fa-paste\"> fa-paste </p>\n                                    <br/>\n                                    <p class=\"fa fa-clipboard\"> fa-clipboard </p>\n                                    <br/>\n                                    <p class=\"fa fa-lightbulb-o\"> fa-lightbulb-o </p>\n                                    <br/>\n                                    <p class=\"fa fa-exchange\"> fa-exchange </p>\n                                    <br/>\n                                    <p class=\"fa fa-cloud-download\"> fa-cloud-download </p>\n                                    <br/>\n                                    <p class=\"fa fa-cloud-upload\"> fa-cloud-upload </p>\n                                    <br/>\n                                    <p class=\"fa fa-user-md\"> fa-user-md </p>\n                                    <br/>\n                                    <p class=\"fa fa-stethoscope\"> fa-stethoscope </p>\n                                    <br/>\n                                    <p class=\"fa fa-suitcase\"> fa-suitcase </p>\n                                    <br/>\n                                    <p class=\"fa fa-bell-o\"> fa-bell-o </p>\n                                    <br/>\n                                    <p class=\"fa fa-coffee\"> fa-coffee </p>\n                                    <br/>\n                                    <p class=\"fa fa-cutlery\"> fa-cutlery </p>\n                                    <br/>\n                                    <p class=\"fa fa-file-text-o\"> fa-file-text-o </p>\n                                    <br/>\n                                    <p class=\"fa fa-building-o\"> fa-building-o </p>\n                                    <br/>\n                                    <p class=\"fa fa-hospital-o\"> fa-hospital-o </p>\n                                    <br/>\n                                    <p class=\"fa fa-ambulance\"> fa-ambulance </p>\n                                    <br/>\n                                    <p class=\"fa fa-medkit\"> fa-medkit </p>\n                                    <br/>\n                                    <p class=\"fa fa-fighter-jet\"> fa-fighter-jet </p>\n                                    <br/>\n                                    <p class=\"fa fa-beer\"> fa-beer </p>\n                                    <br/>\n                                    <p class=\"fa fa-h-square\"> fa-h-square </p>\n                                    <br/>\n                                    <p class=\"fa fa-plus-square\"> fa-plus-square </p>\n                                    <br/>\n                                </div>\n                                <div class=\"fa col-lg-3\">\n                                    <p class=\"fa fa-angle-double-left\"> fa-angle-double-left </p>\n                                    <br/>\n                                    <p class=\"fa fa-angle-double-right\"> fa-angle-double-right </p>\n                                    <br/>\n                                    <p class=\"fa fa-angle-double-up\"> fa-angle-double-up </p>\n                                    <br/>\n                                    <p class=\"fa fa-angle-double-down\"> fa-angle-double-down </p>\n                                    <br/>\n                                    <p class=\"fa fa-angle-left\"> fa-angle-left </p>\n                                    <br/>\n                                    <p class=\"fa fa-angle-right\"> fa-angle-right </p>\n                                    <br/>\n                                    <p class=\"fa fa-angle-up\"> fa-angle-up </p>\n                                    <br/>\n                                    <p class=\"fa fa-angle-down\"> fa-angle-down </p>\n                                    <br/>\n                                    <p class=\"fa fa-desktop\"> fa-desktop </p>\n                                    <br/>\n                                    <p class=\"fa fa-laptop\"> fa-laptop </p>\n                                    <br/>\n                                    <p class=\"fa fa-tablet\"> fa-tablet </p>\n                                    <br/>\n                                    <p class=\"fa fa-mobile-phone\"> fa-mobile-phone </p>\n                                    <br/>\n                                    <p class=\"fa fa-mobile\"> fa-mobile </p>\n                                    <br/>\n                                    <p class=\"fa fa-circle-o\"> fa-circle-o </p>\n                                    <br/>\n                                    <p class=\"fa fa-quote-left\"> fa-quote-left </p>\n                                    <br/>\n                                    <p class=\"fa fa-quote-right\"> fa-quote-right </p>\n                                    <br/>\n                                    <p class=\"fa fa-spinner\"> fa-spinner </p>\n                                    <br/>\n                                    <p class=\"fa fa-circle\"> fa-circle </p>\n                                    <br/>\n                                    <p class=\"fa fa-mail-reply\"> fa-mail-reply </p>\n                                    <br/>\n                                    <p class=\"fa fa-reply\"> fa-reply </p>\n                                    <br/>\n                                    <p class=\"fa fa-github-alt\"> fa-github-alt </p>\n                                    <br/>\n                                    <p class=\"fa fa-folder-o\"> fa-folder-o </p>\n                                    <br/>\n                                    <p class=\"fa fa-folder-open-o\"> fa-folder-open-o </p>\n                                    <br/>\n                                    <p class=\"fa fa-smile-o\"> fa-smile-o </p>\n                                    <br/>\n                                    <p class=\"fa fa-frown-o\"> fa-frown-o </p>\n                                    <br/>\n                                    <p class=\"fa fa-meh-o\"> fa-meh-o </p>\n                                    <br/>\n                                    <p class=\"fa fa-gamepad\"> fa-gamepad </p>\n                                    <br/>\n                                    <p class=\"fa fa-keyboard-o\"> fa-keyboard-o </p>\n                                    <br/>\n                                    <p class=\"fa fa-flag-o\"> fa-flag-o </p>\n                                    <br/>\n                                    <p class=\"fa fa-flag-checkered\"> fa-flag-checkered </p>\n                                    <br/>\n                                    <p class=\"fa fa-terminal\"> fa-terminal </p>\n                                    <br/>\n                                    <p class=\"fa fa-code\"> fa-code </p>\n                                    <br/>\n                                    <p class=\"fa fa-mail-reply-all\"> fa-mail-reply-all </p>\n                                    <br/>\n                                    <p class=\"fa fa-reply-all\"> fa-reply-all </p>\n                                    <br/>\n                                    <p class=\"fa fa-star-half-empty\"> fa-star-half-empty </p>\n                                    <br/>\n                                    <p class=\"fa fa-star-half-full\"> fa-star-half-full </p>\n                                    <br/>\n                                    <p class=\"fa fa-star-half-o\"> fa-star-half-o </p>\n                                    <br/>\n                                    <p class=\"fa fa-location-arrow\"> fa-location-arrow </p>\n                                    <br/>\n                                    <p class=\"fa fa-crop\"> fa-crop </p>\n                                    <br/>\n                                    <p class=\"fa fa-code-fork\"> fa-code-fork </p>\n                                    <br/>\n                                    <p class=\"fa fa-unlink\"> fa-unlink </p>\n                                    <br/>\n                                    <p class=\"fa fa-chain-broken\"> fa-chain-broken </p>\n                                    <br/>\n                                    <p class=\"fa fa-question\"> fa-question </p>\n                                    <br/>\n                                    <p class=\"fa fa-info\"> fa-info </p>\n                                    <br/>\n                                    <p class=\"fa fa-exclamation\"> fa-exclamation </p>\n                                    <br/>\n                                    <p class=\"fa fa-superscript\"> fa-superscript </p>\n                                    <br/>\n                                    <p class=\"fa fa-subscript\"> fa-subscript </p>\n                                    <br/>\n                                    <p class=\"fa fa-eraser\"> fa-eraser </p>\n                                    <br/>\n                                    <p class=\"fa fa-puzzle-piece\"> fa-puzzle-piece </p>\n                                    <br/>\n                                    <p class=\"fa fa-microphone\"> fa-microphone </p>\n                                    <br/>\n                                    <p class=\"fa fa-microphone-slash\"> fa-microphone-slash </p>\n                                    <br/>\n                                    <p class=\"fa fa-shield\"> fa-shield </p>\n                                    <br/>\n                                    <p class=\"fa fa-calendar-o\"> fa-calendar-o </p>\n                                    <br/>\n                                    <p class=\"fa fa-fire-extinguisher\"> fa-fire-extinguisher </p>\n                                    <br/>\n                                    <p class=\"fa fa-rocket\"> fa-rocket </p>\n                                    <br/>\n                                    <p class=\"fa fa-maxcdn\"> fa-maxcdn </p>\n                                    <br/>\n                                    <p class=\"fa fa-chevron-circle-left\"> fa-chevron-circle-left </p>\n                                    <br/>\n                                    <p class=\"fa fa-chevron-circle-right\"> fa-chevron-circle-right </p>\n                                    <br/>\n                                    <p class=\"fa fa-chevron-circle-up\"> fa-chevron-circle-up </p>\n                                    <br/>\n                                    <p class=\"fa fa-chevron-circle-down\"> fa-chevron-circle-down </p>\n                                    <br/>\n                                    <p class=\"fa fa-html5\"> fa-html5 </p>\n                                    <br/>\n                                    <p class=\"fa fa-css3\"> fa-css3 </p>\n                                    <br/>\n                                    <p class=\"fa fa-anchor\"> fa-anchor </p>\n                                    <br/>\n                                    <p class=\"fa fa-unlock-alt\"> fa-unlock-alt </p>\n                                    <br/>\n                                    <p class=\"fa fa-bullseye\"> fa-bullseye </p>\n                                    <br/>\n                                    <p class=\"fa fa-ellipsis-h\"> fa-ellipsis-h </p>\n                                    <br/>\n                                    <p class=\"fa fa-ellipsis-v\"> fa-ellipsis-v </p>\n                                    <br/>\n                                    <p class=\"fa fa-rss-square\"> fa-rss-square </p>\n                                    <br/>\n                                    <p class=\"fa fa-play-circle\"> fa-play-circle </p>\n                                    <br/>\n                                    <p class=\"fa fa-ticket\"> fa-ticket </p>\n                                    <br/>\n                                    <p class=\"fa fa-minus-square\"> fa-minus-square </p>\n                                    <br/>\n                                    <p class=\"fa fa-minus-square-o\"> fa-minus-square-o </p>\n                                    <br/>\n                                    <p class=\"fa fa-level-up\"> fa-level-up </p>\n                                    <br/>\n                                    <p class=\"fa fa-level-down\"> fa-level-down </p>\n                                    <br/>\n                                    <p class=\"fa fa-check-square\"> fa-check-square </p>\n                                    <br/>\n                                    <p class=\"fa fa-pencil-square\"> fa-pencil-square </p>\n                                    <br/>\n                                    <p class=\"fa fa-external-link-square\"> fa-external-link-square </p>\n                                    <br/>\n                                    <p class=\"fa fa-share-square\"> fa-share-square </p>\n                                    <br/>\n                                    <p class=\"fa fa-compass\"> fa-compass </p>\n                                    <br/>\n                                    <p class=\"fa fa-toggle-down\"> fa-toggle-down </p>\n                                    <br/>\n                                    <p class=\"fa fa-caret-square-o-down\"> fa-caret-square-o-down </p>\n                                    <br/>\n                                    <p class=\"fa fa-toggle-up\"> fa-toggle-up </p>\n                                    <br/>\n                                    <p class=\"fa fa-caret-square-o-up\"> fa-caret-square-o-up </p>\n                                    <br/>\n                                    <p class=\"fa fa-toggle-right\"> fa-toggle-right </p>\n                                    <br/>\n                                    <p class=\"fa fa-caret-square-o-right\"> fa-caret-square-o-right </p>\n                                    <br/>\n                                    <p class=\"fa fa-euro\"> fa-euro </p>\n                                    <br/>\n                                    <p class=\"fa fa-eur\"> fa-eur </p>\n                                    <br/>\n                                    <p class=\"fa fa-gbp\"> fa-gbp </p>\n                                    <br/>\n                                    <p class=\"fa fa-dollar\"> fa-dollar </p>\n                                    <br/>\n                                    <p class=\"fa fa-usd\"> fa-usd </p>\n                                    <br/>\n                                    <p class=\"fa fa-rupee\"> fa-rupee </p>\n                                    <br/>\n                                    <p class=\"fa fa-inr\"> fa-inr </p>\n                                    <br/>\n                                    <p class=\"fa fa-cny\"> fa-cny </p>\n                                    <br/>\n                                    <p class=\"fa fa-rmb\"> fa-rmb </p>\n                                    <br/>\n                                    <p class=\"fa fa-yen\"> fa-yen </p>\n                                    <br/>\n                                    <p class=\"fa fa-jpy\"> fa-jpy </p>\n                                    <br/>\n                                    <p class=\"fa fa-ruble\"> fa-ruble </p>\n                                    <br/>\n                                    <p class=\"fa fa-rouble\"> fa-rouble </p>\n                                    <br/>\n                                    <p class=\"fa fa-rub\"> fa-rub </p>\n                                    <br/>\n                                    <p class=\"fa fa-won\"> fa-won </p>\n                                    <br/>\n                                    <p class=\"fa fa-krw\"> fa-krw </p>\n                                    <br/>\n                                    <p class=\"fa fa-bitcoin\"> fa-bitcoin </p>\n                                    <br/>\n                                    <p class=\"fa fa-btc\"> fa-btc </p>\n                                    <br/>\n                                    <p class=\"fa fa-file\"> fa-file </p>\n                                    <br/>\n                                    <p class=\"fa fa-file-text\"> fa-file-text </p>\n                                    <br/>\n                                    <p class=\"fa fa-sort-alpha-asc\"> fa-sort-alpha-asc </p>\n                                    <br/>\n                                    <p class=\"fa fa-sort-alpha-desc\"> fa-sort-alpha-desc </p>\n                                    <br/>\n                                    <p class=\"fa fa-sort-amount-asc\"> fa-sort-amount-asc </p>\n                                    <br/>\n                                    <p class=\"fa fa-sort-amount-desc\"> fa-sort-amount-desc </p>\n                                    <br/>\n                                    <p class=\"fa fa-sort-numeric-asc\"> fa-sort-numeric-asc </p>\n                                    <br/>\n                                    <p class=\"fa fa-sort-numeric-desc\"> fa-sort-numeric-desc </p>\n                                    <br/>\n                                    <p class=\"fa fa-thumbs-up\"> fa-thumbs-up </p>\n                                    <br/>\n                                    <p class=\"fa fa-thumbs-down\"> fa-thumbs-down </p>\n                                    <br/>\n                                    <p class=\"fa fa-youtube-square\"> fa-youtube-square </p>\n                                    <br/>\n                                    <p class=\"fa fa-youtube\"> fa-youtube </p>\n                                    <br/>\n                                    <p class=\"fa fa-xing\"> fa-xing </p>\n                                    <br/>\n                                    <p class=\"fa fa-xing-square\"> fa-xing-square </p>\n                                    <br/>\n                                    <p class=\"fa fa-youtube-play\"> fa-youtube-play </p>\n                                    <br/>\n                                    <p class=\"fa fa-dropbox\"> fa-dropbox </p>\n                                    <br/>\n                                    <p class=\"fa fa-stack-overflow\"> fa-stack-overflow </p>\n                                    <br/>\n                                    <p class=\"fa fa-instagram\"> fa-instagram </p>\n                                    <br/>\n                                    <p class=\"fa fa-flickr\"> fa-flickr </p>\n                                    <br/>\n                                    <p class=\"fa fa-adn\"> fa-adn </p>\n                                    <br/>\n                                    <p class=\"fa fa-bitbucket\"> fa-bitbucket </p>\n                                    <br/>\n                                    <p class=\"fa fa-bitbucket-square\"> fa-bitbucket-square </p>\n                                    <br/>\n                                    <p class=\"fa fa-tumblr\"> fa-tumblr </p>\n                                    <br/>\n                                </div>\n                                <div class=\"fa col-lg-3\">\n                                    <p class=\"fa fa-tumblr-square\"> fa-tumblr-square </p>\n                                    <br/>\n                                    <p class=\"fa fa-long-arrow-down\"> fa-long-arrow-down </p>\n                                    <br/>\n                                    <p class=\"fa fa-long-arrow-up\"> fa-long-arrow-up </p>\n                                    <br/>\n                                    <p class=\"fa fa-long-arrow-left\"> fa-long-arrow-left </p>\n                                    <br/>\n                                    <p class=\"fa fa-long-arrow-right\"> fa-long-arrow-right </p>\n                                    <br/>\n                                    <p class=\"fa fa-apple\"> fa-apple </p>\n                                    <br/>\n                                    <p class=\"fa fa-windows\"> fa-windows </p>\n                                    <br/>\n                                    <p class=\"fa fa-android\"> fa-android </p>\n                                    <br/>\n                                    <p class=\"fa fa-linux\"> fa-linux </p>\n                                    <br/>\n                                    <p class=\"fa fa-dribbble\"> fa-dribbble </p>\n                                    <br/>\n                                    <p class=\"fa fa-skype\"> fa-skype </p>\n                                    <br/>\n                                    <p class=\"fa fa-foursquare\"> fa-foursquare </p>\n                                    <br/>\n                                    <p class=\"fa fa-trello\"> fa-trello </p>\n                                    <br/>\n                                    <p class=\"fa fa-female\"> fa-female </p>\n                                    <br/>\n                                    <p class=\"fa fa-male\"> fa-male </p>\n                                    <br/>\n                                    <p class=\"fa fa-gittip\"> fa-gittip </p>\n                                    <br/>\n                                    <p class=\"fa fa-sun-o\"> fa-sun-o </p>\n                                    <br/>\n                                    <p class=\"fa fa-moon-o\"> fa-moon-o </p>\n                                    <br/>\n                                    <p class=\"fa fa-archive\"> fa-archive </p>\n                                    <br/>\n                                    <p class=\"fa fa-bug\"> fa-bug </p>\n                                    <br/>\n                                    <p class=\"fa fa-vk\"> fa-vk </p>\n                                    <br/>\n                                    <p class=\"fa fa-weibo\"> fa-weibo </p>\n                                    <br/>\n                                    <p class=\"fa fa-renren\"> fa-renren </p>\n                                    <br/>\n                                    <p class=\"fa fa-pagelines\"> fa-pagelines </p>\n                                    <br/>\n                                    <p class=\"fa fa-stack-exchange\"> fa-stack-exchange </p>\n                                    <br/>\n                                    <p class=\"fa fa-arrow-circle-o-right\"> fa-arrow-circle-o-right </p>\n                                    <br/>\n                                    <p class=\"fa fa-arrow-circle-o-left\"> fa-arrow-circle-o-left </p>\n                                    <br/>\n                                    <p class=\"fa fa-toggle-left\"> fa-toggle-left </p>\n                                    <br/>\n                                    <p class=\"fa fa-caret-square-o-left\"> fa-caret-square-o-left </p>\n                                    <br/>\n                                    <p class=\"fa fa-dot-circle-o\"> fa-dot-circle-o </p>\n                                    <br/>\n                                    <p class=\"fa fa-wheelchair\"> fa-wheelchair </p>\n                                    <br/>\n                                    <p class=\"fa fa-vimeo-square\"> fa-vimeo-square </p>\n                                    <br/>\n                                    <p class=\"fa fa-turkish-lira\"> fa-turkish-lira </p>\n                                    <br/>\n                                    <p class=\"fa fa-try\"> fa-try </p>\n                                    <br/>\n                                    <p class=\"fa fa-plus-square-o\"> fa-plus-square-o </p>\n                                    <br/>\n                                    <p class=\"fa fa-space-shuttle\"> fa-space-shuttle </p>\n                                    <br/>\n                                    <p class=\"fa fa-slack\"> fa-slack </p>\n                                    <br/>\n                                    <p class=\"fa fa-envelope-square\"> fa-envelope-square </p>\n                                    <br/>\n                                    <p class=\"fa fa-wordpress\"> fa-wordpress </p>\n                                    <br/>\n                                    <p class=\"fa fa-openid\"> fa-openid </p>\n                                    <br/>\n                                    <p class=\"fa fa-institution\"> fa-institution </p>\n                                    <br/>\n                                    <p class=\"fa fa-bank\"> fa-bank </p>\n                                    <br/>\n                                    <p class=\"fa fa-university\"> fa-university </p>\n                                    <br/>\n                                    <p class=\"fa fa-mortar-board\"> fa-mortar-board </p>\n                                    <br/>\n                                    <p class=\"fa fa-graduation-cap\"> fa-graduation-cap </p>\n                                    <br/>\n                                    <p class=\"fa fa-yahoo\"> fa-yahoo </p>\n                                    <br/>\n                                    <p class=\"fa fa-google\"> fa-google </p>\n                                    <br/>\n                                    <p class=\"fa fa-reddit\"> fa-reddit </p>\n                                    <br/>\n                                    <p class=\"fa fa-reddit-square\"> fa-reddit-square </p>\n                                    <br/>\n                                    <p class=\"fa fa-stumbleupon-circle\"> fa-stumbleupon-circle </p>\n                                    <br/>\n                                    <p class=\"fa fa-stumbleupon\"> fa-stumbleupon </p>\n                                    <br/>\n                                    <p class=\"fa fa-delicious\"> fa-delicious </p>\n                                    <br/>\n                                    <p class=\"fa fa-digg\"> fa-digg </p>\n                                    <br/>\n                                    <p class=\"fa fa-pied-piper-square\"> fa-pied-piper-square </p>\n                                    <br/>\n                                    <p class=\"fa fa-pied-piper\"> fa-pied-piper </p>\n                                    <br/>\n                                    <p class=\"fa fa-pied-piper-alt\"> fa-pied-piper-alt </p>\n                                    <br/>\n                                    <p class=\"fa fa-drupal\"> fa-drupal </p>\n                                    <br/>\n                                    <p class=\"fa fa-joomla\"> fa-joomla </p>\n                                    <br/>\n                                    <p class=\"fa fa-language\"> fa-language </p>\n                                    <br/>\n                                    <p class=\"fa fa-fax\"> fa-fax </p>\n                                    <br/>\n                                    <p class=\"fa fa-building\"> fa-building </p>\n                                    <br/>\n                                    <p class=\"fa fa-child\"> fa-child </p>\n                                    <br/>\n                                    <p class=\"fa fa-paw\"> fa-paw </p>\n                                    <br/>\n                                    <p class=\"fa fa-spoon\"> fa-spoon </p>\n                                    <br/>\n                                    <p class=\"fa fa-cube\"> fa-cube </p>\n                                    <br/>\n                                    <p class=\"fa fa-cubes\"> fa-cubes </p>\n                                    <br/>\n                                    <p class=\"fa fa-behance\"> fa-behance </p>\n                                    <br/>\n                                    <p class=\"fa fa-behance-square\"> fa-behance-square </p>\n                                    <br/>\n                                    <p class=\"fa fa-steam\"> fa-steam </p>\n                                    <br/>\n                                    <p class=\"fa fa-steam-square\"> fa-steam-square </p>\n                                    <br/>\n                                    <p class=\"fa fa-recycle\"> fa-recycle </p>\n                                    <br/>\n                                    <p class=\"fa fa-automobile\"> fa-automobile </p>\n                                    <br/>\n                                    <p class=\"fa fa-car\"> fa-car </p>\n                                    <br/>\n                                    <p class=\"fa fa-cab\"> fa-cab </p>\n                                    <br/>\n                                    <p class=\"fa fa-taxi\"> fa-taxi </p>\n                                    <br/>\n                                    <p class=\"fa fa-tree\"> fa-tree </p>\n                                    <br/>\n                                    <p class=\"fa fa-spotify\"> fa-spotify </p>\n                                    <br/>\n                                    <p class=\"fa fa-deviantart\"> fa-deviantart </p>\n                                    <br/>\n                                    <p class=\"fa fa-soundcloud\"> fa-soundcloud </p>\n                                    <br/>\n                                    <p class=\"fa fa-database\"> fa-database </p>\n                                    <br/>\n                                    <p class=\"fa fa-file-pdf-o\"> fa-file-pdf-o </p>\n                                    <br/>\n                                    <p class=\"fa fa-file-word-o\"> fa-file-word-o </p>\n                                    <br/>\n                                    <p class=\"fa fa-file-excel-o\"> fa-file-excel-o </p>\n                                    <br/>\n                                    <p class=\"fa fa-file-powerpoint-o\"> fa-file-powerpoint-o </p>\n                                    <br/>\n                                    <p class=\"fa fa-file-photo-o\"> fa-file-photo-o </p>\n                                    <br/>\n                                    <p class=\"fa fa-file-picture-o\"> fa-file-picture-o </p>\n                                    <br/>\n                                    <p class=\"fa fa-file-image-o\"> fa-file-image-o </p>\n                                    <br/>\n                                    <p class=\"fa fa-file-zip-o\"> fa-file-zip-o </p>\n                                    <br/>\n                                    <p class=\"fa fa-file-archive-o\"> fa-file-archive-o </p>\n                                    <br/>\n                                    <p class=\"fa fa-file-sound-o\"> fa-file-sound-o </p>\n                                    <br/>\n                                    <p class=\"fa fa-file-audio-o\"> fa-file-audio-o </p>\n                                    <br/>\n                                    <p class=\"fa fa-file-movie-o\"> fa-file-movie-o </p>\n                                    <br/>\n                                    <p class=\"fa fa-file-video-o\"> fa-file-video-o </p>\n                                    <br/>\n                                    <p class=\"fa fa-file-code-o\"> fa-file-code-o </p>\n                                    <br/>\n                                    <p class=\"fa fa-vine\"> fa-vine </p>\n                                    <br/>\n                                    <p class=\"fa fa-codepen\"> fa-codepen </p>\n                                    <br/>\n                                    <p class=\"fa fa-jsfiddle\"> fa-jsfiddle </p>\n                                    <br/>\n                                    <p class=\"fa fa-life-bouy\"> fa-life-bouy </p>\n                                    <br/>\n                                    <p class=\"fa fa-life-saver\"> fa-life-saver </p>\n                                    <br/>\n                                    <p class=\"fa fa-support\"> fa-support </p>\n                                    <br/>\n                                    <p class=\"fa fa-life-ring\"> fa-life-ring </p>\n                                    <br/>\n                                    <p class=\"fa fa-circle-o-notch\"> fa-circle-o-notch </p>\n                                    <br/>\n                                    <p class=\"fa fa-ra\"> fa-ra </p>\n                                    <br/>\n                                    <p class=\"fa fa-rebel\"> fa-rebel </p>\n                                    <br/>\n                                    <p class=\"fa fa-ge\"> fa-ge </p>\n                                    <br/>\n                                    <p class=\"fa fa-empire\"> fa-empire </p>\n                                    <br/>\n                                    <p class=\"fa fa-git-square\"> fa-git-square </p>\n                                    <br/>\n                                    <p class=\"fa fa-git\"> fa-git </p>\n                                    <br/>\n                                    <p class=\"fa fa-hacker-news\"> fa-hacker-news </p>\n                                    <br/>\n                                    <p class=\"fa fa-tencent-weibo\"> fa-tencent-weibo </p>\n                                    <br/>\n                                    <p class=\"fa fa-qq\"> fa-qq </p>\n                                    <br/>\n                                    <p class=\"fa fa-wechat\"> fa-wechat </p>\n                                    <br/>\n                                    <p class=\"fa fa-weixin\"> fa-weixin </p>\n                                    <br/>\n                                    <p class=\"fa fa-send\"> fa-send </p>\n                                    <br/>\n                                    <p class=\"fa fa-paper-plane\"> fa-paper-plane </p>\n                                    <br/>\n                                    <p class=\"fa fa-send-o\"> fa-send-o </p>\n                                    <br/>\n                                    <p class=\"fa fa-paper-plane-o\"> fa-paper-plane-o </p>\n                                    <br/>\n                                    <p class=\"fa fa-history\"> fa-history </p>\n                                    <br/>\n                                    <p class=\"fa fa-circle-thin\"> fa-circle-thin </p>\n                                    <br/>\n                                    <p class=\"fa fa-header\"> fa-header </p>\n                                    <br/>\n                                    <p class=\"fa fa-paragraph\"> fa-paragraph </p>\n                                    <br/>\n                                    <p class=\"fa fa-sliders\"> fa-sliders </p>\n                                    <br/>\n                                    <p class=\"fa fa-share-alt\"> fa-share-alt </p>\n                                    <br/>\n                                    <p class=\"fa fa-share-alt-square\"> fa-share-alt-square </p>\n                                    <br/>\n                                    <p class=\"fa fa-bomb\"> fa-bomb </p>\n                                    <br/>\n                                </div>\n                                <!-- /.col-lg-6 (nested) -->\n                            </div>\n                            <!-- /.row (nested) -->\n                        </div>\n                        <!-- /.panel-body -->\n                    </div>\n                    <!-- /.panel -->\n                </div>\n                <!-- /.col-lg-12 -->\n            </div>\n            <!-- /.row -->\n            <div class=\"row\">\n                <div class=\"col-lg-12\">\n                    <div class=\"panel panel-default\">\n                        <div class=\"panel-heading\">\n                            All available icons (bootstrap)\n                        </div>\n                        <div class=\"panel-body\">\n                            <div class=\"row\">\n                                <div class=\"bs-glyphicons col-lg-4\">\n                                    <span class=\"glyphicon glyphicon-asterisk\"> glyphicon-asterisk </span>\n                                    <br/>\n                                    <span class=\"glyphicon glyphicon-plus\"> glyphicon-plus </span>\n                                    <br/>\n                                    <span class=\"glyphicon glyphicon-euro\"> glyphicon-euro </span>\n                                    <br/>\n                                    <span class=\"glyphicon glyphicon-eur\"> glyphicon-eur </span>\n                                    <br/>\n                                    <span class=\"glyphicon glyphicon-minus\"> glyphicon-minus </span>\n                                    <br/>\n                                    <span class=\"glyphicon glyphicon-cloud\"> glyphicon-cloud </span>\n                                    <br/>\n                                    <span class=\"glyphicon glyphicon-envelope\"> glyphicon-envelope </span>\n                                    <br/>\n                                    <span class=\"glyphicon glyphicon-pencil\"> glyphicon-pencil </span>\n                                    <br/>\n                                    <span class=\"glyphicon glyphicon-glass\"> glyphicon-glass </span>\n                                    <br/>\n                                    <span class=\"glyphicon glyphicon-music\"> glyphicon-music </span>\n                                    <br/>\n                                    <span class=\"glyphicon glyphicon-search\"> glyphicon-search </span>\n                                    <br/>\n                                    <span class=\"glyphicon glyphicon-heart\"> glyphicon-heart </span>\n                                    <br/>\n                                    <span class=\"glyphicon glyphicon-star\"> glyphicon-star </span>\n                                    <br/>\n                                    <span class=\"glyphicon glyphicon-star-empty\"> glyphicon-star-empty </span>\n                                    <br/>\n                                    <span class=\"glyphicon glyphicon-user\"> glyphicon-user </span>\n                                    <br/>\n                                    <span class=\"glyphicon glyphicon-film\"> glyphicon-film </span>\n                                    <br/>\n                                    <span class=\"glyphicon glyphicon-th-large\"> glyphicon-th-large </span>\n                                    <br/>\n                                    <span class=\"glyphicon glyphicon-th\"> glyphicon-th </span>\n                                    <br/>\n                                    <span class=\"glyphicon glyphicon-th-list\"> glyphicon-th-list </span>\n                                    <br/>\n                                    <span class=\"glyphicon glyphicon-ok\"> glyphicon-ok </span>\n                                    <br/>\n                                    <span class=\"glyphicon glyphicon-remove\"> glyphicon-remove </span>\n                                    <br/>\n                                    <span class=\"glyphicon glyphicon-zoom-in\"> glyphicon-zoom-in </span>\n                                    <br/>\n                                    <span class=\"glyphicon glyphicon-zoom-out\"> glyphicon-zoom-out </span>\n                                    <br/>\n                                    <span class=\"glyphicon glyphicon-off\"> glyphicon-off </span>\n                                    <br/>\n                                    <span class=\"glyphicon glyphicon-signal\"> glyphicon-signal </span>\n                                    <br/>\n                                    <span class=\"glyphicon glyphicon-cog\"> glyphicon-cog </span>\n                                    <br/>\n                                    <span class=\"glyphicon glyphicon-trash\"> glyphicon-trash </span>\n                                    <br/>\n                                    <span class=\"glyphicon glyphicon-home\"> glyphicon-home </span>\n                                    <br/>\n                                    <span class=\"glyphicon glyphicon-file\"> glyphicon-file </span>\n                                    <br/>\n                                    <span class=\"glyphicon glyphicon-time\"> glyphicon-time </span>\n                                    <br/>\n                                    <span class=\"glyphicon glyphicon-road\"> glyphicon-road </span>\n                                    <br/>\n                                    <span class=\"glyphicon glyphicon-download-alt\"> glyphicon-download-alt </span>\n                                    <br/>\n                                    <span class=\"glyphicon glyphicon-download\"> glyphicon-download </span>\n                                    <br/>\n                                    <span class=\"glyphicon glyphicon-upload\"> glyphicon-upload </span>\n                                    <br/>\n                                    <span class=\"glyphicon glyphicon-inbox\"> glyphicon-inbox </span>\n                                    <br/>\n                                    <span class=\"glyphicon glyphicon-play-circle\"> glyphicon-play-circle </span>\n                                    <br/>\n                                    <span class=\"glyphicon glyphicon-repeat\"> glyphicon-repeat </span>\n                                    <br/>\n                                    <span class=\"glyphicon glyphicon-refresh\"> glyphicon-refresh </span>\n                                    <br/>\n                                    <span class=\"glyphicon glyphicon-list-alt\"> glyphicon-list-alt </span>\n                                    <br/>\n                                    <span class=\"glyphicon glyphicon-lock\"> glyphicon-lock </span>\n                                    <br/>\n                                    <span class=\"glyphicon glyphicon-flag\"> glyphicon-flag </span>\n                                    <br/>\n                                    <span class=\"glyphicon glyphicon-headphones\"> glyphicon-headphones </span>\n                                    <br/>\n                                    <span class=\"glyphicon glyphicon-volume-off\"> glyphicon-volume-off </span>\n                                    <br/>\n                                    <span class=\"glyphicon glyphicon-volume-down\"> glyphicon-volume-down </span>\n                                    <br/>\n                                    <span class=\"glyphicon glyphicon-volume-up\"> glyphicon-volume-up </span>\n                                    <br/>\n                                    <span class=\"glyphicon glyphicon-qrcode\"> glyphicon-qrcode </span>\n                                    <br/>\n                                    <span class=\"glyphicon glyphicon-barcode\"> glyphicon-barcode </span>\n                                    <br/>\n                                    <span class=\"glyphicon glyphicon-tag\"> glyphicon-tag </span>\n                                    <br/>\n                                    <span class=\"glyphicon glyphicon-tags\"> glyphicon-tags </span>\n                                    <br/>\n                                    <span class=\"glyphicon glyphicon-book\"> glyphicon-book </span>\n                                    <br/>\n                                    <span class=\"glyphicon glyphicon-bookmark\"> glyphicon-bookmark </span>\n                                    <br/>\n                                    <span class=\"glyphicon glyphicon-print\"> glyphicon-print </span>\n                                    <br/>\n                                    <span class=\"glyphicon glyphicon-camera\"> glyphicon-camera </span>\n                                    <br/>\n                                    <span class=\"glyphicon glyphicon-font\"> glyphicon-font </span>\n                                    <br/>\n                                    <span class=\"glyphicon glyphicon-bold\"> glyphicon-bold </span>\n                                    <br/>\n                                    <span class=\"glyphicon glyphicon-italic\"> glyphicon-italic </span>\n                                    <br/>\n                                    <span class=\"glyphicon glyphicon-text-height\"> glyphicon-text-height </span>\n                                    <br/>\n                                    <span class=\"glyphicon glyphicon-text-width\"> glyphicon-text-width </span>\n                                    <br/>\n                                    <span class=\"glyphicon glyphicon-align-left\"> glyphicon-align-left </span>\n                                    <br/>\n                                    <span class=\"glyphicon glyphicon-align-center\"> glyphicon-align-center </span>\n                                    <br/>\n                                    <span class=\"glyphicon glyphicon-align-right\"> glyphicon-align-right </span>\n                                    <br/>\n                                    <span class=\"glyphicon glyphicon-align-justify\"> glyphicon-align-justify </span>\n                                    <br/>\n                                    <span class=\"glyphicon glyphicon-list\"> glyphicon-list </span>\n                                    <br/>\n                                    <span class=\"glyphicon glyphicon-indent-left\"> glyphicon-indent-left </span>\n                                    <br/>\n                                    <span class=\"glyphicon glyphicon-indent-right\"> glyphicon-indent-right </span>\n                                    <br/>\n                                    <span class=\"glyphicon glyphicon-facetime-video\"> glyphicon-facetime-video </span>\n                                    <br/>\n                                    <span class=\"glyphicon glyphicon-picture\"> glyphicon-picture </span>\n                                    <br/>\n                                    <span class=\"glyphicon glyphicon-map-marker\"> glyphicon-map-marker </span>\n                                    <br/>\n                                    <span class=\"glyphicon glyphicon-adjust\"> glyphicon-adjust </span>\n                                    <br/>\n                                    <span class=\"glyphicon glyphicon-tint\"> glyphicon-tint </span>\n                                    <br/>\n                                    <span class=\"glyphicon glyphicon-edit\"> glyphicon-edit </span>\n                                    <br/>\n                                    <span class=\"glyphicon glyphicon-share\"> glyphicon-share </span>\n                                    <br/>\n                                    <span class=\"glyphicon glyphicon-check\"> glyphicon-check </span>\n                                    <br/>\n                                    <span class=\"glyphicon glyphicon-move\"> glyphicon-move </span>\n                                    <br/>\n                                    <span class=\"glyphicon glyphicon-step-backward\"> glyphicon-step-backward </span>\n                                    <br/>\n                                    <span class=\"glyphicon glyphicon-fast-backward\"> glyphicon-fast-backward </span>\n                                    <br/>\n                                    <span class=\"glyphicon glyphicon-backward\"> glyphicon-backward </span>\n                                    <br/>\n                                    <span class=\"glyphicon glyphicon-play\"> glyphicon-play </span>\n                                    <br/>\n                                    <span class=\"glyphicon glyphicon-pause\"> glyphicon-pause </span>\n                                    <br/>\n                                    <span class=\"glyphicon glyphicon-stop\"> glyphicon-stop </span>\n                                    <br/>\n                                    <span class=\"glyphicon glyphicon-forward\"> glyphicon-forward </span>\n                                    <br/>\n                                    <span class=\"glyphicon glyphicon-fast-forward\"> glyphicon-fast-forward </span>\n                                    <br/>\n                                    <span class=\"glyphicon glyphicon-step-forward\"> glyphicon-step-forward </span>\n                                    <br/>\n                                    <span class=\"glyphicon glyphicon-eject\"> glyphicon-eject </span>\n                                    <br/>\n                                    <span class=\"glyphicon glyphicon-chevron-left\"> glyphicon-chevron-left </span>\n                                    <br/>\n                                    <span class=\"glyphicon glyphicon-chevron-right\"> glyphicon-chevron-right </span>\n                                    <br/>\n                                    <span class=\"glyphicon glyphicon-plus-sign\"> glyphicon-plus-sign </span>\n                                    <br/>\n                                </div>\n                                <div class=\"bs-glyphicons col-lg-4\">\n                                    <span class=\"glyphicon glyphicon-minus-sign\"> glyphicon-minus-sign </span>\n                                    <br/>\n                                    <span class=\"glyphicon glyphicon-remove-sign\"> glyphicon-remove-sign </span>\n                                    <br/>\n                                    <span class=\"glyphicon glyphicon-ok-sign\"> glyphicon-ok-sign </span>\n                                    <br/>\n                                    <span class=\"glyphicon glyphicon-question-sign\"> glyphicon-question-sign </span>\n                                    <br/>\n                                    <span class=\"glyphicon glyphicon-info-sign\"> glyphicon-info-sign </span>\n                                    <br/>\n                                    <span class=\"glyphicon glyphicon-screenshot\"> glyphicon-screenshot </span>\n                                    <br/>\n                                    <span class=\"glyphicon glyphicon-remove-circle\"> glyphicon-remove-circle </span>\n                                    <br/>\n                                    <span class=\"glyphicon glyphicon-ok-circle\"> glyphicon-ok-circle </span>\n                                    <br/>\n                                    <span class=\"glyphicon glyphicon-ban-circle\"> glyphicon-ban-circle </span>\n                                    <br/>\n                                    <span class=\"glyphicon glyphicon-arrow-left\"> glyphicon-arrow-left </span>\n                                    <br/>\n                                    <span class=\"glyphicon glyphicon-arrow-right\"> glyphicon-arrow-right </span>\n                                    <br/>\n                                    <span class=\"glyphicon glyphicon-arrow-up\"> glyphicon-arrow-up </span>\n                                    <br/>\n                                    <span class=\"glyphicon glyphicon-arrow-down\"> glyphicon-arrow-down </span>\n                                    <br/>\n                                    <span class=\"glyphicon glyphicon-share-alt\"> glyphicon-share-alt </span>\n                                    <br/>\n                                    <span class=\"glyphicon glyphicon-resize-full\"> glyphicon-resize-full </span>\n                                    <br/>\n                                    <span class=\"glyphicon glyphicon-resize-small\"> glyphicon-resize-small </span>\n                                    <br/>\n                                    <span class=\"glyphicon glyphicon-exclamation-sign\"> glyphicon-exclamation-sign </span>\n                                    <br/>\n                                    <span class=\"glyphicon glyphicon-gift\"> glyphicon-gift </span>\n                                    <br/>\n                                    <span class=\"glyphicon glyphicon-leaf\"> glyphicon-leaf </span>\n                                    <br/>\n                                    <span class=\"glyphicon glyphicon-fire\"> glyphicon-fire </span>\n                                    <br/>\n                                    <span class=\"glyphicon glyphicon-eye-open\"> glyphicon-eye-open </span>\n                                    <br/>\n                                    <span class=\"glyphicon glyphicon-eye-close\"> glyphicon-eye-close </span>\n                                    <br/>\n                                    <span class=\"glyphicon glyphicon-warning-sign\"> glyphicon-warning-sign </span>\n                                    <br/>\n                                    <span class=\"glyphicon glyphicon-plane\"> glyphicon-plane </span>\n                                    <br/>\n                                    <span class=\"glyphicon glyphicon-calendar\"> glyphicon-calendar </span>\n                                    <br/>\n                                    <span class=\"glyphicon glyphicon-random\"> glyphicon-random </span>\n                                    <br/>\n                                    <span class=\"glyphicon glyphicon-comment\"> glyphicon-comment </span>\n                                    <br/>\n                                    <span class=\"glyphicon glyphicon-magnet\"> glyphicon-magnet </span>\n                                    <br/>\n                                    <span class=\"glyphicon glyphicon-chevron-up\"> glyphicon-chevron-up </span>\n                                    <br/>\n                                    <span class=\"glyphicon glyphicon-chevron-down\"> glyphicon-chevron-down </span>\n                                    <br/>\n                                    <span class=\"glyphicon glyphicon-retweet\"> glyphicon-retweet </span>\n                                    <br/>\n                                    <span class=\"glyphicon glyphicon-shopping-cart\"> glyphicon-shopping-cart </span>\n                                    <br/>\n                                    <span class=\"glyphicon glyphicon-folder-close\"> glyphicon-folder-close </span>\n                                    <br/>\n                                    <span class=\"glyphicon glyphicon-folder-open\"> glyphicon-folder-open </span>\n                                    <br/>\n                                    <span class=\"glyphicon glyphicon-resize-vertical\"> glyphicon-resize-vertical </span>\n                                    <br/>\n                                    <span class=\"glyphicon glyphicon-resize-horizontal\"> glyphicon-resize-horizontal </span>\n                                    <br/>\n                                    <span class=\"glyphicon glyphicon-hdd\"> glyphicon-hdd </span>\n                                    <br/>\n                                    <span class=\"glyphicon glyphicon-bullhorn\"> glyphicon-bullhorn </span>\n                                    <br/>\n                                    <span class=\"glyphicon glyphicon-bell\"> glyphicon-bell </span>\n                                    <br/>\n                                    <span class=\"glyphicon glyphicon-certificate\"> glyphicon-certificate </span>\n                                    <br/>\n                                    <span class=\"glyphicon glyphicon-thumbs-up\"> glyphicon-thumbs-up </span>\n                                    <br/>\n                                    <span class=\"glyphicon glyphicon-thumbs-down\"> glyphicon-thumbs-down </span>\n                                    <br/>\n                                    <span class=\"glyphicon glyphicon-hand-right\"> glyphicon-hand-right </span>\n                                    <br/>\n                                    <span class=\"glyphicon glyphicon-hand-left\"> glyphicon-hand-left </span>\n                                    <br/>\n                                    <span class=\"glyphicon glyphicon-hand-up\"> glyphicon-hand-up </span>\n                                    <br/>\n                                    <span class=\"glyphicon glyphicon-hand-down\"> glyphicon-hand-down </span>\n                                    <br/>\n                                    <span class=\"glyphicon glyphicon-circle-arrow-right\"> glyphicon-circle-arrow-right </span>\n                                    <br/>\n                                    <span class=\"glyphicon glyphicon-circle-arrow-left\"> glyphicon-circle-arrow-left </span>\n                                    <br/>\n                                    <span class=\"glyphicon glyphicon-circle-arrow-up\"> glyphicon-circle-arrow-up </span>\n                                    <br/>\n                                    <span class=\"glyphicon glyphicon-circle-arrow-down\"> glyphicon-circle-arrow-down </span>\n                                    <br/>\n                                    <span class=\"glyphicon glyphicon-globe\"> glyphicon-globe </span>\n                                    <br/>\n                                    <span class=\"glyphicon glyphicon-wrench\"> glyphicon-wrench </span>\n                                    <br/>\n                                    <span class=\"glyphicon glyphicon-tasks\"> glyphicon-tasks </span>\n                                    <br/>\n                                    <span class=\"glyphicon glyphicon-filter\"> glyphicon-filter </span>\n                                    <br/>\n                                    <span class=\"glyphicon glyphicon-briefcase\"> glyphicon-briefcase </span>\n                                    <br/>\n                                    <span class=\"glyphicon glyphicon-fullscreen\"> glyphicon-fullscreen </span>\n                                    <br/>\n                                    <span class=\"glyphicon glyphicon-dashboard\"> glyphicon-dashboard </span>\n                                    <br/>\n                                    <span class=\"glyphicon glyphicon-paperclip\"> glyphicon-paperclip </span>\n                                    <br/>\n                                    <span class=\"glyphicon glyphicon-heart-empty\"> glyphicon-heart-empty </span>\n                                    <br/>\n                                    <span class=\"glyphicon glyphicon-link\"> glyphicon-link </span>\n                                    <br/>\n                                    <span class=\"glyphicon glyphicon-phone\"> glyphicon-phone </span>\n                                    <br/>\n                                    <span class=\"glyphicon glyphicon-pushpin\"> glyphicon-pushpin </span>\n                                    <br/>\n                                    <span class=\"glyphicon glyphicon-usd\"> glyphicon-usd </span>\n                                    <br/>\n                                    <span class=\"glyphicon glyphicon-gbp\"> glyphicon-gbp </span>\n                                    <br/>\n                                    <span class=\"glyphicon glyphicon-sort\"> glyphicon-sort </span>\n                                    <br/>\n                                    <span class=\"glyphicon glyphicon-sort-by-alphabet\"> glyphicon-sort-by-alphabet </span>\n                                    <br/>\n                                    <span class=\"glyphicon glyphicon-sort-by-alphabet-alt\"> glyphicon-sort-by-alphabet-alt </span>\n                                    <br/>\n                                    <span class=\"glyphicon glyphicon-sort-by-order\"> glyphicon-sort-by-order </span>\n                                    <br/>\n                                    <span class=\"glyphicon glyphicon-sort-by-order-alt\"> glyphicon-sort-by-order-alt </span>\n                                    <br/>\n                                    <span class=\"glyphicon glyphicon-sort-by-attributes\"> glyphicon-sort-by-attributes </span>\n                                    <br/>\n                                    <span class=\"glyphicon glyphicon-sort-by-attributes-alt\"> glyphicon-sort-by-attributes-alt </span>\n                                    <br/>\n                                    <span class=\"glyphicon glyphicon-unchecked\"> glyphicon-unchecked </span>\n                                    <br/>\n                                    <span class=\"glyphicon glyphicon-expand\"> glyphicon-expand </span>\n                                    <br/>\n                                    <span class=\"glyphicon glyphicon-collapse-down\"> glyphicon-collapse-down </span>\n                                    <br/>\n                                    <span class=\"glyphicon glyphicon-collapse-up\"> glyphicon-collapse-up </span>\n                                    <br/>\n                                    <span class=\"glyphicon glyphicon-log-in\"> glyphicon-log-in </span>\n                                    <br/>\n                                    <span class=\"glyphicon glyphicon-flash\"> glyphicon-flash </span>\n                                    <br/>\n                                    <span class=\"glyphicon glyphicon-log-out\"> glyphicon-log-out </span>\n                                    <br/>\n                                    <span class=\"glyphicon glyphicon-new-window\"> glyphicon-new-window </span>\n                                    <br/>\n                                    <span class=\"glyphicon glyphicon-record\"> glyphicon-record </span>\n                                    <br/>\n                                    <span class=\"glyphicon glyphicon-save\"> glyphicon-save </span>\n                                    <br/>\n                                    <span class=\"glyphicon glyphicon-open\"> glyphicon-open </span>\n                                    <br/>\n                                    <span class=\"glyphicon glyphicon-saved\"> glyphicon-saved </span>\n                                    <br/>\n                                    <span class=\"glyphicon glyphicon-import\"> glyphicon-import </span>\n                                    <br/>\n                                    <span class=\"glyphicon glyphicon-export\"> glyphicon-export </span>\n                                    <br/>\n                                    <span class=\"glyphicon glyphicon-send\"> glyphicon-send </span>\n                                    <br/>\n                                </div>\n                                <div class=\"bs-glyphicons col-lg-4\">\n                                    <span class=\"glyphicon glyphicon-floppy-disk\"> glyphicon-floppy-disk </span>\n                                    <br/>\n                                    <span class=\"glyphicon glyphicon-floppy-saved\"> glyphicon-floppy-saved </span>\n                                    <br/>\n                                    <span class=\"glyphicon glyphicon-floppy-remove\"> glyphicon-floppy-remove </span>\n                                    <br/>\n                                    <span class=\"glyphicon glyphicon-floppy-save\"> glyphicon-floppy-save </span>\n                                    <br/>\n                                    <span class=\"glyphicon glyphicon-floppy-open\"> glyphicon-floppy-open </span>\n                                    <br/>\n                                    <span class=\"glyphicon glyphicon-credit-card\"> glyphicon-credit-card </span>\n                                    <br/>\n                                    <span class=\"glyphicon glyphicon-transfer\"> glyphicon-transfer </span>\n                                    <br/>\n                                    <span class=\"glyphicon glyphicon-cutlery\"> glyphicon-cutlery </span>\n                                    <br/>\n                                    <span class=\"glyphicon glyphicon-header\"> glyphicon-header </span>\n                                    <br/>\n                                    <span class=\"glyphicon glyphicon-compressed\"> glyphicon-compressed </span>\n                                    <br/>\n                                    <span class=\"glyphicon glyphicon-earphone\"> glyphicon-earphone </span>\n                                    <br/>\n                                    <span class=\"glyphicon glyphicon-phone-alt\"> glyphicon-phone-alt </span>\n                                    <br/>\n                                    <span class=\"glyphicon glyphicon-tower\"> glyphicon-tower </span>\n                                    <br/>\n                                    <span class=\"glyphicon glyphicon-stats\"> glyphicon-stats </span>\n                                    <br/>\n                                    <span class=\"glyphicon glyphicon-sd-video\"> glyphicon-sd-video </span>\n                                    <br/>\n                                    <span class=\"glyphicon glyphicon-hd-video\"> glyphicon-hd-video </span>\n                                    <br/>\n                                    <span class=\"glyphicon glyphicon-subtitles\"> glyphicon-subtitles </span>\n                                    <br/>\n                                    <span class=\"glyphicon glyphicon-sound-stereo\"> glyphicon-sound-stereo </span>\n                                    <br/>\n                                    <span class=\"glyphicon glyphicon-sound-dolby\"> glyphicon-sound-dolby </span>\n                                    <br/>\n                                    <span class=\"glyphicon glyphicon-sound-5-1\"> glyphicon-sound-5-1 </span>\n                                    <br/>\n                                    <span class=\"glyphicon glyphicon-sound-6-1\"> glyphicon-sound-6-1 </span>\n                                    <br/>\n                                    <span class=\"glyphicon glyphicon-sound-7-1\"> glyphicon-sound-7-1 </span>\n                                    <br/>\n                                    <span class=\"glyphicon glyphicon-copyright-mark\"> glyphicon-copyright-mark </span>\n                                    <br/>\n                                    <span class=\"glyphicon glyphicon-registration-mark\"> glyphicon-registration-mark </span>\n                                    <br/>\n                                    <span class=\"glyphicon glyphicon-cloud-download\"> glyphicon-cloud-download </span>\n                                    <br/>\n                                    <span class=\"glyphicon glyphicon-cloud-upload\"> glyphicon-cloud-upload </span>\n                                    <br/>\n                                    <span class=\"glyphicon glyphicon-tree-conifer\"> glyphicon-tree-conifer </span>\n                                    <br/>\n                                    <span class=\"glyphicon glyphicon-tree-deciduous\"> glyphicon-tree-deciduous </span>\n                                    <br/>\n                                    <span class=\"glyphicon glyphicon-cd\"> glyphicon-cd </span>\n                                    <br/>\n                                    <span class=\"glyphicon glyphicon-save-file\"> glyphicon-save-file </span>\n                                    <br/>\n                                    <span class=\"glyphicon glyphicon-open-file\"> glyphicon-open-file </span>\n                                    <br/>\n                                    <span class=\"glyphicon glyphicon-level-up\"> glyphicon-level-up </span>\n                                    <br/>\n                                    <span class=\"glyphicon glyphicon-copy\"> glyphicon-copy </span>\n                                    <br/>\n                                    <span class=\"glyphicon glyphicon-paste\"> glyphicon-paste </span>\n                                    <br/>\n                                    <span class=\"glyphicon glyphicon-alert\"> glyphicon-alert </span>\n                                    <br/>\n                                    <span class=\"glyphicon glyphicon-equalizer\"> glyphicon-equalizer </span>\n                                    <br/>\n                                    <span class=\"glyphicon glyphicon-king\"> glyphicon-king </span>\n                                    <br/>\n                                    <span class=\"glyphicon glyphicon-queen\"> glyphicon-queen </span>\n                                    <br/>\n                                    <span class=\"glyphicon glyphicon-pawn\"> glyphicon-pawn </span>\n                                    <br/>\n                                    <span class=\"glyphicon glyphicon-bishop\"> glyphicon-bishop </span>\n                                    <br/>\n                                    <span class=\"glyphicon glyphicon-knight\"> glyphicon-knight </span>\n                                    <br/>\n                                    <span class=\"glyphicon glyphicon-baby-formula\"> glyphicon-baby-formula </span>\n                                    <br/>\n                                    <span class=\"glyphicon glyphicon-tent\"> glyphicon-tent </span>\n                                    <br/>\n                                    <span class=\"glyphicon glyphicon-blackboard\"> glyphicon-blackboard </span>\n                                    <br/>\n                                    <span class=\"glyphicon glyphicon-bed\"> glyphicon-bed </span>\n                                    <br/>\n                                    <span class=\"glyphicon glyphicon-apple\"> glyphicon-apple </span>\n                                    <br/>\n                                    <span class=\"glyphicon glyphicon-erase\"> glyphicon-erase </span>\n                                    <br/>\n                                    <span class=\"glyphicon glyphicon-hourglass\"> glyphicon-hourglass </span>\n                                    <br/>\n                                    <span class=\"glyphicon glyphicon-lamp\"> glyphicon-lamp </span>\n                                    <br/>\n                                    <span class=\"glyphicon glyphicon-duplicate\"> glyphicon-duplicate </span>\n                                    <br/>\n                                    <span class=\"glyphicon glyphicon-piggy-bank\"> glyphicon-piggy-bank </span>\n                                    <br/>\n                                    <span class=\"glyphicon glyphicon-scissors\"> glyphicon-scissors </span>\n                                    <br/>\n                                    <span class=\"glyphicon glyphicon-bitcoin\"> glyphicon-bitcoin </span>\n                                    <br/>\n                                    <span class=\"glyphicon glyphicon-yen\"> glyphicon-yen </span>\n                                    <br/>\n                                    <span class=\"glyphicon glyphicon-ruble\"> glyphicon-ruble </span>\n                                    <br/>\n                                    <span class=\"glyphicon glyphicon-scale\"> glyphicon-scale </span>\n                                    <br/>\n                                    <span class=\"glyphicon glyphicon-ice-lolly\"> glyphicon-ice-lolly </span>\n                                    <br/>\n                                    <span class=\"glyphicon glyphicon-ice-lolly-tasted\"> glyphicon-ice-lolly-tasted </span>\n                                    <br/>\n                                    <span class=\"glyphicon glyphicon-education\"> glyphicon-education </span>\n                                    <br/>\n                                    <span class=\"glyphicon glyphicon-option-horizontal\"> glyphicon-option-horizontal </span>\n                                    <br/>\n                                    <span class=\"glyphicon glyphicon-option-vertical\"> glyphicon-option-vertical </span>\n                                    <br/>\n                                    <span class=\"glyphicon glyphicon-menu-hamburger\"> glyphicon-menu-hamburger </span>\n                                    <br/>\n                                    <span class=\"glyphicon glyphicon-modal-window\"> glyphicon-modal-window </span>\n                                    <br/>\n                                    <span class=\"glyphicon glyphicon-oil\"> glyphicon-oil </span>\n                                    <br/>\n                                    <span class=\"glyphicon glyphicon-grain\"> glyphicon-grain </span>\n                                    <br/>\n                                    <span class=\"glyphicon glyphicon-sunglasses\"> glyphicon-sunglasses </span>\n                                    <br/>\n                                    <span class=\"glyphicon glyphicon-text-size\"> glyphicon-text-size </span>\n                                    <br/>\n                                    <span class=\"glyphicon glyphicon-text-color\"> glyphicon-text-color </span>\n                                    <br/>\n                                    <span class=\"glyphicon glyphicon-text-background\"> glyphicon-text-background </span>\n                                    <br/>\n                                    <span class=\"glyphicon glyphicon-object-align-top\"> glyphicon-object-align-top </span>\n                                    <br/>\n                                    <span class=\"glyphicon glyphicon-object-align-bottom\"> glyphicon-object-align-bottom </span>\n                                    <br/>\n                                    <span class=\"glyphicon glyphicon-object-align-horizontal\"> glyphicon-object-align-horizontal </span>\n                                    <br/>\n                                    <span class=\"glyphicon glyphicon-object-align-left\"> glyphicon-object-align-left </span>\n                                    <br/>\n                                    <span class=\"glyphicon glyphicon-object-align-vertical\"> glyphicon-object-align-vertical </span>\n                                    <br/>\n                                    <span class=\"glyphicon glyphicon-object-align-right\"> glyphicon-object-align-right </span>\n                                    <br/>\n                                    <span class=\"glyphicon glyphicon-triangle-right\"> glyphicon-triangle-right </span>\n                                    <br/>\n                                    <span class=\"glyphicon glyphicon-triangle-left\"> glyphicon-triangle-left </span>\n                                    <br/>\n                                    <span class=\"glyphicon glyphicon-triangle-bottom\"> glyphicon-triangle-bottom </span>\n                                    <br/>\n                                    <span class=\"glyphicon glyphicon-triangle-top\"> glyphicon-triangle-top </span>\n                                    <br/>\n                                    <span class=\"glyphicon glyphicon-console\"> glyphicon-console </span>\n                                    <br/>\n                                    <span class=\"glyphicon glyphicon-superscript\"> glyphicon-superscript </span>\n                                    <br/>\n                                    <span class=\"glyphicon glyphicon-subscript\"> glyphicon-subscript </span>\n                                    <br/>\n                                    <span class=\"glyphicon glyphicon-menu-left\"> glyphicon-menu-left </span>\n                                    <br/>\n                                    <span class=\"glyphicon glyphicon-menu-right\"> glyphicon-menu-right </span>\n                                    <br/>\n                                    <span class=\"glyphicon glyphicon-menu-down\"> glyphicon-menu-down </span>\n                                    <br/>\n                                    <span class=\"glyphicon glyphicon-menu-up\"> glyphicon-menu-up </span>\n                                    <br/>\n                                </div>\n\n                                <!-- /.col-lg-6 (nested) -->\n                            </div>\n                            <!-- /.row (nested) -->\n                        </div>\n                        <!-- /.panel-body -->\n                    </div>\n                    <!-- /.panel -->\n                </div>\n                <!-- /.col-lg-12 -->\n            </div>\n            <!-- /.row -->\n        </div>\n        <!-- /#page-wrapper -->\n\n    </div>\n    <!-- /#wrapper -->\n\n    <!-- jQuery -->\n    <script src=\"../vendor/jquery/jquery.min.js\"></script>\n\n    <!-- Bootstrap Core JavaScript -->\n    <script src=\"../vendor/bootstrap/js/bootstrap.min.js\"></script>\n\n    <!-- Metis Menu Plugin JavaScript -->\n    <script src=\"../vendor/metisMenu/metisMenu.min.js\"></script>\n\n    <!-- Custom Theme JavaScript -->\n    <script src=\"../dist/js/sb-admin-2.js\"></script>\n\n</body>\n\n</html>\n"
  },
  {
    "path": "app_backend/pages/index.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n\n<head>\n\n    <meta charset=\"utf-8\">\n    <meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\">\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">\n    <meta name=\"description\" content=\"\">\n    <meta name=\"author\" content=\"\">\n\n    <title>SB Admin 2 - Bootstrap Admin Theme</title>\n\n    <!-- Bootstrap Core CSS -->\n    <link href=\"../vendor/bootstrap/css/bootstrap.min.css\" rel=\"stylesheet\">\n\n    <!-- MetisMenu CSS -->\n    <link href=\"../vendor/metisMenu/metisMenu.min.css\" rel=\"stylesheet\">\n\n    <!-- Custom CSS -->\n    <link href=\"../dist/css/sb-admin-2.css\" rel=\"stylesheet\">\n\n    <!-- Morris Charts CSS -->\n    <link href=\"../vendor/morrisjs/morris.css\" rel=\"stylesheet\">\n\n    <!-- Custom Fonts -->\n    <link href=\"../vendor/font-awesome/css/font-awesome.min.css\" rel=\"stylesheet\" type=\"text/css\">\n\n    <!-- HTML5 Shim and Respond.js IE8 support of HTML5 elements and media queries -->\n    <!-- WARNING: Respond.js doesn't work if you view the page via file:// -->\n    <!--[if lt IE 9]>\n        <script src=\"https://oss.maxcdn.com/libs/html5shiv/3.7.0/html5shiv.js\"></script>\n        <script src=\"https://oss.maxcdn.com/libs/respond.js/1.4.2/respond.min.js\"></script>\n    <![endif]-->\n\n</head>\n\n<body>\n\n    <div id=\"wrapper\">\n\n        <!-- Navigation -->\n        <nav class=\"navbar navbar-default navbar-static-top\" role=\"navigation\" style=\"margin-bottom: 0\">\n            <div class=\"navbar-header\">\n                <button type=\"button\" class=\"navbar-toggle\" data-toggle=\"collapse\" data-target=\".navbar-collapse\">\n                    <span class=\"sr-only\">Toggle navigation</span>\n                    <span class=\"icon-bar\"></span>\n                    <span class=\"icon-bar\"></span>\n                    <span class=\"icon-bar\"></span>\n                </button>\n                <a class=\"navbar-brand\" href=\"index.html\">SB Admin v2.0</a>\n            </div>\n            <!-- /.navbar-header -->\n\n            <ul class=\"nav navbar-top-links navbar-right\">\n                <li class=\"dropdown\">\n                    <a class=\"dropdown-toggle\" data-toggle=\"dropdown\" href=\"#\">\n                        <i class=\"fa fa-envelope fa-fw\"></i> <i class=\"fa fa-caret-down\"></i>\n                    </a>\n                    <ul class=\"dropdown-menu dropdown-messages\">\n                        <li>\n                            <a href=\"#\">\n                                <div>\n                                    <strong>John Smith</strong>\n                                    <span class=\"pull-right text-muted\">\n                                        <em>Yesterday</em>\n                                    </span>\n                                </div>\n                                <div>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque eleifend...</div>\n                            </a>\n                        </li>\n                        <li class=\"divider\"></li>\n                        <li>\n                            <a href=\"#\">\n                                <div>\n                                    <strong>John Smith</strong>\n                                    <span class=\"pull-right text-muted\">\n                                        <em>Yesterday</em>\n                                    </span>\n                                </div>\n                                <div>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque eleifend...</div>\n                            </a>\n                        </li>\n                        <li class=\"divider\"></li>\n                        <li>\n                            <a href=\"#\">\n                                <div>\n                                    <strong>John Smith</strong>\n                                    <span class=\"pull-right text-muted\">\n                                        <em>Yesterday</em>\n                                    </span>\n                                </div>\n                                <div>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque eleifend...</div>\n                            </a>\n                        </li>\n                        <li class=\"divider\"></li>\n                        <li>\n                            <a class=\"text-center\" href=\"#\">\n                                <strong>Read All Messages</strong>\n                                <i class=\"fa fa-angle-right\"></i>\n                            </a>\n                        </li>\n                    </ul>\n                    <!-- /.dropdown-messages -->\n                </li>\n                <!-- /.dropdown -->\n                <li class=\"dropdown\">\n                    <a class=\"dropdown-toggle\" data-toggle=\"dropdown\" href=\"#\">\n                        <i class=\"fa fa-tasks fa-fw\"></i> <i class=\"fa fa-caret-down\"></i>\n                    </a>\n                    <ul class=\"dropdown-menu dropdown-tasks\">\n                        <li>\n                            <a href=\"#\">\n                                <div>\n                                    <p>\n                                        <strong>Task 1</strong>\n                                        <span class=\"pull-right text-muted\">40% Complete</span>\n                                    </p>\n                                    <div class=\"progress progress-striped active\">\n                                        <div class=\"progress-bar progress-bar-success\" role=\"progressbar\" aria-valuenow=\"40\" aria-valuemin=\"0\" aria-valuemax=\"100\" style=\"width: 40%\">\n                                            <span class=\"sr-only\">40% Complete (success)</span>\n                                        </div>\n                                    </div>\n                                </div>\n                            </a>\n                        </li>\n                        <li class=\"divider\"></li>\n                        <li>\n                            <a href=\"#\">\n                                <div>\n                                    <p>\n                                        <strong>Task 2</strong>\n                                        <span class=\"pull-right text-muted\">20% Complete</span>\n                                    </p>\n                                    <div class=\"progress progress-striped active\">\n                                        <div class=\"progress-bar progress-bar-info\" role=\"progressbar\" aria-valuenow=\"20\" aria-valuemin=\"0\" aria-valuemax=\"100\" style=\"width: 20%\">\n                                            <span class=\"sr-only\">20% Complete</span>\n                                        </div>\n                                    </div>\n                                </div>\n                            </a>\n                        </li>\n                        <li class=\"divider\"></li>\n                        <li>\n                            <a href=\"#\">\n                                <div>\n                                    <p>\n                                        <strong>Task 3</strong>\n                                        <span class=\"pull-right text-muted\">60% Complete</span>\n                                    </p>\n                                    <div class=\"progress progress-striped active\">\n                                        <div class=\"progress-bar progress-bar-warning\" role=\"progressbar\" aria-valuenow=\"60\" aria-valuemin=\"0\" aria-valuemax=\"100\" style=\"width: 60%\">\n                                            <span class=\"sr-only\">60% Complete (warning)</span>\n                                        </div>\n                                    </div>\n                                </div>\n                            </a>\n                        </li>\n                        <li class=\"divider\"></li>\n                        <li>\n                            <a href=\"#\">\n                                <div>\n                                    <p>\n                                        <strong>Task 4</strong>\n                                        <span class=\"pull-right text-muted\">80% Complete</span>\n                                    </p>\n                                    <div class=\"progress progress-striped active\">\n                                        <div class=\"progress-bar progress-bar-danger\" role=\"progressbar\" aria-valuenow=\"80\" aria-valuemin=\"0\" aria-valuemax=\"100\" style=\"width: 80%\">\n                                            <span class=\"sr-only\">80% Complete (danger)</span>\n                                        </div>\n                                    </div>\n                                </div>\n                            </a>\n                        </li>\n                        <li class=\"divider\"></li>\n                        <li>\n                            <a class=\"text-center\" href=\"#\">\n                                <strong>See All Tasks</strong>\n                                <i class=\"fa fa-angle-right\"></i>\n                            </a>\n                        </li>\n                    </ul>\n                    <!-- /.dropdown-tasks -->\n                </li>\n                <!-- /.dropdown -->\n                <li class=\"dropdown\">\n                    <a class=\"dropdown-toggle\" data-toggle=\"dropdown\" href=\"#\">\n                        <i class=\"fa fa-bell fa-fw\"></i> <i class=\"fa fa-caret-down\"></i>\n                    </a>\n                    <ul class=\"dropdown-menu dropdown-alerts\">\n                        <li>\n                            <a href=\"#\">\n                                <div>\n                                    <i class=\"fa fa-comment fa-fw\"></i> New Comment\n                                    <span class=\"pull-right text-muted small\">4 minutes ago</span>\n                                </div>\n                            </a>\n                        </li>\n                        <li class=\"divider\"></li>\n                        <li>\n                            <a href=\"#\">\n                                <div>\n                                    <i class=\"fa fa-twitter fa-fw\"></i> 3 New Followers\n                                    <span class=\"pull-right text-muted small\">12 minutes ago</span>\n                                </div>\n                            </a>\n                        </li>\n                        <li class=\"divider\"></li>\n                        <li>\n                            <a href=\"#\">\n                                <div>\n                                    <i class=\"fa fa-envelope fa-fw\"></i> Message Sent\n                                    <span class=\"pull-right text-muted small\">4 minutes ago</span>\n                                </div>\n                            </a>\n                        </li>\n                        <li class=\"divider\"></li>\n                        <li>\n                            <a href=\"#\">\n                                <div>\n                                    <i class=\"fa fa-tasks fa-fw\"></i> New Task\n                                    <span class=\"pull-right text-muted small\">4 minutes ago</span>\n                                </div>\n                            </a>\n                        </li>\n                        <li class=\"divider\"></li>\n                        <li>\n                            <a href=\"#\">\n                                <div>\n                                    <i class=\"fa fa-upload fa-fw\"></i> Server Rebooted\n                                    <span class=\"pull-right text-muted small\">4 minutes ago</span>\n                                </div>\n                            </a>\n                        </li>\n                        <li class=\"divider\"></li>\n                        <li>\n                            <a class=\"text-center\" href=\"#\">\n                                <strong>See All Alerts</strong>\n                                <i class=\"fa fa-angle-right\"></i>\n                            </a>\n                        </li>\n                    </ul>\n                    <!-- /.dropdown-alerts -->\n                </li>\n                <!-- /.dropdown -->\n                <li class=\"dropdown\">\n                    <a class=\"dropdown-toggle\" data-toggle=\"dropdown\" href=\"#\">\n                        <i class=\"fa fa-user fa-fw\"></i> <i class=\"fa fa-caret-down\"></i>\n                    </a>\n                    <ul class=\"dropdown-menu dropdown-user\">\n                        <li><a href=\"#\"><i class=\"fa fa-user fa-fw\"></i> User Profile</a>\n                        </li>\n                        <li><a href=\"#\"><i class=\"fa fa-gear fa-fw\"></i> Settings</a>\n                        </li>\n                        <li class=\"divider\"></li>\n                        <li><a href=\"login.html\"><i class=\"fa fa-sign-out fa-fw\"></i> Logout</a>\n                        </li>\n                    </ul>\n                    <!-- /.dropdown-user -->\n                </li>\n                <!-- /.dropdown -->\n            </ul>\n            <!-- /.navbar-top-links -->\n\n            <div class=\"navbar-default sidebar\" role=\"navigation\">\n                <div class=\"sidebar-nav navbar-collapse\">\n                    <ul class=\"nav\" id=\"side-menu\">\n                        <li class=\"sidebar-search\">\n                            <div class=\"input-group custom-search-form\">\n                                <input type=\"text\" class=\"form-control\" placeholder=\"Search...\">\n                                <span class=\"input-group-btn\">\n                                <button class=\"btn btn-default\" type=\"button\">\n                                    <i class=\"fa fa-search\"></i>\n                                </button>\n                            </span>\n                            </div>\n                            <!-- /input-group -->\n                        </li>\n                        <li>\n                            <a href=\"index.html\"><i class=\"fa fa-dashboard fa-fw\"></i> Dashboard</a>\n                        </li>\n                        <li>\n                            <a href=\"#\"><i class=\"fa fa-bar-chart-o fa-fw\"></i> Charts<span class=\"fa arrow\"></span></a>\n                            <ul class=\"nav nav-second-level\">\n                                <li>\n                                    <a href=\"flot.html\">Flot Charts</a>\n                                </li>\n                                <li>\n                                    <a href=\"morris.html\">Morris.js Charts</a>\n                                </li>\n                            </ul>\n                            <!-- /.nav-second-level -->\n                        </li>\n                        <li>\n                            <a href=\"tables.html\"><i class=\"fa fa-table fa-fw\"></i> Tables</a>\n                        </li>\n                        <li>\n                            <a href=\"forms.html\"><i class=\"fa fa-edit fa-fw\"></i> Forms</a>\n                        </li>\n                        <li>\n                            <a href=\"#\"><i class=\"fa fa-wrench fa-fw\"></i> UI Elements<span class=\"fa arrow\"></span></a>\n                            <ul class=\"nav nav-second-level\">\n                                <li>\n                                    <a href=\"panels-wells.html\">Panels and Wells</a>\n                                </li>\n                                <li>\n                                    <a href=\"buttons.html\">Buttons</a>\n                                </li>\n                                <li>\n                                    <a href=\"notifications.html\">Notifications</a>\n                                </li>\n                                <li>\n                                    <a href=\"typography.html\">Typography</a>\n                                </li>\n                                <li>\n                                    <a href=\"icons.html\"> Icons</a>\n                                </li>\n                                <li>\n                                    <a href=\"grid.html\">Grid</a>\n                                </li>\n                            </ul>\n                            <!-- /.nav-second-level -->\n                        </li>\n                        <li>\n                            <a href=\"#\"><i class=\"fa fa-sitemap fa-fw\"></i> Multi-Level Dropdown<span class=\"fa arrow\"></span></a>\n                            <ul class=\"nav nav-second-level\">\n                                <li>\n                                    <a href=\"#\">Second Level Item</a>\n                                </li>\n                                <li>\n                                    <a href=\"#\">Second Level Item</a>\n                                </li>\n                                <li>\n                                    <a href=\"#\">Third Level <span class=\"fa arrow\"></span></a>\n                                    <ul class=\"nav nav-third-level\">\n                                        <li>\n                                            <a href=\"#\">Third Level Item</a>\n                                        </li>\n                                        <li>\n                                            <a href=\"#\">Third Level Item</a>\n                                        </li>\n                                        <li>\n                                            <a href=\"#\">Third Level Item</a>\n                                        </li>\n                                        <li>\n                                            <a href=\"#\">Third Level Item</a>\n                                        </li>\n                                    </ul>\n                                    <!-- /.nav-third-level -->\n                                </li>\n                            </ul>\n                            <!-- /.nav-second-level -->\n                        </li>\n                        <li>\n                            <a href=\"#\"><i class=\"fa fa-files-o fa-fw\"></i> Sample Pages<span class=\"fa arrow\"></span></a>\n                            <ul class=\"nav nav-second-level\">\n                                <li>\n                                    <a href=\"blank.html\">Blank Page</a>\n                                </li>\n                                <li>\n                                    <a href=\"login.html\">Login Page</a>\n                                </li>\n                            </ul>\n                            <!-- /.nav-second-level -->\n                        </li>\n                    </ul>\n                </div>\n                <!-- /.sidebar-collapse -->\n            </div>\n            <!-- /.navbar-static-side -->\n        </nav>\n\n        <div id=\"page-wrapper\">\n            <div class=\"row\">\n                <div class=\"col-lg-12\">\n                    <h1 class=\"page-header\">Dashboard</h1>\n                </div>\n                <!-- /.col-lg-12 -->\n            </div>\n            <!-- /.row -->\n            <div class=\"row\">\n                <div class=\"col-lg-3 col-md-6\">\n                    <div class=\"panel panel-primary\">\n                        <div class=\"panel-heading\">\n                            <div class=\"row\">\n                                <div class=\"col-xs-3\">\n                                    <i class=\"fa fa-comments fa-5x\"></i>\n                                </div>\n                                <div class=\"col-xs-9 text-right\">\n                                    <div class=\"huge\">26</div>\n                                    <div>New Comments!</div>\n                                </div>\n                            </div>\n                        </div>\n                        <a href=\"#\">\n                            <div class=\"panel-footer\">\n                                <span class=\"pull-left\">View Details</span>\n                                <span class=\"pull-right\"><i class=\"fa fa-arrow-circle-right\"></i></span>\n                                <div class=\"clearfix\"></div>\n                            </div>\n                        </a>\n                    </div>\n                </div>\n                <div class=\"col-lg-3 col-md-6\">\n                    <div class=\"panel panel-green\">\n                        <div class=\"panel-heading\">\n                            <div class=\"row\">\n                                <div class=\"col-xs-3\">\n                                    <i class=\"fa fa-tasks fa-5x\"></i>\n                                </div>\n                                <div class=\"col-xs-9 text-right\">\n                                    <div class=\"huge\">12</div>\n                                    <div>New Tasks!</div>\n                                </div>\n                            </div>\n                        </div>\n                        <a href=\"#\">\n                            <div class=\"panel-footer\">\n                                <span class=\"pull-left\">View Details</span>\n                                <span class=\"pull-right\"><i class=\"fa fa-arrow-circle-right\"></i></span>\n                                <div class=\"clearfix\"></div>\n                            </div>\n                        </a>\n                    </div>\n                </div>\n                <div class=\"col-lg-3 col-md-6\">\n                    <div class=\"panel panel-yellow\">\n                        <div class=\"panel-heading\">\n                            <div class=\"row\">\n                                <div class=\"col-xs-3\">\n                                    <i class=\"fa fa-shopping-cart fa-5x\"></i>\n                                </div>\n                                <div class=\"col-xs-9 text-right\">\n                                    <div class=\"huge\">124</div>\n                                    <div>New Orders!</div>\n                                </div>\n                            </div>\n                        </div>\n                        <a href=\"#\">\n                            <div class=\"panel-footer\">\n                                <span class=\"pull-left\">View Details</span>\n                                <span class=\"pull-right\"><i class=\"fa fa-arrow-circle-right\"></i></span>\n                                <div class=\"clearfix\"></div>\n                            </div>\n                        </a>\n                    </div>\n                </div>\n                <div class=\"col-lg-3 col-md-6\">\n                    <div class=\"panel panel-red\">\n                        <div class=\"panel-heading\">\n                            <div class=\"row\">\n                                <div class=\"col-xs-3\">\n                                    <i class=\"fa fa-support fa-5x\"></i>\n                                </div>\n                                <div class=\"col-xs-9 text-right\">\n                                    <div class=\"huge\">13</div>\n                                    <div>Support Tickets!</div>\n                                </div>\n                            </div>\n                        </div>\n                        <a href=\"#\">\n                            <div class=\"panel-footer\">\n                                <span class=\"pull-left\">View Details</span>\n                                <span class=\"pull-right\"><i class=\"fa fa-arrow-circle-right\"></i></span>\n                                <div class=\"clearfix\"></div>\n                            </div>\n                        </a>\n                    </div>\n                </div>\n            </div>\n            <!-- /.row -->\n            <div class=\"row\">\n                <div class=\"col-lg-8\">\n                    <div class=\"panel panel-default\">\n                        <div class=\"panel-heading\">\n                            <i class=\"fa fa-bar-chart-o fa-fw\"></i> Area Chart Example\n                            <div class=\"pull-right\">\n                                <div class=\"btn-group\">\n                                    <button type=\"button\" class=\"btn btn-default btn-xs dropdown-toggle\" data-toggle=\"dropdown\">\n                                        Actions\n                                        <span class=\"caret\"></span>\n                                    </button>\n                                    <ul class=\"dropdown-menu pull-right\" role=\"menu\">\n                                        <li><a href=\"#\">Action</a>\n                                        </li>\n                                        <li><a href=\"#\">Another action</a>\n                                        </li>\n                                        <li><a href=\"#\">Something else here</a>\n                                        </li>\n                                        <li class=\"divider\"></li>\n                                        <li><a href=\"#\">Separated link</a>\n                                        </li>\n                                    </ul>\n                                </div>\n                            </div>\n                        </div>\n                        <!-- /.panel-heading -->\n                        <div class=\"panel-body\">\n                            <div id=\"morris-area-chart\"></div>\n                        </div>\n                        <!-- /.panel-body -->\n                    </div>\n                    <!-- /.panel -->\n                    <div class=\"panel panel-default\">\n                        <div class=\"panel-heading\">\n                            <i class=\"fa fa-bar-chart-o fa-fw\"></i> Bar Chart Example\n                            <div class=\"pull-right\">\n                                <div class=\"btn-group\">\n                                    <button type=\"button\" class=\"btn btn-default btn-xs dropdown-toggle\" data-toggle=\"dropdown\">\n                                        Actions\n                                        <span class=\"caret\"></span>\n                                    </button>\n                                    <ul class=\"dropdown-menu pull-right\" role=\"menu\">\n                                        <li><a href=\"#\">Action</a>\n                                        </li>\n                                        <li><a href=\"#\">Another action</a>\n                                        </li>\n                                        <li><a href=\"#\">Something else here</a>\n                                        </li>\n                                        <li class=\"divider\"></li>\n                                        <li><a href=\"#\">Separated link</a>\n                                        </li>\n                                    </ul>\n                                </div>\n                            </div>\n                        </div>\n                        <!-- /.panel-heading -->\n                        <div class=\"panel-body\">\n                            <div class=\"row\">\n                                <div class=\"col-lg-4\">\n                                    <div class=\"table-responsive\">\n                                        <table class=\"table table-bordered table-hover table-striped\">\n                                            <thead>\n                                                <tr>\n                                                    <th>#</th>\n                                                    <th>Date</th>\n                                                    <th>Time</th>\n                                                    <th>Amount</th>\n                                                </tr>\n                                            </thead>\n                                            <tbody>\n                                                <tr>\n                                                    <td>3326</td>\n                                                    <td>10/21/2013</td>\n                                                    <td>3:29 PM</td>\n                                                    <td>$321.33</td>\n                                                </tr>\n                                                <tr>\n                                                    <td>3325</td>\n                                                    <td>10/21/2013</td>\n                                                    <td>3:20 PM</td>\n                                                    <td>$234.34</td>\n                                                </tr>\n                                                <tr>\n                                                    <td>3324</td>\n                                                    <td>10/21/2013</td>\n                                                    <td>3:03 PM</td>\n                                                    <td>$724.17</td>\n                                                </tr>\n                                                <tr>\n                                                    <td>3323</td>\n                                                    <td>10/21/2013</td>\n                                                    <td>3:00 PM</td>\n                                                    <td>$23.71</td>\n                                                </tr>\n                                                <tr>\n                                                    <td>3322</td>\n                                                    <td>10/21/2013</td>\n                                                    <td>2:49 PM</td>\n                                                    <td>$8345.23</td>\n                                                </tr>\n                                                <tr>\n                                                    <td>3321</td>\n                                                    <td>10/21/2013</td>\n                                                    <td>2:23 PM</td>\n                                                    <td>$245.12</td>\n                                                </tr>\n                                                <tr>\n                                                    <td>3320</td>\n                                                    <td>10/21/2013</td>\n                                                    <td>2:15 PM</td>\n                                                    <td>$5663.54</td>\n                                                </tr>\n                                                <tr>\n                                                    <td>3319</td>\n                                                    <td>10/21/2013</td>\n                                                    <td>2:13 PM</td>\n                                                    <td>$943.45</td>\n                                                </tr>\n                                            </tbody>\n                                        </table>\n                                    </div>\n                                    <!-- /.table-responsive -->\n                                </div>\n                                <!-- /.col-lg-4 (nested) -->\n                                <div class=\"col-lg-8\">\n                                    <div id=\"morris-bar-chart\"></div>\n                                </div>\n                                <!-- /.col-lg-8 (nested) -->\n                            </div>\n                            <!-- /.row -->\n                        </div>\n                        <!-- /.panel-body -->\n                    </div>\n                    <!-- /.panel -->\n                    <div class=\"panel panel-default\">\n                        <div class=\"panel-heading\">\n                            <i class=\"fa fa-clock-o fa-fw\"></i> Responsive Timeline\n                        </div>\n                        <!-- /.panel-heading -->\n                        <div class=\"panel-body\">\n                            <ul class=\"timeline\">\n                                <li>\n                                    <div class=\"timeline-badge\"><i class=\"fa fa-check\"></i>\n                                    </div>\n                                    <div class=\"timeline-panel\">\n                                        <div class=\"timeline-heading\">\n                                            <h4 class=\"timeline-title\">Lorem ipsum dolor</h4>\n                                            <p><small class=\"text-muted\"><i class=\"fa fa-clock-o\"></i> 11 hours ago via Twitter</small>\n                                            </p>\n                                        </div>\n                                        <div class=\"timeline-body\">\n                                            <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Libero laboriosam dolor perspiciatis omnis exercitationem. Beatae, officia pariatur? Est cum veniam excepturi. Maiores praesentium, porro voluptas suscipit facere rem dicta, debitis.</p>\n                                        </div>\n                                    </div>\n                                </li>\n                                <li class=\"timeline-inverted\">\n                                    <div class=\"timeline-badge warning\"><i class=\"fa fa-credit-card\"></i>\n                                    </div>\n                                    <div class=\"timeline-panel\">\n                                        <div class=\"timeline-heading\">\n                                            <h4 class=\"timeline-title\">Lorem ipsum dolor</h4>\n                                        </div>\n                                        <div class=\"timeline-body\">\n                                            <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Autem dolorem quibusdam, tenetur commodi provident cumque magni voluptatem libero, quis rerum. Fugiat esse debitis optio, tempore. Animi officiis alias, officia repellendus.</p>\n                                            <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Laudantium maiores odit qui est tempora eos, nostrum provident explicabo dignissimos debitis vel! Adipisci eius voluptates, ad aut recusandae minus eaque facere.</p>\n                                        </div>\n                                    </div>\n                                </li>\n                                <li>\n                                    <div class=\"timeline-badge danger\"><i class=\"fa fa-bomb\"></i>\n                                    </div>\n                                    <div class=\"timeline-panel\">\n                                        <div class=\"timeline-heading\">\n                                            <h4 class=\"timeline-title\">Lorem ipsum dolor</h4>\n                                        </div>\n                                        <div class=\"timeline-body\">\n                                            <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Repellendus numquam facilis enim eaque, tenetur nam id qui vel velit similique nihil iure molestias aliquam, voluptatem totam quaerat, magni commodi quisquam.</p>\n                                        </div>\n                                    </div>\n                                </li>\n                                <li class=\"timeline-inverted\">\n                                    <div class=\"timeline-panel\">\n                                        <div class=\"timeline-heading\">\n                                            <h4 class=\"timeline-title\">Lorem ipsum dolor</h4>\n                                        </div>\n                                        <div class=\"timeline-body\">\n                                            <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Voluptates est quaerat asperiores sapiente, eligendi, nihil. Itaque quos, alias sapiente rerum quas odit! Aperiam officiis quidem delectus libero, omnis ut debitis!</p>\n                                        </div>\n                                    </div>\n                                </li>\n                                <li>\n                                    <div class=\"timeline-badge info\"><i class=\"fa fa-save\"></i>\n                                    </div>\n                                    <div class=\"timeline-panel\">\n                                        <div class=\"timeline-heading\">\n                                            <h4 class=\"timeline-title\">Lorem ipsum dolor</h4>\n                                        </div>\n                                        <div class=\"timeline-body\">\n                                            <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Nobis minus modi quam ipsum alias at est molestiae excepturi delectus nesciunt, quibusdam debitis amet, beatae consequuntur impedit nulla qui! Laborum, atque.</p>\n                                            <hr>\n                                            <div class=\"btn-group\">\n                                                <button type=\"button\" class=\"btn btn-primary btn-sm dropdown-toggle\" data-toggle=\"dropdown\">\n                                                    <i class=\"fa fa-gear\"></i> <span class=\"caret\"></span>\n                                                </button>\n                                                <ul class=\"dropdown-menu\" role=\"menu\">\n                                                    <li><a href=\"#\">Action</a>\n                                                    </li>\n                                                    <li><a href=\"#\">Another action</a>\n                                                    </li>\n                                                    <li><a href=\"#\">Something else here</a>\n                                                    </li>\n                                                    <li class=\"divider\"></li>\n                                                    <li><a href=\"#\">Separated link</a>\n                                                    </li>\n                                                </ul>\n                                            </div>\n                                        </div>\n                                    </div>\n                                </li>\n                                <li>\n                                    <div class=\"timeline-panel\">\n                                        <div class=\"timeline-heading\">\n                                            <h4 class=\"timeline-title\">Lorem ipsum dolor</h4>\n                                        </div>\n                                        <div class=\"timeline-body\">\n                                            <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Sequi fuga odio quibusdam. Iure expedita, incidunt unde quis nam! Quod, quisquam. Officia quam qui adipisci quas consequuntur nostrum sequi. Consequuntur, commodi.</p>\n                                        </div>\n                                    </div>\n                                </li>\n                                <li class=\"timeline-inverted\">\n                                    <div class=\"timeline-badge success\"><i class=\"fa fa-graduation-cap\"></i>\n                                    </div>\n                                    <div class=\"timeline-panel\">\n                                        <div class=\"timeline-heading\">\n                                            <h4 class=\"timeline-title\">Lorem ipsum dolor</h4>\n                                        </div>\n                                        <div class=\"timeline-body\">\n                                            <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Deserunt obcaecati, quaerat tempore officia voluptas debitis consectetur culpa amet, accusamus dolorum fugiat, animi dicta aperiam, enim incidunt quisquam maxime neque eaque.</p>\n                                        </div>\n                                    </div>\n                                </li>\n                            </ul>\n                        </div>\n                        <!-- /.panel-body -->\n                    </div>\n                    <!-- /.panel -->\n                </div>\n                <!-- /.col-lg-8 -->\n                <div class=\"col-lg-4\">\n                    <div class=\"panel panel-default\">\n                        <div class=\"panel-heading\">\n                            <i class=\"fa fa-bell fa-fw\"></i> Notifications Panel\n                        </div>\n                        <!-- /.panel-heading -->\n                        <div class=\"panel-body\">\n                            <div class=\"list-group\">\n                                <a href=\"#\" class=\"list-group-item\">\n                                    <i class=\"fa fa-comment fa-fw\"></i> New Comment\n                                    <span class=\"pull-right text-muted small\"><em>4 minutes ago</em>\n                                    </span>\n                                </a>\n                                <a href=\"#\" class=\"list-group-item\">\n                                    <i class=\"fa fa-twitter fa-fw\"></i> 3 New Followers\n                                    <span class=\"pull-right text-muted small\"><em>12 minutes ago</em>\n                                    </span>\n                                </a>\n                                <a href=\"#\" class=\"list-group-item\">\n                                    <i class=\"fa fa-envelope fa-fw\"></i> Message Sent\n                                    <span class=\"pull-right text-muted small\"><em>27 minutes ago</em>\n                                    </span>\n                                </a>\n                                <a href=\"#\" class=\"list-group-item\">\n                                    <i class=\"fa fa-tasks fa-fw\"></i> New Task\n                                    <span class=\"pull-right text-muted small\"><em>43 minutes ago</em>\n                                    </span>\n                                </a>\n                                <a href=\"#\" class=\"list-group-item\">\n                                    <i class=\"fa fa-upload fa-fw\"></i> Server Rebooted\n                                    <span class=\"pull-right text-muted small\"><em>11:32 AM</em>\n                                    </span>\n                                </a>\n                                <a href=\"#\" class=\"list-group-item\">\n                                    <i class=\"fa fa-bolt fa-fw\"></i> Server Crashed!\n                                    <span class=\"pull-right text-muted small\"><em>11:13 AM</em>\n                                    </span>\n                                </a>\n                                <a href=\"#\" class=\"list-group-item\">\n                                    <i class=\"fa fa-warning fa-fw\"></i> Server Not Responding\n                                    <span class=\"pull-right text-muted small\"><em>10:57 AM</em>\n                                    </span>\n                                </a>\n                                <a href=\"#\" class=\"list-group-item\">\n                                    <i class=\"fa fa-shopping-cart fa-fw\"></i> New Order Placed\n                                    <span class=\"pull-right text-muted small\"><em>9:49 AM</em>\n                                    </span>\n                                </a>\n                                <a href=\"#\" class=\"list-group-item\">\n                                    <i class=\"fa fa-money fa-fw\"></i> Payment Received\n                                    <span class=\"pull-right text-muted small\"><em>Yesterday</em>\n                                    </span>\n                                </a>\n                            </div>\n                            <!-- /.list-group -->\n                            <a href=\"#\" class=\"btn btn-default btn-block\">View All Alerts</a>\n                        </div>\n                        <!-- /.panel-body -->\n                    </div>\n                    <!-- /.panel -->\n                    <div class=\"panel panel-default\">\n                        <div class=\"panel-heading\">\n                            <i class=\"fa fa-bar-chart-o fa-fw\"></i> Donut Chart Example\n                        </div>\n                        <div class=\"panel-body\">\n                            <div id=\"morris-donut-chart\"></div>\n                            <a href=\"#\" class=\"btn btn-default btn-block\">View Details</a>\n                        </div>\n                        <!-- /.panel-body -->\n                    </div>\n                    <!-- /.panel -->\n                    <div class=\"chat-panel panel panel-default\">\n                        <div class=\"panel-heading\">\n                            <i class=\"fa fa-comments fa-fw\"></i> Chat\n                            <div class=\"btn-group pull-right\">\n                                <button type=\"button\" class=\"btn btn-default btn-xs dropdown-toggle\" data-toggle=\"dropdown\">\n                                    <i class=\"fa fa-chevron-down\"></i>\n                                </button>\n                                <ul class=\"dropdown-menu slidedown\">\n                                    <li>\n                                        <a href=\"#\">\n                                            <i class=\"fa fa-refresh fa-fw\"></i> Refresh\n                                        </a>\n                                    </li>\n                                    <li>\n                                        <a href=\"#\">\n                                            <i class=\"fa fa-check-circle fa-fw\"></i> Available\n                                        </a>\n                                    </li>\n                                    <li>\n                                        <a href=\"#\">\n                                            <i class=\"fa fa-times fa-fw\"></i> Busy\n                                        </a>\n                                    </li>\n                                    <li>\n                                        <a href=\"#\">\n                                            <i class=\"fa fa-clock-o fa-fw\"></i> Away\n                                        </a>\n                                    </li>\n                                    <li class=\"divider\"></li>\n                                    <li>\n                                        <a href=\"#\">\n                                            <i class=\"fa fa-sign-out fa-fw\"></i> Sign Out\n                                        </a>\n                                    </li>\n                                </ul>\n                            </div>\n                        </div>\n                        <!-- /.panel-heading -->\n                        <div class=\"panel-body\">\n                            <ul class=\"chat\">\n                                <li class=\"left clearfix\">\n                                    <span class=\"chat-img pull-left\">\n                                        <img src=\"http://placehold.it/50/55C1E7/fff\" alt=\"User Avatar\" class=\"img-circle\" />\n                                    </span>\n                                    <div class=\"chat-body clearfix\">\n                                        <div class=\"header\">\n                                            <strong class=\"primary-font\">Jack Sparrow</strong>\n                                            <small class=\"pull-right text-muted\">\n                                                <i class=\"fa fa-clock-o fa-fw\"></i> 12 mins ago\n                                            </small>\n                                        </div>\n                                        <p>\n                                            Lorem ipsum dolor sit amet, consectetur adipiscing elit. Curabitur bibendum ornare dolor, quis ullamcorper ligula sodales.\n                                        </p>\n                                    </div>\n                                </li>\n                                <li class=\"right clearfix\">\n                                    <span class=\"chat-img pull-right\">\n                                        <img src=\"http://placehold.it/50/FA6F57/fff\" alt=\"User Avatar\" class=\"img-circle\" />\n                                    </span>\n                                    <div class=\"chat-body clearfix\">\n                                        <div class=\"header\">\n                                            <small class=\" text-muted\">\n                                                <i class=\"fa fa-clock-o fa-fw\"></i> 13 mins ago</small>\n                                            <strong class=\"pull-right primary-font\">Bhaumik Patel</strong>\n                                        </div>\n                                        <p>\n                                            Lorem ipsum dolor sit amet, consectetur adipiscing elit. Curabitur bibendum ornare dolor, quis ullamcorper ligula sodales.\n                                        </p>\n                                    </div>\n                                </li>\n                                <li class=\"left clearfix\">\n                                    <span class=\"chat-img pull-left\">\n                                        <img src=\"http://placehold.it/50/55C1E7/fff\" alt=\"User Avatar\" class=\"img-circle\" />\n                                    </span>\n                                    <div class=\"chat-body clearfix\">\n                                        <div class=\"header\">\n                                            <strong class=\"primary-font\">Jack Sparrow</strong>\n                                            <small class=\"pull-right text-muted\">\n                                                <i class=\"fa fa-clock-o fa-fw\"></i> 14 mins ago</small>\n                                        </div>\n                                        <p>\n                                            Lorem ipsum dolor sit amet, consectetur adipiscing elit. Curabitur bibendum ornare dolor, quis ullamcorper ligula sodales.\n                                        </p>\n                                    </div>\n                                </li>\n                                <li class=\"right clearfix\">\n                                    <span class=\"chat-img pull-right\">\n                                        <img src=\"http://placehold.it/50/FA6F57/fff\" alt=\"User Avatar\" class=\"img-circle\" />\n                                    </span>\n                                    <div class=\"chat-body clearfix\">\n                                        <div class=\"header\">\n                                            <small class=\" text-muted\">\n                                                <i class=\"fa fa-clock-o fa-fw\"></i> 15 mins ago</small>\n                                            <strong class=\"pull-right primary-font\">Bhaumik Patel</strong>\n                                        </div>\n                                        <p>\n                                            Lorem ipsum dolor sit amet, consectetur adipiscing elit. Curabitur bibendum ornare dolor, quis ullamcorper ligula sodales.\n                                        </p>\n                                    </div>\n                                </li>\n                            </ul>\n                        </div>\n                        <!-- /.panel-body -->\n                        <div class=\"panel-footer\">\n                            <div class=\"input-group\">\n                                <input id=\"btn-input\" type=\"text\" class=\"form-control input-sm\" placeholder=\"Type your message here...\" />\n                                <span class=\"input-group-btn\">\n                                    <button class=\"btn btn-warning btn-sm\" id=\"btn-chat\">\n                                        Send\n                                    </button>\n                                </span>\n                            </div>\n                        </div>\n                        <!-- /.panel-footer -->\n                    </div>\n                    <!-- /.panel .chat-panel -->\n                </div>\n                <!-- /.col-lg-4 -->\n            </div>\n            <!-- /.row -->\n        </div>\n        <!-- /#page-wrapper -->\n\n    </div>\n    <!-- /#wrapper -->\n\n    <!-- jQuery -->\n    <script src=\"../vendor/jquery/jquery.min.js\"></script>\n\n    <!-- Bootstrap Core JavaScript -->\n    <script src=\"../vendor/bootstrap/js/bootstrap.min.js\"></script>\n\n    <!-- Metis Menu Plugin JavaScript -->\n    <script src=\"../vendor/metisMenu/metisMenu.min.js\"></script>\n\n    <!-- Morris Charts JavaScript -->\n    <script src=\"../vendor/raphael/raphael.min.js\"></script>\n    <script src=\"../vendor/morrisjs/morris.min.js\"></script>\n    <script src=\"../data/morris-data.js\"></script>\n\n    <!-- Custom Theme JavaScript -->\n    <script src=\"../dist/js/sb-admin-2.js\"></script>\n\n</body>\n\n</html>\n"
  },
  {
    "path": "app_backend/pages/login.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n\n<head>\n\n    <meta charset=\"utf-8\">\n    <meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\">\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">\n    <meta name=\"description\" content=\"\">\n    <meta name=\"author\" content=\"\">\n\n    <title>SB Admin 2 - Bootstrap Admin Theme</title>\n\n    <!-- Bootstrap Core CSS -->\n    <link href=\"../vendor/bootstrap/css/bootstrap.min.css\" rel=\"stylesheet\">\n\n    <!-- MetisMenu CSS -->\n    <link href=\"../vendor/metisMenu/metisMenu.min.css\" rel=\"stylesheet\">\n\n    <!-- Custom CSS -->\n    <link href=\"../dist/css/sb-admin-2.css\" rel=\"stylesheet\">\n\n    <!-- Custom Fonts -->\n    <link href=\"../vendor/font-awesome/css/font-awesome.min.css\" rel=\"stylesheet\" type=\"text/css\">\n\n    <!-- HTML5 Shim and Respond.js IE8 support of HTML5 elements and media queries -->\n    <!-- WARNING: Respond.js doesn't work if you view the page via file:// -->\n    <!--[if lt IE 9]>\n        <script src=\"https://oss.maxcdn.com/libs/html5shiv/3.7.0/html5shiv.js\"></script>\n        <script src=\"https://oss.maxcdn.com/libs/respond.js/1.4.2/respond.min.js\"></script>\n    <![endif]-->\n\n</head>\n\n<body>\n\n    <div class=\"container\">\n        <div class=\"row\">\n            <div class=\"col-md-4 col-md-offset-4\">\n                <div class=\"login-panel panel panel-default\">\n                    <div class=\"panel-heading\">\n                        <h3 class=\"panel-title\">Please Sign In</h3>\n                    </div>\n                    <div class=\"panel-body\">\n                        <form role=\"form\">\n                            <fieldset>\n                                <div class=\"form-group\">\n                                    <input class=\"form-control\" placeholder=\"E-mail\" name=\"email\" type=\"email\" autofocus>\n                                </div>\n                                <div class=\"form-group\">\n                                    <input class=\"form-control\" placeholder=\"Password\" name=\"password\" type=\"password\" value=\"\">\n                                </div>\n                                <div class=\"checkbox\">\n                                    <label>\n                                        <input name=\"remember\" type=\"checkbox\" value=\"Remember Me\">Remember Me\n                                    </label>\n                                </div>\n                                <!-- Change this to a button or input when using this as a form -->\n                                <a href=\"index.html\" class=\"btn btn-lg btn-success btn-block\">Login</a>\n                            </fieldset>\n                        </form>\n                    </div>\n                </div>\n            </div>\n        </div>\n    </div>\n\n    <!-- jQuery -->\n    <script src=\"../vendor/jquery/jquery.min.js\"></script>\n\n    <!-- Bootstrap Core JavaScript -->\n    <script src=\"../vendor/bootstrap/js/bootstrap.min.js\"></script>\n\n    <!-- Metis Menu Plugin JavaScript -->\n    <script src=\"../vendor/metisMenu/metisMenu.min.js\"></script>\n\n    <!-- Custom Theme JavaScript -->\n    <script src=\"../dist/js/sb-admin-2.js\"></script>\n\n</body>\n\n</html>\n"
  },
  {
    "path": "app_backend/pages/morris.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n\n<head>\n\n    <meta charset=\"utf-8\">\n    <meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\">\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">\n    <meta name=\"description\" content=\"\">\n    <meta name=\"author\" content=\"\">\n\n    <title>SB Admin 2 - Bootstrap Admin Theme</title>\n\n    <!-- Bootstrap Core CSS -->\n    <link href=\"../vendor/bootstrap/css/bootstrap.min.css\" rel=\"stylesheet\">\n\n    <!-- MetisMenu CSS -->\n    <link href=\"../vendor/metisMenu/metisMenu.min.css\" rel=\"stylesheet\">\n\n    <!-- Custom CSS -->\n    <link href=\"../dist/css/sb-admin-2.css\" rel=\"stylesheet\">\n\n    <!-- Morris Charts CSS -->\n    <link href=\"../vendor/morrisjs/morris.css\" rel=\"stylesheet\">\n\n    <!-- Custom Fonts -->\n    <link href=\"../vendor/font-awesome/css/font-awesome.min.css\" rel=\"stylesheet\" type=\"text/css\">\n\n    <!-- HTML5 Shim and Respond.js IE8 support of HTML5 elements and media queries -->\n    <!-- WARNING: Respond.js doesn't work if you view the page via file:// -->\n    <!--[if lt IE 9]>\n        <script src=\"https://oss.maxcdn.com/libs/html5shiv/3.7.0/html5shiv.js\"></script>\n        <script src=\"https://oss.maxcdn.com/libs/respond.js/1.4.2/respond.min.js\"></script>\n    <![endif]-->\n\n</head>\n\n<body>\n\n    <div id=\"wrapper\">\n\n        <!-- Navigation -->\n        <nav class=\"navbar navbar-default navbar-static-top\" role=\"navigation\" style=\"margin-bottom: 0\">\n            <div class=\"navbar-header\">\n                <button type=\"button\" class=\"navbar-toggle\" data-toggle=\"collapse\" data-target=\".navbar-collapse\">\n                    <span class=\"sr-only\">Toggle navigation</span>\n                    <span class=\"icon-bar\"></span>\n                    <span class=\"icon-bar\"></span>\n                    <span class=\"icon-bar\"></span>\n                </button>\n                <a class=\"navbar-brand\" href=\"index.html\">SB Admin v2.0</a>\n            </div>\n            <!-- /.navbar-header -->\n\n            <ul class=\"nav navbar-top-links navbar-right\">\n                <li class=\"dropdown\">\n                    <a class=\"dropdown-toggle\" data-toggle=\"dropdown\" href=\"#\">\n                        <i class=\"fa fa-envelope fa-fw\"></i> <i class=\"fa fa-caret-down\"></i>\n                    </a>\n                    <ul class=\"dropdown-menu dropdown-messages\">\n                        <li>\n                            <a href=\"#\">\n                                <div>\n                                    <strong>John Smith</strong>\n                                    <span class=\"pull-right text-muted\">\n                                        <em>Yesterday</em>\n                                    </span>\n                                </div>\n                                <div>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque eleifend...</div>\n                            </a>\n                        </li>\n                        <li class=\"divider\"></li>\n                        <li>\n                            <a href=\"#\">\n                                <div>\n                                    <strong>John Smith</strong>\n                                    <span class=\"pull-right text-muted\">\n                                        <em>Yesterday</em>\n                                    </span>\n                                </div>\n                                <div>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque eleifend...</div>\n                            </a>\n                        </li>\n                        <li class=\"divider\"></li>\n                        <li>\n                            <a href=\"#\">\n                                <div>\n                                    <strong>John Smith</strong>\n                                    <span class=\"pull-right text-muted\">\n                                        <em>Yesterday</em>\n                                    </span>\n                                </div>\n                                <div>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque eleifend...</div>\n                            </a>\n                        </li>\n                        <li class=\"divider\"></li>\n                        <li>\n                            <a class=\"text-center\" href=\"#\">\n                                <strong>Read All Messages</strong>\n                                <i class=\"fa fa-angle-right\"></i>\n                            </a>\n                        </li>\n                    </ul>\n                    <!-- /.dropdown-messages -->\n                </li>\n                <!-- /.dropdown -->\n                <li class=\"dropdown\">\n                    <a class=\"dropdown-toggle\" data-toggle=\"dropdown\" href=\"#\">\n                        <i class=\"fa fa-tasks fa-fw\"></i> <i class=\"fa fa-caret-down\"></i>\n                    </a>\n                    <ul class=\"dropdown-menu dropdown-tasks\">\n                        <li>\n                            <a href=\"#\">\n                                <div>\n                                    <p>\n                                        <strong>Task 1</strong>\n                                        <span class=\"pull-right text-muted\">40% Complete</span>\n                                    </p>\n                                    <div class=\"progress progress-striped active\">\n                                        <div class=\"progress-bar progress-bar-success\" role=\"progressbar\" aria-valuenow=\"40\" aria-valuemin=\"0\" aria-valuemax=\"100\" style=\"width: 40%\">\n                                            <span class=\"sr-only\">40% Complete (success)</span>\n                                        </div>\n                                    </div>\n                                </div>\n                            </a>\n                        </li>\n                        <li class=\"divider\"></li>\n                        <li>\n                            <a href=\"#\">\n                                <div>\n                                    <p>\n                                        <strong>Task 2</strong>\n                                        <span class=\"pull-right text-muted\">20% Complete</span>\n                                    </p>\n                                    <div class=\"progress progress-striped active\">\n                                        <div class=\"progress-bar progress-bar-info\" role=\"progressbar\" aria-valuenow=\"20\" aria-valuemin=\"0\" aria-valuemax=\"100\" style=\"width: 20%\">\n                                            <span class=\"sr-only\">20% Complete</span>\n                                        </div>\n                                    </div>\n                                </div>\n                            </a>\n                        </li>\n                        <li class=\"divider\"></li>\n                        <li>\n                            <a href=\"#\">\n                                <div>\n                                    <p>\n                                        <strong>Task 3</strong>\n                                        <span class=\"pull-right text-muted\">60% Complete</span>\n                                    </p>\n                                    <div class=\"progress progress-striped active\">\n                                        <div class=\"progress-bar progress-bar-warning\" role=\"progressbar\" aria-valuenow=\"60\" aria-valuemin=\"0\" aria-valuemax=\"100\" style=\"width: 60%\">\n                                            <span class=\"sr-only\">60% Complete (warning)</span>\n                                        </div>\n                                    </div>\n                                </div>\n                            </a>\n                        </li>\n                        <li class=\"divider\"></li>\n                        <li>\n                            <a href=\"#\">\n                                <div>\n                                    <p>\n                                        <strong>Task 4</strong>\n                                        <span class=\"pull-right text-muted\">80% Complete</span>\n                                    </p>\n                                    <div class=\"progress progress-striped active\">\n                                        <div class=\"progress-bar progress-bar-danger\" role=\"progressbar\" aria-valuenow=\"80\" aria-valuemin=\"0\" aria-valuemax=\"100\" style=\"width: 80%\">\n                                            <span class=\"sr-only\">80% Complete (danger)</span>\n                                        </div>\n                                    </div>\n                                </div>\n                            </a>\n                        </li>\n                        <li class=\"divider\"></li>\n                        <li>\n                            <a class=\"text-center\" href=\"#\">\n                                <strong>See All Tasks</strong>\n                                <i class=\"fa fa-angle-right\"></i>\n                            </a>\n                        </li>\n                    </ul>\n                    <!-- /.dropdown-tasks -->\n                </li>\n                <!-- /.dropdown -->\n                <li class=\"dropdown\">\n                    <a class=\"dropdown-toggle\" data-toggle=\"dropdown\" href=\"#\">\n                        <i class=\"fa fa-bell fa-fw\"></i> <i class=\"fa fa-caret-down\"></i>\n                    </a>\n                    <ul class=\"dropdown-menu dropdown-alerts\">\n                        <li>\n                            <a href=\"#\">\n                                <div>\n                                    <i class=\"fa fa-comment fa-fw\"></i> New Comment\n                                    <span class=\"pull-right text-muted small\">4 minutes ago</span>\n                                </div>\n                            </a>\n                        </li>\n                        <li class=\"divider\"></li>\n                        <li>\n                            <a href=\"#\">\n                                <div>\n                                    <i class=\"fa fa-twitter fa-fw\"></i> 3 New Followers\n                                    <span class=\"pull-right text-muted small\">12 minutes ago</span>\n                                </div>\n                            </a>\n                        </li>\n                        <li class=\"divider\"></li>\n                        <li>\n                            <a href=\"#\">\n                                <div>\n                                    <i class=\"fa fa-envelope fa-fw\"></i> Message Sent\n                                    <span class=\"pull-right text-muted small\">4 minutes ago</span>\n                                </div>\n                            </a>\n                        </li>\n                        <li class=\"divider\"></li>\n                        <li>\n                            <a href=\"#\">\n                                <div>\n                                    <i class=\"fa fa-tasks fa-fw\"></i> New Task\n                                    <span class=\"pull-right text-muted small\">4 minutes ago</span>\n                                </div>\n                            </a>\n                        </li>\n                        <li class=\"divider\"></li>\n                        <li>\n                            <a href=\"#\">\n                                <div>\n                                    <i class=\"fa fa-upload fa-fw\"></i> Server Rebooted\n                                    <span class=\"pull-right text-muted small\">4 minutes ago</span>\n                                </div>\n                            </a>\n                        </li>\n                        <li class=\"divider\"></li>\n                        <li>\n                            <a class=\"text-center\" href=\"#\">\n                                <strong>See All Alerts</strong>\n                                <i class=\"fa fa-angle-right\"></i>\n                            </a>\n                        </li>\n                    </ul>\n                    <!-- /.dropdown-alerts -->\n                </li>\n                <!-- /.dropdown -->\n                <li class=\"dropdown\">\n                    <a class=\"dropdown-toggle\" data-toggle=\"dropdown\" href=\"#\">\n                        <i class=\"fa fa-user fa-fw\"></i> <i class=\"fa fa-caret-down\"></i>\n                    </a>\n                    <ul class=\"dropdown-menu dropdown-user\">\n                        <li><a href=\"#\"><i class=\"fa fa-user fa-fw\"></i> User Profile</a>\n                        </li>\n                        <li><a href=\"#\"><i class=\"fa fa-gear fa-fw\"></i> Settings</a>\n                        </li>\n                        <li class=\"divider\"></li>\n                        <li><a href=\"login.html\"><i class=\"fa fa-sign-out fa-fw\"></i> Logout</a>\n                        </li>\n                    </ul>\n                    <!-- /.dropdown-user -->\n                </li>\n                <!-- /.dropdown -->\n            </ul>\n            <!-- /.navbar-top-links -->\n\n            <div class=\"navbar-default sidebar\" role=\"navigation\">\n                <div class=\"sidebar-nav navbar-collapse\">\n                    <ul class=\"nav\" id=\"side-menu\">\n                        <li class=\"sidebar-search\">\n                            <div class=\"input-group custom-search-form\">\n                                <input type=\"text\" class=\"form-control\" placeholder=\"Search...\">\n                                <span class=\"input-group-btn\">\n                                <button class=\"btn btn-default\" type=\"button\">\n                                    <i class=\"fa fa-search\"></i>\n                                </button>\n                            </span>\n                            </div>\n                            <!-- /input-group -->\n                        </li>\n                        <li>\n                            <a href=\"index.html\"><i class=\"fa fa-dashboard fa-fw\"></i> Dashboard</a>\n                        </li>\n                        <li>\n                            <a href=\"#\"><i class=\"fa fa-bar-chart-o fa-fw\"></i> Charts<span class=\"fa arrow\"></span></a>\n                            <ul class=\"nav nav-second-level\">\n                                <li>\n                                    <a href=\"flot.html\">Flot Charts</a>\n                                </li>\n                                <li>\n                                    <a href=\"morris.html\">Morris.js Charts</a>\n                                </li>\n                            </ul>\n                            <!-- /.nav-second-level -->\n                        </li>\n                        <li>\n                            <a href=\"tables.html\"><i class=\"fa fa-table fa-fw\"></i> Tables</a>\n                        </li>\n                        <li>\n                            <a href=\"forms.html\"><i class=\"fa fa-edit fa-fw\"></i> Forms</a>\n                        </li>\n                        <li>\n                            <a href=\"#\"><i class=\"fa fa-wrench fa-fw\"></i> UI Elements<span class=\"fa arrow\"></span></a>\n                            <ul class=\"nav nav-second-level\">\n                                <li>\n                                    <a href=\"panels-wells.html\">Panels and Wells</a>\n                                </li>\n                                <li>\n                                    <a href=\"buttons.html\">Buttons</a>\n                                </li>\n                                <li>\n                                    <a href=\"notifications.html\">Notifications</a>\n                                </li>\n                                <li>\n                                    <a href=\"typography.html\">Typography</a>\n                                </li>\n                                <li>\n                                    <a href=\"icons.html\"> Icons</a>\n                                </li>\n                                <li>\n                                    <a href=\"grid.html\">Grid</a>\n                                </li>\n                            </ul>\n                            <!-- /.nav-second-level -->\n                        </li>\n                        <li>\n                            <a href=\"#\"><i class=\"fa fa-sitemap fa-fw\"></i> Multi-Level Dropdown<span class=\"fa arrow\"></span></a>\n                            <ul class=\"nav nav-second-level\">\n                                <li>\n                                    <a href=\"#\">Second Level Item</a>\n                                </li>\n                                <li>\n                                    <a href=\"#\">Second Level Item</a>\n                                </li>\n                                <li>\n                                    <a href=\"#\">Third Level <span class=\"fa arrow\"></span></a>\n                                    <ul class=\"nav nav-third-level\">\n                                        <li>\n                                            <a href=\"#\">Third Level Item</a>\n                                        </li>\n                                        <li>\n                                            <a href=\"#\">Third Level Item</a>\n                                        </li>\n                                        <li>\n                                            <a href=\"#\">Third Level Item</a>\n                                        </li>\n                                        <li>\n                                            <a href=\"#\">Third Level Item</a>\n                                        </li>\n                                    </ul>\n                                    <!-- /.nav-third-level -->\n                                </li>\n                            </ul>\n                            <!-- /.nav-second-level -->\n                        </li>\n                        <li>\n                            <a href=\"#\"><i class=\"fa fa-files-o fa-fw\"></i> Sample Pages<span class=\"fa arrow\"></span></a>\n                            <ul class=\"nav nav-second-level\">\n                                <li>\n                                    <a href=\"blank.html\">Blank Page</a>\n                                </li>\n                                <li>\n                                    <a href=\"login.html\">Login Page</a>\n                                </li>\n                            </ul>\n                            <!-- /.nav-second-level -->\n                        </li>\n                    </ul>\n                </div>\n                <!-- /.sidebar-collapse -->\n            </div>\n            <!-- /.navbar-static-side -->\n        </nav>\n\n        <div id=\"page-wrapper\">\n            <div class=\"row\">\n                <div class=\"col-lg-12\">\n                    <h1 class=\"page-header\">Morris.js Charts</h1>\n                </div>\n                <!-- /.col-lg-12 -->\n            </div>\n            <!-- /.row -->\n            <div class=\"row\">\n                <div class=\"col-lg-6\">\n                    <div class=\"panel panel-default\">\n                        <div class=\"panel-heading\">\n                            Area Chart Example\n                        </div>\n                        <!-- /.panel-heading -->\n                        <div class=\"panel-body\">\n                            <div id=\"morris-area-chart\"></div>\n                        </div>\n                        <!-- /.panel-body -->\n                    </div>\n                    <!-- /.panel -->\n                </div>\n                <!-- /.col-lg-6 -->\n                <div class=\"col-lg-6\">\n                    <div class=\"panel panel-default\">\n                        <div class=\"panel-heading\">\n                            Bar Chart Example\n                        </div>\n                        <!-- /.panel-heading -->\n                        <div class=\"panel-body\">\n                            <div id=\"morris-bar-chart\"></div>\n                        </div>\n                        <!-- /.panel-body -->\n                    </div>\n                    <!-- /.panel -->\n                </div>\n                <!-- /.col-lg-6 -->\n                <div class=\"col-lg-6\">\n                    <div class=\"panel panel-default\">\n                        <div class=\"panel-heading\">\n                            Line Chart Example\n                        </div>\n                        <!-- /.panel-heading -->\n                        <div class=\"panel-body\">\n                            <div id=\"morris-line-chart\"></div>\n                        </div>\n                        <!-- /.panel-body -->\n                    </div>\n                    <!-- /.panel -->\n                </div>\n                <!-- /.col-lg-6 -->\n                <div class=\"col-lg-6\">\n                    <div class=\"panel panel-default\">\n                        <div class=\"panel-heading\">\n                            Donut Chart Example\n                        </div>\n                        <!-- /.panel-heading -->\n                        <div class=\"panel-body\">\n                            <div id=\"morris-donut-chart\"></div>\n                        </div>\n                        <!-- /.panel-body -->\n                    </div>\n                    <!-- /.panel -->\n                </div>\n                <!-- /.col-lg-6 -->\n                <div class=\"col-lg-12\">\n                    <div class=\"panel panel-default\">\n                        <div class=\"panel-heading\">\n                            Morris.js Usage\n                        </div>\n                        <!-- /.panel-heading -->\n                        <div class=\"panel-body\">\n                            <p>Morris.js is a jQuery based charting plugin created by Olly Smith. In SB Admin, we are using the most recent version of Morris.js which includes the resize function, which makes the charts fully responsive. The documentation for Morris.js is available on their website, <a target=\"_blank\" href=\"http://morrisjs.github.io/morris.js/\">http://morrisjs.github.io/morris.js/</a>.</p>\n                            <a target=\"_blank\" class=\"btn btn-default btn-lg btn-block\" href=\"http://morrisjs.github.io/morris.js/\">View Morris.js Documentation</a>\n                        </div>\n                        <!-- /.panel-body -->\n                    </div>\n                    <!-- /.panel -->\n                </div>\n                <!-- /.col-lg-6 -->\n            </div>\n            <!-- /.row -->\n        </div>\n        <!-- /#page-wrapper -->\n\n    </div>\n    <!-- /#wrapper -->\n\n    <!-- jQuery -->\n    <script src=\"../vendor/jquery/jquery.min.js\"></script>\n\n    <!-- Bootstrap Core JavaScript -->\n    <script src=\"../vendor/bootstrap/js/bootstrap.min.js\"></script>\n\n    <!-- Metis Menu Plugin JavaScript -->\n    <script src=\"../vendor/metisMenu/metisMenu.min.js\"></script>\n\n    <!-- Morris Charts JavaScript -->\n    <script src=\"../vendor/raphael/raphael.min.js\"></script>\n    <script src=\"../vendor/morrisjs/morris.min.js\"></script>\n    <script src=\"../data/morris-data.js\"></script>\n\n    <!-- Custom Theme JavaScript -->\n    <script src=\"../dist/js/sb-admin-2.js\"></script>\n\n</body>\n\n</html>\n"
  },
  {
    "path": "app_backend/pages/notifications.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n\n<head>\n\n    <meta charset=\"utf-8\">\n    <meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\">\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">\n    <meta name=\"description\" content=\"\">\n    <meta name=\"author\" content=\"\">\n\n    <title>SB Admin 2 - Bootstrap Admin Theme</title>\n\n    <!-- Bootstrap Core CSS -->\n    <link href=\"../vendor/bootstrap/css/bootstrap.min.css\" rel=\"stylesheet\">\n\n    <!-- MetisMenu CSS -->\n    <link href=\"../vendor/metisMenu/metisMenu.min.css\" rel=\"stylesheet\">\n\n    <!-- Custom CSS -->\n    <link href=\"../dist/css/sb-admin-2.css\" rel=\"stylesheet\">\n\n    <!-- Custom Fonts -->\n    <link href=\"../vendor/font-awesome/css/font-awesome.min.css\" rel=\"stylesheet\" type=\"text/css\">\n\n    <!-- HTML5 Shim and Respond.js IE8 support of HTML5 elements and media queries -->\n    <!-- WARNING: Respond.js doesn't work if you view the page via file:// -->\n    <!--[if lt IE 9]>\n        <script src=\"https://oss.maxcdn.com/libs/html5shiv/3.7.0/html5shiv.js\"></script>\n        <script src=\"https://oss.maxcdn.com/libs/respond.js/1.4.2/respond.min.js\"></script>\n    <![endif]-->\n\n</head>\n\n<body>\n\n    <div id=\"wrapper\">\n\n        <!-- Navigation -->\n        <nav class=\"navbar navbar-default navbar-static-top\" role=\"navigation\" style=\"margin-bottom: 0\">\n            <div class=\"navbar-header\">\n                <button type=\"button\" class=\"navbar-toggle\" data-toggle=\"collapse\" data-target=\".navbar-collapse\">\n                    <span class=\"sr-only\">Toggle navigation</span>\n                    <span class=\"icon-bar\"></span>\n                    <span class=\"icon-bar\"></span>\n                    <span class=\"icon-bar\"></span>\n                </button>\n                <a class=\"navbar-brand\" href=\"index.html\">SB Admin v2.0</a>\n            </div>\n            <!-- /.navbar-header -->\n\n            <ul class=\"nav navbar-top-links navbar-right\">\n                <li class=\"dropdown\">\n                    <a class=\"dropdown-toggle\" data-toggle=\"dropdown\" href=\"#\">\n                        <i class=\"fa fa-envelope fa-fw\"></i> <i class=\"fa fa-caret-down\"></i>\n                    </a>\n                    <ul class=\"dropdown-menu dropdown-messages\">\n                        <li>\n                            <a href=\"#\">\n                                <div>\n                                    <strong>John Smith</strong>\n                                    <span class=\"pull-right text-muted\">\n                                        <em>Yesterday</em>\n                                    </span>\n                                </div>\n                                <div>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque eleifend...</div>\n                            </a>\n                        </li>\n                        <li class=\"divider\"></li>\n                        <li>\n                            <a href=\"#\">\n                                <div>\n                                    <strong>John Smith</strong>\n                                    <span class=\"pull-right text-muted\">\n                                        <em>Yesterday</em>\n                                    </span>\n                                </div>\n                                <div>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque eleifend...</div>\n                            </a>\n                        </li>\n                        <li class=\"divider\"></li>\n                        <li>\n                            <a href=\"#\">\n                                <div>\n                                    <strong>John Smith</strong>\n                                    <span class=\"pull-right text-muted\">\n                                        <em>Yesterday</em>\n                                    </span>\n                                </div>\n                                <div>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque eleifend...</div>\n                            </a>\n                        </li>\n                        <li class=\"divider\"></li>\n                        <li>\n                            <a class=\"text-center\" href=\"#\">\n                                <strong>Read All Messages</strong>\n                                <i class=\"fa fa-angle-right\"></i>\n                            </a>\n                        </li>\n                    </ul>\n                    <!-- /.dropdown-messages -->\n                </li>\n                <!-- /.dropdown -->\n                <li class=\"dropdown\">\n                    <a class=\"dropdown-toggle\" data-toggle=\"dropdown\" href=\"#\">\n                        <i class=\"fa fa-tasks fa-fw\"></i> <i class=\"fa fa-caret-down\"></i>\n                    </a>\n                    <ul class=\"dropdown-menu dropdown-tasks\">\n                        <li>\n                            <a href=\"#\">\n                                <div>\n                                    <p>\n                                        <strong>Task 1</strong>\n                                        <span class=\"pull-right text-muted\">40% Complete</span>\n                                    </p>\n                                    <div class=\"progress progress-striped active\">\n                                        <div class=\"progress-bar progress-bar-success\" role=\"progressbar\" aria-valuenow=\"40\" aria-valuemin=\"0\" aria-valuemax=\"100\" style=\"width: 40%\">\n                                            <span class=\"sr-only\">40% Complete (success)</span>\n                                        </div>\n                                    </div>\n                                </div>\n                            </a>\n                        </li>\n                        <li class=\"divider\"></li>\n                        <li>\n                            <a href=\"#\">\n                                <div>\n                                    <p>\n                                        <strong>Task 2</strong>\n                                        <span class=\"pull-right text-muted\">20% Complete</span>\n                                    </p>\n                                    <div class=\"progress progress-striped active\">\n                                        <div class=\"progress-bar progress-bar-info\" role=\"progressbar\" aria-valuenow=\"20\" aria-valuemin=\"0\" aria-valuemax=\"100\" style=\"width: 20%\">\n                                            <span class=\"sr-only\">20% Complete</span>\n                                        </div>\n                                    </div>\n                                </div>\n                            </a>\n                        </li>\n                        <li class=\"divider\"></li>\n                        <li>\n                            <a href=\"#\">\n                                <div>\n                                    <p>\n                                        <strong>Task 3</strong>\n                                        <span class=\"pull-right text-muted\">60% Complete</span>\n                                    </p>\n                                    <div class=\"progress progress-striped active\">\n                                        <div class=\"progress-bar progress-bar-warning\" role=\"progressbar\" aria-valuenow=\"60\" aria-valuemin=\"0\" aria-valuemax=\"100\" style=\"width: 60%\">\n                                            <span class=\"sr-only\">60% Complete (warning)</span>\n                                        </div>\n                                    </div>\n                                </div>\n                            </a>\n                        </li>\n                        <li class=\"divider\"></li>\n                        <li>\n                            <a href=\"#\">\n                                <div>\n                                    <p>\n                                        <strong>Task 4</strong>\n                                        <span class=\"pull-right text-muted\">80% Complete</span>\n                                    </p>\n                                    <div class=\"progress progress-striped active\">\n                                        <div class=\"progress-bar progress-bar-danger\" role=\"progressbar\" aria-valuenow=\"80\" aria-valuemin=\"0\" aria-valuemax=\"100\" style=\"width: 80%\">\n                                            <span class=\"sr-only\">80% Complete (danger)</span>\n                                        </div>\n                                    </div>\n                                </div>\n                            </a>\n                        </li>\n                        <li class=\"divider\"></li>\n                        <li>\n                            <a class=\"text-center\" href=\"#\">\n                                <strong>See All Tasks</strong>\n                                <i class=\"fa fa-angle-right\"></i>\n                            </a>\n                        </li>\n                    </ul>\n                    <!-- /.dropdown-tasks -->\n                </li>\n                <!-- /.dropdown -->\n                <li class=\"dropdown\">\n                    <a class=\"dropdown-toggle\" data-toggle=\"dropdown\" href=\"#\">\n                        <i class=\"fa fa-bell fa-fw\"></i> <i class=\"fa fa-caret-down\"></i>\n                    </a>\n                    <ul class=\"dropdown-menu dropdown-alerts\">\n                        <li>\n                            <a href=\"#\">\n                                <div>\n                                    <i class=\"fa fa-comment fa-fw\"></i> New Comment\n                                    <span class=\"pull-right text-muted small\">4 minutes ago</span>\n                                </div>\n                            </a>\n                        </li>\n                        <li class=\"divider\"></li>\n                        <li>\n                            <a href=\"#\">\n                                <div>\n                                    <i class=\"fa fa-twitter fa-fw\"></i> 3 New Followers\n                                    <span class=\"pull-right text-muted small\">12 minutes ago</span>\n                                </div>\n                            </a>\n                        </li>\n                        <li class=\"divider\"></li>\n                        <li>\n                            <a href=\"#\">\n                                <div>\n                                    <i class=\"fa fa-envelope fa-fw\"></i> Message Sent\n                                    <span class=\"pull-right text-muted small\">4 minutes ago</span>\n                                </div>\n                            </a>\n                        </li>\n                        <li class=\"divider\"></li>\n                        <li>\n                            <a href=\"#\">\n                                <div>\n                                    <i class=\"fa fa-tasks fa-fw\"></i> New Task\n                                    <span class=\"pull-right text-muted small\">4 minutes ago</span>\n                                </div>\n                            </a>\n                        </li>\n                        <li class=\"divider\"></li>\n                        <li>\n                            <a href=\"#\">\n                                <div>\n                                    <i class=\"fa fa-upload fa-fw\"></i> Server Rebooted\n                                    <span class=\"pull-right text-muted small\">4 minutes ago</span>\n                                </div>\n                            </a>\n                        </li>\n                        <li class=\"divider\"></li>\n                        <li>\n                            <a class=\"text-center\" href=\"#\">\n                                <strong>See All Alerts</strong>\n                                <i class=\"fa fa-angle-right\"></i>\n                            </a>\n                        </li>\n                    </ul>\n                    <!-- /.dropdown-alerts -->\n                </li>\n                <!-- /.dropdown -->\n                <li class=\"dropdown\">\n                    <a class=\"dropdown-toggle\" data-toggle=\"dropdown\" href=\"#\">\n                        <i class=\"fa fa-user fa-fw\"></i> <i class=\"fa fa-caret-down\"></i>\n                    </a>\n                    <ul class=\"dropdown-menu dropdown-user\">\n                        <li><a href=\"#\"><i class=\"fa fa-user fa-fw\"></i> User Profile</a>\n                        </li>\n                        <li><a href=\"#\"><i class=\"fa fa-gear fa-fw\"></i> Settings</a>\n                        </li>\n                        <li class=\"divider\"></li>\n                        <li><a href=\"login.html\"><i class=\"fa fa-sign-out fa-fw\"></i> Logout</a>\n                        </li>\n                    </ul>\n                    <!-- /.dropdown-user -->\n                </li>\n                <!-- /.dropdown -->\n            </ul>\n            <!-- /.navbar-top-links -->\n\n            <div class=\"navbar-default sidebar\" role=\"navigation\">\n                <div class=\"sidebar-nav navbar-collapse\">\n                    <ul class=\"nav\" id=\"side-menu\">\n                        <li class=\"sidebar-search\">\n                            <div class=\"input-group custom-search-form\">\n                                <input type=\"text\" class=\"form-control\" placeholder=\"Search...\">\n                                <span class=\"input-group-btn\">\n                                <button class=\"btn btn-default\" type=\"button\">\n                                    <i class=\"fa fa-search\"></i>\n                                </button>\n                            </span>\n                            </div>\n                            <!-- /input-group -->\n                        </li>\n                        <li>\n                            <a href=\"index.html\"><i class=\"fa fa-dashboard fa-fw\"></i> Dashboard</a>\n                        </li>\n                        <li>\n                            <a href=\"#\"><i class=\"fa fa-bar-chart-o fa-fw\"></i> Charts<span class=\"fa arrow\"></span></a>\n                            <ul class=\"nav nav-second-level\">\n                                <li>\n                                    <a href=\"flot.html\">Flot Charts</a>\n                                </li>\n                                <li>\n                                    <a href=\"morris.html\">Morris.js Charts</a>\n                                </li>\n                            </ul>\n                            <!-- /.nav-second-level -->\n                        </li>\n                        <li>\n                            <a href=\"tables.html\"><i class=\"fa fa-table fa-fw\"></i> Tables</a>\n                        </li>\n                        <li>\n                            <a href=\"forms.html\"><i class=\"fa fa-edit fa-fw\"></i> Forms</a>\n                        </li>\n                        <li>\n                            <a href=\"#\"><i class=\"fa fa-wrench fa-fw\"></i> UI Elements<span class=\"fa arrow\"></span></a>\n                            <ul class=\"nav nav-second-level\">\n                                <li>\n                                    <a href=\"panels-wells.html\">Panels and Wells</a>\n                                </li>\n                                <li>\n                                    <a href=\"buttons.html\">Buttons</a>\n                                </li>\n                                <li>\n                                    <a href=\"notifications.html\">Notifications</a>\n                                </li>\n                                <li>\n                                    <a href=\"typography.html\">Typography</a>\n                                </li>\n                                <li>\n                                    <a href=\"icons.html\"> Icons</a>\n                                </li>\n                                <li>\n                                    <a href=\"grid.html\">Grid</a>\n                                </li>\n                            </ul>\n                            <!-- /.nav-second-level -->\n                        </li>\n                        <li>\n                            <a href=\"#\"><i class=\"fa fa-sitemap fa-fw\"></i> Multi-Level Dropdown<span class=\"fa arrow\"></span></a>\n                            <ul class=\"nav nav-second-level\">\n                                <li>\n                                    <a href=\"#\">Second Level Item</a>\n                                </li>\n                                <li>\n                                    <a href=\"#\">Second Level Item</a>\n                                </li>\n                                <li>\n                                    <a href=\"#\">Third Level <span class=\"fa arrow\"></span></a>\n                                    <ul class=\"nav nav-third-level\">\n                                        <li>\n                                            <a href=\"#\">Third Level Item</a>\n                                        </li>\n                                        <li>\n                                            <a href=\"#\">Third Level Item</a>\n                                        </li>\n                                        <li>\n                                            <a href=\"#\">Third Level Item</a>\n                                        </li>\n                                        <li>\n                                            <a href=\"#\">Third Level Item</a>\n                                        </li>\n                                    </ul>\n                                    <!-- /.nav-third-level -->\n                                </li>\n                            </ul>\n                            <!-- /.nav-second-level -->\n                        </li>\n                        <li>\n                            <a href=\"#\"><i class=\"fa fa-files-o fa-fw\"></i> Sample Pages<span class=\"fa arrow\"></span></a>\n                            <ul class=\"nav nav-second-level\">\n                                <li>\n                                    <a href=\"blank.html\">Blank Page</a>\n                                </li>\n                                <li>\n                                    <a href=\"login.html\">Login Page</a>\n                                </li>\n                            </ul>\n                            <!-- /.nav-second-level -->\n                        </li>\n                    </ul>\n                </div>\n                <!-- /.sidebar-collapse -->\n            </div>\n            <!-- /.navbar-static-side -->\n        </nav>\n\n        <div id=\"page-wrapper\">\n            <div class=\"row\">\n                <div class=\"col-lg-12\">\n                    <h1 class=\"page-header\">Notifications</h1>\n                </div>\n                <!-- /.col-lg-12 -->\n            </div>\n            <!-- /.row -->\n            <div class=\"row\">\n                <div class=\"col-lg-6\">\n                    <div class=\"panel panel-default\">\n                        <div class=\"panel-heading\">\n                            Alert Styles\n                        </div>\n                        <!-- /.panel-heading -->\n                        <div class=\"panel-body\">\n                            <div class=\"alert alert-success\">\n                                Lorem ipsum dolor sit amet, consectetur adipisicing elit. <a href=\"#\" class=\"alert-link\">Alert Link</a>.\n                            </div>\n                            <div class=\"alert alert-info\">\n                                Lorem ipsum dolor sit amet, consectetur adipisicing elit. <a href=\"#\" class=\"alert-link\">Alert Link</a>.\n                            </div>\n                            <div class=\"alert alert-warning\">\n                                Lorem ipsum dolor sit amet, consectetur adipisicing elit. <a href=\"#\" class=\"alert-link\">Alert Link</a>.\n                            </div>\n                            <div class=\"alert alert-danger\">\n                                Lorem ipsum dolor sit amet, consectetur adipisicing elit. <a href=\"#\" class=\"alert-link\">Alert Link</a>.\n                            </div>\n                        </div>\n                        <!-- .panel-body -->\n                    </div>\n                    <!-- /.panel -->\n                </div>\n                <!-- /.col-lg-6 -->\n                <div class=\"col-lg-6\">\n                    <div class=\"panel panel-default\">\n                        <div class=\"panel-heading\">\n                            Dismissable Alerts\n                        </div>\n                        <!-- /.panel-heading -->\n                        <div class=\"panel-body\">\n                            <div class=\"alert alert-success alert-dismissable\">\n                                <button type=\"button\" class=\"close\" data-dismiss=\"alert\" aria-hidden=\"true\">&times;</button>\n                                Lorem ipsum dolor sit amet, consectetur adipisicing elit. <a href=\"#\" class=\"alert-link\">Alert Link</a>.\n                            </div>\n                            <div class=\"alert alert-info alert-dismissable\">\n                                <button type=\"button\" class=\"close\" data-dismiss=\"alert\" aria-hidden=\"true\">&times;</button>\n                                Lorem ipsum dolor sit amet, consectetur adipisicing elit. <a href=\"#\" class=\"alert-link\">Alert Link</a>.\n                            </div>\n                            <div class=\"alert alert-warning alert-dismissable\">\n                                <button type=\"button\" class=\"close\" data-dismiss=\"alert\" aria-hidden=\"true\">&times;</button>\n                                Lorem ipsum dolor sit amet, consectetur adipisicing elit. <a href=\"#\" class=\"alert-link\">Alert Link</a>.\n                            </div>\n                            <div class=\"alert alert-danger alert-dismissable\">\n                                <button type=\"button\" class=\"close\" data-dismiss=\"alert\" aria-hidden=\"true\">&times;</button>\n                                Lorem ipsum dolor sit amet, consectetur adipisicing elit. <a href=\"#\" class=\"alert-link\">Alert Link</a>.\n                            </div>\n                        </div>\n                        <!-- .panel-body -->\n                    </div>\n                    <!-- /.panel -->\n                </div>\n                <!-- /.col-lg-6 -->\n            </div>\n            <!-- /.row -->\n            <div class=\"row\">\n                <div class=\"col-lg-6\">\n                    <div class=\"panel panel-default\">\n                        <div class=\"panel-heading\">\n                            Modals\n                        </div>\n                        <!-- /.panel-heading -->\n                        <div class=\"panel-body\">\n                            <!-- Button trigger modal -->\n                            <button class=\"btn btn-primary btn-lg\" data-toggle=\"modal\" data-target=\"#myModal\">\n                                Launch Demo Modal\n                            </button>\n                            <!-- Modal -->\n                            <div class=\"modal fade\" id=\"myModal\" tabindex=\"-1\" role=\"dialog\" aria-labelledby=\"myModalLabel\" aria-hidden=\"true\">\n                                <div class=\"modal-dialog\">\n                                    <div class=\"modal-content\">\n                                        <div class=\"modal-header\">\n                                            <button type=\"button\" class=\"close\" data-dismiss=\"modal\" aria-hidden=\"true\">&times;</button>\n                                            <h4 class=\"modal-title\" id=\"myModalLabel\">Modal title</h4>\n                                        </div>\n                                        <div class=\"modal-body\">\n                                            Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.\n                                        </div>\n                                        <div class=\"modal-footer\">\n                                            <button type=\"button\" class=\"btn btn-default\" data-dismiss=\"modal\">Close</button>\n                                            <button type=\"button\" class=\"btn btn-primary\">Save changes</button>\n                                        </div>\n                                    </div>\n                                    <!-- /.modal-content -->\n                                </div>\n                                <!-- /.modal-dialog -->\n                            </div>\n                            <!-- /.modal -->\n                        </div>\n                        <!-- .panel-body -->\n                    </div>\n                    <!-- /.panel -->\n                </div>\n                <!-- /.col-lg-6 -->\n                <div class=\"col-lg-6\">\n                    <div class=\"panel panel-default\">\n                        <div class=\"panel-heading\">\n                            Tooltips and Popovers\n                        </div>\n                        <!-- /.panel-heading -->\n                        <div class=\"panel-body\">\n                            <h4>Tooltip Demo</h4>\n                            <div class=\"tooltip-demo\">\n                                <button type=\"button\" class=\"btn btn-default\" data-toggle=\"tooltip\" data-placement=\"left\" title=\"Tooltip on left\">Tooltip on left</button>\n                                <button type=\"button\" class=\"btn btn-default\" data-toggle=\"tooltip\" data-placement=\"top\" title=\"Tooltip on top\">Tooltip on top</button>\n                                <button type=\"button\" class=\"btn btn-default\" data-toggle=\"tooltip\" data-placement=\"bottom\" title=\"Tooltip on bottom\">Tooltip on bottom</button>\n                                <button type=\"button\" class=\"btn btn-default\" data-toggle=\"tooltip\" data-placement=\"right\" title=\"Tooltip on right\">Tooltip on right</button>\n                            </div>\n                            <br>\n                            <h4>Clickable Popover Demo</h4>\n                            <div class=\"tooltip-demo\">\n                                <button type=\"button\" class=\"btn btn-default\" data-container=\"body\" data-toggle=\"popover\" data-placement=\"left\" data-content=\"Vivamus sagittis lacus vel augue laoreet rutrum faucibus.\">\n                                    Popover on left\n                                </button>\n                                <button type=\"button\" class=\"btn btn-default\" data-container=\"body\" data-toggle=\"popover\" data-placement=\"top\" data-content=\"Vivamus sagittis lacus vel augue laoreet rutrum faucibus.\">\n                                    Popover on top\n                                </button>\n                                <button type=\"button\" class=\"btn btn-default\" data-container=\"body\" data-toggle=\"popover\" data-placement=\"bottom\" data-content=\"Vivamus sagittis lacus vel augue laoreet rutrum faucibus.\">\n                                    Popover on bottom\n                                </button>\n                                <button type=\"button\" class=\"btn btn-default\" data-container=\"body\" data-toggle=\"popover\" data-placement=\"right\" data-content=\"Vivamus sagittis lacus vel augue laoreet rutrum faucibus.\">\n                                    Popover on right\n                                </button>\n                            </div>\n                        </div>\n                        <!-- .panel-body -->\n                    </div>\n                    <!-- /.panel -->\n                </div>\n                <!-- /.col-lg-6 -->\n            </div>\n            <!-- /.row -->\n        </div>\n        <!-- /#page-wrapper -->\n\n    </div>\n    <!-- /#wrapper -->\n\n    <!-- jQuery -->\n    <script src=\"../vendor/jquery/jquery.min.js\"></script>\n\n    <!-- Bootstrap Core JavaScript -->\n    <script src=\"../vendor/bootstrap/js/bootstrap.min.js\"></script>\n\n    <!-- Metis Menu Plugin JavaScript -->\n    <script src=\"../vendor/metisMenu/metisMenu.min.js\"></script>\n\n    <!-- Custom Theme JavaScript -->\n    <script src=\"../dist/js/sb-admin-2.js\"></script>\n\n    <!-- Page-Level Demo Scripts - Notifications - Use for reference -->\n    <script>\n    // tooltip demo\n    $('.tooltip-demo').tooltip({\n        selector: \"[data-toggle=tooltip]\",\n        container: \"body\"\n    })\n    // popover demo\n    $(\"[data-toggle=popover]\")\n        .popover()\n    </script>\n\n</body>\n\n</html>\n"
  },
  {
    "path": "app_backend/pages/panels-wells.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n\n<head>\n\n    <meta charset=\"utf-8\">\n    <meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\">\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">\n    <meta name=\"description\" content=\"\">\n    <meta name=\"author\" content=\"\">\n\n    <title>SB Admin 2 - Bootstrap Admin Theme</title>\n\n    <!-- Bootstrap Core CSS -->\n    <link href=\"../vendor/bootstrap/css/bootstrap.min.css\" rel=\"stylesheet\">\n\n    <!-- MetisMenu CSS -->\n    <link href=\"../vendor/metisMenu/metisMenu.min.css\" rel=\"stylesheet\">\n\n    <!-- Custom CSS -->\n    <link href=\"../dist/css/sb-admin-2.css\" rel=\"stylesheet\">\n\n    <!-- Custom Fonts -->\n    <link href=\"../vendor/font-awesome/css/font-awesome.min.css\" rel=\"stylesheet\" type=\"text/css\">\n\n    <!-- HTML5 Shim and Respond.js IE8 support of HTML5 elements and media queries -->\n    <!-- WARNING: Respond.js doesn't work if you view the page via file:// -->\n    <!--[if lt IE 9]>\n        <script src=\"https://oss.maxcdn.com/libs/html5shiv/3.7.0/html5shiv.js\"></script>\n        <script src=\"https://oss.maxcdn.com/libs/respond.js/1.4.2/respond.min.js\"></script>\n    <![endif]-->\n\n</head>\n\n<body>\n\n    <div id=\"wrapper\">\n\n        <!-- Navigation -->\n        <nav class=\"navbar navbar-default navbar-static-top\" role=\"navigation\" style=\"margin-bottom: 0\">\n            <div class=\"navbar-header\">\n                <button type=\"button\" class=\"navbar-toggle\" data-toggle=\"collapse\" data-target=\".navbar-collapse\">\n                    <span class=\"sr-only\">Toggle navigation</span>\n                    <span class=\"icon-bar\"></span>\n                    <span class=\"icon-bar\"></span>\n                    <span class=\"icon-bar\"></span>\n                </button>\n                <a class=\"navbar-brand\" href=\"index.html\">SB Admin v2.0</a>\n            </div>\n            <!-- /.navbar-header -->\n\n            <ul class=\"nav navbar-top-links navbar-right\">\n                <li class=\"dropdown\">\n                    <a class=\"dropdown-toggle\" data-toggle=\"dropdown\" href=\"#\">\n                        <i class=\"fa fa-envelope fa-fw\"></i> <i class=\"fa fa-caret-down\"></i>\n                    </a>\n                    <ul class=\"dropdown-menu dropdown-messages\">\n                        <li>\n                            <a href=\"#\">\n                                <div>\n                                    <strong>John Smith</strong>\n                                    <span class=\"pull-right text-muted\">\n                                        <em>Yesterday</em>\n                                    </span>\n                                </div>\n                                <div>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque eleifend...</div>\n                            </a>\n                        </li>\n                        <li class=\"divider\"></li>\n                        <li>\n                            <a href=\"#\">\n                                <div>\n                                    <strong>John Smith</strong>\n                                    <span class=\"pull-right text-muted\">\n                                        <em>Yesterday</em>\n                                    </span>\n                                </div>\n                                <div>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque eleifend...</div>\n                            </a>\n                        </li>\n                        <li class=\"divider\"></li>\n                        <li>\n                            <a href=\"#\">\n                                <div>\n                                    <strong>John Smith</strong>\n                                    <span class=\"pull-right text-muted\">\n                                        <em>Yesterday</em>\n                                    </span>\n                                </div>\n                                <div>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque eleifend...</div>\n                            </a>\n                        </li>\n                        <li class=\"divider\"></li>\n                        <li>\n                            <a class=\"text-center\" href=\"#\">\n                                <strong>Read All Messages</strong>\n                                <i class=\"fa fa-angle-right\"></i>\n                            </a>\n                        </li>\n                    </ul>\n                    <!-- /.dropdown-messages -->\n                </li>\n                <!-- /.dropdown -->\n                <li class=\"dropdown\">\n                    <a class=\"dropdown-toggle\" data-toggle=\"dropdown\" href=\"#\">\n                        <i class=\"fa fa-tasks fa-fw\"></i> <i class=\"fa fa-caret-down\"></i>\n                    </a>\n                    <ul class=\"dropdown-menu dropdown-tasks\">\n                        <li>\n                            <a href=\"#\">\n                                <div>\n                                    <p>\n                                        <strong>Task 1</strong>\n                                        <span class=\"pull-right text-muted\">40% Complete</span>\n                                    </p>\n                                    <div class=\"progress progress-striped active\">\n                                        <div class=\"progress-bar progress-bar-success\" role=\"progressbar\" aria-valuenow=\"40\" aria-valuemin=\"0\" aria-valuemax=\"100\" style=\"width: 40%\">\n                                            <span class=\"sr-only\">40% Complete (success)</span>\n                                        </div>\n                                    </div>\n                                </div>\n                            </a>\n                        </li>\n                        <li class=\"divider\"></li>\n                        <li>\n                            <a href=\"#\">\n                                <div>\n                                    <p>\n                                        <strong>Task 2</strong>\n                                        <span class=\"pull-right text-muted\">20% Complete</span>\n                                    </p>\n                                    <div class=\"progress progress-striped active\">\n                                        <div class=\"progress-bar progress-bar-info\" role=\"progressbar\" aria-valuenow=\"20\" aria-valuemin=\"0\" aria-valuemax=\"100\" style=\"width: 20%\">\n                                            <span class=\"sr-only\">20% Complete</span>\n                                        </div>\n                                    </div>\n                                </div>\n                            </a>\n                        </li>\n                        <li class=\"divider\"></li>\n                        <li>\n                            <a href=\"#\">\n                                <div>\n                                    <p>\n                                        <strong>Task 3</strong>\n                                        <span class=\"pull-right text-muted\">60% Complete</span>\n                                    </p>\n                                    <div class=\"progress progress-striped active\">\n                                        <div class=\"progress-bar progress-bar-warning\" role=\"progressbar\" aria-valuenow=\"60\" aria-valuemin=\"0\" aria-valuemax=\"100\" style=\"width: 60%\">\n                                            <span class=\"sr-only\">60% Complete (warning)</span>\n                                        </div>\n                                    </div>\n                                </div>\n                            </a>\n                        </li>\n                        <li class=\"divider\"></li>\n                        <li>\n                            <a href=\"#\">\n                                <div>\n                                    <p>\n                                        <strong>Task 4</strong>\n                                        <span class=\"pull-right text-muted\">80% Complete</span>\n                                    </p>\n                                    <div class=\"progress progress-striped active\">\n                                        <div class=\"progress-bar progress-bar-danger\" role=\"progressbar\" aria-valuenow=\"80\" aria-valuemin=\"0\" aria-valuemax=\"100\" style=\"width: 80%\">\n                                            <span class=\"sr-only\">80% Complete (danger)</span>\n                                        </div>\n                                    </div>\n                                </div>\n                            </a>\n                        </li>\n                        <li class=\"divider\"></li>\n                        <li>\n                            <a class=\"text-center\" href=\"#\">\n                                <strong>See All Tasks</strong>\n                                <i class=\"fa fa-angle-right\"></i>\n                            </a>\n                        </li>\n                    </ul>\n                    <!-- /.dropdown-tasks -->\n                </li>\n                <!-- /.dropdown -->\n                <li class=\"dropdown\">\n                    <a class=\"dropdown-toggle\" data-toggle=\"dropdown\" href=\"#\">\n                        <i class=\"fa fa-bell fa-fw\"></i> <i class=\"fa fa-caret-down\"></i>\n                    </a>\n                    <ul class=\"dropdown-menu dropdown-alerts\">\n                        <li>\n                            <a href=\"#\">\n                                <div>\n                                    <i class=\"fa fa-comment fa-fw\"></i> New Comment\n                                    <span class=\"pull-right text-muted small\">4 minutes ago</span>\n                                </div>\n                            </a>\n                        </li>\n                        <li class=\"divider\"></li>\n                        <li>\n                            <a href=\"#\">\n                                <div>\n                                    <i class=\"fa fa-twitter fa-fw\"></i> 3 New Followers\n                                    <span class=\"pull-right text-muted small\">12 minutes ago</span>\n                                </div>\n                            </a>\n                        </li>\n                        <li class=\"divider\"></li>\n                        <li>\n                            <a href=\"#\">\n                                <div>\n                                    <i class=\"fa fa-envelope fa-fw\"></i> Message Sent\n                                    <span class=\"pull-right text-muted small\">4 minutes ago</span>\n                                </div>\n                            </a>\n                        </li>\n                        <li class=\"divider\"></li>\n                        <li>\n                            <a href=\"#\">\n                                <div>\n                                    <i class=\"fa fa-tasks fa-fw\"></i> New Task\n                                    <span class=\"pull-right text-muted small\">4 minutes ago</span>\n                                </div>\n                            </a>\n                        </li>\n                        <li class=\"divider\"></li>\n                        <li>\n                            <a href=\"#\">\n                                <div>\n                                    <i class=\"fa fa-upload fa-fw\"></i> Server Rebooted\n                                    <span class=\"pull-right text-muted small\">4 minutes ago</span>\n                                </div>\n                            </a>\n                        </li>\n                        <li class=\"divider\"></li>\n                        <li>\n                            <a class=\"text-center\" href=\"#\">\n                                <strong>See All Alerts</strong>\n                                <i class=\"fa fa-angle-right\"></i>\n                            </a>\n                        </li>\n                    </ul>\n                    <!-- /.dropdown-alerts -->\n                </li>\n                <!-- /.dropdown -->\n                <li class=\"dropdown\">\n                    <a class=\"dropdown-toggle\" data-toggle=\"dropdown\" href=\"#\">\n                        <i class=\"fa fa-user fa-fw\"></i> <i class=\"fa fa-caret-down\"></i>\n                    </a>\n                    <ul class=\"dropdown-menu dropdown-user\">\n                        <li><a href=\"#\"><i class=\"fa fa-user fa-fw\"></i> User Profile</a>\n                        </li>\n                        <li><a href=\"#\"><i class=\"fa fa-gear fa-fw\"></i> Settings</a>\n                        </li>\n                        <li class=\"divider\"></li>\n                        <li><a href=\"login.html\"><i class=\"fa fa-sign-out fa-fw\"></i> Logout</a>\n                        </li>\n                    </ul>\n                    <!-- /.dropdown-user -->\n                </li>\n                <!-- /.dropdown -->\n            </ul>\n            <!-- /.navbar-top-links -->\n\n            <div class=\"navbar-default sidebar\" role=\"navigation\">\n                <div class=\"sidebar-nav navbar-collapse\">\n                    <ul class=\"nav\" id=\"side-menu\">\n                        <li class=\"sidebar-search\">\n                            <div class=\"input-group custom-search-form\">\n                                <input type=\"text\" class=\"form-control\" placeholder=\"Search...\">\n                                <span class=\"input-group-btn\">\n                                <button class=\"btn btn-default\" type=\"button\">\n                                    <i class=\"fa fa-search\"></i>\n                                </button>\n                            </span>\n                            </div>\n                            <!-- /input-group -->\n                        </li>\n                        <li>\n                            <a href=\"index.html\"><i class=\"fa fa-dashboard fa-fw\"></i> Dashboard</a>\n                        </li>\n                        <li>\n                            <a href=\"#\"><i class=\"fa fa-bar-chart-o fa-fw\"></i> Charts<span class=\"fa arrow\"></span></a>\n                            <ul class=\"nav nav-second-level\">\n                                <li>\n                                    <a href=\"flot.html\">Flot Charts</a>\n                                </li>\n                                <li>\n                                    <a href=\"morris.html\">Morris.js Charts</a>\n                                </li>\n                            </ul>\n                            <!-- /.nav-second-level -->\n                        </li>\n                        <li>\n                            <a href=\"tables.html\"><i class=\"fa fa-table fa-fw\"></i> Tables</a>\n                        </li>\n                        <li>\n                            <a href=\"forms.html\"><i class=\"fa fa-edit fa-fw\"></i> Forms</a>\n                        </li>\n                        <li>\n                            <a href=\"#\"><i class=\"fa fa-wrench fa-fw\"></i> UI Elements<span class=\"fa arrow\"></span></a>\n                            <ul class=\"nav nav-second-level\">\n                                <li>\n                                    <a href=\"panels-wells.html\">Panels and Wells</a>\n                                </li>\n                                <li>\n                                    <a href=\"buttons.html\">Buttons</a>\n                                </li>\n                                <li>\n                                    <a href=\"notifications.html\">Notifications</a>\n                                </li>\n                                <li>\n                                    <a href=\"typography.html\">Typography</a>\n                                </li>\n                                <li>\n                                    <a href=\"icons.html\"> Icons</a>\n                                </li>\n                                <li>\n                                    <a href=\"grid.html\">Grid</a>\n                                </li>\n                            </ul>\n                            <!-- /.nav-second-level -->\n                        </li>\n                        <li>\n                            <a href=\"#\"><i class=\"fa fa-sitemap fa-fw\"></i> Multi-Level Dropdown<span class=\"fa arrow\"></span></a>\n                            <ul class=\"nav nav-second-level\">\n                                <li>\n                                    <a href=\"#\">Second Level Item</a>\n                                </li>\n                                <li>\n                                    <a href=\"#\">Second Level Item</a>\n                                </li>\n                                <li>\n                                    <a href=\"#\">Third Level <span class=\"fa arrow\"></span></a>\n                                    <ul class=\"nav nav-third-level\">\n                                        <li>\n                                            <a href=\"#\">Third Level Item</a>\n                                        </li>\n                                        <li>\n                                            <a href=\"#\">Third Level Item</a>\n                                        </li>\n                                        <li>\n                                            <a href=\"#\">Third Level Item</a>\n                                        </li>\n                                        <li>\n                                            <a href=\"#\">Third Level Item</a>\n                                        </li>\n                                    </ul>\n                                    <!-- /.nav-third-level -->\n                                </li>\n                            </ul>\n                            <!-- /.nav-second-level -->\n                        </li>\n                        <li>\n                            <a href=\"#\"><i class=\"fa fa-files-o fa-fw\"></i> Sample Pages<span class=\"fa arrow\"></span></a>\n                            <ul class=\"nav nav-second-level\">\n                                <li>\n                                    <a href=\"blank.html\">Blank Page</a>\n                                </li>\n                                <li>\n                                    <a href=\"login.html\">Login Page</a>\n                                </li>\n                            </ul>\n                            <!-- /.nav-second-level -->\n                        </li>\n                    </ul>\n                </div>\n                <!-- /.sidebar-collapse -->\n            </div>\n            <!-- /.navbar-static-side -->\n        </nav>\n\n        <div id=\"page-wrapper\">\n            <div class=\"row\">\n                <div class=\"col-lg-12\">\n                    <h1 class=\"page-header\">Panels and Wells</h1>\n                </div>\n                <!-- /.col-lg-12 -->\n            </div>\n            <!-- /.row -->\n            <div class=\"row\">\n                <div class=\"col-lg-4\">\n                    <div class=\"panel panel-default\">\n                        <div class=\"panel-heading\">\n                            Default Panel\n                        </div>\n                        <div class=\"panel-body\">\n                            <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum tincidunt est vitae ultrices accumsan. Aliquam ornare lacus adipiscing, posuere lectus et, fringilla augue.</p>\n                        </div>\n                        <div class=\"panel-footer\">\n                            Panel Footer\n                        </div>\n                    </div>\n                </div>\n                <!-- /.col-lg-4 -->\n                <div class=\"col-lg-4\">\n                    <div class=\"panel panel-primary\">\n                        <div class=\"panel-heading\">\n                            Primary Panel\n                        </div>\n                        <div class=\"panel-body\">\n                            <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum tincidunt est vitae ultrices accumsan. Aliquam ornare lacus adipiscing, posuere lectus et, fringilla augue.</p>\n                        </div>\n                        <div class=\"panel-footer\">\n                            Panel Footer\n                        </div>\n                    </div>\n                </div>\n                <!-- /.col-lg-4 -->\n                <div class=\"col-lg-4\">\n                    <div class=\"panel panel-success\">\n                        <div class=\"panel-heading\">\n                            Success Panel\n                        </div>\n                        <div class=\"panel-body\">\n                            <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum tincidunt est vitae ultrices accumsan. Aliquam ornare lacus adipiscing, posuere lectus et, fringilla augue.</p>\n                        </div>\n                        <div class=\"panel-footer\">\n                            Panel Footer\n                        </div>\n                    </div>\n                </div>\n                <!-- /.col-lg-4 -->\n            </div>\n            <!-- /.row -->\n            <div class=\"row\">\n                <div class=\"col-lg-4\">\n                    <div class=\"panel panel-info\">\n                        <div class=\"panel-heading\">\n                            Info Panel\n                        </div>\n                        <div class=\"panel-body\">\n                            <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum tincidunt est vitae ultrices accumsan. Aliquam ornare lacus adipiscing, posuere lectus et, fringilla augue.</p>\n                        </div>\n                        <div class=\"panel-footer\">\n                            Panel Footer\n                        </div>\n                    </div>\n                </div>\n                <!-- /.col-lg-4 -->\n                <div class=\"col-lg-4\">\n                    <div class=\"panel panel-warning\">\n                        <div class=\"panel-heading\">\n                            Warning Panel\n                        </div>\n                        <div class=\"panel-body\">\n                            <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum tincidunt est vitae ultrices accumsan. Aliquam ornare lacus adipiscing, posuere lectus et, fringilla augue.</p>\n                        </div>\n                        <div class=\"panel-footer\">\n                            Panel Footer\n                        </div>\n                    </div>\n                </div>\n                <!-- /.col-lg-4 -->\n                <div class=\"col-lg-4\">\n                    <div class=\"panel panel-danger\">\n                        <div class=\"panel-heading\">\n                            Danger Panel\n                        </div>\n                        <div class=\"panel-body\">\n                            <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum tincidunt est vitae ultrices accumsan. Aliquam ornare lacus adipiscing, posuere lectus et, fringilla augue.</p>\n                        </div>\n                        <div class=\"panel-footer\">\n                            Panel Footer\n                        </div>\n                    </div>\n                </div>\n                <!-- /.col-lg-4 -->\n            </div>\n            <!-- /.row -->\n            <div class=\"row\">\n                <div class=\"col-lg-4\">\n                    <div class=\"panel panel-green\">\n                        <div class=\"panel-heading\">\n                            Green Panel\n                        </div>\n                        <div class=\"panel-body\">\n                            <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum tincidunt est vitae ultrices accumsan. Aliquam ornare lacus adipiscing, posuere lectus et, fringilla augue.</p>\n                        </div>\n                        <div class=\"panel-footer\">\n                            Panel Footer\n                        </div>\n                    </div>\n                    <!-- /.col-lg-4 -->\n                </div>\n                <div class=\"col-lg-4\">\n                    <div class=\"panel panel-yellow\">\n                        <div class=\"panel-heading\">\n                            Yellow Panel\n                        </div>\n                        <div class=\"panel-body\">\n                            <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum tincidunt est vitae ultrices accumsan. Aliquam ornare lacus adipiscing, posuere lectus et, fringilla augue.</p>\n                        </div>\n                        <div class=\"panel-footer\">\n                            Panel Footer\n                        </div>\n                    </div>\n                    <!-- /.col-lg-4 -->\n                </div>\n                <div class=\"col-lg-4\">\n                    <div class=\"panel panel-red\">\n                        <div class=\"panel-heading\">\n                            Red Panel\n                        </div>\n                        <div class=\"panel-body\">\n                            <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum tincidunt est vitae ultrices accumsan. Aliquam ornare lacus adipiscing, posuere lectus et, fringilla augue.</p>\n                        </div>\n                        <div class=\"panel-footer\">\n                            Panel Footer\n                        </div>\n                    </div>\n                    <!-- /.col-lg-4 -->\n                </div>\n            </div>\n            <!-- /.row -->\n            <div class=\"row\">\n                <div class=\"col-lg-12\">\n                    <div class=\"panel panel-default\">\n                        <div class=\"panel-heading\">\n                            Collapsible Accordion Panel Group\n                        </div>\n                        <!-- .panel-heading -->\n                        <div class=\"panel-body\">\n                            <div class=\"panel-group\" id=\"accordion\">\n                                <div class=\"panel panel-default\">\n                                    <div class=\"panel-heading\">\n                                        <h4 class=\"panel-title\">\n                                            <a data-toggle=\"collapse\" data-parent=\"#accordion\" href=\"#collapseOne\">Collapsible Group Item #1</a>\n                                        </h4>\n                                    </div>\n                                    <div id=\"collapseOne\" class=\"panel-collapse collapse in\">\n                                        <div class=\"panel-body\">\n                                            Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.\n                                        </div>\n                                    </div>\n                                </div>\n                                <div class=\"panel panel-default\">\n                                    <div class=\"panel-heading\">\n                                        <h4 class=\"panel-title\">\n                                            <a data-toggle=\"collapse\" data-parent=\"#accordion\" href=\"#collapseTwo\">Collapsible Group Item #2</a>\n                                        </h4>\n                                    </div>\n                                    <div id=\"collapseTwo\" class=\"panel-collapse collapse\">\n                                        <div class=\"panel-body\">\n                                            Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.\n                                        </div>\n                                    </div>\n                                </div>\n                                <div class=\"panel panel-default\">\n                                    <div class=\"panel-heading\">\n                                        <h4 class=\"panel-title\">\n                                            <a data-toggle=\"collapse\" data-parent=\"#accordion\" href=\"#collapseThree\">Collapsible Group Item #3</a>\n                                        </h4>\n                                    </div>\n                                    <div id=\"collapseThree\" class=\"panel-collapse collapse\">\n                                        <div class=\"panel-body\">\n                                            Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.\n                                        </div>\n                                    </div>\n                                </div>\n                            </div>\n                        </div>\n                        <!-- .panel-body -->\n                    </div>\n                    <!-- /.panel -->\n                </div>\n                <!-- /.col-lg-12 -->\n            </div>\n            <!-- /.row -->\n            <div class=\"row\">\n                <div class=\"col-lg-6\">\n                    <div class=\"panel panel-default\">\n                        <div class=\"panel-heading\">\n                            Basic Tabs\n                        </div>\n                        <!-- /.panel-heading -->\n                        <div class=\"panel-body\">\n                            <!-- Nav tabs -->\n                            <ul class=\"nav nav-tabs\">\n                                <li class=\"active\"><a href=\"#home\" data-toggle=\"tab\">Home</a>\n                                </li>\n                                <li><a href=\"#profile\" data-toggle=\"tab\">Profile</a>\n                                </li>\n                                <li><a href=\"#messages\" data-toggle=\"tab\">Messages</a>\n                                </li>\n                                <li><a href=\"#settings\" data-toggle=\"tab\">Settings</a>\n                                </li>\n                            </ul>\n\n                            <!-- Tab panes -->\n                            <div class=\"tab-content\">\n                                <div class=\"tab-pane fade in active\" id=\"home\">\n                                    <h4>Home Tab</h4>\n                                    <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>\n                                </div>\n                                <div class=\"tab-pane fade\" id=\"profile\">\n                                    <h4>Profile Tab</h4>\n                                    <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>\n                                </div>\n                                <div class=\"tab-pane fade\" id=\"messages\">\n                                    <h4>Messages Tab</h4>\n                                    <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>\n                                </div>\n                                <div class=\"tab-pane fade\" id=\"settings\">\n                                    <h4>Settings Tab</h4>\n                                    <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>\n                                </div>\n                            </div>\n                        </div>\n                        <!-- /.panel-body -->\n                    </div>\n                    <!-- /.panel -->\n                </div>\n                <!-- /.col-lg-6 -->\n                <div class=\"col-lg-6\">\n                    <div class=\"panel panel-default\">\n                        <div class=\"panel-heading\">\n                            Pill Tabs\n                        </div>\n                        <!-- /.panel-heading -->\n                        <div class=\"panel-body\">\n                            <!-- Nav tabs -->\n                            <ul class=\"nav nav-pills\">\n                                <li class=\"active\"><a href=\"#home-pills\" data-toggle=\"tab\">Home</a>\n                                </li>\n                                <li><a href=\"#profile-pills\" data-toggle=\"tab\">Profile</a>\n                                </li>\n                                <li><a href=\"#messages-pills\" data-toggle=\"tab\">Messages</a>\n                                </li>\n                                <li><a href=\"#settings-pills\" data-toggle=\"tab\">Settings</a>\n                                </li>\n                            </ul>\n\n                            <!-- Tab panes -->\n                            <div class=\"tab-content\">\n                                <div class=\"tab-pane fade in active\" id=\"home-pills\">\n                                    <h4>Home Tab</h4>\n                                    <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>\n                                </div>\n                                <div class=\"tab-pane fade\" id=\"profile-pills\">\n                                    <h4>Profile Tab</h4>\n                                    <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>\n                                </div>\n                                <div class=\"tab-pane fade\" id=\"messages-pills\">\n                                    <h4>Messages Tab</h4>\n                                    <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>\n                                </div>\n                                <div class=\"tab-pane fade\" id=\"settings-pills\">\n                                    <h4>Settings Tab</h4>\n                                    <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>\n                                </div>\n                            </div>\n                        </div>\n                        <!-- /.panel-body -->\n                    </div>\n                    <!-- /.panel -->\n                </div>\n                <!-- /.col-lg-6 -->\n            </div>\n            <!-- /.row -->\n            <div class=\"row\">\n                <div class=\"col-lg-4\">\n                    <div class=\"well\">\n                        <h4>Normal Well</h4>\n                        <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum tincidunt est vitae ultrices accumsan. Aliquam ornare lacus adipiscing, posuere lectus et, fringilla augue.</p>\n                    </div>\n                </div>\n                <!-- /.col-lg-4 -->\n                <div class=\"col-lg-4\">\n                    <div class=\"well well-lg\">\n                        <h4>Large Well</h4>\n                        <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum tincidunt est vitae ultrices accumsan. Aliquam ornare lacus adipiscing, posuere lectus et, fringilla augue.</p>\n                    </div>\n                </div>\n                <!-- /.col-lg-4 -->\n                <div class=\"col-lg-4\">\n                    <div class=\"well well-sm\">\n                        <h4>Small Well</h4>\n                        <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum tincidunt est vitae ultrices accumsan. Aliquam ornare lacus adipiscing, posuere lectus et, fringilla augue.</p>\n                    </div>\n                </div>\n                <!-- /.col-lg-4 -->\n            </div>\n            <!-- /.row -->\n            <div class=\"row\">\n                <div class=\"col-lg-12\">\n                    <div class=\"jumbotron\">\n                        <h1>Jumbotron</h1>\n                        <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum tincidunt est vitae ultrices accumsan. Aliquam ornare lacus adipiscing, posuere lectus et, fringilla augue. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum tincidunt est vitae ultrices accumsan. Aliquam ornare lacus adipiscing.</p>\n                        <p><a class=\"btn btn-primary btn-lg\" role=\"button\">Learn more</a>\n                        </p>\n                    </div>\n                </div>\n                <!-- /.col-lg-12 -->\n            </div>\n            <!-- /.row -->\n        </div>\n        <!-- /#page-wrapper -->\n\n    </div>\n    <!-- /#wrapper -->\n\n    <!-- jQuery -->\n    <script src=\"../vendor/jquery/jquery.min.js\"></script>\n\n    <!-- Bootstrap Core JavaScript -->\n    <script src=\"../vendor/bootstrap/js/bootstrap.min.js\"></script>\n\n    <!-- Metis Menu Plugin JavaScript -->\n    <script src=\"../vendor/metisMenu/metisMenu.min.js\"></script>\n\n    <!-- Custom Theme JavaScript -->\n    <script src=\"../dist/js/sb-admin-2.js\"></script>\n\n</body>\n\n</html>\n"
  },
  {
    "path": "app_backend/pages/tables.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n\n<head>\n\n    <meta charset=\"utf-8\">\n    <meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\">\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">\n    <meta name=\"description\" content=\"\">\n    <meta name=\"author\" content=\"\">\n\n    <title>SB Admin 2 - Bootstrap Admin Theme</title>\n\n    <!-- Bootstrap Core CSS -->\n    <link href=\"../vendor/bootstrap/css/bootstrap.min.css\" rel=\"stylesheet\">\n\n    <!-- MetisMenu CSS -->\n    <link href=\"../vendor/metisMenu/metisMenu.min.css\" rel=\"stylesheet\">\n\n    <!-- DataTables CSS -->\n    <link href=\"../vendor/datatables-plugins/dataTables.bootstrap.css\" rel=\"stylesheet\">\n\n    <!-- DataTables Responsive CSS -->\n    <link href=\"../vendor/datatables-responsive/dataTables.responsive.css\" rel=\"stylesheet\">\n\n    <!-- Custom CSS -->\n    <link href=\"../dist/css/sb-admin-2.css\" rel=\"stylesheet\">\n\n    <!-- Custom Fonts -->\n    <link href=\"../vendor/font-awesome/css/font-awesome.min.css\" rel=\"stylesheet\" type=\"text/css\">\n\n    <!-- HTML5 Shim and Respond.js IE8 support of HTML5 elements and media queries -->\n    <!-- WARNING: Respond.js doesn't work if you view the page via file:// -->\n    <!--[if lt IE 9]>\n        <script src=\"https://oss.maxcdn.com/libs/html5shiv/3.7.0/html5shiv.js\"></script>\n        <script src=\"https://oss.maxcdn.com/libs/respond.js/1.4.2/respond.min.js\"></script>\n    <![endif]-->\n\n</head>\n\n<body>\n\n    <div id=\"wrapper\">\n\n        <!-- Navigation -->\n        <nav class=\"navbar navbar-default navbar-static-top\" role=\"navigation\" style=\"margin-bottom: 0\">\n            <div class=\"navbar-header\">\n                <button type=\"button\" class=\"navbar-toggle\" data-toggle=\"collapse\" data-target=\".navbar-collapse\">\n                    <span class=\"sr-only\">Toggle navigation</span>\n                    <span class=\"icon-bar\"></span>\n                    <span class=\"icon-bar\"></span>\n                    <span class=\"icon-bar\"></span>\n                </button>\n                <a class=\"navbar-brand\" href=\"index.html\">SB Admin v2.0</a>\n            </div>\n            <!-- /.navbar-header -->\n\n            <ul class=\"nav navbar-top-links navbar-right\">\n                <li class=\"dropdown\">\n                    <a class=\"dropdown-toggle\" data-toggle=\"dropdown\" href=\"#\">\n                        <i class=\"fa fa-envelope fa-fw\"></i> <i class=\"fa fa-caret-down\"></i>\n                    </a>\n                    <ul class=\"dropdown-menu dropdown-messages\">\n                        <li>\n                            <a href=\"#\">\n                                <div>\n                                    <strong>John Smith</strong>\n                                    <span class=\"pull-right text-muted\">\n                                        <em>Yesterday</em>\n                                    </span>\n                                </div>\n                                <div>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque eleifend...</div>\n                            </a>\n                        </li>\n                        <li class=\"divider\"></li>\n                        <li>\n                            <a href=\"#\">\n                                <div>\n                                    <strong>John Smith</strong>\n                                    <span class=\"pull-right text-muted\">\n                                        <em>Yesterday</em>\n                                    </span>\n                                </div>\n                                <div>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque eleifend...</div>\n                            </a>\n                        </li>\n                        <li class=\"divider\"></li>\n                        <li>\n                            <a href=\"#\">\n                                <div>\n                                    <strong>John Smith</strong>\n                                    <span class=\"pull-right text-muted\">\n                                        <em>Yesterday</em>\n                                    </span>\n                                </div>\n                                <div>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque eleifend...</div>\n                            </a>\n                        </li>\n                        <li class=\"divider\"></li>\n                        <li>\n                            <a class=\"text-center\" href=\"#\">\n                                <strong>Read All Messages</strong>\n                                <i class=\"fa fa-angle-right\"></i>\n                            </a>\n                        </li>\n                    </ul>\n                    <!-- /.dropdown-messages -->\n                </li>\n                <!-- /.dropdown -->\n                <li class=\"dropdown\">\n                    <a class=\"dropdown-toggle\" data-toggle=\"dropdown\" href=\"#\">\n                        <i class=\"fa fa-tasks fa-fw\"></i> <i class=\"fa fa-caret-down\"></i>\n                    </a>\n                    <ul class=\"dropdown-menu dropdown-tasks\">\n                        <li>\n                            <a href=\"#\">\n                                <div>\n                                    <p>\n                                        <strong>Task 1</strong>\n                                        <span class=\"pull-right text-muted\">40% Complete</span>\n                                    </p>\n                                    <div class=\"progress progress-striped active\">\n                                        <div class=\"progress-bar progress-bar-success\" role=\"progressbar\" aria-valuenow=\"40\" aria-valuemin=\"0\" aria-valuemax=\"100\" style=\"width: 40%\">\n                                            <span class=\"sr-only\">40% Complete (success)</span>\n                                        </div>\n                                    </div>\n                                </div>\n                            </a>\n                        </li>\n                        <li class=\"divider\"></li>\n                        <li>\n                            <a href=\"#\">\n                                <div>\n                                    <p>\n                                        <strong>Task 2</strong>\n                                        <span class=\"pull-right text-muted\">20% Complete</span>\n                                    </p>\n                                    <div class=\"progress progress-striped active\">\n                                        <div class=\"progress-bar progress-bar-info\" role=\"progressbar\" aria-valuenow=\"20\" aria-valuemin=\"0\" aria-valuemax=\"100\" style=\"width: 20%\">\n                                            <span class=\"sr-only\">20% Complete</span>\n                                        </div>\n                                    </div>\n                                </div>\n                            </a>\n                        </li>\n                        <li class=\"divider\"></li>\n                        <li>\n                            <a href=\"#\">\n                                <div>\n                                    <p>\n                                        <strong>Task 3</strong>\n                                        <span class=\"pull-right text-muted\">60% Complete</span>\n                                    </p>\n                                    <div class=\"progress progress-striped active\">\n                                        <div class=\"progress-bar progress-bar-warning\" role=\"progressbar\" aria-valuenow=\"60\" aria-valuemin=\"0\" aria-valuemax=\"100\" style=\"width: 60%\">\n                                            <span class=\"sr-only\">60% Complete (warning)</span>\n                                        </div>\n                                    </div>\n                                </div>\n                            </a>\n                        </li>\n                        <li class=\"divider\"></li>\n                        <li>\n                            <a href=\"#\">\n                                <div>\n                                    <p>\n                                        <strong>Task 4</strong>\n                                        <span class=\"pull-right text-muted\">80% Complete</span>\n                                    </p>\n                                    <div class=\"progress progress-striped active\">\n                                        <div class=\"progress-bar progress-bar-danger\" role=\"progressbar\" aria-valuenow=\"80\" aria-valuemin=\"0\" aria-valuemax=\"100\" style=\"width: 80%\">\n                                            <span class=\"sr-only\">80% Complete (danger)</span>\n                                        </div>\n                                    </div>\n                                </div>\n                            </a>\n                        </li>\n                        <li class=\"divider\"></li>\n                        <li>\n                            <a class=\"text-center\" href=\"#\">\n                                <strong>See All Tasks</strong>\n                                <i class=\"fa fa-angle-right\"></i>\n                            </a>\n                        </li>\n                    </ul>\n                    <!-- /.dropdown-tasks -->\n                </li>\n                <!-- /.dropdown -->\n                <li class=\"dropdown\">\n                    <a class=\"dropdown-toggle\" data-toggle=\"dropdown\" href=\"#\">\n                        <i class=\"fa fa-bell fa-fw\"></i> <i class=\"fa fa-caret-down\"></i>\n                    </a>\n                    <ul class=\"dropdown-menu dropdown-alerts\">\n                        <li>\n                            <a href=\"#\">\n                                <div>\n                                    <i class=\"fa fa-comment fa-fw\"></i> New Comment\n                                    <span class=\"pull-right text-muted small\">4 minutes ago</span>\n                                </div>\n                            </a>\n                        </li>\n                        <li class=\"divider\"></li>\n                        <li>\n                            <a href=\"#\">\n                                <div>\n                                    <i class=\"fa fa-twitter fa-fw\"></i> 3 New Followers\n                                    <span class=\"pull-right text-muted small\">12 minutes ago</span>\n                                </div>\n                            </a>\n                        </li>\n                        <li class=\"divider\"></li>\n                        <li>\n                            <a href=\"#\">\n                                <div>\n                                    <i class=\"fa fa-envelope fa-fw\"></i> Message Sent\n                                    <span class=\"pull-right text-muted small\">4 minutes ago</span>\n                                </div>\n                            </a>\n                        </li>\n                        <li class=\"divider\"></li>\n                        <li>\n                            <a href=\"#\">\n                                <div>\n                                    <i class=\"fa fa-tasks fa-fw\"></i> New Task\n                                    <span class=\"pull-right text-muted small\">4 minutes ago</span>\n                                </div>\n                            </a>\n                        </li>\n                        <li class=\"divider\"></li>\n                        <li>\n                            <a href=\"#\">\n                                <div>\n                                    <i class=\"fa fa-upload fa-fw\"></i> Server Rebooted\n                                    <span class=\"pull-right text-muted small\">4 minutes ago</span>\n                                </div>\n                            </a>\n                        </li>\n                        <li class=\"divider\"></li>\n                        <li>\n                            <a class=\"text-center\" href=\"#\">\n                                <strong>See All Alerts</strong>\n                                <i class=\"fa fa-angle-right\"></i>\n                            </a>\n                        </li>\n                    </ul>\n                    <!-- /.dropdown-alerts -->\n                </li>\n                <!-- /.dropdown -->\n                <li class=\"dropdown\">\n                    <a class=\"dropdown-toggle\" data-toggle=\"dropdown\" href=\"#\">\n                        <i class=\"fa fa-user fa-fw\"></i> <i class=\"fa fa-caret-down\"></i>\n                    </a>\n                    <ul class=\"dropdown-menu dropdown-user\">\n                        <li><a href=\"#\"><i class=\"fa fa-user fa-fw\"></i> User Profile</a>\n                        </li>\n                        <li><a href=\"#\"><i class=\"fa fa-gear fa-fw\"></i> Settings</a>\n                        </li>\n                        <li class=\"divider\"></li>\n                        <li><a href=\"login.html\"><i class=\"fa fa-sign-out fa-fw\"></i> Logout</a>\n                        </li>\n                    </ul>\n                    <!-- /.dropdown-user -->\n                </li>\n                <!-- /.dropdown -->\n            </ul>\n            <!-- /.navbar-top-links -->\n\n            <div class=\"navbar-default sidebar\" role=\"navigation\">\n                <div class=\"sidebar-nav navbar-collapse\">\n                    <ul class=\"nav\" id=\"side-menu\">\n                        <li class=\"sidebar-search\">\n                            <div class=\"input-group custom-search-form\">\n                                <input type=\"text\" class=\"form-control\" placeholder=\"Search...\">\n                                <span class=\"input-group-btn\">\n                                <button class=\"btn btn-default\" type=\"button\">\n                                    <i class=\"fa fa-search\"></i>\n                                </button>\n                            </span>\n                            </div>\n                            <!-- /input-group -->\n                        </li>\n                        <li>\n                            <a href=\"index.html\"><i class=\"fa fa-dashboard fa-fw\"></i> Dashboard</a>\n                        </li>\n                        <li>\n                            <a href=\"#\"><i class=\"fa fa-bar-chart-o fa-fw\"></i> Charts<span class=\"fa arrow\"></span></a>\n                            <ul class=\"nav nav-second-level\">\n                                <li>\n                                    <a href=\"flot.html\">Flot Charts</a>\n                                </li>\n                                <li>\n                                    <a href=\"morris.html\">Morris.js Charts</a>\n                                </li>\n                            </ul>\n                            <!-- /.nav-second-level -->\n                        </li>\n                        <li>\n                            <a href=\"tables.html\"><i class=\"fa fa-table fa-fw\"></i> Tables</a>\n                        </li>\n                        <li>\n                            <a href=\"forms.html\"><i class=\"fa fa-edit fa-fw\"></i> Forms</a>\n                        </li>\n                        <li>\n                            <a href=\"#\"><i class=\"fa fa-wrench fa-fw\"></i> UI Elements<span class=\"fa arrow\"></span></a>\n                            <ul class=\"nav nav-second-level\">\n                                <li>\n                                    <a href=\"panels-wells.html\">Panels and Wells</a>\n                                </li>\n                                <li>\n                                    <a href=\"buttons.html\">Buttons</a>\n                                </li>\n                                <li>\n                                    <a href=\"notifications.html\">Notifications</a>\n                                </li>\n                                <li>\n                                    <a href=\"typography.html\">Typography</a>\n                                </li>\n                                <li>\n                                    <a href=\"icons.html\"> Icons</a>\n                                </li>\n                                <li>\n                                    <a href=\"grid.html\">Grid</a>\n                                </li>\n                            </ul>\n                            <!-- /.nav-second-level -->\n                        </li>\n                        <li>\n                            <a href=\"#\"><i class=\"fa fa-sitemap fa-fw\"></i> Multi-Level Dropdown<span class=\"fa arrow\"></span></a>\n                            <ul class=\"nav nav-second-level\">\n                                <li>\n                                    <a href=\"#\">Second Level Item</a>\n                                </li>\n                                <li>\n                                    <a href=\"#\">Second Level Item</a>\n                                </li>\n                                <li>\n                                    <a href=\"#\">Third Level <span class=\"fa arrow\"></span></a>\n                                    <ul class=\"nav nav-third-level\">\n                                        <li>\n                                            <a href=\"#\">Third Level Item</a>\n                                        </li>\n                                        <li>\n                                            <a href=\"#\">Third Level Item</a>\n                                        </li>\n                                        <li>\n                                            <a href=\"#\">Third Level Item</a>\n                                        </li>\n                                        <li>\n                                            <a href=\"#\">Third Level Item</a>\n                                        </li>\n                                    </ul>\n                                    <!-- /.nav-third-level -->\n                                </li>\n                            </ul>\n                            <!-- /.nav-second-level -->\n                        </li>\n                        <li>\n                            <a href=\"#\"><i class=\"fa fa-files-o fa-fw\"></i> Sample Pages<span class=\"fa arrow\"></span></a>\n                            <ul class=\"nav nav-second-level\">\n                                <li>\n                                    <a href=\"blank.html\">Blank Page</a>\n                                </li>\n                                <li>\n                                    <a href=\"login.html\">Login Page</a>\n                                </li>\n                            </ul>\n                            <!-- /.nav-second-level -->\n                        </li>\n                    </ul>\n                </div>\n                <!-- /.sidebar-collapse -->\n            </div>\n            <!-- /.navbar-static-side -->\n        </nav>\n\n        <div id=\"page-wrapper\">\n            <div class=\"row\">\n                <div class=\"col-lg-12\">\n                    <h1 class=\"page-header\">Tables</h1>\n                </div>\n                <!-- /.col-lg-12 -->\n            </div>\n            <!-- /.row -->\n            <div class=\"row\">\n                <div class=\"col-lg-12\">\n                    <div class=\"panel panel-default\">\n                        <div class=\"panel-heading\">\n                            DataTables Advanced Tables\n                        </div>\n                        <!-- /.panel-heading -->\n                        <div class=\"panel-body\">\n                            <table width=\"100%\" class=\"table table-striped table-bordered table-hover\" id=\"dataTables-example\">\n                                <thead>\n                                    <tr>\n                                        <th>Rendering engine</th>\n                                        <th>Browser</th>\n                                        <th>Platform(s)</th>\n                                        <th>Engine version</th>\n                                        <th>CSS grade</th>\n                                    </tr>\n                                </thead>\n                                <tbody>\n                                    <tr class=\"odd gradeX\">\n                                        <td>Trident</td>\n                                        <td>Internet Explorer 4.0</td>\n                                        <td>Win 95+</td>\n                                        <td class=\"center\">4</td>\n                                        <td class=\"center\">X</td>\n                                    </tr>\n                                    <tr class=\"even gradeC\">\n                                        <td>Trident</td>\n                                        <td>Internet Explorer 5.0</td>\n                                        <td>Win 95+</td>\n                                        <td class=\"center\">5</td>\n                                        <td class=\"center\">C</td>\n                                    </tr>\n                                    <tr class=\"odd gradeA\">\n                                        <td>Trident</td>\n                                        <td>Internet Explorer 5.5</td>\n                                        <td>Win 95+</td>\n                                        <td class=\"center\">5.5</td>\n                                        <td class=\"center\">A</td>\n                                    </tr>\n                                    <tr class=\"even gradeA\">\n                                        <td>Trident</td>\n                                        <td>Internet Explorer 6</td>\n                                        <td>Win 98+</td>\n                                        <td class=\"center\">6</td>\n                                        <td class=\"center\">A</td>\n                                    </tr>\n                                    <tr class=\"odd gradeA\">\n                                        <td>Trident</td>\n                                        <td>Internet Explorer 7</td>\n                                        <td>Win XP SP2+</td>\n                                        <td class=\"center\">7</td>\n                                        <td class=\"center\">A</td>\n                                    </tr>\n                                    <tr class=\"even gradeA\">\n                                        <td>Trident</td>\n                                        <td>AOL browser (AOL desktop)</td>\n                                        <td>Win XP</td>\n                                        <td class=\"center\">6</td>\n                                        <td class=\"center\">A</td>\n                                    </tr>\n                                    <tr class=\"gradeA\">\n                                        <td>Gecko</td>\n                                        <td>Firefox 1.0</td>\n                                        <td>Win 98+ / OSX.2+</td>\n                                        <td class=\"center\">1.7</td>\n                                        <td class=\"center\">A</td>\n                                    </tr>\n                                    <tr class=\"gradeA\">\n                                        <td>Gecko</td>\n                                        <td>Firefox 1.5</td>\n                                        <td>Win 98+ / OSX.2+</td>\n                                        <td class=\"center\">1.8</td>\n                                        <td class=\"center\">A</td>\n                                    </tr>\n                                    <tr class=\"gradeA\">\n                                        <td>Gecko</td>\n                                        <td>Firefox 2.0</td>\n                                        <td>Win 98+ / OSX.2+</td>\n                                        <td class=\"center\">1.8</td>\n                                        <td class=\"center\">A</td>\n                                    </tr>\n                                    <tr class=\"gradeA\">\n                                        <td>Gecko</td>\n                                        <td>Firefox 3.0</td>\n                                        <td>Win 2k+ / OSX.3+</td>\n                                        <td class=\"center\">1.9</td>\n                                        <td class=\"center\">A</td>\n                                    </tr>\n                                    <tr class=\"gradeA\">\n                                        <td>Gecko</td>\n                                        <td>Camino 1.0</td>\n                                        <td>OSX.2+</td>\n                                        <td class=\"center\">1.8</td>\n                                        <td class=\"center\">A</td>\n                                    </tr>\n                                    <tr class=\"gradeA\">\n                                        <td>Gecko</td>\n                                        <td>Camino 1.5</td>\n                                        <td>OSX.3+</td>\n                                        <td class=\"center\">1.8</td>\n                                        <td class=\"center\">A</td>\n                                    </tr>\n                                    <tr class=\"gradeA\">\n                                        <td>Gecko</td>\n                                        <td>Netscape 7.2</td>\n                                        <td>Win 95+ / Mac OS 8.6-9.2</td>\n                                        <td class=\"center\">1.7</td>\n                                        <td class=\"center\">A</td>\n                                    </tr>\n                                    <tr class=\"gradeA\">\n                                        <td>Gecko</td>\n                                        <td>Netscape Browser 8</td>\n                                        <td>Win 98SE+</td>\n                                        <td class=\"center\">1.7</td>\n                                        <td class=\"center\">A</td>\n                                    </tr>\n                                    <tr class=\"gradeA\">\n                                        <td>Gecko</td>\n                                        <td>Netscape Navigator 9</td>\n                                        <td>Win 98+ / OSX.2+</td>\n                                        <td class=\"center\">1.8</td>\n                                        <td class=\"center\">A</td>\n                                    </tr>\n                                    <tr class=\"gradeA\">\n                                        <td>Gecko</td>\n                                        <td>Mozilla 1.0</td>\n                                        <td>Win 95+ / OSX.1+</td>\n                                        <td class=\"center\">1</td>\n                                        <td class=\"center\">A</td>\n                                    </tr>\n                                    <tr class=\"gradeA\">\n                                        <td>Gecko</td>\n                                        <td>Mozilla 1.1</td>\n                                        <td>Win 95+ / OSX.1+</td>\n                                        <td class=\"center\">1.1</td>\n                                        <td class=\"center\">A</td>\n                                    </tr>\n                                    <tr class=\"gradeA\">\n                                        <td>Gecko</td>\n                                        <td>Mozilla 1.2</td>\n                                        <td>Win 95+ / OSX.1+</td>\n                                        <td class=\"center\">1.2</td>\n                                        <td class=\"center\">A</td>\n                                    </tr>\n                                    <tr class=\"gradeA\">\n                                        <td>Gecko</td>\n                                        <td>Mozilla 1.3</td>\n                                        <td>Win 95+ / OSX.1+</td>\n                                        <td class=\"center\">1.3</td>\n                                        <td class=\"center\">A</td>\n                                    </tr>\n                                    <tr class=\"gradeA\">\n                                        <td>Gecko</td>\n                                        <td>Mozilla 1.4</td>\n                                        <td>Win 95+ / OSX.1+</td>\n                                        <td class=\"center\">1.4</td>\n                                        <td class=\"center\">A</td>\n                                    </tr>\n                                    <tr class=\"gradeA\">\n                                        <td>Gecko</td>\n                                        <td>Mozilla 1.5</td>\n                                        <td>Win 95+ / OSX.1+</td>\n                                        <td class=\"center\">1.5</td>\n                                        <td class=\"center\">A</td>\n                                    </tr>\n                                    <tr class=\"gradeA\">\n                                        <td>Gecko</td>\n                                        <td>Mozilla 1.6</td>\n                                        <td>Win 95+ / OSX.1+</td>\n                                        <td class=\"center\">1.6</td>\n                                        <td class=\"center\">A</td>\n                                    </tr>\n                                    <tr class=\"gradeA\">\n                                        <td>Gecko</td>\n                                        <td>Mozilla 1.7</td>\n                                        <td>Win 98+ / OSX.1+</td>\n                                        <td class=\"center\">1.7</td>\n                                        <td class=\"center\">A</td>\n                                    </tr>\n                                    <tr class=\"gradeA\">\n                                        <td>Gecko</td>\n                                        <td>Mozilla 1.8</td>\n                                        <td>Win 98+ / OSX.1+</td>\n                                        <td class=\"center\">1.8</td>\n                                        <td class=\"center\">A</td>\n                                    </tr>\n                                    <tr class=\"gradeA\">\n                                        <td>Gecko</td>\n                                        <td>Seamonkey 1.1</td>\n                                        <td>Win 98+ / OSX.2+</td>\n                                        <td class=\"center\">1.8</td>\n                                        <td class=\"center\">A</td>\n                                    </tr>\n                                    <tr class=\"gradeA\">\n                                        <td>Gecko</td>\n                                        <td>Epiphany 2.20</td>\n                                        <td>Gnome</td>\n                                        <td class=\"center\">1.8</td>\n                                        <td class=\"center\">A</td>\n                                    </tr>\n                                    <tr class=\"gradeA\">\n                                        <td>Webkit</td>\n                                        <td>Safari 1.2</td>\n                                        <td>OSX.3</td>\n                                        <td class=\"center\">125.5</td>\n                                        <td class=\"center\">A</td>\n                                    </tr>\n                                    <tr class=\"gradeA\">\n                                        <td>Webkit</td>\n                                        <td>Safari 1.3</td>\n                                        <td>OSX.3</td>\n                                        <td class=\"center\">312.8</td>\n                                        <td class=\"center\">A</td>\n                                    </tr>\n                                    <tr class=\"gradeA\">\n                                        <td>Webkit</td>\n                                        <td>Safari 2.0</td>\n                                        <td>OSX.4+</td>\n                                        <td class=\"center\">419.3</td>\n                                        <td class=\"center\">A</td>\n                                    </tr>\n                                    <tr class=\"gradeA\">\n                                        <td>Webkit</td>\n                                        <td>Safari 3.0</td>\n                                        <td>OSX.4+</td>\n                                        <td class=\"center\">522.1</td>\n                                        <td class=\"center\">A</td>\n                                    </tr>\n                                    <tr class=\"gradeA\">\n                                        <td>Webkit</td>\n                                        <td>OmniWeb 5.5</td>\n                                        <td>OSX.4+</td>\n                                        <td class=\"center\">420</td>\n                                        <td class=\"center\">A</td>\n                                    </tr>\n                                    <tr class=\"gradeA\">\n                                        <td>Webkit</td>\n                                        <td>iPod Touch / iPhone</td>\n                                        <td>iPod</td>\n                                        <td class=\"center\">420.1</td>\n                                        <td class=\"center\">A</td>\n                                    </tr>\n                                    <tr class=\"gradeA\">\n                                        <td>Webkit</td>\n                                        <td>S60</td>\n                                        <td>S60</td>\n                                        <td class=\"center\">413</td>\n                                        <td class=\"center\">A</td>\n                                    </tr>\n                                    <tr class=\"gradeA\">\n                                        <td>Presto</td>\n                                        <td>Opera 7.0</td>\n                                        <td>Win 95+ / OSX.1+</td>\n                                        <td class=\"center\">-</td>\n                                        <td class=\"center\">A</td>\n                                    </tr>\n                                    <tr class=\"gradeA\">\n                                        <td>Presto</td>\n                                        <td>Opera 7.5</td>\n                                        <td>Win 95+ / OSX.2+</td>\n                                        <td class=\"center\">-</td>\n                                        <td class=\"center\">A</td>\n                                    </tr>\n                                    <tr class=\"gradeA\">\n                                        <td>Presto</td>\n                                        <td>Opera 8.0</td>\n                                        <td>Win 95+ / OSX.2+</td>\n                                        <td class=\"center\">-</td>\n                                        <td class=\"center\">A</td>\n                                    </tr>\n                                    <tr class=\"gradeA\">\n                                        <td>Presto</td>\n                                        <td>Opera 8.5</td>\n                                        <td>Win 95+ / OSX.2+</td>\n                                        <td class=\"center\">-</td>\n                                        <td class=\"center\">A</td>\n                                    </tr>\n                                    <tr class=\"gradeA\">\n                                        <td>Presto</td>\n                                        <td>Opera 9.0</td>\n                                        <td>Win 95+ / OSX.3+</td>\n                                        <td class=\"center\">-</td>\n                                        <td class=\"center\">A</td>\n                                    </tr>\n                                    <tr class=\"gradeA\">\n                                        <td>Presto</td>\n                                        <td>Opera 9.2</td>\n                                        <td>Win 88+ / OSX.3+</td>\n                                        <td class=\"center\">-</td>\n                                        <td class=\"center\">A</td>\n                                    </tr>\n                                    <tr class=\"gradeA\">\n                                        <td>Presto</td>\n                                        <td>Opera 9.5</td>\n                                        <td>Win 88+ / OSX.3+</td>\n                                        <td class=\"center\">-</td>\n                                        <td class=\"center\">A</td>\n                                    </tr>\n                                    <tr class=\"gradeA\">\n                                        <td>Presto</td>\n                                        <td>Opera for Wii</td>\n                                        <td>Wii</td>\n                                        <td class=\"center\">-</td>\n                                        <td class=\"center\">A</td>\n                                    </tr>\n                                    <tr class=\"gradeA\">\n                                        <td>Presto</td>\n                                        <td>Nokia N800</td>\n                                        <td>N800</td>\n                                        <td class=\"center\">-</td>\n                                        <td class=\"center\">A</td>\n                                    </tr>\n                                    <tr class=\"gradeA\">\n                                        <td>Presto</td>\n                                        <td>Nintendo DS browser</td>\n                                        <td>Nintendo DS</td>\n                                        <td class=\"center\">8.5</td>\n                                        <td class=\"center\">C/A<sup>1</sup>\n                                        </td>\n                                    </tr>\n                                    <tr class=\"gradeC\">\n                                        <td>KHTML</td>\n                                        <td>Konqureror 3.1</td>\n                                        <td>KDE 3.1</td>\n                                        <td class=\"center\">3.1</td>\n                                        <td class=\"center\">C</td>\n                                    </tr>\n                                    <tr class=\"gradeA\">\n                                        <td>KHTML</td>\n                                        <td>Konqureror 3.3</td>\n                                        <td>KDE 3.3</td>\n                                        <td class=\"center\">3.3</td>\n                                        <td class=\"center\">A</td>\n                                    </tr>\n                                    <tr class=\"gradeA\">\n                                        <td>KHTML</td>\n                                        <td>Konqureror 3.5</td>\n                                        <td>KDE 3.5</td>\n                                        <td class=\"center\">3.5</td>\n                                        <td class=\"center\">A</td>\n                                    </tr>\n                                    <tr class=\"gradeX\">\n                                        <td>Tasman</td>\n                                        <td>Internet Explorer 4.5</td>\n                                        <td>Mac OS 8-9</td>\n                                        <td class=\"center\">-</td>\n                                        <td class=\"center\">X</td>\n                                    </tr>\n                                    <tr class=\"gradeC\">\n                                        <td>Tasman</td>\n                                        <td>Internet Explorer 5.1</td>\n                                        <td>Mac OS 7.6-9</td>\n                                        <td class=\"center\">1</td>\n                                        <td class=\"center\">C</td>\n                                    </tr>\n                                    <tr class=\"gradeC\">\n                                        <td>Tasman</td>\n                                        <td>Internet Explorer 5.2</td>\n                                        <td>Mac OS 8-X</td>\n                                        <td class=\"center\">1</td>\n                                        <td class=\"center\">C</td>\n                                    </tr>\n                                    <tr class=\"gradeA\">\n                                        <td>Misc</td>\n                                        <td>NetFront 3.1</td>\n                                        <td>Embedded devices</td>\n                                        <td class=\"center\">-</td>\n                                        <td class=\"center\">C</td>\n                                    </tr>\n                                    <tr class=\"gradeA\">\n                                        <td>Misc</td>\n                                        <td>NetFront 3.4</td>\n                                        <td>Embedded devices</td>\n                                        <td class=\"center\">-</td>\n                                        <td class=\"center\">A</td>\n                                    </tr>\n                                    <tr class=\"gradeX\">\n                                        <td>Misc</td>\n                                        <td>Dillo 0.8</td>\n                                        <td>Embedded devices</td>\n                                        <td class=\"center\">-</td>\n                                        <td class=\"center\">X</td>\n                                    </tr>\n                                    <tr class=\"gradeX\">\n                                        <td>Misc</td>\n                                        <td>Links</td>\n                                        <td>Text only</td>\n                                        <td class=\"center\">-</td>\n                                        <td class=\"center\">X</td>\n                                    </tr>\n                                    <tr class=\"gradeX\">\n                                        <td>Misc</td>\n                                        <td>Lynx</td>\n                                        <td>Text only</td>\n                                        <td class=\"center\">-</td>\n                                        <td class=\"center\">X</td>\n                                    </tr>\n                                    <tr class=\"gradeC\">\n                                        <td>Misc</td>\n                                        <td>IE Mobile</td>\n                                        <td>Windows Mobile 6</td>\n                                        <td class=\"center\">-</td>\n                                        <td class=\"center\">C</td>\n                                    </tr>\n                                    <tr class=\"gradeC\">\n                                        <td>Misc</td>\n                                        <td>PSP browser</td>\n                                        <td>PSP</td>\n                                        <td class=\"center\">-</td>\n                                        <td class=\"center\">C</td>\n                                    </tr>\n                                    <tr class=\"gradeU\">\n                                        <td>Other browsers</td>\n                                        <td>All others</td>\n                                        <td>-</td>\n                                        <td class=\"center\">-</td>\n                                        <td class=\"center\">U</td>\n                                    </tr>\n                                </tbody>\n                            </table>\n                            <!-- /.table-responsive -->\n                            <div class=\"well\">\n                                <h4>DataTables Usage Information</h4>\n                                <p>DataTables is a very flexible, advanced tables plugin for jQuery. In SB Admin, we are using a specialized version of DataTables built for Bootstrap 3. We have also customized the table headings to use Font Awesome icons in place of images. For complete documentation on DataTables, visit their website at <a target=\"_blank\" href=\"https://datatables.net/\">https://datatables.net/</a>.</p>\n                                <a class=\"btn btn-default btn-lg btn-block\" target=\"_blank\" href=\"https://datatables.net/\">View DataTables Documentation</a>\n                            </div>\n                        </div>\n                        <!-- /.panel-body -->\n                    </div>\n                    <!-- /.panel -->\n                </div>\n                <!-- /.col-lg-12 -->\n            </div>\n            <!-- /.row -->\n            <div class=\"row\">\n                <div class=\"col-lg-6\">\n                    <div class=\"panel panel-default\">\n                        <div class=\"panel-heading\">\n                            Kitchen Sink\n                        </div>\n                        <!-- /.panel-heading -->\n                        <div class=\"panel-body\">\n                            <div class=\"table-responsive\">\n                                <table class=\"table table-striped table-bordered table-hover\">\n                                    <thead>\n                                        <tr>\n                                            <th>#</th>\n                                            <th>First Name</th>\n                                            <th>Last Name</th>\n                                            <th>Username</th>\n                                        </tr>\n                                    </thead>\n                                    <tbody>\n                                        <tr>\n                                            <td>1</td>\n                                            <td>Mark</td>\n                                            <td>Otto</td>\n                                            <td>@mdo</td>\n                                        </tr>\n                                        <tr>\n                                            <td>2</td>\n                                            <td>Jacob</td>\n                                            <td>Thornton</td>\n                                            <td>@fat</td>\n                                        </tr>\n                                        <tr>\n                                            <td>3</td>\n                                            <td>Larry</td>\n                                            <td>the Bird</td>\n                                            <td>@twitter</td>\n                                        </tr>\n                                    </tbody>\n                                </table>\n                            </div>\n                            <!-- /.table-responsive -->\n                        </div>\n                        <!-- /.panel-body -->\n                    </div>\n                    <!-- /.panel -->\n                </div>\n                <!-- /.col-lg-6 -->\n                <div class=\"col-lg-6\">\n                    <div class=\"panel panel-default\">\n                        <div class=\"panel-heading\">\n                            Basic Table\n                        </div>\n                        <!-- /.panel-heading -->\n                        <div class=\"panel-body\">\n                            <div class=\"table-responsive\">\n                                <table class=\"table\">\n                                    <thead>\n                                        <tr>\n                                            <th>#</th>\n                                            <th>First Name</th>\n                                            <th>Last Name</th>\n                                            <th>Username</th>\n                                        </tr>\n                                    </thead>\n                                    <tbody>\n                                        <tr>\n                                            <td>1</td>\n                                            <td>Mark</td>\n                                            <td>Otto</td>\n                                            <td>@mdo</td>\n                                        </tr>\n                                        <tr>\n                                            <td>2</td>\n                                            <td>Jacob</td>\n                                            <td>Thornton</td>\n                                            <td>@fat</td>\n                                        </tr>\n                                        <tr>\n                                            <td>3</td>\n                                            <td>Larry</td>\n                                            <td>the Bird</td>\n                                            <td>@twitter</td>\n                                        </tr>\n                                    </tbody>\n                                </table>\n                            </div>\n                            <!-- /.table-responsive -->\n                        </div>\n                        <!-- /.panel-body -->\n                    </div>\n                    <!-- /.panel -->\n                </div>\n                <!-- /.col-lg-6 -->\n            </div>\n            <!-- /.row -->\n            <div class=\"row\">\n                <div class=\"col-lg-6\">\n                    <div class=\"panel panel-default\">\n                        <div class=\"panel-heading\">\n                            Striped Rows\n                        </div>\n                        <!-- /.panel-heading -->\n                        <div class=\"panel-body\">\n                            <div class=\"table-responsive\">\n                                <table class=\"table table-striped\">\n                                    <thead>\n                                        <tr>\n                                            <th>#</th>\n                                            <th>First Name</th>\n                                            <th>Last Name</th>\n                                            <th>Username</th>\n                                        </tr>\n                                    </thead>\n                                    <tbody>\n                                        <tr>\n                                            <td>1</td>\n                                            <td>Mark</td>\n                                            <td>Otto</td>\n                                            <td>@mdo</td>\n                                        </tr>\n                                        <tr>\n                                            <td>2</td>\n                                            <td>Jacob</td>\n                                            <td>Thornton</td>\n                                            <td>@fat</td>\n                                        </tr>\n                                        <tr>\n                                            <td>3</td>\n                                            <td>Larry</td>\n                                            <td>the Bird</td>\n                                            <td>@twitter</td>\n                                        </tr>\n                                    </tbody>\n                                </table>\n                            </div>\n                            <!-- /.table-responsive -->\n                        </div>\n                        <!-- /.panel-body -->\n                    </div>\n                    <!-- /.panel -->\n                </div>\n                <!-- /.col-lg-6 -->\n                <div class=\"col-lg-6\">\n                    <div class=\"panel panel-default\">\n                        <div class=\"panel-heading\">\n                            Bordered Table\n                        </div>\n                        <!-- /.panel-heading -->\n                        <div class=\"panel-body\">\n                            <div class=\"table-responsive table-bordered\">\n                                <table class=\"table\">\n                                    <thead>\n                                        <tr>\n                                            <th>#</th>\n                                            <th>First Name</th>\n                                            <th>Last Name</th>\n                                            <th>Username</th>\n                                        </tr>\n                                    </thead>\n                                    <tbody>\n                                        <tr>\n                                            <td>1</td>\n                                            <td>Mark</td>\n                                            <td>Otto</td>\n                                            <td>@mdo</td>\n                                        </tr>\n                                        <tr>\n                                            <td>2</td>\n                                            <td>Jacob</td>\n                                            <td>Thornton</td>\n                                            <td>@fat</td>\n                                        </tr>\n                                        <tr>\n                                            <td>3</td>\n                                            <td>Larry</td>\n                                            <td>the Bird</td>\n                                            <td>@twitter</td>\n                                        </tr>\n                                    </tbody>\n                                </table>\n                            </div>\n                            <!-- /.table-responsive -->\n                        </div>\n                        <!-- /.panel-body -->\n                    </div>\n                    <!-- /.panel -->\n                </div>\n                <!-- /.col-lg-6 -->\n            </div>\n            <!-- /.row -->\n            <div class=\"row\">\n                <div class=\"col-lg-6\">\n                    <div class=\"panel panel-default\">\n                        <div class=\"panel-heading\">\n                            Hover Rows\n                        </div>\n                        <!-- /.panel-heading -->\n                        <div class=\"panel-body\">\n                            <div class=\"table-responsive\">\n                                <table class=\"table table-hover\">\n                                    <thead>\n                                        <tr>\n                                            <th>#</th>\n                                            <th>First Name</th>\n                                            <th>Last Name</th>\n                                            <th>Username</th>\n                                        </tr>\n                                    </thead>\n                                    <tbody>\n                                        <tr>\n                                            <td>1</td>\n                                            <td>Mark</td>\n                                            <td>Otto</td>\n                                            <td>@mdo</td>\n                                        </tr>\n                                        <tr>\n                                            <td>2</td>\n                                            <td>Jacob</td>\n                                            <td>Thornton</td>\n                                            <td>@fat</td>\n                                        </tr>\n                                        <tr>\n                                            <td>3</td>\n                                            <td>Larry</td>\n                                            <td>the Bird</td>\n                                            <td>@twitter</td>\n                                        </tr>\n                                    </tbody>\n                                </table>\n                            </div>\n                            <!-- /.table-responsive -->\n                        </div>\n                        <!-- /.panel-body -->\n                    </div>\n                    <!-- /.panel -->\n                </div>\n                <!-- /.col-lg-6 -->\n                <div class=\"col-lg-6\">\n                    <div class=\"panel panel-default\">\n                        <div class=\"panel-heading\">\n                            Context Classes\n                        </div>\n                        <!-- /.panel-heading -->\n                        <div class=\"panel-body\">\n                            <div class=\"table-responsive\">\n                                <table class=\"table\">\n                                    <thead>\n                                        <tr>\n                                            <th>#</th>\n                                            <th>First Name</th>\n                                            <th>Last Name</th>\n                                            <th>Username</th>\n                                        </tr>\n                                    </thead>\n                                    <tbody>\n                                        <tr class=\"success\">\n                                            <td>1</td>\n                                            <td>Mark</td>\n                                            <td>Otto</td>\n                                            <td>@mdo</td>\n                                        </tr>\n                                        <tr class=\"info\">\n                                            <td>2</td>\n                                            <td>Jacob</td>\n                                            <td>Thornton</td>\n                                            <td>@fat</td>\n                                        </tr>\n                                        <tr class=\"warning\">\n                                            <td>3</td>\n                                            <td>Larry</td>\n                                            <td>the Bird</td>\n                                            <td>@twitter</td>\n                                        </tr>\n                                        <tr class=\"danger\">\n                                            <td>4</td>\n                                            <td>John</td>\n                                            <td>Smith</td>\n                                            <td>@jsmith</td>\n                                        </tr>\n                                    </tbody>\n                                </table>\n                            </div>\n                            <!-- /.table-responsive -->\n                        </div>\n                        <!-- /.panel-body -->\n                    </div>\n                    <!-- /.panel -->\n                </div>\n                <!-- /.col-lg-6 -->\n            </div>\n            <!-- /.row -->\n        </div>\n        <!-- /#page-wrapper -->\n\n    </div>\n    <!-- /#wrapper -->\n\n    <!-- jQuery -->\n    <script src=\"../vendor/jquery/jquery.min.js\"></script>\n\n    <!-- Bootstrap Core JavaScript -->\n    <script src=\"../vendor/bootstrap/js/bootstrap.min.js\"></script>\n\n    <!-- Metis Menu Plugin JavaScript -->\n    <script src=\"../vendor/metisMenu/metisMenu.min.js\"></script>\n\n    <!-- DataTables JavaScript -->\n    <script src=\"../vendor/datatables/js/jquery.dataTables.min.js\"></script>\n    <script src=\"../vendor/datatables-plugins/dataTables.bootstrap.min.js\"></script>\n    <script src=\"../vendor/datatables-responsive/dataTables.responsive.js\"></script>\n\n    <!-- Custom Theme JavaScript -->\n    <script src=\"../dist/js/sb-admin-2.js\"></script>\n\n    <!-- Page-Level Demo Scripts - Tables - Use for reference -->\n    <script>\n    $(document).ready(function() {\n        $('#dataTables-example').DataTable({\n            responsive: true\n        });\n    });\n    </script>\n\n</body>\n\n</html>\n"
  },
  {
    "path": "app_backend/pages/typography.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n\n<head>\n\n    <meta charset=\"utf-8\">\n    <meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\">\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">\n    <meta name=\"description\" content=\"\">\n    <meta name=\"author\" content=\"\">\n\n    <title>SB Admin 2 - Bootstrap Admin Theme</title>\n\n    <!-- Bootstrap Core CSS -->\n    <link href=\"../vendor/bootstrap/css/bootstrap.min.css\" rel=\"stylesheet\">\n\n    <!-- MetisMenu CSS -->\n    <link href=\"../vendor/metisMenu/metisMenu.min.css\" rel=\"stylesheet\">\n\n    <!-- Custom CSS -->\n    <link href=\"../dist/css/sb-admin-2.css\" rel=\"stylesheet\">\n\n    <!-- Custom Fonts -->\n    <link href=\"../vendor/font-awesome/css/font-awesome.min.css\" rel=\"stylesheet\" type=\"text/css\">\n\n    <!-- HTML5 Shim and Respond.js IE8 support of HTML5 elements and media queries -->\n    <!-- WARNING: Respond.js doesn't work if you view the page via file:// -->\n    <!--[if lt IE 9]>\n        <script src=\"https://oss.maxcdn.com/libs/html5shiv/3.7.0/html5shiv.js\"></script>\n        <script src=\"https://oss.maxcdn.com/libs/respond.js/1.4.2/respond.min.js\"></script>\n    <![endif]-->\n\n</head>\n\n<body>\n\n    <div id=\"wrapper\">\n\n        <!-- Navigation -->\n        <nav class=\"navbar navbar-default navbar-static-top\" role=\"navigation\" style=\"margin-bottom: 0\">\n            <div class=\"navbar-header\">\n                <button type=\"button\" class=\"navbar-toggle\" data-toggle=\"collapse\" data-target=\".navbar-collapse\">\n                    <span class=\"sr-only\">Toggle navigation</span>\n                    <span class=\"icon-bar\"></span>\n                    <span class=\"icon-bar\"></span>\n                    <span class=\"icon-bar\"></span>\n                </button>\n                <a class=\"navbar-brand\" href=\"index.html\">SB Admin v2.0</a>\n            </div>\n            <!-- /.navbar-header -->\n\n            <ul class=\"nav navbar-top-links navbar-right\">\n                <li class=\"dropdown\">\n                    <a class=\"dropdown-toggle\" data-toggle=\"dropdown\" href=\"#\">\n                        <i class=\"fa fa-envelope fa-fw\"></i> <i class=\"fa fa-caret-down\"></i>\n                    </a>\n                    <ul class=\"dropdown-menu dropdown-messages\">\n                        <li>\n                            <a href=\"#\">\n                                <div>\n                                    <strong>John Smith</strong>\n                                    <span class=\"pull-right text-muted\">\n                                        <em>Yesterday</em>\n                                    </span>\n                                </div>\n                                <div>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque eleifend...</div>\n                            </a>\n                        </li>\n                        <li class=\"divider\"></li>\n                        <li>\n                            <a href=\"#\">\n                                <div>\n                                    <strong>John Smith</strong>\n                                    <span class=\"pull-right text-muted\">\n                                        <em>Yesterday</em>\n                                    </span>\n                                </div>\n                                <div>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque eleifend...</div>\n                            </a>\n                        </li>\n                        <li class=\"divider\"></li>\n                        <li>\n                            <a href=\"#\">\n                                <div>\n                                    <strong>John Smith</strong>\n                                    <span class=\"pull-right text-muted\">\n                                        <em>Yesterday</em>\n                                    </span>\n                                </div>\n                                <div>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque eleifend...</div>\n                            </a>\n                        </li>\n                        <li class=\"divider\"></li>\n                        <li>\n                            <a class=\"text-center\" href=\"#\">\n                                <strong>Read All Messages</strong>\n                                <i class=\"fa fa-angle-right\"></i>\n                            </a>\n                        </li>\n                    </ul>\n                    <!-- /.dropdown-messages -->\n                </li>\n                <!-- /.dropdown -->\n                <li class=\"dropdown\">\n                    <a class=\"dropdown-toggle\" data-toggle=\"dropdown\" href=\"#\">\n                        <i class=\"fa fa-tasks fa-fw\"></i> <i class=\"fa fa-caret-down\"></i>\n                    </a>\n                    <ul class=\"dropdown-menu dropdown-tasks\">\n                        <li>\n                            <a href=\"#\">\n                                <div>\n                                    <p>\n                                        <strong>Task 1</strong>\n                                        <span class=\"pull-right text-muted\">40% Complete</span>\n                                    </p>\n                                    <div class=\"progress progress-striped active\">\n                                        <div class=\"progress-bar progress-bar-success\" role=\"progressbar\" aria-valuenow=\"40\" aria-valuemin=\"0\" aria-valuemax=\"100\" style=\"width: 40%\">\n                                            <span class=\"sr-only\">40% Complete (success)</span>\n                                        </div>\n                                    </div>\n                                </div>\n                            </a>\n                        </li>\n                        <li class=\"divider\"></li>\n                        <li>\n                            <a href=\"#\">\n                                <div>\n                                    <p>\n                                        <strong>Task 2</strong>\n                                        <span class=\"pull-right text-muted\">20% Complete</span>\n                                    </p>\n                                    <div class=\"progress progress-striped active\">\n                                        <div class=\"progress-bar progress-bar-info\" role=\"progressbar\" aria-valuenow=\"20\" aria-valuemin=\"0\" aria-valuemax=\"100\" style=\"width: 20%\">\n                                            <span class=\"sr-only\">20% Complete</span>\n                                        </div>\n                                    </div>\n                                </div>\n                            </a>\n                        </li>\n                        <li class=\"divider\"></li>\n                        <li>\n                            <a href=\"#\">\n                                <div>\n                                    <p>\n                                        <strong>Task 3</strong>\n                                        <span class=\"pull-right text-muted\">60% Complete</span>\n                                    </p>\n                                    <div class=\"progress progress-striped active\">\n                                        <div class=\"progress-bar progress-bar-warning\" role=\"progressbar\" aria-valuenow=\"60\" aria-valuemin=\"0\" aria-valuemax=\"100\" style=\"width: 60%\">\n                                            <span class=\"sr-only\">60% Complete (warning)</span>\n                                        </div>\n                                    </div>\n                                </div>\n                            </a>\n                        </li>\n                        <li class=\"divider\"></li>\n                        <li>\n                            <a href=\"#\">\n                                <div>\n                                    <p>\n                                        <strong>Task 4</strong>\n                                        <span class=\"pull-right text-muted\">80% Complete</span>\n                                    </p>\n                                    <div class=\"progress progress-striped active\">\n                                        <div class=\"progress-bar progress-bar-danger\" role=\"progressbar\" aria-valuenow=\"80\" aria-valuemin=\"0\" aria-valuemax=\"100\" style=\"width: 80%\">\n                                            <span class=\"sr-only\">80% Complete (danger)</span>\n                                        </div>\n                                    </div>\n                                </div>\n                            </a>\n                        </li>\n                        <li class=\"divider\"></li>\n                        <li>\n                            <a class=\"text-center\" href=\"#\">\n                                <strong>See All Tasks</strong>\n                                <i class=\"fa fa-angle-right\"></i>\n                            </a>\n                        </li>\n                    </ul>\n                    <!-- /.dropdown-tasks -->\n                </li>\n                <!-- /.dropdown -->\n                <li class=\"dropdown\">\n                    <a class=\"dropdown-toggle\" data-toggle=\"dropdown\" href=\"#\">\n                        <i class=\"fa fa-bell fa-fw\"></i> <i class=\"fa fa-caret-down\"></i>\n                    </a>\n                    <ul class=\"dropdown-menu dropdown-alerts\">\n                        <li>\n                            <a href=\"#\">\n                                <div>\n                                    <i class=\"fa fa-comment fa-fw\"></i> New Comment\n                                    <span class=\"pull-right text-muted small\">4 minutes ago</span>\n                                </div>\n                            </a>\n                        </li>\n                        <li class=\"divider\"></li>\n                        <li>\n                            <a href=\"#\">\n                                <div>\n                                    <i class=\"fa fa-twitter fa-fw\"></i> 3 New Followers\n                                    <span class=\"pull-right text-muted small\">12 minutes ago</span>\n                                </div>\n                            </a>\n                        </li>\n                        <li class=\"divider\"></li>\n                        <li>\n                            <a href=\"#\">\n                                <div>\n                                    <i class=\"fa fa-envelope fa-fw\"></i> Message Sent\n                                    <span class=\"pull-right text-muted small\">4 minutes ago</span>\n                                </div>\n                            </a>\n                        </li>\n                        <li class=\"divider\"></li>\n                        <li>\n                            <a href=\"#\">\n                                <div>\n                                    <i class=\"fa fa-tasks fa-fw\"></i> New Task\n                                    <span class=\"pull-right text-muted small\">4 minutes ago</span>\n                                </div>\n                            </a>\n                        </li>\n                        <li class=\"divider\"></li>\n                        <li>\n                            <a href=\"#\">\n                                <div>\n                                    <i class=\"fa fa-upload fa-fw\"></i> Server Rebooted\n                                    <span class=\"pull-right text-muted small\">4 minutes ago</span>\n                                </div>\n                            </a>\n                        </li>\n                        <li class=\"divider\"></li>\n                        <li>\n                            <a class=\"text-center\" href=\"#\">\n                                <strong>See All Alerts</strong>\n                                <i class=\"fa fa-angle-right\"></i>\n                            </a>\n                        </li>\n                    </ul>\n                    <!-- /.dropdown-alerts -->\n                </li>\n                <!-- /.dropdown -->\n                <li class=\"dropdown\">\n                    <a class=\"dropdown-toggle\" data-toggle=\"dropdown\" href=\"#\">\n                        <i class=\"fa fa-user fa-fw\"></i> <i class=\"fa fa-caret-down\"></i>\n                    </a>\n                    <ul class=\"dropdown-menu dropdown-user\">\n                        <li><a href=\"#\"><i class=\"fa fa-user fa-fw\"></i> User Profile</a>\n                        </li>\n                        <li><a href=\"#\"><i class=\"fa fa-gear fa-fw\"></i> Settings</a>\n                        </li>\n                        <li class=\"divider\"></li>\n                        <li><a href=\"login.html\"><i class=\"fa fa-sign-out fa-fw\"></i> Logout</a>\n                        </li>\n                    </ul>\n                    <!-- /.dropdown-user -->\n                </li>\n                <!-- /.dropdown -->\n            </ul>\n            <!-- /.navbar-top-links -->\n\n            <div class=\"navbar-default sidebar\" role=\"navigation\">\n                <div class=\"sidebar-nav navbar-collapse\">\n                    <ul class=\"nav\" id=\"side-menu\">\n                        <li class=\"sidebar-search\">\n                            <div class=\"input-group custom-search-form\">\n                                <input type=\"text\" class=\"form-control\" placeholder=\"Search...\">\n                                <span class=\"input-group-btn\">\n                                <button class=\"btn btn-default\" type=\"button\">\n                                    <i class=\"fa fa-search\"></i>\n                                </button>\n                            </span>\n                            </div>\n                            <!-- /input-group -->\n                        </li>\n                        <li>\n                            <a href=\"index.html\"><i class=\"fa fa-dashboard fa-fw\"></i> Dashboard</a>\n                        </li>\n                        <li>\n                            <a href=\"#\"><i class=\"fa fa-bar-chart-o fa-fw\"></i> Charts<span class=\"fa arrow\"></span></a>\n                            <ul class=\"nav nav-second-level\">\n                                <li>\n                                    <a href=\"flot.html\">Flot Charts</a>\n                                </li>\n                                <li>\n                                    <a href=\"morris.html\">Morris.js Charts</a>\n                                </li>\n                            </ul>\n                            <!-- /.nav-second-level -->\n                        </li>\n                        <li>\n                            <a href=\"tables.html\"><i class=\"fa fa-table fa-fw\"></i> Tables</a>\n                        </li>\n                        <li>\n                            <a href=\"forms.html\"><i class=\"fa fa-edit fa-fw\"></i> Forms</a>\n                        </li>\n                        <li>\n                            <a href=\"#\"><i class=\"fa fa-wrench fa-fw\"></i> UI Elements<span class=\"fa arrow\"></span></a>\n                            <ul class=\"nav nav-second-level\">\n                                <li>\n                                    <a href=\"panels-wells.html\">Panels and Wells</a>\n                                </li>\n                                <li>\n                                    <a href=\"buttons.html\">Buttons</a>\n                                </li>\n                                <li>\n                                    <a href=\"notifications.html\">Notifications</a>\n                                </li>\n                                <li>\n                                    <a href=\"typography.html\">Typography</a>\n                                </li>\n                                <li>\n                                    <a href=\"icons.html\"> Icons</a>\n                                </li>\n                                <li>\n                                    <a href=\"grid.html\">Grid</a>\n                                </li>\n                            </ul>\n                            <!-- /.nav-second-level -->\n                        </li>\n                        <li>\n                            <a href=\"#\"><i class=\"fa fa-sitemap fa-fw\"></i> Multi-Level Dropdown<span class=\"fa arrow\"></span></a>\n                            <ul class=\"nav nav-second-level\">\n                                <li>\n                                    <a href=\"#\">Second Level Item</a>\n                                </li>\n                                <li>\n                                    <a href=\"#\">Second Level Item</a>\n                                </li>\n                                <li>\n                                    <a href=\"#\">Third Level <span class=\"fa arrow\"></span></a>\n                                    <ul class=\"nav nav-third-level\">\n                                        <li>\n                                            <a href=\"#\">Third Level Item</a>\n                                        </li>\n                                        <li>\n                                            <a href=\"#\">Third Level Item</a>\n                                        </li>\n                                        <li>\n                                            <a href=\"#\">Third Level Item</a>\n                                        </li>\n                                        <li>\n                                            <a href=\"#\">Third Level Item</a>\n                                        </li>\n                                    </ul>\n                                    <!-- /.nav-third-level -->\n                                </li>\n                            </ul>\n                            <!-- /.nav-second-level -->\n                        </li>\n                        <li>\n                            <a href=\"#\"><i class=\"fa fa-files-o fa-fw\"></i> Sample Pages<span class=\"fa arrow\"></span></a>\n                            <ul class=\"nav nav-second-level\">\n                                <li>\n                                    <a href=\"blank.html\">Blank Page</a>\n                                </li>\n                                <li>\n                                    <a href=\"login.html\">Login Page</a>\n                                </li>\n                            </ul>\n                            <!-- /.nav-second-level -->\n                        </li>\n                    </ul>\n                </div>\n                <!-- /.sidebar-collapse -->\n            </div>\n            <!-- /.navbar-static-side -->\n        </nav>\n\n        <div id=\"page-wrapper\">\n            <div class=\"row\">\n                <div class=\"col-lg-12\">\n                    <h1 class=\"page-header\">Typography</h1>\n                </div>\n                <!-- /.col-lg-12 -->\n            </div>\n            <!-- /.row -->\n            <div class=\"row\">\n                <div class=\"col-lg-4\">\n                    <div class=\"panel panel-default\">\n                        <div class=\"panel-heading\">\n                            Headings\n                        </div>\n                        <div class=\"panel-body\">\n                            <h1>Heading 1\n                                <small>Sub-heading</small>\n                            </h1>\n                            <h2>Heading 2\n                                <small>Sub-heading</small>\n                            </h2>\n                            <h3>Heading 3\n                                <small>Sub-heading</small>\n                            </h3>\n                            <h4>Heading 4\n                                <small>Sub-heading</small>\n                            </h4>\n                            <h5>Heading 5\n                                <small>Sub-heading</small>\n                            </h5>\n                            <h6>Heading 6\n                                <small>Sub-heading</small>\n                            </h6>\n                        </div>\n                        <!-- /.panel-body -->\n                    </div>\n                    <!-- /.panel -->\n                </div>\n                <!-- /.col-lg-4 -->\n                <div class=\"col-lg-4\">\n                    <div class=\"panel panel-default\">\n                        <div class=\"panel-heading\">\n                            Paragraphs\n                        </div>\n                        <div class=\"panel-body\">\n                            <p class=\"lead\">This is an example of lead body copy.</p>\n                            <p>This is an example of standard paragraph text. This is an example of <a href=\"#\">link anchor text</a> within body copy.</p>\n                            <p>\n                                <small>This is an example of small, fine print text.</small>\n                            </p>\n                            <p>\n                                <strong>This is an example of strong, bold text.</strong>\n                            </p>\n                            <p>\n                                <em>This is an example of emphasized, italic text.</em>\n                            </p>\n                            <br>\n                            <h4>Alignment Helpers</h4>\n                            <p class=\"text-left\">Left aligned text.</p>\n                            <p class=\"text-center\">Center aligned text.</p>\n                            <p class=\"text-right\">Right aligned text.</p>\n                        </div>\n                        <!-- /.panel-body -->\n                    </div>\n                    <!-- /.panel -->\n                </div>\n                <!-- /.col-lg-4 -->\n                <div class=\"col-lg-4\">\n                    <div class=\"panel panel-default\">\n                        <div class=\"panel-heading\">\n                            Emphasis Classes\n                        </div>\n                        <div class=\"panel-body\">\n                            <p class=\"text-muted\">This is an example of muted text.</p>\n                            <p class=\"text-primary\">This is an example of primary text.</p>\n                            <p class=\"text-success\">This is an example of success text.</p>\n                            <p class=\"text-info\">This is an example of info text.</p>\n                            <p class=\"text-warning\">This is an example of warning text.</p>\n                            <p class=\"text-danger\">This is an example of danger text.</p>\n                        </div>\n                        <!-- /.panel-body -->\n                    </div>\n                    <!-- /.panel -->\n                </div>\n                <!-- /.col-lg-4 -->\n            </div>\n            <!-- /.row -->\n            <div class=\"row\">\n                <div class=\"col-lg-4\">\n                    <div class=\"panel panel-default\">\n                        <div class=\"panel-heading\">\n                            Abbreviations\n                        </div>\n                        <div class=\"panel-body\">\n                            <p>The abbreviation of the word attribute is\n                                <abbr title=\"attribute\">attr</abbr>.</p>\n                            <p>\n                                <abbr title=\"HyperText Markup Language\" class=\"initialism\">HTML</abbr>is an abbreviation for a programming language.</p>\n                            <br>\n                            <h4>Addresses</h4>\n                            <address>\n                                <strong>Twitter, Inc.</strong>\n                                <br>795 Folsom Ave, Suite 600\n                                <br>San Francisco, CA 94107\n                                <br>\n                                <abbr title=\"Phone\">P:</abbr>(123) 456-7890\n                            </address>\n                            <address>\n                                <strong>Full Name</strong>\n                                <br>\n                                <a href=\"mailto:#\">first.last@example.com</a>\n                            </address>\n                        </div>\n                        <!-- /.panel-body -->\n                    </div>\n                    <!-- /.panel -->\n                </div>\n                <!-- /.col-lg-4 -->\n                <div class=\"col-lg-4\">\n                    <div class=\"panel panel-default\">\n                        <div class=\"panel-heading\">\n                            Blockquotes\n                        </div>\n                        <div class=\"panel-body\">\n                            <h4>Default Blockquote</h4>\n                            <blockquote>\n                                <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer posuere erat a ante.</p>\n                            </blockquote>\n                            <h4>Blockquote with Citation</h4>\n                            <blockquote>\n                                <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer posuere erat a ante.</p>\n                                <small>Someone famous in\n                                    <cite title=\"Source Title\">Source Title</cite>\n                                </small>\n                            </blockquote>\n                            <h4>Right Aligned Blockquote</h4>\n                            <blockquote class=\"pull-right\">\n                                <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer posuere erat a ante.</p>\n                            </blockquote>\n                        </div>\n                        <!-- /.panel-body -->\n                    </div>\n                    <!-- /.panel -->\n                </div>\n                <!-- /.col-lg-4 -->\n                <div class=\"col-lg-4\">\n                    <div class=\"panel panel-default\">\n                        <div class=\"panel-heading\">\n                            Lists\n                        </div>\n                        <div class=\"panel-body\">\n                            <h4>Unordered List</h4>\n                            <ul>\n                                <li>List Item</li>\n                                <li>List Item</li>\n                                <li>\n                                    <ul>\n                                        <li>List Item</li>\n                                        <li>List Item</li>\n                                        <li>List Item</li>\n                                    </ul>\n                                </li>\n                                <li>List Item</li>\n                            </ul>\n                            <h4>Ordered List</h4>\n                            <ol>\n                                <li>List Item</li>\n                                <li>List Item</li>\n                                <li>List Item</li>\n                            </ol>\n                            <h4>Unstyled List</h4>\n                            <ul class=\"list-unstyled\">\n                                <li>List Item</li>\n                                <li>List Item</li>\n                                <li>List Item</li>\n                            </ul>\n                            <h4>Inline List</h4>\n                            <ul class=\"list-inline\">\n                                <li>List Item</li>\n                                <li>List Item</li>\n                                <li>List Item</li>\n                            </ul>\n                        </div>\n                        <!-- /.panel-body -->\n                    </div>\n                    <!-- /.panel -->\n                </div>\n                <!-- /.col-lg-4 -->\n            </div>\n            <!-- /.row -->\n            <div class=\"row\">\n                <div class=\"col-lg-4\">\n                    <div class=\"panel panel-default\">\n                        <div class=\"panel-heading\">\n                            Description Lists\n                        </div>\n                        <div class=\"panel-body\">\n                            <dl>\n                                <dt>Standard Description List</dt>\n                                <dd>Description Text</dd>\n                                <dt>Description List Title</dt>\n                                <dd>Description List Text</dd>\n                            </dl>\n                            <dl class=\"dl-horizontal\">\n                                <dt>Horizontal Description List</dt>\n                                <dd>Description Text</dd>\n                                <dt>Description List Title</dt>\n                                <dd>Description List Text</dd>\n                            </dl>\n                        </div>\n                        <!-- /.panel-body -->\n                    </div>\n                    <!-- /.panel -->\n                </div>\n                <!-- /.col-lg-4 -->\n                <div class=\"col-lg-4\">\n                    <div class=\"panel panel-default\">\n                        <div class=\"panel-heading\">\n                            Code\n                        </div>\n                        <div class=\"panel-body\">\n                            <p>This is an example of an inline code element within body copy. Wrap inline code within a\n                                <code>&lt;code&gt;...&lt;/code&gt;</code>tag.</p>\n                            <pre>This is an example of preformatted text.</pre>\n                        </div>\n                        <!-- /.panel-body -->\n                    </div>\n                    <!-- /.panel -->\n                </div>\n                <!-- /.col-lg-4 -->\n            </div>\n            <!-- /.row -->\n        </div>\n        <!-- /#page-wrapper -->\n\n    </div>\n    <!-- /#wrapper -->\n\n    <!-- jQuery -->\n    <script src=\"../vendor/jquery/jquery.min.js\"></script>\n\n    <!-- Bootstrap Core JavaScript -->\n    <script src=\"../vendor/bootstrap/js/bootstrap.min.js\"></script>\n\n    <!-- Metis Menu Plugin JavaScript -->\n    <script src=\"../vendor/metisMenu/metisMenu.min.js\"></script>\n\n    <!-- Custom Theme JavaScript -->\n    <script src=\"../dist/js/sb-admin-2.js\"></script>\n\n</body>\n\n</html>\n"
  },
  {
    "path": "app_backend/permissions.py",
    "content": "#!/usr/bin/env python\n# encoding: utf-8\n\n\"\"\"\n@author: zhanghe\n@software: PyCharm\n@file: permissions.py\n@time: 2017/6/8 下午11:16\n\"\"\"\n\n\nfrom flask_principal import Permission, RoleNeed\n\n\n# 模块列表\n\nmodules = [\n    u'会员',\n    u'订单',\n    u'留言',\n    u'系统',\n    u'权限',\n    u'统计',\n]\n\n# 模块权限\npermission_user = Permission(RoleNeed(u'会员'))\npermission_order = Permission(RoleNeed(u'订单'))\npermission_msg = Permission(RoleNeed(u'留言'))\npermission_sys = Permission(RoleNeed(u'系统'))\npermission_admin = Permission(RoleNeed(u'权限'))\npermission_stats = Permission(RoleNeed(u'统计'))\npermission_other = Permission(RoleNeed(u'其它'))\n"
  },
  {
    "path": "app_backend/static/css/bootstrap-select.css",
    "content": "/*!\r\n * Bootstrap-select v1.12.2 (http://silviomoreto.github.io/bootstrap-select)\r\n *\r\n * Copyright 2013-2017 bootstrap-select\r\n * Licensed under MIT (https://github.com/silviomoreto/bootstrap-select/blob/master/LICENSE)\r\n */\r\n\r\nselect.bs-select-hidden,\nselect.selectpicker {\n  display: none !important;\n}\n.bootstrap-select {\n  width: 220px \\0;\n  /*IE9 and below*/\n}\n.bootstrap-select > .dropdown-toggle {\n  width: 100%;\n  padding-right: 25px;\n  z-index: 1;\n}\n.bootstrap-select > .dropdown-toggle.bs-placeholder,\n.bootstrap-select > .dropdown-toggle.bs-placeholder:hover,\n.bootstrap-select > .dropdown-toggle.bs-placeholder:focus,\n.bootstrap-select > .dropdown-toggle.bs-placeholder:active {\n  color: #999;\n}\n.bootstrap-select > select {\n  position: absolute !important;\n  bottom: 0;\n  left: 50%;\n  display: block !important;\n  width: 0.5px !important;\n  height: 100% !important;\n  padding: 0 !important;\n  opacity: 0 !important;\n  border: none;\n}\n.bootstrap-select > select.mobile-device {\n  top: 0;\n  left: 0;\n  display: block !important;\n  width: 100% !important;\n  z-index: 2;\n}\n.has-error .bootstrap-select .dropdown-toggle,\n.error .bootstrap-select .dropdown-toggle {\n  border-color: #b94a48;\n}\n.bootstrap-select.fit-width {\n  width: auto !important;\n}\n.bootstrap-select:not([class*=\"col-\"]):not([class*=\"form-control\"]):not(.input-group-btn) {\n  width: 220px;\n}\n.bootstrap-select .dropdown-toggle:focus {\n  outline: thin dotted #333333 !important;\n  outline: 5px auto -webkit-focus-ring-color !important;\n  outline-offset: -2px;\n}\n.bootstrap-select.form-control {\n  margin-bottom: 0;\n  padding: 0;\n  border: none;\n}\n.bootstrap-select.form-control:not([class*=\"col-\"]) {\n  width: 100%;\n}\n.bootstrap-select.form-control.input-group-btn {\n  z-index: auto;\n}\n.bootstrap-select.form-control.input-group-btn:not(:first-child):not(:last-child) > .btn {\n  border-radius: 0;\n}\n.bootstrap-select.btn-group:not(.input-group-btn),\n.bootstrap-select.btn-group[class*=\"col-\"] {\n  float: none;\n  display: inline-block;\n  margin-left: 0;\n}\n.bootstrap-select.btn-group.dropdown-menu-right,\n.bootstrap-select.btn-group[class*=\"col-\"].dropdown-menu-right,\n.row .bootstrap-select.btn-group[class*=\"col-\"].dropdown-menu-right {\n  float: right;\n}\n.form-inline .bootstrap-select.btn-group,\n.form-horizontal .bootstrap-select.btn-group,\n.form-group .bootstrap-select.btn-group {\n  margin-bottom: 0;\n}\n.form-group-lg .bootstrap-select.btn-group.form-control,\n.form-group-sm .bootstrap-select.btn-group.form-control {\n  padding: 0;\n}\n.form-group-lg .bootstrap-select.btn-group.form-control .dropdown-toggle,\n.form-group-sm .bootstrap-select.btn-group.form-control .dropdown-toggle {\n  height: 100%;\n  font-size: inherit;\n  line-height: inherit;\n  border-radius: inherit;\n}\n.form-inline .bootstrap-select.btn-group .form-control {\n  width: 100%;\n}\n.bootstrap-select.btn-group.disabled,\n.bootstrap-select.btn-group > .disabled {\n  cursor: not-allowed;\n}\n.bootstrap-select.btn-group.disabled:focus,\n.bootstrap-select.btn-group > .disabled:focus {\n  outline: none !important;\n}\n.bootstrap-select.btn-group.bs-container {\n  position: absolute;\n  height: 0 !important;\n  padding: 0 !important;\n}\n.bootstrap-select.btn-group.bs-container .dropdown-menu {\n  z-index: 1060;\n}\n.bootstrap-select.btn-group .dropdown-toggle .filter-option {\n  display: inline-block;\n  overflow: hidden;\n  width: 100%;\n  text-align: left;\n}\n.bootstrap-select.btn-group .dropdown-toggle .caret {\n  position: absolute;\n  top: 50%;\n  right: 12px;\n  margin-top: -2px;\n  vertical-align: middle;\n}\n.bootstrap-select.btn-group[class*=\"col-\"] .dropdown-toggle {\n  width: 100%;\n}\n.bootstrap-select.btn-group .dropdown-menu {\n  min-width: 100%;\n  -webkit-box-sizing: border-box;\n     -moz-box-sizing: border-box;\n          box-sizing: border-box;\n}\n.bootstrap-select.btn-group .dropdown-menu.inner {\n  position: static;\n  float: none;\n  border: 0;\n  padding: 0;\n  margin: 0;\n  border-radius: 0;\n  -webkit-box-shadow: none;\n          box-shadow: none;\n}\n.bootstrap-select.btn-group .dropdown-menu li {\n  position: relative;\n}\n.bootstrap-select.btn-group .dropdown-menu li.active small {\n  color: #fff;\n}\n.bootstrap-select.btn-group .dropdown-menu li.disabled a {\n  cursor: not-allowed;\n}\n.bootstrap-select.btn-group .dropdown-menu li a {\n  cursor: pointer;\n  -webkit-user-select: none;\n     -moz-user-select: none;\n      -ms-user-select: none;\n          user-select: none;\n}\n.bootstrap-select.btn-group .dropdown-menu li a.opt {\n  position: relative;\n  padding-left: 2.25em;\n}\n.bootstrap-select.btn-group .dropdown-menu li a span.check-mark {\n  display: none;\n}\n.bootstrap-select.btn-group .dropdown-menu li a span.text {\n  display: inline-block;\n}\n.bootstrap-select.btn-group .dropdown-menu li small {\n  padding-left: 0.5em;\n}\n.bootstrap-select.btn-group .dropdown-menu .notify {\n  position: absolute;\n  bottom: 5px;\n  width: 96%;\n  margin: 0 2%;\n  min-height: 26px;\n  padding: 3px 5px;\n  background: #f5f5f5;\n  border: 1px solid #e3e3e3;\n  -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.05);\n          box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.05);\n  pointer-events: none;\n  opacity: 0.9;\n  -webkit-box-sizing: border-box;\n     -moz-box-sizing: border-box;\n          box-sizing: border-box;\n}\n.bootstrap-select.btn-group .no-results {\n  padding: 3px;\n  background: #f5f5f5;\n  margin: 0 5px;\n  white-space: nowrap;\n}\n.bootstrap-select.btn-group.fit-width .dropdown-toggle .filter-option {\n  position: static;\n}\n.bootstrap-select.btn-group.fit-width .dropdown-toggle .caret {\n  position: static;\n  top: auto;\n  margin-top: -1px;\n}\n.bootstrap-select.btn-group.show-tick .dropdown-menu li.selected a span.check-mark {\n  position: absolute;\n  display: inline-block;\n  right: 15px;\n  margin-top: 5px;\n}\n.bootstrap-select.btn-group.show-tick .dropdown-menu li a span.text {\n  margin-right: 34px;\n}\n.bootstrap-select.show-menu-arrow.open > .dropdown-toggle {\n  z-index: 1061;\n}\n.bootstrap-select.show-menu-arrow .dropdown-toggle:before {\n  content: '';\n  border-left: 7px solid transparent;\n  border-right: 7px solid transparent;\n  border-bottom: 7px solid rgba(204, 204, 204, 0.2);\n  position: absolute;\n  bottom: -4px;\n  left: 9px;\n  display: none;\n}\n.bootstrap-select.show-menu-arrow .dropdown-toggle:after {\n  content: '';\n  border-left: 6px solid transparent;\n  border-right: 6px solid transparent;\n  border-bottom: 6px solid white;\n  position: absolute;\n  bottom: -4px;\n  left: 10px;\n  display: none;\n}\n.bootstrap-select.show-menu-arrow.dropup .dropdown-toggle:before {\n  bottom: auto;\n  top: -3px;\n  border-top: 7px solid rgba(204, 204, 204, 0.2);\n  border-bottom: 0;\n}\n.bootstrap-select.show-menu-arrow.dropup .dropdown-toggle:after {\n  bottom: auto;\n  top: -3px;\n  border-top: 6px solid white;\n  border-bottom: 0;\n}\n.bootstrap-select.show-menu-arrow.pull-right .dropdown-toggle:before {\n  right: 12px;\n  left: auto;\n}\n.bootstrap-select.show-menu-arrow.pull-right .dropdown-toggle:after {\n  right: 13px;\n  left: auto;\n}\n.bootstrap-select.show-menu-arrow.open > .dropdown-toggle:before,\n.bootstrap-select.show-menu-arrow.open > .dropdown-toggle:after {\n  display: block;\n}\n.bs-searchbox,\n.bs-actionsbox,\n.bs-donebutton {\n  padding: 4px 8px;\n}\n.bs-actionsbox {\n  width: 100%;\n  -webkit-box-sizing: border-box;\n     -moz-box-sizing: border-box;\n          box-sizing: border-box;\n}\n.bs-actionsbox .btn-group button {\n  width: 50%;\n}\n.bs-donebutton {\n  float: left;\n  width: 100%;\n  -webkit-box-sizing: border-box;\n     -moz-box-sizing: border-box;\n          box-sizing: border-box;\n}\n.bs-donebutton .btn-group button {\n  width: 100%;\n}\n.bs-searchbox + .bs-actionsbox {\n  padding: 0 8px 4px;\n}\n.bs-searchbox .form-control {\n  margin-bottom: 0;\n  width: 100%;\n  float: none;\n}\n/*# sourceMappingURL=bootstrap-select.css.map */"
  },
  {
    "path": "app_backend/static/css/bootstrap-theme.css",
    "content": "/*!\n * Bootstrap v3.3.5 (http://getbootstrap.com)\n * Copyright 2011-2015 Twitter, Inc.\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)\n */\n.btn-default,\n.btn-primary,\n.btn-success,\n.btn-info,\n.btn-warning,\n.btn-danger {\n  text-shadow: 0 -1px 0 rgba(0, 0, 0, .2);\n  -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, .15), 0 1px 1px rgba(0, 0, 0, .075);\n          box-shadow: inset 0 1px 0 rgba(255, 255, 255, .15), 0 1px 1px rgba(0, 0, 0, .075);\n}\n.btn-default:active,\n.btn-primary:active,\n.btn-success:active,\n.btn-info:active,\n.btn-warning:active,\n.btn-danger:active,\n.btn-default.active,\n.btn-primary.active,\n.btn-success.active,\n.btn-info.active,\n.btn-warning.active,\n.btn-danger.active {\n  -webkit-box-shadow: inset 0 3px 5px rgba(0, 0, 0, .125);\n          box-shadow: inset 0 3px 5px rgba(0, 0, 0, .125);\n}\n.btn-default.disabled,\n.btn-primary.disabled,\n.btn-success.disabled,\n.btn-info.disabled,\n.btn-warning.disabled,\n.btn-danger.disabled,\n.btn-default[disabled],\n.btn-primary[disabled],\n.btn-success[disabled],\n.btn-info[disabled],\n.btn-warning[disabled],\n.btn-danger[disabled],\nfieldset[disabled] .btn-default,\nfieldset[disabled] .btn-primary,\nfieldset[disabled] .btn-success,\nfieldset[disabled] .btn-info,\nfieldset[disabled] .btn-warning,\nfieldset[disabled] .btn-danger {\n  -webkit-box-shadow: none;\n          box-shadow: none;\n}\n.btn-default .badge,\n.btn-primary .badge,\n.btn-success .badge,\n.btn-info .badge,\n.btn-warning .badge,\n.btn-danger .badge {\n  text-shadow: none;\n}\n.btn:active,\n.btn.active {\n  background-image: none;\n}\n.btn-default {\n  text-shadow: 0 1px 0 #fff;\n  background-image: -webkit-linear-gradient(top, #fff 0%, #e0e0e0 100%);\n  background-image:      -o-linear-gradient(top, #fff 0%, #e0e0e0 100%);\n  background-image: -webkit-gradient(linear, left top, left bottom, from(#fff), to(#e0e0e0));\n  background-image:         linear-gradient(to bottom, #fff 0%, #e0e0e0 100%);\n  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#ffe0e0e0', GradientType=0);\n  filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);\n  background-repeat: repeat-x;\n  border-color: #dbdbdb;\n  border-color: #ccc;\n}\n.btn-default:hover,\n.btn-default:focus {\n  background-color: #e0e0e0;\n  background-position: 0 -15px;\n}\n.btn-default:active,\n.btn-default.active {\n  background-color: #e0e0e0;\n  border-color: #dbdbdb;\n}\n.btn-default.disabled,\n.btn-default[disabled],\nfieldset[disabled] .btn-default,\n.btn-default.disabled:hover,\n.btn-default[disabled]:hover,\nfieldset[disabled] .btn-default:hover,\n.btn-default.disabled:focus,\n.btn-default[disabled]:focus,\nfieldset[disabled] .btn-default:focus,\n.btn-default.disabled.focus,\n.btn-default[disabled].focus,\nfieldset[disabled] .btn-default.focus,\n.btn-default.disabled:active,\n.btn-default[disabled]:active,\nfieldset[disabled] .btn-default:active,\n.btn-default.disabled.active,\n.btn-default[disabled].active,\nfieldset[disabled] .btn-default.active {\n  background-color: #e0e0e0;\n  background-image: none;\n}\n.btn-primary {\n  background-image: -webkit-linear-gradient(top, #337ab7 0%, #265a88 100%);\n  background-image:      -o-linear-gradient(top, #337ab7 0%, #265a88 100%);\n  background-image: -webkit-gradient(linear, left top, left bottom, from(#337ab7), to(#265a88));\n  background-image:         linear-gradient(to bottom, #337ab7 0%, #265a88 100%);\n  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff265a88', GradientType=0);\n  filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);\n  background-repeat: repeat-x;\n  border-color: #245580;\n}\n.btn-primary:hover,\n.btn-primary:focus {\n  background-color: #265a88;\n  background-position: 0 -15px;\n}\n.btn-primary:active,\n.btn-primary.active {\n  background-color: #265a88;\n  border-color: #245580;\n}\n.btn-primary.disabled,\n.btn-primary[disabled],\nfieldset[disabled] .btn-primary,\n.btn-primary.disabled:hover,\n.btn-primary[disabled]:hover,\nfieldset[disabled] .btn-primary:hover,\n.btn-primary.disabled:focus,\n.btn-primary[disabled]:focus,\nfieldset[disabled] .btn-primary:focus,\n.btn-primary.disabled.focus,\n.btn-primary[disabled].focus,\nfieldset[disabled] .btn-primary.focus,\n.btn-primary.disabled:active,\n.btn-primary[disabled]:active,\nfieldset[disabled] .btn-primary:active,\n.btn-primary.disabled.active,\n.btn-primary[disabled].active,\nfieldset[disabled] .btn-primary.active {\n  background-color: #265a88;\n  background-image: none;\n}\n.btn-success {\n  background-image: -webkit-linear-gradient(top, #5cb85c 0%, #419641 100%);\n  background-image:      -o-linear-gradient(top, #5cb85c 0%, #419641 100%);\n  background-image: -webkit-gradient(linear, left top, left bottom, from(#5cb85c), to(#419641));\n  background-image:         linear-gradient(to bottom, #5cb85c 0%, #419641 100%);\n  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5cb85c', endColorstr='#ff419641', GradientType=0);\n  filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);\n  background-repeat: repeat-x;\n  border-color: #3e8f3e;\n}\n.btn-success:hover,\n.btn-success:focus {\n  background-color: #419641;\n  background-position: 0 -15px;\n}\n.btn-success:active,\n.btn-success.active {\n  background-color: #419641;\n  border-color: #3e8f3e;\n}\n.btn-success.disabled,\n.btn-success[disabled],\nfieldset[disabled] .btn-success,\n.btn-success.disabled:hover,\n.btn-success[disabled]:hover,\nfieldset[disabled] .btn-success:hover,\n.btn-success.disabled:focus,\n.btn-success[disabled]:focus,\nfieldset[disabled] .btn-success:focus,\n.btn-success.disabled.focus,\n.btn-success[disabled].focus,\nfieldset[disabled] .btn-success.focus,\n.btn-success.disabled:active,\n.btn-success[disabled]:active,\nfieldset[disabled] .btn-success:active,\n.btn-success.disabled.active,\n.btn-success[disabled].active,\nfieldset[disabled] .btn-success.active {\n  background-color: #419641;\n  background-image: none;\n}\n.btn-info {\n  background-image: -webkit-linear-gradient(top, #5bc0de 0%, #2aabd2 100%);\n  background-image:      -o-linear-gradient(top, #5bc0de 0%, #2aabd2 100%);\n  background-image: -webkit-gradient(linear, left top, left bottom, from(#5bc0de), to(#2aabd2));\n  background-image:         linear-gradient(to bottom, #5bc0de 0%, #2aabd2 100%);\n  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de', endColorstr='#ff2aabd2', GradientType=0);\n  filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);\n  background-repeat: repeat-x;\n  border-color: #28a4c9;\n}\n.btn-info:hover,\n.btn-info:focus {\n  background-color: #2aabd2;\n  background-position: 0 -15px;\n}\n.btn-info:active,\n.btn-info.active {\n  background-color: #2aabd2;\n  border-color: #28a4c9;\n}\n.btn-info.disabled,\n.btn-info[disabled],\nfieldset[disabled] .btn-info,\n.btn-info.disabled:hover,\n.btn-info[disabled]:hover,\nfieldset[disabled] .btn-info:hover,\n.btn-info.disabled:focus,\n.btn-info[disabled]:focus,\nfieldset[disabled] .btn-info:focus,\n.btn-info.disabled.focus,\n.btn-info[disabled].focus,\nfieldset[disabled] .btn-info.focus,\n.btn-info.disabled:active,\n.btn-info[disabled]:active,\nfieldset[disabled] .btn-info:active,\n.btn-info.disabled.active,\n.btn-info[disabled].active,\nfieldset[disabled] .btn-info.active {\n  background-color: #2aabd2;\n  background-image: none;\n}\n.btn-warning {\n  background-image: -webkit-linear-gradient(top, #f0ad4e 0%, #eb9316 100%);\n  background-image:      -o-linear-gradient(top, #f0ad4e 0%, #eb9316 100%);\n  background-image: -webkit-gradient(linear, left top, left bottom, from(#f0ad4e), to(#eb9316));\n  background-image:         linear-gradient(to bottom, #f0ad4e 0%, #eb9316 100%);\n  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff0ad4e', endColorstr='#ffeb9316', GradientType=0);\n  filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);\n  background-repeat: repeat-x;\n  border-color: #e38d13;\n}\n.btn-warning:hover,\n.btn-warning:focus {\n  background-color: #eb9316;\n  background-position: 0 -15px;\n}\n.btn-warning:active,\n.btn-warning.active {\n  background-color: #eb9316;\n  border-color: #e38d13;\n}\n.btn-warning.disabled,\n.btn-warning[disabled],\nfieldset[disabled] .btn-warning,\n.btn-warning.disabled:hover,\n.btn-warning[disabled]:hover,\nfieldset[disabled] .btn-warning:hover,\n.btn-warning.disabled:focus,\n.btn-warning[disabled]:focus,\nfieldset[disabled] .btn-warning:focus,\n.btn-warning.disabled.focus,\n.btn-warning[disabled].focus,\nfieldset[disabled] .btn-warning.focus,\n.btn-warning.disabled:active,\n.btn-warning[disabled]:active,\nfieldset[disabled] .btn-warning:active,\n.btn-warning.disabled.active,\n.btn-warning[disabled].active,\nfieldset[disabled] .btn-warning.active {\n  background-color: #eb9316;\n  background-image: none;\n}\n.btn-danger {\n  background-image: -webkit-linear-gradient(top, #d9534f 0%, #c12e2a 100%);\n  background-image:      -o-linear-gradient(top, #d9534f 0%, #c12e2a 100%);\n  background-image: -webkit-gradient(linear, left top, left bottom, from(#d9534f), to(#c12e2a));\n  background-image:         linear-gradient(to bottom, #d9534f 0%, #c12e2a 100%);\n  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9534f', endColorstr='#ffc12e2a', GradientType=0);\n  filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);\n  background-repeat: repeat-x;\n  border-color: #b92c28;\n}\n.btn-danger:hover,\n.btn-danger:focus {\n  background-color: #c12e2a;\n  background-position: 0 -15px;\n}\n.btn-danger:active,\n.btn-danger.active {\n  background-color: #c12e2a;\n  border-color: #b92c28;\n}\n.btn-danger.disabled,\n.btn-danger[disabled],\nfieldset[disabled] .btn-danger,\n.btn-danger.disabled:hover,\n.btn-danger[disabled]:hover,\nfieldset[disabled] .btn-danger:hover,\n.btn-danger.disabled:focus,\n.btn-danger[disabled]:focus,\nfieldset[disabled] .btn-danger:focus,\n.btn-danger.disabled.focus,\n.btn-danger[disabled].focus,\nfieldset[disabled] .btn-danger.focus,\n.btn-danger.disabled:active,\n.btn-danger[disabled]:active,\nfieldset[disabled] .btn-danger:active,\n.btn-danger.disabled.active,\n.btn-danger[disabled].active,\nfieldset[disabled] .btn-danger.active {\n  background-color: #c12e2a;\n  background-image: none;\n}\n.thumbnail,\n.img-thumbnail {\n  -webkit-box-shadow: 0 1px 2px rgba(0, 0, 0, .075);\n          box-shadow: 0 1px 2px rgba(0, 0, 0, .075);\n}\n.dropdown-menu > li > a:hover,\n.dropdown-menu > li > a:focus {\n  background-color: #e8e8e8;\n  background-image: -webkit-linear-gradient(top, #f5f5f5 0%, #e8e8e8 100%);\n  background-image:      -o-linear-gradient(top, #f5f5f5 0%, #e8e8e8 100%);\n  background-image: -webkit-gradient(linear, left top, left bottom, from(#f5f5f5), to(#e8e8e8));\n  background-image:         linear-gradient(to bottom, #f5f5f5 0%, #e8e8e8 100%);\n  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff5f5f5', endColorstr='#ffe8e8e8', GradientType=0);\n  background-repeat: repeat-x;\n}\n.dropdown-menu > .active > a,\n.dropdown-menu > .active > a:hover,\n.dropdown-menu > .active > a:focus {\n  background-color: #2e6da4;\n  background-image: -webkit-linear-gradient(top, #337ab7 0%, #2e6da4 100%);\n  background-image:      -o-linear-gradient(top, #337ab7 0%, #2e6da4 100%);\n  background-image: -webkit-gradient(linear, left top, left bottom, from(#337ab7), to(#2e6da4));\n  background-image:         linear-gradient(to bottom, #337ab7 0%, #2e6da4 100%);\n  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2e6da4', GradientType=0);\n  background-repeat: repeat-x;\n}\n.navbar-default {\n  background-image: -webkit-linear-gradient(top, #fff 0%, #f8f8f8 100%);\n  background-image:      -o-linear-gradient(top, #fff 0%, #f8f8f8 100%);\n  background-image: -webkit-gradient(linear, left top, left bottom, from(#fff), to(#f8f8f8));\n  background-image:         linear-gradient(to bottom, #fff 0%, #f8f8f8 100%);\n  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#fff8f8f8', GradientType=0);\n  filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);\n  background-repeat: repeat-x;\n  border-radius: 4px;\n  -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, .15), 0 1px 5px rgba(0, 0, 0, .075);\n          box-shadow: inset 0 1px 0 rgba(255, 255, 255, .15), 0 1px 5px rgba(0, 0, 0, .075);\n}\n.navbar-default .navbar-nav > .open > a,\n.navbar-default .navbar-nav > .active > a {\n  background-image: -webkit-linear-gradient(top, #dbdbdb 0%, #e2e2e2 100%);\n  background-image:      -o-linear-gradient(top, #dbdbdb 0%, #e2e2e2 100%);\n  background-image: -webkit-gradient(linear, left top, left bottom, from(#dbdbdb), to(#e2e2e2));\n  background-image:         linear-gradient(to bottom, #dbdbdb 0%, #e2e2e2 100%);\n  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdbdbdb', endColorstr='#ffe2e2e2', GradientType=0);\n  background-repeat: repeat-x;\n  -webkit-box-shadow: inset 0 3px 9px rgba(0, 0, 0, .075);\n          box-shadow: inset 0 3px 9px rgba(0, 0, 0, .075);\n}\n.navbar-brand,\n.navbar-nav > li > a {\n  text-shadow: 0 1px 0 rgba(255, 255, 255, .25);\n}\n.navbar-inverse {\n  background-image: -webkit-linear-gradient(top, #3c3c3c 0%, #222 100%);\n  background-image:      -o-linear-gradient(top, #3c3c3c 0%, #222 100%);\n  background-image: -webkit-gradient(linear, left top, left bottom, from(#3c3c3c), to(#222));\n  background-image:         linear-gradient(to bottom, #3c3c3c 0%, #222 100%);\n  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff3c3c3c', endColorstr='#ff222222', GradientType=0);\n  filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);\n  background-repeat: repeat-x;\n  border-radius: 4px;\n}\n.navbar-inverse .navbar-nav > .open > a,\n.navbar-inverse .navbar-nav > .active > a {\n  background-image: -webkit-linear-gradient(top, #080808 0%, #0f0f0f 100%);\n  background-image:      -o-linear-gradient(top, #080808 0%, #0f0f0f 100%);\n  background-image: -webkit-gradient(linear, left top, left bottom, from(#080808), to(#0f0f0f));\n  background-image:         linear-gradient(to bottom, #080808 0%, #0f0f0f 100%);\n  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff080808', endColorstr='#ff0f0f0f', GradientType=0);\n  background-repeat: repeat-x;\n  -webkit-box-shadow: inset 0 3px 9px rgba(0, 0, 0, .25);\n          box-shadow: inset 0 3px 9px rgba(0, 0, 0, .25);\n}\n.navbar-inverse .navbar-brand,\n.navbar-inverse .navbar-nav > li > a {\n  text-shadow: 0 -1px 0 rgba(0, 0, 0, .25);\n}\n.navbar-static-top,\n.navbar-fixed-top,\n.navbar-fixed-bottom {\n  border-radius: 0;\n}\n@media (max-width: 767px) {\n  .navbar .navbar-nav .open .dropdown-menu > .active > a,\n  .navbar .navbar-nav .open .dropdown-menu > .active > a:hover,\n  .navbar .navbar-nav .open .dropdown-menu > .active > a:focus {\n    color: #fff;\n    background-image: -webkit-linear-gradient(top, #337ab7 0%, #2e6da4 100%);\n    background-image:      -o-linear-gradient(top, #337ab7 0%, #2e6da4 100%);\n    background-image: -webkit-gradient(linear, left top, left bottom, from(#337ab7), to(#2e6da4));\n    background-image:         linear-gradient(to bottom, #337ab7 0%, #2e6da4 100%);\n    filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2e6da4', GradientType=0);\n    background-repeat: repeat-x;\n  }\n}\n.alert {\n  text-shadow: 0 1px 0 rgba(255, 255, 255, .2);\n  -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, .25), 0 1px 2px rgba(0, 0, 0, .05);\n          box-shadow: inset 0 1px 0 rgba(255, 255, 255, .25), 0 1px 2px rgba(0, 0, 0, .05);\n}\n.alert-success {\n  background-image: -webkit-linear-gradient(top, #dff0d8 0%, #c8e5bc 100%);\n  background-image:      -o-linear-gradient(top, #dff0d8 0%, #c8e5bc 100%);\n  background-image: -webkit-gradient(linear, left top, left bottom, from(#dff0d8), to(#c8e5bc));\n  background-image:         linear-gradient(to bottom, #dff0d8 0%, #c8e5bc 100%);\n  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdff0d8', endColorstr='#ffc8e5bc', GradientType=0);\n  background-repeat: repeat-x;\n  border-color: #b2dba1;\n}\n.alert-info {\n  background-image: -webkit-linear-gradient(top, #d9edf7 0%, #b9def0 100%);\n  background-image:      -o-linear-gradient(top, #d9edf7 0%, #b9def0 100%);\n  background-image: -webkit-gradient(linear, left top, left bottom, from(#d9edf7), to(#b9def0));\n  background-image:         linear-gradient(to bottom, #d9edf7 0%, #b9def0 100%);\n  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9edf7', endColorstr='#ffb9def0', GradientType=0);\n  background-repeat: repeat-x;\n  border-color: #9acfea;\n}\n.alert-warning {\n  background-image: -webkit-linear-gradient(top, #fcf8e3 0%, #f8efc0 100%);\n  background-image:      -o-linear-gradient(top, #fcf8e3 0%, #f8efc0 100%);\n  background-image: -webkit-gradient(linear, left top, left bottom, from(#fcf8e3), to(#f8efc0));\n  background-image:         linear-gradient(to bottom, #fcf8e3 0%, #f8efc0 100%);\n  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffcf8e3', endColorstr='#fff8efc0', GradientType=0);\n  background-repeat: repeat-x;\n  border-color: #f5e79e;\n}\n.alert-danger {\n  background-image: -webkit-linear-gradient(top, #f2dede 0%, #e7c3c3 100%);\n  background-image:      -o-linear-gradient(top, #f2dede 0%, #e7c3c3 100%);\n  background-image: -webkit-gradient(linear, left top, left bottom, from(#f2dede), to(#e7c3c3));\n  background-image:         linear-gradient(to bottom, #f2dede 0%, #e7c3c3 100%);\n  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff2dede', endColorstr='#ffe7c3c3', GradientType=0);\n  background-repeat: repeat-x;\n  border-color: #dca7a7;\n}\n.progress {\n  background-image: -webkit-linear-gradient(top, #ebebeb 0%, #f5f5f5 100%);\n  background-image:      -o-linear-gradient(top, #ebebeb 0%, #f5f5f5 100%);\n  background-image: -webkit-gradient(linear, left top, left bottom, from(#ebebeb), to(#f5f5f5));\n  background-image:         linear-gradient(to bottom, #ebebeb 0%, #f5f5f5 100%);\n  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffebebeb', endColorstr='#fff5f5f5', GradientType=0);\n  background-repeat: repeat-x;\n}\n.progress-bar {\n  background-image: -webkit-linear-gradient(top, #337ab7 0%, #286090 100%);\n  background-image:      -o-linear-gradient(top, #337ab7 0%, #286090 100%);\n  background-image: -webkit-gradient(linear, left top, left bottom, from(#337ab7), to(#286090));\n  background-image:         linear-gradient(to bottom, #337ab7 0%, #286090 100%);\n  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff286090', GradientType=0);\n  background-repeat: repeat-x;\n}\n.progress-bar-success {\n  background-image: -webkit-linear-gradient(top, #5cb85c 0%, #449d44 100%);\n  background-image:      -o-linear-gradient(top, #5cb85c 0%, #449d44 100%);\n  background-image: -webkit-gradient(linear, left top, left bottom, from(#5cb85c), to(#449d44));\n  background-image:         linear-gradient(to bottom, #5cb85c 0%, #449d44 100%);\n  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5cb85c', endColorstr='#ff449d44', GradientType=0);\n  background-repeat: repeat-x;\n}\n.progress-bar-info {\n  background-image: -webkit-linear-gradient(top, #5bc0de 0%, #31b0d5 100%);\n  background-image:      -o-linear-gradient(top, #5bc0de 0%, #31b0d5 100%);\n  background-image: -webkit-gradient(linear, left top, left bottom, from(#5bc0de), to(#31b0d5));\n  background-image:         linear-gradient(to bottom, #5bc0de 0%, #31b0d5 100%);\n  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de', endColorstr='#ff31b0d5', GradientType=0);\n  background-repeat: repeat-x;\n}\n.progress-bar-warning {\n  background-image: -webkit-linear-gradient(top, #f0ad4e 0%, #ec971f 100%);\n  background-image:      -o-linear-gradient(top, #f0ad4e 0%, #ec971f 100%);\n  background-image: -webkit-gradient(linear, left top, left bottom, from(#f0ad4e), to(#ec971f));\n  background-image:         linear-gradient(to bottom, #f0ad4e 0%, #ec971f 100%);\n  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff0ad4e', endColorstr='#ffec971f', GradientType=0);\n  background-repeat: repeat-x;\n}\n.progress-bar-danger {\n  background-image: -webkit-linear-gradient(top, #d9534f 0%, #c9302c 100%);\n  background-image:      -o-linear-gradient(top, #d9534f 0%, #c9302c 100%);\n  background-image: -webkit-gradient(linear, left top, left bottom, from(#d9534f), to(#c9302c));\n  background-image:         linear-gradient(to bottom, #d9534f 0%, #c9302c 100%);\n  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9534f', endColorstr='#ffc9302c', GradientType=0);\n  background-repeat: repeat-x;\n}\n.progress-bar-striped {\n  background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);\n  background-image:      -o-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);\n  background-image:         linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);\n}\n.list-group {\n  border-radius: 4px;\n  -webkit-box-shadow: 0 1px 2px rgba(0, 0, 0, .075);\n          box-shadow: 0 1px 2px rgba(0, 0, 0, .075);\n}\n.list-group-item.active,\n.list-group-item.active:hover,\n.list-group-item.active:focus {\n  text-shadow: 0 -1px 0 #286090;\n  background-image: -webkit-linear-gradient(top, #337ab7 0%, #2b669a 100%);\n  background-image:      -o-linear-gradient(top, #337ab7 0%, #2b669a 100%);\n  background-image: -webkit-gradient(linear, left top, left bottom, from(#337ab7), to(#2b669a));\n  background-image:         linear-gradient(to bottom, #337ab7 0%, #2b669a 100%);\n  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2b669a', GradientType=0);\n  background-repeat: repeat-x;\n  border-color: #2b669a;\n}\n.list-group-item.active .badge,\n.list-group-item.active:hover .badge,\n.list-group-item.active:focus .badge {\n  text-shadow: none;\n}\n.panel {\n  -webkit-box-shadow: 0 1px 2px rgba(0, 0, 0, .05);\n          box-shadow: 0 1px 2px rgba(0, 0, 0, .05);\n}\n.panel-default > .panel-heading {\n  background-image: -webkit-linear-gradient(top, #f5f5f5 0%, #e8e8e8 100%);\n  background-image:      -o-linear-gradient(top, #f5f5f5 0%, #e8e8e8 100%);\n  background-image: -webkit-gradient(linear, left top, left bottom, from(#f5f5f5), to(#e8e8e8));\n  background-image:         linear-gradient(to bottom, #f5f5f5 0%, #e8e8e8 100%);\n  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff5f5f5', endColorstr='#ffe8e8e8', GradientType=0);\n  background-repeat: repeat-x;\n}\n.panel-primary > .panel-heading {\n  background-image: -webkit-linear-gradient(top, #337ab7 0%, #2e6da4 100%);\n  background-image:      -o-linear-gradient(top, #337ab7 0%, #2e6da4 100%);\n  background-image: -webkit-gradient(linear, left top, left bottom, from(#337ab7), to(#2e6da4));\n  background-image:         linear-gradient(to bottom, #337ab7 0%, #2e6da4 100%);\n  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2e6da4', GradientType=0);\n  background-repeat: repeat-x;\n}\n.panel-success > .panel-heading {\n  background-image: -webkit-linear-gradient(top, #dff0d8 0%, #d0e9c6 100%);\n  background-image:      -o-linear-gradient(top, #dff0d8 0%, #d0e9c6 100%);\n  background-image: -webkit-gradient(linear, left top, left bottom, from(#dff0d8), to(#d0e9c6));\n  background-image:         linear-gradient(to bottom, #dff0d8 0%, #d0e9c6 100%);\n  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdff0d8', endColorstr='#ffd0e9c6', GradientType=0);\n  background-repeat: repeat-x;\n}\n.panel-info > .panel-heading {\n  background-image: -webkit-linear-gradient(top, #d9edf7 0%, #c4e3f3 100%);\n  background-image:      -o-linear-gradient(top, #d9edf7 0%, #c4e3f3 100%);\n  background-image: -webkit-gradient(linear, left top, left bottom, from(#d9edf7), to(#c4e3f3));\n  background-image:         linear-gradient(to bottom, #d9edf7 0%, #c4e3f3 100%);\n  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9edf7', endColorstr='#ffc4e3f3', GradientType=0);\n  background-repeat: repeat-x;\n}\n.panel-warning > .panel-heading {\n  background-image: -webkit-linear-gradient(top, #fcf8e3 0%, #faf2cc 100%);\n  background-image:      -o-linear-gradient(top, #fcf8e3 0%, #faf2cc 100%);\n  background-image: -webkit-gradient(linear, left top, left bottom, from(#fcf8e3), to(#faf2cc));\n  background-image:         linear-gradient(to bottom, #fcf8e3 0%, #faf2cc 100%);\n  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffcf8e3', endColorstr='#fffaf2cc', GradientType=0);\n  background-repeat: repeat-x;\n}\n.panel-danger > .panel-heading {\n  background-image: -webkit-linear-gradient(top, #f2dede 0%, #ebcccc 100%);\n  background-image:      -o-linear-gradient(top, #f2dede 0%, #ebcccc 100%);\n  background-image: -webkit-gradient(linear, left top, left bottom, from(#f2dede), to(#ebcccc));\n  background-image:         linear-gradient(to bottom, #f2dede 0%, #ebcccc 100%);\n  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff2dede', endColorstr='#ffebcccc', GradientType=0);\n  background-repeat: repeat-x;\n}\n.well {\n  background-image: -webkit-linear-gradient(top, #e8e8e8 0%, #f5f5f5 100%);\n  background-image:      -o-linear-gradient(top, #e8e8e8 0%, #f5f5f5 100%);\n  background-image: -webkit-gradient(linear, left top, left bottom, from(#e8e8e8), to(#f5f5f5));\n  background-image:         linear-gradient(to bottom, #e8e8e8 0%, #f5f5f5 100%);\n  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffe8e8e8', endColorstr='#fff5f5f5', GradientType=0);\n  background-repeat: repeat-x;\n  border-color: #dcdcdc;\n  -webkit-box-shadow: inset 0 1px 3px rgba(0, 0, 0, .05), 0 1px 0 rgba(255, 255, 255, .1);\n          box-shadow: inset 0 1px 3px rgba(0, 0, 0, .05), 0 1px 0 rgba(255, 255, 255, .1);\n}\n/*# sourceMappingURL=bootstrap-theme.css.map */\n"
  },
  {
    "path": "app_backend/static/css/bootstrap.css",
    "content": "/*!\n * Bootstrap v3.3.5 (http://getbootstrap.com)\n * Copyright 2011-2015 Twitter, Inc.\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)\n */\n/*! normalize.css v3.0.3 | MIT License | github.com/necolas/normalize.css */\nhtml {\n  font-family: sans-serif;\n  -webkit-text-size-adjust: 100%;\n      -ms-text-size-adjust: 100%;\n}\nbody {\n  margin: 0;\n}\narticle,\naside,\ndetails,\nfigcaption,\nfigure,\nfooter,\nheader,\nhgroup,\nmain,\nmenu,\nnav,\nsection,\nsummary {\n  display: block;\n}\naudio,\ncanvas,\nprogress,\nvideo {\n  display: inline-block;\n  vertical-align: baseline;\n}\naudio:not([controls]) {\n  display: none;\n  height: 0;\n}\n[hidden],\ntemplate {\n  display: none;\n}\na {\n  background-color: transparent;\n}\na:active,\na:hover {\n  outline: 0;\n}\nabbr[title] {\n  border-bottom: 1px dotted;\n}\nb,\nstrong {\n  font-weight: bold;\n}\ndfn {\n  font-style: italic;\n}\nh1 {\n  margin: .67em 0;\n  font-size: 2em;\n}\nmark {\n  color: #000;\n  background: #ff0;\n}\nsmall {\n  font-size: 80%;\n}\nsub,\nsup {\n  position: relative;\n  font-size: 75%;\n  line-height: 0;\n  vertical-align: baseline;\n}\nsup {\n  top: -.5em;\n}\nsub {\n  bottom: -.25em;\n}\nimg {\n  border: 0;\n}\nsvg:not(:root) {\n  overflow: hidden;\n}\nfigure {\n  margin: 1em 40px;\n}\nhr {\n  height: 0;\n  -webkit-box-sizing: content-box;\n     -moz-box-sizing: content-box;\n          box-sizing: content-box;\n}\npre {\n  overflow: auto;\n}\ncode,\nkbd,\npre,\nsamp {\n  font-family: monospace, monospace;\n  font-size: 1em;\n}\nbutton,\ninput,\noptgroup,\nselect,\ntextarea {\n  margin: 0;\n  font: inherit;\n  color: inherit;\n}\nbutton {\n  overflow: visible;\n}\nbutton,\nselect {\n  text-transform: none;\n}\nbutton,\nhtml input[type=\"button\"],\ninput[type=\"reset\"],\ninput[type=\"submit\"] {\n  -webkit-appearance: button;\n  cursor: pointer;\n}\nbutton[disabled],\nhtml input[disabled] {\n  cursor: default;\n}\nbutton::-moz-focus-inner,\ninput::-moz-focus-inner {\n  padding: 0;\n  border: 0;\n}\ninput {\n  line-height: normal;\n}\ninput[type=\"checkbox\"],\ninput[type=\"radio\"] {\n  -webkit-box-sizing: border-box;\n     -moz-box-sizing: border-box;\n          box-sizing: border-box;\n  padding: 0;\n}\ninput[type=\"number\"]::-webkit-inner-spin-button,\ninput[type=\"number\"]::-webkit-outer-spin-button {\n  height: auto;\n}\ninput[type=\"search\"] {\n  -webkit-box-sizing: content-box;\n     -moz-box-sizing: content-box;\n          box-sizing: content-box;\n  -webkit-appearance: textfield;\n}\ninput[type=\"search\"]::-webkit-search-cancel-button,\ninput[type=\"search\"]::-webkit-search-decoration {\n  -webkit-appearance: none;\n}\nfieldset {\n  padding: .35em .625em .75em;\n  margin: 0 2px;\n  border: 1px solid #c0c0c0;\n}\nlegend {\n  padding: 0;\n  border: 0;\n}\ntextarea {\n  overflow: auto;\n}\noptgroup {\n  font-weight: bold;\n}\ntable {\n  border-spacing: 0;\n  border-collapse: collapse;\n}\ntd,\nth {\n  padding: 0;\n}\n/*! Source: https://github.com/h5bp/html5-boilerplate/blob/master/src/css/main.css */\n@media print {\n  *,\n  *:before,\n  *:after {\n    color: #000 !important;\n    text-shadow: none !important;\n    background: transparent !important;\n    -webkit-box-shadow: none !important;\n            box-shadow: none !important;\n  }\n  a,\n  a:visited {\n    text-decoration: underline;\n  }\n  a[href]:after {\n    content: \" (\" attr(href) \")\";\n  }\n  abbr[title]:after {\n    content: \" (\" attr(title) \")\";\n  }\n  a[href^=\"#\"]:after,\n  a[href^=\"javascript:\"]:after {\n    content: \"\";\n  }\n  pre,\n  blockquote {\n    border: 1px solid #999;\n\n    page-break-inside: avoid;\n  }\n  thead {\n    display: table-header-group;\n  }\n  tr,\n  img {\n    page-break-inside: avoid;\n  }\n  img {\n    max-width: 100% !important;\n  }\n  p,\n  h2,\n  h3 {\n    orphans: 3;\n    widows: 3;\n  }\n  h2,\n  h3 {\n    page-break-after: avoid;\n  }\n  .navbar {\n    display: none;\n  }\n  .btn > .caret,\n  .dropup > .btn > .caret {\n    border-top-color: #000 !important;\n  }\n  .label {\n    border: 1px solid #000;\n  }\n  .table {\n    border-collapse: collapse !important;\n  }\n  .table td,\n  .table th {\n    background-color: #fff !important;\n  }\n  .table-bordered th,\n  .table-bordered td {\n    border: 1px solid #ddd !important;\n  }\n}\n@font-face {\n  font-family: 'Glyphicons Halflings';\n\n  src: url('../fonts/glyphicons-halflings-regular.eot');\n  src: url('../fonts/glyphicons-halflings-regular.eot?#iefix') format('embedded-opentype'), url('../fonts/glyphicons-halflings-regular.woff2') format('woff2'), url('../fonts/glyphicons-halflings-regular.woff') format('woff'), url('../fonts/glyphicons-halflings-regular.ttf') format('truetype'), url('../fonts/glyphicons-halflings-regular.svg#glyphicons_halflingsregular') format('svg');\n}\n.glyphicon {\n  position: relative;\n  top: 1px;\n  display: inline-block;\n  font-family: 'Glyphicons Halflings';\n  font-style: normal;\n  font-weight: normal;\n  line-height: 1;\n\n  -webkit-font-smoothing: antialiased;\n  -moz-osx-font-smoothing: grayscale;\n}\n.glyphicon-asterisk:before {\n  content: \"\\2a\";\n}\n.glyphicon-plus:before {\n  content: \"\\2b\";\n}\n.glyphicon-euro:before,\n.glyphicon-eur:before {\n  content: \"\\20ac\";\n}\n.glyphicon-minus:before {\n  content: \"\\2212\";\n}\n.glyphicon-cloud:before {\n  content: \"\\2601\";\n}\n.glyphicon-envelope:before {\n  content: \"\\2709\";\n}\n.glyphicon-pencil:before {\n  content: \"\\270f\";\n}\n.glyphicon-glass:before {\n  content: \"\\e001\";\n}\n.glyphicon-music:before {\n  content: \"\\e002\";\n}\n.glyphicon-search:before {\n  content: \"\\e003\";\n}\n.glyphicon-heart:before {\n  content: \"\\e005\";\n}\n.glyphicon-star:before {\n  content: \"\\e006\";\n}\n.glyphicon-star-empty:before {\n  content: \"\\e007\";\n}\n.glyphicon-user:before {\n  content: \"\\e008\";\n}\n.glyphicon-film:before {\n  content: \"\\e009\";\n}\n.glyphicon-th-large:before {\n  content: \"\\e010\";\n}\n.glyphicon-th:before {\n  content: \"\\e011\";\n}\n.glyphicon-th-list:before {\n  content: \"\\e012\";\n}\n.glyphicon-ok:before {\n  content: \"\\e013\";\n}\n.glyphicon-remove:before {\n  content: \"\\e014\";\n}\n.glyphicon-zoom-in:before {\n  content: \"\\e015\";\n}\n.glyphicon-zoom-out:before {\n  content: \"\\e016\";\n}\n.glyphicon-off:before {\n  content: \"\\e017\";\n}\n.glyphicon-signal:before {\n  content: \"\\e018\";\n}\n.glyphicon-cog:before {\n  content: \"\\e019\";\n}\n.glyphicon-trash:before {\n  content: \"\\e020\";\n}\n.glyphicon-home:before {\n  content: \"\\e021\";\n}\n.glyphicon-file:before {\n  content: \"\\e022\";\n}\n.glyphicon-time:before {\n  content: \"\\e023\";\n}\n.glyphicon-road:before {\n  content: \"\\e024\";\n}\n.glyphicon-download-alt:before {\n  content: \"\\e025\";\n}\n.glyphicon-download:before {\n  content: \"\\e026\";\n}\n.glyphicon-upload:before {\n  content: \"\\e027\";\n}\n.glyphicon-inbox:before {\n  content: \"\\e028\";\n}\n.glyphicon-play-circle:before {\n  content: \"\\e029\";\n}\n.glyphicon-repeat:before {\n  content: \"\\e030\";\n}\n.glyphicon-refresh:before {\n  content: \"\\e031\";\n}\n.glyphicon-list-alt:before {\n  content: \"\\e032\";\n}\n.glyphicon-lock:before {\n  content: \"\\e033\";\n}\n.glyphicon-flag:before {\n  content: \"\\e034\";\n}\n.glyphicon-headphones:before {\n  content: \"\\e035\";\n}\n.glyphicon-volume-off:before {\n  content: \"\\e036\";\n}\n.glyphicon-volume-down:before {\n  content: \"\\e037\";\n}\n.glyphicon-volume-up:before {\n  content: \"\\e038\";\n}\n.glyphicon-qrcode:before {\n  content: \"\\e039\";\n}\n.glyphicon-barcode:before {\n  content: \"\\e040\";\n}\n.glyphicon-tag:before {\n  content: \"\\e041\";\n}\n.glyphicon-tags:before {\n  content: \"\\e042\";\n}\n.glyphicon-book:before {\n  content: \"\\e043\";\n}\n.glyphicon-bookmark:before {\n  content: \"\\e044\";\n}\n.glyphicon-print:before {\n  content: \"\\e045\";\n}\n.glyphicon-camera:before {\n  content: \"\\e046\";\n}\n.glyphicon-font:before {\n  content: \"\\e047\";\n}\n.glyphicon-bold:before {\n  content: \"\\e048\";\n}\n.glyphicon-italic:before {\n  content: \"\\e049\";\n}\n.glyphicon-text-height:before {\n  content: \"\\e050\";\n}\n.glyphicon-text-width:before {\n  content: \"\\e051\";\n}\n.glyphicon-align-left:before {\n  content: \"\\e052\";\n}\n.glyphicon-align-center:before {\n  content: \"\\e053\";\n}\n.glyphicon-align-right:before {\n  content: \"\\e054\";\n}\n.glyphicon-align-justify:before {\n  content: \"\\e055\";\n}\n.glyphicon-list:before {\n  content: \"\\e056\";\n}\n.glyphicon-indent-left:before {\n  content: \"\\e057\";\n}\n.glyphicon-indent-right:before {\n  content: \"\\e058\";\n}\n.glyphicon-facetime-video:before {\n  content: \"\\e059\";\n}\n.glyphicon-picture:before {\n  content: \"\\e060\";\n}\n.glyphicon-map-marker:before {\n  content: \"\\e062\";\n}\n.glyphicon-adjust:before {\n  content: \"\\e063\";\n}\n.glyphicon-tint:before {\n  content: \"\\e064\";\n}\n.glyphicon-edit:before {\n  content: \"\\e065\";\n}\n.glyphicon-share:before {\n  content: \"\\e066\";\n}\n.glyphicon-check:before {\n  content: \"\\e067\";\n}\n.glyphicon-move:before {\n  content: \"\\e068\";\n}\n.glyphicon-step-backward:before {\n  content: \"\\e069\";\n}\n.glyphicon-fast-backward:before {\n  content: \"\\e070\";\n}\n.glyphicon-backward:before {\n  content: \"\\e071\";\n}\n.glyphicon-play:before {\n  content: \"\\e072\";\n}\n.glyphicon-pause:before {\n  content: \"\\e073\";\n}\n.glyphicon-stop:before {\n  content: \"\\e074\";\n}\n.glyphicon-forward:before {\n  content: \"\\e075\";\n}\n.glyphicon-fast-forward:before {\n  content: \"\\e076\";\n}\n.glyphicon-step-forward:before {\n  content: \"\\e077\";\n}\n.glyphicon-eject:before {\n  content: \"\\e078\";\n}\n.glyphicon-chevron-left:before {\n  content: \"\\e079\";\n}\n.glyphicon-chevron-right:before {\n  content: \"\\e080\";\n}\n.glyphicon-plus-sign:before {\n  content: \"\\e081\";\n}\n.glyphicon-minus-sign:before {\n  content: \"\\e082\";\n}\n.glyphicon-remove-sign:before {\n  content: \"\\e083\";\n}\n.glyphicon-ok-sign:before {\n  content: \"\\e084\";\n}\n.glyphicon-question-sign:before {\n  content: \"\\e085\";\n}\n.glyphicon-info-sign:before {\n  content: \"\\e086\";\n}\n.glyphicon-screenshot:before {\n  content: \"\\e087\";\n}\n.glyphicon-remove-circle:before {\n  content: \"\\e088\";\n}\n.glyphicon-ok-circle:before {\n  content: \"\\e089\";\n}\n.glyphicon-ban-circle:before {\n  content: \"\\e090\";\n}\n.glyphicon-arrow-left:before {\n  content: \"\\e091\";\n}\n.glyphicon-arrow-right:before {\n  content: \"\\e092\";\n}\n.glyphicon-arrow-up:before {\n  content: \"\\e093\";\n}\n.glyphicon-arrow-down:before {\n  content: \"\\e094\";\n}\n.glyphicon-share-alt:before {\n  content: \"\\e095\";\n}\n.glyphicon-resize-full:before {\n  content: \"\\e096\";\n}\n.glyphicon-resize-small:before {\n  content: \"\\e097\";\n}\n.glyphicon-exclamation-sign:before {\n  content: \"\\e101\";\n}\n.glyphicon-gift:before {\n  content: \"\\e102\";\n}\n.glyphicon-leaf:before {\n  content: \"\\e103\";\n}\n.glyphicon-fire:before {\n  content: \"\\e104\";\n}\n.glyphicon-eye-open:before {\n  content: \"\\e105\";\n}\n.glyphicon-eye-close:before {\n  content: \"\\e106\";\n}\n.glyphicon-warning-sign:before {\n  content: \"\\e107\";\n}\n.glyphicon-plane:before {\n  content: \"\\e108\";\n}\n.glyphicon-calendar:before {\n  content: \"\\e109\";\n}\n.glyphicon-random:before {\n  content: \"\\e110\";\n}\n.glyphicon-comment:before {\n  content: \"\\e111\";\n}\n.glyphicon-magnet:before {\n  content: \"\\e112\";\n}\n.glyphicon-chevron-up:before {\n  content: \"\\e113\";\n}\n.glyphicon-chevron-down:before {\n  content: \"\\e114\";\n}\n.glyphicon-retweet:before {\n  content: \"\\e115\";\n}\n.glyphicon-shopping-cart:before {\n  content: \"\\e116\";\n}\n.glyphicon-folder-close:before {\n  content: \"\\e117\";\n}\n.glyphicon-folder-open:before {\n  content: \"\\e118\";\n}\n.glyphicon-resize-vertical:before {\n  content: \"\\e119\";\n}\n.glyphicon-resize-horizontal:before {\n  content: \"\\e120\";\n}\n.glyphicon-hdd:before {\n  content: \"\\e121\";\n}\n.glyphicon-bullhorn:before {\n  content: \"\\e122\";\n}\n.glyphicon-bell:before {\n  content: \"\\e123\";\n}\n.glyphicon-certificate:before {\n  content: \"\\e124\";\n}\n.glyphicon-thumbs-up:before {\n  content: \"\\e125\";\n}\n.glyphicon-thumbs-down:before {\n  content: \"\\e126\";\n}\n.glyphicon-hand-right:before {\n  content: \"\\e127\";\n}\n.glyphicon-hand-left:before {\n  content: \"\\e128\";\n}\n.glyphicon-hand-up:before {\n  content: \"\\e129\";\n}\n.glyphicon-hand-down:before {\n  content: \"\\e130\";\n}\n.glyphicon-circle-arrow-right:before {\n  content: \"\\e131\";\n}\n.glyphicon-circle-arrow-left:before {\n  content: \"\\e132\";\n}\n.glyphicon-circle-arrow-up:before {\n  content: \"\\e133\";\n}\n.glyphicon-circle-arrow-down:before {\n  content: \"\\e134\";\n}\n.glyphicon-globe:before {\n  content: \"\\e135\";\n}\n.glyphicon-wrench:before {\n  content: \"\\e136\";\n}\n.glyphicon-tasks:before {\n  content: \"\\e137\";\n}\n.glyphicon-filter:before {\n  content: \"\\e138\";\n}\n.glyphicon-briefcase:before {\n  content: \"\\e139\";\n}\n.glyphicon-fullscreen:before {\n  content: \"\\e140\";\n}\n.glyphicon-dashboard:before {\n  content: \"\\e141\";\n}\n.glyphicon-paperclip:before {\n  content: \"\\e142\";\n}\n.glyphicon-heart-empty:before {\n  content: \"\\e143\";\n}\n.glyphicon-link:before {\n  content: \"\\e144\";\n}\n.glyphicon-phone:before {\n  content: \"\\e145\";\n}\n.glyphicon-pushpin:before {\n  content: \"\\e146\";\n}\n.glyphicon-usd:before {\n  content: \"\\e148\";\n}\n.glyphicon-gbp:before {\n  content: \"\\e149\";\n}\n.glyphicon-sort:before {\n  content: \"\\e150\";\n}\n.glyphicon-sort-by-alphabet:before {\n  content: \"\\e151\";\n}\n.glyphicon-sort-by-alphabet-alt:before {\n  content: \"\\e152\";\n}\n.glyphicon-sort-by-order:before {\n  content: \"\\e153\";\n}\n.glyphicon-sort-by-order-alt:before {\n  content: \"\\e154\";\n}\n.glyphicon-sort-by-attributes:before {\n  content: \"\\e155\";\n}\n.glyphicon-sort-by-attributes-alt:before {\n  content: \"\\e156\";\n}\n.glyphicon-unchecked:before {\n  content: \"\\e157\";\n}\n.glyphicon-expand:before {\n  content: \"\\e158\";\n}\n.glyphicon-collapse-down:before {\n  content: \"\\e159\";\n}\n.glyphicon-collapse-up:before {\n  content: \"\\e160\";\n}\n.glyphicon-log-in:before {\n  content: \"\\e161\";\n}\n.glyphicon-flash:before {\n  content: \"\\e162\";\n}\n.glyphicon-log-out:before {\n  content: \"\\e163\";\n}\n.glyphicon-new-window:before {\n  content: \"\\e164\";\n}\n.glyphicon-record:before {\n  content: \"\\e165\";\n}\n.glyphicon-save:before {\n  content: \"\\e166\";\n}\n.glyphicon-open:before {\n  content: \"\\e167\";\n}\n.glyphicon-saved:before {\n  content: \"\\e168\";\n}\n.glyphicon-import:before {\n  content: \"\\e169\";\n}\n.glyphicon-export:before {\n  content: \"\\e170\";\n}\n.glyphicon-send:before {\n  content: \"\\e171\";\n}\n.glyphicon-floppy-disk:before {\n  content: \"\\e172\";\n}\n.glyphicon-floppy-saved:before {\n  content: \"\\e173\";\n}\n.glyphicon-floppy-remove:before {\n  content: \"\\e174\";\n}\n.glyphicon-floppy-save:before {\n  content: \"\\e175\";\n}\n.glyphicon-floppy-open:before {\n  content: \"\\e176\";\n}\n.glyphicon-credit-card:before {\n  content: \"\\e177\";\n}\n.glyphicon-transfer:before {\n  content: \"\\e178\";\n}\n.glyphicon-cutlery:before {\n  content: \"\\e179\";\n}\n.glyphicon-header:before {\n  content: \"\\e180\";\n}\n.glyphicon-compressed:before {\n  content: \"\\e181\";\n}\n.glyphicon-earphone:before {\n  content: \"\\e182\";\n}\n.glyphicon-phone-alt:before {\n  content: \"\\e183\";\n}\n.glyphicon-tower:before {\n  content: \"\\e184\";\n}\n.glyphicon-stats:before {\n  content: \"\\e185\";\n}\n.glyphicon-sd-video:before {\n  content: \"\\e186\";\n}\n.glyphicon-hd-video:before {\n  content: \"\\e187\";\n}\n.glyphicon-subtitles:before {\n  content: \"\\e188\";\n}\n.glyphicon-sound-stereo:before {\n  content: \"\\e189\";\n}\n.glyphicon-sound-dolby:before {\n  content: \"\\e190\";\n}\n.glyphicon-sound-5-1:before {\n  content: \"\\e191\";\n}\n.glyphicon-sound-6-1:before {\n  content: \"\\e192\";\n}\n.glyphicon-sound-7-1:before {\n  content: \"\\e193\";\n}\n.glyphicon-copyright-mark:before {\n  content: \"\\e194\";\n}\n.glyphicon-registration-mark:before {\n  content: \"\\e195\";\n}\n.glyphicon-cloud-download:before {\n  content: \"\\e197\";\n}\n.glyphicon-cloud-upload:before {\n  content: \"\\e198\";\n}\n.glyphicon-tree-conifer:before {\n  content: \"\\e199\";\n}\n.glyphicon-tree-deciduous:before {\n  content: \"\\e200\";\n}\n.glyphicon-cd:before {\n  content: \"\\e201\";\n}\n.glyphicon-save-file:before {\n  content: \"\\e202\";\n}\n.glyphicon-open-file:before {\n  content: \"\\e203\";\n}\n.glyphicon-level-up:before {\n  content: \"\\e204\";\n}\n.glyphicon-copy:before {\n  content: \"\\e205\";\n}\n.glyphicon-paste:before {\n  content: \"\\e206\";\n}\n.glyphicon-alert:before {\n  content: \"\\e209\";\n}\n.glyphicon-equalizer:before {\n  content: \"\\e210\";\n}\n.glyphicon-king:before {\n  content: \"\\e211\";\n}\n.glyphicon-queen:before {\n  content: \"\\e212\";\n}\n.glyphicon-pawn:before {\n  content: \"\\e213\";\n}\n.glyphicon-bishop:before {\n  content: \"\\e214\";\n}\n.glyphicon-knight:before {\n  content: \"\\e215\";\n}\n.glyphicon-baby-formula:before {\n  content: \"\\e216\";\n}\n.glyphicon-tent:before {\n  content: \"\\26fa\";\n}\n.glyphicon-blackboard:before {\n  content: \"\\e218\";\n}\n.glyphicon-bed:before {\n  content: \"\\e219\";\n}\n.glyphicon-apple:before {\n  content: \"\\f8ff\";\n}\n.glyphicon-erase:before {\n  content: \"\\e221\";\n}\n.glyphicon-hourglass:before {\n  content: \"\\231b\";\n}\n.glyphicon-lamp:before {\n  content: \"\\e223\";\n}\n.glyphicon-duplicate:before {\n  content: \"\\e224\";\n}\n.glyphicon-piggy-bank:before {\n  content: \"\\e225\";\n}\n.glyphicon-scissors:before {\n  content: \"\\e226\";\n}\n.glyphicon-bitcoin:before {\n  content: \"\\e227\";\n}\n.glyphicon-btc:before {\n  content: \"\\e227\";\n}\n.glyphicon-xbt:before {\n  content: \"\\e227\";\n}\n.glyphicon-yen:before {\n  content: \"\\00a5\";\n}\n.glyphicon-jpy:before {\n  content: \"\\00a5\";\n}\n.glyphicon-ruble:before {\n  content: \"\\20bd\";\n}\n.glyphicon-rub:before {\n  content: \"\\20bd\";\n}\n.glyphicon-scale:before {\n  content: \"\\e230\";\n}\n.glyphicon-ice-lolly:before {\n  content: \"\\e231\";\n}\n.glyphicon-ice-lolly-tasted:before {\n  content: \"\\e232\";\n}\n.glyphicon-education:before {\n  content: \"\\e233\";\n}\n.glyphicon-option-horizontal:before {\n  content: \"\\e234\";\n}\n.glyphicon-option-vertical:before {\n  content: \"\\e235\";\n}\n.glyphicon-menu-hamburger:before {\n  content: \"\\e236\";\n}\n.glyphicon-modal-window:before {\n  content: \"\\e237\";\n}\n.glyphicon-oil:before {\n  content: \"\\e238\";\n}\n.glyphicon-grain:before {\n  content: \"\\e239\";\n}\n.glyphicon-sunglasses:before {\n  content: \"\\e240\";\n}\n.glyphicon-text-size:before {\n  content: \"\\e241\";\n}\n.glyphicon-text-color:before {\n  content: \"\\e242\";\n}\n.glyphicon-text-background:before {\n  content: \"\\e243\";\n}\n.glyphicon-object-align-top:before {\n  content: \"\\e244\";\n}\n.glyphicon-object-align-bottom:before {\n  content: \"\\e245\";\n}\n.glyphicon-object-align-horizontal:before {\n  content: \"\\e246\";\n}\n.glyphicon-object-align-left:before {\n  content: \"\\e247\";\n}\n.glyphicon-object-align-vertical:before {\n  content: \"\\e248\";\n}\n.glyphicon-object-align-right:before {\n  content: \"\\e249\";\n}\n.glyphicon-triangle-right:before {\n  content: \"\\e250\";\n}\n.glyphicon-triangle-left:before {\n  content: \"\\e251\";\n}\n.glyphicon-triangle-bottom:before {\n  content: \"\\e252\";\n}\n.glyphicon-triangle-top:before {\n  content: \"\\e253\";\n}\n.glyphicon-console:before {\n  content: \"\\e254\";\n}\n.glyphicon-superscript:before {\n  content: \"\\e255\";\n}\n.glyphicon-subscript:before {\n  content: \"\\e256\";\n}\n.glyphicon-menu-left:before {\n  content: \"\\e257\";\n}\n.glyphicon-menu-right:before {\n  content: \"\\e258\";\n}\n.glyphicon-menu-down:before {\n  content: \"\\e259\";\n}\n.glyphicon-menu-up:before {\n  content: \"\\e260\";\n}\n* {\n  -webkit-box-sizing: border-box;\n     -moz-box-sizing: border-box;\n          box-sizing: border-box;\n}\n*:before,\n*:after {\n  -webkit-box-sizing: border-box;\n     -moz-box-sizing: border-box;\n          box-sizing: border-box;\n}\nhtml {\n  font-size: 10px;\n\n  -webkit-tap-highlight-color: rgba(0, 0, 0, 0);\n}\nbody {\n  font-family: \"Helvetica Neue\", Helvetica, Arial, sans-serif;\n  font-size: 14px;\n  line-height: 1.42857143;\n  color: #333;\n  background-color: #fff;\n}\ninput,\nbutton,\nselect,\ntextarea {\n  font-family: inherit;\n  font-size: inherit;\n  line-height: inherit;\n}\na {\n  color: #337ab7;\n  text-decoration: none;\n}\na:hover,\na:focus {\n  color: #23527c;\n  text-decoration: underline;\n}\na:focus {\n  outline: thin dotted;\n  outline: 5px auto -webkit-focus-ring-color;\n  outline-offset: -2px;\n}\nfigure {\n  margin: 0;\n}\nimg {\n  vertical-align: middle;\n}\n.img-responsive,\n.thumbnail > img,\n.thumbnail a > img,\n.carousel-inner > .item > img,\n.carousel-inner > .item > a > img {\n  display: block;\n  max-width: 100%;\n  height: auto;\n}\n.img-rounded {\n  border-radius: 6px;\n}\n.img-thumbnail {\n  display: inline-block;\n  max-width: 100%;\n  height: auto;\n  padding: 4px;\n  line-height: 1.42857143;\n  background-color: #fff;\n  border: 1px solid #ddd;\n  border-radius: 4px;\n  -webkit-transition: all .2s ease-in-out;\n       -o-transition: all .2s ease-in-out;\n          transition: all .2s ease-in-out;\n}\n.img-circle {\n  border-radius: 50%;\n}\nhr {\n  margin-top: 20px;\n  margin-bottom: 20px;\n  border: 0;\n  border-top: 1px solid #eee;\n}\n.sr-only {\n  position: absolute;\n  width: 1px;\n  height: 1px;\n  padding: 0;\n  margin: -1px;\n  overflow: hidden;\n  clip: rect(0, 0, 0, 0);\n  border: 0;\n}\n.sr-only-focusable:active,\n.sr-only-focusable:focus {\n  position: static;\n  width: auto;\n  height: auto;\n  margin: 0;\n  overflow: visible;\n  clip: auto;\n}\n[role=\"button\"] {\n  cursor: pointer;\n}\nh1,\nh2,\nh3,\nh4,\nh5,\nh6,\n.h1,\n.h2,\n.h3,\n.h4,\n.h5,\n.h6 {\n  font-family: inherit;\n  font-weight: 500;\n  line-height: 1.1;\n  color: inherit;\n}\nh1 small,\nh2 small,\nh3 small,\nh4 small,\nh5 small,\nh6 small,\n.h1 small,\n.h2 small,\n.h3 small,\n.h4 small,\n.h5 small,\n.h6 small,\nh1 .small,\nh2 .small,\nh3 .small,\nh4 .small,\nh5 .small,\nh6 .small,\n.h1 .small,\n.h2 .small,\n.h3 .small,\n.h4 .small,\n.h5 .small,\n.h6 .small {\n  font-weight: normal;\n  line-height: 1;\n  color: #777;\n}\nh1,\n.h1,\nh2,\n.h2,\nh3,\n.h3 {\n  margin-top: 20px;\n  margin-bottom: 10px;\n}\nh1 small,\n.h1 small,\nh2 small,\n.h2 small,\nh3 small,\n.h3 small,\nh1 .small,\n.h1 .small,\nh2 .small,\n.h2 .small,\nh3 .small,\n.h3 .small {\n  font-size: 65%;\n}\nh4,\n.h4,\nh5,\n.h5,\nh6,\n.h6 {\n  margin-top: 10px;\n  margin-bottom: 10px;\n}\nh4 small,\n.h4 small,\nh5 small,\n.h5 small,\nh6 small,\n.h6 small,\nh4 .small,\n.h4 .small,\nh5 .small,\n.h5 .small,\nh6 .small,\n.h6 .small {\n  font-size: 75%;\n}\nh1,\n.h1 {\n  font-size: 36px;\n}\nh2,\n.h2 {\n  font-size: 30px;\n}\nh3,\n.h3 {\n  font-size: 24px;\n}\nh4,\n.h4 {\n  font-size: 18px;\n}\nh5,\n.h5 {\n  font-size: 14px;\n}\nh6,\n.h6 {\n  font-size: 12px;\n}\np {\n  margin: 0 0 10px;\n}\n.lead {\n  margin-bottom: 20px;\n  font-size: 16px;\n  font-weight: 300;\n  line-height: 1.4;\n}\n@media (min-width: 768px) {\n  .lead {\n    font-size: 21px;\n  }\n}\nsmall,\n.small {\n  font-size: 85%;\n}\nmark,\n.mark {\n  padding: .2em;\n  background-color: #fcf8e3;\n}\n.text-left {\n  text-align: left;\n}\n.text-right {\n  text-align: right;\n}\n.text-center {\n  text-align: center;\n}\n.text-justify {\n  text-align: justify;\n}\n.text-nowrap {\n  white-space: nowrap;\n}\n.text-lowercase {\n  text-transform: lowercase;\n}\n.text-uppercase {\n  text-transform: uppercase;\n}\n.text-capitalize {\n  text-transform: capitalize;\n}\n.text-muted {\n  color: #777;\n}\n.text-primary {\n  color: #337ab7;\n}\na.text-primary:hover,\na.text-primary:focus {\n  color: #286090;\n}\n.text-success {\n  color: #3c763d;\n}\na.text-success:hover,\na.text-success:focus {\n  color: #2b542c;\n}\n.text-info {\n  color: #31708f;\n}\na.text-info:hover,\na.text-info:focus {\n  color: #245269;\n}\n.text-warning {\n  color: #8a6d3b;\n}\na.text-warning:hover,\na.text-warning:focus {\n  color: #66512c;\n}\n.text-danger {\n  color: #a94442;\n}\na.text-danger:hover,\na.text-danger:focus {\n  color: #843534;\n}\n.bg-primary {\n  color: #fff;\n  background-color: #337ab7;\n}\na.bg-primary:hover,\na.bg-primary:focus {\n  background-color: #286090;\n}\n.bg-success {\n  background-color: #dff0d8;\n}\na.bg-success:hover,\na.bg-success:focus {\n  background-color: #c1e2b3;\n}\n.bg-info {\n  background-color: #d9edf7;\n}\na.bg-info:hover,\na.bg-info:focus {\n  background-color: #afd9ee;\n}\n.bg-warning {\n  background-color: #fcf8e3;\n}\na.bg-warning:hover,\na.bg-warning:focus {\n  background-color: #f7ecb5;\n}\n.bg-danger {\n  background-color: #f2dede;\n}\na.bg-danger:hover,\na.bg-danger:focus {\n  background-color: #e4b9b9;\n}\n.page-header {\n  padding-bottom: 9px;\n  margin: 40px 0 20px;\n  border-bottom: 1px solid #eee;\n}\nul,\nol {\n  margin-top: 0;\n  margin-bottom: 10px;\n}\nul ul,\nol ul,\nul ol,\nol ol {\n  margin-bottom: 0;\n}\n.list-unstyled {\n  padding-left: 0;\n  list-style: none;\n}\n.list-inline {\n  padding-left: 0;\n  margin-left: -5px;\n  list-style: none;\n}\n.list-inline > li {\n  display: inline-block;\n  padding-right: 5px;\n  padding-left: 5px;\n}\ndl {\n  margin-top: 0;\n  margin-bottom: 20px;\n}\ndt,\ndd {\n  line-height: 1.42857143;\n}\ndt {\n  font-weight: bold;\n}\ndd {\n  margin-left: 0;\n}\n@media (min-width: 768px) {\n  .dl-horizontal dt {\n    float: left;\n    width: 160px;\n    overflow: hidden;\n    clear: left;\n    text-align: right;\n    text-overflow: ellipsis;\n    white-space: nowrap;\n  }\n  .dl-horizontal dd {\n    margin-left: 180px;\n  }\n}\nabbr[title],\nabbr[data-original-title] {\n  cursor: help;\n  border-bottom: 1px dotted #777;\n}\n.initialism {\n  font-size: 90%;\n  text-transform: uppercase;\n}\nblockquote {\n  padding: 10px 20px;\n  margin: 0 0 20px;\n  font-size: 17.5px;\n  border-left: 5px solid #eee;\n}\nblockquote p:last-child,\nblockquote ul:last-child,\nblockquote ol:last-child {\n  margin-bottom: 0;\n}\nblockquote footer,\nblockquote small,\nblockquote .small {\n  display: block;\n  font-size: 80%;\n  line-height: 1.42857143;\n  color: #777;\n}\nblockquote footer:before,\nblockquote small:before,\nblockquote .small:before {\n  content: '\\2014 \\00A0';\n}\n.blockquote-reverse,\nblockquote.pull-right {\n  padding-right: 15px;\n  padding-left: 0;\n  text-align: right;\n  border-right: 5px solid #eee;\n  border-left: 0;\n}\n.blockquote-reverse footer:before,\nblockquote.pull-right footer:before,\n.blockquote-reverse small:before,\nblockquote.pull-right small:before,\n.blockquote-reverse .small:before,\nblockquote.pull-right .small:before {\n  content: '';\n}\n.blockquote-reverse footer:after,\nblockquote.pull-right footer:after,\n.blockquote-reverse small:after,\nblockquote.pull-right small:after,\n.blockquote-reverse .small:after,\nblockquote.pull-right .small:after {\n  content: '\\00A0 \\2014';\n}\naddress {\n  margin-bottom: 20px;\n  font-style: normal;\n  line-height: 1.42857143;\n}\ncode,\nkbd,\npre,\nsamp {\n  font-family: Menlo, Monaco, Consolas, \"Courier New\", monospace;\n}\ncode {\n  padding: 2px 4px;\n  font-size: 90%;\n  color: #c7254e;\n  background-color: #f9f2f4;\n  border-radius: 4px;\n}\nkbd {\n  padding: 2px 4px;\n  font-size: 90%;\n  color: #fff;\n  background-color: #333;\n  border-radius: 3px;\n  -webkit-box-shadow: inset 0 -1px 0 rgba(0, 0, 0, .25);\n          box-shadow: inset 0 -1px 0 rgba(0, 0, 0, .25);\n}\nkbd kbd {\n  padding: 0;\n  font-size: 100%;\n  font-weight: bold;\n  -webkit-box-shadow: none;\n          box-shadow: none;\n}\npre {\n  display: block;\n  padding: 9.5px;\n  margin: 0 0 10px;\n  font-size: 13px;\n  line-height: 1.42857143;\n  color: #333;\n  word-break: break-all;\n  word-wrap: break-word;\n  background-color: #f5f5f5;\n  border: 1px solid #ccc;\n  border-radius: 4px;\n}\npre code {\n  padding: 0;\n  font-size: inherit;\n  color: inherit;\n  white-space: pre-wrap;\n  background-color: transparent;\n  border-radius: 0;\n}\n.pre-scrollable {\n  max-height: 340px;\n  overflow-y: scroll;\n}\n.container {\n  padding-right: 15px;\n  padding-left: 15px;\n  margin-right: auto;\n  margin-left: auto;\n}\n@media (min-width: 768px) {\n  .container {\n    width: 750px;\n  }\n}\n@media (min-width: 992px) {\n  .container {\n    width: 970px;\n  }\n}\n@media (min-width: 1200px) {\n  .container {\n    width: 1170px;\n  }\n}\n.container-fluid {\n  padding-right: 15px;\n  padding-left: 15px;\n  margin-right: auto;\n  margin-left: auto;\n}\n.row {\n  margin-right: -15px;\n  margin-left: -15px;\n}\n.col-xs-1, .col-sm-1, .col-md-1, .col-lg-1, .col-xs-2, .col-sm-2, .col-md-2, .col-lg-2, .col-xs-3, .col-sm-3, .col-md-3, .col-lg-3, .col-xs-4, .col-sm-4, .col-md-4, .col-lg-4, .col-xs-5, .col-sm-5, .col-md-5, .col-lg-5, .col-xs-6, .col-sm-6, .col-md-6, .col-lg-6, .col-xs-7, .col-sm-7, .col-md-7, .col-lg-7, .col-xs-8, .col-sm-8, .col-md-8, .col-lg-8, .col-xs-9, .col-sm-9, .col-md-9, .col-lg-9, .col-xs-10, .col-sm-10, .col-md-10, .col-lg-10, .col-xs-11, .col-sm-11, .col-md-11, .col-lg-11, .col-xs-12, .col-sm-12, .col-md-12, .col-lg-12 {\n  position: relative;\n  min-height: 1px;\n  padding-right: 15px;\n  padding-left: 15px;\n}\n.col-xs-1, .col-xs-2, .col-xs-3, .col-xs-4, .col-xs-5, .col-xs-6, .col-xs-7, .col-xs-8, .col-xs-9, .col-xs-10, .col-xs-11, .col-xs-12 {\n  float: left;\n}\n.col-xs-12 {\n  width: 100%;\n}\n.col-xs-11 {\n  width: 91.66666667%;\n}\n.col-xs-10 {\n  width: 83.33333333%;\n}\n.col-xs-9 {\n  width: 75%;\n}\n.col-xs-8 {\n  width: 66.66666667%;\n}\n.col-xs-7 {\n  width: 58.33333333%;\n}\n.col-xs-6 {\n  width: 50%;\n}\n.col-xs-5 {\n  width: 41.66666667%;\n}\n.col-xs-4 {\n  width: 33.33333333%;\n}\n.col-xs-3 {\n  width: 25%;\n}\n.col-xs-2 {\n  width: 16.66666667%;\n}\n.col-xs-1 {\n  width: 8.33333333%;\n}\n.col-xs-pull-12 {\n  right: 100%;\n}\n.col-xs-pull-11 {\n  right: 91.66666667%;\n}\n.col-xs-pull-10 {\n  right: 83.33333333%;\n}\n.col-xs-pull-9 {\n  right: 75%;\n}\n.col-xs-pull-8 {\n  right: 66.66666667%;\n}\n.col-xs-pull-7 {\n  right: 58.33333333%;\n}\n.col-xs-pull-6 {\n  right: 50%;\n}\n.col-xs-pull-5 {\n  right: 41.66666667%;\n}\n.col-xs-pull-4 {\n  right: 33.33333333%;\n}\n.col-xs-pull-3 {\n  right: 25%;\n}\n.col-xs-pull-2 {\n  right: 16.66666667%;\n}\n.col-xs-pull-1 {\n  right: 8.33333333%;\n}\n.col-xs-pull-0 {\n  right: auto;\n}\n.col-xs-push-12 {\n  left: 100%;\n}\n.col-xs-push-11 {\n  left: 91.66666667%;\n}\n.col-xs-push-10 {\n  left: 83.33333333%;\n}\n.col-xs-push-9 {\n  left: 75%;\n}\n.col-xs-push-8 {\n  left: 66.66666667%;\n}\n.col-xs-push-7 {\n  left: 58.33333333%;\n}\n.col-xs-push-6 {\n  left: 50%;\n}\n.col-xs-push-5 {\n  left: 41.66666667%;\n}\n.col-xs-push-4 {\n  left: 33.33333333%;\n}\n.col-xs-push-3 {\n  left: 25%;\n}\n.col-xs-push-2 {\n  left: 16.66666667%;\n}\n.col-xs-push-1 {\n  left: 8.33333333%;\n}\n.col-xs-push-0 {\n  left: auto;\n}\n.col-xs-offset-12 {\n  margin-left: 100%;\n}\n.col-xs-offset-11 {\n  margin-left: 91.66666667%;\n}\n.col-xs-offset-10 {\n  margin-left: 83.33333333%;\n}\n.col-xs-offset-9 {\n  margin-left: 75%;\n}\n.col-xs-offset-8 {\n  margin-left: 66.66666667%;\n}\n.col-xs-offset-7 {\n  margin-left: 58.33333333%;\n}\n.col-xs-offset-6 {\n  margin-left: 50%;\n}\n.col-xs-offset-5 {\n  margin-left: 41.66666667%;\n}\n.col-xs-offset-4 {\n  margin-left: 33.33333333%;\n}\n.col-xs-offset-3 {\n  margin-left: 25%;\n}\n.col-xs-offset-2 {\n  margin-left: 16.66666667%;\n}\n.col-xs-offset-1 {\n  margin-left: 8.33333333%;\n}\n.col-xs-offset-0 {\n  margin-left: 0;\n}\n@media (min-width: 768px) {\n  .col-sm-1, .col-sm-2, .col-sm-3, .col-sm-4, .col-sm-5, .col-sm-6, .col-sm-7, .col-sm-8, .col-sm-9, .col-sm-10, .col-sm-11, .col-sm-12 {\n    float: left;\n  }\n  .col-sm-12 {\n    width: 100%;\n  }\n  .col-sm-11 {\n    width: 91.66666667%;\n  }\n  .col-sm-10 {\n    width: 83.33333333%;\n  }\n  .col-sm-9 {\n    width: 75%;\n  }\n  .col-sm-8 {\n    width: 66.66666667%;\n  }\n  .col-sm-7 {\n    width: 58.33333333%;\n  }\n  .col-sm-6 {\n    width: 50%;\n  }\n  .col-sm-5 {\n    width: 41.66666667%;\n  }\n  .col-sm-4 {\n    width: 33.33333333%;\n  }\n  .col-sm-3 {\n    width: 25%;\n  }\n  .col-sm-2 {\n    width: 16.66666667%;\n  }\n  .col-sm-1 {\n    width: 8.33333333%;\n  }\n  .col-sm-pull-12 {\n    right: 100%;\n  }\n  .col-sm-pull-11 {\n    right: 91.66666667%;\n  }\n  .col-sm-pull-10 {\n    right: 83.33333333%;\n  }\n  .col-sm-pull-9 {\n    right: 75%;\n  }\n  .col-sm-pull-8 {\n    right: 66.66666667%;\n  }\n  .col-sm-pull-7 {\n    right: 58.33333333%;\n  }\n  .col-sm-pull-6 {\n    right: 50%;\n  }\n  .col-sm-pull-5 {\n    right: 41.66666667%;\n  }\n  .col-sm-pull-4 {\n    right: 33.33333333%;\n  }\n  .col-sm-pull-3 {\n    right: 25%;\n  }\n  .col-sm-pull-2 {\n    right: 16.66666667%;\n  }\n  .col-sm-pull-1 {\n    right: 8.33333333%;\n  }\n  .col-sm-pull-0 {\n    right: auto;\n  }\n  .col-sm-push-12 {\n    left: 100%;\n  }\n  .col-sm-push-11 {\n    left: 91.66666667%;\n  }\n  .col-sm-push-10 {\n    left: 83.33333333%;\n  }\n  .col-sm-push-9 {\n    left: 75%;\n  }\n  .col-sm-push-8 {\n    left: 66.66666667%;\n  }\n  .col-sm-push-7 {\n    left: 58.33333333%;\n  }\n  .col-sm-push-6 {\n    left: 50%;\n  }\n  .col-sm-push-5 {\n    left: 41.66666667%;\n  }\n  .col-sm-push-4 {\n    left: 33.33333333%;\n  }\n  .col-sm-push-3 {\n    left: 25%;\n  }\n  .col-sm-push-2 {\n    left: 16.66666667%;\n  }\n  .col-sm-push-1 {\n    left: 8.33333333%;\n  }\n  .col-sm-push-0 {\n    left: auto;\n  }\n  .col-sm-offset-12 {\n    margin-left: 100%;\n  }\n  .col-sm-offset-11 {\n    margin-left: 91.66666667%;\n  }\n  .col-sm-offset-10 {\n    margin-left: 83.33333333%;\n  }\n  .col-sm-offset-9 {\n    margin-left: 75%;\n  }\n  .col-sm-offset-8 {\n    margin-left: 66.66666667%;\n  }\n  .col-sm-offset-7 {\n    margin-left: 58.33333333%;\n  }\n  .col-sm-offset-6 {\n    margin-left: 50%;\n  }\n  .col-sm-offset-5 {\n    margin-left: 41.66666667%;\n  }\n  .col-sm-offset-4 {\n    margin-left: 33.33333333%;\n  }\n  .col-sm-offset-3 {\n    margin-left: 25%;\n  }\n  .col-sm-offset-2 {\n    margin-left: 16.66666667%;\n  }\n  .col-sm-offset-1 {\n    margin-left: 8.33333333%;\n  }\n  .col-sm-offset-0 {\n    margin-left: 0;\n  }\n}\n@media (min-width: 992px) {\n  .col-md-1, .col-md-2, .col-md-3, .col-md-4, .col-md-5, .col-md-6, .col-md-7, .col-md-8, .col-md-9, .col-md-10, .col-md-11, .col-md-12 {\n    float: left;\n  }\n  .col-md-12 {\n    width: 100%;\n  }\n  .col-md-11 {\n    width: 91.66666667%;\n  }\n  .col-md-10 {\n    width: 83.33333333%;\n  }\n  .col-md-9 {\n    width: 75%;\n  }\n  .col-md-8 {\n    width: 66.66666667%;\n  }\n  .col-md-7 {\n    width: 58.33333333%;\n  }\n  .col-md-6 {\n    width: 50%;\n  }\n  .col-md-5 {\n    width: 41.66666667%;\n  }\n  .col-md-4 {\n    width: 33.33333333%;\n  }\n  .col-md-3 {\n    width: 25%;\n  }\n  .col-md-2 {\n    width: 16.66666667%;\n  }\n  .col-md-1 {\n    width: 8.33333333%;\n  }\n  .col-md-pull-12 {\n    right: 100%;\n  }\n  .col-md-pull-11 {\n    right: 91.66666667%;\n  }\n  .col-md-pull-10 {\n    right: 83.33333333%;\n  }\n  .col-md-pull-9 {\n    right: 75%;\n  }\n  .col-md-pull-8 {\n    right: 66.66666667%;\n  }\n  .col-md-pull-7 {\n    right: 58.33333333%;\n  }\n  .col-md-pull-6 {\n    right: 50%;\n  }\n  .col-md-pull-5 {\n    right: 41.66666667%;\n  }\n  .col-md-pull-4 {\n    right: 33.33333333%;\n  }\n  .col-md-pull-3 {\n    right: 25%;\n  }\n  .col-md-pull-2 {\n    right: 16.66666667%;\n  }\n  .col-md-pull-1 {\n    right: 8.33333333%;\n  }\n  .col-md-pull-0 {\n    right: auto;\n  }\n  .col-md-push-12 {\n    left: 100%;\n  }\n  .col-md-push-11 {\n    left: 91.66666667%;\n  }\n  .col-md-push-10 {\n    left: 83.33333333%;\n  }\n  .col-md-push-9 {\n    left: 75%;\n  }\n  .col-md-push-8 {\n    left: 66.66666667%;\n  }\n  .col-md-push-7 {\n    left: 58.33333333%;\n  }\n  .col-md-push-6 {\n    left: 50%;\n  }\n  .col-md-push-5 {\n    left: 41.66666667%;\n  }\n  .col-md-push-4 {\n    left: 33.33333333%;\n  }\n  .col-md-push-3 {\n    left: 25%;\n  }\n  .col-md-push-2 {\n    left: 16.66666667%;\n  }\n  .col-md-push-1 {\n    left: 8.33333333%;\n  }\n  .col-md-push-0 {\n    left: auto;\n  }\n  .col-md-offset-12 {\n    margin-left: 100%;\n  }\n  .col-md-offset-11 {\n    margin-left: 91.66666667%;\n  }\n  .col-md-offset-10 {\n    margin-left: 83.33333333%;\n  }\n  .col-md-offset-9 {\n    margin-left: 75%;\n  }\n  .col-md-offset-8 {\n    margin-left: 66.66666667%;\n  }\n  .col-md-offset-7 {\n    margin-left: 58.33333333%;\n  }\n  .col-md-offset-6 {\n    margin-left: 50%;\n  }\n  .col-md-offset-5 {\n    margin-left: 41.66666667%;\n  }\n  .col-md-offset-4 {\n    margin-left: 33.33333333%;\n  }\n  .col-md-offset-3 {\n    margin-left: 25%;\n  }\n  .col-md-offset-2 {\n    margin-left: 16.66666667%;\n  }\n  .col-md-offset-1 {\n    margin-left: 8.33333333%;\n  }\n  .col-md-offset-0 {\n    margin-left: 0;\n  }\n}\n@media (min-width: 1200px) {\n  .col-lg-1, .col-lg-2, .col-lg-3, .col-lg-4, .col-lg-5, .col-lg-6, .col-lg-7, .col-lg-8, .col-lg-9, .col-lg-10, .col-lg-11, .col-lg-12 {\n    float: left;\n  }\n  .col-lg-12 {\n    width: 100%;\n  }\n  .col-lg-11 {\n    width: 91.66666667%;\n  }\n  .col-lg-10 {\n    width: 83.33333333%;\n  }\n  .col-lg-9 {\n    width: 75%;\n  }\n  .col-lg-8 {\n    width: 66.66666667%;\n  }\n  .col-lg-7 {\n    width: 58.33333333%;\n  }\n  .col-lg-6 {\n    width: 50%;\n  }\n  .col-lg-5 {\n    width: 41.66666667%;\n  }\n  .col-lg-4 {\n    width: 33.33333333%;\n  }\n  .col-lg-3 {\n    width: 25%;\n  }\n  .col-lg-2 {\n    width: 16.66666667%;\n  }\n  .col-lg-1 {\n    width: 8.33333333%;\n  }\n  .col-lg-pull-12 {\n    right: 100%;\n  }\n  .col-lg-pull-11 {\n    right: 91.66666667%;\n  }\n  .col-lg-pull-10 {\n    right: 83.33333333%;\n  }\n  .col-lg-pull-9 {\n    right: 75%;\n  }\n  .col-lg-pull-8 {\n    right: 66.66666667%;\n  }\n  .col-lg-pull-7 {\n    right: 58.33333333%;\n  }\n  .col-lg-pull-6 {\n    right: 50%;\n  }\n  .col-lg-pull-5 {\n    right: 41.66666667%;\n  }\n  .col-lg-pull-4 {\n    right: 33.33333333%;\n  }\n  .col-lg-pull-3 {\n    right: 25%;\n  }\n  .col-lg-pull-2 {\n    right: 16.66666667%;\n  }\n  .col-lg-pull-1 {\n    right: 8.33333333%;\n  }\n  .col-lg-pull-0 {\n    right: auto;\n  }\n  .col-lg-push-12 {\n    left: 100%;\n  }\n  .col-lg-push-11 {\n    left: 91.66666667%;\n  }\n  .col-lg-push-10 {\n    left: 83.33333333%;\n  }\n  .col-lg-push-9 {\n    left: 75%;\n  }\n  .col-lg-push-8 {\n    left: 66.66666667%;\n  }\n  .col-lg-push-7 {\n    left: 58.33333333%;\n  }\n  .col-lg-push-6 {\n    left: 50%;\n  }\n  .col-lg-push-5 {\n    left: 41.66666667%;\n  }\n  .col-lg-push-4 {\n    left: 33.33333333%;\n  }\n  .col-lg-push-3 {\n    left: 25%;\n  }\n  .col-lg-push-2 {\n    left: 16.66666667%;\n  }\n  .col-lg-push-1 {\n    left: 8.33333333%;\n  }\n  .col-lg-push-0 {\n    left: auto;\n  }\n  .col-lg-offset-12 {\n    margin-left: 100%;\n  }\n  .col-lg-offset-11 {\n    margin-left: 91.66666667%;\n  }\n  .col-lg-offset-10 {\n    margin-left: 83.33333333%;\n  }\n  .col-lg-offset-9 {\n    margin-left: 75%;\n  }\n  .col-lg-offset-8 {\n    margin-left: 66.66666667%;\n  }\n  .col-lg-offset-7 {\n    margin-left: 58.33333333%;\n  }\n  .col-lg-offset-6 {\n    margin-left: 50%;\n  }\n  .col-lg-offset-5 {\n    margin-left: 41.66666667%;\n  }\n  .col-lg-offset-4 {\n    margin-left: 33.33333333%;\n  }\n  .col-lg-offset-3 {\n    margin-left: 25%;\n  }\n  .col-lg-offset-2 {\n    margin-left: 16.66666667%;\n  }\n  .col-lg-offset-1 {\n    margin-left: 8.33333333%;\n  }\n  .col-lg-offset-0 {\n    margin-left: 0;\n  }\n}\ntable {\n  background-color: transparent;\n}\ncaption {\n  padding-top: 8px;\n  padding-bottom: 8px;\n  color: #777;\n  text-align: left;\n}\nth {\n  text-align: left;\n}\n.table {\n  width: 100%;\n  max-width: 100%;\n  margin-bottom: 20px;\n}\n.table > thead > tr > th,\n.table > tbody > tr > th,\n.table > tfoot > tr > th,\n.table > thead > tr > td,\n.table > tbody > tr > td,\n.table > tfoot > tr > td {\n  padding: 8px;\n  line-height: 1.42857143;\n  vertical-align: top;\n  border-top: 1px solid #ddd;\n}\n.table > thead > tr > th {\n  vertical-align: bottom;\n  border-bottom: 2px solid #ddd;\n}\n.table > caption + thead > tr:first-child > th,\n.table > colgroup + thead > tr:first-child > th,\n.table > thead:first-child > tr:first-child > th,\n.table > caption + thead > tr:first-child > td,\n.table > colgroup + thead > tr:first-child > td,\n.table > thead:first-child > tr:first-child > td {\n  border-top: 0;\n}\n.table > tbody + tbody {\n  border-top: 2px solid #ddd;\n}\n.table .table {\n  background-color: #fff;\n}\n.table-condensed > thead > tr > th,\n.table-condensed > tbody > tr > th,\n.table-condensed > tfoot > tr > th,\n.table-condensed > thead > tr > td,\n.table-condensed > tbody > tr > td,\n.table-condensed > tfoot > tr > td {\n  padding: 5px;\n}\n.table-bordered {\n  border: 1px solid #ddd;\n}\n.table-bordered > thead > tr > th,\n.table-bordered > tbody > tr > th,\n.table-bordered > tfoot > tr > th,\n.table-bordered > thead > tr > td,\n.table-bordered > tbody > tr > td,\n.table-bordered > tfoot > tr > td {\n  border: 1px solid #ddd;\n}\n.table-bordered > thead > tr > th,\n.table-bordered > thead > tr > td {\n  border-bottom-width: 2px;\n}\n.table-striped > tbody > tr:nth-of-type(odd) {\n  background-color: #f9f9f9;\n}\n.table-hover > tbody > tr:hover {\n  background-color: #f5f5f5;\n}\ntable col[class*=\"col-\"] {\n  position: static;\n  display: table-column;\n  float: none;\n}\ntable td[class*=\"col-\"],\ntable th[class*=\"col-\"] {\n  position: static;\n  display: table-cell;\n  float: none;\n}\n.table > thead > tr > td.active,\n.table > tbody > tr > td.active,\n.table > tfoot > tr > td.active,\n.table > thead > tr > th.active,\n.table > tbody > tr > th.active,\n.table > tfoot > tr > th.active,\n.table > thead > tr.active > td,\n.table > tbody > tr.active > td,\n.table > tfoot > tr.active > td,\n.table > thead > tr.active > th,\n.table > tbody > tr.active > th,\n.table > tfoot > tr.active > th {\n  background-color: #f5f5f5;\n}\n.table-hover > tbody > tr > td.active:hover,\n.table-hover > tbody > tr > th.active:hover,\n.table-hover > tbody > tr.active:hover > td,\n.table-hover > tbody > tr:hover > .active,\n.table-hover > tbody > tr.active:hover > th {\n  background-color: #e8e8e8;\n}\n.table > thead > tr > td.success,\n.table > tbody > tr > td.success,\n.table > tfoot > tr > td.success,\n.table > thead > tr > th.success,\n.table > tbody > tr > th.success,\n.table > tfoot > tr > th.success,\n.table > thead > tr.success > td,\n.table > tbody > tr.success > td,\n.table > tfoot > tr.success > td,\n.table > thead > tr.success > th,\n.table > tbody > tr.success > th,\n.table > tfoot > tr.success > th {\n  background-color: #dff0d8;\n}\n.table-hover > tbody > tr > td.success:hover,\n.table-hover > tbody > tr > th.success:hover,\n.table-hover > tbody > tr.success:hover > td,\n.table-hover > tbody > tr:hover > .success,\n.table-hover > tbody > tr.success:hover > th {\n  background-color: #d0e9c6;\n}\n.table > thead > tr > td.info,\n.table > tbody > tr > td.info,\n.table > tfoot > tr > td.info,\n.table > thead > tr > th.info,\n.table > tbody > tr > th.info,\n.table > tfoot > tr > th.info,\n.table > thead > tr.info > td,\n.table > tbody > tr.info > td,\n.table > tfoot > tr.info > td,\n.table > thead > tr.info > th,\n.table > tbody > tr.info > th,\n.table > tfoot > tr.info > th {\n  background-color: #d9edf7;\n}\n.table-hover > tbody > tr > td.info:hover,\n.table-hover > tbody > tr > th.info:hover,\n.table-hover > tbody > tr.info:hover > td,\n.table-hover > tbody > tr:hover > .info,\n.table-hover > tbody > tr.info:hover > th {\n  background-color: #c4e3f3;\n}\n.table > thead > tr > td.warning,\n.table > tbody > tr > td.warning,\n.table > tfoot > tr > td.warning,\n.table > thead > tr > th.warning,\n.table > tbody > tr > th.warning,\n.table > tfoot > tr > th.warning,\n.table > thead > tr.warning > td,\n.table > tbody > tr.warning > td,\n.table > tfoot > tr.warning > td,\n.table > thead > tr.warning > th,\n.table > tbody > tr.warning > th,\n.table > tfoot > tr.warning > th {\n  background-color: #fcf8e3;\n}\n.table-hover > tbody > tr > td.warning:hover,\n.table-hover > tbody > tr > th.warning:hover,\n.table-hover > tbody > tr.warning:hover > td,\n.table-hover > tbody > tr:hover > .warning,\n.table-hover > tbody > tr.warning:hover > th {\n  background-color: #faf2cc;\n}\n.table > thead > tr > td.danger,\n.table > tbody > tr > td.danger,\n.table > tfoot > tr > td.danger,\n.table > thead > tr > th.danger,\n.table > tbody > tr > th.danger,\n.table > tfoot > tr > th.danger,\n.table > thead > tr.danger > td,\n.table > tbody > tr.danger > td,\n.table > tfoot > tr.danger > td,\n.table > thead > tr.danger > th,\n.table > tbody > tr.danger > th,\n.table > tfoot > tr.danger > th {\n  background-color: #f2dede;\n}\n.table-hover > tbody > tr > td.danger:hover,\n.table-hover > tbody > tr > th.danger:hover,\n.table-hover > tbody > tr.danger:hover > td,\n.table-hover > tbody > tr:hover > .danger,\n.table-hover > tbody > tr.danger:hover > th {\n  background-color: #ebcccc;\n}\n.table-responsive {\n  min-height: .01%;\n  overflow-x: auto;\n}\n@media screen and (max-width: 767px) {\n  .table-responsive {\n    width: 100%;\n    margin-bottom: 15px;\n    overflow-y: hidden;\n    -ms-overflow-style: -ms-autohiding-scrollbar;\n    border: 1px solid #ddd;\n  }\n  .table-responsive > .table {\n    margin-bottom: 0;\n  }\n  .table-responsive > .table > thead > tr > th,\n  .table-responsive > .table > tbody > tr > th,\n  .table-responsive > .table > tfoot > tr > th,\n  .table-responsive > .table > thead > tr > td,\n  .table-responsive > .table > tbody > tr > td,\n  .table-responsive > .table > tfoot > tr > td {\n    white-space: nowrap;\n  }\n  .table-responsive > .table-bordered {\n    border: 0;\n  }\n  .table-responsive > .table-bordered > thead > tr > th:first-child,\n  .table-responsive > .table-bordered > tbody > tr > th:first-child,\n  .table-responsive > .table-bordered > tfoot > tr > th:first-child,\n  .table-responsive > .table-bordered > thead > tr > td:first-child,\n  .table-responsive > .table-bordered > tbody > tr > td:first-child,\n  .table-responsive > .table-bordered > tfoot > tr > td:first-child {\n    border-left: 0;\n  }\n  .table-responsive > .table-bordered > thead > tr > th:last-child,\n  .table-responsive > .table-bordered > tbody > tr > th:last-child,\n  .table-responsive > .table-bordered > tfoot > tr > th:last-child,\n  .table-responsive > .table-bordered > thead > tr > td:last-child,\n  .table-responsive > .table-bordered > tbody > tr > td:last-child,\n  .table-responsive > .table-bordered > tfoot > tr > td:last-child {\n    border-right: 0;\n  }\n  .table-responsive > .table-bordered > tbody > tr:last-child > th,\n  .table-responsive > .table-bordered > tfoot > tr:last-child > th,\n  .table-responsive > .table-bordered > tbody > tr:last-child > td,\n  .table-responsive > .table-bordered > tfoot > tr:last-child > td {\n    border-bottom: 0;\n  }\n}\nfieldset {\n  min-width: 0;\n  padding: 0;\n  margin: 0;\n  border: 0;\n}\nlegend {\n  display: block;\n  width: 100%;\n  padding: 0;\n  margin-bottom: 20px;\n  font-size: 21px;\n  line-height: inherit;\n  color: #333;\n  border: 0;\n  border-bottom: 1px solid #e5e5e5;\n}\nlabel {\n  display: inline-block;\n  max-width: 100%;\n  margin-bottom: 5px;\n  font-weight: bold;\n}\ninput[type=\"search\"] {\n  -webkit-box-sizing: border-box;\n     -moz-box-sizing: border-box;\n          box-sizing: border-box;\n}\ninput[type=\"radio\"],\ninput[type=\"checkbox\"] {\n  margin: 4px 0 0;\n  margin-top: 1px \\9;\n  line-height: normal;\n}\ninput[type=\"file\"] {\n  display: block;\n}\ninput[type=\"range\"] {\n  display: block;\n  width: 100%;\n}\nselect[multiple],\nselect[size] {\n  height: auto;\n}\ninput[type=\"file\"]:focus,\ninput[type=\"radio\"]:focus,\ninput[type=\"checkbox\"]:focus {\n  outline: thin dotted;\n  outline: 5px auto -webkit-focus-ring-color;\n  outline-offset: -2px;\n}\noutput {\n  display: block;\n  padding-top: 7px;\n  font-size: 14px;\n  line-height: 1.42857143;\n  color: #555;\n}\n.form-control {\n  display: block;\n  width: 100%;\n  height: 34px;\n  padding: 6px 12px;\n  font-size: 14px;\n  line-height: 1.42857143;\n  color: #555;\n  background-color: #fff;\n  background-image: none;\n  border: 1px solid #ccc;\n  border-radius: 4px;\n  -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075);\n          box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075);\n  -webkit-transition: border-color ease-in-out .15s, -webkit-box-shadow ease-in-out .15s;\n       -o-transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s;\n          transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s;\n}\n.form-control:focus {\n  border-color: #66afe9;\n  outline: 0;\n  -webkit-box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(102, 175, 233, .6);\n          box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(102, 175, 233, .6);\n}\n.form-control::-moz-placeholder {\n  color: #999;\n  opacity: 1;\n}\n.form-control:-ms-input-placeholder {\n  color: #999;\n}\n.form-control::-webkit-input-placeholder {\n  color: #999;\n}\n.form-control[disabled],\n.form-control[readonly],\nfieldset[disabled] .form-control {\n  background-color: #eee;\n  opacity: 1;\n}\n.form-control[disabled],\nfieldset[disabled] .form-control {\n  cursor: not-allowed;\n}\ntextarea.form-control {\n  height: auto;\n}\ninput[type=\"search\"] {\n  -webkit-appearance: none;\n}\n@media screen and (-webkit-min-device-pixel-ratio: 0) {\n  input[type=\"date\"].form-control,\n  input[type=\"time\"].form-control,\n  input[type=\"datetime-local\"].form-control,\n  input[type=\"month\"].form-control {\n    line-height: 34px;\n  }\n  input[type=\"date\"].input-sm,\n  input[type=\"time\"].input-sm,\n  input[type=\"datetime-local\"].input-sm,\n  input[type=\"month\"].input-sm,\n  .input-group-sm input[type=\"date\"],\n  .input-group-sm input[type=\"time\"],\n  .input-group-sm input[type=\"datetime-local\"],\n  .input-group-sm input[type=\"month\"] {\n    line-height: 30px;\n  }\n  input[type=\"date\"].input-lg,\n  input[type=\"time\"].input-lg,\n  input[type=\"datetime-local\"].input-lg,\n  input[type=\"month\"].input-lg,\n  .input-group-lg input[type=\"date\"],\n  .input-group-lg input[type=\"time\"],\n  .input-group-lg input[type=\"datetime-local\"],\n  .input-group-lg input[type=\"month\"] {\n    line-height: 46px;\n  }\n}\n.form-group {\n  margin-bottom: 15px;\n}\n.radio,\n.checkbox {\n  position: relative;\n  display: block;\n  margin-top: 10px;\n  margin-bottom: 10px;\n}\n.radio label,\n.checkbox label {\n  min-height: 20px;\n  padding-left: 20px;\n  margin-bottom: 0;\n  font-weight: normal;\n  cursor: pointer;\n}\n.radio input[type=\"radio\"],\n.radio-inline input[type=\"radio\"],\n.checkbox input[type=\"checkbox\"],\n.checkbox-inline input[type=\"checkbox\"] {\n  position: absolute;\n  margin-top: 4px \\9;\n  margin-left: -20px;\n}\n.radio + .radio,\n.checkbox + .checkbox {\n  margin-top: -5px;\n}\n.radio-inline,\n.checkbox-inline {\n  position: relative;\n  display: inline-block;\n  padding-left: 20px;\n  margin-bottom: 0;\n  font-weight: normal;\n  vertical-align: middle;\n  cursor: pointer;\n}\n.radio-inline + .radio-inline,\n.checkbox-inline + .checkbox-inline {\n  margin-top: 0;\n  margin-left: 10px;\n}\ninput[type=\"radio\"][disabled],\ninput[type=\"checkbox\"][disabled],\ninput[type=\"radio\"].disabled,\ninput[type=\"checkbox\"].disabled,\nfieldset[disabled] input[type=\"radio\"],\nfieldset[disabled] input[type=\"checkbox\"] {\n  cursor: not-allowed;\n}\n.radio-inline.disabled,\n.checkbox-inline.disabled,\nfieldset[disabled] .radio-inline,\nfieldset[disabled] .checkbox-inline {\n  cursor: not-allowed;\n}\n.radio.disabled label,\n.checkbox.disabled label,\nfieldset[disabled] .radio label,\nfieldset[disabled] .checkbox label {\n  cursor: not-allowed;\n}\n.form-control-static {\n  min-height: 34px;\n  padding-top: 7px;\n  padding-bottom: 7px;\n  margin-bottom: 0;\n}\n.form-control-static.input-lg,\n.form-control-static.input-sm {\n  padding-right: 0;\n  padding-left: 0;\n}\n.input-sm {\n  height: 30px;\n  padding: 5px 10px;\n  font-size: 12px;\n  line-height: 1.5;\n  border-radius: 3px;\n}\nselect.input-sm {\n  height: 30px;\n  line-height: 30px;\n}\ntextarea.input-sm,\nselect[multiple].input-sm {\n  height: auto;\n}\n.form-group-sm .form-control {\n  height: 30px;\n  padding: 5px 10px;\n  font-size: 12px;\n  line-height: 1.5;\n  border-radius: 3px;\n}\n.form-group-sm select.form-control {\n  height: 30px;\n  line-height: 30px;\n}\n.form-group-sm textarea.form-control,\n.form-group-sm select[multiple].form-control {\n  height: auto;\n}\n.form-group-sm .form-control-static {\n  height: 30px;\n  min-height: 32px;\n  padding: 6px 10px;\n  font-size: 12px;\n  line-height: 1.5;\n}\n.input-lg {\n  height: 46px;\n  padding: 10px 16px;\n  font-size: 18px;\n  line-height: 1.3333333;\n  border-radius: 6px;\n}\nselect.input-lg {\n  height: 46px;\n  line-height: 46px;\n}\ntextarea.input-lg,\nselect[multiple].input-lg {\n  height: auto;\n}\n.form-group-lg .form-control {\n  height: 46px;\n  padding: 10px 16px;\n  font-size: 18px;\n  line-height: 1.3333333;\n  border-radius: 6px;\n}\n.form-group-lg select.form-control {\n  height: 46px;\n  line-height: 46px;\n}\n.form-group-lg textarea.form-control,\n.form-group-lg select[multiple].form-control {\n  height: auto;\n}\n.form-group-lg .form-control-static {\n  height: 46px;\n  min-height: 38px;\n  padding: 11px 16px;\n  font-size: 18px;\n  line-height: 1.3333333;\n}\n.has-feedback {\n  position: relative;\n}\n.has-feedback .form-control {\n  padding-right: 42.5px;\n}\n.form-control-feedback {\n  position: absolute;\n  top: 0;\n  right: 0;\n  z-index: 2;\n  display: block;\n  width: 34px;\n  height: 34px;\n  line-height: 34px;\n  text-align: center;\n  pointer-events: none;\n}\n.input-lg + .form-control-feedback,\n.input-group-lg + .form-control-feedback,\n.form-group-lg .form-control + .form-control-feedback {\n  width: 46px;\n  height: 46px;\n  line-height: 46px;\n}\n.input-sm + .form-control-feedback,\n.input-group-sm + .form-control-feedback,\n.form-group-sm .form-control + .form-control-feedback {\n  width: 30px;\n  height: 30px;\n  line-height: 30px;\n}\n.has-success .help-block,\n.has-success .control-label,\n.has-success .radio,\n.has-success .checkbox,\n.has-success .radio-inline,\n.has-success .checkbox-inline,\n.has-success.radio label,\n.has-success.checkbox label,\n.has-success.radio-inline label,\n.has-success.checkbox-inline label {\n  color: #3c763d;\n}\n.has-success .form-control {\n  border-color: #3c763d;\n  -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075);\n          box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075);\n}\n.has-success .form-control:focus {\n  border-color: #2b542c;\n  -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 6px #67b168;\n          box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 6px #67b168;\n}\n.has-success .input-group-addon {\n  color: #3c763d;\n  background-color: #dff0d8;\n  border-color: #3c763d;\n}\n.has-success .form-control-feedback {\n  color: #3c763d;\n}\n.has-warning .help-block,\n.has-warning .control-label,\n.has-warning .radio,\n.has-warning .checkbox,\n.has-warning .radio-inline,\n.has-warning .checkbox-inline,\n.has-warning.radio label,\n.has-warning.checkbox label,\n.has-warning.radio-inline label,\n.has-warning.checkbox-inline label {\n  color: #8a6d3b;\n}\n.has-warning .form-control {\n  border-color: #8a6d3b;\n  -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075);\n          box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075);\n}\n.has-warning .form-control:focus {\n  border-color: #66512c;\n  -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 6px #c0a16b;\n          box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 6px #c0a16b;\n}\n.has-warning .input-group-addon {\n  color: #8a6d3b;\n  background-color: #fcf8e3;\n  border-color: #8a6d3b;\n}\n.has-warning .form-control-feedback {\n  color: #8a6d3b;\n}\n.has-error .help-block,\n.has-error .control-label,\n.has-error .radio,\n.has-error .checkbox,\n.has-error .radio-inline,\n.has-error .checkbox-inline,\n.has-error.radio label,\n.has-error.checkbox label,\n.has-error.radio-inline label,\n.has-error.checkbox-inline label {\n  color: #a94442;\n}\n.has-error .form-control {\n  border-color: #a94442;\n  -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075);\n          box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075);\n}\n.has-error .form-control:focus {\n  border-color: #843534;\n  -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 6px #ce8483;\n          box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 6px #ce8483;\n}\n.has-error .input-group-addon {\n  color: #a94442;\n  background-color: #f2dede;\n  border-color: #a94442;\n}\n.has-error .form-control-feedback {\n  color: #a94442;\n}\n.has-feedback label ~ .form-control-feedback {\n  top: 25px;\n}\n.has-feedback label.sr-only ~ .form-control-feedback {\n  top: 0;\n}\n.help-block {\n  display: block;\n  margin-top: 5px;\n  margin-bottom: 10px;\n  color: #737373;\n}\n@media (min-width: 768px) {\n  .form-inline .form-group {\n    display: inline-block;\n    margin-bottom: 0;\n    vertical-align: middle;\n  }\n  .form-inline .form-control {\n    display: inline-block;\n    width: auto;\n    vertical-align: middle;\n  }\n  .form-inline .form-control-static {\n    display: inline-block;\n  }\n  .form-inline .input-group {\n    display: inline-table;\n    vertical-align: middle;\n  }\n  .form-inline .input-group .input-group-addon,\n  .form-inline .input-group .input-group-btn,\n  .form-inline .input-group .form-control {\n    width: auto;\n  }\n  .form-inline .input-group > .form-control {\n    width: 100%;\n  }\n  .form-inline .control-label {\n    margin-bottom: 0;\n    vertical-align: middle;\n  }\n  .form-inline .radio,\n  .form-inline .checkbox {\n    display: inline-block;\n    margin-top: 0;\n    margin-bottom: 0;\n    vertical-align: middle;\n  }\n  .form-inline .radio label,\n  .form-inline .checkbox label {\n    padding-left: 0;\n  }\n  .form-inline .radio input[type=\"radio\"],\n  .form-inline .checkbox input[type=\"checkbox\"] {\n    position: relative;\n    margin-left: 0;\n  }\n  .form-inline .has-feedback .form-control-feedback {\n    top: 0;\n  }\n}\n.form-horizontal .radio,\n.form-horizontal .checkbox,\n.form-horizontal .radio-inline,\n.form-horizontal .checkbox-inline {\n  padding-top: 7px;\n  margin-top: 0;\n  margin-bottom: 0;\n}\n.form-horizontal .radio,\n.form-horizontal .checkbox {\n  min-height: 27px;\n}\n.form-horizontal .form-group {\n  margin-right: -15px;\n  margin-left: -15px;\n}\n@media (min-width: 768px) {\n  .form-horizontal .control-label {\n    padding-top: 7px;\n    margin-bottom: 0;\n    text-align: right;\n  }\n}\n.form-horizontal .has-feedback .form-control-feedback {\n  right: 15px;\n}\n@media (min-width: 768px) {\n  .form-horizontal .form-group-lg .control-label {\n    padding-top: 14.333333px;\n    font-size: 18px;\n  }\n}\n@media (min-width: 768px) {\n  .form-horizontal .form-group-sm .control-label {\n    padding-top: 6px;\n    font-size: 12px;\n  }\n}\n.btn {\n  display: inline-block;\n  padding: 6px 12px;\n  margin-bottom: 0;\n  font-size: 14px;\n  font-weight: normal;\n  line-height: 1.42857143;\n  text-align: center;\n  white-space: nowrap;\n  vertical-align: middle;\n  -ms-touch-action: manipulation;\n      touch-action: manipulation;\n  cursor: pointer;\n  -webkit-user-select: none;\n     -moz-user-select: none;\n      -ms-user-select: none;\n          user-select: none;\n  background-image: none;\n  border: 1px solid transparent;\n  border-radius: 4px;\n}\n.btn:focus,\n.btn:active:focus,\n.btn.active:focus,\n.btn.focus,\n.btn:active.focus,\n.btn.active.focus {\n  outline: thin dotted;\n  outline: 5px auto -webkit-focus-ring-color;\n  outline-offset: -2px;\n}\n.btn:hover,\n.btn:focus,\n.btn.focus {\n  color: #333;\n  text-decoration: none;\n}\n.btn:active,\n.btn.active {\n  background-image: none;\n  outline: 0;\n  -webkit-box-shadow: inset 0 3px 5px rgba(0, 0, 0, .125);\n          box-shadow: inset 0 3px 5px rgba(0, 0, 0, .125);\n}\n.btn.disabled,\n.btn[disabled],\nfieldset[disabled] .btn {\n  cursor: not-allowed;\n  filter: alpha(opacity=65);\n  -webkit-box-shadow: none;\n          box-shadow: none;\n  opacity: .65;\n}\na.btn.disabled,\nfieldset[disabled] a.btn {\n  pointer-events: none;\n}\n.btn-default {\n  color: #333;\n  background-color: #fff;\n  border-color: #ccc;\n}\n.btn-default:focus,\n.btn-default.focus {\n  color: #333;\n  background-color: #e6e6e6;\n  border-color: #8c8c8c;\n}\n.btn-default:hover {\n  color: #333;\n  background-color: #e6e6e6;\n  border-color: #adadad;\n}\n.btn-default:active,\n.btn-default.active,\n.open > .dropdown-toggle.btn-default {\n  color: #333;\n  background-color: #e6e6e6;\n  border-color: #adadad;\n}\n.btn-default:active:hover,\n.btn-default.active:hover,\n.open > .dropdown-toggle.btn-default:hover,\n.btn-default:active:focus,\n.btn-default.active:focus,\n.open > .dropdown-toggle.btn-default:focus,\n.btn-default:active.focus,\n.btn-default.active.focus,\n.open > .dropdown-toggle.btn-default.focus {\n  color: #333;\n  background-color: #d4d4d4;\n  border-color: #8c8c8c;\n}\n.btn-default:active,\n.btn-default.active,\n.open > .dropdown-toggle.btn-default {\n  background-image: none;\n}\n.btn-default.disabled,\n.btn-default[disabled],\nfieldset[disabled] .btn-default,\n.btn-default.disabled:hover,\n.btn-default[disabled]:hover,\nfieldset[disabled] .btn-default:hover,\n.btn-default.disabled:focus,\n.btn-default[disabled]:focus,\nfieldset[disabled] .btn-default:focus,\n.btn-default.disabled.focus,\n.btn-default[disabled].focus,\nfieldset[disabled] .btn-default.focus,\n.btn-default.disabled:active,\n.btn-default[disabled]:active,\nfieldset[disabled] .btn-default:active,\n.btn-default.disabled.active,\n.btn-default[disabled].active,\nfieldset[disabled] .btn-default.active {\n  background-color: #fff;\n  border-color: #ccc;\n}\n.btn-default .badge {\n  color: #fff;\n  background-color: #333;\n}\n.btn-primary {\n  color: #fff;\n  background-color: #337ab7;\n  border-color: #2e6da4;\n}\n.btn-primary:focus,\n.btn-primary.focus {\n  color: #fff;\n  background-color: #286090;\n  border-color: #122b40;\n}\n.btn-primary:hover {\n  color: #fff;\n  background-color: #286090;\n  border-color: #204d74;\n}\n.btn-primary:active,\n.btn-primary.active,\n.open > .dropdown-toggle.btn-primary {\n  color: #fff;\n  background-color: #286090;\n  border-color: #204d74;\n}\n.btn-primary:active:hover,\n.btn-primary.active:hover,\n.open > .dropdown-toggle.btn-primary:hover,\n.btn-primary:active:focus,\n.btn-primary.active:focus,\n.open > .dropdown-toggle.btn-primary:focus,\n.btn-primary:active.focus,\n.btn-primary.active.focus,\n.open > .dropdown-toggle.btn-primary.focus {\n  color: #fff;\n  background-color: #204d74;\n  border-color: #122b40;\n}\n.btn-primary:active,\n.btn-primary.active,\n.open > .dropdown-toggle.btn-primary {\n  background-image: none;\n}\n.btn-primary.disabled,\n.btn-primary[disabled],\nfieldset[disabled] .btn-primary,\n.btn-primary.disabled:hover,\n.btn-primary[disabled]:hover,\nfieldset[disabled] .btn-primary:hover,\n.btn-primary.disabled:focus,\n.btn-primary[disabled]:focus,\nfieldset[disabled] .btn-primary:focus,\n.btn-primary.disabled.focus,\n.btn-primary[disabled].focus,\nfieldset[disabled] .btn-primary.focus,\n.btn-primary.disabled:active,\n.btn-primary[disabled]:active,\nfieldset[disabled] .btn-primary:active,\n.btn-primary.disabled.active,\n.btn-primary[disabled].active,\nfieldset[disabled] .btn-primary.active {\n  background-color: #337ab7;\n  border-color: #2e6da4;\n}\n.btn-primary .badge {\n  color: #337ab7;\n  background-color: #fff;\n}\n.btn-success {\n  color: #fff;\n  background-color: #5cb85c;\n  border-color: #4cae4c;\n}\n.btn-success:focus,\n.btn-success.focus {\n  color: #fff;\n  background-color: #449d44;\n  border-color: #255625;\n}\n.btn-success:hover {\n  color: #fff;\n  background-color: #449d44;\n  border-color: #398439;\n}\n.btn-success:active,\n.btn-success.active,\n.open > .dropdown-toggle.btn-success {\n  color: #fff;\n  background-color: #449d44;\n  border-color: #398439;\n}\n.btn-success:active:hover,\n.btn-success.active:hover,\n.open > .dropdown-toggle.btn-success:hover,\n.btn-success:active:focus,\n.btn-success.active:focus,\n.open > .dropdown-toggle.btn-success:focus,\n.btn-success:active.focus,\n.btn-success.active.focus,\n.open > .dropdown-toggle.btn-success.focus {\n  color: #fff;\n  background-color: #398439;\n  border-color: #255625;\n}\n.btn-success:active,\n.btn-success.active,\n.open > .dropdown-toggle.btn-success {\n  background-image: none;\n}\n.btn-success.disabled,\n.btn-success[disabled],\nfieldset[disabled] .btn-success,\n.btn-success.disabled:hover,\n.btn-success[disabled]:hover,\nfieldset[disabled] .btn-success:hover,\n.btn-success.disabled:focus,\n.btn-success[disabled]:focus,\nfieldset[disabled] .btn-success:focus,\n.btn-success.disabled.focus,\n.btn-success[disabled].focus,\nfieldset[disabled] .btn-success.focus,\n.btn-success.disabled:active,\n.btn-success[disabled]:active,\nfieldset[disabled] .btn-success:active,\n.btn-success.disabled.active,\n.btn-success[disabled].active,\nfieldset[disabled] .btn-success.active {\n  background-color: #5cb85c;\n  border-color: #4cae4c;\n}\n.btn-success .badge {\n  color: #5cb85c;\n  background-color: #fff;\n}\n.btn-info {\n  color: #fff;\n  background-color: #5bc0de;\n  border-color: #46b8da;\n}\n.btn-info:focus,\n.btn-info.focus {\n  color: #fff;\n  background-color: #31b0d5;\n  border-color: #1b6d85;\n}\n.btn-info:hover {\n  color: #fff;\n  background-color: #31b0d5;\n  border-color: #269abc;\n}\n.btn-info:active,\n.btn-info.active,\n.open > .dropdown-toggle.btn-info {\n  color: #fff;\n  background-color: #31b0d5;\n  border-color: #269abc;\n}\n.btn-info:active:hover,\n.btn-info.active:hover,\n.open > .dropdown-toggle.btn-info:hover,\n.btn-info:active:focus,\n.btn-info.active:focus,\n.open > .dropdown-toggle.btn-info:focus,\n.btn-info:active.focus,\n.btn-info.active.focus,\n.open > .dropdown-toggle.btn-info.focus {\n  color: #fff;\n  background-color: #269abc;\n  border-color: #1b6d85;\n}\n.btn-info:active,\n.btn-info.active,\n.open > .dropdown-toggle.btn-info {\n  background-image: none;\n}\n.btn-info.disabled,\n.btn-info[disabled],\nfieldset[disabled] .btn-info,\n.btn-info.disabled:hover,\n.btn-info[disabled]:hover,\nfieldset[disabled] .btn-info:hover,\n.btn-info.disabled:focus,\n.btn-info[disabled]:focus,\nfieldset[disabled] .btn-info:focus,\n.btn-info.disabled.focus,\n.btn-info[disabled].focus,\nfieldset[disabled] .btn-info.focus,\n.btn-info.disabled:active,\n.btn-info[disabled]:active,\nfieldset[disabled] .btn-info:active,\n.btn-info.disabled.active,\n.btn-info[disabled].active,\nfieldset[disabled] .btn-info.active {\n  background-color: #5bc0de;\n  border-color: #46b8da;\n}\n.btn-info .badge {\n  color: #5bc0de;\n  background-color: #fff;\n}\n.btn-warning {\n  color: #fff;\n  background-color: #f0ad4e;\n  border-color: #eea236;\n}\n.btn-warning:focus,\n.btn-warning.focus {\n  color: #fff;\n  background-color: #ec971f;\n  border-color: #985f0d;\n}\n.btn-warning:hover {\n  color: #fff;\n  background-color: #ec971f;\n  border-color: #d58512;\n}\n.btn-warning:active,\n.btn-warning.active,\n.open > .dropdown-toggle.btn-warning {\n  color: #fff;\n  background-color: #ec971f;\n  border-color: #d58512;\n}\n.btn-warning:active:hover,\n.btn-warning.active:hover,\n.open > .dropdown-toggle.btn-warning:hover,\n.btn-warning:active:focus,\n.btn-warning.active:focus,\n.open > .dropdown-toggle.btn-warning:focus,\n.btn-warning:active.focus,\n.btn-warning.active.focus,\n.open > .dropdown-toggle.btn-warning.focus {\n  color: #fff;\n  background-color: #d58512;\n  border-color: #985f0d;\n}\n.btn-warning:active,\n.btn-warning.active,\n.open > .dropdown-toggle.btn-warning {\n  background-image: none;\n}\n.btn-warning.disabled,\n.btn-warning[disabled],\nfieldset[disabled] .btn-warning,\n.btn-warning.disabled:hover,\n.btn-warning[disabled]:hover,\nfieldset[disabled] .btn-warning:hover,\n.btn-warning.disabled:focus,\n.btn-warning[disabled]:focus,\nfieldset[disabled] .btn-warning:focus,\n.btn-warning.disabled.focus,\n.btn-warning[disabled].focus,\nfieldset[disabled] .btn-warning.focus,\n.btn-warning.disabled:active,\n.btn-warning[disabled]:active,\nfieldset[disabled] .btn-warning:active,\n.btn-warning.disabled.active,\n.btn-warning[disabled].active,\nfieldset[disabled] .btn-warning.active {\n  background-color: #f0ad4e;\n  border-color: #eea236;\n}\n.btn-warning .badge {\n  color: #f0ad4e;\n  background-color: #fff;\n}\n.btn-danger {\n  color: #fff;\n  background-color: #d9534f;\n  border-color: #d43f3a;\n}\n.btn-danger:focus,\n.btn-danger.focus {\n  color: #fff;\n  background-color: #c9302c;\n  border-color: #761c19;\n}\n.btn-danger:hover {\n  color: #fff;\n  background-color: #c9302c;\n  border-color: #ac2925;\n}\n.btn-danger:active,\n.btn-danger.active,\n.open > .dropdown-toggle.btn-danger {\n  color: #fff;\n  background-color: #c9302c;\n  border-color: #ac2925;\n}\n.btn-danger:active:hover,\n.btn-danger.active:hover,\n.open > .dropdown-toggle.btn-danger:hover,\n.btn-danger:active:focus,\n.btn-danger.active:focus,\n.open > .dropdown-toggle.btn-danger:focus,\n.btn-danger:active.focus,\n.btn-danger.active.focus,\n.open > .dropdown-toggle.btn-danger.focus {\n  color: #fff;\n  background-color: #ac2925;\n  border-color: #761c19;\n}\n.btn-danger:active,\n.btn-danger.active,\n.open > .dropdown-toggle.btn-danger {\n  background-image: none;\n}\n.btn-danger.disabled,\n.btn-danger[disabled],\nfieldset[disabled] .btn-danger,\n.btn-danger.disabled:hover,\n.btn-danger[disabled]:hover,\nfieldset[disabled] .btn-danger:hover,\n.btn-danger.disabled:focus,\n.btn-danger[disabled]:focus,\nfieldset[disabled] .btn-danger:focus,\n.btn-danger.disabled.focus,\n.btn-danger[disabled].focus,\nfieldset[disabled] .btn-danger.focus,\n.btn-danger.disabled:active,\n.btn-danger[disabled]:active,\nfieldset[disabled] .btn-danger:active,\n.btn-danger.disabled.active,\n.btn-danger[disabled].active,\nfieldset[disabled] .btn-danger.active {\n  background-color: #d9534f;\n  border-color: #d43f3a;\n}\n.btn-danger .badge {\n  color: #d9534f;\n  background-color: #fff;\n}\n.btn-link {\n  font-weight: normal;\n  color: #337ab7;\n  border-radius: 0;\n}\n.btn-link,\n.btn-link:active,\n.btn-link.active,\n.btn-link[disabled],\nfieldset[disabled] .btn-link {\n  background-color: transparent;\n  -webkit-box-shadow: none;\n          box-shadow: none;\n}\n.btn-link,\n.btn-link:hover,\n.btn-link:focus,\n.btn-link:active {\n  border-color: transparent;\n}\n.btn-link:hover,\n.btn-link:focus {\n  color: #23527c;\n  text-decoration: underline;\n  background-color: transparent;\n}\n.btn-link[disabled]:hover,\nfieldset[disabled] .btn-link:hover,\n.btn-link[disabled]:focus,\nfieldset[disabled] .btn-link:focus {\n  color: #777;\n  text-decoration: none;\n}\n.btn-lg,\n.btn-group-lg > .btn {\n  padding: 10px 16px;\n  font-size: 18px;\n  line-height: 1.3333333;\n  border-radius: 6px;\n}\n.btn-sm,\n.btn-group-sm > .btn {\n  padding: 5px 10px;\n  font-size: 12px;\n  line-height: 1.5;\n  border-radius: 3px;\n}\n.btn-xs,\n.btn-group-xs > .btn {\n  padding: 1px 5px;\n  font-size: 12px;\n  line-height: 1.5;\n  border-radius: 3px;\n}\n.btn-block {\n  display: block;\n  width: 100%;\n}\n.btn-block + .btn-block {\n  margin-top: 5px;\n}\ninput[type=\"submit\"].btn-block,\ninput[type=\"reset\"].btn-block,\ninput[type=\"button\"].btn-block {\n  width: 100%;\n}\n.fade {\n  opacity: 0;\n  -webkit-transition: opacity .15s linear;\n       -o-transition: opacity .15s linear;\n          transition: opacity .15s linear;\n}\n.fade.in {\n  opacity: 1;\n}\n.collapse {\n  display: none;\n}\n.collapse.in {\n  display: block;\n}\ntr.collapse.in {\n  display: table-row;\n}\ntbody.collapse.in {\n  display: table-row-group;\n}\n.collapsing {\n  position: relative;\n  height: 0;\n  overflow: hidden;\n  -webkit-transition-timing-function: ease;\n       -o-transition-timing-function: ease;\n          transition-timing-function: ease;\n  -webkit-transition-duration: .35s;\n       -o-transition-duration: .35s;\n          transition-duration: .35s;\n  -webkit-transition-property: height, visibility;\n       -o-transition-property: height, visibility;\n          transition-property: height, visibility;\n}\n.caret {\n  display: inline-block;\n  width: 0;\n  height: 0;\n  margin-left: 2px;\n  vertical-align: middle;\n  border-top: 4px dashed;\n  border-top: 4px solid \\9;\n  border-right: 4px solid transparent;\n  border-left: 4px solid transparent;\n}\n.dropup,\n.dropdown {\n  position: relative;\n}\n.dropdown-toggle:focus {\n  outline: 0;\n}\n.dropdown-menu {\n  position: absolute;\n  top: 100%;\n  left: 0;\n  z-index: 1000;\n  display: none;\n  float: left;\n  min-width: 160px;\n  padding: 5px 0;\n  margin: 2px 0 0;\n  font-size: 14px;\n  text-align: left;\n  list-style: none;\n  background-color: #fff;\n  -webkit-background-clip: padding-box;\n          background-clip: padding-box;\n  border: 1px solid #ccc;\n  border: 1px solid rgba(0, 0, 0, .15);\n  border-radius: 4px;\n  -webkit-box-shadow: 0 6px 12px rgba(0, 0, 0, .175);\n          box-shadow: 0 6px 12px rgba(0, 0, 0, .175);\n}\n.dropdown-menu.pull-right {\n  right: 0;\n  left: auto;\n}\n.dropdown-menu .divider {\n  height: 1px;\n  margin: 9px 0;\n  overflow: hidden;\n  background-color: #e5e5e5;\n}\n.dropdown-menu > li > a {\n  display: block;\n  padding: 3px 20px;\n  clear: both;\n  font-weight: normal;\n  line-height: 1.42857143;\n  color: #333;\n  white-space: nowrap;\n}\n.dropdown-menu > li > a:hover,\n.dropdown-menu > li > a:focus {\n  color: #262626;\n  text-decoration: none;\n  background-color: #f5f5f5;\n}\n.dropdown-menu > .active > a,\n.dropdown-menu > .active > a:hover,\n.dropdown-menu > .active > a:focus {\n  color: #fff;\n  text-decoration: none;\n  background-color: #337ab7;\n  outline: 0;\n}\n.dropdown-menu > .disabled > a,\n.dropdown-menu > .disabled > a:hover,\n.dropdown-menu > .disabled > a:focus {\n  color: #777;\n}\n.dropdown-menu > .disabled > a:hover,\n.dropdown-menu > .disabled > a:focus {\n  text-decoration: none;\n  cursor: not-allowed;\n  background-color: transparent;\n  background-image: none;\n  filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);\n}\n.open > .dropdown-menu {\n  display: block;\n}\n.open > a {\n  outline: 0;\n}\n.dropdown-menu-right {\n  right: 0;\n  left: auto;\n}\n.dropdown-menu-left {\n  right: auto;\n  left: 0;\n}\n.dropdown-header {\n  display: block;\n  padding: 3px 20px;\n  font-size: 12px;\n  line-height: 1.42857143;\n  color: #777;\n  white-space: nowrap;\n}\n.dropdown-backdrop {\n  position: fixed;\n  top: 0;\n  right: 0;\n  bottom: 0;\n  left: 0;\n  z-index: 990;\n}\n.pull-right > .dropdown-menu {\n  right: 0;\n  left: auto;\n}\n.dropup .caret,\n.navbar-fixed-bottom .dropdown .caret {\n  content: \"\";\n  border-top: 0;\n  border-bottom: 4px dashed;\n  border-bottom: 4px solid \\9;\n}\n.dropup .dropdown-menu,\n.navbar-fixed-bottom .dropdown .dropdown-menu {\n  top: auto;\n  bottom: 100%;\n  margin-bottom: 2px;\n}\n@media (min-width: 768px) {\n  .navbar-right .dropdown-menu {\n    right: 0;\n    left: auto;\n  }\n  .navbar-right .dropdown-menu-left {\n    right: auto;\n    left: 0;\n  }\n}\n.btn-group,\n.btn-group-vertical {\n  position: relative;\n  display: inline-block;\n  vertical-align: middle;\n}\n.btn-group > .btn,\n.btn-group-vertical > .btn {\n  position: relative;\n  float: left;\n}\n.btn-group > .btn:hover,\n.btn-group-vertical > .btn:hover,\n.btn-group > .btn:focus,\n.btn-group-vertical > .btn:focus,\n.btn-group > .btn:active,\n.btn-group-vertical > .btn:active,\n.btn-group > .btn.active,\n.btn-group-vertical > .btn.active {\n  z-index: 2;\n}\n.btn-group .btn + .btn,\n.btn-group .btn + .btn-group,\n.btn-group .btn-group + .btn,\n.btn-group .btn-group + .btn-group {\n  margin-left: -1px;\n}\n.btn-toolbar {\n  margin-left: -5px;\n}\n.btn-toolbar .btn,\n.btn-toolbar .btn-group,\n.btn-toolbar .input-group {\n  float: left;\n}\n.btn-toolbar > .btn,\n.btn-toolbar > .btn-group,\n.btn-toolbar > .input-group {\n  margin-left: 5px;\n}\n.btn-group > .btn:not(:first-child):not(:last-child):not(.dropdown-toggle) {\n  border-radius: 0;\n}\n.btn-group > .btn:first-child {\n  margin-left: 0;\n}\n.btn-group > .btn:first-child:not(:last-child):not(.dropdown-toggle) {\n  border-top-right-radius: 0;\n  border-bottom-right-radius: 0;\n}\n.btn-group > .btn:last-child:not(:first-child),\n.btn-group > .dropdown-toggle:not(:first-child) {\n  border-top-left-radius: 0;\n  border-bottom-left-radius: 0;\n}\n.btn-group > .btn-group {\n  float: left;\n}\n.btn-group > .btn-group:not(:first-child):not(:last-child) > .btn {\n  border-radius: 0;\n}\n.btn-group > .btn-group:first-child:not(:last-child) > .btn:last-child,\n.btn-group > .btn-group:first-child:not(:last-child) > .dropdown-toggle {\n  border-top-right-radius: 0;\n  border-bottom-right-radius: 0;\n}\n.btn-group > .btn-group:last-child:not(:first-child) > .btn:first-child {\n  border-top-left-radius: 0;\n  border-bottom-left-radius: 0;\n}\n.btn-group .dropdown-toggle:active,\n.btn-group.open .dropdown-toggle {\n  outline: 0;\n}\n.btn-group > .btn + .dropdown-toggle {\n  padding-right: 8px;\n  padding-left: 8px;\n}\n.btn-group > .btn-lg + .dropdown-toggle {\n  padding-right: 12px;\n  padding-left: 12px;\n}\n.btn-group.open .dropdown-toggle {\n  -webkit-box-shadow: inset 0 3px 5px rgba(0, 0, 0, .125);\n          box-shadow: inset 0 3px 5px rgba(0, 0, 0, .125);\n}\n.btn-group.open .dropdown-toggle.btn-link {\n  -webkit-box-shadow: none;\n          box-shadow: none;\n}\n.btn .caret {\n  margin-left: 0;\n}\n.btn-lg .caret {\n  border-width: 5px 5px 0;\n  border-bottom-width: 0;\n}\n.dropup .btn-lg .caret {\n  border-width: 0 5px 5px;\n}\n.btn-group-vertical > .btn,\n.btn-group-vertical > .btn-group,\n.btn-group-vertical > .btn-group > .btn {\n  display: block;\n  float: none;\n  width: 100%;\n  max-width: 100%;\n}\n.btn-group-vertical > .btn-group > .btn {\n  float: none;\n}\n.btn-group-vertical > .btn + .btn,\n.btn-group-vertical > .btn + .btn-group,\n.btn-group-vertical > .btn-group + .btn,\n.btn-group-vertical > .btn-group + .btn-group {\n  margin-top: -1px;\n  margin-left: 0;\n}\n.btn-group-vertical > .btn:not(:first-child):not(:last-child) {\n  border-radius: 0;\n}\n.btn-group-vertical > .btn:first-child:not(:last-child) {\n  border-top-right-radius: 4px;\n  border-bottom-right-radius: 0;\n  border-bottom-left-radius: 0;\n}\n.btn-group-vertical > .btn:last-child:not(:first-child) {\n  border-top-left-radius: 0;\n  border-top-right-radius: 0;\n  border-bottom-left-radius: 4px;\n}\n.btn-group-vertical > .btn-group:not(:first-child):not(:last-child) > .btn {\n  border-radius: 0;\n}\n.btn-group-vertical > .btn-group:first-child:not(:last-child) > .btn:last-child,\n.btn-group-vertical > .btn-group:first-child:not(:last-child) > .dropdown-toggle {\n  border-bottom-right-radius: 0;\n  border-bottom-left-radius: 0;\n}\n.btn-group-vertical > .btn-group:last-child:not(:first-child) > .btn:first-child {\n  border-top-left-radius: 0;\n  border-top-right-radius: 0;\n}\n.btn-group-justified {\n  display: table;\n  width: 100%;\n  table-layout: fixed;\n  border-collapse: separate;\n}\n.btn-group-justified > .btn,\n.btn-group-justified > .btn-group {\n  display: table-cell;\n  float: none;\n  width: 1%;\n}\n.btn-group-justified > .btn-group .btn {\n  width: 100%;\n}\n.btn-group-justified > .btn-group .dropdown-menu {\n  left: auto;\n}\n[data-toggle=\"buttons\"] > .btn input[type=\"radio\"],\n[data-toggle=\"buttons\"] > .btn-group > .btn input[type=\"radio\"],\n[data-toggle=\"buttons\"] > .btn input[type=\"checkbox\"],\n[data-toggle=\"buttons\"] > .btn-group > .btn input[type=\"checkbox\"] {\n  position: absolute;\n  clip: rect(0, 0, 0, 0);\n  pointer-events: none;\n}\n.input-group {\n  position: relative;\n  display: table;\n  border-collapse: separate;\n}\n.input-group[class*=\"col-\"] {\n  float: none;\n  padding-right: 0;\n  padding-left: 0;\n}\n.input-group .form-control {\n  position: relative;\n  z-index: 2;\n  float: left;\n  width: 100%;\n  margin-bottom: 0;\n}\n.input-group-lg > .form-control,\n.input-group-lg > .input-group-addon,\n.input-group-lg > .input-group-btn > .btn {\n  height: 46px;\n  padding: 10px 16px;\n  font-size: 18px;\n  line-height: 1.3333333;\n  border-radius: 6px;\n}\nselect.input-group-lg > .form-control,\nselect.input-group-lg > .input-group-addon,\nselect.input-group-lg > .input-group-btn > .btn {\n  height: 46px;\n  line-height: 46px;\n}\ntextarea.input-group-lg > .form-control,\ntextarea.input-group-lg > .input-group-addon,\ntextarea.input-group-lg > .input-group-btn > .btn,\nselect[multiple].input-group-lg > .form-control,\nselect[multiple].input-group-lg > .input-group-addon,\nselect[multiple].input-group-lg > .input-group-btn > .btn {\n  height: auto;\n}\n.input-group-sm > .form-control,\n.input-group-sm > .input-group-addon,\n.input-group-sm > .input-group-btn > .btn {\n  height: 30px;\n  padding: 5px 10px;\n  font-size: 12px;\n  line-height: 1.5;\n  border-radius: 3px;\n}\nselect.input-group-sm > .form-control,\nselect.input-group-sm > .input-group-addon,\nselect.input-group-sm > .input-group-btn > .btn {\n  height: 30px;\n  line-height: 30px;\n}\ntextarea.input-group-sm > .form-control,\ntextarea.input-group-sm > .input-group-addon,\ntextarea.input-group-sm > .input-group-btn > .btn,\nselect[multiple].input-group-sm > .form-control,\nselect[multiple].input-group-sm > .input-group-addon,\nselect[multiple].input-group-sm > .input-group-btn > .btn {\n  height: auto;\n}\n.input-group-addon,\n.input-group-btn,\n.input-group .form-control {\n  display: table-cell;\n}\n.input-group-addon:not(:first-child):not(:last-child),\n.input-group-btn:not(:first-child):not(:last-child),\n.input-group .form-control:not(:first-child):not(:last-child) {\n  border-radius: 0;\n}\n.input-group-addon,\n.input-group-btn {\n  width: 1%;\n  white-space: nowrap;\n  vertical-align: middle;\n}\n.input-group-addon {\n  padding: 6px 12px;\n  font-size: 14px;\n  font-weight: normal;\n  line-height: 1;\n  color: #555;\n  text-align: center;\n  background-color: #eee;\n  border: 1px solid #ccc;\n  border-radius: 4px;\n}\n.input-group-addon.input-sm {\n  padding: 5px 10px;\n  font-size: 12px;\n  border-radius: 3px;\n}\n.input-group-addon.input-lg {\n  padding: 10px 16px;\n  font-size: 18px;\n  border-radius: 6px;\n}\n.input-group-addon input[type=\"radio\"],\n.input-group-addon input[type=\"checkbox\"] {\n  margin-top: 0;\n}\n.input-group .form-control:first-child,\n.input-group-addon:first-child,\n.input-group-btn:first-child > .btn,\n.input-group-btn:first-child > .btn-group > .btn,\n.input-group-btn:first-child > .dropdown-toggle,\n.input-group-btn:last-child > .btn:not(:last-child):not(.dropdown-toggle),\n.input-group-btn:last-child > .btn-group:not(:last-child) > .btn {\n  border-top-right-radius: 0;\n  border-bottom-right-radius: 0;\n}\n.input-group-addon:first-child {\n  border-right: 0;\n}\n.input-group .form-control:last-child,\n.input-group-addon:last-child,\n.input-group-btn:last-child > .btn,\n.input-group-btn:last-child > .btn-group > .btn,\n.input-group-btn:last-child > .dropdown-toggle,\n.input-group-btn:first-child > .btn:not(:first-child),\n.input-group-btn:first-child > .btn-group:not(:first-child) > .btn {\n  border-top-left-radius: 0;\n  border-bottom-left-radius: 0;\n}\n.input-group-addon:last-child {\n  border-left: 0;\n}\n.input-group-btn {\n  position: relative;\n  font-size: 0;\n  white-space: nowrap;\n}\n.input-group-btn > .btn {\n  position: relative;\n}\n.input-group-btn > .btn + .btn {\n  margin-left: -1px;\n}\n.input-group-btn > .btn:hover,\n.input-group-btn > .btn:focus,\n.input-group-btn > .btn:active {\n  z-index: 2;\n}\n.input-group-btn:first-child > .btn,\n.input-group-btn:first-child > .btn-group {\n  margin-right: -1px;\n}\n.input-group-btn:last-child > .btn,\n.input-group-btn:last-child > .btn-group {\n  z-index: 2;\n  margin-left: -1px;\n}\n.nav {\n  padding-left: 0;\n  margin-bottom: 0;\n  list-style: none;\n}\n.nav > li {\n  position: relative;\n  display: block;\n}\n.nav > li > a {\n  position: relative;\n  display: block;\n  padding: 10px 15px;\n}\n.nav > li > a:hover,\n.nav > li > a:focus {\n  text-decoration: none;\n  background-color: #eee;\n}\n.nav > li.disabled > a {\n  color: #777;\n}\n.nav > li.disabled > a:hover,\n.nav > li.disabled > a:focus {\n  color: #777;\n  text-decoration: none;\n  cursor: not-allowed;\n  background-color: transparent;\n}\n.nav .open > a,\n.nav .open > a:hover,\n.nav .open > a:focus {\n  background-color: #eee;\n  border-color: #337ab7;\n}\n.nav .nav-divider {\n  height: 1px;\n  margin: 9px 0;\n  overflow: hidden;\n  background-color: #e5e5e5;\n}\n.nav > li > a > img {\n  max-width: none;\n}\n.nav-tabs {\n  border-bottom: 1px solid #ddd;\n}\n.nav-tabs > li {\n  float: left;\n  margin-bottom: -1px;\n}\n.nav-tabs > li > a {\n  margin-right: 2px;\n  line-height: 1.42857143;\n  border: 1px solid transparent;\n  border-radius: 4px 4px 0 0;\n}\n.nav-tabs > li > a:hover {\n  border-color: #eee #eee #ddd;\n}\n.nav-tabs > li.active > a,\n.nav-tabs > li.active > a:hover,\n.nav-tabs > li.active > a:focus {\n  color: #555;\n  cursor: default;\n  background-color: #fff;\n  border: 1px solid #ddd;\n  border-bottom-color: transparent;\n}\n.nav-tabs.nav-justified {\n  width: 100%;\n  border-bottom: 0;\n}\n.nav-tabs.nav-justified > li {\n  float: none;\n}\n.nav-tabs.nav-justified > li > a {\n  margin-bottom: 5px;\n  text-align: center;\n}\n.nav-tabs.nav-justified > .dropdown .dropdown-menu {\n  top: auto;\n  left: auto;\n}\n@media (min-width: 768px) {\n  .nav-tabs.nav-justified > li {\n    display: table-cell;\n    width: 1%;\n  }\n  .nav-tabs.nav-justified > li > a {\n    margin-bottom: 0;\n  }\n}\n.nav-tabs.nav-justified > li > a {\n  margin-right: 0;\n  border-radius: 4px;\n}\n.nav-tabs.nav-justified > .active > a,\n.nav-tabs.nav-justified > .active > a:hover,\n.nav-tabs.nav-justified > .active > a:focus {\n  border: 1px solid #ddd;\n}\n@media (min-width: 768px) {\n  .nav-tabs.nav-justified > li > a {\n    border-bottom: 1px solid #ddd;\n    border-radius: 4px 4px 0 0;\n  }\n  .nav-tabs.nav-justified > .active > a,\n  .nav-tabs.nav-justified > .active > a:hover,\n  .nav-tabs.nav-justified > .active > a:focus {\n    border-bottom-color: #fff;\n  }\n}\n.nav-pills > li {\n  float: left;\n}\n.nav-pills > li > a {\n  border-radius: 4px;\n}\n.nav-pills > li + li {\n  margin-left: 2px;\n}\n.nav-pills > li.active > a,\n.nav-pills > li.active > a:hover,\n.nav-pills > li.active > a:focus {\n  color: #fff;\n  background-color: #337ab7;\n}\n.nav-stacked > li {\n  float: none;\n}\n.nav-stacked > li + li {\n  margin-top: 2px;\n  margin-left: 0;\n}\n.nav-justified {\n  width: 100%;\n}\n.nav-justified > li {\n  float: none;\n}\n.nav-justified > li > a {\n  margin-bottom: 5px;\n  text-align: center;\n}\n.nav-justified > .dropdown .dropdown-menu {\n  top: auto;\n  left: auto;\n}\n@media (min-width: 768px) {\n  .nav-justified > li {\n    display: table-cell;\n    width: 1%;\n  }\n  .nav-justified > li > a {\n    margin-bottom: 0;\n  }\n}\n.nav-tabs-justified {\n  border-bottom: 0;\n}\n.nav-tabs-justified > li > a {\n  margin-right: 0;\n  border-radius: 4px;\n}\n.nav-tabs-justified > .active > a,\n.nav-tabs-justified > .active > a:hover,\n.nav-tabs-justified > .active > a:focus {\n  border: 1px solid #ddd;\n}\n@media (min-width: 768px) {\n  .nav-tabs-justified > li > a {\n    border-bottom: 1px solid #ddd;\n    border-radius: 4px 4px 0 0;\n  }\n  .nav-tabs-justified > .active > a,\n  .nav-tabs-justified > .active > a:hover,\n  .nav-tabs-justified > .active > a:focus {\n    border-bottom-color: #fff;\n  }\n}\n.tab-content > .tab-pane {\n  display: none;\n}\n.tab-content > .active {\n  display: block;\n}\n.nav-tabs .dropdown-menu {\n  margin-top: -1px;\n  border-top-left-radius: 0;\n  border-top-right-radius: 0;\n}\n.navbar {\n  position: relative;\n  min-height: 50px;\n  margin-bottom: 20px;\n  border: 1px solid transparent;\n}\n@media (min-width: 768px) {\n  .navbar {\n    border-radius: 4px;\n  }\n}\n@media (min-width: 768px) {\n  .navbar-header {\n    float: left;\n  }\n}\n.navbar-collapse {\n  padding-right: 15px;\n  padding-left: 15px;\n  overflow-x: visible;\n  -webkit-overflow-scrolling: touch;\n  border-top: 1px solid transparent;\n  -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, .1);\n          box-shadow: inset 0 1px 0 rgba(255, 255, 255, .1);\n}\n.navbar-collapse.in {\n  overflow-y: auto;\n}\n@media (min-width: 768px) {\n  .navbar-collapse {\n    width: auto;\n    border-top: 0;\n    -webkit-box-shadow: none;\n            box-shadow: none;\n  }\n  .navbar-collapse.collapse {\n    display: block !important;\n    height: auto !important;\n    padding-bottom: 0;\n    overflow: visible !important;\n  }\n  .navbar-collapse.in {\n    overflow-y: visible;\n  }\n  .navbar-fixed-top .navbar-collapse,\n  .navbar-static-top .navbar-collapse,\n  .navbar-fixed-bottom .navbar-collapse {\n    padding-right: 0;\n    padding-left: 0;\n  }\n}\n.navbar-fixed-top .navbar-collapse,\n.navbar-fixed-bottom .navbar-collapse {\n  max-height: 340px;\n}\n@media (max-device-width: 480px) and (orientation: landscape) {\n  .navbar-fixed-top .navbar-collapse,\n  .navbar-fixed-bottom .navbar-collapse {\n    max-height: 200px;\n  }\n}\n.container > .navbar-header,\n.container-fluid > .navbar-header,\n.container > .navbar-collapse,\n.container-fluid > .navbar-collapse {\n  margin-right: -15px;\n  margin-left: -15px;\n}\n@media (min-width: 768px) {\n  .container > .navbar-header,\n  .container-fluid > .navbar-header,\n  .container > .navbar-collapse,\n  .container-fluid > .navbar-collapse {\n    margin-right: 0;\n    margin-left: 0;\n  }\n}\n.navbar-static-top {\n  z-index: 1000;\n  border-width: 0 0 1px;\n}\n@media (min-width: 768px) {\n  .navbar-static-top {\n    border-radius: 0;\n  }\n}\n.navbar-fixed-top,\n.navbar-fixed-bottom {\n  position: fixed;\n  right: 0;\n  left: 0;\n  z-index: 1030;\n}\n@media (min-width: 768px) {\n  .navbar-fixed-top,\n  .navbar-fixed-bottom {\n    border-radius: 0;\n  }\n}\n.navbar-fixed-top {\n  top: 0;\n  border-width: 0 0 1px;\n}\n.navbar-fixed-bottom {\n  bottom: 0;\n  margin-bottom: 0;\n  border-width: 1px 0 0;\n}\n.navbar-brand {\n  float: left;\n  height: 50px;\n  padding: 15px 15px;\n  font-size: 18px;\n  line-height: 20px;\n}\n.navbar-brand:hover,\n.navbar-brand:focus {\n  text-decoration: none;\n}\n.navbar-brand > img {\n  display: block;\n}\n@media (min-width: 768px) {\n  .navbar > .container .navbar-brand,\n  .navbar > .container-fluid .navbar-brand {\n    margin-left: -15px;\n  }\n}\n.navbar-toggle {\n  position: relative;\n  float: right;\n  padding: 9px 10px;\n  margin-top: 8px;\n  margin-right: 15px;\n  margin-bottom: 8px;\n  background-color: transparent;\n  background-image: none;\n  border: 1px solid transparent;\n  border-radius: 4px;\n}\n.navbar-toggle:focus {\n  outline: 0;\n}\n.navbar-toggle .icon-bar {\n  display: block;\n  width: 22px;\n  height: 2px;\n  border-radius: 1px;\n}\n.navbar-toggle .icon-bar + .icon-bar {\n  margin-top: 4px;\n}\n@media (min-width: 768px) {\n  .navbar-toggle {\n    display: none;\n  }\n}\n.navbar-nav {\n  margin: 7.5px -15px;\n}\n.navbar-nav > li > a {\n  padding-top: 10px;\n  padding-bottom: 10px;\n  line-height: 20px;\n}\n@media (max-width: 767px) {\n  .navbar-nav .open .dropdown-menu {\n    position: static;\n    float: none;\n    width: auto;\n    margin-top: 0;\n    background-color: transparent;\n    border: 0;\n    -webkit-box-shadow: none;\n            box-shadow: none;\n  }\n  .navbar-nav .open .dropdown-menu > li > a,\n  .navbar-nav .open .dropdown-menu .dropdown-header {\n    padding: 5px 15px 5px 25px;\n  }\n  .navbar-nav .open .dropdown-menu > li > a {\n    line-height: 20px;\n  }\n  .navbar-nav .open .dropdown-menu > li > a:hover,\n  .navbar-nav .open .dropdown-menu > li > a:focus {\n    background-image: none;\n  }\n}\n@media (min-width: 768px) {\n  .navbar-nav {\n    float: left;\n    margin: 0;\n  }\n  .navbar-nav > li {\n    float: left;\n  }\n  .navbar-nav > li > a {\n    padding-top: 15px;\n    padding-bottom: 15px;\n  }\n}\n.navbar-form {\n  padding: 10px 15px;\n  margin-top: 8px;\n  margin-right: -15px;\n  margin-bottom: 8px;\n  margin-left: -15px;\n  border-top: 1px solid transparent;\n  border-bottom: 1px solid transparent;\n  -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, .1), 0 1px 0 rgba(255, 255, 255, .1);\n          box-shadow: inset 0 1px 0 rgba(255, 255, 255, .1), 0 1px 0 rgba(255, 255, 255, .1);\n}\n@media (min-width: 768px) {\n  .navbar-form .form-group {\n    display: inline-block;\n    margin-bottom: 0;\n    vertical-align: middle;\n  }\n  .navbar-form .form-control {\n    display: inline-block;\n    width: auto;\n    vertical-align: middle;\n  }\n  .navbar-form .form-control-static {\n    display: inline-block;\n  }\n  .navbar-form .input-group {\n    display: inline-table;\n    vertical-align: middle;\n  }\n  .navbar-form .input-group .input-group-addon,\n  .navbar-form .input-group .input-group-btn,\n  .navbar-form .input-group .form-control {\n    width: auto;\n  }\n  .navbar-form .input-group > .form-control {\n    width: 100%;\n  }\n  .navbar-form .control-label {\n    margin-bottom: 0;\n    vertical-align: middle;\n  }\n  .navbar-form .radio,\n  .navbar-form .checkbox {\n    display: inline-block;\n    margin-top: 0;\n    margin-bottom: 0;\n    vertical-align: middle;\n  }\n  .navbar-form .radio label,\n  .navbar-form .checkbox label {\n    padding-left: 0;\n  }\n  .navbar-form .radio input[type=\"radio\"],\n  .navbar-form .checkbox input[type=\"checkbox\"] {\n    position: relative;\n    margin-left: 0;\n  }\n  .navbar-form .has-feedback .form-control-feedback {\n    top: 0;\n  }\n}\n@media (max-width: 767px) {\n  .navbar-form .form-group {\n    margin-bottom: 5px;\n  }\n  .navbar-form .form-group:last-child {\n    margin-bottom: 0;\n  }\n}\n@media (min-width: 768px) {\n  .navbar-form {\n    width: auto;\n    padding-top: 0;\n    padding-bottom: 0;\n    margin-right: 0;\n    margin-left: 0;\n    border: 0;\n    -webkit-box-shadow: none;\n            box-shadow: none;\n  }\n}\n.navbar-nav > li > .dropdown-menu {\n  margin-top: 0;\n  border-top-left-radius: 0;\n  border-top-right-radius: 0;\n}\n.navbar-fixed-bottom .navbar-nav > li > .dropdown-menu {\n  margin-bottom: 0;\n  border-top-left-radius: 4px;\n  border-top-right-radius: 4px;\n  border-bottom-right-radius: 0;\n  border-bottom-left-radius: 0;\n}\n.navbar-btn {\n  margin-top: 8px;\n  margin-bottom: 8px;\n}\n.navbar-btn.btn-sm {\n  margin-top: 10px;\n  margin-bottom: 10px;\n}\n.navbar-btn.btn-xs {\n  margin-top: 14px;\n  margin-bottom: 14px;\n}\n.navbar-text {\n  margin-top: 15px;\n  margin-bottom: 15px;\n}\n@media (min-width: 768px) {\n  .navbar-text {\n    float: left;\n    margin-right: 15px;\n    margin-left: 15px;\n  }\n}\n@media (min-width: 768px) {\n  .navbar-left {\n    float: left !important;\n  }\n  .navbar-right {\n    float: right !important;\n    margin-right: -15px;\n  }\n  .navbar-right ~ .navbar-right {\n    margin-right: 0;\n  }\n}\n.navbar-default {\n  background-color: #f8f8f8;\n  border-color: #e7e7e7;\n}\n.navbar-default .navbar-brand {\n  color: #777;\n}\n.navbar-default .navbar-brand:hover,\n.navbar-default .navbar-brand:focus {\n  color: #5e5e5e;\n  background-color: transparent;\n}\n.navbar-default .navbar-text {\n  color: #777;\n}\n.navbar-default .navbar-nav > li > a {\n  color: #777;\n}\n.navbar-default .navbar-nav > li > a:hover,\n.navbar-default .navbar-nav > li > a:focus {\n  color: #333;\n  background-color: transparent;\n}\n.navbar-default .navbar-nav > .active > a,\n.navbar-default .navbar-nav > .active > a:hover,\n.navbar-default .navbar-nav > .active > a:focus {\n  color: #555;\n  background-color: #e7e7e7;\n}\n.navbar-default .navbar-nav > .disabled > a,\n.navbar-default .navbar-nav > .disabled > a:hover,\n.navbar-default .navbar-nav > .disabled > a:focus {\n  color: #ccc;\n  background-color: transparent;\n}\n.navbar-default .navbar-toggle {\n  border-color: #ddd;\n}\n.navbar-default .navbar-toggle:hover,\n.navbar-default .navbar-toggle:focus {\n  background-color: #ddd;\n}\n.navbar-default .navbar-toggle .icon-bar {\n  background-color: #888;\n}\n.navbar-default .navbar-collapse,\n.navbar-default .navbar-form {\n  border-color: #e7e7e7;\n}\n.navbar-default .navbar-nav > .open > a,\n.navbar-default .navbar-nav > .open > a:hover,\n.navbar-default .navbar-nav > .open > a:focus {\n  color: #555;\n  background-color: #e7e7e7;\n}\n@media (max-width: 767px) {\n  .navbar-default .navbar-nav .open .dropdown-menu > li > a {\n    color: #777;\n  }\n  .navbar-default .navbar-nav .open .dropdown-menu > li > a:hover,\n  .navbar-default .navbar-nav .open .dropdown-menu > li > a:focus {\n    color: #333;\n    background-color: transparent;\n  }\n  .navbar-default .navbar-nav .open .dropdown-menu > .active > a,\n  .navbar-default .navbar-nav .open .dropdown-menu > .active > a:hover,\n  .navbar-default .navbar-nav .open .dropdown-menu > .active > a:focus {\n    color: #555;\n    background-color: #e7e7e7;\n  }\n  .navbar-default .navbar-nav .open .dropdown-menu > .disabled > a,\n  .navbar-default .navbar-nav .open .dropdown-menu > .disabled > a:hover,\n  .navbar-default .navbar-nav .open .dropdown-menu > .disabled > a:focus {\n    color: #ccc;\n    background-color: transparent;\n  }\n}\n.navbar-default .navbar-link {\n  color: #777;\n}\n.navbar-default .navbar-link:hover {\n  color: #333;\n}\n.navbar-default .btn-link {\n  color: #777;\n}\n.navbar-default .btn-link:hover,\n.navbar-default .btn-link:focus {\n  color: #333;\n}\n.navbar-default .btn-link[disabled]:hover,\nfieldset[disabled] .navbar-default .btn-link:hover,\n.navbar-default .btn-link[disabled]:focus,\nfieldset[disabled] .navbar-default .btn-link:focus {\n  color: #ccc;\n}\n.navbar-inverse {\n  background-color: #222;\n  border-color: #080808;\n}\n.navbar-inverse .navbar-brand {\n  color: #9d9d9d;\n}\n.navbar-inverse .navbar-brand:hover,\n.navbar-inverse .navbar-brand:focus {\n  color: #fff;\n  background-color: transparent;\n}\n.navbar-inverse .navbar-text {\n  color: #9d9d9d;\n}\n.navbar-inverse .navbar-nav > li > a {\n  color: #9d9d9d;\n}\n.navbar-inverse .navbar-nav > li > a:hover,\n.navbar-inverse .navbar-nav > li > a:focus {\n  color: #fff;\n  background-color: transparent;\n}\n.navbar-inverse .navbar-nav > .active > a,\n.navbar-inverse .navbar-nav > .active > a:hover,\n.navbar-inverse .navbar-nav > .active > a:focus {\n  color: #fff;\n  background-color: #080808;\n}\n.navbar-inverse .navbar-nav > .disabled > a,\n.navbar-inverse .navbar-nav > .disabled > a:hover,\n.navbar-inverse .navbar-nav > .disabled > a:focus {\n  color: #444;\n  background-color: transparent;\n}\n.navbar-inverse .navbar-toggle {\n  border-color: #333;\n}\n.navbar-inverse .navbar-toggle:hover,\n.navbar-inverse .navbar-toggle:focus {\n  background-color: #333;\n}\n.navbar-inverse .navbar-toggle .icon-bar {\n  background-color: #fff;\n}\n.navbar-inverse .navbar-collapse,\n.navbar-inverse .navbar-form {\n  border-color: #101010;\n}\n.navbar-inverse .navbar-nav > .open > a,\n.navbar-inverse .navbar-nav > .open > a:hover,\n.navbar-inverse .navbar-nav > .open > a:focus {\n  color: #fff;\n  background-color: #080808;\n}\n@media (max-width: 767px) {\n  .navbar-inverse .navbar-nav .open .dropdown-menu > .dropdown-header {\n    border-color: #080808;\n  }\n  .navbar-inverse .navbar-nav .open .dropdown-menu .divider {\n    background-color: #080808;\n  }\n  .navbar-inverse .navbar-nav .open .dropdown-menu > li > a {\n    color: #9d9d9d;\n  }\n  .navbar-inverse .navbar-nav .open .dropdown-menu > li > a:hover,\n  .navbar-inverse .navbar-nav .open .dropdown-menu > li > a:focus {\n    color: #fff;\n    background-color: transparent;\n  }\n  .navbar-inverse .navbar-nav .open .dropdown-menu > .active > a,\n  .navbar-inverse .navbar-nav .open .dropdown-menu > .active > a:hover,\n  .navbar-inverse .navbar-nav .open .dropdown-menu > .active > a:focus {\n    color: #fff;\n    background-color: #080808;\n  }\n  .navbar-inverse .navbar-nav .open .dropdown-menu > .disabled > a,\n  .navbar-inverse .navbar-nav .open .dropdown-menu > .disabled > a:hover,\n  .navbar-inverse .navbar-nav .open .dropdown-menu > .disabled > a:focus {\n    color: #444;\n    background-color: transparent;\n  }\n}\n.navbar-inverse .navbar-link {\n  color: #9d9d9d;\n}\n.navbar-inverse .navbar-link:hover {\n  color: #fff;\n}\n.navbar-inverse .btn-link {\n  color: #9d9d9d;\n}\n.navbar-inverse .btn-link:hover,\n.navbar-inverse .btn-link:focus {\n  color: #fff;\n}\n.navbar-inverse .btn-link[disabled]:hover,\nfieldset[disabled] .navbar-inverse .btn-link:hover,\n.navbar-inverse .btn-link[disabled]:focus,\nfieldset[disabled] .navbar-inverse .btn-link:focus {\n  color: #444;\n}\n.breadcrumb {\n  padding: 8px 15px;\n  margin-bottom: 20px;\n  list-style: none;\n  background-color: #f5f5f5;\n  border-radius: 4px;\n}\n.breadcrumb > li {\n  display: inline-block;\n}\n.breadcrumb > li + li:before {\n  padding: 0 5px;\n  color: #ccc;\n  content: \"/\\00a0\";\n}\n.breadcrumb > .active {\n  color: #777;\n}\n.pagination {\n  display: inline-block;\n  padding-left: 0;\n  margin: 20px 0;\n  border-radius: 4px;\n}\n.pagination > li {\n  display: inline;\n}\n.pagination > li > a,\n.pagination > li > span {\n  position: relative;\n  float: left;\n  padding: 6px 12px;\n  margin-left: -1px;\n  line-height: 1.42857143;\n  color: #337ab7;\n  text-decoration: none;\n  background-color: #fff;\n  border: 1px solid #ddd;\n}\n.pagination > li:first-child > a,\n.pagination > li:first-child > span {\n  margin-left: 0;\n  border-top-left-radius: 4px;\n  border-bottom-left-radius: 4px;\n}\n.pagination > li:last-child > a,\n.pagination > li:last-child > span {\n  border-top-right-radius: 4px;\n  border-bottom-right-radius: 4px;\n}\n.pagination > li > a:hover,\n.pagination > li > span:hover,\n.pagination > li > a:focus,\n.pagination > li > span:focus {\n  z-index: 3;\n  color: #23527c;\n  background-color: #eee;\n  border-color: #ddd;\n}\n.pagination > .active > a,\n.pagination > .active > span,\n.pagination > .active > a:hover,\n.pagination > .active > span:hover,\n.pagination > .active > a:focus,\n.pagination > .active > span:focus {\n  z-index: 2;\n  color: #fff;\n  cursor: default;\n  background-color: #337ab7;\n  border-color: #337ab7;\n}\n.pagination > .disabled > span,\n.pagination > .disabled > span:hover,\n.pagination > .disabled > span:focus,\n.pagination > .disabled > a,\n.pagination > .disabled > a:hover,\n.pagination > .disabled > a:focus {\n  color: #777;\n  cursor: not-allowed;\n  background-color: #fff;\n  border-color: #ddd;\n}\n.pagination-lg > li > a,\n.pagination-lg > li > span {\n  padding: 10px 16px;\n  font-size: 18px;\n  line-height: 1.3333333;\n}\n.pagination-lg > li:first-child > a,\n.pagination-lg > li:first-child > span {\n  border-top-left-radius: 6px;\n  border-bottom-left-radius: 6px;\n}\n.pagination-lg > li:last-child > a,\n.pagination-lg > li:last-child > span {\n  border-top-right-radius: 6px;\n  border-bottom-right-radius: 6px;\n}\n.pagination-sm > li > a,\n.pagination-sm > li > span {\n  padding: 5px 10px;\n  font-size: 12px;\n  line-height: 1.5;\n}\n.pagination-sm > li:first-child > a,\n.pagination-sm > li:first-child > span {\n  border-top-left-radius: 3px;\n  border-bottom-left-radius: 3px;\n}\n.pagination-sm > li:last-child > a,\n.pagination-sm > li:last-child > span {\n  border-top-right-radius: 3px;\n  border-bottom-right-radius: 3px;\n}\n.pager {\n  padding-left: 0;\n  margin: 20px 0;\n  text-align: center;\n  list-style: none;\n}\n.pager li {\n  display: inline;\n}\n.pager li > a,\n.pager li > span {\n  display: inline-block;\n  padding: 5px 14px;\n  background-color: #fff;\n  border: 1px solid #ddd;\n  border-radius: 15px;\n}\n.pager li > a:hover,\n.pager li > a:focus {\n  text-decoration: none;\n  background-color: #eee;\n}\n.pager .next > a,\n.pager .next > span {\n  float: right;\n}\n.pager .previous > a,\n.pager .previous > span {\n  float: left;\n}\n.pager .disabled > a,\n.pager .disabled > a:hover,\n.pager .disabled > a:focus,\n.pager .disabled > span {\n  color: #777;\n  cursor: not-allowed;\n  background-color: #fff;\n}\n.label {\n  display: inline;\n  padding: .2em .6em .3em;\n  font-size: 75%;\n  font-weight: bold;\n  line-height: 1;\n  color: #fff;\n  text-align: center;\n  white-space: nowrap;\n  vertical-align: baseline;\n  border-radius: .25em;\n}\na.label:hover,\na.label:focus {\n  color: #fff;\n  text-decoration: none;\n  cursor: pointer;\n}\n.label:empty {\n  display: none;\n}\n.btn .label {\n  position: relative;\n  top: -1px;\n}\n.label-default {\n  background-color: #777;\n}\n.label-default[href]:hover,\n.label-default[href]:focus {\n  background-color: #5e5e5e;\n}\n.label-primary {\n  background-color: #337ab7;\n}\n.label-primary[href]:hover,\n.label-primary[href]:focus {\n  background-color: #286090;\n}\n.label-success {\n  background-color: #5cb85c;\n}\n.label-success[href]:hover,\n.label-success[href]:focus {\n  background-color: #449d44;\n}\n.label-info {\n  background-color: #5bc0de;\n}\n.label-info[href]:hover,\n.label-info[href]:focus {\n  background-color: #31b0d5;\n}\n.label-warning {\n  background-color: #f0ad4e;\n}\n.label-warning[href]:hover,\n.label-warning[href]:focus {\n  background-color: #ec971f;\n}\n.label-danger {\n  background-color: #d9534f;\n}\n.label-danger[href]:hover,\n.label-danger[href]:focus {\n  background-color: #c9302c;\n}\n.badge {\n  display: inline-block;\n  min-width: 10px;\n  padding: 3px 7px;\n  font-size: 12px;\n  font-weight: bold;\n  line-height: 1;\n  color: #fff;\n  text-align: center;\n  white-space: nowrap;\n  vertical-align: middle;\n  background-color: #777;\n  border-radius: 10px;\n}\n.badge:empty {\n  display: none;\n}\n.btn .badge {\n  position: relative;\n  top: -1px;\n}\n.btn-xs .badge,\n.btn-group-xs > .btn .badge {\n  top: 0;\n  padding: 1px 5px;\n}\na.badge:hover,\na.badge:focus {\n  color: #fff;\n  text-decoration: none;\n  cursor: pointer;\n}\n.list-group-item.active > .badge,\n.nav-pills > .active > a > .badge {\n  color: #337ab7;\n  background-color: #fff;\n}\n.list-group-item > .badge {\n  float: right;\n}\n.list-group-item > .badge + .badge {\n  margin-right: 5px;\n}\n.nav-pills > li > a > .badge {\n  margin-left: 3px;\n}\n.jumbotron {\n  padding-top: 30px;\n  padding-bottom: 30px;\n  margin-bottom: 30px;\n  color: inherit;\n  background-color: #eee;\n}\n.jumbotron h1,\n.jumbotron .h1 {\n  color: inherit;\n}\n.jumbotron p {\n  margin-bottom: 15px;\n  font-size: 21px;\n  font-weight: 200;\n}\n.jumbotron > hr {\n  border-top-color: #d5d5d5;\n}\n.container .jumbotron,\n.container-fluid .jumbotron {\n  border-radius: 6px;\n}\n.jumbotron .container {\n  max-width: 100%;\n}\n@media screen and (min-width: 768px) {\n  .jumbotron {\n    padding-top: 48px;\n    padding-bottom: 48px;\n  }\n  .container .jumbotron,\n  .container-fluid .jumbotron {\n    padding-right: 60px;\n    padding-left: 60px;\n  }\n  .jumbotron h1,\n  .jumbotron .h1 {\n    font-size: 63px;\n  }\n}\n.thumbnail {\n  display: block;\n  padding: 4px;\n  margin-bottom: 20px;\n  line-height: 1.42857143;\n  background-color: #fff;\n  border: 1px solid #ddd;\n  border-radius: 4px;\n  -webkit-transition: border .2s ease-in-out;\n       -o-transition: border .2s ease-in-out;\n          transition: border .2s ease-in-out;\n}\n.thumbnail > img,\n.thumbnail a > img {\n  margin-right: auto;\n  margin-left: auto;\n}\na.thumbnail:hover,\na.thumbnail:focus,\na.thumbnail.active {\n  border-color: #337ab7;\n}\n.thumbnail .caption {\n  padding: 9px;\n  color: #333;\n}\n.alert {\n  padding: 15px;\n  margin-bottom: 20px;\n  border: 1px solid transparent;\n  border-radius: 4px;\n}\n.alert h4 {\n  margin-top: 0;\n  color: inherit;\n}\n.alert .alert-link {\n  font-weight: bold;\n}\n.alert > p,\n.alert > ul {\n  margin-bottom: 0;\n}\n.alert > p + p {\n  margin-top: 5px;\n}\n.alert-dismissable,\n.alert-dismissible {\n  padding-right: 35px;\n}\n.alert-dismissable .close,\n.alert-dismissible .close {\n  position: relative;\n  top: -2px;\n  right: -21px;\n  color: inherit;\n}\n.alert-success {\n  color: #3c763d;\n  background-color: #dff0d8;\n  border-color: #d6e9c6;\n}\n.alert-success hr {\n  border-top-color: #c9e2b3;\n}\n.alert-success .alert-link {\n  color: #2b542c;\n}\n.alert-info {\n  color: #31708f;\n  background-color: #d9edf7;\n  border-color: #bce8f1;\n}\n.alert-info hr {\n  border-top-color: #a6e1ec;\n}\n.alert-info .alert-link {\n  color: #245269;\n}\n.alert-warning {\n  color: #8a6d3b;\n  background-color: #fcf8e3;\n  border-color: #faebcc;\n}\n.alert-warning hr {\n  border-top-color: #f7e1b5;\n}\n.alert-warning .alert-link {\n  color: #66512c;\n}\n.alert-danger {\n  color: #a94442;\n  background-color: #f2dede;\n  border-color: #ebccd1;\n}\n.alert-danger hr {\n  border-top-color: #e4b9c0;\n}\n.alert-danger .alert-link {\n  color: #843534;\n}\n@-webkit-keyframes progress-bar-stripes {\n  from {\n    background-position: 40px 0;\n  }\n  to {\n    background-position: 0 0;\n  }\n}\n@-o-keyframes progress-bar-stripes {\n  from {\n    background-position: 40px 0;\n  }\n  to {\n    background-position: 0 0;\n  }\n}\n@keyframes progress-bar-stripes {\n  from {\n    background-position: 40px 0;\n  }\n  to {\n    background-position: 0 0;\n  }\n}\n.progress {\n  height: 20px;\n  margin-bottom: 20px;\n  overflow: hidden;\n  background-color: #f5f5f5;\n  border-radius: 4px;\n  -webkit-box-shadow: inset 0 1px 2px rgba(0, 0, 0, .1);\n          box-shadow: inset 0 1px 2px rgba(0, 0, 0, .1);\n}\n.progress-bar {\n  float: left;\n  width: 0;\n  height: 100%;\n  font-size: 12px;\n  line-height: 20px;\n  color: #fff;\n  text-align: center;\n  background-color: #337ab7;\n  -webkit-box-shadow: inset 0 -1px 0 rgba(0, 0, 0, .15);\n          box-shadow: inset 0 -1px 0 rgba(0, 0, 0, .15);\n  -webkit-transition: width .6s ease;\n       -o-transition: width .6s ease;\n          transition: width .6s ease;\n}\n.progress-striped .progress-bar,\n.progress-bar-striped {\n  background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);\n  background-image:      -o-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);\n  background-image:         linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);\n  -webkit-background-size: 40px 40px;\n          background-size: 40px 40px;\n}\n.progress.active .progress-bar,\n.progress-bar.active {\n  -webkit-animation: progress-bar-stripes 2s linear infinite;\n       -o-animation: progress-bar-stripes 2s linear infinite;\n          animation: progress-bar-stripes 2s linear infinite;\n}\n.progress-bar-success {\n  background-color: #5cb85c;\n}\n.progress-striped .progress-bar-success {\n  background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);\n  background-image:      -o-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);\n  background-image:         linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);\n}\n.progress-bar-info {\n  background-color: #5bc0de;\n}\n.progress-striped .progress-bar-info {\n  background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);\n  background-image:      -o-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);\n  background-image:         linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);\n}\n.progress-bar-warning {\n  background-color: #f0ad4e;\n}\n.progress-striped .progress-bar-warning {\n  background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);\n  background-image:      -o-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);\n  background-image:         linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);\n}\n.progress-bar-danger {\n  background-color: #d9534f;\n}\n.progress-striped .progress-bar-danger {\n  background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);\n  background-image:      -o-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);\n  background-image:         linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);\n}\n.media {\n  margin-top: 15px;\n}\n.media:first-child {\n  margin-top: 0;\n}\n.media,\n.media-body {\n  overflow: hidden;\n  zoom: 1;\n}\n.media-body {\n  width: 10000px;\n}\n.media-object {\n  display: block;\n}\n.media-object.img-thumbnail {\n  max-width: none;\n}\n.media-right,\n.media > .pull-right {\n  padding-left: 10px;\n}\n.media-left,\n.media > .pull-left {\n  padding-right: 10px;\n}\n.media-left,\n.media-right,\n.media-body {\n  display: table-cell;\n  vertical-align: top;\n}\n.media-middle {\n  vertical-align: middle;\n}\n.media-bottom {\n  vertical-align: bottom;\n}\n.media-heading {\n  margin-top: 0;\n  margin-bottom: 5px;\n}\n.media-list {\n  padding-left: 0;\n  list-style: none;\n}\n.list-group {\n  padding-left: 0;\n  margin-bottom: 20px;\n}\n.list-group-item {\n  position: relative;\n  display: block;\n  padding: 10px 15px;\n  margin-bottom: -1px;\n  background-color: #fff;\n  border: 1px solid #ddd;\n}\n.list-group-item:first-child {\n  border-top-left-radius: 4px;\n  border-top-right-radius: 4px;\n}\n.list-group-item:last-child {\n  margin-bottom: 0;\n  border-bottom-right-radius: 4px;\n  border-bottom-left-radius: 4px;\n}\na.list-group-item,\nbutton.list-group-item {\n  color: #555;\n}\na.list-group-item .list-group-item-heading,\nbutton.list-group-item .list-group-item-heading {\n  color: #333;\n}\na.list-group-item:hover,\nbutton.list-group-item:hover,\na.list-group-item:focus,\nbutton.list-group-item:focus {\n  color: #555;\n  text-decoration: none;\n  background-color: #f5f5f5;\n}\nbutton.list-group-item {\n  width: 100%;\n  text-align: left;\n}\n.list-group-item.disabled,\n.list-group-item.disabled:hover,\n.list-group-item.disabled:focus {\n  color: #777;\n  cursor: not-allowed;\n  background-color: #eee;\n}\n.list-group-item.disabled .list-group-item-heading,\n.list-group-item.disabled:hover .list-group-item-heading,\n.list-group-item.disabled:focus .list-group-item-heading {\n  color: inherit;\n}\n.list-group-item.disabled .list-group-item-text,\n.list-group-item.disabled:hover .list-group-item-text,\n.list-group-item.disabled:focus .list-group-item-text {\n  color: #777;\n}\n.list-group-item.active,\n.list-group-item.active:hover,\n.list-group-item.active:focus {\n  z-index: 2;\n  color: #fff;\n  background-color: #337ab7;\n  border-color: #337ab7;\n}\n.list-group-item.active .list-group-item-heading,\n.list-group-item.active:hover .list-group-item-heading,\n.list-group-item.active:focus .list-group-item-heading,\n.list-group-item.active .list-group-item-heading > small,\n.list-group-item.active:hover .list-group-item-heading > small,\n.list-group-item.active:focus .list-group-item-heading > small,\n.list-group-item.active .list-group-item-heading > .small,\n.list-group-item.active:hover .list-group-item-heading > .small,\n.list-group-item.active:focus .list-group-item-heading > .small {\n  color: inherit;\n}\n.list-group-item.active .list-group-item-text,\n.list-group-item.active:hover .list-group-item-text,\n.list-group-item.active:focus .list-group-item-text {\n  color: #c7ddef;\n}\n.list-group-item-success {\n  color: #3c763d;\n  background-color: #dff0d8;\n}\na.list-group-item-success,\nbutton.list-group-item-success {\n  color: #3c763d;\n}\na.list-group-item-success .list-group-item-heading,\nbutton.list-group-item-success .list-group-item-heading {\n  color: inherit;\n}\na.list-group-item-success:hover,\nbutton.list-group-item-success:hover,\na.list-group-item-success:focus,\nbutton.list-group-item-success:focus {\n  color: #3c763d;\n  background-color: #d0e9c6;\n}\na.list-group-item-success.active,\nbutton.list-group-item-success.active,\na.list-group-item-success.active:hover,\nbutton.list-group-item-success.active:hover,\na.list-group-item-success.active:focus,\nbutton.list-group-item-success.active:focus {\n  color: #fff;\n  background-color: #3c763d;\n  border-color: #3c763d;\n}\n.list-group-item-info {\n  color: #31708f;\n  background-color: #d9edf7;\n}\na.list-group-item-info,\nbutton.list-group-item-info {\n  color: #31708f;\n}\na.list-group-item-info .list-group-item-heading,\nbutton.list-group-item-info .list-group-item-heading {\n  color: inherit;\n}\na.list-group-item-info:hover,\nbutton.list-group-item-info:hover,\na.list-group-item-info:focus,\nbutton.list-group-item-info:focus {\n  color: #31708f;\n  background-color: #c4e3f3;\n}\na.list-group-item-info.active,\nbutton.list-group-item-info.active,\na.list-group-item-info.active:hover,\nbutton.list-group-item-info.active:hover,\na.list-group-item-info.active:focus,\nbutton.list-group-item-info.active:focus {\n  color: #fff;\n  background-color: #31708f;\n  border-color: #31708f;\n}\n.list-group-item-warning {\n  color: #8a6d3b;\n  background-color: #fcf8e3;\n}\na.list-group-item-warning,\nbutton.list-group-item-warning {\n  color: #8a6d3b;\n}\na.list-group-item-warning .list-group-item-heading,\nbutton.list-group-item-warning .list-group-item-heading {\n  color: inherit;\n}\na.list-group-item-warning:hover,\nbutton.list-group-item-warning:hover,\na.list-group-item-warning:focus,\nbutton.list-group-item-warning:focus {\n  color: #8a6d3b;\n  background-color: #faf2cc;\n}\na.list-group-item-warning.active,\nbutton.list-group-item-warning.active,\na.list-group-item-warning.active:hover,\nbutton.list-group-item-warning.active:hover,\na.list-group-item-warning.active:focus,\nbutton.list-group-item-warning.active:focus {\n  color: #fff;\n  background-color: #8a6d3b;\n  border-color: #8a6d3b;\n}\n.list-group-item-danger {\n  color: #a94442;\n  background-color: #f2dede;\n}\na.list-group-item-danger,\nbutton.list-group-item-danger {\n  color: #a94442;\n}\na.list-group-item-danger .list-group-item-heading,\nbutton.list-group-item-danger .list-group-item-heading {\n  color: inherit;\n}\na.list-group-item-danger:hover,\nbutton.list-group-item-danger:hover,\na.list-group-item-danger:focus,\nbutton.list-group-item-danger:focus {\n  color: #a94442;\n  background-color: #ebcccc;\n}\na.list-group-item-danger.active,\nbutton.list-group-item-danger.active,\na.list-group-item-danger.active:hover,\nbutton.list-group-item-danger.active:hover,\na.list-group-item-danger.active:focus,\nbutton.list-group-item-danger.active:focus {\n  color: #fff;\n  background-color: #a94442;\n  border-color: #a94442;\n}\n.list-group-item-heading {\n  margin-top: 0;\n  margin-bottom: 5px;\n}\n.list-group-item-text {\n  margin-bottom: 0;\n  line-height: 1.3;\n}\n.panel {\n  margin-bottom: 20px;\n  background-color: #fff;\n  border: 1px solid transparent;\n  border-radius: 4px;\n  -webkit-box-shadow: 0 1px 1px rgba(0, 0, 0, .05);\n          box-shadow: 0 1px 1px rgba(0, 0, 0, .05);\n}\n.panel-body {\n  padding: 15px;\n}\n.panel-heading {\n  padding: 10px 15px;\n  border-bottom: 1px solid transparent;\n  border-top-left-radius: 3px;\n  border-top-right-radius: 3px;\n}\n.panel-heading > .dropdown .dropdown-toggle {\n  color: inherit;\n}\n.panel-title {\n  margin-top: 0;\n  margin-bottom: 0;\n  font-size: 16px;\n  color: inherit;\n}\n.panel-title > a,\n.panel-title > small,\n.panel-title > .small,\n.panel-title > small > a,\n.panel-title > .small > a {\n  color: inherit;\n}\n.panel-footer {\n  padding: 10px 15px;\n  background-color: #f5f5f5;\n  border-top: 1px solid #ddd;\n  border-bottom-right-radius: 3px;\n  border-bottom-left-radius: 3px;\n}\n.panel > .list-group,\n.panel > .panel-collapse > .list-group {\n  margin-bottom: 0;\n}\n.panel > .list-group .list-group-item,\n.panel > .panel-collapse > .list-group .list-group-item {\n  border-width: 1px 0;\n  border-radius: 0;\n}\n.panel > .list-group:first-child .list-group-item:first-child,\n.panel > .panel-collapse > .list-group:first-child .list-group-item:first-child {\n  border-top: 0;\n  border-top-left-radius: 3px;\n  border-top-right-radius: 3px;\n}\n.panel > .list-group:last-child .list-group-item:last-child,\n.panel > .panel-collapse > .list-group:last-child .list-group-item:last-child {\n  border-bottom: 0;\n  border-bottom-right-radius: 3px;\n  border-bottom-left-radius: 3px;\n}\n.panel > .panel-heading + .panel-collapse > .list-group .list-group-item:first-child {\n  border-top-left-radius: 0;\n  border-top-right-radius: 0;\n}\n.panel-heading + .list-group .list-group-item:first-child {\n  border-top-width: 0;\n}\n.list-group + .panel-footer {\n  border-top-width: 0;\n}\n.panel > .table,\n.panel > .table-responsive > .table,\n.panel > .panel-collapse > .table {\n  margin-bottom: 0;\n}\n.panel > .table caption,\n.panel > .table-responsive > .table caption,\n.panel > .panel-collapse > .table caption {\n  padding-right: 15px;\n  padding-left: 15px;\n}\n.panel > .table:first-child,\n.panel > .table-responsive:first-child > .table:first-child {\n  border-top-left-radius: 3px;\n  border-top-right-radius: 3px;\n}\n.panel > .table:first-child > thead:first-child > tr:first-child,\n.panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child,\n.panel > .table:first-child > tbody:first-child > tr:first-child,\n.panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child {\n  border-top-left-radius: 3px;\n  border-top-right-radius: 3px;\n}\n.panel > .table:first-child > thead:first-child > tr:first-child td:first-child,\n.panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child td:first-child,\n.panel > .table:first-child > tbody:first-child > tr:first-child td:first-child,\n.panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child td:first-child,\n.panel > .table:first-child > thead:first-child > tr:first-child th:first-child,\n.panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child th:first-child,\n.panel > .table:first-child > tbody:first-child > tr:first-child th:first-child,\n.panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child th:first-child {\n  border-top-left-radius: 3px;\n}\n.panel > .table:first-child > thead:first-child > tr:first-child td:last-child,\n.panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child td:last-child,\n.panel > .table:first-child > tbody:first-child > tr:first-child td:last-child,\n.panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child td:last-child,\n.panel > .table:first-child > thead:first-child > tr:first-child th:last-child,\n.panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child th:last-child,\n.panel > .table:first-child > tbody:first-child > tr:first-child th:last-child,\n.panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child th:last-child {\n  border-top-right-radius: 3px;\n}\n.panel > .table:last-child,\n.panel > .table-responsive:last-child > .table:last-child {\n  border-bottom-right-radius: 3px;\n  border-bottom-left-radius: 3px;\n}\n.panel > .table:last-child > tbody:last-child > tr:last-child,\n.panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child,\n.panel > .table:last-child > tfoot:last-child > tr:last-child,\n.panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child {\n  border-bottom-right-radius: 3px;\n  border-bottom-left-radius: 3px;\n}\n.panel > .table:last-child > tbody:last-child > tr:last-child td:first-child,\n.panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child td:first-child,\n.panel > .table:last-child > tfoot:last-child > tr:last-child td:first-child,\n.panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child td:first-child,\n.panel > .table:last-child > tbody:last-child > tr:last-child th:first-child,\n.panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child th:first-child,\n.panel > .table:last-child > tfoot:last-child > tr:last-child th:first-child,\n.panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child th:first-child {\n  border-bottom-left-radius: 3px;\n}\n.panel > .table:last-child > tbody:last-child > tr:last-child td:last-child,\n.panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child td:last-child,\n.panel > .table:last-child > tfoot:last-child > tr:last-child td:last-child,\n.panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child td:last-child,\n.panel > .table:last-child > tbody:last-child > tr:last-child th:last-child,\n.panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child th:last-child,\n.panel > .table:last-child > tfoot:last-child > tr:last-child th:last-child,\n.panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child th:last-child {\n  border-bottom-right-radius: 3px;\n}\n.panel > .panel-body + .table,\n.panel > .panel-body + .table-responsive,\n.panel > .table + .panel-body,\n.panel > .table-responsive + .panel-body {\n  border-top: 1px solid #ddd;\n}\n.panel > .table > tbody:first-child > tr:first-child th,\n.panel > .table > tbody:first-child > tr:first-child td {\n  border-top: 0;\n}\n.panel > .table-bordered,\n.panel > .table-responsive > .table-bordered {\n  border: 0;\n}\n.panel > .table-bordered > thead > tr > th:first-child,\n.panel > .table-responsive > .table-bordered > thead > tr > th:first-child,\n.panel > .table-bordered > tbody > tr > th:first-child,\n.panel > .table-responsive > .table-bordered > tbody > tr > th:first-child,\n.panel > .table-bordered > tfoot > tr > th:first-child,\n.panel > .table-responsive > .table-bordered > tfoot > tr > th:first-child,\n.panel > .table-bordered > thead > tr > td:first-child,\n.panel > .table-responsive > .table-bordered > thead > tr > td:first-child,\n.panel > .table-bordered > tbody > tr > td:first-child,\n.panel > .table-responsive > .table-bordered > tbody > tr > td:first-child,\n.panel > .table-bordered > tfoot > tr > td:first-child,\n.panel > .table-responsive > .table-bordered > tfoot > tr > td:first-child {\n  border-left: 0;\n}\n.panel > .table-bordered > thead > tr > th:last-child,\n.panel > .table-responsive > .table-bordered > thead > tr > th:last-child,\n.panel > .table-bordered > tbody > tr > th:last-child,\n.panel > .table-responsive > .table-bordered > tbody > tr > th:last-child,\n.panel > .table-bordered > tfoot > tr > th:last-child,\n.panel > .table-responsive > .table-bordered > tfoot > tr > th:last-child,\n.panel > .table-bordered > thead > tr > td:last-child,\n.panel > .table-responsive > .table-bordered > thead > tr > td:last-child,\n.panel > .table-bordered > tbody > tr > td:last-child,\n.panel > .table-responsive > .table-bordered > tbody > tr > td:last-child,\n.panel > .table-bordered > tfoot > tr > td:last-child,\n.panel > .table-responsive > .table-bordered > tfoot > tr > td:last-child {\n  border-right: 0;\n}\n.panel > .table-bordered > thead > tr:first-child > td,\n.panel > .table-responsive > .table-bordered > thead > tr:first-child > td,\n.panel > .table-bordered > tbody > tr:first-child > td,\n.panel > .table-responsive > .table-bordered > tbody > tr:first-child > td,\n.panel > .table-bordered > thead > tr:first-child > th,\n.panel > .table-responsive > .table-bordered > thead > tr:first-child > th,\n.panel > .table-bordered > tbody > tr:first-child > th,\n.panel > .table-responsive > .table-bordered > tbody > tr:first-child > th {\n  border-bottom: 0;\n}\n.panel > .table-bordered > tbody > tr:last-child > td,\n.panel > .table-responsive > .table-bordered > tbody > tr:last-child > td,\n.panel > .table-bordered > tfoot > tr:last-child > td,\n.panel > .table-responsive > .table-bordered > tfoot > tr:last-child > td,\n.panel > .table-bordered > tbody > tr:last-child > th,\n.panel > .table-responsive > .table-bordered > tbody > tr:last-child > th,\n.panel > .table-bordered > tfoot > tr:last-child > th,\n.panel > .table-responsive > .table-bordered > tfoot > tr:last-child > th {\n  border-bottom: 0;\n}\n.panel > .table-responsive {\n  margin-bottom: 0;\n  border: 0;\n}\n.panel-group {\n  margin-bottom: 20px;\n}\n.panel-group .panel {\n  margin-bottom: 0;\n  border-radius: 4px;\n}\n.panel-group .panel + .panel {\n  margin-top: 5px;\n}\n.panel-group .panel-heading {\n  border-bottom: 0;\n}\n.panel-group .panel-heading + .panel-collapse > .panel-body,\n.panel-group .panel-heading + .panel-collapse > .list-group {\n  border-top: 1px solid #ddd;\n}\n.panel-group .panel-footer {\n  border-top: 0;\n}\n.panel-group .panel-footer + .panel-collapse .panel-body {\n  border-bottom: 1px solid #ddd;\n}\n.panel-default {\n  border-color: #ddd;\n}\n.panel-default > .panel-heading {\n  color: #333;\n  background-color: #f5f5f5;\n  border-color: #ddd;\n}\n.panel-default > .panel-heading + .panel-collapse > .panel-body {\n  border-top-color: #ddd;\n}\n.panel-default > .panel-heading .badge {\n  color: #f5f5f5;\n  background-color: #333;\n}\n.panel-default > .panel-footer + .panel-collapse > .panel-body {\n  border-bottom-color: #ddd;\n}\n.panel-primary {\n  border-color: #337ab7;\n}\n.panel-primary > .panel-heading {\n  color: #fff;\n  background-color: #337ab7;\n  border-color: #337ab7;\n}\n.panel-primary > .panel-heading + .panel-collapse > .panel-body {\n  border-top-color: #337ab7;\n}\n.panel-primary > .panel-heading .badge {\n  color: #337ab7;\n  background-color: #fff;\n}\n.panel-primary > .panel-footer + .panel-collapse > .panel-body {\n  border-bottom-color: #337ab7;\n}\n.panel-success {\n  border-color: #d6e9c6;\n}\n.panel-success > .panel-heading {\n  color: #3c763d;\n  background-color: #dff0d8;\n  border-color: #d6e9c6;\n}\n.panel-success > .panel-heading + .panel-collapse > .panel-body {\n  border-top-color: #d6e9c6;\n}\n.panel-success > .panel-heading .badge {\n  color: #dff0d8;\n  background-color: #3c763d;\n}\n.panel-success > .panel-footer + .panel-collapse > .panel-body {\n  border-bottom-color: #d6e9c6;\n}\n.panel-info {\n  border-color: #bce8f1;\n}\n.panel-info > .panel-heading {\n  color: #31708f;\n  background-color: #d9edf7;\n  border-color: #bce8f1;\n}\n.panel-info > .panel-heading + .panel-collapse > .panel-body {\n  border-top-color: #bce8f1;\n}\n.panel-info > .panel-heading .badge {\n  color: #d9edf7;\n  background-color: #31708f;\n}\n.panel-info > .panel-footer + .panel-collapse > .panel-body {\n  border-bottom-color: #bce8f1;\n}\n.panel-warning {\n  border-color: #faebcc;\n}\n.panel-warning > .panel-heading {\n  color: #8a6d3b;\n  background-color: #fcf8e3;\n  border-color: #faebcc;\n}\n.panel-warning > .panel-heading + .panel-collapse > .panel-body {\n  border-top-color: #faebcc;\n}\n.panel-warning > .panel-heading .badge {\n  color: #fcf8e3;\n  background-color: #8a6d3b;\n}\n.panel-warning > .panel-footer + .panel-collapse > .panel-body {\n  border-bottom-color: #faebcc;\n}\n.panel-danger {\n  border-color: #ebccd1;\n}\n.panel-danger > .panel-heading {\n  color: #a94442;\n  background-color: #f2dede;\n  border-color: #ebccd1;\n}\n.panel-danger > .panel-heading + .panel-collapse > .panel-body {\n  border-top-color: #ebccd1;\n}\n.panel-danger > .panel-heading .badge {\n  color: #f2dede;\n  background-color: #a94442;\n}\n.panel-danger > .panel-footer + .panel-collapse > .panel-body {\n  border-bottom-color: #ebccd1;\n}\n.embed-responsive {\n  position: relative;\n  display: block;\n  height: 0;\n  padding: 0;\n  overflow: hidden;\n}\n.embed-responsive .embed-responsive-item,\n.embed-responsive iframe,\n.embed-responsive embed,\n.embed-responsive object,\n.embed-responsive video {\n  position: absolute;\n  top: 0;\n  bottom: 0;\n  left: 0;\n  width: 100%;\n  height: 100%;\n  border: 0;\n}\n.embed-responsive-16by9 {\n  padding-bottom: 56.25%;\n}\n.embed-responsive-4by3 {\n  padding-bottom: 75%;\n}\n.well {\n  min-height: 20px;\n  padding: 19px;\n  margin-bottom: 20px;\n  background-color: #f5f5f5;\n  border: 1px solid #e3e3e3;\n  border-radius: 4px;\n  -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .05);\n          box-shadow: inset 0 1px 1px rgba(0, 0, 0, .05);\n}\n.well blockquote {\n  border-color: #ddd;\n  border-color: rgba(0, 0, 0, .15);\n}\n.well-lg {\n  padding: 24px;\n  border-radius: 6px;\n}\n.well-sm {\n  padding: 9px;\n  border-radius: 3px;\n}\n.close {\n  float: right;\n  font-size: 21px;\n  font-weight: bold;\n  line-height: 1;\n  color: #000;\n  text-shadow: 0 1px 0 #fff;\n  filter: alpha(opacity=20);\n  opacity: .2;\n}\n.close:hover,\n.close:focus {\n  color: #000;\n  text-decoration: none;\n  cursor: pointer;\n  filter: alpha(opacity=50);\n  opacity: .5;\n}\nbutton.close {\n  -webkit-appearance: none;\n  padding: 0;\n  cursor: pointer;\n  background: transparent;\n  border: 0;\n}\n.modal-open {\n  overflow: hidden;\n}\n.modal {\n  position: fixed;\n  top: 0;\n  right: 0;\n  bottom: 0;\n  left: 0;\n  z-index: 1050;\n  display: none;\n  overflow: hidden;\n  -webkit-overflow-scrolling: touch;\n  outline: 0;\n}\n.modal.fade .modal-dialog {\n  -webkit-transition: -webkit-transform .3s ease-out;\n       -o-transition:      -o-transform .3s ease-out;\n          transition:         transform .3s ease-out;\n  -webkit-transform: translate(0, -25%);\n      -ms-transform: translate(0, -25%);\n       -o-transform: translate(0, -25%);\n          transform: translate(0, -25%);\n}\n.modal.in .modal-dialog {\n  -webkit-transform: translate(0, 0);\n      -ms-transform: translate(0, 0);\n       -o-transform: translate(0, 0);\n          transform: translate(0, 0);\n}\n.modal-open .modal {\n  overflow-x: hidden;\n  overflow-y: auto;\n}\n.modal-dialog {\n  position: relative;\n  width: auto;\n  margin: 10px;\n}\n.modal-content {\n  position: relative;\n  background-color: #fff;\n  -webkit-background-clip: padding-box;\n          background-clip: padding-box;\n  border: 1px solid #999;\n  border: 1px solid rgba(0, 0, 0, .2);\n  border-radius: 6px;\n  outline: 0;\n  -webkit-box-shadow: 0 3px 9px rgba(0, 0, 0, .5);\n          box-shadow: 0 3px 9px rgba(0, 0, 0, .5);\n}\n.modal-backdrop {\n  position: fixed;\n  top: 0;\n  right: 0;\n  bottom: 0;\n  left: 0;\n  z-index: 1040;\n  background-color: #000;\n}\n.modal-backdrop.fade {\n  filter: alpha(opacity=0);\n  opacity: 0;\n}\n.modal-backdrop.in {\n  filter: alpha(opacity=50);\n  opacity: .5;\n}\n.modal-header {\n  min-height: 16.42857143px;\n  padding: 15px;\n  border-bottom: 1px solid #e5e5e5;\n}\n.modal-header .close {\n  margin-top: -2px;\n}\n.modal-title {\n  margin: 0;\n  line-height: 1.42857143;\n}\n.modal-body {\n  position: relative;\n  padding: 15px;\n}\n.modal-footer {\n  padding: 15px;\n  text-align: right;\n  border-top: 1px solid #e5e5e5;\n}\n.modal-footer .btn + .btn {\n  margin-bottom: 0;\n  margin-left: 5px;\n}\n.modal-footer .btn-group .btn + .btn {\n  margin-left: -1px;\n}\n.modal-footer .btn-block + .btn-block {\n  margin-left: 0;\n}\n.modal-scrollbar-measure {\n  position: absolute;\n  top: -9999px;\n  width: 50px;\n  height: 50px;\n  overflow: scroll;\n}\n@media (min-width: 768px) {\n  .modal-dialog {\n    width: 600px;\n    margin: 30px auto;\n  }\n  .modal-content {\n    -webkit-box-shadow: 0 5px 15px rgba(0, 0, 0, .5);\n            box-shadow: 0 5px 15px rgba(0, 0, 0, .5);\n  }\n  .modal-sm {\n    width: 300px;\n  }\n}\n@media (min-width: 992px) {\n  .modal-lg {\n    width: 900px;\n  }\n}\n.tooltip {\n  position: absolute;\n  z-index: 1070;\n  display: block;\n  font-family: \"Helvetica Neue\", Helvetica, Arial, sans-serif;\n  font-size: 12px;\n  font-style: normal;\n  font-weight: normal;\n  line-height: 1.42857143;\n  text-align: left;\n  text-align: start;\n  text-decoration: none;\n  text-shadow: none;\n  text-transform: none;\n  letter-spacing: normal;\n  word-break: normal;\n  word-spacing: normal;\n  word-wrap: normal;\n  white-space: normal;\n  filter: alpha(opacity=0);\n  opacity: 0;\n\n  line-break: auto;\n}\n.tooltip.in {\n  filter: alpha(opacity=90);\n  opacity: .9;\n}\n.tooltip.top {\n  padding: 5px 0;\n  margin-top: -3px;\n}\n.tooltip.right {\n  padding: 0 5px;\n  margin-left: 3px;\n}\n.tooltip.bottom {\n  padding: 5px 0;\n  margin-top: 3px;\n}\n.tooltip.left {\n  padding: 0 5px;\n  margin-left: -3px;\n}\n.tooltip-inner {\n  max-width: 200px;\n  padding: 3px 8px;\n  color: #fff;\n  text-align: center;\n  background-color: #000;\n  border-radius: 4px;\n}\n.tooltip-arrow {\n  position: absolute;\n  width: 0;\n  height: 0;\n  border-color: transparent;\n  border-style: solid;\n}\n.tooltip.top .tooltip-arrow {\n  bottom: 0;\n  left: 50%;\n  margin-left: -5px;\n  border-width: 5px 5px 0;\n  border-top-color: #000;\n}\n.tooltip.top-left .tooltip-arrow {\n  right: 5px;\n  bottom: 0;\n  margin-bottom: -5px;\n  border-width: 5px 5px 0;\n  border-top-color: #000;\n}\n.tooltip.top-right .tooltip-arrow {\n  bottom: 0;\n  left: 5px;\n  margin-bottom: -5px;\n  border-width: 5px 5px 0;\n  border-top-color: #000;\n}\n.tooltip.right .tooltip-arrow {\n  top: 50%;\n  left: 0;\n  margin-top: -5px;\n  border-width: 5px 5px 5px 0;\n  border-right-color: #000;\n}\n.tooltip.left .tooltip-arrow {\n  top: 50%;\n  right: 0;\n  margin-top: -5px;\n  border-width: 5px 0 5px 5px;\n  border-left-color: #000;\n}\n.tooltip.bottom .tooltip-arrow {\n  top: 0;\n  left: 50%;\n  margin-left: -5px;\n  border-width: 0 5px 5px;\n  border-bottom-color: #000;\n}\n.tooltip.bottom-left .tooltip-arrow {\n  top: 0;\n  right: 5px;\n  margin-top: -5px;\n  border-width: 0 5px 5px;\n  border-bottom-color: #000;\n}\n.tooltip.bottom-right .tooltip-arrow {\n  top: 0;\n  left: 5px;\n  margin-top: -5px;\n  border-width: 0 5px 5px;\n  border-bottom-color: #000;\n}\n.popover {\n  position: absolute;\n  top: 0;\n  left: 0;\n  z-index: 1060;\n  display: none;\n  max-width: 276px;\n  padding: 1px;\n  font-family: \"Helvetica Neue\", Helvetica, Arial, sans-serif;\n  font-size: 14px;\n  font-style: normal;\n  font-weight: normal;\n  line-height: 1.42857143;\n  text-align: left;\n  text-align: start;\n  text-decoration: none;\n  text-shadow: none;\n  text-transform: none;\n  letter-spacing: normal;\n  word-break: normal;\n  word-spacing: normal;\n  word-wrap: normal;\n  white-space: normal;\n  background-color: #fff;\n  -webkit-background-clip: padding-box;\n          background-clip: padding-box;\n  border: 1px solid #ccc;\n  border: 1px solid rgba(0, 0, 0, .2);\n  border-radius: 6px;\n  -webkit-box-shadow: 0 5px 10px rgba(0, 0, 0, .2);\n          box-shadow: 0 5px 10px rgba(0, 0, 0, .2);\n\n  line-break: auto;\n}\n.popover.top {\n  margin-top: -10px;\n}\n.popover.right {\n  margin-left: 10px;\n}\n.popover.bottom {\n  margin-top: 10px;\n}\n.popover.left {\n  margin-left: -10px;\n}\n.popover-title {\n  padding: 8px 14px;\n  margin: 0;\n  font-size: 14px;\n  background-color: #f7f7f7;\n  border-bottom: 1px solid #ebebeb;\n  border-radius: 5px 5px 0 0;\n}\n.popover-content {\n  padding: 9px 14px;\n}\n.popover > .arrow,\n.popover > .arrow:after {\n  position: absolute;\n  display: block;\n  width: 0;\n  height: 0;\n  border-color: transparent;\n  border-style: solid;\n}\n.popover > .arrow {\n  border-width: 11px;\n}\n.popover > .arrow:after {\n  content: \"\";\n  border-width: 10px;\n}\n.popover.top > .arrow {\n  bottom: -11px;\n  left: 50%;\n  margin-left: -11px;\n  border-top-color: #999;\n  border-top-color: rgba(0, 0, 0, .25);\n  border-bottom-width: 0;\n}\n.popover.top > .arrow:after {\n  bottom: 1px;\n  margin-left: -10px;\n  content: \" \";\n  border-top-color: #fff;\n  border-bottom-width: 0;\n}\n.popover.right > .arrow {\n  top: 50%;\n  left: -11px;\n  margin-top: -11px;\n  border-right-color: #999;\n  border-right-color: rgba(0, 0, 0, .25);\n  border-left-width: 0;\n}\n.popover.right > .arrow:after {\n  bottom: -10px;\n  left: 1px;\n  content: \" \";\n  border-right-color: #fff;\n  border-left-width: 0;\n}\n.popover.bottom > .arrow {\n  top: -11px;\n  left: 50%;\n  margin-left: -11px;\n  border-top-width: 0;\n  border-bottom-color: #999;\n  border-bottom-color: rgba(0, 0, 0, .25);\n}\n.popover.bottom > .arrow:after {\n  top: 1px;\n  margin-left: -10px;\n  content: \" \";\n  border-top-width: 0;\n  border-bottom-color: #fff;\n}\n.popover.left > .arrow {\n  top: 50%;\n  right: -11px;\n  margin-top: -11px;\n  border-right-width: 0;\n  border-left-color: #999;\n  border-left-color: rgba(0, 0, 0, .25);\n}\n.popover.left > .arrow:after {\n  right: 1px;\n  bottom: -10px;\n  content: \" \";\n  border-right-width: 0;\n  border-left-color: #fff;\n}\n.carousel {\n  position: relative;\n}\n.carousel-inner {\n  position: relative;\n  width: 100%;\n  overflow: hidden;\n}\n.carousel-inner > .item {\n  position: relative;\n  display: none;\n  -webkit-transition: .6s ease-in-out left;\n       -o-transition: .6s ease-in-out left;\n          transition: .6s ease-in-out left;\n}\n.carousel-inner > .item > img,\n.carousel-inner > .item > a > img {\n  line-height: 1;\n}\n@media all and (transform-3d), (-webkit-transform-3d) {\n  .carousel-inner > .item {\n    -webkit-transition: -webkit-transform .6s ease-in-out;\n         -o-transition:      -o-transform .6s ease-in-out;\n            transition:         transform .6s ease-in-out;\n\n    -webkit-backface-visibility: hidden;\n            backface-visibility: hidden;\n    -webkit-perspective: 1000px;\n            perspective: 1000px;\n  }\n  .carousel-inner > .item.next,\n  .carousel-inner > .item.active.right {\n    left: 0;\n    -webkit-transform: translate3d(100%, 0, 0);\n            transform: translate3d(100%, 0, 0);\n  }\n  .carousel-inner > .item.prev,\n  .carousel-inner > .item.active.left {\n    left: 0;\n    -webkit-transform: translate3d(-100%, 0, 0);\n            transform: translate3d(-100%, 0, 0);\n  }\n  .carousel-inner > .item.next.left,\n  .carousel-inner > .item.prev.right,\n  .carousel-inner > .item.active {\n    left: 0;\n    -webkit-transform: translate3d(0, 0, 0);\n            transform: translate3d(0, 0, 0);\n  }\n}\n.carousel-inner > .active,\n.carousel-inner > .next,\n.carousel-inner > .prev {\n  display: block;\n}\n.carousel-inner > .active {\n  left: 0;\n}\n.carousel-inner > .next,\n.carousel-inner > .prev {\n  position: absolute;\n  top: 0;\n  width: 100%;\n}\n.carousel-inner > .next {\n  left: 100%;\n}\n.carousel-inner > .prev {\n  left: -100%;\n}\n.carousel-inner > .next.left,\n.carousel-inner > .prev.right {\n  left: 0;\n}\n.carousel-inner > .active.left {\n  left: -100%;\n}\n.carousel-inner > .active.right {\n  left: 100%;\n}\n.carousel-control {\n  position: absolute;\n  top: 0;\n  bottom: 0;\n  left: 0;\n  width: 15%;\n  font-size: 20px;\n  color: #fff;\n  text-align: center;\n  text-shadow: 0 1px 2px rgba(0, 0, 0, .6);\n  filter: alpha(opacity=50);\n  opacity: .5;\n}\n.carousel-control.left {\n  background-image: -webkit-linear-gradient(left, rgba(0, 0, 0, .5) 0%, rgba(0, 0, 0, .0001) 100%);\n  background-image:      -o-linear-gradient(left, rgba(0, 0, 0, .5) 0%, rgba(0, 0, 0, .0001) 100%);\n  background-image: -webkit-gradient(linear, left top, right top, from(rgba(0, 0, 0, .5)), to(rgba(0, 0, 0, .0001)));\n  background-image:         linear-gradient(to right, rgba(0, 0, 0, .5) 0%, rgba(0, 0, 0, .0001) 100%);\n  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#80000000', endColorstr='#00000000', GradientType=1);\n  background-repeat: repeat-x;\n}\n.carousel-control.right {\n  right: 0;\n  left: auto;\n  background-image: -webkit-linear-gradient(left, rgba(0, 0, 0, .0001) 0%, rgba(0, 0, 0, .5) 100%);\n  background-image:      -o-linear-gradient(left, rgba(0, 0, 0, .0001) 0%, rgba(0, 0, 0, .5) 100%);\n  background-image: -webkit-gradient(linear, left top, right top, from(rgba(0, 0, 0, .0001)), to(rgba(0, 0, 0, .5)));\n  background-image:         linear-gradient(to right, rgba(0, 0, 0, .0001) 0%, rgba(0, 0, 0, .5) 100%);\n  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#00000000', endColorstr='#80000000', GradientType=1);\n  background-repeat: repeat-x;\n}\n.carousel-control:hover,\n.carousel-control:focus {\n  color: #fff;\n  text-decoration: none;\n  filter: alpha(opacity=90);\n  outline: 0;\n  opacity: .9;\n}\n.carousel-control .icon-prev,\n.carousel-control .icon-next,\n.carousel-control .glyphicon-chevron-left,\n.carousel-control .glyphicon-chevron-right {\n  position: absolute;\n  top: 50%;\n  z-index: 5;\n  display: inline-block;\n  margin-top: -10px;\n}\n.carousel-control .icon-prev,\n.carousel-control .glyphicon-chevron-left {\n  left: 50%;\n  margin-left: -10px;\n}\n.carousel-control .icon-next,\n.carousel-control .glyphicon-chevron-right {\n  right: 50%;\n  margin-right: -10px;\n}\n.carousel-control .icon-prev,\n.carousel-control .icon-next {\n  width: 20px;\n  height: 20px;\n  font-family: serif;\n  line-height: 1;\n}\n.carousel-control .icon-prev:before {\n  content: '\\2039';\n}\n.carousel-control .icon-next:before {\n  content: '\\203a';\n}\n.carousel-indicators {\n  position: absolute;\n  bottom: 10px;\n  left: 50%;\n  z-index: 15;\n  width: 60%;\n  padding-left: 0;\n  margin-left: -30%;\n  text-align: center;\n  list-style: none;\n}\n.carousel-indicators li {\n  display: inline-block;\n  width: 10px;\n  height: 10px;\n  margin: 1px;\n  text-indent: -999px;\n  cursor: pointer;\n  background-color: #000 \\9;\n  background-color: rgba(0, 0, 0, 0);\n  border: 1px solid #fff;\n  border-radius: 10px;\n}\n.carousel-indicators .active {\n  width: 12px;\n  height: 12px;\n  margin: 0;\n  background-color: #fff;\n}\n.carousel-caption {\n  position: absolute;\n  right: 15%;\n  bottom: 20px;\n  left: 15%;\n  z-index: 10;\n  padding-top: 20px;\n  padding-bottom: 20px;\n  color: #fff;\n  text-align: center;\n  text-shadow: 0 1px 2px rgba(0, 0, 0, .6);\n}\n.carousel-caption .btn {\n  text-shadow: none;\n}\n@media screen and (min-width: 768px) {\n  .carousel-control .glyphicon-chevron-left,\n  .carousel-control .glyphicon-chevron-right,\n  .carousel-control .icon-prev,\n  .carousel-control .icon-next {\n    width: 30px;\n    height: 30px;\n    margin-top: -15px;\n    font-size: 30px;\n  }\n  .carousel-control .glyphicon-chevron-left,\n  .carousel-control .icon-prev {\n    margin-left: -15px;\n  }\n  .carousel-control .glyphicon-chevron-right,\n  .carousel-control .icon-next {\n    margin-right: -15px;\n  }\n  .carousel-caption {\n    right: 20%;\n    left: 20%;\n    padding-bottom: 30px;\n  }\n  .carousel-indicators {\n    bottom: 20px;\n  }\n}\n.clearfix:before,\n.clearfix:after,\n.dl-horizontal dd:before,\n.dl-horizontal dd:after,\n.container:before,\n.container:after,\n.container-fluid:before,\n.container-fluid:after,\n.row:before,\n.row:after,\n.form-horizontal .form-group:before,\n.form-horizontal .form-group:after,\n.btn-toolbar:before,\n.btn-toolbar:after,\n.btn-group-vertical > .btn-group:before,\n.btn-group-vertical > .btn-group:after,\n.nav:before,\n.nav:after,\n.navbar:before,\n.navbar:after,\n.navbar-header:before,\n.navbar-header:after,\n.navbar-collapse:before,\n.navbar-collapse:after,\n.pager:before,\n.pager:after,\n.panel-body:before,\n.panel-body:after,\n.modal-footer:before,\n.modal-footer:after {\n  display: table;\n  content: \" \";\n}\n.clearfix:after,\n.dl-horizontal dd:after,\n.container:after,\n.container-fluid:after,\n.row:after,\n.form-horizontal .form-group:after,\n.btn-toolbar:after,\n.btn-group-vertical > .btn-group:after,\n.nav:after,\n.navbar:after,\n.navbar-header:after,\n.navbar-collapse:after,\n.pager:after,\n.panel-body:after,\n.modal-footer:after {\n  clear: both;\n}\n.center-block {\n  display: block;\n  margin-right: auto;\n  margin-left: auto;\n}\n.pull-right {\n  float: right !important;\n}\n.pull-left {\n  float: left !important;\n}\n.hide {\n  display: none !important;\n}\n.show {\n  display: block !important;\n}\n.invisible {\n  visibility: hidden;\n}\n.text-hide {\n  font: 0/0 a;\n  color: transparent;\n  text-shadow: none;\n  background-color: transparent;\n  border: 0;\n}\n.hidden {\n  display: none !important;\n}\n.affix {\n  position: fixed;\n}\n@-ms-viewport {\n  width: device-width;\n}\n.visible-xs,\n.visible-sm,\n.visible-md,\n.visible-lg {\n  display: none !important;\n}\n.visible-xs-block,\n.visible-xs-inline,\n.visible-xs-inline-block,\n.visible-sm-block,\n.visible-sm-inline,\n.visible-sm-inline-block,\n.visible-md-block,\n.visible-md-inline,\n.visible-md-inline-block,\n.visible-lg-block,\n.visible-lg-inline,\n.visible-lg-inline-block {\n  display: none !important;\n}\n@media (max-width: 767px) {\n  .visible-xs {\n    display: block !important;\n  }\n  table.visible-xs {\n    display: table !important;\n  }\n  tr.visible-xs {\n    display: table-row !important;\n  }\n  th.visible-xs,\n  td.visible-xs {\n    display: table-cell !important;\n  }\n}\n@media (max-width: 767px) {\n  .visible-xs-block {\n    display: block !important;\n  }\n}\n@media (max-width: 767px) {\n  .visible-xs-inline {\n    display: inline !important;\n  }\n}\n@media (max-width: 767px) {\n  .visible-xs-inline-block {\n    display: inline-block !important;\n  }\n}\n@media (min-width: 768px) and (max-width: 991px) {\n  .visible-sm {\n    display: block !important;\n  }\n  table.visible-sm {\n    display: table !important;\n  }\n  tr.visible-sm {\n    display: table-row !important;\n  }\n  th.visible-sm,\n  td.visible-sm {\n    display: table-cell !important;\n  }\n}\n@media (min-width: 768px) and (max-width: 991px) {\n  .visible-sm-block {\n    display: block !important;\n  }\n}\n@media (min-width: 768px) and (max-width: 991px) {\n  .visible-sm-inline {\n    display: inline !important;\n  }\n}\n@media (min-width: 768px) and (max-width: 991px) {\n  .visible-sm-inline-block {\n    display: inline-block !important;\n  }\n}\n@media (min-width: 992px) and (max-width: 1199px) {\n  .visible-md {\n    display: block !important;\n  }\n  table.visible-md {\n    display: table !important;\n  }\n  tr.visible-md {\n    display: table-row !important;\n  }\n  th.visible-md,\n  td.visible-md {\n    display: table-cell !important;\n  }\n}\n@media (min-width: 992px) and (max-width: 1199px) {\n  .visible-md-block {\n    display: block !important;\n  }\n}\n@media (min-width: 992px) and (max-width: 1199px) {\n  .visible-md-inline {\n    display: inline !important;\n  }\n}\n@media (min-width: 992px) and (max-width: 1199px) {\n  .visible-md-inline-block {\n    display: inline-block !important;\n  }\n}\n@media (min-width: 1200px) {\n  .visible-lg {\n    display: block !important;\n  }\n  table.visible-lg {\n    display: table !important;\n  }\n  tr.visible-lg {\n    display: table-row !important;\n  }\n  th.visible-lg,\n  td.visible-lg {\n    display: table-cell !important;\n  }\n}\n@media (min-width: 1200px) {\n  .visible-lg-block {\n    display: block !important;\n  }\n}\n@media (min-width: 1200px) {\n  .visible-lg-inline {\n    display: inline !important;\n  }\n}\n@media (min-width: 1200px) {\n  .visible-lg-inline-block {\n    display: inline-block !important;\n  }\n}\n@media (max-width: 767px) {\n  .hidden-xs {\n    display: none !important;\n  }\n}\n@media (min-width: 768px) and (max-width: 991px) {\n  .hidden-sm {\n    display: none !important;\n  }\n}\n@media (min-width: 992px) and (max-width: 1199px) {\n  .hidden-md {\n    display: none !important;\n  }\n}\n@media (min-width: 1200px) {\n  .hidden-lg {\n    display: none !important;\n  }\n}\n.visible-print {\n  display: none !important;\n}\n@media print {\n  .visible-print {\n    display: block !important;\n  }\n  table.visible-print {\n    display: table !important;\n  }\n  tr.visible-print {\n    display: table-row !important;\n  }\n  th.visible-print,\n  td.visible-print {\n    display: table-cell !important;\n  }\n}\n.visible-print-block {\n  display: none !important;\n}\n@media print {\n  .visible-print-block {\n    display: block !important;\n  }\n}\n.visible-print-inline {\n  display: none !important;\n}\n@media print {\n  .visible-print-inline {\n    display: inline !important;\n  }\n}\n.visible-print-inline-block {\n  display: none !important;\n}\n@media print {\n  .visible-print-inline-block {\n    display: inline-block !important;\n  }\n}\n@media print {\n  .hidden-print {\n    display: none !important;\n  }\n}\n/*# sourceMappingURL=bootstrap.css.map */\n"
  },
  {
    "path": "app_backend/static/css/custom.css",
    "content": ".fa {\n    font-size: initial;\n}\n"
  },
  {
    "path": "app_backend/static/css/lightbox.css",
    "content": "/* Preload images */\nbody:after {\n  content: url(../images/close.png) url(../images/loading.gif) url(../images/prev.png) url(../images/next.png);\n  display: none;\n}\n\nbody.lb-disable-scrolling {\n  overflow: hidden;\n}\n\n.lightboxOverlay {\n  position: absolute;\n  top: 0;\n  left: 0;\n  z-index: 9999;\n  background-color: black;\n  filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=80);\n  opacity: 0.8;\n  display: none;\n}\n\n.lightbox {\n  position: absolute;\n  left: 0;\n  width: 100%;\n  z-index: 10000;\n  text-align: center;\n  line-height: 0;\n  font-weight: normal;\n}\n\n.lightbox .lb-image {\n  display: block;\n  height: auto;\n  max-width: inherit;\n  border-radius: 3px;\n}\n\n.lightbox a img {\n  border: none;\n}\n\n.lb-outerContainer {\n  position: relative;\n  background-color: white;\n  *zoom: 1;\n  width: 250px;\n  height: 250px;\n  margin: 0 auto;\n  border-radius: 4px;\n}\n\n.lb-outerContainer:after {\n  content: \"\";\n  display: table;\n  clear: both;\n}\n\n.lb-container {\n  padding: 4px;\n}\n\n.lb-loader {\n  position: absolute;\n  top: 43%;\n  left: 0;\n  height: 25%;\n  width: 100%;\n  text-align: center;\n  line-height: 0;\n}\n\n.lb-cancel {\n  display: block;\n  width: 32px;\n  height: 32px;\n  margin: 0 auto;\n  background: url(../images/loading.gif) no-repeat;\n}\n\n.lb-nav {\n  position: absolute;\n  top: 0;\n  left: 0;\n  height: 100%;\n  width: 100%;\n  z-index: 10;\n}\n\n.lb-container > .nav {\n  left: 0;\n}\n\n.lb-nav a {\n  outline: none;\n  background-image: url('data:image/gif;base64,R0lGODlhAQABAPAAAP///wAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw==');\n}\n\n.lb-prev, .lb-next {\n  height: 100%;\n  cursor: pointer;\n  display: block;\n}\n\n.lb-nav a.lb-prev {\n  width: 34%;\n  left: 0;\n  float: left;\n  background: url(../images/prev.png) left 48% no-repeat;\n  filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=0);\n  opacity: 0;\n  -webkit-transition: opacity 0.6s;\n  -moz-transition: opacity 0.6s;\n  -o-transition: opacity 0.6s;\n  transition: opacity 0.6s;\n}\n\n.lb-nav a.lb-prev:hover {\n  filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=100);\n  opacity: 1;\n}\n\n.lb-nav a.lb-next {\n  width: 64%;\n  right: 0;\n  float: right;\n  background: url(../images/next.png) right 48% no-repeat;\n  filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=0);\n  opacity: 0;\n  -webkit-transition: opacity 0.6s;\n  -moz-transition: opacity 0.6s;\n  -o-transition: opacity 0.6s;\n  transition: opacity 0.6s;\n}\n\n.lb-nav a.lb-next:hover {\n  filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=100);\n  opacity: 1;\n}\n\n.lb-dataContainer {\n  margin: 0 auto;\n  padding-top: 5px;\n  *zoom: 1;\n  width: 100%;\n  -moz-border-radius-bottomleft: 4px;\n  -webkit-border-bottom-left-radius: 4px;\n  border-bottom-left-radius: 4px;\n  -moz-border-radius-bottomright: 4px;\n  -webkit-border-bottom-right-radius: 4px;\n  border-bottom-right-radius: 4px;\n}\n\n.lb-dataContainer:after {\n  content: \"\";\n  display: table;\n  clear: both;\n}\n\n.lb-data {\n  padding: 0 4px;\n  color: #ccc;\n}\n\n.lb-data .lb-details {\n  width: 85%;\n  float: left;\n  text-align: left;\n  line-height: 1.1em;\n}\n\n.lb-data .lb-caption {\n  font-size: 13px;\n  font-weight: bold;\n  line-height: 1em;\n}\n\n.lb-data .lb-number {\n  display: block;\n  clear: left;\n  padding-bottom: 1em;\n  font-size: 12px;\n  color: #999999;\n}\n\n.lb-data .lb-close {\n  display: block;\n  float: right;\n  width: 30px;\n  height: 30px;\n  background: url(../images/close.png) top right no-repeat;\n  text-align: right;\n  outline: none;\n  filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=70);\n  opacity: 0.7;\n  -webkit-transition: opacity 0.2s;\n  -moz-transition: opacity 0.2s;\n  -o-transition: opacity 0.2s;\n  transition: opacity 0.2s;\n}\n\n.lb-data .lb-close:hover {\n  cursor: pointer;\n  filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=100);\n  opacity: 1;\n}\n"
  },
  {
    "path": "app_backend/static/css/sb-admin-2.css",
    "content": "/*!\n * Start Bootstrap - SB Admin 2 v3.3.7+1 (http://startbootstrap.com/template-overviews/sb-admin-2)\n * Copyright 2013-2016 Start Bootstrap\n * Licensed under MIT (https://github.com/BlackrockDigital/startbootstrap/blob/gh-pages/LICENSE)\n */\nbody {\n  background-color: #f8f8f8;\n}\n#wrapper {\n  width: 100%;\n}\n#page-wrapper {\n  /*padding: 0 15px;*/\n  min-height: 568px;\n  background-color: white;\n}\n@media (min-width: 768px) {\n  #page-wrapper {\n    position: inherit;\n    margin: 0 0 0 250px;\n    /*padding: 0 30px;*/\n    border-left: 1px solid #e7e7e7;\n  }\n}\n.navbar-top-links {\n  margin-right: 0;\n}\n.navbar-top-links li {\n  display: inline-block;\n}\n.navbar-top-links li:last-child {\n  margin-right: 15px;\n}\n.navbar-top-links li a {\n  padding: 15px;\n  min-height: 50px;\n}\n.navbar-top-links .dropdown-menu li {\n  display: block;\n}\n.navbar-top-links .dropdown-menu li:last-child {\n  margin-right: 0;\n}\n.navbar-top-links .dropdown-menu li a {\n  padding: 3px 20px;\n  min-height: 0;\n}\n.navbar-top-links .dropdown-menu li a div {\n  white-space: normal;\n}\n.navbar-top-links .dropdown-messages,\n.navbar-top-links .dropdown-tasks,\n.navbar-top-links .dropdown-alerts {\n  width: 310px;\n  min-width: 0;\n}\n.navbar-top-links .dropdown-messages {\n  margin-left: 5px;\n}\n.navbar-top-links .dropdown-tasks {\n  margin-left: -59px;\n}\n.navbar-top-links .dropdown-alerts {\n  margin-left: -123px;\n}\n.navbar-top-links .dropdown-user {\n  right: 0;\n  left: auto;\n}\n.sidebar .sidebar-nav.navbar-collapse {\n  padding-left: 0;\n  padding-right: 0;\n}\n.sidebar .sidebar-search {\n  padding: 15px;\n}\n.sidebar ul li {\n  border-bottom: 1px solid #e7e7e7;\n}\n.sidebar ul li a.active {\n  background-color: #eeeeee;\n}\n.sidebar .arrow {\n  float: right;\n}\n.sidebar .fa.arrow:before {\n  content: \"\\f104\";\n}\n.sidebar .active > a > .fa.arrow:before {\n  content: \"\\f107\";\n}\n.sidebar .nav-second-level li,\n.sidebar .nav-third-level li {\n  border-bottom: none !important;\n}\n.sidebar .nav-second-level li a {\n  padding-left: 37px;\n}\n.sidebar .nav-third-level li a {\n  padding-left: 52px;\n}\n@media (min-width: 768px) {\n  .sidebar {\n    z-index: 1;\n    position: absolute;\n    width: 250px;\n    margin-top: 51px;\n  }\n  .navbar-top-links .dropdown-messages,\n  .navbar-top-links .dropdown-tasks,\n  .navbar-top-links .dropdown-alerts {\n    margin-left: auto;\n  }\n}\n.btn-outline {\n  color: inherit;\n  background-color: transparent;\n  transition: all .5s;\n}\n.btn-primary.btn-outline {\n  color: #428bca;\n}\n.btn-success.btn-outline {\n  color: #5cb85c;\n}\n.btn-info.btn-outline {\n  color: #5bc0de;\n}\n.btn-warning.btn-outline {\n  color: #f0ad4e;\n}\n.btn-danger.btn-outline {\n  color: #d9534f;\n}\n.btn-primary.btn-outline:hover,\n.btn-success.btn-outline:hover,\n.btn-info.btn-outline:hover,\n.btn-warning.btn-outline:hover,\n.btn-danger.btn-outline:hover {\n  color: white;\n}\n.chat {\n  margin: 0;\n  padding: 0;\n  list-style: none;\n}\n.chat li {\n  margin-bottom: 10px;\n  padding-bottom: 5px;\n  border-bottom: 1px dotted #999999;\n}\n.chat li.left .chat-body {\n  margin-left: 60px;\n}\n.chat li.right .chat-body {\n  margin-right: 60px;\n}\n.chat li .chat-body p {\n  margin: 0;\n}\n.panel .slidedown .glyphicon,\n.chat .glyphicon {\n  margin-right: 5px;\n}\n.chat-panel .panel-body {\n  height: 350px;\n  overflow-y: scroll;\n}\n.login-panel {\n  margin-top: 25%;\n}\n.flot-chart {\n  display: block;\n  height: 400px;\n}\n.flot-chart-content {\n  width: 100%;\n  height: 100%;\n}\ntable.dataTable thead .sorting,\ntable.dataTable thead .sorting_asc,\ntable.dataTable thead .sorting_desc,\ntable.dataTable thead .sorting_asc_disabled,\ntable.dataTable thead .sorting_desc_disabled {\n  background: transparent;\n}\ntable.dataTable thead .sorting_asc:after {\n  content: \"\\f0de\";\n  float: right;\n  font-family: fontawesome;\n}\ntable.dataTable thead .sorting_desc:after {\n  content: \"\\f0dd\";\n  float: right;\n  font-family: fontawesome;\n}\ntable.dataTable thead .sorting:after {\n  content: \"\\f0dc\";\n  float: right;\n  font-family: fontawesome;\n  color: rgba(50, 50, 50, 0.5);\n}\n.btn-circle {\n  width: 30px;\n  height: 30px;\n  padding: 6px 0;\n  border-radius: 15px;\n  text-align: center;\n  font-size: 12px;\n  line-height: 1.428571429;\n}\n.btn-circle.btn-lg {\n  width: 50px;\n  height: 50px;\n  padding: 10px 16px;\n  border-radius: 25px;\n  font-size: 18px;\n  line-height: 1.33;\n}\n.btn-circle.btn-xl {\n  width: 70px;\n  height: 70px;\n  padding: 10px 16px;\n  border-radius: 35px;\n  font-size: 24px;\n  line-height: 1.33;\n}\n.show-grid [class^=\"col-\"] {\n  padding-top: 10px;\n  padding-bottom: 10px;\n  border: 1px solid #ddd;\n  background-color: #eee !important;\n}\n.show-grid {\n  margin: 15px 0;\n}\n.huge {\n  font-size: 40px;\n}\n.panel-green {\n  border-color: #5cb85c;\n}\n.panel-green > .panel-heading {\n  border-color: #5cb85c;\n  color: white;\n  background-color: #5cb85c;\n}\n.panel-green > a {\n  color: #5cb85c;\n}\n.panel-green > a:hover {\n  color: #3d8b3d;\n}\n.panel-red {\n  border-color: #d9534f;\n}\n.panel-red > .panel-heading {\n  border-color: #d9534f;\n  color: white;\n  background-color: #d9534f;\n}\n.panel-red > a {\n  color: #d9534f;\n}\n.panel-red > a:hover {\n  color: #b52b27;\n}\n.panel-yellow {\n  border-color: #f0ad4e;\n}\n.panel-yellow > .panel-heading {\n  border-color: #f0ad4e;\n  color: white;\n  background-color: #f0ad4e;\n}\n.panel-yellow > a {\n  color: #f0ad4e;\n}\n.panel-yellow > a:hover {\n  color: #df8a13;\n}\n.timeline {\n  position: relative;\n  padding: 20px 0 20px;\n  list-style: none;\n}\n.timeline:before {\n  content: \" \";\n  position: absolute;\n  top: 0;\n  bottom: 0;\n  left: 50%;\n  width: 3px;\n  margin-left: -1.5px;\n  background-color: #eeeeee;\n}\n.timeline > li {\n  position: relative;\n  margin-bottom: 20px;\n}\n.timeline > li:before,\n.timeline > li:after {\n  content: \" \";\n  display: table;\n}\n.timeline > li:after {\n  clear: both;\n}\n.timeline > li:before,\n.timeline > li:after {\n  content: \" \";\n  display: table;\n}\n.timeline > li:after {\n  clear: both;\n}\n.timeline > li > .timeline-panel {\n  float: left;\n  position: relative;\n  width: 46%;\n  padding: 20px;\n  border: 1px solid #d4d4d4;\n  border-radius: 2px;\n  -webkit-box-shadow: 0 1px 6px rgba(0, 0, 0, 0.175);\n  box-shadow: 0 1px 6px rgba(0, 0, 0, 0.175);\n}\n.timeline > li > .timeline-panel:before {\n  content: \" \";\n  display: inline-block;\n  position: absolute;\n  top: 26px;\n  right: -15px;\n  border-top: 15px solid transparent;\n  border-right: 0 solid #ccc;\n  border-bottom: 15px solid transparent;\n  border-left: 15px solid #ccc;\n}\n.timeline > li > .timeline-panel:after {\n  content: \" \";\n  display: inline-block;\n  position: absolute;\n  top: 27px;\n  right: -14px;\n  border-top: 14px solid transparent;\n  border-right: 0 solid #fff;\n  border-bottom: 14px solid transparent;\n  border-left: 14px solid #fff;\n}\n.timeline > li > .timeline-badge {\n  z-index: 100;\n  position: absolute;\n  top: 16px;\n  left: 50%;\n  width: 50px;\n  height: 50px;\n  margin-left: -25px;\n  border-radius: 50% 50% 50% 50%;\n  text-align: center;\n  font-size: 1.4em;\n  line-height: 50px;\n  color: #fff;\n  background-color: #999999;\n}\n.timeline > li.timeline-inverted > .timeline-panel {\n  float: right;\n}\n.timeline > li.timeline-inverted > .timeline-panel:before {\n  right: auto;\n  left: -15px;\n  border-right-width: 15px;\n  border-left-width: 0;\n}\n.timeline > li.timeline-inverted > .timeline-panel:after {\n  right: auto;\n  left: -14px;\n  border-right-width: 14px;\n  border-left-width: 0;\n}\n.timeline-badge.primary {\n  background-color: #2e6da4 !important;\n}\n.timeline-badge.success {\n  background-color: #3f903f !important;\n}\n.timeline-badge.warning {\n  background-color: #f0ad4e !important;\n}\n.timeline-badge.danger {\n  background-color: #d9534f !important;\n}\n.timeline-badge.info {\n  background-color: #5bc0de !important;\n}\n.timeline-title {\n  margin-top: 0;\n  color: inherit;\n}\n.timeline-body > p,\n.timeline-body > ul {\n  margin-bottom: 0;\n}\n.timeline-body > p + p {\n  margin-top: 5px;\n}\n@media (max-width: 767px) {\n  ul.timeline:before {\n    left: 40px;\n  }\n  ul.timeline > li > .timeline-panel {\n    width: calc(10%);\n    width: -moz-calc(10%);\n    width: -webkit-calc(10%);\n  }\n  ul.timeline > li > .timeline-badge {\n    top: 16px;\n    left: 15px;\n    margin-left: 0;\n  }\n  ul.timeline > li > .timeline-panel {\n    float: right;\n  }\n  ul.timeline > li > .timeline-panel:before {\n    right: auto;\n    left: -15px;\n    border-right-width: 15px;\n    border-left-width: 0;\n  }\n  ul.timeline > li > .timeline-panel:after {\n    right: auto;\n    left: -14px;\n    border-right-width: 14px;\n    border-left-width: 0;\n  }\n}\n"
  },
  {
    "path": "app_backend/static/css/slideout.css",
    "content": ".page-menu {\n    background-image: linear-gradient(90deg, #eeeeee 90%, #bbbbbb 100%);\n}\n\n.page-menu .container {\n    margin-right: 10%;\n}\n\n.page-panel {\n    background-color: #fff;\n    margin-bottom: 0;\n}\n\n.slideout-menu {\n    position: fixed;\n    left: 0;\n    top: 0;\n    bottom: 0;\n    right: 0;\n    z-index: 0;\n    width: 256px;\n    overflow-y: auto;\n    -webkit-overflow-scrolling: touch;\n    display: none;\n}\n\n.slideout-panel {\n    position: relative;\n    z-index: 1;\n    /*will-change: transform;*/\n}\n\n.slideout-open,\n.slideout-open body,\n.slideout-open .slideout-panel {\n    overflow: hidden;\n}\n\n.slideout-open .slideout-menu {\n    display: block;\n}\n"
  },
  {
    "path": "app_backend/static/csv/flare.csv",
    "content": "id,value\nflare,\nflare.analytics,\nflare.analytics.cluster,\nflare.analytics.cluster.AgglomerativeCluster,3938\nflare.analytics.cluster.CommunityStructure,3812\nflare.analytics.cluster.HierarchicalCluster,6714\nflare.analytics.cluster.MergeEdge,743\nflare.analytics.graph,\nflare.analytics.graph.BetweennessCentrality,3534\nflare.analytics.graph.LinkDistance,5731\nflare.analytics.graph.MaxFlowMinCut,7840\nflare.analytics.graph.ShortestPaths,5914\nflare.analytics.graph.SpanningTree,3416\nflare.analytics.optimization,\nflare.analytics.optimization.AspectRatioBanker,7074\nflare.animate,\nflare.animate.Easing,17010\nflare.animate.FunctionSequence,5842\nflare.animate.interpolate,\nflare.animate.interpolate.ArrayInterpolator,1983\nflare.animate.interpolate.ColorInterpolator,2047\nflare.animate.interpolate.DateInterpolator,1375\nflare.animate.interpolate.Interpolator,8746\nflare.animate.interpolate.MatrixInterpolator,2202\nflare.animate.interpolate.NumberInterpolator,1382\nflare.animate.interpolate.ObjectInterpolator,1629\nflare.animate.interpolate.PointInterpolator,1675\nflare.animate.interpolate.RectangleInterpolator,2042\nflare.animate.ISchedulable,1041\nflare.animate.Parallel,5176\nflare.animate.Pause,449\nflare.animate.Scheduler,5593\nflare.animate.Sequence,5534\nflare.animate.Transition,9201\nflare.animate.Transitioner,19975\nflare.animate.TransitionEvent,1116\nflare.animate.Tween,6006\nflare.data,\nflare.data.converters,\nflare.data.converters.Converters,721\nflare.data.converters.DelimitedTextConverter,4294\nflare.data.converters.GraphMLConverter,9800\nflare.data.converters.IDataConverter,1314\nflare.data.converters.JSONConverter,2220\nflare.data.DataField,1759\nflare.data.DataSchema,2165\nflare.data.DataSet,586\nflare.data.DataSource,3331\nflare.data.DataTable,772\nflare.data.DataUtil,3322\nflare.display,\nflare.display.DirtySprite,8833\nflare.display.LineSprite,1732\nflare.display.RectSprite,3623\nflare.display.TextSprite,10066\nflare.flex,\nflare.flex.FlareVis,4116\nflare.physics,\nflare.physics.DragForce,1082\nflare.physics.GravityForce,1336\nflare.physics.IForce,319\nflare.physics.NBodyForce,10498\nflare.physics.Particle,2822\nflare.physics.Simulation,9983\nflare.physics.Spring,2213\nflare.physics.SpringForce,1681\nflare.query,\nflare.query.AggregateExpression,1616\nflare.query.And,1027\nflare.query.Arithmetic,3891\nflare.query.Average,891\nflare.query.BinaryExpression,2893\nflare.query.Comparison,5103\nflare.query.CompositeExpression,3677\nflare.query.Count,781\nflare.query.DateUtil,4141\nflare.query.Distinct,933\nflare.query.Expression,5130\nflare.query.ExpressionIterator,3617\nflare.query.Fn,3240\nflare.query.If,2732\nflare.query.IsA,2039\nflare.query.Literal,1214\nflare.query.Match,3748\nflare.query.Maximum,843\nflare.query.methods,\nflare.query.methods.add,593\nflare.query.methods.and,330\nflare.query.methods.average,287\nflare.query.methods.count,277\nflare.query.methods.distinct,292\nflare.query.methods.div,595\nflare.query.methods.eq,594\nflare.query.methods.fn,460\nflare.query.methods.gt,603\nflare.query.methods.gte,625\nflare.query.methods.iff,748\nflare.query.methods.isa,461\nflare.query.methods.lt,597\nflare.query.methods.lte,619\nflare.query.methods.max,283\nflare.query.methods.min,283\nflare.query.methods.mod,591\nflare.query.methods.mul,603\nflare.query.methods.neq,599\nflare.query.methods.not,386\nflare.query.methods.or,323\nflare.query.methods.orderby,307\nflare.query.methods.range,772\nflare.query.methods.select,296\nflare.query.methods.stddev,363\nflare.query.methods.sub,600\nflare.query.methods.sum,280\nflare.query.methods.update,307\nflare.query.methods.variance,335\nflare.query.methods.where,299\nflare.query.methods.xor,354\nflare.query.methods._,264\nflare.query.Minimum,843\nflare.query.Not,1554\nflare.query.Or,970\nflare.query.Query,13896\nflare.query.Range,1594\nflare.query.StringUtil,4130\nflare.query.Sum,791\nflare.query.Variable,1124\nflare.query.Variance,1876\nflare.query.Xor,1101\nflare.scale,\nflare.scale.IScaleMap,2105\nflare.scale.LinearScale,1316\nflare.scale.LogScale,3151\nflare.scale.OrdinalScale,3770\nflare.scale.QuantileScale,2435\nflare.scale.QuantitativeScale,4839\nflare.scale.RootScale,1756\nflare.scale.Scale,4268\nflare.scale.ScaleType,1821\nflare.scale.TimeScale,5833\nflare.util,\nflare.util.Arrays,8258\nflare.util.Colors,10001\nflare.util.Dates,8217\nflare.util.Displays,12555\nflare.util.Filter,2324\nflare.util.Geometry,10993\nflare.util.heap,\nflare.util.heap.FibonacciHeap,9354\nflare.util.heap.HeapNode,1233\nflare.util.IEvaluable,335\nflare.util.IPredicate,383\nflare.util.IValueProxy,874\nflare.util.math,\nflare.util.math.DenseMatrix,3165\nflare.util.math.IMatrix,2815\nflare.util.math.SparseMatrix,3366\nflare.util.Maths,17705\nflare.util.Orientation,1486\nflare.util.palette,\nflare.util.palette.ColorPalette,6367\nflare.util.palette.Palette,1229\nflare.util.palette.ShapePalette,2059\nflare.util.palette.SizePalette,2291\nflare.util.Property,5559\nflare.util.Shapes,19118\nflare.util.Sort,6887\nflare.util.Stats,6557\nflare.util.Strings,22026\nflare.vis,\nflare.vis.axis,\nflare.vis.axis.Axes,1302\nflare.vis.axis.Axis,24593\nflare.vis.axis.AxisGridLine,652\nflare.vis.axis.AxisLabel,636\nflare.vis.axis.CartesianAxes,6703\nflare.vis.controls,\nflare.vis.controls.AnchorControl,2138\nflare.vis.controls.ClickControl,3824\nflare.vis.controls.Control,1353\nflare.vis.controls.ControlList,4665\nflare.vis.controls.DragControl,2649\nflare.vis.controls.ExpandControl,2832\nflare.vis.controls.HoverControl,4896\nflare.vis.controls.IControl,763\nflare.vis.controls.PanZoomControl,5222\nflare.vis.controls.SelectionControl,7862\nflare.vis.controls.TooltipControl,8435\nflare.vis.data,\nflare.vis.data.Data,20544\nflare.vis.data.DataList,19788\nflare.vis.data.DataSprite,10349\nflare.vis.data.EdgeSprite,3301\nflare.vis.data.NodeSprite,19382\nflare.vis.data.render,\nflare.vis.data.render.ArrowType,698\nflare.vis.data.render.EdgeRenderer,5569\nflare.vis.data.render.IRenderer,353\nflare.vis.data.render.ShapeRenderer,2247\nflare.vis.data.ScaleBinding,11275\nflare.vis.data.Tree,7147\nflare.vis.data.TreeBuilder,9930\nflare.vis.events,\nflare.vis.events.DataEvent,2313\nflare.vis.events.SelectionEvent,1880\nflare.vis.events.TooltipEvent,1701\nflare.vis.events.VisualizationEvent,1117\nflare.vis.legend,\nflare.vis.legend.Legend,20859\nflare.vis.legend.LegendItem,4614\nflare.vis.legend.LegendRange,10530\nflare.vis.operator,\nflare.vis.operator.distortion,\nflare.vis.operator.distortion.BifocalDistortion,4461\nflare.vis.operator.distortion.Distortion,6314\nflare.vis.operator.distortion.FisheyeDistortion,3444\nflare.vis.operator.encoder,\nflare.vis.operator.encoder.ColorEncoder,3179\nflare.vis.operator.encoder.Encoder,4060\nflare.vis.operator.encoder.PropertyEncoder,4138\nflare.vis.operator.encoder.ShapeEncoder,1690\nflare.vis.operator.encoder.SizeEncoder,1830\nflare.vis.operator.filter,\nflare.vis.operator.filter.FisheyeTreeFilter,5219\nflare.vis.operator.filter.GraphDistanceFilter,3165\nflare.vis.operator.filter.VisibilityFilter,3509\nflare.vis.operator.IOperator,1286\nflare.vis.operator.label,\nflare.vis.operator.label.Labeler,9956\nflare.vis.operator.label.RadialLabeler,3899\nflare.vis.operator.label.StackedAreaLabeler,3202\nflare.vis.operator.layout,\nflare.vis.operator.layout.AxisLayout,6725\nflare.vis.operator.layout.BundledEdgeRouter,3727\nflare.vis.operator.layout.CircleLayout,9317\nflare.vis.operator.layout.CirclePackingLayout,12003\nflare.vis.operator.layout.DendrogramLayout,4853\nflare.vis.operator.layout.ForceDirectedLayout,8411\nflare.vis.operator.layout.IcicleTreeLayout,4864\nflare.vis.operator.layout.IndentedTreeLayout,3174\nflare.vis.operator.layout.Layout,7881\nflare.vis.operator.layout.NodeLinkTreeLayout,12870\nflare.vis.operator.layout.PieLayout,2728\nflare.vis.operator.layout.RadialTreeLayout,12348\nflare.vis.operator.layout.RandomLayout,870\nflare.vis.operator.layout.StackedAreaLayout,9121\nflare.vis.operator.layout.TreeMapLayout,9191\nflare.vis.operator.Operator,2490\nflare.vis.operator.OperatorList,5248\nflare.vis.operator.OperatorSequence,4190\nflare.vis.operator.OperatorSwitch,2581\nflare.vis.operator.SortOperator,2023\nflare.vis.Visualization,16540"
  },
  {
    "path": "app_backend/static/js/bootstrap-select.js",
    "content": "/*!\n * Bootstrap-select v1.12.2 (http://silviomoreto.github.io/bootstrap-select)\n *\n * Copyright 2013-2017 bootstrap-select\n * Licensed under MIT (https://github.com/silviomoreto/bootstrap-select/blob/master/LICENSE)\n */\n\n(function (root, factory) {\n  if (typeof define === 'function' && define.amd) {\n    // AMD. Register as an anonymous module unless amdModuleId is set\n    define([\"jquery\"], function (a0) {\n      return (factory(a0));\n    });\n  } else if (typeof module === 'object' && module.exports) {\n    // Node. Does not work with strict CommonJS, but\n    // only CommonJS-like environments that support module.exports,\n    // like Node.\n    module.exports = factory(require(\"jquery\"));\n  } else {\n    factory(root[\"jQuery\"]);\n  }\n}(this, function (jQuery) {\n\n(function ($) {\n  'use strict';\n\n  //<editor-fold desc=\"Shims\">\n  if (!String.prototype.includes) {\n    (function () {\n      'use strict'; // needed to support `apply`/`call` with `undefined`/`null`\n      var toString = {}.toString;\n      var defineProperty = (function () {\n        // IE 8 only supports `Object.defineProperty` on DOM elements\n        try {\n          var object = {};\n          var $defineProperty = Object.defineProperty;\n          var result = $defineProperty(object, object, object) && $defineProperty;\n        } catch (error) {\n        }\n        return result;\n      }());\n      var indexOf = ''.indexOf;\n      var includes = function (search) {\n        if (this == null) {\n          throw new TypeError();\n        }\n        var string = String(this);\n        if (search && toString.call(search) == '[object RegExp]') {\n          throw new TypeError();\n        }\n        var stringLength = string.length;\n        var searchString = String(search);\n        var searchLength = searchString.length;\n        var position = arguments.length > 1 ? arguments[1] : undefined;\n        // `ToInteger`\n        var pos = position ? Number(position) : 0;\n        if (pos != pos) { // better `isNaN`\n          pos = 0;\n        }\n        var start = Math.min(Math.max(pos, 0), stringLength);\n        // Avoid the `indexOf` call if no match is possible\n        if (searchLength + start > stringLength) {\n          return false;\n        }\n        return indexOf.call(string, searchString, pos) != -1;\n      };\n      if (defineProperty) {\n        defineProperty(String.prototype, 'includes', {\n          'value': includes,\n          'configurable': true,\n          'writable': true\n        });\n      } else {\n        String.prototype.includes = includes;\n      }\n    }());\n  }\n\n  if (!String.prototype.startsWith) {\n    (function () {\n      'use strict'; // needed to support `apply`/`call` with `undefined`/`null`\n      var defineProperty = (function () {\n        // IE 8 only supports `Object.defineProperty` on DOM elements\n        try {\n          var object = {};\n          var $defineProperty = Object.defineProperty;\n          var result = $defineProperty(object, object, object) && $defineProperty;\n        } catch (error) {\n        }\n        return result;\n      }());\n      var toString = {}.toString;\n      var startsWith = function (search) {\n        if (this == null) {\n          throw new TypeError();\n        }\n        var string = String(this);\n        if (search && toString.call(search) == '[object RegExp]') {\n          throw new TypeError();\n        }\n        var stringLength = string.length;\n        var searchString = String(search);\n        var searchLength = searchString.length;\n        var position = arguments.length > 1 ? arguments[1] : undefined;\n        // `ToInteger`\n        var pos = position ? Number(position) : 0;\n        if (pos != pos) { // better `isNaN`\n          pos = 0;\n        }\n        var start = Math.min(Math.max(pos, 0), stringLength);\n        // Avoid the `indexOf` call if no match is possible\n        if (searchLength + start > stringLength) {\n          return false;\n        }\n        var index = -1;\n        while (++index < searchLength) {\n          if (string.charCodeAt(start + index) != searchString.charCodeAt(index)) {\n            return false;\n          }\n        }\n        return true;\n      };\n      if (defineProperty) {\n        defineProperty(String.prototype, 'startsWith', {\n          'value': startsWith,\n          'configurable': true,\n          'writable': true\n        });\n      } else {\n        String.prototype.startsWith = startsWith;\n      }\n    }());\n  }\n\n  if (!Object.keys) {\n    Object.keys = function (\n      o, // object\n      k, // key\n      r  // result array\n      ){\n      // initialize object and result\n      r=[];\n      // iterate over object keys\n      for (k in o)\n          // fill result array with non-prototypical keys\n        r.hasOwnProperty.call(o, k) && r.push(k);\n      // return result\n      return r;\n    };\n  }\n\n  // set data-selected on select element if the value has been programmatically selected\n  // prior to initialization of bootstrap-select\n  // * consider removing or replacing an alternative method *\n  var valHooks = {\n    useDefault: false,\n    _set: $.valHooks.select.set\n  };\n\n  $.valHooks.select.set = function(elem, value) {\n    if (value && !valHooks.useDefault) $(elem).data('selected', true);\n\n    return valHooks._set.apply(this, arguments);\n  };\n\n  var changed_arguments = null;\n  $.fn.triggerNative = function (eventName) {\n    var el = this[0],\n        event;\n\n    if (el.dispatchEvent) { // for modern browsers & IE9+\n      if (typeof Event === 'function') {\n        // For modern browsers\n        event = new Event(eventName, {\n          bubbles: true\n        });\n      } else {\n        // For IE since it doesn't support Event constructor\n        event = document.createEvent('Event');\n        event.initEvent(eventName, true, false);\n      }\n\n      el.dispatchEvent(event);\n    } else if (el.fireEvent) { // for IE8\n      event = document.createEventObject();\n      event.eventType = eventName;\n      el.fireEvent('on' + eventName, event);\n    } else {\n      // fall back to jQuery.trigger\n      this.trigger(eventName);\n    }\n  };\n  //</editor-fold>\n\n  // Case insensitive contains search\n  $.expr.pseudos.icontains = function (obj, index, meta) {\n    var $obj = $(obj);\n    var haystack = ($obj.data('tokens') || $obj.text()).toString().toUpperCase();\n    return haystack.includes(meta[3].toUpperCase());\n  };\n\n  // Case insensitive begins search\n  $.expr.pseudos.ibegins = function (obj, index, meta) {\n    var $obj = $(obj);\n    var haystack = ($obj.data('tokens') || $obj.text()).toString().toUpperCase();\n    return haystack.startsWith(meta[3].toUpperCase());\n  };\n\n  // Case and accent insensitive contains search\n  $.expr.pseudos.aicontains = function (obj, index, meta) {\n    var $obj = $(obj);\n    var haystack = ($obj.data('tokens') || $obj.data('normalizedText') || $obj.text()).toString().toUpperCase();\n    return haystack.includes(meta[3].toUpperCase());\n  };\n\n  // Case and accent insensitive begins search\n  $.expr.pseudos.aibegins = function (obj, index, meta) {\n    var $obj = $(obj);\n    var haystack = ($obj.data('tokens') || $obj.data('normalizedText') || $obj.text()).toString().toUpperCase();\n    return haystack.startsWith(meta[3].toUpperCase());\n  };\n\n  /**\n   * Remove all diatrics from the given text.\n   * @access private\n   * @param {String} text\n   * @returns {String}\n   */\n  function normalizeToBase(text) {\n    var rExps = [\n      {re: /[\\xC0-\\xC6]/g, ch: \"A\"},\n      {re: /[\\xE0-\\xE6]/g, ch: \"a\"},\n      {re: /[\\xC8-\\xCB]/g, ch: \"E\"},\n      {re: /[\\xE8-\\xEB]/g, ch: \"e\"},\n      {re: /[\\xCC-\\xCF]/g, ch: \"I\"},\n      {re: /[\\xEC-\\xEF]/g, ch: \"i\"},\n      {re: /[\\xD2-\\xD6]/g, ch: \"O\"},\n      {re: /[\\xF2-\\xF6]/g, ch: \"o\"},\n      {re: /[\\xD9-\\xDC]/g, ch: \"U\"},\n      {re: /[\\xF9-\\xFC]/g, ch: \"u\"},\n      {re: /[\\xC7-\\xE7]/g, ch: \"c\"},\n      {re: /[\\xD1]/g, ch: \"N\"},\n      {re: /[\\xF1]/g, ch: \"n\"}\n    ];\n    $.each(rExps, function () {\n      text = text ? text.replace(this.re, this.ch) : '';\n    });\n    return text;\n  }\n\n\n  // List of HTML entities for escaping.\n  var escapeMap = {\n    '&': '&amp;',\n    '<': '&lt;',\n    '>': '&gt;',\n    '\"': '&quot;',\n    \"'\": '&#x27;',\n    '`': '&#x60;'\n  };\n  \n  var unescapeMap = {\n    '&amp;': '&',\n    '&lt;': '<',\n    '&gt;': '>',\n    '&quot;': '\"',\n    '&#x27;': \"'\",\n    '&#x60;': '`'\n  };\n\n  // Functions for escaping and unescaping strings to/from HTML interpolation.\n  var createEscaper = function(map) {\n    var escaper = function(match) {\n      return map[match];\n    };\n    // Regexes for identifying a key that needs to be escaped.\n    var source = '(?:' + Object.keys(map).join('|') + ')';\n    var testRegexp = RegExp(source);\n    var replaceRegexp = RegExp(source, 'g');\n    return function(string) {\n      string = string == null ? '' : '' + string;\n      return testRegexp.test(string) ? string.replace(replaceRegexp, escaper) : string;\n    };\n  };\n\n  var htmlEscape = createEscaper(escapeMap);\n  var htmlUnescape = createEscaper(unescapeMap);\n\n  var Selectpicker = function (element, options) {\n    // bootstrap-select has been initialized - revert valHooks.select.set back to its original function\n    if (!valHooks.useDefault) {\n      $.valHooks.select.set = valHooks._set;\n      valHooks.useDefault = true;\n    }\n\n    this.$element = $(element);\n    this.$newElement = null;\n    this.$button = null;\n    this.$menu = null;\n    this.$lis = null;\n    this.options = options;\n\n    // If we have no title yet, try to pull it from the html title attribute (jQuery doesnt' pick it up as it's not a\n    // data-attribute)\n    if (this.options.title === null) {\n      this.options.title = this.$element.attr('title');\n    }\n\n    // Format window padding\n    var winPad = this.options.windowPadding;\n    if (typeof winPad === 'number') {\n      this.options.windowPadding = [winPad, winPad, winPad, winPad];\n    }\n\n    //Expose public methods\n    this.val = Selectpicker.prototype.val;\n    this.render = Selectpicker.prototype.render;\n    this.refresh = Selectpicker.prototype.refresh;\n    this.setStyle = Selectpicker.prototype.setStyle;\n    this.selectAll = Selectpicker.prototype.selectAll;\n    this.deselectAll = Selectpicker.prototype.deselectAll;\n    this.destroy = Selectpicker.prototype.destroy;\n    this.remove = Selectpicker.prototype.remove;\n    this.show = Selectpicker.prototype.show;\n    this.hide = Selectpicker.prototype.hide;\n\n    this.init();\n  };\n\n  Selectpicker.VERSION = '1.12.2';\n\n  // part of this is duplicated in i18n/defaults-en_US.js. Make sure to update both.\n  Selectpicker.DEFAULTS = {\n    noneSelectedText: 'Nothing selected',\n    noneResultsText: 'No results matched {0}',\n    countSelectedText: function (numSelected, numTotal) {\n      return (numSelected == 1) ? \"{0} item selected\" : \"{0} items selected\";\n    },\n    maxOptionsText: function (numAll, numGroup) {\n      return [\n        (numAll == 1) ? 'Limit reached ({n} item max)' : 'Limit reached ({n} items max)',\n        (numGroup == 1) ? 'Group limit reached ({n} item max)' : 'Group limit reached ({n} items max)'\n      ];\n    },\n    selectAllText: 'Select All',\n    deselectAllText: 'Deselect All',\n    doneButton: false,\n    doneButtonText: 'Close',\n    multipleSeparator: ', ',\n    styleBase: 'btn',\n    style: 'btn-default',\n    size: 'auto',\n    title: null,\n    selectedTextFormat: 'values',\n    width: false,\n    container: false,\n    hideDisabled: false,\n    showSubtext: false,\n    showIcon: true,\n    showContent: true,\n    dropupAuto: true,\n    header: false,\n    liveSearch: false,\n    liveSearchPlaceholder: null,\n    liveSearchNormalize: false,\n    liveSearchStyle: 'contains',\n    actionsBox: false,\n    iconBase: 'glyphicon',\n    tickIcon: 'glyphicon-ok',\n    showTick: false,\n    template: {\n      caret: '<span class=\"caret\"></span>'\n    },\n    maxOptions: false,\n    mobile: false,\n    selectOnTab: false,\n    dropdownAlignRight: false,\n    windowPadding: 0\n  };\n\n  Selectpicker.prototype = {\n\n    constructor: Selectpicker,\n\n    init: function () {\n      var that = this,\n          id = this.$element.attr('id');\n\n      this.$element.addClass('bs-select-hidden');\n\n      // store originalIndex (key) and newIndex (value) in this.liObj for fast accessibility\n      // allows us to do this.$lis.eq(that.liObj[index]) instead of this.$lis.filter('[data-original-index=\"' + index + '\"]')\n      this.liObj = {};\n      this.multiple = this.$element.prop('multiple');\n      this.autofocus = this.$element.prop('autofocus');\n      this.$newElement = this.createView();\n      this.$element\n        .after(this.$newElement)\n        .appendTo(this.$newElement);\n      this.$button = this.$newElement.children('button');\n      this.$menu = this.$newElement.children('.dropdown-menu');\n      this.$menuInner = this.$menu.children('.inner');\n      this.$searchbox = this.$menu.find('input');\n\n      this.$element.removeClass('bs-select-hidden');\n\n      if (this.options.dropdownAlignRight === true) this.$menu.addClass('dropdown-menu-right');\n\n      if (typeof id !== 'undefined') {\n        this.$button.attr('data-id', id);\n        $('label[for=\"' + id + '\"]').click(function (e) {\n          e.preventDefault();\n          that.$button.focus();\n        });\n      }\n\n      this.checkDisabled();\n      this.clickListener();\n      if (this.options.liveSearch) this.liveSearchListener();\n      this.render();\n      this.setStyle();\n      this.setWidth();\n      if (this.options.container) this.selectPosition();\n      this.$menu.data('this', this);\n      this.$newElement.data('this', this);\n      if (this.options.mobile) this.mobile();\n\n      this.$newElement.on({\n        'hide.bs.dropdown': function (e) {\n          that.$menuInner.attr('aria-expanded', false);\n          that.$element.trigger('hide.bs.select', e);\n        },\n        'hidden.bs.dropdown': function (e) {\n          that.$element.trigger('hidden.bs.select', e);\n        },\n        'show.bs.dropdown': function (e) {\n          that.$menuInner.attr('aria-expanded', true);\n          that.$element.trigger('show.bs.select', e);\n        },\n        'shown.bs.dropdown': function (e) {\n          that.$element.trigger('shown.bs.select', e);\n        }\n      });\n\n      if (that.$element[0].hasAttribute('required')) {\n        this.$element.on('invalid', function () {\n          that.$button\n            .addClass('bs-invalid')\n            .focus();\n\n          that.$element.on({\n            'focus.bs.select': function () {\n              that.$button.focus();\n              that.$element.off('focus.bs.select');\n            },\n            'shown.bs.select': function () {\n              that.$element\n                .val(that.$element.val()) // set the value to hide the validation message in Chrome when menu is opened\n                .off('shown.bs.select');\n            },\n            'rendered.bs.select': function () {\n              // if select is no longer invalid, remove the bs-invalid class\n              if (this.validity.valid) that.$button.removeClass('bs-invalid');\n              that.$element.off('rendered.bs.select');\n            }\n          });\n        });\n      }\n\n      setTimeout(function () {\n        that.$element.trigger('loaded.bs.select');\n      });\n    },\n\n    createDropdown: function () {\n      // Options\n      // If we are multiple or showTick option is set, then add the show-tick class\n      var showTick = (this.multiple || this.options.showTick) ? ' show-tick' : '',\n          inputGroup = this.$element.parent().hasClass('input-group') ? ' input-group-btn' : '',\n          autofocus = this.autofocus ? ' autofocus' : '';\n      // Elements\n      var header = this.options.header ? '<div class=\"popover-title\"><button type=\"button\" class=\"close\" aria-hidden=\"true\">&times;</button>' + this.options.header + '</div>' : '';\n      var searchbox = this.options.liveSearch ?\n      '<div class=\"bs-searchbox\">' +\n      '<input type=\"text\" class=\"form-control\" autocomplete=\"off\"' +\n      (null === this.options.liveSearchPlaceholder ? '' : ' placeholder=\"' + htmlEscape(this.options.liveSearchPlaceholder) + '\"') + ' role=\"textbox\" aria-label=\"Search\">' +\n      '</div>'\n          : '';\n      var actionsbox = this.multiple && this.options.actionsBox ?\n      '<div class=\"bs-actionsbox\">' +\n      '<div class=\"btn-group btn-group-sm btn-block\">' +\n      '<button type=\"button\" class=\"actions-btn bs-select-all btn btn-default\">' +\n      this.options.selectAllText +\n      '</button>' +\n      '<button type=\"button\" class=\"actions-btn bs-deselect-all btn btn-default\">' +\n      this.options.deselectAllText +\n      '</button>' +\n      '</div>' +\n      '</div>'\n          : '';\n      var donebutton = this.multiple && this.options.doneButton ?\n      '<div class=\"bs-donebutton\">' +\n      '<div class=\"btn-group btn-block\">' +\n      '<button type=\"button\" class=\"btn btn-sm btn-default\">' +\n      this.options.doneButtonText +\n      '</button>' +\n      '</div>' +\n      '</div>'\n          : '';\n      var drop =\n          '<div class=\"btn-group bootstrap-select' + showTick + inputGroup + '\">' +\n          '<button type=\"button\" class=\"' + this.options.styleBase + ' dropdown-toggle\" data-toggle=\"dropdown\"' + autofocus + ' role=\"button\">' +\n          '<span class=\"filter-option pull-left\"></span>&nbsp;' +\n          '<span class=\"bs-caret\">' +\n          this.options.template.caret +\n          '</span>' +\n          '</button>' +\n          '<div class=\"dropdown-menu open\" role=\"combobox\">' +\n          header +\n          searchbox +\n          actionsbox +\n          '<ul class=\"dropdown-menu inner\" role=\"listbox\" aria-expanded=\"false\">' +\n          '</ul>' +\n          donebutton +\n          '</div>' +\n          '</div>';\n\n      return $(drop);\n    },\n\n    createView: function () {\n      var $drop = this.createDropdown(),\n          li = this.createLi();\n\n      $drop.find('ul')[0].innerHTML = li;\n      return $drop;\n    },\n\n    reloadLi: function () {\n      // rebuild\n      var li = this.createLi();\n      this.$menuInner[0].innerHTML = li;\n    },\n\n    createLi: function () {\n      var that = this,\n          _li = [],\n          optID = 0,\n          titleOption = document.createElement('option'),\n          liIndex = -1; // increment liIndex whenever a new <li> element is created to ensure liObj is correct\n\n      // Helper functions\n      /**\n       * @param content\n       * @param [index]\n       * @param [classes]\n       * @param [optgroup]\n       * @returns {string}\n       */\n      var generateLI = function (content, index, classes, optgroup) {\n        return '<li' +\n            ((typeof classes !== 'undefined' & '' !== classes) ? ' class=\"' + classes + '\"' : '') +\n            ((typeof index !== 'undefined' & null !== index) ? ' data-original-index=\"' + index + '\"' : '') +\n            ((typeof optgroup !== 'undefined' & null !== optgroup) ? 'data-optgroup=\"' + optgroup + '\"' : '') +\n            '>' + content + '</li>';\n      };\n\n      /**\n       * @param text\n       * @param [classes]\n       * @param [inline]\n       * @param [tokens]\n       * @returns {string}\n       */\n      var generateA = function (text, classes, inline, tokens) {\n        return '<a tabindex=\"0\"' +\n            (typeof classes !== 'undefined' ? ' class=\"' + classes + '\"' : '') +\n            (inline ? ' style=\"' + inline + '\"' : '') +\n            (that.options.liveSearchNormalize ? ' data-normalized-text=\"' + normalizeToBase(htmlEscape($(text).html())) + '\"' : '') +\n            (typeof tokens !== 'undefined' || tokens !== null ? ' data-tokens=\"' + tokens + '\"' : '') +\n            ' role=\"option\">' + text +\n            '<span class=\"' + that.options.iconBase + ' ' + that.options.tickIcon + ' check-mark\"></span>' +\n            '</a>';\n      };\n\n      if (this.options.title && !this.multiple) {\n        // this option doesn't create a new <li> element, but does add a new option, so liIndex is decreased\n        // since liObj is recalculated on every refresh, liIndex needs to be decreased even if the titleOption is already appended\n        liIndex--;\n\n        if (!this.$element.find('.bs-title-option').length) {\n          // Use native JS to prepend option (faster)\n          var element = this.$element[0];\n          titleOption.className = 'bs-title-option';\n          titleOption.innerHTML = this.options.title;\n          titleOption.value = '';\n          element.insertBefore(titleOption, element.firstChild);\n          // Check if selected or data-selected attribute is already set on an option. If not, select the titleOption option.\n          // the selected item may have been changed by user or programmatically before the bootstrap select plugin runs,\n          // if so, the select will have the data-selected attribute\n          var $opt = $(element.options[element.selectedIndex]);\n          if ($opt.attr('selected') === undefined && this.$element.data('selected') === undefined) {\n            titleOption.selected = true;\n          }\n        }\n      }\n\n      this.$element.find('option').each(function (index) {\n        var $this = $(this);\n\n        liIndex++;\n\n        if ($this.hasClass('bs-title-option')) return;\n\n        // Get the class and text for the option\n        var optionClass = this.className || '',\n            inline = this.style.cssText,\n            text = $this.data('content') ? $this.data('content') : $this.html(),\n            tokens = $this.data('tokens') ? $this.data('tokens') : null,\n            subtext = typeof $this.data('subtext') !== 'undefined' ? '<small class=\"text-muted\">' + $this.data('subtext') + '</small>' : '',\n            icon = typeof $this.data('icon') !== 'undefined' ? '<span class=\"' + that.options.iconBase + ' ' + $this.data('icon') + '\"></span> ' : '',\n            $parent = $this.parent(),\n            isOptgroup = $parent[0].tagName === 'OPTGROUP',\n            isOptgroupDisabled = isOptgroup && $parent[0].disabled,\n            isDisabled = this.disabled || isOptgroupDisabled;\n\n        if (icon !== '' && isDisabled) {\n          icon = '<span>' + icon + '</span>';\n        }\n\n        if (that.options.hideDisabled && (isDisabled && !isOptgroup || isOptgroupDisabled)) {\n          liIndex--;\n          return;\n        }\n\n        if (!$this.data('content')) {\n          // Prepend any icon and append any subtext to the main text.\n          text = icon + '<span class=\"text\">' + text + subtext + '</span>';\n        }\n\n        if (isOptgroup && $this.data('divider') !== true) {\n          if (that.options.hideDisabled && isDisabled) {\n            if ($parent.data('allOptionsDisabled') === undefined) {\n              var $options = $parent.children();\n              $parent.data('allOptionsDisabled', $options.filter(':disabled').length === $options.length);\n            }\n\n            if ($parent.data('allOptionsDisabled')) {\n              liIndex--;\n              return;\n            }\n          }\n\n          var optGroupClass = ' ' + $parent[0].className || '';\n\n          if ($this.index() === 0) { // Is it the first option of the optgroup?\n            optID += 1;\n\n            // Get the opt group label\n            var label = $parent[0].label,\n                labelSubtext = typeof $parent.data('subtext') !== 'undefined' ? '<small class=\"text-muted\">' + $parent.data('subtext') + '</small>' : '',\n                labelIcon = $parent.data('icon') ? '<span class=\"' + that.options.iconBase + ' ' + $parent.data('icon') + '\"></span> ' : '';\n\n            label = labelIcon + '<span class=\"text\">' + htmlEscape(label) + labelSubtext + '</span>';\n\n            if (index !== 0 && _li.length > 0) { // Is it NOT the first option of the select && are there elements in the dropdown?\n              liIndex++;\n              _li.push(generateLI('', null, 'divider', optID + 'div'));\n            }\n            liIndex++;\n            _li.push(generateLI(label, null, 'dropdown-header' + optGroupClass, optID));\n          }\n\n          if (that.options.hideDisabled && isDisabled) {\n            liIndex--;\n            return;\n          }\n\n          _li.push(generateLI(generateA(text, 'opt ' + optionClass + optGroupClass, inline, tokens), index, '', optID));\n        } else if ($this.data('divider') === true) {\n          _li.push(generateLI('', index, 'divider'));\n        } else if ($this.data('hidden') === true) {\n          _li.push(generateLI(generateA(text, optionClass, inline, tokens), index, 'hidden is-hidden'));\n        } else {\n          var showDivider = this.previousElementSibling && this.previousElementSibling.tagName === 'OPTGROUP';\n\n          // if previous element is not an optgroup and hideDisabled is true\n          if (!showDivider && that.options.hideDisabled) {\n            // get previous elements\n            var $prev = $(this).prevAll();\n\n            for (var i = 0; i < $prev.length; i++) {\n              // find the first element in the previous elements that is an optgroup\n              if ($prev[i].tagName === 'OPTGROUP') {\n                var optGroupDistance = 0;\n\n                // loop through the options in between the current option and the optgroup\n                // and check if they are hidden or disabled\n                for (var d = 0; d < i; d++) {\n                  var prevOption = $prev[d];\n                  if (prevOption.disabled || $(prevOption).data('hidden') === true) optGroupDistance++;\n                }\n\n                // if all of the options between the current option and the optgroup are hidden or disabled, show the divider\n                if (optGroupDistance === i) showDivider = true;\n\n                break;\n              }\n            }\n          }\n\n          if (showDivider) {\n            liIndex++;\n            _li.push(generateLI('', null, 'divider', optID + 'div'));\n          }\n          _li.push(generateLI(generateA(text, optionClass, inline, tokens), index));\n        }\n\n        that.liObj[index] = liIndex;\n      });\n\n      //If we are not multiple, we don't have a selected item, and we don't have a title, select the first element so something is set in the button\n      if (!this.multiple && this.$element.find('option:selected').length === 0 && !this.options.title) {\n        this.$element.find('option').eq(0).prop('selected', true).attr('selected', 'selected');\n      }\n\n      return _li.join('');\n    },\n\n    findLis: function () {\n      if (this.$lis == null) this.$lis = this.$menu.find('li');\n      return this.$lis;\n    },\n\n    /**\n     * @param [updateLi] defaults to true\n     */\n    render: function (updateLi) {\n      var that = this,\n          notDisabled;\n\n      //Update the LI to match the SELECT\n      if (updateLi !== false) {\n        this.$element.find('option').each(function (index) {\n          var $lis = that.findLis().eq(that.liObj[index]);\n\n          that.setDisabled(index, this.disabled || this.parentNode.tagName === 'OPTGROUP' && this.parentNode.disabled, $lis);\n          that.setSelected(index, this.selected, $lis);\n        });\n      }\n\n      this.togglePlaceholder();\n\n      this.tabIndex();\n\n      var selectedItems = this.$element.find('option').map(function () {\n        if (this.selected) {\n          if (that.options.hideDisabled && (this.disabled || this.parentNode.tagName === 'OPTGROUP' && this.parentNode.disabled)) return;\n\n          var $this = $(this),\n              icon = $this.data('icon') && that.options.showIcon ? '<i class=\"' + that.options.iconBase + ' ' + $this.data('icon') + '\"></i> ' : '',\n              subtext;\n\n          if (that.options.showSubtext && $this.data('subtext') && !that.multiple) {\n            subtext = ' <small class=\"text-muted\">' + $this.data('subtext') + '</small>';\n          } else {\n            subtext = '';\n          }\n          if (typeof $this.attr('title') !== 'undefined') {\n            return $this.attr('title');\n          } else if ($this.data('content') && that.options.showContent) {\n            return $this.data('content').toString();\n          } else {\n            return icon + $this.html() + subtext;\n          }\n        }\n      }).toArray();\n\n      //Fixes issue in IE10 occurring when no default option is selected and at least one option is disabled\n      //Convert all the values into a comma delimited string\n      var title = !this.multiple ? selectedItems[0] : selectedItems.join(this.options.multipleSeparator);\n\n      //If this is multi select, and the selectText type is count, the show 1 of 2 selected etc..\n      if (this.multiple && this.options.selectedTextFormat.indexOf('count') > -1) {\n        var max = this.options.selectedTextFormat.split('>');\n        if ((max.length > 1 && selectedItems.length > max[1]) || (max.length == 1 && selectedItems.length >= 2)) {\n          notDisabled = this.options.hideDisabled ? ', [disabled]' : '';\n          var totalCount = this.$element.find('option').not('[data-divider=\"true\"], [data-hidden=\"true\"]' + notDisabled).length,\n              tr8nText = (typeof this.options.countSelectedText === 'function') ? this.options.countSelectedText(selectedItems.length, totalCount) : this.options.countSelectedText;\n          title = tr8nText.replace('{0}', selectedItems.length.toString()).replace('{1}', totalCount.toString());\n        }\n      }\n\n      if (this.options.title == undefined) {\n        this.options.title = this.$element.attr('title');\n      }\n\n      if (this.options.selectedTextFormat == 'static') {\n        title = this.options.title;\n      }\n\n      //If we dont have a title, then use the default, or if nothing is set at all, use the not selected text\n      if (!title) {\n        title = typeof this.options.title !== 'undefined' ? this.options.title : this.options.noneSelectedText;\n      }\n\n      //strip all HTML tags and trim the result, then unescape any escaped tags\n      this.$button.attr('title', htmlUnescape($.trim(title.replace(/<[^>]*>?/g, ''))));\n      this.$button.children('.filter-option').html(title);\n\n      this.$element.trigger('rendered.bs.select');\n    },\n\n    /**\n     * @param [style]\n     * @param [status]\n     */\n    setStyle: function (style, status) {\n      if (this.$element.attr('class')) {\n        this.$newElement.addClass(this.$element.attr('class').replace(/selectpicker|mobile-device|bs-select-hidden|validate\\[.*\\]/gi, ''));\n      }\n\n      var buttonClass = style ? style : this.options.style;\n\n      if (status == 'add') {\n        this.$button.addClass(buttonClass);\n      } else if (status == 'remove') {\n        this.$button.removeClass(buttonClass);\n      } else {\n        this.$button.removeClass(this.options.style);\n        this.$button.addClass(buttonClass);\n      }\n    },\n\n    liHeight: function (refresh) {\n      if (!refresh && (this.options.size === false || this.sizeInfo)) return;\n\n      var newElement = document.createElement('div'),\n          menu = document.createElement('div'),\n          menuInner = document.createElement('ul'),\n          divider = document.createElement('li'),\n          li = document.createElement('li'),\n          a = document.createElement('a'),\n          text = document.createElement('span'),\n          header = this.options.header && this.$menu.find('.popover-title').length > 0 ? this.$menu.find('.popover-title')[0].cloneNode(true) : null,\n          search = this.options.liveSearch ? document.createElement('div') : null,\n          actions = this.options.actionsBox && this.multiple && this.$menu.find('.bs-actionsbox').length > 0 ? this.$menu.find('.bs-actionsbox')[0].cloneNode(true) : null,\n          doneButton = this.options.doneButton && this.multiple && this.$menu.find('.bs-donebutton').length > 0 ? this.$menu.find('.bs-donebutton')[0].cloneNode(true) : null;\n\n      text.className = 'text';\n      newElement.className = this.$menu[0].parentNode.className + ' open';\n      menu.className = 'dropdown-menu open';\n      menuInner.className = 'dropdown-menu inner';\n      divider.className = 'divider';\n\n      text.appendChild(document.createTextNode('Inner text'));\n      a.appendChild(text);\n      li.appendChild(a);\n      menuInner.appendChild(li);\n      menuInner.appendChild(divider);\n      if (header) menu.appendChild(header);\n      if (search) {\n        var input = document.createElement('input');\n        search.className = 'bs-searchbox';\n        input.className = 'form-control';\n        search.appendChild(input);\n        menu.appendChild(search);\n      }\n      if (actions) menu.appendChild(actions);\n      menu.appendChild(menuInner);\n      if (doneButton) menu.appendChild(doneButton);\n      newElement.appendChild(menu);\n\n      document.body.appendChild(newElement);\n\n      var liHeight = a.offsetHeight,\n          headerHeight = header ? header.offsetHeight : 0,\n          searchHeight = search ? search.offsetHeight : 0,\n          actionsHeight = actions ? actions.offsetHeight : 0,\n          doneButtonHeight = doneButton ? doneButton.offsetHeight : 0,\n          dividerHeight = $(divider).outerHeight(true),\n          // fall back to jQuery if getComputedStyle is not supported\n          menuStyle = typeof getComputedStyle === 'function' ? getComputedStyle(menu) : false,\n          $menu = menuStyle ? null : $(menu),\n          menuPadding = {\n            vert: parseInt(menuStyle ? menuStyle.paddingTop : $menu.css('paddingTop')) +\n                  parseInt(menuStyle ? menuStyle.paddingBottom : $menu.css('paddingBottom')) +\n                  parseInt(menuStyle ? menuStyle.borderTopWidth : $menu.css('borderTopWidth')) +\n                  parseInt(menuStyle ? menuStyle.borderBottomWidth : $menu.css('borderBottomWidth')),\n            horiz: parseInt(menuStyle ? menuStyle.paddingLeft : $menu.css('paddingLeft')) +\n                  parseInt(menuStyle ? menuStyle.paddingRight : $menu.css('paddingRight')) +\n                  parseInt(menuStyle ? menuStyle.borderLeftWidth : $menu.css('borderLeftWidth')) +\n                  parseInt(menuStyle ? menuStyle.borderRightWidth : $menu.css('borderRightWidth'))\n          },\n          menuExtras =  {\n            vert: menuPadding.vert +\n                  parseInt(menuStyle ? menuStyle.marginTop : $menu.css('marginTop')) +\n                  parseInt(menuStyle ? menuStyle.marginBottom : $menu.css('marginBottom')) + 2,\n            horiz: menuPadding.horiz +\n                  parseInt(menuStyle ? menuStyle.marginLeft : $menu.css('marginLeft')) +\n                  parseInt(menuStyle ? menuStyle.marginRight : $menu.css('marginRight')) + 2\n          }\n\n      document.body.removeChild(newElement);\n\n      this.sizeInfo = {\n        liHeight: liHeight,\n        headerHeight: headerHeight,\n        searchHeight: searchHeight,\n        actionsHeight: actionsHeight,\n        doneButtonHeight: doneButtonHeight,\n        dividerHeight: dividerHeight,\n        menuPadding: menuPadding,\n        menuExtras: menuExtras\n      };\n    },\n\n    setSize: function () {\n      this.findLis();\n      this.liHeight();\n\n      if (this.options.header) this.$menu.css('padding-top', 0);\n      if (this.options.size === false) return;\n\n      var that = this,\n          $menu = this.$menu,\n          $menuInner = this.$menuInner,\n          $window = $(window),\n          selectHeight = this.$newElement[0].offsetHeight,\n          selectWidth = this.$newElement[0].offsetWidth,\n          liHeight = this.sizeInfo['liHeight'],\n          headerHeight = this.sizeInfo['headerHeight'],\n          searchHeight = this.sizeInfo['searchHeight'],\n          actionsHeight = this.sizeInfo['actionsHeight'],\n          doneButtonHeight = this.sizeInfo['doneButtonHeight'],\n          divHeight = this.sizeInfo['dividerHeight'],\n          menuPadding = this.sizeInfo['menuPadding'],\n          menuExtras = this.sizeInfo['menuExtras'],\n          notDisabled = this.options.hideDisabled ? '.disabled' : '',\n          menuHeight,\n          menuWidth,\n          getHeight,\n          getWidth,\n          selectOffsetTop,\n          selectOffsetBot,\n          selectOffsetLeft,\n          selectOffsetRight,\n          getPos = function() {\n            var pos = that.$newElement.offset(),\n                $container = $(that.options.container),\n                containerPos;\n\n            if (that.options.container && !$container.is('body')) {\n              containerPos = $container.offset();\n              containerPos.top += parseInt($container.css('borderTopWidth'));\n              containerPos.left += parseInt($container.css('borderLeftWidth'));\n            } else {\n              containerPos = { top: 0, left: 0 };\n            }\n\n            var winPad = that.options.windowPadding;\n            selectOffsetTop = pos.top - containerPos.top - $window.scrollTop();\n            selectOffsetBot = $window.height() - selectOffsetTop - selectHeight - containerPos.top - winPad[2];\n            selectOffsetLeft = pos.left - containerPos.left - $window.scrollLeft();\n            selectOffsetRight = $window.width() - selectOffsetLeft - selectWidth - containerPos.left - winPad[1];\n            selectOffsetTop -= winPad[0];\n            selectOffsetLeft -= winPad[3];\n          };\n\n      getPos();\n\n      if (this.options.size === 'auto') {\n        var getSize = function () {\n          var minHeight,\n              hasClass = function (className, include) {\n                return function (element) {\n                    if (include) {\n                        return (element.classList ? element.classList.contains(className) : $(element).hasClass(className));\n                    } else {\n                        return !(element.classList ? element.classList.contains(className) : $(element).hasClass(className));\n                    }\n                };\n              },\n              lis = that.$menuInner[0].getElementsByTagName('li'),\n              lisVisible = Array.prototype.filter ? Array.prototype.filter.call(lis, hasClass('hidden', false)) : that.$lis.not('.hidden'),\n              optGroup = Array.prototype.filter ? Array.prototype.filter.call(lisVisible, hasClass('dropdown-header', true)) : lisVisible.filter('.dropdown-header');\n\n          getPos();\n          menuHeight = selectOffsetBot - menuExtras.vert;\n          menuWidth = selectOffsetRight - menuExtras.horiz;\n\n          if (that.options.container) {\n            if (!$menu.data('height')) $menu.data('height', $menu.height());\n            getHeight = $menu.data('height');\n\n            if (!$menu.data('width')) $menu.data('width', $menu.width());\n            getWidth = $menu.data('width');\n          } else {\n            getHeight = $menu.height();\n            getWidth = $menu.width();\n          }\n\n          if (that.options.dropupAuto) {\n            that.$newElement.toggleClass('dropup', selectOffsetTop > selectOffsetBot && (menuHeight - menuExtras.vert) < getHeight);\n          }\n\n          if (that.$newElement.hasClass('dropup')) {\n            menuHeight = selectOffsetTop - menuExtras.vert;\n          }\n\n          if (that.options.dropdownAlignRight === 'auto') {\n            $menu.toggleClass('dropdown-menu-right', selectOffsetLeft > selectOffsetRight && (menuWidth - menuExtras.horiz) < (getWidth - selectWidth));\n          }\n\n          if ((lisVisible.length + optGroup.length) > 3) {\n            minHeight = liHeight * 3 + menuExtras.vert - 2;\n          } else {\n            minHeight = 0;\n          }\n\n          $menu.css({\n            'max-height': menuHeight + 'px',\n            'overflow': 'hidden',\n            'min-height': minHeight + headerHeight + searchHeight + actionsHeight + doneButtonHeight + 'px'\n          });\n          $menuInner.css({\n            'max-height': menuHeight - headerHeight - searchHeight - actionsHeight - doneButtonHeight - menuPadding.vert + 'px',\n            'overflow-y': 'auto',\n            'min-height': Math.max(minHeight - menuPadding.vert, 0) + 'px'\n          });\n        };\n        getSize();\n        this.$searchbox.off('input.getSize propertychange.getSize').on('input.getSize propertychange.getSize', getSize);\n        $window.off('resize.getSize scroll.getSize').on('resize.getSize scroll.getSize', getSize);\n      } else if (this.options.size && this.options.size != 'auto' && this.$lis.not(notDisabled).length > this.options.size) {\n        var optIndex = this.$lis.not('.divider').not(notDisabled).children().slice(0, this.options.size).last().parent().index(),\n            divLength = this.$lis.slice(0, optIndex + 1).filter('.divider').length;\n        menuHeight = liHeight * this.options.size + divLength * divHeight + menuPadding.vert;\n\n        if (that.options.container) {\n          if (!$menu.data('height')) $menu.data('height', $menu.height());\n          getHeight = $menu.data('height');\n        } else {\n          getHeight = $menu.height();\n        }\n\n        if (that.options.dropupAuto) {\n          //noinspection JSUnusedAssignment\n          this.$newElement.toggleClass('dropup', selectOffsetTop > selectOffsetBot && (menuHeight - menuExtras.vert) < getHeight);\n        }\n        $menu.css({\n          'max-height': menuHeight + headerHeight + searchHeight + actionsHeight + doneButtonHeight + 'px',\n          'overflow': 'hidden',\n          'min-height': ''\n        });\n        $menuInner.css({\n          'max-height': menuHeight - menuPadding.vert + 'px',\n          'overflow-y': 'auto',\n          'min-height': ''\n        });\n      }\n    },\n\n    setWidth: function () {\n      if (this.options.width === 'auto') {\n        this.$menu.css('min-width', '0');\n\n        // Get correct width if element is hidden\n        var $selectClone = this.$menu.parent().clone().appendTo('body'),\n            $selectClone2 = this.options.container ? this.$newElement.clone().appendTo('body') : $selectClone,\n            ulWidth = $selectClone.children('.dropdown-menu').outerWidth(),\n            btnWidth = $selectClone2.css('width', 'auto').children('button').outerWidth();\n\n        $selectClone.remove();\n        $selectClone2.remove();\n\n        // Set width to whatever's larger, button title or longest option\n        this.$newElement.css('width', Math.max(ulWidth, btnWidth) + 'px');\n      } else if (this.options.width === 'fit') {\n        // Remove inline min-width so width can be changed from 'auto'\n        this.$menu.css('min-width', '');\n        this.$newElement.css('width', '').addClass('fit-width');\n      } else if (this.options.width) {\n        // Remove inline min-width so width can be changed from 'auto'\n        this.$menu.css('min-width', '');\n        this.$newElement.css('width', this.options.width);\n      } else {\n        // Remove inline min-width/width so width can be changed\n        this.$menu.css('min-width', '');\n        this.$newElement.css('width', '');\n      }\n      // Remove fit-width class if width is changed programmatically\n      if (this.$newElement.hasClass('fit-width') && this.options.width !== 'fit') {\n        this.$newElement.removeClass('fit-width');\n      }\n    },\n\n    selectPosition: function () {\n      this.$bsContainer = $('<div class=\"bs-container\" />');\n\n      var that = this,\n          $container = $(this.options.container),\n          pos,\n          containerPos,\n          actualHeight,\n          getPlacement = function ($element) {\n            that.$bsContainer.addClass($element.attr('class').replace(/form-control|fit-width/gi, '')).toggleClass('dropup', $element.hasClass('dropup'));\n            pos = $element.offset();\n\n            if (!$container.is('body')) {\n              containerPos = $container.offset();\n              containerPos.top += parseInt($container.css('borderTopWidth')) - $container.scrollTop();\n              containerPos.left += parseInt($container.css('borderLeftWidth')) - $container.scrollLeft();\n            } else {\n              containerPos = { top: 0, left: 0 };\n            }\n\n            actualHeight = $element.hasClass('dropup') ? 0 : $element[0].offsetHeight;\n\n            that.$bsContainer.css({\n              'top': pos.top - containerPos.top + actualHeight,\n              'left': pos.left - containerPos.left,\n              'width': $element[0].offsetWidth\n            });\n          };\n\n      this.$button.on('click', function () {\n        var $this = $(this);\n\n        if (that.isDisabled()) {\n          return;\n        }\n\n        getPlacement(that.$newElement);\n\n        that.$bsContainer\n          .appendTo(that.options.container)\n          .toggleClass('open', !$this.hasClass('open'))\n          .append(that.$menu);\n      });\n\n      $(window).on('resize scroll', function () {\n        getPlacement(that.$newElement);\n      });\n\n      this.$element.on('hide.bs.select', function () {\n        that.$menu.data('height', that.$menu.height());\n        that.$bsContainer.detach();\n      });\n    },\n\n    /**\n     * @param {number} index - the index of the option that is being changed\n     * @param {boolean} selected - true if the option is being selected, false if being deselected\n     * @param {JQuery} $lis - the 'li' element that is being modified\n     */\n    setSelected: function (index, selected, $lis) {\n      if (!$lis) {\n        this.togglePlaceholder(); // check if setSelected is being called by changing the value of the select\n        $lis = this.findLis().eq(this.liObj[index]);\n      }\n\n      $lis.toggleClass('selected', selected).find('a').attr('aria-selected', selected);\n    },\n\n    /**\n     * @param {number} index - the index of the option that is being disabled\n     * @param {boolean} disabled - true if the option is being disabled, false if being enabled\n     * @param {JQuery} $lis - the 'li' element that is being modified\n     */\n    setDisabled: function (index, disabled, $lis) {\n      if (!$lis) {\n        $lis = this.findLis().eq(this.liObj[index]);\n      }\n\n      if (disabled) {\n        $lis.addClass('disabled').children('a').attr('href', '#').attr('tabindex', -1).attr('aria-disabled', true);\n      } else {\n        $lis.removeClass('disabled').children('a').removeAttr('href').attr('tabindex', 0).attr('aria-disabled', false);\n      }\n    },\n\n    isDisabled: function () {\n      return this.$element[0].disabled;\n    },\n\n    checkDisabled: function () {\n      var that = this;\n\n      if (this.isDisabled()) {\n        this.$newElement.addClass('disabled');\n        this.$button.addClass('disabled').attr('tabindex', -1).attr('aria-disabled', true);\n      } else {\n        if (this.$button.hasClass('disabled')) {\n          this.$newElement.removeClass('disabled');\n          this.$button.removeClass('disabled').attr('aria-disabled', false);\n        }\n\n        if (this.$button.attr('tabindex') == -1 && !this.$element.data('tabindex')) {\n          this.$button.removeAttr('tabindex');\n        }\n      }\n\n      this.$button.click(function () {\n        return !that.isDisabled();\n      });\n    },\n\n    togglePlaceholder: function () {\n      var value = this.$element.val();\n      this.$button.toggleClass('bs-placeholder', value === null || value === '' || (value.constructor === Array && value.length === 0));\n    },\n\n    tabIndex: function () {\n      if (this.$element.data('tabindex') !== this.$element.attr('tabindex') && \n        (this.$element.attr('tabindex') !== -98 && this.$element.attr('tabindex') !== '-98')) {\n        this.$element.data('tabindex', this.$element.attr('tabindex'));\n        this.$button.attr('tabindex', this.$element.data('tabindex'));\n      }\n\n      this.$element.attr('tabindex', -98);\n    },\n\n    clickListener: function () {\n      var that = this,\n          $document = $(document);\n\n      $document.data('spaceSelect', false);\n\n      this.$button.on('keyup', function (e) {\n        if (/(32)/.test(e.keyCode.toString(10)) && $document.data('spaceSelect')) {\n            e.preventDefault();\n            $document.data('spaceSelect', false);\n        }\n      });\n\n      this.$button.on('click', function () {\n        that.setSize();\n      });\n\n      this.$element.on('shown.bs.select', function () {\n        if (!that.options.liveSearch && !that.multiple) {\n          that.$menuInner.find('.selected a').focus();\n        } else if (!that.multiple) {\n          var selectedIndex = that.liObj[that.$element[0].selectedIndex];\n\n          if (typeof selectedIndex !== 'number' || that.options.size === false) return;\n\n          // scroll to selected option\n          var offset = that.$lis.eq(selectedIndex)[0].offsetTop - that.$menuInner[0].offsetTop;\n          offset = offset - that.$menuInner[0].offsetHeight/2 + that.sizeInfo.liHeight/2;\n          that.$menuInner[0].scrollTop = offset;\n        }\n      });\n\n      this.$menuInner.on('click', 'li a', function (e) {\n        var $this = $(this),\n            clickedIndex = $this.parent().data('originalIndex'),\n            prevValue = that.$element.val(),\n            prevIndex = that.$element.prop('selectedIndex'),\n            triggerChange = true;\n\n        // Don't close on multi choice menu\n        if (that.multiple && that.options.maxOptions !== 1) {\n          e.stopPropagation();\n        }\n\n        e.preventDefault();\n\n        //Don't run if we have been disabled\n        if (!that.isDisabled() && !$this.parent().hasClass('disabled')) {\n          var $options = that.$element.find('option'),\n              $option = $options.eq(clickedIndex),\n              state = $option.prop('selected'),\n              $optgroup = $option.parent('optgroup'),\n              maxOptions = that.options.maxOptions,\n              maxOptionsGrp = $optgroup.data('maxOptions') || false;\n\n          if (!that.multiple) { // Deselect all others if not multi select box\n            $options.prop('selected', false);\n            $option.prop('selected', true);\n            that.$menuInner.find('.selected').removeClass('selected').find('a').attr('aria-selected', false);\n            that.setSelected(clickedIndex, true);\n          } else { // Toggle the one we have chosen if we are multi select.\n            $option.prop('selected', !state);\n            that.setSelected(clickedIndex, !state);\n            $this.blur();\n\n            if (maxOptions !== false || maxOptionsGrp !== false) {\n              var maxReached = maxOptions < $options.filter(':selected').length,\n                  maxReachedGrp = maxOptionsGrp < $optgroup.find('option:selected').length;\n\n              if ((maxOptions && maxReached) || (maxOptionsGrp && maxReachedGrp)) {\n                if (maxOptions && maxOptions == 1) {\n                  $options.prop('selected', false);\n                  $option.prop('selected', true);\n                  that.$menuInner.find('.selected').removeClass('selected');\n                  that.setSelected(clickedIndex, true);\n                } else if (maxOptionsGrp && maxOptionsGrp == 1) {\n                  $optgroup.find('option:selected').prop('selected', false);\n                  $option.prop('selected', true);\n                  var optgroupID = $this.parent().data('optgroup');\n                  that.$menuInner.find('[data-optgroup=\"' + optgroupID + '\"]').removeClass('selected');\n                  that.setSelected(clickedIndex, true);\n                } else {\n                  var maxOptionsText = typeof that.options.maxOptionsText === 'string' ? [that.options.maxOptionsText, that.options.maxOptionsText] : that.options.maxOptionsText,\n                      maxOptionsArr = typeof maxOptionsText === 'function' ? maxOptionsText(maxOptions, maxOptionsGrp) : maxOptionsText,\n                      maxTxt = maxOptionsArr[0].replace('{n}', maxOptions),\n                      maxTxtGrp = maxOptionsArr[1].replace('{n}', maxOptionsGrp),\n                      $notify = $('<div class=\"notify\"></div>');\n                  // If {var} is set in array, replace it\n                  /** @deprecated */\n                  if (maxOptionsArr[2]) {\n                    maxTxt = maxTxt.replace('{var}', maxOptionsArr[2][maxOptions > 1 ? 0 : 1]);\n                    maxTxtGrp = maxTxtGrp.replace('{var}', maxOptionsArr[2][maxOptionsGrp > 1 ? 0 : 1]);\n                  }\n\n                  $option.prop('selected', false);\n\n                  that.$menu.append($notify);\n\n                  if (maxOptions && maxReached) {\n                    $notify.append($('<div>' + maxTxt + '</div>'));\n                    triggerChange = false;\n                    that.$element.trigger('maxReached.bs.select');\n                  }\n\n                  if (maxOptionsGrp && maxReachedGrp) {\n                    $notify.append($('<div>' + maxTxtGrp + '</div>'));\n                    triggerChange = false;\n                    that.$element.trigger('maxReachedGrp.bs.select');\n                  }\n\n                  setTimeout(function () {\n                    that.setSelected(clickedIndex, false);\n                  }, 10);\n\n                  $notify.delay(750).fadeOut(300, function () {\n                    $(this).remove();\n                  });\n                }\n              }\n            }\n          }\n\n          if (!that.multiple || (that.multiple && that.options.maxOptions === 1)) {\n            that.$button.focus();\n          } else if (that.options.liveSearch) {\n            that.$searchbox.focus();\n          }\n\n          // Trigger select 'change'\n          if (triggerChange) {\n            if ((prevValue != that.$element.val() && that.multiple) || (prevIndex != that.$element.prop('selectedIndex') && !that.multiple)) {\n              // $option.prop('selected') is current option state (selected/unselected). state is previous option state.\n              changed_arguments = [clickedIndex, $option.prop('selected'), state];\n              that.$element\n                .triggerNative('change');\n            }\n          }\n        }\n      });\n\n      this.$menu.on('click', 'li.disabled a, .popover-title, .popover-title :not(.close)', function (e) {\n        if (e.currentTarget == this) {\n          e.preventDefault();\n          e.stopPropagation();\n          if (that.options.liveSearch && !$(e.target).hasClass('close')) {\n            that.$searchbox.focus();\n          } else {\n            that.$button.focus();\n          }\n        }\n      });\n\n      this.$menuInner.on('click', '.divider, .dropdown-header', function (e) {\n        e.preventDefault();\n        e.stopPropagation();\n        if (that.options.liveSearch) {\n          that.$searchbox.focus();\n        } else {\n          that.$button.focus();\n        }\n      });\n\n      this.$menu.on('click', '.popover-title .close', function () {\n        that.$button.click();\n      });\n\n      this.$searchbox.on('click', function (e) {\n        e.stopPropagation();\n      });\n\n      this.$menu.on('click', '.actions-btn', function (e) {\n        if (that.options.liveSearch) {\n          that.$searchbox.focus();\n        } else {\n          that.$button.focus();\n        }\n\n        e.preventDefault();\n        e.stopPropagation();\n\n        if ($(this).hasClass('bs-select-all')) {\n          that.selectAll();\n        } else {\n          that.deselectAll();\n        }\n      });\n\n      this.$element.change(function () {\n        that.render(false);\n        that.$element.trigger('changed.bs.select', changed_arguments);\n        changed_arguments = null;\n      });\n    },\n\n    liveSearchListener: function () {\n      var that = this,\n          $no_results = $('<li class=\"no-results\"></li>');\n\n      this.$button.on('click.dropdown.data-api', function () {\n        that.$menuInner.find('.active').removeClass('active');\n        if (!!that.$searchbox.val()) {\n          that.$searchbox.val('');\n          that.$lis.not('.is-hidden').removeClass('hidden');\n          if (!!$no_results.parent().length) $no_results.remove();\n        }\n        if (!that.multiple) that.$menuInner.find('.selected').addClass('active');\n        setTimeout(function () {\n          that.$searchbox.focus();\n        }, 10);\n      });\n\n      this.$searchbox.on('click.dropdown.data-api focus.dropdown.data-api touchend.dropdown.data-api', function (e) {\n        e.stopPropagation();\n      });\n\n      this.$searchbox.on('input propertychange', function () {\n        that.$lis.not('.is-hidden').removeClass('hidden');\n        that.$lis.filter('.active').removeClass('active');\n        $no_results.remove();\n\n        if (that.$searchbox.val()) {\n          var $searchBase = that.$lis.not('.is-hidden, .divider, .dropdown-header'),\n              $hideItems;\n          if (that.options.liveSearchNormalize) {\n            $hideItems = $searchBase.find('a').not(':a' + that._searchStyle() + '(\"' + normalizeToBase(that.$searchbox.val()) + '\")');\n          } else {\n            $hideItems = $searchBase.find('a').not(':' + that._searchStyle() + '(\"' + that.$searchbox.val() + '\")');\n          }\n\n          if ($hideItems.length === $searchBase.length) {\n            $no_results.html(that.options.noneResultsText.replace('{0}', '\"' + htmlEscape(that.$searchbox.val()) + '\"'));\n            that.$menuInner.append($no_results);\n            that.$lis.addClass('hidden');\n          } else {\n            $hideItems.parent().addClass('hidden');\n\n            var $lisVisible = that.$lis.not('.hidden'),\n                $foundDiv;\n\n            // hide divider if first or last visible, or if followed by another divider\n            $lisVisible.each(function (index) {\n              var $this = $(this);\n\n              if ($this.hasClass('divider')) {\n                if ($foundDiv === undefined) {\n                  $this.addClass('hidden');\n                } else {\n                  if ($foundDiv) $foundDiv.addClass('hidden');\n                  $foundDiv = $this;\n                }\n              } else if ($this.hasClass('dropdown-header') && $lisVisible.eq(index + 1).data('optgroup') !== $this.data('optgroup')) {\n                $this.addClass('hidden');\n              } else {\n                $foundDiv = null;\n              }\n            });\n            if ($foundDiv) $foundDiv.addClass('hidden');\n\n            $searchBase.not('.hidden').first().addClass('active');\n          }\n        }\n      });\n    },\n\n    _searchStyle: function () {\n      var styles = {\n        begins: 'ibegins',\n        startsWith: 'ibegins'\n      };\n\n      return styles[this.options.liveSearchStyle] || 'icontains';\n    },\n\n    val: function (value) {\n      if (typeof value !== 'undefined') {\n        this.$element.val(value);\n        this.render();\n\n        return this.$element;\n      } else {\n        return this.$element.val();\n      }\n    },\n\n    changeAll: function (status) {\n      if (!this.multiple) return;\n      if (typeof status === 'undefined') status = true;\n\n      this.findLis();\n\n      var $options = this.$element.find('option'),\n          $lisVisible = this.$lis.not('.divider, .dropdown-header, .disabled, .hidden'),\n          lisVisLen = $lisVisible.length,\n          selectedOptions = [];\n          \n      if (status) {\n        if ($lisVisible.filter('.selected').length === $lisVisible.length) return;\n      } else {\n        if ($lisVisible.filter('.selected').length === 0) return;\n      }\n          \n      $lisVisible.toggleClass('selected', status);\n\n      for (var i = 0; i < lisVisLen; i++) {\n        var origIndex = $lisVisible[i].getAttribute('data-original-index');\n        selectedOptions[selectedOptions.length] = $options.eq(origIndex)[0];\n      }\n\n      $(selectedOptions).prop('selected', status);\n\n      this.render(false);\n\n      this.togglePlaceholder();\n\n      this.$element\n        .triggerNative('change');\n    },\n\n    selectAll: function () {\n      return this.changeAll(true);\n    },\n\n    deselectAll: function () {\n      return this.changeAll(false);\n    },\n\n    toggle: function (e) {\n      e = e || window.event;\n\n      if (e) e.stopPropagation();\n\n      this.$button.trigger('click');\n    },\n\n    keydown: function (e) {\n      var $this = $(this),\n          $parent = $this.is('input') ? $this.parent().parent() : $this.parent(),\n          $items,\n          that = $parent.data('this'),\n          index,\n          next,\n          first,\n          last,\n          prev,\n          nextPrev,\n          prevIndex,\n          isActive,\n          selector = ':not(.disabled, .hidden, .dropdown-header, .divider)',\n          keyCodeMap = {\n            32: ' ',\n            48: '0',\n            49: '1',\n            50: '2',\n            51: '3',\n            52: '4',\n            53: '5',\n            54: '6',\n            55: '7',\n            56: '8',\n            57: '9',\n            59: ';',\n            65: 'a',\n            66: 'b',\n            67: 'c',\n            68: 'd',\n            69: 'e',\n            70: 'f',\n            71: 'g',\n            72: 'h',\n            73: 'i',\n            74: 'j',\n            75: 'k',\n            76: 'l',\n            77: 'm',\n            78: 'n',\n            79: 'o',\n            80: 'p',\n            81: 'q',\n            82: 'r',\n            83: 's',\n            84: 't',\n            85: 'u',\n            86: 'v',\n            87: 'w',\n            88: 'x',\n            89: 'y',\n            90: 'z',\n            96: '0',\n            97: '1',\n            98: '2',\n            99: '3',\n            100: '4',\n            101: '5',\n            102: '6',\n            103: '7',\n            104: '8',\n            105: '9'\n          };\n\n      if (that.options.liveSearch) $parent = $this.parent().parent();\n\n      if (that.options.container) $parent = that.$menu;\n\n      $items = $('[role=\"listbox\"] li', $parent);\n\n      isActive = that.$newElement.hasClass('open');\n\n      if (!isActive && (e.keyCode >= 48 && e.keyCode <= 57 || e.keyCode >= 96 && e.keyCode <= 105 || e.keyCode >= 65 && e.keyCode <= 90)) {\n        if (!that.options.container) {\n          that.setSize();\n          that.$menu.parent().addClass('open');\n          isActive = true;\n        } else {\n          that.$button.trigger('click');\n        }\n        that.$searchbox.focus();\n        return;\n      }\n\n      if (that.options.liveSearch) {\n        if (/(^9$|27)/.test(e.keyCode.toString(10)) && isActive) {\n          e.preventDefault();\n          e.stopPropagation();\n          that.$menuInner.click();\n          that.$button.focus();\n        }\n        // $items contains li elements when liveSearch is enabled\n        $items = $('[role=\"listbox\"] li' + selector, $parent);\n        if (!$this.val() && !/(38|40)/.test(e.keyCode.toString(10))) {\n          if ($items.filter('.active').length === 0) {\n            $items = that.$menuInner.find('li');\n            if (that.options.liveSearchNormalize) {\n              $items = $items.filter(':a' + that._searchStyle() + '(' + normalizeToBase(keyCodeMap[e.keyCode]) + ')');\n            } else {\n              $items = $items.filter(':' + that._searchStyle() + '(' + keyCodeMap[e.keyCode] + ')');\n            }\n          }\n        }\n      }\n\n      if (!$items.length) return;\n\n      if (/(38|40)/.test(e.keyCode.toString(10))) {\n        index = $items.index($items.find('a').filter(':focus').parent());\n        first = $items.filter(selector).first().index();\n        last = $items.filter(selector).last().index();\n        next = $items.eq(index).nextAll(selector).eq(0).index();\n        prev = $items.eq(index).prevAll(selector).eq(0).index();\n        nextPrev = $items.eq(next).prevAll(selector).eq(0).index();\n\n        if (that.options.liveSearch) {\n          $items.each(function (i) {\n            if (!$(this).hasClass('disabled')) {\n              $(this).data('index', i);\n            }\n          });\n          index = $items.index($items.filter('.active'));\n          first = $items.first().data('index');\n          last = $items.last().data('index');\n          next = $items.eq(index).nextAll().eq(0).data('index');\n          prev = $items.eq(index).prevAll().eq(0).data('index');\n          nextPrev = $items.eq(next).prevAll().eq(0).data('index');\n        }\n\n        prevIndex = $this.data('prevIndex');\n\n        if (e.keyCode == 38) {\n          if (that.options.liveSearch) index--;\n          if (index != nextPrev && index > prev) index = prev;\n          if (index < first) index = first;\n          if (index == prevIndex) index = last;\n        } else if (e.keyCode == 40) {\n          if (that.options.liveSearch) index++;\n          if (index == -1) index = 0;\n          if (index != nextPrev && index < next) index = next;\n          if (index > last) index = last;\n          if (index == prevIndex) index = first;\n        }\n\n        $this.data('prevIndex', index);\n\n        if (!that.options.liveSearch) {\n          $items.eq(index).children('a').focus();\n        } else {\n          e.preventDefault();\n          if (!$this.hasClass('dropdown-toggle')) {\n            $items.removeClass('active').eq(index).addClass('active').children('a').focus();\n            $this.focus();\n          }\n        }\n\n      } else if (!$this.is('input')) {\n        var keyIndex = [],\n            count,\n            prevKey;\n\n        $items.each(function () {\n          if (!$(this).hasClass('disabled')) {\n            if ($.trim($(this).children('a').text().toLowerCase()).substring(0, 1) == keyCodeMap[e.keyCode]) {\n              keyIndex.push($(this).index());\n            }\n          }\n        });\n\n        count = $(document).data('keycount');\n        count++;\n        $(document).data('keycount', count);\n\n        prevKey = $.trim($(':focus').text().toLowerCase()).substring(0, 1);\n\n        if (prevKey != keyCodeMap[e.keyCode]) {\n          count = 1;\n          $(document).data('keycount', count);\n        } else if (count >= keyIndex.length) {\n          $(document).data('keycount', 0);\n          if (count > keyIndex.length) count = 1;\n        }\n\n        $items.eq(keyIndex[count - 1]).children('a').focus();\n      }\n\n      // Select focused option if \"Enter\", \"Spacebar\" or \"Tab\" (when selectOnTab is true) are pressed inside the menu.\n      if ((/(13|32)/.test(e.keyCode.toString(10)) || (/(^9$)/.test(e.keyCode.toString(10)) && that.options.selectOnTab)) && isActive) {\n        if (!/(32)/.test(e.keyCode.toString(10))) e.preventDefault();\n        if (!that.options.liveSearch) {\n          var elem = $(':focus');\n          elem.click();\n          // Bring back focus for multiselects\n          elem.focus();\n          // Prevent screen from scrolling if the user hit the spacebar\n          e.preventDefault();\n          // Fixes spacebar selection of dropdown items in FF & IE\n          $(document).data('spaceSelect', true);\n        } else if (!/(32)/.test(e.keyCode.toString(10))) {\n          that.$menuInner.find('.active a').click();\n          $this.focus();\n        }\n        $(document).data('keycount', 0);\n      }\n\n      if ((/(^9$|27)/.test(e.keyCode.toString(10)) && isActive && (that.multiple || that.options.liveSearch)) || (/(27)/.test(e.keyCode.toString(10)) && !isActive)) {\n        that.$menu.parent().removeClass('open');\n        if (that.options.container) that.$newElement.removeClass('open');\n        that.$button.focus();\n      }\n    },\n\n    mobile: function () {\n      this.$element.addClass('mobile-device');\n    },\n\n    refresh: function () {\n      this.$lis = null;\n      this.liObj = {};\n      this.reloadLi();\n      this.render();\n      this.checkDisabled();\n      this.liHeight(true);\n      this.setStyle();\n      this.setWidth();\n      if (this.$lis) this.$searchbox.trigger('propertychange');\n\n      this.$element.trigger('refreshed.bs.select');\n    },\n\n    hide: function () {\n      this.$newElement.hide();\n    },\n\n    show: function () {\n      this.$newElement.show();\n    },\n\n    remove: function () {\n      this.$newElement.remove();\n      this.$element.remove();\n    },\n\n    destroy: function () {\n      this.$newElement.before(this.$element).remove();\n\n      if (this.$bsContainer) {\n        this.$bsContainer.remove();\n      } else {\n        this.$menu.remove();\n      }\n\n      this.$element\n        .off('.bs.select')\n        .removeData('selectpicker')\n        .removeClass('bs-select-hidden selectpicker');\n    }\n  };\n\n  // SELECTPICKER PLUGIN DEFINITION\n  // ==============================\n  function Plugin(option) {\n    // get the args of the outer function..\n    var args = arguments;\n    // The arguments of the function are explicitly re-defined from the argument list, because the shift causes them\n    // to get lost/corrupted in android 2.3 and IE9 #715 #775\n    var _option = option;\n\n    [].shift.apply(args);\n\n    var value;\n    var chain = this.each(function () {\n      var $this = $(this);\n      if ($this.is('select')) {\n        var data = $this.data('selectpicker'),\n            options = typeof _option == 'object' && _option;\n\n        if (!data) {\n          var config = $.extend({}, Selectpicker.DEFAULTS, $.fn.selectpicker.defaults || {}, $this.data(), options);\n          config.template = $.extend({}, Selectpicker.DEFAULTS.template, ($.fn.selectpicker.defaults ? $.fn.selectpicker.defaults.template : {}), $this.data().template, options.template);\n          $this.data('selectpicker', (data = new Selectpicker(this, config)));\n        } else if (options) {\n          for (var i in options) {\n            if (options.hasOwnProperty(i)) {\n              data.options[i] = options[i];\n            }\n          }\n        }\n\n        if (typeof _option == 'string') {\n          if (data[_option] instanceof Function) {\n            value = data[_option].apply(data, args);\n          } else {\n            value = data.options[_option];\n          }\n        }\n      }\n    });\n\n    if (typeof value !== 'undefined') {\n      //noinspection JSUnusedAssignment\n      return value;\n    } else {\n      return chain;\n    }\n  }\n\n  var old = $.fn.selectpicker;\n  $.fn.selectpicker = Plugin;\n  $.fn.selectpicker.Constructor = Selectpicker;\n\n  // SELECTPICKER NO CONFLICT\n  // ========================\n  $.fn.selectpicker.noConflict = function () {\n    $.fn.selectpicker = old;\n    return this;\n  };\n\n  $(document)\n      .data('keycount', 0)\n      .on('keydown.bs.select', '.bootstrap-select [data-toggle=dropdown], .bootstrap-select [role=\"listbox\"], .bs-searchbox input', Selectpicker.prototype.keydown)\n      .on('focusin.modal', '.bootstrap-select [data-toggle=dropdown], .bootstrap-select [role=\"listbox\"], .bs-searchbox input', function (e) {\n        e.stopPropagation();\n      });\n\n  // SELECTPICKER DATA-API\n  // =====================\n  $(window).on('load.bs.select.data-api', function () {\n    $('.selectpicker').each(function () {\n      var $selectpicker = $(this);\n      Plugin.call($selectpicker, $selectpicker.data());\n    })\n  });\n})(jQuery);\n\n\n}));\n"
  },
  {
    "path": "app_backend/static/js/bootstrap.js",
    "content": "/*!\n * Bootstrap v3.3.5 (http://getbootstrap.com)\n * Copyright 2011-2015 Twitter, Inc.\n * Licensed under the MIT license\n */\n\nif (typeof jQuery === 'undefined') {\n  throw new Error('Bootstrap\\'s JavaScript requires jQuery')\n}\n\n+function ($) {\n  'use strict';\n  var version = $.fn.jquery.split(' ')[0].split('.')\n  if ((version[0] < 2 && version[1] < 9) || (version[0] == 1 && version[1] == 9 && version[2] < 1)) {\n    throw new Error('Bootstrap\\'s JavaScript requires jQuery version 1.9.1 or higher')\n  }\n}(jQuery);\n\n/* ========================================================================\n * Bootstrap: transition.js v3.3.5\n * http://getbootstrap.com/javascript/#transitions\n * ========================================================================\n * Copyright 2011-2015 Twitter, Inc.\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)\n * ======================================================================== */\n\n\n+function ($) {\n  'use strict';\n\n  // CSS TRANSITION SUPPORT (Shoutout: http://www.modernizr.com/)\n  // ============================================================\n\n  function transitionEnd() {\n    var el = document.createElement('bootstrap')\n\n    var transEndEventNames = {\n      WebkitTransition : 'webkitTransitionEnd',\n      MozTransition    : 'transitionend',\n      OTransition      : 'oTransitionEnd otransitionend',\n      transition       : 'transitionend'\n    }\n\n    for (var name in transEndEventNames) {\n      if (el.style[name] !== undefined) {\n        return { end: transEndEventNames[name] }\n      }\n    }\n\n    return false // explicit for ie8 (  ._.)\n  }\n\n  // http://blog.alexmaccaw.com/css-transitions\n  $.fn.emulateTransitionEnd = function (duration) {\n    var called = false\n    var $el = this\n    $(this).one('bsTransitionEnd', function () { called = true })\n    var callback = function () { if (!called) $($el).trigger($.support.transition.end) }\n    setTimeout(callback, duration)\n    return this\n  }\n\n  $(function () {\n    $.support.transition = transitionEnd()\n\n    if (!$.support.transition) return\n\n    $.event.special.bsTransitionEnd = {\n      bindType: $.support.transition.end,\n      delegateType: $.support.transition.end,\n      handle: function (e) {\n        if ($(e.target).is(this)) return e.handleObj.handler.apply(this, arguments)\n      }\n    }\n  })\n\n}(jQuery);\n\n/* ========================================================================\n * Bootstrap: alert.js v3.3.5\n * http://getbootstrap.com/javascript/#alerts\n * ========================================================================\n * Copyright 2011-2015 Twitter, Inc.\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)\n * ======================================================================== */\n\n\n+function ($) {\n  'use strict';\n\n  // ALERT CLASS DEFINITION\n  // ======================\n\n  var dismiss = '[data-dismiss=\"alert\"]'\n  var Alert   = function (el) {\n    $(el).on('click', dismiss, this.close)\n  }\n\n  Alert.VERSION = '3.3.5'\n\n  Alert.TRANSITION_DURATION = 150\n\n  Alert.prototype.close = function (e) {\n    var $this    = $(this)\n    var selector = $this.attr('data-target')\n\n    if (!selector) {\n      selector = $this.attr('href')\n      selector = selector && selector.replace(/.*(?=#[^\\s]*$)/, '') // strip for ie7\n    }\n\n    var $parent = $(selector)\n\n    if (e) e.preventDefault()\n\n    if (!$parent.length) {\n      $parent = $this.closest('.alert')\n    }\n\n    $parent.trigger(e = $.Event('close.bs.alert'))\n\n    if (e.isDefaultPrevented()) return\n\n    $parent.removeClass('in')\n\n    function removeElement() {\n      // detach from parent, fire event then clean up data\n      $parent.detach().trigger('closed.bs.alert').remove()\n    }\n\n    $.support.transition && $parent.hasClass('fade') ?\n      $parent\n        .one('bsTransitionEnd', removeElement)\n        .emulateTransitionEnd(Alert.TRANSITION_DURATION) :\n      removeElement()\n  }\n\n\n  // ALERT PLUGIN DEFINITION\n  // =======================\n\n  function Plugin(option) {\n    return this.each(function () {\n      var $this = $(this)\n      var data  = $this.data('bs.alert')\n\n      if (!data) $this.data('bs.alert', (data = new Alert(this)))\n      if (typeof option == 'string') data[option].call($this)\n    })\n  }\n\n  var old = $.fn.alert\n\n  $.fn.alert             = Plugin\n  $.fn.alert.Constructor = Alert\n\n\n  // ALERT NO CONFLICT\n  // =================\n\n  $.fn.alert.noConflict = function () {\n    $.fn.alert = old\n    return this\n  }\n\n\n  // ALERT DATA-API\n  // ==============\n\n  $(document).on('click.bs.alert.data-api', dismiss, Alert.prototype.close)\n\n}(jQuery);\n\n/* ========================================================================\n * Bootstrap: button.js v3.3.5\n * http://getbootstrap.com/javascript/#buttons\n * ========================================================================\n * Copyright 2011-2015 Twitter, Inc.\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)\n * ======================================================================== */\n\n\n+function ($) {\n  'use strict';\n\n  // BUTTON PUBLIC CLASS DEFINITION\n  // ==============================\n\n  var Button = function (element, options) {\n    this.$element  = $(element)\n    this.options   = $.extend({}, Button.DEFAULTS, options)\n    this.isLoading = false\n  }\n\n  Button.VERSION  = '3.3.5'\n\n  Button.DEFAULTS = {\n    loadingText: 'loading...'\n  }\n\n  Button.prototype.setState = function (state) {\n    var d    = 'disabled'\n    var $el  = this.$element\n    var val  = $el.is('input') ? 'val' : 'html'\n    var data = $el.data()\n\n    state += 'Text'\n\n    if (data.resetText == null) $el.data('resetText', $el[val]())\n\n    // push to event loop to allow forms to submit\n    setTimeout($.proxy(function () {\n      $el[val](data[state] == null ? this.options[state] : data[state])\n\n      if (state == 'loadingText') {\n        this.isLoading = true\n        $el.addClass(d).attr(d, d)\n      } else if (this.isLoading) {\n        this.isLoading = false\n        $el.removeClass(d).removeAttr(d)\n      }\n    }, this), 0)\n  }\n\n  Button.prototype.toggle = function () {\n    var changed = true\n    var $parent = this.$element.closest('[data-toggle=\"buttons\"]')\n\n    if ($parent.length) {\n      var $input = this.$element.find('input')\n      if ($input.prop('type') == 'radio') {\n        if ($input.prop('checked')) changed = false\n        $parent.find('.active').removeClass('active')\n        this.$element.addClass('active')\n      } else if ($input.prop('type') == 'checkbox') {\n        if (($input.prop('checked')) !== this.$element.hasClass('active')) changed = false\n        this.$element.toggleClass('active')\n      }\n      $input.prop('checked', this.$element.hasClass('active'))\n      if (changed) $input.trigger('change')\n    } else {\n      this.$element.attr('aria-pressed', !this.$element.hasClass('active'))\n      this.$element.toggleClass('active')\n    }\n  }\n\n\n  // BUTTON PLUGIN DEFINITION\n  // ========================\n\n  function Plugin(option) {\n    return this.each(function () {\n      var $this   = $(this)\n      var data    = $this.data('bs.button')\n      var options = typeof option == 'object' && option\n\n      if (!data) $this.data('bs.button', (data = new Button(this, options)))\n\n      if (option == 'toggle') data.toggle()\n      else if (option) data.setState(option)\n    })\n  }\n\n  var old = $.fn.button\n\n  $.fn.button             = Plugin\n  $.fn.button.Constructor = Button\n\n\n  // BUTTON NO CONFLICT\n  // ==================\n\n  $.fn.button.noConflict = function () {\n    $.fn.button = old\n    return this\n  }\n\n\n  // BUTTON DATA-API\n  // ===============\n\n  $(document)\n    .on('click.bs.button.data-api', '[data-toggle^=\"button\"]', function (e) {\n      var $btn = $(e.target)\n      if (!$btn.hasClass('btn')) $btn = $btn.closest('.btn')\n      Plugin.call($btn, 'toggle')\n      if (!($(e.target).is('input[type=\"radio\"]') || $(e.target).is('input[type=\"checkbox\"]'))) e.preventDefault()\n    })\n    .on('focus.bs.button.data-api blur.bs.button.data-api', '[data-toggle^=\"button\"]', function (e) {\n      $(e.target).closest('.btn').toggleClass('focus', /^focus(in)?$/.test(e.type))\n    })\n\n}(jQuery);\n\n/* ========================================================================\n * Bootstrap: carousel.js v3.3.5\n * http://getbootstrap.com/javascript/#carousel\n * ========================================================================\n * Copyright 2011-2015 Twitter, Inc.\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)\n * ======================================================================== */\n\n\n+function ($) {\n  'use strict';\n\n  // CAROUSEL CLASS DEFINITION\n  // =========================\n\n  var Carousel = function (element, options) {\n    this.$element    = $(element)\n    this.$indicators = this.$element.find('.carousel-indicators')\n    this.options     = options\n    this.paused      = null\n    this.sliding     = null\n    this.interval    = null\n    this.$active     = null\n    this.$items      = null\n\n    this.options.keyboard && this.$element.on('keydown.bs.carousel', $.proxy(this.keydown, this))\n\n    this.options.pause == 'hover' && !('ontouchstart' in document.documentElement) && this.$element\n      .on('mouseenter.bs.carousel', $.proxy(this.pause, this))\n      .on('mouseleave.bs.carousel', $.proxy(this.cycle, this))\n  }\n\n  Carousel.VERSION  = '3.3.5'\n\n  Carousel.TRANSITION_DURATION = 600\n\n  Carousel.DEFAULTS = {\n    interval: 5000,\n    pause: 'hover',\n    wrap: true,\n    keyboard: true\n  }\n\n  Carousel.prototype.keydown = function (e) {\n    if (/input|textarea/i.test(e.target.tagName)) return\n    switch (e.which) {\n      case 37: this.prev(); break\n      case 39: this.next(); break\n      default: return\n    }\n\n    e.preventDefault()\n  }\n\n  Carousel.prototype.cycle = function (e) {\n    e || (this.paused = false)\n\n    this.interval && clearInterval(this.interval)\n\n    this.options.interval\n      && !this.paused\n      && (this.interval = setInterval($.proxy(this.next, this), this.options.interval))\n\n    return this\n  }\n\n  Carousel.prototype.getItemIndex = function (item) {\n    this.$items = item.parent().children('.item')\n    return this.$items.index(item || this.$active)\n  }\n\n  Carousel.prototype.getItemForDirection = function (direction, active) {\n    var activeIndex = this.getItemIndex(active)\n    var willWrap = (direction == 'prev' && activeIndex === 0)\n                || (direction == 'next' && activeIndex == (this.$items.length - 1))\n    if (willWrap && !this.options.wrap) return active\n    var delta = direction == 'prev' ? -1 : 1\n    var itemIndex = (activeIndex + delta) % this.$items.length\n    return this.$items.eq(itemIndex)\n  }\n\n  Carousel.prototype.to = function (pos) {\n    var that        = this\n    var activeIndex = this.getItemIndex(this.$active = this.$element.find('.item.active'))\n\n    if (pos > (this.$items.length - 1) || pos < 0) return\n\n    if (this.sliding)       return this.$element.one('slid.bs.carousel', function () { that.to(pos) }) // yes, \"slid\"\n    if (activeIndex == pos) return this.pause().cycle()\n\n    return this.slide(pos > activeIndex ? 'next' : 'prev', this.$items.eq(pos))\n  }\n\n  Carousel.prototype.pause = function (e) {\n    e || (this.paused = true)\n\n    if (this.$element.find('.next, .prev').length && $.support.transition) {\n      this.$element.trigger($.support.transition.end)\n      this.cycle(true)\n    }\n\n    this.interval = clearInterval(this.interval)\n\n    return this\n  }\n\n  Carousel.prototype.next = function () {\n    if (this.sliding) return\n    return this.slide('next')\n  }\n\n  Carousel.prototype.prev = function () {\n    if (this.sliding) return\n    return this.slide('prev')\n  }\n\n  Carousel.prototype.slide = function (type, next) {\n    var $active   = this.$element.find('.item.active')\n    var $next     = next || this.getItemForDirection(type, $active)\n    var isCycling = this.interval\n    var direction = type == 'next' ? 'left' : 'right'\n    var that      = this\n\n    if ($next.hasClass('active')) return (this.sliding = false)\n\n    var relatedTarget = $next[0]\n    var slideEvent = $.Event('slide.bs.carousel', {\n      relatedTarget: relatedTarget,\n      direction: direction\n    })\n    this.$element.trigger(slideEvent)\n    if (slideEvent.isDefaultPrevented()) return\n\n    this.sliding = true\n\n    isCycling && this.pause()\n\n    if (this.$indicators.length) {\n      this.$indicators.find('.active').removeClass('active')\n      var $nextIndicator = $(this.$indicators.children()[this.getItemIndex($next)])\n      $nextIndicator && $nextIndicator.addClass('active')\n    }\n\n    var slidEvent = $.Event('slid.bs.carousel', { relatedTarget: relatedTarget, direction: direction }) // yes, \"slid\"\n    if ($.support.transition && this.$element.hasClass('slide')) {\n      $next.addClass(type)\n      $next[0].offsetWidth // force reflow\n      $active.addClass(direction)\n      $next.addClass(direction)\n      $active\n        .one('bsTransitionEnd', function () {\n          $next.removeClass([type, direction].join(' ')).addClass('active')\n          $active.removeClass(['active', direction].join(' '))\n          that.sliding = false\n          setTimeout(function () {\n            that.$element.trigger(slidEvent)\n          }, 0)\n        })\n        .emulateTransitionEnd(Carousel.TRANSITION_DURATION)\n    } else {\n      $active.removeClass('active')\n      $next.addClass('active')\n      this.sliding = false\n      this.$element.trigger(slidEvent)\n    }\n\n    isCycling && this.cycle()\n\n    return this\n  }\n\n\n  // CAROUSEL PLUGIN DEFINITION\n  // ==========================\n\n  function Plugin(option) {\n    return this.each(function () {\n      var $this   = $(this)\n      var data    = $this.data('bs.carousel')\n      var options = $.extend({}, Carousel.DEFAULTS, $this.data(), typeof option == 'object' && option)\n      var action  = typeof option == 'string' ? option : options.slide\n\n      if (!data) $this.data('bs.carousel', (data = new Carousel(this, options)))\n      if (typeof option == 'number') data.to(option)\n      else if (action) data[action]()\n      else if (options.interval) data.pause().cycle()\n    })\n  }\n\n  var old = $.fn.carousel\n\n  $.fn.carousel             = Plugin\n  $.fn.carousel.Constructor = Carousel\n\n\n  // CAROUSEL NO CONFLICT\n  // ====================\n\n  $.fn.carousel.noConflict = function () {\n    $.fn.carousel = old\n    return this\n  }\n\n\n  // CAROUSEL DATA-API\n  // =================\n\n  var clickHandler = function (e) {\n    var href\n    var $this   = $(this)\n    var $target = $($this.attr('data-target') || (href = $this.attr('href')) && href.replace(/.*(?=#[^\\s]+$)/, '')) // strip for ie7\n    if (!$target.hasClass('carousel')) return\n    var options = $.extend({}, $target.data(), $this.data())\n    var slideIndex = $this.attr('data-slide-to')\n    if (slideIndex) options.interval = false\n\n    Plugin.call($target, options)\n\n    if (slideIndex) {\n      $target.data('bs.carousel').to(slideIndex)\n    }\n\n    e.preventDefault()\n  }\n\n  $(document)\n    .on('click.bs.carousel.data-api', '[data-slide]', clickHandler)\n    .on('click.bs.carousel.data-api', '[data-slide-to]', clickHandler)\n\n  $(window).on('load', function () {\n    $('[data-ride=\"carousel\"]').each(function () {\n      var $carousel = $(this)\n      Plugin.call($carousel, $carousel.data())\n    })\n  })\n\n}(jQuery);\n\n/* ========================================================================\n * Bootstrap: collapse.js v3.3.5\n * http://getbootstrap.com/javascript/#collapse\n * ========================================================================\n * Copyright 2011-2015 Twitter, Inc.\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)\n * ======================================================================== */\n\n\n+function ($) {\n  'use strict';\n\n  // COLLAPSE PUBLIC CLASS DEFINITION\n  // ================================\n\n  var Collapse = function (element, options) {\n    this.$element      = $(element)\n    this.options       = $.extend({}, Collapse.DEFAULTS, options)\n    this.$trigger      = $('[data-toggle=\"collapse\"][href=\"#' + element.id + '\"],' +\n                           '[data-toggle=\"collapse\"][data-target=\"#' + element.id + '\"]')\n    this.transitioning = null\n\n    if (this.options.parent) {\n      this.$parent = this.getParent()\n    } else {\n      this.addAriaAndCollapsedClass(this.$element, this.$trigger)\n    }\n\n    if (this.options.toggle) this.toggle()\n  }\n\n  Collapse.VERSION  = '3.3.5'\n\n  Collapse.TRANSITION_DURATION = 350\n\n  Collapse.DEFAULTS = {\n    toggle: true\n  }\n\n  Collapse.prototype.dimension = function () {\n    var hasWidth = this.$element.hasClass('width')\n    return hasWidth ? 'width' : 'height'\n  }\n\n  Collapse.prototype.show = function () {\n    if (this.transitioning || this.$element.hasClass('in')) return\n\n    var activesData\n    var actives = this.$parent && this.$parent.children('.panel').children('.in, .collapsing')\n\n    if (actives && actives.length) {\n      activesData = actives.data('bs.collapse')\n      if (activesData && activesData.transitioning) return\n    }\n\n    var startEvent = $.Event('show.bs.collapse')\n    this.$element.trigger(startEvent)\n    if (startEvent.isDefaultPrevented()) return\n\n    if (actives && actives.length) {\n      Plugin.call(actives, 'hide')\n      activesData || actives.data('bs.collapse', null)\n    }\n\n    var dimension = this.dimension()\n\n    this.$element\n      .removeClass('collapse')\n      .addClass('collapsing')[dimension](0)\n      .attr('aria-expanded', true)\n\n    this.$trigger\n      .removeClass('collapsed')\n      .attr('aria-expanded', true)\n\n    this.transitioning = 1\n\n    var complete = function () {\n      this.$element\n        .removeClass('collapsing')\n        .addClass('collapse in')[dimension]('')\n      this.transitioning = 0\n      this.$element\n        .trigger('shown.bs.collapse')\n    }\n\n    if (!$.support.transition) return complete.call(this)\n\n    var scrollSize = $.camelCase(['scroll', dimension].join('-'))\n\n    this.$element\n      .one('bsTransitionEnd', $.proxy(complete, this))\n      .emulateTransitionEnd(Collapse.TRANSITION_DURATION)[dimension](this.$element[0][scrollSize])\n  }\n\n  Collapse.prototype.hide = function () {\n    if (this.transitioning || !this.$element.hasClass('in')) return\n\n    var startEvent = $.Event('hide.bs.collapse')\n    this.$element.trigger(startEvent)\n    if (startEvent.isDefaultPrevented()) return\n\n    var dimension = this.dimension()\n\n    this.$element[dimension](this.$element[dimension]())[0].offsetHeight\n\n    this.$element\n      .addClass('collapsing')\n      .removeClass('collapse in')\n      .attr('aria-expanded', false)\n\n    this.$trigger\n      .addClass('collapsed')\n      .attr('aria-expanded', false)\n\n    this.transitioning = 1\n\n    var complete = function () {\n      this.transitioning = 0\n      this.$element\n        .removeClass('collapsing')\n        .addClass('collapse')\n        .trigger('hidden.bs.collapse')\n    }\n\n    if (!$.support.transition) return complete.call(this)\n\n    this.$element\n      [dimension](0)\n      .one('bsTransitionEnd', $.proxy(complete, this))\n      .emulateTransitionEnd(Collapse.TRANSITION_DURATION)\n  }\n\n  Collapse.prototype.toggle = function () {\n    this[this.$element.hasClass('in') ? 'hide' : 'show']()\n  }\n\n  Collapse.prototype.getParent = function () {\n    return $(this.options.parent)\n      .find('[data-toggle=\"collapse\"][data-parent=\"' + this.options.parent + '\"]')\n      .each($.proxy(function (i, element) {\n        var $element = $(element)\n        this.addAriaAndCollapsedClass(getTargetFromTrigger($element), $element)\n      }, this))\n      .end()\n  }\n\n  Collapse.prototype.addAriaAndCollapsedClass = function ($element, $trigger) {\n    var isOpen = $element.hasClass('in')\n\n    $element.attr('aria-expanded', isOpen)\n    $trigger\n      .toggleClass('collapsed', !isOpen)\n      .attr('aria-expanded', isOpen)\n  }\n\n  function getTargetFromTrigger($trigger) {\n    var href\n    var target = $trigger.attr('data-target')\n      || (href = $trigger.attr('href')) && href.replace(/.*(?=#[^\\s]+$)/, '') // strip for ie7\n\n    return $(target)\n  }\n\n\n  // COLLAPSE PLUGIN DEFINITION\n  // ==========================\n\n  function Plugin(option) {\n    return this.each(function () {\n      var $this   = $(this)\n      var data    = $this.data('bs.collapse')\n      var options = $.extend({}, Collapse.DEFAULTS, $this.data(), typeof option == 'object' && option)\n\n      if (!data && options.toggle && /show|hide/.test(option)) options.toggle = false\n      if (!data) $this.data('bs.collapse', (data = new Collapse(this, options)))\n      if (typeof option == 'string') data[option]()\n    })\n  }\n\n  var old = $.fn.collapse\n\n  $.fn.collapse             = Plugin\n  $.fn.collapse.Constructor = Collapse\n\n\n  // COLLAPSE NO CONFLICT\n  // ====================\n\n  $.fn.collapse.noConflict = function () {\n    $.fn.collapse = old\n    return this\n  }\n\n\n  // COLLAPSE DATA-API\n  // =================\n\n  $(document).on('click.bs.collapse.data-api', '[data-toggle=\"collapse\"]', function (e) {\n    var $this   = $(this)\n\n    if (!$this.attr('data-target')) e.preventDefault()\n\n    var $target = getTargetFromTrigger($this)\n    var data    = $target.data('bs.collapse')\n    var option  = data ? 'toggle' : $this.data()\n\n    Plugin.call($target, option)\n  })\n\n}(jQuery);\n\n/* ========================================================================\n * Bootstrap: dropdown.js v3.3.5\n * http://getbootstrap.com/javascript/#dropdowns\n * ========================================================================\n * Copyright 2011-2015 Twitter, Inc.\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)\n * ======================================================================== */\n\n\n+function ($) {\n  'use strict';\n\n  // DROPDOWN CLASS DEFINITION\n  // =========================\n\n  var backdrop = '.dropdown-backdrop'\n  var toggle   = '[data-toggle=\"dropdown\"]'\n  var Dropdown = function (element) {\n    $(element).on('click.bs.dropdown', this.toggle)\n  }\n\n  Dropdown.VERSION = '3.3.5'\n\n  function getParent($this) {\n    var selector = $this.attr('data-target')\n\n    if (!selector) {\n      selector = $this.attr('href')\n      selector = selector && /#[A-Za-z]/.test(selector) && selector.replace(/.*(?=#[^\\s]*$)/, '') // strip for ie7\n    }\n\n    var $parent = selector && $(selector)\n\n    return $parent && $parent.length ? $parent : $this.parent()\n  }\n\n  function clearMenus(e) {\n    if (e && e.which === 3) return\n    $(backdrop).remove()\n    $(toggle).each(function () {\n      var $this         = $(this)\n      var $parent       = getParent($this)\n      var relatedTarget = { relatedTarget: this }\n\n      if (!$parent.hasClass('open')) return\n\n      if (e && e.type == 'click' && /input|textarea/i.test(e.target.tagName) && $.contains($parent[0], e.target)) return\n\n      $parent.trigger(e = $.Event('hide.bs.dropdown', relatedTarget))\n\n      if (e.isDefaultPrevented()) return\n\n      $this.attr('aria-expanded', 'false')\n      $parent.removeClass('open').trigger('hidden.bs.dropdown', relatedTarget)\n    })\n  }\n\n  Dropdown.prototype.toggle = function (e) {\n    var $this = $(this)\n\n    if ($this.is('.disabled, :disabled')) return\n\n    var $parent  = getParent($this)\n    var isActive = $parent.hasClass('open')\n\n    clearMenus()\n\n    if (!isActive) {\n      if ('ontouchstart' in document.documentElement && !$parent.closest('.navbar-nav').length) {\n        // if mobile we use a backdrop because click events don't delegate\n        $(document.createElement('div'))\n          .addClass('dropdown-backdrop')\n          .insertAfter($(this))\n          .on('click', clearMenus)\n      }\n\n      var relatedTarget = { relatedTarget: this }\n      $parent.trigger(e = $.Event('show.bs.dropdown', relatedTarget))\n\n      if (e.isDefaultPrevented()) return\n\n      $this\n        .trigger('focus')\n        .attr('aria-expanded', 'true')\n\n      $parent\n        .toggleClass('open')\n        .trigger('shown.bs.dropdown', relatedTarget)\n    }\n\n    return false\n  }\n\n  Dropdown.prototype.keydown = function (e) {\n    if (!/(38|40|27|32)/.test(e.which) || /input|textarea/i.test(e.target.tagName)) return\n\n    var $this = $(this)\n\n    e.preventDefault()\n    e.stopPropagation()\n\n    if ($this.is('.disabled, :disabled')) return\n\n    var $parent  = getParent($this)\n    var isActive = $parent.hasClass('open')\n\n    if (!isActive && e.which != 27 || isActive && e.which == 27) {\n      if (e.which == 27) $parent.find(toggle).trigger('focus')\n      return $this.trigger('click')\n    }\n\n    var desc = ' li:not(.disabled):visible a'\n    var $items = $parent.find('.dropdown-menu' + desc)\n\n    if (!$items.length) return\n\n    var index = $items.index(e.target)\n\n    if (e.which == 38 && index > 0)                 index--         // up\n    if (e.which == 40 && index < $items.length - 1) index++         // down\n    if (!~index)                                    index = 0\n\n    $items.eq(index).trigger('focus')\n  }\n\n\n  // DROPDOWN PLUGIN DEFINITION\n  // ==========================\n\n  function Plugin(option) {\n    return this.each(function () {\n      var $this = $(this)\n      var data  = $this.data('bs.dropdown')\n\n      if (!data) $this.data('bs.dropdown', (data = new Dropdown(this)))\n      if (typeof option == 'string') data[option].call($this)\n    })\n  }\n\n  var old = $.fn.dropdown\n\n  $.fn.dropdown             = Plugin\n  $.fn.dropdown.Constructor = Dropdown\n\n\n  // DROPDOWN NO CONFLICT\n  // ====================\n\n  $.fn.dropdown.noConflict = function () {\n    $.fn.dropdown = old\n    return this\n  }\n\n\n  // APPLY TO STANDARD DROPDOWN ELEMENTS\n  // ===================================\n\n  $(document)\n    .on('click.bs.dropdown.data-api', clearMenus)\n    .on('click.bs.dropdown.data-api', '.dropdown form', function (e) { e.stopPropagation() })\n    .on('click.bs.dropdown.data-api', toggle, Dropdown.prototype.toggle)\n    .on('keydown.bs.dropdown.data-api', toggle, Dropdown.prototype.keydown)\n    .on('keydown.bs.dropdown.data-api', '.dropdown-menu', Dropdown.prototype.keydown)\n\n}(jQuery);\n\n/* ========================================================================\n * Bootstrap: modal.js v3.3.5\n * http://getbootstrap.com/javascript/#modals\n * ========================================================================\n * Copyright 2011-2015 Twitter, Inc.\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)\n * ======================================================================== */\n\n\n+function ($) {\n  'use strict';\n\n  // MODAL CLASS DEFINITION\n  // ======================\n\n  var Modal = function (element, options) {\n    this.options             = options\n    this.$body               = $(document.body)\n    this.$element            = $(element)\n    this.$dialog             = this.$element.find('.modal-dialog')\n    this.$backdrop           = null\n    this.isShown             = null\n    this.originalBodyPad     = null\n    this.scrollbarWidth      = 0\n    this.ignoreBackdropClick = false\n\n    if (this.options.remote) {\n      this.$element\n        .find('.modal-content')\n        .load(this.options.remote, $.proxy(function () {\n          this.$element.trigger('loaded.bs.modal')\n        }, this))\n    }\n  }\n\n  Modal.VERSION  = '3.3.5'\n\n  Modal.TRANSITION_DURATION = 300\n  Modal.BACKDROP_TRANSITION_DURATION = 150\n\n  Modal.DEFAULTS = {\n    backdrop: true,\n    keyboard: true,\n    show: true\n  }\n\n  Modal.prototype.toggle = function (_relatedTarget) {\n    return this.isShown ? this.hide() : this.show(_relatedTarget)\n  }\n\n  Modal.prototype.show = function (_relatedTarget) {\n    var that = this\n    var e    = $.Event('show.bs.modal', { relatedTarget: _relatedTarget })\n\n    this.$element.trigger(e)\n\n    if (this.isShown || e.isDefaultPrevented()) return\n\n    this.isShown = true\n\n    this.checkScrollbar()\n    this.setScrollbar()\n    this.$body.addClass('modal-open')\n\n    this.escape()\n    this.resize()\n\n    this.$element.on('click.dismiss.bs.modal', '[data-dismiss=\"modal\"]', $.proxy(this.hide, this))\n\n    this.$dialog.on('mousedown.dismiss.bs.modal', function () {\n      that.$element.one('mouseup.dismiss.bs.modal', function (e) {\n        if ($(e.target).is(that.$element)) that.ignoreBackdropClick = true\n      })\n    })\n\n    this.backdrop(function () {\n      var transition = $.support.transition && that.$element.hasClass('fade')\n\n      if (!that.$element.parent().length) {\n        that.$element.appendTo(that.$body) // don't move modals dom position\n      }\n\n      that.$element\n        .show()\n        .scrollTop(0)\n\n      that.adjustDialog()\n\n      if (transition) {\n        that.$element[0].offsetWidth // force reflow\n      }\n\n      that.$element.addClass('in')\n\n      that.enforceFocus()\n\n      var e = $.Event('shown.bs.modal', { relatedTarget: _relatedTarget })\n\n      transition ?\n        that.$dialog // wait for modal to slide in\n          .one('bsTransitionEnd', function () {\n            that.$element.trigger('focus').trigger(e)\n          })\n          .emulateTransitionEnd(Modal.TRANSITION_DURATION) :\n        that.$element.trigger('focus').trigger(e)\n    })\n  }\n\n  Modal.prototype.hide = function (e) {\n    if (e) e.preventDefault()\n\n    e = $.Event('hide.bs.modal')\n\n    this.$element.trigger(e)\n\n    if (!this.isShown || e.isDefaultPrevented()) return\n\n    this.isShown = false\n\n    this.escape()\n    this.resize()\n\n    $(document).off('focusin.bs.modal')\n\n    this.$element\n      .removeClass('in')\n      .off('click.dismiss.bs.modal')\n      .off('mouseup.dismiss.bs.modal')\n\n    this.$dialog.off('mousedown.dismiss.bs.modal')\n\n    $.support.transition && this.$element.hasClass('fade') ?\n      this.$element\n        .one('bsTransitionEnd', $.proxy(this.hideModal, this))\n        .emulateTransitionEnd(Modal.TRANSITION_DURATION) :\n      this.hideModal()\n  }\n\n  Modal.prototype.enforceFocus = function () {\n    $(document)\n      .off('focusin.bs.modal') // guard against infinite focus loop\n      .on('focusin.bs.modal', $.proxy(function (e) {\n        if (this.$element[0] !== e.target && !this.$element.has(e.target).length) {\n          this.$element.trigger('focus')\n        }\n      }, this))\n  }\n\n  Modal.prototype.escape = function () {\n    if (this.isShown && this.options.keyboard) {\n      this.$element.on('keydown.dismiss.bs.modal', $.proxy(function (e) {\n        e.which == 27 && this.hide()\n      }, this))\n    } else if (!this.isShown) {\n      this.$element.off('keydown.dismiss.bs.modal')\n    }\n  }\n\n  Modal.prototype.resize = function () {\n    if (this.isShown) {\n      $(window).on('resize.bs.modal', $.proxy(this.handleUpdate, this))\n    } else {\n      $(window).off('resize.bs.modal')\n    }\n  }\n\n  Modal.prototype.hideModal = function () {\n    var that = this\n    this.$element.hide()\n    this.backdrop(function () {\n      that.$body.removeClass('modal-open')\n      that.resetAdjustments()\n      that.resetScrollbar()\n      that.$element.trigger('hidden.bs.modal')\n    })\n  }\n\n  Modal.prototype.removeBackdrop = function () {\n    this.$backdrop && this.$backdrop.remove()\n    this.$backdrop = null\n  }\n\n  Modal.prototype.backdrop = function (callback) {\n    var that = this\n    var animate = this.$element.hasClass('fade') ? 'fade' : ''\n\n    if (this.isShown && this.options.backdrop) {\n      var doAnimate = $.support.transition && animate\n\n      this.$backdrop = $(document.createElement('div'))\n        .addClass('modal-backdrop ' + animate)\n        .appendTo(this.$body)\n\n      this.$element.on('click.dismiss.bs.modal', $.proxy(function (e) {\n        if (this.ignoreBackdropClick) {\n          this.ignoreBackdropClick = false\n          return\n        }\n        if (e.target !== e.currentTarget) return\n        this.options.backdrop == 'static'\n          ? this.$element[0].focus()\n          : this.hide()\n      }, this))\n\n      if (doAnimate) this.$backdrop[0].offsetWidth // force reflow\n\n      this.$backdrop.addClass('in')\n\n      if (!callback) return\n\n      doAnimate ?\n        this.$backdrop\n          .one('bsTransitionEnd', callback)\n          .emulateTransitionEnd(Modal.BACKDROP_TRANSITION_DURATION) :\n        callback()\n\n    } else if (!this.isShown && this.$backdrop) {\n      this.$backdrop.removeClass('in')\n\n      var callbackRemove = function () {\n        that.removeBackdrop()\n        callback && callback()\n      }\n      $.support.transition && this.$element.hasClass('fade') ?\n        this.$backdrop\n          .one('bsTransitionEnd', callbackRemove)\n          .emulateTransitionEnd(Modal.BACKDROP_TRANSITION_DURATION) :\n        callbackRemove()\n\n    } else if (callback) {\n      callback()\n    }\n  }\n\n  // these following methods are used to handle overflowing modals\n\n  Modal.prototype.handleUpdate = function () {\n    this.adjustDialog()\n  }\n\n  Modal.prototype.adjustDialog = function () {\n    var modalIsOverflowing = this.$element[0].scrollHeight > document.documentElement.clientHeight\n\n    this.$element.css({\n      paddingLeft:  !this.bodyIsOverflowing && modalIsOverflowing ? this.scrollbarWidth : '',\n      paddingRight: this.bodyIsOverflowing && !modalIsOverflowing ? this.scrollbarWidth : ''\n    })\n  }\n\n  Modal.prototype.resetAdjustments = function () {\n    this.$element.css({\n      paddingLeft: '',\n      paddingRight: ''\n    })\n  }\n\n  Modal.prototype.checkScrollbar = function () {\n    var fullWindowWidth = window.innerWidth\n    if (!fullWindowWidth) { // workaround for missing window.innerWidth in IE8\n      var documentElementRect = document.documentElement.getBoundingClientRect()\n      fullWindowWidth = documentElementRect.right - Math.abs(documentElementRect.left)\n    }\n    this.bodyIsOverflowing = document.body.clientWidth < fullWindowWidth\n    this.scrollbarWidth = this.measureScrollbar()\n  }\n\n  Modal.prototype.setScrollbar = function () {\n    var bodyPad = parseInt((this.$body.css('padding-right') || 0), 10)\n    this.originalBodyPad = document.body.style.paddingRight || ''\n    if (this.bodyIsOverflowing) this.$body.css('padding-right', bodyPad + this.scrollbarWidth)\n  }\n\n  Modal.prototype.resetScrollbar = function () {\n    this.$body.css('padding-right', this.originalBodyPad)\n  }\n\n  Modal.prototype.measureScrollbar = function () { // thx walsh\n    var scrollDiv = document.createElement('div')\n    scrollDiv.className = 'modal-scrollbar-measure'\n    this.$body.append(scrollDiv)\n    var scrollbarWidth = scrollDiv.offsetWidth - scrollDiv.clientWidth\n    this.$body[0].removeChild(scrollDiv)\n    return scrollbarWidth\n  }\n\n\n  // MODAL PLUGIN DEFINITION\n  // =======================\n\n  function Plugin(option, _relatedTarget) {\n    return this.each(function () {\n      var $this   = $(this)\n      var data    = $this.data('bs.modal')\n      var options = $.extend({}, Modal.DEFAULTS, $this.data(), typeof option == 'object' && option)\n\n      if (!data) $this.data('bs.modal', (data = new Modal(this, options)))\n      if (typeof option == 'string') data[option](_relatedTarget)\n      else if (options.show) data.show(_relatedTarget)\n    })\n  }\n\n  var old = $.fn.modal\n\n  $.fn.modal             = Plugin\n  $.fn.modal.Constructor = Modal\n\n\n  // MODAL NO CONFLICT\n  // =================\n\n  $.fn.modal.noConflict = function () {\n    $.fn.modal = old\n    return this\n  }\n\n\n  // MODAL DATA-API\n  // ==============\n\n  $(document).on('click.bs.modal.data-api', '[data-toggle=\"modal\"]', function (e) {\n    var $this   = $(this)\n    var href    = $this.attr('href')\n    var $target = $($this.attr('data-target') || (href && href.replace(/.*(?=#[^\\s]+$)/, ''))) // strip for ie7\n    var option  = $target.data('bs.modal') ? 'toggle' : $.extend({ remote: !/#/.test(href) && href }, $target.data(), $this.data())\n\n    if ($this.is('a')) e.preventDefault()\n\n    $target.one('show.bs.modal', function (showEvent) {\n      if (showEvent.isDefaultPrevented()) return // only register focus restorer if modal will actually get shown\n      $target.one('hidden.bs.modal', function () {\n        $this.is(':visible') && $this.trigger('focus')\n      })\n    })\n    Plugin.call($target, option, this)\n  })\n\n}(jQuery);\n\n/* ========================================================================\n * Bootstrap: tooltip.js v3.3.5\n * http://getbootstrap.com/javascript/#tooltip\n * Inspired by the original jQuery.tipsy by Jason Frame\n * ========================================================================\n * Copyright 2011-2015 Twitter, Inc.\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)\n * ======================================================================== */\n\n\n+function ($) {\n  'use strict';\n\n  // TOOLTIP PUBLIC CLASS DEFINITION\n  // ===============================\n\n  var Tooltip = function (element, options) {\n    this.type       = null\n    this.options    = null\n    this.enabled    = null\n    this.timeout    = null\n    this.hoverState = null\n    this.$element   = null\n    this.inState    = null\n\n    this.init('tooltip', element, options)\n  }\n\n  Tooltip.VERSION  = '3.3.5'\n\n  Tooltip.TRANSITION_DURATION = 150\n\n  Tooltip.DEFAULTS = {\n    animation: true,\n    placement: 'top',\n    selector: false,\n    template: '<div class=\"tooltip\" role=\"tooltip\"><div class=\"tooltip-arrow\"></div><div class=\"tooltip-inner\"></div></div>',\n    trigger: 'hover focus',\n    title: '',\n    delay: 0,\n    html: false,\n    container: false,\n    viewport: {\n      selector: 'body',\n      padding: 0\n    }\n  }\n\n  Tooltip.prototype.init = function (type, element, options) {\n    this.enabled   = true\n    this.type      = type\n    this.$element  = $(element)\n    this.options   = this.getOptions(options)\n    this.$viewport = this.options.viewport && $($.isFunction(this.options.viewport) ? this.options.viewport.call(this, this.$element) : (this.options.viewport.selector || this.options.viewport))\n    this.inState   = { click: false, hover: false, focus: false }\n\n    if (this.$element[0] instanceof document.constructor && !this.options.selector) {\n      throw new Error('`selector` option must be specified when initializing ' + this.type + ' on the window.document object!')\n    }\n\n    var triggers = this.options.trigger.split(' ')\n\n    for (var i = triggers.length; i--;) {\n      var trigger = triggers[i]\n\n      if (trigger == 'click') {\n        this.$element.on('click.' + this.type, this.options.selector, $.proxy(this.toggle, this))\n      } else if (trigger != 'manual') {\n        var eventIn  = trigger == 'hover' ? 'mouseenter' : 'focusin'\n        var eventOut = trigger == 'hover' ? 'mouseleave' : 'focusout'\n\n        this.$element.on(eventIn  + '.' + this.type, this.options.selector, $.proxy(this.enter, this))\n        this.$element.on(eventOut + '.' + this.type, this.options.selector, $.proxy(this.leave, this))\n      }\n    }\n\n    this.options.selector ?\n      (this._options = $.extend({}, this.options, { trigger: 'manual', selector: '' })) :\n      this.fixTitle()\n  }\n\n  Tooltip.prototype.getDefaults = function () {\n    return Tooltip.DEFAULTS\n  }\n\n  Tooltip.prototype.getOptions = function (options) {\n    options = $.extend({}, this.getDefaults(), this.$element.data(), options)\n\n    if (options.delay && typeof options.delay == 'number') {\n      options.delay = {\n        show: options.delay,\n        hide: options.delay\n      }\n    }\n\n    return options\n  }\n\n  Tooltip.prototype.getDelegateOptions = function () {\n    var options  = {}\n    var defaults = this.getDefaults()\n\n    this._options && $.each(this._options, function (key, value) {\n      if (defaults[key] != value) options[key] = value\n    })\n\n    return options\n  }\n\n  Tooltip.prototype.enter = function (obj) {\n    var self = obj instanceof this.constructor ?\n      obj : $(obj.currentTarget).data('bs.' + this.type)\n\n    if (!self) {\n      self = new this.constructor(obj.currentTarget, this.getDelegateOptions())\n      $(obj.currentTarget).data('bs.' + this.type, self)\n    }\n\n    if (obj instanceof $.Event) {\n      self.inState[obj.type == 'focusin' ? 'focus' : 'hover'] = true\n    }\n\n    if (self.tip().hasClass('in') || self.hoverState == 'in') {\n      self.hoverState = 'in'\n      return\n    }\n\n    clearTimeout(self.timeout)\n\n    self.hoverState = 'in'\n\n    if (!self.options.delay || !self.options.delay.show) return self.show()\n\n    self.timeout = setTimeout(function () {\n      if (self.hoverState == 'in') self.show()\n    }, self.options.delay.show)\n  }\n\n  Tooltip.prototype.isInStateTrue = function () {\n    for (var key in this.inState) {\n      if (this.inState[key]) return true\n    }\n\n    return false\n  }\n\n  Tooltip.prototype.leave = function (obj) {\n    var self = obj instanceof this.constructor ?\n      obj : $(obj.currentTarget).data('bs.' + this.type)\n\n    if (!self) {\n      self = new this.constructor(obj.currentTarget, this.getDelegateOptions())\n      $(obj.currentTarget).data('bs.' + this.type, self)\n    }\n\n    if (obj instanceof $.Event) {\n      self.inState[obj.type == 'focusout' ? 'focus' : 'hover'] = false\n    }\n\n    if (self.isInStateTrue()) return\n\n    clearTimeout(self.timeout)\n\n    self.hoverState = 'out'\n\n    if (!self.options.delay || !self.options.delay.hide) return self.hide()\n\n    self.timeout = setTimeout(function () {\n      if (self.hoverState == 'out') self.hide()\n    }, self.options.delay.hide)\n  }\n\n  Tooltip.prototype.show = function () {\n    var e = $.Event('show.bs.' + this.type)\n\n    if (this.hasContent() && this.enabled) {\n      this.$element.trigger(e)\n\n      var inDom = $.contains(this.$element[0].ownerDocument.documentElement, this.$element[0])\n      if (e.isDefaultPrevented() || !inDom) return\n      var that = this\n\n      var $tip = this.tip()\n\n      var tipId = this.getUID(this.type)\n\n      this.setContent()\n      $tip.attr('id', tipId)\n      this.$element.attr('aria-describedby', tipId)\n\n      if (this.options.animation) $tip.addClass('fade')\n\n      var placement = typeof this.options.placement == 'function' ?\n        this.options.placement.call(this, $tip[0], this.$element[0]) :\n        this.options.placement\n\n      var autoToken = /\\s?auto?\\s?/i\n      var autoPlace = autoToken.test(placement)\n      if (autoPlace) placement = placement.replace(autoToken, '') || 'top'\n\n      $tip\n        .detach()\n        .css({ top: 0, left: 0, display: 'block' })\n        .addClass(placement)\n        .data('bs.' + this.type, this)\n\n      this.options.container ? $tip.appendTo(this.options.container) : $tip.insertAfter(this.$element)\n      this.$element.trigger('inserted.bs.' + this.type)\n\n      var pos          = this.getPosition()\n      var actualWidth  = $tip[0].offsetWidth\n      var actualHeight = $tip[0].offsetHeight\n\n      if (autoPlace) {\n        var orgPlacement = placement\n        var viewportDim = this.getPosition(this.$viewport)\n\n        placement = placement == 'bottom' && pos.bottom + actualHeight > viewportDim.bottom ? 'top'    :\n                    placement == 'top'    && pos.top    - actualHeight < viewportDim.top    ? 'bottom' :\n                    placement == 'right'  && pos.right  + actualWidth  > viewportDim.width  ? 'left'   :\n                    placement == 'left'   && pos.left   - actualWidth  < viewportDim.left   ? 'right'  :\n                    placement\n\n        $tip\n          .removeClass(orgPlacement)\n          .addClass(placement)\n      }\n\n      var calculatedOffset = this.getCalculatedOffset(placement, pos, actualWidth, actualHeight)\n\n      this.applyPlacement(calculatedOffset, placement)\n\n      var complete = function () {\n        var prevHoverState = that.hoverState\n        that.$element.trigger('shown.bs.' + that.type)\n        that.hoverState = null\n\n        if (prevHoverState == 'out') that.leave(that)\n      }\n\n      $.support.transition && this.$tip.hasClass('fade') ?\n        $tip\n          .one('bsTransitionEnd', complete)\n          .emulateTransitionEnd(Tooltip.TRANSITION_DURATION) :\n        complete()\n    }\n  }\n\n  Tooltip.prototype.applyPlacement = function (offset, placement) {\n    var $tip   = this.tip()\n    var width  = $tip[0].offsetWidth\n    var height = $tip[0].offsetHeight\n\n    // manually read margins because getBoundingClientRect includes difference\n    var marginTop = parseInt($tip.css('margin-top'), 10)\n    var marginLeft = parseInt($tip.css('margin-left'), 10)\n\n    // we must check for NaN for ie 8/9\n    if (isNaN(marginTop))  marginTop  = 0\n    if (isNaN(marginLeft)) marginLeft = 0\n\n    offset.top  += marginTop\n    offset.left += marginLeft\n\n    // $.fn.offset doesn't round pixel values\n    // so we use setOffset directly with our own function B-0\n    $.offset.setOffset($tip[0], $.extend({\n      using: function (props) {\n        $tip.css({\n          top: Math.round(props.top),\n          left: Math.round(props.left)\n        })\n      }\n    }, offset), 0)\n\n    $tip.addClass('in')\n\n    // check to see if placing tip in new offset caused the tip to resize itself\n    var actualWidth  = $tip[0].offsetWidth\n    var actualHeight = $tip[0].offsetHeight\n\n    if (placement == 'top' && actualHeight != height) {\n      offset.top = offset.top + height - actualHeight\n    }\n\n    var delta = this.getViewportAdjustedDelta(placement, offset, actualWidth, actualHeight)\n\n    if (delta.left) offset.left += delta.left\n    else offset.top += delta.top\n\n    var isVertical          = /top|bottom/.test(placement)\n    var arrowDelta          = isVertical ? delta.left * 2 - width + actualWidth : delta.top * 2 - height + actualHeight\n    var arrowOffsetPosition = isVertical ? 'offsetWidth' : 'offsetHeight'\n\n    $tip.offset(offset)\n    this.replaceArrow(arrowDelta, $tip[0][arrowOffsetPosition], isVertical)\n  }\n\n  Tooltip.prototype.replaceArrow = function (delta, dimension, isVertical) {\n    this.arrow()\n      .css(isVertical ? 'left' : 'top', 50 * (1 - delta / dimension) + '%')\n      .css(isVertical ? 'top' : 'left', '')\n  }\n\n  Tooltip.prototype.setContent = function () {\n    var $tip  = this.tip()\n    var title = this.getTitle()\n\n    $tip.find('.tooltip-inner')[this.options.html ? 'html' : 'text'](title)\n    $tip.removeClass('fade in top bottom left right')\n  }\n\n  Tooltip.prototype.hide = function (callback) {\n    var that = this\n    var $tip = $(this.$tip)\n    var e    = $.Event('hide.bs.' + this.type)\n\n    function complete() {\n      if (that.hoverState != 'in') $tip.detach()\n      that.$element\n        .removeAttr('aria-describedby')\n        .trigger('hidden.bs.' + that.type)\n      callback && callback()\n    }\n\n    this.$element.trigger(e)\n\n    if (e.isDefaultPrevented()) return\n\n    $tip.removeClass('in')\n\n    $.support.transition && $tip.hasClass('fade') ?\n      $tip\n        .one('bsTransitionEnd', complete)\n        .emulateTransitionEnd(Tooltip.TRANSITION_DURATION) :\n      complete()\n\n    this.hoverState = null\n\n    return this\n  }\n\n  Tooltip.prototype.fixTitle = function () {\n    var $e = this.$element\n    if ($e.attr('title') || typeof $e.attr('data-original-title') != 'string') {\n      $e.attr('data-original-title', $e.attr('title') || '').attr('title', '')\n    }\n  }\n\n  Tooltip.prototype.hasContent = function () {\n    return this.getTitle()\n  }\n\n  Tooltip.prototype.getPosition = function ($element) {\n    $element   = $element || this.$element\n\n    var el     = $element[0]\n    var isBody = el.tagName == 'BODY'\n\n    var elRect    = el.getBoundingClientRect()\n    if (elRect.width == null) {\n      // width and height are missing in IE8, so compute them manually; see https://github.com/twbs/bootstrap/issues/14093\n      elRect = $.extend({}, elRect, { width: elRect.right - elRect.left, height: elRect.bottom - elRect.top })\n    }\n    var elOffset  = isBody ? { top: 0, left: 0 } : $element.offset()\n    var scroll    = { scroll: isBody ? document.documentElement.scrollTop || document.body.scrollTop : $element.scrollTop() }\n    var outerDims = isBody ? { width: $(window).width(), height: $(window).height() } : null\n\n    return $.extend({}, elRect, scroll, outerDims, elOffset)\n  }\n\n  Tooltip.prototype.getCalculatedOffset = function (placement, pos, actualWidth, actualHeight) {\n    return placement == 'bottom' ? { top: pos.top + pos.height,   left: pos.left + pos.width / 2 - actualWidth / 2 } :\n           placement == 'top'    ? { top: pos.top - actualHeight, left: pos.left + pos.width / 2 - actualWidth / 2 } :\n           placement == 'left'   ? { top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left - actualWidth } :\n        /* placement == 'right' */ { top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left + pos.width }\n\n  }\n\n  Tooltip.prototype.getViewportAdjustedDelta = function (placement, pos, actualWidth, actualHeight) {\n    var delta = { top: 0, left: 0 }\n    if (!this.$viewport) return delta\n\n    var viewportPadding = this.options.viewport && this.options.viewport.padding || 0\n    var viewportDimensions = this.getPosition(this.$viewport)\n\n    if (/right|left/.test(placement)) {\n      var topEdgeOffset    = pos.top - viewportPadding - viewportDimensions.scroll\n      var bottomEdgeOffset = pos.top + viewportPadding - viewportDimensions.scroll + actualHeight\n      if (topEdgeOffset < viewportDimensions.top) { // top overflow\n        delta.top = viewportDimensions.top - topEdgeOffset\n      } else if (bottomEdgeOffset > viewportDimensions.top + viewportDimensions.height) { // bottom overflow\n        delta.top = viewportDimensions.top + viewportDimensions.height - bottomEdgeOffset\n      }\n    } else {\n      var leftEdgeOffset  = pos.left - viewportPadding\n      var rightEdgeOffset = pos.left + viewportPadding + actualWidth\n      if (leftEdgeOffset < viewportDimensions.left) { // left overflow\n        delta.left = viewportDimensions.left - leftEdgeOffset\n      } else if (rightEdgeOffset > viewportDimensions.right) { // right overflow\n        delta.left = viewportDimensions.left + viewportDimensions.width - rightEdgeOffset\n      }\n    }\n\n    return delta\n  }\n\n  Tooltip.prototype.getTitle = function () {\n    var title\n    var $e = this.$element\n    var o  = this.options\n\n    title = $e.attr('data-original-title')\n      || (typeof o.title == 'function' ? o.title.call($e[0]) :  o.title)\n\n    return title\n  }\n\n  Tooltip.prototype.getUID = function (prefix) {\n    do prefix += ~~(Math.random() * 1000000)\n    while (document.getElementById(prefix))\n    return prefix\n  }\n\n  Tooltip.prototype.tip = function () {\n    if (!this.$tip) {\n      this.$tip = $(this.options.template)\n      if (this.$tip.length != 1) {\n        throw new Error(this.type + ' `template` option must consist of exactly 1 top-level element!')\n      }\n    }\n    return this.$tip\n  }\n\n  Tooltip.prototype.arrow = function () {\n    return (this.$arrow = this.$arrow || this.tip().find('.tooltip-arrow'))\n  }\n\n  Tooltip.prototype.enable = function () {\n    this.enabled = true\n  }\n\n  Tooltip.prototype.disable = function () {\n    this.enabled = false\n  }\n\n  Tooltip.prototype.toggleEnabled = function () {\n    this.enabled = !this.enabled\n  }\n\n  Tooltip.prototype.toggle = function (e) {\n    var self = this\n    if (e) {\n      self = $(e.currentTarget).data('bs.' + this.type)\n      if (!self) {\n        self = new this.constructor(e.currentTarget, this.getDelegateOptions())\n        $(e.currentTarget).data('bs.' + this.type, self)\n      }\n    }\n\n    if (e) {\n      self.inState.click = !self.inState.click\n      if (self.isInStateTrue()) self.enter(self)\n      else self.leave(self)\n    } else {\n      self.tip().hasClass('in') ? self.leave(self) : self.enter(self)\n    }\n  }\n\n  Tooltip.prototype.destroy = function () {\n    var that = this\n    clearTimeout(this.timeout)\n    this.hide(function () {\n      that.$element.off('.' + that.type).removeData('bs.' + that.type)\n      if (that.$tip) {\n        that.$tip.detach()\n      }\n      that.$tip = null\n      that.$arrow = null\n      that.$viewport = null\n    })\n  }\n\n\n  // TOOLTIP PLUGIN DEFINITION\n  // =========================\n\n  function Plugin(option) {\n    return this.each(function () {\n      var $this   = $(this)\n      var data    = $this.data('bs.tooltip')\n      var options = typeof option == 'object' && option\n\n      if (!data && /destroy|hide/.test(option)) return\n      if (!data) $this.data('bs.tooltip', (data = new Tooltip(this, options)))\n      if (typeof option == 'string') data[option]()\n    })\n  }\n\n  var old = $.fn.tooltip\n\n  $.fn.tooltip             = Plugin\n  $.fn.tooltip.Constructor = Tooltip\n\n\n  // TOOLTIP NO CONFLICT\n  // ===================\n\n  $.fn.tooltip.noConflict = function () {\n    $.fn.tooltip = old\n    return this\n  }\n\n}(jQuery);\n\n/* ========================================================================\n * Bootstrap: popover.js v3.3.5\n * http://getbootstrap.com/javascript/#popovers\n * ========================================================================\n * Copyright 2011-2015 Twitter, Inc.\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)\n * ======================================================================== */\n\n\n+function ($) {\n  'use strict';\n\n  // POPOVER PUBLIC CLASS DEFINITION\n  // ===============================\n\n  var Popover = function (element, options) {\n    this.init('popover', element, options)\n  }\n\n  if (!$.fn.tooltip) throw new Error('Popover requires tooltip.js')\n\n  Popover.VERSION  = '3.3.5'\n\n  Popover.DEFAULTS = $.extend({}, $.fn.tooltip.Constructor.DEFAULTS, {\n    placement: 'right',\n    trigger: 'click',\n    content: '',\n    template: '<div class=\"popover\" role=\"tooltip\"><div class=\"arrow\"></div><h3 class=\"popover-title\"></h3><div class=\"popover-content\"></div></div>'\n  })\n\n\n  // NOTE: POPOVER EXTENDS tooltip.js\n  // ================================\n\n  Popover.prototype = $.extend({}, $.fn.tooltip.Constructor.prototype)\n\n  Popover.prototype.constructor = Popover\n\n  Popover.prototype.getDefaults = function () {\n    return Popover.DEFAULTS\n  }\n\n  Popover.prototype.setContent = function () {\n    var $tip    = this.tip()\n    var title   = this.getTitle()\n    var content = this.getContent()\n\n    $tip.find('.popover-title')[this.options.html ? 'html' : 'text'](title)\n    $tip.find('.popover-content').children().detach().end()[ // we use append for html objects to maintain js events\n      this.options.html ? (typeof content == 'string' ? 'html' : 'append') : 'text'\n    ](content)\n\n    $tip.removeClass('fade top bottom left right in')\n\n    // IE8 doesn't accept hiding via the `:empty` pseudo selector, we have to do\n    // this manually by checking the contents.\n    if (!$tip.find('.popover-title').html()) $tip.find('.popover-title').hide()\n  }\n\n  Popover.prototype.hasContent = function () {\n    return this.getTitle() || this.getContent()\n  }\n\n  Popover.prototype.getContent = function () {\n    var $e = this.$element\n    var o  = this.options\n\n    return $e.attr('data-content')\n      || (typeof o.content == 'function' ?\n            o.content.call($e[0]) :\n            o.content)\n  }\n\n  Popover.prototype.arrow = function () {\n    return (this.$arrow = this.$arrow || this.tip().find('.arrow'))\n  }\n\n\n  // POPOVER PLUGIN DEFINITION\n  // =========================\n\n  function Plugin(option) {\n    return this.each(function () {\n      var $this   = $(this)\n      var data    = $this.data('bs.popover')\n      var options = typeof option == 'object' && option\n\n      if (!data && /destroy|hide/.test(option)) return\n      if (!data) $this.data('bs.popover', (data = new Popover(this, options)))\n      if (typeof option == 'string') data[option]()\n    })\n  }\n\n  var old = $.fn.popover\n\n  $.fn.popover             = Plugin\n  $.fn.popover.Constructor = Popover\n\n\n  // POPOVER NO CONFLICT\n  // ===================\n\n  $.fn.popover.noConflict = function () {\n    $.fn.popover = old\n    return this\n  }\n\n}(jQuery);\n\n/* ========================================================================\n * Bootstrap: scrollspy.js v3.3.5\n * http://getbootstrap.com/javascript/#scrollspy\n * ========================================================================\n * Copyright 2011-2015 Twitter, Inc.\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)\n * ======================================================================== */\n\n\n+function ($) {\n  'use strict';\n\n  // SCROLLSPY CLASS DEFINITION\n  // ==========================\n\n  function ScrollSpy(element, options) {\n    this.$body          = $(document.body)\n    this.$scrollElement = $(element).is(document.body) ? $(window) : $(element)\n    this.options        = $.extend({}, ScrollSpy.DEFAULTS, options)\n    this.selector       = (this.options.target || '') + ' .nav li > a'\n    this.offsets        = []\n    this.targets        = []\n    this.activeTarget   = null\n    this.scrollHeight   = 0\n\n    this.$scrollElement.on('scroll.bs.scrollspy', $.proxy(this.process, this))\n    this.refresh()\n    this.process()\n  }\n\n  ScrollSpy.VERSION  = '3.3.5'\n\n  ScrollSpy.DEFAULTS = {\n    offset: 10\n  }\n\n  ScrollSpy.prototype.getScrollHeight = function () {\n    return this.$scrollElement[0].scrollHeight || Math.max(this.$body[0].scrollHeight, document.documentElement.scrollHeight)\n  }\n\n  ScrollSpy.prototype.refresh = function () {\n    var that          = this\n    var offsetMethod  = 'offset'\n    var offsetBase    = 0\n\n    this.offsets      = []\n    this.targets      = []\n    this.scrollHeight = this.getScrollHeight()\n\n    if (!$.isWindow(this.$scrollElement[0])) {\n      offsetMethod = 'position'\n      offsetBase   = this.$scrollElement.scrollTop()\n    }\n\n    this.$body\n      .find(this.selector)\n      .map(function () {\n        var $el   = $(this)\n        var href  = $el.data('target') || $el.attr('href')\n        var $href = /^#./.test(href) && $(href)\n\n        return ($href\n          && $href.length\n          && $href.is(':visible')\n          && [[$href[offsetMethod]().top + offsetBase, href]]) || null\n      })\n      .sort(function (a, b) { return a[0] - b[0] })\n      .each(function () {\n        that.offsets.push(this[0])\n        that.targets.push(this[1])\n      })\n  }\n\n  ScrollSpy.prototype.process = function () {\n    var scrollTop    = this.$scrollElement.scrollTop() + this.options.offset\n    var scrollHeight = this.getScrollHeight()\n    var maxScroll    = this.options.offset + scrollHeight - this.$scrollElement.height()\n    var offsets      = this.offsets\n    var targets      = this.targets\n    var activeTarget = this.activeTarget\n    var i\n\n    if (this.scrollHeight != scrollHeight) {\n      this.refresh()\n    }\n\n    if (scrollTop >= maxScroll) {\n      return activeTarget != (i = targets[targets.length - 1]) && this.activate(i)\n    }\n\n    if (activeTarget && scrollTop < offsets[0]) {\n      this.activeTarget = null\n      return this.clear()\n    }\n\n    for (i = offsets.length; i--;) {\n      activeTarget != targets[i]\n        && scrollTop >= offsets[i]\n        && (offsets[i + 1] === undefined || scrollTop < offsets[i + 1])\n        && this.activate(targets[i])\n    }\n  }\n\n  ScrollSpy.prototype.activate = function (target) {\n    this.activeTarget = target\n\n    this.clear()\n\n    var selector = this.selector +\n      '[data-target=\"' + target + '\"],' +\n      this.selector + '[href=\"' + target + '\"]'\n\n    var active = $(selector)\n      .parents('li')\n      .addClass('active')\n\n    if (active.parent('.dropdown-menu').length) {\n      active = active\n        .closest('li.dropdown')\n        .addClass('active')\n    }\n\n    active.trigger('activate.bs.scrollspy')\n  }\n\n  ScrollSpy.prototype.clear = function () {\n    $(this.selector)\n      .parentsUntil(this.options.target, '.active')\n      .removeClass('active')\n  }\n\n\n  // SCROLLSPY PLUGIN DEFINITION\n  // ===========================\n\n  function Plugin(option) {\n    return this.each(function () {\n      var $this   = $(this)\n      var data    = $this.data('bs.scrollspy')\n      var options = typeof option == 'object' && option\n\n      if (!data) $this.data('bs.scrollspy', (data = new ScrollSpy(this, options)))\n      if (typeof option == 'string') data[option]()\n    })\n  }\n\n  var old = $.fn.scrollspy\n\n  $.fn.scrollspy             = Plugin\n  $.fn.scrollspy.Constructor = ScrollSpy\n\n\n  // SCROLLSPY NO CONFLICT\n  // =====================\n\n  $.fn.scrollspy.noConflict = function () {\n    $.fn.scrollspy = old\n    return this\n  }\n\n\n  // SCROLLSPY DATA-API\n  // ==================\n\n  $(window).on('load.bs.scrollspy.data-api', function () {\n    $('[data-spy=\"scroll\"]').each(function () {\n      var $spy = $(this)\n      Plugin.call($spy, $spy.data())\n    })\n  })\n\n}(jQuery);\n\n/* ========================================================================\n * Bootstrap: tab.js v3.3.5\n * http://getbootstrap.com/javascript/#tabs\n * ========================================================================\n * Copyright 2011-2015 Twitter, Inc.\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)\n * ======================================================================== */\n\n\n+function ($) {\n  'use strict';\n\n  // TAB CLASS DEFINITION\n  // ====================\n\n  var Tab = function (element) {\n    // jscs:disable requireDollarBeforejQueryAssignment\n    this.element = $(element)\n    // jscs:enable requireDollarBeforejQueryAssignment\n  }\n\n  Tab.VERSION = '3.3.5'\n\n  Tab.TRANSITION_DURATION = 150\n\n  Tab.prototype.show = function () {\n    var $this    = this.element\n    var $ul      = $this.closest('ul:not(.dropdown-menu)')\n    var selector = $this.data('target')\n\n    if (!selector) {\n      selector = $this.attr('href')\n      selector = selector && selector.replace(/.*(?=#[^\\s]*$)/, '') // strip for ie7\n    }\n\n    if ($this.parent('li').hasClass('active')) return\n\n    var $previous = $ul.find('.active:last a')\n    var hideEvent = $.Event('hide.bs.tab', {\n      relatedTarget: $this[0]\n    })\n    var showEvent = $.Event('show.bs.tab', {\n      relatedTarget: $previous[0]\n    })\n\n    $previous.trigger(hideEvent)\n    $this.trigger(showEvent)\n\n    if (showEvent.isDefaultPrevented() || hideEvent.isDefaultPrevented()) return\n\n    var $target = $(selector)\n\n    this.activate($this.closest('li'), $ul)\n    this.activate($target, $target.parent(), function () {\n      $previous.trigger({\n        type: 'hidden.bs.tab',\n        relatedTarget: $this[0]\n      })\n      $this.trigger({\n        type: 'shown.bs.tab',\n        relatedTarget: $previous[0]\n      })\n    })\n  }\n\n  Tab.prototype.activate = function (element, container, callback) {\n    var $active    = container.find('> .active')\n    var transition = callback\n      && $.support.transition\n      && ($active.length && $active.hasClass('fade') || !!container.find('> .fade').length)\n\n    function next() {\n      $active\n        .removeClass('active')\n        .find('> .dropdown-menu > .active')\n          .removeClass('active')\n        .end()\n        .find('[data-toggle=\"tab\"]')\n          .attr('aria-expanded', false)\n\n      element\n        .addClass('active')\n        .find('[data-toggle=\"tab\"]')\n          .attr('aria-expanded', true)\n\n      if (transition) {\n        element[0].offsetWidth // reflow for transition\n        element.addClass('in')\n      } else {\n        element.removeClass('fade')\n      }\n\n      if (element.parent('.dropdown-menu').length) {\n        element\n          .closest('li.dropdown')\n            .addClass('active')\n          .end()\n          .find('[data-toggle=\"tab\"]')\n            .attr('aria-expanded', true)\n      }\n\n      callback && callback()\n    }\n\n    $active.length && transition ?\n      $active\n        .one('bsTransitionEnd', next)\n        .emulateTransitionEnd(Tab.TRANSITION_DURATION) :\n      next()\n\n    $active.removeClass('in')\n  }\n\n\n  // TAB PLUGIN DEFINITION\n  // =====================\n\n  function Plugin(option) {\n    return this.each(function () {\n      var $this = $(this)\n      var data  = $this.data('bs.tab')\n\n      if (!data) $this.data('bs.tab', (data = new Tab(this)))\n      if (typeof option == 'string') data[option]()\n    })\n  }\n\n  var old = $.fn.tab\n\n  $.fn.tab             = Plugin\n  $.fn.tab.Constructor = Tab\n\n\n  // TAB NO CONFLICT\n  // ===============\n\n  $.fn.tab.noConflict = function () {\n    $.fn.tab = old\n    return this\n  }\n\n\n  // TAB DATA-API\n  // ============\n\n  var clickHandler = function (e) {\n    e.preventDefault()\n    Plugin.call($(this), 'show')\n  }\n\n  $(document)\n    .on('click.bs.tab.data-api', '[data-toggle=\"tab\"]', clickHandler)\n    .on('click.bs.tab.data-api', '[data-toggle=\"pill\"]', clickHandler)\n\n}(jQuery);\n\n/* ========================================================================\n * Bootstrap: affix.js v3.3.5\n * http://getbootstrap.com/javascript/#affix\n * ========================================================================\n * Copyright 2011-2015 Twitter, Inc.\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)\n * ======================================================================== */\n\n\n+function ($) {\n  'use strict';\n\n  // AFFIX CLASS DEFINITION\n  // ======================\n\n  var Affix = function (element, options) {\n    this.options = $.extend({}, Affix.DEFAULTS, options)\n\n    this.$target = $(this.options.target)\n      .on('scroll.bs.affix.data-api', $.proxy(this.checkPosition, this))\n      .on('click.bs.affix.data-api',  $.proxy(this.checkPositionWithEventLoop, this))\n\n    this.$element     = $(element)\n    this.affixed      = null\n    this.unpin        = null\n    this.pinnedOffset = null\n\n    this.checkPosition()\n  }\n\n  Affix.VERSION  = '3.3.5'\n\n  Affix.RESET    = 'affix affix-top affix-bottom'\n\n  Affix.DEFAULTS = {\n    offset: 0,\n    target: window\n  }\n\n  Affix.prototype.getState = function (scrollHeight, height, offsetTop, offsetBottom) {\n    var scrollTop    = this.$target.scrollTop()\n    var position     = this.$element.offset()\n    var targetHeight = this.$target.height()\n\n    if (offsetTop != null && this.affixed == 'top') return scrollTop < offsetTop ? 'top' : false\n\n    if (this.affixed == 'bottom') {\n      if (offsetTop != null) return (scrollTop + this.unpin <= position.top) ? false : 'bottom'\n      return (scrollTop + targetHeight <= scrollHeight - offsetBottom) ? false : 'bottom'\n    }\n\n    var initializing   = this.affixed == null\n    var colliderTop    = initializing ? scrollTop : position.top\n    var colliderHeight = initializing ? targetHeight : height\n\n    if (offsetTop != null && scrollTop <= offsetTop) return 'top'\n    if (offsetBottom != null && (colliderTop + colliderHeight >= scrollHeight - offsetBottom)) return 'bottom'\n\n    return false\n  }\n\n  Affix.prototype.getPinnedOffset = function () {\n    if (this.pinnedOffset) return this.pinnedOffset\n    this.$element.removeClass(Affix.RESET).addClass('affix')\n    var scrollTop = this.$target.scrollTop()\n    var position  = this.$element.offset()\n    return (this.pinnedOffset = position.top - scrollTop)\n  }\n\n  Affix.prototype.checkPositionWithEventLoop = function () {\n    setTimeout($.proxy(this.checkPosition, this), 1)\n  }\n\n  Affix.prototype.checkPosition = function () {\n    if (!this.$element.is(':visible')) return\n\n    var height       = this.$element.height()\n    var offset       = this.options.offset\n    var offsetTop    = offset.top\n    var offsetBottom = offset.bottom\n    var scrollHeight = Math.max($(document).height(), $(document.body).height())\n\n    if (typeof offset != 'object')         offsetBottom = offsetTop = offset\n    if (typeof offsetTop == 'function')    offsetTop    = offset.top(this.$element)\n    if (typeof offsetBottom == 'function') offsetBottom = offset.bottom(this.$element)\n\n    var affix = this.getState(scrollHeight, height, offsetTop, offsetBottom)\n\n    if (this.affixed != affix) {\n      if (this.unpin != null) this.$element.css('top', '')\n\n      var affixType = 'affix' + (affix ? '-' + affix : '')\n      var e         = $.Event(affixType + '.bs.affix')\n\n      this.$element.trigger(e)\n\n      if (e.isDefaultPrevented()) return\n\n      this.affixed = affix\n      this.unpin = affix == 'bottom' ? this.getPinnedOffset() : null\n\n      this.$element\n        .removeClass(Affix.RESET)\n        .addClass(affixType)\n        .trigger(affixType.replace('affix', 'affixed') + '.bs.affix')\n    }\n\n    if (affix == 'bottom') {\n      this.$element.offset({\n        top: scrollHeight - height - offsetBottom\n      })\n    }\n  }\n\n\n  // AFFIX PLUGIN DEFINITION\n  // =======================\n\n  function Plugin(option) {\n    return this.each(function () {\n      var $this   = $(this)\n      var data    = $this.data('bs.affix')\n      var options = typeof option == 'object' && option\n\n      if (!data) $this.data('bs.affix', (data = new Affix(this, options)))\n      if (typeof option == 'string') data[option]()\n    })\n  }\n\n  var old = $.fn.affix\n\n  $.fn.affix             = Plugin\n  $.fn.affix.Constructor = Affix\n\n\n  // AFFIX NO CONFLICT\n  // =================\n\n  $.fn.affix.noConflict = function () {\n    $.fn.affix = old\n    return this\n  }\n\n\n  // AFFIX DATA-API\n  // ==============\n\n  $(window).on('load', function () {\n    $('[data-spy=\"affix\"]').each(function () {\n      var $spy = $(this)\n      var data = $spy.data()\n\n      data.offset = data.offset || {}\n\n      if (data.offsetBottom != null) data.offset.bottom = data.offsetBottom\n      if (data.offsetTop    != null) data.offset.top    = data.offsetTop\n\n      Plugin.call($spy, data)\n    })\n  })\n\n}(jQuery);\n"
  },
  {
    "path": "app_backend/static/js/custom.js",
    "content": "/**\n * Created by zhanghe on 16-1-31.\n */\n\n/* 轮播大图延时加载 */\nfunction lazyContainer(searchNode) {\n    $(searchNode).find('.active').find('img.lazy').each(function () {\n        var imgSrc = $(this).attr('data-src');\n        if (imgSrc) {\n            $(this).attr('src', imgSrc);\n            $(this).attr('data-src', '');\n        }\n    });\n}\n\n$('#myCarousel').bind('slid.bs.carousel', function () {\n    lazyContainer(this);\n});\n\nlazyContainer('#myCarousel');\n\n\n/* 生成工具提示 */\n$('[rel=\"tooltip\"]').tooltip();\n\n\n/* 附加导航 */\n$(function () {\n    // 滚动页面侧边悬浮动态导航宽度控制\n    $(window).resize(function () {\n        $('#affix_nav_ul').width($('#affix_nav_ul').parent().width());\n        //console.log($('.container').width());\n        // 如果屏幕宽度小于940px 隐藏侧边导航\n        if ($('.container').width() <= 940) {\n            $('#affix_nav_ul').hide();\n        } else {\n            $('#affix_nav_ul').show();\n        }\n    });\n    $(window).resize();\n});\n\n\n/* 按钮加载状态 */\n// html button 标签其中 autocomplete=\"off\" 属性是针对FF浏览器在页面加载之后，禁用状态不会自动解除用的。\n$(function () {\n    $(\".btn-load\").click(function () {\n        $(this).button('loading').delay(1000).queue(function () {\n            $(this).button('reset').dequeue();\n        });\n    });\n});\n\n\n/* 返回顶部 */\n$('#top-link').click(function () {\n    $('html,body').animate({scrollTop: 0}, 'slow');\n    return false;\n});\nif (($(window).height() + 100) < $(document).height()) {\n    $('#top-link-block').removeClass('hidden').affix({\n        // how far to scroll down before link \"slides\" into view\n        offset: {top: 100}\n    });\n}\n\n/* 侧滑插件 */\n/*\nvar slideout = new Slideout({\n    'panel': document.getElementById('panel'),\n    'menu': document.getElementById('menu'),\n    'padding': 256,\n    'tolerance': 70\n});\n */\n\n\n/**\n * Vertically center Bootstrap 3 modals so they aren't always stuck at the top\n */\n$(function() {\n    function reposition() {\n        var modal = $(this),\n            dialog = modal.find('.modal-dialog');\n        modal.css('display', 'block');\n\n        // Dividing by two centers the modal exactly, but dividing by three\n        // or four works better for larger screens.\n        dialog.css(\"margin-top\", Math.max(0, ($(window).height() - dialog.height()) / 2));\n    }\n    // Reposition when a modal is shown\n    $('.modal').on('show.bs.modal', reposition);\n    // Reposition when the window is resized\n    $(window).on('resize', function() {\n        $('.modal:visible').each(reposition);\n    });\n});\n\n\n/**\n * 闪现消息自动关闭\n */\n$(\".alert\").fadeTo(2000, 500).slideUp(500, function(){\n    $(\".alert\").slideUp(500);\n});\n"
  },
  {
    "path": "app_backend/static/js/i18n/defaults-ar_AR.js",
    "content": "/*!\n * Bootstrap-select v1.12.2 (http://silviomoreto.github.io/bootstrap-select)\n *\n * Copyright 2013-2017 bootstrap-select\n * Licensed under MIT (https://github.com/silviomoreto/bootstrap-select/blob/master/LICENSE)\n */\n\n(function (root, factory) {\n  if (typeof define === 'function' && define.amd) {\n    // AMD. Register as an anonymous module unless amdModuleId is set\n    define([\"jquery\"], function (a0) {\n      return (factory(a0));\n    });\n  } else if (typeof module === 'object' && module.exports) {\n    // Node. Does not work with strict CommonJS, but\n    // only CommonJS-like environments that support module.exports,\n    // like Node.\n    module.exports = factory(require(\"jquery\"));\n  } else {\n    factory(root[\"jQuery\"]);\n  }\n}(this, function (jQuery) {\n\n/*!\n * Translated default messages for bootstrap-select.\n * Locale: AR (Arabic)\n * Author: Yasser Lotfy <y_l@alive.com>\n */\n(function ($) {\n  $.fn.selectpicker.defaults = {\n    noneSelectedText: 'لم يتم إختيار شئ',\n    noneResultsText: 'لا توجد نتائج مطابقة لـ {0}',\n    countSelectedText: function (numSelected, numTotal) {\n      return (numSelected == 1) ? \"{0} خيار تم إختياره\" : \"{0} خيارات تمت إختيارها\";\n    },\n    maxOptionsText: function (numAll, numGroup) {\n      return [\n        (numAll == 1) ? 'تخطى الحد المسموح ({n} خيار بحد أقصى)' : 'تخطى الحد المسموح ({n} خيارات بحد أقصى)',\n        (numGroup == 1) ? 'تخطى الحد المسموح للمجموعة ({n} خيار بحد أقصى)' : 'تخطى الحد المسموح للمجموعة ({n} خيارات بحد أقصى)'\n      ];\n    },\n    selectAllText: 'إختيار الجميع',\n    deselectAllText: 'إلغاء إختيار الجميع',\n    multipleSeparator: '، '\n  };\n})(jQuery);\n\n\n}));\n"
  },
  {
    "path": "app_backend/static/js/i18n/defaults-bg_BG.js",
    "content": "/*!\n * Bootstrap-select v1.12.2 (http://silviomoreto.github.io/bootstrap-select)\n *\n * Copyright 2013-2017 bootstrap-select\n * Licensed under MIT (https://github.com/silviomoreto/bootstrap-select/blob/master/LICENSE)\n */\n\n(function (root, factory) {\n  if (typeof define === 'function' && define.amd) {\n    // AMD. Register as an anonymous module unless amdModuleId is set\n    define([\"jquery\"], function (a0) {\n      return (factory(a0));\n    });\n  } else if (typeof module === 'object' && module.exports) {\n    // Node. Does not work with strict CommonJS, but\n    // only CommonJS-like environments that support module.exports,\n    // like Node.\n    module.exports = factory(require(\"jquery\"));\n  } else {\n    factory(root[\"jQuery\"]);\n  }\n}(this, function (jQuery) {\n\n(function ($) {\n  $.fn.selectpicker.defaults = {\n    noneSelectedText: 'Нищо избрано',\n    noneResultsText: 'Няма резултат за {0}',\n    countSelectedText: function (numSelected, numTotal) {\n      return (numSelected == 1) ? \"{0} избран елемент\" : \"{0} избрани елемента\";\n    },\n    maxOptionsText: function (numAll, numGroup) {\n      return [\n        (numAll == 1) ? 'Лимита е достигнат ({n} елемент максимум)' : 'Лимита е достигнат ({n} елемента максимум)',\n        (numGroup == 1) ? 'Груповия лимит е достигнат ({n} елемент максимум)' : 'Груповия лимит е достигнат ({n} елемента максимум)'\n      ];\n    },\n    selectAllText: 'Избери всички',\n    deselectAllText: 'Размаркирай всички',\n    multipleSeparator: ', '\n  };\n})(jQuery);\n\n\n}));\n"
  },
  {
    "path": "app_backend/static/js/i18n/defaults-cro_CRO.js",
    "content": "/*!\n * Bootstrap-select v1.12.2 (http://silviomoreto.github.io/bootstrap-select)\n *\n * Copyright 2013-2017 bootstrap-select\n * Licensed under MIT (https://github.com/silviomoreto/bootstrap-select/blob/master/LICENSE)\n */\n\n(function (root, factory) {\n  if (typeof define === 'function' && define.amd) {\n    // AMD. Register as an anonymous module unless amdModuleId is set\n    define([\"jquery\"], function (a0) {\n      return (factory(a0));\n    });\n  } else if (typeof module === 'object' && module.exports) {\n    // Node. Does not work with strict CommonJS, but\n    // only CommonJS-like environments that support module.exports,\n    // like Node.\n    module.exports = factory(require(\"jquery\"));\n  } else {\n    factory(root[\"jQuery\"]);\n  }\n}(this, function (jQuery) {\n\n(function ($) {\n  $.fn.selectpicker.defaults = {\n    noneSelectedText: 'Odaberite stavku',\n    noneResultsText: 'Nema rezultata pretrage {0}',\n    countSelectedText: function (numSelected, numTotal) {\n      return (numSelected == 1) ? \"{0} stavka selektirana\" : \"{0} stavke selektirane\";\n    },\n    maxOptionsText: function (numAll, numGroup) {\n      return [\n        (numAll == 1) ? 'Limit je postignut ({n} stvar maximalno)' : 'Limit je postignut ({n} stavke maksimalno)',\n        (numGroup == 1) ? 'Grupni limit je postignut ({n} stvar maksimalno)' : 'Grupni limit je postignut ({n} stavke maksimalno)'\n      ];\n    },\n    selectAllText: 'Selektiraj sve',\n    deselectAllText: 'Deselektiraj sve',\n    multipleSeparator: ', '\n  };\n})(jQuery);\n\n\n}));\n"
  },
  {
    "path": "app_backend/static/js/i18n/defaults-cs_CZ.js",
    "content": "/*!\n * Bootstrap-select v1.12.2 (http://silviomoreto.github.io/bootstrap-select)\n *\n * Copyright 2013-2017 bootstrap-select\n * Licensed under MIT (https://github.com/silviomoreto/bootstrap-select/blob/master/LICENSE)\n */\n\n(function (root, factory) {\n  if (typeof define === 'function' && define.amd) {\n    // AMD. Register as an anonymous module unless amdModuleId is set\n    define([\"jquery\"], function (a0) {\n      return (factory(a0));\n    });\n  } else if (typeof module === 'object' && module.exports) {\n    // Node. Does not work with strict CommonJS, but\n    // only CommonJS-like environments that support module.exports,\n    // like Node.\n    module.exports = factory(require(\"jquery\"));\n  } else {\n    factory(root[\"jQuery\"]);\n  }\n}(this, function (jQuery) {\n\n(function ($) {\n  $.fn.selectpicker.defaults = {\n    noneSelectedText: 'Nic není vybráno',\n    noneResultsText: 'Žádné výsledky {0}',\n    countSelectedText: 'Označeno {0} z {1}',\n    maxOptionsText: ['Limit překročen ({n} {var} max)', 'Limit skupiny překročen ({n} {var} max)', ['položek', 'položka']],\n    multipleSeparator: ', '\n  };\n})(jQuery);\n\n\n}));\n"
  },
  {
    "path": "app_backend/static/js/i18n/defaults-da_DK.js",
    "content": "/*!\n * Bootstrap-select v1.12.2 (http://silviomoreto.github.io/bootstrap-select)\n *\n * Copyright 2013-2017 bootstrap-select\n * Licensed under MIT (https://github.com/silviomoreto/bootstrap-select/blob/master/LICENSE)\n */\n\n(function (root, factory) {\n  if (typeof define === 'function' && define.amd) {\n    // AMD. Register as an anonymous module unless amdModuleId is set\n    define([\"jquery\"], function (a0) {\n      return (factory(a0));\n    });\n  } else if (typeof module === 'object' && module.exports) {\n    // Node. Does not work with strict CommonJS, but\n    // only CommonJS-like environments that support module.exports,\n    // like Node.\n    module.exports = factory(require(\"jquery\"));\n  } else {\n    factory(root[\"jQuery\"]);\n  }\n}(this, function (jQuery) {\n\n(function ($) {\n  $.fn.selectpicker.defaults = {\n    noneSelectedText: 'Intet valgt',\n    noneResultsText: 'Ingen resultater fundet {0}',\n    countSelectedText: function (numSelected, numTotal) {\n      return (numSelected == 1) ? \"{0} valgt\" : \"{0} valgt\";\n    },\n    maxOptionsText: function (numAll, numGroup) {\n      return [\n        (numAll == 1) ? 'Begrænsning nået (max {n} valgt)' : 'Begrænsning nået (max {n} valgte)',\n        (numGroup == 1) ? 'Gruppe-begrænsning nået (max {n} valgt)' : 'Gruppe-begrænsning nået (max {n} valgte)'\n      ];\n    },\n    selectAllText: 'Markér alle',\n    deselectAllText: 'Afmarkér alle',\n    multipleSeparator: ', '\n  };\n})(jQuery);\n\n\n}));\n"
  },
  {
    "path": "app_backend/static/js/i18n/defaults-de_DE.js",
    "content": "/*!\n * Bootstrap-select v1.12.2 (http://silviomoreto.github.io/bootstrap-select)\n *\n * Copyright 2013-2017 bootstrap-select\n * Licensed under MIT (https://github.com/silviomoreto/bootstrap-select/blob/master/LICENSE)\n */\n\n(function (root, factory) {\n  if (typeof define === 'function' && define.amd) {\n    // AMD. Register as an anonymous module unless amdModuleId is set\n    define([\"jquery\"], function (a0) {\n      return (factory(a0));\n    });\n  } else if (typeof module === 'object' && module.exports) {\n    // Node. Does not work with strict CommonJS, but\n    // only CommonJS-like environments that support module.exports,\n    // like Node.\n    module.exports = factory(require(\"jquery\"));\n  } else {\n    factory(root[\"jQuery\"]);\n  }\n}(this, function (jQuery) {\n\n(function ($) {\n  $.fn.selectpicker.defaults = {\n    noneSelectedText: 'Bitte wählen...',\n    noneResultsText: 'Keine Ergebnisse für {0}',\n    countSelectedText: function (numSelected, numTotal) {\n      return (numSelected == 1) ? \"{0} Element ausgewählt\" : \"{0} Elemente ausgewählt\";\n    },\n    maxOptionsText: function (numAll, numGroup) {\n      return [\n        (numAll == 1) ? 'Limit erreicht ({n} Element max.)' : 'Limit erreicht ({n} Elemente max.)',\n        (numGroup == 1) ? 'Gruppen-Limit erreicht ({n} Element max.)' : 'Gruppen-Limit erreicht ({n} Elemente max.)'\n      ];\n    },\n    selectAllText: 'Alles auswählen',\n    deselectAllText: 'Nichts auswählen',\n    multipleSeparator: ', '\n  };\n})(jQuery);\n\n\n}));\n"
  },
  {
    "path": "app_backend/static/js/i18n/defaults-en_US.js",
    "content": "/*!\n * Bootstrap-select v1.12.2 (http://silviomoreto.github.io/bootstrap-select)\n *\n * Copyright 2013-2017 bootstrap-select\n * Licensed under MIT (https://github.com/silviomoreto/bootstrap-select/blob/master/LICENSE)\n */\n\n(function (root, factory) {\n  if (typeof define === 'function' && define.amd) {\n    // AMD. Register as an anonymous module unless amdModuleId is set\n    define([\"jquery\"], function (a0) {\n      return (factory(a0));\n    });\n  } else if (typeof module === 'object' && module.exports) {\n    // Node. Does not work with strict CommonJS, but\n    // only CommonJS-like environments that support module.exports,\n    // like Node.\n    module.exports = factory(require(\"jquery\"));\n  } else {\n    factory(root[\"jQuery\"]);\n  }\n}(this, function (jQuery) {\n\n(function ($) {\n  $.fn.selectpicker.defaults = {\n    noneSelectedText: 'Nothing selected',\n    noneResultsText: 'No results match {0}',\n    countSelectedText: function (numSelected, numTotal) {\n      return (numSelected == 1) ? \"{0} item selected\" : \"{0} items selected\";\n    },\n    maxOptionsText: function (numAll, numGroup) {\n      return [\n        (numAll == 1) ? 'Limit reached ({n} item max)' : 'Limit reached ({n} items max)',\n        (numGroup == 1) ? 'Group limit reached ({n} item max)' : 'Group limit reached ({n} items max)'\n      ];\n    },\n    selectAllText: 'Select All',\n    deselectAllText: 'Deselect All',\n    multipleSeparator: ', '\n  };\n})(jQuery);\n\n\n}));\n"
  },
  {
    "path": "app_backend/static/js/i18n/defaults-es_CL.js",
    "content": "/*!\n * Bootstrap-select v1.12.2 (http://silviomoreto.github.io/bootstrap-select)\n *\n * Copyright 2013-2017 bootstrap-select\n * Licensed under MIT (https://github.com/silviomoreto/bootstrap-select/blob/master/LICENSE)\n */\n\n(function (root, factory) {\n  if (typeof define === 'function' && define.amd) {\n    // AMD. Register as an anonymous module unless amdModuleId is set\n    define([\"jquery\"], function (a0) {\n      return (factory(a0));\n    });\n  } else if (typeof module === 'object' && module.exports) {\n    // Node. Does not work with strict CommonJS, but\n    // only CommonJS-like environments that support module.exports,\n    // like Node.\n    module.exports = factory(require(\"jquery\"));\n  } else {\n    factory(root[\"jQuery\"]);\n  }\n}(this, function (jQuery) {\n\n(function ($) {\n  $.fn.selectpicker.defaults = {\n    noneSelectedText: 'No hay selección',\n    noneResultsText: 'No hay resultados {0}',\n    countSelectedText: 'Seleccionados {0} de {1}',\n    maxOptionsText: ['Límite alcanzado ({n} {var} max)', 'Límite del grupo alcanzado({n} {var} max)', ['elementos', 'element']],\n    multipleSeparator: ', ',\n    selectAllText: 'Seleccionar Todos',\n    deselectAllText: 'Desmarcar Todos'\n  };\n})(jQuery);\n\n\n}));\n"
  },
  {
    "path": "app_backend/static/js/i18n/defaults-es_ES.js",
    "content": "/*!\n * Bootstrap-select v1.12.2 (http://silviomoreto.github.io/bootstrap-select)\n *\n * Copyright 2013-2017 bootstrap-select\n * Licensed under MIT (https://github.com/silviomoreto/bootstrap-select/blob/master/LICENSE)\n */\n\n(function (root, factory) {\n  if (typeof define === 'function' && define.amd) {\n    // AMD. Register as an anonymous module unless amdModuleId is set\n    define([\"jquery\"], function (a0) {\n      return (factory(a0));\n    });\n  } else if (typeof module === 'object' && module.exports) {\n    // Node. Does not work with strict CommonJS, but\n    // only CommonJS-like environments that support module.exports,\n    // like Node.\n    module.exports = factory(require(\"jquery\"));\n  } else {\n    factory(root[\"jQuery\"]);\n  }\n}(this, function (jQuery) {\n\n(function ($) {\n  $.fn.selectpicker.defaults = {\n    noneSelectedText: 'No hay selección',\n    noneResultsText: 'No hay resultados {0}',\n    countSelectedText: 'Seleccionados {0} de {1}',\n    maxOptionsText: ['Límite alcanzado ({n} {var} max)', 'Límite del grupo alcanzado({n} {var} max)', ['elementos', 'element']],\n    multipleSeparator: ', ',\n    selectAllText: 'Seleccionar Todos',\n    deselectAllText: 'Desmarcar Todos'\n  };\n})(jQuery);\n\n\n}));\n"
  },
  {
    "path": "app_backend/static/js/i18n/defaults-eu.js",
    "content": "/*!\n * Bootstrap-select v1.12.2 (http://silviomoreto.github.io/bootstrap-select)\n *\n * Copyright 2013-2017 bootstrap-select\n * Licensed under MIT (https://github.com/silviomoreto/bootstrap-select/blob/master/LICENSE)\n */\n\n(function (root, factory) {\n  if (typeof define === 'function' && define.amd) {\n    // AMD. Register as an anonymous module unless amdModuleId is set\n    define([\"jquery\"], function (a0) {\n      return (factory(a0));\n    });\n  } else if (typeof module === 'object' && module.exports) {\n    // Node. Does not work with strict CommonJS, but\n    // only CommonJS-like environments that support module.exports,\n    // like Node.\n    module.exports = factory(require(\"jquery\"));\n  } else {\n    factory(root[\"jQuery\"]);\n  }\n}(this, function (jQuery) {\n\n(function ($) {\n  $.fn.selectpicker.defaults = {\n    noneSelectedText: 'Hautapenik ez',\n    noneResultsText: 'Emaitzarik ez {0}',\n    countSelectedText: '{1}(e)tik {0} hautatuta',\n    maxOptionsText: ['Mugara iritsita ({n} {var} gehienez)', 'Taldearen mugara iritsita ({n} {var} gehienez)', ['elementu', 'elementu']],\n    multipleSeparator: ', '\n  };\n})(jQuery);\n\n\n}));\n"
  },
  {
    "path": "app_backend/static/js/i18n/defaults-fa_IR.js",
    "content": "/*!\n * Bootstrap-select v1.12.2 (http://silviomoreto.github.io/bootstrap-select)\n *\n * Copyright 2013-2017 bootstrap-select\n * Licensed under MIT (https://github.com/silviomoreto/bootstrap-select/blob/master/LICENSE)\n */\n\n(function (root, factory) {\n  if (typeof define === 'function' && define.amd) {\n    // AMD. Register as an anonymous module unless amdModuleId is set\n    define([\"jquery\"], function (a0) {\n      return (factory(a0));\n    });\n  } else if (typeof module === 'object' && module.exports) {\n    // Node. Does not work with strict CommonJS, but\n    // only CommonJS-like environments that support module.exports,\n    // like Node.\n    module.exports = factory(require(\"jquery\"));\n  } else {\n    factory(root[\"jQuery\"]);\n  }\n}(this, function (jQuery) {\n\n(function ($) {\n    $.fn.selectpicker.defaults = {\n        noneSelectedText: 'چیزی انتخاب نشده است',\n        noneResultsText: 'هیج مشابهی برای {0} پیدا نشد',\n        countSelectedText: \"{0} از {1} مورد انتخاب شده\",\n        maxOptionsText: ['بیشتر ممکن نیست {حداکثر {n} عدد}', 'بیشتر ممکن نیست {حداکثر {n} عدد}'],\n        selectAllText: 'انتخاب همه',\n        deselectAllText: 'انتخاب هیچ کدام',\n        multipleSeparator: ', '\n    };\n})(jQuery);\n\n\n}));\n"
  },
  {
    "path": "app_backend/static/js/i18n/defaults-fi_FI.js",
    "content": "/*!\n * Bootstrap-select v1.12.2 (http://silviomoreto.github.io/bootstrap-select)\n *\n * Copyright 2013-2017 bootstrap-select\n * Licensed under MIT (https://github.com/silviomoreto/bootstrap-select/blob/master/LICENSE)\n */\n\n(function (root, factory) {\n  if (typeof define === 'function' && define.amd) {\n    // AMD. Register as an anonymous module unless amdModuleId is set\n    define([\"jquery\"], function (a0) {\n      return (factory(a0));\n    });\n  } else if (typeof module === 'object' && module.exports) {\n    // Node. Does not work with strict CommonJS, but\n    // only CommonJS-like environments that support module.exports,\n    // like Node.\n    module.exports = factory(require(\"jquery\"));\n  } else {\n    factory(root[\"jQuery\"]);\n  }\n}(this, function (jQuery) {\n\n(function ($) {\n  $.fn.selectpicker.defaults = {\n    noneSelectedText: 'Ei valintoja',\n    noneResultsText: 'Ei hakutuloksia {0}',\n    countSelectedText: function (numSelected, numTotal) {\n      return (numSelected == 1) ? \"{0} valittu\" : \"{0} valitut\";\n    },\n    maxOptionsText: function (numAll, numGroup) {\n      return [\n        (numAll == 1) ? 'Valintojen maksimimäärä ({n} saavutettu)' : 'Valintojen maksimimäärä ({n} saavutettu)',\n        (numGroup == 1) ? 'Ryhmän maksimimäärä ({n} saavutettu)' : 'Ryhmän maksimimäärä ({n} saavutettu)'\n      ];\n    },\n    selectAllText: 'Valitse kaikki',\n    deselectAllText: 'Poista kaikki',\n    multipleSeparator: ', '\n  };\n})(jQuery);\n\n\n}));\n"
  },
  {
    "path": "app_backend/static/js/i18n/defaults-fr_FR.js",
    "content": "/*!\n * Bootstrap-select v1.12.2 (http://silviomoreto.github.io/bootstrap-select)\n *\n * Copyright 2013-2017 bootstrap-select\n * Licensed under MIT (https://github.com/silviomoreto/bootstrap-select/blob/master/LICENSE)\n */\n\n(function (root, factory) {\n  if (typeof define === 'function' && define.amd) {\n    // AMD. Register as an anonymous module unless amdModuleId is set\n    define([\"jquery\"], function (a0) {\n      return (factory(a0));\n    });\n  } else if (typeof module === 'object' && module.exports) {\n    // Node. Does not work with strict CommonJS, but\n    // only CommonJS-like environments that support module.exports,\n    // like Node.\n    module.exports = factory(require(\"jquery\"));\n  } else {\n    factory(root[\"jQuery\"]);\n  }\n}(this, function (jQuery) {\n\n(function ($) {\n  $.fn.selectpicker.defaults = {\n    noneSelectedText: 'Aucune sélection',\n    noneResultsText: 'Aucun résultat pour {0}',\n    countSelectedText: function (numSelected, numTotal) {\n      return (numSelected > 1) ? \"{0} éléments sélectionnés\" : \"{0} élément sélectionné\";\n    },\n    maxOptionsText: function (numAll, numGroup) {\n      return [\n        (numAll > 1) ? 'Limite atteinte ({n} éléments max)' : 'Limite atteinte ({n} élément max)',\n        (numGroup > 1) ? 'Limite du groupe atteinte ({n} éléments max)' : 'Limite du groupe atteinte ({n} élément max)'\n      ];\n    },\n    multipleSeparator: ', ',\n    selectAllText: 'Tout Sélectionner',\n    deselectAllText: 'Tout Dé-selectionner',\n  };\n})(jQuery);\n\n\n}));\n"
  },
  {
    "path": "app_backend/static/js/i18n/defaults-hu_HU.js",
    "content": "/*!\n * Bootstrap-select v1.12.2 (http://silviomoreto.github.io/bootstrap-select)\n *\n * Copyright 2013-2017 bootstrap-select\n * Licensed under MIT (https://github.com/silviomoreto/bootstrap-select/blob/master/LICENSE)\n */\n\n(function (root, factory) {\n  if (typeof define === 'function' && define.amd) {\n    // AMD. Register as an anonymous module unless amdModuleId is set\n    define([\"jquery\"], function (a0) {\n      return (factory(a0));\n    });\n  } else if (typeof module === 'object' && module.exports) {\n    // Node. Does not work with strict CommonJS, but\n    // only CommonJS-like environments that support module.exports,\n    // like Node.\n    module.exports = factory(require(\"jquery\"));\n  } else {\n    factory(root[\"jQuery\"]);\n  }\n}(this, function (jQuery) {\n\n(function ($) {\n  $.fn.selectpicker.defaults = {\n    noneSelectedText: 'Válasszon!',\n    noneResultsText: 'Nincs találat {0}',\n    countSelectedText: function (numSelected, numTotal) {\n      return '{0} elem kiválasztva';\n    },\n    maxOptionsText: function (numAll, numGroup) {\n      return [\n        'Legfeljebb {n} elem választható',\n        'A csoportban legfeljebb {n} elem választható'\n      ];\n    },\n    selectAllText: 'Mind',\n    deselectAllText: 'Egyik sem',\n    multipleSeparator: ', '\n  };\n})(jQuery);\n\n\n}));\n"
  },
  {
    "path": "app_backend/static/js/i18n/defaults-id_ID.js",
    "content": "/*!\n * Bootstrap-select v1.12.2 (http://silviomoreto.github.io/bootstrap-select)\n *\n * Copyright 2013-2017 bootstrap-select\n * Licensed under MIT (https://github.com/silviomoreto/bootstrap-select/blob/master/LICENSE)\n */\n\n(function (root, factory) {\n  if (typeof define === 'function' && define.amd) {\n    // AMD. Register as an anonymous module unless amdModuleId is set\n    define([\"jquery\"], function (a0) {\n      return (factory(a0));\n    });\n  } else if (typeof module === 'object' && module.exports) {\n    // Node. Does not work with strict CommonJS, but\n    // only CommonJS-like environments that support module.exports,\n    // like Node.\n    module.exports = factory(require(\"jquery\"));\n  } else {\n    factory(root[\"jQuery\"]);\n  }\n}(this, function (jQuery) {\n\n(function ($) {\n  $.fn.selectpicker.defaults = {\n    noneSelectedText: 'Tidak ada yang dipilih',\n    noneResultsText: 'Tidak ada yang cocok {0}',\n    countSelectedText: '{0} terpilih',\n    maxOptionsText: ['Mencapai batas (maksimum {n})', 'Mencapai batas grup (maksimum {n})'],\n    selectAllText: 'Pilih Semua',\n    deselectAllText: 'Hapus Semua',\n    multipleSeparator: ', '\n  };\n})(jQuery);\n\n\n}));\n"
  },
  {
    "path": "app_backend/static/js/i18n/defaults-it_IT.js",
    "content": "/*!\n * Bootstrap-select v1.12.2 (http://silviomoreto.github.io/bootstrap-select)\n *\n * Copyright 2013-2017 bootstrap-select\n * Licensed under MIT (https://github.com/silviomoreto/bootstrap-select/blob/master/LICENSE)\n */\n\n(function (root, factory) {\n  if (typeof define === 'function' && define.amd) {\n    // AMD. Register as an anonymous module unless amdModuleId is set\n    define([\"jquery\"], function (a0) {\n      return (factory(a0));\n    });\n  } else if (typeof module === 'object' && module.exports) {\n    // Node. Does not work with strict CommonJS, but\n    // only CommonJS-like environments that support module.exports,\n    // like Node.\n    module.exports = factory(require(\"jquery\"));\n  } else {\n    factory(root[\"jQuery\"]);\n  }\n}(this, function (jQuery) {\n\n(function ($) {\n  $.fn.selectpicker.defaults = {\n    noneSelectedText: 'Nessuna selezione',\n    noneResultsText: 'Nessun risultato per {0}',\n    countSelectedText: function (numSelected, numTotal){\n      return (numSelected == 1) ? 'Selezionato {0} di {1}' : 'Selezionati {0} di {1}';\n    },\n    maxOptionsText: ['Limite raggiunto ({n} {var} max)', 'Limite del gruppo raggiunto ({n} {var} max)', ['elementi', 'elemento']],\n    multipleSeparator: ', ',\n    selectAllText: 'Seleziona Tutto',\n    deselectAllText: 'Deseleziona Tutto'\n  };\n})(jQuery);\n\n\n}));\n"
  },
  {
    "path": "app_backend/static/js/i18n/defaults-ko_KR.js",
    "content": "/*!\n * Bootstrap-select v1.12.2 (http://silviomoreto.github.io/bootstrap-select)\n *\n * Copyright 2013-2017 bootstrap-select\n * Licensed under MIT (https://github.com/silviomoreto/bootstrap-select/blob/master/LICENSE)\n */\n\n(function (root, factory) {\n  if (typeof define === 'function' && define.amd) {\n    // AMD. Register as an anonymous module unless amdModuleId is set\n    define([\"jquery\"], function (a0) {\n      return (factory(a0));\n    });\n  } else if (typeof module === 'object' && module.exports) {\n    // Node. Does not work with strict CommonJS, but\n    // only CommonJS-like environments that support module.exports,\n    // like Node.\n    module.exports = factory(require(\"jquery\"));\n  } else {\n    factory(root[\"jQuery\"]);\n  }\n}(this, function (jQuery) {\n\n(function ($) {\n  $.fn.selectpicker.defaults = {\n    noneSelectedText: '항목을 선택해주세요',\n    noneResultsText: '{0} 검색 결과가 없습니다',\n    countSelectedText: function (numSelected, numTotal) {\n      return \"{0}개를 선택하였습니다\";\n    },\n    maxOptionsText: function (numAll, numGroup) {\n      return [\n        '{n}개까지 선택 가능합니다',\n        '해당 그룹은 {n}개까지 선택 가능합니다'\n      ];\n    },\n    selectAllText: '전체선택',\n    deselectAllText: '전체해제',\n    multipleSeparator: ', '\n  };\n})(jQuery);\n\n\n}));\n"
  },
  {
    "path": "app_backend/static/js/i18n/defaults-lt_LT.js",
    "content": "/*!\n * Bootstrap-select v1.12.2 (http://silviomoreto.github.io/bootstrap-select)\n *\n * Copyright 2013-2017 bootstrap-select\n * Licensed under MIT (https://github.com/silviomoreto/bootstrap-select/blob/master/LICENSE)\n */\n\n(function (root, factory) {\n  if (typeof define === 'function' && define.amd) {\n    // AMD. Register as an anonymous module unless amdModuleId is set\n    define([\"jquery\"], function (a0) {\n      return (factory(a0));\n    });\n  } else if (typeof module === 'object' && module.exports) {\n    // Node. Does not work with strict CommonJS, but\n    // only CommonJS-like environments that support module.exports,\n    // like Node.\n    module.exports = factory(require(\"jquery\"));\n  } else {\n    factory(root[\"jQuery\"]);\n  }\n}(this, function (jQuery) {\n\n(function ($) {\n  $.fn.selectpicker.defaults = {\n    noneSelectedText: 'Niekas nepasirinkta',\n    noneResultsText: 'Niekas nesutapo su {0}',\n    countSelectedText: function (numSelected, numTotal) {\n      return (numSelected == 1) ? \"{0} elementas pasirinktas\" : \"{0} elementai(-ų) pasirinkta\";\n    },\n    maxOptionsText: function (numAll, numGroup) {\n      return [\n        (numAll == 1) ? 'Pasiekta riba ({n} elementas daugiausiai)' : 'Riba pasiekta ({n} elementai(-ų) daugiausiai)',\n        (numGroup == 1) ? 'Grupės riba pasiekta ({n} elementas daugiausiai)' : 'Grupės riba pasiekta ({n} elementai(-ų) daugiausiai)'\n      ];\n    },\n    selectAllText: 'Pasirinkti visus',\n    deselectAllText: 'Atmesti visus',\n    multipleSeparator: ', '\n  };\n})(jQuery);\n\n\n}));\n"
  },
  {
    "path": "app_backend/static/js/i18n/defaults-nb_NO.js",
    "content": "/*!\n * Bootstrap-select v1.12.2 (http://silviomoreto.github.io/bootstrap-select)\n *\n * Copyright 2013-2017 bootstrap-select\n * Licensed under MIT (https://github.com/silviomoreto/bootstrap-select/blob/master/LICENSE)\n */\n\n(function (root, factory) {\n  if (typeof define === 'function' && define.amd) {\n    // AMD. Register as an anonymous module unless amdModuleId is set\n    define([\"jquery\"], function (a0) {\n      return (factory(a0));\n    });\n  } else if (typeof module === 'object' && module.exports) {\n    // Node. Does not work with strict CommonJS, but\n    // only CommonJS-like environments that support module.exports,\n    // like Node.\n    module.exports = factory(require(\"jquery\"));\n  } else {\n    factory(root[\"jQuery\"]);\n  }\n}(this, function (jQuery) {\n\n(function ($) {\n  $.fn.selectpicker.defaults = {\n    noneSelectedText: 'Ingen valgt',\n    noneResultsText: 'Søket gir ingen treff {0}',\n    countSelectedText: function (numSelected, numTotal) {\n      return (numSelected == 1) ? \"{0} alternativ valgt\" : \"{0} alternativer valgt\";\n    },\n    maxOptionsText: function (numAll, numGroup) {\n      return [\n        (numAll == 1) ? 'Grense nådd (maks {n} valg)' : 'Grense nådd (maks {n} valg)',\n        (numGroup == 1) ? 'Grense for grupper nådd (maks {n} grupper)' : 'Grense for grupper nådd (maks {n} grupper)'\n      ];\n    },\n    selectAllText: 'Merk alle',\n    deselectAllText: 'Fjern alle',\n    multipleSeparator: ', '\n  };\n})(jQuery);\n\n\n}));\n"
  },
  {
    "path": "app_backend/static/js/i18n/defaults-nl_NL.js",
    "content": "/*!\n * Bootstrap-select v1.12.2 (http://silviomoreto.github.io/bootstrap-select)\n *\n * Copyright 2013-2017 bootstrap-select\n * Licensed under MIT (https://github.com/silviomoreto/bootstrap-select/blob/master/LICENSE)\n */\n\n(function (root, factory) {\n  if (typeof define === 'function' && define.amd) {\n    // AMD. Register as an anonymous module unless amdModuleId is set\n    define([\"jquery\"], function (a0) {\n      return (factory(a0));\n    });\n  } else if (typeof module === 'object' && module.exports) {\n    // Node. Does not work with strict CommonJS, but\n    // only CommonJS-like environments that support module.exports,\n    // like Node.\n    module.exports = factory(require(\"jquery\"));\n  } else {\n    factory(root[\"jQuery\"]);\n  }\n}(this, function (jQuery) {\n\n(function ($) {\n  $.fn.selectpicker.defaults = {\n    noneSelectedText: 'Niets geselecteerd',\n    noneResultsText: 'Geen resultaten gevonden voor {0}',\n    countSelectedText: '{0} van {1} geselecteerd',\n    maxOptionsText: ['Limiet bereikt ({n} {var} max)', 'Groep limiet bereikt ({n} {var} max)', ['items', 'item']],\n    multipleSeparator: ', '\n  };\n})(jQuery);\n\n\n}));\n"
  },
  {
    "path": "app_backend/static/js/i18n/defaults-pl_PL.js",
    "content": "/*!\n * Bootstrap-select v1.12.2 (http://silviomoreto.github.io/bootstrap-select)\n *\n * Copyright 2013-2017 bootstrap-select\n * Licensed under MIT (https://github.com/silviomoreto/bootstrap-select/blob/master/LICENSE)\n */\n\n(function (root, factory) {\n  if (typeof define === 'function' && define.amd) {\n    // AMD. Register as an anonymous module unless amdModuleId is set\n    define([\"jquery\"], function (a0) {\n      return (factory(a0));\n    });\n  } else if (typeof module === 'object' && module.exports) {\n    // Node. Does not work with strict CommonJS, but\n    // only CommonJS-like environments that support module.exports,\n    // like Node.\n    module.exports = factory(require(\"jquery\"));\n  } else {\n    factory(root[\"jQuery\"]);\n  }\n}(this, function (jQuery) {\n\n(function ($) {\n  $.fn.selectpicker.defaults = {\n    noneSelectedText: 'Nic nie zaznaczono',\n    noneResultsText: 'Brak wyników wyszukiwania {0}',\n    countSelectedText: 'Zaznaczono {0} z {1}',\n    maxOptionsText: ['Osiągnięto limit ({n} {var} max)', 'Limit grupy osiągnięty ({n} {var} max)', ['elementy', 'element']],\n    selectAll: 'Zaznacz wszystkie',\n    deselectAll: 'Odznacz wszystkie',\n    multipleSeparator: ', '\n  };\n})(jQuery);\n\n\n}));\n"
  },
  {
    "path": "app_backend/static/js/i18n/defaults-pt_BR.js",
    "content": "/*!\n * Bootstrap-select v1.12.2 (http://silviomoreto.github.io/bootstrap-select)\n *\n * Copyright 2013-2017 bootstrap-select\n * Licensed under MIT (https://github.com/silviomoreto/bootstrap-select/blob/master/LICENSE)\n */\n\n(function (root, factory) {\n  if (typeof define === 'function' && define.amd) {\n    // AMD. Register as an anonymous module unless amdModuleId is set\n    define([\"jquery\"], function (a0) {\n      return (factory(a0));\n    });\n  } else if (typeof module === 'object' && module.exports) {\n    // Node. Does not work with strict CommonJS, but\n    // only CommonJS-like environments that support module.exports,\n    // like Node.\n    module.exports = factory(require(\"jquery\"));\n  } else {\n    factory(root[\"jQuery\"]);\n  }\n}(this, function (jQuery) {\n\n(function ($) {\n  $.fn.selectpicker.defaults = {\n    noneSelectedText: 'Nada selecionado',\n    noneResultsText: 'Nada encontrado contendo {0}',\n    countSelectedText: 'Selecionado {0} de {1}',\n    maxOptionsText: ['Limite excedido (máx. {n} {var})', 'Limite do grupo excedido (máx. {n} {var})', ['itens', 'item']],\n    multipleSeparator: ', '\n  };\n})(jQuery);\n\n\n}));\n"
  },
  {
    "path": "app_backend/static/js/i18n/defaults-pt_PT.js",
    "content": "/*!\n * Bootstrap-select v1.12.2 (http://silviomoreto.github.io/bootstrap-select)\n *\n * Copyright 2013-2017 bootstrap-select\n * Licensed under MIT (https://github.com/silviomoreto/bootstrap-select/blob/master/LICENSE)\n */\n\n(function (root, factory) {\n  if (typeof define === 'function' && define.amd) {\n    // AMD. Register as an anonymous module unless amdModuleId is set\n    define([\"jquery\"], function (a0) {\n      return (factory(a0));\n    });\n  } else if (typeof module === 'object' && module.exports) {\n    // Node. Does not work with strict CommonJS, but\n    // only CommonJS-like environments that support module.exports,\n    // like Node.\n    module.exports = factory(require(\"jquery\"));\n  } else {\n    factory(root[\"jQuery\"]);\n  }\n}(this, function (jQuery) {\n\n(function ($) {\n$.fn.selectpicker.defaults = {\nnoneSelectedText: 'Nenhum seleccionado',\nnoneResultsText: 'Sem resultados contendo {0}',\ncountSelectedText: 'Selecionado {0} de {1}',\nmaxOptionsText: ['Limite ultrapassado (máx. {n} {var})', 'Limite de seleções ultrapassado (máx. {n} {var})', ['itens', 'item']],\nmultipleSeparator: ', '\n};\n})(jQuery);\n\n\n}));\n"
  },
  {
    "path": "app_backend/static/js/i18n/defaults-ro_RO.js",
    "content": "/*!\n * Bootstrap-select v1.12.2 (http://silviomoreto.github.io/bootstrap-select)\n *\n * Copyright 2013-2017 bootstrap-select\n * Licensed under MIT (https://github.com/silviomoreto/bootstrap-select/blob/master/LICENSE)\n */\n\n(function (root, factory) {\n  if (typeof define === 'function' && define.amd) {\n    // AMD. Register as an anonymous module unless amdModuleId is set\n    define([\"jquery\"], function (a0) {\n      return (factory(a0));\n    });\n  } else if (typeof module === 'object' && module.exports) {\n    // Node. Does not work with strict CommonJS, but\n    // only CommonJS-like environments that support module.exports,\n    // like Node.\n    module.exports = factory(require(\"jquery\"));\n  } else {\n    factory(root[\"jQuery\"]);\n  }\n}(this, function (jQuery) {\n\n(function ($) {\n  $.fn.selectpicker.defaults = {\n    noneSelectedText: 'Nu a fost selectat nimic',\n    noneResultsText: 'Nu exista niciun rezultat {0}',\n    countSelectedText: '{0} din {1} selectat(e)',\n    maxOptionsText: ['Limita a fost atinsa ({n} {var} max)', 'Limita de grup a fost atinsa ({n} {var} max)', ['iteme', 'item']],\n    multipleSeparator: ', '\n  };\n})(jQuery);\n\n\n}));\n"
  },
  {
    "path": "app_backend/static/js/i18n/defaults-ru_RU.js",
    "content": "/*!\n * Bootstrap-select v1.12.2 (http://silviomoreto.github.io/bootstrap-select)\n *\n * Copyright 2013-2017 bootstrap-select\n * Licensed under MIT (https://github.com/silviomoreto/bootstrap-select/blob/master/LICENSE)\n */\n\n(function (root, factory) {\n  if (typeof define === 'function' && define.amd) {\n    // AMD. Register as an anonymous module unless amdModuleId is set\n    define([\"jquery\"], function (a0) {\n      return (factory(a0));\n    });\n  } else if (typeof module === 'object' && module.exports) {\n    // Node. Does not work with strict CommonJS, but\n    // only CommonJS-like environments that support module.exports,\n    // like Node.\n    module.exports = factory(require(\"jquery\"));\n  } else {\n    factory(root[\"jQuery\"]);\n  }\n}(this, function (jQuery) {\n\n(function ($) {\n  $.fn.selectpicker.defaults = {\n    noneSelectedText: 'Ничего не выбрано',\n    noneResultsText: 'Совпадений не найдено {0}',\n    countSelectedText: 'Выбрано {0} из {1}',\n    maxOptionsText: ['Достигнут предел ({n} {var} максимум)', 'Достигнут предел в группе ({n} {var} максимум)', ['шт.', 'шт.']],\n    doneButtonText: 'Закрыть',\n    selectAllText: 'Выбрать все',\n    deselectAllText: 'Отменить все',    \n    multipleSeparator: ', '\n  };\n})(jQuery);\n\n\n}));\n"
  },
  {
    "path": "app_backend/static/js/i18n/defaults-sk_SK.js",
    "content": "/*!\n * Bootstrap-select v1.12.2 (http://silviomoreto.github.io/bootstrap-select)\n *\n * Copyright 2013-2017 bootstrap-select\n * Licensed under MIT (https://github.com/silviomoreto/bootstrap-select/blob/master/LICENSE)\n */\n\n(function (root, factory) {\n  if (typeof define === 'function' && define.amd) {\n    // AMD. Register as an anonymous module unless amdModuleId is set\n    define([\"jquery\"], function (a0) {\n      return (factory(a0));\n    });\n  } else if (typeof module === 'object' && module.exports) {\n    // Node. Does not work with strict CommonJS, but\n    // only CommonJS-like environments that support module.exports,\n    // like Node.\n    module.exports = factory(require(\"jquery\"));\n  } else {\n    factory(root[\"jQuery\"]);\n  }\n}(this, function (jQuery) {\n\n(function ($) {\n  $.fn.selectpicker.defaults = {\n    noneSelectedText: 'Vyberte zo zoznamu',\n    noneResultsText: 'Pre výraz {0} neboli nájdené žiadne výsledky',\n    countSelectedText: 'Vybrané {0} z {1}',\n    maxOptionsText: ['Limit prekročený ({n} {var} max)', 'Limit skupiny prekročený ({n} {var} max)', ['položiek', 'položka']],\n    selectAllText: 'Vybrať všetky',\n    deselectAllText: 'Zrušiť výber',\n    multipleSeparator: ', '\n  };\n})(jQuery);\n\n\n}));\n"
  },
  {
    "path": "app_backend/static/js/i18n/defaults-sl_SI.js",
    "content": "/*!\n * Bootstrap-select v1.12.2 (http://silviomoreto.github.io/bootstrap-select)\n *\n * Copyright 2013-2017 bootstrap-select\n * Licensed under MIT (https://github.com/silviomoreto/bootstrap-select/blob/master/LICENSE)\n */\n\n(function (root, factory) {\n  if (typeof define === 'function' && define.amd) {\n    // AMD. Register as an anonymous module unless amdModuleId is set\n    define([\"jquery\"], function (a0) {\n      return (factory(a0));\n    });\n  } else if (typeof module === 'object' && module.exports) {\n    // Node. Does not work with strict CommonJS, but\n    // only CommonJS-like environments that support module.exports,\n    // like Node.\n    module.exports = factory(require(\"jquery\"));\n  } else {\n    factory(root[\"jQuery\"]);\n  }\n}(this, function (jQuery) {\n\n(function ($) {\n  $.fn.selectpicker.defaults = {\n    noneSelectedText: 'Nič izbranega',\n    noneResultsText: 'Ni zadetkov za {0}',\n    countSelectedText: function (numSelected, numTotal) {\n      \"Število izbranih: {0}\";\n    },\n    maxOptionsText: function (numAll, numGroup) {\n      return [\n        'Omejitev dosežena (max. izbranih: {n})',\n        'Omejitev skupine dosežena (max. izbranih: {n})'\n      ];\n    },\n    selectAllText: 'Izberi vse',\n    deselectAllText: 'Počisti izbor',\n    multipleSeparator: ', '\n  };\n})(jQuery);\n\n\n}));\n"
  },
  {
    "path": "app_backend/static/js/i18n/defaults-sv_SE.js",
    "content": "/*!\n * Bootstrap-select v1.12.2 (http://silviomoreto.github.io/bootstrap-select)\n *\n * Copyright 2013-2017 bootstrap-select\n * Licensed under MIT (https://github.com/silviomoreto/bootstrap-select/blob/master/LICENSE)\n */\n\n(function (root, factory) {\n  if (typeof define === 'function' && define.amd) {\n    // AMD. Register as an anonymous module unless amdModuleId is set\n    define([\"jquery\"], function (a0) {\n      return (factory(a0));\n    });\n  } else if (typeof module === 'object' && module.exports) {\n    // Node. Does not work with strict CommonJS, but\n    // only CommonJS-like environments that support module.exports,\n    // like Node.\n    module.exports = factory(require(\"jquery\"));\n  } else {\n    factory(root[\"jQuery\"]);\n  }\n}(this, function (jQuery) {\n\n(function ($) {\n  $.fn.selectpicker.defaults = {\n    noneSelectedText: 'Inget valt',\n    noneResultsText: 'Inget sökresultat matchar {0}',\n    countSelectedText: function (numSelected, numTotal) {\n      return (numSelected === 1) ? \"{0} alternativ valt\" : \"{0} alternativ valda\";\n    },\n    maxOptionsText: function (numAll, numGroup) {\n      return [\n        'Gräns uppnåd (max {n} alternativ)',\n        'Gräns uppnåd (max {n} gruppalternativ)'\n      ];\n    },\n    selectAllText: 'Markera alla',\n    deselectAllText: 'Avmarkera alla',\n    multipleSeparator: ', '\n  };\n})(jQuery);\n\n\n}));\n"
  },
  {
    "path": "app_backend/static/js/i18n/defaults-tr_TR.js",
    "content": "/*!\n * Bootstrap-select v1.12.2 (http://silviomoreto.github.io/bootstrap-select)\n *\n * Copyright 2013-2017 bootstrap-select\n * Licensed under MIT (https://github.com/silviomoreto/bootstrap-select/blob/master/LICENSE)\n */\n\n(function (root, factory) {\n  if (typeof define === 'function' && define.amd) {\n    // AMD. Register as an anonymous module unless amdModuleId is set\n    define([\"jquery\"], function (a0) {\n      return (factory(a0));\n    });\n  } else if (typeof module === 'object' && module.exports) {\n    // Node. Does not work with strict CommonJS, but\n    // only CommonJS-like environments that support module.exports,\n    // like Node.\n    module.exports = factory(require(\"jquery\"));\n  } else {\n    factory(root[\"jQuery\"]);\n  }\n}(this, function (jQuery) {\n\n(function ($) {\n  $.fn.selectpicker.defaults = {\n    noneSelectedText: 'Hiçbiri seçilmedi',\n    noneResultsText: 'Hiçbir sonuç bulunamadı {0}',\n    countSelectedText: function (numSelected, numTotal) {\n      return (numSelected == 1) ? \"{0} öğe seçildi\" : \"{0} öğe seçildi\";\n    },\n    maxOptionsText: function (numAll, numGroup) {\n      return [\n        (numAll == 1) ? 'Limit aşıldı (maksimum {n} sayıda öğe )' : 'Limit aşıldı (maksimum {n} sayıda öğe)',\n        (numGroup == 1) ? 'Grup limiti aşıldı (maksimum {n} sayıda öğe)' : 'Grup limiti aşıldı (maksimum {n} sayıda öğe)'\n      ];\n    },\n    selectAllText: 'Tümünü Seç',\n    deselectAllText: 'Seçiniz',\n    multipleSeparator: ', '\n  };\n})(jQuery);\n\n\n}));\n"
  },
  {
    "path": "app_backend/static/js/i18n/defaults-ua_UA.js",
    "content": "/*!\n * Bootstrap-select v1.12.2 (http://silviomoreto.github.io/bootstrap-select)\n *\n * Copyright 2013-2017 bootstrap-select\n * Licensed under MIT (https://github.com/silviomoreto/bootstrap-select/blob/master/LICENSE)\n */\n\n(function (root, factory) {\n  if (typeof define === 'function' && define.amd) {\n    // AMD. Register as an anonymous module unless amdModuleId is set\n    define([\"jquery\"], function (a0) {\n      return (factory(a0));\n    });\n  } else if (typeof module === 'object' && module.exports) {\n    // Node. Does not work with strict CommonJS, but\n    // only CommonJS-like environments that support module.exports,\n    // like Node.\n    module.exports = factory(require(\"jquery\"));\n  } else {\n    factory(root[\"jQuery\"]);\n  }\n}(this, function (jQuery) {\n\n(function ($) {\n  $.fn.selectpicker.defaults = {\n    noneSelectedText: 'Нічого не вибрано',\n    noneResultsText: 'Збігів не знайдено {0}',\n    countSelectedText: 'Вибрано {0} із {1}',\n    maxOptionsText: ['Досягнута межа ({n} {var} максимум)', 'Досягнута межа в групі ({n} {var} максимум)', ['items', 'item']],\n    multipleSeparator: ', '\n  };\n})(jQuery);\n\n\n}));\n"
  },
  {
    "path": "app_backend/static/js/i18n/defaults-zh_CN.js",
    "content": "/*!\n * Bootstrap-select v1.12.2 (http://silviomoreto.github.io/bootstrap-select)\n *\n * Copyright 2013-2017 bootstrap-select\n * Licensed under MIT (https://github.com/silviomoreto/bootstrap-select/blob/master/LICENSE)\n */\n\n(function (root, factory) {\n  if (typeof define === 'function' && define.amd) {\n    // AMD. Register as an anonymous module unless amdModuleId is set\n    define([\"jquery\"], function (a0) {\n      return (factory(a0));\n    });\n  } else if (typeof module === 'object' && module.exports) {\n    // Node. Does not work with strict CommonJS, but\n    // only CommonJS-like environments that support module.exports,\n    // like Node.\n    module.exports = factory(require(\"jquery\"));\n  } else {\n    factory(root[\"jQuery\"]);\n  }\n}(this, function (jQuery) {\n\n(function ($) {\n  $.fn.selectpicker.defaults = {\n    noneSelectedText: '没有选中任何项',\n    noneResultsText: '没有找到匹配项',\n    countSelectedText: '选中{1}中的{0}项',\n    maxOptionsText: ['超出限制 (最多选择{n}项)', '组选择超出限制(最多选择{n}组)'],\n    multipleSeparator: ', '\n  };\n})(jQuery);\n\n\n}));\n"
  },
  {
    "path": "app_backend/static/js/i18n/defaults-zh_TW.js",
    "content": "/*!\n * Bootstrap-select v1.12.2 (http://silviomoreto.github.io/bootstrap-select)\n *\n * Copyright 2013-2017 bootstrap-select\n * Licensed under MIT (https://github.com/silviomoreto/bootstrap-select/blob/master/LICENSE)\n */\n\n(function (root, factory) {\n  if (typeof define === 'function' && define.amd) {\n    // AMD. Register as an anonymous module unless amdModuleId is set\n    define([\"jquery\"], function (a0) {\n      return (factory(a0));\n    });\n  } else if (typeof module === 'object' && module.exports) {\n    // Node. Does not work with strict CommonJS, but\n    // only CommonJS-like environments that support module.exports,\n    // like Node.\n    module.exports = factory(require(\"jquery\"));\n  } else {\n    factory(root[\"jQuery\"]);\n  }\n}(this, function (jQuery) {\n\n(function ($) {\n  $.fn.selectpicker.defaults = {\n    noneSelectedText: '沒有選取任何項目',\n    noneResultsText: '沒有找到符合的結果',\n    countSelectedText: '已經選取{0}個項目',\n    maxOptionsText: ['超過限制 (最多選擇{n}項)', '超過限制(最多選擇{n}組)'],\n    selectAllText: '選取全部',\n    deselectAllText: '全部取消',\n    multipleSeparator: ', '\n  };\n})(jQuery);\n\n\n}));\n"
  },
  {
    "path": "app_backend/static/js/npm.js",
    "content": "// This file is autogenerated via the `commonjs` Grunt task. You can require() this file in a CommonJS environment.\nrequire('../../js/transition.js')\nrequire('../../js/alert.js')\nrequire('../../js/button.js')\nrequire('../../js/carousel.js')\nrequire('../../js/collapse.js')\nrequire('../../js/dropdown.js')\nrequire('../../js/modal.js')\nrequire('../../js/tooltip.js')\nrequire('../../js/popover.js')\nrequire('../../js/scrollspy.js')\nrequire('../../js/tab.js')\nrequire('../../js/affix.js')"
  },
  {
    "path": "app_backend/static/js/sb-admin-2.js",
    "content": "/*!\n * Start Bootstrap - SB Admin 2 v3.3.7+1 (http://startbootstrap.com/template-overviews/sb-admin-2)\n * Copyright 2013-2016 Start Bootstrap\n * Licensed under MIT (https://github.com/BlackrockDigital/startbootstrap/blob/gh-pages/LICENSE)\n */\n$(function() {\n    $('#side-menu').metisMenu();\n});\n\n//Loads the correct sidebar on window load,\n//collapses the sidebar on window resize.\n// Sets the min-height of #page-wrapper to window size\n$(function() {\n    $(window).bind(\"load resize\", function() {\n        var topOffset = 50;\n        var width = (this.window.innerWidth > 0) ? this.window.innerWidth : this.screen.width;\n        if (width < 768) {\n            $('div.navbar-collapse').addClass('collapse');\n            topOffset = 100; // 2-row-menu\n        } else {\n            $('div.navbar-collapse').removeClass('collapse');\n        }\n\n        var height = ((this.window.innerHeight > 0) ? this.window.innerHeight : this.screen.height) - 1;\n        height = height - topOffset;\n        if (height < 1) height = 1;\n        if (height > topOffset) {\n            $(\"#page-wrapper\").css(\"min-height\", (height) + \"px\");\n        }\n    });\n\n    var url = window.location;\n    // var element = $('ul.nav a').filter(function() {\n    //     return this.href == url;\n    // }).addClass('active').parent().parent().addClass('in').parent();\n    var element = $('ul.nav a').filter(function() {\n        return this.href == url;\n    }).addClass('active').parent();\n\n    while (true) {\n        if (element.is('li')) {\n            element = element.parent().addClass('in').parent();\n        } else {\n            break;\n        }\n    }\n});\n"
  },
  {
    "path": "app_backend/static/plugin/Chart.js-2.6.0/.codeclimate.yml",
    "content": "engines:\n  duplication:\n    enabled: true\n    config:\n      languages:\n      - javascript\n    exclude_paths:\n    - \"samples/samples.js\"\n  eslint:\n    enabled: true\n    channel: \"eslint-3\"\n  fixme:\n    enabled: true\nratings:\n  paths:\n  - \"src/**/*.js\"\nexclude_paths:\n- dist/**/*\n- node_modules/**/*\n- test/**/*\n- coverage/**/*\n"
  },
  {
    "path": "app_backend/static/plugin/Chart.js-2.6.0/.editorconfig",
    "content": "# http://editorconfig.org\nroot = true\n\n[*]\nindent_style = tab\nindent_size = 4\nend_of_line = lf\ncharset = utf-8\ntrim_trailing_whitespace = true\ninsert_final_newline = false\n"
  },
  {
    "path": "app_backend/static/plugin/Chart.js-2.6.0/.eslintignore",
    "content": "**/*{.,-}min.js\n"
  },
  {
    "path": "app_backend/static/plugin/Chart.js-2.6.0/.eslintrc",
    "content": "ecmaFeatures:\n  modules: true\n  jsx: true\n\nenv:\n  amd: true\n  browser: true\n  es6: true\n  jquery: true\n  node: true\n\n# http://eslint.org/docs/rules/\nrules:\n  # Possible Errors\n  no-cond-assign: 2\n  no-console: [2, {allow: [warn, error]}]\n  no-constant-condition: 2\n  no-control-regex: 2\n  no-debugger: 2\n  no-dupe-args: 2\n  no-dupe-keys: 2\n  no-duplicate-case: 2\n  no-empty: 2\n  no-empty-character-class: 2\n  no-ex-assign: 2\n  no-extra-boolean-cast: 2\n  no-extra-parens: [2, functions]\n  no-extra-semi: 2\n  no-func-assign: 2\n  no-inner-declarations: [2, functions]\n  no-invalid-regexp: 2\n  no-irregular-whitespace: 2\n  no-negated-in-lhs: 2\n  no-obj-calls: 2\n  no-regex-spaces: 2\n  no-sparse-arrays: 2\n  no-unexpected-multiline: 2\n  no-unreachable: 2\n  use-isnan: 2\n  valid-jsdoc: 0\n  valid-typeof: 2\n\n  # Best Practices\n  accessor-pairs: 2\n  array-callback-return: 0\n  block-scoped-var: 0\n  complexity: [2, 6]\n  consistent-return: 0\n  curly: [2, all]\n  default-case: 2\n  dot-location: 0\n  dot-notation: 2\n  eqeqeq: 2\n  guard-for-in: 2\n  no-alert: 2\n  no-caller: 2\n  no-case-declarations: 2\n  no-div-regex: 2\n  no-else-return: 2\n  no-empty-pattern: 2\n  no-eq-null: 2\n  no-eval: 2\n  no-extend-native: 2\n  no-extra-bind: 2\n  no-fallthrough: 2\n  no-floating-decimal: 2\n  no-implicit-coercion: 0\n  no-implied-eval: 2\n  no-invalid-this: 0\n  no-iterator: 2\n  no-labels: 2\n  no-lone-blocks: 2\n  no-loop-func: 2\n  no-magic-number: 0\n  no-multi-spaces: 2\n  no-multi-str: 2\n  no-native-reassign: 2\n  no-new-func: 2\n  no-new-wrappers: 2\n  no-new: 2\n  no-octal-escape: 2\n  no-octal: 2\n  no-proto: 2\n  no-redeclare: 2\n  no-return-assign: 2\n  no-script-url: 2\n  no-self-compare: 2\n  no-sequences: 2\n  no-throw-literal: 0\n  no-unused-expressions: 2\n  no-useless-call: 2\n  no-useless-concat: 2\n  no-void: 2\n  no-warning-comments: 0\n  no-with: 2\n  radix: 2\n  vars-on-top: 0\n  wrap-iife: 2\n  yoda: [1, never]\n\n  # Strict\n  strict: 0\n\n  # Variables\n  init-declarations: 0\n  no-catch-shadow: 2\n  no-delete-var: 2\n  no-label-var: 2\n  no-shadow-restricted-names: 2\n  no-shadow: 2\n  no-undef-init: 2\n  no-undef: 2\n  no-undefined: 0\n  no-unused-vars: 2\n  no-use-before-define: 2\n\n  # Node.js and CommonJS\n  callback-return: 2\n  global-require: 2\n  handle-callback-err: 2\n  no-mixed-requires: 0\n  no-new-require: 0\n  no-path-concat: 2\n  no-process-exit: 2\n  no-restricted-modules: 0\n  no-sync: 0\n\n  # Stylistic Issues\n  array-bracket-spacing: [2, never]\n  block-spacing: 0\n  brace-style: [2, 1tbs]\n  camelcase: 2\n  comma-dangle: [2, only-multiline]\n  comma-spacing: 2\n  comma-style: [2, last]\n  computed-property-spacing: [2, never]\n  consistent-this: [2, me]\n  eol-last: 2\n  func-call-spacing: 0\n  func-names: [2, never]\n  func-style: 0\n  id-length: 0\n  id-match: 0\n  indent: [2, tab]\n  jsx-quotes: 0\n  key-spacing: 2\n  keyword-spacing: 2\n  linebreak-style: 0\n  lines-around-comment: 0\n  max-depth: 0\n  max-len: 0\n  max-lines: 0\n  max-nested-callbacks: 0\n  max-params: 0\n  max-statements-per-line: 0\n  max-statements: [2, 30]\n  multiline-ternary: 0\n  new-cap: 0\n  new-parens: 2\n  newline-after-var: 0\n  newline-before-return: 0\n  newline-per-chained-call: 0\n  no-array-constructor: 0\n  no-bitwise: 0\n  no-continue: 0\n  no-inline-comments: 0\n  no-lonely-if: 2\n  no-mixed-operators: 0\n  no-mixed-spaces-and-tabs: 2\n  no-multiple-empty-lines: [2, {max: 2}]\n  no-negated-condition: 0\n  no-nested-ternary: 0\n  no-new-object: 0\n  no-plusplus: 0\n  no-restricted-syntax: 0\n  no-spaced-func: 0\n  no-ternary: 0\n  no-trailing-spaces: 2\n  no-underscore-dangle: 0\n  no-unneeded-ternary: 0\n  no-whitespace-before-property: 2\n  object-curly-newline: 0\n  object-curly-spacing: [2, never]\n  object-property-newline: 0\n  one-var-declaration-per-line: 2\n  one-var: 0\n  operator-assignment: 0\n  operator-linebreak: 0\n  padded-blocks: 0\n  quote-props: [2, as-needed]\n  quotes: [2, single, {avoidEscape: true}]\n  require-jsdoc: 0\n  semi-spacing: 2\n  semi: [2, always]\n  sort-keys: 0\n  sort-vars: 0\n  space-before-blocks: [2, always]\n  space-before-function-paren: [2, never]\n  space-in-parens: [2, never]\n  space-infix-ops: 0\n  space-unary-ops: 0\n  spaced-comment: [2, always]\n  unicode-bom: 0\n  wrap-regex: 2\n\n  # ECMAScript 6\n  arrow-body-style: 0\n  arrow-parens: 0\n  arrow-spacing: 0\n  constructor-super: 0\n  generator-star-spacing: 0\n  no-arrow-condition: 0\n  no-class-assign: 0\n  no-const-assign: 0\n  no-dupe-class-members: 0\n  no-this-before-super: 0\n  no-var: 0\n  object-shorthand: 0\n  prefer-arrow-callback: 0\n  prefer-const: 0\n  prefer-reflect: 0\n  prefer-spread: 0\n  prefer-template: 0\n  require-yield: 0\n"
  },
  {
    "path": "app_backend/static/plugin/Chart.js-2.6.0/.github/ISSUE_TEMPLATE.md",
    "content": "<!--\nPlease consider the following before submitting an issue:\n\n- Issues are reserved for BUG reports and FEATURE requests, DO NOT create issues for questions or support requests.\n- Most features should start as plugins outside of Chart.js (http://www.chartjs.org/docs/#advanced-usage-creating-plugins).\n- Bug reports MUST be submitted with an interactive example (http://codepen.io/pen?template=JXVYzq).\n- Chart.js 1.x is NOT supported anymore, new issues will be disregarded.\n-->\n\n<!--- Provide a general summary of the issue in the Title above prefixed by [BUG] or [FEATURE] -->\n\n## Expected Behavior\n<!--- If you're describing a bug, tell us what should happen -->\n<!--- If you're suggesting a change/improvement, tell us how it should work -->\n\n## Current Behavior\n<!--- If describing a bug, tell us what happens instead of the expected behavior -->\n<!--- If suggesting a change/improvement, explain the difference from current behavior -->\n\n## Possible Solution\n<!--- Not obligatory, but suggest a fix/reason for the bug, -->\n<!--- or ideas how to implement the addition or change -->\n\n## Steps to Reproduce (for bugs)\n<!--- Provide a link to a live example, or an unambiguous set of steps to -->\n<!--- reproduce this bug. Include code to reproduce, if relevant -->\n1.\n2.\n3.\n4.\n\n## Context\n<!--- How has this issue affected you? What are you trying to accomplish? -->\n<!--- Providing context helps us come up with a solution that is most useful in the real world -->\n\n## Environment\n<!--- Include as many relevant details about the environment you experienced the bug in -->\n* Chart.js version:\n* Browser name and version:\n* Link to your project:\n"
  },
  {
    "path": "app_backend/static/plugin/Chart.js-2.6.0/.github/PULL_REQUEST_TEMPLATE.md",
    "content": "Please consider the following before submitting a pull request:\n\nGuidelines for contributing: https://github.com/chartjs/Chart.js/blob/master/docs/developers/contributing.md\n\nExample of changes on an interactive website such as the following:\n- http://jsbin.com/\n- http://jsfiddle.net/\n- http://codepen.io/pen/\n- Premade template: http://codepen.io/pen?template=JXVYzq"
  },
  {
    "path": "app_backend/static/plugin/Chart.js-2.6.0/.gitignore",
    "content": "/_book\n/coverage\n/custom\n#/dist\n/docs/index.md\n/gh-pages\n/node_modules\n.DS_Store\n.idea\n.vscode\nbower.json\n*.log\n*.swp\n"
  },
  {
    "path": "app_backend/static/plugin/Chart.js-2.6.0/.npmignore",
    "content": "/.git\n/.github\n/coverage\n/custom\n/dist/*.zip\n/docs/index.md\n/node_modules\n\n.codeclimate.yml\n.DS_Store\n.gitignore\n.idea\n.travis.yml\n"
  },
  {
    "path": "app_backend/static/plugin/Chart.js-2.6.0/.travis.yml",
    "content": "language: node_js\nnode_js:\n  - \"5.10\"\n\nbefore_install:\n  - \"export CHROME_BIN=/usr/bin/google-chrome\"\n  - \"export DISPLAY=:99.0\"\n  - \"sh -e /etc/init.d/xvfb start\"\n\nbefore_script:\n  - npm install\n\nscript:\n  - gulp build\n  - gulp test --coverage\n  - gulp docs\n  - gulp package\n  - gulp bower\n  - cat ./coverage/lcov.info | ./node_modules/.bin/coveralls\n\nnotifications:\n  slack: chartjs:pcfCZR6ugg5TEcaLtmIfQYuA\n\nsudo: required\ndist: trusty\n\naddons:\n  firefox: latest\n  apt:\n    sources:\n      - google-chrome\n    packages:\n      - google-chrome-stable\n\n\n# IMPORTANT: scripts require GITHUB_AUTH_TOKEN and GITHUB_AUTH_EMAIL environment variables\n# IMPORTANT: scripts has to be set executables in the Git repository (error 127)\n# https://github.com/travis-ci/travis-ci/issues/5538#issuecomment-225025939\n\ndeploy:\n- provider: script\n  script: ./scripts/deploy.sh\n  skip_cleanup: true\n  on:\n    all_branches: true\n- provider: script\n  script: ./scripts/release.sh\n  skip_cleanup: true\n  on:\n    branch: release\n- provider: releases\n  api_key: $GITHUB_AUTH_TOKEN\n  file:\n  - \"./dist/Chart.bundle.js\"\n  - \"./dist/Chart.bundle.min.js\"\n  - \"./dist/Chart.js\"\n  - \"./dist/Chart.min.js\"\n  - \"./dist/Chart.js.zip\"\n  skip_cleanup: true\n  on:\n    tags: true\n- provider: npm\n  email: $NPM_AUTH_EMAIL\n  api_key: $NPM_AUTH_TOKEN\n  skip_cleanup: true\n  on:\n    tags: true\n"
  },
  {
    "path": "app_backend/static/plugin/Chart.js-2.6.0/LICENSE.md",
    "content": "The MIT License (MIT)\n\nCopyright (c) 2013-2017 Nick Downie\n\nPermission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the \"Software\"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n"
  },
  {
    "path": "app_backend/static/plugin/Chart.js-2.6.0/MAINTAINING.md",
    "content": "# Maintaining\n## Release Process\nChart.js relies on [Travis CI](https://travis-ci.org/) to automate the library [releases](https://github.com/chartjs/Chart.js/releases).\n\n### Releasing a New Version\n\n1. draft release notes on [GitHub](https://github.com/chartjs/Chart.js/releases/new) for the upcoming tag\n1. update `master` `package.json` version using [semver](http://semver.org/) semantic\n1. merge `master` into the `release` branch\n1. follow the build process on [Travis CI](https://travis-ci.org/chartjs/Chart.js)\n\n> **Note:** if `master` is merged in `release` with a `package.json` version that already exists, the tag\ncreation fails and the release process is aborted.\n\n### Automated Tasks\nMerging into the `release` branch kicks off the automated release process:\n\n* build of the `dist/*.js` files\n* `bower.json` is generated from `package.json`\n* `dist/*.js` and `bower.json` are added to a detached branch\n* a tag is created from the `package.json` version\n* tag (with dist files) is pushed to GitHub\n\nCreation of this tag triggers a new build:\n\n* `Chart.js.zip` package is generated, containing dist files and examples\n* `dist/*.js` and `Chart.js.zip` are attached to the GitHub release (downloads)\n* a new npm package is published on [npmjs](https://www.npmjs.com/package/chart.js)\n\nFinally, [cdnjs](https://cdnjs.com/libraries/Chart.js) is automatically updated from the npm release.\n\n### Further Reading\n\n* [Travis GitHub releases](https://github.com/chartjs/Chart.js/pull/2555)\n* [Bower support and dist/* files](https://github.com/chartjs/Chart.js/issues/3033)\n* [cdnjs npm auto update](https://github.com/cdnjs/cdnjs/pull/8401)\n"
  },
  {
    "path": "app_backend/static/plugin/Chart.js-2.6.0/README.md",
    "content": "# Chart.js\n\n[![Build Status](https://travis-ci.org/chartjs/Chart.js.svg?branch=master)](https://travis-ci.org/chartjs/Chart.js) [![Code Climate](https://codeclimate.com/github/nnnick/Chart.js/badges/gpa.svg)](https://codeclimate.com/github/nnnick/Chart.js) [![Coverage Status](https://coveralls.io/repos/github/chartjs/Chart.js/badge.svg?branch=master)](https://coveralls.io/github/chartjs/Chart.js?branch=master)\n\n[![Chart.js on Slack](https://img.shields.io/badge/slack-Chart.js-blue.svg)](https://chart-js-automation.herokuapp.com/)\n\n*Simple HTML5 Charts using the canvas element* [chartjs.org](http://www.chartjs.org)\n\n## Installation\n\nYou can download the latest version of Chart.js from the [GitHub releases](https://github.com/chartjs/Chart.js/releases/latest) or use a [Chart.js CDN](https://cdnjs.com/libraries/Chart.js).\n\nTo install via npm:\n\n```bash\nnpm install chart.js --save\n```\n\nTo install via bower:\n```bash\nbower install chart.js --save\n```\n\n#### Selecting the Correct Build\n\nChart.js provides two different builds that are available for your use. The `Chart.js` and `Chart.min.js` files include Chart.js and the accompanying color parsing library. If this version is used and you require the use of the time axis, [Moment.js](http://momentjs.com/) will need to be included before Chart.js.\n\nThe `Chart.bundle.js` and `Chart.bundle.min.js` builds include Moment.js in a single file. This version should be used if you require time axes and want a single file to include, select this version. Do not use this build if your application already includes Moment.js. If you do, Moment.js will be included twice, increasing the page load time and potentially introducing version issues.\n\n## Documentation\n\nYou can find documentation at [www.chartjs.org/docs](http://www.chartjs.org/docs). The markdown files that build the site are available under `/docs`. Previous version documentation is available at [www.chartjs.org/docs/#notes-previous-versions](http://www.chartjs.org/docs/#notes-previous-versions).\n\n## Contributing\n\nBefore submitting an issue or a pull request, please take a moment to look over the [contributing guidelines](https://github.com/chartjs/Chart.js/blob/master/docs/developers/contributing.md) first. For support using Chart.js, please post questions with the [`chartjs` tag on Stack Overflow](http://stackoverflow.com/questions/tagged/chartjs).\n\n## Building\nInstructions on building and testing Chart.js can be found in [the documentation](https://github.com/chartjs/Chart.js/blob/master/docs/developers/contributing.md#building-and-testing).\n\n## Thanks\n- [BrowserStack](https://browserstack.com) for allowing our team to test on thousands of browsers.\n- [@n8agrin](https://twitter.com/n8agrin) for the Twitter handle donation.\n\n## License\n\nChart.js is available under the [MIT license](http://opensource.org/licenses/MIT).\n"
  },
  {
    "path": "app_backend/static/plugin/Chart.js-2.6.0/book.json",
    "content": "{\n  \"root\": \"./docs\",\n  \"author\": \"chartjs\",\n  \"gitbook\": \"3.2.2\",\n  \"plugins\": [\"-lunr\", \"-search\", \"search-plus\", \"anchorjs\", \"chartjs\", \"ga\"],\n  \"pluginsConfig\": {\n    \"anchorjs\": {\n      \"icon\": \"#\",\n      \"placement\": \"left\",\n      \"visible\": \"always\"\n    },\n    \"ga\": {\n      \"token\": \"UA-28909194-3\",\n      \"configuration\": \"auto\"\n    },\n    \"theme-default\": {\n      \"showLevel\": false,\n      \"styles\": {\n        \"website\": \"style.css\"\n      }\n    }\n  }\n}\n"
  },
  {
    "path": "app_backend/static/plugin/Chart.js-2.6.0/composer.json",
    "content": "{\n    \"name\": \"nnnick/chartjs\",\n    \"type\": \"library\",\n    \"description\": \"Simple HTML5 charts using the canvas element.\",\n    \"keywords\": [\n        \"chart\",\n        \"js\"\n    ],\n    \"homepage\": \"http://www.chartjs.org/\",\n    \"license\": \"MIT\",\n    \"authors\": [\n        {\n            \"name\": \"NICK DOWNIE\",\n            \"email\": \"hello@nickdownie.com\"\n        }\n    ],\n    \"require\": {\n        \"php\": \">=5.3.3\"\n    },\n    \"minimum-stability\": \"stable\",\n    \"extra\": {\n        \"branch-alias\": {\n            \"release/2.0\": \"v2.0-dev\"\n        }\n    }\n}\n"
  },
  {
    "path": "app_backend/static/plugin/Chart.js-2.6.0/dist/Chart.bundle.js",
    "content": "/*!\n * Chart.js\n * http://chartjs.org/\n * Version: 2.6.0\n *\n * Copyright 2017 Nick Downie\n * Released under the MIT license\n * https://github.com/chartjs/Chart.js/blob/master/LICENSE.md\n */\n(function(f){if(typeof exports===\"object\"&&typeof module!==\"undefined\"){module.exports=f()}else if(typeof define===\"function\"&&define.amd){define([],f)}else{var g;if(typeof window!==\"undefined\"){g=window}else if(typeof global!==\"undefined\"){g=global}else if(typeof self!==\"undefined\"){g=self}else{g=this}g.Chart = f()}})(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require==\"function\"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error(\"Cannot find module '\"+o+\"'\");throw f.code=\"MODULE_NOT_FOUND\",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require==\"function\"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){\n/* MIT license */\r\nvar colorNames = require(5);\r\n\r\nmodule.exports = {\r\n   getRgba: getRgba,\r\n   getHsla: getHsla,\r\n   getRgb: getRgb,\r\n   getHsl: getHsl,\r\n   getHwb: getHwb,\r\n   getAlpha: getAlpha,\r\n\r\n   hexString: hexString,\r\n   rgbString: rgbString,\r\n   rgbaString: rgbaString,\r\n   percentString: percentString,\r\n   percentaString: percentaString,\r\n   hslString: hslString,\r\n   hslaString: hslaString,\r\n   hwbString: hwbString,\r\n   keyword: keyword\r\n}\r\n\r\nfunction getRgba(string) {\r\n   if (!string) {\r\n      return;\r\n   }\r\n   var abbr =  /^#([a-fA-F0-9]{3})$/,\r\n       hex =  /^#([a-fA-F0-9]{6})$/,\r\n       rgba = /^rgba?\\(\\s*([+-]?\\d+)\\s*,\\s*([+-]?\\d+)\\s*,\\s*([+-]?\\d+)\\s*(?:,\\s*([+-]?[\\d\\.]+)\\s*)?\\)$/,\r\n       per = /^rgba?\\(\\s*([+-]?[\\d\\.]+)\\%\\s*,\\s*([+-]?[\\d\\.]+)\\%\\s*,\\s*([+-]?[\\d\\.]+)\\%\\s*(?:,\\s*([+-]?[\\d\\.]+)\\s*)?\\)$/,\r\n       keyword = /(\\w+)/;\r\n\r\n   var rgb = [0, 0, 0],\r\n       a = 1,\r\n       match = string.match(abbr);\r\n   if (match) {\r\n      match = match[1];\r\n      for (var i = 0; i < rgb.length; i++) {\r\n         rgb[i] = parseInt(match[i] + match[i], 16);\r\n      }\r\n   }\r\n   else if (match = string.match(hex)) {\r\n      match = match[1];\r\n      for (var i = 0; i < rgb.length; i++) {\r\n         rgb[i] = parseInt(match.slice(i * 2, i * 2 + 2), 16);\r\n      }\r\n   }\r\n   else if (match = string.match(rgba)) {\r\n      for (var i = 0; i < rgb.length; i++) {\r\n         rgb[i] = parseInt(match[i + 1]);\r\n      }\r\n      a = parseFloat(match[4]);\r\n   }\r\n   else if (match = string.match(per)) {\r\n      for (var i = 0; i < rgb.length; i++) {\r\n         rgb[i] = Math.round(parseFloat(match[i + 1]) * 2.55);\r\n      }\r\n      a = parseFloat(match[4]);\r\n   }\r\n   else if (match = string.match(keyword)) {\r\n      if (match[1] == \"transparent\") {\r\n         return [0, 0, 0, 0];\r\n      }\r\n      rgb = colorNames[match[1]];\r\n      if (!rgb) {\r\n         return;\r\n      }\r\n   }\r\n\r\n   for (var i = 0; i < rgb.length; i++) {\r\n      rgb[i] = scale(rgb[i], 0, 255);\r\n   }\r\n   if (!a && a != 0) {\r\n      a = 1;\r\n   }\r\n   else {\r\n      a = scale(a, 0, 1);\r\n   }\r\n   rgb[3] = a;\r\n   return rgb;\r\n}\r\n\r\nfunction getHsla(string) {\r\n   if (!string) {\r\n      return;\r\n   }\r\n   var hsl = /^hsla?\\(\\s*([+-]?\\d+)(?:deg)?\\s*,\\s*([+-]?[\\d\\.]+)%\\s*,\\s*([+-]?[\\d\\.]+)%\\s*(?:,\\s*([+-]?[\\d\\.]+)\\s*)?\\)/;\r\n   var match = string.match(hsl);\r\n   if (match) {\r\n      var alpha = parseFloat(match[4]);\r\n      var h = scale(parseInt(match[1]), 0, 360),\r\n          s = scale(parseFloat(match[2]), 0, 100),\r\n          l = scale(parseFloat(match[3]), 0, 100),\r\n          a = scale(isNaN(alpha) ? 1 : alpha, 0, 1);\r\n      return [h, s, l, a];\r\n   }\r\n}\r\n\r\nfunction getHwb(string) {\r\n   if (!string) {\r\n      return;\r\n   }\r\n   var hwb = /^hwb\\(\\s*([+-]?\\d+)(?:deg)?\\s*,\\s*([+-]?[\\d\\.]+)%\\s*,\\s*([+-]?[\\d\\.]+)%\\s*(?:,\\s*([+-]?[\\d\\.]+)\\s*)?\\)/;\r\n   var match = string.match(hwb);\r\n   if (match) {\r\n    var alpha = parseFloat(match[4]);\r\n      var h = scale(parseInt(match[1]), 0, 360),\r\n          w = scale(parseFloat(match[2]), 0, 100),\r\n          b = scale(parseFloat(match[3]), 0, 100),\r\n          a = scale(isNaN(alpha) ? 1 : alpha, 0, 1);\r\n      return [h, w, b, a];\r\n   }\r\n}\r\n\r\nfunction getRgb(string) {\r\n   var rgba = getRgba(string);\r\n   return rgba && rgba.slice(0, 3);\r\n}\r\n\r\nfunction getHsl(string) {\r\n  var hsla = getHsla(string);\r\n  return hsla && hsla.slice(0, 3);\r\n}\r\n\r\nfunction getAlpha(string) {\r\n   var vals = getRgba(string);\r\n   if (vals) {\r\n      return vals[3];\r\n   }\r\n   else if (vals = getHsla(string)) {\r\n      return vals[3];\r\n   }\r\n   else if (vals = getHwb(string)) {\r\n      return vals[3];\r\n   }\r\n}\r\n\r\n// generators\r\nfunction hexString(rgb) {\r\n   return \"#\" + hexDouble(rgb[0]) + hexDouble(rgb[1])\r\n              + hexDouble(rgb[2]);\r\n}\r\n\r\nfunction rgbString(rgba, alpha) {\r\n   if (alpha < 1 || (rgba[3] && rgba[3] < 1)) {\r\n      return rgbaString(rgba, alpha);\r\n   }\r\n   return \"rgb(\" + rgba[0] + \", \" + rgba[1] + \", \" + rgba[2] + \")\";\r\n}\r\n\r\nfunction rgbaString(rgba, alpha) {\r\n   if (alpha === undefined) {\r\n      alpha = (rgba[3] !== undefined ? rgba[3] : 1);\r\n   }\r\n   return \"rgba(\" + rgba[0] + \", \" + rgba[1] + \", \" + rgba[2]\r\n           + \", \" + alpha + \")\";\r\n}\r\n\r\nfunction percentString(rgba, alpha) {\r\n   if (alpha < 1 || (rgba[3] && rgba[3] < 1)) {\r\n      return percentaString(rgba, alpha);\r\n   }\r\n   var r = Math.round(rgba[0]/255 * 100),\r\n       g = Math.round(rgba[1]/255 * 100),\r\n       b = Math.round(rgba[2]/255 * 100);\r\n\r\n   return \"rgb(\" + r + \"%, \" + g + \"%, \" + b + \"%)\";\r\n}\r\n\r\nfunction percentaString(rgba, alpha) {\r\n   var r = Math.round(rgba[0]/255 * 100),\r\n       g = Math.round(rgba[1]/255 * 100),\r\n       b = Math.round(rgba[2]/255 * 100);\r\n   return \"rgba(\" + r + \"%, \" + g + \"%, \" + b + \"%, \" + (alpha || rgba[3] || 1) + \")\";\r\n}\r\n\r\nfunction hslString(hsla, alpha) {\r\n   if (alpha < 1 || (hsla[3] && hsla[3] < 1)) {\r\n      return hslaString(hsla, alpha);\r\n   }\r\n   return \"hsl(\" + hsla[0] + \", \" + hsla[1] + \"%, \" + hsla[2] + \"%)\";\r\n}\r\n\r\nfunction hslaString(hsla, alpha) {\r\n   if (alpha === undefined) {\r\n      alpha = (hsla[3] !== undefined ? hsla[3] : 1);\r\n   }\r\n   return \"hsla(\" + hsla[0] + \", \" + hsla[1] + \"%, \" + hsla[2] + \"%, \"\r\n           + alpha + \")\";\r\n}\r\n\r\n// hwb is a bit different than rgb(a) & hsl(a) since there is no alpha specific syntax\r\n// (hwb have alpha optional & 1 is default value)\r\nfunction hwbString(hwb, alpha) {\r\n   if (alpha === undefined) {\r\n      alpha = (hwb[3] !== undefined ? hwb[3] : 1);\r\n   }\r\n   return \"hwb(\" + hwb[0] + \", \" + hwb[1] + \"%, \" + hwb[2] + \"%\"\r\n           + (alpha !== undefined && alpha !== 1 ? \", \" + alpha : \"\") + \")\";\r\n}\r\n\r\nfunction keyword(rgb) {\r\n  return reverseNames[rgb.slice(0, 3)];\r\n}\r\n\r\n// helpers\r\nfunction scale(num, min, max) {\r\n   return Math.min(Math.max(min, num), max);\r\n}\r\n\r\nfunction hexDouble(num) {\r\n  var str = num.toString(16).toUpperCase();\r\n  return (str.length < 2) ? \"0\" + str : str;\r\n}\r\n\r\n\r\n//create a list of reverse color names\r\nvar reverseNames = {};\r\nfor (var name in colorNames) {\r\n   reverseNames[colorNames[name]] = name;\r\n}\r\n\n},{\"5\":5}],2:[function(require,module,exports){\n/* MIT license */\nvar convert = require(4);\nvar string = require(1);\n\nvar Color = function (obj) {\n\tif (obj instanceof Color) {\n\t\treturn obj;\n\t}\n\tif (!(this instanceof Color)) {\n\t\treturn new Color(obj);\n\t}\n\n\tthis.valid = false;\n\tthis.values = {\n\t\trgb: [0, 0, 0],\n\t\thsl: [0, 0, 0],\n\t\thsv: [0, 0, 0],\n\t\thwb: [0, 0, 0],\n\t\tcmyk: [0, 0, 0, 0],\n\t\talpha: 1\n\t};\n\n\t// parse Color() argument\n\tvar vals;\n\tif (typeof obj === 'string') {\n\t\tvals = string.getRgba(obj);\n\t\tif (vals) {\n\t\t\tthis.setValues('rgb', vals);\n\t\t} else if (vals = string.getHsla(obj)) {\n\t\t\tthis.setValues('hsl', vals);\n\t\t} else if (vals = string.getHwb(obj)) {\n\t\t\tthis.setValues('hwb', vals);\n\t\t}\n\t} else if (typeof obj === 'object') {\n\t\tvals = obj;\n\t\tif (vals.r !== undefined || vals.red !== undefined) {\n\t\t\tthis.setValues('rgb', vals);\n\t\t} else if (vals.l !== undefined || vals.lightness !== undefined) {\n\t\t\tthis.setValues('hsl', vals);\n\t\t} else if (vals.v !== undefined || vals.value !== undefined) {\n\t\t\tthis.setValues('hsv', vals);\n\t\t} else if (vals.w !== undefined || vals.whiteness !== undefined) {\n\t\t\tthis.setValues('hwb', vals);\n\t\t} else if (vals.c !== undefined || vals.cyan !== undefined) {\n\t\t\tthis.setValues('cmyk', vals);\n\t\t}\n\t}\n};\n\nColor.prototype = {\n\tisValid: function () {\n\t\treturn this.valid;\n\t},\n\trgb: function () {\n\t\treturn this.setSpace('rgb', arguments);\n\t},\n\thsl: function () {\n\t\treturn this.setSpace('hsl', arguments);\n\t},\n\thsv: function () {\n\t\treturn this.setSpace('hsv', arguments);\n\t},\n\thwb: function () {\n\t\treturn this.setSpace('hwb', arguments);\n\t},\n\tcmyk: function () {\n\t\treturn this.setSpace('cmyk', arguments);\n\t},\n\n\trgbArray: function () {\n\t\treturn this.values.rgb;\n\t},\n\thslArray: function () {\n\t\treturn this.values.hsl;\n\t},\n\thsvArray: function () {\n\t\treturn this.values.hsv;\n\t},\n\thwbArray: function () {\n\t\tvar values = this.values;\n\t\tif (values.alpha !== 1) {\n\t\t\treturn values.hwb.concat([values.alpha]);\n\t\t}\n\t\treturn values.hwb;\n\t},\n\tcmykArray: function () {\n\t\treturn this.values.cmyk;\n\t},\n\trgbaArray: function () {\n\t\tvar values = this.values;\n\t\treturn values.rgb.concat([values.alpha]);\n\t},\n\thslaArray: function () {\n\t\tvar values = this.values;\n\t\treturn values.hsl.concat([values.alpha]);\n\t},\n\talpha: function (val) {\n\t\tif (val === undefined) {\n\t\t\treturn this.values.alpha;\n\t\t}\n\t\tthis.setValues('alpha', val);\n\t\treturn this;\n\t},\n\n\tred: function (val) {\n\t\treturn this.setChannel('rgb', 0, val);\n\t},\n\tgreen: function (val) {\n\t\treturn this.setChannel('rgb', 1, val);\n\t},\n\tblue: function (val) {\n\t\treturn this.setChannel('rgb', 2, val);\n\t},\n\thue: function (val) {\n\t\tif (val) {\n\t\t\tval %= 360;\n\t\t\tval = val < 0 ? 360 + val : val;\n\t\t}\n\t\treturn this.setChannel('hsl', 0, val);\n\t},\n\tsaturation: function (val) {\n\t\treturn this.setChannel('hsl', 1, val);\n\t},\n\tlightness: function (val) {\n\t\treturn this.setChannel('hsl', 2, val);\n\t},\n\tsaturationv: function (val) {\n\t\treturn this.setChannel('hsv', 1, val);\n\t},\n\twhiteness: function (val) {\n\t\treturn this.setChannel('hwb', 1, val);\n\t},\n\tblackness: function (val) {\n\t\treturn this.setChannel('hwb', 2, val);\n\t},\n\tvalue: function (val) {\n\t\treturn this.setChannel('hsv', 2, val);\n\t},\n\tcyan: function (val) {\n\t\treturn this.setChannel('cmyk', 0, val);\n\t},\n\tmagenta: function (val) {\n\t\treturn this.setChannel('cmyk', 1, val);\n\t},\n\tyellow: function (val) {\n\t\treturn this.setChannel('cmyk', 2, val);\n\t},\n\tblack: function (val) {\n\t\treturn this.setChannel('cmyk', 3, val);\n\t},\n\n\thexString: function () {\n\t\treturn string.hexString(this.values.rgb);\n\t},\n\trgbString: function () {\n\t\treturn string.rgbString(this.values.rgb, this.values.alpha);\n\t},\n\trgbaString: function () {\n\t\treturn string.rgbaString(this.values.rgb, this.values.alpha);\n\t},\n\tpercentString: function () {\n\t\treturn string.percentString(this.values.rgb, this.values.alpha);\n\t},\n\thslString: function () {\n\t\treturn string.hslString(this.values.hsl, this.values.alpha);\n\t},\n\thslaString: function () {\n\t\treturn string.hslaString(this.values.hsl, this.values.alpha);\n\t},\n\thwbString: function () {\n\t\treturn string.hwbString(this.values.hwb, this.values.alpha);\n\t},\n\tkeyword: function () {\n\t\treturn string.keyword(this.values.rgb, this.values.alpha);\n\t},\n\n\trgbNumber: function () {\n\t\tvar rgb = this.values.rgb;\n\t\treturn (rgb[0] << 16) | (rgb[1] << 8) | rgb[2];\n\t},\n\n\tluminosity: function () {\n\t\t// http://www.w3.org/TR/WCAG20/#relativeluminancedef\n\t\tvar rgb = this.values.rgb;\n\t\tvar lum = [];\n\t\tfor (var i = 0; i < rgb.length; i++) {\n\t\t\tvar chan = rgb[i] / 255;\n\t\t\tlum[i] = (chan <= 0.03928) ? chan / 12.92 : Math.pow(((chan + 0.055) / 1.055), 2.4);\n\t\t}\n\t\treturn 0.2126 * lum[0] + 0.7152 * lum[1] + 0.0722 * lum[2];\n\t},\n\n\tcontrast: function (color2) {\n\t\t// http://www.w3.org/TR/WCAG20/#contrast-ratiodef\n\t\tvar lum1 = this.luminosity();\n\t\tvar lum2 = color2.luminosity();\n\t\tif (lum1 > lum2) {\n\t\t\treturn (lum1 + 0.05) / (lum2 + 0.05);\n\t\t}\n\t\treturn (lum2 + 0.05) / (lum1 + 0.05);\n\t},\n\n\tlevel: function (color2) {\n\t\tvar contrastRatio = this.contrast(color2);\n\t\tif (contrastRatio >= 7.1) {\n\t\t\treturn 'AAA';\n\t\t}\n\n\t\treturn (contrastRatio >= 4.5) ? 'AA' : '';\n\t},\n\n\tdark: function () {\n\t\t// YIQ equation from http://24ways.org/2010/calculating-color-contrast\n\t\tvar rgb = this.values.rgb;\n\t\tvar yiq = (rgb[0] * 299 + rgb[1] * 587 + rgb[2] * 114) / 1000;\n\t\treturn yiq < 128;\n\t},\n\n\tlight: function () {\n\t\treturn !this.dark();\n\t},\n\n\tnegate: function () {\n\t\tvar rgb = [];\n\t\tfor (var i = 0; i < 3; i++) {\n\t\t\trgb[i] = 255 - this.values.rgb[i];\n\t\t}\n\t\tthis.setValues('rgb', rgb);\n\t\treturn this;\n\t},\n\n\tlighten: function (ratio) {\n\t\tvar hsl = this.values.hsl;\n\t\thsl[2] += hsl[2] * ratio;\n\t\tthis.setValues('hsl', hsl);\n\t\treturn this;\n\t},\n\n\tdarken: function (ratio) {\n\t\tvar hsl = this.values.hsl;\n\t\thsl[2] -= hsl[2] * ratio;\n\t\tthis.setValues('hsl', hsl);\n\t\treturn this;\n\t},\n\n\tsaturate: function (ratio) {\n\t\tvar hsl = this.values.hsl;\n\t\thsl[1] += hsl[1] * ratio;\n\t\tthis.setValues('hsl', hsl);\n\t\treturn this;\n\t},\n\n\tdesaturate: function (ratio) {\n\t\tvar hsl = this.values.hsl;\n\t\thsl[1] -= hsl[1] * ratio;\n\t\tthis.setValues('hsl', hsl);\n\t\treturn this;\n\t},\n\n\twhiten: function (ratio) {\n\t\tvar hwb = this.values.hwb;\n\t\thwb[1] += hwb[1] * ratio;\n\t\tthis.setValues('hwb', hwb);\n\t\treturn this;\n\t},\n\n\tblacken: function (ratio) {\n\t\tvar hwb = this.values.hwb;\n\t\thwb[2] += hwb[2] * ratio;\n\t\tthis.setValues('hwb', hwb);\n\t\treturn this;\n\t},\n\n\tgreyscale: function () {\n\t\tvar rgb = this.values.rgb;\n\t\t// http://en.wikipedia.org/wiki/Grayscale#Converting_color_to_grayscale\n\t\tvar val = rgb[0] * 0.3 + rgb[1] * 0.59 + rgb[2] * 0.11;\n\t\tthis.setValues('rgb', [val, val, val]);\n\t\treturn this;\n\t},\n\n\tclearer: function (ratio) {\n\t\tvar alpha = this.values.alpha;\n\t\tthis.setValues('alpha', alpha - (alpha * ratio));\n\t\treturn this;\n\t},\n\n\topaquer: function (ratio) {\n\t\tvar alpha = this.values.alpha;\n\t\tthis.setValues('alpha', alpha + (alpha * ratio));\n\t\treturn this;\n\t},\n\n\trotate: function (degrees) {\n\t\tvar hsl = this.values.hsl;\n\t\tvar hue = (hsl[0] + degrees) % 360;\n\t\thsl[0] = hue < 0 ? 360 + hue : hue;\n\t\tthis.setValues('hsl', hsl);\n\t\treturn this;\n\t},\n\n\t/**\n\t * Ported from sass implementation in C\n\t * https://github.com/sass/libsass/blob/0e6b4a2850092356aa3ece07c6b249f0221caced/functions.cpp#L209\n\t */\n\tmix: function (mixinColor, weight) {\n\t\tvar color1 = this;\n\t\tvar color2 = mixinColor;\n\t\tvar p = weight === undefined ? 0.5 : weight;\n\n\t\tvar w = 2 * p - 1;\n\t\tvar a = color1.alpha() - color2.alpha();\n\n\t\tvar w1 = (((w * a === -1) ? w : (w + a) / (1 + w * a)) + 1) / 2.0;\n\t\tvar w2 = 1 - w1;\n\n\t\treturn this\n\t\t\t.rgb(\n\t\t\t\tw1 * color1.red() + w2 * color2.red(),\n\t\t\t\tw1 * color1.green() + w2 * color2.green(),\n\t\t\t\tw1 * color1.blue() + w2 * color2.blue()\n\t\t\t)\n\t\t\t.alpha(color1.alpha() * p + color2.alpha() * (1 - p));\n\t},\n\n\ttoJSON: function () {\n\t\treturn this.rgb();\n\t},\n\n\tclone: function () {\n\t\t// NOTE(SB): using node-clone creates a dependency to Buffer when using browserify,\n\t\t// making the final build way to big to embed in Chart.js. So let's do it manually,\n\t\t// assuming that values to clone are 1 dimension arrays containing only numbers,\n\t\t// except 'alpha' which is a number.\n\t\tvar result = new Color();\n\t\tvar source = this.values;\n\t\tvar target = result.values;\n\t\tvar value, type;\n\n\t\tfor (var prop in source) {\n\t\t\tif (source.hasOwnProperty(prop)) {\n\t\t\t\tvalue = source[prop];\n\t\t\t\ttype = ({}).toString.call(value);\n\t\t\t\tif (type === '[object Array]') {\n\t\t\t\t\ttarget[prop] = value.slice(0);\n\t\t\t\t} else if (type === '[object Number]') {\n\t\t\t\t\ttarget[prop] = value;\n\t\t\t\t} else {\n\t\t\t\t\tconsole.error('unexpected color value:', value);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn result;\n\t}\n};\n\nColor.prototype.spaces = {\n\trgb: ['red', 'green', 'blue'],\n\thsl: ['hue', 'saturation', 'lightness'],\n\thsv: ['hue', 'saturation', 'value'],\n\thwb: ['hue', 'whiteness', 'blackness'],\n\tcmyk: ['cyan', 'magenta', 'yellow', 'black']\n};\n\nColor.prototype.maxes = {\n\trgb: [255, 255, 255],\n\thsl: [360, 100, 100],\n\thsv: [360, 100, 100],\n\thwb: [360, 100, 100],\n\tcmyk: [100, 100, 100, 100]\n};\n\nColor.prototype.getValues = function (space) {\n\tvar values = this.values;\n\tvar vals = {};\n\n\tfor (var i = 0; i < space.length; i++) {\n\t\tvals[space.charAt(i)] = values[space][i];\n\t}\n\n\tif (values.alpha !== 1) {\n\t\tvals.a = values.alpha;\n\t}\n\n\t// {r: 255, g: 255, b: 255, a: 0.4}\n\treturn vals;\n};\n\nColor.prototype.setValues = function (space, vals) {\n\tvar values = this.values;\n\tvar spaces = this.spaces;\n\tvar maxes = this.maxes;\n\tvar alpha = 1;\n\tvar i;\n\n\tthis.valid = true;\n\n\tif (space === 'alpha') {\n\t\talpha = vals;\n\t} else if (vals.length) {\n\t\t// [10, 10, 10]\n\t\tvalues[space] = vals.slice(0, space.length);\n\t\talpha = vals[space.length];\n\t} else if (vals[space.charAt(0)] !== undefined) {\n\t\t// {r: 10, g: 10, b: 10}\n\t\tfor (i = 0; i < space.length; i++) {\n\t\t\tvalues[space][i] = vals[space.charAt(i)];\n\t\t}\n\n\t\talpha = vals.a;\n\t} else if (vals[spaces[space][0]] !== undefined) {\n\t\t// {red: 10, green: 10, blue: 10}\n\t\tvar chans = spaces[space];\n\n\t\tfor (i = 0; i < space.length; i++) {\n\t\t\tvalues[space][i] = vals[chans[i]];\n\t\t}\n\n\t\talpha = vals.alpha;\n\t}\n\n\tvalues.alpha = Math.max(0, Math.min(1, (alpha === undefined ? values.alpha : alpha)));\n\n\tif (space === 'alpha') {\n\t\treturn false;\n\t}\n\n\tvar capped;\n\n\t// cap values of the space prior converting all values\n\tfor (i = 0; i < space.length; i++) {\n\t\tcapped = Math.max(0, Math.min(maxes[space][i], values[space][i]));\n\t\tvalues[space][i] = Math.round(capped);\n\t}\n\n\t// convert to all the other color spaces\n\tfor (var sname in spaces) {\n\t\tif (sname !== space) {\n\t\t\tvalues[sname] = convert[space][sname](values[space]);\n\t\t}\n\t}\n\n\treturn true;\n};\n\nColor.prototype.setSpace = function (space, args) {\n\tvar vals = args[0];\n\n\tif (vals === undefined) {\n\t\t// color.rgb()\n\t\treturn this.getValues(space);\n\t}\n\n\t// color.rgb(10, 10, 10)\n\tif (typeof vals === 'number') {\n\t\tvals = Array.prototype.slice.call(args);\n\t}\n\n\tthis.setValues(space, vals);\n\treturn this;\n};\n\nColor.prototype.setChannel = function (space, index, val) {\n\tvar svalues = this.values[space];\n\tif (val === undefined) {\n\t\t// color.red()\n\t\treturn svalues[index];\n\t} else if (val === svalues[index]) {\n\t\t// color.red(color.red())\n\t\treturn this;\n\t}\n\n\t// color.red(100)\n\tsvalues[index] = val;\n\tthis.setValues(space, svalues);\n\n\treturn this;\n};\n\nif (typeof window !== 'undefined') {\n\twindow.Color = Color;\n}\n\nmodule.exports = Color;\n\n},{\"1\":1,\"4\":4}],3:[function(require,module,exports){\n/* MIT license */\n\nmodule.exports = {\n  rgb2hsl: rgb2hsl,\n  rgb2hsv: rgb2hsv,\n  rgb2hwb: rgb2hwb,\n  rgb2cmyk: rgb2cmyk,\n  rgb2keyword: rgb2keyword,\n  rgb2xyz: rgb2xyz,\n  rgb2lab: rgb2lab,\n  rgb2lch: rgb2lch,\n\n  hsl2rgb: hsl2rgb,\n  hsl2hsv: hsl2hsv,\n  hsl2hwb: hsl2hwb,\n  hsl2cmyk: hsl2cmyk,\n  hsl2keyword: hsl2keyword,\n\n  hsv2rgb: hsv2rgb,\n  hsv2hsl: hsv2hsl,\n  hsv2hwb: hsv2hwb,\n  hsv2cmyk: hsv2cmyk,\n  hsv2keyword: hsv2keyword,\n\n  hwb2rgb: hwb2rgb,\n  hwb2hsl: hwb2hsl,\n  hwb2hsv: hwb2hsv,\n  hwb2cmyk: hwb2cmyk,\n  hwb2keyword: hwb2keyword,\n\n  cmyk2rgb: cmyk2rgb,\n  cmyk2hsl: cmyk2hsl,\n  cmyk2hsv: cmyk2hsv,\n  cmyk2hwb: cmyk2hwb,\n  cmyk2keyword: cmyk2keyword,\n\n  keyword2rgb: keyword2rgb,\n  keyword2hsl: keyword2hsl,\n  keyword2hsv: keyword2hsv,\n  keyword2hwb: keyword2hwb,\n  keyword2cmyk: keyword2cmyk,\n  keyword2lab: keyword2lab,\n  keyword2xyz: keyword2xyz,\n\n  xyz2rgb: xyz2rgb,\n  xyz2lab: xyz2lab,\n  xyz2lch: xyz2lch,\n\n  lab2xyz: lab2xyz,\n  lab2rgb: lab2rgb,\n  lab2lch: lab2lch,\n\n  lch2lab: lch2lab,\n  lch2xyz: lch2xyz,\n  lch2rgb: lch2rgb\n}\n\n\nfunction rgb2hsl(rgb) {\n  var r = rgb[0]/255,\n      g = rgb[1]/255,\n      b = rgb[2]/255,\n      min = Math.min(r, g, b),\n      max = Math.max(r, g, b),\n      delta = max - min,\n      h, s, l;\n\n  if (max == min)\n    h = 0;\n  else if (r == max)\n    h = (g - b) / delta;\n  else if (g == max)\n    h = 2 + (b - r) / delta;\n  else if (b == max)\n    h = 4 + (r - g)/ delta;\n\n  h = Math.min(h * 60, 360);\n\n  if (h < 0)\n    h += 360;\n\n  l = (min + max) / 2;\n\n  if (max == min)\n    s = 0;\n  else if (l <= 0.5)\n    s = delta / (max + min);\n  else\n    s = delta / (2 - max - min);\n\n  return [h, s * 100, l * 100];\n}\n\nfunction rgb2hsv(rgb) {\n  var r = rgb[0],\n      g = rgb[1],\n      b = rgb[2],\n      min = Math.min(r, g, b),\n      max = Math.max(r, g, b),\n      delta = max - min,\n      h, s, v;\n\n  if (max == 0)\n    s = 0;\n  else\n    s = (delta/max * 1000)/10;\n\n  if (max == min)\n    h = 0;\n  else if (r == max)\n    h = (g - b) / delta;\n  else if (g == max)\n    h = 2 + (b - r) / delta;\n  else if (b == max)\n    h = 4 + (r - g) / delta;\n\n  h = Math.min(h * 60, 360);\n\n  if (h < 0)\n    h += 360;\n\n  v = ((max / 255) * 1000) / 10;\n\n  return [h, s, v];\n}\n\nfunction rgb2hwb(rgb) {\n  var r = rgb[0],\n      g = rgb[1],\n      b = rgb[2],\n      h = rgb2hsl(rgb)[0],\n      w = 1/255 * Math.min(r, Math.min(g, b)),\n      b = 1 - 1/255 * Math.max(r, Math.max(g, b));\n\n  return [h, w * 100, b * 100];\n}\n\nfunction rgb2cmyk(rgb) {\n  var r = rgb[0] / 255,\n      g = rgb[1] / 255,\n      b = rgb[2] / 255,\n      c, m, y, k;\n\n  k = Math.min(1 - r, 1 - g, 1 - b);\n  c = (1 - r - k) / (1 - k) || 0;\n  m = (1 - g - k) / (1 - k) || 0;\n  y = (1 - b - k) / (1 - k) || 0;\n  return [c * 100, m * 100, y * 100, k * 100];\n}\n\nfunction rgb2keyword(rgb) {\n  return reverseKeywords[JSON.stringify(rgb)];\n}\n\nfunction rgb2xyz(rgb) {\n  var r = rgb[0] / 255,\n      g = rgb[1] / 255,\n      b = rgb[2] / 255;\n\n  // assume sRGB\n  r = r > 0.04045 ? Math.pow(((r + 0.055) / 1.055), 2.4) : (r / 12.92);\n  g = g > 0.04045 ? Math.pow(((g + 0.055) / 1.055), 2.4) : (g / 12.92);\n  b = b > 0.04045 ? Math.pow(((b + 0.055) / 1.055), 2.4) : (b / 12.92);\n\n  var x = (r * 0.4124) + (g * 0.3576) + (b * 0.1805);\n  var y = (r * 0.2126) + (g * 0.7152) + (b * 0.0722);\n  var z = (r * 0.0193) + (g * 0.1192) + (b * 0.9505);\n\n  return [x * 100, y *100, z * 100];\n}\n\nfunction rgb2lab(rgb) {\n  var xyz = rgb2xyz(rgb),\n        x = xyz[0],\n        y = xyz[1],\n        z = xyz[2],\n        l, a, b;\n\n  x /= 95.047;\n  y /= 100;\n  z /= 108.883;\n\n  x = x > 0.008856 ? Math.pow(x, 1/3) : (7.787 * x) + (16 / 116);\n  y = y > 0.008856 ? Math.pow(y, 1/3) : (7.787 * y) + (16 / 116);\n  z = z > 0.008856 ? Math.pow(z, 1/3) : (7.787 * z) + (16 / 116);\n\n  l = (116 * y) - 16;\n  a = 500 * (x - y);\n  b = 200 * (y - z);\n\n  return [l, a, b];\n}\n\nfunction rgb2lch(args) {\n  return lab2lch(rgb2lab(args));\n}\n\nfunction hsl2rgb(hsl) {\n  var h = hsl[0] / 360,\n      s = hsl[1] / 100,\n      l = hsl[2] / 100,\n      t1, t2, t3, rgb, val;\n\n  if (s == 0) {\n    val = l * 255;\n    return [val, val, val];\n  }\n\n  if (l < 0.5)\n    t2 = l * (1 + s);\n  else\n    t2 = l + s - l * s;\n  t1 = 2 * l - t2;\n\n  rgb = [0, 0, 0];\n  for (var i = 0; i < 3; i++) {\n    t3 = h + 1 / 3 * - (i - 1);\n    t3 < 0 && t3++;\n    t3 > 1 && t3--;\n\n    if (6 * t3 < 1)\n      val = t1 + (t2 - t1) * 6 * t3;\n    else if (2 * t3 < 1)\n      val = t2;\n    else if (3 * t3 < 2)\n      val = t1 + (t2 - t1) * (2 / 3 - t3) * 6;\n    else\n      val = t1;\n\n    rgb[i] = val * 255;\n  }\n\n  return rgb;\n}\n\nfunction hsl2hsv(hsl) {\n  var h = hsl[0],\n      s = hsl[1] / 100,\n      l = hsl[2] / 100,\n      sv, v;\n\n  if(l === 0) {\n      // no need to do calc on black\n      // also avoids divide by 0 error\n      return [0, 0, 0];\n  }\n\n  l *= 2;\n  s *= (l <= 1) ? l : 2 - l;\n  v = (l + s) / 2;\n  sv = (2 * s) / (l + s);\n  return [h, sv * 100, v * 100];\n}\n\nfunction hsl2hwb(args) {\n  return rgb2hwb(hsl2rgb(args));\n}\n\nfunction hsl2cmyk(args) {\n  return rgb2cmyk(hsl2rgb(args));\n}\n\nfunction hsl2keyword(args) {\n  return rgb2keyword(hsl2rgb(args));\n}\n\n\nfunction hsv2rgb(hsv) {\n  var h = hsv[0] / 60,\n      s = hsv[1] / 100,\n      v = hsv[2] / 100,\n      hi = Math.floor(h) % 6;\n\n  var f = h - Math.floor(h),\n      p = 255 * v * (1 - s),\n      q = 255 * v * (1 - (s * f)),\n      t = 255 * v * (1 - (s * (1 - f))),\n      v = 255 * v;\n\n  switch(hi) {\n    case 0:\n      return [v, t, p];\n    case 1:\n      return [q, v, p];\n    case 2:\n      return [p, v, t];\n    case 3:\n      return [p, q, v];\n    case 4:\n      return [t, p, v];\n    case 5:\n      return [v, p, q];\n  }\n}\n\nfunction hsv2hsl(hsv) {\n  var h = hsv[0],\n      s = hsv[1] / 100,\n      v = hsv[2] / 100,\n      sl, l;\n\n  l = (2 - s) * v;\n  sl = s * v;\n  sl /= (l <= 1) ? l : 2 - l;\n  sl = sl || 0;\n  l /= 2;\n  return [h, sl * 100, l * 100];\n}\n\nfunction hsv2hwb(args) {\n  return rgb2hwb(hsv2rgb(args))\n}\n\nfunction hsv2cmyk(args) {\n  return rgb2cmyk(hsv2rgb(args));\n}\n\nfunction hsv2keyword(args) {\n  return rgb2keyword(hsv2rgb(args));\n}\n\n// http://dev.w3.org/csswg/css-color/#hwb-to-rgb\nfunction hwb2rgb(hwb) {\n  var h = hwb[0] / 360,\n      wh = hwb[1] / 100,\n      bl = hwb[2] / 100,\n      ratio = wh + bl,\n      i, v, f, n;\n\n  // wh + bl cant be > 1\n  if (ratio > 1) {\n    wh /= ratio;\n    bl /= ratio;\n  }\n\n  i = Math.floor(6 * h);\n  v = 1 - bl;\n  f = 6 * h - i;\n  if ((i & 0x01) != 0) {\n    f = 1 - f;\n  }\n  n = wh + f * (v - wh);  // linear interpolation\n\n  switch (i) {\n    default:\n    case 6:\n    case 0: r = v; g = n; b = wh; break;\n    case 1: r = n; g = v; b = wh; break;\n    case 2: r = wh; g = v; b = n; break;\n    case 3: r = wh; g = n; b = v; break;\n    case 4: r = n; g = wh; b = v; break;\n    case 5: r = v; g = wh; b = n; break;\n  }\n\n  return [r * 255, g * 255, b * 255];\n}\n\nfunction hwb2hsl(args) {\n  return rgb2hsl(hwb2rgb(args));\n}\n\nfunction hwb2hsv(args) {\n  return rgb2hsv(hwb2rgb(args));\n}\n\nfunction hwb2cmyk(args) {\n  return rgb2cmyk(hwb2rgb(args));\n}\n\nfunction hwb2keyword(args) {\n  return rgb2keyword(hwb2rgb(args));\n}\n\nfunction cmyk2rgb(cmyk) {\n  var c = cmyk[0] / 100,\n      m = cmyk[1] / 100,\n      y = cmyk[2] / 100,\n      k = cmyk[3] / 100,\n      r, g, b;\n\n  r = 1 - Math.min(1, c * (1 - k) + k);\n  g = 1 - Math.min(1, m * (1 - k) + k);\n  b = 1 - Math.min(1, y * (1 - k) + k);\n  return [r * 255, g * 255, b * 255];\n}\n\nfunction cmyk2hsl(args) {\n  return rgb2hsl(cmyk2rgb(args));\n}\n\nfunction cmyk2hsv(args) {\n  return rgb2hsv(cmyk2rgb(args));\n}\n\nfunction cmyk2hwb(args) {\n  return rgb2hwb(cmyk2rgb(args));\n}\n\nfunction cmyk2keyword(args) {\n  return rgb2keyword(cmyk2rgb(args));\n}\n\n\nfunction xyz2rgb(xyz) {\n  var x = xyz[0] / 100,\n      y = xyz[1] / 100,\n      z = xyz[2] / 100,\n      r, g, b;\n\n  r = (x * 3.2406) + (y * -1.5372) + (z * -0.4986);\n  g = (x * -0.9689) + (y * 1.8758) + (z * 0.0415);\n  b = (x * 0.0557) + (y * -0.2040) + (z * 1.0570);\n\n  // assume sRGB\n  r = r > 0.0031308 ? ((1.055 * Math.pow(r, 1.0 / 2.4)) - 0.055)\n    : r = (r * 12.92);\n\n  g = g > 0.0031308 ? ((1.055 * Math.pow(g, 1.0 / 2.4)) - 0.055)\n    : g = (g * 12.92);\n\n  b = b > 0.0031308 ? ((1.055 * Math.pow(b, 1.0 / 2.4)) - 0.055)\n    : b = (b * 12.92);\n\n  r = Math.min(Math.max(0, r), 1);\n  g = Math.min(Math.max(0, g), 1);\n  b = Math.min(Math.max(0, b), 1);\n\n  return [r * 255, g * 255, b * 255];\n}\n\nfunction xyz2lab(xyz) {\n  var x = xyz[0],\n      y = xyz[1],\n      z = xyz[2],\n      l, a, b;\n\n  x /= 95.047;\n  y /= 100;\n  z /= 108.883;\n\n  x = x > 0.008856 ? Math.pow(x, 1/3) : (7.787 * x) + (16 / 116);\n  y = y > 0.008856 ? Math.pow(y, 1/3) : (7.787 * y) + (16 / 116);\n  z = z > 0.008856 ? Math.pow(z, 1/3) : (7.787 * z) + (16 / 116);\n\n  l = (116 * y) - 16;\n  a = 500 * (x - y);\n  b = 200 * (y - z);\n\n  return [l, a, b];\n}\n\nfunction xyz2lch(args) {\n  return lab2lch(xyz2lab(args));\n}\n\nfunction lab2xyz(lab) {\n  var l = lab[0],\n      a = lab[1],\n      b = lab[2],\n      x, y, z, y2;\n\n  if (l <= 8) {\n    y = (l * 100) / 903.3;\n    y2 = (7.787 * (y / 100)) + (16 / 116);\n  } else {\n    y = 100 * Math.pow((l + 16) / 116, 3);\n    y2 = Math.pow(y / 100, 1/3);\n  }\n\n  x = x / 95.047 <= 0.008856 ? x = (95.047 * ((a / 500) + y2 - (16 / 116))) / 7.787 : 95.047 * Math.pow((a / 500) + y2, 3);\n\n  z = z / 108.883 <= 0.008859 ? z = (108.883 * (y2 - (b / 200) - (16 / 116))) / 7.787 : 108.883 * Math.pow(y2 - (b / 200), 3);\n\n  return [x, y, z];\n}\n\nfunction lab2lch(lab) {\n  var l = lab[0],\n      a = lab[1],\n      b = lab[2],\n      hr, h, c;\n\n  hr = Math.atan2(b, a);\n  h = hr * 360 / 2 / Math.PI;\n  if (h < 0) {\n    h += 360;\n  }\n  c = Math.sqrt(a * a + b * b);\n  return [l, c, h];\n}\n\nfunction lab2rgb(args) {\n  return xyz2rgb(lab2xyz(args));\n}\n\nfunction lch2lab(lch) {\n  var l = lch[0],\n      c = lch[1],\n      h = lch[2],\n      a, b, hr;\n\n  hr = h / 360 * 2 * Math.PI;\n  a = c * Math.cos(hr);\n  b = c * Math.sin(hr);\n  return [l, a, b];\n}\n\nfunction lch2xyz(args) {\n  return lab2xyz(lch2lab(args));\n}\n\nfunction lch2rgb(args) {\n  return lab2rgb(lch2lab(args));\n}\n\nfunction keyword2rgb(keyword) {\n  return cssKeywords[keyword];\n}\n\nfunction keyword2hsl(args) {\n  return rgb2hsl(keyword2rgb(args));\n}\n\nfunction keyword2hsv(args) {\n  return rgb2hsv(keyword2rgb(args));\n}\n\nfunction keyword2hwb(args) {\n  return rgb2hwb(keyword2rgb(args));\n}\n\nfunction keyword2cmyk(args) {\n  return rgb2cmyk(keyword2rgb(args));\n}\n\nfunction keyword2lab(args) {\n  return rgb2lab(keyword2rgb(args));\n}\n\nfunction keyword2xyz(args) {\n  return rgb2xyz(keyword2rgb(args));\n}\n\nvar cssKeywords = {\n  aliceblue:  [240,248,255],\n  antiquewhite: [250,235,215],\n  aqua: [0,255,255],\n  aquamarine: [127,255,212],\n  azure:  [240,255,255],\n  beige:  [245,245,220],\n  bisque: [255,228,196],\n  black:  [0,0,0],\n  blanchedalmond: [255,235,205],\n  blue: [0,0,255],\n  blueviolet: [138,43,226],\n  brown:  [165,42,42],\n  burlywood:  [222,184,135],\n  cadetblue:  [95,158,160],\n  chartreuse: [127,255,0],\n  chocolate:  [210,105,30],\n  coral:  [255,127,80],\n  cornflowerblue: [100,149,237],\n  cornsilk: [255,248,220],\n  crimson:  [220,20,60],\n  cyan: [0,255,255],\n  darkblue: [0,0,139],\n  darkcyan: [0,139,139],\n  darkgoldenrod:  [184,134,11],\n  darkgray: [169,169,169],\n  darkgreen:  [0,100,0],\n  darkgrey: [169,169,169],\n  darkkhaki:  [189,183,107],\n  darkmagenta:  [139,0,139],\n  darkolivegreen: [85,107,47],\n  darkorange: [255,140,0],\n  darkorchid: [153,50,204],\n  darkred:  [139,0,0],\n  darksalmon: [233,150,122],\n  darkseagreen: [143,188,143],\n  darkslateblue:  [72,61,139],\n  darkslategray:  [47,79,79],\n  darkslategrey:  [47,79,79],\n  darkturquoise:  [0,206,209],\n  darkviolet: [148,0,211],\n  deeppink: [255,20,147],\n  deepskyblue:  [0,191,255],\n  dimgray:  [105,105,105],\n  dimgrey:  [105,105,105],\n  dodgerblue: [30,144,255],\n  firebrick:  [178,34,34],\n  floralwhite:  [255,250,240],\n  forestgreen:  [34,139,34],\n  fuchsia:  [255,0,255],\n  gainsboro:  [220,220,220],\n  ghostwhite: [248,248,255],\n  gold: [255,215,0],\n  goldenrod:  [218,165,32],\n  gray: [128,128,128],\n  green:  [0,128,0],\n  greenyellow:  [173,255,47],\n  grey: [128,128,128],\n  honeydew: [240,255,240],\n  hotpink:  [255,105,180],\n  indianred:  [205,92,92],\n  indigo: [75,0,130],\n  ivory:  [255,255,240],\n  khaki:  [240,230,140],\n  lavender: [230,230,250],\n  lavenderblush:  [255,240,245],\n  lawngreen:  [124,252,0],\n  lemonchiffon: [255,250,205],\n  lightblue:  [173,216,230],\n  lightcoral: [240,128,128],\n  lightcyan:  [224,255,255],\n  lightgoldenrodyellow: [250,250,210],\n  lightgray:  [211,211,211],\n  lightgreen: [144,238,144],\n  lightgrey:  [211,211,211],\n  lightpink:  [255,182,193],\n  lightsalmon:  [255,160,122],\n  lightseagreen:  [32,178,170],\n  lightskyblue: [135,206,250],\n  lightslategray: [119,136,153],\n  lightslategrey: [119,136,153],\n  lightsteelblue: [176,196,222],\n  lightyellow:  [255,255,224],\n  lime: [0,255,0],\n  limegreen:  [50,205,50],\n  linen:  [250,240,230],\n  magenta:  [255,0,255],\n  maroon: [128,0,0],\n  mediumaquamarine: [102,205,170],\n  mediumblue: [0,0,205],\n  mediumorchid: [186,85,211],\n  mediumpurple: [147,112,219],\n  mediumseagreen: [60,179,113],\n  mediumslateblue:  [123,104,238],\n  mediumspringgreen:  [0,250,154],\n  mediumturquoise:  [72,209,204],\n  mediumvioletred:  [199,21,133],\n  midnightblue: [25,25,112],\n  mintcream:  [245,255,250],\n  mistyrose:  [255,228,225],\n  moccasin: [255,228,181],\n  navajowhite:  [255,222,173],\n  navy: [0,0,128],\n  oldlace:  [253,245,230],\n  olive:  [128,128,0],\n  olivedrab:  [107,142,35],\n  orange: [255,165,0],\n  orangered:  [255,69,0],\n  orchid: [218,112,214],\n  palegoldenrod:  [238,232,170],\n  palegreen:  [152,251,152],\n  paleturquoise:  [175,238,238],\n  palevioletred:  [219,112,147],\n  papayawhip: [255,239,213],\n  peachpuff:  [255,218,185],\n  peru: [205,133,63],\n  pink: [255,192,203],\n  plum: [221,160,221],\n  powderblue: [176,224,230],\n  purple: [128,0,128],\n  rebeccapurple: [102, 51, 153],\n  red:  [255,0,0],\n  rosybrown:  [188,143,143],\n  royalblue:  [65,105,225],\n  saddlebrown:  [139,69,19],\n  salmon: [250,128,114],\n  sandybrown: [244,164,96],\n  seagreen: [46,139,87],\n  seashell: [255,245,238],\n  sienna: [160,82,45],\n  silver: [192,192,192],\n  skyblue:  [135,206,235],\n  slateblue:  [106,90,205],\n  slategray:  [112,128,144],\n  slategrey:  [112,128,144],\n  snow: [255,250,250],\n  springgreen:  [0,255,127],\n  steelblue:  [70,130,180],\n  tan:  [210,180,140],\n  teal: [0,128,128],\n  thistle:  [216,191,216],\n  tomato: [255,99,71],\n  turquoise:  [64,224,208],\n  violet: [238,130,238],\n  wheat:  [245,222,179],\n  white:  [255,255,255],\n  whitesmoke: [245,245,245],\n  yellow: [255,255,0],\n  yellowgreen:  [154,205,50]\n};\n\nvar reverseKeywords = {};\nfor (var key in cssKeywords) {\n  reverseKeywords[JSON.stringify(cssKeywords[key])] = key;\n}\n\n},{}],4:[function(require,module,exports){\nvar conversions = require(3);\n\nvar convert = function() {\n   return new Converter();\n}\n\nfor (var func in conversions) {\n  // export Raw versions\n  convert[func + \"Raw\"] =  (function(func) {\n    // accept array or plain args\n    return function(arg) {\n      if (typeof arg == \"number\")\n        arg = Array.prototype.slice.call(arguments);\n      return conversions[func](arg);\n    }\n  })(func);\n\n  var pair = /(\\w+)2(\\w+)/.exec(func),\n      from = pair[1],\n      to = pair[2];\n\n  // export rgb2hsl and [\"rgb\"][\"hsl\"]\n  convert[from] = convert[from] || {};\n\n  convert[from][to] = convert[func] = (function(func) { \n    return function(arg) {\n      if (typeof arg == \"number\")\n        arg = Array.prototype.slice.call(arguments);\n      \n      var val = conversions[func](arg);\n      if (typeof val == \"string\" || val === undefined)\n        return val; // keyword\n\n      for (var i = 0; i < val.length; i++)\n        val[i] = Math.round(val[i]);\n      return val;\n    }\n  })(func);\n}\n\n\n/* Converter does lazy conversion and caching */\nvar Converter = function() {\n   this.convs = {};\n};\n\n/* Either get the values for a space or\n  set the values for a space, depending on args */\nConverter.prototype.routeSpace = function(space, args) {\n   var values = args[0];\n   if (values === undefined) {\n      // color.rgb()\n      return this.getValues(space);\n   }\n   // color.rgb(10, 10, 10)\n   if (typeof values == \"number\") {\n      values = Array.prototype.slice.call(args);        \n   }\n\n   return this.setValues(space, values);\n};\n  \n/* Set the values for a space, invalidating cache */\nConverter.prototype.setValues = function(space, values) {\n   this.space = space;\n   this.convs = {};\n   this.convs[space] = values;\n   return this;\n};\n\n/* Get the values for a space. If there's already\n  a conversion for the space, fetch it, otherwise\n  compute it */\nConverter.prototype.getValues = function(space) {\n   var vals = this.convs[space];\n   if (!vals) {\n      var fspace = this.space,\n          from = this.convs[fspace];\n      vals = convert[fspace][space](from);\n\n      this.convs[space] = vals;\n   }\n  return vals;\n};\n\n[\"rgb\", \"hsl\", \"hsv\", \"cmyk\", \"keyword\"].forEach(function(space) {\n   Converter.prototype[space] = function(vals) {\n      return this.routeSpace(space, arguments);\n   }\n});\n\nmodule.exports = convert;\n},{\"3\":3}],5:[function(require,module,exports){\nmodule.exports = {\r\n\t\"aliceblue\": [240, 248, 255],\r\n\t\"antiquewhite\": [250, 235, 215],\r\n\t\"aqua\": [0, 255, 255],\r\n\t\"aquamarine\": [127, 255, 212],\r\n\t\"azure\": [240, 255, 255],\r\n\t\"beige\": [245, 245, 220],\r\n\t\"bisque\": [255, 228, 196],\r\n\t\"black\": [0, 0, 0],\r\n\t\"blanchedalmond\": [255, 235, 205],\r\n\t\"blue\": [0, 0, 255],\r\n\t\"blueviolet\": [138, 43, 226],\r\n\t\"brown\": [165, 42, 42],\r\n\t\"burlywood\": [222, 184, 135],\r\n\t\"cadetblue\": [95, 158, 160],\r\n\t\"chartreuse\": [127, 255, 0],\r\n\t\"chocolate\": [210, 105, 30],\r\n\t\"coral\": [255, 127, 80],\r\n\t\"cornflowerblue\": [100, 149, 237],\r\n\t\"cornsilk\": [255, 248, 220],\r\n\t\"crimson\": [220, 20, 60],\r\n\t\"cyan\": [0, 255, 255],\r\n\t\"darkblue\": [0, 0, 139],\r\n\t\"darkcyan\": [0, 139, 139],\r\n\t\"darkgoldenrod\": [184, 134, 11],\r\n\t\"darkgray\": [169, 169, 169],\r\n\t\"darkgreen\": [0, 100, 0],\r\n\t\"darkgrey\": [169, 169, 169],\r\n\t\"darkkhaki\": [189, 183, 107],\r\n\t\"darkmagenta\": [139, 0, 139],\r\n\t\"darkolivegreen\": [85, 107, 47],\r\n\t\"darkorange\": [255, 140, 0],\r\n\t\"darkorchid\": [153, 50, 204],\r\n\t\"darkred\": [139, 0, 0],\r\n\t\"darksalmon\": [233, 150, 122],\r\n\t\"darkseagreen\": [143, 188, 143],\r\n\t\"darkslateblue\": [72, 61, 139],\r\n\t\"darkslategray\": [47, 79, 79],\r\n\t\"darkslategrey\": [47, 79, 79],\r\n\t\"darkturquoise\": [0, 206, 209],\r\n\t\"darkviolet\": [148, 0, 211],\r\n\t\"deeppink\": [255, 20, 147],\r\n\t\"deepskyblue\": [0, 191, 255],\r\n\t\"dimgray\": [105, 105, 105],\r\n\t\"dimgrey\": [105, 105, 105],\r\n\t\"dodgerblue\": [30, 144, 255],\r\n\t\"firebrick\": [178, 34, 34],\r\n\t\"floralwhite\": [255, 250, 240],\r\n\t\"forestgreen\": [34, 139, 34],\r\n\t\"fuchsia\": [255, 0, 255],\r\n\t\"gainsboro\": [220, 220, 220],\r\n\t\"ghostwhite\": [248, 248, 255],\r\n\t\"gold\": [255, 215, 0],\r\n\t\"goldenrod\": [218, 165, 32],\r\n\t\"gray\": [128, 128, 128],\r\n\t\"green\": [0, 128, 0],\r\n\t\"greenyellow\": [173, 255, 47],\r\n\t\"grey\": [128, 128, 128],\r\n\t\"honeydew\": [240, 255, 240],\r\n\t\"hotpink\": [255, 105, 180],\r\n\t\"indianred\": [205, 92, 92],\r\n\t\"indigo\": [75, 0, 130],\r\n\t\"ivory\": [255, 255, 240],\r\n\t\"khaki\": [240, 230, 140],\r\n\t\"lavender\": [230, 230, 250],\r\n\t\"lavenderblush\": [255, 240, 245],\r\n\t\"lawngreen\": [124, 252, 0],\r\n\t\"lemonchiffon\": [255, 250, 205],\r\n\t\"lightblue\": [173, 216, 230],\r\n\t\"lightcoral\": [240, 128, 128],\r\n\t\"lightcyan\": [224, 255, 255],\r\n\t\"lightgoldenrodyellow\": [250, 250, 210],\r\n\t\"lightgray\": [211, 211, 211],\r\n\t\"lightgreen\": [144, 238, 144],\r\n\t\"lightgrey\": [211, 211, 211],\r\n\t\"lightpink\": [255, 182, 193],\r\n\t\"lightsalmon\": [255, 160, 122],\r\n\t\"lightseagreen\": [32, 178, 170],\r\n\t\"lightskyblue\": [135, 206, 250],\r\n\t\"lightslategray\": [119, 136, 153],\r\n\t\"lightslategrey\": [119, 136, 153],\r\n\t\"lightsteelblue\": [176, 196, 222],\r\n\t\"lightyellow\": [255, 255, 224],\r\n\t\"lime\": [0, 255, 0],\r\n\t\"limegreen\": [50, 205, 50],\r\n\t\"linen\": [250, 240, 230],\r\n\t\"magenta\": [255, 0, 255],\r\n\t\"maroon\": [128, 0, 0],\r\n\t\"mediumaquamarine\": [102, 205, 170],\r\n\t\"mediumblue\": [0, 0, 205],\r\n\t\"mediumorchid\": [186, 85, 211],\r\n\t\"mediumpurple\": [147, 112, 219],\r\n\t\"mediumseagreen\": [60, 179, 113],\r\n\t\"mediumslateblue\": [123, 104, 238],\r\n\t\"mediumspringgreen\": [0, 250, 154],\r\n\t\"mediumturquoise\": [72, 209, 204],\r\n\t\"mediumvioletred\": [199, 21, 133],\r\n\t\"midnightblue\": [25, 25, 112],\r\n\t\"mintcream\": [245, 255, 250],\r\n\t\"mistyrose\": [255, 228, 225],\r\n\t\"moccasin\": [255, 228, 181],\r\n\t\"navajowhite\": [255, 222, 173],\r\n\t\"navy\": [0, 0, 128],\r\n\t\"oldlace\": [253, 245, 230],\r\n\t\"olive\": [128, 128, 0],\r\n\t\"olivedrab\": [107, 142, 35],\r\n\t\"orange\": [255, 165, 0],\r\n\t\"orangered\": [255, 69, 0],\r\n\t\"orchid\": [218, 112, 214],\r\n\t\"palegoldenrod\": [238, 232, 170],\r\n\t\"palegreen\": [152, 251, 152],\r\n\t\"paleturquoise\": [175, 238, 238],\r\n\t\"palevioletred\": [219, 112, 147],\r\n\t\"papayawhip\": [255, 239, 213],\r\n\t\"peachpuff\": [255, 218, 185],\r\n\t\"peru\": [205, 133, 63],\r\n\t\"pink\": [255, 192, 203],\r\n\t\"plum\": [221, 160, 221],\r\n\t\"powderblue\": [176, 224, 230],\r\n\t\"purple\": [128, 0, 128],\r\n\t\"rebeccapurple\": [102, 51, 153],\r\n\t\"red\": [255, 0, 0],\r\n\t\"rosybrown\": [188, 143, 143],\r\n\t\"royalblue\": [65, 105, 225],\r\n\t\"saddlebrown\": [139, 69, 19],\r\n\t\"salmon\": [250, 128, 114],\r\n\t\"sandybrown\": [244, 164, 96],\r\n\t\"seagreen\": [46, 139, 87],\r\n\t\"seashell\": [255, 245, 238],\r\n\t\"sienna\": [160, 82, 45],\r\n\t\"silver\": [192, 192, 192],\r\n\t\"skyblue\": [135, 206, 235],\r\n\t\"slateblue\": [106, 90, 205],\r\n\t\"slategray\": [112, 128, 144],\r\n\t\"slategrey\": [112, 128, 144],\r\n\t\"snow\": [255, 250, 250],\r\n\t\"springgreen\": [0, 255, 127],\r\n\t\"steelblue\": [70, 130, 180],\r\n\t\"tan\": [210, 180, 140],\r\n\t\"teal\": [0, 128, 128],\r\n\t\"thistle\": [216, 191, 216],\r\n\t\"tomato\": [255, 99, 71],\r\n\t\"turquoise\": [64, 224, 208],\r\n\t\"violet\": [238, 130, 238],\r\n\t\"wheat\": [245, 222, 179],\r\n\t\"white\": [255, 255, 255],\r\n\t\"whitesmoke\": [245, 245, 245],\r\n\t\"yellow\": [255, 255, 0],\r\n\t\"yellowgreen\": [154, 205, 50]\r\n};\n},{}],6:[function(require,module,exports){\n//! moment.js\n//! version : 2.18.1\n//! authors : Tim Wood, Iskren Chernev, Moment.js contributors\n//! license : MIT\n//! momentjs.com\n\n;(function (global, factory) {\n    typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :\n    typeof define === 'function' && define.amd ? define(factory) :\n    global.moment = factory()\n}(this, (function () { 'use strict';\n\nvar hookCallback;\n\nfunction hooks () {\n    return hookCallback.apply(null, arguments);\n}\n\n// This is done to register the method called with moment()\n// without creating circular dependencies.\nfunction setHookCallback (callback) {\n    hookCallback = callback;\n}\n\nfunction isArray(input) {\n    return input instanceof Array || Object.prototype.toString.call(input) === '[object Array]';\n}\n\nfunction isObject(input) {\n    // IE8 will treat undefined and null as object if it wasn't for\n    // input != null\n    return input != null && Object.prototype.toString.call(input) === '[object Object]';\n}\n\nfunction isObjectEmpty(obj) {\n    var k;\n    for (k in obj) {\n        // even if its not own property I'd still call it non-empty\n        return false;\n    }\n    return true;\n}\n\nfunction isUndefined(input) {\n    return input === void 0;\n}\n\nfunction isNumber(input) {\n    return typeof input === 'number' || Object.prototype.toString.call(input) === '[object Number]';\n}\n\nfunction isDate(input) {\n    return input instanceof Date || Object.prototype.toString.call(input) === '[object Date]';\n}\n\nfunction map(arr, fn) {\n    var res = [], i;\n    for (i = 0; i < arr.length; ++i) {\n        res.push(fn(arr[i], i));\n    }\n    return res;\n}\n\nfunction hasOwnProp(a, b) {\n    return Object.prototype.hasOwnProperty.call(a, b);\n}\n\nfunction extend(a, b) {\n    for (var i in b) {\n        if (hasOwnProp(b, i)) {\n            a[i] = b[i];\n        }\n    }\n\n    if (hasOwnProp(b, 'toString')) {\n        a.toString = b.toString;\n    }\n\n    if (hasOwnProp(b, 'valueOf')) {\n        a.valueOf = b.valueOf;\n    }\n\n    return a;\n}\n\nfunction createUTC (input, format, locale, strict) {\n    return createLocalOrUTC(input, format, locale, strict, true).utc();\n}\n\nfunction defaultParsingFlags() {\n    // We need to deep clone this object.\n    return {\n        empty           : false,\n        unusedTokens    : [],\n        unusedInput     : [],\n        overflow        : -2,\n        charsLeftOver   : 0,\n        nullInput       : false,\n        invalidMonth    : null,\n        invalidFormat   : false,\n        userInvalidated : false,\n        iso             : false,\n        parsedDateParts : [],\n        meridiem        : null,\n        rfc2822         : false,\n        weekdayMismatch : false\n    };\n}\n\nfunction getParsingFlags(m) {\n    if (m._pf == null) {\n        m._pf = defaultParsingFlags();\n    }\n    return m._pf;\n}\n\nvar some;\nif (Array.prototype.some) {\n    some = Array.prototype.some;\n} else {\n    some = function (fun) {\n        var t = Object(this);\n        var len = t.length >>> 0;\n\n        for (var i = 0; i < len; i++) {\n            if (i in t && fun.call(this, t[i], i, t)) {\n                return true;\n            }\n        }\n\n        return false;\n    };\n}\n\nvar some$1 = some;\n\nfunction isValid(m) {\n    if (m._isValid == null) {\n        var flags = getParsingFlags(m);\n        var parsedParts = some$1.call(flags.parsedDateParts, function (i) {\n            return i != null;\n        });\n        var isNowValid = !isNaN(m._d.getTime()) &&\n            flags.overflow < 0 &&\n            !flags.empty &&\n            !flags.invalidMonth &&\n            !flags.invalidWeekday &&\n            !flags.nullInput &&\n            !flags.invalidFormat &&\n            !flags.userInvalidated &&\n            (!flags.meridiem || (flags.meridiem && parsedParts));\n\n        if (m._strict) {\n            isNowValid = isNowValid &&\n                flags.charsLeftOver === 0 &&\n                flags.unusedTokens.length === 0 &&\n                flags.bigHour === undefined;\n        }\n\n        if (Object.isFrozen == null || !Object.isFrozen(m)) {\n            m._isValid = isNowValid;\n        }\n        else {\n            return isNowValid;\n        }\n    }\n    return m._isValid;\n}\n\nfunction createInvalid (flags) {\n    var m = createUTC(NaN);\n    if (flags != null) {\n        extend(getParsingFlags(m), flags);\n    }\n    else {\n        getParsingFlags(m).userInvalidated = true;\n    }\n\n    return m;\n}\n\n// Plugins that add properties should also add the key here (null value),\n// so we can properly clone ourselves.\nvar momentProperties = hooks.momentProperties = [];\n\nfunction copyConfig(to, from) {\n    var i, prop, val;\n\n    if (!isUndefined(from._isAMomentObject)) {\n        to._isAMomentObject = from._isAMomentObject;\n    }\n    if (!isUndefined(from._i)) {\n        to._i = from._i;\n    }\n    if (!isUndefined(from._f)) {\n        to._f = from._f;\n    }\n    if (!isUndefined(from._l)) {\n        to._l = from._l;\n    }\n    if (!isUndefined(from._strict)) {\n        to._strict = from._strict;\n    }\n    if (!isUndefined(from._tzm)) {\n        to._tzm = from._tzm;\n    }\n    if (!isUndefined(from._isUTC)) {\n        to._isUTC = from._isUTC;\n    }\n    if (!isUndefined(from._offset)) {\n        to._offset = from._offset;\n    }\n    if (!isUndefined(from._pf)) {\n        to._pf = getParsingFlags(from);\n    }\n    if (!isUndefined(from._locale)) {\n        to._locale = from._locale;\n    }\n\n    if (momentProperties.length > 0) {\n        for (i = 0; i < momentProperties.length; i++) {\n            prop = momentProperties[i];\n            val = from[prop];\n            if (!isUndefined(val)) {\n                to[prop] = val;\n            }\n        }\n    }\n\n    return to;\n}\n\nvar updateInProgress = false;\n\n// Moment prototype object\nfunction Moment(config) {\n    copyConfig(this, config);\n    this._d = new Date(config._d != null ? config._d.getTime() : NaN);\n    if (!this.isValid()) {\n        this._d = new Date(NaN);\n    }\n    // Prevent infinite loop in case updateOffset creates new moment\n    // objects.\n    if (updateInProgress === false) {\n        updateInProgress = true;\n        hooks.updateOffset(this);\n        updateInProgress = false;\n    }\n}\n\nfunction isMoment (obj) {\n    return obj instanceof Moment || (obj != null && obj._isAMomentObject != null);\n}\n\nfunction absFloor (number) {\n    if (number < 0) {\n        // -0 -> 0\n        return Math.ceil(number) || 0;\n    } else {\n        return Math.floor(number);\n    }\n}\n\nfunction toInt(argumentForCoercion) {\n    var coercedNumber = +argumentForCoercion,\n        value = 0;\n\n    if (coercedNumber !== 0 && isFinite(coercedNumber)) {\n        value = absFloor(coercedNumber);\n    }\n\n    return value;\n}\n\n// compare two arrays, return the number of differences\nfunction compareArrays(array1, array2, dontConvert) {\n    var len = Math.min(array1.length, array2.length),\n        lengthDiff = Math.abs(array1.length - array2.length),\n        diffs = 0,\n        i;\n    for (i = 0; i < len; i++) {\n        if ((dontConvert && array1[i] !== array2[i]) ||\n            (!dontConvert && toInt(array1[i]) !== toInt(array2[i]))) {\n            diffs++;\n        }\n    }\n    return diffs + lengthDiff;\n}\n\nfunction warn(msg) {\n    if (hooks.suppressDeprecationWarnings === false &&\n            (typeof console !==  'undefined') && console.warn) {\n        console.warn('Deprecation warning: ' + msg);\n    }\n}\n\nfunction deprecate(msg, fn) {\n    var firstTime = true;\n\n    return extend(function () {\n        if (hooks.deprecationHandler != null) {\n            hooks.deprecationHandler(null, msg);\n        }\n        if (firstTime) {\n            var args = [];\n            var arg;\n            for (var i = 0; i < arguments.length; i++) {\n                arg = '';\n                if (typeof arguments[i] === 'object') {\n                    arg += '\\n[' + i + '] ';\n                    for (var key in arguments[0]) {\n                        arg += key + ': ' + arguments[0][key] + ', ';\n                    }\n                    arg = arg.slice(0, -2); // Remove trailing comma and space\n                } else {\n                    arg = arguments[i];\n                }\n                args.push(arg);\n            }\n            warn(msg + '\\nArguments: ' + Array.prototype.slice.call(args).join('') + '\\n' + (new Error()).stack);\n            firstTime = false;\n        }\n        return fn.apply(this, arguments);\n    }, fn);\n}\n\nvar deprecations = {};\n\nfunction deprecateSimple(name, msg) {\n    if (hooks.deprecationHandler != null) {\n        hooks.deprecationHandler(name, msg);\n    }\n    if (!deprecations[name]) {\n        warn(msg);\n        deprecations[name] = true;\n    }\n}\n\nhooks.suppressDeprecationWarnings = false;\nhooks.deprecationHandler = null;\n\nfunction isFunction(input) {\n    return input instanceof Function || Object.prototype.toString.call(input) === '[object Function]';\n}\n\nfunction set (config) {\n    var prop, i;\n    for (i in config) {\n        prop = config[i];\n        if (isFunction(prop)) {\n            this[i] = prop;\n        } else {\n            this['_' + i] = prop;\n        }\n    }\n    this._config = config;\n    // Lenient ordinal parsing accepts just a number in addition to\n    // number + (possibly) stuff coming from _dayOfMonthOrdinalParse.\n    // TODO: Remove \"ordinalParse\" fallback in next major release.\n    this._dayOfMonthOrdinalParseLenient = new RegExp(\n        (this._dayOfMonthOrdinalParse.source || this._ordinalParse.source) +\n            '|' + (/\\d{1,2}/).source);\n}\n\nfunction mergeConfigs(parentConfig, childConfig) {\n    var res = extend({}, parentConfig), prop;\n    for (prop in childConfig) {\n        if (hasOwnProp(childConfig, prop)) {\n            if (isObject(parentConfig[prop]) && isObject(childConfig[prop])) {\n                res[prop] = {};\n                extend(res[prop], parentConfig[prop]);\n                extend(res[prop], childConfig[prop]);\n            } else if (childConfig[prop] != null) {\n                res[prop] = childConfig[prop];\n            } else {\n                delete res[prop];\n            }\n        }\n    }\n    for (prop in parentConfig) {\n        if (hasOwnProp(parentConfig, prop) &&\n                !hasOwnProp(childConfig, prop) &&\n                isObject(parentConfig[prop])) {\n            // make sure changes to properties don't modify parent config\n            res[prop] = extend({}, res[prop]);\n        }\n    }\n    return res;\n}\n\nfunction Locale(config) {\n    if (config != null) {\n        this.set(config);\n    }\n}\n\nvar keys;\n\nif (Object.keys) {\n    keys = Object.keys;\n} else {\n    keys = function (obj) {\n        var i, res = [];\n        for (i in obj) {\n            if (hasOwnProp(obj, i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    };\n}\n\nvar keys$1 = keys;\n\nvar defaultCalendar = {\n    sameDay : '[Today at] LT',\n    nextDay : '[Tomorrow at] LT',\n    nextWeek : 'dddd [at] LT',\n    lastDay : '[Yesterday at] LT',\n    lastWeek : '[Last] dddd [at] LT',\n    sameElse : 'L'\n};\n\nfunction calendar (key, mom, now) {\n    var output = this._calendar[key] || this._calendar['sameElse'];\n    return isFunction(output) ? output.call(mom, now) : output;\n}\n\nvar defaultLongDateFormat = {\n    LTS  : 'h:mm:ss A',\n    LT   : 'h:mm A',\n    L    : 'MM/DD/YYYY',\n    LL   : 'MMMM D, YYYY',\n    LLL  : 'MMMM D, YYYY h:mm A',\n    LLLL : 'dddd, MMMM D, YYYY h:mm A'\n};\n\nfunction longDateFormat (key) {\n    var format = this._longDateFormat[key],\n        formatUpper = this._longDateFormat[key.toUpperCase()];\n\n    if (format || !formatUpper) {\n        return format;\n    }\n\n    this._longDateFormat[key] = formatUpper.replace(/MMMM|MM|DD|dddd/g, function (val) {\n        return val.slice(1);\n    });\n\n    return this._longDateFormat[key];\n}\n\nvar defaultInvalidDate = 'Invalid date';\n\nfunction invalidDate () {\n    return this._invalidDate;\n}\n\nvar defaultOrdinal = '%d';\nvar defaultDayOfMonthOrdinalParse = /\\d{1,2}/;\n\nfunction ordinal (number) {\n    return this._ordinal.replace('%d', number);\n}\n\nvar defaultRelativeTime = {\n    future : 'in %s',\n    past   : '%s ago',\n    s  : 'a few seconds',\n    ss : '%d seconds',\n    m  : 'a minute',\n    mm : '%d minutes',\n    h  : 'an hour',\n    hh : '%d hours',\n    d  : 'a day',\n    dd : '%d days',\n    M  : 'a month',\n    MM : '%d months',\n    y  : 'a year',\n    yy : '%d years'\n};\n\nfunction relativeTime (number, withoutSuffix, string, isFuture) {\n    var output = this._relativeTime[string];\n    return (isFunction(output)) ?\n        output(number, withoutSuffix, string, isFuture) :\n        output.replace(/%d/i, number);\n}\n\nfunction pastFuture (diff, output) {\n    var format = this._relativeTime[diff > 0 ? 'future' : 'past'];\n    return isFunction(format) ? format(output) : format.replace(/%s/i, output);\n}\n\nvar aliases = {};\n\nfunction addUnitAlias (unit, shorthand) {\n    var lowerCase = unit.toLowerCase();\n    aliases[lowerCase] = aliases[lowerCase + 's'] = aliases[shorthand] = unit;\n}\n\nfunction normalizeUnits(units) {\n    return typeof units === 'string' ? aliases[units] || aliases[units.toLowerCase()] : undefined;\n}\n\nfunction normalizeObjectUnits(inputObject) {\n    var normalizedInput = {},\n        normalizedProp,\n        prop;\n\n    for (prop in inputObject) {\n        if (hasOwnProp(inputObject, prop)) {\n            normalizedProp = normalizeUnits(prop);\n            if (normalizedProp) {\n                normalizedInput[normalizedProp] = inputObject[prop];\n            }\n        }\n    }\n\n    return normalizedInput;\n}\n\nvar priorities = {};\n\nfunction addUnitPriority(unit, priority) {\n    priorities[unit] = priority;\n}\n\nfunction getPrioritizedUnits(unitsObj) {\n    var units = [];\n    for (var u in unitsObj) {\n        units.push({unit: u, priority: priorities[u]});\n    }\n    units.sort(function (a, b) {\n        return a.priority - b.priority;\n    });\n    return units;\n}\n\nfunction makeGetSet (unit, keepTime) {\n    return function (value) {\n        if (value != null) {\n            set$1(this, unit, value);\n            hooks.updateOffset(this, keepTime);\n            return this;\n        } else {\n            return get(this, unit);\n        }\n    };\n}\n\nfunction get (mom, unit) {\n    return mom.isValid() ?\n        mom._d['get' + (mom._isUTC ? 'UTC' : '') + unit]() : NaN;\n}\n\nfunction set$1 (mom, unit, value) {\n    if (mom.isValid()) {\n        mom._d['set' + (mom._isUTC ? 'UTC' : '') + unit](value);\n    }\n}\n\n// MOMENTS\n\nfunction stringGet (units) {\n    units = normalizeUnits(units);\n    if (isFunction(this[units])) {\n        return this[units]();\n    }\n    return this;\n}\n\n\nfunction stringSet (units, value) {\n    if (typeof units === 'object') {\n        units = normalizeObjectUnits(units);\n        var prioritized = getPrioritizedUnits(units);\n        for (var i = 0; i < prioritized.length; i++) {\n            this[prioritized[i].unit](units[prioritized[i].unit]);\n        }\n    } else {\n        units = normalizeUnits(units);\n        if (isFunction(this[units])) {\n            return this[units](value);\n        }\n    }\n    return this;\n}\n\nfunction zeroFill(number, targetLength, forceSign) {\n    var absNumber = '' + Math.abs(number),\n        zerosToFill = targetLength - absNumber.length,\n        sign = number >= 0;\n    return (sign ? (forceSign ? '+' : '') : '-') +\n        Math.pow(10, Math.max(0, zerosToFill)).toString().substr(1) + absNumber;\n}\n\nvar formattingTokens = /(\\[[^\\[]*\\])|(\\\\)?([Hh]mm(ss)?|Mo|MM?M?M?|Do|DDDo|DD?D?D?|ddd?d?|do?|w[o|w]?|W[o|W]?|Qo?|YYYYYY|YYYYY|YYYY|YY|gg(ggg?)?|GG(GGG?)?|e|E|a|A|hh?|HH?|kk?|mm?|ss?|S{1,9}|x|X|zz?|ZZ?|.)/g;\n\nvar localFormattingTokens = /(\\[[^\\[]*\\])|(\\\\)?(LTS|LT|LL?L?L?|l{1,4})/g;\n\nvar formatFunctions = {};\n\nvar formatTokenFunctions = {};\n\n// token:    'M'\n// padded:   ['MM', 2]\n// ordinal:  'Mo'\n// callback: function () { this.month() + 1 }\nfunction addFormatToken (token, padded, ordinal, callback) {\n    var func = callback;\n    if (typeof callback === 'string') {\n        func = function () {\n            return this[callback]();\n        };\n    }\n    if (token) {\n        formatTokenFunctions[token] = func;\n    }\n    if (padded) {\n        formatTokenFunctions[padded[0]] = function () {\n            return zeroFill(func.apply(this, arguments), padded[1], padded[2]);\n        };\n    }\n    if (ordinal) {\n        formatTokenFunctions[ordinal] = function () {\n            return this.localeData().ordinal(func.apply(this, arguments), token);\n        };\n    }\n}\n\nfunction removeFormattingTokens(input) {\n    if (input.match(/\\[[\\s\\S]/)) {\n        return input.replace(/^\\[|\\]$/g, '');\n    }\n    return input.replace(/\\\\/g, '');\n}\n\nfunction makeFormatFunction(format) {\n    var array = format.match(formattingTokens), i, length;\n\n    for (i = 0, length = array.length; i < length; i++) {\n        if (formatTokenFunctions[array[i]]) {\n            array[i] = formatTokenFunctions[array[i]];\n        } else {\n            array[i] = removeFormattingTokens(array[i]);\n        }\n    }\n\n    return function (mom) {\n        var output = '', i;\n        for (i = 0; i < length; i++) {\n            output += isFunction(array[i]) ? array[i].call(mom, format) : array[i];\n        }\n        return output;\n    };\n}\n\n// format date using native date object\nfunction formatMoment(m, format) {\n    if (!m.isValid()) {\n        return m.localeData().invalidDate();\n    }\n\n    format = expandFormat(format, m.localeData());\n    formatFunctions[format] = formatFunctions[format] || makeFormatFunction(format);\n\n    return formatFunctions[format](m);\n}\n\nfunction expandFormat(format, locale) {\n    var i = 5;\n\n    function replaceLongDateFormatTokens(input) {\n        return locale.longDateFormat(input) || input;\n    }\n\n    localFormattingTokens.lastIndex = 0;\n    while (i >= 0 && localFormattingTokens.test(format)) {\n        format = format.replace(localFormattingTokens, replaceLongDateFormatTokens);\n        localFormattingTokens.lastIndex = 0;\n        i -= 1;\n    }\n\n    return format;\n}\n\nvar match1         = /\\d/;            //       0 - 9\nvar match2         = /\\d\\d/;          //      00 - 99\nvar match3         = /\\d{3}/;         //     000 - 999\nvar match4         = /\\d{4}/;         //    0000 - 9999\nvar match6         = /[+-]?\\d{6}/;    // -999999 - 999999\nvar match1to2      = /\\d\\d?/;         //       0 - 99\nvar match3to4      = /\\d\\d\\d\\d?/;     //     999 - 9999\nvar match5to6      = /\\d\\d\\d\\d\\d\\d?/; //   99999 - 999999\nvar match1to3      = /\\d{1,3}/;       //       0 - 999\nvar match1to4      = /\\d{1,4}/;       //       0 - 9999\nvar match1to6      = /[+-]?\\d{1,6}/;  // -999999 - 999999\n\nvar matchUnsigned  = /\\d+/;           //       0 - inf\nvar matchSigned    = /[+-]?\\d+/;      //    -inf - inf\n\nvar matchOffset    = /Z|[+-]\\d\\d:?\\d\\d/gi; // +00:00 -00:00 +0000 -0000 or Z\nvar matchShortOffset = /Z|[+-]\\d\\d(?::?\\d\\d)?/gi; // +00 -00 +00:00 -00:00 +0000 -0000 or Z\n\nvar matchTimestamp = /[+-]?\\d+(\\.\\d{1,3})?/; // 123456789 123456789.123\n\n// any word (or two) characters or numbers including two/three word month in arabic.\n// includes scottish gaelic two word and hyphenated months\nvar matchWord = /[0-9]*['a-z\\u00A0-\\u05FF\\u0700-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF]+|[\\u0600-\\u06FF\\/]+(\\s*?[\\u0600-\\u06FF]+){1,2}/i;\n\n\nvar regexes = {};\n\nfunction addRegexToken (token, regex, strictRegex) {\n    regexes[token] = isFunction(regex) ? regex : function (isStrict, localeData) {\n        return (isStrict && strictRegex) ? strictRegex : regex;\n    };\n}\n\nfunction getParseRegexForToken (token, config) {\n    if (!hasOwnProp(regexes, token)) {\n        return new RegExp(unescapeFormat(token));\n    }\n\n    return regexes[token](config._strict, config._locale);\n}\n\n// Code from http://stackoverflow.com/questions/3561493/is-there-a-regexp-escape-function-in-javascript\nfunction unescapeFormat(s) {\n    return regexEscape(s.replace('\\\\', '').replace(/\\\\(\\[)|\\\\(\\])|\\[([^\\]\\[]*)\\]|\\\\(.)/g, function (matched, p1, p2, p3, p4) {\n        return p1 || p2 || p3 || p4;\n    }));\n}\n\nfunction regexEscape(s) {\n    return s.replace(/[-\\/\\\\^$*+?.()|[\\]{}]/g, '\\\\$&');\n}\n\nvar tokens = {};\n\nfunction addParseToken (token, callback) {\n    var i, func = callback;\n    if (typeof token === 'string') {\n        token = [token];\n    }\n    if (isNumber(callback)) {\n        func = function (input, array) {\n            array[callback] = toInt(input);\n        };\n    }\n    for (i = 0; i < token.length; i++) {\n        tokens[token[i]] = func;\n    }\n}\n\nfunction addWeekParseToken (token, callback) {\n    addParseToken(token, function (input, array, config, token) {\n        config._w = config._w || {};\n        callback(input, config._w, config, token);\n    });\n}\n\nfunction addTimeToArrayFromToken(token, input, config) {\n    if (input != null && hasOwnProp(tokens, token)) {\n        tokens[token](input, config._a, config, token);\n    }\n}\n\nvar YEAR = 0;\nvar MONTH = 1;\nvar DATE = 2;\nvar HOUR = 3;\nvar MINUTE = 4;\nvar SECOND = 5;\nvar MILLISECOND = 6;\nvar WEEK = 7;\nvar WEEKDAY = 8;\n\nvar indexOf;\n\nif (Array.prototype.indexOf) {\n    indexOf = Array.prototype.indexOf;\n} else {\n    indexOf = function (o) {\n        // I know\n        var i;\n        for (i = 0; i < this.length; ++i) {\n            if (this[i] === o) {\n                return i;\n            }\n        }\n        return -1;\n    };\n}\n\nvar indexOf$1 = indexOf;\n\nfunction daysInMonth(year, month) {\n    return new Date(Date.UTC(year, month + 1, 0)).getUTCDate();\n}\n\n// FORMATTING\n\naddFormatToken('M', ['MM', 2], 'Mo', function () {\n    return this.month() + 1;\n});\n\naddFormatToken('MMM', 0, 0, function (format) {\n    return this.localeData().monthsShort(this, format);\n});\n\naddFormatToken('MMMM', 0, 0, function (format) {\n    return this.localeData().months(this, format);\n});\n\n// ALIASES\n\naddUnitAlias('month', 'M');\n\n// PRIORITY\n\naddUnitPriority('month', 8);\n\n// PARSING\n\naddRegexToken('M',    match1to2);\naddRegexToken('MM',   match1to2, match2);\naddRegexToken('MMM',  function (isStrict, locale) {\n    return locale.monthsShortRegex(isStrict);\n});\naddRegexToken('MMMM', function (isStrict, locale) {\n    return locale.monthsRegex(isStrict);\n});\n\naddParseToken(['M', 'MM'], function (input, array) {\n    array[MONTH] = toInt(input) - 1;\n});\n\naddParseToken(['MMM', 'MMMM'], function (input, array, config, token) {\n    var month = config._locale.monthsParse(input, token, config._strict);\n    // if we didn't find a month name, mark the date as invalid.\n    if (month != null) {\n        array[MONTH] = month;\n    } else {\n        getParsingFlags(config).invalidMonth = input;\n    }\n});\n\n// LOCALES\n\nvar MONTHS_IN_FORMAT = /D[oD]?(\\[[^\\[\\]]*\\]|\\s)+MMMM?/;\nvar defaultLocaleMonths = 'January_February_March_April_May_June_July_August_September_October_November_December'.split('_');\nfunction localeMonths (m, format) {\n    if (!m) {\n        return isArray(this._months) ? this._months :\n            this._months['standalone'];\n    }\n    return isArray(this._months) ? this._months[m.month()] :\n        this._months[(this._months.isFormat || MONTHS_IN_FORMAT).test(format) ? 'format' : 'standalone'][m.month()];\n}\n\nvar defaultLocaleMonthsShort = 'Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec'.split('_');\nfunction localeMonthsShort (m, format) {\n    if (!m) {\n        return isArray(this._monthsShort) ? this._monthsShort :\n            this._monthsShort['standalone'];\n    }\n    return isArray(this._monthsShort) ? this._monthsShort[m.month()] :\n        this._monthsShort[MONTHS_IN_FORMAT.test(format) ? 'format' : 'standalone'][m.month()];\n}\n\nfunction handleStrictParse(monthName, format, strict) {\n    var i, ii, mom, llc = monthName.toLocaleLowerCase();\n    if (!this._monthsParse) {\n        // this is not used\n        this._monthsParse = [];\n        this._longMonthsParse = [];\n        this._shortMonthsParse = [];\n        for (i = 0; i < 12; ++i) {\n            mom = createUTC([2000, i]);\n            this._shortMonthsParse[i] = this.monthsShort(mom, '').toLocaleLowerCase();\n            this._longMonthsParse[i] = this.months(mom, '').toLocaleLowerCase();\n        }\n    }\n\n    if (strict) {\n        if (format === 'MMM') {\n            ii = indexOf$1.call(this._shortMonthsParse, llc);\n            return ii !== -1 ? ii : null;\n        } else {\n            ii = indexOf$1.call(this._longMonthsParse, llc);\n            return ii !== -1 ? ii : null;\n        }\n    } else {\n        if (format === 'MMM') {\n            ii = indexOf$1.call(this._shortMonthsParse, llc);\n            if (ii !== -1) {\n                return ii;\n            }\n            ii = indexOf$1.call(this._longMonthsParse, llc);\n            return ii !== -1 ? ii : null;\n        } else {\n            ii = indexOf$1.call(this._longMonthsParse, llc);\n            if (ii !== -1) {\n                return ii;\n            }\n            ii = indexOf$1.call(this._shortMonthsParse, llc);\n            return ii !== -1 ? ii : null;\n        }\n    }\n}\n\nfunction localeMonthsParse (monthName, format, strict) {\n    var i, mom, regex;\n\n    if (this._monthsParseExact) {\n        return handleStrictParse.call(this, monthName, format, strict);\n    }\n\n    if (!this._monthsParse) {\n        this._monthsParse = [];\n        this._longMonthsParse = [];\n        this._shortMonthsParse = [];\n    }\n\n    // TODO: add sorting\n    // Sorting makes sure if one month (or abbr) is a prefix of another\n    // see sorting in computeMonthsParse\n    for (i = 0; i < 12; i++) {\n        // make the regex if we don't have it already\n        mom = createUTC([2000, i]);\n        if (strict && !this._longMonthsParse[i]) {\n            this._longMonthsParse[i] = new RegExp('^' + this.months(mom, '').replace('.', '') + '$', 'i');\n            this._shortMonthsParse[i] = new RegExp('^' + this.monthsShort(mom, '').replace('.', '') + '$', 'i');\n        }\n        if (!strict && !this._monthsParse[i]) {\n            regex = '^' + this.months(mom, '') + '|^' + this.monthsShort(mom, '');\n            this._monthsParse[i] = new RegExp(regex.replace('.', ''), 'i');\n        }\n        // test the regex\n        if (strict && format === 'MMMM' && this._longMonthsParse[i].test(monthName)) {\n            return i;\n        } else if (strict && format === 'MMM' && this._shortMonthsParse[i].test(monthName)) {\n            return i;\n        } else if (!strict && this._monthsParse[i].test(monthName)) {\n            return i;\n        }\n    }\n}\n\n// MOMENTS\n\nfunction setMonth (mom, value) {\n    var dayOfMonth;\n\n    if (!mom.isValid()) {\n        // No op\n        return mom;\n    }\n\n    if (typeof value === 'string') {\n        if (/^\\d+$/.test(value)) {\n            value = toInt(value);\n        } else {\n            value = mom.localeData().monthsParse(value);\n            // TODO: Another silent failure?\n            if (!isNumber(value)) {\n                return mom;\n            }\n        }\n    }\n\n    dayOfMonth = Math.min(mom.date(), daysInMonth(mom.year(), value));\n    mom._d['set' + (mom._isUTC ? 'UTC' : '') + 'Month'](value, dayOfMonth);\n    return mom;\n}\n\nfunction getSetMonth (value) {\n    if (value != null) {\n        setMonth(this, value);\n        hooks.updateOffset(this, true);\n        return this;\n    } else {\n        return get(this, 'Month');\n    }\n}\n\nfunction getDaysInMonth () {\n    return daysInMonth(this.year(), this.month());\n}\n\nvar defaultMonthsShortRegex = matchWord;\nfunction monthsShortRegex (isStrict) {\n    if (this._monthsParseExact) {\n        if (!hasOwnProp(this, '_monthsRegex')) {\n            computeMonthsParse.call(this);\n        }\n        if (isStrict) {\n            return this._monthsShortStrictRegex;\n        } else {\n            return this._monthsShortRegex;\n        }\n    } else {\n        if (!hasOwnProp(this, '_monthsShortRegex')) {\n            this._monthsShortRegex = defaultMonthsShortRegex;\n        }\n        return this._monthsShortStrictRegex && isStrict ?\n            this._monthsShortStrictRegex : this._monthsShortRegex;\n    }\n}\n\nvar defaultMonthsRegex = matchWord;\nfunction monthsRegex (isStrict) {\n    if (this._monthsParseExact) {\n        if (!hasOwnProp(this, '_monthsRegex')) {\n            computeMonthsParse.call(this);\n        }\n        if (isStrict) {\n            return this._monthsStrictRegex;\n        } else {\n            return this._monthsRegex;\n        }\n    } else {\n        if (!hasOwnProp(this, '_monthsRegex')) {\n            this._monthsRegex = defaultMonthsRegex;\n        }\n        return this._monthsStrictRegex && isStrict ?\n            this._monthsStrictRegex : this._monthsRegex;\n    }\n}\n\nfunction computeMonthsParse () {\n    function cmpLenRev(a, b) {\n        return b.length - a.length;\n    }\n\n    var shortPieces = [], longPieces = [], mixedPieces = [],\n        i, mom;\n    for (i = 0; i < 12; i++) {\n        // make the regex if we don't have it already\n        mom = createUTC([2000, i]);\n        shortPieces.push(this.monthsShort(mom, ''));\n        longPieces.push(this.months(mom, ''));\n        mixedPieces.push(this.months(mom, ''));\n        mixedPieces.push(this.monthsShort(mom, ''));\n    }\n    // Sorting makes sure if one month (or abbr) is a prefix of another it\n    // will match the longer piece.\n    shortPieces.sort(cmpLenRev);\n    longPieces.sort(cmpLenRev);\n    mixedPieces.sort(cmpLenRev);\n    for (i = 0; i < 12; i++) {\n        shortPieces[i] = regexEscape(shortPieces[i]);\n        longPieces[i] = regexEscape(longPieces[i]);\n    }\n    for (i = 0; i < 24; i++) {\n        mixedPieces[i] = regexEscape(mixedPieces[i]);\n    }\n\n    this._monthsRegex = new RegExp('^(' + mixedPieces.join('|') + ')', 'i');\n    this._monthsShortRegex = this._monthsRegex;\n    this._monthsStrictRegex = new RegExp('^(' + longPieces.join('|') + ')', 'i');\n    this._monthsShortStrictRegex = new RegExp('^(' + shortPieces.join('|') + ')', 'i');\n}\n\n// FORMATTING\n\naddFormatToken('Y', 0, 0, function () {\n    var y = this.year();\n    return y <= 9999 ? '' + y : '+' + y;\n});\n\naddFormatToken(0, ['YY', 2], 0, function () {\n    return this.year() % 100;\n});\n\naddFormatToken(0, ['YYYY',   4],       0, 'year');\naddFormatToken(0, ['YYYYY',  5],       0, 'year');\naddFormatToken(0, ['YYYYYY', 6, true], 0, 'year');\n\n// ALIASES\n\naddUnitAlias('year', 'y');\n\n// PRIORITIES\n\naddUnitPriority('year', 1);\n\n// PARSING\n\naddRegexToken('Y',      matchSigned);\naddRegexToken('YY',     match1to2, match2);\naddRegexToken('YYYY',   match1to4, match4);\naddRegexToken('YYYYY',  match1to6, match6);\naddRegexToken('YYYYYY', match1to6, match6);\n\naddParseToken(['YYYYY', 'YYYYYY'], YEAR);\naddParseToken('YYYY', function (input, array) {\n    array[YEAR] = input.length === 2 ? hooks.parseTwoDigitYear(input) : toInt(input);\n});\naddParseToken('YY', function (input, array) {\n    array[YEAR] = hooks.parseTwoDigitYear(input);\n});\naddParseToken('Y', function (input, array) {\n    array[YEAR] = parseInt(input, 10);\n});\n\n// HELPERS\n\nfunction daysInYear(year) {\n    return isLeapYear(year) ? 366 : 365;\n}\n\nfunction isLeapYear(year) {\n    return (year % 4 === 0 && year % 100 !== 0) || year % 400 === 0;\n}\n\n// HOOKS\n\nhooks.parseTwoDigitYear = function (input) {\n    return toInt(input) + (toInt(input) > 68 ? 1900 : 2000);\n};\n\n// MOMENTS\n\nvar getSetYear = makeGetSet('FullYear', true);\n\nfunction getIsLeapYear () {\n    return isLeapYear(this.year());\n}\n\nfunction createDate (y, m, d, h, M, s, ms) {\n    // can't just apply() to create a date:\n    // https://stackoverflow.com/q/181348\n    var date = new Date(y, m, d, h, M, s, ms);\n\n    // the date constructor remaps years 0-99 to 1900-1999\n    if (y < 100 && y >= 0 && isFinite(date.getFullYear())) {\n        date.setFullYear(y);\n    }\n    return date;\n}\n\nfunction createUTCDate (y) {\n    var date = new Date(Date.UTC.apply(null, arguments));\n\n    // the Date.UTC function remaps years 0-99 to 1900-1999\n    if (y < 100 && y >= 0 && isFinite(date.getUTCFullYear())) {\n        date.setUTCFullYear(y);\n    }\n    return date;\n}\n\n// start-of-first-week - start-of-year\nfunction firstWeekOffset(year, dow, doy) {\n    var // first-week day -- which january is always in the first week (4 for iso, 1 for other)\n        fwd = 7 + dow - doy,\n        // first-week day local weekday -- which local weekday is fwd\n        fwdlw = (7 + createUTCDate(year, 0, fwd).getUTCDay() - dow) % 7;\n\n    return -fwdlw + fwd - 1;\n}\n\n// https://en.wikipedia.org/wiki/ISO_week_date#Calculating_a_date_given_the_year.2C_week_number_and_weekday\nfunction dayOfYearFromWeeks(year, week, weekday, dow, doy) {\n    var localWeekday = (7 + weekday - dow) % 7,\n        weekOffset = firstWeekOffset(year, dow, doy),\n        dayOfYear = 1 + 7 * (week - 1) + localWeekday + weekOffset,\n        resYear, resDayOfYear;\n\n    if (dayOfYear <= 0) {\n        resYear = year - 1;\n        resDayOfYear = daysInYear(resYear) + dayOfYear;\n    } else if (dayOfYear > daysInYear(year)) {\n        resYear = year + 1;\n        resDayOfYear = dayOfYear - daysInYear(year);\n    } else {\n        resYear = year;\n        resDayOfYear = dayOfYear;\n    }\n\n    return {\n        year: resYear,\n        dayOfYear: resDayOfYear\n    };\n}\n\nfunction weekOfYear(mom, dow, doy) {\n    var weekOffset = firstWeekOffset(mom.year(), dow, doy),\n        week = Math.floor((mom.dayOfYear() - weekOffset - 1) / 7) + 1,\n        resWeek, resYear;\n\n    if (week < 1) {\n        resYear = mom.year() - 1;\n        resWeek = week + weeksInYear(resYear, dow, doy);\n    } else if (week > weeksInYear(mom.year(), dow, doy)) {\n        resWeek = week - weeksInYear(mom.year(), dow, doy);\n        resYear = mom.year() + 1;\n    } else {\n        resYear = mom.year();\n        resWeek = week;\n    }\n\n    return {\n        week: resWeek,\n        year: resYear\n    };\n}\n\nfunction weeksInYear(year, dow, doy) {\n    var weekOffset = firstWeekOffset(year, dow, doy),\n        weekOffsetNext = firstWeekOffset(year + 1, dow, doy);\n    return (daysInYear(year) - weekOffset + weekOffsetNext) / 7;\n}\n\n// FORMATTING\n\naddFormatToken('w', ['ww', 2], 'wo', 'week');\naddFormatToken('W', ['WW', 2], 'Wo', 'isoWeek');\n\n// ALIASES\n\naddUnitAlias('week', 'w');\naddUnitAlias('isoWeek', 'W');\n\n// PRIORITIES\n\naddUnitPriority('week', 5);\naddUnitPriority('isoWeek', 5);\n\n// PARSING\n\naddRegexToken('w',  match1to2);\naddRegexToken('ww', match1to2, match2);\naddRegexToken('W',  match1to2);\naddRegexToken('WW', match1to2, match2);\n\naddWeekParseToken(['w', 'ww', 'W', 'WW'], function (input, week, config, token) {\n    week[token.substr(0, 1)] = toInt(input);\n});\n\n// HELPERS\n\n// LOCALES\n\nfunction localeWeek (mom) {\n    return weekOfYear(mom, this._week.dow, this._week.doy).week;\n}\n\nvar defaultLocaleWeek = {\n    dow : 0, // Sunday is the first day of the week.\n    doy : 6  // The week that contains Jan 1st is the first week of the year.\n};\n\nfunction localeFirstDayOfWeek () {\n    return this._week.dow;\n}\n\nfunction localeFirstDayOfYear () {\n    return this._week.doy;\n}\n\n// MOMENTS\n\nfunction getSetWeek (input) {\n    var week = this.localeData().week(this);\n    return input == null ? week : this.add((input - week) * 7, 'd');\n}\n\nfunction getSetISOWeek (input) {\n    var week = weekOfYear(this, 1, 4).week;\n    return input == null ? week : this.add((input - week) * 7, 'd');\n}\n\n// FORMATTING\n\naddFormatToken('d', 0, 'do', 'day');\n\naddFormatToken('dd', 0, 0, function (format) {\n    return this.localeData().weekdaysMin(this, format);\n});\n\naddFormatToken('ddd', 0, 0, function (format) {\n    return this.localeData().weekdaysShort(this, format);\n});\n\naddFormatToken('dddd', 0, 0, function (format) {\n    return this.localeData().weekdays(this, format);\n});\n\naddFormatToken('e', 0, 0, 'weekday');\naddFormatToken('E', 0, 0, 'isoWeekday');\n\n// ALIASES\n\naddUnitAlias('day', 'd');\naddUnitAlias('weekday', 'e');\naddUnitAlias('isoWeekday', 'E');\n\n// PRIORITY\naddUnitPriority('day', 11);\naddUnitPriority('weekday', 11);\naddUnitPriority('isoWeekday', 11);\n\n// PARSING\n\naddRegexToken('d',    match1to2);\naddRegexToken('e',    match1to2);\naddRegexToken('E',    match1to2);\naddRegexToken('dd',   function (isStrict, locale) {\n    return locale.weekdaysMinRegex(isStrict);\n});\naddRegexToken('ddd',   function (isStrict, locale) {\n    return locale.weekdaysShortRegex(isStrict);\n});\naddRegexToken('dddd',   function (isStrict, locale) {\n    return locale.weekdaysRegex(isStrict);\n});\n\naddWeekParseToken(['dd', 'ddd', 'dddd'], function (input, week, config, token) {\n    var weekday = config._locale.weekdaysParse(input, token, config._strict);\n    // if we didn't get a weekday name, mark the date as invalid\n    if (weekday != null) {\n        week.d = weekday;\n    } else {\n        getParsingFlags(config).invalidWeekday = input;\n    }\n});\n\naddWeekParseToken(['d', 'e', 'E'], function (input, week, config, token) {\n    week[token] = toInt(input);\n});\n\n// HELPERS\n\nfunction parseWeekday(input, locale) {\n    if (typeof input !== 'string') {\n        return input;\n    }\n\n    if (!isNaN(input)) {\n        return parseInt(input, 10);\n    }\n\n    input = locale.weekdaysParse(input);\n    if (typeof input === 'number') {\n        return input;\n    }\n\n    return null;\n}\n\nfunction parseIsoWeekday(input, locale) {\n    if (typeof input === 'string') {\n        return locale.weekdaysParse(input) % 7 || 7;\n    }\n    return isNaN(input) ? null : input;\n}\n\n// LOCALES\n\nvar defaultLocaleWeekdays = 'Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday'.split('_');\nfunction localeWeekdays (m, format) {\n    if (!m) {\n        return isArray(this._weekdays) ? this._weekdays :\n            this._weekdays['standalone'];\n    }\n    return isArray(this._weekdays) ? this._weekdays[m.day()] :\n        this._weekdays[this._weekdays.isFormat.test(format) ? 'format' : 'standalone'][m.day()];\n}\n\nvar defaultLocaleWeekdaysShort = 'Sun_Mon_Tue_Wed_Thu_Fri_Sat'.split('_');\nfunction localeWeekdaysShort (m) {\n    return (m) ? this._weekdaysShort[m.day()] : this._weekdaysShort;\n}\n\nvar defaultLocaleWeekdaysMin = 'Su_Mo_Tu_We_Th_Fr_Sa'.split('_');\nfunction localeWeekdaysMin (m) {\n    return (m) ? this._weekdaysMin[m.day()] : this._weekdaysMin;\n}\n\nfunction handleStrictParse$1(weekdayName, format, strict) {\n    var i, ii, mom, llc = weekdayName.toLocaleLowerCase();\n    if (!this._weekdaysParse) {\n        this._weekdaysParse = [];\n        this._shortWeekdaysParse = [];\n        this._minWeekdaysParse = [];\n\n        for (i = 0; i < 7; ++i) {\n            mom = createUTC([2000, 1]).day(i);\n            this._minWeekdaysParse[i] = this.weekdaysMin(mom, '').toLocaleLowerCase();\n            this._shortWeekdaysParse[i] = this.weekdaysShort(mom, '').toLocaleLowerCase();\n            this._weekdaysParse[i] = this.weekdays(mom, '').toLocaleLowerCase();\n        }\n    }\n\n    if (strict) {\n        if (format === 'dddd') {\n            ii = indexOf$1.call(this._weekdaysParse, llc);\n            return ii !== -1 ? ii : null;\n        } else if (format === 'ddd') {\n            ii = indexOf$1.call(this._shortWeekdaysParse, llc);\n            return ii !== -1 ? ii : null;\n        } else {\n            ii = indexOf$1.call(this._minWeekdaysParse, llc);\n            return ii !== -1 ? ii : null;\n        }\n    } else {\n        if (format === 'dddd') {\n            ii = indexOf$1.call(this._weekdaysParse, llc);\n            if (ii !== -1) {\n                return ii;\n            }\n            ii = indexOf$1.call(this._shortWeekdaysParse, llc);\n            if (ii !== -1) {\n                return ii;\n            }\n            ii = indexOf$1.call(this._minWeekdaysParse, llc);\n            return ii !== -1 ? ii : null;\n        } else if (format === 'ddd') {\n            ii = indexOf$1.call(this._shortWeekdaysParse, llc);\n            if (ii !== -1) {\n                return ii;\n            }\n            ii = indexOf$1.call(this._weekdaysParse, llc);\n            if (ii !== -1) {\n                return ii;\n            }\n            ii = indexOf$1.call(this._minWeekdaysParse, llc);\n            return ii !== -1 ? ii : null;\n        } else {\n            ii = indexOf$1.call(this._minWeekdaysParse, llc);\n            if (ii !== -1) {\n                return ii;\n            }\n            ii = indexOf$1.call(this._weekdaysParse, llc);\n            if (ii !== -1) {\n                return ii;\n            }\n            ii = indexOf$1.call(this._shortWeekdaysParse, llc);\n            return ii !== -1 ? ii : null;\n        }\n    }\n}\n\nfunction localeWeekdaysParse (weekdayName, format, strict) {\n    var i, mom, regex;\n\n    if (this._weekdaysParseExact) {\n        return handleStrictParse$1.call(this, weekdayName, format, strict);\n    }\n\n    if (!this._weekdaysParse) {\n        this._weekdaysParse = [];\n        this._minWeekdaysParse = [];\n        this._shortWeekdaysParse = [];\n        this._fullWeekdaysParse = [];\n    }\n\n    for (i = 0; i < 7; i++) {\n        // make the regex if we don't have it already\n\n        mom = createUTC([2000, 1]).day(i);\n        if (strict && !this._fullWeekdaysParse[i]) {\n            this._fullWeekdaysParse[i] = new RegExp('^' + this.weekdays(mom, '').replace('.', '\\.?') + '$', 'i');\n            this._shortWeekdaysParse[i] = new RegExp('^' + this.weekdaysShort(mom, '').replace('.', '\\.?') + '$', 'i');\n            this._minWeekdaysParse[i] = new RegExp('^' + this.weekdaysMin(mom, '').replace('.', '\\.?') + '$', 'i');\n        }\n        if (!this._weekdaysParse[i]) {\n            regex = '^' + this.weekdays(mom, '') + '|^' + this.weekdaysShort(mom, '') + '|^' + this.weekdaysMin(mom, '');\n            this._weekdaysParse[i] = new RegExp(regex.replace('.', ''), 'i');\n        }\n        // test the regex\n        if (strict && format === 'dddd' && this._fullWeekdaysParse[i].test(weekdayName)) {\n            return i;\n        } else if (strict && format === 'ddd' && this._shortWeekdaysParse[i].test(weekdayName)) {\n            return i;\n        } else if (strict && format === 'dd' && this._minWeekdaysParse[i].test(weekdayName)) {\n            return i;\n        } else if (!strict && this._weekdaysParse[i].test(weekdayName)) {\n            return i;\n        }\n    }\n}\n\n// MOMENTS\n\nfunction getSetDayOfWeek (input) {\n    if (!this.isValid()) {\n        return input != null ? this : NaN;\n    }\n    var day = this._isUTC ? this._d.getUTCDay() : this._d.getDay();\n    if (input != null) {\n        input = parseWeekday(input, this.localeData());\n        return this.add(input - day, 'd');\n    } else {\n        return day;\n    }\n}\n\nfunction getSetLocaleDayOfWeek (input) {\n    if (!this.isValid()) {\n        return input != null ? this : NaN;\n    }\n    var weekday = (this.day() + 7 - this.localeData()._week.dow) % 7;\n    return input == null ? weekday : this.add(input - weekday, 'd');\n}\n\nfunction getSetISODayOfWeek (input) {\n    if (!this.isValid()) {\n        return input != null ? this : NaN;\n    }\n\n    // behaves the same as moment#day except\n    // as a getter, returns 7 instead of 0 (1-7 range instead of 0-6)\n    // as a setter, sunday should belong to the previous week.\n\n    if (input != null) {\n        var weekday = parseIsoWeekday(input, this.localeData());\n        return this.day(this.day() % 7 ? weekday : weekday - 7);\n    } else {\n        return this.day() || 7;\n    }\n}\n\nvar defaultWeekdaysRegex = matchWord;\nfunction weekdaysRegex (isStrict) {\n    if (this._weekdaysParseExact) {\n        if (!hasOwnProp(this, '_weekdaysRegex')) {\n            computeWeekdaysParse.call(this);\n        }\n        if (isStrict) {\n            return this._weekdaysStrictRegex;\n        } else {\n            return this._weekdaysRegex;\n        }\n    } else {\n        if (!hasOwnProp(this, '_weekdaysRegex')) {\n            this._weekdaysRegex = defaultWeekdaysRegex;\n        }\n        return this._weekdaysStrictRegex && isStrict ?\n            this._weekdaysStrictRegex : this._weekdaysRegex;\n    }\n}\n\nvar defaultWeekdaysShortRegex = matchWord;\nfunction weekdaysShortRegex (isStrict) {\n    if (this._weekdaysParseExact) {\n        if (!hasOwnProp(this, '_weekdaysRegex')) {\n            computeWeekdaysParse.call(this);\n        }\n        if (isStrict) {\n            return this._weekdaysShortStrictRegex;\n        } else {\n            return this._weekdaysShortRegex;\n        }\n    } else {\n        if (!hasOwnProp(this, '_weekdaysShortRegex')) {\n            this._weekdaysShortRegex = defaultWeekdaysShortRegex;\n        }\n        return this._weekdaysShortStrictRegex && isStrict ?\n            this._weekdaysShortStrictRegex : this._weekdaysShortRegex;\n    }\n}\n\nvar defaultWeekdaysMinRegex = matchWord;\nfunction weekdaysMinRegex (isStrict) {\n    if (this._weekdaysParseExact) {\n        if (!hasOwnProp(this, '_weekdaysRegex')) {\n            computeWeekdaysParse.call(this);\n        }\n        if (isStrict) {\n            return this._weekdaysMinStrictRegex;\n        } else {\n            return this._weekdaysMinRegex;\n        }\n    } else {\n        if (!hasOwnProp(this, '_weekdaysMinRegex')) {\n            this._weekdaysMinRegex = defaultWeekdaysMinRegex;\n        }\n        return this._weekdaysMinStrictRegex && isStrict ?\n            this._weekdaysMinStrictRegex : this._weekdaysMinRegex;\n    }\n}\n\n\nfunction computeWeekdaysParse () {\n    function cmpLenRev(a, b) {\n        return b.length - a.length;\n    }\n\n    var minPieces = [], shortPieces = [], longPieces = [], mixedPieces = [],\n        i, mom, minp, shortp, longp;\n    for (i = 0; i < 7; i++) {\n        // make the regex if we don't have it already\n        mom = createUTC([2000, 1]).day(i);\n        minp = this.weekdaysMin(mom, '');\n        shortp = this.weekdaysShort(mom, '');\n        longp = this.weekdays(mom, '');\n        minPieces.push(minp);\n        shortPieces.push(shortp);\n        longPieces.push(longp);\n        mixedPieces.push(minp);\n        mixedPieces.push(shortp);\n        mixedPieces.push(longp);\n    }\n    // Sorting makes sure if one weekday (or abbr) is a prefix of another it\n    // will match the longer piece.\n    minPieces.sort(cmpLenRev);\n    shortPieces.sort(cmpLenRev);\n    longPieces.sort(cmpLenRev);\n    mixedPieces.sort(cmpLenRev);\n    for (i = 0; i < 7; i++) {\n        shortPieces[i] = regexEscape(shortPieces[i]);\n        longPieces[i] = regexEscape(longPieces[i]);\n        mixedPieces[i] = regexEscape(mixedPieces[i]);\n    }\n\n    this._weekdaysRegex = new RegExp('^(' + mixedPieces.join('|') + ')', 'i');\n    this._weekdaysShortRegex = this._weekdaysRegex;\n    this._weekdaysMinRegex = this._weekdaysRegex;\n\n    this._weekdaysStrictRegex = new RegExp('^(' + longPieces.join('|') + ')', 'i');\n    this._weekdaysShortStrictRegex = new RegExp('^(' + shortPieces.join('|') + ')', 'i');\n    this._weekdaysMinStrictRegex = new RegExp('^(' + minPieces.join('|') + ')', 'i');\n}\n\n// FORMATTING\n\nfunction hFormat() {\n    return this.hours() % 12 || 12;\n}\n\nfunction kFormat() {\n    return this.hours() || 24;\n}\n\naddFormatToken('H', ['HH', 2], 0, 'hour');\naddFormatToken('h', ['hh', 2], 0, hFormat);\naddFormatToken('k', ['kk', 2], 0, kFormat);\n\naddFormatToken('hmm', 0, 0, function () {\n    return '' + hFormat.apply(this) + zeroFill(this.minutes(), 2);\n});\n\naddFormatToken('hmmss', 0, 0, function () {\n    return '' + hFormat.apply(this) + zeroFill(this.minutes(), 2) +\n        zeroFill(this.seconds(), 2);\n});\n\naddFormatToken('Hmm', 0, 0, function () {\n    return '' + this.hours() + zeroFill(this.minutes(), 2);\n});\n\naddFormatToken('Hmmss', 0, 0, function () {\n    return '' + this.hours() + zeroFill(this.minutes(), 2) +\n        zeroFill(this.seconds(), 2);\n});\n\nfunction meridiem (token, lowercase) {\n    addFormatToken(token, 0, 0, function () {\n        return this.localeData().meridiem(this.hours(), this.minutes(), lowercase);\n    });\n}\n\nmeridiem('a', true);\nmeridiem('A', false);\n\n// ALIASES\n\naddUnitAlias('hour', 'h');\n\n// PRIORITY\naddUnitPriority('hour', 13);\n\n// PARSING\n\nfunction matchMeridiem (isStrict, locale) {\n    return locale._meridiemParse;\n}\n\naddRegexToken('a',  matchMeridiem);\naddRegexToken('A',  matchMeridiem);\naddRegexToken('H',  match1to2);\naddRegexToken('h',  match1to2);\naddRegexToken('k',  match1to2);\naddRegexToken('HH', match1to2, match2);\naddRegexToken('hh', match1to2, match2);\naddRegexToken('kk', match1to2, match2);\n\naddRegexToken('hmm', match3to4);\naddRegexToken('hmmss', match5to6);\naddRegexToken('Hmm', match3to4);\naddRegexToken('Hmmss', match5to6);\n\naddParseToken(['H', 'HH'], HOUR);\naddParseToken(['k', 'kk'], function (input, array, config) {\n    var kInput = toInt(input);\n    array[HOUR] = kInput === 24 ? 0 : kInput;\n});\naddParseToken(['a', 'A'], function (input, array, config) {\n    config._isPm = config._locale.isPM(input);\n    config._meridiem = input;\n});\naddParseToken(['h', 'hh'], function (input, array, config) {\n    array[HOUR] = toInt(input);\n    getParsingFlags(config).bigHour = true;\n});\naddParseToken('hmm', function (input, array, config) {\n    var pos = input.length - 2;\n    array[HOUR] = toInt(input.substr(0, pos));\n    array[MINUTE] = toInt(input.substr(pos));\n    getParsingFlags(config).bigHour = true;\n});\naddParseToken('hmmss', function (input, array, config) {\n    var pos1 = input.length - 4;\n    var pos2 = input.length - 2;\n    array[HOUR] = toInt(input.substr(0, pos1));\n    array[MINUTE] = toInt(input.substr(pos1, 2));\n    array[SECOND] = toInt(input.substr(pos2));\n    getParsingFlags(config).bigHour = true;\n});\naddParseToken('Hmm', function (input, array, config) {\n    var pos = input.length - 2;\n    array[HOUR] = toInt(input.substr(0, pos));\n    array[MINUTE] = toInt(input.substr(pos));\n});\naddParseToken('Hmmss', function (input, array, config) {\n    var pos1 = input.length - 4;\n    var pos2 = input.length - 2;\n    array[HOUR] = toInt(input.substr(0, pos1));\n    array[MINUTE] = toInt(input.substr(pos1, 2));\n    array[SECOND] = toInt(input.substr(pos2));\n});\n\n// LOCALES\n\nfunction localeIsPM (input) {\n    // IE8 Quirks Mode & IE7 Standards Mode do not allow accessing strings like arrays\n    // Using charAt should be more compatible.\n    return ((input + '').toLowerCase().charAt(0) === 'p');\n}\n\nvar defaultLocaleMeridiemParse = /[ap]\\.?m?\\.?/i;\nfunction localeMeridiem (hours, minutes, isLower) {\n    if (hours > 11) {\n        return isLower ? 'pm' : 'PM';\n    } else {\n        return isLower ? 'am' : 'AM';\n    }\n}\n\n\n// MOMENTS\n\n// Setting the hour should keep the time, because the user explicitly\n// specified which hour he wants. So trying to maintain the same hour (in\n// a new timezone) makes sense. Adding/subtracting hours does not follow\n// this rule.\nvar getSetHour = makeGetSet('Hours', true);\n\n// months\n// week\n// weekdays\n// meridiem\nvar baseConfig = {\n    calendar: defaultCalendar,\n    longDateFormat: defaultLongDateFormat,\n    invalidDate: defaultInvalidDate,\n    ordinal: defaultOrdinal,\n    dayOfMonthOrdinalParse: defaultDayOfMonthOrdinalParse,\n    relativeTime: defaultRelativeTime,\n\n    months: defaultLocaleMonths,\n    monthsShort: defaultLocaleMonthsShort,\n\n    week: defaultLocaleWeek,\n\n    weekdays: defaultLocaleWeekdays,\n    weekdaysMin: defaultLocaleWeekdaysMin,\n    weekdaysShort: defaultLocaleWeekdaysShort,\n\n    meridiemParse: defaultLocaleMeridiemParse\n};\n\n// internal storage for locale config files\nvar locales = {};\nvar localeFamilies = {};\nvar globalLocale;\n\nfunction normalizeLocale(key) {\n    return key ? key.toLowerCase().replace('_', '-') : key;\n}\n\n// pick the locale from the array\n// try ['en-au', 'en-gb'] as 'en-au', 'en-gb', 'en', as in move through the list trying each\n// substring from most specific to least, but move to the next array item if it's a more specific variant than the current root\nfunction chooseLocale(names) {\n    var i = 0, j, next, locale, split;\n\n    while (i < names.length) {\n        split = normalizeLocale(names[i]).split('-');\n        j = split.length;\n        next = normalizeLocale(names[i + 1]);\n        next = next ? next.split('-') : null;\n        while (j > 0) {\n            locale = loadLocale(split.slice(0, j).join('-'));\n            if (locale) {\n                return locale;\n            }\n            if (next && next.length >= j && compareArrays(split, next, true) >= j - 1) {\n                //the next array item is better than a shallower substring of this one\n                break;\n            }\n            j--;\n        }\n        i++;\n    }\n    return null;\n}\n\nfunction loadLocale(name) {\n    var oldLocale = null;\n    // TODO: Find a better way to register and load all the locales in Node\n    if (!locales[name] && (typeof module !== 'undefined') &&\n            module && module.exports) {\n        try {\n            oldLocale = globalLocale._abbr;\n            require('./locale/' + name);\n            // because defineLocale currently also sets the global locale, we\n            // want to undo that for lazy loaded locales\n            getSetGlobalLocale(oldLocale);\n        } catch (e) { }\n    }\n    return locales[name];\n}\n\n// This function will load locale and then set the global locale.  If\n// no arguments are passed in, it will simply return the current global\n// locale key.\nfunction getSetGlobalLocale (key, values) {\n    var data;\n    if (key) {\n        if (isUndefined(values)) {\n            data = getLocale(key);\n        }\n        else {\n            data = defineLocale(key, values);\n        }\n\n        if (data) {\n            // moment.duration._locale = moment._locale = data;\n            globalLocale = data;\n        }\n    }\n\n    return globalLocale._abbr;\n}\n\nfunction defineLocale (name, config) {\n    if (config !== null) {\n        var parentConfig = baseConfig;\n        config.abbr = name;\n        if (locales[name] != null) {\n            deprecateSimple('defineLocaleOverride',\n                    'use moment.updateLocale(localeName, config) to change ' +\n                    'an existing locale. moment.defineLocale(localeName, ' +\n                    'config) should only be used for creating a new locale ' +\n                    'See http://momentjs.com/guides/#/warnings/define-locale/ for more info.');\n            parentConfig = locales[name]._config;\n        } else if (config.parentLocale != null) {\n            if (locales[config.parentLocale] != null) {\n                parentConfig = locales[config.parentLocale]._config;\n            } else {\n                if (!localeFamilies[config.parentLocale]) {\n                    localeFamilies[config.parentLocale] = [];\n                }\n                localeFamilies[config.parentLocale].push({\n                    name: name,\n                    config: config\n                });\n                return null;\n            }\n        }\n        locales[name] = new Locale(mergeConfigs(parentConfig, config));\n\n        if (localeFamilies[name]) {\n            localeFamilies[name].forEach(function (x) {\n                defineLocale(x.name, x.config);\n            });\n        }\n\n        // backwards compat for now: also set the locale\n        // make sure we set the locale AFTER all child locales have been\n        // created, so we won't end up with the child locale set.\n        getSetGlobalLocale(name);\n\n\n        return locales[name];\n    } else {\n        // useful for testing\n        delete locales[name];\n        return null;\n    }\n}\n\nfunction updateLocale(name, config) {\n    if (config != null) {\n        var locale, parentConfig = baseConfig;\n        // MERGE\n        if (locales[name] != null) {\n            parentConfig = locales[name]._config;\n        }\n        config = mergeConfigs(parentConfig, config);\n        locale = new Locale(config);\n        locale.parentLocale = locales[name];\n        locales[name] = locale;\n\n        // backwards compat for now: also set the locale\n        getSetGlobalLocale(name);\n    } else {\n        // pass null for config to unupdate, useful for tests\n        if (locales[name] != null) {\n            if (locales[name].parentLocale != null) {\n                locales[name] = locales[name].parentLocale;\n            } else if (locales[name] != null) {\n                delete locales[name];\n            }\n        }\n    }\n    return locales[name];\n}\n\n// returns locale data\nfunction getLocale (key) {\n    var locale;\n\n    if (key && key._locale && key._locale._abbr) {\n        key = key._locale._abbr;\n    }\n\n    if (!key) {\n        return globalLocale;\n    }\n\n    if (!isArray(key)) {\n        //short-circuit everything else\n        locale = loadLocale(key);\n        if (locale) {\n            return locale;\n        }\n        key = [key];\n    }\n\n    return chooseLocale(key);\n}\n\nfunction listLocales() {\n    return keys$1(locales);\n}\n\nfunction checkOverflow (m) {\n    var overflow;\n    var a = m._a;\n\n    if (a && getParsingFlags(m).overflow === -2) {\n        overflow =\n            a[MONTH]       < 0 || a[MONTH]       > 11  ? MONTH :\n            a[DATE]        < 1 || a[DATE]        > daysInMonth(a[YEAR], a[MONTH]) ? DATE :\n            a[HOUR]        < 0 || a[HOUR]        > 24 || (a[HOUR] === 24 && (a[MINUTE] !== 0 || a[SECOND] !== 0 || a[MILLISECOND] !== 0)) ? HOUR :\n            a[MINUTE]      < 0 || a[MINUTE]      > 59  ? MINUTE :\n            a[SECOND]      < 0 || a[SECOND]      > 59  ? SECOND :\n            a[MILLISECOND] < 0 || a[MILLISECOND] > 999 ? MILLISECOND :\n            -1;\n\n        if (getParsingFlags(m)._overflowDayOfYear && (overflow < YEAR || overflow > DATE)) {\n            overflow = DATE;\n        }\n        if (getParsingFlags(m)._overflowWeeks && overflow === -1) {\n            overflow = WEEK;\n        }\n        if (getParsingFlags(m)._overflowWeekday && overflow === -1) {\n            overflow = WEEKDAY;\n        }\n\n        getParsingFlags(m).overflow = overflow;\n    }\n\n    return m;\n}\n\n// iso 8601 regex\n// 0000-00-00 0000-W00 or 0000-W00-0 + T + 00 or 00:00 or 00:00:00 or 00:00:00.000 + +00:00 or +0000 or +00)\nvar extendedIsoRegex = /^\\s*((?:[+-]\\d{6}|\\d{4})-(?:\\d\\d-\\d\\d|W\\d\\d-\\d|W\\d\\d|\\d\\d\\d|\\d\\d))(?:(T| )(\\d\\d(?::\\d\\d(?::\\d\\d(?:[.,]\\d+)?)?)?)([\\+\\-]\\d\\d(?::?\\d\\d)?|\\s*Z)?)?$/;\nvar basicIsoRegex = /^\\s*((?:[+-]\\d{6}|\\d{4})(?:\\d\\d\\d\\d|W\\d\\d\\d|W\\d\\d|\\d\\d\\d|\\d\\d))(?:(T| )(\\d\\d(?:\\d\\d(?:\\d\\d(?:[.,]\\d+)?)?)?)([\\+\\-]\\d\\d(?::?\\d\\d)?|\\s*Z)?)?$/;\n\nvar tzRegex = /Z|[+-]\\d\\d(?::?\\d\\d)?/;\n\nvar isoDates = [\n    ['YYYYYY-MM-DD', /[+-]\\d{6}-\\d\\d-\\d\\d/],\n    ['YYYY-MM-DD', /\\d{4}-\\d\\d-\\d\\d/],\n    ['GGGG-[W]WW-E', /\\d{4}-W\\d\\d-\\d/],\n    ['GGGG-[W]WW', /\\d{4}-W\\d\\d/, false],\n    ['YYYY-DDD', /\\d{4}-\\d{3}/],\n    ['YYYY-MM', /\\d{4}-\\d\\d/, false],\n    ['YYYYYYMMDD', /[+-]\\d{10}/],\n    ['YYYYMMDD', /\\d{8}/],\n    // YYYYMM is NOT allowed by the standard\n    ['GGGG[W]WWE', /\\d{4}W\\d{3}/],\n    ['GGGG[W]WW', /\\d{4}W\\d{2}/, false],\n    ['YYYYDDD', /\\d{7}/]\n];\n\n// iso time formats and regexes\nvar isoTimes = [\n    ['HH:mm:ss.SSSS', /\\d\\d:\\d\\d:\\d\\d\\.\\d+/],\n    ['HH:mm:ss,SSSS', /\\d\\d:\\d\\d:\\d\\d,\\d+/],\n    ['HH:mm:ss', /\\d\\d:\\d\\d:\\d\\d/],\n    ['HH:mm', /\\d\\d:\\d\\d/],\n    ['HHmmss.SSSS', /\\d\\d\\d\\d\\d\\d\\.\\d+/],\n    ['HHmmss,SSSS', /\\d\\d\\d\\d\\d\\d,\\d+/],\n    ['HHmmss', /\\d\\d\\d\\d\\d\\d/],\n    ['HHmm', /\\d\\d\\d\\d/],\n    ['HH', /\\d\\d/]\n];\n\nvar aspNetJsonRegex = /^\\/?Date\\((\\-?\\d+)/i;\n\n// date from iso format\nfunction configFromISO(config) {\n    var i, l,\n        string = config._i,\n        match = extendedIsoRegex.exec(string) || basicIsoRegex.exec(string),\n        allowTime, dateFormat, timeFormat, tzFormat;\n\n    if (match) {\n        getParsingFlags(config).iso = true;\n\n        for (i = 0, l = isoDates.length; i < l; i++) {\n            if (isoDates[i][1].exec(match[1])) {\n                dateFormat = isoDates[i][0];\n                allowTime = isoDates[i][2] !== false;\n                break;\n            }\n        }\n        if (dateFormat == null) {\n            config._isValid = false;\n            return;\n        }\n        if (match[3]) {\n            for (i = 0, l = isoTimes.length; i < l; i++) {\n                if (isoTimes[i][1].exec(match[3])) {\n                    // match[2] should be 'T' or space\n                    timeFormat = (match[2] || ' ') + isoTimes[i][0];\n                    break;\n                }\n            }\n            if (timeFormat == null) {\n                config._isValid = false;\n                return;\n            }\n        }\n        if (!allowTime && timeFormat != null) {\n            config._isValid = false;\n            return;\n        }\n        if (match[4]) {\n            if (tzRegex.exec(match[4])) {\n                tzFormat = 'Z';\n            } else {\n                config._isValid = false;\n                return;\n            }\n        }\n        config._f = dateFormat + (timeFormat || '') + (tzFormat || '');\n        configFromStringAndFormat(config);\n    } else {\n        config._isValid = false;\n    }\n}\n\n// RFC 2822 regex: For details see https://tools.ietf.org/html/rfc2822#section-3.3\nvar basicRfcRegex = /^((?:Mon|Tue|Wed|Thu|Fri|Sat|Sun),?\\s)?(\\d?\\d\\s(?:Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)\\s(?:\\d\\d)?\\d\\d\\s)(\\d\\d:\\d\\d)(\\:\\d\\d)?(\\s(?:UT|GMT|[ECMP][SD]T|[A-IK-Za-ik-z]|[+-]\\d{4}))$/;\n\n// date and time from ref 2822 format\nfunction configFromRFC2822(config) {\n    var string, match, dayFormat,\n        dateFormat, timeFormat, tzFormat;\n    var timezones = {\n        ' GMT': ' +0000',\n        ' EDT': ' -0400',\n        ' EST': ' -0500',\n        ' CDT': ' -0500',\n        ' CST': ' -0600',\n        ' MDT': ' -0600',\n        ' MST': ' -0700',\n        ' PDT': ' -0700',\n        ' PST': ' -0800'\n    };\n    var military = 'YXWVUTSRQPONZABCDEFGHIKLM';\n    var timezone, timezoneIndex;\n\n    string = config._i\n        .replace(/\\([^\\)]*\\)|[\\n\\t]/g, ' ') // Remove comments and folding whitespace\n        .replace(/(\\s\\s+)/g, ' ') // Replace multiple-spaces with a single space\n        .replace(/^\\s|\\s$/g, ''); // Remove leading and trailing spaces\n    match = basicRfcRegex.exec(string);\n\n    if (match) {\n        dayFormat = match[1] ? 'ddd' + ((match[1].length === 5) ? ', ' : ' ') : '';\n        dateFormat = 'D MMM ' + ((match[2].length > 10) ? 'YYYY ' : 'YY ');\n        timeFormat = 'HH:mm' + (match[4] ? ':ss' : '');\n\n        // TODO: Replace the vanilla JS Date object with an indepentent day-of-week check.\n        if (match[1]) { // day of week given\n            var momentDate = new Date(match[2]);\n            var momentDay = ['Sun','Mon','Tue','Wed','Thu','Fri','Sat'][momentDate.getDay()];\n\n            if (match[1].substr(0,3) !== momentDay) {\n                getParsingFlags(config).weekdayMismatch = true;\n                config._isValid = false;\n                return;\n            }\n        }\n\n        switch (match[5].length) {\n            case 2: // military\n                if (timezoneIndex === 0) {\n                    timezone = ' +0000';\n                } else {\n                    timezoneIndex = military.indexOf(match[5][1].toUpperCase()) - 12;\n                    timezone = ((timezoneIndex < 0) ? ' -' : ' +') +\n                        (('' + timezoneIndex).replace(/^-?/, '0')).match(/..$/)[0] + '00';\n                }\n                break;\n            case 4: // Zone\n                timezone = timezones[match[5]];\n                break;\n            default: // UT or +/-9999\n                timezone = timezones[' GMT'];\n        }\n        match[5] = timezone;\n        config._i = match.splice(1).join('');\n        tzFormat = ' ZZ';\n        config._f = dayFormat + dateFormat + timeFormat + tzFormat;\n        configFromStringAndFormat(config);\n        getParsingFlags(config).rfc2822 = true;\n    } else {\n        config._isValid = false;\n    }\n}\n\n// date from iso format or fallback\nfunction configFromString(config) {\n    var matched = aspNetJsonRegex.exec(config._i);\n\n    if (matched !== null) {\n        config._d = new Date(+matched[1]);\n        return;\n    }\n\n    configFromISO(config);\n    if (config._isValid === false) {\n        delete config._isValid;\n    } else {\n        return;\n    }\n\n    configFromRFC2822(config);\n    if (config._isValid === false) {\n        delete config._isValid;\n    } else {\n        return;\n    }\n\n    // Final attempt, use Input Fallback\n    hooks.createFromInputFallback(config);\n}\n\nhooks.createFromInputFallback = deprecate(\n    'value provided is not in a recognized RFC2822 or ISO format. moment construction falls back to js Date(), ' +\n    'which is not reliable across all browsers and versions. Non RFC2822/ISO date formats are ' +\n    'discouraged and will be removed in an upcoming major release. Please refer to ' +\n    'http://momentjs.com/guides/#/warnings/js-date/ for more info.',\n    function (config) {\n        config._d = new Date(config._i + (config._useUTC ? ' UTC' : ''));\n    }\n);\n\n// Pick the first defined of two or three arguments.\nfunction defaults(a, b, c) {\n    if (a != null) {\n        return a;\n    }\n    if (b != null) {\n        return b;\n    }\n    return c;\n}\n\nfunction currentDateArray(config) {\n    // hooks is actually the exported moment object\n    var nowValue = new Date(hooks.now());\n    if (config._useUTC) {\n        return [nowValue.getUTCFullYear(), nowValue.getUTCMonth(), nowValue.getUTCDate()];\n    }\n    return [nowValue.getFullYear(), nowValue.getMonth(), nowValue.getDate()];\n}\n\n// convert an array to a date.\n// the array should mirror the parameters below\n// note: all values past the year are optional and will default to the lowest possible value.\n// [year, month, day , hour, minute, second, millisecond]\nfunction configFromArray (config) {\n    var i, date, input = [], currentDate, yearToUse;\n\n    if (config._d) {\n        return;\n    }\n\n    currentDate = currentDateArray(config);\n\n    //compute day of the year from weeks and weekdays\n    if (config._w && config._a[DATE] == null && config._a[MONTH] == null) {\n        dayOfYearFromWeekInfo(config);\n    }\n\n    //if the day of the year is set, figure out what it is\n    if (config._dayOfYear != null) {\n        yearToUse = defaults(config._a[YEAR], currentDate[YEAR]);\n\n        if (config._dayOfYear > daysInYear(yearToUse) || config._dayOfYear === 0) {\n            getParsingFlags(config)._overflowDayOfYear = true;\n        }\n\n        date = createUTCDate(yearToUse, 0, config._dayOfYear);\n        config._a[MONTH] = date.getUTCMonth();\n        config._a[DATE] = date.getUTCDate();\n    }\n\n    // Default to current date.\n    // * if no year, month, day of month are given, default to today\n    // * if day of month is given, default month and year\n    // * if month is given, default only year\n    // * if year is given, don't default anything\n    for (i = 0; i < 3 && config._a[i] == null; ++i) {\n        config._a[i] = input[i] = currentDate[i];\n    }\n\n    // Zero out whatever was not defaulted, including time\n    for (; i < 7; i++) {\n        config._a[i] = input[i] = (config._a[i] == null) ? (i === 2 ? 1 : 0) : config._a[i];\n    }\n\n    // Check for 24:00:00.000\n    if (config._a[HOUR] === 24 &&\n            config._a[MINUTE] === 0 &&\n            config._a[SECOND] === 0 &&\n            config._a[MILLISECOND] === 0) {\n        config._nextDay = true;\n        config._a[HOUR] = 0;\n    }\n\n    config._d = (config._useUTC ? createUTCDate : createDate).apply(null, input);\n    // Apply timezone offset from input. The actual utcOffset can be changed\n    // with parseZone.\n    if (config._tzm != null) {\n        config._d.setUTCMinutes(config._d.getUTCMinutes() - config._tzm);\n    }\n\n    if (config._nextDay) {\n        config._a[HOUR] = 24;\n    }\n}\n\nfunction dayOfYearFromWeekInfo(config) {\n    var w, weekYear, week, weekday, dow, doy, temp, weekdayOverflow;\n\n    w = config._w;\n    if (w.GG != null || w.W != null || w.E != null) {\n        dow = 1;\n        doy = 4;\n\n        // TODO: We need to take the current isoWeekYear, but that depends on\n        // how we interpret now (local, utc, fixed offset). So create\n        // a now version of current config (take local/utc/offset flags, and\n        // create now).\n        weekYear = defaults(w.GG, config._a[YEAR], weekOfYear(createLocal(), 1, 4).year);\n        week = defaults(w.W, 1);\n        weekday = defaults(w.E, 1);\n        if (weekday < 1 || weekday > 7) {\n            weekdayOverflow = true;\n        }\n    } else {\n        dow = config._locale._week.dow;\n        doy = config._locale._week.doy;\n\n        var curWeek = weekOfYear(createLocal(), dow, doy);\n\n        weekYear = defaults(w.gg, config._a[YEAR], curWeek.year);\n\n        // Default to current week.\n        week = defaults(w.w, curWeek.week);\n\n        if (w.d != null) {\n            // weekday -- low day numbers are considered next week\n            weekday = w.d;\n            if (weekday < 0 || weekday > 6) {\n                weekdayOverflow = true;\n            }\n        } else if (w.e != null) {\n            // local weekday -- counting starts from begining of week\n            weekday = w.e + dow;\n            if (w.e < 0 || w.e > 6) {\n                weekdayOverflow = true;\n            }\n        } else {\n            // default to begining of week\n            weekday = dow;\n        }\n    }\n    if (week < 1 || week > weeksInYear(weekYear, dow, doy)) {\n        getParsingFlags(config)._overflowWeeks = true;\n    } else if (weekdayOverflow != null) {\n        getParsingFlags(config)._overflowWeekday = true;\n    } else {\n        temp = dayOfYearFromWeeks(weekYear, week, weekday, dow, doy);\n        config._a[YEAR] = temp.year;\n        config._dayOfYear = temp.dayOfYear;\n    }\n}\n\n// constant that refers to the ISO standard\nhooks.ISO_8601 = function () {};\n\n// constant that refers to the RFC 2822 form\nhooks.RFC_2822 = function () {};\n\n// date from string and format string\nfunction configFromStringAndFormat(config) {\n    // TODO: Move this to another part of the creation flow to prevent circular deps\n    if (config._f === hooks.ISO_8601) {\n        configFromISO(config);\n        return;\n    }\n    if (config._f === hooks.RFC_2822) {\n        configFromRFC2822(config);\n        return;\n    }\n    config._a = [];\n    getParsingFlags(config).empty = true;\n\n    // This array is used to make a Date, either with `new Date` or `Date.UTC`\n    var string = '' + config._i,\n        i, parsedInput, tokens, token, skipped,\n        stringLength = string.length,\n        totalParsedInputLength = 0;\n\n    tokens = expandFormat(config._f, config._locale).match(formattingTokens) || [];\n\n    for (i = 0; i < tokens.length; i++) {\n        token = tokens[i];\n        parsedInput = (string.match(getParseRegexForToken(token, config)) || [])[0];\n        // console.log('token', token, 'parsedInput', parsedInput,\n        //         'regex', getParseRegexForToken(token, config));\n        if (parsedInput) {\n            skipped = string.substr(0, string.indexOf(parsedInput));\n            if (skipped.length > 0) {\n                getParsingFlags(config).unusedInput.push(skipped);\n            }\n            string = string.slice(string.indexOf(parsedInput) + parsedInput.length);\n            totalParsedInputLength += parsedInput.length;\n        }\n        // don't parse if it's not a known token\n        if (formatTokenFunctions[token]) {\n            if (parsedInput) {\n                getParsingFlags(config).empty = false;\n            }\n            else {\n                getParsingFlags(config).unusedTokens.push(token);\n            }\n            addTimeToArrayFromToken(token, parsedInput, config);\n        }\n        else if (config._strict && !parsedInput) {\n            getParsingFlags(config).unusedTokens.push(token);\n        }\n    }\n\n    // add remaining unparsed input length to the string\n    getParsingFlags(config).charsLeftOver = stringLength - totalParsedInputLength;\n    if (string.length > 0) {\n        getParsingFlags(config).unusedInput.push(string);\n    }\n\n    // clear _12h flag if hour is <= 12\n    if (config._a[HOUR] <= 12 &&\n        getParsingFlags(config).bigHour === true &&\n        config._a[HOUR] > 0) {\n        getParsingFlags(config).bigHour = undefined;\n    }\n\n    getParsingFlags(config).parsedDateParts = config._a.slice(0);\n    getParsingFlags(config).meridiem = config._meridiem;\n    // handle meridiem\n    config._a[HOUR] = meridiemFixWrap(config._locale, config._a[HOUR], config._meridiem);\n\n    configFromArray(config);\n    checkOverflow(config);\n}\n\n\nfunction meridiemFixWrap (locale, hour, meridiem) {\n    var isPm;\n\n    if (meridiem == null) {\n        // nothing to do\n        return hour;\n    }\n    if (locale.meridiemHour != null) {\n        return locale.meridiemHour(hour, meridiem);\n    } else if (locale.isPM != null) {\n        // Fallback\n        isPm = locale.isPM(meridiem);\n        if (isPm && hour < 12) {\n            hour += 12;\n        }\n        if (!isPm && hour === 12) {\n            hour = 0;\n        }\n        return hour;\n    } else {\n        // this is not supposed to happen\n        return hour;\n    }\n}\n\n// date from string and array of format strings\nfunction configFromStringAndArray(config) {\n    var tempConfig,\n        bestMoment,\n\n        scoreToBeat,\n        i,\n        currentScore;\n\n    if (config._f.length === 0) {\n        getParsingFlags(config).invalidFormat = true;\n        config._d = new Date(NaN);\n        return;\n    }\n\n    for (i = 0; i < config._f.length; i++) {\n        currentScore = 0;\n        tempConfig = copyConfig({}, config);\n        if (config._useUTC != null) {\n            tempConfig._useUTC = config._useUTC;\n        }\n        tempConfig._f = config._f[i];\n        configFromStringAndFormat(tempConfig);\n\n        if (!isValid(tempConfig)) {\n            continue;\n        }\n\n        // if there is any input that was not parsed add a penalty for that format\n        currentScore += getParsingFlags(tempConfig).charsLeftOver;\n\n        //or tokens\n        currentScore += getParsingFlags(tempConfig).unusedTokens.length * 10;\n\n        getParsingFlags(tempConfig).score = currentScore;\n\n        if (scoreToBeat == null || currentScore < scoreToBeat) {\n            scoreToBeat = currentScore;\n            bestMoment = tempConfig;\n        }\n    }\n\n    extend(config, bestMoment || tempConfig);\n}\n\nfunction configFromObject(config) {\n    if (config._d) {\n        return;\n    }\n\n    var i = normalizeObjectUnits(config._i);\n    config._a = map([i.year, i.month, i.day || i.date, i.hour, i.minute, i.second, i.millisecond], function (obj) {\n        return obj && parseInt(obj, 10);\n    });\n\n    configFromArray(config);\n}\n\nfunction createFromConfig (config) {\n    var res = new Moment(checkOverflow(prepareConfig(config)));\n    if (res._nextDay) {\n        // Adding is smart enough around DST\n        res.add(1, 'd');\n        res._nextDay = undefined;\n    }\n\n    return res;\n}\n\nfunction prepareConfig (config) {\n    var input = config._i,\n        format = config._f;\n\n    config._locale = config._locale || getLocale(config._l);\n\n    if (input === null || (format === undefined && input === '')) {\n        return createInvalid({nullInput: true});\n    }\n\n    if (typeof input === 'string') {\n        config._i = input = config._locale.preparse(input);\n    }\n\n    if (isMoment(input)) {\n        return new Moment(checkOverflow(input));\n    } else if (isDate(input)) {\n        config._d = input;\n    } else if (isArray(format)) {\n        configFromStringAndArray(config);\n    } else if (format) {\n        configFromStringAndFormat(config);\n    }  else {\n        configFromInput(config);\n    }\n\n    if (!isValid(config)) {\n        config._d = null;\n    }\n\n    return config;\n}\n\nfunction configFromInput(config) {\n    var input = config._i;\n    if (isUndefined(input)) {\n        config._d = new Date(hooks.now());\n    } else if (isDate(input)) {\n        config._d = new Date(input.valueOf());\n    } else if (typeof input === 'string') {\n        configFromString(config);\n    } else if (isArray(input)) {\n        config._a = map(input.slice(0), function (obj) {\n            return parseInt(obj, 10);\n        });\n        configFromArray(config);\n    } else if (isObject(input)) {\n        configFromObject(config);\n    } else if (isNumber(input)) {\n        // from milliseconds\n        config._d = new Date(input);\n    } else {\n        hooks.createFromInputFallback(config);\n    }\n}\n\nfunction createLocalOrUTC (input, format, locale, strict, isUTC) {\n    var c = {};\n\n    if (locale === true || locale === false) {\n        strict = locale;\n        locale = undefined;\n    }\n\n    if ((isObject(input) && isObjectEmpty(input)) ||\n            (isArray(input) && input.length === 0)) {\n        input = undefined;\n    }\n    // object construction must be done this way.\n    // https://github.com/moment/moment/issues/1423\n    c._isAMomentObject = true;\n    c._useUTC = c._isUTC = isUTC;\n    c._l = locale;\n    c._i = input;\n    c._f = format;\n    c._strict = strict;\n\n    return createFromConfig(c);\n}\n\nfunction createLocal (input, format, locale, strict) {\n    return createLocalOrUTC(input, format, locale, strict, false);\n}\n\nvar prototypeMin = deprecate(\n    'moment().min is deprecated, use moment.max instead. http://momentjs.com/guides/#/warnings/min-max/',\n    function () {\n        var other = createLocal.apply(null, arguments);\n        if (this.isValid() && other.isValid()) {\n            return other < this ? this : other;\n        } else {\n            return createInvalid();\n        }\n    }\n);\n\nvar prototypeMax = deprecate(\n    'moment().max is deprecated, use moment.min instead. http://momentjs.com/guides/#/warnings/min-max/',\n    function () {\n        var other = createLocal.apply(null, arguments);\n        if (this.isValid() && other.isValid()) {\n            return other > this ? this : other;\n        } else {\n            return createInvalid();\n        }\n    }\n);\n\n// Pick a moment m from moments so that m[fn](other) is true for all\n// other. This relies on the function fn to be transitive.\n//\n// moments should either be an array of moment objects or an array, whose\n// first element is an array of moment objects.\nfunction pickBy(fn, moments) {\n    var res, i;\n    if (moments.length === 1 && isArray(moments[0])) {\n        moments = moments[0];\n    }\n    if (!moments.length) {\n        return createLocal();\n    }\n    res = moments[0];\n    for (i = 1; i < moments.length; ++i) {\n        if (!moments[i].isValid() || moments[i][fn](res)) {\n            res = moments[i];\n        }\n    }\n    return res;\n}\n\n// TODO: Use [].sort instead?\nfunction min () {\n    var args = [].slice.call(arguments, 0);\n\n    return pickBy('isBefore', args);\n}\n\nfunction max () {\n    var args = [].slice.call(arguments, 0);\n\n    return pickBy('isAfter', args);\n}\n\nvar now = function () {\n    return Date.now ? Date.now() : +(new Date());\n};\n\nvar ordering = ['year', 'quarter', 'month', 'week', 'day', 'hour', 'minute', 'second', 'millisecond'];\n\nfunction isDurationValid(m) {\n    for (var key in m) {\n        if (!(ordering.indexOf(key) !== -1 && (m[key] == null || !isNaN(m[key])))) {\n            return false;\n        }\n    }\n\n    var unitHasDecimal = false;\n    for (var i = 0; i < ordering.length; ++i) {\n        if (m[ordering[i]]) {\n            if (unitHasDecimal) {\n                return false; // only allow non-integers for smallest unit\n            }\n            if (parseFloat(m[ordering[i]]) !== toInt(m[ordering[i]])) {\n                unitHasDecimal = true;\n            }\n        }\n    }\n\n    return true;\n}\n\nfunction isValid$1() {\n    return this._isValid;\n}\n\nfunction createInvalid$1() {\n    return createDuration(NaN);\n}\n\nfunction Duration (duration) {\n    var normalizedInput = normalizeObjectUnits(duration),\n        years = normalizedInput.year || 0,\n        quarters = normalizedInput.quarter || 0,\n        months = normalizedInput.month || 0,\n        weeks = normalizedInput.week || 0,\n        days = normalizedInput.day || 0,\n        hours = normalizedInput.hour || 0,\n        minutes = normalizedInput.minute || 0,\n        seconds = normalizedInput.second || 0,\n        milliseconds = normalizedInput.millisecond || 0;\n\n    this._isValid = isDurationValid(normalizedInput);\n\n    // representation for dateAddRemove\n    this._milliseconds = +milliseconds +\n        seconds * 1e3 + // 1000\n        minutes * 6e4 + // 1000 * 60\n        hours * 1000 * 60 * 60; //using 1000 * 60 * 60 instead of 36e5 to avoid floating point rounding errors https://github.com/moment/moment/issues/2978\n    // Because of dateAddRemove treats 24 hours as different from a\n    // day when working around DST, we need to store them separately\n    this._days = +days +\n        weeks * 7;\n    // It is impossible translate months into days without knowing\n    // which months you are are talking about, so we have to store\n    // it separately.\n    this._months = +months +\n        quarters * 3 +\n        years * 12;\n\n    this._data = {};\n\n    this._locale = getLocale();\n\n    this._bubble();\n}\n\nfunction isDuration (obj) {\n    return obj instanceof Duration;\n}\n\nfunction absRound (number) {\n    if (number < 0) {\n        return Math.round(-1 * number) * -1;\n    } else {\n        return Math.round(number);\n    }\n}\n\n// FORMATTING\n\nfunction offset (token, separator) {\n    addFormatToken(token, 0, 0, function () {\n        var offset = this.utcOffset();\n        var sign = '+';\n        if (offset < 0) {\n            offset = -offset;\n            sign = '-';\n        }\n        return sign + zeroFill(~~(offset / 60), 2) + separator + zeroFill(~~(offset) % 60, 2);\n    });\n}\n\noffset('Z', ':');\noffset('ZZ', '');\n\n// PARSING\n\naddRegexToken('Z',  matchShortOffset);\naddRegexToken('ZZ', matchShortOffset);\naddParseToken(['Z', 'ZZ'], function (input, array, config) {\n    config._useUTC = true;\n    config._tzm = offsetFromString(matchShortOffset, input);\n});\n\n// HELPERS\n\n// timezone chunker\n// '+10:00' > ['10',  '00']\n// '-1530'  > ['-15', '30']\nvar chunkOffset = /([\\+\\-]|\\d\\d)/gi;\n\nfunction offsetFromString(matcher, string) {\n    var matches = (string || '').match(matcher);\n\n    if (matches === null) {\n        return null;\n    }\n\n    var chunk   = matches[matches.length - 1] || [];\n    var parts   = (chunk + '').match(chunkOffset) || ['-', 0, 0];\n    var minutes = +(parts[1] * 60) + toInt(parts[2]);\n\n    return minutes === 0 ?\n      0 :\n      parts[0] === '+' ? minutes : -minutes;\n}\n\n// Return a moment from input, that is local/utc/zone equivalent to model.\nfunction cloneWithOffset(input, model) {\n    var res, diff;\n    if (model._isUTC) {\n        res = model.clone();\n        diff = (isMoment(input) || isDate(input) ? input.valueOf() : createLocal(input).valueOf()) - res.valueOf();\n        // Use low-level api, because this fn is low-level api.\n        res._d.setTime(res._d.valueOf() + diff);\n        hooks.updateOffset(res, false);\n        return res;\n    } else {\n        return createLocal(input).local();\n    }\n}\n\nfunction getDateOffset (m) {\n    // On Firefox.24 Date#getTimezoneOffset returns a floating point.\n    // https://github.com/moment/moment/pull/1871\n    return -Math.round(m._d.getTimezoneOffset() / 15) * 15;\n}\n\n// HOOKS\n\n// This function will be called whenever a moment is mutated.\n// It is intended to keep the offset in sync with the timezone.\nhooks.updateOffset = function () {};\n\n// MOMENTS\n\n// keepLocalTime = true means only change the timezone, without\n// affecting the local hour. So 5:31:26 +0300 --[utcOffset(2, true)]-->\n// 5:31:26 +0200 It is possible that 5:31:26 doesn't exist with offset\n// +0200, so we adjust the time as needed, to be valid.\n//\n// Keeping the time actually adds/subtracts (one hour)\n// from the actual represented time. That is why we call updateOffset\n// a second time. In case it wants us to change the offset again\n// _changeInProgress == true case, then we have to adjust, because\n// there is no such time in the given timezone.\nfunction getSetOffset (input, keepLocalTime, keepMinutes) {\n    var offset = this._offset || 0,\n        localAdjust;\n    if (!this.isValid()) {\n        return input != null ? this : NaN;\n    }\n    if (input != null) {\n        if (typeof input === 'string') {\n            input = offsetFromString(matchShortOffset, input);\n            if (input === null) {\n                return this;\n            }\n        } else if (Math.abs(input) < 16 && !keepMinutes) {\n            input = input * 60;\n        }\n        if (!this._isUTC && keepLocalTime) {\n            localAdjust = getDateOffset(this);\n        }\n        this._offset = input;\n        this._isUTC = true;\n        if (localAdjust != null) {\n            this.add(localAdjust, 'm');\n        }\n        if (offset !== input) {\n            if (!keepLocalTime || this._changeInProgress) {\n                addSubtract(this, createDuration(input - offset, 'm'), 1, false);\n            } else if (!this._changeInProgress) {\n                this._changeInProgress = true;\n                hooks.updateOffset(this, true);\n                this._changeInProgress = null;\n            }\n        }\n        return this;\n    } else {\n        return this._isUTC ? offset : getDateOffset(this);\n    }\n}\n\nfunction getSetZone (input, keepLocalTime) {\n    if (input != null) {\n        if (typeof input !== 'string') {\n            input = -input;\n        }\n\n        this.utcOffset(input, keepLocalTime);\n\n        return this;\n    } else {\n        return -this.utcOffset();\n    }\n}\n\nfunction setOffsetToUTC (keepLocalTime) {\n    return this.utcOffset(0, keepLocalTime);\n}\n\nfunction setOffsetToLocal (keepLocalTime) {\n    if (this._isUTC) {\n        this.utcOffset(0, keepLocalTime);\n        this._isUTC = false;\n\n        if (keepLocalTime) {\n            this.subtract(getDateOffset(this), 'm');\n        }\n    }\n    return this;\n}\n\nfunction setOffsetToParsedOffset () {\n    if (this._tzm != null) {\n        this.utcOffset(this._tzm, false, true);\n    } else if (typeof this._i === 'string') {\n        var tZone = offsetFromString(matchOffset, this._i);\n        if (tZone != null) {\n            this.utcOffset(tZone);\n        }\n        else {\n            this.utcOffset(0, true);\n        }\n    }\n    return this;\n}\n\nfunction hasAlignedHourOffset (input) {\n    if (!this.isValid()) {\n        return false;\n    }\n    input = input ? createLocal(input).utcOffset() : 0;\n\n    return (this.utcOffset() - input) % 60 === 0;\n}\n\nfunction isDaylightSavingTime () {\n    return (\n        this.utcOffset() > this.clone().month(0).utcOffset() ||\n        this.utcOffset() > this.clone().month(5).utcOffset()\n    );\n}\n\nfunction isDaylightSavingTimeShifted () {\n    if (!isUndefined(this._isDSTShifted)) {\n        return this._isDSTShifted;\n    }\n\n    var c = {};\n\n    copyConfig(c, this);\n    c = prepareConfig(c);\n\n    if (c._a) {\n        var other = c._isUTC ? createUTC(c._a) : createLocal(c._a);\n        this._isDSTShifted = this.isValid() &&\n            compareArrays(c._a, other.toArray()) > 0;\n    } else {\n        this._isDSTShifted = false;\n    }\n\n    return this._isDSTShifted;\n}\n\nfunction isLocal () {\n    return this.isValid() ? !this._isUTC : false;\n}\n\nfunction isUtcOffset () {\n    return this.isValid() ? this._isUTC : false;\n}\n\nfunction isUtc () {\n    return this.isValid() ? this._isUTC && this._offset === 0 : false;\n}\n\n// ASP.NET json date format regex\nvar aspNetRegex = /^(\\-)?(?:(\\d*)[. ])?(\\d+)\\:(\\d+)(?:\\:(\\d+)(\\.\\d*)?)?$/;\n\n// from http://docs.closure-library.googlecode.com/git/closure_goog_date_date.js.source.html\n// somewhat more in line with 4.4.3.2 2004 spec, but allows decimal anywhere\n// and further modified to allow for strings containing both week and day\nvar isoRegex = /^(-)?P(?:(-?[0-9,.]*)Y)?(?:(-?[0-9,.]*)M)?(?:(-?[0-9,.]*)W)?(?:(-?[0-9,.]*)D)?(?:T(?:(-?[0-9,.]*)H)?(?:(-?[0-9,.]*)M)?(?:(-?[0-9,.]*)S)?)?$/;\n\nfunction createDuration (input, key) {\n    var duration = input,\n        // matching against regexp is expensive, do it on demand\n        match = null,\n        sign,\n        ret,\n        diffRes;\n\n    if (isDuration(input)) {\n        duration = {\n            ms : input._milliseconds,\n            d  : input._days,\n            M  : input._months\n        };\n    } else if (isNumber(input)) {\n        duration = {};\n        if (key) {\n            duration[key] = input;\n        } else {\n            duration.milliseconds = input;\n        }\n    } else if (!!(match = aspNetRegex.exec(input))) {\n        sign = (match[1] === '-') ? -1 : 1;\n        duration = {\n            y  : 0,\n            d  : toInt(match[DATE])                         * sign,\n            h  : toInt(match[HOUR])                         * sign,\n            m  : toInt(match[MINUTE])                       * sign,\n            s  : toInt(match[SECOND])                       * sign,\n            ms : toInt(absRound(match[MILLISECOND] * 1000)) * sign // the millisecond decimal point is included in the match\n        };\n    } else if (!!(match = isoRegex.exec(input))) {\n        sign = (match[1] === '-') ? -1 : 1;\n        duration = {\n            y : parseIso(match[2], sign),\n            M : parseIso(match[3], sign),\n            w : parseIso(match[4], sign),\n            d : parseIso(match[5], sign),\n            h : parseIso(match[6], sign),\n            m : parseIso(match[7], sign),\n            s : parseIso(match[8], sign)\n        };\n    } else if (duration == null) {// checks for null or undefined\n        duration = {};\n    } else if (typeof duration === 'object' && ('from' in duration || 'to' in duration)) {\n        diffRes = momentsDifference(createLocal(duration.from), createLocal(duration.to));\n\n        duration = {};\n        duration.ms = diffRes.milliseconds;\n        duration.M = diffRes.months;\n    }\n\n    ret = new Duration(duration);\n\n    if (isDuration(input) && hasOwnProp(input, '_locale')) {\n        ret._locale = input._locale;\n    }\n\n    return ret;\n}\n\ncreateDuration.fn = Duration.prototype;\ncreateDuration.invalid = createInvalid$1;\n\nfunction parseIso (inp, sign) {\n    // We'd normally use ~~inp for this, but unfortunately it also\n    // converts floats to ints.\n    // inp may be undefined, so careful calling replace on it.\n    var res = inp && parseFloat(inp.replace(',', '.'));\n    // apply sign while we're at it\n    return (isNaN(res) ? 0 : res) * sign;\n}\n\nfunction positiveMomentsDifference(base, other) {\n    var res = {milliseconds: 0, months: 0};\n\n    res.months = other.month() - base.month() +\n        (other.year() - base.year()) * 12;\n    if (base.clone().add(res.months, 'M').isAfter(other)) {\n        --res.months;\n    }\n\n    res.milliseconds = +other - +(base.clone().add(res.months, 'M'));\n\n    return res;\n}\n\nfunction momentsDifference(base, other) {\n    var res;\n    if (!(base.isValid() && other.isValid())) {\n        return {milliseconds: 0, months: 0};\n    }\n\n    other = cloneWithOffset(other, base);\n    if (base.isBefore(other)) {\n        res = positiveMomentsDifference(base, other);\n    } else {\n        res = positiveMomentsDifference(other, base);\n        res.milliseconds = -res.milliseconds;\n        res.months = -res.months;\n    }\n\n    return res;\n}\n\n// TODO: remove 'name' arg after deprecation is removed\nfunction createAdder(direction, name) {\n    return function (val, period) {\n        var dur, tmp;\n        //invert the arguments, but complain about it\n        if (period !== null && !isNaN(+period)) {\n            deprecateSimple(name, 'moment().' + name  + '(period, number) is deprecated. Please use moment().' + name + '(number, period). ' +\n            'See http://momentjs.com/guides/#/warnings/add-inverted-param/ for more info.');\n            tmp = val; val = period; period = tmp;\n        }\n\n        val = typeof val === 'string' ? +val : val;\n        dur = createDuration(val, period);\n        addSubtract(this, dur, direction);\n        return this;\n    };\n}\n\nfunction addSubtract (mom, duration, isAdding, updateOffset) {\n    var milliseconds = duration._milliseconds,\n        days = absRound(duration._days),\n        months = absRound(duration._months);\n\n    if (!mom.isValid()) {\n        // No op\n        return;\n    }\n\n    updateOffset = updateOffset == null ? true : updateOffset;\n\n    if (milliseconds) {\n        mom._d.setTime(mom._d.valueOf() + milliseconds * isAdding);\n    }\n    if (days) {\n        set$1(mom, 'Date', get(mom, 'Date') + days * isAdding);\n    }\n    if (months) {\n        setMonth(mom, get(mom, 'Month') + months * isAdding);\n    }\n    if (updateOffset) {\n        hooks.updateOffset(mom, days || months);\n    }\n}\n\nvar add      = createAdder(1, 'add');\nvar subtract = createAdder(-1, 'subtract');\n\nfunction getCalendarFormat(myMoment, now) {\n    var diff = myMoment.diff(now, 'days', true);\n    return diff < -6 ? 'sameElse' :\n            diff < -1 ? 'lastWeek' :\n            diff < 0 ? 'lastDay' :\n            diff < 1 ? 'sameDay' :\n            diff < 2 ? 'nextDay' :\n            diff < 7 ? 'nextWeek' : 'sameElse';\n}\n\nfunction calendar$1 (time, formats) {\n    // We want to compare the start of today, vs this.\n    // Getting start-of-today depends on whether we're local/utc/offset or not.\n    var now = time || createLocal(),\n        sod = cloneWithOffset(now, this).startOf('day'),\n        format = hooks.calendarFormat(this, sod) || 'sameElse';\n\n    var output = formats && (isFunction(formats[format]) ? formats[format].call(this, now) : formats[format]);\n\n    return this.format(output || this.localeData().calendar(format, this, createLocal(now)));\n}\n\nfunction clone () {\n    return new Moment(this);\n}\n\nfunction isAfter (input, units) {\n    var localInput = isMoment(input) ? input : createLocal(input);\n    if (!(this.isValid() && localInput.isValid())) {\n        return false;\n    }\n    units = normalizeUnits(!isUndefined(units) ? units : 'millisecond');\n    if (units === 'millisecond') {\n        return this.valueOf() > localInput.valueOf();\n    } else {\n        return localInput.valueOf() < this.clone().startOf(units).valueOf();\n    }\n}\n\nfunction isBefore (input, units) {\n    var localInput = isMoment(input) ? input : createLocal(input);\n    if (!(this.isValid() && localInput.isValid())) {\n        return false;\n    }\n    units = normalizeUnits(!isUndefined(units) ? units : 'millisecond');\n    if (units === 'millisecond') {\n        return this.valueOf() < localInput.valueOf();\n    } else {\n        return this.clone().endOf(units).valueOf() < localInput.valueOf();\n    }\n}\n\nfunction isBetween (from, to, units, inclusivity) {\n    inclusivity = inclusivity || '()';\n    return (inclusivity[0] === '(' ? this.isAfter(from, units) : !this.isBefore(from, units)) &&\n        (inclusivity[1] === ')' ? this.isBefore(to, units) : !this.isAfter(to, units));\n}\n\nfunction isSame (input, units) {\n    var localInput = isMoment(input) ? input : createLocal(input),\n        inputMs;\n    if (!(this.isValid() && localInput.isValid())) {\n        return false;\n    }\n    units = normalizeUnits(units || 'millisecond');\n    if (units === 'millisecond') {\n        return this.valueOf() === localInput.valueOf();\n    } else {\n        inputMs = localInput.valueOf();\n        return this.clone().startOf(units).valueOf() <= inputMs && inputMs <= this.clone().endOf(units).valueOf();\n    }\n}\n\nfunction isSameOrAfter (input, units) {\n    return this.isSame(input, units) || this.isAfter(input,units);\n}\n\nfunction isSameOrBefore (input, units) {\n    return this.isSame(input, units) || this.isBefore(input,units);\n}\n\nfunction diff (input, units, asFloat) {\n    var that,\n        zoneDelta,\n        delta, output;\n\n    if (!this.isValid()) {\n        return NaN;\n    }\n\n    that = cloneWithOffset(input, this);\n\n    if (!that.isValid()) {\n        return NaN;\n    }\n\n    zoneDelta = (that.utcOffset() - this.utcOffset()) * 6e4;\n\n    units = normalizeUnits(units);\n\n    if (units === 'year' || units === 'month' || units === 'quarter') {\n        output = monthDiff(this, that);\n        if (units === 'quarter') {\n            output = output / 3;\n        } else if (units === 'year') {\n            output = output / 12;\n        }\n    } else {\n        delta = this - that;\n        output = units === 'second' ? delta / 1e3 : // 1000\n            units === 'minute' ? delta / 6e4 : // 1000 * 60\n            units === 'hour' ? delta / 36e5 : // 1000 * 60 * 60\n            units === 'day' ? (delta - zoneDelta) / 864e5 : // 1000 * 60 * 60 * 24, negate dst\n            units === 'week' ? (delta - zoneDelta) / 6048e5 : // 1000 * 60 * 60 * 24 * 7, negate dst\n            delta;\n    }\n    return asFloat ? output : absFloor(output);\n}\n\nfunction monthDiff (a, b) {\n    // difference in months\n    var wholeMonthDiff = ((b.year() - a.year()) * 12) + (b.month() - a.month()),\n        // b is in (anchor - 1 month, anchor + 1 month)\n        anchor = a.clone().add(wholeMonthDiff, 'months'),\n        anchor2, adjust;\n\n    if (b - anchor < 0) {\n        anchor2 = a.clone().add(wholeMonthDiff - 1, 'months');\n        // linear across the month\n        adjust = (b - anchor) / (anchor - anchor2);\n    } else {\n        anchor2 = a.clone().add(wholeMonthDiff + 1, 'months');\n        // linear across the month\n        adjust = (b - anchor) / (anchor2 - anchor);\n    }\n\n    //check for negative zero, return zero if negative zero\n    return -(wholeMonthDiff + adjust) || 0;\n}\n\nhooks.defaultFormat = 'YYYY-MM-DDTHH:mm:ssZ';\nhooks.defaultFormatUtc = 'YYYY-MM-DDTHH:mm:ss[Z]';\n\nfunction toString () {\n    return this.clone().locale('en').format('ddd MMM DD YYYY HH:mm:ss [GMT]ZZ');\n}\n\nfunction toISOString() {\n    if (!this.isValid()) {\n        return null;\n    }\n    var m = this.clone().utc();\n    if (m.year() < 0 || m.year() > 9999) {\n        return formatMoment(m, 'YYYYYY-MM-DD[T]HH:mm:ss.SSS[Z]');\n    }\n    if (isFunction(Date.prototype.toISOString)) {\n        // native implementation is ~50x faster, use it when we can\n        return this.toDate().toISOString();\n    }\n    return formatMoment(m, 'YYYY-MM-DD[T]HH:mm:ss.SSS[Z]');\n}\n\n/**\n * Return a human readable representation of a moment that can\n * also be evaluated to get a new moment which is the same\n *\n * @link https://nodejs.org/dist/latest/docs/api/util.html#util_custom_inspect_function_on_objects\n */\nfunction inspect () {\n    if (!this.isValid()) {\n        return 'moment.invalid(/* ' + this._i + ' */)';\n    }\n    var func = 'moment';\n    var zone = '';\n    if (!this.isLocal()) {\n        func = this.utcOffset() === 0 ? 'moment.utc' : 'moment.parseZone';\n        zone = 'Z';\n    }\n    var prefix = '[' + func + '(\"]';\n    var year = (0 <= this.year() && this.year() <= 9999) ? 'YYYY' : 'YYYYYY';\n    var datetime = '-MM-DD[T]HH:mm:ss.SSS';\n    var suffix = zone + '[\")]';\n\n    return this.format(prefix + year + datetime + suffix);\n}\n\nfunction format (inputString) {\n    if (!inputString) {\n        inputString = this.isUtc() ? hooks.defaultFormatUtc : hooks.defaultFormat;\n    }\n    var output = formatMoment(this, inputString);\n    return this.localeData().postformat(output);\n}\n\nfunction from (time, withoutSuffix) {\n    if (this.isValid() &&\n            ((isMoment(time) && time.isValid()) ||\n             createLocal(time).isValid())) {\n        return createDuration({to: this, from: time}).locale(this.locale()).humanize(!withoutSuffix);\n    } else {\n        return this.localeData().invalidDate();\n    }\n}\n\nfunction fromNow (withoutSuffix) {\n    return this.from(createLocal(), withoutSuffix);\n}\n\nfunction to (time, withoutSuffix) {\n    if (this.isValid() &&\n            ((isMoment(time) && time.isValid()) ||\n             createLocal(time).isValid())) {\n        return createDuration({from: this, to: time}).locale(this.locale()).humanize(!withoutSuffix);\n    } else {\n        return this.localeData().invalidDate();\n    }\n}\n\nfunction toNow (withoutSuffix) {\n    return this.to(createLocal(), withoutSuffix);\n}\n\n// If passed a locale key, it will set the locale for this\n// instance.  Otherwise, it will return the locale configuration\n// variables for this instance.\nfunction locale (key) {\n    var newLocaleData;\n\n    if (key === undefined) {\n        return this._locale._abbr;\n    } else {\n        newLocaleData = getLocale(key);\n        if (newLocaleData != null) {\n            this._locale = newLocaleData;\n        }\n        return this;\n    }\n}\n\nvar lang = deprecate(\n    'moment().lang() is deprecated. Instead, use moment().localeData() to get the language configuration. Use moment().locale() to change languages.',\n    function (key) {\n        if (key === undefined) {\n            return this.localeData();\n        } else {\n            return this.locale(key);\n        }\n    }\n);\n\nfunction localeData () {\n    return this._locale;\n}\n\nfunction startOf (units) {\n    units = normalizeUnits(units);\n    // the following switch intentionally omits break keywords\n    // to utilize falling through the cases.\n    switch (units) {\n        case 'year':\n            this.month(0);\n            /* falls through */\n        case 'quarter':\n        case 'month':\n            this.date(1);\n            /* falls through */\n        case 'week':\n        case 'isoWeek':\n        case 'day':\n        case 'date':\n            this.hours(0);\n            /* falls through */\n        case 'hour':\n            this.minutes(0);\n            /* falls through */\n        case 'minute':\n            this.seconds(0);\n            /* falls through */\n        case 'second':\n            this.milliseconds(0);\n    }\n\n    // weeks are a special case\n    if (units === 'week') {\n        this.weekday(0);\n    }\n    if (units === 'isoWeek') {\n        this.isoWeekday(1);\n    }\n\n    // quarters are also special\n    if (units === 'quarter') {\n        this.month(Math.floor(this.month() / 3) * 3);\n    }\n\n    return this;\n}\n\nfunction endOf (units) {\n    units = normalizeUnits(units);\n    if (units === undefined || units === 'millisecond') {\n        return this;\n    }\n\n    // 'date' is an alias for 'day', so it should be considered as such.\n    if (units === 'date') {\n        units = 'day';\n    }\n\n    return this.startOf(units).add(1, (units === 'isoWeek' ? 'week' : units)).subtract(1, 'ms');\n}\n\nfunction valueOf () {\n    return this._d.valueOf() - ((this._offset || 0) * 60000);\n}\n\nfunction unix () {\n    return Math.floor(this.valueOf() / 1000);\n}\n\nfunction toDate () {\n    return new Date(this.valueOf());\n}\n\nfunction toArray () {\n    var m = this;\n    return [m.year(), m.month(), m.date(), m.hour(), m.minute(), m.second(), m.millisecond()];\n}\n\nfunction toObject () {\n    var m = this;\n    return {\n        years: m.year(),\n        months: m.month(),\n        date: m.date(),\n        hours: m.hours(),\n        minutes: m.minutes(),\n        seconds: m.seconds(),\n        milliseconds: m.milliseconds()\n    };\n}\n\nfunction toJSON () {\n    // new Date(NaN).toJSON() === null\n    return this.isValid() ? this.toISOString() : null;\n}\n\nfunction isValid$2 () {\n    return isValid(this);\n}\n\nfunction parsingFlags () {\n    return extend({}, getParsingFlags(this));\n}\n\nfunction invalidAt () {\n    return getParsingFlags(this).overflow;\n}\n\nfunction creationData() {\n    return {\n        input: this._i,\n        format: this._f,\n        locale: this._locale,\n        isUTC: this._isUTC,\n        strict: this._strict\n    };\n}\n\n// FORMATTING\n\naddFormatToken(0, ['gg', 2], 0, function () {\n    return this.weekYear() % 100;\n});\n\naddFormatToken(0, ['GG', 2], 0, function () {\n    return this.isoWeekYear() % 100;\n});\n\nfunction addWeekYearFormatToken (token, getter) {\n    addFormatToken(0, [token, token.length], 0, getter);\n}\n\naddWeekYearFormatToken('gggg',     'weekYear');\naddWeekYearFormatToken('ggggg',    'weekYear');\naddWeekYearFormatToken('GGGG',  'isoWeekYear');\naddWeekYearFormatToken('GGGGG', 'isoWeekYear');\n\n// ALIASES\n\naddUnitAlias('weekYear', 'gg');\naddUnitAlias('isoWeekYear', 'GG');\n\n// PRIORITY\n\naddUnitPriority('weekYear', 1);\naddUnitPriority('isoWeekYear', 1);\n\n\n// PARSING\n\naddRegexToken('G',      matchSigned);\naddRegexToken('g',      matchSigned);\naddRegexToken('GG',     match1to2, match2);\naddRegexToken('gg',     match1to2, match2);\naddRegexToken('GGGG',   match1to4, match4);\naddRegexToken('gggg',   match1to4, match4);\naddRegexToken('GGGGG',  match1to6, match6);\naddRegexToken('ggggg',  match1to6, match6);\n\naddWeekParseToken(['gggg', 'ggggg', 'GGGG', 'GGGGG'], function (input, week, config, token) {\n    week[token.substr(0, 2)] = toInt(input);\n});\n\naddWeekParseToken(['gg', 'GG'], function (input, week, config, token) {\n    week[token] = hooks.parseTwoDigitYear(input);\n});\n\n// MOMENTS\n\nfunction getSetWeekYear (input) {\n    return getSetWeekYearHelper.call(this,\n            input,\n            this.week(),\n            this.weekday(),\n            this.localeData()._week.dow,\n            this.localeData()._week.doy);\n}\n\nfunction getSetISOWeekYear (input) {\n    return getSetWeekYearHelper.call(this,\n            input, this.isoWeek(), this.isoWeekday(), 1, 4);\n}\n\nfunction getISOWeeksInYear () {\n    return weeksInYear(this.year(), 1, 4);\n}\n\nfunction getWeeksInYear () {\n    var weekInfo = this.localeData()._week;\n    return weeksInYear(this.year(), weekInfo.dow, weekInfo.doy);\n}\n\nfunction getSetWeekYearHelper(input, week, weekday, dow, doy) {\n    var weeksTarget;\n    if (input == null) {\n        return weekOfYear(this, dow, doy).year;\n    } else {\n        weeksTarget = weeksInYear(input, dow, doy);\n        if (week > weeksTarget) {\n            week = weeksTarget;\n        }\n        return setWeekAll.call(this, input, week, weekday, dow, doy);\n    }\n}\n\nfunction setWeekAll(weekYear, week, weekday, dow, doy) {\n    var dayOfYearData = dayOfYearFromWeeks(weekYear, week, weekday, dow, doy),\n        date = createUTCDate(dayOfYearData.year, 0, dayOfYearData.dayOfYear);\n\n    this.year(date.getUTCFullYear());\n    this.month(date.getUTCMonth());\n    this.date(date.getUTCDate());\n    return this;\n}\n\n// FORMATTING\n\naddFormatToken('Q', 0, 'Qo', 'quarter');\n\n// ALIASES\n\naddUnitAlias('quarter', 'Q');\n\n// PRIORITY\n\naddUnitPriority('quarter', 7);\n\n// PARSING\n\naddRegexToken('Q', match1);\naddParseToken('Q', function (input, array) {\n    array[MONTH] = (toInt(input) - 1) * 3;\n});\n\n// MOMENTS\n\nfunction getSetQuarter (input) {\n    return input == null ? Math.ceil((this.month() + 1) / 3) : this.month((input - 1) * 3 + this.month() % 3);\n}\n\n// FORMATTING\n\naddFormatToken('D', ['DD', 2], 'Do', 'date');\n\n// ALIASES\n\naddUnitAlias('date', 'D');\n\n// PRIOROITY\naddUnitPriority('date', 9);\n\n// PARSING\n\naddRegexToken('D',  match1to2);\naddRegexToken('DD', match1to2, match2);\naddRegexToken('Do', function (isStrict, locale) {\n    // TODO: Remove \"ordinalParse\" fallback in next major release.\n    return isStrict ?\n      (locale._dayOfMonthOrdinalParse || locale._ordinalParse) :\n      locale._dayOfMonthOrdinalParseLenient;\n});\n\naddParseToken(['D', 'DD'], DATE);\naddParseToken('Do', function (input, array) {\n    array[DATE] = toInt(input.match(match1to2)[0], 10);\n});\n\n// MOMENTS\n\nvar getSetDayOfMonth = makeGetSet('Date', true);\n\n// FORMATTING\n\naddFormatToken('DDD', ['DDDD', 3], 'DDDo', 'dayOfYear');\n\n// ALIASES\n\naddUnitAlias('dayOfYear', 'DDD');\n\n// PRIORITY\naddUnitPriority('dayOfYear', 4);\n\n// PARSING\n\naddRegexToken('DDD',  match1to3);\naddRegexToken('DDDD', match3);\naddParseToken(['DDD', 'DDDD'], function (input, array, config) {\n    config._dayOfYear = toInt(input);\n});\n\n// HELPERS\n\n// MOMENTS\n\nfunction getSetDayOfYear (input) {\n    var dayOfYear = Math.round((this.clone().startOf('day') - this.clone().startOf('year')) / 864e5) + 1;\n    return input == null ? dayOfYear : this.add((input - dayOfYear), 'd');\n}\n\n// FORMATTING\n\naddFormatToken('m', ['mm', 2], 0, 'minute');\n\n// ALIASES\n\naddUnitAlias('minute', 'm');\n\n// PRIORITY\n\naddUnitPriority('minute', 14);\n\n// PARSING\n\naddRegexToken('m',  match1to2);\naddRegexToken('mm', match1to2, match2);\naddParseToken(['m', 'mm'], MINUTE);\n\n// MOMENTS\n\nvar getSetMinute = makeGetSet('Minutes', false);\n\n// FORMATTING\n\naddFormatToken('s', ['ss', 2], 0, 'second');\n\n// ALIASES\n\naddUnitAlias('second', 's');\n\n// PRIORITY\n\naddUnitPriority('second', 15);\n\n// PARSING\n\naddRegexToken('s',  match1to2);\naddRegexToken('ss', match1to2, match2);\naddParseToken(['s', 'ss'], SECOND);\n\n// MOMENTS\n\nvar getSetSecond = makeGetSet('Seconds', false);\n\n// FORMATTING\n\naddFormatToken('S', 0, 0, function () {\n    return ~~(this.millisecond() / 100);\n});\n\naddFormatToken(0, ['SS', 2], 0, function () {\n    return ~~(this.millisecond() / 10);\n});\n\naddFormatToken(0, ['SSS', 3], 0, 'millisecond');\naddFormatToken(0, ['SSSS', 4], 0, function () {\n    return this.millisecond() * 10;\n});\naddFormatToken(0, ['SSSSS', 5], 0, function () {\n    return this.millisecond() * 100;\n});\naddFormatToken(0, ['SSSSSS', 6], 0, function () {\n    return this.millisecond() * 1000;\n});\naddFormatToken(0, ['SSSSSSS', 7], 0, function () {\n    return this.millisecond() * 10000;\n});\naddFormatToken(0, ['SSSSSSSS', 8], 0, function () {\n    return this.millisecond() * 100000;\n});\naddFormatToken(0, ['SSSSSSSSS', 9], 0, function () {\n    return this.millisecond() * 1000000;\n});\n\n\n// ALIASES\n\naddUnitAlias('millisecond', 'ms');\n\n// PRIORITY\n\naddUnitPriority('millisecond', 16);\n\n// PARSING\n\naddRegexToken('S',    match1to3, match1);\naddRegexToken('SS',   match1to3, match2);\naddRegexToken('SSS',  match1to3, match3);\n\nvar token;\nfor (token = 'SSSS'; token.length <= 9; token += 'S') {\n    addRegexToken(token, matchUnsigned);\n}\n\nfunction parseMs(input, array) {\n    array[MILLISECOND] = toInt(('0.' + input) * 1000);\n}\n\nfor (token = 'S'; token.length <= 9; token += 'S') {\n    addParseToken(token, parseMs);\n}\n// MOMENTS\n\nvar getSetMillisecond = makeGetSet('Milliseconds', false);\n\n// FORMATTING\n\naddFormatToken('z',  0, 0, 'zoneAbbr');\naddFormatToken('zz', 0, 0, 'zoneName');\n\n// MOMENTS\n\nfunction getZoneAbbr () {\n    return this._isUTC ? 'UTC' : '';\n}\n\nfunction getZoneName () {\n    return this._isUTC ? 'Coordinated Universal Time' : '';\n}\n\nvar proto = Moment.prototype;\n\nproto.add               = add;\nproto.calendar          = calendar$1;\nproto.clone             = clone;\nproto.diff              = diff;\nproto.endOf             = endOf;\nproto.format            = format;\nproto.from              = from;\nproto.fromNow           = fromNow;\nproto.to                = to;\nproto.toNow             = toNow;\nproto.get               = stringGet;\nproto.invalidAt         = invalidAt;\nproto.isAfter           = isAfter;\nproto.isBefore          = isBefore;\nproto.isBetween         = isBetween;\nproto.isSame            = isSame;\nproto.isSameOrAfter     = isSameOrAfter;\nproto.isSameOrBefore    = isSameOrBefore;\nproto.isValid           = isValid$2;\nproto.lang              = lang;\nproto.locale            = locale;\nproto.localeData        = localeData;\nproto.max               = prototypeMax;\nproto.min               = prototypeMin;\nproto.parsingFlags      = parsingFlags;\nproto.set               = stringSet;\nproto.startOf           = startOf;\nproto.subtract          = subtract;\nproto.toArray           = toArray;\nproto.toObject          = toObject;\nproto.toDate            = toDate;\nproto.toISOString       = toISOString;\nproto.inspect           = inspect;\nproto.toJSON            = toJSON;\nproto.toString          = toString;\nproto.unix              = unix;\nproto.valueOf           = valueOf;\nproto.creationData      = creationData;\n\n// Year\nproto.year       = getSetYear;\nproto.isLeapYear = getIsLeapYear;\n\n// Week Year\nproto.weekYear    = getSetWeekYear;\nproto.isoWeekYear = getSetISOWeekYear;\n\n// Quarter\nproto.quarter = proto.quarters = getSetQuarter;\n\n// Month\nproto.month       = getSetMonth;\nproto.daysInMonth = getDaysInMonth;\n\n// Week\nproto.week           = proto.weeks        = getSetWeek;\nproto.isoWeek        = proto.isoWeeks     = getSetISOWeek;\nproto.weeksInYear    = getWeeksInYear;\nproto.isoWeeksInYear = getISOWeeksInYear;\n\n// Day\nproto.date       = getSetDayOfMonth;\nproto.day        = proto.days             = getSetDayOfWeek;\nproto.weekday    = getSetLocaleDayOfWeek;\nproto.isoWeekday = getSetISODayOfWeek;\nproto.dayOfYear  = getSetDayOfYear;\n\n// Hour\nproto.hour = proto.hours = getSetHour;\n\n// Minute\nproto.minute = proto.minutes = getSetMinute;\n\n// Second\nproto.second = proto.seconds = getSetSecond;\n\n// Millisecond\nproto.millisecond = proto.milliseconds = getSetMillisecond;\n\n// Offset\nproto.utcOffset            = getSetOffset;\nproto.utc                  = setOffsetToUTC;\nproto.local                = setOffsetToLocal;\nproto.parseZone            = setOffsetToParsedOffset;\nproto.hasAlignedHourOffset = hasAlignedHourOffset;\nproto.isDST                = isDaylightSavingTime;\nproto.isLocal              = isLocal;\nproto.isUtcOffset          = isUtcOffset;\nproto.isUtc                = isUtc;\nproto.isUTC                = isUtc;\n\n// Timezone\nproto.zoneAbbr = getZoneAbbr;\nproto.zoneName = getZoneName;\n\n// Deprecations\nproto.dates  = deprecate('dates accessor is deprecated. Use date instead.', getSetDayOfMonth);\nproto.months = deprecate('months accessor is deprecated. Use month instead', getSetMonth);\nproto.years  = deprecate('years accessor is deprecated. Use year instead', getSetYear);\nproto.zone   = deprecate('moment().zone is deprecated, use moment().utcOffset instead. http://momentjs.com/guides/#/warnings/zone/', getSetZone);\nproto.isDSTShifted = deprecate('isDSTShifted is deprecated. See http://momentjs.com/guides/#/warnings/dst-shifted/ for more information', isDaylightSavingTimeShifted);\n\nfunction createUnix (input) {\n    return createLocal(input * 1000);\n}\n\nfunction createInZone () {\n    return createLocal.apply(null, arguments).parseZone();\n}\n\nfunction preParsePostFormat (string) {\n    return string;\n}\n\nvar proto$1 = Locale.prototype;\n\nproto$1.calendar        = calendar;\nproto$1.longDateFormat  = longDateFormat;\nproto$1.invalidDate     = invalidDate;\nproto$1.ordinal         = ordinal;\nproto$1.preparse        = preParsePostFormat;\nproto$1.postformat      = preParsePostFormat;\nproto$1.relativeTime    = relativeTime;\nproto$1.pastFuture      = pastFuture;\nproto$1.set             = set;\n\n// Month\nproto$1.months            =        localeMonths;\nproto$1.monthsShort       =        localeMonthsShort;\nproto$1.monthsParse       =        localeMonthsParse;\nproto$1.monthsRegex       = monthsRegex;\nproto$1.monthsShortRegex  = monthsShortRegex;\n\n// Week\nproto$1.week = localeWeek;\nproto$1.firstDayOfYear = localeFirstDayOfYear;\nproto$1.firstDayOfWeek = localeFirstDayOfWeek;\n\n// Day of Week\nproto$1.weekdays       =        localeWeekdays;\nproto$1.weekdaysMin    =        localeWeekdaysMin;\nproto$1.weekdaysShort  =        localeWeekdaysShort;\nproto$1.weekdaysParse  =        localeWeekdaysParse;\n\nproto$1.weekdaysRegex       =        weekdaysRegex;\nproto$1.weekdaysShortRegex  =        weekdaysShortRegex;\nproto$1.weekdaysMinRegex    =        weekdaysMinRegex;\n\n// Hours\nproto$1.isPM = localeIsPM;\nproto$1.meridiem = localeMeridiem;\n\nfunction get$1 (format, index, field, setter) {\n    var locale = getLocale();\n    var utc = createUTC().set(setter, index);\n    return locale[field](utc, format);\n}\n\nfunction listMonthsImpl (format, index, field) {\n    if (isNumber(format)) {\n        index = format;\n        format = undefined;\n    }\n\n    format = format || '';\n\n    if (index != null) {\n        return get$1(format, index, field, 'month');\n    }\n\n    var i;\n    var out = [];\n    for (i = 0; i < 12; i++) {\n        out[i] = get$1(format, i, field, 'month');\n    }\n    return out;\n}\n\n// ()\n// (5)\n// (fmt, 5)\n// (fmt)\n// (true)\n// (true, 5)\n// (true, fmt, 5)\n// (true, fmt)\nfunction listWeekdaysImpl (localeSorted, format, index, field) {\n    if (typeof localeSorted === 'boolean') {\n        if (isNumber(format)) {\n            index = format;\n            format = undefined;\n        }\n\n        format = format || '';\n    } else {\n        format = localeSorted;\n        index = format;\n        localeSorted = false;\n\n        if (isNumber(format)) {\n            index = format;\n            format = undefined;\n        }\n\n        format = format || '';\n    }\n\n    var locale = getLocale(),\n        shift = localeSorted ? locale._week.dow : 0;\n\n    if (index != null) {\n        return get$1(format, (index + shift) % 7, field, 'day');\n    }\n\n    var i;\n    var out = [];\n    for (i = 0; i < 7; i++) {\n        out[i] = get$1(format, (i + shift) % 7, field, 'day');\n    }\n    return out;\n}\n\nfunction listMonths (format, index) {\n    return listMonthsImpl(format, index, 'months');\n}\n\nfunction listMonthsShort (format, index) {\n    return listMonthsImpl(format, index, 'monthsShort');\n}\n\nfunction listWeekdays (localeSorted, format, index) {\n    return listWeekdaysImpl(localeSorted, format, index, 'weekdays');\n}\n\nfunction listWeekdaysShort (localeSorted, format, index) {\n    return listWeekdaysImpl(localeSorted, format, index, 'weekdaysShort');\n}\n\nfunction listWeekdaysMin (localeSorted, format, index) {\n    return listWeekdaysImpl(localeSorted, format, index, 'weekdaysMin');\n}\n\ngetSetGlobalLocale('en', {\n    dayOfMonthOrdinalParse: /\\d{1,2}(th|st|nd|rd)/,\n    ordinal : function (number) {\n        var b = number % 10,\n            output = (toInt(number % 100 / 10) === 1) ? 'th' :\n            (b === 1) ? 'st' :\n            (b === 2) ? 'nd' :\n            (b === 3) ? 'rd' : 'th';\n        return number + output;\n    }\n});\n\n// Side effect imports\nhooks.lang = deprecate('moment.lang is deprecated. Use moment.locale instead.', getSetGlobalLocale);\nhooks.langData = deprecate('moment.langData is deprecated. Use moment.localeData instead.', getLocale);\n\nvar mathAbs = Math.abs;\n\nfunction abs () {\n    var data           = this._data;\n\n    this._milliseconds = mathAbs(this._milliseconds);\n    this._days         = mathAbs(this._days);\n    this._months       = mathAbs(this._months);\n\n    data.milliseconds  = mathAbs(data.milliseconds);\n    data.seconds       = mathAbs(data.seconds);\n    data.minutes       = mathAbs(data.minutes);\n    data.hours         = mathAbs(data.hours);\n    data.months        = mathAbs(data.months);\n    data.years         = mathAbs(data.years);\n\n    return this;\n}\n\nfunction addSubtract$1 (duration, input, value, direction) {\n    var other = createDuration(input, value);\n\n    duration._milliseconds += direction * other._milliseconds;\n    duration._days         += direction * other._days;\n    duration._months       += direction * other._months;\n\n    return duration._bubble();\n}\n\n// supports only 2.0-style add(1, 's') or add(duration)\nfunction add$1 (input, value) {\n    return addSubtract$1(this, input, value, 1);\n}\n\n// supports only 2.0-style subtract(1, 's') or subtract(duration)\nfunction subtract$1 (input, value) {\n    return addSubtract$1(this, input, value, -1);\n}\n\nfunction absCeil (number) {\n    if (number < 0) {\n        return Math.floor(number);\n    } else {\n        return Math.ceil(number);\n    }\n}\n\nfunction bubble () {\n    var milliseconds = this._milliseconds;\n    var days         = this._days;\n    var months       = this._months;\n    var data         = this._data;\n    var seconds, minutes, hours, years, monthsFromDays;\n\n    // if we have a mix of positive and negative values, bubble down first\n    // check: https://github.com/moment/moment/issues/2166\n    if (!((milliseconds >= 0 && days >= 0 && months >= 0) ||\n            (milliseconds <= 0 && days <= 0 && months <= 0))) {\n        milliseconds += absCeil(monthsToDays(months) + days) * 864e5;\n        days = 0;\n        months = 0;\n    }\n\n    // The following code bubbles up values, see the tests for\n    // examples of what that means.\n    data.milliseconds = milliseconds % 1000;\n\n    seconds           = absFloor(milliseconds / 1000);\n    data.seconds      = seconds % 60;\n\n    minutes           = absFloor(seconds / 60);\n    data.minutes      = minutes % 60;\n\n    hours             = absFloor(minutes / 60);\n    data.hours        = hours % 24;\n\n    days += absFloor(hours / 24);\n\n    // convert days to months\n    monthsFromDays = absFloor(daysToMonths(days));\n    months += monthsFromDays;\n    days -= absCeil(monthsToDays(monthsFromDays));\n\n    // 12 months -> 1 year\n    years = absFloor(months / 12);\n    months %= 12;\n\n    data.days   = days;\n    data.months = months;\n    data.years  = years;\n\n    return this;\n}\n\nfunction daysToMonths (days) {\n    // 400 years have 146097 days (taking into account leap year rules)\n    // 400 years have 12 months === 4800\n    return days * 4800 / 146097;\n}\n\nfunction monthsToDays (months) {\n    // the reverse of daysToMonths\n    return months * 146097 / 4800;\n}\n\nfunction as (units) {\n    if (!this.isValid()) {\n        return NaN;\n    }\n    var days;\n    var months;\n    var milliseconds = this._milliseconds;\n\n    units = normalizeUnits(units);\n\n    if (units === 'month' || units === 'year') {\n        days   = this._days   + milliseconds / 864e5;\n        months = this._months + daysToMonths(days);\n        return units === 'month' ? months : months / 12;\n    } else {\n        // handle milliseconds separately because of floating point math errors (issue #1867)\n        days = this._days + Math.round(monthsToDays(this._months));\n        switch (units) {\n            case 'week'   : return days / 7     + milliseconds / 6048e5;\n            case 'day'    : return days         + milliseconds / 864e5;\n            case 'hour'   : return days * 24    + milliseconds / 36e5;\n            case 'minute' : return days * 1440  + milliseconds / 6e4;\n            case 'second' : return days * 86400 + milliseconds / 1000;\n            // Math.floor prevents floating point math errors here\n            case 'millisecond': return Math.floor(days * 864e5) + milliseconds;\n            default: throw new Error('Unknown unit ' + units);\n        }\n    }\n}\n\n// TODO: Use this.as('ms')?\nfunction valueOf$1 () {\n    if (!this.isValid()) {\n        return NaN;\n    }\n    return (\n        this._milliseconds +\n        this._days * 864e5 +\n        (this._months % 12) * 2592e6 +\n        toInt(this._months / 12) * 31536e6\n    );\n}\n\nfunction makeAs (alias) {\n    return function () {\n        return this.as(alias);\n    };\n}\n\nvar asMilliseconds = makeAs('ms');\nvar asSeconds      = makeAs('s');\nvar asMinutes      = makeAs('m');\nvar asHours        = makeAs('h');\nvar asDays         = makeAs('d');\nvar asWeeks        = makeAs('w');\nvar asMonths       = makeAs('M');\nvar asYears        = makeAs('y');\n\nfunction get$2 (units) {\n    units = normalizeUnits(units);\n    return this.isValid() ? this[units + 's']() : NaN;\n}\n\nfunction makeGetter(name) {\n    return function () {\n        return this.isValid() ? this._data[name] : NaN;\n    };\n}\n\nvar milliseconds = makeGetter('milliseconds');\nvar seconds      = makeGetter('seconds');\nvar minutes      = makeGetter('minutes');\nvar hours        = makeGetter('hours');\nvar days         = makeGetter('days');\nvar months       = makeGetter('months');\nvar years        = makeGetter('years');\n\nfunction weeks () {\n    return absFloor(this.days() / 7);\n}\n\nvar round = Math.round;\nvar thresholds = {\n    ss: 44,         // a few seconds to seconds\n    s : 45,         // seconds to minute\n    m : 45,         // minutes to hour\n    h : 22,         // hours to day\n    d : 26,         // days to month\n    M : 11          // months to year\n};\n\n// helper function for moment.fn.from, moment.fn.fromNow, and moment.duration.fn.humanize\nfunction substituteTimeAgo(string, number, withoutSuffix, isFuture, locale) {\n    return locale.relativeTime(number || 1, !!withoutSuffix, string, isFuture);\n}\n\nfunction relativeTime$1 (posNegDuration, withoutSuffix, locale) {\n    var duration = createDuration(posNegDuration).abs();\n    var seconds  = round(duration.as('s'));\n    var minutes  = round(duration.as('m'));\n    var hours    = round(duration.as('h'));\n    var days     = round(duration.as('d'));\n    var months   = round(duration.as('M'));\n    var years    = round(duration.as('y'));\n\n    var a = seconds <= thresholds.ss && ['s', seconds]  ||\n            seconds < thresholds.s   && ['ss', seconds] ||\n            minutes <= 1             && ['m']           ||\n            minutes < thresholds.m   && ['mm', minutes] ||\n            hours   <= 1             && ['h']           ||\n            hours   < thresholds.h   && ['hh', hours]   ||\n            days    <= 1             && ['d']           ||\n            days    < thresholds.d   && ['dd', days]    ||\n            months  <= 1             && ['M']           ||\n            months  < thresholds.M   && ['MM', months]  ||\n            years   <= 1             && ['y']           || ['yy', years];\n\n    a[2] = withoutSuffix;\n    a[3] = +posNegDuration > 0;\n    a[4] = locale;\n    return substituteTimeAgo.apply(null, a);\n}\n\n// This function allows you to set the rounding function for relative time strings\nfunction getSetRelativeTimeRounding (roundingFunction) {\n    if (roundingFunction === undefined) {\n        return round;\n    }\n    if (typeof(roundingFunction) === 'function') {\n        round = roundingFunction;\n        return true;\n    }\n    return false;\n}\n\n// This function allows you to set a threshold for relative time strings\nfunction getSetRelativeTimeThreshold (threshold, limit) {\n    if (thresholds[threshold] === undefined) {\n        return false;\n    }\n    if (limit === undefined) {\n        return thresholds[threshold];\n    }\n    thresholds[threshold] = limit;\n    if (threshold === 's') {\n        thresholds.ss = limit - 1;\n    }\n    return true;\n}\n\nfunction humanize (withSuffix) {\n    if (!this.isValid()) {\n        return this.localeData().invalidDate();\n    }\n\n    var locale = this.localeData();\n    var output = relativeTime$1(this, !withSuffix, locale);\n\n    if (withSuffix) {\n        output = locale.pastFuture(+this, output);\n    }\n\n    return locale.postformat(output);\n}\n\nvar abs$1 = Math.abs;\n\nfunction toISOString$1() {\n    // for ISO strings we do not use the normal bubbling rules:\n    //  * milliseconds bubble up until they become hours\n    //  * days do not bubble at all\n    //  * months bubble up until they become years\n    // This is because there is no context-free conversion between hours and days\n    // (think of clock changes)\n    // and also not between days and months (28-31 days per month)\n    if (!this.isValid()) {\n        return this.localeData().invalidDate();\n    }\n\n    var seconds = abs$1(this._milliseconds) / 1000;\n    var days         = abs$1(this._days);\n    var months       = abs$1(this._months);\n    var minutes, hours, years;\n\n    // 3600 seconds -> 60 minutes -> 1 hour\n    minutes           = absFloor(seconds / 60);\n    hours             = absFloor(minutes / 60);\n    seconds %= 60;\n    minutes %= 60;\n\n    // 12 months -> 1 year\n    years  = absFloor(months / 12);\n    months %= 12;\n\n\n    // inspired by https://github.com/dordille/moment-isoduration/blob/master/moment.isoduration.js\n    var Y = years;\n    var M = months;\n    var D = days;\n    var h = hours;\n    var m = minutes;\n    var s = seconds;\n    var total = this.asSeconds();\n\n    if (!total) {\n        // this is the same as C#'s (Noda) and python (isodate)...\n        // but not other JS (goog.date)\n        return 'P0D';\n    }\n\n    return (total < 0 ? '-' : '') +\n        'P' +\n        (Y ? Y + 'Y' : '') +\n        (M ? M + 'M' : '') +\n        (D ? D + 'D' : '') +\n        ((h || m || s) ? 'T' : '') +\n        (h ? h + 'H' : '') +\n        (m ? m + 'M' : '') +\n        (s ? s + 'S' : '');\n}\n\nvar proto$2 = Duration.prototype;\n\nproto$2.isValid        = isValid$1;\nproto$2.abs            = abs;\nproto$2.add            = add$1;\nproto$2.subtract       = subtract$1;\nproto$2.as             = as;\nproto$2.asMilliseconds = asMilliseconds;\nproto$2.asSeconds      = asSeconds;\nproto$2.asMinutes      = asMinutes;\nproto$2.asHours        = asHours;\nproto$2.asDays         = asDays;\nproto$2.asWeeks        = asWeeks;\nproto$2.asMonths       = asMonths;\nproto$2.asYears        = asYears;\nproto$2.valueOf        = valueOf$1;\nproto$2._bubble        = bubble;\nproto$2.get            = get$2;\nproto$2.milliseconds   = milliseconds;\nproto$2.seconds        = seconds;\nproto$2.minutes        = minutes;\nproto$2.hours          = hours;\nproto$2.days           = days;\nproto$2.weeks          = weeks;\nproto$2.months         = months;\nproto$2.years          = years;\nproto$2.humanize       = humanize;\nproto$2.toISOString    = toISOString$1;\nproto$2.toString       = toISOString$1;\nproto$2.toJSON         = toISOString$1;\nproto$2.locale         = locale;\nproto$2.localeData     = localeData;\n\n// Deprecations\nproto$2.toIsoString = deprecate('toIsoString() is deprecated. Please use toISOString() instead (notice the capitals)', toISOString$1);\nproto$2.lang = lang;\n\n// Side effect imports\n\n// FORMATTING\n\naddFormatToken('X', 0, 0, 'unix');\naddFormatToken('x', 0, 0, 'valueOf');\n\n// PARSING\n\naddRegexToken('x', matchSigned);\naddRegexToken('X', matchTimestamp);\naddParseToken('X', function (input, array, config) {\n    config._d = new Date(parseFloat(input, 10) * 1000);\n});\naddParseToken('x', function (input, array, config) {\n    config._d = new Date(toInt(input));\n});\n\n// Side effect imports\n\n\nhooks.version = '2.18.1';\n\nsetHookCallback(createLocal);\n\nhooks.fn                    = proto;\nhooks.min                   = min;\nhooks.max                   = max;\nhooks.now                   = now;\nhooks.utc                   = createUTC;\nhooks.unix                  = createUnix;\nhooks.months                = listMonths;\nhooks.isDate                = isDate;\nhooks.locale                = getSetGlobalLocale;\nhooks.invalid               = createInvalid;\nhooks.duration              = createDuration;\nhooks.isMoment              = isMoment;\nhooks.weekdays              = listWeekdays;\nhooks.parseZone             = createInZone;\nhooks.localeData            = getLocale;\nhooks.isDuration            = isDuration;\nhooks.monthsShort           = listMonthsShort;\nhooks.weekdaysMin           = listWeekdaysMin;\nhooks.defineLocale          = defineLocale;\nhooks.updateLocale          = updateLocale;\nhooks.locales               = listLocales;\nhooks.weekdaysShort         = listWeekdaysShort;\nhooks.normalizeUnits        = normalizeUnits;\nhooks.relativeTimeRounding = getSetRelativeTimeRounding;\nhooks.relativeTimeThreshold = getSetRelativeTimeThreshold;\nhooks.calendarFormat        = getCalendarFormat;\nhooks.prototype             = proto;\n\nreturn hooks;\n\n})));\n\n},{}],7:[function(require,module,exports){\n/**\n * @namespace Chart\n */\nvar Chart = require(28)();\n\nrequire(26)(Chart);\nrequire(40)(Chart);\nrequire(22)(Chart);\nrequire(25)(Chart);\nrequire(30)(Chart);\nrequire(21)(Chart);\nrequire(23)(Chart);\nrequire(24)(Chart);\nrequire(29)(Chart);\nrequire(32)(Chart);\nrequire(33)(Chart);\nrequire(31)(Chart);\nrequire(27)(Chart);\nrequire(34)(Chart);\n\nrequire(35)(Chart);\nrequire(36)(Chart);\nrequire(37)(Chart);\nrequire(38)(Chart);\n\nrequire(46)(Chart);\nrequire(44)(Chart);\nrequire(45)(Chart);\nrequire(47)(Chart);\nrequire(48)(Chart);\nrequire(49)(Chart);\n\n// Controllers must be loaded after elements\n// See Chart.core.datasetController.dataElementType\nrequire(15)(Chart);\nrequire(16)(Chart);\nrequire(17)(Chart);\nrequire(18)(Chart);\nrequire(19)(Chart);\nrequire(20)(Chart);\n\nrequire(8)(Chart);\nrequire(9)(Chart);\nrequire(10)(Chart);\nrequire(11)(Chart);\nrequire(12)(Chart);\nrequire(13)(Chart);\nrequire(14)(Chart);\n\n// Loading built-it plugins\nvar plugins = [];\n\nplugins.push(\n    require(41)(Chart),\n    require(42)(Chart),\n    require(43)(Chart)\n);\n\nChart.plugins.register(plugins);\n\nmodule.exports = Chart;\nif (typeof window !== 'undefined') {\n\twindow.Chart = Chart;\n}\n\n},{\"10\":10,\"11\":11,\"12\":12,\"13\":13,\"14\":14,\"15\":15,\"16\":16,\"17\":17,\"18\":18,\"19\":19,\"20\":20,\"21\":21,\"22\":22,\"23\":23,\"24\":24,\"25\":25,\"26\":26,\"27\":27,\"28\":28,\"29\":29,\"30\":30,\"31\":31,\"32\":32,\"33\":33,\"34\":34,\"35\":35,\"36\":36,\"37\":37,\"38\":38,\"40\":40,\"41\":41,\"42\":42,\"43\":43,\"44\":44,\"45\":45,\"46\":46,\"47\":47,\"48\":48,\"49\":49,\"8\":8,\"9\":9}],8:[function(require,module,exports){\n'use strict';\n\nmodule.exports = function(Chart) {\n\n\tChart.Bar = function(context, config) {\n\t\tconfig.type = 'bar';\n\n\t\treturn new Chart(context, config);\n\t};\n\n};\n\n},{}],9:[function(require,module,exports){\n'use strict';\n\nmodule.exports = function(Chart) {\n\n\tChart.Bubble = function(context, config) {\n\t\tconfig.type = 'bubble';\n\t\treturn new Chart(context, config);\n\t};\n\n};\n\n},{}],10:[function(require,module,exports){\n'use strict';\n\nmodule.exports = function(Chart) {\n\n\tChart.Doughnut = function(context, config) {\n\t\tconfig.type = 'doughnut';\n\n\t\treturn new Chart(context, config);\n\t};\n\n};\n\n},{}],11:[function(require,module,exports){\n'use strict';\n\nmodule.exports = function(Chart) {\n\n\tChart.Line = function(context, config) {\n\t\tconfig.type = 'line';\n\n\t\treturn new Chart(context, config);\n\t};\n\n};\n\n},{}],12:[function(require,module,exports){\n'use strict';\n\nmodule.exports = function(Chart) {\n\n\tChart.PolarArea = function(context, config) {\n\t\tconfig.type = 'polarArea';\n\n\t\treturn new Chart(context, config);\n\t};\n\n};\n\n},{}],13:[function(require,module,exports){\n'use strict';\n\nmodule.exports = function(Chart) {\n\n\tChart.Radar = function(context, config) {\n\t\tconfig.type = 'radar';\n\n\t\treturn new Chart(context, config);\n\t};\n\n};\n\n},{}],14:[function(require,module,exports){\n'use strict';\n\nmodule.exports = function(Chart) {\n\n\tvar defaultConfig = {\n\t\thover: {\n\t\t\tmode: 'single'\n\t\t},\n\n\t\tscales: {\n\t\t\txAxes: [{\n\t\t\t\ttype: 'linear', // scatter should not use a category axis\n\t\t\t\tposition: 'bottom',\n\t\t\t\tid: 'x-axis-1' // need an ID so datasets can reference the scale\n\t\t\t}],\n\t\t\tyAxes: [{\n\t\t\t\ttype: 'linear',\n\t\t\t\tposition: 'left',\n\t\t\t\tid: 'y-axis-1'\n\t\t\t}]\n\t\t},\n\n\t\ttooltips: {\n\t\t\tcallbacks: {\n\t\t\t\ttitle: function() {\n\t\t\t\t\t// Title doesn't make sense for scatter since we format the data as a point\n\t\t\t\t\treturn '';\n\t\t\t\t},\n\t\t\t\tlabel: function(tooltipItem) {\n\t\t\t\t\treturn '(' + tooltipItem.xLabel + ', ' + tooltipItem.yLabel + ')';\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t};\n\n\t// Register the default config for this type\n\tChart.defaults.scatter = defaultConfig;\n\n\t// Scatter charts use line controllers\n\tChart.controllers.scatter = Chart.controllers.line;\n\n\tChart.Scatter = function(context, config) {\n\t\tconfig.type = 'scatter';\n\t\treturn new Chart(context, config);\n\t};\n\n};\n\n},{}],15:[function(require,module,exports){\n'use strict';\n\nmodule.exports = function(Chart) {\n\n\tvar helpers = Chart.helpers;\n\n\tChart.defaults.bar = {\n\t\thover: {\n\t\t\tmode: 'label'\n\t\t},\n\n\t\tscales: {\n\t\t\txAxes: [{\n\t\t\t\ttype: 'category',\n\n\t\t\t\t// Specific to Bar Controller\n\t\t\t\tcategoryPercentage: 0.8,\n\t\t\t\tbarPercentage: 0.9,\n\n\t\t\t\t// grid line settings\n\t\t\t\tgridLines: {\n\t\t\t\t\toffsetGridLines: true\n\t\t\t\t}\n\t\t\t}],\n\t\t\tyAxes: [{\n\t\t\t\ttype: 'linear'\n\t\t\t}]\n\t\t}\n\t};\n\n\tChart.controllers.bar = Chart.DatasetController.extend({\n\n\t\tdataElementType: Chart.elements.Rectangle,\n\n\t\tinitialize: function() {\n\t\t\tvar me = this;\n\t\t\tvar meta;\n\n\t\t\tChart.DatasetController.prototype.initialize.apply(me, arguments);\n\n\t\t\tmeta = me.getMeta();\n\t\t\tmeta.stack = me.getDataset().stack;\n\t\t\tmeta.bar = true;\n\t\t},\n\n\t\tupdate: function(reset) {\n\t\t\tvar me = this;\n\t\t\tvar elements = me.getMeta().data;\n\t\t\tvar i, ilen;\n\n\t\t\tme._ruler = me.getRuler();\n\n\t\t\tfor (i = 0, ilen = elements.length; i < ilen; ++i) {\n\t\t\t\tme.updateElement(elements[i], i, reset);\n\t\t\t}\n\t\t},\n\n\t\tupdateElement: function(rectangle, index, reset) {\n\t\t\tvar me = this;\n\t\t\tvar chart = me.chart;\n\t\t\tvar meta = me.getMeta();\n\t\t\tvar dataset = me.getDataset();\n\t\t\tvar custom = rectangle.custom || {};\n\t\t\tvar rectangleOptions = chart.options.elements.rectangle;\n\n\t\t\trectangle._xScale = me.getScaleForId(meta.xAxisID);\n\t\t\trectangle._yScale = me.getScaleForId(meta.yAxisID);\n\t\t\trectangle._datasetIndex = me.index;\n\t\t\trectangle._index = index;\n\n\t\t\trectangle._model = {\n\t\t\t\tdatasetLabel: dataset.label,\n\t\t\t\tlabel: chart.data.labels[index],\n\t\t\t\tborderSkipped: custom.borderSkipped ? custom.borderSkipped : rectangleOptions.borderSkipped,\n\t\t\t\tbackgroundColor: custom.backgroundColor ? custom.backgroundColor : helpers.getValueAtIndexOrDefault(dataset.backgroundColor, index, rectangleOptions.backgroundColor),\n\t\t\t\tborderColor: custom.borderColor ? custom.borderColor : helpers.getValueAtIndexOrDefault(dataset.borderColor, index, rectangleOptions.borderColor),\n\t\t\t\tborderWidth: custom.borderWidth ? custom.borderWidth : helpers.getValueAtIndexOrDefault(dataset.borderWidth, index, rectangleOptions.borderWidth)\n\t\t\t};\n\n\t\t\tme.updateElementGeometry(rectangle, index, reset);\n\n\t\t\trectangle.pivot();\n\t\t},\n\n\t\t/**\n\t\t * @private\n\t\t */\n\t\tupdateElementGeometry: function(rectangle, index, reset) {\n\t\t\tvar me = this;\n\t\t\tvar model = rectangle._model;\n\t\t\tvar vscale = me.getValueScale();\n\t\t\tvar base = vscale.getBasePixel();\n\t\t\tvar horizontal = vscale.isHorizontal();\n\t\t\tvar ruler = me._ruler || me.getRuler();\n\t\t\tvar vpixels = me.calculateBarValuePixels(me.index, index);\n\t\t\tvar ipixels = me.calculateBarIndexPixels(me.index, index, ruler);\n\n\t\t\tmodel.horizontal = horizontal;\n\t\t\tmodel.base = reset? base : vpixels.base;\n\t\t\tmodel.x = horizontal? reset? base : vpixels.head : ipixels.center;\n\t\t\tmodel.y = horizontal? ipixels.center : reset? base : vpixels.head;\n\t\t\tmodel.height = horizontal? ipixels.size : undefined;\n\t\t\tmodel.width = horizontal? undefined : ipixels.size;\n\t\t},\n\n\t\t/**\n\t\t * @private\n\t\t */\n\t\tgetValueScaleId: function() {\n\t\t\treturn this.getMeta().yAxisID;\n\t\t},\n\n\t\t/**\n\t\t * @private\n\t\t */\n\t\tgetIndexScaleId: function() {\n\t\t\treturn this.getMeta().xAxisID;\n\t\t},\n\n\t\t/**\n\t\t * @private\n\t\t */\n\t\tgetValueScale: function() {\n\t\t\treturn this.getScaleForId(this.getValueScaleId());\n\t\t},\n\n\t\t/**\n\t\t * @private\n\t\t */\n\t\tgetIndexScale: function() {\n\t\t\treturn this.getScaleForId(this.getIndexScaleId());\n\t\t},\n\n\t\t/**\n\t\t * Returns the effective number of stacks based on groups and bar visibility.\n\t\t * @private\n\t\t */\n\t\tgetStackCount: function(last) {\n\t\t\tvar me = this;\n\t\t\tvar chart = me.chart;\n\t\t\tvar scale = me.getIndexScale();\n\t\t\tvar stacked = scale.options.stacked;\n\t\t\tvar ilen = last === undefined? chart.data.datasets.length : last + 1;\n\t\t\tvar stacks = [];\n\t\t\tvar i, meta;\n\n\t\t\tfor (i = 0; i < ilen; ++i) {\n\t\t\t\tmeta = chart.getDatasetMeta(i);\n\t\t\t\tif (meta.bar && chart.isDatasetVisible(i) &&\n\t\t\t\t\t(stacked === false ||\n\t\t\t\t\t(stacked === true && stacks.indexOf(meta.stack) === -1) ||\n\t\t\t\t\t(stacked === undefined && (meta.stack === undefined || stacks.indexOf(meta.stack) === -1)))) {\n\t\t\t\t\tstacks.push(meta.stack);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn stacks.length;\n\t\t},\n\n\t\t/**\n\t\t * Returns the stack index for the given dataset based on groups and bar visibility.\n\t\t * @private\n\t\t */\n\t\tgetStackIndex: function(datasetIndex) {\n\t\t\treturn this.getStackCount(datasetIndex) - 1;\n\t\t},\n\n\t\t/**\n\t\t * @private\n\t\t */\n\t\tgetRuler: function() {\n\t\t\tvar me = this;\n\t\t\tvar scale = me.getIndexScale();\n\t\t\tvar options = scale.options;\n\t\t\tvar stackCount = me.getStackCount();\n\t\t\tvar fullSize = scale.isHorizontal()? scale.width : scale.height;\n\t\t\tvar tickSize = fullSize / scale.ticks.length;\n\t\t\tvar categorySize = tickSize * options.categoryPercentage;\n\t\t\tvar fullBarSize = categorySize / stackCount;\n\t\t\tvar barSize = fullBarSize * options.barPercentage;\n\n\t\t\tbarSize = Math.min(\n\t\t\t\thelpers.getValueOrDefault(options.barThickness, barSize),\n\t\t\t\thelpers.getValueOrDefault(options.maxBarThickness, Infinity));\n\n\t\t\treturn {\n\t\t\t\tstackCount: stackCount,\n\t\t\t\ttickSize: tickSize,\n\t\t\t\tcategorySize: categorySize,\n\t\t\t\tcategorySpacing: tickSize - categorySize,\n\t\t\t\tfullBarSize: fullBarSize,\n\t\t\t\tbarSize: barSize,\n\t\t\t\tbarSpacing: fullBarSize - barSize,\n\t\t\t\tscale: scale\n\t\t\t};\n\t\t},\n\n\t\t/**\n\t\t * Note: pixel values are not clamped to the scale area.\n\t\t * @private\n\t\t */\n\t\tcalculateBarValuePixels: function(datasetIndex, index) {\n\t\t\tvar me = this;\n\t\t\tvar chart = me.chart;\n\t\t\tvar meta = me.getMeta();\n\t\t\tvar scale = me.getValueScale();\n\t\t\tvar datasets = chart.data.datasets;\n\t\t\tvar value = Number(datasets[datasetIndex].data[index]);\n\t\t\tvar stacked = scale.options.stacked;\n\t\t\tvar stack = meta.stack;\n\t\t\tvar start = 0;\n\t\t\tvar i, imeta, ivalue, base, head, size;\n\n\t\t\tif (stacked || (stacked === undefined && stack !== undefined)) {\n\t\t\t\tfor (i = 0; i < datasetIndex; ++i) {\n\t\t\t\t\timeta = chart.getDatasetMeta(i);\n\n\t\t\t\t\tif (imeta.bar &&\n\t\t\t\t\t\timeta.stack === stack &&\n\t\t\t\t\t\timeta.controller.getValueScaleId() === scale.id &&\n\t\t\t\t\t\tchart.isDatasetVisible(i)) {\n\n\t\t\t\t\t\tivalue = Number(datasets[i].data[index]);\n\t\t\t\t\t\tif ((value < 0 && ivalue < 0) || (value >= 0 && ivalue > 0)) {\n\t\t\t\t\t\t\tstart += ivalue;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tbase = scale.getPixelForValue(start);\n\t\t\thead = scale.getPixelForValue(start + value);\n\t\t\tsize = (head - base) / 2;\n\n\t\t\treturn {\n\t\t\t\tsize: size,\n\t\t\t\tbase: base,\n\t\t\t\thead: head,\n\t\t\t\tcenter: head + size / 2\n\t\t\t};\n\t\t},\n\n\t\t/**\n\t\t * @private\n\t\t */\n\t\tcalculateBarIndexPixels: function(datasetIndex, index, ruler) {\n\t\t\tvar me = this;\n\t\t\tvar scale = ruler.scale;\n\t\t\tvar isCombo = me.chart.isCombo;\n\t\t\tvar stackIndex = me.getStackIndex(datasetIndex);\n\t\t\tvar base = scale.getPixelForValue(null, index, datasetIndex, isCombo);\n\t\t\tvar size = ruler.barSize;\n\n\t\t\tbase -= isCombo? ruler.tickSize / 2 : 0;\n\t\t\tbase += ruler.fullBarSize * stackIndex;\n\t\t\tbase += ruler.categorySpacing / 2;\n\t\t\tbase += ruler.barSpacing / 2;\n\n\t\t\treturn {\n\t\t\t\tsize: size,\n\t\t\t\tbase: base,\n\t\t\t\thead: base + size,\n\t\t\t\tcenter: base + size / 2\n\t\t\t};\n\t\t},\n\n\t\tdraw: function() {\n\t\t\tvar me = this;\n\t\t\tvar chart = me.chart;\n\t\t\tvar elements = me.getMeta().data;\n\t\t\tvar dataset = me.getDataset();\n\t\t\tvar ilen = elements.length;\n\t\t\tvar i = 0;\n\t\t\tvar d;\n\n\t\t\thelpers.canvas.clipArea(chart.ctx, chart.chartArea);\n\n\t\t\tfor (; i<ilen; ++i) {\n\t\t\t\td = dataset.data[i];\n\t\t\t\tif (d !== null && d !== undefined && !isNaN(d)) {\n\t\t\t\t\telements[i].draw();\n\t\t\t\t}\n\t\t\t}\n\n\t\t\thelpers.canvas.unclipArea(chart.ctx);\n\t\t},\n\n\t\tsetHoverStyle: function(rectangle) {\n\t\t\tvar dataset = this.chart.data.datasets[rectangle._datasetIndex];\n\t\t\tvar index = rectangle._index;\n\t\t\tvar custom = rectangle.custom || {};\n\t\t\tvar model = rectangle._model;\n\n\t\t\tmodel.backgroundColor = custom.hoverBackgroundColor ? custom.hoverBackgroundColor : helpers.getValueAtIndexOrDefault(dataset.hoverBackgroundColor, index, helpers.getHoverColor(model.backgroundColor));\n\t\t\tmodel.borderColor = custom.hoverBorderColor ? custom.hoverBorderColor : helpers.getValueAtIndexOrDefault(dataset.hoverBorderColor, index, helpers.getHoverColor(model.borderColor));\n\t\t\tmodel.borderWidth = custom.hoverBorderWidth ? custom.hoverBorderWidth : helpers.getValueAtIndexOrDefault(dataset.hoverBorderWidth, index, model.borderWidth);\n\t\t},\n\n\t\tremoveHoverStyle: function(rectangle) {\n\t\t\tvar dataset = this.chart.data.datasets[rectangle._datasetIndex];\n\t\t\tvar index = rectangle._index;\n\t\t\tvar custom = rectangle.custom || {};\n\t\t\tvar model = rectangle._model;\n\t\t\tvar rectangleElementOptions = this.chart.options.elements.rectangle;\n\n\t\t\tmodel.backgroundColor = custom.backgroundColor ? custom.backgroundColor : helpers.getValueAtIndexOrDefault(dataset.backgroundColor, index, rectangleElementOptions.backgroundColor);\n\t\t\tmodel.borderColor = custom.borderColor ? custom.borderColor : helpers.getValueAtIndexOrDefault(dataset.borderColor, index, rectangleElementOptions.borderColor);\n\t\t\tmodel.borderWidth = custom.borderWidth ? custom.borderWidth : helpers.getValueAtIndexOrDefault(dataset.borderWidth, index, rectangleElementOptions.borderWidth);\n\t\t}\n\t});\n\n\n\t// including horizontalBar in the bar file, instead of a file of its own\n\t// it extends bar (like pie extends doughnut)\n\tChart.defaults.horizontalBar = {\n\t\thover: {\n\t\t\tmode: 'label'\n\t\t},\n\n\t\tscales: {\n\t\t\txAxes: [{\n\t\t\t\ttype: 'linear',\n\t\t\t\tposition: 'bottom'\n\t\t\t}],\n\t\t\tyAxes: [{\n\t\t\t\tposition: 'left',\n\t\t\t\ttype: 'category',\n\n\t\t\t\t// Specific to Horizontal Bar Controller\n\t\t\t\tcategoryPercentage: 0.8,\n\t\t\t\tbarPercentage: 0.9,\n\n\t\t\t\t// grid line settings\n\t\t\t\tgridLines: {\n\t\t\t\t\toffsetGridLines: true\n\t\t\t\t}\n\t\t\t}]\n\t\t},\n\t\telements: {\n\t\t\trectangle: {\n\t\t\t\tborderSkipped: 'left'\n\t\t\t}\n\t\t},\n\t\ttooltips: {\n\t\t\tcallbacks: {\n\t\t\t\ttitle: function(tooltipItems, data) {\n\t\t\t\t\t// Pick first xLabel for now\n\t\t\t\t\tvar title = '';\n\n\t\t\t\t\tif (tooltipItems.length > 0) {\n\t\t\t\t\t\tif (tooltipItems[0].yLabel) {\n\t\t\t\t\t\t\ttitle = tooltipItems[0].yLabel;\n\t\t\t\t\t\t} else if (data.labels.length > 0 && tooltipItems[0].index < data.labels.length) {\n\t\t\t\t\t\t\ttitle = data.labels[tooltipItems[0].index];\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\treturn title;\n\t\t\t\t},\n\t\t\t\tlabel: function(tooltipItem, data) {\n\t\t\t\t\tvar datasetLabel = data.datasets[tooltipItem.datasetIndex].label || '';\n\t\t\t\t\treturn datasetLabel + ': ' + tooltipItem.xLabel;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t};\n\n\tChart.controllers.horizontalBar = Chart.controllers.bar.extend({\n\t\t/**\n\t\t * @private\n\t\t */\n\t\tgetValueScaleId: function() {\n\t\t\treturn this.getMeta().xAxisID;\n\t\t},\n\n\t\t/**\n\t\t * @private\n\t\t */\n\t\tgetIndexScaleId: function() {\n\t\t\treturn this.getMeta().yAxisID;\n\t\t}\n\t});\n};\n\n},{}],16:[function(require,module,exports){\n'use strict';\n\nmodule.exports = function(Chart) {\n\n\tvar helpers = Chart.helpers;\n\n\tChart.defaults.bubble = {\n\t\thover: {\n\t\t\tmode: 'single'\n\t\t},\n\n\t\tscales: {\n\t\t\txAxes: [{\n\t\t\t\ttype: 'linear', // bubble should probably use a linear scale by default\n\t\t\t\tposition: 'bottom',\n\t\t\t\tid: 'x-axis-0' // need an ID so datasets can reference the scale\n\t\t\t}],\n\t\t\tyAxes: [{\n\t\t\t\ttype: 'linear',\n\t\t\t\tposition: 'left',\n\t\t\t\tid: 'y-axis-0'\n\t\t\t}]\n\t\t},\n\n\t\ttooltips: {\n\t\t\tcallbacks: {\n\t\t\t\ttitle: function() {\n\t\t\t\t\t// Title doesn't make sense for scatter since we format the data as a point\n\t\t\t\t\treturn '';\n\t\t\t\t},\n\t\t\t\tlabel: function(tooltipItem, data) {\n\t\t\t\t\tvar datasetLabel = data.datasets[tooltipItem.datasetIndex].label || '';\n\t\t\t\t\tvar dataPoint = data.datasets[tooltipItem.datasetIndex].data[tooltipItem.index];\n\t\t\t\t\treturn datasetLabel + ': (' + tooltipItem.xLabel + ', ' + tooltipItem.yLabel + ', ' + dataPoint.r + ')';\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t};\n\n\tChart.controllers.bubble = Chart.DatasetController.extend({\n\n\t\tdataElementType: Chart.elements.Point,\n\n\t\tupdate: function(reset) {\n\t\t\tvar me = this;\n\t\t\tvar meta = me.getMeta();\n\t\t\tvar points = meta.data;\n\n\t\t\t// Update Points\n\t\t\thelpers.each(points, function(point, index) {\n\t\t\t\tme.updateElement(point, index, reset);\n\t\t\t});\n\t\t},\n\n\t\tupdateElement: function(point, index, reset) {\n\t\t\tvar me = this;\n\t\t\tvar meta = me.getMeta();\n\t\t\tvar xScale = me.getScaleForId(meta.xAxisID);\n\t\t\tvar yScale = me.getScaleForId(meta.yAxisID);\n\n\t\t\tvar custom = point.custom || {};\n\t\t\tvar dataset = me.getDataset();\n\t\t\tvar data = dataset.data[index];\n\t\t\tvar pointElementOptions = me.chart.options.elements.point;\n\t\t\tvar dsIndex = me.index;\n\n\t\t\thelpers.extend(point, {\n\t\t\t\t// Utility\n\t\t\t\t_xScale: xScale,\n\t\t\t\t_yScale: yScale,\n\t\t\t\t_datasetIndex: dsIndex,\n\t\t\t\t_index: index,\n\n\t\t\t\t// Desired view properties\n\t\t\t\t_model: {\n\t\t\t\t\tx: reset ? xScale.getPixelForDecimal(0.5) : xScale.getPixelForValue(typeof data === 'object' ? data : NaN, index, dsIndex, me.chart.isCombo),\n\t\t\t\t\ty: reset ? yScale.getBasePixel() : yScale.getPixelForValue(data, index, dsIndex),\n\t\t\t\t\t// Appearance\n\t\t\t\t\tradius: reset ? 0 : custom.radius ? custom.radius : me.getRadius(data),\n\n\t\t\t\t\t// Tooltip\n\t\t\t\t\thitRadius: custom.hitRadius ? custom.hitRadius : helpers.getValueAtIndexOrDefault(dataset.hitRadius, index, pointElementOptions.hitRadius)\n\t\t\t\t}\n\t\t\t});\n\n\t\t\t// Trick to reset the styles of the point\n\t\t\tChart.DatasetController.prototype.removeHoverStyle.call(me, point, pointElementOptions);\n\n\t\t\tvar model = point._model;\n\t\t\tmodel.skip = custom.skip ? custom.skip : (isNaN(model.x) || isNaN(model.y));\n\n\t\t\tpoint.pivot();\n\t\t},\n\n\t\tgetRadius: function(value) {\n\t\t\treturn value.r || this.chart.options.elements.point.radius;\n\t\t},\n\n\t\tsetHoverStyle: function(point) {\n\t\t\tvar me = this;\n\t\t\tChart.DatasetController.prototype.setHoverStyle.call(me, point);\n\n\t\t\t// Radius\n\t\t\tvar dataset = me.chart.data.datasets[point._datasetIndex];\n\t\t\tvar index = point._index;\n\t\t\tvar custom = point.custom || {};\n\t\t\tvar model = point._model;\n\t\t\tmodel.radius = custom.hoverRadius ? custom.hoverRadius : (helpers.getValueAtIndexOrDefault(dataset.hoverRadius, index, me.chart.options.elements.point.hoverRadius)) + me.getRadius(dataset.data[index]);\n\t\t},\n\n\t\tremoveHoverStyle: function(point) {\n\t\t\tvar me = this;\n\t\t\tChart.DatasetController.prototype.removeHoverStyle.call(me, point, me.chart.options.elements.point);\n\n\t\t\tvar dataVal = me.chart.data.datasets[point._datasetIndex].data[point._index];\n\t\t\tvar custom = point.custom || {};\n\t\t\tvar model = point._model;\n\n\t\t\tmodel.radius = custom.radius ? custom.radius : me.getRadius(dataVal);\n\t\t}\n\t});\n};\n\n},{}],17:[function(require,module,exports){\n'use strict';\n\nmodule.exports = function(Chart) {\n\n\tvar helpers = Chart.helpers,\n\t\tdefaults = Chart.defaults;\n\n\tdefaults.doughnut = {\n\t\tanimation: {\n\t\t\t// Boolean - Whether we animate the rotation of the Doughnut\n\t\t\tanimateRotate: true,\n\t\t\t// Boolean - Whether we animate scaling the Doughnut from the centre\n\t\t\tanimateScale: false\n\t\t},\n\t\taspectRatio: 1,\n\t\thover: {\n\t\t\tmode: 'single'\n\t\t},\n\t\tlegendCallback: function(chart) {\n\t\t\tvar text = [];\n\t\t\ttext.push('<ul class=\"' + chart.id + '-legend\">');\n\n\t\t\tvar data = chart.data;\n\t\t\tvar datasets = data.datasets;\n\t\t\tvar labels = data.labels;\n\n\t\t\tif (datasets.length) {\n\t\t\t\tfor (var i = 0; i < datasets[0].data.length; ++i) {\n\t\t\t\t\ttext.push('<li><span style=\"background-color:' + datasets[0].backgroundColor[i] + '\"></span>');\n\t\t\t\t\tif (labels[i]) {\n\t\t\t\t\t\ttext.push(labels[i]);\n\t\t\t\t\t}\n\t\t\t\t\ttext.push('</li>');\n\t\t\t\t}\n\t\t\t}\n\n\t\t\ttext.push('</ul>');\n\t\t\treturn text.join('');\n\t\t},\n\t\tlegend: {\n\t\t\tlabels: {\n\t\t\t\tgenerateLabels: function(chart) {\n\t\t\t\t\tvar data = chart.data;\n\t\t\t\t\tif (data.labels.length && data.datasets.length) {\n\t\t\t\t\t\treturn data.labels.map(function(label, i) {\n\t\t\t\t\t\t\tvar meta = chart.getDatasetMeta(0);\n\t\t\t\t\t\t\tvar ds = data.datasets[0];\n\t\t\t\t\t\t\tvar arc = meta.data[i];\n\t\t\t\t\t\t\tvar custom = arc && arc.custom || {};\n\t\t\t\t\t\t\tvar getValueAtIndexOrDefault = helpers.getValueAtIndexOrDefault;\n\t\t\t\t\t\t\tvar arcOpts = chart.options.elements.arc;\n\t\t\t\t\t\t\tvar fill = custom.backgroundColor ? custom.backgroundColor : getValueAtIndexOrDefault(ds.backgroundColor, i, arcOpts.backgroundColor);\n\t\t\t\t\t\t\tvar stroke = custom.borderColor ? custom.borderColor : getValueAtIndexOrDefault(ds.borderColor, i, arcOpts.borderColor);\n\t\t\t\t\t\t\tvar bw = custom.borderWidth ? custom.borderWidth : getValueAtIndexOrDefault(ds.borderWidth, i, arcOpts.borderWidth);\n\n\t\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\t\ttext: label,\n\t\t\t\t\t\t\t\tfillStyle: fill,\n\t\t\t\t\t\t\t\tstrokeStyle: stroke,\n\t\t\t\t\t\t\t\tlineWidth: bw,\n\t\t\t\t\t\t\t\thidden: isNaN(ds.data[i]) || meta.data[i].hidden,\n\n\t\t\t\t\t\t\t\t// Extra data used for toggling the correct item\n\t\t\t\t\t\t\t\tindex: i\n\t\t\t\t\t\t\t};\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t\treturn [];\n\t\t\t\t}\n\t\t\t},\n\n\t\t\tonClick: function(e, legendItem) {\n\t\t\t\tvar index = legendItem.index;\n\t\t\t\tvar chart = this.chart;\n\t\t\t\tvar i, ilen, meta;\n\n\t\t\t\tfor (i = 0, ilen = (chart.data.datasets || []).length; i < ilen; ++i) {\n\t\t\t\t\tmeta = chart.getDatasetMeta(i);\n\t\t\t\t\t// toggle visibility of index if exists\n\t\t\t\t\tif (meta.data[index]) {\n\t\t\t\t\t\tmeta.data[index].hidden = !meta.data[index].hidden;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tchart.update();\n\t\t\t}\n\t\t},\n\n\t\t// The percentage of the chart that we cut out of the middle.\n\t\tcutoutPercentage: 50,\n\n\t\t// The rotation of the chart, where the first data arc begins.\n\t\trotation: Math.PI * -0.5,\n\n\t\t// The total circumference of the chart.\n\t\tcircumference: Math.PI * 2.0,\n\n\t\t// Need to override these to give a nice default\n\t\ttooltips: {\n\t\t\tcallbacks: {\n\t\t\t\ttitle: function() {\n\t\t\t\t\treturn '';\n\t\t\t\t},\n\t\t\t\tlabel: function(tooltipItem, data) {\n\t\t\t\t\tvar dataLabel = data.labels[tooltipItem.index];\n\t\t\t\t\tvar value = ': ' + data.datasets[tooltipItem.datasetIndex].data[tooltipItem.index];\n\n\t\t\t\t\tif (helpers.isArray(dataLabel)) {\n\t\t\t\t\t\t// show value on first line of multiline label\n\t\t\t\t\t\t// need to clone because we are changing the value\n\t\t\t\t\t\tdataLabel = dataLabel.slice();\n\t\t\t\t\t\tdataLabel[0] += value;\n\t\t\t\t\t} else {\n\t\t\t\t\t\tdataLabel += value;\n\t\t\t\t\t}\n\n\t\t\t\t\treturn dataLabel;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t};\n\n\tdefaults.pie = helpers.clone(defaults.doughnut);\n\thelpers.extend(defaults.pie, {\n\t\tcutoutPercentage: 0\n\t});\n\n\n\tChart.controllers.doughnut = Chart.controllers.pie = Chart.DatasetController.extend({\n\n\t\tdataElementType: Chart.elements.Arc,\n\n\t\tlinkScales: helpers.noop,\n\n\t\t// Get index of the dataset in relation to the visible datasets. This allows determining the inner and outer radius correctly\n\t\tgetRingIndex: function(datasetIndex) {\n\t\t\tvar ringIndex = 0;\n\n\t\t\tfor (var j = 0; j < datasetIndex; ++j) {\n\t\t\t\tif (this.chart.isDatasetVisible(j)) {\n\t\t\t\t\t++ringIndex;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn ringIndex;\n\t\t},\n\n\t\tupdate: function(reset) {\n\t\t\tvar me = this;\n\t\t\tvar chart = me.chart,\n\t\t\t\tchartArea = chart.chartArea,\n\t\t\t\topts = chart.options,\n\t\t\t\tarcOpts = opts.elements.arc,\n\t\t\t\tavailableWidth = chartArea.right - chartArea.left - arcOpts.borderWidth,\n\t\t\t\tavailableHeight = chartArea.bottom - chartArea.top - arcOpts.borderWidth,\n\t\t\t\tminSize = Math.min(availableWidth, availableHeight),\n\t\t\t\toffset = {\n\t\t\t\t\tx: 0,\n\t\t\t\t\ty: 0\n\t\t\t\t},\n\t\t\t\tmeta = me.getMeta(),\n\t\t\t\tcutoutPercentage = opts.cutoutPercentage,\n\t\t\t\tcircumference = opts.circumference;\n\n\t\t\t// If the chart's circumference isn't a full circle, calculate minSize as a ratio of the width/height of the arc\n\t\t\tif (circumference < Math.PI * 2.0) {\n\t\t\t\tvar startAngle = opts.rotation % (Math.PI * 2.0);\n\t\t\t\tstartAngle += Math.PI * 2.0 * (startAngle >= Math.PI ? -1 : startAngle < -Math.PI ? 1 : 0);\n\t\t\t\tvar endAngle = startAngle + circumference;\n\t\t\t\tvar start = {x: Math.cos(startAngle), y: Math.sin(startAngle)};\n\t\t\t\tvar end = {x: Math.cos(endAngle), y: Math.sin(endAngle)};\n\t\t\t\tvar contains0 = (startAngle <= 0 && 0 <= endAngle) || (startAngle <= Math.PI * 2.0 && Math.PI * 2.0 <= endAngle);\n\t\t\t\tvar contains90 = (startAngle <= Math.PI * 0.5 && Math.PI * 0.5 <= endAngle) || (startAngle <= Math.PI * 2.5 && Math.PI * 2.5 <= endAngle);\n\t\t\t\tvar contains180 = (startAngle <= -Math.PI && -Math.PI <= endAngle) || (startAngle <= Math.PI && Math.PI <= endAngle);\n\t\t\t\tvar contains270 = (startAngle <= -Math.PI * 0.5 && -Math.PI * 0.5 <= endAngle) || (startAngle <= Math.PI * 1.5 && Math.PI * 1.5 <= endAngle);\n\t\t\t\tvar cutout = cutoutPercentage / 100.0;\n\t\t\t\tvar min = {x: contains180 ? -1 : Math.min(start.x * (start.x < 0 ? 1 : cutout), end.x * (end.x < 0 ? 1 : cutout)), y: contains270 ? -1 : Math.min(start.y * (start.y < 0 ? 1 : cutout), end.y * (end.y < 0 ? 1 : cutout))};\n\t\t\t\tvar max = {x: contains0 ? 1 : Math.max(start.x * (start.x > 0 ? 1 : cutout), end.x * (end.x > 0 ? 1 : cutout)), y: contains90 ? 1 : Math.max(start.y * (start.y > 0 ? 1 : cutout), end.y * (end.y > 0 ? 1 : cutout))};\n\t\t\t\tvar size = {width: (max.x - min.x) * 0.5, height: (max.y - min.y) * 0.5};\n\t\t\t\tminSize = Math.min(availableWidth / size.width, availableHeight / size.height);\n\t\t\t\toffset = {x: (max.x + min.x) * -0.5, y: (max.y + min.y) * -0.5};\n\t\t\t}\n\n\t\t\tchart.borderWidth = me.getMaxBorderWidth(meta.data);\n\t\t\tchart.outerRadius = Math.max((minSize - chart.borderWidth) / 2, 0);\n\t\t\tchart.innerRadius = Math.max(cutoutPercentage ? (chart.outerRadius / 100) * (cutoutPercentage) : 0, 0);\n\t\t\tchart.radiusLength = (chart.outerRadius - chart.innerRadius) / chart.getVisibleDatasetCount();\n\t\t\tchart.offsetX = offset.x * chart.outerRadius;\n\t\t\tchart.offsetY = offset.y * chart.outerRadius;\n\n\t\t\tmeta.total = me.calculateTotal();\n\n\t\t\tme.outerRadius = chart.outerRadius - (chart.radiusLength * me.getRingIndex(me.index));\n\t\t\tme.innerRadius = Math.max(me.outerRadius - chart.radiusLength, 0);\n\n\t\t\thelpers.each(meta.data, function(arc, index) {\n\t\t\t\tme.updateElement(arc, index, reset);\n\t\t\t});\n\t\t},\n\n\t\tupdateElement: function(arc, index, reset) {\n\t\t\tvar me = this;\n\t\t\tvar chart = me.chart,\n\t\t\t\tchartArea = chart.chartArea,\n\t\t\t\topts = chart.options,\n\t\t\t\tanimationOpts = opts.animation,\n\t\t\t\tcenterX = (chartArea.left + chartArea.right) / 2,\n\t\t\t\tcenterY = (chartArea.top + chartArea.bottom) / 2,\n\t\t\t\tstartAngle = opts.rotation, // non reset case handled later\n\t\t\t\tendAngle = opts.rotation, // non reset case handled later\n\t\t\t\tdataset = me.getDataset(),\n\t\t\t\tcircumference = reset && animationOpts.animateRotate ? 0 : arc.hidden ? 0 : me.calculateCircumference(dataset.data[index]) * (opts.circumference / (2.0 * Math.PI)),\n\t\t\t\tinnerRadius = reset && animationOpts.animateScale ? 0 : me.innerRadius,\n\t\t\t\touterRadius = reset && animationOpts.animateScale ? 0 : me.outerRadius,\n\t\t\t\tvalueAtIndexOrDefault = helpers.getValueAtIndexOrDefault;\n\n\t\t\thelpers.extend(arc, {\n\t\t\t\t// Utility\n\t\t\t\t_datasetIndex: me.index,\n\t\t\t\t_index: index,\n\n\t\t\t\t// Desired view properties\n\t\t\t\t_model: {\n\t\t\t\t\tx: centerX + chart.offsetX,\n\t\t\t\t\ty: centerY + chart.offsetY,\n\t\t\t\t\tstartAngle: startAngle,\n\t\t\t\t\tendAngle: endAngle,\n\t\t\t\t\tcircumference: circumference,\n\t\t\t\t\touterRadius: outerRadius,\n\t\t\t\t\tinnerRadius: innerRadius,\n\t\t\t\t\tlabel: valueAtIndexOrDefault(dataset.label, index, chart.data.labels[index])\n\t\t\t\t}\n\t\t\t});\n\n\t\t\tvar model = arc._model;\n\t\t\t// Resets the visual styles\n\t\t\tthis.removeHoverStyle(arc);\n\n\t\t\t// Set correct angles if not resetting\n\t\t\tif (!reset || !animationOpts.animateRotate) {\n\t\t\t\tif (index === 0) {\n\t\t\t\t\tmodel.startAngle = opts.rotation;\n\t\t\t\t} else {\n\t\t\t\t\tmodel.startAngle = me.getMeta().data[index - 1]._model.endAngle;\n\t\t\t\t}\n\n\t\t\t\tmodel.endAngle = model.startAngle + model.circumference;\n\t\t\t}\n\n\t\t\tarc.pivot();\n\t\t},\n\n\t\tremoveHoverStyle: function(arc) {\n\t\t\tChart.DatasetController.prototype.removeHoverStyle.call(this, arc, this.chart.options.elements.arc);\n\t\t},\n\n\t\tcalculateTotal: function() {\n\t\t\tvar dataset = this.getDataset();\n\t\t\tvar meta = this.getMeta();\n\t\t\tvar total = 0;\n\t\t\tvar value;\n\n\t\t\thelpers.each(meta.data, function(element, index) {\n\t\t\t\tvalue = dataset.data[index];\n\t\t\t\tif (!isNaN(value) && !element.hidden) {\n\t\t\t\t\ttotal += Math.abs(value);\n\t\t\t\t}\n\t\t\t});\n\n\t\t\t/* if (total === 0) {\n\t\t\t\ttotal = NaN;\n\t\t\t}*/\n\n\t\t\treturn total;\n\t\t},\n\n\t\tcalculateCircumference: function(value) {\n\t\t\tvar total = this.getMeta().total;\n\t\t\tif (total > 0 && !isNaN(value)) {\n\t\t\t\treturn (Math.PI * 2.0) * (value / total);\n\t\t\t}\n\t\t\treturn 0;\n\t\t},\n\n\t\t// gets the max border or hover width to properly scale pie charts\n\t\tgetMaxBorderWidth: function(elements) {\n\t\t\tvar max = 0,\n\t\t\t\tindex = this.index,\n\t\t\t\tlength = elements.length,\n\t\t\t\tborderWidth,\n\t\t\t\thoverWidth;\n\n\t\t\tfor (var i = 0; i < length; i++) {\n\t\t\t\tborderWidth = elements[i]._model ? elements[i]._model.borderWidth : 0;\n\t\t\t\thoverWidth = elements[i]._chart ? elements[i]._chart.config.data.datasets[index].hoverBorderWidth : 0;\n\n\t\t\t\tmax = borderWidth > max ? borderWidth : max;\n\t\t\t\tmax = hoverWidth > max ? hoverWidth : max;\n\t\t\t}\n\t\t\treturn max;\n\t\t}\n\t});\n};\n\n},{}],18:[function(require,module,exports){\n'use strict';\n\nmodule.exports = function(Chart) {\n\n\tvar helpers = Chart.helpers;\n\n\tChart.defaults.line = {\n\t\tshowLines: true,\n\t\tspanGaps: false,\n\n\t\thover: {\n\t\t\tmode: 'label'\n\t\t},\n\n\t\tscales: {\n\t\t\txAxes: [{\n\t\t\t\ttype: 'category',\n\t\t\t\tid: 'x-axis-0'\n\t\t\t}],\n\t\t\tyAxes: [{\n\t\t\t\ttype: 'linear',\n\t\t\t\tid: 'y-axis-0'\n\t\t\t}]\n\t\t}\n\t};\n\n\tfunction lineEnabled(dataset, options) {\n\t\treturn helpers.getValueOrDefault(dataset.showLine, options.showLines);\n\t}\n\n\tChart.controllers.line = Chart.DatasetController.extend({\n\n\t\tdatasetElementType: Chart.elements.Line,\n\n\t\tdataElementType: Chart.elements.Point,\n\n\t\tupdate: function(reset) {\n\t\t\tvar me = this;\n\t\t\tvar meta = me.getMeta();\n\t\t\tvar line = meta.dataset;\n\t\t\tvar points = meta.data || [];\n\t\t\tvar options = me.chart.options;\n\t\t\tvar lineElementOptions = options.elements.line;\n\t\t\tvar scale = me.getScaleForId(meta.yAxisID);\n\t\t\tvar i, ilen, custom;\n\t\t\tvar dataset = me.getDataset();\n\t\t\tvar showLine = lineEnabled(dataset, options);\n\n\t\t\t// Update Line\n\t\t\tif (showLine) {\n\t\t\t\tcustom = line.custom || {};\n\n\t\t\t\t// Compatibility: If the properties are defined with only the old name, use those values\n\t\t\t\tif ((dataset.tension !== undefined) && (dataset.lineTension === undefined)) {\n\t\t\t\t\tdataset.lineTension = dataset.tension;\n\t\t\t\t}\n\n\t\t\t\t// Utility\n\t\t\t\tline._scale = scale;\n\t\t\t\tline._datasetIndex = me.index;\n\t\t\t\t// Data\n\t\t\t\tline._children = points;\n\t\t\t\t// Model\n\t\t\t\tline._model = {\n\t\t\t\t\t// Appearance\n\t\t\t\t\t// The default behavior of lines is to break at null values, according\n\t\t\t\t\t// to https://github.com/chartjs/Chart.js/issues/2435#issuecomment-216718158\n\t\t\t\t\t// This option gives lines the ability to span gaps\n\t\t\t\t\tspanGaps: dataset.spanGaps ? dataset.spanGaps : options.spanGaps,\n\t\t\t\t\ttension: custom.tension ? custom.tension : helpers.getValueOrDefault(dataset.lineTension, lineElementOptions.tension),\n\t\t\t\t\tbackgroundColor: custom.backgroundColor ? custom.backgroundColor : (dataset.backgroundColor || lineElementOptions.backgroundColor),\n\t\t\t\t\tborderWidth: custom.borderWidth ? custom.borderWidth : (dataset.borderWidth || lineElementOptions.borderWidth),\n\t\t\t\t\tborderColor: custom.borderColor ? custom.borderColor : (dataset.borderColor || lineElementOptions.borderColor),\n\t\t\t\t\tborderCapStyle: custom.borderCapStyle ? custom.borderCapStyle : (dataset.borderCapStyle || lineElementOptions.borderCapStyle),\n\t\t\t\t\tborderDash: custom.borderDash ? custom.borderDash : (dataset.borderDash || lineElementOptions.borderDash),\n\t\t\t\t\tborderDashOffset: custom.borderDashOffset ? custom.borderDashOffset : (dataset.borderDashOffset || lineElementOptions.borderDashOffset),\n\t\t\t\t\tborderJoinStyle: custom.borderJoinStyle ? custom.borderJoinStyle : (dataset.borderJoinStyle || lineElementOptions.borderJoinStyle),\n\t\t\t\t\tfill: custom.fill ? custom.fill : (dataset.fill !== undefined ? dataset.fill : lineElementOptions.fill),\n\t\t\t\t\tsteppedLine: custom.steppedLine ? custom.steppedLine : helpers.getValueOrDefault(dataset.steppedLine, lineElementOptions.stepped),\n\t\t\t\t\tcubicInterpolationMode: custom.cubicInterpolationMode ? custom.cubicInterpolationMode : helpers.getValueOrDefault(dataset.cubicInterpolationMode, lineElementOptions.cubicInterpolationMode),\n\t\t\t\t};\n\n\t\t\t\tline.pivot();\n\t\t\t}\n\n\t\t\t// Update Points\n\t\t\tfor (i=0, ilen=points.length; i<ilen; ++i) {\n\t\t\t\tme.updateElement(points[i], i, reset);\n\t\t\t}\n\n\t\t\tif (showLine && line._model.tension !== 0) {\n\t\t\t\tme.updateBezierControlPoints();\n\t\t\t}\n\n\t\t\t// Now pivot the point for animation\n\t\t\tfor (i=0, ilen=points.length; i<ilen; ++i) {\n\t\t\t\tpoints[i].pivot();\n\t\t\t}\n\t\t},\n\n\t\tgetPointBackgroundColor: function(point, index) {\n\t\t\tvar backgroundColor = this.chart.options.elements.point.backgroundColor;\n\t\t\tvar dataset = this.getDataset();\n\t\t\tvar custom = point.custom || {};\n\n\t\t\tif (custom.backgroundColor) {\n\t\t\t\tbackgroundColor = custom.backgroundColor;\n\t\t\t} else if (dataset.pointBackgroundColor) {\n\t\t\t\tbackgroundColor = helpers.getValueAtIndexOrDefault(dataset.pointBackgroundColor, index, backgroundColor);\n\t\t\t} else if (dataset.backgroundColor) {\n\t\t\t\tbackgroundColor = dataset.backgroundColor;\n\t\t\t}\n\n\t\t\treturn backgroundColor;\n\t\t},\n\n\t\tgetPointBorderColor: function(point, index) {\n\t\t\tvar borderColor = this.chart.options.elements.point.borderColor;\n\t\t\tvar dataset = this.getDataset();\n\t\t\tvar custom = point.custom || {};\n\n\t\t\tif (custom.borderColor) {\n\t\t\t\tborderColor = custom.borderColor;\n\t\t\t} else if (dataset.pointBorderColor) {\n\t\t\t\tborderColor = helpers.getValueAtIndexOrDefault(dataset.pointBorderColor, index, borderColor);\n\t\t\t} else if (dataset.borderColor) {\n\t\t\t\tborderColor = dataset.borderColor;\n\t\t\t}\n\n\t\t\treturn borderColor;\n\t\t},\n\n\t\tgetPointBorderWidth: function(point, index) {\n\t\t\tvar borderWidth = this.chart.options.elements.point.borderWidth;\n\t\t\tvar dataset = this.getDataset();\n\t\t\tvar custom = point.custom || {};\n\n\t\t\tif (!isNaN(custom.borderWidth)) {\n\t\t\t\tborderWidth = custom.borderWidth;\n\t\t\t} else if (!isNaN(dataset.pointBorderWidth)) {\n\t\t\t\tborderWidth = helpers.getValueAtIndexOrDefault(dataset.pointBorderWidth, index, borderWidth);\n\t\t\t} else if (!isNaN(dataset.borderWidth)) {\n\t\t\t\tborderWidth = dataset.borderWidth;\n\t\t\t}\n\n\t\t\treturn borderWidth;\n\t\t},\n\n\t\tupdateElement: function(point, index, reset) {\n\t\t\tvar me = this;\n\t\t\tvar meta = me.getMeta();\n\t\t\tvar custom = point.custom || {};\n\t\t\tvar dataset = me.getDataset();\n\t\t\tvar datasetIndex = me.index;\n\t\t\tvar value = dataset.data[index];\n\t\t\tvar yScale = me.getScaleForId(meta.yAxisID);\n\t\t\tvar xScale = me.getScaleForId(meta.xAxisID);\n\t\t\tvar pointOptions = me.chart.options.elements.point;\n\t\t\tvar x, y;\n\t\t\tvar labels = me.chart.data.labels || [];\n\t\t\tvar includeOffset = (labels.length === 1 || dataset.data.length === 1) || me.chart.isCombo;\n\n\t\t\t// Compatibility: If the properties are defined with only the old name, use those values\n\t\t\tif ((dataset.radius !== undefined) && (dataset.pointRadius === undefined)) {\n\t\t\t\tdataset.pointRadius = dataset.radius;\n\t\t\t}\n\t\t\tif ((dataset.hitRadius !== undefined) && (dataset.pointHitRadius === undefined)) {\n\t\t\t\tdataset.pointHitRadius = dataset.hitRadius;\n\t\t\t}\n\n\t\t\tx = xScale.getPixelForValue(typeof value === 'object' ? value : NaN, index, datasetIndex, includeOffset);\n\t\t\ty = reset ? yScale.getBasePixel() : me.calculatePointY(value, index, datasetIndex);\n\n\t\t\t// Utility\n\t\t\tpoint._xScale = xScale;\n\t\t\tpoint._yScale = yScale;\n\t\t\tpoint._datasetIndex = datasetIndex;\n\t\t\tpoint._index = index;\n\n\t\t\t// Desired view properties\n\t\t\tpoint._model = {\n\t\t\t\tx: x,\n\t\t\t\ty: y,\n\t\t\t\tskip: custom.skip || isNaN(x) || isNaN(y),\n\t\t\t\t// Appearance\n\t\t\t\tradius: custom.radius || helpers.getValueAtIndexOrDefault(dataset.pointRadius, index, pointOptions.radius),\n\t\t\t\tpointStyle: custom.pointStyle || helpers.getValueAtIndexOrDefault(dataset.pointStyle, index, pointOptions.pointStyle),\n\t\t\t\tbackgroundColor: me.getPointBackgroundColor(point, index),\n\t\t\t\tborderColor: me.getPointBorderColor(point, index),\n\t\t\t\tborderWidth: me.getPointBorderWidth(point, index),\n\t\t\t\ttension: meta.dataset._model ? meta.dataset._model.tension : 0,\n\t\t\t\tsteppedLine: meta.dataset._model ? meta.dataset._model.steppedLine : false,\n\t\t\t\t// Tooltip\n\t\t\t\thitRadius: custom.hitRadius || helpers.getValueAtIndexOrDefault(dataset.pointHitRadius, index, pointOptions.hitRadius)\n\t\t\t};\n\t\t},\n\n\t\tcalculatePointY: function(value, index, datasetIndex) {\n\t\t\tvar me = this;\n\t\t\tvar chart = me.chart;\n\t\t\tvar meta = me.getMeta();\n\t\t\tvar yScale = me.getScaleForId(meta.yAxisID);\n\t\t\tvar sumPos = 0;\n\t\t\tvar sumNeg = 0;\n\t\t\tvar i, ds, dsMeta;\n\n\t\t\tif (yScale.options.stacked) {\n\t\t\t\tfor (i = 0; i < datasetIndex; i++) {\n\t\t\t\t\tds = chart.data.datasets[i];\n\t\t\t\t\tdsMeta = chart.getDatasetMeta(i);\n\t\t\t\t\tif (dsMeta.type === 'line' && dsMeta.yAxisID === yScale.id && chart.isDatasetVisible(i)) {\n\t\t\t\t\t\tvar stackedRightValue = Number(yScale.getRightValue(ds.data[index]));\n\t\t\t\t\t\tif (stackedRightValue < 0) {\n\t\t\t\t\t\t\tsumNeg += stackedRightValue || 0;\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tsumPos += stackedRightValue || 0;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tvar rightValue = Number(yScale.getRightValue(value));\n\t\t\t\tif (rightValue < 0) {\n\t\t\t\t\treturn yScale.getPixelForValue(sumNeg + rightValue);\n\t\t\t\t}\n\t\t\t\treturn yScale.getPixelForValue(sumPos + rightValue);\n\t\t\t}\n\n\t\t\treturn yScale.getPixelForValue(value);\n\t\t},\n\n\t\tupdateBezierControlPoints: function() {\n\t\t\tvar me = this;\n\t\t\tvar meta = me.getMeta();\n\t\t\tvar area = me.chart.chartArea;\n\t\t\tvar points = (meta.data || []);\n\t\t\tvar i, ilen, point, model, controlPoints;\n\n\t\t\t// Only consider points that are drawn in case the spanGaps option is used\n\t\t\tif (meta.dataset._model.spanGaps) {\n\t\t\t\tpoints = points.filter(function(pt) {\n\t\t\t\t\treturn !pt._model.skip;\n\t\t\t\t});\n\t\t\t}\n\n\t\t\tfunction capControlPoint(pt, min, max) {\n\t\t\t\treturn Math.max(Math.min(pt, max), min);\n\t\t\t}\n\n\t\t\tif (meta.dataset._model.cubicInterpolationMode === 'monotone') {\n\t\t\t\thelpers.splineCurveMonotone(points);\n\t\t\t} else {\n\t\t\t\tfor (i = 0, ilen = points.length; i < ilen; ++i) {\n\t\t\t\t\tpoint = points[i];\n\t\t\t\t\tmodel = point._model;\n\t\t\t\t\tcontrolPoints = helpers.splineCurve(\n\t\t\t\t\t\thelpers.previousItem(points, i)._model,\n\t\t\t\t\t\tmodel,\n\t\t\t\t\t\thelpers.nextItem(points, i)._model,\n\t\t\t\t\t\tmeta.dataset._model.tension\n\t\t\t\t\t);\n\t\t\t\t\tmodel.controlPointPreviousX = controlPoints.previous.x;\n\t\t\t\t\tmodel.controlPointPreviousY = controlPoints.previous.y;\n\t\t\t\t\tmodel.controlPointNextX = controlPoints.next.x;\n\t\t\t\t\tmodel.controlPointNextY = controlPoints.next.y;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (me.chart.options.elements.line.capBezierPoints) {\n\t\t\t\tfor (i = 0, ilen = points.length; i < ilen; ++i) {\n\t\t\t\t\tmodel = points[i]._model;\n\t\t\t\t\tmodel.controlPointPreviousX = capControlPoint(model.controlPointPreviousX, area.left, area.right);\n\t\t\t\t\tmodel.controlPointPreviousY = capControlPoint(model.controlPointPreviousY, area.top, area.bottom);\n\t\t\t\t\tmodel.controlPointNextX = capControlPoint(model.controlPointNextX, area.left, area.right);\n\t\t\t\t\tmodel.controlPointNextY = capControlPoint(model.controlPointNextY, area.top, area.bottom);\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\n\t\tdraw: function() {\n\t\t\tvar me = this;\n\t\t\tvar chart = me.chart;\n\t\t\tvar meta = me.getMeta();\n\t\t\tvar points = meta.data || [];\n\t\t\tvar area = chart.chartArea;\n\t\t\tvar ilen = points.length;\n\t\t\tvar i = 0;\n\n\t\t\tChart.canvasHelpers.clipArea(chart.ctx, area);\n\n\t\t\tif (lineEnabled(me.getDataset(), chart.options)) {\n\t\t\t\tmeta.dataset.draw();\n\t\t\t}\n\n\t\t\tChart.canvasHelpers.unclipArea(chart.ctx);\n\n\t\t\t// Draw the points\n\t\t\tfor (; i<ilen; ++i) {\n\t\t\t\tpoints[i].draw(area);\n\t\t\t}\n\t\t},\n\n\t\tsetHoverStyle: function(point) {\n\t\t\t// Point\n\t\t\tvar dataset = this.chart.data.datasets[point._datasetIndex];\n\t\t\tvar index = point._index;\n\t\t\tvar custom = point.custom || {};\n\t\t\tvar model = point._model;\n\n\t\t\tmodel.radius = custom.hoverRadius || helpers.getValueAtIndexOrDefault(dataset.pointHoverRadius, index, this.chart.options.elements.point.hoverRadius);\n\t\t\tmodel.backgroundColor = custom.hoverBackgroundColor || helpers.getValueAtIndexOrDefault(dataset.pointHoverBackgroundColor, index, helpers.getHoverColor(model.backgroundColor));\n\t\t\tmodel.borderColor = custom.hoverBorderColor || helpers.getValueAtIndexOrDefault(dataset.pointHoverBorderColor, index, helpers.getHoverColor(model.borderColor));\n\t\t\tmodel.borderWidth = custom.hoverBorderWidth || helpers.getValueAtIndexOrDefault(dataset.pointHoverBorderWidth, index, model.borderWidth);\n\t\t},\n\n\t\tremoveHoverStyle: function(point) {\n\t\t\tvar me = this;\n\t\t\tvar dataset = me.chart.data.datasets[point._datasetIndex];\n\t\t\tvar index = point._index;\n\t\t\tvar custom = point.custom || {};\n\t\t\tvar model = point._model;\n\n\t\t\t// Compatibility: If the properties are defined with only the old name, use those values\n\t\t\tif ((dataset.radius !== undefined) && (dataset.pointRadius === undefined)) {\n\t\t\t\tdataset.pointRadius = dataset.radius;\n\t\t\t}\n\n\t\t\tmodel.radius = custom.radius || helpers.getValueAtIndexOrDefault(dataset.pointRadius, index, me.chart.options.elements.point.radius);\n\t\t\tmodel.backgroundColor = me.getPointBackgroundColor(point, index);\n\t\t\tmodel.borderColor = me.getPointBorderColor(point, index);\n\t\t\tmodel.borderWidth = me.getPointBorderWidth(point, index);\n\t\t}\n\t});\n};\n\n},{}],19:[function(require,module,exports){\n'use strict';\n\nmodule.exports = function(Chart) {\n\n\tvar helpers = Chart.helpers;\n\n\tChart.defaults.polarArea = {\n\n\t\tscale: {\n\t\t\ttype: 'radialLinear',\n\t\t\tangleLines: {\n\t\t\t\tdisplay: false\n\t\t\t},\n\t\t\tgridLines: {\n\t\t\t\tcircular: true\n\t\t\t},\n\t\t\tpointLabels: {\n\t\t\t\tdisplay: false\n\t\t\t},\n\t\t\tticks: {\n\t\t\t\tbeginAtZero: true\n\t\t\t}\n\t\t},\n\n\t\t// Boolean - Whether to animate the rotation of the chart\n\t\tanimation: {\n\t\t\tanimateRotate: true,\n\t\t\tanimateScale: true\n\t\t},\n\n\t\tstartAngle: -0.5 * Math.PI,\n\t\taspectRatio: 1,\n\t\tlegendCallback: function(chart) {\n\t\t\tvar text = [];\n\t\t\ttext.push('<ul class=\"' + chart.id + '-legend\">');\n\n\t\t\tvar data = chart.data;\n\t\t\tvar datasets = data.datasets;\n\t\t\tvar labels = data.labels;\n\n\t\t\tif (datasets.length) {\n\t\t\t\tfor (var i = 0; i < datasets[0].data.length; ++i) {\n\t\t\t\t\ttext.push('<li><span style=\"background-color:' + datasets[0].backgroundColor[i] + '\"></span>');\n\t\t\t\t\tif (labels[i]) {\n\t\t\t\t\t\ttext.push(labels[i]);\n\t\t\t\t\t}\n\t\t\t\t\ttext.push('</li>');\n\t\t\t\t}\n\t\t\t}\n\n\t\t\ttext.push('</ul>');\n\t\t\treturn text.join('');\n\t\t},\n\t\tlegend: {\n\t\t\tlabels: {\n\t\t\t\tgenerateLabels: function(chart) {\n\t\t\t\t\tvar data = chart.data;\n\t\t\t\t\tif (data.labels.length && data.datasets.length) {\n\t\t\t\t\t\treturn data.labels.map(function(label, i) {\n\t\t\t\t\t\t\tvar meta = chart.getDatasetMeta(0);\n\t\t\t\t\t\t\tvar ds = data.datasets[0];\n\t\t\t\t\t\t\tvar arc = meta.data[i];\n\t\t\t\t\t\t\tvar custom = arc.custom || {};\n\t\t\t\t\t\t\tvar getValueAtIndexOrDefault = helpers.getValueAtIndexOrDefault;\n\t\t\t\t\t\t\tvar arcOpts = chart.options.elements.arc;\n\t\t\t\t\t\t\tvar fill = custom.backgroundColor ? custom.backgroundColor : getValueAtIndexOrDefault(ds.backgroundColor, i, arcOpts.backgroundColor);\n\t\t\t\t\t\t\tvar stroke = custom.borderColor ? custom.borderColor : getValueAtIndexOrDefault(ds.borderColor, i, arcOpts.borderColor);\n\t\t\t\t\t\t\tvar bw = custom.borderWidth ? custom.borderWidth : getValueAtIndexOrDefault(ds.borderWidth, i, arcOpts.borderWidth);\n\n\t\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\t\ttext: label,\n\t\t\t\t\t\t\t\tfillStyle: fill,\n\t\t\t\t\t\t\t\tstrokeStyle: stroke,\n\t\t\t\t\t\t\t\tlineWidth: bw,\n\t\t\t\t\t\t\t\thidden: isNaN(ds.data[i]) || meta.data[i].hidden,\n\n\t\t\t\t\t\t\t\t// Extra data used for toggling the correct item\n\t\t\t\t\t\t\t\tindex: i\n\t\t\t\t\t\t\t};\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t\treturn [];\n\t\t\t\t}\n\t\t\t},\n\n\t\t\tonClick: function(e, legendItem) {\n\t\t\t\tvar index = legendItem.index;\n\t\t\t\tvar chart = this.chart;\n\t\t\t\tvar i, ilen, meta;\n\n\t\t\t\tfor (i = 0, ilen = (chart.data.datasets || []).length; i < ilen; ++i) {\n\t\t\t\t\tmeta = chart.getDatasetMeta(i);\n\t\t\t\t\tmeta.data[index].hidden = !meta.data[index].hidden;\n\t\t\t\t}\n\n\t\t\t\tchart.update();\n\t\t\t}\n\t\t},\n\n\t\t// Need to override these to give a nice default\n\t\ttooltips: {\n\t\t\tcallbacks: {\n\t\t\t\ttitle: function() {\n\t\t\t\t\treturn '';\n\t\t\t\t},\n\t\t\t\tlabel: function(tooltipItem, data) {\n\t\t\t\t\treturn data.labels[tooltipItem.index] + ': ' + tooltipItem.yLabel;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t};\n\n\tChart.controllers.polarArea = Chart.DatasetController.extend({\n\n\t\tdataElementType: Chart.elements.Arc,\n\n\t\tlinkScales: helpers.noop,\n\n\t\tupdate: function(reset) {\n\t\t\tvar me = this;\n\t\t\tvar chart = me.chart;\n\t\t\tvar chartArea = chart.chartArea;\n\t\t\tvar meta = me.getMeta();\n\t\t\tvar opts = chart.options;\n\t\t\tvar arcOpts = opts.elements.arc;\n\t\t\tvar minSize = Math.min(chartArea.right - chartArea.left, chartArea.bottom - chartArea.top);\n\t\t\tchart.outerRadius = Math.max((minSize - arcOpts.borderWidth / 2) / 2, 0);\n\t\t\tchart.innerRadius = Math.max(opts.cutoutPercentage ? (chart.outerRadius / 100) * (opts.cutoutPercentage) : 1, 0);\n\t\t\tchart.radiusLength = (chart.outerRadius - chart.innerRadius) / chart.getVisibleDatasetCount();\n\n\t\t\tme.outerRadius = chart.outerRadius - (chart.radiusLength * me.index);\n\t\t\tme.innerRadius = me.outerRadius - chart.radiusLength;\n\n\t\t\tmeta.count = me.countVisibleElements();\n\n\t\t\thelpers.each(meta.data, function(arc, index) {\n\t\t\t\tme.updateElement(arc, index, reset);\n\t\t\t});\n\t\t},\n\n\t\tupdateElement: function(arc, index, reset) {\n\t\t\tvar me = this;\n\t\t\tvar chart = me.chart;\n\t\t\tvar dataset = me.getDataset();\n\t\t\tvar opts = chart.options;\n\t\t\tvar animationOpts = opts.animation;\n\t\t\tvar scale = chart.scale;\n\t\t\tvar getValueAtIndexOrDefault = helpers.getValueAtIndexOrDefault;\n\t\t\tvar labels = chart.data.labels;\n\n\t\t\tvar circumference = me.calculateCircumference(dataset.data[index]);\n\t\t\tvar centerX = scale.xCenter;\n\t\t\tvar centerY = scale.yCenter;\n\n\t\t\t// If there is NaN data before us, we need to calculate the starting angle correctly.\n\t\t\t// We could be way more efficient here, but its unlikely that the polar area chart will have a lot of data\n\t\t\tvar visibleCount = 0;\n\t\t\tvar meta = me.getMeta();\n\t\t\tfor (var i = 0; i < index; ++i) {\n\t\t\t\tif (!isNaN(dataset.data[i]) && !meta.data[i].hidden) {\n\t\t\t\t\t++visibleCount;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// var negHalfPI = -0.5 * Math.PI;\n\t\t\tvar datasetStartAngle = opts.startAngle;\n\t\t\tvar distance = arc.hidden ? 0 : scale.getDistanceFromCenterForValue(dataset.data[index]);\n\t\t\tvar startAngle = datasetStartAngle + (circumference * visibleCount);\n\t\t\tvar endAngle = startAngle + (arc.hidden ? 0 : circumference);\n\n\t\t\tvar resetRadius = animationOpts.animateScale ? 0 : scale.getDistanceFromCenterForValue(dataset.data[index]);\n\n\t\t\thelpers.extend(arc, {\n\t\t\t\t// Utility\n\t\t\t\t_datasetIndex: me.index,\n\t\t\t\t_index: index,\n\t\t\t\t_scale: scale,\n\n\t\t\t\t// Desired view properties\n\t\t\t\t_model: {\n\t\t\t\t\tx: centerX,\n\t\t\t\t\ty: centerY,\n\t\t\t\t\tinnerRadius: 0,\n\t\t\t\t\touterRadius: reset ? resetRadius : distance,\n\t\t\t\t\tstartAngle: reset && animationOpts.animateRotate ? datasetStartAngle : startAngle,\n\t\t\t\t\tendAngle: reset && animationOpts.animateRotate ? datasetStartAngle : endAngle,\n\t\t\t\t\tlabel: getValueAtIndexOrDefault(labels, index, labels[index])\n\t\t\t\t}\n\t\t\t});\n\n\t\t\t// Apply border and fill style\n\t\t\tme.removeHoverStyle(arc);\n\n\t\t\tarc.pivot();\n\t\t},\n\n\t\tremoveHoverStyle: function(arc) {\n\t\t\tChart.DatasetController.prototype.removeHoverStyle.call(this, arc, this.chart.options.elements.arc);\n\t\t},\n\n\t\tcountVisibleElements: function() {\n\t\t\tvar dataset = this.getDataset();\n\t\t\tvar meta = this.getMeta();\n\t\t\tvar count = 0;\n\n\t\t\thelpers.each(meta.data, function(element, index) {\n\t\t\t\tif (!isNaN(dataset.data[index]) && !element.hidden) {\n\t\t\t\t\tcount++;\n\t\t\t\t}\n\t\t\t});\n\n\t\t\treturn count;\n\t\t},\n\n\t\tcalculateCircumference: function(value) {\n\t\t\tvar count = this.getMeta().count;\n\t\t\tif (count > 0 && !isNaN(value)) {\n\t\t\t\treturn (2 * Math.PI) / count;\n\t\t\t}\n\t\t\treturn 0;\n\t\t}\n\t});\n};\n\n},{}],20:[function(require,module,exports){\n'use strict';\n\nmodule.exports = function(Chart) {\n\n\tvar helpers = Chart.helpers;\n\n\tChart.defaults.radar = {\n\t\taspectRatio: 1,\n\t\tscale: {\n\t\t\ttype: 'radialLinear'\n\t\t},\n\t\telements: {\n\t\t\tline: {\n\t\t\t\ttension: 0 // no bezier in radar\n\t\t\t}\n\t\t}\n\t};\n\n\tChart.controllers.radar = Chart.DatasetController.extend({\n\n\t\tdatasetElementType: Chart.elements.Line,\n\n\t\tdataElementType: Chart.elements.Point,\n\n\t\tlinkScales: helpers.noop,\n\n\t\tupdate: function(reset) {\n\t\t\tvar me = this;\n\t\t\tvar meta = me.getMeta();\n\t\t\tvar line = meta.dataset;\n\t\t\tvar points = meta.data;\n\t\t\tvar custom = line.custom || {};\n\t\t\tvar dataset = me.getDataset();\n\t\t\tvar lineElementOptions = me.chart.options.elements.line;\n\t\t\tvar scale = me.chart.scale;\n\n\t\t\t// Compatibility: If the properties are defined with only the old name, use those values\n\t\t\tif ((dataset.tension !== undefined) && (dataset.lineTension === undefined)) {\n\t\t\t\tdataset.lineTension = dataset.tension;\n\t\t\t}\n\n\t\t\thelpers.extend(meta.dataset, {\n\t\t\t\t// Utility\n\t\t\t\t_datasetIndex: me.index,\n\t\t\t\t_scale: scale,\n\t\t\t\t// Data\n\t\t\t\t_children: points,\n\t\t\t\t_loop: true,\n\t\t\t\t// Model\n\t\t\t\t_model: {\n\t\t\t\t\t// Appearance\n\t\t\t\t\ttension: custom.tension ? custom.tension : helpers.getValueOrDefault(dataset.lineTension, lineElementOptions.tension),\n\t\t\t\t\tbackgroundColor: custom.backgroundColor ? custom.backgroundColor : (dataset.backgroundColor || lineElementOptions.backgroundColor),\n\t\t\t\t\tborderWidth: custom.borderWidth ? custom.borderWidth : (dataset.borderWidth || lineElementOptions.borderWidth),\n\t\t\t\t\tborderColor: custom.borderColor ? custom.borderColor : (dataset.borderColor || lineElementOptions.borderColor),\n\t\t\t\t\tfill: custom.fill ? custom.fill : (dataset.fill !== undefined ? dataset.fill : lineElementOptions.fill),\n\t\t\t\t\tborderCapStyle: custom.borderCapStyle ? custom.borderCapStyle : (dataset.borderCapStyle || lineElementOptions.borderCapStyle),\n\t\t\t\t\tborderDash: custom.borderDash ? custom.borderDash : (dataset.borderDash || lineElementOptions.borderDash),\n\t\t\t\t\tborderDashOffset: custom.borderDashOffset ? custom.borderDashOffset : (dataset.borderDashOffset || lineElementOptions.borderDashOffset),\n\t\t\t\t\tborderJoinStyle: custom.borderJoinStyle ? custom.borderJoinStyle : (dataset.borderJoinStyle || lineElementOptions.borderJoinStyle),\n\t\t\t\t}\n\t\t\t});\n\n\t\t\tmeta.dataset.pivot();\n\n\t\t\t// Update Points\n\t\t\thelpers.each(points, function(point, index) {\n\t\t\t\tme.updateElement(point, index, reset);\n\t\t\t}, me);\n\n\t\t\t// Update bezier control points\n\t\t\tme.updateBezierControlPoints();\n\t\t},\n\t\tupdateElement: function(point, index, reset) {\n\t\t\tvar me = this;\n\t\t\tvar custom = point.custom || {};\n\t\t\tvar dataset = me.getDataset();\n\t\t\tvar scale = me.chart.scale;\n\t\t\tvar pointElementOptions = me.chart.options.elements.point;\n\t\t\tvar pointPosition = scale.getPointPositionForValue(index, dataset.data[index]);\n\n\t\t\t// Compatibility: If the properties are defined with only the old name, use those values\n\t\t\tif ((dataset.radius !== undefined) && (dataset.pointRadius === undefined)) {\n\t\t\t\tdataset.pointRadius = dataset.radius;\n\t\t\t}\n\t\t\tif ((dataset.hitRadius !== undefined) && (dataset.pointHitRadius === undefined)) {\n\t\t\t\tdataset.pointHitRadius = dataset.hitRadius;\n\t\t\t}\n\n\t\t\thelpers.extend(point, {\n\t\t\t\t// Utility\n\t\t\t\t_datasetIndex: me.index,\n\t\t\t\t_index: index,\n\t\t\t\t_scale: scale,\n\n\t\t\t\t// Desired view properties\n\t\t\t\t_model: {\n\t\t\t\t\tx: reset ? scale.xCenter : pointPosition.x, // value not used in dataset scale, but we want a consistent API between scales\n\t\t\t\t\ty: reset ? scale.yCenter : pointPosition.y,\n\n\t\t\t\t\t// Appearance\n\t\t\t\t\ttension: custom.tension ? custom.tension : helpers.getValueOrDefault(dataset.lineTension, me.chart.options.elements.line.tension),\n\t\t\t\t\tradius: custom.radius ? custom.radius : helpers.getValueAtIndexOrDefault(dataset.pointRadius, index, pointElementOptions.radius),\n\t\t\t\t\tbackgroundColor: custom.backgroundColor ? custom.backgroundColor : helpers.getValueAtIndexOrDefault(dataset.pointBackgroundColor, index, pointElementOptions.backgroundColor),\n\t\t\t\t\tborderColor: custom.borderColor ? custom.borderColor : helpers.getValueAtIndexOrDefault(dataset.pointBorderColor, index, pointElementOptions.borderColor),\n\t\t\t\t\tborderWidth: custom.borderWidth ? custom.borderWidth : helpers.getValueAtIndexOrDefault(dataset.pointBorderWidth, index, pointElementOptions.borderWidth),\n\t\t\t\t\tpointStyle: custom.pointStyle ? custom.pointStyle : helpers.getValueAtIndexOrDefault(dataset.pointStyle, index, pointElementOptions.pointStyle),\n\n\t\t\t\t\t// Tooltip\n\t\t\t\t\thitRadius: custom.hitRadius ? custom.hitRadius : helpers.getValueAtIndexOrDefault(dataset.pointHitRadius, index, pointElementOptions.hitRadius)\n\t\t\t\t}\n\t\t\t});\n\n\t\t\tpoint._model.skip = custom.skip ? custom.skip : (isNaN(point._model.x) || isNaN(point._model.y));\n\t\t},\n\t\tupdateBezierControlPoints: function() {\n\t\t\tvar chartArea = this.chart.chartArea;\n\t\t\tvar meta = this.getMeta();\n\n\t\t\thelpers.each(meta.data, function(point, index) {\n\t\t\t\tvar model = point._model;\n\t\t\t\tvar controlPoints = helpers.splineCurve(\n\t\t\t\t\thelpers.previousItem(meta.data, index, true)._model,\n\t\t\t\t\tmodel,\n\t\t\t\t\thelpers.nextItem(meta.data, index, true)._model,\n\t\t\t\t\tmodel.tension\n\t\t\t\t);\n\n\t\t\t\t// Prevent the bezier going outside of the bounds of the graph\n\t\t\t\tmodel.controlPointPreviousX = Math.max(Math.min(controlPoints.previous.x, chartArea.right), chartArea.left);\n\t\t\t\tmodel.controlPointPreviousY = Math.max(Math.min(controlPoints.previous.y, chartArea.bottom), chartArea.top);\n\n\t\t\t\tmodel.controlPointNextX = Math.max(Math.min(controlPoints.next.x, chartArea.right), chartArea.left);\n\t\t\t\tmodel.controlPointNextY = Math.max(Math.min(controlPoints.next.y, chartArea.bottom), chartArea.top);\n\n\t\t\t\t// Now pivot the point for animation\n\t\t\t\tpoint.pivot();\n\t\t\t});\n\t\t},\n\n\t\tsetHoverStyle: function(point) {\n\t\t\t// Point\n\t\t\tvar dataset = this.chart.data.datasets[point._datasetIndex];\n\t\t\tvar custom = point.custom || {};\n\t\t\tvar index = point._index;\n\t\t\tvar model = point._model;\n\n\t\t\tmodel.radius = custom.hoverRadius ? custom.hoverRadius : helpers.getValueAtIndexOrDefault(dataset.pointHoverRadius, index, this.chart.options.elements.point.hoverRadius);\n\t\t\tmodel.backgroundColor = custom.hoverBackgroundColor ? custom.hoverBackgroundColor : helpers.getValueAtIndexOrDefault(dataset.pointHoverBackgroundColor, index, helpers.getHoverColor(model.backgroundColor));\n\t\t\tmodel.borderColor = custom.hoverBorderColor ? custom.hoverBorderColor : helpers.getValueAtIndexOrDefault(dataset.pointHoverBorderColor, index, helpers.getHoverColor(model.borderColor));\n\t\t\tmodel.borderWidth = custom.hoverBorderWidth ? custom.hoverBorderWidth : helpers.getValueAtIndexOrDefault(dataset.pointHoverBorderWidth, index, model.borderWidth);\n\t\t},\n\n\t\tremoveHoverStyle: function(point) {\n\t\t\tvar dataset = this.chart.data.datasets[point._datasetIndex];\n\t\t\tvar custom = point.custom || {};\n\t\t\tvar index = point._index;\n\t\t\tvar model = point._model;\n\t\t\tvar pointElementOptions = this.chart.options.elements.point;\n\n\t\t\tmodel.radius = custom.radius ? custom.radius : helpers.getValueAtIndexOrDefault(dataset.pointRadius, index, pointElementOptions.radius);\n\t\t\tmodel.backgroundColor = custom.backgroundColor ? custom.backgroundColor : helpers.getValueAtIndexOrDefault(dataset.pointBackgroundColor, index, pointElementOptions.backgroundColor);\n\t\t\tmodel.borderColor = custom.borderColor ? custom.borderColor : helpers.getValueAtIndexOrDefault(dataset.pointBorderColor, index, pointElementOptions.borderColor);\n\t\t\tmodel.borderWidth = custom.borderWidth ? custom.borderWidth : helpers.getValueAtIndexOrDefault(dataset.pointBorderWidth, index, pointElementOptions.borderWidth);\n\t\t}\n\t});\n};\n\n},{}],21:[function(require,module,exports){\n/* global window: false */\n'use strict';\n\nmodule.exports = function(Chart) {\n\n\tvar helpers = Chart.helpers;\n\n\tChart.defaults.global.animation = {\n\t\tduration: 1000,\n\t\teasing: 'easeOutQuart',\n\t\tonProgress: helpers.noop,\n\t\tonComplete: helpers.noop\n\t};\n\n\tChart.Animation = Chart.Element.extend({\n\t\tchart: null, // the animation associated chart instance\n\t\tcurrentStep: 0, // the current animation step\n\t\tnumSteps: 60, // default number of steps\n\t\teasing: '', // the easing to use for this animation\n\t\trender: null, // render function used by the animation service\n\n\t\tonAnimationProgress: null, // user specified callback to fire on each step of the animation\n\t\tonAnimationComplete: null, // user specified callback to fire when the animation finishes\n\t});\n\n\tChart.animationService = {\n\t\tframeDuration: 17,\n\t\tanimations: [],\n\t\tdropFrames: 0,\n\t\trequest: null,\n\n\t\t/**\n\t\t * @param {Chart} chart - The chart to animate.\n\t\t * @param {Chart.Animation} animation - The animation that we will animate.\n\t\t * @param {Number} duration - The animation duration in ms.\n\t\t * @param {Boolean} lazy - if true, the chart is not marked as animating to enable more responsive interactions\n\t\t */\n\t\taddAnimation: function(chart, animation, duration, lazy) {\n\t\t\tvar animations = this.animations;\n\t\t\tvar i, ilen;\n\n\t\t\tanimation.chart = chart;\n\n\t\t\tif (!lazy) {\n\t\t\t\tchart.animating = true;\n\t\t\t}\n\n\t\t\tfor (i=0, ilen=animations.length; i < ilen; ++i) {\n\t\t\t\tif (animations[i].chart === chart) {\n\t\t\t\t\tanimations[i] = animation;\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tanimations.push(animation);\n\n\t\t\t// If there are no animations queued, manually kickstart a digest, for lack of a better word\n\t\t\tif (animations.length === 1) {\n\t\t\t\tthis.requestAnimationFrame();\n\t\t\t}\n\t\t},\n\n\t\tcancelAnimation: function(chart) {\n\t\t\tvar index = helpers.findIndex(this.animations, function(animation) {\n\t\t\t\treturn animation.chart === chart;\n\t\t\t});\n\n\t\t\tif (index !== -1) {\n\t\t\t\tthis.animations.splice(index, 1);\n\t\t\t\tchart.animating = false;\n\t\t\t}\n\t\t},\n\n\t\trequestAnimationFrame: function() {\n\t\t\tvar me = this;\n\t\t\tif (me.request === null) {\n\t\t\t\t// Skip animation frame requests until the active one is executed.\n\t\t\t\t// This can happen when processing mouse events, e.g. 'mousemove'\n\t\t\t\t// and 'mouseout' events will trigger multiple renders.\n\t\t\t\tme.request = helpers.requestAnimFrame.call(window, function() {\n\t\t\t\t\tme.request = null;\n\t\t\t\t\tme.startDigest();\n\t\t\t\t});\n\t\t\t}\n\t\t},\n\n\t\t/**\n\t\t * @private\n\t\t */\n\t\tstartDigest: function() {\n\t\t\tvar me = this;\n\t\t\tvar startTime = Date.now();\n\t\t\tvar framesToDrop = 0;\n\n\t\t\tif (me.dropFrames > 1) {\n\t\t\t\tframesToDrop = Math.floor(me.dropFrames);\n\t\t\t\tme.dropFrames = me.dropFrames % 1;\n\t\t\t}\n\n\t\t\tme.advance(1 + framesToDrop);\n\n\t\t\tvar endTime = Date.now();\n\n\t\t\tme.dropFrames += (endTime - startTime) / me.frameDuration;\n\n\t\t\t// Do we have more stuff to animate?\n\t\t\tif (me.animations.length > 0) {\n\t\t\t\tme.requestAnimationFrame();\n\t\t\t}\n\t\t},\n\n\t\t/**\n\t\t * @private\n\t\t */\n\t\tadvance: function(count) {\n\t\t\tvar animations = this.animations;\n\t\t\tvar animation, chart;\n\t\t\tvar i = 0;\n\n\t\t\twhile (i < animations.length) {\n\t\t\t\tanimation = animations[i];\n\t\t\t\tchart = animation.chart;\n\n\t\t\t\tanimation.currentStep = (animation.currentStep || 0) + count;\n\t\t\t\tanimation.currentStep = Math.min(animation.currentStep, animation.numSteps);\n\n\t\t\t\thelpers.callback(animation.render, [chart, animation], chart);\n\t\t\t\thelpers.callback(animation.onAnimationProgress, [animation], chart);\n\n\t\t\t\tif (animation.currentStep >= animation.numSteps) {\n\t\t\t\t\thelpers.callback(animation.onAnimationComplete, [animation], chart);\n\t\t\t\t\tchart.animating = false;\n\t\t\t\t\tanimations.splice(i, 1);\n\t\t\t\t} else {\n\t\t\t\t\t++i;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t};\n\n\t/**\n\t * Provided for backward compatibility, use Chart.Animation instead\n\t * @prop Chart.Animation#animationObject\n\t * @deprecated since version 2.6.0\n\t * @todo remove at version 3\n\t */\n\tObject.defineProperty(Chart.Animation.prototype, 'animationObject', {\n\t\tget: function() {\n\t\t\treturn this;\n\t\t}\n\t});\n\n\t/**\n\t * Provided for backward compatibility, use Chart.Animation#chart instead\n\t * @prop Chart.Animation#chartInstance\n\t * @deprecated since version 2.6.0\n\t * @todo remove at version 3\n\t */\n\tObject.defineProperty(Chart.Animation.prototype, 'chartInstance', {\n\t\tget: function() {\n\t\t\treturn this.chart;\n\t\t},\n\t\tset: function(value) {\n\t\t\tthis.chart = value;\n\t\t}\n\t});\n\n};\n\n},{}],22:[function(require,module,exports){\n'use strict';\n\nmodule.exports = function(Chart) {\n\t// Global Chart canvas helpers object for drawing items to canvas\n\tvar helpers = Chart.canvasHelpers = {};\n\n\thelpers.drawPoint = function(ctx, pointStyle, radius, x, y) {\n\t\tvar type, edgeLength, xOffset, yOffset, height, size;\n\n\t\tif (typeof pointStyle === 'object') {\n\t\t\ttype = pointStyle.toString();\n\t\t\tif (type === '[object HTMLImageElement]' || type === '[object HTMLCanvasElement]') {\n\t\t\t\tctx.drawImage(pointStyle, x - pointStyle.width / 2, y - pointStyle.height / 2, pointStyle.width, pointStyle.height);\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\n\t\tif (isNaN(radius) || radius <= 0) {\n\t\t\treturn;\n\t\t}\n\n\t\tswitch (pointStyle) {\n\t\t// Default includes circle\n\t\tdefault:\n\t\t\tctx.beginPath();\n\t\t\tctx.arc(x, y, radius, 0, Math.PI * 2);\n\t\t\tctx.closePath();\n\t\t\tctx.fill();\n\t\t\tbreak;\n\t\tcase 'triangle':\n\t\t\tctx.beginPath();\n\t\t\tedgeLength = 3 * radius / Math.sqrt(3);\n\t\t\theight = edgeLength * Math.sqrt(3) / 2;\n\t\t\tctx.moveTo(x - edgeLength / 2, y + height / 3);\n\t\t\tctx.lineTo(x + edgeLength / 2, y + height / 3);\n\t\t\tctx.lineTo(x, y - 2 * height / 3);\n\t\t\tctx.closePath();\n\t\t\tctx.fill();\n\t\t\tbreak;\n\t\tcase 'rect':\n\t\t\tsize = 1 / Math.SQRT2 * radius;\n\t\t\tctx.beginPath();\n\t\t\tctx.fillRect(x - size, y - size, 2 * size, 2 * size);\n\t\t\tctx.strokeRect(x - size, y - size, 2 * size, 2 * size);\n\t\t\tbreak;\n\t\tcase 'rectRounded':\n\t\t\tvar offset = radius / Math.SQRT2;\n\t\t\tvar leftX = x - offset;\n\t\t\tvar topY = y - offset;\n\t\t\tvar sideSize = Math.SQRT2 * radius;\n\t\t\tChart.helpers.drawRoundedRectangle(ctx, leftX, topY, sideSize, sideSize, radius / 2);\n\t\t\tctx.fill();\n\t\t\tbreak;\n\t\tcase 'rectRot':\n\t\t\tsize = 1 / Math.SQRT2 * radius;\n\t\t\tctx.beginPath();\n\t\t\tctx.moveTo(x - size, y);\n\t\t\tctx.lineTo(x, y + size);\n\t\t\tctx.lineTo(x + size, y);\n\t\t\tctx.lineTo(x, y - size);\n\t\t\tctx.closePath();\n\t\t\tctx.fill();\n\t\t\tbreak;\n\t\tcase 'cross':\n\t\t\tctx.beginPath();\n\t\t\tctx.moveTo(x, y + radius);\n\t\t\tctx.lineTo(x, y - radius);\n\t\t\tctx.moveTo(x - radius, y);\n\t\t\tctx.lineTo(x + radius, y);\n\t\t\tctx.closePath();\n\t\t\tbreak;\n\t\tcase 'crossRot':\n\t\t\tctx.beginPath();\n\t\t\txOffset = Math.cos(Math.PI / 4) * radius;\n\t\t\tyOffset = Math.sin(Math.PI / 4) * radius;\n\t\t\tctx.moveTo(x - xOffset, y - yOffset);\n\t\t\tctx.lineTo(x + xOffset, y + yOffset);\n\t\t\tctx.moveTo(x - xOffset, y + yOffset);\n\t\t\tctx.lineTo(x + xOffset, y - yOffset);\n\t\t\tctx.closePath();\n\t\t\tbreak;\n\t\tcase 'star':\n\t\t\tctx.beginPath();\n\t\t\tctx.moveTo(x, y + radius);\n\t\t\tctx.lineTo(x, y - radius);\n\t\t\tctx.moveTo(x - radius, y);\n\t\t\tctx.lineTo(x + radius, y);\n\t\t\txOffset = Math.cos(Math.PI / 4) * radius;\n\t\t\tyOffset = Math.sin(Math.PI / 4) * radius;\n\t\t\tctx.moveTo(x - xOffset, y - yOffset);\n\t\t\tctx.lineTo(x + xOffset, y + yOffset);\n\t\t\tctx.moveTo(x - xOffset, y + yOffset);\n\t\t\tctx.lineTo(x + xOffset, y - yOffset);\n\t\t\tctx.closePath();\n\t\t\tbreak;\n\t\tcase 'line':\n\t\t\tctx.beginPath();\n\t\t\tctx.moveTo(x - radius, y);\n\t\t\tctx.lineTo(x + radius, y);\n\t\t\tctx.closePath();\n\t\t\tbreak;\n\t\tcase 'dash':\n\t\t\tctx.beginPath();\n\t\t\tctx.moveTo(x, y);\n\t\t\tctx.lineTo(x + radius, y);\n\t\t\tctx.closePath();\n\t\t\tbreak;\n\t\t}\n\n\t\tctx.stroke();\n\t};\n\n\thelpers.clipArea = function(ctx, clipArea) {\n\t\tctx.save();\n\t\tctx.beginPath();\n\t\tctx.rect(clipArea.left, clipArea.top, clipArea.right - clipArea.left, clipArea.bottom - clipArea.top);\n\t\tctx.clip();\n\t};\n\n\thelpers.unclipArea = function(ctx) {\n\t\tctx.restore();\n\t};\n\n\thelpers.lineTo = function(ctx, previous, target, flip) {\n\t\tif (target.steppedLine) {\n\t\t\tif (target.steppedLine === 'after') {\n\t\t\t\tctx.lineTo(previous.x, target.y);\n\t\t\t} else {\n\t\t\t\tctx.lineTo(target.x, previous.y);\n\t\t\t}\n\t\t\tctx.lineTo(target.x, target.y);\n\t\t\treturn;\n\t\t}\n\n\t\tif (!target.tension) {\n\t\t\tctx.lineTo(target.x, target.y);\n\t\t\treturn;\n\t\t}\n\n\t\tctx.bezierCurveTo(\n\t\t\tflip? previous.controlPointPreviousX : previous.controlPointNextX,\n\t\t\tflip? previous.controlPointPreviousY : previous.controlPointNextY,\n\t\t\tflip? target.controlPointNextX : target.controlPointPreviousX,\n\t\t\tflip? target.controlPointNextY : target.controlPointPreviousY,\n\t\t\ttarget.x,\n\t\t\ttarget.y);\n\t};\n\n\tChart.helpers.canvas = helpers;\n};\n\n},{}],23:[function(require,module,exports){\n'use strict';\n\nmodule.exports = function(Chart) {\n\n\tvar helpers = Chart.helpers;\n\tvar plugins = Chart.plugins;\n\tvar platform = Chart.platform;\n\n\t// Create a dictionary of chart types, to allow for extension of existing types\n\tChart.types = {};\n\n\t// Store a reference to each instance - allowing us to globally resize chart instances on window resize.\n\t// Destroy method on the chart will remove the instance of the chart from this reference.\n\tChart.instances = {};\n\n\t// Controllers available for dataset visualization eg. bar, line, slice, etc.\n\tChart.controllers = {};\n\n\t/**\n\t * Initializes the given config with global and chart default values.\n\t */\n\tfunction initConfig(config) {\n\t\tconfig = config || {};\n\n\t\t// Do NOT use configMerge() for the data object because this method merges arrays\n\t\t// and so would change references to labels and datasets, preventing data updates.\n\t\tvar data = config.data = config.data || {};\n\t\tdata.datasets = data.datasets || [];\n\t\tdata.labels = data.labels || [];\n\n\t\tconfig.options = helpers.configMerge(\n\t\t\tChart.defaults.global,\n\t\t\tChart.defaults[config.type],\n\t\t\tconfig.options || {});\n\n\t\treturn config;\n\t}\n\n\t/**\n\t * Updates the config of the chart\n\t * @param chart {Chart} chart to update the options for\n\t */\n\tfunction updateConfig(chart) {\n\t\tvar newOptions = chart.options;\n\n\t\t// Update Scale(s) with options\n\t\tif (newOptions.scale) {\n\t\t\tchart.scale.options = newOptions.scale;\n\t\t} else if (newOptions.scales) {\n\t\t\tnewOptions.scales.xAxes.concat(newOptions.scales.yAxes).forEach(function(scaleOptions) {\n\t\t\t\tchart.scales[scaleOptions.id].options = scaleOptions;\n\t\t\t});\n\t\t}\n\n\t\t// Tooltip\n\t\tchart.tooltip._options = newOptions.tooltips;\n\t}\n\n\tfunction positionIsHorizontal(position) {\n\t\treturn position === 'top' || position === 'bottom';\n\t}\n\n\thelpers.extend(Chart.prototype, /** @lends Chart */ {\n\t\t/**\n\t\t * @private\n\t\t */\n\t\tconstruct: function(item, config) {\n\t\t\tvar me = this;\n\n\t\t\tconfig = initConfig(config);\n\n\t\t\tvar context = platform.acquireContext(item, config);\n\t\t\tvar canvas = context && context.canvas;\n\t\t\tvar height = canvas && canvas.height;\n\t\t\tvar width = canvas && canvas.width;\n\n\t\t\tme.id = helpers.uid();\n\t\t\tme.ctx = context;\n\t\t\tme.canvas = canvas;\n\t\t\tme.config = config;\n\t\t\tme.width = width;\n\t\t\tme.height = height;\n\t\t\tme.aspectRatio = height? width / height : null;\n\t\t\tme.options = config.options;\n\t\t\tme._bufferedRender = false;\n\n\t\t\t/**\n\t\t\t * Provided for backward compatibility, Chart and Chart.Controller have been merged,\n\t\t\t * the \"instance\" still need to be defined since it might be called from plugins.\n\t\t\t * @prop Chart#chart\n\t\t\t * @deprecated since version 2.6.0\n\t\t\t * @todo remove at version 3\n\t\t\t * @private\n\t\t\t */\n\t\t\tme.chart = me;\n\t\t\tme.controller = me;  // chart.chart.controller #inception\n\n\t\t\t// Add the chart instance to the global namespace\n\t\t\tChart.instances[me.id] = me;\n\n\t\t\t// Define alias to the config data: `chart.data === chart.config.data`\n\t\t\tObject.defineProperty(me, 'data', {\n\t\t\t\tget: function() {\n\t\t\t\t\treturn me.config.data;\n\t\t\t\t},\n\t\t\t\tset: function(value) {\n\t\t\t\t\tme.config.data = value;\n\t\t\t\t}\n\t\t\t});\n\n\t\t\tif (!context || !canvas) {\n\t\t\t\t// The given item is not a compatible context2d element, let's return before finalizing\n\t\t\t\t// the chart initialization but after setting basic chart / controller properties that\n\t\t\t\t// can help to figure out that the chart is not valid (e.g chart.canvas !== null);\n\t\t\t\t// https://github.com/chartjs/Chart.js/issues/2807\n\t\t\t\tconsole.error(\"Failed to create chart: can't acquire context from the given item\");\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tme.initialize();\n\t\t\tme.update();\n\t\t},\n\n\t\t/**\n\t\t * @private\n\t\t */\n\t\tinitialize: function() {\n\t\t\tvar me = this;\n\n\t\t\t// Before init plugin notification\n\t\t\tplugins.notify(me, 'beforeInit');\n\n\t\t\thelpers.retinaScale(me);\n\n\t\t\tme.bindEvents();\n\n\t\t\tif (me.options.responsive) {\n\t\t\t\t// Initial resize before chart draws (must be silent to preserve initial animations).\n\t\t\t\tme.resize(true);\n\t\t\t}\n\n\t\t\t// Make sure scales have IDs and are built before we build any controllers.\n\t\t\tme.ensureScalesHaveIDs();\n\t\t\tme.buildScales();\n\t\t\tme.initToolTip();\n\n\t\t\t// After init plugin notification\n\t\t\tplugins.notify(me, 'afterInit');\n\n\t\t\treturn me;\n\t\t},\n\n\t\tclear: function() {\n\t\t\thelpers.clear(this);\n\t\t\treturn this;\n\t\t},\n\n\t\tstop: function() {\n\t\t\t// Stops any current animation loop occurring\n\t\t\tChart.animationService.cancelAnimation(this);\n\t\t\treturn this;\n\t\t},\n\n\t\tresize: function(silent) {\n\t\t\tvar me = this;\n\t\t\tvar options = me.options;\n\t\t\tvar canvas = me.canvas;\n\t\t\tvar aspectRatio = (options.maintainAspectRatio && me.aspectRatio) || null;\n\n\t\t\t// the canvas render width and height will be casted to integers so make sure that\n\t\t\t// the canvas display style uses the same integer values to avoid blurring effect.\n\t\t\tvar newWidth = Math.floor(helpers.getMaximumWidth(canvas));\n\t\t\tvar newHeight = Math.floor(aspectRatio? newWidth / aspectRatio : helpers.getMaximumHeight(canvas));\n\n\t\t\tif (me.width === newWidth && me.height === newHeight) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tcanvas.width = me.width = newWidth;\n\t\t\tcanvas.height = me.height = newHeight;\n\t\t\tcanvas.style.width = newWidth + 'px';\n\t\t\tcanvas.style.height = newHeight + 'px';\n\n\t\t\thelpers.retinaScale(me);\n\n\t\t\tif (!silent) {\n\t\t\t\t// Notify any plugins about the resize\n\t\t\t\tvar newSize = {width: newWidth, height: newHeight};\n\t\t\t\tplugins.notify(me, 'resize', [newSize]);\n\n\t\t\t\t// Notify of resize\n\t\t\t\tif (me.options.onResize) {\n\t\t\t\t\tme.options.onResize(me, newSize);\n\t\t\t\t}\n\n\t\t\t\tme.stop();\n\t\t\t\tme.update(me.options.responsiveAnimationDuration);\n\t\t\t}\n\t\t},\n\n\t\tensureScalesHaveIDs: function() {\n\t\t\tvar options = this.options;\n\t\t\tvar scalesOptions = options.scales || {};\n\t\t\tvar scaleOptions = options.scale;\n\n\t\t\thelpers.each(scalesOptions.xAxes, function(xAxisOptions, index) {\n\t\t\t\txAxisOptions.id = xAxisOptions.id || ('x-axis-' + index);\n\t\t\t});\n\n\t\t\thelpers.each(scalesOptions.yAxes, function(yAxisOptions, index) {\n\t\t\t\tyAxisOptions.id = yAxisOptions.id || ('y-axis-' + index);\n\t\t\t});\n\n\t\t\tif (scaleOptions) {\n\t\t\t\tscaleOptions.id = scaleOptions.id || 'scale';\n\t\t\t}\n\t\t},\n\n\t\t/**\n\t\t * Builds a map of scale ID to scale object for future lookup.\n\t\t */\n\t\tbuildScales: function() {\n\t\t\tvar me = this;\n\t\t\tvar options = me.options;\n\t\t\tvar scales = me.scales = {};\n\t\t\tvar items = [];\n\n\t\t\tif (options.scales) {\n\t\t\t\titems = items.concat(\n\t\t\t\t\t(options.scales.xAxes || []).map(function(xAxisOptions) {\n\t\t\t\t\t\treturn {options: xAxisOptions, dtype: 'category', dposition: 'bottom'};\n\t\t\t\t\t}),\n\t\t\t\t\t(options.scales.yAxes || []).map(function(yAxisOptions) {\n\t\t\t\t\t\treturn {options: yAxisOptions, dtype: 'linear', dposition: 'left'};\n\t\t\t\t\t})\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tif (options.scale) {\n\t\t\t\titems.push({\n\t\t\t\t\toptions: options.scale,\n\t\t\t\t\tdtype: 'radialLinear',\n\t\t\t\t\tisDefault: true,\n\t\t\t\t\tdposition: 'chartArea'\n\t\t\t\t});\n\t\t\t}\n\n\t\t\thelpers.each(items, function(item) {\n\t\t\t\tvar scaleOptions = item.options;\n\t\t\t\tvar scaleType = helpers.getValueOrDefault(scaleOptions.type, item.dtype);\n\t\t\t\tvar scaleClass = Chart.scaleService.getScaleConstructor(scaleType);\n\t\t\t\tif (!scaleClass) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tif (positionIsHorizontal(scaleOptions.position) !== positionIsHorizontal(item.dposition)) {\n\t\t\t\t\tscaleOptions.position = item.dposition;\n\t\t\t\t}\n\n\t\t\t\tvar scale = new scaleClass({\n\t\t\t\t\tid: scaleOptions.id,\n\t\t\t\t\toptions: scaleOptions,\n\t\t\t\t\tctx: me.ctx,\n\t\t\t\t\tchart: me\n\t\t\t\t});\n\n\t\t\t\tscales[scale.id] = scale;\n\n\t\t\t\t// TODO(SB): I think we should be able to remove this custom case (options.scale)\n\t\t\t\t// and consider it as a regular scale part of the \"scales\"\" map only! This would\n\t\t\t\t// make the logic easier and remove some useless? custom code.\n\t\t\t\tif (item.isDefault) {\n\t\t\t\t\tme.scale = scale;\n\t\t\t\t}\n\t\t\t});\n\n\t\t\tChart.scaleService.addScalesToLayout(this);\n\t\t},\n\n\t\tbuildOrUpdateControllers: function() {\n\t\t\tvar me = this;\n\t\t\tvar types = [];\n\t\t\tvar newControllers = [];\n\n\t\t\thelpers.each(me.data.datasets, function(dataset, datasetIndex) {\n\t\t\t\tvar meta = me.getDatasetMeta(datasetIndex);\n\t\t\t\tif (!meta.type) {\n\t\t\t\t\tmeta.type = dataset.type || me.config.type;\n\t\t\t\t}\n\n\t\t\t\ttypes.push(meta.type);\n\n\t\t\t\tif (meta.controller) {\n\t\t\t\t\tmeta.controller.updateIndex(datasetIndex);\n\t\t\t\t} else {\n\t\t\t\t\tvar ControllerClass = Chart.controllers[meta.type];\n\t\t\t\t\tif (ControllerClass === undefined) {\n\t\t\t\t\t\tthrow new Error('\"' + meta.type + '\" is not a chart type.');\n\t\t\t\t\t}\n\n\t\t\t\t\tmeta.controller = new ControllerClass(me, datasetIndex);\n\t\t\t\t\tnewControllers.push(meta.controller);\n\t\t\t\t}\n\t\t\t}, me);\n\n\t\t\tif (types.length > 1) {\n\t\t\t\tfor (var i = 1; i < types.length; i++) {\n\t\t\t\t\tif (types[i] !== types[i - 1]) {\n\t\t\t\t\t\tme.isCombo = true;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn newControllers;\n\t\t},\n\n\t\t/**\n\t\t * Reset the elements of all datasets\n\t\t * @private\n\t\t */\n\t\tresetElements: function() {\n\t\t\tvar me = this;\n\t\t\thelpers.each(me.data.datasets, function(dataset, datasetIndex) {\n\t\t\t\tme.getDatasetMeta(datasetIndex).controller.reset();\n\t\t\t}, me);\n\t\t},\n\n\t\t/**\n\t\t* Resets the chart back to it's state before the initial animation\n\t\t*/\n\t\treset: function() {\n\t\t\tthis.resetElements();\n\t\t\tthis.tooltip.initialize();\n\t\t},\n\n\t\tupdate: function(animationDuration, lazy) {\n\t\t\tvar me = this;\n\n\t\t\tupdateConfig(me);\n\n\t\t\tif (plugins.notify(me, 'beforeUpdate') === false) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// In case the entire data object changed\n\t\t\tme.tooltip._data = me.data;\n\n\t\t\t// Make sure dataset controllers are updated and new controllers are reset\n\t\t\tvar newControllers = me.buildOrUpdateControllers();\n\n\t\t\t// Make sure all dataset controllers have correct meta data counts\n\t\t\thelpers.each(me.data.datasets, function(dataset, datasetIndex) {\n\t\t\t\tme.getDatasetMeta(datasetIndex).controller.buildOrUpdateElements();\n\t\t\t}, me);\n\n\t\t\tme.updateLayout();\n\n\t\t\t// Can only reset the new controllers after the scales have been updated\n\t\t\thelpers.each(newControllers, function(controller) {\n\t\t\t\tcontroller.reset();\n\t\t\t});\n\n\t\t\tme.updateDatasets();\n\n\t\t\t// Do this before render so that any plugins that need final scale updates can use it\n\t\t\tplugins.notify(me, 'afterUpdate');\n\n\t\t\tif (me._bufferedRender) {\n\t\t\t\tme._bufferedRequest = {\n\t\t\t\t\tlazy: lazy,\n\t\t\t\t\tduration: animationDuration\n\t\t\t\t};\n\t\t\t} else {\n\t\t\t\tme.render(animationDuration, lazy);\n\t\t\t}\n\t\t},\n\n\t\t/**\n\t\t * Updates the chart layout unless a plugin returns `false` to the `beforeLayout`\n\t\t * hook, in which case, plugins will not be called on `afterLayout`.\n\t\t * @private\n\t\t */\n\t\tupdateLayout: function() {\n\t\t\tvar me = this;\n\n\t\t\tif (plugins.notify(me, 'beforeLayout') === false) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tChart.layoutService.update(this, this.width, this.height);\n\n\t\t\t/**\n\t\t\t * Provided for backward compatibility, use `afterLayout` instead.\n\t\t\t * @method IPlugin#afterScaleUpdate\n\t\t\t * @deprecated since version 2.5.0\n\t\t\t * @todo remove at version 3\n\t\t\t * @private\n\t\t\t */\n\t\t\tplugins.notify(me, 'afterScaleUpdate');\n\t\t\tplugins.notify(me, 'afterLayout');\n\t\t},\n\n\t\t/**\n\t\t * Updates all datasets unless a plugin returns `false` to the `beforeDatasetsUpdate`\n\t\t * hook, in which case, plugins will not be called on `afterDatasetsUpdate`.\n\t\t * @private\n\t\t */\n\t\tupdateDatasets: function() {\n\t\t\tvar me = this;\n\n\t\t\tif (plugins.notify(me, 'beforeDatasetsUpdate') === false) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tfor (var i = 0, ilen = me.data.datasets.length; i < ilen; ++i) {\n\t\t\t\tme.updateDataset(i);\n\t\t\t}\n\n\t\t\tplugins.notify(me, 'afterDatasetsUpdate');\n\t\t},\n\n\t\t/**\n\t\t * Updates dataset at index unless a plugin returns `false` to the `beforeDatasetUpdate`\n\t\t * hook, in which case, plugins will not be called on `afterDatasetUpdate`.\n\t\t * @private\n\t\t */\n\t\tupdateDataset: function(index) {\n\t\t\tvar me = this;\n\t\t\tvar meta = me.getDatasetMeta(index);\n\t\t\tvar args = {\n\t\t\t\tmeta: meta,\n\t\t\t\tindex: index\n\t\t\t};\n\n\t\t\tif (plugins.notify(me, 'beforeDatasetUpdate', [args]) === false) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tmeta.controller.update();\n\n\t\t\tplugins.notify(me, 'afterDatasetUpdate', [args]);\n\t\t},\n\n\t\trender: function(duration, lazy) {\n\t\t\tvar me = this;\n\n\t\t\tif (plugins.notify(me, 'beforeRender') === false) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tvar animationOptions = me.options.animation;\n\t\t\tvar onComplete = function(animation) {\n\t\t\t\tplugins.notify(me, 'afterRender');\n\t\t\t\thelpers.callback(animationOptions && animationOptions.onComplete, [animation], me);\n\t\t\t};\n\n\t\t\tif (animationOptions && ((typeof duration !== 'undefined' && duration !== 0) || (typeof duration === 'undefined' && animationOptions.duration !== 0))) {\n\t\t\t\tvar animation = new Chart.Animation({\n\t\t\t\t\tnumSteps: (duration || animationOptions.duration) / 16.66, // 60 fps\n\t\t\t\t\teasing: animationOptions.easing,\n\n\t\t\t\t\trender: function(chart, animationObject) {\n\t\t\t\t\t\tvar easingFunction = helpers.easingEffects[animationObject.easing];\n\t\t\t\t\t\tvar currentStep = animationObject.currentStep;\n\t\t\t\t\t\tvar stepDecimal = currentStep / animationObject.numSteps;\n\n\t\t\t\t\t\tchart.draw(easingFunction(stepDecimal), stepDecimal, currentStep);\n\t\t\t\t\t},\n\n\t\t\t\t\tonAnimationProgress: animationOptions.onProgress,\n\t\t\t\t\tonAnimationComplete: onComplete\n\t\t\t\t});\n\n\t\t\t\tChart.animationService.addAnimation(me, animation, duration, lazy);\n\t\t\t} else {\n\t\t\t\tme.draw();\n\n\t\t\t\t// See https://github.com/chartjs/Chart.js/issues/3781\n\t\t\t\tonComplete(new Chart.Animation({numSteps: 0, chart: me}));\n\t\t\t}\n\n\t\t\treturn me;\n\t\t},\n\n\t\tdraw: function(easingValue) {\n\t\t\tvar me = this;\n\n\t\t\tme.clear();\n\n\t\t\tif (easingValue === undefined || easingValue === null) {\n\t\t\t\teasingValue = 1;\n\t\t\t}\n\n\t\t\tme.transition(easingValue);\n\n\t\t\tif (plugins.notify(me, 'beforeDraw', [easingValue]) === false) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// Draw all the scales\n\t\t\thelpers.each(me.boxes, function(box) {\n\t\t\t\tbox.draw(me.chartArea);\n\t\t\t}, me);\n\n\t\t\tif (me.scale) {\n\t\t\t\tme.scale.draw();\n\t\t\t}\n\n\t\t\tme.drawDatasets(easingValue);\n\n\t\t\t// Finally draw the tooltip\n\t\t\tme.tooltip.draw();\n\n\t\t\tplugins.notify(me, 'afterDraw', [easingValue]);\n\t\t},\n\n\t\t/**\n\t\t * @private\n\t\t */\n\t\ttransition: function(easingValue) {\n\t\t\tvar me = this;\n\n\t\t\tfor (var i=0, ilen=(me.data.datasets || []).length; i<ilen; ++i) {\n\t\t\t\tif (me.isDatasetVisible(i)) {\n\t\t\t\t\tme.getDatasetMeta(i).controller.transition(easingValue);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tme.tooltip.transition(easingValue);\n\t\t},\n\n\t\t/**\n\t\t * Draws all datasets unless a plugin returns `false` to the `beforeDatasetsDraw`\n\t\t * hook, in which case, plugins will not be called on `afterDatasetsDraw`.\n\t\t * @private\n\t\t */\n\t\tdrawDatasets: function(easingValue) {\n\t\t\tvar me = this;\n\n\t\t\tif (plugins.notify(me, 'beforeDatasetsDraw', [easingValue]) === false) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// Draw datasets reversed to support proper line stacking\n\t\t\tfor (var i=(me.data.datasets || []).length - 1; i >= 0; --i) {\n\t\t\t\tif (me.isDatasetVisible(i)) {\n\t\t\t\t\tme.drawDataset(i, easingValue);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tplugins.notify(me, 'afterDatasetsDraw', [easingValue]);\n\t\t},\n\n\t\t/**\n\t\t * Draws dataset at index unless a plugin returns `false` to the `beforeDatasetDraw`\n\t\t * hook, in which case, plugins will not be called on `afterDatasetDraw`.\n\t\t * @private\n\t\t */\n\t\tdrawDataset: function(index, easingValue) {\n\t\t\tvar me = this;\n\t\t\tvar meta = me.getDatasetMeta(index);\n\t\t\tvar args = {\n\t\t\t\tmeta: meta,\n\t\t\t\tindex: index,\n\t\t\t\teasingValue: easingValue\n\t\t\t};\n\n\t\t\tif (plugins.notify(me, 'beforeDatasetDraw', [args]) === false) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tmeta.controller.draw(easingValue);\n\n\t\t\tplugins.notify(me, 'afterDatasetDraw', [args]);\n\t\t},\n\n\t\t// Get the single element that was clicked on\n\t\t// @return : An object containing the dataset index and element index of the matching element. Also contains the rectangle that was draw\n\t\tgetElementAtEvent: function(e) {\n\t\t\treturn Chart.Interaction.modes.single(this, e);\n\t\t},\n\n\t\tgetElementsAtEvent: function(e) {\n\t\t\treturn Chart.Interaction.modes.label(this, e, {intersect: true});\n\t\t},\n\n\t\tgetElementsAtXAxis: function(e) {\n\t\t\treturn Chart.Interaction.modes['x-axis'](this, e, {intersect: true});\n\t\t},\n\n\t\tgetElementsAtEventForMode: function(e, mode, options) {\n\t\t\tvar method = Chart.Interaction.modes[mode];\n\t\t\tif (typeof method === 'function') {\n\t\t\t\treturn method(this, e, options);\n\t\t\t}\n\n\t\t\treturn [];\n\t\t},\n\n\t\tgetDatasetAtEvent: function(e) {\n\t\t\treturn Chart.Interaction.modes.dataset(this, e, {intersect: true});\n\t\t},\n\n\t\tgetDatasetMeta: function(datasetIndex) {\n\t\t\tvar me = this;\n\t\t\tvar dataset = me.data.datasets[datasetIndex];\n\t\t\tif (!dataset._meta) {\n\t\t\t\tdataset._meta = {};\n\t\t\t}\n\n\t\t\tvar meta = dataset._meta[me.id];\n\t\t\tif (!meta) {\n\t\t\t\tmeta = dataset._meta[me.id] = {\n\t\t\t\t\ttype: null,\n\t\t\t\t\tdata: [],\n\t\t\t\t\tdataset: null,\n\t\t\t\t\tcontroller: null,\n\t\t\t\t\thidden: null,\t\t\t// See isDatasetVisible() comment\n\t\t\t\t\txAxisID: null,\n\t\t\t\t\tyAxisID: null\n\t\t\t\t};\n\t\t\t}\n\n\t\t\treturn meta;\n\t\t},\n\n\t\tgetVisibleDatasetCount: function() {\n\t\t\tvar count = 0;\n\t\t\tfor (var i = 0, ilen = this.data.datasets.length; i<ilen; ++i) {\n\t\t\t\tif (this.isDatasetVisible(i)) {\n\t\t\t\t\tcount++;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn count;\n\t\t},\n\n\t\tisDatasetVisible: function(datasetIndex) {\n\t\t\tvar meta = this.getDatasetMeta(datasetIndex);\n\n\t\t\t// meta.hidden is a per chart dataset hidden flag override with 3 states: if true or false,\n\t\t\t// the dataset.hidden value is ignored, else if null, the dataset hidden state is returned.\n\t\t\treturn typeof meta.hidden === 'boolean'? !meta.hidden : !this.data.datasets[datasetIndex].hidden;\n\t\t},\n\n\t\tgenerateLegend: function() {\n\t\t\treturn this.options.legendCallback(this);\n\t\t},\n\n\t\tdestroy: function() {\n\t\t\tvar me = this;\n\t\t\tvar canvas = me.canvas;\n\t\t\tvar meta, i, ilen;\n\n\t\t\tme.stop();\n\n\t\t\t// dataset controllers need to cleanup associated data\n\t\t\tfor (i = 0, ilen = me.data.datasets.length; i < ilen; ++i) {\n\t\t\t\tmeta = me.getDatasetMeta(i);\n\t\t\t\tif (meta.controller) {\n\t\t\t\t\tmeta.controller.destroy();\n\t\t\t\t\tmeta.controller = null;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (canvas) {\n\t\t\t\tme.unbindEvents();\n\t\t\t\thelpers.clear(me);\n\t\t\t\tplatform.releaseContext(me.ctx);\n\t\t\t\tme.canvas = null;\n\t\t\t\tme.ctx = null;\n\t\t\t}\n\n\t\t\tplugins.notify(me, 'destroy');\n\n\t\t\tdelete Chart.instances[me.id];\n\t\t},\n\n\t\ttoBase64Image: function() {\n\t\t\treturn this.canvas.toDataURL.apply(this.canvas, arguments);\n\t\t},\n\n\t\tinitToolTip: function() {\n\t\t\tvar me = this;\n\t\t\tme.tooltip = new Chart.Tooltip({\n\t\t\t\t_chart: me,\n\t\t\t\t_chartInstance: me,            // deprecated, backward compatibility\n\t\t\t\t_data: me.data,\n\t\t\t\t_options: me.options.tooltips\n\t\t\t}, me);\n\t\t\tme.tooltip.initialize();\n\t\t},\n\n\t\t/**\n\t\t * @private\n\t\t */\n\t\tbindEvents: function() {\n\t\t\tvar me = this;\n\t\t\tvar listeners = me._listeners = {};\n\t\t\tvar listener = function() {\n\t\t\t\tme.eventHandler.apply(me, arguments);\n\t\t\t};\n\n\t\t\thelpers.each(me.options.events, function(type) {\n\t\t\t\tplatform.addEventListener(me, type, listener);\n\t\t\t\tlisteners[type] = listener;\n\t\t\t});\n\n\t\t\t// Responsiveness is currently based on the use of an iframe, however this method causes\n\t\t\t// performance issues and could be troublesome when used with ad blockers. So make sure\n\t\t\t// that the user is still able to create a chart without iframe when responsive is false.\n\t\t\t// See https://github.com/chartjs/Chart.js/issues/2210\n\t\t\tif (me.options.responsive) {\n\t\t\t\tlistener = function() {\n\t\t\t\t\tme.resize();\n\t\t\t\t};\n\n\t\t\t\tplatform.addEventListener(me, 'resize', listener);\n\t\t\t\tlisteners.resize = listener;\n\t\t\t}\n\t\t},\n\n\t\t/**\n\t\t * @private\n\t\t */\n\t\tunbindEvents: function() {\n\t\t\tvar me = this;\n\t\t\tvar listeners = me._listeners;\n\t\t\tif (!listeners) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tdelete me._listeners;\n\t\t\thelpers.each(listeners, function(listener, type) {\n\t\t\t\tplatform.removeEventListener(me, type, listener);\n\t\t\t});\n\t\t},\n\n\t\tupdateHoverStyle: function(elements, mode, enabled) {\n\t\t\tvar method = enabled? 'setHoverStyle' : 'removeHoverStyle';\n\t\t\tvar element, i, ilen;\n\n\t\t\tfor (i=0, ilen=elements.length; i<ilen; ++i) {\n\t\t\t\telement = elements[i];\n\t\t\t\tif (element) {\n\t\t\t\t\tthis.getDatasetMeta(element._datasetIndex).controller[method](element);\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\n\t\t/**\n\t\t * @private\n\t\t */\n\t\teventHandler: function(e) {\n\t\t\tvar me = this;\n\t\t\tvar tooltip = me.tooltip;\n\n\t\t\tif (plugins.notify(me, 'beforeEvent', [e]) === false) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// Buffer any update calls so that renders do not occur\n\t\t\tme._bufferedRender = true;\n\t\t\tme._bufferedRequest = null;\n\n\t\t\tvar changed = me.handleEvent(e);\n\t\t\tchanged |= tooltip && tooltip.handleEvent(e);\n\n\t\t\tplugins.notify(me, 'afterEvent', [e]);\n\n\t\t\tvar bufferedRequest = me._bufferedRequest;\n\t\t\tif (bufferedRequest) {\n\t\t\t\t// If we have an update that was triggered, we need to do a normal render\n\t\t\t\tme.render(bufferedRequest.duration, bufferedRequest.lazy);\n\t\t\t} else if (changed && !me.animating) {\n\t\t\t\t// If entering, leaving, or changing elements, animate the change via pivot\n\t\t\t\tme.stop();\n\n\t\t\t\t// We only need to render at this point. Updating will cause scales to be\n\t\t\t\t// recomputed generating flicker & using more memory than necessary.\n\t\t\t\tme.render(me.options.hover.animationDuration, true);\n\t\t\t}\n\n\t\t\tme._bufferedRender = false;\n\t\t\tme._bufferedRequest = null;\n\n\t\t\treturn me;\n\t\t},\n\n\t\t/**\n\t\t * Handle an event\n\t\t * @private\n\t\t * @param {IEvent} event the event to handle\n\t\t * @return {Boolean} true if the chart needs to re-render\n\t\t */\n\t\thandleEvent: function(e) {\n\t\t\tvar me = this;\n\t\t\tvar options = me.options || {};\n\t\t\tvar hoverOptions = options.hover;\n\t\t\tvar changed = false;\n\n\t\t\tme.lastActive = me.lastActive || [];\n\n\t\t\t// Find Active Elements for hover and tooltips\n\t\t\tif (e.type === 'mouseout') {\n\t\t\t\tme.active = [];\n\t\t\t} else {\n\t\t\t\tme.active = me.getElementsAtEventForMode(e, hoverOptions.mode, hoverOptions);\n\t\t\t}\n\n\t\t\t// On Hover hook\n\t\t\tif (hoverOptions.onHover) {\n\t\t\t\t// Need to call with native event here to not break backwards compatibility\n\t\t\t\thoverOptions.onHover.call(me, e.native, me.active);\n\t\t\t}\n\n\t\t\tif (e.type === 'mouseup' || e.type === 'click') {\n\t\t\t\tif (options.onClick) {\n\t\t\t\t\t// Use e.native here for backwards compatibility\n\t\t\t\t\toptions.onClick.call(me, e.native, me.active);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Remove styling for last active (even if it may still be active)\n\t\t\tif (me.lastActive.length) {\n\t\t\t\tme.updateHoverStyle(me.lastActive, hoverOptions.mode, false);\n\t\t\t}\n\n\t\t\t// Built in hover styling\n\t\t\tif (me.active.length && hoverOptions.mode) {\n\t\t\t\tme.updateHoverStyle(me.active, hoverOptions.mode, true);\n\t\t\t}\n\n\t\t\tchanged = !helpers.arrayEquals(me.active, me.lastActive);\n\n\t\t\t// Remember Last Actives\n\t\t\tme.lastActive = me.active;\n\n\t\t\treturn changed;\n\t\t}\n\t});\n\n\t/**\n\t * Provided for backward compatibility, use Chart instead.\n\t * @class Chart.Controller\n\t * @deprecated since version 2.6.0\n\t * @todo remove at version 3\n\t * @private\n\t */\n\tChart.Controller = Chart;\n};\n\n},{}],24:[function(require,module,exports){\n'use strict';\n\nmodule.exports = function(Chart) {\n\n\tvar helpers = Chart.helpers;\n\n\tvar arrayEvents = ['push', 'pop', 'shift', 'splice', 'unshift'];\n\n\t/**\n\t * Hooks the array methods that add or remove values ('push', pop', 'shift', 'splice',\n\t * 'unshift') and notify the listener AFTER the array has been altered. Listeners are\n\t * called on the 'onData*' callbacks (e.g. onDataPush, etc.) with same arguments.\n\t */\n\tfunction listenArrayEvents(array, listener) {\n\t\tif (array._chartjs) {\n\t\t\tarray._chartjs.listeners.push(listener);\n\t\t\treturn;\n\t\t}\n\n\t\tObject.defineProperty(array, '_chartjs', {\n\t\t\tconfigurable: true,\n\t\t\tenumerable: false,\n\t\t\tvalue: {\n\t\t\t\tlisteners: [listener]\n\t\t\t}\n\t\t});\n\n\t\tarrayEvents.forEach(function(key) {\n\t\t\tvar method = 'onData' + key.charAt(0).toUpperCase() + key.slice(1);\n\t\t\tvar base = array[key];\n\n\t\t\tObject.defineProperty(array, key, {\n\t\t\t\tconfigurable: true,\n\t\t\t\tenumerable: false,\n\t\t\t\tvalue: function() {\n\t\t\t\t\tvar args = Array.prototype.slice.call(arguments);\n\t\t\t\t\tvar res = base.apply(this, args);\n\n\t\t\t\t\thelpers.each(array._chartjs.listeners, function(object) {\n\t\t\t\t\t\tif (typeof object[method] === 'function') {\n\t\t\t\t\t\t\tobject[method].apply(object, args);\n\t\t\t\t\t\t}\n\t\t\t\t\t});\n\n\t\t\t\t\treturn res;\n\t\t\t\t}\n\t\t\t});\n\t\t});\n\t}\n\n\t/**\n\t * Removes the given array event listener and cleanup extra attached properties (such as\n\t * the _chartjs stub and overridden methods) if array doesn't have any more listeners.\n\t */\n\tfunction unlistenArrayEvents(array, listener) {\n\t\tvar stub = array._chartjs;\n\t\tif (!stub) {\n\t\t\treturn;\n\t\t}\n\n\t\tvar listeners = stub.listeners;\n\t\tvar index = listeners.indexOf(listener);\n\t\tif (index !== -1) {\n\t\t\tlisteners.splice(index, 1);\n\t\t}\n\n\t\tif (listeners.length > 0) {\n\t\t\treturn;\n\t\t}\n\n\t\tarrayEvents.forEach(function(key) {\n\t\t\tdelete array[key];\n\t\t});\n\n\t\tdelete array._chartjs;\n\t}\n\n\t// Base class for all dataset controllers (line, bar, etc)\n\tChart.DatasetController = function(chart, datasetIndex) {\n\t\tthis.initialize(chart, datasetIndex);\n\t};\n\n\thelpers.extend(Chart.DatasetController.prototype, {\n\n\t\t/**\n\t\t * Element type used to generate a meta dataset (e.g. Chart.element.Line).\n\t\t * @type {Chart.core.element}\n\t\t */\n\t\tdatasetElementType: null,\n\n\t\t/**\n\t\t * Element type used to generate a meta data (e.g. Chart.element.Point).\n\t\t * @type {Chart.core.element}\n\t\t */\n\t\tdataElementType: null,\n\n\t\tinitialize: function(chart, datasetIndex) {\n\t\t\tvar me = this;\n\t\t\tme.chart = chart;\n\t\t\tme.index = datasetIndex;\n\t\t\tme.linkScales();\n\t\t\tme.addElements();\n\t\t},\n\n\t\tupdateIndex: function(datasetIndex) {\n\t\t\tthis.index = datasetIndex;\n\t\t},\n\n\t\tlinkScales: function() {\n\t\t\tvar me = this;\n\t\t\tvar meta = me.getMeta();\n\t\t\tvar dataset = me.getDataset();\n\n\t\t\tif (meta.xAxisID === null) {\n\t\t\t\tmeta.xAxisID = dataset.xAxisID || me.chart.options.scales.xAxes[0].id;\n\t\t\t}\n\t\t\tif (meta.yAxisID === null) {\n\t\t\t\tmeta.yAxisID = dataset.yAxisID || me.chart.options.scales.yAxes[0].id;\n\t\t\t}\n\t\t},\n\n\t\tgetDataset: function() {\n\t\t\treturn this.chart.data.datasets[this.index];\n\t\t},\n\n\t\tgetMeta: function() {\n\t\t\treturn this.chart.getDatasetMeta(this.index);\n\t\t},\n\n\t\tgetScaleForId: function(scaleID) {\n\t\t\treturn this.chart.scales[scaleID];\n\t\t},\n\n\t\treset: function() {\n\t\t\tthis.update(true);\n\t\t},\n\n\t\t/**\n\t\t * @private\n\t\t */\n\t\tdestroy: function() {\n\t\t\tif (this._data) {\n\t\t\t\tunlistenArrayEvents(this._data, this);\n\t\t\t}\n\t\t},\n\n\t\tcreateMetaDataset: function() {\n\t\t\tvar me = this;\n\t\t\tvar type = me.datasetElementType;\n\t\t\treturn type && new type({\n\t\t\t\t_chart: me.chart,\n\t\t\t\t_datasetIndex: me.index\n\t\t\t});\n\t\t},\n\n\t\tcreateMetaData: function(index) {\n\t\t\tvar me = this;\n\t\t\tvar type = me.dataElementType;\n\t\t\treturn type && new type({\n\t\t\t\t_chart: me.chart,\n\t\t\t\t_datasetIndex: me.index,\n\t\t\t\t_index: index\n\t\t\t});\n\t\t},\n\n\t\taddElements: function() {\n\t\t\tvar me = this;\n\t\t\tvar meta = me.getMeta();\n\t\t\tvar data = me.getDataset().data || [];\n\t\t\tvar metaData = meta.data;\n\t\t\tvar i, ilen;\n\n\t\t\tfor (i=0, ilen=data.length; i<ilen; ++i) {\n\t\t\t\tmetaData[i] = metaData[i] || me.createMetaData(i);\n\t\t\t}\n\n\t\t\tmeta.dataset = meta.dataset || me.createMetaDataset();\n\t\t},\n\n\t\taddElementAndReset: function(index) {\n\t\t\tvar element = this.createMetaData(index);\n\t\t\tthis.getMeta().data.splice(index, 0, element);\n\t\t\tthis.updateElement(element, index, true);\n\t\t},\n\n\t\tbuildOrUpdateElements: function() {\n\t\t\tvar me = this;\n\t\t\tvar dataset = me.getDataset();\n\t\t\tvar data = dataset.data || (dataset.data = []);\n\n\t\t\t// In order to correctly handle data addition/deletion animation (an thus simulate\n\t\t\t// real-time charts), we need to monitor these data modifications and synchronize\n\t\t\t// the internal meta data accordingly.\n\t\t\tif (me._data !== data) {\n\t\t\t\tif (me._data) {\n\t\t\t\t\t// This case happens when the user replaced the data array instance.\n\t\t\t\t\tunlistenArrayEvents(me._data, me);\n\t\t\t\t}\n\n\t\t\t\tlistenArrayEvents(data, me);\n\t\t\t\tme._data = data;\n\t\t\t}\n\n\t\t\t// Re-sync meta data in case the user replaced the data array or if we missed\n\t\t\t// any updates and so make sure that we handle number of datapoints changing.\n\t\t\tme.resyncElements();\n\t\t},\n\n\t\tupdate: helpers.noop,\n\n\t\ttransition: function(easingValue) {\n\t\t\tvar meta = this.getMeta();\n\t\t\tvar elements = meta.data || [];\n\t\t\tvar ilen = elements.length;\n\t\t\tvar i = 0;\n\n\t\t\tfor (; i<ilen; ++i) {\n\t\t\t\telements[i].transition(easingValue);\n\t\t\t}\n\n\t\t\tif (meta.dataset) {\n\t\t\t\tmeta.dataset.transition(easingValue);\n\t\t\t}\n\t\t},\n\n\t\tdraw: function() {\n\t\t\tvar meta = this.getMeta();\n\t\t\tvar elements = meta.data || [];\n\t\t\tvar ilen = elements.length;\n\t\t\tvar i = 0;\n\n\t\t\tif (meta.dataset) {\n\t\t\t\tmeta.dataset.draw();\n\t\t\t}\n\n\t\t\tfor (; i<ilen; ++i) {\n\t\t\t\telements[i].draw();\n\t\t\t}\n\t\t},\n\n\t\tremoveHoverStyle: function(element, elementOpts) {\n\t\t\tvar dataset = this.chart.data.datasets[element._datasetIndex],\n\t\t\t\tindex = element._index,\n\t\t\t\tcustom = element.custom || {},\n\t\t\t\tvalueOrDefault = helpers.getValueAtIndexOrDefault,\n\t\t\t\tmodel = element._model;\n\n\t\t\tmodel.backgroundColor = custom.backgroundColor ? custom.backgroundColor : valueOrDefault(dataset.backgroundColor, index, elementOpts.backgroundColor);\n\t\t\tmodel.borderColor = custom.borderColor ? custom.borderColor : valueOrDefault(dataset.borderColor, index, elementOpts.borderColor);\n\t\t\tmodel.borderWidth = custom.borderWidth ? custom.borderWidth : valueOrDefault(dataset.borderWidth, index, elementOpts.borderWidth);\n\t\t},\n\n\t\tsetHoverStyle: function(element) {\n\t\t\tvar dataset = this.chart.data.datasets[element._datasetIndex],\n\t\t\t\tindex = element._index,\n\t\t\t\tcustom = element.custom || {},\n\t\t\t\tvalueOrDefault = helpers.getValueAtIndexOrDefault,\n\t\t\t\tgetHoverColor = helpers.getHoverColor,\n\t\t\t\tmodel = element._model;\n\n\t\t\tmodel.backgroundColor = custom.hoverBackgroundColor ? custom.hoverBackgroundColor : valueOrDefault(dataset.hoverBackgroundColor, index, getHoverColor(model.backgroundColor));\n\t\t\tmodel.borderColor = custom.hoverBorderColor ? custom.hoverBorderColor : valueOrDefault(dataset.hoverBorderColor, index, getHoverColor(model.borderColor));\n\t\t\tmodel.borderWidth = custom.hoverBorderWidth ? custom.hoverBorderWidth : valueOrDefault(dataset.hoverBorderWidth, index, model.borderWidth);\n\t\t},\n\n\t\t/**\n\t\t * @private\n\t\t */\n\t\tresyncElements: function() {\n\t\t\tvar me = this;\n\t\t\tvar meta = me.getMeta();\n\t\t\tvar data = me.getDataset().data;\n\t\t\tvar numMeta = meta.data.length;\n\t\t\tvar numData = data.length;\n\n\t\t\tif (numData < numMeta) {\n\t\t\t\tmeta.data.splice(numData, numMeta - numData);\n\t\t\t} else if (numData > numMeta) {\n\t\t\t\tme.insertElements(numMeta, numData - numMeta);\n\t\t\t}\n\t\t},\n\n\t\t/**\n\t\t * @private\n\t\t */\n\t\tinsertElements: function(start, count) {\n\t\t\tfor (var i=0; i<count; ++i) {\n\t\t\t\tthis.addElementAndReset(start + i);\n\t\t\t}\n\t\t},\n\n\t\t/**\n\t\t * @private\n\t\t */\n\t\tonDataPush: function() {\n\t\t\tthis.insertElements(this.getDataset().data.length-1, arguments.length);\n\t\t},\n\n\t\t/**\n\t\t * @private\n\t\t */\n\t\tonDataPop: function() {\n\t\t\tthis.getMeta().data.pop();\n\t\t},\n\n\t\t/**\n\t\t * @private\n\t\t */\n\t\tonDataShift: function() {\n\t\t\tthis.getMeta().data.shift();\n\t\t},\n\n\t\t/**\n\t\t * @private\n\t\t */\n\t\tonDataSplice: function(start, count) {\n\t\t\tthis.getMeta().data.splice(start, count);\n\t\t\tthis.insertElements(start, arguments.length - 2);\n\t\t},\n\n\t\t/**\n\t\t * @private\n\t\t */\n\t\tonDataUnshift: function() {\n\t\t\tthis.insertElements(0, arguments.length);\n\t\t}\n\t});\n\n\tChart.DatasetController.extend = helpers.inherits;\n};\n\n},{}],25:[function(require,module,exports){\n'use strict';\n\nvar color = require(2);\n\nmodule.exports = function(Chart) {\n\n\tvar helpers = Chart.helpers;\n\n\tfunction interpolate(start, view, model, ease) {\n\t\tvar keys = Object.keys(model);\n\t\tvar i, ilen, key, actual, origin, target, type, c0, c1;\n\n\t\tfor (i=0, ilen=keys.length; i<ilen; ++i) {\n\t\t\tkey = keys[i];\n\n\t\t\ttarget = model[key];\n\n\t\t\t// if a value is added to the model after pivot() has been called, the view\n\t\t\t// doesn't contain it, so let's initialize the view to the target value.\n\t\t\tif (!view.hasOwnProperty(key)) {\n\t\t\t\tview[key] = target;\n\t\t\t}\n\n\t\t\tactual = view[key];\n\n\t\t\tif (actual === target || key[0] === '_') {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tif (!start.hasOwnProperty(key)) {\n\t\t\t\tstart[key] = actual;\n\t\t\t}\n\n\t\t\torigin = start[key];\n\n\t\t\ttype = typeof(target);\n\n\t\t\tif (type === typeof(origin)) {\n\t\t\t\tif (type === 'string') {\n\t\t\t\t\tc0 = color(origin);\n\t\t\t\t\tif (c0.valid) {\n\t\t\t\t\t\tc1 = color(target);\n\t\t\t\t\t\tif (c1.valid) {\n\t\t\t\t\t\t\tview[key] = c1.mix(c0, ease).rgbString();\n\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t} else if (type === 'number' && isFinite(origin) && isFinite(target)) {\n\t\t\t\t\tview[key] = origin + (target - origin) * ease;\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tview[key] = target;\n\t\t}\n\t}\n\n\tChart.elements = {};\n\n\tChart.Element = function(configuration) {\n\t\thelpers.extend(this, configuration);\n\t\tthis.initialize.apply(this, arguments);\n\t};\n\n\thelpers.extend(Chart.Element.prototype, {\n\n\t\tinitialize: function() {\n\t\t\tthis.hidden = false;\n\t\t},\n\n\t\tpivot: function() {\n\t\t\tvar me = this;\n\t\t\tif (!me._view) {\n\t\t\t\tme._view = helpers.clone(me._model);\n\t\t\t}\n\t\t\tme._start = {};\n\t\t\treturn me;\n\t\t},\n\n\t\ttransition: function(ease) {\n\t\t\tvar me = this;\n\t\t\tvar model = me._model;\n\t\t\tvar start = me._start;\n\t\t\tvar view = me._view;\n\n\t\t\t// No animation -> No Transition\n\t\t\tif (!model || ease === 1) {\n\t\t\t\tme._view = model;\n\t\t\t\tme._start = null;\n\t\t\t\treturn me;\n\t\t\t}\n\n\t\t\tif (!view) {\n\t\t\t\tview = me._view = {};\n\t\t\t}\n\n\t\t\tif (!start) {\n\t\t\t\tstart = me._start = {};\n\t\t\t}\n\n\t\t\tinterpolate(start, view, model, ease);\n\n\t\t\treturn me;\n\t\t},\n\n\t\ttooltipPosition: function() {\n\t\t\treturn {\n\t\t\t\tx: this._model.x,\n\t\t\t\ty: this._model.y\n\t\t\t};\n\t\t},\n\n\t\thasValue: function() {\n\t\t\treturn helpers.isNumber(this._model.x) && helpers.isNumber(this._model.y);\n\t\t}\n\t});\n\n\tChart.Element.extend = helpers.inherits;\n};\n\n},{\"2\":2}],26:[function(require,module,exports){\n/* global window: false */\n/* global document: false */\n'use strict';\n\nvar color = require(2);\n\nmodule.exports = function(Chart) {\n\t// Global Chart helpers object for utility methods and classes\n\tvar helpers = Chart.helpers = {};\n\n\t// -- Basic js utility methods\n\thelpers.each = function(loopable, callback, self, reverse) {\n\t\t// Check to see if null or undefined firstly.\n\t\tvar i, len;\n\t\tif (helpers.isArray(loopable)) {\n\t\t\tlen = loopable.length;\n\t\t\tif (reverse) {\n\t\t\t\tfor (i = len - 1; i >= 0; i--) {\n\t\t\t\t\tcallback.call(self, loopable[i], i);\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tfor (i = 0; i < len; i++) {\n\t\t\t\t\tcallback.call(self, loopable[i], i);\n\t\t\t\t}\n\t\t\t}\n\t\t} else if (typeof loopable === 'object') {\n\t\t\tvar keys = Object.keys(loopable);\n\t\t\tlen = keys.length;\n\t\t\tfor (i = 0; i < len; i++) {\n\t\t\t\tcallback.call(self, loopable[keys[i]], keys[i]);\n\t\t\t}\n\t\t}\n\t};\n\thelpers.clone = function(obj) {\n\t\tvar objClone = {};\n\t\thelpers.each(obj, function(value, key) {\n\t\t\tif (helpers.isArray(value)) {\n\t\t\t\tobjClone[key] = value.slice(0);\n\t\t\t} else if (typeof value === 'object' && value !== null) {\n\t\t\t\tobjClone[key] = helpers.clone(value);\n\t\t\t} else {\n\t\t\t\tobjClone[key] = value;\n\t\t\t}\n\t\t});\n\t\treturn objClone;\n\t};\n\thelpers.extend = function(base) {\n\t\tvar setFn = function(value, key) {\n\t\t\tbase[key] = value;\n\t\t};\n\t\tfor (var i = 1, ilen = arguments.length; i < ilen; i++) {\n\t\t\thelpers.each(arguments[i], setFn);\n\t\t}\n\t\treturn base;\n\t};\n\t// Need a special merge function to chart configs since they are now grouped\n\thelpers.configMerge = function(_base) {\n\t\tvar base = helpers.clone(_base);\n\t\thelpers.each(Array.prototype.slice.call(arguments, 1), function(extension) {\n\t\t\thelpers.each(extension, function(value, key) {\n\t\t\t\tvar baseHasProperty = base.hasOwnProperty(key);\n\t\t\t\tvar baseVal = baseHasProperty ? base[key] : {};\n\n\t\t\t\tif (key === 'scales') {\n\t\t\t\t\t// Scale config merging is complex. Add our own function here for that\n\t\t\t\t\tbase[key] = helpers.scaleMerge(baseVal, value);\n\t\t\t\t} else if (key === 'scale') {\n\t\t\t\t\t// Used in polar area & radar charts since there is only one scale\n\t\t\t\t\tbase[key] = helpers.configMerge(baseVal, Chart.scaleService.getScaleDefaults(value.type), value);\n\t\t\t\t} else if (baseHasProperty\n\t\t\t\t\t\t&& typeof baseVal === 'object'\n\t\t\t\t\t\t&& !helpers.isArray(baseVal)\n\t\t\t\t\t\t&& baseVal !== null\n\t\t\t\t\t\t&& typeof value === 'object'\n\t\t\t\t\t\t&& !helpers.isArray(value)) {\n\t\t\t\t\t// If we are overwriting an object with an object, do a merge of the properties.\n\t\t\t\t\tbase[key] = helpers.configMerge(baseVal, value);\n\t\t\t\t} else {\n\t\t\t\t\t// can just overwrite the value in this case\n\t\t\t\t\tbase[key] = value;\n\t\t\t\t}\n\t\t\t});\n\t\t});\n\n\t\treturn base;\n\t};\n\thelpers.scaleMerge = function(_base, extension) {\n\t\tvar base = helpers.clone(_base);\n\n\t\thelpers.each(extension, function(value, key) {\n\t\t\tif (key === 'xAxes' || key === 'yAxes') {\n\t\t\t\t// These properties are arrays of items\n\t\t\t\tif (base.hasOwnProperty(key)) {\n\t\t\t\t\thelpers.each(value, function(valueObj, index) {\n\t\t\t\t\t\tvar axisType = helpers.getValueOrDefault(valueObj.type, key === 'xAxes' ? 'category' : 'linear');\n\t\t\t\t\t\tvar axisDefaults = Chart.scaleService.getScaleDefaults(axisType);\n\t\t\t\t\t\tif (index >= base[key].length || !base[key][index].type) {\n\t\t\t\t\t\t\tbase[key].push(helpers.configMerge(axisDefaults, valueObj));\n\t\t\t\t\t\t} else if (valueObj.type && valueObj.type !== base[key][index].type) {\n\t\t\t\t\t\t\t// Type changed. Bring in the new defaults before we bring in valueObj so that valueObj can override the correct scale defaults\n\t\t\t\t\t\t\tbase[key][index] = helpers.configMerge(base[key][index], axisDefaults, valueObj);\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t// Type is the same\n\t\t\t\t\t\t\tbase[key][index] = helpers.configMerge(base[key][index], valueObj);\n\t\t\t\t\t\t}\n\t\t\t\t\t});\n\t\t\t\t} else {\n\t\t\t\t\tbase[key] = [];\n\t\t\t\t\thelpers.each(value, function(valueObj) {\n\t\t\t\t\t\tvar axisType = helpers.getValueOrDefault(valueObj.type, key === 'xAxes' ? 'category' : 'linear');\n\t\t\t\t\t\tbase[key].push(helpers.configMerge(Chart.scaleService.getScaleDefaults(axisType), valueObj));\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t} else if (base.hasOwnProperty(key) && typeof base[key] === 'object' && base[key] !== null && typeof value === 'object') {\n\t\t\t\t// If we are overwriting an object with an object, do a merge of the properties.\n\t\t\t\tbase[key] = helpers.configMerge(base[key], value);\n\n\t\t\t} else {\n\t\t\t\t// can just overwrite the value in this case\n\t\t\t\tbase[key] = value;\n\t\t\t}\n\t\t});\n\n\t\treturn base;\n\t};\n\thelpers.getValueAtIndexOrDefault = function(value, index, defaultValue) {\n\t\tif (value === undefined || value === null) {\n\t\t\treturn defaultValue;\n\t\t}\n\n\t\tif (helpers.isArray(value)) {\n\t\t\treturn index < value.length ? value[index] : defaultValue;\n\t\t}\n\n\t\treturn value;\n\t};\n\thelpers.getValueOrDefault = function(value, defaultValue) {\n\t\treturn value === undefined ? defaultValue : value;\n\t};\n\thelpers.indexOf = Array.prototype.indexOf?\n\t\tfunction(array, item) {\n\t\t\treturn array.indexOf(item);\n\t\t}:\n\t\tfunction(array, item) {\n\t\t\tfor (var i = 0, ilen = array.length; i < ilen; ++i) {\n\t\t\t\tif (array[i] === item) {\n\t\t\t\t\treturn i;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn -1;\n\t\t};\n\thelpers.where = function(collection, filterCallback) {\n\t\tif (helpers.isArray(collection) && Array.prototype.filter) {\n\t\t\treturn collection.filter(filterCallback);\n\t\t}\n\t\tvar filtered = [];\n\n\t\thelpers.each(collection, function(item) {\n\t\t\tif (filterCallback(item)) {\n\t\t\t\tfiltered.push(item);\n\t\t\t}\n\t\t});\n\n\t\treturn filtered;\n\t};\n\thelpers.findIndex = Array.prototype.findIndex?\n\t\tfunction(array, callback, scope) {\n\t\t\treturn array.findIndex(callback, scope);\n\t\t} :\n\t\tfunction(array, callback, scope) {\n\t\t\tscope = scope === undefined? array : scope;\n\t\t\tfor (var i = 0, ilen = array.length; i < ilen; ++i) {\n\t\t\t\tif (callback.call(scope, array[i], i, array)) {\n\t\t\t\t\treturn i;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn -1;\n\t\t};\n\thelpers.findNextWhere = function(arrayToSearch, filterCallback, startIndex) {\n\t\t// Default to start of the array\n\t\tif (startIndex === undefined || startIndex === null) {\n\t\t\tstartIndex = -1;\n\t\t}\n\t\tfor (var i = startIndex + 1; i < arrayToSearch.length; i++) {\n\t\t\tvar currentItem = arrayToSearch[i];\n\t\t\tif (filterCallback(currentItem)) {\n\t\t\t\treturn currentItem;\n\t\t\t}\n\t\t}\n\t};\n\thelpers.findPreviousWhere = function(arrayToSearch, filterCallback, startIndex) {\n\t\t// Default to end of the array\n\t\tif (startIndex === undefined || startIndex === null) {\n\t\t\tstartIndex = arrayToSearch.length;\n\t\t}\n\t\tfor (var i = startIndex - 1; i >= 0; i--) {\n\t\t\tvar currentItem = arrayToSearch[i];\n\t\t\tif (filterCallback(currentItem)) {\n\t\t\t\treturn currentItem;\n\t\t\t}\n\t\t}\n\t};\n\thelpers.inherits = function(extensions) {\n\t\t// Basic javascript inheritance based on the model created in Backbone.js\n\t\tvar me = this;\n\t\tvar ChartElement = (extensions && extensions.hasOwnProperty('constructor')) ? extensions.constructor : function() {\n\t\t\treturn me.apply(this, arguments);\n\t\t};\n\n\t\tvar Surrogate = function() {\n\t\t\tthis.constructor = ChartElement;\n\t\t};\n\t\tSurrogate.prototype = me.prototype;\n\t\tChartElement.prototype = new Surrogate();\n\n\t\tChartElement.extend = helpers.inherits;\n\n\t\tif (extensions) {\n\t\t\thelpers.extend(ChartElement.prototype, extensions);\n\t\t}\n\n\t\tChartElement.__super__ = me.prototype;\n\n\t\treturn ChartElement;\n\t};\n\thelpers.noop = function() {};\n\thelpers.uid = (function() {\n\t\tvar id = 0;\n\t\treturn function() {\n\t\t\treturn id++;\n\t\t};\n\t}());\n\t// -- Math methods\n\thelpers.isNumber = function(n) {\n\t\treturn !isNaN(parseFloat(n)) && isFinite(n);\n\t};\n\thelpers.almostEquals = function(x, y, epsilon) {\n\t\treturn Math.abs(x - y) < epsilon;\n\t};\n\thelpers.almostWhole = function(x, epsilon) {\n\t\tvar rounded = Math.round(x);\n\t\treturn (((rounded - epsilon) < x) && ((rounded + epsilon) > x));\n\t};\n\thelpers.max = function(array) {\n\t\treturn array.reduce(function(max, value) {\n\t\t\tif (!isNaN(value)) {\n\t\t\t\treturn Math.max(max, value);\n\t\t\t}\n\t\t\treturn max;\n\t\t}, Number.NEGATIVE_INFINITY);\n\t};\n\thelpers.min = function(array) {\n\t\treturn array.reduce(function(min, value) {\n\t\t\tif (!isNaN(value)) {\n\t\t\t\treturn Math.min(min, value);\n\t\t\t}\n\t\t\treturn min;\n\t\t}, Number.POSITIVE_INFINITY);\n\t};\n\thelpers.sign = Math.sign?\n\t\tfunction(x) {\n\t\t\treturn Math.sign(x);\n\t\t} :\n\t\tfunction(x) {\n\t\t\tx = +x; // convert to a number\n\t\t\tif (x === 0 || isNaN(x)) {\n\t\t\t\treturn x;\n\t\t\t}\n\t\t\treturn x > 0 ? 1 : -1;\n\t\t};\n\thelpers.log10 = Math.log10?\n\t\tfunction(x) {\n\t\t\treturn Math.log10(x);\n\t\t} :\n\t\tfunction(x) {\n\t\t\treturn Math.log(x) / Math.LN10;\n\t\t};\n\thelpers.toRadians = function(degrees) {\n\t\treturn degrees * (Math.PI / 180);\n\t};\n\thelpers.toDegrees = function(radians) {\n\t\treturn radians * (180 / Math.PI);\n\t};\n\t// Gets the angle from vertical upright to the point about a centre.\n\thelpers.getAngleFromPoint = function(centrePoint, anglePoint) {\n\t\tvar distanceFromXCenter = anglePoint.x - centrePoint.x,\n\t\t\tdistanceFromYCenter = anglePoint.y - centrePoint.y,\n\t\t\tradialDistanceFromCenter = Math.sqrt(distanceFromXCenter * distanceFromXCenter + distanceFromYCenter * distanceFromYCenter);\n\n\t\tvar angle = Math.atan2(distanceFromYCenter, distanceFromXCenter);\n\n\t\tif (angle < (-0.5 * Math.PI)) {\n\t\t\tangle += 2.0 * Math.PI; // make sure the returned angle is in the range of (-PI/2, 3PI/2]\n\t\t}\n\n\t\treturn {\n\t\t\tangle: angle,\n\t\t\tdistance: radialDistanceFromCenter\n\t\t};\n\t};\n\thelpers.distanceBetweenPoints = function(pt1, pt2) {\n\t\treturn Math.sqrt(Math.pow(pt2.x - pt1.x, 2) + Math.pow(pt2.y - pt1.y, 2));\n\t};\n\thelpers.aliasPixel = function(pixelWidth) {\n\t\treturn (pixelWidth % 2 === 0) ? 0 : 0.5;\n\t};\n\thelpers.splineCurve = function(firstPoint, middlePoint, afterPoint, t) {\n\t\t// Props to Rob Spencer at scaled innovation for his post on splining between points\n\t\t// http://scaledinnovation.com/analytics/splines/aboutSplines.html\n\n\t\t// This function must also respect \"skipped\" points\n\n\t\tvar previous = firstPoint.skip ? middlePoint : firstPoint,\n\t\t\tcurrent = middlePoint,\n\t\t\tnext = afterPoint.skip ? middlePoint : afterPoint;\n\n\t\tvar d01 = Math.sqrt(Math.pow(current.x - previous.x, 2) + Math.pow(current.y - previous.y, 2));\n\t\tvar d12 = Math.sqrt(Math.pow(next.x - current.x, 2) + Math.pow(next.y - current.y, 2));\n\n\t\tvar s01 = d01 / (d01 + d12);\n\t\tvar s12 = d12 / (d01 + d12);\n\n\t\t// If all points are the same, s01 & s02 will be inf\n\t\ts01 = isNaN(s01) ? 0 : s01;\n\t\ts12 = isNaN(s12) ? 0 : s12;\n\n\t\tvar fa = t * s01; // scaling factor for triangle Ta\n\t\tvar fb = t * s12;\n\n\t\treturn {\n\t\t\tprevious: {\n\t\t\t\tx: current.x - fa * (next.x - previous.x),\n\t\t\t\ty: current.y - fa * (next.y - previous.y)\n\t\t\t},\n\t\t\tnext: {\n\t\t\t\tx: current.x + fb * (next.x - previous.x),\n\t\t\t\ty: current.y + fb * (next.y - previous.y)\n\t\t\t}\n\t\t};\n\t};\n\thelpers.EPSILON = Number.EPSILON || 1e-14;\n\thelpers.splineCurveMonotone = function(points) {\n\t\t// This function calculates Bézier control points in a similar way than |splineCurve|,\n\t\t// but preserves monotonicity of the provided data and ensures no local extremums are added\n\t\t// between the dataset discrete points due to the interpolation.\n\t\t// See : https://en.wikipedia.org/wiki/Monotone_cubic_interpolation\n\n\t\tvar pointsWithTangents = (points || []).map(function(point) {\n\t\t\treturn {\n\t\t\t\tmodel: point._model,\n\t\t\t\tdeltaK: 0,\n\t\t\t\tmK: 0\n\t\t\t};\n\t\t});\n\n\t\t// Calculate slopes (deltaK) and initialize tangents (mK)\n\t\tvar pointsLen = pointsWithTangents.length;\n\t\tvar i, pointBefore, pointCurrent, pointAfter;\n\t\tfor (i = 0; i < pointsLen; ++i) {\n\t\t\tpointCurrent = pointsWithTangents[i];\n\t\t\tif (pointCurrent.model.skip) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tpointBefore = i > 0 ? pointsWithTangents[i - 1] : null;\n\t\t\tpointAfter = i < pointsLen - 1 ? pointsWithTangents[i + 1] : null;\n\t\t\tif (pointAfter && !pointAfter.model.skip) {\n\t\t\t\tvar slopeDeltaX = (pointAfter.model.x - pointCurrent.model.x);\n\n\t\t\t\t// In the case of two points that appear at the same x pixel, slopeDeltaX is 0\n\t\t\t\tpointCurrent.deltaK = slopeDeltaX !== 0 ? (pointAfter.model.y - pointCurrent.model.y) / slopeDeltaX : 0;\n\t\t\t}\n\n\t\t\tif (!pointBefore || pointBefore.model.skip) {\n\t\t\t\tpointCurrent.mK = pointCurrent.deltaK;\n\t\t\t} else if (!pointAfter || pointAfter.model.skip) {\n\t\t\t\tpointCurrent.mK = pointBefore.deltaK;\n\t\t\t} else if (this.sign(pointBefore.deltaK) !== this.sign(pointCurrent.deltaK)) {\n\t\t\t\tpointCurrent.mK = 0;\n\t\t\t} else {\n\t\t\t\tpointCurrent.mK = (pointBefore.deltaK + pointCurrent.deltaK) / 2;\n\t\t\t}\n\t\t}\n\n\t\t// Adjust tangents to ensure monotonic properties\n\t\tvar alphaK, betaK, tauK, squaredMagnitude;\n\t\tfor (i = 0; i < pointsLen - 1; ++i) {\n\t\t\tpointCurrent = pointsWithTangents[i];\n\t\t\tpointAfter = pointsWithTangents[i + 1];\n\t\t\tif (pointCurrent.model.skip || pointAfter.model.skip) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tif (helpers.almostEquals(pointCurrent.deltaK, 0, this.EPSILON)) {\n\t\t\t\tpointCurrent.mK = pointAfter.mK = 0;\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\talphaK = pointCurrent.mK / pointCurrent.deltaK;\n\t\t\tbetaK = pointAfter.mK / pointCurrent.deltaK;\n\t\t\tsquaredMagnitude = Math.pow(alphaK, 2) + Math.pow(betaK, 2);\n\t\t\tif (squaredMagnitude <= 9) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\ttauK = 3 / Math.sqrt(squaredMagnitude);\n\t\t\tpointCurrent.mK = alphaK * tauK * pointCurrent.deltaK;\n\t\t\tpointAfter.mK = betaK * tauK * pointCurrent.deltaK;\n\t\t}\n\n\t\t// Compute control points\n\t\tvar deltaX;\n\t\tfor (i = 0; i < pointsLen; ++i) {\n\t\t\tpointCurrent = pointsWithTangents[i];\n\t\t\tif (pointCurrent.model.skip) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tpointBefore = i > 0 ? pointsWithTangents[i - 1] : null;\n\t\t\tpointAfter = i < pointsLen - 1 ? pointsWithTangents[i + 1] : null;\n\t\t\tif (pointBefore && !pointBefore.model.skip) {\n\t\t\t\tdeltaX = (pointCurrent.model.x - pointBefore.model.x) / 3;\n\t\t\t\tpointCurrent.model.controlPointPreviousX = pointCurrent.model.x - deltaX;\n\t\t\t\tpointCurrent.model.controlPointPreviousY = pointCurrent.model.y - deltaX * pointCurrent.mK;\n\t\t\t}\n\t\t\tif (pointAfter && !pointAfter.model.skip) {\n\t\t\t\tdeltaX = (pointAfter.model.x - pointCurrent.model.x) / 3;\n\t\t\t\tpointCurrent.model.controlPointNextX = pointCurrent.model.x + deltaX;\n\t\t\t\tpointCurrent.model.controlPointNextY = pointCurrent.model.y + deltaX * pointCurrent.mK;\n\t\t\t}\n\t\t}\n\t};\n\thelpers.nextItem = function(collection, index, loop) {\n\t\tif (loop) {\n\t\t\treturn index >= collection.length - 1 ? collection[0] : collection[index + 1];\n\t\t}\n\t\treturn index >= collection.length - 1 ? collection[collection.length - 1] : collection[index + 1];\n\t};\n\thelpers.previousItem = function(collection, index, loop) {\n\t\tif (loop) {\n\t\t\treturn index <= 0 ? collection[collection.length - 1] : collection[index - 1];\n\t\t}\n\t\treturn index <= 0 ? collection[0] : collection[index - 1];\n\t};\n\t// Implementation of the nice number algorithm used in determining where axis labels will go\n\thelpers.niceNum = function(range, round) {\n\t\tvar exponent = Math.floor(helpers.log10(range));\n\t\tvar fraction = range / Math.pow(10, exponent);\n\t\tvar niceFraction;\n\n\t\tif (round) {\n\t\t\tif (fraction < 1.5) {\n\t\t\t\tniceFraction = 1;\n\t\t\t} else if (fraction < 3) {\n\t\t\t\tniceFraction = 2;\n\t\t\t} else if (fraction < 7) {\n\t\t\t\tniceFraction = 5;\n\t\t\t} else {\n\t\t\t\tniceFraction = 10;\n\t\t\t}\n\t\t} else if (fraction <= 1.0) {\n\t\t\tniceFraction = 1;\n\t\t} else if (fraction <= 2) {\n\t\t\tniceFraction = 2;\n\t\t} else if (fraction <= 5) {\n\t\t\tniceFraction = 5;\n\t\t} else {\n\t\t\tniceFraction = 10;\n\t\t}\n\n\t\treturn niceFraction * Math.pow(10, exponent);\n\t};\n\t// Easing functions adapted from Robert Penner's easing equations\n\t// http://www.robertpenner.com/easing/\n\tvar easingEffects = helpers.easingEffects = {\n\t\tlinear: function(t) {\n\t\t\treturn t;\n\t\t},\n\t\teaseInQuad: function(t) {\n\t\t\treturn t * t;\n\t\t},\n\t\teaseOutQuad: function(t) {\n\t\t\treturn -1 * t * (t - 2);\n\t\t},\n\t\teaseInOutQuad: function(t) {\n\t\t\tif ((t /= 1 / 2) < 1) {\n\t\t\t\treturn 1 / 2 * t * t;\n\t\t\t}\n\t\t\treturn -1 / 2 * ((--t) * (t - 2) - 1);\n\t\t},\n\t\teaseInCubic: function(t) {\n\t\t\treturn t * t * t;\n\t\t},\n\t\teaseOutCubic: function(t) {\n\t\t\treturn 1 * ((t = t / 1 - 1) * t * t + 1);\n\t\t},\n\t\teaseInOutCubic: function(t) {\n\t\t\tif ((t /= 1 / 2) < 1) {\n\t\t\t\treturn 1 / 2 * t * t * t;\n\t\t\t}\n\t\t\treturn 1 / 2 * ((t -= 2) * t * t + 2);\n\t\t},\n\t\teaseInQuart: function(t) {\n\t\t\treturn t * t * t * t;\n\t\t},\n\t\teaseOutQuart: function(t) {\n\t\t\treturn -1 * ((t = t / 1 - 1) * t * t * t - 1);\n\t\t},\n\t\teaseInOutQuart: function(t) {\n\t\t\tif ((t /= 1 / 2) < 1) {\n\t\t\t\treturn 1 / 2 * t * t * t * t;\n\t\t\t}\n\t\t\treturn -1 / 2 * ((t -= 2) * t * t * t - 2);\n\t\t},\n\t\teaseInQuint: function(t) {\n\t\t\treturn 1 * (t /= 1) * t * t * t * t;\n\t\t},\n\t\teaseOutQuint: function(t) {\n\t\t\treturn 1 * ((t = t / 1 - 1) * t * t * t * t + 1);\n\t\t},\n\t\teaseInOutQuint: function(t) {\n\t\t\tif ((t /= 1 / 2) < 1) {\n\t\t\t\treturn 1 / 2 * t * t * t * t * t;\n\t\t\t}\n\t\t\treturn 1 / 2 * ((t -= 2) * t * t * t * t + 2);\n\t\t},\n\t\teaseInSine: function(t) {\n\t\t\treturn -1 * Math.cos(t / 1 * (Math.PI / 2)) + 1;\n\t\t},\n\t\teaseOutSine: function(t) {\n\t\t\treturn 1 * Math.sin(t / 1 * (Math.PI / 2));\n\t\t},\n\t\teaseInOutSine: function(t) {\n\t\t\treturn -1 / 2 * (Math.cos(Math.PI * t / 1) - 1);\n\t\t},\n\t\teaseInExpo: function(t) {\n\t\t\treturn (t === 0) ? 1 : 1 * Math.pow(2, 10 * (t / 1 - 1));\n\t\t},\n\t\teaseOutExpo: function(t) {\n\t\t\treturn (t === 1) ? 1 : 1 * (-Math.pow(2, -10 * t / 1) + 1);\n\t\t},\n\t\teaseInOutExpo: function(t) {\n\t\t\tif (t === 0) {\n\t\t\t\treturn 0;\n\t\t\t}\n\t\t\tif (t === 1) {\n\t\t\t\treturn 1;\n\t\t\t}\n\t\t\tif ((t /= 1 / 2) < 1) {\n\t\t\t\treturn 1 / 2 * Math.pow(2, 10 * (t - 1));\n\t\t\t}\n\t\t\treturn 1 / 2 * (-Math.pow(2, -10 * --t) + 2);\n\t\t},\n\t\teaseInCirc: function(t) {\n\t\t\tif (t >= 1) {\n\t\t\t\treturn t;\n\t\t\t}\n\t\t\treturn -1 * (Math.sqrt(1 - (t /= 1) * t) - 1);\n\t\t},\n\t\teaseOutCirc: function(t) {\n\t\t\treturn 1 * Math.sqrt(1 - (t = t / 1 - 1) * t);\n\t\t},\n\t\teaseInOutCirc: function(t) {\n\t\t\tif ((t /= 1 / 2) < 1) {\n\t\t\t\treturn -1 / 2 * (Math.sqrt(1 - t * t) - 1);\n\t\t\t}\n\t\t\treturn 1 / 2 * (Math.sqrt(1 - (t -= 2) * t) + 1);\n\t\t},\n\t\teaseInElastic: function(t) {\n\t\t\tvar s = 1.70158;\n\t\t\tvar p = 0;\n\t\t\tvar a = 1;\n\t\t\tif (t === 0) {\n\t\t\t\treturn 0;\n\t\t\t}\n\t\t\tif ((t /= 1) === 1) {\n\t\t\t\treturn 1;\n\t\t\t}\n\t\t\tif (!p) {\n\t\t\t\tp = 1 * 0.3;\n\t\t\t}\n\t\t\tif (a < Math.abs(1)) {\n\t\t\t\ta = 1;\n\t\t\t\ts = p / 4;\n\t\t\t} else {\n\t\t\t\ts = p / (2 * Math.PI) * Math.asin(1 / a);\n\t\t\t}\n\t\t\treturn -(a * Math.pow(2, 10 * (t -= 1)) * Math.sin((t * 1 - s) * (2 * Math.PI) / p));\n\t\t},\n\t\teaseOutElastic: function(t) {\n\t\t\tvar s = 1.70158;\n\t\t\tvar p = 0;\n\t\t\tvar a = 1;\n\t\t\tif (t === 0) {\n\t\t\t\treturn 0;\n\t\t\t}\n\t\t\tif ((t /= 1) === 1) {\n\t\t\t\treturn 1;\n\t\t\t}\n\t\t\tif (!p) {\n\t\t\t\tp = 1 * 0.3;\n\t\t\t}\n\t\t\tif (a < Math.abs(1)) {\n\t\t\t\ta = 1;\n\t\t\t\ts = p / 4;\n\t\t\t} else {\n\t\t\t\ts = p / (2 * Math.PI) * Math.asin(1 / a);\n\t\t\t}\n\t\t\treturn a * Math.pow(2, -10 * t) * Math.sin((t * 1 - s) * (2 * Math.PI) / p) + 1;\n\t\t},\n\t\teaseInOutElastic: function(t) {\n\t\t\tvar s = 1.70158;\n\t\t\tvar p = 0;\n\t\t\tvar a = 1;\n\t\t\tif (t === 0) {\n\t\t\t\treturn 0;\n\t\t\t}\n\t\t\tif ((t /= 1 / 2) === 2) {\n\t\t\t\treturn 1;\n\t\t\t}\n\t\t\tif (!p) {\n\t\t\t\tp = 1 * (0.3 * 1.5);\n\t\t\t}\n\t\t\tif (a < Math.abs(1)) {\n\t\t\t\ta = 1;\n\t\t\t\ts = p / 4;\n\t\t\t} else {\n\t\t\t\ts = p / (2 * Math.PI) * Math.asin(1 / a);\n\t\t\t}\n\t\t\tif (t < 1) {\n\t\t\t\treturn -0.5 * (a * Math.pow(2, 10 * (t -= 1)) * Math.sin((t * 1 - s) * (2 * Math.PI) / p));\n\t\t\t}\n\t\t\treturn a * Math.pow(2, -10 * (t -= 1)) * Math.sin((t * 1 - s) * (2 * Math.PI) / p) * 0.5 + 1;\n\t\t},\n\t\teaseInBack: function(t) {\n\t\t\tvar s = 1.70158;\n\t\t\treturn 1 * (t /= 1) * t * ((s + 1) * t - s);\n\t\t},\n\t\teaseOutBack: function(t) {\n\t\t\tvar s = 1.70158;\n\t\t\treturn 1 * ((t = t / 1 - 1) * t * ((s + 1) * t + s) + 1);\n\t\t},\n\t\teaseInOutBack: function(t) {\n\t\t\tvar s = 1.70158;\n\t\t\tif ((t /= 1 / 2) < 1) {\n\t\t\t\treturn 1 / 2 * (t * t * (((s *= (1.525)) + 1) * t - s));\n\t\t\t}\n\t\t\treturn 1 / 2 * ((t -= 2) * t * (((s *= (1.525)) + 1) * t + s) + 2);\n\t\t},\n\t\teaseInBounce: function(t) {\n\t\t\treturn 1 - easingEffects.easeOutBounce(1 - t);\n\t\t},\n\t\teaseOutBounce: function(t) {\n\t\t\tif ((t /= 1) < (1 / 2.75)) {\n\t\t\t\treturn 1 * (7.5625 * t * t);\n\t\t\t} else if (t < (2 / 2.75)) {\n\t\t\t\treturn 1 * (7.5625 * (t -= (1.5 / 2.75)) * t + 0.75);\n\t\t\t} else if (t < (2.5 / 2.75)) {\n\t\t\t\treturn 1 * (7.5625 * (t -= (2.25 / 2.75)) * t + 0.9375);\n\t\t\t}\n\t\t\treturn 1 * (7.5625 * (t -= (2.625 / 2.75)) * t + 0.984375);\n\t\t},\n\t\teaseInOutBounce: function(t) {\n\t\t\tif (t < 1 / 2) {\n\t\t\t\treturn easingEffects.easeInBounce(t * 2) * 0.5;\n\t\t\t}\n\t\t\treturn easingEffects.easeOutBounce(t * 2 - 1) * 0.5 + 1 * 0.5;\n\t\t}\n\t};\n\t// Request animation polyfill - http://www.paulirish.com/2011/requestanimationframe-for-smart-animating/\n\thelpers.requestAnimFrame = (function() {\n\t\tif (typeof window === 'undefined') {\n\t\t\treturn function(callback) {\n\t\t\t\tcallback();\n\t\t\t};\n\t\t}\n\t\treturn window.requestAnimationFrame ||\n\t\t\twindow.webkitRequestAnimationFrame ||\n\t\t\twindow.mozRequestAnimationFrame ||\n\t\t\twindow.oRequestAnimationFrame ||\n\t\t\twindow.msRequestAnimationFrame ||\n\t\t\tfunction(callback) {\n\t\t\t\treturn window.setTimeout(callback, 1000 / 60);\n\t\t\t};\n\t}());\n\t// -- DOM methods\n\thelpers.getRelativePosition = function(evt, chart) {\n\t\tvar mouseX, mouseY;\n\t\tvar e = evt.originalEvent || evt,\n\t\t\tcanvas = evt.currentTarget || evt.srcElement,\n\t\t\tboundingRect = canvas.getBoundingClientRect();\n\n\t\tvar touches = e.touches;\n\t\tif (touches && touches.length > 0) {\n\t\t\tmouseX = touches[0].clientX;\n\t\t\tmouseY = touches[0].clientY;\n\n\t\t} else {\n\t\t\tmouseX = e.clientX;\n\t\t\tmouseY = e.clientY;\n\t\t}\n\n\t\t// Scale mouse coordinates into canvas coordinates\n\t\t// by following the pattern laid out by 'jerryj' in the comments of\n\t\t// http://www.html5canvastutorials.com/advanced/html5-canvas-mouse-coordinates/\n\t\tvar paddingLeft = parseFloat(helpers.getStyle(canvas, 'padding-left'));\n\t\tvar paddingTop = parseFloat(helpers.getStyle(canvas, 'padding-top'));\n\t\tvar paddingRight = parseFloat(helpers.getStyle(canvas, 'padding-right'));\n\t\tvar paddingBottom = parseFloat(helpers.getStyle(canvas, 'padding-bottom'));\n\t\tvar width = boundingRect.right - boundingRect.left - paddingLeft - paddingRight;\n\t\tvar height = boundingRect.bottom - boundingRect.top - paddingTop - paddingBottom;\n\n\t\t// We divide by the current device pixel ratio, because the canvas is scaled up by that amount in each direction. However\n\t\t// the backend model is in unscaled coordinates. Since we are going to deal with our model coordinates, we go back here\n\t\tmouseX = Math.round((mouseX - boundingRect.left - paddingLeft) / (width) * canvas.width / chart.currentDevicePixelRatio);\n\t\tmouseY = Math.round((mouseY - boundingRect.top - paddingTop) / (height) * canvas.height / chart.currentDevicePixelRatio);\n\n\t\treturn {\n\t\t\tx: mouseX,\n\t\t\ty: mouseY\n\t\t};\n\n\t};\n\thelpers.addEvent = function(node, eventType, method) {\n\t\tif (node.addEventListener) {\n\t\t\tnode.addEventListener(eventType, method);\n\t\t} else if (node.attachEvent) {\n\t\t\tnode.attachEvent('on' + eventType, method);\n\t\t} else {\n\t\t\tnode['on' + eventType] = method;\n\t\t}\n\t};\n\thelpers.removeEvent = function(node, eventType, handler) {\n\t\tif (node.removeEventListener) {\n\t\t\tnode.removeEventListener(eventType, handler, false);\n\t\t} else if (node.detachEvent) {\n\t\t\tnode.detachEvent('on' + eventType, handler);\n\t\t} else {\n\t\t\tnode['on' + eventType] = helpers.noop;\n\t\t}\n\t};\n\n\t// Private helper function to convert max-width/max-height values that may be percentages into a number\n\tfunction parseMaxStyle(styleValue, node, parentProperty) {\n\t\tvar valueInPixels;\n\t\tif (typeof(styleValue) === 'string') {\n\t\t\tvalueInPixels = parseInt(styleValue, 10);\n\n\t\t\tif (styleValue.indexOf('%') !== -1) {\n\t\t\t\t// percentage * size in dimension\n\t\t\t\tvalueInPixels = valueInPixels / 100 * node.parentNode[parentProperty];\n\t\t\t}\n\t\t} else {\n\t\t\tvalueInPixels = styleValue;\n\t\t}\n\n\t\treturn valueInPixels;\n\t}\n\n\t/**\n\t * Returns if the given value contains an effective constraint.\n\t * @private\n\t */\n\tfunction isConstrainedValue(value) {\n\t\treturn value !== undefined && value !== null && value !== 'none';\n\t}\n\n\t// Private helper to get a constraint dimension\n\t// @param domNode : the node to check the constraint on\n\t// @param maxStyle : the style that defines the maximum for the direction we are using (maxWidth / maxHeight)\n\t// @param percentageProperty : property of parent to use when calculating width as a percentage\n\t// @see http://www.nathanaeljones.com/blog/2013/reading-max-width-cross-browser\n\tfunction getConstraintDimension(domNode, maxStyle, percentageProperty) {\n\t\tvar view = document.defaultView;\n\t\tvar parentNode = domNode.parentNode;\n\t\tvar constrainedNode = view.getComputedStyle(domNode)[maxStyle];\n\t\tvar constrainedContainer = view.getComputedStyle(parentNode)[maxStyle];\n\t\tvar hasCNode = isConstrainedValue(constrainedNode);\n\t\tvar hasCContainer = isConstrainedValue(constrainedContainer);\n\t\tvar infinity = Number.POSITIVE_INFINITY;\n\n\t\tif (hasCNode || hasCContainer) {\n\t\t\treturn Math.min(\n\t\t\t\thasCNode? parseMaxStyle(constrainedNode, domNode, percentageProperty) : infinity,\n\t\t\t\thasCContainer? parseMaxStyle(constrainedContainer, parentNode, percentageProperty) : infinity);\n\t\t}\n\n\t\treturn 'none';\n\t}\n\t// returns Number or undefined if no constraint\n\thelpers.getConstraintWidth = function(domNode) {\n\t\treturn getConstraintDimension(domNode, 'max-width', 'clientWidth');\n\t};\n\t// returns Number or undefined if no constraint\n\thelpers.getConstraintHeight = function(domNode) {\n\t\treturn getConstraintDimension(domNode, 'max-height', 'clientHeight');\n\t};\n\thelpers.getMaximumWidth = function(domNode) {\n\t\tvar container = domNode.parentNode;\n\t\tvar paddingLeft = parseInt(helpers.getStyle(container, 'padding-left'), 10);\n\t\tvar paddingRight = parseInt(helpers.getStyle(container, 'padding-right'), 10);\n\t\tvar w = container.clientWidth - paddingLeft - paddingRight;\n\t\tvar cw = helpers.getConstraintWidth(domNode);\n\t\treturn isNaN(cw)? w : Math.min(w, cw);\n\t};\n\thelpers.getMaximumHeight = function(domNode) {\n\t\tvar container = domNode.parentNode;\n\t\tvar paddingTop = parseInt(helpers.getStyle(container, 'padding-top'), 10);\n\t\tvar paddingBottom = parseInt(helpers.getStyle(container, 'padding-bottom'), 10);\n\t\tvar h = container.clientHeight - paddingTop - paddingBottom;\n\t\tvar ch = helpers.getConstraintHeight(domNode);\n\t\treturn isNaN(ch)? h : Math.min(h, ch);\n\t};\n\thelpers.getStyle = function(el, property) {\n\t\treturn el.currentStyle ?\n\t\t\tel.currentStyle[property] :\n\t\t\tdocument.defaultView.getComputedStyle(el, null).getPropertyValue(property);\n\t};\n\thelpers.retinaScale = function(chart) {\n\t\tvar pixelRatio = chart.currentDevicePixelRatio = window.devicePixelRatio || 1;\n\t\tif (pixelRatio === 1) {\n\t\t\treturn;\n\t\t}\n\n\t\tvar canvas = chart.canvas;\n\t\tvar height = chart.height;\n\t\tvar width = chart.width;\n\n\t\tcanvas.height = height * pixelRatio;\n\t\tcanvas.width = width * pixelRatio;\n\t\tchart.ctx.scale(pixelRatio, pixelRatio);\n\n\t\t// If no style has been set on the canvas, the render size is used as display size,\n\t\t// making the chart visually bigger, so let's enforce it to the \"correct\" values.\n\t\t// See https://github.com/chartjs/Chart.js/issues/3575\n\t\tcanvas.style.height = height + 'px';\n\t\tcanvas.style.width = width + 'px';\n\t};\n\t// -- Canvas methods\n\thelpers.clear = function(chart) {\n\t\tchart.ctx.clearRect(0, 0, chart.width, chart.height);\n\t};\n\thelpers.fontString = function(pixelSize, fontStyle, fontFamily) {\n\t\treturn fontStyle + ' ' + pixelSize + 'px ' + fontFamily;\n\t};\n\thelpers.longestText = function(ctx, font, arrayOfThings, cache) {\n\t\tcache = cache || {};\n\t\tvar data = cache.data = cache.data || {};\n\t\tvar gc = cache.garbageCollect = cache.garbageCollect || [];\n\n\t\tif (cache.font !== font) {\n\t\t\tdata = cache.data = {};\n\t\t\tgc = cache.garbageCollect = [];\n\t\t\tcache.font = font;\n\t\t}\n\n\t\tctx.font = font;\n\t\tvar longest = 0;\n\t\thelpers.each(arrayOfThings, function(thing) {\n\t\t\t// Undefined strings and arrays should not be measured\n\t\t\tif (thing !== undefined && thing !== null && helpers.isArray(thing) !== true) {\n\t\t\t\tlongest = helpers.measureText(ctx, data, gc, longest, thing);\n\t\t\t} else if (helpers.isArray(thing)) {\n\t\t\t\t// if it is an array lets measure each element\n\t\t\t\t// to do maybe simplify this function a bit so we can do this more recursively?\n\t\t\t\thelpers.each(thing, function(nestedThing) {\n\t\t\t\t\t// Undefined strings and arrays should not be measured\n\t\t\t\t\tif (nestedThing !== undefined && nestedThing !== null && !helpers.isArray(nestedThing)) {\n\t\t\t\t\t\tlongest = helpers.measureText(ctx, data, gc, longest, nestedThing);\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t}\n\t\t});\n\n\t\tvar gcLen = gc.length / 2;\n\t\tif (gcLen > arrayOfThings.length) {\n\t\t\tfor (var i = 0; i < gcLen; i++) {\n\t\t\t\tdelete data[gc[i]];\n\t\t\t}\n\t\t\tgc.splice(0, gcLen);\n\t\t}\n\t\treturn longest;\n\t};\n\thelpers.measureText = function(ctx, data, gc, longest, string) {\n\t\tvar textWidth = data[string];\n\t\tif (!textWidth) {\n\t\t\ttextWidth = data[string] = ctx.measureText(string).width;\n\t\t\tgc.push(string);\n\t\t}\n\t\tif (textWidth > longest) {\n\t\t\tlongest = textWidth;\n\t\t}\n\t\treturn longest;\n\t};\n\thelpers.numberOfLabelLines = function(arrayOfThings) {\n\t\tvar numberOfLines = 1;\n\t\thelpers.each(arrayOfThings, function(thing) {\n\t\t\tif (helpers.isArray(thing)) {\n\t\t\t\tif (thing.length > numberOfLines) {\n\t\t\t\t\tnumberOfLines = thing.length;\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\t\treturn numberOfLines;\n\t};\n\thelpers.drawRoundedRectangle = function(ctx, x, y, width, height, radius) {\n\t\tctx.beginPath();\n\t\tctx.moveTo(x + radius, y);\n\t\tctx.lineTo(x + width - radius, y);\n\t\tctx.quadraticCurveTo(x + width, y, x + width, y + radius);\n\t\tctx.lineTo(x + width, y + height - radius);\n\t\tctx.quadraticCurveTo(x + width, y + height, x + width - radius, y + height);\n\t\tctx.lineTo(x + radius, y + height);\n\t\tctx.quadraticCurveTo(x, y + height, x, y + height - radius);\n\t\tctx.lineTo(x, y + radius);\n\t\tctx.quadraticCurveTo(x, y, x + radius, y);\n\t\tctx.closePath();\n\t};\n\n\thelpers.color = !color?\n\t\tfunction(value) {\n\t\t\tconsole.error('Color.js not found!');\n\t\t\treturn value;\n\t\t} :\n\t\tfunction(value) {\n\t\t\t/* global CanvasGradient */\n\t\t\tif (value instanceof CanvasGradient) {\n\t\t\t\tvalue = Chart.defaults.global.defaultColor;\n\t\t\t}\n\n\t\t\treturn color(value);\n\t\t};\n\n\thelpers.isArray = Array.isArray?\n\t\tfunction(obj) {\n\t\t\treturn Array.isArray(obj);\n\t\t} :\n\t\tfunction(obj) {\n\t\t\treturn Object.prototype.toString.call(obj) === '[object Array]';\n\t\t};\n\t// ! @see http://stackoverflow.com/a/14853974\n\thelpers.arrayEquals = function(a0, a1) {\n\t\tvar i, ilen, v0, v1;\n\n\t\tif (!a0 || !a1 || a0.length !== a1.length) {\n\t\t\treturn false;\n\t\t}\n\n\t\tfor (i = 0, ilen=a0.length; i < ilen; ++i) {\n\t\t\tv0 = a0[i];\n\t\t\tv1 = a1[i];\n\n\t\t\tif (v0 instanceof Array && v1 instanceof Array) {\n\t\t\t\tif (!helpers.arrayEquals(v0, v1)) {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t} else if (v0 !== v1) {\n\t\t\t\t// NOTE: two different object instances will never be equal: {x:20} != {x:20}\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\n\t\treturn true;\n\t};\n\thelpers.callback = function(fn, args, thisArg) {\n\t\tif (fn && typeof fn.call === 'function') {\n\t\t\tfn.apply(thisArg, args);\n\t\t}\n\t};\n\thelpers.getHoverColor = function(colorValue) {\n\t\t/* global CanvasPattern */\n\t\treturn (colorValue instanceof CanvasPattern) ?\n\t\t\tcolorValue :\n\t\t\thelpers.color(colorValue).saturate(0.5).darken(0.1).rgbString();\n\t};\n\n\t/**\n\t * Provided for backward compatibility, use Chart.helpers#callback instead.\n\t * @function Chart.helpers#callCallback\n\t * @deprecated since version 2.6.0\n\t * @todo remove at version 3\n\t */\n\thelpers.callCallback = helpers.callback;\n};\n\n},{\"2\":2}],27:[function(require,module,exports){\n'use strict';\n\nmodule.exports = function(Chart) {\n\tvar helpers = Chart.helpers;\n\n\t/**\n\t * Helper function to get relative position for an event\n\t * @param {Event|IEvent} event - The event to get the position for\n\t * @param {Chart} chart - The chart\n\t * @returns {Point} the event position\n\t */\n\tfunction getRelativePosition(e, chart) {\n\t\tif (e.native) {\n\t\t\treturn {\n\t\t\t\tx: e.x,\n\t\t\t\ty: e.y\n\t\t\t};\n\t\t}\n\n\t\treturn helpers.getRelativePosition(e, chart);\n\t}\n\n\t/**\n\t * Helper function to traverse all of the visible elements in the chart\n\t * @param chart {chart} the chart\n\t * @param handler {Function} the callback to execute for each visible item\n\t */\n\tfunction parseVisibleItems(chart, handler) {\n\t\tvar datasets = chart.data.datasets;\n\t\tvar meta, i, j, ilen, jlen;\n\n\t\tfor (i = 0, ilen = datasets.length; i < ilen; ++i) {\n\t\t\tif (!chart.isDatasetVisible(i)) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tmeta = chart.getDatasetMeta(i);\n\t\t\tfor (j = 0, jlen = meta.data.length; j < jlen; ++j) {\n\t\t\t\tvar element = meta.data[j];\n\t\t\t\tif (!element._view.skip) {\n\t\t\t\t\thandler(element);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Helper function to get the items that intersect the event position\n\t * @param items {ChartElement[]} elements to filter\n\t * @param position {Point} the point to be nearest to\n\t * @return {ChartElement[]} the nearest items\n\t */\n\tfunction getIntersectItems(chart, position) {\n\t\tvar elements = [];\n\n\t\tparseVisibleItems(chart, function(element) {\n\t\t\tif (element.inRange(position.x, position.y)) {\n\t\t\t\telements.push(element);\n\t\t\t}\n\t\t});\n\n\t\treturn elements;\n\t}\n\n\t/**\n\t * Helper function to get the items nearest to the event position considering all visible items in teh chart\n\t * @param chart {Chart} the chart to look at elements from\n\t * @param position {Point} the point to be nearest to\n\t * @param intersect {Boolean} if true, only consider items that intersect the position\n\t * @param distanceMetric {Function} Optional function to provide the distance between\n\t * @return {ChartElement[]} the nearest items\n\t */\n\tfunction getNearestItems(chart, position, intersect, distanceMetric) {\n\t\tvar minDistance = Number.POSITIVE_INFINITY;\n\t\tvar nearestItems = [];\n\n\t\tif (!distanceMetric) {\n\t\t\tdistanceMetric = helpers.distanceBetweenPoints;\n\t\t}\n\n\t\tparseVisibleItems(chart, function(element) {\n\t\t\tif (intersect && !element.inRange(position.x, position.y)) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tvar center = element.getCenterPoint();\n\t\t\tvar distance = distanceMetric(position, center);\n\n\t\t\tif (distance < minDistance) {\n\t\t\t\tnearestItems = [element];\n\t\t\t\tminDistance = distance;\n\t\t\t} else if (distance === minDistance) {\n\t\t\t\t// Can have multiple items at the same distance in which case we sort by size\n\t\t\t\tnearestItems.push(element);\n\t\t\t}\n\t\t});\n\n\t\treturn nearestItems;\n\t}\n\n\tfunction indexMode(chart, e, options) {\n\t\tvar position = getRelativePosition(e, chart);\n\t\tvar distanceMetric = function(pt1, pt2) {\n\t\t\treturn Math.abs(pt1.x - pt2.x);\n\t\t};\n\t\tvar items = options.intersect ? getIntersectItems(chart, position) : getNearestItems(chart, position, false, distanceMetric);\n\t\tvar elements = [];\n\n\t\tif (!items.length) {\n\t\t\treturn [];\n\t\t}\n\n\t\tchart.data.datasets.forEach(function(dataset, datasetIndex) {\n\t\t\tif (chart.isDatasetVisible(datasetIndex)) {\n\t\t\t\tvar meta = chart.getDatasetMeta(datasetIndex),\n\t\t\t\t\telement = meta.data[items[0]._index];\n\n\t\t\t\t// don't count items that are skipped (null data)\n\t\t\t\tif (element && !element._view.skip) {\n\t\t\t\t\telements.push(element);\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\n\t\treturn elements;\n\t}\n\n\t/**\n\t * @interface IInteractionOptions\n\t */\n\t/**\n\t * If true, only consider items that intersect the point\n\t * @name IInterfaceOptions#boolean\n\t * @type Boolean\n\t */\n\n\t/**\n\t * Contains interaction related functions\n\t * @namespace Chart.Interaction\n\t */\n\tChart.Interaction = {\n\t\t// Helper function for different modes\n\t\tmodes: {\n\t\t\tsingle: function(chart, e) {\n\t\t\t\tvar position = getRelativePosition(e, chart);\n\t\t\t\tvar elements = [];\n\n\t\t\t\tparseVisibleItems(chart, function(element) {\n\t\t\t\t\tif (element.inRange(position.x, position.y)) {\n\t\t\t\t\t\telements.push(element);\n\t\t\t\t\t\treturn elements;\n\t\t\t\t\t}\n\t\t\t\t});\n\n\t\t\t\treturn elements.slice(0, 1);\n\t\t\t},\n\n\t\t\t/**\n\t\t\t * @function Chart.Interaction.modes.label\n\t\t\t * @deprecated since version 2.4.0\n\t \t\t * @todo remove at version 3\n\t\t\t * @private\n\t\t\t */\n\t\t\tlabel: indexMode,\n\n\t\t\t/**\n\t\t\t * Returns items at the same index. If the options.intersect parameter is true, we only return items if we intersect something\n\t\t\t * If the options.intersect mode is false, we find the nearest item and return the items at the same index as that item\n\t\t\t * @function Chart.Interaction.modes.index\n\t\t\t * @since v2.4.0\n\t\t\t * @param chart {chart} the chart we are returning items from\n\t\t\t * @param e {Event} the event we are find things at\n\t\t\t * @param options {IInteractionOptions} options to use during interaction\n\t\t\t * @return {Chart.Element[]} Array of elements that are under the point. If none are found, an empty array is returned\n\t\t\t */\n\t\t\tindex: indexMode,\n\n\t\t\t/**\n\t\t\t * Returns items in the same dataset. If the options.intersect parameter is true, we only return items if we intersect something\n\t\t\t * If the options.intersect is false, we find the nearest item and return the items in that dataset\n\t\t\t * @function Chart.Interaction.modes.dataset\n\t\t\t * @param chart {chart} the chart we are returning items from\n\t\t\t * @param e {Event} the event we are find things at\n\t\t\t * @param options {IInteractionOptions} options to use during interaction\n\t\t\t * @return {Chart.Element[]} Array of elements that are under the point. If none are found, an empty array is returned\n\t\t\t */\n\t\t\tdataset: function(chart, e, options) {\n\t\t\t\tvar position = getRelativePosition(e, chart);\n\t\t\t\tvar items = options.intersect ? getIntersectItems(chart, position) : getNearestItems(chart, position, false);\n\n\t\t\t\tif (items.length > 0) {\n\t\t\t\t\titems = chart.getDatasetMeta(items[0]._datasetIndex).data;\n\t\t\t\t}\n\n\t\t\t\treturn items;\n\t\t\t},\n\n\t\t\t/**\n\t\t\t * @function Chart.Interaction.modes.x-axis\n\t\t\t * @deprecated since version 2.4.0. Use index mode and intersect == true\n\t\t\t * @todo remove at version 3\n\t\t\t * @private\n\t\t\t */\n\t\t\t'x-axis': function(chart, e) {\n\t\t\t\treturn indexMode(chart, e, true);\n\t\t\t},\n\n\t\t\t/**\n\t\t\t * Point mode returns all elements that hit test based on the event position\n\t\t\t * of the event\n\t\t\t * @function Chart.Interaction.modes.intersect\n\t\t\t * @param chart {chart} the chart we are returning items from\n\t\t\t * @param e {Event} the event we are find things at\n\t\t\t * @return {Chart.Element[]} Array of elements that are under the point. If none are found, an empty array is returned\n\t\t\t */\n\t\t\tpoint: function(chart, e) {\n\t\t\t\tvar position = getRelativePosition(e, chart);\n\t\t\t\treturn getIntersectItems(chart, position);\n\t\t\t},\n\n\t\t\t/**\n\t\t\t * nearest mode returns the element closest to the point\n\t\t\t * @function Chart.Interaction.modes.intersect\n\t\t\t * @param chart {chart} the chart we are returning items from\n\t\t\t * @param e {Event} the event we are find things at\n\t\t\t * @param options {IInteractionOptions} options to use\n\t\t\t * @return {Chart.Element[]} Array of elements that are under the point. If none are found, an empty array is returned\n\t\t\t */\n\t\t\tnearest: function(chart, e, options) {\n\t\t\t\tvar position = getRelativePosition(e, chart);\n\t\t\t\tvar nearestItems = getNearestItems(chart, position, options.intersect);\n\n\t\t\t\t// We have multiple items at the same distance from the event. Now sort by smallest\n\t\t\t\tif (nearestItems.length > 1) {\n\t\t\t\t\tnearestItems.sort(function(a, b) {\n\t\t\t\t\t\tvar sizeA = a.getArea();\n\t\t\t\t\t\tvar sizeB = b.getArea();\n\t\t\t\t\t\tvar ret = sizeA - sizeB;\n\n\t\t\t\t\t\tif (ret === 0) {\n\t\t\t\t\t\t\t// if equal sort by dataset index\n\t\t\t\t\t\t\tret = a._datasetIndex - b._datasetIndex;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\treturn ret;\n\t\t\t\t\t});\n\t\t\t\t}\n\n\t\t\t\t// Return only 1 item\n\t\t\t\treturn nearestItems.slice(0, 1);\n\t\t\t},\n\n\t\t\t/**\n\t\t\t * x mode returns the elements that hit-test at the current x coordinate\n\t\t\t * @function Chart.Interaction.modes.x\n\t\t\t * @param chart {chart} the chart we are returning items from\n\t\t\t * @param e {Event} the event we are find things at\n\t\t\t * @param options {IInteractionOptions} options to use\n\t\t\t * @return {Chart.Element[]} Array of elements that are under the point. If none are found, an empty array is returned\n\t\t\t */\n\t\t\tx: function(chart, e, options) {\n\t\t\t\tvar position = getRelativePosition(e, chart);\n\t\t\t\tvar items = [];\n\t\t\t\tvar intersectsItem = false;\n\n\t\t\t\tparseVisibleItems(chart, function(element) {\n\t\t\t\t\tif (element.inXRange(position.x)) {\n\t\t\t\t\t\titems.push(element);\n\t\t\t\t\t}\n\n\t\t\t\t\tif (element.inRange(position.x, position.y)) {\n\t\t\t\t\t\tintersectsItem = true;\n\t\t\t\t\t}\n\t\t\t\t});\n\n\t\t\t\t// If we want to trigger on an intersect and we don't have any items\n\t\t\t\t// that intersect the position, return nothing\n\t\t\t\tif (options.intersect && !intersectsItem) {\n\t\t\t\t\titems = [];\n\t\t\t\t}\n\t\t\t\treturn items;\n\t\t\t},\n\n\t\t\t/**\n\t\t\t * y mode returns the elements that hit-test at the current y coordinate\n\t\t\t * @function Chart.Interaction.modes.y\n\t\t\t * @param chart {chart} the chart we are returning items from\n\t\t\t * @param e {Event} the event we are find things at\n\t\t\t * @param options {IInteractionOptions} options to use\n\t\t\t * @return {Chart.Element[]} Array of elements that are under the point. If none are found, an empty array is returned\n\t\t\t */\n\t\t\ty: function(chart, e, options) {\n\t\t\t\tvar position = getRelativePosition(e, chart);\n\t\t\t\tvar items = [];\n\t\t\t\tvar intersectsItem = false;\n\n\t\t\t\tparseVisibleItems(chart, function(element) {\n\t\t\t\t\tif (element.inYRange(position.y)) {\n\t\t\t\t\t\titems.push(element);\n\t\t\t\t\t}\n\n\t\t\t\t\tif (element.inRange(position.x, position.y)) {\n\t\t\t\t\t\tintersectsItem = true;\n\t\t\t\t\t}\n\t\t\t\t});\n\n\t\t\t\t// If we want to trigger on an intersect and we don't have any items\n\t\t\t\t// that intersect the position, return nothing\n\t\t\t\tif (options.intersect && !intersectsItem) {\n\t\t\t\t\titems = [];\n\t\t\t\t}\n\t\t\t\treturn items;\n\t\t\t}\n\t\t}\n\t};\n};\n\n},{}],28:[function(require,module,exports){\n'use strict';\n\nmodule.exports = function() {\n\n\t// Occupy the global variable of Chart, and create a simple base class\n\tvar Chart = function(item, config) {\n\t\tthis.construct(item, config);\n\t\treturn this;\n\t};\n\n\t// Globally expose the defaults to allow for user updating/changing\n\tChart.defaults = {\n\t\tglobal: {\n\t\t\tresponsive: true,\n\t\t\tresponsiveAnimationDuration: 0,\n\t\t\tmaintainAspectRatio: true,\n\t\t\tevents: ['mousemove', 'mouseout', 'click', 'touchstart', 'touchmove'],\n\t\t\thover: {\n\t\t\t\tonHover: null,\n\t\t\t\tmode: 'nearest',\n\t\t\t\tintersect: true,\n\t\t\t\tanimationDuration: 400\n\t\t\t},\n\t\t\tonClick: null,\n\t\t\tdefaultColor: 'rgba(0,0,0,0.1)',\n\t\t\tdefaultFontColor: '#666',\n\t\t\tdefaultFontFamily: \"'Helvetica Neue', 'Helvetica', 'Arial', sans-serif\",\n\t\t\tdefaultFontSize: 12,\n\t\t\tdefaultFontStyle: 'normal',\n\t\t\tshowLines: true,\n\n\t\t\t// Element defaults defined in element extensions\n\t\t\telements: {},\n\n\t\t\t// Legend callback string\n\t\t\tlegendCallback: function(chart) {\n\t\t\t\tvar text = [];\n\t\t\t\ttext.push('<ul class=\"' + chart.id + '-legend\">');\n\t\t\t\tfor (var i = 0; i < chart.data.datasets.length; i++) {\n\t\t\t\t\ttext.push('<li><span style=\"background-color:' + chart.data.datasets[i].backgroundColor + '\"></span>');\n\t\t\t\t\tif (chart.data.datasets[i].label) {\n\t\t\t\t\t\ttext.push(chart.data.datasets[i].label);\n\t\t\t\t\t}\n\t\t\t\t\ttext.push('</li>');\n\t\t\t\t}\n\t\t\t\ttext.push('</ul>');\n\n\t\t\t\treturn text.join('');\n\t\t\t}\n\t\t}\n\t};\n\n\tChart.Chart = Chart;\n\n\treturn Chart;\n};\n\n},{}],29:[function(require,module,exports){\n'use strict';\n\nmodule.exports = function(Chart) {\n\n\tvar helpers = Chart.helpers;\n\n\tfunction filterByPosition(array, position) {\n\t\treturn helpers.where(array, function(v) {\n\t\t\treturn v.position === position;\n\t\t});\n\t}\n\n\tfunction sortByWeight(array, reverse) {\n\t\tarray.forEach(function(v, i) {\n\t\t\tv._tmpIndex_ = i;\n\t\t\treturn v;\n\t\t});\n\t\tarray.sort(function(a, b) {\n\t\t\tvar v0 = reverse ? b : a;\n\t\t\tvar v1 = reverse ? a : b;\n\t\t\treturn v0.weight === v1.weight ?\n\t\t\t\tv0._tmpIndex_ - v1._tmpIndex_ :\n\t\t\t\tv0.weight - v1.weight;\n\t\t});\n\t\tarray.forEach(function(v) {\n\t\t\tdelete v._tmpIndex_;\n\t\t});\n\t}\n\n\t/**\n\t * @interface ILayoutItem\n\t * @prop {String} position - The position of the item in the chart layout. Possible values are\n\t * 'left', 'top', 'right', 'bottom', and 'chartArea'\n\t * @prop {Number} weight - The weight used to sort the item. Higher weights are further away from the chart area\n\t * @prop {Boolean} fullWidth - if true, and the item is horizontal, then push vertical boxes down\n\t * @prop {Function} isHorizontal - returns true if the layout item is horizontal (ie. top or bottom)\n\t * @prop {Function} update - Takes two parameters: width and height. Returns size of item\n\t * @prop {Function} getPadding -  Returns an object with padding on the edges\n\t * @prop {Number} width - Width of item. Must be valid after update()\n\t * @prop {Number} height - Height of item. Must be valid after update()\n\t * @prop {Number} left - Left edge of the item. Set by layout system and cannot be used in update\n\t * @prop {Number} top - Top edge of the item. Set by layout system and cannot be used in update\n\t * @prop {Number} right - Right edge of the item. Set by layout system and cannot be used in update\n\t * @prop {Number} bottom - Bottom edge of the item. Set by layout system and cannot be used in update\n\t */\n\n\t// The layout service is very self explanatory.  It's responsible for the layout within a chart.\n\t// Scales, Legends and Plugins all rely on the layout service and can easily register to be placed anywhere they need\n\t// It is this service's responsibility of carrying out that layout.\n\tChart.layoutService = {\n\t\tdefaults: {},\n\n\t\t/**\n\t\t * Register a box to a chart.\n\t\t * A box is simply a reference to an object that requires layout. eg. Scales, Legend, Title.\n\t\t * @param {Chart} chart - the chart to use\n\t\t * @param {ILayoutItem} item - the item to add to be layed out\n\t\t */\n\t\taddBox: function(chart, item) {\n\t\t\tif (!chart.boxes) {\n\t\t\t\tchart.boxes = [];\n\t\t\t}\n\n\t\t\t// initialize item with default values\n\t\t\titem.fullWidth = item.fullWidth || false;\n\t\t\titem.position = item.position || 'top';\n\t\t\titem.weight = item.weight || 0;\n\n\t\t\tchart.boxes.push(item);\n\t\t},\n\n\t\t/**\n\t\t * Remove a layoutItem from a chart\n\t\t * @param {Chart} chart - the chart to remove the box from\n\t\t * @param {Object} layoutItem - the item to remove from the layout\n\t\t */\n\t\tremoveBox: function(chart, layoutItem) {\n\t\t\tvar index = chart.boxes? chart.boxes.indexOf(layoutItem) : -1;\n\t\t\tif (index !== -1) {\n\t\t\t\tchart.boxes.splice(index, 1);\n\t\t\t}\n\t\t},\n\n\t\t/**\n\t\t * Sets (or updates) options on the given `item`.\n\t\t * @param {Chart} chart - the chart in which the item lives (or will be added to)\n\t\t * @param {Object} item - the item to configure with the given options\n\t\t * @param {Object} options - the new item options.\n\t\t */\n\t\tconfigure: function(chart, item, options) {\n\t\t\tvar props = ['fullWidth', 'position', 'weight'];\n\t\t\tvar ilen = props.length;\n\t\t\tvar i = 0;\n\t\t\tvar prop;\n\n\t\t\tfor (; i<ilen; ++i) {\n\t\t\t\tprop = props[i];\n\t\t\t\tif (options.hasOwnProperty(prop)) {\n\t\t\t\t\titem[prop] = options[prop];\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\n\t\t/**\n\t\t * Fits boxes of the given chart into the given size by having each box measure itself\n\t\t * then running a fitting algorithm\n\t\t * @param {Chart} chart - the chart\n\t\t * @param {Number} width - the width to fit into\n\t\t * @param {Number} height - the height to fit into\n\t\t */\n\t\tupdate: function(chart, width, height) {\n\t\t\tif (!chart) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tvar layoutOptions = chart.options.layout;\n\t\t\tvar padding = layoutOptions ? layoutOptions.padding : null;\n\n\t\t\tvar leftPadding = 0;\n\t\t\tvar rightPadding = 0;\n\t\t\tvar topPadding = 0;\n\t\t\tvar bottomPadding = 0;\n\n\t\t\tif (!isNaN(padding)) {\n\t\t\t\t// options.layout.padding is a number. assign to all\n\t\t\t\tleftPadding = padding;\n\t\t\t\trightPadding = padding;\n\t\t\t\ttopPadding = padding;\n\t\t\t\tbottomPadding = padding;\n\t\t\t} else {\n\t\t\t\tleftPadding = padding.left || 0;\n\t\t\t\trightPadding = padding.right || 0;\n\t\t\t\ttopPadding = padding.top || 0;\n\t\t\t\tbottomPadding = padding.bottom || 0;\n\t\t\t}\n\n\t\t\tvar leftBoxes = filterByPosition(chart.boxes, 'left');\n\t\t\tvar rightBoxes = filterByPosition(chart.boxes, 'right');\n\t\t\tvar topBoxes = filterByPosition(chart.boxes, 'top');\n\t\t\tvar bottomBoxes = filterByPosition(chart.boxes, 'bottom');\n\t\t\tvar chartAreaBoxes = filterByPosition(chart.boxes, 'chartArea');\n\n\t\t\t// Sort boxes by weight. A higher weight is further away from the chart area\n\t\t\tsortByWeight(leftBoxes, true);\n\t\t\tsortByWeight(rightBoxes, false);\n\t\t\tsortByWeight(topBoxes, true);\n\t\t\tsortByWeight(bottomBoxes, false);\n\n\t\t\t// Essentially we now have any number of boxes on each of the 4 sides.\n\t\t\t// Our canvas looks like the following.\n\t\t\t// The areas L1 and L2 are the left axes. R1 is the right axis, T1 is the top axis and\n\t\t\t// B1 is the bottom axis\n\t\t\t// There are also 4 quadrant-like locations (left to right instead of clockwise) reserved for chart overlays\n\t\t\t// These locations are single-box locations only, when trying to register a chartArea location that is already taken,\n\t\t\t// an error will be thrown.\n\t\t\t//\n\t\t\t// |----------------------------------------------------|\n\t\t\t// |                  T1 (Full Width)                   |\n\t\t\t// |----------------------------------------------------|\n\t\t\t// |    |    |                 T2                  |    |\n\t\t\t// |    |----|-------------------------------------|----|\n\t\t\t// |    |    | C1 |                           | C2 |    |\n\t\t\t// |    |    |----|                           |----|    |\n\t\t\t// |    |    |                                     |    |\n\t\t\t// | L1 | L2 |           ChartArea (C0)            | R1 |\n\t\t\t// |    |    |                                     |    |\n\t\t\t// |    |    |----|                           |----|    |\n\t\t\t// |    |    | C3 |                           | C4 |    |\n\t\t\t// |    |----|-------------------------------------|----|\n\t\t\t// |    |    |                 B1                  |    |\n\t\t\t// |----------------------------------------------------|\n\t\t\t// |                  B2 (Full Width)                   |\n\t\t\t// |----------------------------------------------------|\n\t\t\t//\n\t\t\t// What we do to find the best sizing, we do the following\n\t\t\t// 1. Determine the minimum size of the chart area.\n\t\t\t// 2. Split the remaining width equally between each vertical axis\n\t\t\t// 3. Split the remaining height equally between each horizontal axis\n\t\t\t// 4. Give each layout the maximum size it can be. The layout will return it's minimum size\n\t\t\t// 5. Adjust the sizes of each axis based on it's minimum reported size.\n\t\t\t// 6. Refit each axis\n\t\t\t// 7. Position each axis in the final location\n\t\t\t// 8. Tell the chart the final location of the chart area\n\t\t\t// 9. Tell any axes that overlay the chart area the positions of the chart area\n\n\t\t\t// Step 1\n\t\t\tvar chartWidth = width - leftPadding - rightPadding;\n\t\t\tvar chartHeight = height - topPadding - bottomPadding;\n\t\t\tvar chartAreaWidth = chartWidth / 2; // min 50%\n\t\t\tvar chartAreaHeight = chartHeight / 2; // min 50%\n\n\t\t\t// Step 2\n\t\t\tvar verticalBoxWidth = (width - chartAreaWidth) / (leftBoxes.length + rightBoxes.length);\n\n\t\t\t// Step 3\n\t\t\tvar horizontalBoxHeight = (height - chartAreaHeight) / (topBoxes.length + bottomBoxes.length);\n\n\t\t\t// Step 4\n\t\t\tvar maxChartAreaWidth = chartWidth;\n\t\t\tvar maxChartAreaHeight = chartHeight;\n\t\t\tvar minBoxSizes = [];\n\n\t\t\tfunction getMinimumBoxSize(box) {\n\t\t\t\tvar minSize;\n\t\t\t\tvar isHorizontal = box.isHorizontal();\n\n\t\t\t\tif (isHorizontal) {\n\t\t\t\t\tminSize = box.update(box.fullWidth ? chartWidth : maxChartAreaWidth, horizontalBoxHeight);\n\t\t\t\t\tmaxChartAreaHeight -= minSize.height;\n\t\t\t\t} else {\n\t\t\t\t\tminSize = box.update(verticalBoxWidth, chartAreaHeight);\n\t\t\t\t\tmaxChartAreaWidth -= minSize.width;\n\t\t\t\t}\n\n\t\t\t\tminBoxSizes.push({\n\t\t\t\t\thorizontal: isHorizontal,\n\t\t\t\t\tminSize: minSize,\n\t\t\t\t\tbox: box,\n\t\t\t\t});\n\t\t\t}\n\n\t\t\thelpers.each(leftBoxes.concat(rightBoxes, topBoxes, bottomBoxes), getMinimumBoxSize);\n\n\t\t\t// If a horizontal box has padding, we move the left boxes over to avoid ugly charts (see issue #2478)\n\t\t\tvar maxHorizontalLeftPadding = 0;\n\t\t\tvar maxHorizontalRightPadding = 0;\n\t\t\tvar maxVerticalTopPadding = 0;\n\t\t\tvar maxVerticalBottomPadding = 0;\n\n\t\t\thelpers.each(topBoxes.concat(bottomBoxes), function(horizontalBox) {\n\t\t\t\tif (horizontalBox.getPadding) {\n\t\t\t\t\tvar boxPadding = horizontalBox.getPadding();\n\t\t\t\t\tmaxHorizontalLeftPadding = Math.max(maxHorizontalLeftPadding, boxPadding.left);\n\t\t\t\t\tmaxHorizontalRightPadding = Math.max(maxHorizontalRightPadding, boxPadding.right);\n\t\t\t\t}\n\t\t\t});\n\n\t\t\thelpers.each(leftBoxes.concat(rightBoxes), function(verticalBox) {\n\t\t\t\tif (verticalBox.getPadding) {\n\t\t\t\t\tvar boxPadding = verticalBox.getPadding();\n\t\t\t\t\tmaxVerticalTopPadding = Math.max(maxVerticalTopPadding, boxPadding.top);\n\t\t\t\t\tmaxVerticalBottomPadding = Math.max(maxVerticalBottomPadding, boxPadding.bottom);\n\t\t\t\t}\n\t\t\t});\n\n\t\t\t// At this point, maxChartAreaHeight and maxChartAreaWidth are the size the chart area could\n\t\t\t// be if the axes are drawn at their minimum sizes.\n\t\t\t// Steps 5 & 6\n\t\t\tvar totalLeftBoxesWidth = leftPadding;\n\t\t\tvar totalRightBoxesWidth = rightPadding;\n\t\t\tvar totalTopBoxesHeight = topPadding;\n\t\t\tvar totalBottomBoxesHeight = bottomPadding;\n\n\t\t\t// Function to fit a box\n\t\t\tfunction fitBox(box) {\n\t\t\t\tvar minBoxSize = helpers.findNextWhere(minBoxSizes, function(minBox) {\n\t\t\t\t\treturn minBox.box === box;\n\t\t\t\t});\n\n\t\t\t\tif (minBoxSize) {\n\t\t\t\t\tif (box.isHorizontal()) {\n\t\t\t\t\t\tvar scaleMargin = {\n\t\t\t\t\t\t\tleft: Math.max(totalLeftBoxesWidth, maxHorizontalLeftPadding),\n\t\t\t\t\t\t\tright: Math.max(totalRightBoxesWidth, maxHorizontalRightPadding),\n\t\t\t\t\t\t\ttop: 0,\n\t\t\t\t\t\t\tbottom: 0\n\t\t\t\t\t\t};\n\n\t\t\t\t\t\t// Don't use min size here because of label rotation. When the labels are rotated, their rotation highly depends\n\t\t\t\t\t\t// on the margin. Sometimes they need to increase in size slightly\n\t\t\t\t\t\tbox.update(box.fullWidth ? chartWidth : maxChartAreaWidth, chartHeight / 2, scaleMargin);\n\t\t\t\t\t} else {\n\t\t\t\t\t\tbox.update(minBoxSize.minSize.width, maxChartAreaHeight);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Update, and calculate the left and right margins for the horizontal boxes\n\t\t\thelpers.each(leftBoxes.concat(rightBoxes), fitBox);\n\n\t\t\thelpers.each(leftBoxes, function(box) {\n\t\t\t\ttotalLeftBoxesWidth += box.width;\n\t\t\t});\n\n\t\t\thelpers.each(rightBoxes, function(box) {\n\t\t\t\ttotalRightBoxesWidth += box.width;\n\t\t\t});\n\n\t\t\t// Set the Left and Right margins for the horizontal boxes\n\t\t\thelpers.each(topBoxes.concat(bottomBoxes), fitBox);\n\n\t\t\t// Figure out how much margin is on the top and bottom of the vertical boxes\n\t\t\thelpers.each(topBoxes, function(box) {\n\t\t\t\ttotalTopBoxesHeight += box.height;\n\t\t\t});\n\n\t\t\thelpers.each(bottomBoxes, function(box) {\n\t\t\t\ttotalBottomBoxesHeight += box.height;\n\t\t\t});\n\n\t\t\tfunction finalFitVerticalBox(box) {\n\t\t\t\tvar minBoxSize = helpers.findNextWhere(minBoxSizes, function(minSize) {\n\t\t\t\t\treturn minSize.box === box;\n\t\t\t\t});\n\n\t\t\t\tvar scaleMargin = {\n\t\t\t\t\tleft: 0,\n\t\t\t\t\tright: 0,\n\t\t\t\t\ttop: totalTopBoxesHeight,\n\t\t\t\t\tbottom: totalBottomBoxesHeight\n\t\t\t\t};\n\n\t\t\t\tif (minBoxSize) {\n\t\t\t\t\tbox.update(minBoxSize.minSize.width, maxChartAreaHeight, scaleMargin);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Let the left layout know the final margin\n\t\t\thelpers.each(leftBoxes.concat(rightBoxes), finalFitVerticalBox);\n\n\t\t\t// Recalculate because the size of each layout might have changed slightly due to the margins (label rotation for instance)\n\t\t\ttotalLeftBoxesWidth = leftPadding;\n\t\t\ttotalRightBoxesWidth = rightPadding;\n\t\t\ttotalTopBoxesHeight = topPadding;\n\t\t\ttotalBottomBoxesHeight = bottomPadding;\n\n\t\t\thelpers.each(leftBoxes, function(box) {\n\t\t\t\ttotalLeftBoxesWidth += box.width;\n\t\t\t});\n\n\t\t\thelpers.each(rightBoxes, function(box) {\n\t\t\t\ttotalRightBoxesWidth += box.width;\n\t\t\t});\n\n\t\t\thelpers.each(topBoxes, function(box) {\n\t\t\t\ttotalTopBoxesHeight += box.height;\n\t\t\t});\n\t\t\thelpers.each(bottomBoxes, function(box) {\n\t\t\t\ttotalBottomBoxesHeight += box.height;\n\t\t\t});\n\n\t\t\t// We may be adding some padding to account for rotated x axis labels\n\t\t\tvar leftPaddingAddition = Math.max(maxHorizontalLeftPadding - totalLeftBoxesWidth, 0);\n\t\t\ttotalLeftBoxesWidth += leftPaddingAddition;\n\t\t\ttotalRightBoxesWidth += Math.max(maxHorizontalRightPadding - totalRightBoxesWidth, 0);\n\n\t\t\tvar topPaddingAddition = Math.max(maxVerticalTopPadding - totalTopBoxesHeight, 0);\n\t\t\ttotalTopBoxesHeight += topPaddingAddition;\n\t\t\ttotalBottomBoxesHeight += Math.max(maxVerticalBottomPadding - totalBottomBoxesHeight, 0);\n\n\t\t\t// Figure out if our chart area changed. This would occur if the dataset layout label rotation\n\t\t\t// changed due to the application of the margins in step 6. Since we can only get bigger, this is safe to do\n\t\t\t// without calling `fit` again\n\t\t\tvar newMaxChartAreaHeight = height - totalTopBoxesHeight - totalBottomBoxesHeight;\n\t\t\tvar newMaxChartAreaWidth = width - totalLeftBoxesWidth - totalRightBoxesWidth;\n\n\t\t\tif (newMaxChartAreaWidth !== maxChartAreaWidth || newMaxChartAreaHeight !== maxChartAreaHeight) {\n\t\t\t\thelpers.each(leftBoxes, function(box) {\n\t\t\t\t\tbox.height = newMaxChartAreaHeight;\n\t\t\t\t});\n\n\t\t\t\thelpers.each(rightBoxes, function(box) {\n\t\t\t\t\tbox.height = newMaxChartAreaHeight;\n\t\t\t\t});\n\n\t\t\t\thelpers.each(topBoxes, function(box) {\n\t\t\t\t\tif (!box.fullWidth) {\n\t\t\t\t\t\tbox.width = newMaxChartAreaWidth;\n\t\t\t\t\t}\n\t\t\t\t});\n\n\t\t\t\thelpers.each(bottomBoxes, function(box) {\n\t\t\t\t\tif (!box.fullWidth) {\n\t\t\t\t\t\tbox.width = newMaxChartAreaWidth;\n\t\t\t\t\t}\n\t\t\t\t});\n\n\t\t\t\tmaxChartAreaHeight = newMaxChartAreaHeight;\n\t\t\t\tmaxChartAreaWidth = newMaxChartAreaWidth;\n\t\t\t}\n\n\t\t\t// Step 7 - Position the boxes\n\t\t\tvar left = leftPadding + leftPaddingAddition;\n\t\t\tvar top = topPadding + topPaddingAddition;\n\n\t\t\tfunction placeBox(box) {\n\t\t\t\tif (box.isHorizontal()) {\n\t\t\t\t\tbox.left = box.fullWidth ? leftPadding : totalLeftBoxesWidth;\n\t\t\t\t\tbox.right = box.fullWidth ? width - rightPadding : totalLeftBoxesWidth + maxChartAreaWidth;\n\t\t\t\t\tbox.top = top;\n\t\t\t\t\tbox.bottom = top + box.height;\n\n\t\t\t\t\t// Move to next point\n\t\t\t\t\ttop = box.bottom;\n\n\t\t\t\t} else {\n\n\t\t\t\t\tbox.left = left;\n\t\t\t\t\tbox.right = left + box.width;\n\t\t\t\t\tbox.top = totalTopBoxesHeight;\n\t\t\t\t\tbox.bottom = totalTopBoxesHeight + maxChartAreaHeight;\n\n\t\t\t\t\t// Move to next point\n\t\t\t\t\tleft = box.right;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\thelpers.each(leftBoxes.concat(topBoxes), placeBox);\n\n\t\t\t// Account for chart width and height\n\t\t\tleft += maxChartAreaWidth;\n\t\t\ttop += maxChartAreaHeight;\n\n\t\t\thelpers.each(rightBoxes, placeBox);\n\t\t\thelpers.each(bottomBoxes, placeBox);\n\n\t\t\t// Step 8\n\t\t\tchart.chartArea = {\n\t\t\t\tleft: totalLeftBoxesWidth,\n\t\t\t\ttop: totalTopBoxesHeight,\n\t\t\t\tright: totalLeftBoxesWidth + maxChartAreaWidth,\n\t\t\t\tbottom: totalTopBoxesHeight + maxChartAreaHeight\n\t\t\t};\n\n\t\t\t// Step 9\n\t\t\thelpers.each(chartAreaBoxes, function(box) {\n\t\t\t\tbox.left = chart.chartArea.left;\n\t\t\t\tbox.top = chart.chartArea.top;\n\t\t\t\tbox.right = chart.chartArea.right;\n\t\t\t\tbox.bottom = chart.chartArea.bottom;\n\n\t\t\t\tbox.update(maxChartAreaWidth, maxChartAreaHeight);\n\t\t\t});\n\t\t}\n\t};\n};\n\n},{}],30:[function(require,module,exports){\n'use strict';\n\nmodule.exports = function(Chart) {\n\n\tvar helpers = Chart.helpers;\n\n\tChart.defaults.global.plugins = {};\n\n\t/**\n\t * The plugin service singleton\n\t * @namespace Chart.plugins\n\t * @since 2.1.0\n\t */\n\tChart.plugins = {\n\t\t/**\n\t\t * Globally registered plugins.\n\t\t * @private\n\t\t */\n\t\t_plugins: [],\n\n\t\t/**\n\t\t * This identifier is used to invalidate the descriptors cache attached to each chart\n\t\t * when a global plugin is registered or unregistered. In this case, the cache ID is\n\t\t * incremented and descriptors are regenerated during following API calls.\n\t\t * @private\n\t\t */\n\t\t_cacheId: 0,\n\n\t\t/**\n\t\t * Registers the given plugin(s) if not already registered.\n\t\t * @param {Array|Object} plugins plugin instance(s).\n\t\t */\n\t\tregister: function(plugins) {\n\t\t\tvar p = this._plugins;\n\t\t\t([]).concat(plugins).forEach(function(plugin) {\n\t\t\t\tif (p.indexOf(plugin) === -1) {\n\t\t\t\t\tp.push(plugin);\n\t\t\t\t}\n\t\t\t});\n\n\t\t\tthis._cacheId++;\n\t\t},\n\n\t\t/**\n\t\t * Unregisters the given plugin(s) only if registered.\n\t\t * @param {Array|Object} plugins plugin instance(s).\n\t\t */\n\t\tunregister: function(plugins) {\n\t\t\tvar p = this._plugins;\n\t\t\t([]).concat(plugins).forEach(function(plugin) {\n\t\t\t\tvar idx = p.indexOf(plugin);\n\t\t\t\tif (idx !== -1) {\n\t\t\t\t\tp.splice(idx, 1);\n\t\t\t\t}\n\t\t\t});\n\n\t\t\tthis._cacheId++;\n\t\t},\n\n\t\t/**\n\t\t * Remove all registered plugins.\n\t\t * @since 2.1.5\n\t\t */\n\t\tclear: function() {\n\t\t\tthis._plugins = [];\n\t\t\tthis._cacheId++;\n\t\t},\n\n\t\t/**\n\t\t * Returns the number of registered plugins?\n\t\t * @returns {Number}\n\t\t * @since 2.1.5\n\t\t */\n\t\tcount: function() {\n\t\t\treturn this._plugins.length;\n\t\t},\n\n\t\t/**\n\t\t * Returns all registered plugin instances.\n\t\t * @returns {Array} array of plugin objects.\n\t\t * @since 2.1.5\n\t\t */\n\t\tgetAll: function() {\n\t\t\treturn this._plugins;\n\t\t},\n\n\t\t/**\n\t\t * Calls enabled plugins for `chart` on the specified hook and with the given args.\n\t\t * This method immediately returns as soon as a plugin explicitly returns false. The\n\t\t * returned value can be used, for instance, to interrupt the current action.\n\t\t * @param {Object} chart - The chart instance for which plugins should be called.\n\t\t * @param {String} hook - The name of the plugin method to call (e.g. 'beforeUpdate').\n\t\t * @param {Array} [args] - Extra arguments to apply to the hook call.\n\t\t * @returns {Boolean} false if any of the plugins return false, else returns true.\n\t\t */\n\t\tnotify: function(chart, hook, args) {\n\t\t\tvar descriptors = this.descriptors(chart);\n\t\t\tvar ilen = descriptors.length;\n\t\t\tvar i, descriptor, plugin, params, method;\n\n\t\t\tfor (i=0; i<ilen; ++i) {\n\t\t\t\tdescriptor = descriptors[i];\n\t\t\t\tplugin = descriptor.plugin;\n\t\t\t\tmethod = plugin[hook];\n\t\t\t\tif (typeof method === 'function') {\n\t\t\t\t\tparams = [chart].concat(args || []);\n\t\t\t\t\tparams.push(descriptor.options);\n\t\t\t\t\tif (method.apply(plugin, params) === false) {\n\t\t\t\t\t\treturn false;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn true;\n\t\t},\n\n\t\t/**\n\t\t * Returns descriptors of enabled plugins for the given chart.\n\t\t * @returns {Array} [{ plugin, options }]\n\t\t * @private\n\t\t */\n\t\tdescriptors: function(chart) {\n\t\t\tvar cache = chart._plugins || (chart._plugins = {});\n\t\t\tif (cache.id === this._cacheId) {\n\t\t\t\treturn cache.descriptors;\n\t\t\t}\n\n\t\t\tvar plugins = [];\n\t\t\tvar descriptors = [];\n\t\t\tvar config = (chart && chart.config) || {};\n\t\t\tvar defaults = Chart.defaults.global.plugins;\n\t\t\tvar options = (config.options && config.options.plugins) || {};\n\n\t\t\tthis._plugins.concat(config.plugins || []).forEach(function(plugin) {\n\t\t\t\tvar idx = plugins.indexOf(plugin);\n\t\t\t\tif (idx !== -1) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tvar id = plugin.id;\n\t\t\t\tvar opts = options[id];\n\t\t\t\tif (opts === false) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tif (opts === true) {\n\t\t\t\t\topts = helpers.clone(defaults[id]);\n\t\t\t\t}\n\n\t\t\t\tplugins.push(plugin);\n\t\t\t\tdescriptors.push({\n\t\t\t\t\tplugin: plugin,\n\t\t\t\t\toptions: opts || {}\n\t\t\t\t});\n\t\t\t});\n\n\t\t\tcache.descriptors = descriptors;\n\t\t\tcache.id = this._cacheId;\n\t\t\treturn descriptors;\n\t\t}\n\t};\n\n\t/**\n\t * Plugin extension hooks.\n\t * @interface IPlugin\n\t * @since 2.1.0\n\t */\n\t/**\n\t * @method IPlugin#beforeInit\n\t * @desc Called before initializing `chart`.\n\t * @param {Chart.Controller} chart - The chart instance.\n\t * @param {Object} options - The plugin options.\n\t */\n\t/**\n\t * @method IPlugin#afterInit\n\t * @desc Called after `chart` has been initialized and before the first update.\n\t * @param {Chart.Controller} chart - The chart instance.\n\t * @param {Object} options - The plugin options.\n\t */\n\t/**\n\t * @method IPlugin#beforeUpdate\n\t * @desc Called before updating `chart`. If any plugin returns `false`, the update\n\t * is cancelled (and thus subsequent render(s)) until another `update` is triggered.\n\t * @param {Chart.Controller} chart - The chart instance.\n\t * @param {Object} options - The plugin options.\n\t * @returns {Boolean} `false` to cancel the chart update.\n\t */\n\t/**\n\t * @method IPlugin#afterUpdate\n\t * @desc Called after `chart` has been updated and before rendering. Note that this\n\t * hook will not be called if the chart update has been previously cancelled.\n\t * @param {Chart.Controller} chart - The chart instance.\n\t * @param {Object} options - The plugin options.\n\t */\n\t/**\n\t * @method IPlugin#beforeDatasetsUpdate\n \t * @desc Called before updating the `chart` datasets. If any plugin returns `false`,\n\t * the datasets update is cancelled until another `update` is triggered.\n\t * @param {Chart.Controller} chart - The chart instance.\n\t * @param {Object} options - The plugin options.\n\t * @returns {Boolean} false to cancel the datasets update.\n\t * @since version 2.1.5\n\t */\n\t/**\n\t * @method IPlugin#afterDatasetsUpdate\n\t * @desc Called after the `chart` datasets have been updated. Note that this hook\n\t * will not be called if the datasets update has been previously cancelled.\n\t * @param {Chart.Controller} chart - The chart instance.\n\t * @param {Object} options - The plugin options.\n\t * @since version 2.1.5\n\t */\n\t/**\n\t * @method IPlugin#beforeDatasetUpdate\n \t * @desc Called before updating the `chart` dataset at the given `args.index`. If any plugin\n\t * returns `false`, the datasets update is cancelled until another `update` is triggered.\n\t * @param {Chart} chart - The chart instance.\n\t * @param {Object} args - The call arguments.\n\t * @param {Object} args.index - The dataset index.\n\t * @param {Number} args.meta - The dataset metadata.\n\t * @param {Object} options - The plugin options.\n\t * @returns {Boolean} `false` to cancel the chart datasets drawing.\n\t */\n\t/**\n\t * @method IPlugin#afterDatasetUpdate\n \t * @desc Called after the `chart` datasets at the given `args.index` has been updated. Note\n\t * that this hook will not be called if the datasets update has been previously cancelled.\n\t * @param {Chart} chart - The chart instance.\n\t * @param {Object} args - The call arguments.\n\t * @param {Object} args.index - The dataset index.\n\t * @param {Number} args.meta - The dataset metadata.\n\t * @param {Object} options - The plugin options.\n\t */\n\t/**\n\t * @method IPlugin#beforeLayout\n\t * @desc Called before laying out `chart`. If any plugin returns `false`,\n\t * the layout update is cancelled until another `update` is triggered.\n\t * @param {Chart.Controller} chart - The chart instance.\n\t * @param {Object} options - The plugin options.\n\t * @returns {Boolean} `false` to cancel the chart layout.\n\t */\n\t/**\n\t * @method IPlugin#afterLayout\n\t * @desc Called after the `chart` has been layed out. Note that this hook will not\n\t * be called if the layout update has been previously cancelled.\n\t * @param {Chart.Controller} chart - The chart instance.\n\t * @param {Object} options - The plugin options.\n\t */\n\t/**\n\t * @method IPlugin#beforeRender\n\t * @desc Called before rendering `chart`. If any plugin returns `false`,\n\t * the rendering is cancelled until another `render` is triggered.\n\t * @param {Chart.Controller} chart - The chart instance.\n\t * @param {Object} options - The plugin options.\n\t * @returns {Boolean} `false` to cancel the chart rendering.\n\t */\n\t/**\n\t * @method IPlugin#afterRender\n\t * @desc Called after the `chart` has been fully rendered (and animation completed). Note\n\t * that this hook will not be called if the rendering has been previously cancelled.\n\t * @param {Chart.Controller} chart - The chart instance.\n\t * @param {Object} options - The plugin options.\n\t */\n\t/**\n\t * @method IPlugin#beforeDraw\n\t * @desc Called before drawing `chart` at every animation frame specified by the given\n\t * easing value. If any plugin returns `false`, the frame drawing is cancelled until\n\t * another `render` is triggered.\n\t * @param {Chart.Controller} chart - The chart instance.\n\t * @param {Number} easingValue - The current animation value, between 0.0 and 1.0.\n\t * @param {Object} options - The plugin options.\n\t * @returns {Boolean} `false` to cancel the chart drawing.\n\t */\n\t/**\n\t * @method IPlugin#afterDraw\n\t * @desc Called after the `chart` has been drawn for the specific easing value. Note\n\t * that this hook will not be called if the drawing has been previously cancelled.\n\t * @param {Chart.Controller} chart - The chart instance.\n\t * @param {Number} easingValue - The current animation value, between 0.0 and 1.0.\n\t * @param {Object} options - The plugin options.\n\t */\n\t/**\n\t * @method IPlugin#beforeDatasetsDraw\n \t * @desc Called before drawing the `chart` datasets. If any plugin returns `false`,\n\t * the datasets drawing is cancelled until another `render` is triggered.\n\t * @param {Chart.Controller} chart - The chart instance.\n\t * @param {Number} easingValue - The current animation value, between 0.0 and 1.0.\n\t * @param {Object} options - The plugin options.\n\t * @returns {Boolean} `false` to cancel the chart datasets drawing.\n\t */\n\t/**\n\t * @method IPlugin#afterDatasetsDraw\n\t * @desc Called after the `chart` datasets have been drawn. Note that this hook\n\t * will not be called if the datasets drawing has been previously cancelled.\n\t * @param {Chart.Controller} chart - The chart instance.\n\t * @param {Number} easingValue - The current animation value, between 0.0 and 1.0.\n\t * @param {Object} options - The plugin options.\n\t */\n\t/**\n\t * @method IPlugin#beforeDatasetDraw\n \t * @desc Called before drawing the `chart` dataset at the given `args.index` (datasets\n\t * are drawn in the reverse order). If any plugin returns `false`, the datasets drawing\n\t * is cancelled until another `render` is triggered.\n\t * @param {Chart} chart - The chart instance.\n\t * @param {Object} args - The call arguments.\n\t * @param {Object} args.index - The dataset index.\n\t * @param {Number} args.meta - The dataset metadata.\n\t * @param {Number} args.easingValue - The current animation value, between 0.0 and 1.0.\n\t * @param {Object} options - The plugin options.\n\t * @returns {Boolean} `false` to cancel the chart datasets drawing.\n\t */\n\t/**\n\t * @method IPlugin#afterDatasetDraw\n \t * @desc Called after the `chart` datasets at the given `args.index` have been drawn\n\t * (datasets are drawn in the reverse order). Note that this hook will not be called\n\t * if the datasets drawing has been previously cancelled.\n\t * @param {Chart} chart - The chart instance.\n\t * @param {Object} args - The call arguments.\n\t * @param {Object} args.index - The dataset index.\n\t * @param {Number} args.meta - The dataset metadata.\n\t * @param {Number} args.easingValue - The current animation value, between 0.0 and 1.0.\n\t * @param {Object} options - The plugin options.\n\t */\n\t/**\n\t * @method IPlugin#beforeEvent\n \t * @desc Called before processing the specified `event`. If any plugin returns `false`,\n\t * the event will be discarded.\n\t * @param {Chart.Controller} chart - The chart instance.\n\t * @param {IEvent} event - The event object.\n\t * @param {Object} options - The plugin options.\n\t */\n\t/**\n\t * @method IPlugin#afterEvent\n\t * @desc Called after the `event` has been consumed. Note that this hook\n\t * will not be called if the `event` has been previously discarded.\n\t * @param {Chart.Controller} chart - The chart instance.\n\t * @param {IEvent} event - The event object.\n\t * @param {Object} options - The plugin options.\n\t */\n\t/**\n\t * @method IPlugin#resize\n\t * @desc Called after the chart as been resized.\n\t * @param {Chart.Controller} chart - The chart instance.\n\t * @param {Number} size - The new canvas display size (eq. canvas.style width & height).\n\t * @param {Object} options - The plugin options.\n\t */\n\t/**\n\t * @method IPlugin#destroy\n\t * @desc Called after the chart as been destroyed.\n\t * @param {Chart.Controller} chart - The chart instance.\n\t * @param {Object} options - The plugin options.\n\t */\n\n\t/**\n\t * Provided for backward compatibility, use Chart.plugins instead\n\t * @namespace Chart.pluginService\n\t * @deprecated since version 2.1.5\n\t * @todo remove at version 3\n\t * @private\n\t */\n\tChart.pluginService = Chart.plugins;\n\n\t/**\n\t * Provided for backward compatibility, inheriting from Chart.PlugingBase has no\n\t * effect, instead simply create/register plugins via plain JavaScript objects.\n\t * @interface Chart.PluginBase\n\t * @deprecated since version 2.5.0\n\t * @todo remove at version 3\n\t * @private\n\t */\n\tChart.PluginBase = Chart.Element.extend({});\n};\n\n},{}],31:[function(require,module,exports){\n'use strict';\n\nmodule.exports = function(Chart) {\n\n\tvar helpers = Chart.helpers;\n\n\tChart.defaults.scale = {\n\t\tdisplay: true,\n\t\tposition: 'left',\n\n\t\t// grid line settings\n\t\tgridLines: {\n\t\t\tdisplay: true,\n\t\t\tcolor: 'rgba(0, 0, 0, 0.1)',\n\t\t\tlineWidth: 1,\n\t\t\tdrawBorder: true,\n\t\t\tdrawOnChartArea: true,\n\t\t\tdrawTicks: true,\n\t\t\ttickMarkLength: 10,\n\t\t\tzeroLineWidth: 1,\n\t\t\tzeroLineColor: 'rgba(0,0,0,0.25)',\n\t\t\tzeroLineBorderDash: [],\n\t\t\tzeroLineBorderDashOffset: 0.0,\n\t\t\toffsetGridLines: false,\n\t\t\tborderDash: [],\n\t\t\tborderDashOffset: 0.0\n\t\t},\n\n\t\t// scale label\n\t\tscaleLabel: {\n\t\t\t// actual label\n\t\t\tlabelString: '',\n\n\t\t\t// display property\n\t\t\tdisplay: false\n\t\t},\n\n\t\t// label settings\n\t\tticks: {\n\t\t\tbeginAtZero: false,\n\t\t\tminRotation: 0,\n\t\t\tmaxRotation: 50,\n\t\t\tmirror: false,\n\t\t\tpadding: 0,\n\t\t\treverse: false,\n\t\t\tdisplay: true,\n\t\t\tautoSkip: true,\n\t\t\tautoSkipPadding: 0,\n\t\t\tlabelOffset: 0,\n\t\t\t// We pass through arrays to be rendered as multiline labels, we convert Others to strings here.\n\t\t\tcallback: Chart.Ticks.formatters.values\n\t\t}\n\t};\n\n\tfunction computeTextSize(context, tick, font) {\n\t\treturn helpers.isArray(tick) ?\n\t\t\thelpers.longestText(context, font, tick) :\n\t\t\tcontext.measureText(tick).width;\n\t}\n\n\tfunction parseFontOptions(options) {\n\t\tvar getValueOrDefault = helpers.getValueOrDefault;\n\t\tvar globalDefaults = Chart.defaults.global;\n\t\tvar size = getValueOrDefault(options.fontSize, globalDefaults.defaultFontSize);\n\t\tvar style = getValueOrDefault(options.fontStyle, globalDefaults.defaultFontStyle);\n\t\tvar family = getValueOrDefault(options.fontFamily, globalDefaults.defaultFontFamily);\n\n\t\treturn {\n\t\t\tsize: size,\n\t\t\tstyle: style,\n\t\t\tfamily: family,\n\t\t\tfont: helpers.fontString(size, style, family)\n\t\t};\n\t}\n\n\tChart.Scale = Chart.Element.extend({\n\t\t/**\n\t\t * Get the padding needed for the scale\n\t\t * @method getPadding\n\t\t * @private\n\t\t * @returns {Padding} the necessary padding\n\t\t */\n\t\tgetPadding: function() {\n\t\t\tvar me = this;\n\t\t\treturn {\n\t\t\t\tleft: me.paddingLeft || 0,\n\t\t\t\ttop: me.paddingTop || 0,\n\t\t\t\tright: me.paddingRight || 0,\n\t\t\t\tbottom: me.paddingBottom || 0\n\t\t\t};\n\t\t},\n\n\t\t// These methods are ordered by lifecyle. Utilities then follow.\n\t\t// Any function defined here is inherited by all scale types.\n\t\t// Any function can be extended by the scale type\n\n\t\tbeforeUpdate: function() {\n\t\t\thelpers.callback(this.options.beforeUpdate, [this]);\n\t\t},\n\t\tupdate: function(maxWidth, maxHeight, margins) {\n\t\t\tvar me = this;\n\n\t\t\t// Update Lifecycle - Probably don't want to ever extend or overwrite this function ;)\n\t\t\tme.beforeUpdate();\n\n\t\t\t// Absorb the master measurements\n\t\t\tme.maxWidth = maxWidth;\n\t\t\tme.maxHeight = maxHeight;\n\t\t\tme.margins = helpers.extend({\n\t\t\t\tleft: 0,\n\t\t\t\tright: 0,\n\t\t\t\ttop: 0,\n\t\t\t\tbottom: 0\n\t\t\t}, margins);\n\t\t\tme.longestTextCache = me.longestTextCache || {};\n\n\t\t\t// Dimensions\n\t\t\tme.beforeSetDimensions();\n\t\t\tme.setDimensions();\n\t\t\tme.afterSetDimensions();\n\n\t\t\t// Data min/max\n\t\t\tme.beforeDataLimits();\n\t\t\tme.determineDataLimits();\n\t\t\tme.afterDataLimits();\n\n\t\t\t// Ticks\n\t\t\tme.beforeBuildTicks();\n\t\t\tme.buildTicks();\n\t\t\tme.afterBuildTicks();\n\n\t\t\tme.beforeTickToLabelConversion();\n\t\t\tme.convertTicksToLabels();\n\t\t\tme.afterTickToLabelConversion();\n\n\t\t\t// Tick Rotation\n\t\t\tme.beforeCalculateTickRotation();\n\t\t\tme.calculateTickRotation();\n\t\t\tme.afterCalculateTickRotation();\n\t\t\t// Fit\n\t\t\tme.beforeFit();\n\t\t\tme.fit();\n\t\t\tme.afterFit();\n\t\t\t//\n\t\t\tme.afterUpdate();\n\n\t\t\treturn me.minSize;\n\n\t\t},\n\t\tafterUpdate: function() {\n\t\t\thelpers.callback(this.options.afterUpdate, [this]);\n\t\t},\n\n\t\t//\n\n\t\tbeforeSetDimensions: function() {\n\t\t\thelpers.callback(this.options.beforeSetDimensions, [this]);\n\t\t},\n\t\tsetDimensions: function() {\n\t\t\tvar me = this;\n\t\t\t// Set the unconstrained dimension before label rotation\n\t\t\tif (me.isHorizontal()) {\n\t\t\t\t// Reset position before calculating rotation\n\t\t\t\tme.width = me.maxWidth;\n\t\t\t\tme.left = 0;\n\t\t\t\tme.right = me.width;\n\t\t\t} else {\n\t\t\t\tme.height = me.maxHeight;\n\n\t\t\t\t// Reset position before calculating rotation\n\t\t\t\tme.top = 0;\n\t\t\t\tme.bottom = me.height;\n\t\t\t}\n\n\t\t\t// Reset padding\n\t\t\tme.paddingLeft = 0;\n\t\t\tme.paddingTop = 0;\n\t\t\tme.paddingRight = 0;\n\t\t\tme.paddingBottom = 0;\n\t\t},\n\t\tafterSetDimensions: function() {\n\t\t\thelpers.callback(this.options.afterSetDimensions, [this]);\n\t\t},\n\n\t\t// Data limits\n\t\tbeforeDataLimits: function() {\n\t\t\thelpers.callback(this.options.beforeDataLimits, [this]);\n\t\t},\n\t\tdetermineDataLimits: helpers.noop,\n\t\tafterDataLimits: function() {\n\t\t\thelpers.callback(this.options.afterDataLimits, [this]);\n\t\t},\n\n\t\t//\n\t\tbeforeBuildTicks: function() {\n\t\t\thelpers.callback(this.options.beforeBuildTicks, [this]);\n\t\t},\n\t\tbuildTicks: helpers.noop,\n\t\tafterBuildTicks: function() {\n\t\t\thelpers.callback(this.options.afterBuildTicks, [this]);\n\t\t},\n\n\t\tbeforeTickToLabelConversion: function() {\n\t\t\thelpers.callback(this.options.beforeTickToLabelConversion, [this]);\n\t\t},\n\t\tconvertTicksToLabels: function() {\n\t\t\tvar me = this;\n\t\t\t// Convert ticks to strings\n\t\t\tvar tickOpts = me.options.ticks;\n\t\t\tme.ticks = me.ticks.map(tickOpts.userCallback || tickOpts.callback);\n\t\t},\n\t\tafterTickToLabelConversion: function() {\n\t\t\thelpers.callback(this.options.afterTickToLabelConversion, [this]);\n\t\t},\n\n\t\t//\n\n\t\tbeforeCalculateTickRotation: function() {\n\t\t\thelpers.callback(this.options.beforeCalculateTickRotation, [this]);\n\t\t},\n\t\tcalculateTickRotation: function() {\n\t\t\tvar me = this;\n\t\t\tvar context = me.ctx;\n\t\t\tvar tickOpts = me.options.ticks;\n\n\t\t\t// Get the width of each grid by calculating the difference\n\t\t\t// between x offsets between 0 and 1.\n\t\t\tvar tickFont = parseFontOptions(tickOpts);\n\t\t\tcontext.font = tickFont.font;\n\n\t\t\tvar labelRotation = tickOpts.minRotation || 0;\n\n\t\t\tif (me.options.display && me.isHorizontal()) {\n\t\t\t\tvar originalLabelWidth = helpers.longestText(context, tickFont.font, me.ticks, me.longestTextCache);\n\t\t\t\tvar labelWidth = originalLabelWidth;\n\t\t\t\tvar cosRotation;\n\t\t\t\tvar sinRotation;\n\n\t\t\t\t// Allow 3 pixels x2 padding either side for label readability\n\t\t\t\tvar tickWidth = me.getPixelForTick(1) - me.getPixelForTick(0) - 6;\n\n\t\t\t\t// Max label rotation can be set or default to 90 - also act as a loop counter\n\t\t\t\twhile (labelWidth > tickWidth && labelRotation < tickOpts.maxRotation) {\n\t\t\t\t\tvar angleRadians = helpers.toRadians(labelRotation);\n\t\t\t\t\tcosRotation = Math.cos(angleRadians);\n\t\t\t\t\tsinRotation = Math.sin(angleRadians);\n\n\t\t\t\t\tif (sinRotation * originalLabelWidth > me.maxHeight) {\n\t\t\t\t\t\t// go back one step\n\t\t\t\t\t\tlabelRotation--;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\n\t\t\t\t\tlabelRotation++;\n\t\t\t\t\tlabelWidth = cosRotation * originalLabelWidth;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tme.labelRotation = labelRotation;\n\t\t},\n\t\tafterCalculateTickRotation: function() {\n\t\t\thelpers.callback(this.options.afterCalculateTickRotation, [this]);\n\t\t},\n\n\t\t//\n\n\t\tbeforeFit: function() {\n\t\t\thelpers.callback(this.options.beforeFit, [this]);\n\t\t},\n\t\tfit: function() {\n\t\t\tvar me = this;\n\t\t\t// Reset\n\t\t\tvar minSize = me.minSize = {\n\t\t\t\twidth: 0,\n\t\t\t\theight: 0\n\t\t\t};\n\n\t\t\tvar opts = me.options;\n\t\t\tvar tickOpts = opts.ticks;\n\t\t\tvar scaleLabelOpts = opts.scaleLabel;\n\t\t\tvar gridLineOpts = opts.gridLines;\n\t\t\tvar display = opts.display;\n\t\t\tvar isHorizontal = me.isHorizontal();\n\n\t\t\tvar tickFont = parseFontOptions(tickOpts);\n\t\t\tvar scaleLabelFontSize = parseFontOptions(scaleLabelOpts).size * 1.5;\n\t\t\tvar tickMarkLength = opts.gridLines.tickMarkLength;\n\n\t\t\t// Width\n\t\t\tif (isHorizontal) {\n\t\t\t\t// subtract the margins to line up with the chartArea if we are a full width scale\n\t\t\t\tminSize.width = me.isFullWidth() ? me.maxWidth - me.margins.left - me.margins.right : me.maxWidth;\n\t\t\t} else {\n\t\t\t\tminSize.width = display && gridLineOpts.drawTicks ? tickMarkLength : 0;\n\t\t\t}\n\n\t\t\t// height\n\t\t\tif (isHorizontal) {\n\t\t\t\tminSize.height = display && gridLineOpts.drawTicks ? tickMarkLength : 0;\n\t\t\t} else {\n\t\t\t\tminSize.height = me.maxHeight; // fill all the height\n\t\t\t}\n\n\t\t\t// Are we showing a title for the scale?\n\t\t\tif (scaleLabelOpts.display && display) {\n\t\t\t\tif (isHorizontal) {\n\t\t\t\t\tminSize.height += scaleLabelFontSize;\n\t\t\t\t} else {\n\t\t\t\t\tminSize.width += scaleLabelFontSize;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Don't bother fitting the ticks if we are not showing them\n\t\t\tif (tickOpts.display && display) {\n\t\t\t\tvar largestTextWidth = helpers.longestText(me.ctx, tickFont.font, me.ticks, me.longestTextCache);\n\t\t\t\tvar tallestLabelHeightInLines = helpers.numberOfLabelLines(me.ticks);\n\t\t\t\tvar lineSpace = tickFont.size * 0.5;\n\n\t\t\t\tif (isHorizontal) {\n\t\t\t\t\t// A horizontal axis is more constrained by the height.\n\t\t\t\t\tme.longestLabelWidth = largestTextWidth;\n\n\t\t\t\t\tvar angleRadians = helpers.toRadians(me.labelRotation);\n\t\t\t\t\tvar cosRotation = Math.cos(angleRadians);\n\t\t\t\t\tvar sinRotation = Math.sin(angleRadians);\n\n\t\t\t\t\t// TODO - improve this calculation\n\t\t\t\t\tvar labelHeight = (sinRotation * largestTextWidth)\n\t\t\t\t\t\t+ (tickFont.size * tallestLabelHeightInLines)\n\t\t\t\t\t\t+ (lineSpace * tallestLabelHeightInLines);\n\n\t\t\t\t\tminSize.height = Math.min(me.maxHeight, minSize.height + labelHeight);\n\t\t\t\t\tme.ctx.font = tickFont.font;\n\n\t\t\t\t\tvar firstTick = me.ticks[0];\n\t\t\t\t\tvar firstLabelWidth = computeTextSize(me.ctx, firstTick, tickFont.font);\n\n\t\t\t\t\tvar lastTick = me.ticks[me.ticks.length - 1];\n\t\t\t\t\tvar lastLabelWidth = computeTextSize(me.ctx, lastTick, tickFont.font);\n\n\t\t\t\t\t// Ensure that our ticks are always inside the canvas. When rotated, ticks are right aligned which means that the right padding is dominated\n\t\t\t\t\t// by the font height\n\t\t\t\t\tif (me.labelRotation !== 0) {\n\t\t\t\t\t\tme.paddingLeft = opts.position === 'bottom'? (cosRotation * firstLabelWidth) + 3: (cosRotation * lineSpace) + 3; // add 3 px to move away from canvas edges\n\t\t\t\t\t\tme.paddingRight = opts.position === 'bottom'? (cosRotation * lineSpace) + 3: (cosRotation * lastLabelWidth) + 3;\n\t\t\t\t\t} else {\n\t\t\t\t\t\tme.paddingLeft = firstLabelWidth / 2 + 3; // add 3 px to move away from canvas edges\n\t\t\t\t\t\tme.paddingRight = lastLabelWidth / 2 + 3;\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\t// A vertical axis is more constrained by the width. Labels are the dominant factor here, so get that length first\n\t\t\t\t\t// Account for padding\n\n\t\t\t\t\tif (tickOpts.mirror) {\n\t\t\t\t\t\tlargestTextWidth = 0;\n\t\t\t\t\t} else {\n\t\t\t\t\t\tlargestTextWidth += me.options.ticks.padding;\n\t\t\t\t\t}\n\t\t\t\t\tminSize.width = Math.min(me.maxWidth, minSize.width + largestTextWidth);\n\t\t\t\t\tme.paddingTop = tickFont.size / 2;\n\t\t\t\t\tme.paddingBottom = tickFont.size / 2;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tme.handleMargins();\n\n\t\t\tme.width = minSize.width;\n\t\t\tme.height = minSize.height;\n\t\t},\n\n\t\t/**\n\t\t * Handle margins and padding interactions\n\t\t * @private\n\t\t */\n\t\thandleMargins: function() {\n\t\t\tvar me = this;\n\t\t\tif (me.margins) {\n\t\t\t\tme.paddingLeft = Math.max(me.paddingLeft - me.margins.left, 0);\n\t\t\t\tme.paddingTop = Math.max(me.paddingTop - me.margins.top, 0);\n\t\t\t\tme.paddingRight = Math.max(me.paddingRight - me.margins.right, 0);\n\t\t\t\tme.paddingBottom = Math.max(me.paddingBottom - me.margins.bottom, 0);\n\t\t\t}\n\t\t},\n\n\t\tafterFit: function() {\n\t\t\thelpers.callback(this.options.afterFit, [this]);\n\t\t},\n\n\t\t// Shared Methods\n\t\tisHorizontal: function() {\n\t\t\treturn this.options.position === 'top' || this.options.position === 'bottom';\n\t\t},\n\t\tisFullWidth: function() {\n\t\t\treturn (this.options.fullWidth);\n\t\t},\n\n\t\t// Get the correct value. NaN bad inputs, If the value type is object get the x or y based on whether we are horizontal or not\n\t\tgetRightValue: function(rawValue) {\n\t\t\t// Null and undefined values first\n\t\t\tif (rawValue === null || typeof(rawValue) === 'undefined') {\n\t\t\t\treturn NaN;\n\t\t\t}\n\t\t\t// isNaN(object) returns true, so make sure NaN is checking for a number; Discard Infinite values\n\t\t\tif (typeof(rawValue) === 'number' && !isFinite(rawValue)) {\n\t\t\t\treturn NaN;\n\t\t\t}\n\t\t\t// If it is in fact an object, dive in one more level\n\t\t\tif (typeof(rawValue) === 'object') {\n\t\t\t\tif ((rawValue instanceof Date) || (rawValue.isValid)) {\n\t\t\t\t\treturn rawValue;\n\t\t\t\t}\n\t\t\t\treturn this.getRightValue(this.isHorizontal() ? rawValue.x : rawValue.y);\n\t\t\t}\n\n\t\t\t// Value is good, return it\n\t\t\treturn rawValue;\n\t\t},\n\n\t\t// Used to get the value to display in the tooltip for the data at the given index\n\t\t// function getLabelForIndex(index, datasetIndex)\n\t\tgetLabelForIndex: helpers.noop,\n\n\t\t// Used to get data value locations.  Value can either be an index or a numerical value\n\t\tgetPixelForValue: helpers.noop,\n\n\t\t// Used to get the data value from a given pixel. This is the inverse of getPixelForValue\n\t\tgetValueForPixel: helpers.noop,\n\n\t\t// Used for tick location, should\n\t\tgetPixelForTick: function(index, includeOffset) {\n\t\t\tvar me = this;\n\t\t\tif (me.isHorizontal()) {\n\t\t\t\tvar innerWidth = me.width - (me.paddingLeft + me.paddingRight);\n\t\t\t\tvar tickWidth = innerWidth / Math.max((me.ticks.length - ((me.options.gridLines.offsetGridLines) ? 0 : 1)), 1);\n\t\t\t\tvar pixel = (tickWidth * index) + me.paddingLeft;\n\n\t\t\t\tif (includeOffset) {\n\t\t\t\t\tpixel += tickWidth / 2;\n\t\t\t\t}\n\n\t\t\t\tvar finalVal = me.left + Math.round(pixel);\n\t\t\t\tfinalVal += me.isFullWidth() ? me.margins.left : 0;\n\t\t\t\treturn finalVal;\n\t\t\t}\n\t\t\tvar innerHeight = me.height - (me.paddingTop + me.paddingBottom);\n\t\t\treturn me.top + (index * (innerHeight / (me.ticks.length - 1)));\n\t\t},\n\n\t\t// Utility for getting the pixel location of a percentage of scale\n\t\tgetPixelForDecimal: function(decimal /* , includeOffset*/) {\n\t\t\tvar me = this;\n\t\t\tif (me.isHorizontal()) {\n\t\t\t\tvar innerWidth = me.width - (me.paddingLeft + me.paddingRight);\n\t\t\t\tvar valueOffset = (innerWidth * decimal) + me.paddingLeft;\n\n\t\t\t\tvar finalVal = me.left + Math.round(valueOffset);\n\t\t\t\tfinalVal += me.isFullWidth() ? me.margins.left : 0;\n\t\t\t\treturn finalVal;\n\t\t\t}\n\t\t\treturn me.top + (decimal * me.height);\n\t\t},\n\n\t\tgetBasePixel: function() {\n\t\t\treturn this.getPixelForValue(this.getBaseValue());\n\t\t},\n\n\t\tgetBaseValue: function() {\n\t\t\tvar me = this;\n\t\t\tvar min = me.min;\n\t\t\tvar max = me.max;\n\n\t\t\treturn me.beginAtZero ? 0:\n\t\t\t\tmin < 0 && max < 0? max :\n\t\t\t\tmin > 0 && max > 0? min :\n\t\t\t\t0;\n\t\t},\n\n\t\t// Actually draw the scale on the canvas\n\t\t// @param {rectangle} chartArea : the area of the chart to draw full grid lines on\n\t\tdraw: function(chartArea) {\n\t\t\tvar me = this;\n\t\t\tvar options = me.options;\n\t\t\tif (!options.display) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tvar context = me.ctx;\n\t\t\tvar globalDefaults = Chart.defaults.global;\n\t\t\tvar optionTicks = options.ticks;\n\t\t\tvar gridLines = options.gridLines;\n\t\t\tvar scaleLabel = options.scaleLabel;\n\n\t\t\tvar isRotated = me.labelRotation !== 0;\n\t\t\tvar skipRatio;\n\t\t\tvar useAutoskipper = optionTicks.autoSkip;\n\t\t\tvar isHorizontal = me.isHorizontal();\n\n\t\t\t// figure out the maximum number of gridlines to show\n\t\t\tvar maxTicks;\n\t\t\tif (optionTicks.maxTicksLimit) {\n\t\t\t\tmaxTicks = optionTicks.maxTicksLimit;\n\t\t\t}\n\n\t\t\tvar tickFontColor = helpers.getValueOrDefault(optionTicks.fontColor, globalDefaults.defaultFontColor);\n\t\t\tvar tickFont = parseFontOptions(optionTicks);\n\n\t\t\tvar tl = gridLines.drawTicks ? gridLines.tickMarkLength : 0;\n\n\t\t\tvar scaleLabelFontColor = helpers.getValueOrDefault(scaleLabel.fontColor, globalDefaults.defaultFontColor);\n\t\t\tvar scaleLabelFont = parseFontOptions(scaleLabel);\n\n\t\t\tvar labelRotationRadians = helpers.toRadians(me.labelRotation);\n\t\t\tvar cosRotation = Math.cos(labelRotationRadians);\n\t\t\tvar longestRotatedLabel = me.longestLabelWidth * cosRotation;\n\n\t\t\t// Make sure we draw text in the correct color and font\n\t\t\tcontext.fillStyle = tickFontColor;\n\n\t\t\tvar itemsToDraw = [];\n\n\t\t\tif (isHorizontal) {\n\t\t\t\tskipRatio = false;\n\n\t\t\t\tif ((longestRotatedLabel + optionTicks.autoSkipPadding) * me.ticks.length > (me.width - (me.paddingLeft + me.paddingRight))) {\n\t\t\t\t\tskipRatio = 1 + Math.floor(((longestRotatedLabel + optionTicks.autoSkipPadding) * me.ticks.length) / (me.width - (me.paddingLeft + me.paddingRight)));\n\t\t\t\t}\n\n\t\t\t\t// if they defined a max number of optionTicks,\n\t\t\t\t// increase skipRatio until that number is met\n\t\t\t\tif (maxTicks && me.ticks.length > maxTicks) {\n\t\t\t\t\twhile (!skipRatio || me.ticks.length / (skipRatio || 1) > maxTicks) {\n\t\t\t\t\t\tif (!skipRatio) {\n\t\t\t\t\t\t\tskipRatio = 1;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tskipRatio += 1;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif (!useAutoskipper) {\n\t\t\t\t\tskipRatio = false;\n\t\t\t\t}\n\t\t\t}\n\n\n\t\t\tvar xTickStart = options.position === 'right' ? me.left : me.right - tl;\n\t\t\tvar xTickEnd = options.position === 'right' ? me.left + tl : me.right;\n\t\t\tvar yTickStart = options.position === 'bottom' ? me.top : me.bottom - tl;\n\t\t\tvar yTickEnd = options.position === 'bottom' ? me.top + tl : me.bottom;\n\n\t\t\thelpers.each(me.ticks, function(label, index) {\n\t\t\t\t// If the callback returned a null or undefined value, do not draw this line\n\t\t\t\tif (label === undefined || label === null) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tvar isLastTick = me.ticks.length === index + 1;\n\n\t\t\t\t// Since we always show the last tick,we need may need to hide the last shown one before\n\t\t\t\tvar shouldSkip = (skipRatio > 1 && index % skipRatio > 0) || (index % skipRatio === 0 && index + skipRatio >= me.ticks.length);\n\t\t\t\tif (shouldSkip && !isLastTick || (label === undefined || label === null)) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tvar lineWidth, lineColor, borderDash, borderDashOffset;\n\t\t\t\tif (index === (typeof me.zeroLineIndex !== 'undefined' ? me.zeroLineIndex : 0)) {\n\t\t\t\t\t// Draw the first index specially\n\t\t\t\t\tlineWidth = gridLines.zeroLineWidth;\n\t\t\t\t\tlineColor = gridLines.zeroLineColor;\n\t\t\t\t\tborderDash = gridLines.zeroLineBorderDash;\n\t\t\t\t\tborderDashOffset = gridLines.zeroLineBorderDashOffset;\n\t\t\t\t} else {\n\t\t\t\t\tlineWidth = helpers.getValueAtIndexOrDefault(gridLines.lineWidth, index);\n\t\t\t\t\tlineColor = helpers.getValueAtIndexOrDefault(gridLines.color, index);\n\t\t\t\t\tborderDash = helpers.getValueOrDefault(gridLines.borderDash, globalDefaults.borderDash);\n\t\t\t\t\tborderDashOffset = helpers.getValueOrDefault(gridLines.borderDashOffset, globalDefaults.borderDashOffset);\n\t\t\t\t}\n\n\t\t\t\t// Common properties\n\t\t\t\tvar tx1, ty1, tx2, ty2, x1, y1, x2, y2, labelX, labelY;\n\t\t\t\tvar textAlign = 'middle';\n\t\t\t\tvar textBaseline = 'middle';\n\n\t\t\t\tif (isHorizontal) {\n\n\t\t\t\t\tif (options.position === 'bottom') {\n\t\t\t\t\t\t// bottom\n\t\t\t\t\t\ttextBaseline = !isRotated? 'top':'middle';\n\t\t\t\t\t\ttextAlign = !isRotated? 'center': 'right';\n\t\t\t\t\t\tlabelY = me.top + tl;\n\t\t\t\t\t} else {\n\t\t\t\t\t\t// top\n\t\t\t\t\t\ttextBaseline = !isRotated? 'bottom':'middle';\n\t\t\t\t\t\ttextAlign = !isRotated? 'center': 'left';\n\t\t\t\t\t\tlabelY = me.bottom - tl;\n\t\t\t\t\t}\n\n\t\t\t\t\tvar xLineValue = me.getPixelForTick(index) + helpers.aliasPixel(lineWidth); // xvalues for grid lines\n\t\t\t\t\tlabelX = me.getPixelForTick(index, gridLines.offsetGridLines) + optionTicks.labelOffset; // x values for optionTicks (need to consider offsetLabel option)\n\n\t\t\t\t\ttx1 = tx2 = x1 = x2 = xLineValue;\n\t\t\t\t\tty1 = yTickStart;\n\t\t\t\t\tty2 = yTickEnd;\n\t\t\t\t\ty1 = chartArea.top;\n\t\t\t\t\ty2 = chartArea.bottom;\n\t\t\t\t} else {\n\t\t\t\t\tvar isLeft = options.position === 'left';\n\t\t\t\t\tvar tickPadding = optionTicks.padding;\n\t\t\t\t\tvar labelXOffset;\n\n\t\t\t\t\tif (optionTicks.mirror) {\n\t\t\t\t\t\ttextAlign = isLeft ? 'left' : 'right';\n\t\t\t\t\t\tlabelXOffset = tickPadding;\n\t\t\t\t\t} else {\n\t\t\t\t\t\ttextAlign = isLeft ? 'right' : 'left';\n\t\t\t\t\t\tlabelXOffset = tl + tickPadding;\n\t\t\t\t\t}\n\n\t\t\t\t\tlabelX = isLeft ? me.right - labelXOffset : me.left + labelXOffset;\n\n\t\t\t\t\tvar yLineValue = me.getPixelForTick(index); // xvalues for grid lines\n\t\t\t\t\tyLineValue += helpers.aliasPixel(lineWidth);\n\t\t\t\t\tlabelY = me.getPixelForTick(index, gridLines.offsetGridLines);\n\n\t\t\t\t\ttx1 = xTickStart;\n\t\t\t\t\ttx2 = xTickEnd;\n\t\t\t\t\tx1 = chartArea.left;\n\t\t\t\t\tx2 = chartArea.right;\n\t\t\t\t\tty1 = ty2 = y1 = y2 = yLineValue;\n\t\t\t\t}\n\n\t\t\t\titemsToDraw.push({\n\t\t\t\t\ttx1: tx1,\n\t\t\t\t\tty1: ty1,\n\t\t\t\t\ttx2: tx2,\n\t\t\t\t\tty2: ty2,\n\t\t\t\t\tx1: x1,\n\t\t\t\t\ty1: y1,\n\t\t\t\t\tx2: x2,\n\t\t\t\t\ty2: y2,\n\t\t\t\t\tlabelX: labelX,\n\t\t\t\t\tlabelY: labelY,\n\t\t\t\t\tglWidth: lineWidth,\n\t\t\t\t\tglColor: lineColor,\n\t\t\t\t\tglBorderDash: borderDash,\n\t\t\t\t\tglBorderDashOffset: borderDashOffset,\n\t\t\t\t\trotation: -1 * labelRotationRadians,\n\t\t\t\t\tlabel: label,\n\t\t\t\t\ttextBaseline: textBaseline,\n\t\t\t\t\ttextAlign: textAlign\n\t\t\t\t});\n\t\t\t});\n\n\t\t\t// Draw all of the tick labels, tick marks, and grid lines at the correct places\n\t\t\thelpers.each(itemsToDraw, function(itemToDraw) {\n\t\t\t\tif (gridLines.display) {\n\t\t\t\t\tcontext.save();\n\t\t\t\t\tcontext.lineWidth = itemToDraw.glWidth;\n\t\t\t\t\tcontext.strokeStyle = itemToDraw.glColor;\n\t\t\t\t\tif (context.setLineDash) {\n\t\t\t\t\t\tcontext.setLineDash(itemToDraw.glBorderDash);\n\t\t\t\t\t\tcontext.lineDashOffset = itemToDraw.glBorderDashOffset;\n\t\t\t\t\t}\n\n\t\t\t\t\tcontext.beginPath();\n\n\t\t\t\t\tif (gridLines.drawTicks) {\n\t\t\t\t\t\tcontext.moveTo(itemToDraw.tx1, itemToDraw.ty1);\n\t\t\t\t\t\tcontext.lineTo(itemToDraw.tx2, itemToDraw.ty2);\n\t\t\t\t\t}\n\n\t\t\t\t\tif (gridLines.drawOnChartArea) {\n\t\t\t\t\t\tcontext.moveTo(itemToDraw.x1, itemToDraw.y1);\n\t\t\t\t\t\tcontext.lineTo(itemToDraw.x2, itemToDraw.y2);\n\t\t\t\t\t}\n\n\t\t\t\t\tcontext.stroke();\n\t\t\t\t\tcontext.restore();\n\t\t\t\t}\n\n\t\t\t\tif (optionTicks.display) {\n\t\t\t\t\tcontext.save();\n\t\t\t\t\tcontext.translate(itemToDraw.labelX, itemToDraw.labelY);\n\t\t\t\t\tcontext.rotate(itemToDraw.rotation);\n\t\t\t\t\tcontext.font = tickFont.font;\n\t\t\t\t\tcontext.textBaseline = itemToDraw.textBaseline;\n\t\t\t\t\tcontext.textAlign = itemToDraw.textAlign;\n\n\t\t\t\t\tvar label = itemToDraw.label;\n\t\t\t\t\tif (helpers.isArray(label)) {\n\t\t\t\t\t\tfor (var i = 0, y = 0; i < label.length; ++i) {\n\t\t\t\t\t\t\t// We just make sure the multiline element is a string here..\n\t\t\t\t\t\t\tcontext.fillText('' + label[i], 0, y);\n\t\t\t\t\t\t\t// apply same lineSpacing as calculated @ L#320\n\t\t\t\t\t\t\ty += (tickFont.size * 1.5);\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\tcontext.fillText(label, 0, 0);\n\t\t\t\t\t}\n\t\t\t\t\tcontext.restore();\n\t\t\t\t}\n\t\t\t});\n\n\t\t\tif (scaleLabel.display) {\n\t\t\t\t// Draw the scale label\n\t\t\t\tvar scaleLabelX;\n\t\t\t\tvar scaleLabelY;\n\t\t\t\tvar rotation = 0;\n\n\t\t\t\tif (isHorizontal) {\n\t\t\t\t\tscaleLabelX = me.left + ((me.right - me.left) / 2); // midpoint of the width\n\t\t\t\t\tscaleLabelY = options.position === 'bottom' ? me.bottom - (scaleLabelFont.size / 2) : me.top + (scaleLabelFont.size / 2);\n\t\t\t\t} else {\n\t\t\t\t\tvar isLeft = options.position === 'left';\n\t\t\t\t\tscaleLabelX = isLeft ? me.left + (scaleLabelFont.size / 2) : me.right - (scaleLabelFont.size / 2);\n\t\t\t\t\tscaleLabelY = me.top + ((me.bottom - me.top) / 2);\n\t\t\t\t\trotation = isLeft ? -0.5 * Math.PI : 0.5 * Math.PI;\n\t\t\t\t}\n\n\t\t\t\tcontext.save();\n\t\t\t\tcontext.translate(scaleLabelX, scaleLabelY);\n\t\t\t\tcontext.rotate(rotation);\n\t\t\t\tcontext.textAlign = 'center';\n\t\t\t\tcontext.textBaseline = 'middle';\n\t\t\t\tcontext.fillStyle = scaleLabelFontColor; // render in correct colour\n\t\t\t\tcontext.font = scaleLabelFont.font;\n\t\t\t\tcontext.fillText(scaleLabel.labelString, 0, 0);\n\t\t\t\tcontext.restore();\n\t\t\t}\n\n\t\t\tif (gridLines.drawBorder) {\n\t\t\t\t// Draw the line at the edge of the axis\n\t\t\t\tcontext.lineWidth = helpers.getValueAtIndexOrDefault(gridLines.lineWidth, 0);\n\t\t\t\tcontext.strokeStyle = helpers.getValueAtIndexOrDefault(gridLines.color, 0);\n\t\t\t\tvar x1 = me.left,\n\t\t\t\t\tx2 = me.right,\n\t\t\t\t\ty1 = me.top,\n\t\t\t\t\ty2 = me.bottom;\n\n\t\t\t\tvar aliasPixel = helpers.aliasPixel(context.lineWidth);\n\t\t\t\tif (isHorizontal) {\n\t\t\t\t\ty1 = y2 = options.position === 'top' ? me.bottom : me.top;\n\t\t\t\t\ty1 += aliasPixel;\n\t\t\t\t\ty2 += aliasPixel;\n\t\t\t\t} else {\n\t\t\t\t\tx1 = x2 = options.position === 'left' ? me.right : me.left;\n\t\t\t\t\tx1 += aliasPixel;\n\t\t\t\t\tx2 += aliasPixel;\n\t\t\t\t}\n\n\t\t\t\tcontext.beginPath();\n\t\t\t\tcontext.moveTo(x1, y1);\n\t\t\t\tcontext.lineTo(x2, y2);\n\t\t\t\tcontext.stroke();\n\t\t\t}\n\t\t}\n\t});\n};\n\n},{}],32:[function(require,module,exports){\n'use strict';\n\nmodule.exports = function(Chart) {\n\n\tvar helpers = Chart.helpers;\n\n\tChart.scaleService = {\n\t\t// Scale registration object. Extensions can register new scale types (such as log or DB scales) and then\n\t\t// use the new chart options to grab the correct scale\n\t\tconstructors: {},\n\t\t// Use a registration function so that we can move to an ES6 map when we no longer need to support\n\t\t// old browsers\n\n\t\t// Scale config defaults\n\t\tdefaults: {},\n\t\tregisterScaleType: function(type, scaleConstructor, defaults) {\n\t\t\tthis.constructors[type] = scaleConstructor;\n\t\t\tthis.defaults[type] = helpers.clone(defaults);\n\t\t},\n\t\tgetScaleConstructor: function(type) {\n\t\t\treturn this.constructors.hasOwnProperty(type) ? this.constructors[type] : undefined;\n\t\t},\n\t\tgetScaleDefaults: function(type) {\n\t\t\t// Return the scale defaults merged with the global settings so that we always use the latest ones\n\t\t\treturn this.defaults.hasOwnProperty(type) ? helpers.scaleMerge(Chart.defaults.scale, this.defaults[type]) : {};\n\t\t},\n\t\tupdateScaleDefaults: function(type, additions) {\n\t\t\tvar defaults = this.defaults;\n\t\t\tif (defaults.hasOwnProperty(type)) {\n\t\t\t\tdefaults[type] = helpers.extend(defaults[type], additions);\n\t\t\t}\n\t\t},\n\t\taddScalesToLayout: function(chart) {\n\t\t\t// Adds each scale to the chart.boxes array to be sized accordingly\n\t\t\thelpers.each(chart.scales, function(scale) {\n\t\t\t\t// Set ILayoutItem parameters for backwards compatibility\n\t\t\t\tscale.fullWidth = scale.options.fullWidth;\n\t\t\t\tscale.position = scale.options.position;\n\t\t\t\tscale.weight = scale.options.weight;\n\t\t\t\tChart.layoutService.addBox(chart, scale);\n\t\t\t});\n\t\t}\n\t};\n};\n\n},{}],33:[function(require,module,exports){\n'use strict';\n\nmodule.exports = function(Chart) {\n\n\tvar helpers = Chart.helpers;\n\n\t/**\n\t * Namespace to hold static tick generation functions\n\t * @namespace Chart.Ticks\n\t */\n\tChart.Ticks = {\n\t\t/**\n\t\t * Namespace to hold generators for different types of ticks\n\t\t * @namespace Chart.Ticks.generators\n\t\t */\n\t\tgenerators: {\n\t\t\t/**\n\t\t\t * Interface for the options provided to the numeric tick generator\n\t\t\t * @interface INumericTickGenerationOptions\n\t\t\t */\n\t\t\t/**\n\t\t\t * The maximum number of ticks to display\n\t\t\t * @name INumericTickGenerationOptions#maxTicks\n\t\t\t * @type Number\n\t\t\t */\n\t\t\t/**\n\t\t\t * The distance between each tick.\n\t\t\t * @name INumericTickGenerationOptions#stepSize\n\t\t\t * @type Number\n\t\t\t * @optional\n\t\t\t */\n\t\t\t/**\n\t\t\t * Forced minimum for the ticks. If not specified, the minimum of the data range is used to calculate the tick minimum\n\t\t\t * @name INumericTickGenerationOptions#min\n\t\t\t * @type Number\n\t\t\t * @optional\n\t\t\t */\n\t\t\t/**\n\t\t\t * The maximum value of the ticks. If not specified, the maximum of the data range is used to calculate the tick maximum\n\t\t\t * @name INumericTickGenerationOptions#max\n\t\t\t * @type Number\n\t\t\t * @optional\n\t\t\t */\n\n\t\t\t/**\n\t\t\t * Generate a set of linear ticks\n\t\t\t * @method Chart.Ticks.generators.linear\n\t\t\t * @param generationOptions {INumericTickGenerationOptions} the options used to generate the ticks\n\t\t\t * @param dataRange {IRange} the range of the data\n\t\t\t * @returns {Array<Number>} array of tick values\n\t\t\t */\n\t\t\tlinear: function(generationOptions, dataRange) {\n\t\t\t\tvar ticks = [];\n\t\t\t\t// To get a \"nice\" value for the tick spacing, we will use the appropriately named\n\t\t\t\t// \"nice number\" algorithm. See http://stackoverflow.com/questions/8506881/nice-label-algorithm-for-charts-with-minimum-ticks\n\t\t\t\t// for details.\n\n\t\t\t\tvar spacing;\n\t\t\t\tif (generationOptions.stepSize && generationOptions.stepSize > 0) {\n\t\t\t\t\tspacing = generationOptions.stepSize;\n\t\t\t\t} else {\n\t\t\t\t\tvar niceRange = helpers.niceNum(dataRange.max - dataRange.min, false);\n\t\t\t\t\tspacing = helpers.niceNum(niceRange / (generationOptions.maxTicks - 1), true);\n\t\t\t\t}\n\t\t\t\tvar niceMin = Math.floor(dataRange.min / spacing) * spacing;\n\t\t\t\tvar niceMax = Math.ceil(dataRange.max / spacing) * spacing;\n\n\t\t\t\t// If min, max and stepSize is set and they make an evenly spaced scale use it.\n\t\t\t\tif (generationOptions.min && generationOptions.max && generationOptions.stepSize) {\n\t\t\t\t\t// If very close to our whole number, use it.\n\t\t\t\t\tif (helpers.almostWhole((generationOptions.max - generationOptions.min) / generationOptions.stepSize, spacing / 1000)) {\n\t\t\t\t\t\tniceMin = generationOptions.min;\n\t\t\t\t\t\tniceMax = generationOptions.max;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tvar numSpaces = (niceMax - niceMin) / spacing;\n\t\t\t\t// If very close to our rounded value, use it.\n\t\t\t\tif (helpers.almostEquals(numSpaces, Math.round(numSpaces), spacing / 1000)) {\n\t\t\t\t\tnumSpaces = Math.round(numSpaces);\n\t\t\t\t} else {\n\t\t\t\t\tnumSpaces = Math.ceil(numSpaces);\n\t\t\t\t}\n\n\t\t\t\t// Put the values into the ticks array\n\t\t\t\tticks.push(generationOptions.min !== undefined ? generationOptions.min : niceMin);\n\t\t\t\tfor (var j = 1; j < numSpaces; ++j) {\n\t\t\t\t\tticks.push(niceMin + (j * spacing));\n\t\t\t\t}\n\t\t\t\tticks.push(generationOptions.max !== undefined ? generationOptions.max : niceMax);\n\n\t\t\t\treturn ticks;\n\t\t\t},\n\n\t\t\t/**\n\t\t\t * Generate a set of logarithmic ticks\n\t\t\t * @method Chart.Ticks.generators.logarithmic\n\t\t\t * @param generationOptions {INumericTickGenerationOptions} the options used to generate the ticks\n\t\t\t * @param dataRange {IRange} the range of the data\n\t\t\t * @returns {Array<Number>} array of tick values\n\t\t\t */\n\t\t\tlogarithmic: function(generationOptions, dataRange) {\n\t\t\t\tvar ticks = [];\n\t\t\t\tvar getValueOrDefault = helpers.getValueOrDefault;\n\n\t\t\t\t// Figure out what the max number of ticks we can support it is based on the size of\n\t\t\t\t// the axis area. For now, we say that the minimum tick spacing in pixels must be 50\n\t\t\t\t// We also limit the maximum number of ticks to 11 which gives a nice 10 squares on\n\t\t\t\t// the graph\n\t\t\t\tvar tickVal = getValueOrDefault(generationOptions.min, Math.pow(10, Math.floor(helpers.log10(dataRange.min))));\n\n\t\t\t\tvar endExp = Math.floor(helpers.log10(dataRange.max));\n\t\t\t\tvar endSignificand = Math.ceil(dataRange.max / Math.pow(10, endExp));\n\t\t\t\tvar exp;\n\t\t\t\tvar significand;\n\n\t\t\t\tif (tickVal === 0) {\n\t\t\t\t\texp = Math.floor(helpers.log10(dataRange.minNotZero));\n\t\t\t\t\tsignificand = Math.floor(dataRange.minNotZero / Math.pow(10, exp));\n\n\t\t\t\t\tticks.push(tickVal);\n\t\t\t\t\ttickVal = significand * Math.pow(10, exp);\n\t\t\t\t} else {\n\t\t\t\t\texp = Math.floor(helpers.log10(tickVal));\n\t\t\t\t\tsignificand = Math.floor(tickVal / Math.pow(10, exp));\n\t\t\t\t}\n\n\t\t\t\tdo {\n\t\t\t\t\tticks.push(tickVal);\n\n\t\t\t\t\t++significand;\n\t\t\t\t\tif (significand === 10) {\n\t\t\t\t\t\tsignificand = 1;\n\t\t\t\t\t\t++exp;\n\t\t\t\t\t}\n\n\t\t\t\t\ttickVal = significand * Math.pow(10, exp);\n\t\t\t\t} while (exp < endExp || (exp === endExp && significand < endSignificand));\n\n\t\t\t\tvar lastTick = getValueOrDefault(generationOptions.max, tickVal);\n\t\t\t\tticks.push(lastTick);\n\n\t\t\t\treturn ticks;\n\t\t\t}\n\t\t},\n\n\t\t/**\n\t\t * Namespace to hold formatters for different types of ticks\n\t\t * @namespace Chart.Ticks.formatters\n\t\t */\n\t\tformatters: {\n\t\t\t/**\n\t\t\t * Formatter for value labels\n\t\t\t * @method Chart.Ticks.formatters.values\n\t\t\t * @param value the value to display\n\t\t\t * @return {String|Array} the label to display\n\t\t\t */\n\t\t\tvalues: function(value) {\n\t\t\t\treturn helpers.isArray(value) ? value : '' + value;\n\t\t\t},\n\n\t\t\t/**\n\t\t\t * Formatter for linear numeric ticks\n\t\t\t * @method Chart.Ticks.formatters.linear\n\t\t\t * @param tickValue {Number} the value to be formatted\n\t\t\t * @param index {Number} the position of the tickValue parameter in the ticks array\n\t\t\t * @param ticks {Array<Number>} the list of ticks being converted\n\t\t\t * @return {String} string representation of the tickValue parameter\n\t\t\t */\n\t\t\tlinear: function(tickValue, index, ticks) {\n\t\t\t\t// If we have lots of ticks, don't use the ones\n\t\t\t\tvar delta = ticks.length > 3 ? ticks[2] - ticks[1] : ticks[1] - ticks[0];\n\n\t\t\t\t// If we have a number like 2.5 as the delta, figure out how many decimal places we need\n\t\t\t\tif (Math.abs(delta) > 1) {\n\t\t\t\t\tif (tickValue !== Math.floor(tickValue)) {\n\t\t\t\t\t\t// not an integer\n\t\t\t\t\t\tdelta = tickValue - Math.floor(tickValue);\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tvar logDelta = helpers.log10(Math.abs(delta));\n\t\t\t\tvar tickString = '';\n\n\t\t\t\tif (tickValue !== 0) {\n\t\t\t\t\tvar numDecimal = -1 * Math.floor(logDelta);\n\t\t\t\t\tnumDecimal = Math.max(Math.min(numDecimal, 20), 0); // toFixed has a max of 20 decimal places\n\t\t\t\t\ttickString = tickValue.toFixed(numDecimal);\n\t\t\t\t} else {\n\t\t\t\t\ttickString = '0'; // never show decimal places for 0\n\t\t\t\t}\n\n\t\t\t\treturn tickString;\n\t\t\t},\n\n\t\t\tlogarithmic: function(tickValue, index, ticks) {\n\t\t\t\tvar remain = tickValue / (Math.pow(10, Math.floor(helpers.log10(tickValue))));\n\n\t\t\t\tif (tickValue === 0) {\n\t\t\t\t\treturn '0';\n\t\t\t\t} else if (remain === 1 || remain === 2 || remain === 5 || index === 0 || index === ticks.length - 1) {\n\t\t\t\t\treturn tickValue.toExponential();\n\t\t\t\t}\n\t\t\t\treturn '';\n\t\t\t}\n\t\t}\n\t};\n};\n\n},{}],34:[function(require,module,exports){\n'use strict';\n\nmodule.exports = function(Chart) {\n\n\tvar helpers = Chart.helpers;\n\n\t/**\n \t * Helper method to merge the opacity into a color\n \t */\n\tfunction mergeOpacity(colorString, opacity) {\n\t\tvar color = helpers.color(colorString);\n\t\treturn color.alpha(opacity * color.alpha()).rgbaString();\n\t}\n\n\tChart.defaults.global.tooltips = {\n\t\tenabled: true,\n\t\tcustom: null,\n\t\tmode: 'nearest',\n\t\tposition: 'average',\n\t\tintersect: true,\n\t\tbackgroundColor: 'rgba(0,0,0,0.8)',\n\t\ttitleFontStyle: 'bold',\n\t\ttitleSpacing: 2,\n\t\ttitleMarginBottom: 6,\n\t\ttitleFontColor: '#fff',\n\t\ttitleAlign: 'left',\n\t\tbodySpacing: 2,\n\t\tbodyFontColor: '#fff',\n\t\tbodyAlign: 'left',\n\t\tfooterFontStyle: 'bold',\n\t\tfooterSpacing: 2,\n\t\tfooterMarginTop: 6,\n\t\tfooterFontColor: '#fff',\n\t\tfooterAlign: 'left',\n\t\tyPadding: 6,\n\t\txPadding: 6,\n\t\tcaretPadding: 2,\n\t\tcaretSize: 5,\n\t\tcornerRadius: 6,\n\t\tmultiKeyBackground: '#fff',\n\t\tdisplayColors: true,\n\t\tborderColor: 'rgba(0,0,0,0)',\n\t\tborderWidth: 0,\n\t\tcallbacks: {\n\t\t\t// Args are: (tooltipItems, data)\n\t\t\tbeforeTitle: helpers.noop,\n\t\t\ttitle: function(tooltipItems, data) {\n\t\t\t\t// Pick first xLabel for now\n\t\t\t\tvar title = '';\n\t\t\t\tvar labels = data.labels;\n\t\t\t\tvar labelCount = labels ? labels.length : 0;\n\n\t\t\t\tif (tooltipItems.length > 0) {\n\t\t\t\t\tvar item = tooltipItems[0];\n\n\t\t\t\t\tif (item.xLabel) {\n\t\t\t\t\t\ttitle = item.xLabel;\n\t\t\t\t\t} else if (labelCount > 0 && item.index < labelCount) {\n\t\t\t\t\t\ttitle = labels[item.index];\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\treturn title;\n\t\t\t},\n\t\t\tafterTitle: helpers.noop,\n\n\t\t\t// Args are: (tooltipItems, data)\n\t\t\tbeforeBody: helpers.noop,\n\n\t\t\t// Args are: (tooltipItem, data)\n\t\t\tbeforeLabel: helpers.noop,\n\t\t\tlabel: function(tooltipItem, data) {\n\t\t\t\tvar label = data.datasets[tooltipItem.datasetIndex].label || '';\n\n\t\t\t\tif (label) {\n\t\t\t\t\tlabel += ': ';\n\t\t\t\t}\n\t\t\t\tlabel += tooltipItem.yLabel;\n\t\t\t\treturn label;\n\t\t\t},\n\t\t\tlabelColor: function(tooltipItem, chart) {\n\t\t\t\tvar meta = chart.getDatasetMeta(tooltipItem.datasetIndex);\n\t\t\t\tvar activeElement = meta.data[tooltipItem.index];\n\t\t\t\tvar view = activeElement._view;\n\t\t\t\treturn {\n\t\t\t\t\tborderColor: view.borderColor,\n\t\t\t\t\tbackgroundColor: view.backgroundColor\n\t\t\t\t};\n\t\t\t},\n\t\t\tafterLabel: helpers.noop,\n\n\t\t\t// Args are: (tooltipItems, data)\n\t\t\tafterBody: helpers.noop,\n\n\t\t\t// Args are: (tooltipItems, data)\n\t\t\tbeforeFooter: helpers.noop,\n\t\t\tfooter: helpers.noop,\n\t\t\tafterFooter: helpers.noop\n\t\t}\n\t};\n\n\t// Helper to push or concat based on if the 2nd parameter is an array or not\n\tfunction pushOrConcat(base, toPush) {\n\t\tif (toPush) {\n\t\t\tif (helpers.isArray(toPush)) {\n\t\t\t\t// base = base.concat(toPush);\n\t\t\t\tArray.prototype.push.apply(base, toPush);\n\t\t\t} else {\n\t\t\t\tbase.push(toPush);\n\t\t\t}\n\t\t}\n\n\t\treturn base;\n\t}\n\n\t// Private helper to create a tooltip item model\n\t// @param element : the chart element (point, arc, bar) to create the tooltip item for\n\t// @return : new tooltip item\n\tfunction createTooltipItem(element) {\n\t\tvar xScale = element._xScale;\n\t\tvar yScale = element._yScale || element._scale; // handle radar || polarArea charts\n\t\tvar index = element._index,\n\t\t\tdatasetIndex = element._datasetIndex;\n\n\t\treturn {\n\t\t\txLabel: xScale ? xScale.getLabelForIndex(index, datasetIndex) : '',\n\t\t\tyLabel: yScale ? yScale.getLabelForIndex(index, datasetIndex) : '',\n\t\t\tindex: index,\n\t\t\tdatasetIndex: datasetIndex,\n\t\t\tx: element._model.x,\n\t\t\ty: element._model.y\n\t\t};\n\t}\n\n\t/**\n\t * Helper to get the reset model for the tooltip\n\t * @param tooltipOpts {Object} the tooltip options\n\t */\n\tfunction getBaseModel(tooltipOpts) {\n\t\tvar globalDefaults = Chart.defaults.global;\n\t\tvar getValueOrDefault = helpers.getValueOrDefault;\n\n\t\treturn {\n\t\t\t// Positioning\n\t\t\txPadding: tooltipOpts.xPadding,\n\t\t\tyPadding: tooltipOpts.yPadding,\n\t\t\txAlign: tooltipOpts.xAlign,\n\t\t\tyAlign: tooltipOpts.yAlign,\n\n\t\t\t// Body\n\t\t\tbodyFontColor: tooltipOpts.bodyFontColor,\n\t\t\t_bodyFontFamily: getValueOrDefault(tooltipOpts.bodyFontFamily, globalDefaults.defaultFontFamily),\n\t\t\t_bodyFontStyle: getValueOrDefault(tooltipOpts.bodyFontStyle, globalDefaults.defaultFontStyle),\n\t\t\t_bodyAlign: tooltipOpts.bodyAlign,\n\t\t\tbodyFontSize: getValueOrDefault(tooltipOpts.bodyFontSize, globalDefaults.defaultFontSize),\n\t\t\tbodySpacing: tooltipOpts.bodySpacing,\n\n\t\t\t// Title\n\t\t\ttitleFontColor: tooltipOpts.titleFontColor,\n\t\t\t_titleFontFamily: getValueOrDefault(tooltipOpts.titleFontFamily, globalDefaults.defaultFontFamily),\n\t\t\t_titleFontStyle: getValueOrDefault(tooltipOpts.titleFontStyle, globalDefaults.defaultFontStyle),\n\t\t\ttitleFontSize: getValueOrDefault(tooltipOpts.titleFontSize, globalDefaults.defaultFontSize),\n\t\t\t_titleAlign: tooltipOpts.titleAlign,\n\t\t\ttitleSpacing: tooltipOpts.titleSpacing,\n\t\t\ttitleMarginBottom: tooltipOpts.titleMarginBottom,\n\n\t\t\t// Footer\n\t\t\tfooterFontColor: tooltipOpts.footerFontColor,\n\t\t\t_footerFontFamily: getValueOrDefault(tooltipOpts.footerFontFamily, globalDefaults.defaultFontFamily),\n\t\t\t_footerFontStyle: getValueOrDefault(tooltipOpts.footerFontStyle, globalDefaults.defaultFontStyle),\n\t\t\tfooterFontSize: getValueOrDefault(tooltipOpts.footerFontSize, globalDefaults.defaultFontSize),\n\t\t\t_footerAlign: tooltipOpts.footerAlign,\n\t\t\tfooterSpacing: tooltipOpts.footerSpacing,\n\t\t\tfooterMarginTop: tooltipOpts.footerMarginTop,\n\n\t\t\t// Appearance\n\t\t\tcaretSize: tooltipOpts.caretSize,\n\t\t\tcornerRadius: tooltipOpts.cornerRadius,\n\t\t\tbackgroundColor: tooltipOpts.backgroundColor,\n\t\t\topacity: 0,\n\t\t\tlegendColorBackground: tooltipOpts.multiKeyBackground,\n\t\t\tdisplayColors: tooltipOpts.displayColors,\n\t\t\tborderColor: tooltipOpts.borderColor,\n\t\t\tborderWidth: tooltipOpts.borderWidth\n\t\t};\n\t}\n\n\t/**\n\t * Get the size of the tooltip\n\t */\n\tfunction getTooltipSize(tooltip, model) {\n\t\tvar ctx = tooltip._chart.ctx;\n\n\t\tvar height = model.yPadding * 2; // Tooltip Padding\n\t\tvar width = 0;\n\n\t\t// Count of all lines in the body\n\t\tvar body = model.body;\n\t\tvar combinedBodyLength = body.reduce(function(count, bodyItem) {\n\t\t\treturn count + bodyItem.before.length + bodyItem.lines.length + bodyItem.after.length;\n\t\t}, 0);\n\t\tcombinedBodyLength += model.beforeBody.length + model.afterBody.length;\n\n\t\tvar titleLineCount = model.title.length;\n\t\tvar footerLineCount = model.footer.length;\n\t\tvar titleFontSize = model.titleFontSize,\n\t\t\tbodyFontSize = model.bodyFontSize,\n\t\t\tfooterFontSize = model.footerFontSize;\n\n\t\theight += titleLineCount * titleFontSize; // Title Lines\n\t\theight += titleLineCount ? (titleLineCount - 1) * model.titleSpacing : 0; // Title Line Spacing\n\t\theight += titleLineCount ? model.titleMarginBottom : 0; // Title's bottom Margin\n\t\theight += combinedBodyLength * bodyFontSize; // Body Lines\n\t\theight += combinedBodyLength ? (combinedBodyLength - 1) * model.bodySpacing : 0; // Body Line Spacing\n\t\theight += footerLineCount ? model.footerMarginTop : 0; // Footer Margin\n\t\theight += footerLineCount * (footerFontSize); // Footer Lines\n\t\theight += footerLineCount ? (footerLineCount - 1) * model.footerSpacing : 0; // Footer Line Spacing\n\n\t\t// Title width\n\t\tvar widthPadding = 0;\n\t\tvar maxLineWidth = function(line) {\n\t\t\twidth = Math.max(width, ctx.measureText(line).width + widthPadding);\n\t\t};\n\n\t\tctx.font = helpers.fontString(titleFontSize, model._titleFontStyle, model._titleFontFamily);\n\t\thelpers.each(model.title, maxLineWidth);\n\n\t\t// Body width\n\t\tctx.font = helpers.fontString(bodyFontSize, model._bodyFontStyle, model._bodyFontFamily);\n\t\thelpers.each(model.beforeBody.concat(model.afterBody), maxLineWidth);\n\n\t\t// Body lines may include some extra width due to the color box\n\t\twidthPadding = model.displayColors ? (bodyFontSize + 2) : 0;\n\t\thelpers.each(body, function(bodyItem) {\n\t\t\thelpers.each(bodyItem.before, maxLineWidth);\n\t\t\thelpers.each(bodyItem.lines, maxLineWidth);\n\t\t\thelpers.each(bodyItem.after, maxLineWidth);\n\t\t});\n\n\t\t// Reset back to 0\n\t\twidthPadding = 0;\n\n\t\t// Footer width\n\t\tctx.font = helpers.fontString(footerFontSize, model._footerFontStyle, model._footerFontFamily);\n\t\thelpers.each(model.footer, maxLineWidth);\n\n\t\t// Add padding\n\t\twidth += 2 * model.xPadding;\n\n\t\treturn {\n\t\t\twidth: width,\n\t\t\theight: height\n\t\t};\n\t}\n\n\t/**\n\t * Helper to get the alignment of a tooltip given the size\n\t */\n\tfunction determineAlignment(tooltip, size) {\n\t\tvar model = tooltip._model;\n\t\tvar chart = tooltip._chart;\n\t\tvar chartArea = tooltip._chart.chartArea;\n\t\tvar xAlign = 'center';\n\t\tvar yAlign = 'center';\n\n\t\tif (model.y < size.height) {\n\t\t\tyAlign = 'top';\n\t\t} else if (model.y > (chart.height - size.height)) {\n\t\t\tyAlign = 'bottom';\n\t\t}\n\n\t\tvar lf, rf; // functions to determine left, right alignment\n\t\tvar olf, orf; // functions to determine if left/right alignment causes tooltip to go outside chart\n\t\tvar yf; // function to get the y alignment if the tooltip goes outside of the left or right edges\n\t\tvar midX = (chartArea.left + chartArea.right) / 2;\n\t\tvar midY = (chartArea.top + chartArea.bottom) / 2;\n\n\t\tif (yAlign === 'center') {\n\t\t\tlf = function(x) {\n\t\t\t\treturn x <= midX;\n\t\t\t};\n\t\t\trf = function(x) {\n\t\t\t\treturn x > midX;\n\t\t\t};\n\t\t} else {\n\t\t\tlf = function(x) {\n\t\t\t\treturn x <= (size.width / 2);\n\t\t\t};\n\t\t\trf = function(x) {\n\t\t\t\treturn x >= (chart.width - (size.width / 2));\n\t\t\t};\n\t\t}\n\n\t\tolf = function(x) {\n\t\t\treturn x + size.width > chart.width;\n\t\t};\n\t\torf = function(x) {\n\t\t\treturn x - size.width < 0;\n\t\t};\n\t\tyf = function(y) {\n\t\t\treturn y <= midY ? 'top' : 'bottom';\n\t\t};\n\n\t\tif (lf(model.x)) {\n\t\t\txAlign = 'left';\n\n\t\t\t// Is tooltip too wide and goes over the right side of the chart.?\n\t\t\tif (olf(model.x)) {\n\t\t\t\txAlign = 'center';\n\t\t\t\tyAlign = yf(model.y);\n\t\t\t}\n\t\t} else if (rf(model.x)) {\n\t\t\txAlign = 'right';\n\n\t\t\t// Is tooltip too wide and goes outside left edge of canvas?\n\t\t\tif (orf(model.x)) {\n\t\t\t\txAlign = 'center';\n\t\t\t\tyAlign = yf(model.y);\n\t\t\t}\n\t\t}\n\n\t\tvar opts = tooltip._options;\n\t\treturn {\n\t\t\txAlign: opts.xAlign ? opts.xAlign : xAlign,\n\t\t\tyAlign: opts.yAlign ? opts.yAlign : yAlign\n\t\t};\n\t}\n\n\t/**\n\t * @Helper to get the location a tooltip needs to be placed at given the initial position (via the vm) and the size and alignment\n\t */\n\tfunction getBackgroundPoint(vm, size, alignment) {\n\t\t// Background Position\n\t\tvar x = vm.x;\n\t\tvar y = vm.y;\n\n\t\tvar caretSize = vm.caretSize,\n\t\t\tcaretPadding = vm.caretPadding,\n\t\t\tcornerRadius = vm.cornerRadius,\n\t\t\txAlign = alignment.xAlign,\n\t\t\tyAlign = alignment.yAlign,\n\t\t\tpaddingAndSize = caretSize + caretPadding,\n\t\t\tradiusAndPadding = cornerRadius + caretPadding;\n\n\t\tif (xAlign === 'right') {\n\t\t\tx -= size.width;\n\t\t} else if (xAlign === 'center') {\n\t\t\tx -= (size.width / 2);\n\t\t}\n\n\t\tif (yAlign === 'top') {\n\t\t\ty += paddingAndSize;\n\t\t} else if (yAlign === 'bottom') {\n\t\t\ty -= size.height + paddingAndSize;\n\t\t} else {\n\t\t\ty -= (size.height / 2);\n\t\t}\n\n\t\tif (yAlign === 'center') {\n\t\t\tif (xAlign === 'left') {\n\t\t\t\tx += paddingAndSize;\n\t\t\t} else if (xAlign === 'right') {\n\t\t\t\tx -= paddingAndSize;\n\t\t\t}\n\t\t} else if (xAlign === 'left') {\n\t\t\tx -= radiusAndPadding;\n\t\t} else if (xAlign === 'right') {\n\t\t\tx += radiusAndPadding;\n\t\t}\n\n\t\treturn {\n\t\t\tx: x,\n\t\t\ty: y\n\t\t};\n\t}\n\n\tChart.Tooltip = Chart.Element.extend({\n\t\tinitialize: function() {\n\t\t\tthis._model = getBaseModel(this._options);\n\t\t},\n\n\t\t// Get the title\n\t\t// Args are: (tooltipItem, data)\n\t\tgetTitle: function() {\n\t\t\tvar me = this;\n\t\t\tvar opts = me._options;\n\t\t\tvar callbacks = opts.callbacks;\n\n\t\t\tvar beforeTitle = callbacks.beforeTitle.apply(me, arguments),\n\t\t\t\ttitle = callbacks.title.apply(me, arguments),\n\t\t\t\tafterTitle = callbacks.afterTitle.apply(me, arguments);\n\n\t\t\tvar lines = [];\n\t\t\tlines = pushOrConcat(lines, beforeTitle);\n\t\t\tlines = pushOrConcat(lines, title);\n\t\t\tlines = pushOrConcat(lines, afterTitle);\n\n\t\t\treturn lines;\n\t\t},\n\n\t\t// Args are: (tooltipItem, data)\n\t\tgetBeforeBody: function() {\n\t\t\tvar lines = this._options.callbacks.beforeBody.apply(this, arguments);\n\t\t\treturn helpers.isArray(lines) ? lines : lines !== undefined ? [lines] : [];\n\t\t},\n\n\t\t// Args are: (tooltipItem, data)\n\t\tgetBody: function(tooltipItems, data) {\n\t\t\tvar me = this;\n\t\t\tvar callbacks = me._options.callbacks;\n\t\t\tvar bodyItems = [];\n\n\t\t\thelpers.each(tooltipItems, function(tooltipItem) {\n\t\t\t\tvar bodyItem = {\n\t\t\t\t\tbefore: [],\n\t\t\t\t\tlines: [],\n\t\t\t\t\tafter: []\n\t\t\t\t};\n\t\t\t\tpushOrConcat(bodyItem.before, callbacks.beforeLabel.call(me, tooltipItem, data));\n\t\t\t\tpushOrConcat(bodyItem.lines, callbacks.label.call(me, tooltipItem, data));\n\t\t\t\tpushOrConcat(bodyItem.after, callbacks.afterLabel.call(me, tooltipItem, data));\n\n\t\t\t\tbodyItems.push(bodyItem);\n\t\t\t});\n\n\t\t\treturn bodyItems;\n\t\t},\n\n\t\t// Args are: (tooltipItem, data)\n\t\tgetAfterBody: function() {\n\t\t\tvar lines = this._options.callbacks.afterBody.apply(this, arguments);\n\t\t\treturn helpers.isArray(lines) ? lines : lines !== undefined ? [lines] : [];\n\t\t},\n\n\t\t// Get the footer and beforeFooter and afterFooter lines\n\t\t// Args are: (tooltipItem, data)\n\t\tgetFooter: function() {\n\t\t\tvar me = this;\n\t\t\tvar callbacks = me._options.callbacks;\n\n\t\t\tvar beforeFooter = callbacks.beforeFooter.apply(me, arguments);\n\t\t\tvar footer = callbacks.footer.apply(me, arguments);\n\t\t\tvar afterFooter = callbacks.afterFooter.apply(me, arguments);\n\n\t\t\tvar lines = [];\n\t\t\tlines = pushOrConcat(lines, beforeFooter);\n\t\t\tlines = pushOrConcat(lines, footer);\n\t\t\tlines = pushOrConcat(lines, afterFooter);\n\n\t\t\treturn lines;\n\t\t},\n\n\t\tupdate: function(changed) {\n\t\t\tvar me = this;\n\t\t\tvar opts = me._options;\n\n\t\t\t// Need to regenerate the model because its faster than using extend and it is necessary due to the optimization in Chart.Element.transition\n\t\t\t// that does _view = _model if ease === 1. This causes the 2nd tooltip update to set properties in both the view and model at the same time\n\t\t\t// which breaks any animations.\n\t\t\tvar existingModel = me._model;\n\t\t\tvar model = me._model = getBaseModel(opts);\n\t\t\tvar active = me._active;\n\n\t\t\tvar data = me._data;\n\n\t\t\t// In the case where active.length === 0 we need to keep these at existing values for good animations\n\t\t\tvar alignment = {\n\t\t\t\txAlign: existingModel.xAlign,\n\t\t\t\tyAlign: existingModel.yAlign\n\t\t\t};\n\t\t\tvar backgroundPoint = {\n\t\t\t\tx: existingModel.x,\n\t\t\t\ty: existingModel.y\n\t\t\t};\n\t\t\tvar tooltipSize = {\n\t\t\t\twidth: existingModel.width,\n\t\t\t\theight: existingModel.height\n\t\t\t};\n\t\t\tvar tooltipPosition = {\n\t\t\t\tx: existingModel.caretX,\n\t\t\t\ty: existingModel.caretY\n\t\t\t};\n\n\t\t\tvar i, len;\n\n\t\t\tif (active.length) {\n\t\t\t\tmodel.opacity = 1;\n\n\t\t\t\tvar labelColors = [];\n\t\t\t\ttooltipPosition = Chart.Tooltip.positioners[opts.position](active, me._eventPosition);\n\n\t\t\t\tvar tooltipItems = [];\n\t\t\t\tfor (i = 0, len = active.length; i < len; ++i) {\n\t\t\t\t\ttooltipItems.push(createTooltipItem(active[i]));\n\t\t\t\t}\n\n\t\t\t\t// If the user provided a filter function, use it to modify the tooltip items\n\t\t\t\tif (opts.filter) {\n\t\t\t\t\ttooltipItems = tooltipItems.filter(function(a) {\n\t\t\t\t\t\treturn opts.filter(a, data);\n\t\t\t\t\t});\n\t\t\t\t}\n\n\t\t\t\t// If the user provided a sorting function, use it to modify the tooltip items\n\t\t\t\tif (opts.itemSort) {\n\t\t\t\t\ttooltipItems = tooltipItems.sort(function(a, b) {\n\t\t\t\t\t\treturn opts.itemSort(a, b, data);\n\t\t\t\t\t});\n\t\t\t\t}\n\n\t\t\t\t// Determine colors for boxes\n\t\t\t\thelpers.each(tooltipItems, function(tooltipItem) {\n\t\t\t\t\tlabelColors.push(opts.callbacks.labelColor.call(me, tooltipItem, me._chart));\n\t\t\t\t});\n\n\t\t\t\t// Build the Text Lines\n\t\t\t\tmodel.title = me.getTitle(tooltipItems, data);\n\t\t\t\tmodel.beforeBody = me.getBeforeBody(tooltipItems, data);\n\t\t\t\tmodel.body = me.getBody(tooltipItems, data);\n\t\t\t\tmodel.afterBody = me.getAfterBody(tooltipItems, data);\n\t\t\t\tmodel.footer = me.getFooter(tooltipItems, data);\n\n\t\t\t\t// Initial positioning and colors\n\t\t\t\tmodel.x = Math.round(tooltipPosition.x);\n\t\t\t\tmodel.y = Math.round(tooltipPosition.y);\n\t\t\t\tmodel.caretPadding = opts.caretPadding;\n\t\t\t\tmodel.labelColors = labelColors;\n\n\t\t\t\t// data points\n\t\t\t\tmodel.dataPoints = tooltipItems;\n\n\t\t\t\t// We need to determine alignment of the tooltip\n\t\t\t\ttooltipSize = getTooltipSize(this, model);\n\t\t\t\talignment = determineAlignment(this, tooltipSize);\n\t\t\t\t// Final Size and Position\n\t\t\t\tbackgroundPoint = getBackgroundPoint(model, tooltipSize, alignment);\n\t\t\t} else {\n\t\t\t\tmodel.opacity = 0;\n\t\t\t}\n\n\t\t\tmodel.xAlign = alignment.xAlign;\n\t\t\tmodel.yAlign = alignment.yAlign;\n\t\t\tmodel.x = backgroundPoint.x;\n\t\t\tmodel.y = backgroundPoint.y;\n\t\t\tmodel.width = tooltipSize.width;\n\t\t\tmodel.height = tooltipSize.height;\n\n\t\t\t// Point where the caret on the tooltip points to\n\t\t\tmodel.caretX = tooltipPosition.x;\n\t\t\tmodel.caretY = tooltipPosition.y;\n\n\t\t\tme._model = model;\n\n\t\t\tif (changed && opts.custom) {\n\t\t\t\topts.custom.call(me, model);\n\t\t\t}\n\n\t\t\treturn me;\n\t\t},\n\t\tdrawCaret: function(tooltipPoint, size) {\n\t\t\tvar ctx = this._chart.ctx;\n\t\t\tvar vm = this._view;\n\t\t\tvar caretPosition = this.getCaretPosition(tooltipPoint, size, vm);\n\n\t\t\tctx.lineTo(caretPosition.x1, caretPosition.y1);\n\t\t\tctx.lineTo(caretPosition.x2, caretPosition.y2);\n\t\t\tctx.lineTo(caretPosition.x3, caretPosition.y3);\n\t\t},\n\t\tgetCaretPosition: function(tooltipPoint, size, vm) {\n\t\t\tvar x1, x2, x3;\n\t\t\tvar y1, y2, y3;\n\t\t\tvar caretSize = vm.caretSize;\n\t\t\tvar cornerRadius = vm.cornerRadius;\n\t\t\tvar xAlign = vm.xAlign,\n\t\t\t\tyAlign = vm.yAlign;\n\t\t\tvar ptX = tooltipPoint.x,\n\t\t\t\tptY = tooltipPoint.y;\n\t\t\tvar width = size.width,\n\t\t\t\theight = size.height;\n\n\t\t\tif (yAlign === 'center') {\n\t\t\t\ty2 = ptY + (height / 2);\n\n\t\t\t\tif (xAlign === 'left') {\n\t\t\t\t\tx1 = ptX;\n\t\t\t\t\tx2 = x1 - caretSize;\n\t\t\t\t\tx3 = x1;\n\n\t\t\t\t\ty1 = y2 + caretSize;\n\t\t\t\t\ty3 = y2 - caretSize;\n\t\t\t\t} else {\n\t\t\t\t\tx1 = ptX + width;\n\t\t\t\t\tx2 = x1 + caretSize;\n\t\t\t\t\tx3 = x1;\n\n\t\t\t\t\ty1 = y2 - caretSize;\n\t\t\t\t\ty3 = y2 + caretSize;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tif (xAlign === 'left') {\n\t\t\t\t\tx2 = ptX + cornerRadius + (caretSize);\n\t\t\t\t\tx1 = x2 - caretSize;\n\t\t\t\t\tx3 = x2 + caretSize;\n\t\t\t\t} else if (xAlign === 'right') {\n\t\t\t\t\tx2 = ptX + width - cornerRadius - caretSize;\n\t\t\t\t\tx1 = x2 - caretSize;\n\t\t\t\t\tx3 = x2 + caretSize;\n\t\t\t\t} else {\n\t\t\t\t\tx2 = ptX + (width / 2);\n\t\t\t\t\tx1 = x2 - caretSize;\n\t\t\t\t\tx3 = x2 + caretSize;\n\t\t\t\t}\n\t\t\t\tif (yAlign === 'top') {\n\t\t\t\t\ty1 = ptY;\n\t\t\t\t\ty2 = y1 - caretSize;\n\t\t\t\t\ty3 = y1;\n\t\t\t\t} else {\n\t\t\t\t\ty1 = ptY + height;\n\t\t\t\t\ty2 = y1 + caretSize;\n\t\t\t\t\ty3 = y1;\n\t\t\t\t\t// invert drawing order\n\t\t\t\t\tvar tmp = x3;\n\t\t\t\t\tx3 = x1;\n\t\t\t\t\tx1 = tmp;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn {x1: x1, x2: x2, x3: x3, y1: y1, y2: y2, y3: y3};\n\t\t},\n\t\tdrawTitle: function(pt, vm, ctx, opacity) {\n\t\t\tvar title = vm.title;\n\n\t\t\tif (title.length) {\n\t\t\t\tctx.textAlign = vm._titleAlign;\n\t\t\t\tctx.textBaseline = 'top';\n\n\t\t\t\tvar titleFontSize = vm.titleFontSize,\n\t\t\t\t\ttitleSpacing = vm.titleSpacing;\n\n\t\t\t\tctx.fillStyle = mergeOpacity(vm.titleFontColor, opacity);\n\t\t\t\tctx.font = helpers.fontString(titleFontSize, vm._titleFontStyle, vm._titleFontFamily);\n\n\t\t\t\tvar i, len;\n\t\t\t\tfor (i = 0, len = title.length; i < len; ++i) {\n\t\t\t\t\tctx.fillText(title[i], pt.x, pt.y);\n\t\t\t\t\tpt.y += titleFontSize + titleSpacing; // Line Height and spacing\n\n\t\t\t\t\tif (i + 1 === title.length) {\n\t\t\t\t\t\tpt.y += vm.titleMarginBottom - titleSpacing; // If Last, add margin, remove spacing\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\tdrawBody: function(pt, vm, ctx, opacity) {\n\t\t\tvar bodyFontSize = vm.bodyFontSize;\n\t\t\tvar bodySpacing = vm.bodySpacing;\n\t\t\tvar body = vm.body;\n\n\t\t\tctx.textAlign = vm._bodyAlign;\n\t\t\tctx.textBaseline = 'top';\n\n\t\t\tvar textColor = mergeOpacity(vm.bodyFontColor, opacity);\n\t\t\tctx.fillStyle = textColor;\n\t\t\tctx.font = helpers.fontString(bodyFontSize, vm._bodyFontStyle, vm._bodyFontFamily);\n\n\t\t\t// Before Body\n\t\t\tvar xLinePadding = 0;\n\t\t\tvar fillLineOfText = function(line) {\n\t\t\t\tctx.fillText(line, pt.x + xLinePadding, pt.y);\n\t\t\t\tpt.y += bodyFontSize + bodySpacing;\n\t\t\t};\n\n\t\t\t// Before body lines\n\t\t\thelpers.each(vm.beforeBody, fillLineOfText);\n\n\t\t\tvar drawColorBoxes = vm.displayColors;\n\t\t\txLinePadding = drawColorBoxes ? (bodyFontSize + 2) : 0;\n\n\t\t\t// Draw body lines now\n\t\t\thelpers.each(body, function(bodyItem, i) {\n\t\t\t\thelpers.each(bodyItem.before, fillLineOfText);\n\n\t\t\t\thelpers.each(bodyItem.lines, function(line) {\n\t\t\t\t\t// Draw Legend-like boxes if needed\n\t\t\t\t\tif (drawColorBoxes) {\n\t\t\t\t\t\t// Fill a white rect so that colours merge nicely if the opacity is < 1\n\t\t\t\t\t\tctx.fillStyle = mergeOpacity(vm.legendColorBackground, opacity);\n\t\t\t\t\t\tctx.fillRect(pt.x, pt.y, bodyFontSize, bodyFontSize);\n\n\t\t\t\t\t\t// Border\n\t\t\t\t\t\tctx.strokeStyle = mergeOpacity(vm.labelColors[i].borderColor, opacity);\n\t\t\t\t\t\tctx.strokeRect(pt.x, pt.y, bodyFontSize, bodyFontSize);\n\n\t\t\t\t\t\t// Inner square\n\t\t\t\t\t\tctx.fillStyle = mergeOpacity(vm.labelColors[i].backgroundColor, opacity);\n\t\t\t\t\t\tctx.fillRect(pt.x + 1, pt.y + 1, bodyFontSize - 2, bodyFontSize - 2);\n\n\t\t\t\t\t\tctx.fillStyle = textColor;\n\t\t\t\t\t}\n\n\t\t\t\t\tfillLineOfText(line);\n\t\t\t\t});\n\n\t\t\t\thelpers.each(bodyItem.after, fillLineOfText);\n\t\t\t});\n\n\t\t\t// Reset back to 0 for after body\n\t\t\txLinePadding = 0;\n\n\t\t\t// After body lines\n\t\t\thelpers.each(vm.afterBody, fillLineOfText);\n\t\t\tpt.y -= bodySpacing; // Remove last body spacing\n\t\t},\n\t\tdrawFooter: function(pt, vm, ctx, opacity) {\n\t\t\tvar footer = vm.footer;\n\n\t\t\tif (footer.length) {\n\t\t\t\tpt.y += vm.footerMarginTop;\n\n\t\t\t\tctx.textAlign = vm._footerAlign;\n\t\t\t\tctx.textBaseline = 'top';\n\n\t\t\t\tctx.fillStyle = mergeOpacity(vm.footerFontColor, opacity);\n\t\t\t\tctx.font = helpers.fontString(vm.footerFontSize, vm._footerFontStyle, vm._footerFontFamily);\n\n\t\t\t\thelpers.each(footer, function(line) {\n\t\t\t\t\tctx.fillText(line, pt.x, pt.y);\n\t\t\t\t\tpt.y += vm.footerFontSize + vm.footerSpacing;\n\t\t\t\t});\n\t\t\t}\n\t\t},\n\t\tdrawBackground: function(pt, vm, ctx, tooltipSize, opacity) {\n\t\t\tctx.fillStyle = mergeOpacity(vm.backgroundColor, opacity);\n\t\t\tctx.strokeStyle = mergeOpacity(vm.borderColor, opacity);\n\t\t\tctx.lineWidth = vm.borderWidth;\n\t\t\tvar xAlign = vm.xAlign;\n\t\t\tvar yAlign = vm.yAlign;\n\t\t\tvar x = pt.x;\n\t\t\tvar y = pt.y;\n\t\t\tvar width = tooltipSize.width;\n\t\t\tvar height = tooltipSize.height;\n\t\t\tvar radius = vm.cornerRadius;\n\n\t\t\tctx.beginPath();\n\t\t\tctx.moveTo(x + radius, y);\n\t\t\tif (yAlign === 'top') {\n\t\t\t\tthis.drawCaret(pt, tooltipSize);\n\t\t\t}\n\t\t\tctx.lineTo(x + width - radius, y);\n\t\t\tctx.quadraticCurveTo(x + width, y, x + width, y + radius);\n\t\t\tif (yAlign === 'center' && xAlign === 'right') {\n\t\t\t\tthis.drawCaret(pt, tooltipSize);\n\t\t\t}\n\t\t\tctx.lineTo(x + width, y + height - radius);\n\t\t\tctx.quadraticCurveTo(x + width, y + height, x + width - radius, y + height);\n\t\t\tif (yAlign === 'bottom') {\n\t\t\t\tthis.drawCaret(pt, tooltipSize);\n\t\t\t}\n\t\t\tctx.lineTo(x + radius, y + height);\n\t\t\tctx.quadraticCurveTo(x, y + height, x, y + height - radius);\n\t\t\tif (yAlign === 'center' && xAlign === 'left') {\n\t\t\t\tthis.drawCaret(pt, tooltipSize);\n\t\t\t}\n\t\t\tctx.lineTo(x, y + radius);\n\t\t\tctx.quadraticCurveTo(x, y, x + radius, y);\n\t\t\tctx.closePath();\n\n\t\t\tctx.fill();\n\n\t\t\tif (vm.borderWidth > 0) {\n\t\t\t\tctx.stroke();\n\t\t\t}\n\t\t},\n\t\tdraw: function() {\n\t\t\tvar ctx = this._chart.ctx;\n\t\t\tvar vm = this._view;\n\n\t\t\tif (vm.opacity === 0) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tvar tooltipSize = {\n\t\t\t\twidth: vm.width,\n\t\t\t\theight: vm.height\n\t\t\t};\n\t\t\tvar pt = {\n\t\t\t\tx: vm.x,\n\t\t\t\ty: vm.y\n\t\t\t};\n\n\t\t\t// IE11/Edge does not like very small opacities, so snap to 0\n\t\t\tvar opacity = Math.abs(vm.opacity < 1e-3) ? 0 : vm.opacity;\n\n\t\t\t// Truthy/falsey value for empty tooltip\n\t\t\tvar hasTooltipContent = vm.title.length || vm.beforeBody.length || vm.body.length || vm.afterBody.length || vm.footer.length;\n\n\t\t\tif (this._options.enabled && hasTooltipContent) {\n\t\t\t\t// Draw Background\n\t\t\t\tthis.drawBackground(pt, vm, ctx, tooltipSize, opacity);\n\n\t\t\t\t// Draw Title, Body, and Footer\n\t\t\t\tpt.x += vm.xPadding;\n\t\t\t\tpt.y += vm.yPadding;\n\n\t\t\t\t// Titles\n\t\t\t\tthis.drawTitle(pt, vm, ctx, opacity);\n\n\t\t\t\t// Body\n\t\t\t\tthis.drawBody(pt, vm, ctx, opacity);\n\n\t\t\t\t// Footer\n\t\t\t\tthis.drawFooter(pt, vm, ctx, opacity);\n\t\t\t}\n\t\t},\n\n\t\t/**\n\t\t * Handle an event\n\t\t * @private\n\t\t * @param {IEvent} event - The event to handle\n\t\t * @returns {Boolean} true if the tooltip changed\n\t\t */\n\t\thandleEvent: function(e) {\n\t\t\tvar me = this;\n\t\t\tvar options = me._options;\n\t\t\tvar changed = false;\n\n\t\t\tme._lastActive = me._lastActive || [];\n\n\t\t\t// Find Active Elements for tooltips\n\t\t\tif (e.type === 'mouseout') {\n\t\t\t\tme._active = [];\n\t\t\t} else {\n\t\t\t\tme._active = me._chart.getElementsAtEventForMode(e, options.mode, options);\n\t\t\t}\n\n\t\t\t// Remember Last Actives\n\t\t\tchanged = !helpers.arrayEquals(me._active, me._lastActive);\n\n\t\t\t// If tooltip didn't change, do not handle the target event\n\t\t\tif (!changed) {\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\tme._lastActive = me._active;\n\n\t\t\tif (options.enabled || options.custom) {\n\t\t\t\tme._eventPosition = {\n\t\t\t\t\tx: e.x,\n\t\t\t\t\ty: e.y\n\t\t\t\t};\n\n\t\t\t\tvar model = me._model;\n\t\t\t\tme.update(true);\n\t\t\t\tme.pivot();\n\n\t\t\t\t// See if our tooltip position changed\n\t\t\t\tchanged |= (model.x !== me._model.x) || (model.y !== me._model.y);\n\t\t\t}\n\n\t\t\treturn changed;\n\t\t}\n\t});\n\n\t/**\n\t * @namespace Chart.Tooltip.positioners\n\t */\n\tChart.Tooltip.positioners = {\n\t\t/**\n\t\t * Average mode places the tooltip at the average position of the elements shown\n\t\t * @function Chart.Tooltip.positioners.average\n\t\t * @param elements {ChartElement[]} the elements being displayed in the tooltip\n\t\t * @returns {Point} tooltip position\n\t\t */\n\t\taverage: function(elements) {\n\t\t\tif (!elements.length) {\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\tvar i, len;\n\t\t\tvar x = 0;\n\t\t\tvar y = 0;\n\t\t\tvar count = 0;\n\n\t\t\tfor (i = 0, len = elements.length; i < len; ++i) {\n\t\t\t\tvar el = elements[i];\n\t\t\t\tif (el && el.hasValue()) {\n\t\t\t\t\tvar pos = el.tooltipPosition();\n\t\t\t\t\tx += pos.x;\n\t\t\t\t\ty += pos.y;\n\t\t\t\t\t++count;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn {\n\t\t\t\tx: Math.round(x / count),\n\t\t\t\ty: Math.round(y / count)\n\t\t\t};\n\t\t},\n\n\t\t/**\n\t\t * Gets the tooltip position nearest of the item nearest to the event position\n\t\t * @function Chart.Tooltip.positioners.nearest\n\t\t * @param elements {Chart.Element[]} the tooltip elements\n\t\t * @param eventPosition {Point} the position of the event in canvas coordinates\n\t\t * @returns {Point} the tooltip position\n\t\t */\n\t\tnearest: function(elements, eventPosition) {\n\t\t\tvar x = eventPosition.x;\n\t\t\tvar y = eventPosition.y;\n\n\t\t\tvar nearestElement;\n\t\t\tvar minDistance = Number.POSITIVE_INFINITY;\n\t\t\tvar i, len;\n\t\t\tfor (i = 0, len = elements.length; i < len; ++i) {\n\t\t\t\tvar el = elements[i];\n\t\t\t\tif (el && el.hasValue()) {\n\t\t\t\t\tvar center = el.getCenterPoint();\n\t\t\t\t\tvar d = helpers.distanceBetweenPoints(eventPosition, center);\n\n\t\t\t\t\tif (d < minDistance) {\n\t\t\t\t\t\tminDistance = d;\n\t\t\t\t\t\tnearestElement = el;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (nearestElement) {\n\t\t\t\tvar tp = nearestElement.tooltipPosition();\n\t\t\t\tx = tp.x;\n\t\t\t\ty = tp.y;\n\t\t\t}\n\n\t\t\treturn {\n\t\t\t\tx: x,\n\t\t\t\ty: y\n\t\t\t};\n\t\t}\n\t};\n};\n\n},{}],35:[function(require,module,exports){\n'use strict';\n\nmodule.exports = function(Chart) {\n\n\tvar helpers = Chart.helpers,\n\t\tglobalOpts = Chart.defaults.global;\n\n\tglobalOpts.elements.arc = {\n\t\tbackgroundColor: globalOpts.defaultColor,\n\t\tborderColor: '#fff',\n\t\tborderWidth: 2\n\t};\n\n\tChart.elements.Arc = Chart.Element.extend({\n\t\tinLabelRange: function(mouseX) {\n\t\t\tvar vm = this._view;\n\n\t\t\tif (vm) {\n\t\t\t\treturn (Math.pow(mouseX - vm.x, 2) < Math.pow(vm.radius + vm.hoverRadius, 2));\n\t\t\t}\n\t\t\treturn false;\n\t\t},\n\t\tinRange: function(chartX, chartY) {\n\t\t\tvar vm = this._view;\n\n\t\t\tif (vm) {\n\t\t\t\tvar pointRelativePosition = helpers.getAngleFromPoint(vm, {\n\t\t\t\t\t\tx: chartX,\n\t\t\t\t\t\ty: chartY\n\t\t\t\t\t}),\n\t\t\t\t\tangle = pointRelativePosition.angle,\n\t\t\t\t\tdistance = pointRelativePosition.distance;\n\n\t\t\t\t// Sanitise angle range\n\t\t\t\tvar startAngle = vm.startAngle;\n\t\t\t\tvar endAngle = vm.endAngle;\n\t\t\t\twhile (endAngle < startAngle) {\n\t\t\t\t\tendAngle += 2.0 * Math.PI;\n\t\t\t\t}\n\t\t\t\twhile (angle > endAngle) {\n\t\t\t\t\tangle -= 2.0 * Math.PI;\n\t\t\t\t}\n\t\t\t\twhile (angle < startAngle) {\n\t\t\t\t\tangle += 2.0 * Math.PI;\n\t\t\t\t}\n\n\t\t\t\t// Check if within the range of the open/close angle\n\t\t\t\tvar betweenAngles = (angle >= startAngle && angle <= endAngle),\n\t\t\t\t\twithinRadius = (distance >= vm.innerRadius && distance <= vm.outerRadius);\n\n\t\t\t\treturn (betweenAngles && withinRadius);\n\t\t\t}\n\t\t\treturn false;\n\t\t},\n\t\tgetCenterPoint: function() {\n\t\t\tvar vm = this._view;\n\t\t\tvar halfAngle = (vm.startAngle + vm.endAngle) / 2;\n\t\t\tvar halfRadius = (vm.innerRadius + vm.outerRadius) / 2;\n\t\t\treturn {\n\t\t\t\tx: vm.x + Math.cos(halfAngle) * halfRadius,\n\t\t\t\ty: vm.y + Math.sin(halfAngle) * halfRadius\n\t\t\t};\n\t\t},\n\t\tgetArea: function() {\n\t\t\tvar vm = this._view;\n\t\t\treturn Math.PI * ((vm.endAngle - vm.startAngle) / (2 * Math.PI)) * (Math.pow(vm.outerRadius, 2) - Math.pow(vm.innerRadius, 2));\n\t\t},\n\t\ttooltipPosition: function() {\n\t\t\tvar vm = this._view;\n\n\t\t\tvar centreAngle = vm.startAngle + ((vm.endAngle - vm.startAngle) / 2),\n\t\t\t\trangeFromCentre = (vm.outerRadius - vm.innerRadius) / 2 + vm.innerRadius;\n\t\t\treturn {\n\t\t\t\tx: vm.x + (Math.cos(centreAngle) * rangeFromCentre),\n\t\t\t\ty: vm.y + (Math.sin(centreAngle) * rangeFromCentre)\n\t\t\t};\n\t\t},\n\t\tdraw: function() {\n\n\t\t\tvar ctx = this._chart.ctx,\n\t\t\t\tvm = this._view,\n\t\t\t\tsA = vm.startAngle,\n\t\t\t\teA = vm.endAngle;\n\n\t\t\tctx.beginPath();\n\n\t\t\tctx.arc(vm.x, vm.y, vm.outerRadius, sA, eA);\n\t\t\tctx.arc(vm.x, vm.y, vm.innerRadius, eA, sA, true);\n\n\t\t\tctx.closePath();\n\t\t\tctx.strokeStyle = vm.borderColor;\n\t\t\tctx.lineWidth = vm.borderWidth;\n\n\t\t\tctx.fillStyle = vm.backgroundColor;\n\n\t\t\tctx.fill();\n\t\t\tctx.lineJoin = 'bevel';\n\n\t\t\tif (vm.borderWidth) {\n\t\t\t\tctx.stroke();\n\t\t\t}\n\t\t}\n\t});\n};\n\n},{}],36:[function(require,module,exports){\n'use strict';\n\nmodule.exports = function(Chart) {\n\n\tvar helpers = Chart.helpers;\n\tvar globalDefaults = Chart.defaults.global;\n\n\tChart.defaults.global.elements.line = {\n\t\ttension: 0.4,\n\t\tbackgroundColor: globalDefaults.defaultColor,\n\t\tborderWidth: 3,\n\t\tborderColor: globalDefaults.defaultColor,\n\t\tborderCapStyle: 'butt',\n\t\tborderDash: [],\n\t\tborderDashOffset: 0.0,\n\t\tborderJoinStyle: 'miter',\n\t\tcapBezierPoints: true,\n\t\tfill: true, // do we fill in the area between the line and its base axis\n\t};\n\n\tChart.elements.Line = Chart.Element.extend({\n\t\tdraw: function() {\n\t\t\tvar me = this;\n\t\t\tvar vm = me._view;\n\t\t\tvar ctx = me._chart.ctx;\n\t\t\tvar spanGaps = vm.spanGaps;\n\t\t\tvar points = me._children.slice(); // clone array\n\t\t\tvar globalOptionLineElements = globalDefaults.elements.line;\n\t\t\tvar lastDrawnIndex = -1;\n\t\t\tvar index, current, previous, currentVM;\n\n\t\t\t// If we are looping, adding the first point again\n\t\t\tif (me._loop && points.length) {\n\t\t\t\tpoints.push(points[0]);\n\t\t\t}\n\n\t\t\tctx.save();\n\n\t\t\t// Stroke Line Options\n\t\t\tctx.lineCap = vm.borderCapStyle || globalOptionLineElements.borderCapStyle;\n\n\t\t\t// IE 9 and 10 do not support line dash\n\t\t\tif (ctx.setLineDash) {\n\t\t\t\tctx.setLineDash(vm.borderDash || globalOptionLineElements.borderDash);\n\t\t\t}\n\n\t\t\tctx.lineDashOffset = vm.borderDashOffset || globalOptionLineElements.borderDashOffset;\n\t\t\tctx.lineJoin = vm.borderJoinStyle || globalOptionLineElements.borderJoinStyle;\n\t\t\tctx.lineWidth = vm.borderWidth || globalOptionLineElements.borderWidth;\n\t\t\tctx.strokeStyle = vm.borderColor || globalDefaults.defaultColor;\n\n\t\t\t// Stroke Line\n\t\t\tctx.beginPath();\n\t\t\tlastDrawnIndex = -1;\n\n\t\t\tfor (index = 0; index < points.length; ++index) {\n\t\t\t\tcurrent = points[index];\n\t\t\t\tprevious = helpers.previousItem(points, index);\n\t\t\t\tcurrentVM = current._view;\n\n\t\t\t\t// First point moves to it's starting position no matter what\n\t\t\t\tif (index === 0) {\n\t\t\t\t\tif (!currentVM.skip) {\n\t\t\t\t\t\tctx.moveTo(currentVM.x, currentVM.y);\n\t\t\t\t\t\tlastDrawnIndex = index;\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tprevious = lastDrawnIndex === -1 ? previous : points[lastDrawnIndex];\n\n\t\t\t\t\tif (!currentVM.skip) {\n\t\t\t\t\t\tif ((lastDrawnIndex !== (index - 1) && !spanGaps) || lastDrawnIndex === -1) {\n\t\t\t\t\t\t\t// There was a gap and this is the first point after the gap\n\t\t\t\t\t\t\tctx.moveTo(currentVM.x, currentVM.y);\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t// Line to next point\n\t\t\t\t\t\t\thelpers.canvas.lineTo(ctx, previous._view, current._view);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tlastDrawnIndex = index;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tctx.stroke();\n\t\t\tctx.restore();\n\t\t}\n\t});\n};\n\n},{}],37:[function(require,module,exports){\n'use strict';\n\nmodule.exports = function(Chart) {\n\n\tvar helpers = Chart.helpers,\n\t\tglobalOpts = Chart.defaults.global,\n\t\tdefaultColor = globalOpts.defaultColor;\n\n\tglobalOpts.elements.point = {\n\t\tradius: 3,\n\t\tpointStyle: 'circle',\n\t\tbackgroundColor: defaultColor,\n\t\tborderWidth: 1,\n\t\tborderColor: defaultColor,\n\t\t// Hover\n\t\thitRadius: 1,\n\t\thoverRadius: 4,\n\t\thoverBorderWidth: 1\n\t};\n\n\tfunction xRange(mouseX) {\n\t\tvar vm = this._view;\n\t\treturn vm ? (Math.pow(mouseX - vm.x, 2) < Math.pow(vm.radius + vm.hitRadius, 2)) : false;\n\t}\n\n\tfunction yRange(mouseY) {\n\t\tvar vm = this._view;\n\t\treturn vm ? (Math.pow(mouseY - vm.y, 2) < Math.pow(vm.radius + vm.hitRadius, 2)) : false;\n\t}\n\n\tChart.elements.Point = Chart.Element.extend({\n\t\tinRange: function(mouseX, mouseY) {\n\t\t\tvar vm = this._view;\n\t\t\treturn vm ? ((Math.pow(mouseX - vm.x, 2) + Math.pow(mouseY - vm.y, 2)) < Math.pow(vm.hitRadius + vm.radius, 2)) : false;\n\t\t},\n\n\t\tinLabelRange: xRange,\n\t\tinXRange: xRange,\n\t\tinYRange: yRange,\n\n\t\tgetCenterPoint: function() {\n\t\t\tvar vm = this._view;\n\t\t\treturn {\n\t\t\t\tx: vm.x,\n\t\t\t\ty: vm.y\n\t\t\t};\n\t\t},\n\t\tgetArea: function() {\n\t\t\treturn Math.PI * Math.pow(this._view.radius, 2);\n\t\t},\n\t\ttooltipPosition: function() {\n\t\t\tvar vm = this._view;\n\t\t\treturn {\n\t\t\t\tx: vm.x,\n\t\t\t\ty: vm.y,\n\t\t\t\tpadding: vm.radius + vm.borderWidth\n\t\t\t};\n\t\t},\n\t\tdraw: function(chartArea) {\n\t\t\tvar vm = this._view;\n\t\t\tvar model = this._model;\n\t\t\tvar ctx = this._chart.ctx;\n\t\t\tvar pointStyle = vm.pointStyle;\n\t\t\tvar radius = vm.radius;\n\t\t\tvar x = vm.x;\n\t\t\tvar y = vm.y;\n\t\t\tvar color = Chart.helpers.color;\n\t\t\tvar errMargin = 1.01; // 1.01 is margin for Accumulated error. (Especially Edge, IE.)\n\t\t\tvar ratio = 0;\n\n\t\t\tif (vm.skip) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tctx.strokeStyle = vm.borderColor || defaultColor;\n\t\t\tctx.lineWidth = helpers.getValueOrDefault(vm.borderWidth, globalOpts.elements.point.borderWidth);\n\t\t\tctx.fillStyle = vm.backgroundColor || defaultColor;\n\n\t\t\t// Cliping for Points.\n\t\t\t// going out from inner charArea?\n\t\t\tif ((chartArea !== undefined) && ((model.x < chartArea.left) || (chartArea.right*errMargin < model.x) || (model.y < chartArea.top) || (chartArea.bottom*errMargin < model.y))) {\n\t\t\t\t// Point fade out\n\t\t\t\tif (model.x < chartArea.left) {\n\t\t\t\t\tratio = (x - model.x) / (chartArea.left - model.x);\n\t\t\t\t} else if (chartArea.right*errMargin < model.x) {\n\t\t\t\t\tratio = (model.x - x) / (model.x - chartArea.right);\n\t\t\t\t} else if (model.y < chartArea.top) {\n\t\t\t\t\tratio = (y - model.y) / (chartArea.top - model.y);\n\t\t\t\t} else if (chartArea.bottom*errMargin < model.y) {\n\t\t\t\t\tratio = (model.y - y) / (model.y - chartArea.bottom);\n\t\t\t\t}\n\t\t\t\tratio = Math.round(ratio*100) / 100;\n\t\t\t\tctx.strokeStyle = color(ctx.strokeStyle).alpha(ratio).rgbString();\n\t\t\t\tctx.fillStyle = color(ctx.fillStyle).alpha(ratio).rgbString();\n\t\t\t}\n\n\t\t\tChart.canvasHelpers.drawPoint(ctx, pointStyle, radius, x, y);\n\t\t}\n\t});\n};\n\n},{}],38:[function(require,module,exports){\n'use strict';\n\nmodule.exports = function(Chart) {\n\n\tvar globalOpts = Chart.defaults.global;\n\n\tglobalOpts.elements.rectangle = {\n\t\tbackgroundColor: globalOpts.defaultColor,\n\t\tborderWidth: 0,\n\t\tborderColor: globalOpts.defaultColor,\n\t\tborderSkipped: 'bottom'\n\t};\n\n\tfunction isVertical(bar) {\n\t\treturn bar._view.width !== undefined;\n\t}\n\n\t/**\n\t * Helper function to get the bounds of the bar regardless of the orientation\n\t * @private\n\t * @param bar {Chart.Element.Rectangle} the bar\n\t * @return {Bounds} bounds of the bar\n\t */\n\tfunction getBarBounds(bar) {\n\t\tvar vm = bar._view;\n\t\tvar x1, x2, y1, y2;\n\n\t\tif (isVertical(bar)) {\n\t\t\t// vertical\n\t\t\tvar halfWidth = vm.width / 2;\n\t\t\tx1 = vm.x - halfWidth;\n\t\t\tx2 = vm.x + halfWidth;\n\t\t\ty1 = Math.min(vm.y, vm.base);\n\t\t\ty2 = Math.max(vm.y, vm.base);\n\t\t} else {\n\t\t\t// horizontal bar\n\t\t\tvar halfHeight = vm.height / 2;\n\t\t\tx1 = Math.min(vm.x, vm.base);\n\t\t\tx2 = Math.max(vm.x, vm.base);\n\t\t\ty1 = vm.y - halfHeight;\n\t\t\ty2 = vm.y + halfHeight;\n\t\t}\n\n\t\treturn {\n\t\t\tleft: x1,\n\t\t\ttop: y1,\n\t\t\tright: x2,\n\t\t\tbottom: y2\n\t\t};\n\t}\n\n\tChart.elements.Rectangle = Chart.Element.extend({\n\t\tdraw: function() {\n\t\t\tvar ctx = this._chart.ctx;\n\t\t\tvar vm = this._view;\n\t\t\tvar left, right, top, bottom, signX, signY, borderSkipped;\n\t\t\tvar borderWidth = vm.borderWidth;\n\n\t\t\tif (!vm.horizontal) {\n\t\t\t\t// bar\n\t\t\t\tleft = vm.x - vm.width / 2;\n\t\t\t\tright = vm.x + vm.width / 2;\n\t\t\t\ttop = vm.y;\n\t\t\t\tbottom = vm.base;\n\t\t\t\tsignX = 1;\n\t\t\t\tsignY = bottom > top? 1: -1;\n\t\t\t\tborderSkipped = vm.borderSkipped || 'bottom';\n\t\t\t} else {\n\t\t\t\t// horizontal bar\n\t\t\t\tleft = vm.base;\n\t\t\t\tright = vm.x;\n\t\t\t\ttop = vm.y - vm.height / 2;\n\t\t\t\tbottom = vm.y + vm.height / 2;\n\t\t\t\tsignX = right > left? 1: -1;\n\t\t\t\tsignY = 1;\n\t\t\t\tborderSkipped = vm.borderSkipped || 'left';\n\t\t\t}\n\n\t\t\t// Canvas doesn't allow us to stroke inside the width so we can\n\t\t\t// adjust the sizes to fit if we're setting a stroke on the line\n\t\t\tif (borderWidth) {\n\t\t\t\t// borderWidth shold be less than bar width and bar height.\n\t\t\t\tvar barSize = Math.min(Math.abs(left - right), Math.abs(top - bottom));\n\t\t\t\tborderWidth = borderWidth > barSize? barSize: borderWidth;\n\t\t\t\tvar halfStroke = borderWidth / 2;\n\t\t\t\t// Adjust borderWidth when bar top position is near vm.base(zero).\n\t\t\t\tvar borderLeft = left + (borderSkipped !== 'left'? halfStroke * signX: 0);\n\t\t\t\tvar borderRight = right + (borderSkipped !== 'right'? -halfStroke * signX: 0);\n\t\t\t\tvar borderTop = top + (borderSkipped !== 'top'? halfStroke * signY: 0);\n\t\t\t\tvar borderBottom = bottom + (borderSkipped !== 'bottom'? -halfStroke * signY: 0);\n\t\t\t\t// not become a vertical line?\n\t\t\t\tif (borderLeft !== borderRight) {\n\t\t\t\t\ttop = borderTop;\n\t\t\t\t\tbottom = borderBottom;\n\t\t\t\t}\n\t\t\t\t// not become a horizontal line?\n\t\t\t\tif (borderTop !== borderBottom) {\n\t\t\t\t\tleft = borderLeft;\n\t\t\t\t\tright = borderRight;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tctx.beginPath();\n\t\t\tctx.fillStyle = vm.backgroundColor;\n\t\t\tctx.strokeStyle = vm.borderColor;\n\t\t\tctx.lineWidth = borderWidth;\n\n\t\t\t// Corner points, from bottom-left to bottom-right clockwise\n\t\t\t// | 1 2 |\n\t\t\t// | 0 3 |\n\t\t\tvar corners = [\n\t\t\t\t[left, bottom],\n\t\t\t\t[left, top],\n\t\t\t\t[right, top],\n\t\t\t\t[right, bottom]\n\t\t\t];\n\n\t\t\t// Find first (starting) corner with fallback to 'bottom'\n\t\t\tvar borders = ['bottom', 'left', 'top', 'right'];\n\t\t\tvar startCorner = borders.indexOf(borderSkipped, 0);\n\t\t\tif (startCorner === -1) {\n\t\t\t\tstartCorner = 0;\n\t\t\t}\n\n\t\t\tfunction cornerAt(index) {\n\t\t\t\treturn corners[(startCorner + index) % 4];\n\t\t\t}\n\n\t\t\t// Draw rectangle from 'startCorner'\n\t\t\tvar corner = cornerAt(0);\n\t\t\tctx.moveTo(corner[0], corner[1]);\n\n\t\t\tfor (var i = 1; i < 4; i++) {\n\t\t\t\tcorner = cornerAt(i);\n\t\t\t\tctx.lineTo(corner[0], corner[1]);\n\t\t\t}\n\n\t\t\tctx.fill();\n\t\t\tif (borderWidth) {\n\t\t\t\tctx.stroke();\n\t\t\t}\n\t\t},\n\t\theight: function() {\n\t\t\tvar vm = this._view;\n\t\t\treturn vm.base - vm.y;\n\t\t},\n\t\tinRange: function(mouseX, mouseY) {\n\t\t\tvar inRange = false;\n\n\t\t\tif (this._view) {\n\t\t\t\tvar bounds = getBarBounds(this);\n\t\t\t\tinRange = mouseX >= bounds.left && mouseX <= bounds.right && mouseY >= bounds.top && mouseY <= bounds.bottom;\n\t\t\t}\n\n\t\t\treturn inRange;\n\t\t},\n\t\tinLabelRange: function(mouseX, mouseY) {\n\t\t\tvar me = this;\n\t\t\tif (!me._view) {\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\tvar inRange = false;\n\t\t\tvar bounds = getBarBounds(me);\n\n\t\t\tif (isVertical(me)) {\n\t\t\t\tinRange = mouseX >= bounds.left && mouseX <= bounds.right;\n\t\t\t} else {\n\t\t\t\tinRange = mouseY >= bounds.top && mouseY <= bounds.bottom;\n\t\t\t}\n\n\t\t\treturn inRange;\n\t\t},\n\t\tinXRange: function(mouseX) {\n\t\t\tvar bounds = getBarBounds(this);\n\t\t\treturn mouseX >= bounds.left && mouseX <= bounds.right;\n\t\t},\n\t\tinYRange: function(mouseY) {\n\t\t\tvar bounds = getBarBounds(this);\n\t\t\treturn mouseY >= bounds.top && mouseY <= bounds.bottom;\n\t\t},\n\t\tgetCenterPoint: function() {\n\t\t\tvar vm = this._view;\n\t\t\tvar x, y;\n\t\t\tif (isVertical(this)) {\n\t\t\t\tx = vm.x;\n\t\t\t\ty = (vm.y + vm.base) / 2;\n\t\t\t} else {\n\t\t\t\tx = (vm.x + vm.base) / 2;\n\t\t\t\ty = vm.y;\n\t\t\t}\n\n\t\t\treturn {x: x, y: y};\n\t\t},\n\t\tgetArea: function() {\n\t\t\tvar vm = this._view;\n\t\t\treturn vm.width * Math.abs(vm.y - vm.base);\n\t\t},\n\t\ttooltipPosition: function() {\n\t\t\tvar vm = this._view;\n\t\t\treturn {\n\t\t\t\tx: vm.x,\n\t\t\t\ty: vm.y\n\t\t\t};\n\t\t}\n\t});\n\n};\n\n},{}],39:[function(require,module,exports){\n'use strict';\n\n// Chart.Platform implementation for targeting a web browser\nmodule.exports = function(Chart) {\n\tvar helpers = Chart.helpers;\n\n\t// DOM event types -> Chart.js event types.\n\t// Note: only events with different types are mapped.\n\t// https://developer.mozilla.org/en-US/docs/Web/Events\n\tvar eventTypeMap = {\n\t\t// Touch events\n\t\ttouchstart: 'mousedown',\n\t\ttouchmove: 'mousemove',\n\t\ttouchend: 'mouseup',\n\n\t\t// Pointer events\n\t\tpointerenter: 'mouseenter',\n\t\tpointerdown: 'mousedown',\n\t\tpointermove: 'mousemove',\n\t\tpointerup: 'mouseup',\n\t\tpointerleave: 'mouseout',\n\t\tpointerout: 'mouseout'\n\t};\n\n\t/**\n\t * The \"used\" size is the final value of a dimension property after all calculations have\n\t * been performed. This method uses the computed style of `element` but returns undefined\n\t * if the computed style is not expressed in pixels. That can happen in some cases where\n\t * `element` has a size relative to its parent and this last one is not yet displayed,\n\t * for example because of `display: none` on a parent node.\n\t * @see https://developer.mozilla.org/en-US/docs/Web/CSS/used_value\n\t * @returns {Number} Size in pixels or undefined if unknown.\n\t */\n\tfunction readUsedSize(element, property) {\n\t\tvar value = helpers.getStyle(element, property);\n\t\tvar matches = value && value.match(/^(\\d+)(\\.\\d+)?px$/);\n\t\treturn matches? Number(matches[1]) : undefined;\n\t}\n\n\t/**\n\t * Initializes the canvas style and render size without modifying the canvas display size,\n\t * since responsiveness is handled by the controller.resize() method. The config is used\n\t * to determine the aspect ratio to apply in case no explicit height has been specified.\n\t */\n\tfunction initCanvas(canvas, config) {\n\t\tvar style = canvas.style;\n\n\t\t// NOTE(SB) canvas.getAttribute('width') !== canvas.width: in the first case it\n\t\t// returns null or '' if no explicit value has been set to the canvas attribute.\n\t\tvar renderHeight = canvas.getAttribute('height');\n\t\tvar renderWidth = canvas.getAttribute('width');\n\n\t\t// Chart.js modifies some canvas values that we want to restore on destroy\n\t\tcanvas._chartjs = {\n\t\t\tinitial: {\n\t\t\t\theight: renderHeight,\n\t\t\t\twidth: renderWidth,\n\t\t\t\tstyle: {\n\t\t\t\t\tdisplay: style.display,\n\t\t\t\t\theight: style.height,\n\t\t\t\t\twidth: style.width\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\n\t\t// Force canvas to display as block to avoid extra space caused by inline\n\t\t// elements, which would interfere with the responsive resize process.\n\t\t// https://github.com/chartjs/Chart.js/issues/2538\n\t\tstyle.display = style.display || 'block';\n\n\t\tif (renderWidth === null || renderWidth === '') {\n\t\t\tvar displayWidth = readUsedSize(canvas, 'width');\n\t\t\tif (displayWidth !== undefined) {\n\t\t\t\tcanvas.width = displayWidth;\n\t\t\t}\n\t\t}\n\n\t\tif (renderHeight === null || renderHeight === '') {\n\t\t\tif (canvas.style.height === '') {\n\t\t\t\t// If no explicit render height and style height, let's apply the aspect ratio,\n\t\t\t\t// which one can be specified by the user but also by charts as default option\n\t\t\t\t// (i.e. options.aspectRatio). If not specified, use canvas aspect ratio of 2.\n\t\t\t\tcanvas.height = canvas.width / (config.options.aspectRatio || 2);\n\t\t\t} else {\n\t\t\t\tvar displayHeight = readUsedSize(canvas, 'height');\n\t\t\t\tif (displayWidth !== undefined) {\n\t\t\t\t\tcanvas.height = displayHeight;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn canvas;\n\t}\n\n\tfunction createEvent(type, chart, x, y, nativeEvent) {\n\t\treturn {\n\t\t\ttype: type,\n\t\t\tchart: chart,\n\t\t\tnative: nativeEvent || null,\n\t\t\tx: x !== undefined? x : null,\n\t\t\ty: y !== undefined? y : null,\n\t\t};\n\t}\n\n\tfunction fromNativeEvent(event, chart) {\n\t\tvar type = eventTypeMap[event.type] || event.type;\n\t\tvar pos = helpers.getRelativePosition(event, chart);\n\t\treturn createEvent(type, chart, pos.x, pos.y, event);\n\t}\n\n\tfunction createResizer(handler) {\n\t\tvar iframe = document.createElement('iframe');\n\t\tiframe.className = 'chartjs-hidden-iframe';\n\t\tiframe.style.cssText =\n\t\t\t'display:block;'+\n\t\t\t'overflow:hidden;'+\n\t\t\t'border:0;'+\n\t\t\t'margin:0;'+\n\t\t\t'top:0;'+\n\t\t\t'left:0;'+\n\t\t\t'bottom:0;'+\n\t\t\t'right:0;'+\n\t\t\t'height:100%;'+\n\t\t\t'width:100%;'+\n\t\t\t'position:absolute;'+\n\t\t\t'pointer-events:none;'+\n\t\t\t'z-index:-1;';\n\n\t\t// Prevent the iframe to gain focus on tab.\n\t\t// https://github.com/chartjs/Chart.js/issues/3090\n\t\tiframe.tabIndex = -1;\n\n\t\t// If the iframe is re-attached to the DOM, the resize listener is removed because the\n\t\t// content is reloaded, so make sure to install the handler after the iframe is loaded.\n\t\t// https://github.com/chartjs/Chart.js/issues/3521\n\t\thelpers.addEvent(iframe, 'load', function() {\n\t\t\thelpers.addEvent(iframe.contentWindow || iframe, 'resize', handler);\n\n\t\t\t// The iframe size might have changed while loading, which can also\n\t\t\t// happen if the size has been changed while detached from the DOM.\n\t\t\thandler();\n\t\t});\n\n\t\treturn iframe;\n\t}\n\n\tfunction addResizeListener(node, listener, chart) {\n\t\tvar stub = node._chartjs = {\n\t\t\tticking: false\n\t\t};\n\n\t\t// Throttle the callback notification until the next animation frame.\n\t\tvar notify = function() {\n\t\t\tif (!stub.ticking) {\n\t\t\t\tstub.ticking = true;\n\t\t\t\thelpers.requestAnimFrame.call(window, function() {\n\t\t\t\t\tif (stub.resizer) {\n\t\t\t\t\t\tstub.ticking = false;\n\t\t\t\t\t\treturn listener(createEvent('resize', chart));\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t}\n\t\t};\n\n\t\t// Let's keep track of this added iframe and thus avoid DOM query when removing it.\n\t\tstub.resizer = createResizer(notify);\n\n\t\tnode.insertBefore(stub.resizer, node.firstChild);\n\t}\n\n\tfunction removeResizeListener(node) {\n\t\tif (!node || !node._chartjs) {\n\t\t\treturn;\n\t\t}\n\n\t\tvar resizer = node._chartjs.resizer;\n\t\tif (resizer) {\n\t\t\tresizer.parentNode.removeChild(resizer);\n\t\t\tnode._chartjs.resizer = null;\n\t\t}\n\n\t\tdelete node._chartjs;\n\t}\n\n\treturn {\n\t\tacquireContext: function(item, config) {\n\t\t\tif (typeof item === 'string') {\n\t\t\t\titem = document.getElementById(item);\n\t\t\t} else if (item.length) {\n\t\t\t\t// Support for array based queries (such as jQuery)\n\t\t\t\titem = item[0];\n\t\t\t}\n\n\t\t\tif (item && item.canvas) {\n\t\t\t\t// Support for any object associated to a canvas (including a context2d)\n\t\t\t\titem = item.canvas;\n\t\t\t}\n\n\t\t\t// To prevent canvas fingerprinting, some add-ons undefine the getContext\n\t\t\t// method, for example: https://github.com/kkapsner/CanvasBlocker\n\t\t\t// https://github.com/chartjs/Chart.js/issues/2807\n\t\t\tvar context = item && item.getContext && item.getContext('2d');\n\n\t\t\t// `instanceof HTMLCanvasElement/CanvasRenderingContext2D` fails when the item is\n\t\t\t// inside an iframe or when running in a protected environment. We could guess the\n\t\t\t// types from their toString() value but let's keep things flexible and assume it's\n\t\t\t// a sufficient condition if the item has a context2D which has item as `canvas`.\n\t\t\t// https://github.com/chartjs/Chart.js/issues/3887\n\t\t\t// https://github.com/chartjs/Chart.js/issues/4102\n\t\t\t// https://github.com/chartjs/Chart.js/issues/4152\n\t\t\tif (context && context.canvas === item) {\n\t\t\t\tinitCanvas(item, config);\n\t\t\t\treturn context;\n\t\t\t}\n\n\t\t\treturn null;\n\t\t},\n\n\t\treleaseContext: function(context) {\n\t\t\tvar canvas = context.canvas;\n\t\t\tif (!canvas._chartjs) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tvar initial = canvas._chartjs.initial;\n\t\t\t['height', 'width'].forEach(function(prop) {\n\t\t\t\tvar value = initial[prop];\n\t\t\t\tif (value === undefined || value === null) {\n\t\t\t\t\tcanvas.removeAttribute(prop);\n\t\t\t\t} else {\n\t\t\t\t\tcanvas.setAttribute(prop, value);\n\t\t\t\t}\n\t\t\t});\n\n\t\t\thelpers.each(initial.style || {}, function(value, key) {\n\t\t\t\tcanvas.style[key] = value;\n\t\t\t});\n\n\t\t\t// The canvas render size might have been changed (and thus the state stack discarded),\n\t\t\t// we can't use save() and restore() to restore the initial state. So make sure that at\n\t\t\t// least the canvas context is reset to the default state by setting the canvas width.\n\t\t\t// https://www.w3.org/TR/2011/WD-html5-20110525/the-canvas-element.html\n\t\t\tcanvas.width = canvas.width;\n\n\t\t\tdelete canvas._chartjs;\n\t\t},\n\n\t\taddEventListener: function(chart, type, listener) {\n\t\t\tvar canvas = chart.canvas;\n\t\t\tif (type === 'resize') {\n\t\t\t\t// Note: the resize event is not supported on all browsers.\n\t\t\t\taddResizeListener(canvas.parentNode, listener, chart);\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tvar stub = listener._chartjs || (listener._chartjs = {});\n\t\t\tvar proxies = stub.proxies || (stub.proxies = {});\n\t\t\tvar proxy = proxies[chart.id + '_' + type] = function(event) {\n\t\t\t\tlistener(fromNativeEvent(event, chart));\n\t\t\t};\n\n\t\t\thelpers.addEvent(canvas, type, proxy);\n\t\t},\n\n\t\tremoveEventListener: function(chart, type, listener) {\n\t\t\tvar canvas = chart.canvas;\n\t\t\tif (type === 'resize') {\n\t\t\t\t// Note: the resize event is not supported on all browsers.\n\t\t\t\tremoveResizeListener(canvas.parentNode, listener);\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tvar stub = listener._chartjs || {};\n\t\t\tvar proxies = stub.proxies || {};\n\t\t\tvar proxy = proxies[chart.id + '_' + type];\n\t\t\tif (!proxy) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\thelpers.removeEvent(canvas, type, proxy);\n\t\t}\n\t};\n};\n\n},{}],40:[function(require,module,exports){\n'use strict';\n\n// By default, select the browser (DOM) platform.\n// @TODO Make possible to select another platform at build time.\nvar implementation = require(39);\n\nmodule.exports = function(Chart) {\n\t/**\n\t * @namespace Chart.platform\n\t * @see https://chartjs.gitbooks.io/proposals/content/Platform.html\n\t * @since 2.4.0\n\t */\n\tChart.platform = {\n\t\t/**\n\t\t * Called at chart construction time, returns a context2d instance implementing\n\t\t * the [W3C Canvas 2D Context API standard]{@link https://www.w3.org/TR/2dcontext/}.\n\t\t * @param {*} item - The native item from which to acquire context (platform specific)\n\t\t * @param {Object} options - The chart options\n\t\t * @returns {CanvasRenderingContext2D} context2d instance\n\t\t */\n\t\tacquireContext: function() {},\n\n\t\t/**\n\t\t * Called at chart destruction time, releases any resources associated to the context\n\t\t * previously returned by the acquireContext() method.\n\t\t * @param {CanvasRenderingContext2D} context - The context2d instance\n\t\t * @returns {Boolean} true if the method succeeded, else false\n\t\t */\n\t\treleaseContext: function() {},\n\n\t\t/**\n\t\t * Registers the specified listener on the given chart.\n\t\t * @param {Chart} chart - Chart from which to listen for event\n\t\t * @param {String} type - The ({@link IEvent}) type to listen for\n\t\t * @param {Function} listener - Receives a notification (an object that implements\n\t\t * the {@link IEvent} interface) when an event of the specified type occurs.\n\t\t */\n\t\taddEventListener: function() {},\n\n\t\t/**\n\t\t * Removes the specified listener previously registered with addEventListener.\n\t\t * @param {Chart} chart -Chart from which to remove the listener\n\t\t * @param {String} type - The ({@link IEvent}) type to remove\n\t\t * @param {Function} listener - The listener function to remove from the event target.\n\t\t */\n\t\tremoveEventListener: function() {}\n\t};\n\n\t/**\n\t * @interface IPlatform\n\t * Allows abstracting platform dependencies away from the chart\n\t * @borrows Chart.platform.acquireContext as acquireContext\n\t * @borrows Chart.platform.releaseContext as releaseContext\n\t * @borrows Chart.platform.addEventListener as addEventListener\n\t * @borrows Chart.platform.removeEventListener as removeEventListener\n\t */\n\n\t/**\n\t * @interface IEvent\n\t * @prop {String} type - The event type name, possible values are:\n\t * 'contextmenu', 'mouseenter', 'mousedown', 'mousemove', 'mouseup', 'mouseout',\n\t * 'click', 'dblclick', 'keydown', 'keypress', 'keyup' and 'resize'\n\t * @prop {*} native - The original native event (null for emulated events, e.g. 'resize')\n\t * @prop {Number} x - The mouse x position, relative to the canvas (null for incompatible events)\n\t * @prop {Number} y - The mouse y position, relative to the canvas (null for incompatible events)\n\t */\n\n\tChart.helpers.extend(Chart.platform, implementation(Chart));\n};\n\n},{\"39\":39}],41:[function(require,module,exports){\n'use strict';\n\nmodule.exports = function(Chart) {\n\t/**\n\t * Plugin based on discussion from the following Chart.js issues:\n\t * @see https://github.com/chartjs/Chart.js/issues/2380#issuecomment-279961569\n\t * @see https://github.com/chartjs/Chart.js/issues/2440#issuecomment-256461897\n\t */\n\tChart.defaults.global.plugins.filler = {\n\t\tpropagate: true\n\t};\n\n\tvar defaults = Chart.defaults;\n\tvar helpers = Chart.helpers;\n\tvar mappers = {\n\t\tdataset: function(source) {\n\t\t\tvar index = source.fill;\n\t\t\tvar chart = source.chart;\n\t\t\tvar meta = chart.getDatasetMeta(index);\n\t\t\tvar visible = meta && chart.isDatasetVisible(index);\n\t\t\tvar points = (visible && meta.dataset._children) || [];\n\n\t\t\treturn !points.length? null : function(point, i) {\n\t\t\t\treturn points[i]._view || null;\n\t\t\t};\n\t\t},\n\n\t\tboundary: function(source) {\n\t\t\tvar boundary = source.boundary;\n\t\t\tvar x = boundary? boundary.x : null;\n\t\t\tvar y = boundary? boundary.y : null;\n\n\t\t\treturn function(point) {\n\t\t\t\treturn {\n\t\t\t\t\tx: x === null? point.x : x,\n\t\t\t\t\ty: y === null? point.y : y,\n\t\t\t\t};\n\t\t\t};\n\t\t}\n\t};\n\n\t// @todo if (fill[0] === '#')\n\tfunction decodeFill(el, index, count) {\n\t\tvar model = el._model || {};\n\t\tvar fill = model.fill;\n\t\tvar target;\n\n\t\tif (fill === undefined) {\n\t\t\tfill = !!model.backgroundColor;\n\t\t}\n\n\t\tif (fill === false || fill === null) {\n\t\t\treturn false;\n\t\t}\n\n\t\tif (fill === true) {\n\t\t\treturn 'origin';\n\t\t}\n\n\t\ttarget = parseFloat(fill, 10);\n\t\tif (isFinite(target) && Math.floor(target) === target) {\n\t\t\tif (fill[0] === '-' || fill[0] === '+') {\n\t\t\t\ttarget = index + target;\n\t\t\t}\n\n\t\t\tif (target === index || target < 0 || target >= count) {\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\treturn target;\n\t\t}\n\n\t\tswitch (fill) {\n\t\t// compatibility\n\t\tcase 'bottom':\n\t\t\treturn 'start';\n\t\tcase 'top':\n\t\t\treturn 'end';\n\t\tcase 'zero':\n\t\t\treturn 'origin';\n\t\t// supported boundaries\n\t\tcase 'origin':\n\t\tcase 'start':\n\t\tcase 'end':\n\t\t\treturn fill;\n\t\t// invalid fill values\n\t\tdefault:\n\t\t\treturn false;\n\t\t}\n\t}\n\n\tfunction computeBoundary(source) {\n\t\tvar model = source.el._model || {};\n\t\tvar scale = source.el._scale || {};\n\t\tvar fill = source.fill;\n\t\tvar target = null;\n\t\tvar horizontal;\n\n\t\tif (isFinite(fill)) {\n\t\t\treturn null;\n\t\t}\n\n\t\t// Backward compatibility: until v3, we still need to support boundary values set on\n\t\t// the model (scaleTop, scaleBottom and scaleZero) because some external plugins and\n\t\t// controllers might still use it (e.g. the Smith chart).\n\n\t\tif (fill === 'start') {\n\t\t\ttarget = model.scaleBottom === undefined? scale.bottom : model.scaleBottom;\n\t\t} else if (fill === 'end') {\n\t\t\ttarget = model.scaleTop === undefined? scale.top : model.scaleTop;\n\t\t} else if (model.scaleZero !== undefined) {\n\t\t\ttarget = model.scaleZero;\n\t\t} else if (scale.getBasePosition) {\n\t\t\ttarget = scale.getBasePosition();\n\t\t} else if (scale.getBasePixel) {\n\t\t\ttarget = scale.getBasePixel();\n\t\t}\n\n\t\tif (target !== undefined && target !== null) {\n\t\t\tif (target.x !== undefined && target.y !== undefined) {\n\t\t\t\treturn target;\n\t\t\t}\n\n\t\t\tif (typeof target === 'number' && isFinite(target)) {\n\t\t\t\thorizontal = scale.isHorizontal();\n\t\t\t\treturn {\n\t\t\t\t\tx: horizontal? target : null,\n\t\t\t\t\ty: horizontal? null : target\n\t\t\t\t};\n\t\t\t}\n\t\t}\n\n\t\treturn null;\n\t}\n\n\tfunction resolveTarget(sources, index, propagate) {\n\t\tvar source = sources[index];\n\t\tvar fill = source.fill;\n\t\tvar visited = [index];\n\t\tvar target;\n\n\t\tif (!propagate) {\n\t\t\treturn fill;\n\t\t}\n\n\t\twhile (fill !== false && visited.indexOf(fill) === -1) {\n\t\t\tif (!isFinite(fill)) {\n\t\t\t\treturn fill;\n\t\t\t}\n\n\t\t\ttarget = sources[fill];\n\t\t\tif (!target) {\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\tif (target.visible) {\n\t\t\t\treturn fill;\n\t\t\t}\n\n\t\t\tvisited.push(fill);\n\t\t\tfill = target.fill;\n\t\t}\n\n\t\treturn false;\n\t}\n\n\tfunction createMapper(source) {\n\t\tvar fill = source.fill;\n\t\tvar type = 'dataset';\n\n\t\tif (fill === false) {\n\t\t\treturn null;\n\t\t}\n\n\t\tif (!isFinite(fill)) {\n\t\t\ttype = 'boundary';\n\t\t}\n\n\t\treturn mappers[type](source);\n\t}\n\n\tfunction isDrawable(point) {\n\t\treturn point && !point.skip;\n\t}\n\n\tfunction drawArea(ctx, curve0, curve1, len0, len1) {\n\t\tvar i;\n\n\t\tif (!len0 || !len1) {\n\t\t\treturn;\n\t\t}\n\n\t\t// building first area curve (normal)\n\t\tctx.moveTo(curve0[0].x, curve0[0].y);\n\t\tfor (i=1; i<len0; ++i) {\n\t\t\thelpers.canvas.lineTo(ctx, curve0[i-1], curve0[i]);\n\t\t}\n\n\t\t// joining the two area curves\n\t\tctx.lineTo(curve1[len1-1].x, curve1[len1-1].y);\n\n\t\t// building opposite area curve (reverse)\n\t\tfor (i=len1-1; i>0; --i) {\n\t\t\thelpers.canvas.lineTo(ctx, curve1[i], curve1[i-1], true);\n\t\t}\n\t}\n\n\tfunction doFill(ctx, points, mapper, view, color, loop) {\n\t\tvar count = points.length;\n\t\tvar span = view.spanGaps;\n\t\tvar curve0 = [];\n\t\tvar curve1 = [];\n\t\tvar len0 = 0;\n\t\tvar len1 = 0;\n\t\tvar i, ilen, index, p0, p1, d0, d1;\n\n\t\tctx.beginPath();\n\n\t\tfor (i = 0, ilen = (count + !!loop); i < ilen; ++i) {\n\t\t\tindex = i%count;\n\t\t\tp0 = points[index]._view;\n\t\t\tp1 = mapper(p0, index, view);\n\t\t\td0 = isDrawable(p0);\n\t\t\td1 = isDrawable(p1);\n\n\t\t\tif (d0 && d1) {\n\t\t\t\tlen0 = curve0.push(p0);\n\t\t\t\tlen1 = curve1.push(p1);\n\t\t\t} else if (len0 && len1) {\n\t\t\t\tif (!span) {\n\t\t\t\t\tdrawArea(ctx, curve0, curve1, len0, len1);\n\t\t\t\t\tlen0 = len1 = 0;\n\t\t\t\t\tcurve0 = [];\n\t\t\t\t\tcurve1 = [];\n\t\t\t\t} else {\n\t\t\t\t\tif (d0) {\n\t\t\t\t\t\tcurve0.push(p0);\n\t\t\t\t\t}\n\t\t\t\t\tif (d1) {\n\t\t\t\t\t\tcurve1.push(p1);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tdrawArea(ctx, curve0, curve1, len0, len1);\n\n\t\tctx.closePath();\n\t\tctx.fillStyle = color;\n\t\tctx.fill();\n\t}\n\n\treturn {\n\t\tid: 'filler',\n\n\t\tafterDatasetsUpdate: function(chart, options) {\n\t\t\tvar count = (chart.data.datasets || []).length;\n\t\t\tvar propagate = options.propagate;\n\t\t\tvar sources = [];\n\t\t\tvar meta, i, el, source;\n\n\t\t\tfor (i = 0; i < count; ++i) {\n\t\t\t\tmeta = chart.getDatasetMeta(i);\n\t\t\t\tel = meta.dataset;\n\t\t\t\tsource = null;\n\n\t\t\t\tif (el && el._model && el instanceof Chart.elements.Line) {\n\t\t\t\t\tsource = {\n\t\t\t\t\t\tvisible: chart.isDatasetVisible(i),\n\t\t\t\t\t\tfill: decodeFill(el, i, count),\n\t\t\t\t\t\tchart: chart,\n\t\t\t\t\t\tel: el\n\t\t\t\t\t};\n\t\t\t\t}\n\n\t\t\t\tmeta.$filler = source;\n\t\t\t\tsources.push(source);\n\t\t\t}\n\n\t\t\tfor (i=0; i<count; ++i) {\n\t\t\t\tsource = sources[i];\n\t\t\t\tif (!source) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\tsource.fill = resolveTarget(sources, i, propagate);\n\t\t\t\tsource.boundary = computeBoundary(source);\n\t\t\t\tsource.mapper = createMapper(source);\n\t\t\t}\n\t\t},\n\n\t\tbeforeDatasetDraw: function(chart, args) {\n\t\t\tvar meta = args.meta.$filler;\n\t\t\tif (!meta) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tvar el = meta.el;\n\t\t\tvar view = el._view;\n\t\t\tvar points = el._children || [];\n\t\t\tvar mapper = meta.mapper;\n\t\t\tvar color = view.backgroundColor || defaults.global.defaultColor;\n\n\t\t\tif (mapper && color && points.length) {\n\t\t\t\tdoFill(chart.ctx, points, mapper, view, color, el._loop);\n\t\t\t}\n\t\t}\n\t};\n};\n\n},{}],42:[function(require,module,exports){\n'use strict';\n\nmodule.exports = function(Chart) {\n\n\tvar helpers = Chart.helpers;\n\tvar layout = Chart.layoutService;\n\tvar noop = helpers.noop;\n\n\tChart.defaults.global.legend = {\n\t\tdisplay: true,\n\t\tposition: 'top',\n\t\tfullWidth: true,\n\t\treverse: false,\n\t\tweight: 1000,\n\n\t\t// a callback that will handle\n\t\tonClick: function(e, legendItem) {\n\t\t\tvar index = legendItem.datasetIndex;\n\t\t\tvar ci = this.chart;\n\t\t\tvar meta = ci.getDatasetMeta(index);\n\n\t\t\t// See controller.isDatasetVisible comment\n\t\t\tmeta.hidden = meta.hidden === null? !ci.data.datasets[index].hidden : null;\n\n\t\t\t// We hid a dataset ... rerender the chart\n\t\t\tci.update();\n\t\t},\n\n\t\tonHover: null,\n\n\t\tlabels: {\n\t\t\tboxWidth: 40,\n\t\t\tpadding: 10,\n\t\t\t// Generates labels shown in the legend\n\t\t\t// Valid properties to return:\n\t\t\t// text : text to display\n\t\t\t// fillStyle : fill of coloured box\n\t\t\t// strokeStyle: stroke of coloured box\n\t\t\t// hidden : if this legend item refers to a hidden item\n\t\t\t// lineCap : cap style for line\n\t\t\t// lineDash\n\t\t\t// lineDashOffset :\n\t\t\t// lineJoin :\n\t\t\t// lineWidth :\n\t\t\tgenerateLabels: function(chart) {\n\t\t\t\tvar data = chart.data;\n\t\t\t\treturn helpers.isArray(data.datasets) ? data.datasets.map(function(dataset, i) {\n\t\t\t\t\treturn {\n\t\t\t\t\t\ttext: dataset.label,\n\t\t\t\t\t\tfillStyle: (!helpers.isArray(dataset.backgroundColor) ? dataset.backgroundColor : dataset.backgroundColor[0]),\n\t\t\t\t\t\thidden: !chart.isDatasetVisible(i),\n\t\t\t\t\t\tlineCap: dataset.borderCapStyle,\n\t\t\t\t\t\tlineDash: dataset.borderDash,\n\t\t\t\t\t\tlineDashOffset: dataset.borderDashOffset,\n\t\t\t\t\t\tlineJoin: dataset.borderJoinStyle,\n\t\t\t\t\t\tlineWidth: dataset.borderWidth,\n\t\t\t\t\t\tstrokeStyle: dataset.borderColor,\n\t\t\t\t\t\tpointStyle: dataset.pointStyle,\n\n\t\t\t\t\t\t// Below is extra data used for toggling the datasets\n\t\t\t\t\t\tdatasetIndex: i\n\t\t\t\t\t};\n\t\t\t\t}, this) : [];\n\t\t\t}\n\t\t}\n\t};\n\n\t/**\n\t * Helper function to get the box width based on the usePointStyle option\n\t * @param labelopts {Object} the label options on the legend\n\t * @param fontSize {Number} the label font size\n\t * @return {Number} width of the color box area\n\t */\n\tfunction getBoxWidth(labelOpts, fontSize) {\n\t\treturn labelOpts.usePointStyle ?\n\t\t\tfontSize * Math.SQRT2 :\n\t\t\tlabelOpts.boxWidth;\n\t}\n\n\tChart.Legend = Chart.Element.extend({\n\n\t\tinitialize: function(config) {\n\t\t\thelpers.extend(this, config);\n\n\t\t\t// Contains hit boxes for each dataset (in dataset order)\n\t\t\tthis.legendHitBoxes = [];\n\n\t\t\t// Are we in doughnut mode which has a different data type\n\t\t\tthis.doughnutMode = false;\n\t\t},\n\n\t\t// These methods are ordered by lifecycle. Utilities then follow.\n\t\t// Any function defined here is inherited by all legend types.\n\t\t// Any function can be extended by the legend type\n\n\t\tbeforeUpdate: noop,\n\t\tupdate: function(maxWidth, maxHeight, margins) {\n\t\t\tvar me = this;\n\n\t\t\t// Update Lifecycle - Probably don't want to ever extend or overwrite this function ;)\n\t\t\tme.beforeUpdate();\n\n\t\t\t// Absorb the master measurements\n\t\t\tme.maxWidth = maxWidth;\n\t\t\tme.maxHeight = maxHeight;\n\t\t\tme.margins = margins;\n\n\t\t\t// Dimensions\n\t\t\tme.beforeSetDimensions();\n\t\t\tme.setDimensions();\n\t\t\tme.afterSetDimensions();\n\t\t\t// Labels\n\t\t\tme.beforeBuildLabels();\n\t\t\tme.buildLabels();\n\t\t\tme.afterBuildLabels();\n\n\t\t\t// Fit\n\t\t\tme.beforeFit();\n\t\t\tme.fit();\n\t\t\tme.afterFit();\n\t\t\t//\n\t\t\tme.afterUpdate();\n\n\t\t\treturn me.minSize;\n\t\t},\n\t\tafterUpdate: noop,\n\n\t\t//\n\n\t\tbeforeSetDimensions: noop,\n\t\tsetDimensions: function() {\n\t\t\tvar me = this;\n\t\t\t// Set the unconstrained dimension before label rotation\n\t\t\tif (me.isHorizontal()) {\n\t\t\t\t// Reset position before calculating rotation\n\t\t\t\tme.width = me.maxWidth;\n\t\t\t\tme.left = 0;\n\t\t\t\tme.right = me.width;\n\t\t\t} else {\n\t\t\t\tme.height = me.maxHeight;\n\n\t\t\t\t// Reset position before calculating rotation\n\t\t\t\tme.top = 0;\n\t\t\t\tme.bottom = me.height;\n\t\t\t}\n\n\t\t\t// Reset padding\n\t\t\tme.paddingLeft = 0;\n\t\t\tme.paddingTop = 0;\n\t\t\tme.paddingRight = 0;\n\t\t\tme.paddingBottom = 0;\n\n\t\t\t// Reset minSize\n\t\t\tme.minSize = {\n\t\t\t\twidth: 0,\n\t\t\t\theight: 0\n\t\t\t};\n\t\t},\n\t\tafterSetDimensions: noop,\n\n\t\t//\n\n\t\tbeforeBuildLabels: noop,\n\t\tbuildLabels: function() {\n\t\t\tvar me = this;\n\t\t\tvar labelOpts = me.options.labels;\n\t\t\tvar legendItems = labelOpts.generateLabels.call(me, me.chart);\n\n\t\t\tif (labelOpts.filter) {\n\t\t\t\tlegendItems = legendItems.filter(function(item) {\n\t\t\t\t\treturn labelOpts.filter(item, me.chart.data);\n\t\t\t\t});\n\t\t\t}\n\n\t\t\tif (me.options.reverse) {\n\t\t\t\tlegendItems.reverse();\n\t\t\t}\n\n\t\t\tme.legendItems = legendItems;\n\t\t},\n\t\tafterBuildLabels: noop,\n\n\t\t//\n\n\t\tbeforeFit: noop,\n\t\tfit: function() {\n\t\t\tvar me = this;\n\t\t\tvar opts = me.options;\n\t\t\tvar labelOpts = opts.labels;\n\t\t\tvar display = opts.display;\n\n\t\t\tvar ctx = me.ctx;\n\n\t\t\tvar globalDefault = Chart.defaults.global,\n\t\t\t\titemOrDefault = helpers.getValueOrDefault,\n\t\t\t\tfontSize = itemOrDefault(labelOpts.fontSize, globalDefault.defaultFontSize),\n\t\t\t\tfontStyle = itemOrDefault(labelOpts.fontStyle, globalDefault.defaultFontStyle),\n\t\t\t\tfontFamily = itemOrDefault(labelOpts.fontFamily, globalDefault.defaultFontFamily),\n\t\t\t\tlabelFont = helpers.fontString(fontSize, fontStyle, fontFamily);\n\n\t\t\t// Reset hit boxes\n\t\t\tvar hitboxes = me.legendHitBoxes = [];\n\n\t\t\tvar minSize = me.minSize;\n\t\t\tvar isHorizontal = me.isHorizontal();\n\n\t\t\tif (isHorizontal) {\n\t\t\t\tminSize.width = me.maxWidth; // fill all the width\n\t\t\t\tminSize.height = display ? 10 : 0;\n\t\t\t} else {\n\t\t\t\tminSize.width = display ? 10 : 0;\n\t\t\t\tminSize.height = me.maxHeight; // fill all the height\n\t\t\t}\n\n\t\t\t// Increase sizes here\n\t\t\tif (display) {\n\t\t\t\tctx.font = labelFont;\n\n\t\t\t\tif (isHorizontal) {\n\t\t\t\t\t// Labels\n\n\t\t\t\t\t// Width of each line of legend boxes. Labels wrap onto multiple lines when there are too many to fit on one\n\t\t\t\t\tvar lineWidths = me.lineWidths = [0];\n\t\t\t\t\tvar totalHeight = me.legendItems.length ? fontSize + (labelOpts.padding) : 0;\n\n\t\t\t\t\tctx.textAlign = 'left';\n\t\t\t\t\tctx.textBaseline = 'top';\n\n\t\t\t\t\thelpers.each(me.legendItems, function(legendItem, i) {\n\t\t\t\t\t\tvar boxWidth = getBoxWidth(labelOpts, fontSize);\n\t\t\t\t\t\tvar width = boxWidth + (fontSize / 2) + ctx.measureText(legendItem.text).width;\n\n\t\t\t\t\t\tif (lineWidths[lineWidths.length - 1] + width + labelOpts.padding >= me.width) {\n\t\t\t\t\t\t\ttotalHeight += fontSize + (labelOpts.padding);\n\t\t\t\t\t\t\tlineWidths[lineWidths.length] = me.left;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// Store the hitbox width and height here. Final position will be updated in `draw`\n\t\t\t\t\t\thitboxes[i] = {\n\t\t\t\t\t\t\tleft: 0,\n\t\t\t\t\t\t\ttop: 0,\n\t\t\t\t\t\t\twidth: width,\n\t\t\t\t\t\t\theight: fontSize\n\t\t\t\t\t\t};\n\n\t\t\t\t\t\tlineWidths[lineWidths.length - 1] += width + labelOpts.padding;\n\t\t\t\t\t});\n\n\t\t\t\t\tminSize.height += totalHeight;\n\n\t\t\t\t} else {\n\t\t\t\t\tvar vPadding = labelOpts.padding;\n\t\t\t\t\tvar columnWidths = me.columnWidths = [];\n\t\t\t\t\tvar totalWidth = labelOpts.padding;\n\t\t\t\t\tvar currentColWidth = 0;\n\t\t\t\t\tvar currentColHeight = 0;\n\t\t\t\t\tvar itemHeight = fontSize + vPadding;\n\n\t\t\t\t\thelpers.each(me.legendItems, function(legendItem, i) {\n\t\t\t\t\t\tvar boxWidth = getBoxWidth(labelOpts, fontSize);\n\t\t\t\t\t\tvar itemWidth = boxWidth + (fontSize / 2) + ctx.measureText(legendItem.text).width;\n\n\t\t\t\t\t\t// If too tall, go to new column\n\t\t\t\t\t\tif (currentColHeight + itemHeight > minSize.height) {\n\t\t\t\t\t\t\ttotalWidth += currentColWidth + labelOpts.padding;\n\t\t\t\t\t\t\tcolumnWidths.push(currentColWidth); // previous column width\n\n\t\t\t\t\t\t\tcurrentColWidth = 0;\n\t\t\t\t\t\t\tcurrentColHeight = 0;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// Get max width\n\t\t\t\t\t\tcurrentColWidth = Math.max(currentColWidth, itemWidth);\n\t\t\t\t\t\tcurrentColHeight += itemHeight;\n\n\t\t\t\t\t\t// Store the hitbox width and height here. Final position will be updated in `draw`\n\t\t\t\t\t\thitboxes[i] = {\n\t\t\t\t\t\t\tleft: 0,\n\t\t\t\t\t\t\ttop: 0,\n\t\t\t\t\t\t\twidth: itemWidth,\n\t\t\t\t\t\t\theight: fontSize\n\t\t\t\t\t\t};\n\t\t\t\t\t});\n\n\t\t\t\t\ttotalWidth += currentColWidth;\n\t\t\t\t\tcolumnWidths.push(currentColWidth);\n\t\t\t\t\tminSize.width += totalWidth;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tme.width = minSize.width;\n\t\t\tme.height = minSize.height;\n\t\t},\n\t\tafterFit: noop,\n\n\t\t// Shared Methods\n\t\tisHorizontal: function() {\n\t\t\treturn this.options.position === 'top' || this.options.position === 'bottom';\n\t\t},\n\n\t\t// Actually draw the legend on the canvas\n\t\tdraw: function() {\n\t\t\tvar me = this;\n\t\t\tvar opts = me.options;\n\t\t\tvar labelOpts = opts.labels;\n\t\t\tvar globalDefault = Chart.defaults.global,\n\t\t\t\tlineDefault = globalDefault.elements.line,\n\t\t\t\tlegendWidth = me.width,\n\t\t\t\tlineWidths = me.lineWidths;\n\n\t\t\tif (opts.display) {\n\t\t\t\tvar ctx = me.ctx,\n\t\t\t\t\tcursor,\n\t\t\t\t\titemOrDefault = helpers.getValueOrDefault,\n\t\t\t\t\tfontColor = itemOrDefault(labelOpts.fontColor, globalDefault.defaultFontColor),\n\t\t\t\t\tfontSize = itemOrDefault(labelOpts.fontSize, globalDefault.defaultFontSize),\n\t\t\t\t\tfontStyle = itemOrDefault(labelOpts.fontStyle, globalDefault.defaultFontStyle),\n\t\t\t\t\tfontFamily = itemOrDefault(labelOpts.fontFamily, globalDefault.defaultFontFamily),\n\t\t\t\t\tlabelFont = helpers.fontString(fontSize, fontStyle, fontFamily);\n\n\t\t\t\t// Canvas setup\n\t\t\t\tctx.textAlign = 'left';\n\t\t\t\tctx.textBaseline = 'top';\n\t\t\t\tctx.lineWidth = 0.5;\n\t\t\t\tctx.strokeStyle = fontColor; // for strikethrough effect\n\t\t\t\tctx.fillStyle = fontColor; // render in correct colour\n\t\t\t\tctx.font = labelFont;\n\n\t\t\t\tvar boxWidth = getBoxWidth(labelOpts, fontSize),\n\t\t\t\t\thitboxes = me.legendHitBoxes;\n\n\t\t\t\t// current position\n\t\t\t\tvar drawLegendBox = function(x, y, legendItem) {\n\t\t\t\t\tif (isNaN(boxWidth) || boxWidth <= 0) {\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\n\t\t\t\t\t// Set the ctx for the box\n\t\t\t\t\tctx.save();\n\n\t\t\t\t\tctx.fillStyle = itemOrDefault(legendItem.fillStyle, globalDefault.defaultColor);\n\t\t\t\t\tctx.lineCap = itemOrDefault(legendItem.lineCap, lineDefault.borderCapStyle);\n\t\t\t\t\tctx.lineDashOffset = itemOrDefault(legendItem.lineDashOffset, lineDefault.borderDashOffset);\n\t\t\t\t\tctx.lineJoin = itemOrDefault(legendItem.lineJoin, lineDefault.borderJoinStyle);\n\t\t\t\t\tctx.lineWidth = itemOrDefault(legendItem.lineWidth, lineDefault.borderWidth);\n\t\t\t\t\tctx.strokeStyle = itemOrDefault(legendItem.strokeStyle, globalDefault.defaultColor);\n\t\t\t\t\tvar isLineWidthZero = (itemOrDefault(legendItem.lineWidth, lineDefault.borderWidth) === 0);\n\n\t\t\t\t\tif (ctx.setLineDash) {\n\t\t\t\t\t\t// IE 9 and 10 do not support line dash\n\t\t\t\t\t\tctx.setLineDash(itemOrDefault(legendItem.lineDash, lineDefault.borderDash));\n\t\t\t\t\t}\n\n\t\t\t\t\tif (opts.labels && opts.labels.usePointStyle) {\n\t\t\t\t\t\t// Recalculate x and y for drawPoint() because its expecting\n\t\t\t\t\t\t// x and y to be center of figure (instead of top left)\n\t\t\t\t\t\tvar radius = fontSize * Math.SQRT2 / 2;\n\t\t\t\t\t\tvar offSet = radius / Math.SQRT2;\n\t\t\t\t\t\tvar centerX = x + offSet;\n\t\t\t\t\t\tvar centerY = y + offSet;\n\n\t\t\t\t\t\t// Draw pointStyle as legend symbol\n\t\t\t\t\t\tChart.canvasHelpers.drawPoint(ctx, legendItem.pointStyle, radius, centerX, centerY);\n\t\t\t\t\t} else {\n\t\t\t\t\t\t// Draw box as legend symbol\n\t\t\t\t\t\tif (!isLineWidthZero) {\n\t\t\t\t\t\t\tctx.strokeRect(x, y, boxWidth, fontSize);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tctx.fillRect(x, y, boxWidth, fontSize);\n\t\t\t\t\t}\n\n\t\t\t\t\tctx.restore();\n\t\t\t\t};\n\t\t\t\tvar fillText = function(x, y, legendItem, textWidth) {\n\t\t\t\t\tctx.fillText(legendItem.text, boxWidth + (fontSize / 2) + x, y);\n\n\t\t\t\t\tif (legendItem.hidden) {\n\t\t\t\t\t\t// Strikethrough the text if hidden\n\t\t\t\t\t\tctx.beginPath();\n\t\t\t\t\t\tctx.lineWidth = 2;\n\t\t\t\t\t\tctx.moveTo(boxWidth + (fontSize / 2) + x, y + (fontSize / 2));\n\t\t\t\t\t\tctx.lineTo(boxWidth + (fontSize / 2) + x + textWidth, y + (fontSize / 2));\n\t\t\t\t\t\tctx.stroke();\n\t\t\t\t\t}\n\t\t\t\t};\n\n\t\t\t\t// Horizontal\n\t\t\t\tvar isHorizontal = me.isHorizontal();\n\t\t\t\tif (isHorizontal) {\n\t\t\t\t\tcursor = {\n\t\t\t\t\t\tx: me.left + ((legendWidth - lineWidths[0]) / 2),\n\t\t\t\t\t\ty: me.top + labelOpts.padding,\n\t\t\t\t\t\tline: 0\n\t\t\t\t\t};\n\t\t\t\t} else {\n\t\t\t\t\tcursor = {\n\t\t\t\t\t\tx: me.left + labelOpts.padding,\n\t\t\t\t\t\ty: me.top + labelOpts.padding,\n\t\t\t\t\t\tline: 0\n\t\t\t\t\t};\n\t\t\t\t}\n\n\t\t\t\tvar itemHeight = fontSize + labelOpts.padding;\n\t\t\t\thelpers.each(me.legendItems, function(legendItem, i) {\n\t\t\t\t\tvar textWidth = ctx.measureText(legendItem.text).width,\n\t\t\t\t\t\twidth = boxWidth + (fontSize / 2) + textWidth,\n\t\t\t\t\t\tx = cursor.x,\n\t\t\t\t\t\ty = cursor.y;\n\n\t\t\t\t\tif (isHorizontal) {\n\t\t\t\t\t\tif (x + width >= legendWidth) {\n\t\t\t\t\t\t\ty = cursor.y += itemHeight;\n\t\t\t\t\t\t\tcursor.line++;\n\t\t\t\t\t\t\tx = cursor.x = me.left + ((legendWidth - lineWidths[cursor.line]) / 2);\n\t\t\t\t\t\t}\n\t\t\t\t\t} else if (y + itemHeight > me.bottom) {\n\t\t\t\t\t\tx = cursor.x = x + me.columnWidths[cursor.line] + labelOpts.padding;\n\t\t\t\t\t\ty = cursor.y = me.top + labelOpts.padding;\n\t\t\t\t\t\tcursor.line++;\n\t\t\t\t\t}\n\n\t\t\t\t\tdrawLegendBox(x, y, legendItem);\n\n\t\t\t\t\thitboxes[i].left = x;\n\t\t\t\t\thitboxes[i].top = y;\n\n\t\t\t\t\t// Fill the actual label\n\t\t\t\t\tfillText(x, y, legendItem, textWidth);\n\n\t\t\t\t\tif (isHorizontal) {\n\t\t\t\t\t\tcursor.x += width + (labelOpts.padding);\n\t\t\t\t\t} else {\n\t\t\t\t\t\tcursor.y += itemHeight;\n\t\t\t\t\t}\n\n\t\t\t\t});\n\t\t\t}\n\t\t},\n\n\t\t/**\n\t\t * Handle an event\n\t\t * @private\n\t\t * @param {IEvent} event - The event to handle\n\t\t * @return {Boolean} true if a change occured\n\t\t */\n\t\thandleEvent: function(e) {\n\t\t\tvar me = this;\n\t\t\tvar opts = me.options;\n\t\t\tvar type = e.type === 'mouseup' ? 'click' : e.type;\n\t\t\tvar changed = false;\n\n\t\t\tif (type === 'mousemove') {\n\t\t\t\tif (!opts.onHover) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t} else if (type === 'click') {\n\t\t\t\tif (!opts.onClick) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// Chart event already has relative position in it\n\t\t\tvar x = e.x,\n\t\t\t\ty = e.y;\n\n\t\t\tif (x >= me.left && x <= me.right && y >= me.top && y <= me.bottom) {\n\t\t\t\t// See if we are touching one of the dataset boxes\n\t\t\t\tvar lh = me.legendHitBoxes;\n\t\t\t\tfor (var i = 0; i < lh.length; ++i) {\n\t\t\t\t\tvar hitBox = lh[i];\n\n\t\t\t\t\tif (x >= hitBox.left && x <= hitBox.left + hitBox.width && y >= hitBox.top && y <= hitBox.top + hitBox.height) {\n\t\t\t\t\t\t// Touching an element\n\t\t\t\t\t\tif (type === 'click') {\n\t\t\t\t\t\t\t// use e.native for backwards compatibility\n\t\t\t\t\t\t\topts.onClick.call(me, e.native, me.legendItems[i]);\n\t\t\t\t\t\t\tchanged = true;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t} else if (type === 'mousemove') {\n\t\t\t\t\t\t\t// use e.native for backwards compatibility\n\t\t\t\t\t\t\topts.onHover.call(me, e.native, me.legendItems[i]);\n\t\t\t\t\t\t\tchanged = true;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn changed;\n\t\t}\n\t});\n\n\tfunction createNewLegendAndAttach(chart, legendOpts) {\n\t\tvar legend = new Chart.Legend({\n\t\t\tctx: chart.ctx,\n\t\t\toptions: legendOpts,\n\t\t\tchart: chart\n\t\t});\n\n\t\tlayout.configure(chart, legend, legendOpts);\n\t\tlayout.addBox(chart, legend);\n\t\tchart.legend = legend;\n\t}\n\n\treturn {\n\t\tid: 'legend',\n\n\t\tbeforeInit: function(chart) {\n\t\t\tvar legendOpts = chart.options.legend;\n\n\t\t\tif (legendOpts) {\n\t\t\t\tcreateNewLegendAndAttach(chart, legendOpts);\n\t\t\t}\n\t\t},\n\n\t\tbeforeUpdate: function(chart) {\n\t\t\tvar legendOpts = chart.options.legend;\n\t\t\tvar legend = chart.legend;\n\n\t\t\tif (legendOpts) {\n\t\t\t\tlegendOpts = helpers.configMerge(Chart.defaults.global.legend, legendOpts);\n\n\t\t\t\tif (legend) {\n\t\t\t\t\tlayout.configure(chart, legend, legendOpts);\n\t\t\t\t\tlegend.options = legendOpts;\n\t\t\t\t} else {\n\t\t\t\t\tcreateNewLegendAndAttach(chart, legendOpts);\n\t\t\t\t}\n\t\t\t} else if (legend) {\n\t\t\t\tlayout.removeBox(chart, legend);\n\t\t\t\tdelete chart.legend;\n\t\t\t}\n\t\t},\n\n\t\tafterEvent: function(chart, e) {\n\t\t\tvar legend = chart.legend;\n\t\t\tif (legend) {\n\t\t\t\tlegend.handleEvent(e);\n\t\t\t}\n\t\t}\n\t};\n};\n\n},{}],43:[function(require,module,exports){\n'use strict';\n\nmodule.exports = function(Chart) {\n\n\tvar helpers = Chart.helpers;\n\tvar layout = Chart.layoutService;\n\tvar noop = helpers.noop;\n\n\tChart.defaults.global.title = {\n\t\tdisplay: false,\n\t\tposition: 'top',\n\t\tfullWidth: true,\n\t\tweight: 2000,        // by default greater than legend (1000) to be above\n\t\tfontStyle: 'bold',\n\t\tpadding: 10,\n\n\t\t// actual title\n\t\ttext: ''\n\t};\n\n\tChart.Title = Chart.Element.extend({\n\t\tinitialize: function(config) {\n\t\t\tvar me = this;\n\t\t\thelpers.extend(me, config);\n\n\t\t\t// Contains hit boxes for each dataset (in dataset order)\n\t\t\tme.legendHitBoxes = [];\n\t\t},\n\n\t\t// These methods are ordered by lifecycle. Utilities then follow.\n\n\t\tbeforeUpdate: noop,\n\t\tupdate: function(maxWidth, maxHeight, margins) {\n\t\t\tvar me = this;\n\n\t\t\t// Update Lifecycle - Probably don't want to ever extend or overwrite this function ;)\n\t\t\tme.beforeUpdate();\n\n\t\t\t// Absorb the master measurements\n\t\t\tme.maxWidth = maxWidth;\n\t\t\tme.maxHeight = maxHeight;\n\t\t\tme.margins = margins;\n\n\t\t\t// Dimensions\n\t\t\tme.beforeSetDimensions();\n\t\t\tme.setDimensions();\n\t\t\tme.afterSetDimensions();\n\t\t\t// Labels\n\t\t\tme.beforeBuildLabels();\n\t\t\tme.buildLabels();\n\t\t\tme.afterBuildLabels();\n\n\t\t\t// Fit\n\t\t\tme.beforeFit();\n\t\t\tme.fit();\n\t\t\tme.afterFit();\n\t\t\t//\n\t\t\tme.afterUpdate();\n\n\t\t\treturn me.minSize;\n\n\t\t},\n\t\tafterUpdate: noop,\n\n\t\t//\n\n\t\tbeforeSetDimensions: noop,\n\t\tsetDimensions: function() {\n\t\t\tvar me = this;\n\t\t\t// Set the unconstrained dimension before label rotation\n\t\t\tif (me.isHorizontal()) {\n\t\t\t\t// Reset position before calculating rotation\n\t\t\t\tme.width = me.maxWidth;\n\t\t\t\tme.left = 0;\n\t\t\t\tme.right = me.width;\n\t\t\t} else {\n\t\t\t\tme.height = me.maxHeight;\n\n\t\t\t\t// Reset position before calculating rotation\n\t\t\t\tme.top = 0;\n\t\t\t\tme.bottom = me.height;\n\t\t\t}\n\n\t\t\t// Reset padding\n\t\t\tme.paddingLeft = 0;\n\t\t\tme.paddingTop = 0;\n\t\t\tme.paddingRight = 0;\n\t\t\tme.paddingBottom = 0;\n\n\t\t\t// Reset minSize\n\t\t\tme.minSize = {\n\t\t\t\twidth: 0,\n\t\t\t\theight: 0\n\t\t\t};\n\t\t},\n\t\tafterSetDimensions: noop,\n\n\t\t//\n\n\t\tbeforeBuildLabels: noop,\n\t\tbuildLabels: noop,\n\t\tafterBuildLabels: noop,\n\n\t\t//\n\n\t\tbeforeFit: noop,\n\t\tfit: function() {\n\t\t\tvar me = this,\n\t\t\t\tvalueOrDefault = helpers.getValueOrDefault,\n\t\t\t\topts = me.options,\n\t\t\t\tglobalDefaults = Chart.defaults.global,\n\t\t\t\tdisplay = opts.display,\n\t\t\t\tfontSize = valueOrDefault(opts.fontSize, globalDefaults.defaultFontSize),\n\t\t\t\tminSize = me.minSize;\n\n\t\t\tif (me.isHorizontal()) {\n\t\t\t\tminSize.width = me.maxWidth; // fill all the width\n\t\t\t\tminSize.height = display ? fontSize + (opts.padding * 2) : 0;\n\t\t\t} else {\n\t\t\t\tminSize.width = display ? fontSize + (opts.padding * 2) : 0;\n\t\t\t\tminSize.height = me.maxHeight; // fill all the height\n\t\t\t}\n\n\t\t\tme.width = minSize.width;\n\t\t\tme.height = minSize.height;\n\n\t\t},\n\t\tafterFit: noop,\n\n\t\t// Shared Methods\n\t\tisHorizontal: function() {\n\t\t\tvar pos = this.options.position;\n\t\t\treturn pos === 'top' || pos === 'bottom';\n\t\t},\n\n\t\t// Actually draw the title block on the canvas\n\t\tdraw: function() {\n\t\t\tvar me = this,\n\t\t\t\tctx = me.ctx,\n\t\t\t\tvalueOrDefault = helpers.getValueOrDefault,\n\t\t\t\topts = me.options,\n\t\t\t\tglobalDefaults = Chart.defaults.global;\n\n\t\t\tif (opts.display) {\n\t\t\t\tvar fontSize = valueOrDefault(opts.fontSize, globalDefaults.defaultFontSize),\n\t\t\t\t\tfontStyle = valueOrDefault(opts.fontStyle, globalDefaults.defaultFontStyle),\n\t\t\t\t\tfontFamily = valueOrDefault(opts.fontFamily, globalDefaults.defaultFontFamily),\n\t\t\t\t\ttitleFont = helpers.fontString(fontSize, fontStyle, fontFamily),\n\t\t\t\t\trotation = 0,\n\t\t\t\t\ttitleX,\n\t\t\t\t\ttitleY,\n\t\t\t\t\ttop = me.top,\n\t\t\t\t\tleft = me.left,\n\t\t\t\t\tbottom = me.bottom,\n\t\t\t\t\tright = me.right,\n\t\t\t\t\tmaxWidth;\n\n\t\t\t\tctx.fillStyle = valueOrDefault(opts.fontColor, globalDefaults.defaultFontColor); // render in correct colour\n\t\t\t\tctx.font = titleFont;\n\n\t\t\t\t// Horizontal\n\t\t\t\tif (me.isHorizontal()) {\n\t\t\t\t\ttitleX = left + ((right - left) / 2); // midpoint of the width\n\t\t\t\t\ttitleY = top + ((bottom - top) / 2); // midpoint of the height\n\t\t\t\t\tmaxWidth = right - left;\n\t\t\t\t} else {\n\t\t\t\t\ttitleX = opts.position === 'left' ? left + (fontSize / 2) : right - (fontSize / 2);\n\t\t\t\t\ttitleY = top + ((bottom - top) / 2);\n\t\t\t\t\tmaxWidth = bottom - top;\n\t\t\t\t\trotation = Math.PI * (opts.position === 'left' ? -0.5 : 0.5);\n\t\t\t\t}\n\n\t\t\t\tctx.save();\n\t\t\t\tctx.translate(titleX, titleY);\n\t\t\t\tctx.rotate(rotation);\n\t\t\t\tctx.textAlign = 'center';\n\t\t\t\tctx.textBaseline = 'middle';\n\t\t\t\tctx.fillText(opts.text, 0, 0, maxWidth);\n\t\t\t\tctx.restore();\n\t\t\t}\n\t\t}\n\t});\n\n\tfunction createNewTitleBlockAndAttach(chart, titleOpts) {\n\t\tvar title = new Chart.Title({\n\t\t\tctx: chart.ctx,\n\t\t\toptions: titleOpts,\n\t\t\tchart: chart\n\t\t});\n\n\t\tlayout.configure(chart, title, titleOpts);\n\t\tlayout.addBox(chart, title);\n\t\tchart.titleBlock = title;\n\t}\n\n\treturn {\n\t\tid: 'title',\n\n\t\tbeforeInit: function(chart) {\n\t\t\tvar titleOpts = chart.options.title;\n\n\t\t\tif (titleOpts) {\n\t\t\t\tcreateNewTitleBlockAndAttach(chart, titleOpts);\n\t\t\t}\n\t\t},\n\n\t\tbeforeUpdate: function(chart) {\n\t\t\tvar titleOpts = chart.options.title;\n\t\t\tvar titleBlock = chart.titleBlock;\n\n\t\t\tif (titleOpts) {\n\t\t\t\ttitleOpts = helpers.configMerge(Chart.defaults.global.title, titleOpts);\n\n\t\t\t\tif (titleBlock) {\n\t\t\t\t\tlayout.configure(chart, titleBlock, titleOpts);\n\t\t\t\t\ttitleBlock.options = titleOpts;\n\t\t\t\t} else {\n\t\t\t\t\tcreateNewTitleBlockAndAttach(chart, titleOpts);\n\t\t\t\t}\n\t\t\t} else if (titleBlock) {\n\t\t\t\tChart.layoutService.removeBox(chart, titleBlock);\n\t\t\t\tdelete chart.titleBlock;\n\t\t\t}\n\t\t}\n\t};\n};\n\n},{}],44:[function(require,module,exports){\n'use strict';\n\nmodule.exports = function(Chart) {\n\n\tvar helpers = Chart.helpers;\n\t// Default config for a category scale\n\tvar defaultConfig = {\n\t\tposition: 'bottom'\n\t};\n\n\tvar DatasetScale = Chart.Scale.extend({\n\t\t/**\n\t\t* Internal function to get the correct labels. If data.xLabels or data.yLabels are defined, use those\n\t\t* else fall back to data.labels\n\t\t* @private\n\t\t*/\n\t\tgetLabels: function() {\n\t\t\tvar data = this.chart.data;\n\t\t\treturn (this.isHorizontal() ? data.xLabels : data.yLabels) || data.labels;\n\t\t},\n\n\t\tdetermineDataLimits: function() {\n\t\t\tvar me = this;\n\t\t\tvar labels = me.getLabels();\n\t\t\tme.minIndex = 0;\n\t\t\tme.maxIndex = labels.length - 1;\n\t\t\tvar findIndex;\n\n\t\t\tif (me.options.ticks.min !== undefined) {\n\t\t\t\t// user specified min value\n\t\t\t\tfindIndex = helpers.indexOf(labels, me.options.ticks.min);\n\t\t\t\tme.minIndex = findIndex !== -1 ? findIndex : me.minIndex;\n\t\t\t}\n\n\t\t\tif (me.options.ticks.max !== undefined) {\n\t\t\t\t// user specified max value\n\t\t\t\tfindIndex = helpers.indexOf(labels, me.options.ticks.max);\n\t\t\t\tme.maxIndex = findIndex !== -1 ? findIndex : me.maxIndex;\n\t\t\t}\n\n\t\t\tme.min = labels[me.minIndex];\n\t\t\tme.max = labels[me.maxIndex];\n\t\t},\n\n\t\tbuildTicks: function() {\n\t\t\tvar me = this;\n\t\t\tvar labels = me.getLabels();\n\t\t\t// If we are viewing some subset of labels, slice the original array\n\t\t\tme.ticks = (me.minIndex === 0 && me.maxIndex === labels.length - 1) ? labels : labels.slice(me.minIndex, me.maxIndex + 1);\n\t\t},\n\n\t\tgetLabelForIndex: function(index, datasetIndex) {\n\t\t\tvar me = this;\n\t\t\tvar data = me.chart.data;\n\t\t\tvar isHorizontal = me.isHorizontal();\n\n\t\t\tif (data.yLabels && !isHorizontal) {\n\t\t\t\treturn me.getRightValue(data.datasets[datasetIndex].data[index]);\n\t\t\t}\n\t\t\treturn me.ticks[index - me.minIndex];\n\t\t},\n\n\t\t// Used to get data value locations.  Value can either be an index or a numerical value\n\t\tgetPixelForValue: function(value, index, datasetIndex, includeOffset) {\n\t\t\tvar me = this;\n\t\t\t// 1 is added because we need the length but we have the indexes\n\t\t\tvar offsetAmt = Math.max((me.maxIndex + 1 - me.minIndex - ((me.options.gridLines.offsetGridLines) ? 0 : 1)), 1);\n\n\t\t\t// If value is a data object, then index is the index in the data array,\n\t\t\t// not the index of the scale. We need to change that.\n\t\t\tvar valueCategory;\n\t\t\tif (value !== undefined && value !== null) {\n\t\t\t\tvalueCategory = me.isHorizontal() ? value.x : value.y;\n\t\t\t}\n\t\t\tif (valueCategory !== undefined || (value !== undefined && isNaN(index))) {\n\t\t\t\tvar labels = me.getLabels();\n\t\t\t\tvalue = valueCategory || value;\n\t\t\t\tvar idx = labels.indexOf(value);\n\t\t\t\tindex = idx !== -1 ? idx : index;\n\t\t\t}\n\n\t\t\tif (me.isHorizontal()) {\n\t\t\t\tvar valueWidth = me.width / offsetAmt;\n\t\t\t\tvar widthOffset = (valueWidth * (index - me.minIndex));\n\n\t\t\t\tif (me.options.gridLines.offsetGridLines && includeOffset || me.maxIndex === me.minIndex && includeOffset) {\n\t\t\t\t\twidthOffset += (valueWidth / 2);\n\t\t\t\t}\n\n\t\t\t\treturn me.left + Math.round(widthOffset);\n\t\t\t}\n\t\t\tvar valueHeight = me.height / offsetAmt;\n\t\t\tvar heightOffset = (valueHeight * (index - me.minIndex));\n\n\t\t\tif (me.options.gridLines.offsetGridLines && includeOffset) {\n\t\t\t\theightOffset += (valueHeight / 2);\n\t\t\t}\n\n\t\t\treturn me.top + Math.round(heightOffset);\n\t\t},\n\t\tgetPixelForTick: function(index, includeOffset) {\n\t\t\treturn this.getPixelForValue(this.ticks[index], index + this.minIndex, null, includeOffset);\n\t\t},\n\t\tgetValueForPixel: function(pixel) {\n\t\t\tvar me = this;\n\t\t\tvar value;\n\t\t\tvar offsetAmt = Math.max((me.ticks.length - ((me.options.gridLines.offsetGridLines) ? 0 : 1)), 1);\n\t\t\tvar horz = me.isHorizontal();\n\t\t\tvar valueDimension = (horz ? me.width : me.height) / offsetAmt;\n\n\t\t\tpixel -= horz ? me.left : me.top;\n\n\t\t\tif (me.options.gridLines.offsetGridLines) {\n\t\t\t\tpixel -= (valueDimension / 2);\n\t\t\t}\n\n\t\t\tif (pixel <= 0) {\n\t\t\t\tvalue = 0;\n\t\t\t} else {\n\t\t\t\tvalue = Math.round(pixel / valueDimension);\n\t\t\t}\n\n\t\t\treturn value;\n\t\t},\n\t\tgetBasePixel: function() {\n\t\t\treturn this.bottom;\n\t\t}\n\t});\n\n\tChart.scaleService.registerScaleType('category', DatasetScale, defaultConfig);\n\n};\n\n},{}],45:[function(require,module,exports){\n'use strict';\n\nmodule.exports = function(Chart) {\n\n\tvar helpers = Chart.helpers;\n\n\tvar defaultConfig = {\n\t\tposition: 'left',\n\t\tticks: {\n\t\t\tcallback: Chart.Ticks.formatters.linear\n\t\t}\n\t};\n\n\tvar LinearScale = Chart.LinearScaleBase.extend({\n\n\t\tdetermineDataLimits: function() {\n\t\t\tvar me = this;\n\t\t\tvar opts = me.options;\n\t\t\tvar chart = me.chart;\n\t\t\tvar data = chart.data;\n\t\t\tvar datasets = data.datasets;\n\t\t\tvar isHorizontal = me.isHorizontal();\n\t\t\tvar DEFAULT_MIN = 0;\n\t\t\tvar DEFAULT_MAX = 1;\n\n\t\t\tfunction IDMatches(meta) {\n\t\t\t\treturn isHorizontal ? meta.xAxisID === me.id : meta.yAxisID === me.id;\n\t\t\t}\n\n\t\t\t// First Calculate the range\n\t\t\tme.min = null;\n\t\t\tme.max = null;\n\n\t\t\tvar hasStacks = opts.stacked;\n\t\t\tif (hasStacks === undefined) {\n\t\t\t\thelpers.each(datasets, function(dataset, datasetIndex) {\n\t\t\t\t\tif (hasStacks) {\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\n\t\t\t\t\tvar meta = chart.getDatasetMeta(datasetIndex);\n\t\t\t\t\tif (chart.isDatasetVisible(datasetIndex) && IDMatches(meta) &&\n\t\t\t\t\t\tmeta.stack !== undefined) {\n\t\t\t\t\t\thasStacks = true;\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t}\n\n\t\t\tif (opts.stacked || hasStacks) {\n\t\t\t\tvar valuesPerStack = {};\n\n\t\t\t\thelpers.each(datasets, function(dataset, datasetIndex) {\n\t\t\t\t\tvar meta = chart.getDatasetMeta(datasetIndex);\n\t\t\t\t\tvar key = [\n\t\t\t\t\t\tmeta.type,\n\t\t\t\t\t\t// we have a separate stack for stack=undefined datasets when the opts.stacked is undefined\n\t\t\t\t\t\t((opts.stacked === undefined && meta.stack === undefined) ? datasetIndex : ''),\n\t\t\t\t\t\tmeta.stack\n\t\t\t\t\t].join('.');\n\n\t\t\t\t\tif (valuesPerStack[key] === undefined) {\n\t\t\t\t\t\tvaluesPerStack[key] = {\n\t\t\t\t\t\t\tpositiveValues: [],\n\t\t\t\t\t\t\tnegativeValues: []\n\t\t\t\t\t\t};\n\t\t\t\t\t}\n\n\t\t\t\t\t// Store these per type\n\t\t\t\t\tvar positiveValues = valuesPerStack[key].positiveValues;\n\t\t\t\t\tvar negativeValues = valuesPerStack[key].negativeValues;\n\n\t\t\t\t\tif (chart.isDatasetVisible(datasetIndex) && IDMatches(meta)) {\n\t\t\t\t\t\thelpers.each(dataset.data, function(rawValue, index) {\n\t\t\t\t\t\t\tvar value = +me.getRightValue(rawValue);\n\t\t\t\t\t\t\tif (isNaN(value) || meta.data[index].hidden) {\n\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tpositiveValues[index] = positiveValues[index] || 0;\n\t\t\t\t\t\t\tnegativeValues[index] = negativeValues[index] || 0;\n\n\t\t\t\t\t\t\tif (opts.relativePoints) {\n\t\t\t\t\t\t\t\tpositiveValues[index] = 100;\n\t\t\t\t\t\t\t} else if (value < 0) {\n\t\t\t\t\t\t\t\tnegativeValues[index] += value;\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tpositiveValues[index] += value;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t});\n\n\t\t\t\thelpers.each(valuesPerStack, function(valuesForType) {\n\t\t\t\t\tvar values = valuesForType.positiveValues.concat(valuesForType.negativeValues);\n\t\t\t\t\tvar minVal = helpers.min(values);\n\t\t\t\t\tvar maxVal = helpers.max(values);\n\t\t\t\t\tme.min = me.min === null ? minVal : Math.min(me.min, minVal);\n\t\t\t\t\tme.max = me.max === null ? maxVal : Math.max(me.max, maxVal);\n\t\t\t\t});\n\n\t\t\t} else {\n\t\t\t\thelpers.each(datasets, function(dataset, datasetIndex) {\n\t\t\t\t\tvar meta = chart.getDatasetMeta(datasetIndex);\n\t\t\t\t\tif (chart.isDatasetVisible(datasetIndex) && IDMatches(meta)) {\n\t\t\t\t\t\thelpers.each(dataset.data, function(rawValue, index) {\n\t\t\t\t\t\t\tvar value = +me.getRightValue(rawValue);\n\t\t\t\t\t\t\tif (isNaN(value) || meta.data[index].hidden) {\n\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tif (me.min === null) {\n\t\t\t\t\t\t\t\tme.min = value;\n\t\t\t\t\t\t\t} else if (value < me.min) {\n\t\t\t\t\t\t\t\tme.min = value;\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tif (me.max === null) {\n\t\t\t\t\t\t\t\tme.max = value;\n\t\t\t\t\t\t\t} else if (value > me.max) {\n\t\t\t\t\t\t\t\tme.max = value;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t}\n\n\t\t\tme.min = isFinite(me.min) ? me.min : DEFAULT_MIN;\n\t\t\tme.max = isFinite(me.max) ? me.max : DEFAULT_MAX;\n\n\t\t\t// Common base implementation to handle ticks.min, ticks.max, ticks.beginAtZero\n\t\t\tthis.handleTickRangeOptions();\n\t\t},\n\t\tgetTickLimit: function() {\n\t\t\tvar maxTicks;\n\t\t\tvar me = this;\n\t\t\tvar tickOpts = me.options.ticks;\n\n\t\t\tif (me.isHorizontal()) {\n\t\t\t\tmaxTicks = Math.min(tickOpts.maxTicksLimit ? tickOpts.maxTicksLimit : 11, Math.ceil(me.width / 50));\n\t\t\t} else {\n\t\t\t\t// The factor of 2 used to scale the font size has been experimentally determined.\n\t\t\t\tvar tickFontSize = helpers.getValueOrDefault(tickOpts.fontSize, Chart.defaults.global.defaultFontSize);\n\t\t\t\tmaxTicks = Math.min(tickOpts.maxTicksLimit ? tickOpts.maxTicksLimit : 11, Math.ceil(me.height / (2 * tickFontSize)));\n\t\t\t}\n\n\t\t\treturn maxTicks;\n\t\t},\n\t\t// Called after the ticks are built. We need\n\t\thandleDirectionalChanges: function() {\n\t\t\tif (!this.isHorizontal()) {\n\t\t\t\t// We are in a vertical orientation. The top value is the highest. So reverse the array\n\t\t\t\tthis.ticks.reverse();\n\t\t\t}\n\t\t},\n\t\tgetLabelForIndex: function(index, datasetIndex) {\n\t\t\treturn +this.getRightValue(this.chart.data.datasets[datasetIndex].data[index]);\n\t\t},\n\t\t// Utils\n\t\tgetPixelForValue: function(value) {\n\t\t\t// This must be called after fit has been run so that\n\t\t\t// this.left, this.top, this.right, and this.bottom have been defined\n\t\t\tvar me = this;\n\t\t\tvar start = me.start;\n\n\t\t\tvar rightValue = +me.getRightValue(value);\n\t\t\tvar pixel;\n\t\t\tvar range = me.end - start;\n\n\t\t\tif (me.isHorizontal()) {\n\t\t\t\tpixel = me.left + (me.width / range * (rightValue - start));\n\t\t\t\treturn Math.round(pixel);\n\t\t\t}\n\n\t\t\tpixel = me.bottom - (me.height / range * (rightValue - start));\n\t\t\treturn Math.round(pixel);\n\t\t},\n\t\tgetValueForPixel: function(pixel) {\n\t\t\tvar me = this;\n\t\t\tvar isHorizontal = me.isHorizontal();\n\t\t\tvar innerDimension = isHorizontal ? me.width : me.height;\n\t\t\tvar offset = (isHorizontal ? pixel - me.left : me.bottom - pixel) / innerDimension;\n\t\t\treturn me.start + ((me.end - me.start) * offset);\n\t\t},\n\t\tgetPixelForTick: function(index) {\n\t\t\treturn this.getPixelForValue(this.ticksAsNumbers[index]);\n\t\t}\n\t});\n\tChart.scaleService.registerScaleType('linear', LinearScale, defaultConfig);\n\n};\n\n},{}],46:[function(require,module,exports){\n'use strict';\n\nmodule.exports = function(Chart) {\n\n\tvar helpers = Chart.helpers,\n\t\tnoop = helpers.noop;\n\n\tChart.LinearScaleBase = Chart.Scale.extend({\n\t\thandleTickRangeOptions: function() {\n\t\t\tvar me = this;\n\t\t\tvar opts = me.options;\n\t\t\tvar tickOpts = opts.ticks;\n\n\t\t\t// If we are forcing it to begin at 0, but 0 will already be rendered on the chart,\n\t\t\t// do nothing since that would make the chart weird. If the user really wants a weird chart\n\t\t\t// axis, they can manually override it\n\t\t\tif (tickOpts.beginAtZero) {\n\t\t\t\tvar minSign = helpers.sign(me.min);\n\t\t\t\tvar maxSign = helpers.sign(me.max);\n\n\t\t\t\tif (minSign < 0 && maxSign < 0) {\n\t\t\t\t\t// move the top up to 0\n\t\t\t\t\tme.max = 0;\n\t\t\t\t} else if (minSign > 0 && maxSign > 0) {\n\t\t\t\t\t// move the bottom down to 0\n\t\t\t\t\tme.min = 0;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (tickOpts.min !== undefined) {\n\t\t\t\tme.min = tickOpts.min;\n\t\t\t} else if (tickOpts.suggestedMin !== undefined) {\n\t\t\t\tif (me.min === null) {\n\t\t\t\t\tme.min = tickOpts.suggestedMin;\n\t\t\t\t} else {\n\t\t\t\t\tme.min = Math.min(me.min, tickOpts.suggestedMin);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (tickOpts.max !== undefined) {\n\t\t\t\tme.max = tickOpts.max;\n\t\t\t} else if (tickOpts.suggestedMax !== undefined) {\n\t\t\t\tif (me.max === null) {\n\t\t\t\t\tme.max = tickOpts.suggestedMax;\n\t\t\t\t} else {\n\t\t\t\t\tme.max = Math.max(me.max, tickOpts.suggestedMax);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (me.min === me.max) {\n\t\t\t\tme.max++;\n\n\t\t\t\tif (!tickOpts.beginAtZero) {\n\t\t\t\t\tme.min--;\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\tgetTickLimit: noop,\n\t\thandleDirectionalChanges: noop,\n\n\t\tbuildTicks: function() {\n\t\t\tvar me = this;\n\t\t\tvar opts = me.options;\n\t\t\tvar tickOpts = opts.ticks;\n\n\t\t\t// Figure out what the max number of ticks we can support it is based on the size of\n\t\t\t// the axis area. For now, we say that the minimum tick spacing in pixels must be 50\n\t\t\t// We also limit the maximum number of ticks to 11 which gives a nice 10 squares on\n\t\t\t// the graph. Make sure we always have at least 2 ticks\n\t\t\tvar maxTicks = me.getTickLimit();\n\t\t\tmaxTicks = Math.max(2, maxTicks);\n\n\t\t\tvar numericGeneratorOptions = {\n\t\t\t\tmaxTicks: maxTicks,\n\t\t\t\tmin: tickOpts.min,\n\t\t\t\tmax: tickOpts.max,\n\t\t\t\tstepSize: helpers.getValueOrDefault(tickOpts.fixedStepSize, tickOpts.stepSize)\n\t\t\t};\n\t\t\tvar ticks = me.ticks = Chart.Ticks.generators.linear(numericGeneratorOptions, me);\n\n\t\t\tme.handleDirectionalChanges();\n\n\t\t\t// At this point, we need to update our max and min given the tick values since we have expanded the\n\t\t\t// range of the scale\n\t\t\tme.max = helpers.max(ticks);\n\t\t\tme.min = helpers.min(ticks);\n\n\t\t\tif (tickOpts.reverse) {\n\t\t\t\tticks.reverse();\n\n\t\t\t\tme.start = me.max;\n\t\t\t\tme.end = me.min;\n\t\t\t} else {\n\t\t\t\tme.start = me.min;\n\t\t\t\tme.end = me.max;\n\t\t\t}\n\t\t},\n\t\tconvertTicksToLabels: function() {\n\t\t\tvar me = this;\n\t\t\tme.ticksAsNumbers = me.ticks.slice();\n\t\t\tme.zeroLineIndex = me.ticks.indexOf(0);\n\n\t\t\tChart.Scale.prototype.convertTicksToLabels.call(me);\n\t\t}\n\t});\n};\n\n},{}],47:[function(require,module,exports){\n'use strict';\n\nmodule.exports = function(Chart) {\n\n\tvar helpers = Chart.helpers;\n\n\tvar defaultConfig = {\n\t\tposition: 'left',\n\n\t\t// label settings\n\t\tticks: {\n\t\t\tcallback: Chart.Ticks.formatters.logarithmic\n\t\t}\n\t};\n\n\tvar LogarithmicScale = Chart.Scale.extend({\n\t\tdetermineDataLimits: function() {\n\t\t\tvar me = this;\n\t\t\tvar opts = me.options;\n\t\t\tvar tickOpts = opts.ticks;\n\t\t\tvar chart = me.chart;\n\t\t\tvar data = chart.data;\n\t\t\tvar datasets = data.datasets;\n\t\t\tvar getValueOrDefault = helpers.getValueOrDefault;\n\t\t\tvar isHorizontal = me.isHorizontal();\n\t\t\tfunction IDMatches(meta) {\n\t\t\t\treturn isHorizontal ? meta.xAxisID === me.id : meta.yAxisID === me.id;\n\t\t\t}\n\n\t\t\t// Calculate Range\n\t\t\tme.min = null;\n\t\t\tme.max = null;\n\t\t\tme.minNotZero = null;\n\n\t\t\tvar hasStacks = opts.stacked;\n\t\t\tif (hasStacks === undefined) {\n\t\t\t\thelpers.each(datasets, function(dataset, datasetIndex) {\n\t\t\t\t\tif (hasStacks) {\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\n\t\t\t\t\tvar meta = chart.getDatasetMeta(datasetIndex);\n\t\t\t\t\tif (chart.isDatasetVisible(datasetIndex) && IDMatches(meta) &&\n\t\t\t\t\t\tmeta.stack !== undefined) {\n\t\t\t\t\t\thasStacks = true;\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t}\n\n\t\t\tif (opts.stacked || hasStacks) {\n\t\t\t\tvar valuesPerStack = {};\n\n\t\t\t\thelpers.each(datasets, function(dataset, datasetIndex) {\n\t\t\t\t\tvar meta = chart.getDatasetMeta(datasetIndex);\n\t\t\t\t\tvar key = [\n\t\t\t\t\t\tmeta.type,\n\t\t\t\t\t\t// we have a separate stack for stack=undefined datasets when the opts.stacked is undefined\n\t\t\t\t\t\t((opts.stacked === undefined && meta.stack === undefined) ? datasetIndex : ''),\n\t\t\t\t\t\tmeta.stack\n\t\t\t\t\t].join('.');\n\n\t\t\t\t\tif (chart.isDatasetVisible(datasetIndex) && IDMatches(meta)) {\n\t\t\t\t\t\tif (valuesPerStack[key] === undefined) {\n\t\t\t\t\t\t\tvaluesPerStack[key] = [];\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\thelpers.each(dataset.data, function(rawValue, index) {\n\t\t\t\t\t\t\tvar values = valuesPerStack[key];\n\t\t\t\t\t\t\tvar value = +me.getRightValue(rawValue);\n\t\t\t\t\t\t\tif (isNaN(value) || meta.data[index].hidden) {\n\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tvalues[index] = values[index] || 0;\n\n\t\t\t\t\t\t\tif (opts.relativePoints) {\n\t\t\t\t\t\t\t\tvalues[index] = 100;\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t// Don't need to split positive and negative since the log scale can't handle a 0 crossing\n\t\t\t\t\t\t\t\tvalues[index] += value;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t});\n\n\t\t\t\thelpers.each(valuesPerStack, function(valuesForType) {\n\t\t\t\t\tvar minVal = helpers.min(valuesForType);\n\t\t\t\t\tvar maxVal = helpers.max(valuesForType);\n\t\t\t\t\tme.min = me.min === null ? minVal : Math.min(me.min, minVal);\n\t\t\t\t\tme.max = me.max === null ? maxVal : Math.max(me.max, maxVal);\n\t\t\t\t});\n\n\t\t\t} else {\n\t\t\t\thelpers.each(datasets, function(dataset, datasetIndex) {\n\t\t\t\t\tvar meta = chart.getDatasetMeta(datasetIndex);\n\t\t\t\t\tif (chart.isDatasetVisible(datasetIndex) && IDMatches(meta)) {\n\t\t\t\t\t\thelpers.each(dataset.data, function(rawValue, index) {\n\t\t\t\t\t\t\tvar value = +me.getRightValue(rawValue);\n\t\t\t\t\t\t\tif (isNaN(value) || meta.data[index].hidden) {\n\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tif (me.min === null) {\n\t\t\t\t\t\t\t\tme.min = value;\n\t\t\t\t\t\t\t} else if (value < me.min) {\n\t\t\t\t\t\t\t\tme.min = value;\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tif (me.max === null) {\n\t\t\t\t\t\t\t\tme.max = value;\n\t\t\t\t\t\t\t} else if (value > me.max) {\n\t\t\t\t\t\t\t\tme.max = value;\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tif (value !== 0 && (me.minNotZero === null || value < me.minNotZero)) {\n\t\t\t\t\t\t\t\tme.minNotZero = value;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t}\n\n\t\t\tme.min = getValueOrDefault(tickOpts.min, me.min);\n\t\t\tme.max = getValueOrDefault(tickOpts.max, me.max);\n\n\t\t\tif (me.min === me.max) {\n\t\t\t\tif (me.min !== 0 && me.min !== null) {\n\t\t\t\t\tme.min = Math.pow(10, Math.floor(helpers.log10(me.min)) - 1);\n\t\t\t\t\tme.max = Math.pow(10, Math.floor(helpers.log10(me.max)) + 1);\n\t\t\t\t} else {\n\t\t\t\t\tme.min = 1;\n\t\t\t\t\tme.max = 10;\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\tbuildTicks: function() {\n\t\t\tvar me = this;\n\t\t\tvar opts = me.options;\n\t\t\tvar tickOpts = opts.ticks;\n\n\t\t\tvar generationOptions = {\n\t\t\t\tmin: tickOpts.min,\n\t\t\t\tmax: tickOpts.max\n\t\t\t};\n\t\t\tvar ticks = me.ticks = Chart.Ticks.generators.logarithmic(generationOptions, me);\n\n\t\t\tif (!me.isHorizontal()) {\n\t\t\t\t// We are in a vertical orientation. The top value is the highest. So reverse the array\n\t\t\t\tticks.reverse();\n\t\t\t}\n\n\t\t\t// At this point, we need to update our max and min given the tick values since we have expanded the\n\t\t\t// range of the scale\n\t\t\tme.max = helpers.max(ticks);\n\t\t\tme.min = helpers.min(ticks);\n\n\t\t\tif (tickOpts.reverse) {\n\t\t\t\tticks.reverse();\n\n\t\t\t\tme.start = me.max;\n\t\t\t\tme.end = me.min;\n\t\t\t} else {\n\t\t\t\tme.start = me.min;\n\t\t\t\tme.end = me.max;\n\t\t\t}\n\t\t},\n\t\tconvertTicksToLabels: function() {\n\t\t\tthis.tickValues = this.ticks.slice();\n\n\t\t\tChart.Scale.prototype.convertTicksToLabels.call(this);\n\t\t},\n\t\t// Get the correct tooltip label\n\t\tgetLabelForIndex: function(index, datasetIndex) {\n\t\t\treturn +this.getRightValue(this.chart.data.datasets[datasetIndex].data[index]);\n\t\t},\n\t\tgetPixelForTick: function(index) {\n\t\t\treturn this.getPixelForValue(this.tickValues[index]);\n\t\t},\n\t\tgetPixelForValue: function(value) {\n\t\t\tvar me = this;\n\t\t\tvar innerDimension;\n\t\t\tvar pixel;\n\n\t\t\tvar start = me.start;\n\t\t\tvar newVal = +me.getRightValue(value);\n\t\t\tvar range;\n\t\t\tvar opts = me.options;\n\t\t\tvar tickOpts = opts.ticks;\n\n\t\t\tif (me.isHorizontal()) {\n\t\t\t\trange = helpers.log10(me.end) - helpers.log10(start); // todo: if start === 0\n\t\t\t\tif (newVal === 0) {\n\t\t\t\t\tpixel = me.left;\n\t\t\t\t} else {\n\t\t\t\t\tinnerDimension = me.width;\n\t\t\t\t\tpixel = me.left + (innerDimension / range * (helpers.log10(newVal) - helpers.log10(start)));\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t// Bottom - top since pixels increase downward on a screen\n\t\t\t\tinnerDimension = me.height;\n\t\t\t\tif (start === 0 && !tickOpts.reverse) {\n\t\t\t\t\trange = helpers.log10(me.end) - helpers.log10(me.minNotZero);\n\t\t\t\t\tif (newVal === start) {\n\t\t\t\t\t\tpixel = me.bottom;\n\t\t\t\t\t} else if (newVal === me.minNotZero) {\n\t\t\t\t\t\tpixel = me.bottom - innerDimension * 0.02;\n\t\t\t\t\t} else {\n\t\t\t\t\t\tpixel = me.bottom - innerDimension * 0.02 - (innerDimension * 0.98/ range * (helpers.log10(newVal)-helpers.log10(me.minNotZero)));\n\t\t\t\t\t}\n\t\t\t\t} else if (me.end === 0 && tickOpts.reverse) {\n\t\t\t\t\trange = helpers.log10(me.start) - helpers.log10(me.minNotZero);\n\t\t\t\t\tif (newVal === me.end) {\n\t\t\t\t\t\tpixel = me.top;\n\t\t\t\t\t} else if (newVal === me.minNotZero) {\n\t\t\t\t\t\tpixel = me.top + innerDimension * 0.02;\n\t\t\t\t\t} else {\n\t\t\t\t\t\tpixel = me.top + innerDimension * 0.02 + (innerDimension * 0.98/ range * (helpers.log10(newVal)-helpers.log10(me.minNotZero)));\n\t\t\t\t\t}\n\t\t\t\t} else if (newVal === 0) {\n\t\t\t\t\tpixel = tickOpts.reverse ? me.top : me.bottom;\n\t\t\t\t} else {\n\t\t\t\t\trange = helpers.log10(me.end) - helpers.log10(start);\n\t\t\t\t\tinnerDimension = me.height;\n\t\t\t\t\tpixel = me.bottom - (innerDimension / range * (helpers.log10(newVal) - helpers.log10(start)));\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn pixel;\n\t\t},\n\t\tgetValueForPixel: function(pixel) {\n\t\t\tvar me = this;\n\t\t\tvar range = helpers.log10(me.end) - helpers.log10(me.start);\n\t\t\tvar value, innerDimension;\n\n\t\t\tif (me.isHorizontal()) {\n\t\t\t\tinnerDimension = me.width;\n\t\t\t\tvalue = me.start * Math.pow(10, (pixel - me.left) * range / innerDimension);\n\t\t\t} else {  // todo: if start === 0\n\t\t\t\tinnerDimension = me.height;\n\t\t\t\tvalue = Math.pow(10, (me.bottom - pixel) * range / innerDimension) / me.start;\n\t\t\t}\n\t\t\treturn value;\n\t\t}\n\t});\n\tChart.scaleService.registerScaleType('logarithmic', LogarithmicScale, defaultConfig);\n\n};\n\n},{}],48:[function(require,module,exports){\n'use strict';\n\nmodule.exports = function(Chart) {\n\n\tvar helpers = Chart.helpers;\n\tvar globalDefaults = Chart.defaults.global;\n\n\tvar defaultConfig = {\n\t\tdisplay: true,\n\n\t\t// Boolean - Whether to animate scaling the chart from the centre\n\t\tanimate: true,\n\t\tposition: 'chartArea',\n\n\t\tangleLines: {\n\t\t\tdisplay: true,\n\t\t\tcolor: 'rgba(0, 0, 0, 0.1)',\n\t\t\tlineWidth: 1\n\t\t},\n\n\t\tgridLines: {\n\t\t\tcircular: false\n\t\t},\n\n\t\t// label settings\n\t\tticks: {\n\t\t\t// Boolean - Show a backdrop to the scale label\n\t\t\tshowLabelBackdrop: true,\n\n\t\t\t// String - The colour of the label backdrop\n\t\t\tbackdropColor: 'rgba(255,255,255,0.75)',\n\n\t\t\t// Number - The backdrop padding above & below the label in pixels\n\t\t\tbackdropPaddingY: 2,\n\n\t\t\t// Number - The backdrop padding to the side of the label in pixels\n\t\t\tbackdropPaddingX: 2,\n\n\t\t\tcallback: Chart.Ticks.formatters.linear\n\t\t},\n\n\t\tpointLabels: {\n\t\t\t// Boolean - if true, show point labels\n\t\t\tdisplay: true,\n\n\t\t\t// Number - Point label font size in pixels\n\t\t\tfontSize: 10,\n\n\t\t\t// Function - Used to convert point labels\n\t\t\tcallback: function(label) {\n\t\t\t\treturn label;\n\t\t\t}\n\t\t}\n\t};\n\n\tfunction getValueCount(scale) {\n\t\tvar opts = scale.options;\n\t\treturn opts.angleLines.display || opts.pointLabels.display ? scale.chart.data.labels.length : 0;\n\t}\n\n\tfunction getPointLabelFontOptions(scale) {\n\t\tvar pointLabelOptions = scale.options.pointLabels;\n\t\tvar fontSize = helpers.getValueOrDefault(pointLabelOptions.fontSize, globalDefaults.defaultFontSize);\n\t\tvar fontStyle = helpers.getValueOrDefault(pointLabelOptions.fontStyle, globalDefaults.defaultFontStyle);\n\t\tvar fontFamily = helpers.getValueOrDefault(pointLabelOptions.fontFamily, globalDefaults.defaultFontFamily);\n\t\tvar font = helpers.fontString(fontSize, fontStyle, fontFamily);\n\n\t\treturn {\n\t\t\tsize: fontSize,\n\t\t\tstyle: fontStyle,\n\t\t\tfamily: fontFamily,\n\t\t\tfont: font\n\t\t};\n\t}\n\n\tfunction measureLabelSize(ctx, fontSize, label) {\n\t\tif (helpers.isArray(label)) {\n\t\t\treturn {\n\t\t\t\tw: helpers.longestText(ctx, ctx.font, label),\n\t\t\t\th: (label.length * fontSize) + ((label.length - 1) * 1.5 * fontSize)\n\t\t\t};\n\t\t}\n\n\t\treturn {\n\t\t\tw: ctx.measureText(label).width,\n\t\t\th: fontSize\n\t\t};\n\t}\n\n\tfunction determineLimits(angle, pos, size, min, max) {\n\t\tif (angle === min || angle === max) {\n\t\t\treturn {\n\t\t\t\tstart: pos - (size / 2),\n\t\t\t\tend: pos + (size / 2)\n\t\t\t};\n\t\t} else if (angle < min || angle > max) {\n\t\t\treturn {\n\t\t\t\tstart: pos - size - 5,\n\t\t\t\tend: pos\n\t\t\t};\n\t\t}\n\n\t\treturn {\n\t\t\tstart: pos,\n\t\t\tend: pos + size + 5\n\t\t};\n\t}\n\n\t/**\n\t * Helper function to fit a radial linear scale with point labels\n\t */\n\tfunction fitWithPointLabels(scale) {\n\t\t/*\n\t\t * Right, this is really confusing and there is a lot of maths going on here\n\t\t * The gist of the problem is here: https://gist.github.com/nnnick/696cc9c55f4b0beb8fe9\n\t\t *\n\t\t * Reaction: https://dl.dropboxusercontent.com/u/34601363/toomuchscience.gif\n\t\t *\n\t\t * Solution:\n\t\t *\n\t\t * We assume the radius of the polygon is half the size of the canvas at first\n\t\t * at each index we check if the text overlaps.\n\t\t *\n\t\t * Where it does, we store that angle and that index.\n\t\t *\n\t\t * After finding the largest index and angle we calculate how much we need to remove\n\t\t * from the shape radius to move the point inwards by that x.\n\t\t *\n\t\t * We average the left and right distances to get the maximum shape radius that can fit in the box\n\t\t * along with labels.\n\t\t *\n\t\t * Once we have that, we can find the centre point for the chart, by taking the x text protrusion\n\t\t * on each side, removing that from the size, halving it and adding the left x protrusion width.\n\t\t *\n\t\t * This will mean we have a shape fitted to the canvas, as large as it can be with the labels\n\t\t * and position it in the most space efficient manner\n\t\t *\n\t\t * https://dl.dropboxusercontent.com/u/34601363/yeahscience.gif\n\t\t */\n\n\t\tvar plFont = getPointLabelFontOptions(scale);\n\n\t\t// Get maximum radius of the polygon. Either half the height (minus the text width) or half the width.\n\t\t// Use this to calculate the offset + change. - Make sure L/R protrusion is at least 0 to stop issues with centre points\n\t\tvar largestPossibleRadius = Math.min(scale.height / 2, scale.width / 2);\n\t\tvar furthestLimits = {\n\t\t\tr: scale.width,\n\t\t\tl: 0,\n\t\t\tt: scale.height,\n\t\t\tb: 0\n\t\t};\n\t\tvar furthestAngles = {};\n\t\tvar i;\n\t\tvar textSize;\n\t\tvar pointPosition;\n\n\t\tscale.ctx.font = plFont.font;\n\t\tscale._pointLabelSizes = [];\n\n\t\tvar valueCount = getValueCount(scale);\n\t\tfor (i = 0; i < valueCount; i++) {\n\t\t\tpointPosition = scale.getPointPosition(i, largestPossibleRadius);\n\t\t\ttextSize = measureLabelSize(scale.ctx, plFont.size, scale.pointLabels[i] || '');\n\t\t\tscale._pointLabelSizes[i] = textSize;\n\n\t\t\t// Add quarter circle to make degree 0 mean top of circle\n\t\t\tvar angleRadians = scale.getIndexAngle(i);\n\t\t\tvar angle = helpers.toDegrees(angleRadians) % 360;\n\t\t\tvar hLimits = determineLimits(angle, pointPosition.x, textSize.w, 0, 180);\n\t\t\tvar vLimits = determineLimits(angle, pointPosition.y, textSize.h, 90, 270);\n\n\t\t\tif (hLimits.start < furthestLimits.l) {\n\t\t\t\tfurthestLimits.l = hLimits.start;\n\t\t\t\tfurthestAngles.l = angleRadians;\n\t\t\t}\n\n\t\t\tif (hLimits.end > furthestLimits.r) {\n\t\t\t\tfurthestLimits.r = hLimits.end;\n\t\t\t\tfurthestAngles.r = angleRadians;\n\t\t\t}\n\n\t\t\tif (vLimits.start < furthestLimits.t) {\n\t\t\t\tfurthestLimits.t = vLimits.start;\n\t\t\t\tfurthestAngles.t = angleRadians;\n\t\t\t}\n\n\t\t\tif (vLimits.end > furthestLimits.b) {\n\t\t\t\tfurthestLimits.b = vLimits.end;\n\t\t\t\tfurthestAngles.b = angleRadians;\n\t\t\t}\n\t\t}\n\n\t\tscale.setReductions(largestPossibleRadius, furthestLimits, furthestAngles);\n\t}\n\n\t/**\n\t * Helper function to fit a radial linear scale with no point labels\n\t */\n\tfunction fit(scale) {\n\t\tvar largestPossibleRadius = Math.min(scale.height / 2, scale.width / 2);\n\t\tscale.drawingArea = Math.round(largestPossibleRadius);\n\t\tscale.setCenterPoint(0, 0, 0, 0);\n\t}\n\n\tfunction getTextAlignForAngle(angle) {\n\t\tif (angle === 0 || angle === 180) {\n\t\t\treturn 'center';\n\t\t} else if (angle < 180) {\n\t\t\treturn 'left';\n\t\t}\n\n\t\treturn 'right';\n\t}\n\n\tfunction fillText(ctx, text, position, fontSize) {\n\t\tif (helpers.isArray(text)) {\n\t\t\tvar y = position.y;\n\t\t\tvar spacing = 1.5 * fontSize;\n\n\t\t\tfor (var i = 0; i < text.length; ++i) {\n\t\t\t\tctx.fillText(text[i], position.x, y);\n\t\t\t\ty+= spacing;\n\t\t\t}\n\t\t} else {\n\t\t\tctx.fillText(text, position.x, position.y);\n\t\t}\n\t}\n\n\tfunction adjustPointPositionForLabelHeight(angle, textSize, position) {\n\t\tif (angle === 90 || angle === 270) {\n\t\t\tposition.y -= (textSize.h / 2);\n\t\t} else if (angle > 270 || angle < 90) {\n\t\t\tposition.y -= textSize.h;\n\t\t}\n\t}\n\n\tfunction drawPointLabels(scale) {\n\t\tvar ctx = scale.ctx;\n\t\tvar getValueOrDefault = helpers.getValueOrDefault;\n\t\tvar opts = scale.options;\n\t\tvar angleLineOpts = opts.angleLines;\n\t\tvar pointLabelOpts = opts.pointLabels;\n\n\t\tctx.lineWidth = angleLineOpts.lineWidth;\n\t\tctx.strokeStyle = angleLineOpts.color;\n\n\t\tvar outerDistance = scale.getDistanceFromCenterForValue(opts.reverse ? scale.min : scale.max);\n\n\t\t// Point Label Font\n\t\tvar plFont = getPointLabelFontOptions(scale);\n\n\t\tctx.textBaseline = 'top';\n\n\t\tfor (var i = getValueCount(scale) - 1; i >= 0; i--) {\n\t\t\tif (angleLineOpts.display) {\n\t\t\t\tvar outerPosition = scale.getPointPosition(i, outerDistance);\n\t\t\t\tctx.beginPath();\n\t\t\t\tctx.moveTo(scale.xCenter, scale.yCenter);\n\t\t\t\tctx.lineTo(outerPosition.x, outerPosition.y);\n\t\t\t\tctx.stroke();\n\t\t\t\tctx.closePath();\n\t\t\t}\n\n\t\t\tif (pointLabelOpts.display) {\n\t\t\t\t// Extra 3px out for some label spacing\n\t\t\t\tvar pointLabelPosition = scale.getPointPosition(i, outerDistance + 5);\n\n\t\t\t\t// Keep this in loop since we may support array properties here\n\t\t\t\tvar pointLabelFontColor = getValueOrDefault(pointLabelOpts.fontColor, globalDefaults.defaultFontColor);\n\t\t\t\tctx.font = plFont.font;\n\t\t\t\tctx.fillStyle = pointLabelFontColor;\n\n\t\t\t\tvar angleRadians = scale.getIndexAngle(i);\n\t\t\t\tvar angle = helpers.toDegrees(angleRadians);\n\t\t\t\tctx.textAlign = getTextAlignForAngle(angle);\n\t\t\t\tadjustPointPositionForLabelHeight(angle, scale._pointLabelSizes[i], pointLabelPosition);\n\t\t\t\tfillText(ctx, scale.pointLabels[i] || '', pointLabelPosition, plFont.size);\n\t\t\t}\n\t\t}\n\t}\n\n\tfunction drawRadiusLine(scale, gridLineOpts, radius, index) {\n\t\tvar ctx = scale.ctx;\n\t\tctx.strokeStyle = helpers.getValueAtIndexOrDefault(gridLineOpts.color, index - 1);\n\t\tctx.lineWidth = helpers.getValueAtIndexOrDefault(gridLineOpts.lineWidth, index - 1);\n\n\t\tif (scale.options.gridLines.circular) {\n\t\t\t// Draw circular arcs between the points\n\t\t\tctx.beginPath();\n\t\t\tctx.arc(scale.xCenter, scale.yCenter, radius, 0, Math.PI * 2);\n\t\t\tctx.closePath();\n\t\t\tctx.stroke();\n\t\t} else {\n\t\t\t// Draw straight lines connecting each index\n\t\t\tvar valueCount = getValueCount(scale);\n\n\t\t\tif (valueCount === 0) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tctx.beginPath();\n\t\t\tvar pointPosition = scale.getPointPosition(0, radius);\n\t\t\tctx.moveTo(pointPosition.x, pointPosition.y);\n\n\t\t\tfor (var i = 1; i < valueCount; i++) {\n\t\t\t\tpointPosition = scale.getPointPosition(i, radius);\n\t\t\t\tctx.lineTo(pointPosition.x, pointPosition.y);\n\t\t\t}\n\n\t\t\tctx.closePath();\n\t\t\tctx.stroke();\n\t\t}\n\t}\n\n\tfunction numberOrZero(param) {\n\t\treturn helpers.isNumber(param) ? param : 0;\n\t}\n\n\tvar LinearRadialScale = Chart.LinearScaleBase.extend({\n\t\tsetDimensions: function() {\n\t\t\tvar me = this;\n\t\t\tvar opts = me.options;\n\t\t\tvar tickOpts = opts.ticks;\n\t\t\t// Set the unconstrained dimension before label rotation\n\t\t\tme.width = me.maxWidth;\n\t\t\tme.height = me.maxHeight;\n\t\t\tme.xCenter = Math.round(me.width / 2);\n\t\t\tme.yCenter = Math.round(me.height / 2);\n\n\t\t\tvar minSize = helpers.min([me.height, me.width]);\n\t\t\tvar tickFontSize = helpers.getValueOrDefault(tickOpts.fontSize, globalDefaults.defaultFontSize);\n\t\t\tme.drawingArea = opts.display ? (minSize / 2) - (tickFontSize / 2 + tickOpts.backdropPaddingY) : (minSize / 2);\n\t\t},\n\t\tdetermineDataLimits: function() {\n\t\t\tvar me = this;\n\t\t\tvar chart = me.chart;\n\t\t\tvar min = Number.POSITIVE_INFINITY;\n\t\t\tvar max = Number.NEGATIVE_INFINITY;\n\n\t\t\thelpers.each(chart.data.datasets, function(dataset, datasetIndex) {\n\t\t\t\tif (chart.isDatasetVisible(datasetIndex)) {\n\t\t\t\t\tvar meta = chart.getDatasetMeta(datasetIndex);\n\n\t\t\t\t\thelpers.each(dataset.data, function(rawValue, index) {\n\t\t\t\t\t\tvar value = +me.getRightValue(rawValue);\n\t\t\t\t\t\tif (isNaN(value) || meta.data[index].hidden) {\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tmin = Math.min(value, min);\n\t\t\t\t\t\tmax = Math.max(value, max);\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t});\n\n\t\t\tme.min = (min === Number.POSITIVE_INFINITY ? 0 : min);\n\t\t\tme.max = (max === Number.NEGATIVE_INFINITY ? 0 : max);\n\n\t\t\t// Common base implementation to handle ticks.min, ticks.max, ticks.beginAtZero\n\t\t\tme.handleTickRangeOptions();\n\t\t},\n\t\tgetTickLimit: function() {\n\t\t\tvar tickOpts = this.options.ticks;\n\t\t\tvar tickFontSize = helpers.getValueOrDefault(tickOpts.fontSize, globalDefaults.defaultFontSize);\n\t\t\treturn Math.min(tickOpts.maxTicksLimit ? tickOpts.maxTicksLimit : 11, Math.ceil(this.drawingArea / (1.5 * tickFontSize)));\n\t\t},\n\t\tconvertTicksToLabels: function() {\n\t\t\tvar me = this;\n\t\t\tChart.LinearScaleBase.prototype.convertTicksToLabels.call(me);\n\n\t\t\t// Point labels\n\t\t\tme.pointLabels = me.chart.data.labels.map(me.options.pointLabels.callback, me);\n\t\t},\n\t\tgetLabelForIndex: function(index, datasetIndex) {\n\t\t\treturn +this.getRightValue(this.chart.data.datasets[datasetIndex].data[index]);\n\t\t},\n\t\tfit: function() {\n\t\t\tif (this.options.pointLabels.display) {\n\t\t\t\tfitWithPointLabels(this);\n\t\t\t} else {\n\t\t\t\tfit(this);\n\t\t\t}\n\t\t},\n\t\t/**\n\t\t * Set radius reductions and determine new radius and center point\n\t\t * @private\n\t\t */\n\t\tsetReductions: function(largestPossibleRadius, furthestLimits, furthestAngles) {\n\t\t\tvar me = this;\n\t\t\tvar radiusReductionLeft = furthestLimits.l / Math.sin(furthestAngles.l);\n\t\t\tvar radiusReductionRight = Math.max(furthestLimits.r - me.width, 0) / Math.sin(furthestAngles.r);\n\t\t\tvar radiusReductionTop = -furthestLimits.t / Math.cos(furthestAngles.t);\n\t\t\tvar radiusReductionBottom = -Math.max(furthestLimits.b - me.height, 0) / Math.cos(furthestAngles.b);\n\n\t\t\tradiusReductionLeft = numberOrZero(radiusReductionLeft);\n\t\t\tradiusReductionRight = numberOrZero(radiusReductionRight);\n\t\t\tradiusReductionTop = numberOrZero(radiusReductionTop);\n\t\t\tradiusReductionBottom = numberOrZero(radiusReductionBottom);\n\n\t\t\tme.drawingArea = Math.min(\n\t\t\t\tMath.round(largestPossibleRadius - (radiusReductionLeft + radiusReductionRight) / 2),\n\t\t\t\tMath.round(largestPossibleRadius - (radiusReductionTop + radiusReductionBottom) / 2));\n\t\t\tme.setCenterPoint(radiusReductionLeft, radiusReductionRight, radiusReductionTop, radiusReductionBottom);\n\t\t},\n\t\tsetCenterPoint: function(leftMovement, rightMovement, topMovement, bottomMovement) {\n\t\t\tvar me = this;\n\t\t\tvar maxRight = me.width - rightMovement - me.drawingArea,\n\t\t\t\tmaxLeft = leftMovement + me.drawingArea,\n\t\t\t\tmaxTop = topMovement + me.drawingArea,\n\t\t\t\tmaxBottom = me.height - bottomMovement - me.drawingArea;\n\n\t\t\tme.xCenter = Math.round(((maxLeft + maxRight) / 2) + me.left);\n\t\t\tme.yCenter = Math.round(((maxTop + maxBottom) / 2) + me.top);\n\t\t},\n\n\t\tgetIndexAngle: function(index) {\n\t\t\tvar angleMultiplier = (Math.PI * 2) / getValueCount(this);\n\t\t\tvar startAngle = this.chart.options && this.chart.options.startAngle ?\n\t\t\t\tthis.chart.options.startAngle :\n\t\t\t\t0;\n\n\t\t\tvar startAngleRadians = startAngle * Math.PI * 2 / 360;\n\n\t\t\t// Start from the top instead of right, so remove a quarter of the circle\n\t\t\treturn index * angleMultiplier + startAngleRadians;\n\t\t},\n\t\tgetDistanceFromCenterForValue: function(value) {\n\t\t\tvar me = this;\n\n\t\t\tif (value === null) {\n\t\t\t\treturn 0; // null always in center\n\t\t\t}\n\n\t\t\t// Take into account half font size + the yPadding of the top value\n\t\t\tvar scalingFactor = me.drawingArea / (me.max - me.min);\n\t\t\tif (me.options.reverse) {\n\t\t\t\treturn (me.max - value) * scalingFactor;\n\t\t\t}\n\t\t\treturn (value - me.min) * scalingFactor;\n\t\t},\n\t\tgetPointPosition: function(index, distanceFromCenter) {\n\t\t\tvar me = this;\n\t\t\tvar thisAngle = me.getIndexAngle(index) - (Math.PI / 2);\n\t\t\treturn {\n\t\t\t\tx: Math.round(Math.cos(thisAngle) * distanceFromCenter) + me.xCenter,\n\t\t\t\ty: Math.round(Math.sin(thisAngle) * distanceFromCenter) + me.yCenter\n\t\t\t};\n\t\t},\n\t\tgetPointPositionForValue: function(index, value) {\n\t\t\treturn this.getPointPosition(index, this.getDistanceFromCenterForValue(value));\n\t\t},\n\n\t\tgetBasePosition: function() {\n\t\t\tvar me = this;\n\t\t\tvar min = me.min;\n\t\t\tvar max = me.max;\n\n\t\t\treturn me.getPointPositionForValue(0,\n\t\t\t\tme.beginAtZero? 0:\n\t\t\t\tmin < 0 && max < 0? max :\n\t\t\t\tmin > 0 && max > 0? min :\n\t\t\t\t0);\n\t\t},\n\n\t\tdraw: function() {\n\t\t\tvar me = this;\n\t\t\tvar opts = me.options;\n\t\t\tvar gridLineOpts = opts.gridLines;\n\t\t\tvar tickOpts = opts.ticks;\n\t\t\tvar getValueOrDefault = helpers.getValueOrDefault;\n\n\t\t\tif (opts.display) {\n\t\t\t\tvar ctx = me.ctx;\n\n\t\t\t\t// Tick Font\n\t\t\t\tvar tickFontSize = getValueOrDefault(tickOpts.fontSize, globalDefaults.defaultFontSize);\n\t\t\t\tvar tickFontStyle = getValueOrDefault(tickOpts.fontStyle, globalDefaults.defaultFontStyle);\n\t\t\t\tvar tickFontFamily = getValueOrDefault(tickOpts.fontFamily, globalDefaults.defaultFontFamily);\n\t\t\t\tvar tickLabelFont = helpers.fontString(tickFontSize, tickFontStyle, tickFontFamily);\n\n\t\t\t\thelpers.each(me.ticks, function(label, index) {\n\t\t\t\t\t// Don't draw a centre value (if it is minimum)\n\t\t\t\t\tif (index > 0 || opts.reverse) {\n\t\t\t\t\t\tvar yCenterOffset = me.getDistanceFromCenterForValue(me.ticksAsNumbers[index]);\n\t\t\t\t\t\tvar yHeight = me.yCenter - yCenterOffset;\n\n\t\t\t\t\t\t// Draw circular lines around the scale\n\t\t\t\t\t\tif (gridLineOpts.display && index !== 0) {\n\t\t\t\t\t\t\tdrawRadiusLine(me, gridLineOpts, yCenterOffset, index);\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif (tickOpts.display) {\n\t\t\t\t\t\t\tvar tickFontColor = getValueOrDefault(tickOpts.fontColor, globalDefaults.defaultFontColor);\n\t\t\t\t\t\t\tctx.font = tickLabelFont;\n\n\t\t\t\t\t\t\tif (tickOpts.showLabelBackdrop) {\n\t\t\t\t\t\t\t\tvar labelWidth = ctx.measureText(label).width;\n\t\t\t\t\t\t\t\tctx.fillStyle = tickOpts.backdropColor;\n\t\t\t\t\t\t\t\tctx.fillRect(\n\t\t\t\t\t\t\t\t\tme.xCenter - labelWidth / 2 - tickOpts.backdropPaddingX,\n\t\t\t\t\t\t\t\t\tyHeight - tickFontSize / 2 - tickOpts.backdropPaddingY,\n\t\t\t\t\t\t\t\t\tlabelWidth + tickOpts.backdropPaddingX * 2,\n\t\t\t\t\t\t\t\t\ttickFontSize + tickOpts.backdropPaddingY * 2\n\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tctx.textAlign = 'center';\n\t\t\t\t\t\t\tctx.textBaseline = 'middle';\n\t\t\t\t\t\t\tctx.fillStyle = tickFontColor;\n\t\t\t\t\t\t\tctx.fillText(label, me.xCenter, yHeight);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t});\n\n\t\t\t\tif (opts.angleLines.display || opts.pointLabels.display) {\n\t\t\t\t\tdrawPointLabels(me);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t});\n\tChart.scaleService.registerScaleType('radialLinear', LinearRadialScale, defaultConfig);\n\n};\n\n},{}],49:[function(require,module,exports){\n/* global window: false */\n'use strict';\n\nvar moment = require(6);\nmoment = typeof(moment) === 'function' ? moment : window.moment;\n\nmodule.exports = function(Chart) {\n\n\tvar helpers = Chart.helpers;\n\tvar interval = {\n\t\tmillisecond: {\n\t\t\tsize: 1,\n\t\t\tsteps: [1, 2, 5, 10, 20, 50, 100, 250, 500]\n\t\t},\n\t\tsecond: {\n\t\t\tsize: 1000,\n\t\t\tsteps: [1, 2, 5, 10, 30]\n\t\t},\n\t\tminute: {\n\t\t\tsize: 60000,\n\t\t\tsteps: [1, 2, 5, 10, 30]\n\t\t},\n\t\thour: {\n\t\t\tsize: 3600000,\n\t\t\tsteps: [1, 2, 3, 6, 12]\n\t\t},\n\t\tday: {\n\t\t\tsize: 86400000,\n\t\t\tsteps: [1, 2, 5]\n\t\t},\n\t\tweek: {\n\t\t\tsize: 604800000,\n\t\t\tmaxStep: 4\n\t\t},\n\t\tmonth: {\n\t\t\tsize: 2.628e9,\n\t\t\tmaxStep: 3\n\t\t},\n\t\tquarter: {\n\t\t\tsize: 7.884e9,\n\t\t\tmaxStep: 4\n\t\t},\n\t\tyear: {\n\t\t\tsize: 3.154e10,\n\t\t\tmaxStep: false\n\t\t}\n\t};\n\n\tvar defaultConfig = {\n\t\tposition: 'bottom',\n\n\t\ttime: {\n\t\t\tparser: false, // false == a pattern string from http://momentjs.com/docs/#/parsing/string-format/ or a custom callback that converts its argument to a moment\n\t\t\tformat: false, // DEPRECATED false == date objects, moment object, callback or a pattern string from http://momentjs.com/docs/#/parsing/string-format/\n\t\t\tunit: false, // false == automatic or override with week, month, year, etc.\n\t\t\tround: false, // none, or override with week, month, year, etc.\n\t\t\tdisplayFormat: false, // DEPRECATED\n\t\t\tisoWeekday: false, // override week start day - see http://momentjs.com/docs/#/get-set/iso-weekday/\n\t\t\tminUnit: 'millisecond',\n\n\t\t\t// defaults to unit's corresponding unitFormat below or override using pattern string from http://momentjs.com/docs/#/displaying/format/\n\t\t\tdisplayFormats: {\n\t\t\t\tmillisecond: 'h:mm:ss.SSS a', // 11:20:01.123 AM,\n\t\t\t\tsecond: 'h:mm:ss a', // 11:20:01 AM\n\t\t\t\tminute: 'h:mm:ss a', // 11:20:01 AM\n\t\t\t\thour: 'MMM D, hA', // Sept 4, 5PM\n\t\t\t\tday: 'll', // Sep 4 2015\n\t\t\t\tweek: 'll', // Week 46, or maybe \"[W]WW - YYYY\" ?\n\t\t\t\tmonth: 'MMM YYYY', // Sept 2015\n\t\t\t\tquarter: '[Q]Q - YYYY', // Q3\n\t\t\t\tyear: 'YYYY' // 2015\n\t\t\t},\n\t\t},\n\t\tticks: {\n\t\t\tautoSkip: false\n\t\t}\n\t};\n\n\t/**\n\t * Helper function to parse time to a moment object\n\t * @param axis {TimeAxis} the time axis\n\t * @param label {Date|string|number|Moment} The thing to parse\n\t * @return {Moment} parsed time\n\t */\n\tfunction parseTime(axis, label) {\n\t\tvar timeOpts = axis.options.time;\n\t\tif (typeof timeOpts.parser === 'string') {\n\t\t\treturn moment(label, timeOpts.parser);\n\t\t}\n\t\tif (typeof timeOpts.parser === 'function') {\n\t\t\treturn timeOpts.parser(label);\n\t\t}\n\t\tif (typeof label.getMonth === 'function' || typeof label === 'number') {\n\t\t\t// Date objects\n\t\t\treturn moment(label);\n\t\t}\n\t\tif (label.isValid && label.isValid()) {\n\t\t\t// Moment support\n\t\t\treturn label;\n\t\t}\n\t\tvar format = timeOpts.format;\n\t\tif (typeof format !== 'string' && format.call) {\n\t\t\t// Custom parsing (return an instance of moment)\n\t\t\tconsole.warn('options.time.format is deprecated and replaced by options.time.parser.');\n\t\t\treturn format(label);\n\t\t}\n\t\t// Moment format parsing\n\t\treturn moment(label, format);\n\t}\n\n\t/**\n\t * Figure out which is the best unit for the scale\n\t * @param minUnit {String} minimum unit to use\n\t * @param min {Number} scale minimum\n\t * @param max {Number} scale maximum\n\t * @return {String} the unit to use\n\t */\n\tfunction determineUnit(minUnit, min, max, maxTicks) {\n\t\tvar units = Object.keys(interval);\n\t\tvar unit;\n\t\tvar numUnits = units.length;\n\n\t\tfor (var i = units.indexOf(minUnit); i < numUnits; i++) {\n\t\t\tunit = units[i];\n\t\t\tvar unitDetails = interval[unit];\n\t\t\tvar steps = (unitDetails.steps && unitDetails.steps[unitDetails.steps.length - 1]) || unitDetails.maxStep;\n\t\t\tif (steps === undefined || Math.ceil((max - min) / (steps * unitDetails.size)) <= maxTicks) {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\treturn unit;\n\t}\n\n\t/**\n\t * Determines how we scale the unit\n\t * @param min {Number} the scale minimum\n\t * @param max {Number} the scale maximum\n\t * @param unit {String} the unit determined by the {@see determineUnit} method\n\t * @return {Number} the axis step size as a multiple of unit\n\t */\n\tfunction determineStepSize(min, max, unit, maxTicks) {\n\t\t// Using our unit, figoure out what we need to scale as\n\t\tvar unitDefinition = interval[unit];\n\t\tvar unitSizeInMilliSeconds = unitDefinition.size;\n\t\tvar sizeInUnits = Math.ceil((max - min) / unitSizeInMilliSeconds);\n\t\tvar multiplier = 1;\n\t\tvar range = max - min;\n\n\t\tif (unitDefinition.steps) {\n\t\t\t// Have an array of steps\n\t\t\tvar numSteps = unitDefinition.steps.length;\n\t\t\tfor (var i = 0; i < numSteps && sizeInUnits > maxTicks; i++) {\n\t\t\t\tmultiplier = unitDefinition.steps[i];\n\t\t\t\tsizeInUnits = Math.ceil(range / (unitSizeInMilliSeconds * multiplier));\n\t\t\t}\n\t\t} else {\n\t\t\twhile (sizeInUnits > maxTicks && maxTicks > 0) {\n\t\t\t\t++multiplier;\n\t\t\t\tsizeInUnits = Math.ceil(range / (unitSizeInMilliSeconds * multiplier));\n\t\t\t}\n\t\t}\n\n\t\treturn multiplier;\n\t}\n\n\t/**\n\t * Helper for generating axis labels.\n\t * @param options {ITimeGeneratorOptions} the options for generation\n\t * @param dataRange {IRange} the data range\n\t * @param niceRange {IRange} the pretty range to display\n\t * @return {Number[]} ticks\n\t */\n\tfunction generateTicks(options, dataRange, niceRange) {\n\t\tvar ticks = [];\n\t\tif (options.maxTicks) {\n\t\t\tvar stepSize = options.stepSize;\n\t\t\tticks.push(options.min !== undefined ? options.min : niceRange.min);\n\t\t\tvar cur = moment(niceRange.min);\n\t\t\twhile (cur.add(stepSize, options.unit).valueOf() < niceRange.max) {\n\t\t\t\tticks.push(cur.valueOf());\n\t\t\t}\n\t\t\tvar realMax = options.max || niceRange.max;\n\t\t\tif (ticks[ticks.length - 1] !== realMax) {\n\t\t\t\tticks.push(realMax);\n\t\t\t}\n\t\t}\n\t\treturn ticks;\n\t}\n\n\t/**\n\t * @function Chart.Ticks.generators.time\n\t * @param options {ITimeGeneratorOptions} the options for generation\n\t * @param dataRange {IRange} the data range\n\t * @return {Number[]} ticks\n\t */\n\tChart.Ticks.generators.time = function(options, dataRange) {\n\t\tvar niceMin;\n\t\tvar niceMax;\n\t\tvar isoWeekday = options.isoWeekday;\n\t\tif (options.unit === 'week' && isoWeekday !== false) {\n\t\t\tniceMin = moment(dataRange.min).startOf('isoWeek').isoWeekday(isoWeekday).valueOf();\n\t\t\tniceMax = moment(dataRange.max).startOf('isoWeek').isoWeekday(isoWeekday);\n\t\t\tif (dataRange.max - niceMax > 0) {\n\t\t\t\tniceMax.add(1, 'week');\n\t\t\t}\n\t\t\tniceMax = niceMax.valueOf();\n\t\t} else {\n\t\t\tniceMin = moment(dataRange.min).startOf(options.unit).valueOf();\n\t\t\tniceMax = moment(dataRange.max).startOf(options.unit);\n\t\t\tif (dataRange.max - niceMax > 0) {\n\t\t\t\tniceMax.add(1, options.unit);\n\t\t\t}\n\t\t\tniceMax = niceMax.valueOf();\n\t\t}\n\t\treturn generateTicks(options, dataRange, {\n\t\t\tmin: niceMin,\n\t\t\tmax: niceMax\n\t\t});\n\t};\n\n\tvar TimeScale = Chart.Scale.extend({\n\t\tinitialize: function() {\n\t\t\tif (!moment) {\n\t\t\t\tthrow new Error('Chart.js - Moment.js could not be found! You must include it before Chart.js to use the time scale. Download at https://momentjs.com');\n\t\t\t}\n\n\t\t\tChart.Scale.prototype.initialize.call(this);\n\t\t},\n\t\tdetermineDataLimits: function() {\n\t\t\tvar me = this;\n\t\t\tvar timeOpts = me.options.time;\n\n\t\t\t// We store the data range as unix millisecond timestamps so dataMin and dataMax will always be integers.\n\t\t\tvar dataMin = Number.MAX_SAFE_INTEGER;\n\t\t\tvar dataMax = Number.MIN_SAFE_INTEGER;\n\n\t\t\tvar chartData = me.chart.data;\n\t\t\tvar parsedData = {\n\t\t\t\tlabels: [],\n\t\t\t\tdatasets: []\n\t\t\t};\n\n\t\t\tvar timestamp;\n\n\t\t\thelpers.each(chartData.labels, function(label, labelIndex) {\n\t\t\t\tvar labelMoment = parseTime(me, label);\n\n\t\t\t\tif (labelMoment.isValid()) {\n\t\t\t\t\t// We need to round the time\n\t\t\t\t\tif (timeOpts.round) {\n\t\t\t\t\t\tlabelMoment.startOf(timeOpts.round);\n\t\t\t\t\t}\n\n\t\t\t\t\ttimestamp = labelMoment.valueOf();\n\t\t\t\t\tdataMin = Math.min(timestamp, dataMin);\n\t\t\t\t\tdataMax = Math.max(timestamp, dataMax);\n\n\t\t\t\t\t// Store this value for later\n\t\t\t\t\tparsedData.labels[labelIndex] = timestamp;\n\t\t\t\t}\n\t\t\t});\n\n\t\t\thelpers.each(chartData.datasets, function(dataset, datasetIndex) {\n\t\t\t\tvar timestamps = [];\n\n\t\t\t\tif (typeof dataset.data[0] === 'object' && dataset.data[0] !== null && me.chart.isDatasetVisible(datasetIndex)) {\n\t\t\t\t\t// We have potential point data, so we need to parse this\n\t\t\t\t\thelpers.each(dataset.data, function(value, dataIndex) {\n\t\t\t\t\t\tvar dataMoment = parseTime(me, me.getRightValue(value));\n\n\t\t\t\t\t\tif (dataMoment.isValid()) {\n\t\t\t\t\t\t\tif (timeOpts.round) {\n\t\t\t\t\t\t\t\tdataMoment.startOf(timeOpts.round);\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\ttimestamp = dataMoment.valueOf();\n\t\t\t\t\t\t\tdataMin = Math.min(timestamp, dataMin);\n\t\t\t\t\t\t\tdataMax = Math.max(timestamp, dataMax);\n\t\t\t\t\t\t\ttimestamps[dataIndex] = timestamp;\n\t\t\t\t\t\t}\n\t\t\t\t\t});\n\t\t\t\t} else {\n\t\t\t\t\t// We have no x coordinates, so use the ones from the labels\n\t\t\t\t\ttimestamps = parsedData.labels.slice();\n\t\t\t\t}\n\n\t\t\t\tparsedData.datasets[datasetIndex] = timestamps;\n\t\t\t});\n\n\t\t\tme.dataMin = dataMin;\n\t\t\tme.dataMax = dataMax;\n\t\t\tme._parsedData = parsedData;\n\t\t},\n\t\tbuildTicks: function() {\n\t\t\tvar me = this;\n\t\t\tvar timeOpts = me.options.time;\n\n\t\t\tvar minTimestamp;\n\t\t\tvar maxTimestamp;\n\t\t\tvar dataMin = me.dataMin;\n\t\t\tvar dataMax = me.dataMax;\n\n\t\t\tif (timeOpts.min) {\n\t\t\t\tvar minMoment = parseTime(me, timeOpts.min);\n\t\t\t\tif (timeOpts.round) {\n\t\t\t\t\tminMoment.round(timeOpts.round);\n\t\t\t\t}\n\t\t\t\tminTimestamp = minMoment.valueOf();\n\t\t\t}\n\n\t\t\tif (timeOpts.max) {\n\t\t\t\tmaxTimestamp = parseTime(me, timeOpts.max).valueOf();\n\t\t\t}\n\n\t\t\tvar maxTicks = me.getLabelCapacity(minTimestamp || dataMin);\n\t\t\tvar unit = timeOpts.unit || determineUnit(timeOpts.minUnit, minTimestamp || dataMin, maxTimestamp || dataMax, maxTicks);\n\t\t\tme.displayFormat = timeOpts.displayFormats[unit];\n\n\t\t\tvar stepSize = timeOpts.stepSize || determineStepSize(minTimestamp || dataMin, maxTimestamp || dataMax, unit, maxTicks);\n\t\t\tme.ticks = Chart.Ticks.generators.time({\n\t\t\t\tmaxTicks: maxTicks,\n\t\t\t\tmin: minTimestamp,\n\t\t\t\tmax: maxTimestamp,\n\t\t\t\tstepSize: stepSize,\n\t\t\t\tunit: unit,\n\t\t\t\tisoWeekday: timeOpts.isoWeekday\n\t\t\t}, {\n\t\t\t\tmin: dataMin,\n\t\t\t\tmax: dataMax\n\t\t\t});\n\n\t\t\t// At this point, we need to update our max and min given the tick values since we have expanded the\n\t\t\t// range of the scale\n\t\t\tme.max = helpers.max(me.ticks);\n\t\t\tme.min = helpers.min(me.ticks);\n\t\t},\n\t\t// Get tooltip label\n\t\tgetLabelForIndex: function(index, datasetIndex) {\n\t\t\tvar me = this;\n\t\t\tvar label = me.chart.data.labels && index < me.chart.data.labels.length ? me.chart.data.labels[index] : '';\n\t\t\tvar value = me.chart.data.datasets[datasetIndex].data[index];\n\n\t\t\tif (value !== null && typeof value === 'object') {\n\t\t\t\tlabel = me.getRightValue(value);\n\t\t\t}\n\n\t\t\t// Format nicely\n\t\t\tif (me.options.time.tooltipFormat) {\n\t\t\t\tlabel = parseTime(me, label).format(me.options.time.tooltipFormat);\n\t\t\t}\n\n\t\t\treturn label;\n\t\t},\n\t\t// Function to format an individual tick mark\n\t\ttickFormatFunction: function(tick, index, ticks) {\n\t\t\tvar formattedTick = tick.format(this.displayFormat);\n\t\t\tvar tickOpts = this.options.ticks;\n\t\t\tvar callback = helpers.getValueOrDefault(tickOpts.callback, tickOpts.userCallback);\n\n\t\t\tif (callback) {\n\t\t\t\treturn callback(formattedTick, index, ticks);\n\t\t\t}\n\t\t\treturn formattedTick;\n\t\t},\n\t\tconvertTicksToLabels: function() {\n\t\t\tvar me = this;\n\t\t\tme.ticksAsTimestamps = me.ticks;\n\t\t\tme.ticks = me.ticks.map(function(tick) {\n\t\t\t\treturn moment(tick);\n\t\t\t}).map(me.tickFormatFunction, me);\n\t\t},\n\t\tgetPixelForOffset: function(offset) {\n\t\t\tvar me = this;\n\t\t\tvar epochWidth = me.max - me.min;\n\t\t\tvar decimal = epochWidth ? (offset - me.min) / epochWidth : 0;\n\n\t\t\tif (me.isHorizontal()) {\n\t\t\t\tvar valueOffset = (me.width * decimal);\n\t\t\t\treturn me.left + Math.round(valueOffset);\n\t\t\t}\n\n\t\t\tvar heightOffset = (me.height * decimal);\n\t\t\treturn me.top + Math.round(heightOffset);\n\t\t},\n\t\tgetPixelForValue: function(value, index, datasetIndex) {\n\t\t\tvar me = this;\n\t\t\tvar offset = null;\n\t\t\tif (index !== undefined && datasetIndex !== undefined) {\n\t\t\t\toffset = me._parsedData.datasets[datasetIndex][index];\n\t\t\t}\n\n\t\t\tif (offset === null) {\n\t\t\t\tif (!value || !value.isValid) {\n\t\t\t\t\t// not already a moment object\n\t\t\t\t\tvalue = parseTime(me, me.getRightValue(value));\n\t\t\t\t}\n\n\t\t\t\tif (value && value.isValid && value.isValid()) {\n\t\t\t\t\toffset = value.valueOf();\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (offset !== null) {\n\t\t\t\treturn me.getPixelForOffset(offset);\n\t\t\t}\n\t\t},\n\t\tgetPixelForTick: function(index) {\n\t\t\treturn this.getPixelForOffset(this.ticksAsTimestamps[index]);\n\t\t},\n\t\tgetValueForPixel: function(pixel) {\n\t\t\tvar me = this;\n\t\t\tvar innerDimension = me.isHorizontal() ? me.width : me.height;\n\t\t\tvar offset = (pixel - (me.isHorizontal() ? me.left : me.top)) / innerDimension;\n\t\t\treturn moment(me.min + (offset * (me.max - me.min)));\n\t\t},\n\t\t// Crude approximation of what the label width might be\n\t\tgetLabelWidth: function(label) {\n\t\t\tvar me = this;\n\t\t\tvar ticks = me.options.ticks;\n\n\t\t\tvar tickLabelWidth = me.ctx.measureText(label).width;\n\t\t\tvar cosRotation = Math.cos(helpers.toRadians(ticks.maxRotation));\n\t\t\tvar sinRotation = Math.sin(helpers.toRadians(ticks.maxRotation));\n\t\t\tvar tickFontSize = helpers.getValueOrDefault(ticks.fontSize, Chart.defaults.global.defaultFontSize);\n\t\t\treturn (tickLabelWidth * cosRotation) + (tickFontSize * sinRotation);\n\t\t},\n\t\tgetLabelCapacity: function(exampleTime) {\n\t\t\tvar me = this;\n\n\t\t\tme.displayFormat = me.options.time.displayFormats.millisecond;\t// Pick the longest format for guestimation\n\t\t\tvar exampleLabel = me.tickFormatFunction(moment(exampleTime), 0, []);\n\t\t\tvar tickLabelWidth = me.getLabelWidth(exampleLabel);\n\n\t\t\tvar innerWidth = me.isHorizontal() ? me.width : me.height;\n\t\t\tvar labelCapacity = innerWidth / tickLabelWidth;\n\t\t\treturn labelCapacity;\n\t\t}\n\t});\n\tChart.scaleService.registerScaleType('time', TimeScale, defaultConfig);\n\n};\n\n},{\"6\":6}]},{},[7])(7)\n});"
  },
  {
    "path": "app_backend/static/plugin/Chart.js-2.6.0/dist/Chart.js",
    "content": "/*!\n * Chart.js\n * http://chartjs.org/\n * Version: 2.6.0\n *\n * Copyright 2017 Nick Downie\n * Released under the MIT license\n * https://github.com/chartjs/Chart.js/blob/master/LICENSE.md\n */\n(function(f){if(typeof exports===\"object\"&&typeof module!==\"undefined\"){module.exports=f()}else if(typeof define===\"function\"&&define.amd){define([],f)}else{var g;if(typeof window!==\"undefined\"){g=window}else if(typeof global!==\"undefined\"){g=global}else if(typeof self!==\"undefined\"){g=self}else{g=this}g.Chart = f()}})(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require==\"function\"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error(\"Cannot find module '\"+o+\"'\");throw f.code=\"MODULE_NOT_FOUND\",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require==\"function\"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){\n\n},{}],2:[function(require,module,exports){\n/* MIT license */\r\nvar colorNames = require(6);\r\n\r\nmodule.exports = {\r\n   getRgba: getRgba,\r\n   getHsla: getHsla,\r\n   getRgb: getRgb,\r\n   getHsl: getHsl,\r\n   getHwb: getHwb,\r\n   getAlpha: getAlpha,\r\n\r\n   hexString: hexString,\r\n   rgbString: rgbString,\r\n   rgbaString: rgbaString,\r\n   percentString: percentString,\r\n   percentaString: percentaString,\r\n   hslString: hslString,\r\n   hslaString: hslaString,\r\n   hwbString: hwbString,\r\n   keyword: keyword\r\n}\r\n\r\nfunction getRgba(string) {\r\n   if (!string) {\r\n      return;\r\n   }\r\n   var abbr =  /^#([a-fA-F0-9]{3})$/,\r\n       hex =  /^#([a-fA-F0-9]{6})$/,\r\n       rgba = /^rgba?\\(\\s*([+-]?\\d+)\\s*,\\s*([+-]?\\d+)\\s*,\\s*([+-]?\\d+)\\s*(?:,\\s*([+-]?[\\d\\.]+)\\s*)?\\)$/,\r\n       per = /^rgba?\\(\\s*([+-]?[\\d\\.]+)\\%\\s*,\\s*([+-]?[\\d\\.]+)\\%\\s*,\\s*([+-]?[\\d\\.]+)\\%\\s*(?:,\\s*([+-]?[\\d\\.]+)\\s*)?\\)$/,\r\n       keyword = /(\\w+)/;\r\n\r\n   var rgb = [0, 0, 0],\r\n       a = 1,\r\n       match = string.match(abbr);\r\n   if (match) {\r\n      match = match[1];\r\n      for (var i = 0; i < rgb.length; i++) {\r\n         rgb[i] = parseInt(match[i] + match[i], 16);\r\n      }\r\n   }\r\n   else if (match = string.match(hex)) {\r\n      match = match[1];\r\n      for (var i = 0; i < rgb.length; i++) {\r\n         rgb[i] = parseInt(match.slice(i * 2, i * 2 + 2), 16);\r\n      }\r\n   }\r\n   else if (match = string.match(rgba)) {\r\n      for (var i = 0; i < rgb.length; i++) {\r\n         rgb[i] = parseInt(match[i + 1]);\r\n      }\r\n      a = parseFloat(match[4]);\r\n   }\r\n   else if (match = string.match(per)) {\r\n      for (var i = 0; i < rgb.length; i++) {\r\n         rgb[i] = Math.round(parseFloat(match[i + 1]) * 2.55);\r\n      }\r\n      a = parseFloat(match[4]);\r\n   }\r\n   else if (match = string.match(keyword)) {\r\n      if (match[1] == \"transparent\") {\r\n         return [0, 0, 0, 0];\r\n      }\r\n      rgb = colorNames[match[1]];\r\n      if (!rgb) {\r\n         return;\r\n      }\r\n   }\r\n\r\n   for (var i = 0; i < rgb.length; i++) {\r\n      rgb[i] = scale(rgb[i], 0, 255);\r\n   }\r\n   if (!a && a != 0) {\r\n      a = 1;\r\n   }\r\n   else {\r\n      a = scale(a, 0, 1);\r\n   }\r\n   rgb[3] = a;\r\n   return rgb;\r\n}\r\n\r\nfunction getHsla(string) {\r\n   if (!string) {\r\n      return;\r\n   }\r\n   var hsl = /^hsla?\\(\\s*([+-]?\\d+)(?:deg)?\\s*,\\s*([+-]?[\\d\\.]+)%\\s*,\\s*([+-]?[\\d\\.]+)%\\s*(?:,\\s*([+-]?[\\d\\.]+)\\s*)?\\)/;\r\n   var match = string.match(hsl);\r\n   if (match) {\r\n      var alpha = parseFloat(match[4]);\r\n      var h = scale(parseInt(match[1]), 0, 360),\r\n          s = scale(parseFloat(match[2]), 0, 100),\r\n          l = scale(parseFloat(match[3]), 0, 100),\r\n          a = scale(isNaN(alpha) ? 1 : alpha, 0, 1);\r\n      return [h, s, l, a];\r\n   }\r\n}\r\n\r\nfunction getHwb(string) {\r\n   if (!string) {\r\n      return;\r\n   }\r\n   var hwb = /^hwb\\(\\s*([+-]?\\d+)(?:deg)?\\s*,\\s*([+-]?[\\d\\.]+)%\\s*,\\s*([+-]?[\\d\\.]+)%\\s*(?:,\\s*([+-]?[\\d\\.]+)\\s*)?\\)/;\r\n   var match = string.match(hwb);\r\n   if (match) {\r\n    var alpha = parseFloat(match[4]);\r\n      var h = scale(parseInt(match[1]), 0, 360),\r\n          w = scale(parseFloat(match[2]), 0, 100),\r\n          b = scale(parseFloat(match[3]), 0, 100),\r\n          a = scale(isNaN(alpha) ? 1 : alpha, 0, 1);\r\n      return [h, w, b, a];\r\n   }\r\n}\r\n\r\nfunction getRgb(string) {\r\n   var rgba = getRgba(string);\r\n   return rgba && rgba.slice(0, 3);\r\n}\r\n\r\nfunction getHsl(string) {\r\n  var hsla = getHsla(string);\r\n  return hsla && hsla.slice(0, 3);\r\n}\r\n\r\nfunction getAlpha(string) {\r\n   var vals = getRgba(string);\r\n   if (vals) {\r\n      return vals[3];\r\n   }\r\n   else if (vals = getHsla(string)) {\r\n      return vals[3];\r\n   }\r\n   else if (vals = getHwb(string)) {\r\n      return vals[3];\r\n   }\r\n}\r\n\r\n// generators\r\nfunction hexString(rgb) {\r\n   return \"#\" + hexDouble(rgb[0]) + hexDouble(rgb[1])\r\n              + hexDouble(rgb[2]);\r\n}\r\n\r\nfunction rgbString(rgba, alpha) {\r\n   if (alpha < 1 || (rgba[3] && rgba[3] < 1)) {\r\n      return rgbaString(rgba, alpha);\r\n   }\r\n   return \"rgb(\" + rgba[0] + \", \" + rgba[1] + \", \" + rgba[2] + \")\";\r\n}\r\n\r\nfunction rgbaString(rgba, alpha) {\r\n   if (alpha === undefined) {\r\n      alpha = (rgba[3] !== undefined ? rgba[3] : 1);\r\n   }\r\n   return \"rgba(\" + rgba[0] + \", \" + rgba[1] + \", \" + rgba[2]\r\n           + \", \" + alpha + \")\";\r\n}\r\n\r\nfunction percentString(rgba, alpha) {\r\n   if (alpha < 1 || (rgba[3] && rgba[3] < 1)) {\r\n      return percentaString(rgba, alpha);\r\n   }\r\n   var r = Math.round(rgba[0]/255 * 100),\r\n       g = Math.round(rgba[1]/255 * 100),\r\n       b = Math.round(rgba[2]/255 * 100);\r\n\r\n   return \"rgb(\" + r + \"%, \" + g + \"%, \" + b + \"%)\";\r\n}\r\n\r\nfunction percentaString(rgba, alpha) {\r\n   var r = Math.round(rgba[0]/255 * 100),\r\n       g = Math.round(rgba[1]/255 * 100),\r\n       b = Math.round(rgba[2]/255 * 100);\r\n   return \"rgba(\" + r + \"%, \" + g + \"%, \" + b + \"%, \" + (alpha || rgba[3] || 1) + \")\";\r\n}\r\n\r\nfunction hslString(hsla, alpha) {\r\n   if (alpha < 1 || (hsla[3] && hsla[3] < 1)) {\r\n      return hslaString(hsla, alpha);\r\n   }\r\n   return \"hsl(\" + hsla[0] + \", \" + hsla[1] + \"%, \" + hsla[2] + \"%)\";\r\n}\r\n\r\nfunction hslaString(hsla, alpha) {\r\n   if (alpha === undefined) {\r\n      alpha = (hsla[3] !== undefined ? hsla[3] : 1);\r\n   }\r\n   return \"hsla(\" + hsla[0] + \", \" + hsla[1] + \"%, \" + hsla[2] + \"%, \"\r\n           + alpha + \")\";\r\n}\r\n\r\n// hwb is a bit different than rgb(a) & hsl(a) since there is no alpha specific syntax\r\n// (hwb have alpha optional & 1 is default value)\r\nfunction hwbString(hwb, alpha) {\r\n   if (alpha === undefined) {\r\n      alpha = (hwb[3] !== undefined ? hwb[3] : 1);\r\n   }\r\n   return \"hwb(\" + hwb[0] + \", \" + hwb[1] + \"%, \" + hwb[2] + \"%\"\r\n           + (alpha !== undefined && alpha !== 1 ? \", \" + alpha : \"\") + \")\";\r\n}\r\n\r\nfunction keyword(rgb) {\r\n  return reverseNames[rgb.slice(0, 3)];\r\n}\r\n\r\n// helpers\r\nfunction scale(num, min, max) {\r\n   return Math.min(Math.max(min, num), max);\r\n}\r\n\r\nfunction hexDouble(num) {\r\n  var str = num.toString(16).toUpperCase();\r\n  return (str.length < 2) ? \"0\" + str : str;\r\n}\r\n\r\n\r\n//create a list of reverse color names\r\nvar reverseNames = {};\r\nfor (var name in colorNames) {\r\n   reverseNames[colorNames[name]] = name;\r\n}\r\n\n},{\"6\":6}],3:[function(require,module,exports){\n/* MIT license */\nvar convert = require(5);\nvar string = require(2);\n\nvar Color = function (obj) {\n\tif (obj instanceof Color) {\n\t\treturn obj;\n\t}\n\tif (!(this instanceof Color)) {\n\t\treturn new Color(obj);\n\t}\n\n\tthis.valid = false;\n\tthis.values = {\n\t\trgb: [0, 0, 0],\n\t\thsl: [0, 0, 0],\n\t\thsv: [0, 0, 0],\n\t\thwb: [0, 0, 0],\n\t\tcmyk: [0, 0, 0, 0],\n\t\talpha: 1\n\t};\n\n\t// parse Color() argument\n\tvar vals;\n\tif (typeof obj === 'string') {\n\t\tvals = string.getRgba(obj);\n\t\tif (vals) {\n\t\t\tthis.setValues('rgb', vals);\n\t\t} else if (vals = string.getHsla(obj)) {\n\t\t\tthis.setValues('hsl', vals);\n\t\t} else if (vals = string.getHwb(obj)) {\n\t\t\tthis.setValues('hwb', vals);\n\t\t}\n\t} else if (typeof obj === 'object') {\n\t\tvals = obj;\n\t\tif (vals.r !== undefined || vals.red !== undefined) {\n\t\t\tthis.setValues('rgb', vals);\n\t\t} else if (vals.l !== undefined || vals.lightness !== undefined) {\n\t\t\tthis.setValues('hsl', vals);\n\t\t} else if (vals.v !== undefined || vals.value !== undefined) {\n\t\t\tthis.setValues('hsv', vals);\n\t\t} else if (vals.w !== undefined || vals.whiteness !== undefined) {\n\t\t\tthis.setValues('hwb', vals);\n\t\t} else if (vals.c !== undefined || vals.cyan !== undefined) {\n\t\t\tthis.setValues('cmyk', vals);\n\t\t}\n\t}\n};\n\nColor.prototype = {\n\tisValid: function () {\n\t\treturn this.valid;\n\t},\n\trgb: function () {\n\t\treturn this.setSpace('rgb', arguments);\n\t},\n\thsl: function () {\n\t\treturn this.setSpace('hsl', arguments);\n\t},\n\thsv: function () {\n\t\treturn this.setSpace('hsv', arguments);\n\t},\n\thwb: function () {\n\t\treturn this.setSpace('hwb', arguments);\n\t},\n\tcmyk: function () {\n\t\treturn this.setSpace('cmyk', arguments);\n\t},\n\n\trgbArray: function () {\n\t\treturn this.values.rgb;\n\t},\n\thslArray: function () {\n\t\treturn this.values.hsl;\n\t},\n\thsvArray: function () {\n\t\treturn this.values.hsv;\n\t},\n\thwbArray: function () {\n\t\tvar values = this.values;\n\t\tif (values.alpha !== 1) {\n\t\t\treturn values.hwb.concat([values.alpha]);\n\t\t}\n\t\treturn values.hwb;\n\t},\n\tcmykArray: function () {\n\t\treturn this.values.cmyk;\n\t},\n\trgbaArray: function () {\n\t\tvar values = this.values;\n\t\treturn values.rgb.concat([values.alpha]);\n\t},\n\thslaArray: function () {\n\t\tvar values = this.values;\n\t\treturn values.hsl.concat([values.alpha]);\n\t},\n\talpha: function (val) {\n\t\tif (val === undefined) {\n\t\t\treturn this.values.alpha;\n\t\t}\n\t\tthis.setValues('alpha', val);\n\t\treturn this;\n\t},\n\n\tred: function (val) {\n\t\treturn this.setChannel('rgb', 0, val);\n\t},\n\tgreen: function (val) {\n\t\treturn this.setChannel('rgb', 1, val);\n\t},\n\tblue: function (val) {\n\t\treturn this.setChannel('rgb', 2, val);\n\t},\n\thue: function (val) {\n\t\tif (val) {\n\t\t\tval %= 360;\n\t\t\tval = val < 0 ? 360 + val : val;\n\t\t}\n\t\treturn this.setChannel('hsl', 0, val);\n\t},\n\tsaturation: function (val) {\n\t\treturn this.setChannel('hsl', 1, val);\n\t},\n\tlightness: function (val) {\n\t\treturn this.setChannel('hsl', 2, val);\n\t},\n\tsaturationv: function (val) {\n\t\treturn this.setChannel('hsv', 1, val);\n\t},\n\twhiteness: function (val) {\n\t\treturn this.setChannel('hwb', 1, val);\n\t},\n\tblackness: function (val) {\n\t\treturn this.setChannel('hwb', 2, val);\n\t},\n\tvalue: function (val) {\n\t\treturn this.setChannel('hsv', 2, val);\n\t},\n\tcyan: function (val) {\n\t\treturn this.setChannel('cmyk', 0, val);\n\t},\n\tmagenta: function (val) {\n\t\treturn this.setChannel('cmyk', 1, val);\n\t},\n\tyellow: function (val) {\n\t\treturn this.setChannel('cmyk', 2, val);\n\t},\n\tblack: function (val) {\n\t\treturn this.setChannel('cmyk', 3, val);\n\t},\n\n\thexString: function () {\n\t\treturn string.hexString(this.values.rgb);\n\t},\n\trgbString: function () {\n\t\treturn string.rgbString(this.values.rgb, this.values.alpha);\n\t},\n\trgbaString: function () {\n\t\treturn string.rgbaString(this.values.rgb, this.values.alpha);\n\t},\n\tpercentString: function () {\n\t\treturn string.percentString(this.values.rgb, this.values.alpha);\n\t},\n\thslString: function () {\n\t\treturn string.hslString(this.values.hsl, this.values.alpha);\n\t},\n\thslaString: function () {\n\t\treturn string.hslaString(this.values.hsl, this.values.alpha);\n\t},\n\thwbString: function () {\n\t\treturn string.hwbString(this.values.hwb, this.values.alpha);\n\t},\n\tkeyword: function () {\n\t\treturn string.keyword(this.values.rgb, this.values.alpha);\n\t},\n\n\trgbNumber: function () {\n\t\tvar rgb = this.values.rgb;\n\t\treturn (rgb[0] << 16) | (rgb[1] << 8) | rgb[2];\n\t},\n\n\tluminosity: function () {\n\t\t// http://www.w3.org/TR/WCAG20/#relativeluminancedef\n\t\tvar rgb = this.values.rgb;\n\t\tvar lum = [];\n\t\tfor (var i = 0; i < rgb.length; i++) {\n\t\t\tvar chan = rgb[i] / 255;\n\t\t\tlum[i] = (chan <= 0.03928) ? chan / 12.92 : Math.pow(((chan + 0.055) / 1.055), 2.4);\n\t\t}\n\t\treturn 0.2126 * lum[0] + 0.7152 * lum[1] + 0.0722 * lum[2];\n\t},\n\n\tcontrast: function (color2) {\n\t\t// http://www.w3.org/TR/WCAG20/#contrast-ratiodef\n\t\tvar lum1 = this.luminosity();\n\t\tvar lum2 = color2.luminosity();\n\t\tif (lum1 > lum2) {\n\t\t\treturn (lum1 + 0.05) / (lum2 + 0.05);\n\t\t}\n\t\treturn (lum2 + 0.05) / (lum1 + 0.05);\n\t},\n\n\tlevel: function (color2) {\n\t\tvar contrastRatio = this.contrast(color2);\n\t\tif (contrastRatio >= 7.1) {\n\t\t\treturn 'AAA';\n\t\t}\n\n\t\treturn (contrastRatio >= 4.5) ? 'AA' : '';\n\t},\n\n\tdark: function () {\n\t\t// YIQ equation from http://24ways.org/2010/calculating-color-contrast\n\t\tvar rgb = this.values.rgb;\n\t\tvar yiq = (rgb[0] * 299 + rgb[1] * 587 + rgb[2] * 114) / 1000;\n\t\treturn yiq < 128;\n\t},\n\n\tlight: function () {\n\t\treturn !this.dark();\n\t},\n\n\tnegate: function () {\n\t\tvar rgb = [];\n\t\tfor (var i = 0; i < 3; i++) {\n\t\t\trgb[i] = 255 - this.values.rgb[i];\n\t\t}\n\t\tthis.setValues('rgb', rgb);\n\t\treturn this;\n\t},\n\n\tlighten: function (ratio) {\n\t\tvar hsl = this.values.hsl;\n\t\thsl[2] += hsl[2] * ratio;\n\t\tthis.setValues('hsl', hsl);\n\t\treturn this;\n\t},\n\n\tdarken: function (ratio) {\n\t\tvar hsl = this.values.hsl;\n\t\thsl[2] -= hsl[2] * ratio;\n\t\tthis.setValues('hsl', hsl);\n\t\treturn this;\n\t},\n\n\tsaturate: function (ratio) {\n\t\tvar hsl = this.values.hsl;\n\t\thsl[1] += hsl[1] * ratio;\n\t\tthis.setValues('hsl', hsl);\n\t\treturn this;\n\t},\n\n\tdesaturate: function (ratio) {\n\t\tvar hsl = this.values.hsl;\n\t\thsl[1] -= hsl[1] * ratio;\n\t\tthis.setValues('hsl', hsl);\n\t\treturn this;\n\t},\n\n\twhiten: function (ratio) {\n\t\tvar hwb = this.values.hwb;\n\t\thwb[1] += hwb[1] * ratio;\n\t\tthis.setValues('hwb', hwb);\n\t\treturn this;\n\t},\n\n\tblacken: function (ratio) {\n\t\tvar hwb = this.values.hwb;\n\t\thwb[2] += hwb[2] * ratio;\n\t\tthis.setValues('hwb', hwb);\n\t\treturn this;\n\t},\n\n\tgreyscale: function () {\n\t\tvar rgb = this.values.rgb;\n\t\t// http://en.wikipedia.org/wiki/Grayscale#Converting_color_to_grayscale\n\t\tvar val = rgb[0] * 0.3 + rgb[1] * 0.59 + rgb[2] * 0.11;\n\t\tthis.setValues('rgb', [val, val, val]);\n\t\treturn this;\n\t},\n\n\tclearer: function (ratio) {\n\t\tvar alpha = this.values.alpha;\n\t\tthis.setValues('alpha', alpha - (alpha * ratio));\n\t\treturn this;\n\t},\n\n\topaquer: function (ratio) {\n\t\tvar alpha = this.values.alpha;\n\t\tthis.setValues('alpha', alpha + (alpha * ratio));\n\t\treturn this;\n\t},\n\n\trotate: function (degrees) {\n\t\tvar hsl = this.values.hsl;\n\t\tvar hue = (hsl[0] + degrees) % 360;\n\t\thsl[0] = hue < 0 ? 360 + hue : hue;\n\t\tthis.setValues('hsl', hsl);\n\t\treturn this;\n\t},\n\n\t/**\n\t * Ported from sass implementation in C\n\t * https://github.com/sass/libsass/blob/0e6b4a2850092356aa3ece07c6b249f0221caced/functions.cpp#L209\n\t */\n\tmix: function (mixinColor, weight) {\n\t\tvar color1 = this;\n\t\tvar color2 = mixinColor;\n\t\tvar p = weight === undefined ? 0.5 : weight;\n\n\t\tvar w = 2 * p - 1;\n\t\tvar a = color1.alpha() - color2.alpha();\n\n\t\tvar w1 = (((w * a === -1) ? w : (w + a) / (1 + w * a)) + 1) / 2.0;\n\t\tvar w2 = 1 - w1;\n\n\t\treturn this\n\t\t\t.rgb(\n\t\t\t\tw1 * color1.red() + w2 * color2.red(),\n\t\t\t\tw1 * color1.green() + w2 * color2.green(),\n\t\t\t\tw1 * color1.blue() + w2 * color2.blue()\n\t\t\t)\n\t\t\t.alpha(color1.alpha() * p + color2.alpha() * (1 - p));\n\t},\n\n\ttoJSON: function () {\n\t\treturn this.rgb();\n\t},\n\n\tclone: function () {\n\t\t// NOTE(SB): using node-clone creates a dependency to Buffer when using browserify,\n\t\t// making the final build way to big to embed in Chart.js. So let's do it manually,\n\t\t// assuming that values to clone are 1 dimension arrays containing only numbers,\n\t\t// except 'alpha' which is a number.\n\t\tvar result = new Color();\n\t\tvar source = this.values;\n\t\tvar target = result.values;\n\t\tvar value, type;\n\n\t\tfor (var prop in source) {\n\t\t\tif (source.hasOwnProperty(prop)) {\n\t\t\t\tvalue = source[prop];\n\t\t\t\ttype = ({}).toString.call(value);\n\t\t\t\tif (type === '[object Array]') {\n\t\t\t\t\ttarget[prop] = value.slice(0);\n\t\t\t\t} else if (type === '[object Number]') {\n\t\t\t\t\ttarget[prop] = value;\n\t\t\t\t} else {\n\t\t\t\t\tconsole.error('unexpected color value:', value);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn result;\n\t}\n};\n\nColor.prototype.spaces = {\n\trgb: ['red', 'green', 'blue'],\n\thsl: ['hue', 'saturation', 'lightness'],\n\thsv: ['hue', 'saturation', 'value'],\n\thwb: ['hue', 'whiteness', 'blackness'],\n\tcmyk: ['cyan', 'magenta', 'yellow', 'black']\n};\n\nColor.prototype.maxes = {\n\trgb: [255, 255, 255],\n\thsl: [360, 100, 100],\n\thsv: [360, 100, 100],\n\thwb: [360, 100, 100],\n\tcmyk: [100, 100, 100, 100]\n};\n\nColor.prototype.getValues = function (space) {\n\tvar values = this.values;\n\tvar vals = {};\n\n\tfor (var i = 0; i < space.length; i++) {\n\t\tvals[space.charAt(i)] = values[space][i];\n\t}\n\n\tif (values.alpha !== 1) {\n\t\tvals.a = values.alpha;\n\t}\n\n\t// {r: 255, g: 255, b: 255, a: 0.4}\n\treturn vals;\n};\n\nColor.prototype.setValues = function (space, vals) {\n\tvar values = this.values;\n\tvar spaces = this.spaces;\n\tvar maxes = this.maxes;\n\tvar alpha = 1;\n\tvar i;\n\n\tthis.valid = true;\n\n\tif (space === 'alpha') {\n\t\talpha = vals;\n\t} else if (vals.length) {\n\t\t// [10, 10, 10]\n\t\tvalues[space] = vals.slice(0, space.length);\n\t\talpha = vals[space.length];\n\t} else if (vals[space.charAt(0)] !== undefined) {\n\t\t// {r: 10, g: 10, b: 10}\n\t\tfor (i = 0; i < space.length; i++) {\n\t\t\tvalues[space][i] = vals[space.charAt(i)];\n\t\t}\n\n\t\talpha = vals.a;\n\t} else if (vals[spaces[space][0]] !== undefined) {\n\t\t// {red: 10, green: 10, blue: 10}\n\t\tvar chans = spaces[space];\n\n\t\tfor (i = 0; i < space.length; i++) {\n\t\t\tvalues[space][i] = vals[chans[i]];\n\t\t}\n\n\t\talpha = vals.alpha;\n\t}\n\n\tvalues.alpha = Math.max(0, Math.min(1, (alpha === undefined ? values.alpha : alpha)));\n\n\tif (space === 'alpha') {\n\t\treturn false;\n\t}\n\n\tvar capped;\n\n\t// cap values of the space prior converting all values\n\tfor (i = 0; i < space.length; i++) {\n\t\tcapped = Math.max(0, Math.min(maxes[space][i], values[space][i]));\n\t\tvalues[space][i] = Math.round(capped);\n\t}\n\n\t// convert to all the other color spaces\n\tfor (var sname in spaces) {\n\t\tif (sname !== space) {\n\t\t\tvalues[sname] = convert[space][sname](values[space]);\n\t\t}\n\t}\n\n\treturn true;\n};\n\nColor.prototype.setSpace = function (space, args) {\n\tvar vals = args[0];\n\n\tif (vals === undefined) {\n\t\t// color.rgb()\n\t\treturn this.getValues(space);\n\t}\n\n\t// color.rgb(10, 10, 10)\n\tif (typeof vals === 'number') {\n\t\tvals = Array.prototype.slice.call(args);\n\t}\n\n\tthis.setValues(space, vals);\n\treturn this;\n};\n\nColor.prototype.setChannel = function (space, index, val) {\n\tvar svalues = this.values[space];\n\tif (val === undefined) {\n\t\t// color.red()\n\t\treturn svalues[index];\n\t} else if (val === svalues[index]) {\n\t\t// color.red(color.red())\n\t\treturn this;\n\t}\n\n\t// color.red(100)\n\tsvalues[index] = val;\n\tthis.setValues(space, svalues);\n\n\treturn this;\n};\n\nif (typeof window !== 'undefined') {\n\twindow.Color = Color;\n}\n\nmodule.exports = Color;\n\n},{\"2\":2,\"5\":5}],4:[function(require,module,exports){\n/* MIT license */\n\nmodule.exports = {\n  rgb2hsl: rgb2hsl,\n  rgb2hsv: rgb2hsv,\n  rgb2hwb: rgb2hwb,\n  rgb2cmyk: rgb2cmyk,\n  rgb2keyword: rgb2keyword,\n  rgb2xyz: rgb2xyz,\n  rgb2lab: rgb2lab,\n  rgb2lch: rgb2lch,\n\n  hsl2rgb: hsl2rgb,\n  hsl2hsv: hsl2hsv,\n  hsl2hwb: hsl2hwb,\n  hsl2cmyk: hsl2cmyk,\n  hsl2keyword: hsl2keyword,\n\n  hsv2rgb: hsv2rgb,\n  hsv2hsl: hsv2hsl,\n  hsv2hwb: hsv2hwb,\n  hsv2cmyk: hsv2cmyk,\n  hsv2keyword: hsv2keyword,\n\n  hwb2rgb: hwb2rgb,\n  hwb2hsl: hwb2hsl,\n  hwb2hsv: hwb2hsv,\n  hwb2cmyk: hwb2cmyk,\n  hwb2keyword: hwb2keyword,\n\n  cmyk2rgb: cmyk2rgb,\n  cmyk2hsl: cmyk2hsl,\n  cmyk2hsv: cmyk2hsv,\n  cmyk2hwb: cmyk2hwb,\n  cmyk2keyword: cmyk2keyword,\n\n  keyword2rgb: keyword2rgb,\n  keyword2hsl: keyword2hsl,\n  keyword2hsv: keyword2hsv,\n  keyword2hwb: keyword2hwb,\n  keyword2cmyk: keyword2cmyk,\n  keyword2lab: keyword2lab,\n  keyword2xyz: keyword2xyz,\n\n  xyz2rgb: xyz2rgb,\n  xyz2lab: xyz2lab,\n  xyz2lch: xyz2lch,\n\n  lab2xyz: lab2xyz,\n  lab2rgb: lab2rgb,\n  lab2lch: lab2lch,\n\n  lch2lab: lch2lab,\n  lch2xyz: lch2xyz,\n  lch2rgb: lch2rgb\n}\n\n\nfunction rgb2hsl(rgb) {\n  var r = rgb[0]/255,\n      g = rgb[1]/255,\n      b = rgb[2]/255,\n      min = Math.min(r, g, b),\n      max = Math.max(r, g, b),\n      delta = max - min,\n      h, s, l;\n\n  if (max == min)\n    h = 0;\n  else if (r == max)\n    h = (g - b) / delta;\n  else if (g == max)\n    h = 2 + (b - r) / delta;\n  else if (b == max)\n    h = 4 + (r - g)/ delta;\n\n  h = Math.min(h * 60, 360);\n\n  if (h < 0)\n    h += 360;\n\n  l = (min + max) / 2;\n\n  if (max == min)\n    s = 0;\n  else if (l <= 0.5)\n    s = delta / (max + min);\n  else\n    s = delta / (2 - max - min);\n\n  return [h, s * 100, l * 100];\n}\n\nfunction rgb2hsv(rgb) {\n  var r = rgb[0],\n      g = rgb[1],\n      b = rgb[2],\n      min = Math.min(r, g, b),\n      max = Math.max(r, g, b),\n      delta = max - min,\n      h, s, v;\n\n  if (max == 0)\n    s = 0;\n  else\n    s = (delta/max * 1000)/10;\n\n  if (max == min)\n    h = 0;\n  else if (r == max)\n    h = (g - b) / delta;\n  else if (g == max)\n    h = 2 + (b - r) / delta;\n  else if (b == max)\n    h = 4 + (r - g) / delta;\n\n  h = Math.min(h * 60, 360);\n\n  if (h < 0)\n    h += 360;\n\n  v = ((max / 255) * 1000) / 10;\n\n  return [h, s, v];\n}\n\nfunction rgb2hwb(rgb) {\n  var r = rgb[0],\n      g = rgb[1],\n      b = rgb[2],\n      h = rgb2hsl(rgb)[0],\n      w = 1/255 * Math.min(r, Math.min(g, b)),\n      b = 1 - 1/255 * Math.max(r, Math.max(g, b));\n\n  return [h, w * 100, b * 100];\n}\n\nfunction rgb2cmyk(rgb) {\n  var r = rgb[0] / 255,\n      g = rgb[1] / 255,\n      b = rgb[2] / 255,\n      c, m, y, k;\n\n  k = Math.min(1 - r, 1 - g, 1 - b);\n  c = (1 - r - k) / (1 - k) || 0;\n  m = (1 - g - k) / (1 - k) || 0;\n  y = (1 - b - k) / (1 - k) || 0;\n  return [c * 100, m * 100, y * 100, k * 100];\n}\n\nfunction rgb2keyword(rgb) {\n  return reverseKeywords[JSON.stringify(rgb)];\n}\n\nfunction rgb2xyz(rgb) {\n  var r = rgb[0] / 255,\n      g = rgb[1] / 255,\n      b = rgb[2] / 255;\n\n  // assume sRGB\n  r = r > 0.04045 ? Math.pow(((r + 0.055) / 1.055), 2.4) : (r / 12.92);\n  g = g > 0.04045 ? Math.pow(((g + 0.055) / 1.055), 2.4) : (g / 12.92);\n  b = b > 0.04045 ? Math.pow(((b + 0.055) / 1.055), 2.4) : (b / 12.92);\n\n  var x = (r * 0.4124) + (g * 0.3576) + (b * 0.1805);\n  var y = (r * 0.2126) + (g * 0.7152) + (b * 0.0722);\n  var z = (r * 0.0193) + (g * 0.1192) + (b * 0.9505);\n\n  return [x * 100, y *100, z * 100];\n}\n\nfunction rgb2lab(rgb) {\n  var xyz = rgb2xyz(rgb),\n        x = xyz[0],\n        y = xyz[1],\n        z = xyz[2],\n        l, a, b;\n\n  x /= 95.047;\n  y /= 100;\n  z /= 108.883;\n\n  x = x > 0.008856 ? Math.pow(x, 1/3) : (7.787 * x) + (16 / 116);\n  y = y > 0.008856 ? Math.pow(y, 1/3) : (7.787 * y) + (16 / 116);\n  z = z > 0.008856 ? Math.pow(z, 1/3) : (7.787 * z) + (16 / 116);\n\n  l = (116 * y) - 16;\n  a = 500 * (x - y);\n  b = 200 * (y - z);\n\n  return [l, a, b];\n}\n\nfunction rgb2lch(args) {\n  return lab2lch(rgb2lab(args));\n}\n\nfunction hsl2rgb(hsl) {\n  var h = hsl[0] / 360,\n      s = hsl[1] / 100,\n      l = hsl[2] / 100,\n      t1, t2, t3, rgb, val;\n\n  if (s == 0) {\n    val = l * 255;\n    return [val, val, val];\n  }\n\n  if (l < 0.5)\n    t2 = l * (1 + s);\n  else\n    t2 = l + s - l * s;\n  t1 = 2 * l - t2;\n\n  rgb = [0, 0, 0];\n  for (var i = 0; i < 3; i++) {\n    t3 = h + 1 / 3 * - (i - 1);\n    t3 < 0 && t3++;\n    t3 > 1 && t3--;\n\n    if (6 * t3 < 1)\n      val = t1 + (t2 - t1) * 6 * t3;\n    else if (2 * t3 < 1)\n      val = t2;\n    else if (3 * t3 < 2)\n      val = t1 + (t2 - t1) * (2 / 3 - t3) * 6;\n    else\n      val = t1;\n\n    rgb[i] = val * 255;\n  }\n\n  return rgb;\n}\n\nfunction hsl2hsv(hsl) {\n  var h = hsl[0],\n      s = hsl[1] / 100,\n      l = hsl[2] / 100,\n      sv, v;\n\n  if(l === 0) {\n      // no need to do calc on black\n      // also avoids divide by 0 error\n      return [0, 0, 0];\n  }\n\n  l *= 2;\n  s *= (l <= 1) ? l : 2 - l;\n  v = (l + s) / 2;\n  sv = (2 * s) / (l + s);\n  return [h, sv * 100, v * 100];\n}\n\nfunction hsl2hwb(args) {\n  return rgb2hwb(hsl2rgb(args));\n}\n\nfunction hsl2cmyk(args) {\n  return rgb2cmyk(hsl2rgb(args));\n}\n\nfunction hsl2keyword(args) {\n  return rgb2keyword(hsl2rgb(args));\n}\n\n\nfunction hsv2rgb(hsv) {\n  var h = hsv[0] / 60,\n      s = hsv[1] / 100,\n      v = hsv[2] / 100,\n      hi = Math.floor(h) % 6;\n\n  var f = h - Math.floor(h),\n      p = 255 * v * (1 - s),\n      q = 255 * v * (1 - (s * f)),\n      t = 255 * v * (1 - (s * (1 - f))),\n      v = 255 * v;\n\n  switch(hi) {\n    case 0:\n      return [v, t, p];\n    case 1:\n      return [q, v, p];\n    case 2:\n      return [p, v, t];\n    case 3:\n      return [p, q, v];\n    case 4:\n      return [t, p, v];\n    case 5:\n      return [v, p, q];\n  }\n}\n\nfunction hsv2hsl(hsv) {\n  var h = hsv[0],\n      s = hsv[1] / 100,\n      v = hsv[2] / 100,\n      sl, l;\n\n  l = (2 - s) * v;\n  sl = s * v;\n  sl /= (l <= 1) ? l : 2 - l;\n  sl = sl || 0;\n  l /= 2;\n  return [h, sl * 100, l * 100];\n}\n\nfunction hsv2hwb(args) {\n  return rgb2hwb(hsv2rgb(args))\n}\n\nfunction hsv2cmyk(args) {\n  return rgb2cmyk(hsv2rgb(args));\n}\n\nfunction hsv2keyword(args) {\n  return rgb2keyword(hsv2rgb(args));\n}\n\n// http://dev.w3.org/csswg/css-color/#hwb-to-rgb\nfunction hwb2rgb(hwb) {\n  var h = hwb[0] / 360,\n      wh = hwb[1] / 100,\n      bl = hwb[2] / 100,\n      ratio = wh + bl,\n      i, v, f, n;\n\n  // wh + bl cant be > 1\n  if (ratio > 1) {\n    wh /= ratio;\n    bl /= ratio;\n  }\n\n  i = Math.floor(6 * h);\n  v = 1 - bl;\n  f = 6 * h - i;\n  if ((i & 0x01) != 0) {\n    f = 1 - f;\n  }\n  n = wh + f * (v - wh);  // linear interpolation\n\n  switch (i) {\n    default:\n    case 6:\n    case 0: r = v; g = n; b = wh; break;\n    case 1: r = n; g = v; b = wh; break;\n    case 2: r = wh; g = v; b = n; break;\n    case 3: r = wh; g = n; b = v; break;\n    case 4: r = n; g = wh; b = v; break;\n    case 5: r = v; g = wh; b = n; break;\n  }\n\n  return [r * 255, g * 255, b * 255];\n}\n\nfunction hwb2hsl(args) {\n  return rgb2hsl(hwb2rgb(args));\n}\n\nfunction hwb2hsv(args) {\n  return rgb2hsv(hwb2rgb(args));\n}\n\nfunction hwb2cmyk(args) {\n  return rgb2cmyk(hwb2rgb(args));\n}\n\nfunction hwb2keyword(args) {\n  return rgb2keyword(hwb2rgb(args));\n}\n\nfunction cmyk2rgb(cmyk) {\n  var c = cmyk[0] / 100,\n      m = cmyk[1] / 100,\n      y = cmyk[2] / 100,\n      k = cmyk[3] / 100,\n      r, g, b;\n\n  r = 1 - Math.min(1, c * (1 - k) + k);\n  g = 1 - Math.min(1, m * (1 - k) + k);\n  b = 1 - Math.min(1, y * (1 - k) + k);\n  return [r * 255, g * 255, b * 255];\n}\n\nfunction cmyk2hsl(args) {\n  return rgb2hsl(cmyk2rgb(args));\n}\n\nfunction cmyk2hsv(args) {\n  return rgb2hsv(cmyk2rgb(args));\n}\n\nfunction cmyk2hwb(args) {\n  return rgb2hwb(cmyk2rgb(args));\n}\n\nfunction cmyk2keyword(args) {\n  return rgb2keyword(cmyk2rgb(args));\n}\n\n\nfunction xyz2rgb(xyz) {\n  var x = xyz[0] / 100,\n      y = xyz[1] / 100,\n      z = xyz[2] / 100,\n      r, g, b;\n\n  r = (x * 3.2406) + (y * -1.5372) + (z * -0.4986);\n  g = (x * -0.9689) + (y * 1.8758) + (z * 0.0415);\n  b = (x * 0.0557) + (y * -0.2040) + (z * 1.0570);\n\n  // assume sRGB\n  r = r > 0.0031308 ? ((1.055 * Math.pow(r, 1.0 / 2.4)) - 0.055)\n    : r = (r * 12.92);\n\n  g = g > 0.0031308 ? ((1.055 * Math.pow(g, 1.0 / 2.4)) - 0.055)\n    : g = (g * 12.92);\n\n  b = b > 0.0031308 ? ((1.055 * Math.pow(b, 1.0 / 2.4)) - 0.055)\n    : b = (b * 12.92);\n\n  r = Math.min(Math.max(0, r), 1);\n  g = Math.min(Math.max(0, g), 1);\n  b = Math.min(Math.max(0, b), 1);\n\n  return [r * 255, g * 255, b * 255];\n}\n\nfunction xyz2lab(xyz) {\n  var x = xyz[0],\n      y = xyz[1],\n      z = xyz[2],\n      l, a, b;\n\n  x /= 95.047;\n  y /= 100;\n  z /= 108.883;\n\n  x = x > 0.008856 ? Math.pow(x, 1/3) : (7.787 * x) + (16 / 116);\n  y = y > 0.008856 ? Math.pow(y, 1/3) : (7.787 * y) + (16 / 116);\n  z = z > 0.008856 ? Math.pow(z, 1/3) : (7.787 * z) + (16 / 116);\n\n  l = (116 * y) - 16;\n  a = 500 * (x - y);\n  b = 200 * (y - z);\n\n  return [l, a, b];\n}\n\nfunction xyz2lch(args) {\n  return lab2lch(xyz2lab(args));\n}\n\nfunction lab2xyz(lab) {\n  var l = lab[0],\n      a = lab[1],\n      b = lab[2],\n      x, y, z, y2;\n\n  if (l <= 8) {\n    y = (l * 100) / 903.3;\n    y2 = (7.787 * (y / 100)) + (16 / 116);\n  } else {\n    y = 100 * Math.pow((l + 16) / 116, 3);\n    y2 = Math.pow(y / 100, 1/3);\n  }\n\n  x = x / 95.047 <= 0.008856 ? x = (95.047 * ((a / 500) + y2 - (16 / 116))) / 7.787 : 95.047 * Math.pow((a / 500) + y2, 3);\n\n  z = z / 108.883 <= 0.008859 ? z = (108.883 * (y2 - (b / 200) - (16 / 116))) / 7.787 : 108.883 * Math.pow(y2 - (b / 200), 3);\n\n  return [x, y, z];\n}\n\nfunction lab2lch(lab) {\n  var l = lab[0],\n      a = lab[1],\n      b = lab[2],\n      hr, h, c;\n\n  hr = Math.atan2(b, a);\n  h = hr * 360 / 2 / Math.PI;\n  if (h < 0) {\n    h += 360;\n  }\n  c = Math.sqrt(a * a + b * b);\n  return [l, c, h];\n}\n\nfunction lab2rgb(args) {\n  return xyz2rgb(lab2xyz(args));\n}\n\nfunction lch2lab(lch) {\n  var l = lch[0],\n      c = lch[1],\n      h = lch[2],\n      a, b, hr;\n\n  hr = h / 360 * 2 * Math.PI;\n  a = c * Math.cos(hr);\n  b = c * Math.sin(hr);\n  return [l, a, b];\n}\n\nfunction lch2xyz(args) {\n  return lab2xyz(lch2lab(args));\n}\n\nfunction lch2rgb(args) {\n  return lab2rgb(lch2lab(args));\n}\n\nfunction keyword2rgb(keyword) {\n  return cssKeywords[keyword];\n}\n\nfunction keyword2hsl(args) {\n  return rgb2hsl(keyword2rgb(args));\n}\n\nfunction keyword2hsv(args) {\n  return rgb2hsv(keyword2rgb(args));\n}\n\nfunction keyword2hwb(args) {\n  return rgb2hwb(keyword2rgb(args));\n}\n\nfunction keyword2cmyk(args) {\n  return rgb2cmyk(keyword2rgb(args));\n}\n\nfunction keyword2lab(args) {\n  return rgb2lab(keyword2rgb(args));\n}\n\nfunction keyword2xyz(args) {\n  return rgb2xyz(keyword2rgb(args));\n}\n\nvar cssKeywords = {\n  aliceblue:  [240,248,255],\n  antiquewhite: [250,235,215],\n  aqua: [0,255,255],\n  aquamarine: [127,255,212],\n  azure:  [240,255,255],\n  beige:  [245,245,220],\n  bisque: [255,228,196],\n  black:  [0,0,0],\n  blanchedalmond: [255,235,205],\n  blue: [0,0,255],\n  blueviolet: [138,43,226],\n  brown:  [165,42,42],\n  burlywood:  [222,184,135],\n  cadetblue:  [95,158,160],\n  chartreuse: [127,255,0],\n  chocolate:  [210,105,30],\n  coral:  [255,127,80],\n  cornflowerblue: [100,149,237],\n  cornsilk: [255,248,220],\n  crimson:  [220,20,60],\n  cyan: [0,255,255],\n  darkblue: [0,0,139],\n  darkcyan: [0,139,139],\n  darkgoldenrod:  [184,134,11],\n  darkgray: [169,169,169],\n  darkgreen:  [0,100,0],\n  darkgrey: [169,169,169],\n  darkkhaki:  [189,183,107],\n  darkmagenta:  [139,0,139],\n  darkolivegreen: [85,107,47],\n  darkorange: [255,140,0],\n  darkorchid: [153,50,204],\n  darkred:  [139,0,0],\n  darksalmon: [233,150,122],\n  darkseagreen: [143,188,143],\n  darkslateblue:  [72,61,139],\n  darkslategray:  [47,79,79],\n  darkslategrey:  [47,79,79],\n  darkturquoise:  [0,206,209],\n  darkviolet: [148,0,211],\n  deeppink: [255,20,147],\n  deepskyblue:  [0,191,255],\n  dimgray:  [105,105,105],\n  dimgrey:  [105,105,105],\n  dodgerblue: [30,144,255],\n  firebrick:  [178,34,34],\n  floralwhite:  [255,250,240],\n  forestgreen:  [34,139,34],\n  fuchsia:  [255,0,255],\n  gainsboro:  [220,220,220],\n  ghostwhite: [248,248,255],\n  gold: [255,215,0],\n  goldenrod:  [218,165,32],\n  gray: [128,128,128],\n  green:  [0,128,0],\n  greenyellow:  [173,255,47],\n  grey: [128,128,128],\n  honeydew: [240,255,240],\n  hotpink:  [255,105,180],\n  indianred:  [205,92,92],\n  indigo: [75,0,130],\n  ivory:  [255,255,240],\n  khaki:  [240,230,140],\n  lavender: [230,230,250],\n  lavenderblush:  [255,240,245],\n  lawngreen:  [124,252,0],\n  lemonchiffon: [255,250,205],\n  lightblue:  [173,216,230],\n  lightcoral: [240,128,128],\n  lightcyan:  [224,255,255],\n  lightgoldenrodyellow: [250,250,210],\n  lightgray:  [211,211,211],\n  lightgreen: [144,238,144],\n  lightgrey:  [211,211,211],\n  lightpink:  [255,182,193],\n  lightsalmon:  [255,160,122],\n  lightseagreen:  [32,178,170],\n  lightskyblue: [135,206,250],\n  lightslategray: [119,136,153],\n  lightslategrey: [119,136,153],\n  lightsteelblue: [176,196,222],\n  lightyellow:  [255,255,224],\n  lime: [0,255,0],\n  limegreen:  [50,205,50],\n  linen:  [250,240,230],\n  magenta:  [255,0,255],\n  maroon: [128,0,0],\n  mediumaquamarine: [102,205,170],\n  mediumblue: [0,0,205],\n  mediumorchid: [186,85,211],\n  mediumpurple: [147,112,219],\n  mediumseagreen: [60,179,113],\n  mediumslateblue:  [123,104,238],\n  mediumspringgreen:  [0,250,154],\n  mediumturquoise:  [72,209,204],\n  mediumvioletred:  [199,21,133],\n  midnightblue: [25,25,112],\n  mintcream:  [245,255,250],\n  mistyrose:  [255,228,225],\n  moccasin: [255,228,181],\n  navajowhite:  [255,222,173],\n  navy: [0,0,128],\n  oldlace:  [253,245,230],\n  olive:  [128,128,0],\n  olivedrab:  [107,142,35],\n  orange: [255,165,0],\n  orangered:  [255,69,0],\n  orchid: [218,112,214],\n  palegoldenrod:  [238,232,170],\n  palegreen:  [152,251,152],\n  paleturquoise:  [175,238,238],\n  palevioletred:  [219,112,147],\n  papayawhip: [255,239,213],\n  peachpuff:  [255,218,185],\n  peru: [205,133,63],\n  pink: [255,192,203],\n  plum: [221,160,221],\n  powderblue: [176,224,230],\n  purple: [128,0,128],\n  rebeccapurple: [102, 51, 153],\n  red:  [255,0,0],\n  rosybrown:  [188,143,143],\n  royalblue:  [65,105,225],\n  saddlebrown:  [139,69,19],\n  salmon: [250,128,114],\n  sandybrown: [244,164,96],\n  seagreen: [46,139,87],\n  seashell: [255,245,238],\n  sienna: [160,82,45],\n  silver: [192,192,192],\n  skyblue:  [135,206,235],\n  slateblue:  [106,90,205],\n  slategray:  [112,128,144],\n  slategrey:  [112,128,144],\n  snow: [255,250,250],\n  springgreen:  [0,255,127],\n  steelblue:  [70,130,180],\n  tan:  [210,180,140],\n  teal: [0,128,128],\n  thistle:  [216,191,216],\n  tomato: [255,99,71],\n  turquoise:  [64,224,208],\n  violet: [238,130,238],\n  wheat:  [245,222,179],\n  white:  [255,255,255],\n  whitesmoke: [245,245,245],\n  yellow: [255,255,0],\n  yellowgreen:  [154,205,50]\n};\n\nvar reverseKeywords = {};\nfor (var key in cssKeywords) {\n  reverseKeywords[JSON.stringify(cssKeywords[key])] = key;\n}\n\n},{}],5:[function(require,module,exports){\nvar conversions = require(4);\n\nvar convert = function() {\n   return new Converter();\n}\n\nfor (var func in conversions) {\n  // export Raw versions\n  convert[func + \"Raw\"] =  (function(func) {\n    // accept array or plain args\n    return function(arg) {\n      if (typeof arg == \"number\")\n        arg = Array.prototype.slice.call(arguments);\n      return conversions[func](arg);\n    }\n  })(func);\n\n  var pair = /(\\w+)2(\\w+)/.exec(func),\n      from = pair[1],\n      to = pair[2];\n\n  // export rgb2hsl and [\"rgb\"][\"hsl\"]\n  convert[from] = convert[from] || {};\n\n  convert[from][to] = convert[func] = (function(func) { \n    return function(arg) {\n      if (typeof arg == \"number\")\n        arg = Array.prototype.slice.call(arguments);\n      \n      var val = conversions[func](arg);\n      if (typeof val == \"string\" || val === undefined)\n        return val; // keyword\n\n      for (var i = 0; i < val.length; i++)\n        val[i] = Math.round(val[i]);\n      return val;\n    }\n  })(func);\n}\n\n\n/* Converter does lazy conversion and caching */\nvar Converter = function() {\n   this.convs = {};\n};\n\n/* Either get the values for a space or\n  set the values for a space, depending on args */\nConverter.prototype.routeSpace = function(space, args) {\n   var values = args[0];\n   if (values === undefined) {\n      // color.rgb()\n      return this.getValues(space);\n   }\n   // color.rgb(10, 10, 10)\n   if (typeof values == \"number\") {\n      values = Array.prototype.slice.call(args);        \n   }\n\n   return this.setValues(space, values);\n};\n  \n/* Set the values for a space, invalidating cache */\nConverter.prototype.setValues = function(space, values) {\n   this.space = space;\n   this.convs = {};\n   this.convs[space] = values;\n   return this;\n};\n\n/* Get the values for a space. If there's already\n  a conversion for the space, fetch it, otherwise\n  compute it */\nConverter.prototype.getValues = function(space) {\n   var vals = this.convs[space];\n   if (!vals) {\n      var fspace = this.space,\n          from = this.convs[fspace];\n      vals = convert[fspace][space](from);\n\n      this.convs[space] = vals;\n   }\n  return vals;\n};\n\n[\"rgb\", \"hsl\", \"hsv\", \"cmyk\", \"keyword\"].forEach(function(space) {\n   Converter.prototype[space] = function(vals) {\n      return this.routeSpace(space, arguments);\n   }\n});\n\nmodule.exports = convert;\n},{\"4\":4}],6:[function(require,module,exports){\nmodule.exports = {\r\n\t\"aliceblue\": [240, 248, 255],\r\n\t\"antiquewhite\": [250, 235, 215],\r\n\t\"aqua\": [0, 255, 255],\r\n\t\"aquamarine\": [127, 255, 212],\r\n\t\"azure\": [240, 255, 255],\r\n\t\"beige\": [245, 245, 220],\r\n\t\"bisque\": [255, 228, 196],\r\n\t\"black\": [0, 0, 0],\r\n\t\"blanchedalmond\": [255, 235, 205],\r\n\t\"blue\": [0, 0, 255],\r\n\t\"blueviolet\": [138, 43, 226],\r\n\t\"brown\": [165, 42, 42],\r\n\t\"burlywood\": [222, 184, 135],\r\n\t\"cadetblue\": [95, 158, 160],\r\n\t\"chartreuse\": [127, 255, 0],\r\n\t\"chocolate\": [210, 105, 30],\r\n\t\"coral\": [255, 127, 80],\r\n\t\"cornflowerblue\": [100, 149, 237],\r\n\t\"cornsilk\": [255, 248, 220],\r\n\t\"crimson\": [220, 20, 60],\r\n\t\"cyan\": [0, 255, 255],\r\n\t\"darkblue\": [0, 0, 139],\r\n\t\"darkcyan\": [0, 139, 139],\r\n\t\"darkgoldenrod\": [184, 134, 11],\r\n\t\"darkgray\": [169, 169, 169],\r\n\t\"darkgreen\": [0, 100, 0],\r\n\t\"darkgrey\": [169, 169, 169],\r\n\t\"darkkhaki\": [189, 183, 107],\r\n\t\"darkmagenta\": [139, 0, 139],\r\n\t\"darkolivegreen\": [85, 107, 47],\r\n\t\"darkorange\": [255, 140, 0],\r\n\t\"darkorchid\": [153, 50, 204],\r\n\t\"darkred\": [139, 0, 0],\r\n\t\"darksalmon\": [233, 150, 122],\r\n\t\"darkseagreen\": [143, 188, 143],\r\n\t\"darkslateblue\": [72, 61, 139],\r\n\t\"darkslategray\": [47, 79, 79],\r\n\t\"darkslategrey\": [47, 79, 79],\r\n\t\"darkturquoise\": [0, 206, 209],\r\n\t\"darkviolet\": [148, 0, 211],\r\n\t\"deeppink\": [255, 20, 147],\r\n\t\"deepskyblue\": [0, 191, 255],\r\n\t\"dimgray\": [105, 105, 105],\r\n\t\"dimgrey\": [105, 105, 105],\r\n\t\"dodgerblue\": [30, 144, 255],\r\n\t\"firebrick\": [178, 34, 34],\r\n\t\"floralwhite\": [255, 250, 240],\r\n\t\"forestgreen\": [34, 139, 34],\r\n\t\"fuchsia\": [255, 0, 255],\r\n\t\"gainsboro\": [220, 220, 220],\r\n\t\"ghostwhite\": [248, 248, 255],\r\n\t\"gold\": [255, 215, 0],\r\n\t\"goldenrod\": [218, 165, 32],\r\n\t\"gray\": [128, 128, 128],\r\n\t\"green\": [0, 128, 0],\r\n\t\"greenyellow\": [173, 255, 47],\r\n\t\"grey\": [128, 128, 128],\r\n\t\"honeydew\": [240, 255, 240],\r\n\t\"hotpink\": [255, 105, 180],\r\n\t\"indianred\": [205, 92, 92],\r\n\t\"indigo\": [75, 0, 130],\r\n\t\"ivory\": [255, 255, 240],\r\n\t\"khaki\": [240, 230, 140],\r\n\t\"lavender\": [230, 230, 250],\r\n\t\"lavenderblush\": [255, 240, 245],\r\n\t\"lawngreen\": [124, 252, 0],\r\n\t\"lemonchiffon\": [255, 250, 205],\r\n\t\"lightblue\": [173, 216, 230],\r\n\t\"lightcoral\": [240, 128, 128],\r\n\t\"lightcyan\": [224, 255, 255],\r\n\t\"lightgoldenrodyellow\": [250, 250, 210],\r\n\t\"lightgray\": [211, 211, 211],\r\n\t\"lightgreen\": [144, 238, 144],\r\n\t\"lightgrey\": [211, 211, 211],\r\n\t\"lightpink\": [255, 182, 193],\r\n\t\"lightsalmon\": [255, 160, 122],\r\n\t\"lightseagreen\": [32, 178, 170],\r\n\t\"lightskyblue\": [135, 206, 250],\r\n\t\"lightslategray\": [119, 136, 153],\r\n\t\"lightslategrey\": [119, 136, 153],\r\n\t\"lightsteelblue\": [176, 196, 222],\r\n\t\"lightyellow\": [255, 255, 224],\r\n\t\"lime\": [0, 255, 0],\r\n\t\"limegreen\": [50, 205, 50],\r\n\t\"linen\": [250, 240, 230],\r\n\t\"magenta\": [255, 0, 255],\r\n\t\"maroon\": [128, 0, 0],\r\n\t\"mediumaquamarine\": [102, 205, 170],\r\n\t\"mediumblue\": [0, 0, 205],\r\n\t\"mediumorchid\": [186, 85, 211],\r\n\t\"mediumpurple\": [147, 112, 219],\r\n\t\"mediumseagreen\": [60, 179, 113],\r\n\t\"mediumslateblue\": [123, 104, 238],\r\n\t\"mediumspringgreen\": [0, 250, 154],\r\n\t\"mediumturquoise\": [72, 209, 204],\r\n\t\"mediumvioletred\": [199, 21, 133],\r\n\t\"midnightblue\": [25, 25, 112],\r\n\t\"mintcream\": [245, 255, 250],\r\n\t\"mistyrose\": [255, 228, 225],\r\n\t\"moccasin\": [255, 228, 181],\r\n\t\"navajowhite\": [255, 222, 173],\r\n\t\"navy\": [0, 0, 128],\r\n\t\"oldlace\": [253, 245, 230],\r\n\t\"olive\": [128, 128, 0],\r\n\t\"olivedrab\": [107, 142, 35],\r\n\t\"orange\": [255, 165, 0],\r\n\t\"orangered\": [255, 69, 0],\r\n\t\"orchid\": [218, 112, 214],\r\n\t\"palegoldenrod\": [238, 232, 170],\r\n\t\"palegreen\": [152, 251, 152],\r\n\t\"paleturquoise\": [175, 238, 238],\r\n\t\"palevioletred\": [219, 112, 147],\r\n\t\"papayawhip\": [255, 239, 213],\r\n\t\"peachpuff\": [255, 218, 185],\r\n\t\"peru\": [205, 133, 63],\r\n\t\"pink\": [255, 192, 203],\r\n\t\"plum\": [221, 160, 221],\r\n\t\"powderblue\": [176, 224, 230],\r\n\t\"purple\": [128, 0, 128],\r\n\t\"rebeccapurple\": [102, 51, 153],\r\n\t\"red\": [255, 0, 0],\r\n\t\"rosybrown\": [188, 143, 143],\r\n\t\"royalblue\": [65, 105, 225],\r\n\t\"saddlebrown\": [139, 69, 19],\r\n\t\"salmon\": [250, 128, 114],\r\n\t\"sandybrown\": [244, 164, 96],\r\n\t\"seagreen\": [46, 139, 87],\r\n\t\"seashell\": [255, 245, 238],\r\n\t\"sienna\": [160, 82, 45],\r\n\t\"silver\": [192, 192, 192],\r\n\t\"skyblue\": [135, 206, 235],\r\n\t\"slateblue\": [106, 90, 205],\r\n\t\"slategray\": [112, 128, 144],\r\n\t\"slategrey\": [112, 128, 144],\r\n\t\"snow\": [255, 250, 250],\r\n\t\"springgreen\": [0, 255, 127],\r\n\t\"steelblue\": [70, 130, 180],\r\n\t\"tan\": [210, 180, 140],\r\n\t\"teal\": [0, 128, 128],\r\n\t\"thistle\": [216, 191, 216],\r\n\t\"tomato\": [255, 99, 71],\r\n\t\"turquoise\": [64, 224, 208],\r\n\t\"violet\": [238, 130, 238],\r\n\t\"wheat\": [245, 222, 179],\r\n\t\"white\": [255, 255, 255],\r\n\t\"whitesmoke\": [245, 245, 245],\r\n\t\"yellow\": [255, 255, 0],\r\n\t\"yellowgreen\": [154, 205, 50]\r\n};\n},{}],7:[function(require,module,exports){\n/**\n * @namespace Chart\n */\nvar Chart = require(28)();\n\nrequire(26)(Chart);\nrequire(40)(Chart);\nrequire(22)(Chart);\nrequire(25)(Chart);\nrequire(30)(Chart);\nrequire(21)(Chart);\nrequire(23)(Chart);\nrequire(24)(Chart);\nrequire(29)(Chart);\nrequire(32)(Chart);\nrequire(33)(Chart);\nrequire(31)(Chart);\nrequire(27)(Chart);\nrequire(34)(Chart);\n\nrequire(35)(Chart);\nrequire(36)(Chart);\nrequire(37)(Chart);\nrequire(38)(Chart);\n\nrequire(46)(Chart);\nrequire(44)(Chart);\nrequire(45)(Chart);\nrequire(47)(Chart);\nrequire(48)(Chart);\nrequire(49)(Chart);\n\n// Controllers must be loaded after elements\n// See Chart.core.datasetController.dataElementType\nrequire(15)(Chart);\nrequire(16)(Chart);\nrequire(17)(Chart);\nrequire(18)(Chart);\nrequire(19)(Chart);\nrequire(20)(Chart);\n\nrequire(8)(Chart);\nrequire(9)(Chart);\nrequire(10)(Chart);\nrequire(11)(Chart);\nrequire(12)(Chart);\nrequire(13)(Chart);\nrequire(14)(Chart);\n\n// Loading built-it plugins\nvar plugins = [];\n\nplugins.push(\n    require(41)(Chart),\n    require(42)(Chart),\n    require(43)(Chart)\n);\n\nChart.plugins.register(plugins);\n\nmodule.exports = Chart;\nif (typeof window !== 'undefined') {\n\twindow.Chart = Chart;\n}\n\n},{\"10\":10,\"11\":11,\"12\":12,\"13\":13,\"14\":14,\"15\":15,\"16\":16,\"17\":17,\"18\":18,\"19\":19,\"20\":20,\"21\":21,\"22\":22,\"23\":23,\"24\":24,\"25\":25,\"26\":26,\"27\":27,\"28\":28,\"29\":29,\"30\":30,\"31\":31,\"32\":32,\"33\":33,\"34\":34,\"35\":35,\"36\":36,\"37\":37,\"38\":38,\"40\":40,\"41\":41,\"42\":42,\"43\":43,\"44\":44,\"45\":45,\"46\":46,\"47\":47,\"48\":48,\"49\":49,\"8\":8,\"9\":9}],8:[function(require,module,exports){\n'use strict';\n\nmodule.exports = function(Chart) {\n\n\tChart.Bar = function(context, config) {\n\t\tconfig.type = 'bar';\n\n\t\treturn new Chart(context, config);\n\t};\n\n};\n\n},{}],9:[function(require,module,exports){\n'use strict';\n\nmodule.exports = function(Chart) {\n\n\tChart.Bubble = function(context, config) {\n\t\tconfig.type = 'bubble';\n\t\treturn new Chart(context, config);\n\t};\n\n};\n\n},{}],10:[function(require,module,exports){\n'use strict';\n\nmodule.exports = function(Chart) {\n\n\tChart.Doughnut = function(context, config) {\n\t\tconfig.type = 'doughnut';\n\n\t\treturn new Chart(context, config);\n\t};\n\n};\n\n},{}],11:[function(require,module,exports){\n'use strict';\n\nmodule.exports = function(Chart) {\n\n\tChart.Line = function(context, config) {\n\t\tconfig.type = 'line';\n\n\t\treturn new Chart(context, config);\n\t};\n\n};\n\n},{}],12:[function(require,module,exports){\n'use strict';\n\nmodule.exports = function(Chart) {\n\n\tChart.PolarArea = function(context, config) {\n\t\tconfig.type = 'polarArea';\n\n\t\treturn new Chart(context, config);\n\t};\n\n};\n\n},{}],13:[function(require,module,exports){\n'use strict';\n\nmodule.exports = function(Chart) {\n\n\tChart.Radar = function(context, config) {\n\t\tconfig.type = 'radar';\n\n\t\treturn new Chart(context, config);\n\t};\n\n};\n\n},{}],14:[function(require,module,exports){\n'use strict';\n\nmodule.exports = function(Chart) {\n\n\tvar defaultConfig = {\n\t\thover: {\n\t\t\tmode: 'single'\n\t\t},\n\n\t\tscales: {\n\t\t\txAxes: [{\n\t\t\t\ttype: 'linear', // scatter should not use a category axis\n\t\t\t\tposition: 'bottom',\n\t\t\t\tid: 'x-axis-1' // need an ID so datasets can reference the scale\n\t\t\t}],\n\t\t\tyAxes: [{\n\t\t\t\ttype: 'linear',\n\t\t\t\tposition: 'left',\n\t\t\t\tid: 'y-axis-1'\n\t\t\t}]\n\t\t},\n\n\t\ttooltips: {\n\t\t\tcallbacks: {\n\t\t\t\ttitle: function() {\n\t\t\t\t\t// Title doesn't make sense for scatter since we format the data as a point\n\t\t\t\t\treturn '';\n\t\t\t\t},\n\t\t\t\tlabel: function(tooltipItem) {\n\t\t\t\t\treturn '(' + tooltipItem.xLabel + ', ' + tooltipItem.yLabel + ')';\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t};\n\n\t// Register the default config for this type\n\tChart.defaults.scatter = defaultConfig;\n\n\t// Scatter charts use line controllers\n\tChart.controllers.scatter = Chart.controllers.line;\n\n\tChart.Scatter = function(context, config) {\n\t\tconfig.type = 'scatter';\n\t\treturn new Chart(context, config);\n\t};\n\n};\n\n},{}],15:[function(require,module,exports){\n'use strict';\n\nmodule.exports = function(Chart) {\n\n\tvar helpers = Chart.helpers;\n\n\tChart.defaults.bar = {\n\t\thover: {\n\t\t\tmode: 'label'\n\t\t},\n\n\t\tscales: {\n\t\t\txAxes: [{\n\t\t\t\ttype: 'category',\n\n\t\t\t\t// Specific to Bar Controller\n\t\t\t\tcategoryPercentage: 0.8,\n\t\t\t\tbarPercentage: 0.9,\n\n\t\t\t\t// grid line settings\n\t\t\t\tgridLines: {\n\t\t\t\t\toffsetGridLines: true\n\t\t\t\t}\n\t\t\t}],\n\t\t\tyAxes: [{\n\t\t\t\ttype: 'linear'\n\t\t\t}]\n\t\t}\n\t};\n\n\tChart.controllers.bar = Chart.DatasetController.extend({\n\n\t\tdataElementType: Chart.elements.Rectangle,\n\n\t\tinitialize: function() {\n\t\t\tvar me = this;\n\t\t\tvar meta;\n\n\t\t\tChart.DatasetController.prototype.initialize.apply(me, arguments);\n\n\t\t\tmeta = me.getMeta();\n\t\t\tmeta.stack = me.getDataset().stack;\n\t\t\tmeta.bar = true;\n\t\t},\n\n\t\tupdate: function(reset) {\n\t\t\tvar me = this;\n\t\t\tvar elements = me.getMeta().data;\n\t\t\tvar i, ilen;\n\n\t\t\tme._ruler = me.getRuler();\n\n\t\t\tfor (i = 0, ilen = elements.length; i < ilen; ++i) {\n\t\t\t\tme.updateElement(elements[i], i, reset);\n\t\t\t}\n\t\t},\n\n\t\tupdateElement: function(rectangle, index, reset) {\n\t\t\tvar me = this;\n\t\t\tvar chart = me.chart;\n\t\t\tvar meta = me.getMeta();\n\t\t\tvar dataset = me.getDataset();\n\t\t\tvar custom = rectangle.custom || {};\n\t\t\tvar rectangleOptions = chart.options.elements.rectangle;\n\n\t\t\trectangle._xScale = me.getScaleForId(meta.xAxisID);\n\t\t\trectangle._yScale = me.getScaleForId(meta.yAxisID);\n\t\t\trectangle._datasetIndex = me.index;\n\t\t\trectangle._index = index;\n\n\t\t\trectangle._model = {\n\t\t\t\tdatasetLabel: dataset.label,\n\t\t\t\tlabel: chart.data.labels[index],\n\t\t\t\tborderSkipped: custom.borderSkipped ? custom.borderSkipped : rectangleOptions.borderSkipped,\n\t\t\t\tbackgroundColor: custom.backgroundColor ? custom.backgroundColor : helpers.getValueAtIndexOrDefault(dataset.backgroundColor, index, rectangleOptions.backgroundColor),\n\t\t\t\tborderColor: custom.borderColor ? custom.borderColor : helpers.getValueAtIndexOrDefault(dataset.borderColor, index, rectangleOptions.borderColor),\n\t\t\t\tborderWidth: custom.borderWidth ? custom.borderWidth : helpers.getValueAtIndexOrDefault(dataset.borderWidth, index, rectangleOptions.borderWidth)\n\t\t\t};\n\n\t\t\tme.updateElementGeometry(rectangle, index, reset);\n\n\t\t\trectangle.pivot();\n\t\t},\n\n\t\t/**\n\t\t * @private\n\t\t */\n\t\tupdateElementGeometry: function(rectangle, index, reset) {\n\t\t\tvar me = this;\n\t\t\tvar model = rectangle._model;\n\t\t\tvar vscale = me.getValueScale();\n\t\t\tvar base = vscale.getBasePixel();\n\t\t\tvar horizontal = vscale.isHorizontal();\n\t\t\tvar ruler = me._ruler || me.getRuler();\n\t\t\tvar vpixels = me.calculateBarValuePixels(me.index, index);\n\t\t\tvar ipixels = me.calculateBarIndexPixels(me.index, index, ruler);\n\n\t\t\tmodel.horizontal = horizontal;\n\t\t\tmodel.base = reset? base : vpixels.base;\n\t\t\tmodel.x = horizontal? reset? base : vpixels.head : ipixels.center;\n\t\t\tmodel.y = horizontal? ipixels.center : reset? base : vpixels.head;\n\t\t\tmodel.height = horizontal? ipixels.size : undefined;\n\t\t\tmodel.width = horizontal? undefined : ipixels.size;\n\t\t},\n\n\t\t/**\n\t\t * @private\n\t\t */\n\t\tgetValueScaleId: function() {\n\t\t\treturn this.getMeta().yAxisID;\n\t\t},\n\n\t\t/**\n\t\t * @private\n\t\t */\n\t\tgetIndexScaleId: function() {\n\t\t\treturn this.getMeta().xAxisID;\n\t\t},\n\n\t\t/**\n\t\t * @private\n\t\t */\n\t\tgetValueScale: function() {\n\t\t\treturn this.getScaleForId(this.getValueScaleId());\n\t\t},\n\n\t\t/**\n\t\t * @private\n\t\t */\n\t\tgetIndexScale: function() {\n\t\t\treturn this.getScaleForId(this.getIndexScaleId());\n\t\t},\n\n\t\t/**\n\t\t * Returns the effective number of stacks based on groups and bar visibility.\n\t\t * @private\n\t\t */\n\t\tgetStackCount: function(last) {\n\t\t\tvar me = this;\n\t\t\tvar chart = me.chart;\n\t\t\tvar scale = me.getIndexScale();\n\t\t\tvar stacked = scale.options.stacked;\n\t\t\tvar ilen = last === undefined? chart.data.datasets.length : last + 1;\n\t\t\tvar stacks = [];\n\t\t\tvar i, meta;\n\n\t\t\tfor (i = 0; i < ilen; ++i) {\n\t\t\t\tmeta = chart.getDatasetMeta(i);\n\t\t\t\tif (meta.bar && chart.isDatasetVisible(i) &&\n\t\t\t\t\t(stacked === false ||\n\t\t\t\t\t(stacked === true && stacks.indexOf(meta.stack) === -1) ||\n\t\t\t\t\t(stacked === undefined && (meta.stack === undefined || stacks.indexOf(meta.stack) === -1)))) {\n\t\t\t\t\tstacks.push(meta.stack);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn stacks.length;\n\t\t},\n\n\t\t/**\n\t\t * Returns the stack index for the given dataset based on groups and bar visibility.\n\t\t * @private\n\t\t */\n\t\tgetStackIndex: function(datasetIndex) {\n\t\t\treturn this.getStackCount(datasetIndex) - 1;\n\t\t},\n\n\t\t/**\n\t\t * @private\n\t\t */\n\t\tgetRuler: function() {\n\t\t\tvar me = this;\n\t\t\tvar scale = me.getIndexScale();\n\t\t\tvar options = scale.options;\n\t\t\tvar stackCount = me.getStackCount();\n\t\t\tvar fullSize = scale.isHorizontal()? scale.width : scale.height;\n\t\t\tvar tickSize = fullSize / scale.ticks.length;\n\t\t\tvar categorySize = tickSize * options.categoryPercentage;\n\t\t\tvar fullBarSize = categorySize / stackCount;\n\t\t\tvar barSize = fullBarSize * options.barPercentage;\n\n\t\t\tbarSize = Math.min(\n\t\t\t\thelpers.getValueOrDefault(options.barThickness, barSize),\n\t\t\t\thelpers.getValueOrDefault(options.maxBarThickness, Infinity));\n\n\t\t\treturn {\n\t\t\t\tstackCount: stackCount,\n\t\t\t\ttickSize: tickSize,\n\t\t\t\tcategorySize: categorySize,\n\t\t\t\tcategorySpacing: tickSize - categorySize,\n\t\t\t\tfullBarSize: fullBarSize,\n\t\t\t\tbarSize: barSize,\n\t\t\t\tbarSpacing: fullBarSize - barSize,\n\t\t\t\tscale: scale\n\t\t\t};\n\t\t},\n\n\t\t/**\n\t\t * Note: pixel values are not clamped to the scale area.\n\t\t * @private\n\t\t */\n\t\tcalculateBarValuePixels: function(datasetIndex, index) {\n\t\t\tvar me = this;\n\t\t\tvar chart = me.chart;\n\t\t\tvar meta = me.getMeta();\n\t\t\tvar scale = me.getValueScale();\n\t\t\tvar datasets = chart.data.datasets;\n\t\t\tvar value = Number(datasets[datasetIndex].data[index]);\n\t\t\tvar stacked = scale.options.stacked;\n\t\t\tvar stack = meta.stack;\n\t\t\tvar start = 0;\n\t\t\tvar i, imeta, ivalue, base, head, size;\n\n\t\t\tif (stacked || (stacked === undefined && stack !== undefined)) {\n\t\t\t\tfor (i = 0; i < datasetIndex; ++i) {\n\t\t\t\t\timeta = chart.getDatasetMeta(i);\n\n\t\t\t\t\tif (imeta.bar &&\n\t\t\t\t\t\timeta.stack === stack &&\n\t\t\t\t\t\timeta.controller.getValueScaleId() === scale.id &&\n\t\t\t\t\t\tchart.isDatasetVisible(i)) {\n\n\t\t\t\t\t\tivalue = Number(datasets[i].data[index]);\n\t\t\t\t\t\tif ((value < 0 && ivalue < 0) || (value >= 0 && ivalue > 0)) {\n\t\t\t\t\t\t\tstart += ivalue;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tbase = scale.getPixelForValue(start);\n\t\t\thead = scale.getPixelForValue(start + value);\n\t\t\tsize = (head - base) / 2;\n\n\t\t\treturn {\n\t\t\t\tsize: size,\n\t\t\t\tbase: base,\n\t\t\t\thead: head,\n\t\t\t\tcenter: head + size / 2\n\t\t\t};\n\t\t},\n\n\t\t/**\n\t\t * @private\n\t\t */\n\t\tcalculateBarIndexPixels: function(datasetIndex, index, ruler) {\n\t\t\tvar me = this;\n\t\t\tvar scale = ruler.scale;\n\t\t\tvar isCombo = me.chart.isCombo;\n\t\t\tvar stackIndex = me.getStackIndex(datasetIndex);\n\t\t\tvar base = scale.getPixelForValue(null, index, datasetIndex, isCombo);\n\t\t\tvar size = ruler.barSize;\n\n\t\t\tbase -= isCombo? ruler.tickSize / 2 : 0;\n\t\t\tbase += ruler.fullBarSize * stackIndex;\n\t\t\tbase += ruler.categorySpacing / 2;\n\t\t\tbase += ruler.barSpacing / 2;\n\n\t\t\treturn {\n\t\t\t\tsize: size,\n\t\t\t\tbase: base,\n\t\t\t\thead: base + size,\n\t\t\t\tcenter: base + size / 2\n\t\t\t};\n\t\t},\n\n\t\tdraw: function() {\n\t\t\tvar me = this;\n\t\t\tvar chart = me.chart;\n\t\t\tvar elements = me.getMeta().data;\n\t\t\tvar dataset = me.getDataset();\n\t\t\tvar ilen = elements.length;\n\t\t\tvar i = 0;\n\t\t\tvar d;\n\n\t\t\thelpers.canvas.clipArea(chart.ctx, chart.chartArea);\n\n\t\t\tfor (; i<ilen; ++i) {\n\t\t\t\td = dataset.data[i];\n\t\t\t\tif (d !== null && d !== undefined && !isNaN(d)) {\n\t\t\t\t\telements[i].draw();\n\t\t\t\t}\n\t\t\t}\n\n\t\t\thelpers.canvas.unclipArea(chart.ctx);\n\t\t},\n\n\t\tsetHoverStyle: function(rectangle) {\n\t\t\tvar dataset = this.chart.data.datasets[rectangle._datasetIndex];\n\t\t\tvar index = rectangle._index;\n\t\t\tvar custom = rectangle.custom || {};\n\t\t\tvar model = rectangle._model;\n\n\t\t\tmodel.backgroundColor = custom.hoverBackgroundColor ? custom.hoverBackgroundColor : helpers.getValueAtIndexOrDefault(dataset.hoverBackgroundColor, index, helpers.getHoverColor(model.backgroundColor));\n\t\t\tmodel.borderColor = custom.hoverBorderColor ? custom.hoverBorderColor : helpers.getValueAtIndexOrDefault(dataset.hoverBorderColor, index, helpers.getHoverColor(model.borderColor));\n\t\t\tmodel.borderWidth = custom.hoverBorderWidth ? custom.hoverBorderWidth : helpers.getValueAtIndexOrDefault(dataset.hoverBorderWidth, index, model.borderWidth);\n\t\t},\n\n\t\tremoveHoverStyle: function(rectangle) {\n\t\t\tvar dataset = this.chart.data.datasets[rectangle._datasetIndex];\n\t\t\tvar index = rectangle._index;\n\t\t\tvar custom = rectangle.custom || {};\n\t\t\tvar model = rectangle._model;\n\t\t\tvar rectangleElementOptions = this.chart.options.elements.rectangle;\n\n\t\t\tmodel.backgroundColor = custom.backgroundColor ? custom.backgroundColor : helpers.getValueAtIndexOrDefault(dataset.backgroundColor, index, rectangleElementOptions.backgroundColor);\n\t\t\tmodel.borderColor = custom.borderColor ? custom.borderColor : helpers.getValueAtIndexOrDefault(dataset.borderColor, index, rectangleElementOptions.borderColor);\n\t\t\tmodel.borderWidth = custom.borderWidth ? custom.borderWidth : helpers.getValueAtIndexOrDefault(dataset.borderWidth, index, rectangleElementOptions.borderWidth);\n\t\t}\n\t});\n\n\n\t// including horizontalBar in the bar file, instead of a file of its own\n\t// it extends bar (like pie extends doughnut)\n\tChart.defaults.horizontalBar = {\n\t\thover: {\n\t\t\tmode: 'label'\n\t\t},\n\n\t\tscales: {\n\t\t\txAxes: [{\n\t\t\t\ttype: 'linear',\n\t\t\t\tposition: 'bottom'\n\t\t\t}],\n\t\t\tyAxes: [{\n\t\t\t\tposition: 'left',\n\t\t\t\ttype: 'category',\n\n\t\t\t\t// Specific to Horizontal Bar Controller\n\t\t\t\tcategoryPercentage: 0.8,\n\t\t\t\tbarPercentage: 0.9,\n\n\t\t\t\t// grid line settings\n\t\t\t\tgridLines: {\n\t\t\t\t\toffsetGridLines: true\n\t\t\t\t}\n\t\t\t}]\n\t\t},\n\t\telements: {\n\t\t\trectangle: {\n\t\t\t\tborderSkipped: 'left'\n\t\t\t}\n\t\t},\n\t\ttooltips: {\n\t\t\tcallbacks: {\n\t\t\t\ttitle: function(tooltipItems, data) {\n\t\t\t\t\t// Pick first xLabel for now\n\t\t\t\t\tvar title = '';\n\n\t\t\t\t\tif (tooltipItems.length > 0) {\n\t\t\t\t\t\tif (tooltipItems[0].yLabel) {\n\t\t\t\t\t\t\ttitle = tooltipItems[0].yLabel;\n\t\t\t\t\t\t} else if (data.labels.length > 0 && tooltipItems[0].index < data.labels.length) {\n\t\t\t\t\t\t\ttitle = data.labels[tooltipItems[0].index];\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\treturn title;\n\t\t\t\t},\n\t\t\t\tlabel: function(tooltipItem, data) {\n\t\t\t\t\tvar datasetLabel = data.datasets[tooltipItem.datasetIndex].label || '';\n\t\t\t\t\treturn datasetLabel + ': ' + tooltipItem.xLabel;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t};\n\n\tChart.controllers.horizontalBar = Chart.controllers.bar.extend({\n\t\t/**\n\t\t * @private\n\t\t */\n\t\tgetValueScaleId: function() {\n\t\t\treturn this.getMeta().xAxisID;\n\t\t},\n\n\t\t/**\n\t\t * @private\n\t\t */\n\t\tgetIndexScaleId: function() {\n\t\t\treturn this.getMeta().yAxisID;\n\t\t}\n\t});\n};\n\n},{}],16:[function(require,module,exports){\n'use strict';\n\nmodule.exports = function(Chart) {\n\n\tvar helpers = Chart.helpers;\n\n\tChart.defaults.bubble = {\n\t\thover: {\n\t\t\tmode: 'single'\n\t\t},\n\n\t\tscales: {\n\t\t\txAxes: [{\n\t\t\t\ttype: 'linear', // bubble should probably use a linear scale by default\n\t\t\t\tposition: 'bottom',\n\t\t\t\tid: 'x-axis-0' // need an ID so datasets can reference the scale\n\t\t\t}],\n\t\t\tyAxes: [{\n\t\t\t\ttype: 'linear',\n\t\t\t\tposition: 'left',\n\t\t\t\tid: 'y-axis-0'\n\t\t\t}]\n\t\t},\n\n\t\ttooltips: {\n\t\t\tcallbacks: {\n\t\t\t\ttitle: function() {\n\t\t\t\t\t// Title doesn't make sense for scatter since we format the data as a point\n\t\t\t\t\treturn '';\n\t\t\t\t},\n\t\t\t\tlabel: function(tooltipItem, data) {\n\t\t\t\t\tvar datasetLabel = data.datasets[tooltipItem.datasetIndex].label || '';\n\t\t\t\t\tvar dataPoint = data.datasets[tooltipItem.datasetIndex].data[tooltipItem.index];\n\t\t\t\t\treturn datasetLabel + ': (' + tooltipItem.xLabel + ', ' + tooltipItem.yLabel + ', ' + dataPoint.r + ')';\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t};\n\n\tChart.controllers.bubble = Chart.DatasetController.extend({\n\n\t\tdataElementType: Chart.elements.Point,\n\n\t\tupdate: function(reset) {\n\t\t\tvar me = this;\n\t\t\tvar meta = me.getMeta();\n\t\t\tvar points = meta.data;\n\n\t\t\t// Update Points\n\t\t\thelpers.each(points, function(point, index) {\n\t\t\t\tme.updateElement(point, index, reset);\n\t\t\t});\n\t\t},\n\n\t\tupdateElement: function(point, index, reset) {\n\t\t\tvar me = this;\n\t\t\tvar meta = me.getMeta();\n\t\t\tvar xScale = me.getScaleForId(meta.xAxisID);\n\t\t\tvar yScale = me.getScaleForId(meta.yAxisID);\n\n\t\t\tvar custom = point.custom || {};\n\t\t\tvar dataset = me.getDataset();\n\t\t\tvar data = dataset.data[index];\n\t\t\tvar pointElementOptions = me.chart.options.elements.point;\n\t\t\tvar dsIndex = me.index;\n\n\t\t\thelpers.extend(point, {\n\t\t\t\t// Utility\n\t\t\t\t_xScale: xScale,\n\t\t\t\t_yScale: yScale,\n\t\t\t\t_datasetIndex: dsIndex,\n\t\t\t\t_index: index,\n\n\t\t\t\t// Desired view properties\n\t\t\t\t_model: {\n\t\t\t\t\tx: reset ? xScale.getPixelForDecimal(0.5) : xScale.getPixelForValue(typeof data === 'object' ? data : NaN, index, dsIndex, me.chart.isCombo),\n\t\t\t\t\ty: reset ? yScale.getBasePixel() : yScale.getPixelForValue(data, index, dsIndex),\n\t\t\t\t\t// Appearance\n\t\t\t\t\tradius: reset ? 0 : custom.radius ? custom.radius : me.getRadius(data),\n\n\t\t\t\t\t// Tooltip\n\t\t\t\t\thitRadius: custom.hitRadius ? custom.hitRadius : helpers.getValueAtIndexOrDefault(dataset.hitRadius, index, pointElementOptions.hitRadius)\n\t\t\t\t}\n\t\t\t});\n\n\t\t\t// Trick to reset the styles of the point\n\t\t\tChart.DatasetController.prototype.removeHoverStyle.call(me, point, pointElementOptions);\n\n\t\t\tvar model = point._model;\n\t\t\tmodel.skip = custom.skip ? custom.skip : (isNaN(model.x) || isNaN(model.y));\n\n\t\t\tpoint.pivot();\n\t\t},\n\n\t\tgetRadius: function(value) {\n\t\t\treturn value.r || this.chart.options.elements.point.radius;\n\t\t},\n\n\t\tsetHoverStyle: function(point) {\n\t\t\tvar me = this;\n\t\t\tChart.DatasetController.prototype.setHoverStyle.call(me, point);\n\n\t\t\t// Radius\n\t\t\tvar dataset = me.chart.data.datasets[point._datasetIndex];\n\t\t\tvar index = point._index;\n\t\t\tvar custom = point.custom || {};\n\t\t\tvar model = point._model;\n\t\t\tmodel.radius = custom.hoverRadius ? custom.hoverRadius : (helpers.getValueAtIndexOrDefault(dataset.hoverRadius, index, me.chart.options.elements.point.hoverRadius)) + me.getRadius(dataset.data[index]);\n\t\t},\n\n\t\tremoveHoverStyle: function(point) {\n\t\t\tvar me = this;\n\t\t\tChart.DatasetController.prototype.removeHoverStyle.call(me, point, me.chart.options.elements.point);\n\n\t\t\tvar dataVal = me.chart.data.datasets[point._datasetIndex].data[point._index];\n\t\t\tvar custom = point.custom || {};\n\t\t\tvar model = point._model;\n\n\t\t\tmodel.radius = custom.radius ? custom.radius : me.getRadius(dataVal);\n\t\t}\n\t});\n};\n\n},{}],17:[function(require,module,exports){\n'use strict';\n\nmodule.exports = function(Chart) {\n\n\tvar helpers = Chart.helpers,\n\t\tdefaults = Chart.defaults;\n\n\tdefaults.doughnut = {\n\t\tanimation: {\n\t\t\t// Boolean - Whether we animate the rotation of the Doughnut\n\t\t\tanimateRotate: true,\n\t\t\t// Boolean - Whether we animate scaling the Doughnut from the centre\n\t\t\tanimateScale: false\n\t\t},\n\t\taspectRatio: 1,\n\t\thover: {\n\t\t\tmode: 'single'\n\t\t},\n\t\tlegendCallback: function(chart) {\n\t\t\tvar text = [];\n\t\t\ttext.push('<ul class=\"' + chart.id + '-legend\">');\n\n\t\t\tvar data = chart.data;\n\t\t\tvar datasets = data.datasets;\n\t\t\tvar labels = data.labels;\n\n\t\t\tif (datasets.length) {\n\t\t\t\tfor (var i = 0; i < datasets[0].data.length; ++i) {\n\t\t\t\t\ttext.push('<li><span style=\"background-color:' + datasets[0].backgroundColor[i] + '\"></span>');\n\t\t\t\t\tif (labels[i]) {\n\t\t\t\t\t\ttext.push(labels[i]);\n\t\t\t\t\t}\n\t\t\t\t\ttext.push('</li>');\n\t\t\t\t}\n\t\t\t}\n\n\t\t\ttext.push('</ul>');\n\t\t\treturn text.join('');\n\t\t},\n\t\tlegend: {\n\t\t\tlabels: {\n\t\t\t\tgenerateLabels: function(chart) {\n\t\t\t\t\tvar data = chart.data;\n\t\t\t\t\tif (data.labels.length && data.datasets.length) {\n\t\t\t\t\t\treturn data.labels.map(function(label, i) {\n\t\t\t\t\t\t\tvar meta = chart.getDatasetMeta(0);\n\t\t\t\t\t\t\tvar ds = data.datasets[0];\n\t\t\t\t\t\t\tvar arc = meta.data[i];\n\t\t\t\t\t\t\tvar custom = arc && arc.custom || {};\n\t\t\t\t\t\t\tvar getValueAtIndexOrDefault = helpers.getValueAtIndexOrDefault;\n\t\t\t\t\t\t\tvar arcOpts = chart.options.elements.arc;\n\t\t\t\t\t\t\tvar fill = custom.backgroundColor ? custom.backgroundColor : getValueAtIndexOrDefault(ds.backgroundColor, i, arcOpts.backgroundColor);\n\t\t\t\t\t\t\tvar stroke = custom.borderColor ? custom.borderColor : getValueAtIndexOrDefault(ds.borderColor, i, arcOpts.borderColor);\n\t\t\t\t\t\t\tvar bw = custom.borderWidth ? custom.borderWidth : getValueAtIndexOrDefault(ds.borderWidth, i, arcOpts.borderWidth);\n\n\t\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\t\ttext: label,\n\t\t\t\t\t\t\t\tfillStyle: fill,\n\t\t\t\t\t\t\t\tstrokeStyle: stroke,\n\t\t\t\t\t\t\t\tlineWidth: bw,\n\t\t\t\t\t\t\t\thidden: isNaN(ds.data[i]) || meta.data[i].hidden,\n\n\t\t\t\t\t\t\t\t// Extra data used for toggling the correct item\n\t\t\t\t\t\t\t\tindex: i\n\t\t\t\t\t\t\t};\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t\treturn [];\n\t\t\t\t}\n\t\t\t},\n\n\t\t\tonClick: function(e, legendItem) {\n\t\t\t\tvar index = legendItem.index;\n\t\t\t\tvar chart = this.chart;\n\t\t\t\tvar i, ilen, meta;\n\n\t\t\t\tfor (i = 0, ilen = (chart.data.datasets || []).length; i < ilen; ++i) {\n\t\t\t\t\tmeta = chart.getDatasetMeta(i);\n\t\t\t\t\t// toggle visibility of index if exists\n\t\t\t\t\tif (meta.data[index]) {\n\t\t\t\t\t\tmeta.data[index].hidden = !meta.data[index].hidden;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tchart.update();\n\t\t\t}\n\t\t},\n\n\t\t// The percentage of the chart that we cut out of the middle.\n\t\tcutoutPercentage: 50,\n\n\t\t// The rotation of the chart, where the first data arc begins.\n\t\trotation: Math.PI * -0.5,\n\n\t\t// The total circumference of the chart.\n\t\tcircumference: Math.PI * 2.0,\n\n\t\t// Need to override these to give a nice default\n\t\ttooltips: {\n\t\t\tcallbacks: {\n\t\t\t\ttitle: function() {\n\t\t\t\t\treturn '';\n\t\t\t\t},\n\t\t\t\tlabel: function(tooltipItem, data) {\n\t\t\t\t\tvar dataLabel = data.labels[tooltipItem.index];\n\t\t\t\t\tvar value = ': ' + data.datasets[tooltipItem.datasetIndex].data[tooltipItem.index];\n\n\t\t\t\t\tif (helpers.isArray(dataLabel)) {\n\t\t\t\t\t\t// show value on first line of multiline label\n\t\t\t\t\t\t// need to clone because we are changing the value\n\t\t\t\t\t\tdataLabel = dataLabel.slice();\n\t\t\t\t\t\tdataLabel[0] += value;\n\t\t\t\t\t} else {\n\t\t\t\t\t\tdataLabel += value;\n\t\t\t\t\t}\n\n\t\t\t\t\treturn dataLabel;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t};\n\n\tdefaults.pie = helpers.clone(defaults.doughnut);\n\thelpers.extend(defaults.pie, {\n\t\tcutoutPercentage: 0\n\t});\n\n\n\tChart.controllers.doughnut = Chart.controllers.pie = Chart.DatasetController.extend({\n\n\t\tdataElementType: Chart.elements.Arc,\n\n\t\tlinkScales: helpers.noop,\n\n\t\t// Get index of the dataset in relation to the visible datasets. This allows determining the inner and outer radius correctly\n\t\tgetRingIndex: function(datasetIndex) {\n\t\t\tvar ringIndex = 0;\n\n\t\t\tfor (var j = 0; j < datasetIndex; ++j) {\n\t\t\t\tif (this.chart.isDatasetVisible(j)) {\n\t\t\t\t\t++ringIndex;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn ringIndex;\n\t\t},\n\n\t\tupdate: function(reset) {\n\t\t\tvar me = this;\n\t\t\tvar chart = me.chart,\n\t\t\t\tchartArea = chart.chartArea,\n\t\t\t\topts = chart.options,\n\t\t\t\tarcOpts = opts.elements.arc,\n\t\t\t\tavailableWidth = chartArea.right - chartArea.left - arcOpts.borderWidth,\n\t\t\t\tavailableHeight = chartArea.bottom - chartArea.top - arcOpts.borderWidth,\n\t\t\t\tminSize = Math.min(availableWidth, availableHeight),\n\t\t\t\toffset = {\n\t\t\t\t\tx: 0,\n\t\t\t\t\ty: 0\n\t\t\t\t},\n\t\t\t\tmeta = me.getMeta(),\n\t\t\t\tcutoutPercentage = opts.cutoutPercentage,\n\t\t\t\tcircumference = opts.circumference;\n\n\t\t\t// If the chart's circumference isn't a full circle, calculate minSize as a ratio of the width/height of the arc\n\t\t\tif (circumference < Math.PI * 2.0) {\n\t\t\t\tvar startAngle = opts.rotation % (Math.PI * 2.0);\n\t\t\t\tstartAngle += Math.PI * 2.0 * (startAngle >= Math.PI ? -1 : startAngle < -Math.PI ? 1 : 0);\n\t\t\t\tvar endAngle = startAngle + circumference;\n\t\t\t\tvar start = {x: Math.cos(startAngle), y: Math.sin(startAngle)};\n\t\t\t\tvar end = {x: Math.cos(endAngle), y: Math.sin(endAngle)};\n\t\t\t\tvar contains0 = (startAngle <= 0 && 0 <= endAngle) || (startAngle <= Math.PI * 2.0 && Math.PI * 2.0 <= endAngle);\n\t\t\t\tvar contains90 = (startAngle <= Math.PI * 0.5 && Math.PI * 0.5 <= endAngle) || (startAngle <= Math.PI * 2.5 && Math.PI * 2.5 <= endAngle);\n\t\t\t\tvar contains180 = (startAngle <= -Math.PI && -Math.PI <= endAngle) || (startAngle <= Math.PI && Math.PI <= endAngle);\n\t\t\t\tvar contains270 = (startAngle <= -Math.PI * 0.5 && -Math.PI * 0.5 <= endAngle) || (startAngle <= Math.PI * 1.5 && Math.PI * 1.5 <= endAngle);\n\t\t\t\tvar cutout = cutoutPercentage / 100.0;\n\t\t\t\tvar min = {x: contains180 ? -1 : Math.min(start.x * (start.x < 0 ? 1 : cutout), end.x * (end.x < 0 ? 1 : cutout)), y: contains270 ? -1 : Math.min(start.y * (start.y < 0 ? 1 : cutout), end.y * (end.y < 0 ? 1 : cutout))};\n\t\t\t\tvar max = {x: contains0 ? 1 : Math.max(start.x * (start.x > 0 ? 1 : cutout), end.x * (end.x > 0 ? 1 : cutout)), y: contains90 ? 1 : Math.max(start.y * (start.y > 0 ? 1 : cutout), end.y * (end.y > 0 ? 1 : cutout))};\n\t\t\t\tvar size = {width: (max.x - min.x) * 0.5, height: (max.y - min.y) * 0.5};\n\t\t\t\tminSize = Math.min(availableWidth / size.width, availableHeight / size.height);\n\t\t\t\toffset = {x: (max.x + min.x) * -0.5, y: (max.y + min.y) * -0.5};\n\t\t\t}\n\n\t\t\tchart.borderWidth = me.getMaxBorderWidth(meta.data);\n\t\t\tchart.outerRadius = Math.max((minSize - chart.borderWidth) / 2, 0);\n\t\t\tchart.innerRadius = Math.max(cutoutPercentage ? (chart.outerRadius / 100) * (cutoutPercentage) : 0, 0);\n\t\t\tchart.radiusLength = (chart.outerRadius - chart.innerRadius) / chart.getVisibleDatasetCount();\n\t\t\tchart.offsetX = offset.x * chart.outerRadius;\n\t\t\tchart.offsetY = offset.y * chart.outerRadius;\n\n\t\t\tmeta.total = me.calculateTotal();\n\n\t\t\tme.outerRadius = chart.outerRadius - (chart.radiusLength * me.getRingIndex(me.index));\n\t\t\tme.innerRadius = Math.max(me.outerRadius - chart.radiusLength, 0);\n\n\t\t\thelpers.each(meta.data, function(arc, index) {\n\t\t\t\tme.updateElement(arc, index, reset);\n\t\t\t});\n\t\t},\n\n\t\tupdateElement: function(arc, index, reset) {\n\t\t\tvar me = this;\n\t\t\tvar chart = me.chart,\n\t\t\t\tchartArea = chart.chartArea,\n\t\t\t\topts = chart.options,\n\t\t\t\tanimationOpts = opts.animation,\n\t\t\t\tcenterX = (chartArea.left + chartArea.right) / 2,\n\t\t\t\tcenterY = (chartArea.top + chartArea.bottom) / 2,\n\t\t\t\tstartAngle = opts.rotation, // non reset case handled later\n\t\t\t\tendAngle = opts.rotation, // non reset case handled later\n\t\t\t\tdataset = me.getDataset(),\n\t\t\t\tcircumference = reset && animationOpts.animateRotate ? 0 : arc.hidden ? 0 : me.calculateCircumference(dataset.data[index]) * (opts.circumference / (2.0 * Math.PI)),\n\t\t\t\tinnerRadius = reset && animationOpts.animateScale ? 0 : me.innerRadius,\n\t\t\t\touterRadius = reset && animationOpts.animateScale ? 0 : me.outerRadius,\n\t\t\t\tvalueAtIndexOrDefault = helpers.getValueAtIndexOrDefault;\n\n\t\t\thelpers.extend(arc, {\n\t\t\t\t// Utility\n\t\t\t\t_datasetIndex: me.index,\n\t\t\t\t_index: index,\n\n\t\t\t\t// Desired view properties\n\t\t\t\t_model: {\n\t\t\t\t\tx: centerX + chart.offsetX,\n\t\t\t\t\ty: centerY + chart.offsetY,\n\t\t\t\t\tstartAngle: startAngle,\n\t\t\t\t\tendAngle: endAngle,\n\t\t\t\t\tcircumference: circumference,\n\t\t\t\t\touterRadius: outerRadius,\n\t\t\t\t\tinnerRadius: innerRadius,\n\t\t\t\t\tlabel: valueAtIndexOrDefault(dataset.label, index, chart.data.labels[index])\n\t\t\t\t}\n\t\t\t});\n\n\t\t\tvar model = arc._model;\n\t\t\t// Resets the visual styles\n\t\t\tthis.removeHoverStyle(arc);\n\n\t\t\t// Set correct angles if not resetting\n\t\t\tif (!reset || !animationOpts.animateRotate) {\n\t\t\t\tif (index === 0) {\n\t\t\t\t\tmodel.startAngle = opts.rotation;\n\t\t\t\t} else {\n\t\t\t\t\tmodel.startAngle = me.getMeta().data[index - 1]._model.endAngle;\n\t\t\t\t}\n\n\t\t\t\tmodel.endAngle = model.startAngle + model.circumference;\n\t\t\t}\n\n\t\t\tarc.pivot();\n\t\t},\n\n\t\tremoveHoverStyle: function(arc) {\n\t\t\tChart.DatasetController.prototype.removeHoverStyle.call(this, arc, this.chart.options.elements.arc);\n\t\t},\n\n\t\tcalculateTotal: function() {\n\t\t\tvar dataset = this.getDataset();\n\t\t\tvar meta = this.getMeta();\n\t\t\tvar total = 0;\n\t\t\tvar value;\n\n\t\t\thelpers.each(meta.data, function(element, index) {\n\t\t\t\tvalue = dataset.data[index];\n\t\t\t\tif (!isNaN(value) && !element.hidden) {\n\t\t\t\t\ttotal += Math.abs(value);\n\t\t\t\t}\n\t\t\t});\n\n\t\t\t/* if (total === 0) {\n\t\t\t\ttotal = NaN;\n\t\t\t}*/\n\n\t\t\treturn total;\n\t\t},\n\n\t\tcalculateCircumference: function(value) {\n\t\t\tvar total = this.getMeta().total;\n\t\t\tif (total > 0 && !isNaN(value)) {\n\t\t\t\treturn (Math.PI * 2.0) * (value / total);\n\t\t\t}\n\t\t\treturn 0;\n\t\t},\n\n\t\t// gets the max border or hover width to properly scale pie charts\n\t\tgetMaxBorderWidth: function(elements) {\n\t\t\tvar max = 0,\n\t\t\t\tindex = this.index,\n\t\t\t\tlength = elements.length,\n\t\t\t\tborderWidth,\n\t\t\t\thoverWidth;\n\n\t\t\tfor (var i = 0; i < length; i++) {\n\t\t\t\tborderWidth = elements[i]._model ? elements[i]._model.borderWidth : 0;\n\t\t\t\thoverWidth = elements[i]._chart ? elements[i]._chart.config.data.datasets[index].hoverBorderWidth : 0;\n\n\t\t\t\tmax = borderWidth > max ? borderWidth : max;\n\t\t\t\tmax = hoverWidth > max ? hoverWidth : max;\n\t\t\t}\n\t\t\treturn max;\n\t\t}\n\t});\n};\n\n},{}],18:[function(require,module,exports){\n'use strict';\n\nmodule.exports = function(Chart) {\n\n\tvar helpers = Chart.helpers;\n\n\tChart.defaults.line = {\n\t\tshowLines: true,\n\t\tspanGaps: false,\n\n\t\thover: {\n\t\t\tmode: 'label'\n\t\t},\n\n\t\tscales: {\n\t\t\txAxes: [{\n\t\t\t\ttype: 'category',\n\t\t\t\tid: 'x-axis-0'\n\t\t\t}],\n\t\t\tyAxes: [{\n\t\t\t\ttype: 'linear',\n\t\t\t\tid: 'y-axis-0'\n\t\t\t}]\n\t\t}\n\t};\n\n\tfunction lineEnabled(dataset, options) {\n\t\treturn helpers.getValueOrDefault(dataset.showLine, options.showLines);\n\t}\n\n\tChart.controllers.line = Chart.DatasetController.extend({\n\n\t\tdatasetElementType: Chart.elements.Line,\n\n\t\tdataElementType: Chart.elements.Point,\n\n\t\tupdate: function(reset) {\n\t\t\tvar me = this;\n\t\t\tvar meta = me.getMeta();\n\t\t\tvar line = meta.dataset;\n\t\t\tvar points = meta.data || [];\n\t\t\tvar options = me.chart.options;\n\t\t\tvar lineElementOptions = options.elements.line;\n\t\t\tvar scale = me.getScaleForId(meta.yAxisID);\n\t\t\tvar i, ilen, custom;\n\t\t\tvar dataset = me.getDataset();\n\t\t\tvar showLine = lineEnabled(dataset, options);\n\n\t\t\t// Update Line\n\t\t\tif (showLine) {\n\t\t\t\tcustom = line.custom || {};\n\n\t\t\t\t// Compatibility: If the properties are defined with only the old name, use those values\n\t\t\t\tif ((dataset.tension !== undefined) && (dataset.lineTension === undefined)) {\n\t\t\t\t\tdataset.lineTension = dataset.tension;\n\t\t\t\t}\n\n\t\t\t\t// Utility\n\t\t\t\tline._scale = scale;\n\t\t\t\tline._datasetIndex = me.index;\n\t\t\t\t// Data\n\t\t\t\tline._children = points;\n\t\t\t\t// Model\n\t\t\t\tline._model = {\n\t\t\t\t\t// Appearance\n\t\t\t\t\t// The default behavior of lines is to break at null values, according\n\t\t\t\t\t// to https://github.com/chartjs/Chart.js/issues/2435#issuecomment-216718158\n\t\t\t\t\t// This option gives lines the ability to span gaps\n\t\t\t\t\tspanGaps: dataset.spanGaps ? dataset.spanGaps : options.spanGaps,\n\t\t\t\t\ttension: custom.tension ? custom.tension : helpers.getValueOrDefault(dataset.lineTension, lineElementOptions.tension),\n\t\t\t\t\tbackgroundColor: custom.backgroundColor ? custom.backgroundColor : (dataset.backgroundColor || lineElementOptions.backgroundColor),\n\t\t\t\t\tborderWidth: custom.borderWidth ? custom.borderWidth : (dataset.borderWidth || lineElementOptions.borderWidth),\n\t\t\t\t\tborderColor: custom.borderColor ? custom.borderColor : (dataset.borderColor || lineElementOptions.borderColor),\n\t\t\t\t\tborderCapStyle: custom.borderCapStyle ? custom.borderCapStyle : (dataset.borderCapStyle || lineElementOptions.borderCapStyle),\n\t\t\t\t\tborderDash: custom.borderDash ? custom.borderDash : (dataset.borderDash || lineElementOptions.borderDash),\n\t\t\t\t\tborderDashOffset: custom.borderDashOffset ? custom.borderDashOffset : (dataset.borderDashOffset || lineElementOptions.borderDashOffset),\n\t\t\t\t\tborderJoinStyle: custom.borderJoinStyle ? custom.borderJoinStyle : (dataset.borderJoinStyle || lineElementOptions.borderJoinStyle),\n\t\t\t\t\tfill: custom.fill ? custom.fill : (dataset.fill !== undefined ? dataset.fill : lineElementOptions.fill),\n\t\t\t\t\tsteppedLine: custom.steppedLine ? custom.steppedLine : helpers.getValueOrDefault(dataset.steppedLine, lineElementOptions.stepped),\n\t\t\t\t\tcubicInterpolationMode: custom.cubicInterpolationMode ? custom.cubicInterpolationMode : helpers.getValueOrDefault(dataset.cubicInterpolationMode, lineElementOptions.cubicInterpolationMode),\n\t\t\t\t};\n\n\t\t\t\tline.pivot();\n\t\t\t}\n\n\t\t\t// Update Points\n\t\t\tfor (i=0, ilen=points.length; i<ilen; ++i) {\n\t\t\t\tme.updateElement(points[i], i, reset);\n\t\t\t}\n\n\t\t\tif (showLine && line._model.tension !== 0) {\n\t\t\t\tme.updateBezierControlPoints();\n\t\t\t}\n\n\t\t\t// Now pivot the point for animation\n\t\t\tfor (i=0, ilen=points.length; i<ilen; ++i) {\n\t\t\t\tpoints[i].pivot();\n\t\t\t}\n\t\t},\n\n\t\tgetPointBackgroundColor: function(point, index) {\n\t\t\tvar backgroundColor = this.chart.options.elements.point.backgroundColor;\n\t\t\tvar dataset = this.getDataset();\n\t\t\tvar custom = point.custom || {};\n\n\t\t\tif (custom.backgroundColor) {\n\t\t\t\tbackgroundColor = custom.backgroundColor;\n\t\t\t} else if (dataset.pointBackgroundColor) {\n\t\t\t\tbackgroundColor = helpers.getValueAtIndexOrDefault(dataset.pointBackgroundColor, index, backgroundColor);\n\t\t\t} else if (dataset.backgroundColor) {\n\t\t\t\tbackgroundColor = dataset.backgroundColor;\n\t\t\t}\n\n\t\t\treturn backgroundColor;\n\t\t},\n\n\t\tgetPointBorderColor: function(point, index) {\n\t\t\tvar borderColor = this.chart.options.elements.point.borderColor;\n\t\t\tvar dataset = this.getDataset();\n\t\t\tvar custom = point.custom || {};\n\n\t\t\tif (custom.borderColor) {\n\t\t\t\tborderColor = custom.borderColor;\n\t\t\t} else if (dataset.pointBorderColor) {\n\t\t\t\tborderColor = helpers.getValueAtIndexOrDefault(dataset.pointBorderColor, index, borderColor);\n\t\t\t} else if (dataset.borderColor) {\n\t\t\t\tborderColor = dataset.borderColor;\n\t\t\t}\n\n\t\t\treturn borderColor;\n\t\t},\n\n\t\tgetPointBorderWidth: function(point, index) {\n\t\t\tvar borderWidth = this.chart.options.elements.point.borderWidth;\n\t\t\tvar dataset = this.getDataset();\n\t\t\tvar custom = point.custom || {};\n\n\t\t\tif (!isNaN(custom.borderWidth)) {\n\t\t\t\tborderWidth = custom.borderWidth;\n\t\t\t} else if (!isNaN(dataset.pointBorderWidth)) {\n\t\t\t\tborderWidth = helpers.getValueAtIndexOrDefault(dataset.pointBorderWidth, index, borderWidth);\n\t\t\t} else if (!isNaN(dataset.borderWidth)) {\n\t\t\t\tborderWidth = dataset.borderWidth;\n\t\t\t}\n\n\t\t\treturn borderWidth;\n\t\t},\n\n\t\tupdateElement: function(point, index, reset) {\n\t\t\tvar me = this;\n\t\t\tvar meta = me.getMeta();\n\t\t\tvar custom = point.custom || {};\n\t\t\tvar dataset = me.getDataset();\n\t\t\tvar datasetIndex = me.index;\n\t\t\tvar value = dataset.data[index];\n\t\t\tvar yScale = me.getScaleForId(meta.yAxisID);\n\t\t\tvar xScale = me.getScaleForId(meta.xAxisID);\n\t\t\tvar pointOptions = me.chart.options.elements.point;\n\t\t\tvar x, y;\n\t\t\tvar labels = me.chart.data.labels || [];\n\t\t\tvar includeOffset = (labels.length === 1 || dataset.data.length === 1) || me.chart.isCombo;\n\n\t\t\t// Compatibility: If the properties are defined with only the old name, use those values\n\t\t\tif ((dataset.radius !== undefined) && (dataset.pointRadius === undefined)) {\n\t\t\t\tdataset.pointRadius = dataset.radius;\n\t\t\t}\n\t\t\tif ((dataset.hitRadius !== undefined) && (dataset.pointHitRadius === undefined)) {\n\t\t\t\tdataset.pointHitRadius = dataset.hitRadius;\n\t\t\t}\n\n\t\t\tx = xScale.getPixelForValue(typeof value === 'object' ? value : NaN, index, datasetIndex, includeOffset);\n\t\t\ty = reset ? yScale.getBasePixel() : me.calculatePointY(value, index, datasetIndex);\n\n\t\t\t// Utility\n\t\t\tpoint._xScale = xScale;\n\t\t\tpoint._yScale = yScale;\n\t\t\tpoint._datasetIndex = datasetIndex;\n\t\t\tpoint._index = index;\n\n\t\t\t// Desired view properties\n\t\t\tpoint._model = {\n\t\t\t\tx: x,\n\t\t\t\ty: y,\n\t\t\t\tskip: custom.skip || isNaN(x) || isNaN(y),\n\t\t\t\t// Appearance\n\t\t\t\tradius: custom.radius || helpers.getValueAtIndexOrDefault(dataset.pointRadius, index, pointOptions.radius),\n\t\t\t\tpointStyle: custom.pointStyle || helpers.getValueAtIndexOrDefault(dataset.pointStyle, index, pointOptions.pointStyle),\n\t\t\t\tbackgroundColor: me.getPointBackgroundColor(point, index),\n\t\t\t\tborderColor: me.getPointBorderColor(point, index),\n\t\t\t\tborderWidth: me.getPointBorderWidth(point, index),\n\t\t\t\ttension: meta.dataset._model ? meta.dataset._model.tension : 0,\n\t\t\t\tsteppedLine: meta.dataset._model ? meta.dataset._model.steppedLine : false,\n\t\t\t\t// Tooltip\n\t\t\t\thitRadius: custom.hitRadius || helpers.getValueAtIndexOrDefault(dataset.pointHitRadius, index, pointOptions.hitRadius)\n\t\t\t};\n\t\t},\n\n\t\tcalculatePointY: function(value, index, datasetIndex) {\n\t\t\tvar me = this;\n\t\t\tvar chart = me.chart;\n\t\t\tvar meta = me.getMeta();\n\t\t\tvar yScale = me.getScaleForId(meta.yAxisID);\n\t\t\tvar sumPos = 0;\n\t\t\tvar sumNeg = 0;\n\t\t\tvar i, ds, dsMeta;\n\n\t\t\tif (yScale.options.stacked) {\n\t\t\t\tfor (i = 0; i < datasetIndex; i++) {\n\t\t\t\t\tds = chart.data.datasets[i];\n\t\t\t\t\tdsMeta = chart.getDatasetMeta(i);\n\t\t\t\t\tif (dsMeta.type === 'line' && dsMeta.yAxisID === yScale.id && chart.isDatasetVisible(i)) {\n\t\t\t\t\t\tvar stackedRightValue = Number(yScale.getRightValue(ds.data[index]));\n\t\t\t\t\t\tif (stackedRightValue < 0) {\n\t\t\t\t\t\t\tsumNeg += stackedRightValue || 0;\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tsumPos += stackedRightValue || 0;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tvar rightValue = Number(yScale.getRightValue(value));\n\t\t\t\tif (rightValue < 0) {\n\t\t\t\t\treturn yScale.getPixelForValue(sumNeg + rightValue);\n\t\t\t\t}\n\t\t\t\treturn yScale.getPixelForValue(sumPos + rightValue);\n\t\t\t}\n\n\t\t\treturn yScale.getPixelForValue(value);\n\t\t},\n\n\t\tupdateBezierControlPoints: function() {\n\t\t\tvar me = this;\n\t\t\tvar meta = me.getMeta();\n\t\t\tvar area = me.chart.chartArea;\n\t\t\tvar points = (meta.data || []);\n\t\t\tvar i, ilen, point, model, controlPoints;\n\n\t\t\t// Only consider points that are drawn in case the spanGaps option is used\n\t\t\tif (meta.dataset._model.spanGaps) {\n\t\t\t\tpoints = points.filter(function(pt) {\n\t\t\t\t\treturn !pt._model.skip;\n\t\t\t\t});\n\t\t\t}\n\n\t\t\tfunction capControlPoint(pt, min, max) {\n\t\t\t\treturn Math.max(Math.min(pt, max), min);\n\t\t\t}\n\n\t\t\tif (meta.dataset._model.cubicInterpolationMode === 'monotone') {\n\t\t\t\thelpers.splineCurveMonotone(points);\n\t\t\t} else {\n\t\t\t\tfor (i = 0, ilen = points.length; i < ilen; ++i) {\n\t\t\t\t\tpoint = points[i];\n\t\t\t\t\tmodel = point._model;\n\t\t\t\t\tcontrolPoints = helpers.splineCurve(\n\t\t\t\t\t\thelpers.previousItem(points, i)._model,\n\t\t\t\t\t\tmodel,\n\t\t\t\t\t\thelpers.nextItem(points, i)._model,\n\t\t\t\t\t\tmeta.dataset._model.tension\n\t\t\t\t\t);\n\t\t\t\t\tmodel.controlPointPreviousX = controlPoints.previous.x;\n\t\t\t\t\tmodel.controlPointPreviousY = controlPoints.previous.y;\n\t\t\t\t\tmodel.controlPointNextX = controlPoints.next.x;\n\t\t\t\t\tmodel.controlPointNextY = controlPoints.next.y;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (me.chart.options.elements.line.capBezierPoints) {\n\t\t\t\tfor (i = 0, ilen = points.length; i < ilen; ++i) {\n\t\t\t\t\tmodel = points[i]._model;\n\t\t\t\t\tmodel.controlPointPreviousX = capControlPoint(model.controlPointPreviousX, area.left, area.right);\n\t\t\t\t\tmodel.controlPointPreviousY = capControlPoint(model.controlPointPreviousY, area.top, area.bottom);\n\t\t\t\t\tmodel.controlPointNextX = capControlPoint(model.controlPointNextX, area.left, area.right);\n\t\t\t\t\tmodel.controlPointNextY = capControlPoint(model.controlPointNextY, area.top, area.bottom);\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\n\t\tdraw: function() {\n\t\t\tvar me = this;\n\t\t\tvar chart = me.chart;\n\t\t\tvar meta = me.getMeta();\n\t\t\tvar points = meta.data || [];\n\t\t\tvar area = chart.chartArea;\n\t\t\tvar ilen = points.length;\n\t\t\tvar i = 0;\n\n\t\t\tChart.canvasHelpers.clipArea(chart.ctx, area);\n\n\t\t\tif (lineEnabled(me.getDataset(), chart.options)) {\n\t\t\t\tmeta.dataset.draw();\n\t\t\t}\n\n\t\t\tChart.canvasHelpers.unclipArea(chart.ctx);\n\n\t\t\t// Draw the points\n\t\t\tfor (; i<ilen; ++i) {\n\t\t\t\tpoints[i].draw(area);\n\t\t\t}\n\t\t},\n\n\t\tsetHoverStyle: function(point) {\n\t\t\t// Point\n\t\t\tvar dataset = this.chart.data.datasets[point._datasetIndex];\n\t\t\tvar index = point._index;\n\t\t\tvar custom = point.custom || {};\n\t\t\tvar model = point._model;\n\n\t\t\tmodel.radius = custom.hoverRadius || helpers.getValueAtIndexOrDefault(dataset.pointHoverRadius, index, this.chart.options.elements.point.hoverRadius);\n\t\t\tmodel.backgroundColor = custom.hoverBackgroundColor || helpers.getValueAtIndexOrDefault(dataset.pointHoverBackgroundColor, index, helpers.getHoverColor(model.backgroundColor));\n\t\t\tmodel.borderColor = custom.hoverBorderColor || helpers.getValueAtIndexOrDefault(dataset.pointHoverBorderColor, index, helpers.getHoverColor(model.borderColor));\n\t\t\tmodel.borderWidth = custom.hoverBorderWidth || helpers.getValueAtIndexOrDefault(dataset.pointHoverBorderWidth, index, model.borderWidth);\n\t\t},\n\n\t\tremoveHoverStyle: function(point) {\n\t\t\tvar me = this;\n\t\t\tvar dataset = me.chart.data.datasets[point._datasetIndex];\n\t\t\tvar index = point._index;\n\t\t\tvar custom = point.custom || {};\n\t\t\tvar model = point._model;\n\n\t\t\t// Compatibility: If the properties are defined with only the old name, use those values\n\t\t\tif ((dataset.radius !== undefined) && (dataset.pointRadius === undefined)) {\n\t\t\t\tdataset.pointRadius = dataset.radius;\n\t\t\t}\n\n\t\t\tmodel.radius = custom.radius || helpers.getValueAtIndexOrDefault(dataset.pointRadius, index, me.chart.options.elements.point.radius);\n\t\t\tmodel.backgroundColor = me.getPointBackgroundColor(point, index);\n\t\t\tmodel.borderColor = me.getPointBorderColor(point, index);\n\t\t\tmodel.borderWidth = me.getPointBorderWidth(point, index);\n\t\t}\n\t});\n};\n\n},{}],19:[function(require,module,exports){\n'use strict';\n\nmodule.exports = function(Chart) {\n\n\tvar helpers = Chart.helpers;\n\n\tChart.defaults.polarArea = {\n\n\t\tscale: {\n\t\t\ttype: 'radialLinear',\n\t\t\tangleLines: {\n\t\t\t\tdisplay: false\n\t\t\t},\n\t\t\tgridLines: {\n\t\t\t\tcircular: true\n\t\t\t},\n\t\t\tpointLabels: {\n\t\t\t\tdisplay: false\n\t\t\t},\n\t\t\tticks: {\n\t\t\t\tbeginAtZero: true\n\t\t\t}\n\t\t},\n\n\t\t// Boolean - Whether to animate the rotation of the chart\n\t\tanimation: {\n\t\t\tanimateRotate: true,\n\t\t\tanimateScale: true\n\t\t},\n\n\t\tstartAngle: -0.5 * Math.PI,\n\t\taspectRatio: 1,\n\t\tlegendCallback: function(chart) {\n\t\t\tvar text = [];\n\t\t\ttext.push('<ul class=\"' + chart.id + '-legend\">');\n\n\t\t\tvar data = chart.data;\n\t\t\tvar datasets = data.datasets;\n\t\t\tvar labels = data.labels;\n\n\t\t\tif (datasets.length) {\n\t\t\t\tfor (var i = 0; i < datasets[0].data.length; ++i) {\n\t\t\t\t\ttext.push('<li><span style=\"background-color:' + datasets[0].backgroundColor[i] + '\"></span>');\n\t\t\t\t\tif (labels[i]) {\n\t\t\t\t\t\ttext.push(labels[i]);\n\t\t\t\t\t}\n\t\t\t\t\ttext.push('</li>');\n\t\t\t\t}\n\t\t\t}\n\n\t\t\ttext.push('</ul>');\n\t\t\treturn text.join('');\n\t\t},\n\t\tlegend: {\n\t\t\tlabels: {\n\t\t\t\tgenerateLabels: function(chart) {\n\t\t\t\t\tvar data = chart.data;\n\t\t\t\t\tif (data.labels.length && data.datasets.length) {\n\t\t\t\t\t\treturn data.labels.map(function(label, i) {\n\t\t\t\t\t\t\tvar meta = chart.getDatasetMeta(0);\n\t\t\t\t\t\t\tvar ds = data.datasets[0];\n\t\t\t\t\t\t\tvar arc = meta.data[i];\n\t\t\t\t\t\t\tvar custom = arc.custom || {};\n\t\t\t\t\t\t\tvar getValueAtIndexOrDefault = helpers.getValueAtIndexOrDefault;\n\t\t\t\t\t\t\tvar arcOpts = chart.options.elements.arc;\n\t\t\t\t\t\t\tvar fill = custom.backgroundColor ? custom.backgroundColor : getValueAtIndexOrDefault(ds.backgroundColor, i, arcOpts.backgroundColor);\n\t\t\t\t\t\t\tvar stroke = custom.borderColor ? custom.borderColor : getValueAtIndexOrDefault(ds.borderColor, i, arcOpts.borderColor);\n\t\t\t\t\t\t\tvar bw = custom.borderWidth ? custom.borderWidth : getValueAtIndexOrDefault(ds.borderWidth, i, arcOpts.borderWidth);\n\n\t\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\t\ttext: label,\n\t\t\t\t\t\t\t\tfillStyle: fill,\n\t\t\t\t\t\t\t\tstrokeStyle: stroke,\n\t\t\t\t\t\t\t\tlineWidth: bw,\n\t\t\t\t\t\t\t\thidden: isNaN(ds.data[i]) || meta.data[i].hidden,\n\n\t\t\t\t\t\t\t\t// Extra data used for toggling the correct item\n\t\t\t\t\t\t\t\tindex: i\n\t\t\t\t\t\t\t};\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t\treturn [];\n\t\t\t\t}\n\t\t\t},\n\n\t\t\tonClick: function(e, legendItem) {\n\t\t\t\tvar index = legendItem.index;\n\t\t\t\tvar chart = this.chart;\n\t\t\t\tvar i, ilen, meta;\n\n\t\t\t\tfor (i = 0, ilen = (chart.data.datasets || []).length; i < ilen; ++i) {\n\t\t\t\t\tmeta = chart.getDatasetMeta(i);\n\t\t\t\t\tmeta.data[index].hidden = !meta.data[index].hidden;\n\t\t\t\t}\n\n\t\t\t\tchart.update();\n\t\t\t}\n\t\t},\n\n\t\t// Need to override these to give a nice default\n\t\ttooltips: {\n\t\t\tcallbacks: {\n\t\t\t\ttitle: function() {\n\t\t\t\t\treturn '';\n\t\t\t\t},\n\t\t\t\tlabel: function(tooltipItem, data) {\n\t\t\t\t\treturn data.labels[tooltipItem.index] + ': ' + tooltipItem.yLabel;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t};\n\n\tChart.controllers.polarArea = Chart.DatasetController.extend({\n\n\t\tdataElementType: Chart.elements.Arc,\n\n\t\tlinkScales: helpers.noop,\n\n\t\tupdate: function(reset) {\n\t\t\tvar me = this;\n\t\t\tvar chart = me.chart;\n\t\t\tvar chartArea = chart.chartArea;\n\t\t\tvar meta = me.getMeta();\n\t\t\tvar opts = chart.options;\n\t\t\tvar arcOpts = opts.elements.arc;\n\t\t\tvar minSize = Math.min(chartArea.right - chartArea.left, chartArea.bottom - chartArea.top);\n\t\t\tchart.outerRadius = Math.max((minSize - arcOpts.borderWidth / 2) / 2, 0);\n\t\t\tchart.innerRadius = Math.max(opts.cutoutPercentage ? (chart.outerRadius / 100) * (opts.cutoutPercentage) : 1, 0);\n\t\t\tchart.radiusLength = (chart.outerRadius - chart.innerRadius) / chart.getVisibleDatasetCount();\n\n\t\t\tme.outerRadius = chart.outerRadius - (chart.radiusLength * me.index);\n\t\t\tme.innerRadius = me.outerRadius - chart.radiusLength;\n\n\t\t\tmeta.count = me.countVisibleElements();\n\n\t\t\thelpers.each(meta.data, function(arc, index) {\n\t\t\t\tme.updateElement(arc, index, reset);\n\t\t\t});\n\t\t},\n\n\t\tupdateElement: function(arc, index, reset) {\n\t\t\tvar me = this;\n\t\t\tvar chart = me.chart;\n\t\t\tvar dataset = me.getDataset();\n\t\t\tvar opts = chart.options;\n\t\t\tvar animationOpts = opts.animation;\n\t\t\tvar scale = chart.scale;\n\t\t\tvar getValueAtIndexOrDefault = helpers.getValueAtIndexOrDefault;\n\t\t\tvar labels = chart.data.labels;\n\n\t\t\tvar circumference = me.calculateCircumference(dataset.data[index]);\n\t\t\tvar centerX = scale.xCenter;\n\t\t\tvar centerY = scale.yCenter;\n\n\t\t\t// If there is NaN data before us, we need to calculate the starting angle correctly.\n\t\t\t// We could be way more efficient here, but its unlikely that the polar area chart will have a lot of data\n\t\t\tvar visibleCount = 0;\n\t\t\tvar meta = me.getMeta();\n\t\t\tfor (var i = 0; i < index; ++i) {\n\t\t\t\tif (!isNaN(dataset.data[i]) && !meta.data[i].hidden) {\n\t\t\t\t\t++visibleCount;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// var negHalfPI = -0.5 * Math.PI;\n\t\t\tvar datasetStartAngle = opts.startAngle;\n\t\t\tvar distance = arc.hidden ? 0 : scale.getDistanceFromCenterForValue(dataset.data[index]);\n\t\t\tvar startAngle = datasetStartAngle + (circumference * visibleCount);\n\t\t\tvar endAngle = startAngle + (arc.hidden ? 0 : circumference);\n\n\t\t\tvar resetRadius = animationOpts.animateScale ? 0 : scale.getDistanceFromCenterForValue(dataset.data[index]);\n\n\t\t\thelpers.extend(arc, {\n\t\t\t\t// Utility\n\t\t\t\t_datasetIndex: me.index,\n\t\t\t\t_index: index,\n\t\t\t\t_scale: scale,\n\n\t\t\t\t// Desired view properties\n\t\t\t\t_model: {\n\t\t\t\t\tx: centerX,\n\t\t\t\t\ty: centerY,\n\t\t\t\t\tinnerRadius: 0,\n\t\t\t\t\touterRadius: reset ? resetRadius : distance,\n\t\t\t\t\tstartAngle: reset && animationOpts.animateRotate ? datasetStartAngle : startAngle,\n\t\t\t\t\tendAngle: reset && animationOpts.animateRotate ? datasetStartAngle : endAngle,\n\t\t\t\t\tlabel: getValueAtIndexOrDefault(labels, index, labels[index])\n\t\t\t\t}\n\t\t\t});\n\n\t\t\t// Apply border and fill style\n\t\t\tme.removeHoverStyle(arc);\n\n\t\t\tarc.pivot();\n\t\t},\n\n\t\tremoveHoverStyle: function(arc) {\n\t\t\tChart.DatasetController.prototype.removeHoverStyle.call(this, arc, this.chart.options.elements.arc);\n\t\t},\n\n\t\tcountVisibleElements: function() {\n\t\t\tvar dataset = this.getDataset();\n\t\t\tvar meta = this.getMeta();\n\t\t\tvar count = 0;\n\n\t\t\thelpers.each(meta.data, function(element, index) {\n\t\t\t\tif (!isNaN(dataset.data[index]) && !element.hidden) {\n\t\t\t\t\tcount++;\n\t\t\t\t}\n\t\t\t});\n\n\t\t\treturn count;\n\t\t},\n\n\t\tcalculateCircumference: function(value) {\n\t\t\tvar count = this.getMeta().count;\n\t\t\tif (count > 0 && !isNaN(value)) {\n\t\t\t\treturn (2 * Math.PI) / count;\n\t\t\t}\n\t\t\treturn 0;\n\t\t}\n\t});\n};\n\n},{}],20:[function(require,module,exports){\n'use strict';\n\nmodule.exports = function(Chart) {\n\n\tvar helpers = Chart.helpers;\n\n\tChart.defaults.radar = {\n\t\taspectRatio: 1,\n\t\tscale: {\n\t\t\ttype: 'radialLinear'\n\t\t},\n\t\telements: {\n\t\t\tline: {\n\t\t\t\ttension: 0 // no bezier in radar\n\t\t\t}\n\t\t}\n\t};\n\n\tChart.controllers.radar = Chart.DatasetController.extend({\n\n\t\tdatasetElementType: Chart.elements.Line,\n\n\t\tdataElementType: Chart.elements.Point,\n\n\t\tlinkScales: helpers.noop,\n\n\t\tupdate: function(reset) {\n\t\t\tvar me = this;\n\t\t\tvar meta = me.getMeta();\n\t\t\tvar line = meta.dataset;\n\t\t\tvar points = meta.data;\n\t\t\tvar custom = line.custom || {};\n\t\t\tvar dataset = me.getDataset();\n\t\t\tvar lineElementOptions = me.chart.options.elements.line;\n\t\t\tvar scale = me.chart.scale;\n\n\t\t\t// Compatibility: If the properties are defined with only the old name, use those values\n\t\t\tif ((dataset.tension !== undefined) && (dataset.lineTension === undefined)) {\n\t\t\t\tdataset.lineTension = dataset.tension;\n\t\t\t}\n\n\t\t\thelpers.extend(meta.dataset, {\n\t\t\t\t// Utility\n\t\t\t\t_datasetIndex: me.index,\n\t\t\t\t_scale: scale,\n\t\t\t\t// Data\n\t\t\t\t_children: points,\n\t\t\t\t_loop: true,\n\t\t\t\t// Model\n\t\t\t\t_model: {\n\t\t\t\t\t// Appearance\n\t\t\t\t\ttension: custom.tension ? custom.tension : helpers.getValueOrDefault(dataset.lineTension, lineElementOptions.tension),\n\t\t\t\t\tbackgroundColor: custom.backgroundColor ? custom.backgroundColor : (dataset.backgroundColor || lineElementOptions.backgroundColor),\n\t\t\t\t\tborderWidth: custom.borderWidth ? custom.borderWidth : (dataset.borderWidth || lineElementOptions.borderWidth),\n\t\t\t\t\tborderColor: custom.borderColor ? custom.borderColor : (dataset.borderColor || lineElementOptions.borderColor),\n\t\t\t\t\tfill: custom.fill ? custom.fill : (dataset.fill !== undefined ? dataset.fill : lineElementOptions.fill),\n\t\t\t\t\tborderCapStyle: custom.borderCapStyle ? custom.borderCapStyle : (dataset.borderCapStyle || lineElementOptions.borderCapStyle),\n\t\t\t\t\tborderDash: custom.borderDash ? custom.borderDash : (dataset.borderDash || lineElementOptions.borderDash),\n\t\t\t\t\tborderDashOffset: custom.borderDashOffset ? custom.borderDashOffset : (dataset.borderDashOffset || lineElementOptions.borderDashOffset),\n\t\t\t\t\tborderJoinStyle: custom.borderJoinStyle ? custom.borderJoinStyle : (dataset.borderJoinStyle || lineElementOptions.borderJoinStyle),\n\t\t\t\t}\n\t\t\t});\n\n\t\t\tmeta.dataset.pivot();\n\n\t\t\t// Update Points\n\t\t\thelpers.each(points, function(point, index) {\n\t\t\t\tme.updateElement(point, index, reset);\n\t\t\t}, me);\n\n\t\t\t// Update bezier control points\n\t\t\tme.updateBezierControlPoints();\n\t\t},\n\t\tupdateElement: function(point, index, reset) {\n\t\t\tvar me = this;\n\t\t\tvar custom = point.custom || {};\n\t\t\tvar dataset = me.getDataset();\n\t\t\tvar scale = me.chart.scale;\n\t\t\tvar pointElementOptions = me.chart.options.elements.point;\n\t\t\tvar pointPosition = scale.getPointPositionForValue(index, dataset.data[index]);\n\n\t\t\t// Compatibility: If the properties are defined with only the old name, use those values\n\t\t\tif ((dataset.radius !== undefined) && (dataset.pointRadius === undefined)) {\n\t\t\t\tdataset.pointRadius = dataset.radius;\n\t\t\t}\n\t\t\tif ((dataset.hitRadius !== undefined) && (dataset.pointHitRadius === undefined)) {\n\t\t\t\tdataset.pointHitRadius = dataset.hitRadius;\n\t\t\t}\n\n\t\t\thelpers.extend(point, {\n\t\t\t\t// Utility\n\t\t\t\t_datasetIndex: me.index,\n\t\t\t\t_index: index,\n\t\t\t\t_scale: scale,\n\n\t\t\t\t// Desired view properties\n\t\t\t\t_model: {\n\t\t\t\t\tx: reset ? scale.xCenter : pointPosition.x, // value not used in dataset scale, but we want a consistent API between scales\n\t\t\t\t\ty: reset ? scale.yCenter : pointPosition.y,\n\n\t\t\t\t\t// Appearance\n\t\t\t\t\ttension: custom.tension ? custom.tension : helpers.getValueOrDefault(dataset.lineTension, me.chart.options.elements.line.tension),\n\t\t\t\t\tradius: custom.radius ? custom.radius : helpers.getValueAtIndexOrDefault(dataset.pointRadius, index, pointElementOptions.radius),\n\t\t\t\t\tbackgroundColor: custom.backgroundColor ? custom.backgroundColor : helpers.getValueAtIndexOrDefault(dataset.pointBackgroundColor, index, pointElementOptions.backgroundColor),\n\t\t\t\t\tborderColor: custom.borderColor ? custom.borderColor : helpers.getValueAtIndexOrDefault(dataset.pointBorderColor, index, pointElementOptions.borderColor),\n\t\t\t\t\tborderWidth: custom.borderWidth ? custom.borderWidth : helpers.getValueAtIndexOrDefault(dataset.pointBorderWidth, index, pointElementOptions.borderWidth),\n\t\t\t\t\tpointStyle: custom.pointStyle ? custom.pointStyle : helpers.getValueAtIndexOrDefault(dataset.pointStyle, index, pointElementOptions.pointStyle),\n\n\t\t\t\t\t// Tooltip\n\t\t\t\t\thitRadius: custom.hitRadius ? custom.hitRadius : helpers.getValueAtIndexOrDefault(dataset.pointHitRadius, index, pointElementOptions.hitRadius)\n\t\t\t\t}\n\t\t\t});\n\n\t\t\tpoint._model.skip = custom.skip ? custom.skip : (isNaN(point._model.x) || isNaN(point._model.y));\n\t\t},\n\t\tupdateBezierControlPoints: function() {\n\t\t\tvar chartArea = this.chart.chartArea;\n\t\t\tvar meta = this.getMeta();\n\n\t\t\thelpers.each(meta.data, function(point, index) {\n\t\t\t\tvar model = point._model;\n\t\t\t\tvar controlPoints = helpers.splineCurve(\n\t\t\t\t\thelpers.previousItem(meta.data, index, true)._model,\n\t\t\t\t\tmodel,\n\t\t\t\t\thelpers.nextItem(meta.data, index, true)._model,\n\t\t\t\t\tmodel.tension\n\t\t\t\t);\n\n\t\t\t\t// Prevent the bezier going outside of the bounds of the graph\n\t\t\t\tmodel.controlPointPreviousX = Math.max(Math.min(controlPoints.previous.x, chartArea.right), chartArea.left);\n\t\t\t\tmodel.controlPointPreviousY = Math.max(Math.min(controlPoints.previous.y, chartArea.bottom), chartArea.top);\n\n\t\t\t\tmodel.controlPointNextX = Math.max(Math.min(controlPoints.next.x, chartArea.right), chartArea.left);\n\t\t\t\tmodel.controlPointNextY = Math.max(Math.min(controlPoints.next.y, chartArea.bottom), chartArea.top);\n\n\t\t\t\t// Now pivot the point for animation\n\t\t\t\tpoint.pivot();\n\t\t\t});\n\t\t},\n\n\t\tsetHoverStyle: function(point) {\n\t\t\t// Point\n\t\t\tvar dataset = this.chart.data.datasets[point._datasetIndex];\n\t\t\tvar custom = point.custom || {};\n\t\t\tvar index = point._index;\n\t\t\tvar model = point._model;\n\n\t\t\tmodel.radius = custom.hoverRadius ? custom.hoverRadius : helpers.getValueAtIndexOrDefault(dataset.pointHoverRadius, index, this.chart.options.elements.point.hoverRadius);\n\t\t\tmodel.backgroundColor = custom.hoverBackgroundColor ? custom.hoverBackgroundColor : helpers.getValueAtIndexOrDefault(dataset.pointHoverBackgroundColor, index, helpers.getHoverColor(model.backgroundColor));\n\t\t\tmodel.borderColor = custom.hoverBorderColor ? custom.hoverBorderColor : helpers.getValueAtIndexOrDefault(dataset.pointHoverBorderColor, index, helpers.getHoverColor(model.borderColor));\n\t\t\tmodel.borderWidth = custom.hoverBorderWidth ? custom.hoverBorderWidth : helpers.getValueAtIndexOrDefault(dataset.pointHoverBorderWidth, index, model.borderWidth);\n\t\t},\n\n\t\tremoveHoverStyle: function(point) {\n\t\t\tvar dataset = this.chart.data.datasets[point._datasetIndex];\n\t\t\tvar custom = point.custom || {};\n\t\t\tvar index = point._index;\n\t\t\tvar model = point._model;\n\t\t\tvar pointElementOptions = this.chart.options.elements.point;\n\n\t\t\tmodel.radius = custom.radius ? custom.radius : helpers.getValueAtIndexOrDefault(dataset.pointRadius, index, pointElementOptions.radius);\n\t\t\tmodel.backgroundColor = custom.backgroundColor ? custom.backgroundColor : helpers.getValueAtIndexOrDefault(dataset.pointBackgroundColor, index, pointElementOptions.backgroundColor);\n\t\t\tmodel.borderColor = custom.borderColor ? custom.borderColor : helpers.getValueAtIndexOrDefault(dataset.pointBorderColor, index, pointElementOptions.borderColor);\n\t\t\tmodel.borderWidth = custom.borderWidth ? custom.borderWidth : helpers.getValueAtIndexOrDefault(dataset.pointBorderWidth, index, pointElementOptions.borderWidth);\n\t\t}\n\t});\n};\n\n},{}],21:[function(require,module,exports){\n/* global window: false */\n'use strict';\n\nmodule.exports = function(Chart) {\n\n\tvar helpers = Chart.helpers;\n\n\tChart.defaults.global.animation = {\n\t\tduration: 1000,\n\t\teasing: 'easeOutQuart',\n\t\tonProgress: helpers.noop,\n\t\tonComplete: helpers.noop\n\t};\n\n\tChart.Animation = Chart.Element.extend({\n\t\tchart: null, // the animation associated chart instance\n\t\tcurrentStep: 0, // the current animation step\n\t\tnumSteps: 60, // default number of steps\n\t\teasing: '', // the easing to use for this animation\n\t\trender: null, // render function used by the animation service\n\n\t\tonAnimationProgress: null, // user specified callback to fire on each step of the animation\n\t\tonAnimationComplete: null, // user specified callback to fire when the animation finishes\n\t});\n\n\tChart.animationService = {\n\t\tframeDuration: 17,\n\t\tanimations: [],\n\t\tdropFrames: 0,\n\t\trequest: null,\n\n\t\t/**\n\t\t * @param {Chart} chart - The chart to animate.\n\t\t * @param {Chart.Animation} animation - The animation that we will animate.\n\t\t * @param {Number} duration - The animation duration in ms.\n\t\t * @param {Boolean} lazy - if true, the chart is not marked as animating to enable more responsive interactions\n\t\t */\n\t\taddAnimation: function(chart, animation, duration, lazy) {\n\t\t\tvar animations = this.animations;\n\t\t\tvar i, ilen;\n\n\t\t\tanimation.chart = chart;\n\n\t\t\tif (!lazy) {\n\t\t\t\tchart.animating = true;\n\t\t\t}\n\n\t\t\tfor (i=0, ilen=animations.length; i < ilen; ++i) {\n\t\t\t\tif (animations[i].chart === chart) {\n\t\t\t\t\tanimations[i] = animation;\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tanimations.push(animation);\n\n\t\t\t// If there are no animations queued, manually kickstart a digest, for lack of a better word\n\t\t\tif (animations.length === 1) {\n\t\t\t\tthis.requestAnimationFrame();\n\t\t\t}\n\t\t},\n\n\t\tcancelAnimation: function(chart) {\n\t\t\tvar index = helpers.findIndex(this.animations, function(animation) {\n\t\t\t\treturn animation.chart === chart;\n\t\t\t});\n\n\t\t\tif (index !== -1) {\n\t\t\t\tthis.animations.splice(index, 1);\n\t\t\t\tchart.animating = false;\n\t\t\t}\n\t\t},\n\n\t\trequestAnimationFrame: function() {\n\t\t\tvar me = this;\n\t\t\tif (me.request === null) {\n\t\t\t\t// Skip animation frame requests until the active one is executed.\n\t\t\t\t// This can happen when processing mouse events, e.g. 'mousemove'\n\t\t\t\t// and 'mouseout' events will trigger multiple renders.\n\t\t\t\tme.request = helpers.requestAnimFrame.call(window, function() {\n\t\t\t\t\tme.request = null;\n\t\t\t\t\tme.startDigest();\n\t\t\t\t});\n\t\t\t}\n\t\t},\n\n\t\t/**\n\t\t * @private\n\t\t */\n\t\tstartDigest: function() {\n\t\t\tvar me = this;\n\t\t\tvar startTime = Date.now();\n\t\t\tvar framesToDrop = 0;\n\n\t\t\tif (me.dropFrames > 1) {\n\t\t\t\tframesToDrop = Math.floor(me.dropFrames);\n\t\t\t\tme.dropFrames = me.dropFrames % 1;\n\t\t\t}\n\n\t\t\tme.advance(1 + framesToDrop);\n\n\t\t\tvar endTime = Date.now();\n\n\t\t\tme.dropFrames += (endTime - startTime) / me.frameDuration;\n\n\t\t\t// Do we have more stuff to animate?\n\t\t\tif (me.animations.length > 0) {\n\t\t\t\tme.requestAnimationFrame();\n\t\t\t}\n\t\t},\n\n\t\t/**\n\t\t * @private\n\t\t */\n\t\tadvance: function(count) {\n\t\t\tvar animations = this.animations;\n\t\t\tvar animation, chart;\n\t\t\tvar i = 0;\n\n\t\t\twhile (i < animations.length) {\n\t\t\t\tanimation = animations[i];\n\t\t\t\tchart = animation.chart;\n\n\t\t\t\tanimation.currentStep = (animation.currentStep || 0) + count;\n\t\t\t\tanimation.currentStep = Math.min(animation.currentStep, animation.numSteps);\n\n\t\t\t\thelpers.callback(animation.render, [chart, animation], chart);\n\t\t\t\thelpers.callback(animation.onAnimationProgress, [animation], chart);\n\n\t\t\t\tif (animation.currentStep >= animation.numSteps) {\n\t\t\t\t\thelpers.callback(animation.onAnimationComplete, [animation], chart);\n\t\t\t\t\tchart.animating = false;\n\t\t\t\t\tanimations.splice(i, 1);\n\t\t\t\t} else {\n\t\t\t\t\t++i;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t};\n\n\t/**\n\t * Provided for backward compatibility, use Chart.Animation instead\n\t * @prop Chart.Animation#animationObject\n\t * @deprecated since version 2.6.0\n\t * @todo remove at version 3\n\t */\n\tObject.defineProperty(Chart.Animation.prototype, 'animationObject', {\n\t\tget: function() {\n\t\t\treturn this;\n\t\t}\n\t});\n\n\t/**\n\t * Provided for backward compatibility, use Chart.Animation#chart instead\n\t * @prop Chart.Animation#chartInstance\n\t * @deprecated since version 2.6.0\n\t * @todo remove at version 3\n\t */\n\tObject.defineProperty(Chart.Animation.prototype, 'chartInstance', {\n\t\tget: function() {\n\t\t\treturn this.chart;\n\t\t},\n\t\tset: function(value) {\n\t\t\tthis.chart = value;\n\t\t}\n\t});\n\n};\n\n},{}],22:[function(require,module,exports){\n'use strict';\n\nmodule.exports = function(Chart) {\n\t// Global Chart canvas helpers object for drawing items to canvas\n\tvar helpers = Chart.canvasHelpers = {};\n\n\thelpers.drawPoint = function(ctx, pointStyle, radius, x, y) {\n\t\tvar type, edgeLength, xOffset, yOffset, height, size;\n\n\t\tif (typeof pointStyle === 'object') {\n\t\t\ttype = pointStyle.toString();\n\t\t\tif (type === '[object HTMLImageElement]' || type === '[object HTMLCanvasElement]') {\n\t\t\t\tctx.drawImage(pointStyle, x - pointStyle.width / 2, y - pointStyle.height / 2, pointStyle.width, pointStyle.height);\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\n\t\tif (isNaN(radius) || radius <= 0) {\n\t\t\treturn;\n\t\t}\n\n\t\tswitch (pointStyle) {\n\t\t// Default includes circle\n\t\tdefault:\n\t\t\tctx.beginPath();\n\t\t\tctx.arc(x, y, radius, 0, Math.PI * 2);\n\t\t\tctx.closePath();\n\t\t\tctx.fill();\n\t\t\tbreak;\n\t\tcase 'triangle':\n\t\t\tctx.beginPath();\n\t\t\tedgeLength = 3 * radius / Math.sqrt(3);\n\t\t\theight = edgeLength * Math.sqrt(3) / 2;\n\t\t\tctx.moveTo(x - edgeLength / 2, y + height / 3);\n\t\t\tctx.lineTo(x + edgeLength / 2, y + height / 3);\n\t\t\tctx.lineTo(x, y - 2 * height / 3);\n\t\t\tctx.closePath();\n\t\t\tctx.fill();\n\t\t\tbreak;\n\t\tcase 'rect':\n\t\t\tsize = 1 / Math.SQRT2 * radius;\n\t\t\tctx.beginPath();\n\t\t\tctx.fillRect(x - size, y - size, 2 * size, 2 * size);\n\t\t\tctx.strokeRect(x - size, y - size, 2 * size, 2 * size);\n\t\t\tbreak;\n\t\tcase 'rectRounded':\n\t\t\tvar offset = radius / Math.SQRT2;\n\t\t\tvar leftX = x - offset;\n\t\t\tvar topY = y - offset;\n\t\t\tvar sideSize = Math.SQRT2 * radius;\n\t\t\tChart.helpers.drawRoundedRectangle(ctx, leftX, topY, sideSize, sideSize, radius / 2);\n\t\t\tctx.fill();\n\t\t\tbreak;\n\t\tcase 'rectRot':\n\t\t\tsize = 1 / Math.SQRT2 * radius;\n\t\t\tctx.beginPath();\n\t\t\tctx.moveTo(x - size, y);\n\t\t\tctx.lineTo(x, y + size);\n\t\t\tctx.lineTo(x + size, y);\n\t\t\tctx.lineTo(x, y - size);\n\t\t\tctx.closePath();\n\t\t\tctx.fill();\n\t\t\tbreak;\n\t\tcase 'cross':\n\t\t\tctx.beginPath();\n\t\t\tctx.moveTo(x, y + radius);\n\t\t\tctx.lineTo(x, y - radius);\n\t\t\tctx.moveTo(x - radius, y);\n\t\t\tctx.lineTo(x + radius, y);\n\t\t\tctx.closePath();\n\t\t\tbreak;\n\t\tcase 'crossRot':\n\t\t\tctx.beginPath();\n\t\t\txOffset = Math.cos(Math.PI / 4) * radius;\n\t\t\tyOffset = Math.sin(Math.PI / 4) * radius;\n\t\t\tctx.moveTo(x - xOffset, y - yOffset);\n\t\t\tctx.lineTo(x + xOffset, y + yOffset);\n\t\t\tctx.moveTo(x - xOffset, y + yOffset);\n\t\t\tctx.lineTo(x + xOffset, y - yOffset);\n\t\t\tctx.closePath();\n\t\t\tbreak;\n\t\tcase 'star':\n\t\t\tctx.beginPath();\n\t\t\tctx.moveTo(x, y + radius);\n\t\t\tctx.lineTo(x, y - radius);\n\t\t\tctx.moveTo(x - radius, y);\n\t\t\tctx.lineTo(x + radius, y);\n\t\t\txOffset = Math.cos(Math.PI / 4) * radius;\n\t\t\tyOffset = Math.sin(Math.PI / 4) * radius;\n\t\t\tctx.moveTo(x - xOffset, y - yOffset);\n\t\t\tctx.lineTo(x + xOffset, y + yOffset);\n\t\t\tctx.moveTo(x - xOffset, y + yOffset);\n\t\t\tctx.lineTo(x + xOffset, y - yOffset);\n\t\t\tctx.closePath();\n\t\t\tbreak;\n\t\tcase 'line':\n\t\t\tctx.beginPath();\n\t\t\tctx.moveTo(x - radius, y);\n\t\t\tctx.lineTo(x + radius, y);\n\t\t\tctx.closePath();\n\t\t\tbreak;\n\t\tcase 'dash':\n\t\t\tctx.beginPath();\n\t\t\tctx.moveTo(x, y);\n\t\t\tctx.lineTo(x + radius, y);\n\t\t\tctx.closePath();\n\t\t\tbreak;\n\t\t}\n\n\t\tctx.stroke();\n\t};\n\n\thelpers.clipArea = function(ctx, clipArea) {\n\t\tctx.save();\n\t\tctx.beginPath();\n\t\tctx.rect(clipArea.left, clipArea.top, clipArea.right - clipArea.left, clipArea.bottom - clipArea.top);\n\t\tctx.clip();\n\t};\n\n\thelpers.unclipArea = function(ctx) {\n\t\tctx.restore();\n\t};\n\n\thelpers.lineTo = function(ctx, previous, target, flip) {\n\t\tif (target.steppedLine) {\n\t\t\tif (target.steppedLine === 'after') {\n\t\t\t\tctx.lineTo(previous.x, target.y);\n\t\t\t} else {\n\t\t\t\tctx.lineTo(target.x, previous.y);\n\t\t\t}\n\t\t\tctx.lineTo(target.x, target.y);\n\t\t\treturn;\n\t\t}\n\n\t\tif (!target.tension) {\n\t\t\tctx.lineTo(target.x, target.y);\n\t\t\treturn;\n\t\t}\n\n\t\tctx.bezierCurveTo(\n\t\t\tflip? previous.controlPointPreviousX : previous.controlPointNextX,\n\t\t\tflip? previous.controlPointPreviousY : previous.controlPointNextY,\n\t\t\tflip? target.controlPointNextX : target.controlPointPreviousX,\n\t\t\tflip? target.controlPointNextY : target.controlPointPreviousY,\n\t\t\ttarget.x,\n\t\t\ttarget.y);\n\t};\n\n\tChart.helpers.canvas = helpers;\n};\n\n},{}],23:[function(require,module,exports){\n'use strict';\n\nmodule.exports = function(Chart) {\n\n\tvar helpers = Chart.helpers;\n\tvar plugins = Chart.plugins;\n\tvar platform = Chart.platform;\n\n\t// Create a dictionary of chart types, to allow for extension of existing types\n\tChart.types = {};\n\n\t// Store a reference to each instance - allowing us to globally resize chart instances on window resize.\n\t// Destroy method on the chart will remove the instance of the chart from this reference.\n\tChart.instances = {};\n\n\t// Controllers available for dataset visualization eg. bar, line, slice, etc.\n\tChart.controllers = {};\n\n\t/**\n\t * Initializes the given config with global and chart default values.\n\t */\n\tfunction initConfig(config) {\n\t\tconfig = config || {};\n\n\t\t// Do NOT use configMerge() for the data object because this method merges arrays\n\t\t// and so would change references to labels and datasets, preventing data updates.\n\t\tvar data = config.data = config.data || {};\n\t\tdata.datasets = data.datasets || [];\n\t\tdata.labels = data.labels || [];\n\n\t\tconfig.options = helpers.configMerge(\n\t\t\tChart.defaults.global,\n\t\t\tChart.defaults[config.type],\n\t\t\tconfig.options || {});\n\n\t\treturn config;\n\t}\n\n\t/**\n\t * Updates the config of the chart\n\t * @param chart {Chart} chart to update the options for\n\t */\n\tfunction updateConfig(chart) {\n\t\tvar newOptions = chart.options;\n\n\t\t// Update Scale(s) with options\n\t\tif (newOptions.scale) {\n\t\t\tchart.scale.options = newOptions.scale;\n\t\t} else if (newOptions.scales) {\n\t\t\tnewOptions.scales.xAxes.concat(newOptions.scales.yAxes).forEach(function(scaleOptions) {\n\t\t\t\tchart.scales[scaleOptions.id].options = scaleOptions;\n\t\t\t});\n\t\t}\n\n\t\t// Tooltip\n\t\tchart.tooltip._options = newOptions.tooltips;\n\t}\n\n\tfunction positionIsHorizontal(position) {\n\t\treturn position === 'top' || position === 'bottom';\n\t}\n\n\thelpers.extend(Chart.prototype, /** @lends Chart */ {\n\t\t/**\n\t\t * @private\n\t\t */\n\t\tconstruct: function(item, config) {\n\t\t\tvar me = this;\n\n\t\t\tconfig = initConfig(config);\n\n\t\t\tvar context = platform.acquireContext(item, config);\n\t\t\tvar canvas = context && context.canvas;\n\t\t\tvar height = canvas && canvas.height;\n\t\t\tvar width = canvas && canvas.width;\n\n\t\t\tme.id = helpers.uid();\n\t\t\tme.ctx = context;\n\t\t\tme.canvas = canvas;\n\t\t\tme.config = config;\n\t\t\tme.width = width;\n\t\t\tme.height = height;\n\t\t\tme.aspectRatio = height? width / height : null;\n\t\t\tme.options = config.options;\n\t\t\tme._bufferedRender = false;\n\n\t\t\t/**\n\t\t\t * Provided for backward compatibility, Chart and Chart.Controller have been merged,\n\t\t\t * the \"instance\" still need to be defined since it might be called from plugins.\n\t\t\t * @prop Chart#chart\n\t\t\t * @deprecated since version 2.6.0\n\t\t\t * @todo remove at version 3\n\t\t\t * @private\n\t\t\t */\n\t\t\tme.chart = me;\n\t\t\tme.controller = me;  // chart.chart.controller #inception\n\n\t\t\t// Add the chart instance to the global namespace\n\t\t\tChart.instances[me.id] = me;\n\n\t\t\t// Define alias to the config data: `chart.data === chart.config.data`\n\t\t\tObject.defineProperty(me, 'data', {\n\t\t\t\tget: function() {\n\t\t\t\t\treturn me.config.data;\n\t\t\t\t},\n\t\t\t\tset: function(value) {\n\t\t\t\t\tme.config.data = value;\n\t\t\t\t}\n\t\t\t});\n\n\t\t\tif (!context || !canvas) {\n\t\t\t\t// The given item is not a compatible context2d element, let's return before finalizing\n\t\t\t\t// the chart initialization but after setting basic chart / controller properties that\n\t\t\t\t// can help to figure out that the chart is not valid (e.g chart.canvas !== null);\n\t\t\t\t// https://github.com/chartjs/Chart.js/issues/2807\n\t\t\t\tconsole.error(\"Failed to create chart: can't acquire context from the given item\");\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tme.initialize();\n\t\t\tme.update();\n\t\t},\n\n\t\t/**\n\t\t * @private\n\t\t */\n\t\tinitialize: function() {\n\t\t\tvar me = this;\n\n\t\t\t// Before init plugin notification\n\t\t\tplugins.notify(me, 'beforeInit');\n\n\t\t\thelpers.retinaScale(me);\n\n\t\t\tme.bindEvents();\n\n\t\t\tif (me.options.responsive) {\n\t\t\t\t// Initial resize before chart draws (must be silent to preserve initial animations).\n\t\t\t\tme.resize(true);\n\t\t\t}\n\n\t\t\t// Make sure scales have IDs and are built before we build any controllers.\n\t\t\tme.ensureScalesHaveIDs();\n\t\t\tme.buildScales();\n\t\t\tme.initToolTip();\n\n\t\t\t// After init plugin notification\n\t\t\tplugins.notify(me, 'afterInit');\n\n\t\t\treturn me;\n\t\t},\n\n\t\tclear: function() {\n\t\t\thelpers.clear(this);\n\t\t\treturn this;\n\t\t},\n\n\t\tstop: function() {\n\t\t\t// Stops any current animation loop occurring\n\t\t\tChart.animationService.cancelAnimation(this);\n\t\t\treturn this;\n\t\t},\n\n\t\tresize: function(silent) {\n\t\t\tvar me = this;\n\t\t\tvar options = me.options;\n\t\t\tvar canvas = me.canvas;\n\t\t\tvar aspectRatio = (options.maintainAspectRatio && me.aspectRatio) || null;\n\n\t\t\t// the canvas render width and height will be casted to integers so make sure that\n\t\t\t// the canvas display style uses the same integer values to avoid blurring effect.\n\t\t\tvar newWidth = Math.floor(helpers.getMaximumWidth(canvas));\n\t\t\tvar newHeight = Math.floor(aspectRatio? newWidth / aspectRatio : helpers.getMaximumHeight(canvas));\n\n\t\t\tif (me.width === newWidth && me.height === newHeight) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tcanvas.width = me.width = newWidth;\n\t\t\tcanvas.height = me.height = newHeight;\n\t\t\tcanvas.style.width = newWidth + 'px';\n\t\t\tcanvas.style.height = newHeight + 'px';\n\n\t\t\thelpers.retinaScale(me);\n\n\t\t\tif (!silent) {\n\t\t\t\t// Notify any plugins about the resize\n\t\t\t\tvar newSize = {width: newWidth, height: newHeight};\n\t\t\t\tplugins.notify(me, 'resize', [newSize]);\n\n\t\t\t\t// Notify of resize\n\t\t\t\tif (me.options.onResize) {\n\t\t\t\t\tme.options.onResize(me, newSize);\n\t\t\t\t}\n\n\t\t\t\tme.stop();\n\t\t\t\tme.update(me.options.responsiveAnimationDuration);\n\t\t\t}\n\t\t},\n\n\t\tensureScalesHaveIDs: function() {\n\t\t\tvar options = this.options;\n\t\t\tvar scalesOptions = options.scales || {};\n\t\t\tvar scaleOptions = options.scale;\n\n\t\t\thelpers.each(scalesOptions.xAxes, function(xAxisOptions, index) {\n\t\t\t\txAxisOptions.id = xAxisOptions.id || ('x-axis-' + index);\n\t\t\t});\n\n\t\t\thelpers.each(scalesOptions.yAxes, function(yAxisOptions, index) {\n\t\t\t\tyAxisOptions.id = yAxisOptions.id || ('y-axis-' + index);\n\t\t\t});\n\n\t\t\tif (scaleOptions) {\n\t\t\t\tscaleOptions.id = scaleOptions.id || 'scale';\n\t\t\t}\n\t\t},\n\n\t\t/**\n\t\t * Builds a map of scale ID to scale object for future lookup.\n\t\t */\n\t\tbuildScales: function() {\n\t\t\tvar me = this;\n\t\t\tvar options = me.options;\n\t\t\tvar scales = me.scales = {};\n\t\t\tvar items = [];\n\n\t\t\tif (options.scales) {\n\t\t\t\titems = items.concat(\n\t\t\t\t\t(options.scales.xAxes || []).map(function(xAxisOptions) {\n\t\t\t\t\t\treturn {options: xAxisOptions, dtype: 'category', dposition: 'bottom'};\n\t\t\t\t\t}),\n\t\t\t\t\t(options.scales.yAxes || []).map(function(yAxisOptions) {\n\t\t\t\t\t\treturn {options: yAxisOptions, dtype: 'linear', dposition: 'left'};\n\t\t\t\t\t})\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tif (options.scale) {\n\t\t\t\titems.push({\n\t\t\t\t\toptions: options.scale,\n\t\t\t\t\tdtype: 'radialLinear',\n\t\t\t\t\tisDefault: true,\n\t\t\t\t\tdposition: 'chartArea'\n\t\t\t\t});\n\t\t\t}\n\n\t\t\thelpers.each(items, function(item) {\n\t\t\t\tvar scaleOptions = item.options;\n\t\t\t\tvar scaleType = helpers.getValueOrDefault(scaleOptions.type, item.dtype);\n\t\t\t\tvar scaleClass = Chart.scaleService.getScaleConstructor(scaleType);\n\t\t\t\tif (!scaleClass) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tif (positionIsHorizontal(scaleOptions.position) !== positionIsHorizontal(item.dposition)) {\n\t\t\t\t\tscaleOptions.position = item.dposition;\n\t\t\t\t}\n\n\t\t\t\tvar scale = new scaleClass({\n\t\t\t\t\tid: scaleOptions.id,\n\t\t\t\t\toptions: scaleOptions,\n\t\t\t\t\tctx: me.ctx,\n\t\t\t\t\tchart: me\n\t\t\t\t});\n\n\t\t\t\tscales[scale.id] = scale;\n\n\t\t\t\t// TODO(SB): I think we should be able to remove this custom case (options.scale)\n\t\t\t\t// and consider it as a regular scale part of the \"scales\"\" map only! This would\n\t\t\t\t// make the logic easier and remove some useless? custom code.\n\t\t\t\tif (item.isDefault) {\n\t\t\t\t\tme.scale = scale;\n\t\t\t\t}\n\t\t\t});\n\n\t\t\tChart.scaleService.addScalesToLayout(this);\n\t\t},\n\n\t\tbuildOrUpdateControllers: function() {\n\t\t\tvar me = this;\n\t\t\tvar types = [];\n\t\t\tvar newControllers = [];\n\n\t\t\thelpers.each(me.data.datasets, function(dataset, datasetIndex) {\n\t\t\t\tvar meta = me.getDatasetMeta(datasetIndex);\n\t\t\t\tif (!meta.type) {\n\t\t\t\t\tmeta.type = dataset.type || me.config.type;\n\t\t\t\t}\n\n\t\t\t\ttypes.push(meta.type);\n\n\t\t\t\tif (meta.controller) {\n\t\t\t\t\tmeta.controller.updateIndex(datasetIndex);\n\t\t\t\t} else {\n\t\t\t\t\tvar ControllerClass = Chart.controllers[meta.type];\n\t\t\t\t\tif (ControllerClass === undefined) {\n\t\t\t\t\t\tthrow new Error('\"' + meta.type + '\" is not a chart type.');\n\t\t\t\t\t}\n\n\t\t\t\t\tmeta.controller = new ControllerClass(me, datasetIndex);\n\t\t\t\t\tnewControllers.push(meta.controller);\n\t\t\t\t}\n\t\t\t}, me);\n\n\t\t\tif (types.length > 1) {\n\t\t\t\tfor (var i = 1; i < types.length; i++) {\n\t\t\t\t\tif (types[i] !== types[i - 1]) {\n\t\t\t\t\t\tme.isCombo = true;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn newControllers;\n\t\t},\n\n\t\t/**\n\t\t * Reset the elements of all datasets\n\t\t * @private\n\t\t */\n\t\tresetElements: function() {\n\t\t\tvar me = this;\n\t\t\thelpers.each(me.data.datasets, function(dataset, datasetIndex) {\n\t\t\t\tme.getDatasetMeta(datasetIndex).controller.reset();\n\t\t\t}, me);\n\t\t},\n\n\t\t/**\n\t\t* Resets the chart back to it's state before the initial animation\n\t\t*/\n\t\treset: function() {\n\t\t\tthis.resetElements();\n\t\t\tthis.tooltip.initialize();\n\t\t},\n\n\t\tupdate: function(animationDuration, lazy) {\n\t\t\tvar me = this;\n\n\t\t\tupdateConfig(me);\n\n\t\t\tif (plugins.notify(me, 'beforeUpdate') === false) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// In case the entire data object changed\n\t\t\tme.tooltip._data = me.data;\n\n\t\t\t// Make sure dataset controllers are updated and new controllers are reset\n\t\t\tvar newControllers = me.buildOrUpdateControllers();\n\n\t\t\t// Make sure all dataset controllers have correct meta data counts\n\t\t\thelpers.each(me.data.datasets, function(dataset, datasetIndex) {\n\t\t\t\tme.getDatasetMeta(datasetIndex).controller.buildOrUpdateElements();\n\t\t\t}, me);\n\n\t\t\tme.updateLayout();\n\n\t\t\t// Can only reset the new controllers after the scales have been updated\n\t\t\thelpers.each(newControllers, function(controller) {\n\t\t\t\tcontroller.reset();\n\t\t\t});\n\n\t\t\tme.updateDatasets();\n\n\t\t\t// Do this before render so that any plugins that need final scale updates can use it\n\t\t\tplugins.notify(me, 'afterUpdate');\n\n\t\t\tif (me._bufferedRender) {\n\t\t\t\tme._bufferedRequest = {\n\t\t\t\t\tlazy: lazy,\n\t\t\t\t\tduration: animationDuration\n\t\t\t\t};\n\t\t\t} else {\n\t\t\t\tme.render(animationDuration, lazy);\n\t\t\t}\n\t\t},\n\n\t\t/**\n\t\t * Updates the chart layout unless a plugin returns `false` to the `beforeLayout`\n\t\t * hook, in which case, plugins will not be called on `afterLayout`.\n\t\t * @private\n\t\t */\n\t\tupdateLayout: function() {\n\t\t\tvar me = this;\n\n\t\t\tif (plugins.notify(me, 'beforeLayout') === false) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tChart.layoutService.update(this, this.width, this.height);\n\n\t\t\t/**\n\t\t\t * Provided for backward compatibility, use `afterLayout` instead.\n\t\t\t * @method IPlugin#afterScaleUpdate\n\t\t\t * @deprecated since version 2.5.0\n\t\t\t * @todo remove at version 3\n\t\t\t * @private\n\t\t\t */\n\t\t\tplugins.notify(me, 'afterScaleUpdate');\n\t\t\tplugins.notify(me, 'afterLayout');\n\t\t},\n\n\t\t/**\n\t\t * Updates all datasets unless a plugin returns `false` to the `beforeDatasetsUpdate`\n\t\t * hook, in which case, plugins will not be called on `afterDatasetsUpdate`.\n\t\t * @private\n\t\t */\n\t\tupdateDatasets: function() {\n\t\t\tvar me = this;\n\n\t\t\tif (plugins.notify(me, 'beforeDatasetsUpdate') === false) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tfor (var i = 0, ilen = me.data.datasets.length; i < ilen; ++i) {\n\t\t\t\tme.updateDataset(i);\n\t\t\t}\n\n\t\t\tplugins.notify(me, 'afterDatasetsUpdate');\n\t\t},\n\n\t\t/**\n\t\t * Updates dataset at index unless a plugin returns `false` to the `beforeDatasetUpdate`\n\t\t * hook, in which case, plugins will not be called on `afterDatasetUpdate`.\n\t\t * @private\n\t\t */\n\t\tupdateDataset: function(index) {\n\t\t\tvar me = this;\n\t\t\tvar meta = me.getDatasetMeta(index);\n\t\t\tvar args = {\n\t\t\t\tmeta: meta,\n\t\t\t\tindex: index\n\t\t\t};\n\n\t\t\tif (plugins.notify(me, 'beforeDatasetUpdate', [args]) === false) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tmeta.controller.update();\n\n\t\t\tplugins.notify(me, 'afterDatasetUpdate', [args]);\n\t\t},\n\n\t\trender: function(duration, lazy) {\n\t\t\tvar me = this;\n\n\t\t\tif (plugins.notify(me, 'beforeRender') === false) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tvar animationOptions = me.options.animation;\n\t\t\tvar onComplete = function(animation) {\n\t\t\t\tplugins.notify(me, 'afterRender');\n\t\t\t\thelpers.callback(animationOptions && animationOptions.onComplete, [animation], me);\n\t\t\t};\n\n\t\t\tif (animationOptions && ((typeof duration !== 'undefined' && duration !== 0) || (typeof duration === 'undefined' && animationOptions.duration !== 0))) {\n\t\t\t\tvar animation = new Chart.Animation({\n\t\t\t\t\tnumSteps: (duration || animationOptions.duration) / 16.66, // 60 fps\n\t\t\t\t\teasing: animationOptions.easing,\n\n\t\t\t\t\trender: function(chart, animationObject) {\n\t\t\t\t\t\tvar easingFunction = helpers.easingEffects[animationObject.easing];\n\t\t\t\t\t\tvar currentStep = animationObject.currentStep;\n\t\t\t\t\t\tvar stepDecimal = currentStep / animationObject.numSteps;\n\n\t\t\t\t\t\tchart.draw(easingFunction(stepDecimal), stepDecimal, currentStep);\n\t\t\t\t\t},\n\n\t\t\t\t\tonAnimationProgress: animationOptions.onProgress,\n\t\t\t\t\tonAnimationComplete: onComplete\n\t\t\t\t});\n\n\t\t\t\tChart.animationService.addAnimation(me, animation, duration, lazy);\n\t\t\t} else {\n\t\t\t\tme.draw();\n\n\t\t\t\t// See https://github.com/chartjs/Chart.js/issues/3781\n\t\t\t\tonComplete(new Chart.Animation({numSteps: 0, chart: me}));\n\t\t\t}\n\n\t\t\treturn me;\n\t\t},\n\n\t\tdraw: function(easingValue) {\n\t\t\tvar me = this;\n\n\t\t\tme.clear();\n\n\t\t\tif (easingValue === undefined || easingValue === null) {\n\t\t\t\teasingValue = 1;\n\t\t\t}\n\n\t\t\tme.transition(easingValue);\n\n\t\t\tif (plugins.notify(me, 'beforeDraw', [easingValue]) === false) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// Draw all the scales\n\t\t\thelpers.each(me.boxes, function(box) {\n\t\t\t\tbox.draw(me.chartArea);\n\t\t\t}, me);\n\n\t\t\tif (me.scale) {\n\t\t\t\tme.scale.draw();\n\t\t\t}\n\n\t\t\tme.drawDatasets(easingValue);\n\n\t\t\t// Finally draw the tooltip\n\t\t\tme.tooltip.draw();\n\n\t\t\tplugins.notify(me, 'afterDraw', [easingValue]);\n\t\t},\n\n\t\t/**\n\t\t * @private\n\t\t */\n\t\ttransition: function(easingValue) {\n\t\t\tvar me = this;\n\n\t\t\tfor (var i=0, ilen=(me.data.datasets || []).length; i<ilen; ++i) {\n\t\t\t\tif (me.isDatasetVisible(i)) {\n\t\t\t\t\tme.getDatasetMeta(i).controller.transition(easingValue);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tme.tooltip.transition(easingValue);\n\t\t},\n\n\t\t/**\n\t\t * Draws all datasets unless a plugin returns `false` to the `beforeDatasetsDraw`\n\t\t * hook, in which case, plugins will not be called on `afterDatasetsDraw`.\n\t\t * @private\n\t\t */\n\t\tdrawDatasets: function(easingValue) {\n\t\t\tvar me = this;\n\n\t\t\tif (plugins.notify(me, 'beforeDatasetsDraw', [easingValue]) === false) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// Draw datasets reversed to support proper line stacking\n\t\t\tfor (var i=(me.data.datasets || []).length - 1; i >= 0; --i) {\n\t\t\t\tif (me.isDatasetVisible(i)) {\n\t\t\t\t\tme.drawDataset(i, easingValue);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tplugins.notify(me, 'afterDatasetsDraw', [easingValue]);\n\t\t},\n\n\t\t/**\n\t\t * Draws dataset at index unless a plugin returns `false` to the `beforeDatasetDraw`\n\t\t * hook, in which case, plugins will not be called on `afterDatasetDraw`.\n\t\t * @private\n\t\t */\n\t\tdrawDataset: function(index, easingValue) {\n\t\t\tvar me = this;\n\t\t\tvar meta = me.getDatasetMeta(index);\n\t\t\tvar args = {\n\t\t\t\tmeta: meta,\n\t\t\t\tindex: index,\n\t\t\t\teasingValue: easingValue\n\t\t\t};\n\n\t\t\tif (plugins.notify(me, 'beforeDatasetDraw', [args]) === false) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tmeta.controller.draw(easingValue);\n\n\t\t\tplugins.notify(me, 'afterDatasetDraw', [args]);\n\t\t},\n\n\t\t// Get the single element that was clicked on\n\t\t// @return : An object containing the dataset index and element index of the matching element. Also contains the rectangle that was draw\n\t\tgetElementAtEvent: function(e) {\n\t\t\treturn Chart.Interaction.modes.single(this, e);\n\t\t},\n\n\t\tgetElementsAtEvent: function(e) {\n\t\t\treturn Chart.Interaction.modes.label(this, e, {intersect: true});\n\t\t},\n\n\t\tgetElementsAtXAxis: function(e) {\n\t\t\treturn Chart.Interaction.modes['x-axis'](this, e, {intersect: true});\n\t\t},\n\n\t\tgetElementsAtEventForMode: function(e, mode, options) {\n\t\t\tvar method = Chart.Interaction.modes[mode];\n\t\t\tif (typeof method === 'function') {\n\t\t\t\treturn method(this, e, options);\n\t\t\t}\n\n\t\t\treturn [];\n\t\t},\n\n\t\tgetDatasetAtEvent: function(e) {\n\t\t\treturn Chart.Interaction.modes.dataset(this, e, {intersect: true});\n\t\t},\n\n\t\tgetDatasetMeta: function(datasetIndex) {\n\t\t\tvar me = this;\n\t\t\tvar dataset = me.data.datasets[datasetIndex];\n\t\t\tif (!dataset._meta) {\n\t\t\t\tdataset._meta = {};\n\t\t\t}\n\n\t\t\tvar meta = dataset._meta[me.id];\n\t\t\tif (!meta) {\n\t\t\t\tmeta = dataset._meta[me.id] = {\n\t\t\t\t\ttype: null,\n\t\t\t\t\tdata: [],\n\t\t\t\t\tdataset: null,\n\t\t\t\t\tcontroller: null,\n\t\t\t\t\thidden: null,\t\t\t// See isDatasetVisible() comment\n\t\t\t\t\txAxisID: null,\n\t\t\t\t\tyAxisID: null\n\t\t\t\t};\n\t\t\t}\n\n\t\t\treturn meta;\n\t\t},\n\n\t\tgetVisibleDatasetCount: function() {\n\t\t\tvar count = 0;\n\t\t\tfor (var i = 0, ilen = this.data.datasets.length; i<ilen; ++i) {\n\t\t\t\tif (this.isDatasetVisible(i)) {\n\t\t\t\t\tcount++;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn count;\n\t\t},\n\n\t\tisDatasetVisible: function(datasetIndex) {\n\t\t\tvar meta = this.getDatasetMeta(datasetIndex);\n\n\t\t\t// meta.hidden is a per chart dataset hidden flag override with 3 states: if true or false,\n\t\t\t// the dataset.hidden value is ignored, else if null, the dataset hidden state is returned.\n\t\t\treturn typeof meta.hidden === 'boolean'? !meta.hidden : !this.data.datasets[datasetIndex].hidden;\n\t\t},\n\n\t\tgenerateLegend: function() {\n\t\t\treturn this.options.legendCallback(this);\n\t\t},\n\n\t\tdestroy: function() {\n\t\t\tvar me = this;\n\t\t\tvar canvas = me.canvas;\n\t\t\tvar meta, i, ilen;\n\n\t\t\tme.stop();\n\n\t\t\t// dataset controllers need to cleanup associated data\n\t\t\tfor (i = 0, ilen = me.data.datasets.length; i < ilen; ++i) {\n\t\t\t\tmeta = me.getDatasetMeta(i);\n\t\t\t\tif (meta.controller) {\n\t\t\t\t\tmeta.controller.destroy();\n\t\t\t\t\tmeta.controller = null;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (canvas) {\n\t\t\t\tme.unbindEvents();\n\t\t\t\thelpers.clear(me);\n\t\t\t\tplatform.releaseContext(me.ctx);\n\t\t\t\tme.canvas = null;\n\t\t\t\tme.ctx = null;\n\t\t\t}\n\n\t\t\tplugins.notify(me, 'destroy');\n\n\t\t\tdelete Chart.instances[me.id];\n\t\t},\n\n\t\ttoBase64Image: function() {\n\t\t\treturn this.canvas.toDataURL.apply(this.canvas, arguments);\n\t\t},\n\n\t\tinitToolTip: function() {\n\t\t\tvar me = this;\n\t\t\tme.tooltip = new Chart.Tooltip({\n\t\t\t\t_chart: me,\n\t\t\t\t_chartInstance: me,            // deprecated, backward compatibility\n\t\t\t\t_data: me.data,\n\t\t\t\t_options: me.options.tooltips\n\t\t\t}, me);\n\t\t\tme.tooltip.initialize();\n\t\t},\n\n\t\t/**\n\t\t * @private\n\t\t */\n\t\tbindEvents: function() {\n\t\t\tvar me = this;\n\t\t\tvar listeners = me._listeners = {};\n\t\t\tvar listener = function() {\n\t\t\t\tme.eventHandler.apply(me, arguments);\n\t\t\t};\n\n\t\t\thelpers.each(me.options.events, function(type) {\n\t\t\t\tplatform.addEventListener(me, type, listener);\n\t\t\t\tlisteners[type] = listener;\n\t\t\t});\n\n\t\t\t// Responsiveness is currently based on the use of an iframe, however this method causes\n\t\t\t// performance issues and could be troublesome when used with ad blockers. So make sure\n\t\t\t// that the user is still able to create a chart without iframe when responsive is false.\n\t\t\t// See https://github.com/chartjs/Chart.js/issues/2210\n\t\t\tif (me.options.responsive) {\n\t\t\t\tlistener = function() {\n\t\t\t\t\tme.resize();\n\t\t\t\t};\n\n\t\t\t\tplatform.addEventListener(me, 'resize', listener);\n\t\t\t\tlisteners.resize = listener;\n\t\t\t}\n\t\t},\n\n\t\t/**\n\t\t * @private\n\t\t */\n\t\tunbindEvents: function() {\n\t\t\tvar me = this;\n\t\t\tvar listeners = me._listeners;\n\t\t\tif (!listeners) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tdelete me._listeners;\n\t\t\thelpers.each(listeners, function(listener, type) {\n\t\t\t\tplatform.removeEventListener(me, type, listener);\n\t\t\t});\n\t\t},\n\n\t\tupdateHoverStyle: function(elements, mode, enabled) {\n\t\t\tvar method = enabled? 'setHoverStyle' : 'removeHoverStyle';\n\t\t\tvar element, i, ilen;\n\n\t\t\tfor (i=0, ilen=elements.length; i<ilen; ++i) {\n\t\t\t\telement = elements[i];\n\t\t\t\tif (element) {\n\t\t\t\t\tthis.getDatasetMeta(element._datasetIndex).controller[method](element);\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\n\t\t/**\n\t\t * @private\n\t\t */\n\t\teventHandler: function(e) {\n\t\t\tvar me = this;\n\t\t\tvar tooltip = me.tooltip;\n\n\t\t\tif (plugins.notify(me, 'beforeEvent', [e]) === false) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// Buffer any update calls so that renders do not occur\n\t\t\tme._bufferedRender = true;\n\t\t\tme._bufferedRequest = null;\n\n\t\t\tvar changed = me.handleEvent(e);\n\t\t\tchanged |= tooltip && tooltip.handleEvent(e);\n\n\t\t\tplugins.notify(me, 'afterEvent', [e]);\n\n\t\t\tvar bufferedRequest = me._bufferedRequest;\n\t\t\tif (bufferedRequest) {\n\t\t\t\t// If we have an update that was triggered, we need to do a normal render\n\t\t\t\tme.render(bufferedRequest.duration, bufferedRequest.lazy);\n\t\t\t} else if (changed && !me.animating) {\n\t\t\t\t// If entering, leaving, or changing elements, animate the change via pivot\n\t\t\t\tme.stop();\n\n\t\t\t\t// We only need to render at this point. Updating will cause scales to be\n\t\t\t\t// recomputed generating flicker & using more memory than necessary.\n\t\t\t\tme.render(me.options.hover.animationDuration, true);\n\t\t\t}\n\n\t\t\tme._bufferedRender = false;\n\t\t\tme._bufferedRequest = null;\n\n\t\t\treturn me;\n\t\t},\n\n\t\t/**\n\t\t * Handle an event\n\t\t * @private\n\t\t * @param {IEvent} event the event to handle\n\t\t * @return {Boolean} true if the chart needs to re-render\n\t\t */\n\t\thandleEvent: function(e) {\n\t\t\tvar me = this;\n\t\t\tvar options = me.options || {};\n\t\t\tvar hoverOptions = options.hover;\n\t\t\tvar changed = false;\n\n\t\t\tme.lastActive = me.lastActive || [];\n\n\t\t\t// Find Active Elements for hover and tooltips\n\t\t\tif (e.type === 'mouseout') {\n\t\t\t\tme.active = [];\n\t\t\t} else {\n\t\t\t\tme.active = me.getElementsAtEventForMode(e, hoverOptions.mode, hoverOptions);\n\t\t\t}\n\n\t\t\t// On Hover hook\n\t\t\tif (hoverOptions.onHover) {\n\t\t\t\t// Need to call with native event here to not break backwards compatibility\n\t\t\t\thoverOptions.onHover.call(me, e.native, me.active);\n\t\t\t}\n\n\t\t\tif (e.type === 'mouseup' || e.type === 'click') {\n\t\t\t\tif (options.onClick) {\n\t\t\t\t\t// Use e.native here for backwards compatibility\n\t\t\t\t\toptions.onClick.call(me, e.native, me.active);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Remove styling for last active (even if it may still be active)\n\t\t\tif (me.lastActive.length) {\n\t\t\t\tme.updateHoverStyle(me.lastActive, hoverOptions.mode, false);\n\t\t\t}\n\n\t\t\t// Built in hover styling\n\t\t\tif (me.active.length && hoverOptions.mode) {\n\t\t\t\tme.updateHoverStyle(me.active, hoverOptions.mode, true);\n\t\t\t}\n\n\t\t\tchanged = !helpers.arrayEquals(me.active, me.lastActive);\n\n\t\t\t// Remember Last Actives\n\t\t\tme.lastActive = me.active;\n\n\t\t\treturn changed;\n\t\t}\n\t});\n\n\t/**\n\t * Provided for backward compatibility, use Chart instead.\n\t * @class Chart.Controller\n\t * @deprecated since version 2.6.0\n\t * @todo remove at version 3\n\t * @private\n\t */\n\tChart.Controller = Chart;\n};\n\n},{}],24:[function(require,module,exports){\n'use strict';\n\nmodule.exports = function(Chart) {\n\n\tvar helpers = Chart.helpers;\n\n\tvar arrayEvents = ['push', 'pop', 'shift', 'splice', 'unshift'];\n\n\t/**\n\t * Hooks the array methods that add or remove values ('push', pop', 'shift', 'splice',\n\t * 'unshift') and notify the listener AFTER the array has been altered. Listeners are\n\t * called on the 'onData*' callbacks (e.g. onDataPush, etc.) with same arguments.\n\t */\n\tfunction listenArrayEvents(array, listener) {\n\t\tif (array._chartjs) {\n\t\t\tarray._chartjs.listeners.push(listener);\n\t\t\treturn;\n\t\t}\n\n\t\tObject.defineProperty(array, '_chartjs', {\n\t\t\tconfigurable: true,\n\t\t\tenumerable: false,\n\t\t\tvalue: {\n\t\t\t\tlisteners: [listener]\n\t\t\t}\n\t\t});\n\n\t\tarrayEvents.forEach(function(key) {\n\t\t\tvar method = 'onData' + key.charAt(0).toUpperCase() + key.slice(1);\n\t\t\tvar base = array[key];\n\n\t\t\tObject.defineProperty(array, key, {\n\t\t\t\tconfigurable: true,\n\t\t\t\tenumerable: false,\n\t\t\t\tvalue: function() {\n\t\t\t\t\tvar args = Array.prototype.slice.call(arguments);\n\t\t\t\t\tvar res = base.apply(this, args);\n\n\t\t\t\t\thelpers.each(array._chartjs.listeners, function(object) {\n\t\t\t\t\t\tif (typeof object[method] === 'function') {\n\t\t\t\t\t\t\tobject[method].apply(object, args);\n\t\t\t\t\t\t}\n\t\t\t\t\t});\n\n\t\t\t\t\treturn res;\n\t\t\t\t}\n\t\t\t});\n\t\t});\n\t}\n\n\t/**\n\t * Removes the given array event listener and cleanup extra attached properties (such as\n\t * the _chartjs stub and overridden methods) if array doesn't have any more listeners.\n\t */\n\tfunction unlistenArrayEvents(array, listener) {\n\t\tvar stub = array._chartjs;\n\t\tif (!stub) {\n\t\t\treturn;\n\t\t}\n\n\t\tvar listeners = stub.listeners;\n\t\tvar index = listeners.indexOf(listener);\n\t\tif (index !== -1) {\n\t\t\tlisteners.splice(index, 1);\n\t\t}\n\n\t\tif (listeners.length > 0) {\n\t\t\treturn;\n\t\t}\n\n\t\tarrayEvents.forEach(function(key) {\n\t\t\tdelete array[key];\n\t\t});\n\n\t\tdelete array._chartjs;\n\t}\n\n\t// Base class for all dataset controllers (line, bar, etc)\n\tChart.DatasetController = function(chart, datasetIndex) {\n\t\tthis.initialize(chart, datasetIndex);\n\t};\n\n\thelpers.extend(Chart.DatasetController.prototype, {\n\n\t\t/**\n\t\t * Element type used to generate a meta dataset (e.g. Chart.element.Line).\n\t\t * @type {Chart.core.element}\n\t\t */\n\t\tdatasetElementType: null,\n\n\t\t/**\n\t\t * Element type used to generate a meta data (e.g. Chart.element.Point).\n\t\t * @type {Chart.core.element}\n\t\t */\n\t\tdataElementType: null,\n\n\t\tinitialize: function(chart, datasetIndex) {\n\t\t\tvar me = this;\n\t\t\tme.chart = chart;\n\t\t\tme.index = datasetIndex;\n\t\t\tme.linkScales();\n\t\t\tme.addElements();\n\t\t},\n\n\t\tupdateIndex: function(datasetIndex) {\n\t\t\tthis.index = datasetIndex;\n\t\t},\n\n\t\tlinkScales: function() {\n\t\t\tvar me = this;\n\t\t\tvar meta = me.getMeta();\n\t\t\tvar dataset = me.getDataset();\n\n\t\t\tif (meta.xAxisID === null) {\n\t\t\t\tmeta.xAxisID = dataset.xAxisID || me.chart.options.scales.xAxes[0].id;\n\t\t\t}\n\t\t\tif (meta.yAxisID === null) {\n\t\t\t\tmeta.yAxisID = dataset.yAxisID || me.chart.options.scales.yAxes[0].id;\n\t\t\t}\n\t\t},\n\n\t\tgetDataset: function() {\n\t\t\treturn this.chart.data.datasets[this.index];\n\t\t},\n\n\t\tgetMeta: function() {\n\t\t\treturn this.chart.getDatasetMeta(this.index);\n\t\t},\n\n\t\tgetScaleForId: function(scaleID) {\n\t\t\treturn this.chart.scales[scaleID];\n\t\t},\n\n\t\treset: function() {\n\t\t\tthis.update(true);\n\t\t},\n\n\t\t/**\n\t\t * @private\n\t\t */\n\t\tdestroy: function() {\n\t\t\tif (this._data) {\n\t\t\t\tunlistenArrayEvents(this._data, this);\n\t\t\t}\n\t\t},\n\n\t\tcreateMetaDataset: function() {\n\t\t\tvar me = this;\n\t\t\tvar type = me.datasetElementType;\n\t\t\treturn type && new type({\n\t\t\t\t_chart: me.chart,\n\t\t\t\t_datasetIndex: me.index\n\t\t\t});\n\t\t},\n\n\t\tcreateMetaData: function(index) {\n\t\t\tvar me = this;\n\t\t\tvar type = me.dataElementType;\n\t\t\treturn type && new type({\n\t\t\t\t_chart: me.chart,\n\t\t\t\t_datasetIndex: me.index,\n\t\t\t\t_index: index\n\t\t\t});\n\t\t},\n\n\t\taddElements: function() {\n\t\t\tvar me = this;\n\t\t\tvar meta = me.getMeta();\n\t\t\tvar data = me.getDataset().data || [];\n\t\t\tvar metaData = meta.data;\n\t\t\tvar i, ilen;\n\n\t\t\tfor (i=0, ilen=data.length; i<ilen; ++i) {\n\t\t\t\tmetaData[i] = metaData[i] || me.createMetaData(i);\n\t\t\t}\n\n\t\t\tmeta.dataset = meta.dataset || me.createMetaDataset();\n\t\t},\n\n\t\taddElementAndReset: function(index) {\n\t\t\tvar element = this.createMetaData(index);\n\t\t\tthis.getMeta().data.splice(index, 0, element);\n\t\t\tthis.updateElement(element, index, true);\n\t\t},\n\n\t\tbuildOrUpdateElements: function() {\n\t\t\tvar me = this;\n\t\t\tvar dataset = me.getDataset();\n\t\t\tvar data = dataset.data || (dataset.data = []);\n\n\t\t\t// In order to correctly handle data addition/deletion animation (an thus simulate\n\t\t\t// real-time charts), we need to monitor these data modifications and synchronize\n\t\t\t// the internal meta data accordingly.\n\t\t\tif (me._data !== data) {\n\t\t\t\tif (me._data) {\n\t\t\t\t\t// This case happens when the user replaced the data array instance.\n\t\t\t\t\tunlistenArrayEvents(me._data, me);\n\t\t\t\t}\n\n\t\t\t\tlistenArrayEvents(data, me);\n\t\t\t\tme._data = data;\n\t\t\t}\n\n\t\t\t// Re-sync meta data in case the user replaced the data array or if we missed\n\t\t\t// any updates and so make sure that we handle number of datapoints changing.\n\t\t\tme.resyncElements();\n\t\t},\n\n\t\tupdate: helpers.noop,\n\n\t\ttransition: function(easingValue) {\n\t\t\tvar meta = this.getMeta();\n\t\t\tvar elements = meta.data || [];\n\t\t\tvar ilen = elements.length;\n\t\t\tvar i = 0;\n\n\t\t\tfor (; i<ilen; ++i) {\n\t\t\t\telements[i].transition(easingValue);\n\t\t\t}\n\n\t\t\tif (meta.dataset) {\n\t\t\t\tmeta.dataset.transition(easingValue);\n\t\t\t}\n\t\t},\n\n\t\tdraw: function() {\n\t\t\tvar meta = this.getMeta();\n\t\t\tvar elements = meta.data || [];\n\t\t\tvar ilen = elements.length;\n\t\t\tvar i = 0;\n\n\t\t\tif (meta.dataset) {\n\t\t\t\tmeta.dataset.draw();\n\t\t\t}\n\n\t\t\tfor (; i<ilen; ++i) {\n\t\t\t\telements[i].draw();\n\t\t\t}\n\t\t},\n\n\t\tremoveHoverStyle: function(element, elementOpts) {\n\t\t\tvar dataset = this.chart.data.datasets[element._datasetIndex],\n\t\t\t\tindex = element._index,\n\t\t\t\tcustom = element.custom || {},\n\t\t\t\tvalueOrDefault = helpers.getValueAtIndexOrDefault,\n\t\t\t\tmodel = element._model;\n\n\t\t\tmodel.backgroundColor = custom.backgroundColor ? custom.backgroundColor : valueOrDefault(dataset.backgroundColor, index, elementOpts.backgroundColor);\n\t\t\tmodel.borderColor = custom.borderColor ? custom.borderColor : valueOrDefault(dataset.borderColor, index, elementOpts.borderColor);\n\t\t\tmodel.borderWidth = custom.borderWidth ? custom.borderWidth : valueOrDefault(dataset.borderWidth, index, elementOpts.borderWidth);\n\t\t},\n\n\t\tsetHoverStyle: function(element) {\n\t\t\tvar dataset = this.chart.data.datasets[element._datasetIndex],\n\t\t\t\tindex = element._index,\n\t\t\t\tcustom = element.custom || {},\n\t\t\t\tvalueOrDefault = helpers.getValueAtIndexOrDefault,\n\t\t\t\tgetHoverColor = helpers.getHoverColor,\n\t\t\t\tmodel = element._model;\n\n\t\t\tmodel.backgroundColor = custom.hoverBackgroundColor ? custom.hoverBackgroundColor : valueOrDefault(dataset.hoverBackgroundColor, index, getHoverColor(model.backgroundColor));\n\t\t\tmodel.borderColor = custom.hoverBorderColor ? custom.hoverBorderColor : valueOrDefault(dataset.hoverBorderColor, index, getHoverColor(model.borderColor));\n\t\t\tmodel.borderWidth = custom.hoverBorderWidth ? custom.hoverBorderWidth : valueOrDefault(dataset.hoverBorderWidth, index, model.borderWidth);\n\t\t},\n\n\t\t/**\n\t\t * @private\n\t\t */\n\t\tresyncElements: function() {\n\t\t\tvar me = this;\n\t\t\tvar meta = me.getMeta();\n\t\t\tvar data = me.getDataset().data;\n\t\t\tvar numMeta = meta.data.length;\n\t\t\tvar numData = data.length;\n\n\t\t\tif (numData < numMeta) {\n\t\t\t\tmeta.data.splice(numData, numMeta - numData);\n\t\t\t} else if (numData > numMeta) {\n\t\t\t\tme.insertElements(numMeta, numData - numMeta);\n\t\t\t}\n\t\t},\n\n\t\t/**\n\t\t * @private\n\t\t */\n\t\tinsertElements: function(start, count) {\n\t\t\tfor (var i=0; i<count; ++i) {\n\t\t\t\tthis.addElementAndReset(start + i);\n\t\t\t}\n\t\t},\n\n\t\t/**\n\t\t * @private\n\t\t */\n\t\tonDataPush: function() {\n\t\t\tthis.insertElements(this.getDataset().data.length-1, arguments.length);\n\t\t},\n\n\t\t/**\n\t\t * @private\n\t\t */\n\t\tonDataPop: function() {\n\t\t\tthis.getMeta().data.pop();\n\t\t},\n\n\t\t/**\n\t\t * @private\n\t\t */\n\t\tonDataShift: function() {\n\t\t\tthis.getMeta().data.shift();\n\t\t},\n\n\t\t/**\n\t\t * @private\n\t\t */\n\t\tonDataSplice: function(start, count) {\n\t\t\tthis.getMeta().data.splice(start, count);\n\t\t\tthis.insertElements(start, arguments.length - 2);\n\t\t},\n\n\t\t/**\n\t\t * @private\n\t\t */\n\t\tonDataUnshift: function() {\n\t\t\tthis.insertElements(0, arguments.length);\n\t\t}\n\t});\n\n\tChart.DatasetController.extend = helpers.inherits;\n};\n\n},{}],25:[function(require,module,exports){\n'use strict';\n\nvar color = require(3);\n\nmodule.exports = function(Chart) {\n\n\tvar helpers = Chart.helpers;\n\n\tfunction interpolate(start, view, model, ease) {\n\t\tvar keys = Object.keys(model);\n\t\tvar i, ilen, key, actual, origin, target, type, c0, c1;\n\n\t\tfor (i=0, ilen=keys.length; i<ilen; ++i) {\n\t\t\tkey = keys[i];\n\n\t\t\ttarget = model[key];\n\n\t\t\t// if a value is added to the model after pivot() has been called, the view\n\t\t\t// doesn't contain it, so let's initialize the view to the target value.\n\t\t\tif (!view.hasOwnProperty(key)) {\n\t\t\t\tview[key] = target;\n\t\t\t}\n\n\t\t\tactual = view[key];\n\n\t\t\tif (actual === target || key[0] === '_') {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tif (!start.hasOwnProperty(key)) {\n\t\t\t\tstart[key] = actual;\n\t\t\t}\n\n\t\t\torigin = start[key];\n\n\t\t\ttype = typeof(target);\n\n\t\t\tif (type === typeof(origin)) {\n\t\t\t\tif (type === 'string') {\n\t\t\t\t\tc0 = color(origin);\n\t\t\t\t\tif (c0.valid) {\n\t\t\t\t\t\tc1 = color(target);\n\t\t\t\t\t\tif (c1.valid) {\n\t\t\t\t\t\t\tview[key] = c1.mix(c0, ease).rgbString();\n\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t} else if (type === 'number' && isFinite(origin) && isFinite(target)) {\n\t\t\t\t\tview[key] = origin + (target - origin) * ease;\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tview[key] = target;\n\t\t}\n\t}\n\n\tChart.elements = {};\n\n\tChart.Element = function(configuration) {\n\t\thelpers.extend(this, configuration);\n\t\tthis.initialize.apply(this, arguments);\n\t};\n\n\thelpers.extend(Chart.Element.prototype, {\n\n\t\tinitialize: function() {\n\t\t\tthis.hidden = false;\n\t\t},\n\n\t\tpivot: function() {\n\t\t\tvar me = this;\n\t\t\tif (!me._view) {\n\t\t\t\tme._view = helpers.clone(me._model);\n\t\t\t}\n\t\t\tme._start = {};\n\t\t\treturn me;\n\t\t},\n\n\t\ttransition: function(ease) {\n\t\t\tvar me = this;\n\t\t\tvar model = me._model;\n\t\t\tvar start = me._start;\n\t\t\tvar view = me._view;\n\n\t\t\t// No animation -> No Transition\n\t\t\tif (!model || ease === 1) {\n\t\t\t\tme._view = model;\n\t\t\t\tme._start = null;\n\t\t\t\treturn me;\n\t\t\t}\n\n\t\t\tif (!view) {\n\t\t\t\tview = me._view = {};\n\t\t\t}\n\n\t\t\tif (!start) {\n\t\t\t\tstart = me._start = {};\n\t\t\t}\n\n\t\t\tinterpolate(start, view, model, ease);\n\n\t\t\treturn me;\n\t\t},\n\n\t\ttooltipPosition: function() {\n\t\t\treturn {\n\t\t\t\tx: this._model.x,\n\t\t\t\ty: this._model.y\n\t\t\t};\n\t\t},\n\n\t\thasValue: function() {\n\t\t\treturn helpers.isNumber(this._model.x) && helpers.isNumber(this._model.y);\n\t\t}\n\t});\n\n\tChart.Element.extend = helpers.inherits;\n};\n\n},{\"3\":3}],26:[function(require,module,exports){\n/* global window: false */\n/* global document: false */\n'use strict';\n\nvar color = require(3);\n\nmodule.exports = function(Chart) {\n\t// Global Chart helpers object for utility methods and classes\n\tvar helpers = Chart.helpers = {};\n\n\t// -- Basic js utility methods\n\thelpers.each = function(loopable, callback, self, reverse) {\n\t\t// Check to see if null or undefined firstly.\n\t\tvar i, len;\n\t\tif (helpers.isArray(loopable)) {\n\t\t\tlen = loopable.length;\n\t\t\tif (reverse) {\n\t\t\t\tfor (i = len - 1; i >= 0; i--) {\n\t\t\t\t\tcallback.call(self, loopable[i], i);\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tfor (i = 0; i < len; i++) {\n\t\t\t\t\tcallback.call(self, loopable[i], i);\n\t\t\t\t}\n\t\t\t}\n\t\t} else if (typeof loopable === 'object') {\n\t\t\tvar keys = Object.keys(loopable);\n\t\t\tlen = keys.length;\n\t\t\tfor (i = 0; i < len; i++) {\n\t\t\t\tcallback.call(self, loopable[keys[i]], keys[i]);\n\t\t\t}\n\t\t}\n\t};\n\thelpers.clone = function(obj) {\n\t\tvar objClone = {};\n\t\thelpers.each(obj, function(value, key) {\n\t\t\tif (helpers.isArray(value)) {\n\t\t\t\tobjClone[key] = value.slice(0);\n\t\t\t} else if (typeof value === 'object' && value !== null) {\n\t\t\t\tobjClone[key] = helpers.clone(value);\n\t\t\t} else {\n\t\t\t\tobjClone[key] = value;\n\t\t\t}\n\t\t});\n\t\treturn objClone;\n\t};\n\thelpers.extend = function(base) {\n\t\tvar setFn = function(value, key) {\n\t\t\tbase[key] = value;\n\t\t};\n\t\tfor (var i = 1, ilen = arguments.length; i < ilen; i++) {\n\t\t\thelpers.each(arguments[i], setFn);\n\t\t}\n\t\treturn base;\n\t};\n\t// Need a special merge function to chart configs since they are now grouped\n\thelpers.configMerge = function(_base) {\n\t\tvar base = helpers.clone(_base);\n\t\thelpers.each(Array.prototype.slice.call(arguments, 1), function(extension) {\n\t\t\thelpers.each(extension, function(value, key) {\n\t\t\t\tvar baseHasProperty = base.hasOwnProperty(key);\n\t\t\t\tvar baseVal = baseHasProperty ? base[key] : {};\n\n\t\t\t\tif (key === 'scales') {\n\t\t\t\t\t// Scale config merging is complex. Add our own function here for that\n\t\t\t\t\tbase[key] = helpers.scaleMerge(baseVal, value);\n\t\t\t\t} else if (key === 'scale') {\n\t\t\t\t\t// Used in polar area & radar charts since there is only one scale\n\t\t\t\t\tbase[key] = helpers.configMerge(baseVal, Chart.scaleService.getScaleDefaults(value.type), value);\n\t\t\t\t} else if (baseHasProperty\n\t\t\t\t\t\t&& typeof baseVal === 'object'\n\t\t\t\t\t\t&& !helpers.isArray(baseVal)\n\t\t\t\t\t\t&& baseVal !== null\n\t\t\t\t\t\t&& typeof value === 'object'\n\t\t\t\t\t\t&& !helpers.isArray(value)) {\n\t\t\t\t\t// If we are overwriting an object with an object, do a merge of the properties.\n\t\t\t\t\tbase[key] = helpers.configMerge(baseVal, value);\n\t\t\t\t} else {\n\t\t\t\t\t// can just overwrite the value in this case\n\t\t\t\t\tbase[key] = value;\n\t\t\t\t}\n\t\t\t});\n\t\t});\n\n\t\treturn base;\n\t};\n\thelpers.scaleMerge = function(_base, extension) {\n\t\tvar base = helpers.clone(_base);\n\n\t\thelpers.each(extension, function(value, key) {\n\t\t\tif (key === 'xAxes' || key === 'yAxes') {\n\t\t\t\t// These properties are arrays of items\n\t\t\t\tif (base.hasOwnProperty(key)) {\n\t\t\t\t\thelpers.each(value, function(valueObj, index) {\n\t\t\t\t\t\tvar axisType = helpers.getValueOrDefault(valueObj.type, key === 'xAxes' ? 'category' : 'linear');\n\t\t\t\t\t\tvar axisDefaults = Chart.scaleService.getScaleDefaults(axisType);\n\t\t\t\t\t\tif (index >= base[key].length || !base[key][index].type) {\n\t\t\t\t\t\t\tbase[key].push(helpers.configMerge(axisDefaults, valueObj));\n\t\t\t\t\t\t} else if (valueObj.type && valueObj.type !== base[key][index].type) {\n\t\t\t\t\t\t\t// Type changed. Bring in the new defaults before we bring in valueObj so that valueObj can override the correct scale defaults\n\t\t\t\t\t\t\tbase[key][index] = helpers.configMerge(base[key][index], axisDefaults, valueObj);\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t// Type is the same\n\t\t\t\t\t\t\tbase[key][index] = helpers.configMerge(base[key][index], valueObj);\n\t\t\t\t\t\t}\n\t\t\t\t\t});\n\t\t\t\t} else {\n\t\t\t\t\tbase[key] = [];\n\t\t\t\t\thelpers.each(value, function(valueObj) {\n\t\t\t\t\t\tvar axisType = helpers.getValueOrDefault(valueObj.type, key === 'xAxes' ? 'category' : 'linear');\n\t\t\t\t\t\tbase[key].push(helpers.configMerge(Chart.scaleService.getScaleDefaults(axisType), valueObj));\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t} else if (base.hasOwnProperty(key) && typeof base[key] === 'object' && base[key] !== null && typeof value === 'object') {\n\t\t\t\t// If we are overwriting an object with an object, do a merge of the properties.\n\t\t\t\tbase[key] = helpers.configMerge(base[key], value);\n\n\t\t\t} else {\n\t\t\t\t// can just overwrite the value in this case\n\t\t\t\tbase[key] = value;\n\t\t\t}\n\t\t});\n\n\t\treturn base;\n\t};\n\thelpers.getValueAtIndexOrDefault = function(value, index, defaultValue) {\n\t\tif (value === undefined || value === null) {\n\t\t\treturn defaultValue;\n\t\t}\n\n\t\tif (helpers.isArray(value)) {\n\t\t\treturn index < value.length ? value[index] : defaultValue;\n\t\t}\n\n\t\treturn value;\n\t};\n\thelpers.getValueOrDefault = function(value, defaultValue) {\n\t\treturn value === undefined ? defaultValue : value;\n\t};\n\thelpers.indexOf = Array.prototype.indexOf?\n\t\tfunction(array, item) {\n\t\t\treturn array.indexOf(item);\n\t\t}:\n\t\tfunction(array, item) {\n\t\t\tfor (var i = 0, ilen = array.length; i < ilen; ++i) {\n\t\t\t\tif (array[i] === item) {\n\t\t\t\t\treturn i;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn -1;\n\t\t};\n\thelpers.where = function(collection, filterCallback) {\n\t\tif (helpers.isArray(collection) && Array.prototype.filter) {\n\t\t\treturn collection.filter(filterCallback);\n\t\t}\n\t\tvar filtered = [];\n\n\t\thelpers.each(collection, function(item) {\n\t\t\tif (filterCallback(item)) {\n\t\t\t\tfiltered.push(item);\n\t\t\t}\n\t\t});\n\n\t\treturn filtered;\n\t};\n\thelpers.findIndex = Array.prototype.findIndex?\n\t\tfunction(array, callback, scope) {\n\t\t\treturn array.findIndex(callback, scope);\n\t\t} :\n\t\tfunction(array, callback, scope) {\n\t\t\tscope = scope === undefined? array : scope;\n\t\t\tfor (var i = 0, ilen = array.length; i < ilen; ++i) {\n\t\t\t\tif (callback.call(scope, array[i], i, array)) {\n\t\t\t\t\treturn i;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn -1;\n\t\t};\n\thelpers.findNextWhere = function(arrayToSearch, filterCallback, startIndex) {\n\t\t// Default to start of the array\n\t\tif (startIndex === undefined || startIndex === null) {\n\t\t\tstartIndex = -1;\n\t\t}\n\t\tfor (var i = startIndex + 1; i < arrayToSearch.length; i++) {\n\t\t\tvar currentItem = arrayToSearch[i];\n\t\t\tif (filterCallback(currentItem)) {\n\t\t\t\treturn currentItem;\n\t\t\t}\n\t\t}\n\t};\n\thelpers.findPreviousWhere = function(arrayToSearch, filterCallback, startIndex) {\n\t\t// Default to end of the array\n\t\tif (startIndex === undefined || startIndex === null) {\n\t\t\tstartIndex = arrayToSearch.length;\n\t\t}\n\t\tfor (var i = startIndex - 1; i >= 0; i--) {\n\t\t\tvar currentItem = arrayToSearch[i];\n\t\t\tif (filterCallback(currentItem)) {\n\t\t\t\treturn currentItem;\n\t\t\t}\n\t\t}\n\t};\n\thelpers.inherits = function(extensions) {\n\t\t// Basic javascript inheritance based on the model created in Backbone.js\n\t\tvar me = this;\n\t\tvar ChartElement = (extensions && extensions.hasOwnProperty('constructor')) ? extensions.constructor : function() {\n\t\t\treturn me.apply(this, arguments);\n\t\t};\n\n\t\tvar Surrogate = function() {\n\t\t\tthis.constructor = ChartElement;\n\t\t};\n\t\tSurrogate.prototype = me.prototype;\n\t\tChartElement.prototype = new Surrogate();\n\n\t\tChartElement.extend = helpers.inherits;\n\n\t\tif (extensions) {\n\t\t\thelpers.extend(ChartElement.prototype, extensions);\n\t\t}\n\n\t\tChartElement.__super__ = me.prototype;\n\n\t\treturn ChartElement;\n\t};\n\thelpers.noop = function() {};\n\thelpers.uid = (function() {\n\t\tvar id = 0;\n\t\treturn function() {\n\t\t\treturn id++;\n\t\t};\n\t}());\n\t// -- Math methods\n\thelpers.isNumber = function(n) {\n\t\treturn !isNaN(parseFloat(n)) && isFinite(n);\n\t};\n\thelpers.almostEquals = function(x, y, epsilon) {\n\t\treturn Math.abs(x - y) < epsilon;\n\t};\n\thelpers.almostWhole = function(x, epsilon) {\n\t\tvar rounded = Math.round(x);\n\t\treturn (((rounded - epsilon) < x) && ((rounded + epsilon) > x));\n\t};\n\thelpers.max = function(array) {\n\t\treturn array.reduce(function(max, value) {\n\t\t\tif (!isNaN(value)) {\n\t\t\t\treturn Math.max(max, value);\n\t\t\t}\n\t\t\treturn max;\n\t\t}, Number.NEGATIVE_INFINITY);\n\t};\n\thelpers.min = function(array) {\n\t\treturn array.reduce(function(min, value) {\n\t\t\tif (!isNaN(value)) {\n\t\t\t\treturn Math.min(min, value);\n\t\t\t}\n\t\t\treturn min;\n\t\t}, Number.POSITIVE_INFINITY);\n\t};\n\thelpers.sign = Math.sign?\n\t\tfunction(x) {\n\t\t\treturn Math.sign(x);\n\t\t} :\n\t\tfunction(x) {\n\t\t\tx = +x; // convert to a number\n\t\t\tif (x === 0 || isNaN(x)) {\n\t\t\t\treturn x;\n\t\t\t}\n\t\t\treturn x > 0 ? 1 : -1;\n\t\t};\n\thelpers.log10 = Math.log10?\n\t\tfunction(x) {\n\t\t\treturn Math.log10(x);\n\t\t} :\n\t\tfunction(x) {\n\t\t\treturn Math.log(x) / Math.LN10;\n\t\t};\n\thelpers.toRadians = function(degrees) {\n\t\treturn degrees * (Math.PI / 180);\n\t};\n\thelpers.toDegrees = function(radians) {\n\t\treturn radians * (180 / Math.PI);\n\t};\n\t// Gets the angle from vertical upright to the point about a centre.\n\thelpers.getAngleFromPoint = function(centrePoint, anglePoint) {\n\t\tvar distanceFromXCenter = anglePoint.x - centrePoint.x,\n\t\t\tdistanceFromYCenter = anglePoint.y - centrePoint.y,\n\t\t\tradialDistanceFromCenter = Math.sqrt(distanceFromXCenter * distanceFromXCenter + distanceFromYCenter * distanceFromYCenter);\n\n\t\tvar angle = Math.atan2(distanceFromYCenter, distanceFromXCenter);\n\n\t\tif (angle < (-0.5 * Math.PI)) {\n\t\t\tangle += 2.0 * Math.PI; // make sure the returned angle is in the range of (-PI/2, 3PI/2]\n\t\t}\n\n\t\treturn {\n\t\t\tangle: angle,\n\t\t\tdistance: radialDistanceFromCenter\n\t\t};\n\t};\n\thelpers.distanceBetweenPoints = function(pt1, pt2) {\n\t\treturn Math.sqrt(Math.pow(pt2.x - pt1.x, 2) + Math.pow(pt2.y - pt1.y, 2));\n\t};\n\thelpers.aliasPixel = function(pixelWidth) {\n\t\treturn (pixelWidth % 2 === 0) ? 0 : 0.5;\n\t};\n\thelpers.splineCurve = function(firstPoint, middlePoint, afterPoint, t) {\n\t\t// Props to Rob Spencer at scaled innovation for his post on splining between points\n\t\t// http://scaledinnovation.com/analytics/splines/aboutSplines.html\n\n\t\t// This function must also respect \"skipped\" points\n\n\t\tvar previous = firstPoint.skip ? middlePoint : firstPoint,\n\t\t\tcurrent = middlePoint,\n\t\t\tnext = afterPoint.skip ? middlePoint : afterPoint;\n\n\t\tvar d01 = Math.sqrt(Math.pow(current.x - previous.x, 2) + Math.pow(current.y - previous.y, 2));\n\t\tvar d12 = Math.sqrt(Math.pow(next.x - current.x, 2) + Math.pow(next.y - current.y, 2));\n\n\t\tvar s01 = d01 / (d01 + d12);\n\t\tvar s12 = d12 / (d01 + d12);\n\n\t\t// If all points are the same, s01 & s02 will be inf\n\t\ts01 = isNaN(s01) ? 0 : s01;\n\t\ts12 = isNaN(s12) ? 0 : s12;\n\n\t\tvar fa = t * s01; // scaling factor for triangle Ta\n\t\tvar fb = t * s12;\n\n\t\treturn {\n\t\t\tprevious: {\n\t\t\t\tx: current.x - fa * (next.x - previous.x),\n\t\t\t\ty: current.y - fa * (next.y - previous.y)\n\t\t\t},\n\t\t\tnext: {\n\t\t\t\tx: current.x + fb * (next.x - previous.x),\n\t\t\t\ty: current.y + fb * (next.y - previous.y)\n\t\t\t}\n\t\t};\n\t};\n\thelpers.EPSILON = Number.EPSILON || 1e-14;\n\thelpers.splineCurveMonotone = function(points) {\n\t\t// This function calculates Bézier control points in a similar way than |splineCurve|,\n\t\t// but preserves monotonicity of the provided data and ensures no local extremums are added\n\t\t// between the dataset discrete points due to the interpolation.\n\t\t// See : https://en.wikipedia.org/wiki/Monotone_cubic_interpolation\n\n\t\tvar pointsWithTangents = (points || []).map(function(point) {\n\t\t\treturn {\n\t\t\t\tmodel: point._model,\n\t\t\t\tdeltaK: 0,\n\t\t\t\tmK: 0\n\t\t\t};\n\t\t});\n\n\t\t// Calculate slopes (deltaK) and initialize tangents (mK)\n\t\tvar pointsLen = pointsWithTangents.length;\n\t\tvar i, pointBefore, pointCurrent, pointAfter;\n\t\tfor (i = 0; i < pointsLen; ++i) {\n\t\t\tpointCurrent = pointsWithTangents[i];\n\t\t\tif (pointCurrent.model.skip) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tpointBefore = i > 0 ? pointsWithTangents[i - 1] : null;\n\t\t\tpointAfter = i < pointsLen - 1 ? pointsWithTangents[i + 1] : null;\n\t\t\tif (pointAfter && !pointAfter.model.skip) {\n\t\t\t\tvar slopeDeltaX = (pointAfter.model.x - pointCurrent.model.x);\n\n\t\t\t\t// In the case of two points that appear at the same x pixel, slopeDeltaX is 0\n\t\t\t\tpointCurrent.deltaK = slopeDeltaX !== 0 ? (pointAfter.model.y - pointCurrent.model.y) / slopeDeltaX : 0;\n\t\t\t}\n\n\t\t\tif (!pointBefore || pointBefore.model.skip) {\n\t\t\t\tpointCurrent.mK = pointCurrent.deltaK;\n\t\t\t} else if (!pointAfter || pointAfter.model.skip) {\n\t\t\t\tpointCurrent.mK = pointBefore.deltaK;\n\t\t\t} else if (this.sign(pointBefore.deltaK) !== this.sign(pointCurrent.deltaK)) {\n\t\t\t\tpointCurrent.mK = 0;\n\t\t\t} else {\n\t\t\t\tpointCurrent.mK = (pointBefore.deltaK + pointCurrent.deltaK) / 2;\n\t\t\t}\n\t\t}\n\n\t\t// Adjust tangents to ensure monotonic properties\n\t\tvar alphaK, betaK, tauK, squaredMagnitude;\n\t\tfor (i = 0; i < pointsLen - 1; ++i) {\n\t\t\tpointCurrent = pointsWithTangents[i];\n\t\t\tpointAfter = pointsWithTangents[i + 1];\n\t\t\tif (pointCurrent.model.skip || pointAfter.model.skip) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tif (helpers.almostEquals(pointCurrent.deltaK, 0, this.EPSILON)) {\n\t\t\t\tpointCurrent.mK = pointAfter.mK = 0;\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\talphaK = pointCurrent.mK / pointCurrent.deltaK;\n\t\t\tbetaK = pointAfter.mK / pointCurrent.deltaK;\n\t\t\tsquaredMagnitude = Math.pow(alphaK, 2) + Math.pow(betaK, 2);\n\t\t\tif (squaredMagnitude <= 9) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\ttauK = 3 / Math.sqrt(squaredMagnitude);\n\t\t\tpointCurrent.mK = alphaK * tauK * pointCurrent.deltaK;\n\t\t\tpointAfter.mK = betaK * tauK * pointCurrent.deltaK;\n\t\t}\n\n\t\t// Compute control points\n\t\tvar deltaX;\n\t\tfor (i = 0; i < pointsLen; ++i) {\n\t\t\tpointCurrent = pointsWithTangents[i];\n\t\t\tif (pointCurrent.model.skip) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tpointBefore = i > 0 ? pointsWithTangents[i - 1] : null;\n\t\t\tpointAfter = i < pointsLen - 1 ? pointsWithTangents[i + 1] : null;\n\t\t\tif (pointBefore && !pointBefore.model.skip) {\n\t\t\t\tdeltaX = (pointCurrent.model.x - pointBefore.model.x) / 3;\n\t\t\t\tpointCurrent.model.controlPointPreviousX = pointCurrent.model.x - deltaX;\n\t\t\t\tpointCurrent.model.controlPointPreviousY = pointCurrent.model.y - deltaX * pointCurrent.mK;\n\t\t\t}\n\t\t\tif (pointAfter && !pointAfter.model.skip) {\n\t\t\t\tdeltaX = (pointAfter.model.x - pointCurrent.model.x) / 3;\n\t\t\t\tpointCurrent.model.controlPointNextX = pointCurrent.model.x + deltaX;\n\t\t\t\tpointCurrent.model.controlPointNextY = pointCurrent.model.y + deltaX * pointCurrent.mK;\n\t\t\t}\n\t\t}\n\t};\n\thelpers.nextItem = function(collection, index, loop) {\n\t\tif (loop) {\n\t\t\treturn index >= collection.length - 1 ? collection[0] : collection[index + 1];\n\t\t}\n\t\treturn index >= collection.length - 1 ? collection[collection.length - 1] : collection[index + 1];\n\t};\n\thelpers.previousItem = function(collection, index, loop) {\n\t\tif (loop) {\n\t\t\treturn index <= 0 ? collection[collection.length - 1] : collection[index - 1];\n\t\t}\n\t\treturn index <= 0 ? collection[0] : collection[index - 1];\n\t};\n\t// Implementation of the nice number algorithm used in determining where axis labels will go\n\thelpers.niceNum = function(range, round) {\n\t\tvar exponent = Math.floor(helpers.log10(range));\n\t\tvar fraction = range / Math.pow(10, exponent);\n\t\tvar niceFraction;\n\n\t\tif (round) {\n\t\t\tif (fraction < 1.5) {\n\t\t\t\tniceFraction = 1;\n\t\t\t} else if (fraction < 3) {\n\t\t\t\tniceFraction = 2;\n\t\t\t} else if (fraction < 7) {\n\t\t\t\tniceFraction = 5;\n\t\t\t} else {\n\t\t\t\tniceFraction = 10;\n\t\t\t}\n\t\t} else if (fraction <= 1.0) {\n\t\t\tniceFraction = 1;\n\t\t} else if (fraction <= 2) {\n\t\t\tniceFraction = 2;\n\t\t} else if (fraction <= 5) {\n\t\t\tniceFraction = 5;\n\t\t} else {\n\t\t\tniceFraction = 10;\n\t\t}\n\n\t\treturn niceFraction * Math.pow(10, exponent);\n\t};\n\t// Easing functions adapted from Robert Penner's easing equations\n\t// http://www.robertpenner.com/easing/\n\tvar easingEffects = helpers.easingEffects = {\n\t\tlinear: function(t) {\n\t\t\treturn t;\n\t\t},\n\t\teaseInQuad: function(t) {\n\t\t\treturn t * t;\n\t\t},\n\t\teaseOutQuad: function(t) {\n\t\t\treturn -1 * t * (t - 2);\n\t\t},\n\t\teaseInOutQuad: function(t) {\n\t\t\tif ((t /= 1 / 2) < 1) {\n\t\t\t\treturn 1 / 2 * t * t;\n\t\t\t}\n\t\t\treturn -1 / 2 * ((--t) * (t - 2) - 1);\n\t\t},\n\t\teaseInCubic: function(t) {\n\t\t\treturn t * t * t;\n\t\t},\n\t\teaseOutCubic: function(t) {\n\t\t\treturn 1 * ((t = t / 1 - 1) * t * t + 1);\n\t\t},\n\t\teaseInOutCubic: function(t) {\n\t\t\tif ((t /= 1 / 2) < 1) {\n\t\t\t\treturn 1 / 2 * t * t * t;\n\t\t\t}\n\t\t\treturn 1 / 2 * ((t -= 2) * t * t + 2);\n\t\t},\n\t\teaseInQuart: function(t) {\n\t\t\treturn t * t * t * t;\n\t\t},\n\t\teaseOutQuart: function(t) {\n\t\t\treturn -1 * ((t = t / 1 - 1) * t * t * t - 1);\n\t\t},\n\t\teaseInOutQuart: function(t) {\n\t\t\tif ((t /= 1 / 2) < 1) {\n\t\t\t\treturn 1 / 2 * t * t * t * t;\n\t\t\t}\n\t\t\treturn -1 / 2 * ((t -= 2) * t * t * t - 2);\n\t\t},\n\t\teaseInQuint: function(t) {\n\t\t\treturn 1 * (t /= 1) * t * t * t * t;\n\t\t},\n\t\teaseOutQuint: function(t) {\n\t\t\treturn 1 * ((t = t / 1 - 1) * t * t * t * t + 1);\n\t\t},\n\t\teaseInOutQuint: function(t) {\n\t\t\tif ((t /= 1 / 2) < 1) {\n\t\t\t\treturn 1 / 2 * t * t * t * t * t;\n\t\t\t}\n\t\t\treturn 1 / 2 * ((t -= 2) * t * t * t * t + 2);\n\t\t},\n\t\teaseInSine: function(t) {\n\t\t\treturn -1 * Math.cos(t / 1 * (Math.PI / 2)) + 1;\n\t\t},\n\t\teaseOutSine: function(t) {\n\t\t\treturn 1 * Math.sin(t / 1 * (Math.PI / 2));\n\t\t},\n\t\teaseInOutSine: function(t) {\n\t\t\treturn -1 / 2 * (Math.cos(Math.PI * t / 1) - 1);\n\t\t},\n\t\teaseInExpo: function(t) {\n\t\t\treturn (t === 0) ? 1 : 1 * Math.pow(2, 10 * (t / 1 - 1));\n\t\t},\n\t\teaseOutExpo: function(t) {\n\t\t\treturn (t === 1) ? 1 : 1 * (-Math.pow(2, -10 * t / 1) + 1);\n\t\t},\n\t\teaseInOutExpo: function(t) {\n\t\t\tif (t === 0) {\n\t\t\t\treturn 0;\n\t\t\t}\n\t\t\tif (t === 1) {\n\t\t\t\treturn 1;\n\t\t\t}\n\t\t\tif ((t /= 1 / 2) < 1) {\n\t\t\t\treturn 1 / 2 * Math.pow(2, 10 * (t - 1));\n\t\t\t}\n\t\t\treturn 1 / 2 * (-Math.pow(2, -10 * --t) + 2);\n\t\t},\n\t\teaseInCirc: function(t) {\n\t\t\tif (t >= 1) {\n\t\t\t\treturn t;\n\t\t\t}\n\t\t\treturn -1 * (Math.sqrt(1 - (t /= 1) * t) - 1);\n\t\t},\n\t\teaseOutCirc: function(t) {\n\t\t\treturn 1 * Math.sqrt(1 - (t = t / 1 - 1) * t);\n\t\t},\n\t\teaseInOutCirc: function(t) {\n\t\t\tif ((t /= 1 / 2) < 1) {\n\t\t\t\treturn -1 / 2 * (Math.sqrt(1 - t * t) - 1);\n\t\t\t}\n\t\t\treturn 1 / 2 * (Math.sqrt(1 - (t -= 2) * t) + 1);\n\t\t},\n\t\teaseInElastic: function(t) {\n\t\t\tvar s = 1.70158;\n\t\t\tvar p = 0;\n\t\t\tvar a = 1;\n\t\t\tif (t === 0) {\n\t\t\t\treturn 0;\n\t\t\t}\n\t\t\tif ((t /= 1) === 1) {\n\t\t\t\treturn 1;\n\t\t\t}\n\t\t\tif (!p) {\n\t\t\t\tp = 1 * 0.3;\n\t\t\t}\n\t\t\tif (a < Math.abs(1)) {\n\t\t\t\ta = 1;\n\t\t\t\ts = p / 4;\n\t\t\t} else {\n\t\t\t\ts = p / (2 * Math.PI) * Math.asin(1 / a);\n\t\t\t}\n\t\t\treturn -(a * Math.pow(2, 10 * (t -= 1)) * Math.sin((t * 1 - s) * (2 * Math.PI) / p));\n\t\t},\n\t\teaseOutElastic: function(t) {\n\t\t\tvar s = 1.70158;\n\t\t\tvar p = 0;\n\t\t\tvar a = 1;\n\t\t\tif (t === 0) {\n\t\t\t\treturn 0;\n\t\t\t}\n\t\t\tif ((t /= 1) === 1) {\n\t\t\t\treturn 1;\n\t\t\t}\n\t\t\tif (!p) {\n\t\t\t\tp = 1 * 0.3;\n\t\t\t}\n\t\t\tif (a < Math.abs(1)) {\n\t\t\t\ta = 1;\n\t\t\t\ts = p / 4;\n\t\t\t} else {\n\t\t\t\ts = p / (2 * Math.PI) * Math.asin(1 / a);\n\t\t\t}\n\t\t\treturn a * Math.pow(2, -10 * t) * Math.sin((t * 1 - s) * (2 * Math.PI) / p) + 1;\n\t\t},\n\t\teaseInOutElastic: function(t) {\n\t\t\tvar s = 1.70158;\n\t\t\tvar p = 0;\n\t\t\tvar a = 1;\n\t\t\tif (t === 0) {\n\t\t\t\treturn 0;\n\t\t\t}\n\t\t\tif ((t /= 1 / 2) === 2) {\n\t\t\t\treturn 1;\n\t\t\t}\n\t\t\tif (!p) {\n\t\t\t\tp = 1 * (0.3 * 1.5);\n\t\t\t}\n\t\t\tif (a < Math.abs(1)) {\n\t\t\t\ta = 1;\n\t\t\t\ts = p / 4;\n\t\t\t} else {\n\t\t\t\ts = p / (2 * Math.PI) * Math.asin(1 / a);\n\t\t\t}\n\t\t\tif (t < 1) {\n\t\t\t\treturn -0.5 * (a * Math.pow(2, 10 * (t -= 1)) * Math.sin((t * 1 - s) * (2 * Math.PI) / p));\n\t\t\t}\n\t\t\treturn a * Math.pow(2, -10 * (t -= 1)) * Math.sin((t * 1 - s) * (2 * Math.PI) / p) * 0.5 + 1;\n\t\t},\n\t\teaseInBack: function(t) {\n\t\t\tvar s = 1.70158;\n\t\t\treturn 1 * (t /= 1) * t * ((s + 1) * t - s);\n\t\t},\n\t\teaseOutBack: function(t) {\n\t\t\tvar s = 1.70158;\n\t\t\treturn 1 * ((t = t / 1 - 1) * t * ((s + 1) * t + s) + 1);\n\t\t},\n\t\teaseInOutBack: function(t) {\n\t\t\tvar s = 1.70158;\n\t\t\tif ((t /= 1 / 2) < 1) {\n\t\t\t\treturn 1 / 2 * (t * t * (((s *= (1.525)) + 1) * t - s));\n\t\t\t}\n\t\t\treturn 1 / 2 * ((t -= 2) * t * (((s *= (1.525)) + 1) * t + s) + 2);\n\t\t},\n\t\teaseInBounce: function(t) {\n\t\t\treturn 1 - easingEffects.easeOutBounce(1 - t);\n\t\t},\n\t\teaseOutBounce: function(t) {\n\t\t\tif ((t /= 1) < (1 / 2.75)) {\n\t\t\t\treturn 1 * (7.5625 * t * t);\n\t\t\t} else if (t < (2 / 2.75)) {\n\t\t\t\treturn 1 * (7.5625 * (t -= (1.5 / 2.75)) * t + 0.75);\n\t\t\t} else if (t < (2.5 / 2.75)) {\n\t\t\t\treturn 1 * (7.5625 * (t -= (2.25 / 2.75)) * t + 0.9375);\n\t\t\t}\n\t\t\treturn 1 * (7.5625 * (t -= (2.625 / 2.75)) * t + 0.984375);\n\t\t},\n\t\teaseInOutBounce: function(t) {\n\t\t\tif (t < 1 / 2) {\n\t\t\t\treturn easingEffects.easeInBounce(t * 2) * 0.5;\n\t\t\t}\n\t\t\treturn easingEffects.easeOutBounce(t * 2 - 1) * 0.5 + 1 * 0.5;\n\t\t}\n\t};\n\t// Request animation polyfill - http://www.paulirish.com/2011/requestanimationframe-for-smart-animating/\n\thelpers.requestAnimFrame = (function() {\n\t\tif (typeof window === 'undefined') {\n\t\t\treturn function(callback) {\n\t\t\t\tcallback();\n\t\t\t};\n\t\t}\n\t\treturn window.requestAnimationFrame ||\n\t\t\twindow.webkitRequestAnimationFrame ||\n\t\t\twindow.mozRequestAnimationFrame ||\n\t\t\twindow.oRequestAnimationFrame ||\n\t\t\twindow.msRequestAnimationFrame ||\n\t\t\tfunction(callback) {\n\t\t\t\treturn window.setTimeout(callback, 1000 / 60);\n\t\t\t};\n\t}());\n\t// -- DOM methods\n\thelpers.getRelativePosition = function(evt, chart) {\n\t\tvar mouseX, mouseY;\n\t\tvar e = evt.originalEvent || evt,\n\t\t\tcanvas = evt.currentTarget || evt.srcElement,\n\t\t\tboundingRect = canvas.getBoundingClientRect();\n\n\t\tvar touches = e.touches;\n\t\tif (touches && touches.length > 0) {\n\t\t\tmouseX = touches[0].clientX;\n\t\t\tmouseY = touches[0].clientY;\n\n\t\t} else {\n\t\t\tmouseX = e.clientX;\n\t\t\tmouseY = e.clientY;\n\t\t}\n\n\t\t// Scale mouse coordinates into canvas coordinates\n\t\t// by following the pattern laid out by 'jerryj' in the comments of\n\t\t// http://www.html5canvastutorials.com/advanced/html5-canvas-mouse-coordinates/\n\t\tvar paddingLeft = parseFloat(helpers.getStyle(canvas, 'padding-left'));\n\t\tvar paddingTop = parseFloat(helpers.getStyle(canvas, 'padding-top'));\n\t\tvar paddingRight = parseFloat(helpers.getStyle(canvas, 'padding-right'));\n\t\tvar paddingBottom = parseFloat(helpers.getStyle(canvas, 'padding-bottom'));\n\t\tvar width = boundingRect.right - boundingRect.left - paddingLeft - paddingRight;\n\t\tvar height = boundingRect.bottom - boundingRect.top - paddingTop - paddingBottom;\n\n\t\t// We divide by the current device pixel ratio, because the canvas is scaled up by that amount in each direction. However\n\t\t// the backend model is in unscaled coordinates. Since we are going to deal with our model coordinates, we go back here\n\t\tmouseX = Math.round((mouseX - boundingRect.left - paddingLeft) / (width) * canvas.width / chart.currentDevicePixelRatio);\n\t\tmouseY = Math.round((mouseY - boundingRect.top - paddingTop) / (height) * canvas.height / chart.currentDevicePixelRatio);\n\n\t\treturn {\n\t\t\tx: mouseX,\n\t\t\ty: mouseY\n\t\t};\n\n\t};\n\thelpers.addEvent = function(node, eventType, method) {\n\t\tif (node.addEventListener) {\n\t\t\tnode.addEventListener(eventType, method);\n\t\t} else if (node.attachEvent) {\n\t\t\tnode.attachEvent('on' + eventType, method);\n\t\t} else {\n\t\t\tnode['on' + eventType] = method;\n\t\t}\n\t};\n\thelpers.removeEvent = function(node, eventType, handler) {\n\t\tif (node.removeEventListener) {\n\t\t\tnode.removeEventListener(eventType, handler, false);\n\t\t} else if (node.detachEvent) {\n\t\t\tnode.detachEvent('on' + eventType, handler);\n\t\t} else {\n\t\t\tnode['on' + eventType] = helpers.noop;\n\t\t}\n\t};\n\n\t// Private helper function to convert max-width/max-height values that may be percentages into a number\n\tfunction parseMaxStyle(styleValue, node, parentProperty) {\n\t\tvar valueInPixels;\n\t\tif (typeof(styleValue) === 'string') {\n\t\t\tvalueInPixels = parseInt(styleValue, 10);\n\n\t\t\tif (styleValue.indexOf('%') !== -1) {\n\t\t\t\t// percentage * size in dimension\n\t\t\t\tvalueInPixels = valueInPixels / 100 * node.parentNode[parentProperty];\n\t\t\t}\n\t\t} else {\n\t\t\tvalueInPixels = styleValue;\n\t\t}\n\n\t\treturn valueInPixels;\n\t}\n\n\t/**\n\t * Returns if the given value contains an effective constraint.\n\t * @private\n\t */\n\tfunction isConstrainedValue(value) {\n\t\treturn value !== undefined && value !== null && value !== 'none';\n\t}\n\n\t// Private helper to get a constraint dimension\n\t// @param domNode : the node to check the constraint on\n\t// @param maxStyle : the style that defines the maximum for the direction we are using (maxWidth / maxHeight)\n\t// @param percentageProperty : property of parent to use when calculating width as a percentage\n\t// @see http://www.nathanaeljones.com/blog/2013/reading-max-width-cross-browser\n\tfunction getConstraintDimension(domNode, maxStyle, percentageProperty) {\n\t\tvar view = document.defaultView;\n\t\tvar parentNode = domNode.parentNode;\n\t\tvar constrainedNode = view.getComputedStyle(domNode)[maxStyle];\n\t\tvar constrainedContainer = view.getComputedStyle(parentNode)[maxStyle];\n\t\tvar hasCNode = isConstrainedValue(constrainedNode);\n\t\tvar hasCContainer = isConstrainedValue(constrainedContainer);\n\t\tvar infinity = Number.POSITIVE_INFINITY;\n\n\t\tif (hasCNode || hasCContainer) {\n\t\t\treturn Math.min(\n\t\t\t\thasCNode? parseMaxStyle(constrainedNode, domNode, percentageProperty) : infinity,\n\t\t\t\thasCContainer? parseMaxStyle(constrainedContainer, parentNode, percentageProperty) : infinity);\n\t\t}\n\n\t\treturn 'none';\n\t}\n\t// returns Number or undefined if no constraint\n\thelpers.getConstraintWidth = function(domNode) {\n\t\treturn getConstraintDimension(domNode, 'max-width', 'clientWidth');\n\t};\n\t// returns Number or undefined if no constraint\n\thelpers.getConstraintHeight = function(domNode) {\n\t\treturn getConstraintDimension(domNode, 'max-height', 'clientHeight');\n\t};\n\thelpers.getMaximumWidth = function(domNode) {\n\t\tvar container = domNode.parentNode;\n\t\tvar paddingLeft = parseInt(helpers.getStyle(container, 'padding-left'), 10);\n\t\tvar paddingRight = parseInt(helpers.getStyle(container, 'padding-right'), 10);\n\t\tvar w = container.clientWidth - paddingLeft - paddingRight;\n\t\tvar cw = helpers.getConstraintWidth(domNode);\n\t\treturn isNaN(cw)? w : Math.min(w, cw);\n\t};\n\thelpers.getMaximumHeight = function(domNode) {\n\t\tvar container = domNode.parentNode;\n\t\tvar paddingTop = parseInt(helpers.getStyle(container, 'padding-top'), 10);\n\t\tvar paddingBottom = parseInt(helpers.getStyle(container, 'padding-bottom'), 10);\n\t\tvar h = container.clientHeight - paddingTop - paddingBottom;\n\t\tvar ch = helpers.getConstraintHeight(domNode);\n\t\treturn isNaN(ch)? h : Math.min(h, ch);\n\t};\n\thelpers.getStyle = function(el, property) {\n\t\treturn el.currentStyle ?\n\t\t\tel.currentStyle[property] :\n\t\t\tdocument.defaultView.getComputedStyle(el, null).getPropertyValue(property);\n\t};\n\thelpers.retinaScale = function(chart) {\n\t\tvar pixelRatio = chart.currentDevicePixelRatio = window.devicePixelRatio || 1;\n\t\tif (pixelRatio === 1) {\n\t\t\treturn;\n\t\t}\n\n\t\tvar canvas = chart.canvas;\n\t\tvar height = chart.height;\n\t\tvar width = chart.width;\n\n\t\tcanvas.height = height * pixelRatio;\n\t\tcanvas.width = width * pixelRatio;\n\t\tchart.ctx.scale(pixelRatio, pixelRatio);\n\n\t\t// If no style has been set on the canvas, the render size is used as display size,\n\t\t// making the chart visually bigger, so let's enforce it to the \"correct\" values.\n\t\t// See https://github.com/chartjs/Chart.js/issues/3575\n\t\tcanvas.style.height = height + 'px';\n\t\tcanvas.style.width = width + 'px';\n\t};\n\t// -- Canvas methods\n\thelpers.clear = function(chart) {\n\t\tchart.ctx.clearRect(0, 0, chart.width, chart.height);\n\t};\n\thelpers.fontString = function(pixelSize, fontStyle, fontFamily) {\n\t\treturn fontStyle + ' ' + pixelSize + 'px ' + fontFamily;\n\t};\n\thelpers.longestText = function(ctx, font, arrayOfThings, cache) {\n\t\tcache = cache || {};\n\t\tvar data = cache.data = cache.data || {};\n\t\tvar gc = cache.garbageCollect = cache.garbageCollect || [];\n\n\t\tif (cache.font !== font) {\n\t\t\tdata = cache.data = {};\n\t\t\tgc = cache.garbageCollect = [];\n\t\t\tcache.font = font;\n\t\t}\n\n\t\tctx.font = font;\n\t\tvar longest = 0;\n\t\thelpers.each(arrayOfThings, function(thing) {\n\t\t\t// Undefined strings and arrays should not be measured\n\t\t\tif (thing !== undefined && thing !== null && helpers.isArray(thing) !== true) {\n\t\t\t\tlongest = helpers.measureText(ctx, data, gc, longest, thing);\n\t\t\t} else if (helpers.isArray(thing)) {\n\t\t\t\t// if it is an array lets measure each element\n\t\t\t\t// to do maybe simplify this function a bit so we can do this more recursively?\n\t\t\t\thelpers.each(thing, function(nestedThing) {\n\t\t\t\t\t// Undefined strings and arrays should not be measured\n\t\t\t\t\tif (nestedThing !== undefined && nestedThing !== null && !helpers.isArray(nestedThing)) {\n\t\t\t\t\t\tlongest = helpers.measureText(ctx, data, gc, longest, nestedThing);\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t}\n\t\t});\n\n\t\tvar gcLen = gc.length / 2;\n\t\tif (gcLen > arrayOfThings.length) {\n\t\t\tfor (var i = 0; i < gcLen; i++) {\n\t\t\t\tdelete data[gc[i]];\n\t\t\t}\n\t\t\tgc.splice(0, gcLen);\n\t\t}\n\t\treturn longest;\n\t};\n\thelpers.measureText = function(ctx, data, gc, longest, string) {\n\t\tvar textWidth = data[string];\n\t\tif (!textWidth) {\n\t\t\ttextWidth = data[string] = ctx.measureText(string).width;\n\t\t\tgc.push(string);\n\t\t}\n\t\tif (textWidth > longest) {\n\t\t\tlongest = textWidth;\n\t\t}\n\t\treturn longest;\n\t};\n\thelpers.numberOfLabelLines = function(arrayOfThings) {\n\t\tvar numberOfLines = 1;\n\t\thelpers.each(arrayOfThings, function(thing) {\n\t\t\tif (helpers.isArray(thing)) {\n\t\t\t\tif (thing.length > numberOfLines) {\n\t\t\t\t\tnumberOfLines = thing.length;\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\t\treturn numberOfLines;\n\t};\n\thelpers.drawRoundedRectangle = function(ctx, x, y, width, height, radius) {\n\t\tctx.beginPath();\n\t\tctx.moveTo(x + radius, y);\n\t\tctx.lineTo(x + width - radius, y);\n\t\tctx.quadraticCurveTo(x + width, y, x + width, y + radius);\n\t\tctx.lineTo(x + width, y + height - radius);\n\t\tctx.quadraticCurveTo(x + width, y + height, x + width - radius, y + height);\n\t\tctx.lineTo(x + radius, y + height);\n\t\tctx.quadraticCurveTo(x, y + height, x, y + height - radius);\n\t\tctx.lineTo(x, y + radius);\n\t\tctx.quadraticCurveTo(x, y, x + radius, y);\n\t\tctx.closePath();\n\t};\n\n\thelpers.color = !color?\n\t\tfunction(value) {\n\t\t\tconsole.error('Color.js not found!');\n\t\t\treturn value;\n\t\t} :\n\t\tfunction(value) {\n\t\t\t/* global CanvasGradient */\n\t\t\tif (value instanceof CanvasGradient) {\n\t\t\t\tvalue = Chart.defaults.global.defaultColor;\n\t\t\t}\n\n\t\t\treturn color(value);\n\t\t};\n\n\thelpers.isArray = Array.isArray?\n\t\tfunction(obj) {\n\t\t\treturn Array.isArray(obj);\n\t\t} :\n\t\tfunction(obj) {\n\t\t\treturn Object.prototype.toString.call(obj) === '[object Array]';\n\t\t};\n\t// ! @see http://stackoverflow.com/a/14853974\n\thelpers.arrayEquals = function(a0, a1) {\n\t\tvar i, ilen, v0, v1;\n\n\t\tif (!a0 || !a1 || a0.length !== a1.length) {\n\t\t\treturn false;\n\t\t}\n\n\t\tfor (i = 0, ilen=a0.length; i < ilen; ++i) {\n\t\t\tv0 = a0[i];\n\t\t\tv1 = a1[i];\n\n\t\t\tif (v0 instanceof Array && v1 instanceof Array) {\n\t\t\t\tif (!helpers.arrayEquals(v0, v1)) {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t} else if (v0 !== v1) {\n\t\t\t\t// NOTE: two different object instances will never be equal: {x:20} != {x:20}\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\n\t\treturn true;\n\t};\n\thelpers.callback = function(fn, args, thisArg) {\n\t\tif (fn && typeof fn.call === 'function') {\n\t\t\tfn.apply(thisArg, args);\n\t\t}\n\t};\n\thelpers.getHoverColor = function(colorValue) {\n\t\t/* global CanvasPattern */\n\t\treturn (colorValue instanceof CanvasPattern) ?\n\t\t\tcolorValue :\n\t\t\thelpers.color(colorValue).saturate(0.5).darken(0.1).rgbString();\n\t};\n\n\t/**\n\t * Provided for backward compatibility, use Chart.helpers#callback instead.\n\t * @function Chart.helpers#callCallback\n\t * @deprecated since version 2.6.0\n\t * @todo remove at version 3\n\t */\n\thelpers.callCallback = helpers.callback;\n};\n\n},{\"3\":3}],27:[function(require,module,exports){\n'use strict';\n\nmodule.exports = function(Chart) {\n\tvar helpers = Chart.helpers;\n\n\t/**\n\t * Helper function to get relative position for an event\n\t * @param {Event|IEvent} event - The event to get the position for\n\t * @param {Chart} chart - The chart\n\t * @returns {Point} the event position\n\t */\n\tfunction getRelativePosition(e, chart) {\n\t\tif (e.native) {\n\t\t\treturn {\n\t\t\t\tx: e.x,\n\t\t\t\ty: e.y\n\t\t\t};\n\t\t}\n\n\t\treturn helpers.getRelativePosition(e, chart);\n\t}\n\n\t/**\n\t * Helper function to traverse all of the visible elements in the chart\n\t * @param chart {chart} the chart\n\t * @param handler {Function} the callback to execute for each visible item\n\t */\n\tfunction parseVisibleItems(chart, handler) {\n\t\tvar datasets = chart.data.datasets;\n\t\tvar meta, i, j, ilen, jlen;\n\n\t\tfor (i = 0, ilen = datasets.length; i < ilen; ++i) {\n\t\t\tif (!chart.isDatasetVisible(i)) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tmeta = chart.getDatasetMeta(i);\n\t\t\tfor (j = 0, jlen = meta.data.length; j < jlen; ++j) {\n\t\t\t\tvar element = meta.data[j];\n\t\t\t\tif (!element._view.skip) {\n\t\t\t\t\thandler(element);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Helper function to get the items that intersect the event position\n\t * @param items {ChartElement[]} elements to filter\n\t * @param position {Point} the point to be nearest to\n\t * @return {ChartElement[]} the nearest items\n\t */\n\tfunction getIntersectItems(chart, position) {\n\t\tvar elements = [];\n\n\t\tparseVisibleItems(chart, function(element) {\n\t\t\tif (element.inRange(position.x, position.y)) {\n\t\t\t\telements.push(element);\n\t\t\t}\n\t\t});\n\n\t\treturn elements;\n\t}\n\n\t/**\n\t * Helper function to get the items nearest to the event position considering all visible items in teh chart\n\t * @param chart {Chart} the chart to look at elements from\n\t * @param position {Point} the point to be nearest to\n\t * @param intersect {Boolean} if true, only consider items that intersect the position\n\t * @param distanceMetric {Function} Optional function to provide the distance between\n\t * @return {ChartElement[]} the nearest items\n\t */\n\tfunction getNearestItems(chart, position, intersect, distanceMetric) {\n\t\tvar minDistance = Number.POSITIVE_INFINITY;\n\t\tvar nearestItems = [];\n\n\t\tif (!distanceMetric) {\n\t\t\tdistanceMetric = helpers.distanceBetweenPoints;\n\t\t}\n\n\t\tparseVisibleItems(chart, function(element) {\n\t\t\tif (intersect && !element.inRange(position.x, position.y)) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tvar center = element.getCenterPoint();\n\t\t\tvar distance = distanceMetric(position, center);\n\n\t\t\tif (distance < minDistance) {\n\t\t\t\tnearestItems = [element];\n\t\t\t\tminDistance = distance;\n\t\t\t} else if (distance === minDistance) {\n\t\t\t\t// Can have multiple items at the same distance in which case we sort by size\n\t\t\t\tnearestItems.push(element);\n\t\t\t}\n\t\t});\n\n\t\treturn nearestItems;\n\t}\n\n\tfunction indexMode(chart, e, options) {\n\t\tvar position = getRelativePosition(e, chart);\n\t\tvar distanceMetric = function(pt1, pt2) {\n\t\t\treturn Math.abs(pt1.x - pt2.x);\n\t\t};\n\t\tvar items = options.intersect ? getIntersectItems(chart, position) : getNearestItems(chart, position, false, distanceMetric);\n\t\tvar elements = [];\n\n\t\tif (!items.length) {\n\t\t\treturn [];\n\t\t}\n\n\t\tchart.data.datasets.forEach(function(dataset, datasetIndex) {\n\t\t\tif (chart.isDatasetVisible(datasetIndex)) {\n\t\t\t\tvar meta = chart.getDatasetMeta(datasetIndex),\n\t\t\t\t\telement = meta.data[items[0]._index];\n\n\t\t\t\t// don't count items that are skipped (null data)\n\t\t\t\tif (element && !element._view.skip) {\n\t\t\t\t\telements.push(element);\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\n\t\treturn elements;\n\t}\n\n\t/**\n\t * @interface IInteractionOptions\n\t */\n\t/**\n\t * If true, only consider items that intersect the point\n\t * @name IInterfaceOptions#boolean\n\t * @type Boolean\n\t */\n\n\t/**\n\t * Contains interaction related functions\n\t * @namespace Chart.Interaction\n\t */\n\tChart.Interaction = {\n\t\t// Helper function for different modes\n\t\tmodes: {\n\t\t\tsingle: function(chart, e) {\n\t\t\t\tvar position = getRelativePosition(e, chart);\n\t\t\t\tvar elements = [];\n\n\t\t\t\tparseVisibleItems(chart, function(element) {\n\t\t\t\t\tif (element.inRange(position.x, position.y)) {\n\t\t\t\t\t\telements.push(element);\n\t\t\t\t\t\treturn elements;\n\t\t\t\t\t}\n\t\t\t\t});\n\n\t\t\t\treturn elements.slice(0, 1);\n\t\t\t},\n\n\t\t\t/**\n\t\t\t * @function Chart.Interaction.modes.label\n\t\t\t * @deprecated since version 2.4.0\n\t \t\t * @todo remove at version 3\n\t\t\t * @private\n\t\t\t */\n\t\t\tlabel: indexMode,\n\n\t\t\t/**\n\t\t\t * Returns items at the same index. If the options.intersect parameter is true, we only return items if we intersect something\n\t\t\t * If the options.intersect mode is false, we find the nearest item and return the items at the same index as that item\n\t\t\t * @function Chart.Interaction.modes.index\n\t\t\t * @since v2.4.0\n\t\t\t * @param chart {chart} the chart we are returning items from\n\t\t\t * @param e {Event} the event we are find things at\n\t\t\t * @param options {IInteractionOptions} options to use during interaction\n\t\t\t * @return {Chart.Element[]} Array of elements that are under the point. If none are found, an empty array is returned\n\t\t\t */\n\t\t\tindex: indexMode,\n\n\t\t\t/**\n\t\t\t * Returns items in the same dataset. If the options.intersect parameter is true, we only return items if we intersect something\n\t\t\t * If the options.intersect is false, we find the nearest item and return the items in that dataset\n\t\t\t * @function Chart.Interaction.modes.dataset\n\t\t\t * @param chart {chart} the chart we are returning items from\n\t\t\t * @param e {Event} the event we are find things at\n\t\t\t * @param options {IInteractionOptions} options to use during interaction\n\t\t\t * @return {Chart.Element[]} Array of elements that are under the point. If none are found, an empty array is returned\n\t\t\t */\n\t\t\tdataset: function(chart, e, options) {\n\t\t\t\tvar position = getRelativePosition(e, chart);\n\t\t\t\tvar items = options.intersect ? getIntersectItems(chart, position) : getNearestItems(chart, position, false);\n\n\t\t\t\tif (items.length > 0) {\n\t\t\t\t\titems = chart.getDatasetMeta(items[0]._datasetIndex).data;\n\t\t\t\t}\n\n\t\t\t\treturn items;\n\t\t\t},\n\n\t\t\t/**\n\t\t\t * @function Chart.Interaction.modes.x-axis\n\t\t\t * @deprecated since version 2.4.0. Use index mode and intersect == true\n\t\t\t * @todo remove at version 3\n\t\t\t * @private\n\t\t\t */\n\t\t\t'x-axis': function(chart, e) {\n\t\t\t\treturn indexMode(chart, e, true);\n\t\t\t},\n\n\t\t\t/**\n\t\t\t * Point mode returns all elements that hit test based on the event position\n\t\t\t * of the event\n\t\t\t * @function Chart.Interaction.modes.intersect\n\t\t\t * @param chart {chart} the chart we are returning items from\n\t\t\t * @param e {Event} the event we are find things at\n\t\t\t * @return {Chart.Element[]} Array of elements that are under the point. If none are found, an empty array is returned\n\t\t\t */\n\t\t\tpoint: function(chart, e) {\n\t\t\t\tvar position = getRelativePosition(e, chart);\n\t\t\t\treturn getIntersectItems(chart, position);\n\t\t\t},\n\n\t\t\t/**\n\t\t\t * nearest mode returns the element closest to the point\n\t\t\t * @function Chart.Interaction.modes.intersect\n\t\t\t * @param chart {chart} the chart we are returning items from\n\t\t\t * @param e {Event} the event we are find things at\n\t\t\t * @param options {IInteractionOptions} options to use\n\t\t\t * @return {Chart.Element[]} Array of elements that are under the point. If none are found, an empty array is returned\n\t\t\t */\n\t\t\tnearest: function(chart, e, options) {\n\t\t\t\tvar position = getRelativePosition(e, chart);\n\t\t\t\tvar nearestItems = getNearestItems(chart, position, options.intersect);\n\n\t\t\t\t// We have multiple items at the same distance from the event. Now sort by smallest\n\t\t\t\tif (nearestItems.length > 1) {\n\t\t\t\t\tnearestItems.sort(function(a, b) {\n\t\t\t\t\t\tvar sizeA = a.getArea();\n\t\t\t\t\t\tvar sizeB = b.getArea();\n\t\t\t\t\t\tvar ret = sizeA - sizeB;\n\n\t\t\t\t\t\tif (ret === 0) {\n\t\t\t\t\t\t\t// if equal sort by dataset index\n\t\t\t\t\t\t\tret = a._datasetIndex - b._datasetIndex;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\treturn ret;\n\t\t\t\t\t});\n\t\t\t\t}\n\n\t\t\t\t// Return only 1 item\n\t\t\t\treturn nearestItems.slice(0, 1);\n\t\t\t},\n\n\t\t\t/**\n\t\t\t * x mode returns the elements that hit-test at the current x coordinate\n\t\t\t * @function Chart.Interaction.modes.x\n\t\t\t * @param chart {chart} the chart we are returning items from\n\t\t\t * @param e {Event} the event we are find things at\n\t\t\t * @param options {IInteractionOptions} options to use\n\t\t\t * @return {Chart.Element[]} Array of elements that are under the point. If none are found, an empty array is returned\n\t\t\t */\n\t\t\tx: function(chart, e, options) {\n\t\t\t\tvar position = getRelativePosition(e, chart);\n\t\t\t\tvar items = [];\n\t\t\t\tvar intersectsItem = false;\n\n\t\t\t\tparseVisibleItems(chart, function(element) {\n\t\t\t\t\tif (element.inXRange(position.x)) {\n\t\t\t\t\t\titems.push(element);\n\t\t\t\t\t}\n\n\t\t\t\t\tif (element.inRange(position.x, position.y)) {\n\t\t\t\t\t\tintersectsItem = true;\n\t\t\t\t\t}\n\t\t\t\t});\n\n\t\t\t\t// If we want to trigger on an intersect and we don't have any items\n\t\t\t\t// that intersect the position, return nothing\n\t\t\t\tif (options.intersect && !intersectsItem) {\n\t\t\t\t\titems = [];\n\t\t\t\t}\n\t\t\t\treturn items;\n\t\t\t},\n\n\t\t\t/**\n\t\t\t * y mode returns the elements that hit-test at the current y coordinate\n\t\t\t * @function Chart.Interaction.modes.y\n\t\t\t * @param chart {chart} the chart we are returning items from\n\t\t\t * @param e {Event} the event we are find things at\n\t\t\t * @param options {IInteractionOptions} options to use\n\t\t\t * @return {Chart.Element[]} Array of elements that are under the point. If none are found, an empty array is returned\n\t\t\t */\n\t\t\ty: function(chart, e, options) {\n\t\t\t\tvar position = getRelativePosition(e, chart);\n\t\t\t\tvar items = [];\n\t\t\t\tvar intersectsItem = false;\n\n\t\t\t\tparseVisibleItems(chart, function(element) {\n\t\t\t\t\tif (element.inYRange(position.y)) {\n\t\t\t\t\t\titems.push(element);\n\t\t\t\t\t}\n\n\t\t\t\t\tif (element.inRange(position.x, position.y)) {\n\t\t\t\t\t\tintersectsItem = true;\n\t\t\t\t\t}\n\t\t\t\t});\n\n\t\t\t\t// If we want to trigger on an intersect and we don't have any items\n\t\t\t\t// that intersect the position, return nothing\n\t\t\t\tif (options.intersect && !intersectsItem) {\n\t\t\t\t\titems = [];\n\t\t\t\t}\n\t\t\t\treturn items;\n\t\t\t}\n\t\t}\n\t};\n};\n\n},{}],28:[function(require,module,exports){\n'use strict';\n\nmodule.exports = function() {\n\n\t// Occupy the global variable of Chart, and create a simple base class\n\tvar Chart = function(item, config) {\n\t\tthis.construct(item, config);\n\t\treturn this;\n\t};\n\n\t// Globally expose the defaults to allow for user updating/changing\n\tChart.defaults = {\n\t\tglobal: {\n\t\t\tresponsive: true,\n\t\t\tresponsiveAnimationDuration: 0,\n\t\t\tmaintainAspectRatio: true,\n\t\t\tevents: ['mousemove', 'mouseout', 'click', 'touchstart', 'touchmove'],\n\t\t\thover: {\n\t\t\t\tonHover: null,\n\t\t\t\tmode: 'nearest',\n\t\t\t\tintersect: true,\n\t\t\t\tanimationDuration: 400\n\t\t\t},\n\t\t\tonClick: null,\n\t\t\tdefaultColor: 'rgba(0,0,0,0.1)',\n\t\t\tdefaultFontColor: '#666',\n\t\t\tdefaultFontFamily: \"'Helvetica Neue', 'Helvetica', 'Arial', sans-serif\",\n\t\t\tdefaultFontSize: 12,\n\t\t\tdefaultFontStyle: 'normal',\n\t\t\tshowLines: true,\n\n\t\t\t// Element defaults defined in element extensions\n\t\t\telements: {},\n\n\t\t\t// Legend callback string\n\t\t\tlegendCallback: function(chart) {\n\t\t\t\tvar text = [];\n\t\t\t\ttext.push('<ul class=\"' + chart.id + '-legend\">');\n\t\t\t\tfor (var i = 0; i < chart.data.datasets.length; i++) {\n\t\t\t\t\ttext.push('<li><span style=\"background-color:' + chart.data.datasets[i].backgroundColor + '\"></span>');\n\t\t\t\t\tif (chart.data.datasets[i].label) {\n\t\t\t\t\t\ttext.push(chart.data.datasets[i].label);\n\t\t\t\t\t}\n\t\t\t\t\ttext.push('</li>');\n\t\t\t\t}\n\t\t\t\ttext.push('</ul>');\n\n\t\t\t\treturn text.join('');\n\t\t\t}\n\t\t}\n\t};\n\n\tChart.Chart = Chart;\n\n\treturn Chart;\n};\n\n},{}],29:[function(require,module,exports){\n'use strict';\n\nmodule.exports = function(Chart) {\n\n\tvar helpers = Chart.helpers;\n\n\tfunction filterByPosition(array, position) {\n\t\treturn helpers.where(array, function(v) {\n\t\t\treturn v.position === position;\n\t\t});\n\t}\n\n\tfunction sortByWeight(array, reverse) {\n\t\tarray.forEach(function(v, i) {\n\t\t\tv._tmpIndex_ = i;\n\t\t\treturn v;\n\t\t});\n\t\tarray.sort(function(a, b) {\n\t\t\tvar v0 = reverse ? b : a;\n\t\t\tvar v1 = reverse ? a : b;\n\t\t\treturn v0.weight === v1.weight ?\n\t\t\t\tv0._tmpIndex_ - v1._tmpIndex_ :\n\t\t\t\tv0.weight - v1.weight;\n\t\t});\n\t\tarray.forEach(function(v) {\n\t\t\tdelete v._tmpIndex_;\n\t\t});\n\t}\n\n\t/**\n\t * @interface ILayoutItem\n\t * @prop {String} position - The position of the item in the chart layout. Possible values are\n\t * 'left', 'top', 'right', 'bottom', and 'chartArea'\n\t * @prop {Number} weight - The weight used to sort the item. Higher weights are further away from the chart area\n\t * @prop {Boolean} fullWidth - if true, and the item is horizontal, then push vertical boxes down\n\t * @prop {Function} isHorizontal - returns true if the layout item is horizontal (ie. top or bottom)\n\t * @prop {Function} update - Takes two parameters: width and height. Returns size of item\n\t * @prop {Function} getPadding -  Returns an object with padding on the edges\n\t * @prop {Number} width - Width of item. Must be valid after update()\n\t * @prop {Number} height - Height of item. Must be valid after update()\n\t * @prop {Number} left - Left edge of the item. Set by layout system and cannot be used in update\n\t * @prop {Number} top - Top edge of the item. Set by layout system and cannot be used in update\n\t * @prop {Number} right - Right edge of the item. Set by layout system and cannot be used in update\n\t * @prop {Number} bottom - Bottom edge of the item. Set by layout system and cannot be used in update\n\t */\n\n\t// The layout service is very self explanatory.  It's responsible for the layout within a chart.\n\t// Scales, Legends and Plugins all rely on the layout service and can easily register to be placed anywhere they need\n\t// It is this service's responsibility of carrying out that layout.\n\tChart.layoutService = {\n\t\tdefaults: {},\n\n\t\t/**\n\t\t * Register a box to a chart.\n\t\t * A box is simply a reference to an object that requires layout. eg. Scales, Legend, Title.\n\t\t * @param {Chart} chart - the chart to use\n\t\t * @param {ILayoutItem} item - the item to add to be layed out\n\t\t */\n\t\taddBox: function(chart, item) {\n\t\t\tif (!chart.boxes) {\n\t\t\t\tchart.boxes = [];\n\t\t\t}\n\n\t\t\t// initialize item with default values\n\t\t\titem.fullWidth = item.fullWidth || false;\n\t\t\titem.position = item.position || 'top';\n\t\t\titem.weight = item.weight || 0;\n\n\t\t\tchart.boxes.push(item);\n\t\t},\n\n\t\t/**\n\t\t * Remove a layoutItem from a chart\n\t\t * @param {Chart} chart - the chart to remove the box from\n\t\t * @param {Object} layoutItem - the item to remove from the layout\n\t\t */\n\t\tremoveBox: function(chart, layoutItem) {\n\t\t\tvar index = chart.boxes? chart.boxes.indexOf(layoutItem) : -1;\n\t\t\tif (index !== -1) {\n\t\t\t\tchart.boxes.splice(index, 1);\n\t\t\t}\n\t\t},\n\n\t\t/**\n\t\t * Sets (or updates) options on the given `item`.\n\t\t * @param {Chart} chart - the chart in which the item lives (or will be added to)\n\t\t * @param {Object} item - the item to configure with the given options\n\t\t * @param {Object} options - the new item options.\n\t\t */\n\t\tconfigure: function(chart, item, options) {\n\t\t\tvar props = ['fullWidth', 'position', 'weight'];\n\t\t\tvar ilen = props.length;\n\t\t\tvar i = 0;\n\t\t\tvar prop;\n\n\t\t\tfor (; i<ilen; ++i) {\n\t\t\t\tprop = props[i];\n\t\t\t\tif (options.hasOwnProperty(prop)) {\n\t\t\t\t\titem[prop] = options[prop];\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\n\t\t/**\n\t\t * Fits boxes of the given chart into the given size by having each box measure itself\n\t\t * then running a fitting algorithm\n\t\t * @param {Chart} chart - the chart\n\t\t * @param {Number} width - the width to fit into\n\t\t * @param {Number} height - the height to fit into\n\t\t */\n\t\tupdate: function(chart, width, height) {\n\t\t\tif (!chart) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tvar layoutOptions = chart.options.layout;\n\t\t\tvar padding = layoutOptions ? layoutOptions.padding : null;\n\n\t\t\tvar leftPadding = 0;\n\t\t\tvar rightPadding = 0;\n\t\t\tvar topPadding = 0;\n\t\t\tvar bottomPadding = 0;\n\n\t\t\tif (!isNaN(padding)) {\n\t\t\t\t// options.layout.padding is a number. assign to all\n\t\t\t\tleftPadding = padding;\n\t\t\t\trightPadding = padding;\n\t\t\t\ttopPadding = padding;\n\t\t\t\tbottomPadding = padding;\n\t\t\t} else {\n\t\t\t\tleftPadding = padding.left || 0;\n\t\t\t\trightPadding = padding.right || 0;\n\t\t\t\ttopPadding = padding.top || 0;\n\t\t\t\tbottomPadding = padding.bottom || 0;\n\t\t\t}\n\n\t\t\tvar leftBoxes = filterByPosition(chart.boxes, 'left');\n\t\t\tvar rightBoxes = filterByPosition(chart.boxes, 'right');\n\t\t\tvar topBoxes = filterByPosition(chart.boxes, 'top');\n\t\t\tvar bottomBoxes = filterByPosition(chart.boxes, 'bottom');\n\t\t\tvar chartAreaBoxes = filterByPosition(chart.boxes, 'chartArea');\n\n\t\t\t// Sort boxes by weight. A higher weight is further away from the chart area\n\t\t\tsortByWeight(leftBoxes, true);\n\t\t\tsortByWeight(rightBoxes, false);\n\t\t\tsortByWeight(topBoxes, true);\n\t\t\tsortByWeight(bottomBoxes, false);\n\n\t\t\t// Essentially we now have any number of boxes on each of the 4 sides.\n\t\t\t// Our canvas looks like the following.\n\t\t\t// The areas L1 and L2 are the left axes. R1 is the right axis, T1 is the top axis and\n\t\t\t// B1 is the bottom axis\n\t\t\t// There are also 4 quadrant-like locations (left to right instead of clockwise) reserved for chart overlays\n\t\t\t// These locations are single-box locations only, when trying to register a chartArea location that is already taken,\n\t\t\t// an error will be thrown.\n\t\t\t//\n\t\t\t// |----------------------------------------------------|\n\t\t\t// |                  T1 (Full Width)                   |\n\t\t\t// |----------------------------------------------------|\n\t\t\t// |    |    |                 T2                  |    |\n\t\t\t// |    |----|-------------------------------------|----|\n\t\t\t// |    |    | C1 |                           | C2 |    |\n\t\t\t// |    |    |----|                           |----|    |\n\t\t\t// |    |    |                                     |    |\n\t\t\t// | L1 | L2 |           ChartArea (C0)            | R1 |\n\t\t\t// |    |    |                                     |    |\n\t\t\t// |    |    |----|                           |----|    |\n\t\t\t// |    |    | C3 |                           | C4 |    |\n\t\t\t// |    |----|-------------------------------------|----|\n\t\t\t// |    |    |                 B1                  |    |\n\t\t\t// |----------------------------------------------------|\n\t\t\t// |                  B2 (Full Width)                   |\n\t\t\t// |----------------------------------------------------|\n\t\t\t//\n\t\t\t// What we do to find the best sizing, we do the following\n\t\t\t// 1. Determine the minimum size of the chart area.\n\t\t\t// 2. Split the remaining width equally between each vertical axis\n\t\t\t// 3. Split the remaining height equally between each horizontal axis\n\t\t\t// 4. Give each layout the maximum size it can be. The layout will return it's minimum size\n\t\t\t// 5. Adjust the sizes of each axis based on it's minimum reported size.\n\t\t\t// 6. Refit each axis\n\t\t\t// 7. Position each axis in the final location\n\t\t\t// 8. Tell the chart the final location of the chart area\n\t\t\t// 9. Tell any axes that overlay the chart area the positions of the chart area\n\n\t\t\t// Step 1\n\t\t\tvar chartWidth = width - leftPadding - rightPadding;\n\t\t\tvar chartHeight = height - topPadding - bottomPadding;\n\t\t\tvar chartAreaWidth = chartWidth / 2; // min 50%\n\t\t\tvar chartAreaHeight = chartHeight / 2; // min 50%\n\n\t\t\t// Step 2\n\t\t\tvar verticalBoxWidth = (width - chartAreaWidth) / (leftBoxes.length + rightBoxes.length);\n\n\t\t\t// Step 3\n\t\t\tvar horizontalBoxHeight = (height - chartAreaHeight) / (topBoxes.length + bottomBoxes.length);\n\n\t\t\t// Step 4\n\t\t\tvar maxChartAreaWidth = chartWidth;\n\t\t\tvar maxChartAreaHeight = chartHeight;\n\t\t\tvar minBoxSizes = [];\n\n\t\t\tfunction getMinimumBoxSize(box) {\n\t\t\t\tvar minSize;\n\t\t\t\tvar isHorizontal = box.isHorizontal();\n\n\t\t\t\tif (isHorizontal) {\n\t\t\t\t\tminSize = box.update(box.fullWidth ? chartWidth : maxChartAreaWidth, horizontalBoxHeight);\n\t\t\t\t\tmaxChartAreaHeight -= minSize.height;\n\t\t\t\t} else {\n\t\t\t\t\tminSize = box.update(verticalBoxWidth, chartAreaHeight);\n\t\t\t\t\tmaxChartAreaWidth -= minSize.width;\n\t\t\t\t}\n\n\t\t\t\tminBoxSizes.push({\n\t\t\t\t\thorizontal: isHorizontal,\n\t\t\t\t\tminSize: minSize,\n\t\t\t\t\tbox: box,\n\t\t\t\t});\n\t\t\t}\n\n\t\t\thelpers.each(leftBoxes.concat(rightBoxes, topBoxes, bottomBoxes), getMinimumBoxSize);\n\n\t\t\t// If a horizontal box has padding, we move the left boxes over to avoid ugly charts (see issue #2478)\n\t\t\tvar maxHorizontalLeftPadding = 0;\n\t\t\tvar maxHorizontalRightPadding = 0;\n\t\t\tvar maxVerticalTopPadding = 0;\n\t\t\tvar maxVerticalBottomPadding = 0;\n\n\t\t\thelpers.each(topBoxes.concat(bottomBoxes), function(horizontalBox) {\n\t\t\t\tif (horizontalBox.getPadding) {\n\t\t\t\t\tvar boxPadding = horizontalBox.getPadding();\n\t\t\t\t\tmaxHorizontalLeftPadding = Math.max(maxHorizontalLeftPadding, boxPadding.left);\n\t\t\t\t\tmaxHorizontalRightPadding = Math.max(maxHorizontalRightPadding, boxPadding.right);\n\t\t\t\t}\n\t\t\t});\n\n\t\t\thelpers.each(leftBoxes.concat(rightBoxes), function(verticalBox) {\n\t\t\t\tif (verticalBox.getPadding) {\n\t\t\t\t\tvar boxPadding = verticalBox.getPadding();\n\t\t\t\t\tmaxVerticalTopPadding = Math.max(maxVerticalTopPadding, boxPadding.top);\n\t\t\t\t\tmaxVerticalBottomPadding = Math.max(maxVerticalBottomPadding, boxPadding.bottom);\n\t\t\t\t}\n\t\t\t});\n\n\t\t\t// At this point, maxChartAreaHeight and maxChartAreaWidth are the size the chart area could\n\t\t\t// be if the axes are drawn at their minimum sizes.\n\t\t\t// Steps 5 & 6\n\t\t\tvar totalLeftBoxesWidth = leftPadding;\n\t\t\tvar totalRightBoxesWidth = rightPadding;\n\t\t\tvar totalTopBoxesHeight = topPadding;\n\t\t\tvar totalBottomBoxesHeight = bottomPadding;\n\n\t\t\t// Function to fit a box\n\t\t\tfunction fitBox(box) {\n\t\t\t\tvar minBoxSize = helpers.findNextWhere(minBoxSizes, function(minBox) {\n\t\t\t\t\treturn minBox.box === box;\n\t\t\t\t});\n\n\t\t\t\tif (minBoxSize) {\n\t\t\t\t\tif (box.isHorizontal()) {\n\t\t\t\t\t\tvar scaleMargin = {\n\t\t\t\t\t\t\tleft: Math.max(totalLeftBoxesWidth, maxHorizontalLeftPadding),\n\t\t\t\t\t\t\tright: Math.max(totalRightBoxesWidth, maxHorizontalRightPadding),\n\t\t\t\t\t\t\ttop: 0,\n\t\t\t\t\t\t\tbottom: 0\n\t\t\t\t\t\t};\n\n\t\t\t\t\t\t// Don't use min size here because of label rotation. When the labels are rotated, their rotation highly depends\n\t\t\t\t\t\t// on the margin. Sometimes they need to increase in size slightly\n\t\t\t\t\t\tbox.update(box.fullWidth ? chartWidth : maxChartAreaWidth, chartHeight / 2, scaleMargin);\n\t\t\t\t\t} else {\n\t\t\t\t\t\tbox.update(minBoxSize.minSize.width, maxChartAreaHeight);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Update, and calculate the left and right margins for the horizontal boxes\n\t\t\thelpers.each(leftBoxes.concat(rightBoxes), fitBox);\n\n\t\t\thelpers.each(leftBoxes, function(box) {\n\t\t\t\ttotalLeftBoxesWidth += box.width;\n\t\t\t});\n\n\t\t\thelpers.each(rightBoxes, function(box) {\n\t\t\t\ttotalRightBoxesWidth += box.width;\n\t\t\t});\n\n\t\t\t// Set the Left and Right margins for the horizontal boxes\n\t\t\thelpers.each(topBoxes.concat(bottomBoxes), fitBox);\n\n\t\t\t// Figure out how much margin is on the top and bottom of the vertical boxes\n\t\t\thelpers.each(topBoxes, function(box) {\n\t\t\t\ttotalTopBoxesHeight += box.height;\n\t\t\t});\n\n\t\t\thelpers.each(bottomBoxes, function(box) {\n\t\t\t\ttotalBottomBoxesHeight += box.height;\n\t\t\t});\n\n\t\t\tfunction finalFitVerticalBox(box) {\n\t\t\t\tvar minBoxSize = helpers.findNextWhere(minBoxSizes, function(minSize) {\n\t\t\t\t\treturn minSize.box === box;\n\t\t\t\t});\n\n\t\t\t\tvar scaleMargin = {\n\t\t\t\t\tleft: 0,\n\t\t\t\t\tright: 0,\n\t\t\t\t\ttop: totalTopBoxesHeight,\n\t\t\t\t\tbottom: totalBottomBoxesHeight\n\t\t\t\t};\n\n\t\t\t\tif (minBoxSize) {\n\t\t\t\t\tbox.update(minBoxSize.minSize.width, maxChartAreaHeight, scaleMargin);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Let the left layout know the final margin\n\t\t\thelpers.each(leftBoxes.concat(rightBoxes), finalFitVerticalBox);\n\n\t\t\t// Recalculate because the size of each layout might have changed slightly due to the margins (label rotation for instance)\n\t\t\ttotalLeftBoxesWidth = leftPadding;\n\t\t\ttotalRightBoxesWidth = rightPadding;\n\t\t\ttotalTopBoxesHeight = topPadding;\n\t\t\ttotalBottomBoxesHeight = bottomPadding;\n\n\t\t\thelpers.each(leftBoxes, function(box) {\n\t\t\t\ttotalLeftBoxesWidth += box.width;\n\t\t\t});\n\n\t\t\thelpers.each(rightBoxes, function(box) {\n\t\t\t\ttotalRightBoxesWidth += box.width;\n\t\t\t});\n\n\t\t\thelpers.each(topBoxes, function(box) {\n\t\t\t\ttotalTopBoxesHeight += box.height;\n\t\t\t});\n\t\t\thelpers.each(bottomBoxes, function(box) {\n\t\t\t\ttotalBottomBoxesHeight += box.height;\n\t\t\t});\n\n\t\t\t// We may be adding some padding to account for rotated x axis labels\n\t\t\tvar leftPaddingAddition = Math.max(maxHorizontalLeftPadding - totalLeftBoxesWidth, 0);\n\t\t\ttotalLeftBoxesWidth += leftPaddingAddition;\n\t\t\ttotalRightBoxesWidth += Math.max(maxHorizontalRightPadding - totalRightBoxesWidth, 0);\n\n\t\t\tvar topPaddingAddition = Math.max(maxVerticalTopPadding - totalTopBoxesHeight, 0);\n\t\t\ttotalTopBoxesHeight += topPaddingAddition;\n\t\t\ttotalBottomBoxesHeight += Math.max(maxVerticalBottomPadding - totalBottomBoxesHeight, 0);\n\n\t\t\t// Figure out if our chart area changed. This would occur if the dataset layout label rotation\n\t\t\t// changed due to the application of the margins in step 6. Since we can only get bigger, this is safe to do\n\t\t\t// without calling `fit` again\n\t\t\tvar newMaxChartAreaHeight = height - totalTopBoxesHeight - totalBottomBoxesHeight;\n\t\t\tvar newMaxChartAreaWidth = width - totalLeftBoxesWidth - totalRightBoxesWidth;\n\n\t\t\tif (newMaxChartAreaWidth !== maxChartAreaWidth || newMaxChartAreaHeight !== maxChartAreaHeight) {\n\t\t\t\thelpers.each(leftBoxes, function(box) {\n\t\t\t\t\tbox.height = newMaxChartAreaHeight;\n\t\t\t\t});\n\n\t\t\t\thelpers.each(rightBoxes, function(box) {\n\t\t\t\t\tbox.height = newMaxChartAreaHeight;\n\t\t\t\t});\n\n\t\t\t\thelpers.each(topBoxes, function(box) {\n\t\t\t\t\tif (!box.fullWidth) {\n\t\t\t\t\t\tbox.width = newMaxChartAreaWidth;\n\t\t\t\t\t}\n\t\t\t\t});\n\n\t\t\t\thelpers.each(bottomBoxes, function(box) {\n\t\t\t\t\tif (!box.fullWidth) {\n\t\t\t\t\t\tbox.width = newMaxChartAreaWidth;\n\t\t\t\t\t}\n\t\t\t\t});\n\n\t\t\t\tmaxChartAreaHeight = newMaxChartAreaHeight;\n\t\t\t\tmaxChartAreaWidth = newMaxChartAreaWidth;\n\t\t\t}\n\n\t\t\t// Step 7 - Position the boxes\n\t\t\tvar left = leftPadding + leftPaddingAddition;\n\t\t\tvar top = topPadding + topPaddingAddition;\n\n\t\t\tfunction placeBox(box) {\n\t\t\t\tif (box.isHorizontal()) {\n\t\t\t\t\tbox.left = box.fullWidth ? leftPadding : totalLeftBoxesWidth;\n\t\t\t\t\tbox.right = box.fullWidth ? width - rightPadding : totalLeftBoxesWidth + maxChartAreaWidth;\n\t\t\t\t\tbox.top = top;\n\t\t\t\t\tbox.bottom = top + box.height;\n\n\t\t\t\t\t// Move to next point\n\t\t\t\t\ttop = box.bottom;\n\n\t\t\t\t} else {\n\n\t\t\t\t\tbox.left = left;\n\t\t\t\t\tbox.right = left + box.width;\n\t\t\t\t\tbox.top = totalTopBoxesHeight;\n\t\t\t\t\tbox.bottom = totalTopBoxesHeight + maxChartAreaHeight;\n\n\t\t\t\t\t// Move to next point\n\t\t\t\t\tleft = box.right;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\thelpers.each(leftBoxes.concat(topBoxes), placeBox);\n\n\t\t\t// Account for chart width and height\n\t\t\tleft += maxChartAreaWidth;\n\t\t\ttop += maxChartAreaHeight;\n\n\t\t\thelpers.each(rightBoxes, placeBox);\n\t\t\thelpers.each(bottomBoxes, placeBox);\n\n\t\t\t// Step 8\n\t\t\tchart.chartArea = {\n\t\t\t\tleft: totalLeftBoxesWidth,\n\t\t\t\ttop: totalTopBoxesHeight,\n\t\t\t\tright: totalLeftBoxesWidth + maxChartAreaWidth,\n\t\t\t\tbottom: totalTopBoxesHeight + maxChartAreaHeight\n\t\t\t};\n\n\t\t\t// Step 9\n\t\t\thelpers.each(chartAreaBoxes, function(box) {\n\t\t\t\tbox.left = chart.chartArea.left;\n\t\t\t\tbox.top = chart.chartArea.top;\n\t\t\t\tbox.right = chart.chartArea.right;\n\t\t\t\tbox.bottom = chart.chartArea.bottom;\n\n\t\t\t\tbox.update(maxChartAreaWidth, maxChartAreaHeight);\n\t\t\t});\n\t\t}\n\t};\n};\n\n},{}],30:[function(require,module,exports){\n'use strict';\n\nmodule.exports = function(Chart) {\n\n\tvar helpers = Chart.helpers;\n\n\tChart.defaults.global.plugins = {};\n\n\t/**\n\t * The plugin service singleton\n\t * @namespace Chart.plugins\n\t * @since 2.1.0\n\t */\n\tChart.plugins = {\n\t\t/**\n\t\t * Globally registered plugins.\n\t\t * @private\n\t\t */\n\t\t_plugins: [],\n\n\t\t/**\n\t\t * This identifier is used to invalidate the descriptors cache attached to each chart\n\t\t * when a global plugin is registered or unregistered. In this case, the cache ID is\n\t\t * incremented and descriptors are regenerated during following API calls.\n\t\t * @private\n\t\t */\n\t\t_cacheId: 0,\n\n\t\t/**\n\t\t * Registers the given plugin(s) if not already registered.\n\t\t * @param {Array|Object} plugins plugin instance(s).\n\t\t */\n\t\tregister: function(plugins) {\n\t\t\tvar p = this._plugins;\n\t\t\t([]).concat(plugins).forEach(function(plugin) {\n\t\t\t\tif (p.indexOf(plugin) === -1) {\n\t\t\t\t\tp.push(plugin);\n\t\t\t\t}\n\t\t\t});\n\n\t\t\tthis._cacheId++;\n\t\t},\n\n\t\t/**\n\t\t * Unregisters the given plugin(s) only if registered.\n\t\t * @param {Array|Object} plugins plugin instance(s).\n\t\t */\n\t\tunregister: function(plugins) {\n\t\t\tvar p = this._plugins;\n\t\t\t([]).concat(plugins).forEach(function(plugin) {\n\t\t\t\tvar idx = p.indexOf(plugin);\n\t\t\t\tif (idx !== -1) {\n\t\t\t\t\tp.splice(idx, 1);\n\t\t\t\t}\n\t\t\t});\n\n\t\t\tthis._cacheId++;\n\t\t},\n\n\t\t/**\n\t\t * Remove all registered plugins.\n\t\t * @since 2.1.5\n\t\t */\n\t\tclear: function() {\n\t\t\tthis._plugins = [];\n\t\t\tthis._cacheId++;\n\t\t},\n\n\t\t/**\n\t\t * Returns the number of registered plugins?\n\t\t * @returns {Number}\n\t\t * @since 2.1.5\n\t\t */\n\t\tcount: function() {\n\t\t\treturn this._plugins.length;\n\t\t},\n\n\t\t/**\n\t\t * Returns all registered plugin instances.\n\t\t * @returns {Array} array of plugin objects.\n\t\t * @since 2.1.5\n\t\t */\n\t\tgetAll: function() {\n\t\t\treturn this._plugins;\n\t\t},\n\n\t\t/**\n\t\t * Calls enabled plugins for `chart` on the specified hook and with the given args.\n\t\t * This method immediately returns as soon as a plugin explicitly returns false. The\n\t\t * returned value can be used, for instance, to interrupt the current action.\n\t\t * @param {Object} chart - The chart instance for which plugins should be called.\n\t\t * @param {String} hook - The name of the plugin method to call (e.g. 'beforeUpdate').\n\t\t * @param {Array} [args] - Extra arguments to apply to the hook call.\n\t\t * @returns {Boolean} false if any of the plugins return false, else returns true.\n\t\t */\n\t\tnotify: function(chart, hook, args) {\n\t\t\tvar descriptors = this.descriptors(chart);\n\t\t\tvar ilen = descriptors.length;\n\t\t\tvar i, descriptor, plugin, params, method;\n\n\t\t\tfor (i=0; i<ilen; ++i) {\n\t\t\t\tdescriptor = descriptors[i];\n\t\t\t\tplugin = descriptor.plugin;\n\t\t\t\tmethod = plugin[hook];\n\t\t\t\tif (typeof method === 'function') {\n\t\t\t\t\tparams = [chart].concat(args || []);\n\t\t\t\t\tparams.push(descriptor.options);\n\t\t\t\t\tif (method.apply(plugin, params) === false) {\n\t\t\t\t\t\treturn false;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn true;\n\t\t},\n\n\t\t/**\n\t\t * Returns descriptors of enabled plugins for the given chart.\n\t\t * @returns {Array} [{ plugin, options }]\n\t\t * @private\n\t\t */\n\t\tdescriptors: function(chart) {\n\t\t\tvar cache = chart._plugins || (chart._plugins = {});\n\t\t\tif (cache.id === this._cacheId) {\n\t\t\t\treturn cache.descriptors;\n\t\t\t}\n\n\t\t\tvar plugins = [];\n\t\t\tvar descriptors = [];\n\t\t\tvar config = (chart && chart.config) || {};\n\t\t\tvar defaults = Chart.defaults.global.plugins;\n\t\t\tvar options = (config.options && config.options.plugins) || {};\n\n\t\t\tthis._plugins.concat(config.plugins || []).forEach(function(plugin) {\n\t\t\t\tvar idx = plugins.indexOf(plugin);\n\t\t\t\tif (idx !== -1) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tvar id = plugin.id;\n\t\t\t\tvar opts = options[id];\n\t\t\t\tif (opts === false) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tif (opts === true) {\n\t\t\t\t\topts = helpers.clone(defaults[id]);\n\t\t\t\t}\n\n\t\t\t\tplugins.push(plugin);\n\t\t\t\tdescriptors.push({\n\t\t\t\t\tplugin: plugin,\n\t\t\t\t\toptions: opts || {}\n\t\t\t\t});\n\t\t\t});\n\n\t\t\tcache.descriptors = descriptors;\n\t\t\tcache.id = this._cacheId;\n\t\t\treturn descriptors;\n\t\t}\n\t};\n\n\t/**\n\t * Plugin extension hooks.\n\t * @interface IPlugin\n\t * @since 2.1.0\n\t */\n\t/**\n\t * @method IPlugin#beforeInit\n\t * @desc Called before initializing `chart`.\n\t * @param {Chart.Controller} chart - The chart instance.\n\t * @param {Object} options - The plugin options.\n\t */\n\t/**\n\t * @method IPlugin#afterInit\n\t * @desc Called after `chart` has been initialized and before the first update.\n\t * @param {Chart.Controller} chart - The chart instance.\n\t * @param {Object} options - The plugin options.\n\t */\n\t/**\n\t * @method IPlugin#beforeUpdate\n\t * @desc Called before updating `chart`. If any plugin returns `false`, the update\n\t * is cancelled (and thus subsequent render(s)) until another `update` is triggered.\n\t * @param {Chart.Controller} chart - The chart instance.\n\t * @param {Object} options - The plugin options.\n\t * @returns {Boolean} `false` to cancel the chart update.\n\t */\n\t/**\n\t * @method IPlugin#afterUpdate\n\t * @desc Called after `chart` has been updated and before rendering. Note that this\n\t * hook will not be called if the chart update has been previously cancelled.\n\t * @param {Chart.Controller} chart - The chart instance.\n\t * @param {Object} options - The plugin options.\n\t */\n\t/**\n\t * @method IPlugin#beforeDatasetsUpdate\n \t * @desc Called before updating the `chart` datasets. If any plugin returns `false`,\n\t * the datasets update is cancelled until another `update` is triggered.\n\t * @param {Chart.Controller} chart - The chart instance.\n\t * @param {Object} options - The plugin options.\n\t * @returns {Boolean} false to cancel the datasets update.\n\t * @since version 2.1.5\n\t */\n\t/**\n\t * @method IPlugin#afterDatasetsUpdate\n\t * @desc Called after the `chart` datasets have been updated. Note that this hook\n\t * will not be called if the datasets update has been previously cancelled.\n\t * @param {Chart.Controller} chart - The chart instance.\n\t * @param {Object} options - The plugin options.\n\t * @since version 2.1.5\n\t */\n\t/**\n\t * @method IPlugin#beforeDatasetUpdate\n \t * @desc Called before updating the `chart` dataset at the given `args.index`. If any plugin\n\t * returns `false`, the datasets update is cancelled until another `update` is triggered.\n\t * @param {Chart} chart - The chart instance.\n\t * @param {Object} args - The call arguments.\n\t * @param {Object} args.index - The dataset index.\n\t * @param {Number} args.meta - The dataset metadata.\n\t * @param {Object} options - The plugin options.\n\t * @returns {Boolean} `false` to cancel the chart datasets drawing.\n\t */\n\t/**\n\t * @method IPlugin#afterDatasetUpdate\n \t * @desc Called after the `chart` datasets at the given `args.index` has been updated. Note\n\t * that this hook will not be called if the datasets update has been previously cancelled.\n\t * @param {Chart} chart - The chart instance.\n\t * @param {Object} args - The call arguments.\n\t * @param {Object} args.index - The dataset index.\n\t * @param {Number} args.meta - The dataset metadata.\n\t * @param {Object} options - The plugin options.\n\t */\n\t/**\n\t * @method IPlugin#beforeLayout\n\t * @desc Called before laying out `chart`. If any plugin returns `false`,\n\t * the layout update is cancelled until another `update` is triggered.\n\t * @param {Chart.Controller} chart - The chart instance.\n\t * @param {Object} options - The plugin options.\n\t * @returns {Boolean} `false` to cancel the chart layout.\n\t */\n\t/**\n\t * @method IPlugin#afterLayout\n\t * @desc Called after the `chart` has been layed out. Note that this hook will not\n\t * be called if the layout update has been previously cancelled.\n\t * @param {Chart.Controller} chart - The chart instance.\n\t * @param {Object} options - The plugin options.\n\t */\n\t/**\n\t * @method IPlugin#beforeRender\n\t * @desc Called before rendering `chart`. If any plugin returns `false`,\n\t * the rendering is cancelled until another `render` is triggered.\n\t * @param {Chart.Controller} chart - The chart instance.\n\t * @param {Object} options - The plugin options.\n\t * @returns {Boolean} `false` to cancel the chart rendering.\n\t */\n\t/**\n\t * @method IPlugin#afterRender\n\t * @desc Called after the `chart` has been fully rendered (and animation completed). Note\n\t * that this hook will not be called if the rendering has been previously cancelled.\n\t * @param {Chart.Controller} chart - The chart instance.\n\t * @param {Object} options - The plugin options.\n\t */\n\t/**\n\t * @method IPlugin#beforeDraw\n\t * @desc Called before drawing `chart` at every animation frame specified by the given\n\t * easing value. If any plugin returns `false`, the frame drawing is cancelled until\n\t * another `render` is triggered.\n\t * @param {Chart.Controller} chart - The chart instance.\n\t * @param {Number} easingValue - The current animation value, between 0.0 and 1.0.\n\t * @param {Object} options - The plugin options.\n\t * @returns {Boolean} `false` to cancel the chart drawing.\n\t */\n\t/**\n\t * @method IPlugin#afterDraw\n\t * @desc Called after the `chart` has been drawn for the specific easing value. Note\n\t * that this hook will not be called if the drawing has been previously cancelled.\n\t * @param {Chart.Controller} chart - The chart instance.\n\t * @param {Number} easingValue - The current animation value, between 0.0 and 1.0.\n\t * @param {Object} options - The plugin options.\n\t */\n\t/**\n\t * @method IPlugin#beforeDatasetsDraw\n \t * @desc Called before drawing the `chart` datasets. If any plugin returns `false`,\n\t * the datasets drawing is cancelled until another `render` is triggered.\n\t * @param {Chart.Controller} chart - The chart instance.\n\t * @param {Number} easingValue - The current animation value, between 0.0 and 1.0.\n\t * @param {Object} options - The plugin options.\n\t * @returns {Boolean} `false` to cancel the chart datasets drawing.\n\t */\n\t/**\n\t * @method IPlugin#afterDatasetsDraw\n\t * @desc Called after the `chart` datasets have been drawn. Note that this hook\n\t * will not be called if the datasets drawing has been previously cancelled.\n\t * @param {Chart.Controller} chart - The chart instance.\n\t * @param {Number} easingValue - The current animation value, between 0.0 and 1.0.\n\t * @param {Object} options - The plugin options.\n\t */\n\t/**\n\t * @method IPlugin#beforeDatasetDraw\n \t * @desc Called before drawing the `chart` dataset at the given `args.index` (datasets\n\t * are drawn in the reverse order). If any plugin returns `false`, the datasets drawing\n\t * is cancelled until another `render` is triggered.\n\t * @param {Chart} chart - The chart instance.\n\t * @param {Object} args - The call arguments.\n\t * @param {Object} args.index - The dataset index.\n\t * @param {Number} args.meta - The dataset metadata.\n\t * @param {Number} args.easingValue - The current animation value, between 0.0 and 1.0.\n\t * @param {Object} options - The plugin options.\n\t * @returns {Boolean} `false` to cancel the chart datasets drawing.\n\t */\n\t/**\n\t * @method IPlugin#afterDatasetDraw\n \t * @desc Called after the `chart` datasets at the given `args.index` have been drawn\n\t * (datasets are drawn in the reverse order). Note that this hook will not be called\n\t * if the datasets drawing has been previously cancelled.\n\t * @param {Chart} chart - The chart instance.\n\t * @param {Object} args - The call arguments.\n\t * @param {Object} args.index - The dataset index.\n\t * @param {Number} args.meta - The dataset metadata.\n\t * @param {Number} args.easingValue - The current animation value, between 0.0 and 1.0.\n\t * @param {Object} options - The plugin options.\n\t */\n\t/**\n\t * @method IPlugin#beforeEvent\n \t * @desc Called before processing the specified `event`. If any plugin returns `false`,\n\t * the event will be discarded.\n\t * @param {Chart.Controller} chart - The chart instance.\n\t * @param {IEvent} event - The event object.\n\t * @param {Object} options - The plugin options.\n\t */\n\t/**\n\t * @method IPlugin#afterEvent\n\t * @desc Called after the `event` has been consumed. Note that this hook\n\t * will not be called if the `event` has been previously discarded.\n\t * @param {Chart.Controller} chart - The chart instance.\n\t * @param {IEvent} event - The event object.\n\t * @param {Object} options - The plugin options.\n\t */\n\t/**\n\t * @method IPlugin#resize\n\t * @desc Called after the chart as been resized.\n\t * @param {Chart.Controller} chart - The chart instance.\n\t * @param {Number} size - The new canvas display size (eq. canvas.style width & height).\n\t * @param {Object} options - The plugin options.\n\t */\n\t/**\n\t * @method IPlugin#destroy\n\t * @desc Called after the chart as been destroyed.\n\t * @param {Chart.Controller} chart - The chart instance.\n\t * @param {Object} options - The plugin options.\n\t */\n\n\t/**\n\t * Provided for backward compatibility, use Chart.plugins instead\n\t * @namespace Chart.pluginService\n\t * @deprecated since version 2.1.5\n\t * @todo remove at version 3\n\t * @private\n\t */\n\tChart.pluginService = Chart.plugins;\n\n\t/**\n\t * Provided for backward compatibility, inheriting from Chart.PlugingBase has no\n\t * effect, instead simply create/register plugins via plain JavaScript objects.\n\t * @interface Chart.PluginBase\n\t * @deprecated since version 2.5.0\n\t * @todo remove at version 3\n\t * @private\n\t */\n\tChart.PluginBase = Chart.Element.extend({});\n};\n\n},{}],31:[function(require,module,exports){\n'use strict';\n\nmodule.exports = function(Chart) {\n\n\tvar helpers = Chart.helpers;\n\n\tChart.defaults.scale = {\n\t\tdisplay: true,\n\t\tposition: 'left',\n\n\t\t// grid line settings\n\t\tgridLines: {\n\t\t\tdisplay: true,\n\t\t\tcolor: 'rgba(0, 0, 0, 0.1)',\n\t\t\tlineWidth: 1,\n\t\t\tdrawBorder: true,\n\t\t\tdrawOnChartArea: true,\n\t\t\tdrawTicks: true,\n\t\t\ttickMarkLength: 10,\n\t\t\tzeroLineWidth: 1,\n\t\t\tzeroLineColor: 'rgba(0,0,0,0.25)',\n\t\t\tzeroLineBorderDash: [],\n\t\t\tzeroLineBorderDashOffset: 0.0,\n\t\t\toffsetGridLines: false,\n\t\t\tborderDash: [],\n\t\t\tborderDashOffset: 0.0\n\t\t},\n\n\t\t// scale label\n\t\tscaleLabel: {\n\t\t\t// actual label\n\t\t\tlabelString: '',\n\n\t\t\t// display property\n\t\t\tdisplay: false\n\t\t},\n\n\t\t// label settings\n\t\tticks: {\n\t\t\tbeginAtZero: false,\n\t\t\tminRotation: 0,\n\t\t\tmaxRotation: 50,\n\t\t\tmirror: false,\n\t\t\tpadding: 0,\n\t\t\treverse: false,\n\t\t\tdisplay: true,\n\t\t\tautoSkip: true,\n\t\t\tautoSkipPadding: 0,\n\t\t\tlabelOffset: 0,\n\t\t\t// We pass through arrays to be rendered as multiline labels, we convert Others to strings here.\n\t\t\tcallback: Chart.Ticks.formatters.values\n\t\t}\n\t};\n\n\tfunction computeTextSize(context, tick, font) {\n\t\treturn helpers.isArray(tick) ?\n\t\t\thelpers.longestText(context, font, tick) :\n\t\t\tcontext.measureText(tick).width;\n\t}\n\n\tfunction parseFontOptions(options) {\n\t\tvar getValueOrDefault = helpers.getValueOrDefault;\n\t\tvar globalDefaults = Chart.defaults.global;\n\t\tvar size = getValueOrDefault(options.fontSize, globalDefaults.defaultFontSize);\n\t\tvar style = getValueOrDefault(options.fontStyle, globalDefaults.defaultFontStyle);\n\t\tvar family = getValueOrDefault(options.fontFamily, globalDefaults.defaultFontFamily);\n\n\t\treturn {\n\t\t\tsize: size,\n\t\t\tstyle: style,\n\t\t\tfamily: family,\n\t\t\tfont: helpers.fontString(size, style, family)\n\t\t};\n\t}\n\n\tChart.Scale = Chart.Element.extend({\n\t\t/**\n\t\t * Get the padding needed for the scale\n\t\t * @method getPadding\n\t\t * @private\n\t\t * @returns {Padding} the necessary padding\n\t\t */\n\t\tgetPadding: function() {\n\t\t\tvar me = this;\n\t\t\treturn {\n\t\t\t\tleft: me.paddingLeft || 0,\n\t\t\t\ttop: me.paddingTop || 0,\n\t\t\t\tright: me.paddingRight || 0,\n\t\t\t\tbottom: me.paddingBottom || 0\n\t\t\t};\n\t\t},\n\n\t\t// These methods are ordered by lifecyle. Utilities then follow.\n\t\t// Any function defined here is inherited by all scale types.\n\t\t// Any function can be extended by the scale type\n\n\t\tbeforeUpdate: function() {\n\t\t\thelpers.callback(this.options.beforeUpdate, [this]);\n\t\t},\n\t\tupdate: function(maxWidth, maxHeight, margins) {\n\t\t\tvar me = this;\n\n\t\t\t// Update Lifecycle - Probably don't want to ever extend or overwrite this function ;)\n\t\t\tme.beforeUpdate();\n\n\t\t\t// Absorb the master measurements\n\t\t\tme.maxWidth = maxWidth;\n\t\t\tme.maxHeight = maxHeight;\n\t\t\tme.margins = helpers.extend({\n\t\t\t\tleft: 0,\n\t\t\t\tright: 0,\n\t\t\t\ttop: 0,\n\t\t\t\tbottom: 0\n\t\t\t}, margins);\n\t\t\tme.longestTextCache = me.longestTextCache || {};\n\n\t\t\t// Dimensions\n\t\t\tme.beforeSetDimensions();\n\t\t\tme.setDimensions();\n\t\t\tme.afterSetDimensions();\n\n\t\t\t// Data min/max\n\t\t\tme.beforeDataLimits();\n\t\t\tme.determineDataLimits();\n\t\t\tme.afterDataLimits();\n\n\t\t\t// Ticks\n\t\t\tme.beforeBuildTicks();\n\t\t\tme.buildTicks();\n\t\t\tme.afterBuildTicks();\n\n\t\t\tme.beforeTickToLabelConversion();\n\t\t\tme.convertTicksToLabels();\n\t\t\tme.afterTickToLabelConversion();\n\n\t\t\t// Tick Rotation\n\t\t\tme.beforeCalculateTickRotation();\n\t\t\tme.calculateTickRotation();\n\t\t\tme.afterCalculateTickRotation();\n\t\t\t// Fit\n\t\t\tme.beforeFit();\n\t\t\tme.fit();\n\t\t\tme.afterFit();\n\t\t\t//\n\t\t\tme.afterUpdate();\n\n\t\t\treturn me.minSize;\n\n\t\t},\n\t\tafterUpdate: function() {\n\t\t\thelpers.callback(this.options.afterUpdate, [this]);\n\t\t},\n\n\t\t//\n\n\t\tbeforeSetDimensions: function() {\n\t\t\thelpers.callback(this.options.beforeSetDimensions, [this]);\n\t\t},\n\t\tsetDimensions: function() {\n\t\t\tvar me = this;\n\t\t\t// Set the unconstrained dimension before label rotation\n\t\t\tif (me.isHorizontal()) {\n\t\t\t\t// Reset position before calculating rotation\n\t\t\t\tme.width = me.maxWidth;\n\t\t\t\tme.left = 0;\n\t\t\t\tme.right = me.width;\n\t\t\t} else {\n\t\t\t\tme.height = me.maxHeight;\n\n\t\t\t\t// Reset position before calculating rotation\n\t\t\t\tme.top = 0;\n\t\t\t\tme.bottom = me.height;\n\t\t\t}\n\n\t\t\t// Reset padding\n\t\t\tme.paddingLeft = 0;\n\t\t\tme.paddingTop = 0;\n\t\t\tme.paddingRight = 0;\n\t\t\tme.paddingBottom = 0;\n\t\t},\n\t\tafterSetDimensions: function() {\n\t\t\thelpers.callback(this.options.afterSetDimensions, [this]);\n\t\t},\n\n\t\t// Data limits\n\t\tbeforeDataLimits: function() {\n\t\t\thelpers.callback(this.options.beforeDataLimits, [this]);\n\t\t},\n\t\tdetermineDataLimits: helpers.noop,\n\t\tafterDataLimits: function() {\n\t\t\thelpers.callback(this.options.afterDataLimits, [this]);\n\t\t},\n\n\t\t//\n\t\tbeforeBuildTicks: function() {\n\t\t\thelpers.callback(this.options.beforeBuildTicks, [this]);\n\t\t},\n\t\tbuildTicks: helpers.noop,\n\t\tafterBuildTicks: function() {\n\t\t\thelpers.callback(this.options.afterBuildTicks, [this]);\n\t\t},\n\n\t\tbeforeTickToLabelConversion: function() {\n\t\t\thelpers.callback(this.options.beforeTickToLabelConversion, [this]);\n\t\t},\n\t\tconvertTicksToLabels: function() {\n\t\t\tvar me = this;\n\t\t\t// Convert ticks to strings\n\t\t\tvar tickOpts = me.options.ticks;\n\t\t\tme.ticks = me.ticks.map(tickOpts.userCallback || tickOpts.callback);\n\t\t},\n\t\tafterTickToLabelConversion: function() {\n\t\t\thelpers.callback(this.options.afterTickToLabelConversion, [this]);\n\t\t},\n\n\t\t//\n\n\t\tbeforeCalculateTickRotation: function() {\n\t\t\thelpers.callback(this.options.beforeCalculateTickRotation, [this]);\n\t\t},\n\t\tcalculateTickRotation: function() {\n\t\t\tvar me = this;\n\t\t\tvar context = me.ctx;\n\t\t\tvar tickOpts = me.options.ticks;\n\n\t\t\t// Get the width of each grid by calculating the difference\n\t\t\t// between x offsets between 0 and 1.\n\t\t\tvar tickFont = parseFontOptions(tickOpts);\n\t\t\tcontext.font = tickFont.font;\n\n\t\t\tvar labelRotation = tickOpts.minRotation || 0;\n\n\t\t\tif (me.options.display && me.isHorizontal()) {\n\t\t\t\tvar originalLabelWidth = helpers.longestText(context, tickFont.font, me.ticks, me.longestTextCache);\n\t\t\t\tvar labelWidth = originalLabelWidth;\n\t\t\t\tvar cosRotation;\n\t\t\t\tvar sinRotation;\n\n\t\t\t\t// Allow 3 pixels x2 padding either side for label readability\n\t\t\t\tvar tickWidth = me.getPixelForTick(1) - me.getPixelForTick(0) - 6;\n\n\t\t\t\t// Max label rotation can be set or default to 90 - also act as a loop counter\n\t\t\t\twhile (labelWidth > tickWidth && labelRotation < tickOpts.maxRotation) {\n\t\t\t\t\tvar angleRadians = helpers.toRadians(labelRotation);\n\t\t\t\t\tcosRotation = Math.cos(angleRadians);\n\t\t\t\t\tsinRotation = Math.sin(angleRadians);\n\n\t\t\t\t\tif (sinRotation * originalLabelWidth > me.maxHeight) {\n\t\t\t\t\t\t// go back one step\n\t\t\t\t\t\tlabelRotation--;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\n\t\t\t\t\tlabelRotation++;\n\t\t\t\t\tlabelWidth = cosRotation * originalLabelWidth;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tme.labelRotation = labelRotation;\n\t\t},\n\t\tafterCalculateTickRotation: function() {\n\t\t\thelpers.callback(this.options.afterCalculateTickRotation, [this]);\n\t\t},\n\n\t\t//\n\n\t\tbeforeFit: function() {\n\t\t\thelpers.callback(this.options.beforeFit, [this]);\n\t\t},\n\t\tfit: function() {\n\t\t\tvar me = this;\n\t\t\t// Reset\n\t\t\tvar minSize = me.minSize = {\n\t\t\t\twidth: 0,\n\t\t\t\theight: 0\n\t\t\t};\n\n\t\t\tvar opts = me.options;\n\t\t\tvar tickOpts = opts.ticks;\n\t\t\tvar scaleLabelOpts = opts.scaleLabel;\n\t\t\tvar gridLineOpts = opts.gridLines;\n\t\t\tvar display = opts.display;\n\t\t\tvar isHorizontal = me.isHorizontal();\n\n\t\t\tvar tickFont = parseFontOptions(tickOpts);\n\t\t\tvar scaleLabelFontSize = parseFontOptions(scaleLabelOpts).size * 1.5;\n\t\t\tvar tickMarkLength = opts.gridLines.tickMarkLength;\n\n\t\t\t// Width\n\t\t\tif (isHorizontal) {\n\t\t\t\t// subtract the margins to line up with the chartArea if we are a full width scale\n\t\t\t\tminSize.width = me.isFullWidth() ? me.maxWidth - me.margins.left - me.margins.right : me.maxWidth;\n\t\t\t} else {\n\t\t\t\tminSize.width = display && gridLineOpts.drawTicks ? tickMarkLength : 0;\n\t\t\t}\n\n\t\t\t// height\n\t\t\tif (isHorizontal) {\n\t\t\t\tminSize.height = display && gridLineOpts.drawTicks ? tickMarkLength : 0;\n\t\t\t} else {\n\t\t\t\tminSize.height = me.maxHeight; // fill all the height\n\t\t\t}\n\n\t\t\t// Are we showing a title for the scale?\n\t\t\tif (scaleLabelOpts.display && display) {\n\t\t\t\tif (isHorizontal) {\n\t\t\t\t\tminSize.height += scaleLabelFontSize;\n\t\t\t\t} else {\n\t\t\t\t\tminSize.width += scaleLabelFontSize;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Don't bother fitting the ticks if we are not showing them\n\t\t\tif (tickOpts.display && display) {\n\t\t\t\tvar largestTextWidth = helpers.longestText(me.ctx, tickFont.font, me.ticks, me.longestTextCache);\n\t\t\t\tvar tallestLabelHeightInLines = helpers.numberOfLabelLines(me.ticks);\n\t\t\t\tvar lineSpace = tickFont.size * 0.5;\n\n\t\t\t\tif (isHorizontal) {\n\t\t\t\t\t// A horizontal axis is more constrained by the height.\n\t\t\t\t\tme.longestLabelWidth = largestTextWidth;\n\n\t\t\t\t\tvar angleRadians = helpers.toRadians(me.labelRotation);\n\t\t\t\t\tvar cosRotation = Math.cos(angleRadians);\n\t\t\t\t\tvar sinRotation = Math.sin(angleRadians);\n\n\t\t\t\t\t// TODO - improve this calculation\n\t\t\t\t\tvar labelHeight = (sinRotation * largestTextWidth)\n\t\t\t\t\t\t+ (tickFont.size * tallestLabelHeightInLines)\n\t\t\t\t\t\t+ (lineSpace * tallestLabelHeightInLines);\n\n\t\t\t\t\tminSize.height = Math.min(me.maxHeight, minSize.height + labelHeight);\n\t\t\t\t\tme.ctx.font = tickFont.font;\n\n\t\t\t\t\tvar firstTick = me.ticks[0];\n\t\t\t\t\tvar firstLabelWidth = computeTextSize(me.ctx, firstTick, tickFont.font);\n\n\t\t\t\t\tvar lastTick = me.ticks[me.ticks.length - 1];\n\t\t\t\t\tvar lastLabelWidth = computeTextSize(me.ctx, lastTick, tickFont.font);\n\n\t\t\t\t\t// Ensure that our ticks are always inside the canvas. When rotated, ticks are right aligned which means that the right padding is dominated\n\t\t\t\t\t// by the font height\n\t\t\t\t\tif (me.labelRotation !== 0) {\n\t\t\t\t\t\tme.paddingLeft = opts.position === 'bottom'? (cosRotation * firstLabelWidth) + 3: (cosRotation * lineSpace) + 3; // add 3 px to move away from canvas edges\n\t\t\t\t\t\tme.paddingRight = opts.position === 'bottom'? (cosRotation * lineSpace) + 3: (cosRotation * lastLabelWidth) + 3;\n\t\t\t\t\t} else {\n\t\t\t\t\t\tme.paddingLeft = firstLabelWidth / 2 + 3; // add 3 px to move away from canvas edges\n\t\t\t\t\t\tme.paddingRight = lastLabelWidth / 2 + 3;\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\t// A vertical axis is more constrained by the width. Labels are the dominant factor here, so get that length first\n\t\t\t\t\t// Account for padding\n\n\t\t\t\t\tif (tickOpts.mirror) {\n\t\t\t\t\t\tlargestTextWidth = 0;\n\t\t\t\t\t} else {\n\t\t\t\t\t\tlargestTextWidth += me.options.ticks.padding;\n\t\t\t\t\t}\n\t\t\t\t\tminSize.width = Math.min(me.maxWidth, minSize.width + largestTextWidth);\n\t\t\t\t\tme.paddingTop = tickFont.size / 2;\n\t\t\t\t\tme.paddingBottom = tickFont.size / 2;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tme.handleMargins();\n\n\t\t\tme.width = minSize.width;\n\t\t\tme.height = minSize.height;\n\t\t},\n\n\t\t/**\n\t\t * Handle margins and padding interactions\n\t\t * @private\n\t\t */\n\t\thandleMargins: function() {\n\t\t\tvar me = this;\n\t\t\tif (me.margins) {\n\t\t\t\tme.paddingLeft = Math.max(me.paddingLeft - me.margins.left, 0);\n\t\t\t\tme.paddingTop = Math.max(me.paddingTop - me.margins.top, 0);\n\t\t\t\tme.paddingRight = Math.max(me.paddingRight - me.margins.right, 0);\n\t\t\t\tme.paddingBottom = Math.max(me.paddingBottom - me.margins.bottom, 0);\n\t\t\t}\n\t\t},\n\n\t\tafterFit: function() {\n\t\t\thelpers.callback(this.options.afterFit, [this]);\n\t\t},\n\n\t\t// Shared Methods\n\t\tisHorizontal: function() {\n\t\t\treturn this.options.position === 'top' || this.options.position === 'bottom';\n\t\t},\n\t\tisFullWidth: function() {\n\t\t\treturn (this.options.fullWidth);\n\t\t},\n\n\t\t// Get the correct value. NaN bad inputs, If the value type is object get the x or y based on whether we are horizontal or not\n\t\tgetRightValue: function(rawValue) {\n\t\t\t// Null and undefined values first\n\t\t\tif (rawValue === null || typeof(rawValue) === 'undefined') {\n\t\t\t\treturn NaN;\n\t\t\t}\n\t\t\t// isNaN(object) returns true, so make sure NaN is checking for a number; Discard Infinite values\n\t\t\tif (typeof(rawValue) === 'number' && !isFinite(rawValue)) {\n\t\t\t\treturn NaN;\n\t\t\t}\n\t\t\t// If it is in fact an object, dive in one more level\n\t\t\tif (typeof(rawValue) === 'object') {\n\t\t\t\tif ((rawValue instanceof Date) || (rawValue.isValid)) {\n\t\t\t\t\treturn rawValue;\n\t\t\t\t}\n\t\t\t\treturn this.getRightValue(this.isHorizontal() ? rawValue.x : rawValue.y);\n\t\t\t}\n\n\t\t\t// Value is good, return it\n\t\t\treturn rawValue;\n\t\t},\n\n\t\t// Used to get the value to display in the tooltip for the data at the given index\n\t\t// function getLabelForIndex(index, datasetIndex)\n\t\tgetLabelForIndex: helpers.noop,\n\n\t\t// Used to get data value locations.  Value can either be an index or a numerical value\n\t\tgetPixelForValue: helpers.noop,\n\n\t\t// Used to get the data value from a given pixel. This is the inverse of getPixelForValue\n\t\tgetValueForPixel: helpers.noop,\n\n\t\t// Used for tick location, should\n\t\tgetPixelForTick: function(index, includeOffset) {\n\t\t\tvar me = this;\n\t\t\tif (me.isHorizontal()) {\n\t\t\t\tvar innerWidth = me.width - (me.paddingLeft + me.paddingRight);\n\t\t\t\tvar tickWidth = innerWidth / Math.max((me.ticks.length - ((me.options.gridLines.offsetGridLines) ? 0 : 1)), 1);\n\t\t\t\tvar pixel = (tickWidth * index) + me.paddingLeft;\n\n\t\t\t\tif (includeOffset) {\n\t\t\t\t\tpixel += tickWidth / 2;\n\t\t\t\t}\n\n\t\t\t\tvar finalVal = me.left + Math.round(pixel);\n\t\t\t\tfinalVal += me.isFullWidth() ? me.margins.left : 0;\n\t\t\t\treturn finalVal;\n\t\t\t}\n\t\t\tvar innerHeight = me.height - (me.paddingTop + me.paddingBottom);\n\t\t\treturn me.top + (index * (innerHeight / (me.ticks.length - 1)));\n\t\t},\n\n\t\t// Utility for getting the pixel location of a percentage of scale\n\t\tgetPixelForDecimal: function(decimal /* , includeOffset*/) {\n\t\t\tvar me = this;\n\t\t\tif (me.isHorizontal()) {\n\t\t\t\tvar innerWidth = me.width - (me.paddingLeft + me.paddingRight);\n\t\t\t\tvar valueOffset = (innerWidth * decimal) + me.paddingLeft;\n\n\t\t\t\tvar finalVal = me.left + Math.round(valueOffset);\n\t\t\t\tfinalVal += me.isFullWidth() ? me.margins.left : 0;\n\t\t\t\treturn finalVal;\n\t\t\t}\n\t\t\treturn me.top + (decimal * me.height);\n\t\t},\n\n\t\tgetBasePixel: function() {\n\t\t\treturn this.getPixelForValue(this.getBaseValue());\n\t\t},\n\n\t\tgetBaseValue: function() {\n\t\t\tvar me = this;\n\t\t\tvar min = me.min;\n\t\t\tvar max = me.max;\n\n\t\t\treturn me.beginAtZero ? 0:\n\t\t\t\tmin < 0 && max < 0? max :\n\t\t\t\tmin > 0 && max > 0? min :\n\t\t\t\t0;\n\t\t},\n\n\t\t// Actually draw the scale on the canvas\n\t\t// @param {rectangle} chartArea : the area of the chart to draw full grid lines on\n\t\tdraw: function(chartArea) {\n\t\t\tvar me = this;\n\t\t\tvar options = me.options;\n\t\t\tif (!options.display) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tvar context = me.ctx;\n\t\t\tvar globalDefaults = Chart.defaults.global;\n\t\t\tvar optionTicks = options.ticks;\n\t\t\tvar gridLines = options.gridLines;\n\t\t\tvar scaleLabel = options.scaleLabel;\n\n\t\t\tvar isRotated = me.labelRotation !== 0;\n\t\t\tvar skipRatio;\n\t\t\tvar useAutoskipper = optionTicks.autoSkip;\n\t\t\tvar isHorizontal = me.isHorizontal();\n\n\t\t\t// figure out the maximum number of gridlines to show\n\t\t\tvar maxTicks;\n\t\t\tif (optionTicks.maxTicksLimit) {\n\t\t\t\tmaxTicks = optionTicks.maxTicksLimit;\n\t\t\t}\n\n\t\t\tvar tickFontColor = helpers.getValueOrDefault(optionTicks.fontColor, globalDefaults.defaultFontColor);\n\t\t\tvar tickFont = parseFontOptions(optionTicks);\n\n\t\t\tvar tl = gridLines.drawTicks ? gridLines.tickMarkLength : 0;\n\n\t\t\tvar scaleLabelFontColor = helpers.getValueOrDefault(scaleLabel.fontColor, globalDefaults.defaultFontColor);\n\t\t\tvar scaleLabelFont = parseFontOptions(scaleLabel);\n\n\t\t\tvar labelRotationRadians = helpers.toRadians(me.labelRotation);\n\t\t\tvar cosRotation = Math.cos(labelRotationRadians);\n\t\t\tvar longestRotatedLabel = me.longestLabelWidth * cosRotation;\n\n\t\t\t// Make sure we draw text in the correct color and font\n\t\t\tcontext.fillStyle = tickFontColor;\n\n\t\t\tvar itemsToDraw = [];\n\n\t\t\tif (isHorizontal) {\n\t\t\t\tskipRatio = false;\n\n\t\t\t\tif ((longestRotatedLabel + optionTicks.autoSkipPadding) * me.ticks.length > (me.width - (me.paddingLeft + me.paddingRight))) {\n\t\t\t\t\tskipRatio = 1 + Math.floor(((longestRotatedLabel + optionTicks.autoSkipPadding) * me.ticks.length) / (me.width - (me.paddingLeft + me.paddingRight)));\n\t\t\t\t}\n\n\t\t\t\t// if they defined a max number of optionTicks,\n\t\t\t\t// increase skipRatio until that number is met\n\t\t\t\tif (maxTicks && me.ticks.length > maxTicks) {\n\t\t\t\t\twhile (!skipRatio || me.ticks.length / (skipRatio || 1) > maxTicks) {\n\t\t\t\t\t\tif (!skipRatio) {\n\t\t\t\t\t\t\tskipRatio = 1;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tskipRatio += 1;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif (!useAutoskipper) {\n\t\t\t\t\tskipRatio = false;\n\t\t\t\t}\n\t\t\t}\n\n\n\t\t\tvar xTickStart = options.position === 'right' ? me.left : me.right - tl;\n\t\t\tvar xTickEnd = options.position === 'right' ? me.left + tl : me.right;\n\t\t\tvar yTickStart = options.position === 'bottom' ? me.top : me.bottom - tl;\n\t\t\tvar yTickEnd = options.position === 'bottom' ? me.top + tl : me.bottom;\n\n\t\t\thelpers.each(me.ticks, function(label, index) {\n\t\t\t\t// If the callback returned a null or undefined value, do not draw this line\n\t\t\t\tif (label === undefined || label === null) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tvar isLastTick = me.ticks.length === index + 1;\n\n\t\t\t\t// Since we always show the last tick,we need may need to hide the last shown one before\n\t\t\t\tvar shouldSkip = (skipRatio > 1 && index % skipRatio > 0) || (index % skipRatio === 0 && index + skipRatio >= me.ticks.length);\n\t\t\t\tif (shouldSkip && !isLastTick || (label === undefined || label === null)) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tvar lineWidth, lineColor, borderDash, borderDashOffset;\n\t\t\t\tif (index === (typeof me.zeroLineIndex !== 'undefined' ? me.zeroLineIndex : 0)) {\n\t\t\t\t\t// Draw the first index specially\n\t\t\t\t\tlineWidth = gridLines.zeroLineWidth;\n\t\t\t\t\tlineColor = gridLines.zeroLineColor;\n\t\t\t\t\tborderDash = gridLines.zeroLineBorderDash;\n\t\t\t\t\tborderDashOffset = gridLines.zeroLineBorderDashOffset;\n\t\t\t\t} else {\n\t\t\t\t\tlineWidth = helpers.getValueAtIndexOrDefault(gridLines.lineWidth, index);\n\t\t\t\t\tlineColor = helpers.getValueAtIndexOrDefault(gridLines.color, index);\n\t\t\t\t\tborderDash = helpers.getValueOrDefault(gridLines.borderDash, globalDefaults.borderDash);\n\t\t\t\t\tborderDashOffset = helpers.getValueOrDefault(gridLines.borderDashOffset, globalDefaults.borderDashOffset);\n\t\t\t\t}\n\n\t\t\t\t// Common properties\n\t\t\t\tvar tx1, ty1, tx2, ty2, x1, y1, x2, y2, labelX, labelY;\n\t\t\t\tvar textAlign = 'middle';\n\t\t\t\tvar textBaseline = 'middle';\n\n\t\t\t\tif (isHorizontal) {\n\n\t\t\t\t\tif (options.position === 'bottom') {\n\t\t\t\t\t\t// bottom\n\t\t\t\t\t\ttextBaseline = !isRotated? 'top':'middle';\n\t\t\t\t\t\ttextAlign = !isRotated? 'center': 'right';\n\t\t\t\t\t\tlabelY = me.top + tl;\n\t\t\t\t\t} else {\n\t\t\t\t\t\t// top\n\t\t\t\t\t\ttextBaseline = !isRotated? 'bottom':'middle';\n\t\t\t\t\t\ttextAlign = !isRotated? 'center': 'left';\n\t\t\t\t\t\tlabelY = me.bottom - tl;\n\t\t\t\t\t}\n\n\t\t\t\t\tvar xLineValue = me.getPixelForTick(index) + helpers.aliasPixel(lineWidth); // xvalues for grid lines\n\t\t\t\t\tlabelX = me.getPixelForTick(index, gridLines.offsetGridLines) + optionTicks.labelOffset; // x values for optionTicks (need to consider offsetLabel option)\n\n\t\t\t\t\ttx1 = tx2 = x1 = x2 = xLineValue;\n\t\t\t\t\tty1 = yTickStart;\n\t\t\t\t\tty2 = yTickEnd;\n\t\t\t\t\ty1 = chartArea.top;\n\t\t\t\t\ty2 = chartArea.bottom;\n\t\t\t\t} else {\n\t\t\t\t\tvar isLeft = options.position === 'left';\n\t\t\t\t\tvar tickPadding = optionTicks.padding;\n\t\t\t\t\tvar labelXOffset;\n\n\t\t\t\t\tif (optionTicks.mirror) {\n\t\t\t\t\t\ttextAlign = isLeft ? 'left' : 'right';\n\t\t\t\t\t\tlabelXOffset = tickPadding;\n\t\t\t\t\t} else {\n\t\t\t\t\t\ttextAlign = isLeft ? 'right' : 'left';\n\t\t\t\t\t\tlabelXOffset = tl + tickPadding;\n\t\t\t\t\t}\n\n\t\t\t\t\tlabelX = isLeft ? me.right - labelXOffset : me.left + labelXOffset;\n\n\t\t\t\t\tvar yLineValue = me.getPixelForTick(index); // xvalues for grid lines\n\t\t\t\t\tyLineValue += helpers.aliasPixel(lineWidth);\n\t\t\t\t\tlabelY = me.getPixelForTick(index, gridLines.offsetGridLines);\n\n\t\t\t\t\ttx1 = xTickStart;\n\t\t\t\t\ttx2 = xTickEnd;\n\t\t\t\t\tx1 = chartArea.left;\n\t\t\t\t\tx2 = chartArea.right;\n\t\t\t\t\tty1 = ty2 = y1 = y2 = yLineValue;\n\t\t\t\t}\n\n\t\t\t\titemsToDraw.push({\n\t\t\t\t\ttx1: tx1,\n\t\t\t\t\tty1: ty1,\n\t\t\t\t\ttx2: tx2,\n\t\t\t\t\tty2: ty2,\n\t\t\t\t\tx1: x1,\n\t\t\t\t\ty1: y1,\n\t\t\t\t\tx2: x2,\n\t\t\t\t\ty2: y2,\n\t\t\t\t\tlabelX: labelX,\n\t\t\t\t\tlabelY: labelY,\n\t\t\t\t\tglWidth: lineWidth,\n\t\t\t\t\tglColor: lineColor,\n\t\t\t\t\tglBorderDash: borderDash,\n\t\t\t\t\tglBorderDashOffset: borderDashOffset,\n\t\t\t\t\trotation: -1 * labelRotationRadians,\n\t\t\t\t\tlabel: label,\n\t\t\t\t\ttextBaseline: textBaseline,\n\t\t\t\t\ttextAlign: textAlign\n\t\t\t\t});\n\t\t\t});\n\n\t\t\t// Draw all of the tick labels, tick marks, and grid lines at the correct places\n\t\t\thelpers.each(itemsToDraw, function(itemToDraw) {\n\t\t\t\tif (gridLines.display) {\n\t\t\t\t\tcontext.save();\n\t\t\t\t\tcontext.lineWidth = itemToDraw.glWidth;\n\t\t\t\t\tcontext.strokeStyle = itemToDraw.glColor;\n\t\t\t\t\tif (context.setLineDash) {\n\t\t\t\t\t\tcontext.setLineDash(itemToDraw.glBorderDash);\n\t\t\t\t\t\tcontext.lineDashOffset = itemToDraw.glBorderDashOffset;\n\t\t\t\t\t}\n\n\t\t\t\t\tcontext.beginPath();\n\n\t\t\t\t\tif (gridLines.drawTicks) {\n\t\t\t\t\t\tcontext.moveTo(itemToDraw.tx1, itemToDraw.ty1);\n\t\t\t\t\t\tcontext.lineTo(itemToDraw.tx2, itemToDraw.ty2);\n\t\t\t\t\t}\n\n\t\t\t\t\tif (gridLines.drawOnChartArea) {\n\t\t\t\t\t\tcontext.moveTo(itemToDraw.x1, itemToDraw.y1);\n\t\t\t\t\t\tcontext.lineTo(itemToDraw.x2, itemToDraw.y2);\n\t\t\t\t\t}\n\n\t\t\t\t\tcontext.stroke();\n\t\t\t\t\tcontext.restore();\n\t\t\t\t}\n\n\t\t\t\tif (optionTicks.display) {\n\t\t\t\t\tcontext.save();\n\t\t\t\t\tcontext.translate(itemToDraw.labelX, itemToDraw.labelY);\n\t\t\t\t\tcontext.rotate(itemToDraw.rotation);\n\t\t\t\t\tcontext.font = tickFont.font;\n\t\t\t\t\tcontext.textBaseline = itemToDraw.textBaseline;\n\t\t\t\t\tcontext.textAlign = itemToDraw.textAlign;\n\n\t\t\t\t\tvar label = itemToDraw.label;\n\t\t\t\t\tif (helpers.isArray(label)) {\n\t\t\t\t\t\tfor (var i = 0, y = 0; i < label.length; ++i) {\n\t\t\t\t\t\t\t// We just make sure the multiline element is a string here..\n\t\t\t\t\t\t\tcontext.fillText('' + label[i], 0, y);\n\t\t\t\t\t\t\t// apply same lineSpacing as calculated @ L#320\n\t\t\t\t\t\t\ty += (tickFont.size * 1.5);\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\tcontext.fillText(label, 0, 0);\n\t\t\t\t\t}\n\t\t\t\t\tcontext.restore();\n\t\t\t\t}\n\t\t\t});\n\n\t\t\tif (scaleLabel.display) {\n\t\t\t\t// Draw the scale label\n\t\t\t\tvar scaleLabelX;\n\t\t\t\tvar scaleLabelY;\n\t\t\t\tvar rotation = 0;\n\n\t\t\t\tif (isHorizontal) {\n\t\t\t\t\tscaleLabelX = me.left + ((me.right - me.left) / 2); // midpoint of the width\n\t\t\t\t\tscaleLabelY = options.position === 'bottom' ? me.bottom - (scaleLabelFont.size / 2) : me.top + (scaleLabelFont.size / 2);\n\t\t\t\t} else {\n\t\t\t\t\tvar isLeft = options.position === 'left';\n\t\t\t\t\tscaleLabelX = isLeft ? me.left + (scaleLabelFont.size / 2) : me.right - (scaleLabelFont.size / 2);\n\t\t\t\t\tscaleLabelY = me.top + ((me.bottom - me.top) / 2);\n\t\t\t\t\trotation = isLeft ? -0.5 * Math.PI : 0.5 * Math.PI;\n\t\t\t\t}\n\n\t\t\t\tcontext.save();\n\t\t\t\tcontext.translate(scaleLabelX, scaleLabelY);\n\t\t\t\tcontext.rotate(rotation);\n\t\t\t\tcontext.textAlign = 'center';\n\t\t\t\tcontext.textBaseline = 'middle';\n\t\t\t\tcontext.fillStyle = scaleLabelFontColor; // render in correct colour\n\t\t\t\tcontext.font = scaleLabelFont.font;\n\t\t\t\tcontext.fillText(scaleLabel.labelString, 0, 0);\n\t\t\t\tcontext.restore();\n\t\t\t}\n\n\t\t\tif (gridLines.drawBorder) {\n\t\t\t\t// Draw the line at the edge of the axis\n\t\t\t\tcontext.lineWidth = helpers.getValueAtIndexOrDefault(gridLines.lineWidth, 0);\n\t\t\t\tcontext.strokeStyle = helpers.getValueAtIndexOrDefault(gridLines.color, 0);\n\t\t\t\tvar x1 = me.left,\n\t\t\t\t\tx2 = me.right,\n\t\t\t\t\ty1 = me.top,\n\t\t\t\t\ty2 = me.bottom;\n\n\t\t\t\tvar aliasPixel = helpers.aliasPixel(context.lineWidth);\n\t\t\t\tif (isHorizontal) {\n\t\t\t\t\ty1 = y2 = options.position === 'top' ? me.bottom : me.top;\n\t\t\t\t\ty1 += aliasPixel;\n\t\t\t\t\ty2 += aliasPixel;\n\t\t\t\t} else {\n\t\t\t\t\tx1 = x2 = options.position === 'left' ? me.right : me.left;\n\t\t\t\t\tx1 += aliasPixel;\n\t\t\t\t\tx2 += aliasPixel;\n\t\t\t\t}\n\n\t\t\t\tcontext.beginPath();\n\t\t\t\tcontext.moveTo(x1, y1);\n\t\t\t\tcontext.lineTo(x2, y2);\n\t\t\t\tcontext.stroke();\n\t\t\t}\n\t\t}\n\t});\n};\n\n},{}],32:[function(require,module,exports){\n'use strict';\n\nmodule.exports = function(Chart) {\n\n\tvar helpers = Chart.helpers;\n\n\tChart.scaleService = {\n\t\t// Scale registration object. Extensions can register new scale types (such as log or DB scales) and then\n\t\t// use the new chart options to grab the correct scale\n\t\tconstructors: {},\n\t\t// Use a registration function so that we can move to an ES6 map when we no longer need to support\n\t\t// old browsers\n\n\t\t// Scale config defaults\n\t\tdefaults: {},\n\t\tregisterScaleType: function(type, scaleConstructor, defaults) {\n\t\t\tthis.constructors[type] = scaleConstructor;\n\t\t\tthis.defaults[type] = helpers.clone(defaults);\n\t\t},\n\t\tgetScaleConstructor: function(type) {\n\t\t\treturn this.constructors.hasOwnProperty(type) ? this.constructors[type] : undefined;\n\t\t},\n\t\tgetScaleDefaults: function(type) {\n\t\t\t// Return the scale defaults merged with the global settings so that we always use the latest ones\n\t\t\treturn this.defaults.hasOwnProperty(type) ? helpers.scaleMerge(Chart.defaults.scale, this.defaults[type]) : {};\n\t\t},\n\t\tupdateScaleDefaults: function(type, additions) {\n\t\t\tvar defaults = this.defaults;\n\t\t\tif (defaults.hasOwnProperty(type)) {\n\t\t\t\tdefaults[type] = helpers.extend(defaults[type], additions);\n\t\t\t}\n\t\t},\n\t\taddScalesToLayout: function(chart) {\n\t\t\t// Adds each scale to the chart.boxes array to be sized accordingly\n\t\t\thelpers.each(chart.scales, function(scale) {\n\t\t\t\t// Set ILayoutItem parameters for backwards compatibility\n\t\t\t\tscale.fullWidth = scale.options.fullWidth;\n\t\t\t\tscale.position = scale.options.position;\n\t\t\t\tscale.weight = scale.options.weight;\n\t\t\t\tChart.layoutService.addBox(chart, scale);\n\t\t\t});\n\t\t}\n\t};\n};\n\n},{}],33:[function(require,module,exports){\n'use strict';\n\nmodule.exports = function(Chart) {\n\n\tvar helpers = Chart.helpers;\n\n\t/**\n\t * Namespace to hold static tick generation functions\n\t * @namespace Chart.Ticks\n\t */\n\tChart.Ticks = {\n\t\t/**\n\t\t * Namespace to hold generators for different types of ticks\n\t\t * @namespace Chart.Ticks.generators\n\t\t */\n\t\tgenerators: {\n\t\t\t/**\n\t\t\t * Interface for the options provided to the numeric tick generator\n\t\t\t * @interface INumericTickGenerationOptions\n\t\t\t */\n\t\t\t/**\n\t\t\t * The maximum number of ticks to display\n\t\t\t * @name INumericTickGenerationOptions#maxTicks\n\t\t\t * @type Number\n\t\t\t */\n\t\t\t/**\n\t\t\t * The distance between each tick.\n\t\t\t * @name INumericTickGenerationOptions#stepSize\n\t\t\t * @type Number\n\t\t\t * @optional\n\t\t\t */\n\t\t\t/**\n\t\t\t * Forced minimum for the ticks. If not specified, the minimum of the data range is used to calculate the tick minimum\n\t\t\t * @name INumericTickGenerationOptions#min\n\t\t\t * @type Number\n\t\t\t * @optional\n\t\t\t */\n\t\t\t/**\n\t\t\t * The maximum value of the ticks. If not specified, the maximum of the data range is used to calculate the tick maximum\n\t\t\t * @name INumericTickGenerationOptions#max\n\t\t\t * @type Number\n\t\t\t * @optional\n\t\t\t */\n\n\t\t\t/**\n\t\t\t * Generate a set of linear ticks\n\t\t\t * @method Chart.Ticks.generators.linear\n\t\t\t * @param generationOptions {INumericTickGenerationOptions} the options used to generate the ticks\n\t\t\t * @param dataRange {IRange} the range of the data\n\t\t\t * @returns {Array<Number>} array of tick values\n\t\t\t */\n\t\t\tlinear: function(generationOptions, dataRange) {\n\t\t\t\tvar ticks = [];\n\t\t\t\t// To get a \"nice\" value for the tick spacing, we will use the appropriately named\n\t\t\t\t// \"nice number\" algorithm. See http://stackoverflow.com/questions/8506881/nice-label-algorithm-for-charts-with-minimum-ticks\n\t\t\t\t// for details.\n\n\t\t\t\tvar spacing;\n\t\t\t\tif (generationOptions.stepSize && generationOptions.stepSize > 0) {\n\t\t\t\t\tspacing = generationOptions.stepSize;\n\t\t\t\t} else {\n\t\t\t\t\tvar niceRange = helpers.niceNum(dataRange.max - dataRange.min, false);\n\t\t\t\t\tspacing = helpers.niceNum(niceRange / (generationOptions.maxTicks - 1), true);\n\t\t\t\t}\n\t\t\t\tvar niceMin = Math.floor(dataRange.min / spacing) * spacing;\n\t\t\t\tvar niceMax = Math.ceil(dataRange.max / spacing) * spacing;\n\n\t\t\t\t// If min, max and stepSize is set and they make an evenly spaced scale use it.\n\t\t\t\tif (generationOptions.min && generationOptions.max && generationOptions.stepSize) {\n\t\t\t\t\t// If very close to our whole number, use it.\n\t\t\t\t\tif (helpers.almostWhole((generationOptions.max - generationOptions.min) / generationOptions.stepSize, spacing / 1000)) {\n\t\t\t\t\t\tniceMin = generationOptions.min;\n\t\t\t\t\t\tniceMax = generationOptions.max;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tvar numSpaces = (niceMax - niceMin) / spacing;\n\t\t\t\t// If very close to our rounded value, use it.\n\t\t\t\tif (helpers.almostEquals(numSpaces, Math.round(numSpaces), spacing / 1000)) {\n\t\t\t\t\tnumSpaces = Math.round(numSpaces);\n\t\t\t\t} else {\n\t\t\t\t\tnumSpaces = Math.ceil(numSpaces);\n\t\t\t\t}\n\n\t\t\t\t// Put the values into the ticks array\n\t\t\t\tticks.push(generationOptions.min !== undefined ? generationOptions.min : niceMin);\n\t\t\t\tfor (var j = 1; j < numSpaces; ++j) {\n\t\t\t\t\tticks.push(niceMin + (j * spacing));\n\t\t\t\t}\n\t\t\t\tticks.push(generationOptions.max !== undefined ? generationOptions.max : niceMax);\n\n\t\t\t\treturn ticks;\n\t\t\t},\n\n\t\t\t/**\n\t\t\t * Generate a set of logarithmic ticks\n\t\t\t * @method Chart.Ticks.generators.logarithmic\n\t\t\t * @param generationOptions {INumericTickGenerationOptions} the options used to generate the ticks\n\t\t\t * @param dataRange {IRange} the range of the data\n\t\t\t * @returns {Array<Number>} array of tick values\n\t\t\t */\n\t\t\tlogarithmic: function(generationOptions, dataRange) {\n\t\t\t\tvar ticks = [];\n\t\t\t\tvar getValueOrDefault = helpers.getValueOrDefault;\n\n\t\t\t\t// Figure out what the max number of ticks we can support it is based on the size of\n\t\t\t\t// the axis area. For now, we say that the minimum tick spacing in pixels must be 50\n\t\t\t\t// We also limit the maximum number of ticks to 11 which gives a nice 10 squares on\n\t\t\t\t// the graph\n\t\t\t\tvar tickVal = getValueOrDefault(generationOptions.min, Math.pow(10, Math.floor(helpers.log10(dataRange.min))));\n\n\t\t\t\tvar endExp = Math.floor(helpers.log10(dataRange.max));\n\t\t\t\tvar endSignificand = Math.ceil(dataRange.max / Math.pow(10, endExp));\n\t\t\t\tvar exp;\n\t\t\t\tvar significand;\n\n\t\t\t\tif (tickVal === 0) {\n\t\t\t\t\texp = Math.floor(helpers.log10(dataRange.minNotZero));\n\t\t\t\t\tsignificand = Math.floor(dataRange.minNotZero / Math.pow(10, exp));\n\n\t\t\t\t\tticks.push(tickVal);\n\t\t\t\t\ttickVal = significand * Math.pow(10, exp);\n\t\t\t\t} else {\n\t\t\t\t\texp = Math.floor(helpers.log10(tickVal));\n\t\t\t\t\tsignificand = Math.floor(tickVal / Math.pow(10, exp));\n\t\t\t\t}\n\n\t\t\t\tdo {\n\t\t\t\t\tticks.push(tickVal);\n\n\t\t\t\t\t++significand;\n\t\t\t\t\tif (significand === 10) {\n\t\t\t\t\t\tsignificand = 1;\n\t\t\t\t\t\t++exp;\n\t\t\t\t\t}\n\n\t\t\t\t\ttickVal = significand * Math.pow(10, exp);\n\t\t\t\t} while (exp < endExp || (exp === endExp && significand < endSignificand));\n\n\t\t\t\tvar lastTick = getValueOrDefault(generationOptions.max, tickVal);\n\t\t\t\tticks.push(lastTick);\n\n\t\t\t\treturn ticks;\n\t\t\t}\n\t\t},\n\n\t\t/**\n\t\t * Namespace to hold formatters for different types of ticks\n\t\t * @namespace Chart.Ticks.formatters\n\t\t */\n\t\tformatters: {\n\t\t\t/**\n\t\t\t * Formatter for value labels\n\t\t\t * @method Chart.Ticks.formatters.values\n\t\t\t * @param value the value to display\n\t\t\t * @return {String|Array} the label to display\n\t\t\t */\n\t\t\tvalues: function(value) {\n\t\t\t\treturn helpers.isArray(value) ? value : '' + value;\n\t\t\t},\n\n\t\t\t/**\n\t\t\t * Formatter for linear numeric ticks\n\t\t\t * @method Chart.Ticks.formatters.linear\n\t\t\t * @param tickValue {Number} the value to be formatted\n\t\t\t * @param index {Number} the position of the tickValue parameter in the ticks array\n\t\t\t * @param ticks {Array<Number>} the list of ticks being converted\n\t\t\t * @return {String} string representation of the tickValue parameter\n\t\t\t */\n\t\t\tlinear: function(tickValue, index, ticks) {\n\t\t\t\t// If we have lots of ticks, don't use the ones\n\t\t\t\tvar delta = ticks.length > 3 ? ticks[2] - ticks[1] : ticks[1] - ticks[0];\n\n\t\t\t\t// If we have a number like 2.5 as the delta, figure out how many decimal places we need\n\t\t\t\tif (Math.abs(delta) > 1) {\n\t\t\t\t\tif (tickValue !== Math.floor(tickValue)) {\n\t\t\t\t\t\t// not an integer\n\t\t\t\t\t\tdelta = tickValue - Math.floor(tickValue);\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tvar logDelta = helpers.log10(Math.abs(delta));\n\t\t\t\tvar tickString = '';\n\n\t\t\t\tif (tickValue !== 0) {\n\t\t\t\t\tvar numDecimal = -1 * Math.floor(logDelta);\n\t\t\t\t\tnumDecimal = Math.max(Math.min(numDecimal, 20), 0); // toFixed has a max of 20 decimal places\n\t\t\t\t\ttickString = tickValue.toFixed(numDecimal);\n\t\t\t\t} else {\n\t\t\t\t\ttickString = '0'; // never show decimal places for 0\n\t\t\t\t}\n\n\t\t\t\treturn tickString;\n\t\t\t},\n\n\t\t\tlogarithmic: function(tickValue, index, ticks) {\n\t\t\t\tvar remain = tickValue / (Math.pow(10, Math.floor(helpers.log10(tickValue))));\n\n\t\t\t\tif (tickValue === 0) {\n\t\t\t\t\treturn '0';\n\t\t\t\t} else if (remain === 1 || remain === 2 || remain === 5 || index === 0 || index === ticks.length - 1) {\n\t\t\t\t\treturn tickValue.toExponential();\n\t\t\t\t}\n\t\t\t\treturn '';\n\t\t\t}\n\t\t}\n\t};\n};\n\n},{}],34:[function(require,module,exports){\n'use strict';\n\nmodule.exports = function(Chart) {\n\n\tvar helpers = Chart.helpers;\n\n\t/**\n \t * Helper method to merge the opacity into a color\n \t */\n\tfunction mergeOpacity(colorString, opacity) {\n\t\tvar color = helpers.color(colorString);\n\t\treturn color.alpha(opacity * color.alpha()).rgbaString();\n\t}\n\n\tChart.defaults.global.tooltips = {\n\t\tenabled: true,\n\t\tcustom: null,\n\t\tmode: 'nearest',\n\t\tposition: 'average',\n\t\tintersect: true,\n\t\tbackgroundColor: 'rgba(0,0,0,0.8)',\n\t\ttitleFontStyle: 'bold',\n\t\ttitleSpacing: 2,\n\t\ttitleMarginBottom: 6,\n\t\ttitleFontColor: '#fff',\n\t\ttitleAlign: 'left',\n\t\tbodySpacing: 2,\n\t\tbodyFontColor: '#fff',\n\t\tbodyAlign: 'left',\n\t\tfooterFontStyle: 'bold',\n\t\tfooterSpacing: 2,\n\t\tfooterMarginTop: 6,\n\t\tfooterFontColor: '#fff',\n\t\tfooterAlign: 'left',\n\t\tyPadding: 6,\n\t\txPadding: 6,\n\t\tcaretPadding: 2,\n\t\tcaretSize: 5,\n\t\tcornerRadius: 6,\n\t\tmultiKeyBackground: '#fff',\n\t\tdisplayColors: true,\n\t\tborderColor: 'rgba(0,0,0,0)',\n\t\tborderWidth: 0,\n\t\tcallbacks: {\n\t\t\t// Args are: (tooltipItems, data)\n\t\t\tbeforeTitle: helpers.noop,\n\t\t\ttitle: function(tooltipItems, data) {\n\t\t\t\t// Pick first xLabel for now\n\t\t\t\tvar title = '';\n\t\t\t\tvar labels = data.labels;\n\t\t\t\tvar labelCount = labels ? labels.length : 0;\n\n\t\t\t\tif (tooltipItems.length > 0) {\n\t\t\t\t\tvar item = tooltipItems[0];\n\n\t\t\t\t\tif (item.xLabel) {\n\t\t\t\t\t\ttitle = item.xLabel;\n\t\t\t\t\t} else if (labelCount > 0 && item.index < labelCount) {\n\t\t\t\t\t\ttitle = labels[item.index];\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\treturn title;\n\t\t\t},\n\t\t\tafterTitle: helpers.noop,\n\n\t\t\t// Args are: (tooltipItems, data)\n\t\t\tbeforeBody: helpers.noop,\n\n\t\t\t// Args are: (tooltipItem, data)\n\t\t\tbeforeLabel: helpers.noop,\n\t\t\tlabel: function(tooltipItem, data) {\n\t\t\t\tvar label = data.datasets[tooltipItem.datasetIndex].label || '';\n\n\t\t\t\tif (label) {\n\t\t\t\t\tlabel += ': ';\n\t\t\t\t}\n\t\t\t\tlabel += tooltipItem.yLabel;\n\t\t\t\treturn label;\n\t\t\t},\n\t\t\tlabelColor: function(tooltipItem, chart) {\n\t\t\t\tvar meta = chart.getDatasetMeta(tooltipItem.datasetIndex);\n\t\t\t\tvar activeElement = meta.data[tooltipItem.index];\n\t\t\t\tvar view = activeElement._view;\n\t\t\t\treturn {\n\t\t\t\t\tborderColor: view.borderColor,\n\t\t\t\t\tbackgroundColor: view.backgroundColor\n\t\t\t\t};\n\t\t\t},\n\t\t\tafterLabel: helpers.noop,\n\n\t\t\t// Args are: (tooltipItems, data)\n\t\t\tafterBody: helpers.noop,\n\n\t\t\t// Args are: (tooltipItems, data)\n\t\t\tbeforeFooter: helpers.noop,\n\t\t\tfooter: helpers.noop,\n\t\t\tafterFooter: helpers.noop\n\t\t}\n\t};\n\n\t// Helper to push or concat based on if the 2nd parameter is an array or not\n\tfunction pushOrConcat(base, toPush) {\n\t\tif (toPush) {\n\t\t\tif (helpers.isArray(toPush)) {\n\t\t\t\t// base = base.concat(toPush);\n\t\t\t\tArray.prototype.push.apply(base, toPush);\n\t\t\t} else {\n\t\t\t\tbase.push(toPush);\n\t\t\t}\n\t\t}\n\n\t\treturn base;\n\t}\n\n\t// Private helper to create a tooltip item model\n\t// @param element : the chart element (point, arc, bar) to create the tooltip item for\n\t// @return : new tooltip item\n\tfunction createTooltipItem(element) {\n\t\tvar xScale = element._xScale;\n\t\tvar yScale = element._yScale || element._scale; // handle radar || polarArea charts\n\t\tvar index = element._index,\n\t\t\tdatasetIndex = element._datasetIndex;\n\n\t\treturn {\n\t\t\txLabel: xScale ? xScale.getLabelForIndex(index, datasetIndex) : '',\n\t\t\tyLabel: yScale ? yScale.getLabelForIndex(index, datasetIndex) : '',\n\t\t\tindex: index,\n\t\t\tdatasetIndex: datasetIndex,\n\t\t\tx: element._model.x,\n\t\t\ty: element._model.y\n\t\t};\n\t}\n\n\t/**\n\t * Helper to get the reset model for the tooltip\n\t * @param tooltipOpts {Object} the tooltip options\n\t */\n\tfunction getBaseModel(tooltipOpts) {\n\t\tvar globalDefaults = Chart.defaults.global;\n\t\tvar getValueOrDefault = helpers.getValueOrDefault;\n\n\t\treturn {\n\t\t\t// Positioning\n\t\t\txPadding: tooltipOpts.xPadding,\n\t\t\tyPadding: tooltipOpts.yPadding,\n\t\t\txAlign: tooltipOpts.xAlign,\n\t\t\tyAlign: tooltipOpts.yAlign,\n\n\t\t\t// Body\n\t\t\tbodyFontColor: tooltipOpts.bodyFontColor,\n\t\t\t_bodyFontFamily: getValueOrDefault(tooltipOpts.bodyFontFamily, globalDefaults.defaultFontFamily),\n\t\t\t_bodyFontStyle: getValueOrDefault(tooltipOpts.bodyFontStyle, globalDefaults.defaultFontStyle),\n\t\t\t_bodyAlign: tooltipOpts.bodyAlign,\n\t\t\tbodyFontSize: getValueOrDefault(tooltipOpts.bodyFontSize, globalDefaults.defaultFontSize),\n\t\t\tbodySpacing: tooltipOpts.bodySpacing,\n\n\t\t\t// Title\n\t\t\ttitleFontColor: tooltipOpts.titleFontColor,\n\t\t\t_titleFontFamily: getValueOrDefault(tooltipOpts.titleFontFamily, globalDefaults.defaultFontFamily),\n\t\t\t_titleFontStyle: getValueOrDefault(tooltipOpts.titleFontStyle, globalDefaults.defaultFontStyle),\n\t\t\ttitleFontSize: getValueOrDefault(tooltipOpts.titleFontSize, globalDefaults.defaultFontSize),\n\t\t\t_titleAlign: tooltipOpts.titleAlign,\n\t\t\ttitleSpacing: tooltipOpts.titleSpacing,\n\t\t\ttitleMarginBottom: tooltipOpts.titleMarginBottom,\n\n\t\t\t// Footer\n\t\t\tfooterFontColor: tooltipOpts.footerFontColor,\n\t\t\t_footerFontFamily: getValueOrDefault(tooltipOpts.footerFontFamily, globalDefaults.defaultFontFamily),\n\t\t\t_footerFontStyle: getValueOrDefault(tooltipOpts.footerFontStyle, globalDefaults.defaultFontStyle),\n\t\t\tfooterFontSize: getValueOrDefault(tooltipOpts.footerFontSize, globalDefaults.defaultFontSize),\n\t\t\t_footerAlign: tooltipOpts.footerAlign,\n\t\t\tfooterSpacing: tooltipOpts.footerSpacing,\n\t\t\tfooterMarginTop: tooltipOpts.footerMarginTop,\n\n\t\t\t// Appearance\n\t\t\tcaretSize: tooltipOpts.caretSize,\n\t\t\tcornerRadius: tooltipOpts.cornerRadius,\n\t\t\tbackgroundColor: tooltipOpts.backgroundColor,\n\t\t\topacity: 0,\n\t\t\tlegendColorBackground: tooltipOpts.multiKeyBackground,\n\t\t\tdisplayColors: tooltipOpts.displayColors,\n\t\t\tborderColor: tooltipOpts.borderColor,\n\t\t\tborderWidth: tooltipOpts.borderWidth\n\t\t};\n\t}\n\n\t/**\n\t * Get the size of the tooltip\n\t */\n\tfunction getTooltipSize(tooltip, model) {\n\t\tvar ctx = tooltip._chart.ctx;\n\n\t\tvar height = model.yPadding * 2; // Tooltip Padding\n\t\tvar width = 0;\n\n\t\t// Count of all lines in the body\n\t\tvar body = model.body;\n\t\tvar combinedBodyLength = body.reduce(function(count, bodyItem) {\n\t\t\treturn count + bodyItem.before.length + bodyItem.lines.length + bodyItem.after.length;\n\t\t}, 0);\n\t\tcombinedBodyLength += model.beforeBody.length + model.afterBody.length;\n\n\t\tvar titleLineCount = model.title.length;\n\t\tvar footerLineCount = model.footer.length;\n\t\tvar titleFontSize = model.titleFontSize,\n\t\t\tbodyFontSize = model.bodyFontSize,\n\t\t\tfooterFontSize = model.footerFontSize;\n\n\t\theight += titleLineCount * titleFontSize; // Title Lines\n\t\theight += titleLineCount ? (titleLineCount - 1) * model.titleSpacing : 0; // Title Line Spacing\n\t\theight += titleLineCount ? model.titleMarginBottom : 0; // Title's bottom Margin\n\t\theight += combinedBodyLength * bodyFontSize; // Body Lines\n\t\theight += combinedBodyLength ? (combinedBodyLength - 1) * model.bodySpacing : 0; // Body Line Spacing\n\t\theight += footerLineCount ? model.footerMarginTop : 0; // Footer Margin\n\t\theight += footerLineCount * (footerFontSize); // Footer Lines\n\t\theight += footerLineCount ? (footerLineCount - 1) * model.footerSpacing : 0; // Footer Line Spacing\n\n\t\t// Title width\n\t\tvar widthPadding = 0;\n\t\tvar maxLineWidth = function(line) {\n\t\t\twidth = Math.max(width, ctx.measureText(line).width + widthPadding);\n\t\t};\n\n\t\tctx.font = helpers.fontString(titleFontSize, model._titleFontStyle, model._titleFontFamily);\n\t\thelpers.each(model.title, maxLineWidth);\n\n\t\t// Body width\n\t\tctx.font = helpers.fontString(bodyFontSize, model._bodyFontStyle, model._bodyFontFamily);\n\t\thelpers.each(model.beforeBody.concat(model.afterBody), maxLineWidth);\n\n\t\t// Body lines may include some extra width due to the color box\n\t\twidthPadding = model.displayColors ? (bodyFontSize + 2) : 0;\n\t\thelpers.each(body, function(bodyItem) {\n\t\t\thelpers.each(bodyItem.before, maxLineWidth);\n\t\t\thelpers.each(bodyItem.lines, maxLineWidth);\n\t\t\thelpers.each(bodyItem.after, maxLineWidth);\n\t\t});\n\n\t\t// Reset back to 0\n\t\twidthPadding = 0;\n\n\t\t// Footer width\n\t\tctx.font = helpers.fontString(footerFontSize, model._footerFontStyle, model._footerFontFamily);\n\t\thelpers.each(model.footer, maxLineWidth);\n\n\t\t// Add padding\n\t\twidth += 2 * model.xPadding;\n\n\t\treturn {\n\t\t\twidth: width,\n\t\t\theight: height\n\t\t};\n\t}\n\n\t/**\n\t * Helper to get the alignment of a tooltip given the size\n\t */\n\tfunction determineAlignment(tooltip, size) {\n\t\tvar model = tooltip._model;\n\t\tvar chart = tooltip._chart;\n\t\tvar chartArea = tooltip._chart.chartArea;\n\t\tvar xAlign = 'center';\n\t\tvar yAlign = 'center';\n\n\t\tif (model.y < size.height) {\n\t\t\tyAlign = 'top';\n\t\t} else if (model.y > (chart.height - size.height)) {\n\t\t\tyAlign = 'bottom';\n\t\t}\n\n\t\tvar lf, rf; // functions to determine left, right alignment\n\t\tvar olf, orf; // functions to determine if left/right alignment causes tooltip to go outside chart\n\t\tvar yf; // function to get the y alignment if the tooltip goes outside of the left or right edges\n\t\tvar midX = (chartArea.left + chartArea.right) / 2;\n\t\tvar midY = (chartArea.top + chartArea.bottom) / 2;\n\n\t\tif (yAlign === 'center') {\n\t\t\tlf = function(x) {\n\t\t\t\treturn x <= midX;\n\t\t\t};\n\t\t\trf = function(x) {\n\t\t\t\treturn x > midX;\n\t\t\t};\n\t\t} else {\n\t\t\tlf = function(x) {\n\t\t\t\treturn x <= (size.width / 2);\n\t\t\t};\n\t\t\trf = function(x) {\n\t\t\t\treturn x >= (chart.width - (size.width / 2));\n\t\t\t};\n\t\t}\n\n\t\tolf = function(x) {\n\t\t\treturn x + size.width > chart.width;\n\t\t};\n\t\torf = function(x) {\n\t\t\treturn x - size.width < 0;\n\t\t};\n\t\tyf = function(y) {\n\t\t\treturn y <= midY ? 'top' : 'bottom';\n\t\t};\n\n\t\tif (lf(model.x)) {\n\t\t\txAlign = 'left';\n\n\t\t\t// Is tooltip too wide and goes over the right side of the chart.?\n\t\t\tif (olf(model.x)) {\n\t\t\t\txAlign = 'center';\n\t\t\t\tyAlign = yf(model.y);\n\t\t\t}\n\t\t} else if (rf(model.x)) {\n\t\t\txAlign = 'right';\n\n\t\t\t// Is tooltip too wide and goes outside left edge of canvas?\n\t\t\tif (orf(model.x)) {\n\t\t\t\txAlign = 'center';\n\t\t\t\tyAlign = yf(model.y);\n\t\t\t}\n\t\t}\n\n\t\tvar opts = tooltip._options;\n\t\treturn {\n\t\t\txAlign: opts.xAlign ? opts.xAlign : xAlign,\n\t\t\tyAlign: opts.yAlign ? opts.yAlign : yAlign\n\t\t};\n\t}\n\n\t/**\n\t * @Helper to get the location a tooltip needs to be placed at given the initial position (via the vm) and the size and alignment\n\t */\n\tfunction getBackgroundPoint(vm, size, alignment) {\n\t\t// Background Position\n\t\tvar x = vm.x;\n\t\tvar y = vm.y;\n\n\t\tvar caretSize = vm.caretSize,\n\t\t\tcaretPadding = vm.caretPadding,\n\t\t\tcornerRadius = vm.cornerRadius,\n\t\t\txAlign = alignment.xAlign,\n\t\t\tyAlign = alignment.yAlign,\n\t\t\tpaddingAndSize = caretSize + caretPadding,\n\t\t\tradiusAndPadding = cornerRadius + caretPadding;\n\n\t\tif (xAlign === 'right') {\n\t\t\tx -= size.width;\n\t\t} else if (xAlign === 'center') {\n\t\t\tx -= (size.width / 2);\n\t\t}\n\n\t\tif (yAlign === 'top') {\n\t\t\ty += paddingAndSize;\n\t\t} else if (yAlign === 'bottom') {\n\t\t\ty -= size.height + paddingAndSize;\n\t\t} else {\n\t\t\ty -= (size.height / 2);\n\t\t}\n\n\t\tif (yAlign === 'center') {\n\t\t\tif (xAlign === 'left') {\n\t\t\t\tx += paddingAndSize;\n\t\t\t} else if (xAlign === 'right') {\n\t\t\t\tx -= paddingAndSize;\n\t\t\t}\n\t\t} else if (xAlign === 'left') {\n\t\t\tx -= radiusAndPadding;\n\t\t} else if (xAlign === 'right') {\n\t\t\tx += radiusAndPadding;\n\t\t}\n\n\t\treturn {\n\t\t\tx: x,\n\t\t\ty: y\n\t\t};\n\t}\n\n\tChart.Tooltip = Chart.Element.extend({\n\t\tinitialize: function() {\n\t\t\tthis._model = getBaseModel(this._options);\n\t\t},\n\n\t\t// Get the title\n\t\t// Args are: (tooltipItem, data)\n\t\tgetTitle: function() {\n\t\t\tvar me = this;\n\t\t\tvar opts = me._options;\n\t\t\tvar callbacks = opts.callbacks;\n\n\t\t\tvar beforeTitle = callbacks.beforeTitle.apply(me, arguments),\n\t\t\t\ttitle = callbacks.title.apply(me, arguments),\n\t\t\t\tafterTitle = callbacks.afterTitle.apply(me, arguments);\n\n\t\t\tvar lines = [];\n\t\t\tlines = pushOrConcat(lines, beforeTitle);\n\t\t\tlines = pushOrConcat(lines, title);\n\t\t\tlines = pushOrConcat(lines, afterTitle);\n\n\t\t\treturn lines;\n\t\t},\n\n\t\t// Args are: (tooltipItem, data)\n\t\tgetBeforeBody: function() {\n\t\t\tvar lines = this._options.callbacks.beforeBody.apply(this, arguments);\n\t\t\treturn helpers.isArray(lines) ? lines : lines !== undefined ? [lines] : [];\n\t\t},\n\n\t\t// Args are: (tooltipItem, data)\n\t\tgetBody: function(tooltipItems, data) {\n\t\t\tvar me = this;\n\t\t\tvar callbacks = me._options.callbacks;\n\t\t\tvar bodyItems = [];\n\n\t\t\thelpers.each(tooltipItems, function(tooltipItem) {\n\t\t\t\tvar bodyItem = {\n\t\t\t\t\tbefore: [],\n\t\t\t\t\tlines: [],\n\t\t\t\t\tafter: []\n\t\t\t\t};\n\t\t\t\tpushOrConcat(bodyItem.before, callbacks.beforeLabel.call(me, tooltipItem, data));\n\t\t\t\tpushOrConcat(bodyItem.lines, callbacks.label.call(me, tooltipItem, data));\n\t\t\t\tpushOrConcat(bodyItem.after, callbacks.afterLabel.call(me, tooltipItem, data));\n\n\t\t\t\tbodyItems.push(bodyItem);\n\t\t\t});\n\n\t\t\treturn bodyItems;\n\t\t},\n\n\t\t// Args are: (tooltipItem, data)\n\t\tgetAfterBody: function() {\n\t\t\tvar lines = this._options.callbacks.afterBody.apply(this, arguments);\n\t\t\treturn helpers.isArray(lines) ? lines : lines !== undefined ? [lines] : [];\n\t\t},\n\n\t\t// Get the footer and beforeFooter and afterFooter lines\n\t\t// Args are: (tooltipItem, data)\n\t\tgetFooter: function() {\n\t\t\tvar me = this;\n\t\t\tvar callbacks = me._options.callbacks;\n\n\t\t\tvar beforeFooter = callbacks.beforeFooter.apply(me, arguments);\n\t\t\tvar footer = callbacks.footer.apply(me, arguments);\n\t\t\tvar afterFooter = callbacks.afterFooter.apply(me, arguments);\n\n\t\t\tvar lines = [];\n\t\t\tlines = pushOrConcat(lines, beforeFooter);\n\t\t\tlines = pushOrConcat(lines, footer);\n\t\t\tlines = pushOrConcat(lines, afterFooter);\n\n\t\t\treturn lines;\n\t\t},\n\n\t\tupdate: function(changed) {\n\t\t\tvar me = this;\n\t\t\tvar opts = me._options;\n\n\t\t\t// Need to regenerate the model because its faster than using extend and it is necessary due to the optimization in Chart.Element.transition\n\t\t\t// that does _view = _model if ease === 1. This causes the 2nd tooltip update to set properties in both the view and model at the same time\n\t\t\t// which breaks any animations.\n\t\t\tvar existingModel = me._model;\n\t\t\tvar model = me._model = getBaseModel(opts);\n\t\t\tvar active = me._active;\n\n\t\t\tvar data = me._data;\n\n\t\t\t// In the case where active.length === 0 we need to keep these at existing values for good animations\n\t\t\tvar alignment = {\n\t\t\t\txAlign: existingModel.xAlign,\n\t\t\t\tyAlign: existingModel.yAlign\n\t\t\t};\n\t\t\tvar backgroundPoint = {\n\t\t\t\tx: existingModel.x,\n\t\t\t\ty: existingModel.y\n\t\t\t};\n\t\t\tvar tooltipSize = {\n\t\t\t\twidth: existingModel.width,\n\t\t\t\theight: existingModel.height\n\t\t\t};\n\t\t\tvar tooltipPosition = {\n\t\t\t\tx: existingModel.caretX,\n\t\t\t\ty: existingModel.caretY\n\t\t\t};\n\n\t\t\tvar i, len;\n\n\t\t\tif (active.length) {\n\t\t\t\tmodel.opacity = 1;\n\n\t\t\t\tvar labelColors = [];\n\t\t\t\ttooltipPosition = Chart.Tooltip.positioners[opts.position](active, me._eventPosition);\n\n\t\t\t\tvar tooltipItems = [];\n\t\t\t\tfor (i = 0, len = active.length; i < len; ++i) {\n\t\t\t\t\ttooltipItems.push(createTooltipItem(active[i]));\n\t\t\t\t}\n\n\t\t\t\t// If the user provided a filter function, use it to modify the tooltip items\n\t\t\t\tif (opts.filter) {\n\t\t\t\t\ttooltipItems = tooltipItems.filter(function(a) {\n\t\t\t\t\t\treturn opts.filter(a, data);\n\t\t\t\t\t});\n\t\t\t\t}\n\n\t\t\t\t// If the user provided a sorting function, use it to modify the tooltip items\n\t\t\t\tif (opts.itemSort) {\n\t\t\t\t\ttooltipItems = tooltipItems.sort(function(a, b) {\n\t\t\t\t\t\treturn opts.itemSort(a, b, data);\n\t\t\t\t\t});\n\t\t\t\t}\n\n\t\t\t\t// Determine colors for boxes\n\t\t\t\thelpers.each(tooltipItems, function(tooltipItem) {\n\t\t\t\t\tlabelColors.push(opts.callbacks.labelColor.call(me, tooltipItem, me._chart));\n\t\t\t\t});\n\n\t\t\t\t// Build the Text Lines\n\t\t\t\tmodel.title = me.getTitle(tooltipItems, data);\n\t\t\t\tmodel.beforeBody = me.getBeforeBody(tooltipItems, data);\n\t\t\t\tmodel.body = me.getBody(tooltipItems, data);\n\t\t\t\tmodel.afterBody = me.getAfterBody(tooltipItems, data);\n\t\t\t\tmodel.footer = me.getFooter(tooltipItems, data);\n\n\t\t\t\t// Initial positioning and colors\n\t\t\t\tmodel.x = Math.round(tooltipPosition.x);\n\t\t\t\tmodel.y = Math.round(tooltipPosition.y);\n\t\t\t\tmodel.caretPadding = opts.caretPadding;\n\t\t\t\tmodel.labelColors = labelColors;\n\n\t\t\t\t// data points\n\t\t\t\tmodel.dataPoints = tooltipItems;\n\n\t\t\t\t// We need to determine alignment of the tooltip\n\t\t\t\ttooltipSize = getTooltipSize(this, model);\n\t\t\t\talignment = determineAlignment(this, tooltipSize);\n\t\t\t\t// Final Size and Position\n\t\t\t\tbackgroundPoint = getBackgroundPoint(model, tooltipSize, alignment);\n\t\t\t} else {\n\t\t\t\tmodel.opacity = 0;\n\t\t\t}\n\n\t\t\tmodel.xAlign = alignment.xAlign;\n\t\t\tmodel.yAlign = alignment.yAlign;\n\t\t\tmodel.x = backgroundPoint.x;\n\t\t\tmodel.y = backgroundPoint.y;\n\t\t\tmodel.width = tooltipSize.width;\n\t\t\tmodel.height = tooltipSize.height;\n\n\t\t\t// Point where the caret on the tooltip points to\n\t\t\tmodel.caretX = tooltipPosition.x;\n\t\t\tmodel.caretY = tooltipPosition.y;\n\n\t\t\tme._model = model;\n\n\t\t\tif (changed && opts.custom) {\n\t\t\t\topts.custom.call(me, model);\n\t\t\t}\n\n\t\t\treturn me;\n\t\t},\n\t\tdrawCaret: function(tooltipPoint, size) {\n\t\t\tvar ctx = this._chart.ctx;\n\t\t\tvar vm = this._view;\n\t\t\tvar caretPosition = this.getCaretPosition(tooltipPoint, size, vm);\n\n\t\t\tctx.lineTo(caretPosition.x1, caretPosition.y1);\n\t\t\tctx.lineTo(caretPosition.x2, caretPosition.y2);\n\t\t\tctx.lineTo(caretPosition.x3, caretPosition.y3);\n\t\t},\n\t\tgetCaretPosition: function(tooltipPoint, size, vm) {\n\t\t\tvar x1, x2, x3;\n\t\t\tvar y1, y2, y3;\n\t\t\tvar caretSize = vm.caretSize;\n\t\t\tvar cornerRadius = vm.cornerRadius;\n\t\t\tvar xAlign = vm.xAlign,\n\t\t\t\tyAlign = vm.yAlign;\n\t\t\tvar ptX = tooltipPoint.x,\n\t\t\t\tptY = tooltipPoint.y;\n\t\t\tvar width = size.width,\n\t\t\t\theight = size.height;\n\n\t\t\tif (yAlign === 'center') {\n\t\t\t\ty2 = ptY + (height / 2);\n\n\t\t\t\tif (xAlign === 'left') {\n\t\t\t\t\tx1 = ptX;\n\t\t\t\t\tx2 = x1 - caretSize;\n\t\t\t\t\tx3 = x1;\n\n\t\t\t\t\ty1 = y2 + caretSize;\n\t\t\t\t\ty3 = y2 - caretSize;\n\t\t\t\t} else {\n\t\t\t\t\tx1 = ptX + width;\n\t\t\t\t\tx2 = x1 + caretSize;\n\t\t\t\t\tx3 = x1;\n\n\t\t\t\t\ty1 = y2 - caretSize;\n\t\t\t\t\ty3 = y2 + caretSize;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tif (xAlign === 'left') {\n\t\t\t\t\tx2 = ptX + cornerRadius + (caretSize);\n\t\t\t\t\tx1 = x2 - caretSize;\n\t\t\t\t\tx3 = x2 + caretSize;\n\t\t\t\t} else if (xAlign === 'right') {\n\t\t\t\t\tx2 = ptX + width - cornerRadius - caretSize;\n\t\t\t\t\tx1 = x2 - caretSize;\n\t\t\t\t\tx3 = x2 + caretSize;\n\t\t\t\t} else {\n\t\t\t\t\tx2 = ptX + (width / 2);\n\t\t\t\t\tx1 = x2 - caretSize;\n\t\t\t\t\tx3 = x2 + caretSize;\n\t\t\t\t}\n\t\t\t\tif (yAlign === 'top') {\n\t\t\t\t\ty1 = ptY;\n\t\t\t\t\ty2 = y1 - caretSize;\n\t\t\t\t\ty3 = y1;\n\t\t\t\t} else {\n\t\t\t\t\ty1 = ptY + height;\n\t\t\t\t\ty2 = y1 + caretSize;\n\t\t\t\t\ty3 = y1;\n\t\t\t\t\t// invert drawing order\n\t\t\t\t\tvar tmp = x3;\n\t\t\t\t\tx3 = x1;\n\t\t\t\t\tx1 = tmp;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn {x1: x1, x2: x2, x3: x3, y1: y1, y2: y2, y3: y3};\n\t\t},\n\t\tdrawTitle: function(pt, vm, ctx, opacity) {\n\t\t\tvar title = vm.title;\n\n\t\t\tif (title.length) {\n\t\t\t\tctx.textAlign = vm._titleAlign;\n\t\t\t\tctx.textBaseline = 'top';\n\n\t\t\t\tvar titleFontSize = vm.titleFontSize,\n\t\t\t\t\ttitleSpacing = vm.titleSpacing;\n\n\t\t\t\tctx.fillStyle = mergeOpacity(vm.titleFontColor, opacity);\n\t\t\t\tctx.font = helpers.fontString(titleFontSize, vm._titleFontStyle, vm._titleFontFamily);\n\n\t\t\t\tvar i, len;\n\t\t\t\tfor (i = 0, len = title.length; i < len; ++i) {\n\t\t\t\t\tctx.fillText(title[i], pt.x, pt.y);\n\t\t\t\t\tpt.y += titleFontSize + titleSpacing; // Line Height and spacing\n\n\t\t\t\t\tif (i + 1 === title.length) {\n\t\t\t\t\t\tpt.y += vm.titleMarginBottom - titleSpacing; // If Last, add margin, remove spacing\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\tdrawBody: function(pt, vm, ctx, opacity) {\n\t\t\tvar bodyFontSize = vm.bodyFontSize;\n\t\t\tvar bodySpacing = vm.bodySpacing;\n\t\t\tvar body = vm.body;\n\n\t\t\tctx.textAlign = vm._bodyAlign;\n\t\t\tctx.textBaseline = 'top';\n\n\t\t\tvar textColor = mergeOpacity(vm.bodyFontColor, opacity);\n\t\t\tctx.fillStyle = textColor;\n\t\t\tctx.font = helpers.fontString(bodyFontSize, vm._bodyFontStyle, vm._bodyFontFamily);\n\n\t\t\t// Before Body\n\t\t\tvar xLinePadding = 0;\n\t\t\tvar fillLineOfText = function(line) {\n\t\t\t\tctx.fillText(line, pt.x + xLinePadding, pt.y);\n\t\t\t\tpt.y += bodyFontSize + bodySpacing;\n\t\t\t};\n\n\t\t\t// Before body lines\n\t\t\thelpers.each(vm.beforeBody, fillLineOfText);\n\n\t\t\tvar drawColorBoxes = vm.displayColors;\n\t\t\txLinePadding = drawColorBoxes ? (bodyFontSize + 2) : 0;\n\n\t\t\t// Draw body lines now\n\t\t\thelpers.each(body, function(bodyItem, i) {\n\t\t\t\thelpers.each(bodyItem.before, fillLineOfText);\n\n\t\t\t\thelpers.each(bodyItem.lines, function(line) {\n\t\t\t\t\t// Draw Legend-like boxes if needed\n\t\t\t\t\tif (drawColorBoxes) {\n\t\t\t\t\t\t// Fill a white rect so that colours merge nicely if the opacity is < 1\n\t\t\t\t\t\tctx.fillStyle = mergeOpacity(vm.legendColorBackground, opacity);\n\t\t\t\t\t\tctx.fillRect(pt.x, pt.y, bodyFontSize, bodyFontSize);\n\n\t\t\t\t\t\t// Border\n\t\t\t\t\t\tctx.strokeStyle = mergeOpacity(vm.labelColors[i].borderColor, opacity);\n\t\t\t\t\t\tctx.strokeRect(pt.x, pt.y, bodyFontSize, bodyFontSize);\n\n\t\t\t\t\t\t// Inner square\n\t\t\t\t\t\tctx.fillStyle = mergeOpacity(vm.labelColors[i].backgroundColor, opacity);\n\t\t\t\t\t\tctx.fillRect(pt.x + 1, pt.y + 1, bodyFontSize - 2, bodyFontSize - 2);\n\n\t\t\t\t\t\tctx.fillStyle = textColor;\n\t\t\t\t\t}\n\n\t\t\t\t\tfillLineOfText(line);\n\t\t\t\t});\n\n\t\t\t\thelpers.each(bodyItem.after, fillLineOfText);\n\t\t\t});\n\n\t\t\t// Reset back to 0 for after body\n\t\t\txLinePadding = 0;\n\n\t\t\t// After body lines\n\t\t\thelpers.each(vm.afterBody, fillLineOfText);\n\t\t\tpt.y -= bodySpacing; // Remove last body spacing\n\t\t},\n\t\tdrawFooter: function(pt, vm, ctx, opacity) {\n\t\t\tvar footer = vm.footer;\n\n\t\t\tif (footer.length) {\n\t\t\t\tpt.y += vm.footerMarginTop;\n\n\t\t\t\tctx.textAlign = vm._footerAlign;\n\t\t\t\tctx.textBaseline = 'top';\n\n\t\t\t\tctx.fillStyle = mergeOpacity(vm.footerFontColor, opacity);\n\t\t\t\tctx.font = helpers.fontString(vm.footerFontSize, vm._footerFontStyle, vm._footerFontFamily);\n\n\t\t\t\thelpers.each(footer, function(line) {\n\t\t\t\t\tctx.fillText(line, pt.x, pt.y);\n\t\t\t\t\tpt.y += vm.footerFontSize + vm.footerSpacing;\n\t\t\t\t});\n\t\t\t}\n\t\t},\n\t\tdrawBackground: function(pt, vm, ctx, tooltipSize, opacity) {\n\t\t\tctx.fillStyle = mergeOpacity(vm.backgroundColor, opacity);\n\t\t\tctx.strokeStyle = mergeOpacity(vm.borderColor, opacity);\n\t\t\tctx.lineWidth = vm.borderWidth;\n\t\t\tvar xAlign = vm.xAlign;\n\t\t\tvar yAlign = vm.yAlign;\n\t\t\tvar x = pt.x;\n\t\t\tvar y = pt.y;\n\t\t\tvar width = tooltipSize.width;\n\t\t\tvar height = tooltipSize.height;\n\t\t\tvar radius = vm.cornerRadius;\n\n\t\t\tctx.beginPath();\n\t\t\tctx.moveTo(x + radius, y);\n\t\t\tif (yAlign === 'top') {\n\t\t\t\tthis.drawCaret(pt, tooltipSize);\n\t\t\t}\n\t\t\tctx.lineTo(x + width - radius, y);\n\t\t\tctx.quadraticCurveTo(x + width, y, x + width, y + radius);\n\t\t\tif (yAlign === 'center' && xAlign === 'right') {\n\t\t\t\tthis.drawCaret(pt, tooltipSize);\n\t\t\t}\n\t\t\tctx.lineTo(x + width, y + height - radius);\n\t\t\tctx.quadraticCurveTo(x + width, y + height, x + width - radius, y + height);\n\t\t\tif (yAlign === 'bottom') {\n\t\t\t\tthis.drawCaret(pt, tooltipSize);\n\t\t\t}\n\t\t\tctx.lineTo(x + radius, y + height);\n\t\t\tctx.quadraticCurveTo(x, y + height, x, y + height - radius);\n\t\t\tif (yAlign === 'center' && xAlign === 'left') {\n\t\t\t\tthis.drawCaret(pt, tooltipSize);\n\t\t\t}\n\t\t\tctx.lineTo(x, y + radius);\n\t\t\tctx.quadraticCurveTo(x, y, x + radius, y);\n\t\t\tctx.closePath();\n\n\t\t\tctx.fill();\n\n\t\t\tif (vm.borderWidth > 0) {\n\t\t\t\tctx.stroke();\n\t\t\t}\n\t\t},\n\t\tdraw: function() {\n\t\t\tvar ctx = this._chart.ctx;\n\t\t\tvar vm = this._view;\n\n\t\t\tif (vm.opacity === 0) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tvar tooltipSize = {\n\t\t\t\twidth: vm.width,\n\t\t\t\theight: vm.height\n\t\t\t};\n\t\t\tvar pt = {\n\t\t\t\tx: vm.x,\n\t\t\t\ty: vm.y\n\t\t\t};\n\n\t\t\t// IE11/Edge does not like very small opacities, so snap to 0\n\t\t\tvar opacity = Math.abs(vm.opacity < 1e-3) ? 0 : vm.opacity;\n\n\t\t\t// Truthy/falsey value for empty tooltip\n\t\t\tvar hasTooltipContent = vm.title.length || vm.beforeBody.length || vm.body.length || vm.afterBody.length || vm.footer.length;\n\n\t\t\tif (this._options.enabled && hasTooltipContent) {\n\t\t\t\t// Draw Background\n\t\t\t\tthis.drawBackground(pt, vm, ctx, tooltipSize, opacity);\n\n\t\t\t\t// Draw Title, Body, and Footer\n\t\t\t\tpt.x += vm.xPadding;\n\t\t\t\tpt.y += vm.yPadding;\n\n\t\t\t\t// Titles\n\t\t\t\tthis.drawTitle(pt, vm, ctx, opacity);\n\n\t\t\t\t// Body\n\t\t\t\tthis.drawBody(pt, vm, ctx, opacity);\n\n\t\t\t\t// Footer\n\t\t\t\tthis.drawFooter(pt, vm, ctx, opacity);\n\t\t\t}\n\t\t},\n\n\t\t/**\n\t\t * Handle an event\n\t\t * @private\n\t\t * @param {IEvent} event - The event to handle\n\t\t * @returns {Boolean} true if the tooltip changed\n\t\t */\n\t\thandleEvent: function(e) {\n\t\t\tvar me = this;\n\t\t\tvar options = me._options;\n\t\t\tvar changed = false;\n\n\t\t\tme._lastActive = me._lastActive || [];\n\n\t\t\t// Find Active Elements for tooltips\n\t\t\tif (e.type === 'mouseout') {\n\t\t\t\tme._active = [];\n\t\t\t} else {\n\t\t\t\tme._active = me._chart.getElementsAtEventForMode(e, options.mode, options);\n\t\t\t}\n\n\t\t\t// Remember Last Actives\n\t\t\tchanged = !helpers.arrayEquals(me._active, me._lastActive);\n\n\t\t\t// If tooltip didn't change, do not handle the target event\n\t\t\tif (!changed) {\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\tme._lastActive = me._active;\n\n\t\t\tif (options.enabled || options.custom) {\n\t\t\t\tme._eventPosition = {\n\t\t\t\t\tx: e.x,\n\t\t\t\t\ty: e.y\n\t\t\t\t};\n\n\t\t\t\tvar model = me._model;\n\t\t\t\tme.update(true);\n\t\t\t\tme.pivot();\n\n\t\t\t\t// See if our tooltip position changed\n\t\t\t\tchanged |= (model.x !== me._model.x) || (model.y !== me._model.y);\n\t\t\t}\n\n\t\t\treturn changed;\n\t\t}\n\t});\n\n\t/**\n\t * @namespace Chart.Tooltip.positioners\n\t */\n\tChart.Tooltip.positioners = {\n\t\t/**\n\t\t * Average mode places the tooltip at the average position of the elements shown\n\t\t * @function Chart.Tooltip.positioners.average\n\t\t * @param elements {ChartElement[]} the elements being displayed in the tooltip\n\t\t * @returns {Point} tooltip position\n\t\t */\n\t\taverage: function(elements) {\n\t\t\tif (!elements.length) {\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\tvar i, len;\n\t\t\tvar x = 0;\n\t\t\tvar y = 0;\n\t\t\tvar count = 0;\n\n\t\t\tfor (i = 0, len = elements.length; i < len; ++i) {\n\t\t\t\tvar el = elements[i];\n\t\t\t\tif (el && el.hasValue()) {\n\t\t\t\t\tvar pos = el.tooltipPosition();\n\t\t\t\t\tx += pos.x;\n\t\t\t\t\ty += pos.y;\n\t\t\t\t\t++count;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn {\n\t\t\t\tx: Math.round(x / count),\n\t\t\t\ty: Math.round(y / count)\n\t\t\t};\n\t\t},\n\n\t\t/**\n\t\t * Gets the tooltip position nearest of the item nearest to the event position\n\t\t * @function Chart.Tooltip.positioners.nearest\n\t\t * @param elements {Chart.Element[]} the tooltip elements\n\t\t * @param eventPosition {Point} the position of the event in canvas coordinates\n\t\t * @returns {Point} the tooltip position\n\t\t */\n\t\tnearest: function(elements, eventPosition) {\n\t\t\tvar x = eventPosition.x;\n\t\t\tvar y = eventPosition.y;\n\n\t\t\tvar nearestElement;\n\t\t\tvar minDistance = Number.POSITIVE_INFINITY;\n\t\t\tvar i, len;\n\t\t\tfor (i = 0, len = elements.length; i < len; ++i) {\n\t\t\t\tvar el = elements[i];\n\t\t\t\tif (el && el.hasValue()) {\n\t\t\t\t\tvar center = el.getCenterPoint();\n\t\t\t\t\tvar d = helpers.distanceBetweenPoints(eventPosition, center);\n\n\t\t\t\t\tif (d < minDistance) {\n\t\t\t\t\t\tminDistance = d;\n\t\t\t\t\t\tnearestElement = el;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (nearestElement) {\n\t\t\t\tvar tp = nearestElement.tooltipPosition();\n\t\t\t\tx = tp.x;\n\t\t\t\ty = tp.y;\n\t\t\t}\n\n\t\t\treturn {\n\t\t\t\tx: x,\n\t\t\t\ty: y\n\t\t\t};\n\t\t}\n\t};\n};\n\n},{}],35:[function(require,module,exports){\n'use strict';\n\nmodule.exports = function(Chart) {\n\n\tvar helpers = Chart.helpers,\n\t\tglobalOpts = Chart.defaults.global;\n\n\tglobalOpts.elements.arc = {\n\t\tbackgroundColor: globalOpts.defaultColor,\n\t\tborderColor: '#fff',\n\t\tborderWidth: 2\n\t};\n\n\tChart.elements.Arc = Chart.Element.extend({\n\t\tinLabelRange: function(mouseX) {\n\t\t\tvar vm = this._view;\n\n\t\t\tif (vm) {\n\t\t\t\treturn (Math.pow(mouseX - vm.x, 2) < Math.pow(vm.radius + vm.hoverRadius, 2));\n\t\t\t}\n\t\t\treturn false;\n\t\t},\n\t\tinRange: function(chartX, chartY) {\n\t\t\tvar vm = this._view;\n\n\t\t\tif (vm) {\n\t\t\t\tvar pointRelativePosition = helpers.getAngleFromPoint(vm, {\n\t\t\t\t\t\tx: chartX,\n\t\t\t\t\t\ty: chartY\n\t\t\t\t\t}),\n\t\t\t\t\tangle = pointRelativePosition.angle,\n\t\t\t\t\tdistance = pointRelativePosition.distance;\n\n\t\t\t\t// Sanitise angle range\n\t\t\t\tvar startAngle = vm.startAngle;\n\t\t\t\tvar endAngle = vm.endAngle;\n\t\t\t\twhile (endAngle < startAngle) {\n\t\t\t\t\tendAngle += 2.0 * Math.PI;\n\t\t\t\t}\n\t\t\t\twhile (angle > endAngle) {\n\t\t\t\t\tangle -= 2.0 * Math.PI;\n\t\t\t\t}\n\t\t\t\twhile (angle < startAngle) {\n\t\t\t\t\tangle += 2.0 * Math.PI;\n\t\t\t\t}\n\n\t\t\t\t// Check if within the range of the open/close angle\n\t\t\t\tvar betweenAngles = (angle >= startAngle && angle <= endAngle),\n\t\t\t\t\twithinRadius = (distance >= vm.innerRadius && distance <= vm.outerRadius);\n\n\t\t\t\treturn (betweenAngles && withinRadius);\n\t\t\t}\n\t\t\treturn false;\n\t\t},\n\t\tgetCenterPoint: function() {\n\t\t\tvar vm = this._view;\n\t\t\tvar halfAngle = (vm.startAngle + vm.endAngle) / 2;\n\t\t\tvar halfRadius = (vm.innerRadius + vm.outerRadius) / 2;\n\t\t\treturn {\n\t\t\t\tx: vm.x + Math.cos(halfAngle) * halfRadius,\n\t\t\t\ty: vm.y + Math.sin(halfAngle) * halfRadius\n\t\t\t};\n\t\t},\n\t\tgetArea: function() {\n\t\t\tvar vm = this._view;\n\t\t\treturn Math.PI * ((vm.endAngle - vm.startAngle) / (2 * Math.PI)) * (Math.pow(vm.outerRadius, 2) - Math.pow(vm.innerRadius, 2));\n\t\t},\n\t\ttooltipPosition: function() {\n\t\t\tvar vm = this._view;\n\n\t\t\tvar centreAngle = vm.startAngle + ((vm.endAngle - vm.startAngle) / 2),\n\t\t\t\trangeFromCentre = (vm.outerRadius - vm.innerRadius) / 2 + vm.innerRadius;\n\t\t\treturn {\n\t\t\t\tx: vm.x + (Math.cos(centreAngle) * rangeFromCentre),\n\t\t\t\ty: vm.y + (Math.sin(centreAngle) * rangeFromCentre)\n\t\t\t};\n\t\t},\n\t\tdraw: function() {\n\n\t\t\tvar ctx = this._chart.ctx,\n\t\t\t\tvm = this._view,\n\t\t\t\tsA = vm.startAngle,\n\t\t\t\teA = vm.endAngle;\n\n\t\t\tctx.beginPath();\n\n\t\t\tctx.arc(vm.x, vm.y, vm.outerRadius, sA, eA);\n\t\t\tctx.arc(vm.x, vm.y, vm.innerRadius, eA, sA, true);\n\n\t\t\tctx.closePath();\n\t\t\tctx.strokeStyle = vm.borderColor;\n\t\t\tctx.lineWidth = vm.borderWidth;\n\n\t\t\tctx.fillStyle = vm.backgroundColor;\n\n\t\t\tctx.fill();\n\t\t\tctx.lineJoin = 'bevel';\n\n\t\t\tif (vm.borderWidth) {\n\t\t\t\tctx.stroke();\n\t\t\t}\n\t\t}\n\t});\n};\n\n},{}],36:[function(require,module,exports){\n'use strict';\n\nmodule.exports = function(Chart) {\n\n\tvar helpers = Chart.helpers;\n\tvar globalDefaults = Chart.defaults.global;\n\n\tChart.defaults.global.elements.line = {\n\t\ttension: 0.4,\n\t\tbackgroundColor: globalDefaults.defaultColor,\n\t\tborderWidth: 3,\n\t\tborderColor: globalDefaults.defaultColor,\n\t\tborderCapStyle: 'butt',\n\t\tborderDash: [],\n\t\tborderDashOffset: 0.0,\n\t\tborderJoinStyle: 'miter',\n\t\tcapBezierPoints: true,\n\t\tfill: true, // do we fill in the area between the line and its base axis\n\t};\n\n\tChart.elements.Line = Chart.Element.extend({\n\t\tdraw: function() {\n\t\t\tvar me = this;\n\t\t\tvar vm = me._view;\n\t\t\tvar ctx = me._chart.ctx;\n\t\t\tvar spanGaps = vm.spanGaps;\n\t\t\tvar points = me._children.slice(); // clone array\n\t\t\tvar globalOptionLineElements = globalDefaults.elements.line;\n\t\t\tvar lastDrawnIndex = -1;\n\t\t\tvar index, current, previous, currentVM;\n\n\t\t\t// If we are looping, adding the first point again\n\t\t\tif (me._loop && points.length) {\n\t\t\t\tpoints.push(points[0]);\n\t\t\t}\n\n\t\t\tctx.save();\n\n\t\t\t// Stroke Line Options\n\t\t\tctx.lineCap = vm.borderCapStyle || globalOptionLineElements.borderCapStyle;\n\n\t\t\t// IE 9 and 10 do not support line dash\n\t\t\tif (ctx.setLineDash) {\n\t\t\t\tctx.setLineDash(vm.borderDash || globalOptionLineElements.borderDash);\n\t\t\t}\n\n\t\t\tctx.lineDashOffset = vm.borderDashOffset || globalOptionLineElements.borderDashOffset;\n\t\t\tctx.lineJoin = vm.borderJoinStyle || globalOptionLineElements.borderJoinStyle;\n\t\t\tctx.lineWidth = vm.borderWidth || globalOptionLineElements.borderWidth;\n\t\t\tctx.strokeStyle = vm.borderColor || globalDefaults.defaultColor;\n\n\t\t\t// Stroke Line\n\t\t\tctx.beginPath();\n\t\t\tlastDrawnIndex = -1;\n\n\t\t\tfor (index = 0; index < points.length; ++index) {\n\t\t\t\tcurrent = points[index];\n\t\t\t\tprevious = helpers.previousItem(points, index);\n\t\t\t\tcurrentVM = current._view;\n\n\t\t\t\t// First point moves to it's starting position no matter what\n\t\t\t\tif (index === 0) {\n\t\t\t\t\tif (!currentVM.skip) {\n\t\t\t\t\t\tctx.moveTo(currentVM.x, currentVM.y);\n\t\t\t\t\t\tlastDrawnIndex = index;\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tprevious = lastDrawnIndex === -1 ? previous : points[lastDrawnIndex];\n\n\t\t\t\t\tif (!currentVM.skip) {\n\t\t\t\t\t\tif ((lastDrawnIndex !== (index - 1) && !spanGaps) || lastDrawnIndex === -1) {\n\t\t\t\t\t\t\t// There was a gap and this is the first point after the gap\n\t\t\t\t\t\t\tctx.moveTo(currentVM.x, currentVM.y);\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t// Line to next point\n\t\t\t\t\t\t\thelpers.canvas.lineTo(ctx, previous._view, current._view);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tlastDrawnIndex = index;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tctx.stroke();\n\t\t\tctx.restore();\n\t\t}\n\t});\n};\n\n},{}],37:[function(require,module,exports){\n'use strict';\n\nmodule.exports = function(Chart) {\n\n\tvar helpers = Chart.helpers,\n\t\tglobalOpts = Chart.defaults.global,\n\t\tdefaultColor = globalOpts.defaultColor;\n\n\tglobalOpts.elements.point = {\n\t\tradius: 3,\n\t\tpointStyle: 'circle',\n\t\tbackgroundColor: defaultColor,\n\t\tborderWidth: 1,\n\t\tborderColor: defaultColor,\n\t\t// Hover\n\t\thitRadius: 1,\n\t\thoverRadius: 4,\n\t\thoverBorderWidth: 1\n\t};\n\n\tfunction xRange(mouseX) {\n\t\tvar vm = this._view;\n\t\treturn vm ? (Math.pow(mouseX - vm.x, 2) < Math.pow(vm.radius + vm.hitRadius, 2)) : false;\n\t}\n\n\tfunction yRange(mouseY) {\n\t\tvar vm = this._view;\n\t\treturn vm ? (Math.pow(mouseY - vm.y, 2) < Math.pow(vm.radius + vm.hitRadius, 2)) : false;\n\t}\n\n\tChart.elements.Point = Chart.Element.extend({\n\t\tinRange: function(mouseX, mouseY) {\n\t\t\tvar vm = this._view;\n\t\t\treturn vm ? ((Math.pow(mouseX - vm.x, 2) + Math.pow(mouseY - vm.y, 2)) < Math.pow(vm.hitRadius + vm.radius, 2)) : false;\n\t\t},\n\n\t\tinLabelRange: xRange,\n\t\tinXRange: xRange,\n\t\tinYRange: yRange,\n\n\t\tgetCenterPoint: function() {\n\t\t\tvar vm = this._view;\n\t\t\treturn {\n\t\t\t\tx: vm.x,\n\t\t\t\ty: vm.y\n\t\t\t};\n\t\t},\n\t\tgetArea: function() {\n\t\t\treturn Math.PI * Math.pow(this._view.radius, 2);\n\t\t},\n\t\ttooltipPosition: function() {\n\t\t\tvar vm = this._view;\n\t\t\treturn {\n\t\t\t\tx: vm.x,\n\t\t\t\ty: vm.y,\n\t\t\t\tpadding: vm.radius + vm.borderWidth\n\t\t\t};\n\t\t},\n\t\tdraw: function(chartArea) {\n\t\t\tvar vm = this._view;\n\t\t\tvar model = this._model;\n\t\t\tvar ctx = this._chart.ctx;\n\t\t\tvar pointStyle = vm.pointStyle;\n\t\t\tvar radius = vm.radius;\n\t\t\tvar x = vm.x;\n\t\t\tvar y = vm.y;\n\t\t\tvar color = Chart.helpers.color;\n\t\t\tvar errMargin = 1.01; // 1.01 is margin for Accumulated error. (Especially Edge, IE.)\n\t\t\tvar ratio = 0;\n\n\t\t\tif (vm.skip) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tctx.strokeStyle = vm.borderColor || defaultColor;\n\t\t\tctx.lineWidth = helpers.getValueOrDefault(vm.borderWidth, globalOpts.elements.point.borderWidth);\n\t\t\tctx.fillStyle = vm.backgroundColor || defaultColor;\n\n\t\t\t// Cliping for Points.\n\t\t\t// going out from inner charArea?\n\t\t\tif ((chartArea !== undefined) && ((model.x < chartArea.left) || (chartArea.right*errMargin < model.x) || (model.y < chartArea.top) || (chartArea.bottom*errMargin < model.y))) {\n\t\t\t\t// Point fade out\n\t\t\t\tif (model.x < chartArea.left) {\n\t\t\t\t\tratio = (x - model.x) / (chartArea.left - model.x);\n\t\t\t\t} else if (chartArea.right*errMargin < model.x) {\n\t\t\t\t\tratio = (model.x - x) / (model.x - chartArea.right);\n\t\t\t\t} else if (model.y < chartArea.top) {\n\t\t\t\t\tratio = (y - model.y) / (chartArea.top - model.y);\n\t\t\t\t} else if (chartArea.bottom*errMargin < model.y) {\n\t\t\t\t\tratio = (model.y - y) / (model.y - chartArea.bottom);\n\t\t\t\t}\n\t\t\t\tratio = Math.round(ratio*100) / 100;\n\t\t\t\tctx.strokeStyle = color(ctx.strokeStyle).alpha(ratio).rgbString();\n\t\t\t\tctx.fillStyle = color(ctx.fillStyle).alpha(ratio).rgbString();\n\t\t\t}\n\n\t\t\tChart.canvasHelpers.drawPoint(ctx, pointStyle, radius, x, y);\n\t\t}\n\t});\n};\n\n},{}],38:[function(require,module,exports){\n'use strict';\n\nmodule.exports = function(Chart) {\n\n\tvar globalOpts = Chart.defaults.global;\n\n\tglobalOpts.elements.rectangle = {\n\t\tbackgroundColor: globalOpts.defaultColor,\n\t\tborderWidth: 0,\n\t\tborderColor: globalOpts.defaultColor,\n\t\tborderSkipped: 'bottom'\n\t};\n\n\tfunction isVertical(bar) {\n\t\treturn bar._view.width !== undefined;\n\t}\n\n\t/**\n\t * Helper function to get the bounds of the bar regardless of the orientation\n\t * @private\n\t * @param bar {Chart.Element.Rectangle} the bar\n\t * @return {Bounds} bounds of the bar\n\t */\n\tfunction getBarBounds(bar) {\n\t\tvar vm = bar._view;\n\t\tvar x1, x2, y1, y2;\n\n\t\tif (isVertical(bar)) {\n\t\t\t// vertical\n\t\t\tvar halfWidth = vm.width / 2;\n\t\t\tx1 = vm.x - halfWidth;\n\t\t\tx2 = vm.x + halfWidth;\n\t\t\ty1 = Math.min(vm.y, vm.base);\n\t\t\ty2 = Math.max(vm.y, vm.base);\n\t\t} else {\n\t\t\t// horizontal bar\n\t\t\tvar halfHeight = vm.height / 2;\n\t\t\tx1 = Math.min(vm.x, vm.base);\n\t\t\tx2 = Math.max(vm.x, vm.base);\n\t\t\ty1 = vm.y - halfHeight;\n\t\t\ty2 = vm.y + halfHeight;\n\t\t}\n\n\t\treturn {\n\t\t\tleft: x1,\n\t\t\ttop: y1,\n\t\t\tright: x2,\n\t\t\tbottom: y2\n\t\t};\n\t}\n\n\tChart.elements.Rectangle = Chart.Element.extend({\n\t\tdraw: function() {\n\t\t\tvar ctx = this._chart.ctx;\n\t\t\tvar vm = this._view;\n\t\t\tvar left, right, top, bottom, signX, signY, borderSkipped;\n\t\t\tvar borderWidth = vm.borderWidth;\n\n\t\t\tif (!vm.horizontal) {\n\t\t\t\t// bar\n\t\t\t\tleft = vm.x - vm.width / 2;\n\t\t\t\tright = vm.x + vm.width / 2;\n\t\t\t\ttop = vm.y;\n\t\t\t\tbottom = vm.base;\n\t\t\t\tsignX = 1;\n\t\t\t\tsignY = bottom > top? 1: -1;\n\t\t\t\tborderSkipped = vm.borderSkipped || 'bottom';\n\t\t\t} else {\n\t\t\t\t// horizontal bar\n\t\t\t\tleft = vm.base;\n\t\t\t\tright = vm.x;\n\t\t\t\ttop = vm.y - vm.height / 2;\n\t\t\t\tbottom = vm.y + vm.height / 2;\n\t\t\t\tsignX = right > left? 1: -1;\n\t\t\t\tsignY = 1;\n\t\t\t\tborderSkipped = vm.borderSkipped || 'left';\n\t\t\t}\n\n\t\t\t// Canvas doesn't allow us to stroke inside the width so we can\n\t\t\t// adjust the sizes to fit if we're setting a stroke on the line\n\t\t\tif (borderWidth) {\n\t\t\t\t// borderWidth shold be less than bar width and bar height.\n\t\t\t\tvar barSize = Math.min(Math.abs(left - right), Math.abs(top - bottom));\n\t\t\t\tborderWidth = borderWidth > barSize? barSize: borderWidth;\n\t\t\t\tvar halfStroke = borderWidth / 2;\n\t\t\t\t// Adjust borderWidth when bar top position is near vm.base(zero).\n\t\t\t\tvar borderLeft = left + (borderSkipped !== 'left'? halfStroke * signX: 0);\n\t\t\t\tvar borderRight = right + (borderSkipped !== 'right'? -halfStroke * signX: 0);\n\t\t\t\tvar borderTop = top + (borderSkipped !== 'top'? halfStroke * signY: 0);\n\t\t\t\tvar borderBottom = bottom + (borderSkipped !== 'bottom'? -halfStroke * signY: 0);\n\t\t\t\t// not become a vertical line?\n\t\t\t\tif (borderLeft !== borderRight) {\n\t\t\t\t\ttop = borderTop;\n\t\t\t\t\tbottom = borderBottom;\n\t\t\t\t}\n\t\t\t\t// not become a horizontal line?\n\t\t\t\tif (borderTop !== borderBottom) {\n\t\t\t\t\tleft = borderLeft;\n\t\t\t\t\tright = borderRight;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tctx.beginPath();\n\t\t\tctx.fillStyle = vm.backgroundColor;\n\t\t\tctx.strokeStyle = vm.borderColor;\n\t\t\tctx.lineWidth = borderWidth;\n\n\t\t\t// Corner points, from bottom-left to bottom-right clockwise\n\t\t\t// | 1 2 |\n\t\t\t// | 0 3 |\n\t\t\tvar corners = [\n\t\t\t\t[left, bottom],\n\t\t\t\t[left, top],\n\t\t\t\t[right, top],\n\t\t\t\t[right, bottom]\n\t\t\t];\n\n\t\t\t// Find first (starting) corner with fallback to 'bottom'\n\t\t\tvar borders = ['bottom', 'left', 'top', 'right'];\n\t\t\tvar startCorner = borders.indexOf(borderSkipped, 0);\n\t\t\tif (startCorner === -1) {\n\t\t\t\tstartCorner = 0;\n\t\t\t}\n\n\t\t\tfunction cornerAt(index) {\n\t\t\t\treturn corners[(startCorner + index) % 4];\n\t\t\t}\n\n\t\t\t// Draw rectangle from 'startCorner'\n\t\t\tvar corner = cornerAt(0);\n\t\t\tctx.moveTo(corner[0], corner[1]);\n\n\t\t\tfor (var i = 1; i < 4; i++) {\n\t\t\t\tcorner = cornerAt(i);\n\t\t\t\tctx.lineTo(corner[0], corner[1]);\n\t\t\t}\n\n\t\t\tctx.fill();\n\t\t\tif (borderWidth) {\n\t\t\t\tctx.stroke();\n\t\t\t}\n\t\t},\n\t\theight: function() {\n\t\t\tvar vm = this._view;\n\t\t\treturn vm.base - vm.y;\n\t\t},\n\t\tinRange: function(mouseX, mouseY) {\n\t\t\tvar inRange = false;\n\n\t\t\tif (this._view) {\n\t\t\t\tvar bounds = getBarBounds(this);\n\t\t\t\tinRange = mouseX >= bounds.left && mouseX <= bounds.right && mouseY >= bounds.top && mouseY <= bounds.bottom;\n\t\t\t}\n\n\t\t\treturn inRange;\n\t\t},\n\t\tinLabelRange: function(mouseX, mouseY) {\n\t\t\tvar me = this;\n\t\t\tif (!me._view) {\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\tvar inRange = false;\n\t\t\tvar bounds = getBarBounds(me);\n\n\t\t\tif (isVertical(me)) {\n\t\t\t\tinRange = mouseX >= bounds.left && mouseX <= bounds.right;\n\t\t\t} else {\n\t\t\t\tinRange = mouseY >= bounds.top && mouseY <= bounds.bottom;\n\t\t\t}\n\n\t\t\treturn inRange;\n\t\t},\n\t\tinXRange: function(mouseX) {\n\t\t\tvar bounds = getBarBounds(this);\n\t\t\treturn mouseX >= bounds.left && mouseX <= bounds.right;\n\t\t},\n\t\tinYRange: function(mouseY) {\n\t\t\tvar bounds = getBarBounds(this);\n\t\t\treturn mouseY >= bounds.top && mouseY <= bounds.bottom;\n\t\t},\n\t\tgetCenterPoint: function() {\n\t\t\tvar vm = this._view;\n\t\t\tvar x, y;\n\t\t\tif (isVertical(this)) {\n\t\t\t\tx = vm.x;\n\t\t\t\ty = (vm.y + vm.base) / 2;\n\t\t\t} else {\n\t\t\t\tx = (vm.x + vm.base) / 2;\n\t\t\t\ty = vm.y;\n\t\t\t}\n\n\t\t\treturn {x: x, y: y};\n\t\t},\n\t\tgetArea: function() {\n\t\t\tvar vm = this._view;\n\t\t\treturn vm.width * Math.abs(vm.y - vm.base);\n\t\t},\n\t\ttooltipPosition: function() {\n\t\t\tvar vm = this._view;\n\t\t\treturn {\n\t\t\t\tx: vm.x,\n\t\t\t\ty: vm.y\n\t\t\t};\n\t\t}\n\t});\n\n};\n\n},{}],39:[function(require,module,exports){\n'use strict';\n\n// Chart.Platform implementation for targeting a web browser\nmodule.exports = function(Chart) {\n\tvar helpers = Chart.helpers;\n\n\t// DOM event types -> Chart.js event types.\n\t// Note: only events with different types are mapped.\n\t// https://developer.mozilla.org/en-US/docs/Web/Events\n\tvar eventTypeMap = {\n\t\t// Touch events\n\t\ttouchstart: 'mousedown',\n\t\ttouchmove: 'mousemove',\n\t\ttouchend: 'mouseup',\n\n\t\t// Pointer events\n\t\tpointerenter: 'mouseenter',\n\t\tpointerdown: 'mousedown',\n\t\tpointermove: 'mousemove',\n\t\tpointerup: 'mouseup',\n\t\tpointerleave: 'mouseout',\n\t\tpointerout: 'mouseout'\n\t};\n\n\t/**\n\t * The \"used\" size is the final value of a dimension property after all calculations have\n\t * been performed. This method uses the computed style of `element` but returns undefined\n\t * if the computed style is not expressed in pixels. That can happen in some cases where\n\t * `element` has a size relative to its parent and this last one is not yet displayed,\n\t * for example because of `display: none` on a parent node.\n\t * @see https://developer.mozilla.org/en-US/docs/Web/CSS/used_value\n\t * @returns {Number} Size in pixels or undefined if unknown.\n\t */\n\tfunction readUsedSize(element, property) {\n\t\tvar value = helpers.getStyle(element, property);\n\t\tvar matches = value && value.match(/^(\\d+)(\\.\\d+)?px$/);\n\t\treturn matches? Number(matches[1]) : undefined;\n\t}\n\n\t/**\n\t * Initializes the canvas style and render size without modifying the canvas display size,\n\t * since responsiveness is handled by the controller.resize() method. The config is used\n\t * to determine the aspect ratio to apply in case no explicit height has been specified.\n\t */\n\tfunction initCanvas(canvas, config) {\n\t\tvar style = canvas.style;\n\n\t\t// NOTE(SB) canvas.getAttribute('width') !== canvas.width: in the first case it\n\t\t// returns null or '' if no explicit value has been set to the canvas attribute.\n\t\tvar renderHeight = canvas.getAttribute('height');\n\t\tvar renderWidth = canvas.getAttribute('width');\n\n\t\t// Chart.js modifies some canvas values that we want to restore on destroy\n\t\tcanvas._chartjs = {\n\t\t\tinitial: {\n\t\t\t\theight: renderHeight,\n\t\t\t\twidth: renderWidth,\n\t\t\t\tstyle: {\n\t\t\t\t\tdisplay: style.display,\n\t\t\t\t\theight: style.height,\n\t\t\t\t\twidth: style.width\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\n\t\t// Force canvas to display as block to avoid extra space caused by inline\n\t\t// elements, which would interfere with the responsive resize process.\n\t\t// https://github.com/chartjs/Chart.js/issues/2538\n\t\tstyle.display = style.display || 'block';\n\n\t\tif (renderWidth === null || renderWidth === '') {\n\t\t\tvar displayWidth = readUsedSize(canvas, 'width');\n\t\t\tif (displayWidth !== undefined) {\n\t\t\t\tcanvas.width = displayWidth;\n\t\t\t}\n\t\t}\n\n\t\tif (renderHeight === null || renderHeight === '') {\n\t\t\tif (canvas.style.height === '') {\n\t\t\t\t// If no explicit render height and style height, let's apply the aspect ratio,\n\t\t\t\t// which one can be specified by the user but also by charts as default option\n\t\t\t\t// (i.e. options.aspectRatio). If not specified, use canvas aspect ratio of 2.\n\t\t\t\tcanvas.height = canvas.width / (config.options.aspectRatio || 2);\n\t\t\t} else {\n\t\t\t\tvar displayHeight = readUsedSize(canvas, 'height');\n\t\t\t\tif (displayWidth !== undefined) {\n\t\t\t\t\tcanvas.height = displayHeight;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn canvas;\n\t}\n\n\tfunction createEvent(type, chart, x, y, nativeEvent) {\n\t\treturn {\n\t\t\ttype: type,\n\t\t\tchart: chart,\n\t\t\tnative: nativeEvent || null,\n\t\t\tx: x !== undefined? x : null,\n\t\t\ty: y !== undefined? y : null,\n\t\t};\n\t}\n\n\tfunction fromNativeEvent(event, chart) {\n\t\tvar type = eventTypeMap[event.type] || event.type;\n\t\tvar pos = helpers.getRelativePosition(event, chart);\n\t\treturn createEvent(type, chart, pos.x, pos.y, event);\n\t}\n\n\tfunction createResizer(handler) {\n\t\tvar iframe = document.createElement('iframe');\n\t\tiframe.className = 'chartjs-hidden-iframe';\n\t\tiframe.style.cssText =\n\t\t\t'display:block;'+\n\t\t\t'overflow:hidden;'+\n\t\t\t'border:0;'+\n\t\t\t'margin:0;'+\n\t\t\t'top:0;'+\n\t\t\t'left:0;'+\n\t\t\t'bottom:0;'+\n\t\t\t'right:0;'+\n\t\t\t'height:100%;'+\n\t\t\t'width:100%;'+\n\t\t\t'position:absolute;'+\n\t\t\t'pointer-events:none;'+\n\t\t\t'z-index:-1;';\n\n\t\t// Prevent the iframe to gain focus on tab.\n\t\t// https://github.com/chartjs/Chart.js/issues/3090\n\t\tiframe.tabIndex = -1;\n\n\t\t// If the iframe is re-attached to the DOM, the resize listener is removed because the\n\t\t// content is reloaded, so make sure to install the handler after the iframe is loaded.\n\t\t// https://github.com/chartjs/Chart.js/issues/3521\n\t\thelpers.addEvent(iframe, 'load', function() {\n\t\t\thelpers.addEvent(iframe.contentWindow || iframe, 'resize', handler);\n\n\t\t\t// The iframe size might have changed while loading, which can also\n\t\t\t// happen if the size has been changed while detached from the DOM.\n\t\t\thandler();\n\t\t});\n\n\t\treturn iframe;\n\t}\n\n\tfunction addResizeListener(node, listener, chart) {\n\t\tvar stub = node._chartjs = {\n\t\t\tticking: false\n\t\t};\n\n\t\t// Throttle the callback notification until the next animation frame.\n\t\tvar notify = function() {\n\t\t\tif (!stub.ticking) {\n\t\t\t\tstub.ticking = true;\n\t\t\t\thelpers.requestAnimFrame.call(window, function() {\n\t\t\t\t\tif (stub.resizer) {\n\t\t\t\t\t\tstub.ticking = false;\n\t\t\t\t\t\treturn listener(createEvent('resize', chart));\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t}\n\t\t};\n\n\t\t// Let's keep track of this added iframe and thus avoid DOM query when removing it.\n\t\tstub.resizer = createResizer(notify);\n\n\t\tnode.insertBefore(stub.resizer, node.firstChild);\n\t}\n\n\tfunction removeResizeListener(node) {\n\t\tif (!node || !node._chartjs) {\n\t\t\treturn;\n\t\t}\n\n\t\tvar resizer = node._chartjs.resizer;\n\t\tif (resizer) {\n\t\t\tresizer.parentNode.removeChild(resizer);\n\t\t\tnode._chartjs.resizer = null;\n\t\t}\n\n\t\tdelete node._chartjs;\n\t}\n\n\treturn {\n\t\tacquireContext: function(item, config) {\n\t\t\tif (typeof item === 'string') {\n\t\t\t\titem = document.getElementById(item);\n\t\t\t} else if (item.length) {\n\t\t\t\t// Support for array based queries (such as jQuery)\n\t\t\t\titem = item[0];\n\t\t\t}\n\n\t\t\tif (item && item.canvas) {\n\t\t\t\t// Support for any object associated to a canvas (including a context2d)\n\t\t\t\titem = item.canvas;\n\t\t\t}\n\n\t\t\t// To prevent canvas fingerprinting, some add-ons undefine the getContext\n\t\t\t// method, for example: https://github.com/kkapsner/CanvasBlocker\n\t\t\t// https://github.com/chartjs/Chart.js/issues/2807\n\t\t\tvar context = item && item.getContext && item.getContext('2d');\n\n\t\t\t// `instanceof HTMLCanvasElement/CanvasRenderingContext2D` fails when the item is\n\t\t\t// inside an iframe or when running in a protected environment. We could guess the\n\t\t\t// types from their toString() value but let's keep things flexible and assume it's\n\t\t\t// a sufficient condition if the item has a context2D which has item as `canvas`.\n\t\t\t// https://github.com/chartjs/Chart.js/issues/3887\n\t\t\t// https://github.com/chartjs/Chart.js/issues/4102\n\t\t\t// https://github.com/chartjs/Chart.js/issues/4152\n\t\t\tif (context && context.canvas === item) {\n\t\t\t\tinitCanvas(item, config);\n\t\t\t\treturn context;\n\t\t\t}\n\n\t\t\treturn null;\n\t\t},\n\n\t\treleaseContext: function(context) {\n\t\t\tvar canvas = context.canvas;\n\t\t\tif (!canvas._chartjs) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tvar initial = canvas._chartjs.initial;\n\t\t\t['height', 'width'].forEach(function(prop) {\n\t\t\t\tvar value = initial[prop];\n\t\t\t\tif (value === undefined || value === null) {\n\t\t\t\t\tcanvas.removeAttribute(prop);\n\t\t\t\t} else {\n\t\t\t\t\tcanvas.setAttribute(prop, value);\n\t\t\t\t}\n\t\t\t});\n\n\t\t\thelpers.each(initial.style || {}, function(value, key) {\n\t\t\t\tcanvas.style[key] = value;\n\t\t\t});\n\n\t\t\t// The canvas render size might have been changed (and thus the state stack discarded),\n\t\t\t// we can't use save() and restore() to restore the initial state. So make sure that at\n\t\t\t// least the canvas context is reset to the default state by setting the canvas width.\n\t\t\t// https://www.w3.org/TR/2011/WD-html5-20110525/the-canvas-element.html\n\t\t\tcanvas.width = canvas.width;\n\n\t\t\tdelete canvas._chartjs;\n\t\t},\n\n\t\taddEventListener: function(chart, type, listener) {\n\t\t\tvar canvas = chart.canvas;\n\t\t\tif (type === 'resize') {\n\t\t\t\t// Note: the resize event is not supported on all browsers.\n\t\t\t\taddResizeListener(canvas.parentNode, listener, chart);\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tvar stub = listener._chartjs || (listener._chartjs = {});\n\t\t\tvar proxies = stub.proxies || (stub.proxies = {});\n\t\t\tvar proxy = proxies[chart.id + '_' + type] = function(event) {\n\t\t\t\tlistener(fromNativeEvent(event, chart));\n\t\t\t};\n\n\t\t\thelpers.addEvent(canvas, type, proxy);\n\t\t},\n\n\t\tremoveEventListener: function(chart, type, listener) {\n\t\t\tvar canvas = chart.canvas;\n\t\t\tif (type === 'resize') {\n\t\t\t\t// Note: the resize event is not supported on all browsers.\n\t\t\t\tremoveResizeListener(canvas.parentNode, listener);\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tvar stub = listener._chartjs || {};\n\t\t\tvar proxies = stub.proxies || {};\n\t\t\tvar proxy = proxies[chart.id + '_' + type];\n\t\t\tif (!proxy) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\thelpers.removeEvent(canvas, type, proxy);\n\t\t}\n\t};\n};\n\n},{}],40:[function(require,module,exports){\n'use strict';\n\n// By default, select the browser (DOM) platform.\n// @TODO Make possible to select another platform at build time.\nvar implementation = require(39);\n\nmodule.exports = function(Chart) {\n\t/**\n\t * @namespace Chart.platform\n\t * @see https://chartjs.gitbooks.io/proposals/content/Platform.html\n\t * @since 2.4.0\n\t */\n\tChart.platform = {\n\t\t/**\n\t\t * Called at chart construction time, returns a context2d instance implementing\n\t\t * the [W3C Canvas 2D Context API standard]{@link https://www.w3.org/TR/2dcontext/}.\n\t\t * @param {*} item - The native item from which to acquire context (platform specific)\n\t\t * @param {Object} options - The chart options\n\t\t * @returns {CanvasRenderingContext2D} context2d instance\n\t\t */\n\t\tacquireContext: function() {},\n\n\t\t/**\n\t\t * Called at chart destruction time, releases any resources associated to the context\n\t\t * previously returned by the acquireContext() method.\n\t\t * @param {CanvasRenderingContext2D} context - The context2d instance\n\t\t * @returns {Boolean} true if the method succeeded, else false\n\t\t */\n\t\treleaseContext: function() {},\n\n\t\t/**\n\t\t * Registers the specified listener on the given chart.\n\t\t * @param {Chart} chart - Chart from which to listen for event\n\t\t * @param {String} type - The ({@link IEvent}) type to listen for\n\t\t * @param {Function} listener - Receives a notification (an object that implements\n\t\t * the {@link IEvent} interface) when an event of the specified type occurs.\n\t\t */\n\t\taddEventListener: function() {},\n\n\t\t/**\n\t\t * Removes the specified listener previously registered with addEventListener.\n\t\t * @param {Chart} chart -Chart from which to remove the listener\n\t\t * @param {String} type - The ({@link IEvent}) type to remove\n\t\t * @param {Function} listener - The listener function to remove from the event target.\n\t\t */\n\t\tremoveEventListener: function() {}\n\t};\n\n\t/**\n\t * @interface IPlatform\n\t * Allows abstracting platform dependencies away from the chart\n\t * @borrows Chart.platform.acquireContext as acquireContext\n\t * @borrows Chart.platform.releaseContext as releaseContext\n\t * @borrows Chart.platform.addEventListener as addEventListener\n\t * @borrows Chart.platform.removeEventListener as removeEventListener\n\t */\n\n\t/**\n\t * @interface IEvent\n\t * @prop {String} type - The event type name, possible values are:\n\t * 'contextmenu', 'mouseenter', 'mousedown', 'mousemove', 'mouseup', 'mouseout',\n\t * 'click', 'dblclick', 'keydown', 'keypress', 'keyup' and 'resize'\n\t * @prop {*} native - The original native event (null for emulated events, e.g. 'resize')\n\t * @prop {Number} x - The mouse x position, relative to the canvas (null for incompatible events)\n\t * @prop {Number} y - The mouse y position, relative to the canvas (null for incompatible events)\n\t */\n\n\tChart.helpers.extend(Chart.platform, implementation(Chart));\n};\n\n},{\"39\":39}],41:[function(require,module,exports){\n'use strict';\n\nmodule.exports = function(Chart) {\n\t/**\n\t * Plugin based on discussion from the following Chart.js issues:\n\t * @see https://github.com/chartjs/Chart.js/issues/2380#issuecomment-279961569\n\t * @see https://github.com/chartjs/Chart.js/issues/2440#issuecomment-256461897\n\t */\n\tChart.defaults.global.plugins.filler = {\n\t\tpropagate: true\n\t};\n\n\tvar defaults = Chart.defaults;\n\tvar helpers = Chart.helpers;\n\tvar mappers = {\n\t\tdataset: function(source) {\n\t\t\tvar index = source.fill;\n\t\t\tvar chart = source.chart;\n\t\t\tvar meta = chart.getDatasetMeta(index);\n\t\t\tvar visible = meta && chart.isDatasetVisible(index);\n\t\t\tvar points = (visible && meta.dataset._children) || [];\n\n\t\t\treturn !points.length? null : function(point, i) {\n\t\t\t\treturn points[i]._view || null;\n\t\t\t};\n\t\t},\n\n\t\tboundary: function(source) {\n\t\t\tvar boundary = source.boundary;\n\t\t\tvar x = boundary? boundary.x : null;\n\t\t\tvar y = boundary? boundary.y : null;\n\n\t\t\treturn function(point) {\n\t\t\t\treturn {\n\t\t\t\t\tx: x === null? point.x : x,\n\t\t\t\t\ty: y === null? point.y : y,\n\t\t\t\t};\n\t\t\t};\n\t\t}\n\t};\n\n\t// @todo if (fill[0] === '#')\n\tfunction decodeFill(el, index, count) {\n\t\tvar model = el._model || {};\n\t\tvar fill = model.fill;\n\t\tvar target;\n\n\t\tif (fill === undefined) {\n\t\t\tfill = !!model.backgroundColor;\n\t\t}\n\n\t\tif (fill === false || fill === null) {\n\t\t\treturn false;\n\t\t}\n\n\t\tif (fill === true) {\n\t\t\treturn 'origin';\n\t\t}\n\n\t\ttarget = parseFloat(fill, 10);\n\t\tif (isFinite(target) && Math.floor(target) === target) {\n\t\t\tif (fill[0] === '-' || fill[0] === '+') {\n\t\t\t\ttarget = index + target;\n\t\t\t}\n\n\t\t\tif (target === index || target < 0 || target >= count) {\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\treturn target;\n\t\t}\n\n\t\tswitch (fill) {\n\t\t// compatibility\n\t\tcase 'bottom':\n\t\t\treturn 'start';\n\t\tcase 'top':\n\t\t\treturn 'end';\n\t\tcase 'zero':\n\t\t\treturn 'origin';\n\t\t// supported boundaries\n\t\tcase 'origin':\n\t\tcase 'start':\n\t\tcase 'end':\n\t\t\treturn fill;\n\t\t// invalid fill values\n\t\tdefault:\n\t\t\treturn false;\n\t\t}\n\t}\n\n\tfunction computeBoundary(source) {\n\t\tvar model = source.el._model || {};\n\t\tvar scale = source.el._scale || {};\n\t\tvar fill = source.fill;\n\t\tvar target = null;\n\t\tvar horizontal;\n\n\t\tif (isFinite(fill)) {\n\t\t\treturn null;\n\t\t}\n\n\t\t// Backward compatibility: until v3, we still need to support boundary values set on\n\t\t// the model (scaleTop, scaleBottom and scaleZero) because some external plugins and\n\t\t// controllers might still use it (e.g. the Smith chart).\n\n\t\tif (fill === 'start') {\n\t\t\ttarget = model.scaleBottom === undefined? scale.bottom : model.scaleBottom;\n\t\t} else if (fill === 'end') {\n\t\t\ttarget = model.scaleTop === undefined? scale.top : model.scaleTop;\n\t\t} else if (model.scaleZero !== undefined) {\n\t\t\ttarget = model.scaleZero;\n\t\t} else if (scale.getBasePosition) {\n\t\t\ttarget = scale.getBasePosition();\n\t\t} else if (scale.getBasePixel) {\n\t\t\ttarget = scale.getBasePixel();\n\t\t}\n\n\t\tif (target !== undefined && target !== null) {\n\t\t\tif (target.x !== undefined && target.y !== undefined) {\n\t\t\t\treturn target;\n\t\t\t}\n\n\t\t\tif (typeof target === 'number' && isFinite(target)) {\n\t\t\t\thorizontal = scale.isHorizontal();\n\t\t\t\treturn {\n\t\t\t\t\tx: horizontal? target : null,\n\t\t\t\t\ty: horizontal? null : target\n\t\t\t\t};\n\t\t\t}\n\t\t}\n\n\t\treturn null;\n\t}\n\n\tfunction resolveTarget(sources, index, propagate) {\n\t\tvar source = sources[index];\n\t\tvar fill = source.fill;\n\t\tvar visited = [index];\n\t\tvar target;\n\n\t\tif (!propagate) {\n\t\t\treturn fill;\n\t\t}\n\n\t\twhile (fill !== false && visited.indexOf(fill) === -1) {\n\t\t\tif (!isFinite(fill)) {\n\t\t\t\treturn fill;\n\t\t\t}\n\n\t\t\ttarget = sources[fill];\n\t\t\tif (!target) {\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\tif (target.visible) {\n\t\t\t\treturn fill;\n\t\t\t}\n\n\t\t\tvisited.push(fill);\n\t\t\tfill = target.fill;\n\t\t}\n\n\t\treturn false;\n\t}\n\n\tfunction createMapper(source) {\n\t\tvar fill = source.fill;\n\t\tvar type = 'dataset';\n\n\t\tif (fill === false) {\n\t\t\treturn null;\n\t\t}\n\n\t\tif (!isFinite(fill)) {\n\t\t\ttype = 'boundary';\n\t\t}\n\n\t\treturn mappers[type](source);\n\t}\n\n\tfunction isDrawable(point) {\n\t\treturn point && !point.skip;\n\t}\n\n\tfunction drawArea(ctx, curve0, curve1, len0, len1) {\n\t\tvar i;\n\n\t\tif (!len0 || !len1) {\n\t\t\treturn;\n\t\t}\n\n\t\t// building first area curve (normal)\n\t\tctx.moveTo(curve0[0].x, curve0[0].y);\n\t\tfor (i=1; i<len0; ++i) {\n\t\t\thelpers.canvas.lineTo(ctx, curve0[i-1], curve0[i]);\n\t\t}\n\n\t\t// joining the two area curves\n\t\tctx.lineTo(curve1[len1-1].x, curve1[len1-1].y);\n\n\t\t// building opposite area curve (reverse)\n\t\tfor (i=len1-1; i>0; --i) {\n\t\t\thelpers.canvas.lineTo(ctx, curve1[i], curve1[i-1], true);\n\t\t}\n\t}\n\n\tfunction doFill(ctx, points, mapper, view, color, loop) {\n\t\tvar count = points.length;\n\t\tvar span = view.spanGaps;\n\t\tvar curve0 = [];\n\t\tvar curve1 = [];\n\t\tvar len0 = 0;\n\t\tvar len1 = 0;\n\t\tvar i, ilen, index, p0, p1, d0, d1;\n\n\t\tctx.beginPath();\n\n\t\tfor (i = 0, ilen = (count + !!loop); i < ilen; ++i) {\n\t\t\tindex = i%count;\n\t\t\tp0 = points[index]._view;\n\t\t\tp1 = mapper(p0, index, view);\n\t\t\td0 = isDrawable(p0);\n\t\t\td1 = isDrawable(p1);\n\n\t\t\tif (d0 && d1) {\n\t\t\t\tlen0 = curve0.push(p0);\n\t\t\t\tlen1 = curve1.push(p1);\n\t\t\t} else if (len0 && len1) {\n\t\t\t\tif (!span) {\n\t\t\t\t\tdrawArea(ctx, curve0, curve1, len0, len1);\n\t\t\t\t\tlen0 = len1 = 0;\n\t\t\t\t\tcurve0 = [];\n\t\t\t\t\tcurve1 = [];\n\t\t\t\t} else {\n\t\t\t\t\tif (d0) {\n\t\t\t\t\t\tcurve0.push(p0);\n\t\t\t\t\t}\n\t\t\t\t\tif (d1) {\n\t\t\t\t\t\tcurve1.push(p1);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tdrawArea(ctx, curve0, curve1, len0, len1);\n\n\t\tctx.closePath();\n\t\tctx.fillStyle = color;\n\t\tctx.fill();\n\t}\n\n\treturn {\n\t\tid: 'filler',\n\n\t\tafterDatasetsUpdate: function(chart, options) {\n\t\t\tvar count = (chart.data.datasets || []).length;\n\t\t\tvar propagate = options.propagate;\n\t\t\tvar sources = [];\n\t\t\tvar meta, i, el, source;\n\n\t\t\tfor (i = 0; i < count; ++i) {\n\t\t\t\tmeta = chart.getDatasetMeta(i);\n\t\t\t\tel = meta.dataset;\n\t\t\t\tsource = null;\n\n\t\t\t\tif (el && el._model && el instanceof Chart.elements.Line) {\n\t\t\t\t\tsource = {\n\t\t\t\t\t\tvisible: chart.isDatasetVisible(i),\n\t\t\t\t\t\tfill: decodeFill(el, i, count),\n\t\t\t\t\t\tchart: chart,\n\t\t\t\t\t\tel: el\n\t\t\t\t\t};\n\t\t\t\t}\n\n\t\t\t\tmeta.$filler = source;\n\t\t\t\tsources.push(source);\n\t\t\t}\n\n\t\t\tfor (i=0; i<count; ++i) {\n\t\t\t\tsource = sources[i];\n\t\t\t\tif (!source) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\tsource.fill = resolveTarget(sources, i, propagate);\n\t\t\t\tsource.boundary = computeBoundary(source);\n\t\t\t\tsource.mapper = createMapper(source);\n\t\t\t}\n\t\t},\n\n\t\tbeforeDatasetDraw: function(chart, args) {\n\t\t\tvar meta = args.meta.$filler;\n\t\t\tif (!meta) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tvar el = meta.el;\n\t\t\tvar view = el._view;\n\t\t\tvar points = el._children || [];\n\t\t\tvar mapper = meta.mapper;\n\t\t\tvar color = view.backgroundColor || defaults.global.defaultColor;\n\n\t\t\tif (mapper && color && points.length) {\n\t\t\t\tdoFill(chart.ctx, points, mapper, view, color, el._loop);\n\t\t\t}\n\t\t}\n\t};\n};\n\n},{}],42:[function(require,module,exports){\n'use strict';\n\nmodule.exports = function(Chart) {\n\n\tvar helpers = Chart.helpers;\n\tvar layout = Chart.layoutService;\n\tvar noop = helpers.noop;\n\n\tChart.defaults.global.legend = {\n\t\tdisplay: true,\n\t\tposition: 'top',\n\t\tfullWidth: true,\n\t\treverse: false,\n\t\tweight: 1000,\n\n\t\t// a callback that will handle\n\t\tonClick: function(e, legendItem) {\n\t\t\tvar index = legendItem.datasetIndex;\n\t\t\tvar ci = this.chart;\n\t\t\tvar meta = ci.getDatasetMeta(index);\n\n\t\t\t// See controller.isDatasetVisible comment\n\t\t\tmeta.hidden = meta.hidden === null? !ci.data.datasets[index].hidden : null;\n\n\t\t\t// We hid a dataset ... rerender the chart\n\t\t\tci.update();\n\t\t},\n\n\t\tonHover: null,\n\n\t\tlabels: {\n\t\t\tboxWidth: 40,\n\t\t\tpadding: 10,\n\t\t\t// Generates labels shown in the legend\n\t\t\t// Valid properties to return:\n\t\t\t// text : text to display\n\t\t\t// fillStyle : fill of coloured box\n\t\t\t// strokeStyle: stroke of coloured box\n\t\t\t// hidden : if this legend item refers to a hidden item\n\t\t\t// lineCap : cap style for line\n\t\t\t// lineDash\n\t\t\t// lineDashOffset :\n\t\t\t// lineJoin :\n\t\t\t// lineWidth :\n\t\t\tgenerateLabels: function(chart) {\n\t\t\t\tvar data = chart.data;\n\t\t\t\treturn helpers.isArray(data.datasets) ? data.datasets.map(function(dataset, i) {\n\t\t\t\t\treturn {\n\t\t\t\t\t\ttext: dataset.label,\n\t\t\t\t\t\tfillStyle: (!helpers.isArray(dataset.backgroundColor) ? dataset.backgroundColor : dataset.backgroundColor[0]),\n\t\t\t\t\t\thidden: !chart.isDatasetVisible(i),\n\t\t\t\t\t\tlineCap: dataset.borderCapStyle,\n\t\t\t\t\t\tlineDash: dataset.borderDash,\n\t\t\t\t\t\tlineDashOffset: dataset.borderDashOffset,\n\t\t\t\t\t\tlineJoin: dataset.borderJoinStyle,\n\t\t\t\t\t\tlineWidth: dataset.borderWidth,\n\t\t\t\t\t\tstrokeStyle: dataset.borderColor,\n\t\t\t\t\t\tpointStyle: dataset.pointStyle,\n\n\t\t\t\t\t\t// Below is extra data used for toggling the datasets\n\t\t\t\t\t\tdatasetIndex: i\n\t\t\t\t\t};\n\t\t\t\t}, this) : [];\n\t\t\t}\n\t\t}\n\t};\n\n\t/**\n\t * Helper function to get the box width based on the usePointStyle option\n\t * @param labelopts {Object} the label options on the legend\n\t * @param fontSize {Number} the label font size\n\t * @return {Number} width of the color box area\n\t */\n\tfunction getBoxWidth(labelOpts, fontSize) {\n\t\treturn labelOpts.usePointStyle ?\n\t\t\tfontSize * Math.SQRT2 :\n\t\t\tlabelOpts.boxWidth;\n\t}\n\n\tChart.Legend = Chart.Element.extend({\n\n\t\tinitialize: function(config) {\n\t\t\thelpers.extend(this, config);\n\n\t\t\t// Contains hit boxes for each dataset (in dataset order)\n\t\t\tthis.legendHitBoxes = [];\n\n\t\t\t// Are we in doughnut mode which has a different data type\n\t\t\tthis.doughnutMode = false;\n\t\t},\n\n\t\t// These methods are ordered by lifecycle. Utilities then follow.\n\t\t// Any function defined here is inherited by all legend types.\n\t\t// Any function can be extended by the legend type\n\n\t\tbeforeUpdate: noop,\n\t\tupdate: function(maxWidth, maxHeight, margins) {\n\t\t\tvar me = this;\n\n\t\t\t// Update Lifecycle - Probably don't want to ever extend or overwrite this function ;)\n\t\t\tme.beforeUpdate();\n\n\t\t\t// Absorb the master measurements\n\t\t\tme.maxWidth = maxWidth;\n\t\t\tme.maxHeight = maxHeight;\n\t\t\tme.margins = margins;\n\n\t\t\t// Dimensions\n\t\t\tme.beforeSetDimensions();\n\t\t\tme.setDimensions();\n\t\t\tme.afterSetDimensions();\n\t\t\t// Labels\n\t\t\tme.beforeBuildLabels();\n\t\t\tme.buildLabels();\n\t\t\tme.afterBuildLabels();\n\n\t\t\t// Fit\n\t\t\tme.beforeFit();\n\t\t\tme.fit();\n\t\t\tme.afterFit();\n\t\t\t//\n\t\t\tme.afterUpdate();\n\n\t\t\treturn me.minSize;\n\t\t},\n\t\tafterUpdate: noop,\n\n\t\t//\n\n\t\tbeforeSetDimensions: noop,\n\t\tsetDimensions: function() {\n\t\t\tvar me = this;\n\t\t\t// Set the unconstrained dimension before label rotation\n\t\t\tif (me.isHorizontal()) {\n\t\t\t\t// Reset position before calculating rotation\n\t\t\t\tme.width = me.maxWidth;\n\t\t\t\tme.left = 0;\n\t\t\t\tme.right = me.width;\n\t\t\t} else {\n\t\t\t\tme.height = me.maxHeight;\n\n\t\t\t\t// Reset position before calculating rotation\n\t\t\t\tme.top = 0;\n\t\t\t\tme.bottom = me.height;\n\t\t\t}\n\n\t\t\t// Reset padding\n\t\t\tme.paddingLeft = 0;\n\t\t\tme.paddingTop = 0;\n\t\t\tme.paddingRight = 0;\n\t\t\tme.paddingBottom = 0;\n\n\t\t\t// Reset minSize\n\t\t\tme.minSize = {\n\t\t\t\twidth: 0,\n\t\t\t\theight: 0\n\t\t\t};\n\t\t},\n\t\tafterSetDimensions: noop,\n\n\t\t//\n\n\t\tbeforeBuildLabels: noop,\n\t\tbuildLabels: function() {\n\t\t\tvar me = this;\n\t\t\tvar labelOpts = me.options.labels;\n\t\t\tvar legendItems = labelOpts.generateLabels.call(me, me.chart);\n\n\t\t\tif (labelOpts.filter) {\n\t\t\t\tlegendItems = legendItems.filter(function(item) {\n\t\t\t\t\treturn labelOpts.filter(item, me.chart.data);\n\t\t\t\t});\n\t\t\t}\n\n\t\t\tif (me.options.reverse) {\n\t\t\t\tlegendItems.reverse();\n\t\t\t}\n\n\t\t\tme.legendItems = legendItems;\n\t\t},\n\t\tafterBuildLabels: noop,\n\n\t\t//\n\n\t\tbeforeFit: noop,\n\t\tfit: function() {\n\t\t\tvar me = this;\n\t\t\tvar opts = me.options;\n\t\t\tvar labelOpts = opts.labels;\n\t\t\tvar display = opts.display;\n\n\t\t\tvar ctx = me.ctx;\n\n\t\t\tvar globalDefault = Chart.defaults.global,\n\t\t\t\titemOrDefault = helpers.getValueOrDefault,\n\t\t\t\tfontSize = itemOrDefault(labelOpts.fontSize, globalDefault.defaultFontSize),\n\t\t\t\tfontStyle = itemOrDefault(labelOpts.fontStyle, globalDefault.defaultFontStyle),\n\t\t\t\tfontFamily = itemOrDefault(labelOpts.fontFamily, globalDefault.defaultFontFamily),\n\t\t\t\tlabelFont = helpers.fontString(fontSize, fontStyle, fontFamily);\n\n\t\t\t// Reset hit boxes\n\t\t\tvar hitboxes = me.legendHitBoxes = [];\n\n\t\t\tvar minSize = me.minSize;\n\t\t\tvar isHorizontal = me.isHorizontal();\n\n\t\t\tif (isHorizontal) {\n\t\t\t\tminSize.width = me.maxWidth; // fill all the width\n\t\t\t\tminSize.height = display ? 10 : 0;\n\t\t\t} else {\n\t\t\t\tminSize.width = display ? 10 : 0;\n\t\t\t\tminSize.height = me.maxHeight; // fill all the height\n\t\t\t}\n\n\t\t\t// Increase sizes here\n\t\t\tif (display) {\n\t\t\t\tctx.font = labelFont;\n\n\t\t\t\tif (isHorizontal) {\n\t\t\t\t\t// Labels\n\n\t\t\t\t\t// Width of each line of legend boxes. Labels wrap onto multiple lines when there are too many to fit on one\n\t\t\t\t\tvar lineWidths = me.lineWidths = [0];\n\t\t\t\t\tvar totalHeight = me.legendItems.length ? fontSize + (labelOpts.padding) : 0;\n\n\t\t\t\t\tctx.textAlign = 'left';\n\t\t\t\t\tctx.textBaseline = 'top';\n\n\t\t\t\t\thelpers.each(me.legendItems, function(legendItem, i) {\n\t\t\t\t\t\tvar boxWidth = getBoxWidth(labelOpts, fontSize);\n\t\t\t\t\t\tvar width = boxWidth + (fontSize / 2) + ctx.measureText(legendItem.text).width;\n\n\t\t\t\t\t\tif (lineWidths[lineWidths.length - 1] + width + labelOpts.padding >= me.width) {\n\t\t\t\t\t\t\ttotalHeight += fontSize + (labelOpts.padding);\n\t\t\t\t\t\t\tlineWidths[lineWidths.length] = me.left;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// Store the hitbox width and height here. Final position will be updated in `draw`\n\t\t\t\t\t\thitboxes[i] = {\n\t\t\t\t\t\t\tleft: 0,\n\t\t\t\t\t\t\ttop: 0,\n\t\t\t\t\t\t\twidth: width,\n\t\t\t\t\t\t\theight: fontSize\n\t\t\t\t\t\t};\n\n\t\t\t\t\t\tlineWidths[lineWidths.length - 1] += width + labelOpts.padding;\n\t\t\t\t\t});\n\n\t\t\t\t\tminSize.height += totalHeight;\n\n\t\t\t\t} else {\n\t\t\t\t\tvar vPadding = labelOpts.padding;\n\t\t\t\t\tvar columnWidths = me.columnWidths = [];\n\t\t\t\t\tvar totalWidth = labelOpts.padding;\n\t\t\t\t\tvar currentColWidth = 0;\n\t\t\t\t\tvar currentColHeight = 0;\n\t\t\t\t\tvar itemHeight = fontSize + vPadding;\n\n\t\t\t\t\thelpers.each(me.legendItems, function(legendItem, i) {\n\t\t\t\t\t\tvar boxWidth = getBoxWidth(labelOpts, fontSize);\n\t\t\t\t\t\tvar itemWidth = boxWidth + (fontSize / 2) + ctx.measureText(legendItem.text).width;\n\n\t\t\t\t\t\t// If too tall, go to new column\n\t\t\t\t\t\tif (currentColHeight + itemHeight > minSize.height) {\n\t\t\t\t\t\t\ttotalWidth += currentColWidth + labelOpts.padding;\n\t\t\t\t\t\t\tcolumnWidths.push(currentColWidth); // previous column width\n\n\t\t\t\t\t\t\tcurrentColWidth = 0;\n\t\t\t\t\t\t\tcurrentColHeight = 0;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// Get max width\n\t\t\t\t\t\tcurrentColWidth = Math.max(currentColWidth, itemWidth);\n\t\t\t\t\t\tcurrentColHeight += itemHeight;\n\n\t\t\t\t\t\t// Store the hitbox width and height here. Final position will be updated in `draw`\n\t\t\t\t\t\thitboxes[i] = {\n\t\t\t\t\t\t\tleft: 0,\n\t\t\t\t\t\t\ttop: 0,\n\t\t\t\t\t\t\twidth: itemWidth,\n\t\t\t\t\t\t\theight: fontSize\n\t\t\t\t\t\t};\n\t\t\t\t\t});\n\n\t\t\t\t\ttotalWidth += currentColWidth;\n\t\t\t\t\tcolumnWidths.push(currentColWidth);\n\t\t\t\t\tminSize.width += totalWidth;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tme.width = minSize.width;\n\t\t\tme.height = minSize.height;\n\t\t},\n\t\tafterFit: noop,\n\n\t\t// Shared Methods\n\t\tisHorizontal: function() {\n\t\t\treturn this.options.position === 'top' || this.options.position === 'bottom';\n\t\t},\n\n\t\t// Actually draw the legend on the canvas\n\t\tdraw: function() {\n\t\t\tvar me = this;\n\t\t\tvar opts = me.options;\n\t\t\tvar labelOpts = opts.labels;\n\t\t\tvar globalDefault = Chart.defaults.global,\n\t\t\t\tlineDefault = globalDefault.elements.line,\n\t\t\t\tlegendWidth = me.width,\n\t\t\t\tlineWidths = me.lineWidths;\n\n\t\t\tif (opts.display) {\n\t\t\t\tvar ctx = me.ctx,\n\t\t\t\t\tcursor,\n\t\t\t\t\titemOrDefault = helpers.getValueOrDefault,\n\t\t\t\t\tfontColor = itemOrDefault(labelOpts.fontColor, globalDefault.defaultFontColor),\n\t\t\t\t\tfontSize = itemOrDefault(labelOpts.fontSize, globalDefault.defaultFontSize),\n\t\t\t\t\tfontStyle = itemOrDefault(labelOpts.fontStyle, globalDefault.defaultFontStyle),\n\t\t\t\t\tfontFamily = itemOrDefault(labelOpts.fontFamily, globalDefault.defaultFontFamily),\n\t\t\t\t\tlabelFont = helpers.fontString(fontSize, fontStyle, fontFamily);\n\n\t\t\t\t// Canvas setup\n\t\t\t\tctx.textAlign = 'left';\n\t\t\t\tctx.textBaseline = 'top';\n\t\t\t\tctx.lineWidth = 0.5;\n\t\t\t\tctx.strokeStyle = fontColor; // for strikethrough effect\n\t\t\t\tctx.fillStyle = fontColor; // render in correct colour\n\t\t\t\tctx.font = labelFont;\n\n\t\t\t\tvar boxWidth = getBoxWidth(labelOpts, fontSize),\n\t\t\t\t\thitboxes = me.legendHitBoxes;\n\n\t\t\t\t// current position\n\t\t\t\tvar drawLegendBox = function(x, y, legendItem) {\n\t\t\t\t\tif (isNaN(boxWidth) || boxWidth <= 0) {\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\n\t\t\t\t\t// Set the ctx for the box\n\t\t\t\t\tctx.save();\n\n\t\t\t\t\tctx.fillStyle = itemOrDefault(legendItem.fillStyle, globalDefault.defaultColor);\n\t\t\t\t\tctx.lineCap = itemOrDefault(legendItem.lineCap, lineDefault.borderCapStyle);\n\t\t\t\t\tctx.lineDashOffset = itemOrDefault(legendItem.lineDashOffset, lineDefault.borderDashOffset);\n\t\t\t\t\tctx.lineJoin = itemOrDefault(legendItem.lineJoin, lineDefault.borderJoinStyle);\n\t\t\t\t\tctx.lineWidth = itemOrDefault(legendItem.lineWidth, lineDefault.borderWidth);\n\t\t\t\t\tctx.strokeStyle = itemOrDefault(legendItem.strokeStyle, globalDefault.defaultColor);\n\t\t\t\t\tvar isLineWidthZero = (itemOrDefault(legendItem.lineWidth, lineDefault.borderWidth) === 0);\n\n\t\t\t\t\tif (ctx.setLineDash) {\n\t\t\t\t\t\t// IE 9 and 10 do not support line dash\n\t\t\t\t\t\tctx.setLineDash(itemOrDefault(legendItem.lineDash, lineDefault.borderDash));\n\t\t\t\t\t}\n\n\t\t\t\t\tif (opts.labels && opts.labels.usePointStyle) {\n\t\t\t\t\t\t// Recalculate x and y for drawPoint() because its expecting\n\t\t\t\t\t\t// x and y to be center of figure (instead of top left)\n\t\t\t\t\t\tvar radius = fontSize * Math.SQRT2 / 2;\n\t\t\t\t\t\tvar offSet = radius / Math.SQRT2;\n\t\t\t\t\t\tvar centerX = x + offSet;\n\t\t\t\t\t\tvar centerY = y + offSet;\n\n\t\t\t\t\t\t// Draw pointStyle as legend symbol\n\t\t\t\t\t\tChart.canvasHelpers.drawPoint(ctx, legendItem.pointStyle, radius, centerX, centerY);\n\t\t\t\t\t} else {\n\t\t\t\t\t\t// Draw box as legend symbol\n\t\t\t\t\t\tif (!isLineWidthZero) {\n\t\t\t\t\t\t\tctx.strokeRect(x, y, boxWidth, fontSize);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tctx.fillRect(x, y, boxWidth, fontSize);\n\t\t\t\t\t}\n\n\t\t\t\t\tctx.restore();\n\t\t\t\t};\n\t\t\t\tvar fillText = function(x, y, legendItem, textWidth) {\n\t\t\t\t\tctx.fillText(legendItem.text, boxWidth + (fontSize / 2) + x, y);\n\n\t\t\t\t\tif (legendItem.hidden) {\n\t\t\t\t\t\t// Strikethrough the text if hidden\n\t\t\t\t\t\tctx.beginPath();\n\t\t\t\t\t\tctx.lineWidth = 2;\n\t\t\t\t\t\tctx.moveTo(boxWidth + (fontSize / 2) + x, y + (fontSize / 2));\n\t\t\t\t\t\tctx.lineTo(boxWidth + (fontSize / 2) + x + textWidth, y + (fontSize / 2));\n\t\t\t\t\t\tctx.stroke();\n\t\t\t\t\t}\n\t\t\t\t};\n\n\t\t\t\t// Horizontal\n\t\t\t\tvar isHorizontal = me.isHorizontal();\n\t\t\t\tif (isHorizontal) {\n\t\t\t\t\tcursor = {\n\t\t\t\t\t\tx: me.left + ((legendWidth - lineWidths[0]) / 2),\n\t\t\t\t\t\ty: me.top + labelOpts.padding,\n\t\t\t\t\t\tline: 0\n\t\t\t\t\t};\n\t\t\t\t} else {\n\t\t\t\t\tcursor = {\n\t\t\t\t\t\tx: me.left + labelOpts.padding,\n\t\t\t\t\t\ty: me.top + labelOpts.padding,\n\t\t\t\t\t\tline: 0\n\t\t\t\t\t};\n\t\t\t\t}\n\n\t\t\t\tvar itemHeight = fontSize + labelOpts.padding;\n\t\t\t\thelpers.each(me.legendItems, function(legendItem, i) {\n\t\t\t\t\tvar textWidth = ctx.measureText(legendItem.text).width,\n\t\t\t\t\t\twidth = boxWidth + (fontSize / 2) + textWidth,\n\t\t\t\t\t\tx = cursor.x,\n\t\t\t\t\t\ty = cursor.y;\n\n\t\t\t\t\tif (isHorizontal) {\n\t\t\t\t\t\tif (x + width >= legendWidth) {\n\t\t\t\t\t\t\ty = cursor.y += itemHeight;\n\t\t\t\t\t\t\tcursor.line++;\n\t\t\t\t\t\t\tx = cursor.x = me.left + ((legendWidth - lineWidths[cursor.line]) / 2);\n\t\t\t\t\t\t}\n\t\t\t\t\t} else if (y + itemHeight > me.bottom) {\n\t\t\t\t\t\tx = cursor.x = x + me.columnWidths[cursor.line] + labelOpts.padding;\n\t\t\t\t\t\ty = cursor.y = me.top + labelOpts.padding;\n\t\t\t\t\t\tcursor.line++;\n\t\t\t\t\t}\n\n\t\t\t\t\tdrawLegendBox(x, y, legendItem);\n\n\t\t\t\t\thitboxes[i].left = x;\n\t\t\t\t\thitboxes[i].top = y;\n\n\t\t\t\t\t// Fill the actual label\n\t\t\t\t\tfillText(x, y, legendItem, textWidth);\n\n\t\t\t\t\tif (isHorizontal) {\n\t\t\t\t\t\tcursor.x += width + (labelOpts.padding);\n\t\t\t\t\t} else {\n\t\t\t\t\t\tcursor.y += itemHeight;\n\t\t\t\t\t}\n\n\t\t\t\t});\n\t\t\t}\n\t\t},\n\n\t\t/**\n\t\t * Handle an event\n\t\t * @private\n\t\t * @param {IEvent} event - The event to handle\n\t\t * @return {Boolean} true if a change occured\n\t\t */\n\t\thandleEvent: function(e) {\n\t\t\tvar me = this;\n\t\t\tvar opts = me.options;\n\t\t\tvar type = e.type === 'mouseup' ? 'click' : e.type;\n\t\t\tvar changed = false;\n\n\t\t\tif (type === 'mousemove') {\n\t\t\t\tif (!opts.onHover) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t} else if (type === 'click') {\n\t\t\t\tif (!opts.onClick) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// Chart event already has relative position in it\n\t\t\tvar x = e.x,\n\t\t\t\ty = e.y;\n\n\t\t\tif (x >= me.left && x <= me.right && y >= me.top && y <= me.bottom) {\n\t\t\t\t// See if we are touching one of the dataset boxes\n\t\t\t\tvar lh = me.legendHitBoxes;\n\t\t\t\tfor (var i = 0; i < lh.length; ++i) {\n\t\t\t\t\tvar hitBox = lh[i];\n\n\t\t\t\t\tif (x >= hitBox.left && x <= hitBox.left + hitBox.width && y >= hitBox.top && y <= hitBox.top + hitBox.height) {\n\t\t\t\t\t\t// Touching an element\n\t\t\t\t\t\tif (type === 'click') {\n\t\t\t\t\t\t\t// use e.native for backwards compatibility\n\t\t\t\t\t\t\topts.onClick.call(me, e.native, me.legendItems[i]);\n\t\t\t\t\t\t\tchanged = true;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t} else if (type === 'mousemove') {\n\t\t\t\t\t\t\t// use e.native for backwards compatibility\n\t\t\t\t\t\t\topts.onHover.call(me, e.native, me.legendItems[i]);\n\t\t\t\t\t\t\tchanged = true;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn changed;\n\t\t}\n\t});\n\n\tfunction createNewLegendAndAttach(chart, legendOpts) {\n\t\tvar legend = new Chart.Legend({\n\t\t\tctx: chart.ctx,\n\t\t\toptions: legendOpts,\n\t\t\tchart: chart\n\t\t});\n\n\t\tlayout.configure(chart, legend, legendOpts);\n\t\tlayout.addBox(chart, legend);\n\t\tchart.legend = legend;\n\t}\n\n\treturn {\n\t\tid: 'legend',\n\n\t\tbeforeInit: function(chart) {\n\t\t\tvar legendOpts = chart.options.legend;\n\n\t\t\tif (legendOpts) {\n\t\t\t\tcreateNewLegendAndAttach(chart, legendOpts);\n\t\t\t}\n\t\t},\n\n\t\tbeforeUpdate: function(chart) {\n\t\t\tvar legendOpts = chart.options.legend;\n\t\t\tvar legend = chart.legend;\n\n\t\t\tif (legendOpts) {\n\t\t\t\tlegendOpts = helpers.configMerge(Chart.defaults.global.legend, legendOpts);\n\n\t\t\t\tif (legend) {\n\t\t\t\t\tlayout.configure(chart, legend, legendOpts);\n\t\t\t\t\tlegend.options = legendOpts;\n\t\t\t\t} else {\n\t\t\t\t\tcreateNewLegendAndAttach(chart, legendOpts);\n\t\t\t\t}\n\t\t\t} else if (legend) {\n\t\t\t\tlayout.removeBox(chart, legend);\n\t\t\t\tdelete chart.legend;\n\t\t\t}\n\t\t},\n\n\t\tafterEvent: function(chart, e) {\n\t\t\tvar legend = chart.legend;\n\t\t\tif (legend) {\n\t\t\t\tlegend.handleEvent(e);\n\t\t\t}\n\t\t}\n\t};\n};\n\n},{}],43:[function(require,module,exports){\n'use strict';\n\nmodule.exports = function(Chart) {\n\n\tvar helpers = Chart.helpers;\n\tvar layout = Chart.layoutService;\n\tvar noop = helpers.noop;\n\n\tChart.defaults.global.title = {\n\t\tdisplay: false,\n\t\tposition: 'top',\n\t\tfullWidth: true,\n\t\tweight: 2000,        // by default greater than legend (1000) to be above\n\t\tfontStyle: 'bold',\n\t\tpadding: 10,\n\n\t\t// actual title\n\t\ttext: ''\n\t};\n\n\tChart.Title = Chart.Element.extend({\n\t\tinitialize: function(config) {\n\t\t\tvar me = this;\n\t\t\thelpers.extend(me, config);\n\n\t\t\t// Contains hit boxes for each dataset (in dataset order)\n\t\t\tme.legendHitBoxes = [];\n\t\t},\n\n\t\t// These methods are ordered by lifecycle. Utilities then follow.\n\n\t\tbeforeUpdate: noop,\n\t\tupdate: function(maxWidth, maxHeight, margins) {\n\t\t\tvar me = this;\n\n\t\t\t// Update Lifecycle - Probably don't want to ever extend or overwrite this function ;)\n\t\t\tme.beforeUpdate();\n\n\t\t\t// Absorb the master measurements\n\t\t\tme.maxWidth = maxWidth;\n\t\t\tme.maxHeight = maxHeight;\n\t\t\tme.margins = margins;\n\n\t\t\t// Dimensions\n\t\t\tme.beforeSetDimensions();\n\t\t\tme.setDimensions();\n\t\t\tme.afterSetDimensions();\n\t\t\t// Labels\n\t\t\tme.beforeBuildLabels();\n\t\t\tme.buildLabels();\n\t\t\tme.afterBuildLabels();\n\n\t\t\t// Fit\n\t\t\tme.beforeFit();\n\t\t\tme.fit();\n\t\t\tme.afterFit();\n\t\t\t//\n\t\t\tme.afterUpdate();\n\n\t\t\treturn me.minSize;\n\n\t\t},\n\t\tafterUpdate: noop,\n\n\t\t//\n\n\t\tbeforeSetDimensions: noop,\n\t\tsetDimensions: function() {\n\t\t\tvar me = this;\n\t\t\t// Set the unconstrained dimension before label rotation\n\t\t\tif (me.isHorizontal()) {\n\t\t\t\t// Reset position before calculating rotation\n\t\t\t\tme.width = me.maxWidth;\n\t\t\t\tme.left = 0;\n\t\t\t\tme.right = me.width;\n\t\t\t} else {\n\t\t\t\tme.height = me.maxHeight;\n\n\t\t\t\t// Reset position before calculating rotation\n\t\t\t\tme.top = 0;\n\t\t\t\tme.bottom = me.height;\n\t\t\t}\n\n\t\t\t// Reset padding\n\t\t\tme.paddingLeft = 0;\n\t\t\tme.paddingTop = 0;\n\t\t\tme.paddingRight = 0;\n\t\t\tme.paddingBottom = 0;\n\n\t\t\t// Reset minSize\n\t\t\tme.minSize = {\n\t\t\t\twidth: 0,\n\t\t\t\theight: 0\n\t\t\t};\n\t\t},\n\t\tafterSetDimensions: noop,\n\n\t\t//\n\n\t\tbeforeBuildLabels: noop,\n\t\tbuildLabels: noop,\n\t\tafterBuildLabels: noop,\n\n\t\t//\n\n\t\tbeforeFit: noop,\n\t\tfit: function() {\n\t\t\tvar me = this,\n\t\t\t\tvalueOrDefault = helpers.getValueOrDefault,\n\t\t\t\topts = me.options,\n\t\t\t\tglobalDefaults = Chart.defaults.global,\n\t\t\t\tdisplay = opts.display,\n\t\t\t\tfontSize = valueOrDefault(opts.fontSize, globalDefaults.defaultFontSize),\n\t\t\t\tminSize = me.minSize;\n\n\t\t\tif (me.isHorizontal()) {\n\t\t\t\tminSize.width = me.maxWidth; // fill all the width\n\t\t\t\tminSize.height = display ? fontSize + (opts.padding * 2) : 0;\n\t\t\t} else {\n\t\t\t\tminSize.width = display ? fontSize + (opts.padding * 2) : 0;\n\t\t\t\tminSize.height = me.maxHeight; // fill all the height\n\t\t\t}\n\n\t\t\tme.width = minSize.width;\n\t\t\tme.height = minSize.height;\n\n\t\t},\n\t\tafterFit: noop,\n\n\t\t// Shared Methods\n\t\tisHorizontal: function() {\n\t\t\tvar pos = this.options.position;\n\t\t\treturn pos === 'top' || pos === 'bottom';\n\t\t},\n\n\t\t// Actually draw the title block on the canvas\n\t\tdraw: function() {\n\t\t\tvar me = this,\n\t\t\t\tctx = me.ctx,\n\t\t\t\tvalueOrDefault = helpers.getValueOrDefault,\n\t\t\t\topts = me.options,\n\t\t\t\tglobalDefaults = Chart.defaults.global;\n\n\t\t\tif (opts.display) {\n\t\t\t\tvar fontSize = valueOrDefault(opts.fontSize, globalDefaults.defaultFontSize),\n\t\t\t\t\tfontStyle = valueOrDefault(opts.fontStyle, globalDefaults.defaultFontStyle),\n\t\t\t\t\tfontFamily = valueOrDefault(opts.fontFamily, globalDefaults.defaultFontFamily),\n\t\t\t\t\ttitleFont = helpers.fontString(fontSize, fontStyle, fontFamily),\n\t\t\t\t\trotation = 0,\n\t\t\t\t\ttitleX,\n\t\t\t\t\ttitleY,\n\t\t\t\t\ttop = me.top,\n\t\t\t\t\tleft = me.left,\n\t\t\t\t\tbottom = me.bottom,\n\t\t\t\t\tright = me.right,\n\t\t\t\t\tmaxWidth;\n\n\t\t\t\tctx.fillStyle = valueOrDefault(opts.fontColor, globalDefaults.defaultFontColor); // render in correct colour\n\t\t\t\tctx.font = titleFont;\n\n\t\t\t\t// Horizontal\n\t\t\t\tif (me.isHorizontal()) {\n\t\t\t\t\ttitleX = left + ((right - left) / 2); // midpoint of the width\n\t\t\t\t\ttitleY = top + ((bottom - top) / 2); // midpoint of the height\n\t\t\t\t\tmaxWidth = right - left;\n\t\t\t\t} else {\n\t\t\t\t\ttitleX = opts.position === 'left' ? left + (fontSize / 2) : right - (fontSize / 2);\n\t\t\t\t\ttitleY = top + ((bottom - top) / 2);\n\t\t\t\t\tmaxWidth = bottom - top;\n\t\t\t\t\trotation = Math.PI * (opts.position === 'left' ? -0.5 : 0.5);\n\t\t\t\t}\n\n\t\t\t\tctx.save();\n\t\t\t\tctx.translate(titleX, titleY);\n\t\t\t\tctx.rotate(rotation);\n\t\t\t\tctx.textAlign = 'center';\n\t\t\t\tctx.textBaseline = 'middle';\n\t\t\t\tctx.fillText(opts.text, 0, 0, maxWidth);\n\t\t\t\tctx.restore();\n\t\t\t}\n\t\t}\n\t});\n\n\tfunction createNewTitleBlockAndAttach(chart, titleOpts) {\n\t\tvar title = new Chart.Title({\n\t\t\tctx: chart.ctx,\n\t\t\toptions: titleOpts,\n\t\t\tchart: chart\n\t\t});\n\n\t\tlayout.configure(chart, title, titleOpts);\n\t\tlayout.addBox(chart, title);\n\t\tchart.titleBlock = title;\n\t}\n\n\treturn {\n\t\tid: 'title',\n\n\t\tbeforeInit: function(chart) {\n\t\t\tvar titleOpts = chart.options.title;\n\n\t\t\tif (titleOpts) {\n\t\t\t\tcreateNewTitleBlockAndAttach(chart, titleOpts);\n\t\t\t}\n\t\t},\n\n\t\tbeforeUpdate: function(chart) {\n\t\t\tvar titleOpts = chart.options.title;\n\t\t\tvar titleBlock = chart.titleBlock;\n\n\t\t\tif (titleOpts) {\n\t\t\t\ttitleOpts = helpers.configMerge(Chart.defaults.global.title, titleOpts);\n\n\t\t\t\tif (titleBlock) {\n\t\t\t\t\tlayout.configure(chart, titleBlock, titleOpts);\n\t\t\t\t\ttitleBlock.options = titleOpts;\n\t\t\t\t} else {\n\t\t\t\t\tcreateNewTitleBlockAndAttach(chart, titleOpts);\n\t\t\t\t}\n\t\t\t} else if (titleBlock) {\n\t\t\t\tChart.layoutService.removeBox(chart, titleBlock);\n\t\t\t\tdelete chart.titleBlock;\n\t\t\t}\n\t\t}\n\t};\n};\n\n},{}],44:[function(require,module,exports){\n'use strict';\n\nmodule.exports = function(Chart) {\n\n\tvar helpers = Chart.helpers;\n\t// Default config for a category scale\n\tvar defaultConfig = {\n\t\tposition: 'bottom'\n\t};\n\n\tvar DatasetScale = Chart.Scale.extend({\n\t\t/**\n\t\t* Internal function to get the correct labels. If data.xLabels or data.yLabels are defined, use those\n\t\t* else fall back to data.labels\n\t\t* @private\n\t\t*/\n\t\tgetLabels: function() {\n\t\t\tvar data = this.chart.data;\n\t\t\treturn (this.isHorizontal() ? data.xLabels : data.yLabels) || data.labels;\n\t\t},\n\n\t\tdetermineDataLimits: function() {\n\t\t\tvar me = this;\n\t\t\tvar labels = me.getLabels();\n\t\t\tme.minIndex = 0;\n\t\t\tme.maxIndex = labels.length - 1;\n\t\t\tvar findIndex;\n\n\t\t\tif (me.options.ticks.min !== undefined) {\n\t\t\t\t// user specified min value\n\t\t\t\tfindIndex = helpers.indexOf(labels, me.options.ticks.min);\n\t\t\t\tme.minIndex = findIndex !== -1 ? findIndex : me.minIndex;\n\t\t\t}\n\n\t\t\tif (me.options.ticks.max !== undefined) {\n\t\t\t\t// user specified max value\n\t\t\t\tfindIndex = helpers.indexOf(labels, me.options.ticks.max);\n\t\t\t\tme.maxIndex = findIndex !== -1 ? findIndex : me.maxIndex;\n\t\t\t}\n\n\t\t\tme.min = labels[me.minIndex];\n\t\t\tme.max = labels[me.maxIndex];\n\t\t},\n\n\t\tbuildTicks: function() {\n\t\t\tvar me = this;\n\t\t\tvar labels = me.getLabels();\n\t\t\t// If we are viewing some subset of labels, slice the original array\n\t\t\tme.ticks = (me.minIndex === 0 && me.maxIndex === labels.length - 1) ? labels : labels.slice(me.minIndex, me.maxIndex + 1);\n\t\t},\n\n\t\tgetLabelForIndex: function(index, datasetIndex) {\n\t\t\tvar me = this;\n\t\t\tvar data = me.chart.data;\n\t\t\tvar isHorizontal = me.isHorizontal();\n\n\t\t\tif (data.yLabels && !isHorizontal) {\n\t\t\t\treturn me.getRightValue(data.datasets[datasetIndex].data[index]);\n\t\t\t}\n\t\t\treturn me.ticks[index - me.minIndex];\n\t\t},\n\n\t\t// Used to get data value locations.  Value can either be an index or a numerical value\n\t\tgetPixelForValue: function(value, index, datasetIndex, includeOffset) {\n\t\t\tvar me = this;\n\t\t\t// 1 is added because we need the length but we have the indexes\n\t\t\tvar offsetAmt = Math.max((me.maxIndex + 1 - me.minIndex - ((me.options.gridLines.offsetGridLines) ? 0 : 1)), 1);\n\n\t\t\t// If value is a data object, then index is the index in the data array,\n\t\t\t// not the index of the scale. We need to change that.\n\t\t\tvar valueCategory;\n\t\t\tif (value !== undefined && value !== null) {\n\t\t\t\tvalueCategory = me.isHorizontal() ? value.x : value.y;\n\t\t\t}\n\t\t\tif (valueCategory !== undefined || (value !== undefined && isNaN(index))) {\n\t\t\t\tvar labels = me.getLabels();\n\t\t\t\tvalue = valueCategory || value;\n\t\t\t\tvar idx = labels.indexOf(value);\n\t\t\t\tindex = idx !== -1 ? idx : index;\n\t\t\t}\n\n\t\t\tif (me.isHorizontal()) {\n\t\t\t\tvar valueWidth = me.width / offsetAmt;\n\t\t\t\tvar widthOffset = (valueWidth * (index - me.minIndex));\n\n\t\t\t\tif (me.options.gridLines.offsetGridLines && includeOffset || me.maxIndex === me.minIndex && includeOffset) {\n\t\t\t\t\twidthOffset += (valueWidth / 2);\n\t\t\t\t}\n\n\t\t\t\treturn me.left + Math.round(widthOffset);\n\t\t\t}\n\t\t\tvar valueHeight = me.height / offsetAmt;\n\t\t\tvar heightOffset = (valueHeight * (index - me.minIndex));\n\n\t\t\tif (me.options.gridLines.offsetGridLines && includeOffset) {\n\t\t\t\theightOffset += (valueHeight / 2);\n\t\t\t}\n\n\t\t\treturn me.top + Math.round(heightOffset);\n\t\t},\n\t\tgetPixelForTick: function(index, includeOffset) {\n\t\t\treturn this.getPixelForValue(this.ticks[index], index + this.minIndex, null, includeOffset);\n\t\t},\n\t\tgetValueForPixel: function(pixel) {\n\t\t\tvar me = this;\n\t\t\tvar value;\n\t\t\tvar offsetAmt = Math.max((me.ticks.length - ((me.options.gridLines.offsetGridLines) ? 0 : 1)), 1);\n\t\t\tvar horz = me.isHorizontal();\n\t\t\tvar valueDimension = (horz ? me.width : me.height) / offsetAmt;\n\n\t\t\tpixel -= horz ? me.left : me.top;\n\n\t\t\tif (me.options.gridLines.offsetGridLines) {\n\t\t\t\tpixel -= (valueDimension / 2);\n\t\t\t}\n\n\t\t\tif (pixel <= 0) {\n\t\t\t\tvalue = 0;\n\t\t\t} else {\n\t\t\t\tvalue = Math.round(pixel / valueDimension);\n\t\t\t}\n\n\t\t\treturn value;\n\t\t},\n\t\tgetBasePixel: function() {\n\t\t\treturn this.bottom;\n\t\t}\n\t});\n\n\tChart.scaleService.registerScaleType('category', DatasetScale, defaultConfig);\n\n};\n\n},{}],45:[function(require,module,exports){\n'use strict';\n\nmodule.exports = function(Chart) {\n\n\tvar helpers = Chart.helpers;\n\n\tvar defaultConfig = {\n\t\tposition: 'left',\n\t\tticks: {\n\t\t\tcallback: Chart.Ticks.formatters.linear\n\t\t}\n\t};\n\n\tvar LinearScale = Chart.LinearScaleBase.extend({\n\n\t\tdetermineDataLimits: function() {\n\t\t\tvar me = this;\n\t\t\tvar opts = me.options;\n\t\t\tvar chart = me.chart;\n\t\t\tvar data = chart.data;\n\t\t\tvar datasets = data.datasets;\n\t\t\tvar isHorizontal = me.isHorizontal();\n\t\t\tvar DEFAULT_MIN = 0;\n\t\t\tvar DEFAULT_MAX = 1;\n\n\t\t\tfunction IDMatches(meta) {\n\t\t\t\treturn isHorizontal ? meta.xAxisID === me.id : meta.yAxisID === me.id;\n\t\t\t}\n\n\t\t\t// First Calculate the range\n\t\t\tme.min = null;\n\t\t\tme.max = null;\n\n\t\t\tvar hasStacks = opts.stacked;\n\t\t\tif (hasStacks === undefined) {\n\t\t\t\thelpers.each(datasets, function(dataset, datasetIndex) {\n\t\t\t\t\tif (hasStacks) {\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\n\t\t\t\t\tvar meta = chart.getDatasetMeta(datasetIndex);\n\t\t\t\t\tif (chart.isDatasetVisible(datasetIndex) && IDMatches(meta) &&\n\t\t\t\t\t\tmeta.stack !== undefined) {\n\t\t\t\t\t\thasStacks = true;\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t}\n\n\t\t\tif (opts.stacked || hasStacks) {\n\t\t\t\tvar valuesPerStack = {};\n\n\t\t\t\thelpers.each(datasets, function(dataset, datasetIndex) {\n\t\t\t\t\tvar meta = chart.getDatasetMeta(datasetIndex);\n\t\t\t\t\tvar key = [\n\t\t\t\t\t\tmeta.type,\n\t\t\t\t\t\t// we have a separate stack for stack=undefined datasets when the opts.stacked is undefined\n\t\t\t\t\t\t((opts.stacked === undefined && meta.stack === undefined) ? datasetIndex : ''),\n\t\t\t\t\t\tmeta.stack\n\t\t\t\t\t].join('.');\n\n\t\t\t\t\tif (valuesPerStack[key] === undefined) {\n\t\t\t\t\t\tvaluesPerStack[key] = {\n\t\t\t\t\t\t\tpositiveValues: [],\n\t\t\t\t\t\t\tnegativeValues: []\n\t\t\t\t\t\t};\n\t\t\t\t\t}\n\n\t\t\t\t\t// Store these per type\n\t\t\t\t\tvar positiveValues = valuesPerStack[key].positiveValues;\n\t\t\t\t\tvar negativeValues = valuesPerStack[key].negativeValues;\n\n\t\t\t\t\tif (chart.isDatasetVisible(datasetIndex) && IDMatches(meta)) {\n\t\t\t\t\t\thelpers.each(dataset.data, function(rawValue, index) {\n\t\t\t\t\t\t\tvar value = +me.getRightValue(rawValue);\n\t\t\t\t\t\t\tif (isNaN(value) || meta.data[index].hidden) {\n\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tpositiveValues[index] = positiveValues[index] || 0;\n\t\t\t\t\t\t\tnegativeValues[index] = negativeValues[index] || 0;\n\n\t\t\t\t\t\t\tif (opts.relativePoints) {\n\t\t\t\t\t\t\t\tpositiveValues[index] = 100;\n\t\t\t\t\t\t\t} else if (value < 0) {\n\t\t\t\t\t\t\t\tnegativeValues[index] += value;\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tpositiveValues[index] += value;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t});\n\n\t\t\t\thelpers.each(valuesPerStack, function(valuesForType) {\n\t\t\t\t\tvar values = valuesForType.positiveValues.concat(valuesForType.negativeValues);\n\t\t\t\t\tvar minVal = helpers.min(values);\n\t\t\t\t\tvar maxVal = helpers.max(values);\n\t\t\t\t\tme.min = me.min === null ? minVal : Math.min(me.min, minVal);\n\t\t\t\t\tme.max = me.max === null ? maxVal : Math.max(me.max, maxVal);\n\t\t\t\t});\n\n\t\t\t} else {\n\t\t\t\thelpers.each(datasets, function(dataset, datasetIndex) {\n\t\t\t\t\tvar meta = chart.getDatasetMeta(datasetIndex);\n\t\t\t\t\tif (chart.isDatasetVisible(datasetIndex) && IDMatches(meta)) {\n\t\t\t\t\t\thelpers.each(dataset.data, function(rawValue, index) {\n\t\t\t\t\t\t\tvar value = +me.getRightValue(rawValue);\n\t\t\t\t\t\t\tif (isNaN(value) || meta.data[index].hidden) {\n\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tif (me.min === null) {\n\t\t\t\t\t\t\t\tme.min = value;\n\t\t\t\t\t\t\t} else if (value < me.min) {\n\t\t\t\t\t\t\t\tme.min = value;\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tif (me.max === null) {\n\t\t\t\t\t\t\t\tme.max = value;\n\t\t\t\t\t\t\t} else if (value > me.max) {\n\t\t\t\t\t\t\t\tme.max = value;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t}\n\n\t\t\tme.min = isFinite(me.min) ? me.min : DEFAULT_MIN;\n\t\t\tme.max = isFinite(me.max) ? me.max : DEFAULT_MAX;\n\n\t\t\t// Common base implementation to handle ticks.min, ticks.max, ticks.beginAtZero\n\t\t\tthis.handleTickRangeOptions();\n\t\t},\n\t\tgetTickLimit: function() {\n\t\t\tvar maxTicks;\n\t\t\tvar me = this;\n\t\t\tvar tickOpts = me.options.ticks;\n\n\t\t\tif (me.isHorizontal()) {\n\t\t\t\tmaxTicks = Math.min(tickOpts.maxTicksLimit ? tickOpts.maxTicksLimit : 11, Math.ceil(me.width / 50));\n\t\t\t} else {\n\t\t\t\t// The factor of 2 used to scale the font size has been experimentally determined.\n\t\t\t\tvar tickFontSize = helpers.getValueOrDefault(tickOpts.fontSize, Chart.defaults.global.defaultFontSize);\n\t\t\t\tmaxTicks = Math.min(tickOpts.maxTicksLimit ? tickOpts.maxTicksLimit : 11, Math.ceil(me.height / (2 * tickFontSize)));\n\t\t\t}\n\n\t\t\treturn maxTicks;\n\t\t},\n\t\t// Called after the ticks are built. We need\n\t\thandleDirectionalChanges: function() {\n\t\t\tif (!this.isHorizontal()) {\n\t\t\t\t// We are in a vertical orientation. The top value is the highest. So reverse the array\n\t\t\t\tthis.ticks.reverse();\n\t\t\t}\n\t\t},\n\t\tgetLabelForIndex: function(index, datasetIndex) {\n\t\t\treturn +this.getRightValue(this.chart.data.datasets[datasetIndex].data[index]);\n\t\t},\n\t\t// Utils\n\t\tgetPixelForValue: function(value) {\n\t\t\t// This must be called after fit has been run so that\n\t\t\t// this.left, this.top, this.right, and this.bottom have been defined\n\t\t\tvar me = this;\n\t\t\tvar start = me.start;\n\n\t\t\tvar rightValue = +me.getRightValue(value);\n\t\t\tvar pixel;\n\t\t\tvar range = me.end - start;\n\n\t\t\tif (me.isHorizontal()) {\n\t\t\t\tpixel = me.left + (me.width / range * (rightValue - start));\n\t\t\t\treturn Math.round(pixel);\n\t\t\t}\n\n\t\t\tpixel = me.bottom - (me.height / range * (rightValue - start));\n\t\t\treturn Math.round(pixel);\n\t\t},\n\t\tgetValueForPixel: function(pixel) {\n\t\t\tvar me = this;\n\t\t\tvar isHorizontal = me.isHorizontal();\n\t\t\tvar innerDimension = isHorizontal ? me.width : me.height;\n\t\t\tvar offset = (isHorizontal ? pixel - me.left : me.bottom - pixel) / innerDimension;\n\t\t\treturn me.start + ((me.end - me.start) * offset);\n\t\t},\n\t\tgetPixelForTick: function(index) {\n\t\t\treturn this.getPixelForValue(this.ticksAsNumbers[index]);\n\t\t}\n\t});\n\tChart.scaleService.registerScaleType('linear', LinearScale, defaultConfig);\n\n};\n\n},{}],46:[function(require,module,exports){\n'use strict';\n\nmodule.exports = function(Chart) {\n\n\tvar helpers = Chart.helpers,\n\t\tnoop = helpers.noop;\n\n\tChart.LinearScaleBase = Chart.Scale.extend({\n\t\thandleTickRangeOptions: function() {\n\t\t\tvar me = this;\n\t\t\tvar opts = me.options;\n\t\t\tvar tickOpts = opts.ticks;\n\n\t\t\t// If we are forcing it to begin at 0, but 0 will already be rendered on the chart,\n\t\t\t// do nothing since that would make the chart weird. If the user really wants a weird chart\n\t\t\t// axis, they can manually override it\n\t\t\tif (tickOpts.beginAtZero) {\n\t\t\t\tvar minSign = helpers.sign(me.min);\n\t\t\t\tvar maxSign = helpers.sign(me.max);\n\n\t\t\t\tif (minSign < 0 && maxSign < 0) {\n\t\t\t\t\t// move the top up to 0\n\t\t\t\t\tme.max = 0;\n\t\t\t\t} else if (minSign > 0 && maxSign > 0) {\n\t\t\t\t\t// move the bottom down to 0\n\t\t\t\t\tme.min = 0;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (tickOpts.min !== undefined) {\n\t\t\t\tme.min = tickOpts.min;\n\t\t\t} else if (tickOpts.suggestedMin !== undefined) {\n\t\t\t\tif (me.min === null) {\n\t\t\t\t\tme.min = tickOpts.suggestedMin;\n\t\t\t\t} else {\n\t\t\t\t\tme.min = Math.min(me.min, tickOpts.suggestedMin);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (tickOpts.max !== undefined) {\n\t\t\t\tme.max = tickOpts.max;\n\t\t\t} else if (tickOpts.suggestedMax !== undefined) {\n\t\t\t\tif (me.max === null) {\n\t\t\t\t\tme.max = tickOpts.suggestedMax;\n\t\t\t\t} else {\n\t\t\t\t\tme.max = Math.max(me.max, tickOpts.suggestedMax);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (me.min === me.max) {\n\t\t\t\tme.max++;\n\n\t\t\t\tif (!tickOpts.beginAtZero) {\n\t\t\t\t\tme.min--;\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\tgetTickLimit: noop,\n\t\thandleDirectionalChanges: noop,\n\n\t\tbuildTicks: function() {\n\t\t\tvar me = this;\n\t\t\tvar opts = me.options;\n\t\t\tvar tickOpts = opts.ticks;\n\n\t\t\t// Figure out what the max number of ticks we can support it is based on the size of\n\t\t\t// the axis area. For now, we say that the minimum tick spacing in pixels must be 50\n\t\t\t// We also limit the maximum number of ticks to 11 which gives a nice 10 squares on\n\t\t\t// the graph. Make sure we always have at least 2 ticks\n\t\t\tvar maxTicks = me.getTickLimit();\n\t\t\tmaxTicks = Math.max(2, maxTicks);\n\n\t\t\tvar numericGeneratorOptions = {\n\t\t\t\tmaxTicks: maxTicks,\n\t\t\t\tmin: tickOpts.min,\n\t\t\t\tmax: tickOpts.max,\n\t\t\t\tstepSize: helpers.getValueOrDefault(tickOpts.fixedStepSize, tickOpts.stepSize)\n\t\t\t};\n\t\t\tvar ticks = me.ticks = Chart.Ticks.generators.linear(numericGeneratorOptions, me);\n\n\t\t\tme.handleDirectionalChanges();\n\n\t\t\t// At this point, we need to update our max and min given the tick values since we have expanded the\n\t\t\t// range of the scale\n\t\t\tme.max = helpers.max(ticks);\n\t\t\tme.min = helpers.min(ticks);\n\n\t\t\tif (tickOpts.reverse) {\n\t\t\t\tticks.reverse();\n\n\t\t\t\tme.start = me.max;\n\t\t\t\tme.end = me.min;\n\t\t\t} else {\n\t\t\t\tme.start = me.min;\n\t\t\t\tme.end = me.max;\n\t\t\t}\n\t\t},\n\t\tconvertTicksToLabels: function() {\n\t\t\tvar me = this;\n\t\t\tme.ticksAsNumbers = me.ticks.slice();\n\t\t\tme.zeroLineIndex = me.ticks.indexOf(0);\n\n\t\t\tChart.Scale.prototype.convertTicksToLabels.call(me);\n\t\t}\n\t});\n};\n\n},{}],47:[function(require,module,exports){\n'use strict';\n\nmodule.exports = function(Chart) {\n\n\tvar helpers = Chart.helpers;\n\n\tvar defaultConfig = {\n\t\tposition: 'left',\n\n\t\t// label settings\n\t\tticks: {\n\t\t\tcallback: Chart.Ticks.formatters.logarithmic\n\t\t}\n\t};\n\n\tvar LogarithmicScale = Chart.Scale.extend({\n\t\tdetermineDataLimits: function() {\n\t\t\tvar me = this;\n\t\t\tvar opts = me.options;\n\t\t\tvar tickOpts = opts.ticks;\n\t\t\tvar chart = me.chart;\n\t\t\tvar data = chart.data;\n\t\t\tvar datasets = data.datasets;\n\t\t\tvar getValueOrDefault = helpers.getValueOrDefault;\n\t\t\tvar isHorizontal = me.isHorizontal();\n\t\t\tfunction IDMatches(meta) {\n\t\t\t\treturn isHorizontal ? meta.xAxisID === me.id : meta.yAxisID === me.id;\n\t\t\t}\n\n\t\t\t// Calculate Range\n\t\t\tme.min = null;\n\t\t\tme.max = null;\n\t\t\tme.minNotZero = null;\n\n\t\t\tvar hasStacks = opts.stacked;\n\t\t\tif (hasStacks === undefined) {\n\t\t\t\thelpers.each(datasets, function(dataset, datasetIndex) {\n\t\t\t\t\tif (hasStacks) {\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\n\t\t\t\t\tvar meta = chart.getDatasetMeta(datasetIndex);\n\t\t\t\t\tif (chart.isDatasetVisible(datasetIndex) && IDMatches(meta) &&\n\t\t\t\t\t\tmeta.stack !== undefined) {\n\t\t\t\t\t\thasStacks = true;\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t}\n\n\t\t\tif (opts.stacked || hasStacks) {\n\t\t\t\tvar valuesPerStack = {};\n\n\t\t\t\thelpers.each(datasets, function(dataset, datasetIndex) {\n\t\t\t\t\tvar meta = chart.getDatasetMeta(datasetIndex);\n\t\t\t\t\tvar key = [\n\t\t\t\t\t\tmeta.type,\n\t\t\t\t\t\t// we have a separate stack for stack=undefined datasets when the opts.stacked is undefined\n\t\t\t\t\t\t((opts.stacked === undefined && meta.stack === undefined) ? datasetIndex : ''),\n\t\t\t\t\t\tmeta.stack\n\t\t\t\t\t].join('.');\n\n\t\t\t\t\tif (chart.isDatasetVisible(datasetIndex) && IDMatches(meta)) {\n\t\t\t\t\t\tif (valuesPerStack[key] === undefined) {\n\t\t\t\t\t\t\tvaluesPerStack[key] = [];\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\thelpers.each(dataset.data, function(rawValue, index) {\n\t\t\t\t\t\t\tvar values = valuesPerStack[key];\n\t\t\t\t\t\t\tvar value = +me.getRightValue(rawValue);\n\t\t\t\t\t\t\tif (isNaN(value) || meta.data[index].hidden) {\n\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tvalues[index] = values[index] || 0;\n\n\t\t\t\t\t\t\tif (opts.relativePoints) {\n\t\t\t\t\t\t\t\tvalues[index] = 100;\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t// Don't need to split positive and negative since the log scale can't handle a 0 crossing\n\t\t\t\t\t\t\t\tvalues[index] += value;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t});\n\n\t\t\t\thelpers.each(valuesPerStack, function(valuesForType) {\n\t\t\t\t\tvar minVal = helpers.min(valuesForType);\n\t\t\t\t\tvar maxVal = helpers.max(valuesForType);\n\t\t\t\t\tme.min = me.min === null ? minVal : Math.min(me.min, minVal);\n\t\t\t\t\tme.max = me.max === null ? maxVal : Math.max(me.max, maxVal);\n\t\t\t\t});\n\n\t\t\t} else {\n\t\t\t\thelpers.each(datasets, function(dataset, datasetIndex) {\n\t\t\t\t\tvar meta = chart.getDatasetMeta(datasetIndex);\n\t\t\t\t\tif (chart.isDatasetVisible(datasetIndex) && IDMatches(meta)) {\n\t\t\t\t\t\thelpers.each(dataset.data, function(rawValue, index) {\n\t\t\t\t\t\t\tvar value = +me.getRightValue(rawValue);\n\t\t\t\t\t\t\tif (isNaN(value) || meta.data[index].hidden) {\n\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tif (me.min === null) {\n\t\t\t\t\t\t\t\tme.min = value;\n\t\t\t\t\t\t\t} else if (value < me.min) {\n\t\t\t\t\t\t\t\tme.min = value;\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tif (me.max === null) {\n\t\t\t\t\t\t\t\tme.max = value;\n\t\t\t\t\t\t\t} else if (value > me.max) {\n\t\t\t\t\t\t\t\tme.max = value;\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tif (value !== 0 && (me.minNotZero === null || value < me.minNotZero)) {\n\t\t\t\t\t\t\t\tme.minNotZero = value;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t}\n\n\t\t\tme.min = getValueOrDefault(tickOpts.min, me.min);\n\t\t\tme.max = getValueOrDefault(tickOpts.max, me.max);\n\n\t\t\tif (me.min === me.max) {\n\t\t\t\tif (me.min !== 0 && me.min !== null) {\n\t\t\t\t\tme.min = Math.pow(10, Math.floor(helpers.log10(me.min)) - 1);\n\t\t\t\t\tme.max = Math.pow(10, Math.floor(helpers.log10(me.max)) + 1);\n\t\t\t\t} else {\n\t\t\t\t\tme.min = 1;\n\t\t\t\t\tme.max = 10;\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\tbuildTicks: function() {\n\t\t\tvar me = this;\n\t\t\tvar opts = me.options;\n\t\t\tvar tickOpts = opts.ticks;\n\n\t\t\tvar generationOptions = {\n\t\t\t\tmin: tickOpts.min,\n\t\t\t\tmax: tickOpts.max\n\t\t\t};\n\t\t\tvar ticks = me.ticks = Chart.Ticks.generators.logarithmic(generationOptions, me);\n\n\t\t\tif (!me.isHorizontal()) {\n\t\t\t\t// We are in a vertical orientation. The top value is the highest. So reverse the array\n\t\t\t\tticks.reverse();\n\t\t\t}\n\n\t\t\t// At this point, we need to update our max and min given the tick values since we have expanded the\n\t\t\t// range of the scale\n\t\t\tme.max = helpers.max(ticks);\n\t\t\tme.min = helpers.min(ticks);\n\n\t\t\tif (tickOpts.reverse) {\n\t\t\t\tticks.reverse();\n\n\t\t\t\tme.start = me.max;\n\t\t\t\tme.end = me.min;\n\t\t\t} else {\n\t\t\t\tme.start = me.min;\n\t\t\t\tme.end = me.max;\n\t\t\t}\n\t\t},\n\t\tconvertTicksToLabels: function() {\n\t\t\tthis.tickValues = this.ticks.slice();\n\n\t\t\tChart.Scale.prototype.convertTicksToLabels.call(this);\n\t\t},\n\t\t// Get the correct tooltip label\n\t\tgetLabelForIndex: function(index, datasetIndex) {\n\t\t\treturn +this.getRightValue(this.chart.data.datasets[datasetIndex].data[index]);\n\t\t},\n\t\tgetPixelForTick: function(index) {\n\t\t\treturn this.getPixelForValue(this.tickValues[index]);\n\t\t},\n\t\tgetPixelForValue: function(value) {\n\t\t\tvar me = this;\n\t\t\tvar innerDimension;\n\t\t\tvar pixel;\n\n\t\t\tvar start = me.start;\n\t\t\tvar newVal = +me.getRightValue(value);\n\t\t\tvar range;\n\t\t\tvar opts = me.options;\n\t\t\tvar tickOpts = opts.ticks;\n\n\t\t\tif (me.isHorizontal()) {\n\t\t\t\trange = helpers.log10(me.end) - helpers.log10(start); // todo: if start === 0\n\t\t\t\tif (newVal === 0) {\n\t\t\t\t\tpixel = me.left;\n\t\t\t\t} else {\n\t\t\t\t\tinnerDimension = me.width;\n\t\t\t\t\tpixel = me.left + (innerDimension / range * (helpers.log10(newVal) - helpers.log10(start)));\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t// Bottom - top since pixels increase downward on a screen\n\t\t\t\tinnerDimension = me.height;\n\t\t\t\tif (start === 0 && !tickOpts.reverse) {\n\t\t\t\t\trange = helpers.log10(me.end) - helpers.log10(me.minNotZero);\n\t\t\t\t\tif (newVal === start) {\n\t\t\t\t\t\tpixel = me.bottom;\n\t\t\t\t\t} else if (newVal === me.minNotZero) {\n\t\t\t\t\t\tpixel = me.bottom - innerDimension * 0.02;\n\t\t\t\t\t} else {\n\t\t\t\t\t\tpixel = me.bottom - innerDimension * 0.02 - (innerDimension * 0.98/ range * (helpers.log10(newVal)-helpers.log10(me.minNotZero)));\n\t\t\t\t\t}\n\t\t\t\t} else if (me.end === 0 && tickOpts.reverse) {\n\t\t\t\t\trange = helpers.log10(me.start) - helpers.log10(me.minNotZero);\n\t\t\t\t\tif (newVal === me.end) {\n\t\t\t\t\t\tpixel = me.top;\n\t\t\t\t\t} else if (newVal === me.minNotZero) {\n\t\t\t\t\t\tpixel = me.top + innerDimension * 0.02;\n\t\t\t\t\t} else {\n\t\t\t\t\t\tpixel = me.top + innerDimension * 0.02 + (innerDimension * 0.98/ range * (helpers.log10(newVal)-helpers.log10(me.minNotZero)));\n\t\t\t\t\t}\n\t\t\t\t} else if (newVal === 0) {\n\t\t\t\t\tpixel = tickOpts.reverse ? me.top : me.bottom;\n\t\t\t\t} else {\n\t\t\t\t\trange = helpers.log10(me.end) - helpers.log10(start);\n\t\t\t\t\tinnerDimension = me.height;\n\t\t\t\t\tpixel = me.bottom - (innerDimension / range * (helpers.log10(newVal) - helpers.log10(start)));\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn pixel;\n\t\t},\n\t\tgetValueForPixel: function(pixel) {\n\t\t\tvar me = this;\n\t\t\tvar range = helpers.log10(me.end) - helpers.log10(me.start);\n\t\t\tvar value, innerDimension;\n\n\t\t\tif (me.isHorizontal()) {\n\t\t\t\tinnerDimension = me.width;\n\t\t\t\tvalue = me.start * Math.pow(10, (pixel - me.left) * range / innerDimension);\n\t\t\t} else {  // todo: if start === 0\n\t\t\t\tinnerDimension = me.height;\n\t\t\t\tvalue = Math.pow(10, (me.bottom - pixel) * range / innerDimension) / me.start;\n\t\t\t}\n\t\t\treturn value;\n\t\t}\n\t});\n\tChart.scaleService.registerScaleType('logarithmic', LogarithmicScale, defaultConfig);\n\n};\n\n},{}],48:[function(require,module,exports){\n'use strict';\n\nmodule.exports = function(Chart) {\n\n\tvar helpers = Chart.helpers;\n\tvar globalDefaults = Chart.defaults.global;\n\n\tvar defaultConfig = {\n\t\tdisplay: true,\n\n\t\t// Boolean - Whether to animate scaling the chart from the centre\n\t\tanimate: true,\n\t\tposition: 'chartArea',\n\n\t\tangleLines: {\n\t\t\tdisplay: true,\n\t\t\tcolor: 'rgba(0, 0, 0, 0.1)',\n\t\t\tlineWidth: 1\n\t\t},\n\n\t\tgridLines: {\n\t\t\tcircular: false\n\t\t},\n\n\t\t// label settings\n\t\tticks: {\n\t\t\t// Boolean - Show a backdrop to the scale label\n\t\t\tshowLabelBackdrop: true,\n\n\t\t\t// String - The colour of the label backdrop\n\t\t\tbackdropColor: 'rgba(255,255,255,0.75)',\n\n\t\t\t// Number - The backdrop padding above & below the label in pixels\n\t\t\tbackdropPaddingY: 2,\n\n\t\t\t// Number - The backdrop padding to the side of the label in pixels\n\t\t\tbackdropPaddingX: 2,\n\n\t\t\tcallback: Chart.Ticks.formatters.linear\n\t\t},\n\n\t\tpointLabels: {\n\t\t\t// Boolean - if true, show point labels\n\t\t\tdisplay: true,\n\n\t\t\t// Number - Point label font size in pixels\n\t\t\tfontSize: 10,\n\n\t\t\t// Function - Used to convert point labels\n\t\t\tcallback: function(label) {\n\t\t\t\treturn label;\n\t\t\t}\n\t\t}\n\t};\n\n\tfunction getValueCount(scale) {\n\t\tvar opts = scale.options;\n\t\treturn opts.angleLines.display || opts.pointLabels.display ? scale.chart.data.labels.length : 0;\n\t}\n\n\tfunction getPointLabelFontOptions(scale) {\n\t\tvar pointLabelOptions = scale.options.pointLabels;\n\t\tvar fontSize = helpers.getValueOrDefault(pointLabelOptions.fontSize, globalDefaults.defaultFontSize);\n\t\tvar fontStyle = helpers.getValueOrDefault(pointLabelOptions.fontStyle, globalDefaults.defaultFontStyle);\n\t\tvar fontFamily = helpers.getValueOrDefault(pointLabelOptions.fontFamily, globalDefaults.defaultFontFamily);\n\t\tvar font = helpers.fontString(fontSize, fontStyle, fontFamily);\n\n\t\treturn {\n\t\t\tsize: fontSize,\n\t\t\tstyle: fontStyle,\n\t\t\tfamily: fontFamily,\n\t\t\tfont: font\n\t\t};\n\t}\n\n\tfunction measureLabelSize(ctx, fontSize, label) {\n\t\tif (helpers.isArray(label)) {\n\t\t\treturn {\n\t\t\t\tw: helpers.longestText(ctx, ctx.font, label),\n\t\t\t\th: (label.length * fontSize) + ((label.length - 1) * 1.5 * fontSize)\n\t\t\t};\n\t\t}\n\n\t\treturn {\n\t\t\tw: ctx.measureText(label).width,\n\t\t\th: fontSize\n\t\t};\n\t}\n\n\tfunction determineLimits(angle, pos, size, min, max) {\n\t\tif (angle === min || angle === max) {\n\t\t\treturn {\n\t\t\t\tstart: pos - (size / 2),\n\t\t\t\tend: pos + (size / 2)\n\t\t\t};\n\t\t} else if (angle < min || angle > max) {\n\t\t\treturn {\n\t\t\t\tstart: pos - size - 5,\n\t\t\t\tend: pos\n\t\t\t};\n\t\t}\n\n\t\treturn {\n\t\t\tstart: pos,\n\t\t\tend: pos + size + 5\n\t\t};\n\t}\n\n\t/**\n\t * Helper function to fit a radial linear scale with point labels\n\t */\n\tfunction fitWithPointLabels(scale) {\n\t\t/*\n\t\t * Right, this is really confusing and there is a lot of maths going on here\n\t\t * The gist of the problem is here: https://gist.github.com/nnnick/696cc9c55f4b0beb8fe9\n\t\t *\n\t\t * Reaction: https://dl.dropboxusercontent.com/u/34601363/toomuchscience.gif\n\t\t *\n\t\t * Solution:\n\t\t *\n\t\t * We assume the radius of the polygon is half the size of the canvas at first\n\t\t * at each index we check if the text overlaps.\n\t\t *\n\t\t * Where it does, we store that angle and that index.\n\t\t *\n\t\t * After finding the largest index and angle we calculate how much we need to remove\n\t\t * from the shape radius to move the point inwards by that x.\n\t\t *\n\t\t * We average the left and right distances to get the maximum shape radius that can fit in the box\n\t\t * along with labels.\n\t\t *\n\t\t * Once we have that, we can find the centre point for the chart, by taking the x text protrusion\n\t\t * on each side, removing that from the size, halving it and adding the left x protrusion width.\n\t\t *\n\t\t * This will mean we have a shape fitted to the canvas, as large as it can be with the labels\n\t\t * and position it in the most space efficient manner\n\t\t *\n\t\t * https://dl.dropboxusercontent.com/u/34601363/yeahscience.gif\n\t\t */\n\n\t\tvar plFont = getPointLabelFontOptions(scale);\n\n\t\t// Get maximum radius of the polygon. Either half the height (minus the text width) or half the width.\n\t\t// Use this to calculate the offset + change. - Make sure L/R protrusion is at least 0 to stop issues with centre points\n\t\tvar largestPossibleRadius = Math.min(scale.height / 2, scale.width / 2);\n\t\tvar furthestLimits = {\n\t\t\tr: scale.width,\n\t\t\tl: 0,\n\t\t\tt: scale.height,\n\t\t\tb: 0\n\t\t};\n\t\tvar furthestAngles = {};\n\t\tvar i;\n\t\tvar textSize;\n\t\tvar pointPosition;\n\n\t\tscale.ctx.font = plFont.font;\n\t\tscale._pointLabelSizes = [];\n\n\t\tvar valueCount = getValueCount(scale);\n\t\tfor (i = 0; i < valueCount; i++) {\n\t\t\tpointPosition = scale.getPointPosition(i, largestPossibleRadius);\n\t\t\ttextSize = measureLabelSize(scale.ctx, plFont.size, scale.pointLabels[i] || '');\n\t\t\tscale._pointLabelSizes[i] = textSize;\n\n\t\t\t// Add quarter circle to make degree 0 mean top of circle\n\t\t\tvar angleRadians = scale.getIndexAngle(i);\n\t\t\tvar angle = helpers.toDegrees(angleRadians) % 360;\n\t\t\tvar hLimits = determineLimits(angle, pointPosition.x, textSize.w, 0, 180);\n\t\t\tvar vLimits = determineLimits(angle, pointPosition.y, textSize.h, 90, 270);\n\n\t\t\tif (hLimits.start < furthestLimits.l) {\n\t\t\t\tfurthestLimits.l = hLimits.start;\n\t\t\t\tfurthestAngles.l = angleRadians;\n\t\t\t}\n\n\t\t\tif (hLimits.end > furthestLimits.r) {\n\t\t\t\tfurthestLimits.r = hLimits.end;\n\t\t\t\tfurthestAngles.r = angleRadians;\n\t\t\t}\n\n\t\t\tif (vLimits.start < furthestLimits.t) {\n\t\t\t\tfurthestLimits.t = vLimits.start;\n\t\t\t\tfurthestAngles.t = angleRadians;\n\t\t\t}\n\n\t\t\tif (vLimits.end > furthestLimits.b) {\n\t\t\t\tfurthestLimits.b = vLimits.end;\n\t\t\t\tfurthestAngles.b = angleRadians;\n\t\t\t}\n\t\t}\n\n\t\tscale.setReductions(largestPossibleRadius, furthestLimits, furthestAngles);\n\t}\n\n\t/**\n\t * Helper function to fit a radial linear scale with no point labels\n\t */\n\tfunction fit(scale) {\n\t\tvar largestPossibleRadius = Math.min(scale.height / 2, scale.width / 2);\n\t\tscale.drawingArea = Math.round(largestPossibleRadius);\n\t\tscale.setCenterPoint(0, 0, 0, 0);\n\t}\n\n\tfunction getTextAlignForAngle(angle) {\n\t\tif (angle === 0 || angle === 180) {\n\t\t\treturn 'center';\n\t\t} else if (angle < 180) {\n\t\t\treturn 'left';\n\t\t}\n\n\t\treturn 'right';\n\t}\n\n\tfunction fillText(ctx, text, position, fontSize) {\n\t\tif (helpers.isArray(text)) {\n\t\t\tvar y = position.y;\n\t\t\tvar spacing = 1.5 * fontSize;\n\n\t\t\tfor (var i = 0; i < text.length; ++i) {\n\t\t\t\tctx.fillText(text[i], position.x, y);\n\t\t\t\ty+= spacing;\n\t\t\t}\n\t\t} else {\n\t\t\tctx.fillText(text, position.x, position.y);\n\t\t}\n\t}\n\n\tfunction adjustPointPositionForLabelHeight(angle, textSize, position) {\n\t\tif (angle === 90 || angle === 270) {\n\t\t\tposition.y -= (textSize.h / 2);\n\t\t} else if (angle > 270 || angle < 90) {\n\t\t\tposition.y -= textSize.h;\n\t\t}\n\t}\n\n\tfunction drawPointLabels(scale) {\n\t\tvar ctx = scale.ctx;\n\t\tvar getValueOrDefault = helpers.getValueOrDefault;\n\t\tvar opts = scale.options;\n\t\tvar angleLineOpts = opts.angleLines;\n\t\tvar pointLabelOpts = opts.pointLabels;\n\n\t\tctx.lineWidth = angleLineOpts.lineWidth;\n\t\tctx.strokeStyle = angleLineOpts.color;\n\n\t\tvar outerDistance = scale.getDistanceFromCenterForValue(opts.reverse ? scale.min : scale.max);\n\n\t\t// Point Label Font\n\t\tvar plFont = getPointLabelFontOptions(scale);\n\n\t\tctx.textBaseline = 'top';\n\n\t\tfor (var i = getValueCount(scale) - 1; i >= 0; i--) {\n\t\t\tif (angleLineOpts.display) {\n\t\t\t\tvar outerPosition = scale.getPointPosition(i, outerDistance);\n\t\t\t\tctx.beginPath();\n\t\t\t\tctx.moveTo(scale.xCenter, scale.yCenter);\n\t\t\t\tctx.lineTo(outerPosition.x, outerPosition.y);\n\t\t\t\tctx.stroke();\n\t\t\t\tctx.closePath();\n\t\t\t}\n\n\t\t\tif (pointLabelOpts.display) {\n\t\t\t\t// Extra 3px out for some label spacing\n\t\t\t\tvar pointLabelPosition = scale.getPointPosition(i, outerDistance + 5);\n\n\t\t\t\t// Keep this in loop since we may support array properties here\n\t\t\t\tvar pointLabelFontColor = getValueOrDefault(pointLabelOpts.fontColor, globalDefaults.defaultFontColor);\n\t\t\t\tctx.font = plFont.font;\n\t\t\t\tctx.fillStyle = pointLabelFontColor;\n\n\t\t\t\tvar angleRadians = scale.getIndexAngle(i);\n\t\t\t\tvar angle = helpers.toDegrees(angleRadians);\n\t\t\t\tctx.textAlign = getTextAlignForAngle(angle);\n\t\t\t\tadjustPointPositionForLabelHeight(angle, scale._pointLabelSizes[i], pointLabelPosition);\n\t\t\t\tfillText(ctx, scale.pointLabels[i] || '', pointLabelPosition, plFont.size);\n\t\t\t}\n\t\t}\n\t}\n\n\tfunction drawRadiusLine(scale, gridLineOpts, radius, index) {\n\t\tvar ctx = scale.ctx;\n\t\tctx.strokeStyle = helpers.getValueAtIndexOrDefault(gridLineOpts.color, index - 1);\n\t\tctx.lineWidth = helpers.getValueAtIndexOrDefault(gridLineOpts.lineWidth, index - 1);\n\n\t\tif (scale.options.gridLines.circular) {\n\t\t\t// Draw circular arcs between the points\n\t\t\tctx.beginPath();\n\t\t\tctx.arc(scale.xCenter, scale.yCenter, radius, 0, Math.PI * 2);\n\t\t\tctx.closePath();\n\t\t\tctx.stroke();\n\t\t} else {\n\t\t\t// Draw straight lines connecting each index\n\t\t\tvar valueCount = getValueCount(scale);\n\n\t\t\tif (valueCount === 0) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tctx.beginPath();\n\t\t\tvar pointPosition = scale.getPointPosition(0, radius);\n\t\t\tctx.moveTo(pointPosition.x, pointPosition.y);\n\n\t\t\tfor (var i = 1; i < valueCount; i++) {\n\t\t\t\tpointPosition = scale.getPointPosition(i, radius);\n\t\t\t\tctx.lineTo(pointPosition.x, pointPosition.y);\n\t\t\t}\n\n\t\t\tctx.closePath();\n\t\t\tctx.stroke();\n\t\t}\n\t}\n\n\tfunction numberOrZero(param) {\n\t\treturn helpers.isNumber(param) ? param : 0;\n\t}\n\n\tvar LinearRadialScale = Chart.LinearScaleBase.extend({\n\t\tsetDimensions: function() {\n\t\t\tvar me = this;\n\t\t\tvar opts = me.options;\n\t\t\tvar tickOpts = opts.ticks;\n\t\t\t// Set the unconstrained dimension before label rotation\n\t\t\tme.width = me.maxWidth;\n\t\t\tme.height = me.maxHeight;\n\t\t\tme.xCenter = Math.round(me.width / 2);\n\t\t\tme.yCenter = Math.round(me.height / 2);\n\n\t\t\tvar minSize = helpers.min([me.height, me.width]);\n\t\t\tvar tickFontSize = helpers.getValueOrDefault(tickOpts.fontSize, globalDefaults.defaultFontSize);\n\t\t\tme.drawingArea = opts.display ? (minSize / 2) - (tickFontSize / 2 + tickOpts.backdropPaddingY) : (minSize / 2);\n\t\t},\n\t\tdetermineDataLimits: function() {\n\t\t\tvar me = this;\n\t\t\tvar chart = me.chart;\n\t\t\tvar min = Number.POSITIVE_INFINITY;\n\t\t\tvar max = Number.NEGATIVE_INFINITY;\n\n\t\t\thelpers.each(chart.data.datasets, function(dataset, datasetIndex) {\n\t\t\t\tif (chart.isDatasetVisible(datasetIndex)) {\n\t\t\t\t\tvar meta = chart.getDatasetMeta(datasetIndex);\n\n\t\t\t\t\thelpers.each(dataset.data, function(rawValue, index) {\n\t\t\t\t\t\tvar value = +me.getRightValue(rawValue);\n\t\t\t\t\t\tif (isNaN(value) || meta.data[index].hidden) {\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tmin = Math.min(value, min);\n\t\t\t\t\t\tmax = Math.max(value, max);\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t});\n\n\t\t\tme.min = (min === Number.POSITIVE_INFINITY ? 0 : min);\n\t\t\tme.max = (max === Number.NEGATIVE_INFINITY ? 0 : max);\n\n\t\t\t// Common base implementation to handle ticks.min, ticks.max, ticks.beginAtZero\n\t\t\tme.handleTickRangeOptions();\n\t\t},\n\t\tgetTickLimit: function() {\n\t\t\tvar tickOpts = this.options.ticks;\n\t\t\tvar tickFontSize = helpers.getValueOrDefault(tickOpts.fontSize, globalDefaults.defaultFontSize);\n\t\t\treturn Math.min(tickOpts.maxTicksLimit ? tickOpts.maxTicksLimit : 11, Math.ceil(this.drawingArea / (1.5 * tickFontSize)));\n\t\t},\n\t\tconvertTicksToLabels: function() {\n\t\t\tvar me = this;\n\t\t\tChart.LinearScaleBase.prototype.convertTicksToLabels.call(me);\n\n\t\t\t// Point labels\n\t\t\tme.pointLabels = me.chart.data.labels.map(me.options.pointLabels.callback, me);\n\t\t},\n\t\tgetLabelForIndex: function(index, datasetIndex) {\n\t\t\treturn +this.getRightValue(this.chart.data.datasets[datasetIndex].data[index]);\n\t\t},\n\t\tfit: function() {\n\t\t\tif (this.options.pointLabels.display) {\n\t\t\t\tfitWithPointLabels(this);\n\t\t\t} else {\n\t\t\t\tfit(this);\n\t\t\t}\n\t\t},\n\t\t/**\n\t\t * Set radius reductions and determine new radius and center point\n\t\t * @private\n\t\t */\n\t\tsetReductions: function(largestPossibleRadius, furthestLimits, furthestAngles) {\n\t\t\tvar me = this;\n\t\t\tvar radiusReductionLeft = furthestLimits.l / Math.sin(furthestAngles.l);\n\t\t\tvar radiusReductionRight = Math.max(furthestLimits.r - me.width, 0) / Math.sin(furthestAngles.r);\n\t\t\tvar radiusReductionTop = -furthestLimits.t / Math.cos(furthestAngles.t);\n\t\t\tvar radiusReductionBottom = -Math.max(furthestLimits.b - me.height, 0) / Math.cos(furthestAngles.b);\n\n\t\t\tradiusReductionLeft = numberOrZero(radiusReductionLeft);\n\t\t\tradiusReductionRight = numberOrZero(radiusReductionRight);\n\t\t\tradiusReductionTop = numberOrZero(radiusReductionTop);\n\t\t\tradiusReductionBottom = numberOrZero(radiusReductionBottom);\n\n\t\t\tme.drawingArea = Math.min(\n\t\t\t\tMath.round(largestPossibleRadius - (radiusReductionLeft + radiusReductionRight) / 2),\n\t\t\t\tMath.round(largestPossibleRadius - (radiusReductionTop + radiusReductionBottom) / 2));\n\t\t\tme.setCenterPoint(radiusReductionLeft, radiusReductionRight, radiusReductionTop, radiusReductionBottom);\n\t\t},\n\t\tsetCenterPoint: function(leftMovement, rightMovement, topMovement, bottomMovement) {\n\t\t\tvar me = this;\n\t\t\tvar maxRight = me.width - rightMovement - me.drawingArea,\n\t\t\t\tmaxLeft = leftMovement + me.drawingArea,\n\t\t\t\tmaxTop = topMovement + me.drawingArea,\n\t\t\t\tmaxBottom = me.height - bottomMovement - me.drawingArea;\n\n\t\t\tme.xCenter = Math.round(((maxLeft + maxRight) / 2) + me.left);\n\t\t\tme.yCenter = Math.round(((maxTop + maxBottom) / 2) + me.top);\n\t\t},\n\n\t\tgetIndexAngle: function(index) {\n\t\t\tvar angleMultiplier = (Math.PI * 2) / getValueCount(this);\n\t\t\tvar startAngle = this.chart.options && this.chart.options.startAngle ?\n\t\t\t\tthis.chart.options.startAngle :\n\t\t\t\t0;\n\n\t\t\tvar startAngleRadians = startAngle * Math.PI * 2 / 360;\n\n\t\t\t// Start from the top instead of right, so remove a quarter of the circle\n\t\t\treturn index * angleMultiplier + startAngleRadians;\n\t\t},\n\t\tgetDistanceFromCenterForValue: function(value) {\n\t\t\tvar me = this;\n\n\t\t\tif (value === null) {\n\t\t\t\treturn 0; // null always in center\n\t\t\t}\n\n\t\t\t// Take into account half font size + the yPadding of the top value\n\t\t\tvar scalingFactor = me.drawingArea / (me.max - me.min);\n\t\t\tif (me.options.reverse) {\n\t\t\t\treturn (me.max - value) * scalingFactor;\n\t\t\t}\n\t\t\treturn (value - me.min) * scalingFactor;\n\t\t},\n\t\tgetPointPosition: function(index, distanceFromCenter) {\n\t\t\tvar me = this;\n\t\t\tvar thisAngle = me.getIndexAngle(index) - (Math.PI / 2);\n\t\t\treturn {\n\t\t\t\tx: Math.round(Math.cos(thisAngle) * distanceFromCenter) + me.xCenter,\n\t\t\t\ty: Math.round(Math.sin(thisAngle) * distanceFromCenter) + me.yCenter\n\t\t\t};\n\t\t},\n\t\tgetPointPositionForValue: function(index, value) {\n\t\t\treturn this.getPointPosition(index, this.getDistanceFromCenterForValue(value));\n\t\t},\n\n\t\tgetBasePosition: function() {\n\t\t\tvar me = this;\n\t\t\tvar min = me.min;\n\t\t\tvar max = me.max;\n\n\t\t\treturn me.getPointPositionForValue(0,\n\t\t\t\tme.beginAtZero? 0:\n\t\t\t\tmin < 0 && max < 0? max :\n\t\t\t\tmin > 0 && max > 0? min :\n\t\t\t\t0);\n\t\t},\n\n\t\tdraw: function() {\n\t\t\tvar me = this;\n\t\t\tvar opts = me.options;\n\t\t\tvar gridLineOpts = opts.gridLines;\n\t\t\tvar tickOpts = opts.ticks;\n\t\t\tvar getValueOrDefault = helpers.getValueOrDefault;\n\n\t\t\tif (opts.display) {\n\t\t\t\tvar ctx = me.ctx;\n\n\t\t\t\t// Tick Font\n\t\t\t\tvar tickFontSize = getValueOrDefault(tickOpts.fontSize, globalDefaults.defaultFontSize);\n\t\t\t\tvar tickFontStyle = getValueOrDefault(tickOpts.fontStyle, globalDefaults.defaultFontStyle);\n\t\t\t\tvar tickFontFamily = getValueOrDefault(tickOpts.fontFamily, globalDefaults.defaultFontFamily);\n\t\t\t\tvar tickLabelFont = helpers.fontString(tickFontSize, tickFontStyle, tickFontFamily);\n\n\t\t\t\thelpers.each(me.ticks, function(label, index) {\n\t\t\t\t\t// Don't draw a centre value (if it is minimum)\n\t\t\t\t\tif (index > 0 || opts.reverse) {\n\t\t\t\t\t\tvar yCenterOffset = me.getDistanceFromCenterForValue(me.ticksAsNumbers[index]);\n\t\t\t\t\t\tvar yHeight = me.yCenter - yCenterOffset;\n\n\t\t\t\t\t\t// Draw circular lines around the scale\n\t\t\t\t\t\tif (gridLineOpts.display && index !== 0) {\n\t\t\t\t\t\t\tdrawRadiusLine(me, gridLineOpts, yCenterOffset, index);\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif (tickOpts.display) {\n\t\t\t\t\t\t\tvar tickFontColor = getValueOrDefault(tickOpts.fontColor, globalDefaults.defaultFontColor);\n\t\t\t\t\t\t\tctx.font = tickLabelFont;\n\n\t\t\t\t\t\t\tif (tickOpts.showLabelBackdrop) {\n\t\t\t\t\t\t\t\tvar labelWidth = ctx.measureText(label).width;\n\t\t\t\t\t\t\t\tctx.fillStyle = tickOpts.backdropColor;\n\t\t\t\t\t\t\t\tctx.fillRect(\n\t\t\t\t\t\t\t\t\tme.xCenter - labelWidth / 2 - tickOpts.backdropPaddingX,\n\t\t\t\t\t\t\t\t\tyHeight - tickFontSize / 2 - tickOpts.backdropPaddingY,\n\t\t\t\t\t\t\t\t\tlabelWidth + tickOpts.backdropPaddingX * 2,\n\t\t\t\t\t\t\t\t\ttickFontSize + tickOpts.backdropPaddingY * 2\n\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tctx.textAlign = 'center';\n\t\t\t\t\t\t\tctx.textBaseline = 'middle';\n\t\t\t\t\t\t\tctx.fillStyle = tickFontColor;\n\t\t\t\t\t\t\tctx.fillText(label, me.xCenter, yHeight);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t});\n\n\t\t\t\tif (opts.angleLines.display || opts.pointLabels.display) {\n\t\t\t\t\tdrawPointLabels(me);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t});\n\tChart.scaleService.registerScaleType('radialLinear', LinearRadialScale, defaultConfig);\n\n};\n\n},{}],49:[function(require,module,exports){\n/* global window: false */\n'use strict';\n\nvar moment = require(1);\nmoment = typeof(moment) === 'function' ? moment : window.moment;\n\nmodule.exports = function(Chart) {\n\n\tvar helpers = Chart.helpers;\n\tvar interval = {\n\t\tmillisecond: {\n\t\t\tsize: 1,\n\t\t\tsteps: [1, 2, 5, 10, 20, 50, 100, 250, 500]\n\t\t},\n\t\tsecond: {\n\t\t\tsize: 1000,\n\t\t\tsteps: [1, 2, 5, 10, 30]\n\t\t},\n\t\tminute: {\n\t\t\tsize: 60000,\n\t\t\tsteps: [1, 2, 5, 10, 30]\n\t\t},\n\t\thour: {\n\t\t\tsize: 3600000,\n\t\t\tsteps: [1, 2, 3, 6, 12]\n\t\t},\n\t\tday: {\n\t\t\tsize: 86400000,\n\t\t\tsteps: [1, 2, 5]\n\t\t},\n\t\tweek: {\n\t\t\tsize: 604800000,\n\t\t\tmaxStep: 4\n\t\t},\n\t\tmonth: {\n\t\t\tsize: 2.628e9,\n\t\t\tmaxStep: 3\n\t\t},\n\t\tquarter: {\n\t\t\tsize: 7.884e9,\n\t\t\tmaxStep: 4\n\t\t},\n\t\tyear: {\n\t\t\tsize: 3.154e10,\n\t\t\tmaxStep: false\n\t\t}\n\t};\n\n\tvar defaultConfig = {\n\t\tposition: 'bottom',\n\n\t\ttime: {\n\t\t\tparser: false, // false == a pattern string from http://momentjs.com/docs/#/parsing/string-format/ or a custom callback that converts its argument to a moment\n\t\t\tformat: false, // DEPRECATED false == date objects, moment object, callback or a pattern string from http://momentjs.com/docs/#/parsing/string-format/\n\t\t\tunit: false, // false == automatic or override with week, month, year, etc.\n\t\t\tround: false, // none, or override with week, month, year, etc.\n\t\t\tdisplayFormat: false, // DEPRECATED\n\t\t\tisoWeekday: false, // override week start day - see http://momentjs.com/docs/#/get-set/iso-weekday/\n\t\t\tminUnit: 'millisecond',\n\n\t\t\t// defaults to unit's corresponding unitFormat below or override using pattern string from http://momentjs.com/docs/#/displaying/format/\n\t\t\tdisplayFormats: {\n\t\t\t\tmillisecond: 'h:mm:ss.SSS a', // 11:20:01.123 AM,\n\t\t\t\tsecond: 'h:mm:ss a', // 11:20:01 AM\n\t\t\t\tminute: 'h:mm:ss a', // 11:20:01 AM\n\t\t\t\thour: 'MMM D, hA', // Sept 4, 5PM\n\t\t\t\tday: 'll', // Sep 4 2015\n\t\t\t\tweek: 'll', // Week 46, or maybe \"[W]WW - YYYY\" ?\n\t\t\t\tmonth: 'MMM YYYY', // Sept 2015\n\t\t\t\tquarter: '[Q]Q - YYYY', // Q3\n\t\t\t\tyear: 'YYYY' // 2015\n\t\t\t},\n\t\t},\n\t\tticks: {\n\t\t\tautoSkip: false\n\t\t}\n\t};\n\n\t/**\n\t * Helper function to parse time to a moment object\n\t * @param axis {TimeAxis} the time axis\n\t * @param label {Date|string|number|Moment} The thing to parse\n\t * @return {Moment} parsed time\n\t */\n\tfunction parseTime(axis, label) {\n\t\tvar timeOpts = axis.options.time;\n\t\tif (typeof timeOpts.parser === 'string') {\n\t\t\treturn moment(label, timeOpts.parser);\n\t\t}\n\t\tif (typeof timeOpts.parser === 'function') {\n\t\t\treturn timeOpts.parser(label);\n\t\t}\n\t\tif (typeof label.getMonth === 'function' || typeof label === 'number') {\n\t\t\t// Date objects\n\t\t\treturn moment(label);\n\t\t}\n\t\tif (label.isValid && label.isValid()) {\n\t\t\t// Moment support\n\t\t\treturn label;\n\t\t}\n\t\tvar format = timeOpts.format;\n\t\tif (typeof format !== 'string' && format.call) {\n\t\t\t// Custom parsing (return an instance of moment)\n\t\t\tconsole.warn('options.time.format is deprecated and replaced by options.time.parser.');\n\t\t\treturn format(label);\n\t\t}\n\t\t// Moment format parsing\n\t\treturn moment(label, format);\n\t}\n\n\t/**\n\t * Figure out which is the best unit for the scale\n\t * @param minUnit {String} minimum unit to use\n\t * @param min {Number} scale minimum\n\t * @param max {Number} scale maximum\n\t * @return {String} the unit to use\n\t */\n\tfunction determineUnit(minUnit, min, max, maxTicks) {\n\t\tvar units = Object.keys(interval);\n\t\tvar unit;\n\t\tvar numUnits = units.length;\n\n\t\tfor (var i = units.indexOf(minUnit); i < numUnits; i++) {\n\t\t\tunit = units[i];\n\t\t\tvar unitDetails = interval[unit];\n\t\t\tvar steps = (unitDetails.steps && unitDetails.steps[unitDetails.steps.length - 1]) || unitDetails.maxStep;\n\t\t\tif (steps === undefined || Math.ceil((max - min) / (steps * unitDetails.size)) <= maxTicks) {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\treturn unit;\n\t}\n\n\t/**\n\t * Determines how we scale the unit\n\t * @param min {Number} the scale minimum\n\t * @param max {Number} the scale maximum\n\t * @param unit {String} the unit determined by the {@see determineUnit} method\n\t * @return {Number} the axis step size as a multiple of unit\n\t */\n\tfunction determineStepSize(min, max, unit, maxTicks) {\n\t\t// Using our unit, figoure out what we need to scale as\n\t\tvar unitDefinition = interval[unit];\n\t\tvar unitSizeInMilliSeconds = unitDefinition.size;\n\t\tvar sizeInUnits = Math.ceil((max - min) / unitSizeInMilliSeconds);\n\t\tvar multiplier = 1;\n\t\tvar range = max - min;\n\n\t\tif (unitDefinition.steps) {\n\t\t\t// Have an array of steps\n\t\t\tvar numSteps = unitDefinition.steps.length;\n\t\t\tfor (var i = 0; i < numSteps && sizeInUnits > maxTicks; i++) {\n\t\t\t\tmultiplier = unitDefinition.steps[i];\n\t\t\t\tsizeInUnits = Math.ceil(range / (unitSizeInMilliSeconds * multiplier));\n\t\t\t}\n\t\t} else {\n\t\t\twhile (sizeInUnits > maxTicks && maxTicks > 0) {\n\t\t\t\t++multiplier;\n\t\t\t\tsizeInUnits = Math.ceil(range / (unitSizeInMilliSeconds * multiplier));\n\t\t\t}\n\t\t}\n\n\t\treturn multiplier;\n\t}\n\n\t/**\n\t * Helper for generating axis labels.\n\t * @param options {ITimeGeneratorOptions} the options for generation\n\t * @param dataRange {IRange} the data range\n\t * @param niceRange {IRange} the pretty range to display\n\t * @return {Number[]} ticks\n\t */\n\tfunction generateTicks(options, dataRange, niceRange) {\n\t\tvar ticks = [];\n\t\tif (options.maxTicks) {\n\t\t\tvar stepSize = options.stepSize;\n\t\t\tticks.push(options.min !== undefined ? options.min : niceRange.min);\n\t\t\tvar cur = moment(niceRange.min);\n\t\t\twhile (cur.add(stepSize, options.unit).valueOf() < niceRange.max) {\n\t\t\t\tticks.push(cur.valueOf());\n\t\t\t}\n\t\t\tvar realMax = options.max || niceRange.max;\n\t\t\tif (ticks[ticks.length - 1] !== realMax) {\n\t\t\t\tticks.push(realMax);\n\t\t\t}\n\t\t}\n\t\treturn ticks;\n\t}\n\n\t/**\n\t * @function Chart.Ticks.generators.time\n\t * @param options {ITimeGeneratorOptions} the options for generation\n\t * @param dataRange {IRange} the data range\n\t * @return {Number[]} ticks\n\t */\n\tChart.Ticks.generators.time = function(options, dataRange) {\n\t\tvar niceMin;\n\t\tvar niceMax;\n\t\tvar isoWeekday = options.isoWeekday;\n\t\tif (options.unit === 'week' && isoWeekday !== false) {\n\t\t\tniceMin = moment(dataRange.min).startOf('isoWeek').isoWeekday(isoWeekday).valueOf();\n\t\t\tniceMax = moment(dataRange.max).startOf('isoWeek').isoWeekday(isoWeekday);\n\t\t\tif (dataRange.max - niceMax > 0) {\n\t\t\t\tniceMax.add(1, 'week');\n\t\t\t}\n\t\t\tniceMax = niceMax.valueOf();\n\t\t} else {\n\t\t\tniceMin = moment(dataRange.min).startOf(options.unit).valueOf();\n\t\t\tniceMax = moment(dataRange.max).startOf(options.unit);\n\t\t\tif (dataRange.max - niceMax > 0) {\n\t\t\t\tniceMax.add(1, options.unit);\n\t\t\t}\n\t\t\tniceMax = niceMax.valueOf();\n\t\t}\n\t\treturn generateTicks(options, dataRange, {\n\t\t\tmin: niceMin,\n\t\t\tmax: niceMax\n\t\t});\n\t};\n\n\tvar TimeScale = Chart.Scale.extend({\n\t\tinitialize: function() {\n\t\t\tif (!moment) {\n\t\t\t\tthrow new Error('Chart.js - Moment.js could not be found! You must include it before Chart.js to use the time scale. Download at https://momentjs.com');\n\t\t\t}\n\n\t\t\tChart.Scale.prototype.initialize.call(this);\n\t\t},\n\t\tdetermineDataLimits: function() {\n\t\t\tvar me = this;\n\t\t\tvar timeOpts = me.options.time;\n\n\t\t\t// We store the data range as unix millisecond timestamps so dataMin and dataMax will always be integers.\n\t\t\tvar dataMin = Number.MAX_SAFE_INTEGER;\n\t\t\tvar dataMax = Number.MIN_SAFE_INTEGER;\n\n\t\t\tvar chartData = me.chart.data;\n\t\t\tvar parsedData = {\n\t\t\t\tlabels: [],\n\t\t\t\tdatasets: []\n\t\t\t};\n\n\t\t\tvar timestamp;\n\n\t\t\thelpers.each(chartData.labels, function(label, labelIndex) {\n\t\t\t\tvar labelMoment = parseTime(me, label);\n\n\t\t\t\tif (labelMoment.isValid()) {\n\t\t\t\t\t// We need to round the time\n\t\t\t\t\tif (timeOpts.round) {\n\t\t\t\t\t\tlabelMoment.startOf(timeOpts.round);\n\t\t\t\t\t}\n\n\t\t\t\t\ttimestamp = labelMoment.valueOf();\n\t\t\t\t\tdataMin = Math.min(timestamp, dataMin);\n\t\t\t\t\tdataMax = Math.max(timestamp, dataMax);\n\n\t\t\t\t\t// Store this value for later\n\t\t\t\t\tparsedData.labels[labelIndex] = timestamp;\n\t\t\t\t}\n\t\t\t});\n\n\t\t\thelpers.each(chartData.datasets, function(dataset, datasetIndex) {\n\t\t\t\tvar timestamps = [];\n\n\t\t\t\tif (typeof dataset.data[0] === 'object' && dataset.data[0] !== null && me.chart.isDatasetVisible(datasetIndex)) {\n\t\t\t\t\t// We have potential point data, so we need to parse this\n\t\t\t\t\thelpers.each(dataset.data, function(value, dataIndex) {\n\t\t\t\t\t\tvar dataMoment = parseTime(me, me.getRightValue(value));\n\n\t\t\t\t\t\tif (dataMoment.isValid()) {\n\t\t\t\t\t\t\tif (timeOpts.round) {\n\t\t\t\t\t\t\t\tdataMoment.startOf(timeOpts.round);\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\ttimestamp = dataMoment.valueOf();\n\t\t\t\t\t\t\tdataMin = Math.min(timestamp, dataMin);\n\t\t\t\t\t\t\tdataMax = Math.max(timestamp, dataMax);\n\t\t\t\t\t\t\ttimestamps[dataIndex] = timestamp;\n\t\t\t\t\t\t}\n\t\t\t\t\t});\n\t\t\t\t} else {\n\t\t\t\t\t// We have no x coordinates, so use the ones from the labels\n\t\t\t\t\ttimestamps = parsedData.labels.slice();\n\t\t\t\t}\n\n\t\t\t\tparsedData.datasets[datasetIndex] = timestamps;\n\t\t\t});\n\n\t\t\tme.dataMin = dataMin;\n\t\t\tme.dataMax = dataMax;\n\t\t\tme._parsedData = parsedData;\n\t\t},\n\t\tbuildTicks: function() {\n\t\t\tvar me = this;\n\t\t\tvar timeOpts = me.options.time;\n\n\t\t\tvar minTimestamp;\n\t\t\tvar maxTimestamp;\n\t\t\tvar dataMin = me.dataMin;\n\t\t\tvar dataMax = me.dataMax;\n\n\t\t\tif (timeOpts.min) {\n\t\t\t\tvar minMoment = parseTime(me, timeOpts.min);\n\t\t\t\tif (timeOpts.round) {\n\t\t\t\t\tminMoment.round(timeOpts.round);\n\t\t\t\t}\n\t\t\t\tminTimestamp = minMoment.valueOf();\n\t\t\t}\n\n\t\t\tif (timeOpts.max) {\n\t\t\t\tmaxTimestamp = parseTime(me, timeOpts.max).valueOf();\n\t\t\t}\n\n\t\t\tvar maxTicks = me.getLabelCapacity(minTimestamp || dataMin);\n\t\t\tvar unit = timeOpts.unit || determineUnit(timeOpts.minUnit, minTimestamp || dataMin, maxTimestamp || dataMax, maxTicks);\n\t\t\tme.displayFormat = timeOpts.displayFormats[unit];\n\n\t\t\tvar stepSize = timeOpts.stepSize || determineStepSize(minTimestamp || dataMin, maxTimestamp || dataMax, unit, maxTicks);\n\t\t\tme.ticks = Chart.Ticks.generators.time({\n\t\t\t\tmaxTicks: maxTicks,\n\t\t\t\tmin: minTimestamp,\n\t\t\t\tmax: maxTimestamp,\n\t\t\t\tstepSize: stepSize,\n\t\t\t\tunit: unit,\n\t\t\t\tisoWeekday: timeOpts.isoWeekday\n\t\t\t}, {\n\t\t\t\tmin: dataMin,\n\t\t\t\tmax: dataMax\n\t\t\t});\n\n\t\t\t// At this point, we need to update our max and min given the tick values since we have expanded the\n\t\t\t// range of the scale\n\t\t\tme.max = helpers.max(me.ticks);\n\t\t\tme.min = helpers.min(me.ticks);\n\t\t},\n\t\t// Get tooltip label\n\t\tgetLabelForIndex: function(index, datasetIndex) {\n\t\t\tvar me = this;\n\t\t\tvar label = me.chart.data.labels && index < me.chart.data.labels.length ? me.chart.data.labels[index] : '';\n\t\t\tvar value = me.chart.data.datasets[datasetIndex].data[index];\n\n\t\t\tif (value !== null && typeof value === 'object') {\n\t\t\t\tlabel = me.getRightValue(value);\n\t\t\t}\n\n\t\t\t// Format nicely\n\t\t\tif (me.options.time.tooltipFormat) {\n\t\t\t\tlabel = parseTime(me, label).format(me.options.time.tooltipFormat);\n\t\t\t}\n\n\t\t\treturn label;\n\t\t},\n\t\t// Function to format an individual tick mark\n\t\ttickFormatFunction: function(tick, index, ticks) {\n\t\t\tvar formattedTick = tick.format(this.displayFormat);\n\t\t\tvar tickOpts = this.options.ticks;\n\t\t\tvar callback = helpers.getValueOrDefault(tickOpts.callback, tickOpts.userCallback);\n\n\t\t\tif (callback) {\n\t\t\t\treturn callback(formattedTick, index, ticks);\n\t\t\t}\n\t\t\treturn formattedTick;\n\t\t},\n\t\tconvertTicksToLabels: function() {\n\t\t\tvar me = this;\n\t\t\tme.ticksAsTimestamps = me.ticks;\n\t\t\tme.ticks = me.ticks.map(function(tick) {\n\t\t\t\treturn moment(tick);\n\t\t\t}).map(me.tickFormatFunction, me);\n\t\t},\n\t\tgetPixelForOffset: function(offset) {\n\t\t\tvar me = this;\n\t\t\tvar epochWidth = me.max - me.min;\n\t\t\tvar decimal = epochWidth ? (offset - me.min) / epochWidth : 0;\n\n\t\t\tif (me.isHorizontal()) {\n\t\t\t\tvar valueOffset = (me.width * decimal);\n\t\t\t\treturn me.left + Math.round(valueOffset);\n\t\t\t}\n\n\t\t\tvar heightOffset = (me.height * decimal);\n\t\t\treturn me.top + Math.round(heightOffset);\n\t\t},\n\t\tgetPixelForValue: function(value, index, datasetIndex) {\n\t\t\tvar me = this;\n\t\t\tvar offset = null;\n\t\t\tif (index !== undefined && datasetIndex !== undefined) {\n\t\t\t\toffset = me._parsedData.datasets[datasetIndex][index];\n\t\t\t}\n\n\t\t\tif (offset === null) {\n\t\t\t\tif (!value || !value.isValid) {\n\t\t\t\t\t// not already a moment object\n\t\t\t\t\tvalue = parseTime(me, me.getRightValue(value));\n\t\t\t\t}\n\n\t\t\t\tif (value && value.isValid && value.isValid()) {\n\t\t\t\t\toffset = value.valueOf();\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (offset !== null) {\n\t\t\t\treturn me.getPixelForOffset(offset);\n\t\t\t}\n\t\t},\n\t\tgetPixelForTick: function(index) {\n\t\t\treturn this.getPixelForOffset(this.ticksAsTimestamps[index]);\n\t\t},\n\t\tgetValueForPixel: function(pixel) {\n\t\t\tvar me = this;\n\t\t\tvar innerDimension = me.isHorizontal() ? me.width : me.height;\n\t\t\tvar offset = (pixel - (me.isHorizontal() ? me.left : me.top)) / innerDimension;\n\t\t\treturn moment(me.min + (offset * (me.max - me.min)));\n\t\t},\n\t\t// Crude approximation of what the label width might be\n\t\tgetLabelWidth: function(label) {\n\t\t\tvar me = this;\n\t\t\tvar ticks = me.options.ticks;\n\n\t\t\tvar tickLabelWidth = me.ctx.measureText(label).width;\n\t\t\tvar cosRotation = Math.cos(helpers.toRadians(ticks.maxRotation));\n\t\t\tvar sinRotation = Math.sin(helpers.toRadians(ticks.maxRotation));\n\t\t\tvar tickFontSize = helpers.getValueOrDefault(ticks.fontSize, Chart.defaults.global.defaultFontSize);\n\t\t\treturn (tickLabelWidth * cosRotation) + (tickFontSize * sinRotation);\n\t\t},\n\t\tgetLabelCapacity: function(exampleTime) {\n\t\t\tvar me = this;\n\n\t\t\tme.displayFormat = me.options.time.displayFormats.millisecond;\t// Pick the longest format for guestimation\n\t\t\tvar exampleLabel = me.tickFormatFunction(moment(exampleTime), 0, []);\n\t\t\tvar tickLabelWidth = me.getLabelWidth(exampleLabel);\n\n\t\t\tvar innerWidth = me.isHorizontal() ? me.width : me.height;\n\t\t\tvar labelCapacity = innerWidth / tickLabelWidth;\n\t\t\treturn labelCapacity;\n\t\t}\n\t});\n\tChart.scaleService.registerScaleType('time', TimeScale, defaultConfig);\n\n};\n\n},{\"1\":1}]},{},[7])(7)\n});"
  },
  {
    "path": "app_backend/static/plugin/Chart.js-2.6.0/docs/README.md",
    "content": "# Chart.js\n\n[![Chart.js on Slack](https://img.shields.io/badge/slack-Chart.js-blue.svg)](https://chart-js-automation.herokuapp.com/)\n\n## Installation\n\nYou can download the latest version of Chart.js from the [GitHub releases](https://github.com/chartjs/Chart.js/releases/latest) or use a [Chart.js CDN](https://cdnjs.com/libraries/Chart.js). Detailed installation instructions can be found on the [installation](./getting-started/installation.md) page.\n\n## Creating a Chart\n\nIt's easy to get started with Chart.js. All that's required is the script included in your page along with a single `<canvas>` node to render the chart.\n\nIn this example, we create a bar chart for a single dataset and render that in our page. You can see all the ways to use Chart.js in the [usage documentation](./getting-started/usage.md)\n```html\n<canvas id=\"myChart\" width=\"400\" height=\"400\"></canvas>\n<script>\nvar ctx = document.getElementById(\"myChart\").getContext('2d');\nvar myChart = new Chart(ctx, {\n    type: 'bar',\n    data: {\n        labels: [\"Red\", \"Blue\", \"Yellow\", \"Green\", \"Purple\", \"Orange\"],\n        datasets: [{\n            label: '# of Votes',\n            data: [12, 19, 3, 5, 2, 3],\n            backgroundColor: [\n                'rgba(255, 99, 132, 0.2)',\n                'rgba(54, 162, 235, 0.2)',\n                'rgba(255, 206, 86, 0.2)',\n                'rgba(75, 192, 192, 0.2)',\n                'rgba(153, 102, 255, 0.2)',\n                'rgba(255, 159, 64, 0.2)'\n            ],\n            borderColor: [\n                'rgba(255,99,132,1)',\n                'rgba(54, 162, 235, 1)',\n                'rgba(255, 206, 86, 1)',\n                'rgba(75, 192, 192, 1)',\n                'rgba(153, 102, 255, 1)',\n                'rgba(255, 159, 64, 1)'\n            ],\n            borderWidth: 1\n        }]\n    },\n    options: {\n        scales: {\n            yAxes: [{\n                ticks: {\n                    beginAtZero:true\n                }\n            }]\n        }\n    }\n});\n</script>\n```\n\n## Contributing\n\nBefore submitting an issue or a pull request to the project, please take a moment to look over the [contributing guidelines](https://github.com/chartjs/Chart.js/blob/master/docs/developers/contributing.md) first.\n\nFor support using Chart.js, please post questions with the [`chartjs` tag on Stack Overflow](http://stackoverflow.com/questions/tagged/chartjs).\n\n## License\n\nChart.js is available under the [MIT license](http://opensource.org/licenses/MIT).\n"
  },
  {
    "path": "app_backend/static/plugin/Chart.js-2.6.0/docs/SUMMARY.md",
    "content": "# Summary\n\n* [Chart.js](README.md)\n* [Getting Started](getting-started/README.md)\n  * [Installation](getting-started/installation.md)\n  * [Integration](getting-started/integration.md)\n  * [Usage](getting-started/usage.md)\n* [General](general/README.md)\n  * [Responsive](general/responsive.md)\n  * [Interactions](general/interactions/README.md)\n    * [Events](general/interactions/events.md)\n    * [Modes](general/interactions/modes.md)\n  * [Colors](general/colors.md)\n  * [Fonts](general/fonts.md)\n* [Configuration](configuration/README.md)\n  * [Animations](configuration/animations.md)\n  * [Layout](configuration/layout.md)\n  * [Legend](configuration/legend.md)\n  * [Title](configuration/title.md)\n  * [Tooltip](configuration/tooltip.md)\n  * [Elements](configuration/elements.md)\n* [Charts](charts/README.md)\n  * [Line](charts/line.md)\n  * [Bar](charts/bar.md)\n  * [Radar](charts/radar.md)\n  * [Doughnut & Pie](charts/doughnut.md)\n  * [Polar Area](charts/polar.md)\n  * [Bubble](charts/bubble.md)\n  * [Scatter](charts/scatter.md)\n  * [Area](charts/area.md)\n  * [Mixed](charts/mixed.md)\n* [Axes](axes/README.md)\n  * [Cartesian](axes/cartesian/README.md)\n    * [Category](axes/cartesian/category.md)\n    * [Linear](axes/cartesian/linear.md)\n    * [Logarithmic](axes/cartesian/logarithmic.md)\n    * [Time](axes/cartesian/time.md) \n  * [Radial](axes/radial/README.md)\n    * [Linear](axes/radial/linear.md)\n  * [Labelling](axes/labelling.md)\n  * [Styling](axes/styling.md)\n* [Developers](developers/README.md)\n  * [Chart.js API](developers/api.md)\n  * [Updating Charts](developers/updates.md)\n  * [Plugins](developers/plugins.md)\n  * [New Charts](developers/charts.md)\n  * [New Axes](developers/axes.md)\n  * [Contributing](developers/contributing.md)\n* [Additional Notes](notes/README.md)\n  * [Comparison Table](notes/comparison.md)\n  * [Popular Extensions](notes/extensions.md)\n  * [License](notes/license.md)\n"
  },
  {
    "path": "app_backend/static/plugin/Chart.js-2.6.0/docs/axes/README.md",
    "content": "# Axes\n\nAxes are an integral part of a chart. They are used to determine how data maps to a pixel value on the chart. In a cartesian chart, there is 1 or more X axis and 1 or more Y axis to map points onto the 2 dimensional canvas. These axes are know as ['cartesian axes'](./cartesian/README.md#cartesian-axes).\n\nIn a radial chart, such as a radar chart or a polar area chart, there is a single axis that maps points in the angular and radial directions. These are known as ['radial axes'](./radial/README.md#radial-axes).\n\nScales in Chart.js >V2.0 are significantly more powerful, but also different than those of v1.0.\n* Multiple X & Y axes are supported.\n* A built-in label auto-skip feature detects would-be overlapping ticks and labels and removes every nth label to keep things displaying normally.\n* Scale titles are supported\n* New scale types can be extended without writing an entirely new chart type\n\n# Common Configuration\n\nThe following properties are common to all axes provided by Chart.js\n\n| Name | Type | Default | Description\n| ---- | ---- | ------- | -----------\n| `display` | `Boolean` | `true` | If set to `false` the axis is hidden from view. Overrides *gridLines.display*, *scaleLabel.display*, and *ticks.display*.\n| `callbacks` | `Object` | | Callback functions to hook into the axis lifecycle. [more...](#callbacks)\n| `weight` | `Number` | `0` | The weight used to sort the axis. Higher weights are further away from the chart area.\n\n## Callbacks\nThere are a number of config callbacks that can be used to change parameters in the scale at different points in the update process.\n\n| Name | Arguments | Description\n| ---- | --------- | -----------\n| `beforeUpdate` | `axis` | Callback called before the update process starts.\n| `beforeSetDimensions` | `axis` | Callback that runs before dimensions are set. \n| `afterSetDimensions` | `axis` | Callback that runs after dimensions are set.\n| `beforeDataLimits` | `axis` | Callback that runs before data limits are determined.\n| `afterDataLimits` | `axis` | Callback that runs after data limits are determined.\n| `beforeBuildTicks` | `axis` | Callback that runs before ticks are created.\n| `afterBuildTicks` | `axis` | Callback that runs after ticks are created. Useful for filtering ticks.\n| `beforeTickToLabelConversion` | `axis` | Callback that runs before ticks are converted into strings.\n| `afterTickToLabelConversion` | `axis` | Callback that runs after ticks are converted into strings. \n| `beforeCalculateTickRotation` | `axis` | Callback that runs before tick rotation is determined.\n| `afterCalculateTickRotation` | `axis` | Callback that runs after tick rotation is determined.\n| `beforeFit` | `axis` | Callback that runs before the scale fits to the canvas. \n| `afterFit` | `axis` | Callback that runs after the scale fits to the canvas. \n| `afterUpdate` | `axis` | Callback that runs at the end of the update process.\n\n## Updating Axis Defaults\n\nThe default configuration for a scale can be easily changed using the scale service. All you need to do is to pass in a partial configuration that will be merged with the current scale default configuration to form the new default.\n\nFor example, to set the minimum value of 0 for all linear scales, you would do the following. Any linear scales created after this time would now have a minimum of 0.\n\n```javascript\nChart.scaleService.updateScaleDefaults('linear', {\n    ticks: {\n        min: 0\n    }\n});\n```\n\n## Creating New Axes\nTo create a new axis, see the [developer docs](../developers/axes.md).\n"
  },
  {
    "path": "app_backend/static/plugin/Chart.js-2.6.0/docs/axes/cartesian/README.md",
    "content": "# Cartesian Axes\n\nAxes that follow a cartesian grid are known as 'Cartesian Axes'. Cartesian axes are used for line, bar, and bubble charts. Four cartesian axes are included in Chart.js by default.\n\n* [linear](./linear.md#linear-cartesian-axis)\n* [logarithmic](./logarithmic.md#logarithmic-cartesian-axis)\n* [category](./category.md#category-cartesian-axis)\n* [time](./time.md#time-cartesian-axis)\n\n# Common Configuration\n\nAll of the included cartesian axes support a number of common options.\n\n| Name | Type | Default | Description\n| -----| ---- | --------| -----------\n| `type` | `String` | | Type of scale being employed. Custom scales can be created and registered with a string key. This allows changing the type of an axis for a chart.\n| `position` | `String` | | Position of the axis in the chart. Possible values are: `'top'`, `'left'`, `'bottom'`, `'right'`\n| `id` | `String` | | The ID is used to link datasets and scale axes together. [more...](#axis-id)\n| `gridLines` | `Object` | | Grid line configuration. [more...](../styling.md#grid-line-configuration)\n| `scaleLabel` | `Object` | | Scale title configuration. [more...](../labelling.md#scale-title-configuration)\n| `ticks` | `Object` | | Tick configuration. [more...](#tick-configuration)\n\n## Tick Configuration\nThe following options are common to all cartesian axes but do not apply to other axes.\n\n| Name | Type | Default | Description\n| -----| ---- | --------| -----------\n| `autoSkip` | `Boolean` | `true` | If true, automatically calculates how many labels that can be shown and hides labels accordingly. Turn it off to show all labels no matter what\n| `autoSkipPadding` | `Number` | `0` | Padding between the ticks on the horizontal axis when `autoSkip` is enabled. *Note: Only applicable to horizontal scales.*\n| `labelOffset` | `Number` | `0` | Distance in pixels to offset the label from the centre point of the tick (in the y direction for the x axis, and the x direction for the y axis). *Note: this can cause labels at the edges to be cropped by the edge of the canvas*\n| `maxRotation` | `Number` | `90` | Maximum rotation for tick labels when rotating to condense labels. Note: Rotation doesn't occur until necessary. *Note: Only applicable to horizontal scales.*\n| `minRotation` | `Number` | `0` | Minimum rotation for tick labels. *Note: Only applicable to horizontal scales.*\n| `mirror` | `Boolean` | `false` | Flips tick labels around axis, displaying the labels inside the chart instead of outside. *Note: Only applicable to vertical scales.*\n| `padding` | `Number` | `10` | Padding between the tick label and the axis. *Note: Only applicable to horizontal scales.*\n\n## Axis ID\nThe properties `dataset.xAxisID` or `dataset.yAxisID` have to match the scale properties `scales.xAxes.id` or `scales.yAxes.id`. This is especially needed if multi-axes charts are used.\n\n```javascript\nvar myChart = new Chart(ctx, {\n    type: 'line',\n    data: {\n        datasets: [{\n            // This dataset appears on the first axis\n            yAxisID: 'first-y-axis'\n        }, {\n            // This dataset appears on the second axis\n            yAxisID: 'second-y-axis'\n        }]\n    },\n    options: {\n        scales: {\n            yAxes: [{\n                id: 'first-y-axis',\n                type: 'linear'\n            }, {\n                id: 'second-y-axis',\n                type: 'linear'\n            }]\n        }\n    }\n});\n```\n\n# Creating Multiple Axes\n\nWith cartesian axes, it is possible to create multiple X and Y axes. To do so, you can add multiple configuration objects to the `xAxes` and `yAxes` properties. When adding new axes, it is important to ensure that you specify the type of the new axes as default types are **not** used in this case.\n\nIn the example below, we are creating two Y axes. We then use the `yAxisID` property to map the datasets to their correct axes.\n\n```javascript\nvar myChart = new Chart(ctx, {\n    type: 'line',\n    data: {\n        datasets: [{\n            data: [20, 50, 100, 75, 25, 0],\n            label: 'Left dataset'\n\n            // This binds the dataset to the left y axis\n            yAxisID: 'left-y-axis'\n        }, {\n            data: [0.1, 0.5, 1.0, 2.0, 1.5, 0]\n            label: 'Right dataset'\n\n            // This binds the dataset to the right y axis\n            yAxisID: 'right-y-axis',\n        }],\n        labels: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun']\n    },\n    options: {\n        scales: {\n            yAxes: [{\n                id: 'left-y-axis',\n                type: 'linear',\n                position: 'left'\n            }, {\n                id: 'right-y-axis',\n                type: 'linear',\n                position: 'right'\n            }]\n        }\n    }\n});\n```"
  },
  {
    "path": "app_backend/static/plugin/Chart.js-2.6.0/docs/axes/cartesian/category.md",
    "content": "# Category Cartesian Axis\n\nThe category scale will be familiar to those who have used v1.0. Labels are drawn from one of the label arrays included in the chart data. If only `data.labels` is defined, this will be used. If `data.xLabels` is defined and the axis is horizontal, this will be used. Similarly, if `data.yLabels` is defined and the axis is vertical, this property will be used. Using both `xLabels` and `yLabels` together can create a chart that uses strings for both the X and Y axes.\n\n## Tick Configuration Options\n\nThe category scale provides the following options for configuring tick marks. They are nested in the `ticks` sub object. These options extend the [common tick configuration](README.md#tick-configuration).\n\n| Name | Type | Default | Description\n| -----| ---- | --------| -----------\n| `min` | `String` | | The minimum item to display. [more...](#min-max-configuration)\n| `max` | `String` | | The maximum item to display. [more...](#min-max-configuration)\n\n## Min Max Configuration\nFor both the `min` and `max` properties, the value must be in the `labels` array. In the example below, the x axis would only display \"March\" through \"June\".\n\n```javascript\nlet chart = new Chart(ctx, {\n    type: 'line',\n    data: {\n        datasets: [{\n            data: [10, 20, 30, 40, 50, 60]\n        }],\n        labels: ['January', 'February', 'March', 'April', 'May', 'June'],\n    },\n    options: {\n        scales: {\n            xAxes: [{\n                ticks: {\n                    min: 'March'\n                }\n            }]\n        }\n    }\n});\n```\n"
  },
  {
    "path": "app_backend/static/plugin/Chart.js-2.6.0/docs/axes/cartesian/linear.md",
    "content": "# Linear Cartesian Axis\n\nThe linear scale is use to chart numerical data. It can be placed on either the x or y axis. The scatter chart type automatically configures a line chart to use one of these scales for the x axis. As the name suggests, linear interpolation is used to determine where a value lies on the axis.\n\n## Tick Configuration Options\n\nThe following options are provided by the linear scale. They are all located in the `ticks` sub options. These options extend the [common tick configuration](README.md#tick-configuration).\n\n| Name | Type | Default | Description\n| -----| ---- | --------| -----------\n| `beginAtZero` | `Boolean` | | if true, scale will include 0 if it is not already included.\n| `min` | `Number` | | User defined minimum number for the scale, overrides minimum value from data. [more...](#axis-range-settings)\n| `max` | `Number` | | User defined maximum number for the scale, overrides maximum value from data. [more...](#axis-range-settings)\n| `maxTicksLimit` | `Number` | `11` | Maximum number of ticks and gridlines to show.\n| `stepSize` | `Number` | | User defined fixed step size for the scale. [more...](#step-size)\n| `suggestedMax` | `Number` | | Adjustment used when calculating the maximum data value. [more...](#axis-range-settings)\n| `suggestedMin` | `Number` | | Adjustment used when calculating the minimum data value. [more...](#axis-range-settings)\n\n## Axis Range Settings\n\nGiven the number of axis range settings, it is important to understand how they all interact with each other.\n\nThe `suggestedMax` and `suggestedMin` settings only change the data values that are used to scale the axis. These are useful for extending the range of the axis while maintaing the auto fit behaviour.\n\n```javascript\nlet minDataValue = Math.min(mostNegativeValue, options.ticks.suggestedMin);\nlet maxDataValue = Math.max(mostPositiveValue, options.ticks.suggestedMax);\n```\n\nIn this example, the largest positive value is 50, but the data maximum is expanded out to 100. However, because the lowest data value is below the `suggestedMin` setting, it is ignored.\n\n```javascript\nlet chart = new Chart(ctx, {\n    type: 'line',\n    data: {\n        datasets: [{\n            label: 'First dataset',\n            data: [0, 20, 40, 50]\n        }],\n        labels: ['January', 'February', 'March', 'April']\n    },\n    options: {\n        scales: {\n            yAxes: [{\n                ticks: {\n                    suggestedMin: 50\n                    suggestedMax: 100\n                }\n            }]\n        }\n    }\n});\n```\n\nIn contrast to the `suggested*` settings, the `min` and `max` settings set explicit ends to the axes. When these are set, some data points may not be visible.\n\n## Step Size\n If set, the scale ticks will be enumerated by multiple of stepSize, having one tick per increment. If not set, the ticks are labeled automatically using the nice numbers algorithm.\n\nThis example sets up a chart with a y axis that creates ticks at `0, 0.5, 1, 1.5, 2, 2.5, 3, 3.5, 4, 4.5, 5`.\n\n```javascript\nlet options = {\n    scales: {\n        yAxes: [{\n            ticks: {\n                max: 5,\n                min: 0,\n                stepSize: 0.5\n            }\n        }]\n    }\n};\n```"
  },
  {
    "path": "app_backend/static/plugin/Chart.js-2.6.0/docs/axes/cartesian/logarithmic.md",
    "content": "# Logarithmic Cartesian Axis\n\nThe logarithmic scale is use to chart numerical data. It can be placed on either the x or y axis. As the name suggests, logarithmic interpolation is used to determine where a value lies on the axis.\n\n## Tick Configuration Options\n\nThe following options are provided by the logarithmic scale. They are all located in the `ticks` sub options. These options extend the [common tick configuration](README.md#tick-configuration).\n\n| Name | Type | Default | Description\n| -----| ---- | --------| -----------\n| `min` | `Number` | | User defined minimum number for the scale, overrides minimum value from data.\n| `max` | `Number` | | User defined maximum number for the scale, overrides maximum value from data."
  },
  {
    "path": "app_backend/static/plugin/Chart.js-2.6.0/docs/axes/cartesian/time.md",
    "content": "# Time Cartesian Axis\n\nThe time scale is used to display times and dates. When building its ticks, it will automatically calculate the most comfortable unit base on the size of the scale.\n\n## Configuration Options\n\nThe following options are provided by the time scale. They are all located in the `time` sub options. These options extend the [common tick configuration](README.md#tick-configuration).\n\n| Name | Type | Default | Description\n| -----| ---- | --------| -----------\n| `displayFormats` | `Object` | | Sets how different time units are displayed. [more...](#display-formats)\n| `isoWeekday` | `Boolean` | `false` | If true and the unit is set to 'week', iso weekdays will be used.\n| `max` | [Time](#date-formats) | | If defined, this will override the data maximum\n| `min` | [Time](#date-formats) | | If defined, this will override the data minimum\n| `parser` | `String` or `Function` | | Custom parser for dates. [more...](#parser)\n| `round` | `String` | `false` | If defined, dates will be rounded to the start of this unit. See [Time Units](#scales-time-units) below for the allowed units.\n| `tooltipFormat` | `String` | | The moment js format string to use for the tooltip.\n| `unit` | `String` | `false` | If defined, will force the unit to be a certain type. See [Time Units](#scales-time-units) section below for details.\n| `unitStepSize` | `Number` | `1` | The number of units between grid lines.\n| `minUnit` | `String` | `millisecond` | The minimum display format to be used for a time unit.\n\n## Date Formats\n\nWhen providing data for the time scale, Chart.js supports all of the formats that Moment.js accepts. See [Moment.js docs](http://momentjs.com/docs/#/parsing/) for details.\n\n## Time Units\n\nThe following time measurements are supported. The names can be passed as strings to the `time.unit` config option to force a certain unit.\n\n* millisecond\n* second\n* minute\n* hour\n* day\n* week\n* month\n* quarter\n* year\n\nFor example, to create a chart with a time scale that always displayed units per month, the following config could be used.\n\n```javascript\nvar chart = new Chart(ctx, {\n    type: 'line',\n    data: data,\n    options: {\n        scales: {\n            xAxes: [{\n                time: {\n                    unit: 'month'\n                }\n            }]\n        }\n    }\n})\n```\n\n## Display Formats\nThe following display formats are used to configure how different time units are formed into strings for the axis tick marks. See [moment.js](http://momentjs.com/docs/#/displaying/format/) for the allowable format strings.\n\nName | Default\n--- | ---\nmillisecond | 'SSS [ms]'\nsecond | 'h:mm:ss a'\nminute | 'h:mm:ss a'\nhour | 'MMM D, hA'\nday | 'll'\nweek | 'll'\nmonth | 'MMM YYYY'\nquarter | '[Q]Q - YYYY'\nyear | 'YYYY'\n\nFor example, to set the display format for the 'quarter' unit to show the month and year, the following config would be passed to the chart constructor.\n\n```javascript\nvar chart = new Chart(ctx, {\n    type: 'line',\n    data: data,\n    options: {\n        scales: {\n            xAxes: [{\n                type: 'time',\n                time: {\n                    displayFormats: {\n                        quarter: 'MMM YYYY'\n                    }\n                }\n            }]\n        }\n    }\n})\n```\n\n## Parser\nIf this property is defined as a string, it is interpreted as a custom format to be used by moment to parse the date. \n\nIf this is a function, it must return a moment.js object given the appropriate data value."
  },
  {
    "path": "app_backend/static/plugin/Chart.js-2.6.0/docs/axes/labelling.md",
    "content": "# Labeling Axes\n\nWhen creating a chart, you want to tell the viewer what data they are viewing. To do this, you need to label the axis.\n\n## Scale Title Configuration\n\nThe scale label configuration is nested under the scale configuration in the `scaleLabel` key. It defines options for the scale title. Note that this only applies to cartesian axes.\n\n| Name | Type | Default | Description\n| -----| ---- | --------| -----------\n| `display` | `Boolean` | `false` | If true, display the axis title.\n| `labelString` | `String` | `''` | The text for the title. (i.e. \"# of People\" or \"Respone Choices\").\n| `fontColor` | Color | `'#666'` | Font color for scale title.\n| `fontFamily` | `String` | `\"'Helvetica Neue', 'Helvetica', 'Arial', sans-serif\"` | Font family for the scale title, follows CSS font-family options.\n| `fontSize` | `Number` | `12` | Font size for scale title.\n| `fontStyle` | `String` | `'normal'` | Font style for the scale title, follows CSS font-style options (i.e. normal, italic, oblique, initial, inherit).\n\n## Creating Custom Tick Formats\n\nIt is also common to want to change the tick marks to include information about the data type. For example, adding a dollar sign ('$'). To do this, you need to override the `ticks.callback` method in the axis configuration.\nIn the following example, every label of the Y axis would be displayed with a dollar sign at the front..\n\nIf the callback returns `null` or `undefined` the associated grid line will be hidden.\n\n```javascript\nvar chart = new Chart(ctx, {\n    type: 'line',\n    data: data,\n    options: {\n        scales: {\n            yAxes: [{\n                ticks: {\n                    // Include a dollar sign in the ticks\n                    callback: function(value, index, values) {\n                        return '$' + value;\n                    }\n                }\n            }]\n        }\n    }\n});\n```"
  },
  {
    "path": "app_backend/static/plugin/Chart.js-2.6.0/docs/axes/radial/README.md",
    "content": "# Radial Axes\n\nRadial axes are used specifically for the radar and polar area chart types. These axes overlay the chart area, rather than being positioned on one of the edges. One radial axis is included by default in Chart.js.\n\n* [linear](./linear.md#linear-radial-axis)"
  },
  {
    "path": "app_backend/static/plugin/Chart.js-2.6.0/docs/axes/radial/linear.md",
    "content": "# Linear Radial Axis\n\nThe linear scale is use to chart numerical data. As the name suggests, linear interpolation is used to determine where a value lies in relation the center of the axis.\n\nThe following additional configuration options are provided by the radial linear scale.\n\n## Configuration Options\n\nThe axis has configuration properties for ticks, angle lines (line that appear in a radar chart outward from the center), pointLabels (labels around the edge in a radar chart). The following sections define each of the properties in those sections.\n\n| Name | Type | Description\n| ---- | ---- | -----------\n| `angleLines` | `Object` | Angle line configuration. [more...](#angle-line-options)\n| `gridLines` | `Object` | Grid line configuration. [more...](../styling.md#grid-line-configuration)\n| `pointLabels` | `Object` | Point label configuration. [more...](#point-label-options)\n| `ticks` | `Object` | Tick configuration. [more...](#tick-options)\n\n## Tick Options\nThe following options are provided by the linear scale. They are all located in the `ticks` sub options. The [common tick configuration](../styling.md#tick-configuration) options are supported by this axis.\n\n| Name | Type | Default | Description\n| -----| ---- | --------| -----------\n| `backdropColor` | Color | `'rgba(255, 255, 255, 0.75)'` | Color of label backdrops\n| `backdropPaddingX` | `Number` | `2` | Horizontal padding of label backdrop.\n| `backdropPaddingY` | `Number` | `2` | Vertical padding of label backdrop.\n| `beginAtZero` | `Boolean` | `false` | if true, scale will include 0 if it is not already included.\n| `min` | `Number` | | User defined minimum number for the scale, overrides minimum value from data. [more...](#axis-range-settings)\n| `max` | `Number` | | User defined maximum number for the scale, overrides maximum value from data. [more...](#axis-range-settings)\n| `maxTicksLimit` | `Number` | `11` | Maximum number of ticks and gridlines to show.\n| `stepSize` | `Number` | | User defined fixed step size for the scale. [more...](#step-size)\n| `suggestedMax` | `Number` | | Adjustment used when calculating the maximum data value. [more...](#axis-range-settings)\n| `suggestedMin` | `Number` | | Adjustment used when calculating the minimum data value. [more...](#axis-range-settings)\n| `showLabelBackdrop` | `Boolean` | `true` | If true, draw a background behind the tick labels\n\n## Axis Range Settings\n\nGiven the number of axis range settings, it is important to understand how they all interact with each other.\n\nThe `suggestedMax` and `suggestedMin` settings only change the data values that are used to scale the axis. These are useful for extending the range of the axis while maintaing the auto fit behaviour.\n\n```javascript\nlet minDataValue = Math.min(mostNegativeValue, options.ticks.suggestedMin);\nlet maxDataValue = Math.max(mostPositiveValue, options.ticks.suggestedMax);\n```\n\nIn this example, the largest positive value is 50, but the data maximum is expanded out to 100. However, because the lowest data value is below the `suggestedMin` setting, it is ignored.\n\n```javascript\nlet chart = new Chart(ctx, {\n    type: 'radar',\n    data: {\n        datasets: [{\n            label: 'First dataset',\n            data: [0, 20, 40, 50]\n        }],\n        labels: ['January', 'February', 'March', 'April']\n    },\n    options: {\n        scale: {\n            ticks: {\n                suggestedMin: 50\n                suggestedMax: 100\n            }\n        }\n    }\n});\n```\n\nIn contrast to the `suggested*` settings, the `min` and `max` settings set explicit ends to the axes. When these are set, some data points may not be visible.\n\n## Step Size\n If set, the scale ticks will be enumerated by multiple of stepSize, having one tick per increment. If not set, the ticks are labeled automatically using the nice numbers algorithm.\n\nThis example sets up a chart with a y axis that creates ticks at `0, 0.5, 1, 1.5, 2, 2.5, 3, 3.5, 4, 4.5, 5`.\n\n```javascript\nlet options = {\n    scales: {\n        yAxes: [{\n            ticks: {\n                max: 5,\n                min: 0,\n                stepSize: 0.5\n            }\n        }]\n    }\n};\n```\n\n## Angle Line Options\n\nThe following options are used to configure angled lines that radiate from the center of the chart to the point labels. They can be found in the `angleLines` sub options. Note that these options only apply if `angleLines.display` is true.\n\n| Name | Type | Default | Description\n| -----| ---- | --------| -----------\n| `display` | `Boolean` | `true` | if true, angle lines are shown\n| `color` | Color | `rgba(0, 0, 0, 0.1)` | Color of angled lines\n| `lineWidth` | `Number` | `1` | Width of angled lines\n\n## Point Label Options\n\nThe following options are used to configure the point labels that are shown on the perimeter of the scale. They can be found in the `pointLabels` sub options. Note that these options only apply if `pointLabels.display` is true.\n\n| Name | Type | Default | Description\n| -----| ---- | --------| -----------\n| `callback` | `Function` | | Callback function to transform data labels to point labels. The default implementation simply returns the current string.\n| `fontColor` | Color | `'#666'` | Font color for point labels.\n| `fontFamily` | `String` | `\"'Helvetica Neue', 'Helvetica', 'Arial', sans-serif\"` | Font family to use when rendering labels.\n| `fontSize` | `Number` | 10 | font size in pixels\n| `fontStyle` | `String` | `'normal'` | Font style to use when rendering point labels."
  },
  {
    "path": "app_backend/static/plugin/Chart.js-2.6.0/docs/axes/styling.md",
    "content": "# Styling\n\nThere are a number of options to allow styling an axis. There are settings to control [grid lines](#grid-line-configuration) and [ticks](#tick-configuration).\n\n## Grid Line Configuration\n\nThe grid line configuration is nested under the scale configuration in the `gridLines` key. It defines options for the grid lines that run perpendicular to the axis.\n\n| Name | Type | Default | Description\n| -----| ---- | --------| -----------\n| `display` | `Boolean` | `true` | If false, do not display grid lines for this axis.\n| `color` | Color or Color[] | `'rgba(0, 0, 0, 0.1)'` | The color of the grid lines. If specified as an array, the first color applies to the first grid line, the second to the second grid line and so on.\n| `borderDash` | `Number[]` | `[]` | Length and spacing of dashes on grid lines. See [MDN](https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/setLineDash)\n| `borderDashOffset` | `Number` | `0` | Offset for line dashes. See [MDN](https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/lineDashOffset)\n| `lineWidth` | `Number or Number[]` | `1` | Stroke width of grid lines.\n| `drawBorder` | `Boolean` | `true` | If true, draw border at the edge between the axis and the chart area.\n| `drawOnChartArea` | `Boolean` | `true` | If true, draw lines on the chart area inside the axis lines. This is useful when there are multiple axes and you need to control which grid lines are drawn.\n| `drawTicks` | `Boolean` | `true` | If true, draw lines beside the ticks in the axis area beside the chart.\n| `tickMarkLength` | `Number` | `10` | Length in pixels that the grid lines will draw into the axis area.\n| `zeroLineWidth` | `Number` | `1` | Stroke width of the grid line for the first index (index 0).\n| `zeroLineColor` | Color | `'rgba(0, 0, 0, 0.25)'` | Stroke color of the grid line for the first index (index 0).\n| `zeroLineBorderDash` | `Number[]` | `[]` | Length and spacing of dashes of the grid line for the first index (index 0). See [MDN](https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/setLineDash)\n| `zeroLineBorderDashOffset` | `Number` | `0` | Offset for line dashes of the grid line for the first index (index 0). See [MDN](https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/lineDashOffset)\n| `offsetGridLines` | `Boolean` | `false` | If true, labels are shifted to be between grid lines. This is used in the bar chart and should not generally be used.\n\n## Tick Configuration\nThe tick configuration is nested under the scale configuration in the `ticks` key. It defines options for the tick marks that are generated by the axis.\n\n| Name | Type | Default | Description\n| -----| ---- | --------| -----------\n| `callback` | `Function` | | Returns the string representation of the tick value as it should be displayed on the chart. See [callback](../axes/labelling.md#creating-custom-tick-formats).\n| `display` | `Boolean` | `true` | If true, show tick marks\n| `fontColor` | Color | `'#666'` | Font color for tick labels.\n| `fontFamily` | `String` | `\"'Helvetica Neue', 'Helvetica', 'Arial', sans-serif\"` | Font family for the tick labels, follows CSS font-family options.\n| `fontSize` | `Number` | `12` | Font size for the tick labels.\n| `fontStyle` | `String` | `'normal'` | Font style for the tick labels, follows CSS font-style options (i.e. normal, italic, oblique, initial, inherit).\n| `reverse` | `Boolean` | `false` | Reverses order of tick labels.\n"
  },
  {
    "path": "app_backend/static/plugin/Chart.js-2.6.0/docs/charts/README.md",
    "content": "# Charts\n\nChart.js comes with built-in chart types:\n* [line](./line.md)\n* [bar](./bar.md)\n* [radar](./radar.md)\n* [polar area](./polar.md)\n* [doughnut and pie](./doughnut.md)\n* [bubble](./bubble.md)\n\n[Area charts](area.md) can be built from a line or radar chart using the dataset `fill` option.\n\nTo create a new chart type, see the [developer notes](../developers/charts.md#new-charts)\n"
  },
  {
    "path": "app_backend/static/plugin/Chart.js-2.6.0/docs/charts/area.md",
    "content": "# Area Charts\n\nBoth [line](line.md) and [radar](radar.md) charts support a `fill` option on the dataset object which can be used to create area between two datasets or a dataset and a boundary, i.e. the scale `origin`, `start` or `end` (see [filling modes](#filling-modes)).\n\n> **Note:** this feature is implemented by the [`filler` plugin](https://github.com/chartjs/Chart.js/blob/master/src/plugins/plugin.filler.js).\n\n## Filling modes\n\n| Mode | Type | Values |\n| :--- | :--- | :--- |\n| Absolute dataset index <sup>1</sup> | `Number` | `1`, `2`, `3`, ... |\n| Relative dataset index <sup>1</sup> | `String` | `'-1'`, `'-2'`, `'+1'`, ... |\n| Boundary <sup>2</sup> | `String` | `'start'`, `'end'`, `'origin'` |\n| Disabled <sup>3</sup> | `Boolean` | `false` |\n\n> <sup>1</sup> dataset filling modes have been introduced in version 2.6.0<br>\n> <sup>2</sup> prior version 2.6.0, boundary values was `'zero'`, `'top'`, `'bottom'` (deprecated)<br>\n> <sup>3</sup> for backward compatibility, `fill: true` (default) is equivalent to `fill: 'origin'`<br>\n\n**Example**\n```javascript\nnew Chart(ctx, {\n    data: {\n        datasets: [\n            {fill: 'origin'},      // 0: fill to 'origin'\n            {fill: '+2'},          // 1: fill to dataset 3\n            {fill: 1},             // 2: fill to dataset 1\n            {fill: false},         // 3: no fill\n            {fill: '-2'}           // 4: fill to dataset 2\n        ]\n    }\n})\n```\n\n## Configuration\n| Option | Type | Default | Description |\n| :--- | :--- | :--- | :--- |\n| [`plugins.filler.propagate`](#propagate) | `Boolean` | `true` | Fill propagation when target is hidden\n\n### propagate\nBoolean (default: `true`)\n\nIf `true`, the fill area will be recursively extended to the visible target defined by the `fill` value of hidden dataset targets:\n\n**Example**\n```javascript\nnew Chart(ctx, {\n    data: {\n        datasets: [\n            {fill: 'origin'},   // 0: fill to 'origin'\n            {fill: '-1'},       // 1: fill to dataset 0\n            {fill: 1},          // 2: fill to dataset 1\n            {fill: false},      // 3: no fill\n            {fill: '-2'}        // 4: fill to dataset 2\n        ]\n    },\n    options: {\n        plugins: {\n            filler: {\n                propagate: true\n            }\n        }\n    }\n})\n```\n\n`propagate: true`:\n- if dataset 2 is hidden, dataset 4 will fill to dataset 1\n- if dataset 2 and 1 are hidden, dataset 4 will fill to `'origin'`\n\n`propagate: false`:\n- if dataset 2 and/or 4 are hidden, dataset 4 will not be filled\n"
  },
  {
    "path": "app_backend/static/plugin/Chart.js-2.6.0/docs/charts/bar.md",
    "content": "# Bar\nA bar chart provides a way of showing data values represented as vertical bars. It is sometimes used to show trend data, and the comparison of multiple data sets side by side.\n\n{% chartjs %}\n{\n    \"type\": \"bar\",\n    \"data\": {\n        \"labels\": [\n            \"January\", \n            \"February\", \n            \"March\", \n            \"April\", \n            \"May\", \n            \"June\", \n            \"July\"\n        ],\n        \"datasets\": [{\n            \"label\": \"My First Dataset\",\n            \"data\": [65, 59, 80, 81, 56, 55, 40],\n            \"fill\": false,\n            \"backgroundColor\": [\n                \"rgba(255, 99, 132, 0.2)\",\n                \"rgba(255, 159, 64, 0.2)\",\n                \"rgba(255, 205, 86, 0.2)\",\n                \"rgba(75, 192, 192, 0.2)\",\n                \"rgba(54, 162, 235, 0.2)\",\n                \"rgba(153, 102, 255, 0.2)\",\n                \"rgba(201, 203, 207, 0.2)\"\n            ],\n            \"borderColor\": [\n                \"rgb(255, 99, 132)\",\n                \"rgb(255, 159, 64)\",\n                \"rgb(255, 205, 86)\",\n                \"rgb(75, 192, 192)\",\n                \"rgb(54, 162, 235)\",\n                \"rgb(153, 102, 255)\",\n                \"rgb(201, 203, 207)\"\n            ],\n            \"borderWidth\": 1\n        }]\n    },\n    \"options\": {\n        \"scales\": {\n            \"yAxes\": [{\n                \"ticks\": {\n                    \"beginAtZero\": true\n                }\n            }]\n        }\n    }\n}\n{% endchartjs %}\n\n## Example Usage\n```javascript\nvar myBarChart = new Chart(ctx, {\n    type: 'bar',\n    data: data,\n    options: options\n});\n```\n\n## Dataset Properties\nThe bar chart allows a number of properties to be specified for each dataset. These are used to set display properties for a specific dataset. For example, the colour of the bars is generally set this way.\n\nSome properties can be specified as an array. If these are set to an array value, the first value applies to the first bar, the second value to the second bar, and so on.\n\n| Name | Type | Description\n| ---- | ---- | -----------\n| `label` | `String` | The label for the dataset which appears in the legend and tooltips.\n| `xAxisID` | `String` | The ID of the x axis to plot this dataset on. If not specified, this defaults to the ID of the first found x axis\n| `yAxisID` | `String` | The ID of the y axis to plot this dataset on. If not specified, this defaults to the ID of the first found y axis.\n| `backgroundColor` | `Color/Color[]` | The fill color of the bar. See [Colors](../general/colors.md#colors)\n| `borderColor` | `Color/Color[]` | The color of the bar border. See [Colors](../general/colors.md#colors)\n| `borderWidth` | `Number/Number[]` | The stroke width of the bar in pixels.\n| `borderSkipped` | `String` | Which edge to skip drawing the border for. [more...](#borderSkipped)\n| `hoverBackgroundColor` | `Color/Color[]` | The fill colour of the bars when hovered.\n| `hoverBorderColor` | `Color/Color[]` | The stroke colour of the bars when hovered.\n| `hoverBorderWidth` | `Number/Number[]` | The stroke width of the bars when hovered.\n\n### borderSkipped\nThis setting is used to avoid drawing the bar stroke at the base of the fill. In general, this does not need to be changed except when creating chart types that derive from a bar chart.\n\nOptions are:\n* 'bottom'\n* 'left'\n* 'top'\n* 'right'\n\n## Configuration Options\n\nThe bar chart defines the following configuration options. These options are merged with the global chart configuration options, `Chart.defaults.global`, to form the options passed to the chart.\n\n| Name | Type | Default | Description\n| ---- | ---- | ------- | -----------\n| `barPercentage` | `Number` | `0.9` | Percent (0-1) of the available width each bar should be within the category percentage. 1.0 will take the whole category width and put the bars right next to each other. [more...](#bar-chart-barpercentage-vs-categorypercentage)\n| `categoryPercentage` | `Number` | `0.8` | Percent (0-1) of the available width (the space between the gridlines for small datasets) for each data-point to use for the bars. [more...](#bar-chart-barpercentage-vs-categorypercentage)\n| `barThickness` | `Number` | | Manually set width of each bar in pixels. If not set, the bars are sized automatically using `barPercentage` and `categoryPercentage`;\n| `maxBarThickness` | `Number` | | Set this to ensure that the automatically sized bars are not sized thicker than this. Only works if barThickness is not set (automatic sizing is enabled).\n| `gridLines.offsetGridLines` | `Boolean` | `true` | If true, the bars for a particular data point fall between the grid lines. If false, the grid line will go right down the middle of the bars. [more...](#offsetGridLines)\n\n### offsetGridLines\nIf true, the bars for a particular data point fall between the grid lines. If false, the grid line will go right down the middle of the bars. It is unlikely that this will ever need to be changed in practice. It exists more as a way to reuse the axis code by configuring the existing axis slightly differently.\n\nThis setting applies to the axis configuration for a bar chart. If axes are added to the chart, this setting will need to be set for each new axis.\n\n```javascript\noptions = {\n    scales: {\n        xAxes: [{\n            gridLines: {\n                offsetGridLines: true\n            }\n        }]\n    }\n}\n```\n\n## Default Options\n\nIt is common to want to apply a configuration setting to all created bar charts. The global bar chart settings are stored in `Chart.defaults.bar`. Changing the global options only affects charts created after the change. Existing charts are not changed.\n\n## barPercentage vs categoryPercentage\n\nThe following shows the relationship between the bar percentage option and the category percentage option.\n\n```text\n// categoryPercentage: 1.0\n// barPercentage: 1.0\nBar:        | 1.0 | 1.0 |\nCategory:   |    1.0    |\nSample:     |===========|\n\n// categoryPercentage: 1.0\n// barPercentage: 0.5\nBar:          |.5|  |.5|\nCategory:  |      1.0     |\nSample:    |==============|\n\n// categoryPercentage: 0.5\n// barPercentage: 1.0\nBar:            |1.||1.|\nCategory:       |  .5  |\nSample:     |==============|\n```\n\n## Data Structure\n\nThe `data` property of a dataset for a bar chart is specified as a an array of numbers. Each point in the data array corresponds to the label at the same index on the x axis.\n\n```javascript\ndata: [20, 10]\n```\n\n# Stacked Bar Chart\n\nBar charts can be configured into stacked bar charts by changing the settings on the X and Y axes to enable stacking. Stacked bar charts can be used to show how one data series is made up of a number of smaller pieces.\n\n```javascript\nvar stackedBar = new Chart(ctx, {\n    type: 'bar',\n    data: data,\n    options: {\n        scales: {\n            xAxes: [{\n                stacked: true\n            }],\n            yAxes: [{\n                stacked: true\n            }]\n        }\n    }\n});\n```\n\n## Dataset Properties\n\nThe following dataset properties are specific to stacked bar charts.\n\n| Name | Type | Description\n| ---- | ---- | -----------\n| `stack` | `String` | The ID of the group to which this dataset belongs to (when stacked, each group will be a separate stack)\n\n# Horizontal Bar Chart\nA horizontal bar chart is a variation on a vertical bar chart. It is sometimes used to show trend data, and the comparison of multiple data sets side by side.\n{% chartjs %}\n{\n    \"type\": \"horizontalBar\",\n    \"data\": {\n        \"labels\": [\"January\", \"February\", \"March\", \"April\", \"May\", \"June\", \"July\"],\n        \"datasets\": [{\n            \"label\": \"My First Dataset\",\n            \"data\": [65, 59, 80, 81, 56, 55, 40],\n            \"fill\": false,\n            \"backgroundColor\": [\n                \"rgba(255, 99, 132, 0.2)\",\n                \"rgba(255, 159, 64, 0.2)\",\n                \"rgba(255, 205, 86, 0.2)\",\n                \"rgba(75, 192, 192, 0.2)\",\n                \"rgba(54, 162, 235, 0.2)\",\n                \"rgba(153, 102, 255, 0.2)\",\n                \"rgba(201, 203, 207, 0.2)\"\n            ],\n            \"borderColor\": [\n                \"rgb(255, 99, 132)\",\n                \"rgb(255, 159, 64)\",\n                \"rgb(255, 205, 86)\",\n                \"rgb(75, 192, 192)\",\n                \"rgb(54, 162, 235)\",\n                \"rgb(153, 102, 255)\",\n                \"rgb(201, 203, 207)\"\n            ],\n            \"borderWidth\": 1\n        }]\n    },\n    \"options\": {\n        \"scales\": {\n            \"xAxes\": [{\n                \"ticks\": {\n                    \"beginAtZero\": true\n                }\n            }]\n        }\n    }\n}\n{% endchartjs %}\n\n## Example\n```javascript\nvar myBarChart = new Chart(ctx, {\n    type: 'horizontalBar',\n    data: data,\n    options: options\n});\n```\n\n## Config Options\nThe configuration options for the horizontal bar chart are the same as for the [bar chart](../bar/config-options.md#config-options). However, any options specified on the x axis in a bar chart, are applied to the y axis in a horizontal bar chart.\n\nThe default horizontal bar configuration is specified in `Chart.defaults.horizontalBar`."
  },
  {
    "path": "app_backend/static/plugin/Chart.js-2.6.0/docs/charts/bubble.md",
    "content": "# Bubble Chart\n\nA bubble chart is used to display three dimensions of data at the same time. The location of the bubble is determined by the first two dimensions and the corresponding horizontal and vertical axes. The third dimension is represented by the size of the individual bubbles. \n\n{% chartjs %}\n{\n    \"type\": \"bubble\",\n    \"data\": {\n        \"datasets\": [{\n            \"label\": \"First Dataset\",\n            \"data\": [{\n                \"x\": 20,\n                \"y\": 30,\n                \"r\": 15\n            }, {\n                \"x\": 40,\n                \"y\": 10,\n                \"r\": 10\n            }],\n            \"backgroundColor\": \"rgb(255, 99, 132)\"\n        }]\n    },\n}\n{% endchartjs %}\n\n## Example Usage\n\n```javascript\n// For a bubble chart\nvar myBubbleChart = new Chart(ctx,{\n    type: 'bubble',\n    data: data,\n    options: options\n});\n```\n\n## Dataset Properties\n\nThe bubble chart allows a number of properties to be specified for each dataset. These are used to set display properties for a specific dataset. For example, the colour of the bubbles is generally set this way.\n\nAll properties, except `label` can be specified as an array. If these are set to an array value, the first value applies to the first bubble in the dataset, the second value to the second bubble, and so on.\n\n| Name | Type | Description\n| ---- | ---- | -----------\n| `label` | `String` | The label for the dataset which appears in the legend and tooltips.\n| `backgroundColor` | `Color/Color[]` | The fill color for bubbles.\n| `borderColor` | `Color/Color[]` | The border color for bubbles.\n| `borderWidth` | `Number/Number[]` | The width of the point bubbles in pixels.\n| `hoverBackgroundColor` | `Color/Color[]` | Bubble background color when hovered.\n| `hoverBorderColor` | `Color/Color[]` | Bubble border color when hovered.\n| `hoverBorderWidth` | `Number/Number[]` | Border width of point when hovered.\n| `hoverRadius` | `Number/Number[]` | Additional radius to add to data radius on hover.\n\n## Config Options\n\nThe bubble chart has no unique configuration options. To configure options common to all of the bubbles, the [point element options](../configuration/elements/point.md#point-configuration) are used.\n\n## Default Options\n\nWe can also change the default values for the Bubble chart type. Doing so will give all bubble charts created after this point the new defaults. The default configuration for the bubble chart can be accessed at `Chart.defaults.bubble`.\n\n## Data Structure\n\nFor a bubble chart, datasets need to contain an array of data points. Each point must implement the [bubble data object](#bubble-data-object) interface.\n\n### Bubble Data Object\n\nData for the bubble chart is passed in the form of an object. The object must implement the following interface. It is important to note that the radius property, `r` is **not** scaled by the chart. It is the raw radius in pixels of the bubble that is drawn on the canvas.\n\n```javascript\n{\n    // X Value\n    x: <Number>,\n\n    // Y Value\n    y: <Number>,\n\n    // Radius of bubble. This is not scaled.\n    r: <Number>\n}\n```"
  },
  {
    "path": "app_backend/static/plugin/Chart.js-2.6.0/docs/charts/doughnut.md",
    "content": "# Doughnut and Pie\nPie and doughnut charts are probably the most commonly used charts. They are divided into segments, the arc of each segment shows the proportional value of each piece of data.\n\nThey are excellent at showing the relational proportions between data.\n\nPie and doughnut charts are effectively the same class in Chart.js, but have one different default value - their `cutoutPercentage`. This equates what percentage of the inner should be cut out. This defaults to `0` for pie charts, and `50` for doughnuts.\n\nThey are also registered under two aliases in the `Chart` core. Other than their different default value, and different alias, they are exactly the same.\n\n{% chartjs %}\n{\n    \"type\": \"doughnut\",\n    \"data\": {\n        \"labels\": [\n            \"Red\",\n            \"Blue\",\n            \"Yellow\",\n        ],\n        \"datasets\": [{\n            \"label\": \"My First Dataset\",\n            \"data\": [300, 50, 100],\n            \"backgroundColor\": [\n                \"rgb(255, 99, 132)\",\n                \"rgb(54, 162, 235)\",\n                \"rgb(255, 205, 86)\",\n            ]\n        }]\n    },\n}\n{% endchartjs %}\n\n## Example Usage\n\n```javascript\n// For a pie chart\nvar myPieChart = new Chart(ctx,{\n    type: 'pie',\n    data: data,\n    options: options\n});\n```\n\n```javascript\n// And for a doughnut chart\nvar myDoughnutChart = new Chart(ctx, {\n    type: 'doughnut',\n    data: data,\n    options: options\n});\n```\n\n## Dataset Properties\n\nThe doughnut/pie chart allows a number of properties to be specified for each dataset. These are used to set display properties for a specific dataset. For example, the colour of a the dataset's arc are generally set this way.\n\n| Name | Type | Description\n| ---- | ---- | -----------\n| `label` | `String` | The label for the dataset which appears in the legend and tooltips.\n| `backgroundColor` | `Color[]` | The fill color of the arcs in the dataset. See [Colors](../general/colors.md#colors)\n| `borderColor` | `Color[]` | The border color of the arcs in the dataset. See [Colors](../general/colors.md#colors)\n| `borderWidth` | `Number[]` | The border width of the arcs in the dataset.\n| `hoverBackgroundColor` | `Color[]` | The fill colour of the arcs when hovered.\n| `hoverBorderColor` | `Color[]` | The stroke colour of the arcs when hovered.\n| `hoverBorderWidth` | `Number[]` | The stroke width of the arcs when hovered.\n\n## Config Options\n\nThese are the customisation options specific to Pie & Doughnut charts. These options are merged with the global chart configuration options, and form the options of the chart.\n\n| Name | Type | Default | Description\n| ---- | ---- | ------- | -----------\n| `cutoutPercentage` | `Number` | `50` - for doughnut, `0` - for pie | The percentage of the chart that is cut out of the middle.\n| `rotation` | `Number` | `-0.5 * Math.PI` | Starting angle to draw arcs from.\n| `circumference` | `Number` | `2 * Math.PI` | Sweep to allow arcs to cover\n| `animation.animateRotate` | `Boolean` | `true` | If true, the chart will animate in with a rotation animation. This property is in the `options.animation` object.\n| `animation.animateScale` | `Boolean` | `false` | If true, will animate scaling the chart from the center outwards.\n\n## Default Options\n\nWe can also change these default values for each Doughnut type that is created, this object is available at `Chart.defaults.doughnut`. Pie charts also have a clone of these defaults available to change at `Chart.defaults.pie`, with the only difference being `cutoutPercentage` being set to 0.\n\n## Data Structure\n\nFor a pie chart, datasets need to contain an array of data points. The data points should be a number, Chart.js will total all of the numbers and calculate the relative proportion of each.\n\nYou also need to specify an array of labels so that tooltips appear correctly\n\n```javascript\ndata = {\n    datasets: [{\n        data: [10, 20, 30]\n    }],\n\n    // These labels appear in the legend and in the tooltips when hovering different arcs\n    labels: [\n        'Red',\n        'Yellow',\n        'Blue'\n    ]\n};\n```"
  },
  {
    "path": "app_backend/static/plugin/Chart.js-2.6.0/docs/charts/line.md",
    "content": "# Line\nA line chart is a way of plotting data points on a line. Often, it is used to show trend data, or the comparison of two data sets.\n\n{% chartjs %}\n{\n    \"type\": \"line\",\n    \"data\": {\n        \"labels\": [\n            \"January\", \n            \"February\", \n            \"March\", \n            \"April\", \n            \"May\", \n            \"June\",\n            \"July\"\n        ],\n        \"datasets\": [{\n            \"label\": \"My First Dataset\",\n            \"data\": [65, 59, 80, 81, 56, 55, 40],\n            \"fill\": false,\n            \"borderColor\": \"rgb(75, 192, 192)\",\n            \"lineTension\": 0.1\n        }]\n    },\n    \"options\": {\n\n    }\n}\n{% endchartjs %}\n\n## Example Usage\n```javascript\nvar myLineChart = new Chart(ctx, {\n    type: 'line',\n    data: data,\n    options: options\n});\n```\n\n## Dataset Properties\n\nThe line chart allows a number of properties to be specified for each dataset. These are used to set display properties for a specific dataset. For example, the colour of a line is generally set this way.\n\nAll point* properties can be specified as an array. If these are set to an array value, the first value applies to the first point, the second value to the second point, and so on.\n\n| Name | Type | Description\n| ---- | ---- | -----------\n| `label` | `String` | The label for the dataset which appears in the legend and tooltips.\n| `xAxisID` | `String` | The ID of the x axis to plot this dataset on. If not specified, this defaults to the ID of the first found x axis\n| `yAxisID` | `String` | The ID of the y axis to plot this dataset on. If not specified, this defaults to the ID of the first found y axis.\n| `backgroundColor` | `Color/Color[]` | The fill color under the line. See [Colors](../general/colors.md#colors)\n| `borderColor` | `Color/Color[]` | The color of the line. See [Colors](../general/colors.md#colors)\n| `borderWidth` | `Number/Number[]` | The width of the line in pixels.\n| `borderDash` | `Number[]` | Length and spacing of dashes. See [MDN](https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/setLineDash)\n| `borderDashOffset` | `Number` | Offset for line dashes. See [MDN](https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/lineDashOffset)\n| `borderCapStyle` | `String` | Cap style of the line. See [MDN](https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/lineCap)\n| `borderJoinStyle` | `String` | Line joint style. See [MDN](https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/lineJoin)\n| `cubicInterpolationMode` | `String` | Algorithm used to interpolate a smooth curve from the discrete data points. [more...](#cubicInterpolationMode)\n| `fill` | `Boolean/String` | How to fill the area under the line. See [area charts](area.md)\n| `lineTension` | `Number` | Bezier curve tension of the line. Set to 0 to draw straightlines. This option is ignored if monotone cubic interpolation is used.\n| `pointBackgroundColor` | `Color/Color[]` | The fill color for points.\n| `pointBorderColor` | `Color/Color[]` | The border color for points.\n| `pointBorderWidth` | `Number/Number[]` | The width of the point border in pixels.\n| `pointRadius` | `Number/Number[]` | The radius of the point shape. If set to 0, the point is not rendered.\n| `pointStyle` | `String/String[]/Image/Image[]` | Style of the point. [more...](#pointStyle)\n| `pointHitRadius` | `Number/Number[]` | The pixel size of the non-displayed point that reacts to mouse events.\n| `pointHoverBackgroundColor` | `Color/Color[]` | Point background color when hovered.\n| `pointHoverBorderColor` | `Color/Color[]` | Point border color when hovered.\n| `pointHoverBorderWidth` | `Number/Number[]` | Border width of point when hovered.\n| `pointHoverRadius` | `Number/Number[]` | The radius of the point when hovered.\n| `showLine` | `Boolean` | If false, the line is not drawn for this dataset.\n| `spanGaps` | `Boolean` | If true, lines will be drawn between points with no or null data. If false, points with `NaN` data will create a break in the line\n| `steppedLine` | `Boolean/String` | If the line is shown as a stepped line. [more...](#stepped-line)\n\n### cubicInterpolationMode\nThe following interpolation modes are supported:\n* 'default'\n* 'monotone'. \n\nThe 'default' algorithm uses a custom weighted cubic interpolation, which produces pleasant curves for all types of datasets.\n\nThe 'monotone' algorithm is more suited to `y = f(x)` datasets : it preserves monotonicity (or piecewise monotonicity) of the dataset being interpolated, and ensures local extremums (if any) stay at input data points.\n\nIf left untouched (`undefined`), the global `options.elements.line.cubicInterpolationMode` property is used.\n\n### pointStyle\nThe style of point. Options are:\n* 'circle'\n* 'cross'\n* 'crossRot'\n* 'dash'. \n* 'line'\n* 'rect'\n* 'rectRounded'\n* 'rectRot'\n* 'star'\n* 'triangle'\n\nIf the option is an image, that image is drawn on the canvas using [drawImage](https://developer.mozilla.org/en/docs/Web/API/CanvasRenderingContext2D/drawImage).\n\n### Stepped Line\nThe following values are supported for `steppedLine`:\n* `false`:  No Step Interpolation (default)\n* `true`: Step-before Interpolation (eq. 'before')\n* `'before'`: Step-before Interpolation\n* `'after'`: Step-after Interpolation\n\nIf the `steppedLine` value is set to anything other than false, `lineTension` will be ignored.\n\n## Configuration Options\n\nThe line chart defines the following configuration options. These options are merged with the global chart configuration options, `Chart.defaults.global`, to form the options passed to the chart.\n\n| Name | Type | Default | Description\n| ---- | ---- | ------- | -----------\n| `showLines` | `Boolean` | `true` | If false, the lines between points are not drawn.\n| `spanGaps` | `Boolean` | `false` | If false, NaN data causes a break in the line.\n\n## Default Options\n\nIt is common to want to apply a configuration setting to all created line charts. The global line chart settings are stored in `Chart.defaults.line`. Changing the global options only affects charts created after the change. Existing charts are not changed.\n\nFor example, to configure all line charts with `spanGaps = true` you would do:\n```javascript\nChart.defaults.line.spanGaps = true;\n```\n\n## Data Structure\n\nThe `data` property of a dataset for a line chart can be passed in two formats. \n\n### Number[]\n```javascript\ndata: [20, 10]\n```\n\nWhen the `data` array is an array of numbers, the x axis is generally a [category](../axes/cartesian/category.md#Category Axis). The points are placed onto the axis using their position in the array. When a line chart is created with a category axis, the `labels` property of the data object must be specified.\n\n### Point[]\n\n```javascript\ndata: [{\n        x: 10,\n        y: 20\n    }, {\n        x: 15,\n        y: 10\n    }]\n```\n\nThis alternate is used for sparse datasets, such as those in [scatter charts](./scatter.md#scatter-chart). Each data point is specified using an object containing `x` and `y` properties.\n\n# Stacked Area Chart\n\nLine charts can be configured into stacked area charts by changing the settings on the y axis to enable stacking. Stacked area charts can be used to show how one data trend is made up of a number of smaller pieces.\n\n```javascript\nvar stackedLine = new Chart(ctx, {\n    type: 'line',\n    data: data,\n    options: {\n        scales: {\n            yAxes: [{\n                stacked: true\n            }]\n        }\n    }\n});\n```\n\n# High Performance Line Charts\n\nWhen charting a lot of data, the chart render time may start to get quite large. In that case, the following strategies can be used to improve performance.\n\n## Data Decimation\n\nDecimating your data will achieve the best results. When there is a lot of data to display on the graph, it doesn't make sense to show tens of thousands of data points on a graph that is only a few hundred pixels wide.\n\nThere are many approaches to data decimation and selection of an algorithm will depend on your data and the results you want to achieve. For instance, [min/max](http://digital.ni.com/public.nsf/allkb/F694FFEEA0ACF282862576020075F784) decimation will preserve peaks in your data but could require up to 4 points for each pixel. This type of decimation would work well for a very noisy signal where you need to see data peaks.\n\n## Disable Bezier Curves\n\nIf you are drawing lines on your chart, disabling bezier curves will improve render times since drawing a straight line is more performant than a bezier curve.\n\nTo disable bezier curves for an entire chart:\n\n```javascript\nnew Chart(ctx, {\n    type: 'line',\n    data: data,\n    options: {\n        elements: {\n            line: {\n                tension: 0, // disables bezier curves\n            }\n        }\n    }\n});\n```\n\n## Draw Line Drawing\n\nIf you have a lot of data points, it can be more performant to disable rendering of the line for a dataset and only draw points. Doing this means that there is less to draw on the canvas which will improve render performance.\n\nTo disable lines:\n\n```javascript\nnew Chart(ctx, {\n    type: 'line',\n    data: {\n        datasets: [{\n            showLine: false, // disable for a single dataset\n        }]\n    },\n    options: {\n        showLines: false, // disable for all datasets\n    }\n});\n```\n\n## Disable Animations\n\nIf your charts have long render times, it is a good idea to disable animations. Doing so will mean that the chart needs to only be rendered once during an update instead of multiple times. This will have the effect of reducing CPU usage and improving general page performance.\n\nTo disable animations\n\n```javascript\nnew Chart(ctx, {\n    type: 'line',\n    data: data,\n    options: {\n        animation: {\n            duration: 0, // general animation time\n        },\n        hover: {\n            animationDuration: 0, // duration of animations when hovering an item\n        },\n        responsiveAnimationDuration: 0, // animation duration after a resize\n    }\n});\n```\n"
  },
  {
    "path": "app_backend/static/plugin/Chart.js-2.6.0/docs/charts/mixed.md",
    "content": "# Mixed Chart Types\n\nWith Chart.js, it is possible to create mixed charts that are a combination of two or more different chart types. A common example is a bar chart that also includes a line dataset.\n\nCreating a mixed chart starts with the initialization of a basic chart.\n\n```javascript\nvar myChart = new Chart(ctx, {\n  type: 'bar',\n  data: data,\n  options: options\n});\n```\n\nAt this point we have a standard bar chart. Now we need to convert one of the datasets to a line dataset.\n\n```javascript\nvar mixedChart = new Chart(ctx, {\n  type: 'bar',\n  data: {\n    datasets: [{\n          label: 'Bar Dataset',\n          data: [10, 20, 30, 40]\n        }, {\n          label: 'Line Dataset',\n          data: [50, 50, 50, 50],\n\n          // Changes this dataset to become a line\n          type: 'line'\n        }],\n    labels: ['January', 'February', 'March', 'April']\n  },\n  options: options\n});\n```\n\nAt this point we have a chart rendering how we'd like. It's important to note that the default options for a line chart are not merged in this case. Only the options for the default type are merged in. In this case, that means that the default options for a bar chart are merged because that is the type specified by the `type` field.\n\n{% chartjs %}\n{\n  \"type\": \"bar\",\n  \"data\": {\n    \"labels\": [\n      \"January\", \n      \"February\", \n      \"March\", \n      \"April\"\n    ],\n    \"datasets\": [{\n      \"label\": \"Bar Dataset\",\n      \"data\": [10, 20, 30, 40],\n      \"borderColor\": \"rgb(255, 99, 132)\",\n      \"backgroundColor\": \"rgba(255, 99, 132, 0.2)\"\n    }, {\n      \"label\": \"Line Dataset\",\n      \"data\": [50, 50, 50, 50],\n      \"type\": \"line\",\n      \"fill\": false,\n      \"borderColor\": \"rgb(54, 162, 235)\"\n    }]\n  },\n  \"options\": {\n    \"scales\": {\n      \"yAxes\": [{\n        \"ticks\": {\n          \"beginAtZero\": true\n        }\n      }]\n    }\n  }\n}\n{% endchartjs %}\n"
  },
  {
    "path": "app_backend/static/plugin/Chart.js-2.6.0/docs/charts/polar.md",
    "content": "# Polar Area\n\nPolar area charts are similar to pie charts, but each segment has the same angle - the radius of the segment differs depending on the value.\n\nThis type of chart is often useful when we want to show a comparison data similar to a pie chart, but also show a scale of values for context.\n\n{% chartjs %}\n{\n    \"type\": \"polarArea\",\n    \"data\": {\n        \"labels\": [\n            \"Red\",\n            \"Green\",\n            \"Yellow\",\n            \"Grey\",\n            \"Blue\"\n        ],\n        \"datasets\": [{\n            \"label\": \"My First Dataset\",\n            \"data\": [11, 16, 7, 3, 14],\n            \"backgroundColor\": [\n                \"rgb(255, 99, 132)\",\n                \"rgb(75, 192, 192)\",\n                \"rgb(255, 205, 86)\",\n                \"rgb(201, 203, 207)\",\n                \"rgb(54, 162, 235)\"\n            ]\n        }]\n    },\n}\n{% endchartjs %}\n\n## Example Usage\n\n```javascript\nnew Chart(ctx, {\n    data: data,\n    type: 'polarArea',\n    options: options\n});\n```\n\n## Dataset Properties\n\nThe following options can be included in a polar area chart dataset to configure options for that specific dataset.\n\n| Name | Type | Description\n| ---- | ---- | -----------\n| `label` | `String` | The label for the dataset which appears in the legend and tooltips.\n| `backgroundColor` | `Color[]` | The fill color of the arcs in the dataset. See [Colors](../general/colors.md#colors)\n| `borderColor` | `Color[]` | The border color of the arcs in the dataset. See [Colors](../general/colors.md#colors)\n| `borderWidth` | `Number[]` | The border width of the arcs in the dataset.\n| `hoverBackgroundColor` | `Color[]` | The fill colour of the arcs when hovered.\n| `hoverBorderColor` | `Color[]` | The stroke colour of the arcs when hovered.\n| `hoverBorderWidth` | `Number[]` | The stroke width of the arcs when hovered.\n\n## Config Options\n\nThese are the customisation options specific to Polar Area charts. These options are merged with the [global chart configuration options](#global-chart-configuration), and form the options of the chart.\n\n| Name | Type | Default | Description\n| ---- | ---- | ------- | -----------\n| `startAngle` | `Number` | `-0.5 * Math.PI` | Starting angle to draw arcs for the first item in a dataset.\n| `animation.animateRotate` | `Boolean` | `true` | If true, the chart will animate in with a rotation animation. This property is in the `options.animation` object.\n| `animation.animateScale` | `Boolean` | `true` | If true, will animate scaling the chart from the center outwards.\n\n## Default Options\n\nWe can also change these defaults values for each PolarArea type that is created, this object is available at `Chart.defaults.polarArea`. Changing the global options only affects charts created after the change. Existing charts are not changed.\n\nFor example, to configure all new polar area charts with `animateScale = false` you would do:\n```javascript\nChart.defaults.polarArea.animation.animateScale = false;\n```\n\n## Data Structure\n\nFor a polar area chart, datasets need to contain an array of data points. The data points should be a number, Chart.js will total all of the numbers and calculate the relative proportion of each.\n\nYou also need to specify an array of labels so that tooltips appear correctly for each slice.\n\n```javascript\ndata = {\n    datasets: [{\n        data: [10, 20, 30]\n    }],\n\n    // These labels appear in the legend and in the tooltips when hovering different arcs\n    labels: [\n        'Red',\n        'Yellow',\n        'Blue'\n    ]\n};\n```"
  },
  {
    "path": "app_backend/static/plugin/Chart.js-2.6.0/docs/charts/radar.md",
    "content": "# Radar\nA radar chart is a way of showing multiple data points and the variation between them.\n\nThey are often useful for comparing the points of two or more different data sets.\n\n{% chartjs %}\n{\n    \"type\": \"radar\",\n    \"data\": {\n        \"labels\": [\n            \"Eating\", \n            \"Drinking\", \n            \"Sleeping\", \n            \"Designing\",\n            \"Coding\",\n            \"Cycling\",\n            \"Running\"\n        ],\n        \"datasets\": [{\n            \"label\": \"My First Dataset\",\n            \"data\": [65, 59, 90, 81, 56, 55, 40],\n            \"fill\": true,\n            \"backgroundColor\": \"rgba(255, 99, 132, 0.2)\",\n            \"borderColor\": \"rgb(255, 99, 132)\",\n            \"pointBackgroundColor\": \"rgb(255, 99, 132)\",\n            \"pointBorderColor\": \"#fff\",\n            \"pointHoverBackgroundColor\": \"#fff\",\n            \"pointHoverBorderColor\": \"rgb(255, 99, 132)\",\n            \"fill\": true\n        }, {\n            \"label\": \"My Second Dataset\",\n            \"data\": [28, 48, 40, 19, 96, 27, 100],\n            \"fill\": true,\n            \"backgroundColor\": \"rgba(54, 162, 235, 0.2)\",\n            \"borderColor\": \"rgb(54, 162, 235)\",\n            \"pointBackgroundColor\": \"rgb(54, 162, 235)\",\n            \"pointBorderColor\": \"#fff\",\n            \"pointHoverBackgroundColor\": \"#fff\",\n            \"pointHoverBorderColor\": \"rgb(54, 162, 235)\",\n            \"fill\": true\n        }]\n    },\n    \"options\": {\n        \"elements\": {\n            \"line\": {\n                \"tension\": 0,\n                \"borderWidth\": 3\n            }\n        }\n    }\n}\n{% endchartjs %}\n\n## Example Usage\n```javascript\nvar myRadarChart = new Chart(ctx, {\n    type: 'radar',\n    data: data,\n    options: options\n});\n```\n\n## Dataset Properties\n\nThe radar chart allows a number of properties to be specified for each dataset. These are used to set display properties for a specific dataset. For example, the colour of a line is generally set this way.\n\nAll point* properties can be specified as an array. If these are set to an array value, the first value applies to the first point, the second value to the second point, and so on.\n\n| Name | Type | Description\n| ---- | ---- | -----------\n| `label` | `String` | The label for the dataset which appears in the legend and tooltips.\n| `backgroundColor` | `Color/Color[]` | The fill color under the line. See [Colors](../general/colors.md#colors)\n| `borderColor` | `Color/Color[]` | The color of the line. See [Colors](../general/colors.md#colors)\n| `borderWidth` | `Number/Number[]` | The width of the line in pixels.\n| `borderDash` | `Number[]` | Length and spacing of dashes. See [MDN](https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/setLineDash)\n| `borderDashOffset` | `Number` | Offset for line dashes. See [MDN](https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/lineDashOffset)\n| `borderCapStyle` | `String` | Cap style of the line. See [MDN](https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/lineCap)\n| `borderJoinStyle` | `String` | Line joint style. See [MDN](https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/lineJoin)\n| `fill` | `Boolean/String` | How to fill the area under the line. See [area charts](area.md)\n| `lineTension` | `Number` | Bezier curve tension of the line. Set to 0 to draw straightlines.\n| `pointBackgroundColor` | `Color/Color[]` | The fill color for points.\n| `pointBorderColor` | `Color/Color[]` | The border color for points.\n| `pointBorderWidth` | `Number/Number[]` | The width of the point border in pixels.\n| `pointRadius` | `Number/Number[]` | The radius of the point shape. If set to 0, the point is not rendered.\n| `pointStyle` | `String/String[]/Image/Image[]` | Style of the point. [more...](#pointStyle)\n| `pointHitRadius` | `Number/Number[]` | The pixel size of the non-displayed point that reacts to mouse events.\n| `pointHoverBackgroundColor` | `Color/Color[]` | Point background color when hovered.\n| `pointHoverBorderColor` | `Color/Color[]` | Point border color when hovered.\n| `pointHoverBorderWidth` | `Number/Number[]` | Border width of point when hovered.\n| `pointHoverRadius` | `Number/Number[]` | The radius of the point when hovered.\n\n### pointStyle\nThe style of point. Options are:\n* 'circle'\n* 'cross'\n* 'crossRot'\n* 'dash'. \n* 'line'\n* 'rect'\n* 'rectRounded'\n* 'rectRot'\n* 'star'\n* 'triangle'\n\nIf the option is an image, that image is drawn on the canvas using [drawImage](https://developer.mozilla.org/en/docs/Web/API/CanvasRenderingContext2D/drawImage).\n\n## Configuration Options\n\nUnlike other charts, the radar chart has no chart specific options.\n\n## Scale Options\n\nThe radar chart supports only a single scale. The options for this scale are defined in the `scale` property.\n\n```javascript\noptions = {\n    scale: {\n        // Hides the scale\n        display: false\n    }\n};\n```\n\n## Default Options\n\nIt is common to want to apply a configuration setting to all created radar charts. The global radar chart settings are stored in `Chart.defaults.radar`. Changing the global options only affects charts created after the change. Existing charts are not changed.\n\n## Data Structure\n\nThe `data` property of a dataset for a radar chart is specified as a an array of numbers. Each point in the data array corresponds to the label at the same index on the x axis. \n\n```javascript\ndata: [20, 10]\n```\n\nFor a radar chart, to provide context of what each point means, we include an array of strings that show around each point in the chart.\n\n```javascript\ndata: {\n    labels: ['Running', 'Swimming', 'Eating', 'Cycling'],\n    datasets: [{\n        data: [20, 10, 4, 2]\n    }]\n}\n```\n"
  },
  {
    "path": "app_backend/static/plugin/Chart.js-2.6.0/docs/charts/scatter.md",
    "content": "# Scatter Chart\n\nScatter charts are based on basic line charts with the x axis changed to a linear axis. To use a scatter chart, data must be passed as objects containing X and Y properties. The example below creates a scatter chart with 3 points.\n\n```javascript\nvar scatterChart = new Chart(ctx, {\n    type: 'scatter',\n    data: {\n        datasets: [{\n            label: 'Scatter Dataset',\n            data: [{\n                x: -10,\n                y: 0\n            }, {\n                x: 0,\n                y: 10\n            }, {\n                x: 10,\n                y: 5\n            }]\n        }]\n    },\n    options: {\n        scales: {\n            xAxes: [{\n                type: 'linear',\n                position: 'bottom'\n            }]\n        }\n    }\n});\n```\n\n## Dataset Properties\nThe scatter chart supports all of the same properties as the [line chart](./line.md#dataset-properties).\n\n## Data Structure\n\nUnlike the line chart where data can be supplied in two different formats, the scatter chart only accepts data in a point format.\n\n```javascript\ndata: [{\n        x: 10,\n        y: 20\n    }, {\n        x: 15,\n        y: 10\n    }]\n```"
  },
  {
    "path": "app_backend/static/plugin/Chart.js-2.6.0/docs/configuration/README.md",
    "content": "# Configuration\n\nThe configuration is used to change how the chart behaves. There are properties to control styling, fonts, the legend, etc.\n\n## Global Configuration\n\nThis concept was introduced in Chart.js 1.0 to keep configuration [DRY](https://en.wikipedia.org/wiki/Don%27t_repeat_yourself), and allow for changing options globally across chart types, avoiding the need to specify options for each instance, or the default for a particular chart type.\n\nChart.js merges the options object passed to the chart with the global configuration using chart type defaults and scales defaults appropriately. This way you can be as specific as you would like in your individual chart configuration, while still changing the defaults for all chart types where applicable. The global general options are defined in `Chart.defaults.global`. The defaults for each chart type are discussed in the documentation for that chart type.\n\nThe following example would set the hover mode to 'nearest' for all charts where this was not overridden by the chart type defaults or the options passed to the constructor on creation.\n\n```javascript\nChart.defaults.global.hover.mode = 'nearest';\n\n// Hover mode is set to nearest because it was not overridden here\nvar chartHoverModeNearest  = new Chart(ctx, {\n    type: 'line',\n    data: data,\n});\n\n// This chart would have the hover mode that was passed in\nvar chartDifferentHoverMode = new Chart(ctx, {\n    type: 'line',\n    data: data,\n    options: {\n        hover: {\n            // Overrides the global setting\n            mode: 'index'\n        }\n    }\n})\n```\n\n"
  },
  {
    "path": "app_backend/static/plugin/Chart.js-2.6.0/docs/configuration/animations.md",
    "content": "# Animations\n\nChart.js animates charts out of the box. A number of options are provided to configure how the animation looks and how long it takes\n\n## Animation Configuration\n\nThe following animation options are available. The global options for are defined in `Chart.defaults.global.animation`.\n\n| Name | Type | Default | Description\n| -----| ---- | --------| -----------\n| `duration` | `Number` | `1000` | The number of milliseconds an animation takes.\n| `easing` | `String` | `'easeOutQuart'` | Easing function to use. [more...](#easing)\n| `onProgress` | `Function` | `null` | Callback called on each step of an animation. [more...](#animation-callbacks)\n| `onComplete` | `Function` | `null` | Callback called at the end of an animation. [more...](#animation-callbacks)\n\n## Easing\n Available options are:\n* `'linear'`\n* `'easeInQuad'`\n* `'easeOutQuad'`\n* `'easeInOutQuad'`\n* `'easeInCubic'`\n* `'easeOutCubic'`\n* `'easeInOutCubic'`\n* `'easeInQuart'`\n* `'easeOutQuart'`\n* `'easeInOutQuart'`\n* `'easeInQuint'`\n* `'easeOutQuint'`\n* `'easeInOutQuint'`\n* `'easeInSine'`\n* `'easeOutSine'`\n* `'easeInOutSine'`\n* `'easeInExpo'`\n* `'easeOutExpo'`\n* `'easeInOutExpo'`\n* `'easeInCirc'`\n* `'easeOutCirc'`\n* `'easeInOutCirc'`\n* `'easeInElastic'`\n* `'easeOutElastic'`\n* `'easeInOutElastic'`\n* `'easeInBack'`\n* `'easeOutBack'`\n* `'easeInOutBack'`\n* `'easeInBounce'`\n* `'easeOutBounce'`\n* `'easeInOutBounce'`\n\nSee [Robert Penner's easing equations](http://robertpenner.com/easing/).\n\n## Animation Callbacks\n\nThe `onProgress` and `onComplete` callbacks are useful for synchronizing an external draw to the chart animation. The callback is passed a `Chart.Animation` instance:\n\n```javascript\n{\n    // Chart object\n    chart: Chart,\n\n    // Current Animation frame number\n    currentStep: Number,\n\n    // Number of animation frames\n    numSteps: Number,\n\n    // Animation easing to use\n    easing: String,\n\n    // Function that renders the chart\n    render: Function,\n\n    // User callback\n    onAnimationProgress: Function,\n\n    // User callback\n    onAnimationComplete: Function\n}\n```\n\nThe following example fills a progress bar during the chart animation.\n```javascript\nvar chart = new Chart(ctx, {\n    type: 'line',\n    data: data,\n    options: {\n        animation: {\n            onProgress: function(animation) {\n                progress.value = animation.animationObject.currentStep / animation.animationObject.numSteps;\n            }\n        }\n    }\n});\n```\n\nAnother example usage of these callbacks can be found on [Github](https://github.com/chartjs/Chart.js/blob/master/samples/animation/progress-bar.html): this sample displays a progress bar showing how far along the animation is.\n"
  },
  {
    "path": "app_backend/static/plugin/Chart.js-2.6.0/docs/configuration/elements.md",
    "content": "# Elements\n\nWhile chart types provide settings to configure the styling of each dataset, you sometimes want to style **all datasets the same way**. A common example would be to stroke all of the bars in a bar chart with the same colour but change the fill per dataset. Options can be configured for four different types of elements: **[arc](#arc-configuration)**, **[lines](#line-configuration)**, **[points](#point-configuration)**, and **[rectangles](#rectangle-configuration)**. When set, these options apply to all objects of that type unless specifically overridden by the configuration attached to a dataset.\n\n## Global Configuration\n\nThe element options can be specified per chart or globally. The global options for elements are defined in `Chart.defaults.global.elements`. For example, to set the border width of all bar charts globally you would do:\n\n```javascript\nChart.defaults.global.elements.rectangle.borderWidth = 2;\n```\n\n## Point Configuration\nPoint elements are used to represent the points in a line chart or a bubble chart.\n\nGlobal point options: `Chart.defaults.global.elements.point`\n\n| Name | Type | Default | Description\n| -----| ---- | --------| -----------\n| `radius` | `Number` | `3` | Point radius.\n| `pointStyle` | `String` | `circle` | Point style.\n| `backgroundColor` | `Color` | `'rgba(0,0,0,0.1)'` | Point fill color.\n| `borderWidth` | `Number` | `1` | Point stroke width.\n| `borderColor` | `Color` | `'rgba(0,0,0,0.1)'` | Point stroke color.\n| `hitRadius` | `Number` | `1` | Extra radius added to point radius for hit detection.\n| `hoverRadius` | `Number` | `4` | Point radius when hovered.\n| `hoverBorderWidth` | `Number` | `1` | Stroke width when hovered.\n\n## Line Configuration\nLine elements are used to represent the line in a line chart.\n\nGlobal line options: `Chart.defaults.global.elements.line`\n\n| Name | Type | Default | Description\n| -----| ---- | --------| -----------\n| `tension` | `Number` | `0.4` | Bézier curve tension (`0` for no Bézier curves).\n| `backgroundColor` | `Color` | `'rgba(0,0,0,0.1)'` | Line fill color.\n| `borderWidth` | `Number` | `3` | Line stroke width.\n| `borderColor` | `Color` | `'rgba(0,0,0,0.1)'` | Line stroke color.\n| `borderCapStyle` | `String` | `'butt'` | Line cap style (see [MDN](https://developer.mozilla.org/en/docs/Web/API/CanvasRenderingContext2D/lineCap)).\n| `borderDash` | `Array` | `[]` | Line dash (see [MDN](https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/setLineDash)).\n| `borderDashOffset` | `Number` | `0` | Line dash offset (see [MDN](https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/lineDashOffset)).\n| `borderJoinStyle` | `String` | `'miter` | Line join style (see [MDN](https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/lineJoin)).\n| `capBezierPoints` | `Boolean` | `true` | `true` to keep Bézier control inside the chart, `false` for no restriction.\n| `fill` | `Boolean/String` | `true` | Fill location: `'zero'`, `'top'`, `'bottom'`, `true` (eq. `'zero'`) or `false` (no fill).\n| `stepped` | `Boolean` | `false` | `true` to show the line as a stepped line (`tension` will be ignored).\n\n## Rectangle Configuration\nRectangle elements are used to represent the bars in a bar chart.\n\nGlobal rectangle options: `Chart.defaults.global.elements.rectangle`\n\n| Name | Type | Default | Description\n| -----| ---- | --------| -----------\n| `backgroundColor` | `Color` | `'rgba(0,0,0,0.1)'` | Bar fill color.\n| `borderWidth` | `Number` | `0` | Bar stroke width.\n| `borderColor` | `Color` | `'rgba(0,0,0,0.1)'` | Bar stroke color.\n| `borderSkipped` | `String` | `'bottom'` | Skipped (excluded) border: `'bottom'`, `'left'`, `'top'` or `'right'`.\n\n## Arc Configuration\nArcs are used in the polar area, doughnut and pie charts.\n\nGlobal arc options: `Chart.defaults.global.elements.arc`.\n\n| Name | Type | Default | Description\n| -----| ---- | --------| -----------\n| `backgroundColor` | `Color` | `'rgba(0,0,0,0.1)'` | Arc fill color.\n| `borderColor` | `Color` | `'#fff'` | Arc stroke color.\n| `borderWidth`| `Number` | `2` | Arc stroke width.\n"
  },
  {
    "path": "app_backend/static/plugin/Chart.js-2.6.0/docs/configuration/layout.md",
    "content": "# Layout Configuration\n\nThe layout configuration is passed into the `options.layout` namespace. The global options for the chart layout is defined in `Chart.defaults.global.layout`.\n\n| Name | Type | Default | Description\n| -----| ---- | --------| -----------\n| `padding` | `Number` or `Object` | `0` | The padding to add inside the chart. [more...](#padding)\n\n## Padding\nIf this value is a number, it is applied to all sides of the chart (left, top, right, bottom). If this value is an object, the `left` property defines the left padding. Similarly the `right`, `top`, and `bottom` properties can also be specified.\n\nLets say you wanted to add 50px of padding to the left side of the chart canvas, you would do:\n\n```javascript\nlet chart = new Chart(ctx, {\n    type: 'line',\n    data: data,\n    options: {\n        layout: {\n            padding: {\n                left: 50,\n                right: 0,\n                top: 0,\n                bottom: 0\n            }\n        }\n    }\n});\n```"
  },
  {
    "path": "app_backend/static/plugin/Chart.js-2.6.0/docs/configuration/legend.md",
    "content": "# Legend Configuration\n\nThe chart legend displays data about the datasets that area appearing on the chart.\n\n## Configuration options\nThe legend configuration is passed into the `options.legend` namespace. The global options for the chart legend is defined in `Chart.defaults.global.legend`.\n\n| Name | Type | Default | Description\n| -----| ---- | --------| -----------\n| `display` | `Boolean` | `true` | is the legend shown\n| `position` | `String` | `'top'` | Position of the legend. [more...](#position)\n| `fullWidth` | `Boolean` | `true` | Marks that this box should take the full width of the canvas (pushing down other boxes). This is unlikely to need to be changed in day-to-day use.\n| `onClick` | `Function` | | A callback that is called when a click event is registered on a label item \n| `onHover` | `Function` | | A callback that is called when a 'mousemove' event is registered on top of a label item\n| `reverse` | `Boolean` | `false` | Legend will show datasets in reverse order.\n| `labels` | `Object` | | See the [Legend Label Configuration](#legend-label-configuration) section below.\n\n## Position\nPosition of the legend. Options are:\n* `'top'`\n* `'left'`\n* `'bottom'`\n* `'right'`\n\n## Legend Label Configuration\n\nThe legend label configuration is nested below the legend configuration using the `labels` key.\n\n| Name | Type | Default | Description\n| -----| ---- | --------| -----------\n| `boxWidth` | `Number` | `40` | width of coloured box\n| `fontSize` | `Number` | `12` | font size of text\n| `fontStyle` | `String` | `'normal'` | font style of text\n| `fontColor` | Color | `'#666'` | Color of text\n| `fontFamily` | `String` | `\"'Helvetica Neue', 'Helvetica', 'Arial', sans-serif\"` | Font family of legend text.\n| `padding` | `Number` | `10` | Padding between rows of colored boxes.\n| `generateLabels` | `Function` | | Generates legend items for each thing in the legend. Default implementation returns the text + styling for the color box. See [Legend Item](#chart-configuration-legend-item-interface) for details.\n| `filter` | `Function` | `null` | Filters legend items out of the legend. Receives 2 parameters, a [Legend Item](#chart-configuration-legend-item-interface) and the chart data.\n| `usePointStyle` | `Boolean` | `false` | Label style will match corresponding point style (size is based on fontSize, boxWidth is not used in this case).\n\n## Legend Item Interface\n\nItems passed to the legend `onClick` function are the ones returned from `labels.generateLabels`. These items must implement the following interface.\n\n```javascript\n{\n    // Label that will be displayed\n    text: String,\n\n    // Fill style of the legend box\n    fillStyle: Color,\n\n    // If true, this item represents a hidden dataset. Label will be rendered with a strike-through effect\n    hidden: Boolean,\n\n    // For box border. See https://developer.mozilla.org/en/docs/Web/API/CanvasRenderingContext2D/lineCap\n    lineCap: String,\n\n    // For box border. See https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/setLineDash\n    lineDash: Array[Number],\n\n    // For box border. See https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/lineDashOffset\n    lineDashOffset: Number,\n\n    // For box border. See https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/lineJoin\n    lineJoin: String,\n\n    // Width of box border\n    lineWidth: Number,\n\n    // Stroke style of the legend box\n    strokeStyle: Color\n\n    // Point style of the legend box (only used if usePointStyle is true)\n    pointStyle: String\n}\n```\n\n## Example\n\nThe following example will create a chart with the legend enabled and turn all of the text red in color.\n\n```javascript\nvar chart = new Chart(ctx, {\n    type: 'bar',\n    data: data,\n    options: {\n        legend: {\n            display: true,\n            labels: {\n                fontColor: 'rgb(255, 99, 132)'\n            }\n        }\n}\n});\n```\n\n## Custom On Click Actions\n\nIt can be common to want to trigger different behaviour when clicking an item in the legend. This can be easily achieved using a callback in the config object.\n\nThe default legend click handler is:\n```javascript\nfunction(e, legendItem) {\n    var index = legendItem.datasetIndex;\n    var ci = this.chart;\n    var meta = ci.getDatasetMeta(index);\n\n    // See controller.isDatasetVisible comment\n    meta.hidden = meta.hidden === null? !ci.data.datasets[index].hidden : null;\n\n    // We hid a dataset ... rerender the chart\n    ci.update();\n}\n```\n\nLets say we wanted instead to link the display of the first two datasets. We could change the click handler accordingly.\n\n```javascript\nvar defaultLegendClickHandler = Chart.defaults.global.legend.onClick;\nvar newLegendClickHandler = function (e, legendItem) {\n    var index = legendItem.datasetIndex;\n\n    if (index > 1) {\n        // Do the original logic\n        defaultLegendClickHandler(e, legendItem);\n    } else {\n        let ci = this.chart;\n        [ci.getDatasetMeta(0),\n         ci.getDatasetMeta(1)].forEach(function(meta) {\n            meta.hidden = meta.hidden === null? !ci.data.datasets[index].hidden : null;\n        });\n        ci.update();\n    }\n};\n\nvar chart = new Chart(ctx, {\n    type: 'line',\n    data: data,\n    options: {\n        legend: {\n\n        }\n    }\n});\n```\n\nNow when you click the legend in this chart, the visibility of the first two datasets will be linked together.\n\n## HTML Legends\n\nSometimes you need a very complex legend. In these cases, it makes sense to generate an HTML legend. Charts provide a `generateLegend()` method on their prototype that returns an HTML string for the legend.\n\nTo configure how this legend is generated, you can change the `legendCallback` config property.\n\n```javascript\nvar chart = new Chart(ctx, {\n    type: 'line',\n    data: data,\n    options: {\n        legendCallback: function(chart) {\n            // Return the HTML string here.\n        }\n    }\n});\n```"
  },
  {
    "path": "app_backend/static/plugin/Chart.js-2.6.0/docs/configuration/title.md",
    "content": "# Title\n\nThe chart title defines text to draw at the top of the chart.\n\n## Title Configuration\nThe title configuration is passed into the `options.title` namespace. The global options for the chart title is defined in `Chart.defaults.global.title`.\n\n| Name | Type | Default | Description\n| -----| ---- | --------| -----------\n| `display` | `Boolean` | `false` | is the title shown\n| `position` | `String` | `'top'` | Position of title. [more...](#position)\n| `fontSize` | `Number` | `12` | Font size\n| `fontFamily` | `String` |  `\"'Helvetica Neue', 'Helvetica', 'Arial', sans-serif\"` | Font family for the title text.\n| `fontColor` | Color | `'#666'` | Font color\n| `fontStyle` | `String` | `'bold'` | Font style\n| `padding` | `Number` | `10` | Number of pixels to add above and below the title text.\n| `text` | `String` | `''` | Title text ti display\n\n### Position\nPossible title position values are:\n* `'top'`\n* `'left'`\n* `'bottom'`\n* `'right'`\n\n## Example Usage\n\nThe example below would enable a title of 'Custom Chart Title' on the chart that is created.\n\n```javascript\nvar chart = new Chart(ctx, {\n    type: 'line',\n    data: data,\n    options: {\n        title: {\n            display: true,\n            text: 'Custom Chart Title'\n        }\n    }\n})\n```\n"
  },
  {
    "path": "app_backend/static/plugin/Chart.js-2.6.0/docs/configuration/tooltip.md",
    "content": "# Tooltips\n\n## Tooltip Configuration\n\nThe tooltip configuration is passed into the `options.tooltips` namespace. The global options for the chart tooltips is defined in `Chart.defaults.global.tooltips`.\n\n| Name | Type | Default | Description\n| -----| ---- | --------| -----------\n| `enabled` | `Boolean` | `true` | Are tooltips enabled\n| `custom` | `Function` | `null` | See [custom tooltip](#custom-tooltips) section.\n| `mode` | `String` | `'nearest'` | Sets which elements appear in the tooltip. [more...](../general/interactions/modes.md#interaction-modes).\n| `intersect` | `Boolean` | `true` | if true, the tooltip mode applies only when the mouse position intersects with an element. If false, the mode will be applied at all times.\n| `position` | `String` | `'average'` | The mode for positioning the tooltip. [more...](#position-modes)\n| `callbacks` | `Object` | | See the [callbacks section](#tooltip-callbacks)\n| `itemSort` | `Function` | | Sort tooltip items. [more...](#sort-callback)\n| `filter` | `Function` | | Filter tooltip items. [more...](#filter-callback)\n| `backgroundColor` | Color | `'rgba(0,0,0,0.8)'` | Background color of the tooltip.\n| `titleFontFamily` | `String` | `\"'Helvetica Neue', 'Helvetica', 'Arial', sans-serif\"` | title font\n| `titleFontSize` | `Number` | `12` | Title font size\n| `titleFontStyle` | `String` | `'bold'` | Title font style\n| `titleFontColor` | Color | `'#fff'` | Title font color\n| `titleSpacing` | `Number` | `2` | Spacing to add to top and bottom of each title line.\n| `titleMarginBottom` | `Number` | `6` | Margin to add on bottom of title section.\n| `bodyFontFamily` | `String` | `\"'Helvetica Neue', 'Helvetica', 'Arial', sans-serif\"` | body line font\n| `bodyFontSize` | `Number` | `12` | Body font size\n| `bodyFontStyle` | `String` | `'normal'` | Body font style\n| `bodyFontColor` | Color | `'#fff'` | Body font color\n| `bodySpacing` | `Number` | `2` | Spacing to add to top and bottom of each tooltip item.\n| `footerFontFamily` | `String` | `\"'Helvetica Neue', 'Helvetica', 'Arial', sans-serif\"` | footer font\n| `footerFontSize` | `Number` | `12` | Footer font size\n| `footerFontStyle` | `String` | `'bold'` | Footer font style\n| `footerFontColor` | Color | `'#fff'` | Footer font color\n| `footerSpacing` | `Number` | `2` | Spacing to add to top and bottom of each fotter line.\n| `footerMarginTop` | `Number` | `6` | Margin to add before drawing the footer.\n| `xPadding` | `Number` | `6` | Padding to add on left and right of tooltip.\n| `yPadding` | `Number` | `6` | Padding to add on top and bottom of tooltip.\n| `caretPadding` | `Number` | `2` | Extra distance to move the end of the tooltip arrow away from the tooltip point.\n| `caretSize` | `Number` | `5` | Size, in px, of the tooltip arrow.\n| `cornerRadius` | `Number` | `6` | Radius of tooltip corner curves.\n| `multiKeyBackground` | Color | `'#fff'` | Color to draw behind the colored boxes when multiple items are in the tooltip\n| `displayColors` | `Boolean` | `true` | if true, color boxes are shown in the tooltip\n| `borderColor` | Color | `'rgba(0,0,0,0)'` | Color of the border\n| `borderWidth` | `Number` | `0` | Size of the border\n\n### Position Modes\n Possible modes are:\n* 'average'\n* 'nearest'\n\n'average' mode will place the tooltip at the average position of the items displayed in the tooltip. 'nearest' will place the tooltip at the position of the element closest to the event position.\n\nNew modes can be defined by adding functions to the Chart.Tooltip.positioners map.\n\n### Sort Callback\n\nAllows sorting of [tooltip items](#chart-configuration-tooltip-item-interface). Must implement at minimum a function that can be passed to [Array.prototype.sort](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort).  This function can also accept a third parameter that is the data object passed to the chart.\n\n### Filter Callback\n\nAllows filtering of [tooltip items](#chart-configuration-tooltip-item-interface). Must implement at minimum a function that can be passed to [Array.prototype.filter](https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Array/filter). This function can also accept a second parameter that is the data object passed to the chart.\n\n## Tooltip Callbacks\n\nThe tooltip label configuration is nested below the tooltip configuration using the `callbacks` key. The tooltip has the following callbacks for providing text. For all functions, 'this' will be the tooltip object created from the Chart.Tooltip constructor.\n\nAll functions are called with the same arguments: a [tooltip item](#chart-configuration-tooltip-item-interface) and the data object passed to the chart. All functions must return either a string or an array of strings. Arrays of strings are treated as multiple lines of text.\n\n| Name | Arguments | Description\n| ---- | --------- | -----------\n| `beforeTitle` | `Array[tooltipItem], data` | Returns the text to render before the title.\n| `title` | `Array[tooltipItem], data` | Returns text to render as the title of the tooltip.\n| `afterTitle` | `Array[tooltipItem], data` | Returns text to render after the title.\n| `beforeBody` | `Array[tooltipItem], data` | Returns text to render before the body section.\n| `beforeLabel` | `tooltipItem, data` | Returns text to render before an individual label. This will be called for each item in the tooltip.\n| `label` | `tooltipItem, data` | Returns text to render for an individual item in the tooltip.\n| `labelColor` | `tooltipItem, chart` | Returns the colors to render for the tooltip item. [more...](#label-color-callback)\n| `afterLabel` | `tooltipItem, data` | Returns text to render after an individual label.\n| `afterBody` | `Array[tooltipItem], data` | Returns text to render after the body section\n| `beforeFooter` | `Array[tooltipItem], data` | Returns text to render before the footer section.\n| `footer` | `Array[tooltipItem], data` | Returns text to render as the footer of the tooltip.\n| `afterFooter` | `Array[tooltipItem], data` | Text to render after the footer section\n\n### Label Color Callback\n\nFor example, to return a red box for each item in the tooltip you could do:\n```javascript\nvar chart = new Chart(ctx, {\n    type: 'line',\n    data: data,\n    options: {\n        tooltips: {\n            callbacks: {\n                labelColor: function(tooltipItem, chart) {\n                    return {\n                        borderColor: 'rgb(255, 0, 0)',\n                        backgroundColor: 'rgb(255, 0, 0)'\n                    }\n                }\n            }\n        }\n    }\n});\n```\n\n\n### Tooltip Item Interface\n\nThe tooltip items passed to the tooltip callbacks implement the following interface.\n\n```javascript\n{\n    // X Value of the tooltip as a string\n    xLabel: String,\n\n    // Y value of the tooltip as a string\n    yLabel: String,\n\n    // Index of the dataset the item comes from\n    datasetIndex: Number,\n\n    // Index of this data item in the dataset\n    index: Number,\n\n    // X position of matching point\n    x: Number,\n\n    // Y position of matching point\n    y: Number,\n}\n```\n\n## External (Custom) Tooltips\n\nCustom tooltips allow you to hook into the tooltip rendering process so that you can render the tooltip in your own custom way. Generally this is used to create an HTML tooltip instead of an oncanvas one. You can enable custom tooltips in the global or chart configuration like so:\n\n```javascript\nvar myPieChart = new Chart(ctx, {\n    type: 'pie',\n    data: data,\n    options: {\n        tooltips: {\n            custom: function(tooltipModel) {\n                // Tooltip Element\n                var tooltipEl = document.getElementById('chartjs-tooltip');\n\n                // Create element on first render\n                if (!tooltipEl) {\n                    tooltipEl = document.createElement('div');\n                    tooltipEl.id = 'chartjs-tooltip';\n                    tooltipEl.innerHTML = \"<table></table>\"\n                    document.body.appendChild(tooltipEl);\n                }\n\n                // Hide if no tooltip\n                if (tooltipModel.opacity === 0) {\n                    tooltipEl.style.opacity = 0;\n                    return;\n                }\n\n                // Set caret Position\n                tooltipEl.classList.remove('above', 'below', 'no-transform');\n                if (tooltipModel.yAlign) {\n                    tooltipEl.classList.add(tooltipModel.yAlign);\n                } else {\n                    tooltipEl.classList.add('no-transform');\n                }\n\n                function getBody(bodyItem) {\n                    return bodyItem.lines;\n                }\n\n                // Set Text\n                if (tooltipModel.body) {\n                    var titleLines = tooltipModel.title || [];\n                    var bodyLines = tooltipModel.body.map(getBody);\n\n                    var innerHtml = '<thead>';\n\n                    titleLines.forEach(function(title) {\n                        innerHtml += '<tr><th>' + title + '</th></tr>';\n                    });\n                    innerHtml += '</thead><tbody>';\n\n                    bodyLines.forEach(function(body, i) {\n                        var colors = tooltipModel.labelColors[i];\n                        var style = 'background:' + colors.backgroundColor;\n                        style += '; border-color:' + colors.borderColor;\n                        style += '; border-width: 2px';\n                        var span = '<span class=\"chartjs-tooltip-key\" style=\"' + style + '\"></span>';\n                        innerHtml += '<tr><td>' + span + body + '</td></tr>';\n                    });\n                    innerHtml += '</tbody>';\n\n                    var tableRoot = tooltipEl.querySelector('table');\n                    tableRoot.innerHTML = innerHtml;\n                }\n\n                // `this` will be the overall tooltip\n                var position = this._chart.canvas.getBoundingClientRect();\n\n                // Display, position, and set styles for font\n                tooltipEl.style.opacity = 1;\n                tooltipEl.style.left = position.left + tooltipModel.caretX + 'px';\n                tooltipEl.style.top = position.top + tooltipModel.caretY + 'px';\n                tooltipEl.style.fontFamily = tooltipModel._fontFamily;\n                tooltipEl.style.fontSize = tooltipModel.fontSize;\n                tooltipEl.style.fontStyle = tooltipModel._fontStyle;\n                tooltipEl.style.padding = tooltipModel.yPadding + 'px ' + tooltipModel.xPadding + 'px';\n            }\n        }\n    }\n});\n```\n\nSee `samples/tooltips/line-customTooltips.html` for examples on how to get started.\n\n## Tooltip Model\nThe tooltip model contains parameters that can be used to render the tooltip.\n\n```javascript\n{\n    // The items that we are rendering in the tooltip. See Tooltip Item Interface section\n    dataPoints: TooltipItem[],\n\n    // Positioning\n    xPadding: Number,\n    yPadding: Number,\n    xAlign: String,\n    yAlign: String,\n\n    // X and Y properties are the top left of the tooltip\n    x: Number,\n    y: Number,\n    width: Number,\n    height: Number,\n    // Where the tooltip points to\n    caretX: Number,\n    caretY: Number,\n\n    // Body\n    // The body lines that need to be rendered\n    // Each pbject contains 3 parameters\n    // before: String[] // lines of text before the line with the color square\n    // lines: String[], // lines of text to render as the main item with color square\n    // after: String[], // lines of text to render after the main lines\n    body: Object[],\n    // lines of text that appear after the title but before the body\n    beforeBody: String[],\n    // line of text that appear after the body and before the footer\n    afterBody: String[],\n    bodyFontColor: Color,\n    _bodyFontFamily: String,\n    _bodyFontStyle: String,\n    _bodyAlign: String,\n    bodyFontSize: Number,\n    bodySpacing: Number,\n\n    // Title\n    // lines of text that form the title\n    title: String[],\n    titleFontColor: Color,\n    _titleFontFamily: String,\n    _titleFontStyle: String,\n    titleFontSize: Number,\n    _titleAlign: String,\n    titleSpacing: Number,\n    titleMarginBottom: Number,\n\n    // Footer\n    // lines of text that form the footer\n    footer: String[],\n    footerFontColor: Color,\n    _footerFontFamily: String,\n    _footerFontStyle: String,\n    footerFontSize: Number,\n    _footerAlign: String,\n    footerSpacing: Number,\n    footerMarginTop: Number,\n\n    // Appearance\n    caretSize: Number,\n    cornerRadius: Number,\n    backgroundColor: Color,\n\n    // colors to render for each item in body[]. This is the color of the squares in the tooltip\n    labelColors: Color[],\n\n    // 0 opacity is a hidden tooltip\n    opacity: Number,\n    legendColorBackground: Color,\n    displayColors: Boolean,\n}\n```\n"
  },
  {
    "path": "app_backend/static/plugin/Chart.js-2.6.0/docs/developers/README.md",
    "content": "# Developers\nDeveloper features allow extending and enhancing Chart.js in many different ways.\n\n# Browser support\n\nChart.js offers support for all browsers where canvas is supported.\n\nBrowser support for the canvas element is available in all modern & major mobile browsers. [CanIUse](http://caniuse.com/#feat=canvas)\n\nThanks to [BrowserStack](https://browserstack.com) for allowing our team to test on thousands of browsers.\n\n# Previous versions\n\nVersion 2 has a completely different API than earlier versions.\n\nMost earlier version options have current equivalents or are the same.\n\nPlease use the documentation that is available on [chartjs.org](http://www.chartjs.org/docs/) for the current version of Chart.js.\n\nPlease note - documentation for previous versions are available on the GitHub repo.\n\n- [1.x Documentation](https://github.com/chartjs/Chart.js/tree/v1.1.1/docs)"
  },
  {
    "path": "app_backend/static/plugin/Chart.js-2.6.0/docs/developers/api.md",
    "content": "# Chart Prototype Methods\n\nFor each chart, there are a set of global prototype methods on the shared `ChartType` which you may find useful. These are available on all charts created with Chart.js, but for the examples, let's use a line chart we've made.\n\n```javascript\n// For example:\nvar myLineChart = new Chart(ctx, config);\n```\n\n## .destroy()\n\nUse this to destroy any chart instances that are created. This will clean up any references stored to the chart object within Chart.js, along with any associated event listeners attached by Chart.js.\nThis must be called before the canvas is reused for a new chart.\n\n```javascript\n// Destroys a specific chart instance\nmyLineChart.destroy();\n```\n\n## .update(duration, lazy)\n\nTriggers an update of the chart. This can be safely called after updating the data object. This will update all scales, legends, and then re-render the chart.\n\n```javascript\n// duration is the time for the animation of the redraw in milliseconds\n// lazy is a boolean. if true, the animation can be interrupted by other animations\nmyLineChart.data.datasets[0].data[2] = 50; // Would update the first dataset's value of 'March' to be 50\nmyLineChart.update(); // Calling update now animates the position of March from 90 to 50.\n```\n\n> **Note:** replacing the data reference (e.g. `myLineChart.data = {datasets: [...]}` only works starting **version 2.6**. Prior that, replacing the entire data object could be achieved with the following workaround: `myLineChart.config.data = {datasets: [...]}`.\n\nSee [Updating Charts](updates.md) for more details.\n\n## .reset()\n\nReset the chart to it's state before the initial animation. A new animation can then be triggered using `update`.\n\n```javascript\nmyLineChart.reset();\n```\n\n## .render(duration, lazy)\n\nTriggers a redraw of all chart elements. Note, this does not update elements for new data. Use `.update()` in that case.\n\n```javascript\n// duration is the time for the animation of the redraw in milliseconds\n// lazy is a boolean. if true, the animation can be interrupted by other animations\nmyLineChart.render(duration, lazy);\n```\n\n## .stop()\n\nUse this to stop any current animation loop. This will pause the chart during any current animation frame. Call `.render()` to re-animate.\n\n```javascript\n// Stops the charts animation loop at its current frame\nmyLineChart.stop();\n// => returns 'this' for chainability\n```\n\n## .resize()\n\nUse this to manually resize the canvas element. This is run each time the canvas container is resized, but you can call this method manually if you change the size of the canvas nodes container element.\n\n```javascript\n// Resizes & redraws to fill its container element\nmyLineChart.resize();\n// => returns 'this' for chainability\n```\n\n## .clear()\n\nWill clear the chart canvas. Used extensively internally between animation frames, but you might find it useful.\n\n```javascript\n// Will clear the canvas that myLineChart is drawn on\nmyLineChart.clear();\n// => returns 'this' for chainability\n```\n\n## .toBase64Image()\n\nThis returns a base 64 encoded string of the chart in it's current state.\n\n```javascript\nmyLineChart.toBase64Image();\n// => returns png data url of the image on the canvas\n```\n\n## .generateLegend()\n\nReturns an HTML string of a legend for that chart. The legend is generated from the `legendCallback` in the options.\n\n```javascript\nmyLineChart.generateLegend();\n// => returns HTML string of a legend for this chart\n```\n\n## .getElementAtEvent(e)\n\nCalling `getElementAtEvent(event)` on your Chart instance passing an argument of an event, or jQuery event, will return the single element at the event position. If there are multiple items within range, only the first is returned. The value returned from this method is an array with a single parameter. An array is used to keep a consistent API between the `get*AtEvent` methods.\n\n```javascript\nmyLineChart.getElementAtEvent(e);\n// => returns the first element at the event point.\n```\n\n## .getElementsAtEvent(e)\n\nLooks for the element under the event point, then returns all elements at the same data index. This is used internally for 'label' mode highlighting.\n\nCalling `getElementsAtEvent(event)` on your Chart instance passing an argument of an event, or jQuery event, will return the point elements that are at that the same position of that event.\n\n```javascript\ncanvas.onclick = function(evt){\n    var activePoints = myLineChart.getElementsAtEvent(evt);\n    // => activePoints is an array of points on the canvas that are at the same position as the click event.\n};\n```\n\nThis functionality may be useful for implementing DOM based tooltips, or triggering custom behaviour in your application.\n\n## .getDatasetAtEvent(e)\n\nLooks for the element under the event point, then returns all elements from that dataset. This is used internally for 'dataset' mode highlighting\n\n```javascript\nmyLineChart.getDatasetAtEvent(e);\n// => returns an array of elements\n```\n\n## .getDatasetMeta(index)\n\nLooks for the dataset that matches the current index and returns that metadata. This returned data has all of the metadata that is used to construct the chart.\n\nThe `data` property of the metadata will contain information about each point, rectangle, etc. depending on the chart type.\n\nExtensive examples of usage are available in the [Chart.js tests](https://github.com/chartjs/Chart.js/tree/master/test).\n\n```javascript\nvar meta = myChart.getDatasetMeta(0);\nvar x = meta.data[0]._model.x\n```\n"
  },
  {
    "path": "app_backend/static/plugin/Chart.js-2.6.0/docs/developers/axes.md",
    "content": "# New Axes\n\nAxes in Chart.js can be individually extended. Axes should always derive from Chart.Scale but this is not a mandatory requirement.\n\n```javascript\nlet MyScale = Chart.Scale.extend({\n    /* extensions ... */\n});\n\n// MyScale is now derived from Chart.Scale\n```\n\nOnce you have created your scale class, you need to register it with the global chart object so that it can be used. A default config for the scale may be provided when registering the constructor. The first parameter to the register function is a string key that is used later to identify which scale type to use for a chart.\n\n```javascript\nChart.scaleService.registerScaleType('myScale', MyScale, defaultConfigObject);\n```\n\nTo use the new scale, simply pass in the string key to the config when creating a chart.\n\n```javascript\nvar lineChart = new Chart(ctx, {\n    data: data,\n    type: 'line',\n    options: {\n        scales: {\n            yAxes: [{\n                type: 'myScale' // this is the same key that was passed to the registerScaleType function\n            }]\n        }\n    }\n})\n```\n\n## Scale Properties\n\nScale instances are given the following properties during the fitting process.\n\n```javascript\n{\n    left: Number, // left edge of the scale bounding box\n    right: Number, // right edge of the bounding box'\n    top: Number,\n    bottom: Number,\n    width: Number, // the same as right - left\n    height: Number, // the same as bottom - top\n\n    // Margin on each side. Like css, this is outside the bounding box.\n    margins: {\n        left: Number,\n        right: Number,\n        top: Number,\n        bottom: Number,\n    },\n\n    // Amount of padding on the inside of the bounding box (like CSS)\n    paddingLeft: Number,\n    paddingRight: Number,\n    paddingTop: Number,\n    paddingBottom: Number,\n}\n```\n\n## Scale Interface\nTo work with Chart.js, custom scale types must implement the following interface.\n\n```javascript\n{\n    // Determines the data limits. Should set this.min and this.max to be the data max/min\n    determineDataLimits: function() {},\n\n    // Generate tick marks. this.chart is the chart instance. The data object can be accessed as this.chart.data\n    // buildTicks() should create a ticks array on the axis instance, if you intend to use any of the implementations from the base class\n    buildTicks: function() {},\n\n    // Get the value to show for the data at the given index of the the given dataset, ie this.chart.data.datasets[datasetIndex].data[index]\n    getLabelForIndex: function(index, datasetIndex) {},\n\n    // Get the pixel (x coordinate for horizontal axis, y coordinate for vertical axis) for a given value\n    // @param index: index into the ticks array\n    // @param includeOffset: if true, get the pixel halway between the given tick and the next\n    getPixelForTick: function(index, includeOffset) {},\n\n    // Get the pixel (x coordinate for horizontal axis, y coordinate for vertical axis) for a given value\n    // @param value : the value to get the pixel for\n    // @param index : index into the data array of the value\n    // @param datasetIndex : index of the dataset the value comes from\n    // @param includeOffset : if true, get the pixel halway between the given tick and the next\n    getPixelForValue: function(value, index, datasetIndex, includeOffset) {}\n\n    // Get the value for a given pixel (x coordinate for horizontal axis, y coordinate for vertical axis)\n    // @param pixel : pixel value\n    getValueForPixel: function(pixel) {}\n}\n```\n\nOptionally, the following methods may also be overwritten, but an implementation is already provided by the `Chart.Scale` base class.\n\n```javascript\n    // Transform the ticks array of the scale instance into strings. The default implementation simply calls this.options.ticks.callback(numericalTick, index, ticks);\n    convertTicksToLabels: function() {},\n\n    // Determine how much the labels will rotate by. The default implementation will only rotate labels if the scale is horizontal.\n    calculateTickRotation: function() {},\n\n    // Fits the scale into the canvas.\n    // this.maxWidth and this.maxHeight will tell you the maximum dimensions the scale instance can be. Scales should endeavour to be as efficient as possible with canvas space.\n    // this.margins is the amount of space you have on either side of your scale that you may expand in to. This is used already for calculating the best label rotation\n    // You must set this.minSize to be the size of your scale. It must be an object containing 2 properties: width and height.\n    // You must set this.width to be the width and this.height to be the height of the scale\n    fit: function() {},\n\n    // Draws the scale onto the canvas. this.(left|right|top|bottom) will have been populated to tell you the area on the canvas to draw in\n    // @param chartArea : an object containing four properties: left, right, top, bottom. This is the rectangle that lines, bars, etc will be drawn in. It may be used, for example, to draw grid lines.\n    draw: function(chartArea) {},\n```\n\nThe Core.Scale base class also has some utility functions that you may find useful.\n```javascript\n{\n    // Returns true if the scale instance is horizontal\n    isHorizontal: function() {},\n\n    // Get the correct value from the value from this.chart.data.datasets[x].data[]\n    // If dataValue is an object, returns .x or .y depending on the return of isHorizontal()\n    // If the value is undefined, returns NaN\n    // Otherwise returns the value.\n    // Note that in all cases, the returned value is not guaranteed to be a Number\n    getRightValue: function(dataValue) {},\n}\n```"
  },
  {
    "path": "app_backend/static/plugin/Chart.js-2.6.0/docs/developers/charts.md",
    "content": "# New Charts\n\nChart.js 2.0 introduces the concept of controllers for each dataset. Like scales, new controllers can be written as needed.\n\n```javascript\nChart.controllers.MyType = Chart.DatasetController.extend({\n\n});\n\n\n// Now we can create a new instance of our chart, using the Chart.js API\nnew Chart(ctx, {\n    // this is the string the constructor was registered at, ie Chart.controllers.MyType\n    type: 'MyType',\n    data: data,\n    options: options\n});\n```\n\n## Dataset Controller Interface\n\nDataset controllers must implement the following interface.\n\n```javascript\n{\n    // Create elements for each piece of data in the dataset. Store elements in an array on the dataset as dataset.metaData\n    addElements: function() {},\n\n    // Create a single element for the data at the given index and reset its state\n    addElementAndReset: function(index) {},\n\n    // Draw the representation of the dataset\n    // @param ease : if specified, this number represents how far to transition elements. See the implementation of draw() in any of the provided controllers to see how this should be used\n    draw: function(ease) {},\n\n    // Remove hover styling from the given element\n    removeHoverStyle: function(element) {},\n\n    // Add hover styling to the given element\n    setHoverStyle: function(element) {},\n\n    // Update the elements in response to new data\n    // @param reset : if true, put the elements into a reset state so they can animate to their final values\n    update: function(reset) {},\n}\n```\n\nThe following methods may optionally be overridden by derived dataset controllers\n```javascript\n{\n    // Initializes the controller\n    initialize: function(chart, datasetIndex) {},\n\n    // Ensures that the dataset represented by this controller is linked to a scale. Overridden to helpers.noop in the polar area and doughnut controllers as these\n    // chart types using a single scale\n    linkScales: function() {},\n\n    // Called by the main chart controller when an update is triggered. The default implementation handles the number of data points changing and creating elements appropriately.\n    buildOrUpdateElements: function() {}\n}\n```\n\n## Extending Existing Chart Types\n\nExtending or replacing an existing controller type is easy. Simply replace the constructor for one of the built in types with your own.\n\nThe built in controller types are:\n* `Chart.controllers.line`\n* `Chart.controllers.bar`\n* `Chart.controllers.radar`\n* `Chart.controllers.doughnut`\n* `Chart.controllers.polarArea`\n* `Chart.controllers.bubble`\n\nFor example, to derive a new chart type that extends from a bubble chart, you would do the following.\n\n```javascript\n// Sets the default config for 'derivedBubble' to be the same as the bubble defaults. \n// We look for the defaults by doing Chart.defaults[chartType]\n// It looks like a bug exists when the defaults don't exist\nChart.defaults.derivedBubble = Chart.defaults.bubble;\n\n// I think the recommend using Chart.controllers.bubble.extend({ extensions here });\nvar custom = Chart.controllers.bubble.extend({\n    draw: function(ease) {\n        // Call super method first\n        Chart.controllers.bubble.prototype.draw.call(this, ease);\n\n        // Now we can do some custom drawing for this dataset. Here we'll draw a red box around the first point in each dataset\n        var meta = this.getMeta();\n        var pt0 = meta.data[0];\n        var radius = pt0._view.radius;\n\n        var ctx = this.chart.chart.ctx;\n        ctx.save();\n        ctx.strokeStyle = 'red';\n        ctx.lineWidth = 1;\n        ctx.strokeRect(pt0._view.x - radius, pt0._view.y - radius, 2 * radius, 2 * radius);\n        ctx.restore();\n    }\n});\n\n// Stores the controller so that the chart initialization routine can look it up with\n// Chart.controllers[type]\nChart.controllers.derivedBubble = custom; \n\n// Now we can create and use our new chart type\nnew Chart(ctx, {\n    type: 'derivedBubble',\n    data: data,\n    options: options,\n});\n```\n\n### Bar Controller\nThe bar controller has a special property that you should be aware of. To correctly calculate the width of a bar, the controller must determine the number of datasets that map to bars. To do this, the bar controller attaches a property `bar` to the dataset during initialization. If you are creating a replacement or updated bar controller, you should do the same. This will ensure that charts with regular bars and your new derived bars will work seamlessly."
  },
  {
    "path": "app_backend/static/plugin/Chart.js-2.6.0/docs/developers/contributing.md",
    "content": "# Contributing\n\nNew contributions to the library are welcome, but we ask that you please follow these guidelines:\n\n- Use tabs for indentation, not spaces.\n- Only change the individual files in `/src`.\n- Check that your code will pass `eslint` code standards, `gulp lint` will run this for you.\n- Check that your code will pass tests, `gulp test` will run tests for you.\n- Keep pull requests concise, and document new functionality in the relevant `.md` file.\n- Consider whether your changes are useful for all users, or if creating a Chart.js [plugin](plugins.md) would be more appropriate.\n\n# Joining the project\n\n Active committers and contributors are invited to introduce yourself and request commit access to this project. We have a very active Slack community that you can join [here](https://chart-js-automation.herokuapp.com/). If you think you can help, we'd love to have you!\n\n# Building and Testing\n\nChart.js uses <a href=\"http://gulpjs.com/\" target=\"_blank\">gulp</a> to build the library into a single JavaScript file.\n\nFirstly, we need to ensure development dependencies are installed. With node and npm installed, after cloning the Chart.js repo to a local directory, and navigating to that directory in the command line, we can run the following:\n\n```bash\n> npm install\n> npm install -g gulp\n```\n\nThis will install the local development dependencies for Chart.js, along with a CLI for the JavaScript task runner <a href=\"http://gulpjs.com/\" target=\"_blank\">gulp</a>.\n\nThe following commands are now available from the repository root:\n\n```bash\n> gulp build                // build Chart.js in ./dist\n> gulp unittest             // run tests from ./test/specs\n> gulp unittest --watch     // run tests and watch for source changes\n> gulp unittest --coverage  // run tests and generate coverage reports in ./coverage\n> gulp lint                 // perform code linting (ESLint)\n> gulp test                 // perform code linting and run unit tests\n> gulp docs                 // build the documentation in ./dist/docs\n```\n\nMore information can be found in [gulpfile.js](https://github.com/chartjs/Chart.js/blob/master/gulpfile.js).\n\n# Bugs and Issues\n\nPlease report these on the GitHub page - at <a href=\"https://github.com/chartjs/Chart.js\" target=\"_blank\">github.com/chartjs/Chart.js</a>. Please do not use issues for support requests. For help using Chart.js, please take a look at the [`chartjs`](http://stackoverflow.com/questions/tagged/chartjs) tag on Stack Overflow.\n\nWell structured, detailed bug reports are hugely valuable for the project.\n\nGuidelines for reporting bugs:\n\n - Check the issue search to see if it has already been reported\n - Isolate the problem to a simple test case\n - Please include a demonstration of the bug on a website such as [JS Bin](http://jsbin.com/), [JS Fiddle](http://jsfiddle.net/), or [Codepen](http://codepen.io/pen/). ([Template](http://codepen.io/pen?template=JXVYzq))\n\nPlease provide any additional details associated with the bug, if it's browser or screen density specific, or only happens with a certain configuration or data.\n"
  },
  {
    "path": "app_backend/static/plugin/Chart.js-2.6.0/docs/developers/plugins.md",
    "content": "# Plugins\n\nPlugins are the most efficient way to customize or change the default behavior of a chart. They have been introduced at [version 2.1.0](https://github.com/chartjs/Chart.js/releases/tag/2.1.0) (global plugins only) and extended at [version 2.5.0](https://github.com/chartjs/Chart.js/releases/tag/2.5.0) (per chart plugins and options).\n\n## Using plugins\n\nPlugins can be shared between chart instances:\n\n```javascript\nvar plugin = { /* plugin implementation */ };\n\n// chart1 and chart2 use \"plugin\"\nvar chart1 = new Chart(ctx, {\n    plugins: [plugin]\n});\n\nvar chart2 = new Chart(ctx, {\n    plugins: [plugin]\n});\n\n// chart3 doesn't use \"plugin\"\nvar chart3 = new Chart(ctx, {});\n```\n\nPlugins can also be defined directly in the chart `plugins` config (a.k.a. *inline plugins*):\n\n```javascript\nvar chart = new Chart(ctx, {\n    plugins: [{\n        beforeInit: function(chart, options) {\n            //..\n        }\n    }]\n});\n```\n\nHowever, this approach is not ideal when the customization needs to apply to many charts.\n\n## Global plugins\n\nPlugins can be registered globally to be applied on all charts (a.k.a. *global plugins*):\n\n```javascript\nChart.plugins.register({\n    // plugin implementation\n});\n```\n\n> Note: *inline* plugins can't be registered globally.\n\n## Configuration\n\n### Plugin ID\n\nPlugins must define a unique id in order to be configurable.\n\nThis id should follow the [npm package name convention](https://docs.npmjs.com/files/package.json#name):\n\n- can't start with a dot or an underscore\n- can't contain any non-URL-safe characters\n- can't contain uppercase letters\n- should be something short, but also reasonably descriptive\n\nIf a plugin is intended to be released publicly, you may want to check the [registry](https://www.npmjs.com/search?q=chartjs-plugin-) to see if there's something by that name already. Note that in this case, the package name should be prefixed by `chartjs-plugin-` to appear in Chart.js plugin registry.\n\n### Plugin options\n\nPlugin options are located under the `options.plugins` config and are scoped by the plugin ID: `options.plugins.{plugin-id}`.\n\n```javascript\nvar chart = new Chart(ctx, {\n    config: {\n        foo: { ... },           // chart 'foo' option\n        plugins: {\n            p1: {\n                foo: { ... },   // p1 plugin 'foo' option\n                bar: { ... }\n            },\n            p2: {\n                foo: { ... },   // p2 plugin 'foo' option\n                bla: { ... }\n            }\n        }\n    }\n});\n```\n\n#### Disable plugins\n\nTo disable a global plugin for a specific chart instance, the plugin options must be set to `false`:\n\n```javascript\nChart.plugins.register({\n    id: 'p1',\n    // ...\n});\n\nvar chart = new Chart(ctx, {\n    config: {\n        plugins: {\n            p1: false   // disable plugin 'p1' for this instance\n        }\n    }\n});\n```\n\n## Plugin Core API\n\nAvailable hooks (as of version 2.5):\n\n* beforeInit\n* afterInit\n* beforeUpdate *(cancellable)*\n* afterUpdate\n* beforeLayout *(cancellable)*\n* afterLayout\n* beforeDatasetsUpdate *(cancellable)*\n* afterDatasetsUpdate\n* beforeRender *(cancellable)*\n* afterRender\n* beforeDraw *(cancellable)*\n* afterDraw\n* beforeDatasetsDraw *(cancellable)*\n* afterDatasetsDraw\n* beforeEvent *(cancellable)*\n* afterEvent\n* resize\n* destroy\n"
  },
  {
    "path": "app_backend/static/plugin/Chart.js-2.6.0/docs/developers/updates.md",
    "content": "# Updating Charts\n\nIt's pretty common to want to update charts after they've been created. When the chart data is changed, Chart.js will animate to the new data values. \n\n## Adding or Removing Data\n\nAdding and removing data is supported by changing the data array. To add data, just add data into the data array as seen in this example.\n\n```javascript\nfunction addData(chart, label, data) {\n    chart.data.labels.push(label);\n    chart.data.datasets.forEach((dataset) => {\n        dataset.data.push(data);\n    });\n    chart.update();\n}\n```\n\n```javascript\nfunction removeData(chart) {\n    chart.data.labels.pop();\n    chart.data.datasets.forEach((dataset) => {\n        dataset.data.pop();\n    });\n    chart.update();\n}\n```\n\n## Preventing Animations\n\nSometimes when a chart updates, you may not want an animation. To achieve this you can call `update` with a duration of `0`. This will render the chart synchronously and without an animation."
  },
  {
    "path": "app_backend/static/plugin/Chart.js-2.6.0/docs/general/README.md",
    "content": "# General Chart.js Configuration\n\nThese sections describe general configuration options that can apply elsewhere in the documentation. \n\n* [Colors](./colors.md) defines acceptable color values\n* [Font](./fonts.md) defines various font options\n* [Interactions](./interactions/README.md) defines options that reflect how hovering chart elements works\n* [Responsive](./responsive.md) defines responsive chart options that apply to all charts."
  },
  {
    "path": "app_backend/static/plugin/Chart.js-2.6.0/docs/general/colors.md",
    "content": "# Colors\n\nWhen supplying colors to Chart options, you can use a number of formats. You can specify the color as a string in hexadecimal, RGB, or HSL notations. If a color is needed, but not specified, Chart.js will use the global default color. This color is stored at `Chart.defaults.global.defaultColor`. It is initially set to `'rgba(0, 0, 0, 0.1)'`\n\nYou can also pass a [CanvasGradient](https://developer.mozilla.org/en-US/docs/Web/API/CanvasGradient) object. You will need to create this before passing to the chart, but using it you can achieve some interesting effects.\n\n## Patterns and Gradients\n\nAn alternative option is to pass a [CanvasPattern](https://developer.mozilla.org/en-US/docs/Web/API/CanvasPattern) or [CanvasGradient](https://developer.mozilla.org/en/docs/Web/API/CanvasGradient) object instead of a string colour. \n\nFor example, if you wanted to fill a dataset with a pattern from an image you could do the following.\n\n```javascript\nvar img = new Image();\nimg.src = 'https://example.com/my_image.png';\nimg.onload = function() {\n    var ctx = document.getElementById('canvas').getContext('2d');\n    var fillPattern = ctx.createPattern(img, 'repeat');\n\n    var chart = new Chart(ctx, {\n        data: {\n            labels: ['Item 1', 'Item 2', 'Item 3'],\n            datasets: [{\n                data: [10, 20, 30],\n                backgroundColor: fillPattern\n            }]\n        }\n    })\n}\n```\n\nUsing pattern fills for data graphics can help viewers with vision deficiencies (e.g. color-blindness or partial sight) to [more easily understand your data](http://betweentwobrackets.com/data-graphics-and-colour-vision/).\n\nUsing the [Patternomaly](https://github.com/ashiguruma/patternomaly) library you can generate patterns to fill datasets.\n\n```javascript\nvar chartData = {\n    datasets: [{\n        data: [45, 25, 20, 10],\n        backgroundColor: [\n            pattern.draw('square', '#ff6384'),\n            pattern.draw('circle', '#36a2eb'),\n            pattern.draw('diamond', '#cc65fe'),\n            pattern.draw('triangle', '#ffce56'),\n        ]\n    }],\n    labels: ['Red', 'Blue', 'Purple', 'Yellow']\n};\n```"
  },
  {
    "path": "app_backend/static/plugin/Chart.js-2.6.0/docs/general/fonts.md",
    "content": "# Fonts\n\nThere are 4 special global settings that can change all of the fonts on the chart. These options are in `Chart.defaults.global`. The global font settings only apply when more specific options are not included in the config.\n\nFor example, in this chart the text will all be red except for the labels in the legend.\n\n```javascript\nChart.defaults.global.defaultFontColor = 'red';\nlet chart = new Chart(ctx, {\n    type: 'line',\n    data: data,\n    options: {\n        legend: {\n            labels: {\n                // This more specific font property overrides the global property\n                fontColor: 'black'\n            }\n        }\n    }\n});\n```\n\n| Name | Type | Default | Description\n| ---- | ---- | ------- | -----------\n| `defaultFontColor` | `Color` | `'#666'` | Default font color for all text.\n| `defaultFontFamily` | `String` | `\"'Helvetica Neue', 'Helvetica', 'Arial', sans-serif\"` | Default font family for all text.\n| `defaultFontSize` | `Number` | `12` | Default font size (in px) for text. Does not apply to radialLinear scale point labels.\n| `defaultFontStyle` | `String` | `'normal'` | Default font style. Does not apply to tooltip title or footer. Does not apply to chart title.\n"
  },
  {
    "path": "app_backend/static/plugin/Chart.js-2.6.0/docs/general/interactions/README.md",
    "content": "# Interactions\n\nThe hover configuration is passed into the `options.hover` namespace. The global hover configuration is at `Chart.defaults.global.hover`. To configure which events trigger chart interactions, see [events](./events.md#events). \n\n| Name | Type | Default | Description\n| ---- | ---- | ------- | -----------\n| `mode` | `String` | `'nearest'` | Sets which elements appear in the tooltip. See [Interaction Modes](./modes.md#interaction-modes) for details.\n| `intersect` | `Boolean` | `true` | if true, the hover mode only applies when the mouse position intersects an item on the chart.\n| `animationDuration` | `Number` | `400` | Duration in milliseconds it takes to animate hover style changes."
  },
  {
    "path": "app_backend/static/plugin/Chart.js-2.6.0/docs/general/interactions/events.md",
    "content": "# Events\nThe following properties define how the chart interacts with events.\n\n| Name | Type | Default | Description\n| ---- | ---- | ------- | -----------\n| `events` | `String[]` | `[\"mousemove\", \"mouseout\", \"click\", \"touchstart\", \"touchmove\", \"touchend\"]` | The `events` option defines the browser events that the chart should listen to for tooltips and hovering. [more...](#event-option)\n| `onHover` | `Function` | `null` | Called when any of the events fire. Called in the context of the chart and passed the event and an array of active elements (bars, points, etc).\n| `onClick` | `Function` | `null` | Called if the event is of type 'mouseup' or 'click'. Called in the context of the chart and passed the event and an array of active elements\n\n## Event Option \nFor example, to have the chart only respond to click events, you could do\n```javascript\nvar chart = new Chart(ctx, {\n    type: 'line',\n    data: data,\n    options: {\n        // This chart will not respond to mousemove, etc\n        events: ['click']\n    }\n});\n```\n"
  },
  {
    "path": "app_backend/static/plugin/Chart.js-2.6.0/docs/general/interactions/modes.md",
    "content": "# Interaction Modes\n\nWhen configuring interaction with the graph via hover or tooltips, a number of different modes are available.\n\nThe modes are detailed below and how they behave in conjunction with the `intersect` setting.\n\n## point\nFinds all of the items that intersect the point.\n\n```javascript\nvar chart = new Chart(ctx, {\n    type: 'line',\n    data: data,\n    options: {\n        tooltips: {\n            mode: 'point'\n        }\n    }\n})\n```\n\n## nearest\nGets the item that is nearest to the point. The nearest item is determined based on the distance to the center of the chart item (point, bar). If 2 or more items are at the same distance, the one with the smallest area is used. If `intersect` is true, this is only triggered when the mouse position intersects an item in the graph. This is very useful for combo charts where points are hidden behind bars.\n\n```javascript\nvar chart = new Chart(ctx, {\n    type: 'line',\n    data: data,\n    options: {\n        tooltips: {\n            mode: 'nearest'\n        }\n    }\n})\n```\n\n## single (deprecated)\nFinds the first item that intersects the point and returns it. Behaves like 'nearest' mode with intersect = true.\n\n## label (deprecated)\nSee `'index'` mode\n\n## index\nFinds item at the same index. If the `intersect` setting is true, the first intersecting item is used to determine the index in the data. If `intersect` false the nearest item is used to determine the index. \n\n```javascript\nvar chart = new Chart(ctx, {\n    type: 'line',\n    data: data,\n    options: {\n        tooltips: {\n            mode: 'index'\n        }\n    }\n})\n```\n\n## x-axis (deprecated)\nBehaves like `'index'` mode with `intersect = false`.\n\n## dataset\nFinds items in the same dataset. If the `intersect` setting is true, the first intersecting item is used to determine the index in the data. If `intersect` false the nearest item is used to determine the index.\n\n```javascript\nvar chart = new Chart(ctx, {\n    type: 'line',\n    data: data,\n    options: {\n        tooltips: {\n            mode: 'dataset'\n        }\n    }\n})\n```\n\n## x\nReturns all items that would intersect based on the `X` coordinate of the position only. Would be useful for a vertical cursor implementation. Note that this only applies to cartesian charts\n\n```javascript\nvar chart = new Chart(ctx, {\n    type: 'line',\n    data: data,\n    options: {\n        tooltips: {\n            mode: 'x'\n        }\n    }\n})\n```\n\n## y\nReturns all items that would intersect based on the `Y` coordinate of the position. This would be useful for a horizontal cursor implementation. Note that this only applies to cartesian charts.\n\n```javascript\nvar chart = new Chart(ctx, {\n    type: 'line',\n    data: data,\n    options: {\n        tooltips: {\n            mode: 'y'\n        }\n    }\n})\n```"
  },
  {
    "path": "app_backend/static/plugin/Chart.js-2.6.0/docs/general/responsive.md",
    "content": "# Responsive Charts\n\nWhen it comes to change the chart size based on the window size, a major limitation is that the canvas *render* size (`canvas.width` and `.height`) can **not** be expressed with relative values, contrary to the *display* size (`canvas.style.width` and `.height`). Furthermore, these sizes are independent from each other and thus the canvas *render* size does not adjust automatically based on the *display* size, making the rendering inaccurate.\n\nThe following examples **do not work**:\n\n- `<canvas height=\"40vh\" width=\"80vw\">`: **invalid** values, the canvas doesn't resize ([example](https://codepen.io/chartjs/pen/oWLZaR))\n- `<canvas style=\"height:40vh; width:80vw\">`: **invalid** behavior, the canvas is resized but becomes blurry ([example](https://codepen.io/chartjs/pen/WjxpmO))\n\nChart.js provides a [few options](#configuration-options) to enable responsiveness and control the resize behavior of charts by detecting when the canvas *display* size changes and update the *render* size accordingly.\n\n## Configuration Options\n\n| Name | Type | Default | Description\n| ---- | ---- | ------- | -----------\n| `responsive` | `Boolean` | `true` | Resizes the chart canvas when its container does ([important note...](#important-note)).\n| `responsiveAnimationDuration` | `Number` | `0` | Duration in milliseconds it takes to animate to new size after a resize event.\n| `maintainAspectRatio` | `Boolean` | `true` | Maintain the original canvas aspect ratio `(width / height)` when resizing.\n| `onResize` | `Function` | `null` | Called when a resize occurs. Gets passed two arguments: the chart instance and the new size.\n\n## Important Note\n\nDetecting when the canvas size changes can not be done directly from the `CANVAS` element. Chart.js uses its parent container to update the canvas *render* and *display* sizes. However, this method requires the container to be **relatively positioned** and **dedicated to the chart canvas only**. Responsiveness can then be achieved by setting relative values for the container size ([example](https://codepen.io/chartjs/pen/YVWZbz)):\n\n```html\n<div class=\"chart-container\" style=\"position: relative; height:40vh; width:80vw\">\n    <canvas id=\"chart\"></canvas>\n</div>\n```\n\nThe chart can also be programmatically resized by modifying the container size:\n\n```javascript\nchart.canvas.parentNode.style.height = '128px';\n```\n"
  },
  {
    "path": "app_backend/static/plugin/Chart.js-2.6.0/docs/getting-started/README.md",
    "content": "# Getting Started\n\nLet's get started using Chart.js!\n\nFirst, we need to have a canvas in our page.\n\n```html\n<canvas id=\"myChart\"></canvas>\n```\n\nNow that we have a canvas we can use, we need to include Chart.js in our page.\n\n```html\n<script src=\"https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.4.0/Chart.min.js\" />\n```\n\nNow, we can create a chart. We add a script to our page:\n\n```javascript\nvar ctx = document.getElementById('myChart').getContext('2d');\nvar chart = new Chart(ctx, {\n    // The type of chart we want to create\n    type: 'line',\n\n    // The data for our dataset\n    data: {\n        labels: [\"January\", \"February\", \"March\", \"April\", \"May\", \"June\", \"July\"],\n        datasets: [{\n            label: \"My First dataset\",\n            backgroundColor: 'rgb(255, 99, 132)',\n            borderColor: 'rgb(255, 99, 132)',\n            data: [0, 10, 5, 2, 20, 30, 45],\n        }]\n    },\n\n    // Configuration options go here\n    options: {}\n});\n```\n\nIt's that easy to get started using Chart.js! From here you can explore the many options that can help you customise your charts with scales, tooltips, labels, colors, custom actions, and much more.\n\nThere are many examples of Chart.js that are available in the `/samples` folder of `Chart.js.zip` that is attatched to every [release](https://github.com/chartjs/Chart.js/releases)."
  },
  {
    "path": "app_backend/static/plugin/Chart.js-2.6.0/docs/getting-started/installation.md",
    "content": "# Installation\nChart.js can be installed via npm or bower. It is recommended to get Chart.js this way.\n\n## npm\n\n```bash\nnpm install chart.js --save\n```\n\n## Bower\n\n```bash\nbower install chart.js --save\n```\n\n## CDN\nor just use these [Chart.js CDN](https://cdnjs.com/libraries/Chart.js) links.\n\n\n## Github\nYou can download the latest version of [Chart.js on GitHub](https://github.com/chartjs/Chart.js/releases/latest).\n\nIf you download or clone the repository, you must [build](../developers/contributing.md#building-chartjs) Chart.js to generate the dist files. Chart.js no longer comes with prebuilt release versions, so an alternative option to downloading the repo is **strongly** advised.\n\n# Selecting the Correct Build\n\nChart.js provides two different builds that are available for your use.\n\n## Stand-Alone Build\nFiles:\n* `dist/Chart.js`\n* `dist/Chart.min.js`\n\nThis version only includes Chart.js. If this version is used and you require the use of the time axis, [Moment.js](http://momentjs.com/) will need to be included before Chart.js.\n\n## Bundled Build\nFiles:\n* `dist/Chart.bundle.js`\n* `dist/Chart.bundle.min.js`\n\nThe bundled version includes Moment.js built into the same file. This version should be used if you wish to use time axes and want a single file to include. Do not use this build if your application already includes Moment.js. If you do, Moment.js will be included twice, increasing the page load time and potentially introducing version issues."
  },
  {
    "path": "app_backend/static/plugin/Chart.js-2.6.0/docs/getting-started/integration.md",
    "content": "# Integration\n\nChart.js can be integrated with plain JavaScript or with different module loaders. The examples below show how to load Chart.js in different systems.\n\n## ES6 Modules\n\n```javascript\nimport Chart from 'chart.js';\nvar myChart = new Chart(ctx, {...});\n```\n\n## Script Tag\n\n```html\n<script src=\"path/to/chartjs/dist/Chart.js\"></script>\n<script>\n    var myChart = new Chart(ctx, {...});\n</script>\n```\n\n## Common JS\n\n```javascript\nvar Chart = require('chart.js');\nvar myChart = new Chart(ctx, {...});\n```\n\n## Require JS\n\n```javascript\nrequire(['path/to/chartjs/dist/Chart.js'], function(Chart){\n    var myChart = new Chart(ctx, {...});\n});\n```\n\n> **Important:** RequireJS [can **not** load CommonJS module as is](http://www.requirejs.org/docs/commonjs.html#intro), so be sure to require one of the built UMD files instead (i.e. `dist/Chart.js`, `dist/Chart.min.js`, etc.).\n"
  },
  {
    "path": "app_backend/static/plugin/Chart.js-2.6.0/docs/getting-started/usage.md",
    "content": "# Usage\nChart.js can be used with ES6 modules, plain JavaScript and module loaders.\n\n## Creating a Chart\n\nTo create a chart, we need to instantiate the `Chart` class. To do this, we need to pass in the node, jQuery instance, or 2d context of the canvas of where we want to draw the chart. Here's an example.\n\n```html\n<canvas id=\"myChart\" width=\"400\" height=\"400\"></canvas>\n```\n\n```javascript\n// Any of the following formats may be used\nvar ctx = document.getElementById(\"myChart\");\nvar ctx = document.getElementById(\"myChart\").getContext(\"2d\");\nvar ctx = $(\"#myChart\");\nvar ctx = \"myChart\";\n```\n\nOnce you have the element or context, you're ready to instantiate a pre-defined chart-type or create your own!\n\nThe following example instantiates a bar chart showing the number of votes for different colors and the y-axis starting at 0.\n\n```html\n<canvas id=\"myChart\" width=\"400\" height=\"400\"></canvas>\n<script>\nvar ctx = document.getElementById(\"myChart\");\nvar myChart = new Chart(ctx, {\n    type: 'bar',\n    data: {\n        labels: [\"Red\", \"Blue\", \"Yellow\", \"Green\", \"Purple\", \"Orange\"],\n        datasets: [{\n            label: '# of Votes',\n            data: [12, 19, 3, 5, 2, 3],\n            backgroundColor: [\n                'rgba(255, 99, 132, 0.2)',\n                'rgba(54, 162, 235, 0.2)',\n                'rgba(255, 206, 86, 0.2)',\n                'rgba(75, 192, 192, 0.2)',\n                'rgba(153, 102, 255, 0.2)',\n                'rgba(255, 159, 64, 0.2)'\n            ],\n            borderColor: [\n                'rgba(255,99,132,1)',\n                'rgba(54, 162, 235, 1)',\n                'rgba(255, 206, 86, 1)',\n                'rgba(75, 192, 192, 1)',\n                'rgba(153, 102, 255, 1)',\n                'rgba(255, 159, 64, 1)'\n            ],\n            borderWidth: 1\n        }]\n    },\n    options: {\n        scales: {\n            yAxes: [{\n                ticks: {\n                    beginAtZero:true\n                }\n            }]\n        }\n    }\n});\n</script>\n```"
  },
  {
    "path": "app_backend/static/plugin/Chart.js-2.6.0/docs/notes/README.md",
    "content": "# Additional Notes"
  },
  {
    "path": "app_backend/static/plugin/Chart.js-2.6.0/docs/notes/comparison.md",
    "content": "# Comparison with Other Charting Libraries\n\nLibrary Features\n\n| Feature | Chart.js | D3 | HighCharts | Chartist |\n| ------- | -------- | --- | ---------- | -------- |\n| Completely Free | &check; | &check; | | &check; |\n| Canvas | &check; | | | |\n| SVG | | &check; | &check; | &check; |\n| Built-in Charts | &check; | | &check; | &check; |\n| 8+ Chart Types | &check; | &check; | &check; | |\n| Extendable to Custom Charts | &check; | &check; | |  |\n| Supports Modern Browsers | &check; | &check; | &check; | &check; |\n| Extensive Documentation | &check; | &check; | &check; | &check; |\n| Open Source | &check; | &check; | &check; | &check; |\n\nBuilt in Chart Types\n\n| Type | Chart.js | HighCharts | Chartist |\n| ---- | -------- | ---------- | -------- |\n| Combined Types | &check; | &check; | |\n| Line | &check; | &check; | &check; |\n| Bar | &check; | &check; | &check; |\n| Horizontal Bar | &check; | &check; | &check; |\n| Pie/Doughnut | &check; | &check; | &check; |\n| Polar Area | &check; | &check; | |\n| Radar | &check; |  | |\n| Scatter | &check; | &check; | &check; |\n| Bubble | &check; | | |\n| Gauges | | &check; | |\n| Maps (Heat/Tree/etc.) | | &check; | |\n\n"
  },
  {
    "path": "app_backend/static/plugin/Chart.js-2.6.0/docs/notes/extensions.md",
    "content": "# Popular Extensions\n\nMany extensions can be found on the [Chart.js GitHub organization](https://github.com/chartjs) or on the [npm registry](https://www.npmjs.com/search?q=chartjs-).\n\n## Charts\n\n - <a href=\"https://github.com/chartjs/chartjs-chart-financial\" target=\"_blank\">chartjs-chart-financial</a> - Adds financial chart types such as a candlestick.\n - <a href=\"https://github.com/chartjs/Chart.BarFunnel.js\" target=\"_blank\">Chart.BarFunnel.js</a> - Adds a bar funnel chart type.\n - <a href=\"https://github.com/chartjs/Chart.LinearGauge.js\" target=\"_blank\">Chart.LinearGauge.js</a> - Adds a linear gauge chart type.\n - <a href=\"https://github.com/chartjs/Chart.smith.js\" target=\"_blank\">Chart.Smith.js</a> - Adds a smith chart type.\n\nIn addition, many charts can be found on the [npm registry](https://www.npmjs.com/search?q=chartjs-chart-).\n\n## Plugins\n\n - <a href=\"https://github.com/chartjs/chartjs-plugin-annotation\" target=\"_blank\">chartjs-plugin-annotation.js</a> - Draw lines and boxes on chart area.\n - <a href=\"https://github.com/chartjs/chartjs-plugin-deferred\" target=\"_blank\">chartjs-plugin-deferred.js</a> - Defer initial chart update until chart scrolls into viewport.\n - <a href=\"https://github.com/compwright/chartjs-plugin-draggable\" target=\"_blank\">chartjs-plugin-draggable.js</a> - Makes select chart elements draggable with the mouse.\n - <a href=\"https://github.com/y-takey/chartjs-plugin-stacked100\" target=\"_blank\">chartjs-plugin-stacked100.js</a> - Draw 100% stacked bar chart.\n - <a href=\"https://github.com/chartjs/chartjs-plugin-zoom\" target=\"_blank\">chartjs-plugin-zoom.js</a> - Enable zooming and panning on charts.\n\nIn addition, many plugins can be found on the [npm registry](https://www.npmjs.com/search?q=chartjs-plugin-).\n\n## Integrations\n\n### Angular\n - <a href=\"https://github.com/jtblin/angular-chart.js\" target=\"_blank\">angular-chart.js</a>\n - <a href=\"https://github.com/carlcraig/tc-angular-chartjs\" target=\"_blank\">tc-angular-chartjs</a>\n - <a href=\"https://github.com/petermelias/angular-chartjs\" target=\"_blank\">angular-chartjs</a>\n - <a href=\"https://github.com/earlonrails/angular-chartjs-directive\" target=\"_blank\">Angular Chart-js Directive</a>\n\n### React\n - <a href=\"https://github.com/topdmc/react-chartjs2\" target=\"_blank\">react-chartjs2</a>\n - <a href=\"https://github.com/gor181/react-chartjs-2\" target=\"_blank\">react-chartjs-2</a>\n\n### Django\n - <a href=\"https://github.com/matthisk/django-jchart\" target=\"_blank\">Django JChart</a>\n - <a href=\"https://github.com/novafloss/django-chartjs\" target=\"_blank\">Django Chartjs</a>\n\n### Ruby on Rails\n - <a href=\"https://github.com/airblade/chartjs-ror\" target=\"_blank\">chartjs-ror</a>\n\n### Laravel\n - <a href=\"https://github.com/fxcosta/laravel-chartjs\" target=\"_blank\">laravel-chartjs</a>\n\n### Vue.js\n - <a href=\"https://github.com/apertureless/vue-chartjs/\" target=\"_blank\">vue-chartjs</a>\n"
  },
  {
    "path": "app_backend/static/plugin/Chart.js-2.6.0/docs/notes/license.md",
    "content": "# License\n\nChart.js is <a href=\"https://github.com/chartjs/Chart.js\" target=\"_blank\">open source</a> and available under the <a href=\"http://opensource.org/licenses/MIT\" target=\"_blank\">MIT license</a>."
  },
  {
    "path": "app_backend/static/plugin/Chart.js-2.6.0/docs/style.css",
    "content": "a.anchorjs-link {\n    color: rgba(65, 131, 196, 0.1);\n    font-weight: 400;\n    text-decoration: none;\n    transition: color 100ms ease-out;\n    z-index: 999;\n}\n\na.anchorjs-link:hover {\n    color: rgba(65, 131, 196, 1);\n}\n\nsup {\n    font-size: 0.75em !important;\n}\n"
  },
  {
    "path": "app_backend/static/plugin/Chart.js-2.6.0/gulpfile.js",
    "content": "var gulp = require('gulp');\nvar concat = require('gulp-concat');\nvar connect = require('gulp-connect');\nvar eslint = require('gulp-eslint');\nvar file = require('gulp-file');\nvar htmlv = require('gulp-html-validator');\nvar insert = require('gulp-insert');\nvar replace = require('gulp-replace');\nvar size = require('gulp-size');\nvar streamify = require('gulp-streamify');\nvar uglify = require('gulp-uglify');\nvar util = require('gulp-util');\nvar zip = require('gulp-zip');\nvar exec = require('child-process-promise').exec;\nvar karma = require('karma');\nvar browserify = require('browserify');\nvar source = require('vinyl-source-stream');\nvar merge = require('merge-stream');\nvar collapse = require('bundle-collapser/plugin');\nvar argv  = require('yargs').argv\nvar path = require('path');\nvar package = require('./package.json');\n\nvar srcDir = './src/';\nvar outDir = './dist/';\nvar testDir = './test/';\n\nvar header = \"/*!\\n\" +\n  \" * Chart.js\\n\" +\n  \" * http://chartjs.org/\\n\" +\n  \" * Version: {{ version }}\\n\" +\n  \" *\\n\" +\n  \" * Copyright 2017 Nick Downie\\n\" +\n  \" * Released under the MIT license\\n\" +\n  \" * https://github.com/chartjs/Chart.js/blob/master/LICENSE.md\\n\" +\n  \" */\\n\";\n\ngulp.task('bower', bowerTask);\ngulp.task('build', buildTask);\ngulp.task('package', packageTask);\ngulp.task('watch', watchTask);\ngulp.task('lint', lintTask);\ngulp.task('docs', docsTask);\ngulp.task('test', ['lint', 'validHTML', 'unittest']);\ngulp.task('size', ['library-size', 'module-sizes']);\ngulp.task('server', serverTask);\ngulp.task('validHTML', validHTMLTask);\ngulp.task('unittest', unittestTask);\ngulp.task('library-size', librarySizeTask);\ngulp.task('module-sizes', moduleSizesTask);\ngulp.task('_open', _openTask);\ngulp.task('dev', ['server', 'default']);\ngulp.task('default', ['build', 'watch']);\n\n/**\n * Generates the bower.json manifest file which will be pushed along release tags.\n * Specs: https://github.com/bower/spec/blob/master/json.md\n */\nfunction bowerTask() {\n  var json = JSON.stringify({\n      name: package.name,\n      description: package.description,\n      homepage: package.homepage,\n      license: package.license,\n      version: package.version,\n      main: outDir + \"Chart.js\",\n      ignore: [\n        '.github',\n        '.codeclimate.yml',\n        '.gitignore',\n        '.npmignore',\n        '.travis.yml',\n        'scripts'\n      ]\n    }, null, 2);\n\n  return file('bower.json', json, { src: true })\n    .pipe(gulp.dest('./'));\n}\n\nfunction buildTask() {\n\n  var bundled = browserify('./src/chart.js', { standalone: 'Chart' })\n    .plugin(collapse)\n    .bundle()\n    .pipe(source('Chart.bundle.js'))\n    .pipe(insert.prepend(header))\n    .pipe(streamify(replace('{{ version }}', package.version)))\n    .pipe(gulp.dest(outDir))\n    .pipe(streamify(uglify()))\n    .pipe(insert.prepend(header))\n    .pipe(streamify(replace('{{ version }}', package.version)))\n    .pipe(streamify(concat('Chart.bundle.min.js')))\n    .pipe(gulp.dest(outDir));\n\n  var nonBundled = browserify('./src/chart.js', { standalone: 'Chart' })\n    .ignore('moment')\n    .plugin(collapse)\n    .bundle()\n    .pipe(source('Chart.js'))\n    .pipe(insert.prepend(header))\n    .pipe(streamify(replace('{{ version }}', package.version)))\n    .pipe(gulp.dest(outDir))\n    .pipe(streamify(uglify()))\n    .pipe(insert.prepend(header))\n    .pipe(streamify(replace('{{ version }}', package.version)))\n    .pipe(streamify(concat('Chart.min.js')))\n    .pipe(gulp.dest(outDir));\n\n  return merge(bundled, nonBundled);\n\n}\n\nfunction packageTask() {\n  return merge(\n      // gather \"regular\" files landing in the package root\n      gulp.src([outDir + '*.js', 'LICENSE.md']),\n\n      // since we moved the dist files one folder up (package root), we need to rewrite\n      // samples src=\"../dist/ to src=\"../ and then copy them in the /samples directory.\n      gulp.src('./samples/**/*', { base: '.' })\n        .pipe(streamify(replace(/src=\"((?:\\.\\.\\/)+)dist\\//g, 'src=\"$1')))\n  )\n  // finally, create the zip archive\n  .pipe(zip('Chart.js.zip'))\n  .pipe(gulp.dest(outDir));\n}\n\nfunction lintTask() {\n  var files = [\n    srcDir + '**/*.js',\n    testDir + '**/*.js'\n  ];\n\n  // NOTE(SB) codeclimate has 'complexity' and 'max-statements' eslint rules way too strict\n  // compare to what the current codebase can support, and since it's not straightforward\n  // to fix, let's turn them as warnings and rewrite code later progressively.\n  var options = {\n    rules: {\n      'complexity': [1, 6],\n      'max-statements': [1, 30]\n    },\n    globals: [\n      'Chart',\n      'acquireChart',\n      'afterAll',\n      'afterEach',\n      'beforeAll',\n      'beforeEach',\n      'describe',\n      'expect',\n      'fail',\n      'it',\n      'jasmine',\n      'moment',\n      'spyOn',\n      'xit'\n    ]\n  };\n\n  return gulp.src(files)\n    .pipe(eslint(options))\n    .pipe(eslint.format())\n    .pipe(eslint.failAfterError());\n}\n\nfunction docsTask(done) {\n  const script = require.resolve('gitbook-cli/bin/gitbook.js');\n  const cmd = process.execPath;\n\n  exec([cmd, script, 'install', './'].join(' ')).then(() => {\n    return exec([cmd, script, 'build', './', './dist/docs'].join(' '));\n  }).catch((err) => {\n    console.error(err.stdout);\n  }).then(() => {\n    done();\n  });\n}\n\nfunction validHTMLTask() {\n  return gulp.src('samples/*.html')\n    .pipe(htmlv());\n}\n\nfunction startTest() {\n  return [\n    {pattern: './test/fixtures/**/*.json', included: false},\n    {pattern: './test/fixtures/**/*.png', included: false},\n    './node_modules/moment/min/moment.min.js',\n    './test/jasmine.index.js',\n    './src/**/*.js',\n  ].concat(\n    argv.inputs?\n      argv.inputs.split(';'):\n      ['./test/specs/**/*.js']\n  );\n}\n\nfunction unittestTask(done) {\n  new karma.Server({\n    configFile: path.join(__dirname, 'karma.conf.js'),\n    singleRun: !argv.watch,\n    files: startTest(),\n    args: {\n      coverage: !!argv.coverage\n    }\n  }, done).start();\n}\n\nfunction librarySizeTask() {\n  return gulp.src('dist/Chart.bundle.min.js')\n    .pipe(size({\n      gzip: true\n    }));\n}\n\nfunction moduleSizesTask() {\n  return gulp.src(srcDir + '**/*.js')\n    .pipe(uglify({\n      preserveComments: 'some'\n    }))\n    .pipe(size({\n      showFiles: true,\n      gzip: true\n    }));\n}\n\nfunction watchTask() {\n  if (util.env.test) {\n    return gulp.watch('./src/**', ['build', 'unittest', 'unittestWatch']);\n  }\n  return gulp.watch('./src/**', ['build']);\n}\n\nfunction serverTask() {\n  connect.server({\n    port: 8000\n  });\n}\n\n// Convenience task for opening the project straight from the command line\n\nfunction _openTask() {\n  exec('open http://localhost:8000');\n  exec('subl .');\n}\n"
  },
  {
    "path": "app_backend/static/plugin/Chart.js-2.6.0/karma.conf.js",
    "content": "/* eslint camelcase: 0 */\n\nmodule.exports = function(karma) {\n\tvar args = karma.args || {};\n\tvar config = {\n\t\tbrowsers: ['Firefox'],\n\t\tframeworks: ['browserify', 'jasmine'],\n\t\treporters: ['progress', 'kjhtml'],\n\n\t\tpreprocessors: {\n\t\t\t'./test/jasmine.index.js': ['browserify'],\n\t\t\t'./src/**/*.js': ['browserify']\n\t\t},\n\n\t\tbrowserify: {\n\t\t\tdebug: true\n\t\t}\n\t};\n\n\t// https://swizec.com/blog/how-to-run-javascript-tests-in-chrome-on-travis/swizec/6647\n\tif (process.env.TRAVIS) {\n\t\tconfig.browsers.push('chrome_travis_ci');\n\t\tconfig.customLaunchers = {\n\t\t\tchrome_travis_ci: {\n\t\t\t\tbase: 'Chrome',\n\t\t\t\tflags: ['--no-sandbox']\n\t\t\t}\n\t\t};\n\t} else {\n\t\tconfig.browsers.push('Chrome');\n\t}\n\n\tif (args.coverage) {\n\t\tconfig.reporters.push('coverage');\n\t\tconfig.browserify.transform = ['browserify-istanbul'];\n\n\t\t// https://github.com/karma-runner/karma-coverage/blob/master/docs/configuration.md\n\t\tconfig.coverageReporter = {\n\t\t\tdir: 'coverage/',\n\t\t\treporters: [\n\t\t\t\t{type: 'html', subdir: 'report-html'},\n\t\t\t\t{type: 'lcovonly', subdir: '.', file: 'lcov.info'}\n\t\t\t]\n\t\t};\n\t}\n\n\tkarma.set(config);\n};\n"
  },
  {
    "path": "app_backend/static/plugin/Chart.js-2.6.0/package.json",
    "content": "{\n  \"name\": \"chart.js\",\n  \"homepage\": \"http://www.chartjs.org\",\n  \"description\": \"Simple HTML5 charts using the canvas element.\",\n  \"version\": \"2.6.0\",\n  \"license\": \"MIT\",\n  \"main\": \"src/chart.js\",\n  \"repository\": {\n    \"type\": \"git\",\n    \"url\": \"https://github.com/chartjs/Chart.js.git\"\n  },\n  \"devDependencies\": {\n    \"browserify\": \"^13.0.0\",\n    \"browserify-istanbul\": \"^0.2.1\",\n    \"bundle-collapser\": \"^1.2.1\",\n    \"child-process-promise\": \"^2.2.0\",\n    \"coveralls\": \"^2.11.6\",\n    \"gitbook-cli\": \"^2.3.0\",\n    \"gulp\": \"3.9.x\",\n    \"gulp-concat\": \"~2.1.x\",\n    \"gulp-connect\": \"~2.0.5\",\n    \"gulp-eslint\": \"^3.0.0\",\n    \"gulp-file\": \"^0.3.0\",\n    \"gulp-html-validator\": \"^0.0.2\",\n    \"gulp-insert\": \"~0.5.0\",\n    \"gulp-replace\": \"^0.5.4\",\n    \"gulp-size\": \"~0.4.0\",\n    \"gulp-streamify\": \"^1.0.2\",\n    \"gulp-uglify\": \"~2.0.x\",\n    \"gulp-util\": \"~2.2.x\",\n    \"gulp-zip\": \"~3.2.0\",\n    \"jasmine\": \"^2.5.0\",\n    \"jasmine-core\": \"^2.5.0\",\n    \"karma\": \"^1.5.0\",\n    \"karma-browserify\": \"^5.1.0\",\n    \"karma-chrome-launcher\": \"^2.0.0\",\n    \"karma-coverage\": \"^1.1.0\",\n    \"karma-firefox-launcher\": \"^1.0.0\",\n    \"karma-jasmine\": \"^1.1.0\",\n    \"karma-jasmine-html-reporter\": \"^0.2.2\",\n    \"merge-stream\": \"^1.0.0\",\n    \"pixelmatch\": \"^4.0.2\",\n    \"vinyl-source-stream\": \"^1.1.0\",\n    \"watchify\": \"^3.7.0\",\n    \"yargs\": \"^5.0.0\"\n  },\n  \"spm\": {\n    \"main\": \"Chart.js\"\n  },\n  \"dependencies\": {\n    \"chartjs-color\": \"^2.1.0\",\n    \"moment\": \"^2.10.6\"\n  }\n}\n"
  },
  {
    "path": "app_backend/static/plugin/Chart.js-2.6.0/samples/advanced/data-labelling.html",
    "content": "\n<!doctype html>\n<html>\n\n<head>\n    <title>Labelling Data Points</title>\n    <script src=\"../../dist/Chart.bundle.js\"></script>\n    <script src=\"../utils.js\"></script>\n    <style>\n    canvas {\n        -moz-user-select: none;\n        -webkit-user-select: none;\n        -ms-user-select: none;\n    }\n    </style>\n</head>\n\n<body>\n    <div style=\"width: 75%\">\n        <canvas id=\"canvas\"></canvas>\n    </div>\n    <button id=\"randomizeData\">Randomize Data</button>\n    <script>\n        var color = Chart.helpers.color;\n        var barChartData = {\n            labels: [\"January\", \"February\", \"March\", \"April\", \"May\", \"June\", \"July\"],\n            datasets: [{\n                type: 'bar',\n                label: 'Dataset 1',\n                backgroundColor: color(window.chartColors.red).alpha(0.2).rgbString(),\n                borderColor: window.chartColors.red,\n                data: [\n                    randomScalingFactor(),\n                    randomScalingFactor(),\n                    randomScalingFactor(),\n                    randomScalingFactor(),\n                    randomScalingFactor(),\n                    randomScalingFactor(),\n                    randomScalingFactor()\n                ]\n            }, {\n                type: 'line',\n                label: 'Dataset 2',\n                backgroundColor: color(window.chartColors.blue).alpha(0.2).rgbString(),\n                borderColor: window.chartColors.blue,\n                data: [\n                    randomScalingFactor(),\n                    randomScalingFactor(),\n                    randomScalingFactor(),\n                    randomScalingFactor(),\n                    randomScalingFactor(),\n                    randomScalingFactor(),\n                    randomScalingFactor()\n                ]\n            }, {\n                type: 'bar',\n                label: 'Dataset 3',\n                backgroundColor: color(window.chartColors.green).alpha(0.2).rgbString(),\n                borderColor: window.chartColors.green,\n                data: [\n                    randomScalingFactor(),\n                    randomScalingFactor(),\n                    randomScalingFactor(),\n                    randomScalingFactor(),\n                    randomScalingFactor(),\n                    randomScalingFactor(),\n                    randomScalingFactor()\n                ]\n            }]\n        };\n\n        // Define a plugin to provide data labels\n        Chart.plugins.register({\n            afterDatasetsDraw: function(chart, easing) {\n                // To only draw at the end of animation, check for easing === 1\n                var ctx = chart.ctx;\n\n                chart.data.datasets.forEach(function (dataset, i) {\n                    var meta = chart.getDatasetMeta(i);\n                    if (!meta.hidden) {\n                        meta.data.forEach(function(element, index) {\n                            // Draw the text in black, with the specified font\n                            ctx.fillStyle = 'rgb(0, 0, 0)';\n\n                            var fontSize = 16;\n                            var fontStyle = 'normal';\n                            var fontFamily = 'Helvetica Neue';\n                            ctx.font = Chart.helpers.fontString(fontSize, fontStyle, fontFamily);\n\n                            // Just naively convert to string for now\n                            var dataString = dataset.data[index].toString();\n\n                            // Make sure alignment settings are correct\n                            ctx.textAlign = 'center';\n                            ctx.textBaseline = 'middle';\n\n                            var padding = 5;\n                            var position = element.tooltipPosition();\n                            ctx.fillText(dataString, position.x, position.y - (fontSize / 2) - padding);\n                        });\n                    }\n                });\n            }\n        });\n\n        window.onload = function() {\n            var ctx = document.getElementById(\"canvas\").getContext(\"2d\");\n            window.myBar = new Chart(ctx, {\n                type: 'bar',\n                data: barChartData,\n                options: {\n                    responsive: true,\n                    title: {\n                        display: true,\n                        text: 'Chart.js Combo Bar Line Chart'\n                    },\n                }\n            });\n        };\n\n        document.getElementById('randomizeData').addEventListener('click', function() {\n            barChartData.datasets.forEach(function(dataset) {\n                dataset.data = dataset.data.map(function() {\n                    return randomScalingFactor();\n                })\n            });\n            window.myBar.update();\n        });\n    </script>\n</body>\n\n</html>\n"
  },
  {
    "path": "app_backend/static/plugin/Chart.js-2.6.0/samples/advanced/progress-bar.html",
    "content": "<!doctype html>\n<html>\n<head>\n\t<title> Animation Callbacks </title>\n    <script src=\"../../dist/Chart.bundle.js\"></script>\n    <script src=\"../utils.js\"></script>\n    <style>\n    canvas {\n        -moz-user-select: none;\n        -webkit-user-select: none;\n        -ms-user-select: none;\n    }\n    </style>\n</head>\n\n<body>\n    <div style=\"width: 75%;\">\n        <canvas id=\"canvas\"></canvas>\n        <progress id=\"animationProgress\" max=\"1\" value=\"0\" style=\"width: 100%\"></progress>\n    </div>\n    <br>\n    <br>\n    <button id=\"randomizeData\">Randomize Data</button>\n    <script>\n        var MONTHS = [\"January\", \"February\", \"March\", \"April\", \"May\", \"June\", \"July\", \"August\", \"September\", \"October\", \"November\", \"December\"];\n        var progress = document.getElementById('animationProgress');\n        var config = {\n            type: 'line',\n            data: {\n                labels: [\"January\", \"February\", \"March\", \"April\", \"May\", \"June\", \"July\"],\n                datasets: [{\n                    fill: false,\n                    borderColor: window.chartColors.red,\n                    backgroundColor: window.chartColors.red,\n                    data: [\n                        randomScalingFactor(),\n                        randomScalingFactor(),\n                        randomScalingFactor(),\n                        randomScalingFactor(),\n                        randomScalingFactor(),\n                        randomScalingFactor(),\n                        randomScalingFactor()\n                    ]\n                }, {\n                    label: \"My Second dataset \",\n                    fill: false,\n                    borderColor: window.chartColors.blue,\n                    backgroundColor: window.chartColors.blue,\n                    data: [\n                        randomScalingFactor(),\n                        randomScalingFactor(),\n                        randomScalingFactor(),\n                        randomScalingFactor(),\n                        randomScalingFactor(),\n                        randomScalingFactor(),\n                        randomScalingFactor()\n                    ]\n                }]\n            },\n            options: {\n                title:{\n                    display:true,\n                    text: \"Chart.js Line Chart - Animation Progress Bar\"\n                },\n                animation: {\n                    duration: 2000,\n                    onProgress: function(animation) {\n                        progress.value = animation.currentStep / animation.numSteps;\n                    },\n                    onComplete: function(animation) {\n                        window.setTimeout(function() {\n                            progress.value = 0;\n                        }, 2000);\n                    }\n                }\n            }\n        };\n\n        window.onload = function() {\n            var ctx = document.getElementById(\"canvas\").getContext(\"2d\");\n            window.myLine = new Chart(ctx, config);\n        };\n\n        document.getElementById('randomizeData').addEventListener('click', function() {\n            config.data.datasets.forEach(function(dataset) {\n                dataset.data = dataset.data.map(function() {\n                    return randomScalingFactor();\n                });\n            });\n\n            window.myLine.update();\n        });\n    </script>\n</body>\n\n</html>"
  },
  {
    "path": "app_backend/static/plugin/Chart.js-2.6.0/samples/charts/area/analyser.js",
    "content": "/* global Chart */\n\n'use strict';\n\n(function() {\n\tChart.plugins.register({\n\t\tid: 'samples_filler_analyser',\n\n\t\tbeforeInit: function(chart, options) {\n\t\t\tthis.element = document.getElementById(options.target);\n\t\t},\n\n\t\tafterUpdate: function(chart) {\n\t\t\tvar datasets = chart.data.datasets;\n\t\t\tvar element = this.element;\n\t\t\tvar stats = [];\n\t\t\tvar meta, i, ilen, dataset;\n\n\t\t\tif (!element) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tfor (i=0, ilen=datasets.length; i<ilen; ++i) {\n\t\t\t\tmeta = chart.getDatasetMeta(i).$filler;\n\t\t\t\tif (meta) {\n\t\t\t\t\tdataset = datasets[i];\n\t\t\t\t\tstats.push({\n\t\t\t\t\t\tfill: dataset.fill,\n\t\t\t\t\t\ttarget: meta.fill,\n\t\t\t\t\t\tvisible: meta.visible,\n\t\t\t\t\t\tindex: i\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tthis.element.innerHTML = '<table>' +\n\t\t\t\t'<tr>' +\n\t\t\t\t\t'<th>Dataset</th>' +\n\t\t\t\t\t'<th>Fill</th>' +\n\t\t\t\t\t'<th>Target (visibility)</th>' +\n\t\t\t\t'</tr>' +\n\t\t\t\tstats.map(function(stat) {\n\t\t\t\t\tvar target = stat.target;\n\t\t\t\t\tvar row =\n\t\t\t\t\t\t'<td><b>' + stat.index + '</b></td>' +\n\t\t\t\t\t\t'<td>' + JSON.stringify(stat.fill) + '</td>';\n\n\t\t\t\t\tif (target === false) {\n\t\t\t\t\t\ttarget = 'none';\n\t\t\t\t\t} else if (isFinite(target)) {\n\t\t\t\t\t\ttarget = 'dataset ' + target;\n\t\t\t\t\t} else {\n\t\t\t\t\t\ttarget = 'boundary \"' + target + '\"';\n\t\t\t\t\t}\n\n\t\t\t\t\tif (stat.visible) {\n\t\t\t\t\t\trow += '<td>' + target + '</td>';\n\t\t\t\t\t} else {\n\t\t\t\t\t\trow += '<td>(hidden)</td>';\n\t\t\t\t\t}\n\n\t\t\t\t\treturn '<tr>' + row + '</tr>';\n\t\t\t\t}).join('') + '</table>';\n\t\t}\n\t});\n}());\n"
  },
  {
    "path": "app_backend/static/plugin/Chart.js-2.6.0/samples/charts/area/line-boundaries.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en-US\">\n<head>\n\t<meta charset=\"utf-8\">\n\t<meta http-equiv=\"X-UA-Compatible\" content=\"IE=Edge\">\n\t<meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">\n\t<title>area > boundaries | Chart.js sample</title>\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../style.css\">\n\t<script src=\"../../../dist/Chart.bundle.js\"></script>\n\t<script src=\"../../utils.js\"></script>\n\t<script src=\"analyser.js\"></script>\n</head>\n<body>\n\t<div class=\"content\">\n\t\t<div class=\"wrapper col-2\"><canvas id=\"chart-0\"></canvas></div>\n\t\t<div class=\"wrapper col-2\"><canvas id=\"chart-1\"></canvas></div>\n\t\t<div class=\"wrapper col-2\"><canvas id=\"chart-2\"></canvas></div>\n\t\t<div class=\"wrapper col-2\"><canvas id=\"chart-3\"></canvas></div>\n\n\t\t<div class=\"toolbar\">\n\t\t\t<button onclick=\"toggleSmooth(this)\">Smooth</button>\n\t\t\t<button onclick=\"randomize(this)\">Randomize</button>\n\t\t</div>\n\t</div>\n\n\t<script>\n\t\tvar presets = window.chartColors;\n\t\tvar utils = Samples.utils;\n\t\tvar inputs = {\n\t\t\tmin: -100,\n\t\t\tmax: 100,\n\t\t\tcount: 8,\n\t\t\tdecimals: 2,\n\t\t\tcontinuity: 1\n\t\t};\n\n\t\tfunction generateData(config) {\n\t\t\treturn utils.numbers(utils.merge(inputs, config || {}));\n\t\t}\n\n\t\tfunction generateLabels(config) {\n\t\t\treturn utils.months(utils.merge({\n\t\t\t\tcount: inputs.count,\n\t\t\t\tsection: 3\n\t\t\t}, config || {}));\n\t\t}\n\n\t\tvar options = {\n\t\t\tmaintainAspectRatio: false,\n\t\t\tspanGaps: false,\n\t\t\telements: {\n\t\t\t\tline: {\n\t\t\t\t\ttension: 0.000001\n\t\t\t\t}\n\t\t\t},\n\t\t\tplugins: {\n\t\t\t\tfiller: {\n\t\t\t\t\tpropagate: false\n\t\t\t\t}\n\t\t\t},\n\t\t\tscales: {\n\t\t\t\txAxes: [{\n\t\t\t\t\tticks: {\n\t\t\t\t\t\tautoSkip: false,\n\t\t\t\t\t\tmaxRotation: 0\n\t\t\t\t\t}\n\t\t\t\t}]\n\t\t\t}\n\t\t};\n\n\t\t[false, 'origin', 'start', 'end'].forEach(function(boundary, index) {\n\n\t\t\t// reset the random seed to generate the same data for all charts\n\t\t\tutils.srand(8);\n\n\t\t\tnew Chart('chart-' + index, {\n\t\t\t\ttype: 'line',\n\t\t\t\tdata: {\n\t\t\t\t\tlabels: generateLabels(),\n\t\t\t\t\tdatasets: [{\n\t\t\t\t\t\tbackgroundColor: utils.transparentize(presets.red),\n\t\t\t\t\t\tborderColor: presets.red,\n\t\t\t\t\t\tdata: generateData(),\n\t\t\t\t\t\tlabel: 'Dataset',\n\t\t\t\t\t\tfill: boundary\n\t\t\t\t\t}]\n\t\t\t\t},\n\t\t\t\toptions: utils.merge(options, {\n\t\t\t\t\ttitle: {\n\t\t\t\t\t\ttext: 'fill: ' + boundary,\n\t\t\t\t\t\tdisplay: true\n\t\t\t\t\t}\n\t\t\t\t})\n\t\t\t});\n\t\t});\n\n\n\t\tfunction toggleSmooth(btn) {\n\t\t\tvar value = btn.classList.toggle('btn-on');\n\t\t\tChart.helpers.each(Chart.instances, function(chart) {\n\t\t\t\tchart.options.elements.line.tension = value? 0.4 : 0.000001;\n\t\t\t\tchart.update();\n\t\t\t});\n\t\t}\n\n\t\tfunction randomize() {\n\t\t\tvar seed = utils.rand();\n\t\t\tChart.helpers.each(Chart.instances, function(chart) {\n\t\t\t\tutils.srand(seed);\n\n\t\t\t\tchart.data.datasets.forEach(function(dataset) {\n\t\t\t\t\tdataset.data = generateData();\n\t\t\t\t});\n\n\t\t\t\tchart.update();\n\t\t\t});\n\t\t}\n\t</script>\n</body>\n</html>\n"
  },
  {
    "path": "app_backend/static/plugin/Chart.js-2.6.0/samples/charts/area/line-datasets.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en-US\">\n<head>\n\t<meta charset=\"utf-8\">\n\t<meta http-equiv=\"X-UA-Compatible\" content=\"IE=Edge\">\n\t<meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">\n\t<title>area > datasets | Chart.js sample</title>\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../style.css\">\n\t<script src=\"../../../dist/Chart.bundle.js\"></script>\n\t<script src=\"../../utils.js\"></script>\n\t<script src=\"analyser.js\"></script>\n</head>\n<body>\n\t<div class=\"content\">\n\t\t<div class=\"wrapper\">\n\t\t\t<canvas id=\"chart-0\"></canvas>\n\t\t</div>\n\t\t<div class=\"toolbar\">\n\t\t\t<button onclick=\"togglePropagate(this)\">Propagate</button>\n\t\t\t<button onclick=\"toggleSmooth(this)\">Smooth</button>\n\t\t\t<button onclick=\"randomize(this)\">Randomize</button>\n\t\t</div>\n\t\t<div id=\"chart-analyser\" class=\"analyser\"></div>\n\t</div>\n\n\t<script>\n\t\tvar presets = window.chartColors;\n\t\tvar utils = Samples.utils;\n\t\tvar inputs = {\n\t\t\tmin: 20,\n\t\t\tmax: 80,\n\t\t\tcount: 8,\n\t\t\tdecimals: 2,\n\t\t\tcontinuity: 1\n\t\t};\n\n\t\tfunction generateData() {\n\t\t\treturn utils.numbers(inputs);\n\t\t}\n\n\t\tfunction generateLabels(config) {\n\t\t\treturn utils.months({count: inputs.count});\n\t\t}\n\n\t\tutils.srand(42);\n\n\t\tvar data = {\n\t\t\tlabels: generateLabels(),\n\t\t\tdatasets: [{\n\t\t\t\tbackgroundColor: utils.transparentize(presets.red),\n\t\t\t\tborderColor: presets.red,\n\t\t\t\tdata: generateData(),\n\t\t\t\thidden: true,\n\t\t\t\tlabel: 'D0'\n\t\t\t}, {\n\t\t\t\tbackgroundColor: utils.transparentize(presets.orange),\n\t\t\t\tborderColor: presets.orange,\n\t\t\t\tdata: generateData(),\n\t\t\t\tlabel: 'D1',\n\t\t\t\tfill: '-1'\n\t\t\t}, {\n\t\t\t\tbackgroundColor: utils.transparentize(presets.yellow),\n\t\t\t\tborderColor: presets.yellow,\n\t\t\t\tdata: generateData(),\n\t\t\t\thidden: true,\n\t\t\t\tlabel: 'D2',\n\t\t\t\tfill: 1\n\t\t\t}, {\n\t\t\t\tbackgroundColor: utils.transparentize(presets.green),\n\t\t\t\tborderColor: presets.green,\n\t\t\t\tdata: generateData(),\n\t\t\t\tlabel: 'D3',\n\t\t\t\tfill: '-1'\n\t\t\t}, {\n\t\t\t\tbackgroundColor: utils.transparentize(presets.blue),\n\t\t\t\tborderColor: presets.blue,\n\t\t\t\tdata: generateData(),\n\t\t\t\tlabel: 'D4',\n\t\t\t\tfill: '-1'\n\t\t\t}, {\n\t\t\t\tbackgroundColor: utils.transparentize(presets.grey),\n\t\t\t\tborderColor: presets.grey,\n\t\t\t\tdata: generateData(),\n\t\t\t\tlabel: 'D5',\n\t\t\t\tfill: '+2'\n\t\t\t}, {\n\t\t\t\tbackgroundColor: utils.transparentize(presets.purple),\n\t\t\t\tborderColor: presets.purple,\n\t\t\t\tdata: generateData(),\n\t\t\t\tlabel: 'D6',\n\t\t\t\tfill: false\n\t\t\t}, {\n\t\t\t\tbackgroundColor: utils.transparentize(presets.red),\n\t\t\t\tborderColor: presets.red,\n\t\t\t\tdata: generateData(),\n\t\t\t\tlabel: 'D7',\n\t\t\t\tfill: 8\n\t\t\t}, {\n\t\t\t\tbackgroundColor: utils.transparentize(presets.orange),\n\t\t\t\tborderColor: presets.orange,\n\t\t\t\tdata: generateData(),\n\t\t\t\thidden: true,\n\t\t\t\tlabel: 'D8',\n\t\t\t\tfill: 'end'\n\t\t\t}]\n\t\t};\n\n\t\tvar options = {\n\t\t\tmaintainAspectRatio: false,\n\t\t\tspanGaps: false,\n\t\t\telements: {\n\t\t\t\tline: {\n\t\t\t\t\ttension: 0.000001\n\t\t\t\t}\n\t\t\t},\n\t\t\tscales: {\n\t\t\t\tyAxes: [{\n\t\t\t\t\tstacked: true\n\t\t\t\t}]\n\t\t\t},\n\t\t\tplugins: {\n\t\t\t\tfiller: {\n\t\t\t\t\tpropagate: false\n\t\t\t\t},\n\t\t\t\tsamples_filler_analyser: {\n\t\t\t\t\ttarget: 'chart-analyser'\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\n\t\tvar chart = new Chart('chart-0', {\n\t\t\ttype: 'line',\n\t\t\tdata: data,\n\t\t\toptions: options\n\t\t});\n\n\t\tfunction togglePropagate(btn) {\n\t\t\tvar value = btn.classList.toggle('btn-on');\n\t\t\tchart.options.plugins.filler.propagate = value;\n\t\t\tchart.update();\n\t\t}\n\n\t\tfunction toggleSmooth(btn) {\n\t\t\tvar value = btn.classList.toggle('btn-on');\n\t\t\tchart.options.elements.line.tension = value? 0.4 : 0.000001;\n\t\t\tchart.update();\n\t\t}\n\n\t\tfunction randomize() {\n\t\t\tchart.data.datasets.forEach(function(dataset) {\n\t\t\t\tdataset.data = generateData();\n\t\t\t});\n\t\t\tchart.update();\n\t\t}\n\t</script>\n</body>\n</html>\n"
  },
  {
    "path": "app_backend/static/plugin/Chart.js-2.6.0/samples/charts/area/line-stacked.html",
    "content": "<!doctype html>\n<html>\n\n<head>\n\t<title>Line Chart</title>\n\t<script src=\"../../../dist/Chart.bundle.js\"></script>\n\t<script src=\"../../utils.js\"></script>\n\t<style>\n\t\tcanvas {\n\t\t\t\t-moz-user-select: none;\n\t\t\t\t-webkit-user-select: none;\n\t\t\t\t-ms-user-select: none;\n\t\t}\n\t</style>\n</head>\n\n<body>\n\t<div style=\"width:75%;\">\n\t\t<canvas id=\"canvas\"></canvas>\n\t</div>\n\t<br>\n\t<br>\n\t<button id=\"randomizeData\">Randomize Data</button>\n\t<button id=\"addDataset\">Add Dataset</button>\n\t<button id=\"removeDataset\">Remove Dataset</button>\n\t<button id=\"addData\">Add Data</button>\n\t<button id=\"removeData\">Remove Data</button>\n\t<script>\n\t\tvar MONTHS = [\"January\", \"February\", \"March\", \"April\", \"May\", \"June\", \"July\", \"August\", \"September\", \"October\", \"November\", \"December\"];\n\t\tvar config = {\n\t\t\ttype: 'line',\n\t\t\tdata: {\n\t\t\t\tlabels: [\"January\", \"February\", \"March\", \"April\", \"May\", \"June\", \"July\"],\n\t\t\t\tdatasets: [{\n\t\t\t\t\tlabel: \"My First dataset\",\n\t\t\t\t\tborderColor: window.chartColors.red,\n\t\t\t\t\tbackgroundColor: window.chartColors.red,\n\t\t\t\t\tdata: [\n                        randomScalingFactor(),\n                        randomScalingFactor(),\n                        randomScalingFactor(),\n                        randomScalingFactor(),\n                        randomScalingFactor(),\n                        randomScalingFactor(),\n                        randomScalingFactor()\n                    ],\n\t\t\t\t}, {\n\t\t\t\t\tlabel: \"My Second dataset\",\n\t\t\t\t\tborderColor: window.chartColors.blue,\n\t\t\t\t\tbackgroundColor: window.chartColors.blue,\n\t\t\t\t\tdata: [\n                        randomScalingFactor(),\n                        randomScalingFactor(),\n                        randomScalingFactor(),\n                        randomScalingFactor(),\n                        randomScalingFactor(),\n                        randomScalingFactor(),\n                        randomScalingFactor()\n                    ],\n\t\t\t\t}, {\n\t\t\t\t\tlabel: \"My Third dataset\",\n\t\t\t\t\tborderColor: window.chartColors.green,\n\t\t\t\t\tbackgroundColor: window.chartColors.green,\n\t\t\t\t\tdata: [\n                        randomScalingFactor(),\n                        randomScalingFactor(),\n                        randomScalingFactor(),\n                        randomScalingFactor(),\n                        randomScalingFactor(),\n                        randomScalingFactor(),\n                        randomScalingFactor()\n                    ],\n\t\t\t\t}, {\n\t\t\t\t\tlabel: \"My Third dataset\",\n\t\t\t\t\tborderColor: window.chartColors.yellow,\n\t\t\t\t\tbackgroundColor: window.chartColors.yellow,\n\t\t\t\t\tdata: [\n                        randomScalingFactor(),\n                        randomScalingFactor(),\n                        randomScalingFactor(),\n                        randomScalingFactor(),\n                        randomScalingFactor(),\n                        randomScalingFactor(),\n                        randomScalingFactor()\n                    ],\n\t\t\t\t}]\n\t\t\t},\n\t\t\toptions: {\n\t\t\t\tresponsive: true,\n\t\t\t\ttitle:{\n\t\t\t\t\tdisplay:true,\n\t\t\t\t\ttext:\"Chart.js Line Chart - Stacked Area\"\n\t\t\t\t},\n\t\t\t\ttooltips: {\n\t\t\t\t\tmode: 'index',\n\t\t\t\t},\n\t\t\t\thover: {\n\t\t\t\t\tmode: 'index'\n\t\t\t\t},\n\t\t\t\tscales: {\n\t\t\t\t\txAxes: [{\n\t\t\t\t\t\tscaleLabel: {\n\t\t\t\t\t\t\tdisplay: true,\n\t\t\t\t\t\t\tlabelString: 'Month'\n\t\t\t\t\t\t}\n\t\t\t\t\t}],\n\t\t\t\t\tyAxes: [{\n\t\t\t\t\t\tstacked: true,\n\t\t\t\t\t\tscaleLabel: {\n\t\t\t\t\t\t\tdisplay: true,\n\t\t\t\t\t\t\tlabelString: 'Value'\n\t\t\t\t\t\t}\n\t\t\t\t\t}]\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\n\t\twindow.onload = function() {\n\t\t\tvar ctx = document.getElementById(\"canvas\").getContext(\"2d\");\n\t\t\twindow.myLine = new Chart(ctx, config);\n\t\t};\n\n\t\tdocument.getElementById('randomizeData').addEventListener('click', function() {\n\t\t\tconfig.data.datasets.forEach(function(dataset) {\n\t\t\t\tdataset.data = dataset.data.map(function() {\n\t\t\t\t\treturn randomScalingFactor();\n\t\t\t\t});\n\n\t\t\t});\n\n\t\t\twindow.myLine.update();\n\t\t});\n\n\t\tvar colorNames = Object.keys(window.chartColors);\n\t\tdocument.getElementById('addDataset').addEventListener('click', function() {\n\t\t\tvar colorName = colorNames[config.data.datasets.length % colorNames.length];\n\t\t\tvar newColor = window.chartColors[colorName];\n\t\t\tvar newDataset = {\n\t\t\t\tlabel: 'Dataset ' + config.data.datasets.length,\n\t\t\t\tborderColor: newColor,\n\t\t\t\tbackgroundColor: newColor,\n\t\t\t\tdata: [],\n\t\t\t};\n\n\t\t\tfor (var index = 0; index < config.data.labels.length; ++index) {\n\t\t\t\tnewDataset.data.push(randomScalingFactor());\n\t\t\t}\n\n\t\t\tconfig.data.datasets.push(newDataset);\n\t\t\twindow.myLine.update();\n\t\t});\n\n\t\tdocument.getElementById('addData').addEventListener('click', function() {\n\t\t\tif (config.data.datasets.length > 0) {\n\t\t\t\tvar month = MONTHS[config.data.labels.length % MONTHS.length];\n\t\t\t\tconfig.data.labels.push(month);\n\n\t\t\t\tconfig.data.datasets.forEach(function(dataset) {\n\t\t\t\t\tdataset.data.push(randomScalingFactor());\n\t\t\t\t});\n\n\t\t\t\twindow.myLine.update();\n\t\t\t}\n\t\t});\n\n\t\tdocument.getElementById('removeDataset').addEventListener('click', function() {\n\t\t\tconfig.data.datasets.splice(0, 1);\n\t\t\twindow.myLine.update();\n\t\t});\n\n\t\tdocument.getElementById('removeData').addEventListener('click', function() {\n\t\t\tconfig.data.labels.splice(-1, 1); // remove the label first\n\n\t\t\tconfig.data.datasets.forEach(function(dataset, datasetIndex) {\n\t\t\t\tdataset.data.pop();\n\t\t\t});\n\n\t\t\twindow.myLine.update();\n\t\t});\n\t</script>\n</body>\n\n</html>\n"
  },
  {
    "path": "app_backend/static/plugin/Chart.js-2.6.0/samples/charts/area/radar.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en-US\">\n<head>\n\t<meta charset=\"utf-8\">\n\t<meta http-equiv=\"X-UA-Compatible\" content=\"IE=Edge\">\n\t<meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">\n\t<title>area > radar | Chart.js sample</title>\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../style.css\">\n\t<script src=\"../../../dist/Chart.bundle.js\"></script>\n\t<script src=\"../../utils.js\"></script>\n\t<script src=\"analyser.js\"></script>\n</head>\n<body>\n\t<div class=\"content\">\n\t\t<div class=\"wrapper\" style=\"max-width: 512px; margin: auto\">\n\t\t\t<canvas id=\"chart-0\"></canvas>\n\t\t</div>\n\t\t<div class=\"toolbar\">\n\t\t\t<button onclick=\"togglePropagate(this)\">Propagate</button>\n\t\t\t<button onclick=\"toggleSmooth(this)\">Smooth</button>\n\t\t\t<button onclick=\"randomize(this)\">Randomize</button>\n\t\t</div>\n\t\t<div id=\"chart-analyser\" class=\"analyser\"></div>\n\t</div>\n\n\t<script>\n\t\tvar presets = window.chartColors;\n\t\tvar utils = Samples.utils;\n\t\tvar inputs = {\n\t\t\tmin: 8,\n\t\t\tmax: 16,\n\t\t\tcount: 8,\n\t\t\tdecimals: 2,\n\t\t\tcontinuity: 1\n\t\t};\n\n\t\tfunction generateData() {\n\t\t\t// radar chart doesn't support stacked values, let's do it manually\n\t\t\tvar values = utils.numbers(inputs);\n\t\t\tinputs.from = values;\n\t\t\treturn values;\n\t\t}\n\n\t\tfunction generateLabels(config) {\n\t\t\treturn utils.months({count: inputs.count});\n\t\t}\n\n\t\tutils.srand(42);\n\n\t\tvar data = {\n\t\t\tlabels: generateLabels(),\n\t\t\tdatasets: [{\n\t\t\t\tbackgroundColor: utils.transparentize(presets.red),\n\t\t\t\tborderColor: presets.red,\n\t\t\t\tdata: generateData(),\n\t\t\t\tlabel: 'D0'\n\t\t\t}, {\n\t\t\t\tbackgroundColor: utils.transparentize(presets.orange),\n\t\t\t\tborderColor: presets.orange,\n\t\t\t\tdata: generateData(),\n\t\t\t\thidden: true,\n\t\t\t\tlabel: 'D1',\n\t\t\t\tfill: '-1'\n\t\t\t}, {\n\t\t\t\tbackgroundColor: utils.transparentize(presets.yellow),\n\t\t\t\tborderColor: presets.yellow,\n\t\t\t\tdata: generateData(),\n\t\t\t\tlabel: 'D2',\n\t\t\t\tfill: 1\n\t\t\t}, {\n\t\t\t\tbackgroundColor: utils.transparentize(presets.green),\n\t\t\t\tborderColor: presets.green,\n\t\t\t\tdata: generateData(),\n\t\t\t\tlabel: 'D3',\n\t\t\t\tfill: false\n\t\t\t}, {\n\t\t\t\tbackgroundColor: utils.transparentize(presets.blue),\n\t\t\t\tborderColor: presets.blue,\n\t\t\t\tdata: generateData(),\n\t\t\t\tlabel: 'D4',\n\t\t\t\tfill: '-1'\n\t\t\t}, {\n\t\t\t\tbackgroundColor: utils.transparentize(presets.purple),\n\t\t\t\tborderColor: presets.purple,\n\t\t\t\tdata: generateData(),\n\t\t\t\tlabel: 'D5',\n\t\t\t\tfill: '-1'\n\t\t\t}]\n\t\t};\n\n\t\tvar options = {\n\t\t\tmaintainAspectRatio: true,\n\t\t\tspanGaps: false,\n\t\t\telements: {\n\t\t\t\tline: {\n\t\t\t\t\ttension: 0.000001\n\t\t\t\t}\n\t\t\t},\n\t\t\tplugins: {\n\t\t\t\tfiller: {\n\t\t\t\t\tpropagate: false\n\t\t\t\t},\n\t\t\t\tsamples_filler_analyser: {\n\t\t\t\t\ttarget: 'chart-analyser'\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\n\t\tvar chart = new Chart('chart-0', {\n\t\t\ttype: 'radar',\n\t\t\tdata: data,\n\t\t\toptions: options\n\t\t});\n\n\t\tfunction togglePropagate(btn) {\n\t\t\tvar value = btn.classList.toggle('btn-on');\n\t\t\tchart.options.plugins.filler.propagate = value;\n\t\t\tchart.update();\n\t\t}\n\n\t\tfunction toggleSmooth(btn) {\n\t\t\tvar value = btn.classList.toggle('btn-on');\n\t\t\tchart.options.elements.line.tension = value? 0.4 : 0.000001;\n\t\t\tchart.update();\n\t\t}\n\n\t\tfunction randomize() {\n\t\t\tinputs.from = [];\n\t\t\tchart.data.datasets.forEach(function(dataset) {\n\t\t\t\tdataset.data = generateData();\n\t\t\t});\n\t\t\tchart.update();\n\t\t}\n\t</script>\n</body>\n</html>\n"
  },
  {
    "path": "app_backend/static/plugin/Chart.js-2.6.0/samples/charts/bar/horizontal.html",
    "content": "<!doctype html>\n<html>\n\n<head>\n    <title>Horizontal Bar Chart</title>\n    <script src=\"../../../dist/Chart.bundle.js\"></script>\n    <script src=\"../../utils.js\"></script>\n    <style>\n    canvas {\n        -moz-user-select: none;\n        -webkit-user-select: none;\n        -ms-user-select: none;\n    }\n    </style>\n</head>\n\n<body>\n    <div id=\"container\" style=\"width: 75%;\">\n        <canvas id=\"canvas\"></canvas>\n    </div>\n    <button id=\"randomizeData\">Randomize Data</button>\n    <button id=\"addDataset\">Add Dataset</button>\n    <button id=\"removeDataset\">Remove Dataset</button>\n    <button id=\"addData\">Add Data</button>\n    <button id=\"removeData\">Remove Data</button>\n    <script>\n        var MONTHS = [\"January\", \"February\", \"March\", \"April\", \"May\", \"June\", \"July\", \"August\", \"September\", \"October\", \"November\", \"December\"];\n        var color = Chart.helpers.color;\n        var horizontalBarChartData = {\n            labels: [\"January\", \"February\", \"March\", \"April\", \"May\", \"June\", \"July\"],\n            datasets: [{\n                label: 'Dataset 1',\n                backgroundColor: color(window.chartColors.red).alpha(0.5).rgbString(),\n                borderColor: window.chartColors.red,\n                borderWidth: 1,\n                data: [\n                    randomScalingFactor(),\n                    randomScalingFactor(),\n                    randomScalingFactor(),\n                    randomScalingFactor(),\n                    randomScalingFactor(),\n                    randomScalingFactor(),\n                    randomScalingFactor()\n                ]\n            }, {\n                label: 'Dataset 2',\n                backgroundColor: color(window.chartColors.blue).alpha(0.5).rgbString(),\n                borderColor: window.chartColors.blue,\n                data: [\n                    randomScalingFactor(),\n                    randomScalingFactor(),\n                    randomScalingFactor(),\n                    randomScalingFactor(),\n                    randomScalingFactor(),\n                    randomScalingFactor(),\n                    randomScalingFactor()\n                ]\n            }]\n\n        };\n\n        window.onload = function() {\n            var ctx = document.getElementById(\"canvas\").getContext(\"2d\");\n            window.myHorizontalBar = new Chart(ctx, {\n                type: 'horizontalBar',\n                data: horizontalBarChartData,\n                options: {\n                    // Elements options apply to all of the options unless overridden in a dataset\n                    // In this case, we are setting the border of each horizontal bar to be 2px wide\n                    elements: {\n                        rectangle: {\n                            borderWidth: 2,\n                        }\n                    },\n                    responsive: true,\n                    legend: {\n                        position: 'right',\n                    },\n                    title: {\n                        display: true,\n                        text: 'Chart.js Horizontal Bar Chart'\n                    }\n                }\n            });\n\n        };\n\n        document.getElementById('randomizeData').addEventListener('click', function() {\n            var zero = Math.random() < 0.2 ? true : false;\n            horizontalBarChartData.datasets.forEach(function(dataset) {\n                dataset.data = dataset.data.map(function() {\n                    return zero ? 0.0 : randomScalingFactor();\n                });\n\n            });\n            window.myHorizontalBar.update();\n        });\n\n        var colorNames = Object.keys(window.chartColors);\n\n        document.getElementById('addDataset').addEventListener('click', function() {\n            var colorName = colorNames[horizontalBarChartData.datasets.length % colorNames.length];;\n            var dsColor = window.chartColors[colorName];\n            var newDataset = {\n                label: 'Dataset ' + horizontalBarChartData.datasets.length,\n                backgroundColor: color(dsColor).alpha(0.5).rgbString(),\n                borderColor: dsColor,\n                data: []\n            };\n\n            for (var index = 0; index < horizontalBarChartData.labels.length; ++index) {\n                newDataset.data.push(randomScalingFactor());\n            }\n\n            horizontalBarChartData.datasets.push(newDataset);\n            window.myHorizontalBar.update();\n        });\n\n        document.getElementById('addData').addEventListener('click', function() {\n            if (horizontalBarChartData.datasets.length > 0) {\n                var month = MONTHS[horizontalBarChartData.labels.length % MONTHS.length];\n                horizontalBarChartData.labels.push(month);\n\n                for (var index = 0; index < horizontalBarChartData.datasets.length; ++index) {\n                    horizontalBarChartData.datasets[index].data.push(randomScalingFactor());\n                }\n\n                window.myHorizontalBar.update();\n            }\n        });\n\n        document.getElementById('removeDataset').addEventListener('click', function() {\n            horizontalBarChartData.datasets.splice(0, 1);\n            window.myHorizontalBar.update();\n        });\n\n        document.getElementById('removeData').addEventListener('click', function() {\n            horizontalBarChartData.labels.splice(-1, 1); // remove the label first\n\n            horizontalBarChartData.datasets.forEach(function (dataset, datasetIndex) {\n                dataset.data.pop();\n            });\n\n            window.myHorizontalBar.update();\n        });\n    </script>\n</body>\n\n</html>\n"
  },
  {
    "path": "app_backend/static/plugin/Chart.js-2.6.0/samples/charts/bar/multi-axis.html",
    "content": "<!doctype html>\n<html>\n\n<head>\n    <title>Bar Chart Multi Axis</title>\n    <script src=\"../../../dist/Chart.bundle.js\"></script>\n    <script src=\"../../utils.js\"></script>\n    <style>\n    canvas {\n        -moz-user-select: none;\n        -webkit-user-select: none;\n        -ms-user-select: none;\n    }\n    </style>\n</head>\n\n<body>\n    <div style=\"width: 75%\">\n        <canvas id=\"canvas\"></canvas>\n    </div>\n    <button id=\"randomizeData\">Randomize Data</button>\n    <script>\n    var barChartData = {\n        labels: [\"January\", \"February\", \"March\", \"April\", \"May\", \"June\", \"July\"],\n        datasets: [{\n            label: 'Dataset 1',\n            backgroundColor: [\n                window.chartColors.red,\n                window.chartColors.orange,\n                window.chartColors.yellow,\n                window.chartColors.green,\n                window.chartColors.blue,\n                window.chartColors.purple,\n                window.chartColors.red\n            ],\n            yAxisID: \"y-axis-1\",\n            data: [\n                randomScalingFactor(),\n                randomScalingFactor(),\n                randomScalingFactor(),\n                randomScalingFactor(),\n                randomScalingFactor(),\n                randomScalingFactor(),\n                randomScalingFactor()\n            ]\n        }, {\n            label: 'Dataset 2',\n            backgroundColor: window.chartColors.grey,\n            yAxisID: \"y-axis-2\",\n            data: [\n                randomScalingFactor(),\n                randomScalingFactor(),\n                randomScalingFactor(),\n                randomScalingFactor(),\n                randomScalingFactor(),\n                randomScalingFactor(),\n                randomScalingFactor()\n            ]\n        }]\n\n    };\n    window.onload = function() {\n        var ctx = document.getElementById(\"canvas\").getContext(\"2d\");\n        window.myBar = new Chart(ctx, {\n            type: 'bar',\n            data: barChartData,\n            options: {\n                responsive: true,\n                title:{\n                    display:true,\n                    text:\"Chart.js Bar Chart - Multi Axis\"\n                },\n                tooltips: {\n                    mode: 'index',\n                    intersect: true\n                },\n                scales: {\n                    yAxes: [{\n                        type: \"linear\", // only linear but allow scale type registration. This allows extensions to exist solely for log scale for instance\n                        display: true,\n                        position: \"left\",\n                        id: \"y-axis-1\",\n                    }, {\n                        type: \"linear\", // only linear but allow scale type registration. This allows extensions to exist solely for log scale for instance\n                        display: true,\n                        position: \"right\",\n                        id: \"y-axis-2\",\n                        gridLines: {\n                            drawOnChartArea: false\n                        }\n                    }],\n                }\n            }\n        });\n    };\n\n    document.getElementById('randomizeData').addEventListener('click', function() {\n        barChartData.datasets.forEach(function(dataset, i) {\n            dataset.data = dataset.data.map(function() {\n                return randomScalingFactor();\n            });\n        });\n        window.myBar.update();\n    });\n    </script>\n</body>\n\n</html>\n"
  },
  {
    "path": "app_backend/static/plugin/Chart.js-2.6.0/samples/charts/bar/stacked-group.html",
    "content": "<!doctype html>\n<html>\n\n<head>\n    <title>Stacked Bar Chart with Groups</title>\n    <script src=\"../../../dist/Chart.bundle.js\"></script>\n    <script src=\"../../utils.js\"></script>\n    <style>\n    canvas {\n        -moz-user-select: none;\n        -webkit-user-select: none;\n        -ms-user-select: none;\n    }\n    </style>\n</head>\n\n<body>\n    <div style=\"width: 75%\">\n        <canvas id=\"canvas\"></canvas>\n    </div>\n    <button id=\"randomizeData\">Randomize Data</button>\n    <script>\n        var barChartData = {\n            labels: [\"January\", \"February\", \"March\", \"April\", \"May\", \"June\", \"July\"],\n            datasets: [{\n                label: 'Dataset 1',\n                backgroundColor: window.chartColors.red,\n                stack: 'Stack 0',\n                data: [\n                    randomScalingFactor(),\n                    randomScalingFactor(),\n                    randomScalingFactor(),\n                    randomScalingFactor(),\n                    randomScalingFactor(),\n                    randomScalingFactor(),\n                    randomScalingFactor()\n                ]\n            }, {\n                label: 'Dataset 2',\n                backgroundColor: window.chartColors.blue,\n                stack: 'Stack 0',\n                data: [\n                    randomScalingFactor(),\n                    randomScalingFactor(),\n                    randomScalingFactor(),\n                    randomScalingFactor(),\n                    randomScalingFactor(),\n                    randomScalingFactor(),\n                    randomScalingFactor()\n                ]\n            }, {\n                label: 'Dataset 3',\n                backgroundColor: window.chartColors.green,\n                stack: 'Stack 1',\n                data: [\n                    randomScalingFactor(),\n                    randomScalingFactor(),\n                    randomScalingFactor(),\n                    randomScalingFactor(),\n                    randomScalingFactor(),\n                    randomScalingFactor(),\n                    randomScalingFactor()\n                ]\n            }]\n\n        };\n        window.onload = function() {\n            var ctx = document.getElementById(\"canvas\").getContext(\"2d\");\n            window.myBar = new Chart(ctx, {\n                type: 'bar',\n                data: barChartData,\n                options: {\n                    title:{\n                        display:true,\n                        text:\"Chart.js Bar Chart - Stacked\"\n                    },\n                    tooltips: {\n                        mode: 'index',\n                        intersect: false\n                    },\n                    responsive: true,\n                    scales: {\n                        xAxes: [{\n                            stacked: true,\n                        }],\n                        yAxes: [{\n                            stacked: true\n                        }]\n                    }\n                }\n            });\n        };\n\n        document.getElementById('randomizeData').addEventListener('click', function() {\n            barChartData.datasets.forEach(function(dataset, i) {\n                dataset.data = dataset.data.map(function() {\n                    return randomScalingFactor();\n                });\n            });\n            window.myBar.update();\n        });\n    </script>\n</body>\n\n</html>\n"
  },
  {
    "path": "app_backend/static/plugin/Chart.js-2.6.0/samples/charts/bar/stacked.html",
    "content": "<!doctype html>\n<html>\n\n<head>\n    <title>Stacked Bar Chart</title>\n    <script src=\"../../../dist/Chart.bundle.js\"></script>\n    <script src=\"../../utils.js\"></script>\n    <style>\n    canvas {\n        -moz-user-select: none;\n        -webkit-user-select: none;\n        -ms-user-select: none;\n    }\n    </style>\n</head>\n\n<body>\n    <div style=\"width: 75%\">\n        <canvas id=\"canvas\"></canvas>\n    </div>\n    <button id=\"randomizeData\">Randomize Data</button>\n    <script>\n        var barChartData = {\n            labels: [\"January\", \"February\", \"March\", \"April\", \"May\", \"June\", \"July\"],\n            datasets: [{\n                label: 'Dataset 1',\n                backgroundColor: window.chartColors.red,\n                data: [\n                    randomScalingFactor(),\n                    randomScalingFactor(),\n                    randomScalingFactor(),\n                    randomScalingFactor(),\n                    randomScalingFactor(),\n                    randomScalingFactor(),\n                    randomScalingFactor()\n                ]\n            }, {\n                label: 'Dataset 2',\n                backgroundColor: window.chartColors.blue,\n                data: [\n                    randomScalingFactor(),\n                    randomScalingFactor(),\n                    randomScalingFactor(),\n                    randomScalingFactor(),\n                    randomScalingFactor(),\n                    randomScalingFactor(),\n                    randomScalingFactor()\n                ]\n            }, {\n                label: 'Dataset 3',\n                backgroundColor: window.chartColors.green,\n                data: [\n                    randomScalingFactor(),\n                    randomScalingFactor(),\n                    randomScalingFactor(),\n                    randomScalingFactor(),\n                    randomScalingFactor(),\n                    randomScalingFactor(),\n                    randomScalingFactor()\n                ]\n            }]\n\n        };\n        window.onload = function() {\n            var ctx = document.getElementById(\"canvas\").getContext(\"2d\");\n            window.myBar = new Chart(ctx, {\n                type: 'bar',\n                data: barChartData,\n                options: {\n                    title:{\n                        display:true,\n                        text:\"Chart.js Bar Chart - Stacked\"\n                    },\n                    tooltips: {\n                        mode: 'index',\n                        intersect: false\n                    },\n                    responsive: true,\n                    scales: {\n                        xAxes: [{\n                            stacked: true,\n                        }],\n                        yAxes: [{\n                            stacked: true\n                        }]\n                    }\n                }\n            });\n        };\n\n        document.getElementById('randomizeData').addEventListener('click', function() {\n            barChartData.datasets.forEach(function(dataset, i) {\n                dataset.data = dataset.data.map(function() {\n                    return randomScalingFactor();\n                });\n            });\n            window.myBar.update();\n        });\n    </script>\n</body>\n\n</html>\n"
  },
  {
    "path": "app_backend/static/plugin/Chart.js-2.6.0/samples/charts/bar/vertical.html",
    "content": "<!doctype html>\n<html>\n\n<head>\n    <title>Bar Chart</title>\n    <script src=\"../../../dist/Chart.bundle.js\"></script>\n    <script src=\"../../utils.js\"></script>\n    <style>\n    canvas {\n        -moz-user-select: none;\n        -webkit-user-select: none;\n        -ms-user-select: none;\n    }\n    </style>\n</head>\n\n<body>\n    <div id=\"container\" style=\"width: 75%;\">\n        <canvas id=\"canvas\"></canvas>\n    </div>\n    <button id=\"randomizeData\">Randomize Data</button>\n    <button id=\"addDataset\">Add Dataset</button>\n    <button id=\"removeDataset\">Remove Dataset</button>\n    <button id=\"addData\">Add Data</button>\n    <button id=\"removeData\">Remove Data</button>\n    <script>\n        var MONTHS = [\"January\", \"February\", \"March\", \"April\", \"May\", \"June\", \"July\", \"August\", \"September\", \"October\", \"November\", \"December\"];\n        var color = Chart.helpers.color;\n        var barChartData = {\n            labels: [\"January\", \"February\", \"March\", \"April\", \"May\", \"June\", \"July\"],\n            datasets: [{\n                label: 'Dataset 1',\n                backgroundColor: color(window.chartColors.red).alpha(0.5).rgbString(),\n                borderColor: window.chartColors.red,\n                borderWidth: 1,\n                data: [\n                    randomScalingFactor(),\n                    randomScalingFactor(),\n                    randomScalingFactor(),\n                    randomScalingFactor(),\n                    randomScalingFactor(),\n                    randomScalingFactor(),\n                    randomScalingFactor()\n                ]\n            }, {\n                label: 'Dataset 2',\n                backgroundColor: color(window.chartColors.blue).alpha(0.5).rgbString(),\n                borderColor: window.chartColors.blue,\n                borderWidth: 1,\n                data: [\n                    randomScalingFactor(),\n                    randomScalingFactor(),\n                    randomScalingFactor(),\n                    randomScalingFactor(),\n                    randomScalingFactor(),\n                    randomScalingFactor(),\n                    randomScalingFactor()\n                ]\n            }]\n\n        };\n\n        window.onload = function() {\n            var ctx = document.getElementById(\"canvas\").getContext(\"2d\");\n            window.myBar = new Chart(ctx, {\n                type: 'bar',\n                data: barChartData,\n                options: {\n                    responsive: true,\n                    legend: {\n                        position: 'top',\n                    },\n                    title: {\n                        display: true,\n                        text: 'Chart.js Bar Chart'\n                    }\n                }\n            });\n\n        };\n\n        document.getElementById('randomizeData').addEventListener('click', function() {\n            var zero = Math.random() < 0.2 ? true : false;\n            barChartData.datasets.forEach(function(dataset) {\n                dataset.data = dataset.data.map(function() {\n                    return zero ? 0.0 : randomScalingFactor();\n                });\n\n            });\n            window.myBar.update();\n        });\n\n        var colorNames = Object.keys(window.chartColors);\n        document.getElementById('addDataset').addEventListener('click', function() {\n            var colorName = colorNames[barChartData.datasets.length % colorNames.length];;\n            var dsColor = window.chartColors[colorName];\n            var newDataset = {\n                label: 'Dataset ' + barChartData.datasets.length,\n                backgroundColor: color(dsColor).alpha(0.5).rgbString(),\n                borderColor: dsColor,\n                borderWidth: 1,\n                data: []\n            };\n\n            for (var index = 0; index < barChartData.labels.length; ++index) {\n                newDataset.data.push(randomScalingFactor());\n            }\n\n            barChartData.datasets.push(newDataset);\n            window.myBar.update();\n        });\n\n        document.getElementById('addData').addEventListener('click', function() {\n            if (barChartData.datasets.length > 0) {\n                var month = MONTHS[barChartData.labels.length % MONTHS.length];\n                barChartData.labels.push(month);\n\n                for (var index = 0; index < barChartData.datasets.length; ++index) {\n                    //window.myBar.addData(randomScalingFactor(), index);\n                    barChartData.datasets[index].data.push(randomScalingFactor());\n                }\n\n                window.myBar.update();\n            }\n        });\n\n        document.getElementById('removeDataset').addEventListener('click', function() {\n            barChartData.datasets.splice(0, 1);\n            window.myBar.update();\n        });\n\n        document.getElementById('removeData').addEventListener('click', function() {\n            barChartData.labels.splice(-1, 1); // remove the label first\n\n            barChartData.datasets.forEach(function(dataset, datasetIndex) {\n                dataset.data.pop();\n            });\n\n            window.myBar.update();\n        });\n    </script>\n</body>\n\n</html>\n"
  },
  {
    "path": "app_backend/static/plugin/Chart.js-2.6.0/samples/charts/bubble.html",
    "content": "<!doctype html>\n<html>\n\n<head>\n    <title>Bubble Chart</title>\n    <script src=\"../../dist/Chart.bundle.js\"></script>\n    <script src=\"../utils.js\"></script>\n    <style type=\"text/css\">\n    canvas{\n        -moz-user-select: none;\n        -webkit-user-select: none;\n        -ms-user-select: none;\n    }\n    </style>\n</head>\n\n<body>\n    <div id=\"container\" style=\"width: 75%;\">\n        <canvas id=\"canvas\"></canvas>\n    </div>\n    <button id=\"randomizeData\">Randomize Data</button>\n    <button id=\"addDataset\">Add Dataset</button>\n    <button id=\"removeDataset\">Remove Dataset</button>\n    <button id=\"addData\">Add Data</button>\n    <button id=\"removeData\">Remove Data</button>\n    <script>\n        var DEFAULT_DATASET_SIZE = 7;\n\n        var addedCount = 0;\n        var color = Chart.helpers.color;\n        var bubbleChartData = {\n            animation: {\n                duration: 10000\n            },\n            datasets: [{\n                label: \"My First dataset\",\n                backgroundColor: color(window.chartColors.red).alpha(0.5).rgbString(),\n                borderColor: window.chartColors.red,\n                borderWidth: 1,\n                data: [{\n                    x: randomScalingFactor(),\n                    y: randomScalingFactor(),\n                    r: Math.abs(randomScalingFactor()) / 5,\n                }, {\n                    x: randomScalingFactor(),\n                    y: randomScalingFactor(),\n                    r: Math.abs(randomScalingFactor()) / 5,\n                }, {\n                    x: randomScalingFactor(),\n                    y: randomScalingFactor(),\n                    r: Math.abs(randomScalingFactor()) / 5,\n                }, {\n                    x: randomScalingFactor(),\n                    y: randomScalingFactor(),\n                    r: Math.abs(randomScalingFactor()) / 5,\n                }, {\n                    x: randomScalingFactor(),\n                    y: randomScalingFactor(),\n                    r: Math.abs(randomScalingFactor()) / 5,\n                }, {\n                    x: randomScalingFactor(),\n                    y: randomScalingFactor(),\n                    r: Math.abs(randomScalingFactor()) / 5,\n                }, {\n                    x: randomScalingFactor(),\n                    y: randomScalingFactor(),\n                    r: Math.abs(randomScalingFactor()) / 5,\n                }]\n            }, {\n                label: \"My Second dataset\",\n                backgroundColor: color(window.chartColors.orange).alpha(0.5).rgbString(),\n                borderColor: window.chartColors.orange,\n                borderWidth: 1,\n                data: [{\n                    x: randomScalingFactor(),\n                    y: randomScalingFactor(),\n                    r: Math.abs(randomScalingFactor()) / 5,\n                }, {\n                    x: randomScalingFactor(),\n                    y: randomScalingFactor(),\n                    r: Math.abs(randomScalingFactor()) / 5,\n                }, {\n                    x: randomScalingFactor(),\n                    y: randomScalingFactor(),\n                    r: Math.abs(randomScalingFactor()) / 5,\n                }, {\n                    x: randomScalingFactor(),\n                    y: randomScalingFactor(),\n                    r: Math.abs(randomScalingFactor()) / 5,\n                }, {\n                    x: randomScalingFactor(),\n                    y: randomScalingFactor(),\n                    r: Math.abs(randomScalingFactor()) / 5,\n                }, {\n                    x: randomScalingFactor(),\n                    y: randomScalingFactor(),\n                    r: Math.abs(randomScalingFactor()) / 5,\n                }, {\n                    x: randomScalingFactor(),\n                    y: randomScalingFactor(),\n                    r: Math.abs(randomScalingFactor()) / 5,\n                }]\n            }]\n        };\n\n        window.onload = function() {\n            var ctx = document.getElementById(\"canvas\").getContext(\"2d\");\n            window.myChart = new Chart(ctx, {\n                type: 'bubble',\n                data: bubbleChartData,\n                options: {\n                    responsive: true,\n                    title:{\n                        display:true,\n                        text:'Chart.js Bubble Chart'\n                    },\n                    tooltips: {\n                        mode: 'point'\n                    }\n                }\n            });\n        };\n\n        document.getElementById('randomizeData').addEventListener('click', function() {\n            bubbleChartData.datasets.forEach(function(dataset) {\n                dataset.data = dataset.data.map(function() {\n                    return {\n                        x: randomScalingFactor(),\n                        y: randomScalingFactor(),\n                        r: Math.abs(randomScalingFactor()) / 5,\n                    };\n                });\n            });\n            window.myChart.update();\n        });\n\n        var colorNames = Object.keys(window.chartColors);\n        document.getElementById('addDataset').addEventListener('click', function() {\n            ++addedCount;\n            var colorName = colorNames[bubbleChartData.datasets.length % colorNames.length];;\n            var dsColor = window.chartColors[colorName];\n            var newDataset = {\n                label: \"My added dataset \" + addedCount,\n                backgroundColor: color(dsColor).alpha(0.5).rgbString(),\n                borderColor: dsColor,\n                borderWidth: 1,\n                data: []\n            };\n\n            for (var index = 0; index < DEFAULT_DATASET_SIZE; ++index) {\n                newDataset.data.push({\n                    x: randomScalingFactor(),\n                    y: randomScalingFactor(),\n                    r: Math.abs(randomScalingFactor()) / 5,\n                });\n            }\n\n            bubbleChartData.datasets.push(newDataset);\n            window.myChart.update();\n        });\n\n        document.getElementById('addData').addEventListener('click', function() {\n            if (bubbleChartData.datasets.length > 0) {\n                for (var index = 0; index < bubbleChartData.datasets.length; ++index) {\n                    bubbleChartData.datasets[index].data.push({\n                        x: randomScalingFactor(),\n                        y: randomScalingFactor(),\n                        r: Math.abs(randomScalingFactor()) / 5,\n                    });\n                }\n\n                window.myChart.update();\n            }\n        });\n\n        document.getElementById('removeDataset').addEventListener('click', function() {\n            bubbleChartData.datasets.splice(0, 1);\n            window.myChart.update();\n        });\n\n        document.getElementById('removeData').addEventListener('click', function() {\n            bubbleChartData.datasets.forEach(function(dataset, datasetIndex) {\n                dataset.data.pop();\n            });\n\n            window.myChart.update();\n        });\n    </script>\n</body>\n\n</html>\n"
  },
  {
    "path": "app_backend/static/plugin/Chart.js-2.6.0/samples/charts/combo-bar-line.html",
    "content": "<!doctype html>\n<html>\n\n<head>\n    <title>Combo Bar-Line Chart</title>\n    <script src=\"../../dist/Chart.bundle.js\"></script>\n    <script src=\"../utils.js\"></script>\n    <style>\n    canvas {\n        -moz-user-select: none;\n        -webkit-user-select: none;\n        -ms-user-select: none;\n    }\n    </style>\n</head>\n\n<body>\n    <div style=\"width: 75%\">\n        <canvas id=\"canvas\"></canvas>\n    </div>\n    <button id=\"randomizeData\">Randomize Data</button>\n    <script>\n        var chartData = {\n            labels: [\"January\", \"February\", \"March\", \"April\", \"May\", \"June\", \"July\"],\n            datasets: [{\n                type: 'line',\n                label: 'Dataset 1',\n                borderColor: window.chartColors.blue,\n                borderWidth: 2,\n                fill: false,\n                data: [\n                    randomScalingFactor(),\n                    randomScalingFactor(),\n                    randomScalingFactor(),\n                    randomScalingFactor(),\n                    randomScalingFactor(),\n                    randomScalingFactor(),\n                    randomScalingFactor()\n                ]\n            }, {\n                type: 'bar',\n                label: 'Dataset 2',\n                backgroundColor: window.chartColors.red,\n                data: [\n                    randomScalingFactor(),\n                    randomScalingFactor(),\n                    randomScalingFactor(),\n                    randomScalingFactor(),\n                    randomScalingFactor(),\n                    randomScalingFactor(),\n                    randomScalingFactor()\n                ],\n                borderColor: 'white',\n                borderWidth: 2\n            }, {\n                type: 'bar',\n                label: 'Dataset 3',\n                backgroundColor: window.chartColors.green,\n                data: [\n                    randomScalingFactor(),\n                    randomScalingFactor(),\n                    randomScalingFactor(),\n                    randomScalingFactor(),\n                    randomScalingFactor(),\n                    randomScalingFactor(),\n                    randomScalingFactor()\n                ]\n            }]\n\n        };\n        window.onload = function() {\n            var ctx = document.getElementById(\"canvas\").getContext(\"2d\");\n            window.myMixedChart = new Chart(ctx, {\n                type: 'bar',\n                data: chartData,\n                options: {\n                    responsive: true,\n                    title: {\n                        display: true,\n                        text: 'Chart.js Combo Bar Line Chart'\n                    },\n                    tooltips: {\n                        mode: 'index',\n                        intersect: true\n                    }\n                }\n            });\n        };\n\n        document.getElementById('randomizeData').addEventListener('click', function() {\n            chartData.datasets.forEach(function(dataset) {\n                dataset.data = dataset.data.map(function() {\n                    return randomScalingFactor();\n                });\n            });\n            window.myMixedChart.update();\n        });\n    </script>\n</body>\n\n</html>\n"
  },
  {
    "path": "app_backend/static/plugin/Chart.js-2.6.0/samples/charts/doughnut.html",
    "content": "<!doctype html>\n<html>\n\n<head>\n    <title>Doughnut Chart</title>\n    <script src=\"../../dist/Chart.bundle.js\"></script>\n    <script src=\"../utils.js\"></script>\n    <style>\n    canvas {\n        -moz-user-select: none;\n        -webkit-user-select: none;\n        -ms-user-select: none;\n    }\n    </style>\n</head>\n\n<body>\n    <div id=\"canvas-holder\" style=\"width:40%\">\n        <canvas id=\"chart-area\" />\n    </div>\n    <button id=\"randomizeData\">Randomize Data</button>\n    <button id=\"addDataset\">Add Dataset</button>\n    <button id=\"removeDataset\">Remove Dataset</button>\n    <button id=\"addData\">Add Data</button>\n    <button id=\"removeData\">Remove Data</button>\n    <script>\n    var randomScalingFactor = function() {\n        return Math.round(Math.random() * 100);\n    };\n\n    var config = {\n        type: 'doughnut',\n        data: {\n            datasets: [{\n                data: [\n                    randomScalingFactor(),\n                    randomScalingFactor(),\n                    randomScalingFactor(),\n                    randomScalingFactor(),\n                    randomScalingFactor(),\n                ],\n                backgroundColor: [\n                    window.chartColors.red,\n                    window.chartColors.orange,\n                    window.chartColors.yellow,\n                    window.chartColors.green,\n                    window.chartColors.blue,\n                ],\n                label: 'Dataset 1'\n            }],\n            labels: [\n                \"Red\",\n                \"Orange\",\n                \"Yellow\",\n                \"Green\",\n                \"Blue\"\n            ]\n        },\n        options: {\n            responsive: true,\n            legend: {\n                position: 'top',\n            },\n            title: {\n                display: true,\n                text: 'Chart.js Doughnut Chart'\n            },\n            animation: {\n                animateScale: true,\n                animateRotate: true\n            }\n        }\n    };\n\n    window.onload = function() {\n        var ctx = document.getElementById(\"chart-area\").getContext(\"2d\");\n        window.myDoughnut = new Chart(ctx, config);\n    };\n\n    document.getElementById('randomizeData').addEventListener('click', function() {\n        config.data.datasets.forEach(function(dataset) {\n            dataset.data = dataset.data.map(function() {\n                return randomScalingFactor();\n            });\n        });\n\n        window.myDoughnut.update();\n    });\n\n    var colorNames = Object.keys(window.chartColors);\n    document.getElementById('addDataset').addEventListener('click', function() {\n        var newDataset = {\n            backgroundColor: [],\n            data: [],\n            label: 'New dataset ' + config.data.datasets.length,\n        };\n\n        for (var index = 0; index < config.data.labels.length; ++index) {\n            newDataset.data.push(randomScalingFactor());\n\n            var colorName = colorNames[index % colorNames.length];;\n            var newColor = window.chartColors[colorName];\n            newDataset.backgroundColor.push(newColor);\n        }\n\n        config.data.datasets.push(newDataset);\n        window.myDoughnut.update();\n    });\n\n    document.getElementById('addData').addEventListener('click', function() {\n        if (config.data.datasets.length > 0) {\n            config.data.labels.push('data #' + config.data.labels.length);\n\n            var colorName = colorNames[config.data.datasets[0].data.length % colorNames.length];;\n            var newColor = window.chartColors[colorName];\n\n            config.data.datasets.forEach(function(dataset) {\n                dataset.data.push(randomScalingFactor());\n                dataset.backgroundColor.push(newColor);\n            });\n\n            window.myDoughnut.update();\n        }\n    });\n\n    document.getElementById('removeDataset').addEventListener('click', function() {\n        config.data.datasets.splice(0, 1);\n        window.myDoughnut.update();\n    });\n\n    document.getElementById('removeData').addEventListener('click', function() {\n        config.data.labels.splice(-1, 1); // remove the label first\n\n        config.data.datasets.forEach(function(dataset) {\n            dataset.data.pop();\n            dataset.backgroundColor.pop();\n        });\n\n        window.myDoughnut.update();\n    });\n    </script>\n</body>\n\n</html>\n"
  },
  {
    "path": "app_backend/static/plugin/Chart.js-2.6.0/samples/charts/line/basic.html",
    "content": "<!doctype html>\n<html>\n\n<head>\n    <title>Line Chart</title>\n    <script src=\"../../../dist/Chart.bundle.js\"></script>\n    <script src=\"../../utils.js\"></script>\n    <style>\n    canvas{\n        -moz-user-select: none;\n        -webkit-user-select: none;\n        -ms-user-select: none;\n    }\n    </style>\n</head>\n\n<body>\n    <div style=\"width:75%;\">\n        <canvas id=\"canvas\"></canvas>\n    </div>\n    <br>\n    <br>\n    <button id=\"randomizeData\">Randomize Data</button>\n    <button id=\"addDataset\">Add Dataset</button>\n    <button id=\"removeDataset\">Remove Dataset</button>\n    <button id=\"addData\">Add Data</button>\n    <button id=\"removeData\">Remove Data</button>\n    <script>\n        var MONTHS = [\"January\", \"February\", \"March\", \"April\", \"May\", \"June\", \"July\", \"August\", \"September\", \"October\", \"November\", \"December\"];\n        var config = {\n            type: 'line',\n            data: {\n                labels: [\"January\", \"February\", \"March\", \"April\", \"May\", \"June\", \"July\"],\n                datasets: [{\n                    label: \"My First dataset\",\n                    backgroundColor: window.chartColors.red,\n                    borderColor: window.chartColors.red,\n                    data: [\n                        randomScalingFactor(),\n                        randomScalingFactor(),\n                        randomScalingFactor(),\n                        randomScalingFactor(),\n                        randomScalingFactor(),\n                        randomScalingFactor(),\n                        randomScalingFactor()\n                    ],\n                    fill: false,\n                }, {\n                    label: \"My Second dataset\",\n                    fill: false,\n                    backgroundColor: window.chartColors.blue,\n                    borderColor: window.chartColors.blue,\n                    data: [\n                        randomScalingFactor(),\n                        randomScalingFactor(),\n                        randomScalingFactor(),\n                        randomScalingFactor(),\n                        randomScalingFactor(),\n                        randomScalingFactor(),\n                        randomScalingFactor()\n                    ],\n                }]\n            },\n            options: {\n                responsive: true,\n                title:{\n                    display:true,\n                    text:'Chart.js Line Chart'\n                },\n                tooltips: {\n                    mode: 'index',\n                    intersect: false,\n                },\n                hover: {\n                    mode: 'nearest',\n                    intersect: true\n                },\n                scales: {\n                    xAxes: [{\n                        display: true,\n                        scaleLabel: {\n                            display: true,\n                            labelString: 'Month'\n                        }\n                    }],\n                    yAxes: [{\n                        display: true,\n                        scaleLabel: {\n                            display: true,\n                            labelString: 'Value'\n                        }\n                    }]\n                }\n            }\n        };\n\n        window.onload = function() {\n            var ctx = document.getElementById(\"canvas\").getContext(\"2d\");\n            window.myLine = new Chart(ctx, config);\n        };\n\n        document.getElementById('randomizeData').addEventListener('click', function() {\n            config.data.datasets.forEach(function(dataset) {\n                dataset.data = dataset.data.map(function() {\n                    return randomScalingFactor();\n                });\n\n            });\n\n            window.myLine.update();\n        });\n\n        var colorNames = Object.keys(window.chartColors);\n        document.getElementById('addDataset').addEventListener('click', function() {\n            var colorName = colorNames[config.data.datasets.length % colorNames.length];\n            var newColor = window.chartColors[colorName];\n            var newDataset = {\n                label: 'Dataset ' + config.data.datasets.length,\n                backgroundColor: newColor,\n                borderColor: newColor,\n                data: [],\n                fill: false\n            };\n\n            for (var index = 0; index < config.data.labels.length; ++index) {\n                newDataset.data.push(randomScalingFactor());\n            }\n\n            config.data.datasets.push(newDataset);\n            window.myLine.update();\n        });\n\n        document.getElementById('addData').addEventListener('click', function() {\n            if (config.data.datasets.length > 0) {\n                var month = MONTHS[config.data.labels.length % MONTHS.length];\n                config.data.labels.push(month);\n\n                config.data.datasets.forEach(function(dataset) {\n                    dataset.data.push(randomScalingFactor());\n                });\n\n                window.myLine.update();\n            }\n        });\n\n        document.getElementById('removeDataset').addEventListener('click', function() {\n            config.data.datasets.splice(0, 1);\n            window.myLine.update();\n        });\n\n        document.getElementById('removeData').addEventListener('click', function() {\n            config.data.labels.splice(-1, 1); // remove the label first\n\n            config.data.datasets.forEach(function(dataset, datasetIndex) {\n                dataset.data.pop();\n            });\n\n            window.myLine.update();\n        });\n    </script>\n</body>\n\n</html>\n"
  },
  {
    "path": "app_backend/static/plugin/Chart.js-2.6.0/samples/charts/line/interpolation-modes.html",
    "content": "<!doctype html>\n<html>\n\n<head>\n    <title>Line Chart - Cubic interpolation mode</title>\n    <script src=\"../../../dist/Chart.bundle.js\"></script>\n    <script src=\"../../utils.js\"></script>\n    <style>\n    canvas{\n        -moz-user-select: none;\n        -webkit-user-select: none;\n        -ms-user-select: none;\n    }\n    </style>\n</head>\n\n<body>\n    <div style=\"width:75%;\">\n        <canvas id=\"canvas\"></canvas>\n    </div>\n    <br>\n    <br>\n    <button id=\"randomizeData\">Randomize Data</button>\n    <script>\n\n        var randomScalingFactor = function() {\n            return Math.round(Math.random() * 100);\n        };\n\n        var datapoints = [0, 20, 20, 60, 60, 120, NaN, 180, 120, 125, 105, 110, 170];\n\t\tvar config = {\n            type: 'line',\n            data: {\n                labels: [\"0\", \"1\", \"2\", \"3\", \"4\", \"5\", \"6\", \"7\", \"8\", \"9\", \"10\", \"11\", \"12\"],\n                datasets: [{\n                    label: \"Cubic interpolation (monotone)\",\n                    data: datapoints,\n                    borderColor: window.chartColors.red,\n\t\t\t\t\tbackgroundColor: 'rgba(0, 0, 0, 0)',\n                    fill: false,\n\t\t\t\t\tcubicInterpolationMode: 'monotone'\n                }, {\n                    label: \"Cubic interpolation (default)\",\n                    data: datapoints,\n                    borderColor: window.chartColors.blue,\n\t\t\t\t\tbackgroundColor: 'rgba(0, 0, 0, 0)',\n                    fill: false,\n                }, {\n                    label: \"Linear interpolation\",\n                    data: datapoints,\n                    borderColor: window.chartColors.green,\n\t\t\t\t\tbackgroundColor: 'rgba(0, 0, 0, 0)',\n                    fill: false,\n\t\t\t\t\tlineTension: 0\n                }]\n            },\n            options: {\n                responsive: true,\n                title:{\n                    display:true,\n                    text:'Chart.js Line Chart - Cubic interpolation mode'\n                },\n                tooltips: {\n                    mode: 'index'\n                },\n                scales: {\n                    xAxes: [{\n                        display: true,\n                        scaleLabel: {\n                            display: true\n                        }\n                    }],\n                    yAxes: [{\n                        display: true,\n                        scaleLabel: {\n                            display: true,\n                            labelString: 'Value'\n                        },\n                        ticks: {\n                            suggestedMin: -10,\n                            suggestedMax: 200,\n                        }\n                    }]\n                }\n            }\n        };\n\n        window.onload = function() {\n            var ctx = document.getElementById(\"canvas\").getContext(\"2d\");\n            window.myLine = new Chart(ctx, config);\n        };\n\n        document.getElementById('randomizeData').addEventListener('click', function() {\n\t\t\tfor (var i = 0, len = datapoints.length; i < len; ++i) {\n\t\t\t\tdatapoints[i] = Math.random() < 0.05 ? NaN : randomScalingFactor();\n\t\t\t}\n            window.myLine.update();\n        });\n\n    </script>\n</body>\n\n</html>\n"
  },
  {
    "path": "app_backend/static/plugin/Chart.js-2.6.0/samples/charts/line/line-styles.html",
    "content": "<!doctype html>\n<html>\n\n<head>\n    <title>Line Styles</title>\n    <script src=\"../../../dist/Chart.bundle.js\"></script>\n    <script src=\"../../utils.js\"></script>\n    <style>\n    canvas{\n        -moz-user-select: none;\n        -webkit-user-select: none;\n        -ms-user-select: none;\n    }\n    </style>\n</head>\n\n<body>\n    <div style=\"width:75%;\">\n        <canvas id=\"canvas\"></canvas>\n    </div>\n    <script>\n        var config = {\n            type: 'line',\n            data: {\n                labels: [\"January\", \"February\", \"March\", \"April\", \"May\", \"June\", \"July\"],\n                datasets: [{\n                    label: \"Unfilled\",\n                    fill: false,\n                    backgroundColor: window.chartColors.blue,\n                    borderColor: window.chartColors.blue,\n                    data: [\n                        randomScalingFactor(),\n                        randomScalingFactor(),\n                        randomScalingFactor(),\n                        randomScalingFactor(),\n                        randomScalingFactor(),\n                        randomScalingFactor(),\n                        randomScalingFactor()\n                    ],\n                }, {\n                    label: \"Dashed\",\n                    fill: false,\n                    backgroundColor: window.chartColors.green,\n                    borderColor: window.chartColors.green,\n                    borderDash: [5, 5],\n                    data: [\n                        randomScalingFactor(),\n                        randomScalingFactor(),\n                        randomScalingFactor(),\n                        randomScalingFactor(),\n                        randomScalingFactor(),\n                        randomScalingFactor(),\n                        randomScalingFactor()\n                    ],\n                }, {\n                    label: \"Filled\",\n                    backgroundColor: window.chartColors.red,\n                    borderColor: window.chartColors.red,\n                    data: [\n                        randomScalingFactor(),\n                        randomScalingFactor(),\n                        randomScalingFactor(),\n                        randomScalingFactor(),\n                        randomScalingFactor(),\n                        randomScalingFactor(),\n                        randomScalingFactor()\n                    ],\n                    fill: true,\n                }]\n            },\n            options: {\n                responsive: true,\n                title:{\n                    display:true,\n                    text:'Chart.js Line Chart'\n                },\n                tooltips: {\n                    mode: 'index',\n                    intersect: false,\n                },\n                hover: {\n                    mode: 'nearest',\n                    intersect: true\n                },\n                scales: {\n                    xAxes: [{\n                        display: true,\n                        scaleLabel: {\n                            display: true,\n                            labelString: 'Month'\n                        }\n                    }],\n                    yAxes: [{\n                        display: true,\n                        scaleLabel: {\n                            display: true,\n                            labelString: 'Value'\n                        }\n                    }]\n                }\n            }\n        };\n\n        window.onload = function() {\n            var ctx = document.getElementById(\"canvas\").getContext(\"2d\");\n            window.myLine = new Chart(ctx, config);\n        };\n    </script>\n</body>\n\n</html>\n"
  },
  {
    "path": "app_backend/static/plugin/Chart.js-2.6.0/samples/charts/line/multi-axis.html",
    "content": "<!doctype html>\n<html>\n\n<head>\n    <title>Line Chart Multiple Axes</title>\n    <script src=\"../../../dist/Chart.bundle.js\"></script>\n    <script src=\"../../utils.js\"></script>\n    <style>\n    canvas {\n        -moz-user-select: none;\n        -webkit-user-select: none;\n        -ms-user-select: none;\n    }\n    </style>\n</head>\n\n<body>\n    <div style=\"width:75%;\">\n        <canvas id=\"canvas\"></canvas>\n    </div>\n    <button id=\"randomizeData\">Randomize Data</button>\n    <script>\n    var lineChartData = {\n        labels: [\"January\", \"February\", \"March\", \"April\", \"May\", \"June\", \"July\"],\n        datasets: [{\n            label: \"My First dataset\",\n            borderColor: window.chartColors.red,\n            backgroundColor: window.chartColors.red,\n            fill: false,\n            data: [\n                randomScalingFactor(),\n                randomScalingFactor(),\n                randomScalingFactor(),\n                randomScalingFactor(),\n                randomScalingFactor(),\n                randomScalingFactor(),\n                randomScalingFactor()\n            ],\n            yAxisID: \"y-axis-1\",\n        }, {\n            label: \"My Second dataset\",\n            borderColor: window.chartColors.blue,\n            backgroundColor: window.chartColors.blue,\n            fill: false,\n            data: [\n                randomScalingFactor(),\n                randomScalingFactor(),\n                randomScalingFactor(),\n                randomScalingFactor(),\n                randomScalingFactor(),\n                randomScalingFactor(),\n                randomScalingFactor()\n            ],\n            yAxisID: \"y-axis-2\"\n        }]\n    };\n\n    window.onload = function() {\n        var ctx = document.getElementById(\"canvas\").getContext(\"2d\");\n        window.myLine = Chart.Line(ctx, {\n            data: lineChartData,\n            options: {\n                responsive: true,\n                hoverMode: 'index',\n                stacked: false,\n                title:{\n                    display: true,\n                    text:'Chart.js Line Chart - Multi Axis'\n                },\n                scales: {\n                    yAxes: [{\n                        type: \"linear\", // only linear but allow scale type registration. This allows extensions to exist solely for log scale for instance\n                        display: true,\n                        position: \"left\",\n                        id: \"y-axis-1\",\n                    }, {\n                        type: \"linear\", // only linear but allow scale type registration. This allows extensions to exist solely for log scale for instance\n                        display: true,\n                        position: \"right\",\n                        id: \"y-axis-2\",\n\n                        // grid line settings\n                        gridLines: {\n                            drawOnChartArea: false, // only want the grid lines for one axis to show up\n                        },\n                    }],\n                }\n            }\n        });\n    };\n\n    document.getElementById('randomizeData').addEventListener('click', function() {\n        lineChartData.datasets.forEach(function(dataset) {\n            dataset.data = dataset.data.map(function() {\n                return randomScalingFactor();\n            });\n        });\n\n        window.myLine.update();\n    });\n    </script>\n</body>\n\n</html>\n"
  },
  {
    "path": "app_backend/static/plugin/Chart.js-2.6.0/samples/charts/line/point-sizes.html",
    "content": "<!doctype html>\n<html>\n\n<head>\n    <title>Different Point Sizes</title>\n    <script src=\"../../../dist/Chart.bundle.js\"></script>\n    <script src=\"../../utils.js\"></script>\n    <style>\n        canvas {\n            -moz-user-select: none;\n            -webkit-user-select: none;\n            -ms-user-select: none;\n        }\n    </style>\n</head>\n\n<body>\n    <div style=\"width:75%;\">\n        <canvas id=\"canvas\"></canvas>\n    </div>\n    <script>\n        var MONTHS = [\"January\", \"February\", \"March\", \"April\", \"May\", \"June\", \"July\", \"August\", \"September\", \"October\", \"November\", \"December\"];\n        var config = {\n            type: 'line',\n            data: {\n                labels: [\"January\", \"February\", \"March\", \"April\", \"May\", \"June\", \"July\"],\n                datasets: [{\n                    label: \"dataset - big points\",\n                    data: [\n                        randomScalingFactor(),\n                        randomScalingFactor(),\n                        randomScalingFactor(),\n                        randomScalingFactor(),\n                        randomScalingFactor(),\n                        randomScalingFactor(),\n                        randomScalingFactor()\n                    ],\n                    backgroundColor: window.chartColors.red,\n                    borderColor: window.chartColors.red,\n                    fill: false,\n                    borderDash: [5, 5],\n                    pointRadius: 15,\n                    pointHoverRadius: 10,\n                }, {\n                    label: \"dataset - individual point sizes\",\n                    data: [\n                        randomScalingFactor(),\n                        randomScalingFactor(),\n                        randomScalingFactor(),\n                        randomScalingFactor(),\n                        randomScalingFactor(),\n                        randomScalingFactor(),\n                        randomScalingFactor()\n                    ],\n                    backgroundColor: window.chartColors.blue,\n                    borderColor: window.chartColors.blue,\n                    fill: false,\n                    borderDash: [5, 5],\n                    pointRadius: [2, 4, 6, 18, 0, 12, 20],\n                }, {\n                    label: \"dataset - large pointHoverRadius\",\n                    data: [\n                        randomScalingFactor(),\n                        randomScalingFactor(),\n                        randomScalingFactor(),\n                        randomScalingFactor(),\n                        randomScalingFactor(),\n                        randomScalingFactor(),\n                        randomScalingFactor()\n                    ],\n                    backgroundColor: window.chartColors.green,\n                    borderColor: window.chartColors.green,\n                    fill: false,\n                    pointHoverRadius: 30,\n                }, {\n                    label: \"dataset - large pointHitRadius\",\n                    data: [\n                        randomScalingFactor(),\n                        randomScalingFactor(),\n                        randomScalingFactor(),\n                        randomScalingFactor(),\n                        randomScalingFactor(),\n                        randomScalingFactor(),\n                        randomScalingFactor()\n                    ],\n                    backgroundColor: window.chartColors.yellow,\n                    borderColor: window.chartColors.yellow,\n                    fill: false,\n                    pointHitRadius: 20,\n                }]\n            },\n            options: {\n                responsive: true,\n                legend: {\n                    position: 'bottom',\n                },\n                hover: {\n                    mode: 'index'\n                },\n                scales: {\n                    xAxes: [{\n                        display: true,\n                        scaleLabel: {\n                            display: true,\n                            labelString: 'Month'\n                        }\n                    }],\n                    yAxes: [{\n                        display: true,\n                        scaleLabel: {\n                            display: true,\n                            labelString: 'Value'\n                        }\n                    }]\n                },\n                title: {\n                    display: true,\n                    text: 'Chart.js Line Chart - Different point sizes'\n                }\n            }\n        };\n\n        window.onload = function() {\n            var ctx = document.getElementById(\"canvas\").getContext(\"2d\");\n            window.myLine = new Chart(ctx, config);\n        };\n    </script>\n</body>\n\n</html>\n"
  },
  {
    "path": "app_backend/static/plugin/Chart.js-2.6.0/samples/charts/line/point-styles.html",
    "content": "<!doctype html>\n<html>\n\n<head>\n    <title>Line Chart</title>\n    <script src=\"../../../dist/Chart.bundle.js\"></script>\n    <script src=\"../../utils.js\"></script>\n    <style>\n    canvas{\n        -moz-user-select: none;\n        -webkit-user-select: none;\n        -ms-user-select: none;\n    }\n    .chart-container {\n        width: 500px;\n        margin-left: 40px;\n        margin-right: 40px;\n        margin-bottom: 40px;\n    }\n    .container {\n        display: flex;\n        flex-direction: row;\n        flex-wrap: wrap;\n        justify-content: center;\n    }\n    </style>\n</head>\n\n<body>\n    <div class=\"container\">\n    </div>\n    <script>\n        function createConfig(pointStyle) {\n            return {\n                type: 'line',\n                data: {\n                    labels: [\"January\", \"February\", \"March\", \"April\", \"May\", \"June\", \"July\"],\n                    datasets: [{\n                        label: \"My First dataset\",\n                        backgroundColor: window.chartColors.red,\n                        borderColor: window.chartColors.red,\n                        data: [10, 23, 5, 99, 67, 43, 0],\n                        fill: false,\n                        pointRadius: 10,\n                        pointHoverRadius: 15,\n                        showLine: false // no line shown\n                    }]\n                },\n                options: {\n                    responsive: true,\n                    title:{\n                        display:true,\n                        text:'Point Style: ' + pointStyle\n                    },\n                    legend: {\n                        display: false\n                    },\n                    elements: {\n                        point: {\n                            pointStyle: pointStyle\n                        }\n                    }\n                }\n            };\n        }\n\n        window.onload = function() {\n            var container = document.querySelector('.container');\n            [\n                'circle',\n                'triangle',\n                'rect',\n                'rectRounded',\n                'rectRot',\n                'cross',\n                'crossRot',\n                'star',\n                'line',\n                'dash'\n            ].forEach(function(pointStyle) {\n                var div = document.createElement('div');\n                div.classList.add('chart-container');\n\n                var canvas = document.createElement('canvas');\n                div.appendChild(canvas);\n                container.appendChild(div);\n\n                var ctx = canvas.getContext('2d');\n                var config = createConfig(pointStyle);\n                new Chart(ctx, config);\n            });\n        };\n    </script>\n</body>\n\n</html>\n"
  },
  {
    "path": "app_backend/static/plugin/Chart.js-2.6.0/samples/charts/line/skip-points.html",
    "content": "<!doctype html>\n<html>\n\n<head>\n    <title>Line Chart</title>\n    <script src=\"../../../dist/Chart.bundle.js\"></script>\n    <script src=\"../../utils.js\"></script>\n    <style>\n    canvas {\n        -moz-user-select: none;\n        -webkit-user-select: none;\n        -ms-user-select: none;\n    }\n    </style>\n</head>\n\n<body>\n    <div style=\"width:75%;\">\n        <canvas id=\"canvas\"></canvas>\n    </div>\n    <script>\n        var config = {\n            type: 'line',\n            data: {\n                labels: [\"January\", \"February\", \"March\", \"April\", \"May\", \"June\", \"July\"],\n                datasets: [{\n                    label: \"My First dataset\",\n                    borderColor: window.chartColors.red,\n                    fill: false,\n                    // Skip a point in the middle\n                    data: [\n                        randomScalingFactor(),\n                        randomScalingFactor(),\n                        NaN,\n                        randomScalingFactor(),\n                        randomScalingFactor(),\n                        randomScalingFactor(),\n                        randomScalingFactor()\n                    ],\n\n                }, {\n                    label: \"My Second dataset\",\n                    borderColor: window.chartColors.blue,\n                    fill: false,\n                    // Skip first and last points\n                    data: [\n                        NaN,\n                        randomScalingFactor(),\n                        randomScalingFactor(),\n                        randomScalingFactor(),\n                        randomScalingFactor(),\n                        randomScalingFactor(),\n                        NaN\n                    ],\n                }]\n            },\n            options: {\n                responsive: true,\n                title:{\n                    display:true,\n                    text:'Chart.js Line Chart - Skip Points'\n                },\n                tooltips: {\n                    mode: 'index',\n                },\n                hover: {\n                    mode: 'index'\n                },\n                scales: {\n                    xAxes: [{\n                        display: true,\n                        scaleLabel: {\n                            display: true,\n                            labelString: 'Month'\n                        }\n                    }],\n                    yAxes: [{\n                        display: true,\n                        scaleLabel: {\n                            display: true,\n                            labelString: 'Value'\n                        },\n                    }]\n                }\n            }\n        };\n\n        window.onload = function() {\n            var ctx = document.getElementById(\"canvas\").getContext(\"2d\");\n            window.myLine = new Chart(ctx, config);\n        };\n    </script>\n</body>\n\n</html>\n"
  },
  {
    "path": "app_backend/static/plugin/Chart.js-2.6.0/samples/charts/line/stepped.html",
    "content": "<!doctype html>\n<html>\n\n<head>\n    <title>Stepped Line Chart</title>\n    <script src=\"../../../dist/Chart.bundle.js\"></script>\n    <script src=\"../../utils.js\"></script>\n\t<style>\n\tcanvas {\n\t\t-moz-user-select: none;\n\t\t-webkit-user-select: none;\n\t\t-ms-user-select: none;\n\t}\n\t.chart-container {\n\t\twidth: 500px;\n\t\tmargin-left: 40px;\n\t\tmargin-right: 40px;\n\t\tmargin-bottom: 40px;\n\t}\n\t.container {\n\t\tdisplay: flex;\n\t\tflex-direction: row;\n\t\tflex-wrap: wrap;\n\t\tjustify-content: center;\n\t}\n\t</style>\n</head>\n\n<body>\n\t<div class=\"container\">\n\t</div>\n    <script>\n\tfunction createConfig(details, data) {\n\t\treturn {\n\t\t\ttype: 'line',\n\t\t\tdata: {\n\t\t\t\tlabels: ['Day 1', 'Day 2', 'Day 3', 'Day 4', 'Day 5', 'Day 6'],\n\t\t\t\tdatasets: [{\n\t\t\t\t\tlabel: 'steppedLine: ' + ((typeof(details.steppedLine) === 'boolean') ? details.steppedLine : `'${details.steppedLine}'`),\n\t\t\t\t\tsteppedLine: details.steppedLine,\n\t\t\t\t\tdata: data,\n\t\t\t\t\tborderColor: details.color,\n\t\t\t\t\tfill: false,\n\t\t\t\t}]\n\t\t\t},\n\t\t\toptions: {\n\t\t\t\tresponsive: true,\n\t\t\t\ttitle: {\n\t\t\t\t\tdisplay: true,\n\t\t\t\t\ttext: details.label,\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\t}\n\n\n\twindow.onload = function() {\n\t\tvar container = document.querySelector('.container');\n\n\t\tvar data = [\n\t\t\trandomScalingFactor(),\n\t\t\trandomScalingFactor(),\n\t\t\trandomScalingFactor(),\n\t\t\trandomScalingFactor(),\n\t\t\trandomScalingFactor(),\n\t\t\trandomScalingFactor()\n\t\t];\n\n\t\tvar steppedLineSettings = [{\n\t\t\tsteppedLine: false,\n\t\t\tlabel: 'No Step Interpolation',\n\t\t\tcolor: window.chartColors.red\n\t\t}, {\n\t\t\tsteppedLine: true,\n\t\t\tlabel: 'Step Before Interpolation',\n\t\t\tcolor: window.chartColors.green\n\t\t}, {\n\t\t\tsteppedLine: 'before',\n\t\t\tlabel: 'Step Before Interpolation',\n\t\t\tcolor: window.chartColors.green\n\t\t}, {\n\t\t\tsteppedLine: 'after',\n\t\t\tlabel: 'Step After Interpolation',\n\t\t\tcolor: window.chartColors.purple\n\t\t}];\n\n\t\tsteppedLineSettings.forEach(function(details) {\n\t\t\tvar div = document.createElement('div');\n\t\t\tdiv.classList.add('chart-container');\n\n\t\t\tvar canvas = document.createElement('canvas');\n\t\t\tdiv.appendChild(canvas);\n\t\t\tcontainer.appendChild(div);\n\n\t\t\tvar ctx = canvas.getContext('2d');\n\t\t\tvar config = createConfig(details, data);\n\t\t\tnew Chart(ctx, config);\n\t\t});\n\t};\n    </script>\n</body>\n\n</html>\n"
  },
  {
    "path": "app_backend/static/plugin/Chart.js-2.6.0/samples/charts/pie.html",
    "content": "<!doctype html>\n<html>\n\n<head>\n    <title>Pie Chart</title>\n    <script src=\"../../dist/Chart.bundle.js\"></script>\n    <script src=\"../utils.js\"></script>\n</head>\n\n<body>\n    <div id=\"canvas-holder\" style=\"width:40%\">\n        <canvas id=\"chart-area\" />\n    </div>\n    <button id=\"randomizeData\">Randomize Data</button>\n    <button id=\"addDataset\">Add Dataset</button>\n    <button id=\"removeDataset\">Remove Dataset</button>\n    <script>\n    var randomScalingFactor = function() {\n        return Math.round(Math.random() * 100);\n    };\n\n    var config = {\n        type: 'pie',\n        data: {\n            datasets: [{\n                data: [\n                    randomScalingFactor(),\n                    randomScalingFactor(),\n                    randomScalingFactor(),\n                    randomScalingFactor(),\n                    randomScalingFactor(),\n                ],\n                backgroundColor: [\n                    window.chartColors.red,\n                    window.chartColors.orange,\n                    window.chartColors.yellow,\n                    window.chartColors.green,\n                    window.chartColors.blue,\n                ],\n                label: 'Dataset 1'\n            }],\n            labels: [\n                \"Red\",\n                \"Orange\",\n                \"Yellow\",\n                \"Green\",\n                \"Blue\"\n            ]\n        },\n        options: {\n            responsive: true\n        }\n    };\n\n    window.onload = function() {\n        var ctx = document.getElementById(\"chart-area\").getContext(\"2d\");\n        window.myPie = new Chart(ctx, config);\n    };\n\n    document.getElementById('randomizeData').addEventListener('click', function() {\n        config.data.datasets.forEach(function(dataset) {\n            dataset.data = dataset.data.map(function() {\n                return randomScalingFactor();\n            });\n        });\n\n        window.myPie.update();\n    });\n\n    var colorNames = Object.keys(window.chartColors);\n    document.getElementById('addDataset').addEventListener('click', function() {\n        var newDataset = {\n            backgroundColor: [],\n            data: [],\n            label: 'New dataset ' + config.data.datasets.length,\n        };\n\n        for (var index = 0; index < config.data.labels.length; ++index) {\n            newDataset.data.push(randomScalingFactor());\n\n            var colorName = colorNames[index % colorNames.length];;\n            var newColor = window.chartColors[colorName];\n            newDataset.backgroundColor.push(newColor);\n        }\n\n        config.data.datasets.push(newDataset);\n        window.myPie.update();\n    });\n\n    document.getElementById('removeDataset').addEventListener('click', function() {\n        config.data.datasets.splice(0, 1);\n        window.myPie.update();\n    });\n    </script>\n</body>\n\n</html>\n"
  },
  {
    "path": "app_backend/static/plugin/Chart.js-2.6.0/samples/charts/polar-area.html",
    "content": "<!doctype html>\n<html>\n\n<head>\n    <title>Polar Area Chart</title>\n    <script src=\"../../dist/Chart.bundle.js\"></script>\n    <script src=\"../utils.js\"></script>\n    <style>\n    canvas {\n        -moz-user-select: none;\n        -webkit-user-select: none;\n        -ms-user-select: none;\n    }\n    </style>\n</head>\n\n<body>\n    <div id=\"canvas-holder\" style=\"width:50%\">\n        <canvas id=\"chart-area\"></canvas>\n    </div>\n    <button id=\"randomizeData\">Randomize Data</button>\n    <button id=\"addData\">Add Data</button>\n    <button id=\"removeData\">Remove Data</button>\n    <script>\n    var randomScalingFactor = function() {\n        return Math.round(Math.random() * 100);\n    };\n\n    var chartColors = window.chartColors;\n    var color = Chart.helpers.color;\n    var config = {\n        data: {\n            datasets: [{\n                data: [\n                    randomScalingFactor(),\n                    randomScalingFactor(),\n                    randomScalingFactor(),\n                    randomScalingFactor(),\n                    randomScalingFactor(),\n                ],\n                backgroundColor: [\n                    color(chartColors.red).alpha(0.5).rgbString(),\n                    color(chartColors.orange).alpha(0.5).rgbString(),\n                    color(chartColors.yellow).alpha(0.5).rgbString(),\n                    color(chartColors.green).alpha(0.5).rgbString(),\n                    color(chartColors.blue).alpha(0.5).rgbString(),\n                ],\n                label: 'My dataset' // for legend\n            }],\n            labels: [\n                \"Red\",\n                \"Orange\",\n                \"Yellow\",\n                \"Green\",\n                \"Blue\"\n            ]\n        },\n        options: {\n            responsive: true,\n            legend: {\n                position: 'right',\n            },\n            title: {\n                display: true,\n                text: 'Chart.js Polar Area Chart'\n            },\n            scale: {\n              ticks: {\n                beginAtZero: true\n              },\n              reverse: false\n            },\n            animation: {\n                animateRotate: false,\n                animateScale: true\n            }\n        }\n    };\n\n    window.onload = function() {\n        var ctx = document.getElementById(\"chart-area\");\n        window.myPolarArea = Chart.PolarArea(ctx, config);\n    };\n\n    document.getElementById('randomizeData').addEventListener('click', function() {\n        config.data.datasets.forEach(function(piece, i) {\n            piece.data.forEach(function(value, j) {\n                config.data.datasets[i].data[j] = randomScalingFactor();\n            });\n        });\n        window.myPolarArea.update();\n    });\n\n    var colorNames = Object.keys(window.chartColors);\n    document.getElementById('addData').addEventListener('click', function() {\n        if (config.data.datasets.length > 0) {\n            config.data.labels.push('data #' + config.data.labels.length);\n            config.data.datasets.forEach(function(dataset) {\n                var colorName = colorNames[config.data.labels.length % colorNames.length];\n                dataset.backgroundColor.push(window.chartColors[colorName]);\n                dataset.data.push(randomScalingFactor());\n            });\n            window.myPolarArea.update();\n        }\n    });\n    document.getElementById('removeData').addEventListener('click', function() {\n        config.data.labels.pop(); // remove the label first\n        config.data.datasets.forEach(function(dataset) {\n            dataset.backgroundColor.pop();\n            dataset.data.pop();\n        });\n        window.myPolarArea.update();\n    });\n    </script>\n</body>\n\n</html>\n"
  },
  {
    "path": "app_backend/static/plugin/Chart.js-2.6.0/samples/charts/radar-skip-points.html",
    "content": "<!doctype html>\n<html>\n\n<head>\n    <title>Radar Chart</title>\n    <script src=\"../../dist/Chart.bundle.js\"></script>\n    <script src=\"../utils.js\"></script>\n    <style>\n    canvas {\n        -moz-user-select: none;\n        -webkit-user-select: none;\n        -ms-user-select: none;\n    }\n    </style>\n</head>\n\n<body>\n    <div style=\"width:40%\">\n        <canvas id=\"canvas\"></canvas>\n    </div>\n    <button id=\"randomizeData\">Randomize Data</button>\n    <script>\n    var randomScalingFactor = function() {\n        return Math.round(Math.random() * 100);\n    };\n\n    var color = Chart.helpers.color;\n    var config = {\n        type: 'radar',\n        data: {\n            labels: [\"Eating\", \"Drinking\", \"Sleeping\", \"Designing\", \"Coding\", \"Cycling\", \"Running\"],\n            datasets: [{\n                label: \"Skip first dataset\",\n                borderColor: window.chartColors.red,\n                backgroundColor: color(window.chartColors.red).alpha(0.2).rgbString(),\n                pointBackgroundColor: window.chartColors.red,\n                data: [\n                    NaN, \n                    randomScalingFactor(), \n                    randomScalingFactor(), \n                    randomScalingFactor(), \n                    randomScalingFactor(), \n                    randomScalingFactor(), \n                    randomScalingFactor()\n                ]\n            }, {\n                label: \"Skip mid dataset\",\n                borderColor: window.chartColors.blue,\n                backgroundColor: color(window.chartColors.blue).alpha(0.2).rgbString(),\n                pointBackgroundColor: window.chartColors.blue,\n                data: [\n                    randomScalingFactor(), \n                    randomScalingFactor(), \n                    NaN, \n                    randomScalingFactor(), \n                    randomScalingFactor(), \n                    randomScalingFactor(), \n                    randomScalingFactor()\n                ]\n            },{\n                label: \"Skip last dataset\",\n                borderColor: window.chartColors.green,\n                backgroundColor: color(window.chartColors.green).alpha(0.2).rgbString(),\n                pointBackgroundColor: window.chartColors.green,\n                data: [\n                    randomScalingFactor(), \n                    randomScalingFactor(), \n                    randomScalingFactor(), \n                    randomScalingFactor(), \n                    randomScalingFactor(), \n                    randomScalingFactor(),\n                    NaN\n                ]\n            }]\n        },\n        options: {\n            title:{\n                display:true,\n                text:\"Chart.js Radar Chart - Skip Points\"\n            },\n            elements: {\n                line: {\n                    tension: 0.0,\n                }\n            },\n            scale: {\n                beginAtZero: true,\n            }\n        }\n    };\n\n    window.onload = function() {\n        window.myRadar = new Chart(document.getElementById(\"canvas\"), config);\n    };\n\n    document.getElementById('randomizeData').addEventListener('click', function() {\n        config.data.datasets.forEach(function(dataset) {\n            dataset.data = dataset.data.map(function() {\n                return randomScalingFactor();\n            });\n\n        });\n\n        window.myRadar.update();\n    });\n    </script>\n</body>\n\n</html>\n"
  },
  {
    "path": "app_backend/static/plugin/Chart.js-2.6.0/samples/charts/radar.html",
    "content": "<!doctype html>\n<html>\n\n<head>\n    <title>Radar Chart</title>\n    <script src=\"../../dist/Chart.bundle.js\"></script>\n    <script src=\"../utils.js\"></script>\n    <style>\n    canvas {\n        -moz-user-select: none;\n        -webkit-user-select: none;\n        -ms-user-select: none;\n    }\n    </style>\n</head>\n\n<body>\n    <div style=\"width:40%\">\n        <canvas id=\"canvas\"></canvas>\n    </div>\n    <button id=\"randomizeData\">Randomize Data</button>\n    <button id=\"addDataset\">Add Dataset</button>\n    <button id=\"removeDataset\">Remove Dataset</button>\n    <button id=\"addData\">Add Data</button>\n    <button id=\"removeData\">Remove Data</button>\n    <script>\n    var randomScalingFactor = function() {\n        return Math.round(Math.random() * 100);\n    };\n\n    var color = Chart.helpers.color;\n    var config = {\n        type: 'radar',\n        data: {\n            labels: [[\"Eating\", \"Dinner\"], [\"Drinking\", \"Water\"], \"Sleeping\", [\"Designing\", \"Graphics\"], \"Coding\", \"Cycling\", \"Running\"],\n            datasets: [{\n                label: \"My First dataset\",\n                backgroundColor: color(window.chartColors.red).alpha(0.2).rgbString(),\n                borderColor: window.chartColors.red,\n                pointBackgroundColor: window.chartColors.red,\n                data: [\n                    randomScalingFactor(),\n                    randomScalingFactor(),\n                    randomScalingFactor(),\n                    randomScalingFactor(),\n                    randomScalingFactor(),\n                    randomScalingFactor(),\n                    randomScalingFactor()\n                ]\n            }, {\n                label: \"My Second dataset\",\n                backgroundColor: color(window.chartColors.blue).alpha(0.2).rgbString(),\n                borderColor: window.chartColors.blue,\n                pointBackgroundColor: window.chartColors.blue,\n                data: [\n                    randomScalingFactor(),\n                    randomScalingFactor(),\n                    randomScalingFactor(),\n                    randomScalingFactor(),\n                    randomScalingFactor(),\n                    randomScalingFactor(),\n                    randomScalingFactor()\n                ]\n            },]\n        },\n        options: {\n            legend: {\n                position: 'top',\n            },\n            title: {\n                display: true,\n                text: 'Chart.js Radar Chart'\n            },\n            scale: {\n              ticks: {\n                beginAtZero: true\n              }\n            }\n        }\n    };\n\n    window.onload = function() {\n        window.myRadar = new Chart(document.getElementById(\"canvas\"), config);\n    };\n\n    document.getElementById('randomizeData').addEventListener('click', function() {\n        config.data.datasets.forEach(function(dataset) {\n            dataset.data = dataset.data.map(function() {\n                return randomScalingFactor();\n            });\n        });\n\n        window.myRadar.update();\n    });\n\n    var colorNames = Object.keys(window.chartColors);\n    document.getElementById('addDataset').addEventListener('click', function() {\n        var colorName = colorNames[config.data.datasets.length % colorNames.length];;\n        var newColor = window.chartColors[colorName];\n\n        var newDataset = {\n            label: 'Dataset ' + config.data.datasets.length,\n            borderColor: newColor,\n            backgroundColor: color(newColor).alpha(0.2).rgbString(),\n            pointBorderColor: newColor,\n            data: [],\n        };\n\n        for (var index = 0; index < config.data.labels.length; ++index) {\n            newDataset.data.push(randomScalingFactor());\n        }\n\n        config.data.datasets.push(newDataset);\n        window.myRadar.update();\n    });\n\n    document.getElementById('addData').addEventListener('click', function() {\n        if (config.data.datasets.length > 0) {\n            config.data.labels.push('dataset #' + config.data.labels.length);\n\n            config.data.datasets.forEach(function (dataset) {\n                dataset.data.push(randomScalingFactor());\n            });\n\n            window.myRadar.update();\n        }\n    });\n\n    document.getElementById('removeDataset').addEventListener('click', function() {\n        config.data.datasets.splice(0, 1);\n        window.myRadar.update();\n    });\n\n    document.getElementById('removeData').addEventListener('click', function() {\n        config.data.labels.pop(); // remove the label first\n\n        config.data.datasets.forEach(function(dataset) {\n            dataset.data.pop();\n        });\n\n        window.myRadar.update();\n    });\n    </script>\n</body>\n\n</html>\n"
  },
  {
    "path": "app_backend/static/plugin/Chart.js-2.6.0/samples/charts/scatter/basic.html",
    "content": "<!doctype html>\n<html>\n\n<head>\n    <title>Scatter Chart</title>\n    <script src=\"../../../dist/Chart.bundle.js\"></script>\n    <script src=\"../../utils.js\"></script>\n    <style>\n    canvas {\n        -moz-user-select: none;\n        -webkit-user-select: none;\n        -ms-user-select: none;\n    }\n    </style>\n</head>\n\n<body>\n    <div style=\"width:75%\">\n        <canvas id=\"canvas\"></canvas>\n    </div>\n    <button id=\"randomizeData\">Randomize Data</button>\n    <script>\n        var color = Chart.helpers.color;\n        var scatterChartData = {\n            datasets: [{\n                label: \"My First dataset\",\n                borderColor: window.chartColors.red,\n                backgroundColor: color(window.chartColors.red).alpha(0.2).rgbString(),\n                data: [{\n                    x: randomScalingFactor(),\n                    y: randomScalingFactor(),\n                }, {\n                    x: randomScalingFactor(),\n                    y: randomScalingFactor(),\n                }, {\n                    x: randomScalingFactor(),\n                    y: randomScalingFactor(),\n                }, {\n                    x: randomScalingFactor(),\n                    y: randomScalingFactor(),\n                }, {\n                    x: randomScalingFactor(),\n                    y: randomScalingFactor(),\n                }, {\n                    x: randomScalingFactor(),\n                    y: randomScalingFactor(),\n                }, {\n                    x: randomScalingFactor(),\n                    y: randomScalingFactor(),\n                }]\n            }, {\n                label: \"My Second dataset\",\n                borderColor: window.chartColors.blue,\n                backgroundColor: color(window.chartColors.blue).alpha(0.2).rgbString(),\n                data: [{\n                    x: randomScalingFactor(),\n                    y: randomScalingFactor(),\n                }, {\n                    x: randomScalingFactor(),\n                    y: randomScalingFactor(),\n                }, {\n                    x: randomScalingFactor(),\n                    y: randomScalingFactor(),\n                }, {\n                    x: randomScalingFactor(),\n                    y: randomScalingFactor(),\n                }, {\n                    x: randomScalingFactor(),\n                    y: randomScalingFactor(),\n                }, {\n                    x: randomScalingFactor(),\n                    y: randomScalingFactor(),\n                }, {\n                    x: randomScalingFactor(),\n                    y: randomScalingFactor(),\n                }]\n            }]\n        };\n\n        window.onload = function() {\n            var ctx = document.getElementById(\"canvas\").getContext(\"2d\");\n            window.myScatter = Chart.Scatter(ctx, {\n                data: scatterChartData,\n                options: {\n                    title: {\n                        display: true,\n                        text: 'Chart.js Scatter Chart'\n                    },\n                }\n            });\n        };\n\n        document.getElementById('randomizeData').addEventListener('click', function() {\n            scatterChartData.datasets.forEach(function(dataset) {\n                dataset.data = dataset.data.map(function() {\n                    return {\n                        x: randomScalingFactor(),\n                        y: randomScalingFactor()\n                    };\n                });\n            });\n            window.myScatter.update();\n        });\n    </script>\n</body>\n\n</html>\n"
  },
  {
    "path": "app_backend/static/plugin/Chart.js-2.6.0/samples/charts/scatter/multi-axis.html",
    "content": "<!doctype html>\n<html>\n\n<head>\n\t<title>Scatter Chart Multi Axis</title>\n\t<script src=\"../../../dist/Chart.bundle.js\"></script>\n\t<script src=\"../../utils.js\"></script>\n\t<style>\n\tcanvas {\n\t\t-moz-user-select: none;\n\t\t-webkit-user-select: none;\n\t\t-ms-user-select: none;\n\t}\n\t</style>\n</head>\n\n<body>\n\t<div style=\"width:75%\">\n\t\t<canvas id=\"canvas\"></canvas>\n\t</div>\n\t<button id=\"randomizeData\">Randomize Data</button>\n\t<script>\n\tvar color = Chart.helpers.color;\n\tvar scatterChartData = {\n\t\tdatasets: [{\n\t\t\tlabel: \"My First dataset\",\n\t\t\txAxisID: \"x-axis-1\",\n\t\t\tyAxisID: \"y-axis-1\",\n\t\t\tborderColor: window.chartColors.red,\n\t\t\tbackgroundColor: color(window.chartColors.red).alpha(0.2).rgbString(),\n\t\t\tdata: [{\n\t\t\t\tx: randomScalingFactor(),\n\t\t\t\ty: randomScalingFactor(),\n\t\t\t}, {\n\t\t\t\tx: randomScalingFactor(),\n\t\t\t\ty: randomScalingFactor(),\n\t\t\t}, {\n\t\t\t\tx: randomScalingFactor(),\n\t\t\t\ty: randomScalingFactor(),\n\t\t\t}, {\n\t\t\t\tx: randomScalingFactor(),\n\t\t\t\ty: randomScalingFactor(),\n\t\t\t}, {\n\t\t\t\tx: randomScalingFactor(),\n\t\t\t\ty: randomScalingFactor(),\n\t\t\t}, {\n\t\t\t\tx: randomScalingFactor(),\n\t\t\t\ty: randomScalingFactor(),\n\t\t\t}, {\n\t\t\t\tx: randomScalingFactor(),\n\t\t\t\ty: randomScalingFactor(),\n\t\t\t}]\n\t\t}, {\n\t\t\tlabel: \"My Second dataset\",\n\t\t\txAxisID: \"x-axis-1\",\n\t\t\tyAxisID: \"y-axis-2\",\n\t\t\tborderColor: window.chartColors.blue,\n\t\t\tbackgroundColor: color(window.chartColors.blue).alpha(0.2).rgbString(),\n\t\t\tdata: [{\n\t\t\t\tx: randomScalingFactor(),\n\t\t\t\ty: randomScalingFactor(),\n\t\t\t}, {\n\t\t\t\tx: randomScalingFactor(),\n\t\t\t\ty: randomScalingFactor(),\n\t\t\t}, {\n\t\t\t\tx: randomScalingFactor(),\n\t\t\t\ty: randomScalingFactor(),\n\t\t\t}, {\n\t\t\t\tx: randomScalingFactor(),\n\t\t\t\ty: randomScalingFactor(),\n\t\t\t}, {\n\t\t\t\tx: randomScalingFactor(),\n\t\t\t\ty: randomScalingFactor(),\n\t\t\t}, {\n\t\t\t\tx: randomScalingFactor(),\n\t\t\t\ty: randomScalingFactor(),\n\t\t\t}, {\n\t\t\t\tx: randomScalingFactor(),\n\t\t\t\ty: randomScalingFactor(),\n\t\t\t}]\n\t\t}]\n\t};\n\n\twindow.onload = function() {\n\t\tvar ctx = document.getElementById(\"canvas\").getContext(\"2d\");\n\t\twindow.myScatter = Chart.Scatter(ctx, {\n\t\t\tdata: scatterChartData,\n\t\t\toptions: {\n\t\t\t\tresponsive: true,\n\t\t\t\thoverMode: 'nearest',\n\t\t\t\tintersect: true,\n\t\t\t\ttitle: {\n\t\t\t\t\tdisplay: true,\n\t\t\t\t\ttext: 'Chart.js Scatter Chart - Multi Axis'\n\t\t\t\t},\n\t\t\t\tscales: {\n\t\t\t\t\txAxes: [{\n\t\t\t\t\t\tposition: \"bottom\",\n\t\t\t\t\t\tgridLines: {\n\t\t\t\t\t\t\tzeroLineColor: \"rgba(0,0,0,1)\"\n\t\t\t\t\t\t}\n\t\t\t\t\t}],\n\t\t\t\t\tyAxes: [{\n\t\t\t\t\t\ttype: \"linear\", // only linear but allow scale type registration. This allows extensions to exist solely for log scale for instance\n\t\t\t\t\t\tdisplay: true,\n\t\t\t\t\t\tposition: \"left\",\n\t\t\t\t\t\tid: \"y-axis-1\",\n\t\t\t\t\t}, {\n\t\t\t\t\t\ttype: \"linear\", // only linear but allow scale type registration. This allows extensions to exist solely for log scale for instance\n\t\t\t\t\t\tdisplay: true,\n\t\t\t\t\t\tposition: \"right\",\n\t\t\t\t\t\treverse: true,\n\t\t\t\t\t\tid: \"y-axis-2\",\n\n\t\t\t\t\t\t// grid line settings\n\t\t\t\t\t\tgridLines: {\n\t\t\t\t\t\t\tdrawOnChartArea: false, // only want the grid lines for one axis to show up\n\t\t\t\t\t\t},\n\t\t\t\t\t}],\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\t};\n\n\tdocument.getElementById('randomizeData').addEventListener('click', function() {\n\t\tscatterChartData.datasets.forEach(function(dataset) {\n\t\t\tdataset.data = dataset.data.map(function() {\n\t\t\t\treturn {\n\t\t\t\t\tx: randomScalingFactor(),\n\t\t\t\t\ty: randomScalingFactor()\n\t\t\t\t};\n\t\t\t});\n\t\t});\n\t\twindow.myScatter.update();\n\t});\n\t</script>\n</body>\n\n</html>\n"
  },
  {
    "path": "app_backend/static/plugin/Chart.js-2.6.0/samples/index.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en-US\">\n<head>\n\t<meta charset=\"utf-8\">\n\t<meta http-equiv=\"X-UA-Compatible\" content=\"IE=Edge\">\n\t<meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"style.css\">\n\t<link rel=\"icon\" href=\"favicon.ico\">\n\t<script src=\"samples.js\"></script>\n\t<title>Chart.js samples</title>\n</head>\n<body>\n\t<div class=\"content\">\n\t\t<div class=\"header\">\n\t\t\t<div class=\"chartjs-title\">Samples</div>\n\t\t\t<div class=\"chartjs-caption\">Simple yet flexible JavaScript charting for designers &amp; developers</div>\n\t\t\t<div class=\"chartjs-links\">\n\t\t\t\t<a class=\"btn btn-chartjs\" href=\"http://www.chartjs.org\">Website</a>\n\t\t\t\t<a class=\"btn btn-docs\" href=\"http://www.chartjs.org/docs\">Documentation</a>\n\t\t\t\t<a class=\"btn btn-gh\" href=\"https://github.com/chartjs/Chart.js\">GitHub</a>\n\t\t\t</div>\n\t\t</div>\n\n\t\t<div id=\"categories\" class=\"samples-categories\"></div>\n\t</div>\n\n\t<script>\n\t\tfunction createCategory(item) {\n\t\t\tvar el = document.createElement('div');\n\t\t\tel.className = 'samples-category';\n\t\t\tel.innerHTML =\n\t\t\t\t'<div class=\"title\">' + item.title + '</div>' +\n\t\t\t\t'<div class=\"items\"></div>';\n\t\t\treturn el;\n\t\t}\n\n\t\tfunction createEntry(item) {\n\t\t\tvar el = document.createElement('div');\n\t\t\tel.className = 'samples-entry';\n\t\t\tel.innerHTML = '<a class=\"title\" href=\"' + item.path + '\">' + item.title + '</a>';\n\t\t\treturn el;\n\t\t}\n\n\t\tvar categories = document.getElementById('categories');\n\t\tSamples.items.forEach(function(item) {\n\t\t\tvar category = createCategory(item);\n\t\t\tvar children = category.getElementsByClassName('items')[0];\n\n\t\t\t(item.items || []).forEach(function(item) {\n\t\t\t\tchildren.appendChild(createEntry(item));\n\t\t\t});\n\n\t\t\tcategories.appendChild(category);\n\t\t});\n\t</script>\n</body>\n</html>\n"
  },
  {
    "path": "app_backend/static/plugin/Chart.js-2.6.0/samples/legend/point-style.html",
    "content": "<!doctype html>\n<html>\n\n<head>\n    <title>Legend Point Style</title>\n    <script src=\"../../dist/Chart.bundle.js\"></script>\n    <script src=\"../utils.js\"></script>\n    <style>\n        canvas {\n            -moz-user-select: none;\n            -webkit-user-select: none;\n            -ms-user-select: none;\n        }\n        .chart-container {\n            width: 500px;\n            margin-left: 40px;\n            margin-right: 40px;\n        }\n        .container {\n            display: flex;\n            flex-direction: row;\n            flex-wrap: wrap;\n            justify-content: center;\n        }\n    </style>\n</head>\n\n<body>\n    <div class=\"container\">\n        <div class=\"chart-container\">\n            <canvas id=\"chart-legend-normal\"></canvas>\n        </div>\n        <div class=\"chart-container\">\n            <canvas id=\"chart-legend-pointstyle\"></canvas>\n        </div>\n    </div>\n    <script>\n        var color = Chart.helpers.color;\n        function createConfig(colorName) {\n            return {\n                type: 'line',\n                data: {\n                    labels: [\"January\", \"February\", \"March\", \"April\", \"May\", \"June\", \"July\"],\n                    datasets: [{\n                        label: \"My First dataset\",\n                        data: [\n                            randomScalingFactor(), \n                            randomScalingFactor(), \n                            randomScalingFactor(), \n                            randomScalingFactor(), \n                            randomScalingFactor(), \n                            randomScalingFactor(), \n                            randomScalingFactor()\n                        ],\n                        backgroundColor: color(window.chartColors[colorName]).alpha(0.5).rgbString(),\n                        borderColor: window.chartColors[colorName],\n                        borderWidth: 1,\n                        pointStyle: 'rectRot',\n                        pointRadius: 5,\n                        pointBorderColor: 'rgb(0, 0, 0)'\n                    }]\n                },\n                options: {\n                    responsive: true,\n                    legend: {\n                        labels: {\n                            usePointStyle: false\n                        }\n                    },\n                    scales: {\n                        xAxes: [{\n                            display: true,\n                            scaleLabel: {\n                                display: true,\n                                labelString: 'Month'\n                            }\n                        }],\n                        yAxes: [{\n                            display: true,\n                            scaleLabel: {\n                                display: true,\n                                labelString: 'Value'\n                            }\n                        }]\n                    },\n                    title: {\n                        display: true,\n                        text: 'Normal Legend'\n                    }\n                }\n            };\n        }\n\n        function createPointStyleConfig(colorName) {\n            var config = createConfig(colorName);\n            config.options.legend.labels.usePointStyle = true;\n            config.options.title.text = 'Point Style Legend';\n            return config;\n        }\n\n        window.onload = function() {\n            [{\n                id: 'chart-legend-normal',\n                config: createConfig('red')\n            }, {\n                id: 'chart-legend-pointstyle',\n                config: createPointStyleConfig('blue')\n            }].forEach(function(details) {\n                var ctx = document.getElementById(details.id).getContext('2d');\n                new Chart(ctx, details.config)\n            })\n        };\n    </script>\n</body>\n\n</html>\n"
  },
  {
    "path": "app_backend/static/plugin/Chart.js-2.6.0/samples/legend/positioning.html",
    "content": "<!doctype html>\n<html>\n\n<head>\n    <title>Legend Positions</title>\n    <script src=\"../../dist/Chart.bundle.js\"></script>\n    <script src=\"../utils.js\"></script>\n    <style>\n        canvas {\n            -moz-user-select: none;\n            -webkit-user-select: none;\n            -ms-user-select: none;\n        }\n        .chart-container {\n            width: 500px;\n            margin-left: 40px;\n            margin-right: 40px;\n        }\n        .container {\n            display: flex;\n            flex-direction: row;\n            flex-wrap: wrap;\n            justify-content: center;\n        }\n    </style>\n</head>\n\n<body>\n    <div class=\"container\">\n        <div class=\"chart-container\">\n            <canvas id=\"chart-legend-top\"></canvas>\n        </div>\n        <div class=\"chart-container\">\n            <canvas id=\"chart-legend-right\"></canvas>\n        </div>\n        <div class=\"chart-container\">\n            <canvas id=\"chart-legend-bottom\"></canvas>\n        </div>\n        <div class=\"chart-container\">\n            <canvas id=\"chart-legend-left\"></canvas>\n        </div>\n    </div>\n    <script>\n        var color = Chart.helpers.color;\n        function createConfig(legendPosition, colorName) {\n            return {\n                type: 'line',\n                data: {\n                    labels: [\"January\", \"February\", \"March\", \"April\", \"May\", \"June\", \"July\"],\n                    datasets: [{\n                        label: \"My First dataset\",\n                        data: [\n                            randomScalingFactor(), \n                            randomScalingFactor(), \n                            randomScalingFactor(), \n                            randomScalingFactor(), \n                            randomScalingFactor(), \n                            randomScalingFactor(), \n                            randomScalingFactor()\n                        ],\n                        backgroundColor: color(window.chartColors[colorName]).alpha(0.5).rgbString(),\n                        borderColor: window.chartColors[colorName],\n                        borderWidth: 1\n                    }]\n                },\n                options: {\n                    responsive: true,\n                    legend: {\n                        position: legendPosition,\n                    },\n                    scales: {\n                        xAxes: [{\n                            display: true,\n                            scaleLabel: {\n                                display: true,\n                                labelString: 'Month'\n                            }\n                        }],\n                        yAxes: [{\n                            display: true,\n                            scaleLabel: {\n                                display: true,\n                                labelString: 'Value'\n                            }\n                        }]\n                    },\n                    title: {\n                        display: true,\n                        text: 'Legend Position: ' + legendPosition\n                    }\n                }\n            };\n        }\n\n        window.onload = function() {\n            [{\n                id: 'chart-legend-top',\n                legendPosition: 'top',\n                color: 'red'\n            }, {\n                id: 'chart-legend-right',\n                legendPosition: 'right',\n                color: 'blue'\n            }, {\n                id: 'chart-legend-bottom',\n                legendPosition: 'bottom',\n                color: 'green'\n            }, {\n                id: 'chart-legend-left',\n                legendPosition: 'left',\n                color: 'yellow'\n            }].forEach(function(details) {\n                var ctx = document.getElementById(details.id).getContext('2d');\n                var config = createConfig(details.legendPosition, details.color);\n                new Chart(ctx, config)\n            })\n        };\n    </script>\n</body>\n\n</html>\n"
  },
  {
    "path": "app_backend/static/plugin/Chart.js-2.6.0/samples/samples.js",
    "content": "(function(global) {\n\n\tvar Samples = global.Samples || (global.Samples = {});\n\n\tSamples.items = [{\n\t\ttitle: 'Bar charts',\n\t\titems: [{\n\t\t\ttitle: 'Vertical',\n\t\t\tpath: 'charts/bar/vertical.html'\n\t\t}, {\n\t\t\ttitle: 'Horizontal',\n\t\t\tpath: 'charts/bar/horizontal.html'\n\t\t}, {\n\t\t\ttitle: 'Multi axis',\n\t\t\tpath: 'charts/bar/multi-axis.html'\n\t\t}, {\n\t\t\ttitle: 'Stacked',\n\t\t\tpath: 'charts/bar/stacked.html'\n\t\t}, {\n\t\t\ttitle: 'Stacked groups',\n\t\t\tpath: 'charts/bar/stacked-group.html'\n\t\t}]\n\t}, {\n\t\ttitle: 'Line charts',\n\t\titems: [{\n\t\t\ttitle: 'Basic',\n\t\t\tpath: 'charts/line/basic.html'\n\t\t}, {\n\t\t\ttitle: 'Multi axis',\n\t\t\tpath: 'charts/line/multi-axis.html'\n\t\t}, {\n\t\t\ttitle: 'Stepped',\n\t\t\tpath: 'charts/line/stepped.html'\n\t\t}, {\n\t\t\ttitle: 'Interpolation',\n\t\t\tpath: 'charts/line/interpolation-modes.html'\n\t\t}, {\n\t\t\ttitle: 'Line styles',\n\t\t\tpath: 'charts/line/line-styles.html'\n\t\t}, {\n\t\t\ttitle: 'Point styles',\n\t\t\tpath: 'charts/line/point-styles.html'\n\t\t}, {\n\t\t\ttitle: 'Point sizes',\n\t\t\tpath: 'charts/line/point-sizes.html'\n\t\t}]\n\t}, {\n\t\ttitle: 'Area charts',\n\t\titems: [{\n\t\t\ttitle: 'Boundaries (line)',\n\t\t\tpath: 'charts/area/line-boundaries.html'\n\t\t}, {\n\t\t\ttitle: 'Datasets (line)',\n\t\t\tpath: 'charts/area/line-datasets.html'\n\t\t}, {\n\t\t\ttitle: 'Stacked (line)',\n\t\t\tpath: 'charts/area/line-stacked.html'\n\t\t}, {\n\t\t\ttitle: 'Radar',\n\t\t\tpath: 'charts/area/radar.html'\n\t\t}]\n\t}, {\n\t\ttitle: 'Other charts',\n\t\titems: [{\n\t\t\ttitle: 'Scatter',\n\t\t\tpath: 'charts/scatter/basic.html'\n\t\t}, {\n\t\t\ttitle: 'Scatter - Multi axis',\n\t\t\tpath: 'charts/scatter/multi-axis.html'\n\t\t}, {\n\t\t\ttitle: 'Doughnut',\n\t\t\tpath: 'charts/doughnut.html'\n\t\t}, {\n\t\t\ttitle: 'Pie',\n\t\t\tpath: 'charts/pie.html'\n\t\t}, {\n\t\t\ttitle: 'Polar area',\n\t\t\tpath: 'charts/polar-area.html'\n\t\t}, {\n\t\t\ttitle: 'Radar',\n\t\t\tpath: 'charts/radar.html'\n\t\t}, {\n\t\t\ttitle: 'Combo bar/line',\n\t\t\tpath: 'charts/combo-bar-line.html'\n\t\t}]\n\t}, {\n\t\ttitle: 'Linear scale',\n\t\titems: [{\n\t\t\ttitle: 'Step size',\n\t\t\tpath: 'scales/linear/step-size.html'\n\t\t}, {\n\t\t\ttitle: 'Min & max',\n\t\t\tpath: 'scales/linear/min-max.html'\n\t\t}, {\n\t\t\ttitle: 'Min & max (suggested)',\n\t\t\tpath: 'scales/linear/min-max-suggested.html'\n\t\t}]\n\t}, {\n\t\ttitle: 'Logarithmic scale',\n\t\titems: [{\n\t\t\ttitle: 'Line',\n\t\t\tpath: 'scales/logarithmic/line.html'\n\t\t}, {\n\t\t\ttitle: 'Scatter',\n\t\t\tpath: 'scales/logarithmic/scatter.html'\n\t\t}]\n\t}, {\n\t\ttitle: 'Time scale',\n\t\titems: [{\n\t\t\ttitle: 'Line',\n\t\t\tpath: 'scales/time/line.html'\n\t\t}, {\n\t\t\ttitle: 'Line (point data)',\n\t\t\tpath: 'scales/time/line-point-data.html'\n\t\t}, {\n\t\t\ttitle: 'Combo',\n\t\t\tpath: 'scales/time/combo.html'\n\t\t}]\n\t}, {\n\t\ttitle: 'Scale options',\n\t\titems: [{\n\t\t\ttitle: 'Grid lines display',\n\t\t\tpath: 'scales/gridlines-display.html'\n\t\t}, {\n\t\t\ttitle: 'Grid lines style',\n\t\t\tpath: 'scales/gridlines-style.html'\n\t\t}, {\n\t\t\ttitle: 'Multiline labels',\n\t\t\tpath: 'scales/multiline-labels.html'\n\t\t}, {\n\t\t\ttitle: 'Filtering Labels',\n\t\t\tpath: 'scales/filtering-labels.html'\n\t\t}, {\n\t\t\ttitle: 'Non numeric Y Axis',\n\t\t\tpath: 'scales/non-numeric-y.html'\n\t\t}]\n\t}, {\n\t\ttitle: 'Legend',\n\t\titems: [{\n\t\t\ttitle: 'Positioning',\n\t\t\tpath: 'legend/positioning.html'\n\t\t}, {\n\t\t\ttitle: 'Point style',\n\t\t\tpath: 'legend/point-style.html'\n\t\t}]\n\t}, {\n\t\ttitle: 'Tooltip',\n\t\titems: [{\n\t\t\ttitle: 'Positioning',\n\t\t\tpath: 'tooltips/positioning.html'\n\t\t}, {\n\t\t\ttitle: 'Interactions',\n\t\t\tpath: 'tooltips/interactions.html'\n\t\t}, {\n\t\t\ttitle: 'Callbacks',\n\t\t\tpath: 'tooltips/callbacks.html'\n\t\t}, {\n\t\t\ttitle: 'Border',\n\t\t\tpath: 'tooltips/border.html'\n\t\t}, {\n\t\t\ttitle: 'HTML tooltips (line)',\n\t\t\tpath: 'tooltips/custom-line.html'\n\t\t}, {\n\t\t\ttitle: 'HTML tooltips (pie)',\n\t\t\tpath: 'tooltips/custom-pie.html'\n\t\t}, {\n\t\t\ttitle: 'HTML tooltips (points)',\n\t\t\tpath: 'tooltips/custom-points.html'\n\t\t}]\n\t}, {\n\t\ttitle: 'Advanced',\n\t\titems: [{\n\t\t\ttitle: 'Progress bar',\n\t\t\tpath: 'advanced/progress-bar.html'\n\t\t}, {\n\t\t\ttitle: 'Data labelling (plugin)',\n\t\t\tpath: 'advanced/data-labelling.html'\n\t\t}]\n\t}];\n\n}(this));\n"
  },
  {
    "path": "app_backend/static/plugin/Chart.js-2.6.0/samples/scales/filtering-labels.html",
    "content": "<!doctype html>\n<html>\n\n<head>\n    <title>Chart with xAxis Filtering</title>\n    <script src=\"../../dist/Chart.bundle.js\"></script>\n    <script src=\"../utils.js\"></script>\n    <style>\n    canvas {\n        -moz-user-select: none;\n        -webkit-user-select: none;\n        -ms-user-select: none;\n    }\n    </style>\n</head>\n\n<body>\n    <div style=\"width:75%;\">\n        <canvas id=\"canvas\"></canvas>\n    </div>\n    <script>\n        var MONTHS = [\"January\", \"February\", \"March\", \"April\", \"May\", \"June\", \"July\", \"August\", \"September\", \"October\", \"November\", \"December\"];\n\n        var randomScalingFactor = function() {\n            return Math.round(Math.random() * 50 * (Math.random() > 0.5 ? 1 : 1)) + 50;\n        };\n\n        var config = {\n            type: 'line',\n            data: {\n                labels: [\"January\", \"February\", \"March\", \"April\", \"May\", \"June\", \"July\"],\n                datasets: [{\n                    label: \"My First dataset\",\n                    fill: false,\n                    borderColor: window.chartColors.red,\n                    backgroundColor: window.chartColors.red,\n                    data: [\n                        randomScalingFactor(), \n                        randomScalingFactor(), \n                        randomScalingFactor(), \n                        randomScalingFactor(), \n                        randomScalingFactor(), \n                        randomScalingFactor(), \n                        randomScalingFactor()\n                    ]\n                }, {\n                    label: \"My Second dataset\",\n                    fill: false,\n                    borderColor: window.chartColors.blue,\n                    backgroundColor: window.chartColors.blue,\n                    data: [\n                        randomScalingFactor(), \n                        randomScalingFactor(), \n                        randomScalingFactor(), \n                        randomScalingFactor(), \n                        randomScalingFactor(), \n                        randomScalingFactor(), \n                        randomScalingFactor()\n                    ]\n                }]\n            },\n            options: {\n                responsive: true,\n                title:{\n                    display:true,\n                    text:\"Chart.js Line Chart - X-Axis Filter\"\n                },\n                scales: {\n                    xAxes: [{\n                        display: true,\n                        ticks: {\n                            callback: function(dataLabel, index) {\n                                // Hide the label of every 2nd dataset. return null to hide the grid line too\n                                return index % 2 === 0 ? dataLabel : '';\n                            }\n                        }\n                    }],\n                    yAxes: [{\n                        display: true,\n                        beginAtZero: false\n                    }]\n                }\n            }\n        };\n\n        window.onload = function() {\n            var ctx = document.getElementById(\"canvas\").getContext(\"2d\");\n            window.myLine = new Chart(ctx, config);\n        };\n    </script>\n</body>\n\n</html>\n"
  },
  {
    "path": "app_backend/static/plugin/Chart.js-2.6.0/samples/scales/gridlines-display.html",
    "content": "<!doctype html>\n<html>\n\n<head>\n    <title>Suggested Min/Max Settings</title>\n    <script src=\"../../dist/Chart.bundle.js\"></script>\n    <script src=\"../utils.js\"></script>\n    <style>\n    canvas{\n        -moz-user-select: none;\n        -webkit-user-select: none;\n        -ms-user-select: none;\n    }\n    .chart-container {\n        width: 500px;\n        margin-left: 40px;\n        margin-right: 40px;\n        margin-bottom: 40px;\n    }\n    .container {\n        display: flex;\n        flex-direction: row;\n        flex-wrap: wrap;\n        justify-content: center;\n    }\n    </style>\n</head>\n\n<body>\n    <div class=\"container\"></div>\n    <script>\n        function createConfig(gridlines, title) {\n            return {\n                type: 'line',\n                data: {\n                    labels: [\"January\", \"February\", \"March\", \"April\", \"May\", \"June\", \"July\"],\n                    datasets: [{\n                        label: \"My First dataset\",\n                        backgroundColor: window.chartColors.red,\n                        borderColor: window.chartColors.red,\n                        data: [10, 30, 39, 20, 25, 34, 0],\n                        fill: false,\n                    }, {\n                        label: \"My Second dataset\",\n                        fill: false,\n                        backgroundColor: window.chartColors.blue,\n                        borderColor: window.chartColors.blue,\n                        data: [18, 33, 22, 19, 11, 39, 30],\n                    }]\n                },\n                options: {\n                    responsive: true,\n                    title:{\n                        display: true,\n                        text: title\n                    },\n                    scales: {\n                        xAxes: [{\n                            gridLines: gridlines\n                        }],\n                        yAxes: [{\n                            gridLines: gridlines,\n                            ticks: {\n                                min: 0,\n                                max: 100,\n                                stepSize: 10\n                            }\n                        }]\n                    }\n                }\n            };\n        }\n\n        window.onload = function() {\n            var container = document.querySelector('.container');\n\n            [{\n                title: 'Display: true',\n                gridLines: {\n                    display: true\n                }\n            }, {\n                title: 'Display: false',\n                gridLines: {\n                    display: false\n                }\n            }, {\n                title: 'Display: false, no border',\n                gridLines: {\n                    display: false,\n                    drawBorder: false\n                }\n            }, {\n                title: 'DrawOnChartArea: false',\n                gridLines: {\n                    display: true,\n                    drawBorder: true,\n                    drawOnChartArea: false,\n                }\n            }, {\n                title: 'DrawTicks: false',\n                gridLines: {\n                    display: true,\n                    drawBorder: true,\n                    drawOnChartArea: true,\n                    drawTicks: false,\n                }\n            }].forEach(function(details) {\n                var div = document.createElement('div');\n                div.classList.add('chart-container');\n\n                var canvas = document.createElement('canvas');\n                div.appendChild(canvas);\n                container.appendChild(div);\n\n                var ctx = canvas.getContext('2d');\n                var config = createConfig(details.gridLines, details.title);\n                new Chart(ctx, config);\n            });\n        };\n    </script>\n</body>\n\n</html>\n"
  },
  {
    "path": "app_backend/static/plugin/Chart.js-2.6.0/samples/scales/gridlines-style.html",
    "content": "<!doctype html>\n<html>\n\n<head>\n    <title>Suggested Min/Max Settings</title>\n    <script src=\"../../dist/Chart.bundle.js\"></script>\n    <script src=\"../utils.js\"></script>\n    <style>\n    canvas{\n        -moz-user-select: none;\n        -webkit-user-select: none;\n        -ms-user-select: none;\n    }\n    </style>\n</head>\n\n<body>\n    <div style=\"width:75%;\">\n        <canvas id=\"canvas\"></canvas>\n    </div>\n    <script>\n        var config = {\n            type: 'line',\n            data: {\n                labels: [\"January\", \"February\", \"March\", \"April\", \"May\", \"June\", \"July\"],\n                datasets: [{\n                    label: \"My First dataset\",\n                    backgroundColor: window.chartColors.red,\n                    borderColor: window.chartColors.red,\n                    data: [10, 30, 39, 20, 25, 34, -10],\n                    fill: false,\n                }, {\n                    label: \"My Second dataset\",\n                    fill: false,\n                    backgroundColor: window.chartColors.blue,\n                    borderColor: window.chartColors.blue,\n                    data: [18, 33, 22, 19, 11, 39, 30],\n                }]\n            },\n            options: {\n                responsive: true,\n                title:{\n                    display: true,\n                    text: 'Grid Line Settings'\n                },\n                scales: {\n                    yAxes: [{\n                        gridLines: {\n                            drawBorder: false,\n                            color: ['pink', 'red', 'orange', 'yellow', 'green', 'blue', 'indigo', 'purple']\n                        },\n                        ticks: {\n                            min: 0,\n                            max: 100,\n                            stepSize: 10\n                        }\n                    }]\n                }\n            }\n        };\n\n        window.onload = function() {\n            var ctx = document.getElementById(\"canvas\").getContext(\"2d\");\n            window.myLine = new Chart(ctx, config);\n        };\n    </script>\n</body>\n\n</html>\n"
  },
  {
    "path": "app_backend/static/plugin/Chart.js-2.6.0/samples/scales/linear/min-max-suggested.html",
    "content": "<!doctype html>\n<html>\n\n<head>\n    <title>Suggested Min/Max Settings</title>\n    <script src=\"../../../dist/Chart.bundle.js\"></script>\n    <script src=\"../../utils.js\"></script>\n    <style>\n    canvas{\n        -moz-user-select: none;\n        -webkit-user-select: none;\n        -ms-user-select: none;\n    }\n    </style>\n</head>\n\n<body>\n    <div style=\"width:75%;\">\n        <canvas id=\"canvas\"></canvas>\n    </div>\n    <script>\n        var config = {\n            type: 'line',\n            data: {\n                labels: [\"January\", \"February\", \"March\", \"April\", \"May\", \"June\", \"July\"],\n                datasets: [{\n                    label: \"My First dataset\",\n                    backgroundColor: window.chartColors.red,\n                    borderColor: window.chartColors.red,\n                    data: [10, 30, 39, 20, 25, 34, -10],\n                    fill: false,\n                }, {\n                    label: \"My Second dataset\",\n                    fill: false,\n                    backgroundColor: window.chartColors.blue,\n                    borderColor: window.chartColors.blue,\n                    data: [18, 33, 22, 19, 11, 39, 30],\n                }]\n            },\n            options: {\n                responsive: true,\n                title:{\n                    display:true,\n                    text:'Min and Max Settings'\n                },\n                scales: {\n                    yAxes: [{\n                        ticks: {\n                            // the data minimum used for determining the ticks is Math.min(dataMin, suggestedMin)\n                            suggestedMin: 10,\n\n                            // the data maximum used for determining the ticks is Math.max(dataMax, suggestedMax)\n                            suggestedMax: 50\n                        }\n                    }]\n                }\n            }\n        };\n\n        window.onload = function() {\n            var ctx = document.getElementById(\"canvas\").getContext(\"2d\");\n            window.myLine = new Chart(ctx, config);\n        };\n    </script>\n</body>\n\n</html>\n"
  },
  {
    "path": "app_backend/static/plugin/Chart.js-2.6.0/samples/scales/linear/min-max.html",
    "content": "<!doctype html>\n<html>\n\n<head>\n    <title>Min/Max Settings</title>\n    <script src=\"../../../dist/Chart.bundle.js\"></script>\n    <script src=\"../../utils.js\"></script>\n    <style>\n    canvas{\n        -moz-user-select: none;\n        -webkit-user-select: none;\n        -ms-user-select: none;\n    }\n    </style>\n</head>\n\n<body>\n    <div style=\"width:75%;\">\n        <canvas id=\"canvas\"></canvas>\n    </div>\n    <script>\n        var config = {\n            type: 'line',\n            data: {\n                labels: [\"January\", \"February\", \"March\", \"April\", \"May\", \"June\", \"July\"],\n                datasets: [{\n                    label: \"My First dataset\",\n                    backgroundColor: window.chartColors.red,\n                    borderColor: window.chartColors.red,\n                    data: [10, 30, 50, 20, 25, 44, -10],\n                    fill: false,\n                }, {\n                    label: \"My Second dataset\",\n                    fill: false,\n                    backgroundColor: window.chartColors.blue,\n                    borderColor: window.chartColors.blue,\n                    data: [100, 33, 22, 19, 11, 49, 30],\n                }]\n            },\n            options: {\n                responsive: true,\n                title:{\n                    display:true,\n                    text:'Min and Max Settings'\n                },\n                scales: {\n                    yAxes: [{\n                        ticks: {\n                            min: 10,\n                            max: 50\n                        }\n                    }]\n                }\n            }\n        };\n\n        window.onload = function() {\n            var ctx = document.getElementById(\"canvas\").getContext(\"2d\");\n            window.myLine = new Chart(ctx, config);\n        };\n    </script>\n</body>\n\n</html>\n"
  },
  {
    "path": "app_backend/static/plugin/Chart.js-2.6.0/samples/scales/linear/step-size.html",
    "content": "<!doctype html>\n<html>\n\n<head>\n    <title>Line Chart</title>\n    <script src=\"../../../dist/Chart.bundle.js\"></script>\n    <script src=\"../../utils.js\"></script>\n    <style>\n    canvas{\n        -moz-user-select: none;\n        -webkit-user-select: none;\n        -ms-user-select: none;\n    }\n    </style>\n</head>\n\n<body>\n    <div style=\"width:75%;\">\n        <canvas id=\"canvas\"></canvas>\n    </div>\n    <br>\n    <br>\n    <button id=\"randomizeData\">Randomize Data</button>\n    <button id=\"addDataset\">Add Dataset</button>\n    <button id=\"removeDataset\">Remove Dataset</button>\n    <button id=\"addData\">Add Data</button>\n    <button id=\"removeData\">Remove Data</button>\n    <script>\n        var MONTHS = [\"January\", \"February\", \"March\", \"April\", \"May\", \"June\", \"July\", \"August\", \"September\", \"October\", \"November\", \"December\"];\n        \n        var randomScalingFactor = function() {\n            return Math.round(Math.random() * 100);\n        };\n\n        var config = {\n            type: 'line',\n            data: {\n                labels: [\"January\", \"February\", \"March\", \"April\", \"May\", \"June\", \"July\"],\n                datasets: [{\n                    label: \"My First dataset\",\n                    backgroundColor: window.chartColors.red,\n                    borderColor: window.chartColors.red,\n                    data: [\n                        randomScalingFactor(), \n                        randomScalingFactor(), \n                        randomScalingFactor(), \n                        randomScalingFactor(), \n                        randomScalingFactor(), \n                        randomScalingFactor(), \n                        randomScalingFactor()\n                    ],\n                    fill: false,\n                }, {\n                    label: \"My Second dataset\",\n                    fill: false,\n                    backgroundColor: window.chartColors.blue,\n                    borderColor: window.chartColors.blue,\n                    data: [\n                        randomScalingFactor(), \n                        randomScalingFactor(), \n                        randomScalingFactor(), \n                        randomScalingFactor(), \n                        randomScalingFactor(), \n                        randomScalingFactor(), \n                        randomScalingFactor()\n                    ],\n                }]\n            },\n            options: {\n                responsive: true,\n                title:{\n                    display:true,\n                    text:'Chart.js Line Chart'\n                },\n                tooltips: {\n                    mode: 'index',\n                    intersect: false,\n                },\n                hover: {\n                    mode: 'nearest',\n                    intersect: true\n                },\n                scales: {\n                    xAxes: [{\n                        display: true,\n                        scaleLabel: {\n                            display: true,\n                            labelString: 'Month'\n                        }\n                    }],\n                    yAxes: [{\n                        display: true,\n                        scaleLabel: {\n                            display: true,\n                            labelString: 'Value'\n                        },\n                        ticks: {\n                            min: 0,\n                            max: 100,\n\n                            // forces step size to be 5 units\n                            stepSize: 5\n                        }\n                    }]\n                }\n            }\n        };\n\n        window.onload = function() {\n            var ctx = document.getElementById(\"canvas\").getContext(\"2d\");\n            window.myLine = new Chart(ctx, config);\n        };\n\n        document.getElementById('randomizeData').addEventListener('click', function() {\n            config.data.datasets.forEach(function(dataset) {\n                dataset.data = dataset.data.map(function() {\n                    return randomScalingFactor();\n                });\n            });\n\n            window.myLine.update();\n        });\n\n        var colorNames = Object.keys(window.chartColors);\n        document.getElementById('addDataset').addEventListener('click', function() {\n            var colorName = colorNames[config.data.datasets.length % colorNames.length];\n            var newColor = window.chartColors[colorName];\n            var newDataset = {\n                label: 'Dataset ' + config.data.datasets.length,\n                backgroundColor: newColor,\n                borderColor: newColor,\n                data: [],\n                fill: false\n            };\n\n            for (var index = 0; index < config.data.labels.length; ++index) {\n                newDataset.data.push(randomScalingFactor());\n            }\n\n            config.data.datasets.push(newDataset);\n            window.myLine.update();\n        });\n\n        document.getElementById('addData').addEventListener('click', function() {\n            if (config.data.datasets.length > 0) {\n                var month = MONTHS[config.data.labels.length % MONTHS.length];\n                config.data.labels.push(month);\n\n                config.data.datasets.forEach(function(dataset) {\n                    dataset.data.push(randomScalingFactor());\n                });\n\n                window.myLine.update();\n            }\n        });\n\n        document.getElementById('removeDataset').addEventListener('click', function() {\n            config.data.datasets.splice(0, 1);\n            window.myLine.update();\n        });\n\n        document.getElementById('removeData').addEventListener('click', function() {\n            config.data.labels.splice(-1, 1); // remove the label first\n\n            config.data.datasets.forEach(function(dataset, datasetIndex) {\n                dataset.data.pop();\n            });\n\n            window.myLine.update();\n        });\n\n    </script>\n</body>\n\n</html>\n"
  },
  {
    "path": "app_backend/static/plugin/Chart.js-2.6.0/samples/scales/logarithmic/line.html",
    "content": "<!doctype html>\n<html>\n\n<head>\n    <title>Logarithmic Line Chart</title>\n    <script src=\"../../../dist/Chart.bundle.js\"></script>\n    <script src=\"../../utils.js\"></script>\n    <style>\n    canvas {\n        -moz-user-select: none;\n        -webkit-user-select: none;\n        -ms-user-select: none;\n    }\n    </style>\n</head>\n\n<body>\n    <div style=\"width:75%;\">\n        <canvas id=\"canvas\"></canvas>\n    </div>\n    <button id=\"randomizeData\">Randomize Data</button>\n    <script>\n    var randomScalingFactor = function() {\n        return Math.ceil(Math.random() * 10.0) * Math.pow(10, Math.ceil(Math.random() * 5));\n    };\n\n    var config = {\n        type: 'line',\n        data: {\n            labels: [\"January\", \"February\", \"March\", \"April\", \"May\", \"June\", \"July\"],\n            datasets: [{\n                label: \"My First dataset\",\n                backgroundColor: window.chartColors.red,\n                borderColor: window.chartColors.red,\n                fill: false,\n                data: [\n                    randomScalingFactor(), \n                    randomScalingFactor(), \n                    randomScalingFactor(), \n                    randomScalingFactor(), \n                    randomScalingFactor(), \n                    randomScalingFactor(), \n                    randomScalingFactor()\n                ],\n            }, {\n                label: \"My Second dataset\",\n                backgroundColor: window.chartColors.blue,\n                borderColor: window.chartColors.blue,\n                fill: false,\n                data: [\n                    randomScalingFactor(), \n                    randomScalingFactor(), \n                    randomScalingFactor(), \n                    randomScalingFactor(), \n                    randomScalingFactor(), \n                    randomScalingFactor(), \n                    randomScalingFactor()\n                ],\n            }]\n        },\n        options: {\n            responsive: true,\n            title:{\n                display:true,\n                text:'Chart.js Line Chart - Logarithmic'\n            },\n            scales: {\n                xAxes: [{\n                    display: true,\n                }],\n                yAxes: [{\n                    display: true,\n                    type: 'logarithmic',\n                }]\n            }\n        }\n    };\n\n    window.onload = function() {\n        var ctx = document.getElementById(\"canvas\").getContext(\"2d\");\n        window.myLine = new Chart(ctx, config);\n    };\n\n    document.getElementById('randomizeData').addEventListener('click', function() {\n        config.data.datasets.forEach(function(dataset) {\n            dataset.data = dataset.data.map(function() {\n                return randomScalingFactor();\n            });\n\n        });\n\n        window.myLine.update();\n    });\n    </script>\n</body>\n\n</html>\n"
  },
  {
    "path": "app_backend/static/plugin/Chart.js-2.6.0/samples/scales/logarithmic/scatter.html",
    "content": "<!doctype html>\n<html>\n\n<head>\n    <title>Scatter Chart</title>\n    <script src=\"../../../dist/Chart.bundle.js\"></script>\n    <script src=\"../../utils.js\"></script>\n    <style>\n    canvas {\n        -moz-user-select: none;\n        -webkit-user-select: none;\n        -ms-user-select: none;\n    }\n    </style>\n</head>\n\n<body>\n    <div style=\"width:75%\">\n        <canvas id=\"canvas\"></canvas>\n    </div>\n    <script>\n    var color = Chart.helpers.color;\n    var scatterChartData = {\n        datasets: [{\n        \tborderColor: window.chartColors.red,\n        \tbackgroundColor: color(window.chartColors.red).alpha(0.5).rgbString(),\n            label: \"V(node2)\",\n\t\t\tdata: [{\n\t\t\t\tx: 1,\n\t\t\t\ty: -1.711e-2,\n\t\t\t}, {\n\t\t\t\tx: 1.26,\n\t\t\t\ty: -2.708e-2,\n\t\t\t}, {\n\t\t\t\tx: 1.58,\n\t\t\t\ty: -4.285e-2,\n\t\t\t}, {\n\t\t\t\tx: 2.0,\n\t\t\t\ty: -6.772e-2,\n\t\t\t}, {\n\t\t\t\tx: 2.51,\n\t\t\t\ty: -1.068e-1,\n\t\t\t}, {\n\t\t\t\tx: 3.16,\n\t\t\t\ty: -1.681e-1,\n\t\t\t}, {\n\t\t\t\tx: 3.98,\n\t\t\t\ty: -2.635e-1,\n\t\t\t}, {\n\t\t\t\tx: 5.01,\n\t\t\t\ty: -4.106e-1,\n\t\t\t}, {\n\t\t\t\tx: 6.31,\n\t\t\t\ty: -6.339e-1,\n\t\t\t}, {\n\t\t\t\tx: 7.94,\n\t\t\t\ty: -9.659e-1,\n\t\t\t}, {\n\t\t\t\tx: 10.00,\n\t\t\t\ty: -1.445,\n\t\t\t}, {\n\t\t\t\tx: 12.6,\n\t\t\t\ty: -2.110,\n\t\t\t}, {\n\t\t\t\tx: 15.8,\n\t\t\t\ty: -2.992,\n\t\t\t}, {\n\t\t\t\tx: 20.0,\n\t\t\t\ty: -4.102,\n\t\t\t}, {\n\t\t\t\tx: 25.1,\n\t\t\t\ty: -5.429,\n\t\t\t}, {\n\t\t\t\tx: 31.6,\n\t\t\t\ty: -6.944,\n\t\t\t}, {\n\t\t\t\tx: 39.8,\n\t\t\t\ty: -8.607,\n\t\t\t}, {\n\t\t\t\tx: 50.1,\n\t\t\t\ty: -1.038e1,\n\t\t\t}, {\n\t\t\t\tx: 63.1,\n\t\t\t\ty: -1.223e1,\n\t\t\t}, {\n\t\t\t\tx: 79.4,\n\t\t\t\ty: -1.413e1,\n\t\t\t}, {\n\t\t\t\tx: 100.00,\n\t\t\t\ty: -1.607e1,\n\t\t\t}, {\n\t\t\t\tx: 126,\n\t\t\t\ty: -1.803e1,\n\t\t\t}, {\n\t\t\t\tx: 158,\n\t\t\t\ty: -2e1,\n\t\t\t}, {\n\t\t\t\tx: 200,\n\t\t\t\ty: -2.199e1,\n\t\t\t}, {\n\t\t\t\tx: 251,\n\t\t\t\ty: -2.398e1,\n\t\t\t}, {\n\t\t\t\tx: 316,\n\t\t\t\ty: -2.597e1,\n\t\t\t}, {\n\t\t\t\tx: 398,\n\t\t\t\ty: -2.797e1,\n\t\t\t}, {\n\t\t\t\tx: 501,\n\t\t\t\ty: -2.996e1,\n\t\t\t}, {\n\t\t\t\tx: 631,\n\t\t\t\ty: -3.196e1,\n\t\t\t}, {\n\t\t\t\tx: 794,\n\t\t\t\ty: -3.396e1,\n\t\t\t}, {\n\t\t\t\tx: 1000,\n\t\t\t\ty: -3.596e1,\n\t\t\t},]\n        }]\n    };\n\n    window.onload = function() {\n        var ctx = document.getElementById(\"canvas\").getContext(\"2d\");\n        window.myScatter = Chart.Scatter(ctx, {\n        \tdata: scatterChartData,\n        \toptions: {\n        \t\ttitle: {\n\t                display: true,\n\t                text: 'Chart.js Scatter Chart - Logarithmic X-Axis'\n\t            },\n\t            scales: {\n\t            \txAxes: [{\n\t            \t\ttype: 'logarithmic',\n\t            \t\tposition: 'bottom',\n\t            \t\tticks: {\n\t            \t\t\tuserCallback: function(tick) {\n\t            \t\t\t\tvar remain = tick / (Math.pow(10, Math.floor(Chart.helpers.log10(tick))));\n\t            \t\t\t\tif (remain === 1 || remain === 2 || remain === 5) {\n\t            \t\t\t\t\treturn tick.toString() + \"Hz\";\n\t            \t\t\t\t}\n\t            \t\t\t\treturn '';\n\t            \t\t\t},\n\t            \t\t},\n\t            \t\tscaleLabel: {\n\t            \t\t\tlabelString: 'Frequency',\n\t            \t\t\tdisplay: true,\n\t            \t\t}\n\t            \t}],\n\t            \tyAxes: [{\n\t            \t\ttype: 'linear',\n\t            \t\tticks: {\n\t            \t\t\tuserCallback: function(tick) {\n\t            \t\t\t\treturn tick.toString() + \"dB\";\n\t            \t\t\t}\n\t            \t\t},\n\t            \t\tscaleLabel: {\n\t            \t\t\tlabelString: 'Voltage',\n\t            \t\t\tdisplay: true\n\t            \t\t}\n\t            \t}]\n\t            }\n            }\n        });\n    };\n    </script>\n</body>\n\n</html>\n"
  },
  {
    "path": "app_backend/static/plugin/Chart.js-2.6.0/samples/scales/multiline-labels.html",
    "content": "<!doctype html>\n<html>\n\n<head>\n    <title>Line Chart</title>\n    <script src=\"../../dist/Chart.bundle.js\"></script>\n    <script src=\"../utils.js\"></script>\n    <style>\n    canvas{\n        -moz-user-select: none;\n        -webkit-user-select: none;\n        -ms-user-select: none;\n    }\n    </style>\n</head>\n\n<body>\n    <div style=\"width:90%;\">\n        <canvas id=\"canvas\"></canvas>\n    </div>\n    <script>\n        var randomScalingFactor = function() {\n            return Math.round(Math.random() * 100);\n        };\n\n        var config = {\n            type: 'line',\n            data: {\n                labels: [[\"June\",\"2015\"], \"July\", \"August\", \"September\", \"October\", \"November\", \"December\", [\"January\",\"2016\"],\"February\", \"March\", \"April\", \"May\"],\n                datasets: [{\n                    label: \"My First dataset\",\n                    fill: false,\n                    backgroundColor: window.chartColors.red,\n                    borderColor: window.chartColors.red,\n                    data: [\n                        randomScalingFactor(), \n                        randomScalingFactor(), \n                        randomScalingFactor(), \n                        randomScalingFactor(), \n                        randomScalingFactor(), \n                        randomScalingFactor(), \n                        randomScalingFactor(), \n                        randomScalingFactor(), \n                        randomScalingFactor(), \n                        randomScalingFactor(), \n                        randomScalingFactor(), \n                        randomScalingFactor()\n                    ]\n                }, {\n                    label: \"My Second dataset\",\n                    fill: false,\n                    backgroundColor: window.chartColors.blue,\n                    borderColor: window.chartColors.blue,\n                    data: [\n                        randomScalingFactor(), \n                        randomScalingFactor(), \n                        randomScalingFactor(), \n                        randomScalingFactor(), \n                        randomScalingFactor(), \n                        randomScalingFactor(), \n                        randomScalingFactor(), \n                        randomScalingFactor(), \n                        randomScalingFactor(), \n                        randomScalingFactor(), \n                        randomScalingFactor(), \n                        randomScalingFactor()\n                    ],\n                }]\n            },\n            options: {\n                responsive: true,\n                title:{\n                    display:true,\n                    text:'Chart with Multiline Labels'\n                },\n            }\n        };\n\n        window.onload = function() {\n            var ctx = document.getElementById(\"canvas\").getContext(\"2d\");\n            window.myLine = new Chart(ctx, config);\n        };\n    </script>\n</body>\n\n</html>\n"
  },
  {
    "path": "app_backend/static/plugin/Chart.js-2.6.0/samples/scales/non-numeric-y.html",
    "content": "<!doctype html>\n<html>\n\n<head>\n    <title>Line Chart</title>\n    <script src=\"../../dist/Chart.bundle.js\"></script>\n    <script src=\"../utils.js\"></script>\n    <style>\n    canvas{\n        -moz-user-select: none;\n        -webkit-user-select: none;\n        -ms-user-select: none;\n    }\n    </style>\n</head>\n\n<body>\n    <div style=\"width:75%;\">\n        <canvas id=\"canvas\"></canvas>\n    </div>\n    <script>\n        var MONTHS = [\"January\", \"February\", \"March\", \"April\", \"May\", \"June\", \"July\", \"August\", \"September\", \"October\", \"November\", \"December\"];\n        var config = {\n            type: 'line',\n            data: {\n                xLabels: [\"January\", \"February\", \"March\", \"April\", \"May\", \"June\", \"July\"],\n                yLabels: ['', 'Request Added', 'Request Viewed', 'Request Accepted', 'Request Solved', 'Solving Confirmed'],\n                datasets: [{\n                    label: \"My First dataset\",\n                    data: ['', 'Request Added', 'Request Added', 'Request Added', 'Request Viewed', 'Request Viewed', 'Request Viewed'],\n                    fill: false,\n                    borderColor: window.chartColors.red,\n                    backgroundColor: window.chartColors.red\n                }]\n            },\n            options: {\n                responsive: true,\n                title:{\n                    display:true,\n                    text:'Chart with Non Numeric Y Axis'\n                },\n                scales: {\n                    xAxes: [{\n                        display: true,\n                        scaleLabel: {\n                            display: true,\n                            labelString: 'Month'\n                        }\n                    }],\n                    yAxes: [{\n                        type: 'category',\n                        position: 'left',\n                        display: true,\n                        scaleLabel: {\n                            display: true,\n                            labelString: 'Request State'\n                        },\n                        ticks: {\n                            reverse: true\n                        }\n                    }]\n                }\n            }\n        };\n\n        window.onload = function() {\n            var ctx = document.getElementById(\"canvas\").getContext(\"2d\");\n            window.myLine = new Chart(ctx, config);\n        };\n    </script>\n</body>\n\n</html>\n"
  },
  {
    "path": "app_backend/static/plugin/Chart.js-2.6.0/samples/scales/time/combo.html",
    "content": "<!doctype html>\n<html>\n\n<head>\n\t<title>Line Chart - Combo Time Scale</title>\n\t<script src=\"https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.13.0/moment.min.js\"></script>\n\t<script src=\"../../../dist/Chart.js\"></script>\n\t<script src=\"../../utils.js\"></script>\n\t<style>\n    canvas {\n        -moz-user-select: none;\n        -webkit-user-select: none;\n        -ms-user-select: none;\n    }\n\t</style>\n</head>\n\n<body>\n\t<div style=\"width:75%;\">\n\t\t<canvas id=\"canvas\"></canvas>\n\t</div>\n\t<br>\n\t<br>\n\t<button id=\"randomizeData\">Randomize Data</button>\n\t<button id=\"addDataset\">Add Dataset</button>\n\t<button id=\"removeDataset\">Remove Dataset</button>\n\t<button id=\"addData\">Add Data</button>\n\t<button id=\"removeData\">Remove Data</button>\n\t<script>\n\t\tvar timeFormat = 'MM/DD/YYYY HH:mm';\n\n\t\tfunction newDateString(days) {\n\t\t\treturn moment().add(days, 'd').format(timeFormat);\n\t\t}\n\n\t\tvar color = Chart.helpers.color;\n\t\tvar config = {\n\t\t\ttype: 'bar',\n\t\t\tdata: {\n\t\t\t\tlabels: [\n\t\t\t\t\tnewDateString(0), \n\t\t\t\t\tnewDateString(1), \n\t\t\t\t\tnewDateString(2), \n\t\t\t\t\tnewDateString(3), \n\t\t\t\t\tnewDateString(4), \n\t\t\t\t\tnewDateString(5), \n\t\t\t\t\tnewDateString(6)\n\t\t\t\t],\n\t\t\t\tdatasets: [{\n\t\t\t\t\ttype: 'bar',\n\t\t\t\t\tlabel: 'Dataset 1',\n\t\t\t\t\tbackgroundColor: color(window.chartColors.red).alpha(0.5).rgbString(),\n\t\t\t\t\tborderColor: window.chartColors.red,\n\t\t\t\t\tdata: [\n\t\t\t\t\t\trandomScalingFactor(), \n\t\t\t\t\t\trandomScalingFactor(), \n\t\t\t\t\t\trandomScalingFactor(), \n\t\t\t\t\t\trandomScalingFactor(), \n\t\t\t\t\t\trandomScalingFactor(), \n\t\t\t\t\t\trandomScalingFactor(), \n\t\t\t\t\t\trandomScalingFactor()\n\t\t\t\t\t],\n\t\t\t\t}, {\n\t\t\t\t\ttype: 'bar',\n\t\t\t\t\tlabel: 'Dataset 2',\n\t\t\t\t\tbackgroundColor: color(window.chartColors.blue).alpha(0.5).rgbString(),\n\t\t\t\t\tborderColor: window.chartColors.blue,\n\t\t\t\t\tdata: [\n\t\t\t\t\t\trandomScalingFactor(), \n\t\t\t\t\t\trandomScalingFactor(), \n\t\t\t\t\t\trandomScalingFactor(), \n\t\t\t\t\t\trandomScalingFactor(), \n\t\t\t\t\t\trandomScalingFactor(), \n\t\t\t\t\t\trandomScalingFactor(), \n\t\t\t\t\t\trandomScalingFactor()\n\t\t\t\t\t],\n\t\t\t\t}, {\n\t\t\t\t\ttype: 'line',\n\t\t\t\t\tlabel: 'Dataset 3',\n\t\t\t\t\tbackgroundColor: color(window.chartColors.green).alpha(0.5).rgbString(),\n\t\t\t\t\tborderColor: window.chartColors.green,\n\t\t\t\t\tfill: false,\n\t\t\t\t\tdata: [\n\t\t\t\t\t\trandomScalingFactor(), \n\t\t\t\t\t\trandomScalingFactor(), \n\t\t\t\t\t\trandomScalingFactor(), \n\t\t\t\t\t\trandomScalingFactor(), \n\t\t\t\t\t\trandomScalingFactor(), \n\t\t\t\t\t\trandomScalingFactor(), \n\t\t\t\t\t\trandomScalingFactor()\n\t\t\t\t\t],\n\t\t\t\t}, ]\n\t\t\t},\n\t\t\toptions: {\n                title: {\n                    text:\"Chart.js Combo Time Scale\"\n                },\n\t\t\t\tscales: {\n\t\t\t\t\txAxes: [{\n\t\t\t\t\t\ttype: \"time\",\n\t\t\t\t\t\tdisplay: true,\n\t\t\t\t\t\ttime: {\n\t\t\t\t\t\t\tformat: timeFormat,\n\t\t\t\t\t\t\t// round: 'day'\n\t\t\t\t\t\t}\n\t\t\t\t\t}],\n\t\t\t\t},\n\t\t\t}\n\t\t};\n\n\t\twindow.onload = function() {\n\t\t\tvar ctx = document.getElementById(\"canvas\").getContext(\"2d\");\n\t\t\twindow.myLine = new Chart(ctx, config);\n\n\t\t};\n\n\t\tdocument.getElementById('randomizeData').addEventListener('click', function() {\n\t\t\tconfig.data.datasets.forEach(function(dataset) {\n\t\t\t\tdataset.data = dataset.data.map(function() {\n\t\t\t\t\treturn randomScalingFactor();\n\t\t\t\t});\n\t\t\t});\n\n\t\t\twindow.myLine.update();\n\t\t});\n\n\t\tvar colorNames = Object.keys(window.chartColors);\n\t\tdocument.getElementById('addDataset').addEventListener('click', function() {\n\t\t\tvar colorName = colorNames[config.data.datasets.length % colorNames.length];\n\t\t\tvar newColor = window.chartColors[colorName];\n\t\t\tvar newDataset = {\n\t\t\t\tlabel: 'Dataset ' + config.data.datasets.length,\n\t\t\t\tborderColor: newColor,\n\t\t\t\tbackgroundColor: color(newColor).alpha(0.5).rgbString(),\n\t\t\t\tdata: [],\n\t\t\t};\n\n\t\t\tfor (var index = 0; index < config.data.labels.length; ++index) {\n\t\t\t\tnewDataset.data.push(randomScalingFactor());\n\t\t\t}\n\n\t\t\tconfig.data.datasets.push(newDataset);\n\t\t\twindow.myLine.update();\n\t\t});\n\n\t\tdocument.getElementById('addData').addEventListener('click', function() {\n\t\t\tif (config.data.datasets.length > 0) {\n\t\t\t\tconfig.data.labels.push(newDateString(config.data.labels.length));\n\n\t\t\t\tfor (var index = 0; index < config.data.datasets.length; ++index) {\n\t\t\t\t\tconfig.data.datasets[index].data.push(randomScalingFactor());\n\t\t\t\t}\n\n\t\t\t\twindow.myLine.update();\n\t\t\t}\n\t\t});\n\n\t\tdocument.getElementById('removeDataset').addEventListener('click', function() {\n\t\t\tconfig.data.datasets.splice(0, 1);\n\t\t\twindow.myLine.update();\n\t\t});\n\n\t\tdocument.getElementById('removeData').addEventListener('click', function() {\n\t\t\tconfig.data.labels.splice(-1, 1); // remove the label first\n\n\t\t\tconfig.data.datasets.forEach(function(dataset, datasetIndex) {\n\t\t\t\tconfig.data.datasets[datasetIndex].data.pop();\n\t\t\t});\n\n\t\t\twindow.myLine.update();\n\t\t});\n\t</script>\n</body>\n\n</html>\n"
  },
  {
    "path": "app_backend/static/plugin/Chart.js-2.6.0/samples/scales/time/line-point-data.html",
    "content": "<!doctype html>\n<html>\n\n<head>\n\t<title>Time Scale Point Data</title>\n\t<script src=\"https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.13.0/moment.min.js\"></script>\n\t<script src=\"../../../dist/Chart.js\"></script>\n\t<script src=\"../../utils.js\"></script>\n\t<style>\n    canvas {\n        -moz-user-select: none;\n        -webkit-user-select: none;\n        -ms-user-select: none;\n    }\n\t</style>\n</head>\n\n<body>\n\t<div style=\"width:75%;\">\n\t\t<canvas id=\"canvas\"></canvas>\n\t</div>\n\t<br>\n\t<br>\n\t<button id=\"randomizeData\">Randomize Data</button>\n\t<button id=\"addData\">Add Data</button>\n\t<button id=\"removeData\">Remove Data</button>\n\t<script>\n\t\tfunction newDate(days) {\n\t\t\treturn moment().add(days, 'd').toDate();\n\t\t}\n\n\t\tfunction newDateString(days) {\n\t\t\treturn moment().add(days, 'd').format();\n\t\t}\n\n\t\tvar color = Chart.helpers.color;\n\t\tvar config = {\n\t\t\ttype: 'line',\n\t\t\tdata: {\n\t\t\t\tdatasets: [{\n\t\t\t\t\tlabel: \"Dataset with string point data\",\n\t\t\t\t\tbackgroundColor: color(window.chartColors.red).alpha(0.5).rgbString(),\n\t\t\t\t\tborderColor: window.chartColors.red,\n\t\t\t\t\tfill: false,\n\t\t\t\t\tdata: [{\n\t\t\t\t\t\tx: newDateString(0),\n\t\t\t\t\t\ty: randomScalingFactor()\n\t\t\t\t\t}, {\n\t\t\t\t\t\tx: newDateString(2),\n\t\t\t\t\t\ty: randomScalingFactor()\n\t\t\t\t\t}, {\n\t\t\t\t\t\tx: newDateString(4),\n\t\t\t\t\t\ty: randomScalingFactor()\n\t\t\t\t\t}, {\n\t\t\t\t\t\tx: newDateString(5),\n\t\t\t\t\t\ty: randomScalingFactor()\n\t\t\t\t\t}],\n\t\t\t\t}, {\n\t\t\t\t\tlabel: \"Dataset with date object point data\",\n\t\t\t\t\tbackgroundColor: color(window.chartColors.blue).alpha(0.5).rgbString(),\n\t\t\t\t\tborderColor: window.chartColors.blue,\n\t\t\t\t\tfill: false,\n\t\t\t\t\tdata: [{\n\t\t\t\t\t\tx: newDate(0),\n\t\t\t\t\t\ty: randomScalingFactor()\n\t\t\t\t\t}, {\n\t\t\t\t\t\tx: newDate(2),\n\t\t\t\t\t\ty: randomScalingFactor()\n\t\t\t\t\t}, {\n\t\t\t\t\t\tx: newDate(4),\n\t\t\t\t\t\ty: randomScalingFactor()\n\t\t\t\t\t}, {\n\t\t\t\t\t\tx: newDate(5),\n\t\t\t\t\t\ty: randomScalingFactor()\n\t\t\t\t\t}]\n\t\t\t\t}]\n\t\t\t},\n\t\t\toptions: {\n\t\t\t\tresponsive: true,\n                title:{\n                    display:true,\n                    text:\"Chart.js Time Point Data\"\n                },\n\t\t\t\tscales: {\n\t\t\t\t\txAxes: [{\n\t\t\t\t\t\ttype: \"time\",\n\t\t\t\t\t\tdisplay: true,\n\t\t\t\t\t\tscaleLabel: {\n\t\t\t\t\t\t\tdisplay: true,\n\t\t\t\t\t\t\tlabelString: 'Date'\n\t\t\t\t\t\t}\n\t\t\t\t\t}],\n\t\t\t\t\tyAxes: [{\n\t\t\t\t\t\tdisplay: true,\n\t\t\t\t\t\tscaleLabel: {\n\t\t\t\t\t\t\tdisplay: true,\n\t\t\t\t\t\t\tlabelString: 'value'\n\t\t\t\t\t\t}\n\t\t\t\t\t}]\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\n\t\twindow.onload = function() {\n\t\t\tvar ctx = document.getElementById(\"canvas\").getContext(\"2d\");\n\t\t\twindow.myLine = new Chart(ctx, config);\n\n\t\t};\n\n\t\tdocument.getElementById('randomizeData').addEventListener('click', function() {\n\t\t\tconfig.data.datasets.forEach(function(dataset) {\n\t\t\t\tdataset.data.forEach(function(dataObj) {\n\t\t\t\t\tdataObj.y = randomScalingFactor();\n\t\t\t\t});\n\t\t\t});\n\n\t\t\twindow.myLine.update();\n\t\t});\n\n\t\tdocument.getElementById('addData').addEventListener('click', function() {\n\t\t\tif (config.data.datasets.length > 0) {\n\t\t\t\tvar numTicks = myLine.scales['x-axis-0'].ticksAsTimestamps.length;\n\t\t\t\tvar lastTime = numTicks ? moment(myLine.scales['x-axis-0'].ticksAsTimestamps[numTicks - 1]) : moment();\n\t\t\t\tvar newTime = lastTime\n\t\t\t\t\t.clone()\n\t\t\t\t\t.add(1, 'day')\n\t\t\t\t\t.format('MM/DD/YYYY HH:mm');\n\n\t\t\t\tfor (var index = 0; index < config.data.datasets.length; ++index) {\n\t\t\t\t\tconfig.data.datasets[index].data.push({\n\t\t\t\t\t\tx: newTime,\n\t\t\t\t\t\ty: randomScalingFactor()\n\t\t\t\t\t});\n\t\t\t\t}\n\n\t\t\t\twindow.myLine.update();\n\t\t\t}\n\t\t});\n\n\t\tdocument.getElementById('removeData').addEventListener('click', function() {\n\t\t\tconfig.data.datasets.forEach(function(dataset, datasetIndex) {\n\t\t\t\tdataset.data.pop();\n\t\t\t});\n\n\t\t\twindow.myLine.update();\n\t\t});\n\t</script>\n</body>\n\n</html>\n"
  },
  {
    "path": "app_backend/static/plugin/Chart.js-2.6.0/samples/scales/time/line.html",
    "content": "<!doctype html>\n<html>\n\n<head>\n\t<title>Line Chart</title>\n\t<script src=\"https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.13.0/moment.min.js\"></script>\n\t<script src=\"../../../dist/Chart.js\"></script>\n\t<script src=\"../../utils.js\"></script>\n\t<style>\n    canvas {\n        -moz-user-select: none;\n        -webkit-user-select: none;\n        -ms-user-select: none;\n    }\n\t</style>\n</head>\n\n<body>\n\t<div style=\"width:75%;\">\n\t\t<canvas id=\"canvas\"></canvas>\n\t</div>\n\t<br>\n\t<br>\n\t<button id=\"randomizeData\">Randomize Data</button>\n\t<button id=\"addDataset\">Add Dataset</button>\n\t<button id=\"removeDataset\">Remove Dataset</button>\n\t<button id=\"addData\">Add Data</button>\n\t<button id=\"removeData\">Remove Data</button>\n\t<script>\n\t\tvar timeFormat = 'MM/DD/YYYY HH:mm';\n\t\t\n\t\tfunction newDate(days) {\n\t\t\treturn moment().add(days, 'd').toDate();\n\t\t}\n\n\t\tfunction newDateString(days) {\n\t\t\treturn moment().add(days, 'd').format(timeFormat);\n\t\t}\n\n\t\tfunction newTimestamp(days) {\n\t\t\treturn moment().add(days, 'd').unix();\n\t\t}\n\n\t\tvar color = Chart.helpers.color;\n\t\tvar config = {\n\t\t\ttype: 'line',\n\t\t\tdata: {\n\t\t\t\tlabels: [ // Date Objects\n\t\t\t\t\tnewDate(0), \n\t\t\t\t\tnewDate(1), \n\t\t\t\t\tnewDate(2), \n\t\t\t\t\tnewDate(3), \n\t\t\t\t\tnewDate(4), \n\t\t\t\t\tnewDate(5), \n\t\t\t\t\tnewDate(6)\n\t\t\t\t],\n\t\t\t\tdatasets: [{\n\t\t\t\t\tlabel: \"My First dataset\",\n\t\t\t\t\tbackgroundColor: color(window.chartColors.red).alpha(0.5).rgbString(),\n\t\t\t\t\tborderColor: window.chartColors.red,\n\t\t\t\t\tfill: false,\n\t\t\t\t\tdata: [\n\t\t\t\t\t\trandomScalingFactor(), \n\t\t\t\t\t\trandomScalingFactor(), \n\t\t\t\t\t\trandomScalingFactor(), \n\t\t\t\t\t\trandomScalingFactor(), \n\t\t\t\t\t\trandomScalingFactor(), \n\t\t\t\t\t\trandomScalingFactor(), \n\t\t\t\t\t\trandomScalingFactor()\n\t\t\t\t\t],\n\t\t\t\t}, {\n\t\t\t\t\tlabel: \"My Second dataset\",\n\t\t\t\t\tbackgroundColor: color(window.chartColors.blue).alpha(0.5).rgbString(),\n\t\t\t\t\tborderColor: window.chartColors.blue,\n\t\t\t\t\tfill: false,\n\t\t\t\t\tdata: [\n\t\t\t\t\t\trandomScalingFactor(), \n\t\t\t\t\t\trandomScalingFactor(), \n\t\t\t\t\t\trandomScalingFactor(), \n\t\t\t\t\t\trandomScalingFactor(), \n\t\t\t\t\t\trandomScalingFactor(), \n\t\t\t\t\t\trandomScalingFactor(), \n\t\t\t\t\t\trandomScalingFactor()\n\t\t\t\t\t],\n\t\t\t\t}, {\n\t\t\t\t\tlabel: \"Dataset with point data\",\n\t\t\t\t\tbackgroundColor: color(window.chartColors.green).alpha(0.5).rgbString(),\n\t\t\t\t\tborderColor: window.chartColors.green,\n\t\t\t\t\tfill: false,\n\t\t\t\t\tdata: [{\n\t\t\t\t\t\tx: newDateString(0),\n\t\t\t\t\t\ty: randomScalingFactor()\n\t\t\t\t\t}, {\n\t\t\t\t\t\tx: newDateString(5),\n\t\t\t\t\t\ty: randomScalingFactor()\n\t\t\t\t\t}, {\n\t\t\t\t\t\tx: newDateString(7),\n\t\t\t\t\t\ty: randomScalingFactor()\n\t\t\t\t\t}, {\n\t\t\t\t\t\tx: newDateString(15),\n\t\t\t\t\t\ty: randomScalingFactor()\n\t\t\t\t\t}],\n\t\t\t\t}]\n\t\t\t},\n\t\t\toptions: {\n                title:{\n                    text: \"Chart.js Time Scale\"\n                },\n\t\t\t\tscales: {\n\t\t\t\t\txAxes: [{\n\t\t\t\t\t\ttype: \"time\",\n\t\t\t\t\t\ttime: {\n\t\t\t\t\t\t\tformat: timeFormat,\n\t\t\t\t\t\t\t// round: 'day'\n\t\t\t\t\t\t\ttooltipFormat: 'll HH:mm'\n\t\t\t\t\t\t},\n\t\t\t\t\t\tscaleLabel: {\n\t\t\t\t\t\t\tdisplay: true,\n\t\t\t\t\t\t\tlabelString: 'Date'\n\t\t\t\t\t\t}\n\t\t\t\t\t}, ],\n\t\t\t\t\tyAxes: [{\n\t\t\t\t\t\tscaleLabel: {\n\t\t\t\t\t\t\tdisplay: true,\n\t\t\t\t\t\t\tlabelString: 'value'\n\t\t\t\t\t\t}\n\t\t\t\t\t}]\n\t\t\t\t},\n\t\t\t}\n\t\t};\n\n\t\twindow.onload = function() {\n\t\t\tvar ctx = document.getElementById(\"canvas\").getContext(\"2d\");\n\t\t\twindow.myLine = new Chart(ctx, config);\n\n\t\t};\n\n\t\tdocument.getElementById('randomizeData').addEventListener('click', function() {\n\t\t\tconfig.data.datasets.forEach(function(dataset) {\n\t\t\t\tdataset.data.forEach(function(dataObj, j) {\n\t\t\t\t\tif (typeof dataObj === 'object') {\n\t\t\t\t\t\tdataObj.y = randomScalingFactor();\n\t\t\t\t\t} else {\n\t\t\t\t\t\tdataset.data[j] = randomScalingFactor();\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t});\n\n\t\t\twindow.myLine.update();\n\t\t});\n\n\t\tvar colorNames = Object.keys(window.chartColors);\n\t\tdocument.getElementById('addDataset').addEventListener('click', function() {\n\t\t\tvar colorName = colorNames[config.data.datasets.length % colorNames.length];\n\t\t\tvar newColor = window.chartColors[colorName]\n\t\t\tvar newDataset = {\n\t\t\t\tlabel: 'Dataset ' + config.data.datasets.length,\n\t\t\t\tborderColor: newColor,\n\t\t\t\tbackgroundColor: color(newColor).alpha(0.5).rgbString(),\n\t\t\t\tdata: [],\n\t\t\t};\n\n\t\t\tfor (var index = 0; index < config.data.labels.length; ++index) {\n\t\t\t\tnewDataset.data.push(randomScalingFactor());\n\t\t\t}\n\n\t\t\tconfig.data.datasets.push(newDataset);\n\t\t\twindow.myLine.update();\n\t\t});\n\n\t\tdocument.getElementById('addData').addEventListener('click', function() {\n\t\t\tif (config.data.datasets.length > 0) {\n\t\t\t\tconfig.data.labels.push(newDate(config.data.labels.length));\n\n\t\t\t\tfor (var index = 0; index < config.data.datasets.length; ++index) {\n\t\t\t\t\tif (typeof config.data.datasets[index].data[0] === \"object\") {\n\t\t\t\t\t\tconfig.data.datasets[index].data.push({\n\t\t\t\t\t\t\tx: newDate(config.data.datasets[index].data.length),\n\t\t\t\t\t\t\ty: randomScalingFactor(),\n\t\t\t\t\t\t});\n\t\t\t\t\t} else {\n\t\t\t\t\t\tconfig.data.datasets[index].data.push(randomScalingFactor());\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\twindow.myLine.update();\n\t\t\t}\n\t\t});\n\n\t\tdocument.getElementById('removeDataset').addEventListener('click', function() {\n\t\t\tconfig.data.datasets.splice(0, 1);\n\t\t\twindow.myLine.update();\n\t\t});\n\n\t\tdocument.getElementById('removeData').addEventListener('click', function() {\n\t\t\tconfig.data.labels.splice(-1, 1); // remove the label first\n\n\t\t\tconfig.data.datasets.forEach(function(dataset, datasetIndex) {\n\t\t\t\tdataset.data.pop();\n\t\t\t});\n\n\t\t\twindow.myLine.update();\n\t\t});\n\t</script>\n</body>\n\n</html>\n"
  },
  {
    "path": "app_backend/static/plugin/Chart.js-2.6.0/samples/style.css",
    "content": "@import url('https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css');\n@import url('https://fonts.googleapis.com/css?family=Lato:100,300,400,700,900');\n\nbody, html {\n\tcolor: #333538;\n\tfont-family: 'Lato', sans-serif;\n\tline-height: 1.6;\n\tpadding: 0;\n\tmargin: 0;\n}\n\na {\n\tcolor: #f27173;\n\ttext-decoration: none;\n}\n\na:hover {\n\tcolor: #e25f5f;\n\ttext-decoration: underline;\n}\n\n.content {\n\tmax-width: 800px;\n\tmargin: auto;\n\tpadding: 16px 32px;\n}\n\n.header {\n\ttext-align: center;\n\tpadding: 32px 0;\n}\n\n.wrapper {\n\tmin-height: 400px;\n\tpadding: 16px 0;\n\tposition: relative;\n}\n\n.wrapper.col-2 {\n\tdisplay: inline-block;\n\tmin-height: 256px;\n\twidth: 49%;\n}\n\n@media (max-width: 400px) {\n\t.wrapper.col-2 {\n\t\twidth: 100%\n\t}\n}\n\n.wrapper canvas {\n\t-moz-user-select: none;\n\t-webkit-user-select: none;\n\t-ms-user-select: none;\n}\n\n.toolbar {\n\tdisplay: flex;\n}\n\n.toolbar > * {\n\tmargin: 0 8px 0 0;\n}\n\n.btn {\n\tbackground-color: #aaa;\n\tborder-radius: 4px;\n\tcolor: white;\n\tpadding: 0.25rem 0.75rem;\n}\n\n.btn .fa {\n\tfont-size: 1rem;\n}\n\n.btn:hover {\n\tbackground-color: #888;\n\tcolor: white;\n\ttext-decoration: none;\n}\n\n.btn-chartjs { background-color: #f27173; }\n.btn-chartjs:hover { background-color: #e25f5f; }\n.btn-docs:hover { background-color: #2793db; }\n.btn-docs { background-color: #36A2EB; }\n.btn-docs:hover { background-color: #2793db; }\n.btn-gh { background-color: #444; }\n.btn-gh:hover { background-color: #333; }\n\n.btn-on {\n\tborder-style: inset;\n}\n\n.chartjs-title {\n\tfont-size: 2rem;\n\tfont-weight: 600;\n\twhite-space: nowrap;\n}\n\n.chartjs-title::before {\n\tbackground-image: url(logo.svg);\n\tbackground-position: left center;\n\tbackground-repeat: no-repeat;\n\tbackground-size: 40px;\n\tcontent: 'Chart.js | ';\n\tcolor: #f27173;\n\tfont-weight: 600;\n\tpadding-left: 48px;\n}\n\n.chartjs-caption {\n\tfont-size: 1.2rem;\n}\n\n.chartjs-links {\n\tdisplay: flex;\n\tjustify-content: center;\n\tpadding: 8px 0;\n}\n\n.chartjs-links a {\n\talign-items: center;\n\tdisplay: flex;\n\tfont-size: 0.9rem;\n\tmargin: 0.2rem;\n}\n\n.chartjs-links .fa:before {\n\tmargin-right: 0.5em;\n}\n\n.samples-category {\n\tdisplay: inline-block;\n\tmargin-bottom: 32px;\n\tvertical-align: top;\n\twidth: 25%;\n}\n\n.samples-category > .title {\n\tcolor: #aaa;\n\tfont-weight: 300;\n\tfont-size: 1.5rem;\n}\n\n.samples-category:hover > .title {\n\tcolor: black;\n}\n\n.samples-category > .items {\n\tpadding: 8px 0;\n}\n\n.samples-entry {\n\tpadding: 0 0 4px 0;\n}\n\n.samples-entry > .title {\n\tfont-weight: 700;\n}\n\n@media (max-width: 640px) {\n\t.samples-category { width: 33%; }\n}\n\n@media (max-width: 512px) {\n\t.samples-category { width: 50%; }\n}\n\n@media (max-width: 420px) {\n\t.chartjs-caption { font-size: 1.05rem; }\n\t.chartjs-title::before { content: ''; }\n\t.chartjs-links a { flex-direction: column; }\n\t.chartjs-links .fa { margin: 0 }\n\t.samples-category { width: 100%; }\n}\n\n.analyser table {\n\tcolor: #333;\n\tfont-size: 0.9rem;\n\tmargin: 8px 0;\n\twidth: 100%\n}\n\n.analyser th {\n\tbackground-color: #f0f0f0;\n\tpadding: 2px;\n}\n\n.analyser td {\n\tpadding: 2px;\n\ttext-align: center;\n}\n"
  },
  {
    "path": "app_backend/static/plugin/Chart.js-2.6.0/samples/tooltips/border.html",
    "content": "<!doctype html>\n<html>\n\n<head>\n\t<title>Tooltip Border</title>\n\t<script src=\"../../dist/Chart.bundle.js\"></script>\n\t<script src=\"../utils.js\"></script>\n\t<style>\n\tcanvas {\n\t\t-moz-user-select: none;\n\t\t-webkit-user-select: none;\n\t\t-ms-user-select: none;\n\t}\n\t.chart-container {\n\t\twidth: 70%;\n\t\tmargin-left: 40px;\n\t\tmargin-right: 40px;\n\t\tmargin-bottom: 40px;\n\t}\n\t.container {\n\t\tdisplay: flex;\n\t\tflex-direction: row;\n\t\tflex-wrap: wrap;\n\t\tjustify-content: center;\n\t}\n\t</style>\n</head>\n\n<body>\n\t<div class=\"container\">\n\t</div>\n\t<script>\n\t\tfunction createConfig() {\n\t\t\treturn {\n\t\t\t\ttype: 'line',\n\t\t\t\tdata: {\n\t\t\t\t\tlabels: [\"January\", \"February\", \"March\", \"April\", \"May\", \"June\", \"July\"],\n\t\t\t\t\tdatasets: [{\n\t\t\t\t\t\tlabel: \"Dataset\",\n\t\t\t\t\t\tborderColor: window.chartColors.red,\n\t\t\t\t\t\tbackgroundColor: window.chartColors.red,\n\t\t\t\t\t\tdata: [10, 30, 46, 2, 8, 50, 0],\n\t\t\t\t\t\tfill: false,\n\t\t\t\t\t}]\n\t\t\t\t},\n\t\t\t\toptions: {\n\t\t\t\t\tresponsive: true,\n\t\t\t\t\ttitle:{\n\t\t\t\t\t\tdisplay: true,\n\t\t\t\t\t\ttext: 'Sample tooltip with border'\n\t\t\t\t\t},\n\t\t\t\t\ttooltips: {\n\t\t\t\t\t\tposition: 'nearest',\n\t\t\t\t\t\tmode: 'index',\n\t\t\t\t\t\tintersect: false,\n\t\t\t\t\t\tyPadding: 10,\n\t\t\t\t\t\txPadding: 10,\n\t\t\t\t\t\tcaretSize: 8,\n\t\t\t\t\t\tbackgroundColor: 'rgba(72, 241, 12, 1)',\n\t\t\t\t\t\ttitleFontColor: window.chartColors.black,\n\t\t\t\t\t\tbodyFontColor: window.chartColors.black,\n\t\t\t\t\t\tborderColor: 'rgba(0,0,0,1)',\n\t\t\t\t\t\tborderWidth: 4\n\t\t\t\t\t},\n\t\t\t\t}\n\t\t\t};\n\t\t}\n\n\t\twindow.onload = function() {\n\t\t\tvar container = document.querySelector('.container');\n\t\t\tvar div = document.createElement('div');\n\t\t\tdiv.classList.add('chart-container');\n\n\t\t\tvar canvas = document.createElement('canvas');\n\t\t\tdiv.appendChild(canvas);\n\t\t\tcontainer.appendChild(div);\n\n\t\t\tvar ctx = canvas.getContext('2d');\n\t\t\tvar config = createConfig();\n\t\t\tnew Chart(ctx, config);\n\t\t\tconsole.log(config);\n\t\t};\n\t</script>\n</body>\n\n</html>\n"
  },
  {
    "path": "app_backend/static/plugin/Chart.js-2.6.0/samples/tooltips/callbacks.html",
    "content": "<!doctype html>\n<html>\n\n<head>\n    <title>Tooltip Hooks</title>\n    <script src=\"../../dist/Chart.bundle.js\"></script>\n    <script src=\"../utils.js\"></script>\n    <style>\n    canvas {\n        -moz-user-select: none;\n        -webkit-user-select: none;\n        -ms-user-select: none;\n    }\n    </style>\n</head>\n\n<body>\n    <div style=\"width:75%;\">\n        <canvas id=\"canvas\"></canvas>\n    </div>\n    <script>\n        var config = {\n            type: 'line',\n            data: {\n                labels: [\"January\", \"February\", \"March\", \"April\", \"May\", \"June\", \"July\"],\n                datasets: [{\n                    label: \"My First dataset\",\n                    borderColor: window.chartColors.red,\n                    backgroundColor: window.chartColors.red,\n                    data: [\n                        randomScalingFactor(), \n                        randomScalingFactor(), \n                        randomScalingFactor(), \n                        randomScalingFactor(), \n                        randomScalingFactor(), \n                        randomScalingFactor(), \n                        randomScalingFactor()\n                    ],\n                    fill: false,\n                }, {\n                    label: \"My Second dataset\",\n                    borderColor: window.chartColors.blue,\n                    backgroundColor: window.chartColors.blue,\n                    data: [\n                        randomScalingFactor(), \n                        randomScalingFactor(), \n                        randomScalingFactor(), \n                        randomScalingFactor(), \n                        randomScalingFactor(), \n                        randomScalingFactor(), \n                        randomScalingFactor()\n                    ],\n                    fill: false,\n                }]\n            },\n            options: {\n                responsive: true,\n                title:{\n                    display: true,\n                    text: \"Chart.js Line Chart - Custom Information in Tooltip\"\n                },\n                tooltips: {\n                    mode: 'index',\n                    callbacks: {\n                        // Use the footer callback to display the sum of the items showing in the tooltip\n                        footer: function(tooltipItems, data) {\n                            var sum = 0;\n\n                            tooltipItems.forEach(function(tooltipItem) {\n                                sum += data.datasets[tooltipItem.datasetIndex].data[tooltipItem.index];\n                            });\n                            return 'Sum: ' + sum;\n                        },\n                    },\n                    footerFontStyle: 'normal'\n                },\n                hover: {\n                    mode: 'index',\n                    intersect: true\n                },\n                scales: {\n                    xAxes: [{\n                        display: true,\n                        scaleLabel: {\n                            show: true,\n                            labelString: 'Month'\n                        }\n                    }],\n                    yAxes: [{\n                        display: true,\n                        scaleLabel: {\n                            show: true,\n                            labelString: 'Value'\n                        }\n                    }]\n                }\n            }\n        };\n\n        window.onload = function() {\n            var ctx = document.getElementById(\"canvas\").getContext(\"2d\");\n            window.myLine = new Chart(ctx, config);\n        };\n    </script>\n</body>\n\n</html>\n"
  },
  {
    "path": "app_backend/static/plugin/Chart.js-2.6.0/samples/tooltips/custom-line.html",
    "content": "<!doctype html>\n<html>\n\n<head>\n\t<title>Line Chart with Custom Tooltips</title>\n\t<script src=\"../../dist/Chart.bundle.js\"></script>\n\t<script src=\"../utils.js\"></script>\n\t<style>\n\t\tcanvas{\n\t\t\t-moz-user-select: none;\n\t\t\t-webkit-user-select: none;\n\t\t\t-ms-user-select: none;\n\t\t}\n\t\t#chartjs-tooltip {\n\t\t\topacity: 1;\n\t\t\tposition: absolute;\n\t\t\tbackground: rgba(0, 0, 0, .7);\n\t\t\tcolor: white;\n\t\t\tborder-radius: 3px;\n\t\t\t-webkit-transition: all .1s ease;\n\t\t\ttransition: all .1s ease;\n\t\t\tpointer-events: none;\n\t\t\t-webkit-transform: translate(-50%, 0);\n\t\t\ttransform: translate(-50%, 0);\n\t\t}\n\n\t\t.chartjs-tooltip-key {\n\t\t\tdisplay: inline-block;\n\t\t\twidth: 10px;\n\t\t\theight: 10px;\n\t\t\tmargin-right: 10px;\n\t\t}\n\t</style>\n</head>\n\n<body>\n\t<div id=\"canvas-holder1\" style=\"width:75%;\">\n\t\t<canvas id=\"chart\"/>\n\t</div>\n\t<script>\n\t\tChart.defaults.global.pointHitDetectionRadius = 1;\n\n\t\tvar customTooltips = function(tooltip) {\n\t\t\t// Tooltip Element\n\t\t\tvar tooltipEl = document.getElementById('chartjs-tooltip');\n\n\t\t\tif (!tooltipEl) {\n\t\t\t\ttooltipEl = document.createElement('div');\n\t\t\t\ttooltipEl.id = 'chartjs-tooltip';\n\t\t\t\ttooltipEl.innerHTML = \"<table></table>\"\n\t\t\t\tthis._chart.canvas.parentNode.appendChild(tooltipEl);\n\t\t\t}\n\n\t\t\t// Hide if no tooltip\n\t\t\tif (tooltip.opacity === 0) {\n\t\t\t\ttooltipEl.style.opacity = 0;\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// Set caret Position\n\t\t\ttooltipEl.classList.remove('above', 'below', 'no-transform');\n\t\t\tif (tooltip.yAlign) {\n\t\t\t\ttooltipEl.classList.add(tooltip.yAlign);\n\t\t\t} else {\n\t\t\t\ttooltipEl.classList.add('no-transform');\n\t\t\t}\n\n\t\t\tfunction getBody(bodyItem) {\n\t\t\t\treturn bodyItem.lines;\n\t\t\t}\n\n\t\t\t// Set Text\n\t\t\tif (tooltip.body) {\n\t\t\t\tvar titleLines = tooltip.title || [];\n\t\t\t\tvar bodyLines = tooltip.body.map(getBody);\n\n\t\t\t\tvar innerHtml = '<thead>';\n\n\t\t\t\ttitleLines.forEach(function(title) {\n\t\t\t\t\tinnerHtml += '<tr><th>' + title + '</th></tr>';\n\t\t\t\t});\n\t\t\t\tinnerHtml += '</thead><tbody>';\n\n\t\t\t\tbodyLines.forEach(function(body, i) {\n\t\t\t\t\tvar colors = tooltip.labelColors[i];\n\t\t\t\t\tvar style = 'background:' + colors.backgroundColor;\n\t\t\t\t\tstyle += '; border-color:' + colors.borderColor;\n\t\t\t\t\tstyle += '; border-width: 2px'; \n\t\t\t\t\tvar span = '<span class=\"chartjs-tooltip-key\" style=\"' + style + '\"></span>';\n\t\t\t\t\tinnerHtml += '<tr><td>' + span + body + '</td></tr>';\n\t\t\t\t});\n\t\t\t\tinnerHtml += '</tbody>';\n\n\t\t\t\tvar tableRoot = tooltipEl.querySelector('table');\n\t\t\t\ttableRoot.innerHTML = innerHtml;\n\t\t\t}\n\n\t\t\tvar positionY = this._chart.canvas.offsetTop;\n\t\t\tvar positionX = this._chart.canvas.offsetLeft;\n\n\t\t\t// Display, position, and set styles for font\n\t\t\ttooltipEl.style.opacity = 1;\n\t\t\ttooltipEl.style.left = positionX + tooltip.caretX + 'px';\n\t\t\ttooltipEl.style.top = positionY + tooltip.caretY + 'px';\n\t\t\ttooltipEl.style.fontFamily = tooltip._fontFamily;\n\t\t\ttooltipEl.style.fontSize = tooltip.fontSize;\n\t\t\ttooltipEl.style.fontStyle = tooltip._fontStyle;\n\t\t\ttooltipEl.style.padding = tooltip.yPadding + 'px ' + tooltip.xPadding + 'px';\n\t\t};\n\n\t\tvar lineChartData = {\n\t\t\tlabels: [\"January\", \"February\", \"March\", \"April\", \"May\", \"June\", \"July\"],\n\t\t\tdatasets: [{\n\t\t\t\tlabel: \"My First dataset\",\n\t\t\t\tborderColor: window.chartColors.red,\n\t\t\t\tpointBackgroundColor: window.chartColors.red,\n\t\t\t\tfill: false,\n\t\t\t\tdata: [\n\t\t\t\t\trandomScalingFactor(), \n\t\t\t\t\trandomScalingFactor(), \n\t\t\t\t\trandomScalingFactor(), \n\t\t\t\t\trandomScalingFactor(), \n\t\t\t\t\trandomScalingFactor(), \n\t\t\t\t\trandomScalingFactor(), \n\t\t\t\t\trandomScalingFactor()\n\t\t\t\t]\n\t\t\t}, {\n\t\t\t\tlabel: \"My Second dataset\",\n\t\t\t\tborderColor: window.chartColors.blue,\n\t\t\t\tpointBackgroundColor: window.chartColors.blue,\n\t\t\t\tfill: false,\n\t\t\t\tdata: [\n\t\t\t\t\trandomScalingFactor(), \n\t\t\t\t\trandomScalingFactor(), \n\t\t\t\t\trandomScalingFactor(), \n\t\t\t\t\trandomScalingFactor(), \n\t\t\t\t\trandomScalingFactor(), \n\t\t\t\t\trandomScalingFactor(), \n\t\t\t\t\trandomScalingFactor()\n\t\t\t\t]\n\t\t\t}]\n\t\t};\n\n\t\twindow.onload = function() {\n\t\t\tvar chartEl = document.getElementById(\"chart\");\n\t\t\twindow.myLine = new Chart(chartEl, {\n\t\t\t\ttype: 'line',\n\t\t\t\tdata: lineChartData,\n\t\t\t\toptions: {\n\t\t\t\t\ttitle:{\n\t\t\t\t\t\tdisplay:true,\n\t\t\t\t\t\ttext:'Chart.js Line Chart - Custom Tooltips'\n\t\t\t\t\t},\n\t\t\t\t\ttooltips: {\n\t\t\t\t\t\tenabled: false,\n\t\t\t\t\t\tmode: 'index',\n\t\t\t\t\t\tposition: 'nearest',\n\t\t\t\t\t\tcustom: customTooltips\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t});\n\t\t};\n\t</script>\n</body>\n\n</html>\n"
  },
  {
    "path": "app_backend/static/plugin/Chart.js-2.6.0/samples/tooltips/custom-pie.html",
    "content": "<!doctype html>\n<html>\n\n<head>\n\t\t<title>Pie Chart with Custom Tooltips</title>\n\t\t<script src=\"../../dist/Chart.bundle.js\"></script>\n\t\t<script src=\"../utils.js\"></script>\n\n\t\t<style>\n\t\t#canvas-holder {\n\t\t\t\twidth: 100%;\n\t\t\t\tmargin-top: 50px;\n\t\t\t\ttext-align: center;\n\t\t}\n\t\t#chartjs-tooltip {\n\t\t\topacity: 1;\n\t\t\tposition: absolute;\n\t\t\tbackground: rgba(0, 0, 0, .7);\n\t\t\tcolor: white;\n\t\t\tborder-radius: 3px;\n\t\t\t-webkit-transition: all .1s ease;\n\t\t\ttransition: all .1s ease;\n\t\t\tpointer-events: none;\n\t\t\t-webkit-transform: translate(-50%, 0);\n\t\t\ttransform: translate(-50%, 0);\n\t\t}\n\n\t\t.chartjs-tooltip-key {\n\t\t\tdisplay: inline-block;\n\t\t\twidth: 10px;\n\t\t\theight: 10px;\n\t\t\tmargin-right: 10px;\n\t\t}\n\t\t</style>\n</head>\n\n<body>\n\t<div id=\"canvas-holder\" style=\"width: 300px;\">\n\t\t<canvas id=\"chart-area\" width=\"300\" height=\"300\"></canvas>\n\t\t<div id=\"chartjs-tooltip\">\n\t\t\t<table></table>\n\t\t</div>\n\t</div>\n\n\t<script>\n\tChart.defaults.global.tooltips.custom = function(tooltip) {\n\t\t// Tooltip Element\n\t\tvar tooltipEl = document.getElementById('chartjs-tooltip');\n\n\t\t// Hide if no tooltip\n\t\tif (tooltip.opacity === 0) {\n\t\t\ttooltipEl.style.opacity = 0;\n\t\t\treturn;\n\t\t}\n\n\t\t// Set caret Position\n\t\ttooltipEl.classList.remove('above', 'below', 'no-transform');\n\t\tif (tooltip.yAlign) {\n\t\t\ttooltipEl.classList.add(tooltip.yAlign);\n\t\t} else {\n\t\t\ttooltipEl.classList.add('no-transform');\n\t\t}\n\n\t\tfunction getBody(bodyItem) {\n\t\t\treturn bodyItem.lines;\n\t\t}\n\n\t\t// Set Text\n\t\tif (tooltip.body) {\n\t\t\tvar titleLines = tooltip.title || [];\n\t\t\tvar bodyLines = tooltip.body.map(getBody);\n\n\t\t\tvar innerHtml = '<thead>';\n\n\t\t\ttitleLines.forEach(function(title) {\n\t\t\t\tinnerHtml += '<tr><th>' + title + '</th></tr>';\n\t\t\t});\n\t\t\tinnerHtml += '</thead><tbody>';\n\n\t\t\tbodyLines.forEach(function(body, i) {\n\t\t\t\tvar colors = tooltip.labelColors[i];\n\t\t\t\tvar style = 'background:' + colors.backgroundColor;\n\t\t\t\tstyle += '; border-color:' + colors.borderColor;\n\t\t\t\tstyle += '; border-width: 2px'; \n\t\t\t\tvar span = '<span class=\"chartjs-tooltip-key\" style=\"' + style + '\"></span>';\n\t\t\t\tinnerHtml += '<tr><td>' + span + body + '</td></tr>';\n\t\t\t});\n\t\t\tinnerHtml += '</tbody>';\n\n\t\t\tvar tableRoot = tooltipEl.querySelector('table');\n\t\t\ttableRoot.innerHTML = innerHtml;\n\t\t}\n\n\t\tvar positionY = this._chart.canvas.offsetTop;\n\t\tvar positionX = this._chart.canvas.offsetLeft;\n\n\t\t// Display, position, and set styles for font\n\t\ttooltipEl.style.opacity = 1;\n\t\ttooltipEl.style.left = positionX + tooltip.caretX + 'px';\n\t\ttooltipEl.style.top = positionY + tooltip.caretY + 'px';\n\t\ttooltipEl.style.fontFamily = tooltip._fontFamily;\n\t\ttooltipEl.style.fontSize = tooltip.fontSize;\n\t\ttooltipEl.style.fontStyle = tooltip._fontStyle;\n\t\ttooltipEl.style.padding = tooltip.yPadding + 'px ' + tooltip.xPadding + 'px';\n\t};\n\n\tvar config = {\n\t\ttype: 'pie',\n\t\tdata: {\n\t\t\tdatasets: [{\n\t\t\t\tdata: [300, 50, 100, 40, 10],\n\t\t\t\tbackgroundColor: [\n\t\t\t\t\twindow.chartColors.red,\n\t\t\t\t\twindow.chartColors.orange,\n\t\t\t\t\twindow.chartColors.yellow,\n\t\t\t\t\twindow.chartColors.green,\n\t\t\t\t\twindow.chartColors.blue,\n\t\t\t\t],\n\t\t\t}],\n\t\t\tlabels: [\n\t\t\t\t\"Red\",\n\t\t\t\t\"Orange\",\n\t\t\t\t\"Yellow\",\n\t\t\t\t\"Green\",\n\t\t\t\t\"Blue\"\n\t\t\t]\n\t\t},\n\t\toptions: {\n\t\t\tresponsive: true,\n\t\t\tlegend: {\n\t\t\t\tdisplay: false\n\t\t\t},\n\t\t\ttooltips: {\n\t\t\t\tenabled: false,\n\t\t\t}\n\t\t}\n\t};\n\n\twindow.onload = function() {\n\t\t\tvar ctx = document.getElementById(\"chart-area\").getContext(\"2d\");\n\t\t\twindow.myPie = new Chart(ctx, config);\n\t};\n\t</script>\n</body>\n\n</html>\n"
  },
  {
    "path": "app_backend/static/plugin/Chart.js-2.6.0/samples/tooltips/custom-points.html",
    "content": "<!doctype html>\n<html>\n\n<head>\n\t<title>Custom Tooltips using Data Points</title>\n\t<script src=\"../../dist/Chart.bundle.js\"></script>\n\t<script src=\"../utils.js\"></script>\n\t<script src=\"https://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js\"></script>\n\t<style>\n\t\tcanvas{\n\t\t\t-moz-user-select: none;\n\t\t\t-webkit-user-select: none;\n\t\t\t-ms-user-select: none;\n\t\t}\n\t\t.chartjs-tooltip {\n\t\t\topacity: 1;\n\t\t\tposition: absolute;\n\t\t\tbackground: rgba(0, 0, 0, .7);\n\t\t\tcolor: white;\n\t\t\tborder-radius: 3px;\n\t\t\t-webkit-transition: all .1s ease;\n\t\t\ttransition: all .1s ease;\n\t\t\tpointer-events: none;\n\t\t\t-webkit-transform: translate(-50%, 0);\n\t\t\ttransform: translate(-50%, 0);\n\t\t\tpadding: 4px;\n\t\t}\n\n\t\t.chartjs-tooltip-key {\n\t\t\tdisplay: inline-block;\n\t\t\twidth: 10px;\n\t\t\theight: 10px;\n\t\t}\n\t</style>\n</head>\n\n<body>\n\t<div id=\"canvas-holder1\" style=\"width:75%;\">\n\t\t<canvas id=\"chart1\"></canvas>\n\t\t<div class=\"chartjs-tooltip\" id=\"tooltip-0\"></div>\n\t\t<div class=\"chartjs-tooltip\" id=\"tooltip-1\"></div>\n\t</div>\n\t<script>\n\t\tvar customTooltips = function (tooltip) {\n\t\t\t$(this._chart.canvas).css(\"cursor\", \"pointer\");\n\n\t\t\tvar positionY = this._chart.canvas.offsetTop;\n\t\t\tvar positionX = this._chart.canvas.offsetLeft;\n\n\t\t\t$(\".chartjs-tooltip\").css({\n\t\t\t\topacity: 0,\n\t\t\t});\n\n\t\t\tif (!tooltip || !tooltip.opacity) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif (tooltip.dataPoints.length > 0) {\n\t\t\t\ttooltip.dataPoints.forEach(function (dataPoint) {\n\t\t\t\t\tvar content = [dataPoint.xLabel, dataPoint.yLabel].join(\": \");\n\t\t\t\t\tvar $tooltip = $(\"#tooltip-\" + dataPoint.datasetIndex);\n\n\t\t\t\t\t$tooltip.html(content);\n\t\t\t\t\t$tooltip.css({\n\t\t\t\t\t\topacity: 1,\n\t\t\t\t\t\ttop: positionY + dataPoint.y + \"px\",\n\t\t\t\t\t\tleft: positionX + dataPoint.x + \"px\",\n\t\t\t\t\t});\n\t\t\t\t});\n\t\t\t}\n\t\t};\n\t\tvar color = Chart.helpers.color;\n\t\tvar lineChartData = {\n\t\t\tlabels: [\"January\", \"February\", \"March\", \"April\", \"May\", \"June\", \"July\"],\n\t\t\tdatasets: [{\n\t\t\t\tlabel: \"My First dataset\",\n\t\t\t\tbackgroundColor: color(window.chartColors.red).alpha(0.2).rgbString(),\n\t\t\t\tborderColor: window.chartColors.red,\n\t\t\t\tpointBackgroundColor: window.chartColors.red,\n\t\t\t\tdata: [\n\t\t\t\t\trandomScalingFactor(), \n\t\t\t\t\trandomScalingFactor(), \n\t\t\t\t\trandomScalingFactor(), \n\t\t\t\t\trandomScalingFactor(), \n\t\t\t\t\trandomScalingFactor(), \n\t\t\t\t\trandomScalingFactor(), \n\t\t\t\t\trandomScalingFactor()\n\t\t\t\t]\n\t\t\t}, {\n\t\t\t\tlabel: \"My Second dataset\",\n\t\t\t\tbackgroundColor: color(window.chartColors.blue).alpha(0.2).rgbString(),\n\t\t\t\tborderColor: window.chartColors.blue,\n\t\t\t\tpointBackgroundColor: window.chartColors.blue,\n\t\t\t\tdata: [\n\t\t\t\t\trandomScalingFactor(), \n\t\t\t\t\trandomScalingFactor(), \n\t\t\t\t\trandomScalingFactor(), \n\t\t\t\t\trandomScalingFactor(), \n\t\t\t\t\trandomScalingFactor(), \n\t\t\t\t\trandomScalingFactor(), \n\t\t\t\t\trandomScalingFactor()\n\t\t\t\t]\n\t\t\t}]\n\t\t};\n\n\t\twindow.onload = function() {\n\t\t\tvar chartEl = document.getElementById(\"chart1\");\n\t\t\tvar chart = new Chart(chartEl, {\n\t\t\t\ttype: \"line\",\n\t\t\t\tdata: lineChartData,\n\t\t\t\toptions: {\n\t\t\t\t\ttitle:{\n\t\t\t\t\t\tdisplay: true,\n\t\t\t\t\t\ttext: \"Chart.js - Custom Tooltips using Data Points\"\n\t\t\t\t\t},\n\t\t\t\t\ttooltips: {\n\t\t\t\t\t\tenabled: false,\n\t\t\t\t\t\tmode: 'index',\n\t\t\t\t\t\tintersect: false,\n\t\t\t\t\t\tcustom: customTooltips\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t});\n\t\t};\n\t</script>\n</body>\n\n</html>\n"
  },
  {
    "path": "app_backend/static/plugin/Chart.js-2.6.0/samples/tooltips/interactions.html",
    "content": "<!doctype html>\n<html>\n\n<head>\n\t<title>Tooltip Interaction Modes</title>\n\t<script src=\"../../dist/Chart.bundle.js\"></script>\n\t<script src=\"../utils.js\"></script>\n\t<style>\n\tcanvas {\n\t\t-moz-user-select: none;\n\t\t-webkit-user-select: none;\n\t\t-ms-user-select: none;\n\t}\n\t.chart-container {\n\t\twidth: 500px;\n\t\tmargin-left: 40px;\n\t\tmargin-right: 40px;\n\t\tmargin-bottom: 40px;\n\t}\n\t.container {\n\t\tdisplay: flex;\n\t\tflex-direction: row;\n\t\tflex-wrap: wrap;\n\t\tjustify-content: center;\n\t}\n\t</style>\n</head>\n\n<body>\n\t<div class=\"container\">\n\t</div>\n\t<script>\n\t\tfunction createConfig(mode, intersect) {\n\t\t\treturn {\n\t\t\t\ttype: 'line',\n\t\t\t\tdata: {\n\t\t\t\t\tlabels: [\"January\", \"February\", \"March\", \"April\", \"May\", \"June\", \"July\"],\n\t\t\t\t\tdatasets: [{\n\t\t\t\t\t\tlabel: \"My First dataset\",\n\t\t\t\t\t\tborderColor: window.chartColors.red,\n\t\t\t\t\t\tbackgroundColor: window.chartColors.red,\n\t\t\t\t\t\tdata: [10, 30, 46, 2, 8, 50, 0],\n\t\t\t\t\t\tfill: false,\n\t\t\t\t\t}, {\n\t\t\t\t\t\tlabel: \"My Second dataset\",\n\t\t\t\t\t\tborderColor: window.chartColors.blue,\n\t\t\t\t\t\tbackgroundColor: window.chartColors.blue,\n\t\t\t\t\t\tdata: [7, 49, 46, 13, 25, 30, 22],\n\t\t\t\t\t\tfill: false,\n\t\t\t\t\t}]\n\t\t\t\t},\n\t\t\t\toptions: {\n\t\t\t\t\tresponsive: true,\n\t\t\t\t\ttitle:{\n\t\t\t\t\t\tdisplay: true,\n\t\t\t\t\t\ttext: 'Mode: ' + mode + ', intersect = ' + intersect\n\t\t\t\t\t},\n\t\t\t\t\ttooltips: {\n\t\t\t\t\t\tmode: mode,\n\t\t\t\t\t\tintersect: intersect,\n\t\t\t\t\t},\n\t\t\t\t\thover: {\n\t\t\t\t\t\tmode: mode,\n\t\t\t\t\t\tintersect: intersect\n\t\t\t\t\t},\n\t\t\t\t}\n\t\t\t};\n\t\t}\n\n\t\twindow.onload = function() {\n\t\t\tvar container = document.querySelector('.container');\n\n\t\t\t[{\n\t\t\t\tmode: 'index',\n\t\t\t\tintersect: true,\n\t\t\t}, {\n\t\t\t\tmode: 'index',\n\t\t\t\tintersect: false,\n\t\t\t}, {\n\t\t\t\tmode: 'dataset',\n\t\t\t\tintersect: true,\n\t\t\t}, {\n\t\t\t\tmode: 'dataset',\n\t\t\t\tintersect: false,\n\t\t\t}, {\n\t\t\t\tmode: 'point',\n\t\t\t\tintersect: true,\n\t\t\t}, {\n\t\t\t\tmode: 'point',\n\t\t\t\tintersect: false,\n\t\t\t}, {\n\t\t\t\tmode: 'nearest',\n\t\t\t\tintersect: true,\n\t\t\t}, {\n\t\t\t\tmode: 'nearest',\n\t\t\t\tintersect: false,\n\t\t\t}, {\n\t\t\t\tmode: 'x',\n\t\t\t\tintersect: true\n\t\t\t}, {\n\t\t\t\tmode: 'x',\n\t\t\t\tintersect: false\n\t\t\t}, {\n\t\t\t\tmode: 'y',\n\t\t\t\tintersect: true\n\t\t\t}, {\n\t\t\t\tmode: 'y',\n\t\t\t\tintersect: false\n\t\t\t}].forEach(function(details) {\n\t\t\t\tvar div = document.createElement('div');\n\t\t\t\tdiv.classList.add('chart-container');\n\n\t\t\t\tvar canvas = document.createElement('canvas');\n\t\t\t\tdiv.appendChild(canvas);\n\t\t\t\tcontainer.appendChild(div);\n\n\t\t\t\tvar ctx = canvas.getContext('2d');\n\t\t\t\tvar config = createConfig(details.mode, details.intersect);\n\t\t\t\tnew Chart(ctx, config);\n\t\t\t})\n\t\t};\n\t</script>\n</body>\n\n</html>\n"
  },
  {
    "path": "app_backend/static/plugin/Chart.js-2.6.0/samples/tooltips/positioning.html",
    "content": "<!doctype html>\n<html>\n\n<head>\n\t<title>Tooltip Interaction Modes</title>\n\t<script src=\"../../dist/Chart.bundle.js\"></script>\n\t<script src=\"../utils.js\"></script>\n\t<style>\n\tcanvas {\n\t\t-moz-user-select: none;\n\t\t-webkit-user-select: none;\n\t\t-ms-user-select: none;\n\t}\n\t.chart-container {\n\t\twidth: 500px;\n\t\tmargin-left: 40px;\n\t\tmargin-right: 40px;\n\t\tmargin-bottom: 40px;\n\t}\n\t.container {\n\t\tdisplay: flex;\n\t\tflex-direction: row;\n\t\tflex-wrap: wrap;\n\t\tjustify-content: center;\n\t}\n\t</style>\n</head>\n\n<body>\n\t<div class=\"container\">\n\t</div>\n\t<script>\n\t\tfunction createConfig(position) {\n\t\t\treturn {\n\t\t\t\ttype: 'line',\n\t\t\t\tdata: {\n\t\t\t\t\tlabels: [\"January\", \"February\", \"March\", \"April\", \"May\", \"June\", \"July\"],\n\t\t\t\t\tdatasets: [{\n\t\t\t\t\t\tlabel: \"My First dataset\",\n\t\t\t\t\t\tborderColor: window.chartColors.red,\n\t\t\t\t\t\tbackgroundColor: window.chartColors.red,\n\t\t\t\t\t\tdata: [10, 30, 46, 2, 8, 50, 0],\n\t\t\t\t\t\tfill: false,\n\t\t\t\t\t}, {\n\t\t\t\t\t\tlabel: \"My Second dataset\",\n\t\t\t\t\t\tborderColor: window.chartColors.blue,\n\t\t\t\t\t\tbackgroundColor: window.chartColors.blue,\n\t\t\t\t\t\tdata: [7, 49, 46, 13, 25, 30, 22],\n\t\t\t\t\t\tfill: false,\n\t\t\t\t\t}]\n\t\t\t\t},\n\t\t\t\toptions: {\n\t\t\t\t\tresponsive: true,\n\t\t\t\t\ttitle:{\n\t\t\t\t\t\tdisplay: true,\n\t\t\t\t\t\ttext: 'Tooltip Position: ' + position\n\t\t\t\t\t},\n\t\t\t\t\ttooltips: {\n\t\t\t\t\t\tposition: position,\n\t\t\t\t\t\tmode: 'index',\n\t\t\t\t\t\tintersect: false,\n\t\t\t\t\t},\n\t\t\t\t}\n\t\t\t};\n\t\t}\n\n\t\twindow.onload = function() {\n\t\t\tvar container = document.querySelector('.container');\n\n\t\t\t['average', 'nearest'].forEach(function(position) {\n\t\t\t\tvar div = document.createElement('div');\n\t\t\t\tdiv.classList.add('chart-container');\n\n\t\t\t\tvar canvas = document.createElement('canvas');\n\t\t\t\tdiv.appendChild(canvas);\n\t\t\t\tcontainer.appendChild(div);\n\n\t\t\t\tvar ctx = canvas.getContext('2d');\n\t\t\t\tvar config = createConfig(position);\n\t\t\t\tnew Chart(ctx, config);\n\t\t\t})\n\t\t};\n\t</script>\n</body>\n\n</html>\n"
  },
  {
    "path": "app_backend/static/plugin/Chart.js-2.6.0/samples/utils.js",
    "content": "/* global Chart */\n\n'use strict';\n\nwindow.chartColors = {\n\tred: 'rgb(255, 99, 132)',\n\torange: 'rgb(255, 159, 64)',\n\tyellow: 'rgb(255, 205, 86)',\n\tgreen: 'rgb(75, 192, 192)',\n\tblue: 'rgb(54, 162, 235)',\n\tpurple: 'rgb(153, 102, 255)',\n\tgrey: 'rgb(201, 203, 207)'\n};\n\nwindow.randomScalingFactor = function() {\n\treturn (Math.random() > 0.5 ? 1.0 : -1.0) * Math.round(Math.random() * 100);\n};\n\n(function(global) {\n\tvar Months = [\n\t\t'January',\n\t\t'February',\n\t\t'March',\n\t\t'April',\n\t\t'May',\n\t\t'June',\n\t\t'July',\n\t\t'August',\n\t\t'September',\n\t\t'October',\n\t\t'November',\n\t\t'December'\n\t];\n\n\tvar Samples = global.Samples || (global.Samples = {});\n\tSamples.utils = {\n\t\t// Adapted from http://indiegamr.com/generate-repeatable-random-numbers-in-js/\n\t\tsrand: function(seed) {\n\t\t\tthis._seed = seed;\n\t\t},\n\n\t\trand: function(min, max) {\n\t\t\tvar seed = this._seed;\n\t\t\tmin = min === undefined? 0 : min;\n\t\t\tmax = max === undefined? 1 : max;\n\t\t\tthis._seed = (seed * 9301 + 49297) % 233280;\n\t\t\treturn min + (this._seed / 233280) * (max - min);\n\t\t},\n\n\t\tnumbers: function(config) {\n\t\t\tvar cfg = config || {};\n\t\t\tvar min = cfg.min || 0;\n\t\t\tvar max = cfg.max || 1;\n\t\t\tvar from = cfg.from || [];\n\t\t\tvar count = cfg.count || 8;\n\t\t\tvar decimals = cfg.decimals || 8;\n\t\t\tvar continuity = cfg.continuity || 1;\n\t\t\tvar dfactor = Math.pow(10, decimals) || 0;\n\t\t\tvar data = [];\n\t\t\tvar i, value;\n\n\t\t\tfor (i=0; i<count; ++i) {\n\t\t\t\tvalue = (from[i] || 0) + this.rand(min, max);\n\t\t\t\tif (this.rand() <= continuity) {\n\t\t\t\t\tdata.push(Math.round(dfactor * value) / dfactor);\n\t\t\t\t} else {\n\t\t\t\t\tdata.push(null);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn data;\n\t\t},\n\n\t\tlabels: function(config) {\n\t\t\tvar cfg = config || {};\n\t\t\tvar min = cfg.min || 0;\n\t\t\tvar max = cfg.max || 100;\n\t\t\tvar count = cfg.count || 8;\n\t\t\tvar step = (max-min) / count;\n\t\t\tvar decimals = cfg.decimals || 8;\n\t\t\tvar dfactor = Math.pow(10, decimals) || 0;\n\t\t\tvar prefix = cfg.prefix || '';\n\t\t\tvar values = [];\n\t\t\tvar i;\n\n\t\t\tfor (i=min; i<max; i+=step) {\n\t\t\t\tvalues.push(prefix + Math.round(dfactor * i) / dfactor);\n\t\t\t}\n\n\t\t\treturn values;\n\t\t},\n\n\t\tmonths: function(config) {\n\t\t\tvar cfg = config || {};\n\t\t\tvar count = cfg.count || 12;\n\t\t\tvar section = cfg.section;\n\t\t\tvar values = [];\n\t\t\tvar i, value;\n\n\t\t\tfor (i=0; i<count; ++i) {\n\t\t\t\tvalue = Months[Math.ceil(i)%12];\n\t\t\t\tvalues.push(value.substring(0, section));\n\t\t\t}\n\n\t\t\treturn values;\n\t\t},\n\n\t\ttransparentize: function(color, opacity) {\n\t\t\tvar alpha = opacity === undefined? 0.5 : 1 - opacity;\n\t\t\treturn Chart.helpers.color(color).alpha(alpha).rgbString();\n\t\t},\n\n\t\tmerge: Chart.helpers.configMerge\n\t};\n\n\tSamples.utils.srand(Date.now());\n\n}(this));\n\n"
  },
  {
    "path": "app_backend/static/plugin/Chart.js-2.6.0/scripts/deploy.sh",
    "content": "#!/bin/bash\n\nset -e\n\nTARGET_DIR='gh-pages'\nTARGET_BRANCH='master'\nTARGET_REPO_URL=\"https://$GITHUB_AUTH_TOKEN@github.com/chartjs/chartjs.github.io.git\"\nVERSION_REGEX='[[:digit:]]+.[[:digit:]]+.[[:digit:]]+(-.*)?'\n\n# Make sure that this script is executed only for the release and master branches\nif [ \"$TRAVIS_BRANCH\" == \"release\" ]; then\n    # Travis executes this script from the repository root, so at the same level than package.json\n    VERSION=$(node -p -e \"require('./package.json').version\")\nelif [ \"$TRAVIS_BRANCH\" == \"master\" ]; then\n    VERSION=\"master\"\nelse\n    echo \"Skipping deploy because this is not the master or release branch\"\n    exit 0\nfi\n\nfunction update_latest {\n    local out_path=$1\n    local latest=($(ls -v $out_path | egrep '^('$VERSION_REGEX')$' | tail -1))\n    if [ \"$latest\" == \"\" ]; then latest='master'; fi\n    rm -f $out_path/latest\n    ln -s $latest $out_path/latest\n}\n\nfunction deploy_files {\n    local in_files=$1\n    local out_path=$2\n    rm -rf $out_path/$VERSION\n    mkdir -p $out_path/$VERSION\n    cp -r $in_files $out_path/$VERSION\n    update_latest $out_path\n}\n\n# Clone the repository and checkout the gh-pages branch\ngit clone $TARGET_REPO_URL $TARGET_DIR\ncd $TARGET_DIR\ngit checkout $TARGET_BRANCH\n\n# Copy dist files\ndeploy_files '../dist/*.js' './dist'\n\n# Copy generated documentation\ndeploy_files '../dist/docs/*' './docs'\n\n# Copy samples ...\ndeploy_files '../samples/*' './samples'\n\n# ... and relocate samples Chart/js scripts\nfor f in $(find ./samples/$VERSION -name '*.html'); do\n   sed -i -E \"s/((\\.\\.\\/)+dist\\/)/..\\/\\1$VERSION\\//\" $f\ndone\n\ngit add -A\n\ngit remote add auth-origin $TARGET_REPO_URL\ngit config --global user.email \"$GITHUB_AUTH_EMAIL\"\ngit config --global user.name \"Chart.js\"\ngit commit -m \"Deploy $VERSION from $TRAVIS_REPO_SLUG\" -m \"Commit: $TRAVIS_COMMIT\"\ngit push -q auth-origin $TARGET_BRANCH\ngit remote rm auth-origin\n\n# Cleanup\ncd ..\nrm -rf $TARGET_DIR\n"
  },
  {
    "path": "app_backend/static/plugin/Chart.js-2.6.0/scripts/release.sh",
    "content": "#!/bin/bash\n\nset -e\n\nif [ \"$TRAVIS_BRANCH\" != \"release\" ]; then\n    echo \"Skipping release because this is not the 'release' branch\"\n    exit 0\nfi\n\n# Travis executes this script from the repository root, so at the same level than package.json\nVERSION=$(node -p -e \"require('./package.json').version\")\n\n# Make sure that the associated tag doesn't already exist\nGITTAG=$(git ls-remote origin refs/tags/v$VERSION)\nif [ \"$GITTAG\" != \"\" ]; then\n    echo \"Tag for package.json version already exists, aborting release\"\n    exit 1\nfi\n\ngit remote add auth-origin https://$GITHUB_AUTH_TOKEN@github.com/$TRAVIS_REPO_SLUG.git\ngit config --global user.email \"$GITHUB_AUTH_EMAIL\"\ngit config --global user.name \"Chart.js\"\ngit checkout --detach --quiet\ngit add -f dist/*.js bower.json\ngit commit -m \"Release $VERSION\"\ngit tag -a \"v$VERSION\" -m \"Version $VERSION\"\ngit push -q auth-origin refs/tags/v$VERSION 2>/dev/null\ngit remote rm auth-origin\ngit checkout -f @{-1}\n"
  },
  {
    "path": "app_backend/static/plugin/Chart.js-2.6.0/src/chart.js",
    "content": "/**\n * @namespace Chart\n */\nvar Chart = require('./core/core.js')();\n\nrequire('./core/core.helpers')(Chart);\nrequire('./platforms/platform.js')(Chart);\nrequire('./core/core.canvasHelpers')(Chart);\nrequire('./core/core.element')(Chart);\nrequire('./core/core.plugin.js')(Chart);\nrequire('./core/core.animation')(Chart);\nrequire('./core/core.controller')(Chart);\nrequire('./core/core.datasetController')(Chart);\nrequire('./core/core.layoutService')(Chart);\nrequire('./core/core.scaleService')(Chart);\nrequire('./core/core.ticks.js')(Chart);\nrequire('./core/core.scale')(Chart);\nrequire('./core/core.interaction')(Chart);\nrequire('./core/core.tooltip')(Chart);\n\nrequire('./elements/element.arc')(Chart);\nrequire('./elements/element.line')(Chart);\nrequire('./elements/element.point')(Chart);\nrequire('./elements/element.rectangle')(Chart);\n\nrequire('./scales/scale.linearbase.js')(Chart);\nrequire('./scales/scale.category')(Chart);\nrequire('./scales/scale.linear')(Chart);\nrequire('./scales/scale.logarithmic')(Chart);\nrequire('./scales/scale.radialLinear')(Chart);\nrequire('./scales/scale.time')(Chart);\n\n// Controllers must be loaded after elements\n// See Chart.core.datasetController.dataElementType\nrequire('./controllers/controller.bar')(Chart);\nrequire('./controllers/controller.bubble')(Chart);\nrequire('./controllers/controller.doughnut')(Chart);\nrequire('./controllers/controller.line')(Chart);\nrequire('./controllers/controller.polarArea')(Chart);\nrequire('./controllers/controller.radar')(Chart);\n\nrequire('./charts/Chart.Bar')(Chart);\nrequire('./charts/Chart.Bubble')(Chart);\nrequire('./charts/Chart.Doughnut')(Chart);\nrequire('./charts/Chart.Line')(Chart);\nrequire('./charts/Chart.PolarArea')(Chart);\nrequire('./charts/Chart.Radar')(Chart);\nrequire('./charts/Chart.Scatter')(Chart);\n\n// Loading built-it plugins\nvar plugins = [];\n\nplugins.push(\n    require('./plugins/plugin.filler.js')(Chart),\n    require('./plugins/plugin.legend.js')(Chart),\n    require('./plugins/plugin.title.js')(Chart)\n);\n\nChart.plugins.register(plugins);\n\nmodule.exports = Chart;\nif (typeof window !== 'undefined') {\n\twindow.Chart = Chart;\n}\n"
  },
  {
    "path": "app_backend/static/plugin/Chart.js-2.6.0/src/charts/Chart.Bar.js",
    "content": "'use strict';\n\nmodule.exports = function(Chart) {\n\n\tChart.Bar = function(context, config) {\n\t\tconfig.type = 'bar';\n\n\t\treturn new Chart(context, config);\n\t};\n\n};\n"
  },
  {
    "path": "app_backend/static/plugin/Chart.js-2.6.0/src/charts/Chart.Bubble.js",
    "content": "'use strict';\n\nmodule.exports = function(Chart) {\n\n\tChart.Bubble = function(context, config) {\n\t\tconfig.type = 'bubble';\n\t\treturn new Chart(context, config);\n\t};\n\n};\n"
  },
  {
    "path": "app_backend/static/plugin/Chart.js-2.6.0/src/charts/Chart.Doughnut.js",
    "content": "'use strict';\n\nmodule.exports = function(Chart) {\n\n\tChart.Doughnut = function(context, config) {\n\t\tconfig.type = 'doughnut';\n\n\t\treturn new Chart(context, config);\n\t};\n\n};\n"
  },
  {
    "path": "app_backend/static/plugin/Chart.js-2.6.0/src/charts/Chart.Line.js",
    "content": "'use strict';\n\nmodule.exports = function(Chart) {\n\n\tChart.Line = function(context, config) {\n\t\tconfig.type = 'line';\n\n\t\treturn new Chart(context, config);\n\t};\n\n};\n"
  },
  {
    "path": "app_backend/static/plugin/Chart.js-2.6.0/src/charts/Chart.PolarArea.js",
    "content": "'use strict';\n\nmodule.exports = function(Chart) {\n\n\tChart.PolarArea = function(context, config) {\n\t\tconfig.type = 'polarArea';\n\n\t\treturn new Chart(context, config);\n\t};\n\n};\n"
  },
  {
    "path": "app_backend/static/plugin/Chart.js-2.6.0/src/charts/Chart.Radar.js",
    "content": "'use strict';\n\nmodule.exports = function(Chart) {\n\n\tChart.Radar = function(context, config) {\n\t\tconfig.type = 'radar';\n\n\t\treturn new Chart(context, config);\n\t};\n\n};\n"
  },
  {
    "path": "app_backend/static/plugin/Chart.js-2.6.0/src/charts/Chart.Scatter.js",
    "content": "'use strict';\n\nmodule.exports = function(Chart) {\n\n\tvar defaultConfig = {\n\t\thover: {\n\t\t\tmode: 'single'\n\t\t},\n\n\t\tscales: {\n\t\t\txAxes: [{\n\t\t\t\ttype: 'linear', // scatter should not use a category axis\n\t\t\t\tposition: 'bottom',\n\t\t\t\tid: 'x-axis-1' // need an ID so datasets can reference the scale\n\t\t\t}],\n\t\t\tyAxes: [{\n\t\t\t\ttype: 'linear',\n\t\t\t\tposition: 'left',\n\t\t\t\tid: 'y-axis-1'\n\t\t\t}]\n\t\t},\n\n\t\ttooltips: {\n\t\t\tcallbacks: {\n\t\t\t\ttitle: function() {\n\t\t\t\t\t// Title doesn't make sense for scatter since we format the data as a point\n\t\t\t\t\treturn '';\n\t\t\t\t},\n\t\t\t\tlabel: function(tooltipItem) {\n\t\t\t\t\treturn '(' + tooltipItem.xLabel + ', ' + tooltipItem.yLabel + ')';\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t};\n\n\t// Register the default config for this type\n\tChart.defaults.scatter = defaultConfig;\n\n\t// Scatter charts use line controllers\n\tChart.controllers.scatter = Chart.controllers.line;\n\n\tChart.Scatter = function(context, config) {\n\t\tconfig.type = 'scatter';\n\t\treturn new Chart(context, config);\n\t};\n\n};\n"
  },
  {
    "path": "app_backend/static/plugin/Chart.js-2.6.0/src/controllers/controller.bar.js",
    "content": "'use strict';\n\nmodule.exports = function(Chart) {\n\n\tvar helpers = Chart.helpers;\n\n\tChart.defaults.bar = {\n\t\thover: {\n\t\t\tmode: 'label'\n\t\t},\n\n\t\tscales: {\n\t\t\txAxes: [{\n\t\t\t\ttype: 'category',\n\n\t\t\t\t// Specific to Bar Controller\n\t\t\t\tcategoryPercentage: 0.8,\n\t\t\t\tbarPercentage: 0.9,\n\n\t\t\t\t// grid line settings\n\t\t\t\tgridLines: {\n\t\t\t\t\toffsetGridLines: true\n\t\t\t\t}\n\t\t\t}],\n\t\t\tyAxes: [{\n\t\t\t\ttype: 'linear'\n\t\t\t}]\n\t\t}\n\t};\n\n\tChart.controllers.bar = Chart.DatasetController.extend({\n\n\t\tdataElementType: Chart.elements.Rectangle,\n\n\t\tinitialize: function() {\n\t\t\tvar me = this;\n\t\t\tvar meta;\n\n\t\t\tChart.DatasetController.prototype.initialize.apply(me, arguments);\n\n\t\t\tmeta = me.getMeta();\n\t\t\tmeta.stack = me.getDataset().stack;\n\t\t\tmeta.bar = true;\n\t\t},\n\n\t\tupdate: function(reset) {\n\t\t\tvar me = this;\n\t\t\tvar elements = me.getMeta().data;\n\t\t\tvar i, ilen;\n\n\t\t\tme._ruler = me.getRuler();\n\n\t\t\tfor (i = 0, ilen = elements.length; i < ilen; ++i) {\n\t\t\t\tme.updateElement(elements[i], i, reset);\n\t\t\t}\n\t\t},\n\n\t\tupdateElement: function(rectangle, index, reset) {\n\t\t\tvar me = this;\n\t\t\tvar chart = me.chart;\n\t\t\tvar meta = me.getMeta();\n\t\t\tvar dataset = me.getDataset();\n\t\t\tvar custom = rectangle.custom || {};\n\t\t\tvar rectangleOptions = chart.options.elements.rectangle;\n\n\t\t\trectangle._xScale = me.getScaleForId(meta.xAxisID);\n\t\t\trectangle._yScale = me.getScaleForId(meta.yAxisID);\n\t\t\trectangle._datasetIndex = me.index;\n\t\t\trectangle._index = index;\n\n\t\t\trectangle._model = {\n\t\t\t\tdatasetLabel: dataset.label,\n\t\t\t\tlabel: chart.data.labels[index],\n\t\t\t\tborderSkipped: custom.borderSkipped ? custom.borderSkipped : rectangleOptions.borderSkipped,\n\t\t\t\tbackgroundColor: custom.backgroundColor ? custom.backgroundColor : helpers.getValueAtIndexOrDefault(dataset.backgroundColor, index, rectangleOptions.backgroundColor),\n\t\t\t\tborderColor: custom.borderColor ? custom.borderColor : helpers.getValueAtIndexOrDefault(dataset.borderColor, index, rectangleOptions.borderColor),\n\t\t\t\tborderWidth: custom.borderWidth ? custom.borderWidth : helpers.getValueAtIndexOrDefault(dataset.borderWidth, index, rectangleOptions.borderWidth)\n\t\t\t};\n\n\t\t\tme.updateElementGeometry(rectangle, index, reset);\n\n\t\t\trectangle.pivot();\n\t\t},\n\n\t\t/**\n\t\t * @private\n\t\t */\n\t\tupdateElementGeometry: function(rectangle, index, reset) {\n\t\t\tvar me = this;\n\t\t\tvar model = rectangle._model;\n\t\t\tvar vscale = me.getValueScale();\n\t\t\tvar base = vscale.getBasePixel();\n\t\t\tvar horizontal = vscale.isHorizontal();\n\t\t\tvar ruler = me._ruler || me.getRuler();\n\t\t\tvar vpixels = me.calculateBarValuePixels(me.index, index);\n\t\t\tvar ipixels = me.calculateBarIndexPixels(me.index, index, ruler);\n\n\t\t\tmodel.horizontal = horizontal;\n\t\t\tmodel.base = reset? base : vpixels.base;\n\t\t\tmodel.x = horizontal? reset? base : vpixels.head : ipixels.center;\n\t\t\tmodel.y = horizontal? ipixels.center : reset? base : vpixels.head;\n\t\t\tmodel.height = horizontal? ipixels.size : undefined;\n\t\t\tmodel.width = horizontal? undefined : ipixels.size;\n\t\t},\n\n\t\t/**\n\t\t * @private\n\t\t */\n\t\tgetValueScaleId: function() {\n\t\t\treturn this.getMeta().yAxisID;\n\t\t},\n\n\t\t/**\n\t\t * @private\n\t\t */\n\t\tgetIndexScaleId: function() {\n\t\t\treturn this.getMeta().xAxisID;\n\t\t},\n\n\t\t/**\n\t\t * @private\n\t\t */\n\t\tgetValueScale: function() {\n\t\t\treturn this.getScaleForId(this.getValueScaleId());\n\t\t},\n\n\t\t/**\n\t\t * @private\n\t\t */\n\t\tgetIndexScale: function() {\n\t\t\treturn this.getScaleForId(this.getIndexScaleId());\n\t\t},\n\n\t\t/**\n\t\t * Returns the effective number of stacks based on groups and bar visibility.\n\t\t * @private\n\t\t */\n\t\tgetStackCount: function(last) {\n\t\t\tvar me = this;\n\t\t\tvar chart = me.chart;\n\t\t\tvar scale = me.getIndexScale();\n\t\t\tvar stacked = scale.options.stacked;\n\t\t\tvar ilen = last === undefined? chart.data.datasets.length : last + 1;\n\t\t\tvar stacks = [];\n\t\t\tvar i, meta;\n\n\t\t\tfor (i = 0; i < ilen; ++i) {\n\t\t\t\tmeta = chart.getDatasetMeta(i);\n\t\t\t\tif (meta.bar && chart.isDatasetVisible(i) &&\n\t\t\t\t\t(stacked === false ||\n\t\t\t\t\t(stacked === true && stacks.indexOf(meta.stack) === -1) ||\n\t\t\t\t\t(stacked === undefined && (meta.stack === undefined || stacks.indexOf(meta.stack) === -1)))) {\n\t\t\t\t\tstacks.push(meta.stack);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn stacks.length;\n\t\t},\n\n\t\t/**\n\t\t * Returns the stack index for the given dataset based on groups and bar visibility.\n\t\t * @private\n\t\t */\n\t\tgetStackIndex: function(datasetIndex) {\n\t\t\treturn this.getStackCount(datasetIndex) - 1;\n\t\t},\n\n\t\t/**\n\t\t * @private\n\t\t */\n\t\tgetRuler: function() {\n\t\t\tvar me = this;\n\t\t\tvar scale = me.getIndexScale();\n\t\t\tvar options = scale.options;\n\t\t\tvar stackCount = me.getStackCount();\n\t\t\tvar fullSize = scale.isHorizontal()? scale.width : scale.height;\n\t\t\tvar tickSize = fullSize / scale.ticks.length;\n\t\t\tvar categorySize = tickSize * options.categoryPercentage;\n\t\t\tvar fullBarSize = categorySize / stackCount;\n\t\t\tvar barSize = fullBarSize * options.barPercentage;\n\n\t\t\tbarSize = Math.min(\n\t\t\t\thelpers.getValueOrDefault(options.barThickness, barSize),\n\t\t\t\thelpers.getValueOrDefault(options.maxBarThickness, Infinity));\n\n\t\t\treturn {\n\t\t\t\tstackCount: stackCount,\n\t\t\t\ttickSize: tickSize,\n\t\t\t\tcategorySize: categorySize,\n\t\t\t\tcategorySpacing: tickSize - categorySize,\n\t\t\t\tfullBarSize: fullBarSize,\n\t\t\t\tbarSize: barSize,\n\t\t\t\tbarSpacing: fullBarSize - barSize,\n\t\t\t\tscale: scale\n\t\t\t};\n\t\t},\n\n\t\t/**\n\t\t * Note: pixel values are not clamped to the scale area.\n\t\t * @private\n\t\t */\n\t\tcalculateBarValuePixels: function(datasetIndex, index) {\n\t\t\tvar me = this;\n\t\t\tvar chart = me.chart;\n\t\t\tvar meta = me.getMeta();\n\t\t\tvar scale = me.getValueScale();\n\t\t\tvar datasets = chart.data.datasets;\n\t\t\tvar value = Number(datasets[datasetIndex].data[index]);\n\t\t\tvar stacked = scale.options.stacked;\n\t\t\tvar stack = meta.stack;\n\t\t\tvar start = 0;\n\t\t\tvar i, imeta, ivalue, base, head, size;\n\n\t\t\tif (stacked || (stacked === undefined && stack !== undefined)) {\n\t\t\t\tfor (i = 0; i < datasetIndex; ++i) {\n\t\t\t\t\timeta = chart.getDatasetMeta(i);\n\n\t\t\t\t\tif (imeta.bar &&\n\t\t\t\t\t\timeta.stack === stack &&\n\t\t\t\t\t\timeta.controller.getValueScaleId() === scale.id &&\n\t\t\t\t\t\tchart.isDatasetVisible(i)) {\n\n\t\t\t\t\t\tivalue = Number(datasets[i].data[index]);\n\t\t\t\t\t\tif ((value < 0 && ivalue < 0) || (value >= 0 && ivalue > 0)) {\n\t\t\t\t\t\t\tstart += ivalue;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tbase = scale.getPixelForValue(start);\n\t\t\thead = scale.getPixelForValue(start + value);\n\t\t\tsize = (head - base) / 2;\n\n\t\t\treturn {\n\t\t\t\tsize: size,\n\t\t\t\tbase: base,\n\t\t\t\thead: head,\n\t\t\t\tcenter: head + size / 2\n\t\t\t};\n\t\t},\n\n\t\t/**\n\t\t * @private\n\t\t */\n\t\tcalculateBarIndexPixels: function(datasetIndex, index, ruler) {\n\t\t\tvar me = this;\n\t\t\tvar scale = ruler.scale;\n\t\t\tvar isCombo = me.chart.isCombo;\n\t\t\tvar stackIndex = me.getStackIndex(datasetIndex);\n\t\t\tvar base = scale.getPixelForValue(null, index, datasetIndex, isCombo);\n\t\t\tvar size = ruler.barSize;\n\n\t\t\tbase -= isCombo? ruler.tickSize / 2 : 0;\n\t\t\tbase += ruler.fullBarSize * stackIndex;\n\t\t\tbase += ruler.categorySpacing / 2;\n\t\t\tbase += ruler.barSpacing / 2;\n\n\t\t\treturn {\n\t\t\t\tsize: size,\n\t\t\t\tbase: base,\n\t\t\t\thead: base + size,\n\t\t\t\tcenter: base + size / 2\n\t\t\t};\n\t\t},\n\n\t\tdraw: function() {\n\t\t\tvar me = this;\n\t\t\tvar chart = me.chart;\n\t\t\tvar elements = me.getMeta().data;\n\t\t\tvar dataset = me.getDataset();\n\t\t\tvar ilen = elements.length;\n\t\t\tvar i = 0;\n\t\t\tvar d;\n\n\t\t\thelpers.canvas.clipArea(chart.ctx, chart.chartArea);\n\n\t\t\tfor (; i<ilen; ++i) {\n\t\t\t\td = dataset.data[i];\n\t\t\t\tif (d !== null && d !== undefined && !isNaN(d)) {\n\t\t\t\t\telements[i].draw();\n\t\t\t\t}\n\t\t\t}\n\n\t\t\thelpers.canvas.unclipArea(chart.ctx);\n\t\t},\n\n\t\tsetHoverStyle: function(rectangle) {\n\t\t\tvar dataset = this.chart.data.datasets[rectangle._datasetIndex];\n\t\t\tvar index = rectangle._index;\n\t\t\tvar custom = rectangle.custom || {};\n\t\t\tvar model = rectangle._model;\n\n\t\t\tmodel.backgroundColor = custom.hoverBackgroundColor ? custom.hoverBackgroundColor : helpers.getValueAtIndexOrDefault(dataset.hoverBackgroundColor, index, helpers.getHoverColor(model.backgroundColor));\n\t\t\tmodel.borderColor = custom.hoverBorderColor ? custom.hoverBorderColor : helpers.getValueAtIndexOrDefault(dataset.hoverBorderColor, index, helpers.getHoverColor(model.borderColor));\n\t\t\tmodel.borderWidth = custom.hoverBorderWidth ? custom.hoverBorderWidth : helpers.getValueAtIndexOrDefault(dataset.hoverBorderWidth, index, model.borderWidth);\n\t\t},\n\n\t\tremoveHoverStyle: function(rectangle) {\n\t\t\tvar dataset = this.chart.data.datasets[rectangle._datasetIndex];\n\t\t\tvar index = rectangle._index;\n\t\t\tvar custom = rectangle.custom || {};\n\t\t\tvar model = rectangle._model;\n\t\t\tvar rectangleElementOptions = this.chart.options.elements.rectangle;\n\n\t\t\tmodel.backgroundColor = custom.backgroundColor ? custom.backgroundColor : helpers.getValueAtIndexOrDefault(dataset.backgroundColor, index, rectangleElementOptions.backgroundColor);\n\t\t\tmodel.borderColor = custom.borderColor ? custom.borderColor : helpers.getValueAtIndexOrDefault(dataset.borderColor, index, rectangleElementOptions.borderColor);\n\t\t\tmodel.borderWidth = custom.borderWidth ? custom.borderWidth : helpers.getValueAtIndexOrDefault(dataset.borderWidth, index, rectangleElementOptions.borderWidth);\n\t\t}\n\t});\n\n\n\t// including horizontalBar in the bar file, instead of a file of its own\n\t// it extends bar (like pie extends doughnut)\n\tChart.defaults.horizontalBar = {\n\t\thover: {\n\t\t\tmode: 'label'\n\t\t},\n\n\t\tscales: {\n\t\t\txAxes: [{\n\t\t\t\ttype: 'linear',\n\t\t\t\tposition: 'bottom'\n\t\t\t}],\n\t\t\tyAxes: [{\n\t\t\t\tposition: 'left',\n\t\t\t\ttype: 'category',\n\n\t\t\t\t// Specific to Horizontal Bar Controller\n\t\t\t\tcategoryPercentage: 0.8,\n\t\t\t\tbarPercentage: 0.9,\n\n\t\t\t\t// grid line settings\n\t\t\t\tgridLines: {\n\t\t\t\t\toffsetGridLines: true\n\t\t\t\t}\n\t\t\t}]\n\t\t},\n\t\telements: {\n\t\t\trectangle: {\n\t\t\t\tborderSkipped: 'left'\n\t\t\t}\n\t\t},\n\t\ttooltips: {\n\t\t\tcallbacks: {\n\t\t\t\ttitle: function(tooltipItems, data) {\n\t\t\t\t\t// Pick first xLabel for now\n\t\t\t\t\tvar title = '';\n\n\t\t\t\t\tif (tooltipItems.length > 0) {\n\t\t\t\t\t\tif (tooltipItems[0].yLabel) {\n\t\t\t\t\t\t\ttitle = tooltipItems[0].yLabel;\n\t\t\t\t\t\t} else if (data.labels.length > 0 && tooltipItems[0].index < data.labels.length) {\n\t\t\t\t\t\t\ttitle = data.labels[tooltipItems[0].index];\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\treturn title;\n\t\t\t\t},\n\t\t\t\tlabel: function(tooltipItem, data) {\n\t\t\t\t\tvar datasetLabel = data.datasets[tooltipItem.datasetIndex].label || '';\n\t\t\t\t\treturn datasetLabel + ': ' + tooltipItem.xLabel;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t};\n\n\tChart.controllers.horizontalBar = Chart.controllers.bar.extend({\n\t\t/**\n\t\t * @private\n\t\t */\n\t\tgetValueScaleId: function() {\n\t\t\treturn this.getMeta().xAxisID;\n\t\t},\n\n\t\t/**\n\t\t * @private\n\t\t */\n\t\tgetIndexScaleId: function() {\n\t\t\treturn this.getMeta().yAxisID;\n\t\t}\n\t});\n};\n"
  },
  {
    "path": "app_backend/static/plugin/Chart.js-2.6.0/src/controllers/controller.bubble.js",
    "content": "'use strict';\n\nmodule.exports = function(Chart) {\n\n\tvar helpers = Chart.helpers;\n\n\tChart.defaults.bubble = {\n\t\thover: {\n\t\t\tmode: 'single'\n\t\t},\n\n\t\tscales: {\n\t\t\txAxes: [{\n\t\t\t\ttype: 'linear', // bubble should probably use a linear scale by default\n\t\t\t\tposition: 'bottom',\n\t\t\t\tid: 'x-axis-0' // need an ID so datasets can reference the scale\n\t\t\t}],\n\t\t\tyAxes: [{\n\t\t\t\ttype: 'linear',\n\t\t\t\tposition: 'left',\n\t\t\t\tid: 'y-axis-0'\n\t\t\t}]\n\t\t},\n\n\t\ttooltips: {\n\t\t\tcallbacks: {\n\t\t\t\ttitle: function() {\n\t\t\t\t\t// Title doesn't make sense for scatter since we format the data as a point\n\t\t\t\t\treturn '';\n\t\t\t\t},\n\t\t\t\tlabel: function(tooltipItem, data) {\n\t\t\t\t\tvar datasetLabel = data.datasets[tooltipItem.datasetIndex].label || '';\n\t\t\t\t\tvar dataPoint = data.datasets[tooltipItem.datasetIndex].data[tooltipItem.index];\n\t\t\t\t\treturn datasetLabel + ': (' + tooltipItem.xLabel + ', ' + tooltipItem.yLabel + ', ' + dataPoint.r + ')';\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t};\n\n\tChart.controllers.bubble = Chart.DatasetController.extend({\n\n\t\tdataElementType: Chart.elements.Point,\n\n\t\tupdate: function(reset) {\n\t\t\tvar me = this;\n\t\t\tvar meta = me.getMeta();\n\t\t\tvar points = meta.data;\n\n\t\t\t// Update Points\n\t\t\thelpers.each(points, function(point, index) {\n\t\t\t\tme.updateElement(point, index, reset);\n\t\t\t});\n\t\t},\n\n\t\tupdateElement: function(point, index, reset) {\n\t\t\tvar me = this;\n\t\t\tvar meta = me.getMeta();\n\t\t\tvar xScale = me.getScaleForId(meta.xAxisID);\n\t\t\tvar yScale = me.getScaleForId(meta.yAxisID);\n\n\t\t\tvar custom = point.custom || {};\n\t\t\tvar dataset = me.getDataset();\n\t\t\tvar data = dataset.data[index];\n\t\t\tvar pointElementOptions = me.chart.options.elements.point;\n\t\t\tvar dsIndex = me.index;\n\n\t\t\thelpers.extend(point, {\n\t\t\t\t// Utility\n\t\t\t\t_xScale: xScale,\n\t\t\t\t_yScale: yScale,\n\t\t\t\t_datasetIndex: dsIndex,\n\t\t\t\t_index: index,\n\n\t\t\t\t// Desired view properties\n\t\t\t\t_model: {\n\t\t\t\t\tx: reset ? xScale.getPixelForDecimal(0.5) : xScale.getPixelForValue(typeof data === 'object' ? data : NaN, index, dsIndex, me.chart.isCombo),\n\t\t\t\t\ty: reset ? yScale.getBasePixel() : yScale.getPixelForValue(data, index, dsIndex),\n\t\t\t\t\t// Appearance\n\t\t\t\t\tradius: reset ? 0 : custom.radius ? custom.radius : me.getRadius(data),\n\n\t\t\t\t\t// Tooltip\n\t\t\t\t\thitRadius: custom.hitRadius ? custom.hitRadius : helpers.getValueAtIndexOrDefault(dataset.hitRadius, index, pointElementOptions.hitRadius)\n\t\t\t\t}\n\t\t\t});\n\n\t\t\t// Trick to reset the styles of the point\n\t\t\tChart.DatasetController.prototype.removeHoverStyle.call(me, point, pointElementOptions);\n\n\t\t\tvar model = point._model;\n\t\t\tmodel.skip = custom.skip ? custom.skip : (isNaN(model.x) || isNaN(model.y));\n\n\t\t\tpoint.pivot();\n\t\t},\n\n\t\tgetRadius: function(value) {\n\t\t\treturn value.r || this.chart.options.elements.point.radius;\n\t\t},\n\n\t\tsetHoverStyle: function(point) {\n\t\t\tvar me = this;\n\t\t\tChart.DatasetController.prototype.setHoverStyle.call(me, point);\n\n\t\t\t// Radius\n\t\t\tvar dataset = me.chart.data.datasets[point._datasetIndex];\n\t\t\tvar index = point._index;\n\t\t\tvar custom = point.custom || {};\n\t\t\tvar model = point._model;\n\t\t\tmodel.radius = custom.hoverRadius ? custom.hoverRadius : (helpers.getValueAtIndexOrDefault(dataset.hoverRadius, index, me.chart.options.elements.point.hoverRadius)) + me.getRadius(dataset.data[index]);\n\t\t},\n\n\t\tremoveHoverStyle: function(point) {\n\t\t\tvar me = this;\n\t\t\tChart.DatasetController.prototype.removeHoverStyle.call(me, point, me.chart.options.elements.point);\n\n\t\t\tvar dataVal = me.chart.data.datasets[point._datasetIndex].data[point._index];\n\t\t\tvar custom = point.custom || {};\n\t\t\tvar model = point._model;\n\n\t\t\tmodel.radius = custom.radius ? custom.radius : me.getRadius(dataVal);\n\t\t}\n\t});\n};\n"
  },
  {
    "path": "app_backend/static/plugin/Chart.js-2.6.0/src/controllers/controller.doughnut.js",
    "content": "'use strict';\n\nmodule.exports = function(Chart) {\n\n\tvar helpers = Chart.helpers,\n\t\tdefaults = Chart.defaults;\n\n\tdefaults.doughnut = {\n\t\tanimation: {\n\t\t\t// Boolean - Whether we animate the rotation of the Doughnut\n\t\t\tanimateRotate: true,\n\t\t\t// Boolean - Whether we animate scaling the Doughnut from the centre\n\t\t\tanimateScale: false\n\t\t},\n\t\taspectRatio: 1,\n\t\thover: {\n\t\t\tmode: 'single'\n\t\t},\n\t\tlegendCallback: function(chart) {\n\t\t\tvar text = [];\n\t\t\ttext.push('<ul class=\"' + chart.id + '-legend\">');\n\n\t\t\tvar data = chart.data;\n\t\t\tvar datasets = data.datasets;\n\t\t\tvar labels = data.labels;\n\n\t\t\tif (datasets.length) {\n\t\t\t\tfor (var i = 0; i < datasets[0].data.length; ++i) {\n\t\t\t\t\ttext.push('<li><span style=\"background-color:' + datasets[0].backgroundColor[i] + '\"></span>');\n\t\t\t\t\tif (labels[i]) {\n\t\t\t\t\t\ttext.push(labels[i]);\n\t\t\t\t\t}\n\t\t\t\t\ttext.push('</li>');\n\t\t\t\t}\n\t\t\t}\n\n\t\t\ttext.push('</ul>');\n\t\t\treturn text.join('');\n\t\t},\n\t\tlegend: {\n\t\t\tlabels: {\n\t\t\t\tgenerateLabels: function(chart) {\n\t\t\t\t\tvar data = chart.data;\n\t\t\t\t\tif (data.labels.length && data.datasets.length) {\n\t\t\t\t\t\treturn data.labels.map(function(label, i) {\n\t\t\t\t\t\t\tvar meta = chart.getDatasetMeta(0);\n\t\t\t\t\t\t\tvar ds = data.datasets[0];\n\t\t\t\t\t\t\tvar arc = meta.data[i];\n\t\t\t\t\t\t\tvar custom = arc && arc.custom || {};\n\t\t\t\t\t\t\tvar getValueAtIndexOrDefault = helpers.getValueAtIndexOrDefault;\n\t\t\t\t\t\t\tvar arcOpts = chart.options.elements.arc;\n\t\t\t\t\t\t\tvar fill = custom.backgroundColor ? custom.backgroundColor : getValueAtIndexOrDefault(ds.backgroundColor, i, arcOpts.backgroundColor);\n\t\t\t\t\t\t\tvar stroke = custom.borderColor ? custom.borderColor : getValueAtIndexOrDefault(ds.borderColor, i, arcOpts.borderColor);\n\t\t\t\t\t\t\tvar bw = custom.borderWidth ? custom.borderWidth : getValueAtIndexOrDefault(ds.borderWidth, i, arcOpts.borderWidth);\n\n\t\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\t\ttext: label,\n\t\t\t\t\t\t\t\tfillStyle: fill,\n\t\t\t\t\t\t\t\tstrokeStyle: stroke,\n\t\t\t\t\t\t\t\tlineWidth: bw,\n\t\t\t\t\t\t\t\thidden: isNaN(ds.data[i]) || meta.data[i].hidden,\n\n\t\t\t\t\t\t\t\t// Extra data used for toggling the correct item\n\t\t\t\t\t\t\t\tindex: i\n\t\t\t\t\t\t\t};\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t\treturn [];\n\t\t\t\t}\n\t\t\t},\n\n\t\t\tonClick: function(e, legendItem) {\n\t\t\t\tvar index = legendItem.index;\n\t\t\t\tvar chart = this.chart;\n\t\t\t\tvar i, ilen, meta;\n\n\t\t\t\tfor (i = 0, ilen = (chart.data.datasets || []).length; i < ilen; ++i) {\n\t\t\t\t\tmeta = chart.getDatasetMeta(i);\n\t\t\t\t\t// toggle visibility of index if exists\n\t\t\t\t\tif (meta.data[index]) {\n\t\t\t\t\t\tmeta.data[index].hidden = !meta.data[index].hidden;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tchart.update();\n\t\t\t}\n\t\t},\n\n\t\t// The percentage of the chart that we cut out of the middle.\n\t\tcutoutPercentage: 50,\n\n\t\t// The rotation of the chart, where the first data arc begins.\n\t\trotation: Math.PI * -0.5,\n\n\t\t// The total circumference of the chart.\n\t\tcircumference: Math.PI * 2.0,\n\n\t\t// Need to override these to give a nice default\n\t\ttooltips: {\n\t\t\tcallbacks: {\n\t\t\t\ttitle: function() {\n\t\t\t\t\treturn '';\n\t\t\t\t},\n\t\t\t\tlabel: function(tooltipItem, data) {\n\t\t\t\t\tvar dataLabel = data.labels[tooltipItem.index];\n\t\t\t\t\tvar value = ': ' + data.datasets[tooltipItem.datasetIndex].data[tooltipItem.index];\n\n\t\t\t\t\tif (helpers.isArray(dataLabel)) {\n\t\t\t\t\t\t// show value on first line of multiline label\n\t\t\t\t\t\t// need to clone because we are changing the value\n\t\t\t\t\t\tdataLabel = dataLabel.slice();\n\t\t\t\t\t\tdataLabel[0] += value;\n\t\t\t\t\t} else {\n\t\t\t\t\t\tdataLabel += value;\n\t\t\t\t\t}\n\n\t\t\t\t\treturn dataLabel;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t};\n\n\tdefaults.pie = helpers.clone(defaults.doughnut);\n\thelpers.extend(defaults.pie, {\n\t\tcutoutPercentage: 0\n\t});\n\n\n\tChart.controllers.doughnut = Chart.controllers.pie = Chart.DatasetController.extend({\n\n\t\tdataElementType: Chart.elements.Arc,\n\n\t\tlinkScales: helpers.noop,\n\n\t\t// Get index of the dataset in relation to the visible datasets. This allows determining the inner and outer radius correctly\n\t\tgetRingIndex: function(datasetIndex) {\n\t\t\tvar ringIndex = 0;\n\n\t\t\tfor (var j = 0; j < datasetIndex; ++j) {\n\t\t\t\tif (this.chart.isDatasetVisible(j)) {\n\t\t\t\t\t++ringIndex;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn ringIndex;\n\t\t},\n\n\t\tupdate: function(reset) {\n\t\t\tvar me = this;\n\t\t\tvar chart = me.chart,\n\t\t\t\tchartArea = chart.chartArea,\n\t\t\t\topts = chart.options,\n\t\t\t\tarcOpts = opts.elements.arc,\n\t\t\t\tavailableWidth = chartArea.right - chartArea.left - arcOpts.borderWidth,\n\t\t\t\tavailableHeight = chartArea.bottom - chartArea.top - arcOpts.borderWidth,\n\t\t\t\tminSize = Math.min(availableWidth, availableHeight),\n\t\t\t\toffset = {\n\t\t\t\t\tx: 0,\n\t\t\t\t\ty: 0\n\t\t\t\t},\n\t\t\t\tmeta = me.getMeta(),\n\t\t\t\tcutoutPercentage = opts.cutoutPercentage,\n\t\t\t\tcircumference = opts.circumference;\n\n\t\t\t// If the chart's circumference isn't a full circle, calculate minSize as a ratio of the width/height of the arc\n\t\t\tif (circumference < Math.PI * 2.0) {\n\t\t\t\tvar startAngle = opts.rotation % (Math.PI * 2.0);\n\t\t\t\tstartAngle += Math.PI * 2.0 * (startAngle >= Math.PI ? -1 : startAngle < -Math.PI ? 1 : 0);\n\t\t\t\tvar endAngle = startAngle + circumference;\n\t\t\t\tvar start = {x: Math.cos(startAngle), y: Math.sin(startAngle)};\n\t\t\t\tvar end = {x: Math.cos(endAngle), y: Math.sin(endAngle)};\n\t\t\t\tvar contains0 = (startAngle <= 0 && 0 <= endAngle) || (startAngle <= Math.PI * 2.0 && Math.PI * 2.0 <= endAngle);\n\t\t\t\tvar contains90 = (startAngle <= Math.PI * 0.5 && Math.PI * 0.5 <= endAngle) || (startAngle <= Math.PI * 2.5 && Math.PI * 2.5 <= endAngle);\n\t\t\t\tvar contains180 = (startAngle <= -Math.PI && -Math.PI <= endAngle) || (startAngle <= Math.PI && Math.PI <= endAngle);\n\t\t\t\tvar contains270 = (startAngle <= -Math.PI * 0.5 && -Math.PI * 0.5 <= endAngle) || (startAngle <= Math.PI * 1.5 && Math.PI * 1.5 <= endAngle);\n\t\t\t\tvar cutout = cutoutPercentage / 100.0;\n\t\t\t\tvar min = {x: contains180 ? -1 : Math.min(start.x * (start.x < 0 ? 1 : cutout), end.x * (end.x < 0 ? 1 : cutout)), y: contains270 ? -1 : Math.min(start.y * (start.y < 0 ? 1 : cutout), end.y * (end.y < 0 ? 1 : cutout))};\n\t\t\t\tvar max = {x: contains0 ? 1 : Math.max(start.x * (start.x > 0 ? 1 : cutout), end.x * (end.x > 0 ? 1 : cutout)), y: contains90 ? 1 : Math.max(start.y * (start.y > 0 ? 1 : cutout), end.y * (end.y > 0 ? 1 : cutout))};\n\t\t\t\tvar size = {width: (max.x - min.x) * 0.5, height: (max.y - min.y) * 0.5};\n\t\t\t\tminSize = Math.min(availableWidth / size.width, availableHeight / size.height);\n\t\t\t\toffset = {x: (max.x + min.x) * -0.5, y: (max.y + min.y) * -0.5};\n\t\t\t}\n\n\t\t\tchart.borderWidth = me.getMaxBorderWidth(meta.data);\n\t\t\tchart.outerRadius = Math.max((minSize - chart.borderWidth) / 2, 0);\n\t\t\tchart.innerRadius = Math.max(cutoutPercentage ? (chart.outerRadius / 100) * (cutoutPercentage) : 0, 0);\n\t\t\tchart.radiusLength = (chart.outerRadius - chart.innerRadius) / chart.getVisibleDatasetCount();\n\t\t\tchart.offsetX = offset.x * chart.outerRadius;\n\t\t\tchart.offsetY = offset.y * chart.outerRadius;\n\n\t\t\tmeta.total = me.calculateTotal();\n\n\t\t\tme.outerRadius = chart.outerRadius - (chart.radiusLength * me.getRingIndex(me.index));\n\t\t\tme.innerRadius = Math.max(me.outerRadius - chart.radiusLength, 0);\n\n\t\t\thelpers.each(meta.data, function(arc, index) {\n\t\t\t\tme.updateElement(arc, index, reset);\n\t\t\t});\n\t\t},\n\n\t\tupdateElement: function(arc, index, reset) {\n\t\t\tvar me = this;\n\t\t\tvar chart = me.chart,\n\t\t\t\tchartArea = chart.chartArea,\n\t\t\t\topts = chart.options,\n\t\t\t\tanimationOpts = opts.animation,\n\t\t\t\tcenterX = (chartArea.left + chartArea.right) / 2,\n\t\t\t\tcenterY = (chartArea.top + chartArea.bottom) / 2,\n\t\t\t\tstartAngle = opts.rotation, // non reset case handled later\n\t\t\t\tendAngle = opts.rotation, // non reset case handled later\n\t\t\t\tdataset = me.getDataset(),\n\t\t\t\tcircumference = reset && animationOpts.animateRotate ? 0 : arc.hidden ? 0 : me.calculateCircumference(dataset.data[index]) * (opts.circumference / (2.0 * Math.PI)),\n\t\t\t\tinnerRadius = reset && animationOpts.animateScale ? 0 : me.innerRadius,\n\t\t\t\touterRadius = reset && animationOpts.animateScale ? 0 : me.outerRadius,\n\t\t\t\tvalueAtIndexOrDefault = helpers.getValueAtIndexOrDefault;\n\n\t\t\thelpers.extend(arc, {\n\t\t\t\t// Utility\n\t\t\t\t_datasetIndex: me.index,\n\t\t\t\t_index: index,\n\n\t\t\t\t// Desired view properties\n\t\t\t\t_model: {\n\t\t\t\t\tx: centerX + chart.offsetX,\n\t\t\t\t\ty: centerY + chart.offsetY,\n\t\t\t\t\tstartAngle: startAngle,\n\t\t\t\t\tendAngle: endAngle,\n\t\t\t\t\tcircumference: circumference,\n\t\t\t\t\touterRadius: outerRadius,\n\t\t\t\t\tinnerRadius: innerRadius,\n\t\t\t\t\tlabel: valueAtIndexOrDefault(dataset.label, index, chart.data.labels[index])\n\t\t\t\t}\n\t\t\t});\n\n\t\t\tvar model = arc._model;\n\t\t\t// Resets the visual styles\n\t\t\tthis.removeHoverStyle(arc);\n\n\t\t\t// Set correct angles if not resetting\n\t\t\tif (!reset || !animationOpts.animateRotate) {\n\t\t\t\tif (index === 0) {\n\t\t\t\t\tmodel.startAngle = opts.rotation;\n\t\t\t\t} else {\n\t\t\t\t\tmodel.startAngle = me.getMeta().data[index - 1]._model.endAngle;\n\t\t\t\t}\n\n\t\t\t\tmodel.endAngle = model.startAngle + model.circumference;\n\t\t\t}\n\n\t\t\tarc.pivot();\n\t\t},\n\n\t\tremoveHoverStyle: function(arc) {\n\t\t\tChart.DatasetController.prototype.removeHoverStyle.call(this, arc, this.chart.options.elements.arc);\n\t\t},\n\n\t\tcalculateTotal: function() {\n\t\t\tvar dataset = this.getDataset();\n\t\t\tvar meta = this.getMeta();\n\t\t\tvar total = 0;\n\t\t\tvar value;\n\n\t\t\thelpers.each(meta.data, function(element, index) {\n\t\t\t\tvalue = dataset.data[index];\n\t\t\t\tif (!isNaN(value) && !element.hidden) {\n\t\t\t\t\ttotal += Math.abs(value);\n\t\t\t\t}\n\t\t\t});\n\n\t\t\t/* if (total === 0) {\n\t\t\t\ttotal = NaN;\n\t\t\t}*/\n\n\t\t\treturn total;\n\t\t},\n\n\t\tcalculateCircumference: function(value) {\n\t\t\tvar total = this.getMeta().total;\n\t\t\tif (total > 0 && !isNaN(value)) {\n\t\t\t\treturn (Math.PI * 2.0) * (value / total);\n\t\t\t}\n\t\t\treturn 0;\n\t\t},\n\n\t\t// gets the max border or hover width to properly scale pie charts\n\t\tgetMaxBorderWidth: function(elements) {\n\t\t\tvar max = 0,\n\t\t\t\tindex = this.index,\n\t\t\t\tlength = elements.length,\n\t\t\t\tborderWidth,\n\t\t\t\thoverWidth;\n\n\t\t\tfor (var i = 0; i < length; i++) {\n\t\t\t\tborderWidth = elements[i]._model ? elements[i]._model.borderWidth : 0;\n\t\t\t\thoverWidth = elements[i]._chart ? elements[i]._chart.config.data.datasets[index].hoverBorderWidth : 0;\n\n\t\t\t\tmax = borderWidth > max ? borderWidth : max;\n\t\t\t\tmax = hoverWidth > max ? hoverWidth : max;\n\t\t\t}\n\t\t\treturn max;\n\t\t}\n\t});\n};\n"
  },
  {
    "path": "app_backend/static/plugin/Chart.js-2.6.0/src/controllers/controller.line.js",
    "content": "'use strict';\n\nmodule.exports = function(Chart) {\n\n\tvar helpers = Chart.helpers;\n\n\tChart.defaults.line = {\n\t\tshowLines: true,\n\t\tspanGaps: false,\n\n\t\thover: {\n\t\t\tmode: 'label'\n\t\t},\n\n\t\tscales: {\n\t\t\txAxes: [{\n\t\t\t\ttype: 'category',\n\t\t\t\tid: 'x-axis-0'\n\t\t\t}],\n\t\t\tyAxes: [{\n\t\t\t\ttype: 'linear',\n\t\t\t\tid: 'y-axis-0'\n\t\t\t}]\n\t\t}\n\t};\n\n\tfunction lineEnabled(dataset, options) {\n\t\treturn helpers.getValueOrDefault(dataset.showLine, options.showLines);\n\t}\n\n\tChart.controllers.line = Chart.DatasetController.extend({\n\n\t\tdatasetElementType: Chart.elements.Line,\n\n\t\tdataElementType: Chart.elements.Point,\n\n\t\tupdate: function(reset) {\n\t\t\tvar me = this;\n\t\t\tvar meta = me.getMeta();\n\t\t\tvar line = meta.dataset;\n\t\t\tvar points = meta.data || [];\n\t\t\tvar options = me.chart.options;\n\t\t\tvar lineElementOptions = options.elements.line;\n\t\t\tvar scale = me.getScaleForId(meta.yAxisID);\n\t\t\tvar i, ilen, custom;\n\t\t\tvar dataset = me.getDataset();\n\t\t\tvar showLine = lineEnabled(dataset, options);\n\n\t\t\t// Update Line\n\t\t\tif (showLine) {\n\t\t\t\tcustom = line.custom || {};\n\n\t\t\t\t// Compatibility: If the properties are defined with only the old name, use those values\n\t\t\t\tif ((dataset.tension !== undefined) && (dataset.lineTension === undefined)) {\n\t\t\t\t\tdataset.lineTension = dataset.tension;\n\t\t\t\t}\n\n\t\t\t\t// Utility\n\t\t\t\tline._scale = scale;\n\t\t\t\tline._datasetIndex = me.index;\n\t\t\t\t// Data\n\t\t\t\tline._children = points;\n\t\t\t\t// Model\n\t\t\t\tline._model = {\n\t\t\t\t\t// Appearance\n\t\t\t\t\t// The default behavior of lines is to break at null values, according\n\t\t\t\t\t// to https://github.com/chartjs/Chart.js/issues/2435#issuecomment-216718158\n\t\t\t\t\t// This option gives lines the ability to span gaps\n\t\t\t\t\tspanGaps: dataset.spanGaps ? dataset.spanGaps : options.spanGaps,\n\t\t\t\t\ttension: custom.tension ? custom.tension : helpers.getValueOrDefault(dataset.lineTension, lineElementOptions.tension),\n\t\t\t\t\tbackgroundColor: custom.backgroundColor ? custom.backgroundColor : (dataset.backgroundColor || lineElementOptions.backgroundColor),\n\t\t\t\t\tborderWidth: custom.borderWidth ? custom.borderWidth : (dataset.borderWidth || lineElementOptions.borderWidth),\n\t\t\t\t\tborderColor: custom.borderColor ? custom.borderColor : (dataset.borderColor || lineElementOptions.borderColor),\n\t\t\t\t\tborderCapStyle: custom.borderCapStyle ? custom.borderCapStyle : (dataset.borderCapStyle || lineElementOptions.borderCapStyle),\n\t\t\t\t\tborderDash: custom.borderDash ? custom.borderDash : (dataset.borderDash || lineElementOptions.borderDash),\n\t\t\t\t\tborderDashOffset: custom.borderDashOffset ? custom.borderDashOffset : (dataset.borderDashOffset || lineElementOptions.borderDashOffset),\n\t\t\t\t\tborderJoinStyle: custom.borderJoinStyle ? custom.borderJoinStyle : (dataset.borderJoinStyle || lineElementOptions.borderJoinStyle),\n\t\t\t\t\tfill: custom.fill ? custom.fill : (dataset.fill !== undefined ? dataset.fill : lineElementOptions.fill),\n\t\t\t\t\tsteppedLine: custom.steppedLine ? custom.steppedLine : helpers.getValueOrDefault(dataset.steppedLine, lineElementOptions.stepped),\n\t\t\t\t\tcubicInterpolationMode: custom.cubicInterpolationMode ? custom.cubicInterpolationMode : helpers.getValueOrDefault(dataset.cubicInterpolationMode, lineElementOptions.cubicInterpolationMode),\n\t\t\t\t};\n\n\t\t\t\tline.pivot();\n\t\t\t}\n\n\t\t\t// Update Points\n\t\t\tfor (i=0, ilen=points.length; i<ilen; ++i) {\n\t\t\t\tme.updateElement(points[i], i, reset);\n\t\t\t}\n\n\t\t\tif (showLine && line._model.tension !== 0) {\n\t\t\t\tme.updateBezierControlPoints();\n\t\t\t}\n\n\t\t\t// Now pivot the point for animation\n\t\t\tfor (i=0, ilen=points.length; i<ilen; ++i) {\n\t\t\t\tpoints[i].pivot();\n\t\t\t}\n\t\t},\n\n\t\tgetPointBackgroundColor: function(point, index) {\n\t\t\tvar backgroundColor = this.chart.options.elements.point.backgroundColor;\n\t\t\tvar dataset = this.getDataset();\n\t\t\tvar custom = point.custom || {};\n\n\t\t\tif (custom.backgroundColor) {\n\t\t\t\tbackgroundColor = custom.backgroundColor;\n\t\t\t} else if (dataset.pointBackgroundColor) {\n\t\t\t\tbackgroundColor = helpers.getValueAtIndexOrDefault(dataset.pointBackgroundColor, index, backgroundColor);\n\t\t\t} else if (dataset.backgroundColor) {\n\t\t\t\tbackgroundColor = dataset.backgroundColor;\n\t\t\t}\n\n\t\t\treturn backgroundColor;\n\t\t},\n\n\t\tgetPointBorderColor: function(point, index) {\n\t\t\tvar borderColor = this.chart.options.elements.point.borderColor;\n\t\t\tvar dataset = this.getDataset();\n\t\t\tvar custom = point.custom || {};\n\n\t\t\tif (custom.borderColor) {\n\t\t\t\tborderColor = custom.borderColor;\n\t\t\t} else if (dataset.pointBorderColor) {\n\t\t\t\tborderColor = helpers.getValueAtIndexOrDefault(dataset.pointBorderColor, index, borderColor);\n\t\t\t} else if (dataset.borderColor) {\n\t\t\t\tborderColor = dataset.borderColor;\n\t\t\t}\n\n\t\t\treturn borderColor;\n\t\t},\n\n\t\tgetPointBorderWidth: function(point, index) {\n\t\t\tvar borderWidth = this.chart.options.elements.point.borderWidth;\n\t\t\tvar dataset = this.getDataset();\n\t\t\tvar custom = point.custom || {};\n\n\t\t\tif (!isNaN(custom.borderWidth)) {\n\t\t\t\tborderWidth = custom.borderWidth;\n\t\t\t} else if (!isNaN(dataset.pointBorderWidth)) {\n\t\t\t\tborderWidth = helpers.getValueAtIndexOrDefault(dataset.pointBorderWidth, index, borderWidth);\n\t\t\t} else if (!isNaN(dataset.borderWidth)) {\n\t\t\t\tborderWidth = dataset.borderWidth;\n\t\t\t}\n\n\t\t\treturn borderWidth;\n\t\t},\n\n\t\tupdateElement: function(point, index, reset) {\n\t\t\tvar me = this;\n\t\t\tvar meta = me.getMeta();\n\t\t\tvar custom = point.custom || {};\n\t\t\tvar dataset = me.getDataset();\n\t\t\tvar datasetIndex = me.index;\n\t\t\tvar value = dataset.data[index];\n\t\t\tvar yScale = me.getScaleForId(meta.yAxisID);\n\t\t\tvar xScale = me.getScaleForId(meta.xAxisID);\n\t\t\tvar pointOptions = me.chart.options.elements.point;\n\t\t\tvar x, y;\n\t\t\tvar labels = me.chart.data.labels || [];\n\t\t\tvar includeOffset = (labels.length === 1 || dataset.data.length === 1) || me.chart.isCombo;\n\n\t\t\t// Compatibility: If the properties are defined with only the old name, use those values\n\t\t\tif ((dataset.radius !== undefined) && (dataset.pointRadius === undefined)) {\n\t\t\t\tdataset.pointRadius = dataset.radius;\n\t\t\t}\n\t\t\tif ((dataset.hitRadius !== undefined) && (dataset.pointHitRadius === undefined)) {\n\t\t\t\tdataset.pointHitRadius = dataset.hitRadius;\n\t\t\t}\n\n\t\t\tx = xScale.getPixelForValue(typeof value === 'object' ? value : NaN, index, datasetIndex, includeOffset);\n\t\t\ty = reset ? yScale.getBasePixel() : me.calculatePointY(value, index, datasetIndex);\n\n\t\t\t// Utility\n\t\t\tpoint._xScale = xScale;\n\t\t\tpoint._yScale = yScale;\n\t\t\tpoint._datasetIndex = datasetIndex;\n\t\t\tpoint._index = index;\n\n\t\t\t// Desired view properties\n\t\t\tpoint._model = {\n\t\t\t\tx: x,\n\t\t\t\ty: y,\n\t\t\t\tskip: custom.skip || isNaN(x) || isNaN(y),\n\t\t\t\t// Appearance\n\t\t\t\tradius: custom.radius || helpers.getValueAtIndexOrDefault(dataset.pointRadius, index, pointOptions.radius),\n\t\t\t\tpointStyle: custom.pointStyle || helpers.getValueAtIndexOrDefault(dataset.pointStyle, index, pointOptions.pointStyle),\n\t\t\t\tbackgroundColor: me.getPointBackgroundColor(point, index),\n\t\t\t\tborderColor: me.getPointBorderColor(point, index),\n\t\t\t\tborderWidth: me.getPointBorderWidth(point, index),\n\t\t\t\ttension: meta.dataset._model ? meta.dataset._model.tension : 0,\n\t\t\t\tsteppedLine: meta.dataset._model ? meta.dataset._model.steppedLine : false,\n\t\t\t\t// Tooltip\n\t\t\t\thitRadius: custom.hitRadius || helpers.getValueAtIndexOrDefault(dataset.pointHitRadius, index, pointOptions.hitRadius)\n\t\t\t};\n\t\t},\n\n\t\tcalculatePointY: function(value, index, datasetIndex) {\n\t\t\tvar me = this;\n\t\t\tvar chart = me.chart;\n\t\t\tvar meta = me.getMeta();\n\t\t\tvar yScale = me.getScaleForId(meta.yAxisID);\n\t\t\tvar sumPos = 0;\n\t\t\tvar sumNeg = 0;\n\t\t\tvar i, ds, dsMeta;\n\n\t\t\tif (yScale.options.stacked) {\n\t\t\t\tfor (i = 0; i < datasetIndex; i++) {\n\t\t\t\t\tds = chart.data.datasets[i];\n\t\t\t\t\tdsMeta = chart.getDatasetMeta(i);\n\t\t\t\t\tif (dsMeta.type === 'line' && dsMeta.yAxisID === yScale.id && chart.isDatasetVisible(i)) {\n\t\t\t\t\t\tvar stackedRightValue = Number(yScale.getRightValue(ds.data[index]));\n\t\t\t\t\t\tif (stackedRightValue < 0) {\n\t\t\t\t\t\t\tsumNeg += stackedRightValue || 0;\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tsumPos += stackedRightValue || 0;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tvar rightValue = Number(yScale.getRightValue(value));\n\t\t\t\tif (rightValue < 0) {\n\t\t\t\t\treturn yScale.getPixelForValue(sumNeg + rightValue);\n\t\t\t\t}\n\t\t\t\treturn yScale.getPixelForValue(sumPos + rightValue);\n\t\t\t}\n\n\t\t\treturn yScale.getPixelForValue(value);\n\t\t},\n\n\t\tupdateBezierControlPoints: function() {\n\t\t\tvar me = this;\n\t\t\tvar meta = me.getMeta();\n\t\t\tvar area = me.chart.chartArea;\n\t\t\tvar points = (meta.data || []);\n\t\t\tvar i, ilen, point, model, controlPoints;\n\n\t\t\t// Only consider points that are drawn in case the spanGaps option is used\n\t\t\tif (meta.dataset._model.spanGaps) {\n\t\t\t\tpoints = points.filter(function(pt) {\n\t\t\t\t\treturn !pt._model.skip;\n\t\t\t\t});\n\t\t\t}\n\n\t\t\tfunction capControlPoint(pt, min, max) {\n\t\t\t\treturn Math.max(Math.min(pt, max), min);\n\t\t\t}\n\n\t\t\tif (meta.dataset._model.cubicInterpolationMode === 'monotone') {\n\t\t\t\thelpers.splineCurveMonotone(points);\n\t\t\t} else {\n\t\t\t\tfor (i = 0, ilen = points.length; i < ilen; ++i) {\n\t\t\t\t\tpoint = points[i];\n\t\t\t\t\tmodel = point._model;\n\t\t\t\t\tcontrolPoints = helpers.splineCurve(\n\t\t\t\t\t\thelpers.previousItem(points, i)._model,\n\t\t\t\t\t\tmodel,\n\t\t\t\t\t\thelpers.nextItem(points, i)._model,\n\t\t\t\t\t\tmeta.dataset._model.tension\n\t\t\t\t\t);\n\t\t\t\t\tmodel.controlPointPreviousX = controlPoints.previous.x;\n\t\t\t\t\tmodel.controlPointPreviousY = controlPoints.previous.y;\n\t\t\t\t\tmodel.controlPointNextX = controlPoints.next.x;\n\t\t\t\t\tmodel.controlPointNextY = controlPoints.next.y;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (me.chart.options.elements.line.capBezierPoints) {\n\t\t\t\tfor (i = 0, ilen = points.length; i < ilen; ++i) {\n\t\t\t\t\tmodel = points[i]._model;\n\t\t\t\t\tmodel.controlPointPreviousX = capControlPoint(model.controlPointPreviousX, area.left, area.right);\n\t\t\t\t\tmodel.controlPointPreviousY = capControlPoint(model.controlPointPreviousY, area.top, area.bottom);\n\t\t\t\t\tmodel.controlPointNextX = capControlPoint(model.controlPointNextX, area.left, area.right);\n\t\t\t\t\tmodel.controlPointNextY = capControlPoint(model.controlPointNextY, area.top, area.bottom);\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\n\t\tdraw: function() {\n\t\t\tvar me = this;\n\t\t\tvar chart = me.chart;\n\t\t\tvar meta = me.getMeta();\n\t\t\tvar points = meta.data || [];\n\t\t\tvar area = chart.chartArea;\n\t\t\tvar ilen = points.length;\n\t\t\tvar i = 0;\n\n\t\t\tChart.canvasHelpers.clipArea(chart.ctx, area);\n\n\t\t\tif (lineEnabled(me.getDataset(), chart.options)) {\n\t\t\t\tmeta.dataset.draw();\n\t\t\t}\n\n\t\t\tChart.canvasHelpers.unclipArea(chart.ctx);\n\n\t\t\t// Draw the points\n\t\t\tfor (; i<ilen; ++i) {\n\t\t\t\tpoints[i].draw(area);\n\t\t\t}\n\t\t},\n\n\t\tsetHoverStyle: function(point) {\n\t\t\t// Point\n\t\t\tvar dataset = this.chart.data.datasets[point._datasetIndex];\n\t\t\tvar index = point._index;\n\t\t\tvar custom = point.custom || {};\n\t\t\tvar model = point._model;\n\n\t\t\tmodel.radius = custom.hoverRadius || helpers.getValueAtIndexOrDefault(dataset.pointHoverRadius, index, this.chart.options.elements.point.hoverRadius);\n\t\t\tmodel.backgroundColor = custom.hoverBackgroundColor || helpers.getValueAtIndexOrDefault(dataset.pointHoverBackgroundColor, index, helpers.getHoverColor(model.backgroundColor));\n\t\t\tmodel.borderColor = custom.hoverBorderColor || helpers.getValueAtIndexOrDefault(dataset.pointHoverBorderColor, index, helpers.getHoverColor(model.borderColor));\n\t\t\tmodel.borderWidth = custom.hoverBorderWidth || helpers.getValueAtIndexOrDefault(dataset.pointHoverBorderWidth, index, model.borderWidth);\n\t\t},\n\n\t\tremoveHoverStyle: function(point) {\n\t\t\tvar me = this;\n\t\t\tvar dataset = me.chart.data.datasets[point._datasetIndex];\n\t\t\tvar index = point._index;\n\t\t\tvar custom = point.custom || {};\n\t\t\tvar model = point._model;\n\n\t\t\t// Compatibility: If the properties are defined with only the old name, use those values\n\t\t\tif ((dataset.radius !== undefined) && (dataset.pointRadius === undefined)) {\n\t\t\t\tdataset.pointRadius = dataset.radius;\n\t\t\t}\n\n\t\t\tmodel.radius = custom.radius || helpers.getValueAtIndexOrDefault(dataset.pointRadius, index, me.chart.options.elements.point.radius);\n\t\t\tmodel.backgroundColor = me.getPointBackgroundColor(point, index);\n\t\t\tmodel.borderColor = me.getPointBorderColor(point, index);\n\t\t\tmodel.borderWidth = me.getPointBorderWidth(point, index);\n\t\t}\n\t});\n};\n"
  },
  {
    "path": "app_backend/static/plugin/Chart.js-2.6.0/src/controllers/controller.polarArea.js",
    "content": "'use strict';\n\nmodule.exports = function(Chart) {\n\n\tvar helpers = Chart.helpers;\n\n\tChart.defaults.polarArea = {\n\n\t\tscale: {\n\t\t\ttype: 'radialLinear',\n\t\t\tangleLines: {\n\t\t\t\tdisplay: false\n\t\t\t},\n\t\t\tgridLines: {\n\t\t\t\tcircular: true\n\t\t\t},\n\t\t\tpointLabels: {\n\t\t\t\tdisplay: false\n\t\t\t},\n\t\t\tticks: {\n\t\t\t\tbeginAtZero: true\n\t\t\t}\n\t\t},\n\n\t\t// Boolean - Whether to animate the rotation of the chart\n\t\tanimation: {\n\t\t\tanimateRotate: true,\n\t\t\tanimateScale: true\n\t\t},\n\n\t\tstartAngle: -0.5 * Math.PI,\n\t\taspectRatio: 1,\n\t\tlegendCallback: function(chart) {\n\t\t\tvar text = [];\n\t\t\ttext.push('<ul class=\"' + chart.id + '-legend\">');\n\n\t\t\tvar data = chart.data;\n\t\t\tvar datasets = data.datasets;\n\t\t\tvar labels = data.labels;\n\n\t\t\tif (datasets.length) {\n\t\t\t\tfor (var i = 0; i < datasets[0].data.length; ++i) {\n\t\t\t\t\ttext.push('<li><span style=\"background-color:' + datasets[0].backgroundColor[i] + '\"></span>');\n\t\t\t\t\tif (labels[i]) {\n\t\t\t\t\t\ttext.push(labels[i]);\n\t\t\t\t\t}\n\t\t\t\t\ttext.push('</li>');\n\t\t\t\t}\n\t\t\t}\n\n\t\t\ttext.push('</ul>');\n\t\t\treturn text.join('');\n\t\t},\n\t\tlegend: {\n\t\t\tlabels: {\n\t\t\t\tgenerateLabels: function(chart) {\n\t\t\t\t\tvar data = chart.data;\n\t\t\t\t\tif (data.labels.length && data.datasets.length) {\n\t\t\t\t\t\treturn data.labels.map(function(label, i) {\n\t\t\t\t\t\t\tvar meta = chart.getDatasetMeta(0);\n\t\t\t\t\t\t\tvar ds = data.datasets[0];\n\t\t\t\t\t\t\tvar arc = meta.data[i];\n\t\t\t\t\t\t\tvar custom = arc.custom || {};\n\t\t\t\t\t\t\tvar getValueAtIndexOrDefault = helpers.getValueAtIndexOrDefault;\n\t\t\t\t\t\t\tvar arcOpts = chart.options.elements.arc;\n\t\t\t\t\t\t\tvar fill = custom.backgroundColor ? custom.backgroundColor : getValueAtIndexOrDefault(ds.backgroundColor, i, arcOpts.backgroundColor);\n\t\t\t\t\t\t\tvar stroke = custom.borderColor ? custom.borderColor : getValueAtIndexOrDefault(ds.borderColor, i, arcOpts.borderColor);\n\t\t\t\t\t\t\tvar bw = custom.borderWidth ? custom.borderWidth : getValueAtIndexOrDefault(ds.borderWidth, i, arcOpts.borderWidth);\n\n\t\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\t\ttext: label,\n\t\t\t\t\t\t\t\tfillStyle: fill,\n\t\t\t\t\t\t\t\tstrokeStyle: stroke,\n\t\t\t\t\t\t\t\tlineWidth: bw,\n\t\t\t\t\t\t\t\thidden: isNaN(ds.data[i]) || meta.data[i].hidden,\n\n\t\t\t\t\t\t\t\t// Extra data used for toggling the correct item\n\t\t\t\t\t\t\t\tindex: i\n\t\t\t\t\t\t\t};\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t\treturn [];\n\t\t\t\t}\n\t\t\t},\n\n\t\t\tonClick: function(e, legendItem) {\n\t\t\t\tvar index = legendItem.index;\n\t\t\t\tvar chart = this.chart;\n\t\t\t\tvar i, ilen, meta;\n\n\t\t\t\tfor (i = 0, ilen = (chart.data.datasets || []).length; i < ilen; ++i) {\n\t\t\t\t\tmeta = chart.getDatasetMeta(i);\n\t\t\t\t\tmeta.data[index].hidden = !meta.data[index].hidden;\n\t\t\t\t}\n\n\t\t\t\tchart.update();\n\t\t\t}\n\t\t},\n\n\t\t// Need to override these to give a nice default\n\t\ttooltips: {\n\t\t\tcallbacks: {\n\t\t\t\ttitle: function() {\n\t\t\t\t\treturn '';\n\t\t\t\t},\n\t\t\t\tlabel: function(tooltipItem, data) {\n\t\t\t\t\treturn data.labels[tooltipItem.index] + ': ' + tooltipItem.yLabel;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t};\n\n\tChart.controllers.polarArea = Chart.DatasetController.extend({\n\n\t\tdataElementType: Chart.elements.Arc,\n\n\t\tlinkScales: helpers.noop,\n\n\t\tupdate: function(reset) {\n\t\t\tvar me = this;\n\t\t\tvar chart = me.chart;\n\t\t\tvar chartArea = chart.chartArea;\n\t\t\tvar meta = me.getMeta();\n\t\t\tvar opts = chart.options;\n\t\t\tvar arcOpts = opts.elements.arc;\n\t\t\tvar minSize = Math.min(chartArea.right - chartArea.left, chartArea.bottom - chartArea.top);\n\t\t\tchart.outerRadius = Math.max((minSize - arcOpts.borderWidth / 2) / 2, 0);\n\t\t\tchart.innerRadius = Math.max(opts.cutoutPercentage ? (chart.outerRadius / 100) * (opts.cutoutPercentage) : 1, 0);\n\t\t\tchart.radiusLength = (chart.outerRadius - chart.innerRadius) / chart.getVisibleDatasetCount();\n\n\t\t\tme.outerRadius = chart.outerRadius - (chart.radiusLength * me.index);\n\t\t\tme.innerRadius = me.outerRadius - chart.radiusLength;\n\n\t\t\tmeta.count = me.countVisibleElements();\n\n\t\t\thelpers.each(meta.data, function(arc, index) {\n\t\t\t\tme.updateElement(arc, index, reset);\n\t\t\t});\n\t\t},\n\n\t\tupdateElement: function(arc, index, reset) {\n\t\t\tvar me = this;\n\t\t\tvar chart = me.chart;\n\t\t\tvar dataset = me.getDataset();\n\t\t\tvar opts = chart.options;\n\t\t\tvar animationOpts = opts.animation;\n\t\t\tvar scale = chart.scale;\n\t\t\tvar getValueAtIndexOrDefault = helpers.getValueAtIndexOrDefault;\n\t\t\tvar labels = chart.data.labels;\n\n\t\t\tvar circumference = me.calculateCircumference(dataset.data[index]);\n\t\t\tvar centerX = scale.xCenter;\n\t\t\tvar centerY = scale.yCenter;\n\n\t\t\t// If there is NaN data before us, we need to calculate the starting angle correctly.\n\t\t\t// We could be way more efficient here, but its unlikely that the polar area chart will have a lot of data\n\t\t\tvar visibleCount = 0;\n\t\t\tvar meta = me.getMeta();\n\t\t\tfor (var i = 0; i < index; ++i) {\n\t\t\t\tif (!isNaN(dataset.data[i]) && !meta.data[i].hidden) {\n\t\t\t\t\t++visibleCount;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// var negHalfPI = -0.5 * Math.PI;\n\t\t\tvar datasetStartAngle = opts.startAngle;\n\t\t\tvar distance = arc.hidden ? 0 : scale.getDistanceFromCenterForValue(dataset.data[index]);\n\t\t\tvar startAngle = datasetStartAngle + (circumference * visibleCount);\n\t\t\tvar endAngle = startAngle + (arc.hidden ? 0 : circumference);\n\n\t\t\tvar resetRadius = animationOpts.animateScale ? 0 : scale.getDistanceFromCenterForValue(dataset.data[index]);\n\n\t\t\thelpers.extend(arc, {\n\t\t\t\t// Utility\n\t\t\t\t_datasetIndex: me.index,\n\t\t\t\t_index: index,\n\t\t\t\t_scale: scale,\n\n\t\t\t\t// Desired view properties\n\t\t\t\t_model: {\n\t\t\t\t\tx: centerX,\n\t\t\t\t\ty: centerY,\n\t\t\t\t\tinnerRadius: 0,\n\t\t\t\t\touterRadius: reset ? resetRadius : distance,\n\t\t\t\t\tstartAngle: reset && animationOpts.animateRotate ? datasetStartAngle : startAngle,\n\t\t\t\t\tendAngle: reset && animationOpts.animateRotate ? datasetStartAngle : endAngle,\n\t\t\t\t\tlabel: getValueAtIndexOrDefault(labels, index, labels[index])\n\t\t\t\t}\n\t\t\t});\n\n\t\t\t// Apply border and fill style\n\t\t\tme.removeHoverStyle(arc);\n\n\t\t\tarc.pivot();\n\t\t},\n\n\t\tremoveHoverStyle: function(arc) {\n\t\t\tChart.DatasetController.prototype.removeHoverStyle.call(this, arc, this.chart.options.elements.arc);\n\t\t},\n\n\t\tcountVisibleElements: function() {\n\t\t\tvar dataset = this.getDataset();\n\t\t\tvar meta = this.getMeta();\n\t\t\tvar count = 0;\n\n\t\t\thelpers.each(meta.data, function(element, index) {\n\t\t\t\tif (!isNaN(dataset.data[index]) && !element.hidden) {\n\t\t\t\t\tcount++;\n\t\t\t\t}\n\t\t\t});\n\n\t\t\treturn count;\n\t\t},\n\n\t\tcalculateCircumference: function(value) {\n\t\t\tvar count = this.getMeta().count;\n\t\t\tif (count > 0 && !isNaN(value)) {\n\t\t\t\treturn (2 * Math.PI) / count;\n\t\t\t}\n\t\t\treturn 0;\n\t\t}\n\t});\n};\n"
  },
  {
    "path": "app_backend/static/plugin/Chart.js-2.6.0/src/controllers/controller.radar.js",
    "content": "'use strict';\n\nmodule.exports = function(Chart) {\n\n\tvar helpers = Chart.helpers;\n\n\tChart.defaults.radar = {\n\t\taspectRatio: 1,\n\t\tscale: {\n\t\t\ttype: 'radialLinear'\n\t\t},\n\t\telements: {\n\t\t\tline: {\n\t\t\t\ttension: 0 // no bezier in radar\n\t\t\t}\n\t\t}\n\t};\n\n\tChart.controllers.radar = Chart.DatasetController.extend({\n\n\t\tdatasetElementType: Chart.elements.Line,\n\n\t\tdataElementType: Chart.elements.Point,\n\n\t\tlinkScales: helpers.noop,\n\n\t\tupdate: function(reset) {\n\t\t\tvar me = this;\n\t\t\tvar meta = me.getMeta();\n\t\t\tvar line = meta.dataset;\n\t\t\tvar points = meta.data;\n\t\t\tvar custom = line.custom || {};\n\t\t\tvar dataset = me.getDataset();\n\t\t\tvar lineElementOptions = me.chart.options.elements.line;\n\t\t\tvar scale = me.chart.scale;\n\n\t\t\t// Compatibility: If the properties are defined with only the old name, use those values\n\t\t\tif ((dataset.tension !== undefined) && (dataset.lineTension === undefined)) {\n\t\t\t\tdataset.lineTension = dataset.tension;\n\t\t\t}\n\n\t\t\thelpers.extend(meta.dataset, {\n\t\t\t\t// Utility\n\t\t\t\t_datasetIndex: me.index,\n\t\t\t\t_scale: scale,\n\t\t\t\t// Data\n\t\t\t\t_children: points,\n\t\t\t\t_loop: true,\n\t\t\t\t// Model\n\t\t\t\t_model: {\n\t\t\t\t\t// Appearance\n\t\t\t\t\ttension: custom.tension ? custom.tension : helpers.getValueOrDefault(dataset.lineTension, lineElementOptions.tension),\n\t\t\t\t\tbackgroundColor: custom.backgroundColor ? custom.backgroundColor : (dataset.backgroundColor || lineElementOptions.backgroundColor),\n\t\t\t\t\tborderWidth: custom.borderWidth ? custom.borderWidth : (dataset.borderWidth || lineElementOptions.borderWidth),\n\t\t\t\t\tborderColor: custom.borderColor ? custom.borderColor : (dataset.borderColor || lineElementOptions.borderColor),\n\t\t\t\t\tfill: custom.fill ? custom.fill : (dataset.fill !== undefined ? dataset.fill : lineElementOptions.fill),\n\t\t\t\t\tborderCapStyle: custom.borderCapStyle ? custom.borderCapStyle : (dataset.borderCapStyle || lineElementOptions.borderCapStyle),\n\t\t\t\t\tborderDash: custom.borderDash ? custom.borderDash : (dataset.borderDash || lineElementOptions.borderDash),\n\t\t\t\t\tborderDashOffset: custom.borderDashOffset ? custom.borderDashOffset : (dataset.borderDashOffset || lineElementOptions.borderDashOffset),\n\t\t\t\t\tborderJoinStyle: custom.borderJoinStyle ? custom.borderJoinStyle : (dataset.borderJoinStyle || lineElementOptions.borderJoinStyle),\n\t\t\t\t}\n\t\t\t});\n\n\t\t\tmeta.dataset.pivot();\n\n\t\t\t// Update Points\n\t\t\thelpers.each(points, function(point, index) {\n\t\t\t\tme.updateElement(point, index, reset);\n\t\t\t}, me);\n\n\t\t\t// Update bezier control points\n\t\t\tme.updateBezierControlPoints();\n\t\t},\n\t\tupdateElement: function(point, index, reset) {\n\t\t\tvar me = this;\n\t\t\tvar custom = point.custom || {};\n\t\t\tvar dataset = me.getDataset();\n\t\t\tvar scale = me.chart.scale;\n\t\t\tvar pointElementOptions = me.chart.options.elements.point;\n\t\t\tvar pointPosition = scale.getPointPositionForValue(index, dataset.data[index]);\n\n\t\t\t// Compatibility: If the properties are defined with only the old name, use those values\n\t\t\tif ((dataset.radius !== undefined) && (dataset.pointRadius === undefined)) {\n\t\t\t\tdataset.pointRadius = dataset.radius;\n\t\t\t}\n\t\t\tif ((dataset.hitRadius !== undefined) && (dataset.pointHitRadius === undefined)) {\n\t\t\t\tdataset.pointHitRadius = dataset.hitRadius;\n\t\t\t}\n\n\t\t\thelpers.extend(point, {\n\t\t\t\t// Utility\n\t\t\t\t_datasetIndex: me.index,\n\t\t\t\t_index: index,\n\t\t\t\t_scale: scale,\n\n\t\t\t\t// Desired view properties\n\t\t\t\t_model: {\n\t\t\t\t\tx: reset ? scale.xCenter : pointPosition.x, // value not used in dataset scale, but we want a consistent API between scales\n\t\t\t\t\ty: reset ? scale.yCenter : pointPosition.y,\n\n\t\t\t\t\t// Appearance\n\t\t\t\t\ttension: custom.tension ? custom.tension : helpers.getValueOrDefault(dataset.lineTension, me.chart.options.elements.line.tension),\n\t\t\t\t\tradius: custom.radius ? custom.radius : helpers.getValueAtIndexOrDefault(dataset.pointRadius, index, pointElementOptions.radius),\n\t\t\t\t\tbackgroundColor: custom.backgroundColor ? custom.backgroundColor : helpers.getValueAtIndexOrDefault(dataset.pointBackgroundColor, index, pointElementOptions.backgroundColor),\n\t\t\t\t\tborderColor: custom.borderColor ? custom.borderColor : helpers.getValueAtIndexOrDefault(dataset.pointBorderColor, index, pointElementOptions.borderColor),\n\t\t\t\t\tborderWidth: custom.borderWidth ? custom.borderWidth : helpers.getValueAtIndexOrDefault(dataset.pointBorderWidth, index, pointElementOptions.borderWidth),\n\t\t\t\t\tpointStyle: custom.pointStyle ? custom.pointStyle : helpers.getValueAtIndexOrDefault(dataset.pointStyle, index, pointElementOptions.pointStyle),\n\n\t\t\t\t\t// Tooltip\n\t\t\t\t\thitRadius: custom.hitRadius ? custom.hitRadius : helpers.getValueAtIndexOrDefault(dataset.pointHitRadius, index, pointElementOptions.hitRadius)\n\t\t\t\t}\n\t\t\t});\n\n\t\t\tpoint._model.skip = custom.skip ? custom.skip : (isNaN(point._model.x) || isNaN(point._model.y));\n\t\t},\n\t\tupdateBezierControlPoints: function() {\n\t\t\tvar chartArea = this.chart.chartArea;\n\t\t\tvar meta = this.getMeta();\n\n\t\t\thelpers.each(meta.data, function(point, index) {\n\t\t\t\tvar model = point._model;\n\t\t\t\tvar controlPoints = helpers.splineCurve(\n\t\t\t\t\thelpers.previousItem(meta.data, index, true)._model,\n\t\t\t\t\tmodel,\n\t\t\t\t\thelpers.nextItem(meta.data, index, true)._model,\n\t\t\t\t\tmodel.tension\n\t\t\t\t);\n\n\t\t\t\t// Prevent the bezier going outside of the bounds of the graph\n\t\t\t\tmodel.controlPointPreviousX = Math.max(Math.min(controlPoints.previous.x, chartArea.right), chartArea.left);\n\t\t\t\tmodel.controlPointPreviousY = Math.max(Math.min(controlPoints.previous.y, chartArea.bottom), chartArea.top);\n\n\t\t\t\tmodel.controlPointNextX = Math.max(Math.min(controlPoints.next.x, chartArea.right), chartArea.left);\n\t\t\t\tmodel.controlPointNextY = Math.max(Math.min(controlPoints.next.y, chartArea.bottom), chartArea.top);\n\n\t\t\t\t// Now pivot the point for animation\n\t\t\t\tpoint.pivot();\n\t\t\t});\n\t\t},\n\n\t\tsetHoverStyle: function(point) {\n\t\t\t// Point\n\t\t\tvar dataset = this.chart.data.datasets[point._datasetIndex];\n\t\t\tvar custom = point.custom || {};\n\t\t\tvar index = point._index;\n\t\t\tvar model = point._model;\n\n\t\t\tmodel.radius = custom.hoverRadius ? custom.hoverRadius : helpers.getValueAtIndexOrDefault(dataset.pointHoverRadius, index, this.chart.options.elements.point.hoverRadius);\n\t\t\tmodel.backgroundColor = custom.hoverBackgroundColor ? custom.hoverBackgroundColor : helpers.getValueAtIndexOrDefault(dataset.pointHoverBackgroundColor, index, helpers.getHoverColor(model.backgroundColor));\n\t\t\tmodel.borderColor = custom.hoverBorderColor ? custom.hoverBorderColor : helpers.getValueAtIndexOrDefault(dataset.pointHoverBorderColor, index, helpers.getHoverColor(model.borderColor));\n\t\t\tmodel.borderWidth = custom.hoverBorderWidth ? custom.hoverBorderWidth : helpers.getValueAtIndexOrDefault(dataset.pointHoverBorderWidth, index, model.borderWidth);\n\t\t},\n\n\t\tremoveHoverStyle: function(point) {\n\t\t\tvar dataset = this.chart.data.datasets[point._datasetIndex];\n\t\t\tvar custom = point.custom || {};\n\t\t\tvar index = point._index;\n\t\t\tvar model = point._model;\n\t\t\tvar pointElementOptions = this.chart.options.elements.point;\n\n\t\t\tmodel.radius = custom.radius ? custom.radius : helpers.getValueAtIndexOrDefault(dataset.pointRadius, index, pointElementOptions.radius);\n\t\t\tmodel.backgroundColor = custom.backgroundColor ? custom.backgroundColor : helpers.getValueAtIndexOrDefault(dataset.pointBackgroundColor, index, pointElementOptions.backgroundColor);\n\t\t\tmodel.borderColor = custom.borderColor ? custom.borderColor : helpers.getValueAtIndexOrDefault(dataset.pointBorderColor, index, pointElementOptions.borderColor);\n\t\t\tmodel.borderWidth = custom.borderWidth ? custom.borderWidth : helpers.getValueAtIndexOrDefault(dataset.pointBorderWidth, index, pointElementOptions.borderWidth);\n\t\t}\n\t});\n};\n"
  },
  {
    "path": "app_backend/static/plugin/Chart.js-2.6.0/src/core/core.animation.js",
    "content": "/* global window: false */\n'use strict';\n\nmodule.exports = function(Chart) {\n\n\tvar helpers = Chart.helpers;\n\n\tChart.defaults.global.animation = {\n\t\tduration: 1000,\n\t\teasing: 'easeOutQuart',\n\t\tonProgress: helpers.noop,\n\t\tonComplete: helpers.noop\n\t};\n\n\tChart.Animation = Chart.Element.extend({\n\t\tchart: null, // the animation associated chart instance\n\t\tcurrentStep: 0, // the current animation step\n\t\tnumSteps: 60, // default number of steps\n\t\teasing: '', // the easing to use for this animation\n\t\trender: null, // render function used by the animation service\n\n\t\tonAnimationProgress: null, // user specified callback to fire on each step of the animation\n\t\tonAnimationComplete: null, // user specified callback to fire when the animation finishes\n\t});\n\n\tChart.animationService = {\n\t\tframeDuration: 17,\n\t\tanimations: [],\n\t\tdropFrames: 0,\n\t\trequest: null,\n\n\t\t/**\n\t\t * @param {Chart} chart - The chart to animate.\n\t\t * @param {Chart.Animation} animation - The animation that we will animate.\n\t\t * @param {Number} duration - The animation duration in ms.\n\t\t * @param {Boolean} lazy - if true, the chart is not marked as animating to enable more responsive interactions\n\t\t */\n\t\taddAnimation: function(chart, animation, duration, lazy) {\n\t\t\tvar animations = this.animations;\n\t\t\tvar i, ilen;\n\n\t\t\tanimation.chart = chart;\n\n\t\t\tif (!lazy) {\n\t\t\t\tchart.animating = true;\n\t\t\t}\n\n\t\t\tfor (i=0, ilen=animations.length; i < ilen; ++i) {\n\t\t\t\tif (animations[i].chart === chart) {\n\t\t\t\t\tanimations[i] = animation;\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tanimations.push(animation);\n\n\t\t\t// If there are no animations queued, manually kickstart a digest, for lack of a better word\n\t\t\tif (animations.length === 1) {\n\t\t\t\tthis.requestAnimationFrame();\n\t\t\t}\n\t\t},\n\n\t\tcancelAnimation: function(chart) {\n\t\t\tvar index = helpers.findIndex(this.animations, function(animation) {\n\t\t\t\treturn animation.chart === chart;\n\t\t\t});\n\n\t\t\tif (index !== -1) {\n\t\t\t\tthis.animations.splice(index, 1);\n\t\t\t\tchart.animating = false;\n\t\t\t}\n\t\t},\n\n\t\trequestAnimationFrame: function() {\n\t\t\tvar me = this;\n\t\t\tif (me.request === null) {\n\t\t\t\t// Skip animation frame requests until the active one is executed.\n\t\t\t\t// This can happen when processing mouse events, e.g. 'mousemove'\n\t\t\t\t// and 'mouseout' events will trigger multiple renders.\n\t\t\t\tme.request = helpers.requestAnimFrame.call(window, function() {\n\t\t\t\t\tme.request = null;\n\t\t\t\t\tme.startDigest();\n\t\t\t\t});\n\t\t\t}\n\t\t},\n\n\t\t/**\n\t\t * @private\n\t\t */\n\t\tstartDigest: function() {\n\t\t\tvar me = this;\n\t\t\tvar startTime = Date.now();\n\t\t\tvar framesToDrop = 0;\n\n\t\t\tif (me.dropFrames > 1) {\n\t\t\t\tframesToDrop = Math.floor(me.dropFrames);\n\t\t\t\tme.dropFrames = me.dropFrames % 1;\n\t\t\t}\n\n\t\t\tme.advance(1 + framesToDrop);\n\n\t\t\tvar endTime = Date.now();\n\n\t\t\tme.dropFrames += (endTime - startTime) / me.frameDuration;\n\n\t\t\t// Do we have more stuff to animate?\n\t\t\tif (me.animations.length > 0) {\n\t\t\t\tme.requestAnimationFrame();\n\t\t\t}\n\t\t},\n\n\t\t/**\n\t\t * @private\n\t\t */\n\t\tadvance: function(count) {\n\t\t\tvar animations = this.animations;\n\t\t\tvar animation, chart;\n\t\t\tvar i = 0;\n\n\t\t\twhile (i < animations.length) {\n\t\t\t\tanimation = animations[i];\n\t\t\t\tchart = animation.chart;\n\n\t\t\t\tanimation.currentStep = (animation.currentStep || 0) + count;\n\t\t\t\tanimation.currentStep = Math.min(animation.currentStep, animation.numSteps);\n\n\t\t\t\thelpers.callback(animation.render, [chart, animation], chart);\n\t\t\t\thelpers.callback(animation.onAnimationProgress, [animation], chart);\n\n\t\t\t\tif (animation.currentStep >= animation.numSteps) {\n\t\t\t\t\thelpers.callback(animation.onAnimationComplete, [animation], chart);\n\t\t\t\t\tchart.animating = false;\n\t\t\t\t\tanimations.splice(i, 1);\n\t\t\t\t} else {\n\t\t\t\t\t++i;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t};\n\n\t/**\n\t * Provided for backward compatibility, use Chart.Animation instead\n\t * @prop Chart.Animation#animationObject\n\t * @deprecated since version 2.6.0\n\t * @todo remove at version 3\n\t */\n\tObject.defineProperty(Chart.Animation.prototype, 'animationObject', {\n\t\tget: function() {\n\t\t\treturn this;\n\t\t}\n\t});\n\n\t/**\n\t * Provided for backward compatibility, use Chart.Animation#chart instead\n\t * @prop Chart.Animation#chartInstance\n\t * @deprecated since version 2.6.0\n\t * @todo remove at version 3\n\t */\n\tObject.defineProperty(Chart.Animation.prototype, 'chartInstance', {\n\t\tget: function() {\n\t\t\treturn this.chart;\n\t\t},\n\t\tset: function(value) {\n\t\t\tthis.chart = value;\n\t\t}\n\t});\n\n};\n"
  },
  {
    "path": "app_backend/static/plugin/Chart.js-2.6.0/src/core/core.canvasHelpers.js",
    "content": "'use strict';\n\nmodule.exports = function(Chart) {\n\t// Global Chart canvas helpers object for drawing items to canvas\n\tvar helpers = Chart.canvasHelpers = {};\n\n\thelpers.drawPoint = function(ctx, pointStyle, radius, x, y) {\n\t\tvar type, edgeLength, xOffset, yOffset, height, size;\n\n\t\tif (typeof pointStyle === 'object') {\n\t\t\ttype = pointStyle.toString();\n\t\t\tif (type === '[object HTMLImageElement]' || type === '[object HTMLCanvasElement]') {\n\t\t\t\tctx.drawImage(pointStyle, x - pointStyle.width / 2, y - pointStyle.height / 2, pointStyle.width, pointStyle.height);\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\n\t\tif (isNaN(radius) || radius <= 0) {\n\t\t\treturn;\n\t\t}\n\n\t\tswitch (pointStyle) {\n\t\t// Default includes circle\n\t\tdefault:\n\t\t\tctx.beginPath();\n\t\t\tctx.arc(x, y, radius, 0, Math.PI * 2);\n\t\t\tctx.closePath();\n\t\t\tctx.fill();\n\t\t\tbreak;\n\t\tcase 'triangle':\n\t\t\tctx.beginPath();\n\t\t\tedgeLength = 3 * radius / Math.sqrt(3);\n\t\t\theight = edgeLength * Math.sqrt(3) / 2;\n\t\t\tctx.moveTo(x - edgeLength / 2, y + height / 3);\n\t\t\tctx.lineTo(x + edgeLength / 2, y + height / 3);\n\t\t\tctx.lineTo(x, y - 2 * height / 3);\n\t\t\tctx.closePath();\n\t\t\tctx.fill();\n\t\t\tbreak;\n\t\tcase 'rect':\n\t\t\tsize = 1 / Math.SQRT2 * radius;\n\t\t\tctx.beginPath();\n\t\t\tctx.fillRect(x - size, y - size, 2 * size, 2 * size);\n\t\t\tctx.strokeRect(x - size, y - size, 2 * size, 2 * size);\n\t\t\tbreak;\n\t\tcase 'rectRounded':\n\t\t\tvar offset = radius / Math.SQRT2;\n\t\t\tvar leftX = x - offset;\n\t\t\tvar topY = y - offset;\n\t\t\tvar sideSize = Math.SQRT2 * radius;\n\t\t\tChart.helpers.drawRoundedRectangle(ctx, leftX, topY, sideSize, sideSize, radius / 2);\n\t\t\tctx.fill();\n\t\t\tbreak;\n\t\tcase 'rectRot':\n\t\t\tsize = 1 / Math.SQRT2 * radius;\n\t\t\tctx.beginPath();\n\t\t\tctx.moveTo(x - size, y);\n\t\t\tctx.lineTo(x, y + size);\n\t\t\tctx.lineTo(x + size, y);\n\t\t\tctx.lineTo(x, y - size);\n\t\t\tctx.closePath();\n\t\t\tctx.fill();\n\t\t\tbreak;\n\t\tcase 'cross':\n\t\t\tctx.beginPath();\n\t\t\tctx.moveTo(x, y + radius);\n\t\t\tctx.lineTo(x, y - radius);\n\t\t\tctx.moveTo(x - radius, y);\n\t\t\tctx.lineTo(x + radius, y);\n\t\t\tctx.closePath();\n\t\t\tbreak;\n\t\tcase 'crossRot':\n\t\t\tctx.beginPath();\n\t\t\txOffset = Math.cos(Math.PI / 4) * radius;\n\t\t\tyOffset = Math.sin(Math.PI / 4) * radius;\n\t\t\tctx.moveTo(x - xOffset, y - yOffset);\n\t\t\tctx.lineTo(x + xOffset, y + yOffset);\n\t\t\tctx.moveTo(x - xOffset, y + yOffset);\n\t\t\tctx.lineTo(x + xOffset, y - yOffset);\n\t\t\tctx.closePath();\n\t\t\tbreak;\n\t\tcase 'star':\n\t\t\tctx.beginPath();\n\t\t\tctx.moveTo(x, y + radius);\n\t\t\tctx.lineTo(x, y - radius);\n\t\t\tctx.moveTo(x - radius, y);\n\t\t\tctx.lineTo(x + radius, y);\n\t\t\txOffset = Math.cos(Math.PI / 4) * radius;\n\t\t\tyOffset = Math.sin(Math.PI / 4) * radius;\n\t\t\tctx.moveTo(x - xOffset, y - yOffset);\n\t\t\tctx.lineTo(x + xOffset, y + yOffset);\n\t\t\tctx.moveTo(x - xOffset, y + yOffset);\n\t\t\tctx.lineTo(x + xOffset, y - yOffset);\n\t\t\tctx.closePath();\n\t\t\tbreak;\n\t\tcase 'line':\n\t\t\tctx.beginPath();\n\t\t\tctx.moveTo(x - radius, y);\n\t\t\tctx.lineTo(x + radius, y);\n\t\t\tctx.closePath();\n\t\t\tbreak;\n\t\tcase 'dash':\n\t\t\tctx.beginPath();\n\t\t\tctx.moveTo(x, y);\n\t\t\tctx.lineTo(x + radius, y);\n\t\t\tctx.closePath();\n\t\t\tbreak;\n\t\t}\n\n\t\tctx.stroke();\n\t};\n\n\thelpers.clipArea = function(ctx, clipArea) {\n\t\tctx.save();\n\t\tctx.beginPath();\n\t\tctx.rect(clipArea.left, clipArea.top, clipArea.right - clipArea.left, clipArea.bottom - clipArea.top);\n\t\tctx.clip();\n\t};\n\n\thelpers.unclipArea = function(ctx) {\n\t\tctx.restore();\n\t};\n\n\thelpers.lineTo = function(ctx, previous, target, flip) {\n\t\tif (target.steppedLine) {\n\t\t\tif (target.steppedLine === 'after') {\n\t\t\t\tctx.lineTo(previous.x, target.y);\n\t\t\t} else {\n\t\t\t\tctx.lineTo(target.x, previous.y);\n\t\t\t}\n\t\t\tctx.lineTo(target.x, target.y);\n\t\t\treturn;\n\t\t}\n\n\t\tif (!target.tension) {\n\t\t\tctx.lineTo(target.x, target.y);\n\t\t\treturn;\n\t\t}\n\n\t\tctx.bezierCurveTo(\n\t\t\tflip? previous.controlPointPreviousX : previous.controlPointNextX,\n\t\t\tflip? previous.controlPointPreviousY : previous.controlPointNextY,\n\t\t\tflip? target.controlPointNextX : target.controlPointPreviousX,\n\t\t\tflip? target.controlPointNextY : target.controlPointPreviousY,\n\t\t\ttarget.x,\n\t\t\ttarget.y);\n\t};\n\n\tChart.helpers.canvas = helpers;\n};\n"
  },
  {
    "path": "app_backend/static/plugin/Chart.js-2.6.0/src/core/core.controller.js",
    "content": "'use strict';\n\nmodule.exports = function(Chart) {\n\n\tvar helpers = Chart.helpers;\n\tvar plugins = Chart.plugins;\n\tvar platform = Chart.platform;\n\n\t// Create a dictionary of chart types, to allow for extension of existing types\n\tChart.types = {};\n\n\t// Store a reference to each instance - allowing us to globally resize chart instances on window resize.\n\t// Destroy method on the chart will remove the instance of the chart from this reference.\n\tChart.instances = {};\n\n\t// Controllers available for dataset visualization eg. bar, line, slice, etc.\n\tChart.controllers = {};\n\n\t/**\n\t * Initializes the given config with global and chart default values.\n\t */\n\tfunction initConfig(config) {\n\t\tconfig = config || {};\n\n\t\t// Do NOT use configMerge() for the data object because this method merges arrays\n\t\t// and so would change references to labels and datasets, preventing data updates.\n\t\tvar data = config.data = config.data || {};\n\t\tdata.datasets = data.datasets || [];\n\t\tdata.labels = data.labels || [];\n\n\t\tconfig.options = helpers.configMerge(\n\t\t\tChart.defaults.global,\n\t\t\tChart.defaults[config.type],\n\t\t\tconfig.options || {});\n\n\t\treturn config;\n\t}\n\n\t/**\n\t * Updates the config of the chart\n\t * @param chart {Chart} chart to update the options for\n\t */\n\tfunction updateConfig(chart) {\n\t\tvar newOptions = chart.options;\n\n\t\t// Update Scale(s) with options\n\t\tif (newOptions.scale) {\n\t\t\tchart.scale.options = newOptions.scale;\n\t\t} else if (newOptions.scales) {\n\t\t\tnewOptions.scales.xAxes.concat(newOptions.scales.yAxes).forEach(function(scaleOptions) {\n\t\t\t\tchart.scales[scaleOptions.id].options = scaleOptions;\n\t\t\t});\n\t\t}\n\n\t\t// Tooltip\n\t\tchart.tooltip._options = newOptions.tooltips;\n\t}\n\n\tfunction positionIsHorizontal(position) {\n\t\treturn position === 'top' || position === 'bottom';\n\t}\n\n\thelpers.extend(Chart.prototype, /** @lends Chart */ {\n\t\t/**\n\t\t * @private\n\t\t */\n\t\tconstruct: function(item, config) {\n\t\t\tvar me = this;\n\n\t\t\tconfig = initConfig(config);\n\n\t\t\tvar context = platform.acquireContext(item, config);\n\t\t\tvar canvas = context && context.canvas;\n\t\t\tvar height = canvas && canvas.height;\n\t\t\tvar width = canvas && canvas.width;\n\n\t\t\tme.id = helpers.uid();\n\t\t\tme.ctx = context;\n\t\t\tme.canvas = canvas;\n\t\t\tme.config = config;\n\t\t\tme.width = width;\n\t\t\tme.height = height;\n\t\t\tme.aspectRatio = height? width / height : null;\n\t\t\tme.options = config.options;\n\t\t\tme._bufferedRender = false;\n\n\t\t\t/**\n\t\t\t * Provided for backward compatibility, Chart and Chart.Controller have been merged,\n\t\t\t * the \"instance\" still need to be defined since it might be called from plugins.\n\t\t\t * @prop Chart#chart\n\t\t\t * @deprecated since version 2.6.0\n\t\t\t * @todo remove at version 3\n\t\t\t * @private\n\t\t\t */\n\t\t\tme.chart = me;\n\t\t\tme.controller = me;  // chart.chart.controller #inception\n\n\t\t\t// Add the chart instance to the global namespace\n\t\t\tChart.instances[me.id] = me;\n\n\t\t\t// Define alias to the config data: `chart.data === chart.config.data`\n\t\t\tObject.defineProperty(me, 'data', {\n\t\t\t\tget: function() {\n\t\t\t\t\treturn me.config.data;\n\t\t\t\t},\n\t\t\t\tset: function(value) {\n\t\t\t\t\tme.config.data = value;\n\t\t\t\t}\n\t\t\t});\n\n\t\t\tif (!context || !canvas) {\n\t\t\t\t// The given item is not a compatible context2d element, let's return before finalizing\n\t\t\t\t// the chart initialization but after setting basic chart / controller properties that\n\t\t\t\t// can help to figure out that the chart is not valid (e.g chart.canvas !== null);\n\t\t\t\t// https://github.com/chartjs/Chart.js/issues/2807\n\t\t\t\tconsole.error(\"Failed to create chart: can't acquire context from the given item\");\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tme.initialize();\n\t\t\tme.update();\n\t\t},\n\n\t\t/**\n\t\t * @private\n\t\t */\n\t\tinitialize: function() {\n\t\t\tvar me = this;\n\n\t\t\t// Before init plugin notification\n\t\t\tplugins.notify(me, 'beforeInit');\n\n\t\t\thelpers.retinaScale(me);\n\n\t\t\tme.bindEvents();\n\n\t\t\tif (me.options.responsive) {\n\t\t\t\t// Initial resize before chart draws (must be silent to preserve initial animations).\n\t\t\t\tme.resize(true);\n\t\t\t}\n\n\t\t\t// Make sure scales have IDs and are built before we build any controllers.\n\t\t\tme.ensureScalesHaveIDs();\n\t\t\tme.buildScales();\n\t\t\tme.initToolTip();\n\n\t\t\t// After init plugin notification\n\t\t\tplugins.notify(me, 'afterInit');\n\n\t\t\treturn me;\n\t\t},\n\n\t\tclear: function() {\n\t\t\thelpers.clear(this);\n\t\t\treturn this;\n\t\t},\n\n\t\tstop: function() {\n\t\t\t// Stops any current animation loop occurring\n\t\t\tChart.animationService.cancelAnimation(this);\n\t\t\treturn this;\n\t\t},\n\n\t\tresize: function(silent) {\n\t\t\tvar me = this;\n\t\t\tvar options = me.options;\n\t\t\tvar canvas = me.canvas;\n\t\t\tvar aspectRatio = (options.maintainAspectRatio && me.aspectRatio) || null;\n\n\t\t\t// the canvas render width and height will be casted to integers so make sure that\n\t\t\t// the canvas display style uses the same integer values to avoid blurring effect.\n\t\t\tvar newWidth = Math.floor(helpers.getMaximumWidth(canvas));\n\t\t\tvar newHeight = Math.floor(aspectRatio? newWidth / aspectRatio : helpers.getMaximumHeight(canvas));\n\n\t\t\tif (me.width === newWidth && me.height === newHeight) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tcanvas.width = me.width = newWidth;\n\t\t\tcanvas.height = me.height = newHeight;\n\t\t\tcanvas.style.width = newWidth + 'px';\n\t\t\tcanvas.style.height = newHeight + 'px';\n\n\t\t\thelpers.retinaScale(me);\n\n\t\t\tif (!silent) {\n\t\t\t\t// Notify any plugins about the resize\n\t\t\t\tvar newSize = {width: newWidth, height: newHeight};\n\t\t\t\tplugins.notify(me, 'resize', [newSize]);\n\n\t\t\t\t// Notify of resize\n\t\t\t\tif (me.options.onResize) {\n\t\t\t\t\tme.options.onResize(me, newSize);\n\t\t\t\t}\n\n\t\t\t\tme.stop();\n\t\t\t\tme.update(me.options.responsiveAnimationDuration);\n\t\t\t}\n\t\t},\n\n\t\tensureScalesHaveIDs: function() {\n\t\t\tvar options = this.options;\n\t\t\tvar scalesOptions = options.scales || {};\n\t\t\tvar scaleOptions = options.scale;\n\n\t\t\thelpers.each(scalesOptions.xAxes, function(xAxisOptions, index) {\n\t\t\t\txAxisOptions.id = xAxisOptions.id || ('x-axis-' + index);\n\t\t\t});\n\n\t\t\thelpers.each(scalesOptions.yAxes, function(yAxisOptions, index) {\n\t\t\t\tyAxisOptions.id = yAxisOptions.id || ('y-axis-' + index);\n\t\t\t});\n\n\t\t\tif (scaleOptions) {\n\t\t\t\tscaleOptions.id = scaleOptions.id || 'scale';\n\t\t\t}\n\t\t},\n\n\t\t/**\n\t\t * Builds a map of scale ID to scale object for future lookup.\n\t\t */\n\t\tbuildScales: function() {\n\t\t\tvar me = this;\n\t\t\tvar options = me.options;\n\t\t\tvar scales = me.scales = {};\n\t\t\tvar items = [];\n\n\t\t\tif (options.scales) {\n\t\t\t\titems = items.concat(\n\t\t\t\t\t(options.scales.xAxes || []).map(function(xAxisOptions) {\n\t\t\t\t\t\treturn {options: xAxisOptions, dtype: 'category', dposition: 'bottom'};\n\t\t\t\t\t}),\n\t\t\t\t\t(options.scales.yAxes || []).map(function(yAxisOptions) {\n\t\t\t\t\t\treturn {options: yAxisOptions, dtype: 'linear', dposition: 'left'};\n\t\t\t\t\t})\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tif (options.scale) {\n\t\t\t\titems.push({\n\t\t\t\t\toptions: options.scale,\n\t\t\t\t\tdtype: 'radialLinear',\n\t\t\t\t\tisDefault: true,\n\t\t\t\t\tdposition: 'chartArea'\n\t\t\t\t});\n\t\t\t}\n\n\t\t\thelpers.each(items, function(item) {\n\t\t\t\tvar scaleOptions = item.options;\n\t\t\t\tvar scaleType = helpers.getValueOrDefault(scaleOptions.type, item.dtype);\n\t\t\t\tvar scaleClass = Chart.scaleService.getScaleConstructor(scaleType);\n\t\t\t\tif (!scaleClass) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tif (positionIsHorizontal(scaleOptions.position) !== positionIsHorizontal(item.dposition)) {\n\t\t\t\t\tscaleOptions.position = item.dposition;\n\t\t\t\t}\n\n\t\t\t\tvar scale = new scaleClass({\n\t\t\t\t\tid: scaleOptions.id,\n\t\t\t\t\toptions: scaleOptions,\n\t\t\t\t\tctx: me.ctx,\n\t\t\t\t\tchart: me\n\t\t\t\t});\n\n\t\t\t\tscales[scale.id] = scale;\n\n\t\t\t\t// TODO(SB): I think we should be able to remove this custom case (options.scale)\n\t\t\t\t// and consider it as a regular scale part of the \"scales\"\" map only! This would\n\t\t\t\t// make the logic easier and remove some useless? custom code.\n\t\t\t\tif (item.isDefault) {\n\t\t\t\t\tme.scale = scale;\n\t\t\t\t}\n\t\t\t});\n\n\t\t\tChart.scaleService.addScalesToLayout(this);\n\t\t},\n\n\t\tbuildOrUpdateControllers: function() {\n\t\t\tvar me = this;\n\t\t\tvar types = [];\n\t\t\tvar newControllers = [];\n\n\t\t\thelpers.each(me.data.datasets, function(dataset, datasetIndex) {\n\t\t\t\tvar meta = me.getDatasetMeta(datasetIndex);\n\t\t\t\tif (!meta.type) {\n\t\t\t\t\tmeta.type = dataset.type || me.config.type;\n\t\t\t\t}\n\n\t\t\t\ttypes.push(meta.type);\n\n\t\t\t\tif (meta.controller) {\n\t\t\t\t\tmeta.controller.updateIndex(datasetIndex);\n\t\t\t\t} else {\n\t\t\t\t\tvar ControllerClass = Chart.controllers[meta.type];\n\t\t\t\t\tif (ControllerClass === undefined) {\n\t\t\t\t\t\tthrow new Error('\"' + meta.type + '\" is not a chart type.');\n\t\t\t\t\t}\n\n\t\t\t\t\tmeta.controller = new ControllerClass(me, datasetIndex);\n\t\t\t\t\tnewControllers.push(meta.controller);\n\t\t\t\t}\n\t\t\t}, me);\n\n\t\t\tif (types.length > 1) {\n\t\t\t\tfor (var i = 1; i < types.length; i++) {\n\t\t\t\t\tif (types[i] !== types[i - 1]) {\n\t\t\t\t\t\tme.isCombo = true;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn newControllers;\n\t\t},\n\n\t\t/**\n\t\t * Reset the elements of all datasets\n\t\t * @private\n\t\t */\n\t\tresetElements: function() {\n\t\t\tvar me = this;\n\t\t\thelpers.each(me.data.datasets, function(dataset, datasetIndex) {\n\t\t\t\tme.getDatasetMeta(datasetIndex).controller.reset();\n\t\t\t}, me);\n\t\t},\n\n\t\t/**\n\t\t* Resets the chart back to it's state before the initial animation\n\t\t*/\n\t\treset: function() {\n\t\t\tthis.resetElements();\n\t\t\tthis.tooltip.initialize();\n\t\t},\n\n\t\tupdate: function(animationDuration, lazy) {\n\t\t\tvar me = this;\n\n\t\t\tupdateConfig(me);\n\n\t\t\tif (plugins.notify(me, 'beforeUpdate') === false) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// In case the entire data object changed\n\t\t\tme.tooltip._data = me.data;\n\n\t\t\t// Make sure dataset controllers are updated and new controllers are reset\n\t\t\tvar newControllers = me.buildOrUpdateControllers();\n\n\t\t\t// Make sure all dataset controllers have correct meta data counts\n\t\t\thelpers.each(me.data.datasets, function(dataset, datasetIndex) {\n\t\t\t\tme.getDatasetMeta(datasetIndex).controller.buildOrUpdateElements();\n\t\t\t}, me);\n\n\t\t\tme.updateLayout();\n\n\t\t\t// Can only reset the new controllers after the scales have been updated\n\t\t\thelpers.each(newControllers, function(controller) {\n\t\t\t\tcontroller.reset();\n\t\t\t});\n\n\t\t\tme.updateDatasets();\n\n\t\t\t// Do this before render so that any plugins that need final scale updates can use it\n\t\t\tplugins.notify(me, 'afterUpdate');\n\n\t\t\tif (me._bufferedRender) {\n\t\t\t\tme._bufferedRequest = {\n\t\t\t\t\tlazy: lazy,\n\t\t\t\t\tduration: animationDuration\n\t\t\t\t};\n\t\t\t} else {\n\t\t\t\tme.render(animationDuration, lazy);\n\t\t\t}\n\t\t},\n\n\t\t/**\n\t\t * Updates the chart layout unless a plugin returns `false` to the `beforeLayout`\n\t\t * hook, in which case, plugins will not be called on `afterLayout`.\n\t\t * @private\n\t\t */\n\t\tupdateLayout: function() {\n\t\t\tvar me = this;\n\n\t\t\tif (plugins.notify(me, 'beforeLayout') === false) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tChart.layoutService.update(this, this.width, this.height);\n\n\t\t\t/**\n\t\t\t * Provided for backward compatibility, use `afterLayout` instead.\n\t\t\t * @method IPlugin#afterScaleUpdate\n\t\t\t * @deprecated since version 2.5.0\n\t\t\t * @todo remove at version 3\n\t\t\t * @private\n\t\t\t */\n\t\t\tplugins.notify(me, 'afterScaleUpdate');\n\t\t\tplugins.notify(me, 'afterLayout');\n\t\t},\n\n\t\t/**\n\t\t * Updates all datasets unless a plugin returns `false` to the `beforeDatasetsUpdate`\n\t\t * hook, in which case, plugins will not be called on `afterDatasetsUpdate`.\n\t\t * @private\n\t\t */\n\t\tupdateDatasets: function() {\n\t\t\tvar me = this;\n\n\t\t\tif (plugins.notify(me, 'beforeDatasetsUpdate') === false) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tfor (var i = 0, ilen = me.data.datasets.length; i < ilen; ++i) {\n\t\t\t\tme.updateDataset(i);\n\t\t\t}\n\n\t\t\tplugins.notify(me, 'afterDatasetsUpdate');\n\t\t},\n\n\t\t/**\n\t\t * Updates dataset at index unless a plugin returns `false` to the `beforeDatasetUpdate`\n\t\t * hook, in which case, plugins will not be called on `afterDatasetUpdate`.\n\t\t * @private\n\t\t */\n\t\tupdateDataset: function(index) {\n\t\t\tvar me = this;\n\t\t\tvar meta = me.getDatasetMeta(index);\n\t\t\tvar args = {\n\t\t\t\tmeta: meta,\n\t\t\t\tindex: index\n\t\t\t};\n\n\t\t\tif (plugins.notify(me, 'beforeDatasetUpdate', [args]) === false) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tmeta.controller.update();\n\n\t\t\tplugins.notify(me, 'afterDatasetUpdate', [args]);\n\t\t},\n\n\t\trender: function(duration, lazy) {\n\t\t\tvar me = this;\n\n\t\t\tif (plugins.notify(me, 'beforeRender') === false) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tvar animationOptions = me.options.animation;\n\t\t\tvar onComplete = function(animation) {\n\t\t\t\tplugins.notify(me, 'afterRender');\n\t\t\t\thelpers.callback(animationOptions && animationOptions.onComplete, [animation], me);\n\t\t\t};\n\n\t\t\tif (animationOptions && ((typeof duration !== 'undefined' && duration !== 0) || (typeof duration === 'undefined' && animationOptions.duration !== 0))) {\n\t\t\t\tvar animation = new Chart.Animation({\n\t\t\t\t\tnumSteps: (duration || animationOptions.duration) / 16.66, // 60 fps\n\t\t\t\t\teasing: animationOptions.easing,\n\n\t\t\t\t\trender: function(chart, animationObject) {\n\t\t\t\t\t\tvar easingFunction = helpers.easingEffects[animationObject.easing];\n\t\t\t\t\t\tvar currentStep = animationObject.currentStep;\n\t\t\t\t\t\tvar stepDecimal = currentStep / animationObject.numSteps;\n\n\t\t\t\t\t\tchart.draw(easingFunction(stepDecimal), stepDecimal, currentStep);\n\t\t\t\t\t},\n\n\t\t\t\t\tonAnimationProgress: animationOptions.onProgress,\n\t\t\t\t\tonAnimationComplete: onComplete\n\t\t\t\t});\n\n\t\t\t\tChart.animationService.addAnimation(me, animation, duration, lazy);\n\t\t\t} else {\n\t\t\t\tme.draw();\n\n\t\t\t\t// See https://github.com/chartjs/Chart.js/issues/3781\n\t\t\t\tonComplete(new Chart.Animation({numSteps: 0, chart: me}));\n\t\t\t}\n\n\t\t\treturn me;\n\t\t},\n\n\t\tdraw: function(easingValue) {\n\t\t\tvar me = this;\n\n\t\t\tme.clear();\n\n\t\t\tif (easingValue === undefined || easingValue === null) {\n\t\t\t\teasingValue = 1;\n\t\t\t}\n\n\t\t\tme.transition(easingValue);\n\n\t\t\tif (plugins.notify(me, 'beforeDraw', [easingValue]) === false) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// Draw all the scales\n\t\t\thelpers.each(me.boxes, function(box) {\n\t\t\t\tbox.draw(me.chartArea);\n\t\t\t}, me);\n\n\t\t\tif (me.scale) {\n\t\t\t\tme.scale.draw();\n\t\t\t}\n\n\t\t\tme.drawDatasets(easingValue);\n\n\t\t\t// Finally draw the tooltip\n\t\t\tme.tooltip.draw();\n\n\t\t\tplugins.notify(me, 'afterDraw', [easingValue]);\n\t\t},\n\n\t\t/**\n\t\t * @private\n\t\t */\n\t\ttransition: function(easingValue) {\n\t\t\tvar me = this;\n\n\t\t\tfor (var i=0, ilen=(me.data.datasets || []).length; i<ilen; ++i) {\n\t\t\t\tif (me.isDatasetVisible(i)) {\n\t\t\t\t\tme.getDatasetMeta(i).controller.transition(easingValue);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tme.tooltip.transition(easingValue);\n\t\t},\n\n\t\t/**\n\t\t * Draws all datasets unless a plugin returns `false` to the `beforeDatasetsDraw`\n\t\t * hook, in which case, plugins will not be called on `afterDatasetsDraw`.\n\t\t * @private\n\t\t */\n\t\tdrawDatasets: function(easingValue) {\n\t\t\tvar me = this;\n\n\t\t\tif (plugins.notify(me, 'beforeDatasetsDraw', [easingValue]) === false) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// Draw datasets reversed to support proper line stacking\n\t\t\tfor (var i=(me.data.datasets || []).length - 1; i >= 0; --i) {\n\t\t\t\tif (me.isDatasetVisible(i)) {\n\t\t\t\t\tme.drawDataset(i, easingValue);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tplugins.notify(me, 'afterDatasetsDraw', [easingValue]);\n\t\t},\n\n\t\t/**\n\t\t * Draws dataset at index unless a plugin returns `false` to the `beforeDatasetDraw`\n\t\t * hook, in which case, plugins will not be called on `afterDatasetDraw`.\n\t\t * @private\n\t\t */\n\t\tdrawDataset: function(index, easingValue) {\n\t\t\tvar me = this;\n\t\t\tvar meta = me.getDatasetMeta(index);\n\t\t\tvar args = {\n\t\t\t\tmeta: meta,\n\t\t\t\tindex: index,\n\t\t\t\teasingValue: easingValue\n\t\t\t};\n\n\t\t\tif (plugins.notify(me, 'beforeDatasetDraw', [args]) === false) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tmeta.controller.draw(easingValue);\n\n\t\t\tplugins.notify(me, 'afterDatasetDraw', [args]);\n\t\t},\n\n\t\t// Get the single element that was clicked on\n\t\t// @return : An object containing the dataset index and element index of the matching element. Also contains the rectangle that was draw\n\t\tgetElementAtEvent: function(e) {\n\t\t\treturn Chart.Interaction.modes.single(this, e);\n\t\t},\n\n\t\tgetElementsAtEvent: function(e) {\n\t\t\treturn Chart.Interaction.modes.label(this, e, {intersect: true});\n\t\t},\n\n\t\tgetElementsAtXAxis: function(e) {\n\t\t\treturn Chart.Interaction.modes['x-axis'](this, e, {intersect: true});\n\t\t},\n\n\t\tgetElementsAtEventForMode: function(e, mode, options) {\n\t\t\tvar method = Chart.Interaction.modes[mode];\n\t\t\tif (typeof method === 'function') {\n\t\t\t\treturn method(this, e, options);\n\t\t\t}\n\n\t\t\treturn [];\n\t\t},\n\n\t\tgetDatasetAtEvent: function(e) {\n\t\t\treturn Chart.Interaction.modes.dataset(this, e, {intersect: true});\n\t\t},\n\n\t\tgetDatasetMeta: function(datasetIndex) {\n\t\t\tvar me = this;\n\t\t\tvar dataset = me.data.datasets[datasetIndex];\n\t\t\tif (!dataset._meta) {\n\t\t\t\tdataset._meta = {};\n\t\t\t}\n\n\t\t\tvar meta = dataset._meta[me.id];\n\t\t\tif (!meta) {\n\t\t\t\tmeta = dataset._meta[me.id] = {\n\t\t\t\t\ttype: null,\n\t\t\t\t\tdata: [],\n\t\t\t\t\tdataset: null,\n\t\t\t\t\tcontroller: null,\n\t\t\t\t\thidden: null,\t\t\t// See isDatasetVisible() comment\n\t\t\t\t\txAxisID: null,\n\t\t\t\t\tyAxisID: null\n\t\t\t\t};\n\t\t\t}\n\n\t\t\treturn meta;\n\t\t},\n\n\t\tgetVisibleDatasetCount: function() {\n\t\t\tvar count = 0;\n\t\t\tfor (var i = 0, ilen = this.data.datasets.length; i<ilen; ++i) {\n\t\t\t\tif (this.isDatasetVisible(i)) {\n\t\t\t\t\tcount++;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn count;\n\t\t},\n\n\t\tisDatasetVisible: function(datasetIndex) {\n\t\t\tvar meta = this.getDatasetMeta(datasetIndex);\n\n\t\t\t// meta.hidden is a per chart dataset hidden flag override with 3 states: if true or false,\n\t\t\t// the dataset.hidden value is ignored, else if null, the dataset hidden state is returned.\n\t\t\treturn typeof meta.hidden === 'boolean'? !meta.hidden : !this.data.datasets[datasetIndex].hidden;\n\t\t},\n\n\t\tgenerateLegend: function() {\n\t\t\treturn this.options.legendCallback(this);\n\t\t},\n\n\t\tdestroy: function() {\n\t\t\tvar me = this;\n\t\t\tvar canvas = me.canvas;\n\t\t\tvar meta, i, ilen;\n\n\t\t\tme.stop();\n\n\t\t\t// dataset controllers need to cleanup associated data\n\t\t\tfor (i = 0, ilen = me.data.datasets.length; i < ilen; ++i) {\n\t\t\t\tmeta = me.getDatasetMeta(i);\n\t\t\t\tif (meta.controller) {\n\t\t\t\t\tmeta.controller.destroy();\n\t\t\t\t\tmeta.controller = null;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (canvas) {\n\t\t\t\tme.unbindEvents();\n\t\t\t\thelpers.clear(me);\n\t\t\t\tplatform.releaseContext(me.ctx);\n\t\t\t\tme.canvas = null;\n\t\t\t\tme.ctx = null;\n\t\t\t}\n\n\t\t\tplugins.notify(me, 'destroy');\n\n\t\t\tdelete Chart.instances[me.id];\n\t\t},\n\n\t\ttoBase64Image: function() {\n\t\t\treturn this.canvas.toDataURL.apply(this.canvas, arguments);\n\t\t},\n\n\t\tinitToolTip: function() {\n\t\t\tvar me = this;\n\t\t\tme.tooltip = new Chart.Tooltip({\n\t\t\t\t_chart: me,\n\t\t\t\t_chartInstance: me,            // deprecated, backward compatibility\n\t\t\t\t_data: me.data,\n\t\t\t\t_options: me.options.tooltips\n\t\t\t}, me);\n\t\t\tme.tooltip.initialize();\n\t\t},\n\n\t\t/**\n\t\t * @private\n\t\t */\n\t\tbindEvents: function() {\n\t\t\tvar me = this;\n\t\t\tvar listeners = me._listeners = {};\n\t\t\tvar listener = function() {\n\t\t\t\tme.eventHandler.apply(me, arguments);\n\t\t\t};\n\n\t\t\thelpers.each(me.options.events, function(type) {\n\t\t\t\tplatform.addEventListener(me, type, listener);\n\t\t\t\tlisteners[type] = listener;\n\t\t\t});\n\n\t\t\t// Responsiveness is currently based on the use of an iframe, however this method causes\n\t\t\t// performance issues and could be troublesome when used with ad blockers. So make sure\n\t\t\t// that the user is still able to create a chart without iframe when responsive is false.\n\t\t\t// See https://github.com/chartjs/Chart.js/issues/2210\n\t\t\tif (me.options.responsive) {\n\t\t\t\tlistener = function() {\n\t\t\t\t\tme.resize();\n\t\t\t\t};\n\n\t\t\t\tplatform.addEventListener(me, 'resize', listener);\n\t\t\t\tlisteners.resize = listener;\n\t\t\t}\n\t\t},\n\n\t\t/**\n\t\t * @private\n\t\t */\n\t\tunbindEvents: function() {\n\t\t\tvar me = this;\n\t\t\tvar listeners = me._listeners;\n\t\t\tif (!listeners) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tdelete me._listeners;\n\t\t\thelpers.each(listeners, function(listener, type) {\n\t\t\t\tplatform.removeEventListener(me, type, listener);\n\t\t\t});\n\t\t},\n\n\t\tupdateHoverStyle: function(elements, mode, enabled) {\n\t\t\tvar method = enabled? 'setHoverStyle' : 'removeHoverStyle';\n\t\t\tvar element, i, ilen;\n\n\t\t\tfor (i=0, ilen=elements.length; i<ilen; ++i) {\n\t\t\t\telement = elements[i];\n\t\t\t\tif (element) {\n\t\t\t\t\tthis.getDatasetMeta(element._datasetIndex).controller[method](element);\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\n\t\t/**\n\t\t * @private\n\t\t */\n\t\teventHandler: function(e) {\n\t\t\tvar me = this;\n\t\t\tvar tooltip = me.tooltip;\n\n\t\t\tif (plugins.notify(me, 'beforeEvent', [e]) === false) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// Buffer any update calls so that renders do not occur\n\t\t\tme._bufferedRender = true;\n\t\t\tme._bufferedRequest = null;\n\n\t\t\tvar changed = me.handleEvent(e);\n\t\t\tchanged |= tooltip && tooltip.handleEvent(e);\n\n\t\t\tplugins.notify(me, 'afterEvent', [e]);\n\n\t\t\tvar bufferedRequest = me._bufferedRequest;\n\t\t\tif (bufferedRequest) {\n\t\t\t\t// If we have an update that was triggered, we need to do a normal render\n\t\t\t\tme.render(bufferedRequest.duration, bufferedRequest.lazy);\n\t\t\t} else if (changed && !me.animating) {\n\t\t\t\t// If entering, leaving, or changing elements, animate the change via pivot\n\t\t\t\tme.stop();\n\n\t\t\t\t// We only need to render at this point. Updating will cause scales to be\n\t\t\t\t// recomputed generating flicker & using more memory than necessary.\n\t\t\t\tme.render(me.options.hover.animationDuration, true);\n\t\t\t}\n\n\t\t\tme._bufferedRender = false;\n\t\t\tme._bufferedRequest = null;\n\n\t\t\treturn me;\n\t\t},\n\n\t\t/**\n\t\t * Handle an event\n\t\t * @private\n\t\t * @param {IEvent} event the event to handle\n\t\t * @return {Boolean} true if the chart needs to re-render\n\t\t */\n\t\thandleEvent: function(e) {\n\t\t\tvar me = this;\n\t\t\tvar options = me.options || {};\n\t\t\tvar hoverOptions = options.hover;\n\t\t\tvar changed = false;\n\n\t\t\tme.lastActive = me.lastActive || [];\n\n\t\t\t// Find Active Elements for hover and tooltips\n\t\t\tif (e.type === 'mouseout') {\n\t\t\t\tme.active = [];\n\t\t\t} else {\n\t\t\t\tme.active = me.getElementsAtEventForMode(e, hoverOptions.mode, hoverOptions);\n\t\t\t}\n\n\t\t\t// On Hover hook\n\t\t\tif (hoverOptions.onHover) {\n\t\t\t\t// Need to call with native event here to not break backwards compatibility\n\t\t\t\thoverOptions.onHover.call(me, e.native, me.active);\n\t\t\t}\n\n\t\t\tif (e.type === 'mouseup' || e.type === 'click') {\n\t\t\t\tif (options.onClick) {\n\t\t\t\t\t// Use e.native here for backwards compatibility\n\t\t\t\t\toptions.onClick.call(me, e.native, me.active);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Remove styling for last active (even if it may still be active)\n\t\t\tif (me.lastActive.length) {\n\t\t\t\tme.updateHoverStyle(me.lastActive, hoverOptions.mode, false);\n\t\t\t}\n\n\t\t\t// Built in hover styling\n\t\t\tif (me.active.length && hoverOptions.mode) {\n\t\t\t\tme.updateHoverStyle(me.active, hoverOptions.mode, true);\n\t\t\t}\n\n\t\t\tchanged = !helpers.arrayEquals(me.active, me.lastActive);\n\n\t\t\t// Remember Last Actives\n\t\t\tme.lastActive = me.active;\n\n\t\t\treturn changed;\n\t\t}\n\t});\n\n\t/**\n\t * Provided for backward compatibility, use Chart instead.\n\t * @class Chart.Controller\n\t * @deprecated since version 2.6.0\n\t * @todo remove at version 3\n\t * @private\n\t */\n\tChart.Controller = Chart;\n};\n"
  },
  {
    "path": "app_backend/static/plugin/Chart.js-2.6.0/src/core/core.datasetController.js",
    "content": "'use strict';\n\nmodule.exports = function(Chart) {\n\n\tvar helpers = Chart.helpers;\n\n\tvar arrayEvents = ['push', 'pop', 'shift', 'splice', 'unshift'];\n\n\t/**\n\t * Hooks the array methods that add or remove values ('push', pop', 'shift', 'splice',\n\t * 'unshift') and notify the listener AFTER the array has been altered. Listeners are\n\t * called on the 'onData*' callbacks (e.g. onDataPush, etc.) with same arguments.\n\t */\n\tfunction listenArrayEvents(array, listener) {\n\t\tif (array._chartjs) {\n\t\t\tarray._chartjs.listeners.push(listener);\n\t\t\treturn;\n\t\t}\n\n\t\tObject.defineProperty(array, '_chartjs', {\n\t\t\tconfigurable: true,\n\t\t\tenumerable: false,\n\t\t\tvalue: {\n\t\t\t\tlisteners: [listener]\n\t\t\t}\n\t\t});\n\n\t\tarrayEvents.forEach(function(key) {\n\t\t\tvar method = 'onData' + key.charAt(0).toUpperCase() + key.slice(1);\n\t\t\tvar base = array[key];\n\n\t\t\tObject.defineProperty(array, key, {\n\t\t\t\tconfigurable: true,\n\t\t\t\tenumerable: false,\n\t\t\t\tvalue: function() {\n\t\t\t\t\tvar args = Array.prototype.slice.call(arguments);\n\t\t\t\t\tvar res = base.apply(this, args);\n\n\t\t\t\t\thelpers.each(array._chartjs.listeners, function(object) {\n\t\t\t\t\t\tif (typeof object[method] === 'function') {\n\t\t\t\t\t\t\tobject[method].apply(object, args);\n\t\t\t\t\t\t}\n\t\t\t\t\t});\n\n\t\t\t\t\treturn res;\n\t\t\t\t}\n\t\t\t});\n\t\t});\n\t}\n\n\t/**\n\t * Removes the given array event listener and cleanup extra attached properties (such as\n\t * the _chartjs stub and overridden methods) if array doesn't have any more listeners.\n\t */\n\tfunction unlistenArrayEvents(array, listener) {\n\t\tvar stub = array._chartjs;\n\t\tif (!stub) {\n\t\t\treturn;\n\t\t}\n\n\t\tvar listeners = stub.listeners;\n\t\tvar index = listeners.indexOf(listener);\n\t\tif (index !== -1) {\n\t\t\tlisteners.splice(index, 1);\n\t\t}\n\n\t\tif (listeners.length > 0) {\n\t\t\treturn;\n\t\t}\n\n\t\tarrayEvents.forEach(function(key) {\n\t\t\tdelete array[key];\n\t\t});\n\n\t\tdelete array._chartjs;\n\t}\n\n\t// Base class for all dataset controllers (line, bar, etc)\n\tChart.DatasetController = function(chart, datasetIndex) {\n\t\tthis.initialize(chart, datasetIndex);\n\t};\n\n\thelpers.extend(Chart.DatasetController.prototype, {\n\n\t\t/**\n\t\t * Element type used to generate a meta dataset (e.g. Chart.element.Line).\n\t\t * @type {Chart.core.element}\n\t\t */\n\t\tdatasetElementType: null,\n\n\t\t/**\n\t\t * Element type used to generate a meta data (e.g. Chart.element.Point).\n\t\t * @type {Chart.core.element}\n\t\t */\n\t\tdataElementType: null,\n\n\t\tinitialize: function(chart, datasetIndex) {\n\t\t\tvar me = this;\n\t\t\tme.chart = chart;\n\t\t\tme.index = datasetIndex;\n\t\t\tme.linkScales();\n\t\t\tme.addElements();\n\t\t},\n\n\t\tupdateIndex: function(datasetIndex) {\n\t\t\tthis.index = datasetIndex;\n\t\t},\n\n\t\tlinkScales: function() {\n\t\t\tvar me = this;\n\t\t\tvar meta = me.getMeta();\n\t\t\tvar dataset = me.getDataset();\n\n\t\t\tif (meta.xAxisID === null) {\n\t\t\t\tmeta.xAxisID = dataset.xAxisID || me.chart.options.scales.xAxes[0].id;\n\t\t\t}\n\t\t\tif (meta.yAxisID === null) {\n\t\t\t\tmeta.yAxisID = dataset.yAxisID || me.chart.options.scales.yAxes[0].id;\n\t\t\t}\n\t\t},\n\n\t\tgetDataset: function() {\n\t\t\treturn this.chart.data.datasets[this.index];\n\t\t},\n\n\t\tgetMeta: function() {\n\t\t\treturn this.chart.getDatasetMeta(this.index);\n\t\t},\n\n\t\tgetScaleForId: function(scaleID) {\n\t\t\treturn this.chart.scales[scaleID];\n\t\t},\n\n\t\treset: function() {\n\t\t\tthis.update(true);\n\t\t},\n\n\t\t/**\n\t\t * @private\n\t\t */\n\t\tdestroy: function() {\n\t\t\tif (this._data) {\n\t\t\t\tunlistenArrayEvents(this._data, this);\n\t\t\t}\n\t\t},\n\n\t\tcreateMetaDataset: function() {\n\t\t\tvar me = this;\n\t\t\tvar type = me.datasetElementType;\n\t\t\treturn type && new type({\n\t\t\t\t_chart: me.chart,\n\t\t\t\t_datasetIndex: me.index\n\t\t\t});\n\t\t},\n\n\t\tcreateMetaData: function(index) {\n\t\t\tvar me = this;\n\t\t\tvar type = me.dataElementType;\n\t\t\treturn type && new type({\n\t\t\t\t_chart: me.chart,\n\t\t\t\t_datasetIndex: me.index,\n\t\t\t\t_index: index\n\t\t\t});\n\t\t},\n\n\t\taddElements: function() {\n\t\t\tvar me = this;\n\t\t\tvar meta = me.getMeta();\n\t\t\tvar data = me.getDataset().data || [];\n\t\t\tvar metaData = meta.data;\n\t\t\tvar i, ilen;\n\n\t\t\tfor (i=0, ilen=data.length; i<ilen; ++i) {\n\t\t\t\tmetaData[i] = metaData[i] || me.createMetaData(i);\n\t\t\t}\n\n\t\t\tmeta.dataset = meta.dataset || me.createMetaDataset();\n\t\t},\n\n\t\taddElementAndReset: function(index) {\n\t\t\tvar element = this.createMetaData(index);\n\t\t\tthis.getMeta().data.splice(index, 0, element);\n\t\t\tthis.updateElement(element, index, true);\n\t\t},\n\n\t\tbuildOrUpdateElements: function() {\n\t\t\tvar me = this;\n\t\t\tvar dataset = me.getDataset();\n\t\t\tvar data = dataset.data || (dataset.data = []);\n\n\t\t\t// In order to correctly handle data addition/deletion animation (an thus simulate\n\t\t\t// real-time charts), we need to monitor these data modifications and synchronize\n\t\t\t// the internal meta data accordingly.\n\t\t\tif (me._data !== data) {\n\t\t\t\tif (me._data) {\n\t\t\t\t\t// This case happens when the user replaced the data array instance.\n\t\t\t\t\tunlistenArrayEvents(me._data, me);\n\t\t\t\t}\n\n\t\t\t\tlistenArrayEvents(data, me);\n\t\t\t\tme._data = data;\n\t\t\t}\n\n\t\t\t// Re-sync meta data in case the user replaced the data array or if we missed\n\t\t\t// any updates and so make sure that we handle number of datapoints changing.\n\t\t\tme.resyncElements();\n\t\t},\n\n\t\tupdate: helpers.noop,\n\n\t\ttransition: function(easingValue) {\n\t\t\tvar meta = this.getMeta();\n\t\t\tvar elements = meta.data || [];\n\t\t\tvar ilen = elements.length;\n\t\t\tvar i = 0;\n\n\t\t\tfor (; i<ilen; ++i) {\n\t\t\t\telements[i].transition(easingValue);\n\t\t\t}\n\n\t\t\tif (meta.dataset) {\n\t\t\t\tmeta.dataset.transition(easingValue);\n\t\t\t}\n\t\t},\n\n\t\tdraw: function() {\n\t\t\tvar meta = this.getMeta();\n\t\t\tvar elements = meta.data || [];\n\t\t\tvar ilen = elements.length;\n\t\t\tvar i = 0;\n\n\t\t\tif (meta.dataset) {\n\t\t\t\tmeta.dataset.draw();\n\t\t\t}\n\n\t\t\tfor (; i<ilen; ++i) {\n\t\t\t\telements[i].draw();\n\t\t\t}\n\t\t},\n\n\t\tremoveHoverStyle: function(element, elementOpts) {\n\t\t\tvar dataset = this.chart.data.datasets[element._datasetIndex],\n\t\t\t\tindex = element._index,\n\t\t\t\tcustom = element.custom || {},\n\t\t\t\tvalueOrDefault = helpers.getValueAtIndexOrDefault,\n\t\t\t\tmodel = element._model;\n\n\t\t\tmodel.backgroundColor = custom.backgroundColor ? custom.backgroundColor : valueOrDefault(dataset.backgroundColor, index, elementOpts.backgroundColor);\n\t\t\tmodel.borderColor = custom.borderColor ? custom.borderColor : valueOrDefault(dataset.borderColor, index, elementOpts.borderColor);\n\t\t\tmodel.borderWidth = custom.borderWidth ? custom.borderWidth : valueOrDefault(dataset.borderWidth, index, elementOpts.borderWidth);\n\t\t},\n\n\t\tsetHoverStyle: function(element) {\n\t\t\tvar dataset = this.chart.data.datasets[element._datasetIndex],\n\t\t\t\tindex = element._index,\n\t\t\t\tcustom = element.custom || {},\n\t\t\t\tvalueOrDefault = helpers.getValueAtIndexOrDefault,\n\t\t\t\tgetHoverColor = helpers.getHoverColor,\n\t\t\t\tmodel = element._model;\n\n\t\t\tmodel.backgroundColor = custom.hoverBackgroundColor ? custom.hoverBackgroundColor : valueOrDefault(dataset.hoverBackgroundColor, index, getHoverColor(model.backgroundColor));\n\t\t\tmodel.borderColor = custom.hoverBorderColor ? custom.hoverBorderColor : valueOrDefault(dataset.hoverBorderColor, index, getHoverColor(model.borderColor));\n\t\t\tmodel.borderWidth = custom.hoverBorderWidth ? custom.hoverBorderWidth : valueOrDefault(dataset.hoverBorderWidth, index, model.borderWidth);\n\t\t},\n\n\t\t/**\n\t\t * @private\n\t\t */\n\t\tresyncElements: function() {\n\t\t\tvar me = this;\n\t\t\tvar meta = me.getMeta();\n\t\t\tvar data = me.getDataset().data;\n\t\t\tvar numMeta = meta.data.length;\n\t\t\tvar numData = data.length;\n\n\t\t\tif (numData < numMeta) {\n\t\t\t\tmeta.data.splice(numData, numMeta - numData);\n\t\t\t} else if (numData > numMeta) {\n\t\t\t\tme.insertElements(numMeta, numData - numMeta);\n\t\t\t}\n\t\t},\n\n\t\t/**\n\t\t * @private\n\t\t */\n\t\tinsertElements: function(start, count) {\n\t\t\tfor (var i=0; i<count; ++i) {\n\t\t\t\tthis.addElementAndReset(start + i);\n\t\t\t}\n\t\t},\n\n\t\t/**\n\t\t * @private\n\t\t */\n\t\tonDataPush: function() {\n\t\t\tthis.insertElements(this.getDataset().data.length-1, arguments.length);\n\t\t},\n\n\t\t/**\n\t\t * @private\n\t\t */\n\t\tonDataPop: function() {\n\t\t\tthis.getMeta().data.pop();\n\t\t},\n\n\t\t/**\n\t\t * @private\n\t\t */\n\t\tonDataShift: function() {\n\t\t\tthis.getMeta().data.shift();\n\t\t},\n\n\t\t/**\n\t\t * @private\n\t\t */\n\t\tonDataSplice: function(start, count) {\n\t\t\tthis.getMeta().data.splice(start, count);\n\t\t\tthis.insertElements(start, arguments.length - 2);\n\t\t},\n\n\t\t/**\n\t\t * @private\n\t\t */\n\t\tonDataUnshift: function() {\n\t\t\tthis.insertElements(0, arguments.length);\n\t\t}\n\t});\n\n\tChart.DatasetController.extend = helpers.inherits;\n};\n"
  },
  {
    "path": "app_backend/static/plugin/Chart.js-2.6.0/src/core/core.element.js",
    "content": "'use strict';\n\nvar color = require('chartjs-color');\n\nmodule.exports = function(Chart) {\n\n\tvar helpers = Chart.helpers;\n\n\tfunction interpolate(start, view, model, ease) {\n\t\tvar keys = Object.keys(model);\n\t\tvar i, ilen, key, actual, origin, target, type, c0, c1;\n\n\t\tfor (i=0, ilen=keys.length; i<ilen; ++i) {\n\t\t\tkey = keys[i];\n\n\t\t\ttarget = model[key];\n\n\t\t\t// if a value is added to the model after pivot() has been called, the view\n\t\t\t// doesn't contain it, so let's initialize the view to the target value.\n\t\t\tif (!view.hasOwnProperty(key)) {\n\t\t\t\tview[key] = target;\n\t\t\t}\n\n\t\t\tactual = view[key];\n\n\t\t\tif (actual === target || key[0] === '_') {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tif (!start.hasOwnProperty(key)) {\n\t\t\t\tstart[key] = actual;\n\t\t\t}\n\n\t\t\torigin = start[key];\n\n\t\t\ttype = typeof(target);\n\n\t\t\tif (type === typeof(origin)) {\n\t\t\t\tif (type === 'string') {\n\t\t\t\t\tc0 = color(origin);\n\t\t\t\t\tif (c0.valid) {\n\t\t\t\t\t\tc1 = color(target);\n\t\t\t\t\t\tif (c1.valid) {\n\t\t\t\t\t\t\tview[key] = c1.mix(c0, ease).rgbString();\n\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t} else if (type === 'number' && isFinite(origin) && isFinite(target)) {\n\t\t\t\t\tview[key] = origin + (target - origin) * ease;\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tview[key] = target;\n\t\t}\n\t}\n\n\tChart.elements = {};\n\n\tChart.Element = function(configuration) {\n\t\thelpers.extend(this, configuration);\n\t\tthis.initialize.apply(this, arguments);\n\t};\n\n\thelpers.extend(Chart.Element.prototype, {\n\n\t\tinitialize: function() {\n\t\t\tthis.hidden = false;\n\t\t},\n\n\t\tpivot: function() {\n\t\t\tvar me = this;\n\t\t\tif (!me._view) {\n\t\t\t\tme._view = helpers.clone(me._model);\n\t\t\t}\n\t\t\tme._start = {};\n\t\t\treturn me;\n\t\t},\n\n\t\ttransition: function(ease) {\n\t\t\tvar me = this;\n\t\t\tvar model = me._model;\n\t\t\tvar start = me._start;\n\t\t\tvar view = me._view;\n\n\t\t\t// No animation -> No Transition\n\t\t\tif (!model || ease === 1) {\n\t\t\t\tme._view = model;\n\t\t\t\tme._start = null;\n\t\t\t\treturn me;\n\t\t\t}\n\n\t\t\tif (!view) {\n\t\t\t\tview = me._view = {};\n\t\t\t}\n\n\t\t\tif (!start) {\n\t\t\t\tstart = me._start = {};\n\t\t\t}\n\n\t\t\tinterpolate(start, view, model, ease);\n\n\t\t\treturn me;\n\t\t},\n\n\t\ttooltipPosition: function() {\n\t\t\treturn {\n\t\t\t\tx: this._model.x,\n\t\t\t\ty: this._model.y\n\t\t\t};\n\t\t},\n\n\t\thasValue: function() {\n\t\t\treturn helpers.isNumber(this._model.x) && helpers.isNumber(this._model.y);\n\t\t}\n\t});\n\n\tChart.Element.extend = helpers.inherits;\n};\n"
  },
  {
    "path": "app_backend/static/plugin/Chart.js-2.6.0/src/core/core.helpers.js",
    "content": "/* global window: false */\n/* global document: false */\n'use strict';\n\nvar color = require('chartjs-color');\n\nmodule.exports = function(Chart) {\n\t// Global Chart helpers object for utility methods and classes\n\tvar helpers = Chart.helpers = {};\n\n\t// -- Basic js utility methods\n\thelpers.each = function(loopable, callback, self, reverse) {\n\t\t// Check to see if null or undefined firstly.\n\t\tvar i, len;\n\t\tif (helpers.isArray(loopable)) {\n\t\t\tlen = loopable.length;\n\t\t\tif (reverse) {\n\t\t\t\tfor (i = len - 1; i >= 0; i--) {\n\t\t\t\t\tcallback.call(self, loopable[i], i);\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tfor (i = 0; i < len; i++) {\n\t\t\t\t\tcallback.call(self, loopable[i], i);\n\t\t\t\t}\n\t\t\t}\n\t\t} else if (typeof loopable === 'object') {\n\t\t\tvar keys = Object.keys(loopable);\n\t\t\tlen = keys.length;\n\t\t\tfor (i = 0; i < len; i++) {\n\t\t\t\tcallback.call(self, loopable[keys[i]], keys[i]);\n\t\t\t}\n\t\t}\n\t};\n\thelpers.clone = function(obj) {\n\t\tvar objClone = {};\n\t\thelpers.each(obj, function(value, key) {\n\t\t\tif (helpers.isArray(value)) {\n\t\t\t\tobjClone[key] = value.slice(0);\n\t\t\t} else if (typeof value === 'object' && value !== null) {\n\t\t\t\tobjClone[key] = helpers.clone(value);\n\t\t\t} else {\n\t\t\t\tobjClone[key] = value;\n\t\t\t}\n\t\t});\n\t\treturn objClone;\n\t};\n\thelpers.extend = function(base) {\n\t\tvar setFn = function(value, key) {\n\t\t\tbase[key] = value;\n\t\t};\n\t\tfor (var i = 1, ilen = arguments.length; i < ilen; i++) {\n\t\t\thelpers.each(arguments[i], setFn);\n\t\t}\n\t\treturn base;\n\t};\n\t// Need a special merge function to chart configs since they are now grouped\n\thelpers.configMerge = function(_base) {\n\t\tvar base = helpers.clone(_base);\n\t\thelpers.each(Array.prototype.slice.call(arguments, 1), function(extension) {\n\t\t\thelpers.each(extension, function(value, key) {\n\t\t\t\tvar baseHasProperty = base.hasOwnProperty(key);\n\t\t\t\tvar baseVal = baseHasProperty ? base[key] : {};\n\n\t\t\t\tif (key === 'scales') {\n\t\t\t\t\t// Scale config merging is complex. Add our own function here for that\n\t\t\t\t\tbase[key] = helpers.scaleMerge(baseVal, value);\n\t\t\t\t} else if (key === 'scale') {\n\t\t\t\t\t// Used in polar area & radar charts since there is only one scale\n\t\t\t\t\tbase[key] = helpers.configMerge(baseVal, Chart.scaleService.getScaleDefaults(value.type), value);\n\t\t\t\t} else if (baseHasProperty\n\t\t\t\t\t\t&& typeof baseVal === 'object'\n\t\t\t\t\t\t&& !helpers.isArray(baseVal)\n\t\t\t\t\t\t&& baseVal !== null\n\t\t\t\t\t\t&& typeof value === 'object'\n\t\t\t\t\t\t&& !helpers.isArray(value)) {\n\t\t\t\t\t// If we are overwriting an object with an object, do a merge of the properties.\n\t\t\t\t\tbase[key] = helpers.configMerge(baseVal, value);\n\t\t\t\t} else {\n\t\t\t\t\t// can just overwrite the value in this case\n\t\t\t\t\tbase[key] = value;\n\t\t\t\t}\n\t\t\t});\n\t\t});\n\n\t\treturn base;\n\t};\n\thelpers.scaleMerge = function(_base, extension) {\n\t\tvar base = helpers.clone(_base);\n\n\t\thelpers.each(extension, function(value, key) {\n\t\t\tif (key === 'xAxes' || key === 'yAxes') {\n\t\t\t\t// These properties are arrays of items\n\t\t\t\tif (base.hasOwnProperty(key)) {\n\t\t\t\t\thelpers.each(value, function(valueObj, index) {\n\t\t\t\t\t\tvar axisType = helpers.getValueOrDefault(valueObj.type, key === 'xAxes' ? 'category' : 'linear');\n\t\t\t\t\t\tvar axisDefaults = Chart.scaleService.getScaleDefaults(axisType);\n\t\t\t\t\t\tif (index >= base[key].length || !base[key][index].type) {\n\t\t\t\t\t\t\tbase[key].push(helpers.configMerge(axisDefaults, valueObj));\n\t\t\t\t\t\t} else if (valueObj.type && valueObj.type !== base[key][index].type) {\n\t\t\t\t\t\t\t// Type changed. Bring in the new defaults before we bring in valueObj so that valueObj can override the correct scale defaults\n\t\t\t\t\t\t\tbase[key][index] = helpers.configMerge(base[key][index], axisDefaults, valueObj);\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t// Type is the same\n\t\t\t\t\t\t\tbase[key][index] = helpers.configMerge(base[key][index], valueObj);\n\t\t\t\t\t\t}\n\t\t\t\t\t});\n\t\t\t\t} else {\n\t\t\t\t\tbase[key] = [];\n\t\t\t\t\thelpers.each(value, function(valueObj) {\n\t\t\t\t\t\tvar axisType = helpers.getValueOrDefault(valueObj.type, key === 'xAxes' ? 'category' : 'linear');\n\t\t\t\t\t\tbase[key].push(helpers.configMerge(Chart.scaleService.getScaleDefaults(axisType), valueObj));\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t} else if (base.hasOwnProperty(key) && typeof base[key] === 'object' && base[key] !== null && typeof value === 'object') {\n\t\t\t\t// If we are overwriting an object with an object, do a merge of the properties.\n\t\t\t\tbase[key] = helpers.configMerge(base[key], value);\n\n\t\t\t} else {\n\t\t\t\t// can just overwrite the value in this case\n\t\t\t\tbase[key] = value;\n\t\t\t}\n\t\t});\n\n\t\treturn base;\n\t};\n\thelpers.getValueAtIndexOrDefault = function(value, index, defaultValue) {\n\t\tif (value === undefined || value === null) {\n\t\t\treturn defaultValue;\n\t\t}\n\n\t\tif (helpers.isArray(value)) {\n\t\t\treturn index < value.length ? value[index] : defaultValue;\n\t\t}\n\n\t\treturn value;\n\t};\n\thelpers.getValueOrDefault = function(value, defaultValue) {\n\t\treturn value === undefined ? defaultValue : value;\n\t};\n\thelpers.indexOf = Array.prototype.indexOf?\n\t\tfunction(array, item) {\n\t\t\treturn array.indexOf(item);\n\t\t}:\n\t\tfunction(array, item) {\n\t\t\tfor (var i = 0, ilen = array.length; i < ilen; ++i) {\n\t\t\t\tif (array[i] === item) {\n\t\t\t\t\treturn i;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn -1;\n\t\t};\n\thelpers.where = function(collection, filterCallback) {\n\t\tif (helpers.isArray(collection) && Array.prototype.filter) {\n\t\t\treturn collection.filter(filterCallback);\n\t\t}\n\t\tvar filtered = [];\n\n\t\thelpers.each(collection, function(item) {\n\t\t\tif (filterCallback(item)) {\n\t\t\t\tfiltered.push(item);\n\t\t\t}\n\t\t});\n\n\t\treturn filtered;\n\t};\n\thelpers.findIndex = Array.prototype.findIndex?\n\t\tfunction(array, callback, scope) {\n\t\t\treturn array.findIndex(callback, scope);\n\t\t} :\n\t\tfunction(array, callback, scope) {\n\t\t\tscope = scope === undefined? array : scope;\n\t\t\tfor (var i = 0, ilen = array.length; i < ilen; ++i) {\n\t\t\t\tif (callback.call(scope, array[i], i, array)) {\n\t\t\t\t\treturn i;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn -1;\n\t\t};\n\thelpers.findNextWhere = function(arrayToSearch, filterCallback, startIndex) {\n\t\t// Default to start of the array\n\t\tif (startIndex === undefined || startIndex === null) {\n\t\t\tstartIndex = -1;\n\t\t}\n\t\tfor (var i = startIndex + 1; i < arrayToSearch.length; i++) {\n\t\t\tvar currentItem = arrayToSearch[i];\n\t\t\tif (filterCallback(currentItem)) {\n\t\t\t\treturn currentItem;\n\t\t\t}\n\t\t}\n\t};\n\thelpers.findPreviousWhere = function(arrayToSearch, filterCallback, startIndex) {\n\t\t// Default to end of the array\n\t\tif (startIndex === undefined || startIndex === null) {\n\t\t\tstartIndex = arrayToSearch.length;\n\t\t}\n\t\tfor (var i = startIndex - 1; i >= 0; i--) {\n\t\t\tvar currentItem = arrayToSearch[i];\n\t\t\tif (filterCallback(currentItem)) {\n\t\t\t\treturn currentItem;\n\t\t\t}\n\t\t}\n\t};\n\thelpers.inherits = function(extensions) {\n\t\t// Basic javascript inheritance based on the model created in Backbone.js\n\t\tvar me = this;\n\t\tvar ChartElement = (extensions && extensions.hasOwnProperty('constructor')) ? extensions.constructor : function() {\n\t\t\treturn me.apply(this, arguments);\n\t\t};\n\n\t\tvar Surrogate = function() {\n\t\t\tthis.constructor = ChartElement;\n\t\t};\n\t\tSurrogate.prototype = me.prototype;\n\t\tChartElement.prototype = new Surrogate();\n\n\t\tChartElement.extend = helpers.inherits;\n\n\t\tif (extensions) {\n\t\t\thelpers.extend(ChartElement.prototype, extensions);\n\t\t}\n\n\t\tChartElement.__super__ = me.prototype;\n\n\t\treturn ChartElement;\n\t};\n\thelpers.noop = function() {};\n\thelpers.uid = (function() {\n\t\tvar id = 0;\n\t\treturn function() {\n\t\t\treturn id++;\n\t\t};\n\t}());\n\t// -- Math methods\n\thelpers.isNumber = function(n) {\n\t\treturn !isNaN(parseFloat(n)) && isFinite(n);\n\t};\n\thelpers.almostEquals = function(x, y, epsilon) {\n\t\treturn Math.abs(x - y) < epsilon;\n\t};\n\thelpers.almostWhole = function(x, epsilon) {\n\t\tvar rounded = Math.round(x);\n\t\treturn (((rounded - epsilon) < x) && ((rounded + epsilon) > x));\n\t};\n\thelpers.max = function(array) {\n\t\treturn array.reduce(function(max, value) {\n\t\t\tif (!isNaN(value)) {\n\t\t\t\treturn Math.max(max, value);\n\t\t\t}\n\t\t\treturn max;\n\t\t}, Number.NEGATIVE_INFINITY);\n\t};\n\thelpers.min = function(array) {\n\t\treturn array.reduce(function(min, value) {\n\t\t\tif (!isNaN(value)) {\n\t\t\t\treturn Math.min(min, value);\n\t\t\t}\n\t\t\treturn min;\n\t\t}, Number.POSITIVE_INFINITY);\n\t};\n\thelpers.sign = Math.sign?\n\t\tfunction(x) {\n\t\t\treturn Math.sign(x);\n\t\t} :\n\t\tfunction(x) {\n\t\t\tx = +x; // convert to a number\n\t\t\tif (x === 0 || isNaN(x)) {\n\t\t\t\treturn x;\n\t\t\t}\n\t\t\treturn x > 0 ? 1 : -1;\n\t\t};\n\thelpers.log10 = Math.log10?\n\t\tfunction(x) {\n\t\t\treturn Math.log10(x);\n\t\t} :\n\t\tfunction(x) {\n\t\t\treturn Math.log(x) / Math.LN10;\n\t\t};\n\thelpers.toRadians = function(degrees) {\n\t\treturn degrees * (Math.PI / 180);\n\t};\n\thelpers.toDegrees = function(radians) {\n\t\treturn radians * (180 / Math.PI);\n\t};\n\t// Gets the angle from vertical upright to the point about a centre.\n\thelpers.getAngleFromPoint = function(centrePoint, anglePoint) {\n\t\tvar distanceFromXCenter = anglePoint.x - centrePoint.x,\n\t\t\tdistanceFromYCenter = anglePoint.y - centrePoint.y,\n\t\t\tradialDistanceFromCenter = Math.sqrt(distanceFromXCenter * distanceFromXCenter + distanceFromYCenter * distanceFromYCenter);\n\n\t\tvar angle = Math.atan2(distanceFromYCenter, distanceFromXCenter);\n\n\t\tif (angle < (-0.5 * Math.PI)) {\n\t\t\tangle += 2.0 * Math.PI; // make sure the returned angle is in the range of (-PI/2, 3PI/2]\n\t\t}\n\n\t\treturn {\n\t\t\tangle: angle,\n\t\t\tdistance: radialDistanceFromCenter\n\t\t};\n\t};\n\thelpers.distanceBetweenPoints = function(pt1, pt2) {\n\t\treturn Math.sqrt(Math.pow(pt2.x - pt1.x, 2) + Math.pow(pt2.y - pt1.y, 2));\n\t};\n\thelpers.aliasPixel = function(pixelWidth) {\n\t\treturn (pixelWidth % 2 === 0) ? 0 : 0.5;\n\t};\n\thelpers.splineCurve = function(firstPoint, middlePoint, afterPoint, t) {\n\t\t// Props to Rob Spencer at scaled innovation for his post on splining between points\n\t\t// http://scaledinnovation.com/analytics/splines/aboutSplines.html\n\n\t\t// This function must also respect \"skipped\" points\n\n\t\tvar previous = firstPoint.skip ? middlePoint : firstPoint,\n\t\t\tcurrent = middlePoint,\n\t\t\tnext = afterPoint.skip ? middlePoint : afterPoint;\n\n\t\tvar d01 = Math.sqrt(Math.pow(current.x - previous.x, 2) + Math.pow(current.y - previous.y, 2));\n\t\tvar d12 = Math.sqrt(Math.pow(next.x - current.x, 2) + Math.pow(next.y - current.y, 2));\n\n\t\tvar s01 = d01 / (d01 + d12);\n\t\tvar s12 = d12 / (d01 + d12);\n\n\t\t// If all points are the same, s01 & s02 will be inf\n\t\ts01 = isNaN(s01) ? 0 : s01;\n\t\ts12 = isNaN(s12) ? 0 : s12;\n\n\t\tvar fa = t * s01; // scaling factor for triangle Ta\n\t\tvar fb = t * s12;\n\n\t\treturn {\n\t\t\tprevious: {\n\t\t\t\tx: current.x - fa * (next.x - previous.x),\n\t\t\t\ty: current.y - fa * (next.y - previous.y)\n\t\t\t},\n\t\t\tnext: {\n\t\t\t\tx: current.x + fb * (next.x - previous.x),\n\t\t\t\ty: current.y + fb * (next.y - previous.y)\n\t\t\t}\n\t\t};\n\t};\n\thelpers.EPSILON = Number.EPSILON || 1e-14;\n\thelpers.splineCurveMonotone = function(points) {\n\t\t// This function calculates Bézier control points in a similar way than |splineCurve|,\n\t\t// but preserves monotonicity of the provided data and ensures no local extremums are added\n\t\t// between the dataset discrete points due to the interpolation.\n\t\t// See : https://en.wikipedia.org/wiki/Monotone_cubic_interpolation\n\n\t\tvar pointsWithTangents = (points || []).map(function(point) {\n\t\t\treturn {\n\t\t\t\tmodel: point._model,\n\t\t\t\tdeltaK: 0,\n\t\t\t\tmK: 0\n\t\t\t};\n\t\t});\n\n\t\t// Calculate slopes (deltaK) and initialize tangents (mK)\n\t\tvar pointsLen = pointsWithTangents.length;\n\t\tvar i, pointBefore, pointCurrent, pointAfter;\n\t\tfor (i = 0; i < pointsLen; ++i) {\n\t\t\tpointCurrent = pointsWithTangents[i];\n\t\t\tif (pointCurrent.model.skip) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tpointBefore = i > 0 ? pointsWithTangents[i - 1] : null;\n\t\t\tpointAfter = i < pointsLen - 1 ? pointsWithTangents[i + 1] : null;\n\t\t\tif (pointAfter && !pointAfter.model.skip) {\n\t\t\t\tvar slopeDeltaX = (pointAfter.model.x - pointCurrent.model.x);\n\n\t\t\t\t// In the case of two points that appear at the same x pixel, slopeDeltaX is 0\n\t\t\t\tpointCurrent.deltaK = slopeDeltaX !== 0 ? (pointAfter.model.y - pointCurrent.model.y) / slopeDeltaX : 0;\n\t\t\t}\n\n\t\t\tif (!pointBefore || pointBefore.model.skip) {\n\t\t\t\tpointCurrent.mK = pointCurrent.deltaK;\n\t\t\t} else if (!pointAfter || pointAfter.model.skip) {\n\t\t\t\tpointCurrent.mK = pointBefore.deltaK;\n\t\t\t} else if (this.sign(pointBefore.deltaK) !== this.sign(pointCurrent.deltaK)) {\n\t\t\t\tpointCurrent.mK = 0;\n\t\t\t} else {\n\t\t\t\tpointCurrent.mK = (pointBefore.deltaK + pointCurrent.deltaK) / 2;\n\t\t\t}\n\t\t}\n\n\t\t// Adjust tangents to ensure monotonic properties\n\t\tvar alphaK, betaK, tauK, squaredMagnitude;\n\t\tfor (i = 0; i < pointsLen - 1; ++i) {\n\t\t\tpointCurrent = pointsWithTangents[i];\n\t\t\tpointAfter = pointsWithTangents[i + 1];\n\t\t\tif (pointCurrent.model.skip || pointAfter.model.skip) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tif (helpers.almostEquals(pointCurrent.deltaK, 0, this.EPSILON)) {\n\t\t\t\tpointCurrent.mK = pointAfter.mK = 0;\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\talphaK = pointCurrent.mK / pointCurrent.deltaK;\n\t\t\tbetaK = pointAfter.mK / pointCurrent.deltaK;\n\t\t\tsquaredMagnitude = Math.pow(alphaK, 2) + Math.pow(betaK, 2);\n\t\t\tif (squaredMagnitude <= 9) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\ttauK = 3 / Math.sqrt(squaredMagnitude);\n\t\t\tpointCurrent.mK = alphaK * tauK * pointCurrent.deltaK;\n\t\t\tpointAfter.mK = betaK * tauK * pointCurrent.deltaK;\n\t\t}\n\n\t\t// Compute control points\n\t\tvar deltaX;\n\t\tfor (i = 0; i < pointsLen; ++i) {\n\t\t\tpointCurrent = pointsWithTangents[i];\n\t\t\tif (pointCurrent.model.skip) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tpointBefore = i > 0 ? pointsWithTangents[i - 1] : null;\n\t\t\tpointAfter = i < pointsLen - 1 ? pointsWithTangents[i + 1] : null;\n\t\t\tif (pointBefore && !pointBefore.model.skip) {\n\t\t\t\tdeltaX = (pointCurrent.model.x - pointBefore.model.x) / 3;\n\t\t\t\tpointCurrent.model.controlPointPreviousX = pointCurrent.model.x - deltaX;\n\t\t\t\tpointCurrent.model.controlPointPreviousY = pointCurrent.model.y - deltaX * pointCurrent.mK;\n\t\t\t}\n\t\t\tif (pointAfter && !pointAfter.model.skip) {\n\t\t\t\tdeltaX = (pointAfter.model.x - pointCurrent.model.x) / 3;\n\t\t\t\tpointCurrent.model.controlPointNextX = pointCurrent.model.x + deltaX;\n\t\t\t\tpointCurrent.model.controlPointNextY = pointCurrent.model.y + deltaX * pointCurrent.mK;\n\t\t\t}\n\t\t}\n\t};\n\thelpers.nextItem = function(collection, index, loop) {\n\t\tif (loop) {\n\t\t\treturn index >= collection.length - 1 ? collection[0] : collection[index + 1];\n\t\t}\n\t\treturn index >= collection.length - 1 ? collection[collection.length - 1] : collection[index + 1];\n\t};\n\thelpers.previousItem = function(collection, index, loop) {\n\t\tif (loop) {\n\t\t\treturn index <= 0 ? collection[collection.length - 1] : collection[index - 1];\n\t\t}\n\t\treturn index <= 0 ? collection[0] : collection[index - 1];\n\t};\n\t// Implementation of the nice number algorithm used in determining where axis labels will go\n\thelpers.niceNum = function(range, round) {\n\t\tvar exponent = Math.floor(helpers.log10(range));\n\t\tvar fraction = range / Math.pow(10, exponent);\n\t\tvar niceFraction;\n\n\t\tif (round) {\n\t\t\tif (fraction < 1.5) {\n\t\t\t\tniceFraction = 1;\n\t\t\t} else if (fraction < 3) {\n\t\t\t\tniceFraction = 2;\n\t\t\t} else if (fraction < 7) {\n\t\t\t\tniceFraction = 5;\n\t\t\t} else {\n\t\t\t\tniceFraction = 10;\n\t\t\t}\n\t\t} else if (fraction <= 1.0) {\n\t\t\tniceFraction = 1;\n\t\t} else if (fraction <= 2) {\n\t\t\tniceFraction = 2;\n\t\t} else if (fraction <= 5) {\n\t\t\tniceFraction = 5;\n\t\t} else {\n\t\t\tniceFraction = 10;\n\t\t}\n\n\t\treturn niceFraction * Math.pow(10, exponent);\n\t};\n\t// Easing functions adapted from Robert Penner's easing equations\n\t// http://www.robertpenner.com/easing/\n\tvar easingEffects = helpers.easingEffects = {\n\t\tlinear: function(t) {\n\t\t\treturn t;\n\t\t},\n\t\teaseInQuad: function(t) {\n\t\t\treturn t * t;\n\t\t},\n\t\teaseOutQuad: function(t) {\n\t\t\treturn -1 * t * (t - 2);\n\t\t},\n\t\teaseInOutQuad: function(t) {\n\t\t\tif ((t /= 1 / 2) < 1) {\n\t\t\t\treturn 1 / 2 * t * t;\n\t\t\t}\n\t\t\treturn -1 / 2 * ((--t) * (t - 2) - 1);\n\t\t},\n\t\teaseInCubic: function(t) {\n\t\t\treturn t * t * t;\n\t\t},\n\t\teaseOutCubic: function(t) {\n\t\t\treturn 1 * ((t = t / 1 - 1) * t * t + 1);\n\t\t},\n\t\teaseInOutCubic: function(t) {\n\t\t\tif ((t /= 1 / 2) < 1) {\n\t\t\t\treturn 1 / 2 * t * t * t;\n\t\t\t}\n\t\t\treturn 1 / 2 * ((t -= 2) * t * t + 2);\n\t\t},\n\t\teaseInQuart: function(t) {\n\t\t\treturn t * t * t * t;\n\t\t},\n\t\teaseOutQuart: function(t) {\n\t\t\treturn -1 * ((t = t / 1 - 1) * t * t * t - 1);\n\t\t},\n\t\teaseInOutQuart: function(t) {\n\t\t\tif ((t /= 1 / 2) < 1) {\n\t\t\t\treturn 1 / 2 * t * t * t * t;\n\t\t\t}\n\t\t\treturn -1 / 2 * ((t -= 2) * t * t * t - 2);\n\t\t},\n\t\teaseInQuint: function(t) {\n\t\t\treturn 1 * (t /= 1) * t * t * t * t;\n\t\t},\n\t\teaseOutQuint: function(t) {\n\t\t\treturn 1 * ((t = t / 1 - 1) * t * t * t * t + 1);\n\t\t},\n\t\teaseInOutQuint: function(t) {\n\t\t\tif ((t /= 1 / 2) < 1) {\n\t\t\t\treturn 1 / 2 * t * t * t * t * t;\n\t\t\t}\n\t\t\treturn 1 / 2 * ((t -= 2) * t * t * t * t + 2);\n\t\t},\n\t\teaseInSine: function(t) {\n\t\t\treturn -1 * Math.cos(t / 1 * (Math.PI / 2)) + 1;\n\t\t},\n\t\teaseOutSine: function(t) {\n\t\t\treturn 1 * Math.sin(t / 1 * (Math.PI / 2));\n\t\t},\n\t\teaseInOutSine: function(t) {\n\t\t\treturn -1 / 2 * (Math.cos(Math.PI * t / 1) - 1);\n\t\t},\n\t\teaseInExpo: function(t) {\n\t\t\treturn (t === 0) ? 1 : 1 * Math.pow(2, 10 * (t / 1 - 1));\n\t\t},\n\t\teaseOutExpo: function(t) {\n\t\t\treturn (t === 1) ? 1 : 1 * (-Math.pow(2, -10 * t / 1) + 1);\n\t\t},\n\t\teaseInOutExpo: function(t) {\n\t\t\tif (t === 0) {\n\t\t\t\treturn 0;\n\t\t\t}\n\t\t\tif (t === 1) {\n\t\t\t\treturn 1;\n\t\t\t}\n\t\t\tif ((t /= 1 / 2) < 1) {\n\t\t\t\treturn 1 / 2 * Math.pow(2, 10 * (t - 1));\n\t\t\t}\n\t\t\treturn 1 / 2 * (-Math.pow(2, -10 * --t) + 2);\n\t\t},\n\t\teaseInCirc: function(t) {\n\t\t\tif (t >= 1) {\n\t\t\t\treturn t;\n\t\t\t}\n\t\t\treturn -1 * (Math.sqrt(1 - (t /= 1) * t) - 1);\n\t\t},\n\t\teaseOutCirc: function(t) {\n\t\t\treturn 1 * Math.sqrt(1 - (t = t / 1 - 1) * t);\n\t\t},\n\t\teaseInOutCirc: function(t) {\n\t\t\tif ((t /= 1 / 2) < 1) {\n\t\t\t\treturn -1 / 2 * (Math.sqrt(1 - t * t) - 1);\n\t\t\t}\n\t\t\treturn 1 / 2 * (Math.sqrt(1 - (t -= 2) * t) + 1);\n\t\t},\n\t\teaseInElastic: function(t) {\n\t\t\tvar s = 1.70158;\n\t\t\tvar p = 0;\n\t\t\tvar a = 1;\n\t\t\tif (t === 0) {\n\t\t\t\treturn 0;\n\t\t\t}\n\t\t\tif ((t /= 1) === 1) {\n\t\t\t\treturn 1;\n\t\t\t}\n\t\t\tif (!p) {\n\t\t\t\tp = 1 * 0.3;\n\t\t\t}\n\t\t\tif (a < Math.abs(1)) {\n\t\t\t\ta = 1;\n\t\t\t\ts = p / 4;\n\t\t\t} else {\n\t\t\t\ts = p / (2 * Math.PI) * Math.asin(1 / a);\n\t\t\t}\n\t\t\treturn -(a * Math.pow(2, 10 * (t -= 1)) * Math.sin((t * 1 - s) * (2 * Math.PI) / p));\n\t\t},\n\t\teaseOutElastic: function(t) {\n\t\t\tvar s = 1.70158;\n\t\t\tvar p = 0;\n\t\t\tvar a = 1;\n\t\t\tif (t === 0) {\n\t\t\t\treturn 0;\n\t\t\t}\n\t\t\tif ((t /= 1) === 1) {\n\t\t\t\treturn 1;\n\t\t\t}\n\t\t\tif (!p) {\n\t\t\t\tp = 1 * 0.3;\n\t\t\t}\n\t\t\tif (a < Math.abs(1)) {\n\t\t\t\ta = 1;\n\t\t\t\ts = p / 4;\n\t\t\t} else {\n\t\t\t\ts = p / (2 * Math.PI) * Math.asin(1 / a);\n\t\t\t}\n\t\t\treturn a * Math.pow(2, -10 * t) * Math.sin((t * 1 - s) * (2 * Math.PI) / p) + 1;\n\t\t},\n\t\teaseInOutElastic: function(t) {\n\t\t\tvar s = 1.70158;\n\t\t\tvar p = 0;\n\t\t\tvar a = 1;\n\t\t\tif (t === 0) {\n\t\t\t\treturn 0;\n\t\t\t}\n\t\t\tif ((t /= 1 / 2) === 2) {\n\t\t\t\treturn 1;\n\t\t\t}\n\t\t\tif (!p) {\n\t\t\t\tp = 1 * (0.3 * 1.5);\n\t\t\t}\n\t\t\tif (a < Math.abs(1)) {\n\t\t\t\ta = 1;\n\t\t\t\ts = p / 4;\n\t\t\t} else {\n\t\t\t\ts = p / (2 * Math.PI) * Math.asin(1 / a);\n\t\t\t}\n\t\t\tif (t < 1) {\n\t\t\t\treturn -0.5 * (a * Math.pow(2, 10 * (t -= 1)) * Math.sin((t * 1 - s) * (2 * Math.PI) / p));\n\t\t\t}\n\t\t\treturn a * Math.pow(2, -10 * (t -= 1)) * Math.sin((t * 1 - s) * (2 * Math.PI) / p) * 0.5 + 1;\n\t\t},\n\t\teaseInBack: function(t) {\n\t\t\tvar s = 1.70158;\n\t\t\treturn 1 * (t /= 1) * t * ((s + 1) * t - s);\n\t\t},\n\t\teaseOutBack: function(t) {\n\t\t\tvar s = 1.70158;\n\t\t\treturn 1 * ((t = t / 1 - 1) * t * ((s + 1) * t + s) + 1);\n\t\t},\n\t\teaseInOutBack: function(t) {\n\t\t\tvar s = 1.70158;\n\t\t\tif ((t /= 1 / 2) < 1) {\n\t\t\t\treturn 1 / 2 * (t * t * (((s *= (1.525)) + 1) * t - s));\n\t\t\t}\n\t\t\treturn 1 / 2 * ((t -= 2) * t * (((s *= (1.525)) + 1) * t + s) + 2);\n\t\t},\n\t\teaseInBounce: function(t) {\n\t\t\treturn 1 - easingEffects.easeOutBounce(1 - t);\n\t\t},\n\t\teaseOutBounce: function(t) {\n\t\t\tif ((t /= 1) < (1 / 2.75)) {\n\t\t\t\treturn 1 * (7.5625 * t * t);\n\t\t\t} else if (t < (2 / 2.75)) {\n\t\t\t\treturn 1 * (7.5625 * (t -= (1.5 / 2.75)) * t + 0.75);\n\t\t\t} else if (t < (2.5 / 2.75)) {\n\t\t\t\treturn 1 * (7.5625 * (t -= (2.25 / 2.75)) * t + 0.9375);\n\t\t\t}\n\t\t\treturn 1 * (7.5625 * (t -= (2.625 / 2.75)) * t + 0.984375);\n\t\t},\n\t\teaseInOutBounce: function(t) {\n\t\t\tif (t < 1 / 2) {\n\t\t\t\treturn easingEffects.easeInBounce(t * 2) * 0.5;\n\t\t\t}\n\t\t\treturn easingEffects.easeOutBounce(t * 2 - 1) * 0.5 + 1 * 0.5;\n\t\t}\n\t};\n\t// Request animation polyfill - http://www.paulirish.com/2011/requestanimationframe-for-smart-animating/\n\thelpers.requestAnimFrame = (function() {\n\t\tif (typeof window === 'undefined') {\n\t\t\treturn function(callback) {\n\t\t\t\tcallback();\n\t\t\t};\n\t\t}\n\t\treturn window.requestAnimationFrame ||\n\t\t\twindow.webkitRequestAnimationFrame ||\n\t\t\twindow.mozRequestAnimationFrame ||\n\t\t\twindow.oRequestAnimationFrame ||\n\t\t\twindow.msRequestAnimationFrame ||\n\t\t\tfunction(callback) {\n\t\t\t\treturn window.setTimeout(callback, 1000 / 60);\n\t\t\t};\n\t}());\n\t// -- DOM methods\n\thelpers.getRelativePosition = function(evt, chart) {\n\t\tvar mouseX, mouseY;\n\t\tvar e = evt.originalEvent || evt,\n\t\t\tcanvas = evt.currentTarget || evt.srcElement,\n\t\t\tboundingRect = canvas.getBoundingClientRect();\n\n\t\tvar touches = e.touches;\n\t\tif (touches && touches.length > 0) {\n\t\t\tmouseX = touches[0].clientX;\n\t\t\tmouseY = touches[0].clientY;\n\n\t\t} else {\n\t\t\tmouseX = e.clientX;\n\t\t\tmouseY = e.clientY;\n\t\t}\n\n\t\t// Scale mouse coordinates into canvas coordinates\n\t\t// by following the pattern laid out by 'jerryj' in the comments of\n\t\t// http://www.html5canvastutorials.com/advanced/html5-canvas-mouse-coordinates/\n\t\tvar paddingLeft = parseFloat(helpers.getStyle(canvas, 'padding-left'));\n\t\tvar paddingTop = parseFloat(helpers.getStyle(canvas, 'padding-top'));\n\t\tvar paddingRight = parseFloat(helpers.getStyle(canvas, 'padding-right'));\n\t\tvar paddingBottom = parseFloat(helpers.getStyle(canvas, 'padding-bottom'));\n\t\tvar width = boundingRect.right - boundingRect.left - paddingLeft - paddingRight;\n\t\tvar height = boundingRect.bottom - boundingRect.top - paddingTop - paddingBottom;\n\n\t\t// We divide by the current device pixel ratio, because the canvas is scaled up by that amount in each direction. However\n\t\t// the backend model is in unscaled coordinates. Since we are going to deal with our model coordinates, we go back here\n\t\tmouseX = Math.round((mouseX - boundingRect.left - paddingLeft) / (width) * canvas.width / chart.currentDevicePixelRatio);\n\t\tmouseY = Math.round((mouseY - boundingRect.top - paddingTop) / (height) * canvas.height / chart.currentDevicePixelRatio);\n\n\t\treturn {\n\t\t\tx: mouseX,\n\t\t\ty: mouseY\n\t\t};\n\n\t};\n\thelpers.addEvent = function(node, eventType, method) {\n\t\tif (node.addEventListener) {\n\t\t\tnode.addEventListener(eventType, method);\n\t\t} else if (node.attachEvent) {\n\t\t\tnode.attachEvent('on' + eventType, method);\n\t\t} else {\n\t\t\tnode['on' + eventType] = method;\n\t\t}\n\t};\n\thelpers.removeEvent = function(node, eventType, handler) {\n\t\tif (node.removeEventListener) {\n\t\t\tnode.removeEventListener(eventType, handler, false);\n\t\t} else if (node.detachEvent) {\n\t\t\tnode.detachEvent('on' + eventType, handler);\n\t\t} else {\n\t\t\tnode['on' + eventType] = helpers.noop;\n\t\t}\n\t};\n\n\t// Private helper function to convert max-width/max-height values that may be percentages into a number\n\tfunction parseMaxStyle(styleValue, node, parentProperty) {\n\t\tvar valueInPixels;\n\t\tif (typeof(styleValue) === 'string') {\n\t\t\tvalueInPixels = parseInt(styleValue, 10);\n\n\t\t\tif (styleValue.indexOf('%') !== -1) {\n\t\t\t\t// percentage * size in dimension\n\t\t\t\tvalueInPixels = valueInPixels / 100 * node.parentNode[parentProperty];\n\t\t\t}\n\t\t} else {\n\t\t\tvalueInPixels = styleValue;\n\t\t}\n\n\t\treturn valueInPixels;\n\t}\n\n\t/**\n\t * Returns if the given value contains an effective constraint.\n\t * @private\n\t */\n\tfunction isConstrainedValue(value) {\n\t\treturn value !== undefined && value !== null && value !== 'none';\n\t}\n\n\t// Private helper to get a constraint dimension\n\t// @param domNode : the node to check the constraint on\n\t// @param maxStyle : the style that defines the maximum for the direction we are using (maxWidth / maxHeight)\n\t// @param percentageProperty : property of parent to use when calculating width as a percentage\n\t// @see http://www.nathanaeljones.com/blog/2013/reading-max-width-cross-browser\n\tfunction getConstraintDimension(domNode, maxStyle, percentageProperty) {\n\t\tvar view = document.defaultView;\n\t\tvar parentNode = domNode.parentNode;\n\t\tvar constrainedNode = view.getComputedStyle(domNode)[maxStyle];\n\t\tvar constrainedContainer = view.getComputedStyle(parentNode)[maxStyle];\n\t\tvar hasCNode = isConstrainedValue(constrainedNode);\n\t\tvar hasCContainer = isConstrainedValue(constrainedContainer);\n\t\tvar infinity = Number.POSITIVE_INFINITY;\n\n\t\tif (hasCNode || hasCContainer) {\n\t\t\treturn Math.min(\n\t\t\t\thasCNode? parseMaxStyle(constrainedNode, domNode, percentageProperty) : infinity,\n\t\t\t\thasCContainer? parseMaxStyle(constrainedContainer, parentNode, percentageProperty) : infinity);\n\t\t}\n\n\t\treturn 'none';\n\t}\n\t// returns Number or undefined if no constraint\n\thelpers.getConstraintWidth = function(domNode) {\n\t\treturn getConstraintDimension(domNode, 'max-width', 'clientWidth');\n\t};\n\t// returns Number or undefined if no constraint\n\thelpers.getConstraintHeight = function(domNode) {\n\t\treturn getConstraintDimension(domNode, 'max-height', 'clientHeight');\n\t};\n\thelpers.getMaximumWidth = function(domNode) {\n\t\tvar container = domNode.parentNode;\n\t\tvar paddingLeft = parseInt(helpers.getStyle(container, 'padding-left'), 10);\n\t\tvar paddingRight = parseInt(helpers.getStyle(container, 'padding-right'), 10);\n\t\tvar w = container.clientWidth - paddingLeft - paddingRight;\n\t\tvar cw = helpers.getConstraintWidth(domNode);\n\t\treturn isNaN(cw)? w : Math.min(w, cw);\n\t};\n\thelpers.getMaximumHeight = function(domNode) {\n\t\tvar container = domNode.parentNode;\n\t\tvar paddingTop = parseInt(helpers.getStyle(container, 'padding-top'), 10);\n\t\tvar paddingBottom = parseInt(helpers.getStyle(container, 'padding-bottom'), 10);\n\t\tvar h = container.clientHeight - paddingTop - paddingBottom;\n\t\tvar ch = helpers.getConstraintHeight(domNode);\n\t\treturn isNaN(ch)? h : Math.min(h, ch);\n\t};\n\thelpers.getStyle = function(el, property) {\n\t\treturn el.currentStyle ?\n\t\t\tel.currentStyle[property] :\n\t\t\tdocument.defaultView.getComputedStyle(el, null).getPropertyValue(property);\n\t};\n\thelpers.retinaScale = function(chart) {\n\t\tvar pixelRatio = chart.currentDevicePixelRatio = window.devicePixelRatio || 1;\n\t\tif (pixelRatio === 1) {\n\t\t\treturn;\n\t\t}\n\n\t\tvar canvas = chart.canvas;\n\t\tvar height = chart.height;\n\t\tvar width = chart.width;\n\n\t\tcanvas.height = height * pixelRatio;\n\t\tcanvas.width = width * pixelRatio;\n\t\tchart.ctx.scale(pixelRatio, pixelRatio);\n\n\t\t// If no style has been set on the canvas, the render size is used as display size,\n\t\t// making the chart visually bigger, so let's enforce it to the \"correct\" values.\n\t\t// See https://github.com/chartjs/Chart.js/issues/3575\n\t\tcanvas.style.height = height + 'px';\n\t\tcanvas.style.width = width + 'px';\n\t};\n\t// -- Canvas methods\n\thelpers.clear = function(chart) {\n\t\tchart.ctx.clearRect(0, 0, chart.width, chart.height);\n\t};\n\thelpers.fontString = function(pixelSize, fontStyle, fontFamily) {\n\t\treturn fontStyle + ' ' + pixelSize + 'px ' + fontFamily;\n\t};\n\thelpers.longestText = function(ctx, font, arrayOfThings, cache) {\n\t\tcache = cache || {};\n\t\tvar data = cache.data = cache.data || {};\n\t\tvar gc = cache.garbageCollect = cache.garbageCollect || [];\n\n\t\tif (cache.font !== font) {\n\t\t\tdata = cache.data = {};\n\t\t\tgc = cache.garbageCollect = [];\n\t\t\tcache.font = font;\n\t\t}\n\n\t\tctx.font = font;\n\t\tvar longest = 0;\n\t\thelpers.each(arrayOfThings, function(thing) {\n\t\t\t// Undefined strings and arrays should not be measured\n\t\t\tif (thing !== undefined && thing !== null && helpers.isArray(thing) !== true) {\n\t\t\t\tlongest = helpers.measureText(ctx, data, gc, longest, thing);\n\t\t\t} else if (helpers.isArray(thing)) {\n\t\t\t\t// if it is an array lets measure each element\n\t\t\t\t// to do maybe simplify this function a bit so we can do this more recursively?\n\t\t\t\thelpers.each(thing, function(nestedThing) {\n\t\t\t\t\t// Undefined strings and arrays should not be measured\n\t\t\t\t\tif (nestedThing !== undefined && nestedThing !== null && !helpers.isArray(nestedThing)) {\n\t\t\t\t\t\tlongest = helpers.measureText(ctx, data, gc, longest, nestedThing);\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t}\n\t\t});\n\n\t\tvar gcLen = gc.length / 2;\n\t\tif (gcLen > arrayOfThings.length) {\n\t\t\tfor (var i = 0; i < gcLen; i++) {\n\t\t\t\tdelete data[gc[i]];\n\t\t\t}\n\t\t\tgc.splice(0, gcLen);\n\t\t}\n\t\treturn longest;\n\t};\n\thelpers.measureText = function(ctx, data, gc, longest, string) {\n\t\tvar textWidth = data[string];\n\t\tif (!textWidth) {\n\t\t\ttextWidth = data[string] = ctx.measureText(string).width;\n\t\t\tgc.push(string);\n\t\t}\n\t\tif (textWidth > longest) {\n\t\t\tlongest = textWidth;\n\t\t}\n\t\treturn longest;\n\t};\n\thelpers.numberOfLabelLines = function(arrayOfThings) {\n\t\tvar numberOfLines = 1;\n\t\thelpers.each(arrayOfThings, function(thing) {\n\t\t\tif (helpers.isArray(thing)) {\n\t\t\t\tif (thing.length > numberOfLines) {\n\t\t\t\t\tnumberOfLines = thing.length;\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\t\treturn numberOfLines;\n\t};\n\thelpers.drawRoundedRectangle = function(ctx, x, y, width, height, radius) {\n\t\tctx.beginPath();\n\t\tctx.moveTo(x + radius, y);\n\t\tctx.lineTo(x + width - radius, y);\n\t\tctx.quadraticCurveTo(x + width, y, x + width, y + radius);\n\t\tctx.lineTo(x + width, y + height - radius);\n\t\tctx.quadraticCurveTo(x + width, y + height, x + width - radius, y + height);\n\t\tctx.lineTo(x + radius, y + height);\n\t\tctx.quadraticCurveTo(x, y + height, x, y + height - radius);\n\t\tctx.lineTo(x, y + radius);\n\t\tctx.quadraticCurveTo(x, y, x + radius, y);\n\t\tctx.closePath();\n\t};\n\n\thelpers.color = !color?\n\t\tfunction(value) {\n\t\t\tconsole.error('Color.js not found!');\n\t\t\treturn value;\n\t\t} :\n\t\tfunction(value) {\n\t\t\t/* global CanvasGradient */\n\t\t\tif (value instanceof CanvasGradient) {\n\t\t\t\tvalue = Chart.defaults.global.defaultColor;\n\t\t\t}\n\n\t\t\treturn color(value);\n\t\t};\n\n\thelpers.isArray = Array.isArray?\n\t\tfunction(obj) {\n\t\t\treturn Array.isArray(obj);\n\t\t} :\n\t\tfunction(obj) {\n\t\t\treturn Object.prototype.toString.call(obj) === '[object Array]';\n\t\t};\n\t// ! @see http://stackoverflow.com/a/14853974\n\thelpers.arrayEquals = function(a0, a1) {\n\t\tvar i, ilen, v0, v1;\n\n\t\tif (!a0 || !a1 || a0.length !== a1.length) {\n\t\t\treturn false;\n\t\t}\n\n\t\tfor (i = 0, ilen=a0.length; i < ilen; ++i) {\n\t\t\tv0 = a0[i];\n\t\t\tv1 = a1[i];\n\n\t\t\tif (v0 instanceof Array && v1 instanceof Array) {\n\t\t\t\tif (!helpers.arrayEquals(v0, v1)) {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t} else if (v0 !== v1) {\n\t\t\t\t// NOTE: two different object instances will never be equal: {x:20} != {x:20}\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\n\t\treturn true;\n\t};\n\thelpers.callback = function(fn, args, thisArg) {\n\t\tif (fn && typeof fn.call === 'function') {\n\t\t\tfn.apply(thisArg, args);\n\t\t}\n\t};\n\thelpers.getHoverColor = function(colorValue) {\n\t\t/* global CanvasPattern */\n\t\treturn (colorValue instanceof CanvasPattern) ?\n\t\t\tcolorValue :\n\t\t\thelpers.color(colorValue).saturate(0.5).darken(0.1).rgbString();\n\t};\n\n\t/**\n\t * Provided for backward compatibility, use Chart.helpers#callback instead.\n\t * @function Chart.helpers#callCallback\n\t * @deprecated since version 2.6.0\n\t * @todo remove at version 3\n\t */\n\thelpers.callCallback = helpers.callback;\n};\n"
  },
  {
    "path": "app_backend/static/plugin/Chart.js-2.6.0/src/core/core.interaction.js",
    "content": "'use strict';\n\nmodule.exports = function(Chart) {\n\tvar helpers = Chart.helpers;\n\n\t/**\n\t * Helper function to get relative position for an event\n\t * @param {Event|IEvent} event - The event to get the position for\n\t * @param {Chart} chart - The chart\n\t * @returns {Point} the event position\n\t */\n\tfunction getRelativePosition(e, chart) {\n\t\tif (e.native) {\n\t\t\treturn {\n\t\t\t\tx: e.x,\n\t\t\t\ty: e.y\n\t\t\t};\n\t\t}\n\n\t\treturn helpers.getRelativePosition(e, chart);\n\t}\n\n\t/**\n\t * Helper function to traverse all of the visible elements in the chart\n\t * @param chart {chart} the chart\n\t * @param handler {Function} the callback to execute for each visible item\n\t */\n\tfunction parseVisibleItems(chart, handler) {\n\t\tvar datasets = chart.data.datasets;\n\t\tvar meta, i, j, ilen, jlen;\n\n\t\tfor (i = 0, ilen = datasets.length; i < ilen; ++i) {\n\t\t\tif (!chart.isDatasetVisible(i)) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tmeta = chart.getDatasetMeta(i);\n\t\t\tfor (j = 0, jlen = meta.data.length; j < jlen; ++j) {\n\t\t\t\tvar element = meta.data[j];\n\t\t\t\tif (!element._view.skip) {\n\t\t\t\t\thandler(element);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Helper function to get the items that intersect the event position\n\t * @param items {ChartElement[]} elements to filter\n\t * @param position {Point} the point to be nearest to\n\t * @return {ChartElement[]} the nearest items\n\t */\n\tfunction getIntersectItems(chart, position) {\n\t\tvar elements = [];\n\n\t\tparseVisibleItems(chart, function(element) {\n\t\t\tif (element.inRange(position.x, position.y)) {\n\t\t\t\telements.push(element);\n\t\t\t}\n\t\t});\n\n\t\treturn elements;\n\t}\n\n\t/**\n\t * Helper function to get the items nearest to the event position considering all visible items in teh chart\n\t * @param chart {Chart} the chart to look at elements from\n\t * @param position {Point} the point to be nearest to\n\t * @param intersect {Boolean} if true, only consider items that intersect the position\n\t * @param distanceMetric {Function} Optional function to provide the distance between\n\t * @return {ChartElement[]} the nearest items\n\t */\n\tfunction getNearestItems(chart, position, intersect, distanceMetric) {\n\t\tvar minDistance = Number.POSITIVE_INFINITY;\n\t\tvar nearestItems = [];\n\n\t\tif (!distanceMetric) {\n\t\t\tdistanceMetric = helpers.distanceBetweenPoints;\n\t\t}\n\n\t\tparseVisibleItems(chart, function(element) {\n\t\t\tif (intersect && !element.inRange(position.x, position.y)) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tvar center = element.getCenterPoint();\n\t\t\tvar distance = distanceMetric(position, center);\n\n\t\t\tif (distance < minDistance) {\n\t\t\t\tnearestItems = [element];\n\t\t\t\tminDistance = distance;\n\t\t\t} else if (distance === minDistance) {\n\t\t\t\t// Can have multiple items at the same distance in which case we sort by size\n\t\t\t\tnearestItems.push(element);\n\t\t\t}\n\t\t});\n\n\t\treturn nearestItems;\n\t}\n\n\tfunction indexMode(chart, e, options) {\n\t\tvar position = getRelativePosition(e, chart);\n\t\tvar distanceMetric = function(pt1, pt2) {\n\t\t\treturn Math.abs(pt1.x - pt2.x);\n\t\t};\n\t\tvar items = options.intersect ? getIntersectItems(chart, position) : getNearestItems(chart, position, false, distanceMetric);\n\t\tvar elements = [];\n\n\t\tif (!items.length) {\n\t\t\treturn [];\n\t\t}\n\n\t\tchart.data.datasets.forEach(function(dataset, datasetIndex) {\n\t\t\tif (chart.isDatasetVisible(datasetIndex)) {\n\t\t\t\tvar meta = chart.getDatasetMeta(datasetIndex),\n\t\t\t\t\telement = meta.data[items[0]._index];\n\n\t\t\t\t// don't count items that are skipped (null data)\n\t\t\t\tif (element && !element._view.skip) {\n\t\t\t\t\telements.push(element);\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\n\t\treturn elements;\n\t}\n\n\t/**\n\t * @interface IInteractionOptions\n\t */\n\t/**\n\t * If true, only consider items that intersect the point\n\t * @name IInterfaceOptions#boolean\n\t * @type Boolean\n\t */\n\n\t/**\n\t * Contains interaction related functions\n\t * @namespace Chart.Interaction\n\t */\n\tChart.Interaction = {\n\t\t// Helper function for different modes\n\t\tmodes: {\n\t\t\tsingle: function(chart, e) {\n\t\t\t\tvar position = getRelativePosition(e, chart);\n\t\t\t\tvar elements = [];\n\n\t\t\t\tparseVisibleItems(chart, function(element) {\n\t\t\t\t\tif (element.inRange(position.x, position.y)) {\n\t\t\t\t\t\telements.push(element);\n\t\t\t\t\t\treturn elements;\n\t\t\t\t\t}\n\t\t\t\t});\n\n\t\t\t\treturn elements.slice(0, 1);\n\t\t\t},\n\n\t\t\t/**\n\t\t\t * @function Chart.Interaction.modes.label\n\t\t\t * @deprecated since version 2.4.0\n\t \t\t * @todo remove at version 3\n\t\t\t * @private\n\t\t\t */\n\t\t\tlabel: indexMode,\n\n\t\t\t/**\n\t\t\t * Returns items at the same index. If the options.intersect parameter is true, we only return items if we intersect something\n\t\t\t * If the options.intersect mode is false, we find the nearest item and return the items at the same index as that item\n\t\t\t * @function Chart.Interaction.modes.index\n\t\t\t * @since v2.4.0\n\t\t\t * @param chart {chart} the chart we are returning items from\n\t\t\t * @param e {Event} the event we are find things at\n\t\t\t * @param options {IInteractionOptions} options to use during interaction\n\t\t\t * @return {Chart.Element[]} Array of elements that are under the point. If none are found, an empty array is returned\n\t\t\t */\n\t\t\tindex: indexMode,\n\n\t\t\t/**\n\t\t\t * Returns items in the same dataset. If the options.intersect parameter is true, we only return items if we intersect something\n\t\t\t * If the options.intersect is false, we find the nearest item and return the items in that dataset\n\t\t\t * @function Chart.Interaction.modes.dataset\n\t\t\t * @param chart {chart} the chart we are returning items from\n\t\t\t * @param e {Event} the event we are find things at\n\t\t\t * @param options {IInteractionOptions} options to use during interaction\n\t\t\t * @return {Chart.Element[]} Array of elements that are under the point. If none are found, an empty array is returned\n\t\t\t */\n\t\t\tdataset: function(chart, e, options) {\n\t\t\t\tvar position = getRelativePosition(e, chart);\n\t\t\t\tvar items = options.intersect ? getIntersectItems(chart, position) : getNearestItems(chart, position, false);\n\n\t\t\t\tif (items.length > 0) {\n\t\t\t\t\titems = chart.getDatasetMeta(items[0]._datasetIndex).data;\n\t\t\t\t}\n\n\t\t\t\treturn items;\n\t\t\t},\n\n\t\t\t/**\n\t\t\t * @function Chart.Interaction.modes.x-axis\n\t\t\t * @deprecated since version 2.4.0. Use index mode and intersect == true\n\t\t\t * @todo remove at version 3\n\t\t\t * @private\n\t\t\t */\n\t\t\t'x-axis': function(chart, e) {\n\t\t\t\treturn indexMode(chart, e, true);\n\t\t\t},\n\n\t\t\t/**\n\t\t\t * Point mode returns all elements that hit test based on the event position\n\t\t\t * of the event\n\t\t\t * @function Chart.Interaction.modes.intersect\n\t\t\t * @param chart {chart} the chart we are returning items from\n\t\t\t * @param e {Event} the event we are find things at\n\t\t\t * @return {Chart.Element[]} Array of elements that are under the point. If none are found, an empty array is returned\n\t\t\t */\n\t\t\tpoint: function(chart, e) {\n\t\t\t\tvar position = getRelativePosition(e, chart);\n\t\t\t\treturn getIntersectItems(chart, position);\n\t\t\t},\n\n\t\t\t/**\n\t\t\t * nearest mode returns the element closest to the point\n\t\t\t * @function Chart.Interaction.modes.intersect\n\t\t\t * @param chart {chart} the chart we are returning items from\n\t\t\t * @param e {Event} the event we are find things at\n\t\t\t * @param options {IInteractionOptions} options to use\n\t\t\t * @return {Chart.Element[]} Array of elements that are under the point. If none are found, an empty array is returned\n\t\t\t */\n\t\t\tnearest: function(chart, e, options) {\n\t\t\t\tvar position = getRelativePosition(e, chart);\n\t\t\t\tvar nearestItems = getNearestItems(chart, position, options.intersect);\n\n\t\t\t\t// We have multiple items at the same distance from the event. Now sort by smallest\n\t\t\t\tif (nearestItems.length > 1) {\n\t\t\t\t\tnearestItems.sort(function(a, b) {\n\t\t\t\t\t\tvar sizeA = a.getArea();\n\t\t\t\t\t\tvar sizeB = b.getArea();\n\t\t\t\t\t\tvar ret = sizeA - sizeB;\n\n\t\t\t\t\t\tif (ret === 0) {\n\t\t\t\t\t\t\t// if equal sort by dataset index\n\t\t\t\t\t\t\tret = a._datasetIndex - b._datasetIndex;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\treturn ret;\n\t\t\t\t\t});\n\t\t\t\t}\n\n\t\t\t\t// Return only 1 item\n\t\t\t\treturn nearestItems.slice(0, 1);\n\t\t\t},\n\n\t\t\t/**\n\t\t\t * x mode returns the elements that hit-test at the current x coordinate\n\t\t\t * @function Chart.Interaction.modes.x\n\t\t\t * @param chart {chart} the chart we are returning items from\n\t\t\t * @param e {Event} the event we are find things at\n\t\t\t * @param options {IInteractionOptions} options to use\n\t\t\t * @return {Chart.Element[]} Array of elements that are under the point. If none are found, an empty array is returned\n\t\t\t */\n\t\t\tx: function(chart, e, options) {\n\t\t\t\tvar position = getRelativePosition(e, chart);\n\t\t\t\tvar items = [];\n\t\t\t\tvar intersectsItem = false;\n\n\t\t\t\tparseVisibleItems(chart, function(element) {\n\t\t\t\t\tif (element.inXRange(position.x)) {\n\t\t\t\t\t\titems.push(element);\n\t\t\t\t\t}\n\n\t\t\t\t\tif (element.inRange(position.x, position.y)) {\n\t\t\t\t\t\tintersectsItem = true;\n\t\t\t\t\t}\n\t\t\t\t});\n\n\t\t\t\t// If we want to trigger on an intersect and we don't have any items\n\t\t\t\t// that intersect the position, return nothing\n\t\t\t\tif (options.intersect && !intersectsItem) {\n\t\t\t\t\titems = [];\n\t\t\t\t}\n\t\t\t\treturn items;\n\t\t\t},\n\n\t\t\t/**\n\t\t\t * y mode returns the elements that hit-test at the current y coordinate\n\t\t\t * @function Chart.Interaction.modes.y\n\t\t\t * @param chart {chart} the chart we are returning items from\n\t\t\t * @param e {Event} the event we are find things at\n\t\t\t * @param options {IInteractionOptions} options to use\n\t\t\t * @return {Chart.Element[]} Array of elements that are under the point. If none are found, an empty array is returned\n\t\t\t */\n\t\t\ty: function(chart, e, options) {\n\t\t\t\tvar position = getRelativePosition(e, chart);\n\t\t\t\tvar items = [];\n\t\t\t\tvar intersectsItem = false;\n\n\t\t\t\tparseVisibleItems(chart, function(element) {\n\t\t\t\t\tif (element.inYRange(position.y)) {\n\t\t\t\t\t\titems.push(element);\n\t\t\t\t\t}\n\n\t\t\t\t\tif (element.inRange(position.x, position.y)) {\n\t\t\t\t\t\tintersectsItem = true;\n\t\t\t\t\t}\n\t\t\t\t});\n\n\t\t\t\t// If we want to trigger on an intersect and we don't have any items\n\t\t\t\t// that intersect the position, return nothing\n\t\t\t\tif (options.intersect && !intersectsItem) {\n\t\t\t\t\titems = [];\n\t\t\t\t}\n\t\t\t\treturn items;\n\t\t\t}\n\t\t}\n\t};\n};\n"
  },
  {
    "path": "app_backend/static/plugin/Chart.js-2.6.0/src/core/core.js",
    "content": "'use strict';\n\nmodule.exports = function() {\n\n\t// Occupy the global variable of Chart, and create a simple base class\n\tvar Chart = function(item, config) {\n\t\tthis.construct(item, config);\n\t\treturn this;\n\t};\n\n\t// Globally expose the defaults to allow for user updating/changing\n\tChart.defaults = {\n\t\tglobal: {\n\t\t\tresponsive: true,\n\t\t\tresponsiveAnimationDuration: 0,\n\t\t\tmaintainAspectRatio: true,\n\t\t\tevents: ['mousemove', 'mouseout', 'click', 'touchstart', 'touchmove'],\n\t\t\thover: {\n\t\t\t\tonHover: null,\n\t\t\t\tmode: 'nearest',\n\t\t\t\tintersect: true,\n\t\t\t\tanimationDuration: 400\n\t\t\t},\n\t\t\tonClick: null,\n\t\t\tdefaultColor: 'rgba(0,0,0,0.1)',\n\t\t\tdefaultFontColor: '#666',\n\t\t\tdefaultFontFamily: \"'Helvetica Neue', 'Helvetica', 'Arial', sans-serif\",\n\t\t\tdefaultFontSize: 12,\n\t\t\tdefaultFontStyle: 'normal',\n\t\t\tshowLines: true,\n\n\t\t\t// Element defaults defined in element extensions\n\t\t\telements: {},\n\n\t\t\t// Legend callback string\n\t\t\tlegendCallback: function(chart) {\n\t\t\t\tvar text = [];\n\t\t\t\ttext.push('<ul class=\"' + chart.id + '-legend\">');\n\t\t\t\tfor (var i = 0; i < chart.data.datasets.length; i++) {\n\t\t\t\t\ttext.push('<li><span style=\"background-color:' + chart.data.datasets[i].backgroundColor + '\"></span>');\n\t\t\t\t\tif (chart.data.datasets[i].label) {\n\t\t\t\t\t\ttext.push(chart.data.datasets[i].label);\n\t\t\t\t\t}\n\t\t\t\t\ttext.push('</li>');\n\t\t\t\t}\n\t\t\t\ttext.push('</ul>');\n\n\t\t\t\treturn text.join('');\n\t\t\t}\n\t\t}\n\t};\n\n\tChart.Chart = Chart;\n\n\treturn Chart;\n};\n"
  },
  {
    "path": "app_backend/static/plugin/Chart.js-2.6.0/src/core/core.layoutService.js",
    "content": "'use strict';\n\nmodule.exports = function(Chart) {\n\n\tvar helpers = Chart.helpers;\n\n\tfunction filterByPosition(array, position) {\n\t\treturn helpers.where(array, function(v) {\n\t\t\treturn v.position === position;\n\t\t});\n\t}\n\n\tfunction sortByWeight(array, reverse) {\n\t\tarray.forEach(function(v, i) {\n\t\t\tv._tmpIndex_ = i;\n\t\t\treturn v;\n\t\t});\n\t\tarray.sort(function(a, b) {\n\t\t\tvar v0 = reverse ? b : a;\n\t\t\tvar v1 = reverse ? a : b;\n\t\t\treturn v0.weight === v1.weight ?\n\t\t\t\tv0._tmpIndex_ - v1._tmpIndex_ :\n\t\t\t\tv0.weight - v1.weight;\n\t\t});\n\t\tarray.forEach(function(v) {\n\t\t\tdelete v._tmpIndex_;\n\t\t});\n\t}\n\n\t/**\n\t * @interface ILayoutItem\n\t * @prop {String} position - The position of the item in the chart layout. Possible values are\n\t * 'left', 'top', 'right', 'bottom', and 'chartArea'\n\t * @prop {Number} weight - The weight used to sort the item. Higher weights are further away from the chart area\n\t * @prop {Boolean} fullWidth - if true, and the item is horizontal, then push vertical boxes down\n\t * @prop {Function} isHorizontal - returns true if the layout item is horizontal (ie. top or bottom)\n\t * @prop {Function} update - Takes two parameters: width and height. Returns size of item\n\t * @prop {Function} getPadding -  Returns an object with padding on the edges\n\t * @prop {Number} width - Width of item. Must be valid after update()\n\t * @prop {Number} height - Height of item. Must be valid after update()\n\t * @prop {Number} left - Left edge of the item. Set by layout system and cannot be used in update\n\t * @prop {Number} top - Top edge of the item. Set by layout system and cannot be used in update\n\t * @prop {Number} right - Right edge of the item. Set by layout system and cannot be used in update\n\t * @prop {Number} bottom - Bottom edge of the item. Set by layout system and cannot be used in update\n\t */\n\n\t// The layout service is very self explanatory.  It's responsible for the layout within a chart.\n\t// Scales, Legends and Plugins all rely on the layout service and can easily register to be placed anywhere they need\n\t// It is this service's responsibility of carrying out that layout.\n\tChart.layoutService = {\n\t\tdefaults: {},\n\n\t\t/**\n\t\t * Register a box to a chart.\n\t\t * A box is simply a reference to an object that requires layout. eg. Scales, Legend, Title.\n\t\t * @param {Chart} chart - the chart to use\n\t\t * @param {ILayoutItem} item - the item to add to be layed out\n\t\t */\n\t\taddBox: function(chart, item) {\n\t\t\tif (!chart.boxes) {\n\t\t\t\tchart.boxes = [];\n\t\t\t}\n\n\t\t\t// initialize item with default values\n\t\t\titem.fullWidth = item.fullWidth || false;\n\t\t\titem.position = item.position || 'top';\n\t\t\titem.weight = item.weight || 0;\n\n\t\t\tchart.boxes.push(item);\n\t\t},\n\n\t\t/**\n\t\t * Remove a layoutItem from a chart\n\t\t * @param {Chart} chart - the chart to remove the box from\n\t\t * @param {Object} layoutItem - the item to remove from the layout\n\t\t */\n\t\tremoveBox: function(chart, layoutItem) {\n\t\t\tvar index = chart.boxes? chart.boxes.indexOf(layoutItem) : -1;\n\t\t\tif (index !== -1) {\n\t\t\t\tchart.boxes.splice(index, 1);\n\t\t\t}\n\t\t},\n\n\t\t/**\n\t\t * Sets (or updates) options on the given `item`.\n\t\t * @param {Chart} chart - the chart in which the item lives (or will be added to)\n\t\t * @param {Object} item - the item to configure with the given options\n\t\t * @param {Object} options - the new item options.\n\t\t */\n\t\tconfigure: function(chart, item, options) {\n\t\t\tvar props = ['fullWidth', 'position', 'weight'];\n\t\t\tvar ilen = props.length;\n\t\t\tvar i = 0;\n\t\t\tvar prop;\n\n\t\t\tfor (; i<ilen; ++i) {\n\t\t\t\tprop = props[i];\n\t\t\t\tif (options.hasOwnProperty(prop)) {\n\t\t\t\t\titem[prop] = options[prop];\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\n\t\t/**\n\t\t * Fits boxes of the given chart into the given size by having each box measure itself\n\t\t * then running a fitting algorithm\n\t\t * @param {Chart} chart - the chart\n\t\t * @param {Number} width - the width to fit into\n\t\t * @param {Number} height - the height to fit into\n\t\t */\n\t\tupdate: function(chart, width, height) {\n\t\t\tif (!chart) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tvar layoutOptions = chart.options.layout;\n\t\t\tvar padding = layoutOptions ? layoutOptions.padding : null;\n\n\t\t\tvar leftPadding = 0;\n\t\t\tvar rightPadding = 0;\n\t\t\tvar topPadding = 0;\n\t\t\tvar bottomPadding = 0;\n\n\t\t\tif (!isNaN(padding)) {\n\t\t\t\t// options.layout.padding is a number. assign to all\n\t\t\t\tleftPadding = padding;\n\t\t\t\trightPadding = padding;\n\t\t\t\ttopPadding = padding;\n\t\t\t\tbottomPadding = padding;\n\t\t\t} else {\n\t\t\t\tleftPadding = padding.left || 0;\n\t\t\t\trightPadding = padding.right || 0;\n\t\t\t\ttopPadding = padding.top || 0;\n\t\t\t\tbottomPadding = padding.bottom || 0;\n\t\t\t}\n\n\t\t\tvar leftBoxes = filterByPosition(chart.boxes, 'left');\n\t\t\tvar rightBoxes = filterByPosition(chart.boxes, 'right');\n\t\t\tvar topBoxes = filterByPosition(chart.boxes, 'top');\n\t\t\tvar bottomBoxes = filterByPosition(chart.boxes, 'bottom');\n\t\t\tvar chartAreaBoxes = filterByPosition(chart.boxes, 'chartArea');\n\n\t\t\t// Sort boxes by weight. A higher weight is further away from the chart area\n\t\t\tsortByWeight(leftBoxes, true);\n\t\t\tsortByWeight(rightBoxes, false);\n\t\t\tsortByWeight(topBoxes, true);\n\t\t\tsortByWeight(bottomBoxes, false);\n\n\t\t\t// Essentially we now have any number of boxes on each of the 4 sides.\n\t\t\t// Our canvas looks like the following.\n\t\t\t// The areas L1 and L2 are the left axes. R1 is the right axis, T1 is the top axis and\n\t\t\t// B1 is the bottom axis\n\t\t\t// There are also 4 quadrant-like locations (left to right instead of clockwise) reserved for chart overlays\n\t\t\t// These locations are single-box locations only, when trying to register a chartArea location that is already taken,\n\t\t\t// an error will be thrown.\n\t\t\t//\n\t\t\t// |----------------------------------------------------|\n\t\t\t// |                  T1 (Full Width)                   |\n\t\t\t// |----------------------------------------------------|\n\t\t\t// |    |    |                 T2                  |    |\n\t\t\t// |    |----|-------------------------------------|----|\n\t\t\t// |    |    | C1 |                           | C2 |    |\n\t\t\t// |    |    |----|                           |----|    |\n\t\t\t// |    |    |                                     |    |\n\t\t\t// | L1 | L2 |           ChartArea (C0)            | R1 |\n\t\t\t// |    |    |                                     |    |\n\t\t\t// |    |    |----|                           |----|    |\n\t\t\t// |    |    | C3 |                           | C4 |    |\n\t\t\t// |    |----|-------------------------------------|----|\n\t\t\t// |    |    |                 B1                  |    |\n\t\t\t// |----------------------------------------------------|\n\t\t\t// |                  B2 (Full Width)                   |\n\t\t\t// |----------------------------------------------------|\n\t\t\t//\n\t\t\t// What we do to find the best sizing, we do the following\n\t\t\t// 1. Determine the minimum size of the chart area.\n\t\t\t// 2. Split the remaining width equally between each vertical axis\n\t\t\t// 3. Split the remaining height equally between each horizontal axis\n\t\t\t// 4. Give each layout the maximum size it can be. The layout will return it's minimum size\n\t\t\t// 5. Adjust the sizes of each axis based on it's minimum reported size.\n\t\t\t// 6. Refit each axis\n\t\t\t// 7. Position each axis in the final location\n\t\t\t// 8. Tell the chart the final location of the chart area\n\t\t\t// 9. Tell any axes that overlay the chart area the positions of the chart area\n\n\t\t\t// Step 1\n\t\t\tvar chartWidth = width - leftPadding - rightPadding;\n\t\t\tvar chartHeight = height - topPadding - bottomPadding;\n\t\t\tvar chartAreaWidth = chartWidth / 2; // min 50%\n\t\t\tvar chartAreaHeight = chartHeight / 2; // min 50%\n\n\t\t\t// Step 2\n\t\t\tvar verticalBoxWidth = (width - chartAreaWidth) / (leftBoxes.length + rightBoxes.length);\n\n\t\t\t// Step 3\n\t\t\tvar horizontalBoxHeight = (height - chartAreaHeight) / (topBoxes.length + bottomBoxes.length);\n\n\t\t\t// Step 4\n\t\t\tvar maxChartAreaWidth = chartWidth;\n\t\t\tvar maxChartAreaHeight = chartHeight;\n\t\t\tvar minBoxSizes = [];\n\n\t\t\tfunction getMinimumBoxSize(box) {\n\t\t\t\tvar minSize;\n\t\t\t\tvar isHorizontal = box.isHorizontal();\n\n\t\t\t\tif (isHorizontal) {\n\t\t\t\t\tminSize = box.update(box.fullWidth ? chartWidth : maxChartAreaWidth, horizontalBoxHeight);\n\t\t\t\t\tmaxChartAreaHeight -= minSize.height;\n\t\t\t\t} else {\n\t\t\t\t\tminSize = box.update(verticalBoxWidth, chartAreaHeight);\n\t\t\t\t\tmaxChartAreaWidth -= minSize.width;\n\t\t\t\t}\n\n\t\t\t\tminBoxSizes.push({\n\t\t\t\t\thorizontal: isHorizontal,\n\t\t\t\t\tminSize: minSize,\n\t\t\t\t\tbox: box,\n\t\t\t\t});\n\t\t\t}\n\n\t\t\thelpers.each(leftBoxes.concat(rightBoxes, topBoxes, bottomBoxes), getMinimumBoxSize);\n\n\t\t\t// If a horizontal box has padding, we move the left boxes over to avoid ugly charts (see issue #2478)\n\t\t\tvar maxHorizontalLeftPadding = 0;\n\t\t\tvar maxHorizontalRightPadding = 0;\n\t\t\tvar maxVerticalTopPadding = 0;\n\t\t\tvar maxVerticalBottomPadding = 0;\n\n\t\t\thelpers.each(topBoxes.concat(bottomBoxes), function(horizontalBox) {\n\t\t\t\tif (horizontalBox.getPadding) {\n\t\t\t\t\tvar boxPadding = horizontalBox.getPadding();\n\t\t\t\t\tmaxHorizontalLeftPadding = Math.max(maxHorizontalLeftPadding, boxPadding.left);\n\t\t\t\t\tmaxHorizontalRightPadding = Math.max(maxHorizontalRightPadding, boxPadding.right);\n\t\t\t\t}\n\t\t\t});\n\n\t\t\thelpers.each(leftBoxes.concat(rightBoxes), function(verticalBox) {\n\t\t\t\tif (verticalBox.getPadding) {\n\t\t\t\t\tvar boxPadding = verticalBox.getPadding();\n\t\t\t\t\tmaxVerticalTopPadding = Math.max(maxVerticalTopPadding, boxPadding.top);\n\t\t\t\t\tmaxVerticalBottomPadding = Math.max(maxVerticalBottomPadding, boxPadding.bottom);\n\t\t\t\t}\n\t\t\t});\n\n\t\t\t// At this point, maxChartAreaHeight and maxChartAreaWidth are the size the chart area could\n\t\t\t// be if the axes are drawn at their minimum sizes.\n\t\t\t// Steps 5 & 6\n\t\t\tvar totalLeftBoxesWidth = leftPadding;\n\t\t\tvar totalRightBoxesWidth = rightPadding;\n\t\t\tvar totalTopBoxesHeight = topPadding;\n\t\t\tvar totalBottomBoxesHeight = bottomPadding;\n\n\t\t\t// Function to fit a box\n\t\t\tfunction fitBox(box) {\n\t\t\t\tvar minBoxSize = helpers.findNextWhere(minBoxSizes, function(minBox) {\n\t\t\t\t\treturn minBox.box === box;\n\t\t\t\t});\n\n\t\t\t\tif (minBoxSize) {\n\t\t\t\t\tif (box.isHorizontal()) {\n\t\t\t\t\t\tvar scaleMargin = {\n\t\t\t\t\t\t\tleft: Math.max(totalLeftBoxesWidth, maxHorizontalLeftPadding),\n\t\t\t\t\t\t\tright: Math.max(totalRightBoxesWidth, maxHorizontalRightPadding),\n\t\t\t\t\t\t\ttop: 0,\n\t\t\t\t\t\t\tbottom: 0\n\t\t\t\t\t\t};\n\n\t\t\t\t\t\t// Don't use min size here because of label rotation. When the labels are rotated, their rotation highly depends\n\t\t\t\t\t\t// on the margin. Sometimes they need to increase in size slightly\n\t\t\t\t\t\tbox.update(box.fullWidth ? chartWidth : maxChartAreaWidth, chartHeight / 2, scaleMargin);\n\t\t\t\t\t} else {\n\t\t\t\t\t\tbox.update(minBoxSize.minSize.width, maxChartAreaHeight);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Update, and calculate the left and right margins for the horizontal boxes\n\t\t\thelpers.each(leftBoxes.concat(rightBoxes), fitBox);\n\n\t\t\thelpers.each(leftBoxes, function(box) {\n\t\t\t\ttotalLeftBoxesWidth += box.width;\n\t\t\t});\n\n\t\t\thelpers.each(rightBoxes, function(box) {\n\t\t\t\ttotalRightBoxesWidth += box.width;\n\t\t\t});\n\n\t\t\t// Set the Left and Right margins for the horizontal boxes\n\t\t\thelpers.each(topBoxes.concat(bottomBoxes), fitBox);\n\n\t\t\t// Figure out how much margin is on the top and bottom of the vertical boxes\n\t\t\thelpers.each(topBoxes, function(box) {\n\t\t\t\ttotalTopBoxesHeight += box.height;\n\t\t\t});\n\n\t\t\thelpers.each(bottomBoxes, function(box) {\n\t\t\t\ttotalBottomBoxesHeight += box.height;\n\t\t\t});\n\n\t\t\tfunction finalFitVerticalBox(box) {\n\t\t\t\tvar minBoxSize = helpers.findNextWhere(minBoxSizes, function(minSize) {\n\t\t\t\t\treturn minSize.box === box;\n\t\t\t\t});\n\n\t\t\t\tvar scaleMargin = {\n\t\t\t\t\tleft: 0,\n\t\t\t\t\tright: 0,\n\t\t\t\t\ttop: totalTopBoxesHeight,\n\t\t\t\t\tbottom: totalBottomBoxesHeight\n\t\t\t\t};\n\n\t\t\t\tif (minBoxSize) {\n\t\t\t\t\tbox.update(minBoxSize.minSize.width, maxChartAreaHeight, scaleMargin);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Let the left layout know the final margin\n\t\t\thelpers.each(leftBoxes.concat(rightBoxes), finalFitVerticalBox);\n\n\t\t\t// Recalculate because the size of each layout might have changed slightly due to the margins (label rotation for instance)\n\t\t\ttotalLeftBoxesWidth = leftPadding;\n\t\t\ttotalRightBoxesWidth = rightPadding;\n\t\t\ttotalTopBoxesHeight = topPadding;\n\t\t\ttotalBottomBoxesHeight = bottomPadding;\n\n\t\t\thelpers.each(leftBoxes, function(box) {\n\t\t\t\ttotalLeftBoxesWidth += box.width;\n\t\t\t});\n\n\t\t\thelpers.each(rightBoxes, function(box) {\n\t\t\t\ttotalRightBoxesWidth += box.width;\n\t\t\t});\n\n\t\t\thelpers.each(topBoxes, function(box) {\n\t\t\t\ttotalTopBoxesHeight += box.height;\n\t\t\t});\n\t\t\thelpers.each(bottomBoxes, function(box) {\n\t\t\t\ttotalBottomBoxesHeight += box.height;\n\t\t\t});\n\n\t\t\t// We may be adding some padding to account for rotated x axis labels\n\t\t\tvar leftPaddingAddition = Math.max(maxHorizontalLeftPadding - totalLeftBoxesWidth, 0);\n\t\t\ttotalLeftBoxesWidth += leftPaddingAddition;\n\t\t\ttotalRightBoxesWidth += Math.max(maxHorizontalRightPadding - totalRightBoxesWidth, 0);\n\n\t\t\tvar topPaddingAddition = Math.max(maxVerticalTopPadding - totalTopBoxesHeight, 0);\n\t\t\ttotalTopBoxesHeight += topPaddingAddition;\n\t\t\ttotalBottomBoxesHeight += Math.max(maxVerticalBottomPadding - totalBottomBoxesHeight, 0);\n\n\t\t\t// Figure out if our chart area changed. This would occur if the dataset layout label rotation\n\t\t\t// changed due to the application of the margins in step 6. Since we can only get bigger, this is safe to do\n\t\t\t// without calling `fit` again\n\t\t\tvar newMaxChartAreaHeight = height - totalTopBoxesHeight - totalBottomBoxesHeight;\n\t\t\tvar newMaxChartAreaWidth = width - totalLeftBoxesWidth - totalRightBoxesWidth;\n\n\t\t\tif (newMaxChartAreaWidth !== maxChartAreaWidth || newMaxChartAreaHeight !== maxChartAreaHeight) {\n\t\t\t\thelpers.each(leftBoxes, function(box) {\n\t\t\t\t\tbox.height = newMaxChartAreaHeight;\n\t\t\t\t});\n\n\t\t\t\thelpers.each(rightBoxes, function(box) {\n\t\t\t\t\tbox.height = newMaxChartAreaHeight;\n\t\t\t\t});\n\n\t\t\t\thelpers.each(topBoxes, function(box) {\n\t\t\t\t\tif (!box.fullWidth) {\n\t\t\t\t\t\tbox.width = newMaxChartAreaWidth;\n\t\t\t\t\t}\n\t\t\t\t});\n\n\t\t\t\thelpers.each(bottomBoxes, function(box) {\n\t\t\t\t\tif (!box.fullWidth) {\n\t\t\t\t\t\tbox.width = newMaxChartAreaWidth;\n\t\t\t\t\t}\n\t\t\t\t});\n\n\t\t\t\tmaxChartAreaHeight = newMaxChartAreaHeight;\n\t\t\t\tmaxChartAreaWidth = newMaxChartAreaWidth;\n\t\t\t}\n\n\t\t\t// Step 7 - Position the boxes\n\t\t\tvar left = leftPadding + leftPaddingAddition;\n\t\t\tvar top = topPadding + topPaddingAddition;\n\n\t\t\tfunction placeBox(box) {\n\t\t\t\tif (box.isHorizontal()) {\n\t\t\t\t\tbox.left = box.fullWidth ? leftPadding : totalLeftBoxesWidth;\n\t\t\t\t\tbox.right = box.fullWidth ? width - rightPadding : totalLeftBoxesWidth + maxChartAreaWidth;\n\t\t\t\t\tbox.top = top;\n\t\t\t\t\tbox.bottom = top + box.height;\n\n\t\t\t\t\t// Move to next point\n\t\t\t\t\ttop = box.bottom;\n\n\t\t\t\t} else {\n\n\t\t\t\t\tbox.left = left;\n\t\t\t\t\tbox.right = left + box.width;\n\t\t\t\t\tbox.top = totalTopBoxesHeight;\n\t\t\t\t\tbox.bottom = totalTopBoxesHeight + maxChartAreaHeight;\n\n\t\t\t\t\t// Move to next point\n\t\t\t\t\tleft = box.right;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\thelpers.each(leftBoxes.concat(topBoxes), placeBox);\n\n\t\t\t// Account for chart width and height\n\t\t\tleft += maxChartAreaWidth;\n\t\t\ttop += maxChartAreaHeight;\n\n\t\t\thelpers.each(rightBoxes, placeBox);\n\t\t\thelpers.each(bottomBoxes, placeBox);\n\n\t\t\t// Step 8\n\t\t\tchart.chartArea = {\n\t\t\t\tleft: totalLeftBoxesWidth,\n\t\t\t\ttop: totalTopBoxesHeight,\n\t\t\t\tright: totalLeftBoxesWidth + maxChartAreaWidth,\n\t\t\t\tbottom: totalTopBoxesHeight + maxChartAreaHeight\n\t\t\t};\n\n\t\t\t// Step 9\n\t\t\thelpers.each(chartAreaBoxes, function(box) {\n\t\t\t\tbox.left = chart.chartArea.left;\n\t\t\t\tbox.top = chart.chartArea.top;\n\t\t\t\tbox.right = chart.chartArea.right;\n\t\t\t\tbox.bottom = chart.chartArea.bottom;\n\n\t\t\t\tbox.update(maxChartAreaWidth, maxChartAreaHeight);\n\t\t\t});\n\t\t}\n\t};\n};\n"
  },
  {
    "path": "app_backend/static/plugin/Chart.js-2.6.0/src/core/core.plugin.js",
    "content": "'use strict';\n\nmodule.exports = function(Chart) {\n\n\tvar helpers = Chart.helpers;\n\n\tChart.defaults.global.plugins = {};\n\n\t/**\n\t * The plugin service singleton\n\t * @namespace Chart.plugins\n\t * @since 2.1.0\n\t */\n\tChart.plugins = {\n\t\t/**\n\t\t * Globally registered plugins.\n\t\t * @private\n\t\t */\n\t\t_plugins: [],\n\n\t\t/**\n\t\t * This identifier is used to invalidate the descriptors cache attached to each chart\n\t\t * when a global plugin is registered or unregistered. In this case, the cache ID is\n\t\t * incremented and descriptors are regenerated during following API calls.\n\t\t * @private\n\t\t */\n\t\t_cacheId: 0,\n\n\t\t/**\n\t\t * Registers the given plugin(s) if not already registered.\n\t\t * @param {Array|Object} plugins plugin instance(s).\n\t\t */\n\t\tregister: function(plugins) {\n\t\t\tvar p = this._plugins;\n\t\t\t([]).concat(plugins).forEach(function(plugin) {\n\t\t\t\tif (p.indexOf(plugin) === -1) {\n\t\t\t\t\tp.push(plugin);\n\t\t\t\t}\n\t\t\t});\n\n\t\t\tthis._cacheId++;\n\t\t},\n\n\t\t/**\n\t\t * Unregisters the given plugin(s) only if registered.\n\t\t * @param {Array|Object} plugins plugin instance(s).\n\t\t */\n\t\tunregister: function(plugins) {\n\t\t\tvar p = this._plugins;\n\t\t\t([]).concat(plugins).forEach(function(plugin) {\n\t\t\t\tvar idx = p.indexOf(plugin);\n\t\t\t\tif (idx !== -1) {\n\t\t\t\t\tp.splice(idx, 1);\n\t\t\t\t}\n\t\t\t});\n\n\t\t\tthis._cacheId++;\n\t\t},\n\n\t\t/**\n\t\t * Remove all registered plugins.\n\t\t * @since 2.1.5\n\t\t */\n\t\tclear: function() {\n\t\t\tthis._plugins = [];\n\t\t\tthis._cacheId++;\n\t\t},\n\n\t\t/**\n\t\t * Returns the number of registered plugins?\n\t\t * @returns {Number}\n\t\t * @since 2.1.5\n\t\t */\n\t\tcount: function() {\n\t\t\treturn this._plugins.length;\n\t\t},\n\n\t\t/**\n\t\t * Returns all registered plugin instances.\n\t\t * @returns {Array} array of plugin objects.\n\t\t * @since 2.1.5\n\t\t */\n\t\tgetAll: function() {\n\t\t\treturn this._plugins;\n\t\t},\n\n\t\t/**\n\t\t * Calls enabled plugins for `chart` on the specified hook and with the given args.\n\t\t * This method immediately returns as soon as a plugin explicitly returns false. The\n\t\t * returned value can be used, for instance, to interrupt the current action.\n\t\t * @param {Object} chart - The chart instance for which plugins should be called.\n\t\t * @param {String} hook - The name of the plugin method to call (e.g. 'beforeUpdate').\n\t\t * @param {Array} [args] - Extra arguments to apply to the hook call.\n\t\t * @returns {Boolean} false if any of the plugins return false, else returns true.\n\t\t */\n\t\tnotify: function(chart, hook, args) {\n\t\t\tvar descriptors = this.descriptors(chart);\n\t\t\tvar ilen = descriptors.length;\n\t\t\tvar i, descriptor, plugin, params, method;\n\n\t\t\tfor (i=0; i<ilen; ++i) {\n\t\t\t\tdescriptor = descriptors[i];\n\t\t\t\tplugin = descriptor.plugin;\n\t\t\t\tmethod = plugin[hook];\n\t\t\t\tif (typeof method === 'function') {\n\t\t\t\t\tparams = [chart].concat(args || []);\n\t\t\t\t\tparams.push(descriptor.options);\n\t\t\t\t\tif (method.apply(plugin, params) === false) {\n\t\t\t\t\t\treturn false;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn true;\n\t\t},\n\n\t\t/**\n\t\t * Returns descriptors of enabled plugins for the given chart.\n\t\t * @returns {Array} [{ plugin, options }]\n\t\t * @private\n\t\t */\n\t\tdescriptors: function(chart) {\n\t\t\tvar cache = chart._plugins || (chart._plugins = {});\n\t\t\tif (cache.id === this._cacheId) {\n\t\t\t\treturn cache.descriptors;\n\t\t\t}\n\n\t\t\tvar plugins = [];\n\t\t\tvar descriptors = [];\n\t\t\tvar config = (chart && chart.config) || {};\n\t\t\tvar defaults = Chart.defaults.global.plugins;\n\t\t\tvar options = (config.options && config.options.plugins) || {};\n\n\t\t\tthis._plugins.concat(config.plugins || []).forEach(function(plugin) {\n\t\t\t\tvar idx = plugins.indexOf(plugin);\n\t\t\t\tif (idx !== -1) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tvar id = plugin.id;\n\t\t\t\tvar opts = options[id];\n\t\t\t\tif (opts === false) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tif (opts === true) {\n\t\t\t\t\topts = helpers.clone(defaults[id]);\n\t\t\t\t}\n\n\t\t\t\tplugins.push(plugin);\n\t\t\t\tdescriptors.push({\n\t\t\t\t\tplugin: plugin,\n\t\t\t\t\toptions: opts || {}\n\t\t\t\t});\n\t\t\t});\n\n\t\t\tcache.descriptors = descriptors;\n\t\t\tcache.id = this._cacheId;\n\t\t\treturn descriptors;\n\t\t}\n\t};\n\n\t/**\n\t * Plugin extension hooks.\n\t * @interface IPlugin\n\t * @since 2.1.0\n\t */\n\t/**\n\t * @method IPlugin#beforeInit\n\t * @desc Called before initializing `chart`.\n\t * @param {Chart.Controller} chart - The chart instance.\n\t * @param {Object} options - The plugin options.\n\t */\n\t/**\n\t * @method IPlugin#afterInit\n\t * @desc Called after `chart` has been initialized and before the first update.\n\t * @param {Chart.Controller} chart - The chart instance.\n\t * @param {Object} options - The plugin options.\n\t */\n\t/**\n\t * @method IPlugin#beforeUpdate\n\t * @desc Called before updating `chart`. If any plugin returns `false`, the update\n\t * is cancelled (and thus subsequent render(s)) until another `update` is triggered.\n\t * @param {Chart.Controller} chart - The chart instance.\n\t * @param {Object} options - The plugin options.\n\t * @returns {Boolean} `false` to cancel the chart update.\n\t */\n\t/**\n\t * @method IPlugin#afterUpdate\n\t * @desc Called after `chart` has been updated and before rendering. Note that this\n\t * hook will not be called if the chart update has been previously cancelled.\n\t * @param {Chart.Controller} chart - The chart instance.\n\t * @param {Object} options - The plugin options.\n\t */\n\t/**\n\t * @method IPlugin#beforeDatasetsUpdate\n \t * @desc Called before updating the `chart` datasets. If any plugin returns `false`,\n\t * the datasets update is cancelled until another `update` is triggered.\n\t * @param {Chart.Controller} chart - The chart instance.\n\t * @param {Object} options - The plugin options.\n\t * @returns {Boolean} false to cancel the datasets update.\n\t * @since version 2.1.5\n\t */\n\t/**\n\t * @method IPlugin#afterDatasetsUpdate\n\t * @desc Called after the `chart` datasets have been updated. Note that this hook\n\t * will not be called if the datasets update has been previously cancelled.\n\t * @param {Chart.Controller} chart - The chart instance.\n\t * @param {Object} options - The plugin options.\n\t * @since version 2.1.5\n\t */\n\t/**\n\t * @method IPlugin#beforeDatasetUpdate\n \t * @desc Called before updating the `chart` dataset at the given `args.index`. If any plugin\n\t * returns `false`, the datasets update is cancelled until another `update` is triggered.\n\t * @param {Chart} chart - The chart instance.\n\t * @param {Object} args - The call arguments.\n\t * @param {Object} args.index - The dataset index.\n\t * @param {Number} args.meta - The dataset metadata.\n\t * @param {Object} options - The plugin options.\n\t * @returns {Boolean} `false` to cancel the chart datasets drawing.\n\t */\n\t/**\n\t * @method IPlugin#afterDatasetUpdate\n \t * @desc Called after the `chart` datasets at the given `args.index` has been updated. Note\n\t * that this hook will not be called if the datasets update has been previously cancelled.\n\t * @param {Chart} chart - The chart instance.\n\t * @param {Object} args - The call arguments.\n\t * @param {Object} args.index - The dataset index.\n\t * @param {Number} args.meta - The dataset metadata.\n\t * @param {Object} options - The plugin options.\n\t */\n\t/**\n\t * @method IPlugin#beforeLayout\n\t * @desc Called before laying out `chart`. If any plugin returns `false`,\n\t * the layout update is cancelled until another `update` is triggered.\n\t * @param {Chart.Controller} chart - The chart instance.\n\t * @param {Object} options - The plugin options.\n\t * @returns {Boolean} `false` to cancel the chart layout.\n\t */\n\t/**\n\t * @method IPlugin#afterLayout\n\t * @desc Called after the `chart` has been layed out. Note that this hook will not\n\t * be called if the layout update has been previously cancelled.\n\t * @param {Chart.Controller} chart - The chart instance.\n\t * @param {Object} options - The plugin options.\n\t */\n\t/**\n\t * @method IPlugin#beforeRender\n\t * @desc Called before rendering `chart`. If any plugin returns `false`,\n\t * the rendering is cancelled until another `render` is triggered.\n\t * @param {Chart.Controller} chart - The chart instance.\n\t * @param {Object} options - The plugin options.\n\t * @returns {Boolean} `false` to cancel the chart rendering.\n\t */\n\t/**\n\t * @method IPlugin#afterRender\n\t * @desc Called after the `chart` has been fully rendered (and animation completed). Note\n\t * that this hook will not be called if the rendering has been previously cancelled.\n\t * @param {Chart.Controller} chart - The chart instance.\n\t * @param {Object} options - The plugin options.\n\t */\n\t/**\n\t * @method IPlugin#beforeDraw\n\t * @desc Called before drawing `chart` at every animation frame specified by the given\n\t * easing value. If any plugin returns `false`, the frame drawing is cancelled until\n\t * another `render` is triggered.\n\t * @param {Chart.Controller} chart - The chart instance.\n\t * @param {Number} easingValue - The current animation value, between 0.0 and 1.0.\n\t * @param {Object} options - The plugin options.\n\t * @returns {Boolean} `false` to cancel the chart drawing.\n\t */\n\t/**\n\t * @method IPlugin#afterDraw\n\t * @desc Called after the `chart` has been drawn for the specific easing value. Note\n\t * that this hook will not be called if the drawing has been previously cancelled.\n\t * @param {Chart.Controller} chart - The chart instance.\n\t * @param {Number} easingValue - The current animation value, between 0.0 and 1.0.\n\t * @param {Object} options - The plugin options.\n\t */\n\t/**\n\t * @method IPlugin#beforeDatasetsDraw\n \t * @desc Called before drawing the `chart` datasets. If any plugin returns `false`,\n\t * the datasets drawing is cancelled until another `render` is triggered.\n\t * @param {Chart.Controller} chart - The chart instance.\n\t * @param {Number} easingValue - The current animation value, between 0.0 and 1.0.\n\t * @param {Object} options - The plugin options.\n\t * @returns {Boolean} `false` to cancel the chart datasets drawing.\n\t */\n\t/**\n\t * @method IPlugin#afterDatasetsDraw\n\t * @desc Called after the `chart` datasets have been drawn. Note that this hook\n\t * will not be called if the datasets drawing has been previously cancelled.\n\t * @param {Chart.Controller} chart - The chart instance.\n\t * @param {Number} easingValue - The current animation value, between 0.0 and 1.0.\n\t * @param {Object} options - The plugin options.\n\t */\n\t/**\n\t * @method IPlugin#beforeDatasetDraw\n \t * @desc Called before drawing the `chart` dataset at the given `args.index` (datasets\n\t * are drawn in the reverse order). If any plugin returns `false`, the datasets drawing\n\t * is cancelled until another `render` is triggered.\n\t * @param {Chart} chart - The chart instance.\n\t * @param {Object} args - The call arguments.\n\t * @param {Object} args.index - The dataset index.\n\t * @param {Number} args.meta - The dataset metadata.\n\t * @param {Number} args.easingValue - The current animation value, between 0.0 and 1.0.\n\t * @param {Object} options - The plugin options.\n\t * @returns {Boolean} `false` to cancel the chart datasets drawing.\n\t */\n\t/**\n\t * @method IPlugin#afterDatasetDraw\n \t * @desc Called after the `chart` datasets at the given `args.index` have been drawn\n\t * (datasets are drawn in the reverse order). Note that this hook will not be called\n\t * if the datasets drawing has been previously cancelled.\n\t * @param {Chart} chart - The chart instance.\n\t * @param {Object} args - The call arguments.\n\t * @param {Object} args.index - The dataset index.\n\t * @param {Number} args.meta - The dataset metadata.\n\t * @param {Number} args.easingValue - The current animation value, between 0.0 and 1.0.\n\t * @param {Object} options - The plugin options.\n\t */\n\t/**\n\t * @method IPlugin#beforeEvent\n \t * @desc Called before processing the specified `event`. If any plugin returns `false`,\n\t * the event will be discarded.\n\t * @param {Chart.Controller} chart - The chart instance.\n\t * @param {IEvent} event - The event object.\n\t * @param {Object} options - The plugin options.\n\t */\n\t/**\n\t * @method IPlugin#afterEvent\n\t * @desc Called after the `event` has been consumed. Note that this hook\n\t * will not be called if the `event` has been previously discarded.\n\t * @param {Chart.Controller} chart - The chart instance.\n\t * @param {IEvent} event - The event object.\n\t * @param {Object} options - The plugin options.\n\t */\n\t/**\n\t * @method IPlugin#resize\n\t * @desc Called after the chart as been resized.\n\t * @param {Chart.Controller} chart - The chart instance.\n\t * @param {Number} size - The new canvas display size (eq. canvas.style width & height).\n\t * @param {Object} options - The plugin options.\n\t */\n\t/**\n\t * @method IPlugin#destroy\n\t * @desc Called after the chart as been destroyed.\n\t * @param {Chart.Controller} chart - The chart instance.\n\t * @param {Object} options - The plugin options.\n\t */\n\n\t/**\n\t * Provided for backward compatibility, use Chart.plugins instead\n\t * @namespace Chart.pluginService\n\t * @deprecated since version 2.1.5\n\t * @todo remove at version 3\n\t * @private\n\t */\n\tChart.pluginService = Chart.plugins;\n\n\t/**\n\t * Provided for backward compatibility, inheriting from Chart.PlugingBase has no\n\t * effect, instead simply create/register plugins via plain JavaScript objects.\n\t * @interface Chart.PluginBase\n\t * @deprecated since version 2.5.0\n\t * @todo remove at version 3\n\t * @private\n\t */\n\tChart.PluginBase = Chart.Element.extend({});\n};\n"
  },
  {
    "path": "app_backend/static/plugin/Chart.js-2.6.0/src/core/core.scale.js",
    "content": "'use strict';\n\nmodule.exports = function(Chart) {\n\n\tvar helpers = Chart.helpers;\n\n\tChart.defaults.scale = {\n\t\tdisplay: true,\n\t\tposition: 'left',\n\n\t\t// grid line settings\n\t\tgridLines: {\n\t\t\tdisplay: true,\n\t\t\tcolor: 'rgba(0, 0, 0, 0.1)',\n\t\t\tlineWidth: 1,\n\t\t\tdrawBorder: true,\n\t\t\tdrawOnChartArea: true,\n\t\t\tdrawTicks: true,\n\t\t\ttickMarkLength: 10,\n\t\t\tzeroLineWidth: 1,\n\t\t\tzeroLineColor: 'rgba(0,0,0,0.25)',\n\t\t\tzeroLineBorderDash: [],\n\t\t\tzeroLineBorderDashOffset: 0.0,\n\t\t\toffsetGridLines: false,\n\t\t\tborderDash: [],\n\t\t\tborderDashOffset: 0.0\n\t\t},\n\n\t\t// scale label\n\t\tscaleLabel: {\n\t\t\t// actual label\n\t\t\tlabelString: '',\n\n\t\t\t// display property\n\t\t\tdisplay: false\n\t\t},\n\n\t\t// label settings\n\t\tticks: {\n\t\t\tbeginAtZero: false,\n\t\t\tminRotation: 0,\n\t\t\tmaxRotation: 50,\n\t\t\tmirror: false,\n\t\t\tpadding: 0,\n\t\t\treverse: false,\n\t\t\tdisplay: true,\n\t\t\tautoSkip: true,\n\t\t\tautoSkipPadding: 0,\n\t\t\tlabelOffset: 0,\n\t\t\t// We pass through arrays to be rendered as multiline labels, we convert Others to strings here.\n\t\t\tcallback: Chart.Ticks.formatters.values\n\t\t}\n\t};\n\n\tfunction computeTextSize(context, tick, font) {\n\t\treturn helpers.isArray(tick) ?\n\t\t\thelpers.longestText(context, font, tick) :\n\t\t\tcontext.measureText(tick).width;\n\t}\n\n\tfunction parseFontOptions(options) {\n\t\tvar getValueOrDefault = helpers.getValueOrDefault;\n\t\tvar globalDefaults = Chart.defaults.global;\n\t\tvar size = getValueOrDefault(options.fontSize, globalDefaults.defaultFontSize);\n\t\tvar style = getValueOrDefault(options.fontStyle, globalDefaults.defaultFontStyle);\n\t\tvar family = getValueOrDefault(options.fontFamily, globalDefaults.defaultFontFamily);\n\n\t\treturn {\n\t\t\tsize: size,\n\t\t\tstyle: style,\n\t\t\tfamily: family,\n\t\t\tfont: helpers.fontString(size, style, family)\n\t\t};\n\t}\n\n\tChart.Scale = Chart.Element.extend({\n\t\t/**\n\t\t * Get the padding needed for the scale\n\t\t * @method getPadding\n\t\t * @private\n\t\t * @returns {Padding} the necessary padding\n\t\t */\n\t\tgetPadding: function() {\n\t\t\tvar me = this;\n\t\t\treturn {\n\t\t\t\tleft: me.paddingLeft || 0,\n\t\t\t\ttop: me.paddingTop || 0,\n\t\t\t\tright: me.paddingRight || 0,\n\t\t\t\tbottom: me.paddingBottom || 0\n\t\t\t};\n\t\t},\n\n\t\t// These methods are ordered by lifecyle. Utilities then follow.\n\t\t// Any function defined here is inherited by all scale types.\n\t\t// Any function can be extended by the scale type\n\n\t\tbeforeUpdate: function() {\n\t\t\thelpers.callback(this.options.beforeUpdate, [this]);\n\t\t},\n\t\tupdate: function(maxWidth, maxHeight, margins) {\n\t\t\tvar me = this;\n\n\t\t\t// Update Lifecycle - Probably don't want to ever extend or overwrite this function ;)\n\t\t\tme.beforeUpdate();\n\n\t\t\t// Absorb the master measurements\n\t\t\tme.maxWidth = maxWidth;\n\t\t\tme.maxHeight = maxHeight;\n\t\t\tme.margins = helpers.extend({\n\t\t\t\tleft: 0,\n\t\t\t\tright: 0,\n\t\t\t\ttop: 0,\n\t\t\t\tbottom: 0\n\t\t\t}, margins);\n\t\t\tme.longestTextCache = me.longestTextCache || {};\n\n\t\t\t// Dimensions\n\t\t\tme.beforeSetDimensions();\n\t\t\tme.setDimensions();\n\t\t\tme.afterSetDimensions();\n\n\t\t\t// Data min/max\n\t\t\tme.beforeDataLimits();\n\t\t\tme.determineDataLimits();\n\t\t\tme.afterDataLimits();\n\n\t\t\t// Ticks\n\t\t\tme.beforeBuildTicks();\n\t\t\tme.buildTicks();\n\t\t\tme.afterBuildTicks();\n\n\t\t\tme.beforeTickToLabelConversion();\n\t\t\tme.convertTicksToLabels();\n\t\t\tme.afterTickToLabelConversion();\n\n\t\t\t// Tick Rotation\n\t\t\tme.beforeCalculateTickRotation();\n\t\t\tme.calculateTickRotation();\n\t\t\tme.afterCalculateTickRotation();\n\t\t\t// Fit\n\t\t\tme.beforeFit();\n\t\t\tme.fit();\n\t\t\tme.afterFit();\n\t\t\t//\n\t\t\tme.afterUpdate();\n\n\t\t\treturn me.minSize;\n\n\t\t},\n\t\tafterUpdate: function() {\n\t\t\thelpers.callback(this.options.afterUpdate, [this]);\n\t\t},\n\n\t\t//\n\n\t\tbeforeSetDimensions: function() {\n\t\t\thelpers.callback(this.options.beforeSetDimensions, [this]);\n\t\t},\n\t\tsetDimensions: function() {\n\t\t\tvar me = this;\n\t\t\t// Set the unconstrained dimension before label rotation\n\t\t\tif (me.isHorizontal()) {\n\t\t\t\t// Reset position before calculating rotation\n\t\t\t\tme.width = me.maxWidth;\n\t\t\t\tme.left = 0;\n\t\t\t\tme.right = me.width;\n\t\t\t} else {\n\t\t\t\tme.height = me.maxHeight;\n\n\t\t\t\t// Reset position before calculating rotation\n\t\t\t\tme.top = 0;\n\t\t\t\tme.bottom = me.height;\n\t\t\t}\n\n\t\t\t// Reset padding\n\t\t\tme.paddingLeft = 0;\n\t\t\tme.paddingTop = 0;\n\t\t\tme.paddingRight = 0;\n\t\t\tme.paddingBottom = 0;\n\t\t},\n\t\tafterSetDimensions: function() {\n\t\t\thelpers.callback(this.options.afterSetDimensions, [this]);\n\t\t},\n\n\t\t// Data limits\n\t\tbeforeDataLimits: function() {\n\t\t\thelpers.callback(this.options.beforeDataLimits, [this]);\n\t\t},\n\t\tdetermineDataLimits: helpers.noop,\n\t\tafterDataLimits: function() {\n\t\t\thelpers.callback(this.options.afterDataLimits, [this]);\n\t\t},\n\n\t\t//\n\t\tbeforeBuildTicks: function() {\n\t\t\thelpers.callback(this.options.beforeBuildTicks, [this]);\n\t\t},\n\t\tbuildTicks: helpers.noop,\n\t\tafterBuildTicks: function() {\n\t\t\thelpers.callback(this.options.afterBuildTicks, [this]);\n\t\t},\n\n\t\tbeforeTickToLabelConversion: function() {\n\t\t\thelpers.callback(this.options.beforeTickToLabelConversion, [this]);\n\t\t},\n\t\tconvertTicksToLabels: function() {\n\t\t\tvar me = this;\n\t\t\t// Convert ticks to strings\n\t\t\tvar tickOpts = me.options.ticks;\n\t\t\tme.ticks = me.ticks.map(tickOpts.userCallback || tickOpts.callback);\n\t\t},\n\t\tafterTickToLabelConversion: function() {\n\t\t\thelpers.callback(this.options.afterTickToLabelConversion, [this]);\n\t\t},\n\n\t\t//\n\n\t\tbeforeCalculateTickRotation: function() {\n\t\t\thelpers.callback(this.options.beforeCalculateTickRotation, [this]);\n\t\t},\n\t\tcalculateTickRotation: function() {\n\t\t\tvar me = this;\n\t\t\tvar context = me.ctx;\n\t\t\tvar tickOpts = me.options.ticks;\n\n\t\t\t// Get the width of each grid by calculating the difference\n\t\t\t// between x offsets between 0 and 1.\n\t\t\tvar tickFont = parseFontOptions(tickOpts);\n\t\t\tcontext.font = tickFont.font;\n\n\t\t\tvar labelRotation = tickOpts.minRotation || 0;\n\n\t\t\tif (me.options.display && me.isHorizontal()) {\n\t\t\t\tvar originalLabelWidth = helpers.longestText(context, tickFont.font, me.ticks, me.longestTextCache);\n\t\t\t\tvar labelWidth = originalLabelWidth;\n\t\t\t\tvar cosRotation;\n\t\t\t\tvar sinRotation;\n\n\t\t\t\t// Allow 3 pixels x2 padding either side for label readability\n\t\t\t\tvar tickWidth = me.getPixelForTick(1) - me.getPixelForTick(0) - 6;\n\n\t\t\t\t// Max label rotation can be set or default to 90 - also act as a loop counter\n\t\t\t\twhile (labelWidth > tickWidth && labelRotation < tickOpts.maxRotation) {\n\t\t\t\t\tvar angleRadians = helpers.toRadians(labelRotation);\n\t\t\t\t\tcosRotation = Math.cos(angleRadians);\n\t\t\t\t\tsinRotation = Math.sin(angleRadians);\n\n\t\t\t\t\tif (sinRotation * originalLabelWidth > me.maxHeight) {\n\t\t\t\t\t\t// go back one step\n\t\t\t\t\t\tlabelRotation--;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\n\t\t\t\t\tlabelRotation++;\n\t\t\t\t\tlabelWidth = cosRotation * originalLabelWidth;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tme.labelRotation = labelRotation;\n\t\t},\n\t\tafterCalculateTickRotation: function() {\n\t\t\thelpers.callback(this.options.afterCalculateTickRotation, [this]);\n\t\t},\n\n\t\t//\n\n\t\tbeforeFit: function() {\n\t\t\thelpers.callback(this.options.beforeFit, [this]);\n\t\t},\n\t\tfit: function() {\n\t\t\tvar me = this;\n\t\t\t// Reset\n\t\t\tvar minSize = me.minSize = {\n\t\t\t\twidth: 0,\n\t\t\t\theight: 0\n\t\t\t};\n\n\t\t\tvar opts = me.options;\n\t\t\tvar tickOpts = opts.ticks;\n\t\t\tvar scaleLabelOpts = opts.scaleLabel;\n\t\t\tvar gridLineOpts = opts.gridLines;\n\t\t\tvar display = opts.display;\n\t\t\tvar isHorizontal = me.isHorizontal();\n\n\t\t\tvar tickFont = parseFontOptions(tickOpts);\n\t\t\tvar scaleLabelFontSize = parseFontOptions(scaleLabelOpts).size * 1.5;\n\t\t\tvar tickMarkLength = opts.gridLines.tickMarkLength;\n\n\t\t\t// Width\n\t\t\tif (isHorizontal) {\n\t\t\t\t// subtract the margins to line up with the chartArea if we are a full width scale\n\t\t\t\tminSize.width = me.isFullWidth() ? me.maxWidth - me.margins.left - me.margins.right : me.maxWidth;\n\t\t\t} else {\n\t\t\t\tminSize.width = display && gridLineOpts.drawTicks ? tickMarkLength : 0;\n\t\t\t}\n\n\t\t\t// height\n\t\t\tif (isHorizontal) {\n\t\t\t\tminSize.height = display && gridLineOpts.drawTicks ? tickMarkLength : 0;\n\t\t\t} else {\n\t\t\t\tminSize.height = me.maxHeight; // fill all the height\n\t\t\t}\n\n\t\t\t// Are we showing a title for the scale?\n\t\t\tif (scaleLabelOpts.display && display) {\n\t\t\t\tif (isHorizontal) {\n\t\t\t\t\tminSize.height += scaleLabelFontSize;\n\t\t\t\t} else {\n\t\t\t\t\tminSize.width += scaleLabelFontSize;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Don't bother fitting the ticks if we are not showing them\n\t\t\tif (tickOpts.display && display) {\n\t\t\t\tvar largestTextWidth = helpers.longestText(me.ctx, tickFont.font, me.ticks, me.longestTextCache);\n\t\t\t\tvar tallestLabelHeightInLines = helpers.numberOfLabelLines(me.ticks);\n\t\t\t\tvar lineSpace = tickFont.size * 0.5;\n\n\t\t\t\tif (isHorizontal) {\n\t\t\t\t\t// A horizontal axis is more constrained by the height.\n\t\t\t\t\tme.longestLabelWidth = largestTextWidth;\n\n\t\t\t\t\tvar angleRadians = helpers.toRadians(me.labelRotation);\n\t\t\t\t\tvar cosRotation = Math.cos(angleRadians);\n\t\t\t\t\tvar sinRotation = Math.sin(angleRadians);\n\n\t\t\t\t\t// TODO - improve this calculation\n\t\t\t\t\tvar labelHeight = (sinRotation * largestTextWidth)\n\t\t\t\t\t\t+ (tickFont.size * tallestLabelHeightInLines)\n\t\t\t\t\t\t+ (lineSpace * tallestLabelHeightInLines);\n\n\t\t\t\t\tminSize.height = Math.min(me.maxHeight, minSize.height + labelHeight);\n\t\t\t\t\tme.ctx.font = tickFont.font;\n\n\t\t\t\t\tvar firstTick = me.ticks[0];\n\t\t\t\t\tvar firstLabelWidth = computeTextSize(me.ctx, firstTick, tickFont.font);\n\n\t\t\t\t\tvar lastTick = me.ticks[me.ticks.length - 1];\n\t\t\t\t\tvar lastLabelWidth = computeTextSize(me.ctx, lastTick, tickFont.font);\n\n\t\t\t\t\t// Ensure that our ticks are always inside the canvas. When rotated, ticks are right aligned which means that the right padding is dominated\n\t\t\t\t\t// by the font height\n\t\t\t\t\tif (me.labelRotation !== 0) {\n\t\t\t\t\t\tme.paddingLeft = opts.position === 'bottom'? (cosRotation * firstLabelWidth) + 3: (cosRotation * lineSpace) + 3; // add 3 px to move away from canvas edges\n\t\t\t\t\t\tme.paddingRight = opts.position === 'bottom'? (cosRotation * lineSpace) + 3: (cosRotation * lastLabelWidth) + 3;\n\t\t\t\t\t} else {\n\t\t\t\t\t\tme.paddingLeft = firstLabelWidth / 2 + 3; // add 3 px to move away from canvas edges\n\t\t\t\t\t\tme.paddingRight = lastLabelWidth / 2 + 3;\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\t// A vertical axis is more constrained by the width. Labels are the dominant factor here, so get that length first\n\t\t\t\t\t// Account for padding\n\n\t\t\t\t\tif (tickOpts.mirror) {\n\t\t\t\t\t\tlargestTextWidth = 0;\n\t\t\t\t\t} else {\n\t\t\t\t\t\tlargestTextWidth += me.options.ticks.padding;\n\t\t\t\t\t}\n\t\t\t\t\tminSize.width = Math.min(me.maxWidth, minSize.width + largestTextWidth);\n\t\t\t\t\tme.paddingTop = tickFont.size / 2;\n\t\t\t\t\tme.paddingBottom = tickFont.size / 2;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tme.handleMargins();\n\n\t\t\tme.width = minSize.width;\n\t\t\tme.height = minSize.height;\n\t\t},\n\n\t\t/**\n\t\t * Handle margins and padding interactions\n\t\t * @private\n\t\t */\n\t\thandleMargins: function() {\n\t\t\tvar me = this;\n\t\t\tif (me.margins) {\n\t\t\t\tme.paddingLeft = Math.max(me.paddingLeft - me.margins.left, 0);\n\t\t\t\tme.paddingTop = Math.max(me.paddingTop - me.margins.top, 0);\n\t\t\t\tme.paddingRight = Math.max(me.paddingRight - me.margins.right, 0);\n\t\t\t\tme.paddingBottom = Math.max(me.paddingBottom - me.margins.bottom, 0);\n\t\t\t}\n\t\t},\n\n\t\tafterFit: function() {\n\t\t\thelpers.callback(this.options.afterFit, [this]);\n\t\t},\n\n\t\t// Shared Methods\n\t\tisHorizontal: function() {\n\t\t\treturn this.options.position === 'top' || this.options.position === 'bottom';\n\t\t},\n\t\tisFullWidth: function() {\n\t\t\treturn (this.options.fullWidth);\n\t\t},\n\n\t\t// Get the correct value. NaN bad inputs, If the value type is object get the x or y based on whether we are horizontal or not\n\t\tgetRightValue: function(rawValue) {\n\t\t\t// Null and undefined values first\n\t\t\tif (rawValue === null || typeof(rawValue) === 'undefined') {\n\t\t\t\treturn NaN;\n\t\t\t}\n\t\t\t// isNaN(object) returns true, so make sure NaN is checking for a number; Discard Infinite values\n\t\t\tif (typeof(rawValue) === 'number' && !isFinite(rawValue)) {\n\t\t\t\treturn NaN;\n\t\t\t}\n\t\t\t// If it is in fact an object, dive in one more level\n\t\t\tif (typeof(rawValue) === 'object') {\n\t\t\t\tif ((rawValue instanceof Date) || (rawValue.isValid)) {\n\t\t\t\t\treturn rawValue;\n\t\t\t\t}\n\t\t\t\treturn this.getRightValue(this.isHorizontal() ? rawValue.x : rawValue.y);\n\t\t\t}\n\n\t\t\t// Value is good, return it\n\t\t\treturn rawValue;\n\t\t},\n\n\t\t// Used to get the value to display in the tooltip for the data at the given index\n\t\t// function getLabelForIndex(index, datasetIndex)\n\t\tgetLabelForIndex: helpers.noop,\n\n\t\t// Used to get data value locations.  Value can either be an index or a numerical value\n\t\tgetPixelForValue: helpers.noop,\n\n\t\t// Used to get the data value from a given pixel. This is the inverse of getPixelForValue\n\t\tgetValueForPixel: helpers.noop,\n\n\t\t// Used for tick location, should\n\t\tgetPixelForTick: function(index, includeOffset) {\n\t\t\tvar me = this;\n\t\t\tif (me.isHorizontal()) {\n\t\t\t\tvar innerWidth = me.width - (me.paddingLeft + me.paddingRight);\n\t\t\t\tvar tickWidth = innerWidth / Math.max((me.ticks.length - ((me.options.gridLines.offsetGridLines) ? 0 : 1)), 1);\n\t\t\t\tvar pixel = (tickWidth * index) + me.paddingLeft;\n\n\t\t\t\tif (includeOffset) {\n\t\t\t\t\tpixel += tickWidth / 2;\n\t\t\t\t}\n\n\t\t\t\tvar finalVal = me.left + Math.round(pixel);\n\t\t\t\tfinalVal += me.isFullWidth() ? me.margins.left : 0;\n\t\t\t\treturn finalVal;\n\t\t\t}\n\t\t\tvar innerHeight = me.height - (me.paddingTop + me.paddingBottom);\n\t\t\treturn me.top + (index * (innerHeight / (me.ticks.length - 1)));\n\t\t},\n\n\t\t// Utility for getting the pixel location of a percentage of scale\n\t\tgetPixelForDecimal: function(decimal /* , includeOffset*/) {\n\t\t\tvar me = this;\n\t\t\tif (me.isHorizontal()) {\n\t\t\t\tvar innerWidth = me.width - (me.paddingLeft + me.paddingRight);\n\t\t\t\tvar valueOffset = (innerWidth * decimal) + me.paddingLeft;\n\n\t\t\t\tvar finalVal = me.left + Math.round(valueOffset);\n\t\t\t\tfinalVal += me.isFullWidth() ? me.margins.left : 0;\n\t\t\t\treturn finalVal;\n\t\t\t}\n\t\t\treturn me.top + (decimal * me.height);\n\t\t},\n\n\t\tgetBasePixel: function() {\n\t\t\treturn this.getPixelForValue(this.getBaseValue());\n\t\t},\n\n\t\tgetBaseValue: function() {\n\t\t\tvar me = this;\n\t\t\tvar min = me.min;\n\t\t\tvar max = me.max;\n\n\t\t\treturn me.beginAtZero ? 0:\n\t\t\t\tmin < 0 && max < 0? max :\n\t\t\t\tmin > 0 && max > 0? min :\n\t\t\t\t0;\n\t\t},\n\n\t\t// Actually draw the scale on the canvas\n\t\t// @param {rectangle} chartArea : the area of the chart to draw full grid lines on\n\t\tdraw: function(chartArea) {\n\t\t\tvar me = this;\n\t\t\tvar options = me.options;\n\t\t\tif (!options.display) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tvar context = me.ctx;\n\t\t\tvar globalDefaults = Chart.defaults.global;\n\t\t\tvar optionTicks = options.ticks;\n\t\t\tvar gridLines = options.gridLines;\n\t\t\tvar scaleLabel = options.scaleLabel;\n\n\t\t\tvar isRotated = me.labelRotation !== 0;\n\t\t\tvar skipRatio;\n\t\t\tvar useAutoskipper = optionTicks.autoSkip;\n\t\t\tvar isHorizontal = me.isHorizontal();\n\n\t\t\t// figure out the maximum number of gridlines to show\n\t\t\tvar maxTicks;\n\t\t\tif (optionTicks.maxTicksLimit) {\n\t\t\t\tmaxTicks = optionTicks.maxTicksLimit;\n\t\t\t}\n\n\t\t\tvar tickFontColor = helpers.getValueOrDefault(optionTicks.fontColor, globalDefaults.defaultFontColor);\n\t\t\tvar tickFont = parseFontOptions(optionTicks);\n\n\t\t\tvar tl = gridLines.drawTicks ? gridLines.tickMarkLength : 0;\n\n\t\t\tvar scaleLabelFontColor = helpers.getValueOrDefault(scaleLabel.fontColor, globalDefaults.defaultFontColor);\n\t\t\tvar scaleLabelFont = parseFontOptions(scaleLabel);\n\n\t\t\tvar labelRotationRadians = helpers.toRadians(me.labelRotation);\n\t\t\tvar cosRotation = Math.cos(labelRotationRadians);\n\t\t\tvar longestRotatedLabel = me.longestLabelWidth * cosRotation;\n\n\t\t\t// Make sure we draw text in the correct color and font\n\t\t\tcontext.fillStyle = tickFontColor;\n\n\t\t\tvar itemsToDraw = [];\n\n\t\t\tif (isHorizontal) {\n\t\t\t\tskipRatio = false;\n\n\t\t\t\tif ((longestRotatedLabel + optionTicks.autoSkipPadding) * me.ticks.length > (me.width - (me.paddingLeft + me.paddingRight))) {\n\t\t\t\t\tskipRatio = 1 + Math.floor(((longestRotatedLabel + optionTicks.autoSkipPadding) * me.ticks.length) / (me.width - (me.paddingLeft + me.paddingRight)));\n\t\t\t\t}\n\n\t\t\t\t// if they defined a max number of optionTicks,\n\t\t\t\t// increase skipRatio until that number is met\n\t\t\t\tif (maxTicks && me.ticks.length > maxTicks) {\n\t\t\t\t\twhile (!skipRatio || me.ticks.length / (skipRatio || 1) > maxTicks) {\n\t\t\t\t\t\tif (!skipRatio) {\n\t\t\t\t\t\t\tskipRatio = 1;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tskipRatio += 1;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif (!useAutoskipper) {\n\t\t\t\t\tskipRatio = false;\n\t\t\t\t}\n\t\t\t}\n\n\n\t\t\tvar xTickStart = options.position === 'right' ? me.left : me.right - tl;\n\t\t\tvar xTickEnd = options.position === 'right' ? me.left + tl : me.right;\n\t\t\tvar yTickStart = options.position === 'bottom' ? me.top : me.bottom - tl;\n\t\t\tvar yTickEnd = options.position === 'bottom' ? me.top + tl : me.bottom;\n\n\t\t\thelpers.each(me.ticks, function(label, index) {\n\t\t\t\t// If the callback returned a null or undefined value, do not draw this line\n\t\t\t\tif (label === undefined || label === null) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tvar isLastTick = me.ticks.length === index + 1;\n\n\t\t\t\t// Since we always show the last tick,we need may need to hide the last shown one before\n\t\t\t\tvar shouldSkip = (skipRatio > 1 && index % skipRatio > 0) || (index % skipRatio === 0 && index + skipRatio >= me.ticks.length);\n\t\t\t\tif (shouldSkip && !isLastTick || (label === undefined || label === null)) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tvar lineWidth, lineColor, borderDash, borderDashOffset;\n\t\t\t\tif (index === (typeof me.zeroLineIndex !== 'undefined' ? me.zeroLineIndex : 0)) {\n\t\t\t\t\t// Draw the first index specially\n\t\t\t\t\tlineWidth = gridLines.zeroLineWidth;\n\t\t\t\t\tlineColor = gridLines.zeroLineColor;\n\t\t\t\t\tborderDash = gridLines.zeroLineBorderDash;\n\t\t\t\t\tborderDashOffset = gridLines.zeroLineBorderDashOffset;\n\t\t\t\t} else {\n\t\t\t\t\tlineWidth = helpers.getValueAtIndexOrDefault(gridLines.lineWidth, index);\n\t\t\t\t\tlineColor = helpers.getValueAtIndexOrDefault(gridLines.color, index);\n\t\t\t\t\tborderDash = helpers.getValueOrDefault(gridLines.borderDash, globalDefaults.borderDash);\n\t\t\t\t\tborderDashOffset = helpers.getValueOrDefault(gridLines.borderDashOffset, globalDefaults.borderDashOffset);\n\t\t\t\t}\n\n\t\t\t\t// Common properties\n\t\t\t\tvar tx1, ty1, tx2, ty2, x1, y1, x2, y2, labelX, labelY;\n\t\t\t\tvar textAlign = 'middle';\n\t\t\t\tvar textBaseline = 'middle';\n\n\t\t\t\tif (isHorizontal) {\n\n\t\t\t\t\tif (options.position === 'bottom') {\n\t\t\t\t\t\t// bottom\n\t\t\t\t\t\ttextBaseline = !isRotated? 'top':'middle';\n\t\t\t\t\t\ttextAlign = !isRotated? 'center': 'right';\n\t\t\t\t\t\tlabelY = me.top + tl;\n\t\t\t\t\t} else {\n\t\t\t\t\t\t// top\n\t\t\t\t\t\ttextBaseline = !isRotated? 'bottom':'middle';\n\t\t\t\t\t\ttextAlign = !isRotated? 'center': 'left';\n\t\t\t\t\t\tlabelY = me.bottom - tl;\n\t\t\t\t\t}\n\n\t\t\t\t\tvar xLineValue = me.getPixelForTick(index) + helpers.aliasPixel(lineWidth); // xvalues for grid lines\n\t\t\t\t\tlabelX = me.getPixelForTick(index, gridLines.offsetGridLines) + optionTicks.labelOffset; // x values for optionTicks (need to consider offsetLabel option)\n\n\t\t\t\t\ttx1 = tx2 = x1 = x2 = xLineValue;\n\t\t\t\t\tty1 = yTickStart;\n\t\t\t\t\tty2 = yTickEnd;\n\t\t\t\t\ty1 = chartArea.top;\n\t\t\t\t\ty2 = chartArea.bottom;\n\t\t\t\t} else {\n\t\t\t\t\tvar isLeft = options.position === 'left';\n\t\t\t\t\tvar tickPadding = optionTicks.padding;\n\t\t\t\t\tvar labelXOffset;\n\n\t\t\t\t\tif (optionTicks.mirror) {\n\t\t\t\t\t\ttextAlign = isLeft ? 'left' : 'right';\n\t\t\t\t\t\tlabelXOffset = tickPadding;\n\t\t\t\t\t} else {\n\t\t\t\t\t\ttextAlign = isLeft ? 'right' : 'left';\n\t\t\t\t\t\tlabelXOffset = tl + tickPadding;\n\t\t\t\t\t}\n\n\t\t\t\t\tlabelX = isLeft ? me.right - labelXOffset : me.left + labelXOffset;\n\n\t\t\t\t\tvar yLineValue = me.getPixelForTick(index); // xvalues for grid lines\n\t\t\t\t\tyLineValue += helpers.aliasPixel(lineWidth);\n\t\t\t\t\tlabelY = me.getPixelForTick(index, gridLines.offsetGridLines);\n\n\t\t\t\t\ttx1 = xTickStart;\n\t\t\t\t\ttx2 = xTickEnd;\n\t\t\t\t\tx1 = chartArea.left;\n\t\t\t\t\tx2 = chartArea.right;\n\t\t\t\t\tty1 = ty2 = y1 = y2 = yLineValue;\n\t\t\t\t}\n\n\t\t\t\titemsToDraw.push({\n\t\t\t\t\ttx1: tx1,\n\t\t\t\t\tty1: ty1,\n\t\t\t\t\ttx2: tx2,\n\t\t\t\t\tty2: ty2,\n\t\t\t\t\tx1: x1,\n\t\t\t\t\ty1: y1,\n\t\t\t\t\tx2: x2,\n\t\t\t\t\ty2: y2,\n\t\t\t\t\tlabelX: labelX,\n\t\t\t\t\tlabelY: labelY,\n\t\t\t\t\tglWidth: lineWidth,\n\t\t\t\t\tglColor: lineColor,\n\t\t\t\t\tglBorderDash: borderDash,\n\t\t\t\t\tglBorderDashOffset: borderDashOffset,\n\t\t\t\t\trotation: -1 * labelRotationRadians,\n\t\t\t\t\tlabel: label,\n\t\t\t\t\ttextBaseline: textBaseline,\n\t\t\t\t\ttextAlign: textAlign\n\t\t\t\t});\n\t\t\t});\n\n\t\t\t// Draw all of the tick labels, tick marks, and grid lines at the correct places\n\t\t\thelpers.each(itemsToDraw, function(itemToDraw) {\n\t\t\t\tif (gridLines.display) {\n\t\t\t\t\tcontext.save();\n\t\t\t\t\tcontext.lineWidth = itemToDraw.glWidth;\n\t\t\t\t\tcontext.strokeStyle = itemToDraw.glColor;\n\t\t\t\t\tif (context.setLineDash) {\n\t\t\t\t\t\tcontext.setLineDash(itemToDraw.glBorderDash);\n\t\t\t\t\t\tcontext.lineDashOffset = itemToDraw.glBorderDashOffset;\n\t\t\t\t\t}\n\n\t\t\t\t\tcontext.beginPath();\n\n\t\t\t\t\tif (gridLines.drawTicks) {\n\t\t\t\t\t\tcontext.moveTo(itemToDraw.tx1, itemToDraw.ty1);\n\t\t\t\t\t\tcontext.lineTo(itemToDraw.tx2, itemToDraw.ty2);\n\t\t\t\t\t}\n\n\t\t\t\t\tif (gridLines.drawOnChartArea) {\n\t\t\t\t\t\tcontext.moveTo(itemToDraw.x1, itemToDraw.y1);\n\t\t\t\t\t\tcontext.lineTo(itemToDraw.x2, itemToDraw.y2);\n\t\t\t\t\t}\n\n\t\t\t\t\tcontext.stroke();\n\t\t\t\t\tcontext.restore();\n\t\t\t\t}\n\n\t\t\t\tif (optionTicks.display) {\n\t\t\t\t\tcontext.save();\n\t\t\t\t\tcontext.translate(itemToDraw.labelX, itemToDraw.labelY);\n\t\t\t\t\tcontext.rotate(itemToDraw.rotation);\n\t\t\t\t\tcontext.font = tickFont.font;\n\t\t\t\t\tcontext.textBaseline = itemToDraw.textBaseline;\n\t\t\t\t\tcontext.textAlign = itemToDraw.textAlign;\n\n\t\t\t\t\tvar label = itemToDraw.label;\n\t\t\t\t\tif (helpers.isArray(label)) {\n\t\t\t\t\t\tfor (var i = 0, y = 0; i < label.length; ++i) {\n\t\t\t\t\t\t\t// We just make sure the multiline element is a string here..\n\t\t\t\t\t\t\tcontext.fillText('' + label[i], 0, y);\n\t\t\t\t\t\t\t// apply same lineSpacing as calculated @ L#320\n\t\t\t\t\t\t\ty += (tickFont.size * 1.5);\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\tcontext.fillText(label, 0, 0);\n\t\t\t\t\t}\n\t\t\t\t\tcontext.restore();\n\t\t\t\t}\n\t\t\t});\n\n\t\t\tif (scaleLabel.display) {\n\t\t\t\t// Draw the scale label\n\t\t\t\tvar scaleLabelX;\n\t\t\t\tvar scaleLabelY;\n\t\t\t\tvar rotation = 0;\n\n\t\t\t\tif (isHorizontal) {\n\t\t\t\t\tscaleLabelX = me.left + ((me.right - me.left) / 2); // midpoint of the width\n\t\t\t\t\tscaleLabelY = options.position === 'bottom' ? me.bottom - (scaleLabelFont.size / 2) : me.top + (scaleLabelFont.size / 2);\n\t\t\t\t} else {\n\t\t\t\t\tvar isLeft = options.position === 'left';\n\t\t\t\t\tscaleLabelX = isLeft ? me.left + (scaleLabelFont.size / 2) : me.right - (scaleLabelFont.size / 2);\n\t\t\t\t\tscaleLabelY = me.top + ((me.bottom - me.top) / 2);\n\t\t\t\t\trotation = isLeft ? -0.5 * Math.PI : 0.5 * Math.PI;\n\t\t\t\t}\n\n\t\t\t\tcontext.save();\n\t\t\t\tcontext.translate(scaleLabelX, scaleLabelY);\n\t\t\t\tcontext.rotate(rotation);\n\t\t\t\tcontext.textAlign = 'center';\n\t\t\t\tcontext.textBaseline = 'middle';\n\t\t\t\tcontext.fillStyle = scaleLabelFontColor; // render in correct colour\n\t\t\t\tcontext.font = scaleLabelFont.font;\n\t\t\t\tcontext.fillText(scaleLabel.labelString, 0, 0);\n\t\t\t\tcontext.restore();\n\t\t\t}\n\n\t\t\tif (gridLines.drawBorder) {\n\t\t\t\t// Draw the line at the edge of the axis\n\t\t\t\tcontext.lineWidth = helpers.getValueAtIndexOrDefault(gridLines.lineWidth, 0);\n\t\t\t\tcontext.strokeStyle = helpers.getValueAtIndexOrDefault(gridLines.color, 0);\n\t\t\t\tvar x1 = me.left,\n\t\t\t\t\tx2 = me.right,\n\t\t\t\t\ty1 = me.top,\n\t\t\t\t\ty2 = me.bottom;\n\n\t\t\t\tvar aliasPixel = helpers.aliasPixel(context.lineWidth);\n\t\t\t\tif (isHorizontal) {\n\t\t\t\t\ty1 = y2 = options.position === 'top' ? me.bottom : me.top;\n\t\t\t\t\ty1 += aliasPixel;\n\t\t\t\t\ty2 += aliasPixel;\n\t\t\t\t} else {\n\t\t\t\t\tx1 = x2 = options.position === 'left' ? me.right : me.left;\n\t\t\t\t\tx1 += aliasPixel;\n\t\t\t\t\tx2 += aliasPixel;\n\t\t\t\t}\n\n\t\t\t\tcontext.beginPath();\n\t\t\t\tcontext.moveTo(x1, y1);\n\t\t\t\tcontext.lineTo(x2, y2);\n\t\t\t\tcontext.stroke();\n\t\t\t}\n\t\t}\n\t});\n};\n"
  },
  {
    "path": "app_backend/static/plugin/Chart.js-2.6.0/src/core/core.scaleService.js",
    "content": "'use strict';\n\nmodule.exports = function(Chart) {\n\n\tvar helpers = Chart.helpers;\n\n\tChart.scaleService = {\n\t\t// Scale registration object. Extensions can register new scale types (such as log or DB scales) and then\n\t\t// use the new chart options to grab the correct scale\n\t\tconstructors: {},\n\t\t// Use a registration function so that we can move to an ES6 map when we no longer need to support\n\t\t// old browsers\n\n\t\t// Scale config defaults\n\t\tdefaults: {},\n\t\tregisterScaleType: function(type, scaleConstructor, defaults) {\n\t\t\tthis.constructors[type] = scaleConstructor;\n\t\t\tthis.defaults[type] = helpers.clone(defaults);\n\t\t},\n\t\tgetScaleConstructor: function(type) {\n\t\t\treturn this.constructors.hasOwnProperty(type) ? this.constructors[type] : undefined;\n\t\t},\n\t\tgetScaleDefaults: function(type) {\n\t\t\t// Return the scale defaults merged with the global settings so that we always use the latest ones\n\t\t\treturn this.defaults.hasOwnProperty(type) ? helpers.scaleMerge(Chart.defaults.scale, this.defaults[type]) : {};\n\t\t},\n\t\tupdateScaleDefaults: function(type, additions) {\n\t\t\tvar defaults = this.defaults;\n\t\t\tif (defaults.hasOwnProperty(type)) {\n\t\t\t\tdefaults[type] = helpers.extend(defaults[type], additions);\n\t\t\t}\n\t\t},\n\t\taddScalesToLayout: function(chart) {\n\t\t\t// Adds each scale to the chart.boxes array to be sized accordingly\n\t\t\thelpers.each(chart.scales, function(scale) {\n\t\t\t\t// Set ILayoutItem parameters for backwards compatibility\n\t\t\t\tscale.fullWidth = scale.options.fullWidth;\n\t\t\t\tscale.position = scale.options.position;\n\t\t\t\tscale.weight = scale.options.weight;\n\t\t\t\tChart.layoutService.addBox(chart, scale);\n\t\t\t});\n\t\t}\n\t};\n};\n"
  },
  {
    "path": "app_backend/static/plugin/Chart.js-2.6.0/src/core/core.ticks.js",
    "content": "'use strict';\n\nmodule.exports = function(Chart) {\n\n\tvar helpers = Chart.helpers;\n\n\t/**\n\t * Namespace to hold static tick generation functions\n\t * @namespace Chart.Ticks\n\t */\n\tChart.Ticks = {\n\t\t/**\n\t\t * Namespace to hold generators for different types of ticks\n\t\t * @namespace Chart.Ticks.generators\n\t\t */\n\t\tgenerators: {\n\t\t\t/**\n\t\t\t * Interface for the options provided to the numeric tick generator\n\t\t\t * @interface INumericTickGenerationOptions\n\t\t\t */\n\t\t\t/**\n\t\t\t * The maximum number of ticks to display\n\t\t\t * @name INumericTickGenerationOptions#maxTicks\n\t\t\t * @type Number\n\t\t\t */\n\t\t\t/**\n\t\t\t * The distance between each tick.\n\t\t\t * @name INumericTickGenerationOptions#stepSize\n\t\t\t * @type Number\n\t\t\t * @optional\n\t\t\t */\n\t\t\t/**\n\t\t\t * Forced minimum for the ticks. If not specified, the minimum of the data range is used to calculate the tick minimum\n\t\t\t * @name INumericTickGenerationOptions#min\n\t\t\t * @type Number\n\t\t\t * @optional\n\t\t\t */\n\t\t\t/**\n\t\t\t * The maximum value of the ticks. If not specified, the maximum of the data range is used to calculate the tick maximum\n\t\t\t * @name INumericTickGenerationOptions#max\n\t\t\t * @type Number\n\t\t\t * @optional\n\t\t\t */\n\n\t\t\t/**\n\t\t\t * Generate a set of linear ticks\n\t\t\t * @method Chart.Ticks.generators.linear\n\t\t\t * @param generationOptions {INumericTickGenerationOptions} the options used to generate the ticks\n\t\t\t * @param dataRange {IRange} the range of the data\n\t\t\t * @returns {Array<Number>} array of tick values\n\t\t\t */\n\t\t\tlinear: function(generationOptions, dataRange) {\n\t\t\t\tvar ticks = [];\n\t\t\t\t// To get a \"nice\" value for the tick spacing, we will use the appropriately named\n\t\t\t\t// \"nice number\" algorithm. See http://stackoverflow.com/questions/8506881/nice-label-algorithm-for-charts-with-minimum-ticks\n\t\t\t\t// for details.\n\n\t\t\t\tvar spacing;\n\t\t\t\tif (generationOptions.stepSize && generationOptions.stepSize > 0) {\n\t\t\t\t\tspacing = generationOptions.stepSize;\n\t\t\t\t} else {\n\t\t\t\t\tvar niceRange = helpers.niceNum(dataRange.max - dataRange.min, false);\n\t\t\t\t\tspacing = helpers.niceNum(niceRange / (generationOptions.maxTicks - 1), true);\n\t\t\t\t}\n\t\t\t\tvar niceMin = Math.floor(dataRange.min / spacing) * spacing;\n\t\t\t\tvar niceMax = Math.ceil(dataRange.max / spacing) * spacing;\n\n\t\t\t\t// If min, max and stepSize is set and they make an evenly spaced scale use it.\n\t\t\t\tif (generationOptions.min && generationOptions.max && generationOptions.stepSize) {\n\t\t\t\t\t// If very close to our whole number, use it.\n\t\t\t\t\tif (helpers.almostWhole((generationOptions.max - generationOptions.min) / generationOptions.stepSize, spacing / 1000)) {\n\t\t\t\t\t\tniceMin = generationOptions.min;\n\t\t\t\t\t\tniceMax = generationOptions.max;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tvar numSpaces = (niceMax - niceMin) / spacing;\n\t\t\t\t// If very close to our rounded value, use it.\n\t\t\t\tif (helpers.almostEquals(numSpaces, Math.round(numSpaces), spacing / 1000)) {\n\t\t\t\t\tnumSpaces = Math.round(numSpaces);\n\t\t\t\t} else {\n\t\t\t\t\tnumSpaces = Math.ceil(numSpaces);\n\t\t\t\t}\n\n\t\t\t\t// Put the values into the ticks array\n\t\t\t\tticks.push(generationOptions.min !== undefined ? generationOptions.min : niceMin);\n\t\t\t\tfor (var j = 1; j < numSpaces; ++j) {\n\t\t\t\t\tticks.push(niceMin + (j * spacing));\n\t\t\t\t}\n\t\t\t\tticks.push(generationOptions.max !== undefined ? generationOptions.max : niceMax);\n\n\t\t\t\treturn ticks;\n\t\t\t},\n\n\t\t\t/**\n\t\t\t * Generate a set of logarithmic ticks\n\t\t\t * @method Chart.Ticks.generators.logarithmic\n\t\t\t * @param generationOptions {INumericTickGenerationOptions} the options used to generate the ticks\n\t\t\t * @param dataRange {IRange} the range of the data\n\t\t\t * @returns {Array<Number>} array of tick values\n\t\t\t */\n\t\t\tlogarithmic: function(generationOptions, dataRange) {\n\t\t\t\tvar ticks = [];\n\t\t\t\tvar getValueOrDefault = helpers.getValueOrDefault;\n\n\t\t\t\t// Figure out what the max number of ticks we can support it is based on the size of\n\t\t\t\t// the axis area. For now, we say that the minimum tick spacing in pixels must be 50\n\t\t\t\t// We also limit the maximum number of ticks to 11 which gives a nice 10 squares on\n\t\t\t\t// the graph\n\t\t\t\tvar tickVal = getValueOrDefault(generationOptions.min, Math.pow(10, Math.floor(helpers.log10(dataRange.min))));\n\n\t\t\t\tvar endExp = Math.floor(helpers.log10(dataRange.max));\n\t\t\t\tvar endSignificand = Math.ceil(dataRange.max / Math.pow(10, endExp));\n\t\t\t\tvar exp;\n\t\t\t\tvar significand;\n\n\t\t\t\tif (tickVal === 0) {\n\t\t\t\t\texp = Math.floor(helpers.log10(dataRange.minNotZero));\n\t\t\t\t\tsignificand = Math.floor(dataRange.minNotZero / Math.pow(10, exp));\n\n\t\t\t\t\tticks.push(tickVal);\n\t\t\t\t\ttickVal = significand * Math.pow(10, exp);\n\t\t\t\t} else {\n\t\t\t\t\texp = Math.floor(helpers.log10(tickVal));\n\t\t\t\t\tsignificand = Math.floor(tickVal / Math.pow(10, exp));\n\t\t\t\t}\n\n\t\t\t\tdo {\n\t\t\t\t\tticks.push(tickVal);\n\n\t\t\t\t\t++significand;\n\t\t\t\t\tif (significand === 10) {\n\t\t\t\t\t\tsignificand = 1;\n\t\t\t\t\t\t++exp;\n\t\t\t\t\t}\n\n\t\t\t\t\ttickVal = significand * Math.pow(10, exp);\n\t\t\t\t} while (exp < endExp || (exp === endExp && significand < endSignificand));\n\n\t\t\t\tvar lastTick = getValueOrDefault(generationOptions.max, tickVal);\n\t\t\t\tticks.push(lastTick);\n\n\t\t\t\treturn ticks;\n\t\t\t}\n\t\t},\n\n\t\t/**\n\t\t * Namespace to hold formatters for different types of ticks\n\t\t * @namespace Chart.Ticks.formatters\n\t\t */\n\t\tformatters: {\n\t\t\t/**\n\t\t\t * Formatter for value labels\n\t\t\t * @method Chart.Ticks.formatters.values\n\t\t\t * @param value the value to display\n\t\t\t * @return {String|Array} the label to display\n\t\t\t */\n\t\t\tvalues: function(value) {\n\t\t\t\treturn helpers.isArray(value) ? value : '' + value;\n\t\t\t},\n\n\t\t\t/**\n\t\t\t * Formatter for linear numeric ticks\n\t\t\t * @method Chart.Ticks.formatters.linear\n\t\t\t * @param tickValue {Number} the value to be formatted\n\t\t\t * @param index {Number} the position of the tickValue parameter in the ticks array\n\t\t\t * @param ticks {Array<Number>} the list of ticks being converted\n\t\t\t * @return {String} string representation of the tickValue parameter\n\t\t\t */\n\t\t\tlinear: function(tickValue, index, ticks) {\n\t\t\t\t// If we have lots of ticks, don't use the ones\n\t\t\t\tvar delta = ticks.length > 3 ? ticks[2] - ticks[1] : ticks[1] - ticks[0];\n\n\t\t\t\t// If we have a number like 2.5 as the delta, figure out how many decimal places we need\n\t\t\t\tif (Math.abs(delta) > 1) {\n\t\t\t\t\tif (tickValue !== Math.floor(tickValue)) {\n\t\t\t\t\t\t// not an integer\n\t\t\t\t\t\tdelta = tickValue - Math.floor(tickValue);\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tvar logDelta = helpers.log10(Math.abs(delta));\n\t\t\t\tvar tickString = '';\n\n\t\t\t\tif (tickValue !== 0) {\n\t\t\t\t\tvar numDecimal = -1 * Math.floor(logDelta);\n\t\t\t\t\tnumDecimal = Math.max(Math.min(numDecimal, 20), 0); // toFixed has a max of 20 decimal places\n\t\t\t\t\ttickString = tickValue.toFixed(numDecimal);\n\t\t\t\t} else {\n\t\t\t\t\ttickString = '0'; // never show decimal places for 0\n\t\t\t\t}\n\n\t\t\t\treturn tickString;\n\t\t\t},\n\n\t\t\tlogarithmic: function(tickValue, index, ticks) {\n\t\t\t\tvar remain = tickValue / (Math.pow(10, Math.floor(helpers.log10(tickValue))));\n\n\t\t\t\tif (tickValue === 0) {\n\t\t\t\t\treturn '0';\n\t\t\t\t} else if (remain === 1 || remain === 2 || remain === 5 || index === 0 || index === ticks.length - 1) {\n\t\t\t\t\treturn tickValue.toExponential();\n\t\t\t\t}\n\t\t\t\treturn '';\n\t\t\t}\n\t\t}\n\t};\n};\n"
  },
  {
    "path": "app_backend/static/plugin/Chart.js-2.6.0/src/core/core.tooltip.js",
    "content": "'use strict';\n\nmodule.exports = function(Chart) {\n\n\tvar helpers = Chart.helpers;\n\n\t/**\n \t * Helper method to merge the opacity into a color\n \t */\n\tfunction mergeOpacity(colorString, opacity) {\n\t\tvar color = helpers.color(colorString);\n\t\treturn color.alpha(opacity * color.alpha()).rgbaString();\n\t}\n\n\tChart.defaults.global.tooltips = {\n\t\tenabled: true,\n\t\tcustom: null,\n\t\tmode: 'nearest',\n\t\tposition: 'average',\n\t\tintersect: true,\n\t\tbackgroundColor: 'rgba(0,0,0,0.8)',\n\t\ttitleFontStyle: 'bold',\n\t\ttitleSpacing: 2,\n\t\ttitleMarginBottom: 6,\n\t\ttitleFontColor: '#fff',\n\t\ttitleAlign: 'left',\n\t\tbodySpacing: 2,\n\t\tbodyFontColor: '#fff',\n\t\tbodyAlign: 'left',\n\t\tfooterFontStyle: 'bold',\n\t\tfooterSpacing: 2,\n\t\tfooterMarginTop: 6,\n\t\tfooterFontColor: '#fff',\n\t\tfooterAlign: 'left',\n\t\tyPadding: 6,\n\t\txPadding: 6,\n\t\tcaretPadding: 2,\n\t\tcaretSize: 5,\n\t\tcornerRadius: 6,\n\t\tmultiKeyBackground: '#fff',\n\t\tdisplayColors: true,\n\t\tborderColor: 'rgba(0,0,0,0)',\n\t\tborderWidth: 0,\n\t\tcallbacks: {\n\t\t\t// Args are: (tooltipItems, data)\n\t\t\tbeforeTitle: helpers.noop,\n\t\t\ttitle: function(tooltipItems, data) {\n\t\t\t\t// Pick first xLabel for now\n\t\t\t\tvar title = '';\n\t\t\t\tvar labels = data.labels;\n\t\t\t\tvar labelCount = labels ? labels.length : 0;\n\n\t\t\t\tif (tooltipItems.length > 0) {\n\t\t\t\t\tvar item = tooltipItems[0];\n\n\t\t\t\t\tif (item.xLabel) {\n\t\t\t\t\t\ttitle = item.xLabel;\n\t\t\t\t\t} else if (labelCount > 0 && item.index < labelCount) {\n\t\t\t\t\t\ttitle = labels[item.index];\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\treturn title;\n\t\t\t},\n\t\t\tafterTitle: helpers.noop,\n\n\t\t\t// Args are: (tooltipItems, data)\n\t\t\tbeforeBody: helpers.noop,\n\n\t\t\t// Args are: (tooltipItem, data)\n\t\t\tbeforeLabel: helpers.noop,\n\t\t\tlabel: function(tooltipItem, data) {\n\t\t\t\tvar label = data.datasets[tooltipItem.datasetIndex].label || '';\n\n\t\t\t\tif (label) {\n\t\t\t\t\tlabel += ': ';\n\t\t\t\t}\n\t\t\t\tlabel += tooltipItem.yLabel;\n\t\t\t\treturn label;\n\t\t\t},\n\t\t\tlabelColor: function(tooltipItem, chart) {\n\t\t\t\tvar meta = chart.getDatasetMeta(tooltipItem.datasetIndex);\n\t\t\t\tvar activeElement = meta.data[tooltipItem.index];\n\t\t\t\tvar view = activeElement._view;\n\t\t\t\treturn {\n\t\t\t\t\tborderColor: view.borderColor,\n\t\t\t\t\tbackgroundColor: view.backgroundColor\n\t\t\t\t};\n\t\t\t},\n\t\t\tafterLabel: helpers.noop,\n\n\t\t\t// Args are: (tooltipItems, data)\n\t\t\tafterBody: helpers.noop,\n\n\t\t\t// Args are: (tooltipItems, data)\n\t\t\tbeforeFooter: helpers.noop,\n\t\t\tfooter: helpers.noop,\n\t\t\tafterFooter: helpers.noop\n\t\t}\n\t};\n\n\t// Helper to push or concat based on if the 2nd parameter is an array or not\n\tfunction pushOrConcat(base, toPush) {\n\t\tif (toPush) {\n\t\t\tif (helpers.isArray(toPush)) {\n\t\t\t\t// base = base.concat(toPush);\n\t\t\t\tArray.prototype.push.apply(base, toPush);\n\t\t\t} else {\n\t\t\t\tbase.push(toPush);\n\t\t\t}\n\t\t}\n\n\t\treturn base;\n\t}\n\n\t// Private helper to create a tooltip item model\n\t// @param element : the chart element (point, arc, bar) to create the tooltip item for\n\t// @return : new tooltip item\n\tfunction createTooltipItem(element) {\n\t\tvar xScale = element._xScale;\n\t\tvar yScale = element._yScale || element._scale; // handle radar || polarArea charts\n\t\tvar index = element._index,\n\t\t\tdatasetIndex = element._datasetIndex;\n\n\t\treturn {\n\t\t\txLabel: xScale ? xScale.getLabelForIndex(index, datasetIndex) : '',\n\t\t\tyLabel: yScale ? yScale.getLabelForIndex(index, datasetIndex) : '',\n\t\t\tindex: index,\n\t\t\tdatasetIndex: datasetIndex,\n\t\t\tx: element._model.x,\n\t\t\ty: element._model.y\n\t\t};\n\t}\n\n\t/**\n\t * Helper to get the reset model for the tooltip\n\t * @param tooltipOpts {Object} the tooltip options\n\t */\n\tfunction getBaseModel(tooltipOpts) {\n\t\tvar globalDefaults = Chart.defaults.global;\n\t\tvar getValueOrDefault = helpers.getValueOrDefault;\n\n\t\treturn {\n\t\t\t// Positioning\n\t\t\txPadding: tooltipOpts.xPadding,\n\t\t\tyPadding: tooltipOpts.yPadding,\n\t\t\txAlign: tooltipOpts.xAlign,\n\t\t\tyAlign: tooltipOpts.yAlign,\n\n\t\t\t// Body\n\t\t\tbodyFontColor: tooltipOpts.bodyFontColor,\n\t\t\t_bodyFontFamily: getValueOrDefault(tooltipOpts.bodyFontFamily, globalDefaults.defaultFontFamily),\n\t\t\t_bodyFontStyle: getValueOrDefault(tooltipOpts.bodyFontStyle, globalDefaults.defaultFontStyle),\n\t\t\t_bodyAlign: tooltipOpts.bodyAlign,\n\t\t\tbodyFontSize: getValueOrDefault(tooltipOpts.bodyFontSize, globalDefaults.defaultFontSize),\n\t\t\tbodySpacing: tooltipOpts.bodySpacing,\n\n\t\t\t// Title\n\t\t\ttitleFontColor: tooltipOpts.titleFontColor,\n\t\t\t_titleFontFamily: getValueOrDefault(tooltipOpts.titleFontFamily, globalDefaults.defaultFontFamily),\n\t\t\t_titleFontStyle: getValueOrDefault(tooltipOpts.titleFontStyle, globalDefaults.defaultFontStyle),\n\t\t\ttitleFontSize: getValueOrDefault(tooltipOpts.titleFontSize, globalDefaults.defaultFontSize),\n\t\t\t_titleAlign: tooltipOpts.titleAlign,\n\t\t\ttitleSpacing: tooltipOpts.titleSpacing,\n\t\t\ttitleMarginBottom: tooltipOpts.titleMarginBottom,\n\n\t\t\t// Footer\n\t\t\tfooterFontColor: tooltipOpts.footerFontColor,\n\t\t\t_footerFontFamily: getValueOrDefault(tooltipOpts.footerFontFamily, globalDefaults.defaultFontFamily),\n\t\t\t_footerFontStyle: getValueOrDefault(tooltipOpts.footerFontStyle, globalDefaults.defaultFontStyle),\n\t\t\tfooterFontSize: getValueOrDefault(tooltipOpts.footerFontSize, globalDefaults.defaultFontSize),\n\t\t\t_footerAlign: tooltipOpts.footerAlign,\n\t\t\tfooterSpacing: tooltipOpts.footerSpacing,\n\t\t\tfooterMarginTop: tooltipOpts.footerMarginTop,\n\n\t\t\t// Appearance\n\t\t\tcaretSize: tooltipOpts.caretSize,\n\t\t\tcornerRadius: tooltipOpts.cornerRadius,\n\t\t\tbackgroundColor: tooltipOpts.backgroundColor,\n\t\t\topacity: 0,\n\t\t\tlegendColorBackground: tooltipOpts.multiKeyBackground,\n\t\t\tdisplayColors: tooltipOpts.displayColors,\n\t\t\tborderColor: tooltipOpts.borderColor,\n\t\t\tborderWidth: tooltipOpts.borderWidth\n\t\t};\n\t}\n\n\t/**\n\t * Get the size of the tooltip\n\t */\n\tfunction getTooltipSize(tooltip, model) {\n\t\tvar ctx = tooltip._chart.ctx;\n\n\t\tvar height = model.yPadding * 2; // Tooltip Padding\n\t\tvar width = 0;\n\n\t\t// Count of all lines in the body\n\t\tvar body = model.body;\n\t\tvar combinedBodyLength = body.reduce(function(count, bodyItem) {\n\t\t\treturn count + bodyItem.before.length + bodyItem.lines.length + bodyItem.after.length;\n\t\t}, 0);\n\t\tcombinedBodyLength += model.beforeBody.length + model.afterBody.length;\n\n\t\tvar titleLineCount = model.title.length;\n\t\tvar footerLineCount = model.footer.length;\n\t\tvar titleFontSize = model.titleFontSize,\n\t\t\tbodyFontSize = model.bodyFontSize,\n\t\t\tfooterFontSize = model.footerFontSize;\n\n\t\theight += titleLineCount * titleFontSize; // Title Lines\n\t\theight += titleLineCount ? (titleLineCount - 1) * model.titleSpacing : 0; // Title Line Spacing\n\t\theight += titleLineCount ? model.titleMarginBottom : 0; // Title's bottom Margin\n\t\theight += combinedBodyLength * bodyFontSize; // Body Lines\n\t\theight += combinedBodyLength ? (combinedBodyLength - 1) * model.bodySpacing : 0; // Body Line Spacing\n\t\theight += footerLineCount ? model.footerMarginTop : 0; // Footer Margin\n\t\theight += footerLineCount * (footerFontSize); // Footer Lines\n\t\theight += footerLineCount ? (footerLineCount - 1) * model.footerSpacing : 0; // Footer Line Spacing\n\n\t\t// Title width\n\t\tvar widthPadding = 0;\n\t\tvar maxLineWidth = function(line) {\n\t\t\twidth = Math.max(width, ctx.measureText(line).width + widthPadding);\n\t\t};\n\n\t\tctx.font = helpers.fontString(titleFontSize, model._titleFontStyle, model._titleFontFamily);\n\t\thelpers.each(model.title, maxLineWidth);\n\n\t\t// Body width\n\t\tctx.font = helpers.fontString(bodyFontSize, model._bodyFontStyle, model._bodyFontFamily);\n\t\thelpers.each(model.beforeBody.concat(model.afterBody), maxLineWidth);\n\n\t\t// Body lines may include some extra width due to the color box\n\t\twidthPadding = model.displayColors ? (bodyFontSize + 2) : 0;\n\t\thelpers.each(body, function(bodyItem) {\n\t\t\thelpers.each(bodyItem.before, maxLineWidth);\n\t\t\thelpers.each(bodyItem.lines, maxLineWidth);\n\t\t\thelpers.each(bodyItem.after, maxLineWidth);\n\t\t});\n\n\t\t// Reset back to 0\n\t\twidthPadding = 0;\n\n\t\t// Footer width\n\t\tctx.font = helpers.fontString(footerFontSize, model._footerFontStyle, model._footerFontFamily);\n\t\thelpers.each(model.footer, maxLineWidth);\n\n\t\t// Add padding\n\t\twidth += 2 * model.xPadding;\n\n\t\treturn {\n\t\t\twidth: width,\n\t\t\theight: height\n\t\t};\n\t}\n\n\t/**\n\t * Helper to get the alignment of a tooltip given the size\n\t */\n\tfunction determineAlignment(tooltip, size) {\n\t\tvar model = tooltip._model;\n\t\tvar chart = tooltip._chart;\n\t\tvar chartArea = tooltip._chart.chartArea;\n\t\tvar xAlign = 'center';\n\t\tvar yAlign = 'center';\n\n\t\tif (model.y < size.height) {\n\t\t\tyAlign = 'top';\n\t\t} else if (model.y > (chart.height - size.height)) {\n\t\t\tyAlign = 'bottom';\n\t\t}\n\n\t\tvar lf, rf; // functions to determine left, right alignment\n\t\tvar olf, orf; // functions to determine if left/right alignment causes tooltip to go outside chart\n\t\tvar yf; // function to get the y alignment if the tooltip goes outside of the left or right edges\n\t\tvar midX = (chartArea.left + chartArea.right) / 2;\n\t\tvar midY = (chartArea.top + chartArea.bottom) / 2;\n\n\t\tif (yAlign === 'center') {\n\t\t\tlf = function(x) {\n\t\t\t\treturn x <= midX;\n\t\t\t};\n\t\t\trf = function(x) {\n\t\t\t\treturn x > midX;\n\t\t\t};\n\t\t} else {\n\t\t\tlf = function(x) {\n\t\t\t\treturn x <= (size.width / 2);\n\t\t\t};\n\t\t\trf = function(x) {\n\t\t\t\treturn x >= (chart.width - (size.width / 2));\n\t\t\t};\n\t\t}\n\n\t\tolf = function(x) {\n\t\t\treturn x + size.width > chart.width;\n\t\t};\n\t\torf = function(x) {\n\t\t\treturn x - size.width < 0;\n\t\t};\n\t\tyf = function(y) {\n\t\t\treturn y <= midY ? 'top' : 'bottom';\n\t\t};\n\n\t\tif (lf(model.x)) {\n\t\t\txAlign = 'left';\n\n\t\t\t// Is tooltip too wide and goes over the right side of the chart.?\n\t\t\tif (olf(model.x)) {\n\t\t\t\txAlign = 'center';\n\t\t\t\tyAlign = yf(model.y);\n\t\t\t}\n\t\t} else if (rf(model.x)) {\n\t\t\txAlign = 'right';\n\n\t\t\t// Is tooltip too wide and goes outside left edge of canvas?\n\t\t\tif (orf(model.x)) {\n\t\t\t\txAlign = 'center';\n\t\t\t\tyAlign = yf(model.y);\n\t\t\t}\n\t\t}\n\n\t\tvar opts = tooltip._options;\n\t\treturn {\n\t\t\txAlign: opts.xAlign ? opts.xAlign : xAlign,\n\t\t\tyAlign: opts.yAlign ? opts.yAlign : yAlign\n\t\t};\n\t}\n\n\t/**\n\t * @Helper to get the location a tooltip needs to be placed at given the initial position (via the vm) and the size and alignment\n\t */\n\tfunction getBackgroundPoint(vm, size, alignment) {\n\t\t// Background Position\n\t\tvar x = vm.x;\n\t\tvar y = vm.y;\n\n\t\tvar caretSize = vm.caretSize,\n\t\t\tcaretPadding = vm.caretPadding,\n\t\t\tcornerRadius = vm.cornerRadius,\n\t\t\txAlign = alignment.xAlign,\n\t\t\tyAlign = alignment.yAlign,\n\t\t\tpaddingAndSize = caretSize + caretPadding,\n\t\t\tradiusAndPadding = cornerRadius + caretPadding;\n\n\t\tif (xAlign === 'right') {\n\t\t\tx -= size.width;\n\t\t} else if (xAlign === 'center') {\n\t\t\tx -= (size.width / 2);\n\t\t}\n\n\t\tif (yAlign === 'top') {\n\t\t\ty += paddingAndSize;\n\t\t} else if (yAlign === 'bottom') {\n\t\t\ty -= size.height + paddingAndSize;\n\t\t} else {\n\t\t\ty -= (size.height / 2);\n\t\t}\n\n\t\tif (yAlign === 'center') {\n\t\t\tif (xAlign === 'left') {\n\t\t\t\tx += paddingAndSize;\n\t\t\t} else if (xAlign === 'right') {\n\t\t\t\tx -= paddingAndSize;\n\t\t\t}\n\t\t} else if (xAlign === 'left') {\n\t\t\tx -= radiusAndPadding;\n\t\t} else if (xAlign === 'right') {\n\t\t\tx += radiusAndPadding;\n\t\t}\n\n\t\treturn {\n\t\t\tx: x,\n\t\t\ty: y\n\t\t};\n\t}\n\n\tChart.Tooltip = Chart.Element.extend({\n\t\tinitialize: function() {\n\t\t\tthis._model = getBaseModel(this._options);\n\t\t},\n\n\t\t// Get the title\n\t\t// Args are: (tooltipItem, data)\n\t\tgetTitle: function() {\n\t\t\tvar me = this;\n\t\t\tvar opts = me._options;\n\t\t\tvar callbacks = opts.callbacks;\n\n\t\t\tvar beforeTitle = callbacks.beforeTitle.apply(me, arguments),\n\t\t\t\ttitle = callbacks.title.apply(me, arguments),\n\t\t\t\tafterTitle = callbacks.afterTitle.apply(me, arguments);\n\n\t\t\tvar lines = [];\n\t\t\tlines = pushOrConcat(lines, beforeTitle);\n\t\t\tlines = pushOrConcat(lines, title);\n\t\t\tlines = pushOrConcat(lines, afterTitle);\n\n\t\t\treturn lines;\n\t\t},\n\n\t\t// Args are: (tooltipItem, data)\n\t\tgetBeforeBody: function() {\n\t\t\tvar lines = this._options.callbacks.beforeBody.apply(this, arguments);\n\t\t\treturn helpers.isArray(lines) ? lines : lines !== undefined ? [lines] : [];\n\t\t},\n\n\t\t// Args are: (tooltipItem, data)\n\t\tgetBody: function(tooltipItems, data) {\n\t\t\tvar me = this;\n\t\t\tvar callbacks = me._options.callbacks;\n\t\t\tvar bodyItems = [];\n\n\t\t\thelpers.each(tooltipItems, function(tooltipItem) {\n\t\t\t\tvar bodyItem = {\n\t\t\t\t\tbefore: [],\n\t\t\t\t\tlines: [],\n\t\t\t\t\tafter: []\n\t\t\t\t};\n\t\t\t\tpushOrConcat(bodyItem.before, callbacks.beforeLabel.call(me, tooltipItem, data));\n\t\t\t\tpushOrConcat(bodyItem.lines, callbacks.label.call(me, tooltipItem, data));\n\t\t\t\tpushOrConcat(bodyItem.after, callbacks.afterLabel.call(me, tooltipItem, data));\n\n\t\t\t\tbodyItems.push(bodyItem);\n\t\t\t});\n\n\t\t\treturn bodyItems;\n\t\t},\n\n\t\t// Args are: (tooltipItem, data)\n\t\tgetAfterBody: function() {\n\t\t\tvar lines = this._options.callbacks.afterBody.apply(this, arguments);\n\t\t\treturn helpers.isArray(lines) ? lines : lines !== undefined ? [lines] : [];\n\t\t},\n\n\t\t// Get the footer and beforeFooter and afterFooter lines\n\t\t// Args are: (tooltipItem, data)\n\t\tgetFooter: function() {\n\t\t\tvar me = this;\n\t\t\tvar callbacks = me._options.callbacks;\n\n\t\t\tvar beforeFooter = callbacks.beforeFooter.apply(me, arguments);\n\t\t\tvar footer = callbacks.footer.apply(me, arguments);\n\t\t\tvar afterFooter = callbacks.afterFooter.apply(me, arguments);\n\n\t\t\tvar lines = [];\n\t\t\tlines = pushOrConcat(lines, beforeFooter);\n\t\t\tlines = pushOrConcat(lines, footer);\n\t\t\tlines = pushOrConcat(lines, afterFooter);\n\n\t\t\treturn lines;\n\t\t},\n\n\t\tupdate: function(changed) {\n\t\t\tvar me = this;\n\t\t\tvar opts = me._options;\n\n\t\t\t// Need to regenerate the model because its faster than using extend and it is necessary due to the optimization in Chart.Element.transition\n\t\t\t// that does _view = _model if ease === 1. This causes the 2nd tooltip update to set properties in both the view and model at the same time\n\t\t\t// which breaks any animations.\n\t\t\tvar existingModel = me._model;\n\t\t\tvar model = me._model = getBaseModel(opts);\n\t\t\tvar active = me._active;\n\n\t\t\tvar data = me._data;\n\n\t\t\t// In the case where active.length === 0 we need to keep these at existing values for good animations\n\t\t\tvar alignment = {\n\t\t\t\txAlign: existingModel.xAlign,\n\t\t\t\tyAlign: existingModel.yAlign\n\t\t\t};\n\t\t\tvar backgroundPoint = {\n\t\t\t\tx: existingModel.x,\n\t\t\t\ty: existingModel.y\n\t\t\t};\n\t\t\tvar tooltipSize = {\n\t\t\t\twidth: existingModel.width,\n\t\t\t\theight: existingModel.height\n\t\t\t};\n\t\t\tvar tooltipPosition = {\n\t\t\t\tx: existingModel.caretX,\n\t\t\t\ty: existingModel.caretY\n\t\t\t};\n\n\t\t\tvar i, len;\n\n\t\t\tif (active.length) {\n\t\t\t\tmodel.opacity = 1;\n\n\t\t\t\tvar labelColors = [];\n\t\t\t\ttooltipPosition = Chart.Tooltip.positioners[opts.position](active, me._eventPosition);\n\n\t\t\t\tvar tooltipItems = [];\n\t\t\t\tfor (i = 0, len = active.length; i < len; ++i) {\n\t\t\t\t\ttooltipItems.push(createTooltipItem(active[i]));\n\t\t\t\t}\n\n\t\t\t\t// If the user provided a filter function, use it to modify the tooltip items\n\t\t\t\tif (opts.filter) {\n\t\t\t\t\ttooltipItems = tooltipItems.filter(function(a) {\n\t\t\t\t\t\treturn opts.filter(a, data);\n\t\t\t\t\t});\n\t\t\t\t}\n\n\t\t\t\t// If the user provided a sorting function, use it to modify the tooltip items\n\t\t\t\tif (opts.itemSort) {\n\t\t\t\t\ttooltipItems = tooltipItems.sort(function(a, b) {\n\t\t\t\t\t\treturn opts.itemSort(a, b, data);\n\t\t\t\t\t});\n\t\t\t\t}\n\n\t\t\t\t// Determine colors for boxes\n\t\t\t\thelpers.each(tooltipItems, function(tooltipItem) {\n\t\t\t\t\tlabelColors.push(opts.callbacks.labelColor.call(me, tooltipItem, me._chart));\n\t\t\t\t});\n\n\t\t\t\t// Build the Text Lines\n\t\t\t\tmodel.title = me.getTitle(tooltipItems, data);\n\t\t\t\tmodel.beforeBody = me.getBeforeBody(tooltipItems, data);\n\t\t\t\tmodel.body = me.getBody(tooltipItems, data);\n\t\t\t\tmodel.afterBody = me.getAfterBody(tooltipItems, data);\n\t\t\t\tmodel.footer = me.getFooter(tooltipItems, data);\n\n\t\t\t\t// Initial positioning and colors\n\t\t\t\tmodel.x = Math.round(tooltipPosition.x);\n\t\t\t\tmodel.y = Math.round(tooltipPosition.y);\n\t\t\t\tmodel.caretPadding = opts.caretPadding;\n\t\t\t\tmodel.labelColors = labelColors;\n\n\t\t\t\t// data points\n\t\t\t\tmodel.dataPoints = tooltipItems;\n\n\t\t\t\t// We need to determine alignment of the tooltip\n\t\t\t\ttooltipSize = getTooltipSize(this, model);\n\t\t\t\talignment = determineAlignment(this, tooltipSize);\n\t\t\t\t// Final Size and Position\n\t\t\t\tbackgroundPoint = getBackgroundPoint(model, tooltipSize, alignment);\n\t\t\t} else {\n\t\t\t\tmodel.opacity = 0;\n\t\t\t}\n\n\t\t\tmodel.xAlign = alignment.xAlign;\n\t\t\tmodel.yAlign = alignment.yAlign;\n\t\t\tmodel.x = backgroundPoint.x;\n\t\t\tmodel.y = backgroundPoint.y;\n\t\t\tmodel.width = tooltipSize.width;\n\t\t\tmodel.height = tooltipSize.height;\n\n\t\t\t// Point where the caret on the tooltip points to\n\t\t\tmodel.caretX = tooltipPosition.x;\n\t\t\tmodel.caretY = tooltipPosition.y;\n\n\t\t\tme._model = model;\n\n\t\t\tif (changed && opts.custom) {\n\t\t\t\topts.custom.call(me, model);\n\t\t\t}\n\n\t\t\treturn me;\n\t\t},\n\t\tdrawCaret: function(tooltipPoint, size) {\n\t\t\tvar ctx = this._chart.ctx;\n\t\t\tvar vm = this._view;\n\t\t\tvar caretPosition = this.getCaretPosition(tooltipPoint, size, vm);\n\n\t\t\tctx.lineTo(caretPosition.x1, caretPosition.y1);\n\t\t\tctx.lineTo(caretPosition.x2, caretPosition.y2);\n\t\t\tctx.lineTo(caretPosition.x3, caretPosition.y3);\n\t\t},\n\t\tgetCaretPosition: function(tooltipPoint, size, vm) {\n\t\t\tvar x1, x2, x3;\n\t\t\tvar y1, y2, y3;\n\t\t\tvar caretSize = vm.caretSize;\n\t\t\tvar cornerRadius = vm.cornerRadius;\n\t\t\tvar xAlign = vm.xAlign,\n\t\t\t\tyAlign = vm.yAlign;\n\t\t\tvar ptX = tooltipPoint.x,\n\t\t\t\tptY = tooltipPoint.y;\n\t\t\tvar width = size.width,\n\t\t\t\theight = size.height;\n\n\t\t\tif (yAlign === 'center') {\n\t\t\t\ty2 = ptY + (height / 2);\n\n\t\t\t\tif (xAlign === 'left') {\n\t\t\t\t\tx1 = ptX;\n\t\t\t\t\tx2 = x1 - caretSize;\n\t\t\t\t\tx3 = x1;\n\n\t\t\t\t\ty1 = y2 + caretSize;\n\t\t\t\t\ty3 = y2 - caretSize;\n\t\t\t\t} else {\n\t\t\t\t\tx1 = ptX + width;\n\t\t\t\t\tx2 = x1 + caretSize;\n\t\t\t\t\tx3 = x1;\n\n\t\t\t\t\ty1 = y2 - caretSize;\n\t\t\t\t\ty3 = y2 + caretSize;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tif (xAlign === 'left') {\n\t\t\t\t\tx2 = ptX + cornerRadius + (caretSize);\n\t\t\t\t\tx1 = x2 - caretSize;\n\t\t\t\t\tx3 = x2 + caretSize;\n\t\t\t\t} else if (xAlign === 'right') {\n\t\t\t\t\tx2 = ptX + width - cornerRadius - caretSize;\n\t\t\t\t\tx1 = x2 - caretSize;\n\t\t\t\t\tx3 = x2 + caretSize;\n\t\t\t\t} else {\n\t\t\t\t\tx2 = ptX + (width / 2);\n\t\t\t\t\tx1 = x2 - caretSize;\n\t\t\t\t\tx3 = x2 + caretSize;\n\t\t\t\t}\n\t\t\t\tif (yAlign === 'top') {\n\t\t\t\t\ty1 = ptY;\n\t\t\t\t\ty2 = y1 - caretSize;\n\t\t\t\t\ty3 = y1;\n\t\t\t\t} else {\n\t\t\t\t\ty1 = ptY + height;\n\t\t\t\t\ty2 = y1 + caretSize;\n\t\t\t\t\ty3 = y1;\n\t\t\t\t\t// invert drawing order\n\t\t\t\t\tvar tmp = x3;\n\t\t\t\t\tx3 = x1;\n\t\t\t\t\tx1 = tmp;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn {x1: x1, x2: x2, x3: x3, y1: y1, y2: y2, y3: y3};\n\t\t},\n\t\tdrawTitle: function(pt, vm, ctx, opacity) {\n\t\t\tvar title = vm.title;\n\n\t\t\tif (title.length) {\n\t\t\t\tctx.textAlign = vm._titleAlign;\n\t\t\t\tctx.textBaseline = 'top';\n\n\t\t\t\tvar titleFontSize = vm.titleFontSize,\n\t\t\t\t\ttitleSpacing = vm.titleSpacing;\n\n\t\t\t\tctx.fillStyle = mergeOpacity(vm.titleFontColor, opacity);\n\t\t\t\tctx.font = helpers.fontString(titleFontSize, vm._titleFontStyle, vm._titleFontFamily);\n\n\t\t\t\tvar i, len;\n\t\t\t\tfor (i = 0, len = title.length; i < len; ++i) {\n\t\t\t\t\tctx.fillText(title[i], pt.x, pt.y);\n\t\t\t\t\tpt.y += titleFontSize + titleSpacing; // Line Height and spacing\n\n\t\t\t\t\tif (i + 1 === title.length) {\n\t\t\t\t\t\tpt.y += vm.titleMarginBottom - titleSpacing; // If Last, add margin, remove spacing\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\tdrawBody: function(pt, vm, ctx, opacity) {\n\t\t\tvar bodyFontSize = vm.bodyFontSize;\n\t\t\tvar bodySpacing = vm.bodySpacing;\n\t\t\tvar body = vm.body;\n\n\t\t\tctx.textAlign = vm._bodyAlign;\n\t\t\tctx.textBaseline = 'top';\n\n\t\t\tvar textColor = mergeOpacity(vm.bodyFontColor, opacity);\n\t\t\tctx.fillStyle = textColor;\n\t\t\tctx.font = helpers.fontString(bodyFontSize, vm._bodyFontStyle, vm._bodyFontFamily);\n\n\t\t\t// Before Body\n\t\t\tvar xLinePadding = 0;\n\t\t\tvar fillLineOfText = function(line) {\n\t\t\t\tctx.fillText(line, pt.x + xLinePadding, pt.y);\n\t\t\t\tpt.y += bodyFontSize + bodySpacing;\n\t\t\t};\n\n\t\t\t// Before body lines\n\t\t\thelpers.each(vm.beforeBody, fillLineOfText);\n\n\t\t\tvar drawColorBoxes = vm.displayColors;\n\t\t\txLinePadding = drawColorBoxes ? (bodyFontSize + 2) : 0;\n\n\t\t\t// Draw body lines now\n\t\t\thelpers.each(body, function(bodyItem, i) {\n\t\t\t\thelpers.each(bodyItem.before, fillLineOfText);\n\n\t\t\t\thelpers.each(bodyItem.lines, function(line) {\n\t\t\t\t\t// Draw Legend-like boxes if needed\n\t\t\t\t\tif (drawColorBoxes) {\n\t\t\t\t\t\t// Fill a white rect so that colours merge nicely if the opacity is < 1\n\t\t\t\t\t\tctx.fillStyle = mergeOpacity(vm.legendColorBackground, opacity);\n\t\t\t\t\t\tctx.fillRect(pt.x, pt.y, bodyFontSize, bodyFontSize);\n\n\t\t\t\t\t\t// Border\n\t\t\t\t\t\tctx.strokeStyle = mergeOpacity(vm.labelColors[i].borderColor, opacity);\n\t\t\t\t\t\tctx.strokeRect(pt.x, pt.y, bodyFontSize, bodyFontSize);\n\n\t\t\t\t\t\t// Inner square\n\t\t\t\t\t\tctx.fillStyle = mergeOpacity(vm.labelColors[i].backgroundColor, opacity);\n\t\t\t\t\t\tctx.fillRect(pt.x + 1, pt.y + 1, bodyFontSize - 2, bodyFontSize - 2);\n\n\t\t\t\t\t\tctx.fillStyle = textColor;\n\t\t\t\t\t}\n\n\t\t\t\t\tfillLineOfText(line);\n\t\t\t\t});\n\n\t\t\t\thelpers.each(bodyItem.after, fillLineOfText);\n\t\t\t});\n\n\t\t\t// Reset back to 0 for after body\n\t\t\txLinePadding = 0;\n\n\t\t\t// After body lines\n\t\t\thelpers.each(vm.afterBody, fillLineOfText);\n\t\t\tpt.y -= bodySpacing; // Remove last body spacing\n\t\t},\n\t\tdrawFooter: function(pt, vm, ctx, opacity) {\n\t\t\tvar footer = vm.footer;\n\n\t\t\tif (footer.length) {\n\t\t\t\tpt.y += vm.footerMarginTop;\n\n\t\t\t\tctx.textAlign = vm._footerAlign;\n\t\t\t\tctx.textBaseline = 'top';\n\n\t\t\t\tctx.fillStyle = mergeOpacity(vm.footerFontColor, opacity);\n\t\t\t\tctx.font = helpers.fontString(vm.footerFontSize, vm._footerFontStyle, vm._footerFontFamily);\n\n\t\t\t\thelpers.each(footer, function(line) {\n\t\t\t\t\tctx.fillText(line, pt.x, pt.y);\n\t\t\t\t\tpt.y += vm.footerFontSize + vm.footerSpacing;\n\t\t\t\t});\n\t\t\t}\n\t\t},\n\t\tdrawBackground: function(pt, vm, ctx, tooltipSize, opacity) {\n\t\t\tctx.fillStyle = mergeOpacity(vm.backgroundColor, opacity);\n\t\t\tctx.strokeStyle = mergeOpacity(vm.borderColor, opacity);\n\t\t\tctx.lineWidth = vm.borderWidth;\n\t\t\tvar xAlign = vm.xAlign;\n\t\t\tvar yAlign = vm.yAlign;\n\t\t\tvar x = pt.x;\n\t\t\tvar y = pt.y;\n\t\t\tvar width = tooltipSize.width;\n\t\t\tvar height = tooltipSize.height;\n\t\t\tvar radius = vm.cornerRadius;\n\n\t\t\tctx.beginPath();\n\t\t\tctx.moveTo(x + radius, y);\n\t\t\tif (yAlign === 'top') {\n\t\t\t\tthis.drawCaret(pt, tooltipSize);\n\t\t\t}\n\t\t\tctx.lineTo(x + width - radius, y);\n\t\t\tctx.quadraticCurveTo(x + width, y, x + width, y + radius);\n\t\t\tif (yAlign === 'center' && xAlign === 'right') {\n\t\t\t\tthis.drawCaret(pt, tooltipSize);\n\t\t\t}\n\t\t\tctx.lineTo(x + width, y + height - radius);\n\t\t\tctx.quadraticCurveTo(x + width, y + height, x + width - radius, y + height);\n\t\t\tif (yAlign === 'bottom') {\n\t\t\t\tthis.drawCaret(pt, tooltipSize);\n\t\t\t}\n\t\t\tctx.lineTo(x + radius, y + height);\n\t\t\tctx.quadraticCurveTo(x, y + height, x, y + height - radius);\n\t\t\tif (yAlign === 'center' && xAlign === 'left') {\n\t\t\t\tthis.drawCaret(pt, tooltipSize);\n\t\t\t}\n\t\t\tctx.lineTo(x, y + radius);\n\t\t\tctx.quadraticCurveTo(x, y, x + radius, y);\n\t\t\tctx.closePath();\n\n\t\t\tctx.fill();\n\n\t\t\tif (vm.borderWidth > 0) {\n\t\t\t\tctx.stroke();\n\t\t\t}\n\t\t},\n\t\tdraw: function() {\n\t\t\tvar ctx = this._chart.ctx;\n\t\t\tvar vm = this._view;\n\n\t\t\tif (vm.opacity === 0) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tvar tooltipSize = {\n\t\t\t\twidth: vm.width,\n\t\t\t\theight: vm.height\n\t\t\t};\n\t\t\tvar pt = {\n\t\t\t\tx: vm.x,\n\t\t\t\ty: vm.y\n\t\t\t};\n\n\t\t\t// IE11/Edge does not like very small opacities, so snap to 0\n\t\t\tvar opacity = Math.abs(vm.opacity < 1e-3) ? 0 : vm.opacity;\n\n\t\t\t// Truthy/falsey value for empty tooltip\n\t\t\tvar hasTooltipContent = vm.title.length || vm.beforeBody.length || vm.body.length || vm.afterBody.length || vm.footer.length;\n\n\t\t\tif (this._options.enabled && hasTooltipContent) {\n\t\t\t\t// Draw Background\n\t\t\t\tthis.drawBackground(pt, vm, ctx, tooltipSize, opacity);\n\n\t\t\t\t// Draw Title, Body, and Footer\n\t\t\t\tpt.x += vm.xPadding;\n\t\t\t\tpt.y += vm.yPadding;\n\n\t\t\t\t// Titles\n\t\t\t\tthis.drawTitle(pt, vm, ctx, opacity);\n\n\t\t\t\t// Body\n\t\t\t\tthis.drawBody(pt, vm, ctx, opacity);\n\n\t\t\t\t// Footer\n\t\t\t\tthis.drawFooter(pt, vm, ctx, opacity);\n\t\t\t}\n\t\t},\n\n\t\t/**\n\t\t * Handle an event\n\t\t * @private\n\t\t * @param {IEvent} event - The event to handle\n\t\t * @returns {Boolean} true if the tooltip changed\n\t\t */\n\t\thandleEvent: function(e) {\n\t\t\tvar me = this;\n\t\t\tvar options = me._options;\n\t\t\tvar changed = false;\n\n\t\t\tme._lastActive = me._lastActive || [];\n\n\t\t\t// Find Active Elements for tooltips\n\t\t\tif (e.type === 'mouseout') {\n\t\t\t\tme._active = [];\n\t\t\t} else {\n\t\t\t\tme._active = me._chart.getElementsAtEventForMode(e, options.mode, options);\n\t\t\t}\n\n\t\t\t// Remember Last Actives\n\t\t\tchanged = !helpers.arrayEquals(me._active, me._lastActive);\n\n\t\t\t// If tooltip didn't change, do not handle the target event\n\t\t\tif (!changed) {\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\tme._lastActive = me._active;\n\n\t\t\tif (options.enabled || options.custom) {\n\t\t\t\tme._eventPosition = {\n\t\t\t\t\tx: e.x,\n\t\t\t\t\ty: e.y\n\t\t\t\t};\n\n\t\t\t\tvar model = me._model;\n\t\t\t\tme.update(true);\n\t\t\t\tme.pivot();\n\n\t\t\t\t// See if our tooltip position changed\n\t\t\t\tchanged |= (model.x !== me._model.x) || (model.y !== me._model.y);\n\t\t\t}\n\n\t\t\treturn changed;\n\t\t}\n\t});\n\n\t/**\n\t * @namespace Chart.Tooltip.positioners\n\t */\n\tChart.Tooltip.positioners = {\n\t\t/**\n\t\t * Average mode places the tooltip at the average position of the elements shown\n\t\t * @function Chart.Tooltip.positioners.average\n\t\t * @param elements {ChartElement[]} the elements being displayed in the tooltip\n\t\t * @returns {Point} tooltip position\n\t\t */\n\t\taverage: function(elements) {\n\t\t\tif (!elements.length) {\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\tvar i, len;\n\t\t\tvar x = 0;\n\t\t\tvar y = 0;\n\t\t\tvar count = 0;\n\n\t\t\tfor (i = 0, len = elements.length; i < len; ++i) {\n\t\t\t\tvar el = elements[i];\n\t\t\t\tif (el && el.hasValue()) {\n\t\t\t\t\tvar pos = el.tooltipPosition();\n\t\t\t\t\tx += pos.x;\n\t\t\t\t\ty += pos.y;\n\t\t\t\t\t++count;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn {\n\t\t\t\tx: Math.round(x / count),\n\t\t\t\ty: Math.round(y / count)\n\t\t\t};\n\t\t},\n\n\t\t/**\n\t\t * Gets the tooltip position nearest of the item nearest to the event position\n\t\t * @function Chart.Tooltip.positioners.nearest\n\t\t * @param elements {Chart.Element[]} the tooltip elements\n\t\t * @param eventPosition {Point} the position of the event in canvas coordinates\n\t\t * @returns {Point} the tooltip position\n\t\t */\n\t\tnearest: function(elements, eventPosition) {\n\t\t\tvar x = eventPosition.x;\n\t\t\tvar y = eventPosition.y;\n\n\t\t\tvar nearestElement;\n\t\t\tvar minDistance = Number.POSITIVE_INFINITY;\n\t\t\tvar i, len;\n\t\t\tfor (i = 0, len = elements.length; i < len; ++i) {\n\t\t\t\tvar el = elements[i];\n\t\t\t\tif (el && el.hasValue()) {\n\t\t\t\t\tvar center = el.getCenterPoint();\n\t\t\t\t\tvar d = helpers.distanceBetweenPoints(eventPosition, center);\n\n\t\t\t\t\tif (d < minDistance) {\n\t\t\t\t\t\tminDistance = d;\n\t\t\t\t\t\tnearestElement = el;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (nearestElement) {\n\t\t\t\tvar tp = nearestElement.tooltipPosition();\n\t\t\t\tx = tp.x;\n\t\t\t\ty = tp.y;\n\t\t\t}\n\n\t\t\treturn {\n\t\t\t\tx: x,\n\t\t\t\ty: y\n\t\t\t};\n\t\t}\n\t};\n};\n"
  },
  {
    "path": "app_backend/static/plugin/Chart.js-2.6.0/src/elements/element.arc.js",
    "content": "'use strict';\n\nmodule.exports = function(Chart) {\n\n\tvar helpers = Chart.helpers,\n\t\tglobalOpts = Chart.defaults.global;\n\n\tglobalOpts.elements.arc = {\n\t\tbackgroundColor: globalOpts.defaultColor,\n\t\tborderColor: '#fff',\n\t\tborderWidth: 2\n\t};\n\n\tChart.elements.Arc = Chart.Element.extend({\n\t\tinLabelRange: function(mouseX) {\n\t\t\tvar vm = this._view;\n\n\t\t\tif (vm) {\n\t\t\t\treturn (Math.pow(mouseX - vm.x, 2) < Math.pow(vm.radius + vm.hoverRadius, 2));\n\t\t\t}\n\t\t\treturn false;\n\t\t},\n\t\tinRange: function(chartX, chartY) {\n\t\t\tvar vm = this._view;\n\n\t\t\tif (vm) {\n\t\t\t\tvar pointRelativePosition = helpers.getAngleFromPoint(vm, {\n\t\t\t\t\t\tx: chartX,\n\t\t\t\t\t\ty: chartY\n\t\t\t\t\t}),\n\t\t\t\t\tangle = pointRelativePosition.angle,\n\t\t\t\t\tdistance = pointRelativePosition.distance;\n\n\t\t\t\t// Sanitise angle range\n\t\t\t\tvar startAngle = vm.startAngle;\n\t\t\t\tvar endAngle = vm.endAngle;\n\t\t\t\twhile (endAngle < startAngle) {\n\t\t\t\t\tendAngle += 2.0 * Math.PI;\n\t\t\t\t}\n\t\t\t\twhile (angle > endAngle) {\n\t\t\t\t\tangle -= 2.0 * Math.PI;\n\t\t\t\t}\n\t\t\t\twhile (angle < startAngle) {\n\t\t\t\t\tangle += 2.0 * Math.PI;\n\t\t\t\t}\n\n\t\t\t\t// Check if within the range of the open/close angle\n\t\t\t\tvar betweenAngles = (angle >= startAngle && angle <= endAngle),\n\t\t\t\t\twithinRadius = (distance >= vm.innerRadius && distance <= vm.outerRadius);\n\n\t\t\t\treturn (betweenAngles && withinRadius);\n\t\t\t}\n\t\t\treturn false;\n\t\t},\n\t\tgetCenterPoint: function() {\n\t\t\tvar vm = this._view;\n\t\t\tvar halfAngle = (vm.startAngle + vm.endAngle) / 2;\n\t\t\tvar halfRadius = (vm.innerRadius + vm.outerRadius) / 2;\n\t\t\treturn {\n\t\t\t\tx: vm.x + Math.cos(halfAngle) * halfRadius,\n\t\t\t\ty: vm.y + Math.sin(halfAngle) * halfRadius\n\t\t\t};\n\t\t},\n\t\tgetArea: function() {\n\t\t\tvar vm = this._view;\n\t\t\treturn Math.PI * ((vm.endAngle - vm.startAngle) / (2 * Math.PI)) * (Math.pow(vm.outerRadius, 2) - Math.pow(vm.innerRadius, 2));\n\t\t},\n\t\ttooltipPosition: function() {\n\t\t\tvar vm = this._view;\n\n\t\t\tvar centreAngle = vm.startAngle + ((vm.endAngle - vm.startAngle) / 2),\n\t\t\t\trangeFromCentre = (vm.outerRadius - vm.innerRadius) / 2 + vm.innerRadius;\n\t\t\treturn {\n\t\t\t\tx: vm.x + (Math.cos(centreAngle) * rangeFromCentre),\n\t\t\t\ty: vm.y + (Math.sin(centreAngle) * rangeFromCentre)\n\t\t\t};\n\t\t},\n\t\tdraw: function() {\n\n\t\t\tvar ctx = this._chart.ctx,\n\t\t\t\tvm = this._view,\n\t\t\t\tsA = vm.startAngle,\n\t\t\t\teA = vm.endAngle;\n\n\t\t\tctx.beginPath();\n\n\t\t\tctx.arc(vm.x, vm.y, vm.outerRadius, sA, eA);\n\t\t\tctx.arc(vm.x, vm.y, vm.innerRadius, eA, sA, true);\n\n\t\t\tctx.closePath();\n\t\t\tctx.strokeStyle = vm.borderColor;\n\t\t\tctx.lineWidth = vm.borderWidth;\n\n\t\t\tctx.fillStyle = vm.backgroundColor;\n\n\t\t\tctx.fill();\n\t\t\tctx.lineJoin = 'bevel';\n\n\t\t\tif (vm.borderWidth) {\n\t\t\t\tctx.stroke();\n\t\t\t}\n\t\t}\n\t});\n};\n"
  },
  {
    "path": "app_backend/static/plugin/Chart.js-2.6.0/src/elements/element.line.js",
    "content": "'use strict';\n\nmodule.exports = function(Chart) {\n\n\tvar helpers = Chart.helpers;\n\tvar globalDefaults = Chart.defaults.global;\n\n\tChart.defaults.global.elements.line = {\n\t\ttension: 0.4,\n\t\tbackgroundColor: globalDefaults.defaultColor,\n\t\tborderWidth: 3,\n\t\tborderColor: globalDefaults.defaultColor,\n\t\tborderCapStyle: 'butt',\n\t\tborderDash: [],\n\t\tborderDashOffset: 0.0,\n\t\tborderJoinStyle: 'miter',\n\t\tcapBezierPoints: true,\n\t\tfill: true, // do we fill in the area between the line and its base axis\n\t};\n\n\tChart.elements.Line = Chart.Element.extend({\n\t\tdraw: function() {\n\t\t\tvar me = this;\n\t\t\tvar vm = me._view;\n\t\t\tvar ctx = me._chart.ctx;\n\t\t\tvar spanGaps = vm.spanGaps;\n\t\t\tvar points = me._children.slice(); // clone array\n\t\t\tvar globalOptionLineElements = globalDefaults.elements.line;\n\t\t\tvar lastDrawnIndex = -1;\n\t\t\tvar index, current, previous, currentVM;\n\n\t\t\t// If we are looping, adding the first point again\n\t\t\tif (me._loop && points.length) {\n\t\t\t\tpoints.push(points[0]);\n\t\t\t}\n\n\t\t\tctx.save();\n\n\t\t\t// Stroke Line Options\n\t\t\tctx.lineCap = vm.borderCapStyle || globalOptionLineElements.borderCapStyle;\n\n\t\t\t// IE 9 and 10 do not support line dash\n\t\t\tif (ctx.setLineDash) {\n\t\t\t\tctx.setLineDash(vm.borderDash || globalOptionLineElements.borderDash);\n\t\t\t}\n\n\t\t\tctx.lineDashOffset = vm.borderDashOffset || globalOptionLineElements.borderDashOffset;\n\t\t\tctx.lineJoin = vm.borderJoinStyle || globalOptionLineElements.borderJoinStyle;\n\t\t\tctx.lineWidth = vm.borderWidth || globalOptionLineElements.borderWidth;\n\t\t\tctx.strokeStyle = vm.borderColor || globalDefaults.defaultColor;\n\n\t\t\t// Stroke Line\n\t\t\tctx.beginPath();\n\t\t\tlastDrawnIndex = -1;\n\n\t\t\tfor (index = 0; index < points.length; ++index) {\n\t\t\t\tcurrent = points[index];\n\t\t\t\tprevious = helpers.previousItem(points, index);\n\t\t\t\tcurrentVM = current._view;\n\n\t\t\t\t// First point moves to it's starting position no matter what\n\t\t\t\tif (index === 0) {\n\t\t\t\t\tif (!currentVM.skip) {\n\t\t\t\t\t\tctx.moveTo(currentVM.x, currentVM.y);\n\t\t\t\t\t\tlastDrawnIndex = index;\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tprevious = lastDrawnIndex === -1 ? previous : points[lastDrawnIndex];\n\n\t\t\t\t\tif (!currentVM.skip) {\n\t\t\t\t\t\tif ((lastDrawnIndex !== (index - 1) && !spanGaps) || lastDrawnIndex === -1) {\n\t\t\t\t\t\t\t// There was a gap and this is the first point after the gap\n\t\t\t\t\t\t\tctx.moveTo(currentVM.x, currentVM.y);\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t// Line to next point\n\t\t\t\t\t\t\thelpers.canvas.lineTo(ctx, previous._view, current._view);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tlastDrawnIndex = index;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tctx.stroke();\n\t\t\tctx.restore();\n\t\t}\n\t});\n};\n"
  },
  {
    "path": "app_backend/static/plugin/Chart.js-2.6.0/src/elements/element.point.js",
    "content": "'use strict';\n\nmodule.exports = function(Chart) {\n\n\tvar helpers = Chart.helpers,\n\t\tglobalOpts = Chart.defaults.global,\n\t\tdefaultColor = globalOpts.defaultColor;\n\n\tglobalOpts.elements.point = {\n\t\tradius: 3,\n\t\tpointStyle: 'circle',\n\t\tbackgroundColor: defaultColor,\n\t\tborderWidth: 1,\n\t\tborderColor: defaultColor,\n\t\t// Hover\n\t\thitRadius: 1,\n\t\thoverRadius: 4,\n\t\thoverBorderWidth: 1\n\t};\n\n\tfunction xRange(mouseX) {\n\t\tvar vm = this._view;\n\t\treturn vm ? (Math.pow(mouseX - vm.x, 2) < Math.pow(vm.radius + vm.hitRadius, 2)) : false;\n\t}\n\n\tfunction yRange(mouseY) {\n\t\tvar vm = this._view;\n\t\treturn vm ? (Math.pow(mouseY - vm.y, 2) < Math.pow(vm.radius + vm.hitRadius, 2)) : false;\n\t}\n\n\tChart.elements.Point = Chart.Element.extend({\n\t\tinRange: function(mouseX, mouseY) {\n\t\t\tvar vm = this._view;\n\t\t\treturn vm ? ((Math.pow(mouseX - vm.x, 2) + Math.pow(mouseY - vm.y, 2)) < Math.pow(vm.hitRadius + vm.radius, 2)) : false;\n\t\t},\n\n\t\tinLabelRange: xRange,\n\t\tinXRange: xRange,\n\t\tinYRange: yRange,\n\n\t\tgetCenterPoint: function() {\n\t\t\tvar vm = this._view;\n\t\t\treturn {\n\t\t\t\tx: vm.x,\n\t\t\t\ty: vm.y\n\t\t\t};\n\t\t},\n\t\tgetArea: function() {\n\t\t\treturn Math.PI * Math.pow(this._view.radius, 2);\n\t\t},\n\t\ttooltipPosition: function() {\n\t\t\tvar vm = this._view;\n\t\t\treturn {\n\t\t\t\tx: vm.x,\n\t\t\t\ty: vm.y,\n\t\t\t\tpadding: vm.radius + vm.borderWidth\n\t\t\t};\n\t\t},\n\t\tdraw: function(chartArea) {\n\t\t\tvar vm = this._view;\n\t\t\tvar model = this._model;\n\t\t\tvar ctx = this._chart.ctx;\n\t\t\tvar pointStyle = vm.pointStyle;\n\t\t\tvar radius = vm.radius;\n\t\t\tvar x = vm.x;\n\t\t\tvar y = vm.y;\n\t\t\tvar color = Chart.helpers.color;\n\t\t\tvar errMargin = 1.01; // 1.01 is margin for Accumulated error. (Especially Edge, IE.)\n\t\t\tvar ratio = 0;\n\n\t\t\tif (vm.skip) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tctx.strokeStyle = vm.borderColor || defaultColor;\n\t\t\tctx.lineWidth = helpers.getValueOrDefault(vm.borderWidth, globalOpts.elements.point.borderWidth);\n\t\t\tctx.fillStyle = vm.backgroundColor || defaultColor;\n\n\t\t\t// Cliping for Points.\n\t\t\t// going out from inner charArea?\n\t\t\tif ((chartArea !== undefined) && ((model.x < chartArea.left) || (chartArea.right*errMargin < model.x) || (model.y < chartArea.top) || (chartArea.bottom*errMargin < model.y))) {\n\t\t\t\t// Point fade out\n\t\t\t\tif (model.x < chartArea.left) {\n\t\t\t\t\tratio = (x - model.x) / (chartArea.left - model.x);\n\t\t\t\t} else if (chartArea.right*errMargin < model.x) {\n\t\t\t\t\tratio = (model.x - x) / (model.x - chartArea.right);\n\t\t\t\t} else if (model.y < chartArea.top) {\n\t\t\t\t\tratio = (y - model.y) / (chartArea.top - model.y);\n\t\t\t\t} else if (chartArea.bottom*errMargin < model.y) {\n\t\t\t\t\tratio = (model.y - y) / (model.y - chartArea.bottom);\n\t\t\t\t}\n\t\t\t\tratio = Math.round(ratio*100) / 100;\n\t\t\t\tctx.strokeStyle = color(ctx.strokeStyle).alpha(ratio).rgbString();\n\t\t\t\tctx.fillStyle = color(ctx.fillStyle).alpha(ratio).rgbString();\n\t\t\t}\n\n\t\t\tChart.canvasHelpers.drawPoint(ctx, pointStyle, radius, x, y);\n\t\t}\n\t});\n};\n"
  },
  {
    "path": "app_backend/static/plugin/Chart.js-2.6.0/src/elements/element.rectangle.js",
    "content": "'use strict';\n\nmodule.exports = function(Chart) {\n\n\tvar globalOpts = Chart.defaults.global;\n\n\tglobalOpts.elements.rectangle = {\n\t\tbackgroundColor: globalOpts.defaultColor,\n\t\tborderWidth: 0,\n\t\tborderColor: globalOpts.defaultColor,\n\t\tborderSkipped: 'bottom'\n\t};\n\n\tfunction isVertical(bar) {\n\t\treturn bar._view.width !== undefined;\n\t}\n\n\t/**\n\t * Helper function to get the bounds of the bar regardless of the orientation\n\t * @private\n\t * @param bar {Chart.Element.Rectangle} the bar\n\t * @return {Bounds} bounds of the bar\n\t */\n\tfunction getBarBounds(bar) {\n\t\tvar vm = bar._view;\n\t\tvar x1, x2, y1, y2;\n\n\t\tif (isVertical(bar)) {\n\t\t\t// vertical\n\t\t\tvar halfWidth = vm.width / 2;\n\t\t\tx1 = vm.x - halfWidth;\n\t\t\tx2 = vm.x + halfWidth;\n\t\t\ty1 = Math.min(vm.y, vm.base);\n\t\t\ty2 = Math.max(vm.y, vm.base);\n\t\t} else {\n\t\t\t// horizontal bar\n\t\t\tvar halfHeight = vm.height / 2;\n\t\t\tx1 = Math.min(vm.x, vm.base);\n\t\t\tx2 = Math.max(vm.x, vm.base);\n\t\t\ty1 = vm.y - halfHeight;\n\t\t\ty2 = vm.y + halfHeight;\n\t\t}\n\n\t\treturn {\n\t\t\tleft: x1,\n\t\t\ttop: y1,\n\t\t\tright: x2,\n\t\t\tbottom: y2\n\t\t};\n\t}\n\n\tChart.elements.Rectangle = Chart.Element.extend({\n\t\tdraw: function() {\n\t\t\tvar ctx = this._chart.ctx;\n\t\t\tvar vm = this._view;\n\t\t\tvar left, right, top, bottom, signX, signY, borderSkipped;\n\t\t\tvar borderWidth = vm.borderWidth;\n\n\t\t\tif (!vm.horizontal) {\n\t\t\t\t// bar\n\t\t\t\tleft = vm.x - vm.width / 2;\n\t\t\t\tright = vm.x + vm.width / 2;\n\t\t\t\ttop = vm.y;\n\t\t\t\tbottom = vm.base;\n\t\t\t\tsignX = 1;\n\t\t\t\tsignY = bottom > top? 1: -1;\n\t\t\t\tborderSkipped = vm.borderSkipped || 'bottom';\n\t\t\t} else {\n\t\t\t\t// horizontal bar\n\t\t\t\tleft = vm.base;\n\t\t\t\tright = vm.x;\n\t\t\t\ttop = vm.y - vm.height / 2;\n\t\t\t\tbottom = vm.y + vm.height / 2;\n\t\t\t\tsignX = right > left? 1: -1;\n\t\t\t\tsignY = 1;\n\t\t\t\tborderSkipped = vm.borderSkipped || 'left';\n\t\t\t}\n\n\t\t\t// Canvas doesn't allow us to stroke inside the width so we can\n\t\t\t// adjust the sizes to fit if we're setting a stroke on the line\n\t\t\tif (borderWidth) {\n\t\t\t\t// borderWidth shold be less than bar width and bar height.\n\t\t\t\tvar barSize = Math.min(Math.abs(left - right), Math.abs(top - bottom));\n\t\t\t\tborderWidth = borderWidth > barSize? barSize: borderWidth;\n\t\t\t\tvar halfStroke = borderWidth / 2;\n\t\t\t\t// Adjust borderWidth when bar top position is near vm.base(zero).\n\t\t\t\tvar borderLeft = left + (borderSkipped !== 'left'? halfStroke * signX: 0);\n\t\t\t\tvar borderRight = right + (borderSkipped !== 'right'? -halfStroke * signX: 0);\n\t\t\t\tvar borderTop = top + (borderSkipped !== 'top'? halfStroke * signY: 0);\n\t\t\t\tvar borderBottom = bottom + (borderSkipped !== 'bottom'? -halfStroke * signY: 0);\n\t\t\t\t// not become a vertical line?\n\t\t\t\tif (borderLeft !== borderRight) {\n\t\t\t\t\ttop = borderTop;\n\t\t\t\t\tbottom = borderBottom;\n\t\t\t\t}\n\t\t\t\t// not become a horizontal line?\n\t\t\t\tif (borderTop !== borderBottom) {\n\t\t\t\t\tleft = borderLeft;\n\t\t\t\t\tright = borderRight;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tctx.beginPath();\n\t\t\tctx.fillStyle = vm.backgroundColor;\n\t\t\tctx.strokeStyle = vm.borderColor;\n\t\t\tctx.lineWidth = borderWidth;\n\n\t\t\t// Corner points, from bottom-left to bottom-right clockwise\n\t\t\t// | 1 2 |\n\t\t\t// | 0 3 |\n\t\t\tvar corners = [\n\t\t\t\t[left, bottom],\n\t\t\t\t[left, top],\n\t\t\t\t[right, top],\n\t\t\t\t[right, bottom]\n\t\t\t];\n\n\t\t\t// Find first (starting) corner with fallback to 'bottom'\n\t\t\tvar borders = ['bottom', 'left', 'top', 'right'];\n\t\t\tvar startCorner = borders.indexOf(borderSkipped, 0);\n\t\t\tif (startCorner === -1) {\n\t\t\t\tstartCorner = 0;\n\t\t\t}\n\n\t\t\tfunction cornerAt(index) {\n\t\t\t\treturn corners[(startCorner + index) % 4];\n\t\t\t}\n\n\t\t\t// Draw rectangle from 'startCorner'\n\t\t\tvar corner = cornerAt(0);\n\t\t\tctx.moveTo(corner[0], corner[1]);\n\n\t\t\tfor (var i = 1; i < 4; i++) {\n\t\t\t\tcorner = cornerAt(i);\n\t\t\t\tctx.lineTo(corner[0], corner[1]);\n\t\t\t}\n\n\t\t\tctx.fill();\n\t\t\tif (borderWidth) {\n\t\t\t\tctx.stroke();\n\t\t\t}\n\t\t},\n\t\theight: function() {\n\t\t\tvar vm = this._view;\n\t\t\treturn vm.base - vm.y;\n\t\t},\n\t\tinRange: function(mouseX, mouseY) {\n\t\t\tvar inRange = false;\n\n\t\t\tif (this._view) {\n\t\t\t\tvar bounds = getBarBounds(this);\n\t\t\t\tinRange = mouseX >= bounds.left && mouseX <= bounds.right && mouseY >= bounds.top && mouseY <= bounds.bottom;\n\t\t\t}\n\n\t\t\treturn inRange;\n\t\t},\n\t\tinLabelRange: function(mouseX, mouseY) {\n\t\t\tvar me = this;\n\t\t\tif (!me._view) {\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\tvar inRange = false;\n\t\t\tvar bounds = getBarBounds(me);\n\n\t\t\tif (isVertical(me)) {\n\t\t\t\tinRange = mouseX >= bounds.left && mouseX <= bounds.right;\n\t\t\t} else {\n\t\t\t\tinRange = mouseY >= bounds.top && mouseY <= bounds.bottom;\n\t\t\t}\n\n\t\t\treturn inRange;\n\t\t},\n\t\tinXRange: function(mouseX) {\n\t\t\tvar bounds = getBarBounds(this);\n\t\t\treturn mouseX >= bounds.left && mouseX <= bounds.right;\n\t\t},\n\t\tinYRange: function(mouseY) {\n\t\t\tvar bounds = getBarBounds(this);\n\t\t\treturn mouseY >= bounds.top && mouseY <= bounds.bottom;\n\t\t},\n\t\tgetCenterPoint: function() {\n\t\t\tvar vm = this._view;\n\t\t\tvar x, y;\n\t\t\tif (isVertical(this)) {\n\t\t\t\tx = vm.x;\n\t\t\t\ty = (vm.y + vm.base) / 2;\n\t\t\t} else {\n\t\t\t\tx = (vm.x + vm.base) / 2;\n\t\t\t\ty = vm.y;\n\t\t\t}\n\n\t\t\treturn {x: x, y: y};\n\t\t},\n\t\tgetArea: function() {\n\t\t\tvar vm = this._view;\n\t\t\treturn vm.width * Math.abs(vm.y - vm.base);\n\t\t},\n\t\ttooltipPosition: function() {\n\t\t\tvar vm = this._view;\n\t\t\treturn {\n\t\t\t\tx: vm.x,\n\t\t\t\ty: vm.y\n\t\t\t};\n\t\t}\n\t});\n\n};\n"
  },
  {
    "path": "app_backend/static/plugin/Chart.js-2.6.0/src/platforms/platform.dom.js",
    "content": "'use strict';\n\n// Chart.Platform implementation for targeting a web browser\nmodule.exports = function(Chart) {\n\tvar helpers = Chart.helpers;\n\n\t// DOM event types -> Chart.js event types.\n\t// Note: only events with different types are mapped.\n\t// https://developer.mozilla.org/en-US/docs/Web/Events\n\tvar eventTypeMap = {\n\t\t// Touch events\n\t\ttouchstart: 'mousedown',\n\t\ttouchmove: 'mousemove',\n\t\ttouchend: 'mouseup',\n\n\t\t// Pointer events\n\t\tpointerenter: 'mouseenter',\n\t\tpointerdown: 'mousedown',\n\t\tpointermove: 'mousemove',\n\t\tpointerup: 'mouseup',\n\t\tpointerleave: 'mouseout',\n\t\tpointerout: 'mouseout'\n\t};\n\n\t/**\n\t * The \"used\" size is the final value of a dimension property after all calculations have\n\t * been performed. This method uses the computed style of `element` but returns undefined\n\t * if the computed style is not expressed in pixels. That can happen in some cases where\n\t * `element` has a size relative to its parent and this last one is not yet displayed,\n\t * for example because of `display: none` on a parent node.\n\t * @see https://developer.mozilla.org/en-US/docs/Web/CSS/used_value\n\t * @returns {Number} Size in pixels or undefined if unknown.\n\t */\n\tfunction readUsedSize(element, property) {\n\t\tvar value = helpers.getStyle(element, property);\n\t\tvar matches = value && value.match(/^(\\d+)(\\.\\d+)?px$/);\n\t\treturn matches? Number(matches[1]) : undefined;\n\t}\n\n\t/**\n\t * Initializes the canvas style and render size without modifying the canvas display size,\n\t * since responsiveness is handled by the controller.resize() method. The config is used\n\t * to determine the aspect ratio to apply in case no explicit height has been specified.\n\t */\n\tfunction initCanvas(canvas, config) {\n\t\tvar style = canvas.style;\n\n\t\t// NOTE(SB) canvas.getAttribute('width') !== canvas.width: in the first case it\n\t\t// returns null or '' if no explicit value has been set to the canvas attribute.\n\t\tvar renderHeight = canvas.getAttribute('height');\n\t\tvar renderWidth = canvas.getAttribute('width');\n\n\t\t// Chart.js modifies some canvas values that we want to restore on destroy\n\t\tcanvas._chartjs = {\n\t\t\tinitial: {\n\t\t\t\theight: renderHeight,\n\t\t\t\twidth: renderWidth,\n\t\t\t\tstyle: {\n\t\t\t\t\tdisplay: style.display,\n\t\t\t\t\theight: style.height,\n\t\t\t\t\twidth: style.width\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\n\t\t// Force canvas to display as block to avoid extra space caused by inline\n\t\t// elements, which would interfere with the responsive resize process.\n\t\t// https://github.com/chartjs/Chart.js/issues/2538\n\t\tstyle.display = style.display || 'block';\n\n\t\tif (renderWidth === null || renderWidth === '') {\n\t\t\tvar displayWidth = readUsedSize(canvas, 'width');\n\t\t\tif (displayWidth !== undefined) {\n\t\t\t\tcanvas.width = displayWidth;\n\t\t\t}\n\t\t}\n\n\t\tif (renderHeight === null || renderHeight === '') {\n\t\t\tif (canvas.style.height === '') {\n\t\t\t\t// If no explicit render height and style height, let's apply the aspect ratio,\n\t\t\t\t// which one can be specified by the user but also by charts as default option\n\t\t\t\t// (i.e. options.aspectRatio). If not specified, use canvas aspect ratio of 2.\n\t\t\t\tcanvas.height = canvas.width / (config.options.aspectRatio || 2);\n\t\t\t} else {\n\t\t\t\tvar displayHeight = readUsedSize(canvas, 'height');\n\t\t\t\tif (displayWidth !== undefined) {\n\t\t\t\t\tcanvas.height = displayHeight;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn canvas;\n\t}\n\n\tfunction createEvent(type, chart, x, y, nativeEvent) {\n\t\treturn {\n\t\t\ttype: type,\n\t\t\tchart: chart,\n\t\t\tnative: nativeEvent || null,\n\t\t\tx: x !== undefined? x : null,\n\t\t\ty: y !== undefined? y : null,\n\t\t};\n\t}\n\n\tfunction fromNativeEvent(event, chart) {\n\t\tvar type = eventTypeMap[event.type] || event.type;\n\t\tvar pos = helpers.getRelativePosition(event, chart);\n\t\treturn createEvent(type, chart, pos.x, pos.y, event);\n\t}\n\n\tfunction createResizer(handler) {\n\t\tvar iframe = document.createElement('iframe');\n\t\tiframe.className = 'chartjs-hidden-iframe';\n\t\tiframe.style.cssText =\n\t\t\t'display:block;'+\n\t\t\t'overflow:hidden;'+\n\t\t\t'border:0;'+\n\t\t\t'margin:0;'+\n\t\t\t'top:0;'+\n\t\t\t'left:0;'+\n\t\t\t'bottom:0;'+\n\t\t\t'right:0;'+\n\t\t\t'height:100%;'+\n\t\t\t'width:100%;'+\n\t\t\t'position:absolute;'+\n\t\t\t'pointer-events:none;'+\n\t\t\t'z-index:-1;';\n\n\t\t// Prevent the iframe to gain focus on tab.\n\t\t// https://github.com/chartjs/Chart.js/issues/3090\n\t\tiframe.tabIndex = -1;\n\n\t\t// If the iframe is re-attached to the DOM, the resize listener is removed because the\n\t\t// content is reloaded, so make sure to install the handler after the iframe is loaded.\n\t\t// https://github.com/chartjs/Chart.js/issues/3521\n\t\thelpers.addEvent(iframe, 'load', function() {\n\t\t\thelpers.addEvent(iframe.contentWindow || iframe, 'resize', handler);\n\n\t\t\t// The iframe size might have changed while loading, which can also\n\t\t\t// happen if the size has been changed while detached from the DOM.\n\t\t\thandler();\n\t\t});\n\n\t\treturn iframe;\n\t}\n\n\tfunction addResizeListener(node, listener, chart) {\n\t\tvar stub = node._chartjs = {\n\t\t\tticking: false\n\t\t};\n\n\t\t// Throttle the callback notification until the next animation frame.\n\t\tvar notify = function() {\n\t\t\tif (!stub.ticking) {\n\t\t\t\tstub.ticking = true;\n\t\t\t\thelpers.requestAnimFrame.call(window, function() {\n\t\t\t\t\tif (stub.resizer) {\n\t\t\t\t\t\tstub.ticking = false;\n\t\t\t\t\t\treturn listener(createEvent('resize', chart));\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t}\n\t\t};\n\n\t\t// Let's keep track of this added iframe and thus avoid DOM query when removing it.\n\t\tstub.resizer = createResizer(notify);\n\n\t\tnode.insertBefore(stub.resizer, node.firstChild);\n\t}\n\n\tfunction removeResizeListener(node) {\n\t\tif (!node || !node._chartjs) {\n\t\t\treturn;\n\t\t}\n\n\t\tvar resizer = node._chartjs.resizer;\n\t\tif (resizer) {\n\t\t\tresizer.parentNode.removeChild(resizer);\n\t\t\tnode._chartjs.resizer = null;\n\t\t}\n\n\t\tdelete node._chartjs;\n\t}\n\n\treturn {\n\t\tacquireContext: function(item, config) {\n\t\t\tif (typeof item === 'string') {\n\t\t\t\titem = document.getElementById(item);\n\t\t\t} else if (item.length) {\n\t\t\t\t// Support for array based queries (such as jQuery)\n\t\t\t\titem = item[0];\n\t\t\t}\n\n\t\t\tif (item && item.canvas) {\n\t\t\t\t// Support for any object associated to a canvas (including a context2d)\n\t\t\t\titem = item.canvas;\n\t\t\t}\n\n\t\t\t// To prevent canvas fingerprinting, some add-ons undefine the getContext\n\t\t\t// method, for example: https://github.com/kkapsner/CanvasBlocker\n\t\t\t// https://github.com/chartjs/Chart.js/issues/2807\n\t\t\tvar context = item && item.getContext && item.getContext('2d');\n\n\t\t\t// `instanceof HTMLCanvasElement/CanvasRenderingContext2D` fails when the item is\n\t\t\t// inside an iframe or when running in a protected environment. We could guess the\n\t\t\t// types from their toString() value but let's keep things flexible and assume it's\n\t\t\t// a sufficient condition if the item has a context2D which has item as `canvas`.\n\t\t\t// https://github.com/chartjs/Chart.js/issues/3887\n\t\t\t// https://github.com/chartjs/Chart.js/issues/4102\n\t\t\t// https://github.com/chartjs/Chart.js/issues/4152\n\t\t\tif (context && context.canvas === item) {\n\t\t\t\tinitCanvas(item, config);\n\t\t\t\treturn context;\n\t\t\t}\n\n\t\t\treturn null;\n\t\t},\n\n\t\treleaseContext: function(context) {\n\t\t\tvar canvas = context.canvas;\n\t\t\tif (!canvas._chartjs) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tvar initial = canvas._chartjs.initial;\n\t\t\t['height', 'width'].forEach(function(prop) {\n\t\t\t\tvar value = initial[prop];\n\t\t\t\tif (value === undefined || value === null) {\n\t\t\t\t\tcanvas.removeAttribute(prop);\n\t\t\t\t} else {\n\t\t\t\t\tcanvas.setAttribute(prop, value);\n\t\t\t\t}\n\t\t\t});\n\n\t\t\thelpers.each(initial.style || {}, function(value, key) {\n\t\t\t\tcanvas.style[key] = value;\n\t\t\t});\n\n\t\t\t// The canvas render size might have been changed (and thus the state stack discarded),\n\t\t\t// we can't use save() and restore() to restore the initial state. So make sure that at\n\t\t\t// least the canvas context is reset to the default state by setting the canvas width.\n\t\t\t// https://www.w3.org/TR/2011/WD-html5-20110525/the-canvas-element.html\n\t\t\tcanvas.width = canvas.width;\n\n\t\t\tdelete canvas._chartjs;\n\t\t},\n\n\t\taddEventListener: function(chart, type, listener) {\n\t\t\tvar canvas = chart.canvas;\n\t\t\tif (type === 'resize') {\n\t\t\t\t// Note: the resize event is not supported on all browsers.\n\t\t\t\taddResizeListener(canvas.parentNode, listener, chart);\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tvar stub = listener._chartjs || (listener._chartjs = {});\n\t\t\tvar proxies = stub.proxies || (stub.proxies = {});\n\t\t\tvar proxy = proxies[chart.id + '_' + type] = function(event) {\n\t\t\t\tlistener(fromNativeEvent(event, chart));\n\t\t\t};\n\n\t\t\thelpers.addEvent(canvas, type, proxy);\n\t\t},\n\n\t\tremoveEventListener: function(chart, type, listener) {\n\t\t\tvar canvas = chart.canvas;\n\t\t\tif (type === 'resize') {\n\t\t\t\t// Note: the resize event is not supported on all browsers.\n\t\t\t\tremoveResizeListener(canvas.parentNode, listener);\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tvar stub = listener._chartjs || {};\n\t\t\tvar proxies = stub.proxies || {};\n\t\t\tvar proxy = proxies[chart.id + '_' + type];\n\t\t\tif (!proxy) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\thelpers.removeEvent(canvas, type, proxy);\n\t\t}\n\t};\n};\n"
  },
  {
    "path": "app_backend/static/plugin/Chart.js-2.6.0/src/platforms/platform.js",
    "content": "'use strict';\n\n// By default, select the browser (DOM) platform.\n// @TODO Make possible to select another platform at build time.\nvar implementation = require('./platform.dom.js');\n\nmodule.exports = function(Chart) {\n\t/**\n\t * @namespace Chart.platform\n\t * @see https://chartjs.gitbooks.io/proposals/content/Platform.html\n\t * @since 2.4.0\n\t */\n\tChart.platform = {\n\t\t/**\n\t\t * Called at chart construction time, returns a context2d instance implementing\n\t\t * the [W3C Canvas 2D Context API standard]{@link https://www.w3.org/TR/2dcontext/}.\n\t\t * @param {*} item - The native item from which to acquire context (platform specific)\n\t\t * @param {Object} options - The chart options\n\t\t * @returns {CanvasRenderingContext2D} context2d instance\n\t\t */\n\t\tacquireContext: function() {},\n\n\t\t/**\n\t\t * Called at chart destruction time, releases any resources associated to the context\n\t\t * previously returned by the acquireContext() method.\n\t\t * @param {CanvasRenderingContext2D} context - The context2d instance\n\t\t * @returns {Boolean} true if the method succeeded, else false\n\t\t */\n\t\treleaseContext: function() {},\n\n\t\t/**\n\t\t * Registers the specified listener on the given chart.\n\t\t * @param {Chart} chart - Chart from which to listen for event\n\t\t * @param {String} type - The ({@link IEvent}) type to listen for\n\t\t * @param {Function} listener - Receives a notification (an object that implements\n\t\t * the {@link IEvent} interface) when an event of the specified type occurs.\n\t\t */\n\t\taddEventListener: function() {},\n\n\t\t/**\n\t\t * Removes the specified listener previously registered with addEventListener.\n\t\t * @param {Chart} chart -Chart from which to remove the listener\n\t\t * @param {String} type - The ({@link IEvent}) type to remove\n\t\t * @param {Function} listener - The listener function to remove from the event target.\n\t\t */\n\t\tremoveEventListener: function() {}\n\t};\n\n\t/**\n\t * @interface IPlatform\n\t * Allows abstracting platform dependencies away from the chart\n\t * @borrows Chart.platform.acquireContext as acquireContext\n\t * @borrows Chart.platform.releaseContext as releaseContext\n\t * @borrows Chart.platform.addEventListener as addEventListener\n\t * @borrows Chart.platform.removeEventListener as removeEventListener\n\t */\n\n\t/**\n\t * @interface IEvent\n\t * @prop {String} type - The event type name, possible values are:\n\t * 'contextmenu', 'mouseenter', 'mousedown', 'mousemove', 'mouseup', 'mouseout',\n\t * 'click', 'dblclick', 'keydown', 'keypress', 'keyup' and 'resize'\n\t * @prop {*} native - The original native event (null for emulated events, e.g. 'resize')\n\t * @prop {Number} x - The mouse x position, relative to the canvas (null for incompatible events)\n\t * @prop {Number} y - The mouse y position, relative to the canvas (null for incompatible events)\n\t */\n\n\tChart.helpers.extend(Chart.platform, implementation(Chart));\n};\n"
  },
  {
    "path": "app_backend/static/plugin/Chart.js-2.6.0/src/plugins/plugin.filler.js",
    "content": "'use strict';\n\nmodule.exports = function(Chart) {\n\t/**\n\t * Plugin based on discussion from the following Chart.js issues:\n\t * @see https://github.com/chartjs/Chart.js/issues/2380#issuecomment-279961569\n\t * @see https://github.com/chartjs/Chart.js/issues/2440#issuecomment-256461897\n\t */\n\tChart.defaults.global.plugins.filler = {\n\t\tpropagate: true\n\t};\n\n\tvar defaults = Chart.defaults;\n\tvar helpers = Chart.helpers;\n\tvar mappers = {\n\t\tdataset: function(source) {\n\t\t\tvar index = source.fill;\n\t\t\tvar chart = source.chart;\n\t\t\tvar meta = chart.getDatasetMeta(index);\n\t\t\tvar visible = meta && chart.isDatasetVisible(index);\n\t\t\tvar points = (visible && meta.dataset._children) || [];\n\n\t\t\treturn !points.length? null : function(point, i) {\n\t\t\t\treturn points[i]._view || null;\n\t\t\t};\n\t\t},\n\n\t\tboundary: function(source) {\n\t\t\tvar boundary = source.boundary;\n\t\t\tvar x = boundary? boundary.x : null;\n\t\t\tvar y = boundary? boundary.y : null;\n\n\t\t\treturn function(point) {\n\t\t\t\treturn {\n\t\t\t\t\tx: x === null? point.x : x,\n\t\t\t\t\ty: y === null? point.y : y,\n\t\t\t\t};\n\t\t\t};\n\t\t}\n\t};\n\n\t// @todo if (fill[0] === '#')\n\tfunction decodeFill(el, index, count) {\n\t\tvar model = el._model || {};\n\t\tvar fill = model.fill;\n\t\tvar target;\n\n\t\tif (fill === undefined) {\n\t\t\tfill = !!model.backgroundColor;\n\t\t}\n\n\t\tif (fill === false || fill === null) {\n\t\t\treturn false;\n\t\t}\n\n\t\tif (fill === true) {\n\t\t\treturn 'origin';\n\t\t}\n\n\t\ttarget = parseFloat(fill, 10);\n\t\tif (isFinite(target) && Math.floor(target) === target) {\n\t\t\tif (fill[0] === '-' || fill[0] === '+') {\n\t\t\t\ttarget = index + target;\n\t\t\t}\n\n\t\t\tif (target === index || target < 0 || target >= count) {\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\treturn target;\n\t\t}\n\n\t\tswitch (fill) {\n\t\t// compatibility\n\t\tcase 'bottom':\n\t\t\treturn 'start';\n\t\tcase 'top':\n\t\t\treturn 'end';\n\t\tcase 'zero':\n\t\t\treturn 'origin';\n\t\t// supported boundaries\n\t\tcase 'origin':\n\t\tcase 'start':\n\t\tcase 'end':\n\t\t\treturn fill;\n\t\t// invalid fill values\n\t\tdefault:\n\t\t\treturn false;\n\t\t}\n\t}\n\n\tfunction computeBoundary(source) {\n\t\tvar model = source.el._model || {};\n\t\tvar scale = source.el._scale || {};\n\t\tvar fill = source.fill;\n\t\tvar target = null;\n\t\tvar horizontal;\n\n\t\tif (isFinite(fill)) {\n\t\t\treturn null;\n\t\t}\n\n\t\t// Backward compatibility: until v3, we still need to support boundary values set on\n\t\t// the model (scaleTop, scaleBottom and scaleZero) because some external plugins and\n\t\t// controllers might still use it (e.g. the Smith chart).\n\n\t\tif (fill === 'start') {\n\t\t\ttarget = model.scaleBottom === undefined? scale.bottom : model.scaleBottom;\n\t\t} else if (fill === 'end') {\n\t\t\ttarget = model.scaleTop === undefined? scale.top : model.scaleTop;\n\t\t} else if (model.scaleZero !== undefined) {\n\t\t\ttarget = model.scaleZero;\n\t\t} else if (scale.getBasePosition) {\n\t\t\ttarget = scale.getBasePosition();\n\t\t} else if (scale.getBasePixel) {\n\t\t\ttarget = scale.getBasePixel();\n\t\t}\n\n\t\tif (target !== undefined && target !== null) {\n\t\t\tif (target.x !== undefined && target.y !== undefined) {\n\t\t\t\treturn target;\n\t\t\t}\n\n\t\t\tif (typeof target === 'number' && isFinite(target)) {\n\t\t\t\thorizontal = scale.isHorizontal();\n\t\t\t\treturn {\n\t\t\t\t\tx: horizontal? target : null,\n\t\t\t\t\ty: horizontal? null : target\n\t\t\t\t};\n\t\t\t}\n\t\t}\n\n\t\treturn null;\n\t}\n\n\tfunction resolveTarget(sources, index, propagate) {\n\t\tvar source = sources[index];\n\t\tvar fill = source.fill;\n\t\tvar visited = [index];\n\t\tvar target;\n\n\t\tif (!propagate) {\n\t\t\treturn fill;\n\t\t}\n\n\t\twhile (fill !== false && visited.indexOf(fill) === -1) {\n\t\t\tif (!isFinite(fill)) {\n\t\t\t\treturn fill;\n\t\t\t}\n\n\t\t\ttarget = sources[fill];\n\t\t\tif (!target) {\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\tif (target.visible) {\n\t\t\t\treturn fill;\n\t\t\t}\n\n\t\t\tvisited.push(fill);\n\t\t\tfill = target.fill;\n\t\t}\n\n\t\treturn false;\n\t}\n\n\tfunction createMapper(source) {\n\t\tvar fill = source.fill;\n\t\tvar type = 'dataset';\n\n\t\tif (fill === false) {\n\t\t\treturn null;\n\t\t}\n\n\t\tif (!isFinite(fill)) {\n\t\t\ttype = 'boundary';\n\t\t}\n\n\t\treturn mappers[type](source);\n\t}\n\n\tfunction isDrawable(point) {\n\t\treturn point && !point.skip;\n\t}\n\n\tfunction drawArea(ctx, curve0, curve1, len0, len1) {\n\t\tvar i;\n\n\t\tif (!len0 || !len1) {\n\t\t\treturn;\n\t\t}\n\n\t\t// building first area curve (normal)\n\t\tctx.moveTo(curve0[0].x, curve0[0].y);\n\t\tfor (i=1; i<len0; ++i) {\n\t\t\thelpers.canvas.lineTo(ctx, curve0[i-1], curve0[i]);\n\t\t}\n\n\t\t// joining the two area curves\n\t\tctx.lineTo(curve1[len1-1].x, curve1[len1-1].y);\n\n\t\t// building opposite area curve (reverse)\n\t\tfor (i=len1-1; i>0; --i) {\n\t\t\thelpers.canvas.lineTo(ctx, curve1[i], curve1[i-1], true);\n\t\t}\n\t}\n\n\tfunction doFill(ctx, points, mapper, view, color, loop) {\n\t\tvar count = points.length;\n\t\tvar span = view.spanGaps;\n\t\tvar curve0 = [];\n\t\tvar curve1 = [];\n\t\tvar len0 = 0;\n\t\tvar len1 = 0;\n\t\tvar i, ilen, index, p0, p1, d0, d1;\n\n\t\tctx.beginPath();\n\n\t\tfor (i = 0, ilen = (count + !!loop); i < ilen; ++i) {\n\t\t\tindex = i%count;\n\t\t\tp0 = points[index]._view;\n\t\t\tp1 = mapper(p0, index, view);\n\t\t\td0 = isDrawable(p0);\n\t\t\td1 = isDrawable(p1);\n\n\t\t\tif (d0 && d1) {\n\t\t\t\tlen0 = curve0.push(p0);\n\t\t\t\tlen1 = curve1.push(p1);\n\t\t\t} else if (len0 && len1) {\n\t\t\t\tif (!span) {\n\t\t\t\t\tdrawArea(ctx, curve0, curve1, len0, len1);\n\t\t\t\t\tlen0 = len1 = 0;\n\t\t\t\t\tcurve0 = [];\n\t\t\t\t\tcurve1 = [];\n\t\t\t\t} else {\n\t\t\t\t\tif (d0) {\n\t\t\t\t\t\tcurve0.push(p0);\n\t\t\t\t\t}\n\t\t\t\t\tif (d1) {\n\t\t\t\t\t\tcurve1.push(p1);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tdrawArea(ctx, curve0, curve1, len0, len1);\n\n\t\tctx.closePath();\n\t\tctx.fillStyle = color;\n\t\tctx.fill();\n\t}\n\n\treturn {\n\t\tid: 'filler',\n\n\t\tafterDatasetsUpdate: function(chart, options) {\n\t\t\tvar count = (chart.data.datasets || []).length;\n\t\t\tvar propagate = options.propagate;\n\t\t\tvar sources = [];\n\t\t\tvar meta, i, el, source;\n\n\t\t\tfor (i = 0; i < count; ++i) {\n\t\t\t\tmeta = chart.getDatasetMeta(i);\n\t\t\t\tel = meta.dataset;\n\t\t\t\tsource = null;\n\n\t\t\t\tif (el && el._model && el instanceof Chart.elements.Line) {\n\t\t\t\t\tsource = {\n\t\t\t\t\t\tvisible: chart.isDatasetVisible(i),\n\t\t\t\t\t\tfill: decodeFill(el, i, count),\n\t\t\t\t\t\tchart: chart,\n\t\t\t\t\t\tel: el\n\t\t\t\t\t};\n\t\t\t\t}\n\n\t\t\t\tmeta.$filler = source;\n\t\t\t\tsources.push(source);\n\t\t\t}\n\n\t\t\tfor (i=0; i<count; ++i) {\n\t\t\t\tsource = sources[i];\n\t\t\t\tif (!source) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\tsource.fill = resolveTarget(sources, i, propagate);\n\t\t\t\tsource.boundary = computeBoundary(source);\n\t\t\t\tsource.mapper = createMapper(source);\n\t\t\t}\n\t\t},\n\n\t\tbeforeDatasetDraw: function(chart, args) {\n\t\t\tvar meta = args.meta.$filler;\n\t\t\tif (!meta) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tvar el = meta.el;\n\t\t\tvar view = el._view;\n\t\t\tvar points = el._children || [];\n\t\t\tvar mapper = meta.mapper;\n\t\t\tvar color = view.backgroundColor || defaults.global.defaultColor;\n\n\t\t\tif (mapper && color && points.length) {\n\t\t\t\tdoFill(chart.ctx, points, mapper, view, color, el._loop);\n\t\t\t}\n\t\t}\n\t};\n};\n"
  },
  {
    "path": "app_backend/static/plugin/Chart.js-2.6.0/src/plugins/plugin.legend.js",
    "content": "'use strict';\n\nmodule.exports = function(Chart) {\n\n\tvar helpers = Chart.helpers;\n\tvar layout = Chart.layoutService;\n\tvar noop = helpers.noop;\n\n\tChart.defaults.global.legend = {\n\t\tdisplay: true,\n\t\tposition: 'top',\n\t\tfullWidth: true,\n\t\treverse: false,\n\t\tweight: 1000,\n\n\t\t// a callback that will handle\n\t\tonClick: function(e, legendItem) {\n\t\t\tvar index = legendItem.datasetIndex;\n\t\t\tvar ci = this.chart;\n\t\t\tvar meta = ci.getDatasetMeta(index);\n\n\t\t\t// See controller.isDatasetVisible comment\n\t\t\tmeta.hidden = meta.hidden === null? !ci.data.datasets[index].hidden : null;\n\n\t\t\t// We hid a dataset ... rerender the chart\n\t\t\tci.update();\n\t\t},\n\n\t\tonHover: null,\n\n\t\tlabels: {\n\t\t\tboxWidth: 40,\n\t\t\tpadding: 10,\n\t\t\t// Generates labels shown in the legend\n\t\t\t// Valid properties to return:\n\t\t\t// text : text to display\n\t\t\t// fillStyle : fill of coloured box\n\t\t\t// strokeStyle: stroke of coloured box\n\t\t\t// hidden : if this legend item refers to a hidden item\n\t\t\t// lineCap : cap style for line\n\t\t\t// lineDash\n\t\t\t// lineDashOffset :\n\t\t\t// lineJoin :\n\t\t\t// lineWidth :\n\t\t\tgenerateLabels: function(chart) {\n\t\t\t\tvar data = chart.data;\n\t\t\t\treturn helpers.isArray(data.datasets) ? data.datasets.map(function(dataset, i) {\n\t\t\t\t\treturn {\n\t\t\t\t\t\ttext: dataset.label,\n\t\t\t\t\t\tfillStyle: (!helpers.isArray(dataset.backgroundColor) ? dataset.backgroundColor : dataset.backgroundColor[0]),\n\t\t\t\t\t\thidden: !chart.isDatasetVisible(i),\n\t\t\t\t\t\tlineCap: dataset.borderCapStyle,\n\t\t\t\t\t\tlineDash: dataset.borderDash,\n\t\t\t\t\t\tlineDashOffset: dataset.borderDashOffset,\n\t\t\t\t\t\tlineJoin: dataset.borderJoinStyle,\n\t\t\t\t\t\tlineWidth: dataset.borderWidth,\n\t\t\t\t\t\tstrokeStyle: dataset.borderColor,\n\t\t\t\t\t\tpointStyle: dataset.pointStyle,\n\n\t\t\t\t\t\t// Below is extra data used for toggling the datasets\n\t\t\t\t\t\tdatasetIndex: i\n\t\t\t\t\t};\n\t\t\t\t}, this) : [];\n\t\t\t}\n\t\t}\n\t};\n\n\t/**\n\t * Helper function to get the box width based on the usePointStyle option\n\t * @param labelopts {Object} the label options on the legend\n\t * @param fontSize {Number} the label font size\n\t * @return {Number} width of the color box area\n\t */\n\tfunction getBoxWidth(labelOpts, fontSize) {\n\t\treturn labelOpts.usePointStyle ?\n\t\t\tfontSize * Math.SQRT2 :\n\t\t\tlabelOpts.boxWidth;\n\t}\n\n\tChart.Legend = Chart.Element.extend({\n\n\t\tinitialize: function(config) {\n\t\t\thelpers.extend(this, config);\n\n\t\t\t// Contains hit boxes for each dataset (in dataset order)\n\t\t\tthis.legendHitBoxes = [];\n\n\t\t\t// Are we in doughnut mode which has a different data type\n\t\t\tthis.doughnutMode = false;\n\t\t},\n\n\t\t// These methods are ordered by lifecycle. Utilities then follow.\n\t\t// Any function defined here is inherited by all legend types.\n\t\t// Any function can be extended by the legend type\n\n\t\tbeforeUpdate: noop,\n\t\tupdate: function(maxWidth, maxHeight, margins) {\n\t\t\tvar me = this;\n\n\t\t\t// Update Lifecycle - Probably don't want to ever extend or overwrite this function ;)\n\t\t\tme.beforeUpdate();\n\n\t\t\t// Absorb the master measurements\n\t\t\tme.maxWidth = maxWidth;\n\t\t\tme.maxHeight = maxHeight;\n\t\t\tme.margins = margins;\n\n\t\t\t// Dimensions\n\t\t\tme.beforeSetDimensions();\n\t\t\tme.setDimensions();\n\t\t\tme.afterSetDimensions();\n\t\t\t// Labels\n\t\t\tme.beforeBuildLabels();\n\t\t\tme.buildLabels();\n\t\t\tme.afterBuildLabels();\n\n\t\t\t// Fit\n\t\t\tme.beforeFit();\n\t\t\tme.fit();\n\t\t\tme.afterFit();\n\t\t\t//\n\t\t\tme.afterUpdate();\n\n\t\t\treturn me.minSize;\n\t\t},\n\t\tafterUpdate: noop,\n\n\t\t//\n\n\t\tbeforeSetDimensions: noop,\n\t\tsetDimensions: function() {\n\t\t\tvar me = this;\n\t\t\t// Set the unconstrained dimension before label rotation\n\t\t\tif (me.isHorizontal()) {\n\t\t\t\t// Reset position before calculating rotation\n\t\t\t\tme.width = me.maxWidth;\n\t\t\t\tme.left = 0;\n\t\t\t\tme.right = me.width;\n\t\t\t} else {\n\t\t\t\tme.height = me.maxHeight;\n\n\t\t\t\t// Reset position before calculating rotation\n\t\t\t\tme.top = 0;\n\t\t\t\tme.bottom = me.height;\n\t\t\t}\n\n\t\t\t// Reset padding\n\t\t\tme.paddingLeft = 0;\n\t\t\tme.paddingTop = 0;\n\t\t\tme.paddingRight = 0;\n\t\t\tme.paddingBottom = 0;\n\n\t\t\t// Reset minSize\n\t\t\tme.minSize = {\n\t\t\t\twidth: 0,\n\t\t\t\theight: 0\n\t\t\t};\n\t\t},\n\t\tafterSetDimensions: noop,\n\n\t\t//\n\n\t\tbeforeBuildLabels: noop,\n\t\tbuildLabels: function() {\n\t\t\tvar me = this;\n\t\t\tvar labelOpts = me.options.labels;\n\t\t\tvar legendItems = labelOpts.generateLabels.call(me, me.chart);\n\n\t\t\tif (labelOpts.filter) {\n\t\t\t\tlegendItems = legendItems.filter(function(item) {\n\t\t\t\t\treturn labelOpts.filter(item, me.chart.data);\n\t\t\t\t});\n\t\t\t}\n\n\t\t\tif (me.options.reverse) {\n\t\t\t\tlegendItems.reverse();\n\t\t\t}\n\n\t\t\tme.legendItems = legendItems;\n\t\t},\n\t\tafterBuildLabels: noop,\n\n\t\t//\n\n\t\tbeforeFit: noop,\n\t\tfit: function() {\n\t\t\tvar me = this;\n\t\t\tvar opts = me.options;\n\t\t\tvar labelOpts = opts.labels;\n\t\t\tvar display = opts.display;\n\n\t\t\tvar ctx = me.ctx;\n\n\t\t\tvar globalDefault = Chart.defaults.global,\n\t\t\t\titemOrDefault = helpers.getValueOrDefault,\n\t\t\t\tfontSize = itemOrDefault(labelOpts.fontSize, globalDefault.defaultFontSize),\n\t\t\t\tfontStyle = itemOrDefault(labelOpts.fontStyle, globalDefault.defaultFontStyle),\n\t\t\t\tfontFamily = itemOrDefault(labelOpts.fontFamily, globalDefault.defaultFontFamily),\n\t\t\t\tlabelFont = helpers.fontString(fontSize, fontStyle, fontFamily);\n\n\t\t\t// Reset hit boxes\n\t\t\tvar hitboxes = me.legendHitBoxes = [];\n\n\t\t\tvar minSize = me.minSize;\n\t\t\tvar isHorizontal = me.isHorizontal();\n\n\t\t\tif (isHorizontal) {\n\t\t\t\tminSize.width = me.maxWidth; // fill all the width\n\t\t\t\tminSize.height = display ? 10 : 0;\n\t\t\t} else {\n\t\t\t\tminSize.width = display ? 10 : 0;\n\t\t\t\tminSize.height = me.maxHeight; // fill all the height\n\t\t\t}\n\n\t\t\t// Increase sizes here\n\t\t\tif (display) {\n\t\t\t\tctx.font = labelFont;\n\n\t\t\t\tif (isHorizontal) {\n\t\t\t\t\t// Labels\n\n\t\t\t\t\t// Width of each line of legend boxes. Labels wrap onto multiple lines when there are too many to fit on one\n\t\t\t\t\tvar lineWidths = me.lineWidths = [0];\n\t\t\t\t\tvar totalHeight = me.legendItems.length ? fontSize + (labelOpts.padding) : 0;\n\n\t\t\t\t\tctx.textAlign = 'left';\n\t\t\t\t\tctx.textBaseline = 'top';\n\n\t\t\t\t\thelpers.each(me.legendItems, function(legendItem, i) {\n\t\t\t\t\t\tvar boxWidth = getBoxWidth(labelOpts, fontSize);\n\t\t\t\t\t\tvar width = boxWidth + (fontSize / 2) + ctx.measureText(legendItem.text).width;\n\n\t\t\t\t\t\tif (lineWidths[lineWidths.length - 1] + width + labelOpts.padding >= me.width) {\n\t\t\t\t\t\t\ttotalHeight += fontSize + (labelOpts.padding);\n\t\t\t\t\t\t\tlineWidths[lineWidths.length] = me.left;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// Store the hitbox width and height here. Final position will be updated in `draw`\n\t\t\t\t\t\thitboxes[i] = {\n\t\t\t\t\t\t\tleft: 0,\n\t\t\t\t\t\t\ttop: 0,\n\t\t\t\t\t\t\twidth: width,\n\t\t\t\t\t\t\theight: fontSize\n\t\t\t\t\t\t};\n\n\t\t\t\t\t\tlineWidths[lineWidths.length - 1] += width + labelOpts.padding;\n\t\t\t\t\t});\n\n\t\t\t\t\tminSize.height += totalHeight;\n\n\t\t\t\t} else {\n\t\t\t\t\tvar vPadding = labelOpts.padding;\n\t\t\t\t\tvar columnWidths = me.columnWidths = [];\n\t\t\t\t\tvar totalWidth = labelOpts.padding;\n\t\t\t\t\tvar currentColWidth = 0;\n\t\t\t\t\tvar currentColHeight = 0;\n\t\t\t\t\tvar itemHeight = fontSize + vPadding;\n\n\t\t\t\t\thelpers.each(me.legendItems, function(legendItem, i) {\n\t\t\t\t\t\tvar boxWidth = getBoxWidth(labelOpts, fontSize);\n\t\t\t\t\t\tvar itemWidth = boxWidth + (fontSize / 2) + ctx.measureText(legendItem.text).width;\n\n\t\t\t\t\t\t// If too tall, go to new column\n\t\t\t\t\t\tif (currentColHeight + itemHeight > minSize.height) {\n\t\t\t\t\t\t\ttotalWidth += currentColWidth + labelOpts.padding;\n\t\t\t\t\t\t\tcolumnWidths.push(currentColWidth); // previous column width\n\n\t\t\t\t\t\t\tcurrentColWidth = 0;\n\t\t\t\t\t\t\tcurrentColHeight = 0;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// Get max width\n\t\t\t\t\t\tcurrentColWidth = Math.max(currentColWidth, itemWidth);\n\t\t\t\t\t\tcurrentColHeight += itemHeight;\n\n\t\t\t\t\t\t// Store the hitbox width and height here. Final position will be updated in `draw`\n\t\t\t\t\t\thitboxes[i] = {\n\t\t\t\t\t\t\tleft: 0,\n\t\t\t\t\t\t\ttop: 0,\n\t\t\t\t\t\t\twidth: itemWidth,\n\t\t\t\t\t\t\theight: fontSize\n\t\t\t\t\t\t};\n\t\t\t\t\t});\n\n\t\t\t\t\ttotalWidth += currentColWidth;\n\t\t\t\t\tcolumnWidths.push(currentColWidth);\n\t\t\t\t\tminSize.width += totalWidth;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tme.width = minSize.width;\n\t\t\tme.height = minSize.height;\n\t\t},\n\t\tafterFit: noop,\n\n\t\t// Shared Methods\n\t\tisHorizontal: function() {\n\t\t\treturn this.options.position === 'top' || this.options.position === 'bottom';\n\t\t},\n\n\t\t// Actually draw the legend on the canvas\n\t\tdraw: function() {\n\t\t\tvar me = this;\n\t\t\tvar opts = me.options;\n\t\t\tvar labelOpts = opts.labels;\n\t\t\tvar globalDefault = Chart.defaults.global,\n\t\t\t\tlineDefault = globalDefault.elements.line,\n\t\t\t\tlegendWidth = me.width,\n\t\t\t\tlineWidths = me.lineWidths;\n\n\t\t\tif (opts.display) {\n\t\t\t\tvar ctx = me.ctx,\n\t\t\t\t\tcursor,\n\t\t\t\t\titemOrDefault = helpers.getValueOrDefault,\n\t\t\t\t\tfontColor = itemOrDefault(labelOpts.fontColor, globalDefault.defaultFontColor),\n\t\t\t\t\tfontSize = itemOrDefault(labelOpts.fontSize, globalDefault.defaultFontSize),\n\t\t\t\t\tfontStyle = itemOrDefault(labelOpts.fontStyle, globalDefault.defaultFontStyle),\n\t\t\t\t\tfontFamily = itemOrDefault(labelOpts.fontFamily, globalDefault.defaultFontFamily),\n\t\t\t\t\tlabelFont = helpers.fontString(fontSize, fontStyle, fontFamily);\n\n\t\t\t\t// Canvas setup\n\t\t\t\tctx.textAlign = 'left';\n\t\t\t\tctx.textBaseline = 'top';\n\t\t\t\tctx.lineWidth = 0.5;\n\t\t\t\tctx.strokeStyle = fontColor; // for strikethrough effect\n\t\t\t\tctx.fillStyle = fontColor; // render in correct colour\n\t\t\t\tctx.font = labelFont;\n\n\t\t\t\tvar boxWidth = getBoxWidth(labelOpts, fontSize),\n\t\t\t\t\thitboxes = me.legendHitBoxes;\n\n\t\t\t\t// current position\n\t\t\t\tvar drawLegendBox = function(x, y, legendItem) {\n\t\t\t\t\tif (isNaN(boxWidth) || boxWidth <= 0) {\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\n\t\t\t\t\t// Set the ctx for the box\n\t\t\t\t\tctx.save();\n\n\t\t\t\t\tctx.fillStyle = itemOrDefault(legendItem.fillStyle, globalDefault.defaultColor);\n\t\t\t\t\tctx.lineCap = itemOrDefault(legendItem.lineCap, lineDefault.borderCapStyle);\n\t\t\t\t\tctx.lineDashOffset = itemOrDefault(legendItem.lineDashOffset, lineDefault.borderDashOffset);\n\t\t\t\t\tctx.lineJoin = itemOrDefault(legendItem.lineJoin, lineDefault.borderJoinStyle);\n\t\t\t\t\tctx.lineWidth = itemOrDefault(legendItem.lineWidth, lineDefault.borderWidth);\n\t\t\t\t\tctx.strokeStyle = itemOrDefault(legendItem.strokeStyle, globalDefault.defaultColor);\n\t\t\t\t\tvar isLineWidthZero = (itemOrDefault(legendItem.lineWidth, lineDefault.borderWidth) === 0);\n\n\t\t\t\t\tif (ctx.setLineDash) {\n\t\t\t\t\t\t// IE 9 and 10 do not support line dash\n\t\t\t\t\t\tctx.setLineDash(itemOrDefault(legendItem.lineDash, lineDefault.borderDash));\n\t\t\t\t\t}\n\n\t\t\t\t\tif (opts.labels && opts.labels.usePointStyle) {\n\t\t\t\t\t\t// Recalculate x and y for drawPoint() because its expecting\n\t\t\t\t\t\t// x and y to be center of figure (instead of top left)\n\t\t\t\t\t\tvar radius = fontSize * Math.SQRT2 / 2;\n\t\t\t\t\t\tvar offSet = radius / Math.SQRT2;\n\t\t\t\t\t\tvar centerX = x + offSet;\n\t\t\t\t\t\tvar centerY = y + offSet;\n\n\t\t\t\t\t\t// Draw pointStyle as legend symbol\n\t\t\t\t\t\tChart.canvasHelpers.drawPoint(ctx, legendItem.pointStyle, radius, centerX, centerY);\n\t\t\t\t\t} else {\n\t\t\t\t\t\t// Draw box as legend symbol\n\t\t\t\t\t\tif (!isLineWidthZero) {\n\t\t\t\t\t\t\tctx.strokeRect(x, y, boxWidth, fontSize);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tctx.fillRect(x, y, boxWidth, fontSize);\n\t\t\t\t\t}\n\n\t\t\t\t\tctx.restore();\n\t\t\t\t};\n\t\t\t\tvar fillText = function(x, y, legendItem, textWidth) {\n\t\t\t\t\tctx.fillText(legendItem.text, boxWidth + (fontSize / 2) + x, y);\n\n\t\t\t\t\tif (legendItem.hidden) {\n\t\t\t\t\t\t// Strikethrough the text if hidden\n\t\t\t\t\t\tctx.beginPath();\n\t\t\t\t\t\tctx.lineWidth = 2;\n\t\t\t\t\t\tctx.moveTo(boxWidth + (fontSize / 2) + x, y + (fontSize / 2));\n\t\t\t\t\t\tctx.lineTo(boxWidth + (fontSize / 2) + x + textWidth, y + (fontSize / 2));\n\t\t\t\t\t\tctx.stroke();\n\t\t\t\t\t}\n\t\t\t\t};\n\n\t\t\t\t// Horizontal\n\t\t\t\tvar isHorizontal = me.isHorizontal();\n\t\t\t\tif (isHorizontal) {\n\t\t\t\t\tcursor = {\n\t\t\t\t\t\tx: me.left + ((legendWidth - lineWidths[0]) / 2),\n\t\t\t\t\t\ty: me.top + labelOpts.padding,\n\t\t\t\t\t\tline: 0\n\t\t\t\t\t};\n\t\t\t\t} else {\n\t\t\t\t\tcursor = {\n\t\t\t\t\t\tx: me.left + labelOpts.padding,\n\t\t\t\t\t\ty: me.top + labelOpts.padding,\n\t\t\t\t\t\tline: 0\n\t\t\t\t\t};\n\t\t\t\t}\n\n\t\t\t\tvar itemHeight = fontSize + labelOpts.padding;\n\t\t\t\thelpers.each(me.legendItems, function(legendItem, i) {\n\t\t\t\t\tvar textWidth = ctx.measureText(legendItem.text).width,\n\t\t\t\t\t\twidth = boxWidth + (fontSize / 2) + textWidth,\n\t\t\t\t\t\tx = cursor.x,\n\t\t\t\t\t\ty = cursor.y;\n\n\t\t\t\t\tif (isHorizontal) {\n\t\t\t\t\t\tif (x + width >= legendWidth) {\n\t\t\t\t\t\t\ty = cursor.y += itemHeight;\n\t\t\t\t\t\t\tcursor.line++;\n\t\t\t\t\t\t\tx = cursor.x = me.left + ((legendWidth - lineWidths[cursor.line]) / 2);\n\t\t\t\t\t\t}\n\t\t\t\t\t} else if (y + itemHeight > me.bottom) {\n\t\t\t\t\t\tx = cursor.x = x + me.columnWidths[cursor.line] + labelOpts.padding;\n\t\t\t\t\t\ty = cursor.y = me.top + labelOpts.padding;\n\t\t\t\t\t\tcursor.line++;\n\t\t\t\t\t}\n\n\t\t\t\t\tdrawLegendBox(x, y, legendItem);\n\n\t\t\t\t\thitboxes[i].left = x;\n\t\t\t\t\thitboxes[i].top = y;\n\n\t\t\t\t\t// Fill the actual label\n\t\t\t\t\tfillText(x, y, legendItem, textWidth);\n\n\t\t\t\t\tif (isHorizontal) {\n\t\t\t\t\t\tcursor.x += width + (labelOpts.padding);\n\t\t\t\t\t} else {\n\t\t\t\t\t\tcursor.y += itemHeight;\n\t\t\t\t\t}\n\n\t\t\t\t});\n\t\t\t}\n\t\t},\n\n\t\t/**\n\t\t * Handle an event\n\t\t * @private\n\t\t * @param {IEvent} event - The event to handle\n\t\t * @return {Boolean} true if a change occured\n\t\t */\n\t\thandleEvent: function(e) {\n\t\t\tvar me = this;\n\t\t\tvar opts = me.options;\n\t\t\tvar type = e.type === 'mouseup' ? 'click' : e.type;\n\t\t\tvar changed = false;\n\n\t\t\tif (type === 'mousemove') {\n\t\t\t\tif (!opts.onHover) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t} else if (type === 'click') {\n\t\t\t\tif (!opts.onClick) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// Chart event already has relative position in it\n\t\t\tvar x = e.x,\n\t\t\t\ty = e.y;\n\n\t\t\tif (x >= me.left && x <= me.right && y >= me.top && y <= me.bottom) {\n\t\t\t\t// See if we are touching one of the dataset boxes\n\t\t\t\tvar lh = me.legendHitBoxes;\n\t\t\t\tfor (var i = 0; i < lh.length; ++i) {\n\t\t\t\t\tvar hitBox = lh[i];\n\n\t\t\t\t\tif (x >= hitBox.left && x <= hitBox.left + hitBox.width && y >= hitBox.top && y <= hitBox.top + hitBox.height) {\n\t\t\t\t\t\t// Touching an element\n\t\t\t\t\t\tif (type === 'click') {\n\t\t\t\t\t\t\t// use e.native for backwards compatibility\n\t\t\t\t\t\t\topts.onClick.call(me, e.native, me.legendItems[i]);\n\t\t\t\t\t\t\tchanged = true;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t} else if (type === 'mousemove') {\n\t\t\t\t\t\t\t// use e.native for backwards compatibility\n\t\t\t\t\t\t\topts.onHover.call(me, e.native, me.legendItems[i]);\n\t\t\t\t\t\t\tchanged = true;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn changed;\n\t\t}\n\t});\n\n\tfunction createNewLegendAndAttach(chart, legendOpts) {\n\t\tvar legend = new Chart.Legend({\n\t\t\tctx: chart.ctx,\n\t\t\toptions: legendOpts,\n\t\t\tchart: chart\n\t\t});\n\n\t\tlayout.configure(chart, legend, legendOpts);\n\t\tlayout.addBox(chart, legend);\n\t\tchart.legend = legend;\n\t}\n\n\treturn {\n\t\tid: 'legend',\n\n\t\tbeforeInit: function(chart) {\n\t\t\tvar legendOpts = chart.options.legend;\n\n\t\t\tif (legendOpts) {\n\t\t\t\tcreateNewLegendAndAttach(chart, legendOpts);\n\t\t\t}\n\t\t},\n\n\t\tbeforeUpdate: function(chart) {\n\t\t\tvar legendOpts = chart.options.legend;\n\t\t\tvar legend = chart.legend;\n\n\t\t\tif (legendOpts) {\n\t\t\t\tlegendOpts = helpers.configMerge(Chart.defaults.global.legend, legendOpts);\n\n\t\t\t\tif (legend) {\n\t\t\t\t\tlayout.configure(chart, legend, legendOpts);\n\t\t\t\t\tlegend.options = legendOpts;\n\t\t\t\t} else {\n\t\t\t\t\tcreateNewLegendAndAttach(chart, legendOpts);\n\t\t\t\t}\n\t\t\t} else if (legend) {\n\t\t\t\tlayout.removeBox(chart, legend);\n\t\t\t\tdelete chart.legend;\n\t\t\t}\n\t\t},\n\n\t\tafterEvent: function(chart, e) {\n\t\t\tvar legend = chart.legend;\n\t\t\tif (legend) {\n\t\t\t\tlegend.handleEvent(e);\n\t\t\t}\n\t\t}\n\t};\n};\n"
  },
  {
    "path": "app_backend/static/plugin/Chart.js-2.6.0/src/plugins/plugin.title.js",
    "content": "'use strict';\n\nmodule.exports = function(Chart) {\n\n\tvar helpers = Chart.helpers;\n\tvar layout = Chart.layoutService;\n\tvar noop = helpers.noop;\n\n\tChart.defaults.global.title = {\n\t\tdisplay: false,\n\t\tposition: 'top',\n\t\tfullWidth: true,\n\t\tweight: 2000,        // by default greater than legend (1000) to be above\n\t\tfontStyle: 'bold',\n\t\tpadding: 10,\n\n\t\t// actual title\n\t\ttext: ''\n\t};\n\n\tChart.Title = Chart.Element.extend({\n\t\tinitialize: function(config) {\n\t\t\tvar me = this;\n\t\t\thelpers.extend(me, config);\n\n\t\t\t// Contains hit boxes for each dataset (in dataset order)\n\t\t\tme.legendHitBoxes = [];\n\t\t},\n\n\t\t// These methods are ordered by lifecycle. Utilities then follow.\n\n\t\tbeforeUpdate: noop,\n\t\tupdate: function(maxWidth, maxHeight, margins) {\n\t\t\tvar me = this;\n\n\t\t\t// Update Lifecycle - Probably don't want to ever extend or overwrite this function ;)\n\t\t\tme.beforeUpdate();\n\n\t\t\t// Absorb the master measurements\n\t\t\tme.maxWidth = maxWidth;\n\t\t\tme.maxHeight = maxHeight;\n\t\t\tme.margins = margins;\n\n\t\t\t// Dimensions\n\t\t\tme.beforeSetDimensions();\n\t\t\tme.setDimensions();\n\t\t\tme.afterSetDimensions();\n\t\t\t// Labels\n\t\t\tme.beforeBuildLabels();\n\t\t\tme.buildLabels();\n\t\t\tme.afterBuildLabels();\n\n\t\t\t// Fit\n\t\t\tme.beforeFit();\n\t\t\tme.fit();\n\t\t\tme.afterFit();\n\t\t\t//\n\t\t\tme.afterUpdate();\n\n\t\t\treturn me.minSize;\n\n\t\t},\n\t\tafterUpdate: noop,\n\n\t\t//\n\n\t\tbeforeSetDimensions: noop,\n\t\tsetDimensions: function() {\n\t\t\tvar me = this;\n\t\t\t// Set the unconstrained dimension before label rotation\n\t\t\tif (me.isHorizontal()) {\n\t\t\t\t// Reset position before calculating rotation\n\t\t\t\tme.width = me.maxWidth;\n\t\t\t\tme.left = 0;\n\t\t\t\tme.right = me.width;\n\t\t\t} else {\n\t\t\t\tme.height = me.maxHeight;\n\n\t\t\t\t// Reset position before calculating rotation\n\t\t\t\tme.top = 0;\n\t\t\t\tme.bottom = me.height;\n\t\t\t}\n\n\t\t\t// Reset padding\n\t\t\tme.paddingLeft = 0;\n\t\t\tme.paddingTop = 0;\n\t\t\tme.paddingRight = 0;\n\t\t\tme.paddingBottom = 0;\n\n\t\t\t// Reset minSize\n\t\t\tme.minSize = {\n\t\t\t\twidth: 0,\n\t\t\t\theight: 0\n\t\t\t};\n\t\t},\n\t\tafterSetDimensions: noop,\n\n\t\t//\n\n\t\tbeforeBuildLabels: noop,\n\t\tbuildLabels: noop,\n\t\tafterBuildLabels: noop,\n\n\t\t//\n\n\t\tbeforeFit: noop,\n\t\tfit: function() {\n\t\t\tvar me = this,\n\t\t\t\tvalueOrDefault = helpers.getValueOrDefault,\n\t\t\t\topts = me.options,\n\t\t\t\tglobalDefaults = Chart.defaults.global,\n\t\t\t\tdisplay = opts.display,\n\t\t\t\tfontSize = valueOrDefault(opts.fontSize, globalDefaults.defaultFontSize),\n\t\t\t\tminSize = me.minSize;\n\n\t\t\tif (me.isHorizontal()) {\n\t\t\t\tminSize.width = me.maxWidth; // fill all the width\n\t\t\t\tminSize.height = display ? fontSize + (opts.padding * 2) : 0;\n\t\t\t} else {\n\t\t\t\tminSize.width = display ? fontSize + (opts.padding * 2) : 0;\n\t\t\t\tminSize.height = me.maxHeight; // fill all the height\n\t\t\t}\n\n\t\t\tme.width = minSize.width;\n\t\t\tme.height = minSize.height;\n\n\t\t},\n\t\tafterFit: noop,\n\n\t\t// Shared Methods\n\t\tisHorizontal: function() {\n\t\t\tvar pos = this.options.position;\n\t\t\treturn pos === 'top' || pos === 'bottom';\n\t\t},\n\n\t\t// Actually draw the title block on the canvas\n\t\tdraw: function() {\n\t\t\tvar me = this,\n\t\t\t\tctx = me.ctx,\n\t\t\t\tvalueOrDefault = helpers.getValueOrDefault,\n\t\t\t\topts = me.options,\n\t\t\t\tglobalDefaults = Chart.defaults.global;\n\n\t\t\tif (opts.display) {\n\t\t\t\tvar fontSize = valueOrDefault(opts.fontSize, globalDefaults.defaultFontSize),\n\t\t\t\t\tfontStyle = valueOrDefault(opts.fontStyle, globalDefaults.defaultFontStyle),\n\t\t\t\t\tfontFamily = valueOrDefault(opts.fontFamily, globalDefaults.defaultFontFamily),\n\t\t\t\t\ttitleFont = helpers.fontString(fontSize, fontStyle, fontFamily),\n\t\t\t\t\trotation = 0,\n\t\t\t\t\ttitleX,\n\t\t\t\t\ttitleY,\n\t\t\t\t\ttop = me.top,\n\t\t\t\t\tleft = me.left,\n\t\t\t\t\tbottom = me.bottom,\n\t\t\t\t\tright = me.right,\n\t\t\t\t\tmaxWidth;\n\n\t\t\t\tctx.fillStyle = valueOrDefault(opts.fontColor, globalDefaults.defaultFontColor); // render in correct colour\n\t\t\t\tctx.font = titleFont;\n\n\t\t\t\t// Horizontal\n\t\t\t\tif (me.isHorizontal()) {\n\t\t\t\t\ttitleX = left + ((right - left) / 2); // midpoint of the width\n\t\t\t\t\ttitleY = top + ((bottom - top) / 2); // midpoint of the height\n\t\t\t\t\tmaxWidth = right - left;\n\t\t\t\t} else {\n\t\t\t\t\ttitleX = opts.position === 'left' ? left + (fontSize / 2) : right - (fontSize / 2);\n\t\t\t\t\ttitleY = top + ((bottom - top) / 2);\n\t\t\t\t\tmaxWidth = bottom - top;\n\t\t\t\t\trotation = Math.PI * (opts.position === 'left' ? -0.5 : 0.5);\n\t\t\t\t}\n\n\t\t\t\tctx.save();\n\t\t\t\tctx.translate(titleX, titleY);\n\t\t\t\tctx.rotate(rotation);\n\t\t\t\tctx.textAlign = 'center';\n\t\t\t\tctx.textBaseline = 'middle';\n\t\t\t\tctx.fillText(opts.text, 0, 0, maxWidth);\n\t\t\t\tctx.restore();\n\t\t\t}\n\t\t}\n\t});\n\n\tfunction createNewTitleBlockAndAttach(chart, titleOpts) {\n\t\tvar title = new Chart.Title({\n\t\t\tctx: chart.ctx,\n\t\t\toptions: titleOpts,\n\t\t\tchart: chart\n\t\t});\n\n\t\tlayout.configure(chart, title, titleOpts);\n\t\tlayout.addBox(chart, title);\n\t\tchart.titleBlock = title;\n\t}\n\n\treturn {\n\t\tid: 'title',\n\n\t\tbeforeInit: function(chart) {\n\t\t\tvar titleOpts = chart.options.title;\n\n\t\t\tif (titleOpts) {\n\t\t\t\tcreateNewTitleBlockAndAttach(chart, titleOpts);\n\t\t\t}\n\t\t},\n\n\t\tbeforeUpdate: function(chart) {\n\t\t\tvar titleOpts = chart.options.title;\n\t\t\tvar titleBlock = chart.titleBlock;\n\n\t\t\tif (titleOpts) {\n\t\t\t\ttitleOpts = helpers.configMerge(Chart.defaults.global.title, titleOpts);\n\n\t\t\t\tif (titleBlock) {\n\t\t\t\t\tlayout.configure(chart, titleBlock, titleOpts);\n\t\t\t\t\ttitleBlock.options = titleOpts;\n\t\t\t\t} else {\n\t\t\t\t\tcreateNewTitleBlockAndAttach(chart, titleOpts);\n\t\t\t\t}\n\t\t\t} else if (titleBlock) {\n\t\t\t\tChart.layoutService.removeBox(chart, titleBlock);\n\t\t\t\tdelete chart.titleBlock;\n\t\t\t}\n\t\t}\n\t};\n};\n"
  },
  {
    "path": "app_backend/static/plugin/Chart.js-2.6.0/src/scales/scale.category.js",
    "content": "'use strict';\n\nmodule.exports = function(Chart) {\n\n\tvar helpers = Chart.helpers;\n\t// Default config for a category scale\n\tvar defaultConfig = {\n\t\tposition: 'bottom'\n\t};\n\n\tvar DatasetScale = Chart.Scale.extend({\n\t\t/**\n\t\t* Internal function to get the correct labels. If data.xLabels or data.yLabels are defined, use those\n\t\t* else fall back to data.labels\n\t\t* @private\n\t\t*/\n\t\tgetLabels: function() {\n\t\t\tvar data = this.chart.data;\n\t\t\treturn (this.isHorizontal() ? data.xLabels : data.yLabels) || data.labels;\n\t\t},\n\n\t\tdetermineDataLimits: function() {\n\t\t\tvar me = this;\n\t\t\tvar labels = me.getLabels();\n\t\t\tme.minIndex = 0;\n\t\t\tme.maxIndex = labels.length - 1;\n\t\t\tvar findIndex;\n\n\t\t\tif (me.options.ticks.min !== undefined) {\n\t\t\t\t// user specified min value\n\t\t\t\tfindIndex = helpers.indexOf(labels, me.options.ticks.min);\n\t\t\t\tme.minIndex = findIndex !== -1 ? findIndex : me.minIndex;\n\t\t\t}\n\n\t\t\tif (me.options.ticks.max !== undefined) {\n\t\t\t\t// user specified max value\n\t\t\t\tfindIndex = helpers.indexOf(labels, me.options.ticks.max);\n\t\t\t\tme.maxIndex = findIndex !== -1 ? findIndex : me.maxIndex;\n\t\t\t}\n\n\t\t\tme.min = labels[me.minIndex];\n\t\t\tme.max = labels[me.maxIndex];\n\t\t},\n\n\t\tbuildTicks: function() {\n\t\t\tvar me = this;\n\t\t\tvar labels = me.getLabels();\n\t\t\t// If we are viewing some subset of labels, slice the original array\n\t\t\tme.ticks = (me.minIndex === 0 && me.maxIndex === labels.length - 1) ? labels : labels.slice(me.minIndex, me.maxIndex + 1);\n\t\t},\n\n\t\tgetLabelForIndex: function(index, datasetIndex) {\n\t\t\tvar me = this;\n\t\t\tvar data = me.chart.data;\n\t\t\tvar isHorizontal = me.isHorizontal();\n\n\t\t\tif (data.yLabels && !isHorizontal) {\n\t\t\t\treturn me.getRightValue(data.datasets[datasetIndex].data[index]);\n\t\t\t}\n\t\t\treturn me.ticks[index - me.minIndex];\n\t\t},\n\n\t\t// Used to get data value locations.  Value can either be an index or a numerical value\n\t\tgetPixelForValue: function(value, index, datasetIndex, includeOffset) {\n\t\t\tvar me = this;\n\t\t\t// 1 is added because we need the length but we have the indexes\n\t\t\tvar offsetAmt = Math.max((me.maxIndex + 1 - me.minIndex - ((me.options.gridLines.offsetGridLines) ? 0 : 1)), 1);\n\n\t\t\t// If value is a data object, then index is the index in the data array,\n\t\t\t// not the index of the scale. We need to change that.\n\t\t\tvar valueCategory;\n\t\t\tif (value !== undefined && value !== null) {\n\t\t\t\tvalueCategory = me.isHorizontal() ? value.x : value.y;\n\t\t\t}\n\t\t\tif (valueCategory !== undefined || (value !== undefined && isNaN(index))) {\n\t\t\t\tvar labels = me.getLabels();\n\t\t\t\tvalue = valueCategory || value;\n\t\t\t\tvar idx = labels.indexOf(value);\n\t\t\t\tindex = idx !== -1 ? idx : index;\n\t\t\t}\n\n\t\t\tif (me.isHorizontal()) {\n\t\t\t\tvar valueWidth = me.width / offsetAmt;\n\t\t\t\tvar widthOffset = (valueWidth * (index - me.minIndex));\n\n\t\t\t\tif (me.options.gridLines.offsetGridLines && includeOffset || me.maxIndex === me.minIndex && includeOffset) {\n\t\t\t\t\twidthOffset += (valueWidth / 2);\n\t\t\t\t}\n\n\t\t\t\treturn me.left + Math.round(widthOffset);\n\t\t\t}\n\t\t\tvar valueHeight = me.height / offsetAmt;\n\t\t\tvar heightOffset = (valueHeight * (index - me.minIndex));\n\n\t\t\tif (me.options.gridLines.offsetGridLines && includeOffset) {\n\t\t\t\theightOffset += (valueHeight / 2);\n\t\t\t}\n\n\t\t\treturn me.top + Math.round(heightOffset);\n\t\t},\n\t\tgetPixelForTick: function(index, includeOffset) {\n\t\t\treturn this.getPixelForValue(this.ticks[index], index + this.minIndex, null, includeOffset);\n\t\t},\n\t\tgetValueForPixel: function(pixel) {\n\t\t\tvar me = this;\n\t\t\tvar value;\n\t\t\tvar offsetAmt = Math.max((me.ticks.length - ((me.options.gridLines.offsetGridLines) ? 0 : 1)), 1);\n\t\t\tvar horz = me.isHorizontal();\n\t\t\tvar valueDimension = (horz ? me.width : me.height) / offsetAmt;\n\n\t\t\tpixel -= horz ? me.left : me.top;\n\n\t\t\tif (me.options.gridLines.offsetGridLines) {\n\t\t\t\tpixel -= (valueDimension / 2);\n\t\t\t}\n\n\t\t\tif (pixel <= 0) {\n\t\t\t\tvalue = 0;\n\t\t\t} else {\n\t\t\t\tvalue = Math.round(pixel / valueDimension);\n\t\t\t}\n\n\t\t\treturn value;\n\t\t},\n\t\tgetBasePixel: function() {\n\t\t\treturn this.bottom;\n\t\t}\n\t});\n\n\tChart.scaleService.registerScaleType('category', DatasetScale, defaultConfig);\n\n};\n"
  },
  {
    "path": "app_backend/static/plugin/Chart.js-2.6.0/src/scales/scale.linear.js",
    "content": "'use strict';\n\nmodule.exports = function(Chart) {\n\n\tvar helpers = Chart.helpers;\n\n\tvar defaultConfig = {\n\t\tposition: 'left',\n\t\tticks: {\n\t\t\tcallback: Chart.Ticks.formatters.linear\n\t\t}\n\t};\n\n\tvar LinearScale = Chart.LinearScaleBase.extend({\n\n\t\tdetermineDataLimits: function() {\n\t\t\tvar me = this;\n\t\t\tvar opts = me.options;\n\t\t\tvar chart = me.chart;\n\t\t\tvar data = chart.data;\n\t\t\tvar datasets = data.datasets;\n\t\t\tvar isHorizontal = me.isHorizontal();\n\t\t\tvar DEFAULT_MIN = 0;\n\t\t\tvar DEFAULT_MAX = 1;\n\n\t\t\tfunction IDMatches(meta) {\n\t\t\t\treturn isHorizontal ? meta.xAxisID === me.id : meta.yAxisID === me.id;\n\t\t\t}\n\n\t\t\t// First Calculate the range\n\t\t\tme.min = null;\n\t\t\tme.max = null;\n\n\t\t\tvar hasStacks = opts.stacked;\n\t\t\tif (hasStacks === undefined) {\n\t\t\t\thelpers.each(datasets, function(dataset, datasetIndex) {\n\t\t\t\t\tif (hasStacks) {\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\n\t\t\t\t\tvar meta = chart.getDatasetMeta(datasetIndex);\n\t\t\t\t\tif (chart.isDatasetVisible(datasetIndex) && IDMatches(meta) &&\n\t\t\t\t\t\tmeta.stack !== undefined) {\n\t\t\t\t\t\thasStacks = true;\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t}\n\n\t\t\tif (opts.stacked || hasStacks) {\n\t\t\t\tvar valuesPerStack = {};\n\n\t\t\t\thelpers.each(datasets, function(dataset, datasetIndex) {\n\t\t\t\t\tvar meta = chart.getDatasetMeta(datasetIndex);\n\t\t\t\t\tvar key = [\n\t\t\t\t\t\tmeta.type,\n\t\t\t\t\t\t// we have a separate stack for stack=undefined datasets when the opts.stacked is undefined\n\t\t\t\t\t\t((opts.stacked === undefined && meta.stack === undefined) ? datasetIndex : ''),\n\t\t\t\t\t\tmeta.stack\n\t\t\t\t\t].join('.');\n\n\t\t\t\t\tif (valuesPerStack[key] === undefined) {\n\t\t\t\t\t\tvaluesPerStack[key] = {\n\t\t\t\t\t\t\tpositiveValues: [],\n\t\t\t\t\t\t\tnegativeValues: []\n\t\t\t\t\t\t};\n\t\t\t\t\t}\n\n\t\t\t\t\t// Store these per type\n\t\t\t\t\tvar positiveValues = valuesPerStack[key].positiveValues;\n\t\t\t\t\tvar negativeValues = valuesPerStack[key].negativeValues;\n\n\t\t\t\t\tif (chart.isDatasetVisible(datasetIndex) && IDMatches(meta)) {\n\t\t\t\t\t\thelpers.each(dataset.data, function(rawValue, index) {\n\t\t\t\t\t\t\tvar value = +me.getRightValue(rawValue);\n\t\t\t\t\t\t\tif (isNaN(value) || meta.data[index].hidden) {\n\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tpositiveValues[index] = positiveValues[index] || 0;\n\t\t\t\t\t\t\tnegativeValues[index] = negativeValues[index] || 0;\n\n\t\t\t\t\t\t\tif (opts.relativePoints) {\n\t\t\t\t\t\t\t\tpositiveValues[index] = 100;\n\t\t\t\t\t\t\t} else if (value < 0) {\n\t\t\t\t\t\t\t\tnegativeValues[index] += value;\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tpositiveValues[index] += value;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t});\n\n\t\t\t\thelpers.each(valuesPerStack, function(valuesForType) {\n\t\t\t\t\tvar values = valuesForType.positiveValues.concat(valuesForType.negativeValues);\n\t\t\t\t\tvar minVal = helpers.min(values);\n\t\t\t\t\tvar maxVal = helpers.max(values);\n\t\t\t\t\tme.min = me.min === null ? minVal : Math.min(me.min, minVal);\n\t\t\t\t\tme.max = me.max === null ? maxVal : Math.max(me.max, maxVal);\n\t\t\t\t});\n\n\t\t\t} else {\n\t\t\t\thelpers.each(datasets, function(dataset, datasetIndex) {\n\t\t\t\t\tvar meta = chart.getDatasetMeta(datasetIndex);\n\t\t\t\t\tif (chart.isDatasetVisible(datasetIndex) && IDMatches(meta)) {\n\t\t\t\t\t\thelpers.each(dataset.data, function(rawValue, index) {\n\t\t\t\t\t\t\tvar value = +me.getRightValue(rawValue);\n\t\t\t\t\t\t\tif (isNaN(value) || meta.data[index].hidden) {\n\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tif (me.min === null) {\n\t\t\t\t\t\t\t\tme.min = value;\n\t\t\t\t\t\t\t} else if (value < me.min) {\n\t\t\t\t\t\t\t\tme.min = value;\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tif (me.max === null) {\n\t\t\t\t\t\t\t\tme.max = value;\n\t\t\t\t\t\t\t} else if (value > me.max) {\n\t\t\t\t\t\t\t\tme.max = value;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t}\n\n\t\t\tme.min = isFinite(me.min) ? me.min : DEFAULT_MIN;\n\t\t\tme.max = isFinite(me.max) ? me.max : DEFAULT_MAX;\n\n\t\t\t// Common base implementation to handle ticks.min, ticks.max, ticks.beginAtZero\n\t\t\tthis.handleTickRangeOptions();\n\t\t},\n\t\tgetTickLimit: function() {\n\t\t\tvar maxTicks;\n\t\t\tvar me = this;\n\t\t\tvar tickOpts = me.options.ticks;\n\n\t\t\tif (me.isHorizontal()) {\n\t\t\t\tmaxTicks = Math.min(tickOpts.maxTicksLimit ? tickOpts.maxTicksLimit : 11, Math.ceil(me.width / 50));\n\t\t\t} else {\n\t\t\t\t// The factor of 2 used to scale the font size has been experimentally determined.\n\t\t\t\tvar tickFontSize = helpers.getValueOrDefault(tickOpts.fontSize, Chart.defaults.global.defaultFontSize);\n\t\t\t\tmaxTicks = Math.min(tickOpts.maxTicksLimit ? tickOpts.maxTicksLimit : 11, Math.ceil(me.height / (2 * tickFontSize)));\n\t\t\t}\n\n\t\t\treturn maxTicks;\n\t\t},\n\t\t// Called after the ticks are built. We need\n\t\thandleDirectionalChanges: function() {\n\t\t\tif (!this.isHorizontal()) {\n\t\t\t\t// We are in a vertical orientation. The top value is the highest. So reverse the array\n\t\t\t\tthis.ticks.reverse();\n\t\t\t}\n\t\t},\n\t\tgetLabelForIndex: function(index, datasetIndex) {\n\t\t\treturn +this.getRightValue(this.chart.data.datasets[datasetIndex].data[index]);\n\t\t},\n\t\t// Utils\n\t\tgetPixelForValue: function(value) {\n\t\t\t// This must be called after fit has been run so that\n\t\t\t// this.left, this.top, this.right, and this.bottom have been defined\n\t\t\tvar me = this;\n\t\t\tvar start = me.start;\n\n\t\t\tvar rightValue = +me.getRightValue(value);\n\t\t\tvar pixel;\n\t\t\tvar range = me.end - start;\n\n\t\t\tif (me.isHorizontal()) {\n\t\t\t\tpixel = me.left + (me.width / range * (rightValue - start));\n\t\t\t\treturn Math.round(pixel);\n\t\t\t}\n\n\t\t\tpixel = me.bottom - (me.height / range * (rightValue - start));\n\t\t\treturn Math.round(pixel);\n\t\t},\n\t\tgetValueForPixel: function(pixel) {\n\t\t\tvar me = this;\n\t\t\tvar isHorizontal = me.isHorizontal();\n\t\t\tvar innerDimension = isHorizontal ? me.width : me.height;\n\t\t\tvar offset = (isHorizontal ? pixel - me.left : me.bottom - pixel) / innerDimension;\n\t\t\treturn me.start + ((me.end - me.start) * offset);\n\t\t},\n\t\tgetPixelForTick: function(index) {\n\t\t\treturn this.getPixelForValue(this.ticksAsNumbers[index]);\n\t\t}\n\t});\n\tChart.scaleService.registerScaleType('linear', LinearScale, defaultConfig);\n\n};\n"
  },
  {
    "path": "app_backend/static/plugin/Chart.js-2.6.0/src/scales/scale.linearbase.js",
    "content": "'use strict';\n\nmodule.exports = function(Chart) {\n\n\tvar helpers = Chart.helpers,\n\t\tnoop = helpers.noop;\n\n\tChart.LinearScaleBase = Chart.Scale.extend({\n\t\thandleTickRangeOptions: function() {\n\t\t\tvar me = this;\n\t\t\tvar opts = me.options;\n\t\t\tvar tickOpts = opts.ticks;\n\n\t\t\t// If we are forcing it to begin at 0, but 0 will already be rendered on the chart,\n\t\t\t// do nothing since that would make the chart weird. If the user really wants a weird chart\n\t\t\t// axis, they can manually override it\n\t\t\tif (tickOpts.beginAtZero) {\n\t\t\t\tvar minSign = helpers.sign(me.min);\n\t\t\t\tvar maxSign = helpers.sign(me.max);\n\n\t\t\t\tif (minSign < 0 && maxSign < 0) {\n\t\t\t\t\t// move the top up to 0\n\t\t\t\t\tme.max = 0;\n\t\t\t\t} else if (minSign > 0 && maxSign > 0) {\n\t\t\t\t\t// move the bottom down to 0\n\t\t\t\t\tme.min = 0;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (tickOpts.min !== undefined) {\n\t\t\t\tme.min = tickOpts.min;\n\t\t\t} else if (tickOpts.suggestedMin !== undefined) {\n\t\t\t\tif (me.min === null) {\n\t\t\t\t\tme.min = tickOpts.suggestedMin;\n\t\t\t\t} else {\n\t\t\t\t\tme.min = Math.min(me.min, tickOpts.suggestedMin);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (tickOpts.max !== undefined) {\n\t\t\t\tme.max = tickOpts.max;\n\t\t\t} else if (tickOpts.suggestedMax !== undefined) {\n\t\t\t\tif (me.max === null) {\n\t\t\t\t\tme.max = tickOpts.suggestedMax;\n\t\t\t\t} else {\n\t\t\t\t\tme.max = Math.max(me.max, tickOpts.suggestedMax);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (me.min === me.max) {\n\t\t\t\tme.max++;\n\n\t\t\t\tif (!tickOpts.beginAtZero) {\n\t\t\t\t\tme.min--;\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\tgetTickLimit: noop,\n\t\thandleDirectionalChanges: noop,\n\n\t\tbuildTicks: function() {\n\t\t\tvar me = this;\n\t\t\tvar opts = me.options;\n\t\t\tvar tickOpts = opts.ticks;\n\n\t\t\t// Figure out what the max number of ticks we can support it is based on the size of\n\t\t\t// the axis area. For now, we say that the minimum tick spacing in pixels must be 50\n\t\t\t// We also limit the maximum number of ticks to 11 which gives a nice 10 squares on\n\t\t\t// the graph. Make sure we always have at least 2 ticks\n\t\t\tvar maxTicks = me.getTickLimit();\n\t\t\tmaxTicks = Math.max(2, maxTicks);\n\n\t\t\tvar numericGeneratorOptions = {\n\t\t\t\tmaxTicks: maxTicks,\n\t\t\t\tmin: tickOpts.min,\n\t\t\t\tmax: tickOpts.max,\n\t\t\t\tstepSize: helpers.getValueOrDefault(tickOpts.fixedStepSize, tickOpts.stepSize)\n\t\t\t};\n\t\t\tvar ticks = me.ticks = Chart.Ticks.generators.linear(numericGeneratorOptions, me);\n\n\t\t\tme.handleDirectionalChanges();\n\n\t\t\t// At this point, we need to update our max and min given the tick values since we have expanded the\n\t\t\t// range of the scale\n\t\t\tme.max = helpers.max(ticks);\n\t\t\tme.min = helpers.min(ticks);\n\n\t\t\tif (tickOpts.reverse) {\n\t\t\t\tticks.reverse();\n\n\t\t\t\tme.start = me.max;\n\t\t\t\tme.end = me.min;\n\t\t\t} else {\n\t\t\t\tme.start = me.min;\n\t\t\t\tme.end = me.max;\n\t\t\t}\n\t\t},\n\t\tconvertTicksToLabels: function() {\n\t\t\tvar me = this;\n\t\t\tme.ticksAsNumbers = me.ticks.slice();\n\t\t\tme.zeroLineIndex = me.ticks.indexOf(0);\n\n\t\t\tChart.Scale.prototype.convertTicksToLabels.call(me);\n\t\t}\n\t});\n};\n"
  },
  {
    "path": "app_backend/static/plugin/Chart.js-2.6.0/src/scales/scale.logarithmic.js",
    "content": "'use strict';\n\nmodule.exports = function(Chart) {\n\n\tvar helpers = Chart.helpers;\n\n\tvar defaultConfig = {\n\t\tposition: 'left',\n\n\t\t// label settings\n\t\tticks: {\n\t\t\tcallback: Chart.Ticks.formatters.logarithmic\n\t\t}\n\t};\n\n\tvar LogarithmicScale = Chart.Scale.extend({\n\t\tdetermineDataLimits: function() {\n\t\t\tvar me = this;\n\t\t\tvar opts = me.options;\n\t\t\tvar tickOpts = opts.ticks;\n\t\t\tvar chart = me.chart;\n\t\t\tvar data = chart.data;\n\t\t\tvar datasets = data.datasets;\n\t\t\tvar getValueOrDefault = helpers.getValueOrDefault;\n\t\t\tvar isHorizontal = me.isHorizontal();\n\t\t\tfunction IDMatches(meta) {\n\t\t\t\treturn isHorizontal ? meta.xAxisID === me.id : meta.yAxisID === me.id;\n\t\t\t}\n\n\t\t\t// Calculate Range\n\t\t\tme.min = null;\n\t\t\tme.max = null;\n\t\t\tme.minNotZero = null;\n\n\t\t\tvar hasStacks = opts.stacked;\n\t\t\tif (hasStacks === undefined) {\n\t\t\t\thelpers.each(datasets, function(dataset, datasetIndex) {\n\t\t\t\t\tif (hasStacks) {\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\n\t\t\t\t\tvar meta = chart.getDatasetMeta(datasetIndex);\n\t\t\t\t\tif (chart.isDatasetVisible(datasetIndex) && IDMatches(meta) &&\n\t\t\t\t\t\tmeta.stack !== undefined) {\n\t\t\t\t\t\thasStacks = true;\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t}\n\n\t\t\tif (opts.stacked || hasStacks) {\n\t\t\t\tvar valuesPerStack = {};\n\n\t\t\t\thelpers.each(datasets, function(dataset, datasetIndex) {\n\t\t\t\t\tvar meta = chart.getDatasetMeta(datasetIndex);\n\t\t\t\t\tvar key = [\n\t\t\t\t\t\tmeta.type,\n\t\t\t\t\t\t// we have a separate stack for stack=undefined datasets when the opts.stacked is undefined\n\t\t\t\t\t\t((opts.stacked === undefined && meta.stack === undefined) ? datasetIndex : ''),\n\t\t\t\t\t\tmeta.stack\n\t\t\t\t\t].join('.');\n\n\t\t\t\t\tif (chart.isDatasetVisible(datasetIndex) && IDMatches(meta)) {\n\t\t\t\t\t\tif (valuesPerStack[key] === undefined) {\n\t\t\t\t\t\t\tvaluesPerStack[key] = [];\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\thelpers.each(dataset.data, function(rawValue, index) {\n\t\t\t\t\t\t\tvar values = valuesPerStack[key];\n\t\t\t\t\t\t\tvar value = +me.getRightValue(rawValue);\n\t\t\t\t\t\t\tif (isNaN(value) || meta.data[index].hidden) {\n\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tvalues[index] = values[index] || 0;\n\n\t\t\t\t\t\t\tif (opts.relativePoints) {\n\t\t\t\t\t\t\t\tvalues[index] = 100;\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t// Don't need to split positive and negative since the log scale can't handle a 0 crossing\n\t\t\t\t\t\t\t\tvalues[index] += value;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t});\n\n\t\t\t\thelpers.each(valuesPerStack, function(valuesForType) {\n\t\t\t\t\tvar minVal = helpers.min(valuesForType);\n\t\t\t\t\tvar maxVal = helpers.max(valuesForType);\n\t\t\t\t\tme.min = me.min === null ? minVal : Math.min(me.min, minVal);\n\t\t\t\t\tme.max = me.max === null ? maxVal : Math.max(me.max, maxVal);\n\t\t\t\t});\n\n\t\t\t} else {\n\t\t\t\thelpers.each(datasets, function(dataset, datasetIndex) {\n\t\t\t\t\tvar meta = chart.getDatasetMeta(datasetIndex);\n\t\t\t\t\tif (chart.isDatasetVisible(datasetIndex) && IDMatches(meta)) {\n\t\t\t\t\t\thelpers.each(dataset.data, function(rawValue, index) {\n\t\t\t\t\t\t\tvar value = +me.getRightValue(rawValue);\n\t\t\t\t\t\t\tif (isNaN(value) || meta.data[index].hidden) {\n\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tif (me.min === null) {\n\t\t\t\t\t\t\t\tme.min = value;\n\t\t\t\t\t\t\t} else if (value < me.min) {\n\t\t\t\t\t\t\t\tme.min = value;\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tif (me.max === null) {\n\t\t\t\t\t\t\t\tme.max = value;\n\t\t\t\t\t\t\t} else if (value > me.max) {\n\t\t\t\t\t\t\t\tme.max = value;\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tif (value !== 0 && (me.minNotZero === null || value < me.minNotZero)) {\n\t\t\t\t\t\t\t\tme.minNotZero = value;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t}\n\n\t\t\tme.min = getValueOrDefault(tickOpts.min, me.min);\n\t\t\tme.max = getValueOrDefault(tickOpts.max, me.max);\n\n\t\t\tif (me.min === me.max) {\n\t\t\t\tif (me.min !== 0 && me.min !== null) {\n\t\t\t\t\tme.min = Math.pow(10, Math.floor(helpers.log10(me.min)) - 1);\n\t\t\t\t\tme.max = Math.pow(10, Math.floor(helpers.log10(me.max)) + 1);\n\t\t\t\t} else {\n\t\t\t\t\tme.min = 1;\n\t\t\t\t\tme.max = 10;\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\tbuildTicks: function() {\n\t\t\tvar me = this;\n\t\t\tvar opts = me.options;\n\t\t\tvar tickOpts = opts.ticks;\n\n\t\t\tvar generationOptions = {\n\t\t\t\tmin: tickOpts.min,\n\t\t\t\tmax: tickOpts.max\n\t\t\t};\n\t\t\tvar ticks = me.ticks = Chart.Ticks.generators.logarithmic(generationOptions, me);\n\n\t\t\tif (!me.isHorizontal()) {\n\t\t\t\t// We are in a vertical orientation. The top value is the highest. So reverse the array\n\t\t\t\tticks.reverse();\n\t\t\t}\n\n\t\t\t// At this point, we need to update our max and min given the tick values since we have expanded the\n\t\t\t// range of the scale\n\t\t\tme.max = helpers.max(ticks);\n\t\t\tme.min = helpers.min(ticks);\n\n\t\t\tif (tickOpts.reverse) {\n\t\t\t\tticks.reverse();\n\n\t\t\t\tme.start = me.max;\n\t\t\t\tme.end = me.min;\n\t\t\t} else {\n\t\t\t\tme.start = me.min;\n\t\t\t\tme.end = me.max;\n\t\t\t}\n\t\t},\n\t\tconvertTicksToLabels: function() {\n\t\t\tthis.tickValues = this.ticks.slice();\n\n\t\t\tChart.Scale.prototype.convertTicksToLabels.call(this);\n\t\t},\n\t\t// Get the correct tooltip label\n\t\tgetLabelForIndex: function(index, datasetIndex) {\n\t\t\treturn +this.getRightValue(this.chart.data.datasets[datasetIndex].data[index]);\n\t\t},\n\t\tgetPixelForTick: function(index) {\n\t\t\treturn this.getPixelForValue(this.tickValues[index]);\n\t\t},\n\t\tgetPixelForValue: function(value) {\n\t\t\tvar me = this;\n\t\t\tvar innerDimension;\n\t\t\tvar pixel;\n\n\t\t\tvar start = me.start;\n\t\t\tvar newVal = +me.getRightValue(value);\n\t\t\tvar range;\n\t\t\tvar opts = me.options;\n\t\t\tvar tickOpts = opts.ticks;\n\n\t\t\tif (me.isHorizontal()) {\n\t\t\t\trange = helpers.log10(me.end) - helpers.log10(start); // todo: if start === 0\n\t\t\t\tif (newVal === 0) {\n\t\t\t\t\tpixel = me.left;\n\t\t\t\t} else {\n\t\t\t\t\tinnerDimension = me.width;\n\t\t\t\t\tpixel = me.left + (innerDimension / range * (helpers.log10(newVal) - helpers.log10(start)));\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t// Bottom - top since pixels increase downward on a screen\n\t\t\t\tinnerDimension = me.height;\n\t\t\t\tif (start === 0 && !tickOpts.reverse) {\n\t\t\t\t\trange = helpers.log10(me.end) - helpers.log10(me.minNotZero);\n\t\t\t\t\tif (newVal === start) {\n\t\t\t\t\t\tpixel = me.bottom;\n\t\t\t\t\t} else if (newVal === me.minNotZero) {\n\t\t\t\t\t\tpixel = me.bottom - innerDimension * 0.02;\n\t\t\t\t\t} else {\n\t\t\t\t\t\tpixel = me.bottom - innerDimension * 0.02 - (innerDimension * 0.98/ range * (helpers.log10(newVal)-helpers.log10(me.minNotZero)));\n\t\t\t\t\t}\n\t\t\t\t} else if (me.end === 0 && tickOpts.reverse) {\n\t\t\t\t\trange = helpers.log10(me.start) - helpers.log10(me.minNotZero);\n\t\t\t\t\tif (newVal === me.end) {\n\t\t\t\t\t\tpixel = me.top;\n\t\t\t\t\t} else if (newVal === me.minNotZero) {\n\t\t\t\t\t\tpixel = me.top + innerDimension * 0.02;\n\t\t\t\t\t} else {\n\t\t\t\t\t\tpixel = me.top + innerDimension * 0.02 + (innerDimension * 0.98/ range * (helpers.log10(newVal)-helpers.log10(me.minNotZero)));\n\t\t\t\t\t}\n\t\t\t\t} else if (newVal === 0) {\n\t\t\t\t\tpixel = tickOpts.reverse ? me.top : me.bottom;\n\t\t\t\t} else {\n\t\t\t\t\trange = helpers.log10(me.end) - helpers.log10(start);\n\t\t\t\t\tinnerDimension = me.height;\n\t\t\t\t\tpixel = me.bottom - (innerDimension / range * (helpers.log10(newVal) - helpers.log10(start)));\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn pixel;\n\t\t},\n\t\tgetValueForPixel: function(pixel) {\n\t\t\tvar me = this;\n\t\t\tvar range = helpers.log10(me.end) - helpers.log10(me.start);\n\t\t\tvar value, innerDimension;\n\n\t\t\tif (me.isHorizontal()) {\n\t\t\t\tinnerDimension = me.width;\n\t\t\t\tvalue = me.start * Math.pow(10, (pixel - me.left) * range / innerDimension);\n\t\t\t} else {  // todo: if start === 0\n\t\t\t\tinnerDimension = me.height;\n\t\t\t\tvalue = Math.pow(10, (me.bottom - pixel) * range / innerDimension) / me.start;\n\t\t\t}\n\t\t\treturn value;\n\t\t}\n\t});\n\tChart.scaleService.registerScaleType('logarithmic', LogarithmicScale, defaultConfig);\n\n};\n"
  },
  {
    "path": "app_backend/static/plugin/Chart.js-2.6.0/src/scales/scale.radialLinear.js",
    "content": "'use strict';\n\nmodule.exports = function(Chart) {\n\n\tvar helpers = Chart.helpers;\n\tvar globalDefaults = Chart.defaults.global;\n\n\tvar defaultConfig = {\n\t\tdisplay: true,\n\n\t\t// Boolean - Whether to animate scaling the chart from the centre\n\t\tanimate: true,\n\t\tposition: 'chartArea',\n\n\t\tangleLines: {\n\t\t\tdisplay: true,\n\t\t\tcolor: 'rgba(0, 0, 0, 0.1)',\n\t\t\tlineWidth: 1\n\t\t},\n\n\t\tgridLines: {\n\t\t\tcircular: false\n\t\t},\n\n\t\t// label settings\n\t\tticks: {\n\t\t\t// Boolean - Show a backdrop to the scale label\n\t\t\tshowLabelBackdrop: true,\n\n\t\t\t// String - The colour of the label backdrop\n\t\t\tbackdropColor: 'rgba(255,255,255,0.75)',\n\n\t\t\t// Number - The backdrop padding above & below the label in pixels\n\t\t\tbackdropPaddingY: 2,\n\n\t\t\t// Number - The backdrop padding to the side of the label in pixels\n\t\t\tbackdropPaddingX: 2,\n\n\t\t\tcallback: Chart.Ticks.formatters.linear\n\t\t},\n\n\t\tpointLabels: {\n\t\t\t// Boolean - if true, show point labels\n\t\t\tdisplay: true,\n\n\t\t\t// Number - Point label font size in pixels\n\t\t\tfontSize: 10,\n\n\t\t\t// Function - Used to convert point labels\n\t\t\tcallback: function(label) {\n\t\t\t\treturn label;\n\t\t\t}\n\t\t}\n\t};\n\n\tfunction getValueCount(scale) {\n\t\tvar opts = scale.options;\n\t\treturn opts.angleLines.display || opts.pointLabels.display ? scale.chart.data.labels.length : 0;\n\t}\n\n\tfunction getPointLabelFontOptions(scale) {\n\t\tvar pointLabelOptions = scale.options.pointLabels;\n\t\tvar fontSize = helpers.getValueOrDefault(pointLabelOptions.fontSize, globalDefaults.defaultFontSize);\n\t\tvar fontStyle = helpers.getValueOrDefault(pointLabelOptions.fontStyle, globalDefaults.defaultFontStyle);\n\t\tvar fontFamily = helpers.getValueOrDefault(pointLabelOptions.fontFamily, globalDefaults.defaultFontFamily);\n\t\tvar font = helpers.fontString(fontSize, fontStyle, fontFamily);\n\n\t\treturn {\n\t\t\tsize: fontSize,\n\t\t\tstyle: fontStyle,\n\t\t\tfamily: fontFamily,\n\t\t\tfont: font\n\t\t};\n\t}\n\n\tfunction measureLabelSize(ctx, fontSize, label) {\n\t\tif (helpers.isArray(label)) {\n\t\t\treturn {\n\t\t\t\tw: helpers.longestText(ctx, ctx.font, label),\n\t\t\t\th: (label.length * fontSize) + ((label.length - 1) * 1.5 * fontSize)\n\t\t\t};\n\t\t}\n\n\t\treturn {\n\t\t\tw: ctx.measureText(label).width,\n\t\t\th: fontSize\n\t\t};\n\t}\n\n\tfunction determineLimits(angle, pos, size, min, max) {\n\t\tif (angle === min || angle === max) {\n\t\t\treturn {\n\t\t\t\tstart: pos - (size / 2),\n\t\t\t\tend: pos + (size / 2)\n\t\t\t};\n\t\t} else if (angle < min || angle > max) {\n\t\t\treturn {\n\t\t\t\tstart: pos - size - 5,\n\t\t\t\tend: pos\n\t\t\t};\n\t\t}\n\n\t\treturn {\n\t\t\tstart: pos,\n\t\t\tend: pos + size + 5\n\t\t};\n\t}\n\n\t/**\n\t * Helper function to fit a radial linear scale with point labels\n\t */\n\tfunction fitWithPointLabels(scale) {\n\t\t/*\n\t\t * Right, this is really confusing and there is a lot of maths going on here\n\t\t * The gist of the problem is here: https://gist.github.com/nnnick/696cc9c55f4b0beb8fe9\n\t\t *\n\t\t * Reaction: https://dl.dropboxusercontent.com/u/34601363/toomuchscience.gif\n\t\t *\n\t\t * Solution:\n\t\t *\n\t\t * We assume the radius of the polygon is half the size of the canvas at first\n\t\t * at each index we check if the text overlaps.\n\t\t *\n\t\t * Where it does, we store that angle and that index.\n\t\t *\n\t\t * After finding the largest index and angle we calculate how much we need to remove\n\t\t * from the shape radius to move the point inwards by that x.\n\t\t *\n\t\t * We average the left and right distances to get the maximum shape radius that can fit in the box\n\t\t * along with labels.\n\t\t *\n\t\t * Once we have that, we can find the centre point for the chart, by taking the x text protrusion\n\t\t * on each side, removing that from the size, halving it and adding the left x protrusion width.\n\t\t *\n\t\t * This will mean we have a shape fitted to the canvas, as large as it can be with the labels\n\t\t * and position it in the most space efficient manner\n\t\t *\n\t\t * https://dl.dropboxusercontent.com/u/34601363/yeahscience.gif\n\t\t */\n\n\t\tvar plFont = getPointLabelFontOptions(scale);\n\n\t\t// Get maximum radius of the polygon. Either half the height (minus the text width) or half the width.\n\t\t// Use this to calculate the offset + change. - Make sure L/R protrusion is at least 0 to stop issues with centre points\n\t\tvar largestPossibleRadius = Math.min(scale.height / 2, scale.width / 2);\n\t\tvar furthestLimits = {\n\t\t\tr: scale.width,\n\t\t\tl: 0,\n\t\t\tt: scale.height,\n\t\t\tb: 0\n\t\t};\n\t\tvar furthestAngles = {};\n\t\tvar i;\n\t\tvar textSize;\n\t\tvar pointPosition;\n\n\t\tscale.ctx.font = plFont.font;\n\t\tscale._pointLabelSizes = [];\n\n\t\tvar valueCount = getValueCount(scale);\n\t\tfor (i = 0; i < valueCount; i++) {\n\t\t\tpointPosition = scale.getPointPosition(i, largestPossibleRadius);\n\t\t\ttextSize = measureLabelSize(scale.ctx, plFont.size, scale.pointLabels[i] || '');\n\t\t\tscale._pointLabelSizes[i] = textSize;\n\n\t\t\t// Add quarter circle to make degree 0 mean top of circle\n\t\t\tvar angleRadians = scale.getIndexAngle(i);\n\t\t\tvar angle = helpers.toDegrees(angleRadians) % 360;\n\t\t\tvar hLimits = determineLimits(angle, pointPosition.x, textSize.w, 0, 180);\n\t\t\tvar vLimits = determineLimits(angle, pointPosition.y, textSize.h, 90, 270);\n\n\t\t\tif (hLimits.start < furthestLimits.l) {\n\t\t\t\tfurthestLimits.l = hLimits.start;\n\t\t\t\tfurthestAngles.l = angleRadians;\n\t\t\t}\n\n\t\t\tif (hLimits.end > furthestLimits.r) {\n\t\t\t\tfurthestLimits.r = hLimits.end;\n\t\t\t\tfurthestAngles.r = angleRadians;\n\t\t\t}\n\n\t\t\tif (vLimits.start < furthestLimits.t) {\n\t\t\t\tfurthestLimits.t = vLimits.start;\n\t\t\t\tfurthestAngles.t = angleRadians;\n\t\t\t}\n\n\t\t\tif (vLimits.end > furthestLimits.b) {\n\t\t\t\tfurthestLimits.b = vLimits.end;\n\t\t\t\tfurthestAngles.b = angleRadians;\n\t\t\t}\n\t\t}\n\n\t\tscale.setReductions(largestPossibleRadius, furthestLimits, furthestAngles);\n\t}\n\n\t/**\n\t * Helper function to fit a radial linear scale with no point labels\n\t */\n\tfunction fit(scale) {\n\t\tvar largestPossibleRadius = Math.min(scale.height / 2, scale.width / 2);\n\t\tscale.drawingArea = Math.round(largestPossibleRadius);\n\t\tscale.setCenterPoint(0, 0, 0, 0);\n\t}\n\n\tfunction getTextAlignForAngle(angle) {\n\t\tif (angle === 0 || angle === 180) {\n\t\t\treturn 'center';\n\t\t} else if (angle < 180) {\n\t\t\treturn 'left';\n\t\t}\n\n\t\treturn 'right';\n\t}\n\n\tfunction fillText(ctx, text, position, fontSize) {\n\t\tif (helpers.isArray(text)) {\n\t\t\tvar y = position.y;\n\t\t\tvar spacing = 1.5 * fontSize;\n\n\t\t\tfor (var i = 0; i < text.length; ++i) {\n\t\t\t\tctx.fillText(text[i], position.x, y);\n\t\t\t\ty+= spacing;\n\t\t\t}\n\t\t} else {\n\t\t\tctx.fillText(text, position.x, position.y);\n\t\t}\n\t}\n\n\tfunction adjustPointPositionForLabelHeight(angle, textSize, position) {\n\t\tif (angle === 90 || angle === 270) {\n\t\t\tposition.y -= (textSize.h / 2);\n\t\t} else if (angle > 270 || angle < 90) {\n\t\t\tposition.y -= textSize.h;\n\t\t}\n\t}\n\n\tfunction drawPointLabels(scale) {\n\t\tvar ctx = scale.ctx;\n\t\tvar getValueOrDefault = helpers.getValueOrDefault;\n\t\tvar opts = scale.options;\n\t\tvar angleLineOpts = opts.angleLines;\n\t\tvar pointLabelOpts = opts.pointLabels;\n\n\t\tctx.lineWidth = angleLineOpts.lineWidth;\n\t\tctx.strokeStyle = angleLineOpts.color;\n\n\t\tvar outerDistance = scale.getDistanceFromCenterForValue(opts.reverse ? scale.min : scale.max);\n\n\t\t// Point Label Font\n\t\tvar plFont = getPointLabelFontOptions(scale);\n\n\t\tctx.textBaseline = 'top';\n\n\t\tfor (var i = getValueCount(scale) - 1; i >= 0; i--) {\n\t\t\tif (angleLineOpts.display) {\n\t\t\t\tvar outerPosition = scale.getPointPosition(i, outerDistance);\n\t\t\t\tctx.beginPath();\n\t\t\t\tctx.moveTo(scale.xCenter, scale.yCenter);\n\t\t\t\tctx.lineTo(outerPosition.x, outerPosition.y);\n\t\t\t\tctx.stroke();\n\t\t\t\tctx.closePath();\n\t\t\t}\n\n\t\t\tif (pointLabelOpts.display) {\n\t\t\t\t// Extra 3px out for some label spacing\n\t\t\t\tvar pointLabelPosition = scale.getPointPosition(i, outerDistance + 5);\n\n\t\t\t\t// Keep this in loop since we may support array properties here\n\t\t\t\tvar pointLabelFontColor = getValueOrDefault(pointLabelOpts.fontColor, globalDefaults.defaultFontColor);\n\t\t\t\tctx.font = plFont.font;\n\t\t\t\tctx.fillStyle = pointLabelFontColor;\n\n\t\t\t\tvar angleRadians = scale.getIndexAngle(i);\n\t\t\t\tvar angle = helpers.toDegrees(angleRadians);\n\t\t\t\tctx.textAlign = getTextAlignForAngle(angle);\n\t\t\t\tadjustPointPositionForLabelHeight(angle, scale._pointLabelSizes[i], pointLabelPosition);\n\t\t\t\tfillText(ctx, scale.pointLabels[i] || '', pointLabelPosition, plFont.size);\n\t\t\t}\n\t\t}\n\t}\n\n\tfunction drawRadiusLine(scale, gridLineOpts, radius, index) {\n\t\tvar ctx = scale.ctx;\n\t\tctx.strokeStyle = helpers.getValueAtIndexOrDefault(gridLineOpts.color, index - 1);\n\t\tctx.lineWidth = helpers.getValueAtIndexOrDefault(gridLineOpts.lineWidth, index - 1);\n\n\t\tif (scale.options.gridLines.circular) {\n\t\t\t// Draw circular arcs between the points\n\t\t\tctx.beginPath();\n\t\t\tctx.arc(scale.xCenter, scale.yCenter, radius, 0, Math.PI * 2);\n\t\t\tctx.closePath();\n\t\t\tctx.stroke();\n\t\t} else {\n\t\t\t// Draw straight lines connecting each index\n\t\t\tvar valueCount = getValueCount(scale);\n\n\t\t\tif (valueCount === 0) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tctx.beginPath();\n\t\t\tvar pointPosition = scale.getPointPosition(0, radius);\n\t\t\tctx.moveTo(pointPosition.x, pointPosition.y);\n\n\t\t\tfor (var i = 1; i < valueCount; i++) {\n\t\t\t\tpointPosition = scale.getPointPosition(i, radius);\n\t\t\t\tctx.lineTo(pointPosition.x, pointPosition.y);\n\t\t\t}\n\n\t\t\tctx.closePath();\n\t\t\tctx.stroke();\n\t\t}\n\t}\n\n\tfunction numberOrZero(param) {\n\t\treturn helpers.isNumber(param) ? param : 0;\n\t}\n\n\tvar LinearRadialScale = Chart.LinearScaleBase.extend({\n\t\tsetDimensions: function() {\n\t\t\tvar me = this;\n\t\t\tvar opts = me.options;\n\t\t\tvar tickOpts = opts.ticks;\n\t\t\t// Set the unconstrained dimension before label rotation\n\t\t\tme.width = me.maxWidth;\n\t\t\tme.height = me.maxHeight;\n\t\t\tme.xCenter = Math.round(me.width / 2);\n\t\t\tme.yCenter = Math.round(me.height / 2);\n\n\t\t\tvar minSize = helpers.min([me.height, me.width]);\n\t\t\tvar tickFontSize = helpers.getValueOrDefault(tickOpts.fontSize, globalDefaults.defaultFontSize);\n\t\t\tme.drawingArea = opts.display ? (minSize / 2) - (tickFontSize / 2 + tickOpts.backdropPaddingY) : (minSize / 2);\n\t\t},\n\t\tdetermineDataLimits: function() {\n\t\t\tvar me = this;\n\t\t\tvar chart = me.chart;\n\t\t\tvar min = Number.POSITIVE_INFINITY;\n\t\t\tvar max = Number.NEGATIVE_INFINITY;\n\n\t\t\thelpers.each(chart.data.datasets, function(dataset, datasetIndex) {\n\t\t\t\tif (chart.isDatasetVisible(datasetIndex)) {\n\t\t\t\t\tvar meta = chart.getDatasetMeta(datasetIndex);\n\n\t\t\t\t\thelpers.each(dataset.data, function(rawValue, index) {\n\t\t\t\t\t\tvar value = +me.getRightValue(rawValue);\n\t\t\t\t\t\tif (isNaN(value) || meta.data[index].hidden) {\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tmin = Math.min(value, min);\n\t\t\t\t\t\tmax = Math.max(value, max);\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t});\n\n\t\t\tme.min = (min === Number.POSITIVE_INFINITY ? 0 : min);\n\t\t\tme.max = (max === Number.NEGATIVE_INFINITY ? 0 : max);\n\n\t\t\t// Common base implementation to handle ticks.min, ticks.max, ticks.beginAtZero\n\t\t\tme.handleTickRangeOptions();\n\t\t},\n\t\tgetTickLimit: function() {\n\t\t\tvar tickOpts = this.options.ticks;\n\t\t\tvar tickFontSize = helpers.getValueOrDefault(tickOpts.fontSize, globalDefaults.defaultFontSize);\n\t\t\treturn Math.min(tickOpts.maxTicksLimit ? tickOpts.maxTicksLimit : 11, Math.ceil(this.drawingArea / (1.5 * tickFontSize)));\n\t\t},\n\t\tconvertTicksToLabels: function() {\n\t\t\tvar me = this;\n\t\t\tChart.LinearScaleBase.prototype.convertTicksToLabels.call(me);\n\n\t\t\t// Point labels\n\t\t\tme.pointLabels = me.chart.data.labels.map(me.options.pointLabels.callback, me);\n\t\t},\n\t\tgetLabelForIndex: function(index, datasetIndex) {\n\t\t\treturn +this.getRightValue(this.chart.data.datasets[datasetIndex].data[index]);\n\t\t},\n\t\tfit: function() {\n\t\t\tif (this.options.pointLabels.display) {\n\t\t\t\tfitWithPointLabels(this);\n\t\t\t} else {\n\t\t\t\tfit(this);\n\t\t\t}\n\t\t},\n\t\t/**\n\t\t * Set radius reductions and determine new radius and center point\n\t\t * @private\n\t\t */\n\t\tsetReductions: function(largestPossibleRadius, furthestLimits, furthestAngles) {\n\t\t\tvar me = this;\n\t\t\tvar radiusReductionLeft = furthestLimits.l / Math.sin(furthestAngles.l);\n\t\t\tvar radiusReductionRight = Math.max(furthestLimits.r - me.width, 0) / Math.sin(furthestAngles.r);\n\t\t\tvar radiusReductionTop = -furthestLimits.t / Math.cos(furthestAngles.t);\n\t\t\tvar radiusReductionBottom = -Math.max(furthestLimits.b - me.height, 0) / Math.cos(furthestAngles.b);\n\n\t\t\tradiusReductionLeft = numberOrZero(radiusReductionLeft);\n\t\t\tradiusReductionRight = numberOrZero(radiusReductionRight);\n\t\t\tradiusReductionTop = numberOrZero(radiusReductionTop);\n\t\t\tradiusReductionBottom = numberOrZero(radiusReductionBottom);\n\n\t\t\tme.drawingArea = Math.min(\n\t\t\t\tMath.round(largestPossibleRadius - (radiusReductionLeft + radiusReductionRight) / 2),\n\t\t\t\tMath.round(largestPossibleRadius - (radiusReductionTop + radiusReductionBottom) / 2));\n\t\t\tme.setCenterPoint(radiusReductionLeft, radiusReductionRight, radiusReductionTop, radiusReductionBottom);\n\t\t},\n\t\tsetCenterPoint: function(leftMovement, rightMovement, topMovement, bottomMovement) {\n\t\t\tvar me = this;\n\t\t\tvar maxRight = me.width - rightMovement - me.drawingArea,\n\t\t\t\tmaxLeft = leftMovement + me.drawingArea,\n\t\t\t\tmaxTop = topMovement + me.drawingArea,\n\t\t\t\tmaxBottom = me.height - bottomMovement - me.drawingArea;\n\n\t\t\tme.xCenter = Math.round(((maxLeft + maxRight) / 2) + me.left);\n\t\t\tme.yCenter = Math.round(((maxTop + maxBottom) / 2) + me.top);\n\t\t},\n\n\t\tgetIndexAngle: function(index) {\n\t\t\tvar angleMultiplier = (Math.PI * 2) / getValueCount(this);\n\t\t\tvar startAngle = this.chart.options && this.chart.options.startAngle ?\n\t\t\t\tthis.chart.options.startAngle :\n\t\t\t\t0;\n\n\t\t\tvar startAngleRadians = startAngle * Math.PI * 2 / 360;\n\n\t\t\t// Start from the top instead of right, so remove a quarter of the circle\n\t\t\treturn index * angleMultiplier + startAngleRadians;\n\t\t},\n\t\tgetDistanceFromCenterForValue: function(value) {\n\t\t\tvar me = this;\n\n\t\t\tif (value === null) {\n\t\t\t\treturn 0; // null always in center\n\t\t\t}\n\n\t\t\t// Take into account half font size + the yPadding of the top value\n\t\t\tvar scalingFactor = me.drawingArea / (me.max - me.min);\n\t\t\tif (me.options.reverse) {\n\t\t\t\treturn (me.max - value) * scalingFactor;\n\t\t\t}\n\t\t\treturn (value - me.min) * scalingFactor;\n\t\t},\n\t\tgetPointPosition: function(index, distanceFromCenter) {\n\t\t\tvar me = this;\n\t\t\tvar thisAngle = me.getIndexAngle(index) - (Math.PI / 2);\n\t\t\treturn {\n\t\t\t\tx: Math.round(Math.cos(thisAngle) * distanceFromCenter) + me.xCenter,\n\t\t\t\ty: Math.round(Math.sin(thisAngle) * distanceFromCenter) + me.yCenter\n\t\t\t};\n\t\t},\n\t\tgetPointPositionForValue: function(index, value) {\n\t\t\treturn this.getPointPosition(index, this.getDistanceFromCenterForValue(value));\n\t\t},\n\n\t\tgetBasePosition: function() {\n\t\t\tvar me = this;\n\t\t\tvar min = me.min;\n\t\t\tvar max = me.max;\n\n\t\t\treturn me.getPointPositionForValue(0,\n\t\t\t\tme.beginAtZero? 0:\n\t\t\t\tmin < 0 && max < 0? max :\n\t\t\t\tmin > 0 && max > 0? min :\n\t\t\t\t0);\n\t\t},\n\n\t\tdraw: function() {\n\t\t\tvar me = this;\n\t\t\tvar opts = me.options;\n\t\t\tvar gridLineOpts = opts.gridLines;\n\t\t\tvar tickOpts = opts.ticks;\n\t\t\tvar getValueOrDefault = helpers.getValueOrDefault;\n\n\t\t\tif (opts.display) {\n\t\t\t\tvar ctx = me.ctx;\n\n\t\t\t\t// Tick Font\n\t\t\t\tvar tickFontSize = getValueOrDefault(tickOpts.fontSize, globalDefaults.defaultFontSize);\n\t\t\t\tvar tickFontStyle = getValueOrDefault(tickOpts.fontStyle, globalDefaults.defaultFontStyle);\n\t\t\t\tvar tickFontFamily = getValueOrDefault(tickOpts.fontFamily, globalDefaults.defaultFontFamily);\n\t\t\t\tvar tickLabelFont = helpers.fontString(tickFontSize, tickFontStyle, tickFontFamily);\n\n\t\t\t\thelpers.each(me.ticks, function(label, index) {\n\t\t\t\t\t// Don't draw a centre value (if it is minimum)\n\t\t\t\t\tif (index > 0 || opts.reverse) {\n\t\t\t\t\t\tvar yCenterOffset = me.getDistanceFromCenterForValue(me.ticksAsNumbers[index]);\n\t\t\t\t\t\tvar yHeight = me.yCenter - yCenterOffset;\n\n\t\t\t\t\t\t// Draw circular lines around the scale\n\t\t\t\t\t\tif (gridLineOpts.display && index !== 0) {\n\t\t\t\t\t\t\tdrawRadiusLine(me, gridLineOpts, yCenterOffset, index);\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif (tickOpts.display) {\n\t\t\t\t\t\t\tvar tickFontColor = getValueOrDefault(tickOpts.fontColor, globalDefaults.defaultFontColor);\n\t\t\t\t\t\t\tctx.font = tickLabelFont;\n\n\t\t\t\t\t\t\tif (tickOpts.showLabelBackdrop) {\n\t\t\t\t\t\t\t\tvar labelWidth = ctx.measureText(label).width;\n\t\t\t\t\t\t\t\tctx.fillStyle = tickOpts.backdropColor;\n\t\t\t\t\t\t\t\tctx.fillRect(\n\t\t\t\t\t\t\t\t\tme.xCenter - labelWidth / 2 - tickOpts.backdropPaddingX,\n\t\t\t\t\t\t\t\t\tyHeight - tickFontSize / 2 - tickOpts.backdropPaddingY,\n\t\t\t\t\t\t\t\t\tlabelWidth + tickOpts.backdropPaddingX * 2,\n\t\t\t\t\t\t\t\t\ttickFontSize + tickOpts.backdropPaddingY * 2\n\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tctx.textAlign = 'center';\n\t\t\t\t\t\t\tctx.textBaseline = 'middle';\n\t\t\t\t\t\t\tctx.fillStyle = tickFontColor;\n\t\t\t\t\t\t\tctx.fillText(label, me.xCenter, yHeight);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t});\n\n\t\t\t\tif (opts.angleLines.display || opts.pointLabels.display) {\n\t\t\t\t\tdrawPointLabels(me);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t});\n\tChart.scaleService.registerScaleType('radialLinear', LinearRadialScale, defaultConfig);\n\n};\n"
  },
  {
    "path": "app_backend/static/plugin/Chart.js-2.6.0/src/scales/scale.time.js",
    "content": "/* global window: false */\n'use strict';\n\nvar moment = require('moment');\nmoment = typeof(moment) === 'function' ? moment : window.moment;\n\nmodule.exports = function(Chart) {\n\n\tvar helpers = Chart.helpers;\n\tvar interval = {\n\t\tmillisecond: {\n\t\t\tsize: 1,\n\t\t\tsteps: [1, 2, 5, 10, 20, 50, 100, 250, 500]\n\t\t},\n\t\tsecond: {\n\t\t\tsize: 1000,\n\t\t\tsteps: [1, 2, 5, 10, 30]\n\t\t},\n\t\tminute: {\n\t\t\tsize: 60000,\n\t\t\tsteps: [1, 2, 5, 10, 30]\n\t\t},\n\t\thour: {\n\t\t\tsize: 3600000,\n\t\t\tsteps: [1, 2, 3, 6, 12]\n\t\t},\n\t\tday: {\n\t\t\tsize: 86400000,\n\t\t\tsteps: [1, 2, 5]\n\t\t},\n\t\tweek: {\n\t\t\tsize: 604800000,\n\t\t\tmaxStep: 4\n\t\t},\n\t\tmonth: {\n\t\t\tsize: 2.628e9,\n\t\t\tmaxStep: 3\n\t\t},\n\t\tquarter: {\n\t\t\tsize: 7.884e9,\n\t\t\tmaxStep: 4\n\t\t},\n\t\tyear: {\n\t\t\tsize: 3.154e10,\n\t\t\tmaxStep: false\n\t\t}\n\t};\n\n\tvar defaultConfig = {\n\t\tposition: 'bottom',\n\n\t\ttime: {\n\t\t\tparser: false, // false == a pattern string from http://momentjs.com/docs/#/parsing/string-format/ or a custom callback that converts its argument to a moment\n\t\t\tformat: false, // DEPRECATED false == date objects, moment object, callback or a pattern string from http://momentjs.com/docs/#/parsing/string-format/\n\t\t\tunit: false, // false == automatic or override with week, month, year, etc.\n\t\t\tround: false, // none, or override with week, month, year, etc.\n\t\t\tdisplayFormat: false, // DEPRECATED\n\t\t\tisoWeekday: false, // override week start day - see http://momentjs.com/docs/#/get-set/iso-weekday/\n\t\t\tminUnit: 'millisecond',\n\n\t\t\t// defaults to unit's corresponding unitFormat below or override using pattern string from http://momentjs.com/docs/#/displaying/format/\n\t\t\tdisplayFormats: {\n\t\t\t\tmillisecond: 'h:mm:ss.SSS a', // 11:20:01.123 AM,\n\t\t\t\tsecond: 'h:mm:ss a', // 11:20:01 AM\n\t\t\t\tminute: 'h:mm:ss a', // 11:20:01 AM\n\t\t\t\thour: 'MMM D, hA', // Sept 4, 5PM\n\t\t\t\tday: 'll', // Sep 4 2015\n\t\t\t\tweek: 'll', // Week 46, or maybe \"[W]WW - YYYY\" ?\n\t\t\t\tmonth: 'MMM YYYY', // Sept 2015\n\t\t\t\tquarter: '[Q]Q - YYYY', // Q3\n\t\t\t\tyear: 'YYYY' // 2015\n\t\t\t},\n\t\t},\n\t\tticks: {\n\t\t\tautoSkip: false\n\t\t}\n\t};\n\n\t/**\n\t * Helper function to parse time to a moment object\n\t * @param axis {TimeAxis} the time axis\n\t * @param label {Date|string|number|Moment} The thing to parse\n\t * @return {Moment} parsed time\n\t */\n\tfunction parseTime(axis, label) {\n\t\tvar timeOpts = axis.options.time;\n\t\tif (typeof timeOpts.parser === 'string') {\n\t\t\treturn moment(label, timeOpts.parser);\n\t\t}\n\t\tif (typeof timeOpts.parser === 'function') {\n\t\t\treturn timeOpts.parser(label);\n\t\t}\n\t\tif (typeof label.getMonth === 'function' || typeof label === 'number') {\n\t\t\t// Date objects\n\t\t\treturn moment(label);\n\t\t}\n\t\tif (label.isValid && label.isValid()) {\n\t\t\t// Moment support\n\t\t\treturn label;\n\t\t}\n\t\tvar format = timeOpts.format;\n\t\tif (typeof format !== 'string' && format.call) {\n\t\t\t// Custom parsing (return an instance of moment)\n\t\t\tconsole.warn('options.time.format is deprecated and replaced by options.time.parser.');\n\t\t\treturn format(label);\n\t\t}\n\t\t// Moment format parsing\n\t\treturn moment(label, format);\n\t}\n\n\t/**\n\t * Figure out which is the best unit for the scale\n\t * @param minUnit {String} minimum unit to use\n\t * @param min {Number} scale minimum\n\t * @param max {Number} scale maximum\n\t * @return {String} the unit to use\n\t */\n\tfunction determineUnit(minUnit, min, max, maxTicks) {\n\t\tvar units = Object.keys(interval);\n\t\tvar unit;\n\t\tvar numUnits = units.length;\n\n\t\tfor (var i = units.indexOf(minUnit); i < numUnits; i++) {\n\t\t\tunit = units[i];\n\t\t\tvar unitDetails = interval[unit];\n\t\t\tvar steps = (unitDetails.steps && unitDetails.steps[unitDetails.steps.length - 1]) || unitDetails.maxStep;\n\t\t\tif (steps === undefined || Math.ceil((max - min) / (steps * unitDetails.size)) <= maxTicks) {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\treturn unit;\n\t}\n\n\t/**\n\t * Determines how we scale the unit\n\t * @param min {Number} the scale minimum\n\t * @param max {Number} the scale maximum\n\t * @param unit {String} the unit determined by the {@see determineUnit} method\n\t * @return {Number} the axis step size as a multiple of unit\n\t */\n\tfunction determineStepSize(min, max, unit, maxTicks) {\n\t\t// Using our unit, figoure out what we need to scale as\n\t\tvar unitDefinition = interval[unit];\n\t\tvar unitSizeInMilliSeconds = unitDefinition.size;\n\t\tvar sizeInUnits = Math.ceil((max - min) / unitSizeInMilliSeconds);\n\t\tvar multiplier = 1;\n\t\tvar range = max - min;\n\n\t\tif (unitDefinition.steps) {\n\t\t\t// Have an array of steps\n\t\t\tvar numSteps = unitDefinition.steps.length;\n\t\t\tfor (var i = 0; i < numSteps && sizeInUnits > maxTicks; i++) {\n\t\t\t\tmultiplier = unitDefinition.steps[i];\n\t\t\t\tsizeInUnits = Math.ceil(range / (unitSizeInMilliSeconds * multiplier));\n\t\t\t}\n\t\t} else {\n\t\t\twhile (sizeInUnits > maxTicks && maxTicks > 0) {\n\t\t\t\t++multiplier;\n\t\t\t\tsizeInUnits = Math.ceil(range / (unitSizeInMilliSeconds * multiplier));\n\t\t\t}\n\t\t}\n\n\t\treturn multiplier;\n\t}\n\n\t/**\n\t * Helper for generating axis labels.\n\t * @param options {ITimeGeneratorOptions} the options for generation\n\t * @param dataRange {IRange} the data range\n\t * @param niceRange {IRange} the pretty range to display\n\t * @return {Number[]} ticks\n\t */\n\tfunction generateTicks(options, dataRange, niceRange) {\n\t\tvar ticks = [];\n\t\tif (options.maxTicks) {\n\t\t\tvar stepSize = options.stepSize;\n\t\t\tticks.push(options.min !== undefined ? options.min : niceRange.min);\n\t\t\tvar cur = moment(niceRange.min);\n\t\t\twhile (cur.add(stepSize, options.unit).valueOf() < niceRange.max) {\n\t\t\t\tticks.push(cur.valueOf());\n\t\t\t}\n\t\t\tvar realMax = options.max || niceRange.max;\n\t\t\tif (ticks[ticks.length - 1] !== realMax) {\n\t\t\t\tticks.push(realMax);\n\t\t\t}\n\t\t}\n\t\treturn ticks;\n\t}\n\n\t/**\n\t * @function Chart.Ticks.generators.time\n\t * @param options {ITimeGeneratorOptions} the options for generation\n\t * @param dataRange {IRange} the data range\n\t * @return {Number[]} ticks\n\t */\n\tChart.Ticks.generators.time = function(options, dataRange) {\n\t\tvar niceMin;\n\t\tvar niceMax;\n\t\tvar isoWeekday = options.isoWeekday;\n\t\tif (options.unit === 'week' && isoWeekday !== false) {\n\t\t\tniceMin = moment(dataRange.min).startOf('isoWeek').isoWeekday(isoWeekday).valueOf();\n\t\t\tniceMax = moment(dataRange.max).startOf('isoWeek').isoWeekday(isoWeekday);\n\t\t\tif (dataRange.max - niceMax > 0) {\n\t\t\t\tniceMax.add(1, 'week');\n\t\t\t}\n\t\t\tniceMax = niceMax.valueOf();\n\t\t} else {\n\t\t\tniceMin = moment(dataRange.min).startOf(options.unit).valueOf();\n\t\t\tniceMax = moment(dataRange.max).startOf(options.unit);\n\t\t\tif (dataRange.max - niceMax > 0) {\n\t\t\t\tniceMax.add(1, options.unit);\n\t\t\t}\n\t\t\tniceMax = niceMax.valueOf();\n\t\t}\n\t\treturn generateTicks(options, dataRange, {\n\t\t\tmin: niceMin,\n\t\t\tmax: niceMax\n\t\t});\n\t};\n\n\tvar TimeScale = Chart.Scale.extend({\n\t\tinitialize: function() {\n\t\t\tif (!moment) {\n\t\t\t\tthrow new Error('Chart.js - Moment.js could not be found! You must include it before Chart.js to use the time scale. Download at https://momentjs.com');\n\t\t\t}\n\n\t\t\tChart.Scale.prototype.initialize.call(this);\n\t\t},\n\t\tdetermineDataLimits: function() {\n\t\t\tvar me = this;\n\t\t\tvar timeOpts = me.options.time;\n\n\t\t\t// We store the data range as unix millisecond timestamps so dataMin and dataMax will always be integers.\n\t\t\tvar dataMin = Number.MAX_SAFE_INTEGER;\n\t\t\tvar dataMax = Number.MIN_SAFE_INTEGER;\n\n\t\t\tvar chartData = me.chart.data;\n\t\t\tvar parsedData = {\n\t\t\t\tlabels: [],\n\t\t\t\tdatasets: []\n\t\t\t};\n\n\t\t\tvar timestamp;\n\n\t\t\thelpers.each(chartData.labels, function(label, labelIndex) {\n\t\t\t\tvar labelMoment = parseTime(me, label);\n\n\t\t\t\tif (labelMoment.isValid()) {\n\t\t\t\t\t// We need to round the time\n\t\t\t\t\tif (timeOpts.round) {\n\t\t\t\t\t\tlabelMoment.startOf(timeOpts.round);\n\t\t\t\t\t}\n\n\t\t\t\t\ttimestamp = labelMoment.valueOf();\n\t\t\t\t\tdataMin = Math.min(timestamp, dataMin);\n\t\t\t\t\tdataMax = Math.max(timestamp, dataMax);\n\n\t\t\t\t\t// Store this value for later\n\t\t\t\t\tparsedData.labels[labelIndex] = timestamp;\n\t\t\t\t}\n\t\t\t});\n\n\t\t\thelpers.each(chartData.datasets, function(dataset, datasetIndex) {\n\t\t\t\tvar timestamps = [];\n\n\t\t\t\tif (typeof dataset.data[0] === 'object' && dataset.data[0] !== null && me.chart.isDatasetVisible(datasetIndex)) {\n\t\t\t\t\t// We have potential point data, so we need to parse this\n\t\t\t\t\thelpers.each(dataset.data, function(value, dataIndex) {\n\t\t\t\t\t\tvar dataMoment = parseTime(me, me.getRightValue(value));\n\n\t\t\t\t\t\tif (dataMoment.isValid()) {\n\t\t\t\t\t\t\tif (timeOpts.round) {\n\t\t\t\t\t\t\t\tdataMoment.startOf(timeOpts.round);\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\ttimestamp = dataMoment.valueOf();\n\t\t\t\t\t\t\tdataMin = Math.min(timestamp, dataMin);\n\t\t\t\t\t\t\tdataMax = Math.max(timestamp, dataMax);\n\t\t\t\t\t\t\ttimestamps[dataIndex] = timestamp;\n\t\t\t\t\t\t}\n\t\t\t\t\t});\n\t\t\t\t} else {\n\t\t\t\t\t// We have no x coordinates, so use the ones from the labels\n\t\t\t\t\ttimestamps = parsedData.labels.slice();\n\t\t\t\t}\n\n\t\t\t\tparsedData.datasets[datasetIndex] = timestamps;\n\t\t\t});\n\n\t\t\tme.dataMin = dataMin;\n\t\t\tme.dataMax = dataMax;\n\t\t\tme._parsedData = parsedData;\n\t\t},\n\t\tbuildTicks: function() {\n\t\t\tvar me = this;\n\t\t\tvar timeOpts = me.options.time;\n\n\t\t\tvar minTimestamp;\n\t\t\tvar maxTimestamp;\n\t\t\tvar dataMin = me.dataMin;\n\t\t\tvar dataMax = me.dataMax;\n\n\t\t\tif (timeOpts.min) {\n\t\t\t\tvar minMoment = parseTime(me, timeOpts.min);\n\t\t\t\tif (timeOpts.round) {\n\t\t\t\t\tminMoment.round(timeOpts.round);\n\t\t\t\t}\n\t\t\t\tminTimestamp = minMoment.valueOf();\n\t\t\t}\n\n\t\t\tif (timeOpts.max) {\n\t\t\t\tmaxTimestamp = parseTime(me, timeOpts.max).valueOf();\n\t\t\t}\n\n\t\t\tvar maxTicks = me.getLabelCapacity(minTimestamp || dataMin);\n\t\t\tvar unit = timeOpts.unit || determineUnit(timeOpts.minUnit, minTimestamp || dataMin, maxTimestamp || dataMax, maxTicks);\n\t\t\tme.displayFormat = timeOpts.displayFormats[unit];\n\n\t\t\tvar stepSize = timeOpts.stepSize || determineStepSize(minTimestamp || dataMin, maxTimestamp || dataMax, unit, maxTicks);\n\t\t\tme.ticks = Chart.Ticks.generators.time({\n\t\t\t\tmaxTicks: maxTicks,\n\t\t\t\tmin: minTimestamp,\n\t\t\t\tmax: maxTimestamp,\n\t\t\t\tstepSize: stepSize,\n\t\t\t\tunit: unit,\n\t\t\t\tisoWeekday: timeOpts.isoWeekday\n\t\t\t}, {\n\t\t\t\tmin: dataMin,\n\t\t\t\tmax: dataMax\n\t\t\t});\n\n\t\t\t// At this point, we need to update our max and min given the tick values since we have expanded the\n\t\t\t// range of the scale\n\t\t\tme.max = helpers.max(me.ticks);\n\t\t\tme.min = helpers.min(me.ticks);\n\t\t},\n\t\t// Get tooltip label\n\t\tgetLabelForIndex: function(index, datasetIndex) {\n\t\t\tvar me = this;\n\t\t\tvar label = me.chart.data.labels && index < me.chart.data.labels.length ? me.chart.data.labels[index] : '';\n\t\t\tvar value = me.chart.data.datasets[datasetIndex].data[index];\n\n\t\t\tif (value !== null && typeof value === 'object') {\n\t\t\t\tlabel = me.getRightValue(value);\n\t\t\t}\n\n\t\t\t// Format nicely\n\t\t\tif (me.options.time.tooltipFormat) {\n\t\t\t\tlabel = parseTime(me, label).format(me.options.time.tooltipFormat);\n\t\t\t}\n\n\t\t\treturn label;\n\t\t},\n\t\t// Function to format an individual tick mark\n\t\ttickFormatFunction: function(tick, index, ticks) {\n\t\t\tvar formattedTick = tick.format(this.displayFormat);\n\t\t\tvar tickOpts = this.options.ticks;\n\t\t\tvar callback = helpers.getValueOrDefault(tickOpts.callback, tickOpts.userCallback);\n\n\t\t\tif (callback) {\n\t\t\t\treturn callback(formattedTick, index, ticks);\n\t\t\t}\n\t\t\treturn formattedTick;\n\t\t},\n\t\tconvertTicksToLabels: function() {\n\t\t\tvar me = this;\n\t\t\tme.ticksAsTimestamps = me.ticks;\n\t\t\tme.ticks = me.ticks.map(function(tick) {\n\t\t\t\treturn moment(tick);\n\t\t\t}).map(me.tickFormatFunction, me);\n\t\t},\n\t\tgetPixelForOffset: function(offset) {\n\t\t\tvar me = this;\n\t\t\tvar epochWidth = me.max - me.min;\n\t\t\tvar decimal = epochWidth ? (offset - me.min) / epochWidth : 0;\n\n\t\t\tif (me.isHorizontal()) {\n\t\t\t\tvar valueOffset = (me.width * decimal);\n\t\t\t\treturn me.left + Math.round(valueOffset);\n\t\t\t}\n\n\t\t\tvar heightOffset = (me.height * decimal);\n\t\t\treturn me.top + Math.round(heightOffset);\n\t\t},\n\t\tgetPixelForValue: function(value, index, datasetIndex) {\n\t\t\tvar me = this;\n\t\t\tvar offset = null;\n\t\t\tif (index !== undefined && datasetIndex !== undefined) {\n\t\t\t\toffset = me._parsedData.datasets[datasetIndex][index];\n\t\t\t}\n\n\t\t\tif (offset === null) {\n\t\t\t\tif (!value || !value.isValid) {\n\t\t\t\t\t// not already a moment object\n\t\t\t\t\tvalue = parseTime(me, me.getRightValue(value));\n\t\t\t\t}\n\n\t\t\t\tif (value && value.isValid && value.isValid()) {\n\t\t\t\t\toffset = value.valueOf();\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (offset !== null) {\n\t\t\t\treturn me.getPixelForOffset(offset);\n\t\t\t}\n\t\t},\n\t\tgetPixelForTick: function(index) {\n\t\t\treturn this.getPixelForOffset(this.ticksAsTimestamps[index]);\n\t\t},\n\t\tgetValueForPixel: function(pixel) {\n\t\t\tvar me = this;\n\t\t\tvar innerDimension = me.isHorizontal() ? me.width : me.height;\n\t\t\tvar offset = (pixel - (me.isHorizontal() ? me.left : me.top)) / innerDimension;\n\t\t\treturn moment(me.min + (offset * (me.max - me.min)));\n\t\t},\n\t\t// Crude approximation of what the label width might be\n\t\tgetLabelWidth: function(label) {\n\t\t\tvar me = this;\n\t\t\tvar ticks = me.options.ticks;\n\n\t\t\tvar tickLabelWidth = me.ctx.measureText(label).width;\n\t\t\tvar cosRotation = Math.cos(helpers.toRadians(ticks.maxRotation));\n\t\t\tvar sinRotation = Math.sin(helpers.toRadians(ticks.maxRotation));\n\t\t\tvar tickFontSize = helpers.getValueOrDefault(ticks.fontSize, Chart.defaults.global.defaultFontSize);\n\t\t\treturn (tickLabelWidth * cosRotation) + (tickFontSize * sinRotation);\n\t\t},\n\t\tgetLabelCapacity: function(exampleTime) {\n\t\t\tvar me = this;\n\n\t\t\tme.displayFormat = me.options.time.displayFormats.millisecond;\t// Pick the longest format for guestimation\n\t\t\tvar exampleLabel = me.tickFormatFunction(moment(exampleTime), 0, []);\n\t\t\tvar tickLabelWidth = me.getLabelWidth(exampleLabel);\n\n\t\t\tvar innerWidth = me.isHorizontal() ? me.width : me.height;\n\t\t\tvar labelCapacity = innerWidth / tickLabelWidth;\n\t\t\treturn labelCapacity;\n\t\t}\n\t});\n\tChart.scaleService.registerScaleType('time', TimeScale, defaultConfig);\n\n};\n"
  },
  {
    "path": "app_backend/static/plugin/Chart.js-2.6.0/test/fixtures/plugin.filler/fill-line-boundary-end-span.json",
    "content": "{\n    \"config\": {\n        \"type\": \"line\",\n        \"data\": {\n            \"labels\": [\"0\", \"1\", \"2\", \"3\", \"4\", \"5\", \"6\", \"7\", \"8\"],\n            \"datasets\": [{\n                \"backgroundColor\": \"rgba(0, 0, 192, 0.25)\",\n                \"data\": [null, null, 2, 3, 4, -4, -2, 1, 0]\n            }, {\n                \"backgroundColor\": \"rgba(0, 192, 0, 0.25)\",\n                \"data\": [5.5, 2, null, 4, 5, null, null, 2, 1]\n            }, {\n                \"backgroundColor\": \"rgba(192, 0, 0, 0.25)\",\n                \"data\": [7, 3, 4, 5, 6, 1, 4, null, null]\n            }, {\n                \"backgroundColor\": \"rgba(0, 0, 192, 0.25)\",\n                \"data\": [8, 7, 6.5, -6, -4, -6, 4, 5, 8]\n            }]\n        },\n        \"options\": {\n            \"responsive\": false,\n            \"spanGaps\": true,\n            \"legend\": false,\n            \"title\": false,\n            \"scales\": {\n                \"xAxes\": [{\n                    \"ticks\": {\n                        \"display\": false\n                    }\n                }],\n                \"yAxes\": [{\n                    \"ticks\": {\n                        \"display\": false\n                    }\n                }]\n            },\n            \"elements\": {\n                \"point\": {\n                    \"radius\": 0\n                },\n                \"line\": {\n                    \"borderColor\": \"transparent\",\n                    \"fill\": \"end\",\n                    \"tension\": 0\n                }\n            }\n        }\n    },\n    \"options\": {\n        \"canvas\": {\n            \"height\": 256,\n            \"width\": 512\n        }\n    }\n}\n"
  },
  {
    "path": "app_backend/static/plugin/Chart.js-2.6.0/test/fixtures/plugin.filler/fill-line-boundary-end.json",
    "content": "{\n    \"config\": {\n        \"type\": \"line\",\n        \"data\": {\n            \"labels\": [\"0\", \"1\", \"2\", \"3\", \"4\", \"5\", \"6\", \"7\", \"8\"],\n            \"datasets\": [{\n                \"backgroundColor\": \"rgba(0, 0, 192, 0.25)\",\n                \"data\": [null, null, 2, 3, 4, -4, -2, 1, 0]\n            }, {\n                \"backgroundColor\": \"rgba(0, 192, 0, 0.25)\",\n                \"data\": [5.5, 2, null, 4, 5, null, null, 2, 1]\n            }, {\n                \"backgroundColor\": \"rgba(192, 0, 0, 0.25)\",\n                \"data\": [7, 3, 4, 5, 6, 1, 4, null, null]\n            }, {\n                \"backgroundColor\": \"rgba(0, 0, 192, 0.25)\",\n                \"data\": [8, 7, 6.5, -6, -4, -6, 4, 5, 8]\n            }]\n        },\n        \"options\": {\n            \"responsive\": false,\n            \"spanGaps\": false,\n            \"legend\": false,\n            \"title\": false,\n            \"scales\": {\n                \"xAxes\": [{\n                    \"ticks\": {\n                        \"display\": false\n                    }\n                }],\n                \"yAxes\": [{\n                    \"ticks\": {\n                        \"display\": false\n                    }\n                }]\n            },\n            \"elements\": {\n                \"point\": {\n                    \"radius\": 0\n                },\n                \"line\": {\n                    \"borderColor\": \"transparent\",\n                    \"fill\": \"end\",\n                    \"tension\": 0\n                }\n            }\n        }\n    },\n    \"options\": {\n        \"canvas\": {\n            \"height\": 256,\n            \"width\": 512\n        }\n    }\n}\n"
  },
  {
    "path": "app_backend/static/plugin/Chart.js-2.6.0/test/fixtures/plugin.filler/fill-line-boundary-origin-span.json",
    "content": "{\n    \"config\": {\n        \"type\": \"line\",\n        \"data\": {\n            \"labels\": [\"0\", \"1\", \"2\", \"3\", \"4\", \"5\", \"6\", \"7\", \"8\"],\n            \"datasets\": [{\n                \"backgroundColor\": \"rgba(0, 0, 192, 0.25)\",\n                \"data\": [null, null, 2, 3, 4, -4, -2, 1, 0]\n            }, {\n                \"backgroundColor\": \"rgba(0, 192, 0, 0.25)\",\n                \"data\": [6, 2, null, 4, 5, null, null, 2, 1]\n            }, {\n                \"backgroundColor\": \"rgba(192, 0, 0, 0.25)\",\n                \"data\": [7, 3, 4, 5, 6, 1, 4, null, null]\n            }, {\n                \"backgroundColor\": \"rgba(0, 64, 192, 0.25)\",\n                \"data\": [8, 7, 6, -6, -4, -6, 4, 5, 8]\n            }]\n        },\n        \"options\": {\n            \"responsive\": false,\n            \"spanGaps\": true,\n            \"legend\": false,\n            \"title\": false,\n            \"scales\": {\n                \"xAxes\": [{\n                    \"ticks\": {\n                        \"display\": false\n                    }\n                }],\n                \"yAxes\": [{\n                    \"ticks\": {\n                        \"display\": false\n                    }\n                }]\n            },\n            \"elements\": {\n                \"point\": {\n                    \"radius\": 0\n                },\n                \"line\": {\n                    \"borderColor\": \"transparent\",\n                    \"fill\": \"origin\",\n                    \"tension\": 0\n                }\n            }\n        }\n    },\n    \"options\": {\n        \"canvas\": {\n            \"height\": 256,\n            \"width\": 512\n        }\n    }\n}\n"
  },
  {
    "path": "app_backend/static/plugin/Chart.js-2.6.0/test/fixtures/plugin.filler/fill-line-boundary-origin-spline-span.json",
    "content": "{\n    \"config\": {\n        \"type\": \"line\",\n        \"data\": {\n            \"labels\": [\"0\", \"1\", \"2\", \"3\", \"4\", \"5\", \"6\", \"7\", \"8\"],\n            \"datasets\": [{\n                \"backgroundColor\": \"rgba(0, 0, 192, 0.25)\",\n                \"data\": [null, null, 2, 4, 2, 1, -1, 1, 2]\n            }, {\n                \"backgroundColor\": \"rgba(0, 192, 0, 0.25)\",\n                \"data\": [4, 2, null, 3, 2.5, null, -2, 1.5, 3]\n            }, {\n                \"backgroundColor\": \"rgba(192, 0, 0, 0.25)\",\n                \"data\": [3.5, 2, 1, 2.5, -2, 3, -1, null, null]\n            }, {\n                \"backgroundColor\": \"rgba(128, 0, 128, 0.25)\",\n                \"data\": [5, 6, 5, -2, -4, -3, 4, 2, 4.5]\n            }]\n        },\n        \"options\": {\n            \"responsive\": false,\n            \"spanGaps\": true,\n            \"legend\": false,\n            \"title\": false,\n            \"scales\": {\n                \"xAxes\": [{\n                    \"ticks\": {\n                        \"display\": false\n                    }\n                }],\n                \"yAxes\": [{\n                    \"ticks\": {\n                        \"display\": false\n                    }\n                }]\n            },\n            \"elements\": {\n                \"point\": {\n                    \"radius\": 0\n                },\n                \"line\": {\n                    \"cubicInterpolationMode\": \"monotone\",\n                    \"borderColor\": \"transparent\",\n                    \"fill\": \"origin\"\n                }\n            }\n        }\n    },\n    \"options\": {\n        \"canvas\": {\n            \"height\": 256,\n            \"width\": 512\n        }\n    }\n}\n"
  },
  {
    "path": "app_backend/static/plugin/Chart.js-2.6.0/test/fixtures/plugin.filler/fill-line-boundary-origin-spline.json",
    "content": "{\n    \"config\": {\n        \"type\": \"line\",\n        \"data\": {\n            \"labels\": [\"0\", \"1\", \"2\", \"3\", \"4\", \"5\", \"6\", \"7\", \"8\"],\n            \"datasets\": [{\n                \"backgroundColor\": \"rgba(0, 0, 192, 0.25)\",\n                \"data\": [null, null, 2, 4, 2, 1, -1, 1, 2]\n            }, {\n                \"backgroundColor\": \"rgba(0, 192, 0, 0.25)\",\n                \"data\": [4, 2, null, 3, 2.5, null, -2, 1.5, 3]\n            }, {\n                \"backgroundColor\": \"rgba(192, 0, 0, 0.25)\",\n                \"data\": [3.5, 2, 1, 2.5, -2, 3, -1, null, null]\n            }, {\n                \"backgroundColor\": \"rgba(128, 0, 128, 0.25)\",\n                \"data\": [5, 6, 5, -2, -4, -3, 4, 2, 4.5]\n            }]\n        },\n        \"options\": {\n            \"responsive\": false,\n            \"spanGaps\": false,\n            \"legend\": false,\n            \"title\": false,\n            \"scales\": {\n                \"xAxes\": [{\n                    \"ticks\": {\n                        \"display\": false\n                    }\n                }],\n                \"yAxes\": [{\n                    \"ticks\": {\n                        \"display\": false\n                    }\n                }]\n            },\n            \"elements\": {\n                \"point\": {\n                    \"radius\": 0\n                },\n                \"line\": {\n                    \"cubicInterpolationMode\": \"monotone\",\n                    \"borderColor\": \"transparent\",\n                    \"fill\": \"origin\"\n                }\n            }\n        }\n    },\n    \"options\": {\n        \"canvas\": {\n            \"height\": 256,\n            \"width\": 512\n        }\n    }\n}\n"
  },
  {
    "path": "app_backend/static/plugin/Chart.js-2.6.0/test/fixtures/plugin.filler/fill-line-boundary-origin-stepped-span.json",
    "content": "{\n    \"config\": {\n        \"type\": \"line\",\n        \"data\": {\n            \"labels\": [\"0\", \"1\", \"2\", \"3\", \"4\", \"5\", \"6\", \"7\", \"8\"],\n            \"datasets\": [{\n                \"backgroundColor\": \"rgba(0, 0, 192, 0.25)\",\n                \"data\": [null, null, 2, 4, 2, 1, -1, 1, 2]\n            }, {\n                \"backgroundColor\": \"rgba(0, 192, 0, 0.25)\",\n                \"data\": [4, 2, null, 3, 2.5, null, -2, 1.5, 3]\n            }, {\n                \"backgroundColor\": \"rgba(192, 0, 0, 0.25)\",\n                \"data\": [3.5, 2, 1, 2.5, -2, 3, -1, null, null]\n            }, {\n                \"backgroundColor\": \"rgba(128, 0, 128, 0.25)\",\n                \"data\": [5, 6, 5, -2, -4, -3, 4, 2, 4.5]\n            }]\n        },\n        \"options\": {\n            \"responsive\": false,\n            \"spanGaps\": true,\n            \"legend\": false,\n            \"title\": false,\n            \"scales\": {\n                \"xAxes\": [{\n                    \"ticks\": {\n                        \"display\": false\n                    }\n                }],\n                \"yAxes\": [{\n                    \"ticks\": {\n                        \"display\": false\n                    }\n                }]\n            },\n            \"elements\": {\n                \"point\": {\n                    \"radius\": 0\n                },\n                \"line\": {\n                    \"cubicInterpolationMode\": \"monotone\",\n                    \"borderColor\": \"transparent\",\n                    \"stepped\": true,\n                    \"fill\": \"origin\"\n                }\n            }\n        }\n    },\n    \"options\": {\n        \"canvas\": {\n            \"height\": 256,\n            \"width\": 512\n        }\n    }\n}\n"
  },
  {
    "path": "app_backend/static/plugin/Chart.js-2.6.0/test/fixtures/plugin.filler/fill-line-boundary-origin-stepped.json",
    "content": "{\n    \"config\": {\n        \"type\": \"line\",\n        \"data\": {\n            \"labels\": [\"0\", \"1\", \"2\", \"3\", \"4\", \"5\", \"6\", \"7\", \"8\"],\n            \"datasets\": [{\n                \"backgroundColor\": \"rgba(0, 0, 192, 0.25)\",\n                \"data\": [null, null, 2, 4, 2, 1, -1, 1, 2]\n            }, {\n                \"backgroundColor\": \"rgba(0, 192, 0, 0.25)\",\n                \"data\": [4, 2, null, 3, 2.5, null, -2, 1.5, 3]\n            }, {\n                \"backgroundColor\": \"rgba(192, 0, 0, 0.25)\",\n                \"data\": [3.5, 2, 1, 2.5, -2, 3, -1, null, null]\n            }, {\n                \"backgroundColor\": \"rgba(128, 0, 128, 0.25)\",\n                \"data\": [5, 6, 5, -2, -4, -3, 4, 2, 4.5]\n            }]\n        },\n        \"options\": {\n            \"responsive\": false,\n            \"spanGaps\": false,\n            \"legend\": false,\n            \"title\": false,\n            \"scales\": {\n                \"xAxes\": [{\n                    \"ticks\": {\n                        \"display\": false\n                    }\n                }],\n                \"yAxes\": [{\n                    \"ticks\": {\n                        \"display\": false\n                    }\n                }]\n            },\n            \"elements\": {\n                \"point\": {\n                    \"radius\": 0\n                },\n                \"line\": {\n                    \"cubicInterpolationMode\": \"monotone\",\n                    \"borderColor\": \"transparent\",\n                    \"stepped\": true,\n                    \"fill\": \"origin\"\n                }\n            }\n        }\n    },\n    \"options\": {\n        \"canvas\": {\n            \"height\": 256,\n            \"width\": 512\n        }\n    }\n}\n"
  },
  {
    "path": "app_backend/static/plugin/Chart.js-2.6.0/test/fixtures/plugin.filler/fill-line-boundary-origin.json",
    "content": "{\n    \"config\": {\n        \"type\": \"line\",\n        \"data\": {\n            \"labels\": [\"0\", \"1\", \"2\", \"3\", \"4\", \"5\", \"6\", \"7\", \"8\"],\n            \"datasets\": [{\n                \"backgroundColor\": \"rgba(0, 0, 192, 0.25)\",\n                \"data\": [null, null, 2, 3, 4, -4, -2, 1, 0]\n            }, {\n                \"backgroundColor\": \"rgba(0, 192, 0, 0.25)\",\n                \"data\": [6, 2, null, 4, 5, null, null, 2, 1]\n            }, {\n                \"backgroundColor\": \"rgba(192, 0, 0, 0.25)\",\n                \"data\": [7, 3, 4, 5, 6, 1, 4, null, null]\n            }, {\n                \"backgroundColor\": \"rgba(0, 64, 192, 0.25)\",\n                \"data\": [8, 7, 6, -6, -4, -6, 4, 5, 8]\n            }]\n        },\n        \"options\": {\n            \"responsive\": false,\n            \"spanGaps\": false,\n            \"legend\": false,\n            \"title\": false,\n            \"scales\": {\n                \"xAxes\": [{\n                    \"ticks\": {\n                        \"display\": false\n                    }\n                }],\n                \"yAxes\": [{\n                    \"ticks\": {\n                        \"display\": false\n                    }\n                }]\n            },\n            \"elements\": {\n                \"point\": {\n                    \"radius\": 0\n                },\n                \"line\": {\n                    \"borderColor\": \"transparent\",\n                    \"fill\": \"origin\",\n                    \"tension\": 0\n                }\n            }\n        }\n    },\n    \"options\": {\n        \"canvas\": {\n            \"height\": 256,\n            \"width\": 512\n        }\n    }\n}\n"
  },
  {
    "path": "app_backend/static/plugin/Chart.js-2.6.0/test/fixtures/plugin.filler/fill-line-boundary-start-span.json",
    "content": "{\n    \"config\": {\n        \"type\": \"line\",\n        \"data\": {\n            \"labels\": [\"0\", \"1\", \"2\", \"3\", \"4\", \"5\", \"6\", \"7\", \"8\"],\n            \"datasets\": [{\n                \"backgroundColor\": \"rgba(0, 0, 255, 0.25)\",\n                \"data\": [null, null, 2, 3, 4, -4, -2, 1, 0]\n            }, {\n                \"backgroundColor\": \"rgba(0, 255, 0, 0.25)\",\n                \"data\": [6, 2, null, 4, 5, null, null, 2, 1]\n            }, {\n                \"backgroundColor\": \"rgba(255, 0, 0, 0.25)\",\n                \"data\": [7, 3, 4, 5, 6, 1, 4, null, null]\n            }, {\n                \"backgroundColor\": \"rgba(0, 0, 255, 0.25)\",\n                \"data\": [8, 7, 6, -6, -4, -6, 4, 5, 8]\n            }]\n        },\n        \"options\": {\n            \"responsive\": false,\n            \"spanGaps\": true,\n            \"legend\": false,\n            \"title\": false,\n            \"scales\": {\n                \"xAxes\": [{\n                    \"ticks\": {\n                        \"display\": false\n                    }\n                }],\n                \"yAxes\": [{\n                    \"ticks\": {\n                        \"display\": false\n                    }\n                }]\n            },\n            \"elements\": {\n                \"point\": {\n                    \"radius\": 0\n                },\n                \"line\": {\n                    \"borderColor\": \"transparent\",\n                    \"fill\": \"start\",\n                    \"tension\": 0\n                }\n            }\n        }\n    },\n    \"options\": {\n        \"canvas\": {\n            \"height\": 256,\n            \"width\": 512\n        }\n    }\n}\n"
  },
  {
    "path": "app_backend/static/plugin/Chart.js-2.6.0/test/fixtures/plugin.filler/fill-line-boundary-start.json",
    "content": "{\n    \"config\": {\n        \"type\": \"line\",\n        \"data\": {\n            \"labels\": [\"0\", \"1\", \"2\", \"3\", \"4\", \"5\", \"6\", \"7\", \"8\"],\n            \"datasets\": [{\n                \"backgroundColor\": \"rgba(0, 0, 255, 0.25)\",\n                \"data\": [null, null, 2, 3, 4, -4, -2, 1, 0]\n            }, {\n                \"backgroundColor\": \"rgba(0, 255, 0, 0.25)\",\n                \"data\": [6, 2, null, 4, 5, null, null, 2, 1]\n            }, {\n                \"backgroundColor\": \"rgba(255, 0, 0, 0.25)\",\n                \"data\": [7, 3, 4, 5, 6, 1, 4, null, null]\n            }, {\n                \"backgroundColor\": \"rgba(0, 0, 255, 0.25)\",\n                \"data\": [8, 7, 6, -6, -4, -6, 4, 5, 8]\n            }]\n        },\n        \"options\": {\n            \"responsive\": false,\n            \"spanGaps\": false,\n            \"legend\": false,\n            \"title\": false,\n            \"scales\": {\n                \"xAxes\": [{\n                    \"ticks\": {\n                        \"display\": false\n                    }\n                }],\n                \"yAxes\": [{\n                    \"ticks\": {\n                        \"display\": false\n                    }\n                }]\n            },\n            \"elements\": {\n                \"point\": {\n                    \"radius\": 0\n                },\n                \"line\": {\n                    \"borderColor\": \"transparent\",\n                    \"fill\": \"start\",\n                    \"tension\": 0\n                }\n            }\n        }\n    },\n    \"options\": {\n        \"canvas\": {\n            \"height\": 256,\n            \"width\": 512\n        }\n    }\n}\n"
  },
  {
    "path": "app_backend/static/plugin/Chart.js-2.6.0/test/fixtures/plugin.filler/fill-line-dataset-span.json",
    "content": "{\n    \"config\": {\n        \"type\": \"line\",\n        \"data\": {\n            \"labels\": [\"0\", \"1\", \"2\", \"3\", \"4\", \"5\", \"6\", \"7\", \"8\"],\n            \"datasets\": [{\n                \"backgroundColor\": \"rgba(255, 0, 0, 0.25)\",\n                \"data\": [null, null, 0, -1, 0, 1, 0, -1, 0],\n                \"fill\": 1\n            }, {\n                \"backgroundColor\": \"rgba(0, 255, 0, 0.25)\",\n                \"data\": [1, 0, null, 1, 0, null, -1, 0, 1],\n                \"fill\": \"+1\"\n            }, {\n                \"backgroundColor\": \"rgba(0, 0, 255, 0.25)\",\n                \"data\": [0, 2, 0, -2, 0, 2, 0, null, null],\n                \"fill\": 3\n            }, {\n                \"backgroundColor\": \"rgba(255, 0, 255, 0.25)\",\n                \"data\": [2, 0, -2, 0, 2, 0, -2, 0, 2],\n                \"fill\": \"-2\"\n            }, {\n                \"backgroundColor\": \"rgba(255, 255, 0, 0.25)\",\n                \"data\": [3, 1, -1, -3, -1, 1, 3, 1, -1],\n                \"fill\": \"-1\"\n            }]\n        },\n        \"options\": {\n            \"responsive\": false,\n            \"spanGaps\": true,\n            \"legend\": false,\n            \"title\": false,\n            \"scales\": {\n                \"xAxes\": [{\n                    \"ticks\": {\n                        \"display\": false\n                    }\n                }],\n                \"yAxes\": [{\n                    \"ticks\": {\n                        \"display\": false\n                    }\n                }]\n            },\n            \"elements\": {\n                \"point\": {\n                    \"radius\": 0\n                },\n                \"line\": {\n                    \"borderColor\": \"transparent\",\n                    \"tension\": 0\n                }\n            }\n        }\n    },\n    \"options\": {\n        \"canvas\": {\n            \"height\": 256,\n            \"width\": 512\n        }\n    }\n}\n"
  },
  {
    "path": "app_backend/static/plugin/Chart.js-2.6.0/test/fixtures/plugin.filler/fill-line-dataset-spline-span.json",
    "content": "{\n    \"config\": {\n        \"type\": \"line\",\n        \"data\": {\n            \"labels\": [\"0\", \"1\", \"2\", \"3\", \"4\", \"5\", \"6\", \"7\", \"8\"],\n            \"datasets\": [{\n                \"backgroundColor\": \"rgba(255, 0, 0, 0.25)\",\n                \"data\": [null, null, 0, -1, 0, 1, 0, -1, 0],\n                \"fill\": 1\n            }, {\n                \"backgroundColor\": \"rgba(0, 255, 0, 0.25)\",\n                \"data\": [1, 0, null, 1, 0, null, -1, 0, 1],\n                \"fill\": \"+1\"\n            }, {\n                \"backgroundColor\": \"rgba(0, 0, 255, 0.25)\",\n                \"data\": [0, 2, 0, -2, 0, 2, 0, null, null],\n                \"fill\": 3\n            }, {\n                \"backgroundColor\": \"rgba(255, 0, 255, 0.25)\",\n                \"data\": [2, 0, -2, 0, 2, 0, -2, 0, 2],\n                \"fill\": \"-2\"\n            }, {\n                \"backgroundColor\": \"rgba(255, 255, 0, 0.25)\",\n                \"data\": [3, 1, -1, -3, -1, 1, 3, 1, -1],\n                \"fill\": \"-1\"\n            }]\n        },\n        \"options\": {\n            \"responsive\": false,\n            \"spanGaps\": true,\n            \"legend\": false,\n            \"title\": false,\n            \"scales\": {\n                \"xAxes\": [{\n                    \"ticks\": {\n                        \"display\": false\n                    }\n                }],\n                \"yAxes\": [{\n                    \"ticks\": {\n                        \"display\": false\n                    }\n                }]\n            },\n            \"elements\": {\n                \"point\": {\n                    \"radius\": 0\n                },\n                \"line\": {\n                    \"cubicInterpolationMode\": \"monotone\",\n                    \"borderColor\": \"transparent\"\n                }\n            }\n        }\n    },\n    \"options\": {\n        \"canvas\": {\n            \"height\": 256,\n            \"width\": 512\n        }\n    }\n}\n"
  },
  {
    "path": "app_backend/static/plugin/Chart.js-2.6.0/test/fixtures/plugin.filler/fill-line-dataset-spline.json",
    "content": "{\n    \"config\": {\n        \"type\": \"line\",\n        \"data\": {\n            \"labels\": [\"0\", \"1\", \"2\", \"3\", \"4\", \"5\", \"6\", \"7\", \"8\"],\n            \"datasets\": [{\n                \"backgroundColor\": \"rgba(255, 0, 0, 0.25)\",\n                \"data\": [null, null, 0, -1, 0, 1, 0, -1, 0],\n                \"fill\": 1\n            }, {\n                \"backgroundColor\": \"rgba(0, 255, 0, 0.25)\",\n                \"data\": [1, 0, null, 1, 0, null, -1, 0, 1],\n                \"fill\": \"+1\"\n            }, {\n                \"backgroundColor\": \"rgba(0, 0, 255, 0.25)\",\n                \"data\": [0, 2, 0, -2, 0, 2, 0, null, null],\n                \"fill\": 3\n            }, {\n                \"backgroundColor\": \"rgba(255, 0, 255, 0.25)\",\n                \"data\": [2, 0, -2, 0, 2, 0, -2, 0, 2],\n                \"fill\": \"-2\"\n            }, {\n                \"backgroundColor\": \"rgba(255, 255, 0, 0.25)\",\n                \"data\": [3, 1, -1, -3, -1, 1, 3, 1, -1],\n                \"fill\": \"-1\"\n            }]\n        },\n        \"options\": {\n            \"responsive\": false,\n            \"spanGaps\": false,\n            \"legend\": false,\n            \"title\": false,\n            \"scales\": {\n                \"xAxes\": [{\n                    \"ticks\": {\n                        \"display\": false\n                    }\n                }],\n                \"yAxes\": [{\n                    \"ticks\": {\n                        \"display\": false\n                    }\n                }]\n            },\n            \"elements\": {\n                \"point\": {\n                    \"radius\": 0\n                },\n                \"line\": {\n                    \"cubicInterpolationMode\": \"monotone\",\n                    \"borderColor\": \"transparent\"\n                }\n            }\n        }\n    },\n    \"options\": {\n        \"canvas\": {\n            \"height\": 256,\n            \"width\": 512\n        }\n    }\n}\n"
  },
  {
    "path": "app_backend/static/plugin/Chart.js-2.6.0/test/fixtures/plugin.filler/fill-line-dataset.json",
    "content": "{\n    \"config\": {\n        \"type\": \"line\",\n        \"data\": {\n            \"labels\": [\"0\", \"1\", \"2\", \"3\", \"4\", \"5\", \"6\", \"7\", \"8\"],\n            \"datasets\": [{\n                \"backgroundColor\": \"rgba(255, 0, 0, 0.25)\",\n                \"data\": [null, null, 0, -1, 0, 1, 0, -1, 0],\n                \"fill\": 1\n            }, {\n                \"backgroundColor\": \"rgba(0, 255, 0, 0.25)\",\n                \"data\": [1, 0, null, 1, 0, null, -1, 0, 1],\n                \"fill\": \"+1\"\n            }, {\n                \"backgroundColor\": \"rgba(0, 0, 255, 0.25)\",\n                \"data\": [0, 2, 0, -2, 0, 2, 0, null, null],\n                \"fill\": 3\n            }, {\n                \"backgroundColor\": \"rgba(255, 0, 255, 0.25)\",\n                \"data\": [2, 0, -2, 0, 2, 0, -2, 0, 2],\n                \"fill\": \"-2\"\n            }, {\n                \"backgroundColor\": \"rgba(255, 255, 0, 0.25)\",\n                \"data\": [3, 1, -1, -3, -1, 1, 3, 1, -1],\n                \"fill\": \"-1\"\n            }]\n        },\n        \"options\": {\n            \"responsive\": false,\n            \"spanGaps\": false,\n            \"legend\": false,\n            \"title\": false,\n            \"scales\": {\n                \"xAxes\": [{\n                    \"ticks\": {\n                        \"display\": false\n                    }\n                }],\n                \"yAxes\": [{\n                    \"ticks\": {\n                        \"display\": false\n                    }\n                }]\n            },\n            \"elements\": {\n                \"point\": {\n                    \"radius\": 0\n                },\n                \"line\": {\n                    \"borderColor\": \"transparent\",\n                    \"tension\": 0\n                }\n            }\n        }\n    },\n    \"options\": {\n        \"canvas\": {\n            \"height\": 256,\n            \"width\": 512\n        }\n    }\n}\n"
  },
  {
    "path": "app_backend/static/plugin/Chart.js-2.6.0/test/fixtures/plugin.filler/fill-radar-boundary-origin-spline.json",
    "content": "{\n    \"config\": {\n        \"type\": \"radar\",\n        \"data\": {\n            \"labels\": [\"0\", \"1\", \"2\", \"3\", \"4\", \"5\", \"6\", \"7\", \"8\"],\n            \"datasets\": [{\n                \"backgroundColor\": \"rgba(0, 0, 192, 0.25)\",\n                \"data\": [null, null, 2, 4, 2, 1, -1, 1, 2]\n            }, {\n                \"backgroundColor\": \"rgba(0, 192, 0, 0.25)\",\n                \"data\": [4, 2, null, 3, 2.5, null, -2, 1.5, 3]\n            }, {\n                \"backgroundColor\": \"rgba(192, 0, 0, 0.25)\",\n                \"data\": [3.5, 2, 1, 2.5, -2, 3, -1, null, null]\n            }, {\n                \"backgroundColor\": \"rgba(128, 0, 128, 0.25)\",\n                \"data\": [5, 6, 5, -2, -4, -3, 4, 2, 4.5]\n            }]\n        },\n        \"options\": {\n            \"responsive\": false,\n            \"legend\": false,\n            \"title\": false,\n            \"scale\": {\n                \"pointLabels\": {\n                    \"fontSize\": 0\n                },\n                \"ticks\": {\n                    \"display\": false\n                }\n            },\n            \"elements\": {\n                \"point\": {\n                    \"radius\": 0\n                },\n                \"line\": {\n                    \"borderColor\": \"transparent\",\n                    \"tension\": 0.5,\n                    \"fill\": \"origin\"\n                }\n            }\n        }\n    },\n    \"options\": {\n        \"canvas\": {\n            \"height\": 256,\n            \"width\": 256\n        }\n    }\n}\n"
  },
  {
    "path": "app_backend/static/plugin/Chart.js-2.6.0/test/fixtures/plugin.filler/fill-radar-boundary-origin.json",
    "content": "{\n    \"config\": {\n        \"type\": \"radar\",\n        \"data\": {\n            \"labels\": [\"0\", \"1\", \"2\", \"3\", \"4\", \"5\", \"6\", \"7\", \"8\"],\n            \"datasets\": [{\n                \"backgroundColor\": \"rgba(0, 0, 192, 0.25)\",\n                \"data\": [null, null, 2, 4, 2, 1, -1, 1, 2]\n            }, {\n                \"backgroundColor\": \"rgba(0, 192, 0, 0.25)\",\n                \"data\": [4, 2, null, 3, 2.5, null, -2, 1.5, 3]\n            }, {\n                \"backgroundColor\": \"rgba(192, 0, 0, 0.25)\",\n                \"data\": [3.5, 2, 1, 2.5, -2, 3, -1, null, null]\n            }, {\n                \"backgroundColor\": \"rgba(128, 0, 128, 0.25)\",\n                \"data\": [5, 6, 5, -2, -4, -3, 4, 2, 4.5]\n            }]\n        },\n        \"options\": {\n            \"responsive\": false,\n            \"legend\": false,\n            \"title\": false,\n            \"scale\": {\n                \"pointLabels\": {\n                    \"fontSize\": 0\n                },\n                \"ticks\": {\n                    \"display\": false\n                }\n            },\n            \"elements\": {\n                \"point\": {\n                    \"radius\": 0\n                },\n                \"line\": {\n                    \"borderColor\": \"transparent\",\n                    \"fill\": \"origin\"\n                }\n            }\n        }\n    },\n    \"options\": {\n        \"canvas\": {\n            \"height\": 256,\n            \"width\": 256\n        }\n    }\n}\n"
  },
  {
    "path": "app_backend/static/plugin/Chart.js-2.6.0/test/jasmine.context.js",
    "content": "// Code from http://stackoverflow.com/questions/4406864/html-canvas-unit-testing\nvar Context = function() {\n\tthis._calls = []; // names/args of recorded calls\n\tthis._initMethods();\n\n\tthis._fillStyle = null;\n\tthis._lineCap = null;\n\tthis._lineDashOffset = null;\n\tthis._lineJoin = null;\n\tthis._lineWidth = null;\n\tthis._strokeStyle = null;\n\n\t// Define properties here so that we can record each time they are set\n\tObject.defineProperties(this, {\n\t\tfillStyle: {\n\t\t\tget: function() {\n\t\t\t\treturn this._fillStyle;\n\t\t\t},\n\t\t\tset: function(style) {\n\t\t\t\tthis._fillStyle = style;\n\t\t\t\tthis.record('setFillStyle', [style]);\n\t\t\t}\n\t\t},\n\t\tlineCap: {\n\t\t\tget: function() {\n\t\t\t\treturn this._lineCap;\n\t\t\t},\n\t\t\tset: function(cap) {\n\t\t\t\tthis._lineCap = cap;\n\t\t\t\tthis.record('setLineCap', [cap]);\n\t\t\t}\n\t\t},\n\t\tlineDashOffset: {\n\t\t\tget: function() {\n\t\t\t\treturn this._lineDashOffset;\n\t\t\t},\n\t\t\tset: function(offset) {\n\t\t\t\tthis._lineDashOffset = offset;\n\t\t\t\tthis.record('setLineDashOffset', [offset]);\n\t\t\t}\n\t\t},\n\t\tlineJoin: {\n\t\t\tget: function() {\n\t\t\t\treturn this._lineJoin;\n\t\t\t},\n\t\t\tset: function(join) {\n\t\t\t\tthis._lineJoin = join;\n\t\t\t\tthis.record('setLineJoin', [join]);\n\t\t\t}\n\t\t},\n\t\tlineWidth: {\n\t\t\tget: function() {\n\t\t\t\treturn this._lineWidth;\n\t\t\t},\n\t\t\tset: function(width) {\n\t\t\t\tthis._lineWidth = width;\n\t\t\t\tthis.record('setLineWidth', [width]);\n\t\t\t}\n\t\t},\n\t\tstrokeStyle: {\n\t\t\tget: function() {\n\t\t\t\treturn this._strokeStyle;\n\t\t\t},\n\t\t\tset: function(style) {\n\t\t\t\tthis._strokeStyle = style;\n\t\t\t\tthis.record('setStrokeStyle', [style]);\n\t\t\t}\n\t\t},\n\t});\n};\n\nContext.prototype._initMethods = function() {\n\t// define methods to test here\n\t// no way to introspect so we have to do some extra work :(\n\tvar me = this;\n\tvar methods = {\n\t\tarc: function() {},\n\t\tbeginPath: function() {},\n\t\tbezierCurveTo: function() {},\n\t\tclearRect: function() {},\n\t\tclosePath: function() {},\n\t\tfill: function() {},\n\t\tfillRect: function() {},\n\t\tfillText: function() {},\n\t\tlineTo: function() {},\n\t\tmeasureText: function(text) {\n\t\t\t// return the number of characters * fixed size\n\t\t\treturn text ? {width: text.length * 10} : {width: 0};\n\t\t},\n\t\tmoveTo: function() {},\n\t\tquadraticCurveTo: function() {},\n\t\trestore: function() {},\n\t\trotate: function() {},\n\t\tsave: function() {},\n\t\tsetLineDash: function() {},\n\t\tstroke: function() {},\n\t\tstrokeRect: function() {},\n\t\tsetTransform: function() {},\n\t\ttranslate: function() {},\n\t};\n\n\tObject.keys(methods).forEach(function(name) {\n\t\tme[name] = function() {\n\t\t\tme.record(name, arguments);\n\t\t\treturn methods[name].apply(me, arguments);\n\t\t};\n\t});\n};\n\nContext.prototype.record = function(methodName, args) {\n\tthis._calls.push({\n\t\tname: methodName,\n\t\targs: Array.prototype.slice.call(args)\n\t});\n};\n\nContext.prototype.getCalls = function() {\n\treturn this._calls;\n};\n\nContext.prototype.resetCalls = function() {\n\tthis._calls = [];\n};\n\nmodule.exports = Context;\n"
  },
  {
    "path": "app_backend/static/plugin/Chart.js-2.6.0/test/jasmine.index.js",
    "content": "var Context = require('./jasmine.context');\nvar matchers = require('./jasmine.matchers');\nvar utils = require('./jasmine.utils');\n\n(function() {\n\n\t// Keep track of all acquired charts to automatically release them after each specs\n\tvar charts = {};\n\n\tfunction acquireChart() {\n\t\tvar chart = utils.acquireChart.apply(utils, arguments);\n\t\tcharts[chart.id] = chart;\n\t\treturn chart;\n\t}\n\n\tfunction releaseChart(chart) {\n\t\tutils.releaseChart.apply(utils, arguments);\n\t\tdelete charts[chart.id];\n\t}\n\n\tfunction createMockContext() {\n\t\treturn new Context();\n\t}\n\n\twindow.acquireChart = acquireChart;\n\twindow.releaseChart = releaseChart;\n\twindow.createMockContext = createMockContext;\n\n\t// some style initialization to limit differences between browsers across different plateforms.\n\tutils.injectCSS(\n\t\t'.chartjs-wrapper, .chartjs-wrapper canvas {' +\n\t\t\t'border: 0;' +\n\t\t\t'margin: 0;' +\n\t\t\t'padding: 0;' +\n\t\t'}' +\n\t\t'.chartjs-wrapper {' +\n\t\t\t'position: absolute' +\n\t\t'}');\n\n\tjasmine.specsFromFixtures = utils.specsFromFixtures;\n\n\tbeforeEach(function() {\n\t\tjasmine.addMatchers(matchers);\n\t});\n\n\tafterEach(function() {\n\t\t// Auto releasing acquired charts\n\t\tObject.keys(charts).forEach(function(id) {\n\t\t\tvar chart = charts[id];\n\t\t\tif (!(chart.$test || {}).persistent) {\n\t\t\t\treleaseChart(chart);\n\t\t\t}\n\t\t});\n\t});\n}());\n"
  },
  {
    "path": "app_backend/static/plugin/Chart.js-2.6.0/test/jasmine.matchers.js",
    "content": "'use strict';\n\nvar pixelmatch = require('pixelmatch');\nvar utils = require('./jasmine.utils');\n\nfunction toPercent(value) {\n\treturn Math.round(value * 10000) / 100;\n}\n\nfunction createImageData(w, h) {\n\tvar canvas = utils.createCanvas(w, h);\n\tvar context = canvas.getContext('2d');\n\treturn context.getImageData(0, 0, w, h);\n}\n\nfunction canvasFromImageData(data) {\n\tvar canvas = utils.createCanvas(data.width, data.height);\n\tvar context = canvas.getContext('2d');\n\tcontext.putImageData(data, 0, 0);\n\treturn canvas;\n}\n\nfunction buildPixelMatchPreview(actual, expected, diff, threshold, tolerance, count) {\n\tvar ratio = count / (actual.width * actual.height);\n\tvar wrapper = document.createElement('div');\n\n\twrapper.style.cssText = 'display: flex; overflow-y: auto';\n\n\t[\n\t\t{data: actual, label: 'Actual'},\n\t\t{data: expected, label: 'Expected'},\n\t\t{data: diff, label:\n\t\t\t'diff: ' + count + 'px ' +\n\t\t\t'(' + toPercent(ratio) + '%)<br/>' +\n\t\t\t'thr: ' + toPercent(threshold) + '%, ' +\n\t\t\t'tol: '+ toPercent(tolerance) + '%'\n\t\t}\n\t].forEach(function(values) {\n\t\tvar item = document.createElement('div');\n\t\titem.style.cssText = 'text-align: center; font: 12px monospace; line-height: 1.4; margin: 8px';\n\t\titem.innerHTML = '<div style=\"margin: 8px; height: 32px\">' + values.label + '</div>';\n\t\titem.appendChild(canvasFromImageData(values.data));\n\t\twrapper.appendChild(item);\n\t});\n\n\t// WORKAROUND: https://github.com/karma-runner/karma-jasmine/issues/139\n\twrapper.indexOf = function() {\n\t\treturn -1;\n\t};\n\n\treturn wrapper;\n}\n\nfunction toBeCloseToPixel() {\n\treturn {\n\t\tcompare: function(actual, expected) {\n\t\t\tvar result = false;\n\n\t\t\tif (!isNaN(actual) && !isNaN(expected)) {\n\t\t\t\tvar diff = Math.abs(actual - expected);\n\t\t\t\tvar A = Math.abs(actual);\n\t\t\t\tvar B = Math.abs(expected);\n\t\t\t\tvar percentDiff = 0.005; // 0.5% diff\n\t\t\t\tresult = (diff <= (A > B ? A : B) * percentDiff) || diff < 2; // 2 pixels is fine\n\t\t\t}\n\n\t\t\treturn {pass: result};\n\t\t}\n\t};\n}\n\nfunction toEqualOneOf() {\n\treturn {\n\t\tcompare: function(actual, expecteds) {\n\t\t\tvar result = false;\n\t\t\tfor (var i = 0, l = expecteds.length; i < l; i++) {\n\t\t\t\tif (actual === expecteds[i]) {\n\t\t\t\t\tresult = true;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn {\n\t\t\t\tpass: result\n\t\t\t};\n\t\t}\n\t};\n}\n\nfunction toBeValidChart() {\n\treturn {\n\t\tcompare: function(actual) {\n\t\t\tvar message = null;\n\n\t\t\tif (!(actual instanceof Chart)) {\n\t\t\t\tmessage = 'Expected ' + actual + ' to be an instance of Chart';\n\t\t\t} else if (Object.prototype.toString.call(actual.canvas) !== '[object HTMLCanvasElement]') {\n\t\t\t\tmessage = 'Expected canvas to be an instance of HTMLCanvasElement';\n\t\t\t} else if (Object.prototype.toString.call(actual.ctx) !== '[object CanvasRenderingContext2D]') {\n\t\t\t\tmessage = 'Expected context to be an instance of CanvasRenderingContext2D';\n\t\t\t} else if (typeof actual.height !== 'number' || !isFinite(actual.height)) {\n\t\t\t\tmessage = 'Expected height to be a strict finite number';\n\t\t\t} else if (typeof actual.width !== 'number' || !isFinite(actual.width)) {\n\t\t\t\tmessage = 'Expected width to be a strict finite number';\n\t\t\t}\n\n\t\t\treturn {\n\t\t\t\tmessage: message? message : 'Expected ' + actual + ' to be valid chart',\n\t\t\t\tpass: !message\n\t\t\t};\n\t\t}\n\t};\n}\n\nfunction toBeChartOfSize() {\n\treturn {\n\t\tcompare: function(actual, expected) {\n\t\t\tvar res = toBeValidChart().compare(actual);\n\t\t\tif (!res.pass) {\n\t\t\t\treturn res;\n\t\t\t}\n\n\t\t\tvar message = null;\n\t\t\tvar canvas = actual.ctx.canvas;\n\t\t\tvar style = getComputedStyle(canvas);\n\t\t\tvar pixelRatio = window.devicePixelRatio;\n\t\t\tvar dh = parseInt(style.height, 10);\n\t\t\tvar dw = parseInt(style.width, 10);\n\t\t\tvar rh = canvas.height;\n\t\t\tvar rw = canvas.width;\n\t\t\tvar orh = rh / pixelRatio;\n\t\t\tvar orw = rw / pixelRatio;\n\n\t\t\t// sanity checks\n\t\t\tif (actual.height !== orh) {\n\t\t\t\tmessage = 'Expected chart height ' + actual.height + ' to be equal to original render height ' + orh;\n\t\t\t} else if (actual.width !== orw) {\n\t\t\t\tmessage = 'Expected chart width ' + actual.width + ' to be equal to original render width ' + orw;\n\t\t\t}\n\n\t\t\t// validity checks\n\t\t\tif (dh !== expected.dh) {\n\t\t\t\tmessage = 'Expected display height ' + dh + ' to be equal to ' + expected.dh;\n\t\t\t} else if (dw !== expected.dw) {\n\t\t\t\tmessage = 'Expected display width ' + dw + ' to be equal to ' + expected.dw;\n\t\t\t} else if (rh !== expected.rh) {\n\t\t\t\tmessage = 'Expected render height ' + rh + ' to be equal to ' + expected.rh;\n\t\t\t} else if (rw !== expected.rw) {\n\t\t\t\tmessage = 'Expected render width ' + rw + ' to be equal to ' + expected.rw;\n\t\t\t}\n\n\t\t\treturn {\n\t\t\t\tmessage: message? message : 'Expected ' + actual + ' to be a chart of size ' + expected,\n\t\t\t\tpass: !message\n\t\t\t};\n\t\t}\n\t};\n}\n\nfunction toEqualImageData() {\n\treturn {\n\t\tcompare: function(actual, expected, opts) {\n\t\t\tvar message = null;\n\t\t\tvar debug = opts.debug || false;\n\t\t\tvar tolerance = opts.tolerance === undefined? 0.001 : opts.tolerance;\n\t\t\tvar threshold = opts.threshold === undefined? 0.1 : opts.threshold;\n\t\t\tvar ctx, idata, ddata, w, h, count, ratio;\n\n\t\t\tif (actual instanceof Chart) {\n\t\t\t\tctx = actual.ctx;\n\t\t\t} else if (actual instanceof HTMLCanvasElement) {\n\t\t\t\tctx = actual.getContext('2d');\n\t\t\t} else if (actual instanceof CanvasRenderingContext2D) {\n\t\t\t\tctx = actual;\n\t\t\t}\n\n\t\t\tif (ctx) {\n\t\t\t\th = expected.height;\n\t\t\t\tw = expected.width;\n\t\t\t\tidata = ctx.getImageData(0, 0, w, h);\n\t\t\t\tddata = createImageData(w, h);\n\t\t\t\tcount = pixelmatch(idata.data, expected.data, ddata.data, w, h, {threshold: threshold});\n\t\t\t\tratio = count / (w * h);\n\n\t\t\t\tif ((ratio > tolerance) || debug) {\n\t\t\t\t\tmessage = buildPixelMatchPreview(idata, expected, ddata, threshold, tolerance, count);\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tmessage = 'Input value is not a valid image source.';\n\t\t\t}\n\n\t\t\treturn {\n\t\t\t\tmessage: message,\n\t\t\t\tpass: !message\n\t\t\t};\n\t\t}\n\t};\n}\n\nmodule.exports = {\n\ttoBeCloseToPixel: toBeCloseToPixel,\n\ttoEqualOneOf: toEqualOneOf,\n\ttoBeValidChart: toBeValidChart,\n\ttoBeChartOfSize: toBeChartOfSize,\n\ttoEqualImageData: toEqualImageData\n};\n"
  },
  {
    "path": "app_backend/static/plugin/Chart.js-2.6.0/test/jasmine.utils.js",
    "content": "/* global __karma__ */\n\nfunction loadJSON(url, callback) {\n\tvar request = new XMLHttpRequest();\n\trequest.onreadystatechange = function() {\n\t\tif (request.readyState === 4) {\n\t\t\treturn callback(JSON.parse(request.responseText));\n\t\t}\n\t};\n\n\trequest.overrideMimeType('application/json');\n\trequest.open('GET', url, true);\n\trequest.send(null);\n}\n\nfunction createCanvas(w, h) {\n\tvar canvas = document.createElement('canvas');\n\tcanvas.width = w;\n\tcanvas.height = h;\n\treturn canvas;\n}\n\nfunction readImageData(url, callback) {\n\tvar image = new Image();\n\n\timage.onload = function() {\n\t\tvar h = image.height;\n\t\tvar w = image.width;\n\t\tvar canvas = createCanvas(w, h);\n\t\tvar ctx = canvas.getContext('2d');\n\t\tctx.drawImage(image, 0, 0, w, h);\n\t\tcallback(ctx.getImageData(0, 0, w, h));\n\t};\n\n\timage.src = url;\n}\n\n/**\n * Injects a new canvas (and div wrapper) and creates teh associated Chart instance\n * using the given config. Additional options allow tweaking elements generation.\n * @param {object} config - Chart config.\n * @param {object} options - Chart acquisition options.\n * @param {object} options.canvas - Canvas attributes.\n * @param {object} options.wrapper - Canvas wrapper attributes.\n * @param {boolean} options.persistent - If true, the chart will not be released after the spec.\n */\nfunction acquireChart(config, options) {\n\tvar wrapper = document.createElement('div');\n\tvar canvas = document.createElement('canvas');\n\tvar chart, key;\n\n\tconfig = config || {};\n\toptions = options || {};\n\toptions.canvas = options.canvas || {height: 512, width: 512};\n\toptions.wrapper = options.wrapper || {class: 'chartjs-wrapper'};\n\n\tfor (key in options.canvas) {\n\t\tif (options.canvas.hasOwnProperty(key)) {\n\t\t\tcanvas.setAttribute(key, options.canvas[key]);\n\t\t}\n\t}\n\n\tfor (key in options.wrapper) {\n\t\tif (options.wrapper.hasOwnProperty(key)) {\n\t\t\twrapper.setAttribute(key, options.wrapper[key]);\n\t\t}\n\t}\n\n\t// by default, remove chart animation and auto resize\n\tconfig.options = config.options || {};\n\tconfig.options.animation = config.options.animation === undefined? false : config.options.animation;\n\tconfig.options.responsive = config.options.responsive === undefined? false : config.options.responsive;\n\tconfig.options.defaultFontFamily = config.options.defaultFontFamily || 'Arial';\n\n\twrapper.appendChild(canvas);\n\twindow.document.body.appendChild(wrapper);\n\n\tchart = new Chart(canvas.getContext('2d'), config);\n\tchart.$test = {\n\t\tpersistent: options.persistent,\n\t\twrapper: wrapper\n\t};\n\n\treturn chart;\n}\n\nfunction releaseChart(chart) {\n\tchart.destroy();\n\n\tvar wrapper = (chart.$test || {}).wrapper;\n\tif (wrapper && wrapper.parentNode) {\n\t\twrapper.parentNode.removeChild(wrapper);\n\t}\n}\n\nfunction injectCSS(css) {\n\t// http://stackoverflow.com/q/3922139\n\tvar head = document.getElementsByTagName('head')[0];\n\tvar style = document.createElement('style');\n\tstyle.setAttribute('type', 'text/css');\n\tif (style.styleSheet) {   // IE\n\t\tstyle.styleSheet.cssText = css;\n\t} else {\n\t\tstyle.appendChild(document.createTextNode(css));\n\t}\n\thead.appendChild(style);\n}\n\nfunction specFromFixture(description, inputs) {\n\tit(inputs.json, function(done) {\n\t\tloadJSON(inputs.json, function(json) {\n\t\t\tvar chart = acquireChart(json.config, json.options);\n\t\t\tif (!inputs.png) {\n\t\t\t\tfail('Missing PNG comparison file for ' + inputs.json);\n\t\t\t\tif (!json.debug) {\n\t\t\t\t\treleaseChart(chart);\n\t\t\t\t}\n\t\t\t\tdone();\n\t\t\t}\n\n\t\t\treadImageData(inputs.png, function(expected) {\n\t\t\t\texpect(chart).toEqualImageData(expected, json);\n\t\t\t\treleaseChart(chart);\n\t\t\t\tdone();\n\t\t\t});\n\t\t});\n\t});\n}\n\nfunction specsFromFixtures(path) {\n\tvar regex = new RegExp('(^/base/test/fixtures/' + path + '.+)\\\\.(png|json)');\n\tvar inputs = {};\n\n\tObject.keys(__karma__.files || {}).forEach(function(file) {\n\t\tvar matches = file.match(regex);\n\t\tvar name = matches && matches[1];\n\t\tvar type = matches && matches[2];\n\n\t\tif (name && type) {\n\t\t\tinputs[name] = inputs[name] || {};\n\t\t\tinputs[name][type] = file;\n\t\t}\n\t});\n\n\treturn function() {\n\t\tObject.keys(inputs).forEach(function(key) {\n\t\t\tspecFromFixture(key, inputs[key]);\n\t\t});\n\t};\n}\n\nmodule.exports = {\n\tinjectCSS: injectCSS,\n\tcreateCanvas: createCanvas,\n\tacquireChart: acquireChart,\n\treleaseChart: releaseChart,\n\tspecsFromFixtures: specsFromFixtures\n};\n"
  },
  {
    "path": "app_backend/static/plugin/Chart.js-2.6.0/test/specs/controller.bar.tests.js",
    "content": "// Test the bar controller\ndescribe('Bar controller tests', function() {\n\tit('should be constructed', function() {\n\t\tvar chart = window.acquireChart({\n\t\t\ttype: 'bar',\n\t\t\tdata: {\n\t\t\t\tdatasets: [\n\t\t\t\t\t{data: []},\n\t\t\t\t\t{data: []}\n\t\t\t\t],\n\t\t\t\tlabels: []\n\t\t\t}\n\t\t});\n\n\t\tvar meta = chart.getDatasetMeta(1);\n\t\texpect(meta.type).toEqual('bar');\n\t\texpect(meta.data).toEqual([]);\n\t\texpect(meta.hidden).toBe(null);\n\t\texpect(meta.controller).not.toBe(undefined);\n\t\texpect(meta.controller.index).toBe(1);\n\t\texpect(meta.xAxisID).not.toBe(null);\n\t\texpect(meta.yAxisID).not.toBe(null);\n\n\t\tmeta.controller.updateIndex(0);\n\t\texpect(meta.controller.index).toBe(0);\n\t});\n\n\tit('should use the first scale IDs if the dataset does not specify them', function() {\n\t\tvar chart = window.acquireChart({\n\t\t\ttype: 'bar',\n\t\t\tdata: {\n\t\t\t\tdatasets: [\n\t\t\t\t\t{data: []},\n\t\t\t\t\t{data: []}\n\t\t\t\t],\n\t\t\t\tlabels: []\n\t\t\t},\n\t\t\toptions: {\n\t\t\t\tscales: {\n\t\t\t\t\txAxes: [{\n\t\t\t\t\t\tid: 'firstXScaleID'\n\t\t\t\t\t}],\n\t\t\t\t\tyAxes: [{\n\t\t\t\t\t\tid: 'firstYScaleID'\n\t\t\t\t\t}]\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\n\t\tvar meta = chart.getDatasetMeta(1);\n\t\texpect(meta.xAxisID).toBe('firstXScaleID');\n\t\texpect(meta.yAxisID).toBe('firstYScaleID');\n\t});\n\n\tit('should correctly count the number of stacks ignoring datasets of other types and hidden datasets', function() {\n\t\t[\n\t\t\t'bar',\n\t\t\t'horizontalBar'\n\t\t].forEach(function(barType) {\n\t\t\tvar chart = window.acquireChart({\n\t\t\t\ttype: barType,\n\t\t\t\tdata: {\n\t\t\t\t\tdatasets: [\n\t\t\t\t\t\t{data: [], type: 'line'},\n\t\t\t\t\t\t{data: [], hidden: true},\n\t\t\t\t\t\t{data: []},\n\t\t\t\t\t\t{data: []}\n\t\t\t\t\t],\n\t\t\t\t\tlabels: []\n\t\t\t\t}\n\t\t\t});\n\n\t\t\tvar meta = chart.getDatasetMeta(1);\n\t\t\texpect(meta.controller.getStackCount()).toBe(2);\n\t\t});\n\t});\n\n\tit('should correctly count the number of stacks when a group is not specified', function() {\n\t\t[\n\t\t\t'bar',\n\t\t\t'horizontalBar'\n\t\t].forEach(function(barType) {\n\t\t\tvar chart = window.acquireChart({\n\t\t\t\ttype: barType,\n\t\t\t\tdata: {\n\t\t\t\t\tdatasets: [\n\t\t\t\t\t\t{data: []},\n\t\t\t\t\t\t{data: []},\n\t\t\t\t\t\t{data: []},\n\t\t\t\t\t\t{data: []}\n\t\t\t\t\t],\n\t\t\t\t\tlabels: []\n\t\t\t\t}\n\t\t\t});\n\n\t\t\tvar meta = chart.getDatasetMeta(1);\n\t\t\texpect(meta.controller.getStackCount()).toBe(4);\n\t\t});\n\t});\n\n\tit('should correctly count the number of stacks when a group is not specified and the scale is stacked', function() {\n\t\t[\n\t\t\t'bar',\n\t\t\t'horizontalBar'\n\t\t].forEach(function(barType) {\n\t\t\tvar chart = window.acquireChart({\n\t\t\t\ttype: barType,\n\t\t\t\tdata: {\n\t\t\t\t\tdatasets: [\n\t\t\t\t\t\t{data: []},\n\t\t\t\t\t\t{data: []},\n\t\t\t\t\t\t{data: []},\n\t\t\t\t\t\t{data: []}\n\t\t\t\t\t],\n\t\t\t\t\tlabels: []\n\t\t\t\t},\n\t\t\t\toptions: {\n\t\t\t\t\tscales: {\n\t\t\t\t\t\txAxes: [{\n\t\t\t\t\t\t\tstacked: true\n\t\t\t\t\t\t}],\n\t\t\t\t\t\tyAxes: [{\n\t\t\t\t\t\t\tstacked: true\n\t\t\t\t\t\t}]\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t});\n\n\t\t\tvar meta = chart.getDatasetMeta(1);\n\t\t\texpect(meta.controller.getStackCount()).toBe(1);\n\t\t});\n\t});\n\n\tit('should correctly count the number of stacks when a group is not specified and the scale is not stacked', function() {\n\t\t[\n\t\t\t'bar',\n\t\t\t'horizontalBar'\n\t\t].forEach(function(barType) {\n\t\t\tvar chart = window.acquireChart({\n\t\t\t\ttype: barType,\n\t\t\t\tdata: {\n\t\t\t\t\tdatasets: [\n\t\t\t\t\t\t{data: []},\n\t\t\t\t\t\t{data: []},\n\t\t\t\t\t\t{data: []},\n\t\t\t\t\t\t{data: []}\n\t\t\t\t\t],\n\t\t\t\t\tlabels: []\n\t\t\t\t},\n\t\t\t\toptions: {\n\t\t\t\t\tscales: {\n\t\t\t\t\t\txAxes: [{\n\t\t\t\t\t\t\tstacked: false\n\t\t\t\t\t\t}],\n\t\t\t\t\t\tyAxes: [{\n\t\t\t\t\t\t\tstacked: false\n\t\t\t\t\t\t}]\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t});\n\n\t\t\tvar meta = chart.getDatasetMeta(1);\n\t\t\texpect(meta.controller.getStackCount()).toBe(4);\n\t\t});\n\t});\n\n\tit('should correctly count the number of stacks when a group is specified for some', function() {\n\t\t[\n\t\t\t'bar',\n\t\t\t'horizontalBar'\n\t\t].forEach(function(barType) {\n\t\t\tvar chart = window.acquireChart({\n\t\t\t\ttype: barType,\n\t\t\t\tdata: {\n\t\t\t\t\tdatasets: [\n\t\t\t\t\t\t{data: [], stack: 'stack1'},\n\t\t\t\t\t\t{data: [], stack: 'stack1'},\n\t\t\t\t\t\t{data: []},\n\t\t\t\t\t\t{data: []}\n\t\t\t\t\t],\n\t\t\t\t\tlabels: []\n\t\t\t\t}\n\t\t\t});\n\n\t\t\tvar meta = chart.getDatasetMeta(3);\n\t\t\texpect(meta.controller.getStackCount()).toBe(3);\n\t\t});\n\t});\n\n\tit('should correctly count the number of stacks when a group is specified for some and the scale is stacked', function() {\n\t\t[\n\t\t\t'bar',\n\t\t\t'horizontalBar'\n\t\t].forEach(function(barType) {\n\t\t\tvar chart = window.acquireChart({\n\t\t\t\ttype: barType,\n\t\t\t\tdata: {\n\t\t\t\t\tdatasets: [\n\t\t\t\t\t\t{data: [], stack: 'stack1'},\n\t\t\t\t\t\t{data: [], stack: 'stack1'},\n\t\t\t\t\t\t{data: []},\n\t\t\t\t\t\t{data: []}\n\t\t\t\t\t],\n\t\t\t\t\tlabels: []\n\t\t\t\t},\n\t\t\t\toptions: {\n\t\t\t\t\tscales: {\n\t\t\t\t\t\txAxes: [{\n\t\t\t\t\t\t\tstacked: true\n\t\t\t\t\t\t}],\n\t\t\t\t\t\tyAxes: [{\n\t\t\t\t\t\t\tstacked: true\n\t\t\t\t\t\t}]\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t});\n\n\t\t\tvar meta = chart.getDatasetMeta(3);\n\t\t\texpect(meta.controller.getStackCount()).toBe(2);\n\t\t});\n\t});\n\n\tit('should correctly count the number of stacks when a group is specified for some and the scale is not stacked', function() {\n\t\t[\n\t\t\t'bar',\n\t\t\t'horizontalBar'\n\t\t].forEach(function(barType) {\n\t\t\tvar chart = window.acquireChart({\n\t\t\t\ttype: barType,\n\t\t\t\tdata: {\n\t\t\t\t\tdatasets: [\n\t\t\t\t\t\t{data: [], stack: 'stack1'},\n\t\t\t\t\t\t{data: [], stack: 'stack1'},\n\t\t\t\t\t\t{data: []},\n\t\t\t\t\t\t{data: []}\n\t\t\t\t\t],\n\t\t\t\t\tlabels: []\n\t\t\t\t},\n\t\t\t\toptions: {\n\t\t\t\t\tscales: {\n\t\t\t\t\t\txAxes: [{\n\t\t\t\t\t\t\tstacked: false\n\t\t\t\t\t\t}],\n\t\t\t\t\t\tyAxes: [{\n\t\t\t\t\t\t\tstacked: false\n\t\t\t\t\t\t}]\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t});\n\n\t\t\tvar meta = chart.getDatasetMeta(3);\n\t\t\texpect(meta.controller.getStackCount()).toBe(4);\n\t\t});\n\t});\n\n\tit('should correctly count the number of stacks when a group is specified for all', function() {\n\t\t[\n\t\t\t'bar',\n\t\t\t'horizontalBar'\n\t\t].forEach(function(barType) {\n\t\t\tvar chart = window.acquireChart({\n\t\t\t\ttype: barType,\n\t\t\t\tdata: {\n\t\t\t\t\tdatasets: [\n\t\t\t\t\t\t{data: [], stack: 'stack1'},\n\t\t\t\t\t\t{data: [], stack: 'stack1'},\n\t\t\t\t\t\t{data: [], stack: 'stack2'},\n\t\t\t\t\t\t{data: [], stack: 'stack2'}\n\t\t\t\t\t],\n\t\t\t\t\tlabels: []\n\t\t\t\t}\n\t\t\t});\n\n\t\t\tvar meta = chart.getDatasetMeta(3);\n\t\t\texpect(meta.controller.getStackCount()).toBe(2);\n\t\t});\n\t});\n\n\tit('should correctly count the number of stacks when a group is specified for all and the scale is stacked', function() {\n\t\t[\n\t\t\t'bar',\n\t\t\t'horizontalBar'\n\t\t].forEach(function(barType) {\n\t\t\tvar chart = window.acquireChart({\n\t\t\t\ttype: barType,\n\t\t\t\tdata: {\n\t\t\t\t\tdatasets: [\n\t\t\t\t\t\t{data: [], stack: 'stack1'},\n\t\t\t\t\t\t{data: [], stack: 'stack1'},\n\t\t\t\t\t\t{data: [], stack: 'stack2'},\n\t\t\t\t\t\t{data: [], stack: 'stack2'}\n\t\t\t\t\t],\n\t\t\t\t\tlabels: []\n\t\t\t\t},\n\t\t\t\toptions: {\n\t\t\t\t\tscales: {\n\t\t\t\t\t\txAxes: [{\n\t\t\t\t\t\t\tstacked: true\n\t\t\t\t\t\t}],\n\t\t\t\t\t\tyAxes: [{\n\t\t\t\t\t\t\tstacked: true\n\t\t\t\t\t\t}]\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t});\n\n\t\t\tvar meta = chart.getDatasetMeta(3);\n\t\t\texpect(meta.controller.getStackCount()).toBe(2);\n\t\t});\n\t});\n\n\tit('should correctly count the number of stacks when a group is specified for all and the scale is not stacked', function() {\n\t\t[\n\t\t\t'bar',\n\t\t\t'horizontalBar'\n\t\t].forEach(function(barType) {\n\t\t\tvar chart = window.acquireChart({\n\t\t\t\ttype: barType,\n\t\t\t\tdata: {\n\t\t\t\t\tdatasets: [\n\t\t\t\t\t\t{data: [], stack: 'stack1'},\n\t\t\t\t\t\t{data: [], stack: 'stack1'},\n\t\t\t\t\t\t{data: [], stack: 'stack2'},\n\t\t\t\t\t\t{data: [], stack: 'stack2'}\n\t\t\t\t\t],\n\t\t\t\t\tlabels: []\n\t\t\t\t},\n\t\t\t\toptions: {\n\t\t\t\t\tscales: {\n\t\t\t\t\t\txAxes: [{\n\t\t\t\t\t\t\tstacked: false\n\t\t\t\t\t\t}],\n\t\t\t\t\t\tyAxes: [{\n\t\t\t\t\t\t\tstacked: false\n\t\t\t\t\t\t}]\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t});\n\n\t\t\tvar meta = chart.getDatasetMeta(3);\n\t\t\texpect(meta.controller.getStackCount()).toBe(4);\n\t\t});\n\t});\n\n\tit('should correctly get the stack index accounting for datasets of other types and hidden datasets', function() {\n\t\t[\n\t\t\t'bar',\n\t\t\t'horizontalBar'\n\t\t].forEach(function(barType) {\n\t\t\tvar chart = window.acquireChart({\n\t\t\t\ttype: barType,\n\t\t\t\tdata: {\n\t\t\t\t\tdatasets: [\n\t\t\t\t\t\t{data: []},\n\t\t\t\t\t\t{data: [], hidden: true},\n\t\t\t\t\t\t{data: [], type: 'line'},\n\t\t\t\t\t\t{data: []}\n\t\t\t\t\t],\n\t\t\t\t\tlabels: []\n\t\t\t\t}\n\t\t\t});\n\n\t\t\tvar meta = chart.getDatasetMeta(1);\n\t\t\texpect(meta.controller.getStackIndex(0)).toBe(0);\n\t\t\texpect(meta.controller.getStackIndex(3)).toBe(1);\n\t\t});\n\t});\n\n\tit('should correctly get the stack index when a group is not specified', function() {\n\t\t[\n\t\t\t'bar',\n\t\t\t'horizontalBar'\n\t\t].forEach(function(barType) {\n\t\t\tvar chart = window.acquireChart({\n\t\t\t\ttype: barType,\n\t\t\t\tdata: {\n\t\t\t\t\tdatasets: [\n\t\t\t\t\t\t{data: []},\n\t\t\t\t\t\t{data: []},\n\t\t\t\t\t\t{data: []},\n\t\t\t\t\t\t{data: []}\n\t\t\t\t\t],\n\t\t\t\t\tlabels: []\n\t\t\t\t}\n\t\t\t});\n\n\t\t\tvar meta = chart.getDatasetMeta(1);\n\t\t\texpect(meta.controller.getStackIndex(0)).toBe(0);\n\t\t\texpect(meta.controller.getStackIndex(1)).toBe(1);\n\t\t\texpect(meta.controller.getStackIndex(2)).toBe(2);\n\t\t\texpect(meta.controller.getStackIndex(3)).toBe(3);\n\t\t});\n\t});\n\n\tit('should correctly get the stack index when a group is not specified and the scale is stacked', function() {\n\t\t[\n\t\t\t'bar',\n\t\t\t'horizontalBar'\n\t\t].forEach(function(barType) {\n\t\t\tvar chart = window.acquireChart({\n\t\t\t\ttype: barType,\n\t\t\t\tdata: {\n\t\t\t\t\tdatasets: [\n\t\t\t\t\t\t{data: []},\n\t\t\t\t\t\t{data: []},\n\t\t\t\t\t\t{data: []},\n\t\t\t\t\t\t{data: []}\n\t\t\t\t\t],\n\t\t\t\t\tlabels: []\n\t\t\t\t},\n\t\t\t\toptions: {\n\t\t\t\t\tscales: {\n\t\t\t\t\t\txAxes: [{\n\t\t\t\t\t\t\tstacked: true\n\t\t\t\t\t\t}],\n\t\t\t\t\t\tyAxes: [{\n\t\t\t\t\t\t\tstacked: true\n\t\t\t\t\t\t}]\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t});\n\n\t\t\tvar meta = chart.getDatasetMeta(1);\n\t\t\texpect(meta.controller.getStackIndex(0)).toBe(0);\n\t\t\texpect(meta.controller.getStackIndex(1)).toBe(0);\n\t\t\texpect(meta.controller.getStackIndex(2)).toBe(0);\n\t\t\texpect(meta.controller.getStackIndex(3)).toBe(0);\n\t\t});\n\t});\n\n\tit('should correctly get the stack index when a group is not specified and the scale is not stacked', function() {\n\t\t[\n\t\t\t'bar',\n\t\t\t'horizontalBar'\n\t\t].forEach(function(barType) {\n\t\t\tvar chart = window.acquireChart({\n\t\t\t\ttype: barType,\n\t\t\t\tdata: {\n\t\t\t\t\tdatasets: [\n\t\t\t\t\t\t{data: []},\n\t\t\t\t\t\t{data: []},\n\t\t\t\t\t\t{data: []},\n\t\t\t\t\t\t{data: []}\n\t\t\t\t\t],\n\t\t\t\t\tlabels: []\n\t\t\t\t},\n\t\t\t\toptions: {\n\t\t\t\t\tscales: {\n\t\t\t\t\t\txAxes: [{\n\t\t\t\t\t\t\tstacked: false\n\t\t\t\t\t\t}],\n\t\t\t\t\t\tyAxes: [{\n\t\t\t\t\t\t\tstacked: false\n\t\t\t\t\t\t}]\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t});\n\n\t\t\tvar meta = chart.getDatasetMeta(1);\n\t\t\texpect(meta.controller.getStackIndex(0)).toBe(0);\n\t\t\texpect(meta.controller.getStackIndex(1)).toBe(1);\n\t\t\texpect(meta.controller.getStackIndex(2)).toBe(2);\n\t\t\texpect(meta.controller.getStackIndex(3)).toBe(3);\n\t\t});\n\t});\n\n\tit('should correctly get the stack index when a group is specified for some', function() {\n\t\t[\n\t\t\t'bar',\n\t\t\t'horizontalBar'\n\t\t].forEach(function(barType) {\n\t\t\tvar chart = window.acquireChart({\n\t\t\t\ttype: barType,\n\t\t\t\tdata: {\n\t\t\t\t\tdatasets: [\n\t\t\t\t\t\t{data: [], stack: 'stack1'},\n\t\t\t\t\t\t{data: [], stack: 'stack1'},\n\t\t\t\t\t\t{data: []},\n\t\t\t\t\t\t{data: []}\n\t\t\t\t\t],\n\t\t\t\t\tlabels: []\n\t\t\t\t}\n\t\t\t});\n\n\t\t\tvar meta = chart.getDatasetMeta(1);\n\t\t\texpect(meta.controller.getStackIndex(0)).toBe(0);\n\t\t\texpect(meta.controller.getStackIndex(1)).toBe(0);\n\t\t\texpect(meta.controller.getStackIndex(2)).toBe(1);\n\t\t\texpect(meta.controller.getStackIndex(3)).toBe(2);\n\t\t});\n\t});\n\n\tit('should correctly get the stack index when a group is specified for some and the scale is stacked', function() {\n\t\t[\n\t\t\t'bar',\n\t\t\t'horizontalBar'\n\t\t].forEach(function(barType) {\n\t\t\tvar chart = window.acquireChart({\n\t\t\t\ttype: barType,\n\t\t\t\tdata: {\n\t\t\t\t\tdatasets: [\n\t\t\t\t\t\t{data: [], stack: 'stack1'},\n\t\t\t\t\t\t{data: [], stack: 'stack1'},\n\t\t\t\t\t\t{data: []},\n\t\t\t\t\t\t{data: []}\n\t\t\t\t\t],\n\t\t\t\t\tlabels: []\n\t\t\t\t},\n\t\t\t\toptions: {\n\t\t\t\t\tscales: {\n\t\t\t\t\t\txAxes: [{\n\t\t\t\t\t\t\tstacked: true\n\t\t\t\t\t\t}],\n\t\t\t\t\t\tyAxes: [{\n\t\t\t\t\t\t\tstacked: true\n\t\t\t\t\t\t}]\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t});\n\n\t\t\tvar meta = chart.getDatasetMeta(1);\n\t\t\texpect(meta.controller.getStackIndex(0)).toBe(0);\n\t\t\texpect(meta.controller.getStackIndex(1)).toBe(0);\n\t\t\texpect(meta.controller.getStackIndex(2)).toBe(1);\n\t\t\texpect(meta.controller.getStackIndex(3)).toBe(1);\n\t\t});\n\t});\n\n\tit('should correctly get the stack index when a group is specified for some and the scale is not stacked', function() {\n\t\t[\n\t\t\t'bar',\n\t\t\t'horizontalBar'\n\t\t].forEach(function(barType) {\n\t\t\tvar chart = window.acquireChart({\n\t\t\t\ttype: barType,\n\t\t\t\tdata: {\n\t\t\t\t\tdatasets: [\n\t\t\t\t\t\t{data: [], stack: 'stack1'},\n\t\t\t\t\t\t{data: [], stack: 'stack1'},\n\t\t\t\t\t\t{data: []},\n\t\t\t\t\t\t{data: []}\n\t\t\t\t\t],\n\t\t\t\t\tlabels: []\n\t\t\t\t},\n\t\t\t\toptions: {\n\t\t\t\t\tscales: {\n\t\t\t\t\t\txAxes: [{\n\t\t\t\t\t\t\tstacked: false\n\t\t\t\t\t\t}],\n\t\t\t\t\t\tyAxes: [{\n\t\t\t\t\t\t\tstacked: false\n\t\t\t\t\t\t}]\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t});\n\n\t\t\tvar meta = chart.getDatasetMeta(1);\n\t\t\texpect(meta.controller.getStackIndex(0)).toBe(0);\n\t\t\texpect(meta.controller.getStackIndex(1)).toBe(1);\n\t\t\texpect(meta.controller.getStackIndex(2)).toBe(2);\n\t\t\texpect(meta.controller.getStackIndex(3)).toBe(3);\n\t\t});\n\t});\n\n\tit('should correctly get the stack index when a group is specified for all', function() {\n\t\t[\n\t\t\t'bar',\n\t\t\t'horizontalBar'\n\t\t].forEach(function(barType) {\n\t\t\tvar chart = window.acquireChart({\n\t\t\t\ttype: barType,\n\t\t\t\tdata: {\n\t\t\t\t\tdatasets: [\n\t\t\t\t\t\t{data: [], stack: 'stack1'},\n\t\t\t\t\t\t{data: [], stack: 'stack1'},\n\t\t\t\t\t\t{data: [], stack: 'stack2'},\n\t\t\t\t\t\t{data: [], stack: 'stack2'}\n\t\t\t\t\t],\n\t\t\t\t\tlabels: []\n\t\t\t\t}\n\t\t\t});\n\n\t\t\tvar meta = chart.getDatasetMeta(1);\n\t\t\texpect(meta.controller.getStackIndex(0)).toBe(0);\n\t\t\texpect(meta.controller.getStackIndex(1)).toBe(0);\n\t\t\texpect(meta.controller.getStackIndex(2)).toBe(1);\n\t\t\texpect(meta.controller.getStackIndex(3)).toBe(1);\n\t\t});\n\t});\n\n\tit('should correctly get the stack index when a group is specified for all and the scale is stacked', function() {\n\t\t[\n\t\t\t'bar',\n\t\t\t'horizontalBar'\n\t\t].forEach(function(barType) {\n\t\t\tvar chart = window.acquireChart({\n\t\t\t\ttype: barType,\n\t\t\t\tdata: {\n\t\t\t\t\tdatasets: [\n\t\t\t\t\t\t{data: [], stack: 'stack1'},\n\t\t\t\t\t\t{data: [], stack: 'stack1'},\n\t\t\t\t\t\t{data: [], stack: 'stack2'},\n\t\t\t\t\t\t{data: [], stack: 'stack2'}\n\t\t\t\t\t],\n\t\t\t\t\tlabels: []\n\t\t\t\t},\n\t\t\t\toptions: {\n\t\t\t\t\tscales: {\n\t\t\t\t\t\txAxes: [{\n\t\t\t\t\t\t\tstacked: true\n\t\t\t\t\t\t}],\n\t\t\t\t\t\tyAxes: [{\n\t\t\t\t\t\t\tstacked: true\n\t\t\t\t\t\t}]\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t});\n\n\t\t\tvar meta = chart.getDatasetMeta(1);\n\t\t\texpect(meta.controller.getStackIndex(0)).toBe(0);\n\t\t\texpect(meta.controller.getStackIndex(1)).toBe(0);\n\t\t\texpect(meta.controller.getStackIndex(2)).toBe(1);\n\t\t\texpect(meta.controller.getStackIndex(3)).toBe(1);\n\t\t});\n\t});\n\n\tit('should correctly get the stack index when a group is specified for all and the scale is not stacked', function() {\n\t\t[\n\t\t\t'bar',\n\t\t\t'horizontalBar'\n\t\t].forEach(function(barType) {\n\t\t\tvar chart = window.acquireChart({\n\t\t\t\ttype: barType,\n\t\t\t\tdata: {\n\t\t\t\t\tdatasets: [\n\t\t\t\t\t\t{data: [], stack: 'stack1'},\n\t\t\t\t\t\t{data: [], stack: 'stack1'},\n\t\t\t\t\t\t{data: [], stack: 'stack2'},\n\t\t\t\t\t\t{data: [], stack: 'stack2'}\n\t\t\t\t\t],\n\t\t\t\t\tlabels: []\n\t\t\t\t},\n\t\t\t\toptions: {\n\t\t\t\t\tscales: {\n\t\t\t\t\t\txAxes: [{\n\t\t\t\t\t\t\tstacked: false\n\t\t\t\t\t\t}],\n\t\t\t\t\t\tyAxes: [{\n\t\t\t\t\t\t\tstacked: false\n\t\t\t\t\t\t}]\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t});\n\n\t\t\tvar meta = chart.getDatasetMeta(1);\n\t\t\texpect(meta.controller.getStackIndex(0)).toBe(0);\n\t\t\texpect(meta.controller.getStackIndex(1)).toBe(1);\n\t\t\texpect(meta.controller.getStackIndex(2)).toBe(2);\n\t\t\texpect(meta.controller.getStackIndex(3)).toBe(3);\n\t\t});\n\t});\n\n\tit('should create rectangle elements for each data item during initialization', function() {\n\t\tvar chart = window.acquireChart({\n\t\t\ttype: 'bar',\n\t\t\tdata: {\n\t\t\t\tdatasets: [\n\t\t\t\t\t{data: []},\n\t\t\t\t\t{data: [10, 15, 0, -4]}\n\t\t\t\t],\n\t\t\t\tlabels: []\n\t\t\t}\n\t\t});\n\n\t\tvar meta = chart.getDatasetMeta(1);\n\t\texpect(meta.data.length).toBe(4); // 4 rectangles created\n\t\texpect(meta.data[0] instanceof Chart.elements.Rectangle).toBe(true);\n\t\texpect(meta.data[1] instanceof Chart.elements.Rectangle).toBe(true);\n\t\texpect(meta.data[2] instanceof Chart.elements.Rectangle).toBe(true);\n\t\texpect(meta.data[3] instanceof Chart.elements.Rectangle).toBe(true);\n\t});\n\n\tit('should update elements when modifying data', function() {\n\t\tvar chart = window.acquireChart({\n\t\t\ttype: 'bar',\n\t\t\tdata: {\n\t\t\t\tdatasets: [{\n\t\t\t\t\tdata: [1, 2],\n\t\t\t\t\tlabel: 'dataset1'\n\t\t\t\t}, {\n\t\t\t\t\tdata: [10, 15, 0, -4],\n\t\t\t\t\tlabel: 'dataset2',\n\t\t\t\t\tborderColor: 'blue'\n\t\t\t\t}],\n\t\t\t\tlabels: ['label1', 'label2', 'label3', 'label4']\n\t\t\t},\n\t\t\toptions: {\n\t\t\t\telements: {\n\t\t\t\t\trectangle: {\n\t\t\t\t\t\tbackgroundColor: 'red',\n\t\t\t\t\t\tborderSkipped: 'top',\n\t\t\t\t\t\tborderColor: 'green',\n\t\t\t\t\t\tborderWidth: 2,\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t\tscales: {\n\t\t\t\t\txAxes: [{\n\t\t\t\t\t\tid: 'firstXScaleID',\n\t\t\t\t\t\ttype: 'category'\n\t\t\t\t\t}],\n\t\t\t\t\tyAxes: [{\n\t\t\t\t\t\tid: 'firstYScaleID',\n\t\t\t\t\t\ttype: 'linear'\n\t\t\t\t\t}]\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\n\t\tvar meta = chart.getDatasetMeta(1);\n\t\texpect(meta.data.length).toBe(4);\n\n\t\tchart.data.datasets[1].data = [1, 2]; // remove 2 items\n\t\tchart.data.datasets[1].borderWidth = 1;\n\t\tchart.update();\n\n\t\texpect(meta.data.length).toBe(2);\n\n\t\t[\n\t\t\t{x: 113, y: 484},\n\t\t\t{x: 229, y: 32}\n\t\t].forEach(function(expected, i) {\n\t\t\texpect(meta.data[i]._datasetIndex).toBe(1);\n\t\t\texpect(meta.data[i]._index).toBe(i);\n\t\t\texpect(meta.data[i]._xScale).toBe(chart.scales.firstXScaleID);\n\t\t\texpect(meta.data[i]._yScale).toBe(chart.scales.firstYScaleID);\n\t\t\texpect(meta.data[i]._model.x).toBeCloseToPixel(expected.x);\n\t\t\texpect(meta.data[i]._model.y).toBeCloseToPixel(expected.y);\n\t\t\texpect(meta.data[i]._model.base).toBeCloseToPixel(936);\n\t\t\texpect(meta.data[i]._model.width).toBeCloseToPixel(40);\n\t\t\texpect(meta.data[i]._model).toEqual(jasmine.objectContaining({\n\t\t\t\tdatasetLabel: chart.data.datasets[1].label,\n\t\t\t\tlabel: chart.data.labels[i],\n\t\t\t\tbackgroundColor: 'red',\n\t\t\t\tborderSkipped: 'top',\n\t\t\t\tborderColor: 'blue',\n\t\t\t\tborderWidth: 1\n\t\t\t}));\n\t\t});\n\n\t\tchart.data.datasets[1].data = [1, 2, 3]; // add 1 items\n\t\tchart.update();\n\n\t\texpect(meta.data.length).toBe(3); // should add a new meta data item\n\t});\n\n\tit('should get the correct bar points when datasets of different types exist', function() {\n\t\tvar chart = window.acquireChart({\n\t\t\ttype: 'bar',\n\t\t\tdata: {\n\t\t\t\tdatasets: [{\n\t\t\t\t\tdata: [1, 2],\n\t\t\t\t\tlabel: 'dataset1'\n\t\t\t\t}, {\n\t\t\t\t\ttype: 'line',\n\t\t\t\t\tdata: [4, 6],\n\t\t\t\t\tlabel: 'dataset2'\n\t\t\t\t}, {\n\t\t\t\t\tdata: [8, 10],\n\t\t\t\t\tlabel: 'dataset3'\n\t\t\t\t}],\n\t\t\t\tlabels: ['label1', 'label2']\n\t\t\t},\n\t\t\toptions: {\n\t\t\t\tscales: {\n\t\t\t\t\txAxes: [{\n\t\t\t\t\t\ttype: 'category'\n\t\t\t\t\t}],\n\t\t\t\t\tyAxes: [{\n\t\t\t\t\t\ttype: 'linear'\n\t\t\t\t\t}]\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\n\t\tvar meta = chart.getDatasetMeta(2);\n\t\texpect(meta.data.length).toBe(2);\n\n\t\tvar bar1 = meta.data[0];\n\t\tvar bar2 = meta.data[1];\n\n\t\texpect(bar1._model.x).toBeCloseToPixel(187);\n\t\texpect(bar1._model.y).toBeCloseToPixel(132);\n\t\texpect(bar2._model.x).toBeCloseToPixel(422);\n\t\texpect(bar2._model.y).toBeCloseToPixel(32);\n\t});\n\n\tit('should update elements when the scales are stacked', function() {\n\t\tvar chart = window.acquireChart({\n\t\t\ttype: 'bar',\n\t\t\tdata: {\n\t\t\t\tdatasets: [{\n\t\t\t\t\tdata: [10, -10, 10, -10],\n\t\t\t\t\tlabel: 'dataset1'\n\t\t\t\t}, {\n\t\t\t\t\tdata: [10, 15, 0, -4],\n\t\t\t\t\tlabel: 'dataset2'\n\t\t\t\t}],\n\t\t\t\tlabels: ['label1', 'label2', 'label3', 'label4']\n\t\t\t},\n\t\t\toptions: {\n\t\t\t\tscales: {\n\t\t\t\t\txAxes: [{\n\t\t\t\t\t\ttype: 'category'\n\t\t\t\t\t}],\n\t\t\t\t\tyAxes: [{\n\t\t\t\t\t\ttype: 'linear',\n\t\t\t\t\t\tstacked: true\n\t\t\t\t\t}]\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\n\t\tvar meta0 = chart.getDatasetMeta(0);\n\n\t\t[\n\t\t\t{b: 290, w: 83 / 2, x: 63, y: 161},\n\t\t\t{b: 290, w: 83 / 2, x: 179, y: 419},\n\t\t\t{b: 290, w: 83 / 2, x: 295, y: 161},\n\t\t\t{b: 290, w: 83 / 2, x: 411, y: 419}\n\t\t].forEach(function(values, i) {\n\t\t\texpect(meta0.data[i]._model.base).toBeCloseToPixel(values.b);\n\t\t\texpect(meta0.data[i]._model.width).toBeCloseToPixel(values.w);\n\t\t\texpect(meta0.data[i]._model.x).toBeCloseToPixel(values.x);\n\t\t\texpect(meta0.data[i]._model.y).toBeCloseToPixel(values.y);\n\t\t});\n\n\t\tvar meta1 = chart.getDatasetMeta(1);\n\n\t\t[\n\t\t\t{b: 161, w: 83 / 2, x: 109, y: 32},\n\t\t\t{b: 290, w: 83 / 2, x: 225, y: 97},\n\t\t\t{b: 161, w: 83 / 2, x: 341, y: 161},\n\t\t\t{b: 419, w: 83 / 2, x: 457, y: 471}\n\t\t].forEach(function(values, i) {\n\t\t\texpect(meta1.data[i]._model.base).toBeCloseToPixel(values.b);\n\t\t\texpect(meta1.data[i]._model.width).toBeCloseToPixel(values.w);\n\t\t\texpect(meta1.data[i]._model.x).toBeCloseToPixel(values.x);\n\t\t\texpect(meta1.data[i]._model.y).toBeCloseToPixel(values.y);\n\t\t});\n\t});\n\n\tit('should update elements when the scales are stacked and the y axis has a user defined minimum', function() {\n\t\tvar chart = window.acquireChart({\n\t\t\ttype: 'bar',\n\t\t\tdata: {\n\t\t\t\tdatasets: [{\n\t\t\t\t\tdata: [50, 20, 10, 100],\n\t\t\t\t\tlabel: 'dataset1'\n\t\t\t\t}, {\n\t\t\t\t\tdata: [50, 80, 90, 0],\n\t\t\t\t\tlabel: 'dataset2'\n\t\t\t\t}],\n\t\t\t\tlabels: ['label1', 'label2', 'label3', 'label4']\n\t\t\t},\n\t\t\toptions: {\n\t\t\t\tscales: {\n\t\t\t\t\txAxes: [{\n\t\t\t\t\t\ttype: 'category'\n\t\t\t\t\t}],\n\t\t\t\t\tyAxes: [{\n\t\t\t\t\t\ttype: 'linear',\n\t\t\t\t\t\tstacked: true,\n\t\t\t\t\t\tticks: {\n\t\t\t\t\t\t\tmin: 50,\n\t\t\t\t\t\t\tmax: 100\n\t\t\t\t\t\t}\n\t\t\t\t\t}]\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\n\t\tvar meta0 = chart.getDatasetMeta(0);\n\n\t\t[\n\t\t\t{b: 936, w: 83 / 2, x: 65.5, y: 484},\n\t\t\t{b: 936, w: 83 / 2, x: 180.5, y: 755},\n\t\t\t{b: 936, w: 83 / 2, x: 296.5, y: 846},\n\t\t\t{b: 936, w: 83 / 2, x: 411.5, y: 32}\n\t\t].forEach(function(values, i) {\n\t\t\texpect(meta0.data[i]._model.base).toBeCloseToPixel(values.b);\n\t\t\texpect(meta0.data[i]._model.width).toBeCloseToPixel(values.w);\n\t\t\texpect(meta0.data[i]._model.x).toBeCloseToPixel(values.x);\n\t\t\texpect(meta0.data[i]._model.y).toBeCloseToPixel(values.y);\n\t\t});\n\n\t\tvar meta1 = chart.getDatasetMeta(1);\n\n\t\t[\n\t\t\t{b: 484, w: 83 / 2, x: 111.5, y: 32},\n\t\t\t{b: 755, w: 83 / 2, x: 226.5, y: 32},\n\t\t\t{b: 846, w: 83 / 2, x: 342.5, y: 32},\n\t\t\t{b: 32, w: 83 / 2, x: 457.5, y: 32}\n\t\t].forEach(function(values, i) {\n\t\t\texpect(meta1.data[i]._model.base).toBeCloseToPixel(values.b);\n\t\t\texpect(meta1.data[i]._model.width).toBeCloseToPixel(values.w);\n\t\t\texpect(meta1.data[i]._model.x).toBeCloseToPixel(values.x);\n\t\t\texpect(meta1.data[i]._model.y).toBeCloseToPixel(values.y);\n\t\t});\n\t});\n\n\tit('should update elements when only the category scale is stacked', function() {\n\t\tvar chart = window.acquireChart({\n\t\t\ttype: 'bar',\n\t\t\tdata: {\n\t\t\t\tdatasets: [{\n\t\t\t\t\tdata: [20, -10, 10, -10],\n\t\t\t\t\tlabel: 'dataset1'\n\t\t\t\t}, {\n\t\t\t\t\tdata: [10, 15, 0, -14],\n\t\t\t\t\tlabel: 'dataset2'\n\t\t\t\t}],\n\t\t\t\tlabels: ['label1', 'label2', 'label3', 'label4']\n\t\t\t},\n\t\t\toptions: {\n\t\t\t\tscales: {\n\t\t\t\t\txAxes: [{\n\t\t\t\t\t\ttype: 'category',\n\t\t\t\t\t\tstacked: true\n\t\t\t\t\t}],\n\t\t\t\t\tyAxes: [{\n\t\t\t\t\t\ttype: 'linear'\n\t\t\t\t\t}]\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\n\t\tvar meta0 = chart.getDatasetMeta(0);\n\n\t\t[\n\t\t\t{b: 290, w: 83, x: 86, y: 32},\n\t\t\t{b: 290, w: 83, x: 202, y: 419},\n\t\t\t{b: 290, w: 83, x: 318, y: 161},\n\t\t\t{b: 290, w: 83, x: 434, y: 419}\n\t\t].forEach(function(values, i) {\n\t\t\texpect(meta0.data[i]._model.base).toBeCloseToPixel(values.b);\n\t\t\texpect(meta0.data[i]._model.width).toBeCloseToPixel(values.w);\n\t\t\texpect(meta0.data[i]._model.x).toBeCloseToPixel(values.x);\n\t\t\texpect(meta0.data[i]._model.y).toBeCloseToPixel(values.y);\n\t\t});\n\n\t\tvar meta1 = chart.getDatasetMeta(1);\n\n\t\t[\n\t\t\t{b: 290, w: 83, x: 86, y: 161},\n\t\t\t{b: 290, w: 83, x: 202, y: 97},\n\t\t\t{b: 290, w: 83, x: 318, y: 290},\n\t\t\t{b: 290, w: 83, x: 434, y: 471}\n\t\t].forEach(function(values, i) {\n\t\t\texpect(meta1.data[i]._model.base).toBeCloseToPixel(values.b);\n\t\t\texpect(meta1.data[i]._model.width).toBeCloseToPixel(values.w);\n\t\t\texpect(meta1.data[i]._model.x).toBeCloseToPixel(values.x);\n\t\t\texpect(meta1.data[i]._model.y).toBeCloseToPixel(values.y);\n\t\t});\n\t});\n\n\tit('should update elements when the scales are stacked and data is strings', function() {\n\t\tvar chart = window.acquireChart({\n\t\t\ttype: 'bar',\n\t\t\tdata: {\n\t\t\t\tdatasets: [{\n\t\t\t\t\tdata: ['10', '-10', '10', '-10'],\n\t\t\t\t\tlabel: 'dataset1'\n\t\t\t\t}, {\n\t\t\t\t\tdata: ['10', '15', '0', '-4'],\n\t\t\t\t\tlabel: 'dataset2'\n\t\t\t\t}],\n\t\t\t\tlabels: ['label1', 'label2', 'label3', 'label4']\n\t\t\t},\n\t\t\toptions: {\n\t\t\t\tscales: {\n\t\t\t\t\txAxes: [{\n\t\t\t\t\t\ttype: 'category'\n\t\t\t\t\t}],\n\t\t\t\t\tyAxes: [{\n\t\t\t\t\t\ttype: 'linear',\n\t\t\t\t\t\tstacked: true\n\t\t\t\t\t}]\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\n\t\tvar meta0 = chart.getDatasetMeta(0);\n\n\t\t[\n\t\t\t{b: 290, w: 83 / 2, x: 63, y: 161},\n\t\t\t{b: 290, w: 83 / 2, x: 179, y: 419},\n\t\t\t{b: 290, w: 83 / 2, x: 295, y: 161},\n\t\t\t{b: 290, w: 83 / 2, x: 411, y: 419}\n\t\t].forEach(function(values, i) {\n\t\t\texpect(meta0.data[i]._model.base).toBeCloseToPixel(values.b);\n\t\t\texpect(meta0.data[i]._model.width).toBeCloseToPixel(values.w);\n\t\t\texpect(meta0.data[i]._model.x).toBeCloseToPixel(values.x);\n\t\t\texpect(meta0.data[i]._model.y).toBeCloseToPixel(values.y);\n\t\t});\n\n\t\tvar meta1 = chart.getDatasetMeta(1);\n\n\t\t[\n\t\t\t{b: 161, w: 83 / 2, x: 109, y: 32},\n\t\t\t{b: 290, w: 83 / 2, x: 225, y: 97},\n\t\t\t{b: 161, w: 83 / 2, x: 341, y: 161},\n\t\t\t{b: 419, w: 83 / 2, x: 457, y: 471}\n\t\t].forEach(function(values, i) {\n\t\t\texpect(meta1.data[i]._model.base).toBeCloseToPixel(values.b);\n\t\t\texpect(meta1.data[i]._model.width).toBeCloseToPixel(values.w);\n\t\t\texpect(meta1.data[i]._model.x).toBeCloseToPixel(values.x);\n\t\t\texpect(meta1.data[i]._model.y).toBeCloseToPixel(values.y);\n\t\t});\n\t});\n\n\tit('should get the correct bar points for grouped stacked chart if the group name is same', function() {\n\t\tvar chart = window.acquireChart({\n\t\t\ttype: 'bar',\n\t\t\tdata: {\n\t\t\t\tdatasets: [{\n\t\t\t\t\tdata: [10, -10, 10, -10],\n\t\t\t\t\tlabel: 'dataset1',\n\t\t\t\t\tstack: 'stack1'\n\t\t\t\t}, {\n\t\t\t\t\tdata: [10, 15, 0, -4],\n\t\t\t\t\tlabel: 'dataset2',\n\t\t\t\t\tstack: 'stack1'\n\t\t\t\t}],\n\t\t\t\tlabels: ['label1', 'label2', 'label3', 'label4']\n\t\t\t},\n\t\t\toptions: {\n\t\t\t\tscales: {\n\t\t\t\t\txAxes: [{\n\t\t\t\t\t\ttype: 'category'\n\t\t\t\t\t}],\n\t\t\t\t\tyAxes: [{\n\t\t\t\t\t\ttype: 'linear',\n\t\t\t\t\t\tstacked: true\n\t\t\t\t\t}]\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\n\t\tvar meta0 = chart.getDatasetMeta(0);\n\n\t\t[\n\t\t\t{b: 290, w: 83, x: 86, y: 161},\n\t\t\t{b: 290, w: 83, x: 202, y: 419},\n\t\t\t{b: 290, w: 83, x: 318, y: 161},\n\t\t\t{b: 290, w: 83, x: 434, y: 419}\n\t\t].forEach(function(values, i) {\n\t\t\texpect(meta0.data[i]._model.base).toBeCloseToPixel(values.b);\n\t\t\texpect(meta0.data[i]._model.width).toBeCloseToPixel(values.w);\n\t\t\texpect(meta0.data[i]._model.x).toBeCloseToPixel(values.x);\n\t\t\texpect(meta0.data[i]._model.y).toBeCloseToPixel(values.y);\n\t\t});\n\n\t\tvar meta = chart.getDatasetMeta(1);\n\n\t\t[\n\t\t\t{b: 161, w: 83, x: 86, y: 32},\n\t\t\t{b: 290, w: 83, x: 202, y: 97},\n\t\t\t{b: 161, w: 83, x: 318, y: 161},\n\t\t\t{b: 419, w: 83, x: 434, y: 471}\n\t\t].forEach(function(values, i) {\n\t\t\texpect(meta.data[i]._model.base).toBeCloseToPixel(values.b);\n\t\t\texpect(meta.data[i]._model.width).toBeCloseToPixel(values.w);\n\t\t\texpect(meta.data[i]._model.x).toBeCloseToPixel(values.x);\n\t\t\texpect(meta.data[i]._model.y).toBeCloseToPixel(values.y);\n\t\t});\n\t});\n\n\tit('should get the correct bar points for grouped stacked chart if the group name is different', function() {\n\t\tvar chart = window.acquireChart({\n\t\t\ttype: 'bar',\n\t\t\tdata: {\n\t\t\t\tdatasets: [{\n\t\t\t\t\tdata: [1, 2],\n\t\t\t\t\tstack: 'stack1'\n\t\t\t\t}, {\n\t\t\t\t\tdata: [1, 2],\n\t\t\t\t\tstack: 'stack2'\n\t\t\t\t}],\n\t\t\t\tlabels: ['label1', 'label2', 'label3', 'label4']\n\t\t\t},\n\t\t\toptions: {\n\t\t\t\tscales: {\n\t\t\t\t\txAxes: [{\n\t\t\t\t\t\ttype: 'category'\n\t\t\t\t\t}],\n\t\t\t\t\tyAxes: [{\n\t\t\t\t\t\tstacked: true,\n\t\t\t\t\t\ttype: 'linear'\n\t\t\t\t\t}]\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\n\t\tvar meta = chart.getDatasetMeta(1);\n\n\t\t[\n\t\t\t{x: 108, y: 258},\n\t\t\t{x: 224, y: 32}\n\t\t].forEach(function(values, i) {\n\t\t\texpect(meta.data[i]._model.base).toBeCloseToPixel(484);\n\t\t\texpect(meta.data[i]._model.width).toBeCloseToPixel(40);\n\t\t\texpect(meta.data[i]._model.x).toBeCloseToPixel(values.x);\n\t\t\texpect(meta.data[i]._model.y).toBeCloseToPixel(values.y);\n\t\t});\n\t});\n\n\tit('should get the correct bar points for grouped stacked chart', function() {\n\t\tvar chart = window.acquireChart({\n\t\t\ttype: 'bar',\n\t\t\tdata: {\n\t\t\t\tdatasets: [{\n\t\t\t\t\tdata: [1, 2],\n\t\t\t\t\tstack: 'stack1'\n\t\t\t\t}, {\n\t\t\t\t\tdata: [0.5, 1],\n\t\t\t\t\tstack: 'stack2'\n\t\t\t\t}, {\n\t\t\t\t\tdata: [0.5, 1],\n\t\t\t\t\tstack: 'stack2'\n\t\t\t\t}],\n\t\t\t\tlabels: ['label1', 'label2', 'label3', 'label4']\n\t\t\t},\n\t\t\toptions: {\n\t\t\t\tscales: {\n\t\t\t\t\txAxes: [{\n\t\t\t\t\t\ttype: 'category'\n\t\t\t\t\t}],\n\t\t\t\t\tyAxes: [{\n\t\t\t\t\t\tstacked: true,\n\t\t\t\t\t\ttype: 'linear'\n\t\t\t\t\t}]\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\n\t\tvar meta = chart.getDatasetMeta(2);\n\n\t\t[\n\t\t\t{b: 371, x: 108, y: 258},\n\t\t\t{b: 258, x: 224, y: 32}\n\t\t].forEach(function(values, i) {\n\t\t\texpect(meta.data[i]._model.base).toBeCloseToPixel(values.b);\n\t\t\texpect(meta.data[i]._model.width).toBeCloseToPixel(40);\n\t\t\texpect(meta.data[i]._model.x).toBeCloseToPixel(values.x);\n\t\t\texpect(meta.data[i]._model.y).toBeCloseToPixel(values.y);\n\t\t});\n\t});\n\n\tit('should update elements when the scales are stacked and the y axis is logarithmic', function() {\n\t\tvar chart = window.acquireChart({\n\t\t\ttype: 'bar',\n\t\t\tdata: {\n\t\t\t\tdatasets: [{\n\t\t\t\t\tdata: [10, 100, 10, 100],\n\t\t\t\t\tlabel: 'dataset1'\n\t\t\t\t}, {\n\t\t\t\t\tdata: [100, 10, 0, 100],\n\t\t\t\t\tlabel: 'dataset2'\n\t\t\t\t}],\n\t\t\t\tlabels: ['label1', 'label2', 'label3', 'label4']\n\t\t\t},\n\t\t\toptions: {\n\t\t\t\tscales: {\n\t\t\t\t\txAxes: [{\n\t\t\t\t\t\ttype: 'category',\n\t\t\t\t\t\tstacked: true,\n\t\t\t\t\t\tbarPercentage: 1\n\t\t\t\t\t}],\n\t\t\t\t\tyAxes: [{\n\t\t\t\t\t\ttype: 'logarithmic',\n\t\t\t\t\t\tstacked: true,\n\t\t\t\t\t}]\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\n\t\tvar meta0 = chart.getDatasetMeta(0);\n\n\t\t[\n\t\t\t{b: 484, w: 92, x: 94, y: 484},\n\t\t\t{b: 484, w: 92, x: 208, y: 136},\n\t\t\t{b: 484, w: 92, x: 322, y: 484},\n\t\t\t{b: 484, w: 92, x: 436, y: 136}\n\t\t].forEach(function(values, i) {\n\t\t\texpect(meta0.data[i]._model.base).toBeCloseToPixel(values.b);\n\t\t\texpect(meta0.data[i]._model.width).toBeCloseToPixel(values.w);\n\t\t\texpect(meta0.data[i]._model.x).toBeCloseToPixel(values.x);\n\t\t\texpect(meta0.data[i]._model.y).toBeCloseToPixel(values.y);\n\t\t});\n\n\t\tvar meta1 = chart.getDatasetMeta(1);\n\n\t\t[\n\t\t\t{b: 484, w: 92, x: 94, y: 122},\n\t\t\t{b: 136, w: 92, x: 208, y: 122},\n\t\t\t{b: 484, w: 92, x: 322, y: 484},\n\t\t\t{b: 136, w: 92, x: 436, y: 32}\n\t\t].forEach(function(values, i) {\n\t\t\texpect(meta1.data[i]._model.base).toBeCloseToPixel(values.b);\n\t\t\texpect(meta1.data[i]._model.width).toBeCloseToPixel(values.w);\n\t\t\texpect(meta1.data[i]._model.x).toBeCloseToPixel(values.x);\n\t\t\texpect(meta1.data[i]._model.y).toBeCloseToPixel(values.y);\n\t\t});\n\t});\n\n\tit('should draw all bars', function() {\n\t\tvar chart = window.acquireChart({\n\t\t\ttype: 'bar',\n\t\t\tdata: {\n\t\t\t\tdatasets: [{\n\t\t\t\t\tdata: [],\n\t\t\t\t}, {\n\t\t\t\t\tdata: [10, 15, 0, -4],\n\t\t\t\t\tlabel: 'dataset2'\n\t\t\t\t}],\n\t\t\t\tlabels: ['label1', 'label2', 'label3', 'label4']\n\t\t\t}\n\t\t});\n\n\t\tvar meta = chart.getDatasetMeta(1);\n\n\t\tspyOn(meta.data[0], 'draw');\n\t\tspyOn(meta.data[1], 'draw');\n\t\tspyOn(meta.data[2], 'draw');\n\t\tspyOn(meta.data[3], 'draw');\n\n\t\tchart.update();\n\n\t\texpect(meta.data[0].draw.calls.count()).toBe(1);\n\t\texpect(meta.data[1].draw.calls.count()).toBe(1);\n\t\texpect(meta.data[2].draw.calls.count()).toBe(1);\n\t\texpect(meta.data[3].draw.calls.count()).toBe(1);\n\t});\n\n\tit('should set hover styles on rectangles', function() {\n\t\tvar chart = window.acquireChart({\n\t\t\ttype: 'bar',\n\t\t\tdata: {\n\t\t\t\tdatasets: [{\n\t\t\t\t\tdata: [],\n\t\t\t\t}, {\n\t\t\t\t\tdata: [10, 15, 0, -4],\n\t\t\t\t\tlabel: 'dataset2'\n\t\t\t\t}],\n\t\t\t\tlabels: ['label1', 'label2', 'label3', 'label4']\n\t\t\t},\n\t\t\toptions: {\n\t\t\t\telements: {\n\t\t\t\t\trectangle: {\n\t\t\t\t\t\tbackgroundColor: 'rgb(255, 0, 0)',\n\t\t\t\t\t\tborderColor: 'rgb(0, 0, 255)',\n\t\t\t\t\t\tborderWidth: 2,\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\n\t\tvar meta = chart.getDatasetMeta(1);\n\t\tvar bar = meta.data[0];\n\n\t\tmeta.controller.setHoverStyle(bar);\n\t\texpect(bar._model.backgroundColor).toBe('rgb(230, 0, 0)');\n\t\texpect(bar._model.borderColor).toBe('rgb(0, 0, 230)');\n\t\texpect(bar._model.borderWidth).toBe(2);\n\n\t\t// Set a dataset style\n\t\tchart.data.datasets[1].hoverBackgroundColor = 'rgb(128, 128, 128)';\n\t\tchart.data.datasets[1].hoverBorderColor = 'rgb(0, 0, 0)';\n\t\tchart.data.datasets[1].hoverBorderWidth = 5;\n\n\t\tmeta.controller.setHoverStyle(bar);\n\t\texpect(bar._model.backgroundColor).toBe('rgb(128, 128, 128)');\n\t\texpect(bar._model.borderColor).toBe('rgb(0, 0, 0)');\n\t\texpect(bar._model.borderWidth).toBe(5);\n\n\t\t// Should work with array styles so that we can set per bar\n\t\tchart.data.datasets[1].hoverBackgroundColor = ['rgb(255, 255, 255)', 'rgb(128, 128, 128)'];\n\t\tchart.data.datasets[1].hoverBorderColor = ['rgb(9, 9, 9)', 'rgb(0, 0, 0)'];\n\t\tchart.data.datasets[1].hoverBorderWidth = [2.5, 5];\n\n\t\tmeta.controller.setHoverStyle(bar);\n\t\texpect(bar._model.backgroundColor).toBe('rgb(255, 255, 255)');\n\t\texpect(bar._model.borderColor).toBe('rgb(9, 9, 9)');\n\t\texpect(bar._model.borderWidth).toBe(2.5);\n\n\t\t// Should allow a custom style\n\t\tbar.custom = {\n\t\t\thoverBackgroundColor: 'rgb(255, 0, 0)',\n\t\t\thoverBorderColor: 'rgb(0, 255, 0)',\n\t\t\thoverBorderWidth: 1.5\n\t\t};\n\n\t\tmeta.controller.setHoverStyle(bar);\n\t\texpect(bar._model.backgroundColor).toBe('rgb(255, 0, 0)');\n\t\texpect(bar._model.borderColor).toBe('rgb(0, 255, 0)');\n\t\texpect(bar._model.borderWidth).toBe(1.5);\n\t});\n\n\tit('should remove a hover style from a bar', function() {\n\t\tvar chart = window.acquireChart({\n\t\t\ttype: 'bar',\n\t\t\tdata: {\n\t\t\t\tdatasets: [{\n\t\t\t\t\tdata: [],\n\t\t\t\t}, {\n\t\t\t\t\tdata: [10, 15, 0, -4],\n\t\t\t\t\tlabel: 'dataset2'\n\t\t\t\t}],\n\t\t\t\tlabels: ['label1', 'label2', 'label3', 'label4']\n\t\t\t},\n\t\t\toptions: {\n\t\t\t\telements: {\n\t\t\t\t\trectangle: {\n\t\t\t\t\t\tbackgroundColor: 'rgb(255, 0, 0)',\n\t\t\t\t\t\tborderColor: 'rgb(0, 0, 255)',\n\t\t\t\t\t\tborderWidth: 2,\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\n\t\tvar meta = chart.getDatasetMeta(1);\n\t\tvar bar = meta.data[0];\n\n\t\t// Change default\n\t\tchart.options.elements.rectangle.backgroundColor = 'rgb(128, 128, 128)';\n\t\tchart.options.elements.rectangle.borderColor = 'rgb(15, 15, 15)';\n\t\tchart.options.elements.rectangle.borderWidth = 3.14;\n\n\t\t// Remove to defaults\n\t\tmeta.controller.removeHoverStyle(bar);\n\t\texpect(bar._model.backgroundColor).toBe('rgb(128, 128, 128)');\n\t\texpect(bar._model.borderColor).toBe('rgb(15, 15, 15)');\n\t\texpect(bar._model.borderWidth).toBe(3.14);\n\n\t\t// Should work with array styles so that we can set per bar\n\t\tchart.data.datasets[1].backgroundColor = ['rgb(255, 255, 255)', 'rgb(128, 128, 128)'];\n\t\tchart.data.datasets[1].borderColor = ['rgb(9, 9, 9)', 'rgb(0, 0, 0)'];\n\t\tchart.data.datasets[1].borderWidth = [2.5, 5];\n\n\t\tmeta.controller.removeHoverStyle(bar);\n\t\texpect(bar._model.backgroundColor).toBe('rgb(255, 255, 255)');\n\t\texpect(bar._model.borderColor).toBe('rgb(9, 9, 9)');\n\t\texpect(bar._model.borderWidth).toBe(2.5);\n\n\t\t// Should allow a custom style\n\t\tbar.custom = {\n\t\t\tbackgroundColor: 'rgb(255, 0, 0)',\n\t\t\tborderColor: 'rgb(0, 255, 0)',\n\t\t\tborderWidth: 1.5\n\t\t};\n\n\t\tmeta.controller.removeHoverStyle(bar);\n\t\texpect(bar._model.backgroundColor).toBe('rgb(255, 0, 0)');\n\t\texpect(bar._model.borderColor).toBe('rgb(0, 255, 0)');\n\t\texpect(bar._model.borderWidth).toBe(1.5);\n\t});\n\n\tdescribe('Bar width', function() {\n\t\tbeforeEach(function() {\n\t\t\t// 2 datasets\n\t\t\tthis.data = {\n\t\t\t\tlabels: ['January', 'February', 'March', 'April', 'May', 'June', 'July'],\n\t\t\t\tdatasets: [{\n\t\t\t\t\tdata: [10, 20, 30, 40, 50, 60, 70],\n\t\t\t\t}, {\n\t\t\t\t\tdata: [10, 20, 30, 40, 50, 60, 70],\n\t\t\t\t}]\n\t\t\t};\n\t\t});\n\n\t\tafterEach(function() {\n\t\t\tvar chart = window.acquireChart(this.config);\n\t\t\tvar meta = chart.getDatasetMeta(0);\n\t\t\tvar xScale = chart.scales[meta.xAxisID];\n\n\t\t\tvar categoryPercentage = xScale.options.categoryPercentage;\n\t\t\tvar barPercentage = xScale.options.barPercentage;\n\t\t\tvar stacked = xScale.options.stacked;\n\n\t\t\tvar totalBarWidth = 0;\n\t\t\tfor (var i = 0; i < chart.data.datasets.length; i++) {\n\t\t\t\tvar bars = chart.getDatasetMeta(i).data;\n\t\t\t\tfor (var j = xScale.minIndex; j <= xScale.maxIndex; j++) {\n\t\t\t\t\ttotalBarWidth += bars[j]._model.width;\n\t\t\t\t}\n\t\t\t\tif (stacked) {\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tvar actualValue = totalBarWidth;\n\t\t\tvar expectedValue = xScale.width * categoryPercentage * barPercentage;\n\t\t\texpect(actualValue).toBeCloseToPixel(expectedValue);\n\n\t\t});\n\n\t\tit('should correctly set bar width when min and max option is set.', function() {\n\t\t\tthis.config = {\n\t\t\t\ttype: 'bar',\n\t\t\t\tdata: this.data,\n\t\t\t\toptions: {\n\t\t\t\t\tscales: {\n\t\t\t\t\t\txAxes: [{\n\t\t\t\t\t\t\tticks: {\n\t\t\t\t\t\t\t\tmin: 'March',\n\t\t\t\t\t\t\t\tmax: 'May',\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t}]\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t};\n\t\t});\n\n\t\tit('should correctly set bar width when scale are stacked with min and max options.', function() {\n\t\t\tthis.config = {\n\t\t\t\ttype: 'bar',\n\t\t\t\tdata: this.data,\n\t\t\t\toptions: {\n\t\t\t\t\tscales: {\n\t\t\t\t\t\txAxes: [{\n\t\t\t\t\t\t\tticks: {\n\t\t\t\t\t\t\t\tmin: 'March',\n\t\t\t\t\t\t\t\tmax: 'May',\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}],\n\t\t\t\t\t\tyAxes: [{\n\t\t\t\t\t\t\tstacked: true\n\t\t\t\t\t\t}]\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t};\n\t\t});\n\t});\n\n\tdescribe('Bar height (horizontalBar type)', function() {\n\t\tbeforeEach(function() {\n\t\t\t// 2 datasets\n\t\t\tthis.data = {\n\t\t\t\tlabels: ['January', 'February', 'March', 'April', 'May', 'June', 'July'],\n\t\t\t\tdatasets: [{\n\t\t\t\t\tdata: [10, 20, 30, 40, 50, 60, 70],\n\t\t\t\t}, {\n\t\t\t\t\tdata: [10, 20, 30, 40, 50, 60, 70],\n\t\t\t\t}]\n\t\t\t};\n\t\t});\n\n\t\tafterEach(function() {\n\t\t\tvar chart = window.acquireChart(this.config);\n\t\t\tvar meta = chart.getDatasetMeta(0);\n\t\t\tvar yScale = chart.scales[meta.yAxisID];\n\n\t\t\tvar categoryPercentage = yScale.options.categoryPercentage;\n\t\t\tvar barPercentage = yScale.options.barPercentage;\n\t\t\tvar stacked = yScale.options.stacked;\n\n\t\t\tvar totalBarHeight = 0;\n\t\t\tfor (var i = 0; i < chart.data.datasets.length; i++) {\n\t\t\t\tvar bars = chart.getDatasetMeta(i).data;\n\t\t\t\tfor (var j = yScale.minIndex; j <= yScale.maxIndex; j++) {\n\t\t\t\t\ttotalBarHeight += bars[j]._model.height;\n\t\t\t\t}\n\t\t\t\tif (stacked) {\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tvar actualValue = totalBarHeight;\n\t\t\tvar expectedValue = yScale.height * categoryPercentage * barPercentage;\n\t\t\texpect(actualValue).toBeCloseToPixel(expectedValue);\n\n\t\t});\n\n\t\tit('should correctly set bar height when min and max option is set.', function() {\n\t\t\tthis.config = {\n\t\t\t\ttype: 'horizontalBar',\n\t\t\t\tdata: this.data,\n\t\t\t\toptions: {\n\t\t\t\t\tscales: {\n\t\t\t\t\t\tyAxes: [{\n\t\t\t\t\t\t\tticks: {\n\t\t\t\t\t\t\t\tmin: 'March',\n\t\t\t\t\t\t\t\tmax: 'May',\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t}]\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t};\n\t\t});\n\n\t\tit('should correctly set bar height when scale are stacked with min and max options.', function() {\n\t\t\tthis.config = {\n\t\t\t\ttype: 'horizontalBar',\n\t\t\t\tdata: this.data,\n\t\t\t\toptions: {\n\t\t\t\t\tscales: {\n\t\t\t\t\t\txAxes: [{\n\t\t\t\t\t\t\tstacked: true\n\t\t\t\t\t\t}],\n\t\t\t\t\t\tyAxes: [{\n\t\t\t\t\t\t\tticks: {\n\t\t\t\t\t\t\t\tmin: 'March',\n\t\t\t\t\t\t\t\tmax: 'May',\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}]\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t};\n\t\t});\n\t});\n});\n"
  },
  {
    "path": "app_backend/static/plugin/Chart.js-2.6.0/test/specs/controller.bubble.tests.js",
    "content": "// Test the bubble controller\ndescribe('Bubble controller tests', function() {\n\tit('should be constructed', function() {\n\t\tvar chart = window.acquireChart({\n\t\t\ttype: 'bubble',\n\t\t\tdata: {\n\t\t\t\tdatasets: [{\n\t\t\t\t\tdata: []\n\t\t\t\t}]\n\t\t\t}\n\t\t});\n\n\t\tvar meta = chart.getDatasetMeta(0);\n\t\texpect(meta.type).toBe('bubble');\n\t\texpect(meta.controller).not.toBe(undefined);\n\t\texpect(meta.controller.index).toBe(0);\n\t\texpect(meta.data).toEqual([]);\n\n\t\tmeta.controller.updateIndex(1);\n\t\texpect(meta.controller.index).toBe(1);\n\t});\n\n\tit('should use the first scale IDs if the dataset does not specify them', function() {\n\t\tvar chart = window.acquireChart({\n\t\t\ttype: 'bubble',\n\t\t\tdata: {\n\t\t\t\tdatasets: [{\n\t\t\t\t\tdata: []\n\t\t\t\t}]\n\t\t\t},\n\t\t\toptions: {\n\t\t\t\tscales: {\n\t\t\t\t\txAxes: [{\n\t\t\t\t\t\tid: 'firstXScaleID'\n\t\t\t\t\t}],\n\t\t\t\t\tyAxes: [{\n\t\t\t\t\t\tid: 'firstYScaleID'\n\t\t\t\t\t}]\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\n\t\tvar meta = chart.getDatasetMeta(0);\n\n\t\texpect(meta.xAxisID).toBe('firstXScaleID');\n\t\texpect(meta.yAxisID).toBe('firstYScaleID');\n\t});\n\n\tit('should create point elements for each data item during initialization', function() {\n\t\tvar chart = window.acquireChart({\n\t\t\ttype: 'bubble',\n\t\t\tdata: {\n\t\t\t\tdatasets: [{\n\t\t\t\t\tdata: [10, 15, 0, -4]\n\t\t\t\t}]\n\t\t\t}\n\t\t});\n\n\t\tvar meta = chart.getDatasetMeta(0);\n\n\t\texpect(meta.data.length).toBe(4); // 4 points created\n\t\texpect(meta.data[0] instanceof Chart.elements.Point).toBe(true);\n\t\texpect(meta.data[1] instanceof Chart.elements.Point).toBe(true);\n\t\texpect(meta.data[2] instanceof Chart.elements.Point).toBe(true);\n\t\texpect(meta.data[3] instanceof Chart.elements.Point).toBe(true);\n\t});\n\n\tit('should draw all elements', function() {\n\t\tvar chart = window.acquireChart({\n\t\t\ttype: 'bubble',\n\t\t\tdata: {\n\t\t\t\tdatasets: [{\n\t\t\t\t\tdata: [10, 15, 0, -4]\n\t\t\t\t}]\n\t\t\t},\n\t\t\toptions: {\n\t\t\t\tanimation: false,\n\t\t\t\tshowLines: true\n\t\t\t}\n\t\t});\n\n\t\tvar meta = chart.getDatasetMeta(0);\n\n\t\tspyOn(meta.data[0], 'draw');\n\t\tspyOn(meta.data[1], 'draw');\n\t\tspyOn(meta.data[2], 'draw');\n\t\tspyOn(meta.data[3], 'draw');\n\n\t\tchart.update();\n\n\t\texpect(meta.data[0].draw.calls.count()).toBe(1);\n\t\texpect(meta.data[1].draw.calls.count()).toBe(1);\n\t\texpect(meta.data[2].draw.calls.count()).toBe(1);\n\t\texpect(meta.data[3].draw.calls.count()).toBe(1);\n\t});\n\n\tit('should update elements when modifying style', function() {\n\t\tvar chart = window.acquireChart({\n\t\t\ttype: 'bubble',\n\t\t\tdata: {\n\t\t\t\tdatasets: [{\n\t\t\t\t\tdata: [{\n\t\t\t\t\t\tx: 10,\n\t\t\t\t\t\ty: 10,\n\t\t\t\t\t\tr: 5\n\t\t\t\t\t}, {\n\t\t\t\t\t\tx: -15,\n\t\t\t\t\t\ty: -10,\n\t\t\t\t\t\tr: 1\n\t\t\t\t\t}, {\n\t\t\t\t\t\tx: 0,\n\t\t\t\t\t\ty: -9,\n\t\t\t\t\t\tr: 2\n\t\t\t\t\t}, {\n\t\t\t\t\t\tx: -4,\n\t\t\t\t\t\ty: 10,\n\t\t\t\t\t\tr: 1\n\t\t\t\t\t}]\n\t\t\t\t}],\n\t\t\t\tlabels: ['label1', 'label2', 'label3', 'label4']\n\t\t\t},\n\t\t\toptions: {\n\t\t\t\tscales: {\n\t\t\t\t\txAxes: [{\n\t\t\t\t\t\ttype: 'category'\n\t\t\t\t\t}],\n\t\t\t\t\tyAxes: [{\n\t\t\t\t\t\ttype: 'linear'\n\t\t\t\t\t}]\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\n\t\tvar meta = chart.getDatasetMeta(0);\n\n\t\t[\n\t\t\t{r: 5, x: 28, y: 32},\n\t\t\t{r: 1, x: 183, y: 484},\n\t\t\t{r: 2, x: 338, y: 461},\n\t\t\t{r: 1, x: 492, y: 32}\n\t\t].forEach(function(expected, i) {\n\t\t\texpect(meta.data[i]._model.radius).toBe(expected.r);\n\t\t\texpect(meta.data[i]._model.x).toBeCloseToPixel(expected.x);\n\t\t\texpect(meta.data[i]._model.y).toBeCloseToPixel(expected.y);\n\t\t\texpect(meta.data[i]._model).toEqual(jasmine.objectContaining({\n\t\t\t\tbackgroundColor: Chart.defaults.global.defaultColor,\n\t\t\t\tborderColor: Chart.defaults.global.defaultColor,\n\t\t\t\tborderWidth: 1,\n\t\t\t\thitRadius: 1,\n\t\t\t\tskip: false\n\t\t\t}));\n\t\t});\n\n\t\t// Use dataset level styles for lines & points\n\t\tchart.data.datasets[0].backgroundColor = 'rgb(98, 98, 98)';\n\t\tchart.data.datasets[0].borderColor = 'rgb(8, 8, 8)';\n\t\tchart.data.datasets[0].borderWidth = 0.55;\n\n\t\t// point styles\n\t\tchart.data.datasets[0].radius = 22;\n\t\tchart.data.datasets[0].hitRadius = 3.3;\n\n\t\tchart.update();\n\n\t\tfor (var i=0; i<4; ++i) {\n\t\t\texpect(meta.data[i]._model).toEqual(jasmine.objectContaining({\n\t\t\t\tbackgroundColor: 'rgb(98, 98, 98)',\n\t\t\t\tborderColor: 'rgb(8, 8, 8)',\n\t\t\t\tborderWidth: 0.55,\n\t\t\t\thitRadius: 3.3,\n\t\t\t\tskip: false\n\t\t\t}));\n\t\t}\n\n\t\t// point styles\n\t\tmeta.data[0].custom = {\n\t\t\tradius: 2.2,\n\t\t\tbackgroundColor: 'rgb(0, 1, 3)',\n\t\t\tborderColor: 'rgb(4, 6, 8)',\n\t\t\tborderWidth: 0.787,\n\t\t\ttension: 0.15,\n\t\t\thitRadius: 5,\n\t\t\tskip: true\n\t\t};\n\n\t\tchart.update();\n\n\t\texpect(meta.data[0]._model).toEqual(jasmine.objectContaining({\n\t\t\tbackgroundColor: 'rgb(0, 1, 3)',\n\t\t\tborderColor: 'rgb(4, 6, 8)',\n\t\t\tborderWidth: 0.787,\n\t\t\thitRadius: 5,\n\t\t\tskip: true\n\t\t}));\n\t});\n\n\tit('should handle number of data point changes in update', function() {\n\t\tvar chart = window.acquireChart({\n\t\t\ttype: 'bubble',\n\t\t\tdata: {\n\t\t\t\tdatasets: [{\n\t\t\t\t\tdata: [{\n\t\t\t\t\t\tx: 10,\n\t\t\t\t\t\ty: 10,\n\t\t\t\t\t\tr: 5\n\t\t\t\t\t}, {\n\t\t\t\t\t\tx: -15,\n\t\t\t\t\t\ty: -10,\n\t\t\t\t\t\tr: 1\n\t\t\t\t\t}, {\n\t\t\t\t\t\tx: 0,\n\t\t\t\t\t\ty: -9,\n\t\t\t\t\t\tr: 2\n\t\t\t\t\t}, {\n\t\t\t\t\t\tx: -4,\n\t\t\t\t\t\ty: 10,\n\t\t\t\t\t\tr: 1\n\t\t\t\t\t}]\n\t\t\t\t}],\n\t\t\t\tlabels: ['label1', 'label2', 'label3', 'label4']\n\t\t\t}\n\t\t});\n\n\t\tvar meta = chart.getDatasetMeta(0);\n\n\t\texpect(meta.data.length).toBe(4);\n\n\t\tchart.data.datasets[0].data = [{\n\t\t\tx: 1,\n\t\t\ty: 1,\n\t\t\tr: 10\n\t\t}, {\n\t\t\tx: 10,\n\t\t\ty: 5,\n\t\t\tr: 2\n\t\t}]; // remove 2 items\n\n\t\tchart.update();\n\n\t\texpect(meta.data.length).toBe(2);\n\t\texpect(meta.data[0] instanceof Chart.elements.Point).toBe(true);\n\t\texpect(meta.data[1] instanceof Chart.elements.Point).toBe(true);\n\n\t\tchart.data.datasets[0].data = [{\n\t\t\tx: 10,\n\t\t\ty: 10,\n\t\t\tr: 5\n\t\t}, {\n\t\t\tx: -15,\n\t\t\ty: -10,\n\t\t\tr: 1\n\t\t}, {\n\t\t\tx: 0,\n\t\t\ty: -9,\n\t\t\tr: 2\n\t\t}, {\n\t\t\tx: -4,\n\t\t\ty: 10,\n\t\t\tr: 1\n\t\t}, {\n\t\t\tx: -5,\n\t\t\ty: 0,\n\t\t\tr: 3\n\t\t}]; // add 3 items\n\n\t\tchart.update();\n\n\t\texpect(meta.data.length).toBe(5);\n\t\texpect(meta.data[0] instanceof Chart.elements.Point).toBe(true);\n\t\texpect(meta.data[1] instanceof Chart.elements.Point).toBe(true);\n\t\texpect(meta.data[2] instanceof Chart.elements.Point).toBe(true);\n\t\texpect(meta.data[3] instanceof Chart.elements.Point).toBe(true);\n\t\texpect(meta.data[4] instanceof Chart.elements.Point).toBe(true);\n\t});\n\n\tit('should set hover styles', function() {\n\t\tvar chart = window.acquireChart({\n\t\t\ttype: 'bubble',\n\t\t\tdata: {\n\t\t\t\tdatasets: [{\n\t\t\t\t\tdata: [{\n\t\t\t\t\t\tx: 10,\n\t\t\t\t\t\ty: 10,\n\t\t\t\t\t\tr: 5\n\t\t\t\t\t}, {\n\t\t\t\t\t\tx: -15,\n\t\t\t\t\t\ty: -10,\n\t\t\t\t\t\tr: 1\n\t\t\t\t\t}, {\n\t\t\t\t\t\tx: 0,\n\t\t\t\t\t\ty: -9,\n\t\t\t\t\t\tr: 2\n\t\t\t\t\t}, {\n\t\t\t\t\t\tx: -4,\n\t\t\t\t\t\ty: 10,\n\t\t\t\t\t\tr: 1\n\t\t\t\t\t}]\n\t\t\t\t}],\n\t\t\t\tlabels: ['label1', 'label2', 'label3', 'label4']\n\t\t\t},\n\t\t\toptions: {\n\t\t\t\telements: {\n\t\t\t\t\tpoint: {\n\t\t\t\t\t\tbackgroundColor: 'rgb(255, 255, 0)',\n\t\t\t\t\t\tborderWidth: 1,\n\t\t\t\t\t\tborderColor: 'rgb(255, 255, 255)',\n\t\t\t\t\t\thitRadius: 1,\n\t\t\t\t\t\thoverRadius: 4,\n\t\t\t\t\t\thoverBorderWidth: 1,\n\t\t\t\t\t\tradius: 3\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\n\t\tvar meta = chart.getDatasetMeta(0);\n\t\tvar point = meta.data[0];\n\n\t\tmeta.controller.setHoverStyle(point);\n\t\texpect(point._model.backgroundColor).toBe('rgb(229, 230, 0)');\n\t\texpect(point._model.borderColor).toBe('rgb(230, 230, 230)');\n\t\texpect(point._model.borderWidth).toBe(1);\n\t\texpect(point._model.radius).toBe(9);\n\n\t\t// Can set hover style per dataset\n\t\tchart.data.datasets[0].hoverRadius = 3.3;\n\t\tchart.data.datasets[0].hoverBackgroundColor = 'rgb(77, 79, 81)';\n\t\tchart.data.datasets[0].hoverBorderColor = 'rgb(123, 125, 127)';\n\t\tchart.data.datasets[0].hoverBorderWidth = 2.1;\n\n\t\tmeta.controller.setHoverStyle(point);\n\t\texpect(point._model.backgroundColor).toBe('rgb(77, 79, 81)');\n\t\texpect(point._model.borderColor).toBe('rgb(123, 125, 127)');\n\t\texpect(point._model.borderWidth).toBe(2.1);\n\t\texpect(point._model.radius).toBe(8.3);\n\n\t\t// Custom style\n\t\tpoint.custom = {\n\t\t\thoverRadius: 4.4,\n\t\t\thoverBorderWidth: 5.5,\n\t\t\thoverBackgroundColor: 'rgb(0, 0, 0)',\n\t\t\thoverBorderColor: 'rgb(10, 10, 10)'\n\t\t};\n\n\t\tmeta.controller.setHoverStyle(point);\n\t\texpect(point._model.backgroundColor).toBe('rgb(0, 0, 0)');\n\t\texpect(point._model.borderColor).toBe('rgb(10, 10, 10)');\n\t\texpect(point._model.borderWidth).toBe(5.5);\n\t\texpect(point._model.radius).toBe(4.4);\n\t});\n\n\tit('should remove hover styles', function() {\n\t\tvar chart = window.acquireChart({\n\t\t\ttype: 'bubble',\n\t\t\tdata: {\n\t\t\t\tdatasets: [{\n\t\t\t\t\tdata: [{\n\t\t\t\t\t\tx: 10,\n\t\t\t\t\t\ty: 10,\n\t\t\t\t\t\tr: 5\n\t\t\t\t\t}, {\n\t\t\t\t\t\tx: -15,\n\t\t\t\t\t\ty: -10,\n\t\t\t\t\t\tr: 1\n\t\t\t\t\t}, {\n\t\t\t\t\t\tx: 0,\n\t\t\t\t\t\ty: -9,\n\t\t\t\t\t\tr: 2\n\t\t\t\t\t}, {\n\t\t\t\t\t\tx: -4,\n\t\t\t\t\t\ty: 10,\n\t\t\t\t\t\tr: 1\n\t\t\t\t\t}]\n\t\t\t\t}],\n\t\t\t\tlabels: ['label1', 'label2', 'label3', 'label4']\n\t\t\t},\n\t\t\toptions: {\n\t\t\t\telements: {\n\t\t\t\t\tpoint: {\n\t\t\t\t\t\tbackgroundColor: 'rgb(255, 255, 0)',\n\t\t\t\t\t\tborderWidth: 1,\n\t\t\t\t\t\tborderColor: 'rgb(255, 255, 255)',\n\t\t\t\t\t\thitRadius: 1,\n\t\t\t\t\t\thoverRadius: 4,\n\t\t\t\t\t\thoverBorderWidth: 1,\n\t\t\t\t\t\tradius: 3\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\n\t\tvar meta = chart.getDatasetMeta(0);\n\t\tvar point = meta.data[0];\n\n\t\tchart.options.elements.point.backgroundColor = 'rgb(45, 46, 47)';\n\t\tchart.options.elements.point.borderColor = 'rgb(50, 51, 52)';\n\t\tchart.options.elements.point.borderWidth = 10.1;\n\t\tchart.options.elements.point.radius = 1.01;\n\n\t\tmeta.controller.removeHoverStyle(point);\n\t\texpect(point._model.backgroundColor).toBe('rgb(45, 46, 47)');\n\t\texpect(point._model.borderColor).toBe('rgb(50, 51, 52)');\n\t\texpect(point._model.borderWidth).toBe(10.1);\n\t\texpect(point._model.radius).toBe(5);\n\n\t\t// Can set hover style per dataset\n\t\tchart.data.datasets[0].radius = 3.3;\n\t\tchart.data.datasets[0].backgroundColor = 'rgb(77, 79, 81)';\n\t\tchart.data.datasets[0].borderColor = 'rgb(123, 125, 127)';\n\t\tchart.data.datasets[0].borderWidth = 2.1;\n\n\t\tmeta.controller.removeHoverStyle(point);\n\t\texpect(point._model.backgroundColor).toBe('rgb(77, 79, 81)');\n\t\texpect(point._model.borderColor).toBe('rgb(123, 125, 127)');\n\t\texpect(point._model.borderWidth).toBe(2.1);\n\t\texpect(point._model.radius).toBe(5);\n\n\t\t// Custom style\n\t\tpoint.custom = {\n\t\t\tradius: 4.4,\n\t\t\tborderWidth: 5.5,\n\t\t\tbackgroundColor: 'rgb(0, 0, 0)',\n\t\t\tborderColor: 'rgb(10, 10, 10)'\n\t\t};\n\n\t\tmeta.controller.removeHoverStyle(point);\n\t\texpect(point._model.backgroundColor).toBe('rgb(0, 0, 0)');\n\t\texpect(point._model.borderColor).toBe('rgb(10, 10, 10)');\n\t\texpect(point._model.borderWidth).toBe(5.5);\n\t\texpect(point._model.radius).toBe(4.4);\n\t});\n});\n"
  },
  {
    "path": "app_backend/static/plugin/Chart.js-2.6.0/test/specs/controller.doughnut.tests.js",
    "content": "// Test the bar controller\ndescribe('Doughnut controller tests', function() {\n\tit('should be constructed', function() {\n\t\tvar chart = window.acquireChart({\n\t\t\ttype: 'doughnut',\n\t\t\tdata: {\n\t\t\t\tdatasets: [{\n\t\t\t\t\tdata: []\n\t\t\t\t}],\n\t\t\t\tlabels: []\n\t\t\t}\n\t\t});\n\n\t\tvar meta = chart.getDatasetMeta(0);\n\t\texpect(meta.type).toBe('doughnut');\n\t\texpect(meta.controller).not.toBe(undefined);\n\t\texpect(meta.controller.index).toBe(0);\n\t\texpect(meta.data).toEqual([]);\n\n\t\tmeta.controller.updateIndex(1);\n\t\texpect(meta.controller.index).toBe(1);\n\t});\n\n\tit('should create arc elements for each data item during initialization', function() {\n\t\tvar chart = window.acquireChart({\n\t\t\ttype: 'doughnut',\n\t\t\tdata: {\n\t\t\t\tdatasets: [{\n\t\t\t\t\tdata: [10, 15, 0, 4]\n\t\t\t\t}],\n\t\t\t\tlabels: []\n\t\t\t}\n\t\t});\n\n\t\tvar meta = chart.getDatasetMeta(0);\n\t\texpect(meta.data.length).toBe(4); // 4 rectangles created\n\t\texpect(meta.data[0] instanceof Chart.elements.Arc).toBe(true);\n\t\texpect(meta.data[1] instanceof Chart.elements.Arc).toBe(true);\n\t\texpect(meta.data[2] instanceof Chart.elements.Arc).toBe(true);\n\t\texpect(meta.data[3] instanceof Chart.elements.Arc).toBe(true);\n\t});\n\n\tit('should set the innerRadius to 0 if the config option is 0', function() {\n\t\tvar chart = window.acquireChart({\n\t\t\ttype: 'pie',\n\t\t\tdata: {\n\t\t\t\tdatasets: [{\n\t\t\t\t\tdata: [10, 15, 0, 4]\n\t\t\t\t}],\n\t\t\t\tlabels: []\n\t\t\t}\n\t\t});\n\n\t\texpect(chart.innerRadius).toBe(0);\n\t});\n\n\tit ('should reset and update elements', function() {\n\t\tvar chart = window.acquireChart({\n\t\t\ttype: 'doughnut',\n\t\t\tdata: {\n\t\t\t\tdatasets: [{\n\t\t\t\t\tdata: [1, 2, 3, 4],\n\t\t\t\t\thidden: true\n\t\t\t\t}, {\n\t\t\t\t\tdata: [5, 6, 0, 7]\n\t\t\t\t}, {\n\t\t\t\t\tdata: [8, 9, 10, 11]\n\t\t\t\t}],\n\t\t\t\tlabels: ['label0', 'label1', 'label2', 'label3']\n\t\t\t},\n\t\t\toptions: {\n\t\t\t\tanimation: {\n\t\t\t\t\tanimateRotate: true,\n\t\t\t\t\tanimateScale: false\n\t\t\t\t},\n\t\t\t\tcutoutPercentage: 50,\n\t\t\t\trotation: Math.PI * -0.5,\n\t\t\t\tcircumference: Math.PI * 2.0,\n\t\t\t\telements: {\n\t\t\t\t\tarc: {\n\t\t\t\t\t\tbackgroundColor: 'rgb(255, 0, 0)',\n\t\t\t\t\t\tborderColor: 'rgb(0, 0, 255)',\n\t\t\t\t\t\tborderWidth: 2\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\n\t\tvar meta = chart.getDatasetMeta(1);\n\n\t\tmeta.controller.reset(); // reset first\n\n\t\texpect(meta.data.length).toBe(4);\n\n\t\t[\n\t\t\t{c: 0},\n\t\t\t{c: 0},\n\t\t\t{c: 0},\n\t\t\t{c: 0}\n\t\t].forEach(function(expected, i) {\n\t\t\texpect(meta.data[i]._model.x).toBeCloseToPixel(256);\n\t\t\texpect(meta.data[i]._model.y).toBeCloseToPixel(272);\n\t\t\texpect(meta.data[i]._model.outerRadius).toBeCloseToPixel(239);\n\t\t\texpect(meta.data[i]._model.innerRadius).toBeCloseToPixel(179);\n\t\t\texpect(meta.data[i]._model.circumference).toBeCloseTo(expected.c, 8);\n\t\t\texpect(meta.data[i]._model).toEqual(jasmine.objectContaining({\n\t\t\t\tstartAngle: Math.PI * -0.5,\n\t\t\t\tendAngle: Math.PI * -0.5,\n\t\t\t\tlabel: chart.data.labels[i],\n\t\t\t\tbackgroundColor: 'rgb(255, 0, 0)',\n\t\t\t\tborderColor: 'rgb(0, 0, 255)',\n\t\t\t\tborderWidth: 2\n\t\t\t}));\n\t\t});\n\n\t\tchart.update();\n\n\t\t[\n\t\t\t{c: 1.7453292519, s: -1.5707963267, e: 0.1745329251},\n\t\t\t{c: 2.0943951023, s: 0.1745329251, e: 2.2689280275},\n\t\t\t{c: 0, s: 2.2689280275, e: 2.2689280275},\n\t\t\t{c: 2.4434609527, s: 2.2689280275, e: 4.7123889803}\n\t\t].forEach(function(expected, i) {\n\t\t\texpect(meta.data[i]._model.x).toBeCloseToPixel(256);\n\t\t\texpect(meta.data[i]._model.y).toBeCloseToPixel(272);\n\t\t\texpect(meta.data[i]._model.outerRadius).toBeCloseToPixel(239);\n\t\t\texpect(meta.data[i]._model.innerRadius).toBeCloseToPixel(179);\n\t\t\texpect(meta.data[i]._model.circumference).toBeCloseTo(expected.c, 8);\n\t\t\texpect(meta.data[i]._model.startAngle).toBeCloseTo(expected.s, 8);\n\t\t\texpect(meta.data[i]._model.endAngle).toBeCloseTo(expected.e, 8);\n\t\t\texpect(meta.data[i]._model).toEqual(jasmine.objectContaining({\n\t\t\t\tlabel: chart.data.labels[i],\n\t\t\t\tbackgroundColor: 'rgb(255, 0, 0)',\n\t\t\t\tborderColor: 'rgb(0, 0, 255)',\n\t\t\t\tborderWidth: 2\n\t\t\t}));\n\t\t});\n\n\t\t// Change the amount of data and ensure that arcs are updated accordingly\n\t\tchart.data.datasets[1].data = [1, 2]; // remove 2 elements from dataset 0\n\t\tchart.update();\n\n\t\texpect(meta.data.length).toBe(2);\n\t\texpect(meta.data[0] instanceof Chart.elements.Arc).toBe(true);\n\t\texpect(meta.data[1] instanceof Chart.elements.Arc).toBe(true);\n\n\t\t// Add data\n\t\tchart.data.datasets[1].data = [1, 2, 3, 4];\n\t\tchart.update();\n\n\t\texpect(meta.data.length).toBe(4);\n\t\texpect(meta.data[0] instanceof Chart.elements.Arc).toBe(true);\n\t\texpect(meta.data[1] instanceof Chart.elements.Arc).toBe(true);\n\t\texpect(meta.data[2] instanceof Chart.elements.Arc).toBe(true);\n\t\texpect(meta.data[3] instanceof Chart.elements.Arc).toBe(true);\n\t});\n\n\tit ('should rotate and limit circumference', function() {\n\t\tvar chart = window.acquireChart({\n\t\t\ttype: 'doughnut',\n\t\t\tdata: {\n\t\t\t\tdatasets: [{\n\t\t\t\t\tdata: [2, 4],\n\t\t\t\t\thidden: true\n\t\t\t\t}, {\n\t\t\t\t\tdata: [1, 3]\n\t\t\t\t}, {\n\t\t\t\t\tdata: [1, 0]\n\t\t\t\t}],\n\t\t\t\tlabels: ['label0', 'label1']\n\t\t\t},\n\t\t\toptions: {\n\t\t\t\tcutoutPercentage: 50,\n\t\t\t\trotation: Math.PI,\n\t\t\t\tcircumference: Math.PI * 0.5,\n\t\t\t\telements: {\n\t\t\t\t\tarc: {\n\t\t\t\t\t\tbackgroundColor: 'rgb(255, 0, 0)',\n\t\t\t\t\t\tborderColor: 'rgb(0, 0, 255)',\n\t\t\t\t\t\tborderWidth: 2\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\n\t\tvar meta = chart.getDatasetMeta(1);\n\n\t\texpect(meta.data.length).toBe(2);\n\n\t\t// Only startAngle, endAngle and circumference should be different.\n\t\t[\n\t\t\t{c: Math.PI / 8, s: Math.PI, e: Math.PI + Math.PI / 8},\n\t\t\t{c: 3 * Math.PI / 8, s: Math.PI + Math.PI / 8, e: Math.PI + Math.PI / 2}\n\t\t].forEach(function(expected, i) {\n\t\t\texpect(meta.data[i]._model.x).toBeCloseToPixel(495);\n\t\t\texpect(meta.data[i]._model.y).toBeCloseToPixel(511);\n\t\t\texpect(meta.data[i]._model.outerRadius).toBeCloseToPixel(478);\n\t\t\texpect(meta.data[i]._model.innerRadius).toBeCloseToPixel(359);\n\t\t\texpect(meta.data[i]._model.circumference).toBeCloseTo(expected.c, 8);\n\t\t\texpect(meta.data[i]._model.startAngle).toBeCloseTo(expected.s, 8);\n\t\t\texpect(meta.data[i]._model.endAngle).toBeCloseTo(expected.e, 8);\n\t\t});\n\t});\n\n\tit ('should draw all arcs', function() {\n\t\tvar chart = window.acquireChart({\n\t\t\ttype: 'doughnut',\n\t\t\tdata: {\n\t\t\t\tdatasets: [{\n\t\t\t\t\tdata: [10, 15, 0, 4]\n\t\t\t\t}],\n\t\t\t\tlabels: ['label0', 'label1', 'label2', 'label3']\n\t\t\t}\n\t\t});\n\n\t\tvar meta = chart.getDatasetMeta(0);\n\n\t\tspyOn(meta.data[0], 'draw');\n\t\tspyOn(meta.data[1], 'draw');\n\t\tspyOn(meta.data[2], 'draw');\n\t\tspyOn(meta.data[3], 'draw');\n\n\t\tchart.update();\n\n\t\texpect(meta.data[0].draw.calls.count()).toBe(1);\n\t\texpect(meta.data[1].draw.calls.count()).toBe(1);\n\t\texpect(meta.data[2].draw.calls.count()).toBe(1);\n\t\texpect(meta.data[3].draw.calls.count()).toBe(1);\n\t});\n\n\tit ('should set the hover style of an arc', function() {\n\t\tvar chart = window.acquireChart({\n\t\t\ttype: 'doughnut',\n\t\t\tdata: {\n\t\t\t\tdatasets: [{\n\t\t\t\t\tdata: [10, 15, 0, 4]\n\t\t\t\t}],\n\t\t\t\tlabels: ['label0', 'label1', 'label2', 'label3']\n\t\t\t},\n\t\t\toptions: {\n\t\t\t\telements: {\n\t\t\t\t\tarc: {\n\t\t\t\t\t\tbackgroundColor: 'rgb(255, 0, 0)',\n\t\t\t\t\t\tborderColor: 'rgb(0, 0, 255)',\n\t\t\t\t\t\tborderWidth: 2,\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\n\t\tvar meta = chart.getDatasetMeta(0);\n\t\tvar arc = meta.data[0];\n\n\t\tmeta.controller.setHoverStyle(arc);\n\t\texpect(arc._model.backgroundColor).toBe('rgb(230, 0, 0)');\n\t\texpect(arc._model.borderColor).toBe('rgb(0, 0, 230)');\n\t\texpect(arc._model.borderWidth).toBe(2);\n\n\t\t// Set a dataset style to take precedence\n\t\tchart.data.datasets[0].hoverBackgroundColor = 'rgb(9, 9, 9)';\n\t\tchart.data.datasets[0].hoverBorderColor = 'rgb(18, 18, 18)';\n\t\tchart.data.datasets[0].hoverBorderWidth = 1.56;\n\n\t\tmeta.controller.setHoverStyle(arc);\n\t\texpect(arc._model.backgroundColor).toBe('rgb(9, 9, 9)');\n\t\texpect(arc._model.borderColor).toBe('rgb(18, 18, 18)');\n\t\texpect(arc._model.borderWidth).toBe(1.56);\n\n\t\t// Dataset styles can be an array\n\t\tchart.data.datasets[0].hoverBackgroundColor = ['rgb(255, 255, 255)', 'rgb(9, 9, 9)'];\n\t\tchart.data.datasets[0].hoverBorderColor = ['rgb(18, 18, 18)'];\n\t\tchart.data.datasets[0].hoverBorderWidth = [0.1, 1.56];\n\n\t\tmeta.controller.setHoverStyle(arc);\n\t\texpect(arc._model.backgroundColor).toBe('rgb(255, 255, 255)');\n\t\texpect(arc._model.borderColor).toBe('rgb(18, 18, 18)');\n\t\texpect(arc._model.borderWidth).toBe(0.1);\n\n\t\t// Element custom styles also work\n\t\tarc.custom = {\n\t\t\thoverBackgroundColor: 'rgb(7, 7, 7)',\n\t\t\thoverBorderColor: 'rgb(17, 17, 17)',\n\t\t\thoverBorderWidth: 3.14159,\n\t\t};\n\n\t\tmeta.controller.setHoverStyle(arc);\n\t\texpect(arc._model.backgroundColor).toBe('rgb(7, 7, 7)');\n\t\texpect(arc._model.borderColor).toBe('rgb(17, 17, 17)');\n\t\texpect(arc._model.borderWidth).toBe(3.14159);\n\t});\n\n\tit ('should unset the hover style of an arc', function() {\n\t\tvar chart = window.acquireChart({\n\t\t\ttype: 'doughnut',\n\t\t\tdata: {\n\t\t\t\tdatasets: [{\n\t\t\t\t\tdata: [10, 15, 0, 4]\n\t\t\t\t}],\n\t\t\t\tlabels: ['label0', 'label1', 'label2', 'label3']\n\t\t\t},\n\t\t\toptions: {\n\t\t\t\telements: {\n\t\t\t\t\tarc: {\n\t\t\t\t\t\tbackgroundColor: 'rgb(255, 0, 0)',\n\t\t\t\t\t\tborderColor: 'rgb(0, 0, 255)',\n\t\t\t\t\t\tborderWidth: 2,\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\n\t\tvar meta = chart.getDatasetMeta(0);\n\t\tvar arc = meta.data[0];\n\n\t\tmeta.controller.removeHoverStyle(arc);\n\t\texpect(arc._model.backgroundColor).toBe('rgb(255, 0, 0)');\n\t\texpect(arc._model.borderColor).toBe('rgb(0, 0, 255)');\n\t\texpect(arc._model.borderWidth).toBe(2);\n\n\t\t// Set a dataset style to take precedence\n\t\tchart.data.datasets[0].backgroundColor = 'rgb(9, 9, 9)';\n\t\tchart.data.datasets[0].borderColor = 'rgb(18, 18, 18)';\n\t\tchart.data.datasets[0].borderWidth = 1.56;\n\n\t\tmeta.controller.removeHoverStyle(arc);\n\t\texpect(arc._model.backgroundColor).toBe('rgb(9, 9, 9)');\n\t\texpect(arc._model.borderColor).toBe('rgb(18, 18, 18)');\n\t\texpect(arc._model.borderWidth).toBe(1.56);\n\n\t\t// Dataset styles can be an array\n\t\tchart.data.datasets[0].backgroundColor = ['rgb(255, 255, 255)', 'rgb(9, 9, 9)'];\n\t\tchart.data.datasets[0].borderColor = ['rgb(18, 18, 18)'];\n\t\tchart.data.datasets[0].borderWidth = [0.1, 1.56];\n\n\t\tmeta.controller.removeHoverStyle(arc);\n\t\texpect(arc._model.backgroundColor).toBe('rgb(255, 255, 255)');\n\t\texpect(arc._model.borderColor).toBe('rgb(18, 18, 18)');\n\t\texpect(arc._model.borderWidth).toBe(0.1);\n\n\t\t// Element custom styles also work\n\t\tarc.custom = {\n\t\t\tbackgroundColor: 'rgb(7, 7, 7)',\n\t\t\tborderColor: 'rgb(17, 17, 17)',\n\t\t\tborderWidth: 3.14159,\n\t\t};\n\n\t\tmeta.controller.removeHoverStyle(arc);\n\t\texpect(arc._model.backgroundColor).toBe('rgb(7, 7, 7)');\n\t\texpect(arc._model.borderColor).toBe('rgb(17, 17, 17)');\n\t\texpect(arc._model.borderWidth).toBe(3.14159);\n\t});\n});\n"
  },
  {
    "path": "app_backend/static/plugin/Chart.js-2.6.0/test/specs/controller.line.tests.js",
    "content": "// Test the line controller\ndescribe('Line controller tests', function() {\n\tit('should be constructed', function() {\n\t\tvar chart = window.acquireChart({\n\t\t\ttype: 'line',\n\t\t\tdata: {\n\t\t\t\tdatasets: [{\n\t\t\t\t\tdata: []\n\t\t\t\t}],\n\t\t\t\tlabels: []\n\t\t\t}\n\t\t});\n\n\t\tvar meta = chart.getDatasetMeta(0);\n\t\texpect(meta.type).toBe('line');\n\t\texpect(meta.controller).not.toBe(undefined);\n\t\texpect(meta.controller.index).toBe(0);\n\t\texpect(meta.data).toEqual([]);\n\n\t\tmeta.controller.updateIndex(1);\n\t\texpect(meta.controller.index).toBe(1);\n\t});\n\n\tit('Should use the first scale IDs if the dataset does not specify them', function() {\n\t\tvar chart = window.acquireChart({\n\t\t\ttype: 'line',\n\t\t\tdata: {\n\t\t\t\tdatasets: [{\n\t\t\t\t\tdata: []\n\t\t\t\t}],\n\t\t\t\tlabels: []\n\t\t\t},\n\t\t\toptions: {\n\t\t\t\tscales: {\n\t\t\t\t\txAxes: [{\n\t\t\t\t\t\tid: 'firstXScaleID'\n\t\t\t\t\t}],\n\t\t\t\t\tyAxes: [{\n\t\t\t\t\t\tid: 'firstYScaleID'\n\t\t\t\t\t}]\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\n\t\tvar meta = chart.getDatasetMeta(0);\n\t\texpect(meta.xAxisID).toBe('firstXScaleID');\n\t\texpect(meta.yAxisID).toBe('firstYScaleID');\n\t});\n\n\tit('Should create line elements and point elements for each data item during initialization', function() {\n\t\tvar chart = window.acquireChart({\n\t\t\ttype: 'line',\n\t\t\tdata: {\n\t\t\t\tdatasets: [{\n\t\t\t\t\tdata: [10, 15, 0, -4],\n\t\t\t\t\tlabel: 'dataset1'\n\t\t\t\t}],\n\t\t\t\tlabels: ['label1', 'label2', 'label3', 'label4']\n\t\t\t}\n\t\t});\n\n\t\tvar meta = chart.getDatasetMeta(0);\n\t\texpect(meta.data.length).toBe(4); // 4 points created\n\t\texpect(meta.data[0] instanceof Chart.elements.Point).toBe(true);\n\t\texpect(meta.data[1] instanceof Chart.elements.Point).toBe(true);\n\t\texpect(meta.data[2] instanceof Chart.elements.Point).toBe(true);\n\t\texpect(meta.data[3] instanceof Chart.elements.Point).toBe(true);\n\t\texpect(meta.dataset instanceof Chart.elements.Line).toBe(true); // 1 line element\n\t});\n\n\tit('should draw all elements', function() {\n\t\tvar chart = window.acquireChart({\n\t\t\ttype: 'line',\n\t\t\tdata: {\n\t\t\t\tdatasets: [{\n\t\t\t\t\tdata: [10, 15, 0, -4],\n\t\t\t\t\tlabel: 'dataset1'\n\t\t\t\t}],\n\t\t\t\tlabels: ['label1', 'label2', 'label3', 'label4']\n\t\t\t},\n\t\t\toptions: {\n\t\t\t\tshowLines: true\n\t\t\t}\n\t\t});\n\n\t\tvar meta = chart.getDatasetMeta(0);\n\t\tspyOn(meta.dataset, 'draw');\n\t\tspyOn(meta.data[0], 'draw');\n\t\tspyOn(meta.data[1], 'draw');\n\t\tspyOn(meta.data[2], 'draw');\n\t\tspyOn(meta.data[3], 'draw');\n\n\t\tchart.update();\n\n\t\texpect(meta.data[0].draw.calls.count()).toBe(1);\n\t\texpect(meta.data[1].draw.calls.count()).toBe(1);\n\t\texpect(meta.data[2].draw.calls.count()).toBe(1);\n\t\texpect(meta.data[3].draw.calls.count()).toBe(1);\n\t});\n\n\tit('should draw all elements except lines', function() {\n\t\tvar chart = window.acquireChart({\n\t\t\ttype: 'line',\n\t\t\tdata: {\n\t\t\t\tdatasets: [{\n\t\t\t\t\tdata: [10, 15, 0, -4],\n\t\t\t\t\tlabel: 'dataset1'\n\t\t\t\t}],\n\t\t\t\tlabels: ['label1', 'label2', 'label3', 'label4']\n\t\t\t},\n\t\t\toptions: {\n\t\t\t\tshowLines: false\n\t\t\t}\n\t\t});\n\n\t\tvar meta = chart.getDatasetMeta(0);\n\t\tspyOn(meta.dataset, 'draw');\n\t\tspyOn(meta.data[0], 'draw');\n\t\tspyOn(meta.data[1], 'draw');\n\t\tspyOn(meta.data[2], 'draw');\n\t\tspyOn(meta.data[3], 'draw');\n\n\t\tchart.update();\n\n\t\texpect(meta.dataset.draw.calls.count()).toBe(0);\n\t\texpect(meta.data[0].draw.calls.count()).toBe(1);\n\t\texpect(meta.data[1].draw.calls.count()).toBe(1);\n\t\texpect(meta.data[2].draw.calls.count()).toBe(1);\n\t\texpect(meta.data[3].draw.calls.count()).toBe(1);\n\t});\n\n\tit('should draw all elements except lines turned off per dataset', function() {\n\t\tvar chart = window.acquireChart({\n\t\t\ttype: 'line',\n\t\t\tdata: {\n\t\t\t\tdatasets: [{\n\t\t\t\t\tdata: [10, 15, 0, -4],\n\t\t\t\t\tlabel: 'dataset1',\n\t\t\t\t\tshowLine: false\n\t\t\t\t}],\n\t\t\t\tlabels: ['label1', 'label2', 'label3', 'label4']\n\t\t\t},\n\t\t\toptions: {\n\t\t\t\tshowLines: true\n\t\t\t}\n\t\t});\n\n\t\tvar meta = chart.getDatasetMeta(0);\n\t\tspyOn(meta.dataset, 'draw');\n\t\tspyOn(meta.data[0], 'draw');\n\t\tspyOn(meta.data[1], 'draw');\n\t\tspyOn(meta.data[2], 'draw');\n\t\tspyOn(meta.data[3], 'draw');\n\n\t\tchart.update();\n\n\t\texpect(meta.dataset.draw.calls.count()).toBe(0);\n\t\texpect(meta.data[0].draw.calls.count()).toBe(1);\n\t\texpect(meta.data[1].draw.calls.count()).toBe(1);\n\t\texpect(meta.data[2].draw.calls.count()).toBe(1);\n\t\texpect(meta.data[3].draw.calls.count()).toBe(1);\n\t});\n\n\tit('should update elements when modifying data', function() {\n\t\tvar chart = window.acquireChart({\n\t\t\ttype: 'line',\n\t\t\tdata: {\n\t\t\t\tdatasets: [{\n\t\t\t\t\tdata: [10, 15, 0, -4],\n\t\t\t\t\tlabel: 'dataset',\n\t\t\t\t\txAxisID: 'firstXScaleID',\n\t\t\t\t\tyAxisID: 'firstYScaleID'\n\t\t\t\t}],\n\t\t\t\tlabels: ['label1', 'label2', 'label3', 'label4']\n\t\t\t},\n\t\t\toptions: {\n\t\t\t\tshowLines: true,\n\t\t\t\telements: {\n\t\t\t\t\tpoint: {\n\t\t\t\t\t\tbackgroundColor: 'red',\n\t\t\t\t\t\tborderColor: 'blue',\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t\tscales: {\n\t\t\t\t\txAxes: [{\n\t\t\t\t\t\tid: 'firstXScaleID'\n\t\t\t\t\t}],\n\t\t\t\t\tyAxes: [{\n\t\t\t\t\t\tid: 'firstYScaleID'\n\t\t\t\t\t}]\n\t\t\t\t}\n\t\t\t},\n\t\t});\n\n\t\tvar meta = chart.getDatasetMeta(0);\n\t\texpect(meta.data.length).toBe(4);\n\n\t\tchart.data.datasets[0].data = [1, 2]; // remove 2 items\n\t\tchart.data.datasets[0].borderWidth = 1;\n\t\tchart.update();\n\n\t\texpect(meta.data.length).toBe(2);\n\n\n\t\t[\n\t\t\t{x: 33, y: 484},\n\t\t\t{x: 186, y: 32}\n\t\t].forEach(function(expected, i) {\n\t\t\texpect(meta.data[i]._datasetIndex).toBe(0);\n\t\t\texpect(meta.data[i]._index).toBe(i);\n\t\t\texpect(meta.data[i]._xScale).toBe(chart.scales.firstXScaleID);\n\t\t\texpect(meta.data[i]._yScale).toBe(chart.scales.firstYScaleID);\n\t\t\texpect(meta.data[i]._model.x).toBeCloseToPixel(expected.x);\n\t\t\texpect(meta.data[i]._model.y).toBeCloseToPixel(expected.y);\n\t\t\texpect(meta.data[i]._model).toEqual(jasmine.objectContaining({\n\t\t\t\tbackgroundColor: 'red',\n\t\t\t\tborderColor: 'blue',\n\t\t\t}));\n\t\t});\n\n\t\tchart.data.datasets[0].data = [1, 2, 3]; // add 1 items\n\t\tchart.update();\n\n\t\texpect(meta.data.length).toBe(3); // should add a new meta data item\n\t});\n\n\tit('should correctly calculate x scale for label and point', function() {\n\t\tvar chart = window.acquireChart({\n\t\t\ttype: 'line',\n\t\t\tdata: {\n\t\t\t\tlabels: ['One'],\n\t\t\t\tdatasets: [{\n\t\t\t\t\tdata: [1],\n\t\t\t\t}]\n\t\t\t},\n\t\t\toptions: {\n\t\t\t\thover: {\n\t\t\t\t\tmode: 'single'\n\t\t\t\t},\n\t\t\t\tscales: {\n\t\t\t\t\tyAxes: [{\n\t\t\t\t\t\tticks: {\n\t\t\t\t\t\t\tbeginAtZero: true\n\t\t\t\t\t\t}\n\t\t\t\t\t}]\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\n\t\tvar meta = chart.getDatasetMeta(0);\n\t\t// 1 point\n\t\tvar point = meta.data[0];\n\t\texpect(point._model.x).toBeCloseToPixel(262);\n\n\t\t// 2 points\n\t\tchart.data.labels = ['One', 'Two'];\n\t\tchart.data.datasets[0].data = [1, 2];\n\t\tchart.update();\n\n\t\tvar points = meta.data;\n\n\t\texpect(points[0]._model.x).toBeCloseToPixel(27);\n\t\texpect(points[1]._model.x).toBeCloseToPixel(498);\n\n\t\t// 3 points\n\t\tchart.data.labels = ['One', 'Two', 'Three'];\n\t\tchart.data.datasets[0].data = [1, 2, 3];\n\t\tchart.update();\n\n\t\tpoints = meta.data;\n\n\t\texpect(points[0]._model.x).toBeCloseToPixel(27);\n\t\texpect(points[1]._model.x).toBeCloseToPixel(260);\n\t\texpect(points[2]._model.x).toBeCloseToPixel(493);\n\n\t\t// 4 points\n\t\tchart.data.labels = ['One', 'Two', 'Three', 'Four'];\n\t\tchart.data.datasets[0].data = [1, 2, 3, 4];\n\t\tchart.update();\n\n\t\tpoints = meta.data;\n\n\t\texpect(points[0]._model.x).toBeCloseToPixel(27);\n\t\texpect(points[1]._model.x).toBeCloseToPixel(184);\n\t\texpect(points[2]._model.x).toBeCloseToPixel(340);\n\t\texpect(points[3]._model.x).toBeCloseToPixel(497);\n\t});\n\n\tit('should update elements when the y scale is stacked', function() {\n\t\tvar chart = window.acquireChart({\n\t\t\ttype: 'line',\n\t\t\tdata: {\n\t\t\t\tdatasets: [{\n\t\t\t\t\tdata: [10, -10, 10, -10],\n\t\t\t\t\tlabel: 'dataset1'\n\t\t\t\t}, {\n\t\t\t\t\tdata: [10, 15, 0, -4],\n\t\t\t\t\tlabel: 'dataset2'\n\t\t\t\t}],\n\t\t\t\tlabels: ['label1', 'label2', 'label3', 'label4']\n\t\t\t},\n\t\t\toptions: {\n\t\t\t\tscales: {\n\t\t\t\t\tyAxes: [{\n\t\t\t\t\t\tstacked: true\n\t\t\t\t\t}]\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\n\t\tvar meta0 = chart.getDatasetMeta(0);\n\n\t\t[\n\t\t\t{x: 28, y: 161},\n\t\t\t{x: 183, y: 419},\n\t\t\t{x: 338, y: 161},\n\t\t\t{x: 492, y: 419}\n\t\t].forEach(function(values, i) {\n\t\t\texpect(meta0.data[i]._model.x).toBeCloseToPixel(values.x);\n\t\t\texpect(meta0.data[i]._model.y).toBeCloseToPixel(values.y);\n\t\t});\n\n\t\tvar meta1 = chart.getDatasetMeta(1);\n\n\t\t[\n\t\t\t{x: 28, y: 32},\n\t\t\t{x: 183, y: 97},\n\t\t\t{x: 338, y: 161},\n\t\t\t{x: 492, y: 471}\n\t\t].forEach(function(values, i) {\n\t\t\texpect(meta1.data[i]._model.x).toBeCloseToPixel(values.x);\n\t\t\texpect(meta1.data[i]._model.y).toBeCloseToPixel(values.y);\n\t\t});\n\n\t});\n\n\tit('should update elements when the y scale is stacked with multiple axes', function() {\n\t\tvar chart = window.acquireChart({\n\t\t\ttype: 'line',\n\t\t\tdata: {\n\t\t\t\tdatasets: [{\n\t\t\t\t\tdata: [10, -10, 10, -10],\n\t\t\t\t\tlabel: 'dataset1'\n\t\t\t\t}, {\n\t\t\t\t\tdata: [10, 15, 0, -4],\n\t\t\t\t\tlabel: 'dataset2'\n\t\t\t\t}, {\n\t\t\t\t\tdata: [10, 10, -10, -10],\n\t\t\t\t\tlabel: 'dataset3',\n\t\t\t\t\tyAxisID: 'secondAxis'\n\t\t\t\t}],\n\t\t\t\tlabels: ['label1', 'label2', 'label3', 'label4']\n\t\t\t},\n\t\t\toptions: {\n\t\t\t\tscales: {\n\t\t\t\t\tyAxes: [{\n\t\t\t\t\t\tstacked: true\n\t\t\t\t\t}, {\n\t\t\t\t\t\ttype: 'linear',\n\t\t\t\t\t\tid: 'secondAxis'\n\t\t\t\t\t}]\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\n\t\tvar meta0 = chart.getDatasetMeta(0);\n\n\t\t[\n\t\t\t{x: 56, y: 161},\n\t\t\t{x: 202, y: 419},\n\t\t\t{x: 347, y: 161},\n\t\t\t{x: 492, y: 419}\n\t\t].forEach(function(values, i) {\n\t\t\texpect(meta0.data[i]._model.x).toBeCloseToPixel(values.x);\n\t\t\texpect(meta0.data[i]._model.y).toBeCloseToPixel(values.y);\n\t\t});\n\n\t\tvar meta1 = chart.getDatasetMeta(1);\n\n\t\t[\n\t\t\t{x: 56, y: 32},\n\t\t\t{x: 202, y: 97},\n\t\t\t{x: 347, y: 161},\n\t\t\t{x: 492, y: 471}\n\t\t].forEach(function(values, i) {\n\t\t\texpect(meta1.data[i]._model.x).toBeCloseToPixel(values.x);\n\t\t\texpect(meta1.data[i]._model.y).toBeCloseToPixel(values.y);\n\t\t});\n\n\t});\n\n\tit('should update elements when the y scale is stacked and datasets is scatter data', function() {\n\t\tvar chart = window.acquireChart({\n\t\t\ttype: 'line',\n\t\t\tdata: {\n\t\t\t\tdatasets: [{\n\t\t\t\t\tdata: [{\n\t\t\t\t\t\tx: 0,\n\t\t\t\t\t\ty: 10\n\t\t\t\t\t}, {\n\t\t\t\t\t\tx: 1,\n\t\t\t\t\t\ty: -10\n\t\t\t\t\t}, {\n\t\t\t\t\t\tx: 2,\n\t\t\t\t\t\ty: 10\n\t\t\t\t\t}, {\n\t\t\t\t\t\tx: 3,\n\t\t\t\t\t\ty: -10\n\t\t\t\t\t}],\n\t\t\t\t\tlabel: 'dataset1'\n\t\t\t\t}, {\n\t\t\t\t\tdata: [{\n\t\t\t\t\t\tx: 0,\n\t\t\t\t\t\ty: 10\n\t\t\t\t\t}, {\n\t\t\t\t\t\tx: 1,\n\t\t\t\t\t\ty: 15\n\t\t\t\t\t}, {\n\t\t\t\t\t\tx: 2,\n\t\t\t\t\t\ty: 0\n\t\t\t\t\t}, {\n\t\t\t\t\t\tx: 3,\n\t\t\t\t\t\ty: -4\n\t\t\t\t\t}],\n\t\t\t\t\tlabel: 'dataset2'\n\t\t\t\t}],\n\t\t\t\tlabels: ['label1', 'label2', 'label3', 'label4']\n\t\t\t},\n\t\t\toptions: {\n\t\t\t\tscales: {\n\t\t\t\t\tyAxes: [{\n\t\t\t\t\t\tstacked: true\n\t\t\t\t\t}]\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\n\t\tvar meta0 = chart.getDatasetMeta(0);\n\n\t\t[\n\t\t\t{x: 28, y: 161},\n\t\t\t{x: 183, y: 419},\n\t\t\t{x: 338, y: 161},\n\t\t\t{x: 492, y: 419}\n\t\t].forEach(function(values, i) {\n\t\t\texpect(meta0.data[i]._model.x).toBeCloseToPixel(values.x);\n\t\t\texpect(meta0.data[i]._model.y).toBeCloseToPixel(values.y);\n\t\t});\n\n\t\tvar meta1 = chart.getDatasetMeta(1);\n\n\t\t[\n\t\t\t{x: 28, y: 32},\n\t\t\t{x: 183, y: 97},\n\t\t\t{x: 338, y: 161},\n\t\t\t{x: 492, y: 471}\n\t\t].forEach(function(values, i) {\n\t\t\texpect(meta1.data[i]._model.x).toBeCloseToPixel(values.x);\n\t\t\texpect(meta1.data[i]._model.y).toBeCloseToPixel(values.y);\n\t\t});\n\n\t});\n\n\tit('should update elements when the y scale is stacked and data is strings', function() {\n\t\tvar chart = window.acquireChart({\n\t\t\ttype: 'line',\n\t\t\tdata: {\n\t\t\t\tdatasets: [{\n\t\t\t\t\tdata: ['10', '-10', '10', '-10'],\n\t\t\t\t\tlabel: 'dataset1'\n\t\t\t\t}, {\n\t\t\t\t\tdata: ['10', '15', '0', '-4'],\n\t\t\t\t\tlabel: 'dataset2'\n\t\t\t\t}],\n\t\t\t\tlabels: ['label1', 'label2', 'label3', 'label4']\n\t\t\t},\n\t\t\toptions: {\n\t\t\t\tscales: {\n\t\t\t\t\tyAxes: [{\n\t\t\t\t\t\tstacked: true\n\t\t\t\t\t}]\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\n\t\tvar meta0 = chart.getDatasetMeta(0);\n\n\t\t[\n\t\t\t{x: 28, y: 161},\n\t\t\t{x: 183, y: 419},\n\t\t\t{x: 338, y: 161},\n\t\t\t{x: 492, y: 419}\n\t\t].forEach(function(values, i) {\n\t\t\texpect(meta0.data[i]._model.x).toBeCloseToPixel(values.x);\n\t\t\texpect(meta0.data[i]._model.y).toBeCloseToPixel(values.y);\n\t\t});\n\n\t\tvar meta1 = chart.getDatasetMeta(1);\n\n\t\t[\n\t\t\t{x: 28, y: 32},\n\t\t\t{x: 183, y: 97},\n\t\t\t{x: 338, y: 161},\n\t\t\t{x: 492, y: 471}\n\t\t].forEach(function(values, i) {\n\t\t\texpect(meta1.data[i]._model.x).toBeCloseToPixel(values.x);\n\t\t\texpect(meta1.data[i]._model.y).toBeCloseToPixel(values.y);\n\t\t});\n\n\t});\n\n\tit('should fall back to the line styles for points', function() {\n\t\tvar chart = window.acquireChart({\n\t\t\ttype: 'line',\n\t\t\tdata: {\n\t\t\t\tdatasets: [{\n\t\t\t\t\tdata: [0, 0],\n\t\t\t\t\tlabel: 'dataset1',\n\n\t\t\t\t\t// line styles\n\t\t\t\t\tbackgroundColor: 'rgb(98, 98, 98)',\n\t\t\t\t\tborderColor: 'rgb(8, 8, 8)',\n\t\t\t\t\tborderWidth: 0.55,\n\t\t\t\t}],\n\t\t\t\tlabels: ['label1', 'label2']\n\t\t\t}\n\t\t});\n\n\t\tvar meta = chart.getDatasetMeta(0);\n\n\t\texpect(meta.dataset._model.backgroundColor).toBe('rgb(98, 98, 98)');\n\t\texpect(meta.dataset._model.borderColor).toBe('rgb(8, 8, 8)');\n\t\texpect(meta.dataset._model.borderWidth).toBe(0.55);\n\t});\n\n\tit('should handle number of data point changes in update', function() {\n\t\tvar chart = window.acquireChart({\n\t\t\ttype: 'line',\n\t\t\tdata: {\n\t\t\t\tdatasets: [{\n\t\t\t\t\tdata: [10, 15, 0, -4],\n\t\t\t\t\tlabel: 'dataset1',\n\t\t\t\t}],\n\t\t\t\tlabels: ['label1', 'label2', 'label3', 'label4']\n\t\t\t}\n\t\t});\n\n\t\tvar meta = chart.getDatasetMeta(0);\n\n\t\tchart.data.datasets[0].data = [1, 2]; // remove 2 items\n\t\tchart.update();\n\t\texpect(meta.data.length).toBe(2);\n\t\texpect(meta.data[0] instanceof Chart.elements.Point).toBe(true);\n\t\texpect(meta.data[1] instanceof Chart.elements.Point).toBe(true);\n\n\t\tchart.data.datasets[0].data = [1, 2, 3, 4, 5]; // add 3 items\n\t\tchart.update();\n\t\texpect(meta.data.length).toBe(5);\n\t\texpect(meta.data[0] instanceof Chart.elements.Point).toBe(true);\n\t\texpect(meta.data[1] instanceof Chart.elements.Point).toBe(true);\n\t\texpect(meta.data[2] instanceof Chart.elements.Point).toBe(true);\n\t\texpect(meta.data[3] instanceof Chart.elements.Point).toBe(true);\n\t\texpect(meta.data[4] instanceof Chart.elements.Point).toBe(true);\n\t});\n\n\tit('should set point hover styles', function() {\n\t\tvar chart = window.acquireChart({\n\t\t\ttype: 'line',\n\t\t\tdata: {\n\t\t\t\tdatasets: [{\n\t\t\t\t\tdata: [10, 15, 0, -4],\n\t\t\t\t\tlabel: 'dataset1',\n\t\t\t\t}],\n\t\t\t\tlabels: ['label1', 'label2', 'label3', 'label4']\n\t\t\t},\n\t\t\toptions: {\n\t\t\t\telements: {\n\t\t\t\t\tpoint: {\n\t\t\t\t\t\tbackgroundColor: 'rgb(255, 255, 0)',\n\t\t\t\t\t\tborderWidth: 1,\n\t\t\t\t\t\tborderColor: 'rgb(255, 255, 255)',\n\t\t\t\t\t\thitRadius: 1,\n\t\t\t\t\t\thoverRadius: 4,\n\t\t\t\t\t\thoverBorderWidth: 1,\n\t\t\t\t\t\tradius: 3,\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\n\t\tvar meta = chart.getDatasetMeta(0);\n\t\tvar point = meta.data[0];\n\n\t\tmeta.controller.setHoverStyle(point);\n\t\texpect(point._model.backgroundColor).toBe('rgb(229, 230, 0)');\n\t\texpect(point._model.borderColor).toBe('rgb(230, 230, 230)');\n\t\texpect(point._model.borderWidth).toBe(1);\n\t\texpect(point._model.radius).toBe(4);\n\n\t\t// Can set hover style per dataset\n\t\tchart.data.datasets[0].pointHoverRadius = 3.3;\n\t\tchart.data.datasets[0].pointHoverBackgroundColor = 'rgb(77, 79, 81)';\n\t\tchart.data.datasets[0].pointHoverBorderColor = 'rgb(123, 125, 127)';\n\t\tchart.data.datasets[0].pointHoverBorderWidth = 2.1;\n\n\t\tmeta.controller.setHoverStyle(point);\n\t\texpect(point._model.backgroundColor).toBe('rgb(77, 79, 81)');\n\t\texpect(point._model.borderColor).toBe('rgb(123, 125, 127)');\n\t\texpect(point._model.borderWidth).toBe(2.1);\n\t\texpect(point._model.radius).toBe(3.3);\n\n\t\t// Use the consistent name \"pointRadius\", setting but overwriting\n\t\t// another value in \"radius\"\n\t\tchart.data.datasets[0].pointRadius = 250;\n\t\tchart.data.datasets[0].radius = 20;\n\n\t\tmeta.controller.setHoverStyle(point);\n\t\texpect(point._model.backgroundColor).toBe('rgb(77, 79, 81)');\n\t\texpect(point._model.borderColor).toBe('rgb(123, 125, 127)');\n\t\texpect(point._model.borderWidth).toBe(2.1);\n\t\texpect(point._model.radius).toBe(3.3);\n\n\t\t// Custom style\n\t\tpoint.custom = {\n\t\t\thoverRadius: 4.4,\n\t\t\thoverBorderWidth: 5.5,\n\t\t\thoverBackgroundColor: 'rgb(0, 0, 0)',\n\t\t\thoverBorderColor: 'rgb(10, 10, 10)'\n\t\t};\n\n\t\tmeta.controller.setHoverStyle(point);\n\t\texpect(point._model.backgroundColor).toBe('rgb(0, 0, 0)');\n\t\texpect(point._model.borderColor).toBe('rgb(10, 10, 10)');\n\t\texpect(point._model.borderWidth).toBe(5.5);\n\t\texpect(point._model.radius).toBe(4.4);\n\t});\n\n\tit('should remove hover styles', function() {\n\t\tvar chart = window.acquireChart({\n\t\t\ttype: 'line',\n\t\t\tdata: {\n\t\t\t\tdatasets: [{\n\t\t\t\t\tdata: [10, 15, 0, -4],\n\t\t\t\t\tlabel: 'dataset1',\n\t\t\t\t}],\n\t\t\t\tlabels: ['label1', 'label2', 'label3', 'label4']\n\t\t\t},\n\t\t\toptions: {\n\t\t\t\telements: {\n\t\t\t\t\tpoint: {\n\t\t\t\t\t\tbackgroundColor: 'rgb(255, 255, 0)',\n\t\t\t\t\t\tborderWidth: 1,\n\t\t\t\t\t\tborderColor: 'rgb(255, 255, 255)',\n\t\t\t\t\t\thitRadius: 1,\n\t\t\t\t\t\thoverRadius: 4,\n\t\t\t\t\t\thoverBorderWidth: 1,\n\t\t\t\t\t\tradius: 3,\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\n\t\tvar meta = chart.getDatasetMeta(0);\n\t\tvar point = meta.data[0];\n\n\t\tchart.options.elements.point.backgroundColor = 'rgb(45, 46, 47)';\n\t\tchart.options.elements.point.borderColor = 'rgb(50, 51, 52)';\n\t\tchart.options.elements.point.borderWidth = 10.1;\n\t\tchart.options.elements.point.radius = 1.01;\n\n\t\tmeta.controller.removeHoverStyle(point);\n\t\texpect(point._model.backgroundColor).toBe('rgb(45, 46, 47)');\n\t\texpect(point._model.borderColor).toBe('rgb(50, 51, 52)');\n\t\texpect(point._model.borderWidth).toBe(10.1);\n\t\texpect(point._model.radius).toBe(1.01);\n\n\t\t// Can set hover style per dataset\n\t\tchart.data.datasets[0].radius = 3.3;\n\t\tchart.data.datasets[0].pointBackgroundColor = 'rgb(77, 79, 81)';\n\t\tchart.data.datasets[0].pointBorderColor = 'rgb(123, 125, 127)';\n\t\tchart.data.datasets[0].pointBorderWidth = 2.1;\n\n\t\tmeta.controller.removeHoverStyle(point);\n\t\texpect(point._model.backgroundColor).toBe('rgb(77, 79, 81)');\n\t\texpect(point._model.borderColor).toBe('rgb(123, 125, 127)');\n\t\texpect(point._model.borderWidth).toBe(2.1);\n\t\texpect(point._model.radius).toBe(3.3);\n\n\t\t// Use the consistent name \"pointRadius\", setting but overwriting\n\t\t// another value in \"radius\"\n\t\tchart.data.datasets[0].pointRadius = 250;\n\t\tchart.data.datasets[0].radius = 20;\n\n\t\tmeta.controller.removeHoverStyle(point);\n\t\texpect(point._model.backgroundColor).toBe('rgb(77, 79, 81)');\n\t\texpect(point._model.borderColor).toBe('rgb(123, 125, 127)');\n\t\texpect(point._model.borderWidth).toBe(2.1);\n\t\texpect(point._model.radius).toBe(250);\n\n\t\t// Custom style\n\t\tpoint.custom = {\n\t\t\tradius: 4.4,\n\t\t\tborderWidth: 5.5,\n\t\t\tbackgroundColor: 'rgb(0, 0, 0)',\n\t\t\tborderColor: 'rgb(10, 10, 10)'\n\t\t};\n\n\t\tmeta.controller.removeHoverStyle(point);\n\t\texpect(point._model.backgroundColor).toBe('rgb(0, 0, 0)');\n\t\texpect(point._model.borderColor).toBe('rgb(10, 10, 10)');\n\t\texpect(point._model.borderWidth).toBe(5.5);\n\t\texpect(point._model.radius).toBe(4.4);\n\t});\n\n\tit('should allow 0 as a point border width', function() {\n\t\tvar chart = window.acquireChart({\n\t\t\ttype: 'line',\n\t\t\tdata: {\n\t\t\t\tdatasets: [{\n\t\t\t\t\tdata: [10, 15, 0, -4],\n\t\t\t\t\tlabel: 'dataset1',\n\t\t\t\t\tpointBorderWidth: 0\n\t\t\t\t}],\n\t\t\t\tlabels: ['label1', 'label2', 'label3', 'label4']\n\t\t\t}\n\t\t});\n\n\t\tvar meta = chart.getDatasetMeta(0);\n\t\tvar point = meta.data[0];\n\n\t\texpect(point._model.borderWidth).toBe(0);\n\t});\n});\n"
  },
  {
    "path": "app_backend/static/plugin/Chart.js-2.6.0/test/specs/controller.polarArea.tests.js",
    "content": "// Test the polar area controller\ndescribe('Polar area controller tests', function() {\n\tit('should be constructed', function() {\n\t\tvar chart = window.acquireChart({\n\t\t\ttype: 'polarArea',\n\t\t\tdata: {\n\t\t\t\tdatasets: [\n\t\t\t\t{data: []},\n\t\t\t\t{data: []}\n\t\t\t\t],\n\t\t\t\tlabels: []\n\t\t\t}\n\t\t});\n\n\t\tvar meta = chart.getDatasetMeta(1);\n\t\texpect(meta.type).toEqual('polarArea');\n\t\texpect(meta.data).toEqual([]);\n\t\texpect(meta.hidden).toBe(null);\n\t\texpect(meta.controller).not.toBe(undefined);\n\t\texpect(meta.controller.index).toBe(1);\n\n\t\tmeta.controller.updateIndex(0);\n\t\texpect(meta.controller.index).toBe(0);\n\t});\n\n\tit('should create arc elements for each data item during initialization', function() {\n\t\tvar chart = window.acquireChart({\n\t\t\ttype: 'polarArea',\n\t\t\tdata: {\n\t\t\t\tdatasets: [\n\t\t\t\t\t{data: []},\n\t\t\t\t\t{data: [10, 15, 0, -4]}\n\t\t\t\t],\n\t\t\t\tlabels: []\n\t\t\t}\n\t\t});\n\n\t\tvar meta = chart.getDatasetMeta(1);\n\t\texpect(meta.data.length).toBe(4); // 4 arcs created\n\t\texpect(meta.data[0] instanceof Chart.elements.Arc).toBe(true);\n\t\texpect(meta.data[1] instanceof Chart.elements.Arc).toBe(true);\n\t\texpect(meta.data[2] instanceof Chart.elements.Arc).toBe(true);\n\t\texpect(meta.data[3] instanceof Chart.elements.Arc).toBe(true);\n\t});\n\n\tit('should draw all elements', function() {\n\t\tvar chart = window.acquireChart({\n\t\t\ttype: 'polarArea',\n\t\t\tdata: {\n\t\t\t\tdatasets: [{\n\t\t\t\t\tdata: [10, 15, 0, -4],\n\t\t\t\t\tlabel: 'dataset2'\n\t\t\t\t}],\n\t\t\t\tlabels: ['label1', 'label2', 'label3', 'label4']\n\t\t\t}\n\t\t});\n\n\t\tvar meta = chart.getDatasetMeta(0);\n\n\t\tspyOn(meta.data[0], 'draw');\n\t\tspyOn(meta.data[1], 'draw');\n\t\tspyOn(meta.data[2], 'draw');\n\t\tspyOn(meta.data[3], 'draw');\n\n\t\tchart.update();\n\n\t\texpect(meta.data[0].draw.calls.count()).toBe(1);\n\t\texpect(meta.data[1].draw.calls.count()).toBe(1);\n\t\texpect(meta.data[2].draw.calls.count()).toBe(1);\n\t\texpect(meta.data[3].draw.calls.count()).toBe(1);\n\t});\n\n\tit('should update elements when modifying data', function() {\n\t\tvar chart = window.acquireChart({\n\t\t\ttype: 'polarArea',\n\t\t\tdata: {\n\t\t\t\tdatasets: [{\n\t\t\t\t\tdata: [10, 15, 0, -4],\n\t\t\t\t\tlabel: 'dataset2'\n\t\t\t\t}],\n\t\t\t\tlabels: ['label1', 'label2', 'label3', 'label4']\n\t\t\t},\n\t\t\toptions: {\n\t\t\t\tshowLines: true,\n\t\t\t\telements: {\n\t\t\t\t\tarc: {\n\t\t\t\t\t\tbackgroundColor: 'rgb(255, 0, 0)',\n\t\t\t\t\t\tborderColor: 'rgb(0, 255, 0)',\n\t\t\t\t\t\tborderWidth: 1.2\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\n\t\tvar meta = chart.getDatasetMeta(0);\n\t\texpect(meta.data.length).toBe(4);\n\n\t\t[\n\t\t\t{o: 168, s: -0.5 * Math.PI, e: 0},\n\t\t\t{o: 228, s: 0, e: 0.5 * Math.PI},\n\t\t\t{o: 48, s: 0.5 * Math.PI, e: Math.PI},\n\t\t\t{o: 0, s: Math.PI, e: 1.5 * Math.PI}\n\t\t].forEach(function(expected, i) {\n\t\t\texpect(meta.data[i]._model.x).toBeCloseToPixel(256);\n\t\t\texpect(meta.data[i]._model.y).toBeCloseToPixel(272);\n\t\t\texpect(meta.data[i]._model.innerRadius).toBeCloseToPixel(0);\n\t\t\texpect(meta.data[i]._model.outerRadius).toBeCloseToPixel(expected.o);\n\t\t\texpect(meta.data[i]._model.startAngle).toBe(expected.s);\n\t\t\texpect(meta.data[i]._model.endAngle).toBe(expected.e);\n\t\t\texpect(meta.data[i]._model).toEqual(jasmine.objectContaining({\n\t\t\t\tbackgroundColor: 'rgb(255, 0, 0)',\n\t\t\t\tborderColor: 'rgb(0, 255, 0)',\n\t\t\t\tborderWidth: 1.2,\n\t\t\t\tlabel: chart.data.labels[i]\n\t\t\t}));\n\t\t});\n\n\t\t// arc styles\n\t\tchart.data.datasets[0].backgroundColor = 'rgb(128, 129, 130)';\n\t\tchart.data.datasets[0].borderColor = 'rgb(56, 57, 58)';\n\t\tchart.data.datasets[0].borderWidth = 1.123;\n\n\t\tchart.update();\n\n\t\tfor (var i = 0; i < 4; ++i) {\n\t\t\texpect(meta.data[i]._model.backgroundColor).toBe('rgb(128, 129, 130)');\n\t\t\texpect(meta.data[i]._model.borderColor).toBe('rgb(56, 57, 58)');\n\t\t\texpect(meta.data[i]._model.borderWidth).toBe(1.123);\n\t\t}\n\n\t\t// arc styles\n\t\tmeta.data[0].custom = {\n\t\t\tbackgroundColor: 'rgb(0, 1, 3)',\n\t\t\tborderColor: 'rgb(4, 6, 8)',\n\t\t\tborderWidth: 0.787\n\t\t};\n\n\t\tchart.update();\n\n\t\texpect(meta.data[0]._model.x).toBeCloseToPixel(256);\n\t\texpect(meta.data[0]._model.y).toBeCloseToPixel(272);\n\t\texpect(meta.data[0]._model.innerRadius).toBeCloseToPixel(0);\n\t\texpect(meta.data[0]._model.outerRadius).toBeCloseToPixel(168);\n\t\texpect(meta.data[0]._model).toEqual(jasmine.objectContaining({\n\t\t\tstartAngle: -0.5 * Math.PI,\n\t\t\tendAngle: 0,\n\t\t\tbackgroundColor: 'rgb(0, 1, 3)',\n\t\t\tborderWidth: 0.787,\n\t\t\tborderColor: 'rgb(4, 6, 8)',\n\t\t\tlabel: 'label1'\n\t\t}));\n\t});\n\n\tit('should update elements with start angle from options', function() {\n\t\tvar chart = window.acquireChart({\n\t\t\ttype: 'polarArea',\n\t\t\tdata: {\n\t\t\t\tdatasets: [{\n\t\t\t\t\tdata: [10, 15, 0, -4],\n\t\t\t\t\tlabel: 'dataset2'\n\t\t\t\t}],\n\t\t\t\tlabels: ['label1', 'label2', 'label3', 'label4']\n\t\t\t},\n\t\t\toptions: {\n\t\t\t\tshowLines: true,\n\t\t\t\tstartAngle: 0, // default is -0.5 * Math.PI\n\t\t\t\telements: {\n\t\t\t\t\tarc: {\n\t\t\t\t\t\tbackgroundColor: 'rgb(255, 0, 0)',\n\t\t\t\t\t\tborderColor: 'rgb(0, 255, 0)',\n\t\t\t\t\t\tborderWidth: 1.2\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\n\t\tvar meta = chart.getDatasetMeta(0);\n\t\texpect(meta.data.length).toBe(4);\n\n\t\t[\n\t\t\t{o: 168, s: 0, e: 0.5 * Math.PI},\n\t\t\t{o: 228, s: 0.5 * Math.PI, e: Math.PI},\n\t\t\t{o: 48, s: Math.PI, e: 1.5 * Math.PI},\n\t\t\t{o: 0, s: 1.5 * Math.PI, e: 2.0 * Math.PI}\n\t\t].forEach(function(expected, i) {\n\t\t\texpect(meta.data[i]._model.x).toBeCloseToPixel(256);\n\t\t\texpect(meta.data[i]._model.y).toBeCloseToPixel(272);\n\t\t\texpect(meta.data[i]._model.innerRadius).toBeCloseToPixel(0);\n\t\t\texpect(meta.data[i]._model.outerRadius).toBeCloseToPixel(expected.o);\n\t\t\texpect(meta.data[i]._model.startAngle).toBe(expected.s);\n\t\t\texpect(meta.data[i]._model.endAngle).toBe(expected.e);\n\t\t\texpect(meta.data[i]._model).toEqual(jasmine.objectContaining({\n\t\t\t\tbackgroundColor: 'rgb(255, 0, 0)',\n\t\t\t\tborderColor: 'rgb(0, 255, 0)',\n\t\t\t\tborderWidth: 1.2,\n\t\t\t\tlabel: chart.data.labels[i]\n\t\t\t}));\n\t\t});\n\t});\n\n\tit('should handle number of data point changes in update', function() {\n\t\tvar chart = window.acquireChart({\n\t\t\ttype: 'polarArea',\n\t\t\tdata: {\n\t\t\t\tdatasets: [{\n\t\t\t\t\tdata: [10, 15, 0, -4],\n\t\t\t\t\tlabel: 'dataset2'\n\t\t\t\t}],\n\t\t\t\tlabels: ['label1', 'label2', 'label3', 'label4']\n\t\t\t},\n\t\t\toptions: {\n\t\t\t\tshowLines: true,\n\t\t\t\telements: {\n\t\t\t\t\tarc: {\n\t\t\t\t\t\tbackgroundColor: 'rgb(255, 0, 0)',\n\t\t\t\t\t\tborderColor: 'rgb(0, 255, 0)',\n\t\t\t\t\t\tborderWidth: 1.2\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\n\t\tvar meta = chart.getDatasetMeta(0);\n\t\texpect(meta.data.length).toBe(4);\n\n\t\t// remove 2 items\n\t\tchart.data.labels = ['label1', 'label2'];\n\t\tchart.data.datasets[0].data = [1, 2];\n\t\tchart.update();\n\n\t\texpect(meta.data.length).toBe(2);\n\t\texpect(meta.data[0] instanceof Chart.elements.Arc).toBe(true);\n\t\texpect(meta.data[1] instanceof Chart.elements.Arc).toBe(true);\n\n\t\t// add 3 items\n\t\tchart.data.labels = ['label1', 'label2', 'label3', 'label4', 'label5'];\n\t\tchart.data.datasets[0].data = [1, 2, 3, 4, 5];\n\t\tchart.update();\n\n\t\texpect(meta.data.length).toBe(5);\n\t\texpect(meta.data[0] instanceof Chart.elements.Arc).toBe(true);\n\t\texpect(meta.data[1] instanceof Chart.elements.Arc).toBe(true);\n\t\texpect(meta.data[2] instanceof Chart.elements.Arc).toBe(true);\n\t\texpect(meta.data[3] instanceof Chart.elements.Arc).toBe(true);\n\t\texpect(meta.data[4] instanceof Chart.elements.Arc).toBe(true);\n\t});\n\n\tit('should set arc hover styles', function() {\n\t\tvar chart = window.acquireChart({\n\t\t\ttype: 'polarArea',\n\t\t\tdata: {\n\t\t\t\tdatasets: [{\n\t\t\t\t\tdata: [10, 15, 0, -4],\n\t\t\t\t\tlabel: 'dataset2'\n\t\t\t\t}],\n\t\t\t\tlabels: ['label1', 'label2', 'label3', 'label4']\n\t\t\t},\n\t\t\toptions: {\n\t\t\t\tshowLines: true,\n\t\t\t\telements: {\n\t\t\t\t\tarc: {\n\t\t\t\t\t\tbackgroundColor: 'rgb(255, 0, 0)',\n\t\t\t\t\t\tborderColor: 'rgb(0, 255, 0)',\n\t\t\t\t\t\tborderWidth: 1.2\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\n\t\tvar meta = chart.getDatasetMeta(0);\n\t\tvar arc = meta.data[0];\n\n\t\tmeta.controller.setHoverStyle(arc);\n\t\texpect(arc._model.backgroundColor).toBe('rgb(230, 0, 0)');\n\t\texpect(arc._model.borderColor).toBe('rgb(0, 230, 0)');\n\t\texpect(arc._model.borderWidth).toBe(1.2);\n\n\t\t// Can set hover style per dataset\n\t\tchart.data.datasets[0].hoverBackgroundColor = 'rgb(77, 79, 81)';\n\t\tchart.data.datasets[0].hoverBorderColor = 'rgb(123, 125, 127)';\n\t\tchart.data.datasets[0].hoverBorderWidth = 2.1;\n\n\t\tmeta.controller.setHoverStyle(arc);\n\t\texpect(arc._model.backgroundColor).toBe('rgb(77, 79, 81)');\n\t\texpect(arc._model.borderColor).toBe('rgb(123, 125, 127)');\n\t\texpect(arc._model.borderWidth).toBe(2.1);\n\n\t\t// Custom style\n\t\tarc.custom = {\n\t\t\thoverBorderWidth: 5.5,\n\t\t\thoverBackgroundColor: 'rgb(0, 0, 0)',\n\t\t\thoverBorderColor: 'rgb(10, 10, 10)'\n\t\t};\n\n\t\tmeta.controller.setHoverStyle(arc);\n\t\texpect(arc._model.backgroundColor).toBe('rgb(0, 0, 0)');\n\t\texpect(arc._model.borderColor).toBe('rgb(10, 10, 10)');\n\t\texpect(arc._model.borderWidth).toBe(5.5);\n\t});\n\n\tit('should remove hover styles', function() {\n\t\tvar chart = window.acquireChart({\n\t\t\ttype: 'polarArea',\n\t\t\tdata: {\n\t\t\t\tdatasets: [{\n\t\t\t\t\tdata: [10, 15, 0, -4],\n\t\t\t\t\tlabel: 'dataset2'\n\t\t\t\t}],\n\t\t\t\tlabels: ['label1', 'label2', 'label3', 'label4']\n\t\t\t},\n\t\t\toptions: {\n\t\t\t\tshowLines: true,\n\t\t\t\telements: {\n\t\t\t\t\tarc: {\n\t\t\t\t\t\tbackgroundColor: 'rgb(255, 0, 0)',\n\t\t\t\t\t\tborderColor: 'rgb(0, 255, 0)',\n\t\t\t\t\t\tborderWidth: 1.2\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\n\t\tvar meta = chart.getDatasetMeta(0);\n\t\tvar arc = meta.data[0];\n\n\t\tchart.options.elements.arc.backgroundColor = 'rgb(45, 46, 47)';\n\t\tchart.options.elements.arc.borderColor = 'rgb(50, 51, 52)';\n\t\tchart.options.elements.arc.borderWidth = 10.1;\n\n\t\tmeta.controller.removeHoverStyle(arc);\n\t\texpect(arc._model.backgroundColor).toBe('rgb(45, 46, 47)');\n\t\texpect(arc._model.borderColor).toBe('rgb(50, 51, 52)');\n\t\texpect(arc._model.borderWidth).toBe(10.1);\n\n\t\t// Can set hover style per dataset\n\t\tchart.data.datasets[0].backgroundColor = 'rgb(77, 79, 81)';\n\t\tchart.data.datasets[0].borderColor = 'rgb(123, 125, 127)';\n\t\tchart.data.datasets[0].borderWidth = 2.1;\n\n\t\tmeta.controller.removeHoverStyle(arc);\n\t\texpect(arc._model.backgroundColor).toBe('rgb(77, 79, 81)');\n\t\texpect(arc._model.borderColor).toBe('rgb(123, 125, 127)');\n\t\texpect(arc._model.borderWidth).toBe(2.1);\n\n\t\t// Custom style\n\t\tarc.custom = {\n\t\t\tborderWidth: 5.5,\n\t\t\tbackgroundColor: 'rgb(0, 0, 0)',\n\t\t\tborderColor: 'rgb(10, 10, 10)'\n\t\t};\n\n\t\tmeta.controller.removeHoverStyle(arc);\n\t\texpect(arc._model.backgroundColor).toBe('rgb(0, 0, 0)');\n\t\texpect(arc._model.borderColor).toBe('rgb(10, 10, 10)');\n\t\texpect(arc._model.borderWidth).toBe(5.5);\n\t});\n});\n"
  },
  {
    "path": "app_backend/static/plugin/Chart.js-2.6.0/test/specs/controller.radar.tests.js",
    "content": "// Test the polar area controller\ndescribe('Radar controller tests', function() {\n\tit('Should be constructed', function() {\n\t\tvar chart = window.acquireChart({\n\t\t\ttype: 'radar',\n\t\t\tdata: {\n\t\t\t\tdatasets: [{\n\t\t\t\t\tdata: []\n\t\t\t\t}],\n\t\t\t\tlabels: []\n\t\t\t}\n\t\t});\n\n\t\tvar meta = chart.getDatasetMeta(0);\n\t\texpect(meta.type).toBe('radar');\n\t\texpect(meta.controller).not.toBe(undefined);\n\t\texpect(meta.controller.index).toBe(0);\n\t\texpect(meta.data).toEqual([]);\n\n\t\tmeta.controller.updateIndex(1);\n\t\texpect(meta.controller.index).toBe(1);\n\t});\n\n\tit('Should create arc elements for each data item during initialization', function() {\n\t\tvar chart = window.acquireChart({\n\t\t\ttype: 'radar',\n\t\t\tdata: {\n\t\t\t\tdatasets: [{\n\t\t\t\t\tdata: [10, 15, 0, 4]\n\t\t\t\t}],\n\t\t\t\tlabels: ['label1', 'label2', 'label3', 'label4']\n\t\t\t}\n\t\t});\n\n\t\tvar meta = chart.getDatasetMeta(0);\n\t\texpect(meta.dataset instanceof Chart.elements.Line).toBe(true); // line element\n\t\texpect(meta.data.length).toBe(4); // 4 points created\n\t\texpect(meta.data[0] instanceof Chart.elements.Point).toBe(true);\n\t\texpect(meta.data[1] instanceof Chart.elements.Point).toBe(true);\n\t\texpect(meta.data[2] instanceof Chart.elements.Point).toBe(true);\n\t\texpect(meta.data[3] instanceof Chart.elements.Point).toBe(true);\n\t});\n\n\tit('should draw all elements', function() {\n\t\tvar chart = window.acquireChart({\n\t\t\ttype: 'radar',\n\t\t\tdata: {\n\t\t\t\tdatasets: [{\n\t\t\t\t\tdata: [10, 15, 0, 4]\n\t\t\t\t}],\n\t\t\t\tlabels: ['label1', 'label2', 'label3', 'label4']\n\t\t\t}\n\t\t});\n\n\t\tvar meta = chart.getDatasetMeta(0);\n\n\t\tspyOn(meta.dataset, 'draw');\n\t\tspyOn(meta.data[0], 'draw');\n\t\tspyOn(meta.data[1], 'draw');\n\t\tspyOn(meta.data[2], 'draw');\n\t\tspyOn(meta.data[3], 'draw');\n\n\t\tchart.update();\n\n\t\texpect(meta.dataset.draw.calls.count()).toBe(1);\n\t\texpect(meta.data[0].draw.calls.count()).toBe(1);\n\t\texpect(meta.data[1].draw.calls.count()).toBe(1);\n\t\texpect(meta.data[2].draw.calls.count()).toBe(1);\n\t\texpect(meta.data[3].draw.calls.count()).toBe(1);\n\t});\n\n\tit('should update elements', function() {\n\t\tvar chart = window.acquireChart({\n\t\t\ttype: 'radar',\n\t\t\tdata: {\n\t\t\t\tdatasets: [{\n\t\t\t\t\tdata: [10, 15, 0, 4]\n\t\t\t\t}],\n\t\t\t\tlabels: ['label1', 'label2', 'label3', 'label4']\n\t\t\t},\n\t\t\toptions: {\n\t\t\t\tshowLines: true,\n\t\t\t\telements: {\n\t\t\t\t\tline: {\n\t\t\t\t\t\tbackgroundColor: 'rgb(255, 0, 0)',\n\t\t\t\t\t\tborderCapStyle: 'round',\n\t\t\t\t\t\tborderColor: 'rgb(0, 255, 0)',\n\t\t\t\t\t\tborderDash: [],\n\t\t\t\t\t\tborderDashOffset: 0.1,\n\t\t\t\t\t\tborderJoinStyle: 'bevel',\n\t\t\t\t\t\tborderWidth: 1.2,\n\t\t\t\t\t\tfill: true,\n\t\t\t\t\t\ttension: 0.1,\n\t\t\t\t\t},\n\t\t\t\t\tpoint: {\n\t\t\t\t\t\tbackgroundColor: Chart.defaults.global.defaultColor,\n\t\t\t\t\t\tborderWidth: 1,\n\t\t\t\t\t\tborderColor: Chart.defaults.global.defaultColor,\n\t\t\t\t\t\thitRadius: 1,\n\t\t\t\t\t\thoverRadius: 4,\n\t\t\t\t\t\thoverBorderWidth: 1,\n\t\t\t\t\t\tradius: 3,\n\t\t\t\t\t\tpointStyle: 'circle'\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\n\t\tvar meta = chart.getDatasetMeta(0);\n\n\t\tmeta.controller.reset(); // reset first\n\n\t\t// Line element\n\t\texpect(meta.dataset._model).toEqual(jasmine.objectContaining({\n\t\t\tbackgroundColor: 'rgb(255, 0, 0)',\n\t\t\tborderCapStyle: 'round',\n\t\t\tborderColor: 'rgb(0, 255, 0)',\n\t\t\tborderDash: [],\n\t\t\tborderDashOffset: 0.1,\n\t\t\tborderJoinStyle: 'bevel',\n\t\t\tborderWidth: 1.2,\n\t\t\tfill: true,\n\t\t\ttension: 0.1,\n\t\t}));\n\n\t\t[\n\t\t\t{x: 256, y: 272, cppx: 256, cppy: 272, cpnx: 256, cpny: 272},\n\t\t\t{x: 256, y: 272, cppx: 256, cppy: 272, cpnx: 256, cpny: 272},\n\t\t\t{x: 256, y: 272, cppx: 256, cppy: 272, cpnx: 256, cpny: 272},\n\t\t\t{x: 256, y: 272, cppx: 256, cppy: 272, cpnx: 256, cpny: 272},\n\t\t].forEach(function(expected, i) {\n\t\t\texpect(meta.data[i]._model.x).toBeCloseToPixel(expected.x);\n\t\t\texpect(meta.data[i]._model.y).toBeCloseToPixel(expected.y);\n\t\t\texpect(meta.data[i]._model.controlPointPreviousX).toBeCloseToPixel(expected.cppx);\n\t\t\texpect(meta.data[i]._model.controlPointPreviousY).toBeCloseToPixel(expected.cppy);\n\t\t\texpect(meta.data[i]._model.controlPointNextX).toBeCloseToPixel(expected.cpnx);\n\t\t\texpect(meta.data[i]._model.controlPointNextY).toBeCloseToPixel(expected.cpny);\n\t\t\texpect(meta.data[i]._model).toEqual(jasmine.objectContaining({\n\t\t\t\tbackgroundColor: Chart.defaults.global.defaultColor,\n\t\t\t\tborderWidth: 1,\n\t\t\t\tborderColor: Chart.defaults.global.defaultColor,\n\t\t\t\thitRadius: 1,\n\t\t\t\tradius: 3,\n\t\t\t\tpointStyle: 'circle',\n\t\t\t\tskip: false,\n\t\t\t\ttension: 0.1,\n\t\t\t}));\n\t\t});\n\n\t\t// Now update controller and ensure proper updates\n\t\tmeta.controller.update();\n\n\t\t[\n\t\t\t{x: 256, y: 133, cppx: 246, cppy: 133, cpnx: 272, cpny: 133},\n\t\t\t{x: 464, y: 272, cppx: 464, cppy: 264, cpnx: 464, cpny: 278},\n\t\t\t{x: 256, y: 272, cppx: 276.9, cppy: 272, cpnx: 250.4, cpny: 272},\n\t\t\t{x: 200, y: 272, cppx: 200, cppy: 275, cpnx: 200, cpny: 261},\n\t\t].forEach(function(expected, i) {\n\t\t\texpect(meta.data[i]._model.x).toBeCloseToPixel(expected.x);\n\t\t\texpect(meta.data[i]._model.y).toBeCloseToPixel(expected.y);\n\t\t\texpect(meta.data[i]._model.controlPointPreviousX).toBeCloseToPixel(expected.cppx);\n\t\t\texpect(meta.data[i]._model.controlPointPreviousY).toBeCloseToPixel(expected.cppy);\n\t\t\texpect(meta.data[i]._model.controlPointNextX).toBeCloseToPixel(expected.cpnx);\n\t\t\texpect(meta.data[i]._model.controlPointNextY).toBeCloseToPixel(expected.cpny);\n\t\t\texpect(meta.data[i]._model).toEqual(jasmine.objectContaining({\n\t\t\t\tbackgroundColor: Chart.defaults.global.defaultColor,\n\t\t\t\tborderWidth: 1,\n\t\t\t\tborderColor: Chart.defaults.global.defaultColor,\n\t\t\t\thitRadius: 1,\n\t\t\t\tradius: 3,\n\t\t\t\tpointStyle: 'circle',\n\t\t\t\tskip: false,\n\t\t\t\ttension: 0.1,\n\t\t\t}));\n\t\t});\n\n\t\t// Use dataset level styles for lines & points\n\t\tchart.data.datasets[0].lineTension = 0;\n\t\tchart.data.datasets[0].backgroundColor = 'rgb(98, 98, 98)';\n\t\tchart.data.datasets[0].borderColor = 'rgb(8, 8, 8)';\n\t\tchart.data.datasets[0].borderWidth = 0.55;\n\t\tchart.data.datasets[0].borderCapStyle = 'butt';\n\t\tchart.data.datasets[0].borderDash = [2, 3];\n\t\tchart.data.datasets[0].borderDashOffset = 7;\n\t\tchart.data.datasets[0].borderJoinStyle = 'miter';\n\t\tchart.data.datasets[0].fill = false;\n\n\t\t// point styles\n\t\tchart.data.datasets[0].pointRadius = 22;\n\t\tchart.data.datasets[0].hitRadius = 3.3;\n\t\tchart.data.datasets[0].pointBackgroundColor = 'rgb(128, 129, 130)';\n\t\tchart.data.datasets[0].pointBorderColor = 'rgb(56, 57, 58)';\n\t\tchart.data.datasets[0].pointBorderWidth = 1.123;\n\n\t\tmeta.controller.update();\n\n\t\texpect(meta.dataset._model).toEqual(jasmine.objectContaining({\n\t\t\tbackgroundColor: 'rgb(98, 98, 98)',\n\t\t\tborderCapStyle: 'butt',\n\t\t\tborderColor: 'rgb(8, 8, 8)',\n\t\t\tborderDash: [2, 3],\n\t\t\tborderDashOffset: 7,\n\t\t\tborderJoinStyle: 'miter',\n\t\t\tborderWidth: 0.55,\n\t\t\tfill: false,\n\t\t\ttension: 0,\n\t\t}));\n\n\t\t// Since tension is now 0, we don't care about the control points\n\t\t[\n\t\t\t{x: 256, y: 133},\n\t\t\t{x: 464, y: 272},\n\t\t\t{x: 256, y: 272},\n\t\t\t{x: 200, y: 272},\n\t\t].forEach(function(expected, i) {\n\t\t\texpect(meta.data[i]._model.x).toBeCloseToPixel(expected.x);\n\t\t\texpect(meta.data[i]._model.y).toBeCloseToPixel(expected.y);\n\t\t\texpect(meta.data[i]._model).toEqual(jasmine.objectContaining({\n\t\t\t\tbackgroundColor: 'rgb(128, 129, 130)',\n\t\t\t\tborderWidth: 1.123,\n\t\t\t\tborderColor: 'rgb(56, 57, 58)',\n\t\t\t\thitRadius: 3.3,\n\t\t\t\tradius: 22,\n\t\t\t\tpointStyle: 'circle',\n\t\t\t\tskip: false,\n\t\t\t\ttension: 0,\n\t\t\t}));\n\t\t});\n\n\n\t\t// Use custom styles for lines & first point\n\t\tmeta.dataset.custom = {\n\t\t\ttension: 0.25,\n\t\t\tbackgroundColor: 'rgb(55, 55, 54)',\n\t\t\tborderColor: 'rgb(8, 7, 6)',\n\t\t\tborderWidth: 0.3,\n\t\t\tborderCapStyle: 'square',\n\t\t\tborderDash: [4, 3],\n\t\t\tborderDashOffset: 4.4,\n\t\t\tborderJoinStyle: 'round',\n\t\t\tfill: true,\n\t\t};\n\n\t\t// point styles\n\t\tmeta.data[0].custom = {\n\t\t\tradius: 2.2,\n\t\t\tbackgroundColor: 'rgb(0, 1, 3)',\n\t\t\tborderColor: 'rgb(4, 6, 8)',\n\t\t\tborderWidth: 0.787,\n\t\t\ttension: 0.15,\n\t\t\tskip: true,\n\t\t\thitRadius: 5,\n\t\t};\n\n\t\tmeta.controller.update();\n\n\t\texpect(meta.dataset._model).toEqual(jasmine.objectContaining({\n\t\t\tbackgroundColor: 'rgb(55, 55, 54)',\n\t\t\tborderCapStyle: 'square',\n\t\t\tborderColor: 'rgb(8, 7, 6)',\n\t\t\tborderDash: [4, 3],\n\t\t\tborderDashOffset: 4.4,\n\t\t\tborderJoinStyle: 'round',\n\t\t\tborderWidth: 0.3,\n\t\t\tfill: true,\n\t\t\ttension: 0.25,\n\t\t}));\n\n\t\texpect(meta.data[0]._model.x).toBeCloseToPixel(256);\n\t\texpect(meta.data[0]._model.y).toBeCloseToPixel(133);\n\t\texpect(meta.data[0]._model.controlPointPreviousX).toBeCloseToPixel(241);\n\t\texpect(meta.data[0]._model.controlPointPreviousY).toBeCloseToPixel(133);\n\t\texpect(meta.data[0]._model.controlPointNextX).toBeCloseToPixel(281);\n\t\texpect(meta.data[0]._model.controlPointNextY).toBeCloseToPixel(133);\n\t\texpect(meta.data[0]._model).toEqual(jasmine.objectContaining({\n\t\t\tradius: 2.2,\n\t\t\tbackgroundColor: 'rgb(0, 1, 3)',\n\t\t\tborderColor: 'rgb(4, 6, 8)',\n\t\t\tborderWidth: 0.787,\n\t\t\ttension: 0.15,\n\t\t\tskip: true,\n\t\t\thitRadius: 5,\n\t\t}));\n\t});\n\n\tit('should set point hover styles', function() {\n\t\tvar chart = window.acquireChart({\n\t\t\ttype: 'radar',\n\t\t\tdata: {\n\t\t\t\tdatasets: [{\n\t\t\t\t\tdata: [10, 15, 0, 4]\n\t\t\t\t}],\n\t\t\t\tlabels: ['label1', 'label2', 'label3', 'label4']\n\t\t\t},\n\t\t\toptions: {\n\t\t\t\tshowLines: true,\n\t\t\t\telements: {\n\t\t\t\t\tline: {\n\t\t\t\t\t\tbackgroundColor: 'rgb(255, 0, 0)',\n\t\t\t\t\t\tborderCapStyle: 'round',\n\t\t\t\t\t\tborderColor: 'rgb(0, 255, 0)',\n\t\t\t\t\t\tborderDash: [],\n\t\t\t\t\t\tborderDashOffset: 0.1,\n\t\t\t\t\t\tborderJoinStyle: 'bevel',\n\t\t\t\t\t\tborderWidth: 1.2,\n\t\t\t\t\t\tfill: true,\n\t\t\t\t\t\tskipNull: true,\n\t\t\t\t\t\ttension: 0.1,\n\t\t\t\t\t},\n\t\t\t\t\tpoint: {\n\t\t\t\t\t\tbackgroundColor: 'rgb(255, 255, 0)',\n\t\t\t\t\t\tborderWidth: 1,\n\t\t\t\t\t\tborderColor: 'rgb(255, 255, 255)',\n\t\t\t\t\t\thitRadius: 1,\n\t\t\t\t\t\thoverRadius: 4,\n\t\t\t\t\t\thoverBorderWidth: 1,\n\t\t\t\t\t\tradius: 3,\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\n\t\tvar meta = chart.getDatasetMeta(0);\n\n\t\tmeta.controller.update(); // reset first\n\n\t\tvar point = meta.data[0];\n\n\t\tmeta.controller.setHoverStyle(point);\n\t\texpect(point._model.backgroundColor).toBe('rgb(229, 230, 0)');\n\t\texpect(point._model.borderColor).toBe('rgb(230, 230, 230)');\n\t\texpect(point._model.borderWidth).toBe(1);\n\t\texpect(point._model.radius).toBe(4);\n\n\t\t// Can set hover style per dataset\n\t\tchart.data.datasets[0].pointHoverRadius = 3.3;\n\t\tchart.data.datasets[0].pointHoverBackgroundColor = 'rgb(77, 79, 81)';\n\t\tchart.data.datasets[0].pointHoverBorderColor = 'rgb(123, 125, 127)';\n\t\tchart.data.datasets[0].pointHoverBorderWidth = 2.1;\n\n\t\tmeta.controller.setHoverStyle(point);\n\t\texpect(point._model.backgroundColor).toBe('rgb(77, 79, 81)');\n\t\texpect(point._model.borderColor).toBe('rgb(123, 125, 127)');\n\t\texpect(point._model.borderWidth).toBe(2.1);\n\t\texpect(point._model.radius).toBe(3.3);\n\n\t\t// Custom style\n\t\tpoint.custom = {\n\t\t\thoverRadius: 4.4,\n\t\t\thoverBorderWidth: 5.5,\n\t\t\thoverBackgroundColor: 'rgb(0, 0, 0)',\n\t\t\thoverBorderColor: 'rgb(10, 10, 10)'\n\t\t};\n\n\t\tmeta.controller.setHoverStyle(point);\n\t\texpect(point._model.backgroundColor).toBe('rgb(0, 0, 0)');\n\t\texpect(point._model.borderColor).toBe('rgb(10, 10, 10)');\n\t\texpect(point._model.borderWidth).toBe(5.5);\n\t\texpect(point._model.radius).toBe(4.4);\n\t});\n\n\n\tit('should remove hover styles', function() {\n\t\tvar chart = window.acquireChart({\n\t\t\ttype: 'radar',\n\t\t\tdata: {\n\t\t\t\tdatasets: [{\n\t\t\t\t\tdata: [10, 15, 0, 4]\n\t\t\t\t}],\n\t\t\t\tlabels: ['label1', 'label2', 'label3', 'label4']\n\t\t\t},\n\t\t\toptions: {\n\t\t\t\tshowLines: true,\n\t\t\t\telements: {\n\t\t\t\t\tline: {\n\t\t\t\t\t\tbackgroundColor: 'rgb(255, 0, 0)',\n\t\t\t\t\t\tborderCapStyle: 'round',\n\t\t\t\t\t\tborderColor: 'rgb(0, 255, 0)',\n\t\t\t\t\t\tborderDash: [],\n\t\t\t\t\t\tborderDashOffset: 0.1,\n\t\t\t\t\t\tborderJoinStyle: 'bevel',\n\t\t\t\t\t\tborderWidth: 1.2,\n\t\t\t\t\t\tfill: true,\n\t\t\t\t\t\tskipNull: true,\n\t\t\t\t\t\ttension: 0.1,\n\t\t\t\t\t},\n\t\t\t\t\tpoint: {\n\t\t\t\t\t\tbackgroundColor: 'rgb(255, 255, 0)',\n\t\t\t\t\t\tborderWidth: 1,\n\t\t\t\t\t\tborderColor: 'rgb(255, 255, 255)',\n\t\t\t\t\t\thitRadius: 1,\n\t\t\t\t\t\thoverRadius: 4,\n\t\t\t\t\t\thoverBorderWidth: 1,\n\t\t\t\t\t\tradius: 3,\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\n\t\tvar meta = chart.getDatasetMeta(0);\n\n\t\tmeta.controller.update(); // reset first\n\n\t\tvar point = meta.data[0];\n\n\t\tchart.options.elements.point.backgroundColor = 'rgb(45, 46, 47)';\n\t\tchart.options.elements.point.borderColor = 'rgb(50, 51, 52)';\n\t\tchart.options.elements.point.borderWidth = 10.1;\n\t\tchart.options.elements.point.radius = 1.01;\n\n\t\tmeta.controller.removeHoverStyle(point);\n\t\texpect(point._model.backgroundColor).toBe('rgb(45, 46, 47)');\n\t\texpect(point._model.borderColor).toBe('rgb(50, 51, 52)');\n\t\texpect(point._model.borderWidth).toBe(10.1);\n\t\texpect(point._model.radius).toBe(1.01);\n\n\t\t// Can set hover style per dataset\n\t\tchart.data.datasets[0].pointRadius = 3.3;\n\t\tchart.data.datasets[0].pointBackgroundColor = 'rgb(77, 79, 81)';\n\t\tchart.data.datasets[0].pointBorderColor = 'rgb(123, 125, 127)';\n\t\tchart.data.datasets[0].pointBorderWidth = 2.1;\n\n\t\tmeta.controller.removeHoverStyle(point);\n\t\texpect(point._model.backgroundColor).toBe('rgb(77, 79, 81)');\n\t\texpect(point._model.borderColor).toBe('rgb(123, 125, 127)');\n\t\texpect(point._model.borderWidth).toBe(2.1);\n\t\texpect(point._model.radius).toBe(3.3);\n\n\t\t// Custom style\n\t\tpoint.custom = {\n\t\t\tradius: 4.4,\n\t\t\tborderWidth: 5.5,\n\t\t\tbackgroundColor: 'rgb(0, 0, 0)',\n\t\t\tborderColor: 'rgb(10, 10, 10)'\n\t\t};\n\n\t\tmeta.controller.removeHoverStyle(point);\n\t\texpect(point._model.backgroundColor).toBe('rgb(0, 0, 0)');\n\t\texpect(point._model.borderColor).toBe('rgb(10, 10, 10)');\n\t\texpect(point._model.borderWidth).toBe(5.5);\n\t\texpect(point._model.radius).toBe(4.4);\n\t});\n\n\tit('should allow pointBorderWidth to be set to 0', function() {\n\t\tvar chart = window.acquireChart({\n\t\t\ttype: 'radar',\n\t\t\tdata: {\n\t\t\t\tdatasets: [{\n\t\t\t\t\tdata: [10, 15, 0, 4],\n\t\t\t\t\tpointBorderWidth: 0\n\t\t\t\t}],\n\t\t\t\tlabels: ['label1', 'label2', 'label3', 'label4']\n\t\t\t}\n\t\t});\n\n\t\tvar meta = chart.getDatasetMeta(0);\n\t\tvar point = meta.data[0];\n\t\texpect(point._model.borderWidth).toBe(0);\n\t});\n\n\tit('should use the pointRadius setting over the radius setting', function() {\n\t\tvar chart = window.acquireChart({\n\t\t\ttype: 'radar',\n\t\t\tdata: {\n\t\t\t\tdatasets: [{\n\t\t\t\t\tdata: [10, 15, 0, 4],\n\t\t\t\t\tpointRadius: 10,\n\t\t\t\t\tradius: 15,\n\t\t\t\t}, {\n\t\t\t\t\tdata: [20, 20, 20, 20],\n\t\t\t\t\tradius: 20\n\t\t\t\t}],\n\t\t\t\tlabels: ['label1', 'label2', 'label3', 'label4']\n\t\t\t}\n\t\t});\n\n\t\tvar meta0 = chart.getDatasetMeta(0);\n\t\tvar meta1 = chart.getDatasetMeta(1);\n\t\texpect(meta0.data[0]._model.radius).toBe(10);\n\t\texpect(meta1.data[0]._model.radius).toBe(20);\n\t});\n});\n"
  },
  {
    "path": "app_backend/static/plugin/Chart.js-2.6.0/test/specs/core.controller.tests.js",
    "content": "describe('Chart', function() {\n\n\tfunction waitForResize(chart, callback) {\n\t\tvar resizer = chart.canvas.parentNode._chartjs.resizer;\n\t\tvar content = resizer.contentWindow || resizer;\n\t\tvar state = content.document.readyState || 'complete';\n\t\tvar handler = function() {\n\t\t\tChart.helpers.removeEvent(content, 'load', handler);\n\t\t\tChart.helpers.removeEvent(content, 'resize', handler);\n\t\t\tsetTimeout(callback, 50);\n\t\t};\n\n\t\tChart.helpers.addEvent(content, state !== 'complete'? 'load' : 'resize', handler);\n\t}\n\n\t// https://github.com/chartjs/Chart.js/issues/2481\n\t// See global.deprecations.tests.js for backward compatibility\n\tit('should be defined and prototype of chart instances', function() {\n\t\tvar chart = acquireChart({});\n\t\texpect(Chart).toBeDefined();\n\t\texpect(Chart instanceof Object).toBeTruthy();\n\t\texpect(chart.constructor).toBe(Chart);\n\t\texpect(chart instanceof Chart).toBeTruthy();\n\t\texpect(Chart.prototype.isPrototypeOf(chart)).toBeTruthy();\n\t});\n\n\tdescribe('config initialization', function() {\n\t\tit('should create missing config.data properties', function() {\n\t\t\tvar chart = acquireChart({});\n\t\t\tvar data = chart.data;\n\n\t\t\texpect(data instanceof Object).toBeTruthy();\n\t\t\texpect(data.labels instanceof Array).toBeTruthy();\n\t\t\texpect(data.labels.length).toBe(0);\n\t\t\texpect(data.datasets instanceof Array).toBeTruthy();\n\t\t\texpect(data.datasets.length).toBe(0);\n\t\t});\n\n\t\tit('should not alter config.data references', function() {\n\t\t\tvar ds0 = {data: [10, 11, 12, 13]};\n\t\t\tvar ds1 = {data: [20, 21, 22, 23]};\n\t\t\tvar datasets = [ds0, ds1];\n\t\t\tvar labels = [0, 1, 2, 3];\n\t\t\tvar data = {labels: labels, datasets: datasets};\n\n\t\t\tvar chart = acquireChart({\n\t\t\t\ttype: 'line',\n\t\t\t\tdata: data\n\t\t\t});\n\n\t\t\texpect(chart.data).toBe(data);\n\t\t\texpect(chart.data.labels).toBe(labels);\n\t\t\texpect(chart.data.datasets).toBe(datasets);\n\t\t\texpect(chart.data.datasets[0]).toBe(ds0);\n\t\t\texpect(chart.data.datasets[1]).toBe(ds1);\n\t\t\texpect(chart.data.datasets[0].data).toBe(ds0.data);\n\t\t\texpect(chart.data.datasets[1].data).toBe(ds1.data);\n\t\t});\n\n\t\tit('should define chart.data as an alias for config.data', function() {\n\t\t\tvar config = {data: {labels: [], datasets: []}};\n\t\t\tvar chart = acquireChart(config);\n\n\t\t\texpect(chart.data).toBe(config.data);\n\n\t\t\tchart.data = {labels: [1, 2, 3], datasets: [{data: [4, 5, 6]}]};\n\n\t\t\texpect(config.data).toBe(chart.data);\n\t\t\texpect(config.data.labels).toEqual([1, 2, 3]);\n\t\t\texpect(config.data.datasets[0].data).toEqual([4, 5, 6]);\n\n\t\t\tconfig.data = {labels: [7, 8, 9], datasets: [{data: [10, 11, 12]}]};\n\n\t\t\texpect(chart.data).toBe(config.data);\n\t\t\texpect(chart.data.labels).toEqual([7, 8, 9]);\n\t\t\texpect(chart.data.datasets[0].data).toEqual([10, 11, 12]);\n\t\t});\n\n\t\tit('should initialize config with default options', function() {\n\t\t\tvar callback = function() {};\n\n\t\t\tvar defaults = Chart.defaults;\n\t\t\tdefaults.global.responsiveAnimationDuration = 42;\n\t\t\tdefaults.global.hover.onHover = callback;\n\t\t\tdefaults.line.hover.mode = 'x-axis';\n\t\t\tdefaults.line.spanGaps = true;\n\n\t\t\tvar chart = acquireChart({\n\t\t\t\ttype: 'line'\n\t\t\t});\n\n\t\t\tvar options = chart.options;\n\t\t\texpect(options.defaultFontSize).toBe(defaults.global.defaultFontSize);\n\t\t\texpect(options.showLines).toBe(defaults.line.showLines);\n\t\t\texpect(options.spanGaps).toBe(true);\n\t\t\texpect(options.responsiveAnimationDuration).toBe(42);\n\t\t\texpect(options.hover.onHover).toBe(callback);\n\t\t\texpect(options.hover.mode).toBe('x-axis');\n\t\t});\n\n\t\tit('should override default options', function() {\n\t\t\tvar defaults = Chart.defaults;\n\t\t\tdefaults.global.responsiveAnimationDuration = 42;\n\t\t\tdefaults.line.hover.mode = 'x-axis';\n\t\t\tdefaults.line.spanGaps = true;\n\n\t\t\tvar chart = acquireChart({\n\t\t\t\ttype: 'line',\n\t\t\t\toptions: {\n\t\t\t\t\tresponsiveAnimationDuration: 4242,\n\t\t\t\t\tspanGaps: false,\n\t\t\t\t\thover: {\n\t\t\t\t\t\tmode: 'dataset',\n\t\t\t\t\t},\n\t\t\t\t\ttitle: {\n\t\t\t\t\t\tposition: 'bottom'\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t});\n\n\t\t\tvar options = chart.options;\n\t\t\texpect(options.responsiveAnimationDuration).toBe(4242);\n\t\t\texpect(options.spanGaps).toBe(false);\n\t\t\texpect(options.hover.mode).toBe('dataset');\n\t\t\texpect(options.title.position).toBe('bottom');\n\t\t});\n\n\t\tit('should override axis positions that are incorrect', function() {\n\t\t\tvar chart = acquireChart({\n\t\t\t\ttype: 'line',\n\t\t\t\toptions: {\n\t\t\t\t\tscales: {\n\t\t\t\t\t\txAxes: [{\n\t\t\t\t\t\t\tposition: 'left',\n\t\t\t\t\t\t}],\n\t\t\t\t\t\tyAxes: [{\n\t\t\t\t\t\t\tposition: 'bottom'\n\t\t\t\t\t\t}]\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t});\n\n\t\t\tvar scaleOptions = chart.options.scales;\n\t\t\texpect(scaleOptions.xAxes[0].position).toBe('bottom');\n\t\t\texpect(scaleOptions.yAxes[0].position).toBe('left');\n\t\t});\n\n\t\tit('should throw an error if the chart type is incorrect', function() {\n\t\t\tfunction createChart() {\n\t\t\t\tacquireChart({\n\t\t\t\t\ttype: 'area',\n\t\t\t\t\tdata: {\n\t\t\t\t\t\tdatasets: [{\n\t\t\t\t\t\t\tlabel: 'first',\n\t\t\t\t\t\t\tdata: [10, 20]\n\t\t\t\t\t\t}],\n\t\t\t\t\t\tlabels: ['0', '1'],\n\t\t\t\t\t},\n\t\t\t\t\toptions: {\n\t\t\t\t\t\tscales: {\n\t\t\t\t\t\t\txAxes: [{\n\t\t\t\t\t\t\t\tposition: 'left',\n\t\t\t\t\t\t\t}],\n\t\t\t\t\t\t\tyAxes: [{\n\t\t\t\t\t\t\t\tposition: 'bottom'\n\t\t\t\t\t\t\t}]\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t}\n\t\t\texpect(createChart).toThrow(new Error('\"area\" is not a chart type.'));\n\t\t});\n\t});\n\n\tdescribe('config.options.responsive: false', function() {\n\t\tit('should not inject the resizer element', function() {\n\t\t\tvar chart = acquireChart({\n\t\t\t\toptions: {\n\t\t\t\t\tresponsive: false\n\t\t\t\t}\n\t\t\t});\n\n\t\t\tvar wrapper = chart.canvas.parentNode;\n\t\t\texpect(wrapper.childNodes.length).toBe(1);\n\t\t\texpect(wrapper.firstChild.tagName).toBe('CANVAS');\n\t\t});\n\t});\n\n\tdescribe('config.options.responsive: true (maintainAspectRatio: false)', function() {\n\t\tit('should fill parent width and height', function() {\n\t\t\tvar chart = acquireChart({\n\t\t\t\toptions: {\n\t\t\t\t\tresponsive: true,\n\t\t\t\t\tmaintainAspectRatio: false\n\t\t\t\t}\n\t\t\t}, {\n\t\t\t\tcanvas: {\n\t\t\t\t\tstyle: 'width: 150px; height: 245px'\n\t\t\t\t},\n\t\t\t\twrapper: {\n\t\t\t\t\tstyle: 'width: 300px; height: 350px'\n\t\t\t\t}\n\t\t\t});\n\n\t\t\texpect(chart).toBeChartOfSize({\n\t\t\t\tdw: 300, dh: 350,\n\t\t\t\trw: 300, rh: 350,\n\t\t\t});\n\t\t});\n\n\t\tit('should resize the canvas when parent width changes', function(done) {\n\t\t\tvar chart = acquireChart({\n\t\t\t\toptions: {\n\t\t\t\t\tresponsive: true,\n\t\t\t\t\tmaintainAspectRatio: false\n\t\t\t\t}\n\t\t\t}, {\n\t\t\t\tcanvas: {\n\t\t\t\t\tstyle: ''\n\t\t\t\t},\n\t\t\t\twrapper: {\n\t\t\t\t\tstyle: 'width: 300px; height: 350px; position: relative'\n\t\t\t\t}\n\t\t\t});\n\n\t\t\texpect(chart).toBeChartOfSize({\n\t\t\t\tdw: 300, dh: 350,\n\t\t\t\trw: 300, rh: 350,\n\t\t\t});\n\n\t\t\tvar wrapper = chart.canvas.parentNode;\n\t\t\twrapper.style.width = '455px';\n\t\t\twaitForResize(chart, function() {\n\t\t\t\texpect(chart).toBeChartOfSize({\n\t\t\t\t\tdw: 455, dh: 350,\n\t\t\t\t\trw: 455, rh: 350,\n\t\t\t\t});\n\n\t\t\t\twrapper.style.width = '150px';\n\t\t\t\twaitForResize(chart, function() {\n\t\t\t\t\texpect(chart).toBeChartOfSize({\n\t\t\t\t\t\tdw: 150, dh: 350,\n\t\t\t\t\t\trw: 150, rh: 350,\n\t\t\t\t\t});\n\n\t\t\t\t\tdone();\n\t\t\t\t});\n\t\t\t});\n\t\t});\n\n\t\tit('should resize the canvas when parent height changes', function(done) {\n\t\t\tvar chart = acquireChart({\n\t\t\t\toptions: {\n\t\t\t\t\tresponsive: true,\n\t\t\t\t\tmaintainAspectRatio: false\n\t\t\t\t}\n\t\t\t}, {\n\t\t\t\tcanvas: {\n\t\t\t\t\tstyle: ''\n\t\t\t\t},\n\t\t\t\twrapper: {\n\t\t\t\t\tstyle: 'width: 300px; height: 350px; position: relative'\n\t\t\t\t}\n\t\t\t});\n\n\t\t\texpect(chart).toBeChartOfSize({\n\t\t\t\tdw: 300, dh: 350,\n\t\t\t\trw: 300, rh: 350,\n\t\t\t});\n\n\t\t\tvar wrapper = chart.canvas.parentNode;\n\t\t\twrapper.style.height = '455px';\n\t\t\twaitForResize(chart, function() {\n\t\t\t\texpect(chart).toBeChartOfSize({\n\t\t\t\t\tdw: 300, dh: 455,\n\t\t\t\t\trw: 300, rh: 455,\n\t\t\t\t});\n\n\t\t\t\twrapper.style.height = '150px';\n\t\t\t\twaitForResize(chart, function() {\n\t\t\t\t\texpect(chart).toBeChartOfSize({\n\t\t\t\t\t\tdw: 300, dh: 150,\n\t\t\t\t\t\trw: 300, rh: 150,\n\t\t\t\t\t});\n\n\t\t\t\t\tdone();\n\t\t\t\t});\n\t\t\t});\n\t\t});\n\n\t\tit('should not include parent padding when resizing the canvas', function(done) {\n\t\t\tvar chart = acquireChart({\n\t\t\t\ttype: 'line',\n\t\t\t\toptions: {\n\t\t\t\t\tresponsive: true,\n\t\t\t\t\tmaintainAspectRatio: false\n\t\t\t\t}\n\t\t\t}, {\n\t\t\t\tcanvas: {\n\t\t\t\t\tstyle: ''\n\t\t\t\t},\n\t\t\t\twrapper: {\n\t\t\t\t\tstyle: 'padding: 50px; width: 320px; height: 350px; position: relative'\n\t\t\t\t}\n\t\t\t});\n\n\t\t\texpect(chart).toBeChartOfSize({\n\t\t\t\tdw: 320, dh: 350,\n\t\t\t\trw: 320, rh: 350,\n\t\t\t});\n\n\t\t\tvar wrapper = chart.canvas.parentNode;\n\t\t\twrapper.style.height = '355px';\n\t\t\twrapper.style.width = '455px';\n\t\t\twaitForResize(chart, function() {\n\t\t\t\texpect(chart).toBeChartOfSize({\n\t\t\t\t\tdw: 455, dh: 355,\n\t\t\t\t\trw: 455, rh: 355,\n\t\t\t\t});\n\n\t\t\t\tdone();\n\t\t\t});\n\t\t});\n\n\t\tit('should resize the canvas when the canvas display style changes from \"none\" to \"block\"', function(done) {\n\t\t\tvar chart = acquireChart({\n\t\t\t\toptions: {\n\t\t\t\t\tresponsive: true,\n\t\t\t\t\tmaintainAspectRatio: false\n\t\t\t\t}\n\t\t\t}, {\n\t\t\t\tcanvas: {\n\t\t\t\t\tstyle: 'display: none;'\n\t\t\t\t},\n\t\t\t\twrapper: {\n\t\t\t\t\tstyle: 'width: 320px; height: 350px'\n\t\t\t\t}\n\t\t\t});\n\n\t\t\tvar canvas = chart.canvas;\n\t\t\tcanvas.style.display = 'block';\n\t\t\twaitForResize(chart, function() {\n\t\t\t\texpect(chart).toBeChartOfSize({\n\t\t\t\t\tdw: 320, dh: 350,\n\t\t\t\t\trw: 320, rh: 350,\n\t\t\t\t});\n\n\t\t\t\tdone();\n\t\t\t});\n\t\t});\n\n\t\tit('should resize the canvas when the wrapper display style changes from \"none\" to \"block\"', function(done) {\n\t\t\tvar chart = acquireChart({\n\t\t\t\toptions: {\n\t\t\t\t\tresponsive: true,\n\t\t\t\t\tmaintainAspectRatio: false\n\t\t\t\t}\n\t\t\t}, {\n\t\t\t\tcanvas: {\n\t\t\t\t\tstyle: ''\n\t\t\t\t},\n\t\t\t\twrapper: {\n\t\t\t\t\tstyle: 'display: none; width: 460px; height: 380px'\n\t\t\t\t}\n\t\t\t});\n\n\t\t\tvar wrapper = chart.canvas.parentNode;\n\t\t\twrapper.style.display = 'block';\n\t\t\twaitForResize(chart, function() {\n\t\t\t\texpect(chart).toBeChartOfSize({\n\t\t\t\t\tdw: 460, dh: 380,\n\t\t\t\t\trw: 460, rh: 380,\n\t\t\t\t});\n\n\t\t\t\tdone();\n\t\t\t});\n\t\t});\n\n\t\t// https://github.com/chartjs/Chart.js/issues/3521\n\t\tit('should resize the canvas after the wrapper has been re-attached to the DOM', function(done) {\n\t\t\tvar chart = acquireChart({\n\t\t\t\toptions: {\n\t\t\t\t\tresponsive: true,\n\t\t\t\t\tmaintainAspectRatio: false\n\t\t\t\t}\n\t\t\t}, {\n\t\t\t\tcanvas: {\n\t\t\t\t\tstyle: ''\n\t\t\t\t},\n\t\t\t\twrapper: {\n\t\t\t\t\tstyle: 'width: 320px; height: 350px'\n\t\t\t\t}\n\t\t\t});\n\n\t\t\texpect(chart).toBeChartOfSize({\n\t\t\t\tdw: 320, dh: 350,\n\t\t\t\trw: 320, rh: 350,\n\t\t\t});\n\n\t\t\tvar wrapper = chart.canvas.parentNode;\n\t\t\tvar parent = wrapper.parentNode;\n\t\t\tparent.removeChild(wrapper);\n\t\t\tparent.appendChild(wrapper);\n\t\t\twrapper.style.height = '355px';\n\n\t\t\twaitForResize(chart, function() {\n\t\t\t\texpect(chart).toBeChartOfSize({\n\t\t\t\t\tdw: 320, dh: 355,\n\t\t\t\t\trw: 320, rh: 355,\n\t\t\t\t});\n\n\t\t\t\tparent.removeChild(wrapper);\n\t\t\t\twrapper.style.width = '455px';\n\t\t\t\tparent.appendChild(wrapper);\n\n\t\t\t\twaitForResize(chart, function() {\n\t\t\t\t\texpect(chart).toBeChartOfSize({\n\t\t\t\t\t\tdw: 455, dh: 355,\n\t\t\t\t\t\trw: 455, rh: 355,\n\t\t\t\t\t});\n\n\t\t\t\t\tdone();\n\t\t\t\t});\n\t\t\t});\n\t\t});\n\t});\n\n\tdescribe('config.options.responsive: true (maintainAspectRatio: true)', function() {\n\t\tit('should resize the canvas with correct aspect ratio when parent width changes', function(done) {\n\t\t\tvar chart = acquireChart({\n\t\t\t\ttype: 'line', // AR == 2\n\t\t\t\toptions: {\n\t\t\t\t\tresponsive: true,\n\t\t\t\t\tmaintainAspectRatio: true\n\t\t\t\t}\n\t\t\t}, {\n\t\t\t\tcanvas: {\n\t\t\t\t\tstyle: ''\n\t\t\t\t},\n\t\t\t\twrapper: {\n\t\t\t\t\tstyle: 'width: 300px; height: 350px; position: relative'\n\t\t\t\t}\n\t\t\t});\n\n\t\t\texpect(chart).toBeChartOfSize({\n\t\t\t\tdw: 300, dh: 150,\n\t\t\t\trw: 300, rh: 150,\n\t\t\t});\n\n\t\t\tvar wrapper = chart.canvas.parentNode;\n\t\t\twrapper.style.width = '450px';\n\t\t\twaitForResize(chart, function() {\n\t\t\t\texpect(chart).toBeChartOfSize({\n\t\t\t\t\tdw: 450, dh: 225,\n\t\t\t\t\trw: 450, rh: 225,\n\t\t\t\t});\n\n\t\t\t\twrapper.style.width = '150px';\n\t\t\t\twaitForResize(chart, function() {\n\t\t\t\t\texpect(chart).toBeChartOfSize({\n\t\t\t\t\t\tdw: 150, dh: 75,\n\t\t\t\t\t\trw: 150, rh: 75,\n\t\t\t\t\t});\n\n\t\t\t\t\tdone();\n\t\t\t\t});\n\t\t\t});\n\t\t});\n\n\t\tit('should not resize the canvas when parent height changes', function(done) {\n\t\t\tvar chart = acquireChart({\n\t\t\t\toptions: {\n\t\t\t\t\tresponsive: true,\n\t\t\t\t\tmaintainAspectRatio: true\n\t\t\t\t}\n\t\t\t}, {\n\t\t\t\tcanvas: {\n\t\t\t\t\tstyle: ''\n\t\t\t\t},\n\t\t\t\twrapper: {\n\t\t\t\t\tstyle: 'width: 320px; height: 350px; position: relative'\n\t\t\t\t}\n\t\t\t});\n\n\t\t\texpect(chart).toBeChartOfSize({\n\t\t\t\tdw: 320, dh: 160,\n\t\t\t\trw: 320, rh: 160,\n\t\t\t});\n\n\t\t\tvar wrapper = chart.canvas.parentNode;\n\t\t\twrapper.style.height = '455px';\n\t\t\twaitForResize(chart, function() {\n\t\t\t\texpect(chart).toBeChartOfSize({\n\t\t\t\t\tdw: 320, dh: 160,\n\t\t\t\t\trw: 320, rh: 160,\n\t\t\t\t});\n\n\t\t\t\twrapper.style.height = '150px';\n\t\t\t\twaitForResize(chart, function() {\n\t\t\t\t\texpect(chart).toBeChartOfSize({\n\t\t\t\t\t\tdw: 320, dh: 160,\n\t\t\t\t\t\trw: 320, rh: 160,\n\t\t\t\t\t});\n\n\t\t\t\t\tdone();\n\t\t\t\t});\n\t\t\t});\n\t\t});\n\t});\n\n\tdescribe('Retina scale (a.k.a. device pixel ratio)', function() {\n\t\tbeforeEach(function() {\n\t\t\tthis.devicePixelRatio = window.devicePixelRatio;\n\t\t\twindow.devicePixelRatio = 3;\n\t\t});\n\n\t\tafterEach(function() {\n\t\t\twindow.devicePixelRatio = this.devicePixelRatio;\n\t\t});\n\n\t\t// see https://github.com/chartjs/Chart.js/issues/3575\n\t\tit ('should scale the render size but not the \"implicit\" display size', function() {\n\t\t\tvar chart = acquireChart({\n\t\t\t\toptions: {\n\t\t\t\t\tresponsive: false\n\t\t\t\t}\n\t\t\t}, {\n\t\t\t\tcanvas: {\n\t\t\t\t\twidth: 320,\n\t\t\t\t\theight: 240,\n\t\t\t\t}\n\t\t\t});\n\n\t\t\texpect(chart).toBeChartOfSize({\n\t\t\t\tdw: 320, dh: 240,\n\t\t\t\trw: 960, rh: 720,\n\t\t\t});\n\t\t});\n\n\t\tit ('should scale the render size but not the \"explicit\" display size', function() {\n\t\t\tvar chart = acquireChart({\n\t\t\t\toptions: {\n\t\t\t\t\tresponsive: false\n\t\t\t\t}\n\t\t\t}, {\n\t\t\t\tcanvas: {\n\t\t\t\t\tstyle: 'width: 320px; height: 240px'\n\t\t\t\t}\n\t\t\t});\n\n\t\t\texpect(chart).toBeChartOfSize({\n\t\t\t\tdw: 320, dh: 240,\n\t\t\t\trw: 960, rh: 720,\n\t\t\t});\n\t\t});\n\t});\n\n\tdescribe('controller.destroy', function() {\n\t\tit('should remove the resizer element when responsive: true', function() {\n\t\t\tvar chart = acquireChart({\n\t\t\t\toptions: {\n\t\t\t\t\tresponsive: true\n\t\t\t\t}\n\t\t\t});\n\n\t\t\tvar wrapper = chart.canvas.parentNode;\n\t\t\tvar resizer = wrapper.firstChild;\n\n\t\t\texpect(wrapper.childNodes.length).toBe(2);\n\t\t\texpect(resizer.tagName).toBe('IFRAME');\n\n\t\t\tchart.destroy();\n\n\t\t\texpect(wrapper.childNodes.length).toBe(1);\n\t\t\texpect(wrapper.firstChild.tagName).toBe('CANVAS');\n\t\t});\n\t});\n\n\tdescribe('controller.reset', function() {\n\t\tit('should reset the chart elements', function() {\n\t\t\tvar chart = acquireChart({\n\t\t\t\ttype: 'line',\n\t\t\t\tdata: {\n\t\t\t\t\tlabels: ['A', 'B', 'C', 'D'],\n\t\t\t\t\tdatasets: [{\n\t\t\t\t\t\tdata: [10, 20, 30, 0]\n\t\t\t\t\t}]\n\t\t\t\t},\n\t\t\t\toptions: {\n\t\t\t\t\tresponsive: true\n\t\t\t\t}\n\t\t\t});\n\n\t\t\tvar meta = chart.getDatasetMeta(0);\n\n\t\t\t// Verify that points are at their initial correct location,\n\t\t\t// then we will reset and see that they moved\n\t\t\texpect(meta.data[0]._model.y).toBe(333);\n\t\t\texpect(meta.data[1]._model.y).toBe(183);\n\t\t\texpect(meta.data[2]._model.y).toBe(32);\n\t\t\texpect(meta.data[3]._model.y).toBe(484);\n\n\t\t\tchart.reset();\n\n\t\t\t// For a line chart, the animation state is the bottom\n\t\t\texpect(meta.data[0]._model.y).toBe(484);\n\t\t\texpect(meta.data[1]._model.y).toBe(484);\n\t\t\texpect(meta.data[2]._model.y).toBe(484);\n\t\t\texpect(meta.data[3]._model.y).toBe(484);\n\t\t});\n\t});\n\n\tdescribe('config update', function() {\n\t\tit ('should update scales options', function() {\n\t\t\tvar chart = acquireChart({\n\t\t\t\ttype: 'line',\n\t\t\t\tdata: {\n\t\t\t\t\tlabels: ['A', 'B', 'C', 'D'],\n\t\t\t\t\tdatasets: [{\n\t\t\t\t\t\tdata: [10, 20, 30, 100]\n\t\t\t\t\t}]\n\t\t\t\t},\n\t\t\t\toptions: {\n\t\t\t\t\tresponsive: true\n\t\t\t\t}\n\t\t\t});\n\n\t\t\tchart.options.scales.yAxes[0].ticks.min = 0;\n\t\t\tchart.options.scales.yAxes[0].ticks.max = 10;\n\t\t\tchart.update();\n\n\t\t\tvar yScale = chart.scales['y-axis-0'];\n\t\t\texpect(yScale.options.ticks.min).toBe(0);\n\t\t\texpect(yScale.options.ticks.max).toBe(10);\n\t\t});\n\n\t\tit ('should update tooltip options', function() {\n\t\t\tvar chart = acquireChart({\n\t\t\t\ttype: 'line',\n\t\t\t\tdata: {\n\t\t\t\t\tlabels: ['A', 'B', 'C', 'D'],\n\t\t\t\t\tdatasets: [{\n\t\t\t\t\t\tdata: [10, 20, 30, 100]\n\t\t\t\t\t}]\n\t\t\t\t},\n\t\t\t\toptions: {\n\t\t\t\t\tresponsive: true\n\t\t\t\t}\n\t\t\t});\n\n\t\t\tvar newTooltipConfig = {\n\t\t\t\tmode: 'dataset',\n\t\t\t\tintersect: false\n\t\t\t};\n\t\t\tchart.options.tooltips = newTooltipConfig;\n\n\t\t\tchart.update();\n\t\t\texpect(chart.tooltip._options).toEqual(jasmine.objectContaining(newTooltipConfig));\n\t\t});\n\t});\n\n\tdescribe('plugin.extensions', function() {\n\t\tit ('should notify plugin in correct order', function(done) {\n\t\t\tvar plugin = this.plugin = {};\n\t\t\tvar sequence = [];\n\t\t\tvar hooks = {\n\t\t\t\tinit: [\n\t\t\t\t\t'beforeInit',\n\t\t\t\t\t'afterInit'\n\t\t\t\t],\n\t\t\t\tupdate: [\n\t\t\t\t\t'beforeUpdate',\n\t\t\t\t\t'beforeLayout',\n\t\t\t\t\t'afterLayout',\n\t\t\t\t\t'beforeDatasetsUpdate',\n\t\t\t\t\t'beforeDatasetUpdate',\n\t\t\t\t\t'afterDatasetUpdate',\n\t\t\t\t\t'afterDatasetsUpdate',\n\t\t\t\t\t'afterUpdate',\n\t\t\t\t],\n\t\t\t\trender: [\n\t\t\t\t\t'beforeRender',\n\t\t\t\t\t'beforeDraw',\n\t\t\t\t\t'beforeDatasetsDraw',\n\t\t\t\t\t'beforeDatasetDraw',\n\t\t\t\t\t'afterDatasetDraw',\n\t\t\t\t\t'afterDatasetsDraw',\n\t\t\t\t\t'afterDraw',\n\t\t\t\t\t'afterRender',\n\t\t\t\t],\n\t\t\t\tresize: [\n\t\t\t\t\t'resize'\n\t\t\t\t],\n\t\t\t\tdestroy: [\n\t\t\t\t\t'destroy'\n\t\t\t\t]\n\t\t\t};\n\n\t\t\tObject.keys(hooks).forEach(function(group) {\n\t\t\t\thooks[group].forEach(function(name) {\n\t\t\t\t\tplugin[name] = function() {\n\t\t\t\t\t\tsequence.push(name);\n\t\t\t\t\t};\n\t\t\t\t});\n\t\t\t});\n\n\t\t\tvar chart = window.acquireChart({\n\t\t\t\ttype: 'line',\n\t\t\t\tdata: {datasets: [{}]},\n\t\t\t\tplugins: [plugin],\n\t\t\t\toptions: {\n\t\t\t\t\tresponsive: true\n\t\t\t\t}\n\t\t\t}, {\n\t\t\t\twrapper: {\n\t\t\t\t\tstyle: 'width: 300px'\n\t\t\t\t}\n\t\t\t});\n\n\t\t\tchart.canvas.parentNode.style.width = '400px';\n\t\t\twaitForResize(chart, function() {\n\t\t\t\tchart.destroy();\n\n\t\t\t\texpect(sequence).toEqual([].concat(\n\t\t\t\t\thooks.init,\n\t\t\t\t\thooks.update,\n\t\t\t\t\thooks.render,\n\t\t\t\t\thooks.resize,\n\t\t\t\t\thooks.update,\n\t\t\t\t\thooks.render,\n\t\t\t\t\thooks.destroy\n\t\t\t\t));\n\n\t\t\t\tdone();\n\t\t\t});\n\t\t});\n\n\t\tit('should not notify before/afterDatasetDraw if dataset is hidden', function() {\n\t\t\tvar sequence = [];\n\t\t\tvar plugin = this.plugin = {\n\t\t\t\tbeforeDatasetDraw: function(chart, args) {\n\t\t\t\t\tsequence.push('before-' + args.index);\n\t\t\t\t},\n\t\t\t\tafterDatasetDraw: function(chart, args) {\n\t\t\t\t\tsequence.push('after-' + args.index);\n\t\t\t\t}\n\t\t\t};\n\n\t\t\twindow.acquireChart({\n\t\t\t\ttype: 'line',\n\t\t\t\tdata: {datasets: [{}, {hidden: true}, {}]},\n\t\t\t\tplugins: [plugin]\n\t\t\t});\n\n\t\t\texpect(sequence).toEqual([\n\t\t\t\t'before-2', 'after-2',\n\t\t\t\t'before-0', 'after-0'\n\t\t\t]);\n\t\t});\n\t});\n});\n"
  },
  {
    "path": "app_backend/static/plugin/Chart.js-2.6.0/test/specs/core.datasetController.tests.js",
    "content": "describe('Chart.DatasetController', function() {\n\tit('should listen for dataset data insertions or removals', function() {\n\t\tvar data = [0, 1, 2, 3, 4, 5];\n\t\tvar chart = acquireChart({\n\t\t\ttype: 'line',\n\t\t\tdata: {\n\t\t\t\tdatasets: [{\n\t\t\t\t\tdata: data\n\t\t\t\t}]\n\t\t\t}\n\t\t});\n\n\t\tvar controller = chart.getDatasetMeta(0).controller;\n\t\tvar methods = [\n\t\t\t'onDataPush',\n\t\t\t'onDataPop',\n\t\t\t'onDataShift',\n\t\t\t'onDataSplice',\n\t\t\t'onDataUnshift'\n\t\t];\n\n\t\tmethods.forEach(function(method) {\n\t\t\tspyOn(controller, method);\n\t\t});\n\n\t\tdata.push(6, 7, 8);\n\t\tdata.push(9);\n\t\tdata.pop();\n\t\tdata.shift();\n\t\tdata.shift();\n\t\tdata.shift();\n\t\tdata.splice(1, 4, 10, 11);\n\t\tdata.unshift(12, 13, 14, 15);\n\t\tdata.unshift(16, 17);\n\n\t\t[2, 1, 3, 1, 2].forEach(function(expected, index) {\n\t\t\texpect(controller[methods[index]].calls.count()).toBe(expected);\n\t\t});\n\t});\n\n\tit('should synchronize metadata when data are inserted or removed', function() {\n\t\tvar data = [0, 1, 2, 3, 4, 5];\n\t\tvar chart = acquireChart({\n\t\t\ttype: 'line',\n\t\t\tdata: {\n\t\t\t\tdatasets: [{\n\t\t\t\t\tdata: data\n\t\t\t\t}]\n\t\t\t}\n\t\t});\n\n\t\tvar meta = chart.getDatasetMeta(0);\n\t\tvar first, second, last;\n\n\t\tfirst = meta.data[0];\n\t\tlast = meta.data[5];\n\t\tdata.push(6, 7, 8);\n\t\tdata.push(9);\n\t\texpect(meta.data.length).toBe(10);\n\t\texpect(meta.data[0]).toBe(first);\n\t\texpect(meta.data[5]).toBe(last);\n\n\t\tlast = meta.data[9];\n\t\tdata.pop();\n\t\texpect(meta.data.length).toBe(9);\n\t\texpect(meta.data[0]).toBe(first);\n\t\texpect(meta.data.indexOf(last)).toBe(-1);\n\n\t\tlast = meta.data[8];\n\t\tdata.shift();\n\t\tdata.shift();\n\t\tdata.shift();\n\t\texpect(meta.data.length).toBe(6);\n\t\texpect(meta.data.indexOf(first)).toBe(-1);\n\t\texpect(meta.data[5]).toBe(last);\n\n\t\tfirst = meta.data[0];\n\t\tsecond = meta.data[1];\n\t\tlast = meta.data[5];\n\t\tdata.splice(1, 4, 10, 11);\n\t\texpect(meta.data.length).toBe(4);\n\t\texpect(meta.data[0]).toBe(first);\n\t\texpect(meta.data[3]).toBe(last);\n\t\texpect(meta.data.indexOf(second)).toBe(-1);\n\n\t\tdata.unshift(12, 13, 14, 15);\n\t\tdata.unshift(16, 17);\n\t\texpect(meta.data.length).toBe(10);\n\t\texpect(meta.data[6]).toBe(first);\n\t\texpect(meta.data[9]).toBe(last);\n\t});\n\n\tit('should re-synchronize metadata when the data object reference changes', function() {\n\t\tvar data0 = [0, 1, 2, 3, 4, 5];\n\t\tvar data1 = [6, 7, 8];\n\t\tvar chart = acquireChart({\n\t\t\ttype: 'line',\n\t\t\tdata: {\n\t\t\t\tdatasets: [{\n\t\t\t\t\tdata: data0\n\t\t\t\t}]\n\t\t\t}\n\t\t});\n\n\t\tvar meta = chart.getDatasetMeta(0);\n\n\t\texpect(meta.data.length).toBe(6);\n\n\t\tchart.data.datasets[0].data = data1;\n\t\tchart.update();\n\n\t\texpect(meta.data.length).toBe(3);\n\n\t\tdata1.push(9, 10, 11);\n\t\texpect(meta.data.length).toBe(6);\n\t});\n\n\tit('should re-synchronize metadata when data are unusually altered', function() {\n\t\tvar data = [0, 1, 2, 3, 4, 5];\n\t\tvar chart = acquireChart({\n\t\t\ttype: 'line',\n\t\t\tdata: {\n\t\t\t\tdatasets: [{\n\t\t\t\t\tdata: data\n\t\t\t\t}]\n\t\t\t}\n\t\t});\n\n\t\tvar meta = chart.getDatasetMeta(0);\n\n\t\texpect(meta.data.length).toBe(6);\n\n\t\tdata.length = 2;\n\t\tchart.update();\n\n\t\texpect(meta.data.length).toBe(2);\n\n\t\tdata.length = 42;\n\t\tchart.update();\n\n\t\texpect(meta.data.length).toBe(42);\n\t});\n\n\tit('should cleanup attached properties when the reference changes or when the chart is destroyed', function() {\n\t\tvar data0 = [0, 1, 2, 3, 4, 5];\n\t\tvar data1 = [6, 7, 8];\n\t\tvar chart = acquireChart({\n\t\t\ttype: 'line',\n\t\t\tdata: {\n\t\t\t\tdatasets: [{\n\t\t\t\t\tdata: data0\n\t\t\t\t}]\n\t\t\t}\n\t\t});\n\n\t\tvar hooks = ['push', 'pop', 'shift', 'splice', 'unshift'];\n\n\t\texpect(data0._chartjs).toBeDefined();\n\t\thooks.forEach(function(hook) {\n\t\t\texpect(data0[hook]).not.toBe(Array.prototype[hook]);\n\t\t});\n\n\t\texpect(data1._chartjs).not.toBeDefined();\n\t\thooks.forEach(function(hook) {\n\t\t\texpect(data1[hook]).toBe(Array.prototype[hook]);\n\t\t});\n\n\t\tchart.data.datasets[0].data = data1;\n\t\tchart.update();\n\n\t\texpect(data0._chartjs).not.toBeDefined();\n\t\thooks.forEach(function(hook) {\n\t\t\texpect(data0[hook]).toBe(Array.prototype[hook]);\n\t\t});\n\n\t\texpect(data1._chartjs).toBeDefined();\n\t\thooks.forEach(function(hook) {\n\t\t\texpect(data1[hook]).not.toBe(Array.prototype[hook]);\n\t\t});\n\n\t\tchart.destroy();\n\n\t\texpect(data1._chartjs).not.toBeDefined();\n\t\thooks.forEach(function(hook) {\n\t\t\texpect(data1[hook]).toBe(Array.prototype[hook]);\n\t\t});\n\t});\n});\n"
  },
  {
    "path": "app_backend/static/plugin/Chart.js-2.6.0/test/specs/core.element.tests.js",
    "content": "// Test the core element functionality\ndescribe('Core element tests', function() {\n\tit ('should transition model properties', function() {\n\t\tvar element = new Chart.Element({\n\t\t\t_model: {\n\t\t\t\tnumberProp: 0,\n\t\t\t\tnumberProp2: 100,\n\t\t\t\t_underscoreProp: 0,\n\t\t\t\tstringProp: 'abc',\n\t\t\t\tobjectProp: {\n\t\t\t\t\tmyObject: true\n\t\t\t\t},\n\t\t\t\tcolorProp: 'rgb(0, 0, 0)'\n\t\t\t}\n\t\t});\n\n\t\t// First transition clones model into view\n\t\telement.transition(0.25);\n\n\t\texpect(element._view).toEqual(element._model);\n\t\texpect(element._view.objectProp).toBe(element._model.objectProp); // not cloned\n\n\t\telement._model.numberProp = 100;\n\t\telement._model.numberProp2 = 250;\n\t\telement._model._underscoreProp = 200;\n\t\telement._model.stringProp = 'def';\n\t\telement._model.newStringProp = 'newString';\n\t\telement._model.colorProp = 'rgb(255, 255, 0)';\n\n\t\telement.transition(0.25);\n\n\t\texpect(element._view).toEqual({\n\t\t\tnumberProp: 25,\n\t\t\tnumberProp2: 137.5,\n\t\t\t_underscoreProp: 0, // underscore props are not transition to a new value\n\t\t\tstringProp: 'def',\n\t\t\tnewStringProp: 'newString',\n\t\t\tobjectProp: {\n\t\t\t\tmyObject: true\n\t\t\t},\n\t\t\tcolorProp: 'rgb(64, 64, 0)',\n\t\t});\n\t});\n});\n"
  },
  {
    "path": "app_backend/static/plugin/Chart.js-2.6.0/test/specs/core.helpers.tests.js",
    "content": "describe('Core helper tests', function() {\n\n\tvar helpers;\n\n\tbeforeAll(function() {\n\t\thelpers = window.Chart.helpers;\n\t});\n\n\tit('should iterate over an array and pass the extra data to that function', function() {\n\t\tvar testData = [0, 9, 'abc'];\n\t\tvar scope = {}; // fake out the scope and ensure that 'this' is the correct thing\n\n\t\thelpers.each(testData, function(item, index) {\n\t\t\texpect(item).not.toBe(undefined);\n\t\t\texpect(index).not.toBe(undefined);\n\n\t\t\texpect(testData[index]).toBe(item);\n\t\t\texpect(this).toBe(scope);\n\t\t}, scope);\n\n\t\t// Reverse iteration\n\t\tvar iterated = [];\n\t\thelpers.each(testData, function(item, index) {\n\t\t\texpect(item).not.toBe(undefined);\n\t\t\texpect(index).not.toBe(undefined);\n\n\t\t\texpect(testData[index]).toBe(item);\n\t\t\texpect(this).toBe(scope);\n\n\t\t\titerated.push(item);\n\t\t}, scope, true);\n\n\t\texpect(iterated.slice().reverse()).toEqual(testData);\n\t});\n\n\tit('should iterate over properties in an object', function() {\n\t\tvar testData = {\n\t\t\tmyProp1: 'abc',\n\t\t\tmyProp2: 276,\n\t\t\tmyProp3: ['a', 'b']\n\t\t};\n\n\t\thelpers.each(testData, function(value, key) {\n\t\t\tif (key === 'myProp1') {\n\t\t\t\texpect(value).toBe('abc');\n\t\t\t} else if (key === 'myProp2') {\n\t\t\t\texpect(value).toBe(276);\n\t\t\t} else if (key === 'myProp3') {\n\t\t\t\texpect(value).toEqual(['a', 'b']);\n\t\t\t} else {\n\t\t\t\texpect(false).toBe(true);\n\t\t\t}\n\t\t});\n\t});\n\n\tit('should not error when iterating over a null object', function() {\n\t\texpect(function() {\n\t\t\thelpers.each(undefined);\n\t\t}).not.toThrow();\n\t});\n\n\tit('should clone an object', function() {\n\t\tvar testData = {\n\t\t\tmyProp1: 'abc',\n\t\t\tmyProp2: ['a', 'b'],\n\t\t\tmyProp3: {\n\t\t\t\tmyProp4: 5,\n\t\t\t\tmyProp5: [1, 2]\n\t\t\t}\n\t\t};\n\n\t\tvar clone = helpers.clone(testData);\n\t\texpect(clone).toEqual(testData);\n\t\texpect(clone).not.toBe(testData);\n\n\t\texpect(clone.myProp2).not.toBe(testData.myProp2);\n\t\texpect(clone.myProp3).not.toBe(testData.myProp3);\n\t\texpect(clone.myProp3.myProp5).not.toBe(testData.myProp3.myProp5);\n\t});\n\n\tit('should extend an object', function() {\n\t\tvar original = {\n\t\t\tmyProp1: 'abc',\n\t\t\tmyProp2: 56\n\t\t};\n\n\t\tvar extension = {\n\t\t\tmyProp3: [2, 5, 6],\n\t\t\tmyProp2: 0\n\t\t};\n\n\t\thelpers.extend(original, extension);\n\n\t\texpect(original).toEqual({\n\t\t\tmyProp1: 'abc',\n\t\t\tmyProp2: 0,\n\t\t\tmyProp3: [2, 5, 6],\n\t\t});\n\t});\n\n\tit('should merge a normal config without scales', function() {\n\t\tvar baseConfig = {\n\t\t\tvalueProp: 5,\n\t\t\tarrayProp: [1, 2, 3, 4, 5, 6],\n\t\t\tobjectProp: {\n\t\t\t\tprop1: 'abc',\n\t\t\t\tprop2: 56\n\t\t\t}\n\t\t};\n\n\t\tvar toMerge = {\n\t\t\tvalueProp2: null,\n\t\t\tarrayProp: ['a', 'c'],\n\t\t\tobjectProp: {\n\t\t\t\tprop1: 'c',\n\t\t\t\tprop3: 'prop3'\n\t\t\t}\n\t\t};\n\n\t\tvar merged = helpers.configMerge(baseConfig, toMerge);\n\t\texpect(merged).toEqual({\n\t\t\tvalueProp: 5,\n\t\t\tvalueProp2: null,\n\t\t\tarrayProp: ['a', 'c'],\n\t\t\tobjectProp: {\n\t\t\t\tprop1: 'c',\n\t\t\t\tprop2: 56,\n\t\t\t\tprop3: 'prop3'\n\t\t\t}\n\t\t});\n\t});\n\n\tit('should merge scale configs', function() {\n\t\tvar baseConfig = {\n\t\t\tscales: {\n\t\t\t\tprop1: {\n\t\t\t\t\tabc: 123,\n\t\t\t\t\tdef: '456'\n\t\t\t\t},\n\t\t\t\tprop2: 777,\n\t\t\t\tyAxes: [{\n\t\t\t\t\ttype: 'linear',\n\t\t\t\t}, {\n\t\t\t\t\ttype: 'log'\n\t\t\t\t}]\n\t\t\t}\n\t\t};\n\n\t\tvar toMerge = {\n\t\t\tscales: {\n\t\t\t\tprop1: {\n\t\t\t\t\tdef: 'bbb',\n\t\t\t\t\tghi: 78\n\t\t\t\t},\n\t\t\t\tprop2: null,\n\t\t\t\tyAxes: [{\n\t\t\t\t\ttype: 'linear',\n\t\t\t\t\taxisProp: 456\n\t\t\t\t}, {\n\t\t\t\t\t// pulls in linear default config since axis type changes\n\t\t\t\t\ttype: 'linear',\n\t\t\t\t\tposition: 'right'\n\t\t\t\t}, {\n\t\t\t\t\t// Pulls in linear default config since axis not in base\n\t\t\t\t\ttype: 'linear'\n\t\t\t\t}]\n\t\t\t}\n\t\t};\n\n\t\tvar merged = helpers.configMerge(baseConfig, toMerge);\n\t\texpect(merged).toEqual({\n\t\t\tscales: {\n\t\t\t\tprop1: {\n\t\t\t\t\tabc: 123,\n\t\t\t\t\tdef: 'bbb',\n\t\t\t\t\tghi: 78\n\t\t\t\t},\n\t\t\t\tprop2: null,\n\t\t\t\tyAxes: [{\n\t\t\t\t\ttype: 'linear',\n\t\t\t\t\taxisProp: 456\n\t\t\t\t}, {\n\t\t\t\t\tdisplay: true,\n\n\t\t\t\t\tgridLines: {\n\t\t\t\t\t\tcolor: 'rgba(0, 0, 0, 0.1)',\n\t\t\t\t\t\tdrawBorder: true,\n\t\t\t\t\t\tdrawOnChartArea: true,\n\t\t\t\t\t\tdrawTicks: true, // draw ticks extending towards the label\n\t\t\t\t\t\ttickMarkLength: 10,\n\t\t\t\t\t\tlineWidth: 1,\n\t\t\t\t\t\toffsetGridLines: false,\n\t\t\t\t\t\tdisplay: true,\n\t\t\t\t\t\tzeroLineColor: 'rgba(0,0,0,0.25)',\n\t\t\t\t\t\tzeroLineWidth: 1,\n\t\t\t\t\t\tzeroLineBorderDash: [],\n\t\t\t\t\t\tzeroLineBorderDashOffset: 0.0,\n\t\t\t\t\t\tborderDash: [],\n\t\t\t\t\t\tborderDashOffset: 0.0\n\t\t\t\t\t},\n\t\t\t\t\tposition: 'right',\n\t\t\t\t\tscaleLabel: {\n\t\t\t\t\t\tlabelString: '',\n\t\t\t\t\t\tdisplay: false,\n\t\t\t\t\t},\n\t\t\t\t\tticks: {\n\t\t\t\t\t\tbeginAtZero: false,\n\t\t\t\t\t\tminRotation: 0,\n\t\t\t\t\t\tmaxRotation: 50,\n\t\t\t\t\t\tmirror: false,\n\t\t\t\t\t\tpadding: 0,\n\t\t\t\t\t\treverse: false,\n\t\t\t\t\t\tdisplay: true,\n\t\t\t\t\t\tcallback: merged.scales.yAxes[1].ticks.callback, // make it nicer, then check explicitly below\n\t\t\t\t\t\tautoSkip: true,\n\t\t\t\t\t\tautoSkipPadding: 0,\n\t\t\t\t\t\tlabelOffset: 0,\n\t\t\t\t\t},\n\t\t\t\t\ttype: 'linear'\n\t\t\t\t}, {\n\t\t\t\t\tdisplay: true,\n\n\t\t\t\t\tgridLines: {\n\t\t\t\t\t\tcolor: 'rgba(0, 0, 0, 0.1)',\n\t\t\t\t\t\tdrawBorder: true,\n\t\t\t\t\t\tdrawOnChartArea: true,\n\t\t\t\t\t\tdrawTicks: true, // draw ticks extending towards the label,\n\t\t\t\t\t\ttickMarkLength: 10,\n\t\t\t\t\t\tlineWidth: 1,\n\t\t\t\t\t\toffsetGridLines: false,\n\t\t\t\t\t\tdisplay: true,\n\t\t\t\t\t\tzeroLineColor: 'rgba(0,0,0,0.25)',\n\t\t\t\t\t\tzeroLineWidth: 1,\n\t\t\t\t\t\tzeroLineBorderDash: [],\n\t\t\t\t\t\tzeroLineBorderDashOffset: 0.0,\n\t\t\t\t\t\tborderDash: [],\n\t\t\t\t\t\tborderDashOffset: 0.0\n\t\t\t\t\t},\n\t\t\t\t\tposition: 'left',\n\t\t\t\t\tscaleLabel: {\n\t\t\t\t\t\tlabelString: '',\n\t\t\t\t\t\tdisplay: false,\n\t\t\t\t\t},\n\t\t\t\t\tticks: {\n\t\t\t\t\t\tbeginAtZero: false,\n\t\t\t\t\t\tminRotation: 0,\n\t\t\t\t\t\tmaxRotation: 50,\n\t\t\t\t\t\tmirror: false,\n\t\t\t\t\t\tpadding: 0,\n\t\t\t\t\t\treverse: false,\n\t\t\t\t\t\tdisplay: true,\n\t\t\t\t\t\tcallback: merged.scales.yAxes[2].ticks.callback, // make it nicer, then check explicitly below\n\t\t\t\t\t\tautoSkip: true,\n\t\t\t\t\t\tautoSkipPadding: 0,\n\t\t\t\t\t\tlabelOffset: 0,\n\t\t\t\t\t},\n\t\t\t\t\ttype: 'linear'\n\t\t\t\t}]\n\t\t\t}\n\t\t});\n\n\t\t// Are these actually functions\n\t\texpect(merged.scales.yAxes[1].ticks.callback).toEqual(jasmine.any(Function));\n\t\texpect(merged.scales.yAxes[2].ticks.callback).toEqual(jasmine.any(Function));\n\t});\n\n\tit('should get value or default', function() {\n\t\texpect(helpers.getValueAtIndexOrDefault(98, 0, 56)).toBe(98);\n\t\texpect(helpers.getValueAtIndexOrDefault(0, 0, 56)).toBe(0);\n\t\texpect(helpers.getValueAtIndexOrDefault(undefined, undefined, 56)).toBe(56);\n\t\texpect(helpers.getValueAtIndexOrDefault([1, 2, 3], 1, 100)).toBe(2);\n\t\texpect(helpers.getValueAtIndexOrDefault([1, 2, 3], 3, 100)).toBe(100);\n\t});\n\n\tit('should filter an array', function() {\n\t\tvar data = [-10, 0, 6, 0, 7];\n\t\tvar callback = function(item) {\n\t\t\treturn item > 2;\n\t\t};\n\t\texpect(helpers.where(data, callback)).toEqual([6, 7]);\n\t\texpect(helpers.findNextWhere(data, callback)).toEqual(6);\n\t\texpect(helpers.findNextWhere(data, callback, 2)).toBe(7);\n\t\texpect(helpers.findNextWhere(data, callback, 4)).toBe(undefined);\n\t\texpect(helpers.findPreviousWhere(data, callback)).toBe(7);\n\t\texpect(helpers.findPreviousWhere(data, callback, 3)).toBe(6);\n\t\texpect(helpers.findPreviousWhere(data, callback, 0)).toBe(undefined);\n\t});\n\n\tit('should get the correct sign', function() {\n\t\texpect(helpers.sign(0)).toBe(0);\n\t\texpect(helpers.sign(10)).toBe(1);\n\t\texpect(helpers.sign(-5)).toBe(-1);\n\t});\n\n\tit('should do a log10 operation', function() {\n\t\texpect(helpers.log10(0)).toBe(-Infinity);\n\t\texpect(helpers.log10(1)).toBe(0);\n\t\texpect(helpers.log10(1000)).toBeCloseTo(3, 1e-9);\n\t});\n\n\tit('should correctly determine if two numbers are essentially equal', function() {\n\t\texpect(helpers.almostEquals(0, Number.EPSILON, 2 * Number.EPSILON)).toBe(true);\n\t\texpect(helpers.almostEquals(1, 1.1, 0.0001)).toBe(false);\n\t\texpect(helpers.almostEquals(1e30, 1e30 + Number.EPSILON, 0)).toBe(false);\n\t\texpect(helpers.almostEquals(1e30, 1e30 + Number.EPSILON, 2 * Number.EPSILON)).toBe(true);\n\t});\n\n\tit('should correctly determine if a numbers are essentially whole', function() {\n\t\texpect(helpers.almostWhole(0.99999, 0.0001)).toBe(true);\n\t\texpect(helpers.almostWhole(0.9, 0.0001)).toBe(false);\n\t});\n\n\tit('should generate integer ids', function() {\n\t\tvar uid = helpers.uid();\n\t\texpect(uid).toEqual(jasmine.any(Number));\n\t\texpect(helpers.uid()).toBe(uid + 1);\n\t\texpect(helpers.uid()).toBe(uid + 2);\n\t\texpect(helpers.uid()).toBe(uid + 3);\n\t});\n\n\tit('should detect a number', function() {\n\t\texpect(helpers.isNumber(123)).toBe(true);\n\t\texpect(helpers.isNumber('123')).toBe(true);\n\t\texpect(helpers.isNumber(null)).toBe(false);\n\t\texpect(helpers.isNumber(NaN)).toBe(false);\n\t\texpect(helpers.isNumber(undefined)).toBe(false);\n\t\texpect(helpers.isNumber('cbc')).toBe(false);\n\t});\n\n\tit('should convert between radians and degrees', function() {\n\t\texpect(helpers.toRadians(180)).toBe(Math.PI);\n\t\texpect(helpers.toRadians(90)).toBe(0.5 * Math.PI);\n\t\texpect(helpers.toDegrees(Math.PI)).toBe(180);\n\t\texpect(helpers.toDegrees(Math.PI * 3 / 2)).toBe(270);\n\t});\n\n\tit('should get an angle from a point', function() {\n\t\tvar center = {\n\t\t\tx: 0,\n\t\t\ty: 0\n\t\t};\n\n\t\texpect(helpers.getAngleFromPoint(center, {\n\t\t\tx: 0,\n\t\t\ty: 10\n\t\t})).toEqual({\n\t\t\tangle: Math.PI / 2,\n\t\t\tdistance: 10,\n\t\t});\n\n\t\texpect(helpers.getAngleFromPoint(center, {\n\t\t\tx: Math.sqrt(2),\n\t\t\ty: Math.sqrt(2)\n\t\t})).toEqual({\n\t\t\tangle: Math.PI / 4,\n\t\t\tdistance: 2\n\t\t});\n\n\t\texpect(helpers.getAngleFromPoint(center, {\n\t\t\tx: -1.0 * Math.sqrt(2),\n\t\t\ty: -1.0 * Math.sqrt(2)\n\t\t})).toEqual({\n\t\t\tangle: Math.PI * 1.25,\n\t\t\tdistance: 2\n\t\t});\n\t});\n\n\tit('should spline curves', function() {\n\t\texpect(helpers.splineCurve({\n\t\t\tx: 0,\n\t\t\ty: 0\n\t\t}, {\n\t\t\tx: 1,\n\t\t\ty: 1\n\t\t}, {\n\t\t\tx: 2,\n\t\t\ty: 0\n\t\t}, 0)).toEqual({\n\t\t\tprevious: {\n\t\t\t\tx: 1,\n\t\t\t\ty: 1,\n\t\t\t},\n\t\t\tnext: {\n\t\t\t\tx: 1,\n\t\t\t\ty: 1,\n\t\t\t}\n\t\t});\n\n\t\texpect(helpers.splineCurve({\n\t\t\tx: 0,\n\t\t\ty: 0\n\t\t}, {\n\t\t\tx: 1,\n\t\t\ty: 1\n\t\t}, {\n\t\t\tx: 2,\n\t\t\ty: 0\n\t\t}, 1)).toEqual({\n\t\t\tprevious: {\n\t\t\t\tx: 0,\n\t\t\t\ty: 1,\n\t\t\t},\n\t\t\tnext: {\n\t\t\t\tx: 2,\n\t\t\t\ty: 1,\n\t\t\t}\n\t\t});\n\t});\n\n\tit('should spline curves with monotone cubic interpolation', function() {\n\t\tvar dataPoints = [\n\t\t\t{_model: {x: 0, y: 0, skip: false}},\n\t\t\t{_model: {x: 3, y: 6, skip: false}},\n\t\t\t{_model: {x: 9, y: 6, skip: false}},\n\t\t\t{_model: {x: 12, y: 60, skip: false}},\n\t\t\t{_model: {x: 15, y: 60, skip: false}},\n\t\t\t{_model: {x: 18, y: 120, skip: false}},\n\t\t\t{_model: {x: null, y: null, skip: true}},\n\t\t\t{_model: {x: 21, y: 180, skip: false}},\n\t\t\t{_model: {x: 24, y: 120, skip: false}},\n\t\t\t{_model: {x: 27, y: 125, skip: false}},\n\t\t\t{_model: {x: 30, y: 105, skip: false}},\n\t\t\t{_model: {x: 33, y: 110, skip: false}},\n\t\t\t{_model: {x: 33, y: 110, skip: false}},\n\t\t\t{_model: {x: 36, y: 170, skip: false}}\n\t\t];\n\t\thelpers.splineCurveMonotone(dataPoints);\n\t\texpect(dataPoints).toEqual([{\n\t\t\t_model: {\n\t\t\t\tx: 0,\n\t\t\t\ty: 0,\n\t\t\t\tskip: false,\n\t\t\t\tcontrolPointNextX: 1,\n\t\t\t\tcontrolPointNextY: 2\n\t\t\t}\n\t\t},\n\t\t{\n\t\t\t_model: {\n\t\t\t\tx: 3,\n\t\t\t\ty: 6,\n\t\t\t\tskip: false,\n\t\t\t\tcontrolPointPreviousX: 2,\n\t\t\t\tcontrolPointPreviousY: 6,\n\t\t\t\tcontrolPointNextX: 5,\n\t\t\t\tcontrolPointNextY: 6\n\t\t\t}\n\t\t},\n\t\t{\n\t\t\t_model: {\n\t\t\t\tx: 9,\n\t\t\t\ty: 6,\n\t\t\t\tskip: false,\n\t\t\t\tcontrolPointPreviousX: 7,\n\t\t\t\tcontrolPointPreviousY: 6,\n\t\t\t\tcontrolPointNextX: 10,\n\t\t\t\tcontrolPointNextY: 6\n\t\t\t}\n\t\t},\n\t\t{\n\t\t\t_model: {\n\t\t\t\tx: 12,\n\t\t\t\ty: 60,\n\t\t\t\tskip: false,\n\t\t\t\tcontrolPointPreviousX: 11,\n\t\t\t\tcontrolPointPreviousY: 60,\n\t\t\t\tcontrolPointNextX: 13,\n\t\t\t\tcontrolPointNextY: 60\n\t\t\t}\n\t\t},\n\t\t{\n\t\t\t_model: {\n\t\t\t\tx: 15,\n\t\t\t\ty: 60,\n\t\t\t\tskip: false,\n\t\t\t\tcontrolPointPreviousX: 14,\n\t\t\t\tcontrolPointPreviousY: 60,\n\t\t\t\tcontrolPointNextX: 16,\n\t\t\t\tcontrolPointNextY: 60\n\t\t\t}\n\t\t},\n\t\t{\n\t\t\t_model: {\n\t\t\t\tx: 18,\n\t\t\t\ty: 120,\n\t\t\t\tskip: false,\n\t\t\t\tcontrolPointPreviousX: 17,\n\t\t\t\tcontrolPointPreviousY: 100\n\t\t\t}\n\t\t},\n\t\t{\n\t\t\t_model: {\n\t\t\t\tx: null,\n\t\t\t\ty: null,\n\t\t\t\tskip: true\n\t\t\t}\n\t\t},\n\t\t{\n\t\t\t_model: {\n\t\t\t\tx: 21,\n\t\t\t\ty: 180,\n\t\t\t\tskip: false,\n\t\t\t\tcontrolPointNextX: 22,\n\t\t\t\tcontrolPointNextY: 160\n\t\t\t}\n\t\t},\n\t\t{\n\t\t\t_model: {\n\t\t\t\tx: 24,\n\t\t\t\ty: 120,\n\t\t\t\tskip: false,\n\t\t\t\tcontrolPointPreviousX: 23,\n\t\t\t\tcontrolPointPreviousY: 120,\n\t\t\t\tcontrolPointNextX: 25,\n\t\t\t\tcontrolPointNextY: 120\n\t\t\t}\n\t\t},\n\t\t{\n\t\t\t_model: {\n\t\t\t\tx: 27,\n\t\t\t\ty: 125,\n\t\t\t\tskip: false,\n\t\t\t\tcontrolPointPreviousX: 26,\n\t\t\t\tcontrolPointPreviousY: 125,\n\t\t\t\tcontrolPointNextX: 28,\n\t\t\t\tcontrolPointNextY: 125\n\t\t\t}\n\t\t},\n\t\t{\n\t\t\t_model: {\n\t\t\t\tx: 30,\n\t\t\t\ty: 105,\n\t\t\t\tskip: false,\n\t\t\t\tcontrolPointPreviousX: 29,\n\t\t\t\tcontrolPointPreviousY: 105,\n\t\t\t\tcontrolPointNextX: 31,\n\t\t\t\tcontrolPointNextY: 105\n\t\t\t}\n\t\t},\n\t\t{\n\t\t\t_model: {\n\t\t\t\tx: 33,\n\t\t\t\ty: 110,\n\t\t\t\tskip: false,\n\t\t\t\tcontrolPointPreviousX: 32,\n\t\t\t\tcontrolPointPreviousY: 110,\n\t\t\t\tcontrolPointNextX: 33,\n\t\t\t\tcontrolPointNextY: 110\n\t\t\t}\n\t\t},\n\t\t{\n\t\t\t_model: {\n\t\t\t\tx: 33,\n\t\t\t\ty: 110,\n\t\t\t\tskip: false,\n\t\t\t\tcontrolPointPreviousX: 33,\n\t\t\t\tcontrolPointPreviousY: 110,\n\t\t\t\tcontrolPointNextX: 34,\n\t\t\t\tcontrolPointNextY: 110\n\t\t\t}\n\t\t},\n\t\t{\n\t\t\t_model: {\n\t\t\t\tx: 36,\n\t\t\t\ty: 170,\n\t\t\t\tskip: false,\n\t\t\t\tcontrolPointPreviousX: 35,\n\t\t\t\tcontrolPointPreviousY: 150\n\t\t\t}\n\t\t}]);\n\t});\n\n\tit('should get the next or previous item in an array', function() {\n\t\tvar testData = [0, 1, 2];\n\n\t\texpect(helpers.nextItem(testData, 0, false)).toEqual(1);\n\t\texpect(helpers.nextItem(testData, 2, false)).toEqual(2);\n\t\texpect(helpers.nextItem(testData, 2, true)).toEqual(0);\n\t\texpect(helpers.nextItem(testData, 1, true)).toEqual(2);\n\t\texpect(helpers.nextItem(testData, -1, false)).toEqual(0);\n\n\t\texpect(helpers.previousItem(testData, 0, false)).toEqual(0);\n\t\texpect(helpers.previousItem(testData, 0, true)).toEqual(2);\n\t\texpect(helpers.previousItem(testData, 2, false)).toEqual(1);\n\t\texpect(helpers.previousItem(testData, 1, true)).toEqual(0);\n\t});\n\n\tit('should clear a canvas', function() {\n\t\tvar context = window.createMockContext();\n\t\thelpers.clear({\n\t\t\twidth: 100,\n\t\t\theight: 150,\n\t\t\tctx: context\n\t\t});\n\n\t\texpect(context.getCalls()).toEqual([{\n\t\t\tname: 'clearRect',\n\t\t\targs: [0, 0, 100, 150]\n\t\t}]);\n\t});\n\n\tit('should return the width of the longest text in an Array and 2D Array', function() {\n\t\tvar context = window.createMockContext();\n\t\tvar font = \"normal 12px 'Helvetica Neue', 'Helvetica', 'Arial', sans-serif\";\n\t\tvar arrayOfThings1D = ['FooBar', 'Bar'];\n\t\tvar arrayOfThings2D = [['FooBar_1', 'Bar_2'], 'Foo_1'];\n\n\n\t\t// Regardless 'FooBar' is the longest label it should return (characters * 10)\n\t\texpect(helpers.longestText(context, font, arrayOfThings1D, {})).toEqual(60);\n\t\texpect(helpers.longestText(context, font, arrayOfThings2D, {})).toEqual(80);\n\t\t// We check to make sure we made the right calls to the canvas.\n\t\texpect(context.getCalls()).toEqual([{\n\t\t\tname: 'measureText',\n\t\t\targs: ['FooBar']\n\t\t}, {\n\t\t\tname: 'measureText',\n\t\t\targs: ['Bar']\n\t\t}, {\n\t\t\tname: 'measureText',\n\t\t\targs: ['FooBar_1']\n\t\t}, {\n\t\t\tname: 'measureText',\n\t\t\targs: ['Bar_2']\n\t\t}, {\n\t\t\tname: 'measureText',\n\t\t\targs: ['Foo_1']\n\t\t}]);\n\t});\n\n\tit('compare text with current longest and update', function() {\n\t\tvar context = window.createMockContext();\n\t\tvar data = {};\n\t\tvar gc = [];\n\t\tvar longest = 70;\n\n\t\texpect(helpers.measureText(context, data, gc, longest, 'foobar')).toEqual(70);\n\t\texpect(helpers.measureText(context, data, gc, longest, 'foobar_')).toEqual(70);\n\t\texpect(helpers.measureText(context, data, gc, longest, 'foobar_1')).toEqual(80);\n\t\t// We check to make sure we made the right calls to the canvas.\n\t\texpect(context.getCalls()).toEqual([{\n\t\t\tname: 'measureText',\n\t\t\targs: ['foobar']\n\t\t}, {\n\t\t\tname: 'measureText',\n\t\t\targs: ['foobar_']\n\t\t}, {\n\t\t\tname: 'measureText',\n\t\t\targs: ['foobar_1']\n\t\t}]);\n\t});\n\n\tit('count look at all the labels and return maximum number of lines', function() {\n\t\twindow.createMockContext();\n\t\tvar arrayOfThings1 = ['Foo', 'Bar'];\n\t\tvar arrayOfThings2 = [['Foo', 'Bar'], 'Foo'];\n\t\tvar arrayOfThings3 = [['Foo', 'Bar', 'Boo'], ['Foo', 'Bar'], 'Foo'];\n\n\t\texpect(helpers.numberOfLabelLines(arrayOfThings1)).toEqual(1);\n\t\texpect(helpers.numberOfLabelLines(arrayOfThings2)).toEqual(2);\n\t\texpect(helpers.numberOfLabelLines(arrayOfThings3)).toEqual(3);\n\t});\n\n\tit('should draw a rounded rectangle', function() {\n\t\tvar context = window.createMockContext();\n\t\thelpers.drawRoundedRectangle(context, 10, 20, 30, 40, 5);\n\n\t\texpect(context.getCalls()).toEqual([{\n\t\t\tname: 'beginPath',\n\t\t\targs: []\n\t\t}, {\n\t\t\tname: 'moveTo',\n\t\t\targs: [15, 20]\n\t\t}, {\n\t\t\tname: 'lineTo',\n\t\t\targs: [35, 20]\n\t\t}, {\n\t\t\tname: 'quadraticCurveTo',\n\t\t\targs: [40, 20, 40, 25]\n\t\t}, {\n\t\t\tname: 'lineTo',\n\t\t\targs: [40, 55]\n\t\t}, {\n\t\t\tname: 'quadraticCurveTo',\n\t\t\targs: [40, 60, 35, 60]\n\t\t}, {\n\t\t\tname: 'lineTo',\n\t\t\targs: [15, 60]\n\t\t}, {\n\t\t\tname: 'quadraticCurveTo',\n\t\t\targs: [10, 60, 10, 55]\n\t\t}, {\n\t\t\tname: 'lineTo',\n\t\t\targs: [10, 25]\n\t\t}, {\n\t\t\tname: 'quadraticCurveTo',\n\t\t\targs: [10, 20, 15, 20]\n\t\t}, {\n\t\t\tname: 'closePath',\n\t\t\targs: []\n\t\t}]);\n\t});\n\n\tit ('should get the maximum width and height for a node', function() {\n\t\t// Create div with fixed size as a test bed\n\t\tvar div = document.createElement('div');\n\t\tdiv.style.width = '200px';\n\t\tdiv.style.height = '300px';\n\n\t\tdocument.body.appendChild(div);\n\n\t\t// Create the div we want to get the max size for\n\t\tvar innerDiv = document.createElement('div');\n\t\tdiv.appendChild(innerDiv);\n\n\t\texpect(helpers.getMaximumWidth(innerDiv)).toBe(200);\n\t\texpect(helpers.getMaximumHeight(innerDiv)).toBe(300);\n\n\t\tdocument.body.removeChild(div);\n\t});\n\n\tit ('should get the maximum width of a node that has a max-width style', function() {\n\t\t// Create div with fixed size as a test bed\n\t\tvar div = document.createElement('div');\n\t\tdiv.style.width = '200px';\n\t\tdiv.style.height = '300px';\n\n\t\tdocument.body.appendChild(div);\n\n\t\t// Create the div we want to get the max size for and set a max-width style\n\t\tvar innerDiv = document.createElement('div');\n\t\tinnerDiv.style.maxWidth = '150px';\n\t\tdiv.appendChild(innerDiv);\n\n\t\texpect(helpers.getMaximumWidth(innerDiv)).toBe(150);\n\n\t\tdocument.body.removeChild(div);\n\t});\n\n\tit ('should get the maximum height of a node that has a max-height style', function() {\n\t\t// Create div with fixed size as a test bed\n\t\tvar div = document.createElement('div');\n\t\tdiv.style.width = '200px';\n\t\tdiv.style.height = '300px';\n\n\t\tdocument.body.appendChild(div);\n\n\t\t// Create the div we want to get the max size for and set a max-height style\n\t\tvar innerDiv = document.createElement('div');\n\t\tinnerDiv.style.maxHeight = '150px';\n\t\tdiv.appendChild(innerDiv);\n\n\t\texpect(helpers.getMaximumHeight(innerDiv)).toBe(150);\n\n\t\tdocument.body.removeChild(div);\n\t});\n\n\tit ('should get the maximum width of a node when the parent has a max-width style', function() {\n\t\t// Create div with fixed size as a test bed\n\t\tvar div = document.createElement('div');\n\t\tdiv.style.width = '200px';\n\t\tdiv.style.height = '300px';\n\n\t\tdocument.body.appendChild(div);\n\n\t\t// Create an inner wrapper around our div we want to size and give that a max-width style\n\t\tvar parentDiv = document.createElement('div');\n\t\tparentDiv.style.maxWidth = '150px';\n\t\tdiv.appendChild(parentDiv);\n\n\t\t// Create the div we want to get the max size for\n\t\tvar innerDiv = document.createElement('div');\n\t\tparentDiv.appendChild(innerDiv);\n\n\t\texpect(helpers.getMaximumWidth(innerDiv)).toBe(150);\n\n\t\tdocument.body.removeChild(div);\n\t});\n\n\tit ('should get the maximum height of a node when the parent has a max-height style', function() {\n\t\t// Create div with fixed size as a test bed\n\t\tvar div = document.createElement('div');\n\t\tdiv.style.width = '200px';\n\t\tdiv.style.height = '300px';\n\n\t\tdocument.body.appendChild(div);\n\n\t\t// Create an inner wrapper around our div we want to size and give that a max-height style\n\t\tvar parentDiv = document.createElement('div');\n\t\tparentDiv.style.maxHeight = '150px';\n\t\tdiv.appendChild(parentDiv);\n\n\t\t// Create the div we want to get the max size for\n\t\tvar innerDiv = document.createElement('div');\n\t\tinnerDiv.style.height = '300px'; // make it large\n\t\tparentDiv.appendChild(innerDiv);\n\n\t\texpect(helpers.getMaximumHeight(innerDiv)).toBe(150);\n\n\t\tdocument.body.removeChild(div);\n\t});\n\n\tit ('should get the maximum width of a node that has a percentage max-width style', function() {\n\t\t// Create div with fixed size as a test bed\n\t\tvar div = document.createElement('div');\n\t\tdiv.style.width = '200px';\n\t\tdiv.style.height = '300px';\n\n\t\tdocument.body.appendChild(div);\n\n\t\t// Create the div we want to get the max size for and set a max-width style\n\t\tvar innerDiv = document.createElement('div');\n\t\tinnerDiv.style.maxWidth = '50%';\n\t\tdiv.appendChild(innerDiv);\n\n\t\texpect(helpers.getMaximumWidth(innerDiv)).toBe(100);\n\n\t\tdocument.body.removeChild(div);\n\t});\n\n\tit ('should get the maximum height of a node that has a percentage max-height style', function() {\n\t\t// Create div with fixed size as a test bed\n\t\tvar div = document.createElement('div');\n\t\tdiv.style.width = '200px';\n\t\tdiv.style.height = '300px';\n\n\t\tdocument.body.appendChild(div);\n\n\t\t// Create the div we want to get the max size for and set a max-height style\n\t\tvar innerDiv = document.createElement('div');\n\t\tinnerDiv.style.maxHeight = '50%';\n\t\tdiv.appendChild(innerDiv);\n\n\t\texpect(helpers.getMaximumHeight(innerDiv)).toBe(150);\n\n\t\tdocument.body.removeChild(div);\n\t});\n\n\tit ('should get the maximum width of a node when the parent has a percentage max-width style', function() {\n\t\t// Create div with fixed size as a test bed\n\t\tvar div = document.createElement('div');\n\t\tdiv.style.width = '200px';\n\t\tdiv.style.height = '300px';\n\n\t\tdocument.body.appendChild(div);\n\n\t\t// Create an inner wrapper around our div we want to size and give that a max-width style\n\t\tvar parentDiv = document.createElement('div');\n\t\tparentDiv.style.maxWidth = '50%';\n\t\tdiv.appendChild(parentDiv);\n\n\t\t// Create the div we want to get the max size for\n\t\tvar innerDiv = document.createElement('div');\n\t\tparentDiv.appendChild(innerDiv);\n\n\t\texpect(helpers.getMaximumWidth(innerDiv)).toBe(100);\n\n\t\tdocument.body.removeChild(div);\n\t});\n\n\tit ('should get the maximum height of a node when the parent has a percentage max-height style', function() {\n\t\t// Create div with fixed size as a test bed\n\t\tvar div = document.createElement('div');\n\t\tdiv.style.width = '200px';\n\t\tdiv.style.height = '300px';\n\n\t\tdocument.body.appendChild(div);\n\n\t\t// Create an inner wrapper around our div we want to size and give that a max-height style\n\t\tvar parentDiv = document.createElement('div');\n\t\tparentDiv.style.maxHeight = '50%';\n\t\tdiv.appendChild(parentDiv);\n\n\t\tvar innerDiv = document.createElement('div');\n\t\tinnerDiv.style.height = '300px'; // make it large\n\t\tparentDiv.appendChild(innerDiv);\n\n\t\texpect(helpers.getMaximumHeight(innerDiv)).toBe(150);\n\n\t\tdocument.body.removeChild(div);\n\t});\n\n\tdescribe('Color helper', function() {\n\t\tfunction isColorInstance(obj) {\n\t\t\treturn typeof obj === 'object' && obj.hasOwnProperty('values') && obj.values.hasOwnProperty('rgb');\n\t\t}\n\n\t\tit('should return a color when called with a color', function() {\n\t\t\texpect(isColorInstance(helpers.color('rgb(1, 2, 3)'))).toBe(true);\n\t\t});\n\n\t\tit('should return a color when called with a CanvasGradient instance', function() {\n\t\t\tvar context = document.createElement('canvas').getContext('2d');\n\t\t\tvar gradient = context.createLinearGradient(0, 1, 2, 3);\n\n\t\t\texpect(isColorInstance(helpers.color(gradient))).toBe(true);\n\t\t});\n\t});\n\n\tdescribe('Background hover color helper', function() {\n\t\tit('should return a CanvasPattern when called with a CanvasPattern', function(done) {\n\t\t\tvar dots = new Image();\n\t\t\tdots.src = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAA4AAAAOCAMAAAAolt3jAAAAD1BMVEUAAAD///////////////+PQt5oAAAABXRSTlMAHlFhZsfk/BEAAAAqSURBVHgBY2BgZGJmYmSAAUYWEIDzmcBcJhiXGcxlRpPFrhdmMiqgvX0AcGIBEUAo6UAAAAAASUVORK5CYII=';\n\t\t\tdots.onload = function() {\n\t\t\t\tvar chartContext = document.createElement('canvas').getContext('2d');\n\t\t\t\tvar patternCanvas = document.createElement('canvas');\n\t\t\t\tvar patternContext = patternCanvas.getContext('2d');\n\t\t\t\tvar pattern = patternContext.createPattern(dots, 'repeat');\n\t\t\t\tpatternContext.fillStyle = pattern;\n\n\t\t\t\tvar backgroundColor = helpers.getHoverColor(chartContext.createPattern(patternCanvas, 'repeat'));\n\n\t\t\t\texpect(backgroundColor instanceof CanvasPattern).toBe(true);\n\n\t\t\t\tdone();\n\t\t\t};\n\t\t});\n\n\t\tit('should return a modified version of color when called with a color', function() {\n\t\t\tvar originalColorRGB = 'rgb(70, 191, 189)';\n\n\t\t\texpect(helpers.getHoverColor('#46BFBD')).not.toEqual(originalColorRGB);\n\t\t});\n\t});\n});\n"
  },
  {
    "path": "app_backend/static/plugin/Chart.js-2.6.0/test/specs/core.interaction.tests.js",
    "content": "// Tests of the interaction handlers in Core.Interaction\n\n// Test the rectangle element\ndescribe('Core.Interaction', function() {\n\tdescribe('point mode', function() {\n\t\tit ('should return all items under the point', function() {\n\t\t\tvar chart = window.acquireChart({\n\t\t\t\ttype: 'line',\n\t\t\t\tdata: {\n\t\t\t\t\tdatasets: [{\n\t\t\t\t\t\tlabel: 'Dataset 1',\n\t\t\t\t\t\tdata: [10, 20, 30],\n\t\t\t\t\t\tpointHoverBorderColor: 'rgb(255, 0, 0)',\n\t\t\t\t\t\tpointHoverBackgroundColor: 'rgb(0, 255, 0)'\n\t\t\t\t\t}, {\n\t\t\t\t\t\tlabel: 'Dataset 2',\n\t\t\t\t\t\tdata: [40, 20, 40],\n\t\t\t\t\t\tpointHoverBorderColor: 'rgb(0, 0, 255)',\n\t\t\t\t\t\tpointHoverBackgroundColor: 'rgb(0, 255, 255)'\n\t\t\t\t\t}],\n\t\t\t\t\tlabels: ['Point 1', 'Point 2', 'Point 3']\n\t\t\t\t}\n\t\t\t});\n\n\t\t\t// Trigger an event over top of the\n\t\t\tvar meta0 = chart.getDatasetMeta(0);\n\t\t\tvar meta1 = chart.getDatasetMeta(1);\n\t\t\tvar point = meta0.data[1];\n\n\t\t\tvar node = chart.canvas;\n\t\t\tvar rect = node.getBoundingClientRect();\n\n\t\t\tvar evt = {\n\t\t\t\tview: window,\n\t\t\t\tbubbles: true,\n\t\t\t\tcancelable: true,\n\t\t\t\tclientX: rect.left + point._model.x,\n\t\t\t\tclientY: rect.top + point._model.y,\n\t\t\t\tcurrentTarget: node\n\t\t\t};\n\n\t\t\tvar elements = Chart.Interaction.modes.point(chart, evt);\n\t\t\texpect(elements).toEqual([point, meta1.data[1]]);\n\t\t});\n\n\t\tit ('should return an empty array when no items are found', function() {\n\t\t\tvar chart = window.acquireChart({\n\t\t\t\ttype: 'line',\n\t\t\t\tdata: {\n\t\t\t\t\tdatasets: [{\n\t\t\t\t\t\tlabel: 'Dataset 1',\n\t\t\t\t\t\tdata: [10, 20, 30],\n\t\t\t\t\t\tpointHoverBorderColor: 'rgb(255, 0, 0)',\n\t\t\t\t\t\tpointHoverBackgroundColor: 'rgb(0, 255, 0)'\n\t\t\t\t\t}, {\n\t\t\t\t\t\tlabel: 'Dataset 2',\n\t\t\t\t\t\tdata: [40, 20, 40],\n\t\t\t\t\t\tpointHoverBorderColor: 'rgb(0, 0, 255)',\n\t\t\t\t\t\tpointHoverBackgroundColor: 'rgb(0, 255, 255)'\n\t\t\t\t\t}],\n\t\t\t\t\tlabels: ['Point 1', 'Point 2', 'Point 3']\n\t\t\t\t}\n\t\t\t});\n\n\t\t\t// Trigger an event at (0, 0)\n\t\t\tvar node = chart.canvas;\n\t\t\tvar evt = {\n\t\t\t\tview: window,\n\t\t\t\tbubbles: true,\n\t\t\t\tcancelable: true,\n\t\t\t\tclientX: 0,\n\t\t\t\tclientY: 0,\n\t\t\t\tcurrentTarget: node\n\t\t\t};\n\n\t\t\tvar elements = Chart.Interaction.modes.point(chart, evt);\n\t\t\texpect(elements).toEqual([]);\n\t\t});\n\t});\n\n\tdescribe('index mode', function() {\n\t\tit ('should return all items at the same index', function() {\n\t\t\tvar chart = window.acquireChart({\n\t\t\t\ttype: 'line',\n\t\t\t\tdata: {\n\t\t\t\t\tdatasets: [{\n\t\t\t\t\t\tlabel: 'Dataset 1',\n\t\t\t\t\t\tdata: [10, 20, 30],\n\t\t\t\t\t\tpointHoverBorderColor: 'rgb(255, 0, 0)',\n\t\t\t\t\t\tpointHoverBackgroundColor: 'rgb(0, 255, 0)'\n\t\t\t\t\t}, {\n\t\t\t\t\t\tlabel: 'Dataset 2',\n\t\t\t\t\t\tdata: [40, 40, 40],\n\t\t\t\t\t\tpointHoverBorderColor: 'rgb(0, 0, 255)',\n\t\t\t\t\t\tpointHoverBackgroundColor: 'rgb(0, 255, 255)'\n\t\t\t\t\t}],\n\t\t\t\t\tlabels: ['Point 1', 'Point 2', 'Point 3']\n\t\t\t\t}\n\t\t\t});\n\n\t\t\t// Trigger an event over top of the\n\t\t\tvar meta0 = chart.getDatasetMeta(0);\n\t\t\tvar meta1 = chart.getDatasetMeta(1);\n\t\t\tvar point = meta0.data[1];\n\n\t\t\tvar node = chart.canvas;\n\t\t\tvar rect = node.getBoundingClientRect();\n\n\t\t\tvar evt = {\n\t\t\t\tview: window,\n\t\t\t\tbubbles: true,\n\t\t\t\tcancelable: true,\n\t\t\t\tclientX: rect.left + point._model.x,\n\t\t\t\tclientY: rect.top + point._model.y,\n\t\t\t\tcurrentTarget: node\n\t\t\t};\n\n\t\t\tvar elements = Chart.Interaction.modes.index(chart, evt, {intersect: true});\n\t\t\texpect(elements).toEqual([point, meta1.data[1]]);\n\t\t});\n\n\t\tit ('should return all items at the same index when intersect is false', function() {\n\t\t\tvar chart = window.acquireChart({\n\t\t\t\ttype: 'line',\n\t\t\t\tdata: {\n\t\t\t\t\tdatasets: [{\n\t\t\t\t\t\tlabel: 'Dataset 1',\n\t\t\t\t\t\tdata: [10, 20, 30],\n\t\t\t\t\t\tpointHoverBorderColor: 'rgb(255, 0, 0)',\n\t\t\t\t\t\tpointHoverBackgroundColor: 'rgb(0, 255, 0)'\n\t\t\t\t\t}, {\n\t\t\t\t\t\tlabel: 'Dataset 2',\n\t\t\t\t\t\tdata: [40, 40, 40],\n\t\t\t\t\t\tpointHoverBorderColor: 'rgb(0, 0, 255)',\n\t\t\t\t\t\tpointHoverBackgroundColor: 'rgb(0, 255, 255)'\n\t\t\t\t\t}],\n\t\t\t\t\tlabels: ['Point 1', 'Point 2', 'Point 3']\n\t\t\t\t}\n\t\t\t});\n\n\t\t\t// Trigger an event over top of the\n\t\t\tvar meta0 = chart.getDatasetMeta(0);\n\t\t\tvar meta1 = chart.getDatasetMeta(1);\n\n\t\t\tvar node = chart.canvas;\n\t\t\tvar rect = node.getBoundingClientRect();\n\n\t\t\tvar evt = {\n\t\t\t\tview: window,\n\t\t\t\tbubbles: true,\n\t\t\t\tcancelable: true,\n\t\t\t\tclientX: rect.left,\n\t\t\t\tclientY: rect.top,\n\t\t\t\tcurrentTarget: node\n\t\t\t};\n\n\t\t\tvar elements = Chart.Interaction.modes.index(chart, evt, {intersect: false});\n\t\t\texpect(elements).toEqual([meta0.data[0], meta1.data[0]]);\n\t\t});\n\t});\n\n\tdescribe('dataset mode', function() {\n\t\tit ('should return all items in the dataset of the first item found', function() {\n\t\t\tvar chart = window.acquireChart({\n\t\t\t\ttype: 'line',\n\t\t\t\tdata: {\n\t\t\t\t\tdatasets: [{\n\t\t\t\t\t\tlabel: 'Dataset 1',\n\t\t\t\t\t\tdata: [10, 20, 30],\n\t\t\t\t\t\tpointHoverBorderColor: 'rgb(255, 0, 0)',\n\t\t\t\t\t\tpointHoverBackgroundColor: 'rgb(0, 255, 0)'\n\t\t\t\t\t}, {\n\t\t\t\t\t\tlabel: 'Dataset 2',\n\t\t\t\t\t\tdata: [40, 40, 40],\n\t\t\t\t\t\tpointHoverBorderColor: 'rgb(0, 0, 255)',\n\t\t\t\t\t\tpointHoverBackgroundColor: 'rgb(0, 255, 255)'\n\t\t\t\t\t}],\n\t\t\t\t\tlabels: ['Point 1', 'Point 2', 'Point 3']\n\t\t\t\t}\n\t\t\t});\n\n\t\t\t// Trigger an event over top of the\n\t\t\tvar meta = chart.getDatasetMeta(0);\n\t\t\tvar point = meta.data[1];\n\n\t\t\tvar node = chart.canvas;\n\t\t\tvar rect = node.getBoundingClientRect();\n\n\t\t\tvar evt = {\n\t\t\t\tview: window,\n\t\t\t\tbubbles: true,\n\t\t\t\tcancelable: true,\n\t\t\t\tclientX: rect.left + point._model.x,\n\t\t\t\tclientY: rect.top + point._model.y,\n\t\t\t\tcurrentTarget: node\n\t\t\t};\n\n\t\t\tvar elements = Chart.Interaction.modes.dataset(chart, evt, {intersect: true});\n\t\t\texpect(elements).toEqual(meta.data);\n\t\t});\n\n\t\tit ('should return all items in the dataset of the first item found when intersect is false', function() {\n\t\t\tvar chart = window.acquireChart({\n\t\t\t\ttype: 'line',\n\t\t\t\tdata: {\n\t\t\t\t\tdatasets: [{\n\t\t\t\t\t\tlabel: 'Dataset 1',\n\t\t\t\t\t\tdata: [10, 20, 30],\n\t\t\t\t\t\tpointHoverBorderColor: 'rgb(255, 0, 0)',\n\t\t\t\t\t\tpointHoverBackgroundColor: 'rgb(0, 255, 0)'\n\t\t\t\t\t}, {\n\t\t\t\t\t\tlabel: 'Dataset 2',\n\t\t\t\t\t\tdata: [40, 40, 40],\n\t\t\t\t\t\tpointHoverBorderColor: 'rgb(0, 0, 255)',\n\t\t\t\t\t\tpointHoverBackgroundColor: 'rgb(0, 255, 255)'\n\t\t\t\t\t}],\n\t\t\t\t\tlabels: ['Point 1', 'Point 2', 'Point 3']\n\t\t\t\t}\n\t\t\t});\n\n\t\t\tvar node = chart.canvas;\n\t\t\tvar rect = node.getBoundingClientRect();\n\n\t\t\tvar evt = {\n\t\t\t\tview: window,\n\t\t\t\tbubbles: true,\n\t\t\t\tcancelable: true,\n\t\t\t\tclientX: rect.left,\n\t\t\t\tclientY: rect.top,\n\t\t\t\tcurrentTarget: node\n\t\t\t};\n\n\t\t\tvar elements = Chart.Interaction.modes.dataset(chart, evt, {intersect: false});\n\n\t\t\tvar meta = chart.getDatasetMeta(1);\n\t\t\texpect(elements).toEqual(meta.data);\n\t\t});\n\t});\n\n\tdescribe('nearest mode', function() {\n\t\tit ('should return the nearest item', function() {\n\t\t\tvar chart = window.acquireChart({\n\t\t\t\ttype: 'line',\n\t\t\t\tdata: {\n\t\t\t\t\tdatasets: [{\n\t\t\t\t\t\tlabel: 'Dataset 1',\n\t\t\t\t\t\tdata: [10, 20, 30],\n\t\t\t\t\t\tpointHoverBorderColor: 'rgb(255, 0, 0)',\n\t\t\t\t\t\tpointHoverBackgroundColor: 'rgb(0, 255, 0)'\n\t\t\t\t\t}, {\n\t\t\t\t\t\tlabel: 'Dataset 2',\n\t\t\t\t\t\tdata: [40, 40, 40],\n\t\t\t\t\t\tpointHoverBorderColor: 'rgb(0, 0, 255)',\n\t\t\t\t\t\tpointHoverBackgroundColor: 'rgb(0, 255, 255)'\n\t\t\t\t\t}],\n\t\t\t\t\tlabels: ['Point 1', 'Point 2', 'Point 3']\n\t\t\t\t}\n\t\t\t});\n\n\t\t\t// Trigger an event over top of the\n\t\t\tvar meta = chart.getDatasetMeta(1);\n\t\t\tvar node = chart.canvas;\n\t\t\tvar evt = {\n\t\t\t\tview: window,\n\t\t\t\tbubbles: true,\n\t\t\t\tcancelable: true,\n\t\t\t\tclientX: 0,\n\t\t\t\tclientY: 0,\n\t\t\t\tcurrentTarget: node\n\t\t\t};\n\n\t\t\t// Nearest to 0,0 (top left) will be first point of dataset 2\n\t\t\tvar elements = Chart.Interaction.modes.nearest(chart, evt, {intersect: false});\n\t\t\texpect(elements).toEqual([meta.data[0]]);\n\t\t});\n\n\t\tit ('should return the smallest item if more than 1 are at the same distance', function() {\n\t\t\tvar chart = window.acquireChart({\n\t\t\t\ttype: 'line',\n\t\t\t\tdata: {\n\t\t\t\t\tdatasets: [{\n\t\t\t\t\t\tlabel: 'Dataset 1',\n\t\t\t\t\t\tdata: [10, 40, 30],\n\t\t\t\t\t\tpointRadius: [5, 5, 5],\n\t\t\t\t\t\tpointHoverBorderColor: 'rgb(255, 0, 0)',\n\t\t\t\t\t\tpointHoverBackgroundColor: 'rgb(0, 255, 0)'\n\t\t\t\t\t}, {\n\t\t\t\t\t\tlabel: 'Dataset 2',\n\t\t\t\t\t\tdata: [40, 40, 40],\n\t\t\t\t\t\tpointRadius: [10, 10, 10],\n\t\t\t\t\t\tpointHoverBorderColor: 'rgb(0, 0, 255)',\n\t\t\t\t\t\tpointHoverBackgroundColor: 'rgb(0, 255, 255)'\n\t\t\t\t\t}],\n\t\t\t\t\tlabels: ['Point 1', 'Point 2', 'Point 3']\n\t\t\t\t}\n\t\t\t});\n\n\t\t\t// Trigger an event over top of the\n\t\t\tvar meta0 = chart.getDatasetMeta(0);\n\t\t\tvar meta1 = chart.getDatasetMeta(1);\n\n\t\t\t// Halfway between 2 mid points\n\t\t\tvar pt = {\n\t\t\t\tx: meta0.data[1]._view.x,\n\t\t\t\ty: (meta0.data[1]._view.y + meta1.data[1]._view.y) / 2\n\t\t\t};\n\n\t\t\tvar node = chart.canvas;\n\t\t\tvar rect = node.getBoundingClientRect();\n\t\t\tvar evt = {\n\t\t\t\tview: window,\n\t\t\t\tbubbles: true,\n\t\t\t\tcancelable: true,\n\t\t\t\tclientX: rect.left + pt.x,\n\t\t\t\tclientY: rect.top + pt.y,\n\t\t\t\tcurrentTarget: node\n\t\t\t};\n\n\t\t\t// Nearest to 0,0 (top left) will be first point of dataset 2\n\t\t\tvar elements = Chart.Interaction.modes.nearest(chart, evt, {intersect: false});\n\t\t\texpect(elements).toEqual([meta0.data[1]]);\n\t\t});\n\n\t\tit ('should return the lowest dataset index if size and area are the same', function() {\n\t\t\tvar chart = window.acquireChart({\n\t\t\t\ttype: 'line',\n\t\t\t\tdata: {\n\t\t\t\t\tdatasets: [{\n\t\t\t\t\t\tlabel: 'Dataset 1',\n\t\t\t\t\t\tdata: [10, 40, 30],\n\t\t\t\t\t\tpointRadius: [5, 10, 5],\n\t\t\t\t\t\tpointHoverBorderColor: 'rgb(255, 0, 0)',\n\t\t\t\t\t\tpointHoverBackgroundColor: 'rgb(0, 255, 0)'\n\t\t\t\t\t}, {\n\t\t\t\t\t\tlabel: 'Dataset 2',\n\t\t\t\t\t\tdata: [40, 40, 40],\n\t\t\t\t\t\tpointRadius: [10, 10, 10],\n\t\t\t\t\t\tpointHoverBorderColor: 'rgb(0, 0, 255)',\n\t\t\t\t\t\tpointHoverBackgroundColor: 'rgb(0, 255, 255)'\n\t\t\t\t\t}],\n\t\t\t\t\tlabels: ['Point 1', 'Point 2', 'Point 3']\n\t\t\t\t}\n\t\t\t});\n\n\t\t\t// Trigger an event over top of the\n\t\t\tvar meta0 = chart.getDatasetMeta(0);\n\t\t\tvar meta1 = chart.getDatasetMeta(1);\n\n\t\t\t// Halfway between 2 mid points\n\t\t\tvar pt = {\n\t\t\t\tx: meta0.data[1]._view.x,\n\t\t\t\ty: (meta0.data[1]._view.y + meta1.data[1]._view.y) / 2\n\t\t\t};\n\n\t\t\tvar node = chart.canvas;\n\t\t\tvar rect = node.getBoundingClientRect();\n\t\t\tvar evt = {\n\t\t\t\tview: window,\n\t\t\t\tbubbles: true,\n\t\t\t\tcancelable: true,\n\t\t\t\tclientX: rect.left + pt.x,\n\t\t\t\tclientY: rect.top + pt.y,\n\t\t\t\tcurrentTarget: node\n\t\t\t};\n\n\t\t\t// Nearest to 0,0 (top left) will be first point of dataset 2\n\t\t\tvar elements = Chart.Interaction.modes.nearest(chart, evt, {intersect: false});\n\t\t\texpect(elements).toEqual([meta0.data[1]]);\n\t\t});\n\t});\n\n\tdescribe('nearest intersect mode', function() {\n\t\tit ('should return the nearest item', function() {\n\t\t\tvar chart = window.acquireChart({\n\t\t\t\ttype: 'line',\n\t\t\t\tdata: {\n\t\t\t\t\tdatasets: [{\n\t\t\t\t\t\tlabel: 'Dataset 1',\n\t\t\t\t\t\tdata: [10, 20, 30],\n\t\t\t\t\t\tpointHoverBorderColor: 'rgb(255, 0, 0)',\n\t\t\t\t\t\tpointHoverBackgroundColor: 'rgb(0, 255, 0)'\n\t\t\t\t\t}, {\n\t\t\t\t\t\tlabel: 'Dataset 2',\n\t\t\t\t\t\tdata: [40, 40, 40],\n\t\t\t\t\t\tpointHoverBorderColor: 'rgb(0, 0, 255)',\n\t\t\t\t\t\tpointHoverBackgroundColor: 'rgb(0, 255, 255)'\n\t\t\t\t\t}],\n\t\t\t\t\tlabels: ['Point 1', 'Point 2', 'Point 3']\n\t\t\t\t}\n\t\t\t});\n\n\t\t\t// Trigger an event over top of the\n\t\t\tvar meta = chart.getDatasetMeta(1);\n\t\t\tvar point = meta.data[1];\n\n\t\t\tvar node = chart.canvas;\n\t\t\tvar rect = node.getBoundingClientRect();\n\t\t\tvar evt = {\n\t\t\t\tview: window,\n\t\t\t\tbubbles: true,\n\t\t\t\tcancelable: true,\n\t\t\t\tclientX: rect.left + point._view.x + 15,\n\t\t\t\tclientY: rect.top + point._view.y,\n\t\t\t\tcurrentTarget: node\n\t\t\t};\n\n\t\t\t// Nothing intersects so find nothing\n\t\t\tvar elements = Chart.Interaction.modes.nearest(chart, evt, {intersect: true});\n\t\t\texpect(elements).toEqual([]);\n\n\t\t\tevt = {\n\t\t\t\tview: window,\n\t\t\t\tbubbles: true,\n\t\t\t\tcancelable: true,\n\t\t\t\tclientX: rect.left + point._view.x,\n\t\t\t\tclientY: rect.top + point._view.y,\n\t\t\t\tcurrentTarget: node\n\t\t\t};\n\t\t\telements = Chart.Interaction.modes.nearest(chart, evt, {intersect: true});\n\t\t\texpect(elements).toEqual([point]);\n\t\t});\n\n\t\tit ('should return the nearest item even if 2 intersect', function() {\n\t\t\tvar chart = window.acquireChart({\n\t\t\t\ttype: 'line',\n\t\t\t\tdata: {\n\t\t\t\t\tdatasets: [{\n\t\t\t\t\t\tlabel: 'Dataset 1',\n\t\t\t\t\t\tdata: [10, 39, 30],\n\t\t\t\t\t\tpointRadius: [5, 30, 5],\n\t\t\t\t\t\tpointHoverBorderColor: 'rgb(255, 0, 0)',\n\t\t\t\t\t\tpointHoverBackgroundColor: 'rgb(0, 255, 0)'\n\t\t\t\t\t}, {\n\t\t\t\t\t\tlabel: 'Dataset 2',\n\t\t\t\t\t\tdata: [40, 40, 40],\n\t\t\t\t\t\tpointRadius: [10, 10, 10],\n\t\t\t\t\t\tpointHoverBorderColor: 'rgb(0, 0, 255)',\n\t\t\t\t\t\tpointHoverBackgroundColor: 'rgb(0, 255, 255)'\n\t\t\t\t\t}],\n\t\t\t\t\tlabels: ['Point 1', 'Point 2', 'Point 3']\n\t\t\t\t}\n\t\t\t});\n\n\t\t\t// Trigger an event over top of the\n\t\t\tvar meta0 = chart.getDatasetMeta(0);\n\n\t\t\t// Halfway between 2 mid points\n\t\t\tvar pt = {\n\t\t\t\tx: meta0.data[1]._view.x,\n\t\t\t\ty: meta0.data[1]._view.y\n\t\t\t};\n\n\t\t\tvar node = chart.canvas;\n\t\t\tvar rect = node.getBoundingClientRect();\n\t\t\tvar evt = {\n\t\t\t\tview: window,\n\t\t\t\tbubbles: true,\n\t\t\t\tcancelable: true,\n\t\t\t\tclientX: rect.left + pt.x,\n\t\t\t\tclientY: rect.top + pt.y,\n\t\t\t\tcurrentTarget: node\n\t\t\t};\n\n\t\t\t// Nearest to 0,0 (top left) will be first point of dataset 2\n\t\t\tvar elements = Chart.Interaction.modes.nearest(chart, evt, {intersect: true});\n\t\t\texpect(elements).toEqual([meta0.data[1]]);\n\t\t});\n\n\t\tit ('should return the smallest item if more than 1 are at the same distance', function() {\n\t\t\tvar chart = window.acquireChart({\n\t\t\t\ttype: 'line',\n\t\t\t\tdata: {\n\t\t\t\t\tdatasets: [{\n\t\t\t\t\t\tlabel: 'Dataset 1',\n\t\t\t\t\t\tdata: [10, 40, 30],\n\t\t\t\t\t\tpointRadius: [5, 5, 5],\n\t\t\t\t\t\tpointHoverBorderColor: 'rgb(255, 0, 0)',\n\t\t\t\t\t\tpointHoverBackgroundColor: 'rgb(0, 255, 0)'\n\t\t\t\t\t}, {\n\t\t\t\t\t\tlabel: 'Dataset 2',\n\t\t\t\t\t\tdata: [40, 40, 40],\n\t\t\t\t\t\tpointRadius: [10, 10, 10],\n\t\t\t\t\t\tpointHoverBorderColor: 'rgb(0, 0, 255)',\n\t\t\t\t\t\tpointHoverBackgroundColor: 'rgb(0, 255, 255)'\n\t\t\t\t\t}],\n\t\t\t\t\tlabels: ['Point 1', 'Point 2', 'Point 3']\n\t\t\t\t}\n\t\t\t});\n\n\t\t\t// Trigger an event over top of the\n\t\t\tvar meta0 = chart.getDatasetMeta(0);\n\n\t\t\t// Halfway between 2 mid points\n\t\t\tvar pt = {\n\t\t\t\tx: meta0.data[1]._view.x,\n\t\t\t\ty: meta0.data[1]._view.y\n\t\t\t};\n\n\t\t\tvar node = chart.canvas;\n\t\t\tvar rect = node.getBoundingClientRect();\n\t\t\tvar evt = {\n\t\t\t\tview: window,\n\t\t\t\tbubbles: true,\n\t\t\t\tcancelable: true,\n\t\t\t\tclientX: rect.left + pt.x,\n\t\t\t\tclientY: rect.top + pt.y,\n\t\t\t\tcurrentTarget: node\n\t\t\t};\n\n\t\t\t// Nearest to 0,0 (top left) will be first point of dataset 2\n\t\t\tvar elements = Chart.Interaction.modes.nearest(chart, evt, {intersect: true});\n\t\t\texpect(elements).toEqual([meta0.data[1]]);\n\t\t});\n\n\t\tit ('should return the item at the lowest dataset index if distance and area are the same', function() {\n\t\t\tvar chart = window.acquireChart({\n\t\t\t\ttype: 'line',\n\t\t\t\tdata: {\n\t\t\t\t\tdatasets: [{\n\t\t\t\t\t\tlabel: 'Dataset 1',\n\t\t\t\t\t\tdata: [10, 40, 30],\n\t\t\t\t\t\tpointRadius: [5, 10, 5],\n\t\t\t\t\t\tpointHoverBorderColor: 'rgb(255, 0, 0)',\n\t\t\t\t\t\tpointHoverBackgroundColor: 'rgb(0, 255, 0)'\n\t\t\t\t\t}, {\n\t\t\t\t\t\tlabel: 'Dataset 2',\n\t\t\t\t\t\tdata: [40, 40, 40],\n\t\t\t\t\t\tpointRadius: [10, 10, 10],\n\t\t\t\t\t\tpointHoverBorderColor: 'rgb(0, 0, 255)',\n\t\t\t\t\t\tpointHoverBackgroundColor: 'rgb(0, 255, 255)'\n\t\t\t\t\t}],\n\t\t\t\t\tlabels: ['Point 1', 'Point 2', 'Point 3']\n\t\t\t\t}\n\t\t\t});\n\n\t\t\t// Trigger an event over top of the\n\t\t\tvar meta0 = chart.getDatasetMeta(0);\n\n\t\t\t// Halfway between 2 mid points\n\t\t\tvar pt = {\n\t\t\t\tx: meta0.data[1]._view.x,\n\t\t\t\ty: meta0.data[1]._view.y\n\t\t\t};\n\n\t\t\tvar node = chart.canvas;\n\t\t\tvar rect = node.getBoundingClientRect();\n\t\t\tvar evt = {\n\t\t\t\tview: window,\n\t\t\t\tbubbles: true,\n\t\t\t\tcancelable: true,\n\t\t\t\tclientX: rect.left + pt.x,\n\t\t\t\tclientY: rect.top + pt.y,\n\t\t\t\tcurrentTarget: node\n\t\t\t};\n\n\t\t\t// Nearest to 0,0 (top left) will be first point of dataset 2\n\t\t\tvar elements = Chart.Interaction.modes.nearest(chart, evt, {intersect: true});\n\t\t\texpect(elements).toEqual([meta0.data[1]]);\n\t\t});\n\t});\n\n\tdescribe('x mode', function() {\n\t\tit('should return items at the same x value when intersect is false', function() {\n\t\t\tvar chart = window.acquireChart({\n\t\t\t\ttype: 'line',\n\t\t\t\tdata: {\n\t\t\t\t\tdatasets: [{\n\t\t\t\t\t\tlabel: 'Dataset 1',\n\t\t\t\t\t\tdata: [10, 40, 30],\n\t\t\t\t\t\tpointRadius: [5, 10, 5],\n\t\t\t\t\t\tpointHoverBorderColor: 'rgb(255, 0, 0)',\n\t\t\t\t\t\tpointHoverBackgroundColor: 'rgb(0, 255, 0)'\n\t\t\t\t\t}, {\n\t\t\t\t\t\tlabel: 'Dataset 2',\n\t\t\t\t\t\tdata: [40, 40, 40],\n\t\t\t\t\t\tpointRadius: [10, 10, 10],\n\t\t\t\t\t\tpointHoverBorderColor: 'rgb(0, 0, 255)',\n\t\t\t\t\t\tpointHoverBackgroundColor: 'rgb(0, 255, 255)'\n\t\t\t\t\t}],\n\t\t\t\t\tlabels: ['Point 1', 'Point 2', 'Point 3']\n\t\t\t\t}\n\t\t\t});\n\n\t\t\t// Trigger an event over top of the\n\t\t\tvar meta0 = chart.getDatasetMeta(0);\n\t\t\tvar meta1 = chart.getDatasetMeta(1);\n\n\t\t\t// Halfway between 2 mid points\n\t\t\tvar pt = {\n\t\t\t\tx: meta0.data[1]._view.x,\n\t\t\t\ty: meta0.data[1]._view.y\n\t\t\t};\n\n\t\t\tvar node = chart.canvas;\n\t\t\tvar rect = node.getBoundingClientRect();\n\t\t\tvar evt = {\n\t\t\t\tview: window,\n\t\t\t\tbubbles: true,\n\t\t\t\tcancelable: true,\n\t\t\t\tclientX: rect.left + pt.x,\n\t\t\t\tclientY: rect.top,\n\t\t\t\tcurrentTarget: node\n\t\t\t};\n\n\t\t\tvar elements = Chart.Interaction.modes.x(chart, evt, {intersect: false});\n\t\t\texpect(elements).toEqual([meta0.data[1], meta1.data[1]]);\n\n\t\t\tevt = {\n\t\t\t\tview: window,\n\t\t\t\tbubbles: true,\n\t\t\t\tcancelable: true,\n\t\t\t\tclientX: rect.left + pt.x + 20, // out of range\n\t\t\t\tclientY: rect.top,\n\t\t\t\tcurrentTarget: node\n\t\t\t};\n\n\t\t\telements = Chart.Interaction.modes.x(chart, evt, {intersect: false});\n\t\t\texpect(elements).toEqual([]);\n\t\t});\n\n\t\tit('should return items at the same x value when intersect is true', function() {\n\t\t\tvar chart = window.acquireChart({\n\t\t\t\ttype: 'line',\n\t\t\t\tdata: {\n\t\t\t\t\tdatasets: [{\n\t\t\t\t\t\tlabel: 'Dataset 1',\n\t\t\t\t\t\tdata: [10, 40, 30],\n\t\t\t\t\t\tpointRadius: [5, 10, 5],\n\t\t\t\t\t\tpointHoverBorderColor: 'rgb(255, 0, 0)',\n\t\t\t\t\t\tpointHoverBackgroundColor: 'rgb(0, 255, 0)'\n\t\t\t\t\t}, {\n\t\t\t\t\t\tlabel: 'Dataset 2',\n\t\t\t\t\t\tdata: [40, 40, 40],\n\t\t\t\t\t\tpointRadius: [10, 10, 10],\n\t\t\t\t\t\tpointHoverBorderColor: 'rgb(0, 0, 255)',\n\t\t\t\t\t\tpointHoverBackgroundColor: 'rgb(0, 255, 255)'\n\t\t\t\t\t}],\n\t\t\t\t\tlabels: ['Point 1', 'Point 2', 'Point 3']\n\t\t\t\t}\n\t\t\t});\n\n\t\t\t// Trigger an event over top of the\n\t\t\tvar meta0 = chart.getDatasetMeta(0);\n\t\t\tvar meta1 = chart.getDatasetMeta(1);\n\n\t\t\t// Halfway between 2 mid points\n\t\t\tvar pt = {\n\t\t\t\tx: meta0.data[1]._view.x,\n\t\t\t\ty: meta0.data[1]._view.y\n\t\t\t};\n\n\t\t\tvar node = chart.canvas;\n\t\t\tvar rect = node.getBoundingClientRect();\n\t\t\tvar evt = {\n\t\t\t\tview: window,\n\t\t\t\tbubbles: true,\n\t\t\t\tcancelable: true,\n\t\t\t\tclientX: rect.left + pt.x,\n\t\t\t\tclientY: rect.top,\n\t\t\t\tcurrentTarget: node\n\t\t\t};\n\n\t\t\tvar elements = Chart.Interaction.modes.x(chart, evt, {intersect: true});\n\t\t\texpect(elements).toEqual([]); // we don't intersect anything\n\n\t\t\tevt = {\n\t\t\t\tview: window,\n\t\t\t\tbubbles: true,\n\t\t\t\tcancelable: true,\n\t\t\t\tclientX: rect.left + pt.x,\n\t\t\t\tclientY: rect.top + pt.y,\n\t\t\t\tcurrentTarget: node\n\t\t\t};\n\n\t\t\telements = Chart.Interaction.modes.x(chart, evt, {intersect: true});\n\t\t\texpect(elements).toEqual([meta0.data[1], meta1.data[1]]);\n\t\t});\n\t});\n\n\tdescribe('y mode', function() {\n\t\tit('should return items at the same y value when intersect is false', function() {\n\t\t\tvar chart = window.acquireChart({\n\t\t\t\ttype: 'line',\n\t\t\t\tdata: {\n\t\t\t\t\tdatasets: [{\n\t\t\t\t\t\tlabel: 'Dataset 1',\n\t\t\t\t\t\tdata: [10, 40, 30],\n\t\t\t\t\t\tpointRadius: [5, 10, 5],\n\t\t\t\t\t\tpointHoverBorderColor: 'rgb(255, 0, 0)',\n\t\t\t\t\t\tpointHoverBackgroundColor: 'rgb(0, 255, 0)'\n\t\t\t\t\t}, {\n\t\t\t\t\t\tlabel: 'Dataset 2',\n\t\t\t\t\t\tdata: [40, 40, 40],\n\t\t\t\t\t\tpointRadius: [10, 10, 10],\n\t\t\t\t\t\tpointHoverBorderColor: 'rgb(0, 0, 255)',\n\t\t\t\t\t\tpointHoverBackgroundColor: 'rgb(0, 255, 255)'\n\t\t\t\t\t}],\n\t\t\t\t\tlabels: ['Point 1', 'Point 2', 'Point 3']\n\t\t\t\t}\n\t\t\t});\n\n\t\t\t// Trigger an event over top of the\n\t\t\tvar meta0 = chart.getDatasetMeta(0);\n\t\t\tvar meta1 = chart.getDatasetMeta(1);\n\n\t\t\t// Halfway between 2 mid points\n\t\t\tvar pt = {\n\t\t\t\tx: meta0.data[1]._view.x,\n\t\t\t\ty: meta0.data[1]._view.y\n\t\t\t};\n\n\t\t\tvar node = chart.canvas;\n\t\t\tvar rect = node.getBoundingClientRect();\n\t\t\tvar evt = {\n\t\t\t\tview: window,\n\t\t\t\tbubbles: true,\n\t\t\t\tcancelable: true,\n\t\t\t\tclientX: rect.left,\n\t\t\t\tclientY: rect.top + pt.y,\n\t\t\t\tcurrentTarget: node\n\t\t\t};\n\n\t\t\tvar elements = Chart.Interaction.modes.y(chart, evt, {intersect: false});\n\t\t\texpect(elements).toEqual([meta0.data[1], meta1.data[0], meta1.data[1], meta1.data[2]]);\n\n\t\t\tevt = {\n\t\t\t\tview: window,\n\t\t\t\tbubbles: true,\n\t\t\t\tcancelable: true,\n\t\t\t\tclientX: rect.left + pt.x,\n\t\t\t\tclientY: rect.top + pt.y + 20, // out of range\n\t\t\t\tcurrentTarget: node\n\t\t\t};\n\n\t\t\telements = Chart.Interaction.modes.y(chart, evt, {intersect: false});\n\t\t\texpect(elements).toEqual([]);\n\t\t});\n\n\t\tit('should return items at the same y value when intersect is true', function() {\n\t\t\tvar chart = window.acquireChart({\n\t\t\t\ttype: 'line',\n\t\t\t\tdata: {\n\t\t\t\t\tdatasets: [{\n\t\t\t\t\t\tlabel: 'Dataset 1',\n\t\t\t\t\t\tdata: [10, 40, 30],\n\t\t\t\t\t\tpointRadius: [5, 10, 5],\n\t\t\t\t\t\tpointHoverBorderColor: 'rgb(255, 0, 0)',\n\t\t\t\t\t\tpointHoverBackgroundColor: 'rgb(0, 255, 0)'\n\t\t\t\t\t}, {\n\t\t\t\t\t\tlabel: 'Dataset 2',\n\t\t\t\t\t\tdata: [40, 40, 40],\n\t\t\t\t\t\tpointRadius: [10, 10, 10],\n\t\t\t\t\t\tpointHoverBorderColor: 'rgb(0, 0, 255)',\n\t\t\t\t\t\tpointHoverBackgroundColor: 'rgb(0, 255, 255)'\n\t\t\t\t\t}],\n\t\t\t\t\tlabels: ['Point 1', 'Point 2', 'Point 3']\n\t\t\t\t}\n\t\t\t});\n\n\t\t\t// Trigger an event over top of the\n\t\t\tvar meta0 = chart.getDatasetMeta(0);\n\t\t\tvar meta1 = chart.getDatasetMeta(1);\n\n\t\t\t// Halfway between 2 mid points\n\t\t\tvar pt = {\n\t\t\t\tx: meta0.data[1]._view.x,\n\t\t\t\ty: meta0.data[1]._view.y\n\t\t\t};\n\n\t\t\tvar node = chart.canvas;\n\t\t\tvar rect = node.getBoundingClientRect();\n\t\t\tvar evt = {\n\t\t\t\tview: window,\n\t\t\t\tbubbles: true,\n\t\t\t\tcancelable: true,\n\t\t\t\tclientX: rect.left,\n\t\t\t\tclientY: rect.top + pt.y,\n\t\t\t\tcurrentTarget: node\n\t\t\t};\n\n\t\t\tvar elements = Chart.Interaction.modes.y(chart, evt, {intersect: true});\n\t\t\texpect(elements).toEqual([]); // we don't intersect anything\n\n\t\t\tevt = {\n\t\t\t\tview: window,\n\t\t\t\tbubbles: true,\n\t\t\t\tcancelable: true,\n\t\t\t\tclientX: rect.left + pt.x,\n\t\t\t\tclientY: rect.top + pt.y,\n\t\t\t\tcurrentTarget: node\n\t\t\t};\n\n\t\t\telements = Chart.Interaction.modes.y(chart, evt, {intersect: true});\n\t\t\texpect(elements).toEqual([meta0.data[1], meta1.data[0], meta1.data[1], meta1.data[2]]);\n\t\t});\n\t});\n});\n"
  },
  {
    "path": "app_backend/static/plugin/Chart.js-2.6.0/test/specs/core.layoutService.tests.js",
    "content": "// Tests of the scale service\ndescribe('Test the layout service', function() {\n\t// Disable tests which need to be rewritten based on changes introduced by\n\t// the following changes: https://github.com/chartjs/Chart.js/pull/2346\n\t// using xit marks the test as pending: http://jasmine.github.io/2.0/introduction.html#section-Pending_Specs\n\txit('should fit a simple chart with 2 scales', function() {\n\t\tvar chart = window.acquireChart({\n\t\t\ttype: 'bar',\n\t\t\tdata: {\n\t\t\t\tdatasets: [\n\t\t\t\t\t{data: [10, 5, 0, 25, 78, -10]}\n\t\t\t\t],\n\t\t\t\tlabels: ['tick1', 'tick2', 'tick3', 'tick4', 'tick5', 'tick6']\n\t\t\t},\n\t\t\toptions: {\n\t\t\t\tscales: {\n\t\t\t\t\txAxes: [{\n\t\t\t\t\t\tid: 'xScale',\n\t\t\t\t\t\ttype: 'category'\n\t\t\t\t\t}],\n\t\t\t\t\tyAxes: [{\n\t\t\t\t\t\tid: 'yScale',\n\t\t\t\t\t\ttype: 'linear'\n\t\t\t\t\t}]\n\t\t\t\t}\n\t\t\t}\n\t\t}, {\n\t\t\tcanvas: {\n\t\t\t\theight: 150,\n\t\t\t\twidth: 250\n\t\t\t}\n\t\t});\n\n\t\texpect(chart.chartArea.bottom).toBeCloseToPixel(112);\n\t\texpect(chart.chartArea.left).toBeCloseToPixel(41);\n\t\texpect(chart.chartArea.right).toBeCloseToPixel(250);\n\t\texpect(chart.chartArea.top).toBeCloseToPixel(32);\n\n\t\t// Is xScale at the right spot\n\t\texpect(chart.scales.xScale.bottom).toBeCloseToPixel(150);\n\t\texpect(chart.scales.xScale.left).toBeCloseToPixel(41);\n\t\texpect(chart.scales.xScale.right).toBeCloseToPixel(250);\n\t\texpect(chart.scales.xScale.top).toBeCloseToPixel(112);\n\t\texpect(chart.scales.xScale.labelRotation).toBeCloseTo(25);\n\n\t\t// Is yScale at the right spot\n\t\texpect(chart.scales.yScale.bottom).toBeCloseToPixel(112);\n\t\texpect(chart.scales.yScale.left).toBeCloseToPixel(0);\n\t\texpect(chart.scales.yScale.right).toBeCloseToPixel(41);\n\t\texpect(chart.scales.yScale.top).toBeCloseToPixel(32);\n\t\texpect(chart.scales.yScale.labelRotation).toBeCloseTo(0);\n\t});\n\n\txit('should fit scales that are in the top and right positions', function() {\n\t\tvar chart = window.acquireChart({\n\t\t\ttype: 'bar',\n\t\t\tdata: {\n\t\t\t\tdatasets: [\n\t\t\t\t\t{data: [10, 5, 0, 25, 78, -10]}\n\t\t\t\t],\n\t\t\t\tlabels: ['tick1', 'tick2', 'tick3', 'tick4', 'tick5', 'tick6']\n\t\t\t},\n\t\t\toptions: {\n\t\t\t\tscales: {\n\t\t\t\t\txAxes: [{\n\t\t\t\t\t\tid: 'xScale',\n\t\t\t\t\t\ttype: 'category',\n\t\t\t\t\t\tposition: 'top'\n\t\t\t\t\t}],\n\t\t\t\t\tyAxes: [{\n\t\t\t\t\t\tid: 'yScale',\n\t\t\t\t\t\ttype: 'linear',\n\t\t\t\t\t\tposition: 'right'\n\t\t\t\t\t}]\n\t\t\t\t}\n\t\t\t}\n\t\t}, {\n\t\t\tcanvas: {\n\t\t\t\theight: 150,\n\t\t\t\twidth: 250\n\t\t\t}\n\t\t});\n\n\t\texpect(chart.chartArea.bottom).toBeCloseToPixel(150);\n\t\texpect(chart.chartArea.left).toBeCloseToPixel(0);\n\t\texpect(chart.chartArea.right).toBeCloseToPixel(209);\n\t\texpect(chart.chartArea.top).toBeCloseToPixel(71);\n\n\t\t// Is xScale at the right spot\n\t\texpect(chart.scales.xScale.bottom).toBeCloseToPixel(71);\n\t\texpect(chart.scales.xScale.left).toBeCloseToPixel(0);\n\t\texpect(chart.scales.xScale.right).toBeCloseToPixel(209);\n\t\texpect(chart.scales.xScale.top).toBeCloseToPixel(32);\n\t\texpect(chart.scales.xScale.labelRotation).toBeCloseTo(25);\n\n\t\t// Is yScale at the right spot\n\t\texpect(chart.scales.yScale.bottom).toBeCloseToPixel(150);\n\t\texpect(chart.scales.yScale.left).toBeCloseToPixel(209);\n\t\texpect(chart.scales.yScale.right).toBeCloseToPixel(250);\n\t\texpect(chart.scales.yScale.top).toBeCloseToPixel(71);\n\t\texpect(chart.scales.yScale.labelRotation).toBeCloseTo(0);\n\t});\n\n\tit('should fit scales that overlap the chart area', function() {\n\t\tvar chart = window.acquireChart({\n\t\t\ttype: 'radar',\n\t\t\tdata: {\n\t\t\t\tdatasets: [{\n\t\t\t\t\tdata: [10, 5, 0, 25, 78, -10]\n\t\t\t\t}, {\n\t\t\t\t\tdata: [-19, -20, 0, -99, -50, 0]\n\t\t\t\t}],\n\t\t\t\tlabels: ['tick1', 'tick2', 'tick3', 'tick4', 'tick5', 'tick6']\n\t\t\t}\n\t\t});\n\n\t\texpect(chart.chartArea.bottom).toBeCloseToPixel(512);\n\t\texpect(chart.chartArea.left).toBeCloseToPixel(0);\n\t\texpect(chart.chartArea.right).toBeCloseToPixel(512);\n\t\texpect(chart.chartArea.top).toBeCloseToPixel(32);\n\n\t\texpect(chart.scale.bottom).toBeCloseToPixel(512);\n\t\texpect(chart.scale.left).toBeCloseToPixel(0);\n\t\texpect(chart.scale.right).toBeCloseToPixel(512);\n\t\texpect(chart.scale.top).toBeCloseToPixel(32);\n\t\texpect(chart.scale.width).toBeCloseToPixel(512);\n\t\texpect(chart.scale.height).toBeCloseToPixel(480);\n\t});\n\n\txit('should fit multiple axes in the same position', function() {\n\t\tvar chart = window.acquireChart({\n\t\t\ttype: 'bar',\n\t\t\tdata: {\n\t\t\t\tdatasets: [{\n\t\t\t\t\tyAxisID: 'yScale1',\n\t\t\t\t\tdata: [10, 5, 0, 25, 78, -10]\n\t\t\t\t}, {\n\t\t\t\t\tyAxisID: 'yScale2',\n\t\t\t\t\tdata: [-19, -20, 0, -99, -50, 0]\n\t\t\t\t}],\n\t\t\t\tlabels: ['tick1', 'tick2', 'tick3', 'tick4', 'tick5', 'tick6']\n\t\t\t},\n\t\t\toptions: {\n\t\t\t\tscales: {\n\t\t\t\t\txAxes: [{\n\t\t\t\t\t\tid: 'xScale',\n\t\t\t\t\t\ttype: 'category'\n\t\t\t\t\t}],\n\t\t\t\t\tyAxes: [{\n\t\t\t\t\t\tid: 'yScale1',\n\t\t\t\t\t\ttype: 'linear'\n\t\t\t\t\t}, {\n\t\t\t\t\t\tid: 'yScale2',\n\t\t\t\t\t\ttype: 'linear'\n\t\t\t\t\t}]\n\t\t\t\t}\n\t\t\t}\n\t\t}, {\n\t\t\tcanvas: {\n\t\t\t\theight: 150,\n\t\t\t\twidth: 250\n\t\t\t}\n\t\t});\n\n\t\texpect(chart.chartArea.bottom).toBeCloseToPixel(102);\n\t\texpect(chart.chartArea.left).toBeCloseToPixel(86);\n\t\texpect(chart.chartArea.right).toBeCloseToPixel(250);\n\t\texpect(chart.chartArea.top).toBeCloseToPixel(32);\n\n\t\t// Is xScale at the right spot\n\t\texpect(chart.scales.xScale.bottom).toBeCloseToPixel(150);\n\t\texpect(chart.scales.xScale.left).toBeCloseToPixel(86);\n\t\texpect(chart.scales.xScale.right).toBeCloseToPixel(250);\n\t\texpect(chart.scales.xScale.top).toBeCloseToPixel(103);\n\t\texpect(chart.scales.xScale.labelRotation).toBeCloseTo(50);\n\n\t\t// Are yScales at the right spot\n\t\texpect(chart.scales.yScale1.bottom).toBeCloseToPixel(102);\n\t\texpect(chart.scales.yScale1.left).toBeCloseToPixel(0);\n\t\texpect(chart.scales.yScale1.right).toBeCloseToPixel(41);\n\t\texpect(chart.scales.yScale1.top).toBeCloseToPixel(32);\n\t\texpect(chart.scales.yScale1.labelRotation).toBeCloseTo(0);\n\n\t\texpect(chart.scales.yScale2.bottom).toBeCloseToPixel(102);\n\t\texpect(chart.scales.yScale2.left).toBeCloseToPixel(41);\n\t\texpect(chart.scales.yScale2.right).toBeCloseToPixel(86);\n\t\texpect(chart.scales.yScale2.top).toBeCloseToPixel(32);\n\t\texpect(chart.scales.yScale2.labelRotation).toBeCloseTo(0);\n\t});\n\n\txit ('should fix a full width box correctly', function() {\n\t\tvar chart = window.acquireChart({\n\t\t\ttype: 'bar',\n\t\t\tdata: {\n\t\t\t\tdatasets: [{\n\t\t\t\t\txAxisID: 'xScale1',\n\t\t\t\t\tdata: [10, 5, 0, 25, 78, -10]\n\t\t\t\t}, {\n\t\t\t\t\txAxisID: 'xScale2',\n\t\t\t\t\tdata: [-19, -20, 0, -99, -50, 0]\n\t\t\t\t}],\n\t\t\t\tlabels: ['tick1', 'tick2', 'tick3', 'tick4', 'tick5', 'tick6']\n\t\t\t},\n\t\t\toptions: {\n\t\t\t\tscales: {\n\t\t\t\t\txAxes: [{\n\t\t\t\t\t\tid: 'xScale1',\n\t\t\t\t\t\ttype: 'category'\n\t\t\t\t\t}, {\n\t\t\t\t\t\tid: 'xScale2',\n\t\t\t\t\t\ttype: 'category',\n\t\t\t\t\t\tposition: 'top',\n\t\t\t\t\t\tfullWidth: true\n\t\t\t\t\t}],\n\t\t\t\t\tyAxes: [{\n\t\t\t\t\t\tid: 'yScale',\n\t\t\t\t\t\ttype: 'linear'\n\t\t\t\t\t}]\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\n\t\texpect(chart.chartArea.bottom).toBeCloseToPixel(484);\n\t\texpect(chart.chartArea.left).toBeCloseToPixel(45);\n\t\texpect(chart.chartArea.right).toBeCloseToPixel(512);\n\t\texpect(chart.chartArea.top).toBeCloseToPixel(60);\n\n\t\t// Are xScales at the right spot\n\t\texpect(chart.scales.xScale1.bottom).toBeCloseToPixel(512);\n\t\texpect(chart.scales.xScale1.left).toBeCloseToPixel(45);\n\t\texpect(chart.scales.xScale1.right).toBeCloseToPixel(512);\n\t\texpect(chart.scales.xScale1.top).toBeCloseToPixel(484);\n\n\t\texpect(chart.scales.xScale2.bottom).toBeCloseToPixel(60);\n\t\texpect(chart.scales.xScale2.left).toBeCloseToPixel(0);\n\t\texpect(chart.scales.xScale2.right).toBeCloseToPixel(512);\n\t\texpect(chart.scales.xScale2.top).toBeCloseToPixel(32);\n\n\t\t// Is yScale at the right spot\n\t\texpect(chart.scales.yScale.bottom).toBeCloseToPixel(484);\n\t\texpect(chart.scales.yScale.left).toBeCloseToPixel(0);\n\t\texpect(chart.scales.yScale.right).toBeCloseToPixel(45);\n\t\texpect(chart.scales.yScale.top).toBeCloseToPixel(60);\n\t});\n\n\tdescribe('padding settings', function() {\n\t\tit('should apply a single padding to all dimensions', function() {\n\t\t\tvar chart = window.acquireChart({\n\t\t\t\ttype: 'bar',\n\t\t\t\tdata: {\n\t\t\t\t\tdatasets: [\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tdata: [10, 5, 0, 25, 78, -10]\n\t\t\t\t\t\t}\n\t\t\t\t\t],\n\t\t\t\t\tlabels: ['tick1', 'tick2', 'tick3', 'tick4', 'tick5', 'tick6']\n\t\t\t\t},\n\t\t\t\toptions: {\n\t\t\t\t\tscales: {\n\t\t\t\t\t\txAxes: [{\n\t\t\t\t\t\t\tid: 'xScale',\n\t\t\t\t\t\t\ttype: 'category',\n\t\t\t\t\t\t\tdisplay: false\n\t\t\t\t\t\t}],\n\t\t\t\t\t\tyAxes: [{\n\t\t\t\t\t\t\tid: 'yScale',\n\t\t\t\t\t\t\ttype: 'linear',\n\t\t\t\t\t\t\tdisplay: false\n\t\t\t\t\t\t}]\n\t\t\t\t\t},\n\t\t\t\t\tlegend: {\n\t\t\t\t\t\tdisplay: false\n\t\t\t\t\t},\n\t\t\t\t\ttitle: {\n\t\t\t\t\t\tdisplay: false\n\t\t\t\t\t},\n\t\t\t\t\tlayout: {\n\t\t\t\t\t\tpadding: 10\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}, {\n\t\t\t\tcanvas: {\n\t\t\t\t\theight: 150,\n\t\t\t\t\twidth: 250\n\t\t\t\t}\n\t\t\t});\n\n\t\t\texpect(chart.chartArea.bottom).toBeCloseToPixel(140);\n\t\t\texpect(chart.chartArea.left).toBeCloseToPixel(10);\n\t\t\texpect(chart.chartArea.right).toBeCloseToPixel(240);\n\t\t\texpect(chart.chartArea.top).toBeCloseToPixel(10);\n\t\t});\n\n\t\tit('should apply padding in all positions', function() {\n\t\t\tvar chart = window.acquireChart({\n\t\t\t\ttype: 'bar',\n\t\t\t\tdata: {\n\t\t\t\t\tdatasets: [\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tdata: [10, 5, 0, 25, 78, -10]\n\t\t\t\t\t\t}\n\t\t\t\t\t],\n\t\t\t\t\tlabels: ['tick1', 'tick2', 'tick3', 'tick4', 'tick5', 'tick6']\n\t\t\t\t},\n\t\t\t\toptions: {\n\t\t\t\t\tscales: {\n\t\t\t\t\t\txAxes: [{\n\t\t\t\t\t\t\tid: 'xScale',\n\t\t\t\t\t\t\ttype: 'category',\n\t\t\t\t\t\t\tdisplay: false\n\t\t\t\t\t\t}],\n\t\t\t\t\t\tyAxes: [{\n\t\t\t\t\t\t\tid: 'yScale',\n\t\t\t\t\t\t\ttype: 'linear',\n\t\t\t\t\t\t\tdisplay: false\n\t\t\t\t\t\t}]\n\t\t\t\t\t},\n\t\t\t\t\tlegend: {\n\t\t\t\t\t\tdisplay: false\n\t\t\t\t\t},\n\t\t\t\t\ttitle: {\n\t\t\t\t\t\tdisplay: false\n\t\t\t\t\t},\n\t\t\t\t\tlayout: {\n\t\t\t\t\t\tpadding: {\n\t\t\t\t\t\t\tleft: 5,\n\t\t\t\t\t\t\tright: 15,\n\t\t\t\t\t\t\ttop: 8,\n\t\t\t\t\t\t\tbottom: 12\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}, {\n\t\t\t\tcanvas: {\n\t\t\t\t\theight: 150,\n\t\t\t\t\twidth: 250\n\t\t\t\t}\n\t\t\t});\n\n\t\t\texpect(chart.chartArea.bottom).toBeCloseToPixel(138);\n\t\t\texpect(chart.chartArea.left).toBeCloseToPixel(5);\n\t\t\texpect(chart.chartArea.right).toBeCloseToPixel(235);\n\t\t\texpect(chart.chartArea.top).toBeCloseToPixel(8);\n\t\t});\n\n\t\tit('should default to 0 padding if no dimensions specified', function() {\n\t\t\tvar chart = window.acquireChart({\n\t\t\t\ttype: 'bar',\n\t\t\t\tdata: {\n\t\t\t\t\tdatasets: [\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tdata: [10, 5, 0, 25, 78, -10]\n\t\t\t\t\t\t}\n\t\t\t\t\t],\n\t\t\t\t\tlabels: ['tick1', 'tick2', 'tick3', 'tick4', 'tick5', 'tick6']\n\t\t\t\t},\n\t\t\t\toptions: {\n\t\t\t\t\tscales: {\n\t\t\t\t\t\txAxes: [{\n\t\t\t\t\t\t\tid: 'xScale',\n\t\t\t\t\t\t\ttype: 'category',\n\t\t\t\t\t\t\tdisplay: false\n\t\t\t\t\t\t}],\n\t\t\t\t\t\tyAxes: [{\n\t\t\t\t\t\t\tid: 'yScale',\n\t\t\t\t\t\t\ttype: 'linear',\n\t\t\t\t\t\t\tdisplay: false\n\t\t\t\t\t\t}]\n\t\t\t\t\t},\n\t\t\t\t\tlegend: {\n\t\t\t\t\t\tdisplay: false\n\t\t\t\t\t},\n\t\t\t\t\ttitle: {\n\t\t\t\t\t\tdisplay: false\n\t\t\t\t\t},\n\t\t\t\t\tlayout: {\n\t\t\t\t\t\tpadding: {}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}, {\n\t\t\t\tcanvas: {\n\t\t\t\t\theight: 150,\n\t\t\t\t\twidth: 250\n\t\t\t\t}\n\t\t\t});\n\n\t\t\texpect(chart.chartArea.bottom).toBeCloseToPixel(150);\n\t\t\texpect(chart.chartArea.left).toBeCloseToPixel(0);\n\t\t\texpect(chart.chartArea.right).toBeCloseToPixel(250);\n\t\t\texpect(chart.chartArea.top).toBeCloseToPixel(0);\n\t\t});\n\t});\n\n\tdescribe('ordering by weight', function() {\n\t\tit('should keep higher weights outside', function() {\n\t\t\tvar chart = window.acquireChart({\n\t\t\t\ttype: 'bar',\n\t\t\t\tdata: {\n\t\t\t\t\tdatasets: [\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tdata: [10, 5, 0, 25, 78, -10]\n\t\t\t\t\t\t}\n\t\t\t\t\t],\n\t\t\t\t\tlabels: ['tick1', 'tick2', 'tick3', 'tick4', 'tick5', 'tick6']\n\t\t\t\t},\n\t\t\t\toptions: {\n\t\t\t\t\tlegend: {\n\t\t\t\t\t\tdisplay: true,\n\t\t\t\t\t\tposition: 'left',\n\t\t\t\t\t},\n\t\t\t\t\ttitle: {\n\t\t\t\t\t\tdisplay: true,\n\t\t\t\t\t\tposition: 'bottom',\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t}, {\n\t\t\t\tcanvas: {\n\t\t\t\t\theight: 150,\n\t\t\t\t\twidth: 250\n\t\t\t\t}\n\t\t\t});\n\n\t\t\tvar xAxis = chart.scales['x-axis-0'];\n\t\t\tvar yAxis = chart.scales['y-axis-0'];\n\t\t\tvar legend = chart.legend;\n\t\t\tvar title = chart.titleBlock;\n\n\t\t\texpect(yAxis.left).toBe(legend.right);\n\t\t\texpect(xAxis.bottom).toBe(title.top);\n\t\t});\n\n\t\tit('should correctly set weights of scales and order them', function() {\n\t\t\tvar chart = window.acquireChart({\n\t\t\t\ttype: 'bar',\n\t\t\t\tdata: {\n\t\t\t\t\tdatasets: [\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tdata: [10, 5, 0, 25, 78, -10]\n\t\t\t\t\t\t}\n\t\t\t\t\t],\n\t\t\t\t\tlabels: ['tick1', 'tick2', 'tick3', 'tick4', 'tick5', 'tick6']\n\t\t\t\t},\n\t\t\t\toptions: {\n\t\t\t\t\tscales: {\n\t\t\t\t\t\txAxes: [{\n\t\t\t\t\t\t\tid: 'xScale0',\n\t\t\t\t\t\t\ttype: 'category',\n\t\t\t\t\t\t\tdisplay: true,\n\t\t\t\t\t\t\tweight: 1\n\t\t\t\t\t\t}, {\n\t\t\t\t\t\t\tid: 'xScale1',\n\t\t\t\t\t\t\ttype: 'category',\n\t\t\t\t\t\t\tdisplay: true,\n\t\t\t\t\t\t\tweight: 2\n\t\t\t\t\t\t}, {\n\t\t\t\t\t\t\tid: 'xScale2',\n\t\t\t\t\t\t\ttype: 'category',\n\t\t\t\t\t\t\tdisplay: true\n\t\t\t\t\t\t}, {\n\t\t\t\t\t\t\tid: 'xScale3',\n\t\t\t\t\t\t\ttype: 'category',\n\t\t\t\t\t\t\tdisplay: true,\n\t\t\t\t\t\t\tposition: 'top',\n\t\t\t\t\t\t\tweight: 1\n\t\t\t\t\t\t}, {\n\t\t\t\t\t\t\tid: 'xScale4',\n\t\t\t\t\t\t\ttype: 'category',\n\t\t\t\t\t\t\tdisplay: true,\n\t\t\t\t\t\t\tposition: 'top',\n\t\t\t\t\t\t\tweight: 2\n\t\t\t\t\t\t}],\n\t\t\t\t\t\tyAxes: [{\n\t\t\t\t\t\t\tid: 'yScale0',\n\t\t\t\t\t\t\ttype: 'linear',\n\t\t\t\t\t\t\tdisplay: true,\n\t\t\t\t\t\t\tweight: 1\n\t\t\t\t\t\t}, {\n\t\t\t\t\t\t\tid: 'yScale1',\n\t\t\t\t\t\t\ttype: 'linear',\n\t\t\t\t\t\t\tdisplay: true,\n\t\t\t\t\t\t\tweight: 2\n\t\t\t\t\t\t}, {\n\t\t\t\t\t\t\tid: 'yScale2',\n\t\t\t\t\t\t\ttype: 'linear',\n\t\t\t\t\t\t\tdisplay: true\n\t\t\t\t\t\t}, {\n\t\t\t\t\t\t\tid: 'yScale3',\n\t\t\t\t\t\t\ttype: 'linear',\n\t\t\t\t\t\t\tdisplay: true,\n\t\t\t\t\t\t\tposition: 'right',\n\t\t\t\t\t\t\tweight: 1\n\t\t\t\t\t\t}, {\n\t\t\t\t\t\t\tid: 'yScale4',\n\t\t\t\t\t\t\ttype: 'linear',\n\t\t\t\t\t\t\tdisplay: true,\n\t\t\t\t\t\t\tposition: 'right',\n\t\t\t\t\t\t\tweight: 2\n\t\t\t\t\t\t}]\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}, {\n\t\t\t\tcanvas: {\n\t\t\t\t\theight: 150,\n\t\t\t\t\twidth: 250\n\t\t\t\t}\n\t\t\t});\n\n\t\t\tvar xScale0 = chart.scales.xScale0;\n\t\t\tvar xScale1 = chart.scales.xScale1;\n\t\t\tvar xScale2 = chart.scales.xScale2;\n\t\t\tvar xScale3 = chart.scales.xScale3;\n\t\t\tvar xScale4 = chart.scales.xScale4;\n\n\t\t\tvar yScale0 = chart.scales.yScale0;\n\t\t\tvar yScale1 = chart.scales.yScale1;\n\t\t\tvar yScale2 = chart.scales.yScale2;\n\t\t\tvar yScale3 = chart.scales.yScale3;\n\t\t\tvar yScale4 = chart.scales.yScale4;\n\n\t\t\texpect(xScale0.weight).toBe(1);\n\t\t\texpect(xScale1.weight).toBe(2);\n\t\t\texpect(xScale2.weight).toBe(0);\n\n\t\t\texpect(xScale3.weight).toBe(1);\n\t\t\texpect(xScale4.weight).toBe(2);\n\n\t\t\texpect(yScale0.weight).toBe(1);\n\t\t\texpect(yScale1.weight).toBe(2);\n\t\t\texpect(yScale2.weight).toBe(0);\n\n\t\t\texpect(yScale3.weight).toBe(1);\n\t\t\texpect(yScale4.weight).toBe(2);\n\n\t\t\tvar isOrderCorrect = false;\n\n\t\t\t// bottom axes\n\t\t\tisOrderCorrect = xScale2.top < xScale0.top && xScale0.top < xScale1.top;\n\t\t\texpect(isOrderCorrect).toBe(true);\n\n\t\t\t// top axes\n\t\t\tisOrderCorrect = xScale4.top < xScale3.top;\n\t\t\texpect(isOrderCorrect).toBe(true);\n\n\t\t\t// left axes\n\t\t\tisOrderCorrect = yScale1.left < yScale0.left && yScale0.left < yScale2.left;\n\t\t\texpect(isOrderCorrect).toBe(true);\n\n\t\t\t// right axes\n\t\t\tisOrderCorrect = yScale3.left < yScale4.left;\n\t\t\texpect(isOrderCorrect).toBe(true);\n\t\t});\n\t});\n});\n"
  },
  {
    "path": "app_backend/static/plugin/Chart.js-2.6.0/test/specs/core.plugin.tests.js",
    "content": "describe('Chart.plugins', function() {\n\tbeforeEach(function() {\n\t\tthis._plugins = Chart.plugins.getAll();\n\t\tChart.plugins.clear();\n\t});\n\n\tafterEach(function() {\n\t\tChart.plugins.clear();\n\t\tChart.plugins.register(this._plugins);\n\t\tdelete this._plugins;\n\t});\n\n\tdescribe('Chart.plugins.register', function() {\n\t\tit('should register a plugin', function() {\n\t\t\tChart.plugins.register({});\n\t\t\texpect(Chart.plugins.count()).toBe(1);\n\t\t\tChart.plugins.register({});\n\t\t\texpect(Chart.plugins.count()).toBe(2);\n\t\t});\n\n\t\tit('should register an array of plugins', function() {\n\t\t\tChart.plugins.register([{}, {}, {}]);\n\t\t\texpect(Chart.plugins.count()).toBe(3);\n\t\t});\n\n\t\tit('should succeed to register an already registered plugin', function() {\n\t\t\tvar plugin = {};\n\t\t\tChart.plugins.register(plugin);\n\t\t\texpect(Chart.plugins.count()).toBe(1);\n\t\t\tChart.plugins.register(plugin);\n\t\t\texpect(Chart.plugins.count()).toBe(1);\n\t\t\tChart.plugins.register([{}, plugin, plugin]);\n\t\t\texpect(Chart.plugins.count()).toBe(2);\n\t\t});\n\t});\n\n\tdescribe('Chart.plugins.unregister', function() {\n\t\tit('should unregister a plugin', function() {\n\t\t\tvar plugin = {};\n\t\t\tChart.plugins.register(plugin);\n\t\t\texpect(Chart.plugins.count()).toBe(1);\n\t\t\tChart.plugins.unregister(plugin);\n\t\t\texpect(Chart.plugins.count()).toBe(0);\n\t\t});\n\n\t\tit('should unregister an array of plugins', function() {\n\t\t\tvar plugins = [{}, {}, {}];\n\t\t\tChart.plugins.register(plugins);\n\t\t\texpect(Chart.plugins.count()).toBe(3);\n\t\t\tChart.plugins.unregister(plugins.slice(0, 2));\n\t\t\texpect(Chart.plugins.count()).toBe(1);\n\t\t});\n\n\t\tit('should succeed to unregister a plugin not registered', function() {\n\t\t\tvar plugin = {};\n\t\t\tChart.plugins.register(plugin);\n\t\t\texpect(Chart.plugins.count()).toBe(1);\n\t\t\tChart.plugins.unregister({});\n\t\t\texpect(Chart.plugins.count()).toBe(1);\n\t\t\tChart.plugins.unregister([{}, plugin]);\n\t\t\texpect(Chart.plugins.count()).toBe(0);\n\t\t});\n\t});\n\n\tdescribe('Chart.plugins.notify', function() {\n\t\tit('should call inline plugins with arguments', function() {\n\t\t\tvar plugin = {hook: function() {}};\n\t\t\tvar chart = window.acquireChart({\n\t\t\t\tplugins: [plugin]\n\t\t\t});\n\n\t\t\tspyOn(plugin, 'hook');\n\n\t\t\tChart.plugins.notify(chart, 'hook', 42);\n\t\t\texpect(plugin.hook.calls.count()).toBe(1);\n\t\t\texpect(plugin.hook.calls.first().args[0]).toBe(chart);\n\t\t\texpect(plugin.hook.calls.first().args[1]).toBe(42);\n\t\t\texpect(plugin.hook.calls.first().args[2]).toEqual({});\n\t\t});\n\n\t\tit('should call global plugins with arguments', function() {\n\t\t\tvar plugin = {hook: function() {}};\n\t\t\tvar chart = window.acquireChart({});\n\n\t\t\tspyOn(plugin, 'hook');\n\n\t\t\tChart.plugins.register(plugin);\n\t\t\tChart.plugins.notify(chart, 'hook', 42);\n\t\t\texpect(plugin.hook.calls.count()).toBe(1);\n\t\t\texpect(plugin.hook.calls.first().args[0]).toBe(chart);\n\t\t\texpect(plugin.hook.calls.first().args[1]).toBe(42);\n\t\t\texpect(plugin.hook.calls.first().args[2]).toEqual({});\n\t\t});\n\n\t\tit('should call plugin only once even if registered multiple times', function() {\n\t\t\tvar plugin = {hook: function() {}};\n\t\t\tvar chart = window.acquireChart({\n\t\t\t\tplugins: [plugin, plugin]\n\t\t\t});\n\n\t\t\tspyOn(plugin, 'hook');\n\n\t\t\tChart.plugins.register([plugin, plugin]);\n\t\t\tChart.plugins.notify(chart, 'hook');\n\t\t\texpect(plugin.hook.calls.count()).toBe(1);\n\t\t});\n\n\t\tit('should call plugins in the correct order (global first)', function() {\n\t\t\tvar results = [];\n\t\t\tvar chart = window.acquireChart({\n\t\t\t\tplugins: [{\n\t\t\t\t\thook: function() {\n\t\t\t\t\t\tresults.push(1);\n\t\t\t\t\t}\n\t\t\t\t}, {\n\t\t\t\t\thook: function() {\n\t\t\t\t\t\tresults.push(2);\n\t\t\t\t\t}\n\t\t\t\t}, {\n\t\t\t\t\thook: function() {\n\t\t\t\t\t\tresults.push(3);\n\t\t\t\t\t}\n\t\t\t\t}]\n\t\t\t});\n\n\t\t\tChart.plugins.register([{\n\t\t\t\thook: function() {\n\t\t\t\t\tresults.push(4);\n\t\t\t\t}\n\t\t\t}, {\n\t\t\t\thook: function() {\n\t\t\t\t\tresults.push(5);\n\t\t\t\t}\n\t\t\t}, {\n\t\t\t\thook: function() {\n\t\t\t\t\tresults.push(6);\n\t\t\t\t}\n\t\t\t}]);\n\n\t\t\tvar ret = Chart.plugins.notify(chart, 'hook');\n\t\t\texpect(ret).toBeTruthy();\n\t\t\texpect(results).toEqual([4, 5, 6, 1, 2, 3]);\n\t\t});\n\n\t\tit('should return TRUE if no plugin explicitly returns FALSE', function() {\n\t\t\tvar chart = window.acquireChart({\n\t\t\t\tplugins: [{\n\t\t\t\t\thook: function() {}\n\t\t\t\t}, {\n\t\t\t\t\thook: function() {\n\t\t\t\t\t\treturn null;\n\t\t\t\t\t}\n\t\t\t\t}, {\n\t\t\t\t\thook: function() {\n\t\t\t\t\t\treturn 0;\n\t\t\t\t\t}\n\t\t\t\t}, {\n\t\t\t\t\thook: function() {\n\t\t\t\t\t\treturn true;\n\t\t\t\t\t}\n\t\t\t\t}, {\n\t\t\t\t\thook: function() {\n\t\t\t\t\t\treturn 1;\n\t\t\t\t\t}\n\t\t\t\t}]\n\t\t\t});\n\n\t\t\tvar plugins = chart.config.plugins;\n\t\t\tplugins.forEach(function(plugin) {\n\t\t\t\tspyOn(plugin, 'hook').and.callThrough();\n\t\t\t});\n\n\t\t\tvar ret = Chart.plugins.notify(chart, 'hook');\n\t\t\texpect(ret).toBeTruthy();\n\t\t\tplugins.forEach(function(plugin) {\n\t\t\t\texpect(plugin.hook).toHaveBeenCalled();\n\t\t\t});\n\t\t});\n\n\t\tit('should return FALSE if any plugin explicitly returns FALSE', function() {\n\t\t\tvar chart = window.acquireChart({\n\t\t\t\tplugins: [{\n\t\t\t\t\thook: function() {}\n\t\t\t\t}, {\n\t\t\t\t\thook: function() {\n\t\t\t\t\t\treturn null;\n\t\t\t\t\t}\n\t\t\t\t}, {\n\t\t\t\t\thook: function() {\n\t\t\t\t\t\treturn false;\n\t\t\t\t\t}\n\t\t\t\t}, {\n\t\t\t\t\thook: function() {\n\t\t\t\t\t\treturn 42;\n\t\t\t\t\t}\n\t\t\t\t}, {\n\t\t\t\t\thook: function() {\n\t\t\t\t\t\treturn 'bar';\n\t\t\t\t\t}\n\t\t\t\t}]\n\t\t\t});\n\n\t\t\tvar plugins = chart.config.plugins;\n\t\t\tplugins.forEach(function(plugin) {\n\t\t\t\tspyOn(plugin, 'hook').and.callThrough();\n\t\t\t});\n\n\t\t\tvar ret = Chart.plugins.notify(chart, 'hook');\n\t\t\texpect(ret).toBeFalsy();\n\t\t\texpect(plugins[0].hook).toHaveBeenCalled();\n\t\t\texpect(plugins[1].hook).toHaveBeenCalled();\n\t\t\texpect(plugins[2].hook).toHaveBeenCalled();\n\t\t\texpect(plugins[3].hook).not.toHaveBeenCalled();\n\t\t\texpect(plugins[4].hook).not.toHaveBeenCalled();\n\t\t});\n\t});\n\n\tdescribe('config.options.plugins', function() {\n\t\tit('should call plugins with options at last argument', function() {\n\t\t\tvar plugin = {id: 'foo', hook: function() {}};\n\t\t\tvar chart = window.acquireChart({\n\t\t\t\toptions: {\n\t\t\t\t\tplugins: {\n\t\t\t\t\t\tfoo: {a: '123'},\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t});\n\n\t\t\tspyOn(plugin, 'hook');\n\n\t\t\tChart.plugins.register(plugin);\n\t\t\tChart.plugins.notify(chart, 'hook');\n\t\t\tChart.plugins.notify(chart, 'hook', ['bla']);\n\t\t\tChart.plugins.notify(chart, 'hook', ['bla', 42]);\n\n\t\t\texpect(plugin.hook.calls.count()).toBe(3);\n\t\t\texpect(plugin.hook.calls.argsFor(0)[1]).toEqual({a: '123'});\n\t\t\texpect(plugin.hook.calls.argsFor(1)[2]).toEqual({a: '123'});\n\t\t\texpect(plugin.hook.calls.argsFor(2)[3]).toEqual({a: '123'});\n\t\t});\n\n\t\tit('should call plugins with options associated to their identifier', function() {\n\t\t\tvar plugins = {\n\t\t\t\ta: {id: 'a', hook: function() {}},\n\t\t\t\tb: {id: 'b', hook: function() {}},\n\t\t\t\tc: {id: 'c', hook: function() {}}\n\t\t\t};\n\n\t\t\tChart.plugins.register(plugins.a);\n\n\t\t\tvar chart = window.acquireChart({\n\t\t\t\tplugins: [plugins.b, plugins.c],\n\t\t\t\toptions: {\n\t\t\t\t\tplugins: {\n\t\t\t\t\t\ta: {a: '123'},\n\t\t\t\t\t\tb: {b: '456'},\n\t\t\t\t\t\tc: {c: '789'}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t});\n\n\t\t\tspyOn(plugins.a, 'hook');\n\t\t\tspyOn(plugins.b, 'hook');\n\t\t\tspyOn(plugins.c, 'hook');\n\n\t\t\tChart.plugins.notify(chart, 'hook');\n\n\t\t\texpect(plugins.a.hook).toHaveBeenCalled();\n\t\t\texpect(plugins.b.hook).toHaveBeenCalled();\n\t\t\texpect(plugins.c.hook).toHaveBeenCalled();\n\t\t\texpect(plugins.a.hook.calls.first().args[1]).toEqual({a: '123'});\n\t\t\texpect(plugins.b.hook.calls.first().args[1]).toEqual({b: '456'});\n\t\t\texpect(plugins.c.hook.calls.first().args[1]).toEqual({c: '789'});\n\t\t});\n\n\t\tit('should not called plugins when config.options.plugins.{id} is FALSE', function() {\n\t\t\tvar plugins = {\n\t\t\t\ta: {id: 'a', hook: function() {}},\n\t\t\t\tb: {id: 'b', hook: function() {}},\n\t\t\t\tc: {id: 'c', hook: function() {}}\n\t\t\t};\n\n\t\t\tChart.plugins.register(plugins.a);\n\n\t\t\tvar chart = window.acquireChart({\n\t\t\t\tplugins: [plugins.b, plugins.c],\n\t\t\t\toptions: {\n\t\t\t\t\tplugins: {\n\t\t\t\t\t\ta: false,\n\t\t\t\t\t\tb: false\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t});\n\n\t\t\tspyOn(plugins.a, 'hook');\n\t\t\tspyOn(plugins.b, 'hook');\n\t\t\tspyOn(plugins.c, 'hook');\n\n\t\t\tChart.plugins.notify(chart, 'hook');\n\n\t\t\texpect(plugins.a.hook).not.toHaveBeenCalled();\n\t\t\texpect(plugins.b.hook).not.toHaveBeenCalled();\n\t\t\texpect(plugins.c.hook).toHaveBeenCalled();\n\t\t});\n\n\t\tit('should call plugins with default options when plugin options is TRUE', function() {\n\t\t\tvar plugin = {id: 'a', hook: function() {}};\n\n\t\t\tChart.defaults.global.plugins.a = {a: 42};\n\t\t\tChart.plugins.register(plugin);\n\n\t\t\tvar chart = window.acquireChart({\n\t\t\t\toptions: {\n\t\t\t\t\tplugins: {\n\t\t\t\t\t\ta: true\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t});\n\n\t\t\tspyOn(plugin, 'hook');\n\n\t\t\tChart.plugins.notify(chart, 'hook');\n\n\t\t\texpect(plugin.hook).toHaveBeenCalled();\n\t\t\texpect(plugin.hook.calls.first().args[1]).toEqual({a: 42});\n\t\t});\n\n\n\t\tit('should call plugins with default options if plugin config options is undefined', function() {\n\t\t\tvar plugin = {id: 'a', hook: function() {}};\n\n\t\t\tChart.defaults.global.plugins.a = {a: 'foobar'};\n\t\t\tChart.plugins.register(plugin);\n\t\t\tspyOn(plugin, 'hook');\n\n\t\t\tvar chart = window.acquireChart();\n\n\t\t\tChart.plugins.notify(chart, 'hook');\n\n\t\t\texpect(plugin.hook).toHaveBeenCalled();\n\t\t\texpect(plugin.hook.calls.first().args[1]).toEqual({a: 'foobar'});\n\t\t});\n\t});\n});\n"
  },
  {
    "path": "app_backend/static/plugin/Chart.js-2.6.0/test/specs/core.scaleService.tests.js",
    "content": "// Tests of the scale service\ndescribe('Test the scale service', function() {\n\n\tit('should update scale defaults', function() {\n\t\tvar defaults = {\n\t\t\ttestProp: true\n\t\t};\n\t\tvar type = 'my_test_type';\n\t\tvar Constructor = function() {\n\t\t\tthis.initialized = true;\n\t\t};\n\t\tChart.scaleService.registerScaleType(type, Constructor, defaults);\n\n\t\t// Should equal defaults but not be an identical object\n\t\texpect(Chart.scaleService.getScaleDefaults(type)).toEqual(jasmine.objectContaining({\n\t\t\ttestProp: true\n\t\t}));\n\n\t\tChart.scaleService.updateScaleDefaults(type, {\n\t\t\ttestProp: 'red',\n\t\t\tnewProp: 42\n\t\t});\n\n\t\texpect(Chart.scaleService.getScaleDefaults(type)).toEqual(jasmine.objectContaining({\n\t\t\ttestProp: 'red',\n\t\t\tnewProp: 42\n\t\t}));\n\t});\n});\n"
  },
  {
    "path": "app_backend/static/plugin/Chart.js-2.6.0/test/specs/core.tooltip.tests.js",
    "content": "// Test the rectangle element\ndescribe('Core.Tooltip', function() {\n\tdescribe('config', function() {\n\t\tit('should not include the dataset label in the body string if not defined', function() {\n\t\t\tvar data = {\n\t\t\t\tdatasets: [{\n\t\t\t\t\tdata: [10, 20, 30],\n\t\t\t\t\tpointHoverBorderColor: 'rgb(255, 0, 0)',\n\t\t\t\t\tpointHoverBackgroundColor: 'rgb(0, 255, 0)'\n\t\t\t\t}],\n\t\t\t\tlabels: ['Point 1', 'Point 2', 'Point 3']\n\t\t\t};\n\t\t\tvar tooltipItem = {\n\t\t\t\tindex: 1,\n\t\t\t\tdatasetIndex: 0,\n\t\t\t\txLabel: 'Point 2',\n\t\t\t\tyLabel: '20'\n\t\t\t};\n\n\t\t\tvar label = Chart.defaults.global.tooltips.callbacks.label(tooltipItem, data);\n\t\t\texpect(label).toBe('20');\n\n\t\t\tdata.datasets[0].label = 'My dataset';\n\t\t\tlabel = Chart.defaults.global.tooltips.callbacks.label(tooltipItem, data);\n\t\t\texpect(label).toBe('My dataset: 20');\n\t\t});\n\t});\n\n\tdescribe('index mode', function() {\n\t\tit('Should only use x distance when intersect is false', function() {\n\t\t\tvar chart = window.acquireChart({\n\t\t\t\ttype: 'line',\n\t\t\t\tdata: {\n\t\t\t\t\tdatasets: [{\n\t\t\t\t\t\tlabel: 'Dataset 1',\n\t\t\t\t\t\tdata: [10, 20, 30],\n\t\t\t\t\t\tpointHoverBorderColor: 'rgb(255, 0, 0)',\n\t\t\t\t\t\tpointHoverBackgroundColor: 'rgb(0, 255, 0)'\n\t\t\t\t\t}, {\n\t\t\t\t\t\tlabel: 'Dataset 2',\n\t\t\t\t\t\tdata: [40, 40, 40],\n\t\t\t\t\t\tpointHoverBorderColor: 'rgb(0, 0, 255)',\n\t\t\t\t\t\tpointHoverBackgroundColor: 'rgb(0, 255, 255)'\n\t\t\t\t\t}],\n\t\t\t\t\tlabels: ['Point 1', 'Point 2', 'Point 3']\n\t\t\t\t},\n\t\t\t\toptions: {\n\t\t\t\t\ttooltips: {\n\t\t\t\t\t\tmode: 'index',\n\t\t\t\t\t\tintersect: false\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t});\n\n\t\t\t// Trigger an event over top of the\n\t\t\tvar meta = chart.getDatasetMeta(0);\n\t\t\tvar point = meta.data[1];\n\n\t\t\tvar node = chart.canvas;\n\t\t\tvar rect = node.getBoundingClientRect();\n\n\t\t\tvar evt = new MouseEvent('mousemove', {\n\t\t\t\tview: window,\n\t\t\t\tbubbles: true,\n\t\t\t\tcancelable: true,\n\t\t\t\tclientX: rect.left + point._model.x,\n\t\t\t\tclientY: 0\n\t\t\t});\n\n\t\t\t// Manually trigger rather than having an async test\n\t\t\tnode.dispatchEvent(evt);\n\n\t\t\t// Check and see if tooltip was displayed\n\t\t\tvar tooltip = chart.tooltip;\n\t\t\tvar globalDefaults = Chart.defaults.global;\n\n\t\t\texpect(tooltip._view).toEqual(jasmine.objectContaining({\n\t\t\t\t// Positioning\n\t\t\t\txPadding: 6,\n\t\t\t\tyPadding: 6,\n\t\t\t\txAlign: 'left',\n\t\t\t\tyAlign: 'center',\n\n\t\t\t\t// Body\n\t\t\t\tbodyFontColor: '#fff',\n\t\t\t\t_bodyFontFamily: globalDefaults.defaultFontFamily,\n\t\t\t\t_bodyFontStyle: globalDefaults.defaultFontStyle,\n\t\t\t\t_bodyAlign: 'left',\n\t\t\t\tbodyFontSize: globalDefaults.defaultFontSize,\n\t\t\t\tbodySpacing: 2,\n\n\t\t\t\t// Title\n\t\t\t\ttitleFontColor: '#fff',\n\t\t\t\t_titleFontFamily: globalDefaults.defaultFontFamily,\n\t\t\t\t_titleFontStyle: 'bold',\n\t\t\t\ttitleFontSize: globalDefaults.defaultFontSize,\n\t\t\t\t_titleAlign: 'left',\n\t\t\t\ttitleSpacing: 2,\n\t\t\t\ttitleMarginBottom: 6,\n\n\t\t\t\t// Footer\n\t\t\t\tfooterFontColor: '#fff',\n\t\t\t\t_footerFontFamily: globalDefaults.defaultFontFamily,\n\t\t\t\t_footerFontStyle: 'bold',\n\t\t\t\tfooterFontSize: globalDefaults.defaultFontSize,\n\t\t\t\t_footerAlign: 'left',\n\t\t\t\tfooterSpacing: 2,\n\t\t\t\tfooterMarginTop: 6,\n\n\t\t\t\t// Appearance\n\t\t\t\tcaretSize: 5,\n\t\t\t\tcornerRadius: 6,\n\t\t\t\tbackgroundColor: 'rgba(0,0,0,0.8)',\n\t\t\t\topacity: 1,\n\t\t\t\tlegendColorBackground: '#fff',\n\t\t\t\tdisplayColors: true,\n\n\t\t\t\t// Text\n\t\t\t\ttitle: ['Point 2'],\n\t\t\t\tbeforeBody: [],\n\t\t\t\tbody: [{\n\t\t\t\t\tbefore: [],\n\t\t\t\t\tlines: ['Dataset 1: 20'],\n\t\t\t\t\tafter: []\n\t\t\t\t}, {\n\t\t\t\t\tbefore: [],\n\t\t\t\t\tlines: ['Dataset 2: 40'],\n\t\t\t\t\tafter: []\n\t\t\t\t}],\n\t\t\t\tafterBody: [],\n\t\t\t\tfooter: [],\n\t\t\t\tcaretPadding: 2,\n\t\t\t\tlabelColors: [{\n\t\t\t\t\tborderColor: 'rgb(255, 0, 0)',\n\t\t\t\t\tbackgroundColor: 'rgb(0, 255, 0)'\n\t\t\t\t}, {\n\t\t\t\t\tborderColor: 'rgb(0, 0, 255)',\n\t\t\t\t\tbackgroundColor: 'rgb(0, 255, 255)'\n\t\t\t\t}]\n\t\t\t}));\n\n\t\t\texpect(tooltip._view.x).toBeCloseToPixel(263);\n\t\t\texpect(tooltip._view.y).toBeCloseToPixel(155);\n\t\t});\n\n\t\tit('Should only display if intersecting if intersect is set', function() {\n\t\t\tvar chart = window.acquireChart({\n\t\t\t\ttype: 'line',\n\t\t\t\tdata: {\n\t\t\t\t\tdatasets: [{\n\t\t\t\t\t\tlabel: 'Dataset 1',\n\t\t\t\t\t\tdata: [10, 20, 30],\n\t\t\t\t\t\tpointHoverBorderColor: 'rgb(255, 0, 0)',\n\t\t\t\t\t\tpointHoverBackgroundColor: 'rgb(0, 255, 0)'\n\t\t\t\t\t}, {\n\t\t\t\t\t\tlabel: 'Dataset 2',\n\t\t\t\t\t\tdata: [40, 40, 40],\n\t\t\t\t\t\tpointHoverBorderColor: 'rgb(0, 0, 255)',\n\t\t\t\t\t\tpointHoverBackgroundColor: 'rgb(0, 255, 255)'\n\t\t\t\t\t}],\n\t\t\t\t\tlabels: ['Point 1', 'Point 2', 'Point 3']\n\t\t\t\t},\n\t\t\t\toptions: {\n\t\t\t\t\ttooltips: {\n\t\t\t\t\t\tmode: 'index',\n\t\t\t\t\t\tintersect: true\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t});\n\n\t\t\t// Trigger an event over top of the\n\t\t\tvar meta = chart.getDatasetMeta(0);\n\t\t\tvar point = meta.data[1];\n\n\t\t\tvar node = chart.canvas;\n\t\t\tvar rect = node.getBoundingClientRect();\n\n\t\t\tvar evt = new MouseEvent('mousemove', {\n\t\t\t\tview: window,\n\t\t\t\tbubbles: true,\n\t\t\t\tcancelable: true,\n\t\t\t\tclientX: rect.left + point._model.x,\n\t\t\t\tclientY: 0\n\t\t\t});\n\n\t\t\t// Manually trigger rather than having an async test\n\t\t\tnode.dispatchEvent(evt);\n\n\t\t\t// Check and see if tooltip was displayed\n\t\t\tvar tooltip = chart.tooltip;\n\t\t\tvar globalDefaults = Chart.defaults.global;\n\n\t\t\texpect(tooltip._view).toEqual(jasmine.objectContaining({\n\t\t\t\t// Positioning\n\t\t\t\txPadding: 6,\n\t\t\t\tyPadding: 6,\n\n\t\t\t\t// Body\n\t\t\t\tbodyFontColor: '#fff',\n\t\t\t\t_bodyFontFamily: globalDefaults.defaultFontFamily,\n\t\t\t\t_bodyFontStyle: globalDefaults.defaultFontStyle,\n\t\t\t\t_bodyAlign: 'left',\n\t\t\t\tbodyFontSize: globalDefaults.defaultFontSize,\n\t\t\t\tbodySpacing: 2,\n\n\t\t\t\t// Title\n\t\t\t\ttitleFontColor: '#fff',\n\t\t\t\t_titleFontFamily: globalDefaults.defaultFontFamily,\n\t\t\t\t_titleFontStyle: 'bold',\n\t\t\t\ttitleFontSize: globalDefaults.defaultFontSize,\n\t\t\t\t_titleAlign: 'left',\n\t\t\t\ttitleSpacing: 2,\n\t\t\t\ttitleMarginBottom: 6,\n\n\t\t\t\t// Footer\n\t\t\t\tfooterFontColor: '#fff',\n\t\t\t\t_footerFontFamily: globalDefaults.defaultFontFamily,\n\t\t\t\t_footerFontStyle: 'bold',\n\t\t\t\tfooterFontSize: globalDefaults.defaultFontSize,\n\t\t\t\t_footerAlign: 'left',\n\t\t\t\tfooterSpacing: 2,\n\t\t\t\tfooterMarginTop: 6,\n\n\t\t\t\t// Appearance\n\t\t\t\tcaretSize: 5,\n\t\t\t\tcornerRadius: 6,\n\t\t\t\tbackgroundColor: 'rgba(0,0,0,0.8)',\n\t\t\t\topacity: 0,\n\t\t\t\tlegendColorBackground: '#fff',\n\t\t\t\tdisplayColors: true,\n\t\t\t}));\n\t\t});\n\t});\n\n\tit('Should display in single mode', function() {\n\t\tvar chart = window.acquireChart({\n\t\t\ttype: 'line',\n\t\t\tdata: {\n\t\t\t\tdatasets: [{\n\t\t\t\t\tlabel: 'Dataset 1',\n\t\t\t\t\tdata: [10, 20, 30],\n\t\t\t\t\tpointHoverBorderColor: 'rgb(255, 0, 0)',\n\t\t\t\t\tpointHoverBackgroundColor: 'rgb(0, 255, 0)'\n\t\t\t\t}, {\n\t\t\t\t\tlabel: 'Dataset 2',\n\t\t\t\t\tdata: [40, 40, 40],\n\t\t\t\t\tpointHoverBorderColor: 'rgb(0, 0, 255)',\n\t\t\t\t\tpointHoverBackgroundColor: 'rgb(0, 255, 255)'\n\t\t\t\t}],\n\t\t\t\tlabels: ['Point 1', 'Point 2', 'Point 3']\n\t\t\t},\n\t\t\toptions: {\n\t\t\t\ttooltips: {\n\t\t\t\t\tmode: 'single'\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\n\t\t// Trigger an event over top of the\n\t\tvar meta = chart.getDatasetMeta(0);\n\t\tvar point = meta.data[1];\n\n\t\tvar node = chart.canvas;\n\t\tvar rect = node.getBoundingClientRect();\n\n\t\tvar evt = new MouseEvent('mousemove', {\n\t\t\tview: window,\n\t\t\tbubbles: true,\n\t\t\tcancelable: true,\n\t\t\tclientX: rect.left + point._model.x,\n\t\t\tclientY: rect.top + point._model.y\n\t\t});\n\n\t\t// Manually trigger rather than having an async test\n\t\tnode.dispatchEvent(evt);\n\n\t\t// Check and see if tooltip was displayed\n\t\tvar tooltip = chart.tooltip;\n\t\tvar globalDefaults = Chart.defaults.global;\n\n\t\texpect(tooltip._view).toEqual(jasmine.objectContaining({\n\t\t\t// Positioning\n\t\t\txPadding: 6,\n\t\t\tyPadding: 6,\n\t\t\txAlign: 'left',\n\t\t\tyAlign: 'center',\n\n\t\t\t// Body\n\t\t\tbodyFontColor: '#fff',\n\t\t\t_bodyFontFamily: globalDefaults.defaultFontFamily,\n\t\t\t_bodyFontStyle: globalDefaults.defaultFontStyle,\n\t\t\t_bodyAlign: 'left',\n\t\t\tbodyFontSize: globalDefaults.defaultFontSize,\n\t\t\tbodySpacing: 2,\n\n\t\t\t// Title\n\t\t\ttitleFontColor: '#fff',\n\t\t\t_titleFontFamily: globalDefaults.defaultFontFamily,\n\t\t\t_titleFontStyle: 'bold',\n\t\t\ttitleFontSize: globalDefaults.defaultFontSize,\n\t\t\t_titleAlign: 'left',\n\t\t\ttitleSpacing: 2,\n\t\t\ttitleMarginBottom: 6,\n\n\t\t\t// Footer\n\t\t\tfooterFontColor: '#fff',\n\t\t\t_footerFontFamily: globalDefaults.defaultFontFamily,\n\t\t\t_footerFontStyle: 'bold',\n\t\t\tfooterFontSize: globalDefaults.defaultFontSize,\n\t\t\t_footerAlign: 'left',\n\t\t\tfooterSpacing: 2,\n\t\t\tfooterMarginTop: 6,\n\n\t\t\t// Appearance\n\t\t\tcaretSize: 5,\n\t\t\tcornerRadius: 6,\n\t\t\tbackgroundColor: 'rgba(0,0,0,0.8)',\n\t\t\topacity: 1,\n\t\t\tlegendColorBackground: '#fff',\n\t\t\tdisplayColors: true,\n\n\t\t\t// Text\n\t\t\ttitle: ['Point 2'],\n\t\t\tbeforeBody: [],\n\t\t\tbody: [{\n\t\t\t\tbefore: [],\n\t\t\t\tlines: ['Dataset 1: 20'],\n\t\t\t\tafter: []\n\t\t\t}],\n\t\t\tafterBody: [],\n\t\t\tfooter: [],\n\t\t\tcaretPadding: 2,\n\t\t\tlabelColors: [{\n\t\t\t\tborderColor: 'rgb(255, 0, 0)',\n\t\t\t\tbackgroundColor: 'rgb(0, 255, 0)'\n\t\t\t}]\n\t\t}));\n\n\t\texpect(tooltip._view.x).toBeCloseToPixel(263);\n\t\texpect(tooltip._view.y).toBeCloseToPixel(312);\n\t});\n\n\tit('Should display information from user callbacks', function() {\n\t\tvar chart = window.acquireChart({\n\t\t\ttype: 'line',\n\t\t\tdata: {\n\t\t\t\tdatasets: [{\n\t\t\t\t\tlabel: 'Dataset 1',\n\t\t\t\t\tdata: [10, 20, 30],\n\t\t\t\t\tpointHoverBorderColor: 'rgb(255, 0, 0)',\n\t\t\t\t\tpointHoverBackgroundColor: 'rgb(0, 255, 0)'\n\t\t\t\t}, {\n\t\t\t\t\tlabel: 'Dataset 2',\n\t\t\t\t\tdata: [40, 40, 40],\n\t\t\t\t\tpointHoverBorderColor: 'rgb(0, 0, 255)',\n\t\t\t\t\tpointHoverBackgroundColor: 'rgb(0, 255, 255)'\n\t\t\t\t}],\n\t\t\t\tlabels: ['Point 1', 'Point 2', 'Point 3']\n\t\t\t},\n\t\t\toptions: {\n\t\t\t\ttooltips: {\n\t\t\t\t\tmode: 'label',\n\t\t\t\t\tcallbacks: {\n\t\t\t\t\t\tbeforeTitle: function() {\n\t\t\t\t\t\t\treturn 'beforeTitle';\n\t\t\t\t\t\t},\n\t\t\t\t\t\ttitle: function() {\n\t\t\t\t\t\t\treturn 'title';\n\t\t\t\t\t\t},\n\t\t\t\t\t\tafterTitle: function() {\n\t\t\t\t\t\t\treturn 'afterTitle';\n\t\t\t\t\t\t},\n\t\t\t\t\t\tbeforeBody: function() {\n\t\t\t\t\t\t\treturn 'beforeBody';\n\t\t\t\t\t\t},\n\t\t\t\t\t\tbeforeLabel: function() {\n\t\t\t\t\t\t\treturn 'beforeLabel';\n\t\t\t\t\t\t},\n\t\t\t\t\t\tlabel: function() {\n\t\t\t\t\t\t\treturn 'label';\n\t\t\t\t\t\t},\n\t\t\t\t\t\tafterLabel: function() {\n\t\t\t\t\t\t\treturn 'afterLabel';\n\t\t\t\t\t\t},\n\t\t\t\t\t\tafterBody: function() {\n\t\t\t\t\t\t\treturn 'afterBody';\n\t\t\t\t\t\t},\n\t\t\t\t\t\tbeforeFooter: function() {\n\t\t\t\t\t\t\treturn 'beforeFooter';\n\t\t\t\t\t\t},\n\t\t\t\t\t\tfooter: function() {\n\t\t\t\t\t\t\treturn 'footer';\n\t\t\t\t\t\t},\n\t\t\t\t\t\tafterFooter: function() {\n\t\t\t\t\t\t\treturn 'afterFooter';\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\n\t\t// Trigger an event over top of the\n\t\tvar meta = chart.getDatasetMeta(0);\n\t\tvar point = meta.data[1];\n\n\t\tvar node = chart.canvas;\n\t\tvar rect = node.getBoundingClientRect();\n\n\t\tvar evt = new MouseEvent('mousemove', {\n\t\t\tview: window,\n\t\t\tbubbles: true,\n\t\t\tcancelable: true,\n\t\t\tclientX: rect.left + point._model.x,\n\t\t\tclientY: rect.top + point._model.y\n\t\t});\n\n\t\t// Manually trigger rather than having an async test\n\t\tnode.dispatchEvent(evt);\n\n\t\t// Check and see if tooltip was displayed\n\t\tvar tooltip = chart.tooltip;\n\t\tvar globalDefaults = Chart.defaults.global;\n\n\t\texpect(tooltip._view).toEqual(jasmine.objectContaining({\n\t\t\t// Positioning\n\t\t\txPadding: 6,\n\t\t\tyPadding: 6,\n\t\t\txAlign: 'center',\n\t\t\tyAlign: 'top',\n\n\t\t\t// Body\n\t\t\tbodyFontColor: '#fff',\n\t\t\t_bodyFontFamily: globalDefaults.defaultFontFamily,\n\t\t\t_bodyFontStyle: globalDefaults.defaultFontStyle,\n\t\t\t_bodyAlign: 'left',\n\t\t\tbodyFontSize: globalDefaults.defaultFontSize,\n\t\t\tbodySpacing: 2,\n\n\t\t\t// Title\n\t\t\ttitleFontColor: '#fff',\n\t\t\t_titleFontFamily: globalDefaults.defaultFontFamily,\n\t\t\t_titleFontStyle: 'bold',\n\t\t\ttitleFontSize: globalDefaults.defaultFontSize,\n\t\t\t_titleAlign: 'left',\n\t\t\ttitleSpacing: 2,\n\t\t\ttitleMarginBottom: 6,\n\n\t\t\t// Footer\n\t\t\tfooterFontColor: '#fff',\n\t\t\t_footerFontFamily: globalDefaults.defaultFontFamily,\n\t\t\t_footerFontStyle: 'bold',\n\t\t\tfooterFontSize: globalDefaults.defaultFontSize,\n\t\t\t_footerAlign: 'left',\n\t\t\tfooterSpacing: 2,\n\t\t\tfooterMarginTop: 6,\n\n\t\t\t// Appearance\n\t\t\tcaretSize: 5,\n\t\t\tcornerRadius: 6,\n\t\t\tbackgroundColor: 'rgba(0,0,0,0.8)',\n\t\t\topacity: 1,\n\t\t\tlegendColorBackground: '#fff',\n\n\t\t\t// Text\n\t\t\ttitle: ['beforeTitle', 'title', 'afterTitle'],\n\t\t\tbeforeBody: ['beforeBody'],\n\t\t\tbody: [{\n\t\t\t\tbefore: ['beforeLabel'],\n\t\t\t\tlines: ['label'],\n\t\t\t\tafter: ['afterLabel']\n\t\t\t}, {\n\t\t\t\tbefore: ['beforeLabel'],\n\t\t\t\tlines: ['label'],\n\t\t\t\tafter: ['afterLabel']\n\t\t\t}],\n\t\t\tafterBody: ['afterBody'],\n\t\t\tfooter: ['beforeFooter', 'footer', 'afterFooter'],\n\t\t\tcaretPadding: 2,\n\t\t\tlabelColors: [{\n\t\t\t\tborderColor: 'rgb(255, 0, 0)',\n\t\t\t\tbackgroundColor: 'rgb(0, 255, 0)'\n\t\t\t}, {\n\t\t\t\tborderColor: 'rgb(0, 0, 255)',\n\t\t\t\tbackgroundColor: 'rgb(0, 255, 255)'\n\t\t\t}]\n\t\t}));\n\n\t\texpect(tooltip._view.x).toBeCloseToPixel(211);\n\t\texpect(tooltip._view.y).toBeCloseToPixel(190);\n\t});\n\n\tit('Should allow sorting items', function() {\n\t\tvar chart = window.acquireChart({\n\t\t\ttype: 'line',\n\t\t\tdata: {\n\t\t\t\tdatasets: [{\n\t\t\t\t\tlabel: 'Dataset 1',\n\t\t\t\t\tdata: [10, 20, 30],\n\t\t\t\t\tpointHoverBorderColor: 'rgb(255, 0, 0)',\n\t\t\t\t\tpointHoverBackgroundColor: 'rgb(0, 255, 0)'\n\t\t\t\t}, {\n\t\t\t\t\tlabel: 'Dataset 2',\n\t\t\t\t\tdata: [40, 40, 40],\n\t\t\t\t\tpointHoverBorderColor: 'rgb(0, 0, 255)',\n\t\t\t\t\tpointHoverBackgroundColor: 'rgb(0, 255, 255)'\n\t\t\t\t}],\n\t\t\t\tlabels: ['Point 1', 'Point 2', 'Point 3']\n\t\t\t},\n\t\t\toptions: {\n\t\t\t\ttooltips: {\n\t\t\t\t\tmode: 'label',\n\t\t\t\t\titemSort: function(a, b) {\n\t\t\t\t\t\treturn a.datasetIndex > b.datasetIndex ? -1 : 1;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\n\t\t// Trigger an event over top of the\n\t\tvar meta0 = chart.getDatasetMeta(0);\n\t\tvar point0 = meta0.data[1];\n\n\t\tvar node = chart.canvas;\n\t\tvar rect = node.getBoundingClientRect();\n\n\t\tvar evt = new MouseEvent('mousemove', {\n\t\t\tview: window,\n\t\t\tbubbles: true,\n\t\t\tcancelable: true,\n\t\t\tclientX: rect.left + point0._model.x,\n\t\t\tclientY: rect.top + point0._model.y\n\t\t});\n\n\t\t// Manually trigger rather than having an async test\n\t\tnode.dispatchEvent(evt);\n\n\t\t// Check and see if tooltip was displayed\n\t\tvar tooltip = chart.tooltip;\n\n\t\texpect(tooltip._view).toEqual(jasmine.objectContaining({\n\t\t\t// Positioning\n\t\t\txAlign: 'left',\n\t\t\tyAlign: 'center',\n\n\t\t\t// Text\n\t\t\ttitle: ['Point 2'],\n\t\t\tbeforeBody: [],\n\t\t\tbody: [{\n\t\t\t\tbefore: [],\n\t\t\t\tlines: ['Dataset 2: 40'],\n\t\t\t\tafter: []\n\t\t\t}, {\n\t\t\t\tbefore: [],\n\t\t\t\tlines: ['Dataset 1: 20'],\n\t\t\t\tafter: []\n\t\t\t}],\n\t\t\tafterBody: [],\n\t\t\tfooter: [],\n\t\t\tlabelColors: [{\n\t\t\t\tborderColor: 'rgb(0, 0, 255)',\n\t\t\t\tbackgroundColor: 'rgb(0, 255, 255)'\n\t\t\t}, {\n\t\t\t\tborderColor: 'rgb(255, 0, 0)',\n\t\t\t\tbackgroundColor: 'rgb(0, 255, 0)'\n\t\t\t}]\n\t\t}));\n\n\t\texpect(tooltip._view.x).toBeCloseToPixel(263);\n\t\texpect(tooltip._view.y).toBeCloseToPixel(155);\n\t});\n\n\tit('should filter items from the tooltip using the callback', function() {\n\t\tvar chart = window.acquireChart({\n\t\t\ttype: 'line',\n\t\t\tdata: {\n\t\t\t\tdatasets: [{\n\t\t\t\t\tlabel: 'Dataset 1',\n\t\t\t\t\tdata: [10, 20, 30],\n\t\t\t\t\tpointHoverBorderColor: 'rgb(255, 0, 0)',\n\t\t\t\t\tpointHoverBackgroundColor: 'rgb(0, 255, 0)',\n\t\t\t\t\ttooltipHidden: true\n\t\t\t\t}, {\n\t\t\t\t\tlabel: 'Dataset 2',\n\t\t\t\t\tdata: [40, 40, 40],\n\t\t\t\t\tpointHoverBorderColor: 'rgb(0, 0, 255)',\n\t\t\t\t\tpointHoverBackgroundColor: 'rgb(0, 255, 255)'\n\t\t\t\t}],\n\t\t\t\tlabels: ['Point 1', 'Point 2', 'Point 3']\n\t\t\t},\n\t\t\toptions: {\n\t\t\t\ttooltips: {\n\t\t\t\t\tmode: 'label',\n\t\t\t\t\tfilter: function(tooltipItem, data) {\n\t\t\t\t\t\t// For testing purposes remove the first dataset that has a tooltipHidden property\n\t\t\t\t\t\treturn !data.datasets[tooltipItem.datasetIndex].tooltipHidden;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\n\t\t// Trigger an event over top of the\n\t\tvar meta0 = chart.getDatasetMeta(0);\n\t\tvar point0 = meta0.data[1];\n\n\t\tvar node = chart.canvas;\n\t\tvar rect = node.getBoundingClientRect();\n\n\t\tvar evt = new MouseEvent('mousemove', {\n\t\t\tview: window,\n\t\t\tbubbles: true,\n\t\t\tcancelable: true,\n\t\t\tclientX: rect.left + point0._model.x,\n\t\t\tclientY: rect.top + point0._model.y\n\t\t});\n\n\t\t// Manually trigger rather than having an async test\n\t\tnode.dispatchEvent(evt);\n\n\t\t// Check and see if tooltip was displayed\n\t\tvar tooltip = chart.tooltip;\n\n\t\texpect(tooltip._view).toEqual(jasmine.objectContaining({\n\t\t\t// Positioning\n\t\t\txAlign: 'left',\n\t\t\tyAlign: 'center',\n\n\t\t\t// Text\n\t\t\ttitle: ['Point 2'],\n\t\t\tbeforeBody: [],\n\t\t\tbody: [{\n\t\t\t\tbefore: [],\n\t\t\t\tlines: ['Dataset 2: 40'],\n\t\t\t\tafter: []\n\t\t\t}],\n\t\t\tafterBody: [],\n\t\t\tfooter: [],\n\t\t\tlabelColors: [{\n\t\t\t\tborderColor: 'rgb(0, 0, 255)',\n\t\t\t\tbackgroundColor: 'rgb(0, 255, 255)'\n\t\t\t}]\n\t\t}));\n\t});\n\n\tit('should set the caretPadding based on a config setting', function() {\n\t\tvar chart = window.acquireChart({\n\t\t\ttype: 'line',\n\t\t\tdata: {\n\t\t\t\tdatasets: [{\n\t\t\t\t\tlabel: 'Dataset 1',\n\t\t\t\t\tdata: [10, 20, 30],\n\t\t\t\t\tpointHoverBorderColor: 'rgb(255, 0, 0)',\n\t\t\t\t\tpointHoverBackgroundColor: 'rgb(0, 255, 0)',\n\t\t\t\t\ttooltipHidden: true\n\t\t\t\t}, {\n\t\t\t\t\tlabel: 'Dataset 2',\n\t\t\t\t\tdata: [40, 40, 40],\n\t\t\t\t\tpointHoverBorderColor: 'rgb(0, 0, 255)',\n\t\t\t\t\tpointHoverBackgroundColor: 'rgb(0, 255, 255)'\n\t\t\t\t}],\n\t\t\t\tlabels: ['Point 1', 'Point 2', 'Point 3']\n\t\t\t},\n\t\t\toptions: {\n\t\t\t\ttooltips: {\n\t\t\t\t\tcaretPadding: 10\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\n\t\t// Trigger an event over top of the\n\t\tvar meta0 = chart.getDatasetMeta(0);\n\t\tvar point0 = meta0.data[1];\n\n\t\tvar node = chart.canvas;\n\t\tvar rect = node.getBoundingClientRect();\n\n\t\tvar evt = new MouseEvent('mousemove', {\n\t\t\tview: window,\n\t\t\tbubbles: true,\n\t\t\tcancelable: true,\n\t\t\tclientX: rect.left + point0._model.x,\n\t\t\tclientY: rect.top + point0._model.y\n\t\t});\n\n\t\t// Manually trigger rather than having an async test\n\t\tnode.dispatchEvent(evt);\n\n\t\t// Check and see if tooltip was displayed\n\t\tvar tooltip = chart.tooltip;\n\n\t\texpect(tooltip._model).toEqual(jasmine.objectContaining({\n\t\t\t// Positioning\n\t\t\tcaretPadding: 10,\n\t\t}));\n\t});\n\n\tit('Should have dataPoints', function() {\n\t\tvar chart = window.acquireChart({\n\t\t\ttype: 'line',\n\t\t\tdata: {\n\t\t\t\tdatasets: [{\n\t\t\t\t\tlabel: 'Dataset 1',\n\t\t\t\t\tdata: [10, 20, 30],\n\t\t\t\t\tpointHoverBorderColor: 'rgb(255, 0, 0)',\n\t\t\t\t\tpointHoverBackgroundColor: 'rgb(0, 255, 0)'\n\t\t\t\t}, {\n\t\t\t\t\tlabel: 'Dataset 2',\n\t\t\t\t\tdata: [40, 40, 40],\n\t\t\t\t\tpointHoverBorderColor: 'rgb(0, 0, 255)',\n\t\t\t\t\tpointHoverBackgroundColor: 'rgb(0, 255, 255)'\n\t\t\t\t}],\n\t\t\t\tlabels: ['Point 1', 'Point 2', 'Point 3']\n\t\t\t},\n\t\t\toptions: {\n\t\t\t\ttooltips: {\n\t\t\t\t\tmode: 'single'\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\n\t\t// Trigger an event over top of the\n\t\tvar pointIndex = 1;\n\t\tvar datasetIndex = 0;\n\t\tvar meta = chart.getDatasetMeta(datasetIndex);\n\t\tvar point = meta.data[pointIndex];\n\t\tvar node = chart.canvas;\n\t\tvar rect = node.getBoundingClientRect();\n\t\tvar evt = new MouseEvent('mousemove', {\n\t\t\tview: window,\n\t\t\tbubbles: true,\n\t\t\tcancelable: true,\n\t\t\tclientX: rect.left + point._model.x,\n\t\t\tclientY: rect.top + point._model.y\n\t\t});\n\n\t\t// Manually trigger rather than having an async test\n\t\tnode.dispatchEvent(evt);\n\n\t\t// Check and see if tooltip was displayed\n\t\tvar tooltip = chart.tooltip;\n\n\t\texpect(tooltip._view instanceof Object).toBe(true);\n\t\texpect(tooltip._view.dataPoints instanceof Array).toBe(true);\n\t\texpect(tooltip._view.dataPoints.length).toEqual(1);\n\t\texpect(tooltip._view.dataPoints[0].index).toEqual(pointIndex);\n\t\texpect(tooltip._view.dataPoints[0].datasetIndex).toEqual(datasetIndex);\n\t\texpect(tooltip._view.dataPoints[0].xLabel).toEqual(\n\t\t\tchart.data.labels[pointIndex]\n\t\t);\n\t\texpect(tooltip._view.dataPoints[0].yLabel).toEqual(\n\t\t\tchart.data.datasets[datasetIndex].data[pointIndex]\n\t\t);\n\t\texpect(tooltip._view.dataPoints[0].x).toBeCloseToPixel(point._model.x);\n\t\texpect(tooltip._view.dataPoints[0].y).toBeCloseToPixel(point._model.y);\n\t});\n\n\tit('Should not update if active element has not changed', function() {\n\t\tvar chart = window.acquireChart({\n\t\t\ttype: 'bar',\n\t\t\tdata: {\n\t\t\t\tdatasets: [{\n\t\t\t\t\tlabel: 'Dataset 1',\n\t\t\t\t\tdata: [10, 20, 30],\n\t\t\t\t\tpointHoverBorderColor: 'rgb(255, 0, 0)',\n\t\t\t\t\tpointHoverBackgroundColor: 'rgb(0, 255, 0)'\n\t\t\t\t}, {\n\t\t\t\t\tlabel: 'Dataset 2',\n\t\t\t\t\tdata: [40, 40, 40],\n\t\t\t\t\tpointHoverBorderColor: 'rgb(0, 0, 255)',\n\t\t\t\t\tpointHoverBackgroundColor: 'rgb(0, 255, 255)'\n\t\t\t\t}],\n\t\t\t\tlabels: ['Point 1', 'Point 2', 'Point 3']\n\t\t\t},\n\t\t\toptions: {\n\t\t\t\ttooltips: {\n\t\t\t\t\tmode: 'single',\n\t\t\t\t\tcallbacks: {\n\t\t\t\t\t\ttitle: function() {\n\t\t\t\t\t\t\treturn 'registering callback...';\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\n\t\t// Trigger an event over top of the\n\t\tvar meta = chart.getDatasetMeta(0);\n\t\tvar firstPoint = meta.data[1];\n\n\t\tvar node = chart.chart.canvas;\n\t\tvar rect = node.getBoundingClientRect();\n\n\t\tvar firstEvent = new MouseEvent('mousemove', {\n\t\t\tview: window,\n\t\t\tbubbles: false,\n\t\t\tcancelable: true,\n\t\t\tclientX: rect.left + firstPoint._model.x,\n\t\t\tclientY: rect.top + firstPoint._model.y\n\t\t});\n\n\t\tvar tooltip = chart.tooltip;\n\t\tspyOn(tooltip, 'update');\n\n\t\t/* Manually trigger rather than having an async test */\n\n\t\t// First dispatch change event, should update tooltip\n\t\tnode.dispatchEvent(firstEvent);\n\t\texpect(tooltip.update).toHaveBeenCalledWith(true);\n\n\t\t// Reset calls\n\t\ttooltip.update.calls.reset();\n\n\t\t// Second dispatch change event (same event), should not update tooltip\n\t\tnode.dispatchEvent(firstEvent);\n\t\texpect(tooltip.update).not.toHaveBeenCalled();\n\t});\n});\n"
  },
  {
    "path": "app_backend/static/plugin/Chart.js-2.6.0/test/specs/element.arc.tests.js",
    "content": "// Test the rectangle element\n\ndescribe('Arc element tests', function() {\n\tit ('Should be constructed', function() {\n\t\tvar arc = new Chart.elements.Arc({\n\t\t\t_datasetIndex: 2,\n\t\t\t_index: 1\n\t\t});\n\n\t\texpect(arc).not.toBe(undefined);\n\t\texpect(arc._datasetIndex).toBe(2);\n\t\texpect(arc._index).toBe(1);\n\t});\n\n\tit ('should determine if in range', function() {\n\t\tvar arc = new Chart.elements.Arc({\n\t\t\t_datasetIndex: 2,\n\t\t\t_index: 1\n\t\t});\n\n\t\t// Make sure we can run these before the view is added\n\t\texpect(arc.inRange(2, 2)).toBe(false);\n\t\texpect(arc.inLabelRange(2)).toBe(false);\n\n\t\t// Mock out the view as if the controller put it there\n\t\tarc._view = {\n\t\t\tstartAngle: 0,\n\t\t\tendAngle: Math.PI / 2,\n\t\t\tx: 0,\n\t\t\ty: 0,\n\t\t\tinnerRadius: 5,\n\t\t\touterRadius: 10,\n\t\t};\n\n\t\texpect(arc.inRange(2, 2)).toBe(false);\n\t\texpect(arc.inRange(7, 0)).toBe(true);\n\t\texpect(arc.inRange(0, 11)).toBe(false);\n\t\texpect(arc.inRange(Math.sqrt(32), Math.sqrt(32))).toBe(true);\n\t\texpect(arc.inRange(-1.0 * Math.sqrt(7), Math.sqrt(7))).toBe(false);\n\t});\n\n\tit ('should get the tooltip position', function() {\n\t\tvar arc = new Chart.elements.Arc({\n\t\t\t_datasetIndex: 2,\n\t\t\t_index: 1\n\t\t});\n\n\t\t// Mock out the view as if the controller put it there\n\t\tarc._view = {\n\t\t\tstartAngle: 0,\n\t\t\tendAngle: Math.PI / 2,\n\t\t\tx: 0,\n\t\t\ty: 0,\n\t\t\tinnerRadius: 0,\n\t\t\touterRadius: Math.sqrt(2),\n\t\t};\n\n\t\tvar pos = arc.tooltipPosition();\n\t\texpect(pos.x).toBeCloseTo(0.5);\n\t\texpect(pos.y).toBeCloseTo(0.5);\n\t});\n\n\tit ('should get the area', function() {\n\t\tvar arc = new Chart.elements.Arc({\n\t\t\t_datasetIndex: 2,\n\t\t\t_index: 1\n\t\t});\n\n\t\t// Mock out the view as if the controller put it there\n\t\tarc._view = {\n\t\t\tstartAngle: 0,\n\t\t\tendAngle: Math.PI / 2,\n\t\t\tx: 0,\n\t\t\ty: 0,\n\t\t\tinnerRadius: 0,\n\t\t\touterRadius: Math.sqrt(2),\n\t\t};\n\n\t\texpect(arc.getArea()).toBeCloseTo(0.5 * Math.PI, 6);\n\t});\n\n\tit ('should get the center', function() {\n\t\tvar arc = new Chart.elements.Arc({\n\t\t\t_datasetIndex: 2,\n\t\t\t_index: 1\n\t\t});\n\n\t\t// Mock out the view as if the controller put it there\n\t\tarc._view = {\n\t\t\tstartAngle: 0,\n\t\t\tendAngle: Math.PI / 2,\n\t\t\tx: 0,\n\t\t\ty: 0,\n\t\t\tinnerRadius: 0,\n\t\t\touterRadius: Math.sqrt(2),\n\t\t};\n\n\t\tvar center = arc.getCenterPoint();\n\t\texpect(center.x).toBeCloseTo(0.5, 6);\n\t\texpect(center.y).toBeCloseTo(0.5, 6);\n\t});\n\n\tit ('should draw correctly with no border', function() {\n\t\tvar mockContext = window.createMockContext();\n\t\tvar arc = new Chart.elements.Arc({\n\t\t\t_datasetIndex: 2,\n\t\t\t_index: 1,\n\t\t\t_chart: {\n\t\t\t\tctx: mockContext,\n\t\t\t}\n\t\t});\n\n\t\t// Mock out the view as if the controller put it there\n\t\tarc._view = {\n\t\t\tstartAngle: 0,\n\t\t\tendAngle: Math.PI / 2,\n\t\t\tx: 10,\n\t\t\ty: 5,\n\t\t\tinnerRadius: 1,\n\t\t\touterRadius: 3,\n\n\t\t\tbackgroundColor: 'rgb(0, 0, 255)',\n\t\t\tborderColor: 'rgb(255, 0, 0)',\n\t\t};\n\n\t\tarc.draw();\n\n\t\texpect(mockContext.getCalls()).toEqual([{\n\t\t\tname: 'beginPath',\n\t\t\targs: []\n\t\t}, {\n\t\t\tname: 'arc',\n\t\t\targs: [10, 5, 3, 0, Math.PI / 2]\n\t\t}, {\n\t\t\tname: 'arc',\n\t\t\targs: [10, 5, 1, Math.PI / 2, 0, true]\n\t\t}, {\n\t\t\tname: 'closePath',\n\t\t\targs: []\n\t\t}, {\n\t\t\tname: 'setStrokeStyle',\n\t\t\targs: ['rgb(255, 0, 0)']\n\t\t}, {\n\t\t\tname: 'setLineWidth',\n\t\t\targs: [undefined]\n\t\t}, {\n\t\t\tname: 'setFillStyle',\n\t\t\targs: ['rgb(0, 0, 255)']\n\t\t}, {\n\t\t\tname: 'fill',\n\t\t\targs: []\n\t\t}, {\n\t\t\tname: 'setLineJoin',\n\t\t\targs: ['bevel']\n\t\t}]);\n\t});\n\n\tit ('should draw correctly with a border', function() {\n\t\tvar mockContext = window.createMockContext();\n\t\tvar arc = new Chart.elements.Arc({\n\t\t\t_datasetIndex: 2,\n\t\t\t_index: 1,\n\t\t\t_chart: {\n\t\t\t\tctx: mockContext,\n\t\t\t}\n\t\t});\n\n\t\t// Mock out the view as if the controller put it there\n\t\tarc._view = {\n\t\t\tstartAngle: 0,\n\t\t\tendAngle: Math.PI / 2,\n\t\t\tx: 10,\n\t\t\ty: 5,\n\t\t\tinnerRadius: 1,\n\t\t\touterRadius: 3,\n\n\t\t\tbackgroundColor: 'rgb(0, 0, 255)',\n\t\t\tborderColor: 'rgb(255, 0, 0)',\n\t\t\tborderWidth: 5\n\t\t};\n\n\t\tarc.draw();\n\n\t\texpect(mockContext.getCalls()).toEqual([{\n\t\t\tname: 'beginPath',\n\t\t\targs: []\n\t\t}, {\n\t\t\tname: 'arc',\n\t\t\targs: [10, 5, 3, 0, Math.PI / 2]\n\t\t}, {\n\t\t\tname: 'arc',\n\t\t\targs: [10, 5, 1, Math.PI / 2, 0, true]\n\t\t}, {\n\t\t\tname: 'closePath',\n\t\t\targs: []\n\t\t}, {\n\t\t\tname: 'setStrokeStyle',\n\t\t\targs: ['rgb(255, 0, 0)']\n\t\t}, {\n\t\t\tname: 'setLineWidth',\n\t\t\targs: [5]\n\t\t}, {\n\t\t\tname: 'setFillStyle',\n\t\t\targs: ['rgb(0, 0, 255)']\n\t\t}, {\n\t\t\tname: 'fill',\n\t\t\targs: []\n\t\t}, {\n\t\t\tname: 'setLineJoin',\n\t\t\targs: ['bevel']\n\t\t}, {\n\t\t\tname: 'stroke',\n\t\t\targs: []\n\t\t}]);\n\t});\n});\n"
  },
  {
    "path": "app_backend/static/plugin/Chart.js-2.6.0/test/specs/element.line.tests.js",
    "content": "// Tests for the line element\ndescribe('Chart.elements.Line', function() {\n\tit('should be constructed', function() {\n\t\tvar line = new Chart.elements.Line({\n\t\t\t_datasetindex: 2,\n\t\t\t_points: [1, 2, 3, 4]\n\t\t});\n\n\t\texpect(line).not.toBe(undefined);\n\t\texpect(line._datasetindex).toBe(2);\n\t\texpect(line._points).toEqual([1, 2, 3, 4]);\n\t});\n\n\tit('should draw with default settings', function() {\n\t\tvar mockContext = window.createMockContext();\n\n\t\t// Create our points\n\t\tvar points = [];\n\t\tpoints.push(new Chart.elements.Point({\n\t\t\t_datasetindex: 2,\n\t\t\t_index: 0,\n\t\t\t_view: {\n\t\t\t\tx: 0,\n\t\t\t\ty: 10,\n\t\t\t\tcontrolPointNextX: 0,\n\t\t\t\tcontrolPointNextY: 10\n\t\t\t}\n\t\t}));\n\t\tpoints.push(new Chart.elements.Point({\n\t\t\t_datasetindex: 2,\n\t\t\t_index: 1,\n\t\t\t_view: {\n\t\t\t\tx: 5,\n\t\t\t\ty: 0,\n\t\t\t\tcontrolPointPreviousX: 5,\n\t\t\t\tcontrolPointPreviousY: 0,\n\t\t\t\tcontrolPointNextX: 5,\n\t\t\t\tcontrolPointNextY: 0\n\t\t\t}\n\t\t}));\n\t\tpoints.push(new Chart.elements.Point({\n\t\t\t_datasetindex: 2,\n\t\t\t_index: 2,\n\t\t\t_view: {\n\t\t\t\tx: 15,\n\t\t\t\ty: -10,\n\t\t\t\tcontrolPointPreviousX: 15,\n\t\t\t\tcontrolPointPreviousY: -10,\n\t\t\t\tcontrolPointNextX: 15,\n\t\t\t\tcontrolPointNextY: -10\n\t\t\t}\n\t\t}));\n\t\tpoints.push(new Chart.elements.Point({\n\t\t\t_datasetindex: 2,\n\t\t\t_index: 3,\n\t\t\t_view: {\n\t\t\t\tx: 19,\n\t\t\t\ty: -5,\n\t\t\t\tcontrolPointPreviousX: 19,\n\t\t\t\tcontrolPointPreviousY: -5,\n\t\t\t\tcontrolPointNextX: 19,\n\t\t\t\tcontrolPointNextY: -5\n\t\t\t}\n\t\t}));\n\n\t\tvar line = new Chart.elements.Line({\n\t\t\t_datasetindex: 2,\n\t\t\t_chart: {\n\t\t\t\tctx: mockContext,\n\t\t\t},\n\t\t\t_children: points,\n\t\t\t// Need to provide some settings\n\t\t\t_view: {\n\t\t\t\tfill: false, // don't want to fill\n\t\t\t\ttension: 0, // no bezier curve for now\n\t\t\t}\n\t\t});\n\n\t\tline.draw();\n\n\t\texpect(mockContext.getCalls()).toEqual([{\n\t\t\tname: 'save',\n\t\t\targs: [],\n\t\t}, {\n\t\t\tname: 'setLineCap',\n\t\t\targs: ['butt']\n\t\t}, {\n\t\t\tname: 'setLineDash',\n\t\t\targs: [\n\t\t\t\t[]\n\t\t\t]\n\t\t}, {\n\t\t\tname: 'setLineDashOffset',\n\t\t\targs: [0.0]\n\t\t}, {\n\t\t\tname: 'setLineJoin',\n\t\t\targs: ['miter']\n\t\t}, {\n\t\t\tname: 'setLineWidth',\n\t\t\targs: [3]\n\t\t}, {\n\t\t\tname: 'setStrokeStyle',\n\t\t\targs: ['rgba(0,0,0,0.1)']\n\t\t}, {\n\t\t\tname: 'beginPath',\n\t\t\targs: []\n\t\t}, {\n\t\t\tname: 'moveTo',\n\t\t\targs: [0, 10]\n\t\t}, {\n\t\t\tname: 'lineTo',\n\t\t\targs: [5, 0]\n\t\t}, {\n\t\t\tname: 'lineTo',\n\t\t\targs: [15, -10]\n\t\t}, {\n\t\t\tname: 'lineTo',\n\t\t\targs: [19, -5]\n\t\t}, {\n\t\t\tname: 'stroke',\n\t\t\targs: [],\n\t\t}, {\n\t\t\tname: 'restore',\n\t\t\targs: []\n\t\t}]);\n\t});\n\n\tit('should draw with straight lines for a tension of 0', function() {\n\t\tvar mockContext = window.createMockContext();\n\n\t\t// Create our points\n\t\tvar points = [];\n\t\tpoints.push(new Chart.elements.Point({\n\t\t\t_datasetindex: 2,\n\t\t\t_index: 0,\n\t\t\t_view: {\n\t\t\t\tx: 0,\n\t\t\t\ty: 10,\n\t\t\t\tcontrolPointNextX: 0,\n\t\t\t\tcontrolPointNextY: 10,\n\t\t\t\ttension: 0\n\t\t\t}\n\t\t}));\n\t\tpoints.push(new Chart.elements.Point({\n\t\t\t_datasetindex: 2,\n\t\t\t_index: 1,\n\t\t\t_view: {\n\t\t\t\tx: 5,\n\t\t\t\ty: 0,\n\t\t\t\tcontrolPointPreviousX: 5,\n\t\t\t\tcontrolPointPreviousY: 0,\n\t\t\t\tcontrolPointNextX: 5,\n\t\t\t\tcontrolPointNextY: 0,\n\t\t\t\ttension: 0\n\t\t\t}\n\t\t}));\n\t\tpoints.push(new Chart.elements.Point({\n\t\t\t_datasetindex: 2,\n\t\t\t_index: 2,\n\t\t\t_view: {\n\t\t\t\tx: 15,\n\t\t\t\ty: -10,\n\t\t\t\tcontrolPointPreviousX: 15,\n\t\t\t\tcontrolPointPreviousY: -10,\n\t\t\t\tcontrolPointNextX: 15,\n\t\t\t\tcontrolPointNextY: -10,\n\t\t\t\ttension: 0\n\t\t\t}\n\t\t}));\n\t\tpoints.push(new Chart.elements.Point({\n\t\t\t_datasetindex: 2,\n\t\t\t_index: 3,\n\t\t\t_view: {\n\t\t\t\tx: 19,\n\t\t\t\ty: -5,\n\t\t\t\tcontrolPointPreviousX: 19,\n\t\t\t\tcontrolPointPreviousY: -5,\n\t\t\t\tcontrolPointNextX: 19,\n\t\t\t\tcontrolPointNextY: -5,\n\t\t\t\ttension: 0\n\t\t\t}\n\t\t}));\n\n\t\tvar line = new Chart.elements.Line({\n\t\t\t_datasetindex: 2,\n\t\t\t_chart: {\n\t\t\t\tctx: mockContext,\n\t\t\t},\n\t\t\t_children: points,\n\t\t\t// Need to provide some settings\n\t\t\t_view: {\n\t\t\t\tfill: false, // don't want to fill\n\t\t\t\ttension: 0, // no bezier curve for now\n\t\t\t}\n\t\t});\n\n\t\tline.draw();\n\n\t\texpect(mockContext.getCalls()).toEqual([{\n\t\t\tname: 'save',\n\t\t\targs: [],\n\t\t}, {\n\t\t\tname: 'setLineCap',\n\t\t\targs: ['butt']\n\t\t}, {\n\t\t\tname: 'setLineDash',\n\t\t\targs: [\n\t\t\t\t[]\n\t\t\t]\n\t\t}, {\n\t\t\tname: 'setLineDashOffset',\n\t\t\targs: [0.0]\n\t\t}, {\n\t\t\tname: 'setLineJoin',\n\t\t\targs: ['miter']\n\t\t}, {\n\t\t\tname: 'setLineWidth',\n\t\t\targs: [3]\n\t\t}, {\n\t\t\tname: 'setStrokeStyle',\n\t\t\targs: ['rgba(0,0,0,0.1)']\n\t\t}, {\n\t\t\tname: 'beginPath',\n\t\t\targs: []\n\t\t}, {\n\t\t\tname: 'moveTo',\n\t\t\targs: [0, 10]\n\t\t}, {\n\t\t\tname: 'lineTo',\n\t\t\targs: [5, 0]\n\t\t}, {\n\t\t\tname: 'lineTo',\n\t\t\targs: [15, -10]\n\t\t}, {\n\t\t\tname: 'lineTo',\n\t\t\targs: [19, -5]\n\t\t}, {\n\t\t\tname: 'stroke',\n\t\t\targs: [],\n\t\t}, {\n\t\t\tname: 'restore',\n\t\t\targs: []\n\t\t}]);\n\t});\n\n\tit('should draw stepped lines, with \"before\" interpolation', function() {\n\n\t\t// Both `true` and `'before'` should draw the same steppedLine\n\t\tvar beforeInterpolations = [true, 'before'];\n\n\t\tbeforeInterpolations.forEach(function(mode) {\n\t\t\tvar mockContext = window.createMockContext();\n\n\t\t\t// Create our points\n\t\t\tvar points = [];\n\t\t\tpoints.push(new Chart.elements.Point({\n\t\t\t\t_datasetindex: 2,\n\t\t\t\t_index: 0,\n\t\t\t\t_view: {\n\t\t\t\t\tx: 0,\n\t\t\t\t\ty: 10,\n\t\t\t\t\tcontrolPointNextX: 0,\n\t\t\t\t\tcontrolPointNextY: 10,\n\t\t\t\t\tsteppedLine: mode\n\t\t\t\t}\n\t\t\t}));\n\t\t\tpoints.push(new Chart.elements.Point({\n\t\t\t\t_datasetindex: 2,\n\t\t\t\t_index: 1,\n\t\t\t\t_view: {\n\t\t\t\t\tx: 5,\n\t\t\t\t\ty: 0,\n\t\t\t\t\tcontrolPointPreviousX: 5,\n\t\t\t\t\tcontrolPointPreviousY: 0,\n\t\t\t\t\tcontrolPointNextX: 5,\n\t\t\t\t\tcontrolPointNextY: 0,\n\t\t\t\t\tsteppedLine: mode\n\t\t\t\t}\n\t\t\t}));\n\t\t\tpoints.push(new Chart.elements.Point({\n\t\t\t\t_datasetindex: 2,\n\t\t\t\t_index: 2,\n\t\t\t\t_view: {\n\t\t\t\t\tx: 15,\n\t\t\t\t\ty: -10,\n\t\t\t\t\tcontrolPointPreviousX: 15,\n\t\t\t\t\tcontrolPointPreviousY: -10,\n\t\t\t\t\tcontrolPointNextX: 15,\n\t\t\t\t\tcontrolPointNextY: -10,\n\t\t\t\t\tsteppedLine: mode\n\t\t\t\t}\n\t\t\t}));\n\t\t\tpoints.push(new Chart.elements.Point({\n\t\t\t\t_datasetindex: 2,\n\t\t\t\t_index: 3,\n\t\t\t\t_view: {\n\t\t\t\t\tx: 19,\n\t\t\t\t\ty: -5,\n\t\t\t\t\tcontrolPointPreviousX: 19,\n\t\t\t\t\tcontrolPointPreviousY: -5,\n\t\t\t\t\tcontrolPointNextX: 19,\n\t\t\t\t\tcontrolPointNextY: -5,\n\t\t\t\t\tsteppedLine: mode\n\t\t\t\t}\n\t\t\t}));\n\n\t\t\tvar line = new Chart.elements.Line({\n\t\t\t\t_datasetindex: 2,\n\t\t\t\t_chart: {\n\t\t\t\t\tctx: mockContext,\n\t\t\t\t},\n\t\t\t\t_children: points,\n\t\t\t\t// Need to provide some settings\n\t\t\t\t_view: {\n\t\t\t\t\tfill: false, // don't want to fill\n\t\t\t\t\ttension: 0, // no bezier curve for now\n\t\t\t\t}\n\t\t\t});\n\n\t\t\tline.draw();\n\n\t\t\texpect(mockContext.getCalls()).toEqual([{\n\t\t\t\tname: 'save',\n\t\t\t\targs: [],\n\t\t\t}, {\n\t\t\t\tname: 'setLineCap',\n\t\t\t\targs: ['butt']\n\t\t\t}, {\n\t\t\t\tname: 'setLineDash',\n\t\t\t\targs: [\n\t\t\t\t\t[]\n\t\t\t\t]\n\t\t\t}, {\n\t\t\t\tname: 'setLineDashOffset',\n\t\t\t\targs: [0.0]\n\t\t\t}, {\n\t\t\t\tname: 'setLineJoin',\n\t\t\t\targs: ['miter']\n\t\t\t}, {\n\t\t\t\tname: 'setLineWidth',\n\t\t\t\targs: [3]\n\t\t\t}, {\n\t\t\t\tname: 'setStrokeStyle',\n\t\t\t\targs: ['rgba(0,0,0,0.1)']\n\t\t\t}, {\n\t\t\t\tname: 'beginPath',\n\t\t\t\targs: []\n\t\t\t}, {\n\t\t\t\tname: 'moveTo',\n\t\t\t\targs: [0, 10]\n\t\t\t}, {\n\t\t\t\tname: 'lineTo',\n\t\t\t\targs: [5, 10]\n\t\t\t}, {\n\t\t\t\tname: 'lineTo',\n\t\t\t\targs: [5, 0]\n\t\t\t}, {\n\t\t\t\tname: 'lineTo',\n\t\t\t\targs: [15, 0]\n\t\t\t}, {\n\t\t\t\tname: 'lineTo',\n\t\t\t\targs: [15, -10]\n\t\t\t}, {\n\t\t\t\tname: 'lineTo',\n\t\t\t\targs: [19, -10]\n\t\t\t}, {\n\t\t\t\tname: 'lineTo',\n\t\t\t\targs: [19, -5]\n\t\t\t}, {\n\t\t\t\tname: 'stroke',\n\t\t\t\targs: [],\n\t\t\t}, {\n\t\t\t\tname: 'restore',\n\t\t\t\targs: []\n\t\t\t}]);\n\t\t});\n\t});\n\n\tit('should draw stepped lines, with \"after\" interpolation', function() {\n\n\t\tvar mockContext = window.createMockContext();\n\n\t\t// Create our points\n\t\tvar points = [];\n\t\tpoints.push(new Chart.elements.Point({\n\t\t\t_datasetindex: 2,\n\t\t\t_index: 0,\n\t\t\t_view: {\n\t\t\t\tx: 0,\n\t\t\t\ty: 10,\n\t\t\t\tcontrolPointNextX: 0,\n\t\t\t\tcontrolPointNextY: 10,\n\t\t\t\tsteppedLine: 'after'\n\t\t\t}\n\t\t}));\n\t\tpoints.push(new Chart.elements.Point({\n\t\t\t_datasetindex: 2,\n\t\t\t_index: 1,\n\t\t\t_view: {\n\t\t\t\tx: 5,\n\t\t\t\ty: 0,\n\t\t\t\tcontrolPointPreviousX: 5,\n\t\t\t\tcontrolPointPreviousY: 0,\n\t\t\t\tcontrolPointNextX: 5,\n\t\t\t\tcontrolPointNextY: 0,\n\t\t\t\tsteppedLine: 'after'\n\t\t\t}\n\t\t}));\n\t\tpoints.push(new Chart.elements.Point({\n\t\t\t_datasetindex: 2,\n\t\t\t_index: 2,\n\t\t\t_view: {\n\t\t\t\tx: 15,\n\t\t\t\ty: -10,\n\t\t\t\tcontrolPointPreviousX: 15,\n\t\t\t\tcontrolPointPreviousY: -10,\n\t\t\t\tcontrolPointNextX: 15,\n\t\t\t\tcontrolPointNextY: -10,\n\t\t\t\tsteppedLine: 'after'\n\t\t\t}\n\t\t}));\n\t\tpoints.push(new Chart.elements.Point({\n\t\t\t_datasetindex: 2,\n\t\t\t_index: 3,\n\t\t\t_view: {\n\t\t\t\tx: 19,\n\t\t\t\ty: -5,\n\t\t\t\tcontrolPointPreviousX: 19,\n\t\t\t\tcontrolPointPreviousY: -5,\n\t\t\t\tcontrolPointNextX: 19,\n\t\t\t\tcontrolPointNextY: -5,\n\t\t\t\tsteppedLine: 'after'\n\t\t\t}\n\t\t}));\n\n\t\tvar line = new Chart.elements.Line({\n\t\t\t_datasetindex: 2,\n\t\t\t_chart: {\n\t\t\t\tctx: mockContext,\n\t\t\t},\n\t\t\t_children: points,\n\t\t\t// Need to provide some settings\n\t\t\t_view: {\n\t\t\t\tfill: false, // don't want to fill\n\t\t\t\ttension: 0, // no bezier curve for now\n\t\t\t}\n\t\t});\n\n\t\tline.draw();\n\n\t\texpect(mockContext.getCalls()).toEqual([{\n\t\t\tname: 'save',\n\t\t\targs: [],\n\t\t}, {\n\t\t\tname: 'setLineCap',\n\t\t\targs: ['butt']\n\t\t}, {\n\t\t\tname: 'setLineDash',\n\t\t\targs: [\n\t\t\t\t[]\n\t\t\t]\n\t\t}, {\n\t\t\tname: 'setLineDashOffset',\n\t\t\targs: [0.0]\n\t\t}, {\n\t\t\tname: 'setLineJoin',\n\t\t\targs: ['miter']\n\t\t}, {\n\t\t\tname: 'setLineWidth',\n\t\t\targs: [3]\n\t\t}, {\n\t\t\tname: 'setStrokeStyle',\n\t\t\targs: ['rgba(0,0,0,0.1)']\n\t\t}, {\n\t\t\tname: 'beginPath',\n\t\t\targs: []\n\t\t}, {\n\t\t\tname: 'moveTo',\n\t\t\targs: [0, 10]\n\t\t}, {\n\t\t\tname: 'lineTo',\n\t\t\targs: [0, 0]\n\t\t}, {\n\t\t\tname: 'lineTo',\n\t\t\targs: [5, 0]\n\t\t}, {\n\t\t\tname: 'lineTo',\n\t\t\targs: [5, -10]\n\t\t}, {\n\t\t\tname: 'lineTo',\n\t\t\targs: [15, -10]\n\t\t}, {\n\t\t\tname: 'lineTo',\n\t\t\targs: [15, -5]\n\t\t}, {\n\t\t\tname: 'lineTo',\n\t\t\targs: [19, -5]\n\t\t}, {\n\t\t\tname: 'stroke',\n\t\t\targs: [],\n\t\t}, {\n\t\t\tname: 'restore',\n\t\t\targs: []\n\t\t}]);\n\t});\n\n\tit('should draw with custom settings', function() {\n\t\tvar mockContext = window.createMockContext();\n\n\t\t// Create our points\n\t\tvar points = [];\n\t\tpoints.push(new Chart.elements.Point({\n\t\t\t_datasetindex: 2,\n\t\t\t_index: 0,\n\t\t\t_view: {\n\t\t\t\tx: 0,\n\t\t\t\ty: 10,\n\t\t\t\tcontrolPointNextX: 0,\n\t\t\t\tcontrolPointNextY: 10\n\t\t\t}\n\t\t}));\n\t\tpoints.push(new Chart.elements.Point({\n\t\t\t_datasetindex: 2,\n\t\t\t_index: 1,\n\t\t\t_view: {\n\t\t\t\tx: 5,\n\t\t\t\ty: 0,\n\t\t\t\tcontrolPointPreviousX: 5,\n\t\t\t\tcontrolPointPreviousY: 0,\n\t\t\t\tcontrolPointNextX: 5,\n\t\t\t\tcontrolPointNextY: 0\n\t\t\t}\n\t\t}));\n\t\tpoints.push(new Chart.elements.Point({\n\t\t\t_datasetindex: 2,\n\t\t\t_index: 2,\n\t\t\t_view: {\n\t\t\t\tx: 15,\n\t\t\t\ty: -10,\n\t\t\t\tcontrolPointPreviousX: 15,\n\t\t\t\tcontrolPointPreviousY: -10,\n\t\t\t\tcontrolPointNextX: 15,\n\t\t\t\tcontrolPointNextY: -10\n\t\t\t}\n\t\t}));\n\t\tpoints.push(new Chart.elements.Point({\n\t\t\t_datasetindex: 2,\n\t\t\t_index: 3,\n\t\t\t_view: {\n\t\t\t\tx: 19,\n\t\t\t\ty: -5,\n\t\t\t\tcontrolPointPreviousX: 19,\n\t\t\t\tcontrolPointPreviousY: -5,\n\t\t\t\tcontrolPointNextX: 19,\n\t\t\t\tcontrolPointNextY: -5\n\t\t\t}\n\t\t}));\n\n\t\tvar line = new Chart.elements.Line({\n\t\t\t_datasetindex: 2,\n\t\t\t_chart: {\n\t\t\t\tctx: mockContext,\n\t\t\t},\n\t\t\t_children: points,\n\t\t\t// Need to provide some settings\n\t\t\t_view: {\n\t\t\t\tfill: true,\n\t\t\t\ttension: 0, // no bezier curve for now\n\n\t\t\t\tborderCapStyle: 'round',\n\t\t\t\tborderColor: 'rgb(255, 255, 0)',\n\t\t\t\tborderDash: [2, 2],\n\t\t\t\tborderDashOffset: 1.5,\n\t\t\t\tborderJoinStyle: 'bevel',\n\t\t\t\tborderWidth: 4,\n\t\t\t\tbackgroundColor: 'rgb(0, 0, 0)'\n\t\t\t}\n\t\t});\n\n\t\tline.draw();\n\n\t\tvar expected = [{\n\t\t\tname: 'save',\n\t\t\targs: []\n\t\t}, {\n\t\t\tname: 'setLineCap',\n\t\t\targs: ['round']\n\t\t}, {\n\t\t\tname: 'setLineDash',\n\t\t\targs: [\n\t\t\t\t[2, 2]\n\t\t\t]\n\t\t}, {\n\t\t\tname: 'setLineDashOffset',\n\t\t\targs: [1.5]\n\t\t}, {\n\t\t\tname: 'setLineJoin',\n\t\t\targs: ['bevel']\n\t\t}, {\n\t\t\tname: 'setLineWidth',\n\t\t\targs: [4]\n\t\t}, {\n\t\t\tname: 'setStrokeStyle',\n\t\t\targs: ['rgb(255, 255, 0)']\n\t\t}, {\n\t\t\tname: 'beginPath',\n\t\t\targs: []\n\t\t}, {\n\t\t\tname: 'moveTo',\n\t\t\targs: [0, 10]\n\t\t}, {\n\t\t\tname: 'lineTo',\n\t\t\targs: [5, 0]\n\t\t}, {\n\t\t\tname: 'lineTo',\n\t\t\targs: [15, -10]\n\t\t}, {\n\t\t\tname: 'lineTo',\n\t\t\targs: [19, -5]\n\t\t}, {\n\t\t\tname: 'stroke',\n\t\t\targs: []\n\t\t}, {\n\t\t\tname: 'restore',\n\t\t\targs: []\n\t\t}];\n\t\texpect(mockContext.getCalls()).toEqual(expected);\n\t});\n\n\tit('should skip points correctly', function() {\n\t\tvar mockContext = window.createMockContext();\n\n\t\t// Create our points\n\t\tvar points = [];\n\t\tpoints.push(new Chart.elements.Point({\n\t\t\t_datasetindex: 2,\n\t\t\t_index: 0,\n\t\t\t_view: {\n\t\t\t\tx: 0,\n\t\t\t\ty: 10,\n\t\t\t\tcontrolPointNextX: 0,\n\t\t\t\tcontrolPointNextY: 10\n\t\t\t}\n\t\t}));\n\t\tpoints.push(new Chart.elements.Point({\n\t\t\t_datasetindex: 2,\n\t\t\t_index: 1,\n\t\t\t_view: {\n\t\t\t\tx: 5,\n\t\t\t\ty: 0,\n\t\t\t\tcontrolPointPreviousX: 5,\n\t\t\t\tcontrolPointPreviousY: 0,\n\t\t\t\tcontrolPointNextX: 5,\n\t\t\t\tcontrolPointNextY: 0\n\t\t\t}\n\t\t}));\n\t\tpoints.push(new Chart.elements.Point({\n\t\t\t_datasetindex: 2,\n\t\t\t_index: 2,\n\t\t\t_view: {\n\t\t\t\tx: 15,\n\t\t\t\ty: -10,\n\t\t\t\tcontrolPointPreviousX: 15,\n\t\t\t\tcontrolPointPreviousY: -10,\n\t\t\t\tcontrolPointNextX: 15,\n\t\t\t\tcontrolPointNextY: -10,\n\t\t\t\tskip: true\n\t\t\t}\n\t\t}));\n\t\tpoints.push(new Chart.elements.Point({\n\t\t\t_datasetindex: 2,\n\t\t\t_index: 3,\n\t\t\t_view: {\n\t\t\t\tx: 19,\n\t\t\t\ty: -5,\n\t\t\t\tcontrolPointPreviousX: 19,\n\t\t\t\tcontrolPointPreviousY: -5,\n\t\t\t\tcontrolPointNextX: 19,\n\t\t\t\tcontrolPointNextY: -5\n\t\t\t}\n\t\t}));\n\n\t\tvar line = new Chart.elements.Line({\n\t\t\t_datasetindex: 2,\n\t\t\t_chart: {\n\t\t\t\tctx: mockContext,\n\t\t\t},\n\t\t\t_children: points,\n\t\t\t// Need to provide some settings\n\t\t\t_view: {\n\t\t\t\tfill: true,\n\t\t\t\ttension: 0, // no bezier curve for now\n\t\t\t}\n\t\t});\n\n\t\tline.draw();\n\n\t\tvar expected = [{\n\t\t\tname: 'save',\n\t\t\targs: []\n\t\t}, {\n\t\t\tname: 'setLineCap',\n\t\t\targs: ['butt']\n\t\t}, {\n\t\t\tname: 'setLineDash',\n\t\t\targs: [\n\t\t\t\t[]\n\t\t\t]\n\t\t}, {\n\t\t\tname: 'setLineDashOffset',\n\t\t\targs: [0]\n\t\t}, {\n\t\t\tname: 'setLineJoin',\n\t\t\targs: ['miter']\n\t\t}, {\n\t\t\tname: 'setLineWidth',\n\t\t\targs: [3]\n\t\t}, {\n\t\t\tname: 'setStrokeStyle',\n\t\t\targs: ['rgba(0,0,0,0.1)']\n\t\t}, {\n\t\t\tname: 'beginPath',\n\t\t\targs: []\n\t\t}, {\n\t\t\tname: 'moveTo',\n\t\t\targs: [0, 10]\n\t\t}, {\n\t\t\tname: 'lineTo',\n\t\t\targs: [5, 0]\n\t\t}, {\n\t\t\tname: 'moveTo',\n\t\t\targs: [19, -5]\n\t\t}, {\n\t\t\tname: 'stroke',\n\t\t\targs: []\n\t\t}, {\n\t\t\tname: 'restore',\n\t\t\targs: []\n\t\t}];\n\t\texpect(mockContext.getCalls()).toEqual(expected);\n\t});\n\n\tit('should skip points correctly when spanGaps is true', function() {\n\t\tvar mockContext = window.createMockContext();\n\n\t\t// Create our points\n\t\tvar points = [];\n\t\tpoints.push(new Chart.elements.Point({\n\t\t\t_datasetindex: 2,\n\t\t\t_index: 0,\n\t\t\t_view: {\n\t\t\t\tx: 0,\n\t\t\t\ty: 10,\n\t\t\t\tcontrolPointNextX: 0,\n\t\t\t\tcontrolPointNextY: 10\n\t\t\t}\n\t\t}));\n\t\tpoints.push(new Chart.elements.Point({\n\t\t\t_datasetindex: 2,\n\t\t\t_index: 1,\n\t\t\t_view: {\n\t\t\t\tx: 5,\n\t\t\t\ty: 0,\n\t\t\t\tcontrolPointPreviousX: 5,\n\t\t\t\tcontrolPointPreviousY: 0,\n\t\t\t\tcontrolPointNextX: 5,\n\t\t\t\tcontrolPointNextY: 0\n\t\t\t}\n\t\t}));\n\t\tpoints.push(new Chart.elements.Point({\n\t\t\t_datasetindex: 2,\n\t\t\t_index: 2,\n\t\t\t_view: {\n\t\t\t\tx: 15,\n\t\t\t\ty: -10,\n\t\t\t\tcontrolPointPreviousX: 15,\n\t\t\t\tcontrolPointPreviousY: -10,\n\t\t\t\tcontrolPointNextX: 15,\n\t\t\t\tcontrolPointNextY: -10,\n\t\t\t\tskip: true\n\t\t\t}\n\t\t}));\n\t\tpoints.push(new Chart.elements.Point({\n\t\t\t_datasetindex: 2,\n\t\t\t_index: 3,\n\t\t\t_view: {\n\t\t\t\tx: 19,\n\t\t\t\ty: -5,\n\t\t\t\tcontrolPointPreviousX: 19,\n\t\t\t\tcontrolPointPreviousY: -5,\n\t\t\t\tcontrolPointNextX: 19,\n\t\t\t\tcontrolPointNextY: -5\n\t\t\t}\n\t\t}));\n\n\t\tvar line = new Chart.elements.Line({\n\t\t\t_datasetindex: 2,\n\t\t\t_chart: {\n\t\t\t\tctx: mockContext,\n\t\t\t},\n\t\t\t_children: points,\n\t\t\t// Need to provide some settings\n\t\t\t_view: {\n\t\t\t\tfill: true,\n\t\t\t\ttension: 0, // no bezier curve for now\n\t\t\t\tspanGaps: true\n\t\t\t}\n\t\t});\n\n\t\tline.draw();\n\n\t\tvar expected = [{\n\t\t\tname: 'save',\n\t\t\targs: []\n\t\t}, {\n\t\t\tname: 'setLineCap',\n\t\t\targs: ['butt']\n\t\t}, {\n\t\t\tname: 'setLineDash',\n\t\t\targs: [\n\t\t\t\t[]\n\t\t\t]\n\t\t}, {\n\t\t\tname: 'setLineDashOffset',\n\t\t\targs: [0]\n\t\t}, {\n\t\t\tname: 'setLineJoin',\n\t\t\targs: ['miter']\n\t\t}, {\n\t\t\tname: 'setLineWidth',\n\t\t\targs: [3]\n\t\t}, {\n\t\t\tname: 'setStrokeStyle',\n\t\t\targs: ['rgba(0,0,0,0.1)']\n\t\t}, {\n\t\t\tname: 'beginPath',\n\t\t\targs: []\n\t\t}, {\n\t\t\tname: 'moveTo',\n\t\t\targs: [0, 10]\n\t\t}, {\n\t\t\tname: 'lineTo',\n\t\t\targs: [5, 0]\n\t\t}, {\n\t\t\tname: 'lineTo',\n\t\t\targs: [19, -5]\n\t\t}, {\n\t\t\tname: 'stroke',\n\t\t\targs: []\n\t\t}, {\n\t\t\tname: 'restore',\n\t\t\targs: []\n\t\t}];\n\t\texpect(mockContext.getCalls()).toEqual(expected);\n\t});\n\n\tit('should skip points correctly when all points are skipped', function() {\n\t\tvar mockContext = window.createMockContext();\n\n\t\t// Create our points\n\t\tvar points = [];\n\t\tpoints.push(new Chart.elements.Point({\n\t\t\t_datasetindex: 2,\n\t\t\t_index: 0,\n\t\t\t_view: {\n\t\t\t\tx: 0,\n\t\t\t\ty: 10,\n\t\t\t\tcontrolPointNextX: 0,\n\t\t\t\tcontrolPointNextY: 10,\n\t\t\t\tskip: true\n\t\t\t}\n\t\t}));\n\t\tpoints.push(new Chart.elements.Point({\n\t\t\t_datasetindex: 2,\n\t\t\t_index: 1,\n\t\t\t_view: {\n\t\t\t\tx: 5,\n\t\t\t\ty: 0,\n\t\t\t\tcontrolPointPreviousX: 5,\n\t\t\t\tcontrolPointPreviousY: 0,\n\t\t\t\tcontrolPointNextX: 5,\n\t\t\t\tcontrolPointNextY: 0,\n\t\t\t\tskip: true\n\t\t\t}\n\t\t}));\n\t\tpoints.push(new Chart.elements.Point({\n\t\t\t_datasetindex: 2,\n\t\t\t_index: 2,\n\t\t\t_view: {\n\t\t\t\tx: 15,\n\t\t\t\ty: -10,\n\t\t\t\tcontrolPointPreviousX: 15,\n\t\t\t\tcontrolPointPreviousY: -10,\n\t\t\t\tcontrolPointNextX: 15,\n\t\t\t\tcontrolPointNextY: -10,\n\t\t\t\tskip: true\n\t\t\t}\n\t\t}));\n\t\tpoints.push(new Chart.elements.Point({\n\t\t\t_datasetindex: 2,\n\t\t\t_index: 3,\n\t\t\t_view: {\n\t\t\t\tx: 19,\n\t\t\t\ty: -5,\n\t\t\t\tcontrolPointPreviousX: 19,\n\t\t\t\tcontrolPointPreviousY: -5,\n\t\t\t\tcontrolPointNextX: 19,\n\t\t\t\tcontrolPointNextY: -5,\n\t\t\t\tskip: true\n\t\t\t}\n\t\t}));\n\n\t\tvar line = new Chart.elements.Line({\n\t\t\t_datasetindex: 2,\n\t\t\t_chart: {\n\t\t\t\tctx: mockContext,\n\t\t\t},\n\t\t\t_children: points,\n\t\t\t// Need to provide some settings\n\t\t\t_view: {\n\t\t\t\tfill: true,\n\t\t\t\ttension: 0, // no bezier curve for now\n\t\t\t\tspanGaps: true\n\t\t\t}\n\t\t});\n\n\t\tline.draw();\n\n\t\tvar expected = [{\n\t\t\tname: 'save',\n\t\t\targs: []\n\t\t}, {\n\t\t\tname: 'setLineCap',\n\t\t\targs: ['butt']\n\t\t}, {\n\t\t\tname: 'setLineDash',\n\t\t\targs: [\n\t\t\t\t[]\n\t\t\t]\n\t\t}, {\n\t\t\tname: 'setLineDashOffset',\n\t\t\targs: [0]\n\t\t}, {\n\t\t\tname: 'setLineJoin',\n\t\t\targs: ['miter']\n\t\t}, {\n\t\t\tname: 'setLineWidth',\n\t\t\targs: [3]\n\t\t}, {\n\t\t\tname: 'setStrokeStyle',\n\t\t\targs: ['rgba(0,0,0,0.1)']\n\t\t}, {\n\t\t\tname: 'beginPath',\n\t\t\targs: []\n\t\t}, {\n\t\t\tname: 'stroke',\n\t\t\targs: []\n\t\t}, {\n\t\t\tname: 'restore',\n\t\t\targs: []\n\t\t}];\n\t\texpect(mockContext.getCalls()).toEqual(expected);\n\t});\n\n\tit('should skip the first point correctly', function() {\n\t\tvar mockContext = window.createMockContext();\n\n\t\t// Create our points\n\t\tvar points = [];\n\t\tpoints.push(new Chart.elements.Point({\n\t\t\t_datasetindex: 2,\n\t\t\t_index: 0,\n\t\t\t_view: {\n\t\t\t\tx: 0,\n\t\t\t\ty: 10,\n\t\t\t\tcontrolPointNextX: 0,\n\t\t\t\tcontrolPointNextY: 10,\n\t\t\t\tskip: true\n\t\t\t}\n\t\t}));\n\t\tpoints.push(new Chart.elements.Point({\n\t\t\t_datasetindex: 2,\n\t\t\t_index: 1,\n\t\t\t_view: {\n\t\t\t\tx: 5,\n\t\t\t\ty: 0,\n\t\t\t\tcontrolPointPreviousX: 5,\n\t\t\t\tcontrolPointPreviousY: 0,\n\t\t\t\tcontrolPointNextX: 5,\n\t\t\t\tcontrolPointNextY: 0\n\t\t\t}\n\t\t}));\n\t\tpoints.push(new Chart.elements.Point({\n\t\t\t_datasetindex: 2,\n\t\t\t_index: 2,\n\t\t\t_view: {\n\t\t\t\tx: 15,\n\t\t\t\ty: -10,\n\t\t\t\tcontrolPointPreviousX: 15,\n\t\t\t\tcontrolPointPreviousY: -10,\n\t\t\t\tcontrolPointNextX: 15,\n\t\t\t\tcontrolPointNextY: -10\n\t\t\t}\n\t\t}));\n\t\tpoints.push(new Chart.elements.Point({\n\t\t\t_datasetindex: 2,\n\t\t\t_index: 3,\n\t\t\t_view: {\n\t\t\t\tx: 19,\n\t\t\t\ty: -5,\n\t\t\t\tcontrolPointPreviousX: 19,\n\t\t\t\tcontrolPointPreviousY: -5,\n\t\t\t\tcontrolPointNextX: 19,\n\t\t\t\tcontrolPointNextY: -5\n\t\t\t}\n\t\t}));\n\n\t\tvar line = new Chart.elements.Line({\n\t\t\t_datasetindex: 2,\n\t\t\t_chart: {\n\t\t\t\tctx: mockContext,\n\t\t\t},\n\t\t\t_children: points,\n\t\t\t// Need to provide some settings\n\t\t\t_view: {\n\t\t\t\tfill: true,\n\t\t\t\ttension: 0, // no bezier curve for now\n\t\t\t}\n\t\t});\n\n\t\tline.draw();\n\n\t\tvar expected = [{\n\t\t\tname: 'save',\n\t\t\targs: []\n\t\t}, {\n\t\t\tname: 'setLineCap',\n\t\t\targs: ['butt']\n\t\t}, {\n\t\t\tname: 'setLineDash',\n\t\t\targs: [\n\t\t\t\t[]\n\t\t\t]\n\t\t}, {\n\t\t\tname: 'setLineDashOffset',\n\t\t\targs: [0]\n\t\t}, {\n\t\t\tname: 'setLineJoin',\n\t\t\targs: ['miter']\n\t\t}, {\n\t\t\tname: 'setLineWidth',\n\t\t\targs: [3]\n\t\t}, {\n\t\t\tname: 'setStrokeStyle',\n\t\t\targs: ['rgba(0,0,0,0.1)']\n\t\t}, {\n\t\t\tname: 'beginPath',\n\t\t\targs: []\n\t\t}, {\n\t\t\tname: 'moveTo',\n\t\t\targs: [5, 0]\n\t\t}, {\n\t\t\tname: 'lineTo',\n\t\t\targs: [15, -10]\n\t\t}, {\n\t\t\tname: 'lineTo',\n\t\t\targs: [19, -5]\n\t\t}, {\n\t\t\tname: 'stroke',\n\t\t\targs: []\n\t\t}, {\n\t\t\tname: 'restore',\n\t\t\targs: []\n\t\t}];\n\t\texpect(mockContext.getCalls()).toEqual(expected);\n\t});\n\n\tit('should skip the first point correctly when spanGaps is true', function() {\n\t\tvar mockContext = window.createMockContext();\n\n\t\t// Create our points\n\t\tvar points = [];\n\t\tpoints.push(new Chart.elements.Point({\n\t\t\t_datasetindex: 2,\n\t\t\t_index: 0,\n\t\t\t_view: {\n\t\t\t\tx: 0,\n\t\t\t\ty: 10,\n\t\t\t\tcontrolPointNextX: 0,\n\t\t\t\tcontrolPointNextY: 10,\n\t\t\t\tskip: true\n\t\t\t}\n\t\t}));\n\t\tpoints.push(new Chart.elements.Point({\n\t\t\t_datasetindex: 2,\n\t\t\t_index: 1,\n\t\t\t_view: {\n\t\t\t\tx: 5,\n\t\t\t\ty: 0,\n\t\t\t\tcontrolPointPreviousX: 5,\n\t\t\t\tcontrolPointPreviousY: 0,\n\t\t\t\tcontrolPointNextX: 5,\n\t\t\t\tcontrolPointNextY: 0\n\t\t\t}\n\t\t}));\n\t\tpoints.push(new Chart.elements.Point({\n\t\t\t_datasetindex: 2,\n\t\t\t_index: 2,\n\t\t\t_view: {\n\t\t\t\tx: 15,\n\t\t\t\ty: -10,\n\t\t\t\tcontrolPointPreviousX: 15,\n\t\t\t\tcontrolPointPreviousY: -10,\n\t\t\t\tcontrolPointNextX: 15,\n\t\t\t\tcontrolPointNextY: -10\n\t\t\t}\n\t\t}));\n\t\tpoints.push(new Chart.elements.Point({\n\t\t\t_datasetindex: 2,\n\t\t\t_index: 3,\n\t\t\t_view: {\n\t\t\t\tx: 19,\n\t\t\t\ty: -5,\n\t\t\t\tcontrolPointPreviousX: 19,\n\t\t\t\tcontrolPointPreviousY: -5,\n\t\t\t\tcontrolPointNextX: 19,\n\t\t\t\tcontrolPointNextY: -5\n\t\t\t}\n\t\t}));\n\n\t\tvar line = new Chart.elements.Line({\n\t\t\t_datasetindex: 2,\n\t\t\t_chart: {\n\t\t\t\tctx: mockContext,\n\t\t\t},\n\t\t\t_children: points,\n\t\t\t// Need to provide some settings\n\t\t\t_view: {\n\t\t\t\tfill: true,\n\t\t\t\ttension: 0, // no bezier curve for now\n\t\t\t\tspanGaps: true\n\t\t\t}\n\t\t});\n\n\t\tline.draw();\n\n\t\tvar expected = [{\n\t\t\tname: 'save',\n\t\t\targs: []\n\t\t}, {\n\t\t\tname: 'setLineCap',\n\t\t\targs: ['butt']\n\t\t}, {\n\t\t\tname: 'setLineDash',\n\t\t\targs: [\n\t\t\t\t[]\n\t\t\t]\n\t\t}, {\n\t\t\tname: 'setLineDashOffset',\n\t\t\targs: [0]\n\t\t}, {\n\t\t\tname: 'setLineJoin',\n\t\t\targs: ['miter']\n\t\t}, {\n\t\t\tname: 'setLineWidth',\n\t\t\targs: [3]\n\t\t}, {\n\t\t\tname: 'setStrokeStyle',\n\t\t\targs: ['rgba(0,0,0,0.1)']\n\t\t}, {\n\t\t\tname: 'beginPath',\n\t\t\targs: []\n\t\t}, {\n\t\t\tname: 'moveTo',\n\t\t\targs: [5, 0]\n\t\t}, {\n\t\t\tname: 'lineTo',\n\t\t\targs: [15, -10]\n\t\t}, {\n\t\t\tname: 'lineTo',\n\t\t\targs: [19, -5]\n\t\t}, {\n\t\t\tname: 'stroke',\n\t\t\targs: []\n\t\t}, {\n\t\t\tname: 'restore',\n\t\t\targs: []\n\t\t}];\n\t\texpect(mockContext.getCalls()).toEqual(expected);\n\t});\n\n\tit('should skip the last point correctly', function() {\n\t\tvar mockContext = window.createMockContext();\n\n\t\t// Create our points\n\t\tvar points = [];\n\t\tpoints.push(new Chart.elements.Point({\n\t\t\t_datasetindex: 2,\n\t\t\t_index: 0,\n\t\t\t_view: {\n\t\t\t\tx: 0,\n\t\t\t\ty: 10,\n\t\t\t\tcontrolPointNextX: 0,\n\t\t\t\tcontrolPointNextY: 10\n\t\t\t}\n\t\t}));\n\t\tpoints.push(new Chart.elements.Point({\n\t\t\t_datasetindex: 2,\n\t\t\t_index: 1,\n\t\t\t_view: {\n\t\t\t\tx: 5,\n\t\t\t\ty: 0,\n\t\t\t\tcontrolPointPreviousX: 5,\n\t\t\t\tcontrolPointPreviousY: 0,\n\t\t\t\tcontrolPointNextX: 5,\n\t\t\t\tcontrolPointNextY: 0\n\t\t\t}\n\t\t}));\n\t\tpoints.push(new Chart.elements.Point({\n\t\t\t_datasetindex: 2,\n\t\t\t_index: 2,\n\t\t\t_view: {\n\t\t\t\tx: 15,\n\t\t\t\ty: -10,\n\t\t\t\tcontrolPointPreviousX: 15,\n\t\t\t\tcontrolPointPreviousY: -10,\n\t\t\t\tcontrolPointNextX: 15,\n\t\t\t\tcontrolPointNextY: -10\n\t\t\t}\n\t\t}));\n\t\tpoints.push(new Chart.elements.Point({\n\t\t\t_datasetindex: 2,\n\t\t\t_index: 3,\n\t\t\t_view: {\n\t\t\t\tx: 19,\n\t\t\t\ty: -5,\n\t\t\t\tcontrolPointPreviousX: 19,\n\t\t\t\tcontrolPointPreviousY: -5,\n\t\t\t\tcontrolPointNextX: 19,\n\t\t\t\tcontrolPointNextY: -5,\n\t\t\t\tskip: true\n\t\t\t}\n\t\t}));\n\n\t\tvar line = new Chart.elements.Line({\n\t\t\t_datasetindex: 2,\n\t\t\t_chart: {\n\t\t\t\tctx: mockContext,\n\t\t\t},\n\t\t\t_children: points,\n\t\t\t// Need to provide some settings\n\t\t\t_view: {\n\t\t\t\tfill: true,\n\t\t\t\ttension: 0, // no bezier curve for now\n\t\t\t}\n\t\t});\n\n\t\tline.draw();\n\n\t\tvar expected = [{\n\t\t\tname: 'save',\n\t\t\targs: []\n\t\t}, {\n\t\t\tname: 'setLineCap',\n\t\t\targs: ['butt']\n\t\t}, {\n\t\t\tname: 'setLineDash',\n\t\t\targs: [\n\t\t\t\t[]\n\t\t\t]\n\t\t}, {\n\t\t\tname: 'setLineDashOffset',\n\t\t\targs: [0]\n\t\t}, {\n\t\t\tname: 'setLineJoin',\n\t\t\targs: ['miter']\n\t\t}, {\n\t\t\tname: 'setLineWidth',\n\t\t\targs: [3]\n\t\t}, {\n\t\t\tname: 'setStrokeStyle',\n\t\t\targs: ['rgba(0,0,0,0.1)']\n\t\t}, {\n\t\t\tname: 'beginPath',\n\t\t\targs: []\n\t\t}, {\n\t\t\tname: 'moveTo',\n\t\t\targs: [0, 10]\n\t\t}, {\n\t\t\tname: 'lineTo',\n\t\t\targs: [5, 0]\n\t\t}, {\n\t\t\tname: 'lineTo',\n\t\t\targs: [15, -10]\n\t\t}, {\n\t\t\tname: 'stroke',\n\t\t\targs: []\n\t\t}, {\n\t\t\tname: 'restore',\n\t\t\targs: []\n\t\t}];\n\t\texpect(mockContext.getCalls()).toEqual(expected);\n\t});\n\n\tit('should skip the last point correctly when spanGaps is true', function() {\n\t\tvar mockContext = window.createMockContext();\n\n\t\t// Create our points\n\t\tvar points = [];\n\t\tpoints.push(new Chart.elements.Point({\n\t\t\t_datasetindex: 2,\n\t\t\t_index: 0,\n\t\t\t_view: {\n\t\t\t\tx: 0,\n\t\t\t\ty: 10,\n\t\t\t\tcontrolPointNextX: 0,\n\t\t\t\tcontrolPointNextY: 10\n\t\t\t}\n\t\t}));\n\t\tpoints.push(new Chart.elements.Point({\n\t\t\t_datasetindex: 2,\n\t\t\t_index: 1,\n\t\t\t_view: {\n\t\t\t\tx: 5,\n\t\t\t\ty: 0,\n\t\t\t\tcontrolPointPreviousX: 5,\n\t\t\t\tcontrolPointPreviousY: 0,\n\t\t\t\tcontrolPointNextX: 5,\n\t\t\t\tcontrolPointNextY: 0\n\t\t\t}\n\t\t}));\n\t\tpoints.push(new Chart.elements.Point({\n\t\t\t_datasetindex: 2,\n\t\t\t_index: 2,\n\t\t\t_view: {\n\t\t\t\tx: 15,\n\t\t\t\ty: -10,\n\t\t\t\tcontrolPointPreviousX: 15,\n\t\t\t\tcontrolPointPreviousY: -10,\n\t\t\t\tcontrolPointNextX: 15,\n\t\t\t\tcontrolPointNextY: -10\n\t\t\t}\n\t\t}));\n\t\tpoints.push(new Chart.elements.Point({\n\t\t\t_datasetindex: 2,\n\t\t\t_index: 3,\n\t\t\t_view: {\n\t\t\t\tx: 19,\n\t\t\t\ty: -5,\n\t\t\t\tcontrolPointPreviousX: 19,\n\t\t\t\tcontrolPointPreviousY: -5,\n\t\t\t\tcontrolPointNextX: 19,\n\t\t\t\tcontrolPointNextY: -5,\n\t\t\t\tskip: true\n\t\t\t}\n\t\t}));\n\n\t\tvar line = new Chart.elements.Line({\n\t\t\t_datasetindex: 2,\n\t\t\t_chart: {\n\t\t\t\tctx: mockContext,\n\t\t\t},\n\t\t\t_children: points,\n\t\t\t// Need to provide some settings\n\t\t\t_view: {\n\t\t\t\tfill: true,\n\t\t\t\ttension: 0, // no bezier curve for now\n\t\t\t\tspanGaps: true\n\t\t\t}\n\t\t});\n\n\t\tline.draw();\n\n\t\tvar expected = [{\n\t\t\tname: 'save',\n\t\t\targs: []\n\t\t}, {\n\t\t\tname: 'setLineCap',\n\t\t\targs: ['butt']\n\t\t}, {\n\t\t\tname: 'setLineDash',\n\t\t\targs: [\n\t\t\t\t[]\n\t\t\t]\n\t\t}, {\n\t\t\tname: 'setLineDashOffset',\n\t\t\targs: [0]\n\t\t}, {\n\t\t\tname: 'setLineJoin',\n\t\t\targs: ['miter']\n\t\t}, {\n\t\t\tname: 'setLineWidth',\n\t\t\targs: [3]\n\t\t}, {\n\t\t\tname: 'setStrokeStyle',\n\t\t\targs: ['rgba(0,0,0,0.1)']\n\t\t}, {\n\t\t\tname: 'beginPath',\n\t\t\targs: []\n\t\t}, {\n\t\t\tname: 'moveTo',\n\t\t\targs: [0, 10]\n\t\t}, {\n\t\t\tname: 'lineTo',\n\t\t\targs: [5, 0]\n\t\t}, {\n\t\t\tname: 'lineTo',\n\t\t\targs: [15, -10]\n\t\t}, {\n\t\t\tname: 'stroke',\n\t\t\targs: []\n\t\t}, {\n\t\t\tname: 'restore',\n\t\t\targs: []\n\t\t}];\n\t\texpect(mockContext.getCalls()).toEqual(expected);\n\t});\n\n\tit('should be able to draw with a loop back to the beginning point', function() {\n\t\tvar mockContext = window.createMockContext();\n\n\t\t// Create our points\n\t\tvar points = [];\n\t\tpoints.push(new Chart.elements.Point({\n\t\t\t_datasetindex: 2,\n\t\t\t_index: 0,\n\t\t\t_view: {\n\t\t\t\tx: 0,\n\t\t\t\ty: 10,\n\t\t\t\tcontrolPointPreviousX: 0,\n\t\t\t\tcontrolPointPreviousY: 10,\n\t\t\t\tcontrolPointNextX: 0,\n\t\t\t\tcontrolPointNextY: 10\n\t\t\t}\n\t\t}));\n\t\tpoints.push(new Chart.elements.Point({\n\t\t\t_datasetindex: 2,\n\t\t\t_index: 1,\n\t\t\t_view: {\n\t\t\t\tx: 5,\n\t\t\t\ty: 0,\n\t\t\t\tcontrolPointPreviousX: 5,\n\t\t\t\tcontrolPointPreviousY: 0,\n\t\t\t\tcontrolPointNextX: 5,\n\t\t\t\tcontrolPointNextY: 0\n\t\t\t}\n\t\t}));\n\t\tpoints.push(new Chart.elements.Point({\n\t\t\t_datasetindex: 2,\n\t\t\t_index: 2,\n\t\t\t_view: {\n\t\t\t\tx: 15,\n\t\t\t\ty: -10,\n\t\t\t\tcontrolPointPreviousX: 15,\n\t\t\t\tcontrolPointPreviousY: -10,\n\t\t\t\tcontrolPointNextX: 15,\n\t\t\t\tcontrolPointNextY: -10\n\t\t\t}\n\t\t}));\n\t\tpoints.push(new Chart.elements.Point({\n\t\t\t_datasetindex: 2,\n\t\t\t_index: 3,\n\t\t\t_view: {\n\t\t\t\tx: 19,\n\t\t\t\ty: -5,\n\t\t\t\tcontrolPointPreviousX: 19,\n\t\t\t\tcontrolPointPreviousY: -5,\n\t\t\t\tcontrolPointNextX: 19,\n\t\t\t\tcontrolPointNextY: -5\n\t\t\t}\n\t\t}));\n\n\t\tvar line = new Chart.elements.Line({\n\t\t\t_datasetindex: 2,\n\t\t\t_chart: {\n\t\t\t\tctx: mockContext,\n\t\t\t},\n\t\t\t_children: points,\n\t\t\t_loop: true, // want the line to loop back to the first point\n\t\t\t// Need to provide some settings\n\t\t\t_view: {\n\t\t\t\tfill: true, // don't want to fill\n\t\t\t\ttension: 0, // no bezier curve for now\n\t\t\t}\n\t\t});\n\n\t\tline.draw();\n\n\t\texpect(mockContext.getCalls()).toEqual([{\n\t\t\tname: 'save',\n\t\t\targs: [],\n\t\t}, {\n\t\t\tname: 'setLineCap',\n\t\t\targs: ['butt']\n\t\t}, {\n\t\t\tname: 'setLineDash',\n\t\t\targs: [\n\t\t\t\t[]\n\t\t\t]\n\t\t}, {\n\t\t\tname: 'setLineDashOffset',\n\t\t\targs: [0.0]\n\t\t}, {\n\t\t\tname: 'setLineJoin',\n\t\t\targs: ['miter']\n\t\t}, {\n\t\t\tname: 'setLineWidth',\n\t\t\targs: [3]\n\t\t}, {\n\t\t\tname: 'setStrokeStyle',\n\t\t\targs: ['rgba(0,0,0,0.1)']\n\t\t}, {\n\t\t\tname: 'beginPath',\n\t\t\targs: []\n\t\t}, {\n\t\t\tname: 'moveTo',\n\t\t\targs: [0, 10]\n\t\t}, {\n\t\t\tname: 'lineTo',\n\t\t\targs: [5, 0]\n\t\t}, {\n\t\t\tname: 'lineTo',\n\t\t\targs: [15, -10]\n\t\t}, {\n\t\t\tname: 'lineTo',\n\t\t\targs: [19, -5]\n\t\t}, {\n\t\t\tname: 'lineTo',\n\t\t\targs: [0, 10]\n\t\t}, {\n\t\t\tname: 'stroke',\n\t\t\targs: [],\n\t\t}, {\n\t\t\tname: 'restore',\n\t\t\targs: []\n\t\t}]);\n\t});\n\n\tit('should be able to draw with a loop back to the beginning point when there is a skip in the middle of the dataset', function() {\n\t\tvar mockContext = window.createMockContext();\n\n\t\t// Create our points\n\t\tvar points = [];\n\t\tpoints.push(new Chart.elements.Point({\n\t\t\t_datasetindex: 2,\n\t\t\t_index: 0,\n\t\t\t_view: {\n\t\t\t\tx: 0,\n\t\t\t\ty: 10,\n\t\t\t\tcontrolPointPreviousX: 0,\n\t\t\t\tcontrolPointPreviousY: 10,\n\t\t\t\tcontrolPointNextX: 0,\n\t\t\t\tcontrolPointNextY: 10\n\t\t\t}\n\t\t}));\n\t\tpoints.push(new Chart.elements.Point({\n\t\t\t_datasetindex: 2,\n\t\t\t_index: 1,\n\t\t\t_view: {\n\t\t\t\tx: 5,\n\t\t\t\ty: 0,\n\t\t\t\tcontrolPointPreviousX: 5,\n\t\t\t\tcontrolPointPreviousY: 0,\n\t\t\t\tcontrolPointNextX: 5,\n\t\t\t\tcontrolPointNextY: 0,\n\t\t\t\tskip: true\n\t\t\t}\n\t\t}));\n\t\tpoints.push(new Chart.elements.Point({\n\t\t\t_datasetindex: 2,\n\t\t\t_index: 2,\n\t\t\t_view: {\n\t\t\t\tx: 15,\n\t\t\t\ty: -10,\n\t\t\t\tcontrolPointPreviousX: 15,\n\t\t\t\tcontrolPointPreviousY: -10,\n\t\t\t\tcontrolPointNextX: 15,\n\t\t\t\tcontrolPointNextY: -10\n\t\t\t}\n\t\t}));\n\t\tpoints.push(new Chart.elements.Point({\n\t\t\t_datasetindex: 2,\n\t\t\t_index: 3,\n\t\t\t_view: {\n\t\t\t\tx: 19,\n\t\t\t\ty: -5,\n\t\t\t\tcontrolPointPreviousX: 19,\n\t\t\t\tcontrolPointPreviousY: -5,\n\t\t\t\tcontrolPointNextX: 19,\n\t\t\t\tcontrolPointNextY: -5\n\t\t\t}\n\t\t}));\n\n\t\tvar line = new Chart.elements.Line({\n\t\t\t_datasetindex: 2,\n\t\t\t_chart: {\n\t\t\t\tctx: mockContext,\n\t\t\t},\n\t\t\t_children: points,\n\t\t\t_loop: true, // want the line to loop back to the first point\n\t\t\t// Need to provide some settings\n\t\t\t_view: {\n\t\t\t\tfill: true, // don't want to fill\n\t\t\t\ttension: 0, // no bezier curve for now\n\t\t\t}\n\t\t});\n\n\t\tline.draw();\n\n\t\texpect(mockContext.getCalls()).toEqual([{\n\t\t\tname: 'save',\n\t\t\targs: [],\n\t\t}, {\n\t\t\tname: 'setLineCap',\n\t\t\targs: ['butt']\n\t\t}, {\n\t\t\tname: 'setLineDash',\n\t\t\targs: [\n\t\t\t\t[]\n\t\t\t]\n\t\t}, {\n\t\t\tname: 'setLineDashOffset',\n\t\t\targs: [0.0]\n\t\t}, {\n\t\t\tname: 'setLineJoin',\n\t\t\targs: ['miter']\n\t\t}, {\n\t\t\tname: 'setLineWidth',\n\t\t\targs: [3]\n\t\t}, {\n\t\t\tname: 'setStrokeStyle',\n\t\t\targs: ['rgba(0,0,0,0.1)']\n\t\t}, {\n\t\t\tname: 'beginPath',\n\t\t\targs: []\n\t\t}, {\n\t\t\tname: 'moveTo',\n\t\t\targs: [0, 10]\n\t\t}, {\n\t\t\tname: 'moveTo',\n\t\t\targs: [15, -10]\n\t\t}, {\n\t\t\tname: 'lineTo',\n\t\t\targs: [19, -5]\n\t\t}, {\n\t\t\tname: 'lineTo',\n\t\t\targs: [0, 10]\n\t\t}, {\n\t\t\tname: 'stroke',\n\t\t\targs: [],\n\t\t}, {\n\t\t\tname: 'restore',\n\t\t\targs: []\n\t\t}]);\n\t});\n\n\tit('should be able to draw with a loop back to the beginning point when span gaps is true and there is a skip in the middle of the dataset', function() {\n\t\tvar mockContext = window.createMockContext();\n\n\t\t// Create our points\n\t\tvar points = [];\n\t\tpoints.push(new Chart.elements.Point({\n\t\t\t_datasetindex: 2,\n\t\t\t_index: 0,\n\t\t\t_view: {\n\t\t\t\tx: 0,\n\t\t\t\ty: 10,\n\t\t\t\tcontrolPointPreviousX: 0,\n\t\t\t\tcontrolPointPreviousY: 10,\n\t\t\t\tcontrolPointNextX: 0,\n\t\t\t\tcontrolPointNextY: 10\n\t\t\t}\n\t\t}));\n\t\tpoints.push(new Chart.elements.Point({\n\t\t\t_datasetindex: 2,\n\t\t\t_index: 1,\n\t\t\t_view: {\n\t\t\t\tx: 5,\n\t\t\t\ty: 0,\n\t\t\t\tcontrolPointPreviousX: 5,\n\t\t\t\tcontrolPointPreviousY: 0,\n\t\t\t\tcontrolPointNextX: 5,\n\t\t\t\tcontrolPointNextY: 0,\n\t\t\t\tskip: true\n\t\t\t}\n\t\t}));\n\t\tpoints.push(new Chart.elements.Point({\n\t\t\t_datasetindex: 2,\n\t\t\t_index: 2,\n\t\t\t_view: {\n\t\t\t\tx: 15,\n\t\t\t\ty: -10,\n\t\t\t\tcontrolPointPreviousX: 15,\n\t\t\t\tcontrolPointPreviousY: -10,\n\t\t\t\tcontrolPointNextX: 15,\n\t\t\t\tcontrolPointNextY: -10\n\t\t\t}\n\t\t}));\n\t\tpoints.push(new Chart.elements.Point({\n\t\t\t_datasetindex: 2,\n\t\t\t_index: 3,\n\t\t\t_view: {\n\t\t\t\tx: 19,\n\t\t\t\ty: -5,\n\t\t\t\tcontrolPointPreviousX: 19,\n\t\t\t\tcontrolPointPreviousY: -5,\n\t\t\t\tcontrolPointNextX: 19,\n\t\t\t\tcontrolPointNextY: -5\n\t\t\t}\n\t\t}));\n\n\t\tvar line = new Chart.elements.Line({\n\t\t\t_datasetindex: 2,\n\t\t\t_chart: {\n\t\t\t\tctx: mockContext,\n\t\t\t},\n\t\t\t_children: points,\n\t\t\t_loop: true, // want the line to loop back to the first point\n\t\t\t// Need to provide some settings\n\t\t\t_view: {\n\t\t\t\tfill: true, // don't want to fill\n\t\t\t\ttension: 0, // no bezier curve for now\n\t\t\t\tspanGaps: true\n\t\t\t}\n\t\t});\n\n\t\tline.draw();\n\n\t\texpect(mockContext.getCalls()).toEqual([{\n\t\t\tname: 'save',\n\t\t\targs: [],\n\t\t}, {\n\t\t\tname: 'setLineCap',\n\t\t\targs: ['butt']\n\t\t}, {\n\t\t\tname: 'setLineDash',\n\t\t\targs: [\n\t\t\t\t[]\n\t\t\t]\n\t\t}, {\n\t\t\tname: 'setLineDashOffset',\n\t\t\targs: [0.0]\n\t\t}, {\n\t\t\tname: 'setLineJoin',\n\t\t\targs: ['miter']\n\t\t}, {\n\t\t\tname: 'setLineWidth',\n\t\t\targs: [3]\n\t\t}, {\n\t\t\tname: 'setStrokeStyle',\n\t\t\targs: ['rgba(0,0,0,0.1)']\n\t\t}, {\n\t\t\tname: 'beginPath',\n\t\t\targs: []\n\t\t}, {\n\t\t\tname: 'moveTo',\n\t\t\targs: [0, 10]\n\t\t}, {\n\t\t\tname: 'lineTo',\n\t\t\targs: [15, -10]\n\t\t}, {\n\t\t\tname: 'lineTo',\n\t\t\targs: [19, -5]\n\t\t}, {\n\t\t\tname: 'lineTo',\n\t\t\targs: [0, 10]\n\t\t}, {\n\t\t\tname: 'stroke',\n\t\t\targs: [],\n\t\t}, {\n\t\t\tname: 'restore',\n\t\t\targs: []\n\t\t}]);\n\t});\n\n\tit('should be able to draw with a loop back to the beginning point when the first point is skipped', function() {\n\t\tvar mockContext = window.createMockContext();\n\n\t\t// Create our points\n\t\tvar points = [];\n\t\tpoints.push(new Chart.elements.Point({\n\t\t\t_datasetindex: 2,\n\t\t\t_index: 0,\n\t\t\t_view: {\n\t\t\t\tx: 0,\n\t\t\t\ty: 10,\n\t\t\t\tcontrolPointPreviousX: 0,\n\t\t\t\tcontrolPointPreviousY: 10,\n\t\t\t\tcontrolPointNextX: 0,\n\t\t\t\tcontrolPointNextY: 10,\n\t\t\t\tskip: true\n\t\t\t}\n\t\t}));\n\t\tpoints.push(new Chart.elements.Point({\n\t\t\t_datasetindex: 2,\n\t\t\t_index: 1,\n\t\t\t_view: {\n\t\t\t\tx: 5,\n\t\t\t\ty: 0,\n\t\t\t\tcontrolPointPreviousX: 5,\n\t\t\t\tcontrolPointPreviousY: 0,\n\t\t\t\tcontrolPointNextX: 5,\n\t\t\t\tcontrolPointNextY: 0,\n\t\t\t}\n\t\t}));\n\t\tpoints.push(new Chart.elements.Point({\n\t\t\t_datasetindex: 2,\n\t\t\t_index: 2,\n\t\t\t_view: {\n\t\t\t\tx: 15,\n\t\t\t\ty: -10,\n\t\t\t\tcontrolPointPreviousX: 15,\n\t\t\t\tcontrolPointPreviousY: -10,\n\t\t\t\tcontrolPointNextX: 15,\n\t\t\t\tcontrolPointNextY: -10\n\t\t\t}\n\t\t}));\n\t\tpoints.push(new Chart.elements.Point({\n\t\t\t_datasetindex: 2,\n\t\t\t_index: 3,\n\t\t\t_view: {\n\t\t\t\tx: 19,\n\t\t\t\ty: -5,\n\t\t\t\tcontrolPointPreviousX: 19,\n\t\t\t\tcontrolPointPreviousY: -5,\n\t\t\t\tcontrolPointNextX: 19,\n\t\t\t\tcontrolPointNextY: -5\n\t\t\t}\n\t\t}));\n\n\t\tvar line = new Chart.elements.Line({\n\t\t\t_datasetindex: 2,\n\t\t\t_chart: {\n\t\t\t\tctx: mockContext,\n\t\t\t},\n\t\t\t_children: points,\n\t\t\t_loop: true, // want the line to loop back to the first point\n\t\t\t// Need to provide some settings\n\t\t\t_view: {\n\t\t\t\tfill: true, // don't want to fill\n\t\t\t\ttension: 0, // no bezier curve for now\n\t\t\t}\n\t\t});\n\n\t\tline.draw();\n\n\t\texpect(mockContext.getCalls()).toEqual([{\n\t\t\tname: 'save',\n\t\t\targs: [],\n\t\t}, {\n\t\t\tname: 'setLineCap',\n\t\t\targs: ['butt']\n\t\t}, {\n\t\t\tname: 'setLineDash',\n\t\t\targs: [\n\t\t\t\t[]\n\t\t\t]\n\t\t}, {\n\t\t\tname: 'setLineDashOffset',\n\t\t\targs: [0.0]\n\t\t}, {\n\t\t\tname: 'setLineJoin',\n\t\t\targs: ['miter']\n\t\t}, {\n\t\t\tname: 'setLineWidth',\n\t\t\targs: [3]\n\t\t}, {\n\t\t\tname: 'setStrokeStyle',\n\t\t\targs: ['rgba(0,0,0,0.1)']\n\t\t}, {\n\t\t\tname: 'beginPath',\n\t\t\targs: []\n\t\t}, {\n\t\t\tname: 'moveTo',\n\t\t\targs: [5, 0]\n\t\t}, {\n\t\t\tname: 'lineTo',\n\t\t\targs: [15, -10]\n\t\t}, {\n\t\t\tname: 'lineTo',\n\t\t\targs: [19, -5]\n\t\t}, {\n\t\t\tname: 'stroke',\n\t\t\targs: [],\n\t\t}, {\n\t\t\tname: 'restore',\n\t\t\targs: []\n\t\t}]);\n\t});\n\n\tit('should be able to draw with a loop back to the beginning point when the last point is skipped', function() {\n\t\tvar mockContext = window.createMockContext();\n\n\t\t// Create our points\n\t\tvar points = [];\n\t\tpoints.push(new Chart.elements.Point({\n\t\t\t_datasetindex: 2,\n\t\t\t_index: 0,\n\t\t\t_view: {\n\t\t\t\tx: 0,\n\t\t\t\ty: 10,\n\t\t\t\tcontrolPointPreviousX: 0,\n\t\t\t\tcontrolPointPreviousY: 10,\n\t\t\t\tcontrolPointNextX: 0,\n\t\t\t\tcontrolPointNextY: 10\n\t\t\t}\n\t\t}));\n\t\tpoints.push(new Chart.elements.Point({\n\t\t\t_datasetindex: 2,\n\t\t\t_index: 1,\n\t\t\t_view: {\n\t\t\t\tx: 5,\n\t\t\t\ty: 0,\n\t\t\t\tcontrolPointPreviousX: 5,\n\t\t\t\tcontrolPointPreviousY: 0,\n\t\t\t\tcontrolPointNextX: 5,\n\t\t\t\tcontrolPointNextY: 0,\n\t\t\t}\n\t\t}));\n\t\tpoints.push(new Chart.elements.Point({\n\t\t\t_datasetindex: 2,\n\t\t\t_index: 2,\n\t\t\t_view: {\n\t\t\t\tx: 15,\n\t\t\t\ty: -10,\n\t\t\t\tcontrolPointPreviousX: 15,\n\t\t\t\tcontrolPointPreviousY: -10,\n\t\t\t\tcontrolPointNextX: 15,\n\t\t\t\tcontrolPointNextY: -10\n\t\t\t}\n\t\t}));\n\t\tpoints.push(new Chart.elements.Point({\n\t\t\t_datasetindex: 2,\n\t\t\t_index: 3,\n\t\t\t_view: {\n\t\t\t\tx: 19,\n\t\t\t\ty: -5,\n\t\t\t\tcontrolPointPreviousX: 19,\n\t\t\t\tcontrolPointPreviousY: -5,\n\t\t\t\tcontrolPointNextX: 19,\n\t\t\t\tcontrolPointNextY: -5,\n\t\t\t\tskip: true\n\t\t\t}\n\t\t}));\n\n\t\tvar line = new Chart.elements.Line({\n\t\t\t_datasetindex: 2,\n\t\t\t_chart: {\n\t\t\t\tctx: mockContext,\n\t\t\t},\n\t\t\t_children: points,\n\t\t\t_loop: true, // want the line to loop back to the first point\n\t\t\t// Need to provide some settings\n\t\t\t_view: {\n\t\t\t\tfill: true, // don't want to fill\n\t\t\t\ttension: 0, // no bezier curve for now\n\t\t\t}\n\t\t});\n\n\t\tline.draw();\n\n\t\texpect(mockContext.getCalls()).toEqual([{\n\t\t\tname: 'save',\n\t\t\targs: [],\n\t\t}, {\n\t\t\tname: 'setLineCap',\n\t\t\targs: ['butt']\n\t\t}, {\n\t\t\tname: 'setLineDash',\n\t\t\targs: [\n\t\t\t\t[]\n\t\t\t]\n\t\t}, {\n\t\t\tname: 'setLineDashOffset',\n\t\t\targs: [0.0]\n\t\t}, {\n\t\t\tname: 'setLineJoin',\n\t\t\targs: ['miter']\n\t\t}, {\n\t\t\tname: 'setLineWidth',\n\t\t\targs: [3]\n\t\t}, {\n\t\t\tname: 'setStrokeStyle',\n\t\t\targs: ['rgba(0,0,0,0.1)']\n\t\t}, {\n\t\t\tname: 'beginPath',\n\t\t\targs: []\n\t\t}, {\n\t\t\tname: 'moveTo',\n\t\t\targs: [0, 10]\n\t\t}, {\n\t\t\tname: 'lineTo',\n\t\t\targs: [5, 0]\n\t\t}, {\n\t\t\tname: 'lineTo',\n\t\t\targs: [15, -10]\n\t\t}, {\n\t\t\tname: 'moveTo',\n\t\t\targs: [0, 10]\n\t\t}, {\n\t\t\tname: 'stroke',\n\t\t\targs: [],\n\t\t}, {\n\t\t\tname: 'restore',\n\t\t\targs: []\n\t\t}]);\n\t});\n});\n"
  },
  {
    "path": "app_backend/static/plugin/Chart.js-2.6.0/test/specs/element.point.tests.js",
    "content": "// Test the point element\n\ndescribe('Point element tests', function() {\n\tit ('Should be constructed', function() {\n\t\tvar point = new Chart.elements.Point({\n\t\t\t_datasetIndex: 2,\n\t\t\t_index: 1\n\t\t});\n\n\t\texpect(point).not.toBe(undefined);\n\t\texpect(point._datasetIndex).toBe(2);\n\t\texpect(point._index).toBe(1);\n\t});\n\n\tit ('Should correctly identify as in range', function() {\n\t\tvar point = new Chart.elements.Point({\n\t\t\t_datasetIndex: 2,\n\t\t\t_index: 1\n\t\t});\n\n\t\t// Safely handles if these are called before the viewmodel is instantiated\n\t\texpect(point.inRange(5)).toBe(false);\n\t\texpect(point.inLabelRange(5)).toBe(false);\n\n\t\t// Attach a view object as if we were the controller\n\t\tpoint._view = {\n\t\t\tradius: 2,\n\t\t\thitRadius: 3,\n\t\t\tx: 10,\n\t\t\ty: 15\n\t\t};\n\n\t\texpect(point.inRange(10, 15)).toBe(true);\n\t\texpect(point.inRange(10, 10)).toBe(false);\n\t\texpect(point.inRange(10, 5)).toBe(false);\n\t\texpect(point.inRange(5, 5)).toBe(false);\n\n\t\texpect(point.inLabelRange(5)).toBe(false);\n\t\texpect(point.inLabelRange(7)).toBe(true);\n\t\texpect(point.inLabelRange(10)).toBe(true);\n\t\texpect(point.inLabelRange(12)).toBe(true);\n\t\texpect(point.inLabelRange(15)).toBe(false);\n\t\texpect(point.inLabelRange(20)).toBe(false);\n\t});\n\n\tit ('should get the correct tooltip position', function() {\n\t\tvar point = new Chart.elements.Point({\n\t\t\t_datasetIndex: 2,\n\t\t\t_index: 1\n\t\t});\n\n\t\t// Attach a view object as if we were the controller\n\t\tpoint._view = {\n\t\t\tradius: 2,\n\t\t\tborderWidth: 6,\n\t\t\tx: 10,\n\t\t\ty: 15\n\t\t};\n\n\t\texpect(point.tooltipPosition()).toEqual({\n\t\t\tx: 10,\n\t\t\ty: 15,\n\t\t\tpadding: 8\n\t\t});\n\t});\n\n\tit('should get the correct area', function() {\n\t\tvar point = new Chart.elements.Point({\n\t\t\t_datasetIndex: 2,\n\t\t\t_index: 1\n\t\t});\n\n\t\t// Attach a view object as if we were the controller\n\t\tpoint._view = {\n\t\t\tradius: 2,\n\t\t};\n\n\t\texpect(point.getArea()).toEqual(Math.PI * 4);\n\t});\n\n\tit('should get the correct center point', function() {\n\t\tvar point = new Chart.elements.Point({\n\t\t\t_datasetIndex: 2,\n\t\t\t_index: 1\n\t\t});\n\n\t\t// Attach a view object as if we were the controller\n\t\tpoint._view = {\n\t\t\tradius: 2,\n\t\t\tx: 10,\n\t\t\ty: 10\n\t\t};\n\n\t\texpect(point.getCenterPoint()).toEqual({x: 10, y: 10});\n\t});\n\n\tit ('should draw correctly', function() {\n\t\tvar mockContext = window.createMockContext();\n\t\tvar point = new Chart.elements.Point({\n\t\t\t_datasetIndex: 2,\n\t\t\t_index: 1,\n\t\t\t_chart: {\n\t\t\t\tctx: mockContext,\n\t\t\t}\n\t\t});\n\n\t\t// Attach a view object as if we were the controller\n\t\tpoint._view = {\n\t\t\tradius: 2,\n\t\t\tpointStyle: 'circle',\n\t\t\thitRadius: 3,\n\t\t\tborderColor: 'rgba(1, 2, 3, 1)',\n\t\t\tborderWidth: 6,\n\t\t\tbackgroundColor: 'rgba(0, 255, 0)',\n\t\t\tx: 10,\n\t\t\ty: 15,\n\t\t\tctx: mockContext\n\t\t};\n\n\t\tpoint.draw();\n\n\t\texpect(mockContext.getCalls()).toEqual([{\n\t\t\tname: 'setStrokeStyle',\n\t\t\targs: ['rgba(1, 2, 3, 1)']\n\t\t}, {\n\t\t\tname: 'setLineWidth',\n\t\t\targs: [6]\n\t\t}, {\n\t\t\tname: 'setFillStyle',\n\t\t\targs: ['rgba(0, 255, 0)']\n\t\t}, {\n\t\t\tname: 'beginPath',\n\t\t\targs: []\n\t\t}, {\n\t\t\tname: 'arc',\n\t\t\targs: [10, 15, 2, 0, 2 * Math.PI]\n\t\t}, {\n\t\t\tname: 'closePath',\n\t\t\targs: [],\n\t\t}, {\n\t\t\tname: 'fill',\n\t\t\targs: [],\n\t\t}, {\n\t\t\tname: 'stroke',\n\t\t\targs: []\n\t\t}]);\n\n\t\tmockContext.resetCalls();\n\t\tpoint._view.pointStyle = 'triangle';\n\t\tpoint.draw();\n\n\t\texpect(mockContext.getCalls()).toEqual([{\n\t\t\tname: 'setStrokeStyle',\n\t\t\targs: ['rgba(1, 2, 3, 1)']\n\t\t}, {\n\t\t\tname: 'setLineWidth',\n\t\t\targs: [6]\n\t\t}, {\n\t\t\tname: 'setFillStyle',\n\t\t\targs: ['rgba(0, 255, 0)']\n\t\t}, {\n\t\t\tname: 'beginPath',\n\t\t\targs: []\n\t\t}, {\n\t\t\tname: 'moveTo',\n\t\t\targs: [10 - 3 * 2 / Math.sqrt(3) / 2, 15 + 3 * 2 / Math.sqrt(3) * Math.sqrt(3) / 2 / 3]\n\t\t}, {\n\t\t\tname: 'lineTo',\n\t\t\targs: [10 + 3 * 2 / Math.sqrt(3) / 2, 15 + 3 * 2 / Math.sqrt(3) * Math.sqrt(3) / 2 / 3],\n\t\t}, {\n\t\t\tname: 'lineTo',\n\t\t\targs: [10, 15 - 2 * 3 * 2 / Math.sqrt(3) * Math.sqrt(3) / 2 / 3],\n\t\t}, {\n\t\t\tname: 'closePath',\n\t\t\targs: [],\n\t\t}, {\n\t\t\tname: 'fill',\n\t\t\targs: [],\n\t\t}, {\n\t\t\tname: 'stroke',\n\t\t\targs: []\n\t\t}]);\n\n\t\tmockContext.resetCalls();\n\t\tpoint._view.pointStyle = 'rect';\n\t\tpoint.draw();\n\n\t\texpect(mockContext.getCalls()).toEqual([{\n\t\t\tname: 'setStrokeStyle',\n\t\t\targs: ['rgba(1, 2, 3, 1)']\n\t\t}, {\n\t\t\tname: 'setLineWidth',\n\t\t\targs: [6]\n\t\t}, {\n\t\t\tname: 'setFillStyle',\n\t\t\targs: ['rgba(0, 255, 0)']\n\t\t}, {\n\t\t\tname: 'beginPath',\n\t\t\targs: []\n\t\t}, {\n\t\t\tname: 'fillRect',\n\t\t\targs: [10 - 1 / Math.SQRT2 * 2, 15 - 1 / Math.SQRT2 * 2, 2 / Math.SQRT2 * 2, 2 / Math.SQRT2 * 2]\n\t\t}, {\n\t\t\tname: 'strokeRect',\n\t\t\targs: [10 - 1 / Math.SQRT2 * 2, 15 - 1 / Math.SQRT2 * 2, 2 / Math.SQRT2 * 2, 2 / Math.SQRT2 * 2]\n\t\t}, {\n\t\t\tname: 'stroke',\n\t\t\targs: []\n\t\t}]);\n\n\t\tvar drawRoundedRectangleSpy = jasmine.createSpy('drawRoundedRectangle');\n\t\tvar drawRoundedRectangle = Chart.helpers.drawRoundedRectangle;\n\t\tvar offset = point._view.radius / Math.SQRT2;\n\t\tChart.helpers.drawRoundedRectangle = drawRoundedRectangleSpy;\n\t\tmockContext.resetCalls();\n\t\tpoint._view.pointStyle = 'rectRounded';\n\t\tpoint.draw();\n\n\t\texpect(drawRoundedRectangleSpy).toHaveBeenCalledWith(\n\t\t\tmockContext,\n\t\t\t10 - offset,\n\t\t\t15 - offset,\n\t\t\tMath.SQRT2 * 2,\n\t\t\tMath.SQRT2 * 2,\n\t\t\t2 / 2\n\t\t);\n\t\texpect(mockContext.getCalls()).toContain(\n\t\t\tjasmine.objectContaining({\n\t\t\t\tname: 'fill',\n\t\t\t\targs: [],\n\t\t\t})\n\t\t);\n\n\t\tChart.helpers.drawRoundedRectangle = drawRoundedRectangle;\n\t\tmockContext.resetCalls();\n\t\tpoint._view.pointStyle = 'rectRot';\n\t\tpoint.draw();\n\n\t\texpect(mockContext.getCalls()).toEqual([{\n\t\t\tname: 'setStrokeStyle',\n\t\t\targs: ['rgba(1, 2, 3, 1)']\n\t\t}, {\n\t\t\tname: 'setLineWidth',\n\t\t\targs: [6]\n\t\t}, {\n\t\t\tname: 'setFillStyle',\n\t\t\targs: ['rgba(0, 255, 0)']\n\t\t}, {\n\t\t\tname: 'beginPath',\n\t\t\targs: []\n\t\t}, {\n\t\t\tname: 'moveTo',\n\t\t\targs: [10 - 1 / Math.SQRT2 * 2, 15]\n\t\t}, {\n\t\t\tname: 'lineTo',\n\t\t\targs: [10, 15 + 1 / Math.SQRT2 * 2]\n\t\t}, {\n\t\t\tname: 'lineTo',\n\t\t\targs: [10 + 1 / Math.SQRT2 * 2, 15],\n\t\t}, {\n\t\t\tname: 'lineTo',\n\t\t\targs: [10, 15 - 1 / Math.SQRT2 * 2],\n\t\t}, {\n\t\t\tname: 'closePath',\n\t\t\targs: []\n\t\t}, {\n\t\t\tname: 'fill',\n\t\t\targs: [],\n\t\t}, {\n\t\t\tname: 'stroke',\n\t\t\targs: []\n\t\t}]);\n\n\t\tmockContext.resetCalls();\n\t\tpoint._view.pointStyle = 'cross';\n\t\tpoint.draw();\n\n\t\texpect(mockContext.getCalls()).toEqual([{\n\t\t\tname: 'setStrokeStyle',\n\t\t\targs: ['rgba(1, 2, 3, 1)']\n\t\t}, {\n\t\t\tname: 'setLineWidth',\n\t\t\targs: [6]\n\t\t}, {\n\t\t\tname: 'setFillStyle',\n\t\t\targs: ['rgba(0, 255, 0)']\n\t\t}, {\n\t\t\tname: 'beginPath',\n\t\t\targs: []\n\t\t}, {\n\t\t\tname: 'moveTo',\n\t\t\targs: [10, 17]\n\t\t}, {\n\t\t\tname: 'lineTo',\n\t\t\targs: [10, 13],\n\t\t}, {\n\t\t\tname: 'moveTo',\n\t\t\targs: [8, 15],\n\t\t}, {\n\t\t\tname: 'lineTo',\n\t\t\targs: [12, 15],\n\t\t}, {\n\t\t\tname: 'closePath',\n\t\t\targs: [],\n\t\t}, {\n\t\t\tname: 'stroke',\n\t\t\targs: []\n\t\t}]);\n\n\t\tmockContext.resetCalls();\n\t\tpoint._view.pointStyle = 'crossRot';\n\t\tpoint.draw();\n\n\t\texpect(mockContext.getCalls()).toEqual([{\n\t\t\tname: 'setStrokeStyle',\n\t\t\targs: ['rgba(1, 2, 3, 1)']\n\t\t}, {\n\t\t\tname: 'setLineWidth',\n\t\t\targs: [6]\n\t\t}, {\n\t\t\tname: 'setFillStyle',\n\t\t\targs: ['rgba(0, 255, 0)']\n\t\t}, {\n\t\t\tname: 'beginPath',\n\t\t\targs: []\n\t\t}, {\n\t\t\tname: 'moveTo',\n\t\t\targs: [10 - Math.cos(Math.PI / 4) * 2, 15 - Math.sin(Math.PI / 4) * 2]\n\t\t}, {\n\t\t\tname: 'lineTo',\n\t\t\targs: [10 + Math.cos(Math.PI / 4) * 2, 15 + Math.sin(Math.PI / 4) * 2],\n\t\t}, {\n\t\t\tname: 'moveTo',\n\t\t\targs: [10 - Math.cos(Math.PI / 4) * 2, 15 + Math.sin(Math.PI / 4) * 2],\n\t\t}, {\n\t\t\tname: 'lineTo',\n\t\t\targs: [10 + Math.cos(Math.PI / 4) * 2, 15 - Math.sin(Math.PI / 4) * 2],\n\t\t}, {\n\t\t\tname: 'closePath',\n\t\t\targs: [],\n\t\t}, {\n\t\t\tname: 'stroke',\n\t\t\targs: []\n\t\t}]);\n\n\t\tmockContext.resetCalls();\n\t\tpoint._view.pointStyle = 'star';\n\t\tpoint.draw();\n\n\t\texpect(mockContext.getCalls()).toEqual([{\n\t\t\tname: 'setStrokeStyle',\n\t\t\targs: ['rgba(1, 2, 3, 1)']\n\t\t}, {\n\t\t\tname: 'setLineWidth',\n\t\t\targs: [6]\n\t\t}, {\n\t\t\tname: 'setFillStyle',\n\t\t\targs: ['rgba(0, 255, 0)']\n\t\t}, {\n\t\t\tname: 'beginPath',\n\t\t\targs: []\n\t\t}, {\n\t\t\tname: 'moveTo',\n\t\t\targs: [10, 17]\n\t\t}, {\n\t\t\tname: 'lineTo',\n\t\t\targs: [10, 13],\n\t\t}, {\n\t\t\tname: 'moveTo',\n\t\t\targs: [8, 15],\n\t\t}, {\n\t\t\tname: 'lineTo',\n\t\t\targs: [12, 15],\n\t\t}, {\n\t\t\tname: 'moveTo',\n\t\t\targs: [10 - Math.cos(Math.PI / 4) * 2, 15 - Math.sin(Math.PI / 4) * 2]\n\t\t}, {\n\t\t\tname: 'lineTo',\n\t\t\targs: [10 + Math.cos(Math.PI / 4) * 2, 15 + Math.sin(Math.PI / 4) * 2],\n\t\t}, {\n\t\t\tname: 'moveTo',\n\t\t\targs: [10 - Math.cos(Math.PI / 4) * 2, 15 + Math.sin(Math.PI / 4) * 2],\n\t\t}, {\n\t\t\tname: 'lineTo',\n\t\t\targs: [10 + Math.cos(Math.PI / 4) * 2, 15 - Math.sin(Math.PI / 4) * 2],\n\t\t}, {\n\t\t\tname: 'closePath',\n\t\t\targs: [],\n\t\t}, {\n\t\t\tname: 'stroke',\n\t\t\targs: []\n\t\t}]);\n\n\t\tmockContext.resetCalls();\n\t\tpoint._view.pointStyle = 'line';\n\t\tpoint.draw();\n\n\t\texpect(mockContext.getCalls()).toEqual([{\n\t\t\tname: 'setStrokeStyle',\n\t\t\targs: ['rgba(1, 2, 3, 1)']\n\t\t}, {\n\t\t\tname: 'setLineWidth',\n\t\t\targs: [6]\n\t\t}, {\n\t\t\tname: 'setFillStyle',\n\t\t\targs: ['rgba(0, 255, 0)']\n\t\t}, {\n\t\t\tname: 'beginPath',\n\t\t\targs: []\n\t\t}, {\n\t\t\tname: 'moveTo',\n\t\t\targs: [8, 15]\n\t\t}, {\n\t\t\tname: 'lineTo',\n\t\t\targs: [12, 15],\n\t\t}, {\n\t\t\tname: 'closePath',\n\t\t\targs: [],\n\t\t}, {\n\t\t\tname: 'stroke',\n\t\t\targs: []\n\t\t}]);\n\n\t\tmockContext.resetCalls();\n\t\tpoint._view.pointStyle = 'dash';\n\t\tpoint.draw();\n\n\t\texpect(mockContext.getCalls()).toEqual([{\n\t\t\tname: 'setStrokeStyle',\n\t\t\targs: ['rgba(1, 2, 3, 1)']\n\t\t}, {\n\t\t\tname: 'setLineWidth',\n\t\t\targs: [6]\n\t\t}, {\n\t\t\tname: 'setFillStyle',\n\t\t\targs: ['rgba(0, 255, 0)']\n\t\t}, {\n\t\t\tname: 'beginPath',\n\t\t\targs: []\n\t\t}, {\n\t\t\tname: 'moveTo',\n\t\t\targs: [10, 15]\n\t\t}, {\n\t\t\tname: 'lineTo',\n\t\t\targs: [12, 15],\n\t\t}, {\n\t\t\tname: 'closePath',\n\t\t\targs: [],\n\t\t}, {\n\t\t\tname: 'stroke',\n\t\t\targs: []\n\t\t}]);\n\n\t});\n\n\tit ('should draw correctly with default settings if necessary', function() {\n\t\tvar mockContext = window.createMockContext();\n\t\tvar point = new Chart.elements.Point({\n\t\t\t_datasetIndex: 2,\n\t\t\t_index: 1,\n\t\t\t_chart: {\n\t\t\t\tctx: mockContext,\n\t\t\t}\n\t\t});\n\n\t\t// Attach a view object as if we were the controller\n\t\tpoint._view = {\n\t\t\tradius: 2,\n\t\t\thitRadius: 3,\n\t\t\tx: 10,\n\t\t\ty: 15,\n\t\t\tctx: mockContext\n\t\t};\n\n\t\tpoint.draw();\n\n\t\texpect(mockContext.getCalls()).toEqual([{\n\t\t\tname: 'setStrokeStyle',\n\t\t\targs: ['rgba(0,0,0,0.1)']\n\t\t}, {\n\t\t\tname: 'setLineWidth',\n\t\t\targs: [1]\n\t\t}, {\n\t\t\tname: 'setFillStyle',\n\t\t\targs: ['rgba(0,0,0,0.1)']\n\t\t}, {\n\t\t\tname: 'beginPath',\n\t\t\targs: []\n\t\t}, {\n\t\t\tname: 'arc',\n\t\t\targs: [10, 15, 2, 0, 2 * Math.PI]\n\t\t}, {\n\t\t\tname: 'closePath',\n\t\t\targs: [],\n\t\t}, {\n\t\t\tname: 'fill',\n\t\t\targs: [],\n\t\t}, {\n\t\t\tname: 'stroke',\n\t\t\targs: []\n\t\t}]);\n\t});\n\n\tit ('should not draw if skipped', function() {\n\t\tvar mockContext = window.createMockContext();\n\t\tvar point = new Chart.elements.Point({\n\t\t\t_datasetIndex: 2,\n\t\t\t_index: 1,\n\t\t\t_chart: {\n\t\t\t\tctx: mockContext,\n\t\t\t}\n\t\t});\n\n\t\t// Attach a view object as if we were the controller\n\t\tpoint._view = {\n\t\t\tradius: 2,\n\t\t\thitRadius: 3,\n\t\t\tx: 10,\n\t\t\ty: 15,\n\t\t\tctx: mockContext,\n\t\t\tskip: true\n\t\t};\n\n\t\tpoint.draw();\n\n\t\texpect(mockContext.getCalls()).toEqual([]);\n\t});\n});\n"
  },
  {
    "path": "app_backend/static/plugin/Chart.js-2.6.0/test/specs/element.rectangle.tests.js",
    "content": "// Test the rectangle element\n\ndescribe('Rectangle element tests', function() {\n\tit ('Should be constructed', function() {\n\t\tvar rectangle = new Chart.elements.Rectangle({\n\t\t\t_datasetIndex: 2,\n\t\t\t_index: 1\n\t\t});\n\n\t\texpect(rectangle).not.toBe(undefined);\n\t\texpect(rectangle._datasetIndex).toBe(2);\n\t\texpect(rectangle._index).toBe(1);\n\t});\n\n\tit ('Should correctly identify as in range', function() {\n\t\tvar rectangle = new Chart.elements.Rectangle({\n\t\t\t_datasetIndex: 2,\n\t\t\t_index: 1\n\t\t});\n\n\t\t// Safely handles if these are called before the viewmodel is instantiated\n\t\texpect(rectangle.inRange(5)).toBe(false);\n\t\texpect(rectangle.inLabelRange(5)).toBe(false);\n\n\t\t// Attach a view object as if we were the controller\n\t\trectangle._view = {\n\t\t\tbase: 0,\n\t\t\twidth: 4,\n\t\t\tx: 10,\n\t\t\ty: 15\n\t\t};\n\n\t\texpect(rectangle.inRange(10, 15)).toBe(true);\n\t\texpect(rectangle.inRange(10, 10)).toBe(true);\n\t\texpect(rectangle.inRange(10, 16)).toBe(false);\n\t\texpect(rectangle.inRange(5, 5)).toBe(false);\n\n\t\texpect(rectangle.inLabelRange(5)).toBe(false);\n\t\texpect(rectangle.inLabelRange(7)).toBe(false);\n\t\texpect(rectangle.inLabelRange(10)).toBe(true);\n\t\texpect(rectangle.inLabelRange(12)).toBe(true);\n\t\texpect(rectangle.inLabelRange(15)).toBe(false);\n\t\texpect(rectangle.inLabelRange(20)).toBe(false);\n\n\t\t// Test when the y is below the base (negative bar)\n\t\tvar negativeRectangle = new Chart.elements.Rectangle({\n\t\t\t_datasetIndex: 2,\n\t\t\t_index: 1\n\t\t});\n\n\t\t// Attach a view object as if we were the controller\n\t\tnegativeRectangle._view = {\n\t\t\tbase: 0,\n\t\t\twidth: 4,\n\t\t\tx: 10,\n\t\t\ty: -15\n\t\t};\n\n\t\texpect(negativeRectangle.inRange(10, -16)).toBe(false);\n\t\texpect(negativeRectangle.inRange(10, 1)).toBe(false);\n\t\texpect(negativeRectangle.inRange(10, -5)).toBe(true);\n\t});\n\n\tit ('should get the correct height', function() {\n\t\tvar rectangle = new Chart.elements.Rectangle({\n\t\t\t_datasetIndex: 2,\n\t\t\t_index: 1\n\t\t});\n\n\t\t// Attach a view object as if we were the controller\n\t\trectangle._view = {\n\t\t\tbase: 0,\n\t\t\twidth: 4,\n\t\t\tx: 10,\n\t\t\ty: 15\n\t\t};\n\n\t\texpect(rectangle.height()).toBe(-15);\n\n\t\t// Test when the y is below the base (negative bar)\n\t\tvar negativeRectangle = new Chart.elements.Rectangle({\n\t\t\t_datasetIndex: 2,\n\t\t\t_index: 1\n\t\t});\n\n\t\t// Attach a view object as if we were the controller\n\t\tnegativeRectangle._view = {\n\t\t\tbase: -10,\n\t\t\twidth: 4,\n\t\t\tx: 10,\n\t\t\ty: -15\n\t\t};\n\t\texpect(negativeRectangle.height()).toBe(5);\n\t});\n\n\tit ('should get the correct tooltip position', function() {\n\t\tvar rectangle = new Chart.elements.Rectangle({\n\t\t\t_datasetIndex: 2,\n\t\t\t_index: 1\n\t\t});\n\n\t\t// Attach a view object as if we were the controller\n\t\trectangle._view = {\n\t\t\tbase: 0,\n\t\t\twidth: 4,\n\t\t\tx: 10,\n\t\t\ty: 15\n\t\t};\n\n\t\texpect(rectangle.tooltipPosition()).toEqual({\n\t\t\tx: 10,\n\t\t\ty: 15,\n\t\t});\n\n\t\t// Test when the y is below the base (negative bar)\n\t\tvar negativeRectangle = new Chart.elements.Rectangle({\n\t\t\t_datasetIndex: 2,\n\t\t\t_index: 1\n\t\t});\n\n\t\t// Attach a view object as if we were the controller\n\t\tnegativeRectangle._view = {\n\t\t\tbase: -10,\n\t\t\twidth: 4,\n\t\t\tx: 10,\n\t\t\ty: -15\n\t\t};\n\n\t\texpect(negativeRectangle.tooltipPosition()).toEqual({\n\t\t\tx: 10,\n\t\t\ty: -15,\n\t\t});\n\t});\n\n\tit ('should get the correct area', function() {\n\t\tvar rectangle = new Chart.elements.Rectangle({\n\t\t\t_datasetIndex: 2,\n\t\t\t_index: 1\n\t\t});\n\n\t\t// Attach a view object as if we were the controller\n\t\trectangle._view = {\n\t\t\tbase: 0,\n\t\t\twidth: 4,\n\t\t\tx: 10,\n\t\t\ty: 15\n\t\t};\n\n\t\texpect(rectangle.getArea()).toEqual(60);\n\t});\n\n\tit ('should get the center', function() {\n\t\tvar rectangle = new Chart.elements.Rectangle({\n\t\t\t_datasetIndex: 2,\n\t\t\t_index: 1\n\t\t});\n\n\t\t// Attach a view object as if we were the controller\n\t\trectangle._view = {\n\t\t\tbase: 0,\n\t\t\twidth: 4,\n\t\t\tx: 10,\n\t\t\ty: 15\n\t\t};\n\n\t\texpect(rectangle.getCenterPoint()).toEqual({x: 10, y: 7.5});\n\t});\n\n\tit ('should draw correctly', function() {\n\t\tvar mockContext = window.createMockContext();\n\t\tvar rectangle = new Chart.elements.Rectangle({\n\t\t\t_datasetIndex: 2,\n\t\t\t_index: 1,\n\t\t\t_chart: {\n\t\t\t\tctx: mockContext,\n\t\t\t}\n\t\t});\n\n\t\t// Attach a view object as if we were the controller\n\t\trectangle._view = {\n\t\t\tbackgroundColor: 'rgb(255, 0, 0)',\n\t\t\tbase: 0,\n\t\t\tborderColor: 'rgb(0, 0, 255)',\n\t\t\tborderWidth: 1,\n\t\t\tctx: mockContext,\n\t\t\twidth: 4,\n\t\t\tx: 10,\n\t\t\ty: 15,\n\t\t};\n\n\t\trectangle.draw();\n\n\t\texpect(mockContext.getCalls()).toEqual([{\n\t\t\tname: 'beginPath',\n\t\t\targs: [],\n\t\t}, {\n\t\t\tname: 'setFillStyle',\n\t\t\targs: ['rgb(255, 0, 0)']\n\t\t}, {\n\t\t\tname: 'setStrokeStyle',\n\t\t\targs: ['rgb(0, 0, 255)'],\n\t\t}, {\n\t\t\tname: 'setLineWidth',\n\t\t\targs: [1]\n\t\t}, {\n\t\t\tname: 'moveTo',\n\t\t\targs: [8.5, 0]\n\t\t}, {\n\t\t\tname: 'lineTo',\n\t\t\targs: [8.5, 14.5] // This is a minus bar. Not 15.5\n\t\t}, {\n\t\t\tname: 'lineTo',\n\t\t\targs: [11.5, 14.5]\n\t\t}, {\n\t\t\tname: 'lineTo',\n\t\t\targs: [11.5, 0]\n\t\t}, {\n\t\t\tname: 'fill',\n\t\t\targs: [],\n\t\t}, {\n\t\t\tname: 'stroke',\n\t\t\targs: []\n\t\t}]);\n\t});\n\n\tit ('should draw correctly with no stroke', function() {\n\t\tvar mockContext = window.createMockContext();\n\t\tvar rectangle = new Chart.elements.Rectangle({\n\t\t\t_datasetIndex: 2,\n\t\t\t_index: 1,\n\t\t\t_chart: {\n\t\t\t\tctx: mockContext,\n\t\t\t}\n\t\t});\n\n\t\t// Attach a view object as if we were the controller\n\t\trectangle._view = {\n\t\t\tbackgroundColor: 'rgb(255, 0, 0)',\n\t\t\tbase: 0,\n\t\t\tborderColor: 'rgb(0, 0, 255)',\n\t\t\tctx: mockContext,\n\t\t\twidth: 4,\n\t\t\tx: 10,\n\t\t\ty: 15,\n\t\t};\n\n\t\trectangle.draw();\n\n\t\texpect(mockContext.getCalls()).toEqual([{\n\t\t\tname: 'beginPath',\n\t\t\targs: [],\n\t\t}, {\n\t\t\tname: 'setFillStyle',\n\t\t\targs: ['rgb(255, 0, 0)']\n\t\t}, {\n\t\t\tname: 'setStrokeStyle',\n\t\t\targs: ['rgb(0, 0, 255)'],\n\t\t}, {\n\t\t\tname: 'setLineWidth',\n\t\t\targs: [undefined]\n\t\t}, {\n\t\t\tname: 'moveTo',\n\t\t\targs: [8, 0]\n\t\t}, {\n\t\t\tname: 'lineTo',\n\t\t\targs: [8, 15]\n\t\t}, {\n\t\t\tname: 'lineTo',\n\t\t\targs: [12, 15]\n\t\t}, {\n\t\t\tname: 'lineTo',\n\t\t\targs: [12, 0]\n\t\t}, {\n\t\t\tname: 'fill',\n\t\t\targs: [],\n\t\t}]);\n\t});\n\n\tfunction testBorderSkipped(borderSkipped, expectedDrawCalls) {\n\t\tvar mockContext = window.createMockContext();\n\t\tvar rectangle = new Chart.elements.Rectangle({\n\t\t\t_chart: {ctx: mockContext}\n\t\t});\n\n\t\t// Attach a view object as if we were the controller\n\t\trectangle._view = {\n\t\t\tborderSkipped: borderSkipped, // set tested 'borderSkipped' parameter\n\t\t\tctx: mockContext,\n\t\t\tbase: 0,\n\t\t\twidth: 4,\n\t\t\tx: 10,\n\t\t\ty: 15,\n\t\t};\n\n\t\trectangle.draw();\n\n\t\tvar drawCalls = rectangle._view.ctx.getCalls().splice(4, 4);\n\t\texpect(drawCalls).toEqual(expectedDrawCalls);\n\t}\n\n\tit ('should draw correctly respecting \"borderSkipped\" == \"bottom\"', function() {\n\t\ttestBorderSkipped ('bottom', [\n\t\t\t{name: 'moveTo', args: [8, 0]},\n\t\t\t{name: 'lineTo', args: [8, 15]},\n\t\t\t{name: 'lineTo', args: [12, 15]},\n\t\t\t{name: 'lineTo', args: [12, 0]},\n\t\t]);\n\t});\n\n\tit ('should draw correctly respecting \"borderSkipped\" == \"left\"', function() {\n\t\ttestBorderSkipped ('left', [\n\t\t\t{name: 'moveTo', args: [8, 15]},\n\t\t\t{name: 'lineTo', args: [12, 15]},\n\t\t\t{name: 'lineTo', args: [12, 0]},\n\t\t\t{name: 'lineTo', args: [8, 0]},\n\t\t]);\n\t});\n\n\tit ('should draw correctly respecting \"borderSkipped\" == \"top\"', function() {\n\t\ttestBorderSkipped ('top', [\n\t\t\t{name: 'moveTo', args: [12, 15]},\n\t\t\t{name: 'lineTo', args: [12, 0]},\n\t\t\t{name: 'lineTo', args: [8, 0]},\n\t\t\t{name: 'lineTo', args: [8, 15]},\n\t\t]);\n\t});\n\n\tit ('should draw correctly respecting \"borderSkipped\" == \"right\"', function() {\n\t\ttestBorderSkipped ('right', [\n\t\t\t{name: 'moveTo', args: [12, 0]},\n\t\t\t{name: 'lineTo', args: [8, 0]},\n\t\t\t{name: 'lineTo', args: [8, 15]},\n\t\t\t{name: 'lineTo', args: [12, 15]},\n\t\t]);\n\t});\n\n});\n"
  },
  {
    "path": "app_backend/static/plugin/Chart.js-2.6.0/test/specs/global.defaults.tests.js",
    "content": "// Test the bubble chart default config\ndescribe('Default Configs', function() {\n\tdescribe('Bubble Chart', function() {\n\t\tit('should return correct tooltip strings', function() {\n\t\t\tvar config = Chart.defaults.bubble;\n\t\t\tvar chart = window.acquireChart({\n\t\t\t\ttype: 'bubble',\n\t\t\t\tdata: {\n\t\t\t\t\tdatasets: [{\n\t\t\t\t\t\tlabel: 'My dataset',\n\t\t\t\t\t\tdata: [{\n\t\t\t\t\t\t\tx: 10,\n\t\t\t\t\t\t\ty: 12,\n\t\t\t\t\t\t\tr: 5\n\t\t\t\t\t\t}]\n\t\t\t\t\t}]\n\t\t\t\t},\n\t\t\t\toptions: config\n\t\t\t});\n\n\t\t\t// fake out the tooltip hover and force the tooltip to update\n\t\t\tchart.tooltip._active = [chart.getDatasetMeta(0).data[0]];\n\t\t\tchart.tooltip.update();\n\n\t\t\t// Title is always blank\n\t\t\texpect(chart.tooltip._model.title).toEqual([]);\n\t\t\texpect(chart.tooltip._model.body).toEqual([{\n\t\t\t\tbefore: [],\n\t\t\t\tlines: ['My dataset: (10, 12, 5)'],\n\t\t\t\tafter: []\n\t\t\t}]);\n\t\t});\n\t});\n\n\tdescribe('Doughnut Chart', function() {\n\t\tit('should return correct tooltip strings', function() {\n\t\t\tvar config = Chart.defaults.doughnut;\n\t\t\tvar chart = window.acquireChart({\n\t\t\t\ttype: 'doughnut',\n\t\t\t\tdata: {\n\t\t\t\t\tlabels: ['label1', 'label2', 'label3'],\n\t\t\t\t\tdatasets: [{\n\t\t\t\t\t\tdata: [10, 20, 30],\n\t\t\t\t\t}]\n\t\t\t\t},\n\t\t\t\toptions: config\n\t\t\t});\n\n\t\t\t// fake out the tooltip hover and force the tooltip to update\n\t\t\tchart.tooltip._active = [chart.getDatasetMeta(0).data[1]];\n\t\t\tchart.tooltip.update();\n\n\t\t\t// Title is always blank\n\t\t\texpect(chart.tooltip._model.title).toEqual([]);\n\t\t\texpect(chart.tooltip._model.body).toEqual([{\n\t\t\t\tbefore: [],\n\t\t\t\tlines: ['label2: 20'],\n\t\t\t\tafter: []\n\t\t\t}]);\n\t\t});\n\n\t\tit('should return correct tooltip string for a multiline label', function() {\n\t\t\tvar config = Chart.defaults.doughnut;\n\t\t\tvar chart = window.acquireChart({\n\t\t\t\ttype: 'doughnut',\n\t\t\t\tdata: {\n\t\t\t\t\tlabels: ['label1', ['row1', 'row2', 'row3'], 'label3'],\n\t\t\t\t\tdatasets: [{\n\t\t\t\t\t\tdata: [10, 20, 30],\n\t\t\t\t\t}]\n\t\t\t\t},\n\t\t\t\toptions: config\n\t\t\t});\n\n\t\t\t// fake out the tooltip hover and force the tooltip to update\n\t\t\tchart.tooltip._active = [chart.getDatasetMeta(0).data[1]];\n\t\t\tchart.tooltip.update();\n\n\t\t\t// Title is always blank\n\t\t\texpect(chart.tooltip._model.title).toEqual([]);\n\t\t\texpect(chart.tooltip._model.body).toEqual([{\n\t\t\t\tbefore: [],\n\t\t\t\tlines: [\n\t\t\t\t\t'row1: 20',\n\t\t\t\t\t'row2',\n\t\t\t\t\t'row3'\n\t\t\t\t],\n\t\t\t\tafter: []\n\t\t\t}]);\n\t\t});\n\n\t\tit('should return the correct html legend', function() {\n\t\t\tvar config = Chart.defaults.doughnut;\n\t\t\tvar chart = window.acquireChart({\n\t\t\t\ttype: 'doughnut',\n\t\t\t\tdata: {\n\t\t\t\t\tlabels: ['label1', 'label2'],\n\t\t\t\t\tdatasets: [{\n\t\t\t\t\t\tdata: [10, 20],\n\t\t\t\t\t\tbackgroundColor: ['red', 'green']\n\t\t\t\t\t}]\n\t\t\t\t},\n\t\t\t\toptions: config\n\t\t\t});\n\n\t\t\tvar expectedLegend = '<ul class=\"' + chart.id + '-legend\"><li><span style=\"background-color:red\"></span>label1</li><li><span style=\"background-color:green\"></span>label2</li></ul>';\n\t\t\texpect(chart.generateLegend()).toBe(expectedLegend);\n\t\t});\n\n\t\tit('should return correct legend label objects', function() {\n\t\t\tvar config = Chart.defaults.doughnut;\n\t\t\tvar chart = window.acquireChart({\n\t\t\t\ttype: 'doughnut',\n\t\t\t\tdata: {\n\t\t\t\t\tlabels: ['label1', 'label2', 'label3'],\n\t\t\t\t\tdatasets: [{\n\t\t\t\t\t\tdata: [10, 20, NaN],\n\t\t\t\t\t\tbackgroundColor: ['red', 'green', 'blue'],\n\t\t\t\t\t\tborderWidth: 2,\n\t\t\t\t\t\tborderColor: '#000'\n\t\t\t\t\t}]\n\t\t\t\t},\n\t\t\t\toptions: config\n\t\t\t});\n\n\t\t\tvar expected = [{\n\t\t\t\ttext: 'label1',\n\t\t\t\tfillStyle: 'red',\n\t\t\t\thidden: false,\n\t\t\t\tindex: 0,\n\t\t\t\tstrokeStyle: '#000',\n\t\t\t\tlineWidth: 2\n\t\t\t}, {\n\t\t\t\ttext: 'label2',\n\t\t\t\tfillStyle: 'green',\n\t\t\t\thidden: false,\n\t\t\t\tindex: 1,\n\t\t\t\tstrokeStyle: '#000',\n\t\t\t\tlineWidth: 2\n\t\t\t}, {\n\t\t\t\ttext: 'label3',\n\t\t\t\tfillStyle: 'blue',\n\t\t\t\thidden: true,\n\t\t\t\tindex: 2,\n\t\t\t\tstrokeStyle: '#000',\n\t\t\t\tlineWidth: 2\n\t\t\t}];\n\t\t\texpect(chart.legend.legendItems).toEqual(expected);\n\t\t});\n\n\t\tit('should hide the correct arc when a legend item is clicked', function() {\n\t\t\tvar config = Chart.defaults.doughnut;\n\t\t\tvar chart = window.acquireChart({\n\t\t\t\ttype: 'doughnut',\n\t\t\t\tdata: {\n\t\t\t\t\tlabels: ['label1', 'label2', 'label3'],\n\t\t\t\t\tdatasets: [{\n\t\t\t\t\t\tdata: [10, 20, NaN],\n\t\t\t\t\t\tbackgroundColor: ['red', 'green', 'blue'],\n\t\t\t\t\t\tborderWidth: 2,\n\t\t\t\t\t\tborderColor: '#000'\n\t\t\t\t\t}]\n\t\t\t\t},\n\t\t\t\toptions: config\n\t\t\t});\n\t\t\tvar meta = chart.getDatasetMeta(0);\n\n\t\t\tspyOn(chart, 'update').and.callThrough();\n\n\t\t\tvar legendItem = chart.legend.legendItems[0];\n\t\t\tconfig.legend.onClick.call(chart.legend, null, legendItem);\n\n\t\t\texpect(meta.data[0].hidden).toBe(true);\n\t\t\texpect(chart.update).toHaveBeenCalled();\n\n\t\t\tconfig.legend.onClick.call(chart.legend, null, legendItem);\n\t\t\texpect(meta.data[0].hidden).toBe(false);\n\t\t});\n\t});\n\n\tdescribe('Polar Area Chart', function() {\n\t\tit('should return correct tooltip strings', function() {\n\t\t\tvar config = Chart.defaults.polarArea;\n\t\t\tvar chart = window.acquireChart({\n\t\t\t\ttype: 'polarArea',\n\t\t\t\tdata: {\n\t\t\t\t\tlabels: ['label1', 'label2', 'label3'],\n\t\t\t\t\tdatasets: [{\n\t\t\t\t\t\tdata: [10, 20, 30],\n\t\t\t\t\t}]\n\t\t\t\t},\n\t\t\t\toptions: config\n\t\t\t});\n\n\t\t\t// fake out the tooltip hover and force the tooltip to update\n\t\t\tchart.tooltip._active = [chart.getDatasetMeta(0).data[1]];\n\t\t\tchart.tooltip.update();\n\n\t\t\t// Title is always blank\n\t\t\texpect(chart.tooltip._model.title).toEqual([]);\n\t\t\texpect(chart.tooltip._model.body).toEqual([{\n\t\t\t\tbefore: [],\n\t\t\t\tlines: ['label2: 20'],\n\t\t\t\tafter: []\n\t\t\t}]);\n\t\t});\n\n\t\tit('should return the correct html legend', function() {\n\t\t\tvar config = Chart.defaults.polarArea;\n\t\t\tvar chart = window.acquireChart({\n\t\t\t\ttype: 'polarArea',\n\t\t\t\tdata: {\n\t\t\t\t\tlabels: ['label1', 'label2'],\n\t\t\t\t\tdatasets: [{\n\t\t\t\t\t\tdata: [10, 20],\n\t\t\t\t\t\tbackgroundColor: ['red', 'green']\n\t\t\t\t\t}]\n\t\t\t\t},\n\t\t\t\toptions: config\n\t\t\t});\n\n\t\t\tvar expectedLegend = '<ul class=\"' + chart.id + '-legend\"><li><span style=\"background-color:red\"></span>label1</li><li><span style=\"background-color:green\"></span>label2</li></ul>';\n\t\t\texpect(chart.generateLegend()).toBe(expectedLegend);\n\t\t});\n\n\t\tit('should return correct legend label objects', function() {\n\t\t\tvar config = Chart.defaults.polarArea;\n\t\t\tvar chart = window.acquireChart({\n\t\t\t\ttype: 'polarArea',\n\t\t\t\tdata: {\n\t\t\t\t\tlabels: ['label1', 'label2', 'label3'],\n\t\t\t\t\tdatasets: [{\n\t\t\t\t\t\tdata: [10, 20, NaN],\n\t\t\t\t\t\tbackgroundColor: ['red', 'green', 'blue'],\n\t\t\t\t\t\tborderWidth: 2,\n\t\t\t\t\t\tborderColor: '#000'\n\t\t\t\t\t}]\n\t\t\t\t},\n\t\t\t\toptions: config\n\t\t\t});\n\n\t\t\tvar expected = [{\n\t\t\t\ttext: 'label1',\n\t\t\t\tfillStyle: 'red',\n\t\t\t\thidden: false,\n\t\t\t\tindex: 0,\n\t\t\t\tstrokeStyle: '#000',\n\t\t\t\tlineWidth: 2\n\t\t\t}, {\n\t\t\t\ttext: 'label2',\n\t\t\t\tfillStyle: 'green',\n\t\t\t\thidden: false,\n\t\t\t\tindex: 1,\n\t\t\t\tstrokeStyle: '#000',\n\t\t\t\tlineWidth: 2\n\t\t\t}, {\n\t\t\t\ttext: 'label3',\n\t\t\t\tfillStyle: 'blue',\n\t\t\t\thidden: true,\n\t\t\t\tindex: 2,\n\t\t\t\tstrokeStyle: '#000',\n\t\t\t\tlineWidth: 2\n\t\t\t}];\n\t\t\texpect(chart.legend.legendItems).toEqual(expected);\n\t\t});\n\n\t\tit('should hide the correct arc when a legend item is clicked', function() {\n\t\t\tvar config = Chart.defaults.polarArea;\n\t\t\tvar chart = window.acquireChart({\n\t\t\t\ttype: 'polarArea',\n\t\t\t\tdata: {\n\t\t\t\t\tlabels: ['label1', 'label2', 'label3'],\n\t\t\t\t\tdatasets: [{\n\t\t\t\t\t\tdata: [10, 20, NaN],\n\t\t\t\t\t\tbackgroundColor: ['red', 'green', 'blue'],\n\t\t\t\t\t\tborderWidth: 2,\n\t\t\t\t\t\tborderColor: '#000'\n\t\t\t\t\t}]\n\t\t\t\t},\n\t\t\t\toptions: config\n\t\t\t});\n\t\t\tvar meta = chart.getDatasetMeta(0);\n\n\t\t\tspyOn(chart, 'update').and.callThrough();\n\n\t\t\tvar legendItem = chart.legend.legendItems[0];\n\t\t\tconfig.legend.onClick.call(chart.legend, null, legendItem);\n\n\t\t\texpect(meta.data[0].hidden).toBe(true);\n\t\t\texpect(chart.update).toHaveBeenCalled();\n\n\t\t\tconfig.legend.onClick.call(chart.legend, null, legendItem);\n\t\t\texpect(meta.data[0].hidden).toBe(false);\n\t\t});\n\t});\n});\n"
  },
  {
    "path": "app_backend/static/plugin/Chart.js-2.6.0/test/specs/global.deprecations.tests.js",
    "content": "describe('Deprecations', function() {\n\tdescribe('Version 2.6.0', function() {\n\t\t// https://github.com/chartjs/Chart.js/issues/2481\n\t\tdescribe('Chart.Controller', function() {\n\t\t\tit('should be defined and an alias of Chart', function() {\n\t\t\t\texpect(Chart.Controller).toBeDefined();\n\t\t\t\texpect(Chart.Controller).toBe(Chart);\n\t\t\t});\n\t\t\tit('should be prototype of chart instances', function() {\n\t\t\t\tvar chart = acquireChart({});\n\t\t\t\texpect(chart.constructor).toBe(Chart.Controller);\n\t\t\t\texpect(chart instanceof Chart.Controller).toBeTruthy();\n\t\t\t\texpect(Chart.Controller.prototype.isPrototypeOf(chart)).toBeTruthy();\n\t\t\t});\n\t\t});\n\n\t\tdescribe('chart.chart', function() {\n\t\t\tit('should be defined and an alias of chart', function() {\n\t\t\t\tvar chart = acquireChart({});\n\t\t\t\tvar proxy = chart.chart;\n\t\t\t\texpect(proxy).toBeDefined();\n\t\t\t\texpect(proxy).toBe(chart);\n\t\t\t});\n\t\t\tit('should defined previously existing properties', function() {\n\t\t\t\tvar chart = acquireChart({}, {\n\t\t\t\t\tcanvas: {\n\t\t\t\t\t\tstyle: 'width: 140px; height: 320px'\n\t\t\t\t\t}\n\t\t\t\t});\n\n\t\t\t\tvar proxy = chart.chart;\n\t\t\t\texpect(proxy.config instanceof Object).toBeTruthy();\n\t\t\t\texpect(proxy.controller instanceof Chart.Controller).toBeTruthy();\n\t\t\t\texpect(proxy.canvas instanceof HTMLCanvasElement).toBeTruthy();\n\t\t\t\texpect(proxy.ctx instanceof CanvasRenderingContext2D).toBeTruthy();\n\t\t\t\texpect(proxy.currentDevicePixelRatio).toBe(window.devicePixelRatio || 1);\n\t\t\t\texpect(proxy.aspectRatio).toBe(140/320);\n\t\t\t\texpect(proxy.height).toBe(320);\n\t\t\t\texpect(proxy.width).toBe(140);\n\t\t\t});\n\t\t});\n\n\t\tdescribe('Chart.Animation.animationObject', function() {\n\t\t\tit('should be defined and an alias of Chart.Animation', function(done) {\n\t\t\t\tvar animation = null;\n\n\t\t\t\tacquireChart({\n\t\t\t\t\toptions: {\n\t\t\t\t\t\tanimation: {\n\t\t\t\t\t\t\tduration: 50,\n\t\t\t\t\t\t\tonComplete: function(arg) {\n\t\t\t\t\t\t\t\tanimation = arg;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t});\n\n\t\t\t\tsetTimeout(function() {\n\t\t\t\t\texpect(animation).not.toBeNull();\n\t\t\t\t\texpect(animation.animationObject).toBeDefined();\n\t\t\t\t\texpect(animation.animationObject).toBe(animation);\n\t\t\t\t\tdone();\n\t\t\t\t}, 200);\n\t\t\t});\n\t\t});\n\n\t\tdescribe('Chart.Animation.chartInstance', function() {\n\t\t\tit('should be defined and an alias of Chart.Animation.chart', function(done) {\n\t\t\t\tvar animation = null;\n\t\t\t\tvar chart = acquireChart({\n\t\t\t\t\toptions: {\n\t\t\t\t\t\tanimation: {\n\t\t\t\t\t\t\tduration: 50,\n\t\t\t\t\t\t\tonComplete: function(arg) {\n\t\t\t\t\t\t\t\tanimation = arg;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t});\n\n\t\t\t\tsetTimeout(function() {\n\t\t\t\t\texpect(animation).not.toBeNull();\n\t\t\t\t\texpect(animation.chartInstance).toBeDefined();\n\t\t\t\t\texpect(animation.chartInstance).toBe(chart);\n\t\t\t\t\tdone();\n\t\t\t\t}, 200);\n\t\t\t});\n\t\t});\n\n\t\tdescribe('Chart.elements.Line: fill option', function() {\n\t\t\tit('should decode \"zero\", \"top\" and \"bottom\" as \"origin\", \"start\" and \"end\"', function() {\n\t\t\t\tvar chart = window.acquireChart({\n\t\t\t\t\ttype: 'line',\n\t\t\t\t\tdata: {\n\t\t\t\t\t\tdatasets: [\n\t\t\t\t\t\t\t{fill: 'zero'},\n\t\t\t\t\t\t\t{fill: 'bottom'},\n\t\t\t\t\t\t\t{fill: 'top'},\n\t\t\t\t\t\t]\n\t\t\t\t\t}\n\t\t\t\t});\n\n\t\t\t\t['origin', 'start', 'end'].forEach(function(expected, index) {\n\t\t\t\t\tvar meta = chart.getDatasetMeta(index);\n\t\t\t\t\texpect(meta.$filler).toBeDefined();\n\t\t\t\t\texpect(meta.$filler.fill).toBe(expected);\n\t\t\t\t});\n\t\t\t});\n\t\t});\n\t});\n\n\tdescribe('Version 2.5.0', function() {\n\t\tdescribe('Chart.PluginBase', function() {\n\t\t\tit('should exist and extendable', function() {\n\t\t\t\texpect(Chart.PluginBase).toBeDefined();\n\t\t\t\texpect(Chart.PluginBase.extend).toBeDefined();\n\t\t\t});\n\t\t});\n\n\t\tdescribe('IPlugin.afterScaleUpdate', function() {\n\t\t\tit('should be called after the chart as been layed out', function() {\n\t\t\t\tvar sequence = [];\n\t\t\t\tvar plugin = {};\n\t\t\t\tvar hooks = [\n\t\t\t\t\t'beforeLayout',\n\t\t\t\t\t'afterScaleUpdate',\n\t\t\t\t\t'afterLayout'\n\t\t\t\t];\n\n\t\t\t\tvar override = Chart.layoutService.update;\n\t\t\t\tChart.layoutService.update = function() {\n\t\t\t\t\tsequence.push('layoutUpdate');\n\t\t\t\t\toverride.apply(this, arguments);\n\t\t\t\t};\n\n\t\t\t\thooks.forEach(function(name) {\n\t\t\t\t\tplugin[name] = function() {\n\t\t\t\t\t\tsequence.push(name);\n\t\t\t\t\t};\n\t\t\t\t});\n\n\t\t\t\twindow.acquireChart({plugins: [plugin]});\n\t\t\t\texpect(sequence).toEqual([].concat(\n\t\t\t\t\t'beforeLayout',\n\t\t\t\t\t'layoutUpdate',\n\t\t\t\t\t'afterScaleUpdate',\n\t\t\t\t\t'afterLayout'\n\t\t\t\t));\n\t\t\t});\n\t\t});\n\t});\n\n\tdescribe('Version 2.1.5', function() {\n\t\t// https://github.com/chartjs/Chart.js/pull/2752\n\t\tdescribe('Chart.pluginService', function() {\n\t\t\tit('should be defined and an alias of Chart.plugins', function() {\n\t\t\t\texpect(Chart.pluginService).toBeDefined();\n\t\t\t\texpect(Chart.pluginService).toBe(Chart.plugins);\n\t\t\t});\n\t\t});\n\t});\n});\n"
  },
  {
    "path": "app_backend/static/plugin/Chart.js-2.6.0/test/specs/platform.dom.tests.js",
    "content": "describe('Platform.dom', function() {\n\n\tfunction waitForResize(chart, callback) {\n\t\tvar resizer = chart.canvas.parentNode._chartjs.resizer;\n\t\tvar content = resizer.contentWindow || resizer;\n\t\tvar state = content.document.readyState || 'complete';\n\t\tvar handler = function() {\n\t\t\tChart.helpers.removeEvent(content, 'load', handler);\n\t\t\tChart.helpers.removeEvent(content, 'resize', handler);\n\t\t\tsetTimeout(callback, 50);\n\t\t};\n\n\t\tChart.helpers.addEvent(content, state !== 'complete'? 'load' : 'resize', handler);\n\t}\n\n\tdescribe('context acquisition', function() {\n\t\tvar canvasId = 'chartjs-canvas';\n\n\t\tbeforeEach(function() {\n\t\t\tvar canvas = document.createElement('canvas');\n\t\t\tcanvas.setAttribute('id', canvasId);\n\t\t\twindow.document.body.appendChild(canvas);\n\t\t});\n\n\t\tafterEach(function() {\n\t\t\tdocument.getElementById(canvasId).remove();\n\t\t});\n\n\t\t// see https://github.com/chartjs/Chart.js/issues/2807\n\t\tit('should gracefully handle invalid item', function() {\n\t\t\tvar chart = new Chart('foobar');\n\n\t\t\texpect(chart).not.toBeValidChart();\n\n\t\t\tchart.destroy();\n\t\t});\n\n\t\tit('should accept a DOM element id', function() {\n\t\t\tvar canvas = document.getElementById(canvasId);\n\t\t\tvar chart = new Chart(canvasId);\n\n\t\t\texpect(chart).toBeValidChart();\n\t\t\texpect(chart.canvas).toBe(canvas);\n\t\t\texpect(chart.ctx).toBe(canvas.getContext('2d'));\n\n\t\t\tchart.destroy();\n\t\t});\n\n\t\tit('should accept a canvas element', function() {\n\t\t\tvar canvas = document.getElementById(canvasId);\n\t\t\tvar chart = new Chart(canvas);\n\n\t\t\texpect(chart).toBeValidChart();\n\t\t\texpect(chart.canvas).toBe(canvas);\n\t\t\texpect(chart.ctx).toBe(canvas.getContext('2d'));\n\n\t\t\tchart.destroy();\n\t\t});\n\n\t\tit('should accept a canvas context2D', function() {\n\t\t\tvar canvas = document.getElementById(canvasId);\n\t\t\tvar context = canvas.getContext('2d');\n\t\t\tvar chart = new Chart(context);\n\n\t\t\texpect(chart).toBeValidChart();\n\t\t\texpect(chart.canvas).toBe(canvas);\n\t\t\texpect(chart.ctx).toBe(context);\n\n\t\t\tchart.destroy();\n\t\t});\n\n\t\tit('should accept an array containing canvas', function() {\n\t\t\tvar canvas = document.getElementById(canvasId);\n\t\t\tvar chart = new Chart([canvas]);\n\n\t\t\texpect(chart).toBeValidChart();\n\t\t\texpect(chart.canvas).toBe(canvas);\n\t\t\texpect(chart.ctx).toBe(canvas.getContext('2d'));\n\n\t\t\tchart.destroy();\n\t\t});\n\n\t\tit('should accept a canvas from an iframe', function(done) {\n\t\t\tvar iframe = document.createElement('iframe');\n\t\t\tiframe.onload = function() {\n\t\t\t\tvar doc = iframe.contentDocument;\n\t\t\t\tdoc.body.innerHTML += '<canvas id=\"chart\"></canvas>';\n\t\t\t\tvar canvas = doc.getElementById('chart');\n\t\t\t\tvar chart = new Chart(canvas);\n\n\t\t\t\texpect(chart).toBeValidChart();\n\t\t\t\texpect(chart.canvas).toBe(canvas);\n\t\t\t\texpect(chart.ctx).toBe(canvas.getContext('2d'));\n\n\t\t\t\tchart.destroy();\n\t\t\t\tcanvas.remove();\n\t\t\t\tiframe.remove();\n\n\t\t\t\tdone();\n\t\t\t};\n\n\t\t\tdocument.body.appendChild(iframe);\n\t\t});\n\t});\n\n\tdescribe('config.options.aspectRatio', function() {\n\t\tit('should use default \"global\" aspect ratio for render and display sizes', function() {\n\t\t\tvar chart = acquireChart({\n\t\t\t\toptions: {\n\t\t\t\t\tresponsive: false\n\t\t\t\t}\n\t\t\t}, {\n\t\t\t\tcanvas: {\n\t\t\t\t\tstyle: 'width: 620px'\n\t\t\t\t}\n\t\t\t});\n\n\t\t\texpect(chart).toBeChartOfSize({\n\t\t\t\tdw: 620, dh: 310,\n\t\t\t\trw: 620, rh: 310,\n\t\t\t});\n\t\t});\n\n\t\tit('should use default \"chart\" aspect ratio for render and display sizes', function() {\n\t\t\tvar chart = acquireChart({\n\t\t\t\ttype: 'doughnut',\n\t\t\t\toptions: {\n\t\t\t\t\tresponsive: false\n\t\t\t\t}\n\t\t\t}, {\n\t\t\t\tcanvas: {\n\t\t\t\t\tstyle: 'width: 425px'\n\t\t\t\t}\n\t\t\t});\n\n\t\t\texpect(chart).toBeChartOfSize({\n\t\t\t\tdw: 425, dh: 425,\n\t\t\t\trw: 425, rh: 425,\n\t\t\t});\n\t\t});\n\n\t\tit('should use \"user\" aspect ratio for render and display sizes', function() {\n\t\t\tvar chart = acquireChart({\n\t\t\t\toptions: {\n\t\t\t\t\tresponsive: false,\n\t\t\t\t\taspectRatio: 3\n\t\t\t\t}\n\t\t\t}, {\n\t\t\t\tcanvas: {\n\t\t\t\t\tstyle: 'width: 405px'\n\t\t\t\t}\n\t\t\t});\n\n\t\t\texpect(chart).toBeChartOfSize({\n\t\t\t\tdw: 405, dh: 135,\n\t\t\t\trw: 405, rh: 135,\n\t\t\t});\n\t\t});\n\n\t\tit('should not apply aspect ratio when height specified', function() {\n\t\t\tvar chart = acquireChart({\n\t\t\t\toptions: {\n\t\t\t\t\tresponsive: false,\n\t\t\t\t\taspectRatio: 3\n\t\t\t\t}\n\t\t\t}, {\n\t\t\t\tcanvas: {\n\t\t\t\t\tstyle: 'width: 400px; height: 410px'\n\t\t\t\t}\n\t\t\t});\n\n\t\t\texpect(chart).toBeChartOfSize({\n\t\t\t\tdw: 400, dh: 410,\n\t\t\t\trw: 400, rh: 410,\n\t\t\t});\n\t\t});\n\t});\n\n\tdescribe('config.options.responsive: false', function() {\n\t\tit('should use default canvas size for render and display sizes', function() {\n\t\t\tvar chart = acquireChart({\n\t\t\t\toptions: {\n\t\t\t\t\tresponsive: false\n\t\t\t\t}\n\t\t\t}, {\n\t\t\t\tcanvas: {\n\t\t\t\t\tstyle: ''\n\t\t\t\t}\n\t\t\t});\n\n\t\t\texpect(chart).toBeChartOfSize({\n\t\t\t\tdw: 300, dh: 150,\n\t\t\t\trw: 300, rh: 150,\n\t\t\t});\n\t\t});\n\n\t\tit('should use canvas attributes for render and display sizes', function() {\n\t\t\tvar chart = acquireChart({\n\t\t\t\toptions: {\n\t\t\t\t\tresponsive: false\n\t\t\t\t}\n\t\t\t}, {\n\t\t\t\tcanvas: {\n\t\t\t\t\tstyle: '',\n\t\t\t\t\twidth: 305,\n\t\t\t\t\theight: 245,\n\t\t\t\t}\n\t\t\t});\n\n\t\t\texpect(chart).toBeChartOfSize({\n\t\t\t\tdw: 305, dh: 245,\n\t\t\t\trw: 305, rh: 245,\n\t\t\t});\n\t\t});\n\n\t\tit('should use canvas style for render and display sizes (if no attributes)', function() {\n\t\t\tvar chart = acquireChart({\n\t\t\t\toptions: {\n\t\t\t\t\tresponsive: false\n\t\t\t\t}\n\t\t\t}, {\n\t\t\t\tcanvas: {\n\t\t\t\t\tstyle: 'width: 345px; height: 125px'\n\t\t\t\t}\n\t\t\t});\n\n\t\t\texpect(chart).toBeChartOfSize({\n\t\t\t\tdw: 345, dh: 125,\n\t\t\t\trw: 345, rh: 125,\n\t\t\t});\n\t\t});\n\n\t\tit('should use attributes for the render size and style for the display size', function() {\n\t\t\tvar chart = acquireChart({\n\t\t\t\toptions: {\n\t\t\t\t\tresponsive: false\n\t\t\t\t}\n\t\t\t}, {\n\t\t\t\tcanvas: {\n\t\t\t\t\tstyle: 'width: 345px; height: 125px;',\n\t\t\t\t\twidth: 165,\n\t\t\t\t\theight: 85,\n\t\t\t\t}\n\t\t\t});\n\n\t\t\texpect(chart).toBeChartOfSize({\n\t\t\t\tdw: 345, dh: 125,\n\t\t\t\trw: 165, rh: 85,\n\t\t\t});\n\t\t});\n\n\t\t// https://github.com/chartjs/Chart.js/issues/3860\n\t\tit('should support decimal display width and/or height', function() {\n\t\t\tvar chart = acquireChart({\n\t\t\t\toptions: {\n\t\t\t\t\tresponsive: false\n\t\t\t\t}\n\t\t\t}, {\n\t\t\t\tcanvas: {\n\t\t\t\t\tstyle: 'width: 345.42px; height: 125.42px;'\n\t\t\t\t}\n\t\t\t});\n\n\t\t\texpect(chart).toBeChartOfSize({\n\t\t\t\tdw: 345, dh: 125,\n\t\t\t\trw: 345, rh: 125,\n\t\t\t});\n\t\t});\n\t});\n\n\tdescribe('config.options.responsive: true (maintainAspectRatio: true)', function() {\n\t\tit('should fill parent width and use aspect ratio to calculate height', function() {\n\t\t\tvar chart = acquireChart({\n\t\t\t\toptions: {\n\t\t\t\t\tresponsive: true,\n\t\t\t\t\tmaintainAspectRatio: true\n\t\t\t\t}\n\t\t\t}, {\n\t\t\t\tcanvas: {\n\t\t\t\t\tstyle: 'width: 150px; height: 245px'\n\t\t\t\t},\n\t\t\t\twrapper: {\n\t\t\t\t\tstyle: 'width: 300px; height: 350px'\n\t\t\t\t}\n\t\t\t});\n\n\t\t\texpect(chart).toBeChartOfSize({\n\t\t\t\tdw: 300, dh: 490,\n\t\t\t\trw: 300, rh: 490,\n\t\t\t});\n\t\t});\n\t});\n\n\tdescribe('controller.destroy', function() {\n\t\tit('should reset context to default values', function() {\n\t\t\tvar chart = acquireChart({});\n\t\t\tvar context = chart.ctx;\n\n\t\t\tchart.destroy();\n\n\t\t\t// https://www.w3.org/TR/2dcontext/#conformance-requirements\n\t\t\tChart.helpers.each({\n\t\t\t\tfillStyle: '#000000',\n\t\t\t\tfont: '10px sans-serif',\n\t\t\t\tlineJoin: 'miter',\n\t\t\t\tlineCap: 'butt',\n\t\t\t\tlineWidth: 1,\n\t\t\t\tmiterLimit: 10,\n\t\t\t\tshadowBlur: 0,\n\t\t\t\tshadowColor: 'rgba(0, 0, 0, 0)',\n\t\t\t\tshadowOffsetX: 0,\n\t\t\t\tshadowOffsetY: 0,\n\t\t\t\tstrokeStyle: '#000000',\n\t\t\t\ttextAlign: 'start',\n\t\t\t\ttextBaseline: 'alphabetic'\n\t\t\t}, function(value, key) {\n\t\t\t\texpect(context[key]).toBe(value);\n\t\t\t});\n\t\t});\n\n\t\tit('should restore canvas initial values', function(done) {\n\t\t\tvar chart = acquireChart({\n\t\t\t\toptions: {\n\t\t\t\t\tresponsive: true,\n\t\t\t\t\tmaintainAspectRatio: false\n\t\t\t\t}\n\t\t\t}, {\n\t\t\t\tcanvas: {\n\t\t\t\t\twidth: 180,\n\t\t\t\t\tstyle: 'width: 512px; height: 480px'\n\t\t\t\t},\n\t\t\t\twrapper: {\n\t\t\t\t\tstyle: 'width: 450px; height: 450px; position: relative'\n\t\t\t\t}\n\t\t\t});\n\n\t\t\tvar canvas = chart.canvas;\n\t\t\tvar wrapper = canvas.parentNode;\n\t\t\twrapper.style.width = '475px';\n\t\t\twaitForResize(chart, function() {\n\t\t\t\texpect(chart).toBeChartOfSize({\n\t\t\t\t\tdw: 475, dh: 450,\n\t\t\t\t\trw: 475, rh: 450,\n\t\t\t\t});\n\n\t\t\t\tchart.destroy();\n\n\t\t\t\texpect(canvas.getAttribute('width')).toBe('180');\n\t\t\t\texpect(canvas.getAttribute('height')).toBe(null);\n\t\t\t\texpect(canvas.style.width).toBe('512px');\n\t\t\t\texpect(canvas.style.height).toBe('480px');\n\t\t\t\texpect(canvas.style.display).toBe('');\n\n\t\t\t\tdone();\n\t\t\t});\n\t\t});\n\t});\n\n\tdescribe('event handling', function() {\n\t\tit('should notify plugins about events', function() {\n\t\t\tvar notifiedEvent;\n\t\t\tvar plugin = {\n\t\t\t\tafterEvent: function(chart, e) {\n\t\t\t\t\tnotifiedEvent = e;\n\t\t\t\t}\n\t\t\t};\n\t\t\tvar chart = acquireChart({\n\t\t\t\ttype: 'line',\n\t\t\t\tdata: {\n\t\t\t\t\tlabels: ['A', 'B', 'C', 'D'],\n\t\t\t\t\tdatasets: [{\n\t\t\t\t\t\tdata: [10, 20, 30, 100]\n\t\t\t\t\t}]\n\t\t\t\t},\n\t\t\t\toptions: {\n\t\t\t\t\tresponsive: true\n\t\t\t\t},\n\t\t\t\tplugins: [plugin]\n\t\t\t});\n\n\t\t\tvar node = chart.canvas;\n\t\t\tvar rect = node.getBoundingClientRect();\n\t\t\tvar clientX = (rect.left + rect.right) / 2;\n\t\t\tvar clientY = (rect.top + rect.bottom) / 2;\n\n\t\t\tvar evt = new MouseEvent('click', {\n\t\t\t\tview: window,\n\t\t\t\tbubbles: true,\n\t\t\t\tcancelable: true,\n\t\t\t\tclientX: clientX,\n\t\t\t\tclientY: clientY\n\t\t\t});\n\n\t\t\t// Manually trigger rather than having an async test\n\t\t\tnode.dispatchEvent(evt);\n\n\t\t\t// Check that notifiedEvent is correct\n\t\t\texpect(notifiedEvent).not.toBe(undefined);\n\t\t\texpect(notifiedEvent.native).toBe(evt);\n\n\t\t\t// Is type correctly translated\n\t\t\texpect(notifiedEvent.type).toBe(evt.type);\n\n\t\t\t// Relative Position\n\t\t\texpect(notifiedEvent.x).toBe(chart.width / 2);\n\t\t\texpect(notifiedEvent.y).toBe(chart.height / 2);\n\t\t});\n\t});\n});\n"
  },
  {
    "path": "app_backend/static/plugin/Chart.js-2.6.0/test/specs/plugin.filler.tests.js",
    "content": "describe('Plugin.filler', function() {\n\tfunction decodedFillValues(chart) {\n\t\treturn chart.data.datasets.map(function(dataset, index) {\n\t\t\tvar meta = chart.getDatasetMeta(index) || {};\n\t\t\texpect(meta.$filler).toBeDefined();\n\t\t\treturn meta.$filler.fill;\n\t\t});\n\t}\n\n\tdescribe('auto', jasmine.specsFromFixtures('plugin.filler'));\n\n\tdescribe('dataset.fill', function() {\n\t\tit('should support boundaries', function() {\n\t\t\tvar chart = window.acquireChart({\n\t\t\t\ttype: 'line',\n\t\t\t\tdata: {\n\t\t\t\t\tdatasets: [\n\t\t\t\t\t\t{fill: 'origin'},\n\t\t\t\t\t\t{fill: 'start'},\n\t\t\t\t\t\t{fill: 'end'},\n\t\t\t\t\t]\n\t\t\t\t}\n\t\t\t});\n\n\t\t\texpect(decodedFillValues(chart)).toEqual(['origin', 'start', 'end']);\n\t\t});\n\n\t\tit('should support absolute dataset index', function() {\n\t\t\tvar chart = window.acquireChart({\n\t\t\t\ttype: 'line',\n\t\t\t\tdata: {\n\t\t\t\t\tdatasets: [\n\t\t\t\t\t\t{fill: 1},\n\t\t\t\t\t\t{fill: 3},\n\t\t\t\t\t\t{fill: 0},\n\t\t\t\t\t\t{fill: 2},\n\t\t\t\t\t]\n\t\t\t\t}\n\t\t\t});\n\n\t\t\texpect(decodedFillValues(chart)).toEqual([1, 3, 0, 2]);\n\t\t});\n\n\t\tit('should support relative dataset index', function() {\n\t\t\tvar chart = window.acquireChart({\n\t\t\t\ttype: 'line',\n\t\t\t\tdata: {\n\t\t\t\t\tdatasets: [\n\t\t\t\t\t\t{fill: '+3'},\n\t\t\t\t\t\t{fill: '-1'},\n\t\t\t\t\t\t{fill: '+1'},\n\t\t\t\t\t\t{fill: '-2'},\n\t\t\t\t\t]\n\t\t\t\t}\n\t\t\t});\n\n\t\t\texpect(decodedFillValues(chart)).toEqual([\n\t\t\t\t3, // 0 + 3\n\t\t\t\t0, // 1 - 1\n\t\t\t\t3, // 2 + 1\n\t\t\t\t1, // 3 - 2\n\t\t\t]);\n\t\t});\n\n\t\tit('should handle default fill when true (origin)', function() {\n\t\t\tvar chart = window.acquireChart({\n\t\t\t\ttype: 'line',\n\t\t\t\tdata: {\n\t\t\t\t\tdatasets: [\n\t\t\t\t\t\t{fill: true},\n\t\t\t\t\t\t{fill: false},\n\t\t\t\t\t]\n\t\t\t\t}\n\t\t\t});\n\n\t\t\texpect(decodedFillValues(chart)).toEqual(['origin', false]);\n\t\t});\n\n\t\tit('should ignore self dataset index', function() {\n\t\t\tvar chart = window.acquireChart({\n\t\t\t\ttype: 'line',\n\t\t\t\tdata: {\n\t\t\t\t\tdatasets: [\n\t\t\t\t\t\t{fill: 0},\n\t\t\t\t\t\t{fill: '-0'},\n\t\t\t\t\t\t{fill: '+0'},\n\t\t\t\t\t\t{fill: 3},\n\t\t\t\t\t]\n\t\t\t\t}\n\t\t\t});\n\n\t\t\texpect(decodedFillValues(chart)).toEqual([\n\t\t\t\tfalse, // 0 === 0\n\t\t\t\tfalse, // 1 === 1 - 0\n\t\t\t\tfalse, // 2 === 2 + 0\n\t\t\t\tfalse, // 3 === 3\n\t\t\t]);\n\t\t});\n\n\t\tit('should ignore out of bounds dataset index', function() {\n\t\t\tvar chart = window.acquireChart({\n\t\t\t\ttype: 'line',\n\t\t\t\tdata: {\n\t\t\t\t\tdatasets: [\n\t\t\t\t\t\t{fill: -2},\n\t\t\t\t\t\t{fill: 4},\n\t\t\t\t\t\t{fill: '-3'},\n\t\t\t\t\t\t{fill: '+1'},\n\t\t\t\t\t]\n\t\t\t\t}\n\t\t\t});\n\n\t\t\texpect(decodedFillValues(chart)).toEqual([\n\t\t\t\tfalse, // 0 - 2 < 0\n\t\t\t\tfalse, // 1 + 4 > 3\n\t\t\t\tfalse, // 2 - 3 < 0\n\t\t\t\tfalse, // 3 + 1 > 3\n\t\t\t]);\n\t\t});\n\n\t\tit('should ignore invalid values', function() {\n\t\t\tvar chart = window.acquireChart({\n\t\t\t\ttype: 'line',\n\t\t\t\tdata: {\n\t\t\t\t\tdatasets: [\n\t\t\t\t\t\t{fill: 'foo'},\n\t\t\t\t\t\t{fill: '+foo'},\n\t\t\t\t\t\t{fill: '-foo'},\n\t\t\t\t\t\t{fill: '+1.1'},\n\t\t\t\t\t\t{fill: '-2.2'},\n\t\t\t\t\t\t{fill: 3.3},\n\t\t\t\t\t\t{fill: -4.4},\n\t\t\t\t\t\t{fill: NaN},\n\t\t\t\t\t\t{fill: Infinity},\n\t\t\t\t\t\t{fill: ''},\n\t\t\t\t\t\t{fill: null},\n\t\t\t\t\t\t{fill: []},\n\t\t\t\t\t\t{fill: {}},\n\t\t\t\t\t\t{fill: function() {}}\n\t\t\t\t\t]\n\t\t\t\t}\n\t\t\t});\n\n\t\t\texpect(decodedFillValues(chart)).toEqual([\n\t\t\t\tfalse, // NaN (string)\n\t\t\t\tfalse, // NaN (string)\n\t\t\t\tfalse, // NaN (string)\n\t\t\t\tfalse, // float (string)\n\t\t\t\tfalse, // float (string)\n\t\t\t\tfalse, // float (number)\n\t\t\t\tfalse, // float (number)\n\t\t\t\tfalse, // NaN\n\t\t\t\tfalse, // !isFinite\n\t\t\t\tfalse, // empty string\n\t\t\t\tfalse, // null\n\t\t\t\tfalse, // array\n\t\t\t\tfalse, // object\n\t\t\t\tfalse, // function\n\t\t\t]);\n\t\t});\n\t});\n\n\tdescribe('options.plugins.filler.propagate', function() {\n\t\tit('should compute propagated fill targets if true', function() {\n\t\t\tvar chart = window.acquireChart({\n\t\t\t\ttype: 'line',\n\t\t\t\tdata: {\n\t\t\t\t\tdatasets: [\n\t\t\t\t\t\t{fill: 'start', hidden: true},\n\t\t\t\t\t\t{fill: '-1', hidden: true},\n\t\t\t\t\t\t{fill: 1, hidden: true},\n\t\t\t\t\t\t{fill: '-2', hidden: true},\n\t\t\t\t\t\t{fill: '+1'},\n\t\t\t\t\t\t{fill: '+2'},\n\t\t\t\t\t\t{fill: '-1'},\n\t\t\t\t\t\t{fill: 'end', hidden: true},\n\t\t\t\t\t]\n\t\t\t\t},\n\t\t\t\toptions: {\n\t\t\t\t\tplugins: {\n\t\t\t\t\t\tfiller: {\n\t\t\t\t\t\t\tpropagate: true\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t});\n\n\n\t\t\texpect(decodedFillValues(chart)).toEqual([\n\t\t\t\t'start', // 'start'\n\t\t\t\t'start', // 1 - 1 -> 0 (hidden) -> 'start'\n\t\t\t\t'start', // 1 (hidden) -> 0 (hidden) -> 'start'\n\t\t\t\t'start', // 3 - 2 -> 1 (hidden) -> 0 (hidden) -> 'start'\n\t\t\t\t5,       // 4 + 1\n\t\t\t\t'end',   // 5 + 2 -> 7 (hidden) -> 'end'\n\t\t\t\t5,       // 6 - 1 -> 5\n\t\t\t\t'end',   // 'end'\n\t\t\t]);\n\t\t});\n\n\t\tit('should preserve initial fill targets if false', function() {\n\t\t\tvar chart = window.acquireChart({\n\t\t\t\ttype: 'line',\n\t\t\t\tdata: {\n\t\t\t\t\tdatasets: [\n\t\t\t\t\t\t{fill: 'start', hidden: true},\n\t\t\t\t\t\t{fill: '-1', hidden: true},\n\t\t\t\t\t\t{fill: 1, hidden: true},\n\t\t\t\t\t\t{fill: '-2', hidden: true},\n\t\t\t\t\t\t{fill: '+1'},\n\t\t\t\t\t\t{fill: '+2'},\n\t\t\t\t\t\t{fill: '-1'},\n\t\t\t\t\t\t{fill: 'end', hidden: true},\n\t\t\t\t\t]\n\t\t\t\t},\n\t\t\t\toptions: {\n\t\t\t\t\tplugins: {\n\t\t\t\t\t\tfiller: {\n\t\t\t\t\t\t\tpropagate: false\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t});\n\n\t\t\texpect(decodedFillValues(chart)).toEqual([\n\t\t\t\t'start', // 'origin'\n\t\t\t\t0,       // 1 - 1\n\t\t\t\t1,       // 1\n\t\t\t\t1,       // 3 - 2\n\t\t\t\t5,       // 4 + 1\n\t\t\t\t7,       // 5 + 2\n\t\t\t\t5,       // 6 - 1\n\t\t\t\t'end',   // 'end'\n\t\t\t]);\n\t\t});\n\n\t\tit('should prevent recursive propagation', function() {\n\t\t\tvar chart = window.acquireChart({\n\t\t\t\ttype: 'line',\n\t\t\t\tdata: {\n\t\t\t\t\tdatasets: [\n\t\t\t\t\t\t{fill: '+2', hidden: true},\n\t\t\t\t\t\t{fill: '-1', hidden: true},\n\t\t\t\t\t\t{fill: '-1', hidden: true},\n\t\t\t\t\t\t{fill: '-2'}\n\t\t\t\t\t]\n\t\t\t\t},\n\t\t\t\toptions: {\n\t\t\t\t\tplugins: {\n\t\t\t\t\t\tfiller: {\n\t\t\t\t\t\t\tpropagate: true\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t});\n\n\t\t\texpect(decodedFillValues(chart)).toEqual([\n\t\t\t\tfalse, // 0 + 2 -> 2 (hidden) -> 1 (hidden) -> 0 (loop)\n\t\t\t\tfalse, // 1 - 1 -> 0 (hidden) -> 2 (hidden) -> 1 (loop)\n\t\t\t\tfalse, // 2 - 1 -> 1 (hidden) -> 0 (hidden) -> 2 (loop)\n\t\t\t\tfalse, // 3 - 2 -> 1 (hidden) -> 0 (hidden) -> 2 (hidden) -> 1 (loop)\n\t\t\t]);\n\t\t});\n\t});\n});\n"
  },
  {
    "path": "app_backend/static/plugin/Chart.js-2.6.0/test/specs/plugin.legend.tests.js",
    "content": "// Test the rectangle element\ndescribe('Legend block tests', function() {\n\tit('Should be constructed', function() {\n\t\tvar legend = new Chart.Legend({});\n\t\texpect(legend).not.toBe(undefined);\n\t});\n\n\tit('should have the correct default config', function() {\n\t\texpect(Chart.defaults.global.legend).toEqual({\n\t\t\tdisplay: true,\n\t\t\tposition: 'top',\n\t\t\tfullWidth: true, // marks that this box should take the full width of the canvas (pushing down other boxes)\n\t\t\treverse: false,\n\t\t\tweight: 1000,\n\n\t\t\t// a callback that will handle\n\t\t\tonClick: jasmine.any(Function),\n\t\t\tonHover: null,\n\n\t\t\tlabels: {\n\t\t\t\tboxWidth: 40,\n\t\t\t\tpadding: 10,\n\t\t\t\tgenerateLabels: jasmine.any(Function)\n\t\t\t}\n\t\t});\n\t});\n\n\tit('should update correctly', function() {\n\t\tvar chart = window.acquireChart({\n\t\t\ttype: 'bar',\n\t\t\tdata: {\n\t\t\t\tdatasets: [{\n\t\t\t\t\tlabel: 'dataset1',\n\t\t\t\t\tbackgroundColor: '#f31',\n\t\t\t\t\tborderCapStyle: 'butt',\n\t\t\t\t\tborderDash: [2, 2],\n\t\t\t\t\tborderDashOffset: 5.5,\n\t\t\t\t\tdata: []\n\t\t\t\t}, {\n\t\t\t\t\tlabel: 'dataset2',\n\t\t\t\t\thidden: true,\n\t\t\t\t\tborderJoinStyle: 'miter',\n\t\t\t\t\tdata: []\n\t\t\t\t}, {\n\t\t\t\t\tlabel: 'dataset3',\n\t\t\t\t\tborderWidth: 10,\n\t\t\t\t\tborderColor: 'green',\n\t\t\t\t\tpointStyle: 'crossRot',\n\t\t\t\t\tdata: []\n\t\t\t\t}],\n\t\t\t\tlabels: []\n\t\t\t}\n\t\t});\n\n\t\texpect(chart.legend.legendItems).toEqual([{\n\t\t\ttext: 'dataset1',\n\t\t\tfillStyle: '#f31',\n\t\t\thidden: false,\n\t\t\tlineCap: 'butt',\n\t\t\tlineDash: [2, 2],\n\t\t\tlineDashOffset: 5.5,\n\t\t\tlineJoin: undefined,\n\t\t\tlineWidth: undefined,\n\t\t\tstrokeStyle: undefined,\n\t\t\tpointStyle: undefined,\n\t\t\tdatasetIndex: 0\n\t\t}, {\n\t\t\ttext: 'dataset2',\n\t\t\tfillStyle: undefined,\n\t\t\thidden: true,\n\t\t\tlineCap: undefined,\n\t\t\tlineDash: undefined,\n\t\t\tlineDashOffset: undefined,\n\t\t\tlineJoin: 'miter',\n\t\t\tlineWidth: undefined,\n\t\t\tstrokeStyle: undefined,\n\t\t\tpointStyle: undefined,\n\t\t\tdatasetIndex: 1\n\t\t}, {\n\t\t\ttext: 'dataset3',\n\t\t\tfillStyle: undefined,\n\t\t\thidden: false,\n\t\t\tlineCap: undefined,\n\t\t\tlineDash: undefined,\n\t\t\tlineDashOffset: undefined,\n\t\t\tlineJoin: undefined,\n\t\t\tlineWidth: 10,\n\t\t\tstrokeStyle: 'green',\n\t\t\tpointStyle: 'crossRot',\n\t\t\tdatasetIndex: 2\n\t\t}]);\n\t});\n\n\tit('should filter items', function() {\n\t\tvar chart = window.acquireChart({\n\t\t\ttype: 'bar',\n\t\t\tdata: {\n\t\t\t\tdatasets: [{\n\t\t\t\t\tlabel: 'dataset1',\n\t\t\t\t\tbackgroundColor: '#f31',\n\t\t\t\t\tborderCapStyle: 'butt',\n\t\t\t\t\tborderDash: [2, 2],\n\t\t\t\t\tborderDashOffset: 5.5,\n\t\t\t\t\tdata: []\n\t\t\t\t}, {\n\t\t\t\t\tlabel: 'dataset2',\n\t\t\t\t\thidden: true,\n\t\t\t\t\tborderJoinStyle: 'miter',\n\t\t\t\t\tdata: [],\n\t\t\t\t\tlegendHidden: true\n\t\t\t\t}, {\n\t\t\t\t\tlabel: 'dataset3',\n\t\t\t\t\tborderWidth: 10,\n\t\t\t\t\tborderColor: 'green',\n\t\t\t\t\tpointStyle: 'crossRot',\n\t\t\t\t\tdata: []\n\t\t\t\t}],\n\t\t\t\tlabels: []\n\t\t\t},\n\t\t\toptions: {\n\t\t\t\tlegend: {\n\t\t\t\t\tlabels: {\n\t\t\t\t\t\tfilter: function(legendItem, data) {\n\t\t\t\t\t\t\tvar dataset = data.datasets[legendItem.datasetIndex];\n\t\t\t\t\t\t\treturn !dataset.legendHidden;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\n\t\texpect(chart.legend.legendItems).toEqual([{\n\t\t\ttext: 'dataset1',\n\t\t\tfillStyle: '#f31',\n\t\t\thidden: false,\n\t\t\tlineCap: 'butt',\n\t\t\tlineDash: [2, 2],\n\t\t\tlineDashOffset: 5.5,\n\t\t\tlineJoin: undefined,\n\t\t\tlineWidth: undefined,\n\t\t\tstrokeStyle: undefined,\n\t\t\tpointStyle: undefined,\n\t\t\tdatasetIndex: 0\n\t\t}, {\n\t\t\ttext: 'dataset3',\n\t\t\tfillStyle: undefined,\n\t\t\thidden: false,\n\t\t\tlineCap: undefined,\n\t\t\tlineDash: undefined,\n\t\t\tlineDashOffset: undefined,\n\t\t\tlineJoin: undefined,\n\t\t\tlineWidth: 10,\n\t\t\tstrokeStyle: 'green',\n\t\t\tpointStyle: 'crossRot',\n\t\t\tdatasetIndex: 2\n\t\t}]);\n\t});\n\n\tit('should draw correctly', function() {\n\t\tvar chart = window.acquireChart({\n\t\t\ttype: 'bar',\n\t\t\tdata: {\n\t\t\t\tdatasets: [{\n\t\t\t\t\tlabel: 'dataset1',\n\t\t\t\t\tbackgroundColor: '#f31',\n\t\t\t\t\tborderCapStyle: 'butt',\n\t\t\t\t\tborderDash: [2, 2],\n\t\t\t\t\tborderDashOffset: 5.5,\n\t\t\t\t\tdata: []\n\t\t\t\t}, {\n\t\t\t\t\tlabel: 'dataset2',\n\t\t\t\t\thidden: true,\n\t\t\t\t\tborderJoinStyle: 'miter',\n\t\t\t\t\tdata: []\n\t\t\t\t}, {\n\t\t\t\t\tlabel: 'dataset3',\n\t\t\t\t\tborderWidth: 10,\n\t\t\t\t\tborderColor: 'green',\n\t\t\t\t\tdata: []\n\t\t\t\t}],\n\t\t\t\tlabels: []\n\t\t\t}\n\t\t});\n\n\t\texpect(chart.legend.legendHitBoxes.length).toBe(3);\n\n\t\t[\n\t\t\t{h: 12, l: 101, t: 10, w: 93},\n\t\t\t{h: 12, l: 205, t: 10, w: 93},\n\t\t\t{h: 12, l: 308, t: 10, w: 93}\n\t\t].forEach(function(expected, i) {\n\t\t\texpect(chart.legend.legendHitBoxes[i].height).toBeCloseToPixel(expected.h);\n\t\t\texpect(chart.legend.legendHitBoxes[i].left).toBeCloseToPixel(expected.l);\n\t\t\texpect(chart.legend.legendHitBoxes[i].top).toBeCloseToPixel(expected.t);\n\t\t\texpect(chart.legend.legendHitBoxes[i].width).toBeCloseToPixel(expected.w);\n\t\t});\n\n\t\t// NOTE(SB) We should get ride of the following tests and use image diff instead.\n\t\t// For now, as discussed with Evert Timberg, simply comment out.\n\t\t// See http://humblesoftware.github.io/js-imagediff/test.html\n\t\t/* chart.legend.ctx = window.createMockContext();\n\t\tchart.update();\n\n\t\texpect(chart.legend.ctx .getCalls()).toEqual([{\n\t\t\t\"name\": \"measureText\",\n\t\t\t\"args\": [\"dataset1\"]\n\t\t}, {\n\t\t\t\"name\": \"measureText\",\n\t\t\t\"args\": [\"dataset2\"]\n\t\t}, {\n\t\t\t\"name\": \"measureText\",\n\t\t\t\"args\": [\"dataset3\"]\n\t\t}, {\n\t\t\t\"name\": \"measureText\",\n\t\t\t\"args\": [\"dataset1\"]\n\t\t}, {\n\t\t\t\"name\": \"measureText\",\n\t\t\t\"args\": [\"dataset2\"]\n\t\t}, {\n\t\t\t\"name\": \"measureText\",\n\t\t\t\"args\": [\"dataset3\"]\n\t\t}, {\n\t\t\t\"name\": \"setLineWidth\",\n\t\t\t\"args\": [0.5]\n\t\t}, {\n\t\t\t\"name\": \"setStrokeStyle\",\n\t\t\t\"args\": [\"#666\"]\n\t\t}, {\n\t\t\t\"name\": \"setFillStyle\",\n\t\t\t\"args\": [\"#666\"]\n\t\t}, {\n\t\t\t\"name\": \"measureText\",\n\t\t\t\"args\": [\"dataset1\"]\n\t\t}, {\n\t\t\t\"name\": \"save\",\n\t\t\t\"args\": []\n\t\t}, {\n\t\t\t\"name\": \"setFillStyle\",\n\t\t\t\"args\": [\"#f31\"]\n\t\t}, {\n\t\t\t\"name\": \"setLineCap\",\n\t\t\t\"args\": [\"butt\"]\n\t\t}, {\n\t\t\t\"name\": \"setLineDashOffset\",\n\t\t\t\"args\": [5.5]\n\t\t}, {\n\t\t\t\"name\": \"setLineJoin\",\n\t\t\t\"args\": [\"miter\"]\n\t\t}, {\n\t\t\t\"name\": \"setLineWidth\",\n\t\t\t\"args\": [3]\n\t\t}, {\n\t\t\t\"name\": \"setStrokeStyle\",\n\t\t\t\"args\": [\"rgba(0,0,0,0.1)\"]\n\t\t}, {\n\t\t\t\"name\": \"setLineDash\",\n\t\t\t\"args\": [\n\t\t\t\t[2, 2]\n\t\t\t]\n\t\t}, {\n\t\t\t\"name\": \"strokeRect\",\n\t\t\t\"args\": [114, 110, 40, 12]\n\t\t}, {\n\t\t\t\"name\": \"fillRect\",\n\t\t\t\"args\": [114, 110, 40, 12]\n\t\t}, {\n\t\t\t\"name\": \"restore\",\n\t\t\t\"args\": []\n\t\t}, {\n\t\t\t\"name\": \"fillText\",\n\t\t\t\"args\": [\"dataset1\", 160, 110]\n\t\t}, {\n\t\t\t\"name\": \"measureText\",\n\t\t\t\"args\": [\"dataset2\"]\n\t\t}, {\n\t\t\t\"name\": \"save\",\n\t\t\t\"args\": []\n\t\t}, {\n\t\t\t\"name\": \"setFillStyle\",\n\t\t\t\"args\": [\"rgba(0,0,0,0.1)\"]\n\t\t}, {\n\t\t\t\"name\": \"setLineCap\",\n\t\t\t\"args\": [\"butt\"]\n\t\t}, {\n\t\t\t\"name\": \"setLineDashOffset\",\n\t\t\t\"args\": [0]\n\t\t}, {\n\t\t\t\"name\": \"setLineJoin\",\n\t\t\t\"args\": [\"miter\"]\n\t\t}, {\n\t\t\t\"name\": \"setLineWidth\",\n\t\t\t\"args\": [3]\n\t\t}, {\n\t\t\t\"name\": \"setStrokeStyle\",\n\t\t\t\"args\": [\"rgba(0,0,0,0.1)\"]\n\t\t}, {\n\t\t\t\"name\": \"setLineDash\",\n\t\t\t\"args\": [\n\t\t\t\t[]\n\t\t\t]\n\t\t}, {\n\t\t\t\"name\": \"strokeRect\",\n\t\t\t\"args\": [250, 110, 40, 12]\n\t\t}, {\n\t\t\t\"name\": \"fillRect\",\n\t\t\t\"args\": [250, 110, 40, 12]\n\t\t}, {\n\t\t\t\"name\": \"restore\",\n\t\t\t\"args\": []\n\t\t}, {\n\t\t\t\"name\": \"fillText\",\n\t\t\t\"args\": [\"dataset2\", 296, 110]\n\t\t}, {\n\t\t\t\"name\": \"beginPath\",\n\t\t\t\"args\": []\n\t\t}, {\n\t\t\t\"name\": \"setLineWidth\",\n\t\t\t\"args\": [2]\n\t\t}, {\n\t\t\t\"name\": \"moveTo\",\n\t\t\t\"args\": [296, 116]\n\t\t}, {\n\t\t\t\"name\": \"lineTo\",\n\t\t\t\"args\": [376, 116]\n\t\t}, {\n\t\t\t\"name\": \"stroke\",\n\t\t\t\"args\": []\n\t\t}, {\n\t\t\t\"name\": \"measureText\",\n\t\t\t\"args\": [\"dataset3\"]\n\t\t}, {\n\t\t\t\"name\": \"save\",\n\t\t\t\"args\": []\n\t\t}, {\n\t\t\t\"name\": \"setFillStyle\",\n\t\t\t\"args\": [\"rgba(0,0,0,0.1)\"]\n\t\t}, {\n\t\t\t\"name\": \"setLineCap\",\n\t\t\t\"args\": [\"butt\"]\n\t\t}, {\n\t\t\t\"name\": \"setLineDashOffset\",\n\t\t\t\"args\": [0]\n\t\t}, {\n\t\t\t\"name\": \"setLineJoin\",\n\t\t\t\"args\": [\"miter\"]\n\t\t}, {\n\t\t\t\"name\": \"setLineWidth\",\n\t\t\t\"args\": [10]\n\t\t}, {\n\t\t\t\"name\": \"setStrokeStyle\",\n\t\t\t\"args\": [\"green\"]\n\t\t}, {\n\t\t\t\"name\": \"setLineDash\",\n\t\t\t\"args\": [\n\t\t\t\t[]\n\t\t\t]\n\t\t}, {\n\t\t\t\"name\": \"strokeRect\",\n\t\t\t\"args\": [182, 132, 40, 12]\n\t\t}, {\n\t\t\t\"name\": \"fillRect\",\n\t\t\t\"args\": [182, 132, 40, 12]\n\t\t}, {\n\t\t\t\"name\": \"restore\",\n\t\t\t\"args\": []\n\t\t}, {\n\t\t\t\"name\": \"fillText\",\n\t\t\t\"args\": [\"dataset3\", 228, 132]\n\t\t}]);*/\n\t});\n\n\tdescribe('config update', function() {\n\t\tit ('should update the options', function() {\n\t\t\tvar chart = acquireChart({\n\t\t\t\ttype: 'line',\n\t\t\t\tdata: {\n\t\t\t\t\tlabels: ['A', 'B', 'C', 'D'],\n\t\t\t\t\tdatasets: [{\n\t\t\t\t\t\tdata: [10, 20, 30, 100]\n\t\t\t\t\t}]\n\t\t\t\t},\n\t\t\t\toptions: {\n\t\t\t\t\tlegend: {\n\t\t\t\t\t\tdisplay: true\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t});\n\t\t\texpect(chart.legend.options.display).toBe(true);\n\n\t\t\tchart.options.legend.display = false;\n\t\t\tchart.update();\n\t\t\texpect(chart.legend.options.display).toBe(false);\n\t\t});\n\n\t\tit ('should update the associated layout item', function() {\n\t\t\tvar chart = acquireChart({\n\t\t\t\ttype: 'line',\n\t\t\t\tdata: {},\n\t\t\t\toptions: {\n\t\t\t\t\tlegend: {\n\t\t\t\t\t\tfullWidth: true,\n\t\t\t\t\t\tposition: 'top',\n\t\t\t\t\t\tweight: 150\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t});\n\n\t\t\texpect(chart.legend.fullWidth).toBe(true);\n\t\t\texpect(chart.legend.position).toBe('top');\n\t\t\texpect(chart.legend.weight).toBe(150);\n\n\t\t\tchart.options.legend.fullWidth = false;\n\t\t\tchart.options.legend.position = 'left';\n\t\t\tchart.options.legend.weight = 42;\n\t\t\tchart.update();\n\n\t\t\texpect(chart.legend.fullWidth).toBe(false);\n\t\t\texpect(chart.legend.position).toBe('left');\n\t\t\texpect(chart.legend.weight).toBe(42);\n\t\t});\n\n\t\tit ('should remove the legend if the new options are false', function() {\n\t\t\tvar chart = acquireChart({\n\t\t\t\ttype: 'line',\n\t\t\t\tdata: {\n\t\t\t\t\tlabels: ['A', 'B', 'C', 'D'],\n\t\t\t\t\tdatasets: [{\n\t\t\t\t\t\tdata: [10, 20, 30, 100]\n\t\t\t\t\t}]\n\t\t\t\t}\n\t\t\t});\n\t\t\texpect(chart.legend).not.toBe(undefined);\n\n\t\t\tchart.options.legend = false;\n\t\t\tchart.update();\n\t\t\texpect(chart.legend).toBe(undefined);\n\t\t});\n\n\t\tit ('should create the legend if the legend options are changed to exist', function() {\n\t\t\tvar chart = acquireChart({\n\t\t\t\ttype: 'line',\n\t\t\t\tdata: {\n\t\t\t\t\tlabels: ['A', 'B', 'C', 'D'],\n\t\t\t\t\tdatasets: [{\n\t\t\t\t\t\tdata: [10, 20, 30, 100]\n\t\t\t\t\t}]\n\t\t\t\t},\n\t\t\t\toptions: {\n\t\t\t\t\tlegend: false\n\t\t\t\t}\n\t\t\t});\n\t\t\texpect(chart.legend).toBe(undefined);\n\n\t\t\tchart.options.legend = {};\n\t\t\tchart.update();\n\t\t\texpect(chart.legend).not.toBe(undefined);\n\t\t\texpect(chart.legend.options).toEqual(jasmine.objectContaining(Chart.defaults.global.legend));\n\t\t});\n\t});\n});\n"
  },
  {
    "path": "app_backend/static/plugin/Chart.js-2.6.0/test/specs/plugin.title.tests.js",
    "content": "// Test the rectangle element\n\ndescribe('Title block tests', function() {\n\tit('Should be constructed', function() {\n\t\tvar title = new Chart.Title({});\n\t\texpect(title).not.toBe(undefined);\n\t});\n\n\tit('Should have the correct default config', function() {\n\t\texpect(Chart.defaults.global.title).toEqual({\n\t\t\tdisplay: false,\n\t\t\tposition: 'top',\n\t\t\tfullWidth: true,\n\t\t\tweight: 2000,\n\t\t\tfontStyle: 'bold',\n\t\t\tpadding: 10,\n\t\t\ttext: ''\n\t\t});\n\t});\n\n\tit('should update correctly', function() {\n\t\tvar chart = {};\n\n\t\tvar options = Chart.helpers.clone(Chart.defaults.global.title);\n\t\toptions.text = 'My title';\n\n\t\tvar title = new Chart.Title({\n\t\t\tchart: chart,\n\t\t\toptions: options\n\t\t});\n\n\t\tvar minSize = title.update(400, 200);\n\n\t\texpect(minSize).toEqual({\n\t\t\twidth: 400,\n\t\t\theight: 0\n\t\t});\n\n\t\t// Now we have a height since we display\n\t\ttitle.options.display = true;\n\n\t\tminSize = title.update(400, 200);\n\n\t\texpect(minSize).toEqual({\n\t\t\twidth: 400,\n\t\t\theight: 32\n\t\t});\n\t});\n\n\tit('should update correctly when vertical', function() {\n\t\tvar chart = {};\n\n\t\tvar options = Chart.helpers.clone(Chart.defaults.global.title);\n\t\toptions.text = 'My title';\n\t\toptions.position = 'left';\n\n\t\tvar title = new Chart.Title({\n\t\t\tchart: chart,\n\t\t\toptions: options\n\t\t});\n\n\t\tvar minSize = title.update(200, 400);\n\n\t\texpect(minSize).toEqual({\n\t\t\twidth: 0,\n\t\t\theight: 400\n\t\t});\n\n\t\t// Now we have a height since we display\n\t\ttitle.options.display = true;\n\n\t\tminSize = title.update(200, 400);\n\n\t\texpect(minSize).toEqual({\n\t\t\twidth: 32,\n\t\t\theight: 400\n\t\t});\n\t});\n\n\tit('should draw correctly horizontally', function() {\n\t\tvar chart = {};\n\t\tvar context = window.createMockContext();\n\n\t\tvar options = Chart.helpers.clone(Chart.defaults.global.title);\n\t\toptions.text = 'My title';\n\n\t\tvar title = new Chart.Title({\n\t\t\tchart: chart,\n\t\t\toptions: options,\n\t\t\tctx: context\n\t\t});\n\n\t\ttitle.update(400, 200);\n\t\ttitle.draw();\n\n\t\texpect(context.getCalls()).toEqual([]);\n\n\t\t// Now we have a height since we display\n\t\ttitle.options.display = true;\n\n\t\tvar minSize = title.update(400, 200);\n\t\ttitle.top = 50;\n\t\ttitle.left = 100;\n\t\ttitle.bottom = title.top + minSize.height;\n\t\ttitle.right = title.left + minSize.width;\n\t\ttitle.draw();\n\n\t\texpect(context.getCalls()).toEqual([{\n\t\t\tname: 'setFillStyle',\n\t\t\targs: ['#666']\n\t\t}, {\n\t\t\tname: 'save',\n\t\t\targs: []\n\t\t}, {\n\t\t\tname: 'translate',\n\t\t\targs: [300, 66]\n\t\t}, {\n\t\t\tname: 'rotate',\n\t\t\targs: [0]\n\t\t}, {\n\t\t\tname: 'fillText',\n\t\t\targs: ['My title', 0, 0, 400]\n\t\t}, {\n\t\t\tname: 'restore',\n\t\t\targs: []\n\t\t}]);\n\t});\n\n\tit ('should draw correctly vertically', function() {\n\t\tvar chart = {};\n\t\tvar context = window.createMockContext();\n\n\t\tvar options = Chart.helpers.clone(Chart.defaults.global.title);\n\t\toptions.text = 'My title';\n\t\toptions.position = 'left';\n\n\t\tvar title = new Chart.Title({\n\t\t\tchart: chart,\n\t\t\toptions: options,\n\t\t\tctx: context\n\t\t});\n\n\t\ttitle.update(200, 400);\n\t\ttitle.draw();\n\n\t\texpect(context.getCalls()).toEqual([]);\n\n\t\t// Now we have a height since we display\n\t\ttitle.options.display = true;\n\n\t\tvar minSize = title.update(200, 400);\n\t\ttitle.top = 50;\n\t\ttitle.left = 100;\n\t\ttitle.bottom = title.top + minSize.height;\n\t\ttitle.right = title.left + minSize.width;\n\t\ttitle.draw();\n\n\t\texpect(context.getCalls()).toEqual([{\n\t\t\tname: 'setFillStyle',\n\t\t\targs: ['#666']\n\t\t}, {\n\t\t\tname: 'save',\n\t\t\targs: []\n\t\t}, {\n\t\t\tname: 'translate',\n\t\t\targs: [106, 250]\n\t\t}, {\n\t\t\tname: 'rotate',\n\t\t\targs: [-0.5 * Math.PI]\n\t\t}, {\n\t\t\tname: 'fillText',\n\t\t\targs: ['My title', 0, 0, 400]\n\t\t}, {\n\t\t\tname: 'restore',\n\t\t\targs: []\n\t\t}]);\n\n\t\t// Rotation is other way on right side\n\t\ttitle.options.position = 'right';\n\n\t\t// Reset call tracker\n\t\tcontext.resetCalls();\n\n\t\tminSize = title.update(200, 400);\n\t\ttitle.top = 50;\n\t\ttitle.left = 100;\n\t\ttitle.bottom = title.top + minSize.height;\n\t\ttitle.right = title.left + minSize.width;\n\t\ttitle.draw();\n\n\t\texpect(context.getCalls()).toEqual([{\n\t\t\tname: 'setFillStyle',\n\t\t\targs: ['#666']\n\t\t}, {\n\t\t\tname: 'save',\n\t\t\targs: []\n\t\t}, {\n\t\t\tname: 'translate',\n\t\t\targs: [126, 250]\n\t\t}, {\n\t\t\tname: 'rotate',\n\t\t\targs: [0.5 * Math.PI]\n\t\t}, {\n\t\t\tname: 'fillText',\n\t\t\targs: ['My title', 0, 0, 400]\n\t\t}, {\n\t\t\tname: 'restore',\n\t\t\targs: []\n\t\t}]);\n\t});\n\n\tdescribe('config update', function() {\n\t\tit ('should update the options', function() {\n\t\t\tvar chart = acquireChart({\n\t\t\t\ttype: 'line',\n\t\t\t\tdata: {\n\t\t\t\t\tlabels: ['A', 'B', 'C', 'D'],\n\t\t\t\t\tdatasets: [{\n\t\t\t\t\t\tdata: [10, 20, 30, 100]\n\t\t\t\t\t}]\n\t\t\t\t},\n\t\t\t\toptions: {\n\t\t\t\t\ttitle: {\n\t\t\t\t\t\tdisplay: true\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t});\n\t\t\texpect(chart.titleBlock.options.display).toBe(true);\n\n\t\t\tchart.options.title.display = false;\n\t\t\tchart.update();\n\t\t\texpect(chart.titleBlock.options.display).toBe(false);\n\t\t});\n\n\t\tit ('should update the associated layout item', function() {\n\t\t\tvar chart = acquireChart({\n\t\t\t\ttype: 'line',\n\t\t\t\tdata: {},\n\t\t\t\toptions: {\n\t\t\t\t\ttitle: {\n\t\t\t\t\t\tfullWidth: true,\n\t\t\t\t\t\tposition: 'top',\n\t\t\t\t\t\tweight: 150\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t});\n\n\t\t\texpect(chart.titleBlock.fullWidth).toBe(true);\n\t\t\texpect(chart.titleBlock.position).toBe('top');\n\t\t\texpect(chart.titleBlock.weight).toBe(150);\n\n\t\t\tchart.options.title.fullWidth = false;\n\t\t\tchart.options.title.position = 'left';\n\t\t\tchart.options.title.weight = 42;\n\t\t\tchart.update();\n\n\t\t\texpect(chart.titleBlock.fullWidth).toBe(false);\n\t\t\texpect(chart.titleBlock.position).toBe('left');\n\t\t\texpect(chart.titleBlock.weight).toBe(42);\n\t\t});\n\n\t\tit ('should remove the title if the new options are false', function() {\n\t\t\tvar chart = acquireChart({\n\t\t\t\ttype: 'line',\n\t\t\t\tdata: {\n\t\t\t\t\tlabels: ['A', 'B', 'C', 'D'],\n\t\t\t\t\tdatasets: [{\n\t\t\t\t\t\tdata: [10, 20, 30, 100]\n\t\t\t\t\t}]\n\t\t\t\t}\n\t\t\t});\n\t\t\texpect(chart.titleBlock).not.toBe(undefined);\n\n\t\t\tchart.options.title = false;\n\t\t\tchart.update();\n\t\t\texpect(chart.titleBlock).toBe(undefined);\n\t\t});\n\n\t\tit ('should create the title if the title options are changed to exist', function() {\n\t\t\tvar chart = acquireChart({\n\t\t\t\ttype: 'line',\n\t\t\t\tdata: {\n\t\t\t\t\tlabels: ['A', 'B', 'C', 'D'],\n\t\t\t\t\tdatasets: [{\n\t\t\t\t\t\tdata: [10, 20, 30, 100]\n\t\t\t\t\t}]\n\t\t\t\t},\n\t\t\t\toptions: {\n\t\t\t\t\ttitle: false\n\t\t\t\t}\n\t\t\t});\n\t\t\texpect(chart.titleBlock).toBe(undefined);\n\n\t\t\tchart.options.title = {};\n\t\t\tchart.update();\n\t\t\texpect(chart.titleBlock).not.toBe(undefined);\n\t\t\texpect(chart.titleBlock.options).toEqual(jasmine.objectContaining(Chart.defaults.global.title));\n\t\t});\n\t});\n});\n"
  },
  {
    "path": "app_backend/static/plugin/Chart.js-2.6.0/test/specs/scale.category.tests.js",
    "content": "// Test the category scale\n\ndescribe('Category scale tests', function() {\n\tit('Should register the constructor with the scale service', function() {\n\t\tvar Constructor = Chart.scaleService.getScaleConstructor('category');\n\t\texpect(Constructor).not.toBe(undefined);\n\t\texpect(typeof Constructor).toBe('function');\n\t});\n\n\tit('Should have the correct default config', function() {\n\t\tvar defaultConfig = Chart.scaleService.getScaleDefaults('category');\n\t\texpect(defaultConfig).toEqual({\n\t\t\tdisplay: true,\n\n\t\t\tgridLines: {\n\t\t\t\tcolor: 'rgba(0, 0, 0, 0.1)',\n\t\t\t\tdrawBorder: true,\n\t\t\t\tdrawOnChartArea: true,\n\t\t\t\tdrawTicks: true, // draw ticks extending towards the label\n\t\t\t\ttickMarkLength: 10,\n\t\t\t\tlineWidth: 1,\n\t\t\t\toffsetGridLines: false,\n\t\t\t\tdisplay: true,\n\t\t\t\tzeroLineColor: 'rgba(0,0,0,0.25)',\n\t\t\t\tzeroLineWidth: 1,\n\t\t\t\tzeroLineBorderDash: [],\n\t\t\t\tzeroLineBorderDashOffset: 0.0,\n\t\t\t\tborderDash: [],\n\t\t\t\tborderDashOffset: 0.0\n\t\t\t},\n\t\t\tposition: 'bottom',\n\t\t\tscaleLabel: {\n\t\t\t\tlabelString: '',\n\t\t\t\tdisplay: false\n\t\t\t},\n\t\t\tticks: {\n\t\t\t\tbeginAtZero: false,\n\t\t\t\tminRotation: 0,\n\t\t\t\tmaxRotation: 50,\n\t\t\t\tmirror: false,\n\t\t\t\tpadding: 0,\n\t\t\t\treverse: false,\n\t\t\t\tdisplay: true,\n\t\t\t\tcallback: defaultConfig.ticks.callback,  // make this nicer, then check explicitly below\n\t\t\t\tautoSkip: true,\n\t\t\t\tautoSkipPadding: 0,\n\t\t\t\tlabelOffset: 0\n\t\t\t}\n\t\t});\n\n\t\t// Is this actually a function\n\t\texpect(defaultConfig.ticks.callback).toEqual(jasmine.any(Function));\n\t});\n\n\tit('Should generate ticks from the data labels', function() {\n\t\tvar scaleID = 'myScale';\n\n\t\tvar mockData = {\n\t\t\tdatasets: [{\n\t\t\t\tyAxisID: scaleID,\n\t\t\t\tdata: [10, 5, 0, 25, 78]\n\t\t\t}],\n\t\t\tlabels: ['tick1', 'tick2', 'tick3', 'tick4', 'tick5']\n\t\t};\n\n\t\tvar config = Chart.helpers.clone(Chart.scaleService.getScaleDefaults('category'));\n\t\tvar Constructor = Chart.scaleService.getScaleConstructor('category');\n\t\tvar scale = new Constructor({\n\t\t\tctx: {},\n\t\t\toptions: config,\n\t\t\tchart: {\n\t\t\t\tdata: mockData\n\t\t\t},\n\t\t\tid: scaleID\n\t\t});\n\n\t\tscale.determineDataLimits();\n\t\tscale.buildTicks();\n\t\texpect(scale.ticks).toEqual(mockData.labels);\n\t});\n\n\tit('Should generate ticks from the data xLabels', function() {\n\t\tvar scaleID = 'myScale';\n\n\t\tvar mockData = {\n\t\t\tdatasets: [{\n\t\t\t\tyAxisID: scaleID,\n\t\t\t\tdata: [10, 5, 0, 25, 78]\n\t\t\t}],\n\t\t\txLabels: ['tick1', 'tick2', 'tick3', 'tick4', 'tick5']\n\t\t};\n\n\t\tvar config = Chart.helpers.clone(Chart.scaleService.getScaleDefaults('category'));\n\t\tvar Constructor = Chart.scaleService.getScaleConstructor('category');\n\t\tvar scale = new Constructor({\n\t\t\tctx: {},\n\t\t\toptions: config,\n\t\t\tchart: {\n\t\t\t\tdata: mockData\n\t\t\t},\n\t\t\tid: scaleID\n\t\t});\n\n\t\tscale.determineDataLimits();\n\t\tscale.buildTicks();\n\t\texpect(scale.ticks).toEqual(mockData.xLabels);\n\t});\n\n\tit('Should generate ticks from the data xLabels', function() {\n\t\tvar scaleID = 'myScale';\n\n\t\tvar mockData = {\n\t\t\tdatasets: [{\n\t\t\t\tyAxisID: scaleID,\n\t\t\t\tdata: [10, 5, 0, 25, 78]\n\t\t\t}],\n\t\t\tyLabels: ['tick1', 'tick2', 'tick3', 'tick4', 'tick5']\n\t\t};\n\n\t\tvar config = Chart.helpers.clone(Chart.scaleService.getScaleDefaults('category'));\n\t\tconfig.position = 'left'; // y axis\n\t\tvar Constructor = Chart.scaleService.getScaleConstructor('category');\n\t\tvar scale = new Constructor({\n\t\t\tctx: {},\n\t\t\toptions: config,\n\t\t\tchart: {\n\t\t\t\tdata: mockData\n\t\t\t},\n\t\t\tid: scaleID\n\t\t});\n\n\t\tscale.determineDataLimits();\n\t\tscale.buildTicks();\n\t\texpect(scale.ticks).toEqual(mockData.yLabels);\n\t});\n\n\tit ('should get the correct label for the index', function() {\n\t\tvar scaleID = 'myScale';\n\n\t\tvar mockData = {\n\t\t\tdatasets: [{\n\t\t\t\tyAxisID: scaleID,\n\t\t\t\tdata: [10, 5, 0, 25, 78]\n\t\t\t}],\n\t\t\tlabels: ['tick1', 'tick2', 'tick3', 'tick4', 'tick5']\n\t\t};\n\n\t\tvar config = Chart.helpers.clone(Chart.scaleService.getScaleDefaults('category'));\n\t\tvar Constructor = Chart.scaleService.getScaleConstructor('category');\n\t\tvar scale = new Constructor({\n\t\t\tctx: {},\n\t\t\toptions: config,\n\t\t\tchart: {\n\t\t\t\tdata: mockData\n\t\t\t},\n\t\t\tid: scaleID\n\t\t});\n\n\t\tscale.determineDataLimits();\n\t\tscale.buildTicks();\n\n\t\texpect(scale.getLabelForIndex(1)).toBe('tick2');\n\t});\n\n\tit ('Should get the correct pixel for a value when horizontal', function() {\n\t\tvar chart = window.acquireChart({\n\t\t\ttype: 'line',\n\t\t\tdata: {\n\t\t\t\tdatasets: [{\n\t\t\t\t\txAxisID: 'xScale0',\n\t\t\t\t\tyAxisID: 'yScale0',\n\t\t\t\t\tdata: [10, 5, 0, 25, 78]\n\t\t\t\t}],\n\t\t\t\tlabels: ['tick1', 'tick2', 'tick3', 'tick4', 'tick_last']\n\t\t\t},\n\t\t\toptions: {\n\t\t\t\tscales: {\n\t\t\t\t\txAxes: [{\n\t\t\t\t\t\tid: 'xScale0',\n\t\t\t\t\t\ttype: 'category',\n\t\t\t\t\t\tposition: 'bottom'\n\t\t\t\t\t}],\n\t\t\t\t\tyAxes: [{\n\t\t\t\t\t\tid: 'yScale0',\n\t\t\t\t\t\ttype: 'linear'\n\t\t\t\t\t}]\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\n\t\tvar xScale = chart.scales.xScale0;\n\t\texpect(xScale.getPixelForValue(0, 0, 0, false)).toBeCloseToPixel(23);\n\t\texpect(xScale.getPixelForValue(0, 0, 0, true)).toBeCloseToPixel(23);\n\t\texpect(xScale.getValueForPixel(33)).toBe(0);\n\n\t\texpect(xScale.getPixelForValue(0, 4, 0, false)).toBeCloseToPixel(487);\n\t\texpect(xScale.getPixelForValue(0, 4, 0, true)).toBeCloseToPixel(487);\n\t\texpect(xScale.getValueForPixel(487)).toBe(4);\n\n\t\txScale.options.gridLines.offsetGridLines = true;\n\n\t\texpect(xScale.getPixelForValue(0, 0, 0, false)).toBeCloseToPixel(23);\n\t\texpect(xScale.getPixelForValue(0, 0, 0, true)).toBeCloseToPixel(69);\n\t\texpect(xScale.getValueForPixel(33)).toBe(0);\n\t\texpect(xScale.getValueForPixel(78)).toBe(0);\n\n\t\texpect(xScale.getPixelForValue(0, 4, 0, false)).toBeCloseToPixel(395);\n\t\texpect(xScale.getPixelForValue(0, 4, 0, true)).toBeCloseToPixel(441);\n\t\texpect(xScale.getValueForPixel(397)).toBe(4);\n\t\texpect(xScale.getValueForPixel(441)).toBe(4);\n\t});\n\n\tit ('Should get the correct pixel for a value when there are repeated labels', function() {\n\t\tvar chart = window.acquireChart({\n\t\t\ttype: 'line',\n\t\t\tdata: {\n\t\t\t\tdatasets: [{\n\t\t\t\t\txAxisID: 'xScale0',\n\t\t\t\t\tyAxisID: 'yScale0',\n\t\t\t\t\tdata: [10, 5, 0, 25, 78]\n\t\t\t\t}],\n\t\t\t\tlabels: ['tick1', 'tick2', 'tick3', 'tick4', 'tick_last']\n\t\t\t},\n\t\t\toptions: {\n\t\t\t\tscales: {\n\t\t\t\t\txAxes: [{\n\t\t\t\t\t\tid: 'xScale0',\n\t\t\t\t\t\ttype: 'category',\n\t\t\t\t\t\tposition: 'bottom'\n\t\t\t\t\t}],\n\t\t\t\t\tyAxes: [{\n\t\t\t\t\t\tid: 'yScale0',\n\t\t\t\t\t\ttype: 'linear'\n\t\t\t\t\t}]\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\n\t\tvar xScale = chart.scales.xScale0;\n\t\texpect(xScale.getPixelForValue('tick_1', 0, 0, false)).toBeCloseToPixel(23);\n\t\texpect(xScale.getPixelForValue('tick_1', 1, 0, false)).toBeCloseToPixel(139);\n\t});\n\n\tit ('Should get the correct pixel for a value when horizontal and zoomed', function() {\n\t\tvar chart = window.acquireChart({\n\t\t\ttype: 'line',\n\t\t\tdata: {\n\t\t\t\tdatasets: [{\n\t\t\t\t\txAxisID: 'xScale0',\n\t\t\t\t\tyAxisID: 'yScale0',\n\t\t\t\t\tdata: [10, 5, 0, 25, 78]\n\t\t\t\t}],\n\t\t\t\tlabels: ['tick1', 'tick2', 'tick3', 'tick4', 'tick_last']\n\t\t\t},\n\t\t\toptions: {\n\t\t\t\tscales: {\n\t\t\t\t\txAxes: [{\n\t\t\t\t\t\tid: 'xScale0',\n\t\t\t\t\t\ttype: 'category',\n\t\t\t\t\t\tposition: 'bottom',\n\t\t\t\t\t\tticks: {\n\t\t\t\t\t\t\tmin: 'tick2',\n\t\t\t\t\t\t\tmax: 'tick4'\n\t\t\t\t\t\t}\n\t\t\t\t\t}],\n\t\t\t\t\tyAxes: [{\n\t\t\t\t\t\tid: 'yScale0',\n\t\t\t\t\t\ttype: 'linear'\n\t\t\t\t\t}]\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\n\t\tvar xScale = chart.scales.xScale0;\n\t\texpect(xScale.getPixelForValue(0, 1, 0, false)).toBeCloseToPixel(23);\n\t\texpect(xScale.getPixelForValue(0, 1, 0, true)).toBeCloseToPixel(23);\n\n\t\texpect(xScale.getPixelForValue(0, 3, 0, false)).toBeCloseToPixel(496);\n\t\texpect(xScale.getPixelForValue(0, 3, 0, true)).toBeCloseToPixel(496);\n\n\t\txScale.options.gridLines.offsetGridLines = true;\n\n\t\texpect(xScale.getPixelForValue(0, 1, 0, false)).toBeCloseToPixel(23);\n\t\texpect(xScale.getPixelForValue(0, 1, 0, true)).toBeCloseToPixel(102);\n\n\t\texpect(xScale.getPixelForValue(0, 3, 0, false)).toBeCloseToPixel(338);\n\t\texpect(xScale.getPixelForValue(0, 3, 0, true)).toBeCloseToPixel(419);\n\t});\n\n\tit ('should get the correct pixel for a value when vertical', function() {\n\t\tvar chart = window.acquireChart({\n\t\t\ttype: 'line',\n\t\t\tdata: {\n\t\t\t\tdatasets: [{\n\t\t\t\t\txAxisID: 'xScale0',\n\t\t\t\t\tyAxisID: 'yScale0',\n\t\t\t\t\tdata: ['3', '5', '1', '4', '2']\n\t\t\t\t}],\n\t\t\t\tlabels: ['tick1', 'tick2', 'tick3', 'tick4', 'tick5'],\n\t\t\t\tyLabels: ['1', '2', '3', '4', '5']\n\t\t\t},\n\t\t\toptions: {\n\t\t\t\tscales: {\n\t\t\t\t\txAxes: [{\n\t\t\t\t\t\tid: 'xScale0',\n\t\t\t\t\t\ttype: 'category',\n\t\t\t\t\t\tposition: 'bottom',\n\t\t\t\t\t}],\n\t\t\t\t\tyAxes: [{\n\t\t\t\t\t\tid: 'yScale0',\n\t\t\t\t\t\ttype: 'category',\n\t\t\t\t\t\tposition: 'left'\n\t\t\t\t\t}]\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\n\t\tvar yScale = chart.scales.yScale0;\n\t\texpect(yScale.getPixelForValue(0, 0, 0, false)).toBe(32);\n\t\texpect(yScale.getPixelForValue(0, 0, 0, true)).toBe(32);\n\t\texpect(yScale.getValueForPixel(32)).toBe(0);\n\n\t\texpect(yScale.getPixelForValue(0, 4, 0, false)).toBe(484);\n\t\texpect(yScale.getPixelForValue(0, 4, 0, true)).toBe(484);\n\t\texpect(yScale.getValueForPixel(484)).toBe(4);\n\n\t\tyScale.options.gridLines.offsetGridLines = true;\n\n\t\texpect(yScale.getPixelForValue(0, 0, 0, false)).toBe(32);\n\t\texpect(yScale.getPixelForValue(0, 0, 0, true)).toBe(77);\n\t\texpect(yScale.getValueForPixel(32)).toBe(0);\n\t\texpect(yScale.getValueForPixel(77)).toBe(0);\n\n\t\texpect(yScale.getPixelForValue(0, 4, 0, false)).toBe(394);\n\t\texpect(yScale.getPixelForValue(0, 4, 0, true)).toBe(439);\n\t\texpect(yScale.getValueForPixel(394)).toBe(4);\n\t\texpect(yScale.getValueForPixel(439)).toBe(4);\n\t});\n\n\tit ('should get the correct pixel for a value when vertical and zoomed', function() {\n\t\tvar chart = window.acquireChart({\n\t\t\ttype: 'line',\n\t\t\tdata: {\n\t\t\t\tdatasets: [{\n\t\t\t\t\txAxisID: 'xScale0',\n\t\t\t\t\tyAxisID: 'yScale0',\n\t\t\t\t\tdata: ['3', '5', '1', '4', '2']\n\t\t\t\t}],\n\t\t\t\tlabels: ['tick1', 'tick2', 'tick3', 'tick4', 'tick5'],\n\t\t\t\tyLabels: ['1', '2', '3', '4', '5']\n\t\t\t},\n\t\t\toptions: {\n\t\t\t\tscales: {\n\t\t\t\t\txAxes: [{\n\t\t\t\t\t\tid: 'xScale0',\n\t\t\t\t\t\ttype: 'category',\n\t\t\t\t\t\tposition: 'bottom',\n\t\t\t\t\t}],\n\t\t\t\t\tyAxes: [{\n\t\t\t\t\t\tid: 'yScale0',\n\t\t\t\t\t\ttype: 'category',\n\t\t\t\t\t\tposition: 'left',\n\t\t\t\t\t\tticks: {\n\t\t\t\t\t\t\tmin: '2',\n\t\t\t\t\t\t\tmax: '4'\n\t\t\t\t\t\t}\n\t\t\t\t\t}]\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\n\t\tvar yScale = chart.scales.yScale0;\n\n\t\texpect(yScale.getPixelForValue(0, 1, 0, false)).toBe(32);\n\t\texpect(yScale.getPixelForValue(0, 1, 0, true)).toBe(32);\n\n\t\texpect(yScale.getPixelForValue(0, 3, 0, false)).toBe(484);\n\t\texpect(yScale.getPixelForValue(0, 3, 0, true)).toBe(484);\n\n\t\tyScale.options.gridLines.offsetGridLines = true;\n\n\t\texpect(yScale.getPixelForValue(0, 1, 0, false)).toBe(32);\n\t\texpect(yScale.getPixelForValue(0, 1, 0, true)).toBe(107);\n\n\t\texpect(yScale.getPixelForValue(0, 3, 0, false)).toBe(333);\n\t\texpect(yScale.getPixelForValue(0, 3, 0, true)).toBe(409);\n\t});\n});\n"
  },
  {
    "path": "app_backend/static/plugin/Chart.js-2.6.0/test/specs/scale.linear.tests.js",
    "content": "describe('Linear Scale', function() {\n\tit('Should register the constructor with the scale service', function() {\n\t\tvar Constructor = Chart.scaleService.getScaleConstructor('linear');\n\t\texpect(Constructor).not.toBe(undefined);\n\t\texpect(typeof Constructor).toBe('function');\n\t});\n\n\tit('Should have the correct default config', function() {\n\t\tvar defaultConfig = Chart.scaleService.getScaleDefaults('linear');\n\t\texpect(defaultConfig).toEqual({\n\t\t\tdisplay: true,\n\n\t\t\tgridLines: {\n\t\t\t\tcolor: 'rgba(0, 0, 0, 0.1)',\n\t\t\t\tdrawBorder: true,\n\t\t\t\tdrawOnChartArea: true,\n\t\t\t\tdrawTicks: true, // draw ticks extending towards the label\n\t\t\t\ttickMarkLength: 10,\n\t\t\t\tlineWidth: 1,\n\t\t\t\toffsetGridLines: false,\n\t\t\t\tdisplay: true,\n\t\t\t\tzeroLineColor: 'rgba(0,0,0,0.25)',\n\t\t\t\tzeroLineWidth: 1,\n\t\t\t\tzeroLineBorderDash: [],\n\t\t\t\tzeroLineBorderDashOffset: 0.0,\n\t\t\t\tborderDash: [],\n\t\t\t\tborderDashOffset: 0.0\n\t\t\t},\n\t\t\tposition: 'left',\n\t\t\tscaleLabel: {\n\t\t\t\tlabelString: '',\n\t\t\t\tdisplay: false,\n\t\t\t},\n\t\t\tticks: {\n\t\t\t\tbeginAtZero: false,\n\t\t\t\tminRotation: 0,\n\t\t\t\tmaxRotation: 50,\n\t\t\t\tmirror: false,\n\t\t\t\tpadding: 0,\n\t\t\t\treverse: false,\n\t\t\t\tdisplay: true,\n\t\t\t\tcallback: defaultConfig.ticks.callback, // make this work nicer, then check below\n\t\t\t\tautoSkip: true,\n\t\t\t\tautoSkipPadding: 0,\n\t\t\t\tlabelOffset: 0\n\t\t\t}\n\t\t});\n\n\t\texpect(defaultConfig.ticks.callback).toEqual(jasmine.any(Function));\n\t});\n\n\tit('Should correctly determine the max & min data values', function() {\n\t\tvar chart = window.acquireChart({\n\t\t\ttype: 'bar',\n\t\t\tdata: {\n\t\t\t\tdatasets: [{\n\t\t\t\t\tyAxisID: 'yScale0',\n\t\t\t\t\tdata: [10, 5, 0, -5, 78, -100]\n\t\t\t\t}, {\n\t\t\t\t\tyAxisID: 'yScale1',\n\t\t\t\t\tdata: [-1000, 1000],\n\t\t\t\t}, {\n\t\t\t\t\tyAxisID: 'yScale0',\n\t\t\t\t\tdata: [150]\n\t\t\t\t}],\n\t\t\t\tlabels: ['a', 'b', 'c', 'd', 'e', 'f']\n\t\t\t},\n\t\t\toptions: {\n\t\t\t\tscales: {\n\t\t\t\t\tyAxes: [{\n\t\t\t\t\t\tid: 'yScale0',\n\t\t\t\t\t\ttype: 'linear'\n\t\t\t\t\t}, {\n\t\t\t\t\t\tid: 'yScale1',\n\t\t\t\t\t\ttype: 'linear'\n\t\t\t\t\t}]\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\n\t\texpect(chart.scales.yScale0).not.toEqual(undefined); // must construct\n\t\texpect(chart.scales.yScale0.min).toBe(-100);\n\t\texpect(chart.scales.yScale0.max).toBe(150);\n\t});\n\n\tit('Should correctly determine the max & min of string data values', function() {\n\t\tvar chart = window.acquireChart({\n\t\t\ttype: 'bar',\n\t\t\tdata: {\n\t\t\t\tdatasets: [{\n\t\t\t\t\tyAxisID: 'yScale0',\n\t\t\t\t\tdata: ['10', '5', '0', '-5', '78', '-100']\n\t\t\t\t}, {\n\t\t\t\t\tyAxisID: 'yScale1',\n\t\t\t\t\tdata: ['-1000', '1000'],\n\t\t\t\t}, {\n\t\t\t\t\tyAxisID: 'yScale0',\n\t\t\t\t\tdata: ['150']\n\t\t\t\t}],\n\t\t\t\tlabels: ['a', 'b', 'c', 'd', 'e', 'f']\n\t\t\t},\n\t\t\toptions: {\n\t\t\t\tscales: {\n\t\t\t\t\tyAxes: [{\n\t\t\t\t\t\tid: 'yScale0',\n\t\t\t\t\t\ttype: 'linear'\n\t\t\t\t\t}, {\n\t\t\t\t\t\tid: 'yScale1',\n\t\t\t\t\t\ttype: 'linear'\n\t\t\t\t\t}]\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\n\t\texpect(chart.scales.yScale0).not.toEqual(undefined); // must construct\n\t\texpect(chart.scales.yScale0.min).toBe(-100);\n\t\texpect(chart.scales.yScale0.max).toBe(150);\n\t});\n\n\tit('Should correctly determine the max & min when no values provided and suggested minimum and maximum are set', function() {\n\t\tvar chart = window.acquireChart({\n\t\t\ttype: 'bar',\n\t\t\tdata: {\n\t\t\t\tdatasets: [{\n\t\t\t\t\tyAxisID: 'yScale0',\n\t\t\t\t\tdata: []\n\t\t\t\t}],\n\t\t\t\tlabels: ['a', 'b', 'c', 'd', 'e', 'f']\n\t\t\t},\n\t\t\toptions: {\n\t\t\t\tscales: {\n\t\t\t\t\tyAxes: [{\n\t\t\t\t\t\tid: 'yScale0',\n\t\t\t\t\t\ttype: 'linear',\n\t\t\t\t\t\tticks: {\n\t\t\t\t\t\t\tsuggestedMin: -10,\n\t\t\t\t\t\t\tsuggestedMax: 15\n\t\t\t\t\t\t}\n\t\t\t\t\t}]\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\n\t\texpect(chart.scales.yScale0).not.toEqual(undefined); // must construct\n\t\texpect(chart.scales.yScale0.min).toBe(-10);\n\t\texpect(chart.scales.yScale0.max).toBe(15);\n\t});\n\n\tit('Should correctly determine the max & min data values ignoring hidden datasets', function() {\n\t\tvar chart = window.acquireChart({\n\t\t\ttype: 'bar',\n\t\t\tdata: {\n\t\t\t\tdatasets: [{\n\t\t\t\t\tyAxisID: 'yScale0',\n\t\t\t\t\tdata: ['10', '5', '0', '-5', '78', '-100']\n\t\t\t\t}, {\n\t\t\t\t\tyAxisID: 'yScale1',\n\t\t\t\t\tdata: ['-1000', '1000'],\n\t\t\t\t}, {\n\t\t\t\t\tyAxisID: 'yScale0',\n\t\t\t\t\tdata: ['150'],\n\t\t\t\t\thidden: true\n\t\t\t\t}],\n\t\t\t\tlabels: ['a', 'b', 'c', 'd', 'e', 'f']\n\t\t\t},\n\t\t\toptions: {\n\t\t\t\tscales: {\n\t\t\t\t\tyAxes: [{\n\t\t\t\t\t\tid: 'yScale0',\n\t\t\t\t\t\ttype: 'linear'\n\t\t\t\t\t}, {\n\t\t\t\t\t\tid: 'yScale1',\n\t\t\t\t\t\ttype: 'linear'\n\t\t\t\t\t}]\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\n\t\texpect(chart.scales.yScale0).not.toEqual(undefined); // must construct\n\t\texpect(chart.scales.yScale0.min).toBe(-100);\n\t\texpect(chart.scales.yScale0.max).toBe(80);\n\t});\n\n\tit('Should correctly determine the max & min data values ignoring data that is NaN', function() {\n\t\tvar chart = window.acquireChart({\n\t\t\ttype: 'bar',\n\t\t\tdata: {\n\t\t\t\tdatasets: [{\n\t\t\t\t\tyAxisID: 'yScale0',\n\t\t\t\t\tdata: [null, 90, NaN, undefined, 45, 30, Infinity, -Infinity]\n\t\t\t\t}],\n\t\t\t\tlabels: ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h']\n\t\t\t},\n\t\t\toptions: {\n\t\t\t\tscales: {\n\t\t\t\t\tyAxes: [{\n\t\t\t\t\t\tid: 'yScale0',\n\t\t\t\t\t\ttype: 'linear'\n\t\t\t\t\t}]\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\n\t\texpect(chart.scales.yScale0.min).toBe(30);\n\t\texpect(chart.scales.yScale0.max).toBe(90);\n\n\t\t// Scale is now stacked\n\t\tchart.scales.yScale0.options.stacked = true;\n\t\tchart.update();\n\n\t\texpect(chart.scales.yScale0.min).toBe(0);\n\t\texpect(chart.scales.yScale0.max).toBe(90);\n\t});\n\n\tit('Should correctly determine the max & min for scatter data', function() {\n\t\tvar chart = window.acquireChart({\n\t\t\ttype: 'line',\n\t\t\tdata: {\n\t\t\t\tdatasets: [{\n\t\t\t\t\txAxisID: 'xScale0',\n\t\t\t\t\tyAxisID: 'yScale0',\n\t\t\t\t\tdata: [{\n\t\t\t\t\t\tx: 10,\n\t\t\t\t\t\ty: 100\n\t\t\t\t\t}, {\n\t\t\t\t\t\tx: -10,\n\t\t\t\t\t\ty: 0\n\t\t\t\t\t}, {\n\t\t\t\t\t\tx: 0,\n\t\t\t\t\t\ty: 0\n\t\t\t\t\t}, {\n\t\t\t\t\t\tx: 99,\n\t\t\t\t\t\ty: 7\n\t\t\t\t\t}]\n\t\t\t\t}],\n\t\t\t},\n\t\t\toptions: {\n\t\t\t\tscales: {\n\t\t\t\t\txAxes: [{\n\t\t\t\t\t\tid: 'xScale0',\n\t\t\t\t\t\ttype: 'linear',\n\t\t\t\t\t\tposition: 'bottom'\n\t\t\t\t\t}],\n\t\t\t\t\tyAxes: [{\n\t\t\t\t\t\tid: 'yScale0',\n\t\t\t\t\t\ttype: 'linear'\n\t\t\t\t\t}]\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\t\tchart.update();\n\n\t\texpect(chart.scales.xScale0.min).toBe(-20);\n\t\texpect(chart.scales.xScale0.max).toBe(100);\n\t\texpect(chart.scales.yScale0.min).toBe(0);\n\t\texpect(chart.scales.yScale0.max).toBe(100);\n\t});\n\n\tit('Should correctly get the label for the given index', function() {\n\t\tvar chart = window.acquireChart({\n\t\t\ttype: 'line',\n\t\t\tdata: {\n\t\t\t\tdatasets: [{\n\t\t\t\t\txAxisID: 'xScale0',\n\t\t\t\t\tyAxisID: 'yScale0',\n\t\t\t\t\tdata: [{\n\t\t\t\t\t\tx: 10,\n\t\t\t\t\t\ty: 100\n\t\t\t\t\t}, {\n\t\t\t\t\t\tx: -10,\n\t\t\t\t\t\ty: 0\n\t\t\t\t\t}, {\n\t\t\t\t\t\tx: 0,\n\t\t\t\t\t\ty: 0\n\t\t\t\t\t}, {\n\t\t\t\t\t\tx: 99,\n\t\t\t\t\t\ty: 7\n\t\t\t\t\t}]\n\t\t\t\t}],\n\t\t\t},\n\t\t\toptions: {\n\t\t\t\tscales: {\n\t\t\t\t\txAxes: [{\n\t\t\t\t\t\tid: 'xScale0',\n\t\t\t\t\t\ttype: 'linear',\n\t\t\t\t\t\tposition: 'bottom'\n\t\t\t\t\t}],\n\t\t\t\t\tyAxes: [{\n\t\t\t\t\t\tid: 'yScale0',\n\t\t\t\t\t\ttype: 'linear'\n\t\t\t\t\t}]\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\t\tchart.update();\n\n\t\texpect(chart.scales.yScale0.getLabelForIndex(3, 0)).toBe(7);\n\t});\n\n\tit('Should correctly determine the min and max data values when stacked mode is turned on', function() {\n\t\tvar chart = window.acquireChart({\n\t\t\ttype: 'line',\n\t\t\tdata: {\n\t\t\t\tdatasets: [{\n\t\t\t\t\tyAxisID: 'yScale0',\n\t\t\t\t\tdata: [10, 5, 0, -5, 78, -100],\n\t\t\t\t\ttype: 'bar'\n\t\t\t\t}, {\n\t\t\t\t\tyAxisID: 'yScale1',\n\t\t\t\t\tdata: [-1000, 1000],\n\t\t\t\t}, {\n\t\t\t\t\tyAxisID: 'yScale0',\n\t\t\t\t\tdata: [150, 0, 0, -100, -10, 9],\n\t\t\t\t\ttype: 'bar'\n\t\t\t\t}, {\n\t\t\t\t\tyAxisID: 'yScale0',\n\t\t\t\t\tdata: [10, 10, 10, 10, 10, 10],\n\t\t\t\t\ttype: 'line'\n\t\t\t\t}],\n\t\t\t\tlabels: ['a', 'b', 'c', 'd', 'e', 'f']\n\t\t\t},\n\t\t\toptions: {\n\t\t\t\tscales: {\n\t\t\t\t\tyAxes: [{\n\t\t\t\t\t\tid: 'yScale0',\n\t\t\t\t\t\ttype: 'linear',\n\t\t\t\t\t\tstacked: true\n\t\t\t\t\t}, {\n\t\t\t\t\t\tid: 'yScale1',\n\t\t\t\t\t\ttype: 'linear'\n\t\t\t\t\t}]\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\t\tchart.update();\n\n\t\texpect(chart.scales.yScale0.min).toBe(-150);\n\t\texpect(chart.scales.yScale0.max).toBe(200);\n\t});\n\n\tit('Should correctly determine the min and max data values when stacked mode is turned on and there are hidden datasets', function() {\n\t\tvar chart = window.acquireChart({\n\t\t\ttype: 'bar',\n\t\t\tdata: {\n\t\t\t\tdatasets: [{\n\t\t\t\t\tyAxisID: 'yScale0',\n\t\t\t\t\tdata: [10, 5, 0, -5, 78, -100],\n\t\t\t\t}, {\n\t\t\t\t\tyAxisID: 'yScale1',\n\t\t\t\t\tdata: [-1000, 1000],\n\t\t\t\t}, {\n\t\t\t\t\tyAxisID: 'yScale0',\n\t\t\t\t\tdata: [150, 0, 0, -100, -10, 9],\n\t\t\t\t}, {\n\t\t\t\t\tyAxisID: 'yScale0',\n\t\t\t\t\tdata: [10, 20, 30, 40, 50, 60],\n\t\t\t\t\thidden: true\n\t\t\t\t}],\n\t\t\t\tlabels: ['a', 'b', 'c', 'd', 'e', 'f']\n\t\t\t},\n\t\t\toptions: {\n\t\t\t\tscales: {\n\t\t\t\t\tyAxes: [{\n\t\t\t\t\t\tid: 'yScale0',\n\t\t\t\t\t\ttype: 'linear',\n\t\t\t\t\t\tstacked: true\n\t\t\t\t\t}, {\n\t\t\t\t\t\tid: 'yScale1',\n\t\t\t\t\t\ttype: 'linear'\n\t\t\t\t\t}]\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\t\tchart.update();\n\n\t\texpect(chart.scales.yScale0.min).toBe(-150);\n\t\texpect(chart.scales.yScale0.max).toBe(200);\n\t});\n\n\tit('Should correctly determine the min and max data values when stacked mode is turned on there are multiple types of datasets', function() {\n\t\tvar chart = window.acquireChart({\n\t\t\ttype: 'bar',\n\t\t\tdata: {\n\t\t\t\tdatasets: [{\n\t\t\t\t\tyAxisID: 'yScale0',\n\t\t\t\t\ttype: 'bar',\n\t\t\t\t\tdata: [10, 5, 0, -5, 78, -100]\n\t\t\t\t}, {\n\t\t\t\t\ttype: 'line',\n\t\t\t\t\tdata: [10, 10, 10, 10, 10, 10],\n\t\t\t\t}, {\n\t\t\t\t\ttype: 'bar',\n\t\t\t\t\tdata: [150, 0, 0, -100, -10, 9]\n\t\t\t\t}],\n\t\t\t\tlabels: ['a', 'b', 'c', 'd', 'e', 'f']\n\t\t\t},\n\t\t\toptions: {\n\t\t\t\tscales: {\n\t\t\t\t\tyAxes: [{\n\t\t\t\t\t\tid: 'yScale0',\n\t\t\t\t\t\ttype: 'linear',\n\t\t\t\t\t\tstacked: true\n\t\t\t\t\t}]\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\n\t\tchart.scales.yScale0.determineDataLimits();\n\t\texpect(chart.scales.yScale0.min).toBe(-105);\n\t\texpect(chart.scales.yScale0.max).toBe(160);\n\t});\n\n\tit('Should ensure that the scale has a max and min that are not equal', function() {\n\t\tvar chart = window.acquireChart({\n\t\t\ttype: 'bar',\n\t\t\tdata: {\n\t\t\t\tdatasets: [],\n\t\t\t\tlabels: ['a', 'b', 'c', 'd', 'e', 'f']\n\t\t\t},\n\t\t\toptions: {\n\t\t\t\tscales: {\n\t\t\t\t\tyAxes: [{\n\t\t\t\t\t\tid: 'yScale0',\n\t\t\t\t\t\ttype: 'linear'\n\t\t\t\t\t}]\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\n\t\texpect(chart.scales.yScale0).not.toEqual(undefined); // must construct\n\t\texpect(chart.scales.yScale0.min).toBe(-1);\n\t\texpect(chart.scales.yScale0.max).toBe(1);\n\t});\n\n\tit('Should ensure that the scale has a max and min that are not equal when beginAtZero is set', function() {\n\t\tvar chart = window.acquireChart({\n\t\t\ttype: 'bar',\n\t\t\tdata: {\n\t\t\t\tdatasets: [],\n\t\t\t\tlabels: ['a', 'b', 'c', 'd', 'e', 'f']\n\t\t\t},\n\t\t\toptions: {\n\t\t\t\tscales: {\n\t\t\t\t\tyAxes: [{\n\t\t\t\t\t\tid: 'yScale0',\n\t\t\t\t\t\ttype: 'linear',\n\t\t\t\t\t\tticks: {\n\t\t\t\t\t\t\tbeginAtZero: true\n\t\t\t\t\t\t}\n\t\t\t\t\t}]\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\n\t\texpect(chart.scales.yScale0).not.toEqual(undefined); // must construct\n\t\texpect(chart.scales.yScale0.min).toBe(0);\n\t\texpect(chart.scales.yScale0.max).toBe(1);\n\t});\n\n\tit('Should use the suggestedMin and suggestedMax options', function() {\n\t\tvar chart = window.acquireChart({\n\t\t\ttype: 'bar',\n\t\t\tdata: {\n\t\t\t\tdatasets: [{\n\t\t\t\t\tyAxisID: 'yScale0',\n\t\t\t\t\tdata: [1, 1, 1, 2, 1, 0]\n\t\t\t\t}],\n\t\t\t\tlabels: ['a', 'b', 'c', 'd', 'e', 'f']\n\t\t\t},\n\t\t\toptions: {\n\t\t\t\tscales: {\n\t\t\t\t\tyAxes: [{\n\t\t\t\t\t\tid: 'yScale0',\n\t\t\t\t\t\ttype: 'linear',\n\t\t\t\t\t\tticks: {\n\t\t\t\t\t\t\tsuggestedMax: 10,\n\t\t\t\t\t\t\tsuggestedMin: -10\n\t\t\t\t\t\t}\n\t\t\t\t\t}]\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\n\t\texpect(chart.scales.yScale0).not.toEqual(undefined); // must construct\n\t\texpect(chart.scales.yScale0.min).toBe(-10);\n\t\texpect(chart.scales.yScale0.max).toBe(10);\n\t});\n\n\tit('Should use the min and max options', function() {\n\t\tvar chart = window.acquireChart({\n\t\t\ttype: 'bar',\n\t\t\tdata: {\n\t\t\t\tdatasets: [{\n\t\t\t\t\tyAxisID: 'yScale0',\n\t\t\t\t\tdata: [1, 1, 1, 2, 1, 0]\n\t\t\t\t}],\n\t\t\t\tlabels: ['a', 'b', 'c', 'd', 'e', 'f']\n\t\t\t},\n\t\t\toptions: {\n\t\t\t\tscales: {\n\t\t\t\t\tyAxes: [{\n\t\t\t\t\t\tid: 'yScale0',\n\t\t\t\t\t\ttype: 'linear',\n\t\t\t\t\t\tticks: {\n\t\t\t\t\t\t\tmax: 1010,\n\t\t\t\t\t\t\tmin: -1010\n\t\t\t\t\t\t}\n\t\t\t\t\t}]\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\n\t\texpect(chart.scales.yScale0).not.toEqual(undefined); // must construct\n\t\texpect(chart.scales.yScale0.min).toBe(-1010);\n\t\texpect(chart.scales.yScale0.max).toBe(1010);\n\t\texpect(chart.scales.yScale0.ticks[0]).toBe('1010');\n\t\texpect(chart.scales.yScale0.ticks[chart.scales.yScale0.ticks.length - 1]).toBe('-1010');\n\t});\n\n\tit('Should use min, max and stepSize to create fixed spaced ticks', function() {\n\t\tvar chart = window.acquireChart({\n\t\t\ttype: 'bar',\n\t\t\tdata: {\n\t\t\t\tdatasets: [{\n\t\t\t\t\tyAxisID: 'yScale0',\n\t\t\t\t\tdata: [10, 3, 6, 8, 3, 1]\n\t\t\t\t}],\n\t\t\t\tlabels: ['a', 'b', 'c', 'd', 'e', 'f']\n\t\t\t},\n\t\t\toptions: {\n\t\t\t\tscales: {\n\t\t\t\t\tyAxes: [{\n\t\t\t\t\t\tid: 'yScale0',\n\t\t\t\t\t\ttype: 'linear',\n\t\t\t\t\t\tticks: {\n\t\t\t\t\t\t\tmin: 1,\n\t\t\t\t\t\t\tmax: 11,\n\t\t\t\t\t\t\tstepSize: 2\n\t\t\t\t\t\t}\n\t\t\t\t\t}]\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\n\t\texpect(chart.scales.yScale0).not.toEqual(undefined); // must construct\n\t\texpect(chart.scales.yScale0.min).toBe(1);\n\t\texpect(chart.scales.yScale0.max).toBe(11);\n\t\texpect(chart.scales.yScale0.ticks).toEqual(['11', '9', '7', '5', '3', '1']);\n\t});\n\n\n\tit('should forcibly include 0 in the range if the beginAtZero option is used', function() {\n\t\tvar chart = window.acquireChart({\n\t\t\ttype: 'bar',\n\t\t\tdata: {\n\t\t\t\tdatasets: [{\n\t\t\t\t\tyAxisID: 'yScale0',\n\t\t\t\t\tdata: [20, 30, 40, 50]\n\t\t\t\t}],\n\t\t\t\tlabels: ['a', 'b', 'c', 'd']\n\t\t\t},\n\t\t\toptions: {\n\t\t\t\tscales: {\n\t\t\t\t\tyAxes: [{\n\t\t\t\t\t\tid: 'yScale0',\n\t\t\t\t\t\ttype: 'linear',\n\t\t\t\t\t}]\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\n\t\texpect(chart.scales.yScale0).not.toEqual(undefined); // must construct\n\t\texpect(chart.scales.yScale0.ticks).toEqual(['50', '45', '40', '35', '30', '25', '20']);\n\n\t\tchart.scales.yScale0.options.ticks.beginAtZero = true;\n\t\tchart.update();\n\t\texpect(chart.scales.yScale0.ticks).toEqual(['50', '45', '40', '35', '30', '25', '20', '15', '10', '5', '0']);\n\n\t\tchart.data.datasets[0].data = [-20, -30, -40, -50];\n\t\tchart.update();\n\t\texpect(chart.scales.yScale0.ticks).toEqual(['0', '-5', '-10', '-15', '-20', '-25', '-30', '-35', '-40', '-45', '-50']);\n\n\t\tchart.scales.yScale0.options.ticks.beginAtZero = false;\n\t\tchart.update();\n\t\texpect(chart.scales.yScale0.ticks).toEqual(['-20', '-25', '-30', '-35', '-40', '-45', '-50']);\n\t});\n\n\tit('Should generate tick marks in the correct order in reversed mode', function() {\n\t\tvar chart = window.acquireChart({\n\t\t\ttype: 'bar',\n\t\t\tdata: {\n\t\t\t\tdatasets: [{\n\t\t\t\t\tyAxisID: 'yScale0',\n\t\t\t\t\tdata: [10, 5, 0, 25, 78]\n\t\t\t\t}],\n\t\t\t\tlabels: ['a', 'b', 'c', 'd']\n\t\t\t},\n\t\t\toptions: {\n\t\t\t\tscales: {\n\t\t\t\t\tyAxes: [{\n\t\t\t\t\t\tid: 'yScale0',\n\t\t\t\t\t\ttype: 'linear',\n\t\t\t\t\t\tticks: {\n\t\t\t\t\t\t\treverse: true\n\t\t\t\t\t\t}\n\t\t\t\t\t}]\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\n\t\texpect(chart.scales.yScale0.ticks).toEqual(['0', '10', '20', '30', '40', '50', '60', '70', '80']);\n\t\texpect(chart.scales.yScale0.start).toBe(80);\n\t\texpect(chart.scales.yScale0.end).toBe(0);\n\t});\n\n\tit('should use the correct number of decimal places in the default format function', function() {\n\t\tvar chart = window.acquireChart({\n\t\t\ttype: 'bar',\n\t\t\tdata: {\n\t\t\t\tdatasets: [{\n\t\t\t\t\tyAxisID: 'yScale0',\n\t\t\t\t\tdata: [0.06, 0.005, 0, 0.025, 0.0078]\n\t\t\t\t}],\n\t\t\t\tlabels: ['a', 'b', 'c', 'd']\n\t\t\t},\n\t\t\toptions: {\n\t\t\t\tscales: {\n\t\t\t\t\tyAxes: [{\n\t\t\t\t\t\tid: 'yScale0',\n\t\t\t\t\t\ttype: 'linear',\n\t\t\t\t\t}]\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\t\texpect(chart.scales.yScale0.ticks).toEqual(['0.06', '0.05', '0.04', '0.03', '0.02', '0.01', '0']);\n\t});\n\n\tit('Should build labels using the user supplied callback', function() {\n\t\tvar chart = window.acquireChart({\n\t\t\ttype: 'bar',\n\t\t\tdata: {\n\t\t\t\tdatasets: [{\n\t\t\t\t\tyAxisID: 'yScale0',\n\t\t\t\t\tdata: [10, 5, 0, 25, 78]\n\t\t\t\t}],\n\t\t\t\tlabels: ['a', 'b', 'c', 'd']\n\t\t\t},\n\t\t\toptions: {\n\t\t\t\tscales: {\n\t\t\t\t\tyAxes: [{\n\t\t\t\t\t\tid: 'yScale0',\n\t\t\t\t\t\ttype: 'linear',\n\t\t\t\t\t\tticks: {\n\t\t\t\t\t\t\tcallback: function(value, index) {\n\t\t\t\t\t\t\t\treturn index.toString();\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}]\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\n\t\t// Just the index\n\t\texpect(chart.scales.yScale0.ticks).toEqual(['0', '1', '2', '3', '4', '5', '6', '7', '8']);\n\t});\n\n\tit('Should get the correct pixel value for a point', function() {\n\t\tvar chart = window.acquireChart({\n\t\t\ttype: 'line',\n\t\t\tdata: {\n\t\t\t\tdatasets: [{\n\t\t\t\t\txAxisID: 'xScale0',\n\t\t\t\t\tyAxisID: 'yScale0',\n\t\t\t\t\tdata: []\n\t\t\t\t}],\n\t\t\t},\n\t\t\toptions: {\n\t\t\t\tscales: {\n\t\t\t\t\txAxes: [{\n\t\t\t\t\t\tid: 'xScale0',\n\t\t\t\t\t\ttype: 'linear',\n\t\t\t\t\t\tposition: 'bottom'\n\t\t\t\t\t}],\n\t\t\t\t\tyAxes: [{\n\t\t\t\t\t\tid: 'yScale0',\n\t\t\t\t\t\ttype: 'linear'\n\t\t\t\t\t}]\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\n\t\tvar xScale = chart.scales.xScale0;\n\t\texpect(xScale.getPixelForValue(1, 0, 0)).toBeCloseToPixel(501); // right - paddingRight\n\t\texpect(xScale.getPixelForValue(-1, 0, 0)).toBeCloseToPixel(31); // left + paddingLeft\n\t\texpect(xScale.getPixelForValue(0, 0, 0)).toBeCloseToPixel(266); // halfway*/\n\n\t\texpect(xScale.getValueForPixel(501)).toBeCloseTo(1, 1e-2);\n\t\texpect(xScale.getValueForPixel(31)).toBeCloseTo(-1, 1e-2);\n\t\texpect(xScale.getValueForPixel(266)).toBeCloseTo(0, 1e-2);\n\n\t\tvar yScale = chart.scales.yScale0;\n\t\texpect(yScale.getPixelForValue(1, 0, 0)).toBeCloseToPixel(32); // right - paddingRight\n\t\texpect(yScale.getPixelForValue(-1, 0, 0)).toBeCloseToPixel(484); // left + paddingLeft\n\t\texpect(yScale.getPixelForValue(0, 0, 0)).toBeCloseToPixel(258); // halfway*/\n\n\t\texpect(yScale.getValueForPixel(32)).toBe(1);\n\t\texpect(yScale.getValueForPixel(484)).toBe(-1);\n\t\texpect(yScale.getValueForPixel(258)).toBe(0);\n\t});\n\n\tit('should fit correctly', function() {\n\t\tvar chart = window.acquireChart({\n\t\t\ttype: 'line',\n\t\t\tdata: {\n\t\t\t\tdatasets: [{\n\t\t\t\t\txAxisID: 'xScale0',\n\t\t\t\t\tyAxisID: 'yScale0',\n\t\t\t\t\tdata: [{\n\t\t\t\t\t\tx: 10,\n\t\t\t\t\t\ty: 100\n\t\t\t\t\t}, {\n\t\t\t\t\t\tx: -10,\n\t\t\t\t\t\ty: 0\n\t\t\t\t\t}, {\n\t\t\t\t\t\tx: 0,\n\t\t\t\t\t\ty: 0\n\t\t\t\t\t}, {\n\t\t\t\t\t\tx: 99,\n\t\t\t\t\t\ty: 7\n\t\t\t\t\t}]\n\t\t\t\t}],\n\t\t\t},\n\t\t\toptions: {\n\t\t\t\tscales: {\n\t\t\t\t\txAxes: [{\n\t\t\t\t\t\tid: 'xScale0',\n\t\t\t\t\t\ttype: 'linear',\n\t\t\t\t\t\tposition: 'bottom'\n\t\t\t\t\t}],\n\t\t\t\t\tyAxes: [{\n\t\t\t\t\t\tid: 'yScale0',\n\t\t\t\t\t\ttype: 'linear'\n\t\t\t\t\t}]\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\n\t\tvar xScale = chart.scales.xScale0;\n\t\texpect(xScale.paddingTop).toBeCloseToPixel(0);\n\t\texpect(xScale.paddingBottom).toBeCloseToPixel(0);\n\t\texpect(xScale.paddingLeft).toBeCloseToPixel(0);\n\t\texpect(xScale.paddingRight).toBeCloseToPixel(0);\n\t\texpect(xScale.width).toBeCloseToPixel(468);\n\t\texpect(xScale.height).toBeCloseToPixel(28);\n\n\t\tvar yScale = chart.scales.yScale0;\n\t\texpect(yScale.paddingTop).toBeCloseToPixel(0);\n\t\texpect(yScale.paddingBottom).toBeCloseToPixel(0);\n\t\texpect(yScale.paddingLeft).toBeCloseToPixel(0);\n\t\texpect(yScale.paddingRight).toBeCloseToPixel(0);\n\t\texpect(yScale.width).toBeCloseToPixel(30);\n\t\texpect(yScale.height).toBeCloseToPixel(452);\n\n\t\t// Extra size when scale label showing\n\t\txScale.options.scaleLabel.display = true;\n\t\tyScale.options.scaleLabel.display = true;\n\t\tchart.update();\n\n\t\texpect(xScale.paddingTop).toBeCloseToPixel(0);\n\t\texpect(xScale.paddingBottom).toBeCloseToPixel(0);\n\t\texpect(xScale.paddingLeft).toBeCloseToPixel(0);\n\t\texpect(xScale.paddingRight).toBeCloseToPixel(0);\n\t\texpect(xScale.width).toBeCloseToPixel(450);\n\t\texpect(xScale.height).toBeCloseToPixel(46);\n\n\t\texpect(yScale.paddingTop).toBeCloseToPixel(0);\n\t\texpect(yScale.paddingBottom).toBeCloseToPixel(0);\n\t\texpect(yScale.paddingLeft).toBeCloseToPixel(0);\n\t\texpect(yScale.paddingRight).toBeCloseToPixel(0);\n\t\texpect(yScale.width).toBeCloseToPixel(48);\n\t\texpect(yScale.height).toBeCloseToPixel(434);\n\t});\n\n\tit('should fit correctly when display is turned off', function() {\n\t\tvar chart = window.acquireChart({\n\t\t\ttype: 'line',\n\t\t\tdata: {\n\t\t\t\tdatasets: [{\n\t\t\t\t\txAxisID: 'xScale0',\n\t\t\t\t\tyAxisID: 'yScale0',\n\t\t\t\t\tdata: [{\n\t\t\t\t\t\tx: 10,\n\t\t\t\t\t\ty: 100\n\t\t\t\t\t}, {\n\t\t\t\t\t\tx: -10,\n\t\t\t\t\t\ty: 0\n\t\t\t\t\t}, {\n\t\t\t\t\t\tx: 0,\n\t\t\t\t\t\ty: 0\n\t\t\t\t\t}, {\n\t\t\t\t\t\tx: 99,\n\t\t\t\t\t\ty: 7\n\t\t\t\t\t}]\n\t\t\t\t}],\n\t\t\t},\n\t\t\toptions: {\n\t\t\t\tscales: {\n\t\t\t\t\txAxes: [{\n\t\t\t\t\t\tid: 'xScale0',\n\t\t\t\t\t\ttype: 'linear',\n\t\t\t\t\t\tposition: 'bottom'\n\t\t\t\t\t}],\n\t\t\t\t\tyAxes: [{\n\t\t\t\t\t\tid: 'yScale0',\n\t\t\t\t\t\ttype: 'linear',\n\t\t\t\t\t\tgridLines: {\n\t\t\t\t\t\t\tdrawTicks: false,\n\t\t\t\t\t\t\tdrawBorder: false\n\t\t\t\t\t\t},\n\t\t\t\t\t\tscaleLabel: {\n\t\t\t\t\t\t\tdisplay: false\n\t\t\t\t\t\t},\n\t\t\t\t\t\tticks: {\n\t\t\t\t\t\t\tdisplay: false,\n\t\t\t\t\t\t\tpadding: 0\n\t\t\t\t\t\t}\n\t\t\t\t\t}]\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\n\t\tvar yScale = chart.scales.yScale0;\n\t\texpect(yScale.width).toBeCloseToPixel(0);\n\t});\n\n\tit('max and min value should be valid and finite when charts datasets are hidden', function() {\n\t\tvar barData = {\n\t\t\tlabels: ['S1', 'S2', 'S3'],\n\t\t\tdatasets: [{\n\t\t\t\tlabel: 'Closed',\n\t\t\t\tbackgroundColor: '#382765',\n\t\t\t\tdata: [2500, 2000, 1500]\n\t\t\t}, {\n\t\t\t\tlabel: 'In Progress',\n\t\t\t\tbackgroundColor: '#7BC225',\n\t\t\t\tdata: [1000, 2000, 1500]\n\t\t\t}, {\n\t\t\t\tlabel: 'Assigned',\n\t\t\t\tbackgroundColor: '#ffC225',\n\t\t\t\tdata: [1000, 2000, 1500]\n\t\t\t}]\n\t\t};\n\n\t\tvar chart = window.acquireChart({\n\t\t\ttype: 'horizontalBar',\n\t\t\tdata: barData,\n\t\t\toptions: {\n\t\t\t\tscales: {\n\t\t\t\t\txAxes: [{\n\t\t\t\t\t\tstacked: true\n\t\t\t\t\t}],\n\t\t\t\t\tyAxes: [{\n\t\t\t\t\t\tstacked: true\n\t\t\t\t\t}]\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\n\t\tbarData.datasets.forEach(function(data, index) {\n\t\t\tvar meta = chart.getDatasetMeta(index);\n\t\t\tmeta.hidden = true;\n\t\t\tchart.update();\n\t\t});\n\n\t\texpect(chart.scales['x-axis-0'].min).toEqual(0);\n\t\texpect(chart.scales['x-axis-0'].max).toEqual(1);\n\t});\n});\n"
  },
  {
    "path": "app_backend/static/plugin/Chart.js-2.6.0/test/specs/scale.logarithmic.tests.js",
    "content": "describe('Logarithmic Scale tests', function() {\n\tit('should register the constructor with the scale service', function() {\n\t\tvar Constructor = Chart.scaleService.getScaleConstructor('logarithmic');\n\t\texpect(Constructor).not.toBe(undefined);\n\t\texpect(typeof Constructor).toBe('function');\n\t});\n\n\tit('should have the correct default config', function() {\n\t\tvar defaultConfig = Chart.scaleService.getScaleDefaults('logarithmic');\n\t\texpect(defaultConfig).toEqual({\n\t\t\tdisplay: true,\n\t\t\tgridLines: {\n\t\t\t\tcolor: 'rgba(0, 0, 0, 0.1)',\n\t\t\t\tdrawBorder: true,\n\t\t\t\tdrawOnChartArea: true,\n\t\t\t\tdrawTicks: true,\n\t\t\t\ttickMarkLength: 10,\n\t\t\t\tlineWidth: 1,\n\t\t\t\toffsetGridLines: false,\n\t\t\t\tdisplay: true,\n\t\t\t\tzeroLineColor: 'rgba(0,0,0,0.25)',\n\t\t\t\tzeroLineWidth: 1,\n\t\t\t\tzeroLineBorderDash: [],\n\t\t\t\tzeroLineBorderDashOffset: 0.0,\n\t\t\t\tborderDash: [],\n\t\t\t\tborderDashOffset: 0.0\n\t\t\t},\n\t\t\tposition: 'left',\n\t\t\tscaleLabel: {\n\t\t\t\tlabelString: '',\n\t\t\t\tdisplay: false,\n\t\t\t},\n\t\t\tticks: {\n\t\t\t\tbeginAtZero: false,\n\t\t\t\tminRotation: 0,\n\t\t\t\tmaxRotation: 50,\n\t\t\t\tmirror: false,\n\t\t\t\tpadding: 0,\n\t\t\t\treverse: false,\n\t\t\t\tdisplay: true,\n\t\t\t\tcallback: defaultConfig.ticks.callback, // make this nicer, then check explicitly below\n\t\t\t\tautoSkip: true,\n\t\t\t\tautoSkipPadding: 0,\n\t\t\t\tlabelOffset: 0\n\t\t\t},\n\t\t});\n\n\t\t// Is this actually a function\n\t\texpect(defaultConfig.ticks.callback).toEqual(jasmine.any(Function));\n\t});\n\n\tit('should correctly determine the max & min data values', function() {\n\t\tvar chart = window.acquireChart({\n\t\t\ttype: 'bar',\n\t\t\tdata: {\n\t\t\t\tdatasets: [{\n\t\t\t\t\tyAxisID: 'yScale0',\n\t\t\t\t\tdata: [42, 1000, 64, 100],\n\t\t\t\t}, {\n\t\t\t\t\tyAxisID: 'yScale1',\n\t\t\t\t\tdata: [10, 5, 5000, 78, 450]\n\t\t\t\t}, {\n\t\t\t\t\tyAxisID: 'yScale1',\n\t\t\t\t\tdata: [150]\n\t\t\t\t}, {\n\t\t\t\t\tyAxisID: 'yScale2',\n\t\t\t\t\tdata: [20, 0, 150, 1800, 3040]\n\t\t\t\t}, {\n\t\t\t\t\tyAxisID: 'yScale3',\n\t\t\t\t\tdata: [67, 0.0004, 0, 820, 0.001]\n\t\t\t\t}],\n\t\t\t\tlabels: ['a', 'b', 'c', 'd', 'e']\n\t\t\t},\n\t\t\toptions: {\n\t\t\t\tscales: {\n\t\t\t\t\tyAxes: [{\n\t\t\t\t\t\tid: 'yScale0',\n\t\t\t\t\t\ttype: 'logarithmic'\n\t\t\t\t\t}, {\n\t\t\t\t\t\tid: 'yScale1',\n\t\t\t\t\t\ttype: 'logarithmic'\n\t\t\t\t\t}, {\n\t\t\t\t\t\tid: 'yScale2',\n\t\t\t\t\t\ttype: 'logarithmic'\n\t\t\t\t\t}, {\n\t\t\t\t\t\tid: 'yScale3',\n\t\t\t\t\t\ttype: 'logarithmic'\n\t\t\t\t\t}]\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\n\t\texpect(chart.scales.yScale0).not.toEqual(undefined); // must construct\n\t\texpect(chart.scales.yScale0.min).toBe(10);\n\t\texpect(chart.scales.yScale0.max).toBe(1000);\n\n\t\texpect(chart.scales.yScale1).not.toEqual(undefined); // must construct\n\t\texpect(chart.scales.yScale1.min).toBe(1);\n\t\texpect(chart.scales.yScale1.max).toBe(5000);\n\n\t\texpect(chart.scales.yScale2).not.toEqual(undefined); // must construct\n\t\texpect(chart.scales.yScale2.min).toBe(0);\n\t\texpect(chart.scales.yScale2.max).toBe(4000);\n\n\t\texpect(chart.scales.yScale3).not.toEqual(undefined); // must construct\n\t\texpect(chart.scales.yScale3.min).toBe(0);\n\t\texpect(chart.scales.yScale3.max).toBe(900);\n\t});\n\n\tit('should correctly determine the max & min of string data values', function() {\n\t\tvar chart = window.acquireChart({\n\t\t\ttype: 'line',\n\t\t\tdata: {\n\t\t\t\tdatasets: [{\n\t\t\t\t\tyAxisID: 'yScale0',\n\t\t\t\t\tdata: ['42', '1000', '64', '100'],\n\t\t\t\t}, {\n\t\t\t\t\tyAxisID: 'yScale1',\n\t\t\t\t\tdata: ['10', '5', '5000', '78', '450']\n\t\t\t\t}, {\n\t\t\t\t\tyAxisID: 'yScale1',\n\t\t\t\t\tdata: ['150']\n\t\t\t\t}, {\n\t\t\t\t\tyAxisID: 'yScale2',\n\t\t\t\t\tdata: ['20', '0', '150', '1800', '3040']\n\t\t\t\t}, {\n\t\t\t\t\tyAxisID: 'yScale3',\n\t\t\t\t\tdata: ['67', '0.0004', '0', '820', '0.001']\n\t\t\t\t}],\n\t\t\t\tlabels: ['a', 'b', 'c', 'd', 'e']\n\t\t\t},\n\t\t\toptions: {\n\t\t\t\tscales: {\n\t\t\t\t\tyAxes: [{\n\t\t\t\t\t\tid: 'yScale0',\n\t\t\t\t\t\ttype: 'logarithmic'\n\t\t\t\t\t}, {\n\t\t\t\t\t\tid: 'yScale1',\n\t\t\t\t\t\ttype: 'logarithmic'\n\t\t\t\t\t}, {\n\t\t\t\t\t\tid: 'yScale2',\n\t\t\t\t\t\ttype: 'logarithmic'\n\t\t\t\t\t}, {\n\t\t\t\t\t\tid: 'yScale3',\n\t\t\t\t\t\ttype: 'logarithmic'\n\t\t\t\t\t}]\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\n\t\texpect(chart.scales.yScale0).not.toEqual(undefined); // must construct\n\t\texpect(chart.scales.yScale0.min).toBe(10);\n\t\texpect(chart.scales.yScale0.max).toBe(1000);\n\n\t\texpect(chart.scales.yScale1).not.toEqual(undefined); // must construct\n\t\texpect(chart.scales.yScale1.min).toBe(1);\n\t\texpect(chart.scales.yScale1.max).toBe(5000);\n\n\t\texpect(chart.scales.yScale2).not.toEqual(undefined); // must construct\n\t\texpect(chart.scales.yScale2.min).toBe(0);\n\t\texpect(chart.scales.yScale2.max).toBe(4000);\n\n\t\texpect(chart.scales.yScale3).not.toEqual(undefined); // must construct\n\t\texpect(chart.scales.yScale3.min).toBe(0);\n\t\texpect(chart.scales.yScale3.max).toBe(900);\n\t});\n\n\tit('should correctly determine the max & min data values when there are hidden datasets', function() {\n\t\tvar chart = window.acquireChart({\n\t\t\ttype: 'line',\n\t\t\tdata: {\n\t\t\t\tdatasets: [{\n\t\t\t\t\tyAxisID: 'yScale1',\n\t\t\t\t\tdata: [10, 5, 5000, 78, 450]\n\t\t\t\t}, {\n\t\t\t\t\tyAxisID: 'yScale0',\n\t\t\t\t\tdata: [42, 1000, 64, 100],\n\t\t\t\t}, {\n\t\t\t\t\tyAxisID: 'yScale1',\n\t\t\t\t\tdata: [50000],\n\t\t\t\t\thidden: true\n\t\t\t\t}, {\n\t\t\t\t\tyAxisID: 'yScale2',\n\t\t\t\t\tdata: [20, 0, 7400, 14, 291]\n\t\t\t\t}, {\n\t\t\t\t\tyAxisID: 'yScale2',\n\t\t\t\t\tdata: [6, 0.0007, 9, 890, 60000],\n\t\t\t\t\thidden: true\n\t\t\t\t}],\n\t\t\t\tlabels: ['a', 'b', 'c', 'd', 'e']\n\t\t\t},\n\t\t\toptions: {\n\t\t\t\tscales: {\n\t\t\t\t\tyAxes: [{\n\t\t\t\t\t\tid: 'yScale0',\n\t\t\t\t\t\ttype: 'logarithmic'\n\t\t\t\t\t}, {\n\t\t\t\t\t\tid: 'yScale1',\n\t\t\t\t\t\ttype: 'logarithmic'\n\t\t\t\t\t}, {\n\t\t\t\t\t\tid: 'yScale2',\n\t\t\t\t\t\ttype: 'logarithmic'\n\t\t\t\t\t}]\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\n\t\texpect(chart.scales.yScale1).not.toEqual(undefined); // must construct\n\t\texpect(chart.scales.yScale1.min).toBe(1);\n\t\texpect(chart.scales.yScale1.max).toBe(5000);\n\n\t\texpect(chart.scales.yScale2).not.toEqual(undefined); // must construct\n\t\texpect(chart.scales.yScale2.min).toBe(0);\n\t\texpect(chart.scales.yScale2.max).toBe(8000);\n\t});\n\n\tit('should correctly determine the max & min data values when there is NaN data', function() {\n\t\tvar chart = window.acquireChart({\n\t\t\ttype: 'bar',\n\t\t\tdata: {\n\t\t\t\tdatasets: [{\n\t\t\t\t\tyAxisID: 'yScale0',\n\t\t\t\t\tdata: [undefined, 10, null, 5, 5000, NaN, 78, 450]\n\t\t\t\t}, {\n\t\t\t\t\tyAxisID: 'yScale0',\n\t\t\t\t\tdata: [undefined, 28, null, 1000, 500, NaN, 50, 42, Infinity, -Infinity]\n\t\t\t\t}, {\n\t\t\t\t\tyAxisID: 'yScale1',\n\t\t\t\t\tdata: [undefined, 30, null, 9400, 0, NaN, 54, 836]\n\t\t\t\t}, {\n\t\t\t\t\tyAxisID: 'yScale1',\n\t\t\t\t\tdata: [undefined, 0, null, 800, 9, NaN, 894, 21]\n\t\t\t\t}],\n\t\t\t\tlabels: ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i']\n\t\t\t},\n\t\t\toptions: {\n\t\t\t\tscales: {\n\t\t\t\t\tyAxes: [{\n\t\t\t\t\t\tid: 'yScale0',\n\t\t\t\t\t\ttype: 'logarithmic'\n\t\t\t\t\t}, {\n\t\t\t\t\t\tid: 'yScale1',\n\t\t\t\t\t\ttype: 'logarithmic'\n\t\t\t\t\t}]\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\n\t\texpect(chart.scales.yScale0).not.toEqual(undefined); // must construct\n\t\texpect(chart.scales.yScale0.min).toBe(1);\n\t\texpect(chart.scales.yScale0.max).toBe(5000);\n\n\t\t// Turn on stacked mode since it uses it's own\n\t\tchart.options.scales.yAxes[0].stacked = true;\n\t\tchart.update();\n\n\t\texpect(chart.scales.yScale0.min).toBe(10);\n\t\texpect(chart.scales.yScale0.max).toBe(6000);\n\n\t\texpect(chart.scales.yScale1).not.toEqual(undefined); // must construct\n\t\texpect(chart.scales.yScale1.min).toBe(0);\n\t\texpect(chart.scales.yScale1.max).toBe(10000);\n\t});\n\n\tit('should correctly determine the max & min for scatter data', function() {\n\t\tvar chart = window.acquireChart({\n\t\t\ttype: 'line',\n\t\t\tdata: {\n\t\t\t\tdatasets: [{\n\t\t\t\t\tdata: [\n\t\t\t\t\t\t{x: 10, y: 100},\n\t\t\t\t\t\t{x: 2, y: 6},\n\t\t\t\t\t\t{x: 65, y: 121},\n\t\t\t\t\t\t{x: 99, y: 7}\n\t\t\t\t\t]\n\t\t\t\t}]\n\t\t\t},\n\t\t\toptions: {\n\t\t\t\tscales: {\n\t\t\t\t\txAxes: [{\n\t\t\t\t\t\tid: 'xScale',\n\t\t\t\t\t\ttype: 'logarithmic',\n\t\t\t\t\t\tposition: 'bottom'\n\t\t\t\t\t}],\n\t\t\t\t\tyAxes: [{\n\t\t\t\t\t\tid: 'yScale',\n\t\t\t\t\t\ttype: 'logarithmic'\n\t\t\t\t\t}]\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\n\t\texpect(chart.scales.xScale.min).toBe(1);\n\t\texpect(chart.scales.xScale.max).toBe(100);\n\n\t\texpect(chart.scales.yScale.min).toBe(1);\n\t\texpect(chart.scales.yScale.max).toBe(200);\n\t});\n\n\tit('should correctly determine the max & min for scatter data when 0 values are present', function() {\n\t\tvar chart = window.acquireChart({\n\t\t\ttype: 'line',\n\t\t\tdata: {\n\t\t\t\tdatasets: [{\n\t\t\t\t\tdata: [\n\t\t\t\t\t\t{x: 7, y: 950},\n\t\t\t\t\t\t{x: 289, y: 0},\n\t\t\t\t\t\t{x: 0, y: 8},\n\t\t\t\t\t\t{x: 23, y: 0.04}\n\t\t\t\t\t]\n\t\t\t\t}]\n\t\t\t},\n\t\t\toptions: {\n\t\t\t\tscales: {\n\t\t\t\t\txAxes: [{\n\t\t\t\t\t\tid: 'xScale',\n\t\t\t\t\t\ttype: 'logarithmic',\n\t\t\t\t\t\tposition: 'bottom'\n\t\t\t\t\t}],\n\t\t\t\t\tyAxes: [{\n\t\t\t\t\t\tid: 'yScale',\n\t\t\t\t\t\ttype: 'logarithmic'\n\t\t\t\t\t}]\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\n\t\texpect(chart.scales.xScale.min).toBe(0);\n\t\texpect(chart.scales.xScale.max).toBe(300);\n\n\t\texpect(chart.scales.yScale.min).toBe(0);\n\t\texpect(chart.scales.yScale.max).toBe(1000);\n\t});\n\n\tit('should correctly determine the min and max data values when stacked mode is turned on', function() {\n\t\tvar chart = window.acquireChart({\n\t\t\ttype: 'bar',\n\t\t\tdata: {\n\t\t\t\tdatasets: [{\n\t\t\t\t\ttype: 'bar',\n\t\t\t\t\tyAxisID: 'yScale0',\n\t\t\t\t\tdata: [10, 5, 1, 5, 78, 100]\n\t\t\t\t}, {\n\t\t\t\t\tyAxisID: 'yScale1',\n\t\t\t\t\tdata: [0, 1000],\n\t\t\t\t}, {\n\t\t\t\t\ttype: 'bar',\n\t\t\t\t\tyAxisID: 'yScale0',\n\t\t\t\t\tdata: [150, 10, 10, 100, 10, 9]\n\t\t\t\t}, {\n\t\t\t\t\ttype: 'line',\n\t\t\t\t\tyAxisID: 'yScale0',\n\t\t\t\t\tdata: [100, 100, 100, 100, 100, 100]\n\t\t\t\t}],\n\t\t\t\tlabels: ['a', 'b', 'c', 'd', 'e', 'f']\n\t\t\t},\n\t\t\toptions: {\n\t\t\t\tscales: {\n\t\t\t\t\tyAxes: [{\n\t\t\t\t\t\tid: 'yScale0',\n\t\t\t\t\t\ttype: 'logarithmic',\n\t\t\t\t\t\tstacked: true\n\t\t\t\t\t}, {\n\t\t\t\t\t\tid: 'yScale1',\n\t\t\t\t\t\ttype: 'logarithmic'\n\t\t\t\t\t}]\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\n\t\texpect(chart.scales.yScale0.min).toBe(10);\n\t\texpect(chart.scales.yScale0.max).toBe(200);\n\t});\n\n\tit('should correctly determine the min and max data values when stacked mode is turned on ignoring hidden datasets', function() {\n\t\tvar chart = window.acquireChart({\n\t\t\ttype: 'bar',\n\t\t\tdata: {\n\t\t\t\tdatasets: [{\n\t\t\t\t\tyAxisID: 'yScale0',\n\t\t\t\t\tdata: [10, 5, 1, 5, 78, 100],\n\t\t\t\t\ttype: 'bar'\n\t\t\t\t}, {\n\t\t\t\t\tyAxisID: 'yScale1',\n\t\t\t\t\tdata: [0, 1000],\n\t\t\t\t\ttype: 'bar'\n\t\t\t\t}, {\n\t\t\t\t\tyAxisID: 'yScale0',\n\t\t\t\t\tdata: [150, 10, 10, 100, 10, 9],\n\t\t\t\t\ttype: 'bar'\n\t\t\t\t}, {\n\t\t\t\t\tyAxisID: 'yScale0',\n\t\t\t\t\tdata: [10000, 10000, 10000, 10000, 10000, 10000],\n\t\t\t\t\thidden: true,\n\t\t\t\t\ttype: 'bar'\n\t\t\t\t}],\n\t\t\t\tlabels: ['a', 'b', 'c', 'd', 'e', 'f']\n\t\t\t},\n\t\t\toptions: {\n\t\t\t\tscales: {\n\t\t\t\t\tyAxes: [{\n\t\t\t\t\t\tid: 'yScale0',\n\t\t\t\t\t\ttype: 'logarithmic',\n\t\t\t\t\t\tstacked: true\n\t\t\t\t\t}, {\n\t\t\t\t\t\tid: 'yScale1',\n\t\t\t\t\t\ttype: 'logarithmic'\n\t\t\t\t\t}]\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\n\t\texpect(chart.scales.yScale0.min).toBe(10);\n\t\texpect(chart.scales.yScale0.max).toBe(200);\n\t});\n\n\tit('should ensure that the scale has a max and min that are not equal', function() {\n\t\tvar chart = window.acquireChart({\n\t\t\ttype: 'bar',\n\t\t\tdata: {\n\t\t\t\tdatasets: [{\n\t\t\t\t\tdata: []\n\t\t\t\t}],\n\t\t\t\tlabels: []\n\t\t\t},\n\t\t\toptions: {\n\t\t\t\tscales: {\n\t\t\t\t\tyAxes: [{\n\t\t\t\t\t\tid: 'yScale',\n\t\t\t\t\t\ttype: 'logarithmic'\n\t\t\t\t\t}]\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\n\t\texpect(chart.scales.yScale.min).toBe(1);\n\t\texpect(chart.scales.yScale.max).toBe(10);\n\n\t\tchart.data.datasets[0].data = [0.15, 0.15];\n\t\tchart.update();\n\n\t\texpect(chart.scales.yScale.min).toBe(0.01);\n\t\texpect(chart.scales.yScale.max).toBe(1);\n\t});\n\n\tit('should use the min and max options', function() {\n\t\tvar chart = window.acquireChart({\n\t\t\ttype: 'bar',\n\t\t\tdata: {\n\t\t\t\tdatasets: [{\n\t\t\t\t\tdata: [1, 1, 1, 2, 1, 0]\n\t\t\t\t}],\n\t\t\t\tlabels: []\n\t\t\t},\n\t\t\toptions: {\n\t\t\t\tscales: {\n\t\t\t\t\tyAxes: [{\n\t\t\t\t\t\tid: 'yScale',\n\t\t\t\t\t\ttype: 'logarithmic',\n\t\t\t\t\t\tticks: {\n\t\t\t\t\t\t\tmin: 10,\n\t\t\t\t\t\t\tmax: 1010,\n\t\t\t\t\t\t\tcallback: function(value) {\n\t\t\t\t\t\t\t\treturn value;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}]\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\n\t\tvar yScale = chart.scales.yScale;\n\t\tvar tickCount = yScale.ticks.length;\n\t\texpect(yScale.min).toBe(10);\n\t\texpect(yScale.max).toBe(1010);\n\t\texpect(yScale.ticks[0]).toBe(1010);\n\t\texpect(yScale.ticks[tickCount - 1]).toBe(10);\n\t});\n\n\tit('should generate tick marks', function() {\n\t\tvar chart = window.acquireChart({\n\t\t\ttype: 'bar',\n\t\t\tdata: {\n\t\t\t\tdatasets: [{\n\t\t\t\t\tdata: [10, 5, 1, 25, 78]\n\t\t\t\t}],\n\t\t\t\tlabels: []\n\t\t\t},\n\t\t\toptions: {\n\t\t\t\tscales: {\n\t\t\t\t\tyAxes: [{\n\t\t\t\t\t\tid: 'yScale',\n\t\t\t\t\t\ttype: 'logarithmic',\n\t\t\t\t\t\tticks: {\n\t\t\t\t\t\t\tcallback: function(value) {\n\t\t\t\t\t\t\t\treturn value;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}]\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\n\t\t// Counts down because the lines are drawn top to bottom\n\t\texpect(chart.scales.yScale).toEqual(jasmine.objectContaining({\n\t\t\tticks: [80, 70, 60, 50, 40, 30, 20, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1],\n\t\t\tstart: 1,\n\t\t\tend: 80\n\t\t}));\n\t});\n\n\tit('should generate tick marks when 0 values are present', function() {\n\t\tvar chart = window.acquireChart({\n\t\t\ttype: 'bar',\n\t\t\tdata: {\n\t\t\t\tdatasets: [{\n\t\t\t\t\tdata: [11, 0.8, 0, 28, 7]\n\t\t\t\t}],\n\t\t\t\tlabels: []\n\t\t\t},\n\t\t\toptions: {\n\t\t\t\tscales: {\n\t\t\t\t\tyAxes: [{\n\t\t\t\t\t\tid: 'yScale',\n\t\t\t\t\t\ttype: 'logarithmic',\n\t\t\t\t\t\tticks: {\n\t\t\t\t\t\t\tcallback: function(value) {\n\t\t\t\t\t\t\t\treturn value;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}]\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\n\t\t// Counts down because the lines are drawn top to bottom\n\t\texpect(chart.scales.yScale).toEqual(jasmine.objectContaining({\n\t\t\tticks: [30, 20, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0.9, 0.8, 0],\n\t\t\tstart: 0,\n\t\t\tend: 30\n\t\t}));\n\t});\n\n\n\tit('should generate tick marks in the correct order in reversed mode', function() {\n\t\tvar chart = window.acquireChart({\n\t\t\ttype: 'line',\n\t\t\tdata: {\n\t\t\t\tdatasets: [{\n\t\t\t\t\tdata: [10, 5, 1, 25, 78]\n\t\t\t\t}],\n\t\t\t\tlabels: []\n\t\t\t},\n\t\t\toptions: {\n\t\t\t\tscales: {\n\t\t\t\t\tyAxes: [{\n\t\t\t\t\t\tid: 'yScale',\n\t\t\t\t\t\ttype: 'logarithmic',\n\t\t\t\t\t\tticks: {\n\t\t\t\t\t\t\treverse: true,\n\t\t\t\t\t\t\tcallback: function(value) {\n\t\t\t\t\t\t\t\treturn value;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}]\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\n\t\t// Counts down because the lines are drawn top to bottom\n\t\texpect(chart.scales.yScale).toEqual(jasmine.objectContaining({\n\t\t\tticks: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 20, 30, 40, 50, 60, 70, 80],\n\t\t\tstart: 80,\n\t\t\tend: 1\n\t\t}));\n\t});\n\n\tit('should generate tick marks in the correct order in reversed mode when 0 values are present', function() {\n\t\tvar chart = window.acquireChart({\n\t\t\ttype: 'line',\n\t\t\tdata: {\n\t\t\t\tdatasets: [{\n\t\t\t\t\tdata: [21, 9, 0, 10, 25]\n\t\t\t\t}],\n\t\t\t\tlabels: []\n\t\t\t},\n\t\t\toptions: {\n\t\t\t\tscales: {\n\t\t\t\t\tyAxes: [{\n\t\t\t\t\t\tid: 'yScale',\n\t\t\t\t\t\ttype: 'logarithmic',\n\t\t\t\t\t\tticks: {\n\t\t\t\t\t\t\treverse: true,\n\t\t\t\t\t\t\tcallback: function(value) {\n\t\t\t\t\t\t\t\treturn value;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}]\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\n\t\t// Counts down because the lines are drawn top to bottom\n\t\texpect(chart.scales.yScale).toEqual(jasmine.objectContaining({\n\t\t\tticks: [0, 9, 10, 20, 30],\n\t\t\tstart: 30,\n\t\t\tend: 0\n\t\t}));\n\t});\n\n\tit('should build labels using the default template', function() {\n\t\tvar chart = window.acquireChart({\n\t\t\ttype: 'line',\n\t\t\tdata: {\n\t\t\t\tdatasets: [{\n\t\t\t\t\tdata: [10, 5, 1, 25, 0, 78]\n\t\t\t\t}],\n\t\t\t\tlabels: []\n\t\t\t},\n\t\t\toptions: {\n\t\t\t\tscales: {\n\t\t\t\t\tyAxes: [{\n\t\t\t\t\t\tid: 'yScale',\n\t\t\t\t\t\ttype: 'logarithmic'\n\t\t\t\t\t}]\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\n\t\texpect(chart.scales.yScale.ticks).toEqual(['8e+1', '', '', '5e+1', '', '', '2e+1', '1e+1', '', '', '', '', '5e+0', '', '', '2e+0', '1e+0', '0']);\n\t});\n\n\tit('should build labels using the user supplied callback', function() {\n\t\tvar chart = window.acquireChart({\n\t\t\ttype: 'bar',\n\t\t\tdata: {\n\t\t\t\tdatasets: [{\n\t\t\t\t\tdata: [10, 5, 1, 25, 78]\n\t\t\t\t}],\n\t\t\t\tlabels: []\n\t\t\t},\n\t\t\toptions: {\n\t\t\t\tscales: {\n\t\t\t\t\tyAxes: [{\n\t\t\t\t\t\tid: 'yScale',\n\t\t\t\t\t\ttype: 'logarithmic',\n\t\t\t\t\t\tticks: {\n\t\t\t\t\t\t\tcallback: function(value, index) {\n\t\t\t\t\t\t\t\treturn index.toString();\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}]\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\n\t\t// Just the index\n\t\texpect(chart.scales.yScale.ticks).toEqual(['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12', '13', '14', '15', '16']);\n\t});\n\n\tit('should correctly get the correct label for a data item', function() {\n\t\tvar chart = window.acquireChart({\n\t\t\ttype: 'bar',\n\t\t\tdata: {\n\t\t\t\tdatasets: [{\n\t\t\t\t\tyAxisID: 'yScale0',\n\t\t\t\t\tdata: [10, 5, 5000, 78, 450]\n\t\t\t\t}, {\n\t\t\t\t\tyAxisID: 'yScale1',\n\t\t\t\t\tdata: [1, 1000, 10, 100],\n\t\t\t\t}, {\n\t\t\t\t\tyAxisID: 'yScale0',\n\t\t\t\t\tdata: [150]\n\t\t\t\t}],\n\t\t\t\tlabels: []\n\t\t\t},\n\t\t\toptions: {\n\t\t\t\tscales: {\n\t\t\t\t\tyAxes: [{\n\t\t\t\t\t\tid: 'yScale0',\n\t\t\t\t\t\ttype: 'logarithmic'\n\t\t\t\t\t}, {\n\t\t\t\t\t\tid: 'yScale1',\n\t\t\t\t\t\ttype: 'logarithmic'\n\t\t\t\t\t}]\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\n\t\texpect(chart.scales.yScale1.getLabelForIndex(0, 2)).toBe(150);\n\t});\n\n\tit('should get the correct pixel value for a point', function() {\n\t\tvar chart = window.acquireChart({\n\t\t\ttype: 'line',\n\t\t\tdata: {\n\t\t\t\tdatasets: [{\n\t\t\t\t\txAxisID: 'xScale', // for the horizontal scale\n\t\t\t\t\tyAxisID: 'yScale',\n\t\t\t\t\tdata: [{x: 10, y: 10}, {x: 5, y: 5}, {x: 1, y: 1}, {x: 25, y: 25}, {x: 78, y: 78}]\n\t\t\t\t}],\n\t\t\t},\n\t\t\toptions: {\n\t\t\t\tscales: {\n\t\t\t\t\txAxes: [{\n\t\t\t\t\t\tid: 'xScale',\n\t\t\t\t\t\ttype: 'logarithmic'\n\t\t\t\t\t}],\n\t\t\t\t\tyAxes: [{\n\t\t\t\t\t\tid: 'yScale',\n\t\t\t\t\t\ttype: 'logarithmic'\n\t\t\t\t\t}]\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\n\t\tvar xScale = chart.scales.xScale;\n\t\texpect(xScale.getPixelForValue(80, 0, 0)).toBeCloseToPixel(495);  // right - paddingRight\n\t\texpect(xScale.getPixelForValue(1, 0, 0)).toBeCloseToPixel(37);   // left + paddingLeft\n\t\texpect(xScale.getPixelForValue(10, 0, 0)).toBeCloseToPixel(278);  // halfway\n\t\texpect(xScale.getPixelForValue(0, 0, 0)).toBeCloseToPixel(37);   // 0 is invalid, put it on the left.\n\n\t\texpect(xScale.getValueForPixel(495)).toBeCloseToPixel(80);\n\t\texpect(xScale.getValueForPixel(48)).toBeCloseTo(1, 1e-4);\n\t\texpect(xScale.getValueForPixel(278)).toBeCloseTo(10, 1e-4);\n\n\t\tvar yScale = chart.scales.yScale;\n\t\texpect(yScale.getPixelForValue(80, 0, 0)).toBeCloseToPixel(32);   // top + paddingTop\n\t\texpect(yScale.getPixelForValue(1, 0, 0)).toBeCloseToPixel(484);  // bottom - paddingBottom\n\t\texpect(yScale.getPixelForValue(10, 0, 0)).toBeCloseToPixel(246);  // halfway\n\t\texpect(yScale.getPixelForValue(0, 0, 0)).toBeCloseToPixel(484);   // 0 is invalid. force it on bottom\n\n\t\texpect(yScale.getValueForPixel(32)).toBeCloseTo(80, 1e-4);\n\t\texpect(yScale.getValueForPixel(484)).toBeCloseTo(1, 1e-4);\n\t\texpect(yScale.getValueForPixel(246)).toBeCloseTo(10, 1e-4);\n\t});\n\n\tit('should get the correct pixel value for a point when 0 values are present', function() {\n\t\tvar chart = window.acquireChart({\n\t\t\ttype: 'bar',\n\t\t\tdata: {\n\t\t\t\tdatasets: [{\n\t\t\t\t\tyAxisID: 'yScale',\n\t\t\t\t\tdata: [0.063, 4, 0, 63, 10, 0.5]\n\t\t\t\t}],\n\t\t\t\tlabels: []\n\t\t\t},\n\t\t\toptions: {\n\t\t\t\tscales: {\n\t\t\t\t\tyAxes: [{\n\t\t\t\t\t\tid: 'yScale',\n\t\t\t\t\t\ttype: 'logarithmic',\n\t\t\t\t\t\tticks: {\n\t\t\t\t\t\t\treverse: false\n\t\t\t\t\t\t}\n\t\t\t\t\t}]\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\n\t\tvar yScale = chart.scales.yScale;\n\t\texpect(yScale.getPixelForValue(70, 0, 0)).toBeCloseToPixel(32);   // top + paddingTop\n\t\texpect(yScale.getPixelForValue(0, 0, 0)).toBeCloseToPixel(484);  // bottom - paddingBottom\n\t\texpect(yScale.getPixelForValue(0.063, 0, 0)).toBeCloseToPixel(475);  // minNotZero 2% from range\n\t\texpect(yScale.getPixelForValue(0.5, 0, 0)).toBeCloseToPixel(344);\n\t\texpect(yScale.getPixelForValue(4, 0, 0)).toBeCloseToPixel(213);\n\t\texpect(yScale.getPixelForValue(10, 0, 0)).toBeCloseToPixel(155);\n\t\texpect(yScale.getPixelForValue(63, 0, 0)).toBeCloseToPixel(38.5);\n\n\t\tchart.options.scales.yAxes[0].ticks.reverse = true;   // Reverse mode\n\t\tchart.update();\n\n\t\texpect(yScale.getPixelForValue(70, 0, 0)).toBeCloseToPixel(484); // bottom - paddingBottom\n\t\texpect(yScale.getPixelForValue(0, 0, 0)).toBeCloseToPixel(32);  // top + paddingTop\n\t\texpect(yScale.getPixelForValue(0.063, 0, 0)).toBeCloseToPixel(41);  // minNotZero 2% from range\n\t\texpect(yScale.getPixelForValue(0.5, 0, 0)).toBeCloseToPixel(172);\n\t\texpect(yScale.getPixelForValue(4, 0, 0)).toBeCloseToPixel(303);\n\t\texpect(yScale.getPixelForValue(10, 0, 0)).toBeCloseToPixel(361);\n\t\texpect(yScale.getPixelForValue(63, 0, 0)).toBeCloseToPixel(477);\n\t});\n});\n"
  },
  {
    "path": "app_backend/static/plugin/Chart.js-2.6.0/test/specs/scale.radialLinear.tests.js",
    "content": "// Tests for the radial linear scale used by the polar area and radar charts\ndescribe('Test the radial linear scale', function() {\n\tit('Should register the constructor with the scale service', function() {\n\t\tvar Constructor = Chart.scaleService.getScaleConstructor('radialLinear');\n\t\texpect(Constructor).not.toBe(undefined);\n\t\texpect(typeof Constructor).toBe('function');\n\t});\n\n\tit('Should have the correct default config', function() {\n\t\tvar defaultConfig = Chart.scaleService.getScaleDefaults('radialLinear');\n\t\texpect(defaultConfig).toEqual({\n\t\t\tangleLines: {\n\t\t\t\tdisplay: true,\n\t\t\t\tcolor: 'rgba(0, 0, 0, 0.1)',\n\t\t\t\tlineWidth: 1\n\t\t\t},\n\t\t\tanimate: true,\n\t\t\tdisplay: true,\n\t\t\tgridLines: {\n\t\t\t\tcircular: false,\n\t\t\t\tcolor: 'rgba(0, 0, 0, 0.1)',\n\t\t\t\tdrawBorder: true,\n\t\t\t\tdrawOnChartArea: true,\n\t\t\t\tdrawTicks: true,\n\t\t\t\ttickMarkLength: 10,\n\t\t\t\tlineWidth: 1,\n\t\t\t\toffsetGridLines: false,\n\t\t\t\tdisplay: true,\n\t\t\t\tzeroLineColor: 'rgba(0,0,0,0.25)',\n\t\t\t\tzeroLineWidth: 1,\n\t\t\t\tzeroLineBorderDash: [],\n\t\t\t\tzeroLineBorderDashOffset: 0.0,\n\t\t\t\tborderDash: [],\n\t\t\t\tborderDashOffset: 0.0\n\t\t\t},\n\t\t\tpointLabels: {\n\t\t\t\tdisplay: true,\n\t\t\t\tfontSize: 10,\n\t\t\t\tcallback: defaultConfig.pointLabels.callback, // make this nicer, then check explicitly below\n\t\t\t},\n\t\t\tposition: 'chartArea',\n\t\t\tscaleLabel: {\n\t\t\t\tlabelString: '',\n\t\t\t\tdisplay: false,\n\t\t\t},\n\t\t\tticks: {\n\t\t\t\tbackdropColor: 'rgba(255,255,255,0.75)',\n\t\t\t\tbackdropPaddingY: 2,\n\t\t\t\tbackdropPaddingX: 2,\n\t\t\t\tbeginAtZero: false,\n\t\t\t\tminRotation: 0,\n\t\t\t\tmaxRotation: 50,\n\t\t\t\tmirror: false,\n\t\t\t\tpadding: 0,\n\t\t\t\treverse: false,\n\t\t\t\tshowLabelBackdrop: true,\n\t\t\t\tdisplay: true,\n\t\t\t\tcallback: defaultConfig.ticks.callback, // make this nicer, then check explicitly below\n\t\t\t\tautoSkip: true,\n\t\t\t\tautoSkipPadding: 0,\n\t\t\t\tlabelOffset: 0\n\t\t\t},\n\t\t});\n\n\t\t// Is this actually a function\n\t\texpect(defaultConfig.ticks.callback).toEqual(jasmine.any(Function));\n\t\texpect(defaultConfig.pointLabels.callback).toEqual(jasmine.any(Function));\n\t});\n\n\tit('Should correctly determine the max & min data values', function() {\n\t\tvar chart = window.acquireChart({\n\t\t\ttype: 'radar',\n\t\t\tdata: {\n\t\t\t\tdatasets: [{\n\t\t\t\t\tdata: [10, 5, 0, -5, 78, -100]\n\t\t\t\t}, {\n\t\t\t\t\tdata: [150]\n\t\t\t\t}],\n\t\t\t\tlabels: ['label1', 'label2', 'label3', 'label4', 'label5', 'label6']\n\t\t\t},\n\t\t\toptions: {\n\t\t\t\tscales: {}\n\t\t\t}\n\t\t});\n\n\t\texpect(chart.scale.min).toBe(-100);\n\t\texpect(chart.scale.max).toBe(150);\n\t});\n\n\tit('Should correctly determine the max & min of string data values', function() {\n\t\tvar chart = window.acquireChart({\n\t\t\ttype: 'radar',\n\t\t\tdata: {\n\t\t\t\tdatasets: [{\n\t\t\t\t\tdata: ['10', '5', '0', '-5', '78', '-100']\n\t\t\t\t}, {\n\t\t\t\t\tdata: ['150']\n\t\t\t\t}],\n\t\t\t\tlabels: ['label1', 'label2', 'label3', 'label4', 'label5', 'label6']\n\t\t\t},\n\t\t\toptions: {\n\t\t\t\tscales: {}\n\t\t\t}\n\t\t});\n\n\t\texpect(chart.scale.min).toBe(-100);\n\t\texpect(chart.scale.max).toBe(150);\n\t});\n\n\tit('Should correctly determine the max & min data values when there are hidden datasets', function() {\n\t\tvar chart = window.acquireChart({\n\t\t\ttype: 'radar',\n\t\t\tdata: {\n\t\t\t\tdatasets: [{\n\t\t\t\t\tdata: ['10', '5', '0', '-5', '78', '-100']\n\t\t\t\t}, {\n\t\t\t\t\tdata: ['150']\n\t\t\t\t}, {\n\t\t\t\t\tdata: [1000],\n\t\t\t\t\thidden: true\n\t\t\t\t}],\n\t\t\t\tlabels: ['label1', 'label2', 'label3', 'label4', 'label5', 'label6']\n\t\t\t},\n\t\t\toptions: {\n\t\t\t\tscales: {}\n\t\t\t}\n\t\t});\n\n\t\texpect(chart.scale.min).toBe(-100);\n\t\texpect(chart.scale.max).toBe(150);\n\t});\n\n\tit('Should correctly determine the max & min data values when there is NaN data', function() {\n\t\tvar chart = window.acquireChart({\n\t\t\ttype: 'radar',\n\t\t\tdata: {\n\t\t\t\tdatasets: [{\n\t\t\t\t\tdata: [50, 60, NaN, 70, null, undefined, Infinity, -Infinity]\n\t\t\t\t}],\n\t\t\t\tlabels: ['label1', 'label2', 'label3', 'label4', 'label5', 'label6', 'label7', 'label8']\n\t\t\t},\n\t\t\toptions: {\n\t\t\t\tscales: {}\n\t\t\t}\n\t\t});\n\n\t\texpect(chart.scale.min).toBe(50);\n\t\texpect(chart.scale.max).toBe(70);\n\t});\n\n\tit('Should ensure that the scale has a max and min that are not equal', function() {\n\t\tvar scaleID = 'myScale';\n\n\t\tvar mockData = {\n\t\t\tdatasets: [],\n\t\t\tlabels: []\n\t\t};\n\n\t\tvar mockContext = window.createMockContext();\n\t\tvar Constructor = Chart.scaleService.getScaleConstructor('radialLinear');\n\t\tvar scale = new Constructor({\n\t\t\tctx: mockContext,\n\t\t\toptions: Chart.scaleService.getScaleDefaults('radialLinear'), // use default config for scale\n\t\t\tchart: {\n\t\t\t\tdata: mockData\n\t\t\t},\n\t\t\tid: scaleID,\n\t\t});\n\n\t\tscale.update(200, 300);\n\t\texpect(scale.min).toBe(-1);\n\t\texpect(scale.max).toBe(1);\n\t});\n\n\tit('Should use the suggestedMin and suggestedMax options', function() {\n\t\tvar chart = window.acquireChart({\n\t\t\ttype: 'radar',\n\t\t\tdata: {\n\t\t\t\tdatasets: [{\n\t\t\t\t\tdata: [1, 1, 1, 2, 1, 0]\n\t\t\t\t}],\n\t\t\t\tlabels: ['label1', 'label2', 'label3', 'label4', 'label5', 'label6']\n\t\t\t},\n\t\t\toptions: {\n\t\t\t\tscale: {\n\t\t\t\t\tticks: {\n\t\t\t\t\t\tsuggestedMin: -10,\n\t\t\t\t\t\tsuggestedMax: 10\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\n\t\texpect(chart.scale.min).toBe(-10);\n\t\texpect(chart.scale.max).toBe(10);\n\t});\n\n\tit('Should use the min and max options', function() {\n\t\tvar chart = window.acquireChart({\n\t\t\ttype: 'radar',\n\t\t\tdata: {\n\t\t\t\tdatasets: [{\n\t\t\t\t\tdata: [1, 1, 1, 2, 1, 0]\n\t\t\t\t}],\n\t\t\t\tlabels: ['label1', 'label2', 'label3', 'label4', 'label5', 'label6']\n\t\t\t},\n\t\t\toptions: {\n\t\t\t\tscale: {\n\t\t\t\t\tticks: {\n\t\t\t\t\t\tmin: -1010,\n\t\t\t\t\t\tmax: 1010\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\n\t\texpect(chart.scale.min).toBe(-1010);\n\t\texpect(chart.scale.max).toBe(1010);\n\t\texpect(chart.scale.ticks).toEqual(['-1010', '-1000', '-500', '0', '500', '1000', '1010']);\n\t});\n\n\tit('should forcibly include 0 in the range if the beginAtZero option is used', function() {\n\t\tvar chart = window.acquireChart({\n\t\t\ttype: 'radar',\n\t\t\tdata: {\n\t\t\t\tdatasets: [{\n\t\t\t\t\tdata: [20, 30, 40, 50]\n\t\t\t\t}],\n\t\t\t\tlabels: ['label1', 'label2', 'label3', 'label4']\n\t\t\t},\n\t\t\toptions: {\n\t\t\t\tscale: {\n\t\t\t\t\tticks: {\n\t\t\t\t\t\tbeginAtZero: false\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\n\t\texpect(chart.scale.ticks).toEqual(['20', '25', '30', '35', '40', '45', '50']);\n\n\t\tchart.scale.options.ticks.beginAtZero = true;\n\t\tchart.update();\n\n\t\texpect(chart.scale.ticks).toEqual(['0', '5', '10', '15', '20', '25', '30', '35', '40', '45', '50']);\n\n\t\tchart.data.datasets[0].data = [-20, -30, -40, -50];\n\t\tchart.update();\n\n\t\texpect(chart.scale.ticks).toEqual(['-50', '-45', '-40', '-35', '-30', '-25', '-20', '-15', '-10', '-5', '0']);\n\n\t\tchart.scale.options.ticks.beginAtZero = false;\n\t\tchart.update();\n\n\t\texpect(chart.scale.ticks).toEqual(['-50', '-45', '-40', '-35', '-30', '-25', '-20']);\n\t});\n\n\tit('Should generate tick marks in the correct order in reversed mode', function() {\n\t\tvar chart = window.acquireChart({\n\t\t\ttype: 'radar',\n\t\t\tdata: {\n\t\t\t\tdatasets: [{\n\t\t\t\t\tdata: [10, 5, 0, 25, 78]\n\t\t\t\t}],\n\t\t\t\tlabels: ['label1', 'label2', 'label3', 'label4', 'label5']\n\t\t\t},\n\t\t\toptions: {\n\t\t\t\tscale: {\n\t\t\t\t\tticks: {\n\t\t\t\t\t\treverse: true\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\n\t\texpect(chart.scale.ticks).toEqual(['80', '70', '60', '50', '40', '30', '20', '10', '0']);\n\t\texpect(chart.scale.start).toBe(80);\n\t\texpect(chart.scale.end).toBe(0);\n\t});\n\n\tit('Should build labels using the user supplied callback', function() {\n\t\tvar chart = window.acquireChart({\n\t\t\ttype: 'radar',\n\t\t\tdata: {\n\t\t\t\tdatasets: [{\n\t\t\t\t\tdata: [10, 5, 0, 25, 78]\n\t\t\t\t}],\n\t\t\t\tlabels: ['label1', 'label2', 'label3', 'label4', 'label5']\n\t\t\t},\n\t\t\toptions: {\n\t\t\t\tscale: {\n\t\t\t\t\tticks: {\n\t\t\t\t\t\tcallback: function(value, index) {\n\t\t\t\t\t\t\treturn index.toString();\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\n\t\texpect(chart.scale.ticks).toEqual(['0', '1', '2', '3', '4', '5', '6', '7', '8']);\n\t\texpect(chart.scale.pointLabels).toEqual(['label1', 'label2', 'label3', 'label4', 'label5']);\n\t});\n\n\tit('Should build point labels using the user supplied callback', function() {\n\t\tvar chart = window.acquireChart({\n\t\t\ttype: 'radar',\n\t\t\tdata: {\n\t\t\t\tdatasets: [{\n\t\t\t\t\tdata: [10, 5, 0, 25, 78]\n\t\t\t\t}],\n\t\t\t\tlabels: ['label1', 'label2', 'label3', 'label4', 'label5']\n\t\t\t},\n\t\t\toptions: {\n\t\t\t\tscale: {\n\t\t\t\t\tpointLabels: {\n\t\t\t\t\t\tcallback: function(value, index) {\n\t\t\t\t\t\t\treturn index.toString();\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\n\t\texpect(chart.scale.pointLabels).toEqual(['0', '1', '2', '3', '4']);\n\t});\n\n\tit('should correctly set the center point', function() {\n\t\tvar chart = window.acquireChart({\n\t\t\ttype: 'radar',\n\t\t\tdata: {\n\t\t\t\tdatasets: [{\n\t\t\t\t\tdata: [10, 5, 0, 25, 78]\n\t\t\t\t}],\n\t\t\t\tlabels: ['label1', 'label2', 'label3', 'label4', 'label5']\n\t\t\t},\n\t\t\toptions: {\n\t\t\t\tscale: {\n\t\t\t\t\tpointLabels: {\n\t\t\t\t\t\tcallback: function(value, index) {\n\t\t\t\t\t\t\treturn index.toString();\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\n\t\texpect(chart.scale.drawingArea).toBe(233);\n\t\texpect(chart.scale.xCenter).toBe(256);\n\t\texpect(chart.scale.yCenter).toBe(280);\n\t});\n\n\tit('should correctly get the label for a given data index', function() {\n\t\tvar chart = window.acquireChart({\n\t\t\ttype: 'radar',\n\t\t\tdata: {\n\t\t\t\tdatasets: [{\n\t\t\t\t\tdata: [10, 5, 0, 25, 78]\n\t\t\t\t}],\n\t\t\t\tlabels: ['label1', 'label2', 'label3', 'label4', 'label5']\n\t\t\t},\n\t\t\toptions: {\n\t\t\t\tscale: {\n\t\t\t\t\tpointLabels: {\n\t\t\t\t\t\tcallback: function(value, index) {\n\t\t\t\t\t\t\treturn index.toString();\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\t\texpect(chart.scale.getLabelForIndex(1, 0)).toBe(5);\n\t});\n\n\tit('should get the correct distance from the center point', function() {\n\t\tvar chart = window.acquireChart({\n\t\t\ttype: 'radar',\n\t\t\tdata: {\n\t\t\t\tdatasets: [{\n\t\t\t\t\tdata: [10, 5, 0, 25, 78]\n\t\t\t\t}],\n\t\t\t\tlabels: ['label1', 'label2', 'label3', 'label4', 'label5']\n\t\t\t},\n\t\t\toptions: {\n\t\t\t\tscale: {\n\t\t\t\t\tpointLabels: {\n\t\t\t\t\t\tcallback: function(value, index) {\n\t\t\t\t\t\t\treturn index.toString();\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\n\t\texpect(chart.scale.getDistanceFromCenterForValue(chart.scale.min)).toBe(0);\n\t\texpect(chart.scale.getDistanceFromCenterForValue(chart.scale.max)).toBe(233);\n\t\texpect(chart.scale.getPointPositionForValue(1, 5)).toEqual({\n\t\t\tx: 270,\n\t\t\ty: 275,\n\t\t});\n\n\t\tchart.scale.options.reverse = true;\n\t\tchart.update();\n\n\t\texpect(chart.scale.getDistanceFromCenterForValue(chart.scale.min)).toBe(233);\n\t\texpect(chart.scale.getDistanceFromCenterForValue(chart.scale.max)).toBe(0);\n\t});\n\n\tit('should correctly get angles for all points', function() {\n\t\tvar chart = window.acquireChart({\n\t\t\ttype: 'radar',\n\t\t\tdata: {\n\t\t\t\tdatasets: [{\n\t\t\t\t\tdata: [10, 5, 0, 25, 78]\n\t\t\t\t}],\n\t\t\t\tlabels: ['label1', 'label2', 'label3', 'label4', 'label5']\n\t\t\t},\n\t\t\toptions: {\n\t\t\t\tscale: {\n\t\t\t\t\tpointLabels: {\n\t\t\t\t\t\tcallback: function(value, index) {\n\t\t\t\t\t\t\treturn index.toString();\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t\tstartAngle: 15\n\t\t\t}\n\t\t});\n\n\t\tvar radToNearestDegree = function(rad) {\n\t\t\treturn Math.round((360 * rad) / (2 * Math.PI));\n\t\t};\n\n\t\tvar slice = 72; // (360 / 5)\n\n\t\tfor (var i = 0; i < 5; i++) {\n\t\t\texpect(radToNearestDegree(chart.scale.getIndexAngle(i))).toBe(15 + (slice * i));\n\t\t}\n\n\t\tchart.options.startAngle = 0;\n\t\tchart.update();\n\n\t\tfor (var x = 0; x < 5; x++) {\n\t\t\texpect(radToNearestDegree(chart.scale.getIndexAngle(x))).toBe((slice * x));\n\t\t}\n\t});\n});\n"
  },
  {
    "path": "app_backend/static/plugin/Chart.js-2.6.0/test/specs/scale.time.tests.js",
    "content": "// Time scale tests\ndescribe('Time scale tests', function() {\n\tfunction createScale(data, options) {\n\t\tvar scaleID = 'myScale';\n\t\tvar mockContext = window.createMockContext();\n\t\tvar Constructor = Chart.scaleService.getScaleConstructor('time');\n\t\tvar scale = new Constructor({\n\t\t\tctx: mockContext,\n\t\t\toptions: options,\n\t\t\tchart: {\n\t\t\t\tdata: data\n\t\t\t},\n\t\t\tid: scaleID\n\t\t});\n\n\t\tscale.update(400, 50);\n\t\treturn scale;\n\t}\n\n\tbeforeEach(function() {\n\t\t// Need a time matcher for getValueFromPixel\n\t\tjasmine.addMatchers({\n\t\t\ttoBeCloseToTime: function() {\n\t\t\t\treturn {\n\t\t\t\t\tcompare: function(actual, expected) {\n\t\t\t\t\t\tvar result = false;\n\n\t\t\t\t\t\tvar diff = actual.diff(expected.value, expected.unit, true);\n\t\t\t\t\t\tresult = Math.abs(diff) < (expected.threshold !== undefined ? expected.threshold : 0.01);\n\n\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\tpass: result\n\t\t\t\t\t\t};\n\t\t\t\t\t}\n\t\t\t\t};\n\t\t\t}\n\t\t});\n\t});\n\n\tit('Should load moment.js as a dependency', function() {\n\t\texpect(window.moment).not.toBe(undefined);\n\t});\n\n\tit('Should register the constructor with the scale service', function() {\n\t\tvar Constructor = Chart.scaleService.getScaleConstructor('time');\n\t\texpect(Constructor).not.toBe(undefined);\n\t\texpect(typeof Constructor).toBe('function');\n\t});\n\n\tit('Should have the correct default config', function() {\n\t\tvar defaultConfig = Chart.scaleService.getScaleDefaults('time');\n\t\texpect(defaultConfig).toEqual({\n\t\t\tdisplay: true,\n\t\t\tgridLines: {\n\t\t\t\tcolor: 'rgba(0, 0, 0, 0.1)',\n\t\t\t\tdrawBorder: true,\n\t\t\t\tdrawOnChartArea: true,\n\t\t\t\tdrawTicks: true,\n\t\t\t\ttickMarkLength: 10,\n\t\t\t\tlineWidth: 1,\n\t\t\t\toffsetGridLines: false,\n\t\t\t\tdisplay: true,\n\t\t\t\tzeroLineColor: 'rgba(0,0,0,0.25)',\n\t\t\t\tzeroLineWidth: 1,\n\t\t\t\tzeroLineBorderDash: [],\n\t\t\t\tzeroLineBorderDashOffset: 0.0,\n\t\t\t\tborderDash: [],\n\t\t\t\tborderDashOffset: 0.0\n\t\t\t},\n\t\t\tposition: 'bottom',\n\t\t\tscaleLabel: {\n\t\t\t\tlabelString: '',\n\t\t\t\tdisplay: false\n\t\t\t},\n\t\t\tticks: {\n\t\t\t\tbeginAtZero: false,\n\t\t\t\tminRotation: 0,\n\t\t\t\tmaxRotation: 50,\n\t\t\t\tmirror: false,\n\t\t\t\tpadding: 0,\n\t\t\t\treverse: false,\n\t\t\t\tdisplay: true,\n\t\t\t\tcallback: defaultConfig.ticks.callback, // make this nicer, then check explicitly below,\n\t\t\t\tautoSkip: false,\n\t\t\t\tautoSkipPadding: 0,\n\t\t\t\tlabelOffset: 0\n\t\t\t},\n\t\t\ttime: {\n\t\t\t\tparser: false,\n\t\t\t\tformat: false,\n\t\t\t\tunit: false,\n\t\t\t\tround: false,\n\t\t\t\tisoWeekday: false,\n\t\t\t\tdisplayFormat: false,\n\t\t\t\tminUnit: 'millisecond',\n\t\t\t\tdisplayFormats: {\n\t\t\t\t\tmillisecond: 'h:mm:ss.SSS a', // 11:20:01.123 AM\n\t\t\t\t\tsecond: 'h:mm:ss a', // 11:20:01 AM\n\t\t\t\t\tminute: 'h:mm:ss a', // 11:20:01 AM\n\t\t\t\t\thour: 'MMM D, hA', // Sept 4, 5PM\n\t\t\t\t\tday: 'll', // Sep 4 2015\n\t\t\t\t\tweek: 'll', // Week 46, or maybe \"[W]WW - YYYY\" ?\n\t\t\t\t\tmonth: 'MMM YYYY', // Sept 2015\n\t\t\t\t\tquarter: '[Q]Q - YYYY', // Q3\n\t\t\t\t\tyear: 'YYYY' // 2015\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\n\t\t// Is this actually a function\n\t\texpect(defaultConfig.ticks.callback).toEqual(jasmine.any(Function));\n\t});\n\n\tdescribe('when given inputs of different types', function() {\n\t\t// Helper to build date objects\n\t\tfunction newDateFromRef(days) {\n\t\t\treturn moment('01/01/2015 12:00', 'DD/MM/YYYY HH:mm').add(days, 'd').toDate();\n\t\t}\n\n\t\tit('should accept labels as strings', function() {\n\t\t\tvar mockData = {\n\t\t\t\tlabels: ['2015-01-01T12:00:00', '2015-01-02T21:00:00', '2015-01-03T22:00:00', '2015-01-05T23:00:00', '2015-01-07T03:00', '2015-01-08T10:00', '2015-01-10T12:00'], // days\n\t\t\t};\n\n\t\t\tvar scale = createScale(mockData, Chart.scaleService.getScaleDefaults('time'));\n\t\t\tscale.update(1000, 200);\n\t\t\texpect(scale.ticks).toEqual(['Jan 1, 2015', 'Jan 2, 2015', 'Jan 3, 2015', 'Jan 4, 2015', 'Jan 5, 2015', 'Jan 6, 2015', 'Jan 7, 2015', 'Jan 8, 2015', 'Jan 9, 2015', 'Jan 10, 2015', 'Jan 11, 2015']);\n\t\t});\n\n\t\tit('should accept labels as date objects', function() {\n\t\t\tvar mockData = {\n\t\t\t\tlabels: [newDateFromRef(0), newDateFromRef(1), newDateFromRef(2), newDateFromRef(4), newDateFromRef(6), newDateFromRef(7), newDateFromRef(9)], // days\n\t\t\t};\n\t\t\tvar scale = createScale(mockData, Chart.scaleService.getScaleDefaults('time'));\n\t\t\tscale.update(1000, 200);\n\t\t\texpect(scale.ticks).toEqual(['Jan 1, 2015', 'Jan 2, 2015', 'Jan 3, 2015', 'Jan 4, 2015', 'Jan 5, 2015', 'Jan 6, 2015', 'Jan 7, 2015', 'Jan 8, 2015', 'Jan 9, 2015', 'Jan 10, 2015', 'Jan 11, 2015']);\n\t\t});\n\n\t\tit('should accept data as xy points', function() {\n\t\t\tvar chart = window.acquireChart({\n\t\t\t\ttype: 'line',\n\t\t\t\tdata: {\n\t\t\t\t\tdatasets: [{\n\t\t\t\t\t\txAxisID: 'xScale0',\n\t\t\t\t\t\tdata: [{\n\t\t\t\t\t\t\tx: newDateFromRef(0),\n\t\t\t\t\t\t\ty: 1\n\t\t\t\t\t\t}, {\n\t\t\t\t\t\t\tx: newDateFromRef(1),\n\t\t\t\t\t\t\ty: 10\n\t\t\t\t\t\t}, {\n\t\t\t\t\t\t\tx: newDateFromRef(2),\n\t\t\t\t\t\t\ty: 0\n\t\t\t\t\t\t}, {\n\t\t\t\t\t\t\tx: newDateFromRef(4),\n\t\t\t\t\t\t\ty: 5\n\t\t\t\t\t\t}, {\n\t\t\t\t\t\t\tx: newDateFromRef(6),\n\t\t\t\t\t\t\ty: 77\n\t\t\t\t\t\t}, {\n\t\t\t\t\t\t\tx: newDateFromRef(7),\n\t\t\t\t\t\t\ty: 9\n\t\t\t\t\t\t}, {\n\t\t\t\t\t\t\tx: newDateFromRef(9),\n\t\t\t\t\t\t\ty: 5\n\t\t\t\t\t\t}]\n\t\t\t\t\t}],\n\t\t\t\t},\n\t\t\t\toptions: {\n\t\t\t\t\tscales: {\n\t\t\t\t\t\txAxes: [{\n\t\t\t\t\t\t\tid: 'xScale0',\n\t\t\t\t\t\t\ttype: 'time',\n\t\t\t\t\t\t\tposition: 'bottom'\n\t\t\t\t\t\t}],\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t});\n\n\t\t\tvar xScale = chart.scales.xScale0;\n\t\t\txScale.update(800, 200);\n\t\t\texpect(xScale.ticks).toEqual(['Jan 1, 2015', 'Jan 2, 2015', 'Jan 3, 2015', 'Jan 4, 2015', 'Jan 5, 2015', 'Jan 6, 2015', 'Jan 7, 2015', 'Jan 8, 2015', 'Jan 9, 2015', 'Jan 10, 2015', 'Jan 11, 2015']);\n\t\t});\n\t});\n\n\tit('should allow custom time parsers', function() {\n\t\tvar chart = window.acquireChart({\n\t\t\ttype: 'line',\n\t\t\tdata: {\n\t\t\t\tdatasets: [{\n\t\t\t\t\txAxisID: 'xScale0',\n\t\t\t\t\tdata: [{\n\t\t\t\t\t\tx: 375068900,\n\t\t\t\t\t\ty: 1\n\t\t\t\t\t}]\n\t\t\t\t}],\n\t\t\t},\n\t\t\toptions: {\n\t\t\t\tscales: {\n\t\t\t\t\txAxes: [{\n\t\t\t\t\t\tid: 'xScale0',\n\t\t\t\t\t\ttype: 'time',\n\t\t\t\t\t\tposition: 'bottom',\n\t\t\t\t\t\ttime: {\n\t\t\t\t\t\t\tunit: 'day',\n\t\t\t\t\t\t\tround: true,\n\t\t\t\t\t\t\tparser: function(label) {\n\t\t\t\t\t\t\t\treturn moment.unix(label);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}],\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\n\t\t// Counts down because the lines are drawn top to bottom\n\t\tvar xScale = chart.scales.xScale0;\n\n\t\t// Counts down because the lines are drawn top to bottom\n\t\texpect(xScale.ticks[0]).toEqualOneOf(['Nov 19, 1981', 'Nov 20, 1981', 'Nov 21, 1981']); // handle time zone changes\n\t\texpect(xScale.ticks[1]).toEqualOneOf(['Nov 19, 1981', 'Nov 20, 1981', 'Nov 21, 1981']); // handle time zone changes\n\t});\n\n\tit('should build ticks using the config unit', function() {\n\t\tvar mockData = {\n\t\t\tlabels: ['2015-01-01T20:00:00', '2015-01-02T21:00:00'], // days\n\t\t};\n\n\t\tvar config = Chart.helpers.clone(Chart.scaleService.getScaleDefaults('time'));\n\t\tconfig.time.unit = 'hour';\n\n\t\tvar scale = createScale(mockData, config);\n\t\tscale.update(2500, 200);\n\t\texpect(scale.ticks).toEqual(['Jan 1, 8PM', 'Jan 1, 9PM', 'Jan 1, 10PM', 'Jan 1, 11PM', 'Jan 2, 12AM', 'Jan 2, 1AM', 'Jan 2, 2AM', 'Jan 2, 3AM', 'Jan 2, 4AM', 'Jan 2, 5AM', 'Jan 2, 6AM', 'Jan 2, 7AM', 'Jan 2, 8AM', 'Jan 2, 9AM', 'Jan 2, 10AM', 'Jan 2, 11AM', 'Jan 2, 12PM', 'Jan 2, 1PM', 'Jan 2, 2PM', 'Jan 2, 3PM', 'Jan 2, 4PM', 'Jan 2, 5PM', 'Jan 2, 6PM', 'Jan 2, 7PM', 'Jan 2, 8PM', 'Jan 2, 9PM']);\n\t});\n\n\tit('build ticks honoring the minUnit', function() {\n\t\tvar mockData = {\n\t\t\tlabels: ['2015-01-01T20:00:00', '2015-01-02T21:00:00'], // days\n\t\t};\n\n\t\tvar config = Chart.helpers.clone(Chart.scaleService.getScaleDefaults('time'));\n\t\tconfig.time.minUnit = 'day';\n\n\t\tvar scale = createScale(mockData, config);\n\t\texpect(scale.ticks).toEqual(['Jan 1, 2015', 'Jan 2, 2015', 'Jan 3, 2015']);\n\t});\n\n\tit('should build ticks using the config diff', function() {\n\t\tvar mockData = {\n\t\t\tlabels: ['2015-01-01T20:00:00', '2015-02-02T21:00:00', '2015-02-21T01:00:00'], // days\n\t\t};\n\n\t\tvar config = Chart.helpers.clone(Chart.scaleService.getScaleDefaults('time'));\n\t\tconfig.time.unit = 'week';\n\t\tconfig.time.round = 'week';\n\n\t\tvar scale = createScale(mockData, config);\n\t\tscale.update(800, 200);\n\n\t\t// last date is feb 15 because we round to start of week\n\t\texpect(scale.ticks).toEqual(['Dec 28, 2014', 'Jan 4, 2015', 'Jan 11, 2015', 'Jan 18, 2015', 'Jan 25, 2015', 'Feb 1, 2015', 'Feb 8, 2015', 'Feb 15, 2015']);\n\t});\n\n\tdescribe('when specifying limits', function() {\n\t\tvar mockData = {\n\t\t\tlabels: ['2015-01-01T20:00:00', '2015-01-02T20:00:00', '2015-01-03T20:00:00'],\n\t\t};\n\n\t\tvar config;\n\t\tbeforeEach(function() {\n\t\t\tconfig = Chart.helpers.clone(Chart.scaleService.getScaleDefaults('time'));\n\t\t});\n\n\t\tit('should use the min option', function() {\n\t\t\tconfig.time.unit = 'day';\n\t\t\tconfig.time.min = '2014-12-29T04:00:00';\n\n\t\t\tvar scale = createScale(mockData, config);\n\t\t\texpect(scale.ticks[0]).toEqual('Dec 29, 2014');\n\t\t});\n\n\t\tit('should use the max option', function() {\n\t\t\tconfig.time.unit = 'day';\n\t\t\tconfig.time.max = '2015-01-05T06:00:00';\n\n\t\t\tvar scale = createScale(mockData, config);\n\t\t\texpect(scale.ticks[scale.ticks.length - 1]).toEqual('Jan 5, 2015');\n\t\t});\n\t});\n\n\tit('Should use the isoWeekday option', function() {\n\t\tvar mockData = {\n\t\t\tlabels: [\n\t\t\t\t'2015-01-01T20:00:00', // Thursday\n\t\t\t\t'2015-01-02T20:00:00', // Friday\n\t\t\t\t'2015-01-03T20:00:00' // Saturday\n\t\t\t]\n\t\t};\n\n\t\tvar config = Chart.helpers.clone(Chart.scaleService.getScaleDefaults('time'));\n\t\tconfig.time.unit = 'week';\n\t\t// Wednesday\n\t\tconfig.time.isoWeekday = 3;\n\t\tvar scale = createScale(mockData, config);\n\t\texpect(scale.ticks).toEqual(['Dec 31, 2014', 'Jan 7, 2015']);\n\t});\n\n\tdescribe('when rendering several days', function() {\n\t\tvar chart = window.acquireChart({\n\t\t\ttype: 'line',\n\t\t\tdata: {\n\t\t\t\tdatasets: [{\n\t\t\t\t\txAxisID: 'xScale0',\n\t\t\t\t\tdata: []\n\t\t\t\t}],\n\t\t\t\tlabels: ['2015-01-01T20:00:00', '2015-01-02T21:00:00', '2015-01-03T22:00:00', '2015-01-05T23:00:00', '2015-01-07T03:00', '2015-01-08T10:00', '2015-01-10T12:00'], // days\n\t\t\t},\n\t\t\toptions: {\n\t\t\t\tscales: {\n\t\t\t\t\txAxes: [{\n\t\t\t\t\t\tid: 'xScale0',\n\t\t\t\t\t\ttype: 'time',\n\t\t\t\t\t\tposition: 'bottom'\n\t\t\t\t\t}],\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\n\t\tvar xScale = chart.scales.xScale0;\n\n\t\tit('should be bounded by the nearest day beginnings', function() {\n\t\t\texpect(xScale.getValueForPixel(xScale.left)).toBeCloseToTime({\n\t\t\t\tvalue: moment(chart.data.labels[0]).startOf('day'),\n\t\t\t\tunit: 'hour',\n\t\t\t});\n\t\t\texpect(xScale.getValueForPixel(xScale.right)).toBeCloseToTime({\n\t\t\t\tvalue: moment(chart.data.labels[chart.data.labels.length - 1]).endOf('day'),\n\t\t\t\tunit: 'hour',\n\t\t\t});\n\t\t});\n\n\t\tit('should convert between screen coordinates and times', function() {\n\t\t\tvar timeRange = moment('2015-01-11').valueOf() - moment('2015-01-01').valueOf();\n\t\t\tvar msInHour = 3600000;\n\t\t\tvar firstLabelAlong = 20 * msInHour / timeRange;\n\t\t\tvar firstLabelPixel = xScale.left + (xScale.width * firstLabelAlong);\n\t\t\tvar lastLabelAlong = (timeRange - (12 * msInHour)) / timeRange;\n\t\t\tvar lastLabelPixel = xScale.left + (xScale.width * lastLabelAlong);\n\n\t\t\texpect(xScale.getPixelForValue('', 0, 0)).toBeCloseToPixel(firstLabelPixel);\n\t\t\texpect(xScale.getPixelForValue(chart.data.labels[0])).toBeCloseToPixel(firstLabelPixel);\n\t\t\texpect(xScale.getValueForPixel(firstLabelPixel)).toBeCloseToTime({\n\t\t\t\tvalue: moment(chart.data.labels[0]),\n\t\t\t\tunit: 'hour',\n\t\t\t});\n\n\t\t\texpect(xScale.getPixelForValue('', 6, 0)).toBeCloseToPixel(lastLabelPixel);\n\t\t\texpect(xScale.getValueForPixel(lastLabelPixel)).toBeCloseToTime({\n\t\t\t\tvalue: moment(chart.data.labels[6]),\n\t\t\t\tunit: 'hour'\n\t\t\t});\n\t\t});\n\t});\n\n\tdescribe('when rendering several years', function() {\n\t\tvar chart = window.acquireChart({\n\t\t\ttype: 'line',\n\t\t\tdata: {\n\t\t\t\tlabels: ['2005-07-04', '2017-01-20'],\n\t\t\t},\n\t\t\toptions: {\n\t\t\t\tscales: {\n\t\t\t\t\txAxes: [{\n\t\t\t\t\t\tid: 'xScale0',\n\t\t\t\t\t\ttype: 'time',\n\t\t\t\t\t\tposition: 'bottom'\n\t\t\t\t\t}],\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\n\t\tvar xScale = chart.scales.xScale0;\n\t\txScale.update(800, 200);\n\n\t\tit('should be bounded by nearest year starts', function() {\n\t\t\texpect(xScale.getValueForPixel(xScale.left)).toBeCloseToTime({\n\t\t\t\tvalue: moment(chart.data.labels[0]).startOf('year'),\n\t\t\t\tunit: 'hour',\n\t\t\t});\n\t\t\texpect(xScale.getValueForPixel(xScale.right)).toBeCloseToTime({\n\t\t\t\tvalue: moment(chart.data.labels[chart.data.labels - 1]).endOf('year'),\n\t\t\t\tunit: 'hour',\n\t\t\t});\n\t\t});\n\n\t\tit('should build the correct ticks', function() {\n\t\t\t// Where 'correct' is a two year spacing, except the last tick which is the year end of the last point.\n\t\t\texpect(xScale.ticks).toEqual(['2005', '2007', '2009', '2011', '2013', '2015', '2017', '2018']);\n\t\t});\n\n\t\tit('should have ticks with accurate labels', function() {\n\t\t\tvar ticks = xScale.ticks;\n\t\t\tvar pixelsPerYear = xScale.width / 13;\n\n\t\t\tfor (var i = 0; i < ticks.length - 1; i++) {\n\t\t\t\tvar offset = 2 * pixelsPerYear * i;\n\t\t\t\texpect(xScale.getValueForPixel(xScale.left + offset)).toBeCloseToTime({\n\t\t\t\t\tvalue: moment(ticks[i] + '-01-01'),\n\t\t\t\t\tunit: 'day',\n\t\t\t\t\tthreshold: 0.5,\n\t\t\t\t});\n\t\t\t}\n\t\t});\n\t});\n\n\tit('should get the correct label for a data value', function() {\n\t\tvar chart = window.acquireChart({\n\t\t\ttype: 'line',\n\t\t\tdata: {\n\t\t\t\tdatasets: [{\n\t\t\t\t\txAxisID: 'xScale0',\n\t\t\t\t\tdata: [null, 10, 3]\n\t\t\t\t}],\n\t\t\t\tlabels: ['2015-01-01T20:00:00', '2015-01-02T21:00:00', '2015-01-03T22:00:00', '2015-01-05T23:00:00', '2015-01-07T03:00', '2015-01-08T10:00', '2015-01-10T12:00'], // days\n\t\t\t},\n\t\t\toptions: {\n\t\t\t\tscales: {\n\t\t\t\t\txAxes: [{\n\t\t\t\t\t\tid: 'xScale0',\n\t\t\t\t\t\ttype: 'time',\n\t\t\t\t\t\tposition: 'bottom'\n\t\t\t\t\t}],\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\n\t\tvar xScale = chart.scales.xScale0;\n\t\texpect(xScale.getLabelForIndex(0, 0)).toBeTruthy();\n\t\texpect(xScale.getLabelForIndex(0, 0)).toBe('2015-01-01T20:00:00');\n\t\texpect(xScale.getLabelForIndex(6, 0)).toBe('2015-01-10T12:00');\n\t});\n\n\tit('should get the correct pixel for only one data in the dataset', function() {\n\t\tvar chart = window.acquireChart({\n\t\t\ttype: 'line',\n\t\t\tdata: {\n\t\t\t\tlabels: ['2016-05-27'],\n\t\t\t\tdatasets: [{\n\t\t\t\t\txAxisID: 'xScale0',\n\t\t\t\t\tdata: [5]\n\t\t\t\t}]\n\t\t\t},\n\t\t\toptions: {\n\t\t\t\tscales: {\n\t\t\t\t\txAxes: [{\n\t\t\t\t\t\tid: 'xScale0',\n\t\t\t\t\t\tdisplay: true,\n\t\t\t\t\t\ttype: 'time'\n\t\t\t\t\t}]\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\n\t\tvar xScale = chart.scales.xScale0;\n\n\t\texpect(xScale.getPixelForValue('', 0, 0)).toBeCloseToPixel(62);\n\n\t\texpect(xScale.getValueForPixel(62)).toBeCloseToTime({\n\t\t\tvalue: moment(chart.data.labels[0]),\n\t\t\tunit: 'day',\n\t\t});\n\t});\n\n\tit('does not create a negative width chart when hidden', function() {\n\t\tvar chart = window.acquireChart({\n\t\t\ttype: 'line',\n\t\t\tdata: {\n\t\t\t\tdatasets: [{\n\t\t\t\t\tdata: []\n\t\t\t\t}]\n\t\t\t},\n\t\t\toptions: {\n\t\t\t\tscales: {\n\t\t\t\t\txAxes: [{\n\t\t\t\t\t\ttype: 'time',\n\t\t\t\t\t\ttime: {\n\t\t\t\t\t\t\tmin: moment().subtract(1, 'months'),\n\t\t\t\t\t\t\tmax: moment(),\n\t\t\t\t\t\t}\n\t\t\t\t\t}],\n\t\t\t\t},\n\t\t\t\tresponsive: true,\n\t\t\t},\n\t\t}, {\n\t\t\twrapper: {\n\t\t\t\tstyle: 'display: none',\n\t\t\t},\n\t\t});\n\t\texpect(chart.scales['y-axis-0'].width).toEqual(0);\n\t\texpect(chart.scales['y-axis-0'].maxWidth).toEqual(0);\n\t\texpect(chart.width).toEqual(0);\n\t});\n});\n"
  },
  {
    "path": "app_backend/static/plugin/Gallery-2.25.0/.gitignore",
    "content": ".DS_Store\nnode_modules\n"
  },
  {
    "path": "app_backend/static/plugin/Gallery-2.25.0/.npmignore",
    "content": "*\n!css/*.css\n!css/*.css.map\n!img/*.gif\n!img/*.png\n!img/*.svg\n!js/*.js\n!js/*.js.map\n"
  },
  {
    "path": "app_backend/static/plugin/Gallery-2.25.0/LICENSE.txt",
    "content": "Copyright (C) 2013, 2016 Sebastian Tschan, https://blueimp.net\n\nThe Swipe implementation is based on https://github.com/bradbirdsall/Swipe, \nlicensed also under the MIT license.\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n"
  },
  {
    "path": "app_backend/static/plugin/Gallery-2.25.0/README.md",
    "content": "# blueimp Gallery\n\n- [Demo](#demo)\n- [Description](#description)\n- [Setup](#setup)\n    - [Lightbox setup](#lightbox-setup)\n    - [Controls](#controls)\n    - [Carousel setup](#carousel-setup)\n- [Keyboard shortcuts](#keyboard-shortcuts)\n- [Options](#options)\n    - [Default options](#default-options)\n    - [Event callbacks](#event-callbacks)\n    - [Carousel options](#carousel-options)\n    - [Indicator options](#indicator-options)\n    - [Fullscreen options](#fullscreen-options)\n    - [Video options](#video-options)\n        - [Video factory options](#video-factory-options)\n        - [YouTube options](#youtube-options)\n        - [Vimeo options](#vimeo-options)\n    - [Container and element options](#container-and-element-options)\n    - [Property options](#property-options)\n- [API](#api)\n    - [Initialization](#initialization)\n    - [API methods](#api-methods)\n    - [Videos](#videos)\n        - [HTML5 video player](#html5-video-player)\n        - [Multiple video sources](#multiple-video-sources)\n        - [YouTube](#youtube)\n        - [Vimeo](#vimeo)\n    - [Additional Gallery elements](#additional-gallery-elements)\n    - [Additional content types](#additional-content-types)\n        - [Example HTML text factory implementation](#example-html-text-factory-implementation)\n    - [jQuery plugin](#jquery-plugin)\n        - [jQuery plugin setup](#jquery-plugin-setup)\n        - [HTML5 data-attributes](#html5-data-attributes)\n        - [Container ids and link grouping](#container-ids-and-link-grouping)\n        - [Gallery object](#gallery-object)\n        - [jQuery events](#jquery-events)\n- [Requirements](#requirements)\n- [Browsers](#browsers)\n    - [Desktop browsers](#desktop-browsers)\n    - [Mobile browsers](#mobile-browsers)\n- [License](#license)\n- [Credits](#credits)\n\n## Demo\n[blueimp Gallery Demo](https://blueimp.github.io/Gallery/)\n\n## Description\nblueimp Gallery is a touch-enabled, responsive and customizable image and video\ngallery, carousel and lightbox, optimized for both mobile and desktop web\nbrowsers.  \nIt features swipe, mouse and keyboard navigation, transition effects, slideshow\nfunctionality, fullscreen support and on-demand content loading and can be\nextended to display additional content types.\n\n## Setup\n\n### Lightbox setup\nCopy the **css**, **img** and **js** directories to your website.\n\nInclude the Gallery stylesheet in the head section of your webpage:\n\n```html\n<link rel=\"stylesheet\" href=\"css/blueimp-gallery.min.css\">\n```\n\nAdd the following HTML snippet with the Gallery widget to the body of your\nwebpage:\n\n```html\n<!-- The Gallery as lightbox dialog, should be a child element of the document body -->\n<div id=\"blueimp-gallery\" class=\"blueimp-gallery\">\n    <div class=\"slides\"></div>\n    <h3 class=\"title\"></h3>\n    <a class=\"prev\">‹</a>\n    <a class=\"next\">›</a>\n    <a class=\"close\">×</a>\n    <a class=\"play-pause\"></a>\n    <ol class=\"indicator\"></ol>\n</div>\n```\n\nInclude the Gallery script at the bottom of the body of your webpage:\n\n```html\n<script src=\"js/blueimp-gallery.min.js\"></script>\n```\n\nCreate a list of links to image files, optionally with enclosed thumbnails and\nadd them to the body of your webpage, before including the Gallery script:\n\n```html\n<div id=\"links\">\n    <a href=\"images/banana.jpg\" title=\"Banana\">\n        <img src=\"images/thumbnails/banana.jpg\" alt=\"Banana\">\n    </a>\n    <a href=\"images/apple.jpg\" title=\"Apple\">\n        <img src=\"images/thumbnails/apple.jpg\" alt=\"Apple\">\n    </a>\n    <a href=\"images/orange.jpg\" title=\"Orange\">\n        <img src=\"images/thumbnails/orange.jpg\" alt=\"Orange\">\n    </a>\n</div>\n```\n\nAdd the following JavaScript code after including the Gallery script, to display\nthe images in the Gallery lightbox on click of the links:\n\n```html\n<script>\ndocument.getElementById('links').onclick = function (event) {\n    event = event || window.event;\n    var target = event.target || event.srcElement,\n        link = target.src ? target.parentNode : target,\n        options = {index: link, event: event},\n        links = this.getElementsByTagName('a');\n    blueimp.Gallery(links, options);\n};\n</script>\n```\n\n### Controls\nTo initialize the Gallery with visible controls, add the CSS class\n**blueimp-gallery-controls** to the Gallery widget:\n\n```html\n<div id=\"blueimp-gallery\" class=\"blueimp-gallery blueimp-gallery-controls\">\n    <div class=\"slides\"></div>\n    <h3 class=\"title\"></h3>\n    <a class=\"prev\">‹</a>\n    <a class=\"next\">›</a>\n    <a class=\"close\">×</a>\n    <a class=\"play-pause\"></a>\n    <ol class=\"indicator\"></ol>\n</div>\n```\n\n### Carousel setup\nTo display the images in an inline carousel instead of a lightbox, follow the\n[lightbox setup](#lightbox-setup) and add the CSS class\n**blueimp-gallery-carousel** to the Gallery widget and remove the child element\nwith the **close** class, or add a new Gallery widget with a different **id**\nto your webpage:\n\n```html\n<!-- The Gallery as inline carousel, can be positioned anywhere on the page -->\n<div id=\"blueimp-gallery-carousel\" class=\"blueimp-gallery blueimp-gallery-carousel\">\n    <div class=\"slides\"></div>\n    <h3 class=\"title\"></h3>\n    <a class=\"prev\">‹</a>\n    <a class=\"next\">›</a>\n    <a class=\"play-pause\"></a>\n    <ol class=\"indicator\"></ol>\n</div>\n```\n\nAdd the following JavaScript code after including the Gallery script to\ninitialize the carousel:\n\n```html\n<script>\nblueimp.Gallery(\n    document.getElementById('links').getElementsByTagName('a'),\n    {\n        container: '#blueimp-gallery-carousel',\n        carousel: true\n    }\n);\n</script>\n```\n\n## Keyboard shortcuts\nThe Gallery can be controlled with the following keyboard shortcuts:\n\n* **Return**: Toggle controls visibility.\n* **Esc**: Close the Gallery lightbox.\n* **Space**: Toggle the slideshow (play/pause).\n* **Left**: Move to the previous slide.\n* **Right**: Move to the next slide.\n\nPlease note that setting the **carousel** option to **true** disables the\nkeyboard shortcuts by default.\n\n## Options\n\n### Default options\nThe following are the default options set by the core Gallery library:\n\n```js\nvar options = {\n    // The Id, element or querySelector of the gallery widget:\n    container: '#blueimp-gallery',\n    // The tag name, Id, element or querySelector of the slides container:\n    slidesContainer: 'div',\n    // The tag name, Id, element or querySelector of the title element:\n    titleElement: 'h3',\n    // The class to add when the gallery is visible:\n    displayClass: 'blueimp-gallery-display',\n    // The class to add when the gallery controls are visible:\n    controlsClass: 'blueimp-gallery-controls',\n    // The class to add when the gallery only displays one element:\n    singleClass: 'blueimp-gallery-single',\n    // The class to add when the left edge has been reached:\n    leftEdgeClass: 'blueimp-gallery-left',\n    // The class to add when the right edge has been reached:\n    rightEdgeClass: 'blueimp-gallery-right',\n    // The class to add when the automatic slideshow is active:\n    playingClass: 'blueimp-gallery-playing',\n    // The class for all slides:\n    slideClass: 'slide',\n    // The slide class for loading elements:\n    slideLoadingClass: 'slide-loading',\n    // The slide class for elements that failed to load:\n    slideErrorClass: 'slide-error',\n    // The class for the content element loaded into each slide:\n    slideContentClass: 'slide-content',\n    // The class for the \"toggle\" control:\n    toggleClass: 'toggle',\n    // The class for the \"prev\" control:\n    prevClass: 'prev',\n    // The class for the \"next\" control:\n    nextClass: 'next',\n    // The class for the \"close\" control:\n    closeClass: 'close',\n    // The class for the \"play-pause\" toggle control:\n    playPauseClass: 'play-pause',\n    // The list object property (or data attribute) with the object type:\n    typeProperty: 'type',\n    // The list object property (or data attribute) with the object title:\n    titleProperty: 'title',\n    // The list object property (or data attribute) with the object URL:\n    urlProperty: 'href',\n    // The list object property (or data attribute) with the object srcset URL(s):\n    srcsetProperty: 'urlset',\n    // The gallery listens for transitionend events before triggering the\n    // opened and closed events, unless the following option is set to false:\n    displayTransition: true,\n    // Defines if the gallery slides are cleared from the gallery modal,\n    // or reused for the next gallery initialization:\n    clearSlides: true,\n    // Defines if images should be stretched to fill the available space,\n    // while maintaining their aspect ratio (will only be enabled for browsers\n    // supporting background-size=\"contain\", which excludes IE < 9).\n    // Set to \"cover\", to make images cover all available space (requires\n    // support for background-size=\"cover\", which excludes IE < 9):\n    stretchImages: false,\n    // Toggle the controls on pressing the Return key:\n    toggleControlsOnReturn: true,\n    // Toggle the controls on slide click:\n    toggleControlsOnSlideClick: true,\n    // Toggle the automatic slideshow interval on pressing the Space key:\n    toggleSlideshowOnSpace: true,\n    // Navigate the gallery by pressing left and right on the keyboard:\n    enableKeyboardNavigation: true,\n    // Close the gallery on pressing the ESC key:\n    closeOnEscape: true,\n    // Close the gallery when clicking on an empty slide area:\n    closeOnSlideClick: true,\n    // Close the gallery by swiping up or down:\n    closeOnSwipeUpOrDown: true,\n    // Emulate touch events on mouse-pointer devices such as desktop browsers:\n    emulateTouchEvents: true,\n    // Stop touch events from bubbling up to ancestor elements of the Gallery:\n    stopTouchEventsPropagation: false,\n    // Hide the page scrollbars:\n    hidePageScrollbars: true,\n    // Stops any touches on the container from scrolling the page:\n    disableScroll: true,\n    // Carousel mode (shortcut for carousel specific options):\n    carousel: false,\n    // Allow continuous navigation, moving from last to first\n    // and from first to last slide:\n    continuous: true,\n    // Remove elements outside of the preload range from the DOM:\n    unloadElements: true,\n    // Start with the automatic slideshow:\n    startSlideshow: false,\n    // Delay in milliseconds between slides for the automatic slideshow:\n    slideshowInterval: 5000,\n    // The starting index as integer.\n    // Can also be an object of the given list,\n    // or an equal object with the same url property:\n    index: 0,\n    // The number of elements to load around the current index:\n    preloadRange: 2,\n    // The transition speed between slide changes in milliseconds:\n    transitionSpeed: 400,\n    // The transition speed for automatic slide changes, set to an integer\n    // greater 0 to override the default transition speed:\n    slideshowTransitionSpeed: undefined,\n    // The event object for which the default action will be canceled\n    // on Gallery initialization (e.g. the click event to open the Gallery):\n    event: undefined,\n    // Callback function executed when the Gallery is initialized.\n    // Is called with the gallery instance as \"this\" object:\n    onopen: undefined,\n    // Callback function executed when the Gallery has been initialized\n    // and the initialization transition has been completed.\n    // Is called with the gallery instance as \"this\" object:\n    onopened: undefined,\n    // Callback function executed on slide change.\n    // Is called with the gallery instance as \"this\" object and the\n    // current index and slide as arguments:\n    onslide: undefined,\n    // Callback function executed after the slide change transition.\n    // Is called with the gallery instance as \"this\" object and the\n    // current index and slide as arguments:\n    onslideend: undefined,\n    // Callback function executed on slide content load.\n    // Is called with the gallery instance as \"this\" object and the\n    // slide index and slide element as arguments:\n    onslidecomplete: undefined,\n    // Callback function executed when the Gallery is about to be closed.\n    // Is called with the gallery instance as \"this\" object:\n    onclose: undefined,\n    // Callback function executed when the Gallery has been closed\n    // and the closing transition has been completed.\n    // Is called with the gallery instance as \"this\" object:\n    onclosed: undefined\n};\n```\n\n### Event callbacks\nEvent callbacks can be set as function properties of the options object passed\nto the Gallery initialization function:\n\n```js\nvar gallery = blueimp.Gallery(\n    linkList,\n    {\n        onopen: function () {\n            // Callback function executed when the Gallery is initialized.\n        },\n        onopened: function () {\n            // Callback function executed when the Gallery has been initialized\n            // and the initialization transition has been completed.\n        },\n        onslide: function (index, slide) {\n            // Callback function executed on slide change.\n        },\n        onslideend: function (index, slide) {\n            // Callback function executed after the slide change transition.\n        },\n        onslidecomplete: function (index, slide) {\n            // Callback function executed on slide content load.\n        },\n        onclose: function () {\n            // Callback function executed when the Gallery is about to be closed.\n        },\n        onclosed: function () {\n            // Callback function executed when the Gallery has been closed\n            // and the closing transition has been completed.\n        }\n    }\n);\n```\n\n### Carousel options\nIf the **carousel** option is **true**, the following options are set to\ndifferent default values:\n\n```js\nvar carouselOptions = {\n    hidePageScrollbars: false,\n    toggleControlsOnReturn: false,\n    toggleSlideshowOnSpace: false,\n    enableKeyboardNavigation: false,\n    closeOnEscape: false,\n    closeOnSlideClick: false,\n    closeOnSwipeUpOrDown: false,\n    disableScroll: false,\n    startSlideshow: true\n};\n```\n\nThe options object passed to the Gallery function extends the default options\nand also those options set via **carousel** mode.\n\n### Indicator options\nThe following are the additional default options set for the slide position\nindicator:\n\n```js\nvar indicatorOptions = {\n    // The tag name, Id, element or querySelector of the indicator container:\n    indicatorContainer: 'ol',\n    // The class for the active indicator:\n    activeIndicatorClass: 'active',\n    // The list object property (or data attribute) with the thumbnail URL,\n    // used as alternative to a thumbnail child element:\n    thumbnailProperty: 'thumbnail',\n    // Defines if the gallery indicators should display a thumbnail:\n    thumbnailIndicators: true\n};\n```\n\n### Fullscreen options\nThe following are the additional default options set for the fullscreen mode:\n\n```js\nvar fullscreenOptions = {\n    // Defines if the gallery should open in fullscreen mode:\n    fullScreen: false\n};\n```\n\n### Video options\n\n#### Video factory options\nThe following are the additional default options set for the video factory:\n\n```js\nvar videoFactoryOptions = {\n    // The class for video content elements:\n    videoContentClass: 'video-content',\n    // The class for video when it is loading:\n    videoLoadingClass: 'video-loading',\n    // The class for video when it is playing:\n    videoPlayingClass: 'video-playing',\n    // The list object property (or data attribute) for the video poster URL:\n    videoPosterProperty: 'poster',\n    // The list object property (or data attribute) for the video sources array:\n    videoSourcesProperty: 'sources'\n};\n```\n#### YouTube options\nOptions for [YouTube](https://www.youtube.com/) videos:\n\n```js\nvar youTubeOptions = {\n    // The list object property (or data attribute) with the YouTube video id:\n    youTubeVideoIdProperty: 'youtube',\n    // Optional object with parameters passed to the YouTube video player:\n    // https://developers.google.com/youtube/player_parameters\n    youTubePlayerVars: undefined,\n    // Require a click on the native YouTube player for the initial playback:\n    youTubeClickToPlay: true\n};\n```\n\n#### Vimeo options\nOptions for [Vimeo](https://vimeo.com/) videos:\n\n```js\nvar vimeoOptions = {\n    // The list object property (or data attribute) with the Vimeo video id:\n    vimeoVideoIdProperty: 'vimeo',\n    // The URL for the Vimeo video player, can be extended with custom parameters:\n    // https://developer.vimeo.com/player/embedding\n    vimeoPlayerUrl: '//player.vimeo.com/video/VIDEO_ID?api=1&player_id=PLAYER_ID',\n    // The prefix for the Vimeo video player ID:\n    vimeoPlayerIdPrefix: 'vimeo-player-',\n    // Require a click on the native Vimeo player for the initial playback:\n    vimeoClickToPlay: true\n};\n```\n\n### Container and element options\nThe widget **container** option can be set as id string (with \"#\" as prefix) or\nelement node, so the following are equivalent:\n\n```js\nvar options = {\n    container: '#blueimp-gallery'\n};\n```\n\n```js\nvar options = {\n    container: document.getElementById('blueimp-gallery')\n};\n```\n\nThe **slidesContainer**, **titleElement** and **indicatorContainer** options can\nalso be defined using a tag name, which selects the first tag of this kind found\ninside of the widget container:\n\n```js\nvar options = {\n    slidesContainer: 'div',\n    titleElement: 'h3',\n    indicatorContainer: 'ol'\n};\n```\n\nIt is also possible to define the container and element options with a more\ncomplex\n[querySelector](https://developer.mozilla.org/en-US/docs/Web/API/document.querySelector),\nwhich is supported by IE8+ and all modern web browsers.\n\nIf the helper script is replaced with [jQuery](https://jquery.com/),\nthe container and element options can be any valid jQuery selector.\n\n### Property options\nThe options ending with \"Property\" define how the properties of each link\nelement are accessed.  \nFor example, the **urlProperty** is by default set to **href**. This allows to\ndefine link elements with **href** or **data-href** attributes:\n\n```html\n<div id=\"links\">\n    <a href=\"images/banana.jpg\">Banana</a>\n    <a data-href=\"images/apple.jpg\">Apple</a>\n</div>\n```\n\nIf the links are passed as JavaScript array, it is also possible to define\nnested property names, by using the native JavaScript accessor syntax for the\nproperty string:\n\n```js\nblueimp.Gallery(\n    [\n        {\n            data: {urls: ['https://example.org/images/banana.jpg']}\n        },\n        {\n            data: {urls: ['https://example.org/images/apple.jpg']}\n        }\n    ],\n    {\n        urlProperty: 'data.urls[0]'\n    }\n);\n```\n\n## API\n\n### Initialization\nThe blueimp Gallery can be initialized by simply calling it as a function with\nan array of links as first argument and an optional options object as second\nargument:\n\n```js\nvar gallery = blueimp.Gallery(links, options);\n```\n\nThe links array can be a list of URL strings or a list of objects with URL\nproperties:\n\n```js\nvar gallery = blueimp.Gallery([\n    'https://example.org/images/banana.jpg',\n    'https://example.org/images/apple.jpg',\n    'https://example.org/images/orange.jpg'\n]);\n```\n\n```js\nvar gallery = blueimp.Gallery([\n    {\n        title: 'Banana',\n        href: 'https://example.org/images/banana.jpg',\n        type: 'image/jpeg',\n        thumbnail: 'https://example.org/thumbnails/banana.jpg'\n    },\n    {\n        title: 'Apple',\n        href: 'https://example.org/images/apple.jpg',\n        type: 'image/jpeg',\n        thumbnail: 'https://example.org/thumbnails/apple.jpg'\n    }\n]);\n```\n\nThe URL property name defined by each list object can be configured via the\n**urlProperty** option. By default, it is set to **href**, which allows to pass\na list of HTML link elements as first argument.\n\nFor images, the **thumbnail** property defines the URL of the image thumbnail,\nwhich is used for the indicator navigation displayed at the bottom of the\nGallery, if the controls are visible.\n\nThe object returned by executing the Gallery function (the **gallery** variable\nin the example code above) is a new instance of the Gallery and allows to access\nthe public [API methods](#api-methods) provided by the Gallery.  \nThe Gallery initialization function returns **false** if the given list was\nempty, the Gallery widget is missing, or the browser doesn't pass the\nfunctionality test.\n\n### API methods\nThe Gallery object returned by executing the Gallery function provides the\nfollowing public API methods:\n\n```js\n// Return the current slide index position:\nvar pos = gallery.getIndex();\n\n// Return the total number of slides:\nvar count = gallery.getNumber();\n\n// Move to the previous slide:\ngallery.prev();\n\n// Move to the next slide:\ngallery.next();\n\n// Move to the given slide index with the (optional) given duraction speed in milliseconds:\ngallery.slide(index, duration);\n\n// Start an automatic slideshow with the given interval in milliseconds (optional):\ngallery.play(interval);\n\n// Stop the automatic slideshow:\ngallery.pause();\n\n// Add additional slides after Gallery initialization:\ngallery.add(list);\n\n// Close and deinitialize the Gallery:\ngallery.close();\n```\n\n### Videos\n\n#### HTML5 video player\n\nThe Gallery can be initialized with a list of videos instead of images, or a\ncombination of both:\n\n```js\nblueimp.Gallery([\n    {\n        title: 'Fruits',\n        href: 'https://example.org/videos/fruits.mp4',\n        type: 'video/mp4',\n        poster: 'https://example.org/images/fruits.jpg'\n    },\n    {\n        title: 'Banana',\n        href: 'https://example.org/images/banana.jpg',\n        type: 'image/jpeg',\n        thumbnail: 'https://example.org/thumbnails/banana.jpg'\n    }\n]);\n```\n\nThe Gallery uses the **type** property to determine the content type of the\nobject to display.  \nIf the type property is empty or doesn't exist, the default type **image** is\nassumed.  \nObjects with a video type will be displayed in a\n[HTML5 video element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/video)\nif the browser supports the video content type.\n\nFor videos, the **poster** property defines the URL of the poster image to\ndisplay, before the video is started.\n\n#### Multiple video sources\nTo provide multiple video formats, the **sources** property of a list object can\nbe set to an array of objects with **href** and **type** properties for each\nvideo source. The first video format in the list that the browser can play will\nbe displayed:\n\n```js\nblueimp.Gallery([\n    {\n        title: 'Fruits',\n        type: 'video/*',\n        poster: 'https://example.org/images/fruits.jpg',\n        sources: [\n            {\n                href: 'https://example.org/videos/fruits.mp4',\n                type: 'video/mp4'\n            },\n            {\n                href: 'https://example.org/videos/fruits.ogg',\n                type: 'video/ogg'\n            }\n        ]\n    }\n]);\n```\n\nIt is also possible to define the video sources as data-attribute on a link\nelement in [JSON](https://developer.mozilla.org/en-US/docs/JSON) array format:\n\n```html\n<div id=\"links\">\n    <a\n        href=\"https://example.org/videos/fruits.mp4\"\n        title=\"Fruits\"\n        type=\"video/mp4\"\n        data-poster=\"https://example.org/images/fruits.jpg\"\n        data-sources='[{\"href\": \"https://example.org/videos/fruits.mp4\", \"type\": \"video/mp4\"}, {\"href\": \"https://example.org/videos/fruits.ogg\", \"type\": \"video/ogg\"}]'\n    >Fruits</a>\n</div>\n```\n\n#### YouTube\nThe Gallery can display [YouTube](https://www.youtube.com/) videos for Gallery\nitems with a **type** of **text/html** and a **youtube** property\n(configurable via [YouTube options](#youtube-options)) with the YouTube\nvideo-ID:\n\n```js\nblueimp.Gallery([\n    {\n        title: 'A YouYube video',\n        href: 'https://www.youtube.com/watch?v=VIDEO_ID',\n        type: 'text/html',\n        youtube: 'VIDEO_ID',\n        poster: 'https://img.youtube.com/vi/VIDEO_ID/maxresdefault.jpg'\n    },\n    {\n        title: 'Banana',\n        href: 'https://example.org/images/banana.jpg',\n        type: 'image/jpeg',\n        thumbnail: 'https://example.org/thumbnails/banana.jpg'\n    }\n]);\n```\n\nIf the `href` and `poster` properties are undefined, they are set automatically\nbased on the video ID.\n\nPlease note that the Gallery YouTube integration requires a browser with\n[postMessage](https://developer.mozilla.org/en-US/docs/Web/API/window.postMessage)\nsupport, which excludes IE7.\n\n#### Vimeo\nThe Gallery can display [Vimeo](https://vimeo.com/) videos for Gallery items\nwith a **type** of **text/html** and a **vimeo** property\n(configurable via [Vimeo options](#vimeo-options)) with the Vimeo video-ID:\n\n```js\nblueimp.Gallery([\n    {\n        title: 'A Vimeo video',\n        href: 'https://vimeo.com/VIDEO_ID',\n        type: 'text/html',\n        vimeo: 'VIDEO_ID',\n        poster: 'https://secure-b.vimeocdn.com/ts/POSTER_ID.jpg'\n    },\n    {\n        title: 'Banana',\n        href: 'https://example.org/images/banana.jpg',\n        type: 'image/jpeg',\n        thumbnail: 'https://example.org/thumbnails/banana.jpg'\n    }\n]);\n```\n\nIf the `href` property is undefined, it is set automatically based on the\nvideo ID.\n\nPlease note that the Gallery Vimeo integration requires a browser with\n[postMessage](https://developer.mozilla.org/en-US/docs/Web/API/window.postMessage)\nsupport, which excludes IE7.\n\n### Additional Gallery elements\nIt is possible to add additional elements to the Gallery widget, e.g. a\ndescription label.\n\nFirst, add the desired HTML element to the Gallery widget:\n\n```html\n<div id=\"blueimp-gallery\" class=\"blueimp-gallery\">\n    <div class=\"slides\"></div>\n    <h3 class=\"title\"></h3>\n    <!-- The placeholder for the description label: -->\n    <p class=\"description\"></p>\n    <a class=\"prev\">‹</a>\n    <a class=\"next\">›</a>\n    <a class=\"close\">×</a>\n    <a class=\"play-pause\"></a>\n    <ol class=\"indicator\"></ol>\n</div>\n```\n\nNext, add the desired element styles to your CSS file:\n\n```css\n.blueimp-gallery > .description {\n  position: absolute;\n  top: 30px;\n  left: 15px;\n  color: #fff;\n  display: none;\n}\n.blueimp-gallery-controls > .description {\n  display: block;\n}\n```\n\nThen, add the additional element information to each of your links:\n\n```html\n<div id=\"links\">\n    <a href=\"images/banana.jpg\" title=\"Banana\" data-description=\"This is a banana.\">Banana</a>\n    <a href=\"images/apple.jpg\" title=\"Apple\" data-description=\"This is an apple.\">Apple</a>\n</div>\n```\n\nFinally, initialize the Gallery with an onslide callback option, to set the\nelement content based on the information from the current link:\n\n```js\nblueimp.Gallery(\n    document.getElementById('links'),\n    {\n        onslide: function (index, slide) {\n            var text = this.list[index].getAttribute('data-description'),\n                node = this.container.find('.description');\n            node.empty();\n            if (text) {\n                node[0].appendChild(document.createTextNode(text));\n            }\n        }\n    }\n);\n```\n\n### Additional content types\nBy extending the Gallery prototype with new factory methods, additional content\ntypes can be displayed.  By default, blueimp Gallery provides the\n**imageFactory** and **videoFactory** methods for **image** and **video**\ncontent types respectively.  \n\nThe Gallery uses the **type** property of each content object to determine which\nfactory method to use.  The **type** defines the\n[Internet media type](https://en.wikipedia.org/wiki/Internet_media_type) of the\ncontent object and is composed of two or more parts: A type, a subtype, and zero\nor more optional parameters, e.g. **text/html; charset=UTF-8** for an HTML\ndocument with UTF-8 encoding.  \nThe main type (the string in front of the slash, **text** in the example above)\nis concatenated with the string **Factory** to create the factory method name,\ne.g. **textFactory**.\n\n#### Example HTML text factory implementation\nPlease note that the textFactory script has to be included after the core\nGallery script, but before including the [YouTube](#youtube) and [Vimeo](#vimeo)\nintegration plugins, which extend the textFactory implementation to handle\nYouTube and Vimeo video links.\n\nPlease also note that although blueimp Gallery doesn't require\n[jQuery](https://jquery.com/), the following example uses it for convenience.\n\nExtend the Gallery prototype with the **textFactory** method:\n\n```js\nblueimp.Gallery.prototype.textFactory = function (obj, callback) {\n    var $element = $('<div>')\n            .addClass('text-content')\n            .attr('title', obj.title);\n    $.get(obj.href)\n        .done(function (result) {\n            $element.html(result);\n            callback({\n                type: 'load',\n                target: $element[0]\n            });\n        })\n        .fail(function () {\n            callback({\n                type: 'error',\n                target: $element[0]\n            });\n        });\n    return $element[0];\n};\n```\n\nNext, add the **text-content** class to the Gallery CSS:\n\n```css\n.blueimp-gallery > .slides > .slide > .text-content {\n    overflow: auto;\n    margin: 60px auto;\n    padding: 0 60px;\n    max-width: 920px;\n    text-align: left;\n}\n```\n\nWith the previous changes in place, the Gallery can now handle HTML content\ntypes:\n\n```js\nblueimp.Gallery([\n    {\n        title: 'Noodle soup',\n        href: 'https://example.org/text/noodle-soup.html',\n        type: 'text/html'\n    },\n    {\n        title: 'Tomato salad',\n        href: 'https://example.org/text/tomato-salad.html',\n        type: 'text/html'\n    }\n]);\n```\n\n### jQuery plugin\n\n#### jQuery plugin setup\nThe blueimp Gallery jQuery plugin registers a global click handler to open links\nwith **data-gallery** attribute in the Gallery lightbox.\n\nTo use it, follow the [lightbox setup](#lightbox-setup) guide, but replace the\nminified Gallery script with the jQuery plugin version and include it after\nincluding [jQuery](https://jquery.com/):\n\n```html\n<script src=\"//ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js\"></script>\n<script src=\"js/jquery.blueimp-gallery.min.js\"></script>\n```\n\nNext, add the attribute **data-gallery** to your Gallery links:\n\n```html\n<div id=\"links\">\n    <a href=\"images/banana.jpg\" title=\"Banana\" data-gallery>\n        <img src=\"images/thumbnails/banana.jpg\" alt=\"Banana\">\n    </a>\n    <a href=\"images/apple.jpg\" title=\"Apple\" data-gallery>\n        <img src=\"images/thumbnails/apple.jpg\" alt=\"Apple\">\n    </a>\n    <a href=\"images/orange.jpg\" title=\"Orange\" data-gallery>\n        <img src=\"images/thumbnails/orange.jpg\" alt=\"Orange\">\n    </a>\n</div>\n```\n\nThe onclick handler from the [lightbox setup](#lightbox-setup) guide is not\nrequired and can be removed.\n\n#### HTML5 data-attributes\nOptions for the Gallery lightbox opened via the jQuery plugin can be defined as\n[HTML5 data-attributes](https://api.jquery.com/data/#data-html5) on the Gallery\nwidget container.\n\nThe jQuery plugin also introduces the additional **filter** option, which is\napplied to the Gallery links via\n[jQuery's filter method](https://api.jquery.com/filter/) and allows to remove\nduplicates from the list:\n\n```html\n<div id=\"blueimp-gallery\" class=\"blueimp-gallery\" data-start-slideshow=\"true\" data-filter=\":even\">\n    <div class=\"slides\"></div>\n    <h3 class=\"title\"></h3>\n    <a class=\"prev\">‹</a>\n    <a class=\"next\">›</a>\n    <a class=\"close\">×</a>\n    <a class=\"play-pause\"></a>\n    <ol class=\"indicator\"></ol>\n</div>\n```\n\nThis will initialize the Gallery with the option **startSlideshow** set to\n**true**.  \nIt will also filter the Gallery links so that only links with an even index\nnumber will be included.\n\n#### Container ids and link grouping\nIf the **data-gallery** attribute value is a valid id string\n(e.g. \"#blueimp-gallery\"), it is used as container option.  \nSetting **data-gallery** to a non-empty string also allows to group links into\ndifferent sets of Gallery images:\n\n```html\n<div id=\"fruits\">\n    <a href=\"images/banana.jpg\" title=\"Banana\" data-gallery=\"#blueimp-gallery-fruits\">\n        <img src=\"images/thumbnails/banana.jpg\" alt=\"Banana\">\n    </a>\n    <a href=\"images/apple.jpg\" title=\"Apple\" data-gallery=\"#blueimp-gallery-fruits\">\n        <img src=\"images/thumbnails/apple.jpg\" alt=\"Apple\">\n    </a>\n</div>\n<div id=\"vegetables\">\n    <a href=\"images/tomato.jpg\" title=\"Tomato\" data-gallery=\"#blueimp-gallery-vegetables\">\n        <img src=\"images/thumbnails/tomato.jpg\" alt=\"Tomato\">\n    </a>\n    <a href=\"images/onion.jpg\" title=\"Onion\" data-gallery=\"#blueimp-gallery-vegetables\">\n        <img src=\"images/thumbnails/onion.jpg\" alt=\"Onion\">\n    </a>\n</div>\n```\n\nThis will open the links with the **data-gallery** attribute\n**#blueimp-gallery-fruits** in the Gallery widget with the id\n**blueimp-gallery-fruits**, and the links with the **data-gallery** attribute\n**#blueimp-gallery-vegetables**  in the Gallery widget with the id\n**blueimp-gallery-vegetables**.\n\n#### Gallery object\nThe gallery object is stored via\n[jQuery data storage](https://api.jquery.com/category/miscellaneous/data-storage/)\non the Gallery widget when the Gallery is opened and can be retrieved the\nfollowing way:\n\n```js\nvar gallery = $('#blueimp-gallery').data('gallery');\n```\n\nThis gallery object provides all methods outlined in the API methods section.\n\n#### jQuery events\nThe jQuery plugin triggers Gallery events on the widget container, with event\nnames equivalent to the gallery [event callbacks](#event-callbacks):\n\n```js\n$('#blueimp-gallery')\n    .on('open', function (event) {\n        // Gallery open event handler\n    })\n    .on('opened', function (event) {\n        // Gallery opened event handler\n    })\n    .on('slide', function (event, index, slide) {\n        // Gallery slide event handler\n    })\n    .on('slideend', function (event, index, slide) {\n        // Gallery slideend event handler\n    })\n    .on('slidecomplete', function (event, index, slide) {\n        // Gallery slidecomplete event handler\n    })\n    .on('close', function (event) {\n        // Gallery close event handler\n    })\n    .on('closed', function (event) {\n        // Gallery closed event handler\n    });\n```\n\n## Requirements\nblueimp Gallery doesn't require any other libraries and can be used standalone\nwithout any dependencies.\n\nYou can also use the individual source files instead of the standalone minified\nversion:\n\n```html\n<link rel=\"stylesheet\" href=\"css/blueimp-gallery.css\">\n<link rel=\"stylesheet\" href=\"css/blueimp-gallery-indicator.css\">\n<link rel=\"stylesheet\" href=\"css/blueimp-gallery-video.css\">\n<!-- ... -->\n<script src=\"js/blueimp-helper.js\"></script>\n<script src=\"js/blueimp-gallery.js\"></script>\n<script src=\"js/blueimp-gallery-fullscreen.js\"></script>\n<script src=\"js/blueimp-gallery-indicator.js\"></script>\n<script src=\"js/blueimp-gallery-video.js\"></script>\n<script src=\"js/blueimp-gallery-youtube.js\"></script>\n<script src=\"js/blueimp-gallery-vimeo.js\"></script>\n```\n\nThe helper script can be replaced by [jQuery](https://jquery.com/) v. 1.7+.  \nThe fullscreen, indicator, video, youtube and vimeo source files are optional if\ntheir functionality is not required.\n\nThe [jQuery plugin](#jquery-plugin) requires\n[jQuery](https://jquery.com/) v. 1.7+ and the basic Gallery script, while the\nfullscreen, indicator, video, youtube and vimeo source files are also optional:\n\n```html\n<script src=\"//ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js\"></script>\n<script src=\"js/blueimp-gallery.js\"></script>\n<script src=\"js/blueimp-gallery-fullscreen.js\"></script>\n<script src=\"js/blueimp-gallery-indicator.js\"></script>\n<script src=\"js/blueimp-gallery-video.js\"></script>\n<script src=\"js/blueimp-gallery-youtube.js\"></script>\n<script src=\"js/blueimp-gallery-vimeo.js\"></script>\n<script src=\"js/jquery.blueimp-gallery.js\"></script>\n```\n\nPlease note that the jQuery plugin is an optional extension and not required for\nthe Gallery functionality.\n\n## Browsers\nblueimp Gallery has been tested with and supports the following browsers:\n\n### Desktop browsers\n\n* Google Chrome 14.0+\n* Apple Safari 4.0+\n* Mozilla Firefox 4.0+\n* Opera 10.0+\n* Microsoft Internet Explorer 7.0+\n\n### Mobile browsers\n\n* Apple Safari on iOS 6.0+\n* Google Chrome on iOS 6.0+\n* Google Chrome on Android 4.0+\n* Default Browser on Android 2.3+\n* Opera Mobile 12.0+\n\n## License\nReleased under the [MIT license](https://opensource.org/licenses/MIT).\n\n## Credits\nThe swipe implementation is based on code from the\n[Swipe](http://swipejs.com/) library.\n"
  },
  {
    "path": "app_backend/static/plugin/Gallery-2.25.0/css/blueimp-gallery-indicator.css",
    "content": "@charset \"UTF-8\";\n/*\n * blueimp Gallery Indicator CSS\n * https://github.com/blueimp/Gallery\n *\n * Copyright 2013, Sebastian Tschan\n * https://blueimp.net\n *\n * Licensed under the MIT license:\n * https://opensource.org/licenses/MIT\n */\n\n.blueimp-gallery > .indicator {\n  position: absolute;\n  top: auto;\n  right: 15px;\n  bottom: 15px;\n  left: 15px;\n  margin: 0 40px;\n  padding: 0;\n  list-style: none;\n  text-align: center;\n  line-height: 10px;\n  display: none;\n}\n.blueimp-gallery > .indicator > li {\n  display: inline-block;\n  width: 9px;\n  height: 9px;\n  margin: 6px 3px 0 3px;\n  -webkit-box-sizing: content-box;\n     -moz-box-sizing: content-box;\n          box-sizing: content-box;\n  border: 1px solid transparent;\n  background: #ccc;\n  background: rgba(255, 255, 255, 0.25) center no-repeat;\n  border-radius: 5px;\n  box-shadow: 0 0 2px #000;\n  opacity: 0.5;\n  cursor: pointer;\n}\n.blueimp-gallery > .indicator > li:hover,\n.blueimp-gallery > .indicator > .active {\n  background-color: #fff;\n  border-color: #fff;\n  opacity: 1;\n}\n.blueimp-gallery-controls > .indicator {\n  display: block;\n  /* Fix z-index issues (controls behind slide element) on Android: */\n  -webkit-transform: translateZ(0);\n     -moz-transform: translateZ(0);\n      -ms-transform: translateZ(0);\n       -o-transform: translateZ(0);\n          transform: translateZ(0);\n}\n.blueimp-gallery-single > .indicator {\n  display: none;\n}\n.blueimp-gallery > .indicator {\n  -webkit-user-select: none;\n   -khtml-user-select: none;\n     -moz-user-select: none;\n      -ms-user-select: none;\n          user-select: none;\n}\n\n/* IE7 fixes */\n*+html .blueimp-gallery > .indicator > li {\n  display: inline;\n}\n"
  },
  {
    "path": "app_backend/static/plugin/Gallery-2.25.0/css/blueimp-gallery-video.css",
    "content": "@charset \"UTF-8\";\n/*\n * blueimp Gallery Video Factory CSS\n * https://github.com/blueimp/Gallery\n *\n * Copyright 2013, Sebastian Tschan\n * https://blueimp.net\n *\n * Licensed under the MIT license:\n * https://opensource.org/licenses/MIT\n */\n\n.blueimp-gallery > .slides > .slide > .video-content > img {\n  position: absolute;\n  top: 0;\n  right: 0;\n  bottom: 0;\n  left: 0;\n  margin: auto;\n  width: auto;\n  height: auto;\n  max-width: 100%;\n  max-height: 100%;\n  /* Prevent artifacts in Mozilla Firefox: */\n  -moz-backface-visibility: hidden;\n}\n.blueimp-gallery > .slides > .slide > .video-content > video {\n  position: absolute;\n  top: 0;\n  left: 0;\n  width: 100%;\n  height: 100%;\n}\n.blueimp-gallery > .slides > .slide > .video-content > iframe {\n  position: absolute;\n  top: 100%;\n  left: 0;\n  width: 100%;\n  height: 100%;\n  border: none;\n}\n.blueimp-gallery > .slides > .slide > .video-playing > iframe {\n  top: 0;\n}\n.blueimp-gallery > .slides > .slide > .video-content > a {\n  position: absolute;\n  top: 50%;\n  right: 0;\n  left: 0;\n  margin: -64px auto 0;\n  width: 128px;\n  height: 128px;\n  background: url(../img/video-play.png) center no-repeat;\n  opacity: 0.8;\n  cursor: pointer;\n}\n.blueimp-gallery > .slides > .slide > .video-content > a:hover {\n  opacity: 1;\n}\n.blueimp-gallery > .slides > .slide > .video-playing > a,\n.blueimp-gallery > .slides > .slide > .video-playing > img {\n  display: none;\n}\n.blueimp-gallery > .slides > .slide > .video-content > video {\n  display: none;\n}\n.blueimp-gallery > .slides > .slide > .video-playing > video {\n  display: block;\n}\n.blueimp-gallery > .slides > .slide > .video-loading > a {\n  background: url(../img/loading.gif) center no-repeat;\n  background-size: 64px 64px;\n}\n\n/* Replace PNGs with SVGs for capable browsers (excluding IE<9) */\nbody:last-child .blueimp-gallery > .slides > .slide > .video-content:not(.video-loading) > a {\n  background-image: url(../img/video-play.svg);\n}\n\n/* IE7 fixes */\n*+html .blueimp-gallery > .slides > .slide > .video-content {\n  height: 100%;\n}\n*+html .blueimp-gallery > .slides > .slide > .video-content > a {\n  left: 50%;\n  margin-left: -64px;\n}\n"
  },
  {
    "path": "app_backend/static/plugin/Gallery-2.25.0/css/blueimp-gallery.css",
    "content": "@charset \"UTF-8\";\n/*\n * blueimp Gallery CSS\n * https://github.com/blueimp/Gallery\n *\n * Copyright 2013, Sebastian Tschan\n * https://blueimp.net\n *\n * Licensed under the MIT license:\n * https://opensource.org/licenses/MIT\n */\n\n.blueimp-gallery,\n.blueimp-gallery > .slides > .slide > .slide-content {\n  position: absolute;\n  top: 0;\n  right: 0;\n  bottom: 0;\n  left: 0;\n  /* Prevent artifacts in Mozilla Firefox: */\n  -moz-backface-visibility: hidden;\n}\n.blueimp-gallery > .slides > .slide > .slide-content {\n  margin: auto;\n  width: auto;\n  height: auto;\n  max-width: 100%;\n  max-height: 100%;\n  opacity: 1;\n}\n.blueimp-gallery {\n  position: fixed;\n  z-index: 999999;\n  overflow: hidden;\n  background: #000;\n  background: rgba(0, 0, 0, 0.9);\n  opacity: 0;\n  display: none;\n  direction: ltr;\n  -ms-touch-action: none;\n  touch-action: none;\n}\n.blueimp-gallery-carousel {\n  position: relative;\n  z-index: auto;\n  margin: 1em auto;\n  /* Set the carousel width/height ratio to 16/9: */\n  padding-bottom: 56.25%;\n  box-shadow: 0 0 10px #000;\n  -ms-touch-action: pan-y;\n  touch-action: pan-y;\n}\n.blueimp-gallery-display {\n  display: block;\n  opacity: 1;\n}\n.blueimp-gallery > .slides {\n  position: relative;\n  height: 100%;\n  overflow: hidden;\n}\n.blueimp-gallery-carousel > .slides {\n  position: absolute;\n}\n.blueimp-gallery > .slides > .slide {\n  position: relative;\n  float: left;\n  height: 100%;\n  text-align: center;\n  -webkit-transition-timing-function: cubic-bezier(0.645, 0.045, 0.355, 1.000);\n     -moz-transition-timing-function: cubic-bezier(0.645, 0.045, 0.355, 1.000);\n      -ms-transition-timing-function: cubic-bezier(0.645, 0.045, 0.355, 1.000);\n       -o-transition-timing-function: cubic-bezier(0.645, 0.045, 0.355, 1.000);\n          transition-timing-function: cubic-bezier(0.645, 0.045, 0.355, 1.000);\n}\n.blueimp-gallery,\n.blueimp-gallery > .slides > .slide > .slide-content {\n  -webkit-transition: opacity 0.2s linear;\n     -moz-transition: opacity 0.2s linear;\n      -ms-transition: opacity 0.2s linear;\n       -o-transition: opacity 0.2s linear;\n          transition: opacity 0.2s linear;\n}\n.blueimp-gallery > .slides > .slide-loading {\n  background: url(../img/loading.gif) center no-repeat;\n  background-size: 64px 64px;\n}\n.blueimp-gallery > .slides > .slide-loading > .slide-content {\n  opacity: 0;\n}\n.blueimp-gallery > .slides > .slide-error {\n  background: url(../img/error.png) center no-repeat;\n}\n.blueimp-gallery > .slides > .slide-error > .slide-content {\n  display: none;\n}\n.blueimp-gallery > .prev,\n.blueimp-gallery > .next {\n  position: absolute;\n  top: 50%;\n  left: 15px;\n  width: 40px;\n  height: 40px;\n  margin-top: -23px;\n  font-family: \"Helvetica Neue\", Helvetica, Arial, sans-serif;\n  font-size: 60px;\n  font-weight: 100;\n  line-height: 30px;\n  color: #fff;\n  text-decoration: none;\n  text-shadow: 0 0 2px #000;\n  text-align: center;\n  background: #222;\n  background: rgba(0, 0, 0, 0.5);\n  -webkit-box-sizing: content-box;\n     -moz-box-sizing: content-box;\n          box-sizing: content-box;\n  border: 3px solid #fff;\n  -webkit-border-radius: 23px;\n     -moz-border-radius: 23px;\n          border-radius: 23px;\n  opacity: 0.5;\n  cursor: pointer;\n  display: none;\n}\n.blueimp-gallery > .next {\n  left: auto;\n  right: 15px;\n}\n.blueimp-gallery > .close,\n.blueimp-gallery > .title {\n  position: absolute;\n  top: 15px;\n  left: 15px;\n  margin: 0 40px 0 0;\n  font-size: 20px;\n  line-height: 30px;\n  color: #fff;\n  text-shadow: 0 0 2px #000;\n  opacity: 0.8;\n  display: none;\n}\n.blueimp-gallery > .close {\n  padding: 15px;\n  right: 15px;\n  left: auto;\n  margin: -15px;\n  font-size: 30px;\n  text-decoration: none;\n  cursor: pointer;\n}\n.blueimp-gallery > .play-pause {\n  position: absolute;\n  right: 15px;\n  bottom: 15px;\n  width: 15px;\n  height: 15px;\n  background: url(../img/play-pause.png) 0 0 no-repeat;\n  cursor: pointer;\n  opacity: 0.5;\n  display: none;\n}\n.blueimp-gallery-playing > .play-pause {\n  background-position: -15px 0;\n}\n.blueimp-gallery > .prev:hover,\n.blueimp-gallery > .next:hover,\n.blueimp-gallery > .close:hover,\n.blueimp-gallery > .title:hover,\n.blueimp-gallery > .play-pause:hover {\n  color: #fff;\n  opacity: 1;\n}\n.blueimp-gallery-controls > .prev,\n.blueimp-gallery-controls > .next,\n.blueimp-gallery-controls > .close,\n.blueimp-gallery-controls > .title,\n.blueimp-gallery-controls > .play-pause {\n  display: block;\n  /* Fix z-index issues (controls behind slide element) on Android: */\n  -webkit-transform: translateZ(0);\n     -moz-transform: translateZ(0);\n      -ms-transform: translateZ(0);\n       -o-transform: translateZ(0);\n          transform: translateZ(0);\n}\n.blueimp-gallery-single > .prev,\n.blueimp-gallery-left > .prev,\n.blueimp-gallery-single > .next,\n.blueimp-gallery-right > .next,\n.blueimp-gallery-single > .play-pause {\n  display: none;\n}\n.blueimp-gallery > .slides > .slide > .slide-content,\n.blueimp-gallery > .prev,\n.blueimp-gallery > .next,\n.blueimp-gallery > .close,\n.blueimp-gallery > .play-pause {\n  -webkit-user-select: none;\n   -khtml-user-select: none;\n     -moz-user-select: none;\n      -ms-user-select: none;\n          user-select: none;\n}\n\n/* Replace PNGs with SVGs for capable browsers (excluding IE<9) */\nbody:last-child .blueimp-gallery > .slides > .slide-error {\n  background-image: url(../img/error.svg);\n}\nbody:last-child .blueimp-gallery > .play-pause {\n  width: 20px;\n  height: 20px;\n  background-size: 40px 20px;\n  background-image: url(../img/play-pause.svg);\n}\nbody:last-child .blueimp-gallery-playing > .play-pause {\n  background-position: -20px 0;\n}\n\n/* IE7 fixes */\n*+html .blueimp-gallery > .slides > .slide {\n  min-height: 300px;\n}\n*+html .blueimp-gallery > .slides > .slide > .slide-content {\n  position: relative;\n}\n"
  },
  {
    "path": "app_backend/static/plugin/Gallery-2.25.0/css/demo/demo.css",
    "content": "/*\n * blueimp Gallery Demo CSS\n * https://github.com/blueimp/Gallery\n *\n * Copyright 2013, Sebastian Tschan\n * https://blueimp.net\n *\n * Licensed under the MIT license:\n * https://opensource.org/licenses/MIT\n */\n\nbody {\n  max-width: 750px;\n  margin: 0 auto;\n  padding: 1em;\n  font-family: 'Lucida Grande', 'Lucida Sans Unicode', Arial, sans-serif;\n  font-size: 1em;\n  line-height: 1.4em;\n  background: #222;\n  color: #fff;\n  -webkit-text-size-adjust: 100%;\n      -ms-text-size-adjust: 100%;\n}\na {\n  color: orange;\n  text-decoration: none;\n}\nimg {\n  border: 0;\n  vertical-align: middle;\n}\nh1 {\n  line-height: 1em;\n}\nh2,\n.links {\n  text-align: center;\n}\n\n@media (min-width: 481px) {\n  .navigation {\n    list-style: none;\n    padding: 0;\n  }\n  .navigation li {\n    display: inline-block;\n  }\n  .navigation li:not(:first-child):before {\n    content: '| ';\n  }\n}\n"
  },
  {
    "path": "app_backend/static/plugin/Gallery-2.25.0/index.html",
    "content": "<!DOCTYPE HTML>\n<!--\n/*\n * blueimp Gallery Demo\n * https://github.com/blueimp/Gallery\n *\n * Copyright 2013, Sebastian Tschan\n * https://blueimp.net\n *\n * Licensed under the MIT license:\n * https://opensource.org/licenses/MIT\n */\n-->\n<html lang=\"en\">\n<head>\n<!--[if IE]>\n<meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge,chrome=1\">\n<![endif]-->\n<meta charset=\"utf-8\">\n<title>blueimp Gallery</title>\n<meta name=\"description\" content=\"blueimp Gallery is a touch-enabled, responsive and customizable image and video gallery, carousel and lightbox, optimized for both mobile and desktop web browsers. It features swipe, mouse and keyboard navigation, transition effects, slideshow functionality, fullscreen support and on-demand content loading and can be extended to display additional content types.\">\n<meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n<link rel=\"stylesheet\" href=\"css/blueimp-gallery.css\">\n<link rel=\"stylesheet\" href=\"css/blueimp-gallery-indicator.css\">\n<link rel=\"stylesheet\" href=\"css/blueimp-gallery-video.css\">\n<link rel=\"stylesheet\" href=\"css/demo/demo.css\">\n</head>\n<body>\n<h1>blueimp Gallery</h1>\n<p><a href=\"https://github.com/blueimp/Gallery\">blueimp Gallery</a> is a touch-enabled, responsive and customizable image &amp; video gallery, carousel and lightbox, optimized for both mobile and desktop web browsers.<br>\nIt features swipe, mouse and keyboard navigation, transition effects, slideshow functionality, fullscreen support and on-demand content loading and can be extended to display additional content types.</p>\n<ul class=\"navigation\">\n    <li><a href=\"https://github.com/blueimp/Gallery/tags\">Download</a></li>\n    <li><a href=\"https://github.com/blueimp/Gallery\">Source Code</a></li>\n    <li><a href=\"https://github.com/blueimp/Gallery/blob/master/README.md\">Documentation</a></li>\n    <li><a href=\"https://blueimp.net\">&copy; Sebastian Tschan</a></li>\n</ul>\n<p><a href=\"https://github.com/blueimp/Gallery\">blueimp Gallery</a> is based on <a href=\"http://swipejs.com/\">Swipe</a>.</p>\n<br>\n<h2>Carousel image gallery</h2>\n<!-- The Gallery as inline carousel, can be positioned anywhere on the page -->\n<div id=\"blueimp-image-carousel\" class=\"blueimp-gallery blueimp-gallery-carousel\">\n    <div class=\"slides\"></div>\n    <h3 class=\"title\"></h3>\n    <a class=\"prev\">‹</a>\n    <a class=\"next\">›</a>\n    <a class=\"play-pause\"></a>\n</div>\n<br>\n<h2>Carousel video gallery</h2>\n<!-- The Gallery as inline carousel, can be positioned anywhere on the page -->\n<div id=\"blueimp-video-carousel\" class=\"blueimp-gallery blueimp-gallery-controls blueimp-gallery-carousel\">\n    <div class=\"slides\"></div>\n    <h3 class=\"title\"></h3>\n    <a class=\"prev\">‹</a>\n    <a class=\"next\">›</a>\n    <a class=\"play-pause\"></a>\n</div>\n<br>\n<h2>Lightbox image gallery</h2>\n<!-- The container for the list of example images -->\n<div id=\"links\" class=\"links\"></div>\n<!-- The Gallery as lightbox dialog, should be a child element of the document body -->\n<div id=\"blueimp-gallery\" class=\"blueimp-gallery\">\n    <div class=\"slides\"></div>\n    <h3 class=\"title\"></h3>\n    <a class=\"prev\">‹</a>\n    <a class=\"next\">›</a>\n    <a class=\"close\">×</a>\n    <a class=\"play-pause\"></a>\n    <ol class=\"indicator\"></ol>\n</div>\n<script src=\"js/blueimp-helper.js\"></script>\n<script src=\"js/blueimp-gallery.js\"></script>\n<script src=\"js/blueimp-gallery-fullscreen.js\"></script>\n<script src=\"js/blueimp-gallery-indicator.js\"></script>\n<script src=\"js/blueimp-gallery-video.js\"></script>\n<script src=\"js/blueimp-gallery-vimeo.js\"></script>\n<script src=\"js/blueimp-gallery-youtube.js\"></script>\n<script src=\"js/vendor/jquery.js\"></script>\n<script src=\"js/jquery.blueimp-gallery.js\"></script>\n<script src=\"js/demo/demo.js\"></script>\n</body>\n</html>\n"
  },
  {
    "path": "app_backend/static/plugin/Gallery-2.25.0/js/blueimp-gallery-fullscreen.js",
    "content": "/*\n * blueimp Gallery Fullscreen JS\n * https://github.com/blueimp/Gallery\n *\n * Copyright 2013, Sebastian Tschan\n * https://blueimp.net\n *\n * Licensed under the MIT license:\n * https://opensource.org/licenses/MIT\n */\n\n/* global define, window, document */\n\n;(function (factory) {\n  'use strict'\n  if (typeof define === 'function' && define.amd) {\n    // Register as an anonymous AMD module:\n    define([\n      './blueimp-helper',\n      './blueimp-gallery'\n    ], factory)\n  } else {\n    // Browser globals:\n    factory(\n      window.blueimp.helper || window.jQuery,\n      window.blueimp.Gallery\n    )\n  }\n}(function ($, Gallery) {\n  'use strict'\n\n  $.extend(Gallery.prototype.options, {\n    // Defines if the gallery should open in fullscreen mode:\n    fullScreen: false\n  })\n\n  var initialize = Gallery.prototype.initialize\n  var close = Gallery.prototype.close\n\n  $.extend(Gallery.prototype, {\n    getFullScreenElement: function () {\n      return document.fullscreenElement ||\n      document.webkitFullscreenElement ||\n      document.mozFullScreenElement ||\n      document.msFullscreenElement\n    },\n\n    requestFullScreen: function (element) {\n      if (element.requestFullscreen) {\n        element.requestFullscreen()\n      } else if (element.webkitRequestFullscreen) {\n        element.webkitRequestFullscreen()\n      } else if (element.mozRequestFullScreen) {\n        element.mozRequestFullScreen()\n      } else if (element.msRequestFullscreen) {\n        element.msRequestFullscreen()\n      }\n    },\n\n    exitFullScreen: function () {\n      if (document.exitFullscreen) {\n        document.exitFullscreen()\n      } else if (document.webkitCancelFullScreen) {\n        document.webkitCancelFullScreen()\n      } else if (document.mozCancelFullScreen) {\n        document.mozCancelFullScreen()\n      } else if (document.msExitFullscreen) {\n        document.msExitFullscreen()\n      }\n    },\n\n    initialize: function () {\n      initialize.call(this)\n      if (this.options.fullScreen && !this.getFullScreenElement()) {\n        this.requestFullScreen(this.container[0])\n      }\n    },\n\n    close: function () {\n      if (this.getFullScreenElement() === this.container[0]) {\n        this.exitFullScreen()\n      }\n      close.call(this)\n    }\n\n  })\n\n  return Gallery\n}))\n"
  },
  {
    "path": "app_backend/static/plugin/Gallery-2.25.0/js/blueimp-gallery-indicator.js",
    "content": "/*\n * blueimp Gallery Indicator JS\n * https://github.com/blueimp/Gallery\n *\n * Copyright 2013, Sebastian Tschan\n * https://blueimp.net\n *\n * Licensed under the MIT license:\n * https://opensource.org/licenses/MIT\n */\n\n/* global define, window, document */\n\n;(function (factory) {\n  'use strict'\n  if (typeof define === 'function' && define.amd) {\n    // Register as an anonymous AMD module:\n    define([\n      './blueimp-helper',\n      './blueimp-gallery'\n    ], factory)\n  } else {\n    // Browser globals:\n    factory(\n      window.blueimp.helper || window.jQuery,\n      window.blueimp.Gallery\n    )\n  }\n}(function ($, Gallery) {\n  'use strict'\n\n  $.extend(Gallery.prototype.options, {\n    // The tag name, Id, element or querySelector of the indicator container:\n    indicatorContainer: 'ol',\n    // The class for the active indicator:\n    activeIndicatorClass: 'active',\n    // The list object property (or data attribute) with the thumbnail URL,\n    // used as alternative to a thumbnail child element:\n    thumbnailProperty: 'thumbnail',\n    // Defines if the gallery indicators should display a thumbnail:\n    thumbnailIndicators: true\n  })\n\n  var initSlides = Gallery.prototype.initSlides\n  var addSlide = Gallery.prototype.addSlide\n  var resetSlides = Gallery.prototype.resetSlides\n  var handleClick = Gallery.prototype.handleClick\n  var handleSlide = Gallery.prototype.handleSlide\n  var handleClose = Gallery.prototype.handleClose\n\n  $.extend(Gallery.prototype, {\n    createIndicator: function (obj) {\n      var indicator = this.indicatorPrototype.cloneNode(false)\n      var title = this.getItemProperty(obj, this.options.titleProperty)\n      var thumbnailProperty = this.options.thumbnailProperty\n      var thumbnailUrl\n      var thumbnail\n      if (this.options.thumbnailIndicators) {\n        if (thumbnailProperty) {\n          thumbnailUrl = this.getItemProperty(obj, thumbnailProperty)\n        }\n        if (thumbnailUrl === undefined) {\n          thumbnail = obj.getElementsByTagName && $(obj).find('img')[0]\n          if (thumbnail) {\n            thumbnailUrl = thumbnail.src\n          }\n        }\n        if (thumbnailUrl) {\n          indicator.style.backgroundImage = 'url(\"' + thumbnailUrl + '\")'\n        }\n      }\n      if (title) {\n        indicator.title = title\n      }\n      return indicator\n    },\n\n    addIndicator: function (index) {\n      if (this.indicatorContainer.length) {\n        var indicator = this.createIndicator(this.list[index])\n        indicator.setAttribute('data-index', index)\n        this.indicatorContainer[0].appendChild(indicator)\n        this.indicators.push(indicator)\n      }\n    },\n\n    setActiveIndicator: function (index) {\n      if (this.indicators) {\n        if (this.activeIndicator) {\n          this.activeIndicator\n            .removeClass(this.options.activeIndicatorClass)\n        }\n        this.activeIndicator = $(this.indicators[index])\n        this.activeIndicator\n          .addClass(this.options.activeIndicatorClass)\n      }\n    },\n\n    initSlides: function (reload) {\n      if (!reload) {\n        this.indicatorContainer = this.container.find(\n          this.options.indicatorContainer\n        )\n        if (this.indicatorContainer.length) {\n          this.indicatorPrototype = document.createElement('li')\n          this.indicators = this.indicatorContainer[0].children\n        }\n      }\n      initSlides.call(this, reload)\n    },\n\n    addSlide: function (index) {\n      addSlide.call(this, index)\n      this.addIndicator(index)\n    },\n\n    resetSlides: function () {\n      resetSlides.call(this)\n      this.indicatorContainer.empty()\n      this.indicators = []\n    },\n\n    handleClick: function (event) {\n      var target = event.target || event.srcElement\n      var parent = target.parentNode\n      if (parent === this.indicatorContainer[0]) {\n        // Click on indicator element\n        this.preventDefault(event)\n        this.slide(this.getNodeIndex(target))\n      } else if (parent.parentNode === this.indicatorContainer[0]) {\n        // Click on indicator child element\n        this.preventDefault(event)\n        this.slide(this.getNodeIndex(parent))\n      } else {\n        return handleClick.call(this, event)\n      }\n    },\n\n    handleSlide: function (index) {\n      handleSlide.call(this, index)\n      this.setActiveIndicator(index)\n    },\n\n    handleClose: function () {\n      if (this.activeIndicator) {\n        this.activeIndicator\n          .removeClass(this.options.activeIndicatorClass)\n      }\n      handleClose.call(this)\n    }\n\n  })\n\n  return Gallery\n}))\n"
  },
  {
    "path": "app_backend/static/plugin/Gallery-2.25.0/js/blueimp-gallery-video.js",
    "content": "/*\n * blueimp Gallery Video Factory JS\n * https://github.com/blueimp/Gallery\n *\n * Copyright 2013, Sebastian Tschan\n * https://blueimp.net\n *\n * Licensed under the MIT license:\n * https://opensource.org/licenses/MIT\n */\n\n/* global define, window, document */\n\n;(function (factory) {\n  'use strict'\n  if (typeof define === 'function' && define.amd) {\n    // Register as an anonymous AMD module:\n    define([\n      './blueimp-helper',\n      './blueimp-gallery'\n    ], factory)\n  } else {\n    // Browser globals:\n    factory(\n      window.blueimp.helper || window.jQuery,\n      window.blueimp.Gallery\n    )\n  }\n}(function ($, Gallery) {\n  'use strict'\n\n  $.extend(Gallery.prototype.options, {\n    // The class for video content elements:\n    videoContentClass: 'video-content',\n    // The class for video when it is loading:\n    videoLoadingClass: 'video-loading',\n    // The class for video when it is playing:\n    videoPlayingClass: 'video-playing',\n    // The list object property (or data attribute) for the video poster URL:\n    videoPosterProperty: 'poster',\n    // The list object property (or data attribute) for the video sources array:\n    videoSourcesProperty: 'sources'\n  })\n\n  var handleSlide = Gallery.prototype.handleSlide\n\n  $.extend(Gallery.prototype, {\n    handleSlide: function (index) {\n      handleSlide.call(this, index)\n      if (this.playingVideo) {\n        this.playingVideo.pause()\n      }\n    },\n\n    videoFactory: function (obj, callback, videoInterface) {\n      var that = this\n      var options = this.options\n      var videoContainerNode = this.elementPrototype.cloneNode(false)\n      var videoContainer = $(videoContainerNode)\n      var errorArgs = [{\n        type: 'error',\n        target: videoContainerNode\n      }]\n      var video = videoInterface || document.createElement('video')\n      var url = this.getItemProperty(obj, options.urlProperty)\n      var type = this.getItemProperty(obj, options.typeProperty)\n      var title = this.getItemProperty(obj, options.titleProperty)\n      var posterUrl = this.getItemProperty(obj, options.videoPosterProperty)\n      var posterImage\n      var sources = this.getItemProperty(\n        obj,\n        options.videoSourcesProperty\n      )\n      var source\n      var playMediaControl\n      var isLoading\n      var hasControls\n      videoContainer.addClass(options.videoContentClass)\n      if (title) {\n        videoContainerNode.title = title\n      }\n      if (video.canPlayType) {\n        if (url && type && video.canPlayType(type)) {\n          video.src = url\n        } else if (sources) {\n          while (sources.length) {\n            source = sources.shift()\n            url = this.getItemProperty(source, options.urlProperty)\n            type = this.getItemProperty(source, options.typeProperty)\n            if (url && type && video.canPlayType(type)) {\n              video.src = url\n              break\n            }\n          }\n        }\n      }\n      if (posterUrl) {\n        video.poster = posterUrl\n        posterImage = this.imagePrototype.cloneNode(false)\n        $(posterImage).addClass(options.toggleClass)\n        posterImage.src = posterUrl\n        posterImage.draggable = false\n        videoContainerNode.appendChild(posterImage)\n      }\n      playMediaControl = document.createElement('a')\n      playMediaControl.setAttribute('target', '_blank')\n      if (!videoInterface) {\n        playMediaControl.setAttribute('download', title)\n      }\n      playMediaControl.href = url\n      if (video.src) {\n        video.controls = true\n        ;(videoInterface || $(video))\n          .on('error', function () {\n            that.setTimeout(callback, errorArgs)\n          })\n          .on('pause', function () {\n            if (video.seeking) return\n            isLoading = false\n            videoContainer\n              .removeClass(that.options.videoLoadingClass)\n              .removeClass(that.options.videoPlayingClass)\n            if (hasControls) {\n              that.container.addClass(that.options.controlsClass)\n            }\n            delete that.playingVideo\n            if (that.interval) {\n              that.play()\n            }\n          })\n          .on('playing', function () {\n            isLoading = false\n            videoContainer\n              .removeClass(that.options.videoLoadingClass)\n              .addClass(that.options.videoPlayingClass)\n            if (that.container.hasClass(that.options.controlsClass)) {\n              hasControls = true\n              that.container.removeClass(that.options.controlsClass)\n            } else {\n              hasControls = false\n            }\n          })\n          .on('play', function () {\n            window.clearTimeout(that.timeout)\n            isLoading = true\n            videoContainer.addClass(that.options.videoLoadingClass)\n            that.playingVideo = video\n          })\n        $(playMediaControl).on('click', function (event) {\n          that.preventDefault(event)\n          if (isLoading) {\n            video.pause()\n          } else {\n            video.play()\n          }\n        })\n        videoContainerNode.appendChild(\n          (videoInterface && videoInterface.element) || video\n        )\n      }\n      videoContainerNode.appendChild(playMediaControl)\n      this.setTimeout(callback, [{\n        type: 'load',\n        target: videoContainerNode\n      }])\n      return videoContainerNode\n    }\n  })\n\n  return Gallery\n}))\n"
  },
  {
    "path": "app_backend/static/plugin/Gallery-2.25.0/js/blueimp-gallery-vimeo.js",
    "content": "/*\n * blueimp Gallery Vimeo Video Factory JS\n * https://github.com/blueimp/Gallery\n *\n * Copyright 2013, Sebastian Tschan\n * https://blueimp.net\n *\n * Licensed under the MIT license:\n * https://opensource.org/licenses/MIT\n */\n\n/* global define, window, document, $f */\n\n;(function (factory) {\n  'use strict'\n  if (typeof define === 'function' && define.amd) {\n    // Register as an anonymous AMD module:\n    define([\n      './blueimp-helper',\n      './blueimp-gallery-video'\n    ], factory)\n  } else {\n    // Browser globals:\n    factory(\n      window.blueimp.helper || window.jQuery,\n      window.blueimp.Gallery\n    )\n  }\n}(function ($, Gallery) {\n  'use strict'\n\n  if (!window.postMessage) {\n    return Gallery\n  }\n\n  $.extend(Gallery.prototype.options, {\n    // The list object property (or data attribute) with the Vimeo video id:\n    vimeoVideoIdProperty: 'vimeo',\n    // The URL for the Vimeo video player, can be extended with custom parameters:\n    // https://developer.vimeo.com/player/embedding\n    vimeoPlayerUrl: '//player.vimeo.com/video/VIDEO_ID?api=1&player_id=PLAYER_ID',\n    // The prefix for the Vimeo video player ID:\n    vimeoPlayerIdPrefix: 'vimeo-player-',\n    // Require a click on the native Vimeo player for the initial playback:\n    vimeoClickToPlay: true\n  })\n\n  var textFactory = Gallery.prototype.textFactory ||\n                      Gallery.prototype.imageFactory\n  var VimeoPlayer = function (url, videoId, playerId, clickToPlay) {\n    this.url = url\n    this.videoId = videoId\n    this.playerId = playerId\n    this.clickToPlay = clickToPlay\n    this.element = document.createElement('div')\n    this.listeners = {}\n  }\n  var counter = 0\n\n  $.extend(VimeoPlayer.prototype, {\n    canPlayType: function () {\n      return true\n    },\n\n    on: function (type, func) {\n      this.listeners[type] = func\n      return this\n    },\n\n    loadAPI: function () {\n      var that = this\n      var apiUrl = '//f.vimeocdn.com/js/froogaloop2.min.js'\n      var scriptTags = document.getElementsByTagName('script')\n      var i = scriptTags.length\n      var scriptTag\n      var called\n      function callback () {\n        if (!called && that.playOnReady) {\n          that.play()\n        }\n        called = true\n      }\n      while (i) {\n        i -= 1\n        if (scriptTags[i].src === apiUrl) {\n          scriptTag = scriptTags[i]\n          break\n        }\n      }\n      if (!scriptTag) {\n        scriptTag = document.createElement('script')\n        scriptTag.src = apiUrl\n      }\n      $(scriptTag).on('load', callback)\n      scriptTags[0].parentNode.insertBefore(scriptTag, scriptTags[0])\n      // Fix for cached scripts on IE 8:\n      if (/loaded|complete/.test(scriptTag.readyState)) {\n        callback()\n      }\n    },\n\n    onReady: function () {\n      var that = this\n      this.ready = true\n      this.player.addEvent('play', function () {\n        that.hasPlayed = true\n        that.onPlaying()\n      })\n      this.player.addEvent('pause', function () {\n        that.onPause()\n      })\n      this.player.addEvent('finish', function () {\n        that.onPause()\n      })\n      if (this.playOnReady) {\n        this.play()\n      }\n    },\n\n    onPlaying: function () {\n      if (this.playStatus < 2) {\n        this.listeners.playing()\n        this.playStatus = 2\n      }\n    },\n\n    onPause: function () {\n      this.listeners.pause()\n      delete this.playStatus\n    },\n\n    insertIframe: function () {\n      var iframe = document.createElement('iframe')\n      iframe.src = this.url\n        .replace('VIDEO_ID', this.videoId)\n        .replace('PLAYER_ID', this.playerId)\n      iframe.id = this.playerId\n      this.element.parentNode.replaceChild(iframe, this.element)\n      this.element = iframe\n    },\n\n    play: function () {\n      var that = this\n      if (!this.playStatus) {\n        this.listeners.play()\n        this.playStatus = 1\n      }\n      if (this.ready) {\n        if (!this.hasPlayed && (this.clickToPlay || (window.navigator &&\n          /iP(hone|od|ad)/.test(window.navigator.platform)))) {\n          // Manually trigger the playing callback if clickToPlay\n          // is enabled and to workaround a limitation in iOS,\n          // which requires synchronous user interaction to start\n          // the video playback:\n          this.onPlaying()\n        } else {\n          this.player.api('play')\n        }\n      } else {\n        this.playOnReady = true\n        if (!window.$f) {\n          this.loadAPI()\n        } else if (!this.player) {\n          this.insertIframe()\n          this.player = $f(this.element)\n          this.player.addEvent('ready', function () {\n            that.onReady()\n          })\n        }\n      }\n    },\n\n    pause: function () {\n      if (this.ready) {\n        this.player.api('pause')\n      } else if (this.playStatus) {\n        delete this.playOnReady\n        this.listeners.pause()\n        delete this.playStatus\n      }\n    }\n\n  })\n\n  $.extend(Gallery.prototype, {\n    VimeoPlayer: VimeoPlayer,\n\n    textFactory: function (obj, callback) {\n      var options = this.options\n      var videoId = this.getItemProperty(obj, options.vimeoVideoIdProperty)\n      if (videoId) {\n        if (this.getItemProperty(obj, options.urlProperty) === undefined) {\n          obj[options.urlProperty] = '//vimeo.com/' + videoId\n        }\n        counter += 1\n        return this.videoFactory(\n          obj,\n          callback,\n          new VimeoPlayer(\n            options.vimeoPlayerUrl,\n            videoId,\n            options.vimeoPlayerIdPrefix + counter,\n            options.vimeoClickToPlay\n          )\n        )\n      }\n      return textFactory.call(this, obj, callback)\n    }\n\n  })\n\n  return Gallery\n}))\n"
  },
  {
    "path": "app_backend/static/plugin/Gallery-2.25.0/js/blueimp-gallery-youtube.js",
    "content": "/*\n * blueimp Gallery YouTube Video Factory JS\n * https://github.com/blueimp/Gallery\n *\n * Copyright 2013, Sebastian Tschan\n * https://blueimp.net\n *\n * Licensed under the MIT license:\n * https://opensource.org/licenses/MIT\n */\n\n/* global define, window, document, YT */\n\n;(function (factory) {\n  'use strict'\n  if (typeof define === 'function' && define.amd) {\n    // Register as an anonymous AMD module:\n    define([\n      './blueimp-helper',\n      './blueimp-gallery-video'\n    ], factory)\n  } else {\n    // Browser globals:\n    factory(\n      window.blueimp.helper || window.jQuery,\n      window.blueimp.Gallery\n    )\n  }\n}(function ($, Gallery) {\n  'use strict'\n\n  if (!window.postMessage) {\n    return Gallery\n  }\n\n  $.extend(Gallery.prototype.options, {\n    // The list object property (or data attribute) with the YouTube video id:\n    youTubeVideoIdProperty: 'youtube',\n    // Optional object with parameters passed to the YouTube video player:\n    // https://developers.google.com/youtube/player_parameters\n    youTubePlayerVars: {\n      wmode: 'transparent'\n    },\n    // Require a click on the native YouTube player for the initial playback:\n    youTubeClickToPlay: true\n  })\n\n  var textFactory = Gallery.prototype.textFactory ||\n                      Gallery.prototype.imageFactory\n  var YouTubePlayer = function (videoId, playerVars, clickToPlay) {\n    this.videoId = videoId\n    this.playerVars = playerVars\n    this.clickToPlay = clickToPlay\n    this.element = document.createElement('div')\n    this.listeners = {}\n  }\n\n  $.extend(YouTubePlayer.prototype, {\n    canPlayType: function () {\n      return true\n    },\n\n    on: function (type, func) {\n      this.listeners[type] = func\n      return this\n    },\n\n    loadAPI: function () {\n      var that = this\n      var onYouTubeIframeAPIReady = window.onYouTubeIframeAPIReady\n      var apiUrl = '//www.youtube.com/iframe_api'\n      var scriptTags = document.getElementsByTagName('script')\n      var i = scriptTags.length\n      var scriptTag\n      window.onYouTubeIframeAPIReady = function () {\n        if (onYouTubeIframeAPIReady) {\n          onYouTubeIframeAPIReady.apply(this)\n        }\n        if (that.playOnReady) {\n          that.play()\n        }\n      }\n      while (i) {\n        i -= 1\n        if (scriptTags[i].src === apiUrl) {\n          return\n        }\n      }\n      scriptTag = document.createElement('script')\n      scriptTag.src = apiUrl\n      scriptTags[0].parentNode.insertBefore(scriptTag, scriptTags[0])\n    },\n\n    onReady: function () {\n      this.ready = true\n      if (this.playOnReady) {\n        this.play()\n      }\n    },\n\n    onPlaying: function () {\n      if (this.playStatus < 2) {\n        this.listeners.playing()\n        this.playStatus = 2\n      }\n    },\n\n    onPause: function () {\n      Gallery.prototype.setTimeout.call(\n        this,\n        this.checkSeek,\n        null,\n        2000\n      )\n    },\n\n    checkSeek: function () {\n      if (this.stateChange === YT.PlayerState.PAUSED ||\n        this.stateChange === YT.PlayerState.ENDED) {\n        // check if current state change is actually paused\n        this.listeners.pause()\n        delete this.playStatus\n      }\n    },\n\n    onStateChange: function (event) {\n      switch (event.data) {\n        case YT.PlayerState.PLAYING:\n          this.hasPlayed = true\n          this.onPlaying()\n          break\n        case YT.PlayerState.PAUSED:\n        case YT.PlayerState.ENDED:\n          this.onPause()\n          break\n      }\n      // Save most recent state change to this.stateChange\n      this.stateChange = event.data\n    },\n\n    onError: function (event) {\n      this.listeners.error(event)\n    },\n\n    play: function () {\n      var that = this\n      if (!this.playStatus) {\n        this.listeners.play()\n        this.playStatus = 1\n      }\n      if (this.ready) {\n        if (!this.hasPlayed && (this.clickToPlay || (window.navigator &&\n          /iP(hone|od|ad)/.test(window.navigator.platform)))) {\n          // Manually trigger the playing callback if clickToPlay\n          // is enabled and to workaround a limitation in iOS,\n          // which requires synchronous user interaction to start\n          // the video playback:\n          this.onPlaying()\n        } else {\n          this.player.playVideo()\n        }\n      } else {\n        this.playOnReady = true\n        if (!(window.YT && YT.Player)) {\n          this.loadAPI()\n        } else if (!this.player) {\n          this.player = new YT.Player(this.element, {\n            videoId: this.videoId,\n            playerVars: this.playerVars,\n            events: {\n              onReady: function () {\n                that.onReady()\n              },\n              onStateChange: function (event) {\n                that.onStateChange(event)\n              },\n              onError: function (event) {\n                that.onError(event)\n              }\n            }\n          })\n        }\n      }\n    },\n\n    pause: function () {\n      if (this.ready) {\n        this.player.pauseVideo()\n      } else if (this.playStatus) {\n        delete this.playOnReady\n        this.listeners.pause()\n        delete this.playStatus\n      }\n    }\n\n  })\n\n  $.extend(Gallery.prototype, {\n    YouTubePlayer: YouTubePlayer,\n\n    textFactory: function (obj, callback) {\n      var options = this.options\n      var videoId = this.getItemProperty(obj, options.youTubeVideoIdProperty)\n      if (videoId) {\n        if (this.getItemProperty(obj, options.urlProperty) === undefined) {\n          obj[options.urlProperty] = '//www.youtube.com/watch?v=' + videoId\n        }\n        if (this.getItemProperty(obj, options.videoPosterProperty) === undefined) {\n          obj[options.videoPosterProperty] = '//img.youtube.com/vi/' + videoId +\n            '/maxresdefault.jpg'\n        }\n        return this.videoFactory(\n          obj,\n          callback,\n          new YouTubePlayer(\n            videoId,\n            options.youTubePlayerVars,\n            options.youTubeClickToPlay\n          )\n        )\n      }\n      return textFactory.call(this, obj, callback)\n    }\n\n  })\n\n  return Gallery\n}))\n"
  },
  {
    "path": "app_backend/static/plugin/Gallery-2.25.0/js/blueimp-gallery.js",
    "content": "/*\n * blueimp Gallery JS\n * https://github.com/blueimp/Gallery\n *\n * Copyright 2013, Sebastian Tschan\n * https://blueimp.net\n *\n * Swipe implementation based on\n * https://github.com/bradbirdsall/Swipe\n *\n * Licensed under the MIT license:\n * https://opensource.org/licenses/MIT\n */\n\n/* global define, window, document, DocumentTouch */\n\n;(function (factory) {\n  'use strict'\n  if (typeof define === 'function' && define.amd) {\n    // Register as an anonymous AMD module:\n    define(['./blueimp-helper'], factory)\n  } else {\n    // Browser globals:\n    window.blueimp = window.blueimp || {}\n    window.blueimp.Gallery = factory(\n      window.blueimp.helper || window.jQuery\n    )\n  }\n}(function ($) {\n  'use strict'\n\n  function Gallery (list, options) {\n    if (document.body.style.maxHeight === undefined) {\n      // document.body.style.maxHeight is undefined on IE6 and lower\n      return null\n    }\n    if (!this || this.options !== Gallery.prototype.options) {\n      // Called as function instead of as constructor,\n      // so we simply return a new instance:\n      return new Gallery(list, options)\n    }\n    if (!list || !list.length) {\n      this.console.log(\n        'blueimp Gallery: No or empty list provided as first argument.',\n        list\n      )\n      return\n    }\n    this.list = list\n    this.num = list.length\n    this.initOptions(options)\n    this.initialize()\n  }\n\n  $.extend(Gallery.prototype, {\n    options: {\n      // The Id, element or querySelector of the gallery widget:\n      container: '#blueimp-gallery',\n      // The tag name, Id, element or querySelector of the slides container:\n      slidesContainer: 'div',\n      // The tag name, Id, element or querySelector of the title element:\n      titleElement: 'h3',\n      // The class to add when the gallery is visible:\n      displayClass: 'blueimp-gallery-display',\n      // The class to add when the gallery controls are visible:\n      controlsClass: 'blueimp-gallery-controls',\n      // The class to add when the gallery only displays one element:\n      singleClass: 'blueimp-gallery-single',\n      // The class to add when the left edge has been reached:\n      leftEdgeClass: 'blueimp-gallery-left',\n      // The class to add when the right edge has been reached:\n      rightEdgeClass: 'blueimp-gallery-right',\n      // The class to add when the automatic slideshow is active:\n      playingClass: 'blueimp-gallery-playing',\n      // The class for all slides:\n      slideClass: 'slide',\n      // The slide class for loading elements:\n      slideLoadingClass: 'slide-loading',\n      // The slide class for elements that failed to load:\n      slideErrorClass: 'slide-error',\n      // The class for the content element loaded into each slide:\n      slideContentClass: 'slide-content',\n      // The class for the \"toggle\" control:\n      toggleClass: 'toggle',\n      // The class for the \"prev\" control:\n      prevClass: 'prev',\n      // The class for the \"next\" control:\n      nextClass: 'next',\n      // The class for the \"close\" control:\n      closeClass: 'close',\n      // The class for the \"play-pause\" toggle control:\n      playPauseClass: 'play-pause',\n      // The list object property (or data attribute) with the object type:\n      typeProperty: 'type',\n      // The list object property (or data attribute) with the object title:\n      titleProperty: 'title',\n      // The list object property (or data attribute) with the object URL:\n      urlProperty: 'href',\n      // The list object property (or data attribute) with the object srcset URL(s):\n      srcsetProperty: 'urlset',\n      // The gallery listens for transitionend events before triggering the\n      // opened and closed events, unless the following option is set to false:\n      displayTransition: true,\n      // Defines if the gallery slides are cleared from the gallery modal,\n      // or reused for the next gallery initialization:\n      clearSlides: true,\n      // Defines if images should be stretched to fill the available space,\n      // while maintaining their aspect ratio (will only be enabled for browsers\n      // supporting background-size=\"contain\", which excludes IE < 9).\n      // Set to \"cover\", to make images cover all available space (requires\n      // support for background-size=\"cover\", which excludes IE < 9):\n      stretchImages: false,\n      // Toggle the controls on pressing the Return key:\n      toggleControlsOnReturn: true,\n      // Toggle the controls on slide click:\n      toggleControlsOnSlideClick: true,\n      // Toggle the automatic slideshow interval on pressing the Space key:\n      toggleSlideshowOnSpace: true,\n      // Navigate the gallery by pressing left and right on the keyboard:\n      enableKeyboardNavigation: true,\n      // Close the gallery on pressing the Esc key:\n      closeOnEscape: true,\n      // Close the gallery when clicking on an empty slide area:\n      closeOnSlideClick: true,\n      // Close the gallery by swiping up or down:\n      closeOnSwipeUpOrDown: true,\n      // Emulate touch events on mouse-pointer devices such as desktop browsers:\n      emulateTouchEvents: true,\n      // Stop touch events from bubbling up to ancestor elements of the Gallery:\n      stopTouchEventsPropagation: false,\n      // Hide the page scrollbars:\n      hidePageScrollbars: true,\n      // Stops any touches on the container from scrolling the page:\n      disableScroll: true,\n      // Carousel mode (shortcut for carousel specific options):\n      carousel: false,\n      // Allow continuous navigation, moving from last to first\n      // and from first to last slide:\n      continuous: true,\n      // Remove elements outside of the preload range from the DOM:\n      unloadElements: true,\n      // Start with the automatic slideshow:\n      startSlideshow: false,\n      // Delay in milliseconds between slides for the automatic slideshow:\n      slideshowInterval: 5000,\n      // The starting index as integer.\n      // Can also be an object of the given list,\n      // or an equal object with the same url property:\n      index: 0,\n      // The number of elements to load around the current index:\n      preloadRange: 2,\n      // The transition speed between slide changes in milliseconds:\n      transitionSpeed: 400,\n      // The transition speed for automatic slide changes, set to an integer\n      // greater 0 to override the default transition speed:\n      slideshowTransitionSpeed: undefined,\n      // The event object for which the default action will be canceled\n      // on Gallery initialization (e.g. the click event to open the Gallery):\n      event: undefined,\n      // Callback function executed when the Gallery is initialized.\n      // Is called with the gallery instance as \"this\" object:\n      onopen: undefined,\n      // Callback function executed when the Gallery has been initialized\n      // and the initialization transition has been completed.\n      // Is called with the gallery instance as \"this\" object:\n      onopened: undefined,\n      // Callback function executed on slide change.\n      // Is called with the gallery instance as \"this\" object and the\n      // current index and slide as arguments:\n      onslide: undefined,\n      // Callback function executed after the slide change transition.\n      // Is called with the gallery instance as \"this\" object and the\n      // current index and slide as arguments:\n      onslideend: undefined,\n      // Callback function executed on slide content load.\n      // Is called with the gallery instance as \"this\" object and the\n      // slide index and slide element as arguments:\n      onslidecomplete: undefined,\n      // Callback function executed when the Gallery is about to be closed.\n      // Is called with the gallery instance as \"this\" object:\n      onclose: undefined,\n      // Callback function executed when the Gallery has been closed\n      // and the closing transition has been completed.\n      // Is called with the gallery instance as \"this\" object:\n      onclosed: undefined\n    },\n\n    carouselOptions: {\n      hidePageScrollbars: false,\n      toggleControlsOnReturn: false,\n      toggleSlideshowOnSpace: false,\n      enableKeyboardNavigation: false,\n      closeOnEscape: false,\n      closeOnSlideClick: false,\n      closeOnSwipeUpOrDown: false,\n      disableScroll: false,\n      startSlideshow: true\n    },\n\n    console: window.console && typeof window.console.log === 'function'\n      ? window.console\n      : {log: function () {}},\n\n    // Detect touch, transition, transform and background-size support:\n    support: (function (element) {\n      var support = {\n        touch: window.ontouchstart !== undefined ||\n          (window.DocumentTouch && document instanceof DocumentTouch)\n      }\n      var transitions = {\n        webkitTransition: {\n          end: 'webkitTransitionEnd',\n          prefix: '-webkit-'\n        },\n        MozTransition: {\n          end: 'transitionend',\n          prefix: '-moz-'\n        },\n        OTransition: {\n          end: 'otransitionend',\n          prefix: '-o-'\n        },\n        transition: {\n          end: 'transitionend',\n          prefix: ''\n        }\n      }\n      var prop\n      for (prop in transitions) {\n        if (transitions.hasOwnProperty(prop) &&\n          element.style[prop] !== undefined) {\n          support.transition = transitions[prop]\n          support.transition.name = prop\n          break\n        }\n      }\n      function elementTests () {\n        var transition = support.transition\n        var prop\n        var translateZ\n        document.body.appendChild(element)\n        if (transition) {\n          prop = transition.name.slice(0, -9) + 'ransform'\n          if (element.style[prop] !== undefined) {\n            element.style[prop] = 'translateZ(0)'\n            translateZ = window.getComputedStyle(element)\n              .getPropertyValue(transition.prefix + 'transform')\n            support.transform = {\n              prefix: transition.prefix,\n              name: prop,\n              translate: true,\n              translateZ: !!translateZ && translateZ !== 'none'\n            }\n          }\n        }\n        if (element.style.backgroundSize !== undefined) {\n          support.backgroundSize = {}\n          element.style.backgroundSize = 'contain'\n          support.backgroundSize.contain = window\n            .getComputedStyle(element)\n            .getPropertyValue('background-size') === 'contain'\n          element.style.backgroundSize = 'cover'\n          support.backgroundSize.cover = window\n            .getComputedStyle(element)\n            .getPropertyValue('background-size') === 'cover'\n        }\n        document.body.removeChild(element)\n      }\n      if (document.body) {\n        elementTests()\n      } else {\n        $(document).on('DOMContentLoaded', elementTests)\n      }\n      return support\n    // Test element, has to be standard HTML and must not be hidden\n    // for the CSS3 tests using window.getComputedStyle to be applicable:\n    }(document.createElement('div'))),\n\n    requestAnimationFrame: window.requestAnimationFrame ||\n      window.webkitRequestAnimationFrame ||\n      window.mozRequestAnimationFrame,\n\n    initialize: function () {\n      this.initStartIndex()\n      if (this.initWidget() === false) {\n        return false\n      }\n      this.initEventListeners()\n      // Load the slide at the given index:\n      this.onslide(this.index)\n      // Manually trigger the slideend event for the initial slide:\n      this.ontransitionend()\n      // Start the automatic slideshow if applicable:\n      if (this.options.startSlideshow) {\n        this.play()\n      }\n    },\n\n    slide: function (to, speed) {\n      window.clearTimeout(this.timeout)\n      var index = this.index\n      var direction\n      var naturalDirection\n      var diff\n      if (index === to || this.num === 1) {\n        return\n      }\n      if (!speed) {\n        speed = this.options.transitionSpeed\n      }\n      if (this.support.transform) {\n        if (!this.options.continuous) {\n          to = this.circle(to)\n        }\n        // 1: backward, -1: forward:\n        direction = Math.abs(index - to) / (index - to)\n        // Get the actual position of the slide:\n        if (this.options.continuous) {\n          naturalDirection = direction\n          direction = -this.positions[this.circle(to)] / this.slideWidth\n          // If going forward but to < index, use to = slides.length + to\n          // If going backward but to > index, use to = -slides.length + to\n          if (direction !== naturalDirection) {\n            to = -direction * this.num + to\n          }\n        }\n        diff = Math.abs(index - to) - 1\n        // Move all the slides between index and to in the right direction:\n        while (diff) {\n          diff -= 1\n          this.move(\n            this.circle((to > index ? to : index) - diff - 1),\n            this.slideWidth * direction,\n            0\n          )\n        }\n        to = this.circle(to)\n        this.move(index, this.slideWidth * direction, speed)\n        this.move(to, 0, speed)\n        if (this.options.continuous) {\n          this.move(\n            this.circle(to - direction),\n            -(this.slideWidth * direction),\n            0\n          )\n        }\n      } else {\n        to = this.circle(to)\n        this.animate(index * -this.slideWidth, to * -this.slideWidth, speed)\n      }\n      this.onslide(to)\n    },\n\n    getIndex: function () {\n      return this.index\n    },\n\n    getNumber: function () {\n      return this.num\n    },\n\n    prev: function () {\n      if (this.options.continuous || this.index) {\n        this.slide(this.index - 1)\n      }\n    },\n\n    next: function () {\n      if (this.options.continuous || this.index < this.num - 1) {\n        this.slide(this.index + 1)\n      }\n    },\n\n    play: function (time) {\n      var that = this\n      window.clearTimeout(this.timeout)\n      this.interval = time || this.options.slideshowInterval\n      if (this.elements[this.index] > 1) {\n        this.timeout = this.setTimeout(\n          (!this.requestAnimationFrame && this.slide) || function (to, speed) {\n            that.animationFrameId = that.requestAnimationFrame.call(\n              window,\n              function () {\n                that.slide(to, speed)\n              }\n            )\n          },\n          [this.index + 1, this.options.slideshowTransitionSpeed],\n          this.interval\n        )\n      }\n      this.container.addClass(this.options.playingClass)\n    },\n\n    pause: function () {\n      window.clearTimeout(this.timeout)\n      this.interval = null\n      this.container.removeClass(this.options.playingClass)\n    },\n\n    add: function (list) {\n      var i\n      if (!list.concat) {\n        // Make a real array out of the list to add:\n        list = Array.prototype.slice.call(list)\n      }\n      if (!this.list.concat) {\n        // Make a real array out of the Gallery list:\n        this.list = Array.prototype.slice.call(this.list)\n      }\n      this.list = this.list.concat(list)\n      this.num = this.list.length\n      if (this.num > 2 && this.options.continuous === null) {\n        this.options.continuous = true\n        this.container.removeClass(this.options.leftEdgeClass)\n      }\n      this.container\n        .removeClass(this.options.rightEdgeClass)\n        .removeClass(this.options.singleClass)\n      for (i = this.num - list.length; i < this.num; i += 1) {\n        this.addSlide(i)\n        this.positionSlide(i)\n      }\n      this.positions.length = this.num\n      this.initSlides(true)\n    },\n\n    resetSlides: function () {\n      this.slidesContainer.empty()\n      this.unloadAllSlides()\n      this.slides = []\n    },\n\n    handleClose: function () {\n      var options = this.options\n      this.destroyEventListeners()\n      // Cancel the slideshow:\n      this.pause()\n      this.container[0].style.display = 'none'\n      this.container\n        .removeClass(options.displayClass)\n        .removeClass(options.singleClass)\n        .removeClass(options.leftEdgeClass)\n        .removeClass(options.rightEdgeClass)\n      if (options.hidePageScrollbars) {\n        document.body.style.overflow = this.bodyOverflowStyle\n      }\n      if (this.options.clearSlides) {\n        this.resetSlides()\n      }\n      if (this.options.onclosed) {\n        this.options.onclosed.call(this)\n      }\n    },\n\n    close: function () {\n      var that = this\n      function closeHandler (event) {\n        if (event.target === that.container[0]) {\n          that.container.off(\n            that.support.transition.end,\n            closeHandler\n          )\n          that.handleClose()\n        }\n      }\n      if (this.options.onclose) {\n        this.options.onclose.call(this)\n      }\n      if (this.support.transition && this.options.displayTransition) {\n        this.container.on(\n          this.support.transition.end,\n          closeHandler\n        )\n        this.container.removeClass(this.options.displayClass)\n      } else {\n        this.handleClose()\n      }\n    },\n\n    circle: function (index) {\n      // Always return a number inside of the slides index range:\n      return (this.num + (index % this.num)) % this.num\n    },\n\n    move: function (index, dist, speed) {\n      this.translateX(index, dist, speed)\n      this.positions[index] = dist\n    },\n\n    translate: function (index, x, y, speed) {\n      var style = this.slides[index].style\n      var transition = this.support.transition\n      var transform = this.support.transform\n      style[transition.name + 'Duration'] = speed + 'ms'\n      style[transform.name] = 'translate(' + x + 'px, ' + y + 'px)' +\n      (transform.translateZ ? ' translateZ(0)' : '')\n    },\n\n    translateX: function (index, x, speed) {\n      this.translate(index, x, 0, speed)\n    },\n\n    translateY: function (index, y, speed) {\n      this.translate(index, 0, y, speed)\n    },\n\n    animate: function (from, to, speed) {\n      if (!speed) {\n        this.slidesContainer[0].style.left = to + 'px'\n        return\n      }\n      var that = this\n      var start = new Date().getTime()\n      var timer = window.setInterval(function () {\n        var timeElap = new Date().getTime() - start\n        if (timeElap > speed) {\n          that.slidesContainer[0].style.left = to + 'px'\n          that.ontransitionend()\n          window.clearInterval(timer)\n          return\n        }\n        that.slidesContainer[0].style.left = (((to - from) *\n          (Math.floor((timeElap / speed) * 100) / 100)) +\n          from) + 'px'\n      }, 4)\n    },\n\n    preventDefault: function (event) {\n      if (event.preventDefault) {\n        event.preventDefault()\n      } else {\n        event.returnValue = false\n      }\n    },\n\n    stopPropagation: function (event) {\n      if (event.stopPropagation) {\n        event.stopPropagation()\n      } else {\n        event.cancelBubble = true\n      }\n    },\n\n    onresize: function () {\n      this.initSlides(true)\n    },\n\n    onmousedown: function (event) {\n      // Trigger on clicks of the left mouse button only\n      // and exclude video elements:\n      if (event.which && event.which === 1 &&\n        event.target.nodeName !== 'VIDEO') {\n        // Preventing the default mousedown action is required\n        // to make touch emulation work with Firefox:\n        event.preventDefault()\n        ;(event.originalEvent || event).touches = [{\n          pageX: event.pageX,\n          pageY: event.pageY\n        }]\n        this.ontouchstart(event)\n      }\n    },\n\n    onmousemove: function (event) {\n      if (this.touchStart) {\n        (event.originalEvent || event).touches = [{\n          pageX: event.pageX,\n          pageY: event.pageY\n        }]\n        this.ontouchmove(event)\n      }\n    },\n\n    onmouseup: function (event) {\n      if (this.touchStart) {\n        this.ontouchend(event)\n        delete this.touchStart\n      }\n    },\n\n    onmouseout: function (event) {\n      if (this.touchStart) {\n        var target = event.target\n        var related = event.relatedTarget\n        if (!related || (related !== target &&\n          !$.contains(target, related))) {\n          this.onmouseup(event)\n        }\n      }\n    },\n\n    ontouchstart: function (event) {\n      if (this.options.stopTouchEventsPropagation) {\n        this.stopPropagation(event)\n      }\n      // jQuery doesn't copy touch event properties by default,\n      // so we have to access the originalEvent object:\n      var touches = (event.originalEvent || event).touches[0]\n      this.touchStart = {\n        // Remember the initial touch coordinates:\n        x: touches.pageX,\n        y: touches.pageY,\n        // Store the time to determine touch duration:\n        time: Date.now()\n      }\n      // Helper variable to detect scroll movement:\n      this.isScrolling = undefined\n      // Reset delta values:\n      this.touchDelta = {}\n    },\n\n    ontouchmove: function (event) {\n      if (this.options.stopTouchEventsPropagation) {\n        this.stopPropagation(event)\n      }\n      // jQuery doesn't copy touch event properties by default,\n      // so we have to access the originalEvent object:\n      var touches = (event.originalEvent || event).touches[0]\n      var scale = (event.originalEvent || event).scale\n      var index = this.index\n      var touchDeltaX\n      var indices\n      // Ensure this is a one touch swipe and not, e.g. a pinch:\n      if (touches.length > 1 || (scale && scale !== 1)) {\n        return\n      }\n      if (this.options.disableScroll) {\n        event.preventDefault()\n      }\n      // Measure change in x and y coordinates:\n      this.touchDelta = {\n        x: touches.pageX - this.touchStart.x,\n        y: touches.pageY - this.touchStart.y\n      }\n      touchDeltaX = this.touchDelta.x\n      // Detect if this is a vertical scroll movement (run only once per touch):\n      if (this.isScrolling === undefined) {\n        this.isScrolling = this.isScrolling ||\n        Math.abs(touchDeltaX) < Math.abs(this.touchDelta.y)\n      }\n      if (!this.isScrolling) {\n        // Always prevent horizontal scroll:\n        event.preventDefault()\n        // Stop the slideshow:\n        window.clearTimeout(this.timeout)\n        if (this.options.continuous) {\n          indices = [\n            this.circle(index + 1),\n            index,\n            this.circle(index - 1)\n          ]\n        } else {\n          // Increase resistance if first slide and sliding left\n          // or last slide and sliding right:\n          this.touchDelta.x = touchDeltaX =\n            touchDeltaX /\n            (\n            ((!index && touchDeltaX > 0) ||\n            (index === this.num - 1 && touchDeltaX < 0))\n              ? (Math.abs(touchDeltaX) / this.slideWidth + 1)\n              : 1\n          )\n          indices = [index]\n          if (index) {\n            indices.push(index - 1)\n          }\n          if (index < this.num - 1) {\n            indices.unshift(index + 1)\n          }\n        }\n        while (indices.length) {\n          index = indices.pop()\n          this.translateX(index, touchDeltaX + this.positions[index], 0)\n        }\n      } else {\n        this.translateY(index, this.touchDelta.y + this.positions[index], 0)\n      }\n    },\n\n    ontouchend: function (event) {\n      if (this.options.stopTouchEventsPropagation) {\n        this.stopPropagation(event)\n      }\n      var index = this.index\n      var speed = this.options.transitionSpeed\n      var slideWidth = this.slideWidth\n      var isShortDuration = Number(Date.now() - this.touchStart.time) < 250\n      // Determine if slide attempt triggers next/prev slide:\n      var isValidSlide =\n      (isShortDuration && Math.abs(this.touchDelta.x) > 20) ||\n        Math.abs(this.touchDelta.x) > slideWidth / 2\n      // Determine if slide attempt is past start or end:\n      var isPastBounds = (!index && this.touchDelta.x > 0) ||\n        (index === this.num - 1 && this.touchDelta.x < 0)\n      var isValidClose = !isValidSlide && this.options.closeOnSwipeUpOrDown &&\n        ((isShortDuration && Math.abs(this.touchDelta.y) > 20) ||\n        Math.abs(this.touchDelta.y) > this.slideHeight / 2)\n      var direction\n      var indexForward\n      var indexBackward\n      var distanceForward\n      var distanceBackward\n      if (this.options.continuous) {\n        isPastBounds = false\n      }\n      // Determine direction of swipe (true: right, false: left):\n      direction = this.touchDelta.x < 0 ? -1 : 1\n      if (!this.isScrolling) {\n        if (isValidSlide && !isPastBounds) {\n          indexForward = index + direction\n          indexBackward = index - direction\n          distanceForward = slideWidth * direction\n          distanceBackward = -slideWidth * direction\n          if (this.options.continuous) {\n            this.move(this.circle(indexForward), distanceForward, 0)\n            this.move(this.circle(index - 2 * direction), distanceBackward, 0)\n          } else if (indexForward >= 0 &&\n            indexForward < this.num) {\n            this.move(indexForward, distanceForward, 0)\n          }\n          this.move(index, this.positions[index] + distanceForward, speed)\n          this.move(\n            this.circle(indexBackward),\n            this.positions[this.circle(indexBackward)] + distanceForward,\n            speed\n          )\n          index = this.circle(indexBackward)\n          this.onslide(index)\n        } else {\n          // Move back into position\n          if (this.options.continuous) {\n            this.move(this.circle(index - 1), -slideWidth, speed)\n            this.move(index, 0, speed)\n            this.move(this.circle(index + 1), slideWidth, speed)\n          } else {\n            if (index) {\n              this.move(index - 1, -slideWidth, speed)\n            }\n            this.move(index, 0, speed)\n            if (index < this.num - 1) {\n              this.move(index + 1, slideWidth, speed)\n            }\n          }\n        }\n      } else {\n        if (isValidClose) {\n          this.close()\n        } else {\n          // Move back into position\n          this.translateY(index, 0, speed)\n        }\n      }\n    },\n\n    ontouchcancel: function (event) {\n      if (this.touchStart) {\n        this.ontouchend(event)\n        delete this.touchStart\n      }\n    },\n\n    ontransitionend: function (event) {\n      var slide = this.slides[this.index]\n      if (!event || slide === event.target) {\n        if (this.interval) {\n          this.play()\n        }\n        this.setTimeout(\n          this.options.onslideend,\n          [this.index, slide]\n        )\n      }\n    },\n\n    oncomplete: function (event) {\n      var target = event.target || event.srcElement\n      var parent = target && target.parentNode\n      var index\n      if (!target || !parent) {\n        return\n      }\n      index = this.getNodeIndex(parent)\n      $(parent).removeClass(this.options.slideLoadingClass)\n      if (event.type === 'error') {\n        $(parent).addClass(this.options.slideErrorClass)\n        this.elements[index] = 3 // Fail\n      } else {\n        this.elements[index] = 2 // Done\n      }\n      // Fix for IE7's lack of support for percentage max-height:\n      if (target.clientHeight > this.container[0].clientHeight) {\n        target.style.maxHeight = this.container[0].clientHeight\n      }\n      if (this.interval && this.slides[this.index] === parent) {\n        this.play()\n      }\n      this.setTimeout(\n        this.options.onslidecomplete,\n        [index, parent]\n      )\n    },\n\n    onload: function (event) {\n      this.oncomplete(event)\n    },\n\n    onerror: function (event) {\n      this.oncomplete(event)\n    },\n\n    onkeydown: function (event) {\n      switch (event.which || event.keyCode) {\n        case 13: // Return\n          if (this.options.toggleControlsOnReturn) {\n            this.preventDefault(event)\n            this.toggleControls()\n          }\n          break\n        case 27: // Esc\n          if (this.options.closeOnEscape) {\n            this.close()\n            // prevent Esc from closing other things\n            event.stopImmediatePropagation()\n          }\n          break\n        case 32: // Space\n          if (this.options.toggleSlideshowOnSpace) {\n            this.preventDefault(event)\n            this.toggleSlideshow()\n          }\n          break\n        case 37: // Left\n          if (this.options.enableKeyboardNavigation) {\n            this.preventDefault(event)\n            this.prev()\n          }\n          break\n        case 39: // Right\n          if (this.options.enableKeyboardNavigation) {\n            this.preventDefault(event)\n            this.next()\n          }\n          break\n      }\n    },\n\n    handleClick: function (event) {\n      var options = this.options\n      var target = event.target || event.srcElement\n      var parent = target.parentNode\n      function isTarget (className) {\n        return $(target).hasClass(className) ||\n        $(parent).hasClass(className)\n      }\n      if (isTarget(options.toggleClass)) {\n        // Click on \"toggle\" control\n        this.preventDefault(event)\n        this.toggleControls()\n      } else if (isTarget(options.prevClass)) {\n        // Click on \"prev\" control\n        this.preventDefault(event)\n        this.prev()\n      } else if (isTarget(options.nextClass)) {\n        // Click on \"next\" control\n        this.preventDefault(event)\n        this.next()\n      } else if (isTarget(options.closeClass)) {\n        // Click on \"close\" control\n        this.preventDefault(event)\n        this.close()\n      } else if (isTarget(options.playPauseClass)) {\n        // Click on \"play-pause\" control\n        this.preventDefault(event)\n        this.toggleSlideshow()\n      } else if (parent === this.slidesContainer[0]) {\n        // Click on slide background\n        if (options.closeOnSlideClick) {\n          this.preventDefault(event)\n          this.close()\n        } else if (options.toggleControlsOnSlideClick) {\n          this.preventDefault(event)\n          this.toggleControls()\n        }\n      } else if (parent.parentNode &&\n        parent.parentNode === this.slidesContainer[0]) {\n        // Click on displayed element\n        if (options.toggleControlsOnSlideClick) {\n          this.preventDefault(event)\n          this.toggleControls()\n        }\n      }\n    },\n\n    onclick: function (event) {\n      if (this.options.emulateTouchEvents &&\n        this.touchDelta && (Math.abs(this.touchDelta.x) > 20 ||\n        Math.abs(this.touchDelta.y) > 20)) {\n        delete this.touchDelta\n        return\n      }\n      return this.handleClick(event)\n    },\n\n    updateEdgeClasses: function (index) {\n      if (!index) {\n        this.container.addClass(this.options.leftEdgeClass)\n      } else {\n        this.container.removeClass(this.options.leftEdgeClass)\n      }\n      if (index === this.num - 1) {\n        this.container.addClass(this.options.rightEdgeClass)\n      } else {\n        this.container.removeClass(this.options.rightEdgeClass)\n      }\n    },\n\n    handleSlide: function (index) {\n      if (!this.options.continuous) {\n        this.updateEdgeClasses(index)\n      }\n      this.loadElements(index)\n      if (this.options.unloadElements) {\n        this.unloadElements(index)\n      }\n      this.setTitle(index)\n    },\n\n    onslide: function (index) {\n      this.index = index\n      this.handleSlide(index)\n      this.setTimeout(this.options.onslide, [index, this.slides[index]])\n    },\n\n    setTitle: function (index) {\n      var text = this.slides[index].firstChild.title\n      var titleElement = this.titleElement\n      if (titleElement.length) {\n        this.titleElement.empty()\n        if (text) {\n          titleElement[0].appendChild(document.createTextNode(text))\n        }\n      }\n    },\n\n    setTimeout: function (func, args, wait) {\n      var that = this\n      return func && window.setTimeout(function () {\n        func.apply(that, args || [])\n      }, wait || 0)\n    },\n\n    imageFactory: function (obj, callback) {\n      var that = this\n      var img = this.imagePrototype.cloneNode(false)\n      var url = obj\n      var backgroundSize = this.options.stretchImages\n      var called\n      var element\n      var title\n      function callbackWrapper (event) {\n        if (!called) {\n          event = {\n            type: event.type,\n            target: element\n          }\n          if (!element.parentNode) {\n            // Fix for IE7 firing the load event for\n            // cached images before the element could\n            // be added to the DOM:\n            return that.setTimeout(callbackWrapper, [event])\n          }\n          called = true\n          $(img).off('load error', callbackWrapper)\n          if (backgroundSize) {\n            if (event.type === 'load') {\n              element.style.background = 'url(\"' + url +\n                '\") center no-repeat'\n              element.style.backgroundSize = backgroundSize\n            }\n          }\n          callback(event)\n        }\n      }\n      if (typeof url !== 'string') {\n        url = this.getItemProperty(obj, this.options.urlProperty)\n        title = this.getItemProperty(obj, this.options.titleProperty)\n      }\n      if (backgroundSize === true) {\n        backgroundSize = 'contain'\n      }\n      backgroundSize = this.support.backgroundSize &&\n        this.support.backgroundSize[backgroundSize] && backgroundSize\n      if (backgroundSize) {\n        element = this.elementPrototype.cloneNode(false)\n      } else {\n        element = img\n        img.draggable = false\n      }\n      if (title) {\n        element.title = title\n      }\n      $(img).on('load error', callbackWrapper)\n      img.src = url\n      return element\n    },\n\n    createElement: function (obj, callback) {\n      var type = obj && this.getItemProperty(obj, this.options.typeProperty)\n      var factory = (type && this[type.split('/')[0] + 'Factory']) ||\n        this.imageFactory\n      var element = obj && factory.call(this, obj, callback)\n      var srcset = this.getItemProperty(obj, this.options.srcsetProperty)\n      if (!element) {\n        element = this.elementPrototype.cloneNode(false)\n        this.setTimeout(callback, [{\n          type: 'error',\n          target: element\n        }])\n      }\n      if (srcset) {\n        element.setAttribute('srcset', srcset)\n      }\n      $(element).addClass(this.options.slideContentClass)\n      return element\n    },\n\n    loadElement: function (index) {\n      if (!this.elements[index]) {\n        if (this.slides[index].firstChild) {\n          this.elements[index] = $(this.slides[index])\n            .hasClass(this.options.slideErrorClass) ? 3 : 2\n        } else {\n          this.elements[index] = 1 // Loading\n          $(this.slides[index]).addClass(this.options.slideLoadingClass)\n          this.slides[index].appendChild(this.createElement(\n            this.list[index],\n            this.proxyListener\n          ))\n        }\n      }\n    },\n\n    loadElements: function (index) {\n      var limit = Math.min(this.num, this.options.preloadRange * 2 + 1)\n      var j = index\n      var i\n      for (i = 0; i < limit; i += 1) {\n        // First load the current slide element (0),\n        // then the next one (+1),\n        // then the previous one (-2),\n        // then the next after next (+2), etc.:\n        j += i * (i % 2 === 0 ? -1 : 1)\n        // Connect the ends of the list to load slide elements for\n        // continuous navigation:\n        j = this.circle(j)\n        this.loadElement(j)\n      }\n    },\n\n    unloadElements: function (index) {\n      var i,\n        diff\n      for (i in this.elements) {\n        if (this.elements.hasOwnProperty(i)) {\n          diff = Math.abs(index - i)\n          if (diff > this.options.preloadRange &&\n            diff + this.options.preloadRange < this.num) {\n            this.unloadSlide(i)\n            delete this.elements[i]\n          }\n        }\n      }\n    },\n\n    addSlide: function (index) {\n      var slide = this.slidePrototype.cloneNode(false)\n      slide.setAttribute('data-index', index)\n      this.slidesContainer[0].appendChild(slide)\n      this.slides.push(slide)\n    },\n\n    positionSlide: function (index) {\n      var slide = this.slides[index]\n      slide.style.width = this.slideWidth + 'px'\n      if (this.support.transform) {\n        slide.style.left = (index * -this.slideWidth) + 'px'\n        this.move(\n          index, this.index > index\n            ? -this.slideWidth\n            : (this.index < index ? this.slideWidth : 0),\n          0\n        )\n      }\n    },\n\n    initSlides: function (reload) {\n      var clearSlides,\n        i\n      if (!reload) {\n        this.positions = []\n        this.positions.length = this.num\n        this.elements = {}\n        this.imagePrototype = document.createElement('img')\n        this.elementPrototype = document.createElement('div')\n        this.slidePrototype = document.createElement('div')\n        $(this.slidePrototype).addClass(this.options.slideClass)\n        this.slides = this.slidesContainer[0].children\n        clearSlides = this.options.clearSlides ||\n        this.slides.length !== this.num\n      }\n      this.slideWidth = this.container[0].offsetWidth\n      this.slideHeight = this.container[0].offsetHeight\n      this.slidesContainer[0].style.width =\n        (this.num * this.slideWidth) + 'px'\n      if (clearSlides) {\n        this.resetSlides()\n      }\n      for (i = 0; i < this.num; i += 1) {\n        if (clearSlides) {\n          this.addSlide(i)\n        }\n        this.positionSlide(i)\n      }\n      // Reposition the slides before and after the given index:\n      if (this.options.continuous && this.support.transform) {\n        this.move(this.circle(this.index - 1), -this.slideWidth, 0)\n        this.move(this.circle(this.index + 1), this.slideWidth, 0)\n      }\n      if (!this.support.transform) {\n        this.slidesContainer[0].style.left =\n          (this.index * -this.slideWidth) + 'px'\n      }\n    },\n\n    unloadSlide: function (index) {\n      var slide,\n        firstChild\n      slide = this.slides[index]\n      firstChild = slide.firstChild\n      if (firstChild !== null) {\n        slide.removeChild(firstChild)\n      }\n    },\n\n    unloadAllSlides: function () {\n      var i,\n        len\n      for (i = 0, len = this.slides.length; i < len; i++) {\n        this.unloadSlide(i)\n      }\n    },\n\n    toggleControls: function () {\n      var controlsClass = this.options.controlsClass\n      if (this.container.hasClass(controlsClass)) {\n        this.container.removeClass(controlsClass)\n      } else {\n        this.container.addClass(controlsClass)\n      }\n    },\n\n    toggleSlideshow: function () {\n      if (!this.interval) {\n        this.play()\n      } else {\n        this.pause()\n      }\n    },\n\n    getNodeIndex: function (element) {\n      return parseInt(element.getAttribute('data-index'), 10)\n    },\n\n    getNestedProperty: function (obj, property) {\n      property.replace(\n        // Matches native JavaScript notation in a String,\n        // e.g. '[\"doubleQuoteProp\"].dotProp[2]'\n        // eslint-disable-next-line no-useless-escape\n        /\\[(?:'([^']+)'|\"([^\"]+)\"|(\\d+))\\]|(?:(?:^|\\.)([^\\.\\[]+))/g,\n        function (str, singleQuoteProp, doubleQuoteProp, arrayIndex, dotProp) {\n          var prop = dotProp || singleQuoteProp || doubleQuoteProp ||\n            (arrayIndex && parseInt(arrayIndex, 10))\n          if (str && obj) {\n            obj = obj[prop]\n          }\n        }\n      )\n      return obj\n    },\n\n    getDataProperty: function (obj, property) {\n      if (obj.getAttribute) {\n        var prop = obj.getAttribute('data-' +\n          property.replace(/([A-Z])/g, '-$1').toLowerCase())\n        if (typeof prop === 'string') {\n          // eslint-disable-next-line no-useless-escape\n          if (/^(true|false|null|-?\\d+(\\.\\d+)?|\\{[\\s\\S]*\\}|\\[[\\s\\S]*\\])$/\n              .test(prop)) {\n            try {\n              return $.parseJSON(prop)\n            } catch (ignore) {}\n          }\n          return prop\n        }\n      }\n    },\n\n    getItemProperty: function (obj, property) {\n      var prop = obj[property]\n      if (prop === undefined) {\n        prop = this.getDataProperty(obj, property)\n        if (prop === undefined) {\n          prop = this.getNestedProperty(obj, property)\n        }\n      }\n      return prop\n    },\n\n    initStartIndex: function () {\n      var index = this.options.index\n      var urlProperty = this.options.urlProperty\n      var i\n      // Check if the index is given as a list object:\n      if (index && typeof index !== 'number') {\n        for (i = 0; i < this.num; i += 1) {\n          if (this.list[i] === index ||\n            this.getItemProperty(this.list[i], urlProperty) ===\n            this.getItemProperty(index, urlProperty)) {\n            index = i\n            break\n          }\n        }\n      }\n      // Make sure the index is in the list range:\n      this.index = this.circle(parseInt(index, 10) || 0)\n    },\n\n    initEventListeners: function () {\n      var that = this\n      var slidesContainer = this.slidesContainer\n      function proxyListener (event) {\n        var type = that.support.transition &&\n        that.support.transition.end === event.type\n          ? 'transitionend'\n          : event.type\n        that['on' + type](event)\n      }\n      $(window).on('resize', proxyListener)\n      $(document.body).on('keydown', proxyListener)\n      this.container.on('click', proxyListener)\n      if (this.support.touch) {\n        slidesContainer\n          .on('touchstart touchmove touchend touchcancel', proxyListener)\n      } else if (this.options.emulateTouchEvents &&\n        this.support.transition) {\n        slidesContainer\n          .on('mousedown mousemove mouseup mouseout', proxyListener)\n      }\n      if (this.support.transition) {\n        slidesContainer.on(\n          this.support.transition.end,\n          proxyListener\n        )\n      }\n      this.proxyListener = proxyListener\n    },\n\n    destroyEventListeners: function () {\n      var slidesContainer = this.slidesContainer\n      var proxyListener = this.proxyListener\n      $(window).off('resize', proxyListener)\n      $(document.body).off('keydown', proxyListener)\n      this.container.off('click', proxyListener)\n      if (this.support.touch) {\n        slidesContainer\n          .off('touchstart touchmove touchend touchcancel', proxyListener)\n      } else if (this.options.emulateTouchEvents &&\n        this.support.transition) {\n        slidesContainer\n          .off('mousedown mousemove mouseup mouseout', proxyListener)\n      }\n      if (this.support.transition) {\n        slidesContainer.off(\n          this.support.transition.end,\n          proxyListener\n        )\n      }\n    },\n\n    handleOpen: function () {\n      if (this.options.onopened) {\n        this.options.onopened.call(this)\n      }\n    },\n\n    initWidget: function () {\n      var that = this\n      function openHandler (event) {\n        if (event.target === that.container[0]) {\n          that.container.off(\n            that.support.transition.end,\n            openHandler\n          )\n          that.handleOpen()\n        }\n      }\n      this.container = $(this.options.container)\n      if (!this.container.length) {\n        this.console.log(\n          'blueimp Gallery: Widget container not found.',\n          this.options.container\n        )\n        return false\n      }\n      this.slidesContainer = this.container.find(\n        this.options.slidesContainer\n      ).first()\n      if (!this.slidesContainer.length) {\n        this.console.log(\n          'blueimp Gallery: Slides container not found.',\n          this.options.slidesContainer\n        )\n        return false\n      }\n      this.titleElement = this.container.find(\n        this.options.titleElement\n      ).first()\n      if (this.num === 1) {\n        this.container.addClass(this.options.singleClass)\n      }\n      if (this.options.onopen) {\n        this.options.onopen.call(this)\n      }\n      if (this.support.transition && this.options.displayTransition) {\n        this.container.on(\n          this.support.transition.end,\n          openHandler\n        )\n      } else {\n        this.handleOpen()\n      }\n      if (this.options.hidePageScrollbars) {\n        // Hide the page scrollbars:\n        this.bodyOverflowStyle = document.body.style.overflow\n        document.body.style.overflow = 'hidden'\n      }\n      this.container[0].style.display = 'block'\n      this.initSlides()\n      this.container.addClass(this.options.displayClass)\n    },\n\n    initOptions: function (options) {\n      // Create a copy of the prototype options:\n      this.options = $.extend({}, this.options)\n      // Check if carousel mode is enabled:\n      if ((options && options.carousel) ||\n        (this.options.carousel && (!options || options.carousel !== false))) {\n        $.extend(this.options, this.carouselOptions)\n      }\n      // Override any given options:\n      $.extend(this.options, options)\n      if (this.num < 3) {\n        // 1 or 2 slides cannot be displayed continuous,\n        // remember the original option by setting to null instead of false:\n        this.options.continuous = this.options.continuous ? null : false\n      }\n      if (!this.support.transition) {\n        this.options.emulateTouchEvents = false\n      }\n      if (this.options.event) {\n        this.preventDefault(this.options.event)\n      }\n    }\n\n  })\n\n  return Gallery\n}))\n"
  },
  {
    "path": "app_backend/static/plugin/Gallery-2.25.0/js/blueimp-helper.js",
    "content": "/*\n * blueimp helper JS\n * https://github.com/blueimp/Gallery\n *\n * Copyright 2013, Sebastian Tschan\n * https://blueimp.net\n *\n * Licensed under the MIT license:\n * https://opensource.org/licenses/MIT\n */\n\n/* global define, window, document */\n\n;(function () {\n  'use strict'\n\n  function extend (obj1, obj2) {\n    var prop\n    for (prop in obj2) {\n      if (obj2.hasOwnProperty(prop)) {\n        obj1[prop] = obj2[prop]\n      }\n    }\n    return obj1\n  }\n\n  function Helper (query) {\n    if (!this || this.find !== Helper.prototype.find) {\n      // Called as function instead of as constructor,\n      // so we simply return a new instance:\n      return new Helper(query)\n    }\n    this.length = 0\n    if (query) {\n      if (typeof query === 'string') {\n        query = this.find(query)\n      }\n      if (query.nodeType || query === query.window) {\n        // Single HTML element\n        this.length = 1\n        this[0] = query\n      } else {\n        // HTML element collection\n        var i = query.length\n        this.length = i\n        while (i) {\n          i -= 1\n          this[i] = query[i]\n        }\n      }\n    }\n  }\n\n  Helper.extend = extend\n\n  Helper.contains = function (container, element) {\n    do {\n      element = element.parentNode\n      if (element === container) {\n        return true\n      }\n    } while (element)\n    return false\n  }\n\n  Helper.parseJSON = function (string) {\n    return window.JSON && JSON.parse(string)\n  }\n\n  extend(Helper.prototype, {\n    find: function (query) {\n      var container = this[0] || document\n      if (typeof query === 'string') {\n        if (container.querySelectorAll) {\n          query = container.querySelectorAll(query)\n        } else if (query.charAt(0) === '#') {\n          query = container.getElementById(query.slice(1))\n        } else {\n          query = container.getElementsByTagName(query)\n        }\n      }\n      return new Helper(query)\n    },\n\n    hasClass: function (className) {\n      if (!this[0]) {\n        return false\n      }\n      return new RegExp('(^|\\\\s+)' + className +\n        '(\\\\s+|$)').test(this[0].className)\n    },\n\n    addClass: function (className) {\n      var i = this.length\n      var element\n      while (i) {\n        i -= 1\n        element = this[i]\n        if (!element.className) {\n          element.className = className\n          return this\n        }\n        if (this.hasClass(className)) {\n          return this\n        }\n        element.className += ' ' + className\n      }\n      return this\n    },\n\n    removeClass: function (className) {\n      var regexp = new RegExp('(^|\\\\s+)' + className + '(\\\\s+|$)')\n      var i = this.length\n      var element\n      while (i) {\n        i -= 1\n        element = this[i]\n        element.className = element.className.replace(regexp, ' ')\n      }\n      return this\n    },\n\n    on: function (eventName, handler) {\n      var eventNames = eventName.split(/\\s+/)\n      var i\n      var element\n      while (eventNames.length) {\n        eventName = eventNames.shift()\n        i = this.length\n        while (i) {\n          i -= 1\n          element = this[i]\n          if (element.addEventListener) {\n            element.addEventListener(eventName, handler, false)\n          } else if (element.attachEvent) {\n            element.attachEvent('on' + eventName, handler)\n          }\n        }\n      }\n      return this\n    },\n\n    off: function (eventName, handler) {\n      var eventNames = eventName.split(/\\s+/)\n      var i\n      var element\n      while (eventNames.length) {\n        eventName = eventNames.shift()\n        i = this.length\n        while (i) {\n          i -= 1\n          element = this[i]\n          if (element.removeEventListener) {\n            element.removeEventListener(eventName, handler, false)\n          } else if (element.detachEvent) {\n            element.detachEvent('on' + eventName, handler)\n          }\n        }\n      }\n      return this\n    },\n\n    empty: function () {\n      var i = this.length\n      var element\n      while (i) {\n        i -= 1\n        element = this[i]\n        while (element.hasChildNodes()) {\n          element.removeChild(element.lastChild)\n        }\n      }\n      return this\n    },\n\n    first: function () {\n      return new Helper(this[0])\n    }\n\n  })\n\n  if (typeof define === 'function' && define.amd) {\n    define(function () {\n      return Helper\n    })\n  } else {\n    window.blueimp = window.blueimp || {}\n    window.blueimp.helper = Helper\n  }\n}())\n"
  },
  {
    "path": "app_backend/static/plugin/Gallery-2.25.0/js/demo/demo.js",
    "content": "/*\n * blueimp Gallery Demo JS\n * https://github.com/blueimp/Gallery\n *\n * Copyright 2013, Sebastian Tschan\n * https://blueimp.net\n *\n * Licensed under the MIT license:\n * https://opensource.org/licenses/MIT\n */\n\n/* global blueimp, $ */\n\n$(function () {\n  'use strict'\n\n  // Load demo images from flickr:\n  $.ajax({\n    url: 'https://api.flickr.com/services/rest/',\n    data: {\n      format: 'json',\n      method: 'flickr.interestingness.getList',\n      api_key: '7617adae70159d09ba78cfec73c13be3' // jshint ignore:line\n    },\n    dataType: 'jsonp',\n    jsonp: 'jsoncallback'\n  }).done(function (result) {\n    var carouselLinks = []\n    var linksContainer = $('#links')\n    var baseUrl\n    // Add the demo images as links with thumbnails to the page:\n    $.each(result.photos.photo, function (index, photo) {\n      baseUrl = 'https://farm' + photo.farm + '.static.flickr.com/' +\n      photo.server + '/' + photo.id + '_' + photo.secret\n      $('<a/>')\n        .append($('<img>').prop('src', baseUrl + '_s.jpg'))\n        .prop('href', baseUrl + '_b.jpg')\n        .prop('title', photo.title)\n        .attr('data-gallery', '')\n        .appendTo(linksContainer)\n      carouselLinks.push({\n        href: baseUrl + '_c.jpg',\n        title: photo.title\n      })\n    })\n    // Initialize the Gallery as image carousel:\n    blueimp.Gallery(carouselLinks, {\n      container: '#blueimp-image-carousel',\n      carousel: true\n    })\n  })\n\n  // Initialize the Gallery as video carousel:\n  blueimp.Gallery([\n    {\n      title: 'Sintel',\n      href: 'https://archive.org/download/Sintel/' +\n        'sintel-2048-surround.mp4',\n      type: 'video/mp4',\n      poster: 'https://i.imgur.com/MUSw4Zu.jpg'\n    },\n    {\n      title: 'Big Buck Bunny',\n      href: 'https://upload.wikimedia.org/wikipedia/commons/c/c0/' +\n        'Big_Buck_Bunny_4K.webm',\n      type: 'video/webm',\n      poster: 'https://upload.wikimedia.org/wikipedia/commons/thumb/c/c0/' +\n        'Big_Buck_Bunny_4K.webm/4000px--Big_Buck_Bunny_4K.webm.jpg'\n    },\n    {\n      title: 'Elephants Dream',\n      href: 'https://upload.wikimedia.org/wikipedia/commons/8/83/' +\n        'Elephants_Dream_%28high_quality%29.ogv',\n      type: 'video/ogg',\n      poster: 'https://upload.wikimedia.org/wikipedia/commons/thumb/9/90/' +\n        'Elephants_Dream_s1_proog.jpg/800px-Elephants_Dream_s1_proog.jpg'\n    },\n    {\n      title: 'LES TWINS - An Industry Ahead',\n      type: 'text/html',\n      youtube: 'zi4CIXpx7Bg'\n    },\n    {\n      title: 'KN1GHT - Last Moon',\n      type: 'text/html',\n      vimeo: '73686146',\n      poster: 'https://secure-a.vimeocdn.com/ts/448/835/448835699_960.jpg'\n    }\n  ], {\n    container: '#blueimp-video-carousel',\n    carousel: true\n  })\n})\n"
  },
  {
    "path": "app_backend/static/plugin/Gallery-2.25.0/js/jquery.blueimp-gallery.js",
    "content": "/*\n * blueimp Gallery jQuery plugin\n * https://github.com/blueimp/Gallery\n *\n * Copyright 2013, Sebastian Tschan\n * https://blueimp.net\n *\n * Licensed under the MIT license:\n * https://opensource.org/licenses/MIT\n */\n\n/* global define, window, document */\n\n;(function (factory) {\n  'use strict'\n  if (typeof define === 'function' && define.amd) {\n    define([\n      'jquery',\n      './blueimp-gallery'\n    ], factory)\n  } else {\n    factory(\n      window.jQuery,\n      window.blueimp.Gallery\n    )\n  }\n}(function ($, Gallery) {\n  'use strict'\n\n  // Global click handler to open links with data-gallery attribute\n  // in the Gallery lightbox:\n  $(document).on('click', '[data-gallery]', function (event) {\n    // Get the container id from the data-gallery attribute:\n    var id = $(this).data('gallery')\n    var widget = $(id)\n    var container = (widget.length && widget) ||\n          $(Gallery.prototype.options.container)\n    var callbacks = {\n      onopen: function () {\n        container\n          .data('gallery', this)\n          .trigger('open')\n      },\n      onopened: function () {\n        container.trigger('opened')\n      },\n      onslide: function () {\n        container.trigger('slide', arguments)\n      },\n      onslideend: function () {\n        container.trigger('slideend', arguments)\n      },\n      onslidecomplete: function () {\n        container.trigger('slidecomplete', arguments)\n      },\n      onclose: function () {\n        container.trigger('close')\n      },\n      onclosed: function () {\n        container\n          .trigger('closed')\n          .removeData('gallery')\n      }\n    }\n    var options = $.extend(\n      // Retrieve custom options from data-attributes\n      // on the Gallery widget:\n      container.data(),\n      {\n        container: container[0],\n        index: this,\n        event: event\n      },\n      callbacks\n    )\n    // Select all links with the same data-gallery attribute:\n    var links = $('[data-gallery=\"' + id + '\"]')\n    if (options.filter) {\n      links = links.filter(options.filter)\n    }\n    return new Gallery(links, options)\n  })\n}))\n"
  },
  {
    "path": "app_backend/static/plugin/Gallery-2.25.0/js/vendor/jquery.js",
    "content": "/*!\n * jQuery JavaScript Library v1.11.3\n * http://jquery.com/\n *\n * Includes Sizzle.js\n * http://sizzlejs.com/\n *\n * Copyright 2005, 2014 jQuery Foundation, Inc. and other contributors\n * Released under the MIT license\n * http://jquery.org/license\n *\n * Date: 2015-04-28T16:19Z\n */\n\n(function( global, factory ) {\n\n\tif ( typeof module === \"object\" && typeof module.exports === \"object\" ) {\n\t\t// For CommonJS and CommonJS-like environments where a proper window is present,\n\t\t// execute the factory and get jQuery\n\t\t// For environments that do not inherently posses a window with a document\n\t\t// (such as Node.js), expose a jQuery-making factory as module.exports\n\t\t// This accentuates the need for the creation of a real window\n\t\t// e.g. var jQuery = require(\"jquery\")(window);\n\t\t// See ticket #14549 for more info\n\t\tmodule.exports = global.document ?\n\t\t\tfactory( global, true ) :\n\t\t\tfunction( w ) {\n\t\t\t\tif ( !w.document ) {\n\t\t\t\t\tthrow new Error( \"jQuery requires a window with a document\" );\n\t\t\t\t}\n\t\t\t\treturn factory( w );\n\t\t\t};\n\t} else {\n\t\tfactory( global );\n\t}\n\n// Pass this if window is not defined yet\n}(typeof window !== \"undefined\" ? window : this, function( window, noGlobal ) {\n\n// Can't do this because several apps including ASP.NET trace\n// the stack via arguments.caller.callee and Firefox dies if\n// you try to trace through \"use strict\" call chains. (#13335)\n// Support: Firefox 18+\n//\n\nvar deletedIds = [];\n\nvar slice = deletedIds.slice;\n\nvar concat = deletedIds.concat;\n\nvar push = deletedIds.push;\n\nvar indexOf = deletedIds.indexOf;\n\nvar class2type = {};\n\nvar toString = class2type.toString;\n\nvar hasOwn = class2type.hasOwnProperty;\n\nvar support = {};\n\n\n\nvar\n\tversion = \"1.11.3\",\n\n\t// Define a local copy of jQuery\n\tjQuery = function( selector, context ) {\n\t\t// The jQuery object is actually just the init constructor 'enhanced'\n\t\t// Need init if jQuery is called (just allow error to be thrown if not included)\n\t\treturn new jQuery.fn.init( selector, context );\n\t},\n\n\t// Support: Android<4.1, IE<9\n\t// Make sure we trim BOM and NBSP\n\trtrim = /^[\\s\\uFEFF\\xA0]+|[\\s\\uFEFF\\xA0]+$/g,\n\n\t// Matches dashed string for camelizing\n\trmsPrefix = /^-ms-/,\n\trdashAlpha = /-([\\da-z])/gi,\n\n\t// Used by jQuery.camelCase as callback to replace()\n\tfcamelCase = function( all, letter ) {\n\t\treturn letter.toUpperCase();\n\t};\n\njQuery.fn = jQuery.prototype = {\n\t// The current version of jQuery being used\n\tjquery: version,\n\n\tconstructor: jQuery,\n\n\t// Start with an empty selector\n\tselector: \"\",\n\n\t// The default length of a jQuery object is 0\n\tlength: 0,\n\n\ttoArray: function() {\n\t\treturn slice.call( this );\n\t},\n\n\t// Get the Nth element in the matched element set OR\n\t// Get the whole matched element set as a clean array\n\tget: function( num ) {\n\t\treturn num != null ?\n\n\t\t\t// Return just the one element from the set\n\t\t\t( num < 0 ? this[ num + this.length ] : this[ num ] ) :\n\n\t\t\t// Return all the elements in a clean array\n\t\t\tslice.call( this );\n\t},\n\n\t// Take an array of elements and push it onto the stack\n\t// (returning the new matched element set)\n\tpushStack: function( elems ) {\n\n\t\t// Build a new jQuery matched element set\n\t\tvar ret = jQuery.merge( this.constructor(), elems );\n\n\t\t// Add the old object onto the stack (as a reference)\n\t\tret.prevObject = this;\n\t\tret.context = this.context;\n\n\t\t// Return the newly-formed element set\n\t\treturn ret;\n\t},\n\n\t// Execute a callback for every element in the matched set.\n\t// (You can seed the arguments with an array of args, but this is\n\t// only used internally.)\n\teach: function( callback, args ) {\n\t\treturn jQuery.each( this, callback, args );\n\t},\n\n\tmap: function( callback ) {\n\t\treturn this.pushStack( jQuery.map(this, function( elem, i ) {\n\t\t\treturn callback.call( elem, i, elem );\n\t\t}));\n\t},\n\n\tslice: function() {\n\t\treturn this.pushStack( slice.apply( this, arguments ) );\n\t},\n\n\tfirst: function() {\n\t\treturn this.eq( 0 );\n\t},\n\n\tlast: function() {\n\t\treturn this.eq( -1 );\n\t},\n\n\teq: function( i ) {\n\t\tvar len = this.length,\n\t\t\tj = +i + ( i < 0 ? len : 0 );\n\t\treturn this.pushStack( j >= 0 && j < len ? [ this[j] ] : [] );\n\t},\n\n\tend: function() {\n\t\treturn this.prevObject || this.constructor(null);\n\t},\n\n\t// For internal use only.\n\t// Behaves like an Array's method, not like a jQuery method.\n\tpush: push,\n\tsort: deletedIds.sort,\n\tsplice: deletedIds.splice\n};\n\njQuery.extend = jQuery.fn.extend = function() {\n\tvar src, copyIsArray, copy, name, options, clone,\n\t\ttarget = arguments[0] || {},\n\t\ti = 1,\n\t\tlength = arguments.length,\n\t\tdeep = false;\n\n\t// Handle a deep copy situation\n\tif ( typeof target === \"boolean\" ) {\n\t\tdeep = target;\n\n\t\t// skip the boolean and the target\n\t\ttarget = arguments[ i ] || {};\n\t\ti++;\n\t}\n\n\t// Handle case when target is a string or something (possible in deep copy)\n\tif ( typeof target !== \"object\" && !jQuery.isFunction(target) ) {\n\t\ttarget = {};\n\t}\n\n\t// extend jQuery itself if only one argument is passed\n\tif ( i === length ) {\n\t\ttarget = this;\n\t\ti--;\n\t}\n\n\tfor ( ; i < length; i++ ) {\n\t\t// Only deal with non-null/undefined values\n\t\tif ( (options = arguments[ i ]) != null ) {\n\t\t\t// Extend the base object\n\t\t\tfor ( name in options ) {\n\t\t\t\tsrc = target[ name ];\n\t\t\t\tcopy = options[ name ];\n\n\t\t\t\t// Prevent never-ending loop\n\t\t\t\tif ( target === copy ) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\t// Recurse if we're merging plain objects or arrays\n\t\t\t\tif ( deep && copy && ( jQuery.isPlainObject(copy) || (copyIsArray = jQuery.isArray(copy)) ) ) {\n\t\t\t\t\tif ( copyIsArray ) {\n\t\t\t\t\t\tcopyIsArray = false;\n\t\t\t\t\t\tclone = src && jQuery.isArray(src) ? src : [];\n\n\t\t\t\t\t} else {\n\t\t\t\t\t\tclone = src && jQuery.isPlainObject(src) ? src : {};\n\t\t\t\t\t}\n\n\t\t\t\t\t// Never move original objects, clone them\n\t\t\t\t\ttarget[ name ] = jQuery.extend( deep, clone, copy );\n\n\t\t\t\t// Don't bring in undefined values\n\t\t\t\t} else if ( copy !== undefined ) {\n\t\t\t\t\ttarget[ name ] = copy;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t// Return the modified object\n\treturn target;\n};\n\njQuery.extend({\n\t// Unique for each copy of jQuery on the page\n\texpando: \"jQuery\" + ( version + Math.random() ).replace( /\\D/g, \"\" ),\n\n\t// Assume jQuery is ready without the ready module\n\tisReady: true,\n\n\terror: function( msg ) {\n\t\tthrow new Error( msg );\n\t},\n\n\tnoop: function() {},\n\n\t// See test/unit/core.js for details concerning isFunction.\n\t// Since version 1.3, DOM methods and functions like alert\n\t// aren't supported. They return false on IE (#2968).\n\tisFunction: function( obj ) {\n\t\treturn jQuery.type(obj) === \"function\";\n\t},\n\n\tisArray: Array.isArray || function( obj ) {\n\t\treturn jQuery.type(obj) === \"array\";\n\t},\n\n\tisWindow: function( obj ) {\n\t\t/* jshint eqeqeq: false */\n\t\treturn obj != null && obj == obj.window;\n\t},\n\n\tisNumeric: function( obj ) {\n\t\t// parseFloat NaNs numeric-cast false positives (null|true|false|\"\")\n\t\t// ...but misinterprets leading-number strings, particularly hex literals (\"0x...\")\n\t\t// subtraction forces infinities to NaN\n\t\t// adding 1 corrects loss of precision from parseFloat (#15100)\n\t\treturn !jQuery.isArray( obj ) && (obj - parseFloat( obj ) + 1) >= 0;\n\t},\n\n\tisEmptyObject: function( obj ) {\n\t\tvar name;\n\t\tfor ( name in obj ) {\n\t\t\treturn false;\n\t\t}\n\t\treturn true;\n\t},\n\n\tisPlainObject: function( obj ) {\n\t\tvar key;\n\n\t\t// Must be an Object.\n\t\t// Because of IE, we also have to check the presence of the constructor property.\n\t\t// Make sure that DOM nodes and window objects don't pass through, as well\n\t\tif ( !obj || jQuery.type(obj) !== \"object\" || obj.nodeType || jQuery.isWindow( obj ) ) {\n\t\t\treturn false;\n\t\t}\n\n\t\ttry {\n\t\t\t// Not own constructor property must be Object\n\t\t\tif ( obj.constructor &&\n\t\t\t\t!hasOwn.call(obj, \"constructor\") &&\n\t\t\t\t!hasOwn.call(obj.constructor.prototype, \"isPrototypeOf\") ) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t} catch ( e ) {\n\t\t\t// IE8,9 Will throw exceptions on certain host objects #9897\n\t\t\treturn false;\n\t\t}\n\n\t\t// Support: IE<9\n\t\t// Handle iteration over inherited properties before own properties.\n\t\tif ( support.ownLast ) {\n\t\t\tfor ( key in obj ) {\n\t\t\t\treturn hasOwn.call( obj, key );\n\t\t\t}\n\t\t}\n\n\t\t// Own properties are enumerated firstly, so to speed up,\n\t\t// if last one is own, then all properties are own.\n\t\tfor ( key in obj ) {}\n\n\t\treturn key === undefined || hasOwn.call( obj, key );\n\t},\n\n\ttype: function( obj ) {\n\t\tif ( obj == null ) {\n\t\t\treturn obj + \"\";\n\t\t}\n\t\treturn typeof obj === \"object\" || typeof obj === \"function\" ?\n\t\t\tclass2type[ toString.call(obj) ] || \"object\" :\n\t\t\ttypeof obj;\n\t},\n\n\t// Evaluates a script in a global context\n\t// Workarounds based on findings by Jim Driscoll\n\t// http://weblogs.java.net/blog/driscoll/archive/2009/09/08/eval-javascript-global-context\n\tglobalEval: function( data ) {\n\t\tif ( data && jQuery.trim( data ) ) {\n\t\t\t// We use execScript on Internet Explorer\n\t\t\t// We use an anonymous function so that context is window\n\t\t\t// rather than jQuery in Firefox\n\t\t\t( window.execScript || function( data ) {\n\t\t\t\twindow[ \"eval\" ].call( window, data );\n\t\t\t} )( data );\n\t\t}\n\t},\n\n\t// Convert dashed to camelCase; used by the css and data modules\n\t// Microsoft forgot to hump their vendor prefix (#9572)\n\tcamelCase: function( string ) {\n\t\treturn string.replace( rmsPrefix, \"ms-\" ).replace( rdashAlpha, fcamelCase );\n\t},\n\n\tnodeName: function( elem, name ) {\n\t\treturn elem.nodeName && elem.nodeName.toLowerCase() === name.toLowerCase();\n\t},\n\n\t// args is for internal usage only\n\teach: function( obj, callback, args ) {\n\t\tvar value,\n\t\t\ti = 0,\n\t\t\tlength = obj.length,\n\t\t\tisArray = isArraylike( obj );\n\n\t\tif ( args ) {\n\t\t\tif ( isArray ) {\n\t\t\t\tfor ( ; i < length; i++ ) {\n\t\t\t\t\tvalue = callback.apply( obj[ i ], args );\n\n\t\t\t\t\tif ( value === false ) {\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tfor ( i in obj ) {\n\t\t\t\t\tvalue = callback.apply( obj[ i ], args );\n\n\t\t\t\t\tif ( value === false ) {\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t// A special, fast, case for the most common use of each\n\t\t} else {\n\t\t\tif ( isArray ) {\n\t\t\t\tfor ( ; i < length; i++ ) {\n\t\t\t\t\tvalue = callback.call( obj[ i ], i, obj[ i ] );\n\n\t\t\t\t\tif ( value === false ) {\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tfor ( i in obj ) {\n\t\t\t\t\tvalue = callback.call( obj[ i ], i, obj[ i ] );\n\n\t\t\t\t\tif ( value === false ) {\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn obj;\n\t},\n\n\t// Support: Android<4.1, IE<9\n\ttrim: function( text ) {\n\t\treturn text == null ?\n\t\t\t\"\" :\n\t\t\t( text + \"\" ).replace( rtrim, \"\" );\n\t},\n\n\t// results is for internal usage only\n\tmakeArray: function( arr, results ) {\n\t\tvar ret = results || [];\n\n\t\tif ( arr != null ) {\n\t\t\tif ( isArraylike( Object(arr) ) ) {\n\t\t\t\tjQuery.merge( ret,\n\t\t\t\t\ttypeof arr === \"string\" ?\n\t\t\t\t\t[ arr ] : arr\n\t\t\t\t);\n\t\t\t} else {\n\t\t\t\tpush.call( ret, arr );\n\t\t\t}\n\t\t}\n\n\t\treturn ret;\n\t},\n\n\tinArray: function( elem, arr, i ) {\n\t\tvar len;\n\n\t\tif ( arr ) {\n\t\t\tif ( indexOf ) {\n\t\t\t\treturn indexOf.call( arr, elem, i );\n\t\t\t}\n\n\t\t\tlen = arr.length;\n\t\t\ti = i ? i < 0 ? Math.max( 0, len + i ) : i : 0;\n\n\t\t\tfor ( ; i < len; i++ ) {\n\t\t\t\t// Skip accessing in sparse arrays\n\t\t\t\tif ( i in arr && arr[ i ] === elem ) {\n\t\t\t\t\treturn i;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn -1;\n\t},\n\n\tmerge: function( first, second ) {\n\t\tvar len = +second.length,\n\t\t\tj = 0,\n\t\t\ti = first.length;\n\n\t\twhile ( j < len ) {\n\t\t\tfirst[ i++ ] = second[ j++ ];\n\t\t}\n\n\t\t// Support: IE<9\n\t\t// Workaround casting of .length to NaN on otherwise arraylike objects (e.g., NodeLists)\n\t\tif ( len !== len ) {\n\t\t\twhile ( second[j] !== undefined ) {\n\t\t\t\tfirst[ i++ ] = second[ j++ ];\n\t\t\t}\n\t\t}\n\n\t\tfirst.length = i;\n\n\t\treturn first;\n\t},\n\n\tgrep: function( elems, callback, invert ) {\n\t\tvar callbackInverse,\n\t\t\tmatches = [],\n\t\t\ti = 0,\n\t\t\tlength = elems.length,\n\t\t\tcallbackExpect = !invert;\n\n\t\t// Go through the array, only saving the items\n\t\t// that pass the validator function\n\t\tfor ( ; i < length; i++ ) {\n\t\t\tcallbackInverse = !callback( elems[ i ], i );\n\t\t\tif ( callbackInverse !== callbackExpect ) {\n\t\t\t\tmatches.push( elems[ i ] );\n\t\t\t}\n\t\t}\n\n\t\treturn matches;\n\t},\n\n\t// arg is for internal usage only\n\tmap: function( elems, callback, arg ) {\n\t\tvar value,\n\t\t\ti = 0,\n\t\t\tlength = elems.length,\n\t\t\tisArray = isArraylike( elems ),\n\t\t\tret = [];\n\n\t\t// Go through the array, translating each of the items to their new values\n\t\tif ( isArray ) {\n\t\t\tfor ( ; i < length; i++ ) {\n\t\t\t\tvalue = callback( elems[ i ], i, arg );\n\n\t\t\t\tif ( value != null ) {\n\t\t\t\t\tret.push( value );\n\t\t\t\t}\n\t\t\t}\n\n\t\t// Go through every key on the object,\n\t\t} else {\n\t\t\tfor ( i in elems ) {\n\t\t\t\tvalue = callback( elems[ i ], i, arg );\n\n\t\t\t\tif ( value != null ) {\n\t\t\t\t\tret.push( value );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Flatten any nested arrays\n\t\treturn concat.apply( [], ret );\n\t},\n\n\t// A global GUID counter for objects\n\tguid: 1,\n\n\t// Bind a function to a context, optionally partially applying any\n\t// arguments.\n\tproxy: function( fn, context ) {\n\t\tvar args, proxy, tmp;\n\n\t\tif ( typeof context === \"string\" ) {\n\t\t\ttmp = fn[ context ];\n\t\t\tcontext = fn;\n\t\t\tfn = tmp;\n\t\t}\n\n\t\t// Quick check to determine if target is callable, in the spec\n\t\t// this throws a TypeError, but we will just return undefined.\n\t\tif ( !jQuery.isFunction( fn ) ) {\n\t\t\treturn undefined;\n\t\t}\n\n\t\t// Simulated bind\n\t\targs = slice.call( arguments, 2 );\n\t\tproxy = function() {\n\t\t\treturn fn.apply( context || this, args.concat( slice.call( arguments ) ) );\n\t\t};\n\n\t\t// Set the guid of unique handler to the same of original handler, so it can be removed\n\t\tproxy.guid = fn.guid = fn.guid || jQuery.guid++;\n\n\t\treturn proxy;\n\t},\n\n\tnow: function() {\n\t\treturn +( new Date() );\n\t},\n\n\t// jQuery.support is not used in Core but other projects attach their\n\t// properties to it so it needs to exist.\n\tsupport: support\n});\n\n// Populate the class2type map\njQuery.each(\"Boolean Number String Function Array Date RegExp Object Error\".split(\" \"), function(i, name) {\n\tclass2type[ \"[object \" + name + \"]\" ] = name.toLowerCase();\n});\n\nfunction isArraylike( obj ) {\n\n\t// Support: iOS 8.2 (not reproducible in simulator)\n\t// `in` check used to prevent JIT error (gh-2145)\n\t// hasOwn isn't used here due to false negatives\n\t// regarding Nodelist length in IE\n\tvar length = \"length\" in obj && obj.length,\n\t\ttype = jQuery.type( obj );\n\n\tif ( type === \"function\" || jQuery.isWindow( obj ) ) {\n\t\treturn false;\n\t}\n\n\tif ( obj.nodeType === 1 && length ) {\n\t\treturn true;\n\t}\n\n\treturn type === \"array\" || length === 0 ||\n\t\ttypeof length === \"number\" && length > 0 && ( length - 1 ) in obj;\n}\nvar Sizzle =\n/*!\n * Sizzle CSS Selector Engine v2.2.0-pre\n * http://sizzlejs.com/\n *\n * Copyright 2008, 2014 jQuery Foundation, Inc. and other contributors\n * Released under the MIT license\n * http://jquery.org/license\n *\n * Date: 2014-12-16\n */\n(function( window ) {\n\nvar i,\n\tsupport,\n\tExpr,\n\tgetText,\n\tisXML,\n\ttokenize,\n\tcompile,\n\tselect,\n\toutermostContext,\n\tsortInput,\n\thasDuplicate,\n\n\t// Local document vars\n\tsetDocument,\n\tdocument,\n\tdocElem,\n\tdocumentIsHTML,\n\trbuggyQSA,\n\trbuggyMatches,\n\tmatches,\n\tcontains,\n\n\t// Instance-specific data\n\texpando = \"sizzle\" + 1 * new Date(),\n\tpreferredDoc = window.document,\n\tdirruns = 0,\n\tdone = 0,\n\tclassCache = createCache(),\n\ttokenCache = createCache(),\n\tcompilerCache = createCache(),\n\tsortOrder = function( a, b ) {\n\t\tif ( a === b ) {\n\t\t\thasDuplicate = true;\n\t\t}\n\t\treturn 0;\n\t},\n\n\t// General-purpose constants\n\tMAX_NEGATIVE = 1 << 31,\n\n\t// Instance methods\n\thasOwn = ({}).hasOwnProperty,\n\tarr = [],\n\tpop = arr.pop,\n\tpush_native = arr.push,\n\tpush = arr.push,\n\tslice = arr.slice,\n\t// Use a stripped-down indexOf as it's faster than native\n\t// http://jsperf.com/thor-indexof-vs-for/5\n\tindexOf = function( list, elem ) {\n\t\tvar i = 0,\n\t\t\tlen = list.length;\n\t\tfor ( ; i < len; i++ ) {\n\t\t\tif ( list[i] === elem ) {\n\t\t\t\treturn i;\n\t\t\t}\n\t\t}\n\t\treturn -1;\n\t},\n\n\tbooleans = \"checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped\",\n\n\t// Regular expressions\n\n\t// Whitespace characters http://www.w3.org/TR/css3-selectors/#whitespace\n\twhitespace = \"[\\\\x20\\\\t\\\\r\\\\n\\\\f]\",\n\t// http://www.w3.org/TR/css3-syntax/#characters\n\tcharacterEncoding = \"(?:\\\\\\\\.|[\\\\w-]|[^\\\\x00-\\\\xa0])+\",\n\n\t// Loosely modeled on CSS identifier characters\n\t// An unquoted value should be a CSS identifier http://www.w3.org/TR/css3-selectors/#attribute-selectors\n\t// Proper syntax: http://www.w3.org/TR/CSS21/syndata.html#value-def-identifier\n\tidentifier = characterEncoding.replace( \"w\", \"w#\" ),\n\n\t// Attribute selectors: http://www.w3.org/TR/selectors/#attribute-selectors\n\tattributes = \"\\\\[\" + whitespace + \"*(\" + characterEncoding + \")(?:\" + whitespace +\n\t\t// Operator (capture 2)\n\t\t\"*([*^$|!~]?=)\" + whitespace +\n\t\t// \"Attribute values must be CSS identifiers [capture 5] or strings [capture 3 or capture 4]\"\n\t\t\"*(?:'((?:\\\\\\\\.|[^\\\\\\\\'])*)'|\\\"((?:\\\\\\\\.|[^\\\\\\\\\\\"])*)\\\"|(\" + identifier + \"))|)\" + whitespace +\n\t\t\"*\\\\]\",\n\n\tpseudos = \":(\" + characterEncoding + \")(?:\\\\((\" +\n\t\t// To reduce the number of selectors needing tokenize in the preFilter, prefer arguments:\n\t\t// 1. quoted (capture 3; capture 4 or capture 5)\n\t\t\"('((?:\\\\\\\\.|[^\\\\\\\\'])*)'|\\\"((?:\\\\\\\\.|[^\\\\\\\\\\\"])*)\\\")|\" +\n\t\t// 2. simple (capture 6)\n\t\t\"((?:\\\\\\\\.|[^\\\\\\\\()[\\\\]]|\" + attributes + \")*)|\" +\n\t\t// 3. anything else (capture 2)\n\t\t\".*\" +\n\t\t\")\\\\)|)\",\n\n\t// Leading and non-escaped trailing whitespace, capturing some non-whitespace characters preceding the latter\n\trwhitespace = new RegExp( whitespace + \"+\", \"g\" ),\n\trtrim = new RegExp( \"^\" + whitespace + \"+|((?:^|[^\\\\\\\\])(?:\\\\\\\\.)*)\" + whitespace + \"+$\", \"g\" ),\n\n\trcomma = new RegExp( \"^\" + whitespace + \"*,\" + whitespace + \"*\" ),\n\trcombinators = new RegExp( \"^\" + whitespace + \"*([>+~]|\" + whitespace + \")\" + whitespace + \"*\" ),\n\n\trattributeQuotes = new RegExp( \"=\" + whitespace + \"*([^\\\\]'\\\"]*?)\" + whitespace + \"*\\\\]\", \"g\" ),\n\n\trpseudo = new RegExp( pseudos ),\n\tridentifier = new RegExp( \"^\" + identifier + \"$\" ),\n\n\tmatchExpr = {\n\t\t\"ID\": new RegExp( \"^#(\" + characterEncoding + \")\" ),\n\t\t\"CLASS\": new RegExp( \"^\\\\.(\" + characterEncoding + \")\" ),\n\t\t\"TAG\": new RegExp( \"^(\" + characterEncoding.replace( \"w\", \"w*\" ) + \")\" ),\n\t\t\"ATTR\": new RegExp( \"^\" + attributes ),\n\t\t\"PSEUDO\": new RegExp( \"^\" + pseudos ),\n\t\t\"CHILD\": new RegExp( \"^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\\\(\" + whitespace +\n\t\t\t\"*(even|odd|(([+-]|)(\\\\d*)n|)\" + whitespace + \"*(?:([+-]|)\" + whitespace +\n\t\t\t\"*(\\\\d+)|))\" + whitespace + \"*\\\\)|)\", \"i\" ),\n\t\t\"bool\": new RegExp( \"^(?:\" + booleans + \")$\", \"i\" ),\n\t\t// For use in libraries implementing .is()\n\t\t// We use this for POS matching in `select`\n\t\t\"needsContext\": new RegExp( \"^\" + whitespace + \"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\\\(\" +\n\t\t\twhitespace + \"*((?:-\\\\d)?\\\\d*)\" + whitespace + \"*\\\\)|)(?=[^-]|$)\", \"i\" )\n\t},\n\n\trinputs = /^(?:input|select|textarea|button)$/i,\n\trheader = /^h\\d$/i,\n\n\trnative = /^[^{]+\\{\\s*\\[native \\w/,\n\n\t// Easily-parseable/retrievable ID or TAG or CLASS selectors\n\trquickExpr = /^(?:#([\\w-]+)|(\\w+)|\\.([\\w-]+))$/,\n\n\trsibling = /[+~]/,\n\trescape = /'|\\\\/g,\n\n\t// CSS escapes http://www.w3.org/TR/CSS21/syndata.html#escaped-characters\n\trunescape = new RegExp( \"\\\\\\\\([\\\\da-f]{1,6}\" + whitespace + \"?|(\" + whitespace + \")|.)\", \"ig\" ),\n\tfunescape = function( _, escaped, escapedWhitespace ) {\n\t\tvar high = \"0x\" + escaped - 0x10000;\n\t\t// NaN means non-codepoint\n\t\t// Support: Firefox<24\n\t\t// Workaround erroneous numeric interpretation of +\"0x\"\n\t\treturn high !== high || escapedWhitespace ?\n\t\t\tescaped :\n\t\t\thigh < 0 ?\n\t\t\t\t// BMP codepoint\n\t\t\t\tString.fromCharCode( high + 0x10000 ) :\n\t\t\t\t// Supplemental Plane codepoint (surrogate pair)\n\t\t\t\tString.fromCharCode( high >> 10 | 0xD800, high & 0x3FF | 0xDC00 );\n\t},\n\n\t// Used for iframes\n\t// See setDocument()\n\t// Removing the function wrapper causes a \"Permission Denied\"\n\t// error in IE\n\tunloadHandler = function() {\n\t\tsetDocument();\n\t};\n\n// Optimize for push.apply( _, NodeList )\ntry {\n\tpush.apply(\n\t\t(arr = slice.call( preferredDoc.childNodes )),\n\t\tpreferredDoc.childNodes\n\t);\n\t// Support: Android<4.0\n\t// Detect silently failing push.apply\n\tarr[ preferredDoc.childNodes.length ].nodeType;\n} catch ( e ) {\n\tpush = { apply: arr.length ?\n\n\t\t// Leverage slice if possible\n\t\tfunction( target, els ) {\n\t\t\tpush_native.apply( target, slice.call(els) );\n\t\t} :\n\n\t\t// Support: IE<9\n\t\t// Otherwise append directly\n\t\tfunction( target, els ) {\n\t\t\tvar j = target.length,\n\t\t\t\ti = 0;\n\t\t\t// Can't trust NodeList.length\n\t\t\twhile ( (target[j++] = els[i++]) ) {}\n\t\t\ttarget.length = j - 1;\n\t\t}\n\t};\n}\n\nfunction Sizzle( selector, context, results, seed ) {\n\tvar match, elem, m, nodeType,\n\t\t// QSA vars\n\t\ti, groups, old, nid, newContext, newSelector;\n\n\tif ( ( context ? context.ownerDocument || context : preferredDoc ) !== document ) {\n\t\tsetDocument( context );\n\t}\n\n\tcontext = context || document;\n\tresults = results || [];\n\tnodeType = context.nodeType;\n\n\tif ( typeof selector !== \"string\" || !selector ||\n\t\tnodeType !== 1 && nodeType !== 9 && nodeType !== 11 ) {\n\n\t\treturn results;\n\t}\n\n\tif ( !seed && documentIsHTML ) {\n\n\t\t// Try to shortcut find operations when possible (e.g., not under DocumentFragment)\n\t\tif ( nodeType !== 11 && (match = rquickExpr.exec( selector )) ) {\n\t\t\t// Speed-up: Sizzle(\"#ID\")\n\t\t\tif ( (m = match[1]) ) {\n\t\t\t\tif ( nodeType === 9 ) {\n\t\t\t\t\telem = context.getElementById( m );\n\t\t\t\t\t// Check parentNode to catch when Blackberry 4.6 returns\n\t\t\t\t\t// nodes that are no longer in the document (jQuery #6963)\n\t\t\t\t\tif ( elem && elem.parentNode ) {\n\t\t\t\t\t\t// Handle the case where IE, Opera, and Webkit return items\n\t\t\t\t\t\t// by name instead of ID\n\t\t\t\t\t\tif ( elem.id === m ) {\n\t\t\t\t\t\t\tresults.push( elem );\n\t\t\t\t\t\t\treturn results;\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\treturn results;\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\t// Context is not a document\n\t\t\t\t\tif ( context.ownerDocument && (elem = context.ownerDocument.getElementById( m )) &&\n\t\t\t\t\t\tcontains( context, elem ) && elem.id === m ) {\n\t\t\t\t\t\tresults.push( elem );\n\t\t\t\t\t\treturn results;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t// Speed-up: Sizzle(\"TAG\")\n\t\t\t} else if ( match[2] ) {\n\t\t\t\tpush.apply( results, context.getElementsByTagName( selector ) );\n\t\t\t\treturn results;\n\n\t\t\t// Speed-up: Sizzle(\".CLASS\")\n\t\t\t} else if ( (m = match[3]) && support.getElementsByClassName ) {\n\t\t\t\tpush.apply( results, context.getElementsByClassName( m ) );\n\t\t\t\treturn results;\n\t\t\t}\n\t\t}\n\n\t\t// QSA path\n\t\tif ( support.qsa && (!rbuggyQSA || !rbuggyQSA.test( selector )) ) {\n\t\t\tnid = old = expando;\n\t\t\tnewContext = context;\n\t\t\tnewSelector = nodeType !== 1 && selector;\n\n\t\t\t// qSA works strangely on Element-rooted queries\n\t\t\t// We can work around this by specifying an extra ID on the root\n\t\t\t// and working up from there (Thanks to Andrew Dupont for the technique)\n\t\t\t// IE 8 doesn't work on object elements\n\t\t\tif ( nodeType === 1 && context.nodeName.toLowerCase() !== \"object\" ) {\n\t\t\t\tgroups = tokenize( selector );\n\n\t\t\t\tif ( (old = context.getAttribute(\"id\")) ) {\n\t\t\t\t\tnid = old.replace( rescape, \"\\\\$&\" );\n\t\t\t\t} else {\n\t\t\t\t\tcontext.setAttribute( \"id\", nid );\n\t\t\t\t}\n\t\t\t\tnid = \"[id='\" + nid + \"'] \";\n\n\t\t\t\ti = groups.length;\n\t\t\t\twhile ( i-- ) {\n\t\t\t\t\tgroups[i] = nid + toSelector( groups[i] );\n\t\t\t\t}\n\t\t\t\tnewContext = rsibling.test( selector ) && testContext( context.parentNode ) || context;\n\t\t\t\tnewSelector = groups.join(\",\");\n\t\t\t}\n\n\t\t\tif ( newSelector ) {\n\t\t\t\ttry {\n\t\t\t\t\tpush.apply( results,\n\t\t\t\t\t\tnewContext.querySelectorAll( newSelector )\n\t\t\t\t\t);\n\t\t\t\t\treturn results;\n\t\t\t\t} catch(qsaError) {\n\t\t\t\t} finally {\n\t\t\t\t\tif ( !old ) {\n\t\t\t\t\t\tcontext.removeAttribute(\"id\");\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t// All others\n\treturn select( selector.replace( rtrim, \"$1\" ), context, results, seed );\n}\n\n/**\n * Create key-value caches of limited size\n * @returns {Function(string, Object)} Returns the Object data after storing it on itself with\n *\tproperty name the (space-suffixed) string and (if the cache is larger than Expr.cacheLength)\n *\tdeleting the oldest entry\n */\nfunction createCache() {\n\tvar keys = [];\n\n\tfunction cache( key, value ) {\n\t\t// Use (key + \" \") to avoid collision with native prototype properties (see Issue #157)\n\t\tif ( keys.push( key + \" \" ) > Expr.cacheLength ) {\n\t\t\t// Only keep the most recent entries\n\t\t\tdelete cache[ keys.shift() ];\n\t\t}\n\t\treturn (cache[ key + \" \" ] = value);\n\t}\n\treturn cache;\n}\n\n/**\n * Mark a function for special use by Sizzle\n * @param {Function} fn The function to mark\n */\nfunction markFunction( fn ) {\n\tfn[ expando ] = true;\n\treturn fn;\n}\n\n/**\n * Support testing using an element\n * @param {Function} fn Passed the created div and expects a boolean result\n */\nfunction assert( fn ) {\n\tvar div = document.createElement(\"div\");\n\n\ttry {\n\t\treturn !!fn( div );\n\t} catch (e) {\n\t\treturn false;\n\t} finally {\n\t\t// Remove from its parent by default\n\t\tif ( div.parentNode ) {\n\t\t\tdiv.parentNode.removeChild( div );\n\t\t}\n\t\t// release memory in IE\n\t\tdiv = null;\n\t}\n}\n\n/**\n * Adds the same handler for all of the specified attrs\n * @param {String} attrs Pipe-separated list of attributes\n * @param {Function} handler The method that will be applied\n */\nfunction addHandle( attrs, handler ) {\n\tvar arr = attrs.split(\"|\"),\n\t\ti = attrs.length;\n\n\twhile ( i-- ) {\n\t\tExpr.attrHandle[ arr[i] ] = handler;\n\t}\n}\n\n/**\n * Checks document order of two siblings\n * @param {Element} a\n * @param {Element} b\n * @returns {Number} Returns less than 0 if a precedes b, greater than 0 if a follows b\n */\nfunction siblingCheck( a, b ) {\n\tvar cur = b && a,\n\t\tdiff = cur && a.nodeType === 1 && b.nodeType === 1 &&\n\t\t\t( ~b.sourceIndex || MAX_NEGATIVE ) -\n\t\t\t( ~a.sourceIndex || MAX_NEGATIVE );\n\n\t// Use IE sourceIndex if available on both nodes\n\tif ( diff ) {\n\t\treturn diff;\n\t}\n\n\t// Check if b follows a\n\tif ( cur ) {\n\t\twhile ( (cur = cur.nextSibling) ) {\n\t\t\tif ( cur === b ) {\n\t\t\t\treturn -1;\n\t\t\t}\n\t\t}\n\t}\n\n\treturn a ? 1 : -1;\n}\n\n/**\n * Returns a function to use in pseudos for input types\n * @param {String} type\n */\nfunction createInputPseudo( type ) {\n\treturn function( elem ) {\n\t\tvar name = elem.nodeName.toLowerCase();\n\t\treturn name === \"input\" && elem.type === type;\n\t};\n}\n\n/**\n * Returns a function to use in pseudos for buttons\n * @param {String} type\n */\nfunction createButtonPseudo( type ) {\n\treturn function( elem ) {\n\t\tvar name = elem.nodeName.toLowerCase();\n\t\treturn (name === \"input\" || name === \"button\") && elem.type === type;\n\t};\n}\n\n/**\n * Returns a function to use in pseudos for positionals\n * @param {Function} fn\n */\nfunction createPositionalPseudo( fn ) {\n\treturn markFunction(function( argument ) {\n\t\targument = +argument;\n\t\treturn markFunction(function( seed, matches ) {\n\t\t\tvar j,\n\t\t\t\tmatchIndexes = fn( [], seed.length, argument ),\n\t\t\t\ti = matchIndexes.length;\n\n\t\t\t// Match elements found at the specified indexes\n\t\t\twhile ( i-- ) {\n\t\t\t\tif ( seed[ (j = matchIndexes[i]) ] ) {\n\t\t\t\t\tseed[j] = !(matches[j] = seed[j]);\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\t});\n}\n\n/**\n * Checks a node for validity as a Sizzle context\n * @param {Element|Object=} context\n * @returns {Element|Object|Boolean} The input node if acceptable, otherwise a falsy value\n */\nfunction testContext( context ) {\n\treturn context && typeof context.getElementsByTagName !== \"undefined\" && context;\n}\n\n// Expose support vars for convenience\nsupport = Sizzle.support = {};\n\n/**\n * Detects XML nodes\n * @param {Element|Object} elem An element or a document\n * @returns {Boolean} True iff elem is a non-HTML XML node\n */\nisXML = Sizzle.isXML = function( elem ) {\n\t// documentElement is verified for cases where it doesn't yet exist\n\t// (such as loading iframes in IE - #4833)\n\tvar documentElement = elem && (elem.ownerDocument || elem).documentElement;\n\treturn documentElement ? documentElement.nodeName !== \"HTML\" : false;\n};\n\n/**\n * Sets document-related variables once based on the current document\n * @param {Element|Object} [doc] An element or document object to use to set the document\n * @returns {Object} Returns the current document\n */\nsetDocument = Sizzle.setDocument = function( node ) {\n\tvar hasCompare, parent,\n\t\tdoc = node ? node.ownerDocument || node : preferredDoc;\n\n\t// If no document and documentElement is available, return\n\tif ( doc === document || doc.nodeType !== 9 || !doc.documentElement ) {\n\t\treturn document;\n\t}\n\n\t// Set our document\n\tdocument = doc;\n\tdocElem = doc.documentElement;\n\tparent = doc.defaultView;\n\n\t// Support: IE>8\n\t// If iframe document is assigned to \"document\" variable and if iframe has been reloaded,\n\t// IE will throw \"permission denied\" error when accessing \"document\" variable, see jQuery #13936\n\t// IE6-8 do not support the defaultView property so parent will be undefined\n\tif ( parent && parent !== parent.top ) {\n\t\t// IE11 does not have attachEvent, so all must suffer\n\t\tif ( parent.addEventListener ) {\n\t\t\tparent.addEventListener( \"unload\", unloadHandler, false );\n\t\t} else if ( parent.attachEvent ) {\n\t\t\tparent.attachEvent( \"onunload\", unloadHandler );\n\t\t}\n\t}\n\n\t/* Support tests\n\t---------------------------------------------------------------------- */\n\tdocumentIsHTML = !isXML( doc );\n\n\t/* Attributes\n\t---------------------------------------------------------------------- */\n\n\t// Support: IE<8\n\t// Verify that getAttribute really returns attributes and not properties\n\t// (excepting IE8 booleans)\n\tsupport.attributes = assert(function( div ) {\n\t\tdiv.className = \"i\";\n\t\treturn !div.getAttribute(\"className\");\n\t});\n\n\t/* getElement(s)By*\n\t---------------------------------------------------------------------- */\n\n\t// Check if getElementsByTagName(\"*\") returns only elements\n\tsupport.getElementsByTagName = assert(function( div ) {\n\t\tdiv.appendChild( doc.createComment(\"\") );\n\t\treturn !div.getElementsByTagName(\"*\").length;\n\t});\n\n\t// Support: IE<9\n\tsupport.getElementsByClassName = rnative.test( doc.getElementsByClassName );\n\n\t// Support: IE<10\n\t// Check if getElementById returns elements by name\n\t// The broken getElementById methods don't pick up programatically-set names,\n\t// so use a roundabout getElementsByName test\n\tsupport.getById = assert(function( div ) {\n\t\tdocElem.appendChild( div ).id = expando;\n\t\treturn !doc.getElementsByName || !doc.getElementsByName( expando ).length;\n\t});\n\n\t// ID find and filter\n\tif ( support.getById ) {\n\t\tExpr.find[\"ID\"] = function( id, context ) {\n\t\t\tif ( typeof context.getElementById !== \"undefined\" && documentIsHTML ) {\n\t\t\t\tvar m = context.getElementById( id );\n\t\t\t\t// Check parentNode to catch when Blackberry 4.6 returns\n\t\t\t\t// nodes that are no longer in the document #6963\n\t\t\t\treturn m && m.parentNode ? [ m ] : [];\n\t\t\t}\n\t\t};\n\t\tExpr.filter[\"ID\"] = function( id ) {\n\t\t\tvar attrId = id.replace( runescape, funescape );\n\t\t\treturn function( elem ) {\n\t\t\t\treturn elem.getAttribute(\"id\") === attrId;\n\t\t\t};\n\t\t};\n\t} else {\n\t\t// Support: IE6/7\n\t\t// getElementById is not reliable as a find shortcut\n\t\tdelete Expr.find[\"ID\"];\n\n\t\tExpr.filter[\"ID\"] =  function( id ) {\n\t\t\tvar attrId = id.replace( runescape, funescape );\n\t\t\treturn function( elem ) {\n\t\t\t\tvar node = typeof elem.getAttributeNode !== \"undefined\" && elem.getAttributeNode(\"id\");\n\t\t\t\treturn node && node.value === attrId;\n\t\t\t};\n\t\t};\n\t}\n\n\t// Tag\n\tExpr.find[\"TAG\"] = support.getElementsByTagName ?\n\t\tfunction( tag, context ) {\n\t\t\tif ( typeof context.getElementsByTagName !== \"undefined\" ) {\n\t\t\t\treturn context.getElementsByTagName( tag );\n\n\t\t\t// DocumentFragment nodes don't have gEBTN\n\t\t\t} else if ( support.qsa ) {\n\t\t\t\treturn context.querySelectorAll( tag );\n\t\t\t}\n\t\t} :\n\n\t\tfunction( tag, context ) {\n\t\t\tvar elem,\n\t\t\t\ttmp = [],\n\t\t\t\ti = 0,\n\t\t\t\t// By happy coincidence, a (broken) gEBTN appears on DocumentFragment nodes too\n\t\t\t\tresults = context.getElementsByTagName( tag );\n\n\t\t\t// Filter out possible comments\n\t\t\tif ( tag === \"*\" ) {\n\t\t\t\twhile ( (elem = results[i++]) ) {\n\t\t\t\t\tif ( elem.nodeType === 1 ) {\n\t\t\t\t\t\ttmp.push( elem );\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\treturn tmp;\n\t\t\t}\n\t\t\treturn results;\n\t\t};\n\n\t// Class\n\tExpr.find[\"CLASS\"] = support.getElementsByClassName && function( className, context ) {\n\t\tif ( documentIsHTML ) {\n\t\t\treturn context.getElementsByClassName( className );\n\t\t}\n\t};\n\n\t/* QSA/matchesSelector\n\t---------------------------------------------------------------------- */\n\n\t// QSA and matchesSelector support\n\n\t// matchesSelector(:active) reports false when true (IE9/Opera 11.5)\n\trbuggyMatches = [];\n\n\t// qSa(:focus) reports false when true (Chrome 21)\n\t// We allow this because of a bug in IE8/9 that throws an error\n\t// whenever `document.activeElement` is accessed on an iframe\n\t// So, we allow :focus to pass through QSA all the time to avoid the IE error\n\t// See http://bugs.jquery.com/ticket/13378\n\trbuggyQSA = [];\n\n\tif ( (support.qsa = rnative.test( doc.querySelectorAll )) ) {\n\t\t// Build QSA regex\n\t\t// Regex strategy adopted from Diego Perini\n\t\tassert(function( div ) {\n\t\t\t// Select is set to empty string on purpose\n\t\t\t// This is to test IE's treatment of not explicitly\n\t\t\t// setting a boolean content attribute,\n\t\t\t// since its presence should be enough\n\t\t\t// http://bugs.jquery.com/ticket/12359\n\t\t\tdocElem.appendChild( div ).innerHTML = \"<a id='\" + expando + \"'></a>\" +\n\t\t\t\t\"<select id='\" + expando + \"-\\f]' msallowcapture=''>\" +\n\t\t\t\t\"<option selected=''></option></select>\";\n\n\t\t\t// Support: IE8, Opera 11-12.16\n\t\t\t// Nothing should be selected when empty strings follow ^= or $= or *=\n\t\t\t// The test attribute must be unknown in Opera but \"safe\" for WinRT\n\t\t\t// http://msdn.microsoft.com/en-us/library/ie/hh465388.aspx#attribute_section\n\t\t\tif ( div.querySelectorAll(\"[msallowcapture^='']\").length ) {\n\t\t\t\trbuggyQSA.push( \"[*^$]=\" + whitespace + \"*(?:''|\\\"\\\")\" );\n\t\t\t}\n\n\t\t\t// Support: IE8\n\t\t\t// Boolean attributes and \"value\" are not treated correctly\n\t\t\tif ( !div.querySelectorAll(\"[selected]\").length ) {\n\t\t\t\trbuggyQSA.push( \"\\\\[\" + whitespace + \"*(?:value|\" + booleans + \")\" );\n\t\t\t}\n\n\t\t\t// Support: Chrome<29, Android<4.2+, Safari<7.0+, iOS<7.0+, PhantomJS<1.9.7+\n\t\t\tif ( !div.querySelectorAll( \"[id~=\" + expando + \"-]\" ).length ) {\n\t\t\t\trbuggyQSA.push(\"~=\");\n\t\t\t}\n\n\t\t\t// Webkit/Opera - :checked should return selected option elements\n\t\t\t// http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked\n\t\t\t// IE8 throws error here and will not see later tests\n\t\t\tif ( !div.querySelectorAll(\":checked\").length ) {\n\t\t\t\trbuggyQSA.push(\":checked\");\n\t\t\t}\n\n\t\t\t// Support: Safari 8+, iOS 8+\n\t\t\t// https://bugs.webkit.org/show_bug.cgi?id=136851\n\t\t\t// In-page `selector#id sibing-combinator selector` fails\n\t\t\tif ( !div.querySelectorAll( \"a#\" + expando + \"+*\" ).length ) {\n\t\t\t\trbuggyQSA.push(\".#.+[+~]\");\n\t\t\t}\n\t\t});\n\n\t\tassert(function( div ) {\n\t\t\t// Support: Windows 8 Native Apps\n\t\t\t// The type and name attributes are restricted during .innerHTML assignment\n\t\t\tvar input = doc.createElement(\"input\");\n\t\t\tinput.setAttribute( \"type\", \"hidden\" );\n\t\t\tdiv.appendChild( input ).setAttribute( \"name\", \"D\" );\n\n\t\t\t// Support: IE8\n\t\t\t// Enforce case-sensitivity of name attribute\n\t\t\tif ( div.querySelectorAll(\"[name=d]\").length ) {\n\t\t\t\trbuggyQSA.push( \"name\" + whitespace + \"*[*^$|!~]?=\" );\n\t\t\t}\n\n\t\t\t// FF 3.5 - :enabled/:disabled and hidden elements (hidden elements are still enabled)\n\t\t\t// IE8 throws error here and will not see later tests\n\t\t\tif ( !div.querySelectorAll(\":enabled\").length ) {\n\t\t\t\trbuggyQSA.push( \":enabled\", \":disabled\" );\n\t\t\t}\n\n\t\t\t// Opera 10-11 does not throw on post-comma invalid pseudos\n\t\t\tdiv.querySelectorAll(\"*,:x\");\n\t\t\trbuggyQSA.push(\",.*:\");\n\t\t});\n\t}\n\n\tif ( (support.matchesSelector = rnative.test( (matches = docElem.matches ||\n\t\tdocElem.webkitMatchesSelector ||\n\t\tdocElem.mozMatchesSelector ||\n\t\tdocElem.oMatchesSelector ||\n\t\tdocElem.msMatchesSelector) )) ) {\n\n\t\tassert(function( div ) {\n\t\t\t// Check to see if it's possible to do matchesSelector\n\t\t\t// on a disconnected node (IE 9)\n\t\t\tsupport.disconnectedMatch = matches.call( div, \"div\" );\n\n\t\t\t// This should fail with an exception\n\t\t\t// Gecko does not error, returns false instead\n\t\t\tmatches.call( div, \"[s!='']:x\" );\n\t\t\trbuggyMatches.push( \"!=\", pseudos );\n\t\t});\n\t}\n\n\trbuggyQSA = rbuggyQSA.length && new RegExp( rbuggyQSA.join(\"|\") );\n\trbuggyMatches = rbuggyMatches.length && new RegExp( rbuggyMatches.join(\"|\") );\n\n\t/* Contains\n\t---------------------------------------------------------------------- */\n\thasCompare = rnative.test( docElem.compareDocumentPosition );\n\n\t// Element contains another\n\t// Purposefully does not implement inclusive descendent\n\t// As in, an element does not contain itself\n\tcontains = hasCompare || rnative.test( docElem.contains ) ?\n\t\tfunction( a, b ) {\n\t\t\tvar adown = a.nodeType === 9 ? a.documentElement : a,\n\t\t\t\tbup = b && b.parentNode;\n\t\t\treturn a === bup || !!( bup && bup.nodeType === 1 && (\n\t\t\t\tadown.contains ?\n\t\t\t\t\tadown.contains( bup ) :\n\t\t\t\t\ta.compareDocumentPosition && a.compareDocumentPosition( bup ) & 16\n\t\t\t));\n\t\t} :\n\t\tfunction( a, b ) {\n\t\t\tif ( b ) {\n\t\t\t\twhile ( (b = b.parentNode) ) {\n\t\t\t\t\tif ( b === a ) {\n\t\t\t\t\t\treturn true;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn false;\n\t\t};\n\n\t/* Sorting\n\t---------------------------------------------------------------------- */\n\n\t// Document order sorting\n\tsortOrder = hasCompare ?\n\tfunction( a, b ) {\n\n\t\t// Flag for duplicate removal\n\t\tif ( a === b ) {\n\t\t\thasDuplicate = true;\n\t\t\treturn 0;\n\t\t}\n\n\t\t// Sort on method existence if only one input has compareDocumentPosition\n\t\tvar compare = !a.compareDocumentPosition - !b.compareDocumentPosition;\n\t\tif ( compare ) {\n\t\t\treturn compare;\n\t\t}\n\n\t\t// Calculate position if both inputs belong to the same document\n\t\tcompare = ( a.ownerDocument || a ) === ( b.ownerDocument || b ) ?\n\t\t\ta.compareDocumentPosition( b ) :\n\n\t\t\t// Otherwise we know they are disconnected\n\t\t\t1;\n\n\t\t// Disconnected nodes\n\t\tif ( compare & 1 ||\n\t\t\t(!support.sortDetached && b.compareDocumentPosition( a ) === compare) ) {\n\n\t\t\t// Choose the first element that is related to our preferred document\n\t\t\tif ( a === doc || a.ownerDocument === preferredDoc && contains(preferredDoc, a) ) {\n\t\t\t\treturn -1;\n\t\t\t}\n\t\t\tif ( b === doc || b.ownerDocument === preferredDoc && contains(preferredDoc, b) ) {\n\t\t\t\treturn 1;\n\t\t\t}\n\n\t\t\t// Maintain original order\n\t\t\treturn sortInput ?\n\t\t\t\t( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) :\n\t\t\t\t0;\n\t\t}\n\n\t\treturn compare & 4 ? -1 : 1;\n\t} :\n\tfunction( a, b ) {\n\t\t// Exit early if the nodes are identical\n\t\tif ( a === b ) {\n\t\t\thasDuplicate = true;\n\t\t\treturn 0;\n\t\t}\n\n\t\tvar cur,\n\t\t\ti = 0,\n\t\t\taup = a.parentNode,\n\t\t\tbup = b.parentNode,\n\t\t\tap = [ a ],\n\t\t\tbp = [ b ];\n\n\t\t// Parentless nodes are either documents or disconnected\n\t\tif ( !aup || !bup ) {\n\t\t\treturn a === doc ? -1 :\n\t\t\t\tb === doc ? 1 :\n\t\t\t\taup ? -1 :\n\t\t\t\tbup ? 1 :\n\t\t\t\tsortInput ?\n\t\t\t\t( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) :\n\t\t\t\t0;\n\n\t\t// If the nodes are siblings, we can do a quick check\n\t\t} else if ( aup === bup ) {\n\t\t\treturn siblingCheck( a, b );\n\t\t}\n\n\t\t// Otherwise we need full lists of their ancestors for comparison\n\t\tcur = a;\n\t\twhile ( (cur = cur.parentNode) ) {\n\t\t\tap.unshift( cur );\n\t\t}\n\t\tcur = b;\n\t\twhile ( (cur = cur.parentNode) ) {\n\t\t\tbp.unshift( cur );\n\t\t}\n\n\t\t// Walk down the tree looking for a discrepancy\n\t\twhile ( ap[i] === bp[i] ) {\n\t\t\ti++;\n\t\t}\n\n\t\treturn i ?\n\t\t\t// Do a sibling check if the nodes have a common ancestor\n\t\t\tsiblingCheck( ap[i], bp[i] ) :\n\n\t\t\t// Otherwise nodes in our document sort first\n\t\t\tap[i] === preferredDoc ? -1 :\n\t\t\tbp[i] === preferredDoc ? 1 :\n\t\t\t0;\n\t};\n\n\treturn doc;\n};\n\nSizzle.matches = function( expr, elements ) {\n\treturn Sizzle( expr, null, null, elements );\n};\n\nSizzle.matchesSelector = function( elem, expr ) {\n\t// Set document vars if needed\n\tif ( ( elem.ownerDocument || elem ) !== document ) {\n\t\tsetDocument( elem );\n\t}\n\n\t// Make sure that attribute selectors are quoted\n\texpr = expr.replace( rattributeQuotes, \"='$1']\" );\n\n\tif ( support.matchesSelector && documentIsHTML &&\n\t\t( !rbuggyMatches || !rbuggyMatches.test( expr ) ) &&\n\t\t( !rbuggyQSA     || !rbuggyQSA.test( expr ) ) ) {\n\n\t\ttry {\n\t\t\tvar ret = matches.call( elem, expr );\n\n\t\t\t// IE 9's matchesSelector returns false on disconnected nodes\n\t\t\tif ( ret || support.disconnectedMatch ||\n\t\t\t\t\t// As well, disconnected nodes are said to be in a document\n\t\t\t\t\t// fragment in IE 9\n\t\t\t\t\telem.document && elem.document.nodeType !== 11 ) {\n\t\t\t\treturn ret;\n\t\t\t}\n\t\t} catch (e) {}\n\t}\n\n\treturn Sizzle( expr, document, null, [ elem ] ).length > 0;\n};\n\nSizzle.contains = function( context, elem ) {\n\t// Set document vars if needed\n\tif ( ( context.ownerDocument || context ) !== document ) {\n\t\tsetDocument( context );\n\t}\n\treturn contains( context, elem );\n};\n\nSizzle.attr = function( elem, name ) {\n\t// Set document vars if needed\n\tif ( ( elem.ownerDocument || elem ) !== document ) {\n\t\tsetDocument( elem );\n\t}\n\n\tvar fn = Expr.attrHandle[ name.toLowerCase() ],\n\t\t// Don't get fooled by Object.prototype properties (jQuery #13807)\n\t\tval = fn && hasOwn.call( Expr.attrHandle, name.toLowerCase() ) ?\n\t\t\tfn( elem, name, !documentIsHTML ) :\n\t\t\tundefined;\n\n\treturn val !== undefined ?\n\t\tval :\n\t\tsupport.attributes || !documentIsHTML ?\n\t\t\telem.getAttribute( name ) :\n\t\t\t(val = elem.getAttributeNode(name)) && val.specified ?\n\t\t\t\tval.value :\n\t\t\t\tnull;\n};\n\nSizzle.error = function( msg ) {\n\tthrow new Error( \"Syntax error, unrecognized expression: \" + msg );\n};\n\n/**\n * Document sorting and removing duplicates\n * @param {ArrayLike} results\n */\nSizzle.uniqueSort = function( results ) {\n\tvar elem,\n\t\tduplicates = [],\n\t\tj = 0,\n\t\ti = 0;\n\n\t// Unless we *know* we can detect duplicates, assume their presence\n\thasDuplicate = !support.detectDuplicates;\n\tsortInput = !support.sortStable && results.slice( 0 );\n\tresults.sort( sortOrder );\n\n\tif ( hasDuplicate ) {\n\t\twhile ( (elem = results[i++]) ) {\n\t\t\tif ( elem === results[ i ] ) {\n\t\t\t\tj = duplicates.push( i );\n\t\t\t}\n\t\t}\n\t\twhile ( j-- ) {\n\t\t\tresults.splice( duplicates[ j ], 1 );\n\t\t}\n\t}\n\n\t// Clear input after sorting to release objects\n\t// See https://github.com/jquery/sizzle/pull/225\n\tsortInput = null;\n\n\treturn results;\n};\n\n/**\n * Utility function for retrieving the text value of an array of DOM nodes\n * @param {Array|Element} elem\n */\ngetText = Sizzle.getText = function( elem ) {\n\tvar node,\n\t\tret = \"\",\n\t\ti = 0,\n\t\tnodeType = elem.nodeType;\n\n\tif ( !nodeType ) {\n\t\t// If no nodeType, this is expected to be an array\n\t\twhile ( (node = elem[i++]) ) {\n\t\t\t// Do not traverse comment nodes\n\t\t\tret += getText( node );\n\t\t}\n\t} else if ( nodeType === 1 || nodeType === 9 || nodeType === 11 ) {\n\t\t// Use textContent for elements\n\t\t// innerText usage removed for consistency of new lines (jQuery #11153)\n\t\tif ( typeof elem.textContent === \"string\" ) {\n\t\t\treturn elem.textContent;\n\t\t} else {\n\t\t\t// Traverse its children\n\t\t\tfor ( elem = elem.firstChild; elem; elem = elem.nextSibling ) {\n\t\t\t\tret += getText( elem );\n\t\t\t}\n\t\t}\n\t} else if ( nodeType === 3 || nodeType === 4 ) {\n\t\treturn elem.nodeValue;\n\t}\n\t// Do not include comment or processing instruction nodes\n\n\treturn ret;\n};\n\nExpr = Sizzle.selectors = {\n\n\t// Can be adjusted by the user\n\tcacheLength: 50,\n\n\tcreatePseudo: markFunction,\n\n\tmatch: matchExpr,\n\n\tattrHandle: {},\n\n\tfind: {},\n\n\trelative: {\n\t\t\">\": { dir: \"parentNode\", first: true },\n\t\t\" \": { dir: \"parentNode\" },\n\t\t\"+\": { dir: \"previousSibling\", first: true },\n\t\t\"~\": { dir: \"previousSibling\" }\n\t},\n\n\tpreFilter: {\n\t\t\"ATTR\": function( match ) {\n\t\t\tmatch[1] = match[1].replace( runescape, funescape );\n\n\t\t\t// Move the given value to match[3] whether quoted or unquoted\n\t\t\tmatch[3] = ( match[3] || match[4] || match[5] || \"\" ).replace( runescape, funescape );\n\n\t\t\tif ( match[2] === \"~=\" ) {\n\t\t\t\tmatch[3] = \" \" + match[3] + \" \";\n\t\t\t}\n\n\t\t\treturn match.slice( 0, 4 );\n\t\t},\n\n\t\t\"CHILD\": function( match ) {\n\t\t\t/* matches from matchExpr[\"CHILD\"]\n\t\t\t\t1 type (only|nth|...)\n\t\t\t\t2 what (child|of-type)\n\t\t\t\t3 argument (even|odd|\\d*|\\d*n([+-]\\d+)?|...)\n\t\t\t\t4 xn-component of xn+y argument ([+-]?\\d*n|)\n\t\t\t\t5 sign of xn-component\n\t\t\t\t6 x of xn-component\n\t\t\t\t7 sign of y-component\n\t\t\t\t8 y of y-component\n\t\t\t*/\n\t\t\tmatch[1] = match[1].toLowerCase();\n\n\t\t\tif ( match[1].slice( 0, 3 ) === \"nth\" ) {\n\t\t\t\t// nth-* requires argument\n\t\t\t\tif ( !match[3] ) {\n\t\t\t\t\tSizzle.error( match[0] );\n\t\t\t\t}\n\n\t\t\t\t// numeric x and y parameters for Expr.filter.CHILD\n\t\t\t\t// remember that false/true cast respectively to 0/1\n\t\t\t\tmatch[4] = +( match[4] ? match[5] + (match[6] || 1) : 2 * ( match[3] === \"even\" || match[3] === \"odd\" ) );\n\t\t\t\tmatch[5] = +( ( match[7] + match[8] ) || match[3] === \"odd\" );\n\n\t\t\t// other types prohibit arguments\n\t\t\t} else if ( match[3] ) {\n\t\t\t\tSizzle.error( match[0] );\n\t\t\t}\n\n\t\t\treturn match;\n\t\t},\n\n\t\t\"PSEUDO\": function( match ) {\n\t\t\tvar excess,\n\t\t\t\tunquoted = !match[6] && match[2];\n\n\t\t\tif ( matchExpr[\"CHILD\"].test( match[0] ) ) {\n\t\t\t\treturn null;\n\t\t\t}\n\n\t\t\t// Accept quoted arguments as-is\n\t\t\tif ( match[3] ) {\n\t\t\t\tmatch[2] = match[4] || match[5] || \"\";\n\n\t\t\t// Strip excess characters from unquoted arguments\n\t\t\t} else if ( unquoted && rpseudo.test( unquoted ) &&\n\t\t\t\t// Get excess from tokenize (recursively)\n\t\t\t\t(excess = tokenize( unquoted, true )) &&\n\t\t\t\t// advance to the next closing parenthesis\n\t\t\t\t(excess = unquoted.indexOf( \")\", unquoted.length - excess ) - unquoted.length) ) {\n\n\t\t\t\t// excess is a negative index\n\t\t\t\tmatch[0] = match[0].slice( 0, excess );\n\t\t\t\tmatch[2] = unquoted.slice( 0, excess );\n\t\t\t}\n\n\t\t\t// Return only captures needed by the pseudo filter method (type and argument)\n\t\t\treturn match.slice( 0, 3 );\n\t\t}\n\t},\n\n\tfilter: {\n\n\t\t\"TAG\": function( nodeNameSelector ) {\n\t\t\tvar nodeName = nodeNameSelector.replace( runescape, funescape ).toLowerCase();\n\t\t\treturn nodeNameSelector === \"*\" ?\n\t\t\t\tfunction() { return true; } :\n\t\t\t\tfunction( elem ) {\n\t\t\t\t\treturn elem.nodeName && elem.nodeName.toLowerCase() === nodeName;\n\t\t\t\t};\n\t\t},\n\n\t\t\"CLASS\": function( className ) {\n\t\t\tvar pattern = classCache[ className + \" \" ];\n\n\t\t\treturn pattern ||\n\t\t\t\t(pattern = new RegExp( \"(^|\" + whitespace + \")\" + className + \"(\" + whitespace + \"|$)\" )) &&\n\t\t\t\tclassCache( className, function( elem ) {\n\t\t\t\t\treturn pattern.test( typeof elem.className === \"string\" && elem.className || typeof elem.getAttribute !== \"undefined\" && elem.getAttribute(\"class\") || \"\" );\n\t\t\t\t});\n\t\t},\n\n\t\t\"ATTR\": function( name, operator, check ) {\n\t\t\treturn function( elem ) {\n\t\t\t\tvar result = Sizzle.attr( elem, name );\n\n\t\t\t\tif ( result == null ) {\n\t\t\t\t\treturn operator === \"!=\";\n\t\t\t\t}\n\t\t\t\tif ( !operator ) {\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\n\t\t\t\tresult += \"\";\n\n\t\t\t\treturn operator === \"=\" ? result === check :\n\t\t\t\t\toperator === \"!=\" ? result !== check :\n\t\t\t\t\toperator === \"^=\" ? check && result.indexOf( check ) === 0 :\n\t\t\t\t\toperator === \"*=\" ? check && result.indexOf( check ) > -1 :\n\t\t\t\t\toperator === \"$=\" ? check && result.slice( -check.length ) === check :\n\t\t\t\t\toperator === \"~=\" ? ( \" \" + result.replace( rwhitespace, \" \" ) + \" \" ).indexOf( check ) > -1 :\n\t\t\t\t\toperator === \"|=\" ? result === check || result.slice( 0, check.length + 1 ) === check + \"-\" :\n\t\t\t\t\tfalse;\n\t\t\t};\n\t\t},\n\n\t\t\"CHILD\": function( type, what, argument, first, last ) {\n\t\t\tvar simple = type.slice( 0, 3 ) !== \"nth\",\n\t\t\t\tforward = type.slice( -4 ) !== \"last\",\n\t\t\t\tofType = what === \"of-type\";\n\n\t\t\treturn first === 1 && last === 0 ?\n\n\t\t\t\t// Shortcut for :nth-*(n)\n\t\t\t\tfunction( elem ) {\n\t\t\t\t\treturn !!elem.parentNode;\n\t\t\t\t} :\n\n\t\t\t\tfunction( elem, context, xml ) {\n\t\t\t\t\tvar cache, outerCache, node, diff, nodeIndex, start,\n\t\t\t\t\t\tdir = simple !== forward ? \"nextSibling\" : \"previousSibling\",\n\t\t\t\t\t\tparent = elem.parentNode,\n\t\t\t\t\t\tname = ofType && elem.nodeName.toLowerCase(),\n\t\t\t\t\t\tuseCache = !xml && !ofType;\n\n\t\t\t\t\tif ( parent ) {\n\n\t\t\t\t\t\t// :(first|last|only)-(child|of-type)\n\t\t\t\t\t\tif ( simple ) {\n\t\t\t\t\t\t\twhile ( dir ) {\n\t\t\t\t\t\t\t\tnode = elem;\n\t\t\t\t\t\t\t\twhile ( (node = node[ dir ]) ) {\n\t\t\t\t\t\t\t\t\tif ( ofType ? node.nodeName.toLowerCase() === name : node.nodeType === 1 ) {\n\t\t\t\t\t\t\t\t\t\treturn false;\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t// Reverse direction for :only-* (if we haven't yet done so)\n\t\t\t\t\t\t\t\tstart = dir = type === \"only\" && !start && \"nextSibling\";\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\treturn true;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tstart = [ forward ? parent.firstChild : parent.lastChild ];\n\n\t\t\t\t\t\t// non-xml :nth-child(...) stores cache data on `parent`\n\t\t\t\t\t\tif ( forward && useCache ) {\n\t\t\t\t\t\t\t// Seek `elem` from a previously-cached index\n\t\t\t\t\t\t\touterCache = parent[ expando ] || (parent[ expando ] = {});\n\t\t\t\t\t\t\tcache = outerCache[ type ] || [];\n\t\t\t\t\t\t\tnodeIndex = cache[0] === dirruns && cache[1];\n\t\t\t\t\t\t\tdiff = cache[0] === dirruns && cache[2];\n\t\t\t\t\t\t\tnode = nodeIndex && parent.childNodes[ nodeIndex ];\n\n\t\t\t\t\t\t\twhile ( (node = ++nodeIndex && node && node[ dir ] ||\n\n\t\t\t\t\t\t\t\t// Fallback to seeking `elem` from the start\n\t\t\t\t\t\t\t\t(diff = nodeIndex = 0) || start.pop()) ) {\n\n\t\t\t\t\t\t\t\t// When found, cache indexes on `parent` and break\n\t\t\t\t\t\t\t\tif ( node.nodeType === 1 && ++diff && node === elem ) {\n\t\t\t\t\t\t\t\t\touterCache[ type ] = [ dirruns, nodeIndex, diff ];\n\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// Use previously-cached element index if available\n\t\t\t\t\t\t} else if ( useCache && (cache = (elem[ expando ] || (elem[ expando ] = {}))[ type ]) && cache[0] === dirruns ) {\n\t\t\t\t\t\t\tdiff = cache[1];\n\n\t\t\t\t\t\t// xml :nth-child(...) or :nth-last-child(...) or :nth(-last)?-of-type(...)\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t// Use the same loop as above to seek `elem` from the start\n\t\t\t\t\t\t\twhile ( (node = ++nodeIndex && node && node[ dir ] ||\n\t\t\t\t\t\t\t\t(diff = nodeIndex = 0) || start.pop()) ) {\n\n\t\t\t\t\t\t\t\tif ( ( ofType ? node.nodeName.toLowerCase() === name : node.nodeType === 1 ) && ++diff ) {\n\t\t\t\t\t\t\t\t\t// Cache the index of each encountered element\n\t\t\t\t\t\t\t\t\tif ( useCache ) {\n\t\t\t\t\t\t\t\t\t\t(node[ expando ] || (node[ expando ] = {}))[ type ] = [ dirruns, diff ];\n\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t\tif ( node === elem ) {\n\t\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// Incorporate the offset, then check against cycle size\n\t\t\t\t\t\tdiff -= last;\n\t\t\t\t\t\treturn diff === first || ( diff % first === 0 && diff / first >= 0 );\n\t\t\t\t\t}\n\t\t\t\t};\n\t\t},\n\n\t\t\"PSEUDO\": function( pseudo, argument ) {\n\t\t\t// pseudo-class names are case-insensitive\n\t\t\t// http://www.w3.org/TR/selectors/#pseudo-classes\n\t\t\t// Prioritize by case sensitivity in case custom pseudos are added with uppercase letters\n\t\t\t// Remember that setFilters inherits from pseudos\n\t\t\tvar args,\n\t\t\t\tfn = Expr.pseudos[ pseudo ] || Expr.setFilters[ pseudo.toLowerCase() ] ||\n\t\t\t\t\tSizzle.error( \"unsupported pseudo: \" + pseudo );\n\n\t\t\t// The user may use createPseudo to indicate that\n\t\t\t// arguments are needed to create the filter function\n\t\t\t// just as Sizzle does\n\t\t\tif ( fn[ expando ] ) {\n\t\t\t\treturn fn( argument );\n\t\t\t}\n\n\t\t\t// But maintain support for old signatures\n\t\t\tif ( fn.length > 1 ) {\n\t\t\t\targs = [ pseudo, pseudo, \"\", argument ];\n\t\t\t\treturn Expr.setFilters.hasOwnProperty( pseudo.toLowerCase() ) ?\n\t\t\t\t\tmarkFunction(function( seed, matches ) {\n\t\t\t\t\t\tvar idx,\n\t\t\t\t\t\t\tmatched = fn( seed, argument ),\n\t\t\t\t\t\t\ti = matched.length;\n\t\t\t\t\t\twhile ( i-- ) {\n\t\t\t\t\t\t\tidx = indexOf( seed, matched[i] );\n\t\t\t\t\t\t\tseed[ idx ] = !( matches[ idx ] = matched[i] );\n\t\t\t\t\t\t}\n\t\t\t\t\t}) :\n\t\t\t\t\tfunction( elem ) {\n\t\t\t\t\t\treturn fn( elem, 0, args );\n\t\t\t\t\t};\n\t\t\t}\n\n\t\t\treturn fn;\n\t\t}\n\t},\n\n\tpseudos: {\n\t\t// Potentially complex pseudos\n\t\t\"not\": markFunction(function( selector ) {\n\t\t\t// Trim the selector passed to compile\n\t\t\t// to avoid treating leading and trailing\n\t\t\t// spaces as combinators\n\t\t\tvar input = [],\n\t\t\t\tresults = [],\n\t\t\t\tmatcher = compile( selector.replace( rtrim, \"$1\" ) );\n\n\t\t\treturn matcher[ expando ] ?\n\t\t\t\tmarkFunction(function( seed, matches, context, xml ) {\n\t\t\t\t\tvar elem,\n\t\t\t\t\t\tunmatched = matcher( seed, null, xml, [] ),\n\t\t\t\t\t\ti = seed.length;\n\n\t\t\t\t\t// Match elements unmatched by `matcher`\n\t\t\t\t\twhile ( i-- ) {\n\t\t\t\t\t\tif ( (elem = unmatched[i]) ) {\n\t\t\t\t\t\t\tseed[i] = !(matches[i] = elem);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}) :\n\t\t\t\tfunction( elem, context, xml ) {\n\t\t\t\t\tinput[0] = elem;\n\t\t\t\t\tmatcher( input, null, xml, results );\n\t\t\t\t\t// Don't keep the element (issue #299)\n\t\t\t\t\tinput[0] = null;\n\t\t\t\t\treturn !results.pop();\n\t\t\t\t};\n\t\t}),\n\n\t\t\"has\": markFunction(function( selector ) {\n\t\t\treturn function( elem ) {\n\t\t\t\treturn Sizzle( selector, elem ).length > 0;\n\t\t\t};\n\t\t}),\n\n\t\t\"contains\": markFunction(function( text ) {\n\t\t\ttext = text.replace( runescape, funescape );\n\t\t\treturn function( elem ) {\n\t\t\t\treturn ( elem.textContent || elem.innerText || getText( elem ) ).indexOf( text ) > -1;\n\t\t\t};\n\t\t}),\n\n\t\t// \"Whether an element is represented by a :lang() selector\n\t\t// is based solely on the element's language value\n\t\t// being equal to the identifier C,\n\t\t// or beginning with the identifier C immediately followed by \"-\".\n\t\t// The matching of C against the element's language value is performed case-insensitively.\n\t\t// The identifier C does not have to be a valid language name.\"\n\t\t// http://www.w3.org/TR/selectors/#lang-pseudo\n\t\t\"lang\": markFunction( function( lang ) {\n\t\t\t// lang value must be a valid identifier\n\t\t\tif ( !ridentifier.test(lang || \"\") ) {\n\t\t\t\tSizzle.error( \"unsupported lang: \" + lang );\n\t\t\t}\n\t\t\tlang = lang.replace( runescape, funescape ).toLowerCase();\n\t\t\treturn function( elem ) {\n\t\t\t\tvar elemLang;\n\t\t\t\tdo {\n\t\t\t\t\tif ( (elemLang = documentIsHTML ?\n\t\t\t\t\t\telem.lang :\n\t\t\t\t\t\telem.getAttribute(\"xml:lang\") || elem.getAttribute(\"lang\")) ) {\n\n\t\t\t\t\t\telemLang = elemLang.toLowerCase();\n\t\t\t\t\t\treturn elemLang === lang || elemLang.indexOf( lang + \"-\" ) === 0;\n\t\t\t\t\t}\n\t\t\t\t} while ( (elem = elem.parentNode) && elem.nodeType === 1 );\n\t\t\t\treturn false;\n\t\t\t};\n\t\t}),\n\n\t\t// Miscellaneous\n\t\t\"target\": function( elem ) {\n\t\t\tvar hash = window.location && window.location.hash;\n\t\t\treturn hash && hash.slice( 1 ) === elem.id;\n\t\t},\n\n\t\t\"root\": function( elem ) {\n\t\t\treturn elem === docElem;\n\t\t},\n\n\t\t\"focus\": function( elem ) {\n\t\t\treturn elem === document.activeElement && (!document.hasFocus || document.hasFocus()) && !!(elem.type || elem.href || ~elem.tabIndex);\n\t\t},\n\n\t\t// Boolean properties\n\t\t\"enabled\": function( elem ) {\n\t\t\treturn elem.disabled === false;\n\t\t},\n\n\t\t\"disabled\": function( elem ) {\n\t\t\treturn elem.disabled === true;\n\t\t},\n\n\t\t\"checked\": function( elem ) {\n\t\t\t// In CSS3, :checked should return both checked and selected elements\n\t\t\t// http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked\n\t\t\tvar nodeName = elem.nodeName.toLowerCase();\n\t\t\treturn (nodeName === \"input\" && !!elem.checked) || (nodeName === \"option\" && !!elem.selected);\n\t\t},\n\n\t\t\"selected\": function( elem ) {\n\t\t\t// Accessing this property makes selected-by-default\n\t\t\t// options in Safari work properly\n\t\t\tif ( elem.parentNode ) {\n\t\t\t\telem.parentNode.selectedIndex;\n\t\t\t}\n\n\t\t\treturn elem.selected === true;\n\t\t},\n\n\t\t// Contents\n\t\t\"empty\": function( elem ) {\n\t\t\t// http://www.w3.org/TR/selectors/#empty-pseudo\n\t\t\t// :empty is negated by element (1) or content nodes (text: 3; cdata: 4; entity ref: 5),\n\t\t\t//   but not by others (comment: 8; processing instruction: 7; etc.)\n\t\t\t// nodeType < 6 works because attributes (2) do not appear as children\n\t\t\tfor ( elem = elem.firstChild; elem; elem = elem.nextSibling ) {\n\t\t\t\tif ( elem.nodeType < 6 ) {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn true;\n\t\t},\n\n\t\t\"parent\": function( elem ) {\n\t\t\treturn !Expr.pseudos[\"empty\"]( elem );\n\t\t},\n\n\t\t// Element/input types\n\t\t\"header\": function( elem ) {\n\t\t\treturn rheader.test( elem.nodeName );\n\t\t},\n\n\t\t\"input\": function( elem ) {\n\t\t\treturn rinputs.test( elem.nodeName );\n\t\t},\n\n\t\t\"button\": function( elem ) {\n\t\t\tvar name = elem.nodeName.toLowerCase();\n\t\t\treturn name === \"input\" && elem.type === \"button\" || name === \"button\";\n\t\t},\n\n\t\t\"text\": function( elem ) {\n\t\t\tvar attr;\n\t\t\treturn elem.nodeName.toLowerCase() === \"input\" &&\n\t\t\t\telem.type === \"text\" &&\n\n\t\t\t\t// Support: IE<8\n\t\t\t\t// New HTML5 attribute values (e.g., \"search\") appear with elem.type === \"text\"\n\t\t\t\t( (attr = elem.getAttribute(\"type\")) == null || attr.toLowerCase() === \"text\" );\n\t\t},\n\n\t\t// Position-in-collection\n\t\t\"first\": createPositionalPseudo(function() {\n\t\t\treturn [ 0 ];\n\t\t}),\n\n\t\t\"last\": createPositionalPseudo(function( matchIndexes, length ) {\n\t\t\treturn [ length - 1 ];\n\t\t}),\n\n\t\t\"eq\": createPositionalPseudo(function( matchIndexes, length, argument ) {\n\t\t\treturn [ argument < 0 ? argument + length : argument ];\n\t\t}),\n\n\t\t\"even\": createPositionalPseudo(function( matchIndexes, length ) {\n\t\t\tvar i = 0;\n\t\t\tfor ( ; i < length; i += 2 ) {\n\t\t\t\tmatchIndexes.push( i );\n\t\t\t}\n\t\t\treturn matchIndexes;\n\t\t}),\n\n\t\t\"odd\": createPositionalPseudo(function( matchIndexes, length ) {\n\t\t\tvar i = 1;\n\t\t\tfor ( ; i < length; i += 2 ) {\n\t\t\t\tmatchIndexes.push( i );\n\t\t\t}\n\t\t\treturn matchIndexes;\n\t\t}),\n\n\t\t\"lt\": createPositionalPseudo(function( matchIndexes, length, argument ) {\n\t\t\tvar i = argument < 0 ? argument + length : argument;\n\t\t\tfor ( ; --i >= 0; ) {\n\t\t\t\tmatchIndexes.push( i );\n\t\t\t}\n\t\t\treturn matchIndexes;\n\t\t}),\n\n\t\t\"gt\": createPositionalPseudo(function( matchIndexes, length, argument ) {\n\t\t\tvar i = argument < 0 ? argument + length : argument;\n\t\t\tfor ( ; ++i < length; ) {\n\t\t\t\tmatchIndexes.push( i );\n\t\t\t}\n\t\t\treturn matchIndexes;\n\t\t})\n\t}\n};\n\nExpr.pseudos[\"nth\"] = Expr.pseudos[\"eq\"];\n\n// Add button/input type pseudos\nfor ( i in { radio: true, checkbox: true, file: true, password: true, image: true } ) {\n\tExpr.pseudos[ i ] = createInputPseudo( i );\n}\nfor ( i in { submit: true, reset: true } ) {\n\tExpr.pseudos[ i ] = createButtonPseudo( i );\n}\n\n// Easy API for creating new setFilters\nfunction setFilters() {}\nsetFilters.prototype = Expr.filters = Expr.pseudos;\nExpr.setFilters = new setFilters();\n\ntokenize = Sizzle.tokenize = function( selector, parseOnly ) {\n\tvar matched, match, tokens, type,\n\t\tsoFar, groups, preFilters,\n\t\tcached = tokenCache[ selector + \" \" ];\n\n\tif ( cached ) {\n\t\treturn parseOnly ? 0 : cached.slice( 0 );\n\t}\n\n\tsoFar = selector;\n\tgroups = [];\n\tpreFilters = Expr.preFilter;\n\n\twhile ( soFar ) {\n\n\t\t// Comma and first run\n\t\tif ( !matched || (match = rcomma.exec( soFar )) ) {\n\t\t\tif ( match ) {\n\t\t\t\t// Don't consume trailing commas as valid\n\t\t\t\tsoFar = soFar.slice( match[0].length ) || soFar;\n\t\t\t}\n\t\t\tgroups.push( (tokens = []) );\n\t\t}\n\n\t\tmatched = false;\n\n\t\t// Combinators\n\t\tif ( (match = rcombinators.exec( soFar )) ) {\n\t\t\tmatched = match.shift();\n\t\t\ttokens.push({\n\t\t\t\tvalue: matched,\n\t\t\t\t// Cast descendant combinators to space\n\t\t\t\ttype: match[0].replace( rtrim, \" \" )\n\t\t\t});\n\t\t\tsoFar = soFar.slice( matched.length );\n\t\t}\n\n\t\t// Filters\n\t\tfor ( type in Expr.filter ) {\n\t\t\tif ( (match = matchExpr[ type ].exec( soFar )) && (!preFilters[ type ] ||\n\t\t\t\t(match = preFilters[ type ]( match ))) ) {\n\t\t\t\tmatched = match.shift();\n\t\t\t\ttokens.push({\n\t\t\t\t\tvalue: matched,\n\t\t\t\t\ttype: type,\n\t\t\t\t\tmatches: match\n\t\t\t\t});\n\t\t\t\tsoFar = soFar.slice( matched.length );\n\t\t\t}\n\t\t}\n\n\t\tif ( !matched ) {\n\t\t\tbreak;\n\t\t}\n\t}\n\n\t// Return the length of the invalid excess\n\t// if we're just parsing\n\t// Otherwise, throw an error or return tokens\n\treturn parseOnly ?\n\t\tsoFar.length :\n\t\tsoFar ?\n\t\t\tSizzle.error( selector ) :\n\t\t\t// Cache the tokens\n\t\t\ttokenCache( selector, groups ).slice( 0 );\n};\n\nfunction toSelector( tokens ) {\n\tvar i = 0,\n\t\tlen = tokens.length,\n\t\tselector = \"\";\n\tfor ( ; i < len; i++ ) {\n\t\tselector += tokens[i].value;\n\t}\n\treturn selector;\n}\n\nfunction addCombinator( matcher, combinator, base ) {\n\tvar dir = combinator.dir,\n\t\tcheckNonElements = base && dir === \"parentNode\",\n\t\tdoneName = done++;\n\n\treturn combinator.first ?\n\t\t// Check against closest ancestor/preceding element\n\t\tfunction( elem, context, xml ) {\n\t\t\twhile ( (elem = elem[ dir ]) ) {\n\t\t\t\tif ( elem.nodeType === 1 || checkNonElements ) {\n\t\t\t\t\treturn matcher( elem, context, xml );\n\t\t\t\t}\n\t\t\t}\n\t\t} :\n\n\t\t// Check against all ancestor/preceding elements\n\t\tfunction( elem, context, xml ) {\n\t\t\tvar oldCache, outerCache,\n\t\t\t\tnewCache = [ dirruns, doneName ];\n\n\t\t\t// We can't set arbitrary data on XML nodes, so they don't benefit from dir caching\n\t\t\tif ( xml ) {\n\t\t\t\twhile ( (elem = elem[ dir ]) ) {\n\t\t\t\t\tif ( elem.nodeType === 1 || checkNonElements ) {\n\t\t\t\t\t\tif ( matcher( elem, context, xml ) ) {\n\t\t\t\t\t\t\treturn true;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\twhile ( (elem = elem[ dir ]) ) {\n\t\t\t\t\tif ( elem.nodeType === 1 || checkNonElements ) {\n\t\t\t\t\t\touterCache = elem[ expando ] || (elem[ expando ] = {});\n\t\t\t\t\t\tif ( (oldCache = outerCache[ dir ]) &&\n\t\t\t\t\t\t\toldCache[ 0 ] === dirruns && oldCache[ 1 ] === doneName ) {\n\n\t\t\t\t\t\t\t// Assign to newCache so results back-propagate to previous elements\n\t\t\t\t\t\t\treturn (newCache[ 2 ] = oldCache[ 2 ]);\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t// Reuse newcache so results back-propagate to previous elements\n\t\t\t\t\t\t\touterCache[ dir ] = newCache;\n\n\t\t\t\t\t\t\t// A match means we're done; a fail means we have to keep checking\n\t\t\t\t\t\t\tif ( (newCache[ 2 ] = matcher( elem, context, xml )) ) {\n\t\t\t\t\t\t\t\treturn true;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t};\n}\n\nfunction elementMatcher( matchers ) {\n\treturn matchers.length > 1 ?\n\t\tfunction( elem, context, xml ) {\n\t\t\tvar i = matchers.length;\n\t\t\twhile ( i-- ) {\n\t\t\t\tif ( !matchers[i]( elem, context, xml ) ) {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn true;\n\t\t} :\n\t\tmatchers[0];\n}\n\nfunction multipleContexts( selector, contexts, results ) {\n\tvar i = 0,\n\t\tlen = contexts.length;\n\tfor ( ; i < len; i++ ) {\n\t\tSizzle( selector, contexts[i], results );\n\t}\n\treturn results;\n}\n\nfunction condense( unmatched, map, filter, context, xml ) {\n\tvar elem,\n\t\tnewUnmatched = [],\n\t\ti = 0,\n\t\tlen = unmatched.length,\n\t\tmapped = map != null;\n\n\tfor ( ; i < len; i++ ) {\n\t\tif ( (elem = unmatched[i]) ) {\n\t\t\tif ( !filter || filter( elem, context, xml ) ) {\n\t\t\t\tnewUnmatched.push( elem );\n\t\t\t\tif ( mapped ) {\n\t\t\t\t\tmap.push( i );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\treturn newUnmatched;\n}\n\nfunction setMatcher( preFilter, selector, matcher, postFilter, postFinder, postSelector ) {\n\tif ( postFilter && !postFilter[ expando ] ) {\n\t\tpostFilter = setMatcher( postFilter );\n\t}\n\tif ( postFinder && !postFinder[ expando ] ) {\n\t\tpostFinder = setMatcher( postFinder, postSelector );\n\t}\n\treturn markFunction(function( seed, results, context, xml ) {\n\t\tvar temp, i, elem,\n\t\t\tpreMap = [],\n\t\t\tpostMap = [],\n\t\t\tpreexisting = results.length,\n\n\t\t\t// Get initial elements from seed or context\n\t\t\telems = seed || multipleContexts( selector || \"*\", context.nodeType ? [ context ] : context, [] ),\n\n\t\t\t// Prefilter to get matcher input, preserving a map for seed-results synchronization\n\t\t\tmatcherIn = preFilter && ( seed || !selector ) ?\n\t\t\t\tcondense( elems, preMap, preFilter, context, xml ) :\n\t\t\t\telems,\n\n\t\t\tmatcherOut = matcher ?\n\t\t\t\t// If we have a postFinder, or filtered seed, or non-seed postFilter or preexisting results,\n\t\t\t\tpostFinder || ( seed ? preFilter : preexisting || postFilter ) ?\n\n\t\t\t\t\t// ...intermediate processing is necessary\n\t\t\t\t\t[] :\n\n\t\t\t\t\t// ...otherwise use results directly\n\t\t\t\t\tresults :\n\t\t\t\tmatcherIn;\n\n\t\t// Find primary matches\n\t\tif ( matcher ) {\n\t\t\tmatcher( matcherIn, matcherOut, context, xml );\n\t\t}\n\n\t\t// Apply postFilter\n\t\tif ( postFilter ) {\n\t\t\ttemp = condense( matcherOut, postMap );\n\t\t\tpostFilter( temp, [], context, xml );\n\n\t\t\t// Un-match failing elements by moving them back to matcherIn\n\t\t\ti = temp.length;\n\t\t\twhile ( i-- ) {\n\t\t\t\tif ( (elem = temp[i]) ) {\n\t\t\t\t\tmatcherOut[ postMap[i] ] = !(matcherIn[ postMap[i] ] = elem);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif ( seed ) {\n\t\t\tif ( postFinder || preFilter ) {\n\t\t\t\tif ( postFinder ) {\n\t\t\t\t\t// Get the final matcherOut by condensing this intermediate into postFinder contexts\n\t\t\t\t\ttemp = [];\n\t\t\t\t\ti = matcherOut.length;\n\t\t\t\t\twhile ( i-- ) {\n\t\t\t\t\t\tif ( (elem = matcherOut[i]) ) {\n\t\t\t\t\t\t\t// Restore matcherIn since elem is not yet a final match\n\t\t\t\t\t\t\ttemp.push( (matcherIn[i] = elem) );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tpostFinder( null, (matcherOut = []), temp, xml );\n\t\t\t\t}\n\n\t\t\t\t// Move matched elements from seed to results to keep them synchronized\n\t\t\t\ti = matcherOut.length;\n\t\t\t\twhile ( i-- ) {\n\t\t\t\t\tif ( (elem = matcherOut[i]) &&\n\t\t\t\t\t\t(temp = postFinder ? indexOf( seed, elem ) : preMap[i]) > -1 ) {\n\n\t\t\t\t\t\tseed[temp] = !(results[temp] = elem);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t// Add elements to results, through postFinder if defined\n\t\t} else {\n\t\t\tmatcherOut = condense(\n\t\t\t\tmatcherOut === results ?\n\t\t\t\t\tmatcherOut.splice( preexisting, matcherOut.length ) :\n\t\t\t\t\tmatcherOut\n\t\t\t);\n\t\t\tif ( postFinder ) {\n\t\t\t\tpostFinder( null, results, matcherOut, xml );\n\t\t\t} else {\n\t\t\t\tpush.apply( results, matcherOut );\n\t\t\t}\n\t\t}\n\t});\n}\n\nfunction matcherFromTokens( tokens ) {\n\tvar checkContext, matcher, j,\n\t\tlen = tokens.length,\n\t\tleadingRelative = Expr.relative[ tokens[0].type ],\n\t\timplicitRelative = leadingRelative || Expr.relative[\" \"],\n\t\ti = leadingRelative ? 1 : 0,\n\n\t\t// The foundational matcher ensures that elements are reachable from top-level context(s)\n\t\tmatchContext = addCombinator( function( elem ) {\n\t\t\treturn elem === checkContext;\n\t\t}, implicitRelative, true ),\n\t\tmatchAnyContext = addCombinator( function( elem ) {\n\t\t\treturn indexOf( checkContext, elem ) > -1;\n\t\t}, implicitRelative, true ),\n\t\tmatchers = [ function( elem, context, xml ) {\n\t\t\tvar ret = ( !leadingRelative && ( xml || context !== outermostContext ) ) || (\n\t\t\t\t(checkContext = context).nodeType ?\n\t\t\t\t\tmatchContext( elem, context, xml ) :\n\t\t\t\t\tmatchAnyContext( elem, context, xml ) );\n\t\t\t// Avoid hanging onto element (issue #299)\n\t\t\tcheckContext = null;\n\t\t\treturn ret;\n\t\t} ];\n\n\tfor ( ; i < len; i++ ) {\n\t\tif ( (matcher = Expr.relative[ tokens[i].type ]) ) {\n\t\t\tmatchers = [ addCombinator(elementMatcher( matchers ), matcher) ];\n\t\t} else {\n\t\t\tmatcher = Expr.filter[ tokens[i].type ].apply( null, tokens[i].matches );\n\n\t\t\t// Return special upon seeing a positional matcher\n\t\t\tif ( matcher[ expando ] ) {\n\t\t\t\t// Find the next relative operator (if any) for proper handling\n\t\t\t\tj = ++i;\n\t\t\t\tfor ( ; j < len; j++ ) {\n\t\t\t\t\tif ( Expr.relative[ tokens[j].type ] ) {\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn setMatcher(\n\t\t\t\t\ti > 1 && elementMatcher( matchers ),\n\t\t\t\t\ti > 1 && toSelector(\n\t\t\t\t\t\t// If the preceding token was a descendant combinator, insert an implicit any-element `*`\n\t\t\t\t\t\ttokens.slice( 0, i - 1 ).concat({ value: tokens[ i - 2 ].type === \" \" ? \"*\" : \"\" })\n\t\t\t\t\t).replace( rtrim, \"$1\" ),\n\t\t\t\t\tmatcher,\n\t\t\t\t\ti < j && matcherFromTokens( tokens.slice( i, j ) ),\n\t\t\t\t\tj < len && matcherFromTokens( (tokens = tokens.slice( j )) ),\n\t\t\t\t\tj < len && toSelector( tokens )\n\t\t\t\t);\n\t\t\t}\n\t\t\tmatchers.push( matcher );\n\t\t}\n\t}\n\n\treturn elementMatcher( matchers );\n}\n\nfunction matcherFromGroupMatchers( elementMatchers, setMatchers ) {\n\tvar bySet = setMatchers.length > 0,\n\t\tbyElement = elementMatchers.length > 0,\n\t\tsuperMatcher = function( seed, context, xml, results, outermost ) {\n\t\t\tvar elem, j, matcher,\n\t\t\t\tmatchedCount = 0,\n\t\t\t\ti = \"0\",\n\t\t\t\tunmatched = seed && [],\n\t\t\t\tsetMatched = [],\n\t\t\t\tcontextBackup = outermostContext,\n\t\t\t\t// We must always have either seed elements or outermost context\n\t\t\t\telems = seed || byElement && Expr.find[\"TAG\"]( \"*\", outermost ),\n\t\t\t\t// Use integer dirruns iff this is the outermost matcher\n\t\t\t\tdirrunsUnique = (dirruns += contextBackup == null ? 1 : Math.random() || 0.1),\n\t\t\t\tlen = elems.length;\n\n\t\t\tif ( outermost ) {\n\t\t\t\toutermostContext = context !== document && context;\n\t\t\t}\n\n\t\t\t// Add elements passing elementMatchers directly to results\n\t\t\t// Keep `i` a string if there are no elements so `matchedCount` will be \"00\" below\n\t\t\t// Support: IE<9, Safari\n\t\t\t// Tolerate NodeList properties (IE: \"length\"; Safari: <number>) matching elements by id\n\t\t\tfor ( ; i !== len && (elem = elems[i]) != null; i++ ) {\n\t\t\t\tif ( byElement && elem ) {\n\t\t\t\t\tj = 0;\n\t\t\t\t\twhile ( (matcher = elementMatchers[j++]) ) {\n\t\t\t\t\t\tif ( matcher( elem, context, xml ) ) {\n\t\t\t\t\t\t\tresults.push( elem );\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tif ( outermost ) {\n\t\t\t\t\t\tdirruns = dirrunsUnique;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// Track unmatched elements for set filters\n\t\t\t\tif ( bySet ) {\n\t\t\t\t\t// They will have gone through all possible matchers\n\t\t\t\t\tif ( (elem = !matcher && elem) ) {\n\t\t\t\t\t\tmatchedCount--;\n\t\t\t\t\t}\n\n\t\t\t\t\t// Lengthen the array for every element, matched or not\n\t\t\t\t\tif ( seed ) {\n\t\t\t\t\t\tunmatched.push( elem );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Apply set filters to unmatched elements\n\t\t\tmatchedCount += i;\n\t\t\tif ( bySet && i !== matchedCount ) {\n\t\t\t\tj = 0;\n\t\t\t\twhile ( (matcher = setMatchers[j++]) ) {\n\t\t\t\t\tmatcher( unmatched, setMatched, context, xml );\n\t\t\t\t}\n\n\t\t\t\tif ( seed ) {\n\t\t\t\t\t// Reintegrate element matches to eliminate the need for sorting\n\t\t\t\t\tif ( matchedCount > 0 ) {\n\t\t\t\t\t\twhile ( i-- ) {\n\t\t\t\t\t\t\tif ( !(unmatched[i] || setMatched[i]) ) {\n\t\t\t\t\t\t\t\tsetMatched[i] = pop.call( results );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\t// Discard index placeholder values to get only actual matches\n\t\t\t\t\tsetMatched = condense( setMatched );\n\t\t\t\t}\n\n\t\t\t\t// Add matches to results\n\t\t\t\tpush.apply( results, setMatched );\n\n\t\t\t\t// Seedless set matches succeeding multiple successful matchers stipulate sorting\n\t\t\t\tif ( outermost && !seed && setMatched.length > 0 &&\n\t\t\t\t\t( matchedCount + setMatchers.length ) > 1 ) {\n\n\t\t\t\t\tSizzle.uniqueSort( results );\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Override manipulation of globals by nested matchers\n\t\t\tif ( outermost ) {\n\t\t\t\tdirruns = dirrunsUnique;\n\t\t\t\toutermostContext = contextBackup;\n\t\t\t}\n\n\t\t\treturn unmatched;\n\t\t};\n\n\treturn bySet ?\n\t\tmarkFunction( superMatcher ) :\n\t\tsuperMatcher;\n}\n\ncompile = Sizzle.compile = function( selector, match /* Internal Use Only */ ) {\n\tvar i,\n\t\tsetMatchers = [],\n\t\telementMatchers = [],\n\t\tcached = compilerCache[ selector + \" \" ];\n\n\tif ( !cached ) {\n\t\t// Generate a function of recursive functions that can be used to check each element\n\t\tif ( !match ) {\n\t\t\tmatch = tokenize( selector );\n\t\t}\n\t\ti = match.length;\n\t\twhile ( i-- ) {\n\t\t\tcached = matcherFromTokens( match[i] );\n\t\t\tif ( cached[ expando ] ) {\n\t\t\t\tsetMatchers.push( cached );\n\t\t\t} else {\n\t\t\t\telementMatchers.push( cached );\n\t\t\t}\n\t\t}\n\n\t\t// Cache the compiled function\n\t\tcached = compilerCache( selector, matcherFromGroupMatchers( elementMatchers, setMatchers ) );\n\n\t\t// Save selector and tokenization\n\t\tcached.selector = selector;\n\t}\n\treturn cached;\n};\n\n/**\n * A low-level selection function that works with Sizzle's compiled\n *  selector functions\n * @param {String|Function} selector A selector or a pre-compiled\n *  selector function built with Sizzle.compile\n * @param {Element} context\n * @param {Array} [results]\n * @param {Array} [seed] A set of elements to match against\n */\nselect = Sizzle.select = function( selector, context, results, seed ) {\n\tvar i, tokens, token, type, find,\n\t\tcompiled = typeof selector === \"function\" && selector,\n\t\tmatch = !seed && tokenize( (selector = compiled.selector || selector) );\n\n\tresults = results || [];\n\n\t// Try to minimize operations if there is no seed and only one group\n\tif ( match.length === 1 ) {\n\n\t\t// Take a shortcut and set the context if the root selector is an ID\n\t\ttokens = match[0] = match[0].slice( 0 );\n\t\tif ( tokens.length > 2 && (token = tokens[0]).type === \"ID\" &&\n\t\t\t\tsupport.getById && context.nodeType === 9 && documentIsHTML &&\n\t\t\t\tExpr.relative[ tokens[1].type ] ) {\n\n\t\t\tcontext = ( Expr.find[\"ID\"]( token.matches[0].replace(runescape, funescape), context ) || [] )[0];\n\t\t\tif ( !context ) {\n\t\t\t\treturn results;\n\n\t\t\t// Precompiled matchers will still verify ancestry, so step up a level\n\t\t\t} else if ( compiled ) {\n\t\t\t\tcontext = context.parentNode;\n\t\t\t}\n\n\t\t\tselector = selector.slice( tokens.shift().value.length );\n\t\t}\n\n\t\t// Fetch a seed set for right-to-left matching\n\t\ti = matchExpr[\"needsContext\"].test( selector ) ? 0 : tokens.length;\n\t\twhile ( i-- ) {\n\t\t\ttoken = tokens[i];\n\n\t\t\t// Abort if we hit a combinator\n\t\t\tif ( Expr.relative[ (type = token.type) ] ) {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tif ( (find = Expr.find[ type ]) ) {\n\t\t\t\t// Search, expanding context for leading sibling combinators\n\t\t\t\tif ( (seed = find(\n\t\t\t\t\ttoken.matches[0].replace( runescape, funescape ),\n\t\t\t\t\trsibling.test( tokens[0].type ) && testContext( context.parentNode ) || context\n\t\t\t\t)) ) {\n\n\t\t\t\t\t// If seed is empty or no tokens remain, we can return early\n\t\t\t\t\ttokens.splice( i, 1 );\n\t\t\t\t\tselector = seed.length && toSelector( tokens );\n\t\t\t\t\tif ( !selector ) {\n\t\t\t\t\t\tpush.apply( results, seed );\n\t\t\t\t\t\treturn results;\n\t\t\t\t\t}\n\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t// Compile and execute a filtering function if one is not provided\n\t// Provide `match` to avoid retokenization if we modified the selector above\n\t( compiled || compile( selector, match ) )(\n\t\tseed,\n\t\tcontext,\n\t\t!documentIsHTML,\n\t\tresults,\n\t\trsibling.test( selector ) && testContext( context.parentNode ) || context\n\t);\n\treturn results;\n};\n\n// One-time assignments\n\n// Sort stability\nsupport.sortStable = expando.split(\"\").sort( sortOrder ).join(\"\") === expando;\n\n// Support: Chrome 14-35+\n// Always assume duplicates if they aren't passed to the comparison function\nsupport.detectDuplicates = !!hasDuplicate;\n\n// Initialize against the default document\nsetDocument();\n\n// Support: Webkit<537.32 - Safari 6.0.3/Chrome 25 (fixed in Chrome 27)\n// Detached nodes confoundingly follow *each other*\nsupport.sortDetached = assert(function( div1 ) {\n\t// Should return 1, but returns 4 (following)\n\treturn div1.compareDocumentPosition( document.createElement(\"div\") ) & 1;\n});\n\n// Support: IE<8\n// Prevent attribute/property \"interpolation\"\n// http://msdn.microsoft.com/en-us/library/ms536429%28VS.85%29.aspx\nif ( !assert(function( div ) {\n\tdiv.innerHTML = \"<a href='#'></a>\";\n\treturn div.firstChild.getAttribute(\"href\") === \"#\" ;\n}) ) {\n\taddHandle( \"type|href|height|width\", function( elem, name, isXML ) {\n\t\tif ( !isXML ) {\n\t\t\treturn elem.getAttribute( name, name.toLowerCase() === \"type\" ? 1 : 2 );\n\t\t}\n\t});\n}\n\n// Support: IE<9\n// Use defaultValue in place of getAttribute(\"value\")\nif ( !support.attributes || !assert(function( div ) {\n\tdiv.innerHTML = \"<input/>\";\n\tdiv.firstChild.setAttribute( \"value\", \"\" );\n\treturn div.firstChild.getAttribute( \"value\" ) === \"\";\n}) ) {\n\taddHandle( \"value\", function( elem, name, isXML ) {\n\t\tif ( !isXML && elem.nodeName.toLowerCase() === \"input\" ) {\n\t\t\treturn elem.defaultValue;\n\t\t}\n\t});\n}\n\n// Support: IE<9\n// Use getAttributeNode to fetch booleans when getAttribute lies\nif ( !assert(function( div ) {\n\treturn div.getAttribute(\"disabled\") == null;\n}) ) {\n\taddHandle( booleans, function( elem, name, isXML ) {\n\t\tvar val;\n\t\tif ( !isXML ) {\n\t\t\treturn elem[ name ] === true ? name.toLowerCase() :\n\t\t\t\t\t(val = elem.getAttributeNode( name )) && val.specified ?\n\t\t\t\t\tval.value :\n\t\t\t\tnull;\n\t\t}\n\t});\n}\n\nreturn Sizzle;\n\n})( window );\n\n\n\njQuery.find = Sizzle;\njQuery.expr = Sizzle.selectors;\njQuery.expr[\":\"] = jQuery.expr.pseudos;\njQuery.unique = Sizzle.uniqueSort;\njQuery.text = Sizzle.getText;\njQuery.isXMLDoc = Sizzle.isXML;\njQuery.contains = Sizzle.contains;\n\n\n\nvar rneedsContext = jQuery.expr.match.needsContext;\n\nvar rsingleTag = (/^<(\\w+)\\s*\\/?>(?:<\\/\\1>|)$/);\n\n\n\nvar risSimple = /^.[^:#\\[\\.,]*$/;\n\n// Implement the identical functionality for filter and not\nfunction winnow( elements, qualifier, not ) {\n\tif ( jQuery.isFunction( qualifier ) ) {\n\t\treturn jQuery.grep( elements, function( elem, i ) {\n\t\t\t/* jshint -W018 */\n\t\t\treturn !!qualifier.call( elem, i, elem ) !== not;\n\t\t});\n\n\t}\n\n\tif ( qualifier.nodeType ) {\n\t\treturn jQuery.grep( elements, function( elem ) {\n\t\t\treturn ( elem === qualifier ) !== not;\n\t\t});\n\n\t}\n\n\tif ( typeof qualifier === \"string\" ) {\n\t\tif ( risSimple.test( qualifier ) ) {\n\t\t\treturn jQuery.filter( qualifier, elements, not );\n\t\t}\n\n\t\tqualifier = jQuery.filter( qualifier, elements );\n\t}\n\n\treturn jQuery.grep( elements, function( elem ) {\n\t\treturn ( jQuery.inArray( elem, qualifier ) >= 0 ) !== not;\n\t});\n}\n\njQuery.filter = function( expr, elems, not ) {\n\tvar elem = elems[ 0 ];\n\n\tif ( not ) {\n\t\texpr = \":not(\" + expr + \")\";\n\t}\n\n\treturn elems.length === 1 && elem.nodeType === 1 ?\n\t\tjQuery.find.matchesSelector( elem, expr ) ? [ elem ] : [] :\n\t\tjQuery.find.matches( expr, jQuery.grep( elems, function( elem ) {\n\t\t\treturn elem.nodeType === 1;\n\t\t}));\n};\n\njQuery.fn.extend({\n\tfind: function( selector ) {\n\t\tvar i,\n\t\t\tret = [],\n\t\t\tself = this,\n\t\t\tlen = self.length;\n\n\t\tif ( typeof selector !== \"string\" ) {\n\t\t\treturn this.pushStack( jQuery( selector ).filter(function() {\n\t\t\t\tfor ( i = 0; i < len; i++ ) {\n\t\t\t\t\tif ( jQuery.contains( self[ i ], this ) ) {\n\t\t\t\t\t\treturn true;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}) );\n\t\t}\n\n\t\tfor ( i = 0; i < len; i++ ) {\n\t\t\tjQuery.find( selector, self[ i ], ret );\n\t\t}\n\n\t\t// Needed because $( selector, context ) becomes $( context ).find( selector )\n\t\tret = this.pushStack( len > 1 ? jQuery.unique( ret ) : ret );\n\t\tret.selector = this.selector ? this.selector + \" \" + selector : selector;\n\t\treturn ret;\n\t},\n\tfilter: function( selector ) {\n\t\treturn this.pushStack( winnow(this, selector || [], false) );\n\t},\n\tnot: function( selector ) {\n\t\treturn this.pushStack( winnow(this, selector || [], true) );\n\t},\n\tis: function( selector ) {\n\t\treturn !!winnow(\n\t\t\tthis,\n\n\t\t\t// If this is a positional/relative selector, check membership in the returned set\n\t\t\t// so $(\"p:first\").is(\"p:last\") won't return true for a doc with two \"p\".\n\t\t\ttypeof selector === \"string\" && rneedsContext.test( selector ) ?\n\t\t\t\tjQuery( selector ) :\n\t\t\t\tselector || [],\n\t\t\tfalse\n\t\t).length;\n\t}\n});\n\n\n// Initialize a jQuery object\n\n\n// A central reference to the root jQuery(document)\nvar rootjQuery,\n\n\t// Use the correct document accordingly with window argument (sandbox)\n\tdocument = window.document,\n\n\t// A simple way to check for HTML strings\n\t// Prioritize #id over <tag> to avoid XSS via location.hash (#9521)\n\t// Strict HTML recognition (#11290: must start with <)\n\trquickExpr = /^(?:\\s*(<[\\w\\W]+>)[^>]*|#([\\w-]*))$/,\n\n\tinit = jQuery.fn.init = function( selector, context ) {\n\t\tvar match, elem;\n\n\t\t// HANDLE: $(\"\"), $(null), $(undefined), $(false)\n\t\tif ( !selector ) {\n\t\t\treturn this;\n\t\t}\n\n\t\t// Handle HTML strings\n\t\tif ( typeof selector === \"string\" ) {\n\t\t\tif ( selector.charAt(0) === \"<\" && selector.charAt( selector.length - 1 ) === \">\" && selector.length >= 3 ) {\n\t\t\t\t// Assume that strings that start and end with <> are HTML and skip the regex check\n\t\t\t\tmatch = [ null, selector, null ];\n\n\t\t\t} else {\n\t\t\t\tmatch = rquickExpr.exec( selector );\n\t\t\t}\n\n\t\t\t// Match html or make sure no context is specified for #id\n\t\t\tif ( match && (match[1] || !context) ) {\n\n\t\t\t\t// HANDLE: $(html) -> $(array)\n\t\t\t\tif ( match[1] ) {\n\t\t\t\t\tcontext = context instanceof jQuery ? context[0] : context;\n\n\t\t\t\t\t// scripts is true for back-compat\n\t\t\t\t\t// Intentionally let the error be thrown if parseHTML is not present\n\t\t\t\t\tjQuery.merge( this, jQuery.parseHTML(\n\t\t\t\t\t\tmatch[1],\n\t\t\t\t\t\tcontext && context.nodeType ? context.ownerDocument || context : document,\n\t\t\t\t\t\ttrue\n\t\t\t\t\t) );\n\n\t\t\t\t\t// HANDLE: $(html, props)\n\t\t\t\t\tif ( rsingleTag.test( match[1] ) && jQuery.isPlainObject( context ) ) {\n\t\t\t\t\t\tfor ( match in context ) {\n\t\t\t\t\t\t\t// Properties of context are called as methods if possible\n\t\t\t\t\t\t\tif ( jQuery.isFunction( this[ match ] ) ) {\n\t\t\t\t\t\t\t\tthis[ match ]( context[ match ] );\n\n\t\t\t\t\t\t\t// ...and otherwise set as attributes\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tthis.attr( match, context[ match ] );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\treturn this;\n\n\t\t\t\t// HANDLE: $(#id)\n\t\t\t\t} else {\n\t\t\t\t\telem = document.getElementById( match[2] );\n\n\t\t\t\t\t// Check parentNode to catch when Blackberry 4.6 returns\n\t\t\t\t\t// nodes that are no longer in the document #6963\n\t\t\t\t\tif ( elem && elem.parentNode ) {\n\t\t\t\t\t\t// Handle the case where IE and Opera return items\n\t\t\t\t\t\t// by name instead of ID\n\t\t\t\t\t\tif ( elem.id !== match[2] ) {\n\t\t\t\t\t\t\treturn rootjQuery.find( selector );\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// Otherwise, we inject the element directly into the jQuery object\n\t\t\t\t\t\tthis.length = 1;\n\t\t\t\t\t\tthis[0] = elem;\n\t\t\t\t\t}\n\n\t\t\t\t\tthis.context = document;\n\t\t\t\t\tthis.selector = selector;\n\t\t\t\t\treturn this;\n\t\t\t\t}\n\n\t\t\t// HANDLE: $(expr, $(...))\n\t\t\t} else if ( !context || context.jquery ) {\n\t\t\t\treturn ( context || rootjQuery ).find( selector );\n\n\t\t\t// HANDLE: $(expr, context)\n\t\t\t// (which is just equivalent to: $(context).find(expr)\n\t\t\t} else {\n\t\t\t\treturn this.constructor( context ).find( selector );\n\t\t\t}\n\n\t\t// HANDLE: $(DOMElement)\n\t\t} else if ( selector.nodeType ) {\n\t\t\tthis.context = this[0] = selector;\n\t\t\tthis.length = 1;\n\t\t\treturn this;\n\n\t\t// HANDLE: $(function)\n\t\t// Shortcut for document ready\n\t\t} else if ( jQuery.isFunction( selector ) ) {\n\t\t\treturn typeof rootjQuery.ready !== \"undefined\" ?\n\t\t\t\trootjQuery.ready( selector ) :\n\t\t\t\t// Execute immediately if ready is not present\n\t\t\t\tselector( jQuery );\n\t\t}\n\n\t\tif ( selector.selector !== undefined ) {\n\t\t\tthis.selector = selector.selector;\n\t\t\tthis.context = selector.context;\n\t\t}\n\n\t\treturn jQuery.makeArray( selector, this );\n\t};\n\n// Give the init function the jQuery prototype for later instantiation\ninit.prototype = jQuery.fn;\n\n// Initialize central reference\nrootjQuery = jQuery( document );\n\n\nvar rparentsprev = /^(?:parents|prev(?:Until|All))/,\n\t// methods guaranteed to produce a unique set when starting from a unique set\n\tguaranteedUnique = {\n\t\tchildren: true,\n\t\tcontents: true,\n\t\tnext: true,\n\t\tprev: true\n\t};\n\njQuery.extend({\n\tdir: function( elem, dir, until ) {\n\t\tvar matched = [],\n\t\t\tcur = elem[ dir ];\n\n\t\twhile ( cur && cur.nodeType !== 9 && (until === undefined || cur.nodeType !== 1 || !jQuery( cur ).is( until )) ) {\n\t\t\tif ( cur.nodeType === 1 ) {\n\t\t\t\tmatched.push( cur );\n\t\t\t}\n\t\t\tcur = cur[dir];\n\t\t}\n\t\treturn matched;\n\t},\n\n\tsibling: function( n, elem ) {\n\t\tvar r = [];\n\n\t\tfor ( ; n; n = n.nextSibling ) {\n\t\t\tif ( n.nodeType === 1 && n !== elem ) {\n\t\t\t\tr.push( n );\n\t\t\t}\n\t\t}\n\n\t\treturn r;\n\t}\n});\n\njQuery.fn.extend({\n\thas: function( target ) {\n\t\tvar i,\n\t\t\ttargets = jQuery( target, this ),\n\t\t\tlen = targets.length;\n\n\t\treturn this.filter(function() {\n\t\t\tfor ( i = 0; i < len; i++ ) {\n\t\t\t\tif ( jQuery.contains( this, targets[i] ) ) {\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\t},\n\n\tclosest: function( selectors, context ) {\n\t\tvar cur,\n\t\t\ti = 0,\n\t\t\tl = this.length,\n\t\t\tmatched = [],\n\t\t\tpos = rneedsContext.test( selectors ) || typeof selectors !== \"string\" ?\n\t\t\t\tjQuery( selectors, context || this.context ) :\n\t\t\t\t0;\n\n\t\tfor ( ; i < l; i++ ) {\n\t\t\tfor ( cur = this[i]; cur && cur !== context; cur = cur.parentNode ) {\n\t\t\t\t// Always skip document fragments\n\t\t\t\tif ( cur.nodeType < 11 && (pos ?\n\t\t\t\t\tpos.index(cur) > -1 :\n\n\t\t\t\t\t// Don't pass non-elements to Sizzle\n\t\t\t\t\tcur.nodeType === 1 &&\n\t\t\t\t\t\tjQuery.find.matchesSelector(cur, selectors)) ) {\n\n\t\t\t\t\tmatched.push( cur );\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn this.pushStack( matched.length > 1 ? jQuery.unique( matched ) : matched );\n\t},\n\n\t// Determine the position of an element within\n\t// the matched set of elements\n\tindex: function( elem ) {\n\n\t\t// No argument, return index in parent\n\t\tif ( !elem ) {\n\t\t\treturn ( this[0] && this[0].parentNode ) ? this.first().prevAll().length : -1;\n\t\t}\n\n\t\t// index in selector\n\t\tif ( typeof elem === \"string\" ) {\n\t\t\treturn jQuery.inArray( this[0], jQuery( elem ) );\n\t\t}\n\n\t\t// Locate the position of the desired element\n\t\treturn jQuery.inArray(\n\t\t\t// If it receives a jQuery object, the first element is used\n\t\t\telem.jquery ? elem[0] : elem, this );\n\t},\n\n\tadd: function( selector, context ) {\n\t\treturn this.pushStack(\n\t\t\tjQuery.unique(\n\t\t\t\tjQuery.merge( this.get(), jQuery( selector, context ) )\n\t\t\t)\n\t\t);\n\t},\n\n\taddBack: function( selector ) {\n\t\treturn this.add( selector == null ?\n\t\t\tthis.prevObject : this.prevObject.filter(selector)\n\t\t);\n\t}\n});\n\nfunction sibling( cur, dir ) {\n\tdo {\n\t\tcur = cur[ dir ];\n\t} while ( cur && cur.nodeType !== 1 );\n\n\treturn cur;\n}\n\njQuery.each({\n\tparent: function( elem ) {\n\t\tvar parent = elem.parentNode;\n\t\treturn parent && parent.nodeType !== 11 ? parent : null;\n\t},\n\tparents: function( elem ) {\n\t\treturn jQuery.dir( elem, \"parentNode\" );\n\t},\n\tparentsUntil: function( elem, i, until ) {\n\t\treturn jQuery.dir( elem, \"parentNode\", until );\n\t},\n\tnext: function( elem ) {\n\t\treturn sibling( elem, \"nextSibling\" );\n\t},\n\tprev: function( elem ) {\n\t\treturn sibling( elem, \"previousSibling\" );\n\t},\n\tnextAll: function( elem ) {\n\t\treturn jQuery.dir( elem, \"nextSibling\" );\n\t},\n\tprevAll: function( elem ) {\n\t\treturn jQuery.dir( elem, \"previousSibling\" );\n\t},\n\tnextUntil: function( elem, i, until ) {\n\t\treturn jQuery.dir( elem, \"nextSibling\", until );\n\t},\n\tprevUntil: function( elem, i, until ) {\n\t\treturn jQuery.dir( elem, \"previousSibling\", until );\n\t},\n\tsiblings: function( elem ) {\n\t\treturn jQuery.sibling( ( elem.parentNode || {} ).firstChild, elem );\n\t},\n\tchildren: function( elem ) {\n\t\treturn jQuery.sibling( elem.firstChild );\n\t},\n\tcontents: function( elem ) {\n\t\treturn jQuery.nodeName( elem, \"iframe\" ) ?\n\t\t\telem.contentDocument || elem.contentWindow.document :\n\t\t\tjQuery.merge( [], elem.childNodes );\n\t}\n}, function( name, fn ) {\n\tjQuery.fn[ name ] = function( until, selector ) {\n\t\tvar ret = jQuery.map( this, fn, until );\n\n\t\tif ( name.slice( -5 ) !== \"Until\" ) {\n\t\t\tselector = until;\n\t\t}\n\n\t\tif ( selector && typeof selector === \"string\" ) {\n\t\t\tret = jQuery.filter( selector, ret );\n\t\t}\n\n\t\tif ( this.length > 1 ) {\n\t\t\t// Remove duplicates\n\t\t\tif ( !guaranteedUnique[ name ] ) {\n\t\t\t\tret = jQuery.unique( ret );\n\t\t\t}\n\n\t\t\t// Reverse order for parents* and prev-derivatives\n\t\t\tif ( rparentsprev.test( name ) ) {\n\t\t\t\tret = ret.reverse();\n\t\t\t}\n\t\t}\n\n\t\treturn this.pushStack( ret );\n\t};\n});\nvar rnotwhite = (/\\S+/g);\n\n\n\n// String to Object options format cache\nvar optionsCache = {};\n\n// Convert String-formatted options into Object-formatted ones and store in cache\nfunction createOptions( options ) {\n\tvar object = optionsCache[ options ] = {};\n\tjQuery.each( options.match( rnotwhite ) || [], function( _, flag ) {\n\t\tobject[ flag ] = true;\n\t});\n\treturn object;\n}\n\n/*\n * Create a callback list using the following parameters:\n *\n *\toptions: an optional list of space-separated options that will change how\n *\t\t\tthe callback list behaves or a more traditional option object\n *\n * By default a callback list will act like an event callback list and can be\n * \"fired\" multiple times.\n *\n * Possible options:\n *\n *\tonce:\t\t\twill ensure the callback list can only be fired once (like a Deferred)\n *\n *\tmemory:\t\t\twill keep track of previous values and will call any callback added\n *\t\t\t\t\tafter the list has been fired right away with the latest \"memorized\"\n *\t\t\t\t\tvalues (like a Deferred)\n *\n *\tunique:\t\t\twill ensure a callback can only be added once (no duplicate in the list)\n *\n *\tstopOnFalse:\tinterrupt callings when a callback returns false\n *\n */\njQuery.Callbacks = function( options ) {\n\n\t// Convert options from String-formatted to Object-formatted if needed\n\t// (we check in cache first)\n\toptions = typeof options === \"string\" ?\n\t\t( optionsCache[ options ] || createOptions( options ) ) :\n\t\tjQuery.extend( {}, options );\n\n\tvar // Flag to know if list is currently firing\n\t\tfiring,\n\t\t// Last fire value (for non-forgettable lists)\n\t\tmemory,\n\t\t// Flag to know if list was already fired\n\t\tfired,\n\t\t// End of the loop when firing\n\t\tfiringLength,\n\t\t// Index of currently firing callback (modified by remove if needed)\n\t\tfiringIndex,\n\t\t// First callback to fire (used internally by add and fireWith)\n\t\tfiringStart,\n\t\t// Actual callback list\n\t\tlist = [],\n\t\t// Stack of fire calls for repeatable lists\n\t\tstack = !options.once && [],\n\t\t// Fire callbacks\n\t\tfire = function( data ) {\n\t\t\tmemory = options.memory && data;\n\t\t\tfired = true;\n\t\t\tfiringIndex = firingStart || 0;\n\t\t\tfiringStart = 0;\n\t\t\tfiringLength = list.length;\n\t\t\tfiring = true;\n\t\t\tfor ( ; list && firingIndex < firingLength; firingIndex++ ) {\n\t\t\t\tif ( list[ firingIndex ].apply( data[ 0 ], data[ 1 ] ) === false && options.stopOnFalse ) {\n\t\t\t\t\tmemory = false; // To prevent further calls using add\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t\tfiring = false;\n\t\t\tif ( list ) {\n\t\t\t\tif ( stack ) {\n\t\t\t\t\tif ( stack.length ) {\n\t\t\t\t\t\tfire( stack.shift() );\n\t\t\t\t\t}\n\t\t\t\t} else if ( memory ) {\n\t\t\t\t\tlist = [];\n\t\t\t\t} else {\n\t\t\t\t\tself.disable();\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\t// Actual Callbacks object\n\t\tself = {\n\t\t\t// Add a callback or a collection of callbacks to the list\n\t\t\tadd: function() {\n\t\t\t\tif ( list ) {\n\t\t\t\t\t// First, we save the current length\n\t\t\t\t\tvar start = list.length;\n\t\t\t\t\t(function add( args ) {\n\t\t\t\t\t\tjQuery.each( args, function( _, arg ) {\n\t\t\t\t\t\t\tvar type = jQuery.type( arg );\n\t\t\t\t\t\t\tif ( type === \"function\" ) {\n\t\t\t\t\t\t\t\tif ( !options.unique || !self.has( arg ) ) {\n\t\t\t\t\t\t\t\t\tlist.push( arg );\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t} else if ( arg && arg.length && type !== \"string\" ) {\n\t\t\t\t\t\t\t\t// Inspect recursively\n\t\t\t\t\t\t\t\tadd( arg );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t});\n\t\t\t\t\t})( arguments );\n\t\t\t\t\t// Do we need to add the callbacks to the\n\t\t\t\t\t// current firing batch?\n\t\t\t\t\tif ( firing ) {\n\t\t\t\t\t\tfiringLength = list.length;\n\t\t\t\t\t// With memory, if we're not firing then\n\t\t\t\t\t// we should call right away\n\t\t\t\t\t} else if ( memory ) {\n\t\t\t\t\t\tfiringStart = start;\n\t\t\t\t\t\tfire( memory );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn this;\n\t\t\t},\n\t\t\t// Remove a callback from the list\n\t\t\tremove: function() {\n\t\t\t\tif ( list ) {\n\t\t\t\t\tjQuery.each( arguments, function( _, arg ) {\n\t\t\t\t\t\tvar index;\n\t\t\t\t\t\twhile ( ( index = jQuery.inArray( arg, list, index ) ) > -1 ) {\n\t\t\t\t\t\t\tlist.splice( index, 1 );\n\t\t\t\t\t\t\t// Handle firing indexes\n\t\t\t\t\t\t\tif ( firing ) {\n\t\t\t\t\t\t\t\tif ( index <= firingLength ) {\n\t\t\t\t\t\t\t\t\tfiringLength--;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tif ( index <= firingIndex ) {\n\t\t\t\t\t\t\t\t\tfiringIndex--;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t\treturn this;\n\t\t\t},\n\t\t\t// Check if a given callback is in the list.\n\t\t\t// If no argument is given, return whether or not list has callbacks attached.\n\t\t\thas: function( fn ) {\n\t\t\t\treturn fn ? jQuery.inArray( fn, list ) > -1 : !!( list && list.length );\n\t\t\t},\n\t\t\t// Remove all callbacks from the list\n\t\t\tempty: function() {\n\t\t\t\tlist = [];\n\t\t\t\tfiringLength = 0;\n\t\t\t\treturn this;\n\t\t\t},\n\t\t\t// Have the list do nothing anymore\n\t\t\tdisable: function() {\n\t\t\t\tlist = stack = memory = undefined;\n\t\t\t\treturn this;\n\t\t\t},\n\t\t\t// Is it disabled?\n\t\t\tdisabled: function() {\n\t\t\t\treturn !list;\n\t\t\t},\n\t\t\t// Lock the list in its current state\n\t\t\tlock: function() {\n\t\t\t\tstack = undefined;\n\t\t\t\tif ( !memory ) {\n\t\t\t\t\tself.disable();\n\t\t\t\t}\n\t\t\t\treturn this;\n\t\t\t},\n\t\t\t// Is it locked?\n\t\t\tlocked: function() {\n\t\t\t\treturn !stack;\n\t\t\t},\n\t\t\t// Call all callbacks with the given context and arguments\n\t\t\tfireWith: function( context, args ) {\n\t\t\t\tif ( list && ( !fired || stack ) ) {\n\t\t\t\t\targs = args || [];\n\t\t\t\t\targs = [ context, args.slice ? args.slice() : args ];\n\t\t\t\t\tif ( firing ) {\n\t\t\t\t\t\tstack.push( args );\n\t\t\t\t\t} else {\n\t\t\t\t\t\tfire( args );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn this;\n\t\t\t},\n\t\t\t// Call all the callbacks with the given arguments\n\t\t\tfire: function() {\n\t\t\t\tself.fireWith( this, arguments );\n\t\t\t\treturn this;\n\t\t\t},\n\t\t\t// To know if the callbacks have already been called at least once\n\t\t\tfired: function() {\n\t\t\t\treturn !!fired;\n\t\t\t}\n\t\t};\n\n\treturn self;\n};\n\n\njQuery.extend({\n\n\tDeferred: function( func ) {\n\t\tvar tuples = [\n\t\t\t\t// action, add listener, listener list, final state\n\t\t\t\t[ \"resolve\", \"done\", jQuery.Callbacks(\"once memory\"), \"resolved\" ],\n\t\t\t\t[ \"reject\", \"fail\", jQuery.Callbacks(\"once memory\"), \"rejected\" ],\n\t\t\t\t[ \"notify\", \"progress\", jQuery.Callbacks(\"memory\") ]\n\t\t\t],\n\t\t\tstate = \"pending\",\n\t\t\tpromise = {\n\t\t\t\tstate: function() {\n\t\t\t\t\treturn state;\n\t\t\t\t},\n\t\t\t\talways: function() {\n\t\t\t\t\tdeferred.done( arguments ).fail( arguments );\n\t\t\t\t\treturn this;\n\t\t\t\t},\n\t\t\t\tthen: function( /* fnDone, fnFail, fnProgress */ ) {\n\t\t\t\t\tvar fns = arguments;\n\t\t\t\t\treturn jQuery.Deferred(function( newDefer ) {\n\t\t\t\t\t\tjQuery.each( tuples, function( i, tuple ) {\n\t\t\t\t\t\t\tvar fn = jQuery.isFunction( fns[ i ] ) && fns[ i ];\n\t\t\t\t\t\t\t// deferred[ done | fail | progress ] for forwarding actions to newDefer\n\t\t\t\t\t\t\tdeferred[ tuple[1] ](function() {\n\t\t\t\t\t\t\t\tvar returned = fn && fn.apply( this, arguments );\n\t\t\t\t\t\t\t\tif ( returned && jQuery.isFunction( returned.promise ) ) {\n\t\t\t\t\t\t\t\t\treturned.promise()\n\t\t\t\t\t\t\t\t\t\t.done( newDefer.resolve )\n\t\t\t\t\t\t\t\t\t\t.fail( newDefer.reject )\n\t\t\t\t\t\t\t\t\t\t.progress( newDefer.notify );\n\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\tnewDefer[ tuple[ 0 ] + \"With\" ]( this === promise ? newDefer.promise() : this, fn ? [ returned ] : arguments );\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t});\n\t\t\t\t\t\tfns = null;\n\t\t\t\t\t}).promise();\n\t\t\t\t},\n\t\t\t\t// Get a promise for this deferred\n\t\t\t\t// If obj is provided, the promise aspect is added to the object\n\t\t\t\tpromise: function( obj ) {\n\t\t\t\t\treturn obj != null ? jQuery.extend( obj, promise ) : promise;\n\t\t\t\t}\n\t\t\t},\n\t\t\tdeferred = {};\n\n\t\t// Keep pipe for back-compat\n\t\tpromise.pipe = promise.then;\n\n\t\t// Add list-specific methods\n\t\tjQuery.each( tuples, function( i, tuple ) {\n\t\t\tvar list = tuple[ 2 ],\n\t\t\t\tstateString = tuple[ 3 ];\n\n\t\t\t// promise[ done | fail | progress ] = list.add\n\t\t\tpromise[ tuple[1] ] = list.add;\n\n\t\t\t// Handle state\n\t\t\tif ( stateString ) {\n\t\t\t\tlist.add(function() {\n\t\t\t\t\t// state = [ resolved | rejected ]\n\t\t\t\t\tstate = stateString;\n\n\t\t\t\t// [ reject_list | resolve_list ].disable; progress_list.lock\n\t\t\t\t}, tuples[ i ^ 1 ][ 2 ].disable, tuples[ 2 ][ 2 ].lock );\n\t\t\t}\n\n\t\t\t// deferred[ resolve | reject | notify ]\n\t\t\tdeferred[ tuple[0] ] = function() {\n\t\t\t\tdeferred[ tuple[0] + \"With\" ]( this === deferred ? promise : this, arguments );\n\t\t\t\treturn this;\n\t\t\t};\n\t\t\tdeferred[ tuple[0] + \"With\" ] = list.fireWith;\n\t\t});\n\n\t\t// Make the deferred a promise\n\t\tpromise.promise( deferred );\n\n\t\t// Call given func if any\n\t\tif ( func ) {\n\t\t\tfunc.call( deferred, deferred );\n\t\t}\n\n\t\t// All done!\n\t\treturn deferred;\n\t},\n\n\t// Deferred helper\n\twhen: function( subordinate /* , ..., subordinateN */ ) {\n\t\tvar i = 0,\n\t\t\tresolveValues = slice.call( arguments ),\n\t\t\tlength = resolveValues.length,\n\n\t\t\t// the count of uncompleted subordinates\n\t\t\tremaining = length !== 1 || ( subordinate && jQuery.isFunction( subordinate.promise ) ) ? length : 0,\n\n\t\t\t// the master Deferred. If resolveValues consist of only a single Deferred, just use that.\n\t\t\tdeferred = remaining === 1 ? subordinate : jQuery.Deferred(),\n\n\t\t\t// Update function for both resolve and progress values\n\t\t\tupdateFunc = function( i, contexts, values ) {\n\t\t\t\treturn function( value ) {\n\t\t\t\t\tcontexts[ i ] = this;\n\t\t\t\t\tvalues[ i ] = arguments.length > 1 ? slice.call( arguments ) : value;\n\t\t\t\t\tif ( values === progressValues ) {\n\t\t\t\t\t\tdeferred.notifyWith( contexts, values );\n\n\t\t\t\t\t} else if ( !(--remaining) ) {\n\t\t\t\t\t\tdeferred.resolveWith( contexts, values );\n\t\t\t\t\t}\n\t\t\t\t};\n\t\t\t},\n\n\t\t\tprogressValues, progressContexts, resolveContexts;\n\n\t\t// add listeners to Deferred subordinates; treat others as resolved\n\t\tif ( length > 1 ) {\n\t\t\tprogressValues = new Array( length );\n\t\t\tprogressContexts = new Array( length );\n\t\t\tresolveContexts = new Array( length );\n\t\t\tfor ( ; i < length; i++ ) {\n\t\t\t\tif ( resolveValues[ i ] && jQuery.isFunction( resolveValues[ i ].promise ) ) {\n\t\t\t\t\tresolveValues[ i ].promise()\n\t\t\t\t\t\t.done( updateFunc( i, resolveContexts, resolveValues ) )\n\t\t\t\t\t\t.fail( deferred.reject )\n\t\t\t\t\t\t.progress( updateFunc( i, progressContexts, progressValues ) );\n\t\t\t\t} else {\n\t\t\t\t\t--remaining;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// if we're not waiting on anything, resolve the master\n\t\tif ( !remaining ) {\n\t\t\tdeferred.resolveWith( resolveContexts, resolveValues );\n\t\t}\n\n\t\treturn deferred.promise();\n\t}\n});\n\n\n// The deferred used on DOM ready\nvar readyList;\n\njQuery.fn.ready = function( fn ) {\n\t// Add the callback\n\tjQuery.ready.promise().done( fn );\n\n\treturn this;\n};\n\njQuery.extend({\n\t// Is the DOM ready to be used? Set to true once it occurs.\n\tisReady: false,\n\n\t// A counter to track how many items to wait for before\n\t// the ready event fires. See #6781\n\treadyWait: 1,\n\n\t// Hold (or release) the ready event\n\tholdReady: function( hold ) {\n\t\tif ( hold ) {\n\t\t\tjQuery.readyWait++;\n\t\t} else {\n\t\t\tjQuery.ready( true );\n\t\t}\n\t},\n\n\t// Handle when the DOM is ready\n\tready: function( wait ) {\n\n\t\t// Abort if there are pending holds or we're already ready\n\t\tif ( wait === true ? --jQuery.readyWait : jQuery.isReady ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443).\n\t\tif ( !document.body ) {\n\t\t\treturn setTimeout( jQuery.ready );\n\t\t}\n\n\t\t// Remember that the DOM is ready\n\t\tjQuery.isReady = true;\n\n\t\t// If a normal DOM Ready event fired, decrement, and wait if need be\n\t\tif ( wait !== true && --jQuery.readyWait > 0 ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// If there are functions bound, to execute\n\t\treadyList.resolveWith( document, [ jQuery ] );\n\n\t\t// Trigger any bound ready events\n\t\tif ( jQuery.fn.triggerHandler ) {\n\t\t\tjQuery( document ).triggerHandler( \"ready\" );\n\t\t\tjQuery( document ).off( \"ready\" );\n\t\t}\n\t}\n});\n\n/**\n * Clean-up method for dom ready events\n */\nfunction detach() {\n\tif ( document.addEventListener ) {\n\t\tdocument.removeEventListener( \"DOMContentLoaded\", completed, false );\n\t\twindow.removeEventListener( \"load\", completed, false );\n\n\t} else {\n\t\tdocument.detachEvent( \"onreadystatechange\", completed );\n\t\twindow.detachEvent( \"onload\", completed );\n\t}\n}\n\n/**\n * The ready event handler and self cleanup method\n */\nfunction completed() {\n\t// readyState === \"complete\" is good enough for us to call the dom ready in oldIE\n\tif ( document.addEventListener || event.type === \"load\" || document.readyState === \"complete\" ) {\n\t\tdetach();\n\t\tjQuery.ready();\n\t}\n}\n\njQuery.ready.promise = function( obj ) {\n\tif ( !readyList ) {\n\n\t\treadyList = jQuery.Deferred();\n\n\t\t// Catch cases where $(document).ready() is called after the browser event has already occurred.\n\t\t// we once tried to use readyState \"interactive\" here, but it caused issues like the one\n\t\t// discovered by ChrisS here: http://bugs.jquery.com/ticket/12282#comment:15\n\t\tif ( document.readyState === \"complete\" ) {\n\t\t\t// Handle it asynchronously to allow scripts the opportunity to delay ready\n\t\t\tsetTimeout( jQuery.ready );\n\n\t\t// Standards-based browsers support DOMContentLoaded\n\t\t} else if ( document.addEventListener ) {\n\t\t\t// Use the handy event callback\n\t\t\tdocument.addEventListener( \"DOMContentLoaded\", completed, false );\n\n\t\t\t// A fallback to window.onload, that will always work\n\t\t\twindow.addEventListener( \"load\", completed, false );\n\n\t\t// If IE event model is used\n\t\t} else {\n\t\t\t// Ensure firing before onload, maybe late but safe also for iframes\n\t\t\tdocument.attachEvent( \"onreadystatechange\", completed );\n\n\t\t\t// A fallback to window.onload, that will always work\n\t\t\twindow.attachEvent( \"onload\", completed );\n\n\t\t\t// If IE and not a frame\n\t\t\t// continually check to see if the document is ready\n\t\t\tvar top = false;\n\n\t\t\ttry {\n\t\t\t\ttop = window.frameElement == null && document.documentElement;\n\t\t\t} catch(e) {}\n\n\t\t\tif ( top && top.doScroll ) {\n\t\t\t\t(function doScrollCheck() {\n\t\t\t\t\tif ( !jQuery.isReady ) {\n\n\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t// Use the trick by Diego Perini\n\t\t\t\t\t\t\t// http://javascript.nwbox.com/IEContentLoaded/\n\t\t\t\t\t\t\ttop.doScroll(\"left\");\n\t\t\t\t\t\t} catch(e) {\n\t\t\t\t\t\t\treturn setTimeout( doScrollCheck, 50 );\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// detach all dom ready events\n\t\t\t\t\t\tdetach();\n\n\t\t\t\t\t\t// and execute any waiting functions\n\t\t\t\t\t\tjQuery.ready();\n\t\t\t\t\t}\n\t\t\t\t})();\n\t\t\t}\n\t\t}\n\t}\n\treturn readyList.promise( obj );\n};\n\n\nvar strundefined = typeof undefined;\n\n\n\n// Support: IE<9\n// Iteration over object's inherited properties before its own\nvar i;\nfor ( i in jQuery( support ) ) {\n\tbreak;\n}\nsupport.ownLast = i !== \"0\";\n\n// Note: most support tests are defined in their respective modules.\n// false until the test is run\nsupport.inlineBlockNeedsLayout = false;\n\n// Execute ASAP in case we need to set body.style.zoom\njQuery(function() {\n\t// Minified: var a,b,c,d\n\tvar val, div, body, container;\n\n\tbody = document.getElementsByTagName( \"body\" )[ 0 ];\n\tif ( !body || !body.style ) {\n\t\t// Return for frameset docs that don't have a body\n\t\treturn;\n\t}\n\n\t// Setup\n\tdiv = document.createElement( \"div\" );\n\tcontainer = document.createElement( \"div\" );\n\tcontainer.style.cssText = \"position:absolute;border:0;width:0;height:0;top:0;left:-9999px\";\n\tbody.appendChild( container ).appendChild( div );\n\n\tif ( typeof div.style.zoom !== strundefined ) {\n\t\t// Support: IE<8\n\t\t// Check if natively block-level elements act like inline-block\n\t\t// elements when setting their display to 'inline' and giving\n\t\t// them layout\n\t\tdiv.style.cssText = \"display:inline;margin:0;border:0;padding:1px;width:1px;zoom:1\";\n\n\t\tsupport.inlineBlockNeedsLayout = val = div.offsetWidth === 3;\n\t\tif ( val ) {\n\t\t\t// Prevent IE 6 from affecting layout for positioned elements #11048\n\t\t\t// Prevent IE from shrinking the body in IE 7 mode #12869\n\t\t\t// Support: IE<8\n\t\t\tbody.style.zoom = 1;\n\t\t}\n\t}\n\n\tbody.removeChild( container );\n});\n\n\n\n\n(function() {\n\tvar div = document.createElement( \"div\" );\n\n\t// Execute the test only if not already executed in another module.\n\tif (support.deleteExpando == null) {\n\t\t// Support: IE<9\n\t\tsupport.deleteExpando = true;\n\t\ttry {\n\t\t\tdelete div.test;\n\t\t} catch( e ) {\n\t\t\tsupport.deleteExpando = false;\n\t\t}\n\t}\n\n\t// Null elements to avoid leaks in IE.\n\tdiv = null;\n})();\n\n\n/**\n * Determines whether an object can have data\n */\njQuery.acceptData = function( elem ) {\n\tvar noData = jQuery.noData[ (elem.nodeName + \" \").toLowerCase() ],\n\t\tnodeType = +elem.nodeType || 1;\n\n\t// Do not set data on non-element DOM nodes because it will not be cleared (#8335).\n\treturn nodeType !== 1 && nodeType !== 9 ?\n\t\tfalse :\n\n\t\t// Nodes accept data unless otherwise specified; rejection can be conditional\n\t\t!noData || noData !== true && elem.getAttribute(\"classid\") === noData;\n};\n\n\nvar rbrace = /^(?:\\{[\\w\\W]*\\}|\\[[\\w\\W]*\\])$/,\n\trmultiDash = /([A-Z])/g;\n\nfunction dataAttr( elem, key, data ) {\n\t// If nothing was found internally, try to fetch any\n\t// data from the HTML5 data-* attribute\n\tif ( data === undefined && elem.nodeType === 1 ) {\n\n\t\tvar name = \"data-\" + key.replace( rmultiDash, \"-$1\" ).toLowerCase();\n\n\t\tdata = elem.getAttribute( name );\n\n\t\tif ( typeof data === \"string\" ) {\n\t\t\ttry {\n\t\t\t\tdata = data === \"true\" ? true :\n\t\t\t\t\tdata === \"false\" ? false :\n\t\t\t\t\tdata === \"null\" ? null :\n\t\t\t\t\t// Only convert to a number if it doesn't change the string\n\t\t\t\t\t+data + \"\" === data ? +data :\n\t\t\t\t\trbrace.test( data ) ? jQuery.parseJSON( data ) :\n\t\t\t\t\tdata;\n\t\t\t} catch( e ) {}\n\n\t\t\t// Make sure we set the data so it isn't changed later\n\t\t\tjQuery.data( elem, key, data );\n\n\t\t} else {\n\t\t\tdata = undefined;\n\t\t}\n\t}\n\n\treturn data;\n}\n\n// checks a cache object for emptiness\nfunction isEmptyDataObject( obj ) {\n\tvar name;\n\tfor ( name in obj ) {\n\n\t\t// if the public data object is empty, the private is still empty\n\t\tif ( name === \"data\" && jQuery.isEmptyObject( obj[name] ) ) {\n\t\t\tcontinue;\n\t\t}\n\t\tif ( name !== \"toJSON\" ) {\n\t\t\treturn false;\n\t\t}\n\t}\n\n\treturn true;\n}\n\nfunction internalData( elem, name, data, pvt /* Internal Use Only */ ) {\n\tif ( !jQuery.acceptData( elem ) ) {\n\t\treturn;\n\t}\n\n\tvar ret, thisCache,\n\t\tinternalKey = jQuery.expando,\n\n\t\t// We have to handle DOM nodes and JS objects differently because IE6-7\n\t\t// can't GC object references properly across the DOM-JS boundary\n\t\tisNode = elem.nodeType,\n\n\t\t// Only DOM nodes need the global jQuery cache; JS object data is\n\t\t// attached directly to the object so GC can occur automatically\n\t\tcache = isNode ? jQuery.cache : elem,\n\n\t\t// Only defining an ID for JS objects if its cache already exists allows\n\t\t// the code to shortcut on the same path as a DOM node with no cache\n\t\tid = isNode ? elem[ internalKey ] : elem[ internalKey ] && internalKey;\n\n\t// Avoid doing any more work than we need to when trying to get data on an\n\t// object that has no data at all\n\tif ( (!id || !cache[id] || (!pvt && !cache[id].data)) && data === undefined && typeof name === \"string\" ) {\n\t\treturn;\n\t}\n\n\tif ( !id ) {\n\t\t// Only DOM nodes need a new unique ID for each element since their data\n\t\t// ends up in the global cache\n\t\tif ( isNode ) {\n\t\t\tid = elem[ internalKey ] = deletedIds.pop() || jQuery.guid++;\n\t\t} else {\n\t\t\tid = internalKey;\n\t\t}\n\t}\n\n\tif ( !cache[ id ] ) {\n\t\t// Avoid exposing jQuery metadata on plain JS objects when the object\n\t\t// is serialized using JSON.stringify\n\t\tcache[ id ] = isNode ? {} : { toJSON: jQuery.noop };\n\t}\n\n\t// An object can be passed to jQuery.data instead of a key/value pair; this gets\n\t// shallow copied over onto the existing cache\n\tif ( typeof name === \"object\" || typeof name === \"function\" ) {\n\t\tif ( pvt ) {\n\t\t\tcache[ id ] = jQuery.extend( cache[ id ], name );\n\t\t} else {\n\t\t\tcache[ id ].data = jQuery.extend( cache[ id ].data, name );\n\t\t}\n\t}\n\n\tthisCache = cache[ id ];\n\n\t// jQuery data() is stored in a separate object inside the object's internal data\n\t// cache in order to avoid key collisions between internal data and user-defined\n\t// data.\n\tif ( !pvt ) {\n\t\tif ( !thisCache.data ) {\n\t\t\tthisCache.data = {};\n\t\t}\n\n\t\tthisCache = thisCache.data;\n\t}\n\n\tif ( data !== undefined ) {\n\t\tthisCache[ jQuery.camelCase( name ) ] = data;\n\t}\n\n\t// Check for both converted-to-camel and non-converted data property names\n\t// If a data property was specified\n\tif ( typeof name === \"string\" ) {\n\n\t\t// First Try to find as-is property data\n\t\tret = thisCache[ name ];\n\n\t\t// Test for null|undefined property data\n\t\tif ( ret == null ) {\n\n\t\t\t// Try to find the camelCased property\n\t\t\tret = thisCache[ jQuery.camelCase( name ) ];\n\t\t}\n\t} else {\n\t\tret = thisCache;\n\t}\n\n\treturn ret;\n}\n\nfunction internalRemoveData( elem, name, pvt ) {\n\tif ( !jQuery.acceptData( elem ) ) {\n\t\treturn;\n\t}\n\n\tvar thisCache, i,\n\t\tisNode = elem.nodeType,\n\n\t\t// See jQuery.data for more information\n\t\tcache = isNode ? jQuery.cache : elem,\n\t\tid = isNode ? elem[ jQuery.expando ] : jQuery.expando;\n\n\t// If there is already no cache entry for this object, there is no\n\t// purpose in continuing\n\tif ( !cache[ id ] ) {\n\t\treturn;\n\t}\n\n\tif ( name ) {\n\n\t\tthisCache = pvt ? cache[ id ] : cache[ id ].data;\n\n\t\tif ( thisCache ) {\n\n\t\t\t// Support array or space separated string names for data keys\n\t\t\tif ( !jQuery.isArray( name ) ) {\n\n\t\t\t\t// try the string as a key before any manipulation\n\t\t\t\tif ( name in thisCache ) {\n\t\t\t\t\tname = [ name ];\n\t\t\t\t} else {\n\n\t\t\t\t\t// split the camel cased version by spaces unless a key with the spaces exists\n\t\t\t\t\tname = jQuery.camelCase( name );\n\t\t\t\t\tif ( name in thisCache ) {\n\t\t\t\t\t\tname = [ name ];\n\t\t\t\t\t} else {\n\t\t\t\t\t\tname = name.split(\" \");\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t// If \"name\" is an array of keys...\n\t\t\t\t// When data is initially created, via (\"key\", \"val\") signature,\n\t\t\t\t// keys will be converted to camelCase.\n\t\t\t\t// Since there is no way to tell _how_ a key was added, remove\n\t\t\t\t// both plain key and camelCase key. #12786\n\t\t\t\t// This will only penalize the array argument path.\n\t\t\t\tname = name.concat( jQuery.map( name, jQuery.camelCase ) );\n\t\t\t}\n\n\t\t\ti = name.length;\n\t\t\twhile ( i-- ) {\n\t\t\t\tdelete thisCache[ name[i] ];\n\t\t\t}\n\n\t\t\t// If there is no data left in the cache, we want to continue\n\t\t\t// and let the cache object itself get destroyed\n\t\t\tif ( pvt ? !isEmptyDataObject(thisCache) : !jQuery.isEmptyObject(thisCache) ) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\t}\n\n\t// See jQuery.data for more information\n\tif ( !pvt ) {\n\t\tdelete cache[ id ].data;\n\n\t\t// Don't destroy the parent cache unless the internal data object\n\t\t// had been the only thing left in it\n\t\tif ( !isEmptyDataObject( cache[ id ] ) ) {\n\t\t\treturn;\n\t\t}\n\t}\n\n\t// Destroy the cache\n\tif ( isNode ) {\n\t\tjQuery.cleanData( [ elem ], true );\n\n\t// Use delete when supported for expandos or `cache` is not a window per isWindow (#10080)\n\t/* jshint eqeqeq: false */\n\t} else if ( support.deleteExpando || cache != cache.window ) {\n\t\t/* jshint eqeqeq: true */\n\t\tdelete cache[ id ];\n\n\t// When all else fails, null\n\t} else {\n\t\tcache[ id ] = null;\n\t}\n}\n\njQuery.extend({\n\tcache: {},\n\n\t// The following elements (space-suffixed to avoid Object.prototype collisions)\n\t// throw uncatchable exceptions if you attempt to set expando properties\n\tnoData: {\n\t\t\"applet \": true,\n\t\t\"embed \": true,\n\t\t// ...but Flash objects (which have this classid) *can* handle expandos\n\t\t\"object \": \"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000\"\n\t},\n\n\thasData: function( elem ) {\n\t\telem = elem.nodeType ? jQuery.cache[ elem[jQuery.expando] ] : elem[ jQuery.expando ];\n\t\treturn !!elem && !isEmptyDataObject( elem );\n\t},\n\n\tdata: function( elem, name, data ) {\n\t\treturn internalData( elem, name, data );\n\t},\n\n\tremoveData: function( elem, name ) {\n\t\treturn internalRemoveData( elem, name );\n\t},\n\n\t// For internal use only.\n\t_data: function( elem, name, data ) {\n\t\treturn internalData( elem, name, data, true );\n\t},\n\n\t_removeData: function( elem, name ) {\n\t\treturn internalRemoveData( elem, name, true );\n\t}\n});\n\njQuery.fn.extend({\n\tdata: function( key, value ) {\n\t\tvar i, name, data,\n\t\t\telem = this[0],\n\t\t\tattrs = elem && elem.attributes;\n\n\t\t// Special expections of .data basically thwart jQuery.access,\n\t\t// so implement the relevant behavior ourselves\n\n\t\t// Gets all values\n\t\tif ( key === undefined ) {\n\t\t\tif ( this.length ) {\n\t\t\t\tdata = jQuery.data( elem );\n\n\t\t\t\tif ( elem.nodeType === 1 && !jQuery._data( elem, \"parsedAttrs\" ) ) {\n\t\t\t\t\ti = attrs.length;\n\t\t\t\t\twhile ( i-- ) {\n\n\t\t\t\t\t\t// Support: IE11+\n\t\t\t\t\t\t// The attrs elements can be null (#14894)\n\t\t\t\t\t\tif ( attrs[ i ] ) {\n\t\t\t\t\t\t\tname = attrs[ i ].name;\n\t\t\t\t\t\t\tif ( name.indexOf( \"data-\" ) === 0 ) {\n\t\t\t\t\t\t\t\tname = jQuery.camelCase( name.slice(5) );\n\t\t\t\t\t\t\t\tdataAttr( elem, name, data[ name ] );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tjQuery._data( elem, \"parsedAttrs\", true );\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn data;\n\t\t}\n\n\t\t// Sets multiple values\n\t\tif ( typeof key === \"object\" ) {\n\t\t\treturn this.each(function() {\n\t\t\t\tjQuery.data( this, key );\n\t\t\t});\n\t\t}\n\n\t\treturn arguments.length > 1 ?\n\n\t\t\t// Sets one value\n\t\t\tthis.each(function() {\n\t\t\t\tjQuery.data( this, key, value );\n\t\t\t}) :\n\n\t\t\t// Gets one value\n\t\t\t// Try to fetch any internally stored data first\n\t\t\telem ? dataAttr( elem, key, jQuery.data( elem, key ) ) : undefined;\n\t},\n\n\tremoveData: function( key ) {\n\t\treturn this.each(function() {\n\t\t\tjQuery.removeData( this, key );\n\t\t});\n\t}\n});\n\n\njQuery.extend({\n\tqueue: function( elem, type, data ) {\n\t\tvar queue;\n\n\t\tif ( elem ) {\n\t\t\ttype = ( type || \"fx\" ) + \"queue\";\n\t\t\tqueue = jQuery._data( elem, type );\n\n\t\t\t// Speed up dequeue by getting out quickly if this is just a lookup\n\t\t\tif ( data ) {\n\t\t\t\tif ( !queue || jQuery.isArray(data) ) {\n\t\t\t\t\tqueue = jQuery._data( elem, type, jQuery.makeArray(data) );\n\t\t\t\t} else {\n\t\t\t\t\tqueue.push( data );\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn queue || [];\n\t\t}\n\t},\n\n\tdequeue: function( elem, type ) {\n\t\ttype = type || \"fx\";\n\n\t\tvar queue = jQuery.queue( elem, type ),\n\t\t\tstartLength = queue.length,\n\t\t\tfn = queue.shift(),\n\t\t\thooks = jQuery._queueHooks( elem, type ),\n\t\t\tnext = function() {\n\t\t\t\tjQuery.dequeue( elem, type );\n\t\t\t};\n\n\t\t// If the fx queue is dequeued, always remove the progress sentinel\n\t\tif ( fn === \"inprogress\" ) {\n\t\t\tfn = queue.shift();\n\t\t\tstartLength--;\n\t\t}\n\n\t\tif ( fn ) {\n\n\t\t\t// Add a progress sentinel to prevent the fx queue from being\n\t\t\t// automatically dequeued\n\t\t\tif ( type === \"fx\" ) {\n\t\t\t\tqueue.unshift( \"inprogress\" );\n\t\t\t}\n\n\t\t\t// clear up the last queue stop function\n\t\t\tdelete hooks.stop;\n\t\t\tfn.call( elem, next, hooks );\n\t\t}\n\n\t\tif ( !startLength && hooks ) {\n\t\t\thooks.empty.fire();\n\t\t}\n\t},\n\n\t// not intended for public consumption - generates a queueHooks object, or returns the current one\n\t_queueHooks: function( elem, type ) {\n\t\tvar key = type + \"queueHooks\";\n\t\treturn jQuery._data( elem, key ) || jQuery._data( elem, key, {\n\t\t\tempty: jQuery.Callbacks(\"once memory\").add(function() {\n\t\t\t\tjQuery._removeData( elem, type + \"queue\" );\n\t\t\t\tjQuery._removeData( elem, key );\n\t\t\t})\n\t\t});\n\t}\n});\n\njQuery.fn.extend({\n\tqueue: function( type, data ) {\n\t\tvar setter = 2;\n\n\t\tif ( typeof type !== \"string\" ) {\n\t\t\tdata = type;\n\t\t\ttype = \"fx\";\n\t\t\tsetter--;\n\t\t}\n\n\t\tif ( arguments.length < setter ) {\n\t\t\treturn jQuery.queue( this[0], type );\n\t\t}\n\n\t\treturn data === undefined ?\n\t\t\tthis :\n\t\t\tthis.each(function() {\n\t\t\t\tvar queue = jQuery.queue( this, type, data );\n\n\t\t\t\t// ensure a hooks for this queue\n\t\t\t\tjQuery._queueHooks( this, type );\n\n\t\t\t\tif ( type === \"fx\" && queue[0] !== \"inprogress\" ) {\n\t\t\t\t\tjQuery.dequeue( this, type );\n\t\t\t\t}\n\t\t\t});\n\t},\n\tdequeue: function( type ) {\n\t\treturn this.each(function() {\n\t\t\tjQuery.dequeue( this, type );\n\t\t});\n\t},\n\tclearQueue: function( type ) {\n\t\treturn this.queue( type || \"fx\", [] );\n\t},\n\t// Get a promise resolved when queues of a certain type\n\t// are emptied (fx is the type by default)\n\tpromise: function( type, obj ) {\n\t\tvar tmp,\n\t\t\tcount = 1,\n\t\t\tdefer = jQuery.Deferred(),\n\t\t\telements = this,\n\t\t\ti = this.length,\n\t\t\tresolve = function() {\n\t\t\t\tif ( !( --count ) ) {\n\t\t\t\t\tdefer.resolveWith( elements, [ elements ] );\n\t\t\t\t}\n\t\t\t};\n\n\t\tif ( typeof type !== \"string\" ) {\n\t\t\tobj = type;\n\t\t\ttype = undefined;\n\t\t}\n\t\ttype = type || \"fx\";\n\n\t\twhile ( i-- ) {\n\t\t\ttmp = jQuery._data( elements[ i ], type + \"queueHooks\" );\n\t\t\tif ( tmp && tmp.empty ) {\n\t\t\t\tcount++;\n\t\t\t\ttmp.empty.add( resolve );\n\t\t\t}\n\t\t}\n\t\tresolve();\n\t\treturn defer.promise( obj );\n\t}\n});\nvar pnum = (/[+-]?(?:\\d*\\.|)\\d+(?:[eE][+-]?\\d+|)/).source;\n\nvar cssExpand = [ \"Top\", \"Right\", \"Bottom\", \"Left\" ];\n\nvar isHidden = function( elem, el ) {\n\t\t// isHidden might be called from jQuery#filter function;\n\t\t// in that case, element will be second argument\n\t\telem = el || elem;\n\t\treturn jQuery.css( elem, \"display\" ) === \"none\" || !jQuery.contains( elem.ownerDocument, elem );\n\t};\n\n\n\n// Multifunctional method to get and set values of a collection\n// The value/s can optionally be executed if it's a function\nvar access = jQuery.access = function( elems, fn, key, value, chainable, emptyGet, raw ) {\n\tvar i = 0,\n\t\tlength = elems.length,\n\t\tbulk = key == null;\n\n\t// Sets many values\n\tif ( jQuery.type( key ) === \"object\" ) {\n\t\tchainable = true;\n\t\tfor ( i in key ) {\n\t\t\tjQuery.access( elems, fn, i, key[i], true, emptyGet, raw );\n\t\t}\n\n\t// Sets one value\n\t} else if ( value !== undefined ) {\n\t\tchainable = true;\n\n\t\tif ( !jQuery.isFunction( value ) ) {\n\t\t\traw = true;\n\t\t}\n\n\t\tif ( bulk ) {\n\t\t\t// Bulk operations run against the entire set\n\t\t\tif ( raw ) {\n\t\t\t\tfn.call( elems, value );\n\t\t\t\tfn = null;\n\n\t\t\t// ...except when executing function values\n\t\t\t} else {\n\t\t\t\tbulk = fn;\n\t\t\t\tfn = function( elem, key, value ) {\n\t\t\t\t\treturn bulk.call( jQuery( elem ), value );\n\t\t\t\t};\n\t\t\t}\n\t\t}\n\n\t\tif ( fn ) {\n\t\t\tfor ( ; i < length; i++ ) {\n\t\t\t\tfn( elems[i], key, raw ? value : value.call( elems[i], i, fn( elems[i], key ) ) );\n\t\t\t}\n\t\t}\n\t}\n\n\treturn chainable ?\n\t\telems :\n\n\t\t// Gets\n\t\tbulk ?\n\t\t\tfn.call( elems ) :\n\t\t\tlength ? fn( elems[0], key ) : emptyGet;\n};\nvar rcheckableType = (/^(?:checkbox|radio)$/i);\n\n\n\n(function() {\n\t// Minified: var a,b,c\n\tvar input = document.createElement( \"input\" ),\n\t\tdiv = document.createElement( \"div\" ),\n\t\tfragment = document.createDocumentFragment();\n\n\t// Setup\n\tdiv.innerHTML = \"  <link/><table></table><a href='/a'>a</a><input type='checkbox'/>\";\n\n\t// IE strips leading whitespace when .innerHTML is used\n\tsupport.leadingWhitespace = div.firstChild.nodeType === 3;\n\n\t// Make sure that tbody elements aren't automatically inserted\n\t// IE will insert them into empty tables\n\tsupport.tbody = !div.getElementsByTagName( \"tbody\" ).length;\n\n\t// Make sure that link elements get serialized correctly by innerHTML\n\t// This requires a wrapper element in IE\n\tsupport.htmlSerialize = !!div.getElementsByTagName( \"link\" ).length;\n\n\t// Makes sure cloning an html5 element does not cause problems\n\t// Where outerHTML is undefined, this still works\n\tsupport.html5Clone =\n\t\tdocument.createElement( \"nav\" ).cloneNode( true ).outerHTML !== \"<:nav></:nav>\";\n\n\t// Check if a disconnected checkbox will retain its checked\n\t// value of true after appended to the DOM (IE6/7)\n\tinput.type = \"checkbox\";\n\tinput.checked = true;\n\tfragment.appendChild( input );\n\tsupport.appendChecked = input.checked;\n\n\t// Make sure textarea (and checkbox) defaultValue is properly cloned\n\t// Support: IE6-IE11+\n\tdiv.innerHTML = \"<textarea>x</textarea>\";\n\tsupport.noCloneChecked = !!div.cloneNode( true ).lastChild.defaultValue;\n\n\t// #11217 - WebKit loses check when the name is after the checked attribute\n\tfragment.appendChild( div );\n\tdiv.innerHTML = \"<input type='radio' checked='checked' name='t'/>\";\n\n\t// Support: Safari 5.1, iOS 5.1, Android 4.x, Android 2.3\n\t// old WebKit doesn't clone checked state correctly in fragments\n\tsupport.checkClone = div.cloneNode( true ).cloneNode( true ).lastChild.checked;\n\n\t// Support: IE<9\n\t// Opera does not clone events (and typeof div.attachEvent === undefined).\n\t// IE9-10 clones events bound via attachEvent, but they don't trigger with .click()\n\tsupport.noCloneEvent = true;\n\tif ( div.attachEvent ) {\n\t\tdiv.attachEvent( \"onclick\", function() {\n\t\t\tsupport.noCloneEvent = false;\n\t\t});\n\n\t\tdiv.cloneNode( true ).click();\n\t}\n\n\t// Execute the test only if not already executed in another module.\n\tif (support.deleteExpando == null) {\n\t\t// Support: IE<9\n\t\tsupport.deleteExpando = true;\n\t\ttry {\n\t\t\tdelete div.test;\n\t\t} catch( e ) {\n\t\t\tsupport.deleteExpando = false;\n\t\t}\n\t}\n})();\n\n\n(function() {\n\tvar i, eventName,\n\t\tdiv = document.createElement( \"div\" );\n\n\t// Support: IE<9 (lack submit/change bubble), Firefox 23+ (lack focusin event)\n\tfor ( i in { submit: true, change: true, focusin: true }) {\n\t\teventName = \"on\" + i;\n\n\t\tif ( !(support[ i + \"Bubbles\" ] = eventName in window) ) {\n\t\t\t// Beware of CSP restrictions (https://developer.mozilla.org/en/Security/CSP)\n\t\t\tdiv.setAttribute( eventName, \"t\" );\n\t\t\tsupport[ i + \"Bubbles\" ] = div.attributes[ eventName ].expando === false;\n\t\t}\n\t}\n\n\t// Null elements to avoid leaks in IE.\n\tdiv = null;\n})();\n\n\nvar rformElems = /^(?:input|select|textarea)$/i,\n\trkeyEvent = /^key/,\n\trmouseEvent = /^(?:mouse|pointer|contextmenu)|click/,\n\trfocusMorph = /^(?:focusinfocus|focusoutblur)$/,\n\trtypenamespace = /^([^.]*)(?:\\.(.+)|)$/;\n\nfunction returnTrue() {\n\treturn true;\n}\n\nfunction returnFalse() {\n\treturn false;\n}\n\nfunction safeActiveElement() {\n\ttry {\n\t\treturn document.activeElement;\n\t} catch ( err ) { }\n}\n\n/*\n * Helper functions for managing events -- not part of the public interface.\n * Props to Dean Edwards' addEvent library for many of the ideas.\n */\njQuery.event = {\n\n\tglobal: {},\n\n\tadd: function( elem, types, handler, data, selector ) {\n\t\tvar tmp, events, t, handleObjIn,\n\t\t\tspecial, eventHandle, handleObj,\n\t\t\thandlers, type, namespaces, origType,\n\t\t\telemData = jQuery._data( elem );\n\n\t\t// Don't attach events to noData or text/comment nodes (but allow plain objects)\n\t\tif ( !elemData ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Caller can pass in an object of custom data in lieu of the handler\n\t\tif ( handler.handler ) {\n\t\t\thandleObjIn = handler;\n\t\t\thandler = handleObjIn.handler;\n\t\t\tselector = handleObjIn.selector;\n\t\t}\n\n\t\t// Make sure that the handler has a unique ID, used to find/remove it later\n\t\tif ( !handler.guid ) {\n\t\t\thandler.guid = jQuery.guid++;\n\t\t}\n\n\t\t// Init the element's event structure and main handler, if this is the first\n\t\tif ( !(events = elemData.events) ) {\n\t\t\tevents = elemData.events = {};\n\t\t}\n\t\tif ( !(eventHandle = elemData.handle) ) {\n\t\t\teventHandle = elemData.handle = function( e ) {\n\t\t\t\t// Discard the second event of a jQuery.event.trigger() and\n\t\t\t\t// when an event is called after a page has unloaded\n\t\t\t\treturn typeof jQuery !== strundefined && (!e || jQuery.event.triggered !== e.type) ?\n\t\t\t\t\tjQuery.event.dispatch.apply( eventHandle.elem, arguments ) :\n\t\t\t\t\tundefined;\n\t\t\t};\n\t\t\t// Add elem as a property of the handle fn to prevent a memory leak with IE non-native events\n\t\t\teventHandle.elem = elem;\n\t\t}\n\n\t\t// Handle multiple events separated by a space\n\t\ttypes = ( types || \"\" ).match( rnotwhite ) || [ \"\" ];\n\t\tt = types.length;\n\t\twhile ( t-- ) {\n\t\t\ttmp = rtypenamespace.exec( types[t] ) || [];\n\t\t\ttype = origType = tmp[1];\n\t\t\tnamespaces = ( tmp[2] || \"\" ).split( \".\" ).sort();\n\n\t\t\t// There *must* be a type, no attaching namespace-only handlers\n\t\t\tif ( !type ) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\t// If event changes its type, use the special event handlers for the changed type\n\t\t\tspecial = jQuery.event.special[ type ] || {};\n\n\t\t\t// If selector defined, determine special event api type, otherwise given type\n\t\t\ttype = ( selector ? special.delegateType : special.bindType ) || type;\n\n\t\t\t// Update special based on newly reset type\n\t\t\tspecial = jQuery.event.special[ type ] || {};\n\n\t\t\t// handleObj is passed to all event handlers\n\t\t\thandleObj = jQuery.extend({\n\t\t\t\ttype: type,\n\t\t\t\torigType: origType,\n\t\t\t\tdata: data,\n\t\t\t\thandler: handler,\n\t\t\t\tguid: handler.guid,\n\t\t\t\tselector: selector,\n\t\t\t\tneedsContext: selector && jQuery.expr.match.needsContext.test( selector ),\n\t\t\t\tnamespace: namespaces.join(\".\")\n\t\t\t}, handleObjIn );\n\n\t\t\t// Init the event handler queue if we're the first\n\t\t\tif ( !(handlers = events[ type ]) ) {\n\t\t\t\thandlers = events[ type ] = [];\n\t\t\t\thandlers.delegateCount = 0;\n\n\t\t\t\t// Only use addEventListener/attachEvent if the special events handler returns false\n\t\t\t\tif ( !special.setup || special.setup.call( elem, data, namespaces, eventHandle ) === false ) {\n\t\t\t\t\t// Bind the global event handler to the element\n\t\t\t\t\tif ( elem.addEventListener ) {\n\t\t\t\t\t\telem.addEventListener( type, eventHandle, false );\n\n\t\t\t\t\t} else if ( elem.attachEvent ) {\n\t\t\t\t\t\telem.attachEvent( \"on\" + type, eventHandle );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif ( special.add ) {\n\t\t\t\tspecial.add.call( elem, handleObj );\n\n\t\t\t\tif ( !handleObj.handler.guid ) {\n\t\t\t\t\thandleObj.handler.guid = handler.guid;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Add to the element's handler list, delegates in front\n\t\t\tif ( selector ) {\n\t\t\t\thandlers.splice( handlers.delegateCount++, 0, handleObj );\n\t\t\t} else {\n\t\t\t\thandlers.push( handleObj );\n\t\t\t}\n\n\t\t\t// Keep track of which events have ever been used, for event optimization\n\t\t\tjQuery.event.global[ type ] = true;\n\t\t}\n\n\t\t// Nullify elem to prevent memory leaks in IE\n\t\telem = null;\n\t},\n\n\t// Detach an event or set of events from an element\n\tremove: function( elem, types, handler, selector, mappedTypes ) {\n\t\tvar j, handleObj, tmp,\n\t\t\torigCount, t, events,\n\t\t\tspecial, handlers, type,\n\t\t\tnamespaces, origType,\n\t\t\telemData = jQuery.hasData( elem ) && jQuery._data( elem );\n\n\t\tif ( !elemData || !(events = elemData.events) ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Once for each type.namespace in types; type may be omitted\n\t\ttypes = ( types || \"\" ).match( rnotwhite ) || [ \"\" ];\n\t\tt = types.length;\n\t\twhile ( t-- ) {\n\t\t\ttmp = rtypenamespace.exec( types[t] ) || [];\n\t\t\ttype = origType = tmp[1];\n\t\t\tnamespaces = ( tmp[2] || \"\" ).split( \".\" ).sort();\n\n\t\t\t// Unbind all events (on this namespace, if provided) for the element\n\t\t\tif ( !type ) {\n\t\t\t\tfor ( type in events ) {\n\t\t\t\t\tjQuery.event.remove( elem, type + types[ t ], handler, selector, true );\n\t\t\t\t}\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tspecial = jQuery.event.special[ type ] || {};\n\t\t\ttype = ( selector ? special.delegateType : special.bindType ) || type;\n\t\t\thandlers = events[ type ] || [];\n\t\t\ttmp = tmp[2] && new RegExp( \"(^|\\\\.)\" + namespaces.join(\"\\\\.(?:.*\\\\.|)\") + \"(\\\\.|$)\" );\n\n\t\t\t// Remove matching events\n\t\t\torigCount = j = handlers.length;\n\t\t\twhile ( j-- ) {\n\t\t\t\thandleObj = handlers[ j ];\n\n\t\t\t\tif ( ( mappedTypes || origType === handleObj.origType ) &&\n\t\t\t\t\t( !handler || handler.guid === handleObj.guid ) &&\n\t\t\t\t\t( !tmp || tmp.test( handleObj.namespace ) ) &&\n\t\t\t\t\t( !selector || selector === handleObj.selector || selector === \"**\" && handleObj.selector ) ) {\n\t\t\t\t\thandlers.splice( j, 1 );\n\n\t\t\t\t\tif ( handleObj.selector ) {\n\t\t\t\t\t\thandlers.delegateCount--;\n\t\t\t\t\t}\n\t\t\t\t\tif ( special.remove ) {\n\t\t\t\t\t\tspecial.remove.call( elem, handleObj );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Remove generic event handler if we removed something and no more handlers exist\n\t\t\t// (avoids potential for endless recursion during removal of special event handlers)\n\t\t\tif ( origCount && !handlers.length ) {\n\t\t\t\tif ( !special.teardown || special.teardown.call( elem, namespaces, elemData.handle ) === false ) {\n\t\t\t\t\tjQuery.removeEvent( elem, type, elemData.handle );\n\t\t\t\t}\n\n\t\t\t\tdelete events[ type ];\n\t\t\t}\n\t\t}\n\n\t\t// Remove the expando if it's no longer used\n\t\tif ( jQuery.isEmptyObject( events ) ) {\n\t\t\tdelete elemData.handle;\n\n\t\t\t// removeData also checks for emptiness and clears the expando if empty\n\t\t\t// so use it instead of delete\n\t\t\tjQuery._removeData( elem, \"events\" );\n\t\t}\n\t},\n\n\ttrigger: function( event, data, elem, onlyHandlers ) {\n\t\tvar handle, ontype, cur,\n\t\t\tbubbleType, special, tmp, i,\n\t\t\teventPath = [ elem || document ],\n\t\t\ttype = hasOwn.call( event, \"type\" ) ? event.type : event,\n\t\t\tnamespaces = hasOwn.call( event, \"namespace\" ) ? event.namespace.split(\".\") : [];\n\n\t\tcur = tmp = elem = elem || document;\n\n\t\t// Don't do events on text and comment nodes\n\t\tif ( elem.nodeType === 3 || elem.nodeType === 8 ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// focus/blur morphs to focusin/out; ensure we're not firing them right now\n\t\tif ( rfocusMorph.test( type + jQuery.event.triggered ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\tif ( type.indexOf(\".\") >= 0 ) {\n\t\t\t// Namespaced trigger; create a regexp to match event type in handle()\n\t\t\tnamespaces = type.split(\".\");\n\t\t\ttype = namespaces.shift();\n\t\t\tnamespaces.sort();\n\t\t}\n\t\tontype = type.indexOf(\":\") < 0 && \"on\" + type;\n\n\t\t// Caller can pass in a jQuery.Event object, Object, or just an event type string\n\t\tevent = event[ jQuery.expando ] ?\n\t\t\tevent :\n\t\t\tnew jQuery.Event( type, typeof event === \"object\" && event );\n\n\t\t// Trigger bitmask: & 1 for native handlers; & 2 for jQuery (always true)\n\t\tevent.isTrigger = onlyHandlers ? 2 : 3;\n\t\tevent.namespace = namespaces.join(\".\");\n\t\tevent.namespace_re = event.namespace ?\n\t\t\tnew RegExp( \"(^|\\\\.)\" + namespaces.join(\"\\\\.(?:.*\\\\.|)\") + \"(\\\\.|$)\" ) :\n\t\t\tnull;\n\n\t\t// Clean up the event in case it is being reused\n\t\tevent.result = undefined;\n\t\tif ( !event.target ) {\n\t\t\tevent.target = elem;\n\t\t}\n\n\t\t// Clone any incoming data and prepend the event, creating the handler arg list\n\t\tdata = data == null ?\n\t\t\t[ event ] :\n\t\t\tjQuery.makeArray( data, [ event ] );\n\n\t\t// Allow special events to draw outside the lines\n\t\tspecial = jQuery.event.special[ type ] || {};\n\t\tif ( !onlyHandlers && special.trigger && special.trigger.apply( elem, data ) === false ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Determine event propagation path in advance, per W3C events spec (#9951)\n\t\t// Bubble up to document, then to window; watch for a global ownerDocument var (#9724)\n\t\tif ( !onlyHandlers && !special.noBubble && !jQuery.isWindow( elem ) ) {\n\n\t\t\tbubbleType = special.delegateType || type;\n\t\t\tif ( !rfocusMorph.test( bubbleType + type ) ) {\n\t\t\t\tcur = cur.parentNode;\n\t\t\t}\n\t\t\tfor ( ; cur; cur = cur.parentNode ) {\n\t\t\t\teventPath.push( cur );\n\t\t\t\ttmp = cur;\n\t\t\t}\n\n\t\t\t// Only add window if we got to document (e.g., not plain obj or detached DOM)\n\t\t\tif ( tmp === (elem.ownerDocument || document) ) {\n\t\t\t\teventPath.push( tmp.defaultView || tmp.parentWindow || window );\n\t\t\t}\n\t\t}\n\n\t\t// Fire handlers on the event path\n\t\ti = 0;\n\t\twhile ( (cur = eventPath[i++]) && !event.isPropagationStopped() ) {\n\n\t\t\tevent.type = i > 1 ?\n\t\t\t\tbubbleType :\n\t\t\t\tspecial.bindType || type;\n\n\t\t\t// jQuery handler\n\t\t\thandle = ( jQuery._data( cur, \"events\" ) || {} )[ event.type ] && jQuery._data( cur, \"handle\" );\n\t\t\tif ( handle ) {\n\t\t\t\thandle.apply( cur, data );\n\t\t\t}\n\n\t\t\t// Native handler\n\t\t\thandle = ontype && cur[ ontype ];\n\t\t\tif ( handle && handle.apply && jQuery.acceptData( cur ) ) {\n\t\t\t\tevent.result = handle.apply( cur, data );\n\t\t\t\tif ( event.result === false ) {\n\t\t\t\t\tevent.preventDefault();\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tevent.type = type;\n\n\t\t// If nobody prevented the default action, do it now\n\t\tif ( !onlyHandlers && !event.isDefaultPrevented() ) {\n\n\t\t\tif ( (!special._default || special._default.apply( eventPath.pop(), data ) === false) &&\n\t\t\t\tjQuery.acceptData( elem ) ) {\n\n\t\t\t\t// Call a native DOM method on the target with the same name name as the event.\n\t\t\t\t// Can't use an .isFunction() check here because IE6/7 fails that test.\n\t\t\t\t// Don't do default actions on window, that's where global variables be (#6170)\n\t\t\t\tif ( ontype && elem[ type ] && !jQuery.isWindow( elem ) ) {\n\n\t\t\t\t\t// Don't re-trigger an onFOO event when we call its FOO() method\n\t\t\t\t\ttmp = elem[ ontype ];\n\n\t\t\t\t\tif ( tmp ) {\n\t\t\t\t\t\telem[ ontype ] = null;\n\t\t\t\t\t}\n\n\t\t\t\t\t// Prevent re-triggering of the same event, since we already bubbled it above\n\t\t\t\t\tjQuery.event.triggered = type;\n\t\t\t\t\ttry {\n\t\t\t\t\t\telem[ type ]();\n\t\t\t\t\t} catch ( e ) {\n\t\t\t\t\t\t// IE<9 dies on focus/blur to hidden element (#1486,#12518)\n\t\t\t\t\t\t// only reproducible on winXP IE8 native, not IE9 in IE8 mode\n\t\t\t\t\t}\n\t\t\t\t\tjQuery.event.triggered = undefined;\n\n\t\t\t\t\tif ( tmp ) {\n\t\t\t\t\t\telem[ ontype ] = tmp;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn event.result;\n\t},\n\n\tdispatch: function( event ) {\n\n\t\t// Make a writable jQuery.Event from the native event object\n\t\tevent = jQuery.event.fix( event );\n\n\t\tvar i, ret, handleObj, matched, j,\n\t\t\thandlerQueue = [],\n\t\t\targs = slice.call( arguments ),\n\t\t\thandlers = ( jQuery._data( this, \"events\" ) || {} )[ event.type ] || [],\n\t\t\tspecial = jQuery.event.special[ event.type ] || {};\n\n\t\t// Use the fix-ed jQuery.Event rather than the (read-only) native event\n\t\targs[0] = event;\n\t\tevent.delegateTarget = this;\n\n\t\t// Call the preDispatch hook for the mapped type, and let it bail if desired\n\t\tif ( special.preDispatch && special.preDispatch.call( this, event ) === false ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Determine handlers\n\t\thandlerQueue = jQuery.event.handlers.call( this, event, handlers );\n\n\t\t// Run delegates first; they may want to stop propagation beneath us\n\t\ti = 0;\n\t\twhile ( (matched = handlerQueue[ i++ ]) && !event.isPropagationStopped() ) {\n\t\t\tevent.currentTarget = matched.elem;\n\n\t\t\tj = 0;\n\t\t\twhile ( (handleObj = matched.handlers[ j++ ]) && !event.isImmediatePropagationStopped() ) {\n\n\t\t\t\t// Triggered event must either 1) have no namespace, or\n\t\t\t\t// 2) have namespace(s) a subset or equal to those in the bound event (both can have no namespace).\n\t\t\t\tif ( !event.namespace_re || event.namespace_re.test( handleObj.namespace ) ) {\n\n\t\t\t\t\tevent.handleObj = handleObj;\n\t\t\t\t\tevent.data = handleObj.data;\n\n\t\t\t\t\tret = ( (jQuery.event.special[ handleObj.origType ] || {}).handle || handleObj.handler )\n\t\t\t\t\t\t\t.apply( matched.elem, args );\n\n\t\t\t\t\tif ( ret !== undefined ) {\n\t\t\t\t\t\tif ( (event.result = ret) === false ) {\n\t\t\t\t\t\t\tevent.preventDefault();\n\t\t\t\t\t\t\tevent.stopPropagation();\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Call the postDispatch hook for the mapped type\n\t\tif ( special.postDispatch ) {\n\t\t\tspecial.postDispatch.call( this, event );\n\t\t}\n\n\t\treturn event.result;\n\t},\n\n\thandlers: function( event, handlers ) {\n\t\tvar sel, handleObj, matches, i,\n\t\t\thandlerQueue = [],\n\t\t\tdelegateCount = handlers.delegateCount,\n\t\t\tcur = event.target;\n\n\t\t// Find delegate handlers\n\t\t// Black-hole SVG <use> instance trees (#13180)\n\t\t// Avoid non-left-click bubbling in Firefox (#3861)\n\t\tif ( delegateCount && cur.nodeType && (!event.button || event.type !== \"click\") ) {\n\n\t\t\t/* jshint eqeqeq: false */\n\t\t\tfor ( ; cur != this; cur = cur.parentNode || this ) {\n\t\t\t\t/* jshint eqeqeq: true */\n\n\t\t\t\t// Don't check non-elements (#13208)\n\t\t\t\t// Don't process clicks on disabled elements (#6911, #8165, #11382, #11764)\n\t\t\t\tif ( cur.nodeType === 1 && (cur.disabled !== true || event.type !== \"click\") ) {\n\t\t\t\t\tmatches = [];\n\t\t\t\t\tfor ( i = 0; i < delegateCount; i++ ) {\n\t\t\t\t\t\thandleObj = handlers[ i ];\n\n\t\t\t\t\t\t// Don't conflict with Object.prototype properties (#13203)\n\t\t\t\t\t\tsel = handleObj.selector + \" \";\n\n\t\t\t\t\t\tif ( matches[ sel ] === undefined ) {\n\t\t\t\t\t\t\tmatches[ sel ] = handleObj.needsContext ?\n\t\t\t\t\t\t\t\tjQuery( sel, this ).index( cur ) >= 0 :\n\t\t\t\t\t\t\t\tjQuery.find( sel, this, null, [ cur ] ).length;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif ( matches[ sel ] ) {\n\t\t\t\t\t\t\tmatches.push( handleObj );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tif ( matches.length ) {\n\t\t\t\t\t\thandlerQueue.push({ elem: cur, handlers: matches });\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Add the remaining (directly-bound) handlers\n\t\tif ( delegateCount < handlers.length ) {\n\t\t\thandlerQueue.push({ elem: this, handlers: handlers.slice( delegateCount ) });\n\t\t}\n\n\t\treturn handlerQueue;\n\t},\n\n\tfix: function( event ) {\n\t\tif ( event[ jQuery.expando ] ) {\n\t\t\treturn event;\n\t\t}\n\n\t\t// Create a writable copy of the event object and normalize some properties\n\t\tvar i, prop, copy,\n\t\t\ttype = event.type,\n\t\t\toriginalEvent = event,\n\t\t\tfixHook = this.fixHooks[ type ];\n\n\t\tif ( !fixHook ) {\n\t\t\tthis.fixHooks[ type ] = fixHook =\n\t\t\t\trmouseEvent.test( type ) ? this.mouseHooks :\n\t\t\t\trkeyEvent.test( type ) ? this.keyHooks :\n\t\t\t\t{};\n\t\t}\n\t\tcopy = fixHook.props ? this.props.concat( fixHook.props ) : this.props;\n\n\t\tevent = new jQuery.Event( originalEvent );\n\n\t\ti = copy.length;\n\t\twhile ( i-- ) {\n\t\t\tprop = copy[ i ];\n\t\t\tevent[ prop ] = originalEvent[ prop ];\n\t\t}\n\n\t\t// Support: IE<9\n\t\t// Fix target property (#1925)\n\t\tif ( !event.target ) {\n\t\t\tevent.target = originalEvent.srcElement || document;\n\t\t}\n\n\t\t// Support: Chrome 23+, Safari?\n\t\t// Target should not be a text node (#504, #13143)\n\t\tif ( event.target.nodeType === 3 ) {\n\t\t\tevent.target = event.target.parentNode;\n\t\t}\n\n\t\t// Support: IE<9\n\t\t// For mouse/key events, metaKey==false if it's undefined (#3368, #11328)\n\t\tevent.metaKey = !!event.metaKey;\n\n\t\treturn fixHook.filter ? fixHook.filter( event, originalEvent ) : event;\n\t},\n\n\t// Includes some event props shared by KeyEvent and MouseEvent\n\tprops: \"altKey bubbles cancelable ctrlKey currentTarget eventPhase metaKey relatedTarget shiftKey target timeStamp view which\".split(\" \"),\n\n\tfixHooks: {},\n\n\tkeyHooks: {\n\t\tprops: \"char charCode key keyCode\".split(\" \"),\n\t\tfilter: function( event, original ) {\n\n\t\t\t// Add which for key events\n\t\t\tif ( event.which == null ) {\n\t\t\t\tevent.which = original.charCode != null ? original.charCode : original.keyCode;\n\t\t\t}\n\n\t\t\treturn event;\n\t\t}\n\t},\n\n\tmouseHooks: {\n\t\tprops: \"button buttons clientX clientY fromElement offsetX offsetY pageX pageY screenX screenY toElement\".split(\" \"),\n\t\tfilter: function( event, original ) {\n\t\t\tvar body, eventDoc, doc,\n\t\t\t\tbutton = original.button,\n\t\t\t\tfromElement = original.fromElement;\n\n\t\t\t// Calculate pageX/Y if missing and clientX/Y available\n\t\t\tif ( event.pageX == null && original.clientX != null ) {\n\t\t\t\teventDoc = event.target.ownerDocument || document;\n\t\t\t\tdoc = eventDoc.documentElement;\n\t\t\t\tbody = eventDoc.body;\n\n\t\t\t\tevent.pageX = original.clientX + ( doc && doc.scrollLeft || body && body.scrollLeft || 0 ) - ( doc && doc.clientLeft || body && body.clientLeft || 0 );\n\t\t\t\tevent.pageY = original.clientY + ( doc && doc.scrollTop  || body && body.scrollTop  || 0 ) - ( doc && doc.clientTop  || body && body.clientTop  || 0 );\n\t\t\t}\n\n\t\t\t// Add relatedTarget, if necessary\n\t\t\tif ( !event.relatedTarget && fromElement ) {\n\t\t\t\tevent.relatedTarget = fromElement === event.target ? original.toElement : fromElement;\n\t\t\t}\n\n\t\t\t// Add which for click: 1 === left; 2 === middle; 3 === right\n\t\t\t// Note: button is not normalized, so don't use it\n\t\t\tif ( !event.which && button !== undefined ) {\n\t\t\t\tevent.which = ( button & 1 ? 1 : ( button & 2 ? 3 : ( button & 4 ? 2 : 0 ) ) );\n\t\t\t}\n\n\t\t\treturn event;\n\t\t}\n\t},\n\n\tspecial: {\n\t\tload: {\n\t\t\t// Prevent triggered image.load events from bubbling to window.load\n\t\t\tnoBubble: true\n\t\t},\n\t\tfocus: {\n\t\t\t// Fire native event if possible so blur/focus sequence is correct\n\t\t\ttrigger: function() {\n\t\t\t\tif ( this !== safeActiveElement() && this.focus ) {\n\t\t\t\t\ttry {\n\t\t\t\t\t\tthis.focus();\n\t\t\t\t\t\treturn false;\n\t\t\t\t\t} catch ( e ) {\n\t\t\t\t\t\t// Support: IE<9\n\t\t\t\t\t\t// If we error on focus to hidden element (#1486, #12518),\n\t\t\t\t\t\t// let .trigger() run the handlers\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t},\n\t\t\tdelegateType: \"focusin\"\n\t\t},\n\t\tblur: {\n\t\t\ttrigger: function() {\n\t\t\t\tif ( this === safeActiveElement() && this.blur ) {\n\t\t\t\t\tthis.blur();\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t},\n\t\t\tdelegateType: \"focusout\"\n\t\t},\n\t\tclick: {\n\t\t\t// For checkbox, fire native event so checked state will be right\n\t\t\ttrigger: function() {\n\t\t\t\tif ( jQuery.nodeName( this, \"input\" ) && this.type === \"checkbox\" && this.click ) {\n\t\t\t\t\tthis.click();\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t},\n\n\t\t\t// For cross-browser consistency, don't fire native .click() on links\n\t\t\t_default: function( event ) {\n\t\t\t\treturn jQuery.nodeName( event.target, \"a\" );\n\t\t\t}\n\t\t},\n\n\t\tbeforeunload: {\n\t\t\tpostDispatch: function( event ) {\n\n\t\t\t\t// Support: Firefox 20+\n\t\t\t\t// Firefox doesn't alert if the returnValue field is not set.\n\t\t\t\tif ( event.result !== undefined && event.originalEvent ) {\n\t\t\t\t\tevent.originalEvent.returnValue = event.result;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t},\n\n\tsimulate: function( type, elem, event, bubble ) {\n\t\t// Piggyback on a donor event to simulate a different one.\n\t\t// Fake originalEvent to avoid donor's stopPropagation, but if the\n\t\t// simulated event prevents default then we do the same on the donor.\n\t\tvar e = jQuery.extend(\n\t\t\tnew jQuery.Event(),\n\t\t\tevent,\n\t\t\t{\n\t\t\t\ttype: type,\n\t\t\t\tisSimulated: true,\n\t\t\t\toriginalEvent: {}\n\t\t\t}\n\t\t);\n\t\tif ( bubble ) {\n\t\t\tjQuery.event.trigger( e, null, elem );\n\t\t} else {\n\t\t\tjQuery.event.dispatch.call( elem, e );\n\t\t}\n\t\tif ( e.isDefaultPrevented() ) {\n\t\t\tevent.preventDefault();\n\t\t}\n\t}\n};\n\njQuery.removeEvent = document.removeEventListener ?\n\tfunction( elem, type, handle ) {\n\t\tif ( elem.removeEventListener ) {\n\t\t\telem.removeEventListener( type, handle, false );\n\t\t}\n\t} :\n\tfunction( elem, type, handle ) {\n\t\tvar name = \"on\" + type;\n\n\t\tif ( elem.detachEvent ) {\n\n\t\t\t// #8545, #7054, preventing memory leaks for custom events in IE6-8\n\t\t\t// detachEvent needed property on element, by name of that event, to properly expose it to GC\n\t\t\tif ( typeof elem[ name ] === strundefined ) {\n\t\t\t\telem[ name ] = null;\n\t\t\t}\n\n\t\t\telem.detachEvent( name, handle );\n\t\t}\n\t};\n\njQuery.Event = function( src, props ) {\n\t// Allow instantiation without the 'new' keyword\n\tif ( !(this instanceof jQuery.Event) ) {\n\t\treturn new jQuery.Event( src, props );\n\t}\n\n\t// Event object\n\tif ( src && src.type ) {\n\t\tthis.originalEvent = src;\n\t\tthis.type = src.type;\n\n\t\t// Events bubbling up the document may have been marked as prevented\n\t\t// by a handler lower down the tree; reflect the correct value.\n\t\tthis.isDefaultPrevented = src.defaultPrevented ||\n\t\t\t\tsrc.defaultPrevented === undefined &&\n\t\t\t\t// Support: IE < 9, Android < 4.0\n\t\t\t\tsrc.returnValue === false ?\n\t\t\treturnTrue :\n\t\t\treturnFalse;\n\n\t// Event type\n\t} else {\n\t\tthis.type = src;\n\t}\n\n\t// Put explicitly provided properties onto the event object\n\tif ( props ) {\n\t\tjQuery.extend( this, props );\n\t}\n\n\t// Create a timestamp if incoming event doesn't have one\n\tthis.timeStamp = src && src.timeStamp || jQuery.now();\n\n\t// Mark it as fixed\n\tthis[ jQuery.expando ] = true;\n};\n\n// jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding\n// http://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html\njQuery.Event.prototype = {\n\tisDefaultPrevented: returnFalse,\n\tisPropagationStopped: returnFalse,\n\tisImmediatePropagationStopped: returnFalse,\n\n\tpreventDefault: function() {\n\t\tvar e = this.originalEvent;\n\n\t\tthis.isDefaultPrevented = returnTrue;\n\t\tif ( !e ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// If preventDefault exists, run it on the original event\n\t\tif ( e.preventDefault ) {\n\t\t\te.preventDefault();\n\n\t\t// Support: IE\n\t\t// Otherwise set the returnValue property of the original event to false\n\t\t} else {\n\t\t\te.returnValue = false;\n\t\t}\n\t},\n\tstopPropagation: function() {\n\t\tvar e = this.originalEvent;\n\n\t\tthis.isPropagationStopped = returnTrue;\n\t\tif ( !e ) {\n\t\t\treturn;\n\t\t}\n\t\t// If stopPropagation exists, run it on the original event\n\t\tif ( e.stopPropagation ) {\n\t\t\te.stopPropagation();\n\t\t}\n\n\t\t// Support: IE\n\t\t// Set the cancelBubble property of the original event to true\n\t\te.cancelBubble = true;\n\t},\n\tstopImmediatePropagation: function() {\n\t\tvar e = this.originalEvent;\n\n\t\tthis.isImmediatePropagationStopped = returnTrue;\n\n\t\tif ( e && e.stopImmediatePropagation ) {\n\t\t\te.stopImmediatePropagation();\n\t\t}\n\n\t\tthis.stopPropagation();\n\t}\n};\n\n// Create mouseenter/leave events using mouseover/out and event-time checks\njQuery.each({\n\tmouseenter: \"mouseover\",\n\tmouseleave: \"mouseout\",\n\tpointerenter: \"pointerover\",\n\tpointerleave: \"pointerout\"\n}, function( orig, fix ) {\n\tjQuery.event.special[ orig ] = {\n\t\tdelegateType: fix,\n\t\tbindType: fix,\n\n\t\thandle: function( event ) {\n\t\t\tvar ret,\n\t\t\t\ttarget = this,\n\t\t\t\trelated = event.relatedTarget,\n\t\t\t\thandleObj = event.handleObj;\n\n\t\t\t// For mousenter/leave call the handler if related is outside the target.\n\t\t\t// NB: No relatedTarget if the mouse left/entered the browser window\n\t\t\tif ( !related || (related !== target && !jQuery.contains( target, related )) ) {\n\t\t\t\tevent.type = handleObj.origType;\n\t\t\t\tret = handleObj.handler.apply( this, arguments );\n\t\t\t\tevent.type = fix;\n\t\t\t}\n\t\t\treturn ret;\n\t\t}\n\t};\n});\n\n// IE submit delegation\nif ( !support.submitBubbles ) {\n\n\tjQuery.event.special.submit = {\n\t\tsetup: function() {\n\t\t\t// Only need this for delegated form submit events\n\t\t\tif ( jQuery.nodeName( this, \"form\" ) ) {\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\t// Lazy-add a submit handler when a descendant form may potentially be submitted\n\t\t\tjQuery.event.add( this, \"click._submit keypress._submit\", function( e ) {\n\t\t\t\t// Node name check avoids a VML-related crash in IE (#9807)\n\t\t\t\tvar elem = e.target,\n\t\t\t\t\tform = jQuery.nodeName( elem, \"input\" ) || jQuery.nodeName( elem, \"button\" ) ? elem.form : undefined;\n\t\t\t\tif ( form && !jQuery._data( form, \"submitBubbles\" ) ) {\n\t\t\t\t\tjQuery.event.add( form, \"submit._submit\", function( event ) {\n\t\t\t\t\t\tevent._submit_bubble = true;\n\t\t\t\t\t});\n\t\t\t\t\tjQuery._data( form, \"submitBubbles\", true );\n\t\t\t\t}\n\t\t\t});\n\t\t\t// return undefined since we don't need an event listener\n\t\t},\n\n\t\tpostDispatch: function( event ) {\n\t\t\t// If form was submitted by the user, bubble the event up the tree\n\t\t\tif ( event._submit_bubble ) {\n\t\t\t\tdelete event._submit_bubble;\n\t\t\t\tif ( this.parentNode && !event.isTrigger ) {\n\t\t\t\t\tjQuery.event.simulate( \"submit\", this.parentNode, event, true );\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\n\t\tteardown: function() {\n\t\t\t// Only need this for delegated form submit events\n\t\t\tif ( jQuery.nodeName( this, \"form\" ) ) {\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\t// Remove delegated handlers; cleanData eventually reaps submit handlers attached above\n\t\t\tjQuery.event.remove( this, \"._submit\" );\n\t\t}\n\t};\n}\n\n// IE change delegation and checkbox/radio fix\nif ( !support.changeBubbles ) {\n\n\tjQuery.event.special.change = {\n\n\t\tsetup: function() {\n\n\t\t\tif ( rformElems.test( this.nodeName ) ) {\n\t\t\t\t// IE doesn't fire change on a check/radio until blur; trigger it on click\n\t\t\t\t// after a propertychange. Eat the blur-change in special.change.handle.\n\t\t\t\t// This still fires onchange a second time for check/radio after blur.\n\t\t\t\tif ( this.type === \"checkbox\" || this.type === \"radio\" ) {\n\t\t\t\t\tjQuery.event.add( this, \"propertychange._change\", function( event ) {\n\t\t\t\t\t\tif ( event.originalEvent.propertyName === \"checked\" ) {\n\t\t\t\t\t\t\tthis._just_changed = true;\n\t\t\t\t\t\t}\n\t\t\t\t\t});\n\t\t\t\t\tjQuery.event.add( this, \"click._change\", function( event ) {\n\t\t\t\t\t\tif ( this._just_changed && !event.isTrigger ) {\n\t\t\t\t\t\t\tthis._just_changed = false;\n\t\t\t\t\t\t}\n\t\t\t\t\t\t// Allow triggered, simulated change events (#11500)\n\t\t\t\t\t\tjQuery.event.simulate( \"change\", this, event, true );\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\t// Delegated event; lazy-add a change handler on descendant inputs\n\t\t\tjQuery.event.add( this, \"beforeactivate._change\", function( e ) {\n\t\t\t\tvar elem = e.target;\n\n\t\t\t\tif ( rformElems.test( elem.nodeName ) && !jQuery._data( elem, \"changeBubbles\" ) ) {\n\t\t\t\t\tjQuery.event.add( elem, \"change._change\", function( event ) {\n\t\t\t\t\t\tif ( this.parentNode && !event.isSimulated && !event.isTrigger ) {\n\t\t\t\t\t\t\tjQuery.event.simulate( \"change\", this.parentNode, event, true );\n\t\t\t\t\t\t}\n\t\t\t\t\t});\n\t\t\t\t\tjQuery._data( elem, \"changeBubbles\", true );\n\t\t\t\t}\n\t\t\t});\n\t\t},\n\n\t\thandle: function( event ) {\n\t\t\tvar elem = event.target;\n\n\t\t\t// Swallow native change events from checkbox/radio, we already triggered them above\n\t\t\tif ( this !== elem || event.isSimulated || event.isTrigger || (elem.type !== \"radio\" && elem.type !== \"checkbox\") ) {\n\t\t\t\treturn event.handleObj.handler.apply( this, arguments );\n\t\t\t}\n\t\t},\n\n\t\tteardown: function() {\n\t\t\tjQuery.event.remove( this, \"._change\" );\n\n\t\t\treturn !rformElems.test( this.nodeName );\n\t\t}\n\t};\n}\n\n// Create \"bubbling\" focus and blur events\nif ( !support.focusinBubbles ) {\n\tjQuery.each({ focus: \"focusin\", blur: \"focusout\" }, function( orig, fix ) {\n\n\t\t// Attach a single capturing handler on the document while someone wants focusin/focusout\n\t\tvar handler = function( event ) {\n\t\t\t\tjQuery.event.simulate( fix, event.target, jQuery.event.fix( event ), true );\n\t\t\t};\n\n\t\tjQuery.event.special[ fix ] = {\n\t\t\tsetup: function() {\n\t\t\t\tvar doc = this.ownerDocument || this,\n\t\t\t\t\tattaches = jQuery._data( doc, fix );\n\n\t\t\t\tif ( !attaches ) {\n\t\t\t\t\tdoc.addEventListener( orig, handler, true );\n\t\t\t\t}\n\t\t\t\tjQuery._data( doc, fix, ( attaches || 0 ) + 1 );\n\t\t\t},\n\t\t\tteardown: function() {\n\t\t\t\tvar doc = this.ownerDocument || this,\n\t\t\t\t\tattaches = jQuery._data( doc, fix ) - 1;\n\n\t\t\t\tif ( !attaches ) {\n\t\t\t\t\tdoc.removeEventListener( orig, handler, true );\n\t\t\t\t\tjQuery._removeData( doc, fix );\n\t\t\t\t} else {\n\t\t\t\t\tjQuery._data( doc, fix, attaches );\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\t});\n}\n\njQuery.fn.extend({\n\n\ton: function( types, selector, data, fn, /*INTERNAL*/ one ) {\n\t\tvar type, origFn;\n\n\t\t// Types can be a map of types/handlers\n\t\tif ( typeof types === \"object\" ) {\n\t\t\t// ( types-Object, selector, data )\n\t\t\tif ( typeof selector !== \"string\" ) {\n\t\t\t\t// ( types-Object, data )\n\t\t\t\tdata = data || selector;\n\t\t\t\tselector = undefined;\n\t\t\t}\n\t\t\tfor ( type in types ) {\n\t\t\t\tthis.on( type, selector, data, types[ type ], one );\n\t\t\t}\n\t\t\treturn this;\n\t\t}\n\n\t\tif ( data == null && fn == null ) {\n\t\t\t// ( types, fn )\n\t\t\tfn = selector;\n\t\t\tdata = selector = undefined;\n\t\t} else if ( fn == null ) {\n\t\t\tif ( typeof selector === \"string\" ) {\n\t\t\t\t// ( types, selector, fn )\n\t\t\t\tfn = data;\n\t\t\t\tdata = undefined;\n\t\t\t} else {\n\t\t\t\t// ( types, data, fn )\n\t\t\t\tfn = data;\n\t\t\t\tdata = selector;\n\t\t\t\tselector = undefined;\n\t\t\t}\n\t\t}\n\t\tif ( fn === false ) {\n\t\t\tfn = returnFalse;\n\t\t} else if ( !fn ) {\n\t\t\treturn this;\n\t\t}\n\n\t\tif ( one === 1 ) {\n\t\t\torigFn = fn;\n\t\t\tfn = function( event ) {\n\t\t\t\t// Can use an empty set, since event contains the info\n\t\t\t\tjQuery().off( event );\n\t\t\t\treturn origFn.apply( this, arguments );\n\t\t\t};\n\t\t\t// Use same guid so caller can remove using origFn\n\t\t\tfn.guid = origFn.guid || ( origFn.guid = jQuery.guid++ );\n\t\t}\n\t\treturn this.each( function() {\n\t\t\tjQuery.event.add( this, types, fn, data, selector );\n\t\t});\n\t},\n\tone: function( types, selector, data, fn ) {\n\t\treturn this.on( types, selector, data, fn, 1 );\n\t},\n\toff: function( types, selector, fn ) {\n\t\tvar handleObj, type;\n\t\tif ( types && types.preventDefault && types.handleObj ) {\n\t\t\t// ( event )  dispatched jQuery.Event\n\t\t\thandleObj = types.handleObj;\n\t\t\tjQuery( types.delegateTarget ).off(\n\t\t\t\thandleObj.namespace ? handleObj.origType + \".\" + handleObj.namespace : handleObj.origType,\n\t\t\t\thandleObj.selector,\n\t\t\t\thandleObj.handler\n\t\t\t);\n\t\t\treturn this;\n\t\t}\n\t\tif ( typeof types === \"object\" ) {\n\t\t\t// ( types-object [, selector] )\n\t\t\tfor ( type in types ) {\n\t\t\t\tthis.off( type, selector, types[ type ] );\n\t\t\t}\n\t\t\treturn this;\n\t\t}\n\t\tif ( selector === false || typeof selector === \"function\" ) {\n\t\t\t// ( types [, fn] )\n\t\t\tfn = selector;\n\t\t\tselector = undefined;\n\t\t}\n\t\tif ( fn === false ) {\n\t\t\tfn = returnFalse;\n\t\t}\n\t\treturn this.each(function() {\n\t\t\tjQuery.event.remove( this, types, fn, selector );\n\t\t});\n\t},\n\n\ttrigger: function( type, data ) {\n\t\treturn this.each(function() {\n\t\t\tjQuery.event.trigger( type, data, this );\n\t\t});\n\t},\n\ttriggerHandler: function( type, data ) {\n\t\tvar elem = this[0];\n\t\tif ( elem ) {\n\t\t\treturn jQuery.event.trigger( type, data, elem, true );\n\t\t}\n\t}\n});\n\n\nfunction createSafeFragment( document ) {\n\tvar list = nodeNames.split( \"|\" ),\n\t\tsafeFrag = document.createDocumentFragment();\n\n\tif ( safeFrag.createElement ) {\n\t\twhile ( list.length ) {\n\t\t\tsafeFrag.createElement(\n\t\t\t\tlist.pop()\n\t\t\t);\n\t\t}\n\t}\n\treturn safeFrag;\n}\n\nvar nodeNames = \"abbr|article|aside|audio|bdi|canvas|data|datalist|details|figcaption|figure|footer|\" +\n\t\t\"header|hgroup|mark|meter|nav|output|progress|section|summary|time|video\",\n\trinlinejQuery = / jQuery\\d+=\"(?:null|\\d+)\"/g,\n\trnoshimcache = new RegExp(\"<(?:\" + nodeNames + \")[\\\\s/>]\", \"i\"),\n\trleadingWhitespace = /^\\s+/,\n\trxhtmlTag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\\w:]+)[^>]*)\\/>/gi,\n\trtagName = /<([\\w:]+)/,\n\trtbody = /<tbody/i,\n\trhtml = /<|&#?\\w+;/,\n\trnoInnerhtml = /<(?:script|style|link)/i,\n\t// checked=\"checked\" or checked\n\trchecked = /checked\\s*(?:[^=]|=\\s*.checked.)/i,\n\trscriptType = /^$|\\/(?:java|ecma)script/i,\n\trscriptTypeMasked = /^true\\/(.*)/,\n\trcleanScript = /^\\s*<!(?:\\[CDATA\\[|--)|(?:\\]\\]|--)>\\s*$/g,\n\n\t// We have to close these tags to support XHTML (#13200)\n\twrapMap = {\n\t\toption: [ 1, \"<select multiple='multiple'>\", \"</select>\" ],\n\t\tlegend: [ 1, \"<fieldset>\", \"</fieldset>\" ],\n\t\tarea: [ 1, \"<map>\", \"</map>\" ],\n\t\tparam: [ 1, \"<object>\", \"</object>\" ],\n\t\tthead: [ 1, \"<table>\", \"</table>\" ],\n\t\ttr: [ 2, \"<table><tbody>\", \"</tbody></table>\" ],\n\t\tcol: [ 2, \"<table><tbody></tbody><colgroup>\", \"</colgroup></table>\" ],\n\t\ttd: [ 3, \"<table><tbody><tr>\", \"</tr></tbody></table>\" ],\n\n\t\t// IE6-8 can't serialize link, script, style, or any html5 (NoScope) tags,\n\t\t// unless wrapped in a div with non-breaking characters in front of it.\n\t\t_default: support.htmlSerialize ? [ 0, \"\", \"\" ] : [ 1, \"X<div>\", \"</div>\"  ]\n\t},\n\tsafeFragment = createSafeFragment( document ),\n\tfragmentDiv = safeFragment.appendChild( document.createElement(\"div\") );\n\nwrapMap.optgroup = wrapMap.option;\nwrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead;\nwrapMap.th = wrapMap.td;\n\nfunction getAll( context, tag ) {\n\tvar elems, elem,\n\t\ti = 0,\n\t\tfound = typeof context.getElementsByTagName !== strundefined ? context.getElementsByTagName( tag || \"*\" ) :\n\t\t\ttypeof context.querySelectorAll !== strundefined ? context.querySelectorAll( tag || \"*\" ) :\n\t\t\tundefined;\n\n\tif ( !found ) {\n\t\tfor ( found = [], elems = context.childNodes || context; (elem = elems[i]) != null; i++ ) {\n\t\t\tif ( !tag || jQuery.nodeName( elem, tag ) ) {\n\t\t\t\tfound.push( elem );\n\t\t\t} else {\n\t\t\t\tjQuery.merge( found, getAll( elem, tag ) );\n\t\t\t}\n\t\t}\n\t}\n\n\treturn tag === undefined || tag && jQuery.nodeName( context, tag ) ?\n\t\tjQuery.merge( [ context ], found ) :\n\t\tfound;\n}\n\n// Used in buildFragment, fixes the defaultChecked property\nfunction fixDefaultChecked( elem ) {\n\tif ( rcheckableType.test( elem.type ) ) {\n\t\telem.defaultChecked = elem.checked;\n\t}\n}\n\n// Support: IE<8\n// Manipulating tables requires a tbody\nfunction manipulationTarget( elem, content ) {\n\treturn jQuery.nodeName( elem, \"table\" ) &&\n\t\tjQuery.nodeName( content.nodeType !== 11 ? content : content.firstChild, \"tr\" ) ?\n\n\t\telem.getElementsByTagName(\"tbody\")[0] ||\n\t\t\telem.appendChild( elem.ownerDocument.createElement(\"tbody\") ) :\n\t\telem;\n}\n\n// Replace/restore the type attribute of script elements for safe DOM manipulation\nfunction disableScript( elem ) {\n\telem.type = (jQuery.find.attr( elem, \"type\" ) !== null) + \"/\" + elem.type;\n\treturn elem;\n}\nfunction restoreScript( elem ) {\n\tvar match = rscriptTypeMasked.exec( elem.type );\n\tif ( match ) {\n\t\telem.type = match[1];\n\t} else {\n\t\telem.removeAttribute(\"type\");\n\t}\n\treturn elem;\n}\n\n// Mark scripts as having already been evaluated\nfunction setGlobalEval( elems, refElements ) {\n\tvar elem,\n\t\ti = 0;\n\tfor ( ; (elem = elems[i]) != null; i++ ) {\n\t\tjQuery._data( elem, \"globalEval\", !refElements || jQuery._data( refElements[i], \"globalEval\" ) );\n\t}\n}\n\nfunction cloneCopyEvent( src, dest ) {\n\n\tif ( dest.nodeType !== 1 || !jQuery.hasData( src ) ) {\n\t\treturn;\n\t}\n\n\tvar type, i, l,\n\t\toldData = jQuery._data( src ),\n\t\tcurData = jQuery._data( dest, oldData ),\n\t\tevents = oldData.events;\n\n\tif ( events ) {\n\t\tdelete curData.handle;\n\t\tcurData.events = {};\n\n\t\tfor ( type in events ) {\n\t\t\tfor ( i = 0, l = events[ type ].length; i < l; i++ ) {\n\t\t\t\tjQuery.event.add( dest, type, events[ type ][ i ] );\n\t\t\t}\n\t\t}\n\t}\n\n\t// make the cloned public data object a copy from the original\n\tif ( curData.data ) {\n\t\tcurData.data = jQuery.extend( {}, curData.data );\n\t}\n}\n\nfunction fixCloneNodeIssues( src, dest ) {\n\tvar nodeName, e, data;\n\n\t// We do not need to do anything for non-Elements\n\tif ( dest.nodeType !== 1 ) {\n\t\treturn;\n\t}\n\n\tnodeName = dest.nodeName.toLowerCase();\n\n\t// IE6-8 copies events bound via attachEvent when using cloneNode.\n\tif ( !support.noCloneEvent && dest[ jQuery.expando ] ) {\n\t\tdata = jQuery._data( dest );\n\n\t\tfor ( e in data.events ) {\n\t\t\tjQuery.removeEvent( dest, e, data.handle );\n\t\t}\n\n\t\t// Event data gets referenced instead of copied if the expando gets copied too\n\t\tdest.removeAttribute( jQuery.expando );\n\t}\n\n\t// IE blanks contents when cloning scripts, and tries to evaluate newly-set text\n\tif ( nodeName === \"script\" && dest.text !== src.text ) {\n\t\tdisableScript( dest ).text = src.text;\n\t\trestoreScript( dest );\n\n\t// IE6-10 improperly clones children of object elements using classid.\n\t// IE10 throws NoModificationAllowedError if parent is null, #12132.\n\t} else if ( nodeName === \"object\" ) {\n\t\tif ( dest.parentNode ) {\n\t\t\tdest.outerHTML = src.outerHTML;\n\t\t}\n\n\t\t// This path appears unavoidable for IE9. When cloning an object\n\t\t// element in IE9, the outerHTML strategy above is not sufficient.\n\t\t// If the src has innerHTML and the destination does not,\n\t\t// copy the src.innerHTML into the dest.innerHTML. #10324\n\t\tif ( support.html5Clone && ( src.innerHTML && !jQuery.trim(dest.innerHTML) ) ) {\n\t\t\tdest.innerHTML = src.innerHTML;\n\t\t}\n\n\t} else if ( nodeName === \"input\" && rcheckableType.test( src.type ) ) {\n\t\t// IE6-8 fails to persist the checked state of a cloned checkbox\n\t\t// or radio button. Worse, IE6-7 fail to give the cloned element\n\t\t// a checked appearance if the defaultChecked value isn't also set\n\n\t\tdest.defaultChecked = dest.checked = src.checked;\n\n\t\t// IE6-7 get confused and end up setting the value of a cloned\n\t\t// checkbox/radio button to an empty string instead of \"on\"\n\t\tif ( dest.value !== src.value ) {\n\t\t\tdest.value = src.value;\n\t\t}\n\n\t// IE6-8 fails to return the selected option to the default selected\n\t// state when cloning options\n\t} else if ( nodeName === \"option\" ) {\n\t\tdest.defaultSelected = dest.selected = src.defaultSelected;\n\n\t// IE6-8 fails to set the defaultValue to the correct value when\n\t// cloning other types of input fields\n\t} else if ( nodeName === \"input\" || nodeName === \"textarea\" ) {\n\t\tdest.defaultValue = src.defaultValue;\n\t}\n}\n\njQuery.extend({\n\tclone: function( elem, dataAndEvents, deepDataAndEvents ) {\n\t\tvar destElements, node, clone, i, srcElements,\n\t\t\tinPage = jQuery.contains( elem.ownerDocument, elem );\n\n\t\tif ( support.html5Clone || jQuery.isXMLDoc(elem) || !rnoshimcache.test( \"<\" + elem.nodeName + \">\" ) ) {\n\t\t\tclone = elem.cloneNode( true );\n\n\t\t// IE<=8 does not properly clone detached, unknown element nodes\n\t\t} else {\n\t\t\tfragmentDiv.innerHTML = elem.outerHTML;\n\t\t\tfragmentDiv.removeChild( clone = fragmentDiv.firstChild );\n\t\t}\n\n\t\tif ( (!support.noCloneEvent || !support.noCloneChecked) &&\n\t\t\t\t(elem.nodeType === 1 || elem.nodeType === 11) && !jQuery.isXMLDoc(elem) ) {\n\n\t\t\t// We eschew Sizzle here for performance reasons: http://jsperf.com/getall-vs-sizzle/2\n\t\t\tdestElements = getAll( clone );\n\t\t\tsrcElements = getAll( elem );\n\n\t\t\t// Fix all IE cloning issues\n\t\t\tfor ( i = 0; (node = srcElements[i]) != null; ++i ) {\n\t\t\t\t// Ensure that the destination node is not null; Fixes #9587\n\t\t\t\tif ( destElements[i] ) {\n\t\t\t\t\tfixCloneNodeIssues( node, destElements[i] );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Copy the events from the original to the clone\n\t\tif ( dataAndEvents ) {\n\t\t\tif ( deepDataAndEvents ) {\n\t\t\t\tsrcElements = srcElements || getAll( elem );\n\t\t\t\tdestElements = destElements || getAll( clone );\n\n\t\t\t\tfor ( i = 0; (node = srcElements[i]) != null; i++ ) {\n\t\t\t\t\tcloneCopyEvent( node, destElements[i] );\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tcloneCopyEvent( elem, clone );\n\t\t\t}\n\t\t}\n\n\t\t// Preserve script evaluation history\n\t\tdestElements = getAll( clone, \"script\" );\n\t\tif ( destElements.length > 0 ) {\n\t\t\tsetGlobalEval( destElements, !inPage && getAll( elem, \"script\" ) );\n\t\t}\n\n\t\tdestElements = srcElements = node = null;\n\n\t\t// Return the cloned set\n\t\treturn clone;\n\t},\n\n\tbuildFragment: function( elems, context, scripts, selection ) {\n\t\tvar j, elem, contains,\n\t\t\ttmp, tag, tbody, wrap,\n\t\t\tl = elems.length,\n\n\t\t\t// Ensure a safe fragment\n\t\t\tsafe = createSafeFragment( context ),\n\n\t\t\tnodes = [],\n\t\t\ti = 0;\n\n\t\tfor ( ; i < l; i++ ) {\n\t\t\telem = elems[ i ];\n\n\t\t\tif ( elem || elem === 0 ) {\n\n\t\t\t\t// Add nodes directly\n\t\t\t\tif ( jQuery.type( elem ) === \"object\" ) {\n\t\t\t\t\tjQuery.merge( nodes, elem.nodeType ? [ elem ] : elem );\n\n\t\t\t\t// Convert non-html into a text node\n\t\t\t\t} else if ( !rhtml.test( elem ) ) {\n\t\t\t\t\tnodes.push( context.createTextNode( elem ) );\n\n\t\t\t\t// Convert html into DOM nodes\n\t\t\t\t} else {\n\t\t\t\t\ttmp = tmp || safe.appendChild( context.createElement(\"div\") );\n\n\t\t\t\t\t// Deserialize a standard representation\n\t\t\t\t\ttag = (rtagName.exec( elem ) || [ \"\", \"\" ])[ 1 ].toLowerCase();\n\t\t\t\t\twrap = wrapMap[ tag ] || wrapMap._default;\n\n\t\t\t\t\ttmp.innerHTML = wrap[1] + elem.replace( rxhtmlTag, \"<$1></$2>\" ) + wrap[2];\n\n\t\t\t\t\t// Descend through wrappers to the right content\n\t\t\t\t\tj = wrap[0];\n\t\t\t\t\twhile ( j-- ) {\n\t\t\t\t\t\ttmp = tmp.lastChild;\n\t\t\t\t\t}\n\n\t\t\t\t\t// Manually add leading whitespace removed by IE\n\t\t\t\t\tif ( !support.leadingWhitespace && rleadingWhitespace.test( elem ) ) {\n\t\t\t\t\t\tnodes.push( context.createTextNode( rleadingWhitespace.exec( elem )[0] ) );\n\t\t\t\t\t}\n\n\t\t\t\t\t// Remove IE's autoinserted <tbody> from table fragments\n\t\t\t\t\tif ( !support.tbody ) {\n\n\t\t\t\t\t\t// String was a <table>, *may* have spurious <tbody>\n\t\t\t\t\t\telem = tag === \"table\" && !rtbody.test( elem ) ?\n\t\t\t\t\t\t\ttmp.firstChild :\n\n\t\t\t\t\t\t\t// String was a bare <thead> or <tfoot>\n\t\t\t\t\t\t\twrap[1] === \"<table>\" && !rtbody.test( elem ) ?\n\t\t\t\t\t\t\t\ttmp :\n\t\t\t\t\t\t\t\t0;\n\n\t\t\t\t\t\tj = elem && elem.childNodes.length;\n\t\t\t\t\t\twhile ( j-- ) {\n\t\t\t\t\t\t\tif ( jQuery.nodeName( (tbody = elem.childNodes[j]), \"tbody\" ) && !tbody.childNodes.length ) {\n\t\t\t\t\t\t\t\telem.removeChild( tbody );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tjQuery.merge( nodes, tmp.childNodes );\n\n\t\t\t\t\t// Fix #12392 for WebKit and IE > 9\n\t\t\t\t\ttmp.textContent = \"\";\n\n\t\t\t\t\t// Fix #12392 for oldIE\n\t\t\t\t\twhile ( tmp.firstChild ) {\n\t\t\t\t\t\ttmp.removeChild( tmp.firstChild );\n\t\t\t\t\t}\n\n\t\t\t\t\t// Remember the top-level container for proper cleanup\n\t\t\t\t\ttmp = safe.lastChild;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Fix #11356: Clear elements from fragment\n\t\tif ( tmp ) {\n\t\t\tsafe.removeChild( tmp );\n\t\t}\n\n\t\t// Reset defaultChecked for any radios and checkboxes\n\t\t// about to be appended to the DOM in IE 6/7 (#8060)\n\t\tif ( !support.appendChecked ) {\n\t\t\tjQuery.grep( getAll( nodes, \"input\" ), fixDefaultChecked );\n\t\t}\n\n\t\ti = 0;\n\t\twhile ( (elem = nodes[ i++ ]) ) {\n\n\t\t\t// #4087 - If origin and destination elements are the same, and this is\n\t\t\t// that element, do not do anything\n\t\t\tif ( selection && jQuery.inArray( elem, selection ) !== -1 ) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tcontains = jQuery.contains( elem.ownerDocument, elem );\n\n\t\t\t// Append to fragment\n\t\t\ttmp = getAll( safe.appendChild( elem ), \"script\" );\n\n\t\t\t// Preserve script evaluation history\n\t\t\tif ( contains ) {\n\t\t\t\tsetGlobalEval( tmp );\n\t\t\t}\n\n\t\t\t// Capture executables\n\t\t\tif ( scripts ) {\n\t\t\t\tj = 0;\n\t\t\t\twhile ( (elem = tmp[ j++ ]) ) {\n\t\t\t\t\tif ( rscriptType.test( elem.type || \"\" ) ) {\n\t\t\t\t\t\tscripts.push( elem );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\ttmp = null;\n\n\t\treturn safe;\n\t},\n\n\tcleanData: function( elems, /* internal */ acceptData ) {\n\t\tvar elem, type, id, data,\n\t\t\ti = 0,\n\t\t\tinternalKey = jQuery.expando,\n\t\t\tcache = jQuery.cache,\n\t\t\tdeleteExpando = support.deleteExpando,\n\t\t\tspecial = jQuery.event.special;\n\n\t\tfor ( ; (elem = elems[i]) != null; i++ ) {\n\t\t\tif ( acceptData || jQuery.acceptData( elem ) ) {\n\n\t\t\t\tid = elem[ internalKey ];\n\t\t\t\tdata = id && cache[ id ];\n\n\t\t\t\tif ( data ) {\n\t\t\t\t\tif ( data.events ) {\n\t\t\t\t\t\tfor ( type in data.events ) {\n\t\t\t\t\t\t\tif ( special[ type ] ) {\n\t\t\t\t\t\t\t\tjQuery.event.remove( elem, type );\n\n\t\t\t\t\t\t\t// This is a shortcut to avoid jQuery.event.remove's overhead\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tjQuery.removeEvent( elem, type, data.handle );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\t// Remove cache only if it was not already removed by jQuery.event.remove\n\t\t\t\t\tif ( cache[ id ] ) {\n\n\t\t\t\t\t\tdelete cache[ id ];\n\n\t\t\t\t\t\t// IE does not allow us to delete expando properties from nodes,\n\t\t\t\t\t\t// nor does it have a removeAttribute function on Document nodes;\n\t\t\t\t\t\t// we must handle all of these cases\n\t\t\t\t\t\tif ( deleteExpando ) {\n\t\t\t\t\t\t\tdelete elem[ internalKey ];\n\n\t\t\t\t\t\t} else if ( typeof elem.removeAttribute !== strundefined ) {\n\t\t\t\t\t\t\telem.removeAttribute( internalKey );\n\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\telem[ internalKey ] = null;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tdeletedIds.push( id );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n});\n\njQuery.fn.extend({\n\ttext: function( value ) {\n\t\treturn access( this, function( value ) {\n\t\t\treturn value === undefined ?\n\t\t\t\tjQuery.text( this ) :\n\t\t\t\tthis.empty().append( ( this[0] && this[0].ownerDocument || document ).createTextNode( value ) );\n\t\t}, null, value, arguments.length );\n\t},\n\n\tappend: function() {\n\t\treturn this.domManip( arguments, function( elem ) {\n\t\t\tif ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) {\n\t\t\t\tvar target = manipulationTarget( this, elem );\n\t\t\t\ttarget.appendChild( elem );\n\t\t\t}\n\t\t});\n\t},\n\n\tprepend: function() {\n\t\treturn this.domManip( arguments, function( elem ) {\n\t\t\tif ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) {\n\t\t\t\tvar target = manipulationTarget( this, elem );\n\t\t\t\ttarget.insertBefore( elem, target.firstChild );\n\t\t\t}\n\t\t});\n\t},\n\n\tbefore: function() {\n\t\treturn this.domManip( arguments, function( elem ) {\n\t\t\tif ( this.parentNode ) {\n\t\t\t\tthis.parentNode.insertBefore( elem, this );\n\t\t\t}\n\t\t});\n\t},\n\n\tafter: function() {\n\t\treturn this.domManip( arguments, function( elem ) {\n\t\t\tif ( this.parentNode ) {\n\t\t\t\tthis.parentNode.insertBefore( elem, this.nextSibling );\n\t\t\t}\n\t\t});\n\t},\n\n\tremove: function( selector, keepData /* Internal Use Only */ ) {\n\t\tvar elem,\n\t\t\telems = selector ? jQuery.filter( selector, this ) : this,\n\t\t\ti = 0;\n\n\t\tfor ( ; (elem = elems[i]) != null; i++ ) {\n\n\t\t\tif ( !keepData && elem.nodeType === 1 ) {\n\t\t\t\tjQuery.cleanData( getAll( elem ) );\n\t\t\t}\n\n\t\t\tif ( elem.parentNode ) {\n\t\t\t\tif ( keepData && jQuery.contains( elem.ownerDocument, elem ) ) {\n\t\t\t\t\tsetGlobalEval( getAll( elem, \"script\" ) );\n\t\t\t\t}\n\t\t\t\telem.parentNode.removeChild( elem );\n\t\t\t}\n\t\t}\n\n\t\treturn this;\n\t},\n\n\tempty: function() {\n\t\tvar elem,\n\t\t\ti = 0;\n\n\t\tfor ( ; (elem = this[i]) != null; i++ ) {\n\t\t\t// Remove element nodes and prevent memory leaks\n\t\t\tif ( elem.nodeType === 1 ) {\n\t\t\t\tjQuery.cleanData( getAll( elem, false ) );\n\t\t\t}\n\n\t\t\t// Remove any remaining nodes\n\t\t\twhile ( elem.firstChild ) {\n\t\t\t\telem.removeChild( elem.firstChild );\n\t\t\t}\n\n\t\t\t// If this is a select, ensure that it displays empty (#12336)\n\t\t\t// Support: IE<9\n\t\t\tif ( elem.options && jQuery.nodeName( elem, \"select\" ) ) {\n\t\t\t\telem.options.length = 0;\n\t\t\t}\n\t\t}\n\n\t\treturn this;\n\t},\n\n\tclone: function( dataAndEvents, deepDataAndEvents ) {\n\t\tdataAndEvents = dataAndEvents == null ? false : dataAndEvents;\n\t\tdeepDataAndEvents = deepDataAndEvents == null ? dataAndEvents : deepDataAndEvents;\n\n\t\treturn this.map(function() {\n\t\t\treturn jQuery.clone( this, dataAndEvents, deepDataAndEvents );\n\t\t});\n\t},\n\n\thtml: function( value ) {\n\t\treturn access( this, function( value ) {\n\t\t\tvar elem = this[ 0 ] || {},\n\t\t\t\ti = 0,\n\t\t\t\tl = this.length;\n\n\t\t\tif ( value === undefined ) {\n\t\t\t\treturn elem.nodeType === 1 ?\n\t\t\t\t\telem.innerHTML.replace( rinlinejQuery, \"\" ) :\n\t\t\t\t\tundefined;\n\t\t\t}\n\n\t\t\t// See if we can take a shortcut and just use innerHTML\n\t\t\tif ( typeof value === \"string\" && !rnoInnerhtml.test( value ) &&\n\t\t\t\t( support.htmlSerialize || !rnoshimcache.test( value )  ) &&\n\t\t\t\t( support.leadingWhitespace || !rleadingWhitespace.test( value ) ) &&\n\t\t\t\t!wrapMap[ (rtagName.exec( value ) || [ \"\", \"\" ])[ 1 ].toLowerCase() ] ) {\n\n\t\t\t\tvalue = value.replace( rxhtmlTag, \"<$1></$2>\" );\n\n\t\t\t\ttry {\n\t\t\t\t\tfor (; i < l; i++ ) {\n\t\t\t\t\t\t// Remove element nodes and prevent memory leaks\n\t\t\t\t\t\telem = this[i] || {};\n\t\t\t\t\t\tif ( elem.nodeType === 1 ) {\n\t\t\t\t\t\t\tjQuery.cleanData( getAll( elem, false ) );\n\t\t\t\t\t\t\telem.innerHTML = value;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\telem = 0;\n\n\t\t\t\t// If using innerHTML throws an exception, use the fallback method\n\t\t\t\t} catch(e) {}\n\t\t\t}\n\n\t\t\tif ( elem ) {\n\t\t\t\tthis.empty().append( value );\n\t\t\t}\n\t\t}, null, value, arguments.length );\n\t},\n\n\treplaceWith: function() {\n\t\tvar arg = arguments[ 0 ];\n\n\t\t// Make the changes, replacing each context element with the new content\n\t\tthis.domManip( arguments, function( elem ) {\n\t\t\targ = this.parentNode;\n\n\t\t\tjQuery.cleanData( getAll( this ) );\n\n\t\t\tif ( arg ) {\n\t\t\t\targ.replaceChild( elem, this );\n\t\t\t}\n\t\t});\n\n\t\t// Force removal if there was no new content (e.g., from empty arguments)\n\t\treturn arg && (arg.length || arg.nodeType) ? this : this.remove();\n\t},\n\n\tdetach: function( selector ) {\n\t\treturn this.remove( selector, true );\n\t},\n\n\tdomManip: function( args, callback ) {\n\n\t\t// Flatten any nested arrays\n\t\targs = concat.apply( [], args );\n\n\t\tvar first, node, hasScripts,\n\t\t\tscripts, doc, fragment,\n\t\t\ti = 0,\n\t\t\tl = this.length,\n\t\t\tset = this,\n\t\t\tiNoClone = l - 1,\n\t\t\tvalue = args[0],\n\t\t\tisFunction = jQuery.isFunction( value );\n\n\t\t// We can't cloneNode fragments that contain checked, in WebKit\n\t\tif ( isFunction ||\n\t\t\t\t( l > 1 && typeof value === \"string\" &&\n\t\t\t\t\t!support.checkClone && rchecked.test( value ) ) ) {\n\t\t\treturn this.each(function( index ) {\n\t\t\t\tvar self = set.eq( index );\n\t\t\t\tif ( isFunction ) {\n\t\t\t\t\targs[0] = value.call( this, index, self.html() );\n\t\t\t\t}\n\t\t\t\tself.domManip( args, callback );\n\t\t\t});\n\t\t}\n\n\t\tif ( l ) {\n\t\t\tfragment = jQuery.buildFragment( args, this[ 0 ].ownerDocument, false, this );\n\t\t\tfirst = fragment.firstChild;\n\n\t\t\tif ( fragment.childNodes.length === 1 ) {\n\t\t\t\tfragment = first;\n\t\t\t}\n\n\t\t\tif ( first ) {\n\t\t\t\tscripts = jQuery.map( getAll( fragment, \"script\" ), disableScript );\n\t\t\t\thasScripts = scripts.length;\n\n\t\t\t\t// Use the original fragment for the last item instead of the first because it can end up\n\t\t\t\t// being emptied incorrectly in certain situations (#8070).\n\t\t\t\tfor ( ; i < l; i++ ) {\n\t\t\t\t\tnode = fragment;\n\n\t\t\t\t\tif ( i !== iNoClone ) {\n\t\t\t\t\t\tnode = jQuery.clone( node, true, true );\n\n\t\t\t\t\t\t// Keep references to cloned scripts for later restoration\n\t\t\t\t\t\tif ( hasScripts ) {\n\t\t\t\t\t\t\tjQuery.merge( scripts, getAll( node, \"script\" ) );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tcallback.call( this[i], node, i );\n\t\t\t\t}\n\n\t\t\t\tif ( hasScripts ) {\n\t\t\t\t\tdoc = scripts[ scripts.length - 1 ].ownerDocument;\n\n\t\t\t\t\t// Reenable scripts\n\t\t\t\t\tjQuery.map( scripts, restoreScript );\n\n\t\t\t\t\t// Evaluate executable scripts on first document insertion\n\t\t\t\t\tfor ( i = 0; i < hasScripts; i++ ) {\n\t\t\t\t\t\tnode = scripts[ i ];\n\t\t\t\t\t\tif ( rscriptType.test( node.type || \"\" ) &&\n\t\t\t\t\t\t\t!jQuery._data( node, \"globalEval\" ) && jQuery.contains( doc, node ) ) {\n\n\t\t\t\t\t\t\tif ( node.src ) {\n\t\t\t\t\t\t\t\t// Optional AJAX dependency, but won't run scripts if not present\n\t\t\t\t\t\t\t\tif ( jQuery._evalUrl ) {\n\t\t\t\t\t\t\t\t\tjQuery._evalUrl( node.src );\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tjQuery.globalEval( ( node.text || node.textContent || node.innerHTML || \"\" ).replace( rcleanScript, \"\" ) );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// Fix #11809: Avoid leaking memory\n\t\t\t\tfragment = first = null;\n\t\t\t}\n\t\t}\n\n\t\treturn this;\n\t}\n});\n\njQuery.each({\n\tappendTo: \"append\",\n\tprependTo: \"prepend\",\n\tinsertBefore: \"before\",\n\tinsertAfter: \"after\",\n\treplaceAll: \"replaceWith\"\n}, function( name, original ) {\n\tjQuery.fn[ name ] = function( selector ) {\n\t\tvar elems,\n\t\t\ti = 0,\n\t\t\tret = [],\n\t\t\tinsert = jQuery( selector ),\n\t\t\tlast = insert.length - 1;\n\n\t\tfor ( ; i <= last; i++ ) {\n\t\t\telems = i === last ? this : this.clone(true);\n\t\t\tjQuery( insert[i] )[ original ]( elems );\n\n\t\t\t// Modern browsers can apply jQuery collections as arrays, but oldIE needs a .get()\n\t\t\tpush.apply( ret, elems.get() );\n\t\t}\n\n\t\treturn this.pushStack( ret );\n\t};\n});\n\n\nvar iframe,\n\telemdisplay = {};\n\n/**\n * Retrieve the actual display of a element\n * @param {String} name nodeName of the element\n * @param {Object} doc Document object\n */\n// Called only from within defaultDisplay\nfunction actualDisplay( name, doc ) {\n\tvar style,\n\t\telem = jQuery( doc.createElement( name ) ).appendTo( doc.body ),\n\n\t\t// getDefaultComputedStyle might be reliably used only on attached element\n\t\tdisplay = window.getDefaultComputedStyle && ( style = window.getDefaultComputedStyle( elem[ 0 ] ) ) ?\n\n\t\t\t// Use of this method is a temporary fix (more like optmization) until something better comes along,\n\t\t\t// since it was removed from specification and supported only in FF\n\t\t\tstyle.display : jQuery.css( elem[ 0 ], \"display\" );\n\n\t// We don't have any data stored on the element,\n\t// so use \"detach\" method as fast way to get rid of the element\n\telem.detach();\n\n\treturn display;\n}\n\n/**\n * Try to determine the default display value of an element\n * @param {String} nodeName\n */\nfunction defaultDisplay( nodeName ) {\n\tvar doc = document,\n\t\tdisplay = elemdisplay[ nodeName ];\n\n\tif ( !display ) {\n\t\tdisplay = actualDisplay( nodeName, doc );\n\n\t\t// If the simple way fails, read from inside an iframe\n\t\tif ( display === \"none\" || !display ) {\n\n\t\t\t// Use the already-created iframe if possible\n\t\t\tiframe = (iframe || jQuery( \"<iframe frameborder='0' width='0' height='0'/>\" )).appendTo( doc.documentElement );\n\n\t\t\t// Always write a new HTML skeleton so Webkit and Firefox don't choke on reuse\n\t\t\tdoc = ( iframe[ 0 ].contentWindow || iframe[ 0 ].contentDocument ).document;\n\n\t\t\t// Support: IE\n\t\t\tdoc.write();\n\t\t\tdoc.close();\n\n\t\t\tdisplay = actualDisplay( nodeName, doc );\n\t\t\tiframe.detach();\n\t\t}\n\n\t\t// Store the correct default display\n\t\telemdisplay[ nodeName ] = display;\n\t}\n\n\treturn display;\n}\n\n\n(function() {\n\tvar shrinkWrapBlocksVal;\n\n\tsupport.shrinkWrapBlocks = function() {\n\t\tif ( shrinkWrapBlocksVal != null ) {\n\t\t\treturn shrinkWrapBlocksVal;\n\t\t}\n\n\t\t// Will be changed later if needed.\n\t\tshrinkWrapBlocksVal = false;\n\n\t\t// Minified: var b,c,d\n\t\tvar div, body, container;\n\n\t\tbody = document.getElementsByTagName( \"body\" )[ 0 ];\n\t\tif ( !body || !body.style ) {\n\t\t\t// Test fired too early or in an unsupported environment, exit.\n\t\t\treturn;\n\t\t}\n\n\t\t// Setup\n\t\tdiv = document.createElement( \"div\" );\n\t\tcontainer = document.createElement( \"div\" );\n\t\tcontainer.style.cssText = \"position:absolute;border:0;width:0;height:0;top:0;left:-9999px\";\n\t\tbody.appendChild( container ).appendChild( div );\n\n\t\t// Support: IE6\n\t\t// Check if elements with layout shrink-wrap their children\n\t\tif ( typeof div.style.zoom !== strundefined ) {\n\t\t\t// Reset CSS: box-sizing; display; margin; border\n\t\t\tdiv.style.cssText =\n\t\t\t\t// Support: Firefox<29, Android 2.3\n\t\t\t\t// Vendor-prefix box-sizing\n\t\t\t\t\"-webkit-box-sizing:content-box;-moz-box-sizing:content-box;\" +\n\t\t\t\t\"box-sizing:content-box;display:block;margin:0;border:0;\" +\n\t\t\t\t\"padding:1px;width:1px;zoom:1\";\n\t\t\tdiv.appendChild( document.createElement( \"div\" ) ).style.width = \"5px\";\n\t\t\tshrinkWrapBlocksVal = div.offsetWidth !== 3;\n\t\t}\n\n\t\tbody.removeChild( container );\n\n\t\treturn shrinkWrapBlocksVal;\n\t};\n\n})();\nvar rmargin = (/^margin/);\n\nvar rnumnonpx = new RegExp( \"^(\" + pnum + \")(?!px)[a-z%]+$\", \"i\" );\n\n\n\nvar getStyles, curCSS,\n\trposition = /^(top|right|bottom|left)$/;\n\nif ( window.getComputedStyle ) {\n\tgetStyles = function( elem ) {\n\t\t// Support: IE<=11+, Firefox<=30+ (#15098, #14150)\n\t\t// IE throws on elements created in popups\n\t\t// FF meanwhile throws on frame elements through \"defaultView.getComputedStyle\"\n\t\tif ( elem.ownerDocument.defaultView.opener ) {\n\t\t\treturn elem.ownerDocument.defaultView.getComputedStyle( elem, null );\n\t\t}\n\n\t\treturn window.getComputedStyle( elem, null );\n\t};\n\n\tcurCSS = function( elem, name, computed ) {\n\t\tvar width, minWidth, maxWidth, ret,\n\t\t\tstyle = elem.style;\n\n\t\tcomputed = computed || getStyles( elem );\n\n\t\t// getPropertyValue is only needed for .css('filter') in IE9, see #12537\n\t\tret = computed ? computed.getPropertyValue( name ) || computed[ name ] : undefined;\n\n\t\tif ( computed ) {\n\n\t\t\tif ( ret === \"\" && !jQuery.contains( elem.ownerDocument, elem ) ) {\n\t\t\t\tret = jQuery.style( elem, name );\n\t\t\t}\n\n\t\t\t// A tribute to the \"awesome hack by Dean Edwards\"\n\t\t\t// Chrome < 17 and Safari 5.0 uses \"computed value\" instead of \"used value\" for margin-right\n\t\t\t// Safari 5.1.7 (at least) returns percentage for a larger set of values, but width seems to be reliably pixels\n\t\t\t// this is against the CSSOM draft spec: http://dev.w3.org/csswg/cssom/#resolved-values\n\t\t\tif ( rnumnonpx.test( ret ) && rmargin.test( name ) ) {\n\n\t\t\t\t// Remember the original values\n\t\t\t\twidth = style.width;\n\t\t\t\tminWidth = style.minWidth;\n\t\t\t\tmaxWidth = style.maxWidth;\n\n\t\t\t\t// Put in the new values to get a computed value out\n\t\t\t\tstyle.minWidth = style.maxWidth = style.width = ret;\n\t\t\t\tret = computed.width;\n\n\t\t\t\t// Revert the changed values\n\t\t\t\tstyle.width = width;\n\t\t\t\tstyle.minWidth = minWidth;\n\t\t\t\tstyle.maxWidth = maxWidth;\n\t\t\t}\n\t\t}\n\n\t\t// Support: IE\n\t\t// IE returns zIndex value as an integer.\n\t\treturn ret === undefined ?\n\t\t\tret :\n\t\t\tret + \"\";\n\t};\n} else if ( document.documentElement.currentStyle ) {\n\tgetStyles = function( elem ) {\n\t\treturn elem.currentStyle;\n\t};\n\n\tcurCSS = function( elem, name, computed ) {\n\t\tvar left, rs, rsLeft, ret,\n\t\t\tstyle = elem.style;\n\n\t\tcomputed = computed || getStyles( elem );\n\t\tret = computed ? computed[ name ] : undefined;\n\n\t\t// Avoid setting ret to empty string here\n\t\t// so we don't default to auto\n\t\tif ( ret == null && style && style[ name ] ) {\n\t\t\tret = style[ name ];\n\t\t}\n\n\t\t// From the awesome hack by Dean Edwards\n\t\t// http://erik.eae.net/archives/2007/07/27/18.54.15/#comment-102291\n\n\t\t// If we're not dealing with a regular pixel number\n\t\t// but a number that has a weird ending, we need to convert it to pixels\n\t\t// but not position css attributes, as those are proportional to the parent element instead\n\t\t// and we can't measure the parent instead because it might trigger a \"stacking dolls\" problem\n\t\tif ( rnumnonpx.test( ret ) && !rposition.test( name ) ) {\n\n\t\t\t// Remember the original values\n\t\t\tleft = style.left;\n\t\t\trs = elem.runtimeStyle;\n\t\t\trsLeft = rs && rs.left;\n\n\t\t\t// Put in the new values to get a computed value out\n\t\t\tif ( rsLeft ) {\n\t\t\t\trs.left = elem.currentStyle.left;\n\t\t\t}\n\t\t\tstyle.left = name === \"fontSize\" ? \"1em\" : ret;\n\t\t\tret = style.pixelLeft + \"px\";\n\n\t\t\t// Revert the changed values\n\t\t\tstyle.left = left;\n\t\t\tif ( rsLeft ) {\n\t\t\t\trs.left = rsLeft;\n\t\t\t}\n\t\t}\n\n\t\t// Support: IE\n\t\t// IE returns zIndex value as an integer.\n\t\treturn ret === undefined ?\n\t\t\tret :\n\t\t\tret + \"\" || \"auto\";\n\t};\n}\n\n\n\n\nfunction addGetHookIf( conditionFn, hookFn ) {\n\t// Define the hook, we'll check on the first run if it's really needed.\n\treturn {\n\t\tget: function() {\n\t\t\tvar condition = conditionFn();\n\n\t\t\tif ( condition == null ) {\n\t\t\t\t// The test was not ready at this point; screw the hook this time\n\t\t\t\t// but check again when needed next time.\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif ( condition ) {\n\t\t\t\t// Hook not needed (or it's not possible to use it due to missing dependency),\n\t\t\t\t// remove it.\n\t\t\t\t// Since there are no other hooks for marginRight, remove the whole object.\n\t\t\t\tdelete this.get;\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// Hook needed; redefine it so that the support test is not executed again.\n\n\t\t\treturn (this.get = hookFn).apply( this, arguments );\n\t\t}\n\t};\n}\n\n\n(function() {\n\t// Minified: var b,c,d,e,f,g, h,i\n\tvar div, style, a, pixelPositionVal, boxSizingReliableVal,\n\t\treliableHiddenOffsetsVal, reliableMarginRightVal;\n\n\t// Setup\n\tdiv = document.createElement( \"div\" );\n\tdiv.innerHTML = \"  <link/><table></table><a href='/a'>a</a><input type='checkbox'/>\";\n\ta = div.getElementsByTagName( \"a\" )[ 0 ];\n\tstyle = a && a.style;\n\n\t// Finish early in limited (non-browser) environments\n\tif ( !style ) {\n\t\treturn;\n\t}\n\n\tstyle.cssText = \"float:left;opacity:.5\";\n\n\t// Support: IE<9\n\t// Make sure that element opacity exists (as opposed to filter)\n\tsupport.opacity = style.opacity === \"0.5\";\n\n\t// Verify style float existence\n\t// (IE uses styleFloat instead of cssFloat)\n\tsupport.cssFloat = !!style.cssFloat;\n\n\tdiv.style.backgroundClip = \"content-box\";\n\tdiv.cloneNode( true ).style.backgroundClip = \"\";\n\tsupport.clearCloneStyle = div.style.backgroundClip === \"content-box\";\n\n\t// Support: Firefox<29, Android 2.3\n\t// Vendor-prefix box-sizing\n\tsupport.boxSizing = style.boxSizing === \"\" || style.MozBoxSizing === \"\" ||\n\t\tstyle.WebkitBoxSizing === \"\";\n\n\tjQuery.extend(support, {\n\t\treliableHiddenOffsets: function() {\n\t\t\tif ( reliableHiddenOffsetsVal == null ) {\n\t\t\t\tcomputeStyleTests();\n\t\t\t}\n\t\t\treturn reliableHiddenOffsetsVal;\n\t\t},\n\n\t\tboxSizingReliable: function() {\n\t\t\tif ( boxSizingReliableVal == null ) {\n\t\t\t\tcomputeStyleTests();\n\t\t\t}\n\t\t\treturn boxSizingReliableVal;\n\t\t},\n\n\t\tpixelPosition: function() {\n\t\t\tif ( pixelPositionVal == null ) {\n\t\t\t\tcomputeStyleTests();\n\t\t\t}\n\t\t\treturn pixelPositionVal;\n\t\t},\n\n\t\t// Support: Android 2.3\n\t\treliableMarginRight: function() {\n\t\t\tif ( reliableMarginRightVal == null ) {\n\t\t\t\tcomputeStyleTests();\n\t\t\t}\n\t\t\treturn reliableMarginRightVal;\n\t\t}\n\t});\n\n\tfunction computeStyleTests() {\n\t\t// Minified: var b,c,d,j\n\t\tvar div, body, container, contents;\n\n\t\tbody = document.getElementsByTagName( \"body\" )[ 0 ];\n\t\tif ( !body || !body.style ) {\n\t\t\t// Test fired too early or in an unsupported environment, exit.\n\t\t\treturn;\n\t\t}\n\n\t\t// Setup\n\t\tdiv = document.createElement( \"div\" );\n\t\tcontainer = document.createElement( \"div\" );\n\t\tcontainer.style.cssText = \"position:absolute;border:0;width:0;height:0;top:0;left:-9999px\";\n\t\tbody.appendChild( container ).appendChild( div );\n\n\t\tdiv.style.cssText =\n\t\t\t// Support: Firefox<29, Android 2.3\n\t\t\t// Vendor-prefix box-sizing\n\t\t\t\"-webkit-box-sizing:border-box;-moz-box-sizing:border-box;\" +\n\t\t\t\"box-sizing:border-box;display:block;margin-top:1%;top:1%;\" +\n\t\t\t\"border:1px;padding:1px;width:4px;position:absolute\";\n\n\t\t// Support: IE<9\n\t\t// Assume reasonable values in the absence of getComputedStyle\n\t\tpixelPositionVal = boxSizingReliableVal = false;\n\t\treliableMarginRightVal = true;\n\n\t\t// Check for getComputedStyle so that this code is not run in IE<9.\n\t\tif ( window.getComputedStyle ) {\n\t\t\tpixelPositionVal = ( window.getComputedStyle( div, null ) || {} ).top !== \"1%\";\n\t\t\tboxSizingReliableVal =\n\t\t\t\t( window.getComputedStyle( div, null ) || { width: \"4px\" } ).width === \"4px\";\n\n\t\t\t// Support: Android 2.3\n\t\t\t// Div with explicit width and no margin-right incorrectly\n\t\t\t// gets computed margin-right based on width of container (#3333)\n\t\t\t// WebKit Bug 13343 - getComputedStyle returns wrong value for margin-right\n\t\t\tcontents = div.appendChild( document.createElement( \"div\" ) );\n\n\t\t\t// Reset CSS: box-sizing; display; margin; border; padding\n\t\t\tcontents.style.cssText = div.style.cssText =\n\t\t\t\t// Support: Firefox<29, Android 2.3\n\t\t\t\t// Vendor-prefix box-sizing\n\t\t\t\t\"-webkit-box-sizing:content-box;-moz-box-sizing:content-box;\" +\n\t\t\t\t\"box-sizing:content-box;display:block;margin:0;border:0;padding:0\";\n\t\t\tcontents.style.marginRight = contents.style.width = \"0\";\n\t\t\tdiv.style.width = \"1px\";\n\n\t\t\treliableMarginRightVal =\n\t\t\t\t!parseFloat( ( window.getComputedStyle( contents, null ) || {} ).marginRight );\n\n\t\t\tdiv.removeChild( contents );\n\t\t}\n\n\t\t// Support: IE8\n\t\t// Check if table cells still have offsetWidth/Height when they are set\n\t\t// to display:none and there are still other visible table cells in a\n\t\t// table row; if so, offsetWidth/Height are not reliable for use when\n\t\t// determining if an element has been hidden directly using\n\t\t// display:none (it is still safe to use offsets if a parent element is\n\t\t// hidden; don safety goggles and see bug #4512 for more information).\n\t\tdiv.innerHTML = \"<table><tr><td></td><td>t</td></tr></table>\";\n\t\tcontents = div.getElementsByTagName( \"td\" );\n\t\tcontents[ 0 ].style.cssText = \"margin:0;border:0;padding:0;display:none\";\n\t\treliableHiddenOffsetsVal = contents[ 0 ].offsetHeight === 0;\n\t\tif ( reliableHiddenOffsetsVal ) {\n\t\t\tcontents[ 0 ].style.display = \"\";\n\t\t\tcontents[ 1 ].style.display = \"none\";\n\t\t\treliableHiddenOffsetsVal = contents[ 0 ].offsetHeight === 0;\n\t\t}\n\n\t\tbody.removeChild( container );\n\t}\n\n})();\n\n\n// A method for quickly swapping in/out CSS properties to get correct calculations.\njQuery.swap = function( elem, options, callback, args ) {\n\tvar ret, name,\n\t\told = {};\n\n\t// Remember the old values, and insert the new ones\n\tfor ( name in options ) {\n\t\told[ name ] = elem.style[ name ];\n\t\telem.style[ name ] = options[ name ];\n\t}\n\n\tret = callback.apply( elem, args || [] );\n\n\t// Revert the old values\n\tfor ( name in options ) {\n\t\telem.style[ name ] = old[ name ];\n\t}\n\n\treturn ret;\n};\n\n\nvar\n\t\tralpha = /alpha\\([^)]*\\)/i,\n\tropacity = /opacity\\s*=\\s*([^)]*)/,\n\n\t// swappable if display is none or starts with table except \"table\", \"table-cell\", or \"table-caption\"\n\t// see here for display values: https://developer.mozilla.org/en-US/docs/CSS/display\n\trdisplayswap = /^(none|table(?!-c[ea]).+)/,\n\trnumsplit = new RegExp( \"^(\" + pnum + \")(.*)$\", \"i\" ),\n\trrelNum = new RegExp( \"^([+-])=(\" + pnum + \")\", \"i\" ),\n\n\tcssShow = { position: \"absolute\", visibility: \"hidden\", display: \"block\" },\n\tcssNormalTransform = {\n\t\tletterSpacing: \"0\",\n\t\tfontWeight: \"400\"\n\t},\n\n\tcssPrefixes = [ \"Webkit\", \"O\", \"Moz\", \"ms\" ];\n\n\n// return a css property mapped to a potentially vendor prefixed property\nfunction vendorPropName( style, name ) {\n\n\t// shortcut for names that are not vendor prefixed\n\tif ( name in style ) {\n\t\treturn name;\n\t}\n\n\t// check for vendor prefixed names\n\tvar capName = name.charAt(0).toUpperCase() + name.slice(1),\n\t\torigName = name,\n\t\ti = cssPrefixes.length;\n\n\twhile ( i-- ) {\n\t\tname = cssPrefixes[ i ] + capName;\n\t\tif ( name in style ) {\n\t\t\treturn name;\n\t\t}\n\t}\n\n\treturn origName;\n}\n\nfunction showHide( elements, show ) {\n\tvar display, elem, hidden,\n\t\tvalues = [],\n\t\tindex = 0,\n\t\tlength = elements.length;\n\n\tfor ( ; index < length; index++ ) {\n\t\telem = elements[ index ];\n\t\tif ( !elem.style ) {\n\t\t\tcontinue;\n\t\t}\n\n\t\tvalues[ index ] = jQuery._data( elem, \"olddisplay\" );\n\t\tdisplay = elem.style.display;\n\t\tif ( show ) {\n\t\t\t// Reset the inline display of this element to learn if it is\n\t\t\t// being hidden by cascaded rules or not\n\t\t\tif ( !values[ index ] && display === \"none\" ) {\n\t\t\t\telem.style.display = \"\";\n\t\t\t}\n\n\t\t\t// Set elements which have been overridden with display: none\n\t\t\t// in a stylesheet to whatever the default browser style is\n\t\t\t// for such an element\n\t\t\tif ( elem.style.display === \"\" && isHidden( elem ) ) {\n\t\t\t\tvalues[ index ] = jQuery._data( elem, \"olddisplay\", defaultDisplay(elem.nodeName) );\n\t\t\t}\n\t\t} else {\n\t\t\thidden = isHidden( elem );\n\n\t\t\tif ( display && display !== \"none\" || !hidden ) {\n\t\t\t\tjQuery._data( elem, \"olddisplay\", hidden ? display : jQuery.css( elem, \"display\" ) );\n\t\t\t}\n\t\t}\n\t}\n\n\t// Set the display of most of the elements in a second loop\n\t// to avoid the constant reflow\n\tfor ( index = 0; index < length; index++ ) {\n\t\telem = elements[ index ];\n\t\tif ( !elem.style ) {\n\t\t\tcontinue;\n\t\t}\n\t\tif ( !show || elem.style.display === \"none\" || elem.style.display === \"\" ) {\n\t\t\telem.style.display = show ? values[ index ] || \"\" : \"none\";\n\t\t}\n\t}\n\n\treturn elements;\n}\n\nfunction setPositiveNumber( elem, value, subtract ) {\n\tvar matches = rnumsplit.exec( value );\n\treturn matches ?\n\t\t// Guard against undefined \"subtract\", e.g., when used as in cssHooks\n\t\tMath.max( 0, matches[ 1 ] - ( subtract || 0 ) ) + ( matches[ 2 ] || \"px\" ) :\n\t\tvalue;\n}\n\nfunction augmentWidthOrHeight( elem, name, extra, isBorderBox, styles ) {\n\tvar i = extra === ( isBorderBox ? \"border\" : \"content\" ) ?\n\t\t// If we already have the right measurement, avoid augmentation\n\t\t4 :\n\t\t// Otherwise initialize for horizontal or vertical properties\n\t\tname === \"width\" ? 1 : 0,\n\n\t\tval = 0;\n\n\tfor ( ; i < 4; i += 2 ) {\n\t\t// both box models exclude margin, so add it if we want it\n\t\tif ( extra === \"margin\" ) {\n\t\t\tval += jQuery.css( elem, extra + cssExpand[ i ], true, styles );\n\t\t}\n\n\t\tif ( isBorderBox ) {\n\t\t\t// border-box includes padding, so remove it if we want content\n\t\t\tif ( extra === \"content\" ) {\n\t\t\t\tval -= jQuery.css( elem, \"padding\" + cssExpand[ i ], true, styles );\n\t\t\t}\n\n\t\t\t// at this point, extra isn't border nor margin, so remove border\n\t\t\tif ( extra !== \"margin\" ) {\n\t\t\t\tval -= jQuery.css( elem, \"border\" + cssExpand[ i ] + \"Width\", true, styles );\n\t\t\t}\n\t\t} else {\n\t\t\t// at this point, extra isn't content, so add padding\n\t\t\tval += jQuery.css( elem, \"padding\" + cssExpand[ i ], true, styles );\n\n\t\t\t// at this point, extra isn't content nor padding, so add border\n\t\t\tif ( extra !== \"padding\" ) {\n\t\t\t\tval += jQuery.css( elem, \"border\" + cssExpand[ i ] + \"Width\", true, styles );\n\t\t\t}\n\t\t}\n\t}\n\n\treturn val;\n}\n\nfunction getWidthOrHeight( elem, name, extra ) {\n\n\t// Start with offset property, which is equivalent to the border-box value\n\tvar valueIsBorderBox = true,\n\t\tval = name === \"width\" ? elem.offsetWidth : elem.offsetHeight,\n\t\tstyles = getStyles( elem ),\n\t\tisBorderBox = support.boxSizing && jQuery.css( elem, \"boxSizing\", false, styles ) === \"border-box\";\n\n\t// some non-html elements return undefined for offsetWidth, so check for null/undefined\n\t// svg - https://bugzilla.mozilla.org/show_bug.cgi?id=649285\n\t// MathML - https://bugzilla.mozilla.org/show_bug.cgi?id=491668\n\tif ( val <= 0 || val == null ) {\n\t\t// Fall back to computed then uncomputed css if necessary\n\t\tval = curCSS( elem, name, styles );\n\t\tif ( val < 0 || val == null ) {\n\t\t\tval = elem.style[ name ];\n\t\t}\n\n\t\t// Computed unit is not pixels. Stop here and return.\n\t\tif ( rnumnonpx.test(val) ) {\n\t\t\treturn val;\n\t\t}\n\n\t\t// we need the check for style in case a browser which returns unreliable values\n\t\t// for getComputedStyle silently falls back to the reliable elem.style\n\t\tvalueIsBorderBox = isBorderBox && ( support.boxSizingReliable() || val === elem.style[ name ] );\n\n\t\t// Normalize \"\", auto, and prepare for extra\n\t\tval = parseFloat( val ) || 0;\n\t}\n\n\t// use the active box-sizing model to add/subtract irrelevant styles\n\treturn ( val +\n\t\taugmentWidthOrHeight(\n\t\t\telem,\n\t\t\tname,\n\t\t\textra || ( isBorderBox ? \"border\" : \"content\" ),\n\t\t\tvalueIsBorderBox,\n\t\t\tstyles\n\t\t)\n\t) + \"px\";\n}\n\njQuery.extend({\n\t// Add in style property hooks for overriding the default\n\t// behavior of getting and setting a style property\n\tcssHooks: {\n\t\topacity: {\n\t\t\tget: function( elem, computed ) {\n\t\t\t\tif ( computed ) {\n\t\t\t\t\t// We should always get a number back from opacity\n\t\t\t\t\tvar ret = curCSS( elem, \"opacity\" );\n\t\t\t\t\treturn ret === \"\" ? \"1\" : ret;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t},\n\n\t// Don't automatically add \"px\" to these possibly-unitless properties\n\tcssNumber: {\n\t\t\"columnCount\": true,\n\t\t\"fillOpacity\": true,\n\t\t\"flexGrow\": true,\n\t\t\"flexShrink\": true,\n\t\t\"fontWeight\": true,\n\t\t\"lineHeight\": true,\n\t\t\"opacity\": true,\n\t\t\"order\": true,\n\t\t\"orphans\": true,\n\t\t\"widows\": true,\n\t\t\"zIndex\": true,\n\t\t\"zoom\": true\n\t},\n\n\t// Add in properties whose names you wish to fix before\n\t// setting or getting the value\n\tcssProps: {\n\t\t// normalize float css property\n\t\t\"float\": support.cssFloat ? \"cssFloat\" : \"styleFloat\"\n\t},\n\n\t// Get and set the style property on a DOM Node\n\tstyle: function( elem, name, value, extra ) {\n\t\t// Don't set styles on text and comment nodes\n\t\tif ( !elem || elem.nodeType === 3 || elem.nodeType === 8 || !elem.style ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Make sure that we're working with the right name\n\t\tvar ret, type, hooks,\n\t\t\torigName = jQuery.camelCase( name ),\n\t\t\tstyle = elem.style;\n\n\t\tname = jQuery.cssProps[ origName ] || ( jQuery.cssProps[ origName ] = vendorPropName( style, origName ) );\n\n\t\t// gets hook for the prefixed version\n\t\t// followed by the unprefixed version\n\t\thooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ];\n\n\t\t// Check if we're setting a value\n\t\tif ( value !== undefined ) {\n\t\t\ttype = typeof value;\n\n\t\t\t// convert relative number strings (+= or -=) to relative numbers. #7345\n\t\t\tif ( type === \"string\" && (ret = rrelNum.exec( value )) ) {\n\t\t\t\tvalue = ( ret[1] + 1 ) * ret[2] + parseFloat( jQuery.css( elem, name ) );\n\t\t\t\t// Fixes bug #9237\n\t\t\t\ttype = \"number\";\n\t\t\t}\n\n\t\t\t// Make sure that null and NaN values aren't set. See: #7116\n\t\t\tif ( value == null || value !== value ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// If a number was passed in, add 'px' to the (except for certain CSS properties)\n\t\t\tif ( type === \"number\" && !jQuery.cssNumber[ origName ] ) {\n\t\t\t\tvalue += \"px\";\n\t\t\t}\n\n\t\t\t// Fixes #8908, it can be done more correctly by specifing setters in cssHooks,\n\t\t\t// but it would mean to define eight (for every problematic property) identical functions\n\t\t\tif ( !support.clearCloneStyle && value === \"\" && name.indexOf(\"background\") === 0 ) {\n\t\t\t\tstyle[ name ] = \"inherit\";\n\t\t\t}\n\n\t\t\t// If a hook was provided, use that value, otherwise just set the specified value\n\t\t\tif ( !hooks || !(\"set\" in hooks) || (value = hooks.set( elem, value, extra )) !== undefined ) {\n\n\t\t\t\t// Support: IE\n\t\t\t\t// Swallow errors from 'invalid' CSS values (#5509)\n\t\t\t\ttry {\n\t\t\t\t\tstyle[ name ] = value;\n\t\t\t\t} catch(e) {}\n\t\t\t}\n\n\t\t} else {\n\t\t\t// If a hook was provided get the non-computed value from there\n\t\t\tif ( hooks && \"get\" in hooks && (ret = hooks.get( elem, false, extra )) !== undefined ) {\n\t\t\t\treturn ret;\n\t\t\t}\n\n\t\t\t// Otherwise just get the value from the style object\n\t\t\treturn style[ name ];\n\t\t}\n\t},\n\n\tcss: function( elem, name, extra, styles ) {\n\t\tvar num, val, hooks,\n\t\t\torigName = jQuery.camelCase( name );\n\n\t\t// Make sure that we're working with the right name\n\t\tname = jQuery.cssProps[ origName ] || ( jQuery.cssProps[ origName ] = vendorPropName( elem.style, origName ) );\n\n\t\t// gets hook for the prefixed version\n\t\t// followed by the unprefixed version\n\t\thooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ];\n\n\t\t// If a hook was provided get the computed value from there\n\t\tif ( hooks && \"get\" in hooks ) {\n\t\t\tval = hooks.get( elem, true, extra );\n\t\t}\n\n\t\t// Otherwise, if a way to get the computed value exists, use that\n\t\tif ( val === undefined ) {\n\t\t\tval = curCSS( elem, name, styles );\n\t\t}\n\n\t\t//convert \"normal\" to computed value\n\t\tif ( val === \"normal\" && name in cssNormalTransform ) {\n\t\t\tval = cssNormalTransform[ name ];\n\t\t}\n\n\t\t// Return, converting to number if forced or a qualifier was provided and val looks numeric\n\t\tif ( extra === \"\" || extra ) {\n\t\t\tnum = parseFloat( val );\n\t\t\treturn extra === true || jQuery.isNumeric( num ) ? num || 0 : val;\n\t\t}\n\t\treturn val;\n\t}\n});\n\njQuery.each([ \"height\", \"width\" ], function( i, name ) {\n\tjQuery.cssHooks[ name ] = {\n\t\tget: function( elem, computed, extra ) {\n\t\t\tif ( computed ) {\n\t\t\t\t// certain elements can have dimension info if we invisibly show them\n\t\t\t\t// however, it must have a current display style that would benefit from this\n\t\t\t\treturn rdisplayswap.test( jQuery.css( elem, \"display\" ) ) && elem.offsetWidth === 0 ?\n\t\t\t\t\tjQuery.swap( elem, cssShow, function() {\n\t\t\t\t\t\treturn getWidthOrHeight( elem, name, extra );\n\t\t\t\t\t}) :\n\t\t\t\t\tgetWidthOrHeight( elem, name, extra );\n\t\t\t}\n\t\t},\n\n\t\tset: function( elem, value, extra ) {\n\t\t\tvar styles = extra && getStyles( elem );\n\t\t\treturn setPositiveNumber( elem, value, extra ?\n\t\t\t\taugmentWidthOrHeight(\n\t\t\t\t\telem,\n\t\t\t\t\tname,\n\t\t\t\t\textra,\n\t\t\t\t\tsupport.boxSizing && jQuery.css( elem, \"boxSizing\", false, styles ) === \"border-box\",\n\t\t\t\t\tstyles\n\t\t\t\t) : 0\n\t\t\t);\n\t\t}\n\t};\n});\n\nif ( !support.opacity ) {\n\tjQuery.cssHooks.opacity = {\n\t\tget: function( elem, computed ) {\n\t\t\t// IE uses filters for opacity\n\t\t\treturn ropacity.test( (computed && elem.currentStyle ? elem.currentStyle.filter : elem.style.filter) || \"\" ) ?\n\t\t\t\t( 0.01 * parseFloat( RegExp.$1 ) ) + \"\" :\n\t\t\t\tcomputed ? \"1\" : \"\";\n\t\t},\n\n\t\tset: function( elem, value ) {\n\t\t\tvar style = elem.style,\n\t\t\t\tcurrentStyle = elem.currentStyle,\n\t\t\t\topacity = jQuery.isNumeric( value ) ? \"alpha(opacity=\" + value * 100 + \")\" : \"\",\n\t\t\t\tfilter = currentStyle && currentStyle.filter || style.filter || \"\";\n\n\t\t\t// IE has trouble with opacity if it does not have layout\n\t\t\t// Force it by setting the zoom level\n\t\t\tstyle.zoom = 1;\n\n\t\t\t// if setting opacity to 1, and no other filters exist - attempt to remove filter attribute #6652\n\t\t\t// if value === \"\", then remove inline opacity #12685\n\t\t\tif ( ( value >= 1 || value === \"\" ) &&\n\t\t\t\t\tjQuery.trim( filter.replace( ralpha, \"\" ) ) === \"\" &&\n\t\t\t\t\tstyle.removeAttribute ) {\n\n\t\t\t\t// Setting style.filter to null, \"\" & \" \" still leave \"filter:\" in the cssText\n\t\t\t\t// if \"filter:\" is present at all, clearType is disabled, we want to avoid this\n\t\t\t\t// style.removeAttribute is IE Only, but so apparently is this code path...\n\t\t\t\tstyle.removeAttribute( \"filter\" );\n\n\t\t\t\t// if there is no filter style applied in a css rule or unset inline opacity, we are done\n\t\t\t\tif ( value === \"\" || currentStyle && !currentStyle.filter ) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// otherwise, set new filter values\n\t\t\tstyle.filter = ralpha.test( filter ) ?\n\t\t\t\tfilter.replace( ralpha, opacity ) :\n\t\t\t\tfilter + \" \" + opacity;\n\t\t}\n\t};\n}\n\njQuery.cssHooks.marginRight = addGetHookIf( support.reliableMarginRight,\n\tfunction( elem, computed ) {\n\t\tif ( computed ) {\n\t\t\t// WebKit Bug 13343 - getComputedStyle returns wrong value for margin-right\n\t\t\t// Work around by temporarily setting element display to inline-block\n\t\t\treturn jQuery.swap( elem, { \"display\": \"inline-block\" },\n\t\t\t\tcurCSS, [ elem, \"marginRight\" ] );\n\t\t}\n\t}\n);\n\n// These hooks are used by animate to expand properties\njQuery.each({\n\tmargin: \"\",\n\tpadding: \"\",\n\tborder: \"Width\"\n}, function( prefix, suffix ) {\n\tjQuery.cssHooks[ prefix + suffix ] = {\n\t\texpand: function( value ) {\n\t\t\tvar i = 0,\n\t\t\t\texpanded = {},\n\n\t\t\t\t// assumes a single number if not a string\n\t\t\t\tparts = typeof value === \"string\" ? value.split(\" \") : [ value ];\n\n\t\t\tfor ( ; i < 4; i++ ) {\n\t\t\t\texpanded[ prefix + cssExpand[ i ] + suffix ] =\n\t\t\t\t\tparts[ i ] || parts[ i - 2 ] || parts[ 0 ];\n\t\t\t}\n\n\t\t\treturn expanded;\n\t\t}\n\t};\n\n\tif ( !rmargin.test( prefix ) ) {\n\t\tjQuery.cssHooks[ prefix + suffix ].set = setPositiveNumber;\n\t}\n});\n\njQuery.fn.extend({\n\tcss: function( name, value ) {\n\t\treturn access( this, function( elem, name, value ) {\n\t\t\tvar styles, len,\n\t\t\t\tmap = {},\n\t\t\t\ti = 0;\n\n\t\t\tif ( jQuery.isArray( name ) ) {\n\t\t\t\tstyles = getStyles( elem );\n\t\t\t\tlen = name.length;\n\n\t\t\t\tfor ( ; i < len; i++ ) {\n\t\t\t\t\tmap[ name[ i ] ] = jQuery.css( elem, name[ i ], false, styles );\n\t\t\t\t}\n\n\t\t\t\treturn map;\n\t\t\t}\n\n\t\t\treturn value !== undefined ?\n\t\t\t\tjQuery.style( elem, name, value ) :\n\t\t\t\tjQuery.css( elem, name );\n\t\t}, name, value, arguments.length > 1 );\n\t},\n\tshow: function() {\n\t\treturn showHide( this, true );\n\t},\n\thide: function() {\n\t\treturn showHide( this );\n\t},\n\ttoggle: function( state ) {\n\t\tif ( typeof state === \"boolean\" ) {\n\t\t\treturn state ? this.show() : this.hide();\n\t\t}\n\n\t\treturn this.each(function() {\n\t\t\tif ( isHidden( this ) ) {\n\t\t\t\tjQuery( this ).show();\n\t\t\t} else {\n\t\t\t\tjQuery( this ).hide();\n\t\t\t}\n\t\t});\n\t}\n});\n\n\nfunction Tween( elem, options, prop, end, easing ) {\n\treturn new Tween.prototype.init( elem, options, prop, end, easing );\n}\njQuery.Tween = Tween;\n\nTween.prototype = {\n\tconstructor: Tween,\n\tinit: function( elem, options, prop, end, easing, unit ) {\n\t\tthis.elem = elem;\n\t\tthis.prop = prop;\n\t\tthis.easing = easing || \"swing\";\n\t\tthis.options = options;\n\t\tthis.start = this.now = this.cur();\n\t\tthis.end = end;\n\t\tthis.unit = unit || ( jQuery.cssNumber[ prop ] ? \"\" : \"px\" );\n\t},\n\tcur: function() {\n\t\tvar hooks = Tween.propHooks[ this.prop ];\n\n\t\treturn hooks && hooks.get ?\n\t\t\thooks.get( this ) :\n\t\t\tTween.propHooks._default.get( this );\n\t},\n\trun: function( percent ) {\n\t\tvar eased,\n\t\t\thooks = Tween.propHooks[ this.prop ];\n\n\t\tif ( this.options.duration ) {\n\t\t\tthis.pos = eased = jQuery.easing[ this.easing ](\n\t\t\t\tpercent, this.options.duration * percent, 0, 1, this.options.duration\n\t\t\t);\n\t\t} else {\n\t\t\tthis.pos = eased = percent;\n\t\t}\n\t\tthis.now = ( this.end - this.start ) * eased + this.start;\n\n\t\tif ( this.options.step ) {\n\t\t\tthis.options.step.call( this.elem, this.now, this );\n\t\t}\n\n\t\tif ( hooks && hooks.set ) {\n\t\t\thooks.set( this );\n\t\t} else {\n\t\t\tTween.propHooks._default.set( this );\n\t\t}\n\t\treturn this;\n\t}\n};\n\nTween.prototype.init.prototype = Tween.prototype;\n\nTween.propHooks = {\n\t_default: {\n\t\tget: function( tween ) {\n\t\t\tvar result;\n\n\t\t\tif ( tween.elem[ tween.prop ] != null &&\n\t\t\t\t(!tween.elem.style || tween.elem.style[ tween.prop ] == null) ) {\n\t\t\t\treturn tween.elem[ tween.prop ];\n\t\t\t}\n\n\t\t\t// passing an empty string as a 3rd parameter to .css will automatically\n\t\t\t// attempt a parseFloat and fallback to a string if the parse fails\n\t\t\t// so, simple values such as \"10px\" are parsed to Float.\n\t\t\t// complex values such as \"rotate(1rad)\" are returned as is.\n\t\t\tresult = jQuery.css( tween.elem, tween.prop, \"\" );\n\t\t\t// Empty strings, null, undefined and \"auto\" are converted to 0.\n\t\t\treturn !result || result === \"auto\" ? 0 : result;\n\t\t},\n\t\tset: function( tween ) {\n\t\t\t// use step hook for back compat - use cssHook if its there - use .style if its\n\t\t\t// available and use plain properties where available\n\t\t\tif ( jQuery.fx.step[ tween.prop ] ) {\n\t\t\t\tjQuery.fx.step[ tween.prop ]( tween );\n\t\t\t} else if ( tween.elem.style && ( tween.elem.style[ jQuery.cssProps[ tween.prop ] ] != null || jQuery.cssHooks[ tween.prop ] ) ) {\n\t\t\t\tjQuery.style( tween.elem, tween.prop, tween.now + tween.unit );\n\t\t\t} else {\n\t\t\t\ttween.elem[ tween.prop ] = tween.now;\n\t\t\t}\n\t\t}\n\t}\n};\n\n// Support: IE <=9\n// Panic based approach to setting things on disconnected nodes\n\nTween.propHooks.scrollTop = Tween.propHooks.scrollLeft = {\n\tset: function( tween ) {\n\t\tif ( tween.elem.nodeType && tween.elem.parentNode ) {\n\t\t\ttween.elem[ tween.prop ] = tween.now;\n\t\t}\n\t}\n};\n\njQuery.easing = {\n\tlinear: function( p ) {\n\t\treturn p;\n\t},\n\tswing: function( p ) {\n\t\treturn 0.5 - Math.cos( p * Math.PI ) / 2;\n\t}\n};\n\njQuery.fx = Tween.prototype.init;\n\n// Back Compat <1.8 extension point\njQuery.fx.step = {};\n\n\n\n\nvar\n\tfxNow, timerId,\n\trfxtypes = /^(?:toggle|show|hide)$/,\n\trfxnum = new RegExp( \"^(?:([+-])=|)(\" + pnum + \")([a-z%]*)$\", \"i\" ),\n\trrun = /queueHooks$/,\n\tanimationPrefilters = [ defaultPrefilter ],\n\ttweeners = {\n\t\t\"*\": [ function( prop, value ) {\n\t\t\tvar tween = this.createTween( prop, value ),\n\t\t\t\ttarget = tween.cur(),\n\t\t\t\tparts = rfxnum.exec( value ),\n\t\t\t\tunit = parts && parts[ 3 ] || ( jQuery.cssNumber[ prop ] ? \"\" : \"px\" ),\n\n\t\t\t\t// Starting value computation is required for potential unit mismatches\n\t\t\t\tstart = ( jQuery.cssNumber[ prop ] || unit !== \"px\" && +target ) &&\n\t\t\t\t\trfxnum.exec( jQuery.css( tween.elem, prop ) ),\n\t\t\t\tscale = 1,\n\t\t\t\tmaxIterations = 20;\n\n\t\t\tif ( start && start[ 3 ] !== unit ) {\n\t\t\t\t// Trust units reported by jQuery.css\n\t\t\t\tunit = unit || start[ 3 ];\n\n\t\t\t\t// Make sure we update the tween properties later on\n\t\t\t\tparts = parts || [];\n\n\t\t\t\t// Iteratively approximate from a nonzero starting point\n\t\t\t\tstart = +target || 1;\n\n\t\t\t\tdo {\n\t\t\t\t\t// If previous iteration zeroed out, double until we get *something*\n\t\t\t\t\t// Use a string for doubling factor so we don't accidentally see scale as unchanged below\n\t\t\t\t\tscale = scale || \".5\";\n\n\t\t\t\t\t// Adjust and apply\n\t\t\t\t\tstart = start / scale;\n\t\t\t\t\tjQuery.style( tween.elem, prop, start + unit );\n\n\t\t\t\t// Update scale, tolerating zero or NaN from tween.cur()\n\t\t\t\t// And breaking the loop if scale is unchanged or perfect, or if we've just had enough\n\t\t\t\t} while ( scale !== (scale = tween.cur() / target) && scale !== 1 && --maxIterations );\n\t\t\t}\n\n\t\t\t// Update tween properties\n\t\t\tif ( parts ) {\n\t\t\t\tstart = tween.start = +start || +target || 0;\n\t\t\t\ttween.unit = unit;\n\t\t\t\t// If a +=/-= token was provided, we're doing a relative animation\n\t\t\t\ttween.end = parts[ 1 ] ?\n\t\t\t\t\tstart + ( parts[ 1 ] + 1 ) * parts[ 2 ] :\n\t\t\t\t\t+parts[ 2 ];\n\t\t\t}\n\n\t\t\treturn tween;\n\t\t} ]\n\t};\n\n// Animations created synchronously will run synchronously\nfunction createFxNow() {\n\tsetTimeout(function() {\n\t\tfxNow = undefined;\n\t});\n\treturn ( fxNow = jQuery.now() );\n}\n\n// Generate parameters to create a standard animation\nfunction genFx( type, includeWidth ) {\n\tvar which,\n\t\tattrs = { height: type },\n\t\ti = 0;\n\n\t// if we include width, step value is 1 to do all cssExpand values,\n\t// if we don't include width, step value is 2 to skip over Left and Right\n\tincludeWidth = includeWidth ? 1 : 0;\n\tfor ( ; i < 4 ; i += 2 - includeWidth ) {\n\t\twhich = cssExpand[ i ];\n\t\tattrs[ \"margin\" + which ] = attrs[ \"padding\" + which ] = type;\n\t}\n\n\tif ( includeWidth ) {\n\t\tattrs.opacity = attrs.width = type;\n\t}\n\n\treturn attrs;\n}\n\nfunction createTween( value, prop, animation ) {\n\tvar tween,\n\t\tcollection = ( tweeners[ prop ] || [] ).concat( tweeners[ \"*\" ] ),\n\t\tindex = 0,\n\t\tlength = collection.length;\n\tfor ( ; index < length; index++ ) {\n\t\tif ( (tween = collection[ index ].call( animation, prop, value )) ) {\n\n\t\t\t// we're done with this property\n\t\t\treturn tween;\n\t\t}\n\t}\n}\n\nfunction defaultPrefilter( elem, props, opts ) {\n\t/* jshint validthis: true */\n\tvar prop, value, toggle, tween, hooks, oldfire, display, checkDisplay,\n\t\tanim = this,\n\t\torig = {},\n\t\tstyle = elem.style,\n\t\thidden = elem.nodeType && isHidden( elem ),\n\t\tdataShow = jQuery._data( elem, \"fxshow\" );\n\n\t// handle queue: false promises\n\tif ( !opts.queue ) {\n\t\thooks = jQuery._queueHooks( elem, \"fx\" );\n\t\tif ( hooks.unqueued == null ) {\n\t\t\thooks.unqueued = 0;\n\t\t\toldfire = hooks.empty.fire;\n\t\t\thooks.empty.fire = function() {\n\t\t\t\tif ( !hooks.unqueued ) {\n\t\t\t\t\toldfire();\n\t\t\t\t}\n\t\t\t};\n\t\t}\n\t\thooks.unqueued++;\n\n\t\tanim.always(function() {\n\t\t\t// doing this makes sure that the complete handler will be called\n\t\t\t// before this completes\n\t\t\tanim.always(function() {\n\t\t\t\thooks.unqueued--;\n\t\t\t\tif ( !jQuery.queue( elem, \"fx\" ).length ) {\n\t\t\t\t\thooks.empty.fire();\n\t\t\t\t}\n\t\t\t});\n\t\t});\n\t}\n\n\t// height/width overflow pass\n\tif ( elem.nodeType === 1 && ( \"height\" in props || \"width\" in props ) ) {\n\t\t// Make sure that nothing sneaks out\n\t\t// Record all 3 overflow attributes because IE does not\n\t\t// change the overflow attribute when overflowX and\n\t\t// overflowY are set to the same value\n\t\topts.overflow = [ style.overflow, style.overflowX, style.overflowY ];\n\n\t\t// Set display property to inline-block for height/width\n\t\t// animations on inline elements that are having width/height animated\n\t\tdisplay = jQuery.css( elem, \"display\" );\n\n\t\t// Test default display if display is currently \"none\"\n\t\tcheckDisplay = display === \"none\" ?\n\t\t\tjQuery._data( elem, \"olddisplay\" ) || defaultDisplay( elem.nodeName ) : display;\n\n\t\tif ( checkDisplay === \"inline\" && jQuery.css( elem, \"float\" ) === \"none\" ) {\n\n\t\t\t// inline-level elements accept inline-block;\n\t\t\t// block-level elements need to be inline with layout\n\t\t\tif ( !support.inlineBlockNeedsLayout || defaultDisplay( elem.nodeName ) === \"inline\" ) {\n\t\t\t\tstyle.display = \"inline-block\";\n\t\t\t} else {\n\t\t\t\tstyle.zoom = 1;\n\t\t\t}\n\t\t}\n\t}\n\n\tif ( opts.overflow ) {\n\t\tstyle.overflow = \"hidden\";\n\t\tif ( !support.shrinkWrapBlocks() ) {\n\t\t\tanim.always(function() {\n\t\t\t\tstyle.overflow = opts.overflow[ 0 ];\n\t\t\t\tstyle.overflowX = opts.overflow[ 1 ];\n\t\t\t\tstyle.overflowY = opts.overflow[ 2 ];\n\t\t\t});\n\t\t}\n\t}\n\n\t// show/hide pass\n\tfor ( prop in props ) {\n\t\tvalue = props[ prop ];\n\t\tif ( rfxtypes.exec( value ) ) {\n\t\t\tdelete props[ prop ];\n\t\t\ttoggle = toggle || value === \"toggle\";\n\t\t\tif ( value === ( hidden ? \"hide\" : \"show\" ) ) {\n\n\t\t\t\t// If there is dataShow left over from a stopped hide or show and we are going to proceed with show, we should pretend to be hidden\n\t\t\t\tif ( value === \"show\" && dataShow && dataShow[ prop ] !== undefined ) {\n\t\t\t\t\thidden = true;\n\t\t\t\t} else {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t}\n\t\t\torig[ prop ] = dataShow && dataShow[ prop ] || jQuery.style( elem, prop );\n\n\t\t// Any non-fx value stops us from restoring the original display value\n\t\t} else {\n\t\t\tdisplay = undefined;\n\t\t}\n\t}\n\n\tif ( !jQuery.isEmptyObject( orig ) ) {\n\t\tif ( dataShow ) {\n\t\t\tif ( \"hidden\" in dataShow ) {\n\t\t\t\thidden = dataShow.hidden;\n\t\t\t}\n\t\t} else {\n\t\t\tdataShow = jQuery._data( elem, \"fxshow\", {} );\n\t\t}\n\n\t\t// store state if its toggle - enables .stop().toggle() to \"reverse\"\n\t\tif ( toggle ) {\n\t\t\tdataShow.hidden = !hidden;\n\t\t}\n\t\tif ( hidden ) {\n\t\t\tjQuery( elem ).show();\n\t\t} else {\n\t\t\tanim.done(function() {\n\t\t\t\tjQuery( elem ).hide();\n\t\t\t});\n\t\t}\n\t\tanim.done(function() {\n\t\t\tvar prop;\n\t\t\tjQuery._removeData( elem, \"fxshow\" );\n\t\t\tfor ( prop in orig ) {\n\t\t\t\tjQuery.style( elem, prop, orig[ prop ] );\n\t\t\t}\n\t\t});\n\t\tfor ( prop in orig ) {\n\t\t\ttween = createTween( hidden ? dataShow[ prop ] : 0, prop, anim );\n\n\t\t\tif ( !( prop in dataShow ) ) {\n\t\t\t\tdataShow[ prop ] = tween.start;\n\t\t\t\tif ( hidden ) {\n\t\t\t\t\ttween.end = tween.start;\n\t\t\t\t\ttween.start = prop === \"width\" || prop === \"height\" ? 1 : 0;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t// If this is a noop like .hide().hide(), restore an overwritten display value\n\t} else if ( (display === \"none\" ? defaultDisplay( elem.nodeName ) : display) === \"inline\" ) {\n\t\tstyle.display = display;\n\t}\n}\n\nfunction propFilter( props, specialEasing ) {\n\tvar index, name, easing, value, hooks;\n\n\t// camelCase, specialEasing and expand cssHook pass\n\tfor ( index in props ) {\n\t\tname = jQuery.camelCase( index );\n\t\teasing = specialEasing[ name ];\n\t\tvalue = props[ index ];\n\t\tif ( jQuery.isArray( value ) ) {\n\t\t\teasing = value[ 1 ];\n\t\t\tvalue = props[ index ] = value[ 0 ];\n\t\t}\n\n\t\tif ( index !== name ) {\n\t\t\tprops[ name ] = value;\n\t\t\tdelete props[ index ];\n\t\t}\n\n\t\thooks = jQuery.cssHooks[ name ];\n\t\tif ( hooks && \"expand\" in hooks ) {\n\t\t\tvalue = hooks.expand( value );\n\t\t\tdelete props[ name ];\n\n\t\t\t// not quite $.extend, this wont overwrite keys already present.\n\t\t\t// also - reusing 'index' from above because we have the correct \"name\"\n\t\t\tfor ( index in value ) {\n\t\t\t\tif ( !( index in props ) ) {\n\t\t\t\t\tprops[ index ] = value[ index ];\n\t\t\t\t\tspecialEasing[ index ] = easing;\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\tspecialEasing[ name ] = easing;\n\t\t}\n\t}\n}\n\nfunction Animation( elem, properties, options ) {\n\tvar result,\n\t\tstopped,\n\t\tindex = 0,\n\t\tlength = animationPrefilters.length,\n\t\tdeferred = jQuery.Deferred().always( function() {\n\t\t\t// don't match elem in the :animated selector\n\t\t\tdelete tick.elem;\n\t\t}),\n\t\ttick = function() {\n\t\t\tif ( stopped ) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\tvar currentTime = fxNow || createFxNow(),\n\t\t\t\tremaining = Math.max( 0, animation.startTime + animation.duration - currentTime ),\n\t\t\t\t// archaic crash bug won't allow us to use 1 - ( 0.5 || 0 ) (#12497)\n\t\t\t\ttemp = remaining / animation.duration || 0,\n\t\t\t\tpercent = 1 - temp,\n\t\t\t\tindex = 0,\n\t\t\t\tlength = animation.tweens.length;\n\n\t\t\tfor ( ; index < length ; index++ ) {\n\t\t\t\tanimation.tweens[ index ].run( percent );\n\t\t\t}\n\n\t\t\tdeferred.notifyWith( elem, [ animation, percent, remaining ]);\n\n\t\t\tif ( percent < 1 && length ) {\n\t\t\t\treturn remaining;\n\t\t\t} else {\n\t\t\t\tdeferred.resolveWith( elem, [ animation ] );\n\t\t\t\treturn false;\n\t\t\t}\n\t\t},\n\t\tanimation = deferred.promise({\n\t\t\telem: elem,\n\t\t\tprops: jQuery.extend( {}, properties ),\n\t\t\topts: jQuery.extend( true, { specialEasing: {} }, options ),\n\t\t\toriginalProperties: properties,\n\t\t\toriginalOptions: options,\n\t\t\tstartTime: fxNow || createFxNow(),\n\t\t\tduration: options.duration,\n\t\t\ttweens: [],\n\t\t\tcreateTween: function( prop, end ) {\n\t\t\t\tvar tween = jQuery.Tween( elem, animation.opts, prop, end,\n\t\t\t\t\t\tanimation.opts.specialEasing[ prop ] || animation.opts.easing );\n\t\t\t\tanimation.tweens.push( tween );\n\t\t\t\treturn tween;\n\t\t\t},\n\t\t\tstop: function( gotoEnd ) {\n\t\t\t\tvar index = 0,\n\t\t\t\t\t// if we are going to the end, we want to run all the tweens\n\t\t\t\t\t// otherwise we skip this part\n\t\t\t\t\tlength = gotoEnd ? animation.tweens.length : 0;\n\t\t\t\tif ( stopped ) {\n\t\t\t\t\treturn this;\n\t\t\t\t}\n\t\t\t\tstopped = true;\n\t\t\t\tfor ( ; index < length ; index++ ) {\n\t\t\t\t\tanimation.tweens[ index ].run( 1 );\n\t\t\t\t}\n\n\t\t\t\t// resolve when we played the last frame\n\t\t\t\t// otherwise, reject\n\t\t\t\tif ( gotoEnd ) {\n\t\t\t\t\tdeferred.resolveWith( elem, [ animation, gotoEnd ] );\n\t\t\t\t} else {\n\t\t\t\t\tdeferred.rejectWith( elem, [ animation, gotoEnd ] );\n\t\t\t\t}\n\t\t\t\treturn this;\n\t\t\t}\n\t\t}),\n\t\tprops = animation.props;\n\n\tpropFilter( props, animation.opts.specialEasing );\n\n\tfor ( ; index < length ; index++ ) {\n\t\tresult = animationPrefilters[ index ].call( animation, elem, props, animation.opts );\n\t\tif ( result ) {\n\t\t\treturn result;\n\t\t}\n\t}\n\n\tjQuery.map( props, createTween, animation );\n\n\tif ( jQuery.isFunction( animation.opts.start ) ) {\n\t\tanimation.opts.start.call( elem, animation );\n\t}\n\n\tjQuery.fx.timer(\n\t\tjQuery.extend( tick, {\n\t\t\telem: elem,\n\t\t\tanim: animation,\n\t\t\tqueue: animation.opts.queue\n\t\t})\n\t);\n\n\t// attach callbacks from options\n\treturn animation.progress( animation.opts.progress )\n\t\t.done( animation.opts.done, animation.opts.complete )\n\t\t.fail( animation.opts.fail )\n\t\t.always( animation.opts.always );\n}\n\njQuery.Animation = jQuery.extend( Animation, {\n\ttweener: function( props, callback ) {\n\t\tif ( jQuery.isFunction( props ) ) {\n\t\t\tcallback = props;\n\t\t\tprops = [ \"*\" ];\n\t\t} else {\n\t\t\tprops = props.split(\" \");\n\t\t}\n\n\t\tvar prop,\n\t\t\tindex = 0,\n\t\t\tlength = props.length;\n\n\t\tfor ( ; index < length ; index++ ) {\n\t\t\tprop = props[ index ];\n\t\t\ttweeners[ prop ] = tweeners[ prop ] || [];\n\t\t\ttweeners[ prop ].unshift( callback );\n\t\t}\n\t},\n\n\tprefilter: function( callback, prepend ) {\n\t\tif ( prepend ) {\n\t\t\tanimationPrefilters.unshift( callback );\n\t\t} else {\n\t\t\tanimationPrefilters.push( callback );\n\t\t}\n\t}\n});\n\njQuery.speed = function( speed, easing, fn ) {\n\tvar opt = speed && typeof speed === \"object\" ? jQuery.extend( {}, speed ) : {\n\t\tcomplete: fn || !fn && easing ||\n\t\t\tjQuery.isFunction( speed ) && speed,\n\t\tduration: speed,\n\t\teasing: fn && easing || easing && !jQuery.isFunction( easing ) && easing\n\t};\n\n\topt.duration = jQuery.fx.off ? 0 : typeof opt.duration === \"number\" ? opt.duration :\n\t\topt.duration in jQuery.fx.speeds ? jQuery.fx.speeds[ opt.duration ] : jQuery.fx.speeds._default;\n\n\t// normalize opt.queue - true/undefined/null -> \"fx\"\n\tif ( opt.queue == null || opt.queue === true ) {\n\t\topt.queue = \"fx\";\n\t}\n\n\t// Queueing\n\topt.old = opt.complete;\n\n\topt.complete = function() {\n\t\tif ( jQuery.isFunction( opt.old ) ) {\n\t\t\topt.old.call( this );\n\t\t}\n\n\t\tif ( opt.queue ) {\n\t\t\tjQuery.dequeue( this, opt.queue );\n\t\t}\n\t};\n\n\treturn opt;\n};\n\njQuery.fn.extend({\n\tfadeTo: function( speed, to, easing, callback ) {\n\n\t\t// show any hidden elements after setting opacity to 0\n\t\treturn this.filter( isHidden ).css( \"opacity\", 0 ).show()\n\n\t\t\t// animate to the value specified\n\t\t\t.end().animate({ opacity: to }, speed, easing, callback );\n\t},\n\tanimate: function( prop, speed, easing, callback ) {\n\t\tvar empty = jQuery.isEmptyObject( prop ),\n\t\t\toptall = jQuery.speed( speed, easing, callback ),\n\t\t\tdoAnimation = function() {\n\t\t\t\t// Operate on a copy of prop so per-property easing won't be lost\n\t\t\t\tvar anim = Animation( this, jQuery.extend( {}, prop ), optall );\n\n\t\t\t\t// Empty animations, or finishing resolves immediately\n\t\t\t\tif ( empty || jQuery._data( this, \"finish\" ) ) {\n\t\t\t\t\tanim.stop( true );\n\t\t\t\t}\n\t\t\t};\n\t\t\tdoAnimation.finish = doAnimation;\n\n\t\treturn empty || optall.queue === false ?\n\t\t\tthis.each( doAnimation ) :\n\t\t\tthis.queue( optall.queue, doAnimation );\n\t},\n\tstop: function( type, clearQueue, gotoEnd ) {\n\t\tvar stopQueue = function( hooks ) {\n\t\t\tvar stop = hooks.stop;\n\t\t\tdelete hooks.stop;\n\t\t\tstop( gotoEnd );\n\t\t};\n\n\t\tif ( typeof type !== \"string\" ) {\n\t\t\tgotoEnd = clearQueue;\n\t\t\tclearQueue = type;\n\t\t\ttype = undefined;\n\t\t}\n\t\tif ( clearQueue && type !== false ) {\n\t\t\tthis.queue( type || \"fx\", [] );\n\t\t}\n\n\t\treturn this.each(function() {\n\t\t\tvar dequeue = true,\n\t\t\t\tindex = type != null && type + \"queueHooks\",\n\t\t\t\ttimers = jQuery.timers,\n\t\t\t\tdata = jQuery._data( this );\n\n\t\t\tif ( index ) {\n\t\t\t\tif ( data[ index ] && data[ index ].stop ) {\n\t\t\t\t\tstopQueue( data[ index ] );\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tfor ( index in data ) {\n\t\t\t\t\tif ( data[ index ] && data[ index ].stop && rrun.test( index ) ) {\n\t\t\t\t\t\tstopQueue( data[ index ] );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tfor ( index = timers.length; index--; ) {\n\t\t\t\tif ( timers[ index ].elem === this && (type == null || timers[ index ].queue === type) ) {\n\t\t\t\t\ttimers[ index ].anim.stop( gotoEnd );\n\t\t\t\t\tdequeue = false;\n\t\t\t\t\ttimers.splice( index, 1 );\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// start the next in the queue if the last step wasn't forced\n\t\t\t// timers currently will call their complete callbacks, which will dequeue\n\t\t\t// but only if they were gotoEnd\n\t\t\tif ( dequeue || !gotoEnd ) {\n\t\t\t\tjQuery.dequeue( this, type );\n\t\t\t}\n\t\t});\n\t},\n\tfinish: function( type ) {\n\t\tif ( type !== false ) {\n\t\t\ttype = type || \"fx\";\n\t\t}\n\t\treturn this.each(function() {\n\t\t\tvar index,\n\t\t\t\tdata = jQuery._data( this ),\n\t\t\t\tqueue = data[ type + \"queue\" ],\n\t\t\t\thooks = data[ type + \"queueHooks\" ],\n\t\t\t\ttimers = jQuery.timers,\n\t\t\t\tlength = queue ? queue.length : 0;\n\n\t\t\t// enable finishing flag on private data\n\t\t\tdata.finish = true;\n\n\t\t\t// empty the queue first\n\t\t\tjQuery.queue( this, type, [] );\n\n\t\t\tif ( hooks && hooks.stop ) {\n\t\t\t\thooks.stop.call( this, true );\n\t\t\t}\n\n\t\t\t// look for any active animations, and finish them\n\t\t\tfor ( index = timers.length; index--; ) {\n\t\t\t\tif ( timers[ index ].elem === this && timers[ index ].queue === type ) {\n\t\t\t\t\ttimers[ index ].anim.stop( true );\n\t\t\t\t\ttimers.splice( index, 1 );\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// look for any animations in the old queue and finish them\n\t\t\tfor ( index = 0; index < length; index++ ) {\n\t\t\t\tif ( queue[ index ] && queue[ index ].finish ) {\n\t\t\t\t\tqueue[ index ].finish.call( this );\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// turn off finishing flag\n\t\t\tdelete data.finish;\n\t\t});\n\t}\n});\n\njQuery.each([ \"toggle\", \"show\", \"hide\" ], function( i, name ) {\n\tvar cssFn = jQuery.fn[ name ];\n\tjQuery.fn[ name ] = function( speed, easing, callback ) {\n\t\treturn speed == null || typeof speed === \"boolean\" ?\n\t\t\tcssFn.apply( this, arguments ) :\n\t\t\tthis.animate( genFx( name, true ), speed, easing, callback );\n\t};\n});\n\n// Generate shortcuts for custom animations\njQuery.each({\n\tslideDown: genFx(\"show\"),\n\tslideUp: genFx(\"hide\"),\n\tslideToggle: genFx(\"toggle\"),\n\tfadeIn: { opacity: \"show\" },\n\tfadeOut: { opacity: \"hide\" },\n\tfadeToggle: { opacity: \"toggle\" }\n}, function( name, props ) {\n\tjQuery.fn[ name ] = function( speed, easing, callback ) {\n\t\treturn this.animate( props, speed, easing, callback );\n\t};\n});\n\njQuery.timers = [];\njQuery.fx.tick = function() {\n\tvar timer,\n\t\ttimers = jQuery.timers,\n\t\ti = 0;\n\n\tfxNow = jQuery.now();\n\n\tfor ( ; i < timers.length; i++ ) {\n\t\ttimer = timers[ i ];\n\t\t// Checks the timer has not already been removed\n\t\tif ( !timer() && timers[ i ] === timer ) {\n\t\t\ttimers.splice( i--, 1 );\n\t\t}\n\t}\n\n\tif ( !timers.length ) {\n\t\tjQuery.fx.stop();\n\t}\n\tfxNow = undefined;\n};\n\njQuery.fx.timer = function( timer ) {\n\tjQuery.timers.push( timer );\n\tif ( timer() ) {\n\t\tjQuery.fx.start();\n\t} else {\n\t\tjQuery.timers.pop();\n\t}\n};\n\njQuery.fx.interval = 13;\n\njQuery.fx.start = function() {\n\tif ( !timerId ) {\n\t\ttimerId = setInterval( jQuery.fx.tick, jQuery.fx.interval );\n\t}\n};\n\njQuery.fx.stop = function() {\n\tclearInterval( timerId );\n\ttimerId = null;\n};\n\njQuery.fx.speeds = {\n\tslow: 600,\n\tfast: 200,\n\t// Default speed\n\t_default: 400\n};\n\n\n// Based off of the plugin by Clint Helfers, with permission.\n// http://blindsignals.com/index.php/2009/07/jquery-delay/\njQuery.fn.delay = function( time, type ) {\n\ttime = jQuery.fx ? jQuery.fx.speeds[ time ] || time : time;\n\ttype = type || \"fx\";\n\n\treturn this.queue( type, function( next, hooks ) {\n\t\tvar timeout = setTimeout( next, time );\n\t\thooks.stop = function() {\n\t\t\tclearTimeout( timeout );\n\t\t};\n\t});\n};\n\n\n(function() {\n\t// Minified: var a,b,c,d,e\n\tvar input, div, select, a, opt;\n\n\t// Setup\n\tdiv = document.createElement( \"div\" );\n\tdiv.setAttribute( \"className\", \"t\" );\n\tdiv.innerHTML = \"  <link/><table></table><a href='/a'>a</a><input type='checkbox'/>\";\n\ta = div.getElementsByTagName(\"a\")[ 0 ];\n\n\t// First batch of tests.\n\tselect = document.createElement(\"select\");\n\topt = select.appendChild( document.createElement(\"option\") );\n\tinput = div.getElementsByTagName(\"input\")[ 0 ];\n\n\ta.style.cssText = \"top:1px\";\n\n\t// Test setAttribute on camelCase class. If it works, we need attrFixes when doing get/setAttribute (ie6/7)\n\tsupport.getSetAttribute = div.className !== \"t\";\n\n\t// Get the style information from getAttribute\n\t// (IE uses .cssText instead)\n\tsupport.style = /top/.test( a.getAttribute(\"style\") );\n\n\t// Make sure that URLs aren't manipulated\n\t// (IE normalizes it by default)\n\tsupport.hrefNormalized = a.getAttribute(\"href\") === \"/a\";\n\n\t// Check the default checkbox/radio value (\"\" on WebKit; \"on\" elsewhere)\n\tsupport.checkOn = !!input.value;\n\n\t// Make sure that a selected-by-default option has a working selected property.\n\t// (WebKit defaults to false instead of true, IE too, if it's in an optgroup)\n\tsupport.optSelected = opt.selected;\n\n\t// Tests for enctype support on a form (#6743)\n\tsupport.enctype = !!document.createElement(\"form\").enctype;\n\n\t// Make sure that the options inside disabled selects aren't marked as disabled\n\t// (WebKit marks them as disabled)\n\tselect.disabled = true;\n\tsupport.optDisabled = !opt.disabled;\n\n\t// Support: IE8 only\n\t// Check if we can trust getAttribute(\"value\")\n\tinput = document.createElement( \"input\" );\n\tinput.setAttribute( \"value\", \"\" );\n\tsupport.input = input.getAttribute( \"value\" ) === \"\";\n\n\t// Check if an input maintains its value after becoming a radio\n\tinput.value = \"t\";\n\tinput.setAttribute( \"type\", \"radio\" );\n\tsupport.radioValue = input.value === \"t\";\n})();\n\n\nvar rreturn = /\\r/g;\n\njQuery.fn.extend({\n\tval: function( value ) {\n\t\tvar hooks, ret, isFunction,\n\t\t\telem = this[0];\n\n\t\tif ( !arguments.length ) {\n\t\t\tif ( elem ) {\n\t\t\t\thooks = jQuery.valHooks[ elem.type ] || jQuery.valHooks[ elem.nodeName.toLowerCase() ];\n\n\t\t\t\tif ( hooks && \"get\" in hooks && (ret = hooks.get( elem, \"value\" )) !== undefined ) {\n\t\t\t\t\treturn ret;\n\t\t\t\t}\n\n\t\t\t\tret = elem.value;\n\n\t\t\t\treturn typeof ret === \"string\" ?\n\t\t\t\t\t// handle most common string cases\n\t\t\t\t\tret.replace(rreturn, \"\") :\n\t\t\t\t\t// handle cases where value is null/undef or number\n\t\t\t\t\tret == null ? \"\" : ret;\n\t\t\t}\n\n\t\t\treturn;\n\t\t}\n\n\t\tisFunction = jQuery.isFunction( value );\n\n\t\treturn this.each(function( i ) {\n\t\t\tvar val;\n\n\t\t\tif ( this.nodeType !== 1 ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif ( isFunction ) {\n\t\t\t\tval = value.call( this, i, jQuery( this ).val() );\n\t\t\t} else {\n\t\t\t\tval = value;\n\t\t\t}\n\n\t\t\t// Treat null/undefined as \"\"; convert numbers to string\n\t\t\tif ( val == null ) {\n\t\t\t\tval = \"\";\n\t\t\t} else if ( typeof val === \"number\" ) {\n\t\t\t\tval += \"\";\n\t\t\t} else if ( jQuery.isArray( val ) ) {\n\t\t\t\tval = jQuery.map( val, function( value ) {\n\t\t\t\t\treturn value == null ? \"\" : value + \"\";\n\t\t\t\t});\n\t\t\t}\n\n\t\t\thooks = jQuery.valHooks[ this.type ] || jQuery.valHooks[ this.nodeName.toLowerCase() ];\n\n\t\t\t// If set returns undefined, fall back to normal setting\n\t\t\tif ( !hooks || !(\"set\" in hooks) || hooks.set( this, val, \"value\" ) === undefined ) {\n\t\t\t\tthis.value = val;\n\t\t\t}\n\t\t});\n\t}\n});\n\njQuery.extend({\n\tvalHooks: {\n\t\toption: {\n\t\t\tget: function( elem ) {\n\t\t\t\tvar val = jQuery.find.attr( elem, \"value\" );\n\t\t\t\treturn val != null ?\n\t\t\t\t\tval :\n\t\t\t\t\t// Support: IE10-11+\n\t\t\t\t\t// option.text throws exceptions (#14686, #14858)\n\t\t\t\t\tjQuery.trim( jQuery.text( elem ) );\n\t\t\t}\n\t\t},\n\t\tselect: {\n\t\t\tget: function( elem ) {\n\t\t\t\tvar value, option,\n\t\t\t\t\toptions = elem.options,\n\t\t\t\t\tindex = elem.selectedIndex,\n\t\t\t\t\tone = elem.type === \"select-one\" || index < 0,\n\t\t\t\t\tvalues = one ? null : [],\n\t\t\t\t\tmax = one ? index + 1 : options.length,\n\t\t\t\t\ti = index < 0 ?\n\t\t\t\t\t\tmax :\n\t\t\t\t\t\tone ? index : 0;\n\n\t\t\t\t// Loop through all the selected options\n\t\t\t\tfor ( ; i < max; i++ ) {\n\t\t\t\t\toption = options[ i ];\n\n\t\t\t\t\t// oldIE doesn't update selected after form reset (#2551)\n\t\t\t\t\tif ( ( option.selected || i === index ) &&\n\t\t\t\t\t\t\t// Don't return options that are disabled or in a disabled optgroup\n\t\t\t\t\t\t\t( support.optDisabled ? !option.disabled : option.getAttribute(\"disabled\") === null ) &&\n\t\t\t\t\t\t\t( !option.parentNode.disabled || !jQuery.nodeName( option.parentNode, \"optgroup\" ) ) ) {\n\n\t\t\t\t\t\t// Get the specific value for the option\n\t\t\t\t\t\tvalue = jQuery( option ).val();\n\n\t\t\t\t\t\t// We don't need an array for one selects\n\t\t\t\t\t\tif ( one ) {\n\t\t\t\t\t\t\treturn value;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// Multi-Selects return an array\n\t\t\t\t\t\tvalues.push( value );\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\treturn values;\n\t\t\t},\n\n\t\t\tset: function( elem, value ) {\n\t\t\t\tvar optionSet, option,\n\t\t\t\t\toptions = elem.options,\n\t\t\t\t\tvalues = jQuery.makeArray( value ),\n\t\t\t\t\ti = options.length;\n\n\t\t\t\twhile ( i-- ) {\n\t\t\t\t\toption = options[ i ];\n\n\t\t\t\t\tif ( jQuery.inArray( jQuery.valHooks.option.get( option ), values ) >= 0 ) {\n\n\t\t\t\t\t\t// Support: IE6\n\t\t\t\t\t\t// When new option element is added to select box we need to\n\t\t\t\t\t\t// force reflow of newly added node in order to workaround delay\n\t\t\t\t\t\t// of initialization properties\n\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\toption.selected = optionSet = true;\n\n\t\t\t\t\t\t} catch ( _ ) {\n\n\t\t\t\t\t\t\t// Will be executed only in IE6\n\t\t\t\t\t\t\toption.scrollHeight;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t} else {\n\t\t\t\t\t\toption.selected = false;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// Force browsers to behave consistently when non-matching value is set\n\t\t\t\tif ( !optionSet ) {\n\t\t\t\t\telem.selectedIndex = -1;\n\t\t\t\t}\n\n\t\t\t\treturn options;\n\t\t\t}\n\t\t}\n\t}\n});\n\n// Radios and checkboxes getter/setter\njQuery.each([ \"radio\", \"checkbox\" ], function() {\n\tjQuery.valHooks[ this ] = {\n\t\tset: function( elem, value ) {\n\t\t\tif ( jQuery.isArray( value ) ) {\n\t\t\t\treturn ( elem.checked = jQuery.inArray( jQuery(elem).val(), value ) >= 0 );\n\t\t\t}\n\t\t}\n\t};\n\tif ( !support.checkOn ) {\n\t\tjQuery.valHooks[ this ].get = function( elem ) {\n\t\t\t// Support: Webkit\n\t\t\t// \"\" is returned instead of \"on\" if a value isn't specified\n\t\t\treturn elem.getAttribute(\"value\") === null ? \"on\" : elem.value;\n\t\t};\n\t}\n});\n\n\n\n\nvar nodeHook, boolHook,\n\tattrHandle = jQuery.expr.attrHandle,\n\truseDefault = /^(?:checked|selected)$/i,\n\tgetSetAttribute = support.getSetAttribute,\n\tgetSetInput = support.input;\n\njQuery.fn.extend({\n\tattr: function( name, value ) {\n\t\treturn access( this, jQuery.attr, name, value, arguments.length > 1 );\n\t},\n\n\tremoveAttr: function( name ) {\n\t\treturn this.each(function() {\n\t\t\tjQuery.removeAttr( this, name );\n\t\t});\n\t}\n});\n\njQuery.extend({\n\tattr: function( elem, name, value ) {\n\t\tvar hooks, ret,\n\t\t\tnType = elem.nodeType;\n\n\t\t// don't get/set attributes on text, comment and attribute nodes\n\t\tif ( !elem || nType === 3 || nType === 8 || nType === 2 ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Fallback to prop when attributes are not supported\n\t\tif ( typeof elem.getAttribute === strundefined ) {\n\t\t\treturn jQuery.prop( elem, name, value );\n\t\t}\n\n\t\t// All attributes are lowercase\n\t\t// Grab necessary hook if one is defined\n\t\tif ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) {\n\t\t\tname = name.toLowerCase();\n\t\t\thooks = jQuery.attrHooks[ name ] ||\n\t\t\t\t( jQuery.expr.match.bool.test( name ) ? boolHook : nodeHook );\n\t\t}\n\n\t\tif ( value !== undefined ) {\n\n\t\t\tif ( value === null ) {\n\t\t\t\tjQuery.removeAttr( elem, name );\n\n\t\t\t} else if ( hooks && \"set\" in hooks && (ret = hooks.set( elem, value, name )) !== undefined ) {\n\t\t\t\treturn ret;\n\n\t\t\t} else {\n\t\t\t\telem.setAttribute( name, value + \"\" );\n\t\t\t\treturn value;\n\t\t\t}\n\n\t\t} else if ( hooks && \"get\" in hooks && (ret = hooks.get( elem, name )) !== null ) {\n\t\t\treturn ret;\n\n\t\t} else {\n\t\t\tret = jQuery.find.attr( elem, name );\n\n\t\t\t// Non-existent attributes return null, we normalize to undefined\n\t\t\treturn ret == null ?\n\t\t\t\tundefined :\n\t\t\t\tret;\n\t\t}\n\t},\n\n\tremoveAttr: function( elem, value ) {\n\t\tvar name, propName,\n\t\t\ti = 0,\n\t\t\tattrNames = value && value.match( rnotwhite );\n\n\t\tif ( attrNames && elem.nodeType === 1 ) {\n\t\t\twhile ( (name = attrNames[i++]) ) {\n\t\t\t\tpropName = jQuery.propFix[ name ] || name;\n\n\t\t\t\t// Boolean attributes get special treatment (#10870)\n\t\t\t\tif ( jQuery.expr.match.bool.test( name ) ) {\n\t\t\t\t\t// Set corresponding property to false\n\t\t\t\t\tif ( getSetInput && getSetAttribute || !ruseDefault.test( name ) ) {\n\t\t\t\t\t\telem[ propName ] = false;\n\t\t\t\t\t// Support: IE<9\n\t\t\t\t\t// Also clear defaultChecked/defaultSelected (if appropriate)\n\t\t\t\t\t} else {\n\t\t\t\t\t\telem[ jQuery.camelCase( \"default-\" + name ) ] =\n\t\t\t\t\t\t\telem[ propName ] = false;\n\t\t\t\t\t}\n\n\t\t\t\t// See #9699 for explanation of this approach (setting first, then removal)\n\t\t\t\t} else {\n\t\t\t\t\tjQuery.attr( elem, name, \"\" );\n\t\t\t\t}\n\n\t\t\t\telem.removeAttribute( getSetAttribute ? name : propName );\n\t\t\t}\n\t\t}\n\t},\n\n\tattrHooks: {\n\t\ttype: {\n\t\t\tset: function( elem, value ) {\n\t\t\t\tif ( !support.radioValue && value === \"radio\" && jQuery.nodeName(elem, \"input\") ) {\n\t\t\t\t\t// Setting the type on a radio button after the value resets the value in IE6-9\n\t\t\t\t\t// Reset value to default in case type is set after value during creation\n\t\t\t\t\tvar val = elem.value;\n\t\t\t\t\telem.setAttribute( \"type\", value );\n\t\t\t\t\tif ( val ) {\n\t\t\t\t\t\telem.value = val;\n\t\t\t\t\t}\n\t\t\t\t\treturn value;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n});\n\n// Hook for boolean attributes\nboolHook = {\n\tset: function( elem, value, name ) {\n\t\tif ( value === false ) {\n\t\t\t// Remove boolean attributes when set to false\n\t\t\tjQuery.removeAttr( elem, name );\n\t\t} else if ( getSetInput && getSetAttribute || !ruseDefault.test( name ) ) {\n\t\t\t// IE<8 needs the *property* name\n\t\t\telem.setAttribute( !getSetAttribute && jQuery.propFix[ name ] || name, name );\n\n\t\t// Use defaultChecked and defaultSelected for oldIE\n\t\t} else {\n\t\t\telem[ jQuery.camelCase( \"default-\" + name ) ] = elem[ name ] = true;\n\t\t}\n\n\t\treturn name;\n\t}\n};\n\n// Retrieve booleans specially\njQuery.each( jQuery.expr.match.bool.source.match( /\\w+/g ), function( i, name ) {\n\n\tvar getter = attrHandle[ name ] || jQuery.find.attr;\n\n\tattrHandle[ name ] = getSetInput && getSetAttribute || !ruseDefault.test( name ) ?\n\t\tfunction( elem, name, isXML ) {\n\t\t\tvar ret, handle;\n\t\t\tif ( !isXML ) {\n\t\t\t\t// Avoid an infinite loop by temporarily removing this function from the getter\n\t\t\t\thandle = attrHandle[ name ];\n\t\t\t\tattrHandle[ name ] = ret;\n\t\t\t\tret = getter( elem, name, isXML ) != null ?\n\t\t\t\t\tname.toLowerCase() :\n\t\t\t\t\tnull;\n\t\t\t\tattrHandle[ name ] = handle;\n\t\t\t}\n\t\t\treturn ret;\n\t\t} :\n\t\tfunction( elem, name, isXML ) {\n\t\t\tif ( !isXML ) {\n\t\t\t\treturn elem[ jQuery.camelCase( \"default-\" + name ) ] ?\n\t\t\t\t\tname.toLowerCase() :\n\t\t\t\t\tnull;\n\t\t\t}\n\t\t};\n});\n\n// fix oldIE attroperties\nif ( !getSetInput || !getSetAttribute ) {\n\tjQuery.attrHooks.value = {\n\t\tset: function( elem, value, name ) {\n\t\t\tif ( jQuery.nodeName( elem, \"input\" ) ) {\n\t\t\t\t// Does not return so that setAttribute is also used\n\t\t\t\telem.defaultValue = value;\n\t\t\t} else {\n\t\t\t\t// Use nodeHook if defined (#1954); otherwise setAttribute is fine\n\t\t\t\treturn nodeHook && nodeHook.set( elem, value, name );\n\t\t\t}\n\t\t}\n\t};\n}\n\n// IE6/7 do not support getting/setting some attributes with get/setAttribute\nif ( !getSetAttribute ) {\n\n\t// Use this for any attribute in IE6/7\n\t// This fixes almost every IE6/7 issue\n\tnodeHook = {\n\t\tset: function( elem, value, name ) {\n\t\t\t// Set the existing or create a new attribute node\n\t\t\tvar ret = elem.getAttributeNode( name );\n\t\t\tif ( !ret ) {\n\t\t\t\telem.setAttributeNode(\n\t\t\t\t\t(ret = elem.ownerDocument.createAttribute( name ))\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tret.value = value += \"\";\n\n\t\t\t// Break association with cloned elements by also using setAttribute (#9646)\n\t\t\tif ( name === \"value\" || value === elem.getAttribute( name ) ) {\n\t\t\t\treturn value;\n\t\t\t}\n\t\t}\n\t};\n\n\t// Some attributes are constructed with empty-string values when not defined\n\tattrHandle.id = attrHandle.name = attrHandle.coords =\n\t\tfunction( elem, name, isXML ) {\n\t\t\tvar ret;\n\t\t\tif ( !isXML ) {\n\t\t\t\treturn (ret = elem.getAttributeNode( name )) && ret.value !== \"\" ?\n\t\t\t\t\tret.value :\n\t\t\t\t\tnull;\n\t\t\t}\n\t\t};\n\n\t// Fixing value retrieval on a button requires this module\n\tjQuery.valHooks.button = {\n\t\tget: function( elem, name ) {\n\t\t\tvar ret = elem.getAttributeNode( name );\n\t\t\tif ( ret && ret.specified ) {\n\t\t\t\treturn ret.value;\n\t\t\t}\n\t\t},\n\t\tset: nodeHook.set\n\t};\n\n\t// Set contenteditable to false on removals(#10429)\n\t// Setting to empty string throws an error as an invalid value\n\tjQuery.attrHooks.contenteditable = {\n\t\tset: function( elem, value, name ) {\n\t\t\tnodeHook.set( elem, value === \"\" ? false : value, name );\n\t\t}\n\t};\n\n\t// Set width and height to auto instead of 0 on empty string( Bug #8150 )\n\t// This is for removals\n\tjQuery.each([ \"width\", \"height\" ], function( i, name ) {\n\t\tjQuery.attrHooks[ name ] = {\n\t\t\tset: function( elem, value ) {\n\t\t\t\tif ( value === \"\" ) {\n\t\t\t\t\telem.setAttribute( name, \"auto\" );\n\t\t\t\t\treturn value;\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\t});\n}\n\nif ( !support.style ) {\n\tjQuery.attrHooks.style = {\n\t\tget: function( elem ) {\n\t\t\t// Return undefined in the case of empty string\n\t\t\t// Note: IE uppercases css property names, but if we were to .toLowerCase()\n\t\t\t// .cssText, that would destroy case senstitivity in URL's, like in \"background\"\n\t\t\treturn elem.style.cssText || undefined;\n\t\t},\n\t\tset: function( elem, value ) {\n\t\t\treturn ( elem.style.cssText = value + \"\" );\n\t\t}\n\t};\n}\n\n\n\n\nvar rfocusable = /^(?:input|select|textarea|button|object)$/i,\n\trclickable = /^(?:a|area)$/i;\n\njQuery.fn.extend({\n\tprop: function( name, value ) {\n\t\treturn access( this, jQuery.prop, name, value, arguments.length > 1 );\n\t},\n\n\tremoveProp: function( name ) {\n\t\tname = jQuery.propFix[ name ] || name;\n\t\treturn this.each(function() {\n\t\t\t// try/catch handles cases where IE balks (such as removing a property on window)\n\t\t\ttry {\n\t\t\t\tthis[ name ] = undefined;\n\t\t\t\tdelete this[ name ];\n\t\t\t} catch( e ) {}\n\t\t});\n\t}\n});\n\njQuery.extend({\n\tpropFix: {\n\t\t\"for\": \"htmlFor\",\n\t\t\"class\": \"className\"\n\t},\n\n\tprop: function( elem, name, value ) {\n\t\tvar ret, hooks, notxml,\n\t\t\tnType = elem.nodeType;\n\n\t\t// don't get/set properties on text, comment and attribute nodes\n\t\tif ( !elem || nType === 3 || nType === 8 || nType === 2 ) {\n\t\t\treturn;\n\t\t}\n\n\t\tnotxml = nType !== 1 || !jQuery.isXMLDoc( elem );\n\n\t\tif ( notxml ) {\n\t\t\t// Fix name and attach hooks\n\t\t\tname = jQuery.propFix[ name ] || name;\n\t\t\thooks = jQuery.propHooks[ name ];\n\t\t}\n\n\t\tif ( value !== undefined ) {\n\t\t\treturn hooks && \"set\" in hooks && (ret = hooks.set( elem, value, name )) !== undefined ?\n\t\t\t\tret :\n\t\t\t\t( elem[ name ] = value );\n\n\t\t} else {\n\t\t\treturn hooks && \"get\" in hooks && (ret = hooks.get( elem, name )) !== null ?\n\t\t\t\tret :\n\t\t\t\telem[ name ];\n\t\t}\n\t},\n\n\tpropHooks: {\n\t\ttabIndex: {\n\t\t\tget: function( elem ) {\n\t\t\t\t// elem.tabIndex doesn't always return the correct value when it hasn't been explicitly set\n\t\t\t\t// http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/\n\t\t\t\t// Use proper attribute retrieval(#12072)\n\t\t\t\tvar tabindex = jQuery.find.attr( elem, \"tabindex\" );\n\n\t\t\t\treturn tabindex ?\n\t\t\t\t\tparseInt( tabindex, 10 ) :\n\t\t\t\t\trfocusable.test( elem.nodeName ) || rclickable.test( elem.nodeName ) && elem.href ?\n\t\t\t\t\t\t0 :\n\t\t\t\t\t\t-1;\n\t\t\t}\n\t\t}\n\t}\n});\n\n// Some attributes require a special call on IE\n// http://msdn.microsoft.com/en-us/library/ms536429%28VS.85%29.aspx\nif ( !support.hrefNormalized ) {\n\t// href/src property should get the full normalized URL (#10299/#12915)\n\tjQuery.each([ \"href\", \"src\" ], function( i, name ) {\n\t\tjQuery.propHooks[ name ] = {\n\t\t\tget: function( elem ) {\n\t\t\t\treturn elem.getAttribute( name, 4 );\n\t\t\t}\n\t\t};\n\t});\n}\n\n// Support: Safari, IE9+\n// mis-reports the default selected property of an option\n// Accessing the parent's selectedIndex property fixes it\nif ( !support.optSelected ) {\n\tjQuery.propHooks.selected = {\n\t\tget: function( elem ) {\n\t\t\tvar parent = elem.parentNode;\n\n\t\t\tif ( parent ) {\n\t\t\t\tparent.selectedIndex;\n\n\t\t\t\t// Make sure that it also works with optgroups, see #5701\n\t\t\t\tif ( parent.parentNode ) {\n\t\t\t\t\tparent.parentNode.selectedIndex;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn null;\n\t\t}\n\t};\n}\n\njQuery.each([\n\t\"tabIndex\",\n\t\"readOnly\",\n\t\"maxLength\",\n\t\"cellSpacing\",\n\t\"cellPadding\",\n\t\"rowSpan\",\n\t\"colSpan\",\n\t\"useMap\",\n\t\"frameBorder\",\n\t\"contentEditable\"\n], function() {\n\tjQuery.propFix[ this.toLowerCase() ] = this;\n});\n\n// IE6/7 call enctype encoding\nif ( !support.enctype ) {\n\tjQuery.propFix.enctype = \"encoding\";\n}\n\n\n\n\nvar rclass = /[\\t\\r\\n\\f]/g;\n\njQuery.fn.extend({\n\taddClass: function( value ) {\n\t\tvar classes, elem, cur, clazz, j, finalValue,\n\t\t\ti = 0,\n\t\t\tlen = this.length,\n\t\t\tproceed = typeof value === \"string\" && value;\n\n\t\tif ( jQuery.isFunction( value ) ) {\n\t\t\treturn this.each(function( j ) {\n\t\t\t\tjQuery( this ).addClass( value.call( this, j, this.className ) );\n\t\t\t});\n\t\t}\n\n\t\tif ( proceed ) {\n\t\t\t// The disjunction here is for better compressibility (see removeClass)\n\t\t\tclasses = ( value || \"\" ).match( rnotwhite ) || [];\n\n\t\t\tfor ( ; i < len; i++ ) {\n\t\t\t\telem = this[ i ];\n\t\t\t\tcur = elem.nodeType === 1 && ( elem.className ?\n\t\t\t\t\t( \" \" + elem.className + \" \" ).replace( rclass, \" \" ) :\n\t\t\t\t\t\" \"\n\t\t\t\t);\n\n\t\t\t\tif ( cur ) {\n\t\t\t\t\tj = 0;\n\t\t\t\t\twhile ( (clazz = classes[j++]) ) {\n\t\t\t\t\t\tif ( cur.indexOf( \" \" + clazz + \" \" ) < 0 ) {\n\t\t\t\t\t\t\tcur += clazz + \" \";\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\t// only assign if different to avoid unneeded rendering.\n\t\t\t\t\tfinalValue = jQuery.trim( cur );\n\t\t\t\t\tif ( elem.className !== finalValue ) {\n\t\t\t\t\t\telem.className = finalValue;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn this;\n\t},\n\n\tremoveClass: function( value ) {\n\t\tvar classes, elem, cur, clazz, j, finalValue,\n\t\t\ti = 0,\n\t\t\tlen = this.length,\n\t\t\tproceed = arguments.length === 0 || typeof value === \"string\" && value;\n\n\t\tif ( jQuery.isFunction( value ) ) {\n\t\t\treturn this.each(function( j ) {\n\t\t\t\tjQuery( this ).removeClass( value.call( this, j, this.className ) );\n\t\t\t});\n\t\t}\n\t\tif ( proceed ) {\n\t\t\tclasses = ( value || \"\" ).match( rnotwhite ) || [];\n\n\t\t\tfor ( ; i < len; i++ ) {\n\t\t\t\telem = this[ i ];\n\t\t\t\t// This expression is here for better compressibility (see addClass)\n\t\t\t\tcur = elem.nodeType === 1 && ( elem.className ?\n\t\t\t\t\t( \" \" + elem.className + \" \" ).replace( rclass, \" \" ) :\n\t\t\t\t\t\"\"\n\t\t\t\t);\n\n\t\t\t\tif ( cur ) {\n\t\t\t\t\tj = 0;\n\t\t\t\t\twhile ( (clazz = classes[j++]) ) {\n\t\t\t\t\t\t// Remove *all* instances\n\t\t\t\t\t\twhile ( cur.indexOf( \" \" + clazz + \" \" ) >= 0 ) {\n\t\t\t\t\t\t\tcur = cur.replace( \" \" + clazz + \" \", \" \" );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\t// only assign if different to avoid unneeded rendering.\n\t\t\t\t\tfinalValue = value ? jQuery.trim( cur ) : \"\";\n\t\t\t\t\tif ( elem.className !== finalValue ) {\n\t\t\t\t\t\telem.className = finalValue;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn this;\n\t},\n\n\ttoggleClass: function( value, stateVal ) {\n\t\tvar type = typeof value;\n\n\t\tif ( typeof stateVal === \"boolean\" && type === \"string\" ) {\n\t\t\treturn stateVal ? this.addClass( value ) : this.removeClass( value );\n\t\t}\n\n\t\tif ( jQuery.isFunction( value ) ) {\n\t\t\treturn this.each(function( i ) {\n\t\t\t\tjQuery( this ).toggleClass( value.call(this, i, this.className, stateVal), stateVal );\n\t\t\t});\n\t\t}\n\n\t\treturn this.each(function() {\n\t\t\tif ( type === \"string\" ) {\n\t\t\t\t// toggle individual class names\n\t\t\t\tvar className,\n\t\t\t\t\ti = 0,\n\t\t\t\t\tself = jQuery( this ),\n\t\t\t\t\tclassNames = value.match( rnotwhite ) || [];\n\n\t\t\t\twhile ( (className = classNames[ i++ ]) ) {\n\t\t\t\t\t// check each className given, space separated list\n\t\t\t\t\tif ( self.hasClass( className ) ) {\n\t\t\t\t\t\tself.removeClass( className );\n\t\t\t\t\t} else {\n\t\t\t\t\t\tself.addClass( className );\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t// Toggle whole class name\n\t\t\t} else if ( type === strundefined || type === \"boolean\" ) {\n\t\t\t\tif ( this.className ) {\n\t\t\t\t\t// store className if set\n\t\t\t\t\tjQuery._data( this, \"__className__\", this.className );\n\t\t\t\t}\n\n\t\t\t\t// If the element has a class name or if we're passed \"false\",\n\t\t\t\t// then remove the whole classname (if there was one, the above saved it).\n\t\t\t\t// Otherwise bring back whatever was previously saved (if anything),\n\t\t\t\t// falling back to the empty string if nothing was stored.\n\t\t\t\tthis.className = this.className || value === false ? \"\" : jQuery._data( this, \"__className__\" ) || \"\";\n\t\t\t}\n\t\t});\n\t},\n\n\thasClass: function( selector ) {\n\t\tvar className = \" \" + selector + \" \",\n\t\t\ti = 0,\n\t\t\tl = this.length;\n\t\tfor ( ; i < l; i++ ) {\n\t\t\tif ( this[i].nodeType === 1 && (\" \" + this[i].className + \" \").replace(rclass, \" \").indexOf( className ) >= 0 ) {\n\t\t\t\treturn true;\n\t\t\t}\n\t\t}\n\n\t\treturn false;\n\t}\n});\n\n\n\n\n// Return jQuery for attributes-only inclusion\n\n\njQuery.each( (\"blur focus focusin focusout load resize scroll unload click dblclick \" +\n\t\"mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave \" +\n\t\"change select submit keydown keypress keyup error contextmenu\").split(\" \"), function( i, name ) {\n\n\t// Handle event binding\n\tjQuery.fn[ name ] = function( data, fn ) {\n\t\treturn arguments.length > 0 ?\n\t\t\tthis.on( name, null, data, fn ) :\n\t\t\tthis.trigger( name );\n\t};\n});\n\njQuery.fn.extend({\n\thover: function( fnOver, fnOut ) {\n\t\treturn this.mouseenter( fnOver ).mouseleave( fnOut || fnOver );\n\t},\n\n\tbind: function( types, data, fn ) {\n\t\treturn this.on( types, null, data, fn );\n\t},\n\tunbind: function( types, fn ) {\n\t\treturn this.off( types, null, fn );\n\t},\n\n\tdelegate: function( selector, types, data, fn ) {\n\t\treturn this.on( types, selector, data, fn );\n\t},\n\tundelegate: function( selector, types, fn ) {\n\t\t// ( namespace ) or ( selector, types [, fn] )\n\t\treturn arguments.length === 1 ? this.off( selector, \"**\" ) : this.off( types, selector || \"**\", fn );\n\t}\n});\n\n\nvar nonce = jQuery.now();\n\nvar rquery = (/\\?/);\n\n\n\nvar rvalidtokens = /(,)|(\\[|{)|(}|])|\"(?:[^\"\\\\\\r\\n]|\\\\[\"\\\\\\/bfnrt]|\\\\u[\\da-fA-F]{4})*\"\\s*:?|true|false|null|-?(?!0\\d)\\d+(?:\\.\\d+|)(?:[eE][+-]?\\d+|)/g;\n\njQuery.parseJSON = function( data ) {\n\t// Attempt to parse using the native JSON parser first\n\tif ( window.JSON && window.JSON.parse ) {\n\t\t// Support: Android 2.3\n\t\t// Workaround failure to string-cast null input\n\t\treturn window.JSON.parse( data + \"\" );\n\t}\n\n\tvar requireNonComma,\n\t\tdepth = null,\n\t\tstr = jQuery.trim( data + \"\" );\n\n\t// Guard against invalid (and possibly dangerous) input by ensuring that nothing remains\n\t// after removing valid tokens\n\treturn str && !jQuery.trim( str.replace( rvalidtokens, function( token, comma, open, close ) {\n\n\t\t// Force termination if we see a misplaced comma\n\t\tif ( requireNonComma && comma ) {\n\t\t\tdepth = 0;\n\t\t}\n\n\t\t// Perform no more replacements after returning to outermost depth\n\t\tif ( depth === 0 ) {\n\t\t\treturn token;\n\t\t}\n\n\t\t// Commas must not follow \"[\", \"{\", or \",\"\n\t\trequireNonComma = open || comma;\n\n\t\t// Determine new depth\n\t\t// array/object open (\"[\" or \"{\"): depth += true - false (increment)\n\t\t// array/object close (\"]\" or \"}\"): depth += false - true (decrement)\n\t\t// other cases (\",\" or primitive): depth += true - true (numeric cast)\n\t\tdepth += !close - !open;\n\n\t\t// Remove this token\n\t\treturn \"\";\n\t}) ) ?\n\t\t( Function( \"return \" + str ) )() :\n\t\tjQuery.error( \"Invalid JSON: \" + data );\n};\n\n\n// Cross-browser xml parsing\njQuery.parseXML = function( data ) {\n\tvar xml, tmp;\n\tif ( !data || typeof data !== \"string\" ) {\n\t\treturn null;\n\t}\n\ttry {\n\t\tif ( window.DOMParser ) { // Standard\n\t\t\ttmp = new DOMParser();\n\t\t\txml = tmp.parseFromString( data, \"text/xml\" );\n\t\t} else { // IE\n\t\t\txml = new ActiveXObject( \"Microsoft.XMLDOM\" );\n\t\t\txml.async = \"false\";\n\t\t\txml.loadXML( data );\n\t\t}\n\t} catch( e ) {\n\t\txml = undefined;\n\t}\n\tif ( !xml || !xml.documentElement || xml.getElementsByTagName( \"parsererror\" ).length ) {\n\t\tjQuery.error( \"Invalid XML: \" + data );\n\t}\n\treturn xml;\n};\n\n\nvar\n\t// Document location\n\tajaxLocParts,\n\tajaxLocation,\n\n\trhash = /#.*$/,\n\trts = /([?&])_=[^&]*/,\n\trheaders = /^(.*?):[ \\t]*([^\\r\\n]*)\\r?$/mg, // IE leaves an \\r character at EOL\n\t// #7653, #8125, #8152: local protocol detection\n\trlocalProtocol = /^(?:about|app|app-storage|.+-extension|file|res|widget):$/,\n\trnoContent = /^(?:GET|HEAD)$/,\n\trprotocol = /^\\/\\//,\n\trurl = /^([\\w.+-]+:)(?:\\/\\/(?:[^\\/?#]*@|)([^\\/?#:]*)(?::(\\d+)|)|)/,\n\n\t/* Prefilters\n\t * 1) They are useful to introduce custom dataTypes (see ajax/jsonp.js for an example)\n\t * 2) These are called:\n\t *    - BEFORE asking for a transport\n\t *    - AFTER param serialization (s.data is a string if s.processData is true)\n\t * 3) key is the dataType\n\t * 4) the catchall symbol \"*\" can be used\n\t * 5) execution will start with transport dataType and THEN continue down to \"*\" if needed\n\t */\n\tprefilters = {},\n\n\t/* Transports bindings\n\t * 1) key is the dataType\n\t * 2) the catchall symbol \"*\" can be used\n\t * 3) selection will start with transport dataType and THEN go to \"*\" if needed\n\t */\n\ttransports = {},\n\n\t// Avoid comment-prolog char sequence (#10098); must appease lint and evade compression\n\tallTypes = \"*/\".concat(\"*\");\n\n// #8138, IE may throw an exception when accessing\n// a field from window.location if document.domain has been set\ntry {\n\tajaxLocation = location.href;\n} catch( e ) {\n\t// Use the href attribute of an A element\n\t// since IE will modify it given document.location\n\tajaxLocation = document.createElement( \"a\" );\n\tajaxLocation.href = \"\";\n\tajaxLocation = ajaxLocation.href;\n}\n\n// Segment location into parts\najaxLocParts = rurl.exec( ajaxLocation.toLowerCase() ) || [];\n\n// Base \"constructor\" for jQuery.ajaxPrefilter and jQuery.ajaxTransport\nfunction addToPrefiltersOrTransports( structure ) {\n\n\t// dataTypeExpression is optional and defaults to \"*\"\n\treturn function( dataTypeExpression, func ) {\n\n\t\tif ( typeof dataTypeExpression !== \"string\" ) {\n\t\t\tfunc = dataTypeExpression;\n\t\t\tdataTypeExpression = \"*\";\n\t\t}\n\n\t\tvar dataType,\n\t\t\ti = 0,\n\t\t\tdataTypes = dataTypeExpression.toLowerCase().match( rnotwhite ) || [];\n\n\t\tif ( jQuery.isFunction( func ) ) {\n\t\t\t// For each dataType in the dataTypeExpression\n\t\t\twhile ( (dataType = dataTypes[i++]) ) {\n\t\t\t\t// Prepend if requested\n\t\t\t\tif ( dataType.charAt( 0 ) === \"+\" ) {\n\t\t\t\t\tdataType = dataType.slice( 1 ) || \"*\";\n\t\t\t\t\t(structure[ dataType ] = structure[ dataType ] || []).unshift( func );\n\n\t\t\t\t// Otherwise append\n\t\t\t\t} else {\n\t\t\t\t\t(structure[ dataType ] = structure[ dataType ] || []).push( func );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t};\n}\n\n// Base inspection function for prefilters and transports\nfunction inspectPrefiltersOrTransports( structure, options, originalOptions, jqXHR ) {\n\n\tvar inspected = {},\n\t\tseekingTransport = ( structure === transports );\n\n\tfunction inspect( dataType ) {\n\t\tvar selected;\n\t\tinspected[ dataType ] = true;\n\t\tjQuery.each( structure[ dataType ] || [], function( _, prefilterOrFactory ) {\n\t\t\tvar dataTypeOrTransport = prefilterOrFactory( options, originalOptions, jqXHR );\n\t\t\tif ( typeof dataTypeOrTransport === \"string\" && !seekingTransport && !inspected[ dataTypeOrTransport ] ) {\n\t\t\t\toptions.dataTypes.unshift( dataTypeOrTransport );\n\t\t\t\tinspect( dataTypeOrTransport );\n\t\t\t\treturn false;\n\t\t\t} else if ( seekingTransport ) {\n\t\t\t\treturn !( selected = dataTypeOrTransport );\n\t\t\t}\n\t\t});\n\t\treturn selected;\n\t}\n\n\treturn inspect( options.dataTypes[ 0 ] ) || !inspected[ \"*\" ] && inspect( \"*\" );\n}\n\n// A special extend for ajax options\n// that takes \"flat\" options (not to be deep extended)\n// Fixes #9887\nfunction ajaxExtend( target, src ) {\n\tvar deep, key,\n\t\tflatOptions = jQuery.ajaxSettings.flatOptions || {};\n\n\tfor ( key in src ) {\n\t\tif ( src[ key ] !== undefined ) {\n\t\t\t( flatOptions[ key ] ? target : ( deep || (deep = {}) ) )[ key ] = src[ key ];\n\t\t}\n\t}\n\tif ( deep ) {\n\t\tjQuery.extend( true, target, deep );\n\t}\n\n\treturn target;\n}\n\n/* Handles responses to an ajax request:\n * - finds the right dataType (mediates between content-type and expected dataType)\n * - returns the corresponding response\n */\nfunction ajaxHandleResponses( s, jqXHR, responses ) {\n\tvar firstDataType, ct, finalDataType, type,\n\t\tcontents = s.contents,\n\t\tdataTypes = s.dataTypes;\n\n\t// Remove auto dataType and get content-type in the process\n\twhile ( dataTypes[ 0 ] === \"*\" ) {\n\t\tdataTypes.shift();\n\t\tif ( ct === undefined ) {\n\t\t\tct = s.mimeType || jqXHR.getResponseHeader(\"Content-Type\");\n\t\t}\n\t}\n\n\t// Check if we're dealing with a known content-type\n\tif ( ct ) {\n\t\tfor ( type in contents ) {\n\t\t\tif ( contents[ type ] && contents[ type ].test( ct ) ) {\n\t\t\t\tdataTypes.unshift( type );\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t}\n\n\t// Check to see if we have a response for the expected dataType\n\tif ( dataTypes[ 0 ] in responses ) {\n\t\tfinalDataType = dataTypes[ 0 ];\n\t} else {\n\t\t// Try convertible dataTypes\n\t\tfor ( type in responses ) {\n\t\t\tif ( !dataTypes[ 0 ] || s.converters[ type + \" \" + dataTypes[0] ] ) {\n\t\t\t\tfinalDataType = type;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tif ( !firstDataType ) {\n\t\t\t\tfirstDataType = type;\n\t\t\t}\n\t\t}\n\t\t// Or just use first one\n\t\tfinalDataType = finalDataType || firstDataType;\n\t}\n\n\t// If we found a dataType\n\t// We add the dataType to the list if needed\n\t// and return the corresponding response\n\tif ( finalDataType ) {\n\t\tif ( finalDataType !== dataTypes[ 0 ] ) {\n\t\t\tdataTypes.unshift( finalDataType );\n\t\t}\n\t\treturn responses[ finalDataType ];\n\t}\n}\n\n/* Chain conversions given the request and the original response\n * Also sets the responseXXX fields on the jqXHR instance\n */\nfunction ajaxConvert( s, response, jqXHR, isSuccess ) {\n\tvar conv2, current, conv, tmp, prev,\n\t\tconverters = {},\n\t\t// Work with a copy of dataTypes in case we need to modify it for conversion\n\t\tdataTypes = s.dataTypes.slice();\n\n\t// Create converters map with lowercased keys\n\tif ( dataTypes[ 1 ] ) {\n\t\tfor ( conv in s.converters ) {\n\t\t\tconverters[ conv.toLowerCase() ] = s.converters[ conv ];\n\t\t}\n\t}\n\n\tcurrent = dataTypes.shift();\n\n\t// Convert to each sequential dataType\n\twhile ( current ) {\n\n\t\tif ( s.responseFields[ current ] ) {\n\t\t\tjqXHR[ s.responseFields[ current ] ] = response;\n\t\t}\n\n\t\t// Apply the dataFilter if provided\n\t\tif ( !prev && isSuccess && s.dataFilter ) {\n\t\t\tresponse = s.dataFilter( response, s.dataType );\n\t\t}\n\n\t\tprev = current;\n\t\tcurrent = dataTypes.shift();\n\n\t\tif ( current ) {\n\n\t\t\t// There's only work to do if current dataType is non-auto\n\t\t\tif ( current === \"*\" ) {\n\n\t\t\t\tcurrent = prev;\n\n\t\t\t// Convert response if prev dataType is non-auto and differs from current\n\t\t\t} else if ( prev !== \"*\" && prev !== current ) {\n\n\t\t\t\t// Seek a direct converter\n\t\t\t\tconv = converters[ prev + \" \" + current ] || converters[ \"* \" + current ];\n\n\t\t\t\t// If none found, seek a pair\n\t\t\t\tif ( !conv ) {\n\t\t\t\t\tfor ( conv2 in converters ) {\n\n\t\t\t\t\t\t// If conv2 outputs current\n\t\t\t\t\t\ttmp = conv2.split( \" \" );\n\t\t\t\t\t\tif ( tmp[ 1 ] === current ) {\n\n\t\t\t\t\t\t\t// If prev can be converted to accepted input\n\t\t\t\t\t\t\tconv = converters[ prev + \" \" + tmp[ 0 ] ] ||\n\t\t\t\t\t\t\t\tconverters[ \"* \" + tmp[ 0 ] ];\n\t\t\t\t\t\t\tif ( conv ) {\n\t\t\t\t\t\t\t\t// Condense equivalence converters\n\t\t\t\t\t\t\t\tif ( conv === true ) {\n\t\t\t\t\t\t\t\t\tconv = converters[ conv2 ];\n\n\t\t\t\t\t\t\t\t// Otherwise, insert the intermediate dataType\n\t\t\t\t\t\t\t\t} else if ( converters[ conv2 ] !== true ) {\n\t\t\t\t\t\t\t\t\tcurrent = tmp[ 0 ];\n\t\t\t\t\t\t\t\t\tdataTypes.unshift( tmp[ 1 ] );\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// Apply converter (if not an equivalence)\n\t\t\t\tif ( conv !== true ) {\n\n\t\t\t\t\t// Unless errors are allowed to bubble, catch and return them\n\t\t\t\t\tif ( conv && s[ \"throws\" ] ) {\n\t\t\t\t\t\tresponse = conv( response );\n\t\t\t\t\t} else {\n\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\tresponse = conv( response );\n\t\t\t\t\t\t} catch ( e ) {\n\t\t\t\t\t\t\treturn { state: \"parsererror\", error: conv ? e : \"No conversion from \" + prev + \" to \" + current };\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\treturn { state: \"success\", data: response };\n}\n\njQuery.extend({\n\n\t// Counter for holding the number of active queries\n\tactive: 0,\n\n\t// Last-Modified header cache for next request\n\tlastModified: {},\n\tetag: {},\n\n\tajaxSettings: {\n\t\turl: ajaxLocation,\n\t\ttype: \"GET\",\n\t\tisLocal: rlocalProtocol.test( ajaxLocParts[ 1 ] ),\n\t\tglobal: true,\n\t\tprocessData: true,\n\t\tasync: true,\n\t\tcontentType: \"application/x-www-form-urlencoded; charset=UTF-8\",\n\t\t/*\n\t\ttimeout: 0,\n\t\tdata: null,\n\t\tdataType: null,\n\t\tusername: null,\n\t\tpassword: null,\n\t\tcache: null,\n\t\tthrows: false,\n\t\ttraditional: false,\n\t\theaders: {},\n\t\t*/\n\n\t\taccepts: {\n\t\t\t\"*\": allTypes,\n\t\t\ttext: \"text/plain\",\n\t\t\thtml: \"text/html\",\n\t\t\txml: \"application/xml, text/xml\",\n\t\t\tjson: \"application/json, text/javascript\"\n\t\t},\n\n\t\tcontents: {\n\t\t\txml: /xml/,\n\t\t\thtml: /html/,\n\t\t\tjson: /json/\n\t\t},\n\n\t\tresponseFields: {\n\t\t\txml: \"responseXML\",\n\t\t\ttext: \"responseText\",\n\t\t\tjson: \"responseJSON\"\n\t\t},\n\n\t\t// Data converters\n\t\t// Keys separate source (or catchall \"*\") and destination types with a single space\n\t\tconverters: {\n\n\t\t\t// Convert anything to text\n\t\t\t\"* text\": String,\n\n\t\t\t// Text to html (true = no transformation)\n\t\t\t\"text html\": true,\n\n\t\t\t// Evaluate text as a json expression\n\t\t\t\"text json\": jQuery.parseJSON,\n\n\t\t\t// Parse text as xml\n\t\t\t\"text xml\": jQuery.parseXML\n\t\t},\n\n\t\t// For options that shouldn't be deep extended:\n\t\t// you can add your own custom options here if\n\t\t// and when you create one that shouldn't be\n\t\t// deep extended (see ajaxExtend)\n\t\tflatOptions: {\n\t\t\turl: true,\n\t\t\tcontext: true\n\t\t}\n\t},\n\n\t// Creates a full fledged settings object into target\n\t// with both ajaxSettings and settings fields.\n\t// If target is omitted, writes into ajaxSettings.\n\tajaxSetup: function( target, settings ) {\n\t\treturn settings ?\n\n\t\t\t// Building a settings object\n\t\t\tajaxExtend( ajaxExtend( target, jQuery.ajaxSettings ), settings ) :\n\n\t\t\t// Extending ajaxSettings\n\t\t\tajaxExtend( jQuery.ajaxSettings, target );\n\t},\n\n\tajaxPrefilter: addToPrefiltersOrTransports( prefilters ),\n\tajaxTransport: addToPrefiltersOrTransports( transports ),\n\n\t// Main method\n\tajax: function( url, options ) {\n\n\t\t// If url is an object, simulate pre-1.5 signature\n\t\tif ( typeof url === \"object\" ) {\n\t\t\toptions = url;\n\t\t\turl = undefined;\n\t\t}\n\n\t\t// Force options to be an object\n\t\toptions = options || {};\n\n\t\tvar // Cross-domain detection vars\n\t\t\tparts,\n\t\t\t// Loop variable\n\t\t\ti,\n\t\t\t// URL without anti-cache param\n\t\t\tcacheURL,\n\t\t\t// Response headers as string\n\t\t\tresponseHeadersString,\n\t\t\t// timeout handle\n\t\t\ttimeoutTimer,\n\n\t\t\t// To know if global events are to be dispatched\n\t\t\tfireGlobals,\n\n\t\t\ttransport,\n\t\t\t// Response headers\n\t\t\tresponseHeaders,\n\t\t\t// Create the final options object\n\t\t\ts = jQuery.ajaxSetup( {}, options ),\n\t\t\t// Callbacks context\n\t\t\tcallbackContext = s.context || s,\n\t\t\t// Context for global events is callbackContext if it is a DOM node or jQuery collection\n\t\t\tglobalEventContext = s.context && ( callbackContext.nodeType || callbackContext.jquery ) ?\n\t\t\t\tjQuery( callbackContext ) :\n\t\t\t\tjQuery.event,\n\t\t\t// Deferreds\n\t\t\tdeferred = jQuery.Deferred(),\n\t\t\tcompleteDeferred = jQuery.Callbacks(\"once memory\"),\n\t\t\t// Status-dependent callbacks\n\t\t\tstatusCode = s.statusCode || {},\n\t\t\t// Headers (they are sent all at once)\n\t\t\trequestHeaders = {},\n\t\t\trequestHeadersNames = {},\n\t\t\t// The jqXHR state\n\t\t\tstate = 0,\n\t\t\t// Default abort message\n\t\t\tstrAbort = \"canceled\",\n\t\t\t// Fake xhr\n\t\t\tjqXHR = {\n\t\t\t\treadyState: 0,\n\n\t\t\t\t// Builds headers hashtable if needed\n\t\t\t\tgetResponseHeader: function( key ) {\n\t\t\t\t\tvar match;\n\t\t\t\t\tif ( state === 2 ) {\n\t\t\t\t\t\tif ( !responseHeaders ) {\n\t\t\t\t\t\t\tresponseHeaders = {};\n\t\t\t\t\t\t\twhile ( (match = rheaders.exec( responseHeadersString )) ) {\n\t\t\t\t\t\t\t\tresponseHeaders[ match[1].toLowerCase() ] = match[ 2 ];\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\tmatch = responseHeaders[ key.toLowerCase() ];\n\t\t\t\t\t}\n\t\t\t\t\treturn match == null ? null : match;\n\t\t\t\t},\n\n\t\t\t\t// Raw string\n\t\t\t\tgetAllResponseHeaders: function() {\n\t\t\t\t\treturn state === 2 ? responseHeadersString : null;\n\t\t\t\t},\n\n\t\t\t\t// Caches the header\n\t\t\t\tsetRequestHeader: function( name, value ) {\n\t\t\t\t\tvar lname = name.toLowerCase();\n\t\t\t\t\tif ( !state ) {\n\t\t\t\t\t\tname = requestHeadersNames[ lname ] = requestHeadersNames[ lname ] || name;\n\t\t\t\t\t\trequestHeaders[ name ] = value;\n\t\t\t\t\t}\n\t\t\t\t\treturn this;\n\t\t\t\t},\n\n\t\t\t\t// Overrides response content-type header\n\t\t\t\toverrideMimeType: function( type ) {\n\t\t\t\t\tif ( !state ) {\n\t\t\t\t\t\ts.mimeType = type;\n\t\t\t\t\t}\n\t\t\t\t\treturn this;\n\t\t\t\t},\n\n\t\t\t\t// Status-dependent callbacks\n\t\t\t\tstatusCode: function( map ) {\n\t\t\t\t\tvar code;\n\t\t\t\t\tif ( map ) {\n\t\t\t\t\t\tif ( state < 2 ) {\n\t\t\t\t\t\t\tfor ( code in map ) {\n\t\t\t\t\t\t\t\t// Lazy-add the new callback in a way that preserves old ones\n\t\t\t\t\t\t\t\tstatusCode[ code ] = [ statusCode[ code ], map[ code ] ];\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t// Execute the appropriate callbacks\n\t\t\t\t\t\t\tjqXHR.always( map[ jqXHR.status ] );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\treturn this;\n\t\t\t\t},\n\n\t\t\t\t// Cancel the request\n\t\t\t\tabort: function( statusText ) {\n\t\t\t\t\tvar finalText = statusText || strAbort;\n\t\t\t\t\tif ( transport ) {\n\t\t\t\t\t\ttransport.abort( finalText );\n\t\t\t\t\t}\n\t\t\t\t\tdone( 0, finalText );\n\t\t\t\t\treturn this;\n\t\t\t\t}\n\t\t\t};\n\n\t\t// Attach deferreds\n\t\tdeferred.promise( jqXHR ).complete = completeDeferred.add;\n\t\tjqXHR.success = jqXHR.done;\n\t\tjqXHR.error = jqXHR.fail;\n\n\t\t// Remove hash character (#7531: and string promotion)\n\t\t// Add protocol if not provided (#5866: IE7 issue with protocol-less urls)\n\t\t// Handle falsy url in the settings object (#10093: consistency with old signature)\n\t\t// We also use the url parameter if available\n\t\ts.url = ( ( url || s.url || ajaxLocation ) + \"\" ).replace( rhash, \"\" ).replace( rprotocol, ajaxLocParts[ 1 ] + \"//\" );\n\n\t\t// Alias method option to type as per ticket #12004\n\t\ts.type = options.method || options.type || s.method || s.type;\n\n\t\t// Extract dataTypes list\n\t\ts.dataTypes = jQuery.trim( s.dataType || \"*\" ).toLowerCase().match( rnotwhite ) || [ \"\" ];\n\n\t\t// A cross-domain request is in order when we have a protocol:host:port mismatch\n\t\tif ( s.crossDomain == null ) {\n\t\t\tparts = rurl.exec( s.url.toLowerCase() );\n\t\t\ts.crossDomain = !!( parts &&\n\t\t\t\t( parts[ 1 ] !== ajaxLocParts[ 1 ] || parts[ 2 ] !== ajaxLocParts[ 2 ] ||\n\t\t\t\t\t( parts[ 3 ] || ( parts[ 1 ] === \"http:\" ? \"80\" : \"443\" ) ) !==\n\t\t\t\t\t\t( ajaxLocParts[ 3 ] || ( ajaxLocParts[ 1 ] === \"http:\" ? \"80\" : \"443\" ) ) )\n\t\t\t);\n\t\t}\n\n\t\t// Convert data if not already a string\n\t\tif ( s.data && s.processData && typeof s.data !== \"string\" ) {\n\t\t\ts.data = jQuery.param( s.data, s.traditional );\n\t\t}\n\n\t\t// Apply prefilters\n\t\tinspectPrefiltersOrTransports( prefilters, s, options, jqXHR );\n\n\t\t// If request was aborted inside a prefilter, stop there\n\t\tif ( state === 2 ) {\n\t\t\treturn jqXHR;\n\t\t}\n\n\t\t// We can fire global events as of now if asked to\n\t\t// Don't fire events if jQuery.event is undefined in an AMD-usage scenario (#15118)\n\t\tfireGlobals = jQuery.event && s.global;\n\n\t\t// Watch for a new set of requests\n\t\tif ( fireGlobals && jQuery.active++ === 0 ) {\n\t\t\tjQuery.event.trigger(\"ajaxStart\");\n\t\t}\n\n\t\t// Uppercase the type\n\t\ts.type = s.type.toUpperCase();\n\n\t\t// Determine if request has content\n\t\ts.hasContent = !rnoContent.test( s.type );\n\n\t\t// Save the URL in case we're toying with the If-Modified-Since\n\t\t// and/or If-None-Match header later on\n\t\tcacheURL = s.url;\n\n\t\t// More options handling for requests with no content\n\t\tif ( !s.hasContent ) {\n\n\t\t\t// If data is available, append data to url\n\t\t\tif ( s.data ) {\n\t\t\t\tcacheURL = ( s.url += ( rquery.test( cacheURL ) ? \"&\" : \"?\" ) + s.data );\n\t\t\t\t// #9682: remove data so that it's not used in an eventual retry\n\t\t\t\tdelete s.data;\n\t\t\t}\n\n\t\t\t// Add anti-cache in url if needed\n\t\t\tif ( s.cache === false ) {\n\t\t\t\ts.url = rts.test( cacheURL ) ?\n\n\t\t\t\t\t// If there is already a '_' parameter, set its value\n\t\t\t\t\tcacheURL.replace( rts, \"$1_=\" + nonce++ ) :\n\n\t\t\t\t\t// Otherwise add one to the end\n\t\t\t\t\tcacheURL + ( rquery.test( cacheURL ) ? \"&\" : \"?\" ) + \"_=\" + nonce++;\n\t\t\t}\n\t\t}\n\n\t\t// Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.\n\t\tif ( s.ifModified ) {\n\t\t\tif ( jQuery.lastModified[ cacheURL ] ) {\n\t\t\t\tjqXHR.setRequestHeader( \"If-Modified-Since\", jQuery.lastModified[ cacheURL ] );\n\t\t\t}\n\t\t\tif ( jQuery.etag[ cacheURL ] ) {\n\t\t\t\tjqXHR.setRequestHeader( \"If-None-Match\", jQuery.etag[ cacheURL ] );\n\t\t\t}\n\t\t}\n\n\t\t// Set the correct header, if data is being sent\n\t\tif ( s.data && s.hasContent && s.contentType !== false || options.contentType ) {\n\t\t\tjqXHR.setRequestHeader( \"Content-Type\", s.contentType );\n\t\t}\n\n\t\t// Set the Accepts header for the server, depending on the dataType\n\t\tjqXHR.setRequestHeader(\n\t\t\t\"Accept\",\n\t\t\ts.dataTypes[ 0 ] && s.accepts[ s.dataTypes[0] ] ?\n\t\t\t\ts.accepts[ s.dataTypes[0] ] + ( s.dataTypes[ 0 ] !== \"*\" ? \", \" + allTypes + \"; q=0.01\" : \"\" ) :\n\t\t\t\ts.accepts[ \"*\" ]\n\t\t);\n\n\t\t// Check for headers option\n\t\tfor ( i in s.headers ) {\n\t\t\tjqXHR.setRequestHeader( i, s.headers[ i ] );\n\t\t}\n\n\t\t// Allow custom headers/mimetypes and early abort\n\t\tif ( s.beforeSend && ( s.beforeSend.call( callbackContext, jqXHR, s ) === false || state === 2 ) ) {\n\t\t\t// Abort if not done already and return\n\t\t\treturn jqXHR.abort();\n\t\t}\n\n\t\t// aborting is no longer a cancellation\n\t\tstrAbort = \"abort\";\n\n\t\t// Install callbacks on deferreds\n\t\tfor ( i in { success: 1, error: 1, complete: 1 } ) {\n\t\t\tjqXHR[ i ]( s[ i ] );\n\t\t}\n\n\t\t// Get transport\n\t\ttransport = inspectPrefiltersOrTransports( transports, s, options, jqXHR );\n\n\t\t// If no transport, we auto-abort\n\t\tif ( !transport ) {\n\t\t\tdone( -1, \"No Transport\" );\n\t\t} else {\n\t\t\tjqXHR.readyState = 1;\n\n\t\t\t// Send global event\n\t\t\tif ( fireGlobals ) {\n\t\t\t\tglobalEventContext.trigger( \"ajaxSend\", [ jqXHR, s ] );\n\t\t\t}\n\t\t\t// Timeout\n\t\t\tif ( s.async && s.timeout > 0 ) {\n\t\t\t\ttimeoutTimer = setTimeout(function() {\n\t\t\t\t\tjqXHR.abort(\"timeout\");\n\t\t\t\t}, s.timeout );\n\t\t\t}\n\n\t\t\ttry {\n\t\t\t\tstate = 1;\n\t\t\t\ttransport.send( requestHeaders, done );\n\t\t\t} catch ( e ) {\n\t\t\t\t// Propagate exception as error if not done\n\t\t\t\tif ( state < 2 ) {\n\t\t\t\t\tdone( -1, e );\n\t\t\t\t// Simply rethrow otherwise\n\t\t\t\t} else {\n\t\t\t\t\tthrow e;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Callback for when everything is done\n\t\tfunction done( status, nativeStatusText, responses, headers ) {\n\t\t\tvar isSuccess, success, error, response, modified,\n\t\t\t\tstatusText = nativeStatusText;\n\n\t\t\t// Called once\n\t\t\tif ( state === 2 ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// State is \"done\" now\n\t\t\tstate = 2;\n\n\t\t\t// Clear timeout if it exists\n\t\t\tif ( timeoutTimer ) {\n\t\t\t\tclearTimeout( timeoutTimer );\n\t\t\t}\n\n\t\t\t// Dereference transport for early garbage collection\n\t\t\t// (no matter how long the jqXHR object will be used)\n\t\t\ttransport = undefined;\n\n\t\t\t// Cache response headers\n\t\t\tresponseHeadersString = headers || \"\";\n\n\t\t\t// Set readyState\n\t\t\tjqXHR.readyState = status > 0 ? 4 : 0;\n\n\t\t\t// Determine if successful\n\t\t\tisSuccess = status >= 200 && status < 300 || status === 304;\n\n\t\t\t// Get response data\n\t\t\tif ( responses ) {\n\t\t\t\tresponse = ajaxHandleResponses( s, jqXHR, responses );\n\t\t\t}\n\n\t\t\t// Convert no matter what (that way responseXXX fields are always set)\n\t\t\tresponse = ajaxConvert( s, response, jqXHR, isSuccess );\n\n\t\t\t// If successful, handle type chaining\n\t\t\tif ( isSuccess ) {\n\n\t\t\t\t// Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.\n\t\t\t\tif ( s.ifModified ) {\n\t\t\t\t\tmodified = jqXHR.getResponseHeader(\"Last-Modified\");\n\t\t\t\t\tif ( modified ) {\n\t\t\t\t\t\tjQuery.lastModified[ cacheURL ] = modified;\n\t\t\t\t\t}\n\t\t\t\t\tmodified = jqXHR.getResponseHeader(\"etag\");\n\t\t\t\t\tif ( modified ) {\n\t\t\t\t\t\tjQuery.etag[ cacheURL ] = modified;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// if no content\n\t\t\t\tif ( status === 204 || s.type === \"HEAD\" ) {\n\t\t\t\t\tstatusText = \"nocontent\";\n\n\t\t\t\t// if not modified\n\t\t\t\t} else if ( status === 304 ) {\n\t\t\t\t\tstatusText = \"notmodified\";\n\n\t\t\t\t// If we have data, let's convert it\n\t\t\t\t} else {\n\t\t\t\t\tstatusText = response.state;\n\t\t\t\t\tsuccess = response.data;\n\t\t\t\t\terror = response.error;\n\t\t\t\t\tisSuccess = !error;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t// We extract error from statusText\n\t\t\t\t// then normalize statusText and status for non-aborts\n\t\t\t\terror = statusText;\n\t\t\t\tif ( status || !statusText ) {\n\t\t\t\t\tstatusText = \"error\";\n\t\t\t\t\tif ( status < 0 ) {\n\t\t\t\t\t\tstatus = 0;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Set data for the fake xhr object\n\t\t\tjqXHR.status = status;\n\t\t\tjqXHR.statusText = ( nativeStatusText || statusText ) + \"\";\n\n\t\t\t// Success/Error\n\t\t\tif ( isSuccess ) {\n\t\t\t\tdeferred.resolveWith( callbackContext, [ success, statusText, jqXHR ] );\n\t\t\t} else {\n\t\t\t\tdeferred.rejectWith( callbackContext, [ jqXHR, statusText, error ] );\n\t\t\t}\n\n\t\t\t// Status-dependent callbacks\n\t\t\tjqXHR.statusCode( statusCode );\n\t\t\tstatusCode = undefined;\n\n\t\t\tif ( fireGlobals ) {\n\t\t\t\tglobalEventContext.trigger( isSuccess ? \"ajaxSuccess\" : \"ajaxError\",\n\t\t\t\t\t[ jqXHR, s, isSuccess ? success : error ] );\n\t\t\t}\n\n\t\t\t// Complete\n\t\t\tcompleteDeferred.fireWith( callbackContext, [ jqXHR, statusText ] );\n\n\t\t\tif ( fireGlobals ) {\n\t\t\t\tglobalEventContext.trigger( \"ajaxComplete\", [ jqXHR, s ] );\n\t\t\t\t// Handle the global AJAX counter\n\t\t\t\tif ( !( --jQuery.active ) ) {\n\t\t\t\t\tjQuery.event.trigger(\"ajaxStop\");\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn jqXHR;\n\t},\n\n\tgetJSON: function( url, data, callback ) {\n\t\treturn jQuery.get( url, data, callback, \"json\" );\n\t},\n\n\tgetScript: function( url, callback ) {\n\t\treturn jQuery.get( url, undefined, callback, \"script\" );\n\t}\n});\n\njQuery.each( [ \"get\", \"post\" ], function( i, method ) {\n\tjQuery[ method ] = function( url, data, callback, type ) {\n\t\t// shift arguments if data argument was omitted\n\t\tif ( jQuery.isFunction( data ) ) {\n\t\t\ttype = type || callback;\n\t\t\tcallback = data;\n\t\t\tdata = undefined;\n\t\t}\n\n\t\treturn jQuery.ajax({\n\t\t\turl: url,\n\t\t\ttype: method,\n\t\t\tdataType: type,\n\t\t\tdata: data,\n\t\t\tsuccess: callback\n\t\t});\n\t};\n});\n\n\njQuery._evalUrl = function( url ) {\n\treturn jQuery.ajax({\n\t\turl: url,\n\t\ttype: \"GET\",\n\t\tdataType: \"script\",\n\t\tasync: false,\n\t\tglobal: false,\n\t\t\"throws\": true\n\t});\n};\n\n\njQuery.fn.extend({\n\twrapAll: function( html ) {\n\t\tif ( jQuery.isFunction( html ) ) {\n\t\t\treturn this.each(function(i) {\n\t\t\t\tjQuery(this).wrapAll( html.call(this, i) );\n\t\t\t});\n\t\t}\n\n\t\tif ( this[0] ) {\n\t\t\t// The elements to wrap the target around\n\t\t\tvar wrap = jQuery( html, this[0].ownerDocument ).eq(0).clone(true);\n\n\t\t\tif ( this[0].parentNode ) {\n\t\t\t\twrap.insertBefore( this[0] );\n\t\t\t}\n\n\t\t\twrap.map(function() {\n\t\t\t\tvar elem = this;\n\n\t\t\t\twhile ( elem.firstChild && elem.firstChild.nodeType === 1 ) {\n\t\t\t\t\telem = elem.firstChild;\n\t\t\t\t}\n\n\t\t\t\treturn elem;\n\t\t\t}).append( this );\n\t\t}\n\n\t\treturn this;\n\t},\n\n\twrapInner: function( html ) {\n\t\tif ( jQuery.isFunction( html ) ) {\n\t\t\treturn this.each(function(i) {\n\t\t\t\tjQuery(this).wrapInner( html.call(this, i) );\n\t\t\t});\n\t\t}\n\n\t\treturn this.each(function() {\n\t\t\tvar self = jQuery( this ),\n\t\t\t\tcontents = self.contents();\n\n\t\t\tif ( contents.length ) {\n\t\t\t\tcontents.wrapAll( html );\n\n\t\t\t} else {\n\t\t\t\tself.append( html );\n\t\t\t}\n\t\t});\n\t},\n\n\twrap: function( html ) {\n\t\tvar isFunction = jQuery.isFunction( html );\n\n\t\treturn this.each(function(i) {\n\t\t\tjQuery( this ).wrapAll( isFunction ? html.call(this, i) : html );\n\t\t});\n\t},\n\n\tunwrap: function() {\n\t\treturn this.parent().each(function() {\n\t\t\tif ( !jQuery.nodeName( this, \"body\" ) ) {\n\t\t\t\tjQuery( this ).replaceWith( this.childNodes );\n\t\t\t}\n\t\t}).end();\n\t}\n});\n\n\njQuery.expr.filters.hidden = function( elem ) {\n\t// Support: Opera <= 12.12\n\t// Opera reports offsetWidths and offsetHeights less than zero on some elements\n\treturn elem.offsetWidth <= 0 && elem.offsetHeight <= 0 ||\n\t\t(!support.reliableHiddenOffsets() &&\n\t\t\t((elem.style && elem.style.display) || jQuery.css( elem, \"display\" )) === \"none\");\n};\n\njQuery.expr.filters.visible = function( elem ) {\n\treturn !jQuery.expr.filters.hidden( elem );\n};\n\n\n\n\nvar r20 = /%20/g,\n\trbracket = /\\[\\]$/,\n\trCRLF = /\\r?\\n/g,\n\trsubmitterTypes = /^(?:submit|button|image|reset|file)$/i,\n\trsubmittable = /^(?:input|select|textarea|keygen)/i;\n\nfunction buildParams( prefix, obj, traditional, add ) {\n\tvar name;\n\n\tif ( jQuery.isArray( obj ) ) {\n\t\t// Serialize array item.\n\t\tjQuery.each( obj, function( i, v ) {\n\t\t\tif ( traditional || rbracket.test( prefix ) ) {\n\t\t\t\t// Treat each array item as a scalar.\n\t\t\t\tadd( prefix, v );\n\n\t\t\t} else {\n\t\t\t\t// Item is non-scalar (array or object), encode its numeric index.\n\t\t\t\tbuildParams( prefix + \"[\" + ( typeof v === \"object\" ? i : \"\" ) + \"]\", v, traditional, add );\n\t\t\t}\n\t\t});\n\n\t} else if ( !traditional && jQuery.type( obj ) === \"object\" ) {\n\t\t// Serialize object item.\n\t\tfor ( name in obj ) {\n\t\t\tbuildParams( prefix + \"[\" + name + \"]\", obj[ name ], traditional, add );\n\t\t}\n\n\t} else {\n\t\t// Serialize scalar item.\n\t\tadd( prefix, obj );\n\t}\n}\n\n// Serialize an array of form elements or a set of\n// key/values into a query string\njQuery.param = function( a, traditional ) {\n\tvar prefix,\n\t\ts = [],\n\t\tadd = function( key, value ) {\n\t\t\t// If value is a function, invoke it and return its value\n\t\t\tvalue = jQuery.isFunction( value ) ? value() : ( value == null ? \"\" : value );\n\t\t\ts[ s.length ] = encodeURIComponent( key ) + \"=\" + encodeURIComponent( value );\n\t\t};\n\n\t// Set traditional to true for jQuery <= 1.3.2 behavior.\n\tif ( traditional === undefined ) {\n\t\ttraditional = jQuery.ajaxSettings && jQuery.ajaxSettings.traditional;\n\t}\n\n\t// If an array was passed in, assume that it is an array of form elements.\n\tif ( jQuery.isArray( a ) || ( a.jquery && !jQuery.isPlainObject( a ) ) ) {\n\t\t// Serialize the form elements\n\t\tjQuery.each( a, function() {\n\t\t\tadd( this.name, this.value );\n\t\t});\n\n\t} else {\n\t\t// If traditional, encode the \"old\" way (the way 1.3.2 or older\n\t\t// did it), otherwise encode params recursively.\n\t\tfor ( prefix in a ) {\n\t\t\tbuildParams( prefix, a[ prefix ], traditional, add );\n\t\t}\n\t}\n\n\t// Return the resulting serialization\n\treturn s.join( \"&\" ).replace( r20, \"+\" );\n};\n\njQuery.fn.extend({\n\tserialize: function() {\n\t\treturn jQuery.param( this.serializeArray() );\n\t},\n\tserializeArray: function() {\n\t\treturn this.map(function() {\n\t\t\t// Can add propHook for \"elements\" to filter or add form elements\n\t\t\tvar elements = jQuery.prop( this, \"elements\" );\n\t\t\treturn elements ? jQuery.makeArray( elements ) : this;\n\t\t})\n\t\t.filter(function() {\n\t\t\tvar type = this.type;\n\t\t\t// Use .is(\":disabled\") so that fieldset[disabled] works\n\t\t\treturn this.name && !jQuery( this ).is( \":disabled\" ) &&\n\t\t\t\trsubmittable.test( this.nodeName ) && !rsubmitterTypes.test( type ) &&\n\t\t\t\t( this.checked || !rcheckableType.test( type ) );\n\t\t})\n\t\t.map(function( i, elem ) {\n\t\t\tvar val = jQuery( this ).val();\n\n\t\t\treturn val == null ?\n\t\t\t\tnull :\n\t\t\t\tjQuery.isArray( val ) ?\n\t\t\t\t\tjQuery.map( val, function( val ) {\n\t\t\t\t\t\treturn { name: elem.name, value: val.replace( rCRLF, \"\\r\\n\" ) };\n\t\t\t\t\t}) :\n\t\t\t\t\t{ name: elem.name, value: val.replace( rCRLF, \"\\r\\n\" ) };\n\t\t}).get();\n\t}\n});\n\n\n// Create the request object\n// (This is still attached to ajaxSettings for backward compatibility)\njQuery.ajaxSettings.xhr = window.ActiveXObject !== undefined ?\n\t// Support: IE6+\n\tfunction() {\n\n\t\t// XHR cannot access local files, always use ActiveX for that case\n\t\treturn !this.isLocal &&\n\n\t\t\t// Support: IE7-8\n\t\t\t// oldIE XHR does not support non-RFC2616 methods (#13240)\n\t\t\t// See http://msdn.microsoft.com/en-us/library/ie/ms536648(v=vs.85).aspx\n\t\t\t// and http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html#sec9\n\t\t\t// Although this check for six methods instead of eight\n\t\t\t// since IE also does not support \"trace\" and \"connect\"\n\t\t\t/^(get|post|head|put|delete|options)$/i.test( this.type ) &&\n\n\t\t\tcreateStandardXHR() || createActiveXHR();\n\t} :\n\t// For all other browsers, use the standard XMLHttpRequest object\n\tcreateStandardXHR;\n\nvar xhrId = 0,\n\txhrCallbacks = {},\n\txhrSupported = jQuery.ajaxSettings.xhr();\n\n// Support: IE<10\n// Open requests must be manually aborted on unload (#5280)\n// See https://support.microsoft.com/kb/2856746 for more info\nif ( window.attachEvent ) {\n\twindow.attachEvent( \"onunload\", function() {\n\t\tfor ( var key in xhrCallbacks ) {\n\t\t\txhrCallbacks[ key ]( undefined, true );\n\t\t}\n\t});\n}\n\n// Determine support properties\nsupport.cors = !!xhrSupported && ( \"withCredentials\" in xhrSupported );\nxhrSupported = support.ajax = !!xhrSupported;\n\n// Create transport if the browser can provide an xhr\nif ( xhrSupported ) {\n\n\tjQuery.ajaxTransport(function( options ) {\n\t\t// Cross domain only allowed if supported through XMLHttpRequest\n\t\tif ( !options.crossDomain || support.cors ) {\n\n\t\t\tvar callback;\n\n\t\t\treturn {\n\t\t\t\tsend: function( headers, complete ) {\n\t\t\t\t\tvar i,\n\t\t\t\t\t\txhr = options.xhr(),\n\t\t\t\t\t\tid = ++xhrId;\n\n\t\t\t\t\t// Open the socket\n\t\t\t\t\txhr.open( options.type, options.url, options.async, options.username, options.password );\n\n\t\t\t\t\t// Apply custom fields if provided\n\t\t\t\t\tif ( options.xhrFields ) {\n\t\t\t\t\t\tfor ( i in options.xhrFields ) {\n\t\t\t\t\t\t\txhr[ i ] = options.xhrFields[ i ];\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\t// Override mime type if needed\n\t\t\t\t\tif ( options.mimeType && xhr.overrideMimeType ) {\n\t\t\t\t\t\txhr.overrideMimeType( options.mimeType );\n\t\t\t\t\t}\n\n\t\t\t\t\t// X-Requested-With header\n\t\t\t\t\t// For cross-domain requests, seeing as conditions for a preflight are\n\t\t\t\t\t// akin to a jigsaw puzzle, we simply never set it to be sure.\n\t\t\t\t\t// (it can always be set on a per-request basis or even using ajaxSetup)\n\t\t\t\t\t// For same-domain requests, won't change header if already provided.\n\t\t\t\t\tif ( !options.crossDomain && !headers[\"X-Requested-With\"] ) {\n\t\t\t\t\t\theaders[\"X-Requested-With\"] = \"XMLHttpRequest\";\n\t\t\t\t\t}\n\n\t\t\t\t\t// Set headers\n\t\t\t\t\tfor ( i in headers ) {\n\t\t\t\t\t\t// Support: IE<9\n\t\t\t\t\t\t// IE's ActiveXObject throws a 'Type Mismatch' exception when setting\n\t\t\t\t\t\t// request header to a null-value.\n\t\t\t\t\t\t//\n\t\t\t\t\t\t// To keep consistent with other XHR implementations, cast the value\n\t\t\t\t\t\t// to string and ignore `undefined`.\n\t\t\t\t\t\tif ( headers[ i ] !== undefined ) {\n\t\t\t\t\t\t\txhr.setRequestHeader( i, headers[ i ] + \"\" );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\t// Do send the request\n\t\t\t\t\t// This may raise an exception which is actually\n\t\t\t\t\t// handled in jQuery.ajax (so no try/catch here)\n\t\t\t\t\txhr.send( ( options.hasContent && options.data ) || null );\n\n\t\t\t\t\t// Listener\n\t\t\t\t\tcallback = function( _, isAbort ) {\n\t\t\t\t\t\tvar status, statusText, responses;\n\n\t\t\t\t\t\t// Was never called and is aborted or complete\n\t\t\t\t\t\tif ( callback && ( isAbort || xhr.readyState === 4 ) ) {\n\t\t\t\t\t\t\t// Clean up\n\t\t\t\t\t\t\tdelete xhrCallbacks[ id ];\n\t\t\t\t\t\t\tcallback = undefined;\n\t\t\t\t\t\t\txhr.onreadystatechange = jQuery.noop;\n\n\t\t\t\t\t\t\t// Abort manually if needed\n\t\t\t\t\t\t\tif ( isAbort ) {\n\t\t\t\t\t\t\t\tif ( xhr.readyState !== 4 ) {\n\t\t\t\t\t\t\t\t\txhr.abort();\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tresponses = {};\n\t\t\t\t\t\t\t\tstatus = xhr.status;\n\n\t\t\t\t\t\t\t\t// Support: IE<10\n\t\t\t\t\t\t\t\t// Accessing binary-data responseText throws an exception\n\t\t\t\t\t\t\t\t// (#11426)\n\t\t\t\t\t\t\t\tif ( typeof xhr.responseText === \"string\" ) {\n\t\t\t\t\t\t\t\t\tresponses.text = xhr.responseText;\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t// Firefox throws an exception when accessing\n\t\t\t\t\t\t\t\t// statusText for faulty cross-domain requests\n\t\t\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t\t\tstatusText = xhr.statusText;\n\t\t\t\t\t\t\t\t} catch( e ) {\n\t\t\t\t\t\t\t\t\t// We normalize with Webkit giving an empty statusText\n\t\t\t\t\t\t\t\t\tstatusText = \"\";\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t// Filter status for non standard behaviors\n\n\t\t\t\t\t\t\t\t// If the request is local and we have data: assume a success\n\t\t\t\t\t\t\t\t// (success with no data won't get notified, that's the best we\n\t\t\t\t\t\t\t\t// can do given current implementations)\n\t\t\t\t\t\t\t\tif ( !status && options.isLocal && !options.crossDomain ) {\n\t\t\t\t\t\t\t\t\tstatus = responses.text ? 200 : 404;\n\t\t\t\t\t\t\t\t// IE - #1450: sometimes returns 1223 when it should be 204\n\t\t\t\t\t\t\t\t} else if ( status === 1223 ) {\n\t\t\t\t\t\t\t\t\tstatus = 204;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// Call complete if needed\n\t\t\t\t\t\tif ( responses ) {\n\t\t\t\t\t\t\tcomplete( status, statusText, responses, xhr.getAllResponseHeaders() );\n\t\t\t\t\t\t}\n\t\t\t\t\t};\n\n\t\t\t\t\tif ( !options.async ) {\n\t\t\t\t\t\t// if we're in sync mode we fire the callback\n\t\t\t\t\t\tcallback();\n\t\t\t\t\t} else if ( xhr.readyState === 4 ) {\n\t\t\t\t\t\t// (IE6 & IE7) if it's in cache and has been\n\t\t\t\t\t\t// retrieved directly we need to fire the callback\n\t\t\t\t\t\tsetTimeout( callback );\n\t\t\t\t\t} else {\n\t\t\t\t\t\t// Add to the list of active xhr callbacks\n\t\t\t\t\t\txhr.onreadystatechange = xhrCallbacks[ id ] = callback;\n\t\t\t\t\t}\n\t\t\t\t},\n\n\t\t\t\tabort: function() {\n\t\t\t\t\tif ( callback ) {\n\t\t\t\t\t\tcallback( undefined, true );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t};\n\t\t}\n\t});\n}\n\n// Functions to create xhrs\nfunction createStandardXHR() {\n\ttry {\n\t\treturn new window.XMLHttpRequest();\n\t} catch( e ) {}\n}\n\nfunction createActiveXHR() {\n\ttry {\n\t\treturn new window.ActiveXObject( \"Microsoft.XMLHTTP\" );\n\t} catch( e ) {}\n}\n\n\n\n\n// Install script dataType\njQuery.ajaxSetup({\n\taccepts: {\n\t\tscript: \"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript\"\n\t},\n\tcontents: {\n\t\tscript: /(?:java|ecma)script/\n\t},\n\tconverters: {\n\t\t\"text script\": function( text ) {\n\t\t\tjQuery.globalEval( text );\n\t\t\treturn text;\n\t\t}\n\t}\n});\n\n// Handle cache's special case and global\njQuery.ajaxPrefilter( \"script\", function( s ) {\n\tif ( s.cache === undefined ) {\n\t\ts.cache = false;\n\t}\n\tif ( s.crossDomain ) {\n\t\ts.type = \"GET\";\n\t\ts.global = false;\n\t}\n});\n\n// Bind script tag hack transport\njQuery.ajaxTransport( \"script\", function(s) {\n\n\t// This transport only deals with cross domain requests\n\tif ( s.crossDomain ) {\n\n\t\tvar script,\n\t\t\thead = document.head || jQuery(\"head\")[0] || document.documentElement;\n\n\t\treturn {\n\n\t\t\tsend: function( _, callback ) {\n\n\t\t\t\tscript = document.createElement(\"script\");\n\n\t\t\t\tscript.async = true;\n\n\t\t\t\tif ( s.scriptCharset ) {\n\t\t\t\t\tscript.charset = s.scriptCharset;\n\t\t\t\t}\n\n\t\t\t\tscript.src = s.url;\n\n\t\t\t\t// Attach handlers for all browsers\n\t\t\t\tscript.onload = script.onreadystatechange = function( _, isAbort ) {\n\n\t\t\t\t\tif ( isAbort || !script.readyState || /loaded|complete/.test( script.readyState ) ) {\n\n\t\t\t\t\t\t// Handle memory leak in IE\n\t\t\t\t\t\tscript.onload = script.onreadystatechange = null;\n\n\t\t\t\t\t\t// Remove the script\n\t\t\t\t\t\tif ( script.parentNode ) {\n\t\t\t\t\t\t\tscript.parentNode.removeChild( script );\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// Dereference the script\n\t\t\t\t\t\tscript = null;\n\n\t\t\t\t\t\t// Callback if not abort\n\t\t\t\t\t\tif ( !isAbort ) {\n\t\t\t\t\t\t\tcallback( 200, \"success\" );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t};\n\n\t\t\t\t// Circumvent IE6 bugs with base elements (#2709 and #4378) by prepending\n\t\t\t\t// Use native DOM manipulation to avoid our domManip AJAX trickery\n\t\t\t\thead.insertBefore( script, head.firstChild );\n\t\t\t},\n\n\t\t\tabort: function() {\n\t\t\t\tif ( script ) {\n\t\t\t\t\tscript.onload( undefined, true );\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\t}\n});\n\n\n\n\nvar oldCallbacks = [],\n\trjsonp = /(=)\\?(?=&|$)|\\?\\?/;\n\n// Default jsonp settings\njQuery.ajaxSetup({\n\tjsonp: \"callback\",\n\tjsonpCallback: function() {\n\t\tvar callback = oldCallbacks.pop() || ( jQuery.expando + \"_\" + ( nonce++ ) );\n\t\tthis[ callback ] = true;\n\t\treturn callback;\n\t}\n});\n\n// Detect, normalize options and install callbacks for jsonp requests\njQuery.ajaxPrefilter( \"json jsonp\", function( s, originalSettings, jqXHR ) {\n\n\tvar callbackName, overwritten, responseContainer,\n\t\tjsonProp = s.jsonp !== false && ( rjsonp.test( s.url ) ?\n\t\t\t\"url\" :\n\t\t\ttypeof s.data === \"string\" && !( s.contentType || \"\" ).indexOf(\"application/x-www-form-urlencoded\") && rjsonp.test( s.data ) && \"data\"\n\t\t);\n\n\t// Handle iff the expected data type is \"jsonp\" or we have a parameter to set\n\tif ( jsonProp || s.dataTypes[ 0 ] === \"jsonp\" ) {\n\n\t\t// Get callback name, remembering preexisting value associated with it\n\t\tcallbackName = s.jsonpCallback = jQuery.isFunction( s.jsonpCallback ) ?\n\t\t\ts.jsonpCallback() :\n\t\t\ts.jsonpCallback;\n\n\t\t// Insert callback into url or form data\n\t\tif ( jsonProp ) {\n\t\t\ts[ jsonProp ] = s[ jsonProp ].replace( rjsonp, \"$1\" + callbackName );\n\t\t} else if ( s.jsonp !== false ) {\n\t\t\ts.url += ( rquery.test( s.url ) ? \"&\" : \"?\" ) + s.jsonp + \"=\" + callbackName;\n\t\t}\n\n\t\t// Use data converter to retrieve json after script execution\n\t\ts.converters[\"script json\"] = function() {\n\t\t\tif ( !responseContainer ) {\n\t\t\t\tjQuery.error( callbackName + \" was not called\" );\n\t\t\t}\n\t\t\treturn responseContainer[ 0 ];\n\t\t};\n\n\t\t// force json dataType\n\t\ts.dataTypes[ 0 ] = \"json\";\n\n\t\t// Install callback\n\t\toverwritten = window[ callbackName ];\n\t\twindow[ callbackName ] = function() {\n\t\t\tresponseContainer = arguments;\n\t\t};\n\n\t\t// Clean-up function (fires after converters)\n\t\tjqXHR.always(function() {\n\t\t\t// Restore preexisting value\n\t\t\twindow[ callbackName ] = overwritten;\n\n\t\t\t// Save back as free\n\t\t\tif ( s[ callbackName ] ) {\n\t\t\t\t// make sure that re-using the options doesn't screw things around\n\t\t\t\ts.jsonpCallback = originalSettings.jsonpCallback;\n\n\t\t\t\t// save the callback name for future use\n\t\t\t\toldCallbacks.push( callbackName );\n\t\t\t}\n\n\t\t\t// Call if it was a function and we have a response\n\t\t\tif ( responseContainer && jQuery.isFunction( overwritten ) ) {\n\t\t\t\toverwritten( responseContainer[ 0 ] );\n\t\t\t}\n\n\t\t\tresponseContainer = overwritten = undefined;\n\t\t});\n\n\t\t// Delegate to script\n\t\treturn \"script\";\n\t}\n});\n\n\n\n\n// data: string of html\n// context (optional): If specified, the fragment will be created in this context, defaults to document\n// keepScripts (optional): If true, will include scripts passed in the html string\njQuery.parseHTML = function( data, context, keepScripts ) {\n\tif ( !data || typeof data !== \"string\" ) {\n\t\treturn null;\n\t}\n\tif ( typeof context === \"boolean\" ) {\n\t\tkeepScripts = context;\n\t\tcontext = false;\n\t}\n\tcontext = context || document;\n\n\tvar parsed = rsingleTag.exec( data ),\n\t\tscripts = !keepScripts && [];\n\n\t// Single tag\n\tif ( parsed ) {\n\t\treturn [ context.createElement( parsed[1] ) ];\n\t}\n\n\tparsed = jQuery.buildFragment( [ data ], context, scripts );\n\n\tif ( scripts && scripts.length ) {\n\t\tjQuery( scripts ).remove();\n\t}\n\n\treturn jQuery.merge( [], parsed.childNodes );\n};\n\n\n// Keep a copy of the old load method\nvar _load = jQuery.fn.load;\n\n/**\n * Load a url into a page\n */\njQuery.fn.load = function( url, params, callback ) {\n\tif ( typeof url !== \"string\" && _load ) {\n\t\treturn _load.apply( this, arguments );\n\t}\n\n\tvar selector, response, type,\n\t\tself = this,\n\t\toff = url.indexOf(\" \");\n\n\tif ( off >= 0 ) {\n\t\tselector = jQuery.trim( url.slice( off, url.length ) );\n\t\turl = url.slice( 0, off );\n\t}\n\n\t// If it's a function\n\tif ( jQuery.isFunction( params ) ) {\n\n\t\t// We assume that it's the callback\n\t\tcallback = params;\n\t\tparams = undefined;\n\n\t// Otherwise, build a param string\n\t} else if ( params && typeof params === \"object\" ) {\n\t\ttype = \"POST\";\n\t}\n\n\t// If we have elements to modify, make the request\n\tif ( self.length > 0 ) {\n\t\tjQuery.ajax({\n\t\t\turl: url,\n\n\t\t\t// if \"type\" variable is undefined, then \"GET\" method will be used\n\t\t\ttype: type,\n\t\t\tdataType: \"html\",\n\t\t\tdata: params\n\t\t}).done(function( responseText ) {\n\n\t\t\t// Save response for use in complete callback\n\t\t\tresponse = arguments;\n\n\t\t\tself.html( selector ?\n\n\t\t\t\t// If a selector was specified, locate the right elements in a dummy div\n\t\t\t\t// Exclude scripts to avoid IE 'Permission Denied' errors\n\t\t\t\tjQuery(\"<div>\").append( jQuery.parseHTML( responseText ) ).find( selector ) :\n\n\t\t\t\t// Otherwise use the full result\n\t\t\t\tresponseText );\n\n\t\t}).complete( callback && function( jqXHR, status ) {\n\t\t\tself.each( callback, response || [ jqXHR.responseText, status, jqXHR ] );\n\t\t});\n\t}\n\n\treturn this;\n};\n\n\n\n\n// Attach a bunch of functions for handling common AJAX events\njQuery.each( [ \"ajaxStart\", \"ajaxStop\", \"ajaxComplete\", \"ajaxError\", \"ajaxSuccess\", \"ajaxSend\" ], function( i, type ) {\n\tjQuery.fn[ type ] = function( fn ) {\n\t\treturn this.on( type, fn );\n\t};\n});\n\n\n\n\njQuery.expr.filters.animated = function( elem ) {\n\treturn jQuery.grep(jQuery.timers, function( fn ) {\n\t\treturn elem === fn.elem;\n\t}).length;\n};\n\n\n\n\n\nvar docElem = window.document.documentElement;\n\n/**\n * Gets a window from an element\n */\nfunction getWindow( elem ) {\n\treturn jQuery.isWindow( elem ) ?\n\t\telem :\n\t\telem.nodeType === 9 ?\n\t\t\telem.defaultView || elem.parentWindow :\n\t\t\tfalse;\n}\n\njQuery.offset = {\n\tsetOffset: function( elem, options, i ) {\n\t\tvar curPosition, curLeft, curCSSTop, curTop, curOffset, curCSSLeft, calculatePosition,\n\t\t\tposition = jQuery.css( elem, \"position\" ),\n\t\t\tcurElem = jQuery( elem ),\n\t\t\tprops = {};\n\n\t\t// set position first, in-case top/left are set even on static elem\n\t\tif ( position === \"static\" ) {\n\t\t\telem.style.position = \"relative\";\n\t\t}\n\n\t\tcurOffset = curElem.offset();\n\t\tcurCSSTop = jQuery.css( elem, \"top\" );\n\t\tcurCSSLeft = jQuery.css( elem, \"left\" );\n\t\tcalculatePosition = ( position === \"absolute\" || position === \"fixed\" ) &&\n\t\t\tjQuery.inArray(\"auto\", [ curCSSTop, curCSSLeft ] ) > -1;\n\n\t\t// need to be able to calculate position if either top or left is auto and position is either absolute or fixed\n\t\tif ( calculatePosition ) {\n\t\t\tcurPosition = curElem.position();\n\t\t\tcurTop = curPosition.top;\n\t\t\tcurLeft = curPosition.left;\n\t\t} else {\n\t\t\tcurTop = parseFloat( curCSSTop ) || 0;\n\t\t\tcurLeft = parseFloat( curCSSLeft ) || 0;\n\t\t}\n\n\t\tif ( jQuery.isFunction( options ) ) {\n\t\t\toptions = options.call( elem, i, curOffset );\n\t\t}\n\n\t\tif ( options.top != null ) {\n\t\t\tprops.top = ( options.top - curOffset.top ) + curTop;\n\t\t}\n\t\tif ( options.left != null ) {\n\t\t\tprops.left = ( options.left - curOffset.left ) + curLeft;\n\t\t}\n\n\t\tif ( \"using\" in options ) {\n\t\t\toptions.using.call( elem, props );\n\t\t} else {\n\t\t\tcurElem.css( props );\n\t\t}\n\t}\n};\n\njQuery.fn.extend({\n\toffset: function( options ) {\n\t\tif ( arguments.length ) {\n\t\t\treturn options === undefined ?\n\t\t\t\tthis :\n\t\t\t\tthis.each(function( i ) {\n\t\t\t\t\tjQuery.offset.setOffset( this, options, i );\n\t\t\t\t});\n\t\t}\n\n\t\tvar docElem, win,\n\t\t\tbox = { top: 0, left: 0 },\n\t\t\telem = this[ 0 ],\n\t\t\tdoc = elem && elem.ownerDocument;\n\n\t\tif ( !doc ) {\n\t\t\treturn;\n\t\t}\n\n\t\tdocElem = doc.documentElement;\n\n\t\t// Make sure it's not a disconnected DOM node\n\t\tif ( !jQuery.contains( docElem, elem ) ) {\n\t\t\treturn box;\n\t\t}\n\n\t\t// If we don't have gBCR, just use 0,0 rather than error\n\t\t// BlackBerry 5, iOS 3 (original iPhone)\n\t\tif ( typeof elem.getBoundingClientRect !== strundefined ) {\n\t\t\tbox = elem.getBoundingClientRect();\n\t\t}\n\t\twin = getWindow( doc );\n\t\treturn {\n\t\t\ttop: box.top  + ( win.pageYOffset || docElem.scrollTop )  - ( docElem.clientTop  || 0 ),\n\t\t\tleft: box.left + ( win.pageXOffset || docElem.scrollLeft ) - ( docElem.clientLeft || 0 )\n\t\t};\n\t},\n\n\tposition: function() {\n\t\tif ( !this[ 0 ] ) {\n\t\t\treturn;\n\t\t}\n\n\t\tvar offsetParent, offset,\n\t\t\tparentOffset = { top: 0, left: 0 },\n\t\t\telem = this[ 0 ];\n\n\t\t// fixed elements are offset from window (parentOffset = {top:0, left: 0}, because it is its only offset parent\n\t\tif ( jQuery.css( elem, \"position\" ) === \"fixed\" ) {\n\t\t\t// we assume that getBoundingClientRect is available when computed position is fixed\n\t\t\toffset = elem.getBoundingClientRect();\n\t\t} else {\n\t\t\t// Get *real* offsetParent\n\t\t\toffsetParent = this.offsetParent();\n\n\t\t\t// Get correct offsets\n\t\t\toffset = this.offset();\n\t\t\tif ( !jQuery.nodeName( offsetParent[ 0 ], \"html\" ) ) {\n\t\t\t\tparentOffset = offsetParent.offset();\n\t\t\t}\n\n\t\t\t// Add offsetParent borders\n\t\t\tparentOffset.top  += jQuery.css( offsetParent[ 0 ], \"borderTopWidth\", true );\n\t\t\tparentOffset.left += jQuery.css( offsetParent[ 0 ], \"borderLeftWidth\", true );\n\t\t}\n\n\t\t// Subtract parent offsets and element margins\n\t\t// note: when an element has margin: auto the offsetLeft and marginLeft\n\t\t// are the same in Safari causing offset.left to incorrectly be 0\n\t\treturn {\n\t\t\ttop:  offset.top  - parentOffset.top - jQuery.css( elem, \"marginTop\", true ),\n\t\t\tleft: offset.left - parentOffset.left - jQuery.css( elem, \"marginLeft\", true)\n\t\t};\n\t},\n\n\toffsetParent: function() {\n\t\treturn this.map(function() {\n\t\t\tvar offsetParent = this.offsetParent || docElem;\n\n\t\t\twhile ( offsetParent && ( !jQuery.nodeName( offsetParent, \"html\" ) && jQuery.css( offsetParent, \"position\" ) === \"static\" ) ) {\n\t\t\t\toffsetParent = offsetParent.offsetParent;\n\t\t\t}\n\t\t\treturn offsetParent || docElem;\n\t\t});\n\t}\n});\n\n// Create scrollLeft and scrollTop methods\njQuery.each( { scrollLeft: \"pageXOffset\", scrollTop: \"pageYOffset\" }, function( method, prop ) {\n\tvar top = /Y/.test( prop );\n\n\tjQuery.fn[ method ] = function( val ) {\n\t\treturn access( this, function( elem, method, val ) {\n\t\t\tvar win = getWindow( elem );\n\n\t\t\tif ( val === undefined ) {\n\t\t\t\treturn win ? (prop in win) ? win[ prop ] :\n\t\t\t\t\twin.document.documentElement[ method ] :\n\t\t\t\t\telem[ method ];\n\t\t\t}\n\n\t\t\tif ( win ) {\n\t\t\t\twin.scrollTo(\n\t\t\t\t\t!top ? val : jQuery( win ).scrollLeft(),\n\t\t\t\t\ttop ? val : jQuery( win ).scrollTop()\n\t\t\t\t);\n\n\t\t\t} else {\n\t\t\t\telem[ method ] = val;\n\t\t\t}\n\t\t}, method, val, arguments.length, null );\n\t};\n});\n\n// Add the top/left cssHooks using jQuery.fn.position\n// Webkit bug: https://bugs.webkit.org/show_bug.cgi?id=29084\n// getComputedStyle returns percent when specified for top/left/bottom/right\n// rather than make the css module depend on the offset module, we just check for it here\njQuery.each( [ \"top\", \"left\" ], function( i, prop ) {\n\tjQuery.cssHooks[ prop ] = addGetHookIf( support.pixelPosition,\n\t\tfunction( elem, computed ) {\n\t\t\tif ( computed ) {\n\t\t\t\tcomputed = curCSS( elem, prop );\n\t\t\t\t// if curCSS returns percentage, fallback to offset\n\t\t\t\treturn rnumnonpx.test( computed ) ?\n\t\t\t\t\tjQuery( elem ).position()[ prop ] + \"px\" :\n\t\t\t\t\tcomputed;\n\t\t\t}\n\t\t}\n\t);\n});\n\n\n// Create innerHeight, innerWidth, height, width, outerHeight and outerWidth methods\njQuery.each( { Height: \"height\", Width: \"width\" }, function( name, type ) {\n\tjQuery.each( { padding: \"inner\" + name, content: type, \"\": \"outer\" + name }, function( defaultExtra, funcName ) {\n\t\t// margin is only for outerHeight, outerWidth\n\t\tjQuery.fn[ funcName ] = function( margin, value ) {\n\t\t\tvar chainable = arguments.length && ( defaultExtra || typeof margin !== \"boolean\" ),\n\t\t\t\textra = defaultExtra || ( margin === true || value === true ? \"margin\" : \"border\" );\n\n\t\t\treturn access( this, function( elem, type, value ) {\n\t\t\t\tvar doc;\n\n\t\t\t\tif ( jQuery.isWindow( elem ) ) {\n\t\t\t\t\t// As of 5/8/2012 this will yield incorrect results for Mobile Safari, but there\n\t\t\t\t\t// isn't a whole lot we can do. See pull request at this URL for discussion:\n\t\t\t\t\t// https://github.com/jquery/jquery/pull/764\n\t\t\t\t\treturn elem.document.documentElement[ \"client\" + name ];\n\t\t\t\t}\n\n\t\t\t\t// Get document width or height\n\t\t\t\tif ( elem.nodeType === 9 ) {\n\t\t\t\t\tdoc = elem.documentElement;\n\n\t\t\t\t\t// Either scroll[Width/Height] or offset[Width/Height] or client[Width/Height], whichever is greatest\n\t\t\t\t\t// unfortunately, this causes bug #3838 in IE6/8 only, but there is currently no good, small way to fix it.\n\t\t\t\t\treturn Math.max(\n\t\t\t\t\t\telem.body[ \"scroll\" + name ], doc[ \"scroll\" + name ],\n\t\t\t\t\t\telem.body[ \"offset\" + name ], doc[ \"offset\" + name ],\n\t\t\t\t\t\tdoc[ \"client\" + name ]\n\t\t\t\t\t);\n\t\t\t\t}\n\n\t\t\t\treturn value === undefined ?\n\t\t\t\t\t// Get width or height on the element, requesting but not forcing parseFloat\n\t\t\t\t\tjQuery.css( elem, type, extra ) :\n\n\t\t\t\t\t// Set width or height on the element\n\t\t\t\t\tjQuery.style( elem, type, value, extra );\n\t\t\t}, type, chainable ? margin : undefined, chainable, null );\n\t\t};\n\t});\n});\n\n\n// The number of elements contained in the matched element set\njQuery.fn.size = function() {\n\treturn this.length;\n};\n\njQuery.fn.andSelf = jQuery.fn.addBack;\n\n\n\n\n// Register as a named AMD module, since jQuery can be concatenated with other\n// files that may use define, but not via a proper concatenation script that\n// understands anonymous AMD modules. A named AMD is safest and most robust\n// way to register. Lowercase jquery is used because AMD module names are\n// derived from file names, and jQuery is normally delivered in a lowercase\n// file name. Do this after creating the global so that if an AMD module wants\n// to call noConflict to hide this version of jQuery, it will work.\n\n// Note that for maximum portability, libraries that are not jQuery should\n// declare themselves as anonymous modules, and avoid setting a global if an\n// AMD loader is present. jQuery is a special case. For more information, see\n// https://github.com/jrburke/requirejs/wiki/Updating-existing-libraries#wiki-anon\n\nif ( typeof define === \"function\" && define.amd ) {\n\tdefine( \"jquery\", [], function() {\n\t\treturn jQuery;\n\t});\n}\n\n\n\n\nvar\n\t// Map over jQuery in case of overwrite\n\t_jQuery = window.jQuery,\n\n\t// Map over the $ in case of overwrite\n\t_$ = window.$;\n\njQuery.noConflict = function( deep ) {\n\tif ( window.$ === jQuery ) {\n\t\twindow.$ = _$;\n\t}\n\n\tif ( deep && window.jQuery === jQuery ) {\n\t\twindow.jQuery = _jQuery;\n\t}\n\n\treturn jQuery;\n};\n\n// Expose jQuery and $ identifiers, even in\n// AMD (#7102#comment:10, https://github.com/jquery/jquery/pull/557)\n// and CommonJS for browser emulators (#13566)\nif ( typeof noGlobal === strundefined ) {\n\twindow.jQuery = window.$ = jQuery;\n}\n\n\n\n\nreturn jQuery;\n\n}));\n"
  },
  {
    "path": "app_backend/static/plugin/Gallery-2.25.0/package.json",
    "content": "{\n  \"name\": \"blueimp-gallery\",\n  \"version\": \"2.25.0\",\n  \"title\": \"blueimp Gallery\",\n  \"description\": \"blueimp Gallery is a touch-enabled, responsive and customizable image and video gallery, carousel and lightbox, optimized for both mobile and desktop web browsers. It features swipe, mouse and keyboard navigation, transition effects, slideshow functionality, fullscreen support and on-demand content loading and can be extended to display additional content types.\",\n  \"keywords\": [\n    \"image\",\n    \"video\",\n    \"gallery\",\n    \"carousel\",\n    \"lightbox\",\n    \"mobile\",\n    \"desktop\",\n    \"touch\",\n    \"responsive\",\n    \"swipe\",\n    \"mouse\",\n    \"keyboard\",\n    \"navigation\",\n    \"transition\",\n    \"effects\",\n    \"slideshow\",\n    \"fullscreen\"\n  ],\n  \"homepage\": \"https://github.com/blueimp/Gallery\",\n  \"author\": {\n    \"name\": \"Sebastian Tschan\",\n    \"url\": \"https://blueimp.net\"\n  },\n  \"repository\": {\n    \"type\": \"git\",\n    \"url\": \"git://github.com/blueimp/Gallery.git\"\n  },\n  \"license\": \"MIT\",\n  \"devDependencies\": {\n    \"clean-css\": \"3.4.21\",\n    \"standard\": \"8.6.0\",\n    \"uglify-js\": \"2.7.4\"\n  },\n  \"scripts\": {\n    \"test\": \"standard js/*.js\",\n    \"build:js\": \"cd js && uglifyjs blueimp-helper.js blueimp-gallery.js blueimp-gallery-fullscreen.js blueimp-gallery-indicator.js blueimp-gallery-video.js blueimp-gallery-vimeo.js blueimp-gallery-youtube.js -c -m -o blueimp-gallery.min.js --source-map blueimp-gallery.min.js.map\",\n    \"build:jquery\": \"cd js && uglifyjs blueimp-gallery.js blueimp-gallery-fullscreen.js blueimp-gallery-indicator.js blueimp-gallery-video.js blueimp-gallery-vimeo.js blueimp-gallery-youtube.js jquery.blueimp-gallery.js -c -m -o jquery.blueimp-gallery.min.js --source-map jquery.blueimp-gallery.min.js.map\",\n    \"build:css\": \"cd css && cleancss -c ie7 --source-map -o blueimp-gallery.min.css blueimp-gallery.css blueimp-gallery-indicator.css blueimp-gallery-video.css\",\n    \"build\": \"npm run build:js && npm run build:jquery && npm run build:css\",\n    \"preversion\": \"npm test\",\n    \"version\": \"npm run build && git add -A js css\",\n    \"postversion\": \"git push --tags origin master master:gh-pages && npm publish\"\n  },\n  \"main\": \"js/blueimp-gallery.js\"\n}\n"
  },
  {
    "path": "app_backend/static/plugin/JavaScript-Canvas-to-Blob-3.7.0/.gitignore",
    "content": ".DS_Store\nnode_modules\n"
  },
  {
    "path": "app_backend/static/plugin/JavaScript-Canvas-to-Blob-3.7.0/.npmignore",
    "content": "*\n!js/*.js\n!js/*.js.map\n"
  },
  {
    "path": "app_backend/static/plugin/JavaScript-Canvas-to-Blob-3.7.0/.travis.yml",
    "content": "language: node_js\nnode_js:\n  - \"stable\"\n"
  },
  {
    "path": "app_backend/static/plugin/JavaScript-Canvas-to-Blob-3.7.0/README.md",
    "content": "# JavaScript Canvas to Blob\n\n## Description\nCanvas to Blob is a polyfill for the standard JavaScript\n[canvas.toBlob](http://www.w3.org/TR/html5/scripting-1.html#dom-canvas-toblob)\nmethod.\n\nIt can be used to create\n[Blob](https://developer.mozilla.org/en-US/docs/Web/API/Blob)\nobjects from an HTML\n[canvas](https://developer.mozilla.org/en-US/docs/HTML/Canvas) element.\n\n## Usage\nInclude the (minified) JavaScript Canvas to Blob script in your HTML markup:\n\n```html\n<script src=\"js/canvas-to-blob.min.js\"></script>\n```\n\nThen use the *canvas.toBlob()* method in the same way as the native\nimplementation:\n\n```js\nvar canvas = document.createElement('canvas');\n/* ... your canvas manipulations ... */\nif (canvas.toBlob) {\n    canvas.toBlob(\n        function (blob) {\n            // Do something with the blob object,\n            // e.g. creating a multipart form for file uploads:\n            var formData = new FormData();\n            formData.append('file', blob, fileName);\n            /* ... */\n        },\n        'image/jpeg'\n    );\n}\n```\n\n## Requirements\nThe JavaScript Canvas to Blob function has zero dependencies.\n\nHowever, Canvas to Blob is a very suitable complement to the\n[JavaScript Load Image](https://github.com/blueimp/JavaScript-Load-Image)\nfunction.\n\n## API\nIn addition to the **canvas.toBlob** polyfill, the JavaScript Canvas to Blob\nscript provides one additional function called **dataURLtoBlob**, which is added\nto the global window object, unless the library is loaded via a module loader\nlike RequireJS, Browserify or webpack:\n\n```js\n// 80x60px GIF image (color black, base64 data):\nvar b64Data = 'R0lGODdhUAA8AIABAAAAAP///ywAAAAAUAA8AAACS4SPqcvtD6' +\n        'OctNqLs968+w+G4kiW5omm6sq27gvH8kzX9o3n+s73/g8MCofE' +\n        'ovGITCqXzKbzCY1Kp9Sq9YrNarfcrvcLDovH5PKsAAA7',\n    imageUrl = 'data:image/gif;base64,' + b64Data,\n    blob = window.dataURLtoBlob && window.dataURLtoBlob(imageUrl);\n```\n\n## Browsers\nThe following browsers support either the native or the polyfill\n*canvas.toBlob()* method:\n\n### Desktop browsers\n\n* Google Chrome (see [Chromium issue #67587](https://code.google.com/p/chromium/issues/detail?id=67587))\n* Apple Safari 6.0+ (see [Mozilla issue #648610](https://bugzilla.mozilla.org/show_bug.cgi?id=648610))\n* Mozilla Firefox 4.0+\n* Microsoft Internet Explorer 10.0+\n\n### Mobile browsers\n\n* Apple Safari Mobile on iOS 6.0+\n* Google Chrome on iOS 6.0+\n* Google Chrome on Android 4.0+\n\n## Test\n[JavaScript Canvas to Blob Test](https://blueimp.github.io/JavaScript-Canvas-to-Blob/test/)\n\n## License\nThe JavaScript Canvas to Blob script is released under the\n[MIT license](https://opensource.org/licenses/MIT).\n"
  },
  {
    "path": "app_backend/static/plugin/JavaScript-Canvas-to-Blob-3.7.0/js/canvas-to-blob.js",
    "content": "/*\n * JavaScript Canvas to Blob\n * https://github.com/blueimp/JavaScript-Canvas-to-Blob\n *\n * Copyright 2012, Sebastian Tschan\n * https://blueimp.net\n *\n * Licensed under the MIT license:\n * https://opensource.org/licenses/MIT\n *\n * Based on stackoverflow user Stoive's code snippet:\n * http://stackoverflow.com/q/4998908\n */\n\n/* global atob, Blob, define */\n\n;(function (window) {\n  'use strict'\n\n  var CanvasPrototype = window.HTMLCanvasElement &&\n                          window.HTMLCanvasElement.prototype\n  var hasBlobConstructor = window.Blob && (function () {\n    try {\n      return Boolean(new Blob())\n    } catch (e) {\n      return false\n    }\n  }())\n  var hasArrayBufferViewSupport = hasBlobConstructor && window.Uint8Array &&\n    (function () {\n      try {\n        return new Blob([new Uint8Array(100)]).size === 100\n      } catch (e) {\n        return false\n      }\n    }())\n  var BlobBuilder = window.BlobBuilder || window.WebKitBlobBuilder ||\n                      window.MozBlobBuilder || window.MSBlobBuilder\n  var dataURIPattern = /^data:((.*?)(;charset=.*?)?)(;base64)?,/\n  var dataURLtoBlob = (hasBlobConstructor || BlobBuilder) && window.atob &&\n    window.ArrayBuffer && window.Uint8Array &&\n    function (dataURI) {\n      var matches,\n        mediaType,\n        isBase64,\n        dataString,\n        byteString,\n        arrayBuffer,\n        intArray,\n        i,\n        bb\n      // Parse the dataURI components as per RFC 2397\n      matches = dataURI.match(dataURIPattern)\n      if (!matches) {\n        throw new Error('invalid data URI')\n      }\n      // Default to text/plain;charset=US-ASCII\n      mediaType = matches[2]\n        ? matches[1]\n        : 'text/plain' + (matches[3] || ';charset=US-ASCII')\n      isBase64 = !!matches[4]\n      dataString = dataURI.slice(matches[0].length)\n      if (isBase64) {\n        // Convert base64 to raw binary data held in a string:\n        byteString = atob(dataString)\n      } else {\n        // Convert base64/URLEncoded data component to raw binary:\n        byteString = decodeURIComponent(dataString)\n      }\n      // Write the bytes of the string to an ArrayBuffer:\n      arrayBuffer = new ArrayBuffer(byteString.length)\n      intArray = new Uint8Array(arrayBuffer)\n      for (i = 0; i < byteString.length; i += 1) {\n        intArray[i] = byteString.charCodeAt(i)\n      }\n      // Write the ArrayBuffer (or ArrayBufferView) to a blob:\n      if (hasBlobConstructor) {\n        return new Blob(\n          [hasArrayBufferViewSupport ? intArray : arrayBuffer],\n          {type: mediaType}\n        )\n      }\n      bb = new BlobBuilder()\n      bb.append(arrayBuffer)\n      return bb.getBlob(mediaType)\n    }\n  if (window.HTMLCanvasElement && !CanvasPrototype.toBlob) {\n    if (CanvasPrototype.mozGetAsFile) {\n      CanvasPrototype.toBlob = function (callback, type, quality) {\n        if (quality && CanvasPrototype.toDataURL && dataURLtoBlob) {\n          callback(dataURLtoBlob(this.toDataURL(type, quality)))\n        } else {\n          callback(this.mozGetAsFile('blob', type))\n        }\n      }\n    } else if (CanvasPrototype.toDataURL && dataURLtoBlob) {\n      CanvasPrototype.toBlob = function (callback, type, quality) {\n        callback(dataURLtoBlob(this.toDataURL(type, quality)))\n      }\n    }\n  }\n  if (typeof define === 'function' && define.amd) {\n    define(function () {\n      return dataURLtoBlob\n    })\n  } else if (typeof module === 'object' && module.exports) {\n    module.exports = dataURLtoBlob\n  } else {\n    window.dataURLtoBlob = dataURLtoBlob\n  }\n}(window))\n"
  },
  {
    "path": "app_backend/static/plugin/JavaScript-Canvas-to-Blob-3.7.0/package.json",
    "content": "{\n  \"name\": \"blueimp-canvas-to-blob\",\n  \"version\": \"3.7.0\",\n  \"title\": \"JavaScript Canvas to Blob\",\n  \"description\": \"Canvas to Blob is a polyfill for the standard JavaScript canvas.toBlob method. It can be used to create Blob objects from an HTML canvas element.\",\n  \"keywords\": [\n    \"javascript\",\n    \"canvas\",\n    \"blob\",\n    \"convert\",\n    \"conversion\"\n  ],\n  \"homepage\": \"https://github.com/blueimp/JavaScript-Canvas-to-Blob\",\n  \"author\": {\n    \"name\": \"Sebastian Tschan\",\n    \"url\": \"https://blueimp.net\"\n  },\n  \"repository\": {\n    \"type\": \"git\",\n    \"url\": \"git://github.com/blueimp/JavaScript-Canvas-to-Blob.git\"\n  },\n  \"license\": \"MIT\",\n  \"main\": \"./js/canvas-to-blob.js\",\n  \"devDependencies\": {\n    \"phantomjs-prebuilt\": \"2.1.13\",\n    \"mocha-phantomjs-core\": \"1.3.1\",\n    \"standard\": \"8.3.0\",\n    \"uglify-js\": \"2.7.3\"\n  },\n  \"scripts\": {\n    \"lint\": \"standard js/*.js test/*.js\",\n    \"unit\": \"phantomjs node_modules/mocha-phantomjs-core/mocha-phantomjs-core.js test/index.html\",\n    \"test\": \"npm run lint && npm run unit\",\n    \"build\": \"cd js && uglifyjs canvas-to-blob.js -c -m -o canvas-to-blob.min.js --source-map canvas-to-blob.min.js.map\",\n    \"preversion\": \"npm test\",\n    \"version\": \"npm run build && git add -A js\",\n    \"postversion\": \"git push --tags origin master master:gh-pages && npm publish\"\n  }\n}\n"
  },
  {
    "path": "app_backend/static/plugin/JavaScript-Canvas-to-Blob-3.7.0/test/index.html",
    "content": "<!DOCTYPE HTML>\n<!--\n/*\n * JavaScript Canvas to Blob Test\n * https://github.com/blueimp/JavaScript-Canvas-to-Blob\n *\n * Copyright 2012, Sebastian Tschan\n * https://blueimp.net\n *\n * Licensed under the MIT license:\n * https://opensource.org/licenses/MIT\n */\n-->\n<html lang=\"en\">\n<head>\n<!--[if IE]>\n<meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge,chrome=1\">\n<![endif]-->\n<meta charset=\"utf-8\">\n<title>JavaScript Canvas to Blob Test</title>\n<meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n<link rel=\"stylesheet\" href=\"vendor/mocha.css\">\n</head>\n<body>\n<div id=\"mocha\"></div>\n<script src=\"vendor/mocha.js\"></script>\n<script src=\"vendor/chai.js\"></script>\n<script>\nwindow.initMochaPhantomJS && initMochaPhantomJS();\nmocha.setup('bdd');\n</script>\n<script src=\"vendor/load-image.js\"></script>\n<script src=\"../js/canvas-to-blob.js\"></script>\n<script src=\"test.js\"></script>\n<script>\nmocha.checkLeaks();\nmocha.run();\n</script>\n</body>\n</html>\n"
  },
  {
    "path": "app_backend/static/plugin/JavaScript-Canvas-to-Blob-3.7.0/test/test.js",
    "content": "/*\n * JavaScript Canvas to Blob Test\n * https://github.com/blueimp/JavaScript-Canvas-to-Blob\n *\n * Copyright 2012, Sebastian Tschan\n * https://blueimp.net\n *\n * Licensed under the MIT license:\n * https://opensource.org/licenses/MIT\n */\n\n/* global describe, it, Blob */\n\n;(function (expect) {\n  'use strict'\n\n  // 80x60px GIF image (color black, base64 data):\n  var b64Data = 'R0lGODdhUAA8AIABAAAAAP///ywAAAAAUAA8AAACS4SPqcvtD6' +\n      'OctNqLs968+w+G4kiW5omm6sq27gvH8kzX9o3n+s73/g8MCofE' +\n      'ovGITCqXzKbzCY1Kp9Sq9YrNarfcrvcLDovH5PKsAAA7'\n  var imageUrl = 'data:image/gif;base64,' + b64Data\n  var blob = window.dataURLtoBlob && window.dataURLtoBlob(imageUrl)\n\n  describe('canvas.toBlob', function () {\n    it('Converts a canvas element to a blob and passes it to the callback function', function (done) {\n      window.loadImage(blob, function (canvas) {\n        canvas.toBlob(\n          function (newBlob) {\n            expect(newBlob).to.be.a.instanceOf(Blob)\n            done()\n          }\n        )\n      }, {canvas: true})\n    })\n\n    it('Converts a canvas element to a PNG blob', function (done) {\n      window.loadImage(blob, function (canvas) {\n        canvas.toBlob(\n          function (newBlob) {\n            expect(newBlob.type).to.equal('image/png')\n            done()\n          },\n          'image/png'\n        )\n      }, {canvas: true})\n    })\n\n    it('Converts a canvas element to a JPG blob', function (done) {\n      window.loadImage(blob, function (canvas) {\n        canvas.toBlob(\n          function (newBlob) {\n            expect(newBlob.type).to.equal('image/jpeg')\n            done()\n          },\n          'image/jpeg'\n        )\n      }, {canvas: true})\n    })\n\n    it('Keeps the aspect ratio of the canvas image', function (done) {\n      window.loadImage(blob, function (canvas) {\n        canvas.toBlob(\n          function (newBlob) {\n            window.loadImage(newBlob, function (img) {\n              expect(img.width).to.equal(canvas.width)\n              expect(img.height).to.equal(canvas.height)\n              done()\n            })\n          }\n        )\n      }, {canvas: true})\n    })\n\n    it('Keeps the image data of the canvas image', function (done) {\n      window.loadImage(blob, function (canvas) {\n        canvas.toBlob(\n          function (newBlob) {\n            window.loadImage(newBlob, function (newCanvas) {\n              var canvasData = canvas.getContext('2d')\n                  .getImageData(0, 0, canvas.width, canvas.height)\n              var newCanvasData = newCanvas.getContext('2d')\n                  .getImageData(0, 0, newCanvas.width, newCanvas.height)\n              expect(canvasData.width).to.equal(newCanvasData.width)\n              expect(canvasData.height).to.equal(newCanvasData.height)\n              done()\n            }, {canvas: true})\n          }\n        )\n      }, {canvas: true})\n    })\n  })\n}(this.chai.expect))\n"
  },
  {
    "path": "app_backend/static/plugin/JavaScript-Canvas-to-Blob-3.7.0/test/vendor/chai.js",
    "content": "(function(f){if(typeof exports===\"object\"&&typeof module!==\"undefined\"){module.exports=f()}else if(typeof define===\"function\"&&define.amd){define([],f)}else{var g;if(typeof window!==\"undefined\"){g=window}else if(typeof global!==\"undefined\"){g=global}else if(typeof self!==\"undefined\"){g=self}else{g=this}g.chai = f()}})(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require==\"function\"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error(\"Cannot find module '\"+o+\"'\");throw f.code=\"MODULE_NOT_FOUND\",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require==\"function\"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){\nmodule.exports = require('./lib/chai');\n\n},{\"./lib/chai\":2}],2:[function(require,module,exports){\n/*!\n * chai\n * Copyright(c) 2011-2014 Jake Luer <jake@alogicalparadox.com>\n * MIT Licensed\n */\n\nvar used = []\n  , exports = module.exports = {};\n\n/*!\n * Chai version\n */\n\nexports.version = '3.5.0';\n\n/*!\n * Assertion Error\n */\n\nexports.AssertionError = require('assertion-error');\n\n/*!\n * Utils for plugins (not exported)\n */\n\nvar util = require('./chai/utils');\n\n/**\n * # .use(function)\n *\n * Provides a way to extend the internals of Chai\n *\n * @param {Function}\n * @returns {this} for chaining\n * @api public\n */\n\nexports.use = function (fn) {\n  if (!~used.indexOf(fn)) {\n    fn(this, util);\n    used.push(fn);\n  }\n\n  return this;\n};\n\n/*!\n * Utility Functions\n */\n\nexports.util = util;\n\n/*!\n * Configuration\n */\n\nvar config = require('./chai/config');\nexports.config = config;\n\n/*!\n * Primary `Assertion` prototype\n */\n\nvar assertion = require('./chai/assertion');\nexports.use(assertion);\n\n/*!\n * Core Assertions\n */\n\nvar core = require('./chai/core/assertions');\nexports.use(core);\n\n/*!\n * Expect interface\n */\n\nvar expect = require('./chai/interface/expect');\nexports.use(expect);\n\n/*!\n * Should interface\n */\n\nvar should = require('./chai/interface/should');\nexports.use(should);\n\n/*!\n * Assert interface\n */\n\nvar assert = require('./chai/interface/assert');\nexports.use(assert);\n\n},{\"./chai/assertion\":3,\"./chai/config\":4,\"./chai/core/assertions\":5,\"./chai/interface/assert\":6,\"./chai/interface/expect\":7,\"./chai/interface/should\":8,\"./chai/utils\":22,\"assertion-error\":30}],3:[function(require,module,exports){\n/*!\n * chai\n * http://chaijs.com\n * Copyright(c) 2011-2014 Jake Luer <jake@alogicalparadox.com>\n * MIT Licensed\n */\n\nvar config = require('./config');\n\nmodule.exports = function (_chai, util) {\n  /*!\n   * Module dependencies.\n   */\n\n  var AssertionError = _chai.AssertionError\n    , flag = util.flag;\n\n  /*!\n   * Module export.\n   */\n\n  _chai.Assertion = Assertion;\n\n  /*!\n   * Assertion Constructor\n   *\n   * Creates object for chaining.\n   *\n   * @api private\n   */\n\n  function Assertion (obj, msg, stack) {\n    flag(this, 'ssfi', stack || arguments.callee);\n    flag(this, 'object', obj);\n    flag(this, 'message', msg);\n  }\n\n  Object.defineProperty(Assertion, 'includeStack', {\n    get: function() {\n      console.warn('Assertion.includeStack is deprecated, use chai.config.includeStack instead.');\n      return config.includeStack;\n    },\n    set: function(value) {\n      console.warn('Assertion.includeStack is deprecated, use chai.config.includeStack instead.');\n      config.includeStack = value;\n    }\n  });\n\n  Object.defineProperty(Assertion, 'showDiff', {\n    get: function() {\n      console.warn('Assertion.showDiff is deprecated, use chai.config.showDiff instead.');\n      return config.showDiff;\n    },\n    set: function(value) {\n      console.warn('Assertion.showDiff is deprecated, use chai.config.showDiff instead.');\n      config.showDiff = value;\n    }\n  });\n\n  Assertion.addProperty = function (name, fn) {\n    util.addProperty(this.prototype, name, fn);\n  };\n\n  Assertion.addMethod = function (name, fn) {\n    util.addMethod(this.prototype, name, fn);\n  };\n\n  Assertion.addChainableMethod = function (name, fn, chainingBehavior) {\n    util.addChainableMethod(this.prototype, name, fn, chainingBehavior);\n  };\n\n  Assertion.overwriteProperty = function (name, fn) {\n    util.overwriteProperty(this.prototype, name, fn);\n  };\n\n  Assertion.overwriteMethod = function (name, fn) {\n    util.overwriteMethod(this.prototype, name, fn);\n  };\n\n  Assertion.overwriteChainableMethod = function (name, fn, chainingBehavior) {\n    util.overwriteChainableMethod(this.prototype, name, fn, chainingBehavior);\n  };\n\n  /**\n   * ### .assert(expression, message, negateMessage, expected, actual, showDiff)\n   *\n   * Executes an expression and check expectations. Throws AssertionError for reporting if test doesn't pass.\n   *\n   * @name assert\n   * @param {Philosophical} expression to be tested\n   * @param {String|Function} message or function that returns message to display if expression fails\n   * @param {String|Function} negatedMessage or function that returns negatedMessage to display if negated expression fails\n   * @param {Mixed} expected value (remember to check for negation)\n   * @param {Mixed} actual (optional) will default to `this.obj`\n   * @param {Boolean} showDiff (optional) when set to `true`, assert will display a diff in addition to the message if expression fails\n   * @api private\n   */\n\n  Assertion.prototype.assert = function (expr, msg, negateMsg, expected, _actual, showDiff) {\n    var ok = util.test(this, arguments);\n    if (true !== showDiff) showDiff = false;\n    if (true !== config.showDiff) showDiff = false;\n\n    if (!ok) {\n      var msg = util.getMessage(this, arguments)\n        , actual = util.getActual(this, arguments);\n      throw new AssertionError(msg, {\n          actual: actual\n        , expected: expected\n        , showDiff: showDiff\n      }, (config.includeStack) ? this.assert : flag(this, 'ssfi'));\n    }\n  };\n\n  /*!\n   * ### ._obj\n   *\n   * Quick reference to stored `actual` value for plugin developers.\n   *\n   * @api private\n   */\n\n  Object.defineProperty(Assertion.prototype, '_obj',\n    { get: function () {\n        return flag(this, 'object');\n      }\n    , set: function (val) {\n        flag(this, 'object', val);\n      }\n  });\n};\n\n},{\"./config\":4}],4:[function(require,module,exports){\nmodule.exports = {\n\n  /**\n   * ### config.includeStack\n   *\n   * User configurable property, influences whether stack trace\n   * is included in Assertion error message. Default of false\n   * suppresses stack trace in the error message.\n   *\n   *     chai.config.includeStack = true;  // enable stack on error\n   *\n   * @param {Boolean}\n   * @api public\n   */\n\n   includeStack: false,\n\n  /**\n   * ### config.showDiff\n   *\n   * User configurable property, influences whether or not\n   * the `showDiff` flag should be included in the thrown\n   * AssertionErrors. `false` will always be `false`; `true`\n   * will be true when the assertion has requested a diff\n   * be shown.\n   *\n   * @param {Boolean}\n   * @api public\n   */\n\n  showDiff: true,\n\n  /**\n   * ### config.truncateThreshold\n   *\n   * User configurable property, sets length threshold for actual and\n   * expected values in assertion errors. If this threshold is exceeded, for\n   * example for large data structures, the value is replaced with something\n   * like `[ Array(3) ]` or `{ Object (prop1, prop2) }`.\n   *\n   * Set it to zero if you want to disable truncating altogether.\n   *\n   * This is especially userful when doing assertions on arrays: having this\n   * set to a reasonable large value makes the failure messages readily\n   * inspectable.\n   *\n   *     chai.config.truncateThreshold = 0;  // disable truncating\n   *\n   * @param {Number}\n   * @api public\n   */\n\n  truncateThreshold: 40\n\n};\n\n},{}],5:[function(require,module,exports){\n/*!\n * chai\n * http://chaijs.com\n * Copyright(c) 2011-2014 Jake Luer <jake@alogicalparadox.com>\n * MIT Licensed\n */\n\nmodule.exports = function (chai, _) {\n  var Assertion = chai.Assertion\n    , toString = Object.prototype.toString\n    , flag = _.flag;\n\n  /**\n   * ### Language Chains\n   *\n   * The following are provided as chainable getters to\n   * improve the readability of your assertions. They\n   * do not provide testing capabilities unless they\n   * have been overwritten by a plugin.\n   *\n   * **Chains**\n   *\n   * - to\n   * - be\n   * - been\n   * - is\n   * - that\n   * - which\n   * - and\n   * - has\n   * - have\n   * - with\n   * - at\n   * - of\n   * - same\n   *\n   * @name language chains\n   * @namespace BDD\n   * @api public\n   */\n\n  [ 'to', 'be', 'been'\n  , 'is', 'and', 'has', 'have'\n  , 'with', 'that', 'which', 'at'\n  , 'of', 'same' ].forEach(function (chain) {\n    Assertion.addProperty(chain, function () {\n      return this;\n    });\n  });\n\n  /**\n   * ### .not\n   *\n   * Negates any of assertions following in the chain.\n   *\n   *     expect(foo).to.not.equal('bar');\n   *     expect(goodFn).to.not.throw(Error);\n   *     expect({ foo: 'baz' }).to.have.property('foo')\n   *       .and.not.equal('bar');\n   *\n   * @name not\n   * @namespace BDD\n   * @api public\n   */\n\n  Assertion.addProperty('not', function () {\n    flag(this, 'negate', true);\n  });\n\n  /**\n   * ### .deep\n   *\n   * Sets the `deep` flag, later used by the `equal` and\n   * `property` assertions.\n   *\n   *     expect(foo).to.deep.equal({ bar: 'baz' });\n   *     expect({ foo: { bar: { baz: 'quux' } } })\n   *       .to.have.deep.property('foo.bar.baz', 'quux');\n   *\n   * `.deep.property` special characters can be escaped\n   * by adding two slashes before the `.` or `[]`.\n   *\n   *     var deepCss = { '.link': { '[target]': 42 }};\n   *     expect(deepCss).to.have.deep.property('\\\\.link.\\\\[target\\\\]', 42);\n   *\n   * @name deep\n   * @namespace BDD\n   * @api public\n   */\n\n  Assertion.addProperty('deep', function () {\n    flag(this, 'deep', true);\n  });\n\n  /**\n   * ### .any\n   *\n   * Sets the `any` flag, (opposite of the `all` flag)\n   * later used in the `keys` assertion.\n   *\n   *     expect(foo).to.have.any.keys('bar', 'baz');\n   *\n   * @name any\n   * @namespace BDD\n   * @api public\n   */\n\n  Assertion.addProperty('any', function () {\n    flag(this, 'any', true);\n    flag(this, 'all', false)\n  });\n\n\n  /**\n   * ### .all\n   *\n   * Sets the `all` flag (opposite of the `any` flag)\n   * later used by the `keys` assertion.\n   *\n   *     expect(foo).to.have.all.keys('bar', 'baz');\n   *\n   * @name all\n   * @namespace BDD\n   * @api public\n   */\n\n  Assertion.addProperty('all', function () {\n    flag(this, 'all', true);\n    flag(this, 'any', false);\n  });\n\n  /**\n   * ### .a(type)\n   *\n   * The `a` and `an` assertions are aliases that can be\n   * used either as language chains or to assert a value's\n   * type.\n   *\n   *     // typeof\n   *     expect('test').to.be.a('string');\n   *     expect({ foo: 'bar' }).to.be.an('object');\n   *     expect(null).to.be.a('null');\n   *     expect(undefined).to.be.an('undefined');\n   *     expect(new Error).to.be.an('error');\n   *     expect(new Promise).to.be.a('promise');\n   *     expect(new Float32Array()).to.be.a('float32array');\n   *     expect(Symbol()).to.be.a('symbol');\n   *\n   *     // es6 overrides\n   *     expect({[Symbol.toStringTag]:()=>'foo'}).to.be.a('foo');\n   *\n   *     // language chain\n   *     expect(foo).to.be.an.instanceof(Foo);\n   *\n   * @name a\n   * @alias an\n   * @param {String} type\n   * @param {String} message _optional_\n   * @namespace BDD\n   * @api public\n   */\n\n  function an (type, msg) {\n    if (msg) flag(this, 'message', msg);\n    type = type.toLowerCase();\n    var obj = flag(this, 'object')\n      , article = ~[ 'a', 'e', 'i', 'o', 'u' ].indexOf(type.charAt(0)) ? 'an ' : 'a ';\n\n    this.assert(\n        type === _.type(obj)\n      , 'expected #{this} to be ' + article + type\n      , 'expected #{this} not to be ' + article + type\n    );\n  }\n\n  Assertion.addChainableMethod('an', an);\n  Assertion.addChainableMethod('a', an);\n\n  /**\n   * ### .include(value)\n   *\n   * The `include` and `contain` assertions can be used as either property\n   * based language chains or as methods to assert the inclusion of an object\n   * in an array or a substring in a string. When used as language chains,\n   * they toggle the `contains` flag for the `keys` assertion.\n   *\n   *     expect([1,2,3]).to.include(2);\n   *     expect('foobar').to.contain('foo');\n   *     expect({ foo: 'bar', hello: 'universe' }).to.include.keys('foo');\n   *\n   * @name include\n   * @alias contain\n   * @alias includes\n   * @alias contains\n   * @param {Object|String|Number} obj\n   * @param {String} message _optional_\n   * @namespace BDD\n   * @api public\n   */\n\n  function includeChainingBehavior () {\n    flag(this, 'contains', true);\n  }\n\n  function include (val, msg) {\n    _.expectTypes(this, ['array', 'object', 'string']);\n\n    if (msg) flag(this, 'message', msg);\n    var obj = flag(this, 'object');\n    var expected = false;\n\n    if (_.type(obj) === 'array' && _.type(val) === 'object') {\n      for (var i in obj) {\n        if (_.eql(obj[i], val)) {\n          expected = true;\n          break;\n        }\n      }\n    } else if (_.type(val) === 'object') {\n      if (!flag(this, 'negate')) {\n        for (var k in val) new Assertion(obj).property(k, val[k]);\n        return;\n      }\n      var subset = {};\n      for (var k in val) subset[k] = obj[k];\n      expected = _.eql(subset, val);\n    } else {\n      expected = (obj != undefined) && ~obj.indexOf(val);\n    }\n    this.assert(\n        expected\n      , 'expected #{this} to include ' + _.inspect(val)\n      , 'expected #{this} to not include ' + _.inspect(val));\n  }\n\n  Assertion.addChainableMethod('include', include, includeChainingBehavior);\n  Assertion.addChainableMethod('contain', include, includeChainingBehavior);\n  Assertion.addChainableMethod('contains', include, includeChainingBehavior);\n  Assertion.addChainableMethod('includes', include, includeChainingBehavior);\n\n  /**\n   * ### .ok\n   *\n   * Asserts that the target is truthy.\n   *\n   *     expect('everything').to.be.ok;\n   *     expect(1).to.be.ok;\n   *     expect(false).to.not.be.ok;\n   *     expect(undefined).to.not.be.ok;\n   *     expect(null).to.not.be.ok;\n   *\n   * @name ok\n   * @namespace BDD\n   * @api public\n   */\n\n  Assertion.addProperty('ok', function () {\n    this.assert(\n        flag(this, 'object')\n      , 'expected #{this} to be truthy'\n      , 'expected #{this} to be falsy');\n  });\n\n  /**\n   * ### .true\n   *\n   * Asserts that the target is `true`.\n   *\n   *     expect(true).to.be.true;\n   *     expect(1).to.not.be.true;\n   *\n   * @name true\n   * @namespace BDD\n   * @api public\n   */\n\n  Assertion.addProperty('true', function () {\n    this.assert(\n        true === flag(this, 'object')\n      , 'expected #{this} to be true'\n      , 'expected #{this} to be false'\n      , this.negate ? false : true\n    );\n  });\n\n  /**\n   * ### .false\n   *\n   * Asserts that the target is `false`.\n   *\n   *     expect(false).to.be.false;\n   *     expect(0).to.not.be.false;\n   *\n   * @name false\n   * @namespace BDD\n   * @api public\n   */\n\n  Assertion.addProperty('false', function () {\n    this.assert(\n        false === flag(this, 'object')\n      , 'expected #{this} to be false'\n      , 'expected #{this} to be true'\n      , this.negate ? true : false\n    );\n  });\n\n  /**\n   * ### .null\n   *\n   * Asserts that the target is `null`.\n   *\n   *     expect(null).to.be.null;\n   *     expect(undefined).to.not.be.null;\n   *\n   * @name null\n   * @namespace BDD\n   * @api public\n   */\n\n  Assertion.addProperty('null', function () {\n    this.assert(\n        null === flag(this, 'object')\n      , 'expected #{this} to be null'\n      , 'expected #{this} not to be null'\n    );\n  });\n\n  /**\n   * ### .undefined\n   *\n   * Asserts that the target is `undefined`.\n   *\n   *     expect(undefined).to.be.undefined;\n   *     expect(null).to.not.be.undefined;\n   *\n   * @name undefined\n   * @namespace BDD\n   * @api public\n   */\n\n  Assertion.addProperty('undefined', function () {\n    this.assert(\n        undefined === flag(this, 'object')\n      , 'expected #{this} to be undefined'\n      , 'expected #{this} not to be undefined'\n    );\n  });\n\n  /**\n   * ### .NaN\n   * Asserts that the target is `NaN`.\n   *\n   *     expect('foo').to.be.NaN;\n   *     expect(4).not.to.be.NaN;\n   *\n   * @name NaN\n   * @namespace BDD\n   * @api public\n   */\n\n  Assertion.addProperty('NaN', function () {\n    this.assert(\n        isNaN(flag(this, 'object'))\n        , 'expected #{this} to be NaN'\n        , 'expected #{this} not to be NaN'\n    );\n  });\n\n  /**\n   * ### .exist\n   *\n   * Asserts that the target is neither `null` nor `undefined`.\n   *\n   *     var foo = 'hi'\n   *       , bar = null\n   *       , baz;\n   *\n   *     expect(foo).to.exist;\n   *     expect(bar).to.not.exist;\n   *     expect(baz).to.not.exist;\n   *\n   * @name exist\n   * @namespace BDD\n   * @api public\n   */\n\n  Assertion.addProperty('exist', function () {\n    this.assert(\n        null != flag(this, 'object')\n      , 'expected #{this} to exist'\n      , 'expected #{this} to not exist'\n    );\n  });\n\n\n  /**\n   * ### .empty\n   *\n   * Asserts that the target's length is `0`. For arrays and strings, it checks\n   * the `length` property. For objects, it gets the count of\n   * enumerable keys.\n   *\n   *     expect([]).to.be.empty;\n   *     expect('').to.be.empty;\n   *     expect({}).to.be.empty;\n   *\n   * @name empty\n   * @namespace BDD\n   * @api public\n   */\n\n  Assertion.addProperty('empty', function () {\n    var obj = flag(this, 'object')\n      , expected = obj;\n\n    if (Array.isArray(obj) || 'string' === typeof object) {\n      expected = obj.length;\n    } else if (typeof obj === 'object') {\n      expected = Object.keys(obj).length;\n    }\n\n    this.assert(\n        !expected\n      , 'expected #{this} to be empty'\n      , 'expected #{this} not to be empty'\n    );\n  });\n\n  /**\n   * ### .arguments\n   *\n   * Asserts that the target is an arguments object.\n   *\n   *     function test () {\n   *       expect(arguments).to.be.arguments;\n   *     }\n   *\n   * @name arguments\n   * @alias Arguments\n   * @namespace BDD\n   * @api public\n   */\n\n  function checkArguments () {\n    var obj = flag(this, 'object')\n      , type = Object.prototype.toString.call(obj);\n    this.assert(\n        '[object Arguments]' === type\n      , 'expected #{this} to be arguments but got ' + type\n      , 'expected #{this} to not be arguments'\n    );\n  }\n\n  Assertion.addProperty('arguments', checkArguments);\n  Assertion.addProperty('Arguments', checkArguments);\n\n  /**\n   * ### .equal(value)\n   *\n   * Asserts that the target is strictly equal (`===`) to `value`.\n   * Alternately, if the `deep` flag is set, asserts that\n   * the target is deeply equal to `value`.\n   *\n   *     expect('hello').to.equal('hello');\n   *     expect(42).to.equal(42);\n   *     expect(1).to.not.equal(true);\n   *     expect({ foo: 'bar' }).to.not.equal({ foo: 'bar' });\n   *     expect({ foo: 'bar' }).to.deep.equal({ foo: 'bar' });\n   *\n   * @name equal\n   * @alias equals\n   * @alias eq\n   * @alias deep.equal\n   * @param {Mixed} value\n   * @param {String} message _optional_\n   * @namespace BDD\n   * @api public\n   */\n\n  function assertEqual (val, msg) {\n    if (msg) flag(this, 'message', msg);\n    var obj = flag(this, 'object');\n    if (flag(this, 'deep')) {\n      return this.eql(val);\n    } else {\n      this.assert(\n          val === obj\n        , 'expected #{this} to equal #{exp}'\n        , 'expected #{this} to not equal #{exp}'\n        , val\n        , this._obj\n        , true\n      );\n    }\n  }\n\n  Assertion.addMethod('equal', assertEqual);\n  Assertion.addMethod('equals', assertEqual);\n  Assertion.addMethod('eq', assertEqual);\n\n  /**\n   * ### .eql(value)\n   *\n   * Asserts that the target is deeply equal to `value`.\n   *\n   *     expect({ foo: 'bar' }).to.eql({ foo: 'bar' });\n   *     expect([ 1, 2, 3 ]).to.eql([ 1, 2, 3 ]);\n   *\n   * @name eql\n   * @alias eqls\n   * @param {Mixed} value\n   * @param {String} message _optional_\n   * @namespace BDD\n   * @api public\n   */\n\n  function assertEql(obj, msg) {\n    if (msg) flag(this, 'message', msg);\n    this.assert(\n        _.eql(obj, flag(this, 'object'))\n      , 'expected #{this} to deeply equal #{exp}'\n      , 'expected #{this} to not deeply equal #{exp}'\n      , obj\n      , this._obj\n      , true\n    );\n  }\n\n  Assertion.addMethod('eql', assertEql);\n  Assertion.addMethod('eqls', assertEql);\n\n  /**\n   * ### .above(value)\n   *\n   * Asserts that the target is greater than `value`.\n   *\n   *     expect(10).to.be.above(5);\n   *\n   * Can also be used in conjunction with `length` to\n   * assert a minimum length. The benefit being a\n   * more informative error message than if the length\n   * was supplied directly.\n   *\n   *     expect('foo').to.have.length.above(2);\n   *     expect([ 1, 2, 3 ]).to.have.length.above(2);\n   *\n   * @name above\n   * @alias gt\n   * @alias greaterThan\n   * @param {Number} value\n   * @param {String} message _optional_\n   * @namespace BDD\n   * @api public\n   */\n\n  function assertAbove (n, msg) {\n    if (msg) flag(this, 'message', msg);\n    var obj = flag(this, 'object');\n    if (flag(this, 'doLength')) {\n      new Assertion(obj, msg).to.have.property('length');\n      var len = obj.length;\n      this.assert(\n          len > n\n        , 'expected #{this} to have a length above #{exp} but got #{act}'\n        , 'expected #{this} to not have a length above #{exp}'\n        , n\n        , len\n      );\n    } else {\n      this.assert(\n          obj > n\n        , 'expected #{this} to be above ' + n\n        , 'expected #{this} to be at most ' + n\n      );\n    }\n  }\n\n  Assertion.addMethod('above', assertAbove);\n  Assertion.addMethod('gt', assertAbove);\n  Assertion.addMethod('greaterThan', assertAbove);\n\n  /**\n   * ### .least(value)\n   *\n   * Asserts that the target is greater than or equal to `value`.\n   *\n   *     expect(10).to.be.at.least(10);\n   *\n   * Can also be used in conjunction with `length` to\n   * assert a minimum length. The benefit being a\n   * more informative error message than if the length\n   * was supplied directly.\n   *\n   *     expect('foo').to.have.length.of.at.least(2);\n   *     expect([ 1, 2, 3 ]).to.have.length.of.at.least(3);\n   *\n   * @name least\n   * @alias gte\n   * @param {Number} value\n   * @param {String} message _optional_\n   * @namespace BDD\n   * @api public\n   */\n\n  function assertLeast (n, msg) {\n    if (msg) flag(this, 'message', msg);\n    var obj = flag(this, 'object');\n    if (flag(this, 'doLength')) {\n      new Assertion(obj, msg).to.have.property('length');\n      var len = obj.length;\n      this.assert(\n          len >= n\n        , 'expected #{this} to have a length at least #{exp} but got #{act}'\n        , 'expected #{this} to have a length below #{exp}'\n        , n\n        , len\n      );\n    } else {\n      this.assert(\n          obj >= n\n        , 'expected #{this} to be at least ' + n\n        , 'expected #{this} to be below ' + n\n      );\n    }\n  }\n\n  Assertion.addMethod('least', assertLeast);\n  Assertion.addMethod('gte', assertLeast);\n\n  /**\n   * ### .below(value)\n   *\n   * Asserts that the target is less than `value`.\n   *\n   *     expect(5).to.be.below(10);\n   *\n   * Can also be used in conjunction with `length` to\n   * assert a maximum length. The benefit being a\n   * more informative error message than if the length\n   * was supplied directly.\n   *\n   *     expect('foo').to.have.length.below(4);\n   *     expect([ 1, 2, 3 ]).to.have.length.below(4);\n   *\n   * @name below\n   * @alias lt\n   * @alias lessThan\n   * @param {Number} value\n   * @param {String} message _optional_\n   * @namespace BDD\n   * @api public\n   */\n\n  function assertBelow (n, msg) {\n    if (msg) flag(this, 'message', msg);\n    var obj = flag(this, 'object');\n    if (flag(this, 'doLength')) {\n      new Assertion(obj, msg).to.have.property('length');\n      var len = obj.length;\n      this.assert(\n          len < n\n        , 'expected #{this} to have a length below #{exp} but got #{act}'\n        , 'expected #{this} to not have a length below #{exp}'\n        , n\n        , len\n      );\n    } else {\n      this.assert(\n          obj < n\n        , 'expected #{this} to be below ' + n\n        , 'expected #{this} to be at least ' + n\n      );\n    }\n  }\n\n  Assertion.addMethod('below', assertBelow);\n  Assertion.addMethod('lt', assertBelow);\n  Assertion.addMethod('lessThan', assertBelow);\n\n  /**\n   * ### .most(value)\n   *\n   * Asserts that the target is less than or equal to `value`.\n   *\n   *     expect(5).to.be.at.most(5);\n   *\n   * Can also be used in conjunction with `length` to\n   * assert a maximum length. The benefit being a\n   * more informative error message than if the length\n   * was supplied directly.\n   *\n   *     expect('foo').to.have.length.of.at.most(4);\n   *     expect([ 1, 2, 3 ]).to.have.length.of.at.most(3);\n   *\n   * @name most\n   * @alias lte\n   * @param {Number} value\n   * @param {String} message _optional_\n   * @namespace BDD\n   * @api public\n   */\n\n  function assertMost (n, msg) {\n    if (msg) flag(this, 'message', msg);\n    var obj = flag(this, 'object');\n    if (flag(this, 'doLength')) {\n      new Assertion(obj, msg).to.have.property('length');\n      var len = obj.length;\n      this.assert(\n          len <= n\n        , 'expected #{this} to have a length at most #{exp} but got #{act}'\n        , 'expected #{this} to have a length above #{exp}'\n        , n\n        , len\n      );\n    } else {\n      this.assert(\n          obj <= n\n        , 'expected #{this} to be at most ' + n\n        , 'expected #{this} to be above ' + n\n      );\n    }\n  }\n\n  Assertion.addMethod('most', assertMost);\n  Assertion.addMethod('lte', assertMost);\n\n  /**\n   * ### .within(start, finish)\n   *\n   * Asserts that the target is within a range.\n   *\n   *     expect(7).to.be.within(5,10);\n   *\n   * Can also be used in conjunction with `length` to\n   * assert a length range. The benefit being a\n   * more informative error message than if the length\n   * was supplied directly.\n   *\n   *     expect('foo').to.have.length.within(2,4);\n   *     expect([ 1, 2, 3 ]).to.have.length.within(2,4);\n   *\n   * @name within\n   * @param {Number} start lowerbound inclusive\n   * @param {Number} finish upperbound inclusive\n   * @param {String} message _optional_\n   * @namespace BDD\n   * @api public\n   */\n\n  Assertion.addMethod('within', function (start, finish, msg) {\n    if (msg) flag(this, 'message', msg);\n    var obj = flag(this, 'object')\n      , range = start + '..' + finish;\n    if (flag(this, 'doLength')) {\n      new Assertion(obj, msg).to.have.property('length');\n      var len = obj.length;\n      this.assert(\n          len >= start && len <= finish\n        , 'expected #{this} to have a length within ' + range\n        , 'expected #{this} to not have a length within ' + range\n      );\n    } else {\n      this.assert(\n          obj >= start && obj <= finish\n        , 'expected #{this} to be within ' + range\n        , 'expected #{this} to not be within ' + range\n      );\n    }\n  });\n\n  /**\n   * ### .instanceof(constructor)\n   *\n   * Asserts that the target is an instance of `constructor`.\n   *\n   *     var Tea = function (name) { this.name = name; }\n   *       , Chai = new Tea('chai');\n   *\n   *     expect(Chai).to.be.an.instanceof(Tea);\n   *     expect([ 1, 2, 3 ]).to.be.instanceof(Array);\n   *\n   * @name instanceof\n   * @param {Constructor} constructor\n   * @param {String} message _optional_\n   * @alias instanceOf\n   * @namespace BDD\n   * @api public\n   */\n\n  function assertInstanceOf (constructor, msg) {\n    if (msg) flag(this, 'message', msg);\n    var name = _.getName(constructor);\n    this.assert(\n        flag(this, 'object') instanceof constructor\n      , 'expected #{this} to be an instance of ' + name\n      , 'expected #{this} to not be an instance of ' + name\n    );\n  };\n\n  Assertion.addMethod('instanceof', assertInstanceOf);\n  Assertion.addMethod('instanceOf', assertInstanceOf);\n\n  /**\n   * ### .property(name, [value])\n   *\n   * Asserts that the target has a property `name`, optionally asserting that\n   * the value of that property is strictly equal to  `value`.\n   * If the `deep` flag is set, you can use dot- and bracket-notation for deep\n   * references into objects and arrays.\n   *\n   *     // simple referencing\n   *     var obj = { foo: 'bar' };\n   *     expect(obj).to.have.property('foo');\n   *     expect(obj).to.have.property('foo', 'bar');\n   *\n   *     // deep referencing\n   *     var deepObj = {\n   *         green: { tea: 'matcha' }\n   *       , teas: [ 'chai', 'matcha', { tea: 'konacha' } ]\n   *     };\n   *\n   *     expect(deepObj).to.have.deep.property('green.tea', 'matcha');\n   *     expect(deepObj).to.have.deep.property('teas[1]', 'matcha');\n   *     expect(deepObj).to.have.deep.property('teas[2].tea', 'konacha');\n   *\n   * You can also use an array as the starting point of a `deep.property`\n   * assertion, or traverse nested arrays.\n   *\n   *     var arr = [\n   *         [ 'chai', 'matcha', 'konacha' ]\n   *       , [ { tea: 'chai' }\n   *         , { tea: 'matcha' }\n   *         , { tea: 'konacha' } ]\n   *     ];\n   *\n   *     expect(arr).to.have.deep.property('[0][1]', 'matcha');\n   *     expect(arr).to.have.deep.property('[1][2].tea', 'konacha');\n   *\n   * Furthermore, `property` changes the subject of the assertion\n   * to be the value of that property from the original object. This\n   * permits for further chainable assertions on that property.\n   *\n   *     expect(obj).to.have.property('foo')\n   *       .that.is.a('string');\n   *     expect(deepObj).to.have.property('green')\n   *       .that.is.an('object')\n   *       .that.deep.equals({ tea: 'matcha' });\n   *     expect(deepObj).to.have.property('teas')\n   *       .that.is.an('array')\n   *       .with.deep.property('[2]')\n   *         .that.deep.equals({ tea: 'konacha' });\n   *\n   * Note that dots and bracket in `name` must be backslash-escaped when\n   * the `deep` flag is set, while they must NOT be escaped when the `deep`\n   * flag is not set.\n   *\n   *     // simple referencing\n   *     var css = { '.link[target]': 42 };\n   *     expect(css).to.have.property('.link[target]', 42);\n   *\n   *     // deep referencing\n   *     var deepCss = { '.link': { '[target]': 42 }};\n   *     expect(deepCss).to.have.deep.property('\\\\.link.\\\\[target\\\\]', 42);\n   *\n   * @name property\n   * @alias deep.property\n   * @param {String} name\n   * @param {Mixed} value (optional)\n   * @param {String} message _optional_\n   * @returns value of property for chaining\n   * @namespace BDD\n   * @api public\n   */\n\n  Assertion.addMethod('property', function (name, val, msg) {\n    if (msg) flag(this, 'message', msg);\n\n    var isDeep = !!flag(this, 'deep')\n      , descriptor = isDeep ? 'deep property ' : 'property '\n      , negate = flag(this, 'negate')\n      , obj = flag(this, 'object')\n      , pathInfo = isDeep ? _.getPathInfo(name, obj) : null\n      , hasProperty = isDeep\n        ? pathInfo.exists\n        : _.hasProperty(name, obj)\n      , value = isDeep\n        ? pathInfo.value\n        : obj[name];\n\n    if (negate && arguments.length > 1) {\n      if (undefined === value) {\n        msg = (msg != null) ? msg + ': ' : '';\n        throw new Error(msg + _.inspect(obj) + ' has no ' + descriptor + _.inspect(name));\n      }\n    } else {\n      this.assert(\n          hasProperty\n        , 'expected #{this} to have a ' + descriptor + _.inspect(name)\n        , 'expected #{this} to not have ' + descriptor + _.inspect(name));\n    }\n\n    if (arguments.length > 1) {\n      this.assert(\n          val === value\n        , 'expected #{this} to have a ' + descriptor + _.inspect(name) + ' of #{exp}, but got #{act}'\n        , 'expected #{this} to not have a ' + descriptor + _.inspect(name) + ' of #{act}'\n        , val\n        , value\n      );\n    }\n\n    flag(this, 'object', value);\n  });\n\n\n  /**\n   * ### .ownProperty(name)\n   *\n   * Asserts that the target has an own property `name`.\n   *\n   *     expect('test').to.have.ownProperty('length');\n   *\n   * @name ownProperty\n   * @alias haveOwnProperty\n   * @param {String} name\n   * @param {String} message _optional_\n   * @namespace BDD\n   * @api public\n   */\n\n  function assertOwnProperty (name, msg) {\n    if (msg) flag(this, 'message', msg);\n    var obj = flag(this, 'object');\n    this.assert(\n        obj.hasOwnProperty(name)\n      , 'expected #{this} to have own property ' + _.inspect(name)\n      , 'expected #{this} to not have own property ' + _.inspect(name)\n    );\n  }\n\n  Assertion.addMethod('ownProperty', assertOwnProperty);\n  Assertion.addMethod('haveOwnProperty', assertOwnProperty);\n\n  /**\n   * ### .ownPropertyDescriptor(name[, descriptor[, message]])\n   *\n   * Asserts that the target has an own property descriptor `name`, that optionally matches `descriptor`.\n   *\n   *     expect('test').to.have.ownPropertyDescriptor('length');\n   *     expect('test').to.have.ownPropertyDescriptor('length', { enumerable: false, configurable: false, writable: false, value: 4 });\n   *     expect('test').not.to.have.ownPropertyDescriptor('length', { enumerable: false, configurable: false, writable: false, value: 3 });\n   *     expect('test').ownPropertyDescriptor('length').to.have.property('enumerable', false);\n   *     expect('test').ownPropertyDescriptor('length').to.have.keys('value');\n   *\n   * @name ownPropertyDescriptor\n   * @alias haveOwnPropertyDescriptor\n   * @param {String} name\n   * @param {Object} descriptor _optional_\n   * @param {String} message _optional_\n   * @namespace BDD\n   * @api public\n   */\n\n  function assertOwnPropertyDescriptor (name, descriptor, msg) {\n    if (typeof descriptor === 'string') {\n      msg = descriptor;\n      descriptor = null;\n    }\n    if (msg) flag(this, 'message', msg);\n    var obj = flag(this, 'object');\n    var actualDescriptor = Object.getOwnPropertyDescriptor(Object(obj), name);\n    if (actualDescriptor && descriptor) {\n      this.assert(\n          _.eql(descriptor, actualDescriptor)\n        , 'expected the own property descriptor for ' + _.inspect(name) + ' on #{this} to match ' + _.inspect(descriptor) + ', got ' + _.inspect(actualDescriptor)\n        , 'expected the own property descriptor for ' + _.inspect(name) + ' on #{this} to not match ' + _.inspect(descriptor)\n        , descriptor\n        , actualDescriptor\n        , true\n      );\n    } else {\n      this.assert(\n          actualDescriptor\n        , 'expected #{this} to have an own property descriptor for ' + _.inspect(name)\n        , 'expected #{this} to not have an own property descriptor for ' + _.inspect(name)\n      );\n    }\n    flag(this, 'object', actualDescriptor);\n  }\n\n  Assertion.addMethod('ownPropertyDescriptor', assertOwnPropertyDescriptor);\n  Assertion.addMethod('haveOwnPropertyDescriptor', assertOwnPropertyDescriptor);\n\n  /**\n   * ### .length\n   *\n   * Sets the `doLength` flag later used as a chain precursor to a value\n   * comparison for the `length` property.\n   *\n   *     expect('foo').to.have.length.above(2);\n   *     expect([ 1, 2, 3 ]).to.have.length.above(2);\n   *     expect('foo').to.have.length.below(4);\n   *     expect([ 1, 2, 3 ]).to.have.length.below(4);\n   *     expect('foo').to.have.length.within(2,4);\n   *     expect([ 1, 2, 3 ]).to.have.length.within(2,4);\n   *\n   * *Deprecation notice:* Using `length` as an assertion will be deprecated\n   * in version 2.4.0 and removed in 3.0.0. Code using the old style of\n   * asserting for `length` property value using `length(value)` should be\n   * switched to use `lengthOf(value)` instead.\n   *\n   * @name length\n   * @namespace BDD\n   * @api public\n   */\n\n  /**\n   * ### .lengthOf(value[, message])\n   *\n   * Asserts that the target's `length` property has\n   * the expected value.\n   *\n   *     expect([ 1, 2, 3]).to.have.lengthOf(3);\n   *     expect('foobar').to.have.lengthOf(6);\n   *\n   * @name lengthOf\n   * @param {Number} length\n   * @param {String} message _optional_\n   * @namespace BDD\n   * @api public\n   */\n\n  function assertLengthChain () {\n    flag(this, 'doLength', true);\n  }\n\n  function assertLength (n, msg) {\n    if (msg) flag(this, 'message', msg);\n    var obj = flag(this, 'object');\n    new Assertion(obj, msg).to.have.property('length');\n    var len = obj.length;\n\n    this.assert(\n        len == n\n      , 'expected #{this} to have a length of #{exp} but got #{act}'\n      , 'expected #{this} to not have a length of #{act}'\n      , n\n      , len\n    );\n  }\n\n  Assertion.addChainableMethod('length', assertLength, assertLengthChain);\n  Assertion.addMethod('lengthOf', assertLength);\n\n  /**\n   * ### .match(regexp)\n   *\n   * Asserts that the target matches a regular expression.\n   *\n   *     expect('foobar').to.match(/^foo/);\n   *\n   * @name match\n   * @alias matches\n   * @param {RegExp} RegularExpression\n   * @param {String} message _optional_\n   * @namespace BDD\n   * @api public\n   */\n  function assertMatch(re, msg) {\n    if (msg) flag(this, 'message', msg);\n    var obj = flag(this, 'object');\n    this.assert(\n        re.exec(obj)\n      , 'expected #{this} to match ' + re\n      , 'expected #{this} not to match ' + re\n    );\n  }\n\n  Assertion.addMethod('match', assertMatch);\n  Assertion.addMethod('matches', assertMatch);\n\n  /**\n   * ### .string(string)\n   *\n   * Asserts that the string target contains another string.\n   *\n   *     expect('foobar').to.have.string('bar');\n   *\n   * @name string\n   * @param {String} string\n   * @param {String} message _optional_\n   * @namespace BDD\n   * @api public\n   */\n\n  Assertion.addMethod('string', function (str, msg) {\n    if (msg) flag(this, 'message', msg);\n    var obj = flag(this, 'object');\n    new Assertion(obj, msg).is.a('string');\n\n    this.assert(\n        ~obj.indexOf(str)\n      , 'expected #{this} to contain ' + _.inspect(str)\n      , 'expected #{this} to not contain ' + _.inspect(str)\n    );\n  });\n\n\n  /**\n   * ### .keys(key1, [key2], [...])\n   *\n   * Asserts that the target contains any or all of the passed-in keys.\n   * Use in combination with `any`, `all`, `contains`, or `have` will affect\n   * what will pass.\n   *\n   * When used in conjunction with `any`, at least one key that is passed\n   * in must exist in the target object. This is regardless whether or not\n   * the `have` or `contain` qualifiers are used. Note, either `any` or `all`\n   * should be used in the assertion. If neither are used, the assertion is\n   * defaulted to `all`.\n   *\n   * When both `all` and `contain` are used, the target object must have at\n   * least all of the passed-in keys but may have more keys not listed.\n   *\n   * When both `all` and `have` are used, the target object must both contain\n   * all of the passed-in keys AND the number of keys in the target object must\n   * match the number of keys passed in (in other words, a target object must\n   * have all and only all of the passed-in keys).\n   *\n   *     expect({ foo: 1, bar: 2 }).to.have.any.keys('foo', 'baz');\n   *     expect({ foo: 1, bar: 2 }).to.have.any.keys('foo');\n   *     expect({ foo: 1, bar: 2 }).to.contain.any.keys('bar', 'baz');\n   *     expect({ foo: 1, bar: 2 }).to.contain.any.keys(['foo']);\n   *     expect({ foo: 1, bar: 2 }).to.contain.any.keys({'foo': 6});\n   *     expect({ foo: 1, bar: 2 }).to.have.all.keys(['bar', 'foo']);\n   *     expect({ foo: 1, bar: 2 }).to.have.all.keys({'bar': 6, 'foo': 7});\n   *     expect({ foo: 1, bar: 2, baz: 3 }).to.contain.all.keys(['bar', 'foo']);\n   *     expect({ foo: 1, bar: 2, baz: 3 }).to.contain.all.keys({'bar': 6});\n   *\n   *\n   * @name keys\n   * @alias key\n   * @param {...String|Array|Object} keys\n   * @namespace BDD\n   * @api public\n   */\n\n  function assertKeys (keys) {\n    var obj = flag(this, 'object')\n      , str\n      , ok = true\n      , mixedArgsMsg = 'keys must be given single argument of Array|Object|String, or multiple String arguments';\n\n    switch (_.type(keys)) {\n      case \"array\":\n        if (arguments.length > 1) throw (new Error(mixedArgsMsg));\n        break;\n      case \"object\":\n        if (arguments.length > 1) throw (new Error(mixedArgsMsg));\n        keys = Object.keys(keys);\n        break;\n      default:\n        keys = Array.prototype.slice.call(arguments);\n    }\n\n    if (!keys.length) throw new Error('keys required');\n\n    var actual = Object.keys(obj)\n      , expected = keys\n      , len = keys.length\n      , any = flag(this, 'any')\n      , all = flag(this, 'all');\n\n    if (!any && !all) {\n      all = true;\n    }\n\n    // Has any\n    if (any) {\n      var intersection = expected.filter(function(key) {\n        return ~actual.indexOf(key);\n      });\n      ok = intersection.length > 0;\n    }\n\n    // Has all\n    if (all) {\n      ok = keys.every(function(key){\n        return ~actual.indexOf(key);\n      });\n      if (!flag(this, 'negate') && !flag(this, 'contains')) {\n        ok = ok && keys.length == actual.length;\n      }\n    }\n\n    // Key string\n    if (len > 1) {\n      keys = keys.map(function(key){\n        return _.inspect(key);\n      });\n      var last = keys.pop();\n      if (all) {\n        str = keys.join(', ') + ', and ' + last;\n      }\n      if (any) {\n        str = keys.join(', ') + ', or ' + last;\n      }\n    } else {\n      str = _.inspect(keys[0]);\n    }\n\n    // Form\n    str = (len > 1 ? 'keys ' : 'key ') + str;\n\n    // Have / include\n    str = (flag(this, 'contains') ? 'contain ' : 'have ') + str;\n\n    // Assertion\n    this.assert(\n        ok\n      , 'expected #{this} to ' + str\n      , 'expected #{this} to not ' + str\n      , expected.slice(0).sort()\n      , actual.sort()\n      , true\n    );\n  }\n\n  Assertion.addMethod('keys', assertKeys);\n  Assertion.addMethod('key', assertKeys);\n\n  /**\n   * ### .throw(constructor)\n   *\n   * Asserts that the function target will throw a specific error, or specific type of error\n   * (as determined using `instanceof`), optionally with a RegExp or string inclusion test\n   * for the error's message.\n   *\n   *     var err = new ReferenceError('This is a bad function.');\n   *     var fn = function () { throw err; }\n   *     expect(fn).to.throw(ReferenceError);\n   *     expect(fn).to.throw(Error);\n   *     expect(fn).to.throw(/bad function/);\n   *     expect(fn).to.not.throw('good function');\n   *     expect(fn).to.throw(ReferenceError, /bad function/);\n   *     expect(fn).to.throw(err);\n   *\n   * Please note that when a throw expectation is negated, it will check each\n   * parameter independently, starting with error constructor type. The appropriate way\n   * to check for the existence of a type of error but for a message that does not match\n   * is to use `and`.\n   *\n   *     expect(fn).to.throw(ReferenceError)\n   *        .and.not.throw(/good function/);\n   *\n   * @name throw\n   * @alias throws\n   * @alias Throw\n   * @param {ErrorConstructor} constructor\n   * @param {String|RegExp} expected error message\n   * @param {String} message _optional_\n   * @see https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Error#Error_types\n   * @returns error for chaining (null if no error)\n   * @namespace BDD\n   * @api public\n   */\n\n  function assertThrows (constructor, errMsg, msg) {\n    if (msg) flag(this, 'message', msg);\n    var obj = flag(this, 'object');\n    new Assertion(obj, msg).is.a('function');\n\n    var thrown = false\n      , desiredError = null\n      , name = null\n      , thrownError = null;\n\n    if (arguments.length === 0) {\n      errMsg = null;\n      constructor = null;\n    } else if (constructor && (constructor instanceof RegExp || 'string' === typeof constructor)) {\n      errMsg = constructor;\n      constructor = null;\n    } else if (constructor && constructor instanceof Error) {\n      desiredError = constructor;\n      constructor = null;\n      errMsg = null;\n    } else if (typeof constructor === 'function') {\n      name = constructor.prototype.name;\n      if (!name || (name === 'Error' && constructor !== Error)) {\n        name = constructor.name || (new constructor()).name;\n      }\n    } else {\n      constructor = null;\n    }\n\n    try {\n      obj();\n    } catch (err) {\n      // first, check desired error\n      if (desiredError) {\n        this.assert(\n            err === desiredError\n          , 'expected #{this} to throw #{exp} but #{act} was thrown'\n          , 'expected #{this} to not throw #{exp}'\n          , (desiredError instanceof Error ? desiredError.toString() : desiredError)\n          , (err instanceof Error ? err.toString() : err)\n        );\n\n        flag(this, 'object', err);\n        return this;\n      }\n\n      // next, check constructor\n      if (constructor) {\n        this.assert(\n            err instanceof constructor\n          , 'expected #{this} to throw #{exp} but #{act} was thrown'\n          , 'expected #{this} to not throw #{exp} but #{act} was thrown'\n          , name\n          , (err instanceof Error ? err.toString() : err)\n        );\n\n        if (!errMsg) {\n          flag(this, 'object', err);\n          return this;\n        }\n      }\n\n      // next, check message\n      var message = 'error' === _.type(err) && \"message\" in err\n        ? err.message\n        : '' + err;\n\n      if ((message != null) && errMsg && errMsg instanceof RegExp) {\n        this.assert(\n            errMsg.exec(message)\n          , 'expected #{this} to throw error matching #{exp} but got #{act}'\n          , 'expected #{this} to throw error not matching #{exp}'\n          , errMsg\n          , message\n        );\n\n        flag(this, 'object', err);\n        return this;\n      } else if ((message != null) && errMsg && 'string' === typeof errMsg) {\n        this.assert(\n            ~message.indexOf(errMsg)\n          , 'expected #{this} to throw error including #{exp} but got #{act}'\n          , 'expected #{this} to throw error not including #{act}'\n          , errMsg\n          , message\n        );\n\n        flag(this, 'object', err);\n        return this;\n      } else {\n        thrown = true;\n        thrownError = err;\n      }\n    }\n\n    var actuallyGot = ''\n      , expectedThrown = name !== null\n        ? name\n        : desiredError\n          ? '#{exp}' //_.inspect(desiredError)\n          : 'an error';\n\n    if (thrown) {\n      actuallyGot = ' but #{act} was thrown'\n    }\n\n    this.assert(\n        thrown === true\n      , 'expected #{this} to throw ' + expectedThrown + actuallyGot\n      , 'expected #{this} to not throw ' + expectedThrown + actuallyGot\n      , (desiredError instanceof Error ? desiredError.toString() : desiredError)\n      , (thrownError instanceof Error ? thrownError.toString() : thrownError)\n    );\n\n    flag(this, 'object', thrownError);\n  };\n\n  Assertion.addMethod('throw', assertThrows);\n  Assertion.addMethod('throws', assertThrows);\n  Assertion.addMethod('Throw', assertThrows);\n\n  /**\n   * ### .respondTo(method)\n   *\n   * Asserts that the object or class target will respond to a method.\n   *\n   *     Klass.prototype.bar = function(){};\n   *     expect(Klass).to.respondTo('bar');\n   *     expect(obj).to.respondTo('bar');\n   *\n   * To check if a constructor will respond to a static function,\n   * set the `itself` flag.\n   *\n   *     Klass.baz = function(){};\n   *     expect(Klass).itself.to.respondTo('baz');\n   *\n   * @name respondTo\n   * @alias respondsTo\n   * @param {String} method\n   * @param {String} message _optional_\n   * @namespace BDD\n   * @api public\n   */\n\n  function respondTo (method, msg) {\n    if (msg) flag(this, 'message', msg);\n    var obj = flag(this, 'object')\n      , itself = flag(this, 'itself')\n      , context = ('function' === _.type(obj) && !itself)\n        ? obj.prototype[method]\n        : obj[method];\n\n    this.assert(\n        'function' === typeof context\n      , 'expected #{this} to respond to ' + _.inspect(method)\n      , 'expected #{this} to not respond to ' + _.inspect(method)\n    );\n  }\n\n  Assertion.addMethod('respondTo', respondTo);\n  Assertion.addMethod('respondsTo', respondTo);\n\n  /**\n   * ### .itself\n   *\n   * Sets the `itself` flag, later used by the `respondTo` assertion.\n   *\n   *     function Foo() {}\n   *     Foo.bar = function() {}\n   *     Foo.prototype.baz = function() {}\n   *\n   *     expect(Foo).itself.to.respondTo('bar');\n   *     expect(Foo).itself.not.to.respondTo('baz');\n   *\n   * @name itself\n   * @namespace BDD\n   * @api public\n   */\n\n  Assertion.addProperty('itself', function () {\n    flag(this, 'itself', true);\n  });\n\n  /**\n   * ### .satisfy(method)\n   *\n   * Asserts that the target passes a given truth test.\n   *\n   *     expect(1).to.satisfy(function(num) { return num > 0; });\n   *\n   * @name satisfy\n   * @alias satisfies\n   * @param {Function} matcher\n   * @param {String} message _optional_\n   * @namespace BDD\n   * @api public\n   */\n\n  function satisfy (matcher, msg) {\n    if (msg) flag(this, 'message', msg);\n    var obj = flag(this, 'object');\n    var result = matcher(obj);\n    this.assert(\n        result\n      , 'expected #{this} to satisfy ' + _.objDisplay(matcher)\n      , 'expected #{this} to not satisfy' + _.objDisplay(matcher)\n      , this.negate ? false : true\n      , result\n    );\n  }\n\n  Assertion.addMethod('satisfy', satisfy);\n  Assertion.addMethod('satisfies', satisfy);\n\n  /**\n   * ### .closeTo(expected, delta)\n   *\n   * Asserts that the target is equal `expected`, to within a +/- `delta` range.\n   *\n   *     expect(1.5).to.be.closeTo(1, 0.5);\n   *\n   * @name closeTo\n   * @alias approximately\n   * @param {Number} expected\n   * @param {Number} delta\n   * @param {String} message _optional_\n   * @namespace BDD\n   * @api public\n   */\n\n  function closeTo(expected, delta, msg) {\n    if (msg) flag(this, 'message', msg);\n    var obj = flag(this, 'object');\n\n    new Assertion(obj, msg).is.a('number');\n    if (_.type(expected) !== 'number' || _.type(delta) !== 'number') {\n      throw new Error('the arguments to closeTo or approximately must be numbers');\n    }\n\n    this.assert(\n        Math.abs(obj - expected) <= delta\n      , 'expected #{this} to be close to ' + expected + ' +/- ' + delta\n      , 'expected #{this} not to be close to ' + expected + ' +/- ' + delta\n    );\n  }\n\n  Assertion.addMethod('closeTo', closeTo);\n  Assertion.addMethod('approximately', closeTo);\n\n  function isSubsetOf(subset, superset, cmp) {\n    return subset.every(function(elem) {\n      if (!cmp) return superset.indexOf(elem) !== -1;\n\n      return superset.some(function(elem2) {\n        return cmp(elem, elem2);\n      });\n    })\n  }\n\n  /**\n   * ### .members(set)\n   *\n   * Asserts that the target is a superset of `set`,\n   * or that the target and `set` have the same strictly-equal (===) members.\n   * Alternately, if the `deep` flag is set, set members are compared for deep\n   * equality.\n   *\n   *     expect([1, 2, 3]).to.include.members([3, 2]);\n   *     expect([1, 2, 3]).to.not.include.members([3, 2, 8]);\n   *\n   *     expect([4, 2]).to.have.members([2, 4]);\n   *     expect([5, 2]).to.not.have.members([5, 2, 1]);\n   *\n   *     expect([{ id: 1 }]).to.deep.include.members([{ id: 1 }]);\n   *\n   * @name members\n   * @param {Array} set\n   * @param {String} message _optional_\n   * @namespace BDD\n   * @api public\n   */\n\n  Assertion.addMethod('members', function (subset, msg) {\n    if (msg) flag(this, 'message', msg);\n    var obj = flag(this, 'object');\n\n    new Assertion(obj).to.be.an('array');\n    new Assertion(subset).to.be.an('array');\n\n    var cmp = flag(this, 'deep') ? _.eql : undefined;\n\n    if (flag(this, 'contains')) {\n      return this.assert(\n          isSubsetOf(subset, obj, cmp)\n        , 'expected #{this} to be a superset of #{act}'\n        , 'expected #{this} to not be a superset of #{act}'\n        , obj\n        , subset\n      );\n    }\n\n    this.assert(\n        isSubsetOf(obj, subset, cmp) && isSubsetOf(subset, obj, cmp)\n        , 'expected #{this} to have the same members as #{act}'\n        , 'expected #{this} to not have the same members as #{act}'\n        , obj\n        , subset\n    );\n  });\n\n  /**\n   * ### .oneOf(list)\n   *\n   * Assert that a value appears somewhere in the top level of array `list`.\n   *\n   *     expect('a').to.be.oneOf(['a', 'b', 'c']);\n   *     expect(9).to.not.be.oneOf(['z']);\n   *     expect([3]).to.not.be.oneOf([1, 2, [3]]);\n   *\n   *     var three = [3];\n   *     // for object-types, contents are not compared\n   *     expect(three).to.not.be.oneOf([1, 2, [3]]);\n   *     // comparing references works\n   *     expect(three).to.be.oneOf([1, 2, three]);\n   *\n   * @name oneOf\n   * @param {Array<*>} list\n   * @param {String} message _optional_\n   * @namespace BDD\n   * @api public\n   */\n\n  function oneOf (list, msg) {\n    if (msg) flag(this, 'message', msg);\n    var expected = flag(this, 'object');\n    new Assertion(list).to.be.an('array');\n\n    this.assert(\n        list.indexOf(expected) > -1\n      , 'expected #{this} to be one of #{exp}'\n      , 'expected #{this} to not be one of #{exp}'\n      , list\n      , expected\n    );\n  }\n\n  Assertion.addMethod('oneOf', oneOf);\n\n\n  /**\n   * ### .change(function)\n   *\n   * Asserts that a function changes an object property\n   *\n   *     var obj = { val: 10 };\n   *     var fn = function() { obj.val += 3 };\n   *     var noChangeFn = function() { return 'foo' + 'bar'; }\n   *     expect(fn).to.change(obj, 'val');\n   *     expect(noChangeFn).to.not.change(obj, 'val')\n   *\n   * @name change\n   * @alias changes\n   * @alias Change\n   * @param {String} object\n   * @param {String} property name\n   * @param {String} message _optional_\n   * @namespace BDD\n   * @api public\n   */\n\n  function assertChanges (object, prop, msg) {\n    if (msg) flag(this, 'message', msg);\n    var fn = flag(this, 'object');\n    new Assertion(object, msg).to.have.property(prop);\n    new Assertion(fn).is.a('function');\n\n    var initial = object[prop];\n    fn();\n\n    this.assert(\n      initial !== object[prop]\n      , 'expected .' + prop + ' to change'\n      , 'expected .' + prop + ' to not change'\n    );\n  }\n\n  Assertion.addChainableMethod('change', assertChanges);\n  Assertion.addChainableMethod('changes', assertChanges);\n\n  /**\n   * ### .increase(function)\n   *\n   * Asserts that a function increases an object property\n   *\n   *     var obj = { val: 10 };\n   *     var fn = function() { obj.val = 15 };\n   *     expect(fn).to.increase(obj, 'val');\n   *\n   * @name increase\n   * @alias increases\n   * @alias Increase\n   * @param {String} object\n   * @param {String} property name\n   * @param {String} message _optional_\n   * @namespace BDD\n   * @api public\n   */\n\n  function assertIncreases (object, prop, msg) {\n    if (msg) flag(this, 'message', msg);\n    var fn = flag(this, 'object');\n    new Assertion(object, msg).to.have.property(prop);\n    new Assertion(fn).is.a('function');\n\n    var initial = object[prop];\n    fn();\n\n    this.assert(\n      object[prop] - initial > 0\n      , 'expected .' + prop + ' to increase'\n      , 'expected .' + prop + ' to not increase'\n    );\n  }\n\n  Assertion.addChainableMethod('increase', assertIncreases);\n  Assertion.addChainableMethod('increases', assertIncreases);\n\n  /**\n   * ### .decrease(function)\n   *\n   * Asserts that a function decreases an object property\n   *\n   *     var obj = { val: 10 };\n   *     var fn = function() { obj.val = 5 };\n   *     expect(fn).to.decrease(obj, 'val');\n   *\n   * @name decrease\n   * @alias decreases\n   * @alias Decrease\n   * @param {String} object\n   * @param {String} property name\n   * @param {String} message _optional_\n   * @namespace BDD\n   * @api public\n   */\n\n  function assertDecreases (object, prop, msg) {\n    if (msg) flag(this, 'message', msg);\n    var fn = flag(this, 'object');\n    new Assertion(object, msg).to.have.property(prop);\n    new Assertion(fn).is.a('function');\n\n    var initial = object[prop];\n    fn();\n\n    this.assert(\n      object[prop] - initial < 0\n      , 'expected .' + prop + ' to decrease'\n      , 'expected .' + prop + ' to not decrease'\n    );\n  }\n\n  Assertion.addChainableMethod('decrease', assertDecreases);\n  Assertion.addChainableMethod('decreases', assertDecreases);\n\n  /**\n   * ### .extensible\n   *\n   * Asserts that the target is extensible (can have new properties added to\n   * it).\n   *\n   *     var nonExtensibleObject = Object.preventExtensions({});\n   *     var sealedObject = Object.seal({});\n   *     var frozenObject = Object.freeze({});\n   *\n   *     expect({}).to.be.extensible;\n   *     expect(nonExtensibleObject).to.not.be.extensible;\n   *     expect(sealedObject).to.not.be.extensible;\n   *     expect(frozenObject).to.not.be.extensible;\n   *\n   * @name extensible\n   * @namespace BDD\n   * @api public\n   */\n\n  Assertion.addProperty('extensible', function() {\n    var obj = flag(this, 'object');\n\n    // In ES5, if the argument to this method is not an object (a primitive), then it will cause a TypeError.\n    // In ES6, a non-object argument will be treated as if it was a non-extensible ordinary object, simply return false.\n    // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/isExtensible\n    // The following provides ES6 behavior when a TypeError is thrown under ES5.\n\n    var isExtensible;\n\n    try {\n      isExtensible = Object.isExtensible(obj);\n    } catch (err) {\n      if (err instanceof TypeError) isExtensible = false;\n      else throw err;\n    }\n\n    this.assert(\n      isExtensible\n      , 'expected #{this} to be extensible'\n      , 'expected #{this} to not be extensible'\n    );\n  });\n\n  /**\n   * ### .sealed\n   *\n   * Asserts that the target is sealed (cannot have new properties added to it\n   * and its existing properties cannot be removed).\n   *\n   *     var sealedObject = Object.seal({});\n   *     var frozenObject = Object.freeze({});\n   *\n   *     expect(sealedObject).to.be.sealed;\n   *     expect(frozenObject).to.be.sealed;\n   *     expect({}).to.not.be.sealed;\n   *\n   * @name sealed\n   * @namespace BDD\n   * @api public\n   */\n\n  Assertion.addProperty('sealed', function() {\n    var obj = flag(this, 'object');\n\n    // In ES5, if the argument to this method is not an object (a primitive), then it will cause a TypeError.\n    // In ES6, a non-object argument will be treated as if it was a sealed ordinary object, simply return true.\n    // See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/isSealed\n    // The following provides ES6 behavior when a TypeError is thrown under ES5.\n\n    var isSealed;\n\n    try {\n      isSealed = Object.isSealed(obj);\n    } catch (err) {\n      if (err instanceof TypeError) isSealed = true;\n      else throw err;\n    }\n\n    this.assert(\n      isSealed\n      , 'expected #{this} to be sealed'\n      , 'expected #{this} to not be sealed'\n    );\n  });\n\n  /**\n   * ### .frozen\n   *\n   * Asserts that the target is frozen (cannot have new properties added to it\n   * and its existing properties cannot be modified).\n   *\n   *     var frozenObject = Object.freeze({});\n   *\n   *     expect(frozenObject).to.be.frozen;\n   *     expect({}).to.not.be.frozen;\n   *\n   * @name frozen\n   * @namespace BDD\n   * @api public\n   */\n\n  Assertion.addProperty('frozen', function() {\n    var obj = flag(this, 'object');\n\n    // In ES5, if the argument to this method is not an object (a primitive), then it will cause a TypeError.\n    // In ES6, a non-object argument will be treated as if it was a frozen ordinary object, simply return true.\n    // See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/isFrozen\n    // The following provides ES6 behavior when a TypeError is thrown under ES5.\n\n    var isFrozen;\n\n    try {\n      isFrozen = Object.isFrozen(obj);\n    } catch (err) {\n      if (err instanceof TypeError) isFrozen = true;\n      else throw err;\n    }\n\n    this.assert(\n      isFrozen\n      , 'expected #{this} to be frozen'\n      , 'expected #{this} to not be frozen'\n    );\n  });\n};\n\n},{}],6:[function(require,module,exports){\n/*!\n * chai\n * Copyright(c) 2011-2014 Jake Luer <jake@alogicalparadox.com>\n * MIT Licensed\n */\n\n\nmodule.exports = function (chai, util) {\n\n  /*!\n   * Chai dependencies.\n   */\n\n  var Assertion = chai.Assertion\n    , flag = util.flag;\n\n  /*!\n   * Module export.\n   */\n\n  /**\n   * ### assert(expression, message)\n   *\n   * Write your own test expressions.\n   *\n   *     assert('foo' !== 'bar', 'foo is not bar');\n   *     assert(Array.isArray([]), 'empty arrays are arrays');\n   *\n   * @param {Mixed} expression to test for truthiness\n   * @param {String} message to display on error\n   * @name assert\n   * @namespace Assert\n   * @api public\n   */\n\n  var assert = chai.assert = function (express, errmsg) {\n    var test = new Assertion(null, null, chai.assert);\n    test.assert(\n        express\n      , errmsg\n      , '[ negation message unavailable ]'\n    );\n  };\n\n  /**\n   * ### .fail(actual, expected, [message], [operator])\n   *\n   * Throw a failure. Node.js `assert` module-compatible.\n   *\n   * @name fail\n   * @param {Mixed} actual\n   * @param {Mixed} expected\n   * @param {String} message\n   * @param {String} operator\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.fail = function (actual, expected, message, operator) {\n    message = message || 'assert.fail()';\n    throw new chai.AssertionError(message, {\n        actual: actual\n      , expected: expected\n      , operator: operator\n    }, assert.fail);\n  };\n\n  /**\n   * ### .isOk(object, [message])\n   *\n   * Asserts that `object` is truthy.\n   *\n   *     assert.isOk('everything', 'everything is ok');\n   *     assert.isOk(false, 'this will fail');\n   *\n   * @name isOk\n   * @alias ok\n   * @param {Mixed} object to test\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.isOk = function (val, msg) {\n    new Assertion(val, msg).is.ok;\n  };\n\n  /**\n   * ### .isNotOk(object, [message])\n   *\n   * Asserts that `object` is falsy.\n   *\n   *     assert.isNotOk('everything', 'this will fail');\n   *     assert.isNotOk(false, 'this will pass');\n   *\n   * @name isNotOk\n   * @alias notOk\n   * @param {Mixed} object to test\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.isNotOk = function (val, msg) {\n    new Assertion(val, msg).is.not.ok;\n  };\n\n  /**\n   * ### .equal(actual, expected, [message])\n   *\n   * Asserts non-strict equality (`==`) of `actual` and `expected`.\n   *\n   *     assert.equal(3, '3', '== coerces values to strings');\n   *\n   * @name equal\n   * @param {Mixed} actual\n   * @param {Mixed} expected\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.equal = function (act, exp, msg) {\n    var test = new Assertion(act, msg, assert.equal);\n\n    test.assert(\n        exp == flag(test, 'object')\n      , 'expected #{this} to equal #{exp}'\n      , 'expected #{this} to not equal #{act}'\n      , exp\n      , act\n    );\n  };\n\n  /**\n   * ### .notEqual(actual, expected, [message])\n   *\n   * Asserts non-strict inequality (`!=`) of `actual` and `expected`.\n   *\n   *     assert.notEqual(3, 4, 'these numbers are not equal');\n   *\n   * @name notEqual\n   * @param {Mixed} actual\n   * @param {Mixed} expected\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.notEqual = function (act, exp, msg) {\n    var test = new Assertion(act, msg, assert.notEqual);\n\n    test.assert(\n        exp != flag(test, 'object')\n      , 'expected #{this} to not equal #{exp}'\n      , 'expected #{this} to equal #{act}'\n      , exp\n      , act\n    );\n  };\n\n  /**\n   * ### .strictEqual(actual, expected, [message])\n   *\n   * Asserts strict equality (`===`) of `actual` and `expected`.\n   *\n   *     assert.strictEqual(true, true, 'these booleans are strictly equal');\n   *\n   * @name strictEqual\n   * @param {Mixed} actual\n   * @param {Mixed} expected\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.strictEqual = function (act, exp, msg) {\n    new Assertion(act, msg).to.equal(exp);\n  };\n\n  /**\n   * ### .notStrictEqual(actual, expected, [message])\n   *\n   * Asserts strict inequality (`!==`) of `actual` and `expected`.\n   *\n   *     assert.notStrictEqual(3, '3', 'no coercion for strict equality');\n   *\n   * @name notStrictEqual\n   * @param {Mixed} actual\n   * @param {Mixed} expected\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.notStrictEqual = function (act, exp, msg) {\n    new Assertion(act, msg).to.not.equal(exp);\n  };\n\n  /**\n   * ### .deepEqual(actual, expected, [message])\n   *\n   * Asserts that `actual` is deeply equal to `expected`.\n   *\n   *     assert.deepEqual({ tea: 'green' }, { tea: 'green' });\n   *\n   * @name deepEqual\n   * @param {Mixed} actual\n   * @param {Mixed} expected\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.deepEqual = function (act, exp, msg) {\n    new Assertion(act, msg).to.eql(exp);\n  };\n\n  /**\n   * ### .notDeepEqual(actual, expected, [message])\n   *\n   * Assert that `actual` is not deeply equal to `expected`.\n   *\n   *     assert.notDeepEqual({ tea: 'green' }, { tea: 'jasmine' });\n   *\n   * @name notDeepEqual\n   * @param {Mixed} actual\n   * @param {Mixed} expected\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.notDeepEqual = function (act, exp, msg) {\n    new Assertion(act, msg).to.not.eql(exp);\n  };\n\n   /**\n   * ### .isAbove(valueToCheck, valueToBeAbove, [message])\n   *\n   * Asserts `valueToCheck` is strictly greater than (>) `valueToBeAbove`\n   *\n   *     assert.isAbove(5, 2, '5 is strictly greater than 2');\n   *\n   * @name isAbove\n   * @param {Mixed} valueToCheck\n   * @param {Mixed} valueToBeAbove\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.isAbove = function (val, abv, msg) {\n    new Assertion(val, msg).to.be.above(abv);\n  };\n\n   /**\n   * ### .isAtLeast(valueToCheck, valueToBeAtLeast, [message])\n   *\n   * Asserts `valueToCheck` is greater than or equal to (>=) `valueToBeAtLeast`\n   *\n   *     assert.isAtLeast(5, 2, '5 is greater or equal to 2');\n   *     assert.isAtLeast(3, 3, '3 is greater or equal to 3');\n   *\n   * @name isAtLeast\n   * @param {Mixed} valueToCheck\n   * @param {Mixed} valueToBeAtLeast\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.isAtLeast = function (val, atlst, msg) {\n    new Assertion(val, msg).to.be.least(atlst);\n  };\n\n   /**\n   * ### .isBelow(valueToCheck, valueToBeBelow, [message])\n   *\n   * Asserts `valueToCheck` is strictly less than (<) `valueToBeBelow`\n   *\n   *     assert.isBelow(3, 6, '3 is strictly less than 6');\n   *\n   * @name isBelow\n   * @param {Mixed} valueToCheck\n   * @param {Mixed} valueToBeBelow\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.isBelow = function (val, blw, msg) {\n    new Assertion(val, msg).to.be.below(blw);\n  };\n\n   /**\n   * ### .isAtMost(valueToCheck, valueToBeAtMost, [message])\n   *\n   * Asserts `valueToCheck` is less than or equal to (<=) `valueToBeAtMost`\n   *\n   *     assert.isAtMost(3, 6, '3 is less than or equal to 6');\n   *     assert.isAtMost(4, 4, '4 is less than or equal to 4');\n   *\n   * @name isAtMost\n   * @param {Mixed} valueToCheck\n   * @param {Mixed} valueToBeAtMost\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.isAtMost = function (val, atmst, msg) {\n    new Assertion(val, msg).to.be.most(atmst);\n  };\n\n  /**\n   * ### .isTrue(value, [message])\n   *\n   * Asserts that `value` is true.\n   *\n   *     var teaServed = true;\n   *     assert.isTrue(teaServed, 'the tea has been served');\n   *\n   * @name isTrue\n   * @param {Mixed} value\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.isTrue = function (val, msg) {\n    new Assertion(val, msg).is['true'];\n  };\n\n  /**\n   * ### .isNotTrue(value, [message])\n   *\n   * Asserts that `value` is not true.\n   *\n   *     var tea = 'tasty chai';\n   *     assert.isNotTrue(tea, 'great, time for tea!');\n   *\n   * @name isNotTrue\n   * @param {Mixed} value\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.isNotTrue = function (val, msg) {\n    new Assertion(val, msg).to.not.equal(true);\n  };\n\n  /**\n   * ### .isFalse(value, [message])\n   *\n   * Asserts that `value` is false.\n   *\n   *     var teaServed = false;\n   *     assert.isFalse(teaServed, 'no tea yet? hmm...');\n   *\n   * @name isFalse\n   * @param {Mixed} value\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.isFalse = function (val, msg) {\n    new Assertion(val, msg).is['false'];\n  };\n\n  /**\n   * ### .isNotFalse(value, [message])\n   *\n   * Asserts that `value` is not false.\n   *\n   *     var tea = 'tasty chai';\n   *     assert.isNotFalse(tea, 'great, time for tea!');\n   *\n   * @name isNotFalse\n   * @param {Mixed} value\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.isNotFalse = function (val, msg) {\n    new Assertion(val, msg).to.not.equal(false);\n  };\n\n  /**\n   * ### .isNull(value, [message])\n   *\n   * Asserts that `value` is null.\n   *\n   *     assert.isNull(err, 'there was no error');\n   *\n   * @name isNull\n   * @param {Mixed} value\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.isNull = function (val, msg) {\n    new Assertion(val, msg).to.equal(null);\n  };\n\n  /**\n   * ### .isNotNull(value, [message])\n   *\n   * Asserts that `value` is not null.\n   *\n   *     var tea = 'tasty chai';\n   *     assert.isNotNull(tea, 'great, time for tea!');\n   *\n   * @name isNotNull\n   * @param {Mixed} value\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.isNotNull = function (val, msg) {\n    new Assertion(val, msg).to.not.equal(null);\n  };\n\n  /**\n   * ### .isNaN\n   * Asserts that value is NaN\n   *\n   *    assert.isNaN('foo', 'foo is NaN');\n   *\n   * @name isNaN\n   * @param {Mixed} value\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.isNaN = function (val, msg) {\n    new Assertion(val, msg).to.be.NaN;\n  };\n\n  /**\n   * ### .isNotNaN\n   * Asserts that value is not NaN\n   *\n   *    assert.isNotNaN(4, '4 is not NaN');\n   *\n   * @name isNotNaN\n   * @param {Mixed} value\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n  assert.isNotNaN = function (val, msg) {\n    new Assertion(val, msg).not.to.be.NaN;\n  };\n\n  /**\n   * ### .isUndefined(value, [message])\n   *\n   * Asserts that `value` is `undefined`.\n   *\n   *     var tea;\n   *     assert.isUndefined(tea, 'no tea defined');\n   *\n   * @name isUndefined\n   * @param {Mixed} value\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.isUndefined = function (val, msg) {\n    new Assertion(val, msg).to.equal(undefined);\n  };\n\n  /**\n   * ### .isDefined(value, [message])\n   *\n   * Asserts that `value` is not `undefined`.\n   *\n   *     var tea = 'cup of chai';\n   *     assert.isDefined(tea, 'tea has been defined');\n   *\n   * @name isDefined\n   * @param {Mixed} value\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.isDefined = function (val, msg) {\n    new Assertion(val, msg).to.not.equal(undefined);\n  };\n\n  /**\n   * ### .isFunction(value, [message])\n   *\n   * Asserts that `value` is a function.\n   *\n   *     function serveTea() { return 'cup of tea'; };\n   *     assert.isFunction(serveTea, 'great, we can have tea now');\n   *\n   * @name isFunction\n   * @param {Mixed} value\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.isFunction = function (val, msg) {\n    new Assertion(val, msg).to.be.a('function');\n  };\n\n  /**\n   * ### .isNotFunction(value, [message])\n   *\n   * Asserts that `value` is _not_ a function.\n   *\n   *     var serveTea = [ 'heat', 'pour', 'sip' ];\n   *     assert.isNotFunction(serveTea, 'great, we have listed the steps');\n   *\n   * @name isNotFunction\n   * @param {Mixed} value\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.isNotFunction = function (val, msg) {\n    new Assertion(val, msg).to.not.be.a('function');\n  };\n\n  /**\n   * ### .isObject(value, [message])\n   *\n   * Asserts that `value` is an object of type 'Object' (as revealed by `Object.prototype.toString`).\n   * _The assertion does not match subclassed objects._\n   *\n   *     var selection = { name: 'Chai', serve: 'with spices' };\n   *     assert.isObject(selection, 'tea selection is an object');\n   *\n   * @name isObject\n   * @param {Mixed} value\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.isObject = function (val, msg) {\n    new Assertion(val, msg).to.be.a('object');\n  };\n\n  /**\n   * ### .isNotObject(value, [message])\n   *\n   * Asserts that `value` is _not_ an object of type 'Object' (as revealed by `Object.prototype.toString`).\n   *\n   *     var selection = 'chai'\n   *     assert.isNotObject(selection, 'tea selection is not an object');\n   *     assert.isNotObject(null, 'null is not an object');\n   *\n   * @name isNotObject\n   * @param {Mixed} value\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.isNotObject = function (val, msg) {\n    new Assertion(val, msg).to.not.be.a('object');\n  };\n\n  /**\n   * ### .isArray(value, [message])\n   *\n   * Asserts that `value` is an array.\n   *\n   *     var menu = [ 'green', 'chai', 'oolong' ];\n   *     assert.isArray(menu, 'what kind of tea do we want?');\n   *\n   * @name isArray\n   * @param {Mixed} value\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.isArray = function (val, msg) {\n    new Assertion(val, msg).to.be.an('array');\n  };\n\n  /**\n   * ### .isNotArray(value, [message])\n   *\n   * Asserts that `value` is _not_ an array.\n   *\n   *     var menu = 'green|chai|oolong';\n   *     assert.isNotArray(menu, 'what kind of tea do we want?');\n   *\n   * @name isNotArray\n   * @param {Mixed} value\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.isNotArray = function (val, msg) {\n    new Assertion(val, msg).to.not.be.an('array');\n  };\n\n  /**\n   * ### .isString(value, [message])\n   *\n   * Asserts that `value` is a string.\n   *\n   *     var teaOrder = 'chai';\n   *     assert.isString(teaOrder, 'order placed');\n   *\n   * @name isString\n   * @param {Mixed} value\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.isString = function (val, msg) {\n    new Assertion(val, msg).to.be.a('string');\n  };\n\n  /**\n   * ### .isNotString(value, [message])\n   *\n   * Asserts that `value` is _not_ a string.\n   *\n   *     var teaOrder = 4;\n   *     assert.isNotString(teaOrder, 'order placed');\n   *\n   * @name isNotString\n   * @param {Mixed} value\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.isNotString = function (val, msg) {\n    new Assertion(val, msg).to.not.be.a('string');\n  };\n\n  /**\n   * ### .isNumber(value, [message])\n   *\n   * Asserts that `value` is a number.\n   *\n   *     var cups = 2;\n   *     assert.isNumber(cups, 'how many cups');\n   *\n   * @name isNumber\n   * @param {Number} value\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.isNumber = function (val, msg) {\n    new Assertion(val, msg).to.be.a('number');\n  };\n\n  /**\n   * ### .isNotNumber(value, [message])\n   *\n   * Asserts that `value` is _not_ a number.\n   *\n   *     var cups = '2 cups please';\n   *     assert.isNotNumber(cups, 'how many cups');\n   *\n   * @name isNotNumber\n   * @param {Mixed} value\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.isNotNumber = function (val, msg) {\n    new Assertion(val, msg).to.not.be.a('number');\n  };\n\n  /**\n   * ### .isBoolean(value, [message])\n   *\n   * Asserts that `value` is a boolean.\n   *\n   *     var teaReady = true\n   *       , teaServed = false;\n   *\n   *     assert.isBoolean(teaReady, 'is the tea ready');\n   *     assert.isBoolean(teaServed, 'has tea been served');\n   *\n   * @name isBoolean\n   * @param {Mixed} value\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.isBoolean = function (val, msg) {\n    new Assertion(val, msg).to.be.a('boolean');\n  };\n\n  /**\n   * ### .isNotBoolean(value, [message])\n   *\n   * Asserts that `value` is _not_ a boolean.\n   *\n   *     var teaReady = 'yep'\n   *       , teaServed = 'nope';\n   *\n   *     assert.isNotBoolean(teaReady, 'is the tea ready');\n   *     assert.isNotBoolean(teaServed, 'has tea been served');\n   *\n   * @name isNotBoolean\n   * @param {Mixed} value\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.isNotBoolean = function (val, msg) {\n    new Assertion(val, msg).to.not.be.a('boolean');\n  };\n\n  /**\n   * ### .typeOf(value, name, [message])\n   *\n   * Asserts that `value`'s type is `name`, as determined by\n   * `Object.prototype.toString`.\n   *\n   *     assert.typeOf({ tea: 'chai' }, 'object', 'we have an object');\n   *     assert.typeOf(['chai', 'jasmine'], 'array', 'we have an array');\n   *     assert.typeOf('tea', 'string', 'we have a string');\n   *     assert.typeOf(/tea/, 'regexp', 'we have a regular expression');\n   *     assert.typeOf(null, 'null', 'we have a null');\n   *     assert.typeOf(undefined, 'undefined', 'we have an undefined');\n   *\n   * @name typeOf\n   * @param {Mixed} value\n   * @param {String} name\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.typeOf = function (val, type, msg) {\n    new Assertion(val, msg).to.be.a(type);\n  };\n\n  /**\n   * ### .notTypeOf(value, name, [message])\n   *\n   * Asserts that `value`'s type is _not_ `name`, as determined by\n   * `Object.prototype.toString`.\n   *\n   *     assert.notTypeOf('tea', 'number', 'strings are not numbers');\n   *\n   * @name notTypeOf\n   * @param {Mixed} value\n   * @param {String} typeof name\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.notTypeOf = function (val, type, msg) {\n    new Assertion(val, msg).to.not.be.a(type);\n  };\n\n  /**\n   * ### .instanceOf(object, constructor, [message])\n   *\n   * Asserts that `value` is an instance of `constructor`.\n   *\n   *     var Tea = function (name) { this.name = name; }\n   *       , chai = new Tea('chai');\n   *\n   *     assert.instanceOf(chai, Tea, 'chai is an instance of tea');\n   *\n   * @name instanceOf\n   * @param {Object} object\n   * @param {Constructor} constructor\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.instanceOf = function (val, type, msg) {\n    new Assertion(val, msg).to.be.instanceOf(type);\n  };\n\n  /**\n   * ### .notInstanceOf(object, constructor, [message])\n   *\n   * Asserts `value` is not an instance of `constructor`.\n   *\n   *     var Tea = function (name) { this.name = name; }\n   *       , chai = new String('chai');\n   *\n   *     assert.notInstanceOf(chai, Tea, 'chai is not an instance of tea');\n   *\n   * @name notInstanceOf\n   * @param {Object} object\n   * @param {Constructor} constructor\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.notInstanceOf = function (val, type, msg) {\n    new Assertion(val, msg).to.not.be.instanceOf(type);\n  };\n\n  /**\n   * ### .include(haystack, needle, [message])\n   *\n   * Asserts that `haystack` includes `needle`. Works\n   * for strings and arrays.\n   *\n   *     assert.include('foobar', 'bar', 'foobar contains string \"bar\"');\n   *     assert.include([ 1, 2, 3 ], 3, 'array contains value');\n   *\n   * @name include\n   * @param {Array|String} haystack\n   * @param {Mixed} needle\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.include = function (exp, inc, msg) {\n    new Assertion(exp, msg, assert.include).include(inc);\n  };\n\n  /**\n   * ### .notInclude(haystack, needle, [message])\n   *\n   * Asserts that `haystack` does not include `needle`. Works\n   * for strings and arrays.\n   *\n   *     assert.notInclude('foobar', 'baz', 'string not include substring');\n   *     assert.notInclude([ 1, 2, 3 ], 4, 'array not include contain value');\n   *\n   * @name notInclude\n   * @param {Array|String} haystack\n   * @param {Mixed} needle\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.notInclude = function (exp, inc, msg) {\n    new Assertion(exp, msg, assert.notInclude).not.include(inc);\n  };\n\n  /**\n   * ### .match(value, regexp, [message])\n   *\n   * Asserts that `value` matches the regular expression `regexp`.\n   *\n   *     assert.match('foobar', /^foo/, 'regexp matches');\n   *\n   * @name match\n   * @param {Mixed} value\n   * @param {RegExp} regexp\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.match = function (exp, re, msg) {\n    new Assertion(exp, msg).to.match(re);\n  };\n\n  /**\n   * ### .notMatch(value, regexp, [message])\n   *\n   * Asserts that `value` does not match the regular expression `regexp`.\n   *\n   *     assert.notMatch('foobar', /^foo/, 'regexp does not match');\n   *\n   * @name notMatch\n   * @param {Mixed} value\n   * @param {RegExp} regexp\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.notMatch = function (exp, re, msg) {\n    new Assertion(exp, msg).to.not.match(re);\n  };\n\n  /**\n   * ### .property(object, property, [message])\n   *\n   * Asserts that `object` has a property named by `property`.\n   *\n   *     assert.property({ tea: { green: 'matcha' }}, 'tea');\n   *\n   * @name property\n   * @param {Object} object\n   * @param {String} property\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.property = function (obj, prop, msg) {\n    new Assertion(obj, msg).to.have.property(prop);\n  };\n\n  /**\n   * ### .notProperty(object, property, [message])\n   *\n   * Asserts that `object` does _not_ have a property named by `property`.\n   *\n   *     assert.notProperty({ tea: { green: 'matcha' }}, 'coffee');\n   *\n   * @name notProperty\n   * @param {Object} object\n   * @param {String} property\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.notProperty = function (obj, prop, msg) {\n    new Assertion(obj, msg).to.not.have.property(prop);\n  };\n\n  /**\n   * ### .deepProperty(object, property, [message])\n   *\n   * Asserts that `object` has a property named by `property`, which can be a\n   * string using dot- and bracket-notation for deep reference.\n   *\n   *     assert.deepProperty({ tea: { green: 'matcha' }}, 'tea.green');\n   *\n   * @name deepProperty\n   * @param {Object} object\n   * @param {String} property\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.deepProperty = function (obj, prop, msg) {\n    new Assertion(obj, msg).to.have.deep.property(prop);\n  };\n\n  /**\n   * ### .notDeepProperty(object, property, [message])\n   *\n   * Asserts that `object` does _not_ have a property named by `property`, which\n   * can be a string using dot- and bracket-notation for deep reference.\n   *\n   *     assert.notDeepProperty({ tea: { green: 'matcha' }}, 'tea.oolong');\n   *\n   * @name notDeepProperty\n   * @param {Object} object\n   * @param {String} property\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.notDeepProperty = function (obj, prop, msg) {\n    new Assertion(obj, msg).to.not.have.deep.property(prop);\n  };\n\n  /**\n   * ### .propertyVal(object, property, value, [message])\n   *\n   * Asserts that `object` has a property named by `property` with value given\n   * by `value`.\n   *\n   *     assert.propertyVal({ tea: 'is good' }, 'tea', 'is good');\n   *\n   * @name propertyVal\n   * @param {Object} object\n   * @param {String} property\n   * @param {Mixed} value\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.propertyVal = function (obj, prop, val, msg) {\n    new Assertion(obj, msg).to.have.property(prop, val);\n  };\n\n  /**\n   * ### .propertyNotVal(object, property, value, [message])\n   *\n   * Asserts that `object` has a property named by `property`, but with a value\n   * different from that given by `value`.\n   *\n   *     assert.propertyNotVal({ tea: 'is good' }, 'tea', 'is bad');\n   *\n   * @name propertyNotVal\n   * @param {Object} object\n   * @param {String} property\n   * @param {Mixed} value\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.propertyNotVal = function (obj, prop, val, msg) {\n    new Assertion(obj, msg).to.not.have.property(prop, val);\n  };\n\n  /**\n   * ### .deepPropertyVal(object, property, value, [message])\n   *\n   * Asserts that `object` has a property named by `property` with value given\n   * by `value`. `property` can use dot- and bracket-notation for deep\n   * reference.\n   *\n   *     assert.deepPropertyVal({ tea: { green: 'matcha' }}, 'tea.green', 'matcha');\n   *\n   * @name deepPropertyVal\n   * @param {Object} object\n   * @param {String} property\n   * @param {Mixed} value\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.deepPropertyVal = function (obj, prop, val, msg) {\n    new Assertion(obj, msg).to.have.deep.property(prop, val);\n  };\n\n  /**\n   * ### .deepPropertyNotVal(object, property, value, [message])\n   *\n   * Asserts that `object` has a property named by `property`, but with a value\n   * different from that given by `value`. `property` can use dot- and\n   * bracket-notation for deep reference.\n   *\n   *     assert.deepPropertyNotVal({ tea: { green: 'matcha' }}, 'tea.green', 'konacha');\n   *\n   * @name deepPropertyNotVal\n   * @param {Object} object\n   * @param {String} property\n   * @param {Mixed} value\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.deepPropertyNotVal = function (obj, prop, val, msg) {\n    new Assertion(obj, msg).to.not.have.deep.property(prop, val);\n  };\n\n  /**\n   * ### .lengthOf(object, length, [message])\n   *\n   * Asserts that `object` has a `length` property with the expected value.\n   *\n   *     assert.lengthOf([1,2,3], 3, 'array has length of 3');\n   *     assert.lengthOf('foobar', 6, 'string has length of 6');\n   *\n   * @name lengthOf\n   * @param {Mixed} object\n   * @param {Number} length\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.lengthOf = function (exp, len, msg) {\n    new Assertion(exp, msg).to.have.length(len);\n  };\n\n  /**\n   * ### .throws(function, [constructor/string/regexp], [string/regexp], [message])\n   *\n   * Asserts that `function` will throw an error that is an instance of\n   * `constructor`, or alternately that it will throw an error with message\n   * matching `regexp`.\n   *\n   *     assert.throws(fn, 'function throws a reference error');\n   *     assert.throws(fn, /function throws a reference error/);\n   *     assert.throws(fn, ReferenceError);\n   *     assert.throws(fn, ReferenceError, 'function throws a reference error');\n   *     assert.throws(fn, ReferenceError, /function throws a reference error/);\n   *\n   * @name throws\n   * @alias throw\n   * @alias Throw\n   * @param {Function} function\n   * @param {ErrorConstructor} constructor\n   * @param {RegExp} regexp\n   * @param {String} message\n   * @see https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Error#Error_types\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.throws = function (fn, errt, errs, msg) {\n    if ('string' === typeof errt || errt instanceof RegExp) {\n      errs = errt;\n      errt = null;\n    }\n\n    var assertErr = new Assertion(fn, msg).to.throw(errt, errs);\n    return flag(assertErr, 'object');\n  };\n\n  /**\n   * ### .doesNotThrow(function, [constructor/regexp], [message])\n   *\n   * Asserts that `function` will _not_ throw an error that is an instance of\n   * `constructor`, or alternately that it will not throw an error with message\n   * matching `regexp`.\n   *\n   *     assert.doesNotThrow(fn, Error, 'function does not throw');\n   *\n   * @name doesNotThrow\n   * @param {Function} function\n   * @param {ErrorConstructor} constructor\n   * @param {RegExp} regexp\n   * @param {String} message\n   * @see https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Error#Error_types\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.doesNotThrow = function (fn, type, msg) {\n    if ('string' === typeof type) {\n      msg = type;\n      type = null;\n    }\n\n    new Assertion(fn, msg).to.not.Throw(type);\n  };\n\n  /**\n   * ### .operator(val1, operator, val2, [message])\n   *\n   * Compares two values using `operator`.\n   *\n   *     assert.operator(1, '<', 2, 'everything is ok');\n   *     assert.operator(1, '>', 2, 'this will fail');\n   *\n   * @name operator\n   * @param {Mixed} val1\n   * @param {String} operator\n   * @param {Mixed} val2\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.operator = function (val, operator, val2, msg) {\n    var ok;\n    switch(operator) {\n      case '==':\n        ok = val == val2;\n        break;\n      case '===':\n        ok = val === val2;\n        break;\n      case '>':\n        ok = val > val2;\n        break;\n      case '>=':\n        ok = val >= val2;\n        break;\n      case '<':\n        ok = val < val2;\n        break;\n      case '<=':\n        ok = val <= val2;\n        break;\n      case '!=':\n        ok = val != val2;\n        break;\n      case '!==':\n        ok = val !== val2;\n        break;\n      default:\n        throw new Error('Invalid operator \"' + operator + '\"');\n    }\n    var test = new Assertion(ok, msg);\n    test.assert(\n        true === flag(test, 'object')\n      , 'expected ' + util.inspect(val) + ' to be ' + operator + ' ' + util.inspect(val2)\n      , 'expected ' + util.inspect(val) + ' to not be ' + operator + ' ' + util.inspect(val2) );\n  };\n\n  /**\n   * ### .closeTo(actual, expected, delta, [message])\n   *\n   * Asserts that the target is equal `expected`, to within a +/- `delta` range.\n   *\n   *     assert.closeTo(1.5, 1, 0.5, 'numbers are close');\n   *\n   * @name closeTo\n   * @param {Number} actual\n   * @param {Number} expected\n   * @param {Number} delta\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.closeTo = function (act, exp, delta, msg) {\n    new Assertion(act, msg).to.be.closeTo(exp, delta);\n  };\n\n  /**\n   * ### .approximately(actual, expected, delta, [message])\n   *\n   * Asserts that the target is equal `expected`, to within a +/- `delta` range.\n   *\n   *     assert.approximately(1.5, 1, 0.5, 'numbers are close');\n   *\n   * @name approximately\n   * @param {Number} actual\n   * @param {Number} expected\n   * @param {Number} delta\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.approximately = function (act, exp, delta, msg) {\n    new Assertion(act, msg).to.be.approximately(exp, delta);\n  };\n\n  /**\n   * ### .sameMembers(set1, set2, [message])\n   *\n   * Asserts that `set1` and `set2` have the same members.\n   * Order is not taken into account.\n   *\n   *     assert.sameMembers([ 1, 2, 3 ], [ 2, 1, 3 ], 'same members');\n   *\n   * @name sameMembers\n   * @param {Array} set1\n   * @param {Array} set2\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.sameMembers = function (set1, set2, msg) {\n    new Assertion(set1, msg).to.have.same.members(set2);\n  }\n\n  /**\n   * ### .sameDeepMembers(set1, set2, [message])\n   *\n   * Asserts that `set1` and `set2` have the same members - using a deep equality checking.\n   * Order is not taken into account.\n   *\n   *     assert.sameDeepMembers([ {b: 3}, {a: 2}, {c: 5} ], [ {c: 5}, {b: 3}, {a: 2} ], 'same deep members');\n   *\n   * @name sameDeepMembers\n   * @param {Array} set1\n   * @param {Array} set2\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.sameDeepMembers = function (set1, set2, msg) {\n    new Assertion(set1, msg).to.have.same.deep.members(set2);\n  }\n\n  /**\n   * ### .includeMembers(superset, subset, [message])\n   *\n   * Asserts that `subset` is included in `superset`.\n   * Order is not taken into account.\n   *\n   *     assert.includeMembers([ 1, 2, 3 ], [ 2, 1 ], 'include members');\n   *\n   * @name includeMembers\n   * @param {Array} superset\n   * @param {Array} subset\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.includeMembers = function (superset, subset, msg) {\n    new Assertion(superset, msg).to.include.members(subset);\n  }\n\n  /**\n   * ### .includeDeepMembers(superset, subset, [message])\n   *\n   * Asserts that `subset` is included in `superset` - using deep equality checking.\n   * Order is not taken into account.\n   * Duplicates are ignored.\n   *\n   *     assert.includeDeepMembers([ {a: 1}, {b: 2}, {c: 3} ], [ {b: 2}, {a: 1}, {b: 2} ], 'include deep members');\n   *\n   * @name includeDeepMembers\n   * @param {Array} superset\n   * @param {Array} subset\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.includeDeepMembers = function (superset, subset, msg) {\n    new Assertion(superset, msg).to.include.deep.members(subset);\n  }\n\n  /**\n   * ### .oneOf(inList, list, [message])\n   *\n   * Asserts that non-object, non-array value `inList` appears in the flat array `list`.\n   *\n   *     assert.oneOf(1, [ 2, 1 ], 'Not found in list');\n   *\n   * @name oneOf\n   * @param {*} inList\n   * @param {Array<*>} list\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.oneOf = function (inList, list, msg) {\n    new Assertion(inList, msg).to.be.oneOf(list);\n  }\n\n   /**\n   * ### .changes(function, object, property)\n   *\n   * Asserts that a function changes the value of a property\n   *\n   *     var obj = { val: 10 };\n   *     var fn = function() { obj.val = 22 };\n   *     assert.changes(fn, obj, 'val');\n   *\n   * @name changes\n   * @param {Function} modifier function\n   * @param {Object} object\n   * @param {String} property name\n   * @param {String} message _optional_\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.changes = function (fn, obj, prop) {\n    new Assertion(fn).to.change(obj, prop);\n  }\n\n   /**\n   * ### .doesNotChange(function, object, property)\n   *\n   * Asserts that a function does not changes the value of a property\n   *\n   *     var obj = { val: 10 };\n   *     var fn = function() { console.log('foo'); };\n   *     assert.doesNotChange(fn, obj, 'val');\n   *\n   * @name doesNotChange\n   * @param {Function} modifier function\n   * @param {Object} object\n   * @param {String} property name\n   * @param {String} message _optional_\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.doesNotChange = function (fn, obj, prop) {\n    new Assertion(fn).to.not.change(obj, prop);\n  }\n\n   /**\n   * ### .increases(function, object, property)\n   *\n   * Asserts that a function increases an object property\n   *\n   *     var obj = { val: 10 };\n   *     var fn = function() { obj.val = 13 };\n   *     assert.increases(fn, obj, 'val');\n   *\n   * @name increases\n   * @param {Function} modifier function\n   * @param {Object} object\n   * @param {String} property name\n   * @param {String} message _optional_\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.increases = function (fn, obj, prop) {\n    new Assertion(fn).to.increase(obj, prop);\n  }\n\n   /**\n   * ### .doesNotIncrease(function, object, property)\n   *\n   * Asserts that a function does not increase object property\n   *\n   *     var obj = { val: 10 };\n   *     var fn = function() { obj.val = 8 };\n   *     assert.doesNotIncrease(fn, obj, 'val');\n   *\n   * @name doesNotIncrease\n   * @param {Function} modifier function\n   * @param {Object} object\n   * @param {String} property name\n   * @param {String} message _optional_\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.doesNotIncrease = function (fn, obj, prop) {\n    new Assertion(fn).to.not.increase(obj, prop);\n  }\n\n   /**\n   * ### .decreases(function, object, property)\n   *\n   * Asserts that a function decreases an object property\n   *\n   *     var obj = { val: 10 };\n   *     var fn = function() { obj.val = 5 };\n   *     assert.decreases(fn, obj, 'val');\n   *\n   * @name decreases\n   * @param {Function} modifier function\n   * @param {Object} object\n   * @param {String} property name\n   * @param {String} message _optional_\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.decreases = function (fn, obj, prop) {\n    new Assertion(fn).to.decrease(obj, prop);\n  }\n\n   /**\n   * ### .doesNotDecrease(function, object, property)\n   *\n   * Asserts that a function does not decreases an object property\n   *\n   *     var obj = { val: 10 };\n   *     var fn = function() { obj.val = 15 };\n   *     assert.doesNotDecrease(fn, obj, 'val');\n   *\n   * @name doesNotDecrease\n   * @param {Function} modifier function\n   * @param {Object} object\n   * @param {String} property name\n   * @param {String} message _optional_\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.doesNotDecrease = function (fn, obj, prop) {\n    new Assertion(fn).to.not.decrease(obj, prop);\n  }\n\n  /*!\n   * ### .ifError(object)\n   *\n   * Asserts if value is not a false value, and throws if it is a true value.\n   * This is added to allow for chai to be a drop-in replacement for Node's\n   * assert class.\n   *\n   *     var err = new Error('I am a custom error');\n   *     assert.ifError(err); // Rethrows err!\n   *\n   * @name ifError\n   * @param {Object} object\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.ifError = function (val) {\n    if (val) {\n      throw(val);\n    }\n  };\n\n  /**\n   * ### .isExtensible(object)\n   *\n   * Asserts that `object` is extensible (can have new properties added to it).\n   *\n   *     assert.isExtensible({});\n   *\n   * @name isExtensible\n   * @alias extensible\n   * @param {Object} object\n   * @param {String} message _optional_\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.isExtensible = function (obj, msg) {\n    new Assertion(obj, msg).to.be.extensible;\n  };\n\n  /**\n   * ### .isNotExtensible(object)\n   *\n   * Asserts that `object` is _not_ extensible.\n   *\n   *     var nonExtensibleObject = Object.preventExtensions({});\n   *     var sealedObject = Object.seal({});\n   *     var frozenObject = Object.freese({});\n   *\n   *     assert.isNotExtensible(nonExtensibleObject);\n   *     assert.isNotExtensible(sealedObject);\n   *     assert.isNotExtensible(frozenObject);\n   *\n   * @name isNotExtensible\n   * @alias notExtensible\n   * @param {Object} object\n   * @param {String} message _optional_\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.isNotExtensible = function (obj, msg) {\n    new Assertion(obj, msg).to.not.be.extensible;\n  };\n\n  /**\n   * ### .isSealed(object)\n   *\n   * Asserts that `object` is sealed (cannot have new properties added to it\n   * and its existing properties cannot be removed).\n   *\n   *     var sealedObject = Object.seal({});\n   *     var frozenObject = Object.seal({});\n   *\n   *     assert.isSealed(sealedObject);\n   *     assert.isSealed(frozenObject);\n   *\n   * @name isSealed\n   * @alias sealed\n   * @param {Object} object\n   * @param {String} message _optional_\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.isSealed = function (obj, msg) {\n    new Assertion(obj, msg).to.be.sealed;\n  };\n\n  /**\n   * ### .isNotSealed(object)\n   *\n   * Asserts that `object` is _not_ sealed.\n   *\n   *     assert.isNotSealed({});\n   *\n   * @name isNotSealed\n   * @alias notSealed\n   * @param {Object} object\n   * @param {String} message _optional_\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.isNotSealed = function (obj, msg) {\n    new Assertion(obj, msg).to.not.be.sealed;\n  };\n\n  /**\n   * ### .isFrozen(object)\n   *\n   * Asserts that `object` is frozen (cannot have new properties added to it\n   * and its existing properties cannot be modified).\n   *\n   *     var frozenObject = Object.freeze({});\n   *     assert.frozen(frozenObject);\n   *\n   * @name isFrozen\n   * @alias frozen\n   * @param {Object} object\n   * @param {String} message _optional_\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.isFrozen = function (obj, msg) {\n    new Assertion(obj, msg).to.be.frozen;\n  };\n\n  /**\n   * ### .isNotFrozen(object)\n   *\n   * Asserts that `object` is _not_ frozen.\n   *\n   *     assert.isNotFrozen({});\n   *\n   * @name isNotFrozen\n   * @alias notFrozen\n   * @param {Object} object\n   * @param {String} message _optional_\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.isNotFrozen = function (obj, msg) {\n    new Assertion(obj, msg).to.not.be.frozen;\n  };\n\n  /*!\n   * Aliases.\n   */\n\n  (function alias(name, as){\n    assert[as] = assert[name];\n    return alias;\n  })\n  ('isOk', 'ok')\n  ('isNotOk', 'notOk')\n  ('throws', 'throw')\n  ('throws', 'Throw')\n  ('isExtensible', 'extensible')\n  ('isNotExtensible', 'notExtensible')\n  ('isSealed', 'sealed')\n  ('isNotSealed', 'notSealed')\n  ('isFrozen', 'frozen')\n  ('isNotFrozen', 'notFrozen');\n};\n\n},{}],7:[function(require,module,exports){\n/*!\n * chai\n * Copyright(c) 2011-2014 Jake Luer <jake@alogicalparadox.com>\n * MIT Licensed\n */\n\nmodule.exports = function (chai, util) {\n  chai.expect = function (val, message) {\n    return new chai.Assertion(val, message);\n  };\n\n  /**\n   * ### .fail(actual, expected, [message], [operator])\n   *\n   * Throw a failure.\n   *\n   * @name fail\n   * @param {Mixed} actual\n   * @param {Mixed} expected\n   * @param {String} message\n   * @param {String} operator\n   * @namespace Expect\n   * @api public\n   */\n\n  chai.expect.fail = function (actual, expected, message, operator) {\n    message = message || 'expect.fail()';\n    throw new chai.AssertionError(message, {\n        actual: actual\n      , expected: expected\n      , operator: operator\n    }, chai.expect.fail);\n  };\n};\n\n},{}],8:[function(require,module,exports){\n/*!\n * chai\n * Copyright(c) 2011-2014 Jake Luer <jake@alogicalparadox.com>\n * MIT Licensed\n */\n\nmodule.exports = function (chai, util) {\n  var Assertion = chai.Assertion;\n\n  function loadShould () {\n    // explicitly define this method as function as to have it's name to include as `ssfi`\n    function shouldGetter() {\n      if (this instanceof String || this instanceof Number || this instanceof Boolean ) {\n        return new Assertion(this.valueOf(), null, shouldGetter);\n      }\n      return new Assertion(this, null, shouldGetter);\n    }\n    function shouldSetter(value) {\n      // See https://github.com/chaijs/chai/issues/86: this makes\n      // `whatever.should = someValue` actually set `someValue`, which is\n      // especially useful for `global.should = require('chai').should()`.\n      //\n      // Note that we have to use [[DefineProperty]] instead of [[Put]]\n      // since otherwise we would trigger this very setter!\n      Object.defineProperty(this, 'should', {\n        value: value,\n        enumerable: true,\n        configurable: true,\n        writable: true\n      });\n    }\n    // modify Object.prototype to have `should`\n    Object.defineProperty(Object.prototype, 'should', {\n      set: shouldSetter\n      , get: shouldGetter\n      , configurable: true\n    });\n\n    var should = {};\n\n    /**\n     * ### .fail(actual, expected, [message], [operator])\n     *\n     * Throw a failure.\n     *\n     * @name fail\n     * @param {Mixed} actual\n     * @param {Mixed} expected\n     * @param {String} message\n     * @param {String} operator\n     * @namespace Should\n     * @api public\n     */\n\n    should.fail = function (actual, expected, message, operator) {\n      message = message || 'should.fail()';\n      throw new chai.AssertionError(message, {\n          actual: actual\n        , expected: expected\n        , operator: operator\n      }, should.fail);\n    };\n\n    /**\n     * ### .equal(actual, expected, [message])\n     *\n     * Asserts non-strict equality (`==`) of `actual` and `expected`.\n     *\n     *     should.equal(3, '3', '== coerces values to strings');\n     *\n     * @name equal\n     * @param {Mixed} actual\n     * @param {Mixed} expected\n     * @param {String} message\n     * @namespace Should\n     * @api public\n     */\n\n    should.equal = function (val1, val2, msg) {\n      new Assertion(val1, msg).to.equal(val2);\n    };\n\n    /**\n     * ### .throw(function, [constructor/string/regexp], [string/regexp], [message])\n     *\n     * Asserts that `function` will throw an error that is an instance of\n     * `constructor`, or alternately that it will throw an error with message\n     * matching `regexp`.\n     *\n     *     should.throw(fn, 'function throws a reference error');\n     *     should.throw(fn, /function throws a reference error/);\n     *     should.throw(fn, ReferenceError);\n     *     should.throw(fn, ReferenceError, 'function throws a reference error');\n     *     should.throw(fn, ReferenceError, /function throws a reference error/);\n     *\n     * @name throw\n     * @alias Throw\n     * @param {Function} function\n     * @param {ErrorConstructor} constructor\n     * @param {RegExp} regexp\n     * @param {String} message\n     * @see https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Error#Error_types\n     * @namespace Should\n     * @api public\n     */\n\n    should.Throw = function (fn, errt, errs, msg) {\n      new Assertion(fn, msg).to.Throw(errt, errs);\n    };\n\n    /**\n     * ### .exist\n     *\n     * Asserts that the target is neither `null` nor `undefined`.\n     *\n     *     var foo = 'hi';\n     *\n     *     should.exist(foo, 'foo exists');\n     *\n     * @name exist\n     * @namespace Should\n     * @api public\n     */\n\n    should.exist = function (val, msg) {\n      new Assertion(val, msg).to.exist;\n    }\n\n    // negation\n    should.not = {}\n\n    /**\n     * ### .not.equal(actual, expected, [message])\n     *\n     * Asserts non-strict inequality (`!=`) of `actual` and `expected`.\n     *\n     *     should.not.equal(3, 4, 'these numbers are not equal');\n     *\n     * @name not.equal\n     * @param {Mixed} actual\n     * @param {Mixed} expected\n     * @param {String} message\n     * @namespace Should\n     * @api public\n     */\n\n    should.not.equal = function (val1, val2, msg) {\n      new Assertion(val1, msg).to.not.equal(val2);\n    };\n\n    /**\n     * ### .throw(function, [constructor/regexp], [message])\n     *\n     * Asserts that `function` will _not_ throw an error that is an instance of\n     * `constructor`, or alternately that it will not throw an error with message\n     * matching `regexp`.\n     *\n     *     should.not.throw(fn, Error, 'function does not throw');\n     *\n     * @name not.throw\n     * @alias not.Throw\n     * @param {Function} function\n     * @param {ErrorConstructor} constructor\n     * @param {RegExp} regexp\n     * @param {String} message\n     * @see https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Error#Error_types\n     * @namespace Should\n     * @api public\n     */\n\n    should.not.Throw = function (fn, errt, errs, msg) {\n      new Assertion(fn, msg).to.not.Throw(errt, errs);\n    };\n\n    /**\n     * ### .not.exist\n     *\n     * Asserts that the target is neither `null` nor `undefined`.\n     *\n     *     var bar = null;\n     *\n     *     should.not.exist(bar, 'bar does not exist');\n     *\n     * @name not.exist\n     * @namespace Should\n     * @api public\n     */\n\n    should.not.exist = function (val, msg) {\n      new Assertion(val, msg).to.not.exist;\n    }\n\n    should['throw'] = should['Throw'];\n    should.not['throw'] = should.not['Throw'];\n\n    return should;\n  };\n\n  chai.should = loadShould;\n  chai.Should = loadShould;\n};\n\n},{}],9:[function(require,module,exports){\n/*!\n * Chai - addChainingMethod utility\n * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com>\n * MIT Licensed\n */\n\n/*!\n * Module dependencies\n */\n\nvar transferFlags = require('./transferFlags');\nvar flag = require('./flag');\nvar config = require('../config');\n\n/*!\n * Module variables\n */\n\n// Check whether `__proto__` is supported\nvar hasProtoSupport = '__proto__' in Object;\n\n// Without `__proto__` support, this module will need to add properties to a function.\n// However, some Function.prototype methods cannot be overwritten,\n// and there seems no easy cross-platform way to detect them (@see chaijs/chai/issues/69).\nvar excludeNames = /^(?:length|name|arguments|caller)$/;\n\n// Cache `Function` properties\nvar call  = Function.prototype.call,\n    apply = Function.prototype.apply;\n\n/**\n * ### addChainableMethod (ctx, name, method, chainingBehavior)\n *\n * Adds a method to an object, such that the method can also be chained.\n *\n *     utils.addChainableMethod(chai.Assertion.prototype, 'foo', function (str) {\n *       var obj = utils.flag(this, 'object');\n *       new chai.Assertion(obj).to.be.equal(str);\n *     });\n *\n * Can also be accessed directly from `chai.Assertion`.\n *\n *     chai.Assertion.addChainableMethod('foo', fn, chainingBehavior);\n *\n * The result can then be used as both a method assertion, executing both `method` and\n * `chainingBehavior`, or as a language chain, which only executes `chainingBehavior`.\n *\n *     expect(fooStr).to.be.foo('bar');\n *     expect(fooStr).to.be.foo.equal('foo');\n *\n * @param {Object} ctx object to which the method is added\n * @param {String} name of method to add\n * @param {Function} method function to be used for `name`, when called\n * @param {Function} chainingBehavior function to be called every time the property is accessed\n * @namespace Utils\n * @name addChainableMethod\n * @api public\n */\n\nmodule.exports = function (ctx, name, method, chainingBehavior) {\n  if (typeof chainingBehavior !== 'function') {\n    chainingBehavior = function () { };\n  }\n\n  var chainableBehavior = {\n      method: method\n    , chainingBehavior: chainingBehavior\n  };\n\n  // save the methods so we can overwrite them later, if we need to.\n  if (!ctx.__methods) {\n    ctx.__methods = {};\n  }\n  ctx.__methods[name] = chainableBehavior;\n\n  Object.defineProperty(ctx, name,\n    { get: function () {\n        chainableBehavior.chainingBehavior.call(this);\n\n        var assert = function assert() {\n          var old_ssfi = flag(this, 'ssfi');\n          if (old_ssfi && config.includeStack === false)\n            flag(this, 'ssfi', assert);\n          var result = chainableBehavior.method.apply(this, arguments);\n          return result === undefined ? this : result;\n        };\n\n        // Use `__proto__` if available\n        if (hasProtoSupport) {\n          // Inherit all properties from the object by replacing the `Function` prototype\n          var prototype = assert.__proto__ = Object.create(this);\n          // Restore the `call` and `apply` methods from `Function`\n          prototype.call = call;\n          prototype.apply = apply;\n        }\n        // Otherwise, redefine all properties (slow!)\n        else {\n          var asserterNames = Object.getOwnPropertyNames(ctx);\n          asserterNames.forEach(function (asserterName) {\n            if (!excludeNames.test(asserterName)) {\n              var pd = Object.getOwnPropertyDescriptor(ctx, asserterName);\n              Object.defineProperty(assert, asserterName, pd);\n            }\n          });\n        }\n\n        transferFlags(this, assert);\n        return assert;\n      }\n    , configurable: true\n  });\n};\n\n},{\"../config\":4,\"./flag\":13,\"./transferFlags\":29}],10:[function(require,module,exports){\n/*!\n * Chai - addMethod utility\n * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com>\n * MIT Licensed\n */\n\nvar config = require('../config');\n\n/**\n * ### .addMethod (ctx, name, method)\n *\n * Adds a method to the prototype of an object.\n *\n *     utils.addMethod(chai.Assertion.prototype, 'foo', function (str) {\n *       var obj = utils.flag(this, 'object');\n *       new chai.Assertion(obj).to.be.equal(str);\n *     });\n *\n * Can also be accessed directly from `chai.Assertion`.\n *\n *     chai.Assertion.addMethod('foo', fn);\n *\n * Then can be used as any other assertion.\n *\n *     expect(fooStr).to.be.foo('bar');\n *\n * @param {Object} ctx object to which the method is added\n * @param {String} name of method to add\n * @param {Function} method function to be used for name\n * @namespace Utils\n * @name addMethod\n * @api public\n */\nvar flag = require('./flag');\n\nmodule.exports = function (ctx, name, method) {\n  ctx[name] = function () {\n    var old_ssfi = flag(this, 'ssfi');\n    if (old_ssfi && config.includeStack === false)\n      flag(this, 'ssfi', ctx[name]);\n    var result = method.apply(this, arguments);\n    return result === undefined ? this : result;\n  };\n};\n\n},{\"../config\":4,\"./flag\":13}],11:[function(require,module,exports){\n/*!\n * Chai - addProperty utility\n * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com>\n * MIT Licensed\n */\n\nvar config = require('../config');\nvar flag = require('./flag');\n\n/**\n * ### addProperty (ctx, name, getter)\n *\n * Adds a property to the prototype of an object.\n *\n *     utils.addProperty(chai.Assertion.prototype, 'foo', function () {\n *       var obj = utils.flag(this, 'object');\n *       new chai.Assertion(obj).to.be.instanceof(Foo);\n *     });\n *\n * Can also be accessed directly from `chai.Assertion`.\n *\n *     chai.Assertion.addProperty('foo', fn);\n *\n * Then can be used as any other assertion.\n *\n *     expect(myFoo).to.be.foo;\n *\n * @param {Object} ctx object to which the property is added\n * @param {String} name of property to add\n * @param {Function} getter function to be used for name\n * @namespace Utils\n * @name addProperty\n * @api public\n */\n\nmodule.exports = function (ctx, name, getter) {\n  Object.defineProperty(ctx, name,\n    { get: function addProperty() {\n        var old_ssfi = flag(this, 'ssfi');\n        if (old_ssfi && config.includeStack === false)\n          flag(this, 'ssfi', addProperty);\n\n        var result = getter.call(this);\n        return result === undefined ? this : result;\n      }\n    , configurable: true\n  });\n};\n\n},{\"../config\":4,\"./flag\":13}],12:[function(require,module,exports){\n/*!\n * Chai - expectTypes utility\n * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com>\n * MIT Licensed\n */\n\n/**\n * ### expectTypes(obj, types)\n *\n * Ensures that the object being tested against is of a valid type.\n *\n *     utils.expectTypes(this, ['array', 'object', 'string']);\n *\n * @param {Mixed} obj constructed Assertion\n * @param {Array} type A list of allowed types for this assertion\n * @namespace Utils\n * @name expectTypes\n * @api public\n */\n\nvar AssertionError = require('assertion-error');\nvar flag = require('./flag');\nvar type = require('type-detect');\n\nmodule.exports = function (obj, types) {\n  var obj = flag(obj, 'object');\n  types = types.map(function (t) { return t.toLowerCase(); });\n  types.sort();\n\n  // Transforms ['lorem', 'ipsum'] into 'a lirum, or an ipsum'\n  var str = types.map(function (t, index) {\n    var art = ~[ 'a', 'e', 'i', 'o', 'u' ].indexOf(t.charAt(0)) ? 'an' : 'a';\n    var or = types.length > 1 && index === types.length - 1 ? 'or ' : '';\n    return or + art + ' ' + t;\n  }).join(', ');\n\n  if (!types.some(function (expected) { return type(obj) === expected; })) {\n    throw new AssertionError(\n      'object tested must be ' + str + ', but ' + type(obj) + ' given'\n    );\n  }\n};\n\n},{\"./flag\":13,\"assertion-error\":30,\"type-detect\":35}],13:[function(require,module,exports){\n/*!\n * Chai - flag utility\n * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com>\n * MIT Licensed\n */\n\n/**\n * ### flag(object, key, [value])\n *\n * Get or set a flag value on an object. If a\n * value is provided it will be set, else it will\n * return the currently set value or `undefined` if\n * the value is not set.\n *\n *     utils.flag(this, 'foo', 'bar'); // setter\n *     utils.flag(this, 'foo'); // getter, returns `bar`\n *\n * @param {Object} object constructed Assertion\n * @param {String} key\n * @param {Mixed} value (optional)\n * @namespace Utils\n * @name flag\n * @api private\n */\n\nmodule.exports = function (obj, key, value) {\n  var flags = obj.__flags || (obj.__flags = Object.create(null));\n  if (arguments.length === 3) {\n    flags[key] = value;\n  } else {\n    return flags[key];\n  }\n};\n\n},{}],14:[function(require,module,exports){\n/*!\n * Chai - getActual utility\n * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com>\n * MIT Licensed\n */\n\n/**\n * # getActual(object, [actual])\n *\n * Returns the `actual` value for an Assertion\n *\n * @param {Object} object (constructed Assertion)\n * @param {Arguments} chai.Assertion.prototype.assert arguments\n * @namespace Utils\n * @name getActual\n */\n\nmodule.exports = function (obj, args) {\n  return args.length > 4 ? args[4] : obj._obj;\n};\n\n},{}],15:[function(require,module,exports){\n/*!\n * Chai - getEnumerableProperties utility\n * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com>\n * MIT Licensed\n */\n\n/**\n * ### .getEnumerableProperties(object)\n *\n * This allows the retrieval of enumerable property names of an object,\n * inherited or not.\n *\n * @param {Object} object\n * @returns {Array}\n * @namespace Utils\n * @name getEnumerableProperties\n * @api public\n */\n\nmodule.exports = function getEnumerableProperties(object) {\n  var result = [];\n  for (var name in object) {\n    result.push(name);\n  }\n  return result;\n};\n\n},{}],16:[function(require,module,exports){\n/*!\n * Chai - message composition utility\n * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com>\n * MIT Licensed\n */\n\n/*!\n * Module dependancies\n */\n\nvar flag = require('./flag')\n  , getActual = require('./getActual')\n  , inspect = require('./inspect')\n  , objDisplay = require('./objDisplay');\n\n/**\n * ### .getMessage(object, message, negateMessage)\n *\n * Construct the error message based on flags\n * and template tags. Template tags will return\n * a stringified inspection of the object referenced.\n *\n * Message template tags:\n * - `#{this}` current asserted object\n * - `#{act}` actual value\n * - `#{exp}` expected value\n *\n * @param {Object} object (constructed Assertion)\n * @param {Arguments} chai.Assertion.prototype.assert arguments\n * @namespace Utils\n * @name getMessage\n * @api public\n */\n\nmodule.exports = function (obj, args) {\n  var negate = flag(obj, 'negate')\n    , val = flag(obj, 'object')\n    , expected = args[3]\n    , actual = getActual(obj, args)\n    , msg = negate ? args[2] : args[1]\n    , flagMsg = flag(obj, 'message');\n\n  if(typeof msg === \"function\") msg = msg();\n  msg = msg || '';\n  msg = msg\n    .replace(/#\\{this\\}/g, function () { return objDisplay(val); })\n    .replace(/#\\{act\\}/g, function () { return objDisplay(actual); })\n    .replace(/#\\{exp\\}/g, function () { return objDisplay(expected); });\n\n  return flagMsg ? flagMsg + ': ' + msg : msg;\n};\n\n},{\"./flag\":13,\"./getActual\":14,\"./inspect\":23,\"./objDisplay\":24}],17:[function(require,module,exports){\n/*!\n * Chai - getName utility\n * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com>\n * MIT Licensed\n */\n\n/**\n * # getName(func)\n *\n * Gets the name of a function, in a cross-browser way.\n *\n * @param {Function} a function (usually a constructor)\n * @namespace Utils\n * @name getName\n */\n\nmodule.exports = function (func) {\n  if (func.name) return func.name;\n\n  var match = /^\\s?function ([^(]*)\\(/.exec(func);\n  return match && match[1] ? match[1] : \"\";\n};\n\n},{}],18:[function(require,module,exports){\n/*!\n * Chai - getPathInfo utility\n * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com>\n * MIT Licensed\n */\n\nvar hasProperty = require('./hasProperty');\n\n/**\n * ### .getPathInfo(path, object)\n *\n * This allows the retrieval of property info in an\n * object given a string path.\n *\n * The path info consists of an object with the\n * following properties:\n *\n * * parent - The parent object of the property referenced by `path`\n * * name - The name of the final property, a number if it was an array indexer\n * * value - The value of the property, if it exists, otherwise `undefined`\n * * exists - Whether the property exists or not\n *\n * @param {String} path\n * @param {Object} object\n * @returns {Object} info\n * @namespace Utils\n * @name getPathInfo\n * @api public\n */\n\nmodule.exports = function getPathInfo(path, obj) {\n  var parsed = parsePath(path),\n      last = parsed[parsed.length - 1];\n\n  var info = {\n    parent: parsed.length > 1 ? _getPathValue(parsed, obj, parsed.length - 1) : obj,\n    name: last.p || last.i,\n    value: _getPathValue(parsed, obj)\n  };\n  info.exists = hasProperty(info.name, info.parent);\n\n  return info;\n};\n\n\n/*!\n * ## parsePath(path)\n *\n * Helper function used to parse string object\n * paths. Use in conjunction with `_getPathValue`.\n *\n *      var parsed = parsePath('myobject.property.subprop');\n *\n * ### Paths:\n *\n * * Can be as near infinitely deep and nested\n * * Arrays are also valid using the formal `myobject.document[3].property`.\n * * Literal dots and brackets (not delimiter) must be backslash-escaped.\n *\n * @param {String} path\n * @returns {Object} parsed\n * @api private\n */\n\nfunction parsePath (path) {\n  var str = path.replace(/([^\\\\])\\[/g, '$1.[')\n    , parts = str.match(/(\\\\\\.|[^.]+?)+/g);\n  return parts.map(function (value) {\n    var re = /^\\[(\\d+)\\]$/\n      , mArr = re.exec(value);\n    if (mArr) return { i: parseFloat(mArr[1]) };\n    else return { p: value.replace(/\\\\([.\\[\\]])/g, '$1') };\n  });\n}\n\n\n/*!\n * ## _getPathValue(parsed, obj)\n *\n * Helper companion function for `.parsePath` that returns\n * the value located at the parsed address.\n *\n *      var value = getPathValue(parsed, obj);\n *\n * @param {Object} parsed definition from `parsePath`.\n * @param {Object} object to search against\n * @param {Number} object to search against\n * @returns {Object|Undefined} value\n * @api private\n */\n\nfunction _getPathValue (parsed, obj, index) {\n  var tmp = obj\n    , res;\n\n  index = (index === undefined ? parsed.length : index);\n\n  for (var i = 0, l = index; i < l; i++) {\n    var part = parsed[i];\n    if (tmp) {\n      if ('undefined' !== typeof part.p)\n        tmp = tmp[part.p];\n      else if ('undefined' !== typeof part.i)\n        tmp = tmp[part.i];\n      if (i == (l - 1)) res = tmp;\n    } else {\n      res = undefined;\n    }\n  }\n  return res;\n}\n\n},{\"./hasProperty\":21}],19:[function(require,module,exports){\n/*!\n * Chai - getPathValue utility\n * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com>\n * @see https://github.com/logicalparadox/filtr\n * MIT Licensed\n */\n\nvar getPathInfo = require('./getPathInfo');\n\n/**\n * ### .getPathValue(path, object)\n *\n * This allows the retrieval of values in an\n * object given a string path.\n *\n *     var obj = {\n *         prop1: {\n *             arr: ['a', 'b', 'c']\n *           , str: 'Hello'\n *         }\n *       , prop2: {\n *             arr: [ { nested: 'Universe' } ]\n *           , str: 'Hello again!'\n *         }\n *     }\n *\n * The following would be the results.\n *\n *     getPathValue('prop1.str', obj); // Hello\n *     getPathValue('prop1.att[2]', obj); // b\n *     getPathValue('prop2.arr[0].nested', obj); // Universe\n *\n * @param {String} path\n * @param {Object} object\n * @returns {Object} value or `undefined`\n * @namespace Utils\n * @name getPathValue\n * @api public\n */\nmodule.exports = function(path, obj) {\n  var info = getPathInfo(path, obj);\n  return info.value;\n};\n\n},{\"./getPathInfo\":18}],20:[function(require,module,exports){\n/*!\n * Chai - getProperties utility\n * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com>\n * MIT Licensed\n */\n\n/**\n * ### .getProperties(object)\n *\n * This allows the retrieval of property names of an object, enumerable or not,\n * inherited or not.\n *\n * @param {Object} object\n * @returns {Array}\n * @namespace Utils\n * @name getProperties\n * @api public\n */\n\nmodule.exports = function getProperties(object) {\n  var result = Object.getOwnPropertyNames(object);\n\n  function addProperty(property) {\n    if (result.indexOf(property) === -1) {\n      result.push(property);\n    }\n  }\n\n  var proto = Object.getPrototypeOf(object);\n  while (proto !== null) {\n    Object.getOwnPropertyNames(proto).forEach(addProperty);\n    proto = Object.getPrototypeOf(proto);\n  }\n\n  return result;\n};\n\n},{}],21:[function(require,module,exports){\n/*!\n * Chai - hasProperty utility\n * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com>\n * MIT Licensed\n */\n\nvar type = require('type-detect');\n\n/**\n * ### .hasProperty(object, name)\n *\n * This allows checking whether an object has\n * named property or numeric array index.\n *\n * Basically does the same thing as the `in`\n * operator but works properly with natives\n * and null/undefined values.\n *\n *     var obj = {\n *         arr: ['a', 'b', 'c']\n *       , str: 'Hello'\n *     }\n *\n * The following would be the results.\n *\n *     hasProperty('str', obj);  // true\n *     hasProperty('constructor', obj);  // true\n *     hasProperty('bar', obj);  // false\n *\n *     hasProperty('length', obj.str); // true\n *     hasProperty(1, obj.str);  // true\n *     hasProperty(5, obj.str);  // false\n *\n *     hasProperty('length', obj.arr);  // true\n *     hasProperty(2, obj.arr);  // true\n *     hasProperty(3, obj.arr);  // false\n *\n * @param {Objuect} object\n * @param {String|Number} name\n * @returns {Boolean} whether it exists\n * @namespace Utils\n * @name getPathInfo\n * @api public\n */\n\nvar literals = {\n    'number': Number\n  , 'string': String\n};\n\nmodule.exports = function hasProperty(name, obj) {\n  var ot = type(obj);\n\n  // Bad Object, obviously no props at all\n  if(ot === 'null' || ot === 'undefined')\n    return false;\n\n  // The `in` operator does not work with certain literals\n  // box these before the check\n  if(literals[ot] && typeof obj !== 'object')\n    obj = new literals[ot](obj);\n\n  return name in obj;\n};\n\n},{\"type-detect\":35}],22:[function(require,module,exports){\n/*!\n * chai\n * Copyright(c) 2011 Jake Luer <jake@alogicalparadox.com>\n * MIT Licensed\n */\n\n/*!\n * Main exports\n */\n\nvar exports = module.exports = {};\n\n/*!\n * test utility\n */\n\nexports.test = require('./test');\n\n/*!\n * type utility\n */\n\nexports.type = require('type-detect');\n\n/*!\n * expectTypes utility\n */\nexports.expectTypes = require('./expectTypes');\n\n/*!\n * message utility\n */\n\nexports.getMessage = require('./getMessage');\n\n/*!\n * actual utility\n */\n\nexports.getActual = require('./getActual');\n\n/*!\n * Inspect util\n */\n\nexports.inspect = require('./inspect');\n\n/*!\n * Object Display util\n */\n\nexports.objDisplay = require('./objDisplay');\n\n/*!\n * Flag utility\n */\n\nexports.flag = require('./flag');\n\n/*!\n * Flag transferring utility\n */\n\nexports.transferFlags = require('./transferFlags');\n\n/*!\n * Deep equal utility\n */\n\nexports.eql = require('deep-eql');\n\n/*!\n * Deep path value\n */\n\nexports.getPathValue = require('./getPathValue');\n\n/*!\n * Deep path info\n */\n\nexports.getPathInfo = require('./getPathInfo');\n\n/*!\n * Check if a property exists\n */\n\nexports.hasProperty = require('./hasProperty');\n\n/*!\n * Function name\n */\n\nexports.getName = require('./getName');\n\n/*!\n * add Property\n */\n\nexports.addProperty = require('./addProperty');\n\n/*!\n * add Method\n */\n\nexports.addMethod = require('./addMethod');\n\n/*!\n * overwrite Property\n */\n\nexports.overwriteProperty = require('./overwriteProperty');\n\n/*!\n * overwrite Method\n */\n\nexports.overwriteMethod = require('./overwriteMethod');\n\n/*!\n * Add a chainable method\n */\n\nexports.addChainableMethod = require('./addChainableMethod');\n\n/*!\n * Overwrite chainable method\n */\n\nexports.overwriteChainableMethod = require('./overwriteChainableMethod');\n\n},{\"./addChainableMethod\":9,\"./addMethod\":10,\"./addProperty\":11,\"./expectTypes\":12,\"./flag\":13,\"./getActual\":14,\"./getMessage\":16,\"./getName\":17,\"./getPathInfo\":18,\"./getPathValue\":19,\"./hasProperty\":21,\"./inspect\":23,\"./objDisplay\":24,\"./overwriteChainableMethod\":25,\"./overwriteMethod\":26,\"./overwriteProperty\":27,\"./test\":28,\"./transferFlags\":29,\"deep-eql\":31,\"type-detect\":35}],23:[function(require,module,exports){\n// This is (almost) directly from Node.js utils\n// https://github.com/joyent/node/blob/f8c335d0caf47f16d31413f89aa28eda3878e3aa/lib/util.js\n\nvar getName = require('./getName');\nvar getProperties = require('./getProperties');\nvar getEnumerableProperties = require('./getEnumerableProperties');\n\nmodule.exports = inspect;\n\n/**\n * Echos the value of a value. Trys to print the value out\n * in the best way possible given the different types.\n *\n * @param {Object} obj The object to print out.\n * @param {Boolean} showHidden Flag that shows hidden (not enumerable)\n *    properties of objects.\n * @param {Number} depth Depth in which to descend in object. Default is 2.\n * @param {Boolean} colors Flag to turn on ANSI escape codes to color the\n *    output. Default is false (no coloring).\n * @namespace Utils\n * @name inspect\n */\nfunction inspect(obj, showHidden, depth, colors) {\n  var ctx = {\n    showHidden: showHidden,\n    seen: [],\n    stylize: function (str) { return str; }\n  };\n  return formatValue(ctx, obj, (typeof depth === 'undefined' ? 2 : depth));\n}\n\n// Returns true if object is a DOM element.\nvar isDOMElement = function (object) {\n  if (typeof HTMLElement === 'object') {\n    return object instanceof HTMLElement;\n  } else {\n    return object &&\n      typeof object === 'object' &&\n      object.nodeType === 1 &&\n      typeof object.nodeName === 'string';\n  }\n};\n\nfunction formatValue(ctx, value, recurseTimes) {\n  // Provide a hook for user-specified inspect functions.\n  // Check that value is an object with an inspect function on it\n  if (value && typeof value.inspect === 'function' &&\n      // Filter out the util module, it's inspect function is special\n      value.inspect !== exports.inspect &&\n      // Also filter out any prototype objects using the circular check.\n      !(value.constructor && value.constructor.prototype === value)) {\n    var ret = value.inspect(recurseTimes);\n    if (typeof ret !== 'string') {\n      ret = formatValue(ctx, ret, recurseTimes);\n    }\n    return ret;\n  }\n\n  // Primitive types cannot have properties\n  var primitive = formatPrimitive(ctx, value);\n  if (primitive) {\n    return primitive;\n  }\n\n  // If this is a DOM element, try to get the outer HTML.\n  if (isDOMElement(value)) {\n    if ('outerHTML' in value) {\n      return value.outerHTML;\n      // This value does not have an outerHTML attribute,\n      //   it could still be an XML element\n    } else {\n      // Attempt to serialize it\n      try {\n        if (document.xmlVersion) {\n          var xmlSerializer = new XMLSerializer();\n          return xmlSerializer.serializeToString(value);\n        } else {\n          // Firefox 11- do not support outerHTML\n          //   It does, however, support innerHTML\n          //   Use the following to render the element\n          var ns = \"http://www.w3.org/1999/xhtml\";\n          var container = document.createElementNS(ns, '_');\n\n          container.appendChild(value.cloneNode(false));\n          html = container.innerHTML\n            .replace('><', '>' + value.innerHTML + '<');\n          container.innerHTML = '';\n          return html;\n        }\n      } catch (err) {\n        // This could be a non-native DOM implementation,\n        //   continue with the normal flow:\n        //   printing the element as if it is an object.\n      }\n    }\n  }\n\n  // Look up the keys of the object.\n  var visibleKeys = getEnumerableProperties(value);\n  var keys = ctx.showHidden ? getProperties(value) : visibleKeys;\n\n  // Some type of object without properties can be shortcutted.\n  // In IE, errors have a single `stack` property, or if they are vanilla `Error`,\n  // a `stack` plus `description` property; ignore those for consistency.\n  if (keys.length === 0 || (isError(value) && (\n      (keys.length === 1 && keys[0] === 'stack') ||\n      (keys.length === 2 && keys[0] === 'description' && keys[1] === 'stack')\n     ))) {\n    if (typeof value === 'function') {\n      var name = getName(value);\n      var nameSuffix = name ? ': ' + name : '';\n      return ctx.stylize('[Function' + nameSuffix + ']', 'special');\n    }\n    if (isRegExp(value)) {\n      return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp');\n    }\n    if (isDate(value)) {\n      return ctx.stylize(Date.prototype.toUTCString.call(value), 'date');\n    }\n    if (isError(value)) {\n      return formatError(value);\n    }\n  }\n\n  var base = '', array = false, braces = ['{', '}'];\n\n  // Make Array say that they are Array\n  if (isArray(value)) {\n    array = true;\n    braces = ['[', ']'];\n  }\n\n  // Make functions say that they are functions\n  if (typeof value === 'function') {\n    var name = getName(value);\n    var nameSuffix = name ? ': ' + name : '';\n    base = ' [Function' + nameSuffix + ']';\n  }\n\n  // Make RegExps say that they are RegExps\n  if (isRegExp(value)) {\n    base = ' ' + RegExp.prototype.toString.call(value);\n  }\n\n  // Make dates with properties first say the date\n  if (isDate(value)) {\n    base = ' ' + Date.prototype.toUTCString.call(value);\n  }\n\n  // Make error with message first say the error\n  if (isError(value)) {\n    return formatError(value);\n  }\n\n  if (keys.length === 0 && (!array || value.length == 0)) {\n    return braces[0] + base + braces[1];\n  }\n\n  if (recurseTimes < 0) {\n    if (isRegExp(value)) {\n      return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp');\n    } else {\n      return ctx.stylize('[Object]', 'special');\n    }\n  }\n\n  ctx.seen.push(value);\n\n  var output;\n  if (array) {\n    output = formatArray(ctx, value, recurseTimes, visibleKeys, keys);\n  } else {\n    output = keys.map(function(key) {\n      return formatProperty(ctx, value, recurseTimes, visibleKeys, key, array);\n    });\n  }\n\n  ctx.seen.pop();\n\n  return reduceToSingleString(output, base, braces);\n}\n\n\nfunction formatPrimitive(ctx, value) {\n  switch (typeof value) {\n    case 'undefined':\n      return ctx.stylize('undefined', 'undefined');\n\n    case 'string':\n      var simple = '\\'' + JSON.stringify(value).replace(/^\"|\"$/g, '')\n                                               .replace(/'/g, \"\\\\'\")\n                                               .replace(/\\\\\"/g, '\"') + '\\'';\n      return ctx.stylize(simple, 'string');\n\n    case 'number':\n      if (value === 0 && (1/value) === -Infinity) {\n        return ctx.stylize('-0', 'number');\n      }\n      return ctx.stylize('' + value, 'number');\n\n    case 'boolean':\n      return ctx.stylize('' + value, 'boolean');\n  }\n  // For some reason typeof null is \"object\", so special case here.\n  if (value === null) {\n    return ctx.stylize('null', 'null');\n  }\n}\n\n\nfunction formatError(value) {\n  return '[' + Error.prototype.toString.call(value) + ']';\n}\n\n\nfunction formatArray(ctx, value, recurseTimes, visibleKeys, keys) {\n  var output = [];\n  for (var i = 0, l = value.length; i < l; ++i) {\n    if (Object.prototype.hasOwnProperty.call(value, String(i))) {\n      output.push(formatProperty(ctx, value, recurseTimes, visibleKeys,\n          String(i), true));\n    } else {\n      output.push('');\n    }\n  }\n  keys.forEach(function(key) {\n    if (!key.match(/^\\d+$/)) {\n      output.push(formatProperty(ctx, value, recurseTimes, visibleKeys,\n          key, true));\n    }\n  });\n  return output;\n}\n\n\nfunction formatProperty(ctx, value, recurseTimes, visibleKeys, key, array) {\n  var name, str;\n  if (value.__lookupGetter__) {\n    if (value.__lookupGetter__(key)) {\n      if (value.__lookupSetter__(key)) {\n        str = ctx.stylize('[Getter/Setter]', 'special');\n      } else {\n        str = ctx.stylize('[Getter]', 'special');\n      }\n    } else {\n      if (value.__lookupSetter__(key)) {\n        str = ctx.stylize('[Setter]', 'special');\n      }\n    }\n  }\n  if (visibleKeys.indexOf(key) < 0) {\n    name = '[' + key + ']';\n  }\n  if (!str) {\n    if (ctx.seen.indexOf(value[key]) < 0) {\n      if (recurseTimes === null) {\n        str = formatValue(ctx, value[key], null);\n      } else {\n        str = formatValue(ctx, value[key], recurseTimes - 1);\n      }\n      if (str.indexOf('\\n') > -1) {\n        if (array) {\n          str = str.split('\\n').map(function(line) {\n            return '  ' + line;\n          }).join('\\n').substr(2);\n        } else {\n          str = '\\n' + str.split('\\n').map(function(line) {\n            return '   ' + line;\n          }).join('\\n');\n        }\n      }\n    } else {\n      str = ctx.stylize('[Circular]', 'special');\n    }\n  }\n  if (typeof name === 'undefined') {\n    if (array && key.match(/^\\d+$/)) {\n      return str;\n    }\n    name = JSON.stringify('' + key);\n    if (name.match(/^\"([a-zA-Z_][a-zA-Z_0-9]*)\"$/)) {\n      name = name.substr(1, name.length - 2);\n      name = ctx.stylize(name, 'name');\n    } else {\n      name = name.replace(/'/g, \"\\\\'\")\n                 .replace(/\\\\\"/g, '\"')\n                 .replace(/(^\"|\"$)/g, \"'\");\n      name = ctx.stylize(name, 'string');\n    }\n  }\n\n  return name + ': ' + str;\n}\n\n\nfunction reduceToSingleString(output, base, braces) {\n  var numLinesEst = 0;\n  var length = output.reduce(function(prev, cur) {\n    numLinesEst++;\n    if (cur.indexOf('\\n') >= 0) numLinesEst++;\n    return prev + cur.length + 1;\n  }, 0);\n\n  if (length > 60) {\n    return braces[0] +\n           (base === '' ? '' : base + '\\n ') +\n           ' ' +\n           output.join(',\\n  ') +\n           ' ' +\n           braces[1];\n  }\n\n  return braces[0] + base + ' ' + output.join(', ') + ' ' + braces[1];\n}\n\nfunction isArray(ar) {\n  return Array.isArray(ar) ||\n         (typeof ar === 'object' && objectToString(ar) === '[object Array]');\n}\n\nfunction isRegExp(re) {\n  return typeof re === 'object' && objectToString(re) === '[object RegExp]';\n}\n\nfunction isDate(d) {\n  return typeof d === 'object' && objectToString(d) === '[object Date]';\n}\n\nfunction isError(e) {\n  return typeof e === 'object' && objectToString(e) === '[object Error]';\n}\n\nfunction objectToString(o) {\n  return Object.prototype.toString.call(o);\n}\n\n},{\"./getEnumerableProperties\":15,\"./getName\":17,\"./getProperties\":20}],24:[function(require,module,exports){\n/*!\n * Chai - flag utility\n * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com>\n * MIT Licensed\n */\n\n/*!\n * Module dependancies\n */\n\nvar inspect = require('./inspect');\nvar config = require('../config');\n\n/**\n * ### .objDisplay (object)\n *\n * Determines if an object or an array matches\n * criteria to be inspected in-line for error\n * messages or should be truncated.\n *\n * @param {Mixed} javascript object to inspect\n * @name objDisplay\n * @namespace Utils\n * @api public\n */\n\nmodule.exports = function (obj) {\n  var str = inspect(obj)\n    , type = Object.prototype.toString.call(obj);\n\n  if (config.truncateThreshold && str.length >= config.truncateThreshold) {\n    if (type === '[object Function]') {\n      return !obj.name || obj.name === ''\n        ? '[Function]'\n        : '[Function: ' + obj.name + ']';\n    } else if (type === '[object Array]') {\n      return '[ Array(' + obj.length + ') ]';\n    } else if (type === '[object Object]') {\n      var keys = Object.keys(obj)\n        , kstr = keys.length > 2\n          ? keys.splice(0, 2).join(', ') + ', ...'\n          : keys.join(', ');\n      return '{ Object (' + kstr + ') }';\n    } else {\n      return str;\n    }\n  } else {\n    return str;\n  }\n};\n\n},{\"../config\":4,\"./inspect\":23}],25:[function(require,module,exports){\n/*!\n * Chai - overwriteChainableMethod utility\n * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com>\n * MIT Licensed\n */\n\n/**\n * ### overwriteChainableMethod (ctx, name, method, chainingBehavior)\n *\n * Overwites an already existing chainable method\n * and provides access to the previous function or\n * property.  Must return functions to be used for\n * name.\n *\n *     utils.overwriteChainableMethod(chai.Assertion.prototype, 'length',\n *       function (_super) {\n *       }\n *     , function (_super) {\n *       }\n *     );\n *\n * Can also be accessed directly from `chai.Assertion`.\n *\n *     chai.Assertion.overwriteChainableMethod('foo', fn, fn);\n *\n * Then can be used as any other assertion.\n *\n *     expect(myFoo).to.have.length(3);\n *     expect(myFoo).to.have.length.above(3);\n *\n * @param {Object} ctx object whose method / property is to be overwritten\n * @param {String} name of method / property to overwrite\n * @param {Function} method function that returns a function to be used for name\n * @param {Function} chainingBehavior function that returns a function to be used for property\n * @namespace Utils\n * @name overwriteChainableMethod\n * @api public\n */\n\nmodule.exports = function (ctx, name, method, chainingBehavior) {\n  var chainableBehavior = ctx.__methods[name];\n\n  var _chainingBehavior = chainableBehavior.chainingBehavior;\n  chainableBehavior.chainingBehavior = function () {\n    var result = chainingBehavior(_chainingBehavior).call(this);\n    return result === undefined ? this : result;\n  };\n\n  var _method = chainableBehavior.method;\n  chainableBehavior.method = function () {\n    var result = method(_method).apply(this, arguments);\n    return result === undefined ? this : result;\n  };\n};\n\n},{}],26:[function(require,module,exports){\n/*!\n * Chai - overwriteMethod utility\n * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com>\n * MIT Licensed\n */\n\n/**\n * ### overwriteMethod (ctx, name, fn)\n *\n * Overwites an already existing method and provides\n * access to previous function. Must return function\n * to be used for name.\n *\n *     utils.overwriteMethod(chai.Assertion.prototype, 'equal', function (_super) {\n *       return function (str) {\n *         var obj = utils.flag(this, 'object');\n *         if (obj instanceof Foo) {\n *           new chai.Assertion(obj.value).to.equal(str);\n *         } else {\n *           _super.apply(this, arguments);\n *         }\n *       }\n *     });\n *\n * Can also be accessed directly from `chai.Assertion`.\n *\n *     chai.Assertion.overwriteMethod('foo', fn);\n *\n * Then can be used as any other assertion.\n *\n *     expect(myFoo).to.equal('bar');\n *\n * @param {Object} ctx object whose method is to be overwritten\n * @param {String} name of method to overwrite\n * @param {Function} method function that returns a function to be used for name\n * @namespace Utils\n * @name overwriteMethod\n * @api public\n */\n\nmodule.exports = function (ctx, name, method) {\n  var _method = ctx[name]\n    , _super = function () { return this; };\n\n  if (_method && 'function' === typeof _method)\n    _super = _method;\n\n  ctx[name] = function () {\n    var result = method(_super).apply(this, arguments);\n    return result === undefined ? this : result;\n  }\n};\n\n},{}],27:[function(require,module,exports){\n/*!\n * Chai - overwriteProperty utility\n * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com>\n * MIT Licensed\n */\n\n/**\n * ### overwriteProperty (ctx, name, fn)\n *\n * Overwites an already existing property getter and provides\n * access to previous value. Must return function to use as getter.\n *\n *     utils.overwriteProperty(chai.Assertion.prototype, 'ok', function (_super) {\n *       return function () {\n *         var obj = utils.flag(this, 'object');\n *         if (obj instanceof Foo) {\n *           new chai.Assertion(obj.name).to.equal('bar');\n *         } else {\n *           _super.call(this);\n *         }\n *       }\n *     });\n *\n *\n * Can also be accessed directly from `chai.Assertion`.\n *\n *     chai.Assertion.overwriteProperty('foo', fn);\n *\n * Then can be used as any other assertion.\n *\n *     expect(myFoo).to.be.ok;\n *\n * @param {Object} ctx object whose property is to be overwritten\n * @param {String} name of property to overwrite\n * @param {Function} getter function that returns a getter function to be used for name\n * @namespace Utils\n * @name overwriteProperty\n * @api public\n */\n\nmodule.exports = function (ctx, name, getter) {\n  var _get = Object.getOwnPropertyDescriptor(ctx, name)\n    , _super = function () {};\n\n  if (_get && 'function' === typeof _get.get)\n    _super = _get.get\n\n  Object.defineProperty(ctx, name,\n    { get: function () {\n        var result = getter(_super).call(this);\n        return result === undefined ? this : result;\n      }\n    , configurable: true\n  });\n};\n\n},{}],28:[function(require,module,exports){\n/*!\n * Chai - test utility\n * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com>\n * MIT Licensed\n */\n\n/*!\n * Module dependancies\n */\n\nvar flag = require('./flag');\n\n/**\n * # test(object, expression)\n *\n * Test and object for expression.\n *\n * @param {Object} object (constructed Assertion)\n * @param {Arguments} chai.Assertion.prototype.assert arguments\n * @namespace Utils\n * @name test\n */\n\nmodule.exports = function (obj, args) {\n  var negate = flag(obj, 'negate')\n    , expr = args[0];\n  return negate ? !expr : expr;\n};\n\n},{\"./flag\":13}],29:[function(require,module,exports){\n/*!\n * Chai - transferFlags utility\n * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com>\n * MIT Licensed\n */\n\n/**\n * ### transferFlags(assertion, object, includeAll = true)\n *\n * Transfer all the flags for `assertion` to `object`. If\n * `includeAll` is set to `false`, then the base Chai\n * assertion flags (namely `object`, `ssfi`, and `message`)\n * will not be transferred.\n *\n *\n *     var newAssertion = new Assertion();\n *     utils.transferFlags(assertion, newAssertion);\n *\n *     var anotherAsseriton = new Assertion(myObj);\n *     utils.transferFlags(assertion, anotherAssertion, false);\n *\n * @param {Assertion} assertion the assertion to transfer the flags from\n * @param {Object} object the object to transfer the flags to; usually a new assertion\n * @param {Boolean} includeAll\n * @namespace Utils\n * @name transferFlags\n * @api private\n */\n\nmodule.exports = function (assertion, object, includeAll) {\n  var flags = assertion.__flags || (assertion.__flags = Object.create(null));\n\n  if (!object.__flags) {\n    object.__flags = Object.create(null);\n  }\n\n  includeAll = arguments.length === 3 ? includeAll : true;\n\n  for (var flag in flags) {\n    if (includeAll ||\n        (flag !== 'object' && flag !== 'ssfi' && flag != 'message')) {\n      object.__flags[flag] = flags[flag];\n    }\n  }\n};\n\n},{}],30:[function(require,module,exports){\n/*!\n * assertion-error\n * Copyright(c) 2013 Jake Luer <jake@qualiancy.com>\n * MIT Licensed\n */\n\n/*!\n * Return a function that will copy properties from\n * one object to another excluding any originally\n * listed. Returned function will create a new `{}`.\n *\n * @param {String} excluded properties ...\n * @return {Function}\n */\n\nfunction exclude () {\n  var excludes = [].slice.call(arguments);\n\n  function excludeProps (res, obj) {\n    Object.keys(obj).forEach(function (key) {\n      if (!~excludes.indexOf(key)) res[key] = obj[key];\n    });\n  }\n\n  return function extendExclude () {\n    var args = [].slice.call(arguments)\n      , i = 0\n      , res = {};\n\n    for (; i < args.length; i++) {\n      excludeProps(res, args[i]);\n    }\n\n    return res;\n  };\n};\n\n/*!\n * Primary Exports\n */\n\nmodule.exports = AssertionError;\n\n/**\n * ### AssertionError\n *\n * An extension of the JavaScript `Error` constructor for\n * assertion and validation scenarios.\n *\n * @param {String} message\n * @param {Object} properties to include (optional)\n * @param {callee} start stack function (optional)\n */\n\nfunction AssertionError (message, _props, ssf) {\n  var extend = exclude('name', 'message', 'stack', 'constructor', 'toJSON')\n    , props = extend(_props || {});\n\n  // default values\n  this.message = message || 'Unspecified AssertionError';\n  this.showDiff = false;\n\n  // copy from properties\n  for (var key in props) {\n    this[key] = props[key];\n  }\n\n  // capture stack trace\n  ssf = ssf || arguments.callee;\n  if (ssf && Error.captureStackTrace) {\n    Error.captureStackTrace(this, ssf);\n  } else {\n    this.stack = new Error().stack;\n  }\n}\n\n/*!\n * Inherit from Error.prototype\n */\n\nAssertionError.prototype = Object.create(Error.prototype);\n\n/*!\n * Statically set name\n */\n\nAssertionError.prototype.name = 'AssertionError';\n\n/*!\n * Ensure correct constructor\n */\n\nAssertionError.prototype.constructor = AssertionError;\n\n/**\n * Allow errors to be converted to JSON for static transfer.\n *\n * @param {Boolean} include stack (default: `true`)\n * @return {Object} object that can be `JSON.stringify`\n */\n\nAssertionError.prototype.toJSON = function (stack) {\n  var extend = exclude('constructor', 'toJSON', 'stack')\n    , props = extend({ name: this.name }, this);\n\n  // include stack if exists and not turned off\n  if (false !== stack && this.stack) {\n    props.stack = this.stack;\n  }\n\n  return props;\n};\n\n},{}],31:[function(require,module,exports){\nmodule.exports = require('./lib/eql');\n\n},{\"./lib/eql\":32}],32:[function(require,module,exports){\n/*!\n * deep-eql\n * Copyright(c) 2013 Jake Luer <jake@alogicalparadox.com>\n * MIT Licensed\n */\n\n/*!\n * Module dependencies\n */\n\nvar type = require('type-detect');\n\n/*!\n * Buffer.isBuffer browser shim\n */\n\nvar Buffer;\ntry { Buffer = require('buffer').Buffer; }\ncatch(ex) {\n  Buffer = {};\n  Buffer.isBuffer = function() { return false; }\n}\n\n/*!\n * Primary Export\n */\n\nmodule.exports = deepEqual;\n\n/**\n * Assert super-strict (egal) equality between\n * two objects of any type.\n *\n * @param {Mixed} a\n * @param {Mixed} b\n * @param {Array} memoised (optional)\n * @return {Boolean} equal match\n */\n\nfunction deepEqual(a, b, m) {\n  if (sameValue(a, b)) {\n    return true;\n  } else if ('date' === type(a)) {\n    return dateEqual(a, b);\n  } else if ('regexp' === type(a)) {\n    return regexpEqual(a, b);\n  } else if (Buffer.isBuffer(a)) {\n    return bufferEqual(a, b);\n  } else if ('arguments' === type(a)) {\n    return argumentsEqual(a, b, m);\n  } else if (!typeEqual(a, b)) {\n    return false;\n  } else if (('object' !== type(a) && 'object' !== type(b))\n  && ('array' !== type(a) && 'array' !== type(b))) {\n    return sameValue(a, b);\n  } else {\n    return objectEqual(a, b, m);\n  }\n}\n\n/*!\n * Strict (egal) equality test. Ensures that NaN always\n * equals NaN and `-0` does not equal `+0`.\n *\n * @param {Mixed} a\n * @param {Mixed} b\n * @return {Boolean} equal match\n */\n\nfunction sameValue(a, b) {\n  if (a === b) return a !== 0 || 1 / a === 1 / b;\n  return a !== a && b !== b;\n}\n\n/*!\n * Compare the types of two given objects and\n * return if they are equal. Note that an Array\n * has a type of `array` (not `object`) and arguments\n * have a type of `arguments` (not `array`/`object`).\n *\n * @param {Mixed} a\n * @param {Mixed} b\n * @return {Boolean} result\n */\n\nfunction typeEqual(a, b) {\n  return type(a) === type(b);\n}\n\n/*!\n * Compare two Date objects by asserting that\n * the time values are equal using `saveValue`.\n *\n * @param {Date} a\n * @param {Date} b\n * @return {Boolean} result\n */\n\nfunction dateEqual(a, b) {\n  if ('date' !== type(b)) return false;\n  return sameValue(a.getTime(), b.getTime());\n}\n\n/*!\n * Compare two regular expressions by converting them\n * to string and checking for `sameValue`.\n *\n * @param {RegExp} a\n * @param {RegExp} b\n * @return {Boolean} result\n */\n\nfunction regexpEqual(a, b) {\n  if ('regexp' !== type(b)) return false;\n  return sameValue(a.toString(), b.toString());\n}\n\n/*!\n * Assert deep equality of two `arguments` objects.\n * Unfortunately, these must be sliced to arrays\n * prior to test to ensure no bad behavior.\n *\n * @param {Arguments} a\n * @param {Arguments} b\n * @param {Array} memoize (optional)\n * @return {Boolean} result\n */\n\nfunction argumentsEqual(a, b, m) {\n  if ('arguments' !== type(b)) return false;\n  a = [].slice.call(a);\n  b = [].slice.call(b);\n  return deepEqual(a, b, m);\n}\n\n/*!\n * Get enumerable properties of a given object.\n *\n * @param {Object} a\n * @return {Array} property names\n */\n\nfunction enumerable(a) {\n  var res = [];\n  for (var key in a) res.push(key);\n  return res;\n}\n\n/*!\n * Simple equality for flat iterable objects\n * such as Arrays or Node.js buffers.\n *\n * @param {Iterable} a\n * @param {Iterable} b\n * @return {Boolean} result\n */\n\nfunction iterableEqual(a, b) {\n  if (a.length !==  b.length) return false;\n\n  var i = 0;\n  var match = true;\n\n  for (; i < a.length; i++) {\n    if (a[i] !== b[i]) {\n      match = false;\n      break;\n    }\n  }\n\n  return match;\n}\n\n/*!\n * Extension to `iterableEqual` specifically\n * for Node.js Buffers.\n *\n * @param {Buffer} a\n * @param {Mixed} b\n * @return {Boolean} result\n */\n\nfunction bufferEqual(a, b) {\n  if (!Buffer.isBuffer(b)) return false;\n  return iterableEqual(a, b);\n}\n\n/*!\n * Block for `objectEqual` ensuring non-existing\n * values don't get in.\n *\n * @param {Mixed} object\n * @return {Boolean} result\n */\n\nfunction isValue(a) {\n  return a !== null && a !== undefined;\n}\n\n/*!\n * Recursively check the equality of two objects.\n * Once basic sameness has been established it will\n * defer to `deepEqual` for each enumerable key\n * in the object.\n *\n * @param {Mixed} a\n * @param {Mixed} b\n * @return {Boolean} result\n */\n\nfunction objectEqual(a, b, m) {\n  if (!isValue(a) || !isValue(b)) {\n    return false;\n  }\n\n  if (a.prototype !== b.prototype) {\n    return false;\n  }\n\n  var i;\n  if (m) {\n    for (i = 0; i < m.length; i++) {\n      if ((m[i][0] === a && m[i][1] === b)\n      ||  (m[i][0] === b && m[i][1] === a)) {\n        return true;\n      }\n    }\n  } else {\n    m = [];\n  }\n\n  try {\n    var ka = enumerable(a);\n    var kb = enumerable(b);\n  } catch (ex) {\n    return false;\n  }\n\n  ka.sort();\n  kb.sort();\n\n  if (!iterableEqual(ka, kb)) {\n    return false;\n  }\n\n  m.push([ a, b ]);\n\n  var key;\n  for (i = ka.length - 1; i >= 0; i--) {\n    key = ka[i];\n    if (!deepEqual(a[key], b[key], m)) {\n      return false;\n    }\n  }\n\n  return true;\n}\n\n},{\"buffer\":undefined,\"type-detect\":33}],33:[function(require,module,exports){\nmodule.exports = require('./lib/type');\n\n},{\"./lib/type\":34}],34:[function(require,module,exports){\n/*!\n * type-detect\n * Copyright(c) 2013 jake luer <jake@alogicalparadox.com>\n * MIT Licensed\n */\n\n/*!\n * Primary Exports\n */\n\nvar exports = module.exports = getType;\n\n/*!\n * Detectable javascript natives\n */\n\nvar natives = {\n    '[object Array]': 'array'\n  , '[object RegExp]': 'regexp'\n  , '[object Function]': 'function'\n  , '[object Arguments]': 'arguments'\n  , '[object Date]': 'date'\n};\n\n/**\n * ### typeOf (obj)\n *\n * Use several different techniques to determine\n * the type of object being tested.\n *\n *\n * @param {Mixed} object\n * @return {String} object type\n * @api public\n */\n\nfunction getType (obj) {\n  var str = Object.prototype.toString.call(obj);\n  if (natives[str]) return natives[str];\n  if (obj === null) return 'null';\n  if (obj === undefined) return 'undefined';\n  if (obj === Object(obj)) return 'object';\n  return typeof obj;\n}\n\nexports.Library = Library;\n\n/**\n * ### Library\n *\n * Create a repository for custom type detection.\n *\n * ```js\n * var lib = new type.Library;\n * ```\n *\n */\n\nfunction Library () {\n  this.tests = {};\n}\n\n/**\n * #### .of (obj)\n *\n * Expose replacement `typeof` detection to the library.\n *\n * ```js\n * if ('string' === lib.of('hello world')) {\n *   // ...\n * }\n * ```\n *\n * @param {Mixed} object to test\n * @return {String} type\n */\n\nLibrary.prototype.of = getType;\n\n/**\n * #### .define (type, test)\n *\n * Add a test to for the `.test()` assertion.\n *\n * Can be defined as a regular expression:\n *\n * ```js\n * lib.define('int', /^[0-9]+$/);\n * ```\n *\n * ... or as a function:\n *\n * ```js\n * lib.define('bln', function (obj) {\n *   if ('boolean' === lib.of(obj)) return true;\n *   var blns = [ 'yes', 'no', 'true', 'false', 1, 0 ];\n *   if ('string' === lib.of(obj)) obj = obj.toLowerCase();\n *   return !! ~blns.indexOf(obj);\n * });\n * ```\n *\n * @param {String} type\n * @param {RegExp|Function} test\n * @api public\n */\n\nLibrary.prototype.define = function (type, test) {\n  if (arguments.length === 1) return this.tests[type];\n  this.tests[type] = test;\n  return this;\n};\n\n/**\n * #### .test (obj, test)\n *\n * Assert that an object is of type. Will first\n * check natives, and if that does not pass it will\n * use the user defined custom tests.\n *\n * ```js\n * assert(lib.test('1', 'int'));\n * assert(lib.test('yes', 'bln'));\n * ```\n *\n * @param {Mixed} object\n * @param {String} type\n * @return {Boolean} result\n * @api public\n */\n\nLibrary.prototype.test = function (obj, type) {\n  if (type === getType(obj)) return true;\n  var test = this.tests[type];\n\n  if (test && 'regexp' === getType(test)) {\n    return test.test(obj);\n  } else if (test && 'function' === getType(test)) {\n    return test(obj);\n  } else {\n    throw new ReferenceError('Type test \"' + type + '\" not defined or invalid.');\n  }\n};\n\n},{}],35:[function(require,module,exports){\narguments[4][33][0].apply(exports,arguments)\n},{\"./lib/type\":36,\"dup\":33}],36:[function(require,module,exports){\n/*!\n * type-detect\n * Copyright(c) 2013 jake luer <jake@alogicalparadox.com>\n * MIT Licensed\n */\n\n/*!\n * Primary Exports\n */\n\nvar exports = module.exports = getType;\n\n/**\n * ### typeOf (obj)\n *\n * Use several different techniques to determine\n * the type of object being tested.\n *\n *\n * @param {Mixed} object\n * @return {String} object type\n * @api public\n */\nvar objectTypeRegexp = /^\\[object (.*)\\]$/;\n\nfunction getType(obj) {\n  var type = Object.prototype.toString.call(obj).match(objectTypeRegexp)[1].toLowerCase();\n  // Let \"new String('')\" return 'object'\n  if (typeof Promise === 'function' && obj instanceof Promise) return 'promise';\n  // PhantomJS has type \"DOMWindow\" for null\n  if (obj === null) return 'null';\n  // PhantomJS has type \"DOMWindow\" for undefined\n  if (obj === undefined) return 'undefined';\n  return type;\n}\n\nexports.Library = Library;\n\n/**\n * ### Library\n *\n * Create a repository for custom type detection.\n *\n * ```js\n * var lib = new type.Library;\n * ```\n *\n */\n\nfunction Library() {\n  if (!(this instanceof Library)) return new Library();\n  this.tests = {};\n}\n\n/**\n * #### .of (obj)\n *\n * Expose replacement `typeof` detection to the library.\n *\n * ```js\n * if ('string' === lib.of('hello world')) {\n *   // ...\n * }\n * ```\n *\n * @param {Mixed} object to test\n * @return {String} type\n */\n\nLibrary.prototype.of = getType;\n\n/**\n * #### .define (type, test)\n *\n * Add a test to for the `.test()` assertion.\n *\n * Can be defined as a regular expression:\n *\n * ```js\n * lib.define('int', /^[0-9]+$/);\n * ```\n *\n * ... or as a function:\n *\n * ```js\n * lib.define('bln', function (obj) {\n *   if ('boolean' === lib.of(obj)) return true;\n *   var blns = [ 'yes', 'no', 'true', 'false', 1, 0 ];\n *   if ('string' === lib.of(obj)) obj = obj.toLowerCase();\n *   return !! ~blns.indexOf(obj);\n * });\n * ```\n *\n * @param {String} type\n * @param {RegExp|Function} test\n * @api public\n */\n\nLibrary.prototype.define = function(type, test) {\n  if (arguments.length === 1) return this.tests[type];\n  this.tests[type] = test;\n  return this;\n};\n\n/**\n * #### .test (obj, test)\n *\n * Assert that an object is of type. Will first\n * check natives, and if that does not pass it will\n * use the user defined custom tests.\n *\n * ```js\n * assert(lib.test('1', 'int'));\n * assert(lib.test('yes', 'bln'));\n * ```\n *\n * @param {Mixed} object\n * @param {String} type\n * @return {Boolean} result\n * @api public\n */\n\nLibrary.prototype.test = function(obj, type) {\n  if (type === getType(obj)) return true;\n  var test = this.tests[type];\n\n  if (test && 'regexp' === getType(test)) {\n    return test.test(obj);\n  } else if (test && 'function' === getType(test)) {\n    return test(obj);\n  } else {\n    throw new ReferenceError('Type test \"' + type + '\" not defined or invalid.');\n  }\n};\n\n},{}]},{},[1])(1)\n});\n"
  },
  {
    "path": "app_backend/static/plugin/JavaScript-Canvas-to-Blob-3.7.0/test/vendor/load-image.js",
    "content": "/*\n * JavaScript Load Image\n * https://github.com/blueimp/JavaScript-Load-Image\n *\n * Copyright 2011, Sebastian Tschan\n * https://blueimp.net\n *\n * Licensed under the MIT license:\n * https://opensource.org/licenses/MIT\n */\n\n/* global define, URL, webkitURL, FileReader */\n\n;(function ($) {\n  'use strict'\n\n  // Loads an image for a given File object.\n  // Invokes the callback with an img or optional canvas\n  // element (if supported by the browser) as parameter:\n  function loadImage (file, callback, options) {\n    var img = document.createElement('img')\n    var url\n    img.onerror = function (event) {\n      return loadImage.onerror(img, event, file, callback, options)\n    }\n    img.onload = function (event) {\n      return loadImage.onload(img, event, file, callback, options)\n    }\n    if (loadImage.isInstanceOf('Blob', file) ||\n      // Files are also Blob instances, but some browsers\n      // (Firefox 3.6) support the File API but not Blobs:\n      loadImage.isInstanceOf('File', file)) {\n      url = img._objectURL = loadImage.createObjectURL(file)\n    } else if (typeof file === 'string') {\n      url = file\n      if (options && options.crossOrigin) {\n        img.crossOrigin = options.crossOrigin\n      }\n    } else {\n      return false\n    }\n    if (url) {\n      img.src = url\n      return img\n    }\n    return loadImage.readFile(file, function (e) {\n      var target = e.target\n      if (target && target.result) {\n        img.src = target.result\n      } else if (callback) {\n        callback(e)\n      }\n    })\n  }\n  // The check for URL.revokeObjectURL fixes an issue with Opera 12,\n  // which provides URL.createObjectURL but doesn't properly implement it:\n  var urlAPI = (window.createObjectURL && window) ||\n                (window.URL && URL.revokeObjectURL && URL) ||\n                (window.webkitURL && webkitURL)\n\n  function revokeHelper (img, options) {\n    if (img._objectURL && !(options && options.noRevoke)) {\n      loadImage.revokeObjectURL(img._objectURL)\n      delete img._objectURL\n    }\n  }\n\n  loadImage.isInstanceOf = function (type, obj) {\n    // Cross-frame instanceof check\n    return Object.prototype.toString.call(obj) === '[object ' + type + ']'\n  }\n\n  loadImage.transform = function (img, options, callback, file, data) {\n    callback(loadImage.scale(img, options, data), data)\n  }\n\n  loadImage.onerror = function (img, event, file, callback, options) {\n    revokeHelper(img, options)\n    if (callback) {\n      callback.call(img, event)\n    }\n  }\n\n  loadImage.onload = function (img, event, file, callback, options) {\n    revokeHelper(img, options)\n    if (callback) {\n      loadImage.transform(img, options, callback, file, {})\n    }\n  }\n\n  // Transform image coordinates, allows to override e.g.\n  // the canvas orientation based on the orientation option,\n  // gets canvas, options passed as arguments:\n  loadImage.transformCoordinates = function () {\n    return\n  }\n\n  // Returns transformed options, allows to override e.g.\n  // maxWidth, maxHeight and crop options based on the aspectRatio.\n  // gets img, options passed as arguments:\n  loadImage.getTransformedOptions = function (img, options) {\n    var aspectRatio = options.aspectRatio\n    var newOptions\n    var i\n    var width\n    var height\n    if (!aspectRatio) {\n      return options\n    }\n    newOptions = {}\n    for (i in options) {\n      if (options.hasOwnProperty(i)) {\n        newOptions[i] = options[i]\n      }\n    }\n    newOptions.crop = true\n    width = img.naturalWidth || img.width\n    height = img.naturalHeight || img.height\n    if (width / height > aspectRatio) {\n      newOptions.maxWidth = height * aspectRatio\n      newOptions.maxHeight = height\n    } else {\n      newOptions.maxWidth = width\n      newOptions.maxHeight = width / aspectRatio\n    }\n    return newOptions\n  }\n\n  // Canvas render method, allows to implement a different rendering algorithm:\n  loadImage.renderImageToCanvas = function (\n    canvas,\n    img,\n    sourceX,\n    sourceY,\n    sourceWidth,\n    sourceHeight,\n    destX,\n    destY,\n    destWidth,\n    destHeight\n  ) {\n    canvas.getContext('2d').drawImage(\n      img,\n      sourceX,\n      sourceY,\n      sourceWidth,\n      sourceHeight,\n      destX,\n      destY,\n      destWidth,\n      destHeight\n    )\n    return canvas\n  }\n\n  // Determines if the target image should be a canvas element:\n  loadImage.hasCanvasOption = function (options) {\n    return options.canvas || options.crop || !!options.aspectRatio\n  }\n\n  // Scales and/or crops the given image (img or canvas HTML element)\n  // using the given options.\n  // Returns a canvas object if the browser supports canvas\n  // and the hasCanvasOption method returns true or a canvas\n  // object is passed as image, else the scaled image:\n  loadImage.scale = function (img, options, data) {\n    options = options || {}\n    var canvas = document.createElement('canvas')\n    var useCanvas = img.getContext ||\n                    (loadImage.hasCanvasOption(options) && canvas.getContext)\n    var width = img.naturalWidth || img.width\n    var height = img.naturalHeight || img.height\n    var destWidth = width\n    var destHeight = height\n    var maxWidth\n    var maxHeight\n    var minWidth\n    var minHeight\n    var sourceWidth\n    var sourceHeight\n    var sourceX\n    var sourceY\n    var pixelRatio\n    var downsamplingRatio\n    var tmp\n    function scaleUp () {\n      var scale = Math.max(\n        (minWidth || destWidth) / destWidth,\n        (minHeight || destHeight) / destHeight\n      )\n      if (scale > 1) {\n        destWidth *= scale\n        destHeight *= scale\n      }\n    }\n    function scaleDown () {\n      var scale = Math.min(\n        (maxWidth || destWidth) / destWidth,\n        (maxHeight || destHeight) / destHeight\n      )\n      if (scale < 1) {\n        destWidth *= scale\n        destHeight *= scale\n      }\n    }\n    if (useCanvas) {\n      options = loadImage.getTransformedOptions(img, options, data)\n      sourceX = options.left || 0\n      sourceY = options.top || 0\n      if (options.sourceWidth) {\n        sourceWidth = options.sourceWidth\n        if (options.right !== undefined && options.left === undefined) {\n          sourceX = width - sourceWidth - options.right\n        }\n      } else {\n        sourceWidth = width - sourceX - (options.right || 0)\n      }\n      if (options.sourceHeight) {\n        sourceHeight = options.sourceHeight\n        if (options.bottom !== undefined && options.top === undefined) {\n          sourceY = height - sourceHeight - options.bottom\n        }\n      } else {\n        sourceHeight = height - sourceY - (options.bottom || 0)\n      }\n      destWidth = sourceWidth\n      destHeight = sourceHeight\n    }\n    maxWidth = options.maxWidth\n    maxHeight = options.maxHeight\n    minWidth = options.minWidth\n    minHeight = options.minHeight\n    if (useCanvas && maxWidth && maxHeight && options.crop) {\n      destWidth = maxWidth\n      destHeight = maxHeight\n      tmp = sourceWidth / sourceHeight - maxWidth / maxHeight\n      if (tmp < 0) {\n        sourceHeight = maxHeight * sourceWidth / maxWidth\n        if (options.top === undefined && options.bottom === undefined) {\n          sourceY = (height - sourceHeight) / 2\n        }\n      } else if (tmp > 0) {\n        sourceWidth = maxWidth * sourceHeight / maxHeight\n        if (options.left === undefined && options.right === undefined) {\n          sourceX = (width - sourceWidth) / 2\n        }\n      }\n    } else {\n      if (options.contain || options.cover) {\n        minWidth = maxWidth = maxWidth || minWidth\n        minHeight = maxHeight = maxHeight || minHeight\n      }\n      if (options.cover) {\n        scaleDown()\n        scaleUp()\n      } else {\n        scaleUp()\n        scaleDown()\n      }\n    }\n    if (useCanvas) {\n      pixelRatio = options.pixelRatio\n      if (pixelRatio > 1) {\n        canvas.style.width = destWidth + 'px'\n        canvas.style.height = destHeight + 'px'\n        destWidth *= pixelRatio\n        destHeight *= pixelRatio\n        canvas.getContext('2d').scale(pixelRatio, pixelRatio)\n      }\n      downsamplingRatio = options.downsamplingRatio\n      if (downsamplingRatio > 0 && downsamplingRatio < 1 &&\n            destWidth < sourceWidth && destHeight < sourceHeight) {\n        while (sourceWidth * downsamplingRatio > destWidth) {\n          canvas.width = sourceWidth * downsamplingRatio\n          canvas.height = sourceHeight * downsamplingRatio\n          loadImage.renderImageToCanvas(\n            canvas,\n            img,\n            sourceX,\n            sourceY,\n            sourceWidth,\n            sourceHeight,\n            0,\n            0,\n            canvas.width,\n            canvas.height\n          )\n          sourceX = 0\n          sourceY = 0\n          sourceWidth = canvas.width\n          sourceHeight = canvas.height\n          img = document.createElement('canvas')\n          img.width = sourceWidth\n          img.height = sourceHeight\n          loadImage.renderImageToCanvas(\n            img,\n            canvas,\n            0,\n            0,\n            sourceWidth,\n            sourceHeight,\n            0,\n            0,\n            sourceWidth,\n            sourceHeight\n          )\n        }\n      }\n      canvas.width = destWidth\n      canvas.height = destHeight\n      loadImage.transformCoordinates(\n        canvas,\n        options\n      )\n      return loadImage.renderImageToCanvas(\n        canvas,\n        img,\n        sourceX,\n        sourceY,\n        sourceWidth,\n        sourceHeight,\n        0,\n        0,\n        destWidth,\n        destHeight\n      )\n    }\n    img.width = destWidth\n    img.height = destHeight\n    return img\n  }\n\n  loadImage.createObjectURL = function (file) {\n    return urlAPI ? urlAPI.createObjectURL(file) : false\n  }\n\n  loadImage.revokeObjectURL = function (url) {\n    return urlAPI ? urlAPI.revokeObjectURL(url) : false\n  }\n\n  // Loads a given File object via FileReader interface,\n  // invokes the callback with the event object (load or error).\n  // The result can be read via event.target.result:\n  loadImage.readFile = function (file, callback, method) {\n    if (window.FileReader) {\n      var fileReader = new FileReader()\n      fileReader.onload = fileReader.onerror = callback\n      method = method || 'readAsDataURL'\n      if (fileReader[method]) {\n        fileReader[method](file)\n        return fileReader\n      }\n    }\n    return false\n  }\n\n  if (typeof define === 'function' && define.amd) {\n    define(function () {\n      return loadImage\n    })\n  } else if (typeof module === 'object' && module.exports) {\n    module.exports = loadImage\n  } else {\n    $.loadImage = loadImage\n  }\n}(window))\n"
  },
  {
    "path": "app_backend/static/plugin/JavaScript-Canvas-to-Blob-3.7.0/test/vendor/mocha.css",
    "content": "@charset \"utf-8\";\n\nbody {\n  margin:0;\n}\n\n#mocha {\n  font: 20px/1.5 \"Helvetica Neue\", Helvetica, Arial, sans-serif;\n  margin: 60px 50px;\n}\n\n#mocha ul,\n#mocha li {\n  margin: 0;\n  padding: 0;\n}\n\n#mocha ul {\n  list-style: none;\n}\n\n#mocha h1,\n#mocha h2 {\n  margin: 0;\n}\n\n#mocha h1 {\n  margin-top: 15px;\n  font-size: 1em;\n  font-weight: 200;\n}\n\n#mocha h1 a {\n  text-decoration: none;\n  color: inherit;\n}\n\n#mocha h1 a:hover {\n  text-decoration: underline;\n}\n\n#mocha .suite .suite h1 {\n  margin-top: 0;\n  font-size: .8em;\n}\n\n#mocha .hidden {\n  display: none;\n}\n\n#mocha h2 {\n  font-size: 12px;\n  font-weight: normal;\n  cursor: pointer;\n}\n\n#mocha .suite {\n  margin-left: 15px;\n}\n\n#mocha .test {\n  margin-left: 15px;\n  overflow: hidden;\n}\n\n#mocha .test.pending:hover h2::after {\n  content: '(pending)';\n  font-family: arial, sans-serif;\n}\n\n#mocha .test.pass.medium .duration {\n  background: #c09853;\n}\n\n#mocha .test.pass.slow .duration {\n  background: #b94a48;\n}\n\n#mocha .test.pass::before {\n  content: '✓';\n  font-size: 12px;\n  display: block;\n  float: left;\n  margin-right: 5px;\n  color: #00d6b2;\n}\n\n#mocha .test.pass .duration {\n  font-size: 9px;\n  margin-left: 5px;\n  padding: 2px 5px;\n  color: #fff;\n  -webkit-box-shadow: inset 0 1px 1px rgba(0,0,0,.2);\n  -moz-box-shadow: inset 0 1px 1px rgba(0,0,0,.2);\n  box-shadow: inset 0 1px 1px rgba(0,0,0,.2);\n  -webkit-border-radius: 5px;\n  -moz-border-radius: 5px;\n  -ms-border-radius: 5px;\n  -o-border-radius: 5px;\n  border-radius: 5px;\n}\n\n#mocha .test.pass.fast .duration {\n  display: none;\n}\n\n#mocha .test.pending {\n  color: #0b97c4;\n}\n\n#mocha .test.pending::before {\n  content: '◦';\n  color: #0b97c4;\n}\n\n#mocha .test.fail {\n  color: #c00;\n}\n\n#mocha .test.fail pre {\n  color: black;\n}\n\n#mocha .test.fail::before {\n  content: '✖';\n  font-size: 12px;\n  display: block;\n  float: left;\n  margin-right: 5px;\n  color: #c00;\n}\n\n#mocha .test pre.error {\n  color: #c00;\n  max-height: 300px;\n  overflow: auto;\n}\n\n#mocha .test .html-error {\n  overflow: auto;\n  color: black;\n  line-height: 1.5;\n  display: block;\n  float: left;\n  clear: left;\n  font: 12px/1.5 monaco, monospace;\n  margin: 5px;\n  padding: 15px;\n  border: 1px solid #eee;\n  max-width: 85%; /*(1)*/\n  max-width: -webkit-calc(100% - 42px);\n  max-width: -moz-calc(100% - 42px);\n  max-width: calc(100% - 42px); /*(2)*/\n  max-height: 300px;\n  word-wrap: break-word;\n  border-bottom-color: #ddd;\n  -webkit-box-shadow: 0 1px 3px #eee;\n  -moz-box-shadow: 0 1px 3px #eee;\n  box-shadow: 0 1px 3px #eee;\n  -webkit-border-radius: 3px;\n  -moz-border-radius: 3px;\n  border-radius: 3px;\n}\n\n#mocha .test .html-error pre.error {\n  border: none;\n  -webkit-border-radius: 0;\n  -moz-border-radius: 0;\n  border-radius: 0;\n  -webkit-box-shadow: 0;\n  -moz-box-shadow: 0;\n  box-shadow: 0;\n  padding: 0;\n  margin: 0;\n  margin-top: 18px;\n  max-height: none;\n}\n\n/**\n * (1): approximate for browsers not supporting calc\n * (2): 42 = 2*15 + 2*10 + 2*1 (padding + margin + border)\n *      ^^ seriously\n */\n#mocha .test pre {\n  display: block;\n  float: left;\n  clear: left;\n  font: 12px/1.5 monaco, monospace;\n  margin: 5px;\n  padding: 15px;\n  border: 1px solid #eee;\n  max-width: 85%; /*(1)*/\n  max-width: -webkit-calc(100% - 42px);\n  max-width: -moz-calc(100% - 42px);\n  max-width: calc(100% - 42px); /*(2)*/\n  word-wrap: break-word;\n  border-bottom-color: #ddd;\n  -webkit-box-shadow: 0 1px 3px #eee;\n  -moz-box-shadow: 0 1px 3px #eee;\n  box-shadow: 0 1px 3px #eee;\n  -webkit-border-radius: 3px;\n  -moz-border-radius: 3px;\n  border-radius: 3px;\n}\n\n#mocha .test h2 {\n  position: relative;\n}\n\n#mocha .test a.replay {\n  position: absolute;\n  top: 3px;\n  right: 0;\n  text-decoration: none;\n  vertical-align: middle;\n  display: block;\n  width: 15px;\n  height: 15px;\n  line-height: 15px;\n  text-align: center;\n  background: #eee;\n  font-size: 15px;\n  -webkit-border-radius: 15px;\n  -moz-border-radius: 15px;\n  border-radius: 15px;\n  -webkit-transition:opacity 200ms;\n  -moz-transition:opacity 200ms;\n  -o-transition:opacity 200ms;\n  transition: opacity 200ms;\n  opacity: 0.3;\n  color: #888;\n}\n\n#mocha .test:hover a.replay {\n  opacity: 1;\n}\n\n#mocha-report.pass .test.fail {\n  display: none;\n}\n\n#mocha-report.fail .test.pass {\n  display: none;\n}\n\n#mocha-report.pending .test.pass,\n#mocha-report.pending .test.fail {\n  display: none;\n}\n#mocha-report.pending .test.pass.pending {\n  display: block;\n}\n\n#mocha-error {\n  color: #c00;\n  font-size: 1.5em;\n  font-weight: 100;\n  letter-spacing: 1px;\n}\n\n#mocha-stats {\n  position: fixed;\n  top: 15px;\n  right: 10px;\n  font-size: 12px;\n  margin: 0;\n  color: #888;\n  z-index: 1;\n}\n\n#mocha-stats .progress {\n  float: right;\n  padding-top: 0;\n\n  /**\n   * Set safe initial values, so mochas .progress does not inherit these\n   * properties from Bootstrap .progress (which causes .progress height to\n   * equal line height set in Bootstrap).\n   */\n  height: auto;\n  -webkit-box-shadow: none;\n  -moz-box-shadow: none;\n  box-shadow: none;\n  background-color: initial;\n}\n\n#mocha-stats em {\n  color: black;\n}\n\n#mocha-stats a {\n  text-decoration: none;\n  color: inherit;\n}\n\n#mocha-stats a:hover {\n  border-bottom: 1px solid #eee;\n}\n\n#mocha-stats li {\n  display: inline-block;\n  margin: 0 5px;\n  list-style: none;\n  padding-top: 11px;\n}\n\n#mocha-stats canvas {\n  width: 40px;\n  height: 40px;\n}\n\n#mocha code .comment { color: #ddd; }\n#mocha code .init { color: #2f6fad; }\n#mocha code .string { color: #5890ad; }\n#mocha code .keyword { color: #8a6343; }\n#mocha code .number { color: #2f6fad; }\n\n@media screen and (max-device-width: 480px) {\n  #mocha {\n    margin: 60px 0px;\n  }\n\n  #mocha #stats {\n    position: absolute;\n  }\n}\n"
  },
  {
    "path": "app_backend/static/plugin/JavaScript-Canvas-to-Blob-3.7.0/test/vendor/mocha.js",
    "content": "(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require==\"function\"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error(\"Cannot find module '\"+o+\"'\");throw f.code=\"MODULE_NOT_FOUND\",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require==\"function\"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){\n(function (process,global){\n/* eslint no-unused-vars: off */\n\n/**\n * Shim process.stdout.\n */\n\nprocess.stdout = require('browser-stdout')();\n\nvar Mocha = require('./lib/mocha');\n\n/**\n * Create a Mocha instance.\n *\n * @return {undefined}\n */\n\nvar mocha = new Mocha({ reporter: 'html' });\n\n/**\n * Save timer references to avoid Sinon interfering (see GH-237).\n */\n\nvar Date = global.Date;\nvar setTimeout = global.setTimeout;\nvar setInterval = global.setInterval;\nvar clearTimeout = global.clearTimeout;\nvar clearInterval = global.clearInterval;\n\nvar uncaughtExceptionHandlers = [];\n\nvar originalOnerrorHandler = global.onerror;\n\n/**\n * Remove uncaughtException listener.\n * Revert to original onerror handler if previously defined.\n */\n\nprocess.removeListener = function(e, fn) {\n  if (e === 'uncaughtException') {\n    if (originalOnerrorHandler) {\n      global.onerror = originalOnerrorHandler;\n    } else {\n      global.onerror = function() {};\n    }\n    var i = Mocha.utils.indexOf(uncaughtExceptionHandlers, fn);\n    if (i !== -1) {\n      uncaughtExceptionHandlers.splice(i, 1);\n    }\n  }\n};\n\n/**\n * Implements uncaughtException listener.\n */\n\nprocess.on = function(e, fn) {\n  if (e === 'uncaughtException') {\n    global.onerror = function(err, url, line) {\n      fn(new Error(err + ' (' + url + ':' + line + ')'));\n      return !mocha.allowUncaught;\n    };\n    uncaughtExceptionHandlers.push(fn);\n  }\n};\n\n// The BDD UI is registered by default, but no UI will be functional in the\n// browser without an explicit call to the overridden `mocha.ui` (see below).\n// Ensure that this default UI does not expose its methods to the global scope.\nmocha.suite.removeAllListeners('pre-require');\n\nvar immediateQueue = [];\nvar immediateTimeout;\n\nfunction timeslice() {\n  var immediateStart = new Date().getTime();\n  while (immediateQueue.length && (new Date().getTime() - immediateStart) < 100) {\n    immediateQueue.shift()();\n  }\n  if (immediateQueue.length) {\n    immediateTimeout = setTimeout(timeslice, 0);\n  } else {\n    immediateTimeout = null;\n  }\n}\n\n/**\n * High-performance override of Runner.immediately.\n */\n\nMocha.Runner.immediately = function(callback) {\n  immediateQueue.push(callback);\n  if (!immediateTimeout) {\n    immediateTimeout = setTimeout(timeslice, 0);\n  }\n};\n\n/**\n * Function to allow assertion libraries to throw errors directly into mocha.\n * This is useful when running tests in a browser because window.onerror will\n * only receive the 'message' attribute of the Error.\n */\nmocha.throwError = function(err) {\n  Mocha.utils.forEach(uncaughtExceptionHandlers, function(fn) {\n    fn(err);\n  });\n  throw err;\n};\n\n/**\n * Override ui to ensure that the ui functions are initialized.\n * Normally this would happen in Mocha.prototype.loadFiles.\n */\n\nmocha.ui = function(ui) {\n  Mocha.prototype.ui.call(this, ui);\n  this.suite.emit('pre-require', global, null, this);\n  return this;\n};\n\n/**\n * Setup mocha with the given setting options.\n */\n\nmocha.setup = function(opts) {\n  if (typeof opts === 'string') {\n    opts = { ui: opts };\n  }\n  for (var opt in opts) {\n    if (opts.hasOwnProperty(opt)) {\n      this[opt](opts[opt]);\n    }\n  }\n  return this;\n};\n\n/**\n * Run mocha, returning the Runner.\n */\n\nmocha.run = function(fn) {\n  var options = mocha.options;\n  mocha.globals('location');\n\n  var query = Mocha.utils.parseQuery(global.location.search || '');\n  if (query.grep) {\n    mocha.grep(query.grep);\n  }\n  if (query.fgrep) {\n    mocha.fgrep(query.fgrep);\n  }\n  if (query.invert) {\n    mocha.invert();\n  }\n\n  return Mocha.prototype.run.call(mocha, function(err) {\n    // The DOM Document is not available in Web Workers.\n    var document = global.document;\n    if (document && document.getElementById('mocha') && options.noHighlighting !== true) {\n      Mocha.utils.highlightTags('code');\n    }\n    if (fn) {\n      fn(err);\n    }\n  });\n};\n\n/**\n * Expose the process shim.\n * https://github.com/mochajs/mocha/pull/916\n */\n\nMocha.process = process;\n\n/**\n * Expose mocha.\n */\n\nglobal.Mocha = Mocha;\nglobal.mocha = mocha;\n\n// this allows test/acceptance/required-tokens.js to pass; thus,\n// you can now do `const describe = require('mocha').describe` in a\n// browser context (assuming browserification).  should fix #880\nmodule.exports = global;\n\n}).call(this,require('_process'),typeof global !== \"undefined\" ? global : typeof self !== \"undefined\" ? self : typeof window !== \"undefined\" ? window : {})\n},{\"./lib/mocha\":14,\"_process\":67,\"browser-stdout\":41}],2:[function(require,module,exports){\n/* eslint-disable no-unused-vars */\nmodule.exports = function(type) {\n  return function() {};\n};\n\n},{}],3:[function(require,module,exports){\n/**\n * Module exports.\n */\n\nexports.EventEmitter = EventEmitter;\n\n/**\n * Object#toString reference.\n */\nvar objToString = Object.prototype.toString;\n\n/**\n * Check if a value is an array.\n *\n * @api private\n * @param {*} val The value to test.\n * @return {boolean} true if the value is an array, otherwise false.\n */\nfunction isArray(val) {\n  return objToString.call(val) === '[object Array]';\n}\n\n/**\n * Event emitter constructor.\n *\n * @api public\n */\nfunction EventEmitter() {}\n\n/**\n * Add a listener.\n *\n * @api public\n * @param {string} name Event name.\n * @param {Function} fn Event handler.\n * @return {EventEmitter} Emitter instance.\n */\nEventEmitter.prototype.on = function(name, fn) {\n  if (!this.$events) {\n    this.$events = {};\n  }\n\n  if (!this.$events[name]) {\n    this.$events[name] = fn;\n  } else if (isArray(this.$events[name])) {\n    this.$events[name].push(fn);\n  } else {\n    this.$events[name] = [this.$events[name], fn];\n  }\n\n  return this;\n};\n\nEventEmitter.prototype.addListener = EventEmitter.prototype.on;\n\n/**\n * Adds a volatile listener.\n *\n * @api public\n * @param {string} name Event name.\n * @param {Function} fn Event handler.\n * @return {EventEmitter} Emitter instance.\n */\nEventEmitter.prototype.once = function(name, fn) {\n  var self = this;\n\n  function on() {\n    self.removeListener(name, on);\n    fn.apply(this, arguments);\n  }\n\n  on.listener = fn;\n  this.on(name, on);\n\n  return this;\n};\n\n/**\n * Remove a listener.\n *\n * @api public\n * @param {string} name Event name.\n * @param {Function} fn Event handler.\n * @return {EventEmitter} Emitter instance.\n */\nEventEmitter.prototype.removeListener = function(name, fn) {\n  if (this.$events && this.$events[name]) {\n    var list = this.$events[name];\n\n    if (isArray(list)) {\n      var pos = -1;\n\n      for (var i = 0, l = list.length; i < l; i++) {\n        if (list[i] === fn || (list[i].listener && list[i].listener === fn)) {\n          pos = i;\n          break;\n        }\n      }\n\n      if (pos < 0) {\n        return this;\n      }\n\n      list.splice(pos, 1);\n\n      if (!list.length) {\n        delete this.$events[name];\n      }\n    } else if (list === fn || (list.listener && list.listener === fn)) {\n      delete this.$events[name];\n    }\n  }\n\n  return this;\n};\n\n/**\n * Remove all listeners for an event.\n *\n * @api public\n * @param {string} name Event name.\n * @return {EventEmitter} Emitter instance.\n */\nEventEmitter.prototype.removeAllListeners = function(name) {\n  if (name === undefined) {\n    this.$events = {};\n    return this;\n  }\n\n  if (this.$events && this.$events[name]) {\n    this.$events[name] = null;\n  }\n\n  return this;\n};\n\n/**\n * Get all listeners for a given event.\n *\n * @api public\n * @param {string} name Event name.\n * @return {EventEmitter} Emitter instance.\n */\nEventEmitter.prototype.listeners = function(name) {\n  if (!this.$events) {\n    this.$events = {};\n  }\n\n  if (!this.$events[name]) {\n    this.$events[name] = [];\n  }\n\n  if (!isArray(this.$events[name])) {\n    this.$events[name] = [this.$events[name]];\n  }\n\n  return this.$events[name];\n};\n\n/**\n * Emit an event.\n *\n * @api public\n * @param {string} name Event name.\n * @return {boolean} true if at least one handler was invoked, else false.\n */\nEventEmitter.prototype.emit = function(name) {\n  if (!this.$events) {\n    return false;\n  }\n\n  var handler = this.$events[name];\n\n  if (!handler) {\n    return false;\n  }\n\n  var args = Array.prototype.slice.call(arguments, 1);\n\n  if (typeof handler === 'function') {\n    handler.apply(this, args);\n  } else if (isArray(handler)) {\n    var listeners = handler.slice();\n\n    for (var i = 0, l = listeners.length; i < l; i++) {\n      listeners[i].apply(this, args);\n    }\n  } else {\n    return false;\n  }\n\n  return true;\n};\n\n},{}],4:[function(require,module,exports){\n/**\n * Expose `Progress`.\n */\n\nmodule.exports = Progress;\n\n/**\n * Initialize a new `Progress` indicator.\n */\nfunction Progress() {\n  this.percent = 0;\n  this.size(0);\n  this.fontSize(11);\n  this.font('helvetica, arial, sans-serif');\n}\n\n/**\n * Set progress size to `size`.\n *\n * @api public\n * @param {number} size\n * @return {Progress} Progress instance.\n */\nProgress.prototype.size = function(size) {\n  this._size = size;\n  return this;\n};\n\n/**\n * Set text to `text`.\n *\n * @api public\n * @param {string} text\n * @return {Progress} Progress instance.\n */\nProgress.prototype.text = function(text) {\n  this._text = text;\n  return this;\n};\n\n/**\n * Set font size to `size`.\n *\n * @api public\n * @param {number} size\n * @return {Progress} Progress instance.\n */\nProgress.prototype.fontSize = function(size) {\n  this._fontSize = size;\n  return this;\n};\n\n/**\n * Set font to `family`.\n *\n * @param {string} family\n * @return {Progress} Progress instance.\n */\nProgress.prototype.font = function(family) {\n  this._font = family;\n  return this;\n};\n\n/**\n * Update percentage to `n`.\n *\n * @param {number} n\n * @return {Progress} Progress instance.\n */\nProgress.prototype.update = function(n) {\n  this.percent = n;\n  return this;\n};\n\n/**\n * Draw on `ctx`.\n *\n * @param {CanvasRenderingContext2d} ctx\n * @return {Progress} Progress instance.\n */\nProgress.prototype.draw = function(ctx) {\n  try {\n    var percent = Math.min(this.percent, 100);\n    var size = this._size;\n    var half = size / 2;\n    var x = half;\n    var y = half;\n    var rad = half - 1;\n    var fontSize = this._fontSize;\n\n    ctx.font = fontSize + 'px ' + this._font;\n\n    var angle = Math.PI * 2 * (percent / 100);\n    ctx.clearRect(0, 0, size, size);\n\n    // outer circle\n    ctx.strokeStyle = '#9f9f9f';\n    ctx.beginPath();\n    ctx.arc(x, y, rad, 0, angle, false);\n    ctx.stroke();\n\n    // inner circle\n    ctx.strokeStyle = '#eee';\n    ctx.beginPath();\n    ctx.arc(x, y, rad - 1, 0, angle, true);\n    ctx.stroke();\n\n    // text\n    var text = this._text || (percent | 0) + '%';\n    var w = ctx.measureText(text).width;\n\n    ctx.fillText(text, x - w / 2 + 1, y + fontSize / 2 - 1);\n  } catch (err) {\n    // don't fail if we can't render progress\n  }\n  return this;\n};\n\n},{}],5:[function(require,module,exports){\n(function (global){\nexports.isatty = function isatty() {\n  return true;\n};\n\nexports.getWindowSize = function getWindowSize() {\n  if ('innerHeight' in global) {\n    return [global.innerHeight, global.innerWidth];\n  }\n  // In a Web Worker, the DOM Window is not available.\n  return [640, 480];\n};\n\n}).call(this,typeof global !== \"undefined\" ? global : typeof self !== \"undefined\" ? self : typeof window !== \"undefined\" ? window : {})\n},{}],6:[function(require,module,exports){\n/**\n * Module dependencies.\n */\n\nvar JSON = require('json3');\n\n/**\n * Expose `Context`.\n */\n\nmodule.exports = Context;\n\n/**\n * Initialize a new `Context`.\n *\n * @api private\n */\nfunction Context() {}\n\n/**\n * Set or get the context `Runnable` to `runnable`.\n *\n * @api private\n * @param {Runnable} runnable\n * @return {Context}\n */\nContext.prototype.runnable = function(runnable) {\n  if (!arguments.length) {\n    return this._runnable;\n  }\n  this.test = this._runnable = runnable;\n  return this;\n};\n\n/**\n * Set test timeout `ms`.\n *\n * @api private\n * @param {number} ms\n * @return {Context} self\n */\nContext.prototype.timeout = function(ms) {\n  if (!arguments.length) {\n    return this.runnable().timeout();\n  }\n  this.runnable().timeout(ms);\n  return this;\n};\n\n/**\n * Set test timeout `enabled`.\n *\n * @api private\n * @param {boolean} enabled\n * @return {Context} self\n */\nContext.prototype.enableTimeouts = function(enabled) {\n  this.runnable().enableTimeouts(enabled);\n  return this;\n};\n\n/**\n * Set test slowness threshold `ms`.\n *\n * @api private\n * @param {number} ms\n * @return {Context} self\n */\nContext.prototype.slow = function(ms) {\n  this.runnable().slow(ms);\n  return this;\n};\n\n/**\n * Mark a test as skipped.\n *\n * @api private\n * @return {Context} self\n */\nContext.prototype.skip = function() {\n  this.runnable().skip();\n  return this;\n};\n\n/**\n * Allow a number of retries on failed tests\n *\n * @api private\n * @param {number} n\n * @return {Context} self\n */\nContext.prototype.retries = function(n) {\n  if (!arguments.length) {\n    return this.runnable().retries();\n  }\n  this.runnable().retries(n);\n  return this;\n};\n\n/**\n * Inspect the context void of `._runnable`.\n *\n * @api private\n * @return {string}\n */\nContext.prototype.inspect = function() {\n  return JSON.stringify(this, function(key, val) {\n    return key === 'runnable' || key === 'test' ? undefined : val;\n  }, 2);\n};\n\n},{\"json3\":54}],7:[function(require,module,exports){\n/**\n * Module dependencies.\n */\n\nvar Runnable = require('./runnable');\nvar inherits = require('./utils').inherits;\n\n/**\n * Expose `Hook`.\n */\n\nmodule.exports = Hook;\n\n/**\n * Initialize a new `Hook` with the given `title` and callback `fn`.\n *\n * @param {String} title\n * @param {Function} fn\n * @api private\n */\nfunction Hook(title, fn) {\n  Runnable.call(this, title, fn);\n  this.type = 'hook';\n}\n\n/**\n * Inherit from `Runnable.prototype`.\n */\ninherits(Hook, Runnable);\n\n/**\n * Get or set the test `err`.\n *\n * @param {Error} err\n * @return {Error}\n * @api public\n */\nHook.prototype.error = function(err) {\n  if (!arguments.length) {\n    err = this._error;\n    this._error = null;\n    return err;\n  }\n\n  this._error = err;\n};\n\n},{\"./runnable\":33,\"./utils\":38}],8:[function(require,module,exports){\n/**\n * Module dependencies.\n */\n\nvar Test = require('../test');\n\n/**\n * BDD-style interface:\n *\n *      describe('Array', function() {\n *        describe('#indexOf()', function() {\n *          it('should return -1 when not present', function() {\n *            // ...\n *          });\n *\n *          it('should return the index when present', function() {\n *            // ...\n *          });\n *        });\n *      });\n *\n * @param {Suite} suite Root suite.\n */\nmodule.exports = function(suite) {\n  var suites = [suite];\n\n  suite.on('pre-require', function(context, file, mocha) {\n    var common = require('./common')(suites, context, mocha);\n\n    context.before = common.before;\n    context.after = common.after;\n    context.beforeEach = common.beforeEach;\n    context.afterEach = common.afterEach;\n    context.run = mocha.options.delay && common.runWithSuite(suite);\n    /**\n     * Describe a \"suite\" with the given `title`\n     * and callback `fn` containing nested suites\n     * and/or tests.\n     */\n\n    context.describe = context.context = function(title, fn) {\n      return common.suite.create({\n        title: title,\n        file: file,\n        fn: fn\n      });\n    };\n\n    /**\n     * Pending describe.\n     */\n\n    context.xdescribe = context.xcontext = context.describe.skip = function(title, fn) {\n      return common.suite.skip({\n        title: title,\n        file: file,\n        fn: fn\n      });\n    };\n\n    /**\n     * Exclusive suite.\n     */\n\n    context.describe.only = function(title, fn) {\n      return common.suite.only({\n        title: title,\n        file: file,\n        fn: fn\n      });\n    };\n\n    /**\n     * Describe a specification or test-case\n     * with the given `title` and callback `fn`\n     * acting as a thunk.\n     */\n\n    context.it = context.specify = function(title, fn) {\n      var suite = suites[0];\n      if (suite.isPending()) {\n        fn = null;\n      }\n      var test = new Test(title, fn);\n      test.file = file;\n      suite.addTest(test);\n      return test;\n    };\n\n    /**\n     * Exclusive test-case.\n     */\n\n    context.it.only = function(title, fn) {\n      return common.test.only(mocha, context.it(title, fn));\n    };\n\n    /**\n     * Pending test case.\n     */\n\n    context.xit = context.xspecify = context.it.skip = function(title) {\n      context.it(title);\n    };\n\n    /**\n     * Number of attempts to retry.\n     */\n    context.it.retries = function(n) {\n      context.retries(n);\n    };\n  });\n};\n\n},{\"../test\":36,\"./common\":9}],9:[function(require,module,exports){\n'use strict';\n\nvar Suite = require('../suite');\n\n/**\n * Functions common to more than one interface.\n *\n * @param {Suite[]} suites\n * @param {Context} context\n * @param {Mocha} mocha\n * @return {Object} An object containing common functions.\n */\nmodule.exports = function(suites, context, mocha) {\n  return {\n    /**\n     * This is only present if flag --delay is passed into Mocha. It triggers\n     * root suite execution.\n     *\n     * @param {Suite} suite The root wuite.\n     * @return {Function} A function which runs the root suite\n     */\n    runWithSuite: function runWithSuite(suite) {\n      return function run() {\n        suite.run();\n      };\n    },\n\n    /**\n     * Execute before running tests.\n     *\n     * @param {string} name\n     * @param {Function} fn\n     */\n    before: function(name, fn) {\n      suites[0].beforeAll(name, fn);\n    },\n\n    /**\n     * Execute after running tests.\n     *\n     * @param {string} name\n     * @param {Function} fn\n     */\n    after: function(name, fn) {\n      suites[0].afterAll(name, fn);\n    },\n\n    /**\n     * Execute before each test case.\n     *\n     * @param {string} name\n     * @param {Function} fn\n     */\n    beforeEach: function(name, fn) {\n      suites[0].beforeEach(name, fn);\n    },\n\n    /**\n     * Execute after each test case.\n     *\n     * @param {string} name\n     * @param {Function} fn\n     */\n    afterEach: function(name, fn) {\n      suites[0].afterEach(name, fn);\n    },\n\n    suite: {\n      /**\n       * Create an exclusive Suite; convenience function\n       * See docstring for create() below.\n       *\n       * @param {Object} opts\n       * @returns {Suite}\n       */\n      only: function only(opts) {\n        mocha.options.hasOnly = true;\n        opts.isOnly = true;\n        return this.create(opts);\n      },\n\n      /**\n       * Create a Suite, but skip it; convenience function\n       * See docstring for create() below.\n       *\n       * @param {Object} opts\n       * @returns {Suite}\n       */\n      skip: function skip(opts) {\n        opts.pending = true;\n        return this.create(opts);\n      },\n\n      /**\n       * Creates a suite.\n       * @param {Object} opts Options\n       * @param {string} opts.title Title of Suite\n       * @param {Function} [opts.fn] Suite Function (not always applicable)\n       * @param {boolean} [opts.pending] Is Suite pending?\n       * @param {string} [opts.file] Filepath where this Suite resides\n       * @param {boolean} [opts.isOnly] Is Suite exclusive?\n       * @returns {Suite}\n       */\n      create: function create(opts) {\n        var suite = Suite.create(suites[0], opts.title);\n        suite.pending = Boolean(opts.pending);\n        suite.file = opts.file;\n        suites.unshift(suite);\n        if (opts.isOnly) {\n          suite.parent._onlySuites = suite.parent._onlySuites.concat(suite);\n          mocha.options.hasOnly = true;\n        }\n        if (typeof opts.fn === 'function') {\n          opts.fn.call(suite);\n          suites.shift();\n        } else if (typeof opts.fn === 'undefined' && !suite.pending) {\n          throw new Error('Suite \"' + suite.fullTitle() + '\" was defined but no callback was supplied. Supply a callback or explicitly skip the suite.');\n        }\n\n        return suite;\n      }\n    },\n\n    test: {\n\n      /**\n       * Exclusive test-case.\n       *\n       * @param {Object} mocha\n       * @param {Function} test\n       * @returns {*}\n       */\n      only: function(mocha, test) {\n        test.parent._onlyTests = test.parent._onlyTests.concat(test);\n        mocha.options.hasOnly = true;\n        return test;\n      },\n\n      /**\n       * Pending test case.\n       *\n       * @param {string} title\n       */\n      skip: function(title) {\n        context.test(title);\n      },\n\n      /**\n       * Number of retry attempts\n       *\n       * @param {number} n\n       */\n      retries: function(n) {\n        context.retries(n);\n      }\n    }\n  };\n};\n\n},{\"../suite\":35}],10:[function(require,module,exports){\n/**\n * Module dependencies.\n */\n\nvar Suite = require('../suite');\nvar Test = require('../test');\n\n/**\n * Exports-style (as Node.js module) interface:\n *\n *     exports.Array = {\n *       '#indexOf()': {\n *         'should return -1 when the value is not present': function() {\n *\n *         },\n *\n *         'should return the correct index when the value is present': function() {\n *\n *         }\n *       }\n *     };\n *\n * @param {Suite} suite Root suite.\n */\nmodule.exports = function(suite) {\n  var suites = [suite];\n\n  suite.on('require', visit);\n\n  function visit(obj, file) {\n    var suite;\n    for (var key in obj) {\n      if (typeof obj[key] === 'function') {\n        var fn = obj[key];\n        switch (key) {\n          case 'before':\n            suites[0].beforeAll(fn);\n            break;\n          case 'after':\n            suites[0].afterAll(fn);\n            break;\n          case 'beforeEach':\n            suites[0].beforeEach(fn);\n            break;\n          case 'afterEach':\n            suites[0].afterEach(fn);\n            break;\n          default:\n            var test = new Test(key, fn);\n            test.file = file;\n            suites[0].addTest(test);\n        }\n      } else {\n        suite = Suite.create(suites[0], key);\n        suites.unshift(suite);\n        visit(obj[key], file);\n        suites.shift();\n      }\n    }\n  }\n};\n\n},{\"../suite\":35,\"../test\":36}],11:[function(require,module,exports){\nexports.bdd = require('./bdd');\nexports.tdd = require('./tdd');\nexports.qunit = require('./qunit');\nexports.exports = require('./exports');\n\n},{\"./bdd\":8,\"./exports\":10,\"./qunit\":12,\"./tdd\":13}],12:[function(require,module,exports){\n/**\n * Module dependencies.\n */\n\nvar Test = require('../test');\n\n/**\n * QUnit-style interface:\n *\n *     suite('Array');\n *\n *     test('#length', function() {\n *       var arr = [1,2,3];\n *       ok(arr.length == 3);\n *     });\n *\n *     test('#indexOf()', function() {\n *       var arr = [1,2,3];\n *       ok(arr.indexOf(1) == 0);\n *       ok(arr.indexOf(2) == 1);\n *       ok(arr.indexOf(3) == 2);\n *     });\n *\n *     suite('String');\n *\n *     test('#length', function() {\n *       ok('foo'.length == 3);\n *     });\n *\n * @param {Suite} suite Root suite.\n */\nmodule.exports = function(suite) {\n  var suites = [suite];\n\n  suite.on('pre-require', function(context, file, mocha) {\n    var common = require('./common')(suites, context, mocha);\n\n    context.before = common.before;\n    context.after = common.after;\n    context.beforeEach = common.beforeEach;\n    context.afterEach = common.afterEach;\n    context.run = mocha.options.delay && common.runWithSuite(suite);\n    /**\n     * Describe a \"suite\" with the given `title`.\n     */\n\n    context.suite = function(title) {\n      if (suites.length > 1) {\n        suites.shift();\n      }\n      return common.suite.create({\n        title: title,\n        file: file,\n        fn: false\n      });\n    };\n\n    /**\n     * Exclusive Suite.\n     */\n\n    context.suite.only = function(title) {\n      if (suites.length > 1) {\n        suites.shift();\n      }\n      return common.suite.only({\n        title: title,\n        file: file,\n        fn: false\n      });\n    };\n\n    /**\n     * Describe a specification or test-case\n     * with the given `title` and callback `fn`\n     * acting as a thunk.\n     */\n\n    context.test = function(title, fn) {\n      var test = new Test(title, fn);\n      test.file = file;\n      suites[0].addTest(test);\n      return test;\n    };\n\n    /**\n     * Exclusive test-case.\n     */\n\n    context.test.only = function(title, fn) {\n      return common.test.only(mocha, context.test(title, fn));\n    };\n\n    context.test.skip = common.test.skip;\n    context.test.retries = common.test.retries;\n  });\n};\n\n},{\"../test\":36,\"./common\":9}],13:[function(require,module,exports){\n/**\n * Module dependencies.\n */\n\nvar Test = require('../test');\n\n/**\n * TDD-style interface:\n *\n *      suite('Array', function() {\n *        suite('#indexOf()', function() {\n *          suiteSetup(function() {\n *\n *          });\n *\n *          test('should return -1 when not present', function() {\n *\n *          });\n *\n *          test('should return the index when present', function() {\n *\n *          });\n *\n *          suiteTeardown(function() {\n *\n *          });\n *        });\n *      });\n *\n * @param {Suite} suite Root suite.\n */\nmodule.exports = function(suite) {\n  var suites = [suite];\n\n  suite.on('pre-require', function(context, file, mocha) {\n    var common = require('./common')(suites, context, mocha);\n\n    context.setup = common.beforeEach;\n    context.teardown = common.afterEach;\n    context.suiteSetup = common.before;\n    context.suiteTeardown = common.after;\n    context.run = mocha.options.delay && common.runWithSuite(suite);\n\n    /**\n     * Describe a \"suite\" with the given `title` and callback `fn` containing\n     * nested suites and/or tests.\n     */\n    context.suite = function(title, fn) {\n      return common.suite.create({\n        title: title,\n        file: file,\n        fn: fn\n      });\n    };\n\n    /**\n     * Pending suite.\n     */\n    context.suite.skip = function(title, fn) {\n      return common.suite.skip({\n        title: title,\n        file: file,\n        fn: fn\n      });\n    };\n\n    /**\n     * Exclusive test-case.\n     */\n    context.suite.only = function(title, fn) {\n      return common.suite.only({\n        title: title,\n        file: file,\n        fn: fn\n      });\n    };\n\n    /**\n     * Describe a specification or test-case with the given `title` and\n     * callback `fn` acting as a thunk.\n     */\n    context.test = function(title, fn) {\n      var suite = suites[0];\n      if (suite.isPending()) {\n        fn = null;\n      }\n      var test = new Test(title, fn);\n      test.file = file;\n      suite.addTest(test);\n      return test;\n    };\n\n    /**\n     * Exclusive test-case.\n     */\n\n    context.test.only = function(title, fn) {\n      return common.test.only(mocha, context.test(title, fn));\n    };\n\n    context.test.skip = common.test.skip;\n    context.test.retries = common.test.retries;\n  });\n};\n\n},{\"../test\":36,\"./common\":9}],14:[function(require,module,exports){\n(function (process,global,__dirname){\n/*!\n * mocha\n * Copyright(c) 2011 TJ Holowaychuk <tj@vision-media.ca>\n * MIT Licensed\n */\n\n/**\n * Module dependencies.\n */\n\nvar escapeRe = require('escape-string-regexp');\nvar path = require('path');\nvar reporters = require('./reporters');\nvar utils = require('./utils');\n\n/**\n * Expose `Mocha`.\n */\n\nexports = module.exports = Mocha;\n\n/**\n * To require local UIs and reporters when running in node.\n */\n\nif (!process.browser) {\n  var cwd = process.cwd();\n  module.paths.push(cwd, path.join(cwd, 'node_modules'));\n}\n\n/**\n * Expose internals.\n */\n\nexports.utils = utils;\nexports.interfaces = require('./interfaces');\nexports.reporters = reporters;\nexports.Runnable = require('./runnable');\nexports.Context = require('./context');\nexports.Runner = require('./runner');\nexports.Suite = require('./suite');\nexports.Hook = require('./hook');\nexports.Test = require('./test');\n\n/**\n * Return image `name` path.\n *\n * @api private\n * @param {string} name\n * @return {string}\n */\nfunction image(name) {\n  return path.join(__dirname, '../images', name + '.png');\n}\n\n/**\n * Set up mocha with `options`.\n *\n * Options:\n *\n *   - `ui` name \"bdd\", \"tdd\", \"exports\" etc\n *   - `reporter` reporter instance, defaults to `mocha.reporters.spec`\n *   - `globals` array of accepted globals\n *   - `timeout` timeout in milliseconds\n *   - `retries` number of times to retry failed tests\n *   - `bail` bail on the first test failure\n *   - `slow` milliseconds to wait before considering a test slow\n *   - `ignoreLeaks` ignore global leaks\n *   - `fullTrace` display the full stack-trace on failing\n *   - `grep` string or regexp to filter tests with\n *\n * @param {Object} options\n * @api public\n */\nfunction Mocha(options) {\n  options = options || {};\n  this.files = [];\n  this.options = options;\n  if (options.grep) {\n    this.grep(new RegExp(options.grep));\n  }\n  if (options.fgrep) {\n    this.fgrep(options.fgrep);\n  }\n  this.suite = new exports.Suite('', new exports.Context());\n  this.ui(options.ui);\n  this.bail(options.bail);\n  this.reporter(options.reporter, options.reporterOptions);\n  if (typeof options.timeout !== 'undefined' && options.timeout !== null) {\n    this.timeout(options.timeout);\n  }\n  if (typeof options.retries !== 'undefined' && options.retries !== null) {\n    this.retries(options.retries);\n  }\n  this.useColors(options.useColors);\n  if (options.enableTimeouts !== null) {\n    this.enableTimeouts(options.enableTimeouts);\n  }\n  if (options.slow) {\n    this.slow(options.slow);\n  }\n}\n\n/**\n * Enable or disable bailing on the first failure.\n *\n * @api public\n * @param {boolean} [bail]\n */\nMocha.prototype.bail = function(bail) {\n  if (!arguments.length) {\n    bail = true;\n  }\n  this.suite.bail(bail);\n  return this;\n};\n\n/**\n * Add test `file`.\n *\n * @api public\n * @param {string} file\n */\nMocha.prototype.addFile = function(file) {\n  this.files.push(file);\n  return this;\n};\n\n/**\n * Set reporter to `reporter`, defaults to \"spec\".\n *\n * @param {String|Function} reporter name or constructor\n * @param {Object} reporterOptions optional options\n * @api public\n * @param {string|Function} reporter name or constructor\n * @param {Object} reporterOptions optional options\n */\nMocha.prototype.reporter = function(reporter, reporterOptions) {\n  if (typeof reporter === 'function') {\n    this._reporter = reporter;\n  } else {\n    reporter = reporter || 'spec';\n    var _reporter;\n    // Try to load a built-in reporter.\n    if (reporters[reporter]) {\n      _reporter = reporters[reporter];\n    }\n    // Try to load reporters from process.cwd() and node_modules\n    if (!_reporter) {\n      try {\n        _reporter = require(reporter);\n      } catch (err) {\n        err.message.indexOf('Cannot find module') !== -1\n          ? console.warn('\"' + reporter + '\" reporter not found')\n          : console.warn('\"' + reporter + '\" reporter blew up with error:\\n' + err.stack);\n      }\n    }\n    if (!_reporter && reporter === 'teamcity') {\n      console.warn('The Teamcity reporter was moved to a package named '\n        + 'mocha-teamcity-reporter '\n        + '(https://npmjs.org/package/mocha-teamcity-reporter).');\n    }\n    if (!_reporter) {\n      throw new Error('invalid reporter \"' + reporter + '\"');\n    }\n    this._reporter = _reporter;\n  }\n  this.options.reporterOptions = reporterOptions;\n  return this;\n};\n\n/**\n * Set test UI `name`, defaults to \"bdd\".\n *\n * @api public\n * @param {string} bdd\n */\nMocha.prototype.ui = function(name) {\n  name = name || 'bdd';\n  this._ui = exports.interfaces[name];\n  if (!this._ui) {\n    try {\n      this._ui = require(name);\n    } catch (err) {\n      throw new Error('invalid interface \"' + name + '\"');\n    }\n  }\n  this._ui = this._ui(this.suite);\n\n  this.suite.on('pre-require', function(context) {\n    exports.afterEach = context.afterEach || context.teardown;\n    exports.after = context.after || context.suiteTeardown;\n    exports.beforeEach = context.beforeEach || context.setup;\n    exports.before = context.before || context.suiteSetup;\n    exports.describe = context.describe || context.suite;\n    exports.it = context.it || context.test;\n    exports.setup = context.setup || context.beforeEach;\n    exports.suiteSetup = context.suiteSetup || context.before;\n    exports.suiteTeardown = context.suiteTeardown || context.after;\n    exports.suite = context.suite || context.describe;\n    exports.teardown = context.teardown || context.afterEach;\n    exports.test = context.test || context.it;\n    exports.run = context.run;\n  });\n\n  return this;\n};\n\n/**\n * Load registered files.\n *\n * @api private\n */\nMocha.prototype.loadFiles = function(fn) {\n  var self = this;\n  var suite = this.suite;\n  this.files.forEach(function(file) {\n    file = path.resolve(file);\n    suite.emit('pre-require', global, file, self);\n    suite.emit('require', require(file), file, self);\n    suite.emit('post-require', global, file, self);\n  });\n  fn && fn();\n};\n\n/**\n * Enable growl support.\n *\n * @api private\n */\nMocha.prototype._growl = function(runner, reporter) {\n  var notify = require('growl');\n\n  runner.on('end', function() {\n    var stats = reporter.stats;\n    if (stats.failures) {\n      var msg = stats.failures + ' of ' + runner.total + ' tests failed';\n      notify(msg, { name: 'mocha', title: 'Failed', image: image('error') });\n    } else {\n      notify(stats.passes + ' tests passed in ' + stats.duration + 'ms', {\n        name: 'mocha',\n        title: 'Passed',\n        image: image('ok')\n      });\n    }\n  });\n};\n\n/**\n * Escape string and add it to grep as a regexp.\n *\n * @api public\n * @param str\n * @returns {Mocha}\n */\nMocha.prototype.fgrep = function(str) {\n  return this.grep(new RegExp(escapeRe(str)));\n};\n\n/**\n * Add regexp to grep, if `re` is a string it is escaped.\n *\n * @param {RegExp|String} re\n * @return {Mocha}\n * @api public\n * @param {RegExp|string} re\n * @return {Mocha}\n */\nMocha.prototype.grep = function(re) {\n  if (utils.isString(re)) {\n    // extract args if it's regex-like, i.e: [string, pattern, flag]\n    var arg = re.match(/^\\/(.*)\\/(g|i|)$|.*/);\n    this.options.grep = new RegExp(arg[1] || arg[0], arg[2]);\n  } else {\n    this.options.grep = re;\n  }\n  return this;\n};\n/**\n * Invert `.grep()` matches.\n *\n * @return {Mocha}\n * @api public\n */\nMocha.prototype.invert = function() {\n  this.options.invert = true;\n  return this;\n};\n\n/**\n * Ignore global leaks.\n *\n * @param {Boolean} ignore\n * @return {Mocha}\n * @api public\n * @param {boolean} ignore\n * @return {Mocha}\n */\nMocha.prototype.ignoreLeaks = function(ignore) {\n  this.options.ignoreLeaks = Boolean(ignore);\n  return this;\n};\n\n/**\n * Enable global leak checking.\n *\n * @return {Mocha}\n * @api public\n */\nMocha.prototype.checkLeaks = function() {\n  this.options.ignoreLeaks = false;\n  return this;\n};\n\n/**\n * Display long stack-trace on failing\n *\n * @return {Mocha}\n * @api public\n */\nMocha.prototype.fullTrace = function() {\n  this.options.fullStackTrace = true;\n  return this;\n};\n\n/**\n * Enable growl support.\n *\n * @return {Mocha}\n * @api public\n */\nMocha.prototype.growl = function() {\n  this.options.growl = true;\n  return this;\n};\n\n/**\n * Ignore `globals` array or string.\n *\n * @param {Array|String} globals\n * @return {Mocha}\n * @api public\n * @param {Array|string} globals\n * @return {Mocha}\n */\nMocha.prototype.globals = function(globals) {\n  this.options.globals = (this.options.globals || []).concat(globals);\n  return this;\n};\n\n/**\n * Emit color output.\n *\n * @param {Boolean} colors\n * @return {Mocha}\n * @api public\n * @param {boolean} colors\n * @return {Mocha}\n */\nMocha.prototype.useColors = function(colors) {\n  if (colors !== undefined) {\n    this.options.useColors = colors;\n  }\n  return this;\n};\n\n/**\n * Use inline diffs rather than +/-.\n *\n * @param {Boolean} inlineDiffs\n * @return {Mocha}\n * @api public\n * @param {boolean} inlineDiffs\n * @return {Mocha}\n */\nMocha.prototype.useInlineDiffs = function(inlineDiffs) {\n  this.options.useInlineDiffs = inlineDiffs !== undefined && inlineDiffs;\n  return this;\n};\n\n/**\n * Set the timeout in milliseconds.\n *\n * @param {Number} timeout\n * @return {Mocha}\n * @api public\n * @param {number} timeout\n * @return {Mocha}\n */\nMocha.prototype.timeout = function(timeout) {\n  this.suite.timeout(timeout);\n  return this;\n};\n\n/**\n * Set the number of times to retry failed tests.\n *\n * @param {Number} retry times\n * @return {Mocha}\n * @api public\n */\nMocha.prototype.retries = function(n) {\n  this.suite.retries(n);\n  return this;\n};\n\n/**\n * Set slowness threshold in milliseconds.\n *\n * @param {Number} slow\n * @return {Mocha}\n * @api public\n * @param {number} slow\n * @return {Mocha}\n */\nMocha.prototype.slow = function(slow) {\n  this.suite.slow(slow);\n  return this;\n};\n\n/**\n * Enable timeouts.\n *\n * @param {Boolean} enabled\n * @return {Mocha}\n * @api public\n * @param {boolean} enabled\n * @return {Mocha}\n */\nMocha.prototype.enableTimeouts = function(enabled) {\n  this.suite.enableTimeouts(arguments.length && enabled !== undefined ? enabled : true);\n  return this;\n};\n\n/**\n * Makes all tests async (accepting a callback)\n *\n * @return {Mocha}\n * @api public\n */\nMocha.prototype.asyncOnly = function() {\n  this.options.asyncOnly = true;\n  return this;\n};\n\n/**\n * Disable syntax highlighting (in browser).\n *\n * @api public\n */\nMocha.prototype.noHighlighting = function() {\n  this.options.noHighlighting = true;\n  return this;\n};\n\n/**\n * Enable uncaught errors to propagate (in browser).\n *\n * @return {Mocha}\n * @api public\n */\nMocha.prototype.allowUncaught = function() {\n  this.options.allowUncaught = true;\n  return this;\n};\n\n/**\n * Delay root suite execution.\n * @returns {Mocha}\n */\nMocha.prototype.delay = function delay() {\n  this.options.delay = true;\n  return this;\n};\n\n/**\n * Run tests and invoke `fn()` when complete.\n *\n * @api public\n * @param {Function} fn\n * @return {Runner}\n */\nMocha.prototype.run = function(fn) {\n  if (this.files.length) {\n    this.loadFiles();\n  }\n  var suite = this.suite;\n  var options = this.options;\n  options.files = this.files;\n  var runner = new exports.Runner(suite, options.delay);\n  var reporter = new this._reporter(runner, options);\n  runner.ignoreLeaks = options.ignoreLeaks !== false;\n  runner.fullStackTrace = options.fullStackTrace;\n  runner.hasOnly = options.hasOnly;\n  runner.asyncOnly = options.asyncOnly;\n  runner.allowUncaught = options.allowUncaught;\n  if (options.grep) {\n    runner.grep(options.grep, options.invert);\n  }\n  if (options.globals) {\n    runner.globals(options.globals);\n  }\n  if (options.growl) {\n    this._growl(runner, reporter);\n  }\n  if (options.useColors !== undefined) {\n    exports.reporters.Base.useColors = options.useColors;\n  }\n  exports.reporters.Base.inlineDiffs = options.useInlineDiffs;\n\n  function done(failures) {\n    if (reporter.done) {\n      reporter.done(failures, fn);\n    } else {\n      fn && fn(failures);\n    }\n  }\n\n  return runner.run(done);\n};\n\n}).call(this,require('_process'),typeof global !== \"undefined\" ? global : typeof self !== \"undefined\" ? self : typeof window !== \"undefined\" ? window : {},\"/lib\")\n},{\"./context\":6,\"./hook\":7,\"./interfaces\":11,\"./reporters\":21,\"./runnable\":33,\"./runner\":34,\"./suite\":35,\"./test\":36,\"./utils\":38,\"_process\":67,\"escape-string-regexp\":47,\"growl\":49,\"path\":42}],15:[function(require,module,exports){\n/**\n * Helpers.\n */\n\nvar s = 1000;\nvar m = s * 60;\nvar h = m * 60;\nvar d = h * 24;\nvar y = d * 365.25;\n\n/**\n * Parse or format the given `val`.\n *\n * Options:\n *\n *  - `long` verbose formatting [false]\n *\n * @api public\n * @param {string|number} val\n * @param {Object} options\n * @return {string|number}\n */\nmodule.exports = function(val, options) {\n  options = options || {};\n  if (typeof val === 'string') {\n    return parse(val);\n  }\n  // https://github.com/mochajs/mocha/pull/1035\n  return options['long'] ? longFormat(val) : shortFormat(val);\n};\n\n/**\n * Parse the given `str` and return milliseconds.\n *\n * @api private\n * @param {string} str\n * @return {number}\n */\nfunction parse(str) {\n  var match = (/^((?:\\d+)?\\.?\\d+) *(ms|seconds?|s|minutes?|m|hours?|h|days?|d|years?|y)?$/i).exec(str);\n  if (!match) {\n    return;\n  }\n  var n = parseFloat(match[1]);\n  var type = (match[2] || 'ms').toLowerCase();\n  switch (type) {\n    case 'years':\n    case 'year':\n    case 'y':\n      return n * y;\n    case 'days':\n    case 'day':\n    case 'd':\n      return n * d;\n    case 'hours':\n    case 'hour':\n    case 'h':\n      return n * h;\n    case 'minutes':\n    case 'minute':\n    case 'm':\n      return n * m;\n    case 'seconds':\n    case 'second':\n    case 's':\n      return n * s;\n    case 'ms':\n      return n;\n    default:\n      // No default case\n  }\n}\n\n/**\n * Short format for `ms`.\n *\n * @api private\n * @param {number} ms\n * @return {string}\n */\nfunction shortFormat(ms) {\n  if (ms >= d) {\n    return Math.round(ms / d) + 'd';\n  }\n  if (ms >= h) {\n    return Math.round(ms / h) + 'h';\n  }\n  if (ms >= m) {\n    return Math.round(ms / m) + 'm';\n  }\n  if (ms >= s) {\n    return Math.round(ms / s) + 's';\n  }\n  return ms + 'ms';\n}\n\n/**\n * Long format for `ms`.\n *\n * @api private\n * @param {number} ms\n * @return {string}\n */\nfunction longFormat(ms) {\n  return plural(ms, d, 'day')\n    || plural(ms, h, 'hour')\n    || plural(ms, m, 'minute')\n    || plural(ms, s, 'second')\n    || ms + ' ms';\n}\n\n/**\n * Pluralization helper.\n *\n * @api private\n * @param {number} ms\n * @param {number} n\n * @param {string} name\n */\nfunction plural(ms, n, name) {\n  if (ms < n) {\n    return;\n  }\n  if (ms < n * 1.5) {\n    return Math.floor(ms / n) + ' ' + name;\n  }\n  return Math.ceil(ms / n) + ' ' + name + 's';\n}\n\n},{}],16:[function(require,module,exports){\n\n/**\n * Expose `Pending`.\n */\n\nmodule.exports = Pending;\n\n/**\n * Initialize a new `Pending` error with the given message.\n *\n * @param {string} message\n */\nfunction Pending(message) {\n  this.message = message;\n}\n\n},{}],17:[function(require,module,exports){\n(function (process,global){\n/**\n * Module dependencies.\n */\n\nvar tty = require('tty');\nvar diff = require('diff');\nvar ms = require('../ms');\nvar utils = require('../utils');\nvar supportsColor = process.browser ? null : require('supports-color');\n\n/**\n * Expose `Base`.\n */\n\nexports = module.exports = Base;\n\n/**\n * Save timer references to avoid Sinon interfering.\n * See: https://github.com/mochajs/mocha/issues/237\n */\n\n/* eslint-disable no-unused-vars, no-native-reassign */\nvar Date = global.Date;\nvar setTimeout = global.setTimeout;\nvar setInterval = global.setInterval;\nvar clearTimeout = global.clearTimeout;\nvar clearInterval = global.clearInterval;\n/* eslint-enable no-unused-vars, no-native-reassign */\n\n/**\n * Check if both stdio streams are associated with a tty.\n */\n\nvar isatty = tty.isatty(1) && tty.isatty(2);\n\n/**\n * Enable coloring by default, except in the browser interface.\n */\n\nexports.useColors = !process.browser && (supportsColor || (process.env.MOCHA_COLORS !== undefined));\n\n/**\n * Inline diffs instead of +/-\n */\n\nexports.inlineDiffs = false;\n\n/**\n * Default color map.\n */\n\nexports.colors = {\n  pass: 90,\n  fail: 31,\n  'bright pass': 92,\n  'bright fail': 91,\n  'bright yellow': 93,\n  pending: 36,\n  suite: 0,\n  'error title': 0,\n  'error message': 31,\n  'error stack': 90,\n  checkmark: 32,\n  fast: 90,\n  medium: 33,\n  slow: 31,\n  green: 32,\n  light: 90,\n  'diff gutter': 90,\n  'diff added': 32,\n  'diff removed': 31\n};\n\n/**\n * Default symbol map.\n */\n\nexports.symbols = {\n  ok: '✓',\n  err: '✖',\n  dot: '․',\n  comma: ',',\n  bang: '!'\n};\n\n// With node.js on Windows: use symbols available in terminal default fonts\nif (process.platform === 'win32') {\n  exports.symbols.ok = '\\u221A';\n  exports.symbols.err = '\\u00D7';\n  exports.symbols.dot = '.';\n}\n\n/**\n * Color `str` with the given `type`,\n * allowing colors to be disabled,\n * as well as user-defined color\n * schemes.\n *\n * @param {string} type\n * @param {string} str\n * @return {string}\n * @api private\n */\nvar color = exports.color = function(type, str) {\n  if (!exports.useColors) {\n    return String(str);\n  }\n  return '\\u001b[' + exports.colors[type] + 'm' + str + '\\u001b[0m';\n};\n\n/**\n * Expose term window size, with some defaults for when stderr is not a tty.\n */\n\nexports.window = {\n  width: 75\n};\n\nif (isatty) {\n  exports.window.width = process.stdout.getWindowSize\n      ? process.stdout.getWindowSize(1)[0]\n      : tty.getWindowSize()[1];\n}\n\n/**\n * Expose some basic cursor interactions that are common among reporters.\n */\n\nexports.cursor = {\n  hide: function() {\n    isatty && process.stdout.write('\\u001b[?25l');\n  },\n\n  show: function() {\n    isatty && process.stdout.write('\\u001b[?25h');\n  },\n\n  deleteLine: function() {\n    isatty && process.stdout.write('\\u001b[2K');\n  },\n\n  beginningOfLine: function() {\n    isatty && process.stdout.write('\\u001b[0G');\n  },\n\n  CR: function() {\n    if (isatty) {\n      exports.cursor.deleteLine();\n      exports.cursor.beginningOfLine();\n    } else {\n      process.stdout.write('\\r');\n    }\n  }\n};\n\n/**\n * Outut the given `failures` as a list.\n *\n * @param {Array} failures\n * @api public\n */\n\nexports.list = function(failures) {\n  console.log();\n  failures.forEach(function(test, i) {\n    // format\n    var fmt = color('error title', '  %s) %s:\\n')\n      + color('error message', '     %s')\n      + color('error stack', '\\n%s\\n');\n\n    // msg\n    var msg;\n    var err = test.err;\n    var message;\n    if (err.message && typeof err.message.toString === 'function') {\n      message = err.message + '';\n    } else if (typeof err.inspect === 'function') {\n      message = err.inspect() + '';\n    } else {\n      message = '';\n    }\n    var stack = err.stack || message;\n    var index = message ? stack.indexOf(message) : -1;\n    var actual = err.actual;\n    var expected = err.expected;\n    var escape = true;\n\n    if (index === -1) {\n      msg = message;\n    } else {\n      index += message.length;\n      msg = stack.slice(0, index);\n      // remove msg from stack\n      stack = stack.slice(index + 1);\n    }\n\n    // uncaught\n    if (err.uncaught) {\n      msg = 'Uncaught ' + msg;\n    }\n    // explicitly show diff\n    if (err.showDiff !== false && sameType(actual, expected) && expected !== undefined) {\n      escape = false;\n      if (!(utils.isString(actual) && utils.isString(expected))) {\n        err.actual = actual = utils.stringify(actual);\n        err.expected = expected = utils.stringify(expected);\n      }\n\n      fmt = color('error title', '  %s) %s:\\n%s') + color('error stack', '\\n%s\\n');\n      var match = message.match(/^([^:]+): expected/);\n      msg = '\\n      ' + color('error message', match ? match[1] : msg);\n\n      if (exports.inlineDiffs) {\n        msg += inlineDiff(err, escape);\n      } else {\n        msg += unifiedDiff(err, escape);\n      }\n    }\n\n    // indent stack trace\n    stack = stack.replace(/^/gm, '  ');\n\n    console.log(fmt, (i + 1), test.fullTitle(), msg, stack);\n  });\n};\n\n/**\n * Initialize a new `Base` reporter.\n *\n * All other reporters generally\n * inherit from this reporter, providing\n * stats such as test duration, number\n * of tests passed / failed etc.\n *\n * @param {Runner} runner\n * @api public\n */\n\nfunction Base(runner) {\n  var stats = this.stats = { suites: 0, tests: 0, passes: 0, pending: 0, failures: 0 };\n  var failures = this.failures = [];\n\n  if (!runner) {\n    return;\n  }\n  this.runner = runner;\n\n  runner.stats = stats;\n\n  runner.on('start', function() {\n    stats.start = new Date();\n  });\n\n  runner.on('suite', function(suite) {\n    stats.suites = stats.suites || 0;\n    suite.root || stats.suites++;\n  });\n\n  runner.on('test end', function() {\n    stats.tests = stats.tests || 0;\n    stats.tests++;\n  });\n\n  runner.on('pass', function(test) {\n    stats.passes = stats.passes || 0;\n\n    if (test.duration > test.slow()) {\n      test.speed = 'slow';\n    } else if (test.duration > test.slow() / 2) {\n      test.speed = 'medium';\n    } else {\n      test.speed = 'fast';\n    }\n\n    stats.passes++;\n  });\n\n  runner.on('fail', function(test, err) {\n    stats.failures = stats.failures || 0;\n    stats.failures++;\n    test.err = err;\n    failures.push(test);\n  });\n\n  runner.on('end', function() {\n    stats.end = new Date();\n    stats.duration = new Date() - stats.start;\n  });\n\n  runner.on('pending', function() {\n    stats.pending++;\n  });\n}\n\n/**\n * Output common epilogue used by many of\n * the bundled reporters.\n *\n * @api public\n */\nBase.prototype.epilogue = function() {\n  var stats = this.stats;\n  var fmt;\n\n  console.log();\n\n  // passes\n  fmt = color('bright pass', ' ')\n    + color('green', ' %d passing')\n    + color('light', ' (%s)');\n\n  console.log(fmt,\n    stats.passes || 0,\n    ms(stats.duration));\n\n  // pending\n  if (stats.pending) {\n    fmt = color('pending', ' ')\n      + color('pending', ' %d pending');\n\n    console.log(fmt, stats.pending);\n  }\n\n  // failures\n  if (stats.failures) {\n    fmt = color('fail', '  %d failing');\n\n    console.log(fmt, stats.failures);\n\n    Base.list(this.failures);\n    console.log();\n  }\n\n  console.log();\n};\n\n/**\n * Pad the given `str` to `len`.\n *\n * @api private\n * @param {string} str\n * @param {string} len\n * @return {string}\n */\nfunction pad(str, len) {\n  str = String(str);\n  return Array(len - str.length + 1).join(' ') + str;\n}\n\n/**\n * Returns an inline diff between 2 strings with coloured ANSI output\n *\n * @api private\n * @param {Error} err with actual/expected\n * @param {boolean} escape\n * @return {string} Diff\n */\nfunction inlineDiff(err, escape) {\n  var msg = errorDiff(err, 'WordsWithSpace', escape);\n\n  // linenos\n  var lines = msg.split('\\n');\n  if (lines.length > 4) {\n    var width = String(lines.length).length;\n    msg = lines.map(function(str, i) {\n      return pad(++i, width) + ' |' + ' ' + str;\n    }).join('\\n');\n  }\n\n  // legend\n  msg = '\\n'\n    + color('diff removed', 'actual')\n    + ' '\n    + color('diff added', 'expected')\n    + '\\n\\n'\n    + msg\n    + '\\n';\n\n  // indent\n  msg = msg.replace(/^/gm, '      ');\n  return msg;\n}\n\n/**\n * Returns a unified diff between two strings.\n *\n * @api private\n * @param {Error} err with actual/expected\n * @param {boolean} escape\n * @return {string} The diff.\n */\nfunction unifiedDiff(err, escape) {\n  var indent = '      ';\n  function cleanUp(line) {\n    if (escape) {\n      line = escapeInvisibles(line);\n    }\n    if (line[0] === '+') {\n      return indent + colorLines('diff added', line);\n    }\n    if (line[0] === '-') {\n      return indent + colorLines('diff removed', line);\n    }\n    if (line.match(/\\@\\@/)) {\n      return null;\n    }\n    if (line.match(/\\\\ No newline/)) {\n      return null;\n    }\n    return indent + line;\n  }\n  function notBlank(line) {\n    return typeof line !== 'undefined' && line !== null;\n  }\n  var msg = diff.createPatch('string', err.actual, err.expected);\n  var lines = msg.split('\\n').splice(4);\n  return '\\n      '\n    + colorLines('diff added', '+ expected') + ' '\n    + colorLines('diff removed', '- actual')\n    + '\\n\\n'\n    + lines.map(cleanUp).filter(notBlank).join('\\n');\n}\n\n/**\n * Return a character diff for `err`.\n *\n * @api private\n * @param {Error} err\n * @param {string} type\n * @param {boolean} escape\n * @return {string}\n */\nfunction errorDiff(err, type, escape) {\n  var actual = escape ? escapeInvisibles(err.actual) : err.actual;\n  var expected = escape ? escapeInvisibles(err.expected) : err.expected;\n  return diff['diff' + type](actual, expected).map(function(str) {\n    if (str.added) {\n      return colorLines('diff added', str.value);\n    }\n    if (str.removed) {\n      return colorLines('diff removed', str.value);\n    }\n    return str.value;\n  }).join('');\n}\n\n/**\n * Returns a string with all invisible characters in plain text\n *\n * @api private\n * @param {string} line\n * @return {string}\n */\nfunction escapeInvisibles(line) {\n  return line.replace(/\\t/g, '<tab>')\n    .replace(/\\r/g, '<CR>')\n    .replace(/\\n/g, '<LF>\\n');\n}\n\n/**\n * Color lines for `str`, using the color `name`.\n *\n * @api private\n * @param {string} name\n * @param {string} str\n * @return {string}\n */\nfunction colorLines(name, str) {\n  return str.split('\\n').map(function(str) {\n    return color(name, str);\n  }).join('\\n');\n}\n\n/**\n * Object#toString reference.\n */\nvar objToString = Object.prototype.toString;\n\n/**\n * Check that a / b have the same type.\n *\n * @api private\n * @param {Object} a\n * @param {Object} b\n * @return {boolean}\n */\nfunction sameType(a, b) {\n  return objToString.call(a) === objToString.call(b);\n}\n\n}).call(this,require('_process'),typeof global !== \"undefined\" ? global : typeof self !== \"undefined\" ? self : typeof window !== \"undefined\" ? window : {})\n},{\"../ms\":15,\"../utils\":38,\"_process\":67,\"diff\":46,\"supports-color\":42,\"tty\":5}],18:[function(require,module,exports){\n/**\n * Module dependencies.\n */\n\nvar Base = require('./base');\nvar utils = require('../utils');\n\n/**\n * Expose `Doc`.\n */\n\nexports = module.exports = Doc;\n\n/**\n * Initialize a new `Doc` reporter.\n *\n * @param {Runner} runner\n * @api public\n */\nfunction Doc(runner) {\n  Base.call(this, runner);\n\n  var indents = 2;\n\n  function indent() {\n    return Array(indents).join('  ');\n  }\n\n  runner.on('suite', function(suite) {\n    if (suite.root) {\n      return;\n    }\n    ++indents;\n    console.log('%s<section class=\"suite\">', indent());\n    ++indents;\n    console.log('%s<h1>%s</h1>', indent(), utils.escape(suite.title));\n    console.log('%s<dl>', indent());\n  });\n\n  runner.on('suite end', function(suite) {\n    if (suite.root) {\n      return;\n    }\n    console.log('%s</dl>', indent());\n    --indents;\n    console.log('%s</section>', indent());\n    --indents;\n  });\n\n  runner.on('pass', function(test) {\n    console.log('%s  <dt>%s</dt>', indent(), utils.escape(test.title));\n    var code = utils.escape(utils.clean(test.body));\n    console.log('%s  <dd><pre><code>%s</code></pre></dd>', indent(), code);\n  });\n\n  runner.on('fail', function(test, err) {\n    console.log('%s  <dt class=\"error\">%s</dt>', indent(), utils.escape(test.title));\n    var code = utils.escape(utils.clean(test.body));\n    console.log('%s  <dd class=\"error\"><pre><code>%s</code></pre></dd>', indent(), code);\n    console.log('%s  <dd class=\"error\">%s</dd>', indent(), utils.escape(err));\n  });\n}\n\n},{\"../utils\":38,\"./base\":17}],19:[function(require,module,exports){\n(function (process){\n/**\n * Module dependencies.\n */\n\nvar Base = require('./base');\nvar inherits = require('../utils').inherits;\nvar color = Base.color;\n\n/**\n * Expose `Dot`.\n */\n\nexports = module.exports = Dot;\n\n/**\n * Initialize a new `Dot` matrix test reporter.\n *\n * @api public\n * @param {Runner} runner\n */\nfunction Dot(runner) {\n  Base.call(this, runner);\n\n  var self = this;\n  var width = Base.window.width * .75 | 0;\n  var n = -1;\n\n  runner.on('start', function() {\n    process.stdout.write('\\n');\n  });\n\n  runner.on('pending', function() {\n    if (++n % width === 0) {\n      process.stdout.write('\\n  ');\n    }\n    process.stdout.write(color('pending', Base.symbols.comma));\n  });\n\n  runner.on('pass', function(test) {\n    if (++n % width === 0) {\n      process.stdout.write('\\n  ');\n    }\n    if (test.speed === 'slow') {\n      process.stdout.write(color('bright yellow', Base.symbols.dot));\n    } else {\n      process.stdout.write(color(test.speed, Base.symbols.dot));\n    }\n  });\n\n  runner.on('fail', function() {\n    if (++n % width === 0) {\n      process.stdout.write('\\n  ');\n    }\n    process.stdout.write(color('fail', Base.symbols.bang));\n  });\n\n  runner.on('end', function() {\n    console.log();\n    self.epilogue();\n  });\n}\n\n/**\n * Inherit from `Base.prototype`.\n */\ninherits(Dot, Base);\n\n}).call(this,require('_process'))\n},{\"../utils\":38,\"./base\":17,\"_process\":67}],20:[function(require,module,exports){\n(function (global){\n/* eslint-env browser */\n\n/**\n * Module dependencies.\n */\n\nvar Base = require('./base');\nvar utils = require('../utils');\nvar Progress = require('../browser/progress');\nvar escapeRe = require('escape-string-regexp');\nvar escape = utils.escape;\n\n/**\n * Save timer references to avoid Sinon interfering (see GH-237).\n */\n\n/* eslint-disable no-unused-vars, no-native-reassign */\nvar Date = global.Date;\nvar setTimeout = global.setTimeout;\nvar setInterval = global.setInterval;\nvar clearTimeout = global.clearTimeout;\nvar clearInterval = global.clearInterval;\n/* eslint-enable no-unused-vars, no-native-reassign */\n\n/**\n * Expose `HTML`.\n */\n\nexports = module.exports = HTML;\n\n/**\n * Stats template.\n */\n\nvar statsTemplate = '<ul id=\"mocha-stats\">'\n  + '<li class=\"progress\"><canvas width=\"40\" height=\"40\"></canvas></li>'\n  + '<li class=\"passes\"><a href=\"javascript:void(0);\">passes:</a> <em>0</em></li>'\n  + '<li class=\"failures\"><a href=\"javascript:void(0);\">failures:</a> <em>0</em></li>'\n  + '<li class=\"duration\">duration: <em>0</em>s</li>'\n  + '</ul>';\n\n/**\n * Initialize a new `HTML` reporter.\n *\n * @api public\n * @param {Runner} runner\n */\nfunction HTML(runner) {\n  Base.call(this, runner);\n\n  var self = this;\n  var stats = this.stats;\n  var stat = fragment(statsTemplate);\n  var items = stat.getElementsByTagName('li');\n  var passes = items[1].getElementsByTagName('em')[0];\n  var passesLink = items[1].getElementsByTagName('a')[0];\n  var failures = items[2].getElementsByTagName('em')[0];\n  var failuresLink = items[2].getElementsByTagName('a')[0];\n  var duration = items[3].getElementsByTagName('em')[0];\n  var canvas = stat.getElementsByTagName('canvas')[0];\n  var report = fragment('<ul id=\"mocha-report\"></ul>');\n  var stack = [report];\n  var progress;\n  var ctx;\n  var root = document.getElementById('mocha');\n\n  if (canvas.getContext) {\n    var ratio = window.devicePixelRatio || 1;\n    canvas.style.width = canvas.width;\n    canvas.style.height = canvas.height;\n    canvas.width *= ratio;\n    canvas.height *= ratio;\n    ctx = canvas.getContext('2d');\n    ctx.scale(ratio, ratio);\n    progress = new Progress();\n  }\n\n  if (!root) {\n    return error('#mocha div missing, add it to your document');\n  }\n\n  // pass toggle\n  on(passesLink, 'click', function(evt) {\n    evt.preventDefault();\n    unhide();\n    var name = (/pass/).test(report.className) ? '' : ' pass';\n    report.className = report.className.replace(/fail|pass/g, '') + name;\n    if (report.className.trim()) {\n      hideSuitesWithout('test pass');\n    }\n  });\n\n  // failure toggle\n  on(failuresLink, 'click', function(evt) {\n    evt.preventDefault();\n    unhide();\n    var name = (/fail/).test(report.className) ? '' : ' fail';\n    report.className = report.className.replace(/fail|pass/g, '') + name;\n    if (report.className.trim()) {\n      hideSuitesWithout('test fail');\n    }\n  });\n\n  root.appendChild(stat);\n  root.appendChild(report);\n\n  if (progress) {\n    progress.size(40);\n  }\n\n  runner.on('suite', function(suite) {\n    if (suite.root) {\n      return;\n    }\n\n    // suite\n    var url = self.suiteURL(suite);\n    var el = fragment('<li class=\"suite\"><h1><a href=\"%s\">%s</a></h1></li>', url, escape(suite.title));\n\n    // container\n    stack[0].appendChild(el);\n    stack.unshift(document.createElement('ul'));\n    el.appendChild(stack[0]);\n  });\n\n  runner.on('suite end', function(suite) {\n    if (suite.root) {\n      updateStats();\n      return;\n    }\n    stack.shift();\n  });\n\n  runner.on('pass', function(test) {\n    var url = self.testURL(test);\n    var markup = '<li class=\"test pass %e\"><h2>%e<span class=\"duration\">%ems</span> '\n      + '<a href=\"%s\" class=\"replay\">‣</a></h2></li>';\n    var el = fragment(markup, test.speed, test.title, test.duration, url);\n    self.addCodeToggle(el, test.body);\n    appendToStack(el);\n    updateStats();\n  });\n\n  runner.on('fail', function(test) {\n    var el = fragment('<li class=\"test fail\"><h2>%e <a href=\"%e\" class=\"replay\">‣</a></h2></li>',\n      test.title, self.testURL(test));\n    var stackString; // Note: Includes leading newline\n    var message = test.err.toString();\n\n    // <=IE7 stringifies to [Object Error]. Since it can be overloaded, we\n    // check for the result of the stringifying.\n    if (message === '[object Error]') {\n      message = test.err.message;\n    }\n\n    if (test.err.stack) {\n      var indexOfMessage = test.err.stack.indexOf(test.err.message);\n      if (indexOfMessage === -1) {\n        stackString = test.err.stack;\n      } else {\n        stackString = test.err.stack.substr(test.err.message.length + indexOfMessage);\n      }\n    } else if (test.err.sourceURL && test.err.line !== undefined) {\n      // Safari doesn't give you a stack. Let's at least provide a source line.\n      stackString = '\\n(' + test.err.sourceURL + ':' + test.err.line + ')';\n    }\n\n    stackString = stackString || '';\n\n    if (test.err.htmlMessage && stackString) {\n      el.appendChild(fragment('<div class=\"html-error\">%s\\n<pre class=\"error\">%e</pre></div>',\n        test.err.htmlMessage, stackString));\n    } else if (test.err.htmlMessage) {\n      el.appendChild(fragment('<div class=\"html-error\">%s</div>', test.err.htmlMessage));\n    } else {\n      el.appendChild(fragment('<pre class=\"error\">%e%e</pre>', message, stackString));\n    }\n\n    self.addCodeToggle(el, test.body);\n    appendToStack(el);\n    updateStats();\n  });\n\n  runner.on('pending', function(test) {\n    var el = fragment('<li class=\"test pass pending\"><h2>%e</h2></li>', test.title);\n    appendToStack(el);\n    updateStats();\n  });\n\n  function appendToStack(el) {\n    // Don't call .appendChild if #mocha-report was already .shift()'ed off the stack.\n    if (stack[0]) {\n      stack[0].appendChild(el);\n    }\n  }\n\n  function updateStats() {\n    // TODO: add to stats\n    var percent = stats.tests / runner.total * 100 | 0;\n    if (progress) {\n      progress.update(percent).draw(ctx);\n    }\n\n    // update stats\n    var ms = new Date() - stats.start;\n    text(passes, stats.passes);\n    text(failures, stats.failures);\n    text(duration, (ms / 1000).toFixed(2));\n  }\n}\n\n/**\n * Makes a URL, preserving querystring (\"search\") parameters.\n *\n * @param {string} s\n * @return {string} A new URL.\n */\nfunction makeUrl(s) {\n  var search = window.location.search;\n\n  // Remove previous grep query parameter if present\n  if (search) {\n    search = search.replace(/[?&]grep=[^&\\s]*/g, '').replace(/^&/, '?');\n  }\n\n  return window.location.pathname + (search ? search + '&' : '?') + 'grep=' + encodeURIComponent(escapeRe(s));\n}\n\n/**\n * Provide suite URL.\n *\n * @param {Object} [suite]\n */\nHTML.prototype.suiteURL = function(suite) {\n  return makeUrl(suite.fullTitle());\n};\n\n/**\n * Provide test URL.\n *\n * @param {Object} [test]\n */\nHTML.prototype.testURL = function(test) {\n  return makeUrl(test.fullTitle());\n};\n\n/**\n * Adds code toggle functionality for the provided test's list element.\n *\n * @param {HTMLLIElement} el\n * @param {string} contents\n */\nHTML.prototype.addCodeToggle = function(el, contents) {\n  var h2 = el.getElementsByTagName('h2')[0];\n\n  on(h2, 'click', function() {\n    pre.style.display = pre.style.display === 'none' ? 'block' : 'none';\n  });\n\n  var pre = fragment('<pre><code>%e</code></pre>', utils.clean(contents));\n  el.appendChild(pre);\n  pre.style.display = 'none';\n};\n\n/**\n * Display error `msg`.\n *\n * @param {string} msg\n */\nfunction error(msg) {\n  document.body.appendChild(fragment('<div id=\"mocha-error\">%s</div>', msg));\n}\n\n/**\n * Return a DOM fragment from `html`.\n *\n * @param {string} html\n */\nfunction fragment(html) {\n  var args = arguments;\n  var div = document.createElement('div');\n  var i = 1;\n\n  div.innerHTML = html.replace(/%([se])/g, function(_, type) {\n    switch (type) {\n      case 's': return String(args[i++]);\n      case 'e': return escape(args[i++]);\n      // no default\n    }\n  });\n\n  return div.firstChild;\n}\n\n/**\n * Check for suites that do not have elements\n * with `classname`, and hide them.\n *\n * @param {text} classname\n */\nfunction hideSuitesWithout(classname) {\n  var suites = document.getElementsByClassName('suite');\n  for (var i = 0; i < suites.length; i++) {\n    var els = suites[i].getElementsByClassName(classname);\n    if (!els.length) {\n      suites[i].className += ' hidden';\n    }\n  }\n}\n\n/**\n * Unhide .hidden suites.\n */\nfunction unhide() {\n  var els = document.getElementsByClassName('suite hidden');\n  for (var i = 0; i < els.length; ++i) {\n    els[i].className = els[i].className.replace('suite hidden', 'suite');\n  }\n}\n\n/**\n * Set an element's text contents.\n *\n * @param {HTMLElement} el\n * @param {string} contents\n */\nfunction text(el, contents) {\n  if (el.textContent) {\n    el.textContent = contents;\n  } else {\n    el.innerText = contents;\n  }\n}\n\n/**\n * Listen on `event` with callback `fn`.\n */\nfunction on(el, event, fn) {\n  if (el.addEventListener) {\n    el.addEventListener(event, fn, false);\n  } else {\n    el.attachEvent('on' + event, fn);\n  }\n}\n\n}).call(this,typeof global !== \"undefined\" ? global : typeof self !== \"undefined\" ? self : typeof window !== \"undefined\" ? window : {})\n},{\"../browser/progress\":4,\"../utils\":38,\"./base\":17,\"escape-string-regexp\":47}],21:[function(require,module,exports){\n// Alias exports to a their normalized format Mocha#reporter to prevent a need\n// for dynamic (try/catch) requires, which Browserify doesn't handle.\nexports.Base = exports.base = require('./base');\nexports.Dot = exports.dot = require('./dot');\nexports.Doc = exports.doc = require('./doc');\nexports.TAP = exports.tap = require('./tap');\nexports.JSON = exports.json = require('./json');\nexports.HTML = exports.html = require('./html');\nexports.List = exports.list = require('./list');\nexports.Min = exports.min = require('./min');\nexports.Spec = exports.spec = require('./spec');\nexports.Nyan = exports.nyan = require('./nyan');\nexports.XUnit = exports.xunit = require('./xunit');\nexports.Markdown = exports.markdown = require('./markdown');\nexports.Progress = exports.progress = require('./progress');\nexports.Landing = exports.landing = require('./landing');\nexports.JSONStream = exports['json-stream'] = require('./json-stream');\n\n},{\"./base\":17,\"./doc\":18,\"./dot\":19,\"./html\":20,\"./json\":23,\"./json-stream\":22,\"./landing\":24,\"./list\":25,\"./markdown\":26,\"./min\":27,\"./nyan\":28,\"./progress\":29,\"./spec\":30,\"./tap\":31,\"./xunit\":32}],22:[function(require,module,exports){\n(function (process){\n/**\n * Module dependencies.\n */\n\nvar Base = require('./base');\nvar JSON = require('json3');\n\n/**\n * Expose `List`.\n */\n\nexports = module.exports = List;\n\n/**\n * Initialize a new `List` test reporter.\n *\n * @api public\n * @param {Runner} runner\n */\nfunction List(runner) {\n  Base.call(this, runner);\n\n  var self = this;\n  var total = runner.total;\n\n  runner.on('start', function() {\n    console.log(JSON.stringify(['start', { total: total }]));\n  });\n\n  runner.on('pass', function(test) {\n    console.log(JSON.stringify(['pass', clean(test)]));\n  });\n\n  runner.on('fail', function(test, err) {\n    test = clean(test);\n    test.err = err.message;\n    test.stack = err.stack || null;\n    console.log(JSON.stringify(['fail', test]));\n  });\n\n  runner.on('end', function() {\n    process.stdout.write(JSON.stringify(['end', self.stats]));\n  });\n}\n\n/**\n * Return a plain-object representation of `test`\n * free of cyclic properties etc.\n *\n * @api private\n * @param {Object} test\n * @return {Object}\n */\nfunction clean(test) {\n  return {\n    title: test.title,\n    fullTitle: test.fullTitle(),\n    duration: test.duration,\n    currentRetry: test.currentRetry()\n  };\n}\n\n}).call(this,require('_process'))\n},{\"./base\":17,\"_process\":67,\"json3\":54}],23:[function(require,module,exports){\n(function (process){\n/**\n * Module dependencies.\n */\n\nvar Base = require('./base');\n\n/**\n * Expose `JSON`.\n */\n\nexports = module.exports = JSONReporter;\n\n/**\n * Initialize a new `JSON` reporter.\n *\n * @api public\n * @param {Runner} runner\n */\nfunction JSONReporter(runner) {\n  Base.call(this, runner);\n\n  var self = this;\n  var tests = [];\n  var pending = [];\n  var failures = [];\n  var passes = [];\n\n  runner.on('test end', function(test) {\n    tests.push(test);\n  });\n\n  runner.on('pass', function(test) {\n    passes.push(test);\n  });\n\n  runner.on('fail', function(test) {\n    failures.push(test);\n  });\n\n  runner.on('pending', function(test) {\n    pending.push(test);\n  });\n\n  runner.on('end', function() {\n    var obj = {\n      stats: self.stats,\n      tests: tests.map(clean),\n      pending: pending.map(clean),\n      failures: failures.map(clean),\n      passes: passes.map(clean)\n    };\n\n    runner.testResults = obj;\n\n    process.stdout.write(JSON.stringify(obj, null, 2));\n  });\n}\n\n/**\n * Return a plain-object representation of `test`\n * free of cyclic properties etc.\n *\n * @api private\n * @param {Object} test\n * @return {Object}\n */\nfunction clean(test) {\n  return {\n    title: test.title,\n    fullTitle: test.fullTitle(),\n    duration: test.duration,\n    currentRetry: test.currentRetry(),\n    err: errorJSON(test.err || {})\n  };\n}\n\n/**\n * Transform `error` into a JSON object.\n *\n * @api private\n * @param {Error} err\n * @return {Object}\n */\nfunction errorJSON(err) {\n  var res = {};\n  Object.getOwnPropertyNames(err).forEach(function(key) {\n    res[key] = err[key];\n  }, err);\n  return res;\n}\n\n}).call(this,require('_process'))\n},{\"./base\":17,\"_process\":67}],24:[function(require,module,exports){\n(function (process){\n/**\n * Module dependencies.\n */\n\nvar Base = require('./base');\nvar inherits = require('../utils').inherits;\nvar cursor = Base.cursor;\nvar color = Base.color;\n\n/**\n * Expose `Landing`.\n */\n\nexports = module.exports = Landing;\n\n/**\n * Airplane color.\n */\n\nBase.colors.plane = 0;\n\n/**\n * Airplane crash color.\n */\n\nBase.colors['plane crash'] = 31;\n\n/**\n * Runway color.\n */\n\nBase.colors.runway = 90;\n\n/**\n * Initialize a new `Landing` reporter.\n *\n * @api public\n * @param {Runner} runner\n */\nfunction Landing(runner) {\n  Base.call(this, runner);\n\n  var self = this;\n  var width = Base.window.width * .75 | 0;\n  var total = runner.total;\n  var stream = process.stdout;\n  var plane = color('plane', '✈');\n  var crashed = -1;\n  var n = 0;\n\n  function runway() {\n    var buf = Array(width).join('-');\n    return '  ' + color('runway', buf);\n  }\n\n  runner.on('start', function() {\n    stream.write('\\n\\n\\n  ');\n    cursor.hide();\n  });\n\n  runner.on('test end', function(test) {\n    // check if the plane crashed\n    var col = crashed === -1 ? width * ++n / total | 0 : crashed;\n\n    // show the crash\n    if (test.state === 'failed') {\n      plane = color('plane crash', '✈');\n      crashed = col;\n    }\n\n    // render landing strip\n    stream.write('\\u001b[' + (width + 1) + 'D\\u001b[2A');\n    stream.write(runway());\n    stream.write('\\n  ');\n    stream.write(color('runway', Array(col).join('⋅')));\n    stream.write(plane);\n    stream.write(color('runway', Array(width - col).join('⋅') + '\\n'));\n    stream.write(runway());\n    stream.write('\\u001b[0m');\n  });\n\n  runner.on('end', function() {\n    cursor.show();\n    console.log();\n    self.epilogue();\n  });\n}\n\n/**\n * Inherit from `Base.prototype`.\n */\ninherits(Landing, Base);\n\n}).call(this,require('_process'))\n},{\"../utils\":38,\"./base\":17,\"_process\":67}],25:[function(require,module,exports){\n(function (process){\n/**\n * Module dependencies.\n */\n\nvar Base = require('./base');\nvar inherits = require('../utils').inherits;\nvar color = Base.color;\nvar cursor = Base.cursor;\n\n/**\n * Expose `List`.\n */\n\nexports = module.exports = List;\n\n/**\n * Initialize a new `List` test reporter.\n *\n * @api public\n * @param {Runner} runner\n */\nfunction List(runner) {\n  Base.call(this, runner);\n\n  var self = this;\n  var n = 0;\n\n  runner.on('start', function() {\n    console.log();\n  });\n\n  runner.on('test', function(test) {\n    process.stdout.write(color('pass', '    ' + test.fullTitle() + ': '));\n  });\n\n  runner.on('pending', function(test) {\n    var fmt = color('checkmark', '  -')\n      + color('pending', ' %s');\n    console.log(fmt, test.fullTitle());\n  });\n\n  runner.on('pass', function(test) {\n    var fmt = color('checkmark', '  ' + Base.symbols.dot)\n      + color('pass', ' %s: ')\n      + color(test.speed, '%dms');\n    cursor.CR();\n    console.log(fmt, test.fullTitle(), test.duration);\n  });\n\n  runner.on('fail', function(test) {\n    cursor.CR();\n    console.log(color('fail', '  %d) %s'), ++n, test.fullTitle());\n  });\n\n  runner.on('end', self.epilogue.bind(self));\n}\n\n/**\n * Inherit from `Base.prototype`.\n */\ninherits(List, Base);\n\n}).call(this,require('_process'))\n},{\"../utils\":38,\"./base\":17,\"_process\":67}],26:[function(require,module,exports){\n(function (process){\n/**\n * Module dependencies.\n */\n\nvar Base = require('./base');\nvar utils = require('../utils');\n\n/**\n * Constants\n */\n\nvar SUITE_PREFIX = '$';\n\n/**\n * Expose `Markdown`.\n */\n\nexports = module.exports = Markdown;\n\n/**\n * Initialize a new `Markdown` reporter.\n *\n * @api public\n * @param {Runner} runner\n */\nfunction Markdown(runner) {\n  Base.call(this, runner);\n\n  var level = 0;\n  var buf = '';\n\n  function title(str) {\n    return Array(level).join('#') + ' ' + str;\n  }\n\n  function mapTOC(suite, obj) {\n    var ret = obj;\n    var key = SUITE_PREFIX + suite.title;\n\n    obj = obj[key] = obj[key] || { suite: suite };\n    suite.suites.forEach(function(suite) {\n      mapTOC(suite, obj);\n    });\n\n    return ret;\n  }\n\n  function stringifyTOC(obj, level) {\n    ++level;\n    var buf = '';\n    var link;\n    for (var key in obj) {\n      if (key === 'suite') {\n        continue;\n      }\n      if (key !== SUITE_PREFIX) {\n        link = ' - [' + key.substring(1) + ']';\n        link += '(#' + utils.slug(obj[key].suite.fullTitle()) + ')\\n';\n        buf += Array(level).join('  ') + link;\n      }\n      buf += stringifyTOC(obj[key], level);\n    }\n    return buf;\n  }\n\n  function generateTOC(suite) {\n    var obj = mapTOC(suite, {});\n    return stringifyTOC(obj, 0);\n  }\n\n  generateTOC(runner.suite);\n\n  runner.on('suite', function(suite) {\n    ++level;\n    var slug = utils.slug(suite.fullTitle());\n    buf += '<a name=\"' + slug + '\"></a>' + '\\n';\n    buf += title(suite.title) + '\\n';\n  });\n\n  runner.on('suite end', function() {\n    --level;\n  });\n\n  runner.on('pass', function(test) {\n    var code = utils.clean(test.body);\n    buf += test.title + '.\\n';\n    buf += '\\n```js\\n';\n    buf += code + '\\n';\n    buf += '```\\n\\n';\n  });\n\n  runner.on('end', function() {\n    process.stdout.write('# TOC\\n');\n    process.stdout.write(generateTOC(runner.suite));\n    process.stdout.write(buf);\n  });\n}\n\n}).call(this,require('_process'))\n},{\"../utils\":38,\"./base\":17,\"_process\":67}],27:[function(require,module,exports){\n(function (process){\n/**\n * Module dependencies.\n */\n\nvar Base = require('./base');\nvar inherits = require('../utils').inherits;\n\n/**\n * Expose `Min`.\n */\n\nexports = module.exports = Min;\n\n/**\n * Initialize a new `Min` minimal test reporter (best used with --watch).\n *\n * @api public\n * @param {Runner} runner\n */\nfunction Min(runner) {\n  Base.call(this, runner);\n\n  runner.on('start', function() {\n    // clear screen\n    process.stdout.write('\\u001b[2J');\n    // set cursor position\n    process.stdout.write('\\u001b[1;3H');\n  });\n\n  runner.on('end', this.epilogue.bind(this));\n}\n\n/**\n * Inherit from `Base.prototype`.\n */\ninherits(Min, Base);\n\n}).call(this,require('_process'))\n},{\"../utils\":38,\"./base\":17,\"_process\":67}],28:[function(require,module,exports){\n(function (process){\n/**\n * Module dependencies.\n */\n\nvar Base = require('./base');\nvar inherits = require('../utils').inherits;\n\n/**\n * Expose `Dot`.\n */\n\nexports = module.exports = NyanCat;\n\n/**\n * Initialize a new `Dot` matrix test reporter.\n *\n * @param {Runner} runner\n * @api public\n */\n\nfunction NyanCat(runner) {\n  Base.call(this, runner);\n\n  var self = this;\n  var width = Base.window.width * .75 | 0;\n  var nyanCatWidth = this.nyanCatWidth = 11;\n\n  this.colorIndex = 0;\n  this.numberOfLines = 4;\n  this.rainbowColors = self.generateColors();\n  this.scoreboardWidth = 5;\n  this.tick = 0;\n  this.trajectories = [[], [], [], []];\n  this.trajectoryWidthMax = (width - nyanCatWidth);\n\n  runner.on('start', function() {\n    Base.cursor.hide();\n    self.draw();\n  });\n\n  runner.on('pending', function() {\n    self.draw();\n  });\n\n  runner.on('pass', function() {\n    self.draw();\n  });\n\n  runner.on('fail', function() {\n    self.draw();\n  });\n\n  runner.on('end', function() {\n    Base.cursor.show();\n    for (var i = 0; i < self.numberOfLines; i++) {\n      write('\\n');\n    }\n    self.epilogue();\n  });\n}\n\n/**\n * Inherit from `Base.prototype`.\n */\ninherits(NyanCat, Base);\n\n/**\n * Draw the nyan cat\n *\n * @api private\n */\n\nNyanCat.prototype.draw = function() {\n  this.appendRainbow();\n  this.drawScoreboard();\n  this.drawRainbow();\n  this.drawNyanCat();\n  this.tick = !this.tick;\n};\n\n/**\n * Draw the \"scoreboard\" showing the number\n * of passes, failures and pending tests.\n *\n * @api private\n */\n\nNyanCat.prototype.drawScoreboard = function() {\n  var stats = this.stats;\n\n  function draw(type, n) {\n    write(' ');\n    write(Base.color(type, n));\n    write('\\n');\n  }\n\n  draw('green', stats.passes);\n  draw('fail', stats.failures);\n  draw('pending', stats.pending);\n  write('\\n');\n\n  this.cursorUp(this.numberOfLines);\n};\n\n/**\n * Append the rainbow.\n *\n * @api private\n */\n\nNyanCat.prototype.appendRainbow = function() {\n  var segment = this.tick ? '_' : '-';\n  var rainbowified = this.rainbowify(segment);\n\n  for (var index = 0; index < this.numberOfLines; index++) {\n    var trajectory = this.trajectories[index];\n    if (trajectory.length >= this.trajectoryWidthMax) {\n      trajectory.shift();\n    }\n    trajectory.push(rainbowified);\n  }\n};\n\n/**\n * Draw the rainbow.\n *\n * @api private\n */\n\nNyanCat.prototype.drawRainbow = function() {\n  var self = this;\n\n  this.trajectories.forEach(function(line) {\n    write('\\u001b[' + self.scoreboardWidth + 'C');\n    write(line.join(''));\n    write('\\n');\n  });\n\n  this.cursorUp(this.numberOfLines);\n};\n\n/**\n * Draw the nyan cat\n *\n * @api private\n */\nNyanCat.prototype.drawNyanCat = function() {\n  var self = this;\n  var startWidth = this.scoreboardWidth + this.trajectories[0].length;\n  var dist = '\\u001b[' + startWidth + 'C';\n  var padding = '';\n\n  write(dist);\n  write('_,------,');\n  write('\\n');\n\n  write(dist);\n  padding = self.tick ? '  ' : '   ';\n  write('_|' + padding + '/\\\\_/\\\\ ');\n  write('\\n');\n\n  write(dist);\n  padding = self.tick ? '_' : '__';\n  var tail = self.tick ? '~' : '^';\n  write(tail + '|' + padding + this.face() + ' ');\n  write('\\n');\n\n  write(dist);\n  padding = self.tick ? ' ' : '  ';\n  write(padding + '\"\"  \"\" ');\n  write('\\n');\n\n  this.cursorUp(this.numberOfLines);\n};\n\n/**\n * Draw nyan cat face.\n *\n * @api private\n * @return {string}\n */\n\nNyanCat.prototype.face = function() {\n  var stats = this.stats;\n  if (stats.failures) {\n    return '( x .x)';\n  } else if (stats.pending) {\n    return '( o .o)';\n  } else if (stats.passes) {\n    return '( ^ .^)';\n  }\n  return '( - .-)';\n};\n\n/**\n * Move cursor up `n`.\n *\n * @api private\n * @param {number} n\n */\n\nNyanCat.prototype.cursorUp = function(n) {\n  write('\\u001b[' + n + 'A');\n};\n\n/**\n * Move cursor down `n`.\n *\n * @api private\n * @param {number} n\n */\n\nNyanCat.prototype.cursorDown = function(n) {\n  write('\\u001b[' + n + 'B');\n};\n\n/**\n * Generate rainbow colors.\n *\n * @api private\n * @return {Array}\n */\nNyanCat.prototype.generateColors = function() {\n  var colors = [];\n\n  for (var i = 0; i < (6 * 7); i++) {\n    var pi3 = Math.floor(Math.PI / 3);\n    var n = (i * (1.0 / 6));\n    var r = Math.floor(3 * Math.sin(n) + 3);\n    var g = Math.floor(3 * Math.sin(n + 2 * pi3) + 3);\n    var b = Math.floor(3 * Math.sin(n + 4 * pi3) + 3);\n    colors.push(36 * r + 6 * g + b + 16);\n  }\n\n  return colors;\n};\n\n/**\n * Apply rainbow to the given `str`.\n *\n * @api private\n * @param {string} str\n * @return {string}\n */\nNyanCat.prototype.rainbowify = function(str) {\n  if (!Base.useColors) {\n    return str;\n  }\n  var color = this.rainbowColors[this.colorIndex % this.rainbowColors.length];\n  this.colorIndex += 1;\n  return '\\u001b[38;5;' + color + 'm' + str + '\\u001b[0m';\n};\n\n/**\n * Stdout helper.\n *\n * @param {string} string A message to write to stdout.\n */\nfunction write(string) {\n  process.stdout.write(string);\n}\n\n}).call(this,require('_process'))\n},{\"../utils\":38,\"./base\":17,\"_process\":67}],29:[function(require,module,exports){\n(function (process){\n/**\n * Module dependencies.\n */\n\nvar Base = require('./base');\nvar inherits = require('../utils').inherits;\nvar color = Base.color;\nvar cursor = Base.cursor;\n\n/**\n * Expose `Progress`.\n */\n\nexports = module.exports = Progress;\n\n/**\n * General progress bar color.\n */\n\nBase.colors.progress = 90;\n\n/**\n * Initialize a new `Progress` bar test reporter.\n *\n * @api public\n * @param {Runner} runner\n * @param {Object} options\n */\nfunction Progress(runner, options) {\n  Base.call(this, runner);\n\n  var self = this;\n  var width = Base.window.width * .50 | 0;\n  var total = runner.total;\n  var complete = 0;\n  var lastN = -1;\n\n  // default chars\n  options = options || {};\n  options.open = options.open || '[';\n  options.complete = options.complete || '▬';\n  options.incomplete = options.incomplete || Base.symbols.dot;\n  options.close = options.close || ']';\n  options.verbose = false;\n\n  // tests started\n  runner.on('start', function() {\n    console.log();\n    cursor.hide();\n  });\n\n  // tests complete\n  runner.on('test end', function() {\n    complete++;\n\n    var percent = complete / total;\n    var n = width * percent | 0;\n    var i = width - n;\n\n    if (n === lastN && !options.verbose) {\n      // Don't re-render the line if it hasn't changed\n      return;\n    }\n    lastN = n;\n\n    cursor.CR();\n    process.stdout.write('\\u001b[J');\n    process.stdout.write(color('progress', '  ' + options.open));\n    process.stdout.write(Array(n).join(options.complete));\n    process.stdout.write(Array(i).join(options.incomplete));\n    process.stdout.write(color('progress', options.close));\n    if (options.verbose) {\n      process.stdout.write(color('progress', ' ' + complete + ' of ' + total));\n    }\n  });\n\n  // tests are complete, output some stats\n  // and the failures if any\n  runner.on('end', function() {\n    cursor.show();\n    console.log();\n    self.epilogue();\n  });\n}\n\n/**\n * Inherit from `Base.prototype`.\n */\ninherits(Progress, Base);\n\n}).call(this,require('_process'))\n},{\"../utils\":38,\"./base\":17,\"_process\":67}],30:[function(require,module,exports){\n/**\n * Module dependencies.\n */\n\nvar Base = require('./base');\nvar inherits = require('../utils').inherits;\nvar color = Base.color;\n\n/**\n * Expose `Spec`.\n */\n\nexports = module.exports = Spec;\n\n/**\n * Initialize a new `Spec` test reporter.\n *\n * @api public\n * @param {Runner} runner\n */\nfunction Spec(runner) {\n  Base.call(this, runner);\n\n  var self = this;\n  var indents = 0;\n  var n = 0;\n\n  function indent() {\n    return Array(indents).join('  ');\n  }\n\n  runner.on('start', function() {\n    console.log();\n  });\n\n  runner.on('suite', function(suite) {\n    ++indents;\n    console.log(color('suite', '%s%s'), indent(), suite.title);\n  });\n\n  runner.on('suite end', function() {\n    --indents;\n    if (indents === 1) {\n      console.log();\n    }\n  });\n\n  runner.on('pending', function(test) {\n    var fmt = indent() + color('pending', '  - %s');\n    console.log(fmt, test.title);\n  });\n\n  runner.on('pass', function(test) {\n    var fmt;\n    if (test.speed === 'fast') {\n      fmt = indent()\n        + color('checkmark', '  ' + Base.symbols.ok)\n        + color('pass', ' %s');\n      console.log(fmt, test.title);\n    } else {\n      fmt = indent()\n        + color('checkmark', '  ' + Base.symbols.ok)\n        + color('pass', ' %s')\n        + color(test.speed, ' (%dms)');\n      console.log(fmt, test.title, test.duration);\n    }\n  });\n\n  runner.on('fail', function(test) {\n    console.log(indent() + color('fail', '  %d) %s'), ++n, test.title);\n  });\n\n  runner.on('end', self.epilogue.bind(self));\n}\n\n/**\n * Inherit from `Base.prototype`.\n */\ninherits(Spec, Base);\n\n},{\"../utils\":38,\"./base\":17}],31:[function(require,module,exports){\n/**\n * Module dependencies.\n */\n\nvar Base = require('./base');\n\n/**\n * Expose `TAP`.\n */\n\nexports = module.exports = TAP;\n\n/**\n * Initialize a new `TAP` reporter.\n *\n * @api public\n * @param {Runner} runner\n */\nfunction TAP(runner) {\n  Base.call(this, runner);\n\n  var n = 1;\n  var passes = 0;\n  var failures = 0;\n\n  runner.on('start', function() {\n    var total = runner.grepTotal(runner.suite);\n    console.log('%d..%d', 1, total);\n  });\n\n  runner.on('test end', function() {\n    ++n;\n  });\n\n  runner.on('pending', function(test) {\n    console.log('ok %d %s # SKIP -', n, title(test));\n  });\n\n  runner.on('pass', function(test) {\n    passes++;\n    console.log('ok %d %s', n, title(test));\n  });\n\n  runner.on('fail', function(test, err) {\n    failures++;\n    console.log('not ok %d %s', n, title(test));\n    if (err.stack) {\n      console.log(err.stack.replace(/^/gm, '  '));\n    }\n  });\n\n  runner.on('end', function() {\n    console.log('# tests ' + (passes + failures));\n    console.log('# pass ' + passes);\n    console.log('# fail ' + failures);\n  });\n}\n\n/**\n * Return a TAP-safe title of `test`\n *\n * @api private\n * @param {Object} test\n * @return {String}\n */\nfunction title(test) {\n  return test.fullTitle().replace(/#/g, '');\n}\n\n},{\"./base\":17}],32:[function(require,module,exports){\n(function (process,global){\n/**\n * Module dependencies.\n */\n\nvar Base = require('./base');\nvar utils = require('../utils');\nvar inherits = utils.inherits;\nvar fs = require('fs');\nvar escape = utils.escape;\nvar mkdirp = require('mkdirp');\nvar path = require('path');\n\n/**\n * Save timer references to avoid Sinon interfering (see GH-237).\n */\n\n/* eslint-disable no-unused-vars, no-native-reassign */\nvar Date = global.Date;\nvar setTimeout = global.setTimeout;\nvar setInterval = global.setInterval;\nvar clearTimeout = global.clearTimeout;\nvar clearInterval = global.clearInterval;\n/* eslint-enable no-unused-vars, no-native-reassign */\n\n/**\n * Expose `XUnit`.\n */\n\nexports = module.exports = XUnit;\n\n/**\n * Initialize a new `XUnit` reporter.\n *\n * @api public\n * @param {Runner} runner\n */\nfunction XUnit(runner, options) {\n  Base.call(this, runner);\n\n  var stats = this.stats;\n  var tests = [];\n  var self = this;\n\n  if (options.reporterOptions && options.reporterOptions.output) {\n    if (!fs.createWriteStream) {\n      throw new Error('file output not supported in browser');\n    }\n    mkdirp.sync(path.dirname(options.reporterOptions.output));\n    self.fileStream = fs.createWriteStream(options.reporterOptions.output);\n  }\n\n  runner.on('pending', function(test) {\n    tests.push(test);\n  });\n\n  runner.on('pass', function(test) {\n    tests.push(test);\n  });\n\n  runner.on('fail', function(test) {\n    tests.push(test);\n  });\n\n  runner.on('end', function() {\n    self.write(tag('testsuite', {\n      name: 'Mocha Tests',\n      tests: stats.tests,\n      failures: stats.failures,\n      errors: stats.failures,\n      skipped: stats.tests - stats.failures - stats.passes,\n      timestamp: (new Date()).toUTCString(),\n      time: (stats.duration / 1000) || 0\n    }, false));\n\n    tests.forEach(function(t) {\n      self.test(t);\n    });\n\n    self.write('</testsuite>');\n  });\n}\n\n/**\n * Inherit from `Base.prototype`.\n */\ninherits(XUnit, Base);\n\n/**\n * Override done to close the stream (if it's a file).\n *\n * @param failures\n * @param {Function} fn\n */\nXUnit.prototype.done = function(failures, fn) {\n  if (this.fileStream) {\n    this.fileStream.end(function() {\n      fn(failures);\n    });\n  } else {\n    fn(failures);\n  }\n};\n\n/**\n * Write out the given line.\n *\n * @param {string} line\n */\nXUnit.prototype.write = function(line) {\n  if (this.fileStream) {\n    this.fileStream.write(line + '\\n');\n  } else if (typeof process === 'object' && process.stdout) {\n    process.stdout.write(line + '\\n');\n  } else {\n    console.log(line);\n  }\n};\n\n/**\n * Output tag for the given `test.`\n *\n * @param {Test} test\n */\nXUnit.prototype.test = function(test) {\n  var attrs = {\n    classname: test.parent.fullTitle(),\n    name: test.title,\n    time: (test.duration / 1000) || 0\n  };\n\n  if (test.state === 'failed') {\n    var err = test.err;\n    this.write(tag('testcase', attrs, false, tag('failure', {}, false, escape(err.message) + '\\n' + escape(err.stack))));\n  } else if (test.isPending()) {\n    this.write(tag('testcase', attrs, false, tag('skipped', {}, true)));\n  } else {\n    this.write(tag('testcase', attrs, true));\n  }\n};\n\n/**\n * HTML tag helper.\n *\n * @param name\n * @param attrs\n * @param close\n * @param content\n * @return {string}\n */\nfunction tag(name, attrs, close, content) {\n  var end = close ? '/>' : '>';\n  var pairs = [];\n  var tag;\n\n  for (var key in attrs) {\n    if (Object.prototype.hasOwnProperty.call(attrs, key)) {\n      pairs.push(key + '=\"' + escape(attrs[key]) + '\"');\n    }\n  }\n\n  tag = '<' + name + (pairs.length ? ' ' + pairs.join(' ') : '') + end;\n  if (content) {\n    tag += content + '</' + name + end;\n  }\n  return tag;\n}\n\n}).call(this,require('_process'),typeof global !== \"undefined\" ? global : typeof self !== \"undefined\" ? self : typeof window !== \"undefined\" ? window : {})\n},{\"../utils\":38,\"./base\":17,\"_process\":67,\"fs\":42,\"mkdirp\":64,\"path\":42}],33:[function(require,module,exports){\n(function (global){\n/**\n * Module dependencies.\n */\n\nvar EventEmitter = require('events').EventEmitter;\nvar JSON = require('json3');\nvar Pending = require('./pending');\nvar debug = require('debug')('mocha:runnable');\nvar milliseconds = require('./ms');\nvar utils = require('./utils');\nvar create = require('lodash.create');\n\n/**\n * Save timer references to avoid Sinon interfering (see GH-237).\n */\n\n/* eslint-disable no-unused-vars, no-native-reassign */\nvar Date = global.Date;\nvar setTimeout = global.setTimeout;\nvar setInterval = global.setInterval;\nvar clearTimeout = global.clearTimeout;\nvar clearInterval = global.clearInterval;\n/* eslint-enable no-unused-vars, no-native-reassign */\n\n/**\n * Object#toString().\n */\n\nvar toString = Object.prototype.toString;\n\n/**\n * Expose `Runnable`.\n */\n\nmodule.exports = Runnable;\n\n/**\n * Initialize a new `Runnable` with the given `title` and callback `fn`.\n *\n * @param {String} title\n * @param {Function} fn\n * @api private\n * @param {string} title\n * @param {Function} fn\n */\nfunction Runnable(title, fn) {\n  this.title = title;\n  this.fn = fn;\n  this.body = (fn || '').toString();\n  this.async = fn && fn.length;\n  this.sync = !this.async;\n  this._timeout = 2000;\n  this._slow = 75;\n  this._enableTimeouts = true;\n  this.timedOut = false;\n  this._trace = new Error('done() called multiple times');\n  this._retries = -1;\n  this._currentRetry = 0;\n  this.pending = false;\n}\n\n/**\n * Inherit from `EventEmitter.prototype`.\n */\nRunnable.prototype = create(EventEmitter.prototype, {\n  constructor: Runnable\n});\n\n/**\n * Set & get timeout `ms`.\n *\n * @api private\n * @param {number|string} ms\n * @return {Runnable|number} ms or Runnable instance.\n */\nRunnable.prototype.timeout = function(ms) {\n  if (!arguments.length) {\n    return this._timeout;\n  }\n  // see #1652 for reasoning\n  if (ms === 0 || ms > Math.pow(2, 31)) {\n    this._enableTimeouts = false;\n  }\n  if (typeof ms === 'string') {\n    ms = milliseconds(ms);\n  }\n  debug('timeout %d', ms);\n  this._timeout = ms;\n  if (this.timer) {\n    this.resetTimeout();\n  }\n  return this;\n};\n\n/**\n * Set & get slow `ms`.\n *\n * @api private\n * @param {number|string} ms\n * @return {Runnable|number} ms or Runnable instance.\n */\nRunnable.prototype.slow = function(ms) {\n  if (typeof ms === 'undefined') {\n    return this._slow;\n  }\n  if (typeof ms === 'string') {\n    ms = milliseconds(ms);\n  }\n  debug('timeout %d', ms);\n  this._slow = ms;\n  return this;\n};\n\n/**\n * Set and get whether timeout is `enabled`.\n *\n * @api private\n * @param {boolean} enabled\n * @return {Runnable|boolean} enabled or Runnable instance.\n */\nRunnable.prototype.enableTimeouts = function(enabled) {\n  if (!arguments.length) {\n    return this._enableTimeouts;\n  }\n  debug('enableTimeouts %s', enabled);\n  this._enableTimeouts = enabled;\n  return this;\n};\n\n/**\n * Halt and mark as pending.\n *\n * @api public\n */\nRunnable.prototype.skip = function() {\n  throw new Pending('sync skip');\n};\n\n/**\n * Check if this runnable or its parent suite is marked as pending.\n *\n * @api private\n */\nRunnable.prototype.isPending = function() {\n  return this.pending || (this.parent && this.parent.isPending());\n};\n\n/**\n * Set number of retries.\n *\n * @api private\n */\nRunnable.prototype.retries = function(n) {\n  if (!arguments.length) {\n    return this._retries;\n  }\n  this._retries = n;\n};\n\n/**\n * Get current retry\n *\n * @api private\n */\nRunnable.prototype.currentRetry = function(n) {\n  if (!arguments.length) {\n    return this._currentRetry;\n  }\n  this._currentRetry = n;\n};\n\n/**\n * Return the full title generated by recursively concatenating the parent's\n * full title.\n *\n * @api public\n * @return {string}\n */\nRunnable.prototype.fullTitle = function() {\n  return this.parent.fullTitle() + ' ' + this.title;\n};\n\n/**\n * Clear the timeout.\n *\n * @api private\n */\nRunnable.prototype.clearTimeout = function() {\n  clearTimeout(this.timer);\n};\n\n/**\n * Inspect the runnable void of private properties.\n *\n * @api private\n * @return {string}\n */\nRunnable.prototype.inspect = function() {\n  return JSON.stringify(this, function(key, val) {\n    if (key[0] === '_') {\n      return;\n    }\n    if (key === 'parent') {\n      return '#<Suite>';\n    }\n    if (key === 'ctx') {\n      return '#<Context>';\n    }\n    return val;\n  }, 2);\n};\n\n/**\n * Reset the timeout.\n *\n * @api private\n */\nRunnable.prototype.resetTimeout = function() {\n  var self = this;\n  var ms = this.timeout() || 1e9;\n\n  if (!this._enableTimeouts) {\n    return;\n  }\n  this.clearTimeout();\n  this.timer = setTimeout(function() {\n    if (!self._enableTimeouts) {\n      return;\n    }\n    self.callback(new Error('timeout of ' + ms + 'ms exceeded. Ensure the done() callback is being called in this test.'));\n    self.timedOut = true;\n  }, ms);\n};\n\n/**\n * Whitelist a list of globals for this test run.\n *\n * @api private\n * @param {string[]} globals\n */\nRunnable.prototype.globals = function(globals) {\n  if (!arguments.length) {\n    return this._allowedGlobals;\n  }\n  this._allowedGlobals = globals;\n};\n\n/**\n * Run the test and invoke `fn(err)`.\n *\n * @param {Function} fn\n * @api private\n */\nRunnable.prototype.run = function(fn) {\n  var self = this;\n  var start = new Date();\n  var ctx = this.ctx;\n  var finished;\n  var emitted;\n\n  // Sometimes the ctx exists, but it is not runnable\n  if (ctx && ctx.runnable) {\n    ctx.runnable(this);\n  }\n\n  // called multiple times\n  function multiple(err) {\n    if (emitted) {\n      return;\n    }\n    emitted = true;\n    self.emit('error', err || new Error('done() called multiple times; stacktrace may be inaccurate'));\n  }\n\n  // finished\n  function done(err) {\n    var ms = self.timeout();\n    if (self.timedOut) {\n      return;\n    }\n    if (finished) {\n      return multiple(err || self._trace);\n    }\n\n    self.clearTimeout();\n    self.duration = new Date() - start;\n    finished = true;\n    if (!err && self.duration > ms && self._enableTimeouts) {\n      err = new Error('timeout of ' + ms + 'ms exceeded. Ensure the done() callback is being called in this test.');\n    }\n    fn(err);\n  }\n\n  // for .resetTimeout()\n  this.callback = done;\n\n  // explicit async with `done` argument\n  if (this.async) {\n    this.resetTimeout();\n\n    // allows skip() to be used in an explicit async context\n    this.skip = function asyncSkip() {\n      done(new Pending('async skip call'));\n      // halt execution.  the Runnable will be marked pending\n      // by the previous call, and the uncaught handler will ignore\n      // the failure.\n      throw new Pending('async skip; aborting execution');\n    };\n\n    if (this.allowUncaught) {\n      return callFnAsync(this.fn);\n    }\n    try {\n      callFnAsync(this.fn);\n    } catch (err) {\n      done(utils.getError(err));\n    }\n    return;\n  }\n\n  if (this.allowUncaught) {\n    callFn(this.fn);\n    done();\n    return;\n  }\n\n  // sync or promise-returning\n  try {\n    if (this.isPending()) {\n      done();\n    } else {\n      callFn(this.fn);\n    }\n  } catch (err) {\n    done(utils.getError(err));\n  }\n\n  function callFn(fn) {\n    var result = fn.call(ctx);\n    if (result && typeof result.then === 'function') {\n      self.resetTimeout();\n      result\n        .then(function() {\n          done();\n          // Return null so libraries like bluebird do not warn about\n          // subsequently constructed Promises.\n          return null;\n        },\n        function(reason) {\n          done(reason || new Error('Promise rejected with no or falsy reason'));\n        });\n    } else {\n      if (self.asyncOnly) {\n        return done(new Error('--async-only option in use without declaring `done()` or returning a promise'));\n      }\n\n      done();\n    }\n  }\n\n  function callFnAsync(fn) {\n    var result = fn.call(ctx, function(err) {\n      if (err instanceof Error || toString.call(err) === '[object Error]') {\n        return done(err);\n      }\n      if (err) {\n        if (Object.prototype.toString.call(err) === '[object Object]') {\n          return done(new Error('done() invoked with non-Error: '\n            + JSON.stringify(err)));\n        }\n        return done(new Error('done() invoked with non-Error: ' + err));\n      }\n      if (result && utils.isPromise(result)) {\n        return done(new Error('Resolution method is overspecified. Specify a callback *or* return a Promise; not both.'));\n      }\n\n      done();\n    });\n  }\n};\n\n}).call(this,typeof global !== \"undefined\" ? global : typeof self !== \"undefined\" ? self : typeof window !== \"undefined\" ? window : {})\n},{\"./ms\":15,\"./pending\":16,\"./utils\":38,\"debug\":2,\"events\":3,\"json3\":54,\"lodash.create\":60}],34:[function(require,module,exports){\n(function (process,global){\n/**\n * Module dependencies.\n */\n\nvar EventEmitter = require('events').EventEmitter;\nvar Pending = require('./pending');\nvar utils = require('./utils');\nvar inherits = utils.inherits;\nvar debug = require('debug')('mocha:runner');\nvar Runnable = require('./runnable');\nvar filter = utils.filter;\nvar indexOf = utils.indexOf;\nvar some = utils.some;\nvar keys = utils.keys;\nvar stackFilter = utils.stackTraceFilter();\nvar stringify = utils.stringify;\nvar type = utils.type;\nvar undefinedError = utils.undefinedError;\nvar isArray = utils.isArray;\n\n/**\n * Non-enumerable globals.\n */\n\nvar globals = [\n  'setTimeout',\n  'clearTimeout',\n  'setInterval',\n  'clearInterval',\n  'XMLHttpRequest',\n  'Date',\n  'setImmediate',\n  'clearImmediate'\n];\n\n/**\n * Expose `Runner`.\n */\n\nmodule.exports = Runner;\n\n/**\n * Initialize a `Runner` for the given `suite`.\n *\n * Events:\n *\n *   - `start`  execution started\n *   - `end`  execution complete\n *   - `suite`  (suite) test suite execution started\n *   - `suite end`  (suite) all tests (and sub-suites) have finished\n *   - `test`  (test) test execution started\n *   - `test end`  (test) test completed\n *   - `hook`  (hook) hook execution started\n *   - `hook end`  (hook) hook complete\n *   - `pass`  (test) test passed\n *   - `fail`  (test, err) test failed\n *   - `pending`  (test) test pending\n *\n * @api public\n * @param {Suite} suite Root suite\n * @param {boolean} [delay] Whether or not to delay execution of root suite\n * until ready.\n */\nfunction Runner(suite, delay) {\n  var self = this;\n  this._globals = [];\n  this._abort = false;\n  this._delay = delay;\n  this.suite = suite;\n  this.started = false;\n  this.total = suite.total();\n  this.failures = 0;\n  this.on('test end', function(test) {\n    self.checkGlobals(test);\n  });\n  this.on('hook end', function(hook) {\n    self.checkGlobals(hook);\n  });\n  this._defaultGrep = /.*/;\n  this.grep(this._defaultGrep);\n  this.globals(this.globalProps().concat(extraGlobals()));\n}\n\n/**\n * Wrapper for setImmediate, process.nextTick, or browser polyfill.\n *\n * @param {Function} fn\n * @api private\n */\nRunner.immediately = global.setImmediate || process.nextTick;\n\n/**\n * Inherit from `EventEmitter.prototype`.\n */\ninherits(Runner, EventEmitter);\n\n/**\n * Run tests with full titles matching `re`. Updates runner.total\n * with number of tests matched.\n *\n * @param {RegExp} re\n * @param {Boolean} invert\n * @return {Runner} for chaining\n * @api public\n * @param {RegExp} re\n * @param {boolean} invert\n * @return {Runner} Runner instance.\n */\nRunner.prototype.grep = function(re, invert) {\n  debug('grep %s', re);\n  this._grep = re;\n  this._invert = invert;\n  this.total = this.grepTotal(this.suite);\n  return this;\n};\n\n/**\n * Returns the number of tests matching the grep search for the\n * given suite.\n *\n * @param {Suite} suite\n * @return {Number}\n * @api public\n * @param {Suite} suite\n * @return {number}\n */\nRunner.prototype.grepTotal = function(suite) {\n  var self = this;\n  var total = 0;\n\n  suite.eachTest(function(test) {\n    var match = self._grep.test(test.fullTitle());\n    if (self._invert) {\n      match = !match;\n    }\n    if (match) {\n      total++;\n    }\n  });\n\n  return total;\n};\n\n/**\n * Return a list of global properties.\n *\n * @return {Array}\n * @api private\n */\nRunner.prototype.globalProps = function() {\n  var props = keys(global);\n\n  // non-enumerables\n  for (var i = 0; i < globals.length; ++i) {\n    if (~indexOf(props, globals[i])) {\n      continue;\n    }\n    props.push(globals[i]);\n  }\n\n  return props;\n};\n\n/**\n * Allow the given `arr` of globals.\n *\n * @param {Array} arr\n * @return {Runner} for chaining\n * @api public\n * @param {Array} arr\n * @return {Runner} Runner instance.\n */\nRunner.prototype.globals = function(arr) {\n  if (!arguments.length) {\n    return this._globals;\n  }\n  debug('globals %j', arr);\n  this._globals = this._globals.concat(arr);\n  return this;\n};\n\n/**\n * Check for global variable leaks.\n *\n * @api private\n */\nRunner.prototype.checkGlobals = function(test) {\n  if (this.ignoreLeaks) {\n    return;\n  }\n  var ok = this._globals;\n\n  var globals = this.globalProps();\n  var leaks;\n\n  if (test) {\n    ok = ok.concat(test._allowedGlobals || []);\n  }\n\n  if (this.prevGlobalsLength === globals.length) {\n    return;\n  }\n  this.prevGlobalsLength = globals.length;\n\n  leaks = filterLeaks(ok, globals);\n  this._globals = this._globals.concat(leaks);\n\n  if (leaks.length > 1) {\n    this.fail(test, new Error('global leaks detected: ' + leaks.join(', ') + ''));\n  } else if (leaks.length) {\n    this.fail(test, new Error('global leak detected: ' + leaks[0]));\n  }\n};\n\n/**\n * Fail the given `test`.\n *\n * @api private\n * @param {Test} test\n * @param {Error} err\n */\nRunner.prototype.fail = function(test, err) {\n  if (test.isPending()) {\n    return;\n  }\n\n  ++this.failures;\n  test.state = 'failed';\n\n  if (!(err instanceof Error || err && typeof err.message === 'string')) {\n    err = new Error('the ' + type(err) + ' ' + stringify(err) + ' was thrown, throw an Error :)');\n  }\n\n  err.stack = (this.fullStackTrace || !err.stack)\n    ? err.stack\n    : stackFilter(err.stack);\n\n  this.emit('fail', test, err);\n};\n\n/**\n * Fail the given `hook` with `err`.\n *\n * Hook failures work in the following pattern:\n * - If bail, then exit\n * - Failed `before` hook skips all tests in a suite and subsuites,\n *   but jumps to corresponding `after` hook\n * - Failed `before each` hook skips remaining tests in a\n *   suite and jumps to corresponding `after each` hook,\n *   which is run only once\n * - Failed `after` hook does not alter\n *   execution order\n * - Failed `after each` hook skips remaining tests in a\n *   suite and subsuites, but executes other `after each`\n *   hooks\n *\n * @api private\n * @param {Hook} hook\n * @param {Error} err\n */\nRunner.prototype.failHook = function(hook, err) {\n  if (hook.ctx && hook.ctx.currentTest) {\n    hook.originalTitle = hook.originalTitle || hook.title;\n    hook.title = hook.originalTitle + ' for \"' + hook.ctx.currentTest.title + '\"';\n  }\n\n  this.fail(hook, err);\n  if (this.suite.bail()) {\n    this.emit('end');\n  }\n};\n\n/**\n * Run hook `name` callbacks and then invoke `fn()`.\n *\n * @api private\n * @param {string} name\n * @param {Function} fn\n */\n\nRunner.prototype.hook = function(name, fn) {\n  var suite = this.suite;\n  var hooks = suite['_' + name];\n  var self = this;\n\n  function next(i) {\n    var hook = hooks[i];\n    if (!hook) {\n      return fn();\n    }\n    self.currentRunnable = hook;\n\n    hook.ctx.currentTest = self.test;\n\n    self.emit('hook', hook);\n\n    if (!hook.listeners('error').length) {\n      hook.on('error', function(err) {\n        self.failHook(hook, err);\n      });\n    }\n\n    hook.run(function(err) {\n      var testError = hook.error();\n      if (testError) {\n        self.fail(self.test, testError);\n      }\n      if (err) {\n        if (err instanceof Pending) {\n          if (name === 'beforeEach' || name === 'afterEach') {\n            self.test.pending = true;\n          } else {\n            utils.forEach(suite.tests, function(test) {\n              test.pending = true;\n            });\n            // a pending hook won't be executed twice.\n            hook.pending = true;\n          }\n        } else {\n          self.failHook(hook, err);\n\n          // stop executing hooks, notify callee of hook err\n          return fn(err);\n        }\n      }\n      self.emit('hook end', hook);\n      delete hook.ctx.currentTest;\n      next(++i);\n    });\n  }\n\n  Runner.immediately(function() {\n    next(0);\n  });\n};\n\n/**\n * Run hook `name` for the given array of `suites`\n * in order, and callback `fn(err, errSuite)`.\n *\n * @api private\n * @param {string} name\n * @param {Array} suites\n * @param {Function} fn\n */\nRunner.prototype.hooks = function(name, suites, fn) {\n  var self = this;\n  var orig = this.suite;\n\n  function next(suite) {\n    self.suite = suite;\n\n    if (!suite) {\n      self.suite = orig;\n      return fn();\n    }\n\n    self.hook(name, function(err) {\n      if (err) {\n        var errSuite = self.suite;\n        self.suite = orig;\n        return fn(err, errSuite);\n      }\n\n      next(suites.pop());\n    });\n  }\n\n  next(suites.pop());\n};\n\n/**\n * Run hooks from the top level down.\n *\n * @param {String} name\n * @param {Function} fn\n * @api private\n */\nRunner.prototype.hookUp = function(name, fn) {\n  var suites = [this.suite].concat(this.parents()).reverse();\n  this.hooks(name, suites, fn);\n};\n\n/**\n * Run hooks from the bottom up.\n *\n * @param {String} name\n * @param {Function} fn\n * @api private\n */\nRunner.prototype.hookDown = function(name, fn) {\n  var suites = [this.suite].concat(this.parents());\n  this.hooks(name, suites, fn);\n};\n\n/**\n * Return an array of parent Suites from\n * closest to furthest.\n *\n * @return {Array}\n * @api private\n */\nRunner.prototype.parents = function() {\n  var suite = this.suite;\n  var suites = [];\n  while (suite.parent) {\n    suite = suite.parent;\n    suites.push(suite);\n  }\n  return suites;\n};\n\n/**\n * Run the current test and callback `fn(err)`.\n *\n * @param {Function} fn\n * @api private\n */\nRunner.prototype.runTest = function(fn) {\n  var self = this;\n  var test = this.test;\n\n  if (!test) {\n    return;\n  }\n  if (this.asyncOnly) {\n    test.asyncOnly = true;\n  }\n\n  if (this.allowUncaught) {\n    test.allowUncaught = true;\n    return test.run(fn);\n  }\n  try {\n    test.on('error', function(err) {\n      self.fail(test, err);\n    });\n    test.run(fn);\n  } catch (err) {\n    fn(err);\n  }\n};\n\n/**\n * Run tests in the given `suite` and invoke the callback `fn()` when complete.\n *\n * @api private\n * @param {Suite} suite\n * @param {Function} fn\n */\nRunner.prototype.runTests = function(suite, fn) {\n  var self = this;\n  var tests = suite.tests.slice();\n  var test;\n\n  function hookErr(_, errSuite, after) {\n    // before/after Each hook for errSuite failed:\n    var orig = self.suite;\n\n    // for failed 'after each' hook start from errSuite parent,\n    // otherwise start from errSuite itself\n    self.suite = after ? errSuite.parent : errSuite;\n\n    if (self.suite) {\n      // call hookUp afterEach\n      self.hookUp('afterEach', function(err2, errSuite2) {\n        self.suite = orig;\n        // some hooks may fail even now\n        if (err2) {\n          return hookErr(err2, errSuite2, true);\n        }\n        // report error suite\n        fn(errSuite);\n      });\n    } else {\n      // there is no need calling other 'after each' hooks\n      self.suite = orig;\n      fn(errSuite);\n    }\n  }\n\n  function next(err, errSuite) {\n    // if we bail after first err\n    if (self.failures && suite._bail) {\n      return fn();\n    }\n\n    if (self._abort) {\n      return fn();\n    }\n\n    if (err) {\n      return hookErr(err, errSuite, true);\n    }\n\n    // next test\n    test = tests.shift();\n\n    // all done\n    if (!test) {\n      return fn();\n    }\n\n    // grep\n    var match = self._grep.test(test.fullTitle());\n    if (self._invert) {\n      match = !match;\n    }\n    if (!match) {\n      // Run immediately only if we have defined a grep. When we\n      // define a grep — It can cause maximum callstack error if\n      // the grep is doing a large recursive loop by neglecting\n      // all tests. The run immediately function also comes with\n      // a performance cost. So we don't want to run immediately\n      // if we run the whole test suite, because running the whole\n      // test suite don't do any immediate recursive loops. Thus,\n      // allowing a JS runtime to breathe.\n      if (self._grep !== self._defaultGrep) {\n        Runner.immediately(next);\n      } else {\n        next();\n      }\n      return;\n    }\n\n    if (test.isPending()) {\n      self.emit('pending', test);\n      self.emit('test end', test);\n      return next();\n    }\n\n    // execute test and hook(s)\n    self.emit('test', self.test = test);\n    self.hookDown('beforeEach', function(err, errSuite) {\n      if (test.isPending()) {\n        self.emit('pending', test);\n        self.emit('test end', test);\n        return next();\n      }\n      if (err) {\n        return hookErr(err, errSuite, false);\n      }\n      self.currentRunnable = self.test;\n      self.runTest(function(err) {\n        test = self.test;\n        if (err) {\n          var retry = test.currentRetry();\n          if (err instanceof Pending) {\n            test.pending = true;\n            self.emit('pending', test);\n          } else if (retry < test.retries()) {\n            var clonedTest = test.clone();\n            clonedTest.currentRetry(retry + 1);\n            tests.unshift(clonedTest);\n\n            // Early return + hook trigger so that it doesn't\n            // increment the count wrong\n            return self.hookUp('afterEach', next);\n          } else {\n            self.fail(test, err);\n          }\n          self.emit('test end', test);\n\n          if (err instanceof Pending) {\n            return next();\n          }\n\n          return self.hookUp('afterEach', next);\n        }\n\n        test.state = 'passed';\n        self.emit('pass', test);\n        self.emit('test end', test);\n        self.hookUp('afterEach', next);\n      });\n    });\n  }\n\n  this.next = next;\n  this.hookErr = hookErr;\n  next();\n};\n\n/**\n * Run the given `suite` and invoke the callback `fn()` when complete.\n *\n * @api private\n * @param {Suite} suite\n * @param {Function} fn\n */\nRunner.prototype.runSuite = function(suite, fn) {\n  var i = 0;\n  var self = this;\n  var total = this.grepTotal(suite);\n  var afterAllHookCalled = false;\n\n  debug('run suite %s', suite.fullTitle());\n\n  if (!total || (self.failures && suite._bail)) {\n    return fn();\n  }\n\n  this.emit('suite', this.suite = suite);\n\n  function next(errSuite) {\n    if (errSuite) {\n      // current suite failed on a hook from errSuite\n      if (errSuite === suite) {\n        // if errSuite is current suite\n        // continue to the next sibling suite\n        return done();\n      }\n      // errSuite is among the parents of current suite\n      // stop execution of errSuite and all sub-suites\n      return done(errSuite);\n    }\n\n    if (self._abort) {\n      return done();\n    }\n\n    var curr = suite.suites[i++];\n    if (!curr) {\n      return done();\n    }\n\n    // Avoid grep neglecting large number of tests causing a\n    // huge recursive loop and thus a maximum call stack error.\n    // See comment in `this.runTests()` for more information.\n    if (self._grep !== self._defaultGrep) {\n      Runner.immediately(function() {\n        self.runSuite(curr, next);\n      });\n    } else {\n      self.runSuite(curr, next);\n    }\n  }\n\n  function done(errSuite) {\n    self.suite = suite;\n    self.nextSuite = next;\n\n    if (afterAllHookCalled) {\n      fn(errSuite);\n    } else {\n      // mark that the afterAll block has been called once\n      // and so can be skipped if there is an error in it.\n      afterAllHookCalled = true;\n\n      // remove reference to test\n      delete self.test;\n\n      self.hook('afterAll', function() {\n        self.emit('suite end', suite);\n        fn(errSuite);\n      });\n    }\n  }\n\n  this.nextSuite = next;\n\n  this.hook('beforeAll', function(err) {\n    if (err) {\n      return done();\n    }\n    self.runTests(suite, next);\n  });\n};\n\n/**\n * Handle uncaught exceptions.\n *\n * @param {Error} err\n * @api private\n */\nRunner.prototype.uncaught = function(err) {\n  if (err) {\n    debug('uncaught exception %s', err !== function() {\n      return this;\n    }.call(err) ? err : (err.message || err));\n  } else {\n    debug('uncaught undefined exception');\n    err = undefinedError();\n  }\n  err.uncaught = true;\n\n  var runnable = this.currentRunnable;\n\n  if (!runnable) {\n    runnable = new Runnable('Uncaught error outside test suite');\n    runnable.parent = this.suite;\n\n    if (this.started) {\n      this.fail(runnable, err);\n    } else {\n      // Can't recover from this failure\n      this.emit('start');\n      this.fail(runnable, err);\n      this.emit('end');\n    }\n\n    return;\n  }\n\n  runnable.clearTimeout();\n\n  // Ignore errors if complete or pending\n  if (runnable.state || runnable.isPending()) {\n    return;\n  }\n  this.fail(runnable, err);\n\n  // recover from test\n  if (runnable.type === 'test') {\n    this.emit('test end', runnable);\n    this.hookUp('afterEach', this.next);\n    return;\n  }\n\n // recover from hooks\n  if (runnable.type === 'hook') {\n    var errSuite = this.suite;\n    // if hook failure is in afterEach block\n    if (runnable.fullTitle().indexOf('after each') > -1) {\n      return this.hookErr(err, errSuite, true);\n    }\n    // if hook failure is in beforeEach block\n    if (runnable.fullTitle().indexOf('before each') > -1) {\n      return this.hookErr(err, errSuite, false);\n    }\n    // if hook failure is in after or before blocks\n    return this.nextSuite(errSuite);\n  }\n\n  // bail\n  this.emit('end');\n};\n\n/**\n * Cleans up the references to all the deferred functions\n * (before/after/beforeEach/afterEach) and tests of a Suite.\n * These must be deleted otherwise a memory leak can happen,\n * as those functions may reference variables from closures,\n * thus those variables can never be garbage collected as long\n * as the deferred functions exist.\n *\n * @param {Suite} suite\n */\nfunction cleanSuiteReferences(suite) {\n  function cleanArrReferences(arr) {\n    for (var i = 0; i < arr.length; i++) {\n      delete arr[i].fn;\n    }\n  }\n\n  if (isArray(suite._beforeAll)) {\n    cleanArrReferences(suite._beforeAll);\n  }\n\n  if (isArray(suite._beforeEach)) {\n    cleanArrReferences(suite._beforeEach);\n  }\n\n  if (isArray(suite._afterAll)) {\n    cleanArrReferences(suite._afterAll);\n  }\n\n  if (isArray(suite._afterEach)) {\n    cleanArrReferences(suite._afterEach);\n  }\n\n  for (var i = 0; i < suite.tests.length; i++) {\n    delete suite.tests[i].fn;\n  }\n}\n\n/**\n * Run the root suite and invoke `fn(failures)`\n * on completion.\n *\n * @param {Function} fn\n * @return {Runner} for chaining\n * @api public\n * @param {Function} fn\n * @return {Runner} Runner instance.\n */\nRunner.prototype.run = function(fn) {\n  var self = this;\n  var rootSuite = this.suite;\n\n  // If there is an `only` filter\n  if (this.hasOnly) {\n    filterOnly(rootSuite);\n  }\n\n  fn = fn || function() {};\n\n  function uncaught(err) {\n    self.uncaught(err);\n  }\n\n  function start() {\n    self.started = true;\n    self.emit('start');\n    self.runSuite(rootSuite, function() {\n      debug('finished running');\n      self.emit('end');\n    });\n  }\n\n  debug('start');\n\n  // references cleanup to avoid memory leaks\n  this.on('suite end', cleanSuiteReferences);\n\n  // callback\n  this.on('end', function() {\n    debug('end');\n    process.removeListener('uncaughtException', uncaught);\n    fn(self.failures);\n  });\n\n  // uncaught exception\n  process.on('uncaughtException', uncaught);\n\n  if (this._delay) {\n    // for reporters, I guess.\n    // might be nice to debounce some dots while we wait.\n    this.emit('waiting', rootSuite);\n    rootSuite.once('run', start);\n  } else {\n    start();\n  }\n\n  return this;\n};\n\n/**\n * Cleanly abort execution.\n *\n * @api public\n * @return {Runner} Runner instance.\n */\nRunner.prototype.abort = function() {\n  debug('aborting');\n  this._abort = true;\n\n  return this;\n};\n\n/**\n * Filter suites based on `isOnly` logic.\n *\n * @param {Array} suite\n * @returns {Boolean}\n * @api private\n */\nfunction filterOnly(suite) {\n  if (suite._onlyTests.length) {\n    // If the suite contains `only` tests, run those and ignore any nested suites.\n    suite.tests = suite._onlyTests;\n    suite.suites = [];\n  } else {\n    // Otherwise, do not run any of the tests in this suite.\n    suite.tests = [];\n    utils.forEach(suite._onlySuites, function(onlySuite) {\n      // If there are other `only` tests/suites nested in the current `only` suite, then filter that `only` suite.\n      // Otherwise, all of the tests on this `only` suite should be run, so don't filter it.\n      if (hasOnly(onlySuite)) {\n        filterOnly(onlySuite);\n      }\n    });\n    // Run the `only` suites, as well as any other suites that have `only` tests/suites as descendants.\n    suite.suites = filter(suite.suites, function(childSuite) {\n      return indexOf(suite._onlySuites, childSuite) !== -1 || filterOnly(childSuite);\n    });\n  }\n  // Keep the suite only if there is something to run\n  return suite.tests.length || suite.suites.length;\n}\n\n/**\n * Determines whether a suite has an `only` test or suite as a descendant.\n *\n * @param {Array} suite\n * @returns {Boolean}\n * @api private\n */\nfunction hasOnly(suite) {\n  return suite._onlyTests.length || suite._onlySuites.length || some(suite.suites, hasOnly);\n}\n\n/**\n * Filter leaks with the given globals flagged as `ok`.\n *\n * @api private\n * @param {Array} ok\n * @param {Array} globals\n * @return {Array}\n */\nfunction filterLeaks(ok, globals) {\n  return filter(globals, function(key) {\n    // Firefox and Chrome exposes iframes as index inside the window object\n    if (/^\\d+/.test(key)) {\n      return false;\n    }\n\n    // in firefox\n    // if runner runs in an iframe, this iframe's window.getInterface method\n    // not init at first it is assigned in some seconds\n    if (global.navigator && (/^getInterface/).test(key)) {\n      return false;\n    }\n\n    // an iframe could be approached by window[iframeIndex]\n    // in ie6,7,8 and opera, iframeIndex is enumerable, this could cause leak\n    if (global.navigator && (/^\\d+/).test(key)) {\n      return false;\n    }\n\n    // Opera and IE expose global variables for HTML element IDs (issue #243)\n    if (/^mocha-/.test(key)) {\n      return false;\n    }\n\n    var matched = filter(ok, function(ok) {\n      if (~ok.indexOf('*')) {\n        return key.indexOf(ok.split('*')[0]) === 0;\n      }\n      return key === ok;\n    });\n    return !matched.length && (!global.navigator || key !== 'onerror');\n  });\n}\n\n/**\n * Array of globals dependent on the environment.\n *\n * @return {Array}\n * @api private\n */\nfunction extraGlobals() {\n  if (typeof process === 'object' && typeof process.version === 'string') {\n    var parts = process.version.split('.');\n    var nodeVersion = utils.reduce(parts, function(a, v) {\n      return a << 8 | v;\n    });\n\n    // 'errno' was renamed to process._errno in v0.9.11.\n\n    if (nodeVersion < 0x00090B) {\n      return ['errno'];\n    }\n  }\n\n  return [];\n}\n\n}).call(this,require('_process'),typeof global !== \"undefined\" ? global : typeof self !== \"undefined\" ? self : typeof window !== \"undefined\" ? window : {})\n},{\"./pending\":16,\"./runnable\":33,\"./utils\":38,\"_process\":67,\"debug\":2,\"events\":3}],35:[function(require,module,exports){\n/**\n * Module dependencies.\n */\n\nvar EventEmitter = require('events').EventEmitter;\nvar Hook = require('./hook');\nvar utils = require('./utils');\nvar inherits = utils.inherits;\nvar debug = require('debug')('mocha:suite');\nvar milliseconds = require('./ms');\n\n/**\n * Expose `Suite`.\n */\n\nexports = module.exports = Suite;\n\n/**\n * Create a new `Suite` with the given `title` and parent `Suite`. When a suite\n * with the same title is already present, that suite is returned to provide\n * nicer reporter and more flexible meta-testing.\n *\n * @api public\n * @param {Suite} parent\n * @param {string} title\n * @return {Suite}\n */\nexports.create = function(parent, title) {\n  var suite = new Suite(title, parent.ctx);\n  suite.parent = parent;\n  title = suite.fullTitle();\n  parent.addSuite(suite);\n  return suite;\n};\n\n/**\n * Initialize a new `Suite` with the given `title` and `ctx`.\n *\n * @api private\n * @param {string} title\n * @param {Context} parentContext\n */\nfunction Suite(title, parentContext) {\n  if (!utils.isString(title)) {\n    throw new Error('Suite `title` should be a \"string\" but \"' + typeof title + '\" was given instead.');\n  }\n  this.title = title;\n  function Context() {}\n  Context.prototype = parentContext;\n  this.ctx = new Context();\n  this.suites = [];\n  this.tests = [];\n  this.pending = false;\n  this._beforeEach = [];\n  this._beforeAll = [];\n  this._afterEach = [];\n  this._afterAll = [];\n  this.root = !title;\n  this._timeout = 2000;\n  this._enableTimeouts = true;\n  this._slow = 75;\n  this._bail = false;\n  this._retries = -1;\n  this._onlyTests = [];\n  this._onlySuites = [];\n  this.delayed = false;\n}\n\n/**\n * Inherit from `EventEmitter.prototype`.\n */\ninherits(Suite, EventEmitter);\n\n/**\n * Return a clone of this `Suite`.\n *\n * @api private\n * @return {Suite}\n */\nSuite.prototype.clone = function() {\n  var suite = new Suite(this.title);\n  debug('clone');\n  suite.ctx = this.ctx;\n  suite.timeout(this.timeout());\n  suite.retries(this.retries());\n  suite.enableTimeouts(this.enableTimeouts());\n  suite.slow(this.slow());\n  suite.bail(this.bail());\n  return suite;\n};\n\n/**\n * Set timeout `ms` or short-hand such as \"2s\".\n *\n * @api private\n * @param {number|string} ms\n * @return {Suite|number} for chaining\n */\nSuite.prototype.timeout = function(ms) {\n  if (!arguments.length) {\n    return this._timeout;\n  }\n  if (ms.toString() === '0') {\n    this._enableTimeouts = false;\n  }\n  if (typeof ms === 'string') {\n    ms = milliseconds(ms);\n  }\n  debug('timeout %d', ms);\n  this._timeout = parseInt(ms, 10);\n  return this;\n};\n\n/**\n * Set number of times to retry a failed test.\n *\n * @api private\n * @param {number|string} n\n * @return {Suite|number} for chaining\n */\nSuite.prototype.retries = function(n) {\n  if (!arguments.length) {\n    return this._retries;\n  }\n  debug('retries %d', n);\n  this._retries = parseInt(n, 10) || 0;\n  return this;\n};\n\n/**\n  * Set timeout to `enabled`.\n  *\n  * @api private\n  * @param {boolean} enabled\n  * @return {Suite|boolean} self or enabled\n  */\nSuite.prototype.enableTimeouts = function(enabled) {\n  if (!arguments.length) {\n    return this._enableTimeouts;\n  }\n  debug('enableTimeouts %s', enabled);\n  this._enableTimeouts = enabled;\n  return this;\n};\n\n/**\n * Set slow `ms` or short-hand such as \"2s\".\n *\n * @api private\n * @param {number|string} ms\n * @return {Suite|number} for chaining\n */\nSuite.prototype.slow = function(ms) {\n  if (!arguments.length) {\n    return this._slow;\n  }\n  if (typeof ms === 'string') {\n    ms = milliseconds(ms);\n  }\n  debug('slow %d', ms);\n  this._slow = ms;\n  return this;\n};\n\n/**\n * Sets whether to bail after first error.\n *\n * @api private\n * @param {boolean} bail\n * @return {Suite|number} for chaining\n */\nSuite.prototype.bail = function(bail) {\n  if (!arguments.length) {\n    return this._bail;\n  }\n  debug('bail %s', bail);\n  this._bail = bail;\n  return this;\n};\n\n/**\n * Check if this suite or its parent suite is marked as pending.\n *\n * @api private\n */\nSuite.prototype.isPending = function() {\n  return this.pending || (this.parent && this.parent.isPending());\n};\n\n/**\n * Run `fn(test[, done])` before running tests.\n *\n * @api private\n * @param {string} title\n * @param {Function} fn\n * @return {Suite} for chaining\n */\nSuite.prototype.beforeAll = function(title, fn) {\n  if (this.isPending()) {\n    return this;\n  }\n  if (typeof title === 'function') {\n    fn = title;\n    title = fn.name;\n  }\n  title = '\"before all\" hook' + (title ? ': ' + title : '');\n\n  var hook = new Hook(title, fn);\n  hook.parent = this;\n  hook.timeout(this.timeout());\n  hook.retries(this.retries());\n  hook.enableTimeouts(this.enableTimeouts());\n  hook.slow(this.slow());\n  hook.ctx = this.ctx;\n  this._beforeAll.push(hook);\n  this.emit('beforeAll', hook);\n  return this;\n};\n\n/**\n * Run `fn(test[, done])` after running tests.\n *\n * @api private\n * @param {string} title\n * @param {Function} fn\n * @return {Suite} for chaining\n */\nSuite.prototype.afterAll = function(title, fn) {\n  if (this.isPending()) {\n    return this;\n  }\n  if (typeof title === 'function') {\n    fn = title;\n    title = fn.name;\n  }\n  title = '\"after all\" hook' + (title ? ': ' + title : '');\n\n  var hook = new Hook(title, fn);\n  hook.parent = this;\n  hook.timeout(this.timeout());\n  hook.retries(this.retries());\n  hook.enableTimeouts(this.enableTimeouts());\n  hook.slow(this.slow());\n  hook.ctx = this.ctx;\n  this._afterAll.push(hook);\n  this.emit('afterAll', hook);\n  return this;\n};\n\n/**\n * Run `fn(test[, done])` before each test case.\n *\n * @api private\n * @param {string} title\n * @param {Function} fn\n * @return {Suite} for chaining\n */\nSuite.prototype.beforeEach = function(title, fn) {\n  if (this.isPending()) {\n    return this;\n  }\n  if (typeof title === 'function') {\n    fn = title;\n    title = fn.name;\n  }\n  title = '\"before each\" hook' + (title ? ': ' + title : '');\n\n  var hook = new Hook(title, fn);\n  hook.parent = this;\n  hook.timeout(this.timeout());\n  hook.retries(this.retries());\n  hook.enableTimeouts(this.enableTimeouts());\n  hook.slow(this.slow());\n  hook.ctx = this.ctx;\n  this._beforeEach.push(hook);\n  this.emit('beforeEach', hook);\n  return this;\n};\n\n/**\n * Run `fn(test[, done])` after each test case.\n *\n * @api private\n * @param {string} title\n * @param {Function} fn\n * @return {Suite} for chaining\n */\nSuite.prototype.afterEach = function(title, fn) {\n  if (this.isPending()) {\n    return this;\n  }\n  if (typeof title === 'function') {\n    fn = title;\n    title = fn.name;\n  }\n  title = '\"after each\" hook' + (title ? ': ' + title : '');\n\n  var hook = new Hook(title, fn);\n  hook.parent = this;\n  hook.timeout(this.timeout());\n  hook.retries(this.retries());\n  hook.enableTimeouts(this.enableTimeouts());\n  hook.slow(this.slow());\n  hook.ctx = this.ctx;\n  this._afterEach.push(hook);\n  this.emit('afterEach', hook);\n  return this;\n};\n\n/**\n * Add a test `suite`.\n *\n * @api private\n * @param {Suite} suite\n * @return {Suite} for chaining\n */\nSuite.prototype.addSuite = function(suite) {\n  suite.parent = this;\n  suite.timeout(this.timeout());\n  suite.retries(this.retries());\n  suite.enableTimeouts(this.enableTimeouts());\n  suite.slow(this.slow());\n  suite.bail(this.bail());\n  this.suites.push(suite);\n  this.emit('suite', suite);\n  return this;\n};\n\n/**\n * Add a `test` to this suite.\n *\n * @api private\n * @param {Test} test\n * @return {Suite} for chaining\n */\nSuite.prototype.addTest = function(test) {\n  test.parent = this;\n  test.timeout(this.timeout());\n  test.retries(this.retries());\n  test.enableTimeouts(this.enableTimeouts());\n  test.slow(this.slow());\n  test.ctx = this.ctx;\n  this.tests.push(test);\n  this.emit('test', test);\n  return this;\n};\n\n/**\n * Return the full title generated by recursively concatenating the parent's\n * full title.\n *\n * @api public\n * @return {string}\n */\nSuite.prototype.fullTitle = function() {\n  if (this.parent) {\n    var full = this.parent.fullTitle();\n    if (full) {\n      return full + ' ' + this.title;\n    }\n  }\n  return this.title;\n};\n\n/**\n * Return the total number of tests.\n *\n * @api public\n * @return {number}\n */\nSuite.prototype.total = function() {\n  return utils.reduce(this.suites, function(sum, suite) {\n    return sum + suite.total();\n  }, 0) + this.tests.length;\n};\n\n/**\n * Iterates through each suite recursively to find all tests. Applies a\n * function in the format `fn(test)`.\n *\n * @api private\n * @param {Function} fn\n * @return {Suite}\n */\nSuite.prototype.eachTest = function(fn) {\n  utils.forEach(this.tests, fn);\n  utils.forEach(this.suites, function(suite) {\n    suite.eachTest(fn);\n  });\n  return this;\n};\n\n/**\n * This will run the root suite if we happen to be running in delayed mode.\n */\nSuite.prototype.run = function run() {\n  if (this.root) {\n    this.emit('run');\n  }\n};\n\n},{\"./hook\":7,\"./ms\":15,\"./utils\":38,\"debug\":2,\"events\":3}],36:[function(require,module,exports){\n/**\n * Module dependencies.\n */\n\nvar Runnable = require('./runnable');\nvar create = require('lodash.create');\nvar isString = require('./utils').isString;\n\n/**\n * Expose `Test`.\n */\n\nmodule.exports = Test;\n\n/**\n * Initialize a new `Test` with the given `title` and callback `fn`.\n *\n * @api private\n * @param {String} title\n * @param {Function} fn\n */\nfunction Test(title, fn) {\n  if (!isString(title)) {\n    throw new Error('Test `title` should be a \"string\" but \"' + typeof title + '\" was given instead.');\n  }\n  Runnable.call(this, title, fn);\n  this.pending = !fn;\n  this.type = 'test';\n}\n\n/**\n * Inherit from `Runnable.prototype`.\n */\nTest.prototype = create(Runnable.prototype, {\n  constructor: Test\n});\n\nTest.prototype.clone = function() {\n  var test = new Test(this.title, this.fn);\n  test.timeout(this.timeout());\n  test.slow(this.slow());\n  test.enableTimeouts(this.enableTimeouts());\n  test.retries(this.retries());\n  test.currentRetry(this.currentRetry());\n  test.globals(this.globals());\n  test.parent = this.parent;\n  test.file = this.file;\n  test.ctx = this.ctx;\n  return test;\n};\n\n},{\"./runnable\":33,\"./utils\":38,\"lodash.create\":60}],37:[function(require,module,exports){\n'use strict';\n\n/**\n * Pad a `number` with a ten's place zero.\n *\n * @param {number} number\n * @return {string}\n */\nfunction pad(number) {\n  var n = number.toString();\n  return n.length === 1 ? '0' + n : n;\n}\n\n/**\n * Turn a `date` into an ISO string.\n *\n * https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/toISOString\n *\n * @param {Date} date\n * @return {string}\n */\nfunction toISOString(date) {\n  return date.getUTCFullYear()\n    + '-' + pad(date.getUTCMonth() + 1)\n    + '-' + pad(date.getUTCDate())\n    + 'T' + pad(date.getUTCHours())\n    + ':' + pad(date.getUTCMinutes())\n    + ':' + pad(date.getUTCSeconds())\n    + '.' + String((date.getUTCMilliseconds()/1000).toFixed(3)).slice(2, 5)\n    + 'Z';\n}\n\n/*\n * Exports.\n */\n\nmodule.exports = toISOString;\n\n},{}],38:[function(require,module,exports){\n(function (process,Buffer){\n/* eslint-env browser */\n\n/**\n * Module dependencies.\n */\n\nvar JSON = require('json3');\nvar basename = require('path').basename;\nvar debug = require('debug')('mocha:watch');\nvar exists = require('fs').existsSync || require('path').existsSync;\nvar glob = require('glob');\nvar path = require('path');\nvar join = path.join;\nvar readdirSync = require('fs').readdirSync;\nvar statSync = require('fs').statSync;\nvar watchFile = require('fs').watchFile;\nvar toISOString = require('./to-iso-string');\n\n/**\n * Ignored directories.\n */\n\nvar ignore = ['node_modules', '.git'];\n\nexports.inherits = require('util').inherits;\n\n/**\n * Escape special characters in the given string of html.\n *\n * @api private\n * @param  {string} html\n * @return {string}\n */\nexports.escape = function(html) {\n  return String(html)\n    .replace(/&/g, '&amp;')\n    .replace(/\"/g, '&quot;')\n    .replace(/</g, '&lt;')\n    .replace(/>/g, '&gt;');\n};\n\n/**\n * Array#forEach (<=IE8)\n *\n * @api private\n * @param {Array} arr\n * @param {Function} fn\n * @param {Object} scope\n */\nexports.forEach = function(arr, fn, scope) {\n  for (var i = 0, l = arr.length; i < l; i++) {\n    fn.call(scope, arr[i], i);\n  }\n};\n\n/**\n * Test if the given obj is type of string.\n *\n * @api private\n * @param {Object} obj\n * @return {boolean}\n */\nexports.isString = function(obj) {\n  return typeof obj === 'string';\n};\n\n/**\n * Array#map (<=IE8)\n *\n * @api private\n * @param {Array} arr\n * @param {Function} fn\n * @param {Object} scope\n * @return {Array}\n */\nexports.map = function(arr, fn, scope) {\n  var result = [];\n  for (var i = 0, l = arr.length; i < l; i++) {\n    result.push(fn.call(scope, arr[i], i, arr));\n  }\n  return result;\n};\n\n/**\n * Array#indexOf (<=IE8)\n *\n * @api private\n * @param {Array} arr\n * @param {Object} obj to find index of\n * @param {number} start\n * @return {number}\n */\nvar indexOf = exports.indexOf = function(arr, obj, start) {\n  for (var i = start || 0, l = arr.length; i < l; i++) {\n    if (arr[i] === obj) {\n      return i;\n    }\n  }\n  return -1;\n};\n\n/**\n * Array#reduce (<=IE8)\n *\n * @api private\n * @param {Array} arr\n * @param {Function} fn\n * @param {Object} val Initial value.\n * @return {*}\n */\nvar reduce = exports.reduce = function(arr, fn, val) {\n  var rval = val;\n\n  for (var i = 0, l = arr.length; i < l; i++) {\n    rval = fn(rval, arr[i], i, arr);\n  }\n\n  return rval;\n};\n\n/**\n * Array#filter (<=IE8)\n *\n * @api private\n * @param {Array} arr\n * @param {Function} fn\n * @return {Array}\n */\nexports.filter = function(arr, fn) {\n  var ret = [];\n\n  for (var i = 0, l = arr.length; i < l; i++) {\n    var val = arr[i];\n    if (fn(val, i, arr)) {\n      ret.push(val);\n    }\n  }\n\n  return ret;\n};\n\n/**\n * Array#some (<=IE8)\n *\n * @api private\n * @param {Array} arr\n * @param {Function} fn\n * @return {Array}\n */\nexports.some = function(arr, fn) {\n  for (var i = 0, l = arr.length; i < l; i++) {\n    if (fn(arr[i])) {\n      return true;\n    }\n  }\n  return false;\n};\n\n/**\n * Object.keys (<=IE8)\n *\n * @api private\n * @param {Object} obj\n * @return {Array} keys\n */\nexports.keys = typeof Object.keys === 'function' ? Object.keys : function(obj) {\n  var keys = [];\n  var has = Object.prototype.hasOwnProperty; // for `window` on <=IE8\n\n  for (var key in obj) {\n    if (has.call(obj, key)) {\n      keys.push(key);\n    }\n  }\n\n  return keys;\n};\n\n/**\n * Watch the given `files` for changes\n * and invoke `fn(file)` on modification.\n *\n * @api private\n * @param {Array} files\n * @param {Function} fn\n */\nexports.watch = function(files, fn) {\n  var options = { interval: 100 };\n  files.forEach(function(file) {\n    debug('file %s', file);\n    watchFile(file, options, function(curr, prev) {\n      if (prev.mtime < curr.mtime) {\n        fn(file);\n      }\n    });\n  });\n};\n\n/**\n * Array.isArray (<=IE8)\n *\n * @api private\n * @param {Object} obj\n * @return {Boolean}\n */\nvar isArray = typeof Array.isArray === 'function' ? Array.isArray : function(obj) {\n  return Object.prototype.toString.call(obj) === '[object Array]';\n};\n\nexports.isArray = isArray;\n\n/**\n * Buffer.prototype.toJSON polyfill.\n *\n * @type {Function}\n */\nif (typeof Buffer !== 'undefined' && Buffer.prototype) {\n  Buffer.prototype.toJSON = Buffer.prototype.toJSON || function() {\n    return Array.prototype.slice.call(this, 0);\n  };\n}\n\n/**\n * Ignored files.\n *\n * @api private\n * @param {string} path\n * @return {boolean}\n */\nfunction ignored(path) {\n  return !~ignore.indexOf(path);\n}\n\n/**\n * Lookup files in the given `dir`.\n *\n * @api private\n * @param {string} dir\n * @param {string[]} [ext=['.js']]\n * @param {Array} [ret=[]]\n * @return {Array}\n */\nexports.files = function(dir, ext, ret) {\n  ret = ret || [];\n  ext = ext || ['js'];\n\n  var re = new RegExp('\\\\.(' + ext.join('|') + ')$');\n\n  readdirSync(dir)\n    .filter(ignored)\n    .forEach(function(path) {\n      path = join(dir, path);\n      if (statSync(path).isDirectory()) {\n        exports.files(path, ext, ret);\n      } else if (path.match(re)) {\n        ret.push(path);\n      }\n    });\n\n  return ret;\n};\n\n/**\n * Compute a slug from the given `str`.\n *\n * @api private\n * @param {string} str\n * @return {string}\n */\nexports.slug = function(str) {\n  return str\n    .toLowerCase()\n    .replace(/ +/g, '-')\n    .replace(/[^-\\w]/g, '');\n};\n\n/**\n * Strip the function definition from `str`, and re-indent for pre whitespace.\n *\n * @param {string} str\n * @return {string}\n */\nexports.clean = function(str) {\n  str = str\n    .replace(/\\r\\n?|[\\n\\u2028\\u2029]/g, '\\n').replace(/^\\uFEFF/, '')\n    // (traditional)->  space/name     parameters    body     (lambda)-> parameters       body   multi-statement/single          keep body content\n    .replace(/^function(?:\\s*|\\s+[^(]*)\\([^)]*\\)\\s*\\{((?:.|\\n)*?)\\s*\\}$|^\\([^)]*\\)\\s*=>\\s*(?:\\{((?:.|\\n)*?)\\s*\\}|((?:.|\\n)*))$/, '$1$2$3');\n\n  var spaces = str.match(/^\\n?( *)/)[1].length;\n  var tabs = str.match(/^\\n?(\\t*)/)[1].length;\n  var re = new RegExp('^\\n?' + (tabs ? '\\t' : ' ') + '{' + (tabs ? tabs : spaces) + '}', 'gm');\n\n  str = str.replace(re, '');\n\n  return exports.trim(str);\n};\n\n/**\n * Trim the given `str`.\n *\n * @api private\n * @param {string} str\n * @return {string}\n */\nexports.trim = function(str) {\n  return str.replace(/^\\s+|\\s+$/g, '');\n};\n\n/**\n * Parse the given `qs`.\n *\n * @api private\n * @param {string} qs\n * @return {Object}\n */\nexports.parseQuery = function(qs) {\n  return reduce(qs.replace('?', '').split('&'), function(obj, pair) {\n    var i = pair.indexOf('=');\n    var key = pair.slice(0, i);\n    var val = pair.slice(++i);\n\n    obj[key] = decodeURIComponent(val);\n    return obj;\n  }, {});\n};\n\n/**\n * Highlight the given string of `js`.\n *\n * @api private\n * @param {string} js\n * @return {string}\n */\nfunction highlight(js) {\n  return js\n    .replace(/</g, '&lt;')\n    .replace(/>/g, '&gt;')\n    .replace(/\\/\\/(.*)/gm, '<span class=\"comment\">//$1</span>')\n    .replace(/('.*?')/gm, '<span class=\"string\">$1</span>')\n    .replace(/(\\d+\\.\\d+)/gm, '<span class=\"number\">$1</span>')\n    .replace(/(\\d+)/gm, '<span class=\"number\">$1</span>')\n    .replace(/\\bnew[ \\t]+(\\w+)/gm, '<span class=\"keyword\">new</span> <span class=\"init\">$1</span>')\n    .replace(/\\b(function|new|throw|return|var|if|else)\\b/gm, '<span class=\"keyword\">$1</span>');\n}\n\n/**\n * Highlight the contents of tag `name`.\n *\n * @api private\n * @param {string} name\n */\nexports.highlightTags = function(name) {\n  var code = document.getElementById('mocha').getElementsByTagName(name);\n  for (var i = 0, len = code.length; i < len; ++i) {\n    code[i].innerHTML = highlight(code[i].innerHTML);\n  }\n};\n\n/**\n * If a value could have properties, and has none, this function is called,\n * which returns a string representation of the empty value.\n *\n * Functions w/ no properties return `'[Function]'`\n * Arrays w/ length === 0 return `'[]'`\n * Objects w/ no properties return `'{}'`\n * All else: return result of `value.toString()`\n *\n * @api private\n * @param {*} value The value to inspect.\n * @param {string} typeHint The type of the value\n * @returns {string}\n */\nfunction emptyRepresentation(value, typeHint) {\n  switch (typeHint) {\n    case 'function':\n      return '[Function]';\n    case 'object':\n      return '{}';\n    case 'array':\n      return '[]';\n    default:\n      return value.toString();\n  }\n}\n\n/**\n * Takes some variable and asks `Object.prototype.toString()` what it thinks it\n * is.\n *\n * @api private\n * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/toString\n * @param {*} value The value to test.\n * @returns {string} Computed type\n * @example\n * type({}) // 'object'\n * type([]) // 'array'\n * type(1) // 'number'\n * type(false) // 'boolean'\n * type(Infinity) // 'number'\n * type(null) // 'null'\n * type(new Date()) // 'date'\n * type(/foo/) // 'regexp'\n * type('type') // 'string'\n * type(global) // 'global'\n * type(new String('foo') // 'object'\n */\nvar type = exports.type = function type(value) {\n  if (value === undefined) {\n    return 'undefined';\n  } else if (value === null) {\n    return 'null';\n  } else if (typeof Buffer !== 'undefined' && Buffer.isBuffer(value)) {\n    return 'buffer';\n  }\n  return Object.prototype.toString.call(value)\n    .replace(/^\\[.+\\s(.+?)\\]$/, '$1')\n    .toLowerCase();\n};\n\n/**\n * Stringify `value`. Different behavior depending on type of value:\n *\n * - If `value` is undefined or null, return `'[undefined]'` or `'[null]'`, respectively.\n * - If `value` is not an object, function or array, return result of `value.toString()` wrapped in double-quotes.\n * - If `value` is an *empty* object, function, or array, return result of function\n *   {@link emptyRepresentation}.\n * - If `value` has properties, call {@link exports.canonicalize} on it, then return result of\n *   JSON.stringify().\n *\n * @api private\n * @see exports.type\n * @param {*} value\n * @return {string}\n */\nexports.stringify = function(value) {\n  var typeHint = type(value);\n\n  if (!~indexOf(['object', 'array', 'function'], typeHint)) {\n    if (typeHint === 'buffer') {\n      var json = value.toJSON();\n      // Based on the toJSON result\n      return jsonStringify(json.data && json.type ? json.data : json, 2)\n        .replace(/,(\\n|$)/g, '$1');\n    }\n\n    // IE7/IE8 has a bizarre String constructor; needs to be coerced\n    // into an array and back to obj.\n    if (typeHint === 'string' && typeof value === 'object') {\n      value = reduce(value.split(''), function(acc, char, idx) {\n        acc[idx] = char;\n        return acc;\n      }, {});\n      typeHint = 'object';\n    } else {\n      return jsonStringify(value);\n    }\n  }\n\n  for (var prop in value) {\n    if (Object.prototype.hasOwnProperty.call(value, prop)) {\n      return jsonStringify(exports.canonicalize(value, null, typeHint), 2).replace(/,(\\n|$)/g, '$1');\n    }\n  }\n\n  return emptyRepresentation(value, typeHint);\n};\n\n/**\n * like JSON.stringify but more sense.\n *\n * @api private\n * @param {Object}  object\n * @param {number=} spaces\n * @param {number=} depth\n * @returns {*}\n */\nfunction jsonStringify(object, spaces, depth) {\n  if (typeof spaces === 'undefined') {\n    // primitive types\n    return _stringify(object);\n  }\n\n  depth = depth || 1;\n  var space = spaces * depth;\n  var str = isArray(object) ? '[' : '{';\n  var end = isArray(object) ? ']' : '}';\n  var length = typeof object.length === 'number' ? object.length : exports.keys(object).length;\n  // `.repeat()` polyfill\n  function repeat(s, n) {\n    return new Array(n).join(s);\n  }\n\n  function _stringify(val) {\n    switch (type(val)) {\n      case 'null':\n      case 'undefined':\n        val = '[' + val + ']';\n        break;\n      case 'array':\n      case 'object':\n        val = jsonStringify(val, spaces, depth + 1);\n        break;\n      case 'boolean':\n      case 'regexp':\n      case 'symbol':\n      case 'number':\n        val = val === 0 && (1 / val) === -Infinity // `-0`\n          ? '-0'\n          : val.toString();\n        break;\n      case 'date':\n        var sDate;\n        if (isNaN(val.getTime())) { // Invalid date\n          sDate = val.toString();\n        } else {\n          sDate = val.toISOString ? val.toISOString() : toISOString(val);\n        }\n        val = '[Date: ' + sDate + ']';\n        break;\n      case 'buffer':\n        var json = val.toJSON();\n        // Based on the toJSON result\n        json = json.data && json.type ? json.data : json;\n        val = '[Buffer: ' + jsonStringify(json, 2, depth + 1) + ']';\n        break;\n      default:\n        val = (val === '[Function]' || val === '[Circular]')\n          ? val\n          : JSON.stringify(val); // string\n    }\n    return val;\n  }\n\n  for (var i in object) {\n    if (!Object.prototype.hasOwnProperty.call(object, i)) {\n      continue; // not my business\n    }\n    --length;\n    str += '\\n ' + repeat(' ', space)\n      + (isArray(object) ? '' : '\"' + i + '\": ') // key\n      + _stringify(object[i])                     // value\n      + (length ? ',' : '');                     // comma\n  }\n\n  return str\n    // [], {}\n    + (str.length !== 1 ? '\\n' + repeat(' ', --space) + end : end);\n}\n\n/**\n * Test if a value is a buffer.\n *\n * @api private\n * @param {*} value The value to test.\n * @return {boolean} True if `value` is a buffer, otherwise false\n */\nexports.isBuffer = function(value) {\n  return typeof Buffer !== 'undefined' && Buffer.isBuffer(value);\n};\n\n/**\n * Return a new Thing that has the keys in sorted order. Recursive.\n *\n * If the Thing...\n * - has already been seen, return string `'[Circular]'`\n * - is `undefined`, return string `'[undefined]'`\n * - is `null`, return value `null`\n * - is some other primitive, return the value\n * - is not a primitive or an `Array`, `Object`, or `Function`, return the value of the Thing's `toString()` method\n * - is a non-empty `Array`, `Object`, or `Function`, return the result of calling this function again.\n * - is an empty `Array`, `Object`, or `Function`, return the result of calling `emptyRepresentation()`\n *\n * @api private\n * @see {@link exports.stringify}\n * @param {*} value Thing to inspect.  May or may not have properties.\n * @param {Array} [stack=[]] Stack of seen values\n * @param {string} [typeHint] Type hint\n * @return {(Object|Array|Function|string|undefined)}\n */\nexports.canonicalize = function canonicalize(value, stack, typeHint) {\n  var canonicalizedObj;\n  /* eslint-disable no-unused-vars */\n  var prop;\n  /* eslint-enable no-unused-vars */\n  typeHint = typeHint || type(value);\n  function withStack(value, fn) {\n    stack.push(value);\n    fn();\n    stack.pop();\n  }\n\n  stack = stack || [];\n\n  if (indexOf(stack, value) !== -1) {\n    return '[Circular]';\n  }\n\n  switch (typeHint) {\n    case 'undefined':\n    case 'buffer':\n    case 'null':\n      canonicalizedObj = value;\n      break;\n    case 'array':\n      withStack(value, function() {\n        canonicalizedObj = exports.map(value, function(item) {\n          return exports.canonicalize(item, stack);\n        });\n      });\n      break;\n    case 'function':\n      /* eslint-disable guard-for-in */\n      for (prop in value) {\n        canonicalizedObj = {};\n        break;\n      }\n      /* eslint-enable guard-for-in */\n      if (!canonicalizedObj) {\n        canonicalizedObj = emptyRepresentation(value, typeHint);\n        break;\n      }\n    /* falls through */\n    case 'object':\n      canonicalizedObj = canonicalizedObj || {};\n      withStack(value, function() {\n        exports.forEach(exports.keys(value).sort(), function(key) {\n          canonicalizedObj[key] = exports.canonicalize(value[key], stack);\n        });\n      });\n      break;\n    case 'date':\n    case 'number':\n    case 'regexp':\n    case 'boolean':\n    case 'symbol':\n      canonicalizedObj = value;\n      break;\n    default:\n      canonicalizedObj = value + '';\n  }\n\n  return canonicalizedObj;\n};\n\n/**\n * Lookup file names at the given `path`.\n *\n * @api public\n * @param {string} path Base path to start searching from.\n * @param {string[]} extensions File extensions to look for.\n * @param {boolean} recursive Whether or not to recurse into subdirectories.\n * @return {string[]} An array of paths.\n */\nexports.lookupFiles = function lookupFiles(path, extensions, recursive) {\n  var files = [];\n  var re = new RegExp('\\\\.(' + extensions.join('|') + ')$');\n\n  if (!exists(path)) {\n    if (exists(path + '.js')) {\n      path += '.js';\n    } else {\n      files = glob.sync(path);\n      if (!files.length) {\n        throw new Error(\"cannot resolve path (or pattern) '\" + path + \"'\");\n      }\n      return files;\n    }\n  }\n\n  try {\n    var stat = statSync(path);\n    if (stat.isFile()) {\n      return path;\n    }\n  } catch (err) {\n    // ignore error\n    return;\n  }\n\n  readdirSync(path).forEach(function(file) {\n    file = join(path, file);\n    try {\n      var stat = statSync(file);\n      if (stat.isDirectory()) {\n        if (recursive) {\n          files = files.concat(lookupFiles(file, extensions, recursive));\n        }\n        return;\n      }\n    } catch (err) {\n      // ignore error\n      return;\n    }\n    if (!stat.isFile() || !re.test(file) || basename(file)[0] === '.') {\n      return;\n    }\n    files.push(file);\n  });\n\n  return files;\n};\n\n/**\n * Generate an undefined error with a message warning the user.\n *\n * @return {Error}\n */\n\nexports.undefinedError = function() {\n  return new Error('Caught undefined error, did you throw without specifying what?');\n};\n\n/**\n * Generate an undefined error if `err` is not defined.\n *\n * @param {Error} err\n * @return {Error}\n */\n\nexports.getError = function(err) {\n  return err || exports.undefinedError();\n};\n\n/**\n * @summary\n * This Filter based on `mocha-clean` module.(see: `github.com/rstacruz/mocha-clean`)\n * @description\n * When invoking this function you get a filter function that get the Error.stack as an input,\n * and return a prettify output.\n * (i.e: strip Mocha and internal node functions from stack trace).\n * @returns {Function}\n */\nexports.stackTraceFilter = function() {\n  // TODO: Replace with `process.browser`\n  var is = typeof document === 'undefined' ? { node: true } : { browser: true };\n  var slash = path.sep;\n  var cwd;\n  if (is.node) {\n    cwd = process.cwd() + slash;\n  } else {\n    cwd = (typeof location === 'undefined' ? window.location : location).href.replace(/\\/[^\\/]*$/, '/');\n    slash = '/';\n  }\n\n  function isMochaInternal(line) {\n    return (~line.indexOf('node_modules' + slash + 'mocha' + slash))\n      || (~line.indexOf('node_modules' + slash + 'mocha.js'))\n      || (~line.indexOf('bower_components' + slash + 'mocha.js'))\n      || (~line.indexOf(slash + 'mocha.js'));\n  }\n\n  function isNodeInternal(line) {\n    return (~line.indexOf('(timers.js:'))\n      || (~line.indexOf('(events.js:'))\n      || (~line.indexOf('(node.js:'))\n      || (~line.indexOf('(module.js:'))\n      || (~line.indexOf('GeneratorFunctionPrototype.next (native)'))\n      || false;\n  }\n\n  return function(stack) {\n    stack = stack.split('\\n');\n\n    stack = reduce(stack, function(list, line) {\n      if (isMochaInternal(line)) {\n        return list;\n      }\n\n      if (is.node && isNodeInternal(line)) {\n        return list;\n      }\n\n      // Clean up cwd(absolute)\n      if (/\\(?.+:\\d+:\\d+\\)?$/.test(line)) {\n        line = line.replace(cwd, '');\n      }\n\n      list.push(line);\n      return list;\n    }, []);\n\n    return stack.join('\\n');\n  };\n};\n\n/**\n * Crude, but effective.\n * @api\n * @param {*} value\n * @returns {boolean} Whether or not `value` is a Promise\n */\nexports.isPromise = function isPromise(value) {\n  return typeof value === 'object' && typeof value.then === 'function';\n};\n\n}).call(this,require('_process'),require(\"buffer\").Buffer)\n},{\"./to-iso-string\":37,\"_process\":67,\"buffer\":44,\"debug\":2,\"fs\":42,\"glob\":42,\"json3\":54,\"path\":42,\"util\":84}],39:[function(require,module,exports){\n'use strict'\n\nexports.toByteArray = toByteArray\nexports.fromByteArray = fromByteArray\n\nvar lookup = []\nvar revLookup = []\nvar Arr = typeof Uint8Array !== 'undefined' ? Uint8Array : Array\n\nfunction init () {\n  var code = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'\n  for (var i = 0, len = code.length; i < len; ++i) {\n    lookup[i] = code[i]\n    revLookup[code.charCodeAt(i)] = i\n  }\n\n  revLookup['-'.charCodeAt(0)] = 62\n  revLookup['_'.charCodeAt(0)] = 63\n}\n\ninit()\n\nfunction toByteArray (b64) {\n  var i, j, l, tmp, placeHolders, arr\n  var len = b64.length\n\n  if (len % 4 > 0) {\n    throw new Error('Invalid string. Length must be a multiple of 4')\n  }\n\n  // the number of equal signs (place holders)\n  // if there are two placeholders, than the two characters before it\n  // represent one byte\n  // if there is only one, then the three characters before it represent 2 bytes\n  // this is just a cheap hack to not do indexOf twice\n  placeHolders = b64[len - 2] === '=' ? 2 : b64[len - 1] === '=' ? 1 : 0\n\n  // base64 is 4/3 + up to two characters of the original data\n  arr = new Arr(len * 3 / 4 - placeHolders)\n\n  // if there are placeholders, only get up to the last complete 4 chars\n  l = placeHolders > 0 ? len - 4 : len\n\n  var L = 0\n\n  for (i = 0, j = 0; i < l; i += 4, j += 3) {\n    tmp = (revLookup[b64.charCodeAt(i)] << 18) | (revLookup[b64.charCodeAt(i + 1)] << 12) | (revLookup[b64.charCodeAt(i + 2)] << 6) | revLookup[b64.charCodeAt(i + 3)]\n    arr[L++] = (tmp >> 16) & 0xFF\n    arr[L++] = (tmp >> 8) & 0xFF\n    arr[L++] = tmp & 0xFF\n  }\n\n  if (placeHolders === 2) {\n    tmp = (revLookup[b64.charCodeAt(i)] << 2) | (revLookup[b64.charCodeAt(i + 1)] >> 4)\n    arr[L++] = tmp & 0xFF\n  } else if (placeHolders === 1) {\n    tmp = (revLookup[b64.charCodeAt(i)] << 10) | (revLookup[b64.charCodeAt(i + 1)] << 4) | (revLookup[b64.charCodeAt(i + 2)] >> 2)\n    arr[L++] = (tmp >> 8) & 0xFF\n    arr[L++] = tmp & 0xFF\n  }\n\n  return arr\n}\n\nfunction tripletToBase64 (num) {\n  return lookup[num >> 18 & 0x3F] + lookup[num >> 12 & 0x3F] + lookup[num >> 6 & 0x3F] + lookup[num & 0x3F]\n}\n\nfunction encodeChunk (uint8, start, end) {\n  var tmp\n  var output = []\n  for (var i = start; i < end; i += 3) {\n    tmp = (uint8[i] << 16) + (uint8[i + 1] << 8) + (uint8[i + 2])\n    output.push(tripletToBase64(tmp))\n  }\n  return output.join('')\n}\n\nfunction fromByteArray (uint8) {\n  var tmp\n  var len = uint8.length\n  var extraBytes = len % 3 // if we have 1 byte left, pad 2 bytes\n  var output = ''\n  var parts = []\n  var maxChunkLength = 16383 // must be multiple of 3\n\n  // go through the array every three bytes, we'll deal with trailing stuff later\n  for (var i = 0, len2 = len - extraBytes; i < len2; i += maxChunkLength) {\n    parts.push(encodeChunk(uint8, i, (i + maxChunkLength) > len2 ? len2 : (i + maxChunkLength)))\n  }\n\n  // pad the end with zeros, but make sure to not forget the extra bytes\n  if (extraBytes === 1) {\n    tmp = uint8[len - 1]\n    output += lookup[tmp >> 2]\n    output += lookup[(tmp << 4) & 0x3F]\n    output += '=='\n  } else if (extraBytes === 2) {\n    tmp = (uint8[len - 2] << 8) + (uint8[len - 1])\n    output += lookup[tmp >> 10]\n    output += lookup[(tmp >> 4) & 0x3F]\n    output += lookup[(tmp << 2) & 0x3F]\n    output += '='\n  }\n\n  parts.push(output)\n\n  return parts.join('')\n}\n\n},{}],40:[function(require,module,exports){\n\n},{}],41:[function(require,module,exports){\n(function (process){\nvar WritableStream = require('stream').Writable\nvar inherits = require('util').inherits\n\nmodule.exports = BrowserStdout\n\n\ninherits(BrowserStdout, WritableStream)\n\nfunction BrowserStdout(opts) {\n  if (!(this instanceof BrowserStdout)) return new BrowserStdout(opts)\n\n  opts = opts || {}\n  WritableStream.call(this, opts)\n  this.label = (opts.label !== undefined) ? opts.label : 'stdout'\n}\n\nBrowserStdout.prototype._write = function(chunks, encoding, cb) {\n  var output = chunks.toString ? chunks.toString() : chunks\n  if (this.label === false) {\n    console.log(output)\n  } else {\n    console.log(this.label+':', output)\n  }\n  process.nextTick(cb)\n}\n\n}).call(this,require('_process'))\n},{\"_process\":67,\"stream\":79,\"util\":84}],42:[function(require,module,exports){\narguments[4][40][0].apply(exports,arguments)\n},{\"dup\":40}],43:[function(require,module,exports){\n(function (global){\n'use strict';\n\nvar buffer = require('buffer');\nvar Buffer = buffer.Buffer;\nvar SlowBuffer = buffer.SlowBuffer;\nvar MAX_LEN = buffer.kMaxLength || 2147483647;\nexports.alloc = function alloc(size, fill, encoding) {\n  if (typeof Buffer.alloc === 'function') {\n    return Buffer.alloc(size, fill, encoding);\n  }\n  if (typeof encoding === 'number') {\n    throw new TypeError('encoding must not be number');\n  }\n  if (typeof size !== 'number') {\n    throw new TypeError('size must be a number');\n  }\n  if (size > MAX_LEN) {\n    throw new RangeError('size is too large');\n  }\n  var enc = encoding;\n  var _fill = fill;\n  if (_fill === undefined) {\n    enc = undefined;\n    _fill = 0;\n  }\n  var buf = new Buffer(size);\n  if (typeof _fill === 'string') {\n    var fillBuf = new Buffer(_fill, enc);\n    var flen = fillBuf.length;\n    var i = -1;\n    while (++i < size) {\n      buf[i] = fillBuf[i % flen];\n    }\n  } else {\n    buf.fill(_fill);\n  }\n  return buf;\n}\nexports.allocUnsafe = function allocUnsafe(size) {\n  if (typeof Buffer.allocUnsafe === 'function') {\n    return Buffer.allocUnsafe(size);\n  }\n  if (typeof size !== 'number') {\n    throw new TypeError('size must be a number');\n  }\n  if (size > MAX_LEN) {\n    throw new RangeError('size is too large');\n  }\n  return new Buffer(size);\n}\nexports.from = function from(value, encodingOrOffset, length) {\n  if (typeof Buffer.from === 'function' && (!global.Uint8Array || Uint8Array.from !== Buffer.from)) {\n    return Buffer.from(value, encodingOrOffset, length);\n  }\n  if (typeof value === 'number') {\n    throw new TypeError('\"value\" argument must not be a number');\n  }\n  if (typeof value === 'string') {\n    return new Buffer(value, encodingOrOffset);\n  }\n  if (typeof ArrayBuffer !== 'undefined' && value instanceof ArrayBuffer) {\n    var offset = encodingOrOffset;\n    if (arguments.length === 1) {\n      return new Buffer(value);\n    }\n    if (typeof offset === 'undefined') {\n      offset = 0;\n    }\n    var len = length;\n    if (typeof len === 'undefined') {\n      len = value.byteLength - offset;\n    }\n    if (offset >= value.byteLength) {\n      throw new RangeError('\\'offset\\' is out of bounds');\n    }\n    if (len > value.byteLength - offset) {\n      throw new RangeError('\\'length\\' is out of bounds');\n    }\n    return new Buffer(value.slice(offset, offset + len));\n  }\n  if (Buffer.isBuffer(value)) {\n    var out = new Buffer(value.length);\n    value.copy(out, 0, 0, value.length);\n    return out;\n  }\n  if (value) {\n    if (Array.isArray(value) || (typeof ArrayBuffer !== 'undefined' && value.buffer instanceof ArrayBuffer) || 'length' in value) {\n      return new Buffer(value);\n    }\n    if (value.type === 'Buffer' && Array.isArray(value.data)) {\n      return new Buffer(value.data);\n    }\n  }\n\n  throw new TypeError('First argument must be a string, Buffer, ' + 'ArrayBuffer, Array, or array-like object.');\n}\nexports.allocUnsafeSlow = function allocUnsafeSlow(size) {\n  if (typeof Buffer.allocUnsafeSlow === 'function') {\n    return Buffer.allocUnsafeSlow(size);\n  }\n  if (typeof size !== 'number') {\n    throw new TypeError('size must be a number');\n  }\n  if (size >= MAX_LEN) {\n    throw new RangeError('size is too large');\n  }\n  return new SlowBuffer(size);\n}\n\n}).call(this,typeof global !== \"undefined\" ? global : typeof self !== \"undefined\" ? self : typeof window !== \"undefined\" ? window : {})\n},{\"buffer\":44}],44:[function(require,module,exports){\n(function (global){\n/*!\n * The buffer module from node.js, for the browser.\n *\n * @author   Feross Aboukhadijeh <feross@feross.org> <http://feross.org>\n * @license  MIT\n */\n/* eslint-disable no-proto */\n\n'use strict'\n\nvar base64 = require('base64-js')\nvar ieee754 = require('ieee754')\nvar isArray = require('isarray')\n\nexports.Buffer = Buffer\nexports.SlowBuffer = SlowBuffer\nexports.INSPECT_MAX_BYTES = 50\n\n/**\n * If `Buffer.TYPED_ARRAY_SUPPORT`:\n *   === true    Use Uint8Array implementation (fastest)\n *   === false   Use Object implementation (most compatible, even IE6)\n *\n * Browsers that support typed arrays are IE 10+, Firefox 4+, Chrome 7+, Safari 5.1+,\n * Opera 11.6+, iOS 4.2+.\n *\n * Due to various browser bugs, sometimes the Object implementation will be used even\n * when the browser supports typed arrays.\n *\n * Note:\n *\n *   - Firefox 4-29 lacks support for adding new properties to `Uint8Array` instances,\n *     See: https://bugzilla.mozilla.org/show_bug.cgi?id=695438.\n *\n *   - Chrome 9-10 is missing the `TypedArray.prototype.subarray` function.\n *\n *   - IE10 has a broken `TypedArray.prototype.subarray` function which returns arrays of\n *     incorrect length in some situations.\n\n * We detect these buggy browsers and set `Buffer.TYPED_ARRAY_SUPPORT` to `false` so they\n * get the Object implementation, which is slower but behaves correctly.\n */\nBuffer.TYPED_ARRAY_SUPPORT = global.TYPED_ARRAY_SUPPORT !== undefined\n  ? global.TYPED_ARRAY_SUPPORT\n  : typedArraySupport()\n\n/*\n * Export kMaxLength after typed array support is determined.\n */\nexports.kMaxLength = kMaxLength()\n\nfunction typedArraySupport () {\n  try {\n    var arr = new Uint8Array(1)\n    arr.__proto__ = {__proto__: Uint8Array.prototype, foo: function () { return 42 }}\n    return arr.foo() === 42 && // typed array instances can be augmented\n        typeof arr.subarray === 'function' && // chrome 9-10 lack `subarray`\n        arr.subarray(1, 1).byteLength === 0 // ie10 has broken `subarray`\n  } catch (e) {\n    return false\n  }\n}\n\nfunction kMaxLength () {\n  return Buffer.TYPED_ARRAY_SUPPORT\n    ? 0x7fffffff\n    : 0x3fffffff\n}\n\nfunction createBuffer (that, length) {\n  if (kMaxLength() < length) {\n    throw new RangeError('Invalid typed array length')\n  }\n  if (Buffer.TYPED_ARRAY_SUPPORT) {\n    // Return an augmented `Uint8Array` instance, for best performance\n    that = new Uint8Array(length)\n    that.__proto__ = Buffer.prototype\n  } else {\n    // Fallback: Return an object instance of the Buffer class\n    if (that === null) {\n      that = new Buffer(length)\n    }\n    that.length = length\n  }\n\n  return that\n}\n\n/**\n * The Buffer constructor returns instances of `Uint8Array` that have their\n * prototype changed to `Buffer.prototype`. Furthermore, `Buffer` is a subclass of\n * `Uint8Array`, so the returned instances will have all the node `Buffer` methods\n * and the `Uint8Array` methods. Square bracket notation works as expected -- it\n * returns a single octet.\n *\n * The `Uint8Array` prototype remains unmodified.\n */\n\nfunction Buffer (arg, encodingOrOffset, length) {\n  if (!Buffer.TYPED_ARRAY_SUPPORT && !(this instanceof Buffer)) {\n    return new Buffer(arg, encodingOrOffset, length)\n  }\n\n  // Common case.\n  if (typeof arg === 'number') {\n    if (typeof encodingOrOffset === 'string') {\n      throw new Error(\n        'If encoding is specified then the first argument must be a string'\n      )\n    }\n    return allocUnsafe(this, arg)\n  }\n  return from(this, arg, encodingOrOffset, length)\n}\n\nBuffer.poolSize = 8192 // not used by this implementation\n\n// TODO: Legacy, not needed anymore. Remove in next major version.\nBuffer._augment = function (arr) {\n  arr.__proto__ = Buffer.prototype\n  return arr\n}\n\nfunction from (that, value, encodingOrOffset, length) {\n  if (typeof value === 'number') {\n    throw new TypeError('\"value\" argument must not be a number')\n  }\n\n  if (typeof ArrayBuffer !== 'undefined' && value instanceof ArrayBuffer) {\n    return fromArrayBuffer(that, value, encodingOrOffset, length)\n  }\n\n  if (typeof value === 'string') {\n    return fromString(that, value, encodingOrOffset)\n  }\n\n  return fromObject(that, value)\n}\n\n/**\n * Functionally equivalent to Buffer(arg, encoding) but throws a TypeError\n * if value is a number.\n * Buffer.from(str[, encoding])\n * Buffer.from(array)\n * Buffer.from(buffer)\n * Buffer.from(arrayBuffer[, byteOffset[, length]])\n **/\nBuffer.from = function (value, encodingOrOffset, length) {\n  return from(null, value, encodingOrOffset, length)\n}\n\nif (Buffer.TYPED_ARRAY_SUPPORT) {\n  Buffer.prototype.__proto__ = Uint8Array.prototype\n  Buffer.__proto__ = Uint8Array\n  if (typeof Symbol !== 'undefined' && Symbol.species &&\n      Buffer[Symbol.species] === Buffer) {\n    // Fix subarray() in ES2016. See: https://github.com/feross/buffer/pull/97\n    Object.defineProperty(Buffer, Symbol.species, {\n      value: null,\n      configurable: true\n    })\n  }\n}\n\nfunction assertSize (size) {\n  if (typeof size !== 'number') {\n    throw new TypeError('\"size\" argument must be a number')\n  } else if (size < 0) {\n    throw new RangeError('\"size\" argument must not be negative')\n  }\n}\n\nfunction alloc (that, size, fill, encoding) {\n  assertSize(size)\n  if (size <= 0) {\n    return createBuffer(that, size)\n  }\n  if (fill !== undefined) {\n    // Only pay attention to encoding if it's a string. This\n    // prevents accidentally sending in a number that would\n    // be interpretted as a start offset.\n    return typeof encoding === 'string'\n      ? createBuffer(that, size).fill(fill, encoding)\n      : createBuffer(that, size).fill(fill)\n  }\n  return createBuffer(that, size)\n}\n\n/**\n * Creates a new filled Buffer instance.\n * alloc(size[, fill[, encoding]])\n **/\nBuffer.alloc = function (size, fill, encoding) {\n  return alloc(null, size, fill, encoding)\n}\n\nfunction allocUnsafe (that, size) {\n  assertSize(size)\n  that = createBuffer(that, size < 0 ? 0 : checked(size) | 0)\n  if (!Buffer.TYPED_ARRAY_SUPPORT) {\n    for (var i = 0; i < size; ++i) {\n      that[i] = 0\n    }\n  }\n  return that\n}\n\n/**\n * Equivalent to Buffer(num), by default creates a non-zero-filled Buffer instance.\n * */\nBuffer.allocUnsafe = function (size) {\n  return allocUnsafe(null, size)\n}\n/**\n * Equivalent to SlowBuffer(num), by default creates a non-zero-filled Buffer instance.\n */\nBuffer.allocUnsafeSlow = function (size) {\n  return allocUnsafe(null, size)\n}\n\nfunction fromString (that, string, encoding) {\n  if (typeof encoding !== 'string' || encoding === '') {\n    encoding = 'utf8'\n  }\n\n  if (!Buffer.isEncoding(encoding)) {\n    throw new TypeError('\"encoding\" must be a valid string encoding')\n  }\n\n  var length = byteLength(string, encoding) | 0\n  that = createBuffer(that, length)\n\n  var actual = that.write(string, encoding)\n\n  if (actual !== length) {\n    // Writing a hex string, for example, that contains invalid characters will\n    // cause everything after the first invalid character to be ignored. (e.g.\n    // 'abxxcd' will be treated as 'ab')\n    that = that.slice(0, actual)\n  }\n\n  return that\n}\n\nfunction fromArrayLike (that, array) {\n  var length = array.length < 0 ? 0 : checked(array.length) | 0\n  that = createBuffer(that, length)\n  for (var i = 0; i < length; i += 1) {\n    that[i] = array[i] & 255\n  }\n  return that\n}\n\nfunction fromArrayBuffer (that, array, byteOffset, length) {\n  array.byteLength // this throws if `array` is not a valid ArrayBuffer\n\n  if (byteOffset < 0 || array.byteLength < byteOffset) {\n    throw new RangeError('\\'offset\\' is out of bounds')\n  }\n\n  if (array.byteLength < byteOffset + (length || 0)) {\n    throw new RangeError('\\'length\\' is out of bounds')\n  }\n\n  if (byteOffset === undefined && length === undefined) {\n    array = new Uint8Array(array)\n  } else if (length === undefined) {\n    array = new Uint8Array(array, byteOffset)\n  } else {\n    array = new Uint8Array(array, byteOffset, length)\n  }\n\n  if (Buffer.TYPED_ARRAY_SUPPORT) {\n    // Return an augmented `Uint8Array` instance, for best performance\n    that = array\n    that.__proto__ = Buffer.prototype\n  } else {\n    // Fallback: Return an object instance of the Buffer class\n    that = fromArrayLike(that, array)\n  }\n  return that\n}\n\nfunction fromObject (that, obj) {\n  if (Buffer.isBuffer(obj)) {\n    var len = checked(obj.length) | 0\n    that = createBuffer(that, len)\n\n    if (that.length === 0) {\n      return that\n    }\n\n    obj.copy(that, 0, 0, len)\n    return that\n  }\n\n  if (obj) {\n    if ((typeof ArrayBuffer !== 'undefined' &&\n        obj.buffer instanceof ArrayBuffer) || 'length' in obj) {\n      if (typeof obj.length !== 'number' || isnan(obj.length)) {\n        return createBuffer(that, 0)\n      }\n      return fromArrayLike(that, obj)\n    }\n\n    if (obj.type === 'Buffer' && isArray(obj.data)) {\n      return fromArrayLike(that, obj.data)\n    }\n  }\n\n  throw new TypeError('First argument must be a string, Buffer, ArrayBuffer, Array, or array-like object.')\n}\n\nfunction checked (length) {\n  // Note: cannot use `length < kMaxLength()` here because that fails when\n  // length is NaN (which is otherwise coerced to zero.)\n  if (length >= kMaxLength()) {\n    throw new RangeError('Attempt to allocate Buffer larger than maximum ' +\n                         'size: 0x' + kMaxLength().toString(16) + ' bytes')\n  }\n  return length | 0\n}\n\nfunction SlowBuffer (length) {\n  if (+length != length) { // eslint-disable-line eqeqeq\n    length = 0\n  }\n  return Buffer.alloc(+length)\n}\n\nBuffer.isBuffer = function isBuffer (b) {\n  return !!(b != null && b._isBuffer)\n}\n\nBuffer.compare = function compare (a, b) {\n  if (!Buffer.isBuffer(a) || !Buffer.isBuffer(b)) {\n    throw new TypeError('Arguments must be Buffers')\n  }\n\n  if (a === b) return 0\n\n  var x = a.length\n  var y = b.length\n\n  for (var i = 0, len = Math.min(x, y); i < len; ++i) {\n    if (a[i] !== b[i]) {\n      x = a[i]\n      y = b[i]\n      break\n    }\n  }\n\n  if (x < y) return -1\n  if (y < x) return 1\n  return 0\n}\n\nBuffer.isEncoding = function isEncoding (encoding) {\n  switch (String(encoding).toLowerCase()) {\n    case 'hex':\n    case 'utf8':\n    case 'utf-8':\n    case 'ascii':\n    case 'latin1':\n    case 'binary':\n    case 'base64':\n    case 'ucs2':\n    case 'ucs-2':\n    case 'utf16le':\n    case 'utf-16le':\n      return true\n    default:\n      return false\n  }\n}\n\nBuffer.concat = function concat (list, length) {\n  if (!isArray(list)) {\n    throw new TypeError('\"list\" argument must be an Array of Buffers')\n  }\n\n  if (list.length === 0) {\n    return Buffer.alloc(0)\n  }\n\n  var i\n  if (length === undefined) {\n    length = 0\n    for (i = 0; i < list.length; ++i) {\n      length += list[i].length\n    }\n  }\n\n  var buffer = Buffer.allocUnsafe(length)\n  var pos = 0\n  for (i = 0; i < list.length; ++i) {\n    var buf = list[i]\n    if (!Buffer.isBuffer(buf)) {\n      throw new TypeError('\"list\" argument must be an Array of Buffers')\n    }\n    buf.copy(buffer, pos)\n    pos += buf.length\n  }\n  return buffer\n}\n\nfunction byteLength (string, encoding) {\n  if (Buffer.isBuffer(string)) {\n    return string.length\n  }\n  if (typeof ArrayBuffer !== 'undefined' && typeof ArrayBuffer.isView === 'function' &&\n      (ArrayBuffer.isView(string) || string instanceof ArrayBuffer)) {\n    return string.byteLength\n  }\n  if (typeof string !== 'string') {\n    string = '' + string\n  }\n\n  var len = string.length\n  if (len === 0) return 0\n\n  // Use a for loop to avoid recursion\n  var loweredCase = false\n  for (;;) {\n    switch (encoding) {\n      case 'ascii':\n      case 'latin1':\n      case 'binary':\n        return len\n      case 'utf8':\n      case 'utf-8':\n      case undefined:\n        return utf8ToBytes(string).length\n      case 'ucs2':\n      case 'ucs-2':\n      case 'utf16le':\n      case 'utf-16le':\n        return len * 2\n      case 'hex':\n        return len >>> 1\n      case 'base64':\n        return base64ToBytes(string).length\n      default:\n        if (loweredCase) return utf8ToBytes(string).length // assume utf8\n        encoding = ('' + encoding).toLowerCase()\n        loweredCase = true\n    }\n  }\n}\nBuffer.byteLength = byteLength\n\nfunction slowToString (encoding, start, end) {\n  var loweredCase = false\n\n  // No need to verify that \"this.length <= MAX_UINT32\" since it's a read-only\n  // property of a typed array.\n\n  // This behaves neither like String nor Uint8Array in that we set start/end\n  // to their upper/lower bounds if the value passed is out of range.\n  // undefined is handled specially as per ECMA-262 6th Edition,\n  // Section 13.3.3.7 Runtime Semantics: KeyedBindingInitialization.\n  if (start === undefined || start < 0) {\n    start = 0\n  }\n  // Return early if start > this.length. Done here to prevent potential uint32\n  // coercion fail below.\n  if (start > this.length) {\n    return ''\n  }\n\n  if (end === undefined || end > this.length) {\n    end = this.length\n  }\n\n  if (end <= 0) {\n    return ''\n  }\n\n  // Force coersion to uint32. This will also coerce falsey/NaN values to 0.\n  end >>>= 0\n  start >>>= 0\n\n  if (end <= start) {\n    return ''\n  }\n\n  if (!encoding) encoding = 'utf8'\n\n  while (true) {\n    switch (encoding) {\n      case 'hex':\n        return hexSlice(this, start, end)\n\n      case 'utf8':\n      case 'utf-8':\n        return utf8Slice(this, start, end)\n\n      case 'ascii':\n        return asciiSlice(this, start, end)\n\n      case 'latin1':\n      case 'binary':\n        return latin1Slice(this, start, end)\n\n      case 'base64':\n        return base64Slice(this, start, end)\n\n      case 'ucs2':\n      case 'ucs-2':\n      case 'utf16le':\n      case 'utf-16le':\n        return utf16leSlice(this, start, end)\n\n      default:\n        if (loweredCase) throw new TypeError('Unknown encoding: ' + encoding)\n        encoding = (encoding + '').toLowerCase()\n        loweredCase = true\n    }\n  }\n}\n\n// The property is used by `Buffer.isBuffer` and `is-buffer` (in Safari 5-7) to detect\n// Buffer instances.\nBuffer.prototype._isBuffer = true\n\nfunction swap (b, n, m) {\n  var i = b[n]\n  b[n] = b[m]\n  b[m] = i\n}\n\nBuffer.prototype.swap16 = function swap16 () {\n  var len = this.length\n  if (len % 2 !== 0) {\n    throw new RangeError('Buffer size must be a multiple of 16-bits')\n  }\n  for (var i = 0; i < len; i += 2) {\n    swap(this, i, i + 1)\n  }\n  return this\n}\n\nBuffer.prototype.swap32 = function swap32 () {\n  var len = this.length\n  if (len % 4 !== 0) {\n    throw new RangeError('Buffer size must be a multiple of 32-bits')\n  }\n  for (var i = 0; i < len; i += 4) {\n    swap(this, i, i + 3)\n    swap(this, i + 1, i + 2)\n  }\n  return this\n}\n\nBuffer.prototype.swap64 = function swap64 () {\n  var len = this.length\n  if (len % 8 !== 0) {\n    throw new RangeError('Buffer size must be a multiple of 64-bits')\n  }\n  for (var i = 0; i < len; i += 8) {\n    swap(this, i, i + 7)\n    swap(this, i + 1, i + 6)\n    swap(this, i + 2, i + 5)\n    swap(this, i + 3, i + 4)\n  }\n  return this\n}\n\nBuffer.prototype.toString = function toString () {\n  var length = this.length | 0\n  if (length === 0) return ''\n  if (arguments.length === 0) return utf8Slice(this, 0, length)\n  return slowToString.apply(this, arguments)\n}\n\nBuffer.prototype.equals = function equals (b) {\n  if (!Buffer.isBuffer(b)) throw new TypeError('Argument must be a Buffer')\n  if (this === b) return true\n  return Buffer.compare(this, b) === 0\n}\n\nBuffer.prototype.inspect = function inspect () {\n  var str = ''\n  var max = exports.INSPECT_MAX_BYTES\n  if (this.length > 0) {\n    str = this.toString('hex', 0, max).match(/.{2}/g).join(' ')\n    if (this.length > max) str += ' ... '\n  }\n  return '<Buffer ' + str + '>'\n}\n\nBuffer.prototype.compare = function compare (target, start, end, thisStart, thisEnd) {\n  if (!Buffer.isBuffer(target)) {\n    throw new TypeError('Argument must be a Buffer')\n  }\n\n  if (start === undefined) {\n    start = 0\n  }\n  if (end === undefined) {\n    end = target ? target.length : 0\n  }\n  if (thisStart === undefined) {\n    thisStart = 0\n  }\n  if (thisEnd === undefined) {\n    thisEnd = this.length\n  }\n\n  if (start < 0 || end > target.length || thisStart < 0 || thisEnd > this.length) {\n    throw new RangeError('out of range index')\n  }\n\n  if (thisStart >= thisEnd && start >= end) {\n    return 0\n  }\n  if (thisStart >= thisEnd) {\n    return -1\n  }\n  if (start >= end) {\n    return 1\n  }\n\n  start >>>= 0\n  end >>>= 0\n  thisStart >>>= 0\n  thisEnd >>>= 0\n\n  if (this === target) return 0\n\n  var x = thisEnd - thisStart\n  var y = end - start\n  var len = Math.min(x, y)\n\n  var thisCopy = this.slice(thisStart, thisEnd)\n  var targetCopy = target.slice(start, end)\n\n  for (var i = 0; i < len; ++i) {\n    if (thisCopy[i] !== targetCopy[i]) {\n      x = thisCopy[i]\n      y = targetCopy[i]\n      break\n    }\n  }\n\n  if (x < y) return -1\n  if (y < x) return 1\n  return 0\n}\n\n// Finds either the first index of `val` in `buffer` at offset >= `byteOffset`,\n// OR the last index of `val` in `buffer` at offset <= `byteOffset`.\n//\n// Arguments:\n// - buffer - a Buffer to search\n// - val - a string, Buffer, or number\n// - byteOffset - an index into `buffer`; will be clamped to an int32\n// - encoding - an optional encoding, relevant is val is a string\n// - dir - true for indexOf, false for lastIndexOf\nfunction bidirectionalIndexOf (buffer, val, byteOffset, encoding, dir) {\n  // Empty buffer means no match\n  if (buffer.length === 0) return -1\n\n  // Normalize byteOffset\n  if (typeof byteOffset === 'string') {\n    encoding = byteOffset\n    byteOffset = 0\n  } else if (byteOffset > 0x7fffffff) {\n    byteOffset = 0x7fffffff\n  } else if (byteOffset < -0x80000000) {\n    byteOffset = -0x80000000\n  }\n  byteOffset = +byteOffset  // Coerce to Number.\n  if (isNaN(byteOffset)) {\n    // byteOffset: it it's undefined, null, NaN, \"foo\", etc, search whole buffer\n    byteOffset = dir ? 0 : (buffer.length - 1)\n  }\n\n  // Normalize byteOffset: negative offsets start from the end of the buffer\n  if (byteOffset < 0) byteOffset = buffer.length + byteOffset\n  if (byteOffset >= buffer.length) {\n    if (dir) return -1\n    else byteOffset = buffer.length - 1\n  } else if (byteOffset < 0) {\n    if (dir) byteOffset = 0\n    else return -1\n  }\n\n  // Normalize val\n  if (typeof val === 'string') {\n    val = Buffer.from(val, encoding)\n  }\n\n  // Finally, search either indexOf (if dir is true) or lastIndexOf\n  if (Buffer.isBuffer(val)) {\n    // Special case: looking for empty string/buffer always fails\n    if (val.length === 0) {\n      return -1\n    }\n    return arrayIndexOf(buffer, val, byteOffset, encoding, dir)\n  } else if (typeof val === 'number') {\n    val = val & 0xFF // Search for a byte value [0-255]\n    if (Buffer.TYPED_ARRAY_SUPPORT &&\n        typeof Uint8Array.prototype.indexOf === 'function') {\n      if (dir) {\n        return Uint8Array.prototype.indexOf.call(buffer, val, byteOffset)\n      } else {\n        return Uint8Array.prototype.lastIndexOf.call(buffer, val, byteOffset)\n      }\n    }\n    return arrayIndexOf(buffer, [ val ], byteOffset, encoding, dir)\n  }\n\n  throw new TypeError('val must be string, number or Buffer')\n}\n\nfunction arrayIndexOf (arr, val, byteOffset, encoding, dir) {\n  var indexSize = 1\n  var arrLength = arr.length\n  var valLength = val.length\n\n  if (encoding !== undefined) {\n    encoding = String(encoding).toLowerCase()\n    if (encoding === 'ucs2' || encoding === 'ucs-2' ||\n        encoding === 'utf16le' || encoding === 'utf-16le') {\n      if (arr.length < 2 || val.length < 2) {\n        return -1\n      }\n      indexSize = 2\n      arrLength /= 2\n      valLength /= 2\n      byteOffset /= 2\n    }\n  }\n\n  function read (buf, i) {\n    if (indexSize === 1) {\n      return buf[i]\n    } else {\n      return buf.readUInt16BE(i * indexSize)\n    }\n  }\n\n  var i\n  if (dir) {\n    var foundIndex = -1\n    for (i = byteOffset; i < arrLength; i++) {\n      if (read(arr, i) === read(val, foundIndex === -1 ? 0 : i - foundIndex)) {\n        if (foundIndex === -1) foundIndex = i\n        if (i - foundIndex + 1 === valLength) return foundIndex * indexSize\n      } else {\n        if (foundIndex !== -1) i -= i - foundIndex\n        foundIndex = -1\n      }\n    }\n  } else {\n    if (byteOffset + valLength > arrLength) byteOffset = arrLength - valLength\n    for (i = byteOffset; i >= 0; i--) {\n      var found = true\n      for (var j = 0; j < valLength; j++) {\n        if (read(arr, i + j) !== read(val, j)) {\n          found = false\n          break\n        }\n      }\n      if (found) return i\n    }\n  }\n\n  return -1\n}\n\nBuffer.prototype.includes = function includes (val, byteOffset, encoding) {\n  return this.indexOf(val, byteOffset, encoding) !== -1\n}\n\nBuffer.prototype.indexOf = function indexOf (val, byteOffset, encoding) {\n  return bidirectionalIndexOf(this, val, byteOffset, encoding, true)\n}\n\nBuffer.prototype.lastIndexOf = function lastIndexOf (val, byteOffset, encoding) {\n  return bidirectionalIndexOf(this, val, byteOffset, encoding, false)\n}\n\nfunction hexWrite (buf, string, offset, length) {\n  offset = Number(offset) || 0\n  var remaining = buf.length - offset\n  if (!length) {\n    length = remaining\n  } else {\n    length = Number(length)\n    if (length > remaining) {\n      length = remaining\n    }\n  }\n\n  // must be an even number of digits\n  var strLen = string.length\n  if (strLen % 2 !== 0) throw new TypeError('Invalid hex string')\n\n  if (length > strLen / 2) {\n    length = strLen / 2\n  }\n  for (var i = 0; i < length; ++i) {\n    var parsed = parseInt(string.substr(i * 2, 2), 16)\n    if (isNaN(parsed)) return i\n    buf[offset + i] = parsed\n  }\n  return i\n}\n\nfunction utf8Write (buf, string, offset, length) {\n  return blitBuffer(utf8ToBytes(string, buf.length - offset), buf, offset, length)\n}\n\nfunction asciiWrite (buf, string, offset, length) {\n  return blitBuffer(asciiToBytes(string), buf, offset, length)\n}\n\nfunction latin1Write (buf, string, offset, length) {\n  return asciiWrite(buf, string, offset, length)\n}\n\nfunction base64Write (buf, string, offset, length) {\n  return blitBuffer(base64ToBytes(string), buf, offset, length)\n}\n\nfunction ucs2Write (buf, string, offset, length) {\n  return blitBuffer(utf16leToBytes(string, buf.length - offset), buf, offset, length)\n}\n\nBuffer.prototype.write = function write (string, offset, length, encoding) {\n  // Buffer#write(string)\n  if (offset === undefined) {\n    encoding = 'utf8'\n    length = this.length\n    offset = 0\n  // Buffer#write(string, encoding)\n  } else if (length === undefined && typeof offset === 'string') {\n    encoding = offset\n    length = this.length\n    offset = 0\n  // Buffer#write(string, offset[, length][, encoding])\n  } else if (isFinite(offset)) {\n    offset = offset | 0\n    if (isFinite(length)) {\n      length = length | 0\n      if (encoding === undefined) encoding = 'utf8'\n    } else {\n      encoding = length\n      length = undefined\n    }\n  // legacy write(string, encoding, offset, length) - remove in v0.13\n  } else {\n    throw new Error(\n      'Buffer.write(string, encoding, offset[, length]) is no longer supported'\n    )\n  }\n\n  var remaining = this.length - offset\n  if (length === undefined || length > remaining) length = remaining\n\n  if ((string.length > 0 && (length < 0 || offset < 0)) || offset > this.length) {\n    throw new RangeError('Attempt to write outside buffer bounds')\n  }\n\n  if (!encoding) encoding = 'utf8'\n\n  var loweredCase = false\n  for (;;) {\n    switch (encoding) {\n      case 'hex':\n        return hexWrite(this, string, offset, length)\n\n      case 'utf8':\n      case 'utf-8':\n        return utf8Write(this, string, offset, length)\n\n      case 'ascii':\n        return asciiWrite(this, string, offset, length)\n\n      case 'latin1':\n      case 'binary':\n        return latin1Write(this, string, offset, length)\n\n      case 'base64':\n        // Warning: maxLength not taken into account in base64Write\n        return base64Write(this, string, offset, length)\n\n      case 'ucs2':\n      case 'ucs-2':\n      case 'utf16le':\n      case 'utf-16le':\n        return ucs2Write(this, string, offset, length)\n\n      default:\n        if (loweredCase) throw new TypeError('Unknown encoding: ' + encoding)\n        encoding = ('' + encoding).toLowerCase()\n        loweredCase = true\n    }\n  }\n}\n\nBuffer.prototype.toJSON = function toJSON () {\n  return {\n    type: 'Buffer',\n    data: Array.prototype.slice.call(this._arr || this, 0)\n  }\n}\n\nfunction base64Slice (buf, start, end) {\n  if (start === 0 && end === buf.length) {\n    return base64.fromByteArray(buf)\n  } else {\n    return base64.fromByteArray(buf.slice(start, end))\n  }\n}\n\nfunction utf8Slice (buf, start, end) {\n  end = Math.min(buf.length, end)\n  var res = []\n\n  var i = start\n  while (i < end) {\n    var firstByte = buf[i]\n    var codePoint = null\n    var bytesPerSequence = (firstByte > 0xEF) ? 4\n      : (firstByte > 0xDF) ? 3\n      : (firstByte > 0xBF) ? 2\n      : 1\n\n    if (i + bytesPerSequence <= end) {\n      var secondByte, thirdByte, fourthByte, tempCodePoint\n\n      switch (bytesPerSequence) {\n        case 1:\n          if (firstByte < 0x80) {\n            codePoint = firstByte\n          }\n          break\n        case 2:\n          secondByte = buf[i + 1]\n          if ((secondByte & 0xC0) === 0x80) {\n            tempCodePoint = (firstByte & 0x1F) << 0x6 | (secondByte & 0x3F)\n            if (tempCodePoint > 0x7F) {\n              codePoint = tempCodePoint\n            }\n          }\n          break\n        case 3:\n          secondByte = buf[i + 1]\n          thirdByte = buf[i + 2]\n          if ((secondByte & 0xC0) === 0x80 && (thirdByte & 0xC0) === 0x80) {\n            tempCodePoint = (firstByte & 0xF) << 0xC | (secondByte & 0x3F) << 0x6 | (thirdByte & 0x3F)\n            if (tempCodePoint > 0x7FF && (tempCodePoint < 0xD800 || tempCodePoint > 0xDFFF)) {\n              codePoint = tempCodePoint\n            }\n          }\n          break\n        case 4:\n          secondByte = buf[i + 1]\n          thirdByte = buf[i + 2]\n          fourthByte = buf[i + 3]\n          if ((secondByte & 0xC0) === 0x80 && (thirdByte & 0xC0) === 0x80 && (fourthByte & 0xC0) === 0x80) {\n            tempCodePoint = (firstByte & 0xF) << 0x12 | (secondByte & 0x3F) << 0xC | (thirdByte & 0x3F) << 0x6 | (fourthByte & 0x3F)\n            if (tempCodePoint > 0xFFFF && tempCodePoint < 0x110000) {\n              codePoint = tempCodePoint\n            }\n          }\n      }\n    }\n\n    if (codePoint === null) {\n      // we did not generate a valid codePoint so insert a\n      // replacement char (U+FFFD) and advance only 1 byte\n      codePoint = 0xFFFD\n      bytesPerSequence = 1\n    } else if (codePoint > 0xFFFF) {\n      // encode to utf16 (surrogate pair dance)\n      codePoint -= 0x10000\n      res.push(codePoint >>> 10 & 0x3FF | 0xD800)\n      codePoint = 0xDC00 | codePoint & 0x3FF\n    }\n\n    res.push(codePoint)\n    i += bytesPerSequence\n  }\n\n  return decodeCodePointsArray(res)\n}\n\n// Based on http://stackoverflow.com/a/22747272/680742, the browser with\n// the lowest limit is Chrome, with 0x10000 args.\n// We go 1 magnitude less, for safety\nvar MAX_ARGUMENTS_LENGTH = 0x1000\n\nfunction decodeCodePointsArray (codePoints) {\n  var len = codePoints.length\n  if (len <= MAX_ARGUMENTS_LENGTH) {\n    return String.fromCharCode.apply(String, codePoints) // avoid extra slice()\n  }\n\n  // Decode in chunks to avoid \"call stack size exceeded\".\n  var res = ''\n  var i = 0\n  while (i < len) {\n    res += String.fromCharCode.apply(\n      String,\n      codePoints.slice(i, i += MAX_ARGUMENTS_LENGTH)\n    )\n  }\n  return res\n}\n\nfunction asciiSlice (buf, start, end) {\n  var ret = ''\n  end = Math.min(buf.length, end)\n\n  for (var i = start; i < end; ++i) {\n    ret += String.fromCharCode(buf[i] & 0x7F)\n  }\n  return ret\n}\n\nfunction latin1Slice (buf, start, end) {\n  var ret = ''\n  end = Math.min(buf.length, end)\n\n  for (var i = start; i < end; ++i) {\n    ret += String.fromCharCode(buf[i])\n  }\n  return ret\n}\n\nfunction hexSlice (buf, start, end) {\n  var len = buf.length\n\n  if (!start || start < 0) start = 0\n  if (!end || end < 0 || end > len) end = len\n\n  var out = ''\n  for (var i = start; i < end; ++i) {\n    out += toHex(buf[i])\n  }\n  return out\n}\n\nfunction utf16leSlice (buf, start, end) {\n  var bytes = buf.slice(start, end)\n  var res = ''\n  for (var i = 0; i < bytes.length; i += 2) {\n    res += String.fromCharCode(bytes[i] + bytes[i + 1] * 256)\n  }\n  return res\n}\n\nBuffer.prototype.slice = function slice (start, end) {\n  var len = this.length\n  start = ~~start\n  end = end === undefined ? len : ~~end\n\n  if (start < 0) {\n    start += len\n    if (start < 0) start = 0\n  } else if (start > len) {\n    start = len\n  }\n\n  if (end < 0) {\n    end += len\n    if (end < 0) end = 0\n  } else if (end > len) {\n    end = len\n  }\n\n  if (end < start) end = start\n\n  var newBuf\n  if (Buffer.TYPED_ARRAY_SUPPORT) {\n    newBuf = this.subarray(start, end)\n    newBuf.__proto__ = Buffer.prototype\n  } else {\n    var sliceLen = end - start\n    newBuf = new Buffer(sliceLen, undefined)\n    for (var i = 0; i < sliceLen; ++i) {\n      newBuf[i] = this[i + start]\n    }\n  }\n\n  return newBuf\n}\n\n/*\n * Need to make sure that buffer isn't trying to write out of bounds.\n */\nfunction checkOffset (offset, ext, length) {\n  if ((offset % 1) !== 0 || offset < 0) throw new RangeError('offset is not uint')\n  if (offset + ext > length) throw new RangeError('Trying to access beyond buffer length')\n}\n\nBuffer.prototype.readUIntLE = function readUIntLE (offset, byteLength, noAssert) {\n  offset = offset | 0\n  byteLength = byteLength | 0\n  if (!noAssert) checkOffset(offset, byteLength, this.length)\n\n  var val = this[offset]\n  var mul = 1\n  var i = 0\n  while (++i < byteLength && (mul *= 0x100)) {\n    val += this[offset + i] * mul\n  }\n\n  return val\n}\n\nBuffer.prototype.readUIntBE = function readUIntBE (offset, byteLength, noAssert) {\n  offset = offset | 0\n  byteLength = byteLength | 0\n  if (!noAssert) {\n    checkOffset(offset, byteLength, this.length)\n  }\n\n  var val = this[offset + --byteLength]\n  var mul = 1\n  while (byteLength > 0 && (mul *= 0x100)) {\n    val += this[offset + --byteLength] * mul\n  }\n\n  return val\n}\n\nBuffer.prototype.readUInt8 = function readUInt8 (offset, noAssert) {\n  if (!noAssert) checkOffset(offset, 1, this.length)\n  return this[offset]\n}\n\nBuffer.prototype.readUInt16LE = function readUInt16LE (offset, noAssert) {\n  if (!noAssert) checkOffset(offset, 2, this.length)\n  return this[offset] | (this[offset + 1] << 8)\n}\n\nBuffer.prototype.readUInt16BE = function readUInt16BE (offset, noAssert) {\n  if (!noAssert) checkOffset(offset, 2, this.length)\n  return (this[offset] << 8) | this[offset + 1]\n}\n\nBuffer.prototype.readUInt32LE = function readUInt32LE (offset, noAssert) {\n  if (!noAssert) checkOffset(offset, 4, this.length)\n\n  return ((this[offset]) |\n      (this[offset + 1] << 8) |\n      (this[offset + 2] << 16)) +\n      (this[offset + 3] * 0x1000000)\n}\n\nBuffer.prototype.readUInt32BE = function readUInt32BE (offset, noAssert) {\n  if (!noAssert) checkOffset(offset, 4, this.length)\n\n  return (this[offset] * 0x1000000) +\n    ((this[offset + 1] << 16) |\n    (this[offset + 2] << 8) |\n    this[offset + 3])\n}\n\nBuffer.prototype.readIntLE = function readIntLE (offset, byteLength, noAssert) {\n  offset = offset | 0\n  byteLength = byteLength | 0\n  if (!noAssert) checkOffset(offset, byteLength, this.length)\n\n  var val = this[offset]\n  var mul = 1\n  var i = 0\n  while (++i < byteLength && (mul *= 0x100)) {\n    val += this[offset + i] * mul\n  }\n  mul *= 0x80\n\n  if (val >= mul) val -= Math.pow(2, 8 * byteLength)\n\n  return val\n}\n\nBuffer.prototype.readIntBE = function readIntBE (offset, byteLength, noAssert) {\n  offset = offset | 0\n  byteLength = byteLength | 0\n  if (!noAssert) checkOffset(offset, byteLength, this.length)\n\n  var i = byteLength\n  var mul = 1\n  var val = this[offset + --i]\n  while (i > 0 && (mul *= 0x100)) {\n    val += this[offset + --i] * mul\n  }\n  mul *= 0x80\n\n  if (val >= mul) val -= Math.pow(2, 8 * byteLength)\n\n  return val\n}\n\nBuffer.prototype.readInt8 = function readInt8 (offset, noAssert) {\n  if (!noAssert) checkOffset(offset, 1, this.length)\n  if (!(this[offset] & 0x80)) return (this[offset])\n  return ((0xff - this[offset] + 1) * -1)\n}\n\nBuffer.prototype.readInt16LE = function readInt16LE (offset, noAssert) {\n  if (!noAssert) checkOffset(offset, 2, this.length)\n  var val = this[offset] | (this[offset + 1] << 8)\n  return (val & 0x8000) ? val | 0xFFFF0000 : val\n}\n\nBuffer.prototype.readInt16BE = function readInt16BE (offset, noAssert) {\n  if (!noAssert) checkOffset(offset, 2, this.length)\n  var val = this[offset + 1] | (this[offset] << 8)\n  return (val & 0x8000) ? val | 0xFFFF0000 : val\n}\n\nBuffer.prototype.readInt32LE = function readInt32LE (offset, noAssert) {\n  if (!noAssert) checkOffset(offset, 4, this.length)\n\n  return (this[offset]) |\n    (this[offset + 1] << 8) |\n    (this[offset + 2] << 16) |\n    (this[offset + 3] << 24)\n}\n\nBuffer.prototype.readInt32BE = function readInt32BE (offset, noAssert) {\n  if (!noAssert) checkOffset(offset, 4, this.length)\n\n  return (this[offset] << 24) |\n    (this[offset + 1] << 16) |\n    (this[offset + 2] << 8) |\n    (this[offset + 3])\n}\n\nBuffer.prototype.readFloatLE = function readFloatLE (offset, noAssert) {\n  if (!noAssert) checkOffset(offset, 4, this.length)\n  return ieee754.read(this, offset, true, 23, 4)\n}\n\nBuffer.prototype.readFloatBE = function readFloatBE (offset, noAssert) {\n  if (!noAssert) checkOffset(offset, 4, this.length)\n  return ieee754.read(this, offset, false, 23, 4)\n}\n\nBuffer.prototype.readDoubleLE = function readDoubleLE (offset, noAssert) {\n  if (!noAssert) checkOffset(offset, 8, this.length)\n  return ieee754.read(this, offset, true, 52, 8)\n}\n\nBuffer.prototype.readDoubleBE = function readDoubleBE (offset, noAssert) {\n  if (!noAssert) checkOffset(offset, 8, this.length)\n  return ieee754.read(this, offset, false, 52, 8)\n}\n\nfunction checkInt (buf, value, offset, ext, max, min) {\n  if (!Buffer.isBuffer(buf)) throw new TypeError('\"buffer\" argument must be a Buffer instance')\n  if (value > max || value < min) throw new RangeError('\"value\" argument is out of bounds')\n  if (offset + ext > buf.length) throw new RangeError('Index out of range')\n}\n\nBuffer.prototype.writeUIntLE = function writeUIntLE (value, offset, byteLength, noAssert) {\n  value = +value\n  offset = offset | 0\n  byteLength = byteLength | 0\n  if (!noAssert) {\n    var maxBytes = Math.pow(2, 8 * byteLength) - 1\n    checkInt(this, value, offset, byteLength, maxBytes, 0)\n  }\n\n  var mul = 1\n  var i = 0\n  this[offset] = value & 0xFF\n  while (++i < byteLength && (mul *= 0x100)) {\n    this[offset + i] = (value / mul) & 0xFF\n  }\n\n  return offset + byteLength\n}\n\nBuffer.prototype.writeUIntBE = function writeUIntBE (value, offset, byteLength, noAssert) {\n  value = +value\n  offset = offset | 0\n  byteLength = byteLength | 0\n  if (!noAssert) {\n    var maxBytes = Math.pow(2, 8 * byteLength) - 1\n    checkInt(this, value, offset, byteLength, maxBytes, 0)\n  }\n\n  var i = byteLength - 1\n  var mul = 1\n  this[offset + i] = value & 0xFF\n  while (--i >= 0 && (mul *= 0x100)) {\n    this[offset + i] = (value / mul) & 0xFF\n  }\n\n  return offset + byteLength\n}\n\nBuffer.prototype.writeUInt8 = function writeUInt8 (value, offset, noAssert) {\n  value = +value\n  offset = offset | 0\n  if (!noAssert) checkInt(this, value, offset, 1, 0xff, 0)\n  if (!Buffer.TYPED_ARRAY_SUPPORT) value = Math.floor(value)\n  this[offset] = (value & 0xff)\n  return offset + 1\n}\n\nfunction objectWriteUInt16 (buf, value, offset, littleEndian) {\n  if (value < 0) value = 0xffff + value + 1\n  for (var i = 0, j = Math.min(buf.length - offset, 2); i < j; ++i) {\n    buf[offset + i] = (value & (0xff << (8 * (littleEndian ? i : 1 - i)))) >>>\n      (littleEndian ? i : 1 - i) * 8\n  }\n}\n\nBuffer.prototype.writeUInt16LE = function writeUInt16LE (value, offset, noAssert) {\n  value = +value\n  offset = offset | 0\n  if (!noAssert) checkInt(this, value, offset, 2, 0xffff, 0)\n  if (Buffer.TYPED_ARRAY_SUPPORT) {\n    this[offset] = (value & 0xff)\n    this[offset + 1] = (value >>> 8)\n  } else {\n    objectWriteUInt16(this, value, offset, true)\n  }\n  return offset + 2\n}\n\nBuffer.prototype.writeUInt16BE = function writeUInt16BE (value, offset, noAssert) {\n  value = +value\n  offset = offset | 0\n  if (!noAssert) checkInt(this, value, offset, 2, 0xffff, 0)\n  if (Buffer.TYPED_ARRAY_SUPPORT) {\n    this[offset] = (value >>> 8)\n    this[offset + 1] = (value & 0xff)\n  } else {\n    objectWriteUInt16(this, value, offset, false)\n  }\n  return offset + 2\n}\n\nfunction objectWriteUInt32 (buf, value, offset, littleEndian) {\n  if (value < 0) value = 0xffffffff + value + 1\n  for (var i = 0, j = Math.min(buf.length - offset, 4); i < j; ++i) {\n    buf[offset + i] = (value >>> (littleEndian ? i : 3 - i) * 8) & 0xff\n  }\n}\n\nBuffer.prototype.writeUInt32LE = function writeUInt32LE (value, offset, noAssert) {\n  value = +value\n  offset = offset | 0\n  if (!noAssert) checkInt(this, value, offset, 4, 0xffffffff, 0)\n  if (Buffer.TYPED_ARRAY_SUPPORT) {\n    this[offset + 3] = (value >>> 24)\n    this[offset + 2] = (value >>> 16)\n    this[offset + 1] = (value >>> 8)\n    this[offset] = (value & 0xff)\n  } else {\n    objectWriteUInt32(this, value, offset, true)\n  }\n  return offset + 4\n}\n\nBuffer.prototype.writeUInt32BE = function writeUInt32BE (value, offset, noAssert) {\n  value = +value\n  offset = offset | 0\n  if (!noAssert) checkInt(this, value, offset, 4, 0xffffffff, 0)\n  if (Buffer.TYPED_ARRAY_SUPPORT) {\n    this[offset] = (value >>> 24)\n    this[offset + 1] = (value >>> 16)\n    this[offset + 2] = (value >>> 8)\n    this[offset + 3] = (value & 0xff)\n  } else {\n    objectWriteUInt32(this, value, offset, false)\n  }\n  return offset + 4\n}\n\nBuffer.prototype.writeIntLE = function writeIntLE (value, offset, byteLength, noAssert) {\n  value = +value\n  offset = offset | 0\n  if (!noAssert) {\n    var limit = Math.pow(2, 8 * byteLength - 1)\n\n    checkInt(this, value, offset, byteLength, limit - 1, -limit)\n  }\n\n  var i = 0\n  var mul = 1\n  var sub = 0\n  this[offset] = value & 0xFF\n  while (++i < byteLength && (mul *= 0x100)) {\n    if (value < 0 && sub === 0 && this[offset + i - 1] !== 0) {\n      sub = 1\n    }\n    this[offset + i] = ((value / mul) >> 0) - sub & 0xFF\n  }\n\n  return offset + byteLength\n}\n\nBuffer.prototype.writeIntBE = function writeIntBE (value, offset, byteLength, noAssert) {\n  value = +value\n  offset = offset | 0\n  if (!noAssert) {\n    var limit = Math.pow(2, 8 * byteLength - 1)\n\n    checkInt(this, value, offset, byteLength, limit - 1, -limit)\n  }\n\n  var i = byteLength - 1\n  var mul = 1\n  var sub = 0\n  this[offset + i] = value & 0xFF\n  while (--i >= 0 && (mul *= 0x100)) {\n    if (value < 0 && sub === 0 && this[offset + i + 1] !== 0) {\n      sub = 1\n    }\n    this[offset + i] = ((value / mul) >> 0) - sub & 0xFF\n  }\n\n  return offset + byteLength\n}\n\nBuffer.prototype.writeInt8 = function writeInt8 (value, offset, noAssert) {\n  value = +value\n  offset = offset | 0\n  if (!noAssert) checkInt(this, value, offset, 1, 0x7f, -0x80)\n  if (!Buffer.TYPED_ARRAY_SUPPORT) value = Math.floor(value)\n  if (value < 0) value = 0xff + value + 1\n  this[offset] = (value & 0xff)\n  return offset + 1\n}\n\nBuffer.prototype.writeInt16LE = function writeInt16LE (value, offset, noAssert) {\n  value = +value\n  offset = offset | 0\n  if (!noAssert) checkInt(this, value, offset, 2, 0x7fff, -0x8000)\n  if (Buffer.TYPED_ARRAY_SUPPORT) {\n    this[offset] = (value & 0xff)\n    this[offset + 1] = (value >>> 8)\n  } else {\n    objectWriteUInt16(this, value, offset, true)\n  }\n  return offset + 2\n}\n\nBuffer.prototype.writeInt16BE = function writeInt16BE (value, offset, noAssert) {\n  value = +value\n  offset = offset | 0\n  if (!noAssert) checkInt(this, value, offset, 2, 0x7fff, -0x8000)\n  if (Buffer.TYPED_ARRAY_SUPPORT) {\n    this[offset] = (value >>> 8)\n    this[offset + 1] = (value & 0xff)\n  } else {\n    objectWriteUInt16(this, value, offset, false)\n  }\n  return offset + 2\n}\n\nBuffer.prototype.writeInt32LE = function writeInt32LE (value, offset, noAssert) {\n  value = +value\n  offset = offset | 0\n  if (!noAssert) checkInt(this, value, offset, 4, 0x7fffffff, -0x80000000)\n  if (Buffer.TYPED_ARRAY_SUPPORT) {\n    this[offset] = (value & 0xff)\n    this[offset + 1] = (value >>> 8)\n    this[offset + 2] = (value >>> 16)\n    this[offset + 3] = (value >>> 24)\n  } else {\n    objectWriteUInt32(this, value, offset, true)\n  }\n  return offset + 4\n}\n\nBuffer.prototype.writeInt32BE = function writeInt32BE (value, offset, noAssert) {\n  value = +value\n  offset = offset | 0\n  if (!noAssert) checkInt(this, value, offset, 4, 0x7fffffff, -0x80000000)\n  if (value < 0) value = 0xffffffff + value + 1\n  if (Buffer.TYPED_ARRAY_SUPPORT) {\n    this[offset] = (value >>> 24)\n    this[offset + 1] = (value >>> 16)\n    this[offset + 2] = (value >>> 8)\n    this[offset + 3] = (value & 0xff)\n  } else {\n    objectWriteUInt32(this, value, offset, false)\n  }\n  return offset + 4\n}\n\nfunction checkIEEE754 (buf, value, offset, ext, max, min) {\n  if (offset + ext > buf.length) throw new RangeError('Index out of range')\n  if (offset < 0) throw new RangeError('Index out of range')\n}\n\nfunction writeFloat (buf, value, offset, littleEndian, noAssert) {\n  if (!noAssert) {\n    checkIEEE754(buf, value, offset, 4, 3.4028234663852886e+38, -3.4028234663852886e+38)\n  }\n  ieee754.write(buf, value, offset, littleEndian, 23, 4)\n  return offset + 4\n}\n\nBuffer.prototype.writeFloatLE = function writeFloatLE (value, offset, noAssert) {\n  return writeFloat(this, value, offset, true, noAssert)\n}\n\nBuffer.prototype.writeFloatBE = function writeFloatBE (value, offset, noAssert) {\n  return writeFloat(this, value, offset, false, noAssert)\n}\n\nfunction writeDouble (buf, value, offset, littleEndian, noAssert) {\n  if (!noAssert) {\n    checkIEEE754(buf, value, offset, 8, 1.7976931348623157E+308, -1.7976931348623157E+308)\n  }\n  ieee754.write(buf, value, offset, littleEndian, 52, 8)\n  return offset + 8\n}\n\nBuffer.prototype.writeDoubleLE = function writeDoubleLE (value, offset, noAssert) {\n  return writeDouble(this, value, offset, true, noAssert)\n}\n\nBuffer.prototype.writeDoubleBE = function writeDoubleBE (value, offset, noAssert) {\n  return writeDouble(this, value, offset, false, noAssert)\n}\n\n// copy(targetBuffer, targetStart=0, sourceStart=0, sourceEnd=buffer.length)\nBuffer.prototype.copy = function copy (target, targetStart, start, end) {\n  if (!start) start = 0\n  if (!end && end !== 0) end = this.length\n  if (targetStart >= target.length) targetStart = target.length\n  if (!targetStart) targetStart = 0\n  if (end > 0 && end < start) end = start\n\n  // Copy 0 bytes; we're done\n  if (end === start) return 0\n  if (target.length === 0 || this.length === 0) return 0\n\n  // Fatal error conditions\n  if (targetStart < 0) {\n    throw new RangeError('targetStart out of bounds')\n  }\n  if (start < 0 || start >= this.length) throw new RangeError('sourceStart out of bounds')\n  if (end < 0) throw new RangeError('sourceEnd out of bounds')\n\n  // Are we oob?\n  if (end > this.length) end = this.length\n  if (target.length - targetStart < end - start) {\n    end = target.length - targetStart + start\n  }\n\n  var len = end - start\n  var i\n\n  if (this === target && start < targetStart && targetStart < end) {\n    // descending copy from end\n    for (i = len - 1; i >= 0; --i) {\n      target[i + targetStart] = this[i + start]\n    }\n  } else if (len < 1000 || !Buffer.TYPED_ARRAY_SUPPORT) {\n    // ascending copy from start\n    for (i = 0; i < len; ++i) {\n      target[i + targetStart] = this[i + start]\n    }\n  } else {\n    Uint8Array.prototype.set.call(\n      target,\n      this.subarray(start, start + len),\n      targetStart\n    )\n  }\n\n  return len\n}\n\n// Usage:\n//    buffer.fill(number[, offset[, end]])\n//    buffer.fill(buffer[, offset[, end]])\n//    buffer.fill(string[, offset[, end]][, encoding])\nBuffer.prototype.fill = function fill (val, start, end, encoding) {\n  // Handle string cases:\n  if (typeof val === 'string') {\n    if (typeof start === 'string') {\n      encoding = start\n      start = 0\n      end = this.length\n    } else if (typeof end === 'string') {\n      encoding = end\n      end = this.length\n    }\n    if (val.length === 1) {\n      var code = val.charCodeAt(0)\n      if (code < 256) {\n        val = code\n      }\n    }\n    if (encoding !== undefined && typeof encoding !== 'string') {\n      throw new TypeError('encoding must be a string')\n    }\n    if (typeof encoding === 'string' && !Buffer.isEncoding(encoding)) {\n      throw new TypeError('Unknown encoding: ' + encoding)\n    }\n  } else if (typeof val === 'number') {\n    val = val & 255\n  }\n\n  // Invalid ranges are not set to a default, so can range check early.\n  if (start < 0 || this.length < start || this.length < end) {\n    throw new RangeError('Out of range index')\n  }\n\n  if (end <= start) {\n    return this\n  }\n\n  start = start >>> 0\n  end = end === undefined ? this.length : end >>> 0\n\n  if (!val) val = 0\n\n  var i\n  if (typeof val === 'number') {\n    for (i = start; i < end; ++i) {\n      this[i] = val\n    }\n  } else {\n    var bytes = Buffer.isBuffer(val)\n      ? val\n      : utf8ToBytes(new Buffer(val, encoding).toString())\n    var len = bytes.length\n    for (i = 0; i < end - start; ++i) {\n      this[i + start] = bytes[i % len]\n    }\n  }\n\n  return this\n}\n\n// HELPER FUNCTIONS\n// ================\n\nvar INVALID_BASE64_RE = /[^+\\/0-9A-Za-z-_]/g\n\nfunction base64clean (str) {\n  // Node strips out invalid characters like \\n and \\t from the string, base64-js does not\n  str = stringtrim(str).replace(INVALID_BASE64_RE, '')\n  // Node converts strings with length < 2 to ''\n  if (str.length < 2) return ''\n  // Node allows for non-padded base64 strings (missing trailing ===), base64-js does not\n  while (str.length % 4 !== 0) {\n    str = str + '='\n  }\n  return str\n}\n\nfunction stringtrim (str) {\n  if (str.trim) return str.trim()\n  return str.replace(/^\\s+|\\s+$/g, '')\n}\n\nfunction toHex (n) {\n  if (n < 16) return '0' + n.toString(16)\n  return n.toString(16)\n}\n\nfunction utf8ToBytes (string, units) {\n  units = units || Infinity\n  var codePoint\n  var length = string.length\n  var leadSurrogate = null\n  var bytes = []\n\n  for (var i = 0; i < length; ++i) {\n    codePoint = string.charCodeAt(i)\n\n    // is surrogate component\n    if (codePoint > 0xD7FF && codePoint < 0xE000) {\n      // last char was a lead\n      if (!leadSurrogate) {\n        // no lead yet\n        if (codePoint > 0xDBFF) {\n          // unexpected trail\n          if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD)\n          continue\n        } else if (i + 1 === length) {\n          // unpaired lead\n          if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD)\n          continue\n        }\n\n        // valid lead\n        leadSurrogate = codePoint\n\n        continue\n      }\n\n      // 2 leads in a row\n      if (codePoint < 0xDC00) {\n        if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD)\n        leadSurrogate = codePoint\n        continue\n      }\n\n      // valid surrogate pair\n      codePoint = (leadSurrogate - 0xD800 << 10 | codePoint - 0xDC00) + 0x10000\n    } else if (leadSurrogate) {\n      // valid bmp char, but last char was a lead\n      if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD)\n    }\n\n    leadSurrogate = null\n\n    // encode utf8\n    if (codePoint < 0x80) {\n      if ((units -= 1) < 0) break\n      bytes.push(codePoint)\n    } else if (codePoint < 0x800) {\n      if ((units -= 2) < 0) break\n      bytes.push(\n        codePoint >> 0x6 | 0xC0,\n        codePoint & 0x3F | 0x80\n      )\n    } else if (codePoint < 0x10000) {\n      if ((units -= 3) < 0) break\n      bytes.push(\n        codePoint >> 0xC | 0xE0,\n        codePoint >> 0x6 & 0x3F | 0x80,\n        codePoint & 0x3F | 0x80\n      )\n    } else if (codePoint < 0x110000) {\n      if ((units -= 4) < 0) break\n      bytes.push(\n        codePoint >> 0x12 | 0xF0,\n        codePoint >> 0xC & 0x3F | 0x80,\n        codePoint >> 0x6 & 0x3F | 0x80,\n        codePoint & 0x3F | 0x80\n      )\n    } else {\n      throw new Error('Invalid code point')\n    }\n  }\n\n  return bytes\n}\n\nfunction asciiToBytes (str) {\n  var byteArray = []\n  for (var i = 0; i < str.length; ++i) {\n    // Node's code seems to be doing this and not & 0x7F..\n    byteArray.push(str.charCodeAt(i) & 0xFF)\n  }\n  return byteArray\n}\n\nfunction utf16leToBytes (str, units) {\n  var c, hi, lo\n  var byteArray = []\n  for (var i = 0; i < str.length; ++i) {\n    if ((units -= 2) < 0) break\n\n    c = str.charCodeAt(i)\n    hi = c >> 8\n    lo = c % 256\n    byteArray.push(lo)\n    byteArray.push(hi)\n  }\n\n  return byteArray\n}\n\nfunction base64ToBytes (str) {\n  return base64.toByteArray(base64clean(str))\n}\n\nfunction blitBuffer (src, dst, offset, length) {\n  for (var i = 0; i < length; ++i) {\n    if ((i + offset >= dst.length) || (i >= src.length)) break\n    dst[i + offset] = src[i]\n  }\n  return i\n}\n\nfunction isnan (val) {\n  return val !== val // eslint-disable-line no-self-compare\n}\n\n}).call(this,typeof global !== \"undefined\" ? global : typeof self !== \"undefined\" ? self : typeof window !== \"undefined\" ? window : {})\n},{\"base64-js\":39,\"ieee754\":50,\"isarray\":53}],45:[function(require,module,exports){\n(function (Buffer){\n// Copyright Joyent, Inc. and other Node contributors.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a\n// copy of this software and associated documentation files (the\n// \"Software\"), to deal in the Software without restriction, including\n// without limitation the rights to use, copy, modify, merge, publish,\n// distribute, sublicense, and/or sell copies of the Software, and to permit\n// persons to whom the Software is furnished to do so, subject to the\n// following conditions:\n//\n// The above copyright notice and this permission notice shall be included\n// in all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS\n// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN\n// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,\n// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE\n// USE OR OTHER DEALINGS IN THE SOFTWARE.\n\n// NOTE: These type checking functions intentionally don't use `instanceof`\n// because it is fragile and can be easily faked with `Object.create()`.\n\nfunction isArray(arg) {\n  if (Array.isArray) {\n    return Array.isArray(arg);\n  }\n  return objectToString(arg) === '[object Array]';\n}\nexports.isArray = isArray;\n\nfunction isBoolean(arg) {\n  return typeof arg === 'boolean';\n}\nexports.isBoolean = isBoolean;\n\nfunction isNull(arg) {\n  return arg === null;\n}\nexports.isNull = isNull;\n\nfunction isNullOrUndefined(arg) {\n  return arg == null;\n}\nexports.isNullOrUndefined = isNullOrUndefined;\n\nfunction isNumber(arg) {\n  return typeof arg === 'number';\n}\nexports.isNumber = isNumber;\n\nfunction isString(arg) {\n  return typeof arg === 'string';\n}\nexports.isString = isString;\n\nfunction isSymbol(arg) {\n  return typeof arg === 'symbol';\n}\nexports.isSymbol = isSymbol;\n\nfunction isUndefined(arg) {\n  return arg === void 0;\n}\nexports.isUndefined = isUndefined;\n\nfunction isRegExp(re) {\n  return objectToString(re) === '[object RegExp]';\n}\nexports.isRegExp = isRegExp;\n\nfunction isObject(arg) {\n  return typeof arg === 'object' && arg !== null;\n}\nexports.isObject = isObject;\n\nfunction isDate(d) {\n  return objectToString(d) === '[object Date]';\n}\nexports.isDate = isDate;\n\nfunction isError(e) {\n  return (objectToString(e) === '[object Error]' || e instanceof Error);\n}\nexports.isError = isError;\n\nfunction isFunction(arg) {\n  return typeof arg === 'function';\n}\nexports.isFunction = isFunction;\n\nfunction isPrimitive(arg) {\n  return arg === null ||\n         typeof arg === 'boolean' ||\n         typeof arg === 'number' ||\n         typeof arg === 'string' ||\n         typeof arg === 'symbol' ||  // ES6 symbol\n         typeof arg === 'undefined';\n}\nexports.isPrimitive = isPrimitive;\n\nexports.isBuffer = Buffer.isBuffer;\n\nfunction objectToString(o) {\n  return Object.prototype.toString.call(o);\n}\n\n}).call(this,{\"isBuffer\":require(\"../../is-buffer/index.js\")})\n},{\"../../is-buffer/index.js\":52}],46:[function(require,module,exports){\n/* See LICENSE file for terms of use */\n\n/*\n * Text diff implementation.\n *\n * This library supports the following APIS:\n * JsDiff.diffChars: Character by character diff\n * JsDiff.diffWords: Word (as defined by \\b regex) diff which ignores whitespace\n * JsDiff.diffLines: Line based diff\n *\n * JsDiff.diffCss: Diff targeted at CSS content\n *\n * These methods are based on the implementation proposed in\n * \"An O(ND) Difference Algorithm and its Variations\" (Myers, 1986).\n * http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.4.6927\n */\n(function(global, undefined) {\n  var objectPrototypeToString = Object.prototype.toString;\n\n  /*istanbul ignore next*/\n  function map(arr, mapper, that) {\n    if (Array.prototype.map) {\n      return Array.prototype.map.call(arr, mapper, that);\n    }\n\n    var other = new Array(arr.length);\n\n    for (var i = 0, n = arr.length; i < n; i++) {\n      other[i] = mapper.call(that, arr[i], i, arr);\n    }\n    return other;\n  }\n  function clonePath(path) {\n    return { newPos: path.newPos, components: path.components.slice(0) };\n  }\n  function removeEmpty(array) {\n    var ret = [];\n    for (var i = 0; i < array.length; i++) {\n      if (array[i]) {\n        ret.push(array[i]);\n      }\n    }\n    return ret;\n  }\n  function escapeHTML(s) {\n    var n = s;\n    n = n.replace(/&/g, '&amp;');\n    n = n.replace(/</g, '&lt;');\n    n = n.replace(/>/g, '&gt;');\n    n = n.replace(/\"/g, '&quot;');\n\n    return n;\n  }\n\n  // This function handles the presence of circular references by bailing out when encountering an\n  // object that is already on the \"stack\" of items being processed.\n  function canonicalize(obj, stack, replacementStack) {\n    stack = stack || [];\n    replacementStack = replacementStack || [];\n\n    var i;\n\n    for (i = 0; i < stack.length; i += 1) {\n      if (stack[i] === obj) {\n        return replacementStack[i];\n      }\n    }\n\n    var canonicalizedObj;\n\n    if ('[object Array]' === objectPrototypeToString.call(obj)) {\n      stack.push(obj);\n      canonicalizedObj = new Array(obj.length);\n      replacementStack.push(canonicalizedObj);\n      for (i = 0; i < obj.length; i += 1) {\n        canonicalizedObj[i] = canonicalize(obj[i], stack, replacementStack);\n      }\n      stack.pop();\n      replacementStack.pop();\n    } else if (typeof obj === 'object' && obj !== null) {\n      stack.push(obj);\n      canonicalizedObj = {};\n      replacementStack.push(canonicalizedObj);\n      var sortedKeys = [],\n          key;\n      for (key in obj) {\n        sortedKeys.push(key);\n      }\n      sortedKeys.sort();\n      for (i = 0; i < sortedKeys.length; i += 1) {\n        key = sortedKeys[i];\n        canonicalizedObj[key] = canonicalize(obj[key], stack, replacementStack);\n      }\n      stack.pop();\n      replacementStack.pop();\n    } else {\n      canonicalizedObj = obj;\n    }\n    return canonicalizedObj;\n  }\n\n  function buildValues(components, newString, oldString, useLongestToken) {\n    var componentPos = 0,\n        componentLen = components.length,\n        newPos = 0,\n        oldPos = 0;\n\n    for (; componentPos < componentLen; componentPos++) {\n      var component = components[componentPos];\n      if (!component.removed) {\n        if (!component.added && useLongestToken) {\n          var value = newString.slice(newPos, newPos + component.count);\n          value = map(value, function(value, i) {\n            var oldValue = oldString[oldPos + i];\n            return oldValue.length > value.length ? oldValue : value;\n          });\n\n          component.value = value.join('');\n        } else {\n          component.value = newString.slice(newPos, newPos + component.count).join('');\n        }\n        newPos += component.count;\n\n        // Common case\n        if (!component.added) {\n          oldPos += component.count;\n        }\n      } else {\n        component.value = oldString.slice(oldPos, oldPos + component.count).join('');\n        oldPos += component.count;\n\n        // Reverse add and remove so removes are output first to match common convention\n        // The diffing algorithm is tied to add then remove output and this is the simplest\n        // route to get the desired output with minimal overhead.\n        if (componentPos && components[componentPos - 1].added) {\n          var tmp = components[componentPos - 1];\n          components[componentPos - 1] = components[componentPos];\n          components[componentPos] = tmp;\n        }\n      }\n    }\n\n    return components;\n  }\n\n  function Diff(ignoreWhitespace) {\n    this.ignoreWhitespace = ignoreWhitespace;\n  }\n  Diff.prototype = {\n    diff: function(oldString, newString, callback) {\n      var self = this;\n\n      function done(value) {\n        if (callback) {\n          setTimeout(function() { callback(undefined, value); }, 0);\n          return true;\n        } else {\n          return value;\n        }\n      }\n\n      // Handle the identity case (this is due to unrolling editLength == 0\n      if (newString === oldString) {\n        return done([{ value: newString }]);\n      }\n      if (!newString) {\n        return done([{ value: oldString, removed: true }]);\n      }\n      if (!oldString) {\n        return done([{ value: newString, added: true }]);\n      }\n\n      newString = this.tokenize(newString);\n      oldString = this.tokenize(oldString);\n\n      var newLen = newString.length, oldLen = oldString.length;\n      var editLength = 1;\n      var maxEditLength = newLen + oldLen;\n      var bestPath = [{ newPos: -1, components: [] }];\n\n      // Seed editLength = 0, i.e. the content starts with the same values\n      var oldPos = this.extractCommon(bestPath[0], newString, oldString, 0);\n      if (bestPath[0].newPos + 1 >= newLen && oldPos + 1 >= oldLen) {\n        // Identity per the equality and tokenizer\n        return done([{value: newString.join('')}]);\n      }\n\n      // Main worker method. checks all permutations of a given edit length for acceptance.\n      function execEditLength() {\n        for (var diagonalPath = -1 * editLength; diagonalPath <= editLength; diagonalPath += 2) {\n          var basePath;\n          var addPath = bestPath[diagonalPath - 1],\n              removePath = bestPath[diagonalPath + 1],\n              oldPos = (removePath ? removePath.newPos : 0) - diagonalPath;\n          if (addPath) {\n            // No one else is going to attempt to use this value, clear it\n            bestPath[diagonalPath - 1] = undefined;\n          }\n\n          var canAdd = addPath && addPath.newPos + 1 < newLen,\n              canRemove = removePath && 0 <= oldPos && oldPos < oldLen;\n          if (!canAdd && !canRemove) {\n            // If this path is a terminal then prune\n            bestPath[diagonalPath] = undefined;\n            continue;\n          }\n\n          // Select the diagonal that we want to branch from. We select the prior\n          // path whose position in the new string is the farthest from the origin\n          // and does not pass the bounds of the diff graph\n          if (!canAdd || (canRemove && addPath.newPos < removePath.newPos)) {\n            basePath = clonePath(removePath);\n            self.pushComponent(basePath.components, undefined, true);\n          } else {\n            basePath = addPath;   // No need to clone, we've pulled it from the list\n            basePath.newPos++;\n            self.pushComponent(basePath.components, true, undefined);\n          }\n\n          oldPos = self.extractCommon(basePath, newString, oldString, diagonalPath);\n\n          // If we have hit the end of both strings, then we are done\n          if (basePath.newPos + 1 >= newLen && oldPos + 1 >= oldLen) {\n            return done(buildValues(basePath.components, newString, oldString, self.useLongestToken));\n          } else {\n            // Otherwise track this path as a potential candidate and continue.\n            bestPath[diagonalPath] = basePath;\n          }\n        }\n\n        editLength++;\n      }\n\n      // Performs the length of edit iteration. Is a bit fugly as this has to support the\n      // sync and async mode which is never fun. Loops over execEditLength until a value\n      // is produced.\n      if (callback) {\n        (function exec() {\n          setTimeout(function() {\n            // This should not happen, but we want to be safe.\n            /*istanbul ignore next */\n            if (editLength > maxEditLength) {\n              return callback();\n            }\n\n            if (!execEditLength()) {\n              exec();\n            }\n          }, 0);\n        }());\n      } else {\n        while (editLength <= maxEditLength) {\n          var ret = execEditLength();\n          if (ret) {\n            return ret;\n          }\n        }\n      }\n    },\n\n    pushComponent: function(components, added, removed) {\n      var last = components[components.length - 1];\n      if (last && last.added === added && last.removed === removed) {\n        // We need to clone here as the component clone operation is just\n        // as shallow array clone\n        components[components.length - 1] = {count: last.count + 1, added: added, removed: removed };\n      } else {\n        components.push({count: 1, added: added, removed: removed });\n      }\n    },\n    extractCommon: function(basePath, newString, oldString, diagonalPath) {\n      var newLen = newString.length,\n          oldLen = oldString.length,\n          newPos = basePath.newPos,\n          oldPos = newPos - diagonalPath,\n\n          commonCount = 0;\n      while (newPos + 1 < newLen && oldPos + 1 < oldLen && this.equals(newString[newPos + 1], oldString[oldPos + 1])) {\n        newPos++;\n        oldPos++;\n        commonCount++;\n      }\n\n      if (commonCount) {\n        basePath.components.push({count: commonCount});\n      }\n\n      basePath.newPos = newPos;\n      return oldPos;\n    },\n\n    equals: function(left, right) {\n      var reWhitespace = /\\S/;\n      return left === right || (this.ignoreWhitespace && !reWhitespace.test(left) && !reWhitespace.test(right));\n    },\n    tokenize: function(value) {\n      return value.split('');\n    }\n  };\n\n  var CharDiff = new Diff();\n\n  var WordDiff = new Diff(true);\n  var WordWithSpaceDiff = new Diff();\n  WordDiff.tokenize = WordWithSpaceDiff.tokenize = function(value) {\n    return removeEmpty(value.split(/(\\s+|\\b)/));\n  };\n\n  var CssDiff = new Diff(true);\n  CssDiff.tokenize = function(value) {\n    return removeEmpty(value.split(/([{}:;,]|\\s+)/));\n  };\n\n  var LineDiff = new Diff();\n\n  var TrimmedLineDiff = new Diff();\n  TrimmedLineDiff.ignoreTrim = true;\n\n  LineDiff.tokenize = TrimmedLineDiff.tokenize = function(value) {\n    var retLines = [],\n        lines = value.split(/^/m);\n    for (var i = 0; i < lines.length; i++) {\n      var line = lines[i],\n          lastLine = lines[i - 1],\n          lastLineLastChar = lastLine && lastLine[lastLine.length - 1];\n\n      // Merge lines that may contain windows new lines\n      if (line === '\\n' && lastLineLastChar === '\\r') {\n          retLines[retLines.length - 1] = retLines[retLines.length - 1].slice(0, -1) + '\\r\\n';\n      } else {\n        if (this.ignoreTrim) {\n          line = line.trim();\n          // add a newline unless this is the last line.\n          if (i < lines.length - 1) {\n            line += '\\n';\n          }\n        }\n        retLines.push(line);\n      }\n    }\n\n    return retLines;\n  };\n\n  var PatchDiff = new Diff();\n  PatchDiff.tokenize = function(value) {\n    var ret = [],\n        linesAndNewlines = value.split(/(\\n|\\r\\n)/);\n\n    // Ignore the final empty token that occurs if the string ends with a new line\n    if (!linesAndNewlines[linesAndNewlines.length - 1]) {\n      linesAndNewlines.pop();\n    }\n\n    // Merge the content and line separators into single tokens\n    for (var i = 0; i < linesAndNewlines.length; i++) {\n      var line = linesAndNewlines[i];\n\n      if (i % 2) {\n        ret[ret.length - 1] += line;\n      } else {\n        ret.push(line);\n      }\n    }\n    return ret;\n  };\n\n  var SentenceDiff = new Diff();\n  SentenceDiff.tokenize = function(value) {\n    return removeEmpty(value.split(/(\\S.+?[.!?])(?=\\s+|$)/));\n  };\n\n  var JsonDiff = new Diff();\n  // Discriminate between two lines of pretty-printed, serialized JSON where one of them has a\n  // dangling comma and the other doesn't. Turns out including the dangling comma yields the nicest output:\n  JsonDiff.useLongestToken = true;\n  JsonDiff.tokenize = LineDiff.tokenize;\n  JsonDiff.equals = function(left, right) {\n    return LineDiff.equals(left.replace(/,([\\r\\n])/g, '$1'), right.replace(/,([\\r\\n])/g, '$1'));\n  };\n\n  var JsDiff = {\n    Diff: Diff,\n\n    diffChars: function(oldStr, newStr, callback) { return CharDiff.diff(oldStr, newStr, callback); },\n    diffWords: function(oldStr, newStr, callback) { return WordDiff.diff(oldStr, newStr, callback); },\n    diffWordsWithSpace: function(oldStr, newStr, callback) { return WordWithSpaceDiff.diff(oldStr, newStr, callback); },\n    diffLines: function(oldStr, newStr, callback) { return LineDiff.diff(oldStr, newStr, callback); },\n    diffTrimmedLines: function(oldStr, newStr, callback) { return TrimmedLineDiff.diff(oldStr, newStr, callback); },\n\n    diffSentences: function(oldStr, newStr, callback) { return SentenceDiff.diff(oldStr, newStr, callback); },\n\n    diffCss: function(oldStr, newStr, callback) { return CssDiff.diff(oldStr, newStr, callback); },\n    diffJson: function(oldObj, newObj, callback) {\n      return JsonDiff.diff(\n        typeof oldObj === 'string' ? oldObj : JSON.stringify(canonicalize(oldObj), undefined, '  '),\n        typeof newObj === 'string' ? newObj : JSON.stringify(canonicalize(newObj), undefined, '  '),\n        callback\n      );\n    },\n\n    createTwoFilesPatch: function(oldFileName, newFileName, oldStr, newStr, oldHeader, newHeader) {\n      var ret = [];\n\n      if (oldFileName == newFileName) {\n        ret.push('Index: ' + oldFileName);\n      }\n      ret.push('===================================================================');\n      ret.push('--- ' + oldFileName + (typeof oldHeader === 'undefined' ? '' : '\\t' + oldHeader));\n      ret.push('+++ ' + newFileName + (typeof newHeader === 'undefined' ? '' : '\\t' + newHeader));\n\n      var diff = PatchDiff.diff(oldStr, newStr);\n      diff.push({value: '', lines: []});   // Append an empty value to make cleanup easier\n\n      // Formats a given set of lines for printing as context lines in a patch\n      function contextLines(lines) {\n        return map(lines, function(entry) { return ' ' + entry; });\n      }\n\n      // Outputs the no newline at end of file warning if needed\n      function eofNL(curRange, i, current) {\n        var last = diff[diff.length - 2],\n            isLast = i === diff.length - 2,\n            isLastOfType = i === diff.length - 3 && current.added !== last.added;\n\n        // Figure out if this is the last line for the given file and missing NL\n        if (!(/\\n$/.test(current.value)) && (isLast || isLastOfType)) {\n          curRange.push('\\\\ No newline at end of file');\n        }\n      }\n\n      var oldRangeStart = 0, newRangeStart = 0, curRange = [],\n          oldLine = 1, newLine = 1;\n      for (var i = 0; i < diff.length; i++) {\n        var current = diff[i],\n            lines = current.lines || current.value.replace(/\\n$/, '').split('\\n');\n        current.lines = lines;\n\n        if (current.added || current.removed) {\n          // If we have previous context, start with that\n          if (!oldRangeStart) {\n            var prev = diff[i - 1];\n            oldRangeStart = oldLine;\n            newRangeStart = newLine;\n\n            if (prev) {\n              curRange = contextLines(prev.lines.slice(-4));\n              oldRangeStart -= curRange.length;\n              newRangeStart -= curRange.length;\n            }\n          }\n\n          // Output our changes\n          curRange.push.apply(curRange, map(lines, function(entry) {\n            return (current.added ? '+' : '-') + entry;\n          }));\n          eofNL(curRange, i, current);\n\n          // Track the updated file position\n          if (current.added) {\n            newLine += lines.length;\n          } else {\n            oldLine += lines.length;\n          }\n        } else {\n          // Identical context lines. Track line changes\n          if (oldRangeStart) {\n            // Close out any changes that have been output (or join overlapping)\n            if (lines.length <= 8 && i < diff.length - 2) {\n              // Overlapping\n              curRange.push.apply(curRange, contextLines(lines));\n            } else {\n              // end the range and output\n              var contextSize = Math.min(lines.length, 4);\n              ret.push(\n                  '@@ -' + oldRangeStart + ',' + (oldLine - oldRangeStart + contextSize)\n                  + ' +' + newRangeStart + ',' + (newLine - newRangeStart + contextSize)\n                  + ' @@');\n              ret.push.apply(ret, curRange);\n              ret.push.apply(ret, contextLines(lines.slice(0, contextSize)));\n              if (lines.length <= 4) {\n                eofNL(ret, i, current);\n              }\n\n              oldRangeStart = 0;\n              newRangeStart = 0;\n              curRange = [];\n            }\n          }\n          oldLine += lines.length;\n          newLine += lines.length;\n        }\n      }\n\n      return ret.join('\\n') + '\\n';\n    },\n\n    createPatch: function(fileName, oldStr, newStr, oldHeader, newHeader) {\n      return JsDiff.createTwoFilesPatch(fileName, fileName, oldStr, newStr, oldHeader, newHeader);\n    },\n\n    applyPatch: function(oldStr, uniDiff) {\n      var diffstr = uniDiff.split('\\n'),\n          hunks = [],\n          i = 0,\n          remEOFNL = false,\n          addEOFNL = false;\n\n      // Skip to the first change hunk\n      while (i < diffstr.length && !(/^@@/.test(diffstr[i]))) {\n        i++;\n      }\n\n      // Parse the unified diff\n      for (; i < diffstr.length; i++) {\n        if (diffstr[i][0] === '@') {\n          var chnukHeader = diffstr[i].split(/@@ -(\\d+),(\\d+) \\+(\\d+),(\\d+) @@/);\n          hunks.unshift({\n            start: chnukHeader[3],\n            oldlength: +chnukHeader[2],\n            removed: [],\n            newlength: chnukHeader[4],\n            added: []\n          });\n        } else if (diffstr[i][0] === '+') {\n          hunks[0].added.push(diffstr[i].substr(1));\n        } else if (diffstr[i][0] === '-') {\n          hunks[0].removed.push(diffstr[i].substr(1));\n        } else if (diffstr[i][0] === ' ') {\n          hunks[0].added.push(diffstr[i].substr(1));\n          hunks[0].removed.push(diffstr[i].substr(1));\n        } else if (diffstr[i][0] === '\\\\') {\n          if (diffstr[i - 1][0] === '+') {\n            remEOFNL = true;\n          } else if (diffstr[i - 1][0] === '-') {\n            addEOFNL = true;\n          }\n        }\n      }\n\n      // Apply the diff to the input\n      var lines = oldStr.split('\\n');\n      for (i = hunks.length - 1; i >= 0; i--) {\n        var hunk = hunks[i];\n        // Sanity check the input string. Bail if we don't match.\n        for (var j = 0; j < hunk.oldlength; j++) {\n          if (lines[hunk.start - 1 + j] !== hunk.removed[j]) {\n            return false;\n          }\n        }\n        Array.prototype.splice.apply(lines, [hunk.start - 1, hunk.oldlength].concat(hunk.added));\n      }\n\n      // Handle EOFNL insertion/removal\n      if (remEOFNL) {\n        while (!lines[lines.length - 1]) {\n          lines.pop();\n        }\n      } else if (addEOFNL) {\n        lines.push('');\n      }\n      return lines.join('\\n');\n    },\n\n    convertChangesToXML: function(changes) {\n      var ret = [];\n      for (var i = 0; i < changes.length; i++) {\n        var change = changes[i];\n        if (change.added) {\n          ret.push('<ins>');\n        } else if (change.removed) {\n          ret.push('<del>');\n        }\n\n        ret.push(escapeHTML(change.value));\n\n        if (change.added) {\n          ret.push('</ins>');\n        } else if (change.removed) {\n          ret.push('</del>');\n        }\n      }\n      return ret.join('');\n    },\n\n    // See: http://code.google.com/p/google-diff-match-patch/wiki/API\n    convertChangesToDMP: function(changes) {\n      var ret = [],\n          change,\n          operation;\n      for (var i = 0; i < changes.length; i++) {\n        change = changes[i];\n        if (change.added) {\n          operation = 1;\n        } else if (change.removed) {\n          operation = -1;\n        } else {\n          operation = 0;\n        }\n\n        ret.push([operation, change.value]);\n      }\n      return ret;\n    },\n\n    canonicalize: canonicalize\n  };\n\n  /*istanbul ignore next */\n  /*global module */\n  if (typeof module !== 'undefined' && module.exports) {\n    module.exports = JsDiff;\n  } else if (false) {\n    /*global define */\n    define([], function() { return JsDiff; });\n  } else if (typeof global.JsDiff === 'undefined') {\n    global.JsDiff = JsDiff;\n  }\n}(this));\n\n},{}],47:[function(require,module,exports){\n'use strict';\n\nvar matchOperatorsRe = /[|\\\\{}()[\\]^$+*?.]/g;\n\nmodule.exports = function (str) {\n\tif (typeof str !== 'string') {\n\t\tthrow new TypeError('Expected a string');\n\t}\n\n\treturn str.replace(matchOperatorsRe, '\\\\$&');\n};\n\n},{}],48:[function(require,module,exports){\n// Copyright Joyent, Inc. and other Node contributors.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a\n// copy of this software and associated documentation files (the\n// \"Software\"), to deal in the Software without restriction, including\n// without limitation the rights to use, copy, modify, merge, publish,\n// distribute, sublicense, and/or sell copies of the Software, and to permit\n// persons to whom the Software is furnished to do so, subject to the\n// following conditions:\n//\n// The above copyright notice and this permission notice shall be included\n// in all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS\n// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN\n// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,\n// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE\n// USE OR OTHER DEALINGS IN THE SOFTWARE.\n\nfunction EventEmitter() {\n  this._events = this._events || {};\n  this._maxListeners = this._maxListeners || undefined;\n}\nmodule.exports = EventEmitter;\n\n// Backwards-compat with node 0.10.x\nEventEmitter.EventEmitter = EventEmitter;\n\nEventEmitter.prototype._events = undefined;\nEventEmitter.prototype._maxListeners = undefined;\n\n// By default EventEmitters will print a warning if more than 10 listeners are\n// added to it. This is a useful default which helps finding memory leaks.\nEventEmitter.defaultMaxListeners = 10;\n\n// Obviously not all Emitters should be limited to 10. This function allows\n// that to be increased. Set to zero for unlimited.\nEventEmitter.prototype.setMaxListeners = function(n) {\n  if (!isNumber(n) || n < 0 || isNaN(n))\n    throw TypeError('n must be a positive number');\n  this._maxListeners = n;\n  return this;\n};\n\nEventEmitter.prototype.emit = function(type) {\n  var er, handler, len, args, i, listeners;\n\n  if (!this._events)\n    this._events = {};\n\n  // If there is no 'error' event listener then throw.\n  if (type === 'error') {\n    if (!this._events.error ||\n        (isObject(this._events.error) && !this._events.error.length)) {\n      er = arguments[1];\n      if (er instanceof Error) {\n        throw er; // Unhandled 'error' event\n      } else {\n        // At least give some kind of context to the user\n        var err = new Error('Uncaught, unspecified \"error\" event. (' + er + ')');\n        err.context = er;\n        throw err;\n      }\n    }\n  }\n\n  handler = this._events[type];\n\n  if (isUndefined(handler))\n    return false;\n\n  if (isFunction(handler)) {\n    switch (arguments.length) {\n      // fast cases\n      case 1:\n        handler.call(this);\n        break;\n      case 2:\n        handler.call(this, arguments[1]);\n        break;\n      case 3:\n        handler.call(this, arguments[1], arguments[2]);\n        break;\n      // slower\n      default:\n        args = Array.prototype.slice.call(arguments, 1);\n        handler.apply(this, args);\n    }\n  } else if (isObject(handler)) {\n    args = Array.prototype.slice.call(arguments, 1);\n    listeners = handler.slice();\n    len = listeners.length;\n    for (i = 0; i < len; i++)\n      listeners[i].apply(this, args);\n  }\n\n  return true;\n};\n\nEventEmitter.prototype.addListener = function(type, listener) {\n  var m;\n\n  if (!isFunction(listener))\n    throw TypeError('listener must be a function');\n\n  if (!this._events)\n    this._events = {};\n\n  // To avoid recursion in the case that type === \"newListener\"! Before\n  // adding it to the listeners, first emit \"newListener\".\n  if (this._events.newListener)\n    this.emit('newListener', type,\n              isFunction(listener.listener) ?\n              listener.listener : listener);\n\n  if (!this._events[type])\n    // Optimize the case of one listener. Don't need the extra array object.\n    this._events[type] = listener;\n  else if (isObject(this._events[type]))\n    // If we've already got an array, just append.\n    this._events[type].push(listener);\n  else\n    // Adding the second element, need to change to array.\n    this._events[type] = [this._events[type], listener];\n\n  // Check for listener leak\n  if (isObject(this._events[type]) && !this._events[type].warned) {\n    if (!isUndefined(this._maxListeners)) {\n      m = this._maxListeners;\n    } else {\n      m = EventEmitter.defaultMaxListeners;\n    }\n\n    if (m && m > 0 && this._events[type].length > m) {\n      this._events[type].warned = true;\n      console.error('(node) warning: possible EventEmitter memory ' +\n                    'leak detected. %d listeners added. ' +\n                    'Use emitter.setMaxListeners() to increase limit.',\n                    this._events[type].length);\n      if (typeof console.trace === 'function') {\n        // not supported in IE 10\n        console.trace();\n      }\n    }\n  }\n\n  return this;\n};\n\nEventEmitter.prototype.on = EventEmitter.prototype.addListener;\n\nEventEmitter.prototype.once = function(type, listener) {\n  if (!isFunction(listener))\n    throw TypeError('listener must be a function');\n\n  var fired = false;\n\n  function g() {\n    this.removeListener(type, g);\n\n    if (!fired) {\n      fired = true;\n      listener.apply(this, arguments);\n    }\n  }\n\n  g.listener = listener;\n  this.on(type, g);\n\n  return this;\n};\n\n// emits a 'removeListener' event iff the listener was removed\nEventEmitter.prototype.removeListener = function(type, listener) {\n  var list, position, length, i;\n\n  if (!isFunction(listener))\n    throw TypeError('listener must be a function');\n\n  if (!this._events || !this._events[type])\n    return this;\n\n  list = this._events[type];\n  length = list.length;\n  position = -1;\n\n  if (list === listener ||\n      (isFunction(list.listener) && list.listener === listener)) {\n    delete this._events[type];\n    if (this._events.removeListener)\n      this.emit('removeListener', type, listener);\n\n  } else if (isObject(list)) {\n    for (i = length; i-- > 0;) {\n      if (list[i] === listener ||\n          (list[i].listener && list[i].listener === listener)) {\n        position = i;\n        break;\n      }\n    }\n\n    if (position < 0)\n      return this;\n\n    if (list.length === 1) {\n      list.length = 0;\n      delete this._events[type];\n    } else {\n      list.splice(position, 1);\n    }\n\n    if (this._events.removeListener)\n      this.emit('removeListener', type, listener);\n  }\n\n  return this;\n};\n\nEventEmitter.prototype.removeAllListeners = function(type) {\n  var key, listeners;\n\n  if (!this._events)\n    return this;\n\n  // not listening for removeListener, no need to emit\n  if (!this._events.removeListener) {\n    if (arguments.length === 0)\n      this._events = {};\n    else if (this._events[type])\n      delete this._events[type];\n    return this;\n  }\n\n  // emit removeListener for all listeners on all events\n  if (arguments.length === 0) {\n    for (key in this._events) {\n      if (key === 'removeListener') continue;\n      this.removeAllListeners(key);\n    }\n    this.removeAllListeners('removeListener');\n    this._events = {};\n    return this;\n  }\n\n  listeners = this._events[type];\n\n  if (isFunction(listeners)) {\n    this.removeListener(type, listeners);\n  } else if (listeners) {\n    // LIFO order\n    while (listeners.length)\n      this.removeListener(type, listeners[listeners.length - 1]);\n  }\n  delete this._events[type];\n\n  return this;\n};\n\nEventEmitter.prototype.listeners = function(type) {\n  var ret;\n  if (!this._events || !this._events[type])\n    ret = [];\n  else if (isFunction(this._events[type]))\n    ret = [this._events[type]];\n  else\n    ret = this._events[type].slice();\n  return ret;\n};\n\nEventEmitter.prototype.listenerCount = function(type) {\n  if (this._events) {\n    var evlistener = this._events[type];\n\n    if (isFunction(evlistener))\n      return 1;\n    else if (evlistener)\n      return evlistener.length;\n  }\n  return 0;\n};\n\nEventEmitter.listenerCount = function(emitter, type) {\n  return emitter.listenerCount(type);\n};\n\nfunction isFunction(arg) {\n  return typeof arg === 'function';\n}\n\nfunction isNumber(arg) {\n  return typeof arg === 'number';\n}\n\nfunction isObject(arg) {\n  return typeof arg === 'object' && arg !== null;\n}\n\nfunction isUndefined(arg) {\n  return arg === void 0;\n}\n\n},{}],49:[function(require,module,exports){\n(function (process){\n// Growl - Copyright TJ Holowaychuk <tj@vision-media.ca> (MIT Licensed)\n\n/**\n * Module dependencies.\n */\n\nvar exec = require('child_process').exec\n  , fs = require('fs')\n  , path = require('path')\n  , exists = fs.existsSync || path.existsSync\n  , os = require('os')\n  , quote = JSON.stringify\n  , cmd;\n\nfunction which(name) {\n  var paths = process.env.PATH.split(':');\n  var loc;\n\n  for (var i = 0, len = paths.length; i < len; ++i) {\n    loc = path.join(paths[i], name);\n    if (exists(loc)) return loc;\n  }\n}\n\nswitch(os.type()) {\n  case 'Darwin':\n    if (which('terminal-notifier')) {\n      cmd = {\n          type: \"Darwin-NotificationCenter\"\n        , pkg: \"terminal-notifier\"\n        , msg: '-message'\n        , title: '-title'\n        , subtitle: '-subtitle'\n        , icon: '-appIcon'\n        , sound:  '-sound'\n        , url: '-open'\n        , priority: {\n              cmd: '-execute'\n            , range: []\n          }\n      };\n    } else {\n      cmd = {\n          type: \"Darwin-Growl\"\n        , pkg: \"growlnotify\"\n        , msg: '-m'\n        , sticky: '--sticky'\n        , priority: {\n              cmd: '--priority'\n            , range: [\n                -2\n              , -1\n              , 0\n              , 1\n              , 2\n              , \"Very Low\"\n              , \"Moderate\"\n              , \"Normal\"\n              , \"High\"\n              , \"Emergency\"\n            ]\n          }\n      };\n    }\n    break;\n  case 'Linux':\n    if (which('growl')) {\n      cmd = {\n          type: \"Linux-Growl\"\n        , pkg: \"growl\"\n        , msg: '-m'\n        , title: '-title'\n        , subtitle: '-subtitle'\n        , host: {\n            cmd: '-H'\n          , hostname: '192.168.33.1'\n        }\n      };\n    } else {\n      cmd = {\n          type: \"Linux\"\n        , pkg: \"notify-send\"\n        , msg: ''\n        , sticky: '-t 0'\n        , icon: '-i'\n        , priority: {\n            cmd: '-u'\n          , range: [\n              \"low\"\n            , \"normal\"\n            , \"critical\"\n          ]\n        }\n      };\n    }\n    break;\n  case 'Windows_NT':\n    cmd = {\n        type: \"Windows\"\n      , pkg: \"growlnotify\"\n      , msg: ''\n      , sticky: '/s:true'\n      , title: '/t:'\n      , icon: '/i:'\n      , url: '/cu:'\n      , priority: {\n            cmd: '/p:'\n          , range: [\n              -2\n            , -1\n            , 0\n            , 1\n            , 2\n          ]\n        }\n    };\n    break;\n}\n\n/**\n * Expose `growl`.\n */\n\nexports = module.exports = growl;\n\n/**\n * Node-growl version.\n */\n\nexports.version = '1.4.1'\n\n/**\n * Send growl notification _msg_ with _options_.\n *\n * Options:\n *\n *  - title   Notification title\n *  - sticky  Make the notification stick (defaults to false)\n *  - priority  Specify an int or named key (default is 0)\n *  - name    Application name (defaults to growlnotify)\n *  - sound   Sound efect ( in OSx defined in preferences -> sound -> effects) * works only in OSX > 10.8x\n *  - image\n *    - path to an icon sets --iconpath\n *    - path to an image sets --image\n *    - capitalized word sets --appIcon\n *    - filename uses extname as --icon\n *    - otherwise treated as --icon\n *\n * Examples:\n *\n *   growl('New email')\n *   growl('5 new emails', { title: 'Thunderbird' })\n *   growl('5 new emails', { title: 'Thunderbird', sound: 'Purr' })\n *   growl('Email sent', function(){\n *     // ... notification sent\n *   })\n *\n * @param {string} msg\n * @param {object} options\n * @param {function} fn\n * @api public\n */\n\nfunction growl(msg, options, fn) {\n  var image\n    , args\n    , options = options || {}\n    , fn = fn || function(){};\n\n  if (options.exec) {\n    cmd = {\n        type: \"Custom\"\n      , pkg: options.exec\n      , range: []\n    };\n  }\n\n  // noop\n  if (!cmd) return fn(new Error('growl not supported on this platform'));\n  args = [cmd.pkg];\n\n  // image\n  if (image = options.image) {\n    switch(cmd.type) {\n      case 'Darwin-Growl':\n        var flag, ext = path.extname(image).substr(1)\n        flag = flag || ext == 'icns' && 'iconpath'\n        flag = flag || /^[A-Z]/.test(image) && 'appIcon'\n        flag = flag || /^png|gif|jpe?g$/.test(ext) && 'image'\n        flag = flag || ext && (image = ext) && 'icon'\n        flag = flag || 'icon'\n        args.push('--' + flag, quote(image))\n        break;\n      case 'Darwin-NotificationCenter':\n        args.push(cmd.icon, quote(image));\n        break;\n      case 'Linux':\n        args.push(cmd.icon, quote(image));\n        // libnotify defaults to sticky, set a hint for transient notifications\n        if (!options.sticky) args.push('--hint=int:transient:1');\n        break;\n      case 'Windows':\n        args.push(cmd.icon + quote(image));\n        break;\n    }\n  }\n\n  // sticky\n  if (options.sticky) args.push(cmd.sticky);\n\n  // priority\n  if (options.priority) {\n    var priority = options.priority + '';\n    var checkindexOf = cmd.priority.range.indexOf(priority);\n    if (~cmd.priority.range.indexOf(priority)) {\n      args.push(cmd.priority, options.priority);\n    }\n  }\n\n  //sound\n  if(options.sound && cmd.type === 'Darwin-NotificationCenter'){\n    args.push(cmd.sound, options.sound)\n  }\n\n  // name\n  if (options.name && cmd.type === \"Darwin-Growl\") {\n    args.push('--name', options.name);\n  }\n\n  switch(cmd.type) {\n    case 'Darwin-Growl':\n      args.push(cmd.msg);\n      args.push(quote(msg).replace(/\\\\n/g, '\\n'));\n      if (options.title) args.push(quote(options.title));\n      break;\n    case 'Darwin-NotificationCenter':\n      args.push(cmd.msg);\n      var stringifiedMsg = quote(msg);\n      var escapedMsg = stringifiedMsg.replace(/\\\\n/g, '\\n');\n      args.push(escapedMsg);\n      if (options.title) {\n        args.push(cmd.title);\n        args.push(quote(options.title));\n      }\n      if (options.subtitle) {\n        args.push(cmd.subtitle);\n        args.push(quote(options.subtitle));\n      }\n      if (options.url) {\n        args.push(cmd.url);\n        args.push(quote(options.url));\n      }\n      break;\n    case 'Linux-Growl':\n      args.push(cmd.msg);\n      args.push(quote(msg).replace(/\\\\n/g, '\\n'));\n      if (options.title) args.push(quote(options.title));\n      if (cmd.host) {\n        args.push(cmd.host.cmd, cmd.host.hostname)\n      }\n      break;\n    case 'Linux':\n      if (options.title) {\n        args.push(quote(options.title));\n        args.push(cmd.msg);\n        args.push(quote(msg).replace(/\\\\n/g, '\\n'));\n      } else {\n        args.push(quote(msg).replace(/\\\\n/g, '\\n'));\n      }\n      break;\n    case 'Windows':\n      args.push(quote(msg).replace(/\\\\n/g, '\\n'));\n      if (options.title) args.push(cmd.title + quote(options.title));\n      if (options.url) args.push(cmd.url + quote(options.url));\n      break;\n    case 'Custom':\n      args[0] = (function(origCommand) {\n        var message = options.title\n          ? options.title + ': ' + msg\n          : msg;\n        var command = origCommand.replace(/(^|[^%])%s/g, '$1' + quote(message));\n        if (command === origCommand) args.push(quote(message));\n        return command;\n      })(args[0]);\n      break;\n  }\n\n  // execute\n  exec(args.join(' '), fn);\n};\n\n}).call(this,require('_process'))\n},{\"_process\":67,\"child_process\":42,\"fs\":42,\"os\":65,\"path\":42}],50:[function(require,module,exports){\nexports.read = function (buffer, offset, isLE, mLen, nBytes) {\n  var e, m\n  var eLen = nBytes * 8 - mLen - 1\n  var eMax = (1 << eLen) - 1\n  var eBias = eMax >> 1\n  var nBits = -7\n  var i = isLE ? (nBytes - 1) : 0\n  var d = isLE ? -1 : 1\n  var s = buffer[offset + i]\n\n  i += d\n\n  e = s & ((1 << (-nBits)) - 1)\n  s >>= (-nBits)\n  nBits += eLen\n  for (; nBits > 0; e = e * 256 + buffer[offset + i], i += d, nBits -= 8) {}\n\n  m = e & ((1 << (-nBits)) - 1)\n  e >>= (-nBits)\n  nBits += mLen\n  for (; nBits > 0; m = m * 256 + buffer[offset + i], i += d, nBits -= 8) {}\n\n  if (e === 0) {\n    e = 1 - eBias\n  } else if (e === eMax) {\n    return m ? NaN : ((s ? -1 : 1) * Infinity)\n  } else {\n    m = m + Math.pow(2, mLen)\n    e = e - eBias\n  }\n  return (s ? -1 : 1) * m * Math.pow(2, e - mLen)\n}\n\nexports.write = function (buffer, value, offset, isLE, mLen, nBytes) {\n  var e, m, c\n  var eLen = nBytes * 8 - mLen - 1\n  var eMax = (1 << eLen) - 1\n  var eBias = eMax >> 1\n  var rt = (mLen === 23 ? Math.pow(2, -24) - Math.pow(2, -77) : 0)\n  var i = isLE ? 0 : (nBytes - 1)\n  var d = isLE ? 1 : -1\n  var s = value < 0 || (value === 0 && 1 / value < 0) ? 1 : 0\n\n  value = Math.abs(value)\n\n  if (isNaN(value) || value === Infinity) {\n    m = isNaN(value) ? 1 : 0\n    e = eMax\n  } else {\n    e = Math.floor(Math.log(value) / Math.LN2)\n    if (value * (c = Math.pow(2, -e)) < 1) {\n      e--\n      c *= 2\n    }\n    if (e + eBias >= 1) {\n      value += rt / c\n    } else {\n      value += rt * Math.pow(2, 1 - eBias)\n    }\n    if (value * c >= 2) {\n      e++\n      c /= 2\n    }\n\n    if (e + eBias >= eMax) {\n      m = 0\n      e = eMax\n    } else if (e + eBias >= 1) {\n      m = (value * c - 1) * Math.pow(2, mLen)\n      e = e + eBias\n    } else {\n      m = value * Math.pow(2, eBias - 1) * Math.pow(2, mLen)\n      e = 0\n    }\n  }\n\n  for (; mLen >= 8; buffer[offset + i] = m & 0xff, i += d, m /= 256, mLen -= 8) {}\n\n  e = (e << mLen) | m\n  eLen += mLen\n  for (; eLen > 0; buffer[offset + i] = e & 0xff, i += d, e /= 256, eLen -= 8) {}\n\n  buffer[offset + i - d] |= s * 128\n}\n\n},{}],51:[function(require,module,exports){\nif (typeof Object.create === 'function') {\n  // implementation from standard node.js 'util' module\n  module.exports = function inherits(ctor, superCtor) {\n    ctor.super_ = superCtor\n    ctor.prototype = Object.create(superCtor.prototype, {\n      constructor: {\n        value: ctor,\n        enumerable: false,\n        writable: true,\n        configurable: true\n      }\n    });\n  };\n} else {\n  // old school shim for old browsers\n  module.exports = function inherits(ctor, superCtor) {\n    ctor.super_ = superCtor\n    var TempCtor = function () {}\n    TempCtor.prototype = superCtor.prototype\n    ctor.prototype = new TempCtor()\n    ctor.prototype.constructor = ctor\n  }\n}\n\n},{}],52:[function(require,module,exports){\n/*!\n * Determine if an object is a Buffer\n *\n * @author   Feross Aboukhadijeh <feross@feross.org> <http://feross.org>\n * @license  MIT\n */\n\n// The _isBuffer check is for Safari 5-7 support, because it's missing\n// Object.prototype.constructor. Remove this eventually\nmodule.exports = function (obj) {\n  return obj != null && (isBuffer(obj) || isSlowBuffer(obj) || !!obj._isBuffer)\n}\n\nfunction isBuffer (obj) {\n  return !!obj.constructor && typeof obj.constructor.isBuffer === 'function' && obj.constructor.isBuffer(obj)\n}\n\n// For Node v0.10 support. Remove this eventually.\nfunction isSlowBuffer (obj) {\n  return typeof obj.readFloatLE === 'function' && typeof obj.slice === 'function' && isBuffer(obj.slice(0, 0))\n}\n\n},{}],53:[function(require,module,exports){\nvar toString = {}.toString;\n\nmodule.exports = Array.isArray || function (arr) {\n  return toString.call(arr) == '[object Array]';\n};\n\n},{}],54:[function(require,module,exports){\n(function (global){\n/*! JSON v3.3.2 | http://bestiejs.github.io/json3 | Copyright 2012-2014, Kit Cambridge | http://kit.mit-license.org */\n;(function () {\n  // Detect the `define` function exposed by asynchronous module loaders. The\n  // strict `define` check is necessary for compatibility with `r.js`.\n  var isLoader = false;\n\n  // A set of types used to distinguish objects from primitives.\n  var objectTypes = {\n    \"function\": true,\n    \"object\": true\n  };\n\n  // Detect the `exports` object exposed by CommonJS implementations.\n  var freeExports = objectTypes[typeof exports] && exports && !exports.nodeType && exports;\n\n  // Use the `global` object exposed by Node (including Browserify via\n  // `insert-module-globals`), Narwhal, and Ringo as the default context,\n  // and the `window` object in browsers. Rhino exports a `global` function\n  // instead.\n  var root = objectTypes[typeof window] && window || this,\n      freeGlobal = freeExports && objectTypes[typeof module] && module && !module.nodeType && typeof global == \"object\" && global;\n\n  if (freeGlobal && (freeGlobal[\"global\"] === freeGlobal || freeGlobal[\"window\"] === freeGlobal || freeGlobal[\"self\"] === freeGlobal)) {\n    root = freeGlobal;\n  }\n\n  // Public: Initializes JSON 3 using the given `context` object, attaching the\n  // `stringify` and `parse` functions to the specified `exports` object.\n  function runInContext(context, exports) {\n    context || (context = root[\"Object\"]());\n    exports || (exports = root[\"Object\"]());\n\n    // Native constructor aliases.\n    var Number = context[\"Number\"] || root[\"Number\"],\n        String = context[\"String\"] || root[\"String\"],\n        Object = context[\"Object\"] || root[\"Object\"],\n        Date = context[\"Date\"] || root[\"Date\"],\n        SyntaxError = context[\"SyntaxError\"] || root[\"SyntaxError\"],\n        TypeError = context[\"TypeError\"] || root[\"TypeError\"],\n        Math = context[\"Math\"] || root[\"Math\"],\n        nativeJSON = context[\"JSON\"] || root[\"JSON\"];\n\n    // Delegate to the native `stringify` and `parse` implementations.\n    if (typeof nativeJSON == \"object\" && nativeJSON) {\n      exports.stringify = nativeJSON.stringify;\n      exports.parse = nativeJSON.parse;\n    }\n\n    // Convenience aliases.\n    var objectProto = Object.prototype,\n        getClass = objectProto.toString,\n        isProperty, forEach, undef;\n\n    // Test the `Date#getUTC*` methods. Based on work by @Yaffle.\n    var isExtended = new Date(-3509827334573292);\n    try {\n      // The `getUTCFullYear`, `Month`, and `Date` methods return nonsensical\n      // results for certain dates in Opera >= 10.53.\n      isExtended = isExtended.getUTCFullYear() == -109252 && isExtended.getUTCMonth() === 0 && isExtended.getUTCDate() === 1 &&\n        // Safari < 2.0.2 stores the internal millisecond time value correctly,\n        // but clips the values returned by the date methods to the range of\n        // signed 32-bit integers ([-2 ** 31, 2 ** 31 - 1]).\n        isExtended.getUTCHours() == 10 && isExtended.getUTCMinutes() == 37 && isExtended.getUTCSeconds() == 6 && isExtended.getUTCMilliseconds() == 708;\n    } catch (exception) {}\n\n    // Internal: Determines whether the native `JSON.stringify` and `parse`\n    // implementations are spec-compliant. Based on work by Ken Snyder.\n    function has(name) {\n      if (has[name] !== undef) {\n        // Return cached feature test result.\n        return has[name];\n      }\n      var isSupported;\n      if (name == \"bug-string-char-index\") {\n        // IE <= 7 doesn't support accessing string characters using square\n        // bracket notation. IE 8 only supports this for primitives.\n        isSupported = \"a\"[0] != \"a\";\n      } else if (name == \"json\") {\n        // Indicates whether both `JSON.stringify` and `JSON.parse` are\n        // supported.\n        isSupported = has(\"json-stringify\") && has(\"json-parse\");\n      } else {\n        var value, serialized = '{\"a\":[1,true,false,null,\"\\\\u0000\\\\b\\\\n\\\\f\\\\r\\\\t\"]}';\n        // Test `JSON.stringify`.\n        if (name == \"json-stringify\") {\n          var stringify = exports.stringify, stringifySupported = typeof stringify == \"function\" && isExtended;\n          if (stringifySupported) {\n            // A test function object with a custom `toJSON` method.\n            (value = function () {\n              return 1;\n            }).toJSON = value;\n            try {\n              stringifySupported =\n                // Firefox 3.1b1 and b2 serialize string, number, and boolean\n                // primitives as object literals.\n                stringify(0) === \"0\" &&\n                // FF 3.1b1, b2, and JSON 2 serialize wrapped primitives as object\n                // literals.\n                stringify(new Number()) === \"0\" &&\n                stringify(new String()) == '\"\"' &&\n                // FF 3.1b1, 2 throw an error if the value is `null`, `undefined`, or\n                // does not define a canonical JSON representation (this applies to\n                // objects with `toJSON` properties as well, *unless* they are nested\n                // within an object or array).\n                stringify(getClass) === undef &&\n                // IE 8 serializes `undefined` as `\"undefined\"`. Safari <= 5.1.7 and\n                // FF 3.1b3 pass this test.\n                stringify(undef) === undef &&\n                // Safari <= 5.1.7 and FF 3.1b3 throw `Error`s and `TypeError`s,\n                // respectively, if the value is omitted entirely.\n                stringify() === undef &&\n                // FF 3.1b1, 2 throw an error if the given value is not a number,\n                // string, array, object, Boolean, or `null` literal. This applies to\n                // objects with custom `toJSON` methods as well, unless they are nested\n                // inside object or array literals. YUI 3.0.0b1 ignores custom `toJSON`\n                // methods entirely.\n                stringify(value) === \"1\" &&\n                stringify([value]) == \"[1]\" &&\n                // Prototype <= 1.6.1 serializes `[undefined]` as `\"[]\"` instead of\n                // `\"[null]\"`.\n                stringify([undef]) == \"[null]\" &&\n                // YUI 3.0.0b1 fails to serialize `null` literals.\n                stringify(null) == \"null\" &&\n                // FF 3.1b1, 2 halts serialization if an array contains a function:\n                // `[1, true, getClass, 1]` serializes as \"[1,true,],\". FF 3.1b3\n                // elides non-JSON values from objects and arrays, unless they\n                // define custom `toJSON` methods.\n                stringify([undef, getClass, null]) == \"[null,null,null]\" &&\n                // Simple serialization test. FF 3.1b1 uses Unicode escape sequences\n                // where character escape codes are expected (e.g., `\\b` => `\\u0008`).\n                stringify({ \"a\": [value, true, false, null, \"\\x00\\b\\n\\f\\r\\t\"] }) == serialized &&\n                // FF 3.1b1 and b2 ignore the `filter` and `width` arguments.\n                stringify(null, value) === \"1\" &&\n                stringify([1, 2], null, 1) == \"[\\n 1,\\n 2\\n]\" &&\n                // JSON 2, Prototype <= 1.7, and older WebKit builds incorrectly\n                // serialize extended years.\n                stringify(new Date(-8.64e15)) == '\"-271821-04-20T00:00:00.000Z\"' &&\n                // The milliseconds are optional in ES 5, but required in 5.1.\n                stringify(new Date(8.64e15)) == '\"+275760-09-13T00:00:00.000Z\"' &&\n                // Firefox <= 11.0 incorrectly serializes years prior to 0 as negative\n                // four-digit years instead of six-digit years. Credits: @Yaffle.\n                stringify(new Date(-621987552e5)) == '\"-000001-01-01T00:00:00.000Z\"' &&\n                // Safari <= 5.1.5 and Opera >= 10.53 incorrectly serialize millisecond\n                // values less than 1000. Credits: @Yaffle.\n                stringify(new Date(-1)) == '\"1969-12-31T23:59:59.999Z\"';\n            } catch (exception) {\n              stringifySupported = false;\n            }\n          }\n          isSupported = stringifySupported;\n        }\n        // Test `JSON.parse`.\n        if (name == \"json-parse\") {\n          var parse = exports.parse;\n          if (typeof parse == \"function\") {\n            try {\n              // FF 3.1b1, b2 will throw an exception if a bare literal is provided.\n              // Conforming implementations should also coerce the initial argument to\n              // a string prior to parsing.\n              if (parse(\"0\") === 0 && !parse(false)) {\n                // Simple parsing test.\n                value = parse(serialized);\n                var parseSupported = value[\"a\"].length == 5 && value[\"a\"][0] === 1;\n                if (parseSupported) {\n                  try {\n                    // Safari <= 5.1.2 and FF 3.1b1 allow unescaped tabs in strings.\n                    parseSupported = !parse('\"\\t\"');\n                  } catch (exception) {}\n                  if (parseSupported) {\n                    try {\n                      // FF 4.0 and 4.0.1 allow leading `+` signs and leading\n                      // decimal points. FF 4.0, 4.0.1, and IE 9-10 also allow\n                      // certain octal literals.\n                      parseSupported = parse(\"01\") !== 1;\n                    } catch (exception) {}\n                  }\n                  if (parseSupported) {\n                    try {\n                      // FF 4.0, 4.0.1, and Rhino 1.7R3-R4 allow trailing decimal\n                      // points. These environments, along with FF 3.1b1 and 2,\n                      // also allow trailing commas in JSON objects and arrays.\n                      parseSupported = parse(\"1.\") !== 1;\n                    } catch (exception) {}\n                  }\n                }\n              }\n            } catch (exception) {\n              parseSupported = false;\n            }\n          }\n          isSupported = parseSupported;\n        }\n      }\n      return has[name] = !!isSupported;\n    }\n\n    if (!has(\"json\")) {\n      // Common `[[Class]]` name aliases.\n      var functionClass = \"[object Function]\",\n          dateClass = \"[object Date]\",\n          numberClass = \"[object Number]\",\n          stringClass = \"[object String]\",\n          arrayClass = \"[object Array]\",\n          booleanClass = \"[object Boolean]\";\n\n      // Detect incomplete support for accessing string characters by index.\n      var charIndexBuggy = has(\"bug-string-char-index\");\n\n      // Define additional utility methods if the `Date` methods are buggy.\n      if (!isExtended) {\n        var floor = Math.floor;\n        // A mapping between the months of the year and the number of days between\n        // January 1st and the first of the respective month.\n        var Months = [0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334];\n        // Internal: Calculates the number of days between the Unix epoch and the\n        // first day of the given month.\n        var getDay = function (year, month) {\n          return Months[month] + 365 * (year - 1970) + floor((year - 1969 + (month = +(month > 1))) / 4) - floor((year - 1901 + month) / 100) + floor((year - 1601 + month) / 400);\n        };\n      }\n\n      // Internal: Determines if a property is a direct property of the given\n      // object. Delegates to the native `Object#hasOwnProperty` method.\n      if (!(isProperty = objectProto.hasOwnProperty)) {\n        isProperty = function (property) {\n          var members = {}, constructor;\n          if ((members.__proto__ = null, members.__proto__ = {\n            // The *proto* property cannot be set multiple times in recent\n            // versions of Firefox and SeaMonkey.\n            \"toString\": 1\n          }, members).toString != getClass) {\n            // Safari <= 2.0.3 doesn't implement `Object#hasOwnProperty`, but\n            // supports the mutable *proto* property.\n            isProperty = function (property) {\n              // Capture and break the object's prototype chain (see section 8.6.2\n              // of the ES 5.1 spec). The parenthesized expression prevents an\n              // unsafe transformation by the Closure Compiler.\n              var original = this.__proto__, result = property in (this.__proto__ = null, this);\n              // Restore the original prototype chain.\n              this.__proto__ = original;\n              return result;\n            };\n          } else {\n            // Capture a reference to the top-level `Object` constructor.\n            constructor = members.constructor;\n            // Use the `constructor` property to simulate `Object#hasOwnProperty` in\n            // other environments.\n            isProperty = function (property) {\n              var parent = (this.constructor || constructor).prototype;\n              return property in this && !(property in parent && this[property] === parent[property]);\n            };\n          }\n          members = null;\n          return isProperty.call(this, property);\n        };\n      }\n\n      // Internal: Normalizes the `for...in` iteration algorithm across\n      // environments. Each enumerated key is yielded to a `callback` function.\n      forEach = function (object, callback) {\n        var size = 0, Properties, members, property;\n\n        // Tests for bugs in the current environment's `for...in` algorithm. The\n        // `valueOf` property inherits the non-enumerable flag from\n        // `Object.prototype` in older versions of IE, Netscape, and Mozilla.\n        (Properties = function () {\n          this.valueOf = 0;\n        }).prototype.valueOf = 0;\n\n        // Iterate over a new instance of the `Properties` class.\n        members = new Properties();\n        for (property in members) {\n          // Ignore all properties inherited from `Object.prototype`.\n          if (isProperty.call(members, property)) {\n            size++;\n          }\n        }\n        Properties = members = null;\n\n        // Normalize the iteration algorithm.\n        if (!size) {\n          // A list of non-enumerable properties inherited from `Object.prototype`.\n          members = [\"valueOf\", \"toString\", \"toLocaleString\", \"propertyIsEnumerable\", \"isPrototypeOf\", \"hasOwnProperty\", \"constructor\"];\n          // IE <= 8, Mozilla 1.0, and Netscape 6.2 ignore shadowed non-enumerable\n          // properties.\n          forEach = function (object, callback) {\n            var isFunction = getClass.call(object) == functionClass, property, length;\n            var hasProperty = !isFunction && typeof object.constructor != \"function\" && objectTypes[typeof object.hasOwnProperty] && object.hasOwnProperty || isProperty;\n            for (property in object) {\n              // Gecko <= 1.0 enumerates the `prototype` property of functions under\n              // certain conditions; IE does not.\n              if (!(isFunction && property == \"prototype\") && hasProperty.call(object, property)) {\n                callback(property);\n              }\n            }\n            // Manually invoke the callback for each non-enumerable property.\n            for (length = members.length; property = members[--length]; hasProperty.call(object, property) && callback(property));\n          };\n        } else if (size == 2) {\n          // Safari <= 2.0.4 enumerates shadowed properties twice.\n          forEach = function (object, callback) {\n            // Create a set of iterated properties.\n            var members = {}, isFunction = getClass.call(object) == functionClass, property;\n            for (property in object) {\n              // Store each property name to prevent double enumeration. The\n              // `prototype` property of functions is not enumerated due to cross-\n              // environment inconsistencies.\n              if (!(isFunction && property == \"prototype\") && !isProperty.call(members, property) && (members[property] = 1) && isProperty.call(object, property)) {\n                callback(property);\n              }\n            }\n          };\n        } else {\n          // No bugs detected; use the standard `for...in` algorithm.\n          forEach = function (object, callback) {\n            var isFunction = getClass.call(object) == functionClass, property, isConstructor;\n            for (property in object) {\n              if (!(isFunction && property == \"prototype\") && isProperty.call(object, property) && !(isConstructor = property === \"constructor\")) {\n                callback(property);\n              }\n            }\n            // Manually invoke the callback for the `constructor` property due to\n            // cross-environment inconsistencies.\n            if (isConstructor || isProperty.call(object, (property = \"constructor\"))) {\n              callback(property);\n            }\n          };\n        }\n        return forEach(object, callback);\n      };\n\n      // Public: Serializes a JavaScript `value` as a JSON string. The optional\n      // `filter` argument may specify either a function that alters how object and\n      // array members are serialized, or an array of strings and numbers that\n      // indicates which properties should be serialized. The optional `width`\n      // argument may be either a string or number that specifies the indentation\n      // level of the output.\n      if (!has(\"json-stringify\")) {\n        // Internal: A map of control characters and their escaped equivalents.\n        var Escapes = {\n          92: \"\\\\\\\\\",\n          34: '\\\\\"',\n          8: \"\\\\b\",\n          12: \"\\\\f\",\n          10: \"\\\\n\",\n          13: \"\\\\r\",\n          9: \"\\\\t\"\n        };\n\n        // Internal: Converts `value` into a zero-padded string such that its\n        // length is at least equal to `width`. The `width` must be <= 6.\n        var leadingZeroes = \"000000\";\n        var toPaddedString = function (width, value) {\n          // The `|| 0` expression is necessary to work around a bug in\n          // Opera <= 7.54u2 where `0 == -0`, but `String(-0) !== \"0\"`.\n          return (leadingZeroes + (value || 0)).slice(-width);\n        };\n\n        // Internal: Double-quotes a string `value`, replacing all ASCII control\n        // characters (characters with code unit values between 0 and 31) with\n        // their escaped equivalents. This is an implementation of the\n        // `Quote(value)` operation defined in ES 5.1 section 15.12.3.\n        var unicodePrefix = \"\\\\u00\";\n        var quote = function (value) {\n          var result = '\"', index = 0, length = value.length, useCharIndex = !charIndexBuggy || length > 10;\n          var symbols = useCharIndex && (charIndexBuggy ? value.split(\"\") : value);\n          for (; index < length; index++) {\n            var charCode = value.charCodeAt(index);\n            // If the character is a control character, append its Unicode or\n            // shorthand escape sequence; otherwise, append the character as-is.\n            switch (charCode) {\n              case 8: case 9: case 10: case 12: case 13: case 34: case 92:\n                result += Escapes[charCode];\n                break;\n              default:\n                if (charCode < 32) {\n                  result += unicodePrefix + toPaddedString(2, charCode.toString(16));\n                  break;\n                }\n                result += useCharIndex ? symbols[index] : value.charAt(index);\n            }\n          }\n          return result + '\"';\n        };\n\n        // Internal: Recursively serializes an object. Implements the\n        // `Str(key, holder)`, `JO(value)`, and `JA(value)` operations.\n        var serialize = function (property, object, callback, properties, whitespace, indentation, stack) {\n          var value, className, year, month, date, time, hours, minutes, seconds, milliseconds, results, element, index, length, prefix, result;\n          try {\n            // Necessary for host object support.\n            value = object[property];\n          } catch (exception) {}\n          if (typeof value == \"object\" && value) {\n            className = getClass.call(value);\n            if (className == dateClass && !isProperty.call(value, \"toJSON\")) {\n              if (value > -1 / 0 && value < 1 / 0) {\n                // Dates are serialized according to the `Date#toJSON` method\n                // specified in ES 5.1 section 15.9.5.44. See section 15.9.1.15\n                // for the ISO 8601 date time string format.\n                if (getDay) {\n                  // Manually compute the year, month, date, hours, minutes,\n                  // seconds, and milliseconds if the `getUTC*` methods are\n                  // buggy. Adapted from @Yaffle's `date-shim` project.\n                  date = floor(value / 864e5);\n                  for (year = floor(date / 365.2425) + 1970 - 1; getDay(year + 1, 0) <= date; year++);\n                  for (month = floor((date - getDay(year, 0)) / 30.42); getDay(year, month + 1) <= date; month++);\n                  date = 1 + date - getDay(year, month);\n                  // The `time` value specifies the time within the day (see ES\n                  // 5.1 section 15.9.1.2). The formula `(A % B + B) % B` is used\n                  // to compute `A modulo B`, as the `%` operator does not\n                  // correspond to the `modulo` operation for negative numbers.\n                  time = (value % 864e5 + 864e5) % 864e5;\n                  // The hours, minutes, seconds, and milliseconds are obtained by\n                  // decomposing the time within the day. See section 15.9.1.10.\n                  hours = floor(time / 36e5) % 24;\n                  minutes = floor(time / 6e4) % 60;\n                  seconds = floor(time / 1e3) % 60;\n                  milliseconds = time % 1e3;\n                } else {\n                  year = value.getUTCFullYear();\n                  month = value.getUTCMonth();\n                  date = value.getUTCDate();\n                  hours = value.getUTCHours();\n                  minutes = value.getUTCMinutes();\n                  seconds = value.getUTCSeconds();\n                  milliseconds = value.getUTCMilliseconds();\n                }\n                // Serialize extended years correctly.\n                value = (year <= 0 || year >= 1e4 ? (year < 0 ? \"-\" : \"+\") + toPaddedString(6, year < 0 ? -year : year) : toPaddedString(4, year)) +\n                  \"-\" + toPaddedString(2, month + 1) + \"-\" + toPaddedString(2, date) +\n                  // Months, dates, hours, minutes, and seconds should have two\n                  // digits; milliseconds should have three.\n                  \"T\" + toPaddedString(2, hours) + \":\" + toPaddedString(2, minutes) + \":\" + toPaddedString(2, seconds) +\n                  // Milliseconds are optional in ES 5.0, but required in 5.1.\n                  \".\" + toPaddedString(3, milliseconds) + \"Z\";\n              } else {\n                value = null;\n              }\n            } else if (typeof value.toJSON == \"function\" && ((className != numberClass && className != stringClass && className != arrayClass) || isProperty.call(value, \"toJSON\"))) {\n              // Prototype <= 1.6.1 adds non-standard `toJSON` methods to the\n              // `Number`, `String`, `Date`, and `Array` prototypes. JSON 3\n              // ignores all `toJSON` methods on these objects unless they are\n              // defined directly on an instance.\n              value = value.toJSON(property);\n            }\n          }\n          if (callback) {\n            // If a replacement function was provided, call it to obtain the value\n            // for serialization.\n            value = callback.call(object, property, value);\n          }\n          if (value === null) {\n            return \"null\";\n          }\n          className = getClass.call(value);\n          if (className == booleanClass) {\n            // Booleans are represented literally.\n            return \"\" + value;\n          } else if (className == numberClass) {\n            // JSON numbers must be finite. `Infinity` and `NaN` are serialized as\n            // `\"null\"`.\n            return value > -1 / 0 && value < 1 / 0 ? \"\" + value : \"null\";\n          } else if (className == stringClass) {\n            // Strings are double-quoted and escaped.\n            return quote(\"\" + value);\n          }\n          // Recursively serialize objects and arrays.\n          if (typeof value == \"object\") {\n            // Check for cyclic structures. This is a linear search; performance\n            // is inversely proportional to the number of unique nested objects.\n            for (length = stack.length; length--;) {\n              if (stack[length] === value) {\n                // Cyclic structures cannot be serialized by `JSON.stringify`.\n                throw TypeError();\n              }\n            }\n            // Add the object to the stack of traversed objects.\n            stack.push(value);\n            results = [];\n            // Save the current indentation level and indent one additional level.\n            prefix = indentation;\n            indentation += whitespace;\n            if (className == arrayClass) {\n              // Recursively serialize array elements.\n              for (index = 0, length = value.length; index < length; index++) {\n                element = serialize(index, value, callback, properties, whitespace, indentation, stack);\n                results.push(element === undef ? \"null\" : element);\n              }\n              result = results.length ? (whitespace ? \"[\\n\" + indentation + results.join(\",\\n\" + indentation) + \"\\n\" + prefix + \"]\" : (\"[\" + results.join(\",\") + \"]\")) : \"[]\";\n            } else {\n              // Recursively serialize object members. Members are selected from\n              // either a user-specified list of property names, or the object\n              // itself.\n              forEach(properties || value, function (property) {\n                var element = serialize(property, value, callback, properties, whitespace, indentation, stack);\n                if (element !== undef) {\n                  // According to ES 5.1 section 15.12.3: \"If `gap` {whitespace}\n                  // is not the empty string, let `member` {quote(property) + \":\"}\n                  // be the concatenation of `member` and the `space` character.\"\n                  // The \"`space` character\" refers to the literal space\n                  // character, not the `space` {width} argument provided to\n                  // `JSON.stringify`.\n                  results.push(quote(property) + \":\" + (whitespace ? \" \" : \"\") + element);\n                }\n              });\n              result = results.length ? (whitespace ? \"{\\n\" + indentation + results.join(\",\\n\" + indentation) + \"\\n\" + prefix + \"}\" : (\"{\" + results.join(\",\") + \"}\")) : \"{}\";\n            }\n            // Remove the object from the traversed object stack.\n            stack.pop();\n            return result;\n          }\n        };\n\n        // Public: `JSON.stringify`. See ES 5.1 section 15.12.3.\n        exports.stringify = function (source, filter, width) {\n          var whitespace, callback, properties, className;\n          if (objectTypes[typeof filter] && filter) {\n            if ((className = getClass.call(filter)) == functionClass) {\n              callback = filter;\n            } else if (className == arrayClass) {\n              // Convert the property names array into a makeshift set.\n              properties = {};\n              for (var index = 0, length = filter.length, value; index < length; value = filter[index++], ((className = getClass.call(value)), className == stringClass || className == numberClass) && (properties[value] = 1));\n            }\n          }\n          if (width) {\n            if ((className = getClass.call(width)) == numberClass) {\n              // Convert the `width` to an integer and create a string containing\n              // `width` number of space characters.\n              if ((width -= width % 1) > 0) {\n                for (whitespace = \"\", width > 10 && (width = 10); whitespace.length < width; whitespace += \" \");\n              }\n            } else if (className == stringClass) {\n              whitespace = width.length <= 10 ? width : width.slice(0, 10);\n            }\n          }\n          // Opera <= 7.54u2 discards the values associated with empty string keys\n          // (`\"\"`) only if they are used directly within an object member list\n          // (e.g., `!(\"\" in { \"\": 1})`).\n          return serialize(\"\", (value = {}, value[\"\"] = source, value), callback, properties, whitespace, \"\", []);\n        };\n      }\n\n      // Public: Parses a JSON source string.\n      if (!has(\"json-parse\")) {\n        var fromCharCode = String.fromCharCode;\n\n        // Internal: A map of escaped control characters and their unescaped\n        // equivalents.\n        var Unescapes = {\n          92: \"\\\\\",\n          34: '\"',\n          47: \"/\",\n          98: \"\\b\",\n          116: \"\\t\",\n          110: \"\\n\",\n          102: \"\\f\",\n          114: \"\\r\"\n        };\n\n        // Internal: Stores the parser state.\n        var Index, Source;\n\n        // Internal: Resets the parser state and throws a `SyntaxError`.\n        var abort = function () {\n          Index = Source = null;\n          throw SyntaxError();\n        };\n\n        // Internal: Returns the next token, or `\"$\"` if the parser has reached\n        // the end of the source string. A token may be a string, number, `null`\n        // literal, or Boolean literal.\n        var lex = function () {\n          var source = Source, length = source.length, value, begin, position, isSigned, charCode;\n          while (Index < length) {\n            charCode = source.charCodeAt(Index);\n            switch (charCode) {\n              case 9: case 10: case 13: case 32:\n                // Skip whitespace tokens, including tabs, carriage returns, line\n                // feeds, and space characters.\n                Index++;\n                break;\n              case 123: case 125: case 91: case 93: case 58: case 44:\n                // Parse a punctuator token (`{`, `}`, `[`, `]`, `:`, or `,`) at\n                // the current position.\n                value = charIndexBuggy ? source.charAt(Index) : source[Index];\n                Index++;\n                return value;\n              case 34:\n                // `\"` delimits a JSON string; advance to the next character and\n                // begin parsing the string. String tokens are prefixed with the\n                // sentinel `@` character to distinguish them from punctuators and\n                // end-of-string tokens.\n                for (value = \"@\", Index++; Index < length;) {\n                  charCode = source.charCodeAt(Index);\n                  if (charCode < 32) {\n                    // Unescaped ASCII control characters (those with a code unit\n                    // less than the space character) are not permitted.\n                    abort();\n                  } else if (charCode == 92) {\n                    // A reverse solidus (`\\`) marks the beginning of an escaped\n                    // control character (including `\"`, `\\`, and `/`) or Unicode\n                    // escape sequence.\n                    charCode = source.charCodeAt(++Index);\n                    switch (charCode) {\n                      case 92: case 34: case 47: case 98: case 116: case 110: case 102: case 114:\n                        // Revive escaped control characters.\n                        value += Unescapes[charCode];\n                        Index++;\n                        break;\n                      case 117:\n                        // `\\u` marks the beginning of a Unicode escape sequence.\n                        // Advance to the first character and validate the\n                        // four-digit code point.\n                        begin = ++Index;\n                        for (position = Index + 4; Index < position; Index++) {\n                          charCode = source.charCodeAt(Index);\n                          // A valid sequence comprises four hexdigits (case-\n                          // insensitive) that form a single hexadecimal value.\n                          if (!(charCode >= 48 && charCode <= 57 || charCode >= 97 && charCode <= 102 || charCode >= 65 && charCode <= 70)) {\n                            // Invalid Unicode escape sequence.\n                            abort();\n                          }\n                        }\n                        // Revive the escaped character.\n                        value += fromCharCode(\"0x\" + source.slice(begin, Index));\n                        break;\n                      default:\n                        // Invalid escape sequence.\n                        abort();\n                    }\n                  } else {\n                    if (charCode == 34) {\n                      // An unescaped double-quote character marks the end of the\n                      // string.\n                      break;\n                    }\n                    charCode = source.charCodeAt(Index);\n                    begin = Index;\n                    // Optimize for the common case where a string is valid.\n                    while (charCode >= 32 && charCode != 92 && charCode != 34) {\n                      charCode = source.charCodeAt(++Index);\n                    }\n                    // Append the string as-is.\n                    value += source.slice(begin, Index);\n                  }\n                }\n                if (source.charCodeAt(Index) == 34) {\n                  // Advance to the next character and return the revived string.\n                  Index++;\n                  return value;\n                }\n                // Unterminated string.\n                abort();\n              default:\n                // Parse numbers and literals.\n                begin = Index;\n                // Advance past the negative sign, if one is specified.\n                if (charCode == 45) {\n                  isSigned = true;\n                  charCode = source.charCodeAt(++Index);\n                }\n                // Parse an integer or floating-point value.\n                if (charCode >= 48 && charCode <= 57) {\n                  // Leading zeroes are interpreted as octal literals.\n                  if (charCode == 48 && ((charCode = source.charCodeAt(Index + 1)), charCode >= 48 && charCode <= 57)) {\n                    // Illegal octal literal.\n                    abort();\n                  }\n                  isSigned = false;\n                  // Parse the integer component.\n                  for (; Index < length && ((charCode = source.charCodeAt(Index)), charCode >= 48 && charCode <= 57); Index++);\n                  // Floats cannot contain a leading decimal point; however, this\n                  // case is already accounted for by the parser.\n                  if (source.charCodeAt(Index) == 46) {\n                    position = ++Index;\n                    // Parse the decimal component.\n                    for (; position < length && ((charCode = source.charCodeAt(position)), charCode >= 48 && charCode <= 57); position++);\n                    if (position == Index) {\n                      // Illegal trailing decimal.\n                      abort();\n                    }\n                    Index = position;\n                  }\n                  // Parse exponents. The `e` denoting the exponent is\n                  // case-insensitive.\n                  charCode = source.charCodeAt(Index);\n                  if (charCode == 101 || charCode == 69) {\n                    charCode = source.charCodeAt(++Index);\n                    // Skip past the sign following the exponent, if one is\n                    // specified.\n                    if (charCode == 43 || charCode == 45) {\n                      Index++;\n                    }\n                    // Parse the exponential component.\n                    for (position = Index; position < length && ((charCode = source.charCodeAt(position)), charCode >= 48 && charCode <= 57); position++);\n                    if (position == Index) {\n                      // Illegal empty exponent.\n                      abort();\n                    }\n                    Index = position;\n                  }\n                  // Coerce the parsed value to a JavaScript number.\n                  return +source.slice(begin, Index);\n                }\n                // A negative sign may only precede numbers.\n                if (isSigned) {\n                  abort();\n                }\n                // `true`, `false`, and `null` literals.\n                if (source.slice(Index, Index + 4) == \"true\") {\n                  Index += 4;\n                  return true;\n                } else if (source.slice(Index, Index + 5) == \"false\") {\n                  Index += 5;\n                  return false;\n                } else if (source.slice(Index, Index + 4) == \"null\") {\n                  Index += 4;\n                  return null;\n                }\n                // Unrecognized token.\n                abort();\n            }\n          }\n          // Return the sentinel `$` character if the parser has reached the end\n          // of the source string.\n          return \"$\";\n        };\n\n        // Internal: Parses a JSON `value` token.\n        var get = function (value) {\n          var results, hasMembers;\n          if (value == \"$\") {\n            // Unexpected end of input.\n            abort();\n          }\n          if (typeof value == \"string\") {\n            if ((charIndexBuggy ? value.charAt(0) : value[0]) == \"@\") {\n              // Remove the sentinel `@` character.\n              return value.slice(1);\n            }\n            // Parse object and array literals.\n            if (value == \"[\") {\n              // Parses a JSON array, returning a new JavaScript array.\n              results = [];\n              for (;; hasMembers || (hasMembers = true)) {\n                value = lex();\n                // A closing square bracket marks the end of the array literal.\n                if (value == \"]\") {\n                  break;\n                }\n                // If the array literal contains elements, the current token\n                // should be a comma separating the previous element from the\n                // next.\n                if (hasMembers) {\n                  if (value == \",\") {\n                    value = lex();\n                    if (value == \"]\") {\n                      // Unexpected trailing `,` in array literal.\n                      abort();\n                    }\n                  } else {\n                    // A `,` must separate each array element.\n                    abort();\n                  }\n                }\n                // Elisions and leading commas are not permitted.\n                if (value == \",\") {\n                  abort();\n                }\n                results.push(get(value));\n              }\n              return results;\n            } else if (value == \"{\") {\n              // Parses a JSON object, returning a new JavaScript object.\n              results = {};\n              for (;; hasMembers || (hasMembers = true)) {\n                value = lex();\n                // A closing curly brace marks the end of the object literal.\n                if (value == \"}\") {\n                  break;\n                }\n                // If the object literal contains members, the current token\n                // should be a comma separator.\n                if (hasMembers) {\n                  if (value == \",\") {\n                    value = lex();\n                    if (value == \"}\") {\n                      // Unexpected trailing `,` in object literal.\n                      abort();\n                    }\n                  } else {\n                    // A `,` must separate each object member.\n                    abort();\n                  }\n                }\n                // Leading commas are not permitted, object property names must be\n                // double-quoted strings, and a `:` must separate each property\n                // name and value.\n                if (value == \",\" || typeof value != \"string\" || (charIndexBuggy ? value.charAt(0) : value[0]) != \"@\" || lex() != \":\") {\n                  abort();\n                }\n                results[value.slice(1)] = get(lex());\n              }\n              return results;\n            }\n            // Unexpected token encountered.\n            abort();\n          }\n          return value;\n        };\n\n        // Internal: Updates a traversed object member.\n        var update = function (source, property, callback) {\n          var element = walk(source, property, callback);\n          if (element === undef) {\n            delete source[property];\n          } else {\n            source[property] = element;\n          }\n        };\n\n        // Internal: Recursively traverses a parsed JSON object, invoking the\n        // `callback` function for each value. This is an implementation of the\n        // `Walk(holder, name)` operation defined in ES 5.1 section 15.12.2.\n        var walk = function (source, property, callback) {\n          var value = source[property], length;\n          if (typeof value == \"object\" && value) {\n            // `forEach` can't be used to traverse an array in Opera <= 8.54\n            // because its `Object#hasOwnProperty` implementation returns `false`\n            // for array indices (e.g., `![1, 2, 3].hasOwnProperty(\"0\")`).\n            if (getClass.call(value) == arrayClass) {\n              for (length = value.length; length--;) {\n                update(value, length, callback);\n              }\n            } else {\n              forEach(value, function (property) {\n                update(value, property, callback);\n              });\n            }\n          }\n          return callback.call(source, property, value);\n        };\n\n        // Public: `JSON.parse`. See ES 5.1 section 15.12.2.\n        exports.parse = function (source, callback) {\n          var result, value;\n          Index = 0;\n          Source = \"\" + source;\n          result = get(lex());\n          // If a JSON string contains multiple tokens, it is invalid.\n          if (lex() != \"$\") {\n            abort();\n          }\n          // Reset the parser state.\n          Index = Source = null;\n          return callback && getClass.call(callback) == functionClass ? walk((value = {}, value[\"\"] = result, value), \"\", callback) : result;\n        };\n      }\n    }\n\n    exports[\"runInContext\"] = runInContext;\n    return exports;\n  }\n\n  if (freeExports && !isLoader) {\n    // Export for CommonJS environments.\n    runInContext(root, freeExports);\n  } else {\n    // Export for web browsers and JavaScript engines.\n    var nativeJSON = root.JSON,\n        previousJSON = root[\"JSON3\"],\n        isRestored = false;\n\n    var JSON3 = runInContext(root, (root[\"JSON3\"] = {\n      // Public: Restores the original value of the global `JSON` object and\n      // returns a reference to the `JSON3` object.\n      \"noConflict\": function () {\n        if (!isRestored) {\n          isRestored = true;\n          root.JSON = nativeJSON;\n          root[\"JSON3\"] = previousJSON;\n          nativeJSON = previousJSON = null;\n        }\n        return JSON3;\n      }\n    }));\n\n    root.JSON = {\n      \"parse\": JSON3.parse,\n      \"stringify\": JSON3.stringify\n    };\n  }\n\n  // Export for asynchronous module loaders.\n  if (isLoader) {\n    define(function () {\n      return JSON3;\n    });\n  }\n}).call(this);\n\n}).call(this,typeof global !== \"undefined\" ? global : typeof self !== \"undefined\" ? self : typeof window !== \"undefined\" ? window : {})\n},{}],55:[function(require,module,exports){\n/**\n * lodash 3.2.0 (Custom Build) <https://lodash.com/>\n * Build: `lodash modern modularize exports=\"npm\" -o ./`\n * Copyright 2012-2015 The Dojo Foundation <http://dojofoundation.org/>\n * Based on Underscore.js 1.8.3 <http://underscorejs.org/LICENSE>\n * Copyright 2009-2015 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors\n * Available under MIT license <https://lodash.com/license>\n */\nvar baseCopy = require('lodash._basecopy'),\n    keys = require('lodash.keys');\n\n/**\n * The base implementation of `_.assign` without support for argument juggling,\n * multiple sources, and `customizer` functions.\n *\n * @private\n * @param {Object} object The destination object.\n * @param {Object} source The source object.\n * @returns {Object} Returns `object`.\n */\nfunction baseAssign(object, source) {\n  return source == null\n    ? object\n    : baseCopy(source, keys(source), object);\n}\n\nmodule.exports = baseAssign;\n\n},{\"lodash._basecopy\":56,\"lodash.keys\":63}],56:[function(require,module,exports){\n/**\n * lodash 3.0.1 (Custom Build) <https://lodash.com/>\n * Build: `lodash modern modularize exports=\"npm\" -o ./`\n * Copyright 2012-2015 The Dojo Foundation <http://dojofoundation.org/>\n * Based on Underscore.js 1.8.3 <http://underscorejs.org/LICENSE>\n * Copyright 2009-2015 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors\n * Available under MIT license <https://lodash.com/license>\n */\n\n/**\n * Copies properties of `source` to `object`.\n *\n * @private\n * @param {Object} source The object to copy properties from.\n * @param {Array} props The property names to copy.\n * @param {Object} [object={}] The object to copy properties to.\n * @returns {Object} Returns `object`.\n */\nfunction baseCopy(source, props, object) {\n  object || (object = {});\n\n  var index = -1,\n      length = props.length;\n\n  while (++index < length) {\n    var key = props[index];\n    object[key] = source[key];\n  }\n  return object;\n}\n\nmodule.exports = baseCopy;\n\n},{}],57:[function(require,module,exports){\n/**\n * lodash 3.0.3 (Custom Build) <https://lodash.com/>\n * Build: `lodash modern modularize exports=\"npm\" -o ./`\n * Copyright 2012-2015 The Dojo Foundation <http://dojofoundation.org/>\n * Based on Underscore.js 1.8.3 <http://underscorejs.org/LICENSE>\n * Copyright 2009-2015 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors\n * Available under MIT license <https://lodash.com/license>\n */\n\n/**\n * The base implementation of `_.create` without support for assigning\n * properties to the created object.\n *\n * @private\n * @param {Object} prototype The object to inherit from.\n * @returns {Object} Returns the new object.\n */\nvar baseCreate = (function() {\n  function object() {}\n  return function(prototype) {\n    if (isObject(prototype)) {\n      object.prototype = prototype;\n      var result = new object;\n      object.prototype = undefined;\n    }\n    return result || {};\n  };\n}());\n\n/**\n * Checks if `value` is the [language type](https://es5.github.io/#x8) of `Object`.\n * (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)\n *\n * @static\n * @memberOf _\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is an object, else `false`.\n * @example\n *\n * _.isObject({});\n * // => true\n *\n * _.isObject([1, 2, 3]);\n * // => true\n *\n * _.isObject(1);\n * // => false\n */\nfunction isObject(value) {\n  // Avoid a V8 JIT bug in Chrome 19-20.\n  // See https://code.google.com/p/v8/issues/detail?id=2291 for more details.\n  var type = typeof value;\n  return !!value && (type == 'object' || type == 'function');\n}\n\nmodule.exports = baseCreate;\n\n},{}],58:[function(require,module,exports){\n/**\n * lodash 3.9.1 (Custom Build) <https://lodash.com/>\n * Build: `lodash modern modularize exports=\"npm\" -o ./`\n * Copyright 2012-2015 The Dojo Foundation <http://dojofoundation.org/>\n * Based on Underscore.js 1.8.3 <http://underscorejs.org/LICENSE>\n * Copyright 2009-2015 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors\n * Available under MIT license <https://lodash.com/license>\n */\n\n/** `Object#toString` result references. */\nvar funcTag = '[object Function]';\n\n/** Used to detect host constructors (Safari > 5). */\nvar reIsHostCtor = /^\\[object .+?Constructor\\]$/;\n\n/**\n * Checks if `value` is object-like.\n *\n * @private\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is object-like, else `false`.\n */\nfunction isObjectLike(value) {\n  return !!value && typeof value == 'object';\n}\n\n/** Used for native method references. */\nvar objectProto = Object.prototype;\n\n/** Used to resolve the decompiled source of functions. */\nvar fnToString = Function.prototype.toString;\n\n/** Used to check objects for own properties. */\nvar hasOwnProperty = objectProto.hasOwnProperty;\n\n/**\n * Used to resolve the [`toStringTag`](http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring)\n * of values.\n */\nvar objToString = objectProto.toString;\n\n/** Used to detect if a method is native. */\nvar reIsNative = RegExp('^' +\n  fnToString.call(hasOwnProperty).replace(/[\\\\^$.*+?()[\\]{}|]/g, '\\\\$&')\n  .replace(/hasOwnProperty|(function).*?(?=\\\\\\()| for .+?(?=\\\\\\])/g, '$1.*?') + '$'\n);\n\n/**\n * Gets the native function at `key` of `object`.\n *\n * @private\n * @param {Object} object The object to query.\n * @param {string} key The key of the method to get.\n * @returns {*} Returns the function if it's native, else `undefined`.\n */\nfunction getNative(object, key) {\n  var value = object == null ? undefined : object[key];\n  return isNative(value) ? value : undefined;\n}\n\n/**\n * Checks if `value` is classified as a `Function` object.\n *\n * @static\n * @memberOf _\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`.\n * @example\n *\n * _.isFunction(_);\n * // => true\n *\n * _.isFunction(/abc/);\n * // => false\n */\nfunction isFunction(value) {\n  // The use of `Object#toString` avoids issues with the `typeof` operator\n  // in older versions of Chrome and Safari which return 'function' for regexes\n  // and Safari 8 equivalents which return 'object' for typed array constructors.\n  return isObject(value) && objToString.call(value) == funcTag;\n}\n\n/**\n * Checks if `value` is the [language type](https://es5.github.io/#x8) of `Object`.\n * (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)\n *\n * @static\n * @memberOf _\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is an object, else `false`.\n * @example\n *\n * _.isObject({});\n * // => true\n *\n * _.isObject([1, 2, 3]);\n * // => true\n *\n * _.isObject(1);\n * // => false\n */\nfunction isObject(value) {\n  // Avoid a V8 JIT bug in Chrome 19-20.\n  // See https://code.google.com/p/v8/issues/detail?id=2291 for more details.\n  var type = typeof value;\n  return !!value && (type == 'object' || type == 'function');\n}\n\n/**\n * Checks if `value` is a native function.\n *\n * @static\n * @memberOf _\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a native function, else `false`.\n * @example\n *\n * _.isNative(Array.prototype.push);\n * // => true\n *\n * _.isNative(_);\n * // => false\n */\nfunction isNative(value) {\n  if (value == null) {\n    return false;\n  }\n  if (isFunction(value)) {\n    return reIsNative.test(fnToString.call(value));\n  }\n  return isObjectLike(value) && reIsHostCtor.test(value);\n}\n\nmodule.exports = getNative;\n\n},{}],59:[function(require,module,exports){\n/**\n * lodash 3.0.9 (Custom Build) <https://lodash.com/>\n * Build: `lodash modern modularize exports=\"npm\" -o ./`\n * Copyright 2012-2015 The Dojo Foundation <http://dojofoundation.org/>\n * Based on Underscore.js 1.8.3 <http://underscorejs.org/LICENSE>\n * Copyright 2009-2015 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors\n * Available under MIT license <https://lodash.com/license>\n */\n\n/** Used to detect unsigned integer values. */\nvar reIsUint = /^\\d+$/;\n\n/**\n * Used as the [maximum length](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-number.max_safe_integer)\n * of an array-like value.\n */\nvar MAX_SAFE_INTEGER = 9007199254740991;\n\n/**\n * The base implementation of `_.property` without support for deep paths.\n *\n * @private\n * @param {string} key The key of the property to get.\n * @returns {Function} Returns the new function.\n */\nfunction baseProperty(key) {\n  return function(object) {\n    return object == null ? undefined : object[key];\n  };\n}\n\n/**\n * Gets the \"length\" property value of `object`.\n *\n * **Note:** This function is used to avoid a [JIT bug](https://bugs.webkit.org/show_bug.cgi?id=142792)\n * that affects Safari on at least iOS 8.1-8.3 ARM64.\n *\n * @private\n * @param {Object} object The object to query.\n * @returns {*} Returns the \"length\" value.\n */\nvar getLength = baseProperty('length');\n\n/**\n * Checks if `value` is array-like.\n *\n * @private\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is array-like, else `false`.\n */\nfunction isArrayLike(value) {\n  return value != null && isLength(getLength(value));\n}\n\n/**\n * Checks if `value` is a valid array-like index.\n *\n * @private\n * @param {*} value The value to check.\n * @param {number} [length=MAX_SAFE_INTEGER] The upper bounds of a valid index.\n * @returns {boolean} Returns `true` if `value` is a valid index, else `false`.\n */\nfunction isIndex(value, length) {\n  value = (typeof value == 'number' || reIsUint.test(value)) ? +value : -1;\n  length = length == null ? MAX_SAFE_INTEGER : length;\n  return value > -1 && value % 1 == 0 && value < length;\n}\n\n/**\n * Checks if the provided arguments are from an iteratee call.\n *\n * @private\n * @param {*} value The potential iteratee value argument.\n * @param {*} index The potential iteratee index or key argument.\n * @param {*} object The potential iteratee object argument.\n * @returns {boolean} Returns `true` if the arguments are from an iteratee call, else `false`.\n */\nfunction isIterateeCall(value, index, object) {\n  if (!isObject(object)) {\n    return false;\n  }\n  var type = typeof index;\n  if (type == 'number'\n      ? (isArrayLike(object) && isIndex(index, object.length))\n      : (type == 'string' && index in object)) {\n    var other = object[index];\n    return value === value ? (value === other) : (other !== other);\n  }\n  return false;\n}\n\n/**\n * Checks if `value` is a valid array-like length.\n *\n * **Note:** This function is based on [`ToLength`](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-tolength).\n *\n * @private\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a valid length, else `false`.\n */\nfunction isLength(value) {\n  return typeof value == 'number' && value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER;\n}\n\n/**\n * Checks if `value` is the [language type](https://es5.github.io/#x8) of `Object`.\n * (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)\n *\n * @static\n * @memberOf _\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is an object, else `false`.\n * @example\n *\n * _.isObject({});\n * // => true\n *\n * _.isObject([1, 2, 3]);\n * // => true\n *\n * _.isObject(1);\n * // => false\n */\nfunction isObject(value) {\n  // Avoid a V8 JIT bug in Chrome 19-20.\n  // See https://code.google.com/p/v8/issues/detail?id=2291 for more details.\n  var type = typeof value;\n  return !!value && (type == 'object' || type == 'function');\n}\n\nmodule.exports = isIterateeCall;\n\n},{}],60:[function(require,module,exports){\n/**\n * lodash 3.1.1 (Custom Build) <https://lodash.com/>\n * Build: `lodash modern modularize exports=\"npm\" -o ./`\n * Copyright 2012-2015 The Dojo Foundation <http://dojofoundation.org/>\n * Based on Underscore.js 1.8.3 <http://underscorejs.org/LICENSE>\n * Copyright 2009-2015 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors\n * Available under MIT license <https://lodash.com/license>\n */\nvar baseAssign = require('lodash._baseassign'),\n    baseCreate = require('lodash._basecreate'),\n    isIterateeCall = require('lodash._isiterateecall');\n\n/**\n * Creates an object that inherits from the given `prototype` object. If a\n * `properties` object is provided its own enumerable properties are assigned\n * to the created object.\n *\n * @static\n * @memberOf _\n * @category Object\n * @param {Object} prototype The object to inherit from.\n * @param {Object} [properties] The properties to assign to the object.\n * @param- {Object} [guard] Enables use as a callback for functions like `_.map`.\n * @returns {Object} Returns the new object.\n * @example\n *\n * function Shape() {\n *   this.x = 0;\n *   this.y = 0;\n * }\n *\n * function Circle() {\n *   Shape.call(this);\n * }\n *\n * Circle.prototype = _.create(Shape.prototype, {\n *   'constructor': Circle\n * });\n *\n * var circle = new Circle;\n * circle instanceof Circle;\n * // => true\n *\n * circle instanceof Shape;\n * // => true\n */\nfunction create(prototype, properties, guard) {\n  var result = baseCreate(prototype);\n  if (guard && isIterateeCall(prototype, properties, guard)) {\n    properties = undefined;\n  }\n  return properties ? baseAssign(result, properties) : result;\n}\n\nmodule.exports = create;\n\n},{\"lodash._baseassign\":55,\"lodash._basecreate\":57,\"lodash._isiterateecall\":59}],61:[function(require,module,exports){\n/**\n * lodash (Custom Build) <https://lodash.com/>\n * Build: `lodash modularize exports=\"npm\" -o ./`\n * Copyright jQuery Foundation and other contributors <https://jquery.org/>\n * Released under MIT license <https://lodash.com/license>\n * Based on Underscore.js 1.8.3 <http://underscorejs.org/LICENSE>\n * Copyright Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors\n */\n\n/** Used as references for various `Number` constants. */\nvar MAX_SAFE_INTEGER = 9007199254740991;\n\n/** `Object#toString` result references. */\nvar argsTag = '[object Arguments]',\n    funcTag = '[object Function]',\n    genTag = '[object GeneratorFunction]';\n\n/** Used for built-in method references. */\nvar objectProto = Object.prototype;\n\n/** Used to check objects for own properties. */\nvar hasOwnProperty = objectProto.hasOwnProperty;\n\n/**\n * Used to resolve the\n * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring)\n * of values.\n */\nvar objectToString = objectProto.toString;\n\n/** Built-in value references. */\nvar propertyIsEnumerable = objectProto.propertyIsEnumerable;\n\n/**\n * Checks if `value` is likely an `arguments` object.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is an `arguments` object,\n *  else `false`.\n * @example\n *\n * _.isArguments(function() { return arguments; }());\n * // => true\n *\n * _.isArguments([1, 2, 3]);\n * // => false\n */\nfunction isArguments(value) {\n  // Safari 8.1 makes `arguments.callee` enumerable in strict mode.\n  return isArrayLikeObject(value) && hasOwnProperty.call(value, 'callee') &&\n    (!propertyIsEnumerable.call(value, 'callee') || objectToString.call(value) == argsTag);\n}\n\n/**\n * Checks if `value` is array-like. A value is considered array-like if it's\n * not a function and has a `value.length` that's an integer greater than or\n * equal to `0` and less than or equal to `Number.MAX_SAFE_INTEGER`.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is array-like, else `false`.\n * @example\n *\n * _.isArrayLike([1, 2, 3]);\n * // => true\n *\n * _.isArrayLike(document.body.children);\n * // => true\n *\n * _.isArrayLike('abc');\n * // => true\n *\n * _.isArrayLike(_.noop);\n * // => false\n */\nfunction isArrayLike(value) {\n  return value != null && isLength(value.length) && !isFunction(value);\n}\n\n/**\n * This method is like `_.isArrayLike` except that it also checks if `value`\n * is an object.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is an array-like object,\n *  else `false`.\n * @example\n *\n * _.isArrayLikeObject([1, 2, 3]);\n * // => true\n *\n * _.isArrayLikeObject(document.body.children);\n * // => true\n *\n * _.isArrayLikeObject('abc');\n * // => false\n *\n * _.isArrayLikeObject(_.noop);\n * // => false\n */\nfunction isArrayLikeObject(value) {\n  return isObjectLike(value) && isArrayLike(value);\n}\n\n/**\n * Checks if `value` is classified as a `Function` object.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a function, else `false`.\n * @example\n *\n * _.isFunction(_);\n * // => true\n *\n * _.isFunction(/abc/);\n * // => false\n */\nfunction isFunction(value) {\n  // The use of `Object#toString` avoids issues with the `typeof` operator\n  // in Safari 8-9 which returns 'object' for typed array and other constructors.\n  var tag = isObject(value) ? objectToString.call(value) : '';\n  return tag == funcTag || tag == genTag;\n}\n\n/**\n * Checks if `value` is a valid array-like length.\n *\n * **Note:** This method is loosely based on\n * [`ToLength`](http://ecma-international.org/ecma-262/7.0/#sec-tolength).\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a valid length, else `false`.\n * @example\n *\n * _.isLength(3);\n * // => true\n *\n * _.isLength(Number.MIN_VALUE);\n * // => false\n *\n * _.isLength(Infinity);\n * // => false\n *\n * _.isLength('3');\n * // => false\n */\nfunction isLength(value) {\n  return typeof value == 'number' &&\n    value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER;\n}\n\n/**\n * Checks if `value` is the\n * [language type](http://www.ecma-international.org/ecma-262/7.0/#sec-ecmascript-language-types)\n * of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is an object, else `false`.\n * @example\n *\n * _.isObject({});\n * // => true\n *\n * _.isObject([1, 2, 3]);\n * // => true\n *\n * _.isObject(_.noop);\n * // => true\n *\n * _.isObject(null);\n * // => false\n */\nfunction isObject(value) {\n  var type = typeof value;\n  return !!value && (type == 'object' || type == 'function');\n}\n\n/**\n * Checks if `value` is object-like. A value is object-like if it's not `null`\n * and has a `typeof` result of \"object\".\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is object-like, else `false`.\n * @example\n *\n * _.isObjectLike({});\n * // => true\n *\n * _.isObjectLike([1, 2, 3]);\n * // => true\n *\n * _.isObjectLike(_.noop);\n * // => false\n *\n * _.isObjectLike(null);\n * // => false\n */\nfunction isObjectLike(value) {\n  return !!value && typeof value == 'object';\n}\n\nmodule.exports = isArguments;\n\n},{}],62:[function(require,module,exports){\n/**\n * lodash 3.0.4 (Custom Build) <https://lodash.com/>\n * Build: `lodash modern modularize exports=\"npm\" -o ./`\n * Copyright 2012-2015 The Dojo Foundation <http://dojofoundation.org/>\n * Based on Underscore.js 1.8.3 <http://underscorejs.org/LICENSE>\n * Copyright 2009-2015 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors\n * Available under MIT license <https://lodash.com/license>\n */\n\n/** `Object#toString` result references. */\nvar arrayTag = '[object Array]',\n    funcTag = '[object Function]';\n\n/** Used to detect host constructors (Safari > 5). */\nvar reIsHostCtor = /^\\[object .+?Constructor\\]$/;\n\n/**\n * Checks if `value` is object-like.\n *\n * @private\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is object-like, else `false`.\n */\nfunction isObjectLike(value) {\n  return !!value && typeof value == 'object';\n}\n\n/** Used for native method references. */\nvar objectProto = Object.prototype;\n\n/** Used to resolve the decompiled source of functions. */\nvar fnToString = Function.prototype.toString;\n\n/** Used to check objects for own properties. */\nvar hasOwnProperty = objectProto.hasOwnProperty;\n\n/**\n * Used to resolve the [`toStringTag`](http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring)\n * of values.\n */\nvar objToString = objectProto.toString;\n\n/** Used to detect if a method is native. */\nvar reIsNative = RegExp('^' +\n  fnToString.call(hasOwnProperty).replace(/[\\\\^$.*+?()[\\]{}|]/g, '\\\\$&')\n  .replace(/hasOwnProperty|(function).*?(?=\\\\\\()| for .+?(?=\\\\\\])/g, '$1.*?') + '$'\n);\n\n/* Native method references for those with the same name as other `lodash` methods. */\nvar nativeIsArray = getNative(Array, 'isArray');\n\n/**\n * Used as the [maximum length](http://ecma-international.org/ecma-262/6.0/#sec-number.max_safe_integer)\n * of an array-like value.\n */\nvar MAX_SAFE_INTEGER = 9007199254740991;\n\n/**\n * Gets the native function at `key` of `object`.\n *\n * @private\n * @param {Object} object The object to query.\n * @param {string} key The key of the method to get.\n * @returns {*} Returns the function if it's native, else `undefined`.\n */\nfunction getNative(object, key) {\n  var value = object == null ? undefined : object[key];\n  return isNative(value) ? value : undefined;\n}\n\n/**\n * Checks if `value` is a valid array-like length.\n *\n * **Note:** This function is based on [`ToLength`](http://ecma-international.org/ecma-262/6.0/#sec-tolength).\n *\n * @private\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a valid length, else `false`.\n */\nfunction isLength(value) {\n  return typeof value == 'number' && value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER;\n}\n\n/**\n * Checks if `value` is classified as an `Array` object.\n *\n * @static\n * @memberOf _\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`.\n * @example\n *\n * _.isArray([1, 2, 3]);\n * // => true\n *\n * _.isArray(function() { return arguments; }());\n * // => false\n */\nvar isArray = nativeIsArray || function(value) {\n  return isObjectLike(value) && isLength(value.length) && objToString.call(value) == arrayTag;\n};\n\n/**\n * Checks if `value` is classified as a `Function` object.\n *\n * @static\n * @memberOf _\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`.\n * @example\n *\n * _.isFunction(_);\n * // => true\n *\n * _.isFunction(/abc/);\n * // => false\n */\nfunction isFunction(value) {\n  // The use of `Object#toString` avoids issues with the `typeof` operator\n  // in older versions of Chrome and Safari which return 'function' for regexes\n  // and Safari 8 equivalents which return 'object' for typed array constructors.\n  return isObject(value) && objToString.call(value) == funcTag;\n}\n\n/**\n * Checks if `value` is the [language type](https://es5.github.io/#x8) of `Object`.\n * (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)\n *\n * @static\n * @memberOf _\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is an object, else `false`.\n * @example\n *\n * _.isObject({});\n * // => true\n *\n * _.isObject([1, 2, 3]);\n * // => true\n *\n * _.isObject(1);\n * // => false\n */\nfunction isObject(value) {\n  // Avoid a V8 JIT bug in Chrome 19-20.\n  // See https://code.google.com/p/v8/issues/detail?id=2291 for more details.\n  var type = typeof value;\n  return !!value && (type == 'object' || type == 'function');\n}\n\n/**\n * Checks if `value` is a native function.\n *\n * @static\n * @memberOf _\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a native function, else `false`.\n * @example\n *\n * _.isNative(Array.prototype.push);\n * // => true\n *\n * _.isNative(_);\n * // => false\n */\nfunction isNative(value) {\n  if (value == null) {\n    return false;\n  }\n  if (isFunction(value)) {\n    return reIsNative.test(fnToString.call(value));\n  }\n  return isObjectLike(value) && reIsHostCtor.test(value);\n}\n\nmodule.exports = isArray;\n\n},{}],63:[function(require,module,exports){\n/**\n * lodash 3.1.2 (Custom Build) <https://lodash.com/>\n * Build: `lodash modern modularize exports=\"npm\" -o ./`\n * Copyright 2012-2015 The Dojo Foundation <http://dojofoundation.org/>\n * Based on Underscore.js 1.8.3 <http://underscorejs.org/LICENSE>\n * Copyright 2009-2015 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors\n * Available under MIT license <https://lodash.com/license>\n */\nvar getNative = require('lodash._getnative'),\n    isArguments = require('lodash.isarguments'),\n    isArray = require('lodash.isarray');\n\n/** Used to detect unsigned integer values. */\nvar reIsUint = /^\\d+$/;\n\n/** Used for native method references. */\nvar objectProto = Object.prototype;\n\n/** Used to check objects for own properties. */\nvar hasOwnProperty = objectProto.hasOwnProperty;\n\n/* Native method references for those with the same name as other `lodash` methods. */\nvar nativeKeys = getNative(Object, 'keys');\n\n/**\n * Used as the [maximum length](http://ecma-international.org/ecma-262/6.0/#sec-number.max_safe_integer)\n * of an array-like value.\n */\nvar MAX_SAFE_INTEGER = 9007199254740991;\n\n/**\n * The base implementation of `_.property` without support for deep paths.\n *\n * @private\n * @param {string} key The key of the property to get.\n * @returns {Function} Returns the new function.\n */\nfunction baseProperty(key) {\n  return function(object) {\n    return object == null ? undefined : object[key];\n  };\n}\n\n/**\n * Gets the \"length\" property value of `object`.\n *\n * **Note:** This function is used to avoid a [JIT bug](https://bugs.webkit.org/show_bug.cgi?id=142792)\n * that affects Safari on at least iOS 8.1-8.3 ARM64.\n *\n * @private\n * @param {Object} object The object to query.\n * @returns {*} Returns the \"length\" value.\n */\nvar getLength = baseProperty('length');\n\n/**\n * Checks if `value` is array-like.\n *\n * @private\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is array-like, else `false`.\n */\nfunction isArrayLike(value) {\n  return value != null && isLength(getLength(value));\n}\n\n/**\n * Checks if `value` is a valid array-like index.\n *\n * @private\n * @param {*} value The value to check.\n * @param {number} [length=MAX_SAFE_INTEGER] The upper bounds of a valid index.\n * @returns {boolean} Returns `true` if `value` is a valid index, else `false`.\n */\nfunction isIndex(value, length) {\n  value = (typeof value == 'number' || reIsUint.test(value)) ? +value : -1;\n  length = length == null ? MAX_SAFE_INTEGER : length;\n  return value > -1 && value % 1 == 0 && value < length;\n}\n\n/**\n * Checks if `value` is a valid array-like length.\n *\n * **Note:** This function is based on [`ToLength`](http://ecma-international.org/ecma-262/6.0/#sec-tolength).\n *\n * @private\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a valid length, else `false`.\n */\nfunction isLength(value) {\n  return typeof value == 'number' && value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER;\n}\n\n/**\n * A fallback implementation of `Object.keys` which creates an array of the\n * own enumerable property names of `object`.\n *\n * @private\n * @param {Object} object The object to query.\n * @returns {Array} Returns the array of property names.\n */\nfunction shimKeys(object) {\n  var props = keysIn(object),\n      propsLength = props.length,\n      length = propsLength && object.length;\n\n  var allowIndexes = !!length && isLength(length) &&\n    (isArray(object) || isArguments(object));\n\n  var index = -1,\n      result = [];\n\n  while (++index < propsLength) {\n    var key = props[index];\n    if ((allowIndexes && isIndex(key, length)) || hasOwnProperty.call(object, key)) {\n      result.push(key);\n    }\n  }\n  return result;\n}\n\n/**\n * Checks if `value` is the [language type](https://es5.github.io/#x8) of `Object`.\n * (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)\n *\n * @static\n * @memberOf _\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is an object, else `false`.\n * @example\n *\n * _.isObject({});\n * // => true\n *\n * _.isObject([1, 2, 3]);\n * // => true\n *\n * _.isObject(1);\n * // => false\n */\nfunction isObject(value) {\n  // Avoid a V8 JIT bug in Chrome 19-20.\n  // See https://code.google.com/p/v8/issues/detail?id=2291 for more details.\n  var type = typeof value;\n  return !!value && (type == 'object' || type == 'function');\n}\n\n/**\n * Creates an array of the own enumerable property names of `object`.\n *\n * **Note:** Non-object values are coerced to objects. See the\n * [ES spec](http://ecma-international.org/ecma-262/6.0/#sec-object.keys)\n * for more details.\n *\n * @static\n * @memberOf _\n * @category Object\n * @param {Object} object The object to query.\n * @returns {Array} Returns the array of property names.\n * @example\n *\n * function Foo() {\n *   this.a = 1;\n *   this.b = 2;\n * }\n *\n * Foo.prototype.c = 3;\n *\n * _.keys(new Foo);\n * // => ['a', 'b'] (iteration order is not guaranteed)\n *\n * _.keys('hi');\n * // => ['0', '1']\n */\nvar keys = !nativeKeys ? shimKeys : function(object) {\n  var Ctor = object == null ? undefined : object.constructor;\n  if ((typeof Ctor == 'function' && Ctor.prototype === object) ||\n      (typeof object != 'function' && isArrayLike(object))) {\n    return shimKeys(object);\n  }\n  return isObject(object) ? nativeKeys(object) : [];\n};\n\n/**\n * Creates an array of the own and inherited enumerable property names of `object`.\n *\n * **Note:** Non-object values are coerced to objects.\n *\n * @static\n * @memberOf _\n * @category Object\n * @param {Object} object The object to query.\n * @returns {Array} Returns the array of property names.\n * @example\n *\n * function Foo() {\n *   this.a = 1;\n *   this.b = 2;\n * }\n *\n * Foo.prototype.c = 3;\n *\n * _.keysIn(new Foo);\n * // => ['a', 'b', 'c'] (iteration order is not guaranteed)\n */\nfunction keysIn(object) {\n  if (object == null) {\n    return [];\n  }\n  if (!isObject(object)) {\n    object = Object(object);\n  }\n  var length = object.length;\n  length = (length && isLength(length) &&\n    (isArray(object) || isArguments(object)) && length) || 0;\n\n  var Ctor = object.constructor,\n      index = -1,\n      isProto = typeof Ctor == 'function' && Ctor.prototype === object,\n      result = Array(length),\n      skipIndexes = length > 0;\n\n  while (++index < length) {\n    result[index] = (index + '');\n  }\n  for (var key in object) {\n    if (!(skipIndexes && isIndex(key, length)) &&\n        !(key == 'constructor' && (isProto || !hasOwnProperty.call(object, key)))) {\n      result.push(key);\n    }\n  }\n  return result;\n}\n\nmodule.exports = keys;\n\n},{\"lodash._getnative\":58,\"lodash.isarguments\":61,\"lodash.isarray\":62}],64:[function(require,module,exports){\n(function (process){\nvar path = require('path');\nvar fs = require('fs');\nvar _0777 = parseInt('0777', 8);\n\nmodule.exports = mkdirP.mkdirp = mkdirP.mkdirP = mkdirP;\n\nfunction mkdirP (p, opts, f, made) {\n    if (typeof opts === 'function') {\n        f = opts;\n        opts = {};\n    }\n    else if (!opts || typeof opts !== 'object') {\n        opts = { mode: opts };\n    }\n\n    var mode = opts.mode;\n    var xfs = opts.fs || fs;\n\n    if (mode === undefined) {\n        mode = _0777 & (~process.umask());\n    }\n    if (!made) made = null;\n\n    var cb = f || function () {};\n    p = path.resolve(p);\n\n    xfs.mkdir(p, mode, function (er) {\n        if (!er) {\n            made = made || p;\n            return cb(null, made);\n        }\n        switch (er.code) {\n            case 'ENOENT':\n                mkdirP(path.dirname(p), opts, function (er, made) {\n                    if (er) cb(er, made);\n                    else mkdirP(p, opts, cb, made);\n                });\n                break;\n\n            // In the case of any other error, just see if there's a dir\n            // there already.  If so, then hooray!  If not, then something\n            // is borked.\n            default:\n                xfs.stat(p, function (er2, stat) {\n                    // if the stat fails, then that's super weird.\n                    // let the original error be the failure reason.\n                    if (er2 || !stat.isDirectory()) cb(er, made)\n                    else cb(null, made);\n                });\n                break;\n        }\n    });\n}\n\nmkdirP.sync = function sync (p, opts, made) {\n    if (!opts || typeof opts !== 'object') {\n        opts = { mode: opts };\n    }\n\n    var mode = opts.mode;\n    var xfs = opts.fs || fs;\n\n    if (mode === undefined) {\n        mode = _0777 & (~process.umask());\n    }\n    if (!made) made = null;\n\n    p = path.resolve(p);\n\n    try {\n        xfs.mkdirSync(p, mode);\n        made = made || p;\n    }\n    catch (err0) {\n        switch (err0.code) {\n            case 'ENOENT' :\n                made = sync(path.dirname(p), opts, made);\n                sync(p, opts, made);\n                break;\n\n            // In the case of any other error, just see if there's a dir\n            // there already.  If so, then hooray!  If not, then something\n            // is borked.\n            default:\n                var stat;\n                try {\n                    stat = xfs.statSync(p);\n                }\n                catch (err1) {\n                    throw err0;\n                }\n                if (!stat.isDirectory()) throw err0;\n                break;\n        }\n    }\n\n    return made;\n};\n\n}).call(this,require('_process'))\n},{\"_process\":67,\"fs\":42,\"path\":42}],65:[function(require,module,exports){\nexports.endianness = function () { return 'LE' };\n\nexports.hostname = function () {\n    if (typeof location !== 'undefined') {\n        return location.hostname\n    }\n    else return '';\n};\n\nexports.loadavg = function () { return [] };\n\nexports.uptime = function () { return 0 };\n\nexports.freemem = function () {\n    return Number.MAX_VALUE;\n};\n\nexports.totalmem = function () {\n    return Number.MAX_VALUE;\n};\n\nexports.cpus = function () { return [] };\n\nexports.type = function () { return 'Browser' };\n\nexports.release = function () {\n    if (typeof navigator !== 'undefined') {\n        return navigator.appVersion;\n    }\n    return '';\n};\n\nexports.networkInterfaces\n= exports.getNetworkInterfaces\n= function () { return {} };\n\nexports.arch = function () { return 'javascript' };\n\nexports.platform = function () { return 'browser' };\n\nexports.tmpdir = exports.tmpDir = function () {\n    return '/tmp';\n};\n\nexports.EOL = '\\n';\n\n},{}],66:[function(require,module,exports){\n(function (process){\n'use strict';\n\nif (!process.version ||\n    process.version.indexOf('v0.') === 0 ||\n    process.version.indexOf('v1.') === 0 && process.version.indexOf('v1.8.') !== 0) {\n  module.exports = nextTick;\n} else {\n  module.exports = process.nextTick;\n}\n\nfunction nextTick(fn, arg1, arg2, arg3) {\n  if (typeof fn !== 'function') {\n    throw new TypeError('\"callback\" argument must be a function');\n  }\n  var len = arguments.length;\n  var args, i;\n  switch (len) {\n  case 0:\n  case 1:\n    return process.nextTick(fn);\n  case 2:\n    return process.nextTick(function afterTickOne() {\n      fn.call(null, arg1);\n    });\n  case 3:\n    return process.nextTick(function afterTickTwo() {\n      fn.call(null, arg1, arg2);\n    });\n  case 4:\n    return process.nextTick(function afterTickThree() {\n      fn.call(null, arg1, arg2, arg3);\n    });\n  default:\n    args = new Array(len - 1);\n    i = 0;\n    while (i < args.length) {\n      args[i++] = arguments[i];\n    }\n    return process.nextTick(function afterTick() {\n      fn.apply(null, args);\n    });\n  }\n}\n\n}).call(this,require('_process'))\n},{\"_process\":67}],67:[function(require,module,exports){\n// shim for using process in browser\nvar process = module.exports = {};\n\n// cached from whatever global is present so that test runners that stub it\n// don't break things.  But we need to wrap it in a try catch in case it is\n// wrapped in strict mode code which doesn't define any globals.  It's inside a\n// function because try/catches deoptimize in certain engines.\n\nvar cachedSetTimeout;\nvar cachedClearTimeout;\n\nfunction defaultSetTimout() {\n    throw new Error('setTimeout has not been defined');\n}\nfunction defaultClearTimeout () {\n    throw new Error('clearTimeout has not been defined');\n}\n(function () {\n    try {\n        if (typeof setTimeout === 'function') {\n            cachedSetTimeout = setTimeout;\n        } else {\n            cachedSetTimeout = defaultSetTimout;\n        }\n    } catch (e) {\n        cachedSetTimeout = defaultSetTimout;\n    }\n    try {\n        if (typeof clearTimeout === 'function') {\n            cachedClearTimeout = clearTimeout;\n        } else {\n            cachedClearTimeout = defaultClearTimeout;\n        }\n    } catch (e) {\n        cachedClearTimeout = defaultClearTimeout;\n    }\n} ())\nfunction runTimeout(fun) {\n    if (cachedSetTimeout === setTimeout) {\n        //normal enviroments in sane situations\n        return setTimeout(fun, 0);\n    }\n    // if setTimeout wasn't available but was latter defined\n    if ((cachedSetTimeout === defaultSetTimout || !cachedSetTimeout) && setTimeout) {\n        cachedSetTimeout = setTimeout;\n        return setTimeout(fun, 0);\n    }\n    try {\n        // when when somebody has screwed with setTimeout but no I.E. maddness\n        return cachedSetTimeout(fun, 0);\n    } catch(e){\n        try {\n            // When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally\n            return cachedSetTimeout.call(null, fun, 0);\n        } catch(e){\n            // same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error\n            return cachedSetTimeout.call(this, fun, 0);\n        }\n    }\n\n\n}\nfunction runClearTimeout(marker) {\n    if (cachedClearTimeout === clearTimeout) {\n        //normal enviroments in sane situations\n        return clearTimeout(marker);\n    }\n    // if clearTimeout wasn't available but was latter defined\n    if ((cachedClearTimeout === defaultClearTimeout || !cachedClearTimeout) && clearTimeout) {\n        cachedClearTimeout = clearTimeout;\n        return clearTimeout(marker);\n    }\n    try {\n        // when when somebody has screwed with setTimeout but no I.E. maddness\n        return cachedClearTimeout(marker);\n    } catch (e){\n        try {\n            // When we are in I.E. but the script has been evaled so I.E. doesn't  trust the global object when called normally\n            return cachedClearTimeout.call(null, marker);\n        } catch (e){\n            // same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error.\n            // Some versions of I.E. have different rules for clearTimeout vs setTimeout\n            return cachedClearTimeout.call(this, marker);\n        }\n    }\n\n\n\n}\nvar queue = [];\nvar draining = false;\nvar currentQueue;\nvar queueIndex = -1;\n\nfunction cleanUpNextTick() {\n    if (!draining || !currentQueue) {\n        return;\n    }\n    draining = false;\n    if (currentQueue.length) {\n        queue = currentQueue.concat(queue);\n    } else {\n        queueIndex = -1;\n    }\n    if (queue.length) {\n        drainQueue();\n    }\n}\n\nfunction drainQueue() {\n    if (draining) {\n        return;\n    }\n    var timeout = runTimeout(cleanUpNextTick);\n    draining = true;\n\n    var len = queue.length;\n    while(len) {\n        currentQueue = queue;\n        queue = [];\n        while (++queueIndex < len) {\n            if (currentQueue) {\n                currentQueue[queueIndex].run();\n            }\n        }\n        queueIndex = -1;\n        len = queue.length;\n    }\n    currentQueue = null;\n    draining = false;\n    runClearTimeout(timeout);\n}\n\nprocess.nextTick = function (fun) {\n    var args = new Array(arguments.length - 1);\n    if (arguments.length > 1) {\n        for (var i = 1; i < arguments.length; i++) {\n            args[i - 1] = arguments[i];\n        }\n    }\n    queue.push(new Item(fun, args));\n    if (queue.length === 1 && !draining) {\n        runTimeout(drainQueue);\n    }\n};\n\n// v8 likes predictible objects\nfunction Item(fun, array) {\n    this.fun = fun;\n    this.array = array;\n}\nItem.prototype.run = function () {\n    this.fun.apply(null, this.array);\n};\nprocess.title = 'browser';\nprocess.browser = true;\nprocess.env = {};\nprocess.argv = [];\nprocess.version = ''; // empty string to avoid regexp issues\nprocess.versions = {};\n\nfunction noop() {}\n\nprocess.on = noop;\nprocess.addListener = noop;\nprocess.once = noop;\nprocess.off = noop;\nprocess.removeListener = noop;\nprocess.removeAllListeners = noop;\nprocess.emit = noop;\n\nprocess.binding = function (name) {\n    throw new Error('process.binding is not supported');\n};\n\nprocess.cwd = function () { return '/' };\nprocess.chdir = function (dir) {\n    throw new Error('process.chdir is not supported');\n};\nprocess.umask = function() { return 0; };\n\n},{}],68:[function(require,module,exports){\nmodule.exports = require(\"./lib/_stream_duplex.js\")\n\n},{\"./lib/_stream_duplex.js\":69}],69:[function(require,module,exports){\n// a duplex stream is just a stream that is both readable and writable.\n// Since JS doesn't have multiple prototypal inheritance, this class\n// prototypally inherits from Readable, and then parasitically from\n// Writable.\n\n'use strict';\n\n/*<replacement>*/\n\nvar objectKeys = Object.keys || function (obj) {\n  var keys = [];\n  for (var key in obj) {\n    keys.push(key);\n  }return keys;\n};\n/*</replacement>*/\n\nmodule.exports = Duplex;\n\n/*<replacement>*/\nvar processNextTick = require('process-nextick-args');\n/*</replacement>*/\n\n/*<replacement>*/\nvar util = require('core-util-is');\nutil.inherits = require('inherits');\n/*</replacement>*/\n\nvar Readable = require('./_stream_readable');\nvar Writable = require('./_stream_writable');\n\nutil.inherits(Duplex, Readable);\n\nvar keys = objectKeys(Writable.prototype);\nfor (var v = 0; v < keys.length; v++) {\n  var method = keys[v];\n  if (!Duplex.prototype[method]) Duplex.prototype[method] = Writable.prototype[method];\n}\n\nfunction Duplex(options) {\n  if (!(this instanceof Duplex)) return new Duplex(options);\n\n  Readable.call(this, options);\n  Writable.call(this, options);\n\n  if (options && options.readable === false) this.readable = false;\n\n  if (options && options.writable === false) this.writable = false;\n\n  this.allowHalfOpen = true;\n  if (options && options.allowHalfOpen === false) this.allowHalfOpen = false;\n\n  this.once('end', onend);\n}\n\n// the no-half-open enforcer\nfunction onend() {\n  // if we allow half-open state, or if the writable side ended,\n  // then we're ok.\n  if (this.allowHalfOpen || this._writableState.ended) return;\n\n  // no more data can be written.\n  // But allow more writes to happen in this tick.\n  processNextTick(onEndNT, this);\n}\n\nfunction onEndNT(self) {\n  self.end();\n}\n\nfunction forEach(xs, f) {\n  for (var i = 0, l = xs.length; i < l; i++) {\n    f(xs[i], i);\n  }\n}\n},{\"./_stream_readable\":71,\"./_stream_writable\":73,\"core-util-is\":45,\"inherits\":51,\"process-nextick-args\":66}],70:[function(require,module,exports){\n// a passthrough stream.\n// basically just the most minimal sort of Transform stream.\n// Every written chunk gets output as-is.\n\n'use strict';\n\nmodule.exports = PassThrough;\n\nvar Transform = require('./_stream_transform');\n\n/*<replacement>*/\nvar util = require('core-util-is');\nutil.inherits = require('inherits');\n/*</replacement>*/\n\nutil.inherits(PassThrough, Transform);\n\nfunction PassThrough(options) {\n  if (!(this instanceof PassThrough)) return new PassThrough(options);\n\n  Transform.call(this, options);\n}\n\nPassThrough.prototype._transform = function (chunk, encoding, cb) {\n  cb(null, chunk);\n};\n},{\"./_stream_transform\":72,\"core-util-is\":45,\"inherits\":51}],71:[function(require,module,exports){\n(function (process){\n'use strict';\n\nmodule.exports = Readable;\n\n/*<replacement>*/\nvar processNextTick = require('process-nextick-args');\n/*</replacement>*/\n\n/*<replacement>*/\nvar isArray = require('isarray');\n/*</replacement>*/\n\nReadable.ReadableState = ReadableState;\n\n/*<replacement>*/\nvar EE = require('events').EventEmitter;\n\nvar EElistenerCount = function (emitter, type) {\n  return emitter.listeners(type).length;\n};\n/*</replacement>*/\n\n/*<replacement>*/\nvar Stream;\n(function () {\n  try {\n    Stream = require('st' + 'ream');\n  } catch (_) {} finally {\n    if (!Stream) Stream = require('events').EventEmitter;\n  }\n})();\n/*</replacement>*/\n\nvar Buffer = require('buffer').Buffer;\n/*<replacement>*/\nvar bufferShim = require('buffer-shims');\n/*</replacement>*/\n\n/*<replacement>*/\nvar util = require('core-util-is');\nutil.inherits = require('inherits');\n/*</replacement>*/\n\n/*<replacement>*/\nvar debugUtil = require('util');\nvar debug = void 0;\nif (debugUtil && debugUtil.debuglog) {\n  debug = debugUtil.debuglog('stream');\n} else {\n  debug = function () {};\n}\n/*</replacement>*/\n\nvar BufferList = require('./internal/streams/BufferList');\nvar StringDecoder;\n\nutil.inherits(Readable, Stream);\n\nfunction prependListener(emitter, event, fn) {\n  if (typeof emitter.prependListener === 'function') {\n    return emitter.prependListener(event, fn);\n  } else {\n    // This is a hack to make sure that our error handler is attached before any\n    // userland ones.  NEVER DO THIS. This is here only because this code needs\n    // to continue to work with older versions of Node.js that do not include\n    // the prependListener() method. The goal is to eventually remove this hack.\n    if (!emitter._events || !emitter._events[event]) emitter.on(event, fn);else if (isArray(emitter._events[event])) emitter._events[event].unshift(fn);else emitter._events[event] = [fn, emitter._events[event]];\n  }\n}\n\nvar Duplex;\nfunction ReadableState(options, stream) {\n  Duplex = Duplex || require('./_stream_duplex');\n\n  options = options || {};\n\n  // object stream flag. Used to make read(n) ignore n and to\n  // make all the buffer merging and length checks go away\n  this.objectMode = !!options.objectMode;\n\n  if (stream instanceof Duplex) this.objectMode = this.objectMode || !!options.readableObjectMode;\n\n  // the point at which it stops calling _read() to fill the buffer\n  // Note: 0 is a valid value, means \"don't call _read preemptively ever\"\n  var hwm = options.highWaterMark;\n  var defaultHwm = this.objectMode ? 16 : 16 * 1024;\n  this.highWaterMark = hwm || hwm === 0 ? hwm : defaultHwm;\n\n  // cast to ints.\n  this.highWaterMark = ~ ~this.highWaterMark;\n\n  // A linked list is used to store data chunks instead of an array because the\n  // linked list can remove elements from the beginning faster than\n  // array.shift()\n  this.buffer = new BufferList();\n  this.length = 0;\n  this.pipes = null;\n  this.pipesCount = 0;\n  this.flowing = null;\n  this.ended = false;\n  this.endEmitted = false;\n  this.reading = false;\n\n  // a flag to be able to tell if the onwrite cb is called immediately,\n  // or on a later tick.  We set this to true at first, because any\n  // actions that shouldn't happen until \"later\" should generally also\n  // not happen before the first write call.\n  this.sync = true;\n\n  // whenever we return null, then we set a flag to say\n  // that we're awaiting a 'readable' event emission.\n  this.needReadable = false;\n  this.emittedReadable = false;\n  this.readableListening = false;\n  this.resumeScheduled = false;\n\n  // Crypto is kind of old and crusty.  Historically, its default string\n  // encoding is 'binary' so we have to make this configurable.\n  // Everything else in the universe uses 'utf8', though.\n  this.defaultEncoding = options.defaultEncoding || 'utf8';\n\n  // when piping, we only care about 'readable' events that happen\n  // after read()ing all the bytes and not getting any pushback.\n  this.ranOut = false;\n\n  // the number of writers that are awaiting a drain event in .pipe()s\n  this.awaitDrain = 0;\n\n  // if true, a maybeReadMore has been scheduled\n  this.readingMore = false;\n\n  this.decoder = null;\n  this.encoding = null;\n  if (options.encoding) {\n    if (!StringDecoder) StringDecoder = require('string_decoder/').StringDecoder;\n    this.decoder = new StringDecoder(options.encoding);\n    this.encoding = options.encoding;\n  }\n}\n\nvar Duplex;\nfunction Readable(options) {\n  Duplex = Duplex || require('./_stream_duplex');\n\n  if (!(this instanceof Readable)) return new Readable(options);\n\n  this._readableState = new ReadableState(options, this);\n\n  // legacy\n  this.readable = true;\n\n  if (options && typeof options.read === 'function') this._read = options.read;\n\n  Stream.call(this);\n}\n\n// Manually shove something into the read() buffer.\n// This returns true if the highWaterMark has not been hit yet,\n// similar to how Writable.write() returns true if you should\n// write() some more.\nReadable.prototype.push = function (chunk, encoding) {\n  var state = this._readableState;\n\n  if (!state.objectMode && typeof chunk === 'string') {\n    encoding = encoding || state.defaultEncoding;\n    if (encoding !== state.encoding) {\n      chunk = bufferShim.from(chunk, encoding);\n      encoding = '';\n    }\n  }\n\n  return readableAddChunk(this, state, chunk, encoding, false);\n};\n\n// Unshift should *always* be something directly out of read()\nReadable.prototype.unshift = function (chunk) {\n  var state = this._readableState;\n  return readableAddChunk(this, state, chunk, '', true);\n};\n\nReadable.prototype.isPaused = function () {\n  return this._readableState.flowing === false;\n};\n\nfunction readableAddChunk(stream, state, chunk, encoding, addToFront) {\n  var er = chunkInvalid(state, chunk);\n  if (er) {\n    stream.emit('error', er);\n  } else if (chunk === null) {\n    state.reading = false;\n    onEofChunk(stream, state);\n  } else if (state.objectMode || chunk && chunk.length > 0) {\n    if (state.ended && !addToFront) {\n      var e = new Error('stream.push() after EOF');\n      stream.emit('error', e);\n    } else if (state.endEmitted && addToFront) {\n      var _e = new Error('stream.unshift() after end event');\n      stream.emit('error', _e);\n    } else {\n      var skipAdd;\n      if (state.decoder && !addToFront && !encoding) {\n        chunk = state.decoder.write(chunk);\n        skipAdd = !state.objectMode && chunk.length === 0;\n      }\n\n      if (!addToFront) state.reading = false;\n\n      // Don't add to the buffer if we've decoded to an empty string chunk and\n      // we're not in object mode\n      if (!skipAdd) {\n        // if we want the data now, just emit it.\n        if (state.flowing && state.length === 0 && !state.sync) {\n          stream.emit('data', chunk);\n          stream.read(0);\n        } else {\n          // update the buffer info.\n          state.length += state.objectMode ? 1 : chunk.length;\n          if (addToFront) state.buffer.unshift(chunk);else state.buffer.push(chunk);\n\n          if (state.needReadable) emitReadable(stream);\n        }\n      }\n\n      maybeReadMore(stream, state);\n    }\n  } else if (!addToFront) {\n    state.reading = false;\n  }\n\n  return needMoreData(state);\n}\n\n// if it's past the high water mark, we can push in some more.\n// Also, if we have no data yet, we can stand some\n// more bytes.  This is to work around cases where hwm=0,\n// such as the repl.  Also, if the push() triggered a\n// readable event, and the user called read(largeNumber) such that\n// needReadable was set, then we ought to push more, so that another\n// 'readable' event will be triggered.\nfunction needMoreData(state) {\n  return !state.ended && (state.needReadable || state.length < state.highWaterMark || state.length === 0);\n}\n\n// backwards compatibility.\nReadable.prototype.setEncoding = function (enc) {\n  if (!StringDecoder) StringDecoder = require('string_decoder/').StringDecoder;\n  this._readableState.decoder = new StringDecoder(enc);\n  this._readableState.encoding = enc;\n  return this;\n};\n\n// Don't raise the hwm > 8MB\nvar MAX_HWM = 0x800000;\nfunction computeNewHighWaterMark(n) {\n  if (n >= MAX_HWM) {\n    n = MAX_HWM;\n  } else {\n    // Get the next highest power of 2 to prevent increasing hwm excessively in\n    // tiny amounts\n    n--;\n    n |= n >>> 1;\n    n |= n >>> 2;\n    n |= n >>> 4;\n    n |= n >>> 8;\n    n |= n >>> 16;\n    n++;\n  }\n  return n;\n}\n\n// This function is designed to be inlinable, so please take care when making\n// changes to the function body.\nfunction howMuchToRead(n, state) {\n  if (n <= 0 || state.length === 0 && state.ended) return 0;\n  if (state.objectMode) return 1;\n  if (n !== n) {\n    // Only flow one buffer at a time\n    if (state.flowing && state.length) return state.buffer.head.data.length;else return state.length;\n  }\n  // If we're asking for more than the current hwm, then raise the hwm.\n  if (n > state.highWaterMark) state.highWaterMark = computeNewHighWaterMark(n);\n  if (n <= state.length) return n;\n  // Don't have enough\n  if (!state.ended) {\n    state.needReadable = true;\n    return 0;\n  }\n  return state.length;\n}\n\n// you can override either this method, or the async _read(n) below.\nReadable.prototype.read = function (n) {\n  debug('read', n);\n  n = parseInt(n, 10);\n  var state = this._readableState;\n  var nOrig = n;\n\n  if (n !== 0) state.emittedReadable = false;\n\n  // if we're doing read(0) to trigger a readable event, but we\n  // already have a bunch of data in the buffer, then just trigger\n  // the 'readable' event and move on.\n  if (n === 0 && state.needReadable && (state.length >= state.highWaterMark || state.ended)) {\n    debug('read: emitReadable', state.length, state.ended);\n    if (state.length === 0 && state.ended) endReadable(this);else emitReadable(this);\n    return null;\n  }\n\n  n = howMuchToRead(n, state);\n\n  // if we've ended, and we're now clear, then finish it up.\n  if (n === 0 && state.ended) {\n    if (state.length === 0) endReadable(this);\n    return null;\n  }\n\n  // All the actual chunk generation logic needs to be\n  // *below* the call to _read.  The reason is that in certain\n  // synthetic stream cases, such as passthrough streams, _read\n  // may be a completely synchronous operation which may change\n  // the state of the read buffer, providing enough data when\n  // before there was *not* enough.\n  //\n  // So, the steps are:\n  // 1. Figure out what the state of things will be after we do\n  // a read from the buffer.\n  //\n  // 2. If that resulting state will trigger a _read, then call _read.\n  // Note that this may be asynchronous, or synchronous.  Yes, it is\n  // deeply ugly to write APIs this way, but that still doesn't mean\n  // that the Readable class should behave improperly, as streams are\n  // designed to be sync/async agnostic.\n  // Take note if the _read call is sync or async (ie, if the read call\n  // has returned yet), so that we know whether or not it's safe to emit\n  // 'readable' etc.\n  //\n  // 3. Actually pull the requested chunks out of the buffer and return.\n\n  // if we need a readable event, then we need to do some reading.\n  var doRead = state.needReadable;\n  debug('need readable', doRead);\n\n  // if we currently have less than the highWaterMark, then also read some\n  if (state.length === 0 || state.length - n < state.highWaterMark) {\n    doRead = true;\n    debug('length less than watermark', doRead);\n  }\n\n  // however, if we've ended, then there's no point, and if we're already\n  // reading, then it's unnecessary.\n  if (state.ended || state.reading) {\n    doRead = false;\n    debug('reading or ended', doRead);\n  } else if (doRead) {\n    debug('do read');\n    state.reading = true;\n    state.sync = true;\n    // if the length is currently zero, then we *need* a readable event.\n    if (state.length === 0) state.needReadable = true;\n    // call internal read method\n    this._read(state.highWaterMark);\n    state.sync = false;\n    // If _read pushed data synchronously, then `reading` will be false,\n    // and we need to re-evaluate how much data we can return to the user.\n    if (!state.reading) n = howMuchToRead(nOrig, state);\n  }\n\n  var ret;\n  if (n > 0) ret = fromList(n, state);else ret = null;\n\n  if (ret === null) {\n    state.needReadable = true;\n    n = 0;\n  } else {\n    state.length -= n;\n  }\n\n  if (state.length === 0) {\n    // If we have nothing in the buffer, then we want to know\n    // as soon as we *do* get something into the buffer.\n    if (!state.ended) state.needReadable = true;\n\n    // If we tried to read() past the EOF, then emit end on the next tick.\n    if (nOrig !== n && state.ended) endReadable(this);\n  }\n\n  if (ret !== null) this.emit('data', ret);\n\n  return ret;\n};\n\nfunction chunkInvalid(state, chunk) {\n  var er = null;\n  if (!Buffer.isBuffer(chunk) && typeof chunk !== 'string' && chunk !== null && chunk !== undefined && !state.objectMode) {\n    er = new TypeError('Invalid non-string/buffer chunk');\n  }\n  return er;\n}\n\nfunction onEofChunk(stream, state) {\n  if (state.ended) return;\n  if (state.decoder) {\n    var chunk = state.decoder.end();\n    if (chunk && chunk.length) {\n      state.buffer.push(chunk);\n      state.length += state.objectMode ? 1 : chunk.length;\n    }\n  }\n  state.ended = true;\n\n  // emit 'readable' now to make sure it gets picked up.\n  emitReadable(stream);\n}\n\n// Don't emit readable right away in sync mode, because this can trigger\n// another read() call => stack overflow.  This way, it might trigger\n// a nextTick recursion warning, but that's not so bad.\nfunction emitReadable(stream) {\n  var state = stream._readableState;\n  state.needReadable = false;\n  if (!state.emittedReadable) {\n    debug('emitReadable', state.flowing);\n    state.emittedReadable = true;\n    if (state.sync) processNextTick(emitReadable_, stream);else emitReadable_(stream);\n  }\n}\n\nfunction emitReadable_(stream) {\n  debug('emit readable');\n  stream.emit('readable');\n  flow(stream);\n}\n\n// at this point, the user has presumably seen the 'readable' event,\n// and called read() to consume some data.  that may have triggered\n// in turn another _read(n) call, in which case reading = true if\n// it's in progress.\n// However, if we're not ended, or reading, and the length < hwm,\n// then go ahead and try to read some more preemptively.\nfunction maybeReadMore(stream, state) {\n  if (!state.readingMore) {\n    state.readingMore = true;\n    processNextTick(maybeReadMore_, stream, state);\n  }\n}\n\nfunction maybeReadMore_(stream, state) {\n  var len = state.length;\n  while (!state.reading && !state.flowing && !state.ended && state.length < state.highWaterMark) {\n    debug('maybeReadMore read 0');\n    stream.read(0);\n    if (len === state.length)\n      // didn't get any data, stop spinning.\n      break;else len = state.length;\n  }\n  state.readingMore = false;\n}\n\n// abstract method.  to be overridden in specific implementation classes.\n// call cb(er, data) where data is <= n in length.\n// for virtual (non-string, non-buffer) streams, \"length\" is somewhat\n// arbitrary, and perhaps not very meaningful.\nReadable.prototype._read = function (n) {\n  this.emit('error', new Error('not implemented'));\n};\n\nReadable.prototype.pipe = function (dest, pipeOpts) {\n  var src = this;\n  var state = this._readableState;\n\n  switch (state.pipesCount) {\n    case 0:\n      state.pipes = dest;\n      break;\n    case 1:\n      state.pipes = [state.pipes, dest];\n      break;\n    default:\n      state.pipes.push(dest);\n      break;\n  }\n  state.pipesCount += 1;\n  debug('pipe count=%d opts=%j', state.pipesCount, pipeOpts);\n\n  var doEnd = (!pipeOpts || pipeOpts.end !== false) && dest !== process.stdout && dest !== process.stderr;\n\n  var endFn = doEnd ? onend : cleanup;\n  if (state.endEmitted) processNextTick(endFn);else src.once('end', endFn);\n\n  dest.on('unpipe', onunpipe);\n  function onunpipe(readable) {\n    debug('onunpipe');\n    if (readable === src) {\n      cleanup();\n    }\n  }\n\n  function onend() {\n    debug('onend');\n    dest.end();\n  }\n\n  // when the dest drains, it reduces the awaitDrain counter\n  // on the source.  This would be more elegant with a .once()\n  // handler in flow(), but adding and removing repeatedly is\n  // too slow.\n  var ondrain = pipeOnDrain(src);\n  dest.on('drain', ondrain);\n\n  var cleanedUp = false;\n  function cleanup() {\n    debug('cleanup');\n    // cleanup event handlers once the pipe is broken\n    dest.removeListener('close', onclose);\n    dest.removeListener('finish', onfinish);\n    dest.removeListener('drain', ondrain);\n    dest.removeListener('error', onerror);\n    dest.removeListener('unpipe', onunpipe);\n    src.removeListener('end', onend);\n    src.removeListener('end', cleanup);\n    src.removeListener('data', ondata);\n\n    cleanedUp = true;\n\n    // if the reader is waiting for a drain event from this\n    // specific writer, then it would cause it to never start\n    // flowing again.\n    // So, if this is awaiting a drain, then we just call it now.\n    // If we don't know, then assume that we are waiting for one.\n    if (state.awaitDrain && (!dest._writableState || dest._writableState.needDrain)) ondrain();\n  }\n\n  // If the user pushes more data while we're writing to dest then we'll end up\n  // in ondata again. However, we only want to increase awaitDrain once because\n  // dest will only emit one 'drain' event for the multiple writes.\n  // => Introduce a guard on increasing awaitDrain.\n  var increasedAwaitDrain = false;\n  src.on('data', ondata);\n  function ondata(chunk) {\n    debug('ondata');\n    increasedAwaitDrain = false;\n    var ret = dest.write(chunk);\n    if (false === ret && !increasedAwaitDrain) {\n      // If the user unpiped during `dest.write()`, it is possible\n      // to get stuck in a permanently paused state if that write\n      // also returned false.\n      // => Check whether `dest` is still a piping destination.\n      if ((state.pipesCount === 1 && state.pipes === dest || state.pipesCount > 1 && indexOf(state.pipes, dest) !== -1) && !cleanedUp) {\n        debug('false write response, pause', src._readableState.awaitDrain);\n        src._readableState.awaitDrain++;\n        increasedAwaitDrain = true;\n      }\n      src.pause();\n    }\n  }\n\n  // if the dest has an error, then stop piping into it.\n  // however, don't suppress the throwing behavior for this.\n  function onerror(er) {\n    debug('onerror', er);\n    unpipe();\n    dest.removeListener('error', onerror);\n    if (EElistenerCount(dest, 'error') === 0) dest.emit('error', er);\n  }\n\n  // Make sure our error handler is attached before userland ones.\n  prependListener(dest, 'error', onerror);\n\n  // Both close and finish should trigger unpipe, but only once.\n  function onclose() {\n    dest.removeListener('finish', onfinish);\n    unpipe();\n  }\n  dest.once('close', onclose);\n  function onfinish() {\n    debug('onfinish');\n    dest.removeListener('close', onclose);\n    unpipe();\n  }\n  dest.once('finish', onfinish);\n\n  function unpipe() {\n    debug('unpipe');\n    src.unpipe(dest);\n  }\n\n  // tell the dest that it's being piped to\n  dest.emit('pipe', src);\n\n  // start the flow if it hasn't been started already.\n  if (!state.flowing) {\n    debug('pipe resume');\n    src.resume();\n  }\n\n  return dest;\n};\n\nfunction pipeOnDrain(src) {\n  return function () {\n    var state = src._readableState;\n    debug('pipeOnDrain', state.awaitDrain);\n    if (state.awaitDrain) state.awaitDrain--;\n    if (state.awaitDrain === 0 && EElistenerCount(src, 'data')) {\n      state.flowing = true;\n      flow(src);\n    }\n  };\n}\n\nReadable.prototype.unpipe = function (dest) {\n  var state = this._readableState;\n\n  // if we're not piping anywhere, then do nothing.\n  if (state.pipesCount === 0) return this;\n\n  // just one destination.  most common case.\n  if (state.pipesCount === 1) {\n    // passed in one, but it's not the right one.\n    if (dest && dest !== state.pipes) return this;\n\n    if (!dest) dest = state.pipes;\n\n    // got a match.\n    state.pipes = null;\n    state.pipesCount = 0;\n    state.flowing = false;\n    if (dest) dest.emit('unpipe', this);\n    return this;\n  }\n\n  // slow case. multiple pipe destinations.\n\n  if (!dest) {\n    // remove all.\n    var dests = state.pipes;\n    var len = state.pipesCount;\n    state.pipes = null;\n    state.pipesCount = 0;\n    state.flowing = false;\n\n    for (var _i = 0; _i < len; _i++) {\n      dests[_i].emit('unpipe', this);\n    }return this;\n  }\n\n  // try to find the right one.\n  var i = indexOf(state.pipes, dest);\n  if (i === -1) return this;\n\n  state.pipes.splice(i, 1);\n  state.pipesCount -= 1;\n  if (state.pipesCount === 1) state.pipes = state.pipes[0];\n\n  dest.emit('unpipe', this);\n\n  return this;\n};\n\n// set up data events if they are asked for\n// Ensure readable listeners eventually get something\nReadable.prototype.on = function (ev, fn) {\n  var res = Stream.prototype.on.call(this, ev, fn);\n\n  if (ev === 'data') {\n    // Start flowing on next tick if stream isn't explicitly paused\n    if (this._readableState.flowing !== false) this.resume();\n  } else if (ev === 'readable') {\n    var state = this._readableState;\n    if (!state.endEmitted && !state.readableListening) {\n      state.readableListening = state.needReadable = true;\n      state.emittedReadable = false;\n      if (!state.reading) {\n        processNextTick(nReadingNextTick, this);\n      } else if (state.length) {\n        emitReadable(this, state);\n      }\n    }\n  }\n\n  return res;\n};\nReadable.prototype.addListener = Readable.prototype.on;\n\nfunction nReadingNextTick(self) {\n  debug('readable nexttick read 0');\n  self.read(0);\n}\n\n// pause() and resume() are remnants of the legacy readable stream API\n// If the user uses them, then switch into old mode.\nReadable.prototype.resume = function () {\n  var state = this._readableState;\n  if (!state.flowing) {\n    debug('resume');\n    state.flowing = true;\n    resume(this, state);\n  }\n  return this;\n};\n\nfunction resume(stream, state) {\n  if (!state.resumeScheduled) {\n    state.resumeScheduled = true;\n    processNextTick(resume_, stream, state);\n  }\n}\n\nfunction resume_(stream, state) {\n  if (!state.reading) {\n    debug('resume read 0');\n    stream.read(0);\n  }\n\n  state.resumeScheduled = false;\n  state.awaitDrain = 0;\n  stream.emit('resume');\n  flow(stream);\n  if (state.flowing && !state.reading) stream.read(0);\n}\n\nReadable.prototype.pause = function () {\n  debug('call pause flowing=%j', this._readableState.flowing);\n  if (false !== this._readableState.flowing) {\n    debug('pause');\n    this._readableState.flowing = false;\n    this.emit('pause');\n  }\n  return this;\n};\n\nfunction flow(stream) {\n  var state = stream._readableState;\n  debug('flow', state.flowing);\n  while (state.flowing && stream.read() !== null) {}\n}\n\n// wrap an old-style stream as the async data source.\n// This is *not* part of the readable stream interface.\n// It is an ugly unfortunate mess of history.\nReadable.prototype.wrap = function (stream) {\n  var state = this._readableState;\n  var paused = false;\n\n  var self = this;\n  stream.on('end', function () {\n    debug('wrapped end');\n    if (state.decoder && !state.ended) {\n      var chunk = state.decoder.end();\n      if (chunk && chunk.length) self.push(chunk);\n    }\n\n    self.push(null);\n  });\n\n  stream.on('data', function (chunk) {\n    debug('wrapped data');\n    if (state.decoder) chunk = state.decoder.write(chunk);\n\n    // don't skip over falsy values in objectMode\n    if (state.objectMode && (chunk === null || chunk === undefined)) return;else if (!state.objectMode && (!chunk || !chunk.length)) return;\n\n    var ret = self.push(chunk);\n    if (!ret) {\n      paused = true;\n      stream.pause();\n    }\n  });\n\n  // proxy all the other methods.\n  // important when wrapping filters and duplexes.\n  for (var i in stream) {\n    if (this[i] === undefined && typeof stream[i] === 'function') {\n      this[i] = function (method) {\n        return function () {\n          return stream[method].apply(stream, arguments);\n        };\n      }(i);\n    }\n  }\n\n  // proxy certain important events.\n  var events = ['error', 'close', 'destroy', 'pause', 'resume'];\n  forEach(events, function (ev) {\n    stream.on(ev, self.emit.bind(self, ev));\n  });\n\n  // when we try to consume some more bytes, simply unpause the\n  // underlying stream.\n  self._read = function (n) {\n    debug('wrapped _read', n);\n    if (paused) {\n      paused = false;\n      stream.resume();\n    }\n  };\n\n  return self;\n};\n\n// exposed for testing purposes only.\nReadable._fromList = fromList;\n\n// Pluck off n bytes from an array of buffers.\n// Length is the combined lengths of all the buffers in the list.\n// This function is designed to be inlinable, so please take care when making\n// changes to the function body.\nfunction fromList(n, state) {\n  // nothing buffered\n  if (state.length === 0) return null;\n\n  var ret;\n  if (state.objectMode) ret = state.buffer.shift();else if (!n || n >= state.length) {\n    // read it all, truncate the list\n    if (state.decoder) ret = state.buffer.join('');else if (state.buffer.length === 1) ret = state.buffer.head.data;else ret = state.buffer.concat(state.length);\n    state.buffer.clear();\n  } else {\n    // read part of list\n    ret = fromListPartial(n, state.buffer, state.decoder);\n  }\n\n  return ret;\n}\n\n// Extracts only enough buffered data to satisfy the amount requested.\n// This function is designed to be inlinable, so please take care when making\n// changes to the function body.\nfunction fromListPartial(n, list, hasStrings) {\n  var ret;\n  if (n < list.head.data.length) {\n    // slice is the same for buffers and strings\n    ret = list.head.data.slice(0, n);\n    list.head.data = list.head.data.slice(n);\n  } else if (n === list.head.data.length) {\n    // first chunk is a perfect match\n    ret = list.shift();\n  } else {\n    // result spans more than one buffer\n    ret = hasStrings ? copyFromBufferString(n, list) : copyFromBuffer(n, list);\n  }\n  return ret;\n}\n\n// Copies a specified amount of characters from the list of buffered data\n// chunks.\n// This function is designed to be inlinable, so please take care when making\n// changes to the function body.\nfunction copyFromBufferString(n, list) {\n  var p = list.head;\n  var c = 1;\n  var ret = p.data;\n  n -= ret.length;\n  while (p = p.next) {\n    var str = p.data;\n    var nb = n > str.length ? str.length : n;\n    if (nb === str.length) ret += str;else ret += str.slice(0, n);\n    n -= nb;\n    if (n === 0) {\n      if (nb === str.length) {\n        ++c;\n        if (p.next) list.head = p.next;else list.head = list.tail = null;\n      } else {\n        list.head = p;\n        p.data = str.slice(nb);\n      }\n      break;\n    }\n    ++c;\n  }\n  list.length -= c;\n  return ret;\n}\n\n// Copies a specified amount of bytes from the list of buffered data chunks.\n// This function is designed to be inlinable, so please take care when making\n// changes to the function body.\nfunction copyFromBuffer(n, list) {\n  var ret = bufferShim.allocUnsafe(n);\n  var p = list.head;\n  var c = 1;\n  p.data.copy(ret);\n  n -= p.data.length;\n  while (p = p.next) {\n    var buf = p.data;\n    var nb = n > buf.length ? buf.length : n;\n    buf.copy(ret, ret.length - n, 0, nb);\n    n -= nb;\n    if (n === 0) {\n      if (nb === buf.length) {\n        ++c;\n        if (p.next) list.head = p.next;else list.head = list.tail = null;\n      } else {\n        list.head = p;\n        p.data = buf.slice(nb);\n      }\n      break;\n    }\n    ++c;\n  }\n  list.length -= c;\n  return ret;\n}\n\nfunction endReadable(stream) {\n  var state = stream._readableState;\n\n  // If we get here before consuming all the bytes, then that is a\n  // bug in node.  Should never happen.\n  if (state.length > 0) throw new Error('\"endReadable()\" called on non-empty stream');\n\n  if (!state.endEmitted) {\n    state.ended = true;\n    processNextTick(endReadableNT, state, stream);\n  }\n}\n\nfunction endReadableNT(state, stream) {\n  // Check that we didn't get one last unshift.\n  if (!state.endEmitted && state.length === 0) {\n    state.endEmitted = true;\n    stream.readable = false;\n    stream.emit('end');\n  }\n}\n\nfunction forEach(xs, f) {\n  for (var i = 0, l = xs.length; i < l; i++) {\n    f(xs[i], i);\n  }\n}\n\nfunction indexOf(xs, x) {\n  for (var i = 0, l = xs.length; i < l; i++) {\n    if (xs[i] === x) return i;\n  }\n  return -1;\n}\n}).call(this,require('_process'))\n},{\"./_stream_duplex\":69,\"./internal/streams/BufferList\":74,\"_process\":67,\"buffer\":44,\"buffer-shims\":43,\"core-util-is\":45,\"events\":48,\"inherits\":51,\"isarray\":53,\"process-nextick-args\":66,\"string_decoder/\":80,\"util\":40}],72:[function(require,module,exports){\n// a transform stream is a readable/writable stream where you do\n// something with the data.  Sometimes it's called a \"filter\",\n// but that's not a great name for it, since that implies a thing where\n// some bits pass through, and others are simply ignored.  (That would\n// be a valid example of a transform, of course.)\n//\n// While the output is causally related to the input, it's not a\n// necessarily symmetric or synchronous transformation.  For example,\n// a zlib stream might take multiple plain-text writes(), and then\n// emit a single compressed chunk some time in the future.\n//\n// Here's how this works:\n//\n// The Transform stream has all the aspects of the readable and writable\n// stream classes.  When you write(chunk), that calls _write(chunk,cb)\n// internally, and returns false if there's a lot of pending writes\n// buffered up.  When you call read(), that calls _read(n) until\n// there's enough pending readable data buffered up.\n//\n// In a transform stream, the written data is placed in a buffer.  When\n// _read(n) is called, it transforms the queued up data, calling the\n// buffered _write cb's as it consumes chunks.  If consuming a single\n// written chunk would result in multiple output chunks, then the first\n// outputted bit calls the readcb, and subsequent chunks just go into\n// the read buffer, and will cause it to emit 'readable' if necessary.\n//\n// This way, back-pressure is actually determined by the reading side,\n// since _read has to be called to start processing a new chunk.  However,\n// a pathological inflate type of transform can cause excessive buffering\n// here.  For example, imagine a stream where every byte of input is\n// interpreted as an integer from 0-255, and then results in that many\n// bytes of output.  Writing the 4 bytes {ff,ff,ff,ff} would result in\n// 1kb of data being output.  In this case, you could write a very small\n// amount of input, and end up with a very large amount of output.  In\n// such a pathological inflating mechanism, there'd be no way to tell\n// the system to stop doing the transform.  A single 4MB write could\n// cause the system to run out of memory.\n//\n// However, even in such a pathological case, only a single written chunk\n// would be consumed, and then the rest would wait (un-transformed) until\n// the results of the previous transformed chunk were consumed.\n\n'use strict';\n\nmodule.exports = Transform;\n\nvar Duplex = require('./_stream_duplex');\n\n/*<replacement>*/\nvar util = require('core-util-is');\nutil.inherits = require('inherits');\n/*</replacement>*/\n\nutil.inherits(Transform, Duplex);\n\nfunction TransformState(stream) {\n  this.afterTransform = function (er, data) {\n    return afterTransform(stream, er, data);\n  };\n\n  this.needTransform = false;\n  this.transforming = false;\n  this.writecb = null;\n  this.writechunk = null;\n  this.writeencoding = null;\n}\n\nfunction afterTransform(stream, er, data) {\n  var ts = stream._transformState;\n  ts.transforming = false;\n\n  var cb = ts.writecb;\n\n  if (!cb) return stream.emit('error', new Error('no writecb in Transform class'));\n\n  ts.writechunk = null;\n  ts.writecb = null;\n\n  if (data !== null && data !== undefined) stream.push(data);\n\n  cb(er);\n\n  var rs = stream._readableState;\n  rs.reading = false;\n  if (rs.needReadable || rs.length < rs.highWaterMark) {\n    stream._read(rs.highWaterMark);\n  }\n}\n\nfunction Transform(options) {\n  if (!(this instanceof Transform)) return new Transform(options);\n\n  Duplex.call(this, options);\n\n  this._transformState = new TransformState(this);\n\n  // when the writable side finishes, then flush out anything remaining.\n  var stream = this;\n\n  // start out asking for a readable event once data is transformed.\n  this._readableState.needReadable = true;\n\n  // we have implemented the _read method, and done the other things\n  // that Readable wants before the first _read call, so unset the\n  // sync guard flag.\n  this._readableState.sync = false;\n\n  if (options) {\n    if (typeof options.transform === 'function') this._transform = options.transform;\n\n    if (typeof options.flush === 'function') this._flush = options.flush;\n  }\n\n  this.once('prefinish', function () {\n    if (typeof this._flush === 'function') this._flush(function (er) {\n      done(stream, er);\n    });else done(stream);\n  });\n}\n\nTransform.prototype.push = function (chunk, encoding) {\n  this._transformState.needTransform = false;\n  return Duplex.prototype.push.call(this, chunk, encoding);\n};\n\n// This is the part where you do stuff!\n// override this function in implementation classes.\n// 'chunk' is an input chunk.\n//\n// Call `push(newChunk)` to pass along transformed output\n// to the readable side.  You may call 'push' zero or more times.\n//\n// Call `cb(err)` when you are done with this chunk.  If you pass\n// an error, then that'll put the hurt on the whole operation.  If you\n// never call cb(), then you'll never get another chunk.\nTransform.prototype._transform = function (chunk, encoding, cb) {\n  throw new Error('Not implemented');\n};\n\nTransform.prototype._write = function (chunk, encoding, cb) {\n  var ts = this._transformState;\n  ts.writecb = cb;\n  ts.writechunk = chunk;\n  ts.writeencoding = encoding;\n  if (!ts.transforming) {\n    var rs = this._readableState;\n    if (ts.needTransform || rs.needReadable || rs.length < rs.highWaterMark) this._read(rs.highWaterMark);\n  }\n};\n\n// Doesn't matter what the args are here.\n// _transform does all the work.\n// That we got here means that the readable side wants more data.\nTransform.prototype._read = function (n) {\n  var ts = this._transformState;\n\n  if (ts.writechunk !== null && ts.writecb && !ts.transforming) {\n    ts.transforming = true;\n    this._transform(ts.writechunk, ts.writeencoding, ts.afterTransform);\n  } else {\n    // mark that we need a transform, so that any data that comes in\n    // will get processed, now that we've asked for it.\n    ts.needTransform = true;\n  }\n};\n\nfunction done(stream, er) {\n  if (er) return stream.emit('error', er);\n\n  // if there's nothing in the write buffer, then that means\n  // that nothing more will ever be provided\n  var ws = stream._writableState;\n  var ts = stream._transformState;\n\n  if (ws.length) throw new Error('Calling transform done when ws.length != 0');\n\n  if (ts.transforming) throw new Error('Calling transform done when still transforming');\n\n  return stream.push(null);\n}\n},{\"./_stream_duplex\":69,\"core-util-is\":45,\"inherits\":51}],73:[function(require,module,exports){\n(function (process){\n// A bit simpler than readable streams.\n// Implement an async ._write(chunk, encoding, cb), and it'll handle all\n// the drain event emission and buffering.\n\n'use strict';\n\nmodule.exports = Writable;\n\n/*<replacement>*/\nvar processNextTick = require('process-nextick-args');\n/*</replacement>*/\n\n/*<replacement>*/\nvar asyncWrite = !process.browser && ['v0.10', 'v0.9.'].indexOf(process.version.slice(0, 5)) > -1 ? setImmediate : processNextTick;\n/*</replacement>*/\n\nWritable.WritableState = WritableState;\n\n/*<replacement>*/\nvar util = require('core-util-is');\nutil.inherits = require('inherits');\n/*</replacement>*/\n\n/*<replacement>*/\nvar internalUtil = {\n  deprecate: require('util-deprecate')\n};\n/*</replacement>*/\n\n/*<replacement>*/\nvar Stream;\n(function () {\n  try {\n    Stream = require('st' + 'ream');\n  } catch (_) {} finally {\n    if (!Stream) Stream = require('events').EventEmitter;\n  }\n})();\n/*</replacement>*/\n\nvar Buffer = require('buffer').Buffer;\n/*<replacement>*/\nvar bufferShim = require('buffer-shims');\n/*</replacement>*/\n\nutil.inherits(Writable, Stream);\n\nfunction nop() {}\n\nfunction WriteReq(chunk, encoding, cb) {\n  this.chunk = chunk;\n  this.encoding = encoding;\n  this.callback = cb;\n  this.next = null;\n}\n\nvar Duplex;\nfunction WritableState(options, stream) {\n  Duplex = Duplex || require('./_stream_duplex');\n\n  options = options || {};\n\n  // object stream flag to indicate whether or not this stream\n  // contains buffers or objects.\n  this.objectMode = !!options.objectMode;\n\n  if (stream instanceof Duplex) this.objectMode = this.objectMode || !!options.writableObjectMode;\n\n  // the point at which write() starts returning false\n  // Note: 0 is a valid value, means that we always return false if\n  // the entire buffer is not flushed immediately on write()\n  var hwm = options.highWaterMark;\n  var defaultHwm = this.objectMode ? 16 : 16 * 1024;\n  this.highWaterMark = hwm || hwm === 0 ? hwm : defaultHwm;\n\n  // cast to ints.\n  this.highWaterMark = ~ ~this.highWaterMark;\n\n  this.needDrain = false;\n  // at the start of calling end()\n  this.ending = false;\n  // when end() has been called, and returned\n  this.ended = false;\n  // when 'finish' is emitted\n  this.finished = false;\n\n  // should we decode strings into buffers before passing to _write?\n  // this is here so that some node-core streams can optimize string\n  // handling at a lower level.\n  var noDecode = options.decodeStrings === false;\n  this.decodeStrings = !noDecode;\n\n  // Crypto is kind of old and crusty.  Historically, its default string\n  // encoding is 'binary' so we have to make this configurable.\n  // Everything else in the universe uses 'utf8', though.\n  this.defaultEncoding = options.defaultEncoding || 'utf8';\n\n  // not an actual buffer we keep track of, but a measurement\n  // of how much we're waiting to get pushed to some underlying\n  // socket or file.\n  this.length = 0;\n\n  // a flag to see when we're in the middle of a write.\n  this.writing = false;\n\n  // when true all writes will be buffered until .uncork() call\n  this.corked = 0;\n\n  // a flag to be able to tell if the onwrite cb is called immediately,\n  // or on a later tick.  We set this to true at first, because any\n  // actions that shouldn't happen until \"later\" should generally also\n  // not happen before the first write call.\n  this.sync = true;\n\n  // a flag to know if we're processing previously buffered items, which\n  // may call the _write() callback in the same tick, so that we don't\n  // end up in an overlapped onwrite situation.\n  this.bufferProcessing = false;\n\n  // the callback that's passed to _write(chunk,cb)\n  this.onwrite = function (er) {\n    onwrite(stream, er);\n  };\n\n  // the callback that the user supplies to write(chunk,encoding,cb)\n  this.writecb = null;\n\n  // the amount that is being written when _write is called.\n  this.writelen = 0;\n\n  this.bufferedRequest = null;\n  this.lastBufferedRequest = null;\n\n  // number of pending user-supplied write callbacks\n  // this must be 0 before 'finish' can be emitted\n  this.pendingcb = 0;\n\n  // emit prefinish if the only thing we're waiting for is _write cbs\n  // This is relevant for synchronous Transform streams\n  this.prefinished = false;\n\n  // True if the error was already emitted and should not be thrown again\n  this.errorEmitted = false;\n\n  // count buffered requests\n  this.bufferedRequestCount = 0;\n\n  // allocate the first CorkedRequest, there is always\n  // one allocated and free to use, and we maintain at most two\n  this.corkedRequestsFree = new CorkedRequest(this);\n}\n\nWritableState.prototype.getBuffer = function writableStateGetBuffer() {\n  var current = this.bufferedRequest;\n  var out = [];\n  while (current) {\n    out.push(current);\n    current = current.next;\n  }\n  return out;\n};\n\n(function () {\n  try {\n    Object.defineProperty(WritableState.prototype, 'buffer', {\n      get: internalUtil.deprecate(function () {\n        return this.getBuffer();\n      }, '_writableState.buffer is deprecated. Use _writableState.getBuffer ' + 'instead.')\n    });\n  } catch (_) {}\n})();\n\nvar Duplex;\nfunction Writable(options) {\n  Duplex = Duplex || require('./_stream_duplex');\n\n  // Writable ctor is applied to Duplexes, though they're not\n  // instanceof Writable, they're instanceof Readable.\n  if (!(this instanceof Writable) && !(this instanceof Duplex)) return new Writable(options);\n\n  this._writableState = new WritableState(options, this);\n\n  // legacy.\n  this.writable = true;\n\n  if (options) {\n    if (typeof options.write === 'function') this._write = options.write;\n\n    if (typeof options.writev === 'function') this._writev = options.writev;\n  }\n\n  Stream.call(this);\n}\n\n// Otherwise people can pipe Writable streams, which is just wrong.\nWritable.prototype.pipe = function () {\n  this.emit('error', new Error('Cannot pipe, not readable'));\n};\n\nfunction writeAfterEnd(stream, cb) {\n  var er = new Error('write after end');\n  // TODO: defer error events consistently everywhere, not just the cb\n  stream.emit('error', er);\n  processNextTick(cb, er);\n}\n\n// If we get something that is not a buffer, string, null, or undefined,\n// and we're not in objectMode, then that's an error.\n// Otherwise stream chunks are all considered to be of length=1, and the\n// watermarks determine how many objects to keep in the buffer, rather than\n// how many bytes or characters.\nfunction validChunk(stream, state, chunk, cb) {\n  var valid = true;\n  var er = false;\n  // Always throw error if a null is written\n  // if we are not in object mode then throw\n  // if it is not a buffer, string, or undefined.\n  if (chunk === null) {\n    er = new TypeError('May not write null values to stream');\n  } else if (!Buffer.isBuffer(chunk) && typeof chunk !== 'string' && chunk !== undefined && !state.objectMode) {\n    er = new TypeError('Invalid non-string/buffer chunk');\n  }\n  if (er) {\n    stream.emit('error', er);\n    processNextTick(cb, er);\n    valid = false;\n  }\n  return valid;\n}\n\nWritable.prototype.write = function (chunk, encoding, cb) {\n  var state = this._writableState;\n  var ret = false;\n\n  if (typeof encoding === 'function') {\n    cb = encoding;\n    encoding = null;\n  }\n\n  if (Buffer.isBuffer(chunk)) encoding = 'buffer';else if (!encoding) encoding = state.defaultEncoding;\n\n  if (typeof cb !== 'function') cb = nop;\n\n  if (state.ended) writeAfterEnd(this, cb);else if (validChunk(this, state, chunk, cb)) {\n    state.pendingcb++;\n    ret = writeOrBuffer(this, state, chunk, encoding, cb);\n  }\n\n  return ret;\n};\n\nWritable.prototype.cork = function () {\n  var state = this._writableState;\n\n  state.corked++;\n};\n\nWritable.prototype.uncork = function () {\n  var state = this._writableState;\n\n  if (state.corked) {\n    state.corked--;\n\n    if (!state.writing && !state.corked && !state.finished && !state.bufferProcessing && state.bufferedRequest) clearBuffer(this, state);\n  }\n};\n\nWritable.prototype.setDefaultEncoding = function setDefaultEncoding(encoding) {\n  // node::ParseEncoding() requires lower case.\n  if (typeof encoding === 'string') encoding = encoding.toLowerCase();\n  if (!(['hex', 'utf8', 'utf-8', 'ascii', 'binary', 'base64', 'ucs2', 'ucs-2', 'utf16le', 'utf-16le', 'raw'].indexOf((encoding + '').toLowerCase()) > -1)) throw new TypeError('Unknown encoding: ' + encoding);\n  this._writableState.defaultEncoding = encoding;\n  return this;\n};\n\nfunction decodeChunk(state, chunk, encoding) {\n  if (!state.objectMode && state.decodeStrings !== false && typeof chunk === 'string') {\n    chunk = bufferShim.from(chunk, encoding);\n  }\n  return chunk;\n}\n\n// if we're already writing something, then just put this\n// in the queue, and wait our turn.  Otherwise, call _write\n// If we return false, then we need a drain event, so set that flag.\nfunction writeOrBuffer(stream, state, chunk, encoding, cb) {\n  chunk = decodeChunk(state, chunk, encoding);\n\n  if (Buffer.isBuffer(chunk)) encoding = 'buffer';\n  var len = state.objectMode ? 1 : chunk.length;\n\n  state.length += len;\n\n  var ret = state.length < state.highWaterMark;\n  // we must ensure that previous needDrain will not be reset to false.\n  if (!ret) state.needDrain = true;\n\n  if (state.writing || state.corked) {\n    var last = state.lastBufferedRequest;\n    state.lastBufferedRequest = new WriteReq(chunk, encoding, cb);\n    if (last) {\n      last.next = state.lastBufferedRequest;\n    } else {\n      state.bufferedRequest = state.lastBufferedRequest;\n    }\n    state.bufferedRequestCount += 1;\n  } else {\n    doWrite(stream, state, false, len, chunk, encoding, cb);\n  }\n\n  return ret;\n}\n\nfunction doWrite(stream, state, writev, len, chunk, encoding, cb) {\n  state.writelen = len;\n  state.writecb = cb;\n  state.writing = true;\n  state.sync = true;\n  if (writev) stream._writev(chunk, state.onwrite);else stream._write(chunk, encoding, state.onwrite);\n  state.sync = false;\n}\n\nfunction onwriteError(stream, state, sync, er, cb) {\n  --state.pendingcb;\n  if (sync) processNextTick(cb, er);else cb(er);\n\n  stream._writableState.errorEmitted = true;\n  stream.emit('error', er);\n}\n\nfunction onwriteStateUpdate(state) {\n  state.writing = false;\n  state.writecb = null;\n  state.length -= state.writelen;\n  state.writelen = 0;\n}\n\nfunction onwrite(stream, er) {\n  var state = stream._writableState;\n  var sync = state.sync;\n  var cb = state.writecb;\n\n  onwriteStateUpdate(state);\n\n  if (er) onwriteError(stream, state, sync, er, cb);else {\n    // Check if we're actually ready to finish, but don't emit yet\n    var finished = needFinish(state);\n\n    if (!finished && !state.corked && !state.bufferProcessing && state.bufferedRequest) {\n      clearBuffer(stream, state);\n    }\n\n    if (sync) {\n      /*<replacement>*/\n      asyncWrite(afterWrite, stream, state, finished, cb);\n      /*</replacement>*/\n    } else {\n        afterWrite(stream, state, finished, cb);\n      }\n  }\n}\n\nfunction afterWrite(stream, state, finished, cb) {\n  if (!finished) onwriteDrain(stream, state);\n  state.pendingcb--;\n  cb();\n  finishMaybe(stream, state);\n}\n\n// Must force callback to be called on nextTick, so that we don't\n// emit 'drain' before the write() consumer gets the 'false' return\n// value, and has a chance to attach a 'drain' listener.\nfunction onwriteDrain(stream, state) {\n  if (state.length === 0 && state.needDrain) {\n    state.needDrain = false;\n    stream.emit('drain');\n  }\n}\n\n// if there's something in the buffer waiting, then process it\nfunction clearBuffer(stream, state) {\n  state.bufferProcessing = true;\n  var entry = state.bufferedRequest;\n\n  if (stream._writev && entry && entry.next) {\n    // Fast case, write everything using _writev()\n    var l = state.bufferedRequestCount;\n    var buffer = new Array(l);\n    var holder = state.corkedRequestsFree;\n    holder.entry = entry;\n\n    var count = 0;\n    while (entry) {\n      buffer[count] = entry;\n      entry = entry.next;\n      count += 1;\n    }\n\n    doWrite(stream, state, true, state.length, buffer, '', holder.finish);\n\n    // doWrite is almost always async, defer these to save a bit of time\n    // as the hot path ends with doWrite\n    state.pendingcb++;\n    state.lastBufferedRequest = null;\n    if (holder.next) {\n      state.corkedRequestsFree = holder.next;\n      holder.next = null;\n    } else {\n      state.corkedRequestsFree = new CorkedRequest(state);\n    }\n  } else {\n    // Slow case, write chunks one-by-one\n    while (entry) {\n      var chunk = entry.chunk;\n      var encoding = entry.encoding;\n      var cb = entry.callback;\n      var len = state.objectMode ? 1 : chunk.length;\n\n      doWrite(stream, state, false, len, chunk, encoding, cb);\n      entry = entry.next;\n      // if we didn't call the onwrite immediately, then\n      // it means that we need to wait until it does.\n      // also, that means that the chunk and cb are currently\n      // being processed, so move the buffer counter past them.\n      if (state.writing) {\n        break;\n      }\n    }\n\n    if (entry === null) state.lastBufferedRequest = null;\n  }\n\n  state.bufferedRequestCount = 0;\n  state.bufferedRequest = entry;\n  state.bufferProcessing = false;\n}\n\nWritable.prototype._write = function (chunk, encoding, cb) {\n  cb(new Error('not implemented'));\n};\n\nWritable.prototype._writev = null;\n\nWritable.prototype.end = function (chunk, encoding, cb) {\n  var state = this._writableState;\n\n  if (typeof chunk === 'function') {\n    cb = chunk;\n    chunk = null;\n    encoding = null;\n  } else if (typeof encoding === 'function') {\n    cb = encoding;\n    encoding = null;\n  }\n\n  if (chunk !== null && chunk !== undefined) this.write(chunk, encoding);\n\n  // .end() fully uncorks\n  if (state.corked) {\n    state.corked = 1;\n    this.uncork();\n  }\n\n  // ignore unnecessary end() calls.\n  if (!state.ending && !state.finished) endWritable(this, state, cb);\n};\n\nfunction needFinish(state) {\n  return state.ending && state.length === 0 && state.bufferedRequest === null && !state.finished && !state.writing;\n}\n\nfunction prefinish(stream, state) {\n  if (!state.prefinished) {\n    state.prefinished = true;\n    stream.emit('prefinish');\n  }\n}\n\nfunction finishMaybe(stream, state) {\n  var need = needFinish(state);\n  if (need) {\n    if (state.pendingcb === 0) {\n      prefinish(stream, state);\n      state.finished = true;\n      stream.emit('finish');\n    } else {\n      prefinish(stream, state);\n    }\n  }\n  return need;\n}\n\nfunction endWritable(stream, state, cb) {\n  state.ending = true;\n  finishMaybe(stream, state);\n  if (cb) {\n    if (state.finished) processNextTick(cb);else stream.once('finish', cb);\n  }\n  state.ended = true;\n  stream.writable = false;\n}\n\n// It seems a linked list but it is not\n// there will be only 2 of these for each stream\nfunction CorkedRequest(state) {\n  var _this = this;\n\n  this.next = null;\n  this.entry = null;\n\n  this.finish = function (err) {\n    var entry = _this.entry;\n    _this.entry = null;\n    while (entry) {\n      var cb = entry.callback;\n      state.pendingcb--;\n      cb(err);\n      entry = entry.next;\n    }\n    if (state.corkedRequestsFree) {\n      state.corkedRequestsFree.next = _this;\n    } else {\n      state.corkedRequestsFree = _this;\n    }\n  };\n}\n}).call(this,require('_process'))\n},{\"./_stream_duplex\":69,\"_process\":67,\"buffer\":44,\"buffer-shims\":43,\"core-util-is\":45,\"events\":48,\"inherits\":51,\"process-nextick-args\":66,\"util-deprecate\":81}],74:[function(require,module,exports){\n'use strict';\n\nvar Buffer = require('buffer').Buffer;\n/*<replacement>*/\nvar bufferShim = require('buffer-shims');\n/*</replacement>*/\n\nmodule.exports = BufferList;\n\nfunction BufferList() {\n  this.head = null;\n  this.tail = null;\n  this.length = 0;\n}\n\nBufferList.prototype.push = function (v) {\n  var entry = { data: v, next: null };\n  if (this.length > 0) this.tail.next = entry;else this.head = entry;\n  this.tail = entry;\n  ++this.length;\n};\n\nBufferList.prototype.unshift = function (v) {\n  var entry = { data: v, next: this.head };\n  if (this.length === 0) this.tail = entry;\n  this.head = entry;\n  ++this.length;\n};\n\nBufferList.prototype.shift = function () {\n  if (this.length === 0) return;\n  var ret = this.head.data;\n  if (this.length === 1) this.head = this.tail = null;else this.head = this.head.next;\n  --this.length;\n  return ret;\n};\n\nBufferList.prototype.clear = function () {\n  this.head = this.tail = null;\n  this.length = 0;\n};\n\nBufferList.prototype.join = function (s) {\n  if (this.length === 0) return '';\n  var p = this.head;\n  var ret = '' + p.data;\n  while (p = p.next) {\n    ret += s + p.data;\n  }return ret;\n};\n\nBufferList.prototype.concat = function (n) {\n  if (this.length === 0) return bufferShim.alloc(0);\n  if (this.length === 1) return this.head.data;\n  var ret = bufferShim.allocUnsafe(n >>> 0);\n  var p = this.head;\n  var i = 0;\n  while (p) {\n    p.data.copy(ret, i);\n    i += p.data.length;\n    p = p.next;\n  }\n  return ret;\n};\n},{\"buffer\":44,\"buffer-shims\":43}],75:[function(require,module,exports){\nmodule.exports = require(\"./lib/_stream_passthrough.js\")\n\n},{\"./lib/_stream_passthrough.js\":70}],76:[function(require,module,exports){\n(function (process){\nvar Stream = (function (){\n  try {\n    return require('st' + 'ream'); // hack to fix a circular dependency issue when used with browserify\n  } catch(_){}\n}());\nexports = module.exports = require('./lib/_stream_readable.js');\nexports.Stream = Stream || exports;\nexports.Readable = exports;\nexports.Writable = require('./lib/_stream_writable.js');\nexports.Duplex = require('./lib/_stream_duplex.js');\nexports.Transform = require('./lib/_stream_transform.js');\nexports.PassThrough = require('./lib/_stream_passthrough.js');\n\nif (!process.browser && process.env.READABLE_STREAM === 'disable' && Stream) {\n  module.exports = Stream;\n}\n\n}).call(this,require('_process'))\n},{\"./lib/_stream_duplex.js\":69,\"./lib/_stream_passthrough.js\":70,\"./lib/_stream_readable.js\":71,\"./lib/_stream_transform.js\":72,\"./lib/_stream_writable.js\":73,\"_process\":67}],77:[function(require,module,exports){\nmodule.exports = require(\"./lib/_stream_transform.js\")\n\n},{\"./lib/_stream_transform.js\":72}],78:[function(require,module,exports){\nmodule.exports = require(\"./lib/_stream_writable.js\")\n\n},{\"./lib/_stream_writable.js\":73}],79:[function(require,module,exports){\n// Copyright Joyent, Inc. and other Node contributors.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a\n// copy of this software and associated documentation files (the\n// \"Software\"), to deal in the Software without restriction, including\n// without limitation the rights to use, copy, modify, merge, publish,\n// distribute, sublicense, and/or sell copies of the Software, and to permit\n// persons to whom the Software is furnished to do so, subject to the\n// following conditions:\n//\n// The above copyright notice and this permission notice shall be included\n// in all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS\n// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN\n// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,\n// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE\n// USE OR OTHER DEALINGS IN THE SOFTWARE.\n\nmodule.exports = Stream;\n\nvar EE = require('events').EventEmitter;\nvar inherits = require('inherits');\n\ninherits(Stream, EE);\nStream.Readable = require('readable-stream/readable.js');\nStream.Writable = require('readable-stream/writable.js');\nStream.Duplex = require('readable-stream/duplex.js');\nStream.Transform = require('readable-stream/transform.js');\nStream.PassThrough = require('readable-stream/passthrough.js');\n\n// Backwards-compat with node 0.4.x\nStream.Stream = Stream;\n\n\n\n// old-style streams.  Note that the pipe method (the only relevant\n// part of this class) is overridden in the Readable class.\n\nfunction Stream() {\n  EE.call(this);\n}\n\nStream.prototype.pipe = function(dest, options) {\n  var source = this;\n\n  function ondata(chunk) {\n    if (dest.writable) {\n      if (false === dest.write(chunk) && source.pause) {\n        source.pause();\n      }\n    }\n  }\n\n  source.on('data', ondata);\n\n  function ondrain() {\n    if (source.readable && source.resume) {\n      source.resume();\n    }\n  }\n\n  dest.on('drain', ondrain);\n\n  // If the 'end' option is not supplied, dest.end() will be called when\n  // source gets the 'end' or 'close' events.  Only dest.end() once.\n  if (!dest._isStdio && (!options || options.end !== false)) {\n    source.on('end', onend);\n    source.on('close', onclose);\n  }\n\n  var didOnEnd = false;\n  function onend() {\n    if (didOnEnd) return;\n    didOnEnd = true;\n\n    dest.end();\n  }\n\n\n  function onclose() {\n    if (didOnEnd) return;\n    didOnEnd = true;\n\n    if (typeof dest.destroy === 'function') dest.destroy();\n  }\n\n  // don't leave dangling pipes when there are errors.\n  function onerror(er) {\n    cleanup();\n    if (EE.listenerCount(this, 'error') === 0) {\n      throw er; // Unhandled stream error in pipe.\n    }\n  }\n\n  source.on('error', onerror);\n  dest.on('error', onerror);\n\n  // remove all the event listeners that were added.\n  function cleanup() {\n    source.removeListener('data', ondata);\n    dest.removeListener('drain', ondrain);\n\n    source.removeListener('end', onend);\n    source.removeListener('close', onclose);\n\n    source.removeListener('error', onerror);\n    dest.removeListener('error', onerror);\n\n    source.removeListener('end', cleanup);\n    source.removeListener('close', cleanup);\n\n    dest.removeListener('close', cleanup);\n  }\n\n  source.on('end', cleanup);\n  source.on('close', cleanup);\n\n  dest.on('close', cleanup);\n\n  dest.emit('pipe', source);\n\n  // Allow for unix-like usage: A.pipe(B).pipe(C)\n  return dest;\n};\n\n},{\"events\":48,\"inherits\":51,\"readable-stream/duplex.js\":68,\"readable-stream/passthrough.js\":75,\"readable-stream/readable.js\":76,\"readable-stream/transform.js\":77,\"readable-stream/writable.js\":78}],80:[function(require,module,exports){\n// Copyright Joyent, Inc. and other Node contributors.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a\n// copy of this software and associated documentation files (the\n// \"Software\"), to deal in the Software without restriction, including\n// without limitation the rights to use, copy, modify, merge, publish,\n// distribute, sublicense, and/or sell copies of the Software, and to permit\n// persons to whom the Software is furnished to do so, subject to the\n// following conditions:\n//\n// The above copyright notice and this permission notice shall be included\n// in all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS\n// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN\n// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,\n// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE\n// USE OR OTHER DEALINGS IN THE SOFTWARE.\n\nvar Buffer = require('buffer').Buffer;\n\nvar isBufferEncoding = Buffer.isEncoding\n  || function(encoding) {\n       switch (encoding && encoding.toLowerCase()) {\n         case 'hex': case 'utf8': case 'utf-8': case 'ascii': case 'binary': case 'base64': case 'ucs2': case 'ucs-2': case 'utf16le': case 'utf-16le': case 'raw': return true;\n         default: return false;\n       }\n     }\n\n\nfunction assertEncoding(encoding) {\n  if (encoding && !isBufferEncoding(encoding)) {\n    throw new Error('Unknown encoding: ' + encoding);\n  }\n}\n\n// StringDecoder provides an interface for efficiently splitting a series of\n// buffers into a series of JS strings without breaking apart multi-byte\n// characters. CESU-8 is handled as part of the UTF-8 encoding.\n//\n// @TODO Handling all encodings inside a single object makes it very difficult\n// to reason about this code, so it should be split up in the future.\n// @TODO There should be a utf8-strict encoding that rejects invalid UTF-8 code\n// points as used by CESU-8.\nvar StringDecoder = exports.StringDecoder = function(encoding) {\n  this.encoding = (encoding || 'utf8').toLowerCase().replace(/[-_]/, '');\n  assertEncoding(encoding);\n  switch (this.encoding) {\n    case 'utf8':\n      // CESU-8 represents each of Surrogate Pair by 3-bytes\n      this.surrogateSize = 3;\n      break;\n    case 'ucs2':\n    case 'utf16le':\n      // UTF-16 represents each of Surrogate Pair by 2-bytes\n      this.surrogateSize = 2;\n      this.detectIncompleteChar = utf16DetectIncompleteChar;\n      break;\n    case 'base64':\n      // Base-64 stores 3 bytes in 4 chars, and pads the remainder.\n      this.surrogateSize = 3;\n      this.detectIncompleteChar = base64DetectIncompleteChar;\n      break;\n    default:\n      this.write = passThroughWrite;\n      return;\n  }\n\n  // Enough space to store all bytes of a single character. UTF-8 needs 4\n  // bytes, but CESU-8 may require up to 6 (3 bytes per surrogate).\n  this.charBuffer = new Buffer(6);\n  // Number of bytes received for the current incomplete multi-byte character.\n  this.charReceived = 0;\n  // Number of bytes expected for the current incomplete multi-byte character.\n  this.charLength = 0;\n};\n\n\n// write decodes the given buffer and returns it as JS string that is\n// guaranteed to not contain any partial multi-byte characters. Any partial\n// character found at the end of the buffer is buffered up, and will be\n// returned when calling write again with the remaining bytes.\n//\n// Note: Converting a Buffer containing an orphan surrogate to a String\n// currently works, but converting a String to a Buffer (via `new Buffer`, or\n// Buffer#write) will replace incomplete surrogates with the unicode\n// replacement character. See https://codereview.chromium.org/121173009/ .\nStringDecoder.prototype.write = function(buffer) {\n  var charStr = '';\n  // if our last write ended with an incomplete multibyte character\n  while (this.charLength) {\n    // determine how many remaining bytes this buffer has to offer for this char\n    var available = (buffer.length >= this.charLength - this.charReceived) ?\n        this.charLength - this.charReceived :\n        buffer.length;\n\n    // add the new bytes to the char buffer\n    buffer.copy(this.charBuffer, this.charReceived, 0, available);\n    this.charReceived += available;\n\n    if (this.charReceived < this.charLength) {\n      // still not enough chars in this buffer? wait for more ...\n      return '';\n    }\n\n    // remove bytes belonging to the current character from the buffer\n    buffer = buffer.slice(available, buffer.length);\n\n    // get the character that was split\n    charStr = this.charBuffer.slice(0, this.charLength).toString(this.encoding);\n\n    // CESU-8: lead surrogate (D800-DBFF) is also the incomplete character\n    var charCode = charStr.charCodeAt(charStr.length - 1);\n    if (charCode >= 0xD800 && charCode <= 0xDBFF) {\n      this.charLength += this.surrogateSize;\n      charStr = '';\n      continue;\n    }\n    this.charReceived = this.charLength = 0;\n\n    // if there are no more bytes in this buffer, just emit our char\n    if (buffer.length === 0) {\n      return charStr;\n    }\n    break;\n  }\n\n  // determine and set charLength / charReceived\n  this.detectIncompleteChar(buffer);\n\n  var end = buffer.length;\n  if (this.charLength) {\n    // buffer the incomplete character bytes we got\n    buffer.copy(this.charBuffer, 0, buffer.length - this.charReceived, end);\n    end -= this.charReceived;\n  }\n\n  charStr += buffer.toString(this.encoding, 0, end);\n\n  var end = charStr.length - 1;\n  var charCode = charStr.charCodeAt(end);\n  // CESU-8: lead surrogate (D800-DBFF) is also the incomplete character\n  if (charCode >= 0xD800 && charCode <= 0xDBFF) {\n    var size = this.surrogateSize;\n    this.charLength += size;\n    this.charReceived += size;\n    this.charBuffer.copy(this.charBuffer, size, 0, size);\n    buffer.copy(this.charBuffer, 0, 0, size);\n    return charStr.substring(0, end);\n  }\n\n  // or just emit the charStr\n  return charStr;\n};\n\n// detectIncompleteChar determines if there is an incomplete UTF-8 character at\n// the end of the given buffer. If so, it sets this.charLength to the byte\n// length that character, and sets this.charReceived to the number of bytes\n// that are available for this character.\nStringDecoder.prototype.detectIncompleteChar = function(buffer) {\n  // determine how many bytes we have to check at the end of this buffer\n  var i = (buffer.length >= 3) ? 3 : buffer.length;\n\n  // Figure out if one of the last i bytes of our buffer announces an\n  // incomplete char.\n  for (; i > 0; i--) {\n    var c = buffer[buffer.length - i];\n\n    // See http://en.wikipedia.org/wiki/UTF-8#Description\n\n    // 110XXXXX\n    if (i == 1 && c >> 5 == 0x06) {\n      this.charLength = 2;\n      break;\n    }\n\n    // 1110XXXX\n    if (i <= 2 && c >> 4 == 0x0E) {\n      this.charLength = 3;\n      break;\n    }\n\n    // 11110XXX\n    if (i <= 3 && c >> 3 == 0x1E) {\n      this.charLength = 4;\n      break;\n    }\n  }\n  this.charReceived = i;\n};\n\nStringDecoder.prototype.end = function(buffer) {\n  var res = '';\n  if (buffer && buffer.length)\n    res = this.write(buffer);\n\n  if (this.charReceived) {\n    var cr = this.charReceived;\n    var buf = this.charBuffer;\n    var enc = this.encoding;\n    res += buf.slice(0, cr).toString(enc);\n  }\n\n  return res;\n};\n\nfunction passThroughWrite(buffer) {\n  return buffer.toString(this.encoding);\n}\n\nfunction utf16DetectIncompleteChar(buffer) {\n  this.charReceived = buffer.length % 2;\n  this.charLength = this.charReceived ? 2 : 0;\n}\n\nfunction base64DetectIncompleteChar(buffer) {\n  this.charReceived = buffer.length % 3;\n  this.charLength = this.charReceived ? 3 : 0;\n}\n\n},{\"buffer\":44}],81:[function(require,module,exports){\n(function (global){\n\n/**\n * Module exports.\n */\n\nmodule.exports = deprecate;\n\n/**\n * Mark that a method should not be used.\n * Returns a modified function which warns once by default.\n *\n * If `localStorage.noDeprecation = true` is set, then it is a no-op.\n *\n * If `localStorage.throwDeprecation = true` is set, then deprecated functions\n * will throw an Error when invoked.\n *\n * If `localStorage.traceDeprecation = true` is set, then deprecated functions\n * will invoke `console.trace()` instead of `console.error()`.\n *\n * @param {Function} fn - the function to deprecate\n * @param {String} msg - the string to print to the console when `fn` is invoked\n * @returns {Function} a new \"deprecated\" version of `fn`\n * @api public\n */\n\nfunction deprecate (fn, msg) {\n  if (config('noDeprecation')) {\n    return fn;\n  }\n\n  var warned = false;\n  function deprecated() {\n    if (!warned) {\n      if (config('throwDeprecation')) {\n        throw new Error(msg);\n      } else if (config('traceDeprecation')) {\n        console.trace(msg);\n      } else {\n        console.warn(msg);\n      }\n      warned = true;\n    }\n    return fn.apply(this, arguments);\n  }\n\n  return deprecated;\n}\n\n/**\n * Checks `localStorage` for boolean values for the given `name`.\n *\n * @param {String} name\n * @returns {Boolean}\n * @api private\n */\n\nfunction config (name) {\n  // accessing global.localStorage can trigger a DOMException in sandboxed iframes\n  try {\n    if (!global.localStorage) return false;\n  } catch (_) {\n    return false;\n  }\n  var val = global.localStorage[name];\n  if (null == val) return false;\n  return String(val).toLowerCase() === 'true';\n}\n\n}).call(this,typeof global !== \"undefined\" ? global : typeof self !== \"undefined\" ? self : typeof window !== \"undefined\" ? window : {})\n},{}],82:[function(require,module,exports){\narguments[4][51][0].apply(exports,arguments)\n},{\"dup\":51}],83:[function(require,module,exports){\nmodule.exports = function isBuffer(arg) {\n  return arg && typeof arg === 'object'\n    && typeof arg.copy === 'function'\n    && typeof arg.fill === 'function'\n    && typeof arg.readUInt8 === 'function';\n}\n},{}],84:[function(require,module,exports){\n(function (process,global){\n// Copyright Joyent, Inc. and other Node contributors.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a\n// copy of this software and associated documentation files (the\n// \"Software\"), to deal in the Software without restriction, including\n// without limitation the rights to use, copy, modify, merge, publish,\n// distribute, sublicense, and/or sell copies of the Software, and to permit\n// persons to whom the Software is furnished to do so, subject to the\n// following conditions:\n//\n// The above copyright notice and this permission notice shall be included\n// in all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS\n// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN\n// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,\n// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE\n// USE OR OTHER DEALINGS IN THE SOFTWARE.\n\nvar formatRegExp = /%[sdj%]/g;\nexports.format = function(f) {\n  if (!isString(f)) {\n    var objects = [];\n    for (var i = 0; i < arguments.length; i++) {\n      objects.push(inspect(arguments[i]));\n    }\n    return objects.join(' ');\n  }\n\n  var i = 1;\n  var args = arguments;\n  var len = args.length;\n  var str = String(f).replace(formatRegExp, function(x) {\n    if (x === '%%') return '%';\n    if (i >= len) return x;\n    switch (x) {\n      case '%s': return String(args[i++]);\n      case '%d': return Number(args[i++]);\n      case '%j':\n        try {\n          return JSON.stringify(args[i++]);\n        } catch (_) {\n          return '[Circular]';\n        }\n      default:\n        return x;\n    }\n  });\n  for (var x = args[i]; i < len; x = args[++i]) {\n    if (isNull(x) || !isObject(x)) {\n      str += ' ' + x;\n    } else {\n      str += ' ' + inspect(x);\n    }\n  }\n  return str;\n};\n\n\n// Mark that a method should not be used.\n// Returns a modified function which warns once by default.\n// If --no-deprecation is set, then it is a no-op.\nexports.deprecate = function(fn, msg) {\n  // Allow for deprecating things in the process of starting up.\n  if (isUndefined(global.process)) {\n    return function() {\n      return exports.deprecate(fn, msg).apply(this, arguments);\n    };\n  }\n\n  if (process.noDeprecation === true) {\n    return fn;\n  }\n\n  var warned = false;\n  function deprecated() {\n    if (!warned) {\n      if (process.throwDeprecation) {\n        throw new Error(msg);\n      } else if (process.traceDeprecation) {\n        console.trace(msg);\n      } else {\n        console.error(msg);\n      }\n      warned = true;\n    }\n    return fn.apply(this, arguments);\n  }\n\n  return deprecated;\n};\n\n\nvar debugs = {};\nvar debugEnviron;\nexports.debuglog = function(set) {\n  if (isUndefined(debugEnviron))\n    debugEnviron = process.env.NODE_DEBUG || '';\n  set = set.toUpperCase();\n  if (!debugs[set]) {\n    if (new RegExp('\\\\b' + set + '\\\\b', 'i').test(debugEnviron)) {\n      var pid = process.pid;\n      debugs[set] = function() {\n        var msg = exports.format.apply(exports, arguments);\n        console.error('%s %d: %s', set, pid, msg);\n      };\n    } else {\n      debugs[set] = function() {};\n    }\n  }\n  return debugs[set];\n};\n\n\n/**\n * Echos the value of a value. Trys to print the value out\n * in the best way possible given the different types.\n *\n * @param {Object} obj The object to print out.\n * @param {Object} opts Optional options object that alters the output.\n */\n/* legacy: obj, showHidden, depth, colors*/\nfunction inspect(obj, opts) {\n  // default options\n  var ctx = {\n    seen: [],\n    stylize: stylizeNoColor\n  };\n  // legacy...\n  if (arguments.length >= 3) ctx.depth = arguments[2];\n  if (arguments.length >= 4) ctx.colors = arguments[3];\n  if (isBoolean(opts)) {\n    // legacy...\n    ctx.showHidden = opts;\n  } else if (opts) {\n    // got an \"options\" object\n    exports._extend(ctx, opts);\n  }\n  // set default options\n  if (isUndefined(ctx.showHidden)) ctx.showHidden = false;\n  if (isUndefined(ctx.depth)) ctx.depth = 2;\n  if (isUndefined(ctx.colors)) ctx.colors = false;\n  if (isUndefined(ctx.customInspect)) ctx.customInspect = true;\n  if (ctx.colors) ctx.stylize = stylizeWithColor;\n  return formatValue(ctx, obj, ctx.depth);\n}\nexports.inspect = inspect;\n\n\n// http://en.wikipedia.org/wiki/ANSI_escape_code#graphics\ninspect.colors = {\n  'bold' : [1, 22],\n  'italic' : [3, 23],\n  'underline' : [4, 24],\n  'inverse' : [7, 27],\n  'white' : [37, 39],\n  'grey' : [90, 39],\n  'black' : [30, 39],\n  'blue' : [34, 39],\n  'cyan' : [36, 39],\n  'green' : [32, 39],\n  'magenta' : [35, 39],\n  'red' : [31, 39],\n  'yellow' : [33, 39]\n};\n\n// Don't use 'blue' not visible on cmd.exe\ninspect.styles = {\n  'special': 'cyan',\n  'number': 'yellow',\n  'boolean': 'yellow',\n  'undefined': 'grey',\n  'null': 'bold',\n  'string': 'green',\n  'date': 'magenta',\n  // \"name\": intentionally not styling\n  'regexp': 'red'\n};\n\n\nfunction stylizeWithColor(str, styleType) {\n  var style = inspect.styles[styleType];\n\n  if (style) {\n    return '\\u001b[' + inspect.colors[style][0] + 'm' + str +\n           '\\u001b[' + inspect.colors[style][1] + 'm';\n  } else {\n    return str;\n  }\n}\n\n\nfunction stylizeNoColor(str, styleType) {\n  return str;\n}\n\n\nfunction arrayToHash(array) {\n  var hash = {};\n\n  array.forEach(function(val, idx) {\n    hash[val] = true;\n  });\n\n  return hash;\n}\n\n\nfunction formatValue(ctx, value, recurseTimes) {\n  // Provide a hook for user-specified inspect functions.\n  // Check that value is an object with an inspect function on it\n  if (ctx.customInspect &&\n      value &&\n      isFunction(value.inspect) &&\n      // Filter out the util module, it's inspect function is special\n      value.inspect !== exports.inspect &&\n      // Also filter out any prototype objects using the circular check.\n      !(value.constructor && value.constructor.prototype === value)) {\n    var ret = value.inspect(recurseTimes, ctx);\n    if (!isString(ret)) {\n      ret = formatValue(ctx, ret, recurseTimes);\n    }\n    return ret;\n  }\n\n  // Primitive types cannot have properties\n  var primitive = formatPrimitive(ctx, value);\n  if (primitive) {\n    return primitive;\n  }\n\n  // Look up the keys of the object.\n  var keys = Object.keys(value);\n  var visibleKeys = arrayToHash(keys);\n\n  if (ctx.showHidden) {\n    keys = Object.getOwnPropertyNames(value);\n  }\n\n  // IE doesn't make error fields non-enumerable\n  // http://msdn.microsoft.com/en-us/library/ie/dww52sbt(v=vs.94).aspx\n  if (isError(value)\n      && (keys.indexOf('message') >= 0 || keys.indexOf('description') >= 0)) {\n    return formatError(value);\n  }\n\n  // Some type of object without properties can be shortcutted.\n  if (keys.length === 0) {\n    if (isFunction(value)) {\n      var name = value.name ? ': ' + value.name : '';\n      return ctx.stylize('[Function' + name + ']', 'special');\n    }\n    if (isRegExp(value)) {\n      return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp');\n    }\n    if (isDate(value)) {\n      return ctx.stylize(Date.prototype.toString.call(value), 'date');\n    }\n    if (isError(value)) {\n      return formatError(value);\n    }\n  }\n\n  var base = '', array = false, braces = ['{', '}'];\n\n  // Make Array say that they are Array\n  if (isArray(value)) {\n    array = true;\n    braces = ['[', ']'];\n  }\n\n  // Make functions say that they are functions\n  if (isFunction(value)) {\n    var n = value.name ? ': ' + value.name : '';\n    base = ' [Function' + n + ']';\n  }\n\n  // Make RegExps say that they are RegExps\n  if (isRegExp(value)) {\n    base = ' ' + RegExp.prototype.toString.call(value);\n  }\n\n  // Make dates with properties first say the date\n  if (isDate(value)) {\n    base = ' ' + Date.prototype.toUTCString.call(value);\n  }\n\n  // Make error with message first say the error\n  if (isError(value)) {\n    base = ' ' + formatError(value);\n  }\n\n  if (keys.length === 0 && (!array || value.length == 0)) {\n    return braces[0] + base + braces[1];\n  }\n\n  if (recurseTimes < 0) {\n    if (isRegExp(value)) {\n      return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp');\n    } else {\n      return ctx.stylize('[Object]', 'special');\n    }\n  }\n\n  ctx.seen.push(value);\n\n  var output;\n  if (array) {\n    output = formatArray(ctx, value, recurseTimes, visibleKeys, keys);\n  } else {\n    output = keys.map(function(key) {\n      return formatProperty(ctx, value, recurseTimes, visibleKeys, key, array);\n    });\n  }\n\n  ctx.seen.pop();\n\n  return reduceToSingleString(output, base, braces);\n}\n\n\nfunction formatPrimitive(ctx, value) {\n  if (isUndefined(value))\n    return ctx.stylize('undefined', 'undefined');\n  if (isString(value)) {\n    var simple = '\\'' + JSON.stringify(value).replace(/^\"|\"$/g, '')\n                                             .replace(/'/g, \"\\\\'\")\n                                             .replace(/\\\\\"/g, '\"') + '\\'';\n    return ctx.stylize(simple, 'string');\n  }\n  if (isNumber(value))\n    return ctx.stylize('' + value, 'number');\n  if (isBoolean(value))\n    return ctx.stylize('' + value, 'boolean');\n  // For some reason typeof null is \"object\", so special case here.\n  if (isNull(value))\n    return ctx.stylize('null', 'null');\n}\n\n\nfunction formatError(value) {\n  return '[' + Error.prototype.toString.call(value) + ']';\n}\n\n\nfunction formatArray(ctx, value, recurseTimes, visibleKeys, keys) {\n  var output = [];\n  for (var i = 0, l = value.length; i < l; ++i) {\n    if (hasOwnProperty(value, String(i))) {\n      output.push(formatProperty(ctx, value, recurseTimes, visibleKeys,\n          String(i), true));\n    } else {\n      output.push('');\n    }\n  }\n  keys.forEach(function(key) {\n    if (!key.match(/^\\d+$/)) {\n      output.push(formatProperty(ctx, value, recurseTimes, visibleKeys,\n          key, true));\n    }\n  });\n  return output;\n}\n\n\nfunction formatProperty(ctx, value, recurseTimes, visibleKeys, key, array) {\n  var name, str, desc;\n  desc = Object.getOwnPropertyDescriptor(value, key) || { value: value[key] };\n  if (desc.get) {\n    if (desc.set) {\n      str = ctx.stylize('[Getter/Setter]', 'special');\n    } else {\n      str = ctx.stylize('[Getter]', 'special');\n    }\n  } else {\n    if (desc.set) {\n      str = ctx.stylize('[Setter]', 'special');\n    }\n  }\n  if (!hasOwnProperty(visibleKeys, key)) {\n    name = '[' + key + ']';\n  }\n  if (!str) {\n    if (ctx.seen.indexOf(desc.value) < 0) {\n      if (isNull(recurseTimes)) {\n        str = formatValue(ctx, desc.value, null);\n      } else {\n        str = formatValue(ctx, desc.value, recurseTimes - 1);\n      }\n      if (str.indexOf('\\n') > -1) {\n        if (array) {\n          str = str.split('\\n').map(function(line) {\n            return '  ' + line;\n          }).join('\\n').substr(2);\n        } else {\n          str = '\\n' + str.split('\\n').map(function(line) {\n            return '   ' + line;\n          }).join('\\n');\n        }\n      }\n    } else {\n      str = ctx.stylize('[Circular]', 'special');\n    }\n  }\n  if (isUndefined(name)) {\n    if (array && key.match(/^\\d+$/)) {\n      return str;\n    }\n    name = JSON.stringify('' + key);\n    if (name.match(/^\"([a-zA-Z_][a-zA-Z_0-9]*)\"$/)) {\n      name = name.substr(1, name.length - 2);\n      name = ctx.stylize(name, 'name');\n    } else {\n      name = name.replace(/'/g, \"\\\\'\")\n                 .replace(/\\\\\"/g, '\"')\n                 .replace(/(^\"|\"$)/g, \"'\");\n      name = ctx.stylize(name, 'string');\n    }\n  }\n\n  return name + ': ' + str;\n}\n\n\nfunction reduceToSingleString(output, base, braces) {\n  var numLinesEst = 0;\n  var length = output.reduce(function(prev, cur) {\n    numLinesEst++;\n    if (cur.indexOf('\\n') >= 0) numLinesEst++;\n    return prev + cur.replace(/\\u001b\\[\\d\\d?m/g, '').length + 1;\n  }, 0);\n\n  if (length > 60) {\n    return braces[0] +\n           (base === '' ? '' : base + '\\n ') +\n           ' ' +\n           output.join(',\\n  ') +\n           ' ' +\n           braces[1];\n  }\n\n  return braces[0] + base + ' ' + output.join(', ') + ' ' + braces[1];\n}\n\n\n// NOTE: These type checking functions intentionally don't use `instanceof`\n// because it is fragile and can be easily faked with `Object.create()`.\nfunction isArray(ar) {\n  return Array.isArray(ar);\n}\nexports.isArray = isArray;\n\nfunction isBoolean(arg) {\n  return typeof arg === 'boolean';\n}\nexports.isBoolean = isBoolean;\n\nfunction isNull(arg) {\n  return arg === null;\n}\nexports.isNull = isNull;\n\nfunction isNullOrUndefined(arg) {\n  return arg == null;\n}\nexports.isNullOrUndefined = isNullOrUndefined;\n\nfunction isNumber(arg) {\n  return typeof arg === 'number';\n}\nexports.isNumber = isNumber;\n\nfunction isString(arg) {\n  return typeof arg === 'string';\n}\nexports.isString = isString;\n\nfunction isSymbol(arg) {\n  return typeof arg === 'symbol';\n}\nexports.isSymbol = isSymbol;\n\nfunction isUndefined(arg) {\n  return arg === void 0;\n}\nexports.isUndefined = isUndefined;\n\nfunction isRegExp(re) {\n  return isObject(re) && objectToString(re) === '[object RegExp]';\n}\nexports.isRegExp = isRegExp;\n\nfunction isObject(arg) {\n  return typeof arg === 'object' && arg !== null;\n}\nexports.isObject = isObject;\n\nfunction isDate(d) {\n  return isObject(d) && objectToString(d) === '[object Date]';\n}\nexports.isDate = isDate;\n\nfunction isError(e) {\n  return isObject(e) &&\n      (objectToString(e) === '[object Error]' || e instanceof Error);\n}\nexports.isError = isError;\n\nfunction isFunction(arg) {\n  return typeof arg === 'function';\n}\nexports.isFunction = isFunction;\n\nfunction isPrimitive(arg) {\n  return arg === null ||\n         typeof arg === 'boolean' ||\n         typeof arg === 'number' ||\n         typeof arg === 'string' ||\n         typeof arg === 'symbol' ||  // ES6 symbol\n         typeof arg === 'undefined';\n}\nexports.isPrimitive = isPrimitive;\n\nexports.isBuffer = require('./support/isBuffer');\n\nfunction objectToString(o) {\n  return Object.prototype.toString.call(o);\n}\n\n\nfunction pad(n) {\n  return n < 10 ? '0' + n.toString(10) : n.toString(10);\n}\n\n\nvar months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep',\n              'Oct', 'Nov', 'Dec'];\n\n// 26 Feb 16:19:34\nfunction timestamp() {\n  var d = new Date();\n  var time = [pad(d.getHours()),\n              pad(d.getMinutes()),\n              pad(d.getSeconds())].join(':');\n  return [d.getDate(), months[d.getMonth()], time].join(' ');\n}\n\n\n// log is just a thin wrapper to console.log that prepends a timestamp\nexports.log = function() {\n  console.log('%s - %s', timestamp(), exports.format.apply(exports, arguments));\n};\n\n\n/**\n * Inherit the prototype methods from one constructor into another.\n *\n * The Function.prototype.inherits from lang.js rewritten as a standalone\n * function (not on Function.prototype). NOTE: If this file is to be loaded\n * during bootstrapping this function needs to be rewritten using some native\n * functions as prototype setup using normal JavaScript does not work as\n * expected during bootstrapping (see mirror.js in r114903).\n *\n * @param {function} ctor Constructor function which needs to inherit the\n *     prototype.\n * @param {function} superCtor Constructor function to inherit prototype from.\n */\nexports.inherits = require('inherits');\n\nexports._extend = function(origin, add) {\n  // Don't do anything if add isn't an object\n  if (!add || !isObject(add)) return origin;\n\n  var keys = Object.keys(add);\n  var i = keys.length;\n  while (i--) {\n    origin[keys[i]] = add[keys[i]];\n  }\n  return origin;\n};\n\nfunction hasOwnProperty(obj, prop) {\n  return Object.prototype.hasOwnProperty.call(obj, prop);\n}\n\n}).call(this,require('_process'),typeof global !== \"undefined\" ? global : typeof self !== \"undefined\" ? self : typeof window !== \"undefined\" ? window : {})\n},{\"./support/isBuffer\":83,\"_process\":67,\"inherits\":82}]},{},[1]);\n"
  },
  {
    "path": "app_backend/static/plugin/JavaScript-Load-Image-2.12.2/.gitignore",
    "content": ".DS_Store\nnode_modules\n"
  },
  {
    "path": "app_backend/static/plugin/JavaScript-Load-Image-2.12.2/.npmignore",
    "content": "*\n!js/*.js\n!js/*.js.map\n"
  },
  {
    "path": "app_backend/static/plugin/JavaScript-Load-Image-2.12.2/.travis.yml",
    "content": "language: node_js\nnode_js:\n  - \"stable\"\n"
  },
  {
    "path": "app_backend/static/plugin/JavaScript-Load-Image-2.12.2/README.md",
    "content": "# JavaScript Load Image\n\n> A JavaScript library to load and transform image files.\n\n## Table of contents\n\n- [Demo](#demo)\n- [Description](#description)\n- [Setup](#setup)\n- [Usage](#usage)\n- [Image loading](#image-loading)\n- [Image scaling](#image-scaling)\n- [Requirements](#requirements)\n- [API](#api)\n- [Options](#options)\n- [Meta data parsing](#meta-data-parsing)\n- [Exif parser](#exif-parser)\n- [License](#license)\n- [Credits](#credits)\n\n## Demo\n[JavaScript Load Image Demo](https://blueimp.github.io/JavaScript-Load-Image/)\n\n## Description\nJavaScript Load Image is a library to load images provided as File or Blob\nobjects or via URL.  \nIt returns an optionally scaled and/or cropped HTML img or canvas element via an\nasynchronous callback.  \nIt also provides a method to parse image meta data to extract Exif tags and\nthumbnails and to restore the complete image header after resizing.\n\n## Setup\nInclude the (combined and minified) JavaScript Load Image script in your HTML\nmarkup:\n\n```html\n<script src=\"js/load-image.all.min.js\"></script>\n```\n\nOr alternatively, choose which components you want to include:\n\n```html\n<script src=\"js/load-image.js\"></script>\n<script src=\"js/load-image-scale.js\"></script>\n<script src=\"js/load-image-meta.js\"></script>\n<script src=\"js/load-image-fetch.js\"></script>\n<script src=\"js/load-image-exif.js\"></script>\n<script src=\"js/load-image-exif-map.js\"></script>\n<script src=\"js/load-image-orientation.js\"></script>\n```\n\n## Usage\n\n### Image loading\nIn your application code, use the **loadImage()** function like this:\n\n```js\ndocument.getElementById('file-input').onchange = function (e) {\n    loadImage(\n        e.target.files[0],\n        function (img) {\n            document.body.appendChild(img);\n        },\n        {maxWidth: 600} // Options\n    );\n};\n```\n\n### Image scaling\nIt is also possible to use the image scaling functionality with an existing\nimage:\n\n```js\nvar scaledImage = loadImage.scale(\n    img, // img or canvas element\n    {maxWidth: 600}\n);\n```\n\n## Requirements\nThe JavaScript Load Image library has zero dependencies.\n\nHowever, JavaScript Load Image is a very suitable complement to the\n[Canvas to Blob](https://github.com/blueimp/JavaScript-Canvas-to-Blob) library.\n\n## API\nThe **loadImage()** function accepts a\n[File](https://developer.mozilla.org/en/DOM/File) or\n[Blob](https://developer.mozilla.org/en/DOM/Blob) object or a simple image URL\n(e.g. `'https://example.org/image.png'`) as first argument.\n\nIf a [File](https://developer.mozilla.org/en/DOM/File) or\n[Blob](https://developer.mozilla.org/en/DOM/Blob) is passed as parameter, it\nreturns a HTML **img** element if the browser supports the\n[URL](https://developer.mozilla.org/en/DOM/window.URL) API or a\n[FileReader](https://developer.mozilla.org/en/DOM/FileReader) object if\nsupported, or **false**.  \nIt always returns a HTML\n[img](https://developer.mozilla.org/en/docs/HTML/Element/Img) element when\npassing an image URL:\n\n```js\ndocument.getElementById('file-input').onchange = function (e) {\n    var loadingImage = loadImage(\n        e.target.files[0],\n        function (img) {\n            document.body.appendChild(img);\n        },\n        {maxWidth: 600}\n    );\n    if (!loadingImage) {\n        // Alternative code ...\n    }\n};\n```\n\nThe **img** element or\n[FileReader](https://developer.mozilla.org/en/DOM/FileReader) object returned by\nthe **loadImage()** function allows to abort the loading process by setting the\n**onload** and **onerror** event handlers to null:\n\n```js\ndocument.getElementById('file-input').onchange = function (e) {\n    var loadingImage = loadImage(\n        e.target.files[0],\n        function (img) {\n            document.body.appendChild(img);\n        },\n        {maxWidth: 600}\n    );\n    loadingImage.onload = loadingImage.onerror = null;\n};\n```\n\nThe second argument must be a **callback** function, which is called when the\nimage has been loaded or an error occurred while loading the image. The callback\nfunction is passed one argument, which is either a HTML **img** element, a\n[canvas](https://developer.mozilla.org/en/HTML/Canvas) element, or an\n[Event](https://developer.mozilla.org/en/DOM/event) object of type **error**:\n\n```js\nvar imageUrl = \"https://example.org/image.png\";\nloadImage(\n    imageUrl,\n    function (img) {\n        if(img.type === \"error\") {\n            console.log(\"Error loading image \" + imageUrl);\n        } else {\n            document.body.appendChild(img);\n        }\n    },\n    {maxWidth: 600}\n);\n```\n\n## Options\nThe optional third argument to **loadImage()** is a map of options:\n\n* **maxWidth**: Defines the maximum width of the img/canvas element.\n* **maxHeight**: Defines the maximum height of the img/canvas element.\n* **minWidth**: Defines the minimum width of the img/canvas element.\n* **minHeight**: Defines the minimum height of the img/canvas element.\n* **sourceWidth**: The width of the sub-rectangle of the source image to draw\ninto the destination canvas.  \nDefaults to the source image width and requires `canvas: true`.\n* **sourceHeight**: The height of the sub-rectangle of the source image to draw\ninto the destination canvas.  \nDefaults to the source image height and requires `canvas: true`.\n* **top**: The top margin of the sub-rectangle of the source image.  \nDefaults to `0` and requires `canvas: true`.\n* **right**: The right margin of the sub-rectangle of the source image.  \nDefaults to `0` and requires `canvas: true`.\n* **bottom**: The bottom margin of the sub-rectangle of the source image.  \nDefaults to `0` and requires `canvas: true`.\n* **left**: The left margin of the sub-rectangle of the source image.  \nDefaults to `0` and requires `canvas: true`.\n* **contain**: Scales the image up/down to contain it in the max dimensions if\nset to `true`.  \nThis emulates the CSS feature\n[background-image: contain](https://developer.mozilla.org/en-US/docs/Web/Guide/CSS/Scaling_background_images#contain).\n* **cover**: Scales the image up/down to cover the max dimensions with the image\ndimensions if set to `true`.  \nThis emulates the CSS feature\n[background-image: cover](https://developer.mozilla.org/en-US/docs/Web/Guide/CSS/Scaling_background_images#cover).\n* **aspectRatio**: Crops the image to the given aspect ratio (e.g. `16/9`).  \nSetting the `aspectRatio` also enables the `crop` option.\n* **pixelRatio**: Defines the ratio of the canvas pixels to the physical image\npixels on the screen.  \nShould be set to `window.devicePixelRatio` unless the scaled image is not\nrendered on screen.  \nDefaults to `1` and requires `canvas: true`.\n* **downsamplingRatio**: Defines the ratio in which the image is downsampled.  \nBy default, images are downsampled in one step. With a ratio of `0.5`, each step\nscales the image to half the size, before reaching the target dimensions.  \nRequires `canvas: true`.\n* **crop**: Crops the image to the maxWidth/maxHeight constraints if set to\n`true`.  \nEnabling the `crop` option also enables the `canvas` option.\n* **orientation**: Transform the canvas according to the specified Exif\norientation, which can be an `integer` in the range of `1` to `8` or the boolean\nvalue `true`.  \nWhen set to `true`, it will set the orientation value based on the EXIF data of\nthe image, which will be parsed automatically if the exif library is available.  \nSetting the `orientation` also enables the `canvas` option.  \nSetting `orientation` to `true` also enables the `meta` option.\n* **meta**: Automatically parses the image meta data if set to `true`.  \nThe meta data is passed to the callback as second argument.  \nIf the file is given as URL and the browser supports the\n[fetch API](https://developer.mozilla.org/en/docs/Web/API/Fetch_API), fetches\nthe file as Blob to be able to parse the meta data.\n* **canvas**: Returns the image as\n[canvas](https://developer.mozilla.org/en/HTML/Canvas) element if set to `true`.\n* **crossOrigin**: Sets the crossOrigin property on the img element for loading\n[CORS enabled images](https://developer.mozilla.org/en-US/docs/HTML/CORS_Enabled_Image).\n* **noRevoke**: By default, the\n[created object URL](https://developer.mozilla.org/en/DOM/window.URL.createObjectURL)\nis revoked after the image has been loaded, except when this option is set to\n`true`.\n\nThey can be used the following way:\n\n```js\nloadImage(\n    fileOrBlobOrUrl,\n    function (img) {\n        document.body.appendChild(img);\n    },\n    {\n        maxWidth: 600,\n        maxHeight: 300,\n        minWidth: 100,\n        minHeight: 50,\n        canvas: true\n    }\n);\n```\n\nAll settings are optional. By default, the image is returned as HTML **img**\nelement without any image size restrictions.\n\n## Meta data parsing\nIf the Load Image Meta extension is included, it is also possible to parse image\nmeta data.  \nThe extension provides the method **loadImage.parseMetaData**, which can be used\nthe following way:\n\n```js\nloadImage.parseMetaData(\n    fileOrBlob,\n    function (data) {\n        if (!data.imageHead) {\n            return;\n        }\n        // Combine data.imageHead with the image body of a resized file\n        // to create scaled images with the original image meta data, e.g.:\n        var blob = new Blob([\n            data.imageHead,\n            // Resized images always have a head size of 20 bytes,\n            // including the JPEG marker and a minimal JFIF header:\n            loadImage.blobSlice.call(resizedImage, 20)\n        ], {type: resizedImage.type});\n    },\n    {\n        maxMetaDataSize: 262144,\n        disableImageHead: false\n    }\n);\n```\n\nThe third argument is an options object which defines the maximum number of\nbytes to parse for the image meta data, allows to disable the imageHead creation\nand is also passed along to segment parsers registered via loadImage extensions,\ne.g. the Exif parser.\n\n**Note:**  \nBlob objects of resized images can be created via\n[canvas.toBlob()](https://github.com/blueimp/JavaScript-Canvas-to-Blob).\n\n### Exif parser\nIf you include the Load Image Exif Parser extension, the argument passed to the\ncallback for **parseMetaData** will contain the additional property **exif** if\nExif data could be found in the given image.  \nThe **exif** object stores the parsed Exif tags:\n\n```js\nvar orientation = data.exif[0x0112];\n```\n\nIt also provides an **exif.get()** method to retrieve the tag value via the\ntag's mapped name:\n\n```js\nvar orientation = data.exif.get('Orientation');\n```\n\nBy default, the only available mapped names are **Orientation** and\n**Thumbnail**.  \nIf you also include the Load Image Exif Map library, additional tag mappings\nbecome available, as well as two additional methods, **exif.getText()** and\n**exif.getAll()**:\n\n```js\nvar flashText = data.exif.getText('Flash'); // e.g.: 'Flash fired, auto mode',\n\n// A map of all parsed tags with their mapped names as keys and their text values:\nvar allTags = data.exif.getAll();\n```\n\nThe Exif parser also adds additional options for the parseMetaData method, to\ndisable certain aspects of the parser:\n\n* **disableExif**: Disables Exif parsing.\n* **disableExifThumbnail**: Disables parsing of the Exif Thumbnail.\n* **disableExifSub**: Disables parsing of the Exif Sub IFD.\n* **disableExifGps**: Disables parsing of the Exif GPS Info IFD.\n\n## License\nThe JavaScript Load Image script is released under the\n[MIT license](https://opensource.org/licenses/MIT).\n\n## Credits\n\n* Image meta data handling implementation based on the help and contribution of\nAchim Stöhr.\n* Exif tags mapping based on Jacob Seidelin's\n[exif-js](https://github.com/jseidelin/exif-js).\n"
  },
  {
    "path": "app_backend/static/plugin/JavaScript-Load-Image-2.12.2/css/demo.css",
    "content": "/*\n * JavaScript Load Image Demo CSS\n * https://github.com/blueimp/JavaScript-Load-Image\n *\n * Copyright 2013, Sebastian Tschan\n * https://blueimp.net\n *\n * Licensed under the MIT license:\n * https://opensource.org/licenses/MIT\n */\n\nbody {\n  max-width: 750px;\n  margin: 0 auto;\n  padding: 1em;\n  font-family: 'Lucida Grande', 'Lucida Sans Unicode', Arial, sans-serif;\n  font-size: 1em;\n  line-height: 1.4em;\n  background: #222;\n  color: #fff;\n  -webkit-text-size-adjust: 100%;\n      -ms-text-size-adjust: 100%;\n}\na {\n  color: orange;\n  text-decoration: none;\n}\nimg {\n  border: 0;\n  vertical-align: middle;\n}\nh1 {\n  line-height: 1em;\n}\ntable {\n  width: 100%;\n  word-wrap: break-word;\n  table-layout: fixed;\n  border-collapse: collapse;\n}\ntr {\n  background: #fff;\n  color: #222;\n}\ntr:nth-child(odd) {\n  background: #eee;\n  color: #222;\n}\ntd {\n  padding: 10px;\n}\n.result,\n.thumbnail {\n  padding: 20px;\n  background: #fff;\n  color: #222;\n  text-align: center;\n}\n.jcrop-holder {\n  margin: 0 auto;\n}\n\n@media (min-width: 481px) {\n  .navigation {\n    list-style: none;\n    padding: 0;\n  }\n  .navigation li {\n    display: inline-block;\n  }\n  .navigation li:not(:first-child):before {\n    content: '| ';\n  }\n}\n"
  },
  {
    "path": "app_backend/static/plugin/JavaScript-Load-Image-2.12.2/css/vendor/jquery.Jcrop.css",
    "content": "/* jquery.Jcrop.css v0.9.12 - MIT License */\n/*\n  The outer-most container in a typical Jcrop instance\n  If you are having difficulty with formatting related to styles\n  on a parent element, place any fixes here or in a like selector\n\n  You can also style this element if you want to add a border, etc\n  A better method for styling can be seen below with .jcrop-light\n  (Add a class to the holder and style elements for that extended class)\n*/\n.jcrop-holder {\n  direction: ltr;\n  text-align: left;\n}\n/* Selection Border */\n.jcrop-vline,\n.jcrop-hline {\n  background: #ffffff url(\"Jcrop.gif\");\n  font-size: 0;\n  position: absolute;\n}\n.jcrop-vline {\n  height: 100%;\n  width: 1px !important;\n}\n.jcrop-vline.right {\n  right: 0;\n}\n.jcrop-hline {\n  height: 1px !important;\n  width: 100%;\n}\n.jcrop-hline.bottom {\n  bottom: 0;\n}\n/* Invisible click targets */\n.jcrop-tracker {\n  height: 100%;\n  width: 100%;\n  /* \"turn off\" link highlight */\n  -webkit-tap-highlight-color: transparent;\n  /* disable callout, image save panel */\n  -webkit-touch-callout: none;\n  /* disable cut copy paste */\n  -webkit-user-select: none;\n}\n/* Selection Handles */\n.jcrop-handle {\n  background-color: #333333;\n  border: 1px #eeeeee solid;\n  width: 7px;\n  height: 7px;\n  font-size: 1px;\n}\n.jcrop-handle.ord-n {\n  left: 50%;\n  margin-left: -4px;\n  margin-top: -4px;\n  top: 0;\n}\n.jcrop-handle.ord-s {\n  bottom: 0;\n  left: 50%;\n  margin-bottom: -4px;\n  margin-left: -4px;\n}\n.jcrop-handle.ord-e {\n  margin-right: -4px;\n  margin-top: -4px;\n  right: 0;\n  top: 50%;\n}\n.jcrop-handle.ord-w {\n  left: 0;\n  margin-left: -4px;\n  margin-top: -4px;\n  top: 50%;\n}\n.jcrop-handle.ord-nw {\n  left: 0;\n  margin-left: -4px;\n  margin-top: -4px;\n  top: 0;\n}\n.jcrop-handle.ord-ne {\n  margin-right: -4px;\n  margin-top: -4px;\n  right: 0;\n  top: 0;\n}\n.jcrop-handle.ord-se {\n  bottom: 0;\n  margin-bottom: -4px;\n  margin-right: -4px;\n  right: 0;\n}\n.jcrop-handle.ord-sw {\n  bottom: 0;\n  left: 0;\n  margin-bottom: -4px;\n  margin-left: -4px;\n}\n/* Dragbars */\n.jcrop-dragbar.ord-n,\n.jcrop-dragbar.ord-s {\n  height: 7px;\n  width: 100%;\n}\n.jcrop-dragbar.ord-e,\n.jcrop-dragbar.ord-w {\n  height: 100%;\n  width: 7px;\n}\n.jcrop-dragbar.ord-n {\n  margin-top: -4px;\n}\n.jcrop-dragbar.ord-s {\n  bottom: 0;\n  margin-bottom: -4px;\n}\n.jcrop-dragbar.ord-e {\n  margin-right: -4px;\n  right: 0;\n}\n.jcrop-dragbar.ord-w {\n  margin-left: -4px;\n}\n/* The \"jcrop-light\" class/extension */\n.jcrop-light .jcrop-vline,\n.jcrop-light .jcrop-hline {\n  background: #ffffff;\n  filter: alpha(opacity=70) !important;\n  opacity: .70!important;\n}\n.jcrop-light .jcrop-handle {\n  -moz-border-radius: 3px;\n  -webkit-border-radius: 3px;\n  background-color: #000000;\n  border-color: #ffffff;\n  border-radius: 3px;\n}\n/* The \"jcrop-dark\" class/extension */\n.jcrop-dark .jcrop-vline,\n.jcrop-dark .jcrop-hline {\n  background: #000000;\n  filter: alpha(opacity=70) !important;\n  opacity: 0.7 !important;\n}\n.jcrop-dark .jcrop-handle {\n  -moz-border-radius: 3px;\n  -webkit-border-radius: 3px;\n  background-color: #ffffff;\n  border-color: #000000;\n  border-radius: 3px;\n}\n/* Simple macro to turn off the antlines */\n.solid-line .jcrop-vline,\n.solid-line .jcrop-hline {\n  background: #ffffff;\n}\n/* Fix for twitter bootstrap et al. */\n.jcrop-holder img,\nimg.jcrop-preview {\n  max-width: none;\n}\n"
  },
  {
    "path": "app_backend/static/plugin/JavaScript-Load-Image-2.12.2/index.html",
    "content": "<!DOCTYPE HTML>\n<!--\n/*\n * JavaScript Load Image Demo\n * https://github.com/blueimp/JavaScript-Load-Image\n *\n * Copyright 2011, Sebastian Tschan\n * https://blueimp.net\n *\n * Licensed under the MIT license:\n * https://opensource.org/licenses/MIT\n */\n-->\n<html lang=\"en\">\n<head>\n<!--[if IE]>\n<meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge,chrome=1\">\n<![endif]-->\n<meta charset=\"utf-8\">\n<title>JavaScript Load Image</title>\n<meta name=\"description\" content=\"JavaScript Load Image is a library to load images provided as File or Blob objects or via URL. It returns an optionally scaled and/or cropped HTML img or canvas element. It also provides a method to parse image meta data to extract Exif tags and thumbnails and to restore the complete image header after resizing.\">\n<meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n<!-- Jcrop is not required by JavaScript Load Image, but included for the demo -->\n<link rel=\"stylesheet\" href=\"css/vendor/jquery.Jcrop.css\">\n<link rel=\"stylesheet\" href=\"css/demo.css\">\n</head>\n<body>\n<h1>JavaScript Load Image Demo</h1>\n<p><a href=\"https://github.com/blueimp/JavaScript-Load-Image\">JavaScript Load Image</a> is a library to load images provided as <a href=\"https://developer.mozilla.org/en/DOM/File\">File</a> or <a href=\"https://developer.mozilla.org/en/DOM/Blob\">Blob</a> objects or via URL.<br>\nIt returns an optionally <strong>scaled</strong> and/or <strong>cropped</strong> HTML <a href=\"https://developer.mozilla.org/en/docs/HTML/Element/Img\">img</a> or <a href=\"https://developer.mozilla.org/en/docs/HTML/Canvas\">canvas</a> element.<br>\nIt also provides a method to parse image meta data to extract <a href=\"https://en.wikipedia.org/wiki/Exif\">Exif</a> tags and thumbnails and to restore the complete image header after resizing.</p>\n<ul class=\"navigation\">\n    <li><a href=\"https://github.com/blueimp/JavaScript-Load-Image/tags\">Download</a></li>\n    <li><a href=\"https://github.com/blueimp/JavaScript-Load-Image\">Source Code</a></li>\n    <li><a href=\"https://github.com/blueimp/JavaScript-Load-Image/blob/master/README.md\">Documentation</a></li>\n    <li><a href=\"test/\">Test</a></li>\n    <li><a href=\"https://blueimp.net\">&copy; Sebastian Tschan</a></li>\n</ul>\n<br>\n<h2>Select an image file</h2>\n<p><input type=\"file\" id=\"file-input\"></p>\n<p>Or <strong>drag &amp; drop</strong> an image file onto this webpage.</p>\n<br>\n<h2>Result</h2>\n<p id=\"actions\" style=\"display:none;\">\n\t<button type=\"button\" id=\"edit\">Edit</button>\n\t<button type=\"button\" id=\"crop\">Crop</button>\n</p>\n<div id=\"result\" class=\"result\">\n    <p>This demo works only in browsers with support for the <a href=\"https://developer.mozilla.org/en/DOM/window.URL\">URL</a> or <a href=\"https://developer.mozilla.org/en/DOM/FileReader\">FileReader</a> API.</p>\n</div>\n<br>\n<div id=\"exif\" class=\"exif\" style=\"display:none;\">\n    <h2>Exif meta data</h2>\n    <p id=\"thumbnail\" class=\"thumbnail\" style=\"display:none;\"></p>\n    <table></table>\n</div>\n<br>\n<script src=\"js/load-image.js\"></script>\n<script src=\"js/load-image-scale.js\"></script>\n<script src=\"js/load-image-meta.js\"></script>\n<script src=\"js/load-image-fetch.js\"></script>\n<script src=\"js/load-image-exif.js\"></script>\n<script src=\"js/load-image-exif-map.js\"></script>\n<script src=\"js/load-image-orientation.js\"></script>\n<!-- jQuery and Jcrop are not required by JavaScript Load Image, but included for the demo -->\n<script src=\"js/vendor/jquery.js\"></script>\n<script src=\"js/vendor/jquery.Jcrop.js\"></script>\n<script src=\"js/demo/demo.js\"></script>\n</body>\n</html>\n"
  },
  {
    "path": "app_backend/static/plugin/JavaScript-Load-Image-2.12.2/js/demo/demo.js",
    "content": "/*\n * JavaScript Load Image Demo JS\n * https://github.com/blueimp/JavaScript-Load-Image\n *\n * Copyright 2013, Sebastian Tschan\n * https://blueimp.net\n *\n * Licensed under the MIT license:\n * https://opensource.org/licenses/MIT\n */\n\n/* global loadImage, HTMLCanvasElement, $ */\n\n$(function () {\n  'use strict'\n\n  var result = $('#result')\n  var exifNode = $('#exif')\n  var thumbNode = $('#thumbnail')\n  var actionsNode = $('#actions')\n  var currentFile\n  var coordinates\n\n  function displayExifData (exif) {\n    var thumbnail = exif.get('Thumbnail')\n    var tags = exif.getAll()\n    var table = exifNode.find('table').empty()\n    var row = $('<tr></tr>')\n    var cell = $('<td></td>')\n    var prop\n    if (thumbnail) {\n      thumbNode.empty()\n      loadImage(thumbnail, function (img) {\n        thumbNode.append(img).show()\n      }, {orientation: exif.get('Orientation')})\n    }\n    for (prop in tags) {\n      if (tags.hasOwnProperty(prop)) {\n        table.append(\n          row.clone()\n            .append(cell.clone().text(prop))\n            .append(cell.clone().text(tags[prop]))\n        )\n      }\n    }\n    exifNode.show()\n  }\n\n  function updateResults (img, data) {\n    var content\n    if (!(img.src || img instanceof HTMLCanvasElement)) {\n      content = $('<span>Loading image file failed</span>')\n    } else {\n      content = $('<a target=\"_blank\">').append(img)\n        .attr('download', currentFile.name)\n        .attr('href', img.src || img.toDataURL())\n    }\n    result.children().replaceWith(content)\n    if (img.getContext) {\n      actionsNode.show()\n    }\n    if (data && data.exif) {\n      displayExifData(data.exif)\n    }\n  }\n\n  function displayImage (file, options) {\n    currentFile = file\n    if (!loadImage(\n        file,\n        updateResults,\n        options\n      )) {\n      result.children().replaceWith(\n        $('<span>' +\n          'Your browser does not support the URL or FileReader API.' +\n          '</span>')\n      )\n    }\n  }\n\n  function dropChangeHandler (e) {\n    e.preventDefault()\n    e = e.originalEvent\n    var target = e.dataTransfer || e.target\n    var file = target && target.files && target.files[0]\n    var options = {\n      maxWidth: result.width(),\n      canvas: true,\n      pixelRatio: window.devicePixelRatio,\n      downsamplingRatio: 0.5,\n      orientation: true\n    }\n    if (!file) {\n      return\n    }\n    exifNode.hide()\n    thumbNode.hide()\n    displayImage(file, options)\n  }\n\n  // Hide URL/FileReader API requirement message in capable browsers:\n  if (window.createObjectURL || window.URL || window.webkitURL ||\n      window.FileReader) {\n    result.children().hide()\n  }\n\n  $(document)\n    .on('dragover', function (e) {\n      e.preventDefault()\n      e = e.originalEvent\n      e.dataTransfer.dropEffect = 'copy'\n    })\n    .on('drop', dropChangeHandler)\n\n  $('#file-input')\n    .on('change', dropChangeHandler)\n\n  $('#edit')\n    .on('click', function (event) {\n      event.preventDefault()\n      var imgNode = result.find('img, canvas')\n      var img = imgNode[0]\n      var pixelRatio = window.devicePixelRatio || 1\n      imgNode.Jcrop({\n        setSelect: [\n          40,\n          40,\n          (img.width / pixelRatio) - 40,\n          (img.height / pixelRatio) - 40\n        ],\n        onSelect: function (coords) {\n          coordinates = coords\n        },\n        onRelease: function () {\n          coordinates = null\n        }\n      }).parent().on('click', function (event) {\n        event.preventDefault()\n      })\n    })\n\n  $('#crop')\n    .on('click', function (event) {\n      event.preventDefault()\n      var img = result.find('img, canvas')[0]\n      var pixelRatio = window.devicePixelRatio || 1\n      if (img && coordinates) {\n        updateResults(loadImage.scale(img, {\n          left: coordinates.x * pixelRatio,\n          top: coordinates.y * pixelRatio,\n          sourceWidth: coordinates.w * pixelRatio,\n          sourceHeight: coordinates.h * pixelRatio,\n          minWidth: result.width(),\n          maxWidth: result.width(),\n          pixelRatio: pixelRatio,\n          downsamplingRatio: 0.5\n        }))\n        coordinates = null\n      }\n    })\n})\n"
  },
  {
    "path": "app_backend/static/plugin/JavaScript-Load-Image-2.12.2/js/index.js",
    "content": "module.exports = require('./load-image')\n\nrequire('./load-image-scale')\nrequire('./load-image-meta')\nrequire('./load-image-fetch')\nrequire('./load-image-exif')\nrequire('./load-image-exif-map')\nrequire('./load-image-orientation')\n"
  },
  {
    "path": "app_backend/static/plugin/JavaScript-Load-Image-2.12.2/js/load-image-exif-map.js",
    "content": "/*\n * JavaScript Load Image Exif Map\n * https://github.com/blueimp/JavaScript-Load-Image\n *\n * Copyright 2013, Sebastian Tschan\n * https://blueimp.net\n *\n * Exif tags mapping based on\n * https://github.com/jseidelin/exif-js\n *\n * Licensed under the MIT license:\n * https://opensource.org/licenses/MIT\n */\n\n/* global define */\n\n;(function (factory) {\n  'use strict'\n  if (typeof define === 'function' && define.amd) {\n    // Register as an anonymous AMD module:\n    define(['./load-image', './load-image-exif'], factory)\n  } else if (typeof module === 'object' && module.exports) {\n    factory(require('./load-image'), require('./load-image-exif'))\n  } else {\n    // Browser globals:\n    factory(window.loadImage)\n  }\n}(function (loadImage) {\n  'use strict'\n\n  loadImage.ExifMap.prototype.tags = {\n    // =================\n    // TIFF tags (IFD0):\n    // =================\n    0x0100: 'ImageWidth',\n    0x0101: 'ImageHeight',\n    0x8769: 'ExifIFDPointer',\n    0x8825: 'GPSInfoIFDPointer',\n    0xA005: 'InteroperabilityIFDPointer',\n    0x0102: 'BitsPerSample',\n    0x0103: 'Compression',\n    0x0106: 'PhotometricInterpretation',\n    0x0112: 'Orientation',\n    0x0115: 'SamplesPerPixel',\n    0x011C: 'PlanarConfiguration',\n    0x0212: 'YCbCrSubSampling',\n    0x0213: 'YCbCrPositioning',\n    0x011A: 'XResolution',\n    0x011B: 'YResolution',\n    0x0128: 'ResolutionUnit',\n    0x0111: 'StripOffsets',\n    0x0116: 'RowsPerStrip',\n    0x0117: 'StripByteCounts',\n    0x0201: 'JPEGInterchangeFormat',\n    0x0202: 'JPEGInterchangeFormatLength',\n    0x012D: 'TransferFunction',\n    0x013E: 'WhitePoint',\n    0x013F: 'PrimaryChromaticities',\n    0x0211: 'YCbCrCoefficients',\n    0x0214: 'ReferenceBlackWhite',\n    0x0132: 'DateTime',\n    0x010E: 'ImageDescription',\n    0x010F: 'Make',\n    0x0110: 'Model',\n    0x0131: 'Software',\n    0x013B: 'Artist',\n    0x8298: 'Copyright',\n    // ==================\n    // Exif Sub IFD tags:\n    // ==================\n    0x9000: 'ExifVersion', // EXIF version\n    0xA000: 'FlashpixVersion', // Flashpix format version\n    0xA001: 'ColorSpace', // Color space information tag\n    0xA002: 'PixelXDimension', // Valid width of meaningful image\n    0xA003: 'PixelYDimension', // Valid height of meaningful image\n    0xA500: 'Gamma',\n    0x9101: 'ComponentsConfiguration', // Information about channels\n    0x9102: 'CompressedBitsPerPixel', // Compressed bits per pixel\n    0x927C: 'MakerNote', // Any desired information written by the manufacturer\n    0x9286: 'UserComment', // Comments by user\n    0xA004: 'RelatedSoundFile', // Name of related sound file\n    0x9003: 'DateTimeOriginal', // Date and time when the original image was generated\n    0x9004: 'DateTimeDigitized', // Date and time when the image was stored digitally\n    0x9290: 'SubSecTime', // Fractions of seconds for DateTime\n    0x9291: 'SubSecTimeOriginal', // Fractions of seconds for DateTimeOriginal\n    0x9292: 'SubSecTimeDigitized', // Fractions of seconds for DateTimeDigitized\n    0x829A: 'ExposureTime', // Exposure time (in seconds)\n    0x829D: 'FNumber',\n    0x8822: 'ExposureProgram', // Exposure program\n    0x8824: 'SpectralSensitivity', // Spectral sensitivity\n    0x8827: 'PhotographicSensitivity', // EXIF 2.3, ISOSpeedRatings in EXIF 2.2\n    0x8828: 'OECF', // Optoelectric conversion factor\n    0x8830: 'SensitivityType',\n    0x8831: 'StandardOutputSensitivity',\n    0x8832: 'RecommendedExposureIndex',\n    0x8833: 'ISOSpeed',\n    0x8834: 'ISOSpeedLatitudeyyy',\n    0x8835: 'ISOSpeedLatitudezzz',\n    0x9201: 'ShutterSpeedValue', // Shutter speed\n    0x9202: 'ApertureValue', // Lens aperture\n    0x9203: 'BrightnessValue', // Value of brightness\n    0x9204: 'ExposureBias', // Exposure bias\n    0x9205: 'MaxApertureValue', // Smallest F number of lens\n    0x9206: 'SubjectDistance', // Distance to subject in meters\n    0x9207: 'MeteringMode', // Metering mode\n    0x9208: 'LightSource', // Kind of light source\n    0x9209: 'Flash', // Flash status\n    0x9214: 'SubjectArea', // Location and area of main subject\n    0x920A: 'FocalLength', // Focal length of the lens in mm\n    0xA20B: 'FlashEnergy', // Strobe energy in BCPS\n    0xA20C: 'SpatialFrequencyResponse',\n    0xA20E: 'FocalPlaneXResolution', // Number of pixels in width direction per FPRUnit\n    0xA20F: 'FocalPlaneYResolution', // Number of pixels in height direction per FPRUnit\n    0xA210: 'FocalPlaneResolutionUnit', // Unit for measuring the focal plane resolution\n    0xA214: 'SubjectLocation', // Location of subject in image\n    0xA215: 'ExposureIndex', // Exposure index selected on camera\n    0xA217: 'SensingMethod', // Image sensor type\n    0xA300: 'FileSource', // Image source (3 == DSC)\n    0xA301: 'SceneType', // Scene type (1 == directly photographed)\n    0xA302: 'CFAPattern', // Color filter array geometric pattern\n    0xA401: 'CustomRendered', // Special processing\n    0xA402: 'ExposureMode', // Exposure mode\n    0xA403: 'WhiteBalance', // 1 = auto white balance, 2 = manual\n    0xA404: 'DigitalZoomRatio', // Digital zoom ratio\n    0xA405: 'FocalLengthIn35mmFilm',\n    0xA406: 'SceneCaptureType', // Type of scene\n    0xA407: 'GainControl', // Degree of overall image gain adjustment\n    0xA408: 'Contrast', // Direction of contrast processing applied by camera\n    0xA409: 'Saturation', // Direction of saturation processing applied by camera\n    0xA40A: 'Sharpness', // Direction of sharpness processing applied by camera\n    0xA40B: 'DeviceSettingDescription',\n    0xA40C: 'SubjectDistanceRange', // Distance to subject\n    0xA420: 'ImageUniqueID', // Identifier assigned uniquely to each image\n    0xA430: 'CameraOwnerName',\n    0xA431: 'BodySerialNumber',\n    0xA432: 'LensSpecification',\n    0xA433: 'LensMake',\n    0xA434: 'LensModel',\n    0xA435: 'LensSerialNumber',\n    // ==============\n    // GPS Info tags:\n    // ==============\n    0x0000: 'GPSVersionID',\n    0x0001: 'GPSLatitudeRef',\n    0x0002: 'GPSLatitude',\n    0x0003: 'GPSLongitudeRef',\n    0x0004: 'GPSLongitude',\n    0x0005: 'GPSAltitudeRef',\n    0x0006: 'GPSAltitude',\n    0x0007: 'GPSTimeStamp',\n    0x0008: 'GPSSatellites',\n    0x0009: 'GPSStatus',\n    0x000A: 'GPSMeasureMode',\n    0x000B: 'GPSDOP',\n    0x000C: 'GPSSpeedRef',\n    0x000D: 'GPSSpeed',\n    0x000E: 'GPSTrackRef',\n    0x000F: 'GPSTrack',\n    0x0010: 'GPSImgDirectionRef',\n    0x0011: 'GPSImgDirection',\n    0x0012: 'GPSMapDatum',\n    0x0013: 'GPSDestLatitudeRef',\n    0x0014: 'GPSDestLatitude',\n    0x0015: 'GPSDestLongitudeRef',\n    0x0016: 'GPSDestLongitude',\n    0x0017: 'GPSDestBearingRef',\n    0x0018: 'GPSDestBearing',\n    0x0019: 'GPSDestDistanceRef',\n    0x001A: 'GPSDestDistance',\n    0x001B: 'GPSProcessingMethod',\n    0x001C: 'GPSAreaInformation',\n    0x001D: 'GPSDateStamp',\n    0x001E: 'GPSDifferential',\n    0x001F: 'GPSHPositioningError'\n  }\n\n  loadImage.ExifMap.prototype.stringValues = {\n    ExposureProgram: {\n      0: 'Undefined',\n      1: 'Manual',\n      2: 'Normal program',\n      3: 'Aperture priority',\n      4: 'Shutter priority',\n      5: 'Creative program',\n      6: 'Action program',\n      7: 'Portrait mode',\n      8: 'Landscape mode'\n    },\n    MeteringMode: {\n      0: 'Unknown',\n      1: 'Average',\n      2: 'CenterWeightedAverage',\n      3: 'Spot',\n      4: 'MultiSpot',\n      5: 'Pattern',\n      6: 'Partial',\n      255: 'Other'\n    },\n    LightSource: {\n      0: 'Unknown',\n      1: 'Daylight',\n      2: 'Fluorescent',\n      3: 'Tungsten (incandescent light)',\n      4: 'Flash',\n      9: 'Fine weather',\n      10: 'Cloudy weather',\n      11: 'Shade',\n      12: 'Daylight fluorescent (D 5700 - 7100K)',\n      13: 'Day white fluorescent (N 4600 - 5400K)',\n      14: 'Cool white fluorescent (W 3900 - 4500K)',\n      15: 'White fluorescent (WW 3200 - 3700K)',\n      17: 'Standard light A',\n      18: 'Standard light B',\n      19: 'Standard light C',\n      20: 'D55',\n      21: 'D65',\n      22: 'D75',\n      23: 'D50',\n      24: 'ISO studio tungsten',\n      255: 'Other'\n    },\n    Flash: {\n      0x0000: 'Flash did not fire',\n      0x0001: 'Flash fired',\n      0x0005: 'Strobe return light not detected',\n      0x0007: 'Strobe return light detected',\n      0x0009: 'Flash fired, compulsory flash mode',\n      0x000D: 'Flash fired, compulsory flash mode, return light not detected',\n      0x000F: 'Flash fired, compulsory flash mode, return light detected',\n      0x0010: 'Flash did not fire, compulsory flash mode',\n      0x0018: 'Flash did not fire, auto mode',\n      0x0019: 'Flash fired, auto mode',\n      0x001D: 'Flash fired, auto mode, return light not detected',\n      0x001F: 'Flash fired, auto mode, return light detected',\n      0x0020: 'No flash function',\n      0x0041: 'Flash fired, red-eye reduction mode',\n      0x0045: 'Flash fired, red-eye reduction mode, return light not detected',\n      0x0047: 'Flash fired, red-eye reduction mode, return light detected',\n      0x0049: 'Flash fired, compulsory flash mode, red-eye reduction mode',\n      0x004D: 'Flash fired, compulsory flash mode, red-eye reduction mode, return light not detected',\n      0x004F: 'Flash fired, compulsory flash mode, red-eye reduction mode, return light detected',\n      0x0059: 'Flash fired, auto mode, red-eye reduction mode',\n      0x005D: 'Flash fired, auto mode, return light not detected, red-eye reduction mode',\n      0x005F: 'Flash fired, auto mode, return light detected, red-eye reduction mode'\n    },\n    SensingMethod: {\n      1: 'Undefined',\n      2: 'One-chip color area sensor',\n      3: 'Two-chip color area sensor',\n      4: 'Three-chip color area sensor',\n      5: 'Color sequential area sensor',\n      7: 'Trilinear sensor',\n      8: 'Color sequential linear sensor'\n    },\n    SceneCaptureType: {\n      0: 'Standard',\n      1: 'Landscape',\n      2: 'Portrait',\n      3: 'Night scene'\n    },\n    SceneType: {\n      1: 'Directly photographed'\n    },\n    CustomRendered: {\n      0: 'Normal process',\n      1: 'Custom process'\n    },\n    WhiteBalance: {\n      0: 'Auto white balance',\n      1: 'Manual white balance'\n    },\n    GainControl: {\n      0: 'None',\n      1: 'Low gain up',\n      2: 'High gain up',\n      3: 'Low gain down',\n      4: 'High gain down'\n    },\n    Contrast: {\n      0: 'Normal',\n      1: 'Soft',\n      2: 'Hard'\n    },\n    Saturation: {\n      0: 'Normal',\n      1: 'Low saturation',\n      2: 'High saturation'\n    },\n    Sharpness: {\n      0: 'Normal',\n      1: 'Soft',\n      2: 'Hard'\n    },\n    SubjectDistanceRange: {\n      0: 'Unknown',\n      1: 'Macro',\n      2: 'Close view',\n      3: 'Distant view'\n    },\n    FileSource: {\n      3: 'DSC'\n    },\n    ComponentsConfiguration: {\n      0: '',\n      1: 'Y',\n      2: 'Cb',\n      3: 'Cr',\n      4: 'R',\n      5: 'G',\n      6: 'B'\n    },\n    Orientation: {\n      1: 'top-left',\n      2: 'top-right',\n      3: 'bottom-right',\n      4: 'bottom-left',\n      5: 'left-top',\n      6: 'right-top',\n      7: 'right-bottom',\n      8: 'left-bottom'\n    }\n  }\n\n  loadImage.ExifMap.prototype.getText = function (id) {\n    var value = this.get(id)\n    switch (id) {\n      case 'LightSource':\n      case 'Flash':\n      case 'MeteringMode':\n      case 'ExposureProgram':\n      case 'SensingMethod':\n      case 'SceneCaptureType':\n      case 'SceneType':\n      case 'CustomRendered':\n      case 'WhiteBalance':\n      case 'GainControl':\n      case 'Contrast':\n      case 'Saturation':\n      case 'Sharpness':\n      case 'SubjectDistanceRange':\n      case 'FileSource':\n      case 'Orientation':\n        return this.stringValues[id][value]\n      case 'ExifVersion':\n      case 'FlashpixVersion':\n        if (!value) return\n        return String.fromCharCode(value[0], value[1], value[2], value[3])\n      case 'ComponentsConfiguration':\n        if (!value) return\n        return this.stringValues[id][value[0]] +\n        this.stringValues[id][value[1]] +\n        this.stringValues[id][value[2]] +\n        this.stringValues[id][value[3]]\n      case 'GPSVersionID':\n        if (!value) return\n        return value[0] + '.' + value[1] + '.' + value[2] + '.' + value[3]\n    }\n    return String(value)\n  }\n\n  ;(function (exifMapPrototype) {\n    var tags = exifMapPrototype.tags\n    var map = exifMapPrototype.map\n    var prop\n    // Map the tag names to tags:\n    for (prop in tags) {\n      if (tags.hasOwnProperty(prop)) {\n        map[tags[prop]] = prop\n      }\n    }\n  }(loadImage.ExifMap.prototype))\n\n  loadImage.ExifMap.prototype.getAll = function () {\n    var map = {}\n    var prop\n    var id\n    for (prop in this) {\n      if (this.hasOwnProperty(prop)) {\n        id = this.tags[prop]\n        if (id) {\n          map[id] = this.getText(id)\n        }\n      }\n    }\n    return map\n  }\n}))\n"
  },
  {
    "path": "app_backend/static/plugin/JavaScript-Load-Image-2.12.2/js/load-image-exif.js",
    "content": "/*\n * JavaScript Load Image Exif Parser\n * https://github.com/blueimp/JavaScript-Load-Image\n *\n * Copyright 2013, Sebastian Tschan\n * https://blueimp.net\n *\n * Licensed under the MIT license:\n * https://opensource.org/licenses/MIT\n */\n\n/* global define */\n\n;(function (factory) {\n  'use strict'\n  if (typeof define === 'function' && define.amd) {\n    // Register as an anonymous AMD module:\n    define(['./load-image', './load-image-meta'], factory)\n  } else if (typeof module === 'object' && module.exports) {\n    factory(require('./load-image'), require('./load-image-meta'))\n  } else {\n    // Browser globals:\n    factory(window.loadImage)\n  }\n}(function (loadImage) {\n  'use strict'\n\n  loadImage.ExifMap = function () {\n    return this\n  }\n\n  loadImage.ExifMap.prototype.map = {\n    'Orientation': 0x0112\n  }\n\n  loadImage.ExifMap.prototype.get = function (id) {\n    return this[id] || this[this.map[id]]\n  }\n\n  loadImage.getExifThumbnail = function (dataView, offset, length) {\n    var hexData,\n      i,\n      b\n    if (!length || offset + length > dataView.byteLength) {\n      console.log('Invalid Exif data: Invalid thumbnail data.')\n      return\n    }\n    hexData = []\n    for (i = 0; i < length; i += 1) {\n      b = dataView.getUint8(offset + i)\n      hexData.push((b < 16 ? '0' : '') + b.toString(16))\n    }\n    return 'data:image/jpeg,%' + hexData.join('%')\n  }\n\n  loadImage.exifTagTypes = {\n    // byte, 8-bit unsigned int:\n    1: {\n      getValue: function (dataView, dataOffset) {\n        return dataView.getUint8(dataOffset)\n      },\n      size: 1\n    },\n    // ascii, 8-bit byte:\n    2: {\n      getValue: function (dataView, dataOffset) {\n        return String.fromCharCode(dataView.getUint8(dataOffset))\n      },\n      size: 1,\n      ascii: true\n    },\n    // short, 16 bit int:\n    3: {\n      getValue: function (dataView, dataOffset, littleEndian) {\n        return dataView.getUint16(dataOffset, littleEndian)\n      },\n      size: 2\n    },\n    // long, 32 bit int:\n    4: {\n      getValue: function (dataView, dataOffset, littleEndian) {\n        return dataView.getUint32(dataOffset, littleEndian)\n      },\n      size: 4\n    },\n    // rational = two long values, first is numerator, second is denominator:\n    5: {\n      getValue: function (dataView, dataOffset, littleEndian) {\n        return dataView.getUint32(dataOffset, littleEndian) /\n        dataView.getUint32(dataOffset + 4, littleEndian)\n      },\n      size: 8\n    },\n    // slong, 32 bit signed int:\n    9: {\n      getValue: function (dataView, dataOffset, littleEndian) {\n        return dataView.getInt32(dataOffset, littleEndian)\n      },\n      size: 4\n    },\n    // srational, two slongs, first is numerator, second is denominator:\n    10: {\n      getValue: function (dataView, dataOffset, littleEndian) {\n        return dataView.getInt32(dataOffset, littleEndian) /\n        dataView.getInt32(dataOffset + 4, littleEndian)\n      },\n      size: 8\n    }\n  }\n  // undefined, 8-bit byte, value depending on field:\n  loadImage.exifTagTypes[7] = loadImage.exifTagTypes[1]\n\n  loadImage.getExifValue = function (dataView, tiffOffset, offset, type, length, littleEndian) {\n    var tagType = loadImage.exifTagTypes[type]\n    var tagSize\n    var dataOffset\n    var values\n    var i\n    var str\n    var c\n    if (!tagType) {\n      console.log('Invalid Exif data: Invalid tag type.')\n      return\n    }\n    tagSize = tagType.size * length\n    // Determine if the value is contained in the dataOffset bytes,\n    // or if the value at the dataOffset is a pointer to the actual data:\n    dataOffset = tagSize > 4\n      ? tiffOffset + dataView.getUint32(offset + 8, littleEndian)\n      : (offset + 8)\n    if (dataOffset + tagSize > dataView.byteLength) {\n      console.log('Invalid Exif data: Invalid data offset.')\n      return\n    }\n    if (length === 1) {\n      return tagType.getValue(dataView, dataOffset, littleEndian)\n    }\n    values = []\n    for (i = 0; i < length; i += 1) {\n      values[i] = tagType.getValue(dataView, dataOffset + i * tagType.size, littleEndian)\n    }\n    if (tagType.ascii) {\n      str = ''\n      // Concatenate the chars:\n      for (i = 0; i < values.length; i += 1) {\n        c = values[i]\n        // Ignore the terminating NULL byte(s):\n        if (c === '\\u0000') {\n          break\n        }\n        str += c\n      }\n      return str\n    }\n    return values\n  }\n\n  loadImage.parseExifTag = function (dataView, tiffOffset, offset, littleEndian, data) {\n    var tag = dataView.getUint16(offset, littleEndian)\n    data.exif[tag] = loadImage.getExifValue(\n      dataView,\n      tiffOffset,\n      offset,\n      dataView.getUint16(offset + 2, littleEndian), // tag type\n      dataView.getUint32(offset + 4, littleEndian), // tag length\n      littleEndian\n    )\n  }\n\n  loadImage.parseExifTags = function (dataView, tiffOffset, dirOffset, littleEndian, data) {\n    var tagsNumber,\n      dirEndOffset,\n      i\n    if (dirOffset + 6 > dataView.byteLength) {\n      console.log('Invalid Exif data: Invalid directory offset.')\n      return\n    }\n    tagsNumber = dataView.getUint16(dirOffset, littleEndian)\n    dirEndOffset = dirOffset + 2 + 12 * tagsNumber\n    if (dirEndOffset + 4 > dataView.byteLength) {\n      console.log('Invalid Exif data: Invalid directory size.')\n      return\n    }\n    for (i = 0; i < tagsNumber; i += 1) {\n      this.parseExifTag(\n        dataView,\n        tiffOffset,\n        dirOffset + 2 + 12 * i, // tag offset\n        littleEndian,\n        data\n      )\n    }\n    // Return the offset to the next directory:\n    return dataView.getUint32(dirEndOffset, littleEndian)\n  }\n\n  loadImage.parseExifData = function (dataView, offset, length, data, options) {\n    if (options.disableExif) {\n      return\n    }\n    var tiffOffset = offset + 10\n    var littleEndian\n    var dirOffset\n    var thumbnailData\n    // Check for the ASCII code for \"Exif\" (0x45786966):\n    if (dataView.getUint32(offset + 4) !== 0x45786966) {\n      // No Exif data, might be XMP data instead\n      return\n    }\n    if (tiffOffset + 8 > dataView.byteLength) {\n      console.log('Invalid Exif data: Invalid segment size.')\n      return\n    }\n    // Check for the two null bytes:\n    if (dataView.getUint16(offset + 8) !== 0x0000) {\n      console.log('Invalid Exif data: Missing byte alignment offset.')\n      return\n    }\n    // Check the byte alignment:\n    switch (dataView.getUint16(tiffOffset)) {\n      case 0x4949:\n        littleEndian = true\n        break\n      case 0x4D4D:\n        littleEndian = false\n        break\n      default:\n        console.log('Invalid Exif data: Invalid byte alignment marker.')\n        return\n    }\n    // Check for the TIFF tag marker (0x002A):\n    if (dataView.getUint16(tiffOffset + 2, littleEndian) !== 0x002A) {\n      console.log('Invalid Exif data: Missing TIFF marker.')\n      return\n    }\n    // Retrieve the directory offset bytes, usually 0x00000008 or 8 decimal:\n    dirOffset = dataView.getUint32(tiffOffset + 4, littleEndian)\n    // Create the exif object to store the tags:\n    data.exif = new loadImage.ExifMap()\n    // Parse the tags of the main image directory and retrieve the\n    // offset to the next directory, usually the thumbnail directory:\n    dirOffset = loadImage.parseExifTags(\n      dataView,\n      tiffOffset,\n      tiffOffset + dirOffset,\n      littleEndian,\n      data\n    )\n    if (dirOffset && !options.disableExifThumbnail) {\n      thumbnailData = {exif: {}}\n      dirOffset = loadImage.parseExifTags(\n        dataView,\n        tiffOffset,\n        tiffOffset + dirOffset,\n        littleEndian,\n        thumbnailData\n      )\n      // Check for JPEG Thumbnail offset:\n      if (thumbnailData.exif[0x0201]) {\n        data.exif.Thumbnail = loadImage.getExifThumbnail(\n          dataView,\n          tiffOffset + thumbnailData.exif[0x0201],\n          thumbnailData.exif[0x0202] // Thumbnail data length\n        )\n      }\n    }\n    // Check for Exif Sub IFD Pointer:\n    if (data.exif[0x8769] && !options.disableExifSub) {\n      loadImage.parseExifTags(\n        dataView,\n        tiffOffset,\n        tiffOffset + data.exif[0x8769], // directory offset\n        littleEndian,\n        data\n      )\n    }\n    // Check for GPS Info IFD Pointer:\n    if (data.exif[0x8825] && !options.disableExifGps) {\n      loadImage.parseExifTags(\n        dataView,\n        tiffOffset,\n        tiffOffset + data.exif[0x8825], // directory offset\n        littleEndian,\n        data\n      )\n    }\n  }\n\n  // Registers the Exif parser for the APP1 JPEG meta data segment:\n  loadImage.metaDataParsers.jpeg[0xffe1].push(loadImage.parseExifData)\n\n  // Adds the following properties to the parseMetaData callback data:\n  // * exif: The exif tags, parsed by the parseExifData method\n\n  // Adds the following options to the parseMetaData method:\n  // * disableExif: Disables Exif parsing.\n  // * disableExifThumbnail: Disables parsing of the Exif Thumbnail.\n  // * disableExifSub: Disables parsing of the Exif Sub IFD.\n  // * disableExifGps: Disables parsing of the Exif GPS Info IFD.\n}))\n"
  },
  {
    "path": "app_backend/static/plugin/JavaScript-Load-Image-2.12.2/js/load-image-fetch.js",
    "content": "/*\n * JavaScript Load Image Fetch\n * https://github.com/blueimp/JavaScript-Load-Image\n *\n * Copyright 2017, Sebastian Tschan\n * https://blueimp.net\n *\n * Licensed under the MIT license:\n * https://opensource.org/licenses/MIT\n */\n\n/* global define, fetch, Request */\n\n;(function (factory) {\n  'use strict'\n  if (typeof define === 'function' && define.amd) {\n    // Register as an anonymous AMD module:\n    define(['./load-image', './load-image-meta'], factory)\n  } else if (typeof module === 'object' && module.exports) {\n    factory(require('./load-image'), require('./load-image-meta'))\n  } else {\n    // Browser globals:\n    factory(window.loadImage)\n  }\n}(function (loadImage) {\n  'use strict'\n\n  if ('fetch' in window && 'Request' in window) {\n    loadImage.fetchBlob = function (url, callback, options) {\n      if (loadImage.hasMetaOption(options)) {\n        return fetch(new Request(url, options)).then(function (response) {\n          return response.blob()\n        }).then(callback).catch(function (err) {\n          console.log(err)\n          callback()\n        })\n      } else {\n        callback()\n      }\n    }\n  }\n}))\n"
  },
  {
    "path": "app_backend/static/plugin/JavaScript-Load-Image-2.12.2/js/load-image-meta.js",
    "content": "/*\n * JavaScript Load Image Meta\n * https://github.com/blueimp/JavaScript-Load-Image\n *\n * Copyright 2013, Sebastian Tschan\n * https://blueimp.net\n *\n * Image meta data handling implementation\n * based on the help and contribution of\n * Achim Stöhr.\n *\n * Licensed under the MIT license:\n * https://opensource.org/licenses/MIT\n */\n\n/* global define, Blob */\n\n;(function (factory) {\n  'use strict'\n  if (typeof define === 'function' && define.amd) {\n    // Register as an anonymous AMD module:\n    define(['./load-image'], factory)\n  } else if (typeof module === 'object' && module.exports) {\n    factory(require('./load-image'))\n  } else {\n    // Browser globals:\n    factory(window.loadImage)\n  }\n}(function (loadImage) {\n  'use strict'\n\n  var hasblobSlice = window.Blob && (Blob.prototype.slice ||\n  Blob.prototype.webkitSlice || Blob.prototype.mozSlice)\n\n  loadImage.blobSlice = hasblobSlice && function () {\n    var slice = this.slice || this.webkitSlice || this.mozSlice\n    return slice.apply(this, arguments)\n  }\n\n  loadImage.metaDataParsers = {\n    jpeg: {\n      0xffe1: [] // APP1 marker\n    }\n  }\n\n  // Parses image meta data and calls the callback with an object argument\n  // with the following properties:\n  // * imageHead: The complete image head as ArrayBuffer (Uint8Array for IE10)\n  // The options arguments accepts an object and supports the following properties:\n  // * maxMetaDataSize: Defines the maximum number of bytes to parse.\n  // * disableImageHead: Disables creating the imageHead property.\n  loadImage.parseMetaData = function (file, callback, options, data) {\n    options = options || {}\n    data = data || {}\n    var that = this\n    // 256 KiB should contain all EXIF/ICC/IPTC segments:\n    var maxMetaDataSize = options.maxMetaDataSize || 262144\n    var noMetaData = !(window.DataView && file && file.size >= 12 &&\n                      file.type === 'image/jpeg' && loadImage.blobSlice)\n    if (noMetaData || !loadImage.readFile(\n        loadImage.blobSlice.call(file, 0, maxMetaDataSize),\n        function (e) {\n          if (e.target.error) {\n            // FileReader error\n            console.log(e.target.error)\n            callback(data)\n            return\n          }\n          // Note on endianness:\n          // Since the marker and length bytes in JPEG files are always\n          // stored in big endian order, we can leave the endian parameter\n          // of the DataView methods undefined, defaulting to big endian.\n          var buffer = e.target.result\n          var dataView = new DataView(buffer)\n          var offset = 2\n          var maxOffset = dataView.byteLength - 4\n          var headLength = offset\n          var markerBytes\n          var markerLength\n          var parsers\n          var i\n          // Check for the JPEG marker (0xffd8):\n          if (dataView.getUint16(0) === 0xffd8) {\n            while (offset < maxOffset) {\n              markerBytes = dataView.getUint16(offset)\n              // Search for APPn (0xffeN) and COM (0xfffe) markers,\n              // which contain application-specific meta-data like\n              // Exif, ICC and IPTC data and text comments:\n              if ((markerBytes >= 0xffe0 && markerBytes <= 0xffef) ||\n                markerBytes === 0xfffe) {\n                // The marker bytes (2) are always followed by\n                // the length bytes (2), indicating the length of the\n                // marker segment, which includes the length bytes,\n                // but not the marker bytes, so we add 2:\n                markerLength = dataView.getUint16(offset + 2) + 2\n                if (offset + markerLength > dataView.byteLength) {\n                  console.log('Invalid meta data: Invalid segment size.')\n                  break\n                }\n                parsers = loadImage.metaDataParsers.jpeg[markerBytes]\n                if (parsers) {\n                  for (i = 0; i < parsers.length; i += 1) {\n                    parsers[i].call(\n                      that,\n                      dataView,\n                      offset,\n                      markerLength,\n                      data,\n                      options\n                    )\n                  }\n                }\n                offset += markerLength\n                headLength = offset\n              } else {\n                // Not an APPn or COM marker, probably safe to\n                // assume that this is the end of the meta data\n                break\n              }\n            }\n            // Meta length must be longer than JPEG marker (2)\n            // plus APPn marker (2), followed by length bytes (2):\n            if (!options.disableImageHead && headLength > 6) {\n              if (buffer.slice) {\n                data.imageHead = buffer.slice(0, headLength)\n              } else {\n                // Workaround for IE10, which does not yet\n                // support ArrayBuffer.slice:\n                data.imageHead = new Uint8Array(buffer)\n                  .subarray(0, headLength)\n              }\n            }\n          } else {\n            console.log('Invalid JPEG file: Missing JPEG marker.')\n          }\n          callback(data)\n        },\n        'readAsArrayBuffer'\n      )) {\n      callback(data)\n    }\n  }\n\n  // Determines if meta data should be loaded automatically:\n  loadImage.hasMetaOption = function (options) {\n    return options && options.meta\n  }\n\n  var originalTransform = loadImage.transform\n  loadImage.transform = function (img, options, callback, file, data) {\n    if (loadImage.hasMetaOption(options)) {\n      loadImage.parseMetaData(file, function (data) {\n        originalTransform.call(loadImage, img, options, callback, file, data)\n      }, options, data)\n    } else {\n      originalTransform.apply(loadImage, arguments)\n    }\n  }\n}))\n"
  },
  {
    "path": "app_backend/static/plugin/JavaScript-Load-Image-2.12.2/js/load-image-orientation.js",
    "content": "/*\n * JavaScript Load Image Orientation\n * https://github.com/blueimp/JavaScript-Load-Image\n *\n * Copyright 2013, Sebastian Tschan\n * https://blueimp.net\n *\n * Licensed under the MIT license:\n * https://opensource.org/licenses/MIT\n */\n\n/* global define */\n\n;(function (factory) {\n  'use strict'\n  if (typeof define === 'function' && define.amd) {\n    // Register as an anonymous AMD module:\n    define(['./load-image', './load-image-scale', './load-image-meta'], factory)\n  } else if (typeof module === 'object' && module.exports) {\n    factory(\n      require('./load-image'),\n      require('./load-image-scale'),\n      require('./load-image-meta')\n    )\n  } else {\n    // Browser globals:\n    factory(window.loadImage)\n  }\n}(function (loadImage) {\n  'use strict'\n\n  var originalHasCanvasOption = loadImage.hasCanvasOption\n  var originalHasMetaOption = loadImage.hasMetaOption\n  var originalTransformCoordinates = loadImage.transformCoordinates\n  var originalGetTransformedOptions = loadImage.getTransformedOptions\n\n  // Determines if the target image should be a canvas element:\n  loadImage.hasCanvasOption = function (options) {\n    return !!options.orientation ||\n      originalHasCanvasOption.call(loadImage, options)\n  }\n\n  // Determines if meta data should be loaded automatically:\n  loadImage.hasMetaOption = function (options) {\n    return options && options.orientation === true ||\n      originalHasMetaOption.call(loadImage, options)\n  }\n\n  // Transform image orientation based on\n  // the given EXIF orientation option:\n  loadImage.transformCoordinates = function (canvas, options) {\n    originalTransformCoordinates.call(loadImage, canvas, options)\n    var ctx = canvas.getContext('2d')\n    var width = canvas.width\n    var height = canvas.height\n    var styleWidth = canvas.style.width\n    var styleHeight = canvas.style.height\n    var orientation = options.orientation\n    if (!orientation || orientation > 8) {\n      return\n    }\n    if (orientation > 4) {\n      canvas.width = height\n      canvas.height = width\n      canvas.style.width = styleHeight\n      canvas.style.height = styleWidth\n    }\n    switch (orientation) {\n      case 2:\n        // horizontal flip\n        ctx.translate(width, 0)\n        ctx.scale(-1, 1)\n        break\n      case 3:\n        // 180° rotate left\n        ctx.translate(width, height)\n        ctx.rotate(Math.PI)\n        break\n      case 4:\n        // vertical flip\n        ctx.translate(0, height)\n        ctx.scale(1, -1)\n        break\n      case 5:\n        // vertical flip + 90 rotate right\n        ctx.rotate(0.5 * Math.PI)\n        ctx.scale(1, -1)\n        break\n      case 6:\n        // 90° rotate right\n        ctx.rotate(0.5 * Math.PI)\n        ctx.translate(0, -height)\n        break\n      case 7:\n        // horizontal flip + 90 rotate right\n        ctx.rotate(0.5 * Math.PI)\n        ctx.translate(width, -height)\n        ctx.scale(-1, 1)\n        break\n      case 8:\n        // 90° rotate left\n        ctx.rotate(-0.5 * Math.PI)\n        ctx.translate(-width, 0)\n        break\n    }\n  }\n\n  // Transforms coordinate and dimension options\n  // based on the given orientation option:\n  loadImage.getTransformedOptions = function (img, opts, data) {\n    var options = originalGetTransformedOptions.call(loadImage, img, opts)\n    var orientation = options.orientation\n    var newOptions\n    var i\n    if (orientation === true && data && data.exif) {\n      orientation = data.exif.get('Orientation')\n    }\n    if (!orientation || orientation > 8 || orientation === 1) {\n      return options\n    }\n    newOptions = {}\n    for (i in options) {\n      if (options.hasOwnProperty(i)) {\n        newOptions[i] = options[i]\n      }\n    }\n    newOptions.orientation = orientation\n    switch (orientation) {\n      case 2:\n        // horizontal flip\n        newOptions.left = options.right\n        newOptions.right = options.left\n        break\n      case 3:\n        // 180° rotate left\n        newOptions.left = options.right\n        newOptions.top = options.bottom\n        newOptions.right = options.left\n        newOptions.bottom = options.top\n        break\n      case 4:\n        // vertical flip\n        newOptions.top = options.bottom\n        newOptions.bottom = options.top\n        break\n      case 5:\n        // vertical flip + 90 rotate right\n        newOptions.left = options.top\n        newOptions.top = options.left\n        newOptions.right = options.bottom\n        newOptions.bottom = options.right\n        break\n      case 6:\n        // 90° rotate right\n        newOptions.left = options.top\n        newOptions.top = options.right\n        newOptions.right = options.bottom\n        newOptions.bottom = options.left\n        break\n      case 7:\n        // horizontal flip + 90 rotate right\n        newOptions.left = options.bottom\n        newOptions.top = options.right\n        newOptions.right = options.top\n        newOptions.bottom = options.left\n        break\n      case 8:\n        // 90° rotate left\n        newOptions.left = options.bottom\n        newOptions.top = options.left\n        newOptions.right = options.top\n        newOptions.bottom = options.right\n        break\n    }\n    if (newOptions.orientation > 4) {\n      newOptions.maxWidth = options.maxHeight\n      newOptions.maxHeight = options.maxWidth\n      newOptions.minWidth = options.minHeight\n      newOptions.minHeight = options.minWidth\n      newOptions.sourceWidth = options.sourceHeight\n      newOptions.sourceHeight = options.sourceWidth\n    }\n    return newOptions\n  }\n}))\n"
  },
  {
    "path": "app_backend/static/plugin/JavaScript-Load-Image-2.12.2/js/load-image-scale.js",
    "content": "/*\n * JavaScript Load Image Scaling\n * https://github.com/blueimp/JavaScript-Load-Image\n *\n * Copyright 2011, Sebastian Tschan\n * https://blueimp.net\n *\n * Licensed under the MIT license:\n * https://opensource.org/licenses/MIT\n */\n\n/* global define */\n\n;(function (factory) {\n  'use strict'\n  if (typeof define === 'function' && define.amd) {\n    // Register as an anonymous AMD module:\n    define(['./load-image'], factory)\n  } else if (typeof module === 'object' && module.exports) {\n    factory(require('./load-image'))\n  } else {\n    // Browser globals:\n    factory(window.loadImage)\n  }\n}(function (loadImage) {\n  'use strict'\n\n  var originalTransform = loadImage.transform\n\n  loadImage.transform = function (img, options, callback, file, data) {\n    originalTransform.call(\n      loadImage,\n      loadImage.scale(img, options, data),\n      options,\n      callback,\n      file,\n      data\n    )\n  }\n\n  // Transform image coordinates, allows to override e.g.\n  // the canvas orientation based on the orientation option,\n  // gets canvas, options passed as arguments:\n  loadImage.transformCoordinates = function () {\n    return\n  }\n\n  // Returns transformed options, allows to override e.g.\n  // maxWidth, maxHeight and crop options based on the aspectRatio.\n  // gets img, options passed as arguments:\n  loadImage.getTransformedOptions = function (img, options) {\n    var aspectRatio = options.aspectRatio\n    var newOptions\n    var i\n    var width\n    var height\n    if (!aspectRatio) {\n      return options\n    }\n    newOptions = {}\n    for (i in options) {\n      if (options.hasOwnProperty(i)) {\n        newOptions[i] = options[i]\n      }\n    }\n    newOptions.crop = true\n    width = img.naturalWidth || img.width\n    height = img.naturalHeight || img.height\n    if (width / height > aspectRatio) {\n      newOptions.maxWidth = height * aspectRatio\n      newOptions.maxHeight = height\n    } else {\n      newOptions.maxWidth = width\n      newOptions.maxHeight = width / aspectRatio\n    }\n    return newOptions\n  }\n\n  // Canvas render method, allows to implement a different rendering algorithm:\n  loadImage.renderImageToCanvas = function (\n    canvas,\n    img,\n    sourceX,\n    sourceY,\n    sourceWidth,\n    sourceHeight,\n    destX,\n    destY,\n    destWidth,\n    destHeight\n  ) {\n    canvas.getContext('2d').drawImage(\n      img,\n      sourceX,\n      sourceY,\n      sourceWidth,\n      sourceHeight,\n      destX,\n      destY,\n      destWidth,\n      destHeight\n    )\n    return canvas\n  }\n\n  // Determines if the target image should be a canvas element:\n  loadImage.hasCanvasOption = function (options) {\n    return options.canvas || options.crop || !!options.aspectRatio\n  }\n\n  // Scales and/or crops the given image (img or canvas HTML element)\n  // using the given options.\n  // Returns a canvas object if the browser supports canvas\n  // and the hasCanvasOption method returns true or a canvas\n  // object is passed as image, else the scaled image:\n  loadImage.scale = function (img, options, data) {\n    options = options || {}\n    var canvas = document.createElement('canvas')\n    var useCanvas = img.getContext ||\n                    (loadImage.hasCanvasOption(options) && canvas.getContext)\n    var width = img.naturalWidth || img.width\n    var height = img.naturalHeight || img.height\n    var destWidth = width\n    var destHeight = height\n    var maxWidth\n    var maxHeight\n    var minWidth\n    var minHeight\n    var sourceWidth\n    var sourceHeight\n    var sourceX\n    var sourceY\n    var pixelRatio\n    var downsamplingRatio\n    var tmp\n    function scaleUp () {\n      var scale = Math.max(\n        (minWidth || destWidth) / destWidth,\n        (minHeight || destHeight) / destHeight\n      )\n      if (scale > 1) {\n        destWidth *= scale\n        destHeight *= scale\n      }\n    }\n    function scaleDown () {\n      var scale = Math.min(\n        (maxWidth || destWidth) / destWidth,\n        (maxHeight || destHeight) / destHeight\n      )\n      if (scale < 1) {\n        destWidth *= scale\n        destHeight *= scale\n      }\n    }\n    if (useCanvas) {\n      options = loadImage.getTransformedOptions(img, options, data)\n      sourceX = options.left || 0\n      sourceY = options.top || 0\n      if (options.sourceWidth) {\n        sourceWidth = options.sourceWidth\n        if (options.right !== undefined && options.left === undefined) {\n          sourceX = width - sourceWidth - options.right\n        }\n      } else {\n        sourceWidth = width - sourceX - (options.right || 0)\n      }\n      if (options.sourceHeight) {\n        sourceHeight = options.sourceHeight\n        if (options.bottom !== undefined && options.top === undefined) {\n          sourceY = height - sourceHeight - options.bottom\n        }\n      } else {\n        sourceHeight = height - sourceY - (options.bottom || 0)\n      }\n      destWidth = sourceWidth\n      destHeight = sourceHeight\n    }\n    maxWidth = options.maxWidth\n    maxHeight = options.maxHeight\n    minWidth = options.minWidth\n    minHeight = options.minHeight\n    if (useCanvas && maxWidth && maxHeight && options.crop) {\n      destWidth = maxWidth\n      destHeight = maxHeight\n      tmp = sourceWidth / sourceHeight - maxWidth / maxHeight\n      if (tmp < 0) {\n        sourceHeight = maxHeight * sourceWidth / maxWidth\n        if (options.top === undefined && options.bottom === undefined) {\n          sourceY = (height - sourceHeight) / 2\n        }\n      } else if (tmp > 0) {\n        sourceWidth = maxWidth * sourceHeight / maxHeight\n        if (options.left === undefined && options.right === undefined) {\n          sourceX = (width - sourceWidth) / 2\n        }\n      }\n    } else {\n      if (options.contain || options.cover) {\n        minWidth = maxWidth = maxWidth || minWidth\n        minHeight = maxHeight = maxHeight || minHeight\n      }\n      if (options.cover) {\n        scaleDown()\n        scaleUp()\n      } else {\n        scaleUp()\n        scaleDown()\n      }\n    }\n    if (useCanvas) {\n      pixelRatio = options.pixelRatio\n      if (pixelRatio > 1) {\n        canvas.style.width = destWidth + 'px'\n        canvas.style.height = destHeight + 'px'\n        destWidth *= pixelRatio\n        destHeight *= pixelRatio\n        canvas.getContext('2d').scale(pixelRatio, pixelRatio)\n      }\n      downsamplingRatio = options.downsamplingRatio\n      if (downsamplingRatio > 0 && downsamplingRatio < 1 &&\n            destWidth < sourceWidth && destHeight < sourceHeight) {\n        while (sourceWidth * downsamplingRatio > destWidth) {\n          canvas.width = sourceWidth * downsamplingRatio\n          canvas.height = sourceHeight * downsamplingRatio\n          loadImage.renderImageToCanvas(\n            canvas,\n            img,\n            sourceX,\n            sourceY,\n            sourceWidth,\n            sourceHeight,\n            0,\n            0,\n            canvas.width,\n            canvas.height\n          )\n          sourceX = 0\n          sourceY = 0\n          sourceWidth = canvas.width\n          sourceHeight = canvas.height\n          img = document.createElement('canvas')\n          img.width = sourceWidth\n          img.height = sourceHeight\n          loadImage.renderImageToCanvas(\n            img,\n            canvas,\n            0,\n            0,\n            sourceWidth,\n            sourceHeight,\n            0,\n            0,\n            sourceWidth,\n            sourceHeight\n          )\n        }\n      }\n      canvas.width = destWidth\n      canvas.height = destHeight\n      loadImage.transformCoordinates(\n        canvas,\n        options\n      )\n      return loadImage.renderImageToCanvas(\n        canvas,\n        img,\n        sourceX,\n        sourceY,\n        sourceWidth,\n        sourceHeight,\n        0,\n        0,\n        destWidth,\n        destHeight\n      )\n    }\n    img.width = destWidth\n    img.height = destHeight\n    return img\n  }\n}))\n"
  },
  {
    "path": "app_backend/static/plugin/JavaScript-Load-Image-2.12.2/js/load-image.js",
    "content": "/*\n * JavaScript Load Image\n * https://github.com/blueimp/JavaScript-Load-Image\n *\n * Copyright 2011, Sebastian Tschan\n * https://blueimp.net\n *\n * Licensed under the MIT license:\n * https://opensource.org/licenses/MIT\n */\n\n/* global define, URL, webkitURL, FileReader */\n\n;(function ($) {\n  'use strict'\n\n  // Loads an image for a given File object.\n  // Invokes the callback with an img or optional canvas\n  // element (if supported by the browser) as parameter:\n  function loadImage (file, callback, options) {\n    var img = document.createElement('img')\n    var url\n    img.onerror = function (event) {\n      return loadImage.onerror(img, event, file, callback, options)\n    }\n    img.onload = function (event) {\n      return loadImage.onload(img, event, file, callback, options)\n    }\n    if (typeof file === 'string') {\n      loadImage.fetchBlob(file, function (blob) {\n        if (blob) {\n          file = blob\n          url = loadImage.createObjectURL(file)\n        } else {\n          url = file\n          if (options && options.crossOrigin) {\n            img.crossOrigin = options.crossOrigin\n          }\n        }\n        img.src = url\n      }, options)\n      return img\n    } else if (loadImage.isInstanceOf('Blob', file) ||\n        // Files are also Blob instances, but some browsers\n        // (Firefox 3.6) support the File API but not Blobs:\n        loadImage.isInstanceOf('File', file)) {\n      url = img._objectURL = loadImage.createObjectURL(file)\n      if (url) {\n        img.src = url\n        return img\n      }\n      return loadImage.readFile(file, function (e) {\n        var target = e.target\n        if (target && target.result) {\n          img.src = target.result\n        } else if (callback) {\n          callback(e)\n        }\n      })\n    }\n  }\n  // The check for URL.revokeObjectURL fixes an issue with Opera 12,\n  // which provides URL.createObjectURL but doesn't properly implement it:\n  var urlAPI = (window.createObjectURL && window) ||\n                (window.URL && URL.revokeObjectURL && URL) ||\n                (window.webkitURL && webkitURL)\n\n  function revokeHelper (img, options) {\n    if (img._objectURL && !(options && options.noRevoke)) {\n      loadImage.revokeObjectURL(img._objectURL)\n      delete img._objectURL\n    }\n  }\n\n  // If the callback given to this function returns a blob, it is used as image\n  // source instead of the original url and overrides the file argument used in\n  // the onload and onerror event callbacks:\n  loadImage.fetchBlob = function (url, callback, options) {\n    callback()\n  }\n\n  loadImage.isInstanceOf = function (type, obj) {\n    // Cross-frame instanceof check\n    return Object.prototype.toString.call(obj) === '[object ' + type + ']'\n  }\n\n  loadImage.transform = function (img, options, callback, file, data) {\n    callback(img, data)\n  }\n\n  loadImage.onerror = function (img, event, file, callback, options) {\n    revokeHelper(img, options)\n    if (callback) {\n      callback.call(img, event)\n    }\n  }\n\n  loadImage.onload = function (img, event, file, callback, options) {\n    revokeHelper(img, options)\n    if (callback) {\n      loadImage.transform(img, options, callback, file, {})\n    }\n  }\n\n  loadImage.createObjectURL = function (file) {\n    return urlAPI ? urlAPI.createObjectURL(file) : false\n  }\n\n  loadImage.revokeObjectURL = function (url) {\n    return urlAPI ? urlAPI.revokeObjectURL(url) : false\n  }\n\n  // Loads a given File object via FileReader interface,\n  // invokes the callback with the event object (load or error).\n  // The result can be read via event.target.result:\n  loadImage.readFile = function (file, callback, method) {\n    if (window.FileReader) {\n      var fileReader = new FileReader()\n      fileReader.onload = fileReader.onerror = callback\n      method = method || 'readAsDataURL'\n      if (fileReader[method]) {\n        fileReader[method](file)\n        return fileReader\n      }\n    }\n    return false\n  }\n\n  if (typeof define === 'function' && define.amd) {\n    define(function () {\n      return loadImage\n    })\n  } else if (typeof module === 'object' && module.exports) {\n    module.exports = loadImage\n  } else {\n    $.loadImage = loadImage\n  }\n}(window))\n"
  },
  {
    "path": "app_backend/static/plugin/JavaScript-Load-Image-2.12.2/js/vendor/jquery.Jcrop.js",
    "content": "/**\n * jquery.Jcrop.js v0.9.12\n * jQuery Image Cropping Plugin - released under MIT License \n * Author: Kelly Hallman <khallman@gmail.com>\n * http://github.com/tapmodo/Jcrop\n * Copyright (c) 2008-2013 Tapmodo Interactive LLC {{{\n *\n * Permission is hereby granted, free of charge, to any person\n * obtaining a copy of this software and associated documentation\n * files (the \"Software\"), to deal in the Software without\n * restriction, including without limitation the rights to use,\n * copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the\n * Software is furnished to do so, subject to the following\n * conditions:\n *\n * The above copyright notice and this permission notice shall be\n * included in all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\n * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES\n * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\n * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT\n * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,\n * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR\n * OTHER DEALINGS IN THE SOFTWARE.\n *\n * }}}\n */\n\n(function ($) {\n\n  $.Jcrop = function (obj, opt) {\n    var options = $.extend({}, $.Jcrop.defaults),\n        docOffset,\n        _ua = navigator.userAgent.toLowerCase(),\n        is_msie = /msie/.test(_ua),\n        ie6mode = /msie [1-6]\\./.test(_ua);\n\n    // Internal Methods {{{\n    function px(n) {\n      return Math.round(n) + 'px';\n    }\n    function cssClass(cl) {\n      return options.baseClass + '-' + cl;\n    }\n    function supportsColorFade() {\n      return $.fx.step.hasOwnProperty('backgroundColor');\n    }\n    function getPos(obj) //{{{\n    {\n      var pos = $(obj).offset();\n      return [pos.left, pos.top];\n    }\n    //}}}\n    function mouseAbs(e) //{{{\n    {\n      return [(e.pageX - docOffset[0]), (e.pageY - docOffset[1])];\n    }\n    //}}}\n    function setOptions(opt) //{{{\n    {\n      if (typeof(opt) !== 'object') opt = {};\n      options = $.extend(options, opt);\n\n      $.each(['onChange','onSelect','onRelease','onDblClick'],function(i,e) {\n        if (typeof(options[e]) !== 'function') options[e] = function () {};\n      });\n    }\n    //}}}\n    function startDragMode(mode, pos, touch) //{{{\n    {\n      docOffset = getPos($img);\n      Tracker.setCursor(mode === 'move' ? mode : mode + '-resize');\n\n      if (mode === 'move') {\n        return Tracker.activateHandlers(createMover(pos), doneSelect, touch);\n      }\n\n      var fc = Coords.getFixed();\n      var opp = oppLockCorner(mode);\n      var opc = Coords.getCorner(oppLockCorner(opp));\n\n      Coords.setPressed(Coords.getCorner(opp));\n      Coords.setCurrent(opc);\n\n      Tracker.activateHandlers(dragmodeHandler(mode, fc), doneSelect, touch);\n    }\n    //}}}\n    function dragmodeHandler(mode, f) //{{{\n    {\n      return function (pos) {\n        if (!options.aspectRatio) {\n          switch (mode) {\n          case 'e':\n            pos[1] = f.y2;\n            break;\n          case 'w':\n            pos[1] = f.y2;\n            break;\n          case 'n':\n            pos[0] = f.x2;\n            break;\n          case 's':\n            pos[0] = f.x2;\n            break;\n          }\n        } else {\n          switch (mode) {\n          case 'e':\n            pos[1] = f.y + 1;\n            break;\n          case 'w':\n            pos[1] = f.y + 1;\n            break;\n          case 'n':\n            pos[0] = f.x + 1;\n            break;\n          case 's':\n            pos[0] = f.x + 1;\n            break;\n          }\n        }\n        Coords.setCurrent(pos);\n        Selection.update();\n      };\n    }\n    //}}}\n    function createMover(pos) //{{{\n    {\n      var lloc = pos;\n      KeyManager.watchKeys();\n\n      return function (pos) {\n        Coords.moveOffset([pos[0] - lloc[0], pos[1] - lloc[1]]);\n        lloc = pos;\n\n        Selection.update();\n      };\n    }\n    //}}}\n    function oppLockCorner(ord) //{{{\n    {\n      switch (ord) {\n      case 'n':\n        return 'sw';\n      case 's':\n        return 'nw';\n      case 'e':\n        return 'nw';\n      case 'w':\n        return 'ne';\n      case 'ne':\n        return 'sw';\n      case 'nw':\n        return 'se';\n      case 'se':\n        return 'nw';\n      case 'sw':\n        return 'ne';\n      }\n    }\n    //}}}\n    function createDragger(ord) //{{{\n    {\n      return function (e) {\n        if (options.disabled) {\n          return false;\n        }\n        if ((ord === 'move') && !options.allowMove) {\n          return false;\n        }\n        \n        // Fix position of crop area when dragged the very first time.\n        // Necessary when crop image is in a hidden element when page is loaded.\n        docOffset = getPos($img);\n\n        btndown = true;\n        startDragMode(ord, mouseAbs(e));\n        e.stopPropagation();\n        e.preventDefault();\n        return false;\n      };\n    }\n    //}}}\n    function presize($obj, w, h) //{{{\n    {\n      var nw = $obj.width(),\n          nh = $obj.height();\n      if ((nw > w) && w > 0) {\n        nw = w;\n        nh = (w / $obj.width()) * $obj.height();\n      }\n      if ((nh > h) && h > 0) {\n        nh = h;\n        nw = (h / $obj.height()) * $obj.width();\n      }\n      xscale = $obj.width() / nw;\n      yscale = $obj.height() / nh;\n      $obj.width(nw).height(nh);\n    }\n    //}}}\n    function unscale(c) //{{{\n    {\n      return {\n        x: c.x * xscale,\n        y: c.y * yscale,\n        x2: c.x2 * xscale,\n        y2: c.y2 * yscale,\n        w: c.w * xscale,\n        h: c.h * yscale\n      };\n    }\n    //}}}\n    function doneSelect(pos) //{{{\n    {\n      var c = Coords.getFixed();\n      if ((c.w > options.minSelect[0]) && (c.h > options.minSelect[1])) {\n        Selection.enableHandles();\n        Selection.done();\n      } else {\n        Selection.release();\n      }\n      Tracker.setCursor(options.allowSelect ? 'crosshair' : 'default');\n    }\n    //}}}\n    function newSelection(e) //{{{\n    {\n      if (options.disabled) {\n        return false;\n      }\n      if (!options.allowSelect) {\n        return false;\n      }\n      btndown = true;\n      docOffset = getPos($img);\n      Selection.disableHandles();\n      Tracker.setCursor('crosshair');\n      var pos = mouseAbs(e);\n      Coords.setPressed(pos);\n      Selection.update();\n      Tracker.activateHandlers(selectDrag, doneSelect, e.type.substring(0,5)==='touch');\n      KeyManager.watchKeys();\n\n      e.stopPropagation();\n      e.preventDefault();\n      return false;\n    }\n    //}}}\n    function selectDrag(pos) //{{{\n    {\n      Coords.setCurrent(pos);\n      Selection.update();\n    }\n    //}}}\n    function newTracker() //{{{\n    {\n      var trk = $('<div></div>').addClass(cssClass('tracker'));\n      if (is_msie) {\n        trk.css({\n          opacity: 0,\n          backgroundColor: 'white'\n        });\n      }\n      return trk;\n    }\n    //}}}\n\n    // }}}\n    // Initialization {{{\n    // Sanitize some options {{{\n    if (typeof(obj) !== 'object') {\n      obj = $(obj)[0];\n    }\n    if (typeof(opt) !== 'object') {\n      opt = {};\n    }\n    // }}}\n    setOptions(opt);\n    // Initialize some jQuery objects {{{\n    // The values are SET on the image(s) for the interface\n    // If the original image has any of these set, they will be reset\n    // However, if you destroy() the Jcrop instance the original image's\n    // character in the DOM will be as you left it.\n    var img_css = {\n      border: 'none',\n      visibility: 'visible',\n      margin: 0,\n      padding: 0,\n      position: 'absolute',\n      top: 0,\n      left: 0\n    };\n\n    var $origimg = $(obj),\n      img_mode = true;\n\n    if (obj.tagName == 'IMG') {\n      // Fix size of crop image.\n      // Necessary when crop image is within a hidden element when page is loaded.\n      if ($origimg[0].width != 0 && $origimg[0].height != 0) {\n        // Obtain dimensions from contained img element.\n        $origimg.width($origimg[0].width);\n        $origimg.height($origimg[0].height);\n      } else {\n        // Obtain dimensions from temporary image in case the original is not loaded yet (e.g. IE 7.0). \n        var tempImage = new Image();\n        tempImage.src = $origimg[0].src;\n        $origimg.width(tempImage.width);\n        $origimg.height(tempImage.height);\n      } \n\n      var $img = $origimg.clone().removeAttr('id').css(img_css).show();\n\n      $img.width($origimg.width());\n      $img.height($origimg.height());\n      $origimg.after($img).hide();\n\n    } else {\n      $img = $origimg.css(img_css).show();\n      img_mode = false;\n      if (options.shade === null) { options.shade = true; }\n    }\n\n    presize($img, options.boxWidth, options.boxHeight);\n\n    var boundx = $img.width(),\n        boundy = $img.height(),\n        \n        \n        $div = $('<div />').width(boundx).height(boundy).addClass(cssClass('holder')).css({\n        position: 'relative',\n        backgroundColor: options.bgColor\n      }).insertAfter($origimg).append($img);\n\n    if (options.addClass) {\n      $div.addClass(options.addClass);\n    }\n\n    var $img2 = $('<div />'),\n\n        $img_holder = $('<div />') \n        .width('100%').height('100%').css({\n          zIndex: 310,\n          position: 'absolute',\n          overflow: 'hidden'\n        }),\n\n        $hdl_holder = $('<div />') \n        .width('100%').height('100%').css('zIndex', 320), \n\n        $sel = $('<div />') \n        .css({\n          position: 'absolute',\n          zIndex: 600\n        }).dblclick(function(){\n          var c = Coords.getFixed();\n          options.onDblClick.call(api,c);\n        }).insertBefore($img).append($img_holder, $hdl_holder); \n\n    if (img_mode) {\n\n      $img2 = $('<img />')\n          .attr('src', $img.attr('src')).css(img_css).width(boundx).height(boundy),\n\n      $img_holder.append($img2);\n\n    }\n\n    if (ie6mode) {\n      $sel.css({\n        overflowY: 'hidden'\n      });\n    }\n\n    var bound = options.boundary;\n    var $trk = newTracker().width(boundx + (bound * 2)).height(boundy + (bound * 2)).css({\n      position: 'absolute',\n      top: px(-bound),\n      left: px(-bound),\n      zIndex: 290\n    }).mousedown(newSelection);\n\n    /* }}} */\n    // Set more variables {{{\n    var bgcolor = options.bgColor,\n        bgopacity = options.bgOpacity,\n        xlimit, ylimit, xmin, ymin, xscale, yscale, enabled = true,\n        btndown, animating, shift_down;\n\n    docOffset = getPos($img);\n    // }}}\n    // }}}\n    // Internal Modules {{{\n    // Touch Module {{{ \n    var Touch = (function () {\n      // Touch support detection function adapted (under MIT License)\n      // from code by Jeffrey Sambells - http://github.com/iamamused/\n      function hasTouchSupport() {\n        var support = {}, events = ['touchstart', 'touchmove', 'touchend'],\n            el = document.createElement('div'), i;\n\n        try {\n          for(i=0; i<events.length; i++) {\n            var eventName = events[i];\n            eventName = 'on' + eventName;\n            var isSupported = (eventName in el);\n            if (!isSupported) {\n              el.setAttribute(eventName, 'return;');\n              isSupported = typeof el[eventName] == 'function';\n            }\n            support[events[i]] = isSupported;\n          }\n          return support.touchstart && support.touchend && support.touchmove;\n        }\n        catch(err) {\n          return false;\n        }\n      }\n\n      function detectSupport() {\n        if ((options.touchSupport === true) || (options.touchSupport === false)) return options.touchSupport;\n          else return hasTouchSupport();\n      }\n      return {\n        createDragger: function (ord) {\n          return function (e) {\n            if (options.disabled) {\n              return false;\n            }\n            if ((ord === 'move') && !options.allowMove) {\n              return false;\n            }\n            docOffset = getPos($img);\n            btndown = true;\n            startDragMode(ord, mouseAbs(Touch.cfilter(e)), true);\n            e.stopPropagation();\n            e.preventDefault();\n            return false;\n          };\n        },\n        newSelection: function (e) {\n          return newSelection(Touch.cfilter(e));\n        },\n        cfilter: function (e){\n          e.pageX = e.originalEvent.changedTouches[0].pageX;\n          e.pageY = e.originalEvent.changedTouches[0].pageY;\n          return e;\n        },\n        isSupported: hasTouchSupport,\n        support: detectSupport()\n      };\n    }());\n    // }}}\n    // Coords Module {{{\n    var Coords = (function () {\n      var x1 = 0,\n          y1 = 0,\n          x2 = 0,\n          y2 = 0,\n          ox, oy;\n\n      function setPressed(pos) //{{{\n      {\n        pos = rebound(pos);\n        x2 = x1 = pos[0];\n        y2 = y1 = pos[1];\n      }\n      //}}}\n      function setCurrent(pos) //{{{\n      {\n        pos = rebound(pos);\n        ox = pos[0] - x2;\n        oy = pos[1] - y2;\n        x2 = pos[0];\n        y2 = pos[1];\n      }\n      //}}}\n      function getOffset() //{{{\n      {\n        return [ox, oy];\n      }\n      //}}}\n      function moveOffset(offset) //{{{\n      {\n        var ox = offset[0],\n            oy = offset[1];\n\n        if (0 > x1 + ox) {\n          ox -= ox + x1;\n        }\n        if (0 > y1 + oy) {\n          oy -= oy + y1;\n        }\n\n        if (boundy < y2 + oy) {\n          oy += boundy - (y2 + oy);\n        }\n        if (boundx < x2 + ox) {\n          ox += boundx - (x2 + ox);\n        }\n\n        x1 += ox;\n        x2 += ox;\n        y1 += oy;\n        y2 += oy;\n      }\n      //}}}\n      function getCorner(ord) //{{{\n      {\n        var c = getFixed();\n        switch (ord) {\n        case 'ne':\n          return [c.x2, c.y];\n        case 'nw':\n          return [c.x, c.y];\n        case 'se':\n          return [c.x2, c.y2];\n        case 'sw':\n          return [c.x, c.y2];\n        }\n      }\n      //}}}\n      function getFixed() //{{{\n      {\n        if (!options.aspectRatio) {\n          return getRect();\n        }\n        // This function could use some optimization I think...\n        var aspect = options.aspectRatio,\n            min_x = options.minSize[0] / xscale,\n            \n            \n            //min_y = options.minSize[1]/yscale,\n            max_x = options.maxSize[0] / xscale,\n            max_y = options.maxSize[1] / yscale,\n            rw = x2 - x1,\n            rh = y2 - y1,\n            rwa = Math.abs(rw),\n            rha = Math.abs(rh),\n            real_ratio = rwa / rha,\n            xx, yy, w, h;\n\n        if (max_x === 0) {\n          max_x = boundx * 10;\n        }\n        if (max_y === 0) {\n          max_y = boundy * 10;\n        }\n        if (real_ratio < aspect) {\n          yy = y2;\n          w = rha * aspect;\n          xx = rw < 0 ? x1 - w : w + x1;\n\n          if (xx < 0) {\n            xx = 0;\n            h = Math.abs((xx - x1) / aspect);\n            yy = rh < 0 ? y1 - h : h + y1;\n          } else if (xx > boundx) {\n            xx = boundx;\n            h = Math.abs((xx - x1) / aspect);\n            yy = rh < 0 ? y1 - h : h + y1;\n          }\n        } else {\n          xx = x2;\n          h = rwa / aspect;\n          yy = rh < 0 ? y1 - h : y1 + h;\n          if (yy < 0) {\n            yy = 0;\n            w = Math.abs((yy - y1) * aspect);\n            xx = rw < 0 ? x1 - w : w + x1;\n          } else if (yy > boundy) {\n            yy = boundy;\n            w = Math.abs(yy - y1) * aspect;\n            xx = rw < 0 ? x1 - w : w + x1;\n          }\n        }\n\n        // Magic %-)\n        if (xx > x1) { // right side\n          if (xx - x1 < min_x) {\n            xx = x1 + min_x;\n          } else if (xx - x1 > max_x) {\n            xx = x1 + max_x;\n          }\n          if (yy > y1) {\n            yy = y1 + (xx - x1) / aspect;\n          } else {\n            yy = y1 - (xx - x1) / aspect;\n          }\n        } else if (xx < x1) { // left side\n          if (x1 - xx < min_x) {\n            xx = x1 - min_x;\n          } else if (x1 - xx > max_x) {\n            xx = x1 - max_x;\n          }\n          if (yy > y1) {\n            yy = y1 + (x1 - xx) / aspect;\n          } else {\n            yy = y1 - (x1 - xx) / aspect;\n          }\n        }\n\n        if (xx < 0) {\n          x1 -= xx;\n          xx = 0;\n        } else if (xx > boundx) {\n          x1 -= xx - boundx;\n          xx = boundx;\n        }\n\n        if (yy < 0) {\n          y1 -= yy;\n          yy = 0;\n        } else if (yy > boundy) {\n          y1 -= yy - boundy;\n          yy = boundy;\n        }\n\n        return makeObj(flipCoords(x1, y1, xx, yy));\n      }\n      //}}}\n      function rebound(p) //{{{\n      {\n        if (p[0] < 0) p[0] = 0;\n        if (p[1] < 0) p[1] = 0;\n\n        if (p[0] > boundx) p[0] = boundx;\n        if (p[1] > boundy) p[1] = boundy;\n\n        return [Math.round(p[0]), Math.round(p[1])];\n      }\n      //}}}\n      function flipCoords(x1, y1, x2, y2) //{{{\n      {\n        var xa = x1,\n            xb = x2,\n            ya = y1,\n            yb = y2;\n        if (x2 < x1) {\n          xa = x2;\n          xb = x1;\n        }\n        if (y2 < y1) {\n          ya = y2;\n          yb = y1;\n        }\n        return [xa, ya, xb, yb];\n      }\n      //}}}\n      function getRect() //{{{\n      {\n        var xsize = x2 - x1,\n            ysize = y2 - y1,\n            delta;\n\n        if (xlimit && (Math.abs(xsize) > xlimit)) {\n          x2 = (xsize > 0) ? (x1 + xlimit) : (x1 - xlimit);\n        }\n        if (ylimit && (Math.abs(ysize) > ylimit)) {\n          y2 = (ysize > 0) ? (y1 + ylimit) : (y1 - ylimit);\n        }\n\n        if (ymin / yscale && (Math.abs(ysize) < ymin / yscale)) {\n          y2 = (ysize > 0) ? (y1 + ymin / yscale) : (y1 - ymin / yscale);\n        }\n        if (xmin / xscale && (Math.abs(xsize) < xmin / xscale)) {\n          x2 = (xsize > 0) ? (x1 + xmin / xscale) : (x1 - xmin / xscale);\n        }\n\n        if (x1 < 0) {\n          x2 -= x1;\n          x1 -= x1;\n        }\n        if (y1 < 0) {\n          y2 -= y1;\n          y1 -= y1;\n        }\n        if (x2 < 0) {\n          x1 -= x2;\n          x2 -= x2;\n        }\n        if (y2 < 0) {\n          y1 -= y2;\n          y2 -= y2;\n        }\n        if (x2 > boundx) {\n          delta = x2 - boundx;\n          x1 -= delta;\n          x2 -= delta;\n        }\n        if (y2 > boundy) {\n          delta = y2 - boundy;\n          y1 -= delta;\n          y2 -= delta;\n        }\n        if (x1 > boundx) {\n          delta = x1 - boundy;\n          y2 -= delta;\n          y1 -= delta;\n        }\n        if (y1 > boundy) {\n          delta = y1 - boundy;\n          y2 -= delta;\n          y1 -= delta;\n        }\n\n        return makeObj(flipCoords(x1, y1, x2, y2));\n      }\n      //}}}\n      function makeObj(a) //{{{\n      {\n        return {\n          x: a[0],\n          y: a[1],\n          x2: a[2],\n          y2: a[3],\n          w: a[2] - a[0],\n          h: a[3] - a[1]\n        };\n      }\n      //}}}\n\n      return {\n        flipCoords: flipCoords,\n        setPressed: setPressed,\n        setCurrent: setCurrent,\n        getOffset: getOffset,\n        moveOffset: moveOffset,\n        getCorner: getCorner,\n        getFixed: getFixed\n      };\n    }());\n\n    //}}}\n    // Shade Module {{{\n    var Shade = (function() {\n      var enabled = false,\n          holder = $('<div />').css({\n            position: 'absolute',\n            zIndex: 240,\n            opacity: 0\n          }),\n          shades = {\n            top: createShade(),\n            left: createShade().height(boundy),\n            right: createShade().height(boundy),\n            bottom: createShade()\n          };\n\n      function resizeShades(w,h) {\n        shades.left.css({ height: px(h) });\n        shades.right.css({ height: px(h) });\n      }\n      function updateAuto()\n      {\n        return updateShade(Coords.getFixed());\n      }\n      function updateShade(c)\n      {\n        shades.top.css({\n          left: px(c.x),\n          width: px(c.w),\n          height: px(c.y)\n        });\n        shades.bottom.css({\n          top: px(c.y2),\n          left: px(c.x),\n          width: px(c.w),\n          height: px(boundy-c.y2)\n        });\n        shades.right.css({\n          left: px(c.x2),\n          width: px(boundx-c.x2)\n        });\n        shades.left.css({\n          width: px(c.x)\n        });\n      }\n      function createShade() {\n        return $('<div />').css({\n          position: 'absolute',\n          backgroundColor: options.shadeColor||options.bgColor\n        }).appendTo(holder);\n      }\n      function enableShade() {\n        if (!enabled) {\n          enabled = true;\n          holder.insertBefore($img);\n          updateAuto();\n          Selection.setBgOpacity(1,0,1);\n          $img2.hide();\n\n          setBgColor(options.shadeColor||options.bgColor,1);\n          if (Selection.isAwake())\n          {\n            setOpacity(options.bgOpacity,1);\n          }\n            else setOpacity(1,1);\n        }\n      }\n      function setBgColor(color,now) {\n        colorChangeMacro(getShades(),color,now);\n      }\n      function disableShade() {\n        if (enabled) {\n          holder.remove();\n          $img2.show();\n          enabled = false;\n          if (Selection.isAwake()) {\n            Selection.setBgOpacity(options.bgOpacity,1,1);\n          } else {\n            Selection.setBgOpacity(1,1,1);\n            Selection.disableHandles();\n          }\n          colorChangeMacro($div,0,1);\n        }\n      }\n      function setOpacity(opacity,now) {\n        if (enabled) {\n          if (options.bgFade && !now) {\n            holder.animate({\n              opacity: 1-opacity\n            },{\n              queue: false,\n              duration: options.fadeTime\n            });\n          }\n          else holder.css({opacity:1-opacity});\n        }\n      }\n      function refreshAll() {\n        options.shade ? enableShade() : disableShade();\n        if (Selection.isAwake()) setOpacity(options.bgOpacity);\n      }\n      function getShades() {\n        return holder.children();\n      }\n\n      return {\n        update: updateAuto,\n        updateRaw: updateShade,\n        getShades: getShades,\n        setBgColor: setBgColor,\n        enable: enableShade,\n        disable: disableShade,\n        resize: resizeShades,\n        refresh: refreshAll,\n        opacity: setOpacity\n      };\n    }());\n    // }}}\n    // Selection Module {{{\n    var Selection = (function () {\n      var awake,\n          hdep = 370,\n          borders = {},\n          handle = {},\n          dragbar = {},\n          seehandles = false;\n\n      // Private Methods\n      function insertBorder(type) //{{{\n      {\n        var jq = $('<div />').css({\n          position: 'absolute',\n          opacity: options.borderOpacity\n        }).addClass(cssClass(type));\n        $img_holder.append(jq);\n        return jq;\n      }\n      //}}}\n      function dragDiv(ord, zi) //{{{\n      {\n        var jq = $('<div />').mousedown(createDragger(ord)).css({\n          cursor: ord + '-resize',\n          position: 'absolute',\n          zIndex: zi\n        }).addClass('ord-'+ord);\n\n        if (Touch.support) {\n          jq.bind('touchstart.jcrop', Touch.createDragger(ord));\n        }\n\n        $hdl_holder.append(jq);\n        return jq;\n      }\n      //}}}\n      function insertHandle(ord) //{{{\n      {\n        var hs = options.handleSize,\n\n          div = dragDiv(ord, hdep++).css({\n            opacity: options.handleOpacity\n          }).addClass(cssClass('handle'));\n\n        if (hs) { div.width(hs).height(hs); }\n\n        return div;\n      }\n      //}}}\n      function insertDragbar(ord) //{{{\n      {\n        return dragDiv(ord, hdep++).addClass('jcrop-dragbar');\n      }\n      //}}}\n      function createDragbars(li) //{{{\n      {\n        var i;\n        for (i = 0; i < li.length; i++) {\n          dragbar[li[i]] = insertDragbar(li[i]);\n        }\n      }\n      //}}}\n      function createBorders(li) //{{{\n      {\n        var cl,i;\n        for (i = 0; i < li.length; i++) {\n          switch(li[i]){\n            case'n': cl='hline'; break;\n            case's': cl='hline bottom'; break;\n            case'e': cl='vline right'; break;\n            case'w': cl='vline'; break;\n          }\n          borders[li[i]] = insertBorder(cl);\n        }\n      }\n      //}}}\n      function createHandles(li) //{{{\n      {\n        var i;\n        for (i = 0; i < li.length; i++) {\n          handle[li[i]] = insertHandle(li[i]);\n        }\n      }\n      //}}}\n      function moveto(x, y) //{{{\n      {\n        if (!options.shade) {\n          $img2.css({\n            top: px(-y),\n            left: px(-x)\n          });\n        }\n        $sel.css({\n          top: px(y),\n          left: px(x)\n        });\n      }\n      //}}}\n      function resize(w, h) //{{{\n      {\n        $sel.width(Math.round(w)).height(Math.round(h));\n      }\n      //}}}\n      function refresh() //{{{\n      {\n        var c = Coords.getFixed();\n\n        Coords.setPressed([c.x, c.y]);\n        Coords.setCurrent([c.x2, c.y2]);\n\n        updateVisible();\n      }\n      //}}}\n\n      // Internal Methods\n      function updateVisible(select) //{{{\n      {\n        if (awake) {\n          return update(select);\n        }\n      }\n      //}}}\n      function update(select) //{{{\n      {\n        var c = Coords.getFixed();\n\n        resize(c.w, c.h);\n        moveto(c.x, c.y);\n        if (options.shade) Shade.updateRaw(c);\n\n        awake || show();\n\n        if (select) {\n          options.onSelect.call(api, unscale(c));\n        } else {\n          options.onChange.call(api, unscale(c));\n        }\n      }\n      //}}}\n      function setBgOpacity(opacity,force,now) //{{{\n      {\n        if (!awake && !force) return;\n        if (options.bgFade && !now) {\n          $img.animate({\n            opacity: opacity\n          },{\n            queue: false,\n            duration: options.fadeTime\n          });\n        } else {\n          $img.css('opacity', opacity);\n        }\n      }\n      //}}}\n      function show() //{{{\n      {\n        $sel.show();\n\n        if (options.shade) Shade.opacity(bgopacity);\n          else setBgOpacity(bgopacity,true);\n\n        awake = true;\n      }\n      //}}}\n      function release() //{{{\n      {\n        disableHandles();\n        $sel.hide();\n\n        if (options.shade) Shade.opacity(1);\n          else setBgOpacity(1);\n\n        awake = false;\n        options.onRelease.call(api);\n      }\n      //}}}\n      function showHandles() //{{{\n      {\n        if (seehandles) {\n          $hdl_holder.show();\n        }\n      }\n      //}}}\n      function enableHandles() //{{{\n      {\n        seehandles = true;\n        if (options.allowResize) {\n          $hdl_holder.show();\n          return true;\n        }\n      }\n      //}}}\n      function disableHandles() //{{{\n      {\n        seehandles = false;\n        $hdl_holder.hide();\n      } \n      //}}}\n      function animMode(v) //{{{\n      {\n        if (v) {\n          animating = true;\n          disableHandles();\n        } else {\n          animating = false;\n          enableHandles();\n        }\n      } \n      //}}}\n      function done() //{{{\n      {\n        animMode(false);\n        refresh();\n      } \n      //}}}\n      // Insert draggable elements {{{\n      // Insert border divs for outline\n\n      if (options.dragEdges && $.isArray(options.createDragbars))\n        createDragbars(options.createDragbars);\n\n      if ($.isArray(options.createHandles))\n        createHandles(options.createHandles);\n\n      if (options.drawBorders && $.isArray(options.createBorders))\n        createBorders(options.createBorders);\n\n      //}}}\n\n      // This is a hack for iOS5 to support drag/move touch functionality\n      $(document).bind('touchstart.jcrop-ios',function(e) {\n        if ($(e.currentTarget).hasClass('jcrop-tracker')) e.stopPropagation();\n      });\n\n      var $track = newTracker().mousedown(createDragger('move')).css({\n        cursor: 'move',\n        position: 'absolute',\n        zIndex: 360\n      });\n\n      if (Touch.support) {\n        $track.bind('touchstart.jcrop', Touch.createDragger('move'));\n      }\n\n      $img_holder.append($track);\n      disableHandles();\n\n      return {\n        updateVisible: updateVisible,\n        update: update,\n        release: release,\n        refresh: refresh,\n        isAwake: function () {\n          return awake;\n        },\n        setCursor: function (cursor) {\n          $track.css('cursor', cursor);\n        },\n        enableHandles: enableHandles,\n        enableOnly: function () {\n          seehandles = true;\n        },\n        showHandles: showHandles,\n        disableHandles: disableHandles,\n        animMode: animMode,\n        setBgOpacity: setBgOpacity,\n        done: done\n      };\n    }());\n    \n    //}}}\n    // Tracker Module {{{\n    var Tracker = (function () {\n      var onMove = function () {},\n          onDone = function () {},\n          trackDoc = options.trackDocument;\n\n      function toFront(touch) //{{{\n      {\n        $trk.css({\n          zIndex: 450\n        });\n\n        if (touch)\n          $(document)\n            .bind('touchmove.jcrop', trackTouchMove)\n            .bind('touchend.jcrop', trackTouchEnd);\n\n        else if (trackDoc)\n          $(document)\n            .bind('mousemove.jcrop',trackMove)\n            .bind('mouseup.jcrop',trackUp);\n      } \n      //}}}\n      function toBack() //{{{\n      {\n        $trk.css({\n          zIndex: 290\n        });\n        $(document).unbind('.jcrop');\n      } \n      //}}}\n      function trackMove(e) //{{{\n      {\n        onMove(mouseAbs(e));\n        return false;\n      } \n      //}}}\n      function trackUp(e) //{{{\n      {\n        e.preventDefault();\n        e.stopPropagation();\n\n        if (btndown) {\n          btndown = false;\n\n          onDone(mouseAbs(e));\n\n          if (Selection.isAwake()) {\n            options.onSelect.call(api, unscale(Coords.getFixed()));\n          }\n\n          toBack();\n          onMove = function () {};\n          onDone = function () {};\n        }\n\n        return false;\n      }\n      //}}}\n      function activateHandlers(move, done, touch) //{{{\n      {\n        btndown = true;\n        onMove = move;\n        onDone = done;\n        toFront(touch);\n        return false;\n      }\n      //}}}\n      function trackTouchMove(e) //{{{\n      {\n        onMove(mouseAbs(Touch.cfilter(e)));\n        return false;\n      }\n      //}}}\n      function trackTouchEnd(e) //{{{\n      {\n        return trackUp(Touch.cfilter(e));\n      }\n      //}}}\n      function setCursor(t) //{{{\n      {\n        $trk.css('cursor', t);\n      }\n      //}}}\n\n      if (!trackDoc) {\n        $trk.mousemove(trackMove).mouseup(trackUp).mouseout(trackUp);\n      }\n\n      $img.before($trk);\n      return {\n        activateHandlers: activateHandlers,\n        setCursor: setCursor\n      };\n    }());\n    //}}}\n    // KeyManager Module {{{\n    var KeyManager = (function () {\n      var $keymgr = $('<input type=\"radio\" />').css({\n        position: 'fixed',\n        left: '-120px',\n        width: '12px'\n      }).addClass('jcrop-keymgr'),\n\n        $keywrap = $('<div />').css({\n          position: 'absolute',\n          overflow: 'hidden'\n        }).append($keymgr);\n\n      function watchKeys() //{{{\n      {\n        if (options.keySupport) {\n          $keymgr.show();\n          $keymgr.focus();\n        }\n      }\n      //}}}\n      function onBlur(e) //{{{\n      {\n        $keymgr.hide();\n      }\n      //}}}\n      function doNudge(e, x, y) //{{{\n      {\n        if (options.allowMove) {\n          Coords.moveOffset([x, y]);\n          Selection.updateVisible(true);\n        }\n        e.preventDefault();\n        e.stopPropagation();\n      }\n      //}}}\n      function parseKey(e) //{{{\n      {\n        if (e.ctrlKey || e.metaKey) {\n          return true;\n        }\n        shift_down = e.shiftKey ? true : false;\n        var nudge = shift_down ? 10 : 1;\n\n        switch (e.keyCode) {\n        case 37:\n          doNudge(e, -nudge, 0);\n          break;\n        case 39:\n          doNudge(e, nudge, 0);\n          break;\n        case 38:\n          doNudge(e, 0, -nudge);\n          break;\n        case 40:\n          doNudge(e, 0, nudge);\n          break;\n        case 27:\n          if (options.allowSelect) Selection.release();\n          break;\n        case 9:\n          return true;\n        }\n\n        return false;\n      }\n      //}}}\n\n      if (options.keySupport) {\n        $keymgr.keydown(parseKey).blur(onBlur);\n        if (ie6mode || !options.fixedSupport) {\n          $keymgr.css({\n            position: 'absolute',\n            left: '-20px'\n          });\n          $keywrap.append($keymgr).insertBefore($img);\n        } else {\n          $keymgr.insertBefore($img);\n        }\n      }\n\n\n      return {\n        watchKeys: watchKeys\n      };\n    }());\n    //}}}\n    // }}}\n    // API methods {{{\n    function setClass(cname) //{{{\n    {\n      $div.removeClass().addClass(cssClass('holder')).addClass(cname);\n    }\n    //}}}\n    function animateTo(a, callback) //{{{\n    {\n      var x1 = a[0] / xscale,\n          y1 = a[1] / yscale,\n          x2 = a[2] / xscale,\n          y2 = a[3] / yscale;\n\n      if (animating) {\n        return;\n      }\n\n      var animto = Coords.flipCoords(x1, y1, x2, y2),\n          c = Coords.getFixed(),\n          initcr = [c.x, c.y, c.x2, c.y2],\n          animat = initcr,\n          interv = options.animationDelay,\n          ix1 = animto[0] - initcr[0],\n          iy1 = animto[1] - initcr[1],\n          ix2 = animto[2] - initcr[2],\n          iy2 = animto[3] - initcr[3],\n          pcent = 0,\n          velocity = options.swingSpeed;\n\n      x1 = animat[0];\n      y1 = animat[1];\n      x2 = animat[2];\n      y2 = animat[3];\n\n      Selection.animMode(true);\n      var anim_timer;\n\n      function queueAnimator() {\n        window.setTimeout(animator, interv);\n      }\n      var animator = (function () {\n        return function () {\n          pcent += (100 - pcent) / velocity;\n\n          animat[0] = Math.round(x1 + ((pcent / 100) * ix1));\n          animat[1] = Math.round(y1 + ((pcent / 100) * iy1));\n          animat[2] = Math.round(x2 + ((pcent / 100) * ix2));\n          animat[3] = Math.round(y2 + ((pcent / 100) * iy2));\n\n          if (pcent >= 99.8) {\n            pcent = 100;\n          }\n          if (pcent < 100) {\n            setSelectRaw(animat);\n            queueAnimator();\n          } else {\n            Selection.done();\n            Selection.animMode(false);\n            if (typeof(callback) === 'function') {\n              callback.call(api);\n            }\n          }\n        };\n      }());\n      queueAnimator();\n    }\n    //}}}\n    function setSelect(rect) //{{{\n    {\n      setSelectRaw([rect[0] / xscale, rect[1] / yscale, rect[2] / xscale, rect[3] / yscale]);\n      options.onSelect.call(api, unscale(Coords.getFixed()));\n      Selection.enableHandles();\n    }\n    //}}}\n    function setSelectRaw(l) //{{{\n    {\n      Coords.setPressed([l[0], l[1]]);\n      Coords.setCurrent([l[2], l[3]]);\n      Selection.update();\n    }\n    //}}}\n    function tellSelect() //{{{\n    {\n      return unscale(Coords.getFixed());\n    }\n    //}}}\n    function tellScaled() //{{{\n    {\n      return Coords.getFixed();\n    }\n    //}}}\n    function setOptionsNew(opt) //{{{\n    {\n      setOptions(opt);\n      interfaceUpdate();\n    }\n    //}}}\n    function disableCrop() //{{{\n    {\n      options.disabled = true;\n      Selection.disableHandles();\n      Selection.setCursor('default');\n      Tracker.setCursor('default');\n    }\n    //}}}\n    function enableCrop() //{{{\n    {\n      options.disabled = false;\n      interfaceUpdate();\n    }\n    //}}}\n    function cancelCrop() //{{{\n    {\n      Selection.done();\n      Tracker.activateHandlers(null, null);\n    }\n    //}}}\n    function destroy() //{{{\n    {\n      $div.remove();\n      $origimg.show();\n      $origimg.css('visibility','visible');\n      $(obj).removeData('Jcrop');\n    }\n    //}}}\n    function setImage(src, callback) //{{{\n    {\n      Selection.release();\n      disableCrop();\n      var img = new Image();\n      img.onload = function () {\n        var iw = img.width;\n        var ih = img.height;\n        var bw = options.boxWidth;\n        var bh = options.boxHeight;\n        $img.width(iw).height(ih);\n        $img.attr('src', src);\n        $img2.attr('src', src);\n        presize($img, bw, bh);\n        boundx = $img.width();\n        boundy = $img.height();\n        $img2.width(boundx).height(boundy);\n        $trk.width(boundx + (bound * 2)).height(boundy + (bound * 2));\n        $div.width(boundx).height(boundy);\n        Shade.resize(boundx,boundy);\n        enableCrop();\n\n        if (typeof(callback) === 'function') {\n          callback.call(api);\n        }\n      };\n      img.src = src;\n    }\n    //}}}\n    function colorChangeMacro($obj,color,now) {\n      var mycolor = color || options.bgColor;\n      if (options.bgFade && supportsColorFade() && options.fadeTime && !now) {\n        $obj.animate({\n          backgroundColor: mycolor\n        }, {\n          queue: false,\n          duration: options.fadeTime\n        });\n      } else {\n        $obj.css('backgroundColor', mycolor);\n      }\n    }\n    function interfaceUpdate(alt) //{{{\n    // This method tweaks the interface based on options object.\n    // Called when options are changed and at end of initialization.\n    {\n      if (options.allowResize) {\n        if (alt) {\n          Selection.enableOnly();\n        } else {\n          Selection.enableHandles();\n        }\n      } else {\n        Selection.disableHandles();\n      }\n\n      Tracker.setCursor(options.allowSelect ? 'crosshair' : 'default');\n      Selection.setCursor(options.allowMove ? 'move' : 'default');\n\n      if (options.hasOwnProperty('trueSize')) {\n        xscale = options.trueSize[0] / boundx;\n        yscale = options.trueSize[1] / boundy;\n      }\n\n      if (options.hasOwnProperty('setSelect')) {\n        setSelect(options.setSelect);\n        Selection.done();\n        delete(options.setSelect);\n      }\n\n      Shade.refresh();\n\n      if (options.bgColor != bgcolor) {\n        colorChangeMacro(\n          options.shade? Shade.getShades(): $div,\n          options.shade?\n            (options.shadeColor || options.bgColor):\n            options.bgColor\n        );\n        bgcolor = options.bgColor;\n      }\n\n      if (bgopacity != options.bgOpacity) {\n        bgopacity = options.bgOpacity;\n        if (options.shade) Shade.refresh();\n          else Selection.setBgOpacity(bgopacity);\n      }\n\n      xlimit = options.maxSize[0] || 0;\n      ylimit = options.maxSize[1] || 0;\n      xmin = options.minSize[0] || 0;\n      ymin = options.minSize[1] || 0;\n\n      if (options.hasOwnProperty('outerImage')) {\n        $img.attr('src', options.outerImage);\n        delete(options.outerImage);\n      }\n\n      Selection.refresh();\n    }\n    //}}}\n    //}}}\n\n    if (Touch.support) $trk.bind('touchstart.jcrop', Touch.newSelection);\n\n    $hdl_holder.hide();\n    interfaceUpdate(true);\n\n    var api = {\n      setImage: setImage,\n      animateTo: animateTo,\n      setSelect: setSelect,\n      setOptions: setOptionsNew,\n      tellSelect: tellSelect,\n      tellScaled: tellScaled,\n      setClass: setClass,\n\n      disable: disableCrop,\n      enable: enableCrop,\n      cancel: cancelCrop,\n      release: Selection.release,\n      destroy: destroy,\n\n      focus: KeyManager.watchKeys,\n\n      getBounds: function () {\n        return [boundx * xscale, boundy * yscale];\n      },\n      getWidgetSize: function () {\n        return [boundx, boundy];\n      },\n      getScaleFactor: function () {\n        return [xscale, yscale];\n      },\n      getOptions: function() {\n        // careful: internal values are returned\n        return options;\n      },\n\n      ui: {\n        holder: $div,\n        selection: $sel\n      }\n    };\n\n    if (is_msie) $div.bind('selectstart', function () { return false; });\n\n    $origimg.data('Jcrop', api);\n    return api;\n  };\n  $.fn.Jcrop = function (options, callback) //{{{\n  {\n    var api;\n    // Iterate over each object, attach Jcrop\n    this.each(function () {\n      // If we've already attached to this object\n      if ($(this).data('Jcrop')) {\n        // The API can be requested this way (undocumented)\n        if (options === 'api') return $(this).data('Jcrop');\n        // Otherwise, we just reset the options...\n        else $(this).data('Jcrop').setOptions(options);\n      }\n      // If we haven't been attached, preload and attach\n      else {\n        if (this.tagName == 'IMG')\n          $.Jcrop.Loader(this,function(){\n            $(this).css({display:'block',visibility:'hidden'});\n            api = $.Jcrop(this, options);\n            if ($.isFunction(callback)) callback.call(api);\n          });\n        else {\n          $(this).css({display:'block',visibility:'hidden'});\n          api = $.Jcrop(this, options);\n          if ($.isFunction(callback)) callback.call(api);\n        }\n      }\n    });\n\n    // Return \"this\" so the object is chainable (jQuery-style)\n    return this;\n  };\n  //}}}\n  // $.Jcrop.Loader - basic image loader {{{\n\n  $.Jcrop.Loader = function(imgobj,success,error){\n    var $img = $(imgobj), img = $img[0];\n\n    function completeCheck(){\n      if (img.complete) {\n        $img.unbind('.jcloader');\n        if ($.isFunction(success)) success.call(img);\n      }\n      else window.setTimeout(completeCheck,50);\n    }\n\n    $img\n      .bind('load.jcloader',completeCheck)\n      .bind('error.jcloader',function(e){\n        $img.unbind('.jcloader');\n        if ($.isFunction(error)) error.call(img);\n      });\n\n    if (img.complete && $.isFunction(success)){\n      $img.unbind('.jcloader');\n      success.call(img);\n    }\n  };\n\n  //}}}\n  // Global Defaults {{{\n  $.Jcrop.defaults = {\n\n    // Basic Settings\n    allowSelect: true,\n    allowMove: true,\n    allowResize: true,\n\n    trackDocument: true,\n\n    // Styling Options\n    baseClass: 'jcrop',\n    addClass: null,\n    bgColor: 'black',\n    bgOpacity: 0.6,\n    bgFade: false,\n    borderOpacity: 0.4,\n    handleOpacity: 0.5,\n    handleSize: null,\n\n    aspectRatio: 0,\n    keySupport: true,\n    createHandles: ['n','s','e','w','nw','ne','se','sw'],\n    createDragbars: ['n','s','e','w'],\n    createBorders: ['n','s','e','w'],\n    drawBorders: true,\n    dragEdges: true,\n    fixedSupport: true,\n    touchSupport: null,\n\n    shade: null,\n\n    boxWidth: 0,\n    boxHeight: 0,\n    boundary: 2,\n    fadeTime: 400,\n    animationDelay: 20,\n    swingSpeed: 3,\n\n    minSelect: [0, 0],\n    maxSize: [0, 0],\n    minSize: [0, 0],\n\n    // Callbacks / Event Handlers\n    onChange: function () {},\n    onSelect: function () {},\n    onDblClick: function () {},\n    onRelease: function () {}\n  };\n\n  // }}}\n}(jQuery));\n"
  },
  {
    "path": "app_backend/static/plugin/JavaScript-Load-Image-2.12.2/js/vendor/jquery.js",
    "content": "/*!\n * jQuery JavaScript Library v1.11.3\n * http://jquery.com/\n *\n * Includes Sizzle.js\n * http://sizzlejs.com/\n *\n * Copyright 2005, 2014 jQuery Foundation, Inc. and other contributors\n * Released under the MIT license\n * http://jquery.org/license\n *\n * Date: 2015-04-28T16:19Z\n */\n\n(function( global, factory ) {\n\n\tif ( typeof module === \"object\" && typeof module.exports === \"object\" ) {\n\t\t// For CommonJS and CommonJS-like environments where a proper window is present,\n\t\t// execute the factory and get jQuery\n\t\t// For environments that do not inherently posses a window with a document\n\t\t// (such as Node.js), expose a jQuery-making factory as module.exports\n\t\t// This accentuates the need for the creation of a real window\n\t\t// e.g. var jQuery = require(\"jquery\")(window);\n\t\t// See ticket #14549 for more info\n\t\tmodule.exports = global.document ?\n\t\t\tfactory( global, true ) :\n\t\t\tfunction( w ) {\n\t\t\t\tif ( !w.document ) {\n\t\t\t\t\tthrow new Error( \"jQuery requires a window with a document\" );\n\t\t\t\t}\n\t\t\t\treturn factory( w );\n\t\t\t};\n\t} else {\n\t\tfactory( global );\n\t}\n\n// Pass this if window is not defined yet\n}(typeof window !== \"undefined\" ? window : this, function( window, noGlobal ) {\n\n// Can't do this because several apps including ASP.NET trace\n// the stack via arguments.caller.callee and Firefox dies if\n// you try to trace through \"use strict\" call chains. (#13335)\n// Support: Firefox 18+\n//\n\nvar deletedIds = [];\n\nvar slice = deletedIds.slice;\n\nvar concat = deletedIds.concat;\n\nvar push = deletedIds.push;\n\nvar indexOf = deletedIds.indexOf;\n\nvar class2type = {};\n\nvar toString = class2type.toString;\n\nvar hasOwn = class2type.hasOwnProperty;\n\nvar support = {};\n\n\n\nvar\n\tversion = \"1.11.3\",\n\n\t// Define a local copy of jQuery\n\tjQuery = function( selector, context ) {\n\t\t// The jQuery object is actually just the init constructor 'enhanced'\n\t\t// Need init if jQuery is called (just allow error to be thrown if not included)\n\t\treturn new jQuery.fn.init( selector, context );\n\t},\n\n\t// Support: Android<4.1, IE<9\n\t// Make sure we trim BOM and NBSP\n\trtrim = /^[\\s\\uFEFF\\xA0]+|[\\s\\uFEFF\\xA0]+$/g,\n\n\t// Matches dashed string for camelizing\n\trmsPrefix = /^-ms-/,\n\trdashAlpha = /-([\\da-z])/gi,\n\n\t// Used by jQuery.camelCase as callback to replace()\n\tfcamelCase = function( all, letter ) {\n\t\treturn letter.toUpperCase();\n\t};\n\njQuery.fn = jQuery.prototype = {\n\t// The current version of jQuery being used\n\tjquery: version,\n\n\tconstructor: jQuery,\n\n\t// Start with an empty selector\n\tselector: \"\",\n\n\t// The default length of a jQuery object is 0\n\tlength: 0,\n\n\ttoArray: function() {\n\t\treturn slice.call( this );\n\t},\n\n\t// Get the Nth element in the matched element set OR\n\t// Get the whole matched element set as a clean array\n\tget: function( num ) {\n\t\treturn num != null ?\n\n\t\t\t// Return just the one element from the set\n\t\t\t( num < 0 ? this[ num + this.length ] : this[ num ] ) :\n\n\t\t\t// Return all the elements in a clean array\n\t\t\tslice.call( this );\n\t},\n\n\t// Take an array of elements and push it onto the stack\n\t// (returning the new matched element set)\n\tpushStack: function( elems ) {\n\n\t\t// Build a new jQuery matched element set\n\t\tvar ret = jQuery.merge( this.constructor(), elems );\n\n\t\t// Add the old object onto the stack (as a reference)\n\t\tret.prevObject = this;\n\t\tret.context = this.context;\n\n\t\t// Return the newly-formed element set\n\t\treturn ret;\n\t},\n\n\t// Execute a callback for every element in the matched set.\n\t// (You can seed the arguments with an array of args, but this is\n\t// only used internally.)\n\teach: function( callback, args ) {\n\t\treturn jQuery.each( this, callback, args );\n\t},\n\n\tmap: function( callback ) {\n\t\treturn this.pushStack( jQuery.map(this, function( elem, i ) {\n\t\t\treturn callback.call( elem, i, elem );\n\t\t}));\n\t},\n\n\tslice: function() {\n\t\treturn this.pushStack( slice.apply( this, arguments ) );\n\t},\n\n\tfirst: function() {\n\t\treturn this.eq( 0 );\n\t},\n\n\tlast: function() {\n\t\treturn this.eq( -1 );\n\t},\n\n\teq: function( i ) {\n\t\tvar len = this.length,\n\t\t\tj = +i + ( i < 0 ? len : 0 );\n\t\treturn this.pushStack( j >= 0 && j < len ? [ this[j] ] : [] );\n\t},\n\n\tend: function() {\n\t\treturn this.prevObject || this.constructor(null);\n\t},\n\n\t// For internal use only.\n\t// Behaves like an Array's method, not like a jQuery method.\n\tpush: push,\n\tsort: deletedIds.sort,\n\tsplice: deletedIds.splice\n};\n\njQuery.extend = jQuery.fn.extend = function() {\n\tvar src, copyIsArray, copy, name, options, clone,\n\t\ttarget = arguments[0] || {},\n\t\ti = 1,\n\t\tlength = arguments.length,\n\t\tdeep = false;\n\n\t// Handle a deep copy situation\n\tif ( typeof target === \"boolean\" ) {\n\t\tdeep = target;\n\n\t\t// skip the boolean and the target\n\t\ttarget = arguments[ i ] || {};\n\t\ti++;\n\t}\n\n\t// Handle case when target is a string or something (possible in deep copy)\n\tif ( typeof target !== \"object\" && !jQuery.isFunction(target) ) {\n\t\ttarget = {};\n\t}\n\n\t// extend jQuery itself if only one argument is passed\n\tif ( i === length ) {\n\t\ttarget = this;\n\t\ti--;\n\t}\n\n\tfor ( ; i < length; i++ ) {\n\t\t// Only deal with non-null/undefined values\n\t\tif ( (options = arguments[ i ]) != null ) {\n\t\t\t// Extend the base object\n\t\t\tfor ( name in options ) {\n\t\t\t\tsrc = target[ name ];\n\t\t\t\tcopy = options[ name ];\n\n\t\t\t\t// Prevent never-ending loop\n\t\t\t\tif ( target === copy ) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\t// Recurse if we're merging plain objects or arrays\n\t\t\t\tif ( deep && copy && ( jQuery.isPlainObject(copy) || (copyIsArray = jQuery.isArray(copy)) ) ) {\n\t\t\t\t\tif ( copyIsArray ) {\n\t\t\t\t\t\tcopyIsArray = false;\n\t\t\t\t\t\tclone = src && jQuery.isArray(src) ? src : [];\n\n\t\t\t\t\t} else {\n\t\t\t\t\t\tclone = src && jQuery.isPlainObject(src) ? src : {};\n\t\t\t\t\t}\n\n\t\t\t\t\t// Never move original objects, clone them\n\t\t\t\t\ttarget[ name ] = jQuery.extend( deep, clone, copy );\n\n\t\t\t\t// Don't bring in undefined values\n\t\t\t\t} else if ( copy !== undefined ) {\n\t\t\t\t\ttarget[ name ] = copy;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t// Return the modified object\n\treturn target;\n};\n\njQuery.extend({\n\t// Unique for each copy of jQuery on the page\n\texpando: \"jQuery\" + ( version + Math.random() ).replace( /\\D/g, \"\" ),\n\n\t// Assume jQuery is ready without the ready module\n\tisReady: true,\n\n\terror: function( msg ) {\n\t\tthrow new Error( msg );\n\t},\n\n\tnoop: function() {},\n\n\t// See test/unit/core.js for details concerning isFunction.\n\t// Since version 1.3, DOM methods and functions like alert\n\t// aren't supported. They return false on IE (#2968).\n\tisFunction: function( obj ) {\n\t\treturn jQuery.type(obj) === \"function\";\n\t},\n\n\tisArray: Array.isArray || function( obj ) {\n\t\treturn jQuery.type(obj) === \"array\";\n\t},\n\n\tisWindow: function( obj ) {\n\t\t/* jshint eqeqeq: false */\n\t\treturn obj != null && obj == obj.window;\n\t},\n\n\tisNumeric: function( obj ) {\n\t\t// parseFloat NaNs numeric-cast false positives (null|true|false|\"\")\n\t\t// ...but misinterprets leading-number strings, particularly hex literals (\"0x...\")\n\t\t// subtraction forces infinities to NaN\n\t\t// adding 1 corrects loss of precision from parseFloat (#15100)\n\t\treturn !jQuery.isArray( obj ) && (obj - parseFloat( obj ) + 1) >= 0;\n\t},\n\n\tisEmptyObject: function( obj ) {\n\t\tvar name;\n\t\tfor ( name in obj ) {\n\t\t\treturn false;\n\t\t}\n\t\treturn true;\n\t},\n\n\tisPlainObject: function( obj ) {\n\t\tvar key;\n\n\t\t// Must be an Object.\n\t\t// Because of IE, we also have to check the presence of the constructor property.\n\t\t// Make sure that DOM nodes and window objects don't pass through, as well\n\t\tif ( !obj || jQuery.type(obj) !== \"object\" || obj.nodeType || jQuery.isWindow( obj ) ) {\n\t\t\treturn false;\n\t\t}\n\n\t\ttry {\n\t\t\t// Not own constructor property must be Object\n\t\t\tif ( obj.constructor &&\n\t\t\t\t!hasOwn.call(obj, \"constructor\") &&\n\t\t\t\t!hasOwn.call(obj.constructor.prototype, \"isPrototypeOf\") ) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t} catch ( e ) {\n\t\t\t// IE8,9 Will throw exceptions on certain host objects #9897\n\t\t\treturn false;\n\t\t}\n\n\t\t// Support: IE<9\n\t\t// Handle iteration over inherited properties before own properties.\n\t\tif ( support.ownLast ) {\n\t\t\tfor ( key in obj ) {\n\t\t\t\treturn hasOwn.call( obj, key );\n\t\t\t}\n\t\t}\n\n\t\t// Own properties are enumerated firstly, so to speed up,\n\t\t// if last one is own, then all properties are own.\n\t\tfor ( key in obj ) {}\n\n\t\treturn key === undefined || hasOwn.call( obj, key );\n\t},\n\n\ttype: function( obj ) {\n\t\tif ( obj == null ) {\n\t\t\treturn obj + \"\";\n\t\t}\n\t\treturn typeof obj === \"object\" || typeof obj === \"function\" ?\n\t\t\tclass2type[ toString.call(obj) ] || \"object\" :\n\t\t\ttypeof obj;\n\t},\n\n\t// Evaluates a script in a global context\n\t// Workarounds based on findings by Jim Driscoll\n\t// http://weblogs.java.net/blog/driscoll/archive/2009/09/08/eval-javascript-global-context\n\tglobalEval: function( data ) {\n\t\tif ( data && jQuery.trim( data ) ) {\n\t\t\t// We use execScript on Internet Explorer\n\t\t\t// We use an anonymous function so that context is window\n\t\t\t// rather than jQuery in Firefox\n\t\t\t( window.execScript || function( data ) {\n\t\t\t\twindow[ \"eval\" ].call( window, data );\n\t\t\t} )( data );\n\t\t}\n\t},\n\n\t// Convert dashed to camelCase; used by the css and data modules\n\t// Microsoft forgot to hump their vendor prefix (#9572)\n\tcamelCase: function( string ) {\n\t\treturn string.replace( rmsPrefix, \"ms-\" ).replace( rdashAlpha, fcamelCase );\n\t},\n\n\tnodeName: function( elem, name ) {\n\t\treturn elem.nodeName && elem.nodeName.toLowerCase() === name.toLowerCase();\n\t},\n\n\t// args is for internal usage only\n\teach: function( obj, callback, args ) {\n\t\tvar value,\n\t\t\ti = 0,\n\t\t\tlength = obj.length,\n\t\t\tisArray = isArraylike( obj );\n\n\t\tif ( args ) {\n\t\t\tif ( isArray ) {\n\t\t\t\tfor ( ; i < length; i++ ) {\n\t\t\t\t\tvalue = callback.apply( obj[ i ], args );\n\n\t\t\t\t\tif ( value === false ) {\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tfor ( i in obj ) {\n\t\t\t\t\tvalue = callback.apply( obj[ i ], args );\n\n\t\t\t\t\tif ( value === false ) {\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t// A special, fast, case for the most common use of each\n\t\t} else {\n\t\t\tif ( isArray ) {\n\t\t\t\tfor ( ; i < length; i++ ) {\n\t\t\t\t\tvalue = callback.call( obj[ i ], i, obj[ i ] );\n\n\t\t\t\t\tif ( value === false ) {\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tfor ( i in obj ) {\n\t\t\t\t\tvalue = callback.call( obj[ i ], i, obj[ i ] );\n\n\t\t\t\t\tif ( value === false ) {\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn obj;\n\t},\n\n\t// Support: Android<4.1, IE<9\n\ttrim: function( text ) {\n\t\treturn text == null ?\n\t\t\t\"\" :\n\t\t\t( text + \"\" ).replace( rtrim, \"\" );\n\t},\n\n\t// results is for internal usage only\n\tmakeArray: function( arr, results ) {\n\t\tvar ret = results || [];\n\n\t\tif ( arr != null ) {\n\t\t\tif ( isArraylike( Object(arr) ) ) {\n\t\t\t\tjQuery.merge( ret,\n\t\t\t\t\ttypeof arr === \"string\" ?\n\t\t\t\t\t[ arr ] : arr\n\t\t\t\t);\n\t\t\t} else {\n\t\t\t\tpush.call( ret, arr );\n\t\t\t}\n\t\t}\n\n\t\treturn ret;\n\t},\n\n\tinArray: function( elem, arr, i ) {\n\t\tvar len;\n\n\t\tif ( arr ) {\n\t\t\tif ( indexOf ) {\n\t\t\t\treturn indexOf.call( arr, elem, i );\n\t\t\t}\n\n\t\t\tlen = arr.length;\n\t\t\ti = i ? i < 0 ? Math.max( 0, len + i ) : i : 0;\n\n\t\t\tfor ( ; i < len; i++ ) {\n\t\t\t\t// Skip accessing in sparse arrays\n\t\t\t\tif ( i in arr && arr[ i ] === elem ) {\n\t\t\t\t\treturn i;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn -1;\n\t},\n\n\tmerge: function( first, second ) {\n\t\tvar len = +second.length,\n\t\t\tj = 0,\n\t\t\ti = first.length;\n\n\t\twhile ( j < len ) {\n\t\t\tfirst[ i++ ] = second[ j++ ];\n\t\t}\n\n\t\t// Support: IE<9\n\t\t// Workaround casting of .length to NaN on otherwise arraylike objects (e.g., NodeLists)\n\t\tif ( len !== len ) {\n\t\t\twhile ( second[j] !== undefined ) {\n\t\t\t\tfirst[ i++ ] = second[ j++ ];\n\t\t\t}\n\t\t}\n\n\t\tfirst.length = i;\n\n\t\treturn first;\n\t},\n\n\tgrep: function( elems, callback, invert ) {\n\t\tvar callbackInverse,\n\t\t\tmatches = [],\n\t\t\ti = 0,\n\t\t\tlength = elems.length,\n\t\t\tcallbackExpect = !invert;\n\n\t\t// Go through the array, only saving the items\n\t\t// that pass the validator function\n\t\tfor ( ; i < length; i++ ) {\n\t\t\tcallbackInverse = !callback( elems[ i ], i );\n\t\t\tif ( callbackInverse !== callbackExpect ) {\n\t\t\t\tmatches.push( elems[ i ] );\n\t\t\t}\n\t\t}\n\n\t\treturn matches;\n\t},\n\n\t// arg is for internal usage only\n\tmap: function( elems, callback, arg ) {\n\t\tvar value,\n\t\t\ti = 0,\n\t\t\tlength = elems.length,\n\t\t\tisArray = isArraylike( elems ),\n\t\t\tret = [];\n\n\t\t// Go through the array, translating each of the items to their new values\n\t\tif ( isArray ) {\n\t\t\tfor ( ; i < length; i++ ) {\n\t\t\t\tvalue = callback( elems[ i ], i, arg );\n\n\t\t\t\tif ( value != null ) {\n\t\t\t\t\tret.push( value );\n\t\t\t\t}\n\t\t\t}\n\n\t\t// Go through every key on the object,\n\t\t} else {\n\t\t\tfor ( i in elems ) {\n\t\t\t\tvalue = callback( elems[ i ], i, arg );\n\n\t\t\t\tif ( value != null ) {\n\t\t\t\t\tret.push( value );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Flatten any nested arrays\n\t\treturn concat.apply( [], ret );\n\t},\n\n\t// A global GUID counter for objects\n\tguid: 1,\n\n\t// Bind a function to a context, optionally partially applying any\n\t// arguments.\n\tproxy: function( fn, context ) {\n\t\tvar args, proxy, tmp;\n\n\t\tif ( typeof context === \"string\" ) {\n\t\t\ttmp = fn[ context ];\n\t\t\tcontext = fn;\n\t\t\tfn = tmp;\n\t\t}\n\n\t\t// Quick check to determine if target is callable, in the spec\n\t\t// this throws a TypeError, but we will just return undefined.\n\t\tif ( !jQuery.isFunction( fn ) ) {\n\t\t\treturn undefined;\n\t\t}\n\n\t\t// Simulated bind\n\t\targs = slice.call( arguments, 2 );\n\t\tproxy = function() {\n\t\t\treturn fn.apply( context || this, args.concat( slice.call( arguments ) ) );\n\t\t};\n\n\t\t// Set the guid of unique handler to the same of original handler, so it can be removed\n\t\tproxy.guid = fn.guid = fn.guid || jQuery.guid++;\n\n\t\treturn proxy;\n\t},\n\n\tnow: function() {\n\t\treturn +( new Date() );\n\t},\n\n\t// jQuery.support is not used in Core but other projects attach their\n\t// properties to it so it needs to exist.\n\tsupport: support\n});\n\n// Populate the class2type map\njQuery.each(\"Boolean Number String Function Array Date RegExp Object Error\".split(\" \"), function(i, name) {\n\tclass2type[ \"[object \" + name + \"]\" ] = name.toLowerCase();\n});\n\nfunction isArraylike( obj ) {\n\n\t// Support: iOS 8.2 (not reproducible in simulator)\n\t// `in` check used to prevent JIT error (gh-2145)\n\t// hasOwn isn't used here due to false negatives\n\t// regarding Nodelist length in IE\n\tvar length = \"length\" in obj && obj.length,\n\t\ttype = jQuery.type( obj );\n\n\tif ( type === \"function\" || jQuery.isWindow( obj ) ) {\n\t\treturn false;\n\t}\n\n\tif ( obj.nodeType === 1 && length ) {\n\t\treturn true;\n\t}\n\n\treturn type === \"array\" || length === 0 ||\n\t\ttypeof length === \"number\" && length > 0 && ( length - 1 ) in obj;\n}\nvar Sizzle =\n/*!\n * Sizzle CSS Selector Engine v2.2.0-pre\n * http://sizzlejs.com/\n *\n * Copyright 2008, 2014 jQuery Foundation, Inc. and other contributors\n * Released under the MIT license\n * http://jquery.org/license\n *\n * Date: 2014-12-16\n */\n(function( window ) {\n\nvar i,\n\tsupport,\n\tExpr,\n\tgetText,\n\tisXML,\n\ttokenize,\n\tcompile,\n\tselect,\n\toutermostContext,\n\tsortInput,\n\thasDuplicate,\n\n\t// Local document vars\n\tsetDocument,\n\tdocument,\n\tdocElem,\n\tdocumentIsHTML,\n\trbuggyQSA,\n\trbuggyMatches,\n\tmatches,\n\tcontains,\n\n\t// Instance-specific data\n\texpando = \"sizzle\" + 1 * new Date(),\n\tpreferredDoc = window.document,\n\tdirruns = 0,\n\tdone = 0,\n\tclassCache = createCache(),\n\ttokenCache = createCache(),\n\tcompilerCache = createCache(),\n\tsortOrder = function( a, b ) {\n\t\tif ( a === b ) {\n\t\t\thasDuplicate = true;\n\t\t}\n\t\treturn 0;\n\t},\n\n\t// General-purpose constants\n\tMAX_NEGATIVE = 1 << 31,\n\n\t// Instance methods\n\thasOwn = ({}).hasOwnProperty,\n\tarr = [],\n\tpop = arr.pop,\n\tpush_native = arr.push,\n\tpush = arr.push,\n\tslice = arr.slice,\n\t// Use a stripped-down indexOf as it's faster than native\n\t// http://jsperf.com/thor-indexof-vs-for/5\n\tindexOf = function( list, elem ) {\n\t\tvar i = 0,\n\t\t\tlen = list.length;\n\t\tfor ( ; i < len; i++ ) {\n\t\t\tif ( list[i] === elem ) {\n\t\t\t\treturn i;\n\t\t\t}\n\t\t}\n\t\treturn -1;\n\t},\n\n\tbooleans = \"checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped\",\n\n\t// Regular expressions\n\n\t// Whitespace characters http://www.w3.org/TR/css3-selectors/#whitespace\n\twhitespace = \"[\\\\x20\\\\t\\\\r\\\\n\\\\f]\",\n\t// http://www.w3.org/TR/css3-syntax/#characters\n\tcharacterEncoding = \"(?:\\\\\\\\.|[\\\\w-]|[^\\\\x00-\\\\xa0])+\",\n\n\t// Loosely modeled on CSS identifier characters\n\t// An unquoted value should be a CSS identifier http://www.w3.org/TR/css3-selectors/#attribute-selectors\n\t// Proper syntax: http://www.w3.org/TR/CSS21/syndata.html#value-def-identifier\n\tidentifier = characterEncoding.replace( \"w\", \"w#\" ),\n\n\t// Attribute selectors: http://www.w3.org/TR/selectors/#attribute-selectors\n\tattributes = \"\\\\[\" + whitespace + \"*(\" + characterEncoding + \")(?:\" + whitespace +\n\t\t// Operator (capture 2)\n\t\t\"*([*^$|!~]?=)\" + whitespace +\n\t\t// \"Attribute values must be CSS identifiers [capture 5] or strings [capture 3 or capture 4]\"\n\t\t\"*(?:'((?:\\\\\\\\.|[^\\\\\\\\'])*)'|\\\"((?:\\\\\\\\.|[^\\\\\\\\\\\"])*)\\\"|(\" + identifier + \"))|)\" + whitespace +\n\t\t\"*\\\\]\",\n\n\tpseudos = \":(\" + characterEncoding + \")(?:\\\\((\" +\n\t\t// To reduce the number of selectors needing tokenize in the preFilter, prefer arguments:\n\t\t// 1. quoted (capture 3; capture 4 or capture 5)\n\t\t\"('((?:\\\\\\\\.|[^\\\\\\\\'])*)'|\\\"((?:\\\\\\\\.|[^\\\\\\\\\\\"])*)\\\")|\" +\n\t\t// 2. simple (capture 6)\n\t\t\"((?:\\\\\\\\.|[^\\\\\\\\()[\\\\]]|\" + attributes + \")*)|\" +\n\t\t// 3. anything else (capture 2)\n\t\t\".*\" +\n\t\t\")\\\\)|)\",\n\n\t// Leading and non-escaped trailing whitespace, capturing some non-whitespace characters preceding the latter\n\trwhitespace = new RegExp( whitespace + \"+\", \"g\" ),\n\trtrim = new RegExp( \"^\" + whitespace + \"+|((?:^|[^\\\\\\\\])(?:\\\\\\\\.)*)\" + whitespace + \"+$\", \"g\" ),\n\n\trcomma = new RegExp( \"^\" + whitespace + \"*,\" + whitespace + \"*\" ),\n\trcombinators = new RegExp( \"^\" + whitespace + \"*([>+~]|\" + whitespace + \")\" + whitespace + \"*\" ),\n\n\trattributeQuotes = new RegExp( \"=\" + whitespace + \"*([^\\\\]'\\\"]*?)\" + whitespace + \"*\\\\]\", \"g\" ),\n\n\trpseudo = new RegExp( pseudos ),\n\tridentifier = new RegExp( \"^\" + identifier + \"$\" ),\n\n\tmatchExpr = {\n\t\t\"ID\": new RegExp( \"^#(\" + characterEncoding + \")\" ),\n\t\t\"CLASS\": new RegExp( \"^\\\\.(\" + characterEncoding + \")\" ),\n\t\t\"TAG\": new RegExp( \"^(\" + characterEncoding.replace( \"w\", \"w*\" ) + \")\" ),\n\t\t\"ATTR\": new RegExp( \"^\" + attributes ),\n\t\t\"PSEUDO\": new RegExp( \"^\" + pseudos ),\n\t\t\"CHILD\": new RegExp( \"^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\\\(\" + whitespace +\n\t\t\t\"*(even|odd|(([+-]|)(\\\\d*)n|)\" + whitespace + \"*(?:([+-]|)\" + whitespace +\n\t\t\t\"*(\\\\d+)|))\" + whitespace + \"*\\\\)|)\", \"i\" ),\n\t\t\"bool\": new RegExp( \"^(?:\" + booleans + \")$\", \"i\" ),\n\t\t// For use in libraries implementing .is()\n\t\t// We use this for POS matching in `select`\n\t\t\"needsContext\": new RegExp( \"^\" + whitespace + \"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\\\(\" +\n\t\t\twhitespace + \"*((?:-\\\\d)?\\\\d*)\" + whitespace + \"*\\\\)|)(?=[^-]|$)\", \"i\" )\n\t},\n\n\trinputs = /^(?:input|select|textarea|button)$/i,\n\trheader = /^h\\d$/i,\n\n\trnative = /^[^{]+\\{\\s*\\[native \\w/,\n\n\t// Easily-parseable/retrievable ID or TAG or CLASS selectors\n\trquickExpr = /^(?:#([\\w-]+)|(\\w+)|\\.([\\w-]+))$/,\n\n\trsibling = /[+~]/,\n\trescape = /'|\\\\/g,\n\n\t// CSS escapes http://www.w3.org/TR/CSS21/syndata.html#escaped-characters\n\trunescape = new RegExp( \"\\\\\\\\([\\\\da-f]{1,6}\" + whitespace + \"?|(\" + whitespace + \")|.)\", \"ig\" ),\n\tfunescape = function( _, escaped, escapedWhitespace ) {\n\t\tvar high = \"0x\" + escaped - 0x10000;\n\t\t// NaN means non-codepoint\n\t\t// Support: Firefox<24\n\t\t// Workaround erroneous numeric interpretation of +\"0x\"\n\t\treturn high !== high || escapedWhitespace ?\n\t\t\tescaped :\n\t\t\thigh < 0 ?\n\t\t\t\t// BMP codepoint\n\t\t\t\tString.fromCharCode( high + 0x10000 ) :\n\t\t\t\t// Supplemental Plane codepoint (surrogate pair)\n\t\t\t\tString.fromCharCode( high >> 10 | 0xD800, high & 0x3FF | 0xDC00 );\n\t},\n\n\t// Used for iframes\n\t// See setDocument()\n\t// Removing the function wrapper causes a \"Permission Denied\"\n\t// error in IE\n\tunloadHandler = function() {\n\t\tsetDocument();\n\t};\n\n// Optimize for push.apply( _, NodeList )\ntry {\n\tpush.apply(\n\t\t(arr = slice.call( preferredDoc.childNodes )),\n\t\tpreferredDoc.childNodes\n\t);\n\t// Support: Android<4.0\n\t// Detect silently failing push.apply\n\tarr[ preferredDoc.childNodes.length ].nodeType;\n} catch ( e ) {\n\tpush = { apply: arr.length ?\n\n\t\t// Leverage slice if possible\n\t\tfunction( target, els ) {\n\t\t\tpush_native.apply( target, slice.call(els) );\n\t\t} :\n\n\t\t// Support: IE<9\n\t\t// Otherwise append directly\n\t\tfunction( target, els ) {\n\t\t\tvar j = target.length,\n\t\t\t\ti = 0;\n\t\t\t// Can't trust NodeList.length\n\t\t\twhile ( (target[j++] = els[i++]) ) {}\n\t\t\ttarget.length = j - 1;\n\t\t}\n\t};\n}\n\nfunction Sizzle( selector, context, results, seed ) {\n\tvar match, elem, m, nodeType,\n\t\t// QSA vars\n\t\ti, groups, old, nid, newContext, newSelector;\n\n\tif ( ( context ? context.ownerDocument || context : preferredDoc ) !== document ) {\n\t\tsetDocument( context );\n\t}\n\n\tcontext = context || document;\n\tresults = results || [];\n\tnodeType = context.nodeType;\n\n\tif ( typeof selector !== \"string\" || !selector ||\n\t\tnodeType !== 1 && nodeType !== 9 && nodeType !== 11 ) {\n\n\t\treturn results;\n\t}\n\n\tif ( !seed && documentIsHTML ) {\n\n\t\t// Try to shortcut find operations when possible (e.g., not under DocumentFragment)\n\t\tif ( nodeType !== 11 && (match = rquickExpr.exec( selector )) ) {\n\t\t\t// Speed-up: Sizzle(\"#ID\")\n\t\t\tif ( (m = match[1]) ) {\n\t\t\t\tif ( nodeType === 9 ) {\n\t\t\t\t\telem = context.getElementById( m );\n\t\t\t\t\t// Check parentNode to catch when Blackberry 4.6 returns\n\t\t\t\t\t// nodes that are no longer in the document (jQuery #6963)\n\t\t\t\t\tif ( elem && elem.parentNode ) {\n\t\t\t\t\t\t// Handle the case where IE, Opera, and Webkit return items\n\t\t\t\t\t\t// by name instead of ID\n\t\t\t\t\t\tif ( elem.id === m ) {\n\t\t\t\t\t\t\tresults.push( elem );\n\t\t\t\t\t\t\treturn results;\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\treturn results;\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\t// Context is not a document\n\t\t\t\t\tif ( context.ownerDocument && (elem = context.ownerDocument.getElementById( m )) &&\n\t\t\t\t\t\tcontains( context, elem ) && elem.id === m ) {\n\t\t\t\t\t\tresults.push( elem );\n\t\t\t\t\t\treturn results;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t// Speed-up: Sizzle(\"TAG\")\n\t\t\t} else if ( match[2] ) {\n\t\t\t\tpush.apply( results, context.getElementsByTagName( selector ) );\n\t\t\t\treturn results;\n\n\t\t\t// Speed-up: Sizzle(\".CLASS\")\n\t\t\t} else if ( (m = match[3]) && support.getElementsByClassName ) {\n\t\t\t\tpush.apply( results, context.getElementsByClassName( m ) );\n\t\t\t\treturn results;\n\t\t\t}\n\t\t}\n\n\t\t// QSA path\n\t\tif ( support.qsa && (!rbuggyQSA || !rbuggyQSA.test( selector )) ) {\n\t\t\tnid = old = expando;\n\t\t\tnewContext = context;\n\t\t\tnewSelector = nodeType !== 1 && selector;\n\n\t\t\t// qSA works strangely on Element-rooted queries\n\t\t\t// We can work around this by specifying an extra ID on the root\n\t\t\t// and working up from there (Thanks to Andrew Dupont for the technique)\n\t\t\t// IE 8 doesn't work on object elements\n\t\t\tif ( nodeType === 1 && context.nodeName.toLowerCase() !== \"object\" ) {\n\t\t\t\tgroups = tokenize( selector );\n\n\t\t\t\tif ( (old = context.getAttribute(\"id\")) ) {\n\t\t\t\t\tnid = old.replace( rescape, \"\\\\$&\" );\n\t\t\t\t} else {\n\t\t\t\t\tcontext.setAttribute( \"id\", nid );\n\t\t\t\t}\n\t\t\t\tnid = \"[id='\" + nid + \"'] \";\n\n\t\t\t\ti = groups.length;\n\t\t\t\twhile ( i-- ) {\n\t\t\t\t\tgroups[i] = nid + toSelector( groups[i] );\n\t\t\t\t}\n\t\t\t\tnewContext = rsibling.test( selector ) && testContext( context.parentNode ) || context;\n\t\t\t\tnewSelector = groups.join(\",\");\n\t\t\t}\n\n\t\t\tif ( newSelector ) {\n\t\t\t\ttry {\n\t\t\t\t\tpush.apply( results,\n\t\t\t\t\t\tnewContext.querySelectorAll( newSelector )\n\t\t\t\t\t);\n\t\t\t\t\treturn results;\n\t\t\t\t} catch(qsaError) {\n\t\t\t\t} finally {\n\t\t\t\t\tif ( !old ) {\n\t\t\t\t\t\tcontext.removeAttribute(\"id\");\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t// All others\n\treturn select( selector.replace( rtrim, \"$1\" ), context, results, seed );\n}\n\n/**\n * Create key-value caches of limited size\n * @returns {Function(string, Object)} Returns the Object data after storing it on itself with\n *\tproperty name the (space-suffixed) string and (if the cache is larger than Expr.cacheLength)\n *\tdeleting the oldest entry\n */\nfunction createCache() {\n\tvar keys = [];\n\n\tfunction cache( key, value ) {\n\t\t// Use (key + \" \") to avoid collision with native prototype properties (see Issue #157)\n\t\tif ( keys.push( key + \" \" ) > Expr.cacheLength ) {\n\t\t\t// Only keep the most recent entries\n\t\t\tdelete cache[ keys.shift() ];\n\t\t}\n\t\treturn (cache[ key + \" \" ] = value);\n\t}\n\treturn cache;\n}\n\n/**\n * Mark a function for special use by Sizzle\n * @param {Function} fn The function to mark\n */\nfunction markFunction( fn ) {\n\tfn[ expando ] = true;\n\treturn fn;\n}\n\n/**\n * Support testing using an element\n * @param {Function} fn Passed the created div and expects a boolean result\n */\nfunction assert( fn ) {\n\tvar div = document.createElement(\"div\");\n\n\ttry {\n\t\treturn !!fn( div );\n\t} catch (e) {\n\t\treturn false;\n\t} finally {\n\t\t// Remove from its parent by default\n\t\tif ( div.parentNode ) {\n\t\t\tdiv.parentNode.removeChild( div );\n\t\t}\n\t\t// release memory in IE\n\t\tdiv = null;\n\t}\n}\n\n/**\n * Adds the same handler for all of the specified attrs\n * @param {String} attrs Pipe-separated list of attributes\n * @param {Function} handler The method that will be applied\n */\nfunction addHandle( attrs, handler ) {\n\tvar arr = attrs.split(\"|\"),\n\t\ti = attrs.length;\n\n\twhile ( i-- ) {\n\t\tExpr.attrHandle[ arr[i] ] = handler;\n\t}\n}\n\n/**\n * Checks document order of two siblings\n * @param {Element} a\n * @param {Element} b\n * @returns {Number} Returns less than 0 if a precedes b, greater than 0 if a follows b\n */\nfunction siblingCheck( a, b ) {\n\tvar cur = b && a,\n\t\tdiff = cur && a.nodeType === 1 && b.nodeType === 1 &&\n\t\t\t( ~b.sourceIndex || MAX_NEGATIVE ) -\n\t\t\t( ~a.sourceIndex || MAX_NEGATIVE );\n\n\t// Use IE sourceIndex if available on both nodes\n\tif ( diff ) {\n\t\treturn diff;\n\t}\n\n\t// Check if b follows a\n\tif ( cur ) {\n\t\twhile ( (cur = cur.nextSibling) ) {\n\t\t\tif ( cur === b ) {\n\t\t\t\treturn -1;\n\t\t\t}\n\t\t}\n\t}\n\n\treturn a ? 1 : -1;\n}\n\n/**\n * Returns a function to use in pseudos for input types\n * @param {String} type\n */\nfunction createInputPseudo( type ) {\n\treturn function( elem ) {\n\t\tvar name = elem.nodeName.toLowerCase();\n\t\treturn name === \"input\" && elem.type === type;\n\t};\n}\n\n/**\n * Returns a function to use in pseudos for buttons\n * @param {String} type\n */\nfunction createButtonPseudo( type ) {\n\treturn function( elem ) {\n\t\tvar name = elem.nodeName.toLowerCase();\n\t\treturn (name === \"input\" || name === \"button\") && elem.type === type;\n\t};\n}\n\n/**\n * Returns a function to use in pseudos for positionals\n * @param {Function} fn\n */\nfunction createPositionalPseudo( fn ) {\n\treturn markFunction(function( argument ) {\n\t\targument = +argument;\n\t\treturn markFunction(function( seed, matches ) {\n\t\t\tvar j,\n\t\t\t\tmatchIndexes = fn( [], seed.length, argument ),\n\t\t\t\ti = matchIndexes.length;\n\n\t\t\t// Match elements found at the specified indexes\n\t\t\twhile ( i-- ) {\n\t\t\t\tif ( seed[ (j = matchIndexes[i]) ] ) {\n\t\t\t\t\tseed[j] = !(matches[j] = seed[j]);\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\t});\n}\n\n/**\n * Checks a node for validity as a Sizzle context\n * @param {Element|Object=} context\n * @returns {Element|Object|Boolean} The input node if acceptable, otherwise a falsy value\n */\nfunction testContext( context ) {\n\treturn context && typeof context.getElementsByTagName !== \"undefined\" && context;\n}\n\n// Expose support vars for convenience\nsupport = Sizzle.support = {};\n\n/**\n * Detects XML nodes\n * @param {Element|Object} elem An element or a document\n * @returns {Boolean} True iff elem is a non-HTML XML node\n */\nisXML = Sizzle.isXML = function( elem ) {\n\t// documentElement is verified for cases where it doesn't yet exist\n\t// (such as loading iframes in IE - #4833)\n\tvar documentElement = elem && (elem.ownerDocument || elem).documentElement;\n\treturn documentElement ? documentElement.nodeName !== \"HTML\" : false;\n};\n\n/**\n * Sets document-related variables once based on the current document\n * @param {Element|Object} [doc] An element or document object to use to set the document\n * @returns {Object} Returns the current document\n */\nsetDocument = Sizzle.setDocument = function( node ) {\n\tvar hasCompare, parent,\n\t\tdoc = node ? node.ownerDocument || node : preferredDoc;\n\n\t// If no document and documentElement is available, return\n\tif ( doc === document || doc.nodeType !== 9 || !doc.documentElement ) {\n\t\treturn document;\n\t}\n\n\t// Set our document\n\tdocument = doc;\n\tdocElem = doc.documentElement;\n\tparent = doc.defaultView;\n\n\t// Support: IE>8\n\t// If iframe document is assigned to \"document\" variable and if iframe has been reloaded,\n\t// IE will throw \"permission denied\" error when accessing \"document\" variable, see jQuery #13936\n\t// IE6-8 do not support the defaultView property so parent will be undefined\n\tif ( parent && parent !== parent.top ) {\n\t\t// IE11 does not have attachEvent, so all must suffer\n\t\tif ( parent.addEventListener ) {\n\t\t\tparent.addEventListener( \"unload\", unloadHandler, false );\n\t\t} else if ( parent.attachEvent ) {\n\t\t\tparent.attachEvent( \"onunload\", unloadHandler );\n\t\t}\n\t}\n\n\t/* Support tests\n\t---------------------------------------------------------------------- */\n\tdocumentIsHTML = !isXML( doc );\n\n\t/* Attributes\n\t---------------------------------------------------------------------- */\n\n\t// Support: IE<8\n\t// Verify that getAttribute really returns attributes and not properties\n\t// (excepting IE8 booleans)\n\tsupport.attributes = assert(function( div ) {\n\t\tdiv.className = \"i\";\n\t\treturn !div.getAttribute(\"className\");\n\t});\n\n\t/* getElement(s)By*\n\t---------------------------------------------------------------------- */\n\n\t// Check if getElementsByTagName(\"*\") returns only elements\n\tsupport.getElementsByTagName = assert(function( div ) {\n\t\tdiv.appendChild( doc.createComment(\"\") );\n\t\treturn !div.getElementsByTagName(\"*\").length;\n\t});\n\n\t// Support: IE<9\n\tsupport.getElementsByClassName = rnative.test( doc.getElementsByClassName );\n\n\t// Support: IE<10\n\t// Check if getElementById returns elements by name\n\t// The broken getElementById methods don't pick up programatically-set names,\n\t// so use a roundabout getElementsByName test\n\tsupport.getById = assert(function( div ) {\n\t\tdocElem.appendChild( div ).id = expando;\n\t\treturn !doc.getElementsByName || !doc.getElementsByName( expando ).length;\n\t});\n\n\t// ID find and filter\n\tif ( support.getById ) {\n\t\tExpr.find[\"ID\"] = function( id, context ) {\n\t\t\tif ( typeof context.getElementById !== \"undefined\" && documentIsHTML ) {\n\t\t\t\tvar m = context.getElementById( id );\n\t\t\t\t// Check parentNode to catch when Blackberry 4.6 returns\n\t\t\t\t// nodes that are no longer in the document #6963\n\t\t\t\treturn m && m.parentNode ? [ m ] : [];\n\t\t\t}\n\t\t};\n\t\tExpr.filter[\"ID\"] = function( id ) {\n\t\t\tvar attrId = id.replace( runescape, funescape );\n\t\t\treturn function( elem ) {\n\t\t\t\treturn elem.getAttribute(\"id\") === attrId;\n\t\t\t};\n\t\t};\n\t} else {\n\t\t// Support: IE6/7\n\t\t// getElementById is not reliable as a find shortcut\n\t\tdelete Expr.find[\"ID\"];\n\n\t\tExpr.filter[\"ID\"] =  function( id ) {\n\t\t\tvar attrId = id.replace( runescape, funescape );\n\t\t\treturn function( elem ) {\n\t\t\t\tvar node = typeof elem.getAttributeNode !== \"undefined\" && elem.getAttributeNode(\"id\");\n\t\t\t\treturn node && node.value === attrId;\n\t\t\t};\n\t\t};\n\t}\n\n\t// Tag\n\tExpr.find[\"TAG\"] = support.getElementsByTagName ?\n\t\tfunction( tag, context ) {\n\t\t\tif ( typeof context.getElementsByTagName !== \"undefined\" ) {\n\t\t\t\treturn context.getElementsByTagName( tag );\n\n\t\t\t// DocumentFragment nodes don't have gEBTN\n\t\t\t} else if ( support.qsa ) {\n\t\t\t\treturn context.querySelectorAll( tag );\n\t\t\t}\n\t\t} :\n\n\t\tfunction( tag, context ) {\n\t\t\tvar elem,\n\t\t\t\ttmp = [],\n\t\t\t\ti = 0,\n\t\t\t\t// By happy coincidence, a (broken) gEBTN appears on DocumentFragment nodes too\n\t\t\t\tresults = context.getElementsByTagName( tag );\n\n\t\t\t// Filter out possible comments\n\t\t\tif ( tag === \"*\" ) {\n\t\t\t\twhile ( (elem = results[i++]) ) {\n\t\t\t\t\tif ( elem.nodeType === 1 ) {\n\t\t\t\t\t\ttmp.push( elem );\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\treturn tmp;\n\t\t\t}\n\t\t\treturn results;\n\t\t};\n\n\t// Class\n\tExpr.find[\"CLASS\"] = support.getElementsByClassName && function( className, context ) {\n\t\tif ( documentIsHTML ) {\n\t\t\treturn context.getElementsByClassName( className );\n\t\t}\n\t};\n\n\t/* QSA/matchesSelector\n\t---------------------------------------------------------------------- */\n\n\t// QSA and matchesSelector support\n\n\t// matchesSelector(:active) reports false when true (IE9/Opera 11.5)\n\trbuggyMatches = [];\n\n\t// qSa(:focus) reports false when true (Chrome 21)\n\t// We allow this because of a bug in IE8/9 that throws an error\n\t// whenever `document.activeElement` is accessed on an iframe\n\t// So, we allow :focus to pass through QSA all the time to avoid the IE error\n\t// See http://bugs.jquery.com/ticket/13378\n\trbuggyQSA = [];\n\n\tif ( (support.qsa = rnative.test( doc.querySelectorAll )) ) {\n\t\t// Build QSA regex\n\t\t// Regex strategy adopted from Diego Perini\n\t\tassert(function( div ) {\n\t\t\t// Select is set to empty string on purpose\n\t\t\t// This is to test IE's treatment of not explicitly\n\t\t\t// setting a boolean content attribute,\n\t\t\t// since its presence should be enough\n\t\t\t// http://bugs.jquery.com/ticket/12359\n\t\t\tdocElem.appendChild( div ).innerHTML = \"<a id='\" + expando + \"'></a>\" +\n\t\t\t\t\"<select id='\" + expando + \"-\\f]' msallowcapture=''>\" +\n\t\t\t\t\"<option selected=''></option></select>\";\n\n\t\t\t// Support: IE8, Opera 11-12.16\n\t\t\t// Nothing should be selected when empty strings follow ^= or $= or *=\n\t\t\t// The test attribute must be unknown in Opera but \"safe\" for WinRT\n\t\t\t// http://msdn.microsoft.com/en-us/library/ie/hh465388.aspx#attribute_section\n\t\t\tif ( div.querySelectorAll(\"[msallowcapture^='']\").length ) {\n\t\t\t\trbuggyQSA.push( \"[*^$]=\" + whitespace + \"*(?:''|\\\"\\\")\" );\n\t\t\t}\n\n\t\t\t// Support: IE8\n\t\t\t// Boolean attributes and \"value\" are not treated correctly\n\t\t\tif ( !div.querySelectorAll(\"[selected]\").length ) {\n\t\t\t\trbuggyQSA.push( \"\\\\[\" + whitespace + \"*(?:value|\" + booleans + \")\" );\n\t\t\t}\n\n\t\t\t// Support: Chrome<29, Android<4.2+, Safari<7.0+, iOS<7.0+, PhantomJS<1.9.7+\n\t\t\tif ( !div.querySelectorAll( \"[id~=\" + expando + \"-]\" ).length ) {\n\t\t\t\trbuggyQSA.push(\"~=\");\n\t\t\t}\n\n\t\t\t// Webkit/Opera - :checked should return selected option elements\n\t\t\t// http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked\n\t\t\t// IE8 throws error here and will not see later tests\n\t\t\tif ( !div.querySelectorAll(\":checked\").length ) {\n\t\t\t\trbuggyQSA.push(\":checked\");\n\t\t\t}\n\n\t\t\t// Support: Safari 8+, iOS 8+\n\t\t\t// https://bugs.webkit.org/show_bug.cgi?id=136851\n\t\t\t// In-page `selector#id sibing-combinator selector` fails\n\t\t\tif ( !div.querySelectorAll( \"a#\" + expando + \"+*\" ).length ) {\n\t\t\t\trbuggyQSA.push(\".#.+[+~]\");\n\t\t\t}\n\t\t});\n\n\t\tassert(function( div ) {\n\t\t\t// Support: Windows 8 Native Apps\n\t\t\t// The type and name attributes are restricted during .innerHTML assignment\n\t\t\tvar input = doc.createElement(\"input\");\n\t\t\tinput.setAttribute( \"type\", \"hidden\" );\n\t\t\tdiv.appendChild( input ).setAttribute( \"name\", \"D\" );\n\n\t\t\t// Support: IE8\n\t\t\t// Enforce case-sensitivity of name attribute\n\t\t\tif ( div.querySelectorAll(\"[name=d]\").length ) {\n\t\t\t\trbuggyQSA.push( \"name\" + whitespace + \"*[*^$|!~]?=\" );\n\t\t\t}\n\n\t\t\t// FF 3.5 - :enabled/:disabled and hidden elements (hidden elements are still enabled)\n\t\t\t// IE8 throws error here and will not see later tests\n\t\t\tif ( !div.querySelectorAll(\":enabled\").length ) {\n\t\t\t\trbuggyQSA.push( \":enabled\", \":disabled\" );\n\t\t\t}\n\n\t\t\t// Opera 10-11 does not throw on post-comma invalid pseudos\n\t\t\tdiv.querySelectorAll(\"*,:x\");\n\t\t\trbuggyQSA.push(\",.*:\");\n\t\t});\n\t}\n\n\tif ( (support.matchesSelector = rnative.test( (matches = docElem.matches ||\n\t\tdocElem.webkitMatchesSelector ||\n\t\tdocElem.mozMatchesSelector ||\n\t\tdocElem.oMatchesSelector ||\n\t\tdocElem.msMatchesSelector) )) ) {\n\n\t\tassert(function( div ) {\n\t\t\t// Check to see if it's possible to do matchesSelector\n\t\t\t// on a disconnected node (IE 9)\n\t\t\tsupport.disconnectedMatch = matches.call( div, \"div\" );\n\n\t\t\t// This should fail with an exception\n\t\t\t// Gecko does not error, returns false instead\n\t\t\tmatches.call( div, \"[s!='']:x\" );\n\t\t\trbuggyMatches.push( \"!=\", pseudos );\n\t\t});\n\t}\n\n\trbuggyQSA = rbuggyQSA.length && new RegExp( rbuggyQSA.join(\"|\") );\n\trbuggyMatches = rbuggyMatches.length && new RegExp( rbuggyMatches.join(\"|\") );\n\n\t/* Contains\n\t---------------------------------------------------------------------- */\n\thasCompare = rnative.test( docElem.compareDocumentPosition );\n\n\t// Element contains another\n\t// Purposefully does not implement inclusive descendent\n\t// As in, an element does not contain itself\n\tcontains = hasCompare || rnative.test( docElem.contains ) ?\n\t\tfunction( a, b ) {\n\t\t\tvar adown = a.nodeType === 9 ? a.documentElement : a,\n\t\t\t\tbup = b && b.parentNode;\n\t\t\treturn a === bup || !!( bup && bup.nodeType === 1 && (\n\t\t\t\tadown.contains ?\n\t\t\t\t\tadown.contains( bup ) :\n\t\t\t\t\ta.compareDocumentPosition && a.compareDocumentPosition( bup ) & 16\n\t\t\t));\n\t\t} :\n\t\tfunction( a, b ) {\n\t\t\tif ( b ) {\n\t\t\t\twhile ( (b = b.parentNode) ) {\n\t\t\t\t\tif ( b === a ) {\n\t\t\t\t\t\treturn true;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn false;\n\t\t};\n\n\t/* Sorting\n\t---------------------------------------------------------------------- */\n\n\t// Document order sorting\n\tsortOrder = hasCompare ?\n\tfunction( a, b ) {\n\n\t\t// Flag for duplicate removal\n\t\tif ( a === b ) {\n\t\t\thasDuplicate = true;\n\t\t\treturn 0;\n\t\t}\n\n\t\t// Sort on method existence if only one input has compareDocumentPosition\n\t\tvar compare = !a.compareDocumentPosition - !b.compareDocumentPosition;\n\t\tif ( compare ) {\n\t\t\treturn compare;\n\t\t}\n\n\t\t// Calculate position if both inputs belong to the same document\n\t\tcompare = ( a.ownerDocument || a ) === ( b.ownerDocument || b ) ?\n\t\t\ta.compareDocumentPosition( b ) :\n\n\t\t\t// Otherwise we know they are disconnected\n\t\t\t1;\n\n\t\t// Disconnected nodes\n\t\tif ( compare & 1 ||\n\t\t\t(!support.sortDetached && b.compareDocumentPosition( a ) === compare) ) {\n\n\t\t\t// Choose the first element that is related to our preferred document\n\t\t\tif ( a === doc || a.ownerDocument === preferredDoc && contains(preferredDoc, a) ) {\n\t\t\t\treturn -1;\n\t\t\t}\n\t\t\tif ( b === doc || b.ownerDocument === preferredDoc && contains(preferredDoc, b) ) {\n\t\t\t\treturn 1;\n\t\t\t}\n\n\t\t\t// Maintain original order\n\t\t\treturn sortInput ?\n\t\t\t\t( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) :\n\t\t\t\t0;\n\t\t}\n\n\t\treturn compare & 4 ? -1 : 1;\n\t} :\n\tfunction( a, b ) {\n\t\t// Exit early if the nodes are identical\n\t\tif ( a === b ) {\n\t\t\thasDuplicate = true;\n\t\t\treturn 0;\n\t\t}\n\n\t\tvar cur,\n\t\t\ti = 0,\n\t\t\taup = a.parentNode,\n\t\t\tbup = b.parentNode,\n\t\t\tap = [ a ],\n\t\t\tbp = [ b ];\n\n\t\t// Parentless nodes are either documents or disconnected\n\t\tif ( !aup || !bup ) {\n\t\t\treturn a === doc ? -1 :\n\t\t\t\tb === doc ? 1 :\n\t\t\t\taup ? -1 :\n\t\t\t\tbup ? 1 :\n\t\t\t\tsortInput ?\n\t\t\t\t( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) :\n\t\t\t\t0;\n\n\t\t// If the nodes are siblings, we can do a quick check\n\t\t} else if ( aup === bup ) {\n\t\t\treturn siblingCheck( a, b );\n\t\t}\n\n\t\t// Otherwise we need full lists of their ancestors for comparison\n\t\tcur = a;\n\t\twhile ( (cur = cur.parentNode) ) {\n\t\t\tap.unshift( cur );\n\t\t}\n\t\tcur = b;\n\t\twhile ( (cur = cur.parentNode) ) {\n\t\t\tbp.unshift( cur );\n\t\t}\n\n\t\t// Walk down the tree looking for a discrepancy\n\t\twhile ( ap[i] === bp[i] ) {\n\t\t\ti++;\n\t\t}\n\n\t\treturn i ?\n\t\t\t// Do a sibling check if the nodes have a common ancestor\n\t\t\tsiblingCheck( ap[i], bp[i] ) :\n\n\t\t\t// Otherwise nodes in our document sort first\n\t\t\tap[i] === preferredDoc ? -1 :\n\t\t\tbp[i] === preferredDoc ? 1 :\n\t\t\t0;\n\t};\n\n\treturn doc;\n};\n\nSizzle.matches = function( expr, elements ) {\n\treturn Sizzle( expr, null, null, elements );\n};\n\nSizzle.matchesSelector = function( elem, expr ) {\n\t// Set document vars if needed\n\tif ( ( elem.ownerDocument || elem ) !== document ) {\n\t\tsetDocument( elem );\n\t}\n\n\t// Make sure that attribute selectors are quoted\n\texpr = expr.replace( rattributeQuotes, \"='$1']\" );\n\n\tif ( support.matchesSelector && documentIsHTML &&\n\t\t( !rbuggyMatches || !rbuggyMatches.test( expr ) ) &&\n\t\t( !rbuggyQSA     || !rbuggyQSA.test( expr ) ) ) {\n\n\t\ttry {\n\t\t\tvar ret = matches.call( elem, expr );\n\n\t\t\t// IE 9's matchesSelector returns false on disconnected nodes\n\t\t\tif ( ret || support.disconnectedMatch ||\n\t\t\t\t\t// As well, disconnected nodes are said to be in a document\n\t\t\t\t\t// fragment in IE 9\n\t\t\t\t\telem.document && elem.document.nodeType !== 11 ) {\n\t\t\t\treturn ret;\n\t\t\t}\n\t\t} catch (e) {}\n\t}\n\n\treturn Sizzle( expr, document, null, [ elem ] ).length > 0;\n};\n\nSizzle.contains = function( context, elem ) {\n\t// Set document vars if needed\n\tif ( ( context.ownerDocument || context ) !== document ) {\n\t\tsetDocument( context );\n\t}\n\treturn contains( context, elem );\n};\n\nSizzle.attr = function( elem, name ) {\n\t// Set document vars if needed\n\tif ( ( elem.ownerDocument || elem ) !== document ) {\n\t\tsetDocument( elem );\n\t}\n\n\tvar fn = Expr.attrHandle[ name.toLowerCase() ],\n\t\t// Don't get fooled by Object.prototype properties (jQuery #13807)\n\t\tval = fn && hasOwn.call( Expr.attrHandle, name.toLowerCase() ) ?\n\t\t\tfn( elem, name, !documentIsHTML ) :\n\t\t\tundefined;\n\n\treturn val !== undefined ?\n\t\tval :\n\t\tsupport.attributes || !documentIsHTML ?\n\t\t\telem.getAttribute( name ) :\n\t\t\t(val = elem.getAttributeNode(name)) && val.specified ?\n\t\t\t\tval.value :\n\t\t\t\tnull;\n};\n\nSizzle.error = function( msg ) {\n\tthrow new Error( \"Syntax error, unrecognized expression: \" + msg );\n};\n\n/**\n * Document sorting and removing duplicates\n * @param {ArrayLike} results\n */\nSizzle.uniqueSort = function( results ) {\n\tvar elem,\n\t\tduplicates = [],\n\t\tj = 0,\n\t\ti = 0;\n\n\t// Unless we *know* we can detect duplicates, assume their presence\n\thasDuplicate = !support.detectDuplicates;\n\tsortInput = !support.sortStable && results.slice( 0 );\n\tresults.sort( sortOrder );\n\n\tif ( hasDuplicate ) {\n\t\twhile ( (elem = results[i++]) ) {\n\t\t\tif ( elem === results[ i ] ) {\n\t\t\t\tj = duplicates.push( i );\n\t\t\t}\n\t\t}\n\t\twhile ( j-- ) {\n\t\t\tresults.splice( duplicates[ j ], 1 );\n\t\t}\n\t}\n\n\t// Clear input after sorting to release objects\n\t// See https://github.com/jquery/sizzle/pull/225\n\tsortInput = null;\n\n\treturn results;\n};\n\n/**\n * Utility function for retrieving the text value of an array of DOM nodes\n * @param {Array|Element} elem\n */\ngetText = Sizzle.getText = function( elem ) {\n\tvar node,\n\t\tret = \"\",\n\t\ti = 0,\n\t\tnodeType = elem.nodeType;\n\n\tif ( !nodeType ) {\n\t\t// If no nodeType, this is expected to be an array\n\t\twhile ( (node = elem[i++]) ) {\n\t\t\t// Do not traverse comment nodes\n\t\t\tret += getText( node );\n\t\t}\n\t} else if ( nodeType === 1 || nodeType === 9 || nodeType === 11 ) {\n\t\t// Use textContent for elements\n\t\t// innerText usage removed for consistency of new lines (jQuery #11153)\n\t\tif ( typeof elem.textContent === \"string\" ) {\n\t\t\treturn elem.textContent;\n\t\t} else {\n\t\t\t// Traverse its children\n\t\t\tfor ( elem = elem.firstChild; elem; elem = elem.nextSibling ) {\n\t\t\t\tret += getText( elem );\n\t\t\t}\n\t\t}\n\t} else if ( nodeType === 3 || nodeType === 4 ) {\n\t\treturn elem.nodeValue;\n\t}\n\t// Do not include comment or processing instruction nodes\n\n\treturn ret;\n};\n\nExpr = Sizzle.selectors = {\n\n\t// Can be adjusted by the user\n\tcacheLength: 50,\n\n\tcreatePseudo: markFunction,\n\n\tmatch: matchExpr,\n\n\tattrHandle: {},\n\n\tfind: {},\n\n\trelative: {\n\t\t\">\": { dir: \"parentNode\", first: true },\n\t\t\" \": { dir: \"parentNode\" },\n\t\t\"+\": { dir: \"previousSibling\", first: true },\n\t\t\"~\": { dir: \"previousSibling\" }\n\t},\n\n\tpreFilter: {\n\t\t\"ATTR\": function( match ) {\n\t\t\tmatch[1] = match[1].replace( runescape, funescape );\n\n\t\t\t// Move the given value to match[3] whether quoted or unquoted\n\t\t\tmatch[3] = ( match[3] || match[4] || match[5] || \"\" ).replace( runescape, funescape );\n\n\t\t\tif ( match[2] === \"~=\" ) {\n\t\t\t\tmatch[3] = \" \" + match[3] + \" \";\n\t\t\t}\n\n\t\t\treturn match.slice( 0, 4 );\n\t\t},\n\n\t\t\"CHILD\": function( match ) {\n\t\t\t/* matches from matchExpr[\"CHILD\"]\n\t\t\t\t1 type (only|nth|...)\n\t\t\t\t2 what (child|of-type)\n\t\t\t\t3 argument (even|odd|\\d*|\\d*n([+-]\\d+)?|...)\n\t\t\t\t4 xn-component of xn+y argument ([+-]?\\d*n|)\n\t\t\t\t5 sign of xn-component\n\t\t\t\t6 x of xn-component\n\t\t\t\t7 sign of y-component\n\t\t\t\t8 y of y-component\n\t\t\t*/\n\t\t\tmatch[1] = match[1].toLowerCase();\n\n\t\t\tif ( match[1].slice( 0, 3 ) === \"nth\" ) {\n\t\t\t\t// nth-* requires argument\n\t\t\t\tif ( !match[3] ) {\n\t\t\t\t\tSizzle.error( match[0] );\n\t\t\t\t}\n\n\t\t\t\t// numeric x and y parameters for Expr.filter.CHILD\n\t\t\t\t// remember that false/true cast respectively to 0/1\n\t\t\t\tmatch[4] = +( match[4] ? match[5] + (match[6] || 1) : 2 * ( match[3] === \"even\" || match[3] === \"odd\" ) );\n\t\t\t\tmatch[5] = +( ( match[7] + match[8] ) || match[3] === \"odd\" );\n\n\t\t\t// other types prohibit arguments\n\t\t\t} else if ( match[3] ) {\n\t\t\t\tSizzle.error( match[0] );\n\t\t\t}\n\n\t\t\treturn match;\n\t\t},\n\n\t\t\"PSEUDO\": function( match ) {\n\t\t\tvar excess,\n\t\t\t\tunquoted = !match[6] && match[2];\n\n\t\t\tif ( matchExpr[\"CHILD\"].test( match[0] ) ) {\n\t\t\t\treturn null;\n\t\t\t}\n\n\t\t\t// Accept quoted arguments as-is\n\t\t\tif ( match[3] ) {\n\t\t\t\tmatch[2] = match[4] || match[5] || \"\";\n\n\t\t\t// Strip excess characters from unquoted arguments\n\t\t\t} else if ( unquoted && rpseudo.test( unquoted ) &&\n\t\t\t\t// Get excess from tokenize (recursively)\n\t\t\t\t(excess = tokenize( unquoted, true )) &&\n\t\t\t\t// advance to the next closing parenthesis\n\t\t\t\t(excess = unquoted.indexOf( \")\", unquoted.length - excess ) - unquoted.length) ) {\n\n\t\t\t\t// excess is a negative index\n\t\t\t\tmatch[0] = match[0].slice( 0, excess );\n\t\t\t\tmatch[2] = unquoted.slice( 0, excess );\n\t\t\t}\n\n\t\t\t// Return only captures needed by the pseudo filter method (type and argument)\n\t\t\treturn match.slice( 0, 3 );\n\t\t}\n\t},\n\n\tfilter: {\n\n\t\t\"TAG\": function( nodeNameSelector ) {\n\t\t\tvar nodeName = nodeNameSelector.replace( runescape, funescape ).toLowerCase();\n\t\t\treturn nodeNameSelector === \"*\" ?\n\t\t\t\tfunction() { return true; } :\n\t\t\t\tfunction( elem ) {\n\t\t\t\t\treturn elem.nodeName && elem.nodeName.toLowerCase() === nodeName;\n\t\t\t\t};\n\t\t},\n\n\t\t\"CLASS\": function( className ) {\n\t\t\tvar pattern = classCache[ className + \" \" ];\n\n\t\t\treturn pattern ||\n\t\t\t\t(pattern = new RegExp( \"(^|\" + whitespace + \")\" + className + \"(\" + whitespace + \"|$)\" )) &&\n\t\t\t\tclassCache( className, function( elem ) {\n\t\t\t\t\treturn pattern.test( typeof elem.className === \"string\" && elem.className || typeof elem.getAttribute !== \"undefined\" && elem.getAttribute(\"class\") || \"\" );\n\t\t\t\t});\n\t\t},\n\n\t\t\"ATTR\": function( name, operator, check ) {\n\t\t\treturn function( elem ) {\n\t\t\t\tvar result = Sizzle.attr( elem, name );\n\n\t\t\t\tif ( result == null ) {\n\t\t\t\t\treturn operator === \"!=\";\n\t\t\t\t}\n\t\t\t\tif ( !operator ) {\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\n\t\t\t\tresult += \"\";\n\n\t\t\t\treturn operator === \"=\" ? result === check :\n\t\t\t\t\toperator === \"!=\" ? result !== check :\n\t\t\t\t\toperator === \"^=\" ? check && result.indexOf( check ) === 0 :\n\t\t\t\t\toperator === \"*=\" ? check && result.indexOf( check ) > -1 :\n\t\t\t\t\toperator === \"$=\" ? check && result.slice( -check.length ) === check :\n\t\t\t\t\toperator === \"~=\" ? ( \" \" + result.replace( rwhitespace, \" \" ) + \" \" ).indexOf( check ) > -1 :\n\t\t\t\t\toperator === \"|=\" ? result === check || result.slice( 0, check.length + 1 ) === check + \"-\" :\n\t\t\t\t\tfalse;\n\t\t\t};\n\t\t},\n\n\t\t\"CHILD\": function( type, what, argument, first, last ) {\n\t\t\tvar simple = type.slice( 0, 3 ) !== \"nth\",\n\t\t\t\tforward = type.slice( -4 ) !== \"last\",\n\t\t\t\tofType = what === \"of-type\";\n\n\t\t\treturn first === 1 && last === 0 ?\n\n\t\t\t\t// Shortcut for :nth-*(n)\n\t\t\t\tfunction( elem ) {\n\t\t\t\t\treturn !!elem.parentNode;\n\t\t\t\t} :\n\n\t\t\t\tfunction( elem, context, xml ) {\n\t\t\t\t\tvar cache, outerCache, node, diff, nodeIndex, start,\n\t\t\t\t\t\tdir = simple !== forward ? \"nextSibling\" : \"previousSibling\",\n\t\t\t\t\t\tparent = elem.parentNode,\n\t\t\t\t\t\tname = ofType && elem.nodeName.toLowerCase(),\n\t\t\t\t\t\tuseCache = !xml && !ofType;\n\n\t\t\t\t\tif ( parent ) {\n\n\t\t\t\t\t\t// :(first|last|only)-(child|of-type)\n\t\t\t\t\t\tif ( simple ) {\n\t\t\t\t\t\t\twhile ( dir ) {\n\t\t\t\t\t\t\t\tnode = elem;\n\t\t\t\t\t\t\t\twhile ( (node = node[ dir ]) ) {\n\t\t\t\t\t\t\t\t\tif ( ofType ? node.nodeName.toLowerCase() === name : node.nodeType === 1 ) {\n\t\t\t\t\t\t\t\t\t\treturn false;\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t// Reverse direction for :only-* (if we haven't yet done so)\n\t\t\t\t\t\t\t\tstart = dir = type === \"only\" && !start && \"nextSibling\";\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\treturn true;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tstart = [ forward ? parent.firstChild : parent.lastChild ];\n\n\t\t\t\t\t\t// non-xml :nth-child(...) stores cache data on `parent`\n\t\t\t\t\t\tif ( forward && useCache ) {\n\t\t\t\t\t\t\t// Seek `elem` from a previously-cached index\n\t\t\t\t\t\t\touterCache = parent[ expando ] || (parent[ expando ] = {});\n\t\t\t\t\t\t\tcache = outerCache[ type ] || [];\n\t\t\t\t\t\t\tnodeIndex = cache[0] === dirruns && cache[1];\n\t\t\t\t\t\t\tdiff = cache[0] === dirruns && cache[2];\n\t\t\t\t\t\t\tnode = nodeIndex && parent.childNodes[ nodeIndex ];\n\n\t\t\t\t\t\t\twhile ( (node = ++nodeIndex && node && node[ dir ] ||\n\n\t\t\t\t\t\t\t\t// Fallback to seeking `elem` from the start\n\t\t\t\t\t\t\t\t(diff = nodeIndex = 0) || start.pop()) ) {\n\n\t\t\t\t\t\t\t\t// When found, cache indexes on `parent` and break\n\t\t\t\t\t\t\t\tif ( node.nodeType === 1 && ++diff && node === elem ) {\n\t\t\t\t\t\t\t\t\touterCache[ type ] = [ dirruns, nodeIndex, diff ];\n\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// Use previously-cached element index if available\n\t\t\t\t\t\t} else if ( useCache && (cache = (elem[ expando ] || (elem[ expando ] = {}))[ type ]) && cache[0] === dirruns ) {\n\t\t\t\t\t\t\tdiff = cache[1];\n\n\t\t\t\t\t\t// xml :nth-child(...) or :nth-last-child(...) or :nth(-last)?-of-type(...)\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t// Use the same loop as above to seek `elem` from the start\n\t\t\t\t\t\t\twhile ( (node = ++nodeIndex && node && node[ dir ] ||\n\t\t\t\t\t\t\t\t(diff = nodeIndex = 0) || start.pop()) ) {\n\n\t\t\t\t\t\t\t\tif ( ( ofType ? node.nodeName.toLowerCase() === name : node.nodeType === 1 ) && ++diff ) {\n\t\t\t\t\t\t\t\t\t// Cache the index of each encountered element\n\t\t\t\t\t\t\t\t\tif ( useCache ) {\n\t\t\t\t\t\t\t\t\t\t(node[ expando ] || (node[ expando ] = {}))[ type ] = [ dirruns, diff ];\n\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t\tif ( node === elem ) {\n\t\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// Incorporate the offset, then check against cycle size\n\t\t\t\t\t\tdiff -= last;\n\t\t\t\t\t\treturn diff === first || ( diff % first === 0 && diff / first >= 0 );\n\t\t\t\t\t}\n\t\t\t\t};\n\t\t},\n\n\t\t\"PSEUDO\": function( pseudo, argument ) {\n\t\t\t// pseudo-class names are case-insensitive\n\t\t\t// http://www.w3.org/TR/selectors/#pseudo-classes\n\t\t\t// Prioritize by case sensitivity in case custom pseudos are added with uppercase letters\n\t\t\t// Remember that setFilters inherits from pseudos\n\t\t\tvar args,\n\t\t\t\tfn = Expr.pseudos[ pseudo ] || Expr.setFilters[ pseudo.toLowerCase() ] ||\n\t\t\t\t\tSizzle.error( \"unsupported pseudo: \" + pseudo );\n\n\t\t\t// The user may use createPseudo to indicate that\n\t\t\t// arguments are needed to create the filter function\n\t\t\t// just as Sizzle does\n\t\t\tif ( fn[ expando ] ) {\n\t\t\t\treturn fn( argument );\n\t\t\t}\n\n\t\t\t// But maintain support for old signatures\n\t\t\tif ( fn.length > 1 ) {\n\t\t\t\targs = [ pseudo, pseudo, \"\", argument ];\n\t\t\t\treturn Expr.setFilters.hasOwnProperty( pseudo.toLowerCase() ) ?\n\t\t\t\t\tmarkFunction(function( seed, matches ) {\n\t\t\t\t\t\tvar idx,\n\t\t\t\t\t\t\tmatched = fn( seed, argument ),\n\t\t\t\t\t\t\ti = matched.length;\n\t\t\t\t\t\twhile ( i-- ) {\n\t\t\t\t\t\t\tidx = indexOf( seed, matched[i] );\n\t\t\t\t\t\t\tseed[ idx ] = !( matches[ idx ] = matched[i] );\n\t\t\t\t\t\t}\n\t\t\t\t\t}) :\n\t\t\t\t\tfunction( elem ) {\n\t\t\t\t\t\treturn fn( elem, 0, args );\n\t\t\t\t\t};\n\t\t\t}\n\n\t\t\treturn fn;\n\t\t}\n\t},\n\n\tpseudos: {\n\t\t// Potentially complex pseudos\n\t\t\"not\": markFunction(function( selector ) {\n\t\t\t// Trim the selector passed to compile\n\t\t\t// to avoid treating leading and trailing\n\t\t\t// spaces as combinators\n\t\t\tvar input = [],\n\t\t\t\tresults = [],\n\t\t\t\tmatcher = compile( selector.replace( rtrim, \"$1\" ) );\n\n\t\t\treturn matcher[ expando ] ?\n\t\t\t\tmarkFunction(function( seed, matches, context, xml ) {\n\t\t\t\t\tvar elem,\n\t\t\t\t\t\tunmatched = matcher( seed, null, xml, [] ),\n\t\t\t\t\t\ti = seed.length;\n\n\t\t\t\t\t// Match elements unmatched by `matcher`\n\t\t\t\t\twhile ( i-- ) {\n\t\t\t\t\t\tif ( (elem = unmatched[i]) ) {\n\t\t\t\t\t\t\tseed[i] = !(matches[i] = elem);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}) :\n\t\t\t\tfunction( elem, context, xml ) {\n\t\t\t\t\tinput[0] = elem;\n\t\t\t\t\tmatcher( input, null, xml, results );\n\t\t\t\t\t// Don't keep the element (issue #299)\n\t\t\t\t\tinput[0] = null;\n\t\t\t\t\treturn !results.pop();\n\t\t\t\t};\n\t\t}),\n\n\t\t\"has\": markFunction(function( selector ) {\n\t\t\treturn function( elem ) {\n\t\t\t\treturn Sizzle( selector, elem ).length > 0;\n\t\t\t};\n\t\t}),\n\n\t\t\"contains\": markFunction(function( text ) {\n\t\t\ttext = text.replace( runescape, funescape );\n\t\t\treturn function( elem ) {\n\t\t\t\treturn ( elem.textContent || elem.innerText || getText( elem ) ).indexOf( text ) > -1;\n\t\t\t};\n\t\t}),\n\n\t\t// \"Whether an element is represented by a :lang() selector\n\t\t// is based solely on the element's language value\n\t\t// being equal to the identifier C,\n\t\t// or beginning with the identifier C immediately followed by \"-\".\n\t\t// The matching of C against the element's language value is performed case-insensitively.\n\t\t// The identifier C does not have to be a valid language name.\"\n\t\t// http://www.w3.org/TR/selectors/#lang-pseudo\n\t\t\"lang\": markFunction( function( lang ) {\n\t\t\t// lang value must be a valid identifier\n\t\t\tif ( !ridentifier.test(lang || \"\") ) {\n\t\t\t\tSizzle.error( \"unsupported lang: \" + lang );\n\t\t\t}\n\t\t\tlang = lang.replace( runescape, funescape ).toLowerCase();\n\t\t\treturn function( elem ) {\n\t\t\t\tvar elemLang;\n\t\t\t\tdo {\n\t\t\t\t\tif ( (elemLang = documentIsHTML ?\n\t\t\t\t\t\telem.lang :\n\t\t\t\t\t\telem.getAttribute(\"xml:lang\") || elem.getAttribute(\"lang\")) ) {\n\n\t\t\t\t\t\telemLang = elemLang.toLowerCase();\n\t\t\t\t\t\treturn elemLang === lang || elemLang.indexOf( lang + \"-\" ) === 0;\n\t\t\t\t\t}\n\t\t\t\t} while ( (elem = elem.parentNode) && elem.nodeType === 1 );\n\t\t\t\treturn false;\n\t\t\t};\n\t\t}),\n\n\t\t// Miscellaneous\n\t\t\"target\": function( elem ) {\n\t\t\tvar hash = window.location && window.location.hash;\n\t\t\treturn hash && hash.slice( 1 ) === elem.id;\n\t\t},\n\n\t\t\"root\": function( elem ) {\n\t\t\treturn elem === docElem;\n\t\t},\n\n\t\t\"focus\": function( elem ) {\n\t\t\treturn elem === document.activeElement && (!document.hasFocus || document.hasFocus()) && !!(elem.type || elem.href || ~elem.tabIndex);\n\t\t},\n\n\t\t// Boolean properties\n\t\t\"enabled\": function( elem ) {\n\t\t\treturn elem.disabled === false;\n\t\t},\n\n\t\t\"disabled\": function( elem ) {\n\t\t\treturn elem.disabled === true;\n\t\t},\n\n\t\t\"checked\": function( elem ) {\n\t\t\t// In CSS3, :checked should return both checked and selected elements\n\t\t\t// http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked\n\t\t\tvar nodeName = elem.nodeName.toLowerCase();\n\t\t\treturn (nodeName === \"input\" && !!elem.checked) || (nodeName === \"option\" && !!elem.selected);\n\t\t},\n\n\t\t\"selected\": function( elem ) {\n\t\t\t// Accessing this property makes selected-by-default\n\t\t\t// options in Safari work properly\n\t\t\tif ( elem.parentNode ) {\n\t\t\t\telem.parentNode.selectedIndex;\n\t\t\t}\n\n\t\t\treturn elem.selected === true;\n\t\t},\n\n\t\t// Contents\n\t\t\"empty\": function( elem ) {\n\t\t\t// http://www.w3.org/TR/selectors/#empty-pseudo\n\t\t\t// :empty is negated by element (1) or content nodes (text: 3; cdata: 4; entity ref: 5),\n\t\t\t//   but not by others (comment: 8; processing instruction: 7; etc.)\n\t\t\t// nodeType < 6 works because attributes (2) do not appear as children\n\t\t\tfor ( elem = elem.firstChild; elem; elem = elem.nextSibling ) {\n\t\t\t\tif ( elem.nodeType < 6 ) {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn true;\n\t\t},\n\n\t\t\"parent\": function( elem ) {\n\t\t\treturn !Expr.pseudos[\"empty\"]( elem );\n\t\t},\n\n\t\t// Element/input types\n\t\t\"header\": function( elem ) {\n\t\t\treturn rheader.test( elem.nodeName );\n\t\t},\n\n\t\t\"input\": function( elem ) {\n\t\t\treturn rinputs.test( elem.nodeName );\n\t\t},\n\n\t\t\"button\": function( elem ) {\n\t\t\tvar name = elem.nodeName.toLowerCase();\n\t\t\treturn name === \"input\" && elem.type === \"button\" || name === \"button\";\n\t\t},\n\n\t\t\"text\": function( elem ) {\n\t\t\tvar attr;\n\t\t\treturn elem.nodeName.toLowerCase() === \"input\" &&\n\t\t\t\telem.type === \"text\" &&\n\n\t\t\t\t// Support: IE<8\n\t\t\t\t// New HTML5 attribute values (e.g., \"search\") appear with elem.type === \"text\"\n\t\t\t\t( (attr = elem.getAttribute(\"type\")) == null || attr.toLowerCase() === \"text\" );\n\t\t},\n\n\t\t// Position-in-collection\n\t\t\"first\": createPositionalPseudo(function() {\n\t\t\treturn [ 0 ];\n\t\t}),\n\n\t\t\"last\": createPositionalPseudo(function( matchIndexes, length ) {\n\t\t\treturn [ length - 1 ];\n\t\t}),\n\n\t\t\"eq\": createPositionalPseudo(function( matchIndexes, length, argument ) {\n\t\t\treturn [ argument < 0 ? argument + length : argument ];\n\t\t}),\n\n\t\t\"even\": createPositionalPseudo(function( matchIndexes, length ) {\n\t\t\tvar i = 0;\n\t\t\tfor ( ; i < length; i += 2 ) {\n\t\t\t\tmatchIndexes.push( i );\n\t\t\t}\n\t\t\treturn matchIndexes;\n\t\t}),\n\n\t\t\"odd\": createPositionalPseudo(function( matchIndexes, length ) {\n\t\t\tvar i = 1;\n\t\t\tfor ( ; i < length; i += 2 ) {\n\t\t\t\tmatchIndexes.push( i );\n\t\t\t}\n\t\t\treturn matchIndexes;\n\t\t}),\n\n\t\t\"lt\": createPositionalPseudo(function( matchIndexes, length, argument ) {\n\t\t\tvar i = argument < 0 ? argument + length : argument;\n\t\t\tfor ( ; --i >= 0; ) {\n\t\t\t\tmatchIndexes.push( i );\n\t\t\t}\n\t\t\treturn matchIndexes;\n\t\t}),\n\n\t\t\"gt\": createPositionalPseudo(function( matchIndexes, length, argument ) {\n\t\t\tvar i = argument < 0 ? argument + length : argument;\n\t\t\tfor ( ; ++i < length; ) {\n\t\t\t\tmatchIndexes.push( i );\n\t\t\t}\n\t\t\treturn matchIndexes;\n\t\t})\n\t}\n};\n\nExpr.pseudos[\"nth\"] = Expr.pseudos[\"eq\"];\n\n// Add button/input type pseudos\nfor ( i in { radio: true, checkbox: true, file: true, password: true, image: true } ) {\n\tExpr.pseudos[ i ] = createInputPseudo( i );\n}\nfor ( i in { submit: true, reset: true } ) {\n\tExpr.pseudos[ i ] = createButtonPseudo( i );\n}\n\n// Easy API for creating new setFilters\nfunction setFilters() {}\nsetFilters.prototype = Expr.filters = Expr.pseudos;\nExpr.setFilters = new setFilters();\n\ntokenize = Sizzle.tokenize = function( selector, parseOnly ) {\n\tvar matched, match, tokens, type,\n\t\tsoFar, groups, preFilters,\n\t\tcached = tokenCache[ selector + \" \" ];\n\n\tif ( cached ) {\n\t\treturn parseOnly ? 0 : cached.slice( 0 );\n\t}\n\n\tsoFar = selector;\n\tgroups = [];\n\tpreFilters = Expr.preFilter;\n\n\twhile ( soFar ) {\n\n\t\t// Comma and first run\n\t\tif ( !matched || (match = rcomma.exec( soFar )) ) {\n\t\t\tif ( match ) {\n\t\t\t\t// Don't consume trailing commas as valid\n\t\t\t\tsoFar = soFar.slice( match[0].length ) || soFar;\n\t\t\t}\n\t\t\tgroups.push( (tokens = []) );\n\t\t}\n\n\t\tmatched = false;\n\n\t\t// Combinators\n\t\tif ( (match = rcombinators.exec( soFar )) ) {\n\t\t\tmatched = match.shift();\n\t\t\ttokens.push({\n\t\t\t\tvalue: matched,\n\t\t\t\t// Cast descendant combinators to space\n\t\t\t\ttype: match[0].replace( rtrim, \" \" )\n\t\t\t});\n\t\t\tsoFar = soFar.slice( matched.length );\n\t\t}\n\n\t\t// Filters\n\t\tfor ( type in Expr.filter ) {\n\t\t\tif ( (match = matchExpr[ type ].exec( soFar )) && (!preFilters[ type ] ||\n\t\t\t\t(match = preFilters[ type ]( match ))) ) {\n\t\t\t\tmatched = match.shift();\n\t\t\t\ttokens.push({\n\t\t\t\t\tvalue: matched,\n\t\t\t\t\ttype: type,\n\t\t\t\t\tmatches: match\n\t\t\t\t});\n\t\t\t\tsoFar = soFar.slice( matched.length );\n\t\t\t}\n\t\t}\n\n\t\tif ( !matched ) {\n\t\t\tbreak;\n\t\t}\n\t}\n\n\t// Return the length of the invalid excess\n\t// if we're just parsing\n\t// Otherwise, throw an error or return tokens\n\treturn parseOnly ?\n\t\tsoFar.length :\n\t\tsoFar ?\n\t\t\tSizzle.error( selector ) :\n\t\t\t// Cache the tokens\n\t\t\ttokenCache( selector, groups ).slice( 0 );\n};\n\nfunction toSelector( tokens ) {\n\tvar i = 0,\n\t\tlen = tokens.length,\n\t\tselector = \"\";\n\tfor ( ; i < len; i++ ) {\n\t\tselector += tokens[i].value;\n\t}\n\treturn selector;\n}\n\nfunction addCombinator( matcher, combinator, base ) {\n\tvar dir = combinator.dir,\n\t\tcheckNonElements = base && dir === \"parentNode\",\n\t\tdoneName = done++;\n\n\treturn combinator.first ?\n\t\t// Check against closest ancestor/preceding element\n\t\tfunction( elem, context, xml ) {\n\t\t\twhile ( (elem = elem[ dir ]) ) {\n\t\t\t\tif ( elem.nodeType === 1 || checkNonElements ) {\n\t\t\t\t\treturn matcher( elem, context, xml );\n\t\t\t\t}\n\t\t\t}\n\t\t} :\n\n\t\t// Check against all ancestor/preceding elements\n\t\tfunction( elem, context, xml ) {\n\t\t\tvar oldCache, outerCache,\n\t\t\t\tnewCache = [ dirruns, doneName ];\n\n\t\t\t// We can't set arbitrary data on XML nodes, so they don't benefit from dir caching\n\t\t\tif ( xml ) {\n\t\t\t\twhile ( (elem = elem[ dir ]) ) {\n\t\t\t\t\tif ( elem.nodeType === 1 || checkNonElements ) {\n\t\t\t\t\t\tif ( matcher( elem, context, xml ) ) {\n\t\t\t\t\t\t\treturn true;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\twhile ( (elem = elem[ dir ]) ) {\n\t\t\t\t\tif ( elem.nodeType === 1 || checkNonElements ) {\n\t\t\t\t\t\touterCache = elem[ expando ] || (elem[ expando ] = {});\n\t\t\t\t\t\tif ( (oldCache = outerCache[ dir ]) &&\n\t\t\t\t\t\t\toldCache[ 0 ] === dirruns && oldCache[ 1 ] === doneName ) {\n\n\t\t\t\t\t\t\t// Assign to newCache so results back-propagate to previous elements\n\t\t\t\t\t\t\treturn (newCache[ 2 ] = oldCache[ 2 ]);\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t// Reuse newcache so results back-propagate to previous elements\n\t\t\t\t\t\t\touterCache[ dir ] = newCache;\n\n\t\t\t\t\t\t\t// A match means we're done; a fail means we have to keep checking\n\t\t\t\t\t\t\tif ( (newCache[ 2 ] = matcher( elem, context, xml )) ) {\n\t\t\t\t\t\t\t\treturn true;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t};\n}\n\nfunction elementMatcher( matchers ) {\n\treturn matchers.length > 1 ?\n\t\tfunction( elem, context, xml ) {\n\t\t\tvar i = matchers.length;\n\t\t\twhile ( i-- ) {\n\t\t\t\tif ( !matchers[i]( elem, context, xml ) ) {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn true;\n\t\t} :\n\t\tmatchers[0];\n}\n\nfunction multipleContexts( selector, contexts, results ) {\n\tvar i = 0,\n\t\tlen = contexts.length;\n\tfor ( ; i < len; i++ ) {\n\t\tSizzle( selector, contexts[i], results );\n\t}\n\treturn results;\n}\n\nfunction condense( unmatched, map, filter, context, xml ) {\n\tvar elem,\n\t\tnewUnmatched = [],\n\t\ti = 0,\n\t\tlen = unmatched.length,\n\t\tmapped = map != null;\n\n\tfor ( ; i < len; i++ ) {\n\t\tif ( (elem = unmatched[i]) ) {\n\t\t\tif ( !filter || filter( elem, context, xml ) ) {\n\t\t\t\tnewUnmatched.push( elem );\n\t\t\t\tif ( mapped ) {\n\t\t\t\t\tmap.push( i );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\treturn newUnmatched;\n}\n\nfunction setMatcher( preFilter, selector, matcher, postFilter, postFinder, postSelector ) {\n\tif ( postFilter && !postFilter[ expando ] ) {\n\t\tpostFilter = setMatcher( postFilter );\n\t}\n\tif ( postFinder && !postFinder[ expando ] ) {\n\t\tpostFinder = setMatcher( postFinder, postSelector );\n\t}\n\treturn markFunction(function( seed, results, context, xml ) {\n\t\tvar temp, i, elem,\n\t\t\tpreMap = [],\n\t\t\tpostMap = [],\n\t\t\tpreexisting = results.length,\n\n\t\t\t// Get initial elements from seed or context\n\t\t\telems = seed || multipleContexts( selector || \"*\", context.nodeType ? [ context ] : context, [] ),\n\n\t\t\t// Prefilter to get matcher input, preserving a map for seed-results synchronization\n\t\t\tmatcherIn = preFilter && ( seed || !selector ) ?\n\t\t\t\tcondense( elems, preMap, preFilter, context, xml ) :\n\t\t\t\telems,\n\n\t\t\tmatcherOut = matcher ?\n\t\t\t\t// If we have a postFinder, or filtered seed, or non-seed postFilter or preexisting results,\n\t\t\t\tpostFinder || ( seed ? preFilter : preexisting || postFilter ) ?\n\n\t\t\t\t\t// ...intermediate processing is necessary\n\t\t\t\t\t[] :\n\n\t\t\t\t\t// ...otherwise use results directly\n\t\t\t\t\tresults :\n\t\t\t\tmatcherIn;\n\n\t\t// Find primary matches\n\t\tif ( matcher ) {\n\t\t\tmatcher( matcherIn, matcherOut, context, xml );\n\t\t}\n\n\t\t// Apply postFilter\n\t\tif ( postFilter ) {\n\t\t\ttemp = condense( matcherOut, postMap );\n\t\t\tpostFilter( temp, [], context, xml );\n\n\t\t\t// Un-match failing elements by moving them back to matcherIn\n\t\t\ti = temp.length;\n\t\t\twhile ( i-- ) {\n\t\t\t\tif ( (elem = temp[i]) ) {\n\t\t\t\t\tmatcherOut[ postMap[i] ] = !(matcherIn[ postMap[i] ] = elem);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif ( seed ) {\n\t\t\tif ( postFinder || preFilter ) {\n\t\t\t\tif ( postFinder ) {\n\t\t\t\t\t// Get the final matcherOut by condensing this intermediate into postFinder contexts\n\t\t\t\t\ttemp = [];\n\t\t\t\t\ti = matcherOut.length;\n\t\t\t\t\twhile ( i-- ) {\n\t\t\t\t\t\tif ( (elem = matcherOut[i]) ) {\n\t\t\t\t\t\t\t// Restore matcherIn since elem is not yet a final match\n\t\t\t\t\t\t\ttemp.push( (matcherIn[i] = elem) );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tpostFinder( null, (matcherOut = []), temp, xml );\n\t\t\t\t}\n\n\t\t\t\t// Move matched elements from seed to results to keep them synchronized\n\t\t\t\ti = matcherOut.length;\n\t\t\t\twhile ( i-- ) {\n\t\t\t\t\tif ( (elem = matcherOut[i]) &&\n\t\t\t\t\t\t(temp = postFinder ? indexOf( seed, elem ) : preMap[i]) > -1 ) {\n\n\t\t\t\t\t\tseed[temp] = !(results[temp] = elem);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t// Add elements to results, through postFinder if defined\n\t\t} else {\n\t\t\tmatcherOut = condense(\n\t\t\t\tmatcherOut === results ?\n\t\t\t\t\tmatcherOut.splice( preexisting, matcherOut.length ) :\n\t\t\t\t\tmatcherOut\n\t\t\t);\n\t\t\tif ( postFinder ) {\n\t\t\t\tpostFinder( null, results, matcherOut, xml );\n\t\t\t} else {\n\t\t\t\tpush.apply( results, matcherOut );\n\t\t\t}\n\t\t}\n\t});\n}\n\nfunction matcherFromTokens( tokens ) {\n\tvar checkContext, matcher, j,\n\t\tlen = tokens.length,\n\t\tleadingRelative = Expr.relative[ tokens[0].type ],\n\t\timplicitRelative = leadingRelative || Expr.relative[\" \"],\n\t\ti = leadingRelative ? 1 : 0,\n\n\t\t// The foundational matcher ensures that elements are reachable from top-level context(s)\n\t\tmatchContext = addCombinator( function( elem ) {\n\t\t\treturn elem === checkContext;\n\t\t}, implicitRelative, true ),\n\t\tmatchAnyContext = addCombinator( function( elem ) {\n\t\t\treturn indexOf( checkContext, elem ) > -1;\n\t\t}, implicitRelative, true ),\n\t\tmatchers = [ function( elem, context, xml ) {\n\t\t\tvar ret = ( !leadingRelative && ( xml || context !== outermostContext ) ) || (\n\t\t\t\t(checkContext = context).nodeType ?\n\t\t\t\t\tmatchContext( elem, context, xml ) :\n\t\t\t\t\tmatchAnyContext( elem, context, xml ) );\n\t\t\t// Avoid hanging onto element (issue #299)\n\t\t\tcheckContext = null;\n\t\t\treturn ret;\n\t\t} ];\n\n\tfor ( ; i < len; i++ ) {\n\t\tif ( (matcher = Expr.relative[ tokens[i].type ]) ) {\n\t\t\tmatchers = [ addCombinator(elementMatcher( matchers ), matcher) ];\n\t\t} else {\n\t\t\tmatcher = Expr.filter[ tokens[i].type ].apply( null, tokens[i].matches );\n\n\t\t\t// Return special upon seeing a positional matcher\n\t\t\tif ( matcher[ expando ] ) {\n\t\t\t\t// Find the next relative operator (if any) for proper handling\n\t\t\t\tj = ++i;\n\t\t\t\tfor ( ; j < len; j++ ) {\n\t\t\t\t\tif ( Expr.relative[ tokens[j].type ] ) {\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn setMatcher(\n\t\t\t\t\ti > 1 && elementMatcher( matchers ),\n\t\t\t\t\ti > 1 && toSelector(\n\t\t\t\t\t\t// If the preceding token was a descendant combinator, insert an implicit any-element `*`\n\t\t\t\t\t\ttokens.slice( 0, i - 1 ).concat({ value: tokens[ i - 2 ].type === \" \" ? \"*\" : \"\" })\n\t\t\t\t\t).replace( rtrim, \"$1\" ),\n\t\t\t\t\tmatcher,\n\t\t\t\t\ti < j && matcherFromTokens( tokens.slice( i, j ) ),\n\t\t\t\t\tj < len && matcherFromTokens( (tokens = tokens.slice( j )) ),\n\t\t\t\t\tj < len && toSelector( tokens )\n\t\t\t\t);\n\t\t\t}\n\t\t\tmatchers.push( matcher );\n\t\t}\n\t}\n\n\treturn elementMatcher( matchers );\n}\n\nfunction matcherFromGroupMatchers( elementMatchers, setMatchers ) {\n\tvar bySet = setMatchers.length > 0,\n\t\tbyElement = elementMatchers.length > 0,\n\t\tsuperMatcher = function( seed, context, xml, results, outermost ) {\n\t\t\tvar elem, j, matcher,\n\t\t\t\tmatchedCount = 0,\n\t\t\t\ti = \"0\",\n\t\t\t\tunmatched = seed && [],\n\t\t\t\tsetMatched = [],\n\t\t\t\tcontextBackup = outermostContext,\n\t\t\t\t// We must always have either seed elements or outermost context\n\t\t\t\telems = seed || byElement && Expr.find[\"TAG\"]( \"*\", outermost ),\n\t\t\t\t// Use integer dirruns iff this is the outermost matcher\n\t\t\t\tdirrunsUnique = (dirruns += contextBackup == null ? 1 : Math.random() || 0.1),\n\t\t\t\tlen = elems.length;\n\n\t\t\tif ( outermost ) {\n\t\t\t\toutermostContext = context !== document && context;\n\t\t\t}\n\n\t\t\t// Add elements passing elementMatchers directly to results\n\t\t\t// Keep `i` a string if there are no elements so `matchedCount` will be \"00\" below\n\t\t\t// Support: IE<9, Safari\n\t\t\t// Tolerate NodeList properties (IE: \"length\"; Safari: <number>) matching elements by id\n\t\t\tfor ( ; i !== len && (elem = elems[i]) != null; i++ ) {\n\t\t\t\tif ( byElement && elem ) {\n\t\t\t\t\tj = 0;\n\t\t\t\t\twhile ( (matcher = elementMatchers[j++]) ) {\n\t\t\t\t\t\tif ( matcher( elem, context, xml ) ) {\n\t\t\t\t\t\t\tresults.push( elem );\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tif ( outermost ) {\n\t\t\t\t\t\tdirruns = dirrunsUnique;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// Track unmatched elements for set filters\n\t\t\t\tif ( bySet ) {\n\t\t\t\t\t// They will have gone through all possible matchers\n\t\t\t\t\tif ( (elem = !matcher && elem) ) {\n\t\t\t\t\t\tmatchedCount--;\n\t\t\t\t\t}\n\n\t\t\t\t\t// Lengthen the array for every element, matched or not\n\t\t\t\t\tif ( seed ) {\n\t\t\t\t\t\tunmatched.push( elem );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Apply set filters to unmatched elements\n\t\t\tmatchedCount += i;\n\t\t\tif ( bySet && i !== matchedCount ) {\n\t\t\t\tj = 0;\n\t\t\t\twhile ( (matcher = setMatchers[j++]) ) {\n\t\t\t\t\tmatcher( unmatched, setMatched, context, xml );\n\t\t\t\t}\n\n\t\t\t\tif ( seed ) {\n\t\t\t\t\t// Reintegrate element matches to eliminate the need for sorting\n\t\t\t\t\tif ( matchedCount > 0 ) {\n\t\t\t\t\t\twhile ( i-- ) {\n\t\t\t\t\t\t\tif ( !(unmatched[i] || setMatched[i]) ) {\n\t\t\t\t\t\t\t\tsetMatched[i] = pop.call( results );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\t// Discard index placeholder values to get only actual matches\n\t\t\t\t\tsetMatched = condense( setMatched );\n\t\t\t\t}\n\n\t\t\t\t// Add matches to results\n\t\t\t\tpush.apply( results, setMatched );\n\n\t\t\t\t// Seedless set matches succeeding multiple successful matchers stipulate sorting\n\t\t\t\tif ( outermost && !seed && setMatched.length > 0 &&\n\t\t\t\t\t( matchedCount + setMatchers.length ) > 1 ) {\n\n\t\t\t\t\tSizzle.uniqueSort( results );\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Override manipulation of globals by nested matchers\n\t\t\tif ( outermost ) {\n\t\t\t\tdirruns = dirrunsUnique;\n\t\t\t\toutermostContext = contextBackup;\n\t\t\t}\n\n\t\t\treturn unmatched;\n\t\t};\n\n\treturn bySet ?\n\t\tmarkFunction( superMatcher ) :\n\t\tsuperMatcher;\n}\n\ncompile = Sizzle.compile = function( selector, match /* Internal Use Only */ ) {\n\tvar i,\n\t\tsetMatchers = [],\n\t\telementMatchers = [],\n\t\tcached = compilerCache[ selector + \" \" ];\n\n\tif ( !cached ) {\n\t\t// Generate a function of recursive functions that can be used to check each element\n\t\tif ( !match ) {\n\t\t\tmatch = tokenize( selector );\n\t\t}\n\t\ti = match.length;\n\t\twhile ( i-- ) {\n\t\t\tcached = matcherFromTokens( match[i] );\n\t\t\tif ( cached[ expando ] ) {\n\t\t\t\tsetMatchers.push( cached );\n\t\t\t} else {\n\t\t\t\telementMatchers.push( cached );\n\t\t\t}\n\t\t}\n\n\t\t// Cache the compiled function\n\t\tcached = compilerCache( selector, matcherFromGroupMatchers( elementMatchers, setMatchers ) );\n\n\t\t// Save selector and tokenization\n\t\tcached.selector = selector;\n\t}\n\treturn cached;\n};\n\n/**\n * A low-level selection function that works with Sizzle's compiled\n *  selector functions\n * @param {String|Function} selector A selector or a pre-compiled\n *  selector function built with Sizzle.compile\n * @param {Element} context\n * @param {Array} [results]\n * @param {Array} [seed] A set of elements to match against\n */\nselect = Sizzle.select = function( selector, context, results, seed ) {\n\tvar i, tokens, token, type, find,\n\t\tcompiled = typeof selector === \"function\" && selector,\n\t\tmatch = !seed && tokenize( (selector = compiled.selector || selector) );\n\n\tresults = results || [];\n\n\t// Try to minimize operations if there is no seed and only one group\n\tif ( match.length === 1 ) {\n\n\t\t// Take a shortcut and set the context if the root selector is an ID\n\t\ttokens = match[0] = match[0].slice( 0 );\n\t\tif ( tokens.length > 2 && (token = tokens[0]).type === \"ID\" &&\n\t\t\t\tsupport.getById && context.nodeType === 9 && documentIsHTML &&\n\t\t\t\tExpr.relative[ tokens[1].type ] ) {\n\n\t\t\tcontext = ( Expr.find[\"ID\"]( token.matches[0].replace(runescape, funescape), context ) || [] )[0];\n\t\t\tif ( !context ) {\n\t\t\t\treturn results;\n\n\t\t\t// Precompiled matchers will still verify ancestry, so step up a level\n\t\t\t} else if ( compiled ) {\n\t\t\t\tcontext = context.parentNode;\n\t\t\t}\n\n\t\t\tselector = selector.slice( tokens.shift().value.length );\n\t\t}\n\n\t\t// Fetch a seed set for right-to-left matching\n\t\ti = matchExpr[\"needsContext\"].test( selector ) ? 0 : tokens.length;\n\t\twhile ( i-- ) {\n\t\t\ttoken = tokens[i];\n\n\t\t\t// Abort if we hit a combinator\n\t\t\tif ( Expr.relative[ (type = token.type) ] ) {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tif ( (find = Expr.find[ type ]) ) {\n\t\t\t\t// Search, expanding context for leading sibling combinators\n\t\t\t\tif ( (seed = find(\n\t\t\t\t\ttoken.matches[0].replace( runescape, funescape ),\n\t\t\t\t\trsibling.test( tokens[0].type ) && testContext( context.parentNode ) || context\n\t\t\t\t)) ) {\n\n\t\t\t\t\t// If seed is empty or no tokens remain, we can return early\n\t\t\t\t\ttokens.splice( i, 1 );\n\t\t\t\t\tselector = seed.length && toSelector( tokens );\n\t\t\t\t\tif ( !selector ) {\n\t\t\t\t\t\tpush.apply( results, seed );\n\t\t\t\t\t\treturn results;\n\t\t\t\t\t}\n\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t// Compile and execute a filtering function if one is not provided\n\t// Provide `match` to avoid retokenization if we modified the selector above\n\t( compiled || compile( selector, match ) )(\n\t\tseed,\n\t\tcontext,\n\t\t!documentIsHTML,\n\t\tresults,\n\t\trsibling.test( selector ) && testContext( context.parentNode ) || context\n\t);\n\treturn results;\n};\n\n// One-time assignments\n\n// Sort stability\nsupport.sortStable = expando.split(\"\").sort( sortOrder ).join(\"\") === expando;\n\n// Support: Chrome 14-35+\n// Always assume duplicates if they aren't passed to the comparison function\nsupport.detectDuplicates = !!hasDuplicate;\n\n// Initialize against the default document\nsetDocument();\n\n// Support: Webkit<537.32 - Safari 6.0.3/Chrome 25 (fixed in Chrome 27)\n// Detached nodes confoundingly follow *each other*\nsupport.sortDetached = assert(function( div1 ) {\n\t// Should return 1, but returns 4 (following)\n\treturn div1.compareDocumentPosition( document.createElement(\"div\") ) & 1;\n});\n\n// Support: IE<8\n// Prevent attribute/property \"interpolation\"\n// http://msdn.microsoft.com/en-us/library/ms536429%28VS.85%29.aspx\nif ( !assert(function( div ) {\n\tdiv.innerHTML = \"<a href='#'></a>\";\n\treturn div.firstChild.getAttribute(\"href\") === \"#\" ;\n}) ) {\n\taddHandle( \"type|href|height|width\", function( elem, name, isXML ) {\n\t\tif ( !isXML ) {\n\t\t\treturn elem.getAttribute( name, name.toLowerCase() === \"type\" ? 1 : 2 );\n\t\t}\n\t});\n}\n\n// Support: IE<9\n// Use defaultValue in place of getAttribute(\"value\")\nif ( !support.attributes || !assert(function( div ) {\n\tdiv.innerHTML = \"<input/>\";\n\tdiv.firstChild.setAttribute( \"value\", \"\" );\n\treturn div.firstChild.getAttribute( \"value\" ) === \"\";\n}) ) {\n\taddHandle( \"value\", function( elem, name, isXML ) {\n\t\tif ( !isXML && elem.nodeName.toLowerCase() === \"input\" ) {\n\t\t\treturn elem.defaultValue;\n\t\t}\n\t});\n}\n\n// Support: IE<9\n// Use getAttributeNode to fetch booleans when getAttribute lies\nif ( !assert(function( div ) {\n\treturn div.getAttribute(\"disabled\") == null;\n}) ) {\n\taddHandle( booleans, function( elem, name, isXML ) {\n\t\tvar val;\n\t\tif ( !isXML ) {\n\t\t\treturn elem[ name ] === true ? name.toLowerCase() :\n\t\t\t\t\t(val = elem.getAttributeNode( name )) && val.specified ?\n\t\t\t\t\tval.value :\n\t\t\t\tnull;\n\t\t}\n\t});\n}\n\nreturn Sizzle;\n\n})( window );\n\n\n\njQuery.find = Sizzle;\njQuery.expr = Sizzle.selectors;\njQuery.expr[\":\"] = jQuery.expr.pseudos;\njQuery.unique = Sizzle.uniqueSort;\njQuery.text = Sizzle.getText;\njQuery.isXMLDoc = Sizzle.isXML;\njQuery.contains = Sizzle.contains;\n\n\n\nvar rneedsContext = jQuery.expr.match.needsContext;\n\nvar rsingleTag = (/^<(\\w+)\\s*\\/?>(?:<\\/\\1>|)$/);\n\n\n\nvar risSimple = /^.[^:#\\[\\.,]*$/;\n\n// Implement the identical functionality for filter and not\nfunction winnow( elements, qualifier, not ) {\n\tif ( jQuery.isFunction( qualifier ) ) {\n\t\treturn jQuery.grep( elements, function( elem, i ) {\n\t\t\t/* jshint -W018 */\n\t\t\treturn !!qualifier.call( elem, i, elem ) !== not;\n\t\t});\n\n\t}\n\n\tif ( qualifier.nodeType ) {\n\t\treturn jQuery.grep( elements, function( elem ) {\n\t\t\treturn ( elem === qualifier ) !== not;\n\t\t});\n\n\t}\n\n\tif ( typeof qualifier === \"string\" ) {\n\t\tif ( risSimple.test( qualifier ) ) {\n\t\t\treturn jQuery.filter( qualifier, elements, not );\n\t\t}\n\n\t\tqualifier = jQuery.filter( qualifier, elements );\n\t}\n\n\treturn jQuery.grep( elements, function( elem ) {\n\t\treturn ( jQuery.inArray( elem, qualifier ) >= 0 ) !== not;\n\t});\n}\n\njQuery.filter = function( expr, elems, not ) {\n\tvar elem = elems[ 0 ];\n\n\tif ( not ) {\n\t\texpr = \":not(\" + expr + \")\";\n\t}\n\n\treturn elems.length === 1 && elem.nodeType === 1 ?\n\t\tjQuery.find.matchesSelector( elem, expr ) ? [ elem ] : [] :\n\t\tjQuery.find.matches( expr, jQuery.grep( elems, function( elem ) {\n\t\t\treturn elem.nodeType === 1;\n\t\t}));\n};\n\njQuery.fn.extend({\n\tfind: function( selector ) {\n\t\tvar i,\n\t\t\tret = [],\n\t\t\tself = this,\n\t\t\tlen = self.length;\n\n\t\tif ( typeof selector !== \"string\" ) {\n\t\t\treturn this.pushStack( jQuery( selector ).filter(function() {\n\t\t\t\tfor ( i = 0; i < len; i++ ) {\n\t\t\t\t\tif ( jQuery.contains( self[ i ], this ) ) {\n\t\t\t\t\t\treturn true;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}) );\n\t\t}\n\n\t\tfor ( i = 0; i < len; i++ ) {\n\t\t\tjQuery.find( selector, self[ i ], ret );\n\t\t}\n\n\t\t// Needed because $( selector, context ) becomes $( context ).find( selector )\n\t\tret = this.pushStack( len > 1 ? jQuery.unique( ret ) : ret );\n\t\tret.selector = this.selector ? this.selector + \" \" + selector : selector;\n\t\treturn ret;\n\t},\n\tfilter: function( selector ) {\n\t\treturn this.pushStack( winnow(this, selector || [], false) );\n\t},\n\tnot: function( selector ) {\n\t\treturn this.pushStack( winnow(this, selector || [], true) );\n\t},\n\tis: function( selector ) {\n\t\treturn !!winnow(\n\t\t\tthis,\n\n\t\t\t// If this is a positional/relative selector, check membership in the returned set\n\t\t\t// so $(\"p:first\").is(\"p:last\") won't return true for a doc with two \"p\".\n\t\t\ttypeof selector === \"string\" && rneedsContext.test( selector ) ?\n\t\t\t\tjQuery( selector ) :\n\t\t\t\tselector || [],\n\t\t\tfalse\n\t\t).length;\n\t}\n});\n\n\n// Initialize a jQuery object\n\n\n// A central reference to the root jQuery(document)\nvar rootjQuery,\n\n\t// Use the correct document accordingly with window argument (sandbox)\n\tdocument = window.document,\n\n\t// A simple way to check for HTML strings\n\t// Prioritize #id over <tag> to avoid XSS via location.hash (#9521)\n\t// Strict HTML recognition (#11290: must start with <)\n\trquickExpr = /^(?:\\s*(<[\\w\\W]+>)[^>]*|#([\\w-]*))$/,\n\n\tinit = jQuery.fn.init = function( selector, context ) {\n\t\tvar match, elem;\n\n\t\t// HANDLE: $(\"\"), $(null), $(undefined), $(false)\n\t\tif ( !selector ) {\n\t\t\treturn this;\n\t\t}\n\n\t\t// Handle HTML strings\n\t\tif ( typeof selector === \"string\" ) {\n\t\t\tif ( selector.charAt(0) === \"<\" && selector.charAt( selector.length - 1 ) === \">\" && selector.length >= 3 ) {\n\t\t\t\t// Assume that strings that start and end with <> are HTML and skip the regex check\n\t\t\t\tmatch = [ null, selector, null ];\n\n\t\t\t} else {\n\t\t\t\tmatch = rquickExpr.exec( selector );\n\t\t\t}\n\n\t\t\t// Match html or make sure no context is specified for #id\n\t\t\tif ( match && (match[1] || !context) ) {\n\n\t\t\t\t// HANDLE: $(html) -> $(array)\n\t\t\t\tif ( match[1] ) {\n\t\t\t\t\tcontext = context instanceof jQuery ? context[0] : context;\n\n\t\t\t\t\t// scripts is true for back-compat\n\t\t\t\t\t// Intentionally let the error be thrown if parseHTML is not present\n\t\t\t\t\tjQuery.merge( this, jQuery.parseHTML(\n\t\t\t\t\t\tmatch[1],\n\t\t\t\t\t\tcontext && context.nodeType ? context.ownerDocument || context : document,\n\t\t\t\t\t\ttrue\n\t\t\t\t\t) );\n\n\t\t\t\t\t// HANDLE: $(html, props)\n\t\t\t\t\tif ( rsingleTag.test( match[1] ) && jQuery.isPlainObject( context ) ) {\n\t\t\t\t\t\tfor ( match in context ) {\n\t\t\t\t\t\t\t// Properties of context are called as methods if possible\n\t\t\t\t\t\t\tif ( jQuery.isFunction( this[ match ] ) ) {\n\t\t\t\t\t\t\t\tthis[ match ]( context[ match ] );\n\n\t\t\t\t\t\t\t// ...and otherwise set as attributes\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tthis.attr( match, context[ match ] );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\treturn this;\n\n\t\t\t\t// HANDLE: $(#id)\n\t\t\t\t} else {\n\t\t\t\t\telem = document.getElementById( match[2] );\n\n\t\t\t\t\t// Check parentNode to catch when Blackberry 4.6 returns\n\t\t\t\t\t// nodes that are no longer in the document #6963\n\t\t\t\t\tif ( elem && elem.parentNode ) {\n\t\t\t\t\t\t// Handle the case where IE and Opera return items\n\t\t\t\t\t\t// by name instead of ID\n\t\t\t\t\t\tif ( elem.id !== match[2] ) {\n\t\t\t\t\t\t\treturn rootjQuery.find( selector );\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// Otherwise, we inject the element directly into the jQuery object\n\t\t\t\t\t\tthis.length = 1;\n\t\t\t\t\t\tthis[0] = elem;\n\t\t\t\t\t}\n\n\t\t\t\t\tthis.context = document;\n\t\t\t\t\tthis.selector = selector;\n\t\t\t\t\treturn this;\n\t\t\t\t}\n\n\t\t\t// HANDLE: $(expr, $(...))\n\t\t\t} else if ( !context || context.jquery ) {\n\t\t\t\treturn ( context || rootjQuery ).find( selector );\n\n\t\t\t// HANDLE: $(expr, context)\n\t\t\t// (which is just equivalent to: $(context).find(expr)\n\t\t\t} else {\n\t\t\t\treturn this.constructor( context ).find( selector );\n\t\t\t}\n\n\t\t// HANDLE: $(DOMElement)\n\t\t} else if ( selector.nodeType ) {\n\t\t\tthis.context = this[0] = selector;\n\t\t\tthis.length = 1;\n\t\t\treturn this;\n\n\t\t// HANDLE: $(function)\n\t\t// Shortcut for document ready\n\t\t} else if ( jQuery.isFunction( selector ) ) {\n\t\t\treturn typeof rootjQuery.ready !== \"undefined\" ?\n\t\t\t\trootjQuery.ready( selector ) :\n\t\t\t\t// Execute immediately if ready is not present\n\t\t\t\tselector( jQuery );\n\t\t}\n\n\t\tif ( selector.selector !== undefined ) {\n\t\t\tthis.selector = selector.selector;\n\t\t\tthis.context = selector.context;\n\t\t}\n\n\t\treturn jQuery.makeArray( selector, this );\n\t};\n\n// Give the init function the jQuery prototype for later instantiation\ninit.prototype = jQuery.fn;\n\n// Initialize central reference\nrootjQuery = jQuery( document );\n\n\nvar rparentsprev = /^(?:parents|prev(?:Until|All))/,\n\t// methods guaranteed to produce a unique set when starting from a unique set\n\tguaranteedUnique = {\n\t\tchildren: true,\n\t\tcontents: true,\n\t\tnext: true,\n\t\tprev: true\n\t};\n\njQuery.extend({\n\tdir: function( elem, dir, until ) {\n\t\tvar matched = [],\n\t\t\tcur = elem[ dir ];\n\n\t\twhile ( cur && cur.nodeType !== 9 && (until === undefined || cur.nodeType !== 1 || !jQuery( cur ).is( until )) ) {\n\t\t\tif ( cur.nodeType === 1 ) {\n\t\t\t\tmatched.push( cur );\n\t\t\t}\n\t\t\tcur = cur[dir];\n\t\t}\n\t\treturn matched;\n\t},\n\n\tsibling: function( n, elem ) {\n\t\tvar r = [];\n\n\t\tfor ( ; n; n = n.nextSibling ) {\n\t\t\tif ( n.nodeType === 1 && n !== elem ) {\n\t\t\t\tr.push( n );\n\t\t\t}\n\t\t}\n\n\t\treturn r;\n\t}\n});\n\njQuery.fn.extend({\n\thas: function( target ) {\n\t\tvar i,\n\t\t\ttargets = jQuery( target, this ),\n\t\t\tlen = targets.length;\n\n\t\treturn this.filter(function() {\n\t\t\tfor ( i = 0; i < len; i++ ) {\n\t\t\t\tif ( jQuery.contains( this, targets[i] ) ) {\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\t},\n\n\tclosest: function( selectors, context ) {\n\t\tvar cur,\n\t\t\ti = 0,\n\t\t\tl = this.length,\n\t\t\tmatched = [],\n\t\t\tpos = rneedsContext.test( selectors ) || typeof selectors !== \"string\" ?\n\t\t\t\tjQuery( selectors, context || this.context ) :\n\t\t\t\t0;\n\n\t\tfor ( ; i < l; i++ ) {\n\t\t\tfor ( cur = this[i]; cur && cur !== context; cur = cur.parentNode ) {\n\t\t\t\t// Always skip document fragments\n\t\t\t\tif ( cur.nodeType < 11 && (pos ?\n\t\t\t\t\tpos.index(cur) > -1 :\n\n\t\t\t\t\t// Don't pass non-elements to Sizzle\n\t\t\t\t\tcur.nodeType === 1 &&\n\t\t\t\t\t\tjQuery.find.matchesSelector(cur, selectors)) ) {\n\n\t\t\t\t\tmatched.push( cur );\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn this.pushStack( matched.length > 1 ? jQuery.unique( matched ) : matched );\n\t},\n\n\t// Determine the position of an element within\n\t// the matched set of elements\n\tindex: function( elem ) {\n\n\t\t// No argument, return index in parent\n\t\tif ( !elem ) {\n\t\t\treturn ( this[0] && this[0].parentNode ) ? this.first().prevAll().length : -1;\n\t\t}\n\n\t\t// index in selector\n\t\tif ( typeof elem === \"string\" ) {\n\t\t\treturn jQuery.inArray( this[0], jQuery( elem ) );\n\t\t}\n\n\t\t// Locate the position of the desired element\n\t\treturn jQuery.inArray(\n\t\t\t// If it receives a jQuery object, the first element is used\n\t\t\telem.jquery ? elem[0] : elem, this );\n\t},\n\n\tadd: function( selector, context ) {\n\t\treturn this.pushStack(\n\t\t\tjQuery.unique(\n\t\t\t\tjQuery.merge( this.get(), jQuery( selector, context ) )\n\t\t\t)\n\t\t);\n\t},\n\n\taddBack: function( selector ) {\n\t\treturn this.add( selector == null ?\n\t\t\tthis.prevObject : this.prevObject.filter(selector)\n\t\t);\n\t}\n});\n\nfunction sibling( cur, dir ) {\n\tdo {\n\t\tcur = cur[ dir ];\n\t} while ( cur && cur.nodeType !== 1 );\n\n\treturn cur;\n}\n\njQuery.each({\n\tparent: function( elem ) {\n\t\tvar parent = elem.parentNode;\n\t\treturn parent && parent.nodeType !== 11 ? parent : null;\n\t},\n\tparents: function( elem ) {\n\t\treturn jQuery.dir( elem, \"parentNode\" );\n\t},\n\tparentsUntil: function( elem, i, until ) {\n\t\treturn jQuery.dir( elem, \"parentNode\", until );\n\t},\n\tnext: function( elem ) {\n\t\treturn sibling( elem, \"nextSibling\" );\n\t},\n\tprev: function( elem ) {\n\t\treturn sibling( elem, \"previousSibling\" );\n\t},\n\tnextAll: function( elem ) {\n\t\treturn jQuery.dir( elem, \"nextSibling\" );\n\t},\n\tprevAll: function( elem ) {\n\t\treturn jQuery.dir( elem, \"previousSibling\" );\n\t},\n\tnextUntil: function( elem, i, until ) {\n\t\treturn jQuery.dir( elem, \"nextSibling\", until );\n\t},\n\tprevUntil: function( elem, i, until ) {\n\t\treturn jQuery.dir( elem, \"previousSibling\", until );\n\t},\n\tsiblings: function( elem ) {\n\t\treturn jQuery.sibling( ( elem.parentNode || {} ).firstChild, elem );\n\t},\n\tchildren: function( elem ) {\n\t\treturn jQuery.sibling( elem.firstChild );\n\t},\n\tcontents: function( elem ) {\n\t\treturn jQuery.nodeName( elem, \"iframe\" ) ?\n\t\t\telem.contentDocument || elem.contentWindow.document :\n\t\t\tjQuery.merge( [], elem.childNodes );\n\t}\n}, function( name, fn ) {\n\tjQuery.fn[ name ] = function( until, selector ) {\n\t\tvar ret = jQuery.map( this, fn, until );\n\n\t\tif ( name.slice( -5 ) !== \"Until\" ) {\n\t\t\tselector = until;\n\t\t}\n\n\t\tif ( selector && typeof selector === \"string\" ) {\n\t\t\tret = jQuery.filter( selector, ret );\n\t\t}\n\n\t\tif ( this.length > 1 ) {\n\t\t\t// Remove duplicates\n\t\t\tif ( !guaranteedUnique[ name ] ) {\n\t\t\t\tret = jQuery.unique( ret );\n\t\t\t}\n\n\t\t\t// Reverse order for parents* and prev-derivatives\n\t\t\tif ( rparentsprev.test( name ) ) {\n\t\t\t\tret = ret.reverse();\n\t\t\t}\n\t\t}\n\n\t\treturn this.pushStack( ret );\n\t};\n});\nvar rnotwhite = (/\\S+/g);\n\n\n\n// String to Object options format cache\nvar optionsCache = {};\n\n// Convert String-formatted options into Object-formatted ones and store in cache\nfunction createOptions( options ) {\n\tvar object = optionsCache[ options ] = {};\n\tjQuery.each( options.match( rnotwhite ) || [], function( _, flag ) {\n\t\tobject[ flag ] = true;\n\t});\n\treturn object;\n}\n\n/*\n * Create a callback list using the following parameters:\n *\n *\toptions: an optional list of space-separated options that will change how\n *\t\t\tthe callback list behaves or a more traditional option object\n *\n * By default a callback list will act like an event callback list and can be\n * \"fired\" multiple times.\n *\n * Possible options:\n *\n *\tonce:\t\t\twill ensure the callback list can only be fired once (like a Deferred)\n *\n *\tmemory:\t\t\twill keep track of previous values and will call any callback added\n *\t\t\t\t\tafter the list has been fired right away with the latest \"memorized\"\n *\t\t\t\t\tvalues (like a Deferred)\n *\n *\tunique:\t\t\twill ensure a callback can only be added once (no duplicate in the list)\n *\n *\tstopOnFalse:\tinterrupt callings when a callback returns false\n *\n */\njQuery.Callbacks = function( options ) {\n\n\t// Convert options from String-formatted to Object-formatted if needed\n\t// (we check in cache first)\n\toptions = typeof options === \"string\" ?\n\t\t( optionsCache[ options ] || createOptions( options ) ) :\n\t\tjQuery.extend( {}, options );\n\n\tvar // Flag to know if list is currently firing\n\t\tfiring,\n\t\t// Last fire value (for non-forgettable lists)\n\t\tmemory,\n\t\t// Flag to know if list was already fired\n\t\tfired,\n\t\t// End of the loop when firing\n\t\tfiringLength,\n\t\t// Index of currently firing callback (modified by remove if needed)\n\t\tfiringIndex,\n\t\t// First callback to fire (used internally by add and fireWith)\n\t\tfiringStart,\n\t\t// Actual callback list\n\t\tlist = [],\n\t\t// Stack of fire calls for repeatable lists\n\t\tstack = !options.once && [],\n\t\t// Fire callbacks\n\t\tfire = function( data ) {\n\t\t\tmemory = options.memory && data;\n\t\t\tfired = true;\n\t\t\tfiringIndex = firingStart || 0;\n\t\t\tfiringStart = 0;\n\t\t\tfiringLength = list.length;\n\t\t\tfiring = true;\n\t\t\tfor ( ; list && firingIndex < firingLength; firingIndex++ ) {\n\t\t\t\tif ( list[ firingIndex ].apply( data[ 0 ], data[ 1 ] ) === false && options.stopOnFalse ) {\n\t\t\t\t\tmemory = false; // To prevent further calls using add\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t\tfiring = false;\n\t\t\tif ( list ) {\n\t\t\t\tif ( stack ) {\n\t\t\t\t\tif ( stack.length ) {\n\t\t\t\t\t\tfire( stack.shift() );\n\t\t\t\t\t}\n\t\t\t\t} else if ( memory ) {\n\t\t\t\t\tlist = [];\n\t\t\t\t} else {\n\t\t\t\t\tself.disable();\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\t// Actual Callbacks object\n\t\tself = {\n\t\t\t// Add a callback or a collection of callbacks to the list\n\t\t\tadd: function() {\n\t\t\t\tif ( list ) {\n\t\t\t\t\t// First, we save the current length\n\t\t\t\t\tvar start = list.length;\n\t\t\t\t\t(function add( args ) {\n\t\t\t\t\t\tjQuery.each( args, function( _, arg ) {\n\t\t\t\t\t\t\tvar type = jQuery.type( arg );\n\t\t\t\t\t\t\tif ( type === \"function\" ) {\n\t\t\t\t\t\t\t\tif ( !options.unique || !self.has( arg ) ) {\n\t\t\t\t\t\t\t\t\tlist.push( arg );\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t} else if ( arg && arg.length && type !== \"string\" ) {\n\t\t\t\t\t\t\t\t// Inspect recursively\n\t\t\t\t\t\t\t\tadd( arg );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t});\n\t\t\t\t\t})( arguments );\n\t\t\t\t\t// Do we need to add the callbacks to the\n\t\t\t\t\t// current firing batch?\n\t\t\t\t\tif ( firing ) {\n\t\t\t\t\t\tfiringLength = list.length;\n\t\t\t\t\t// With memory, if we're not firing then\n\t\t\t\t\t// we should call right away\n\t\t\t\t\t} else if ( memory ) {\n\t\t\t\t\t\tfiringStart = start;\n\t\t\t\t\t\tfire( memory );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn this;\n\t\t\t},\n\t\t\t// Remove a callback from the list\n\t\t\tremove: function() {\n\t\t\t\tif ( list ) {\n\t\t\t\t\tjQuery.each( arguments, function( _, arg ) {\n\t\t\t\t\t\tvar index;\n\t\t\t\t\t\twhile ( ( index = jQuery.inArray( arg, list, index ) ) > -1 ) {\n\t\t\t\t\t\t\tlist.splice( index, 1 );\n\t\t\t\t\t\t\t// Handle firing indexes\n\t\t\t\t\t\t\tif ( firing ) {\n\t\t\t\t\t\t\t\tif ( index <= firingLength ) {\n\t\t\t\t\t\t\t\t\tfiringLength--;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tif ( index <= firingIndex ) {\n\t\t\t\t\t\t\t\t\tfiringIndex--;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t\treturn this;\n\t\t\t},\n\t\t\t// Check if a given callback is in the list.\n\t\t\t// If no argument is given, return whether or not list has callbacks attached.\n\t\t\thas: function( fn ) {\n\t\t\t\treturn fn ? jQuery.inArray( fn, list ) > -1 : !!( list && list.length );\n\t\t\t},\n\t\t\t// Remove all callbacks from the list\n\t\t\tempty: function() {\n\t\t\t\tlist = [];\n\t\t\t\tfiringLength = 0;\n\t\t\t\treturn this;\n\t\t\t},\n\t\t\t// Have the list do nothing anymore\n\t\t\tdisable: function() {\n\t\t\t\tlist = stack = memory = undefined;\n\t\t\t\treturn this;\n\t\t\t},\n\t\t\t// Is it disabled?\n\t\t\tdisabled: function() {\n\t\t\t\treturn !list;\n\t\t\t},\n\t\t\t// Lock the list in its current state\n\t\t\tlock: function() {\n\t\t\t\tstack = undefined;\n\t\t\t\tif ( !memory ) {\n\t\t\t\t\tself.disable();\n\t\t\t\t}\n\t\t\t\treturn this;\n\t\t\t},\n\t\t\t// Is it locked?\n\t\t\tlocked: function() {\n\t\t\t\treturn !stack;\n\t\t\t},\n\t\t\t// Call all callbacks with the given context and arguments\n\t\t\tfireWith: function( context, args ) {\n\t\t\t\tif ( list && ( !fired || stack ) ) {\n\t\t\t\t\targs = args || [];\n\t\t\t\t\targs = [ context, args.slice ? args.slice() : args ];\n\t\t\t\t\tif ( firing ) {\n\t\t\t\t\t\tstack.push( args );\n\t\t\t\t\t} else {\n\t\t\t\t\t\tfire( args );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn this;\n\t\t\t},\n\t\t\t// Call all the callbacks with the given arguments\n\t\t\tfire: function() {\n\t\t\t\tself.fireWith( this, arguments );\n\t\t\t\treturn this;\n\t\t\t},\n\t\t\t// To know if the callbacks have already been called at least once\n\t\t\tfired: function() {\n\t\t\t\treturn !!fired;\n\t\t\t}\n\t\t};\n\n\treturn self;\n};\n\n\njQuery.extend({\n\n\tDeferred: function( func ) {\n\t\tvar tuples = [\n\t\t\t\t// action, add listener, listener list, final state\n\t\t\t\t[ \"resolve\", \"done\", jQuery.Callbacks(\"once memory\"), \"resolved\" ],\n\t\t\t\t[ \"reject\", \"fail\", jQuery.Callbacks(\"once memory\"), \"rejected\" ],\n\t\t\t\t[ \"notify\", \"progress\", jQuery.Callbacks(\"memory\") ]\n\t\t\t],\n\t\t\tstate = \"pending\",\n\t\t\tpromise = {\n\t\t\t\tstate: function() {\n\t\t\t\t\treturn state;\n\t\t\t\t},\n\t\t\t\talways: function() {\n\t\t\t\t\tdeferred.done( arguments ).fail( arguments );\n\t\t\t\t\treturn this;\n\t\t\t\t},\n\t\t\t\tthen: function( /* fnDone, fnFail, fnProgress */ ) {\n\t\t\t\t\tvar fns = arguments;\n\t\t\t\t\treturn jQuery.Deferred(function( newDefer ) {\n\t\t\t\t\t\tjQuery.each( tuples, function( i, tuple ) {\n\t\t\t\t\t\t\tvar fn = jQuery.isFunction( fns[ i ] ) && fns[ i ];\n\t\t\t\t\t\t\t// deferred[ done | fail | progress ] for forwarding actions to newDefer\n\t\t\t\t\t\t\tdeferred[ tuple[1] ](function() {\n\t\t\t\t\t\t\t\tvar returned = fn && fn.apply( this, arguments );\n\t\t\t\t\t\t\t\tif ( returned && jQuery.isFunction( returned.promise ) ) {\n\t\t\t\t\t\t\t\t\treturned.promise()\n\t\t\t\t\t\t\t\t\t\t.done( newDefer.resolve )\n\t\t\t\t\t\t\t\t\t\t.fail( newDefer.reject )\n\t\t\t\t\t\t\t\t\t\t.progress( newDefer.notify );\n\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\tnewDefer[ tuple[ 0 ] + \"With\" ]( this === promise ? newDefer.promise() : this, fn ? [ returned ] : arguments );\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t});\n\t\t\t\t\t\tfns = null;\n\t\t\t\t\t}).promise();\n\t\t\t\t},\n\t\t\t\t// Get a promise for this deferred\n\t\t\t\t// If obj is provided, the promise aspect is added to the object\n\t\t\t\tpromise: function( obj ) {\n\t\t\t\t\treturn obj != null ? jQuery.extend( obj, promise ) : promise;\n\t\t\t\t}\n\t\t\t},\n\t\t\tdeferred = {};\n\n\t\t// Keep pipe for back-compat\n\t\tpromise.pipe = promise.then;\n\n\t\t// Add list-specific methods\n\t\tjQuery.each( tuples, function( i, tuple ) {\n\t\t\tvar list = tuple[ 2 ],\n\t\t\t\tstateString = tuple[ 3 ];\n\n\t\t\t// promise[ done | fail | progress ] = list.add\n\t\t\tpromise[ tuple[1] ] = list.add;\n\n\t\t\t// Handle state\n\t\t\tif ( stateString ) {\n\t\t\t\tlist.add(function() {\n\t\t\t\t\t// state = [ resolved | rejected ]\n\t\t\t\t\tstate = stateString;\n\n\t\t\t\t// [ reject_list | resolve_list ].disable; progress_list.lock\n\t\t\t\t}, tuples[ i ^ 1 ][ 2 ].disable, tuples[ 2 ][ 2 ].lock );\n\t\t\t}\n\n\t\t\t// deferred[ resolve | reject | notify ]\n\t\t\tdeferred[ tuple[0] ] = function() {\n\t\t\t\tdeferred[ tuple[0] + \"With\" ]( this === deferred ? promise : this, arguments );\n\t\t\t\treturn this;\n\t\t\t};\n\t\t\tdeferred[ tuple[0] + \"With\" ] = list.fireWith;\n\t\t});\n\n\t\t// Make the deferred a promise\n\t\tpromise.promise( deferred );\n\n\t\t// Call given func if any\n\t\tif ( func ) {\n\t\t\tfunc.call( deferred, deferred );\n\t\t}\n\n\t\t// All done!\n\t\treturn deferred;\n\t},\n\n\t// Deferred helper\n\twhen: function( subordinate /* , ..., subordinateN */ ) {\n\t\tvar i = 0,\n\t\t\tresolveValues = slice.call( arguments ),\n\t\t\tlength = resolveValues.length,\n\n\t\t\t// the count of uncompleted subordinates\n\t\t\tremaining = length !== 1 || ( subordinate && jQuery.isFunction( subordinate.promise ) ) ? length : 0,\n\n\t\t\t// the master Deferred. If resolveValues consist of only a single Deferred, just use that.\n\t\t\tdeferred = remaining === 1 ? subordinate : jQuery.Deferred(),\n\n\t\t\t// Update function for both resolve and progress values\n\t\t\tupdateFunc = function( i, contexts, values ) {\n\t\t\t\treturn function( value ) {\n\t\t\t\t\tcontexts[ i ] = this;\n\t\t\t\t\tvalues[ i ] = arguments.length > 1 ? slice.call( arguments ) : value;\n\t\t\t\t\tif ( values === progressValues ) {\n\t\t\t\t\t\tdeferred.notifyWith( contexts, values );\n\n\t\t\t\t\t} else if ( !(--remaining) ) {\n\t\t\t\t\t\tdeferred.resolveWith( contexts, values );\n\t\t\t\t\t}\n\t\t\t\t};\n\t\t\t},\n\n\t\t\tprogressValues, progressContexts, resolveContexts;\n\n\t\t// add listeners to Deferred subordinates; treat others as resolved\n\t\tif ( length > 1 ) {\n\t\t\tprogressValues = new Array( length );\n\t\t\tprogressContexts = new Array( length );\n\t\t\tresolveContexts = new Array( length );\n\t\t\tfor ( ; i < length; i++ ) {\n\t\t\t\tif ( resolveValues[ i ] && jQuery.isFunction( resolveValues[ i ].promise ) ) {\n\t\t\t\t\tresolveValues[ i ].promise()\n\t\t\t\t\t\t.done( updateFunc( i, resolveContexts, resolveValues ) )\n\t\t\t\t\t\t.fail( deferred.reject )\n\t\t\t\t\t\t.progress( updateFunc( i, progressContexts, progressValues ) );\n\t\t\t\t} else {\n\t\t\t\t\t--remaining;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// if we're not waiting on anything, resolve the master\n\t\tif ( !remaining ) {\n\t\t\tdeferred.resolveWith( resolveContexts, resolveValues );\n\t\t}\n\n\t\treturn deferred.promise();\n\t}\n});\n\n\n// The deferred used on DOM ready\nvar readyList;\n\njQuery.fn.ready = function( fn ) {\n\t// Add the callback\n\tjQuery.ready.promise().done( fn );\n\n\treturn this;\n};\n\njQuery.extend({\n\t// Is the DOM ready to be used? Set to true once it occurs.\n\tisReady: false,\n\n\t// A counter to track how many items to wait for before\n\t// the ready event fires. See #6781\n\treadyWait: 1,\n\n\t// Hold (or release) the ready event\n\tholdReady: function( hold ) {\n\t\tif ( hold ) {\n\t\t\tjQuery.readyWait++;\n\t\t} else {\n\t\t\tjQuery.ready( true );\n\t\t}\n\t},\n\n\t// Handle when the DOM is ready\n\tready: function( wait ) {\n\n\t\t// Abort if there are pending holds or we're already ready\n\t\tif ( wait === true ? --jQuery.readyWait : jQuery.isReady ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443).\n\t\tif ( !document.body ) {\n\t\t\treturn setTimeout( jQuery.ready );\n\t\t}\n\n\t\t// Remember that the DOM is ready\n\t\tjQuery.isReady = true;\n\n\t\t// If a normal DOM Ready event fired, decrement, and wait if need be\n\t\tif ( wait !== true && --jQuery.readyWait > 0 ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// If there are functions bound, to execute\n\t\treadyList.resolveWith( document, [ jQuery ] );\n\n\t\t// Trigger any bound ready events\n\t\tif ( jQuery.fn.triggerHandler ) {\n\t\t\tjQuery( document ).triggerHandler( \"ready\" );\n\t\t\tjQuery( document ).off( \"ready\" );\n\t\t}\n\t}\n});\n\n/**\n * Clean-up method for dom ready events\n */\nfunction detach() {\n\tif ( document.addEventListener ) {\n\t\tdocument.removeEventListener( \"DOMContentLoaded\", completed, false );\n\t\twindow.removeEventListener( \"load\", completed, false );\n\n\t} else {\n\t\tdocument.detachEvent( \"onreadystatechange\", completed );\n\t\twindow.detachEvent( \"onload\", completed );\n\t}\n}\n\n/**\n * The ready event handler and self cleanup method\n */\nfunction completed() {\n\t// readyState === \"complete\" is good enough for us to call the dom ready in oldIE\n\tif ( document.addEventListener || event.type === \"load\" || document.readyState === \"complete\" ) {\n\t\tdetach();\n\t\tjQuery.ready();\n\t}\n}\n\njQuery.ready.promise = function( obj ) {\n\tif ( !readyList ) {\n\n\t\treadyList = jQuery.Deferred();\n\n\t\t// Catch cases where $(document).ready() is called after the browser event has already occurred.\n\t\t// we once tried to use readyState \"interactive\" here, but it caused issues like the one\n\t\t// discovered by ChrisS here: http://bugs.jquery.com/ticket/12282#comment:15\n\t\tif ( document.readyState === \"complete\" ) {\n\t\t\t// Handle it asynchronously to allow scripts the opportunity to delay ready\n\t\t\tsetTimeout( jQuery.ready );\n\n\t\t// Standards-based browsers support DOMContentLoaded\n\t\t} else if ( document.addEventListener ) {\n\t\t\t// Use the handy event callback\n\t\t\tdocument.addEventListener( \"DOMContentLoaded\", completed, false );\n\n\t\t\t// A fallback to window.onload, that will always work\n\t\t\twindow.addEventListener( \"load\", completed, false );\n\n\t\t// If IE event model is used\n\t\t} else {\n\t\t\t// Ensure firing before onload, maybe late but safe also for iframes\n\t\t\tdocument.attachEvent( \"onreadystatechange\", completed );\n\n\t\t\t// A fallback to window.onload, that will always work\n\t\t\twindow.attachEvent( \"onload\", completed );\n\n\t\t\t// If IE and not a frame\n\t\t\t// continually check to see if the document is ready\n\t\t\tvar top = false;\n\n\t\t\ttry {\n\t\t\t\ttop = window.frameElement == null && document.documentElement;\n\t\t\t} catch(e) {}\n\n\t\t\tif ( top && top.doScroll ) {\n\t\t\t\t(function doScrollCheck() {\n\t\t\t\t\tif ( !jQuery.isReady ) {\n\n\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t// Use the trick by Diego Perini\n\t\t\t\t\t\t\t// http://javascript.nwbox.com/IEContentLoaded/\n\t\t\t\t\t\t\ttop.doScroll(\"left\");\n\t\t\t\t\t\t} catch(e) {\n\t\t\t\t\t\t\treturn setTimeout( doScrollCheck, 50 );\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// detach all dom ready events\n\t\t\t\t\t\tdetach();\n\n\t\t\t\t\t\t// and execute any waiting functions\n\t\t\t\t\t\tjQuery.ready();\n\t\t\t\t\t}\n\t\t\t\t})();\n\t\t\t}\n\t\t}\n\t}\n\treturn readyList.promise( obj );\n};\n\n\nvar strundefined = typeof undefined;\n\n\n\n// Support: IE<9\n// Iteration over object's inherited properties before its own\nvar i;\nfor ( i in jQuery( support ) ) {\n\tbreak;\n}\nsupport.ownLast = i !== \"0\";\n\n// Note: most support tests are defined in their respective modules.\n// false until the test is run\nsupport.inlineBlockNeedsLayout = false;\n\n// Execute ASAP in case we need to set body.style.zoom\njQuery(function() {\n\t// Minified: var a,b,c,d\n\tvar val, div, body, container;\n\n\tbody = document.getElementsByTagName( \"body\" )[ 0 ];\n\tif ( !body || !body.style ) {\n\t\t// Return for frameset docs that don't have a body\n\t\treturn;\n\t}\n\n\t// Setup\n\tdiv = document.createElement( \"div\" );\n\tcontainer = document.createElement( \"div\" );\n\tcontainer.style.cssText = \"position:absolute;border:0;width:0;height:0;top:0;left:-9999px\";\n\tbody.appendChild( container ).appendChild( div );\n\n\tif ( typeof div.style.zoom !== strundefined ) {\n\t\t// Support: IE<8\n\t\t// Check if natively block-level elements act like inline-block\n\t\t// elements when setting their display to 'inline' and giving\n\t\t// them layout\n\t\tdiv.style.cssText = \"display:inline;margin:0;border:0;padding:1px;width:1px;zoom:1\";\n\n\t\tsupport.inlineBlockNeedsLayout = val = div.offsetWidth === 3;\n\t\tif ( val ) {\n\t\t\t// Prevent IE 6 from affecting layout for positioned elements #11048\n\t\t\t// Prevent IE from shrinking the body in IE 7 mode #12869\n\t\t\t// Support: IE<8\n\t\t\tbody.style.zoom = 1;\n\t\t}\n\t}\n\n\tbody.removeChild( container );\n});\n\n\n\n\n(function() {\n\tvar div = document.createElement( \"div\" );\n\n\t// Execute the test only if not already executed in another module.\n\tif (support.deleteExpando == null) {\n\t\t// Support: IE<9\n\t\tsupport.deleteExpando = true;\n\t\ttry {\n\t\t\tdelete div.test;\n\t\t} catch( e ) {\n\t\t\tsupport.deleteExpando = false;\n\t\t}\n\t}\n\n\t// Null elements to avoid leaks in IE.\n\tdiv = null;\n})();\n\n\n/**\n * Determines whether an object can have data\n */\njQuery.acceptData = function( elem ) {\n\tvar noData = jQuery.noData[ (elem.nodeName + \" \").toLowerCase() ],\n\t\tnodeType = +elem.nodeType || 1;\n\n\t// Do not set data on non-element DOM nodes because it will not be cleared (#8335).\n\treturn nodeType !== 1 && nodeType !== 9 ?\n\t\tfalse :\n\n\t\t// Nodes accept data unless otherwise specified; rejection can be conditional\n\t\t!noData || noData !== true && elem.getAttribute(\"classid\") === noData;\n};\n\n\nvar rbrace = /^(?:\\{[\\w\\W]*\\}|\\[[\\w\\W]*\\])$/,\n\trmultiDash = /([A-Z])/g;\n\nfunction dataAttr( elem, key, data ) {\n\t// If nothing was found internally, try to fetch any\n\t// data from the HTML5 data-* attribute\n\tif ( data === undefined && elem.nodeType === 1 ) {\n\n\t\tvar name = \"data-\" + key.replace( rmultiDash, \"-$1\" ).toLowerCase();\n\n\t\tdata = elem.getAttribute( name );\n\n\t\tif ( typeof data === \"string\" ) {\n\t\t\ttry {\n\t\t\t\tdata = data === \"true\" ? true :\n\t\t\t\t\tdata === \"false\" ? false :\n\t\t\t\t\tdata === \"null\" ? null :\n\t\t\t\t\t// Only convert to a number if it doesn't change the string\n\t\t\t\t\t+data + \"\" === data ? +data :\n\t\t\t\t\trbrace.test( data ) ? jQuery.parseJSON( data ) :\n\t\t\t\t\tdata;\n\t\t\t} catch( e ) {}\n\n\t\t\t// Make sure we set the data so it isn't changed later\n\t\t\tjQuery.data( elem, key, data );\n\n\t\t} else {\n\t\t\tdata = undefined;\n\t\t}\n\t}\n\n\treturn data;\n}\n\n// checks a cache object for emptiness\nfunction isEmptyDataObject( obj ) {\n\tvar name;\n\tfor ( name in obj ) {\n\n\t\t// if the public data object is empty, the private is still empty\n\t\tif ( name === \"data\" && jQuery.isEmptyObject( obj[name] ) ) {\n\t\t\tcontinue;\n\t\t}\n\t\tif ( name !== \"toJSON\" ) {\n\t\t\treturn false;\n\t\t}\n\t}\n\n\treturn true;\n}\n\nfunction internalData( elem, name, data, pvt /* Internal Use Only */ ) {\n\tif ( !jQuery.acceptData( elem ) ) {\n\t\treturn;\n\t}\n\n\tvar ret, thisCache,\n\t\tinternalKey = jQuery.expando,\n\n\t\t// We have to handle DOM nodes and JS objects differently because IE6-7\n\t\t// can't GC object references properly across the DOM-JS boundary\n\t\tisNode = elem.nodeType,\n\n\t\t// Only DOM nodes need the global jQuery cache; JS object data is\n\t\t// attached directly to the object so GC can occur automatically\n\t\tcache = isNode ? jQuery.cache : elem,\n\n\t\t// Only defining an ID for JS objects if its cache already exists allows\n\t\t// the code to shortcut on the same path as a DOM node with no cache\n\t\tid = isNode ? elem[ internalKey ] : elem[ internalKey ] && internalKey;\n\n\t// Avoid doing any more work than we need to when trying to get data on an\n\t// object that has no data at all\n\tif ( (!id || !cache[id] || (!pvt && !cache[id].data)) && data === undefined && typeof name === \"string\" ) {\n\t\treturn;\n\t}\n\n\tif ( !id ) {\n\t\t// Only DOM nodes need a new unique ID for each element since their data\n\t\t// ends up in the global cache\n\t\tif ( isNode ) {\n\t\t\tid = elem[ internalKey ] = deletedIds.pop() || jQuery.guid++;\n\t\t} else {\n\t\t\tid = internalKey;\n\t\t}\n\t}\n\n\tif ( !cache[ id ] ) {\n\t\t// Avoid exposing jQuery metadata on plain JS objects when the object\n\t\t// is serialized using JSON.stringify\n\t\tcache[ id ] = isNode ? {} : { toJSON: jQuery.noop };\n\t}\n\n\t// An object can be passed to jQuery.data instead of a key/value pair; this gets\n\t// shallow copied over onto the existing cache\n\tif ( typeof name === \"object\" || typeof name === \"function\" ) {\n\t\tif ( pvt ) {\n\t\t\tcache[ id ] = jQuery.extend( cache[ id ], name );\n\t\t} else {\n\t\t\tcache[ id ].data = jQuery.extend( cache[ id ].data, name );\n\t\t}\n\t}\n\n\tthisCache = cache[ id ];\n\n\t// jQuery data() is stored in a separate object inside the object's internal data\n\t// cache in order to avoid key collisions between internal data and user-defined\n\t// data.\n\tif ( !pvt ) {\n\t\tif ( !thisCache.data ) {\n\t\t\tthisCache.data = {};\n\t\t}\n\n\t\tthisCache = thisCache.data;\n\t}\n\n\tif ( data !== undefined ) {\n\t\tthisCache[ jQuery.camelCase( name ) ] = data;\n\t}\n\n\t// Check for both converted-to-camel and non-converted data property names\n\t// If a data property was specified\n\tif ( typeof name === \"string\" ) {\n\n\t\t// First Try to find as-is property data\n\t\tret = thisCache[ name ];\n\n\t\t// Test for null|undefined property data\n\t\tif ( ret == null ) {\n\n\t\t\t// Try to find the camelCased property\n\t\t\tret = thisCache[ jQuery.camelCase( name ) ];\n\t\t}\n\t} else {\n\t\tret = thisCache;\n\t}\n\n\treturn ret;\n}\n\nfunction internalRemoveData( elem, name, pvt ) {\n\tif ( !jQuery.acceptData( elem ) ) {\n\t\treturn;\n\t}\n\n\tvar thisCache, i,\n\t\tisNode = elem.nodeType,\n\n\t\t// See jQuery.data for more information\n\t\tcache = isNode ? jQuery.cache : elem,\n\t\tid = isNode ? elem[ jQuery.expando ] : jQuery.expando;\n\n\t// If there is already no cache entry for this object, there is no\n\t// purpose in continuing\n\tif ( !cache[ id ] ) {\n\t\treturn;\n\t}\n\n\tif ( name ) {\n\n\t\tthisCache = pvt ? cache[ id ] : cache[ id ].data;\n\n\t\tif ( thisCache ) {\n\n\t\t\t// Support array or space separated string names for data keys\n\t\t\tif ( !jQuery.isArray( name ) ) {\n\n\t\t\t\t// try the string as a key before any manipulation\n\t\t\t\tif ( name in thisCache ) {\n\t\t\t\t\tname = [ name ];\n\t\t\t\t} else {\n\n\t\t\t\t\t// split the camel cased version by spaces unless a key with the spaces exists\n\t\t\t\t\tname = jQuery.camelCase( name );\n\t\t\t\t\tif ( name in thisCache ) {\n\t\t\t\t\t\tname = [ name ];\n\t\t\t\t\t} else {\n\t\t\t\t\t\tname = name.split(\" \");\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t// If \"name\" is an array of keys...\n\t\t\t\t// When data is initially created, via (\"key\", \"val\") signature,\n\t\t\t\t// keys will be converted to camelCase.\n\t\t\t\t// Since there is no way to tell _how_ a key was added, remove\n\t\t\t\t// both plain key and camelCase key. #12786\n\t\t\t\t// This will only penalize the array argument path.\n\t\t\t\tname = name.concat( jQuery.map( name, jQuery.camelCase ) );\n\t\t\t}\n\n\t\t\ti = name.length;\n\t\t\twhile ( i-- ) {\n\t\t\t\tdelete thisCache[ name[i] ];\n\t\t\t}\n\n\t\t\t// If there is no data left in the cache, we want to continue\n\t\t\t// and let the cache object itself get destroyed\n\t\t\tif ( pvt ? !isEmptyDataObject(thisCache) : !jQuery.isEmptyObject(thisCache) ) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\t}\n\n\t// See jQuery.data for more information\n\tif ( !pvt ) {\n\t\tdelete cache[ id ].data;\n\n\t\t// Don't destroy the parent cache unless the internal data object\n\t\t// had been the only thing left in it\n\t\tif ( !isEmptyDataObject( cache[ id ] ) ) {\n\t\t\treturn;\n\t\t}\n\t}\n\n\t// Destroy the cache\n\tif ( isNode ) {\n\t\tjQuery.cleanData( [ elem ], true );\n\n\t// Use delete when supported for expandos or `cache` is not a window per isWindow (#10080)\n\t/* jshint eqeqeq: false */\n\t} else if ( support.deleteExpando || cache != cache.window ) {\n\t\t/* jshint eqeqeq: true */\n\t\tdelete cache[ id ];\n\n\t// When all else fails, null\n\t} else {\n\t\tcache[ id ] = null;\n\t}\n}\n\njQuery.extend({\n\tcache: {},\n\n\t// The following elements (space-suffixed to avoid Object.prototype collisions)\n\t// throw uncatchable exceptions if you attempt to set expando properties\n\tnoData: {\n\t\t\"applet \": true,\n\t\t\"embed \": true,\n\t\t// ...but Flash objects (which have this classid) *can* handle expandos\n\t\t\"object \": \"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000\"\n\t},\n\n\thasData: function( elem ) {\n\t\telem = elem.nodeType ? jQuery.cache[ elem[jQuery.expando] ] : elem[ jQuery.expando ];\n\t\treturn !!elem && !isEmptyDataObject( elem );\n\t},\n\n\tdata: function( elem, name, data ) {\n\t\treturn internalData( elem, name, data );\n\t},\n\n\tremoveData: function( elem, name ) {\n\t\treturn internalRemoveData( elem, name );\n\t},\n\n\t// For internal use only.\n\t_data: function( elem, name, data ) {\n\t\treturn internalData( elem, name, data, true );\n\t},\n\n\t_removeData: function( elem, name ) {\n\t\treturn internalRemoveData( elem, name, true );\n\t}\n});\n\njQuery.fn.extend({\n\tdata: function( key, value ) {\n\t\tvar i, name, data,\n\t\t\telem = this[0],\n\t\t\tattrs = elem && elem.attributes;\n\n\t\t// Special expections of .data basically thwart jQuery.access,\n\t\t// so implement the relevant behavior ourselves\n\n\t\t// Gets all values\n\t\tif ( key === undefined ) {\n\t\t\tif ( this.length ) {\n\t\t\t\tdata = jQuery.data( elem );\n\n\t\t\t\tif ( elem.nodeType === 1 && !jQuery._data( elem, \"parsedAttrs\" ) ) {\n\t\t\t\t\ti = attrs.length;\n\t\t\t\t\twhile ( i-- ) {\n\n\t\t\t\t\t\t// Support: IE11+\n\t\t\t\t\t\t// The attrs elements can be null (#14894)\n\t\t\t\t\t\tif ( attrs[ i ] ) {\n\t\t\t\t\t\t\tname = attrs[ i ].name;\n\t\t\t\t\t\t\tif ( name.indexOf( \"data-\" ) === 0 ) {\n\t\t\t\t\t\t\t\tname = jQuery.camelCase( name.slice(5) );\n\t\t\t\t\t\t\t\tdataAttr( elem, name, data[ name ] );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tjQuery._data( elem, \"parsedAttrs\", true );\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn data;\n\t\t}\n\n\t\t// Sets multiple values\n\t\tif ( typeof key === \"object\" ) {\n\t\t\treturn this.each(function() {\n\t\t\t\tjQuery.data( this, key );\n\t\t\t});\n\t\t}\n\n\t\treturn arguments.length > 1 ?\n\n\t\t\t// Sets one value\n\t\t\tthis.each(function() {\n\t\t\t\tjQuery.data( this, key, value );\n\t\t\t}) :\n\n\t\t\t// Gets one value\n\t\t\t// Try to fetch any internally stored data first\n\t\t\telem ? dataAttr( elem, key, jQuery.data( elem, key ) ) : undefined;\n\t},\n\n\tremoveData: function( key ) {\n\t\treturn this.each(function() {\n\t\t\tjQuery.removeData( this, key );\n\t\t});\n\t}\n});\n\n\njQuery.extend({\n\tqueue: function( elem, type, data ) {\n\t\tvar queue;\n\n\t\tif ( elem ) {\n\t\t\ttype = ( type || \"fx\" ) + \"queue\";\n\t\t\tqueue = jQuery._data( elem, type );\n\n\t\t\t// Speed up dequeue by getting out quickly if this is just a lookup\n\t\t\tif ( data ) {\n\t\t\t\tif ( !queue || jQuery.isArray(data) ) {\n\t\t\t\t\tqueue = jQuery._data( elem, type, jQuery.makeArray(data) );\n\t\t\t\t} else {\n\t\t\t\t\tqueue.push( data );\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn queue || [];\n\t\t}\n\t},\n\n\tdequeue: function( elem, type ) {\n\t\ttype = type || \"fx\";\n\n\t\tvar queue = jQuery.queue( elem, type ),\n\t\t\tstartLength = queue.length,\n\t\t\tfn = queue.shift(),\n\t\t\thooks = jQuery._queueHooks( elem, type ),\n\t\t\tnext = function() {\n\t\t\t\tjQuery.dequeue( elem, type );\n\t\t\t};\n\n\t\t// If the fx queue is dequeued, always remove the progress sentinel\n\t\tif ( fn === \"inprogress\" ) {\n\t\t\tfn = queue.shift();\n\t\t\tstartLength--;\n\t\t}\n\n\t\tif ( fn ) {\n\n\t\t\t// Add a progress sentinel to prevent the fx queue from being\n\t\t\t// automatically dequeued\n\t\t\tif ( type === \"fx\" ) {\n\t\t\t\tqueue.unshift( \"inprogress\" );\n\t\t\t}\n\n\t\t\t// clear up the last queue stop function\n\t\t\tdelete hooks.stop;\n\t\t\tfn.call( elem, next, hooks );\n\t\t}\n\n\t\tif ( !startLength && hooks ) {\n\t\t\thooks.empty.fire();\n\t\t}\n\t},\n\n\t// not intended for public consumption - generates a queueHooks object, or returns the current one\n\t_queueHooks: function( elem, type ) {\n\t\tvar key = type + \"queueHooks\";\n\t\treturn jQuery._data( elem, key ) || jQuery._data( elem, key, {\n\t\t\tempty: jQuery.Callbacks(\"once memory\").add(function() {\n\t\t\t\tjQuery._removeData( elem, type + \"queue\" );\n\t\t\t\tjQuery._removeData( elem, key );\n\t\t\t})\n\t\t});\n\t}\n});\n\njQuery.fn.extend({\n\tqueue: function( type, data ) {\n\t\tvar setter = 2;\n\n\t\tif ( typeof type !== \"string\" ) {\n\t\t\tdata = type;\n\t\t\ttype = \"fx\";\n\t\t\tsetter--;\n\t\t}\n\n\t\tif ( arguments.length < setter ) {\n\t\t\treturn jQuery.queue( this[0], type );\n\t\t}\n\n\t\treturn data === undefined ?\n\t\t\tthis :\n\t\t\tthis.each(function() {\n\t\t\t\tvar queue = jQuery.queue( this, type, data );\n\n\t\t\t\t// ensure a hooks for this queue\n\t\t\t\tjQuery._queueHooks( this, type );\n\n\t\t\t\tif ( type === \"fx\" && queue[0] !== \"inprogress\" ) {\n\t\t\t\t\tjQuery.dequeue( this, type );\n\t\t\t\t}\n\t\t\t});\n\t},\n\tdequeue: function( type ) {\n\t\treturn this.each(function() {\n\t\t\tjQuery.dequeue( this, type );\n\t\t});\n\t},\n\tclearQueue: function( type ) {\n\t\treturn this.queue( type || \"fx\", [] );\n\t},\n\t// Get a promise resolved when queues of a certain type\n\t// are emptied (fx is the type by default)\n\tpromise: function( type, obj ) {\n\t\tvar tmp,\n\t\t\tcount = 1,\n\t\t\tdefer = jQuery.Deferred(),\n\t\t\telements = this,\n\t\t\ti = this.length,\n\t\t\tresolve = function() {\n\t\t\t\tif ( !( --count ) ) {\n\t\t\t\t\tdefer.resolveWith( elements, [ elements ] );\n\t\t\t\t}\n\t\t\t};\n\n\t\tif ( typeof type !== \"string\" ) {\n\t\t\tobj = type;\n\t\t\ttype = undefined;\n\t\t}\n\t\ttype = type || \"fx\";\n\n\t\twhile ( i-- ) {\n\t\t\ttmp = jQuery._data( elements[ i ], type + \"queueHooks\" );\n\t\t\tif ( tmp && tmp.empty ) {\n\t\t\t\tcount++;\n\t\t\t\ttmp.empty.add( resolve );\n\t\t\t}\n\t\t}\n\t\tresolve();\n\t\treturn defer.promise( obj );\n\t}\n});\nvar pnum = (/[+-]?(?:\\d*\\.|)\\d+(?:[eE][+-]?\\d+|)/).source;\n\nvar cssExpand = [ \"Top\", \"Right\", \"Bottom\", \"Left\" ];\n\nvar isHidden = function( elem, el ) {\n\t\t// isHidden might be called from jQuery#filter function;\n\t\t// in that case, element will be second argument\n\t\telem = el || elem;\n\t\treturn jQuery.css( elem, \"display\" ) === \"none\" || !jQuery.contains( elem.ownerDocument, elem );\n\t};\n\n\n\n// Multifunctional method to get and set values of a collection\n// The value/s can optionally be executed if it's a function\nvar access = jQuery.access = function( elems, fn, key, value, chainable, emptyGet, raw ) {\n\tvar i = 0,\n\t\tlength = elems.length,\n\t\tbulk = key == null;\n\n\t// Sets many values\n\tif ( jQuery.type( key ) === \"object\" ) {\n\t\tchainable = true;\n\t\tfor ( i in key ) {\n\t\t\tjQuery.access( elems, fn, i, key[i], true, emptyGet, raw );\n\t\t}\n\n\t// Sets one value\n\t} else if ( value !== undefined ) {\n\t\tchainable = true;\n\n\t\tif ( !jQuery.isFunction( value ) ) {\n\t\t\traw = true;\n\t\t}\n\n\t\tif ( bulk ) {\n\t\t\t// Bulk operations run against the entire set\n\t\t\tif ( raw ) {\n\t\t\t\tfn.call( elems, value );\n\t\t\t\tfn = null;\n\n\t\t\t// ...except when executing function values\n\t\t\t} else {\n\t\t\t\tbulk = fn;\n\t\t\t\tfn = function( elem, key, value ) {\n\t\t\t\t\treturn bulk.call( jQuery( elem ), value );\n\t\t\t\t};\n\t\t\t}\n\t\t}\n\n\t\tif ( fn ) {\n\t\t\tfor ( ; i < length; i++ ) {\n\t\t\t\tfn( elems[i], key, raw ? value : value.call( elems[i], i, fn( elems[i], key ) ) );\n\t\t\t}\n\t\t}\n\t}\n\n\treturn chainable ?\n\t\telems :\n\n\t\t// Gets\n\t\tbulk ?\n\t\t\tfn.call( elems ) :\n\t\t\tlength ? fn( elems[0], key ) : emptyGet;\n};\nvar rcheckableType = (/^(?:checkbox|radio)$/i);\n\n\n\n(function() {\n\t// Minified: var a,b,c\n\tvar input = document.createElement( \"input\" ),\n\t\tdiv = document.createElement( \"div\" ),\n\t\tfragment = document.createDocumentFragment();\n\n\t// Setup\n\tdiv.innerHTML = \"  <link/><table></table><a href='/a'>a</a><input type='checkbox'/>\";\n\n\t// IE strips leading whitespace when .innerHTML is used\n\tsupport.leadingWhitespace = div.firstChild.nodeType === 3;\n\n\t// Make sure that tbody elements aren't automatically inserted\n\t// IE will insert them into empty tables\n\tsupport.tbody = !div.getElementsByTagName( \"tbody\" ).length;\n\n\t// Make sure that link elements get serialized correctly by innerHTML\n\t// This requires a wrapper element in IE\n\tsupport.htmlSerialize = !!div.getElementsByTagName( \"link\" ).length;\n\n\t// Makes sure cloning an html5 element does not cause problems\n\t// Where outerHTML is undefined, this still works\n\tsupport.html5Clone =\n\t\tdocument.createElement( \"nav\" ).cloneNode( true ).outerHTML !== \"<:nav></:nav>\";\n\n\t// Check if a disconnected checkbox will retain its checked\n\t// value of true after appended to the DOM (IE6/7)\n\tinput.type = \"checkbox\";\n\tinput.checked = true;\n\tfragment.appendChild( input );\n\tsupport.appendChecked = input.checked;\n\n\t// Make sure textarea (and checkbox) defaultValue is properly cloned\n\t// Support: IE6-IE11+\n\tdiv.innerHTML = \"<textarea>x</textarea>\";\n\tsupport.noCloneChecked = !!div.cloneNode( true ).lastChild.defaultValue;\n\n\t// #11217 - WebKit loses check when the name is after the checked attribute\n\tfragment.appendChild( div );\n\tdiv.innerHTML = \"<input type='radio' checked='checked' name='t'/>\";\n\n\t// Support: Safari 5.1, iOS 5.1, Android 4.x, Android 2.3\n\t// old WebKit doesn't clone checked state correctly in fragments\n\tsupport.checkClone = div.cloneNode( true ).cloneNode( true ).lastChild.checked;\n\n\t// Support: IE<9\n\t// Opera does not clone events (and typeof div.attachEvent === undefined).\n\t// IE9-10 clones events bound via attachEvent, but they don't trigger with .click()\n\tsupport.noCloneEvent = true;\n\tif ( div.attachEvent ) {\n\t\tdiv.attachEvent( \"onclick\", function() {\n\t\t\tsupport.noCloneEvent = false;\n\t\t});\n\n\t\tdiv.cloneNode( true ).click();\n\t}\n\n\t// Execute the test only if not already executed in another module.\n\tif (support.deleteExpando == null) {\n\t\t// Support: IE<9\n\t\tsupport.deleteExpando = true;\n\t\ttry {\n\t\t\tdelete div.test;\n\t\t} catch( e ) {\n\t\t\tsupport.deleteExpando = false;\n\t\t}\n\t}\n})();\n\n\n(function() {\n\tvar i, eventName,\n\t\tdiv = document.createElement( \"div\" );\n\n\t// Support: IE<9 (lack submit/change bubble), Firefox 23+ (lack focusin event)\n\tfor ( i in { submit: true, change: true, focusin: true }) {\n\t\teventName = \"on\" + i;\n\n\t\tif ( !(support[ i + \"Bubbles\" ] = eventName in window) ) {\n\t\t\t// Beware of CSP restrictions (https://developer.mozilla.org/en/Security/CSP)\n\t\t\tdiv.setAttribute( eventName, \"t\" );\n\t\t\tsupport[ i + \"Bubbles\" ] = div.attributes[ eventName ].expando === false;\n\t\t}\n\t}\n\n\t// Null elements to avoid leaks in IE.\n\tdiv = null;\n})();\n\n\nvar rformElems = /^(?:input|select|textarea)$/i,\n\trkeyEvent = /^key/,\n\trmouseEvent = /^(?:mouse|pointer|contextmenu)|click/,\n\trfocusMorph = /^(?:focusinfocus|focusoutblur)$/,\n\trtypenamespace = /^([^.]*)(?:\\.(.+)|)$/;\n\nfunction returnTrue() {\n\treturn true;\n}\n\nfunction returnFalse() {\n\treturn false;\n}\n\nfunction safeActiveElement() {\n\ttry {\n\t\treturn document.activeElement;\n\t} catch ( err ) { }\n}\n\n/*\n * Helper functions for managing events -- not part of the public interface.\n * Props to Dean Edwards' addEvent library for many of the ideas.\n */\njQuery.event = {\n\n\tglobal: {},\n\n\tadd: function( elem, types, handler, data, selector ) {\n\t\tvar tmp, events, t, handleObjIn,\n\t\t\tspecial, eventHandle, handleObj,\n\t\t\thandlers, type, namespaces, origType,\n\t\t\telemData = jQuery._data( elem );\n\n\t\t// Don't attach events to noData or text/comment nodes (but allow plain objects)\n\t\tif ( !elemData ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Caller can pass in an object of custom data in lieu of the handler\n\t\tif ( handler.handler ) {\n\t\t\thandleObjIn = handler;\n\t\t\thandler = handleObjIn.handler;\n\t\t\tselector = handleObjIn.selector;\n\t\t}\n\n\t\t// Make sure that the handler has a unique ID, used to find/remove it later\n\t\tif ( !handler.guid ) {\n\t\t\thandler.guid = jQuery.guid++;\n\t\t}\n\n\t\t// Init the element's event structure and main handler, if this is the first\n\t\tif ( !(events = elemData.events) ) {\n\t\t\tevents = elemData.events = {};\n\t\t}\n\t\tif ( !(eventHandle = elemData.handle) ) {\n\t\t\teventHandle = elemData.handle = function( e ) {\n\t\t\t\t// Discard the second event of a jQuery.event.trigger() and\n\t\t\t\t// when an event is called after a page has unloaded\n\t\t\t\treturn typeof jQuery !== strundefined && (!e || jQuery.event.triggered !== e.type) ?\n\t\t\t\t\tjQuery.event.dispatch.apply( eventHandle.elem, arguments ) :\n\t\t\t\t\tundefined;\n\t\t\t};\n\t\t\t// Add elem as a property of the handle fn to prevent a memory leak with IE non-native events\n\t\t\teventHandle.elem = elem;\n\t\t}\n\n\t\t// Handle multiple events separated by a space\n\t\ttypes = ( types || \"\" ).match( rnotwhite ) || [ \"\" ];\n\t\tt = types.length;\n\t\twhile ( t-- ) {\n\t\t\ttmp = rtypenamespace.exec( types[t] ) || [];\n\t\t\ttype = origType = tmp[1];\n\t\t\tnamespaces = ( tmp[2] || \"\" ).split( \".\" ).sort();\n\n\t\t\t// There *must* be a type, no attaching namespace-only handlers\n\t\t\tif ( !type ) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\t// If event changes its type, use the special event handlers for the changed type\n\t\t\tspecial = jQuery.event.special[ type ] || {};\n\n\t\t\t// If selector defined, determine special event api type, otherwise given type\n\t\t\ttype = ( selector ? special.delegateType : special.bindType ) || type;\n\n\t\t\t// Update special based on newly reset type\n\t\t\tspecial = jQuery.event.special[ type ] || {};\n\n\t\t\t// handleObj is passed to all event handlers\n\t\t\thandleObj = jQuery.extend({\n\t\t\t\ttype: type,\n\t\t\t\torigType: origType,\n\t\t\t\tdata: data,\n\t\t\t\thandler: handler,\n\t\t\t\tguid: handler.guid,\n\t\t\t\tselector: selector,\n\t\t\t\tneedsContext: selector && jQuery.expr.match.needsContext.test( selector ),\n\t\t\t\tnamespace: namespaces.join(\".\")\n\t\t\t}, handleObjIn );\n\n\t\t\t// Init the event handler queue if we're the first\n\t\t\tif ( !(handlers = events[ type ]) ) {\n\t\t\t\thandlers = events[ type ] = [];\n\t\t\t\thandlers.delegateCount = 0;\n\n\t\t\t\t// Only use addEventListener/attachEvent if the special events handler returns false\n\t\t\t\tif ( !special.setup || special.setup.call( elem, data, namespaces, eventHandle ) === false ) {\n\t\t\t\t\t// Bind the global event handler to the element\n\t\t\t\t\tif ( elem.addEventListener ) {\n\t\t\t\t\t\telem.addEventListener( type, eventHandle, false );\n\n\t\t\t\t\t} else if ( elem.attachEvent ) {\n\t\t\t\t\t\telem.attachEvent( \"on\" + type, eventHandle );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif ( special.add ) {\n\t\t\t\tspecial.add.call( elem, handleObj );\n\n\t\t\t\tif ( !handleObj.handler.guid ) {\n\t\t\t\t\thandleObj.handler.guid = handler.guid;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Add to the element's handler list, delegates in front\n\t\t\tif ( selector ) {\n\t\t\t\thandlers.splice( handlers.delegateCount++, 0, handleObj );\n\t\t\t} else {\n\t\t\t\thandlers.push( handleObj );\n\t\t\t}\n\n\t\t\t// Keep track of which events have ever been used, for event optimization\n\t\t\tjQuery.event.global[ type ] = true;\n\t\t}\n\n\t\t// Nullify elem to prevent memory leaks in IE\n\t\telem = null;\n\t},\n\n\t// Detach an event or set of events from an element\n\tremove: function( elem, types, handler, selector, mappedTypes ) {\n\t\tvar j, handleObj, tmp,\n\t\t\torigCount, t, events,\n\t\t\tspecial, handlers, type,\n\t\t\tnamespaces, origType,\n\t\t\telemData = jQuery.hasData( elem ) && jQuery._data( elem );\n\n\t\tif ( !elemData || !(events = elemData.events) ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Once for each type.namespace in types; type may be omitted\n\t\ttypes = ( types || \"\" ).match( rnotwhite ) || [ \"\" ];\n\t\tt = types.length;\n\t\twhile ( t-- ) {\n\t\t\ttmp = rtypenamespace.exec( types[t] ) || [];\n\t\t\ttype = origType = tmp[1];\n\t\t\tnamespaces = ( tmp[2] || \"\" ).split( \".\" ).sort();\n\n\t\t\t// Unbind all events (on this namespace, if provided) for the element\n\t\t\tif ( !type ) {\n\t\t\t\tfor ( type in events ) {\n\t\t\t\t\tjQuery.event.remove( elem, type + types[ t ], handler, selector, true );\n\t\t\t\t}\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tspecial = jQuery.event.special[ type ] || {};\n\t\t\ttype = ( selector ? special.delegateType : special.bindType ) || type;\n\t\t\thandlers = events[ type ] || [];\n\t\t\ttmp = tmp[2] && new RegExp( \"(^|\\\\.)\" + namespaces.join(\"\\\\.(?:.*\\\\.|)\") + \"(\\\\.|$)\" );\n\n\t\t\t// Remove matching events\n\t\t\torigCount = j = handlers.length;\n\t\t\twhile ( j-- ) {\n\t\t\t\thandleObj = handlers[ j ];\n\n\t\t\t\tif ( ( mappedTypes || origType === handleObj.origType ) &&\n\t\t\t\t\t( !handler || handler.guid === handleObj.guid ) &&\n\t\t\t\t\t( !tmp || tmp.test( handleObj.namespace ) ) &&\n\t\t\t\t\t( !selector || selector === handleObj.selector || selector === \"**\" && handleObj.selector ) ) {\n\t\t\t\t\thandlers.splice( j, 1 );\n\n\t\t\t\t\tif ( handleObj.selector ) {\n\t\t\t\t\t\thandlers.delegateCount--;\n\t\t\t\t\t}\n\t\t\t\t\tif ( special.remove ) {\n\t\t\t\t\t\tspecial.remove.call( elem, handleObj );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Remove generic event handler if we removed something and no more handlers exist\n\t\t\t// (avoids potential for endless recursion during removal of special event handlers)\n\t\t\tif ( origCount && !handlers.length ) {\n\t\t\t\tif ( !special.teardown || special.teardown.call( elem, namespaces, elemData.handle ) === false ) {\n\t\t\t\t\tjQuery.removeEvent( elem, type, elemData.handle );\n\t\t\t\t}\n\n\t\t\t\tdelete events[ type ];\n\t\t\t}\n\t\t}\n\n\t\t// Remove the expando if it's no longer used\n\t\tif ( jQuery.isEmptyObject( events ) ) {\n\t\t\tdelete elemData.handle;\n\n\t\t\t// removeData also checks for emptiness and clears the expando if empty\n\t\t\t// so use it instead of delete\n\t\t\tjQuery._removeData( elem, \"events\" );\n\t\t}\n\t},\n\n\ttrigger: function( event, data, elem, onlyHandlers ) {\n\t\tvar handle, ontype, cur,\n\t\t\tbubbleType, special, tmp, i,\n\t\t\teventPath = [ elem || document ],\n\t\t\ttype = hasOwn.call( event, \"type\" ) ? event.type : event,\n\t\t\tnamespaces = hasOwn.call( event, \"namespace\" ) ? event.namespace.split(\".\") : [];\n\n\t\tcur = tmp = elem = elem || document;\n\n\t\t// Don't do events on text and comment nodes\n\t\tif ( elem.nodeType === 3 || elem.nodeType === 8 ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// focus/blur morphs to focusin/out; ensure we're not firing them right now\n\t\tif ( rfocusMorph.test( type + jQuery.event.triggered ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\tif ( type.indexOf(\".\") >= 0 ) {\n\t\t\t// Namespaced trigger; create a regexp to match event type in handle()\n\t\t\tnamespaces = type.split(\".\");\n\t\t\ttype = namespaces.shift();\n\t\t\tnamespaces.sort();\n\t\t}\n\t\tontype = type.indexOf(\":\") < 0 && \"on\" + type;\n\n\t\t// Caller can pass in a jQuery.Event object, Object, or just an event type string\n\t\tevent = event[ jQuery.expando ] ?\n\t\t\tevent :\n\t\t\tnew jQuery.Event( type, typeof event === \"object\" && event );\n\n\t\t// Trigger bitmask: & 1 for native handlers; & 2 for jQuery (always true)\n\t\tevent.isTrigger = onlyHandlers ? 2 : 3;\n\t\tevent.namespace = namespaces.join(\".\");\n\t\tevent.namespace_re = event.namespace ?\n\t\t\tnew RegExp( \"(^|\\\\.)\" + namespaces.join(\"\\\\.(?:.*\\\\.|)\") + \"(\\\\.|$)\" ) :\n\t\t\tnull;\n\n\t\t// Clean up the event in case it is being reused\n\t\tevent.result = undefined;\n\t\tif ( !event.target ) {\n\t\t\tevent.target = elem;\n\t\t}\n\n\t\t// Clone any incoming data and prepend the event, creating the handler arg list\n\t\tdata = data == null ?\n\t\t\t[ event ] :\n\t\t\tjQuery.makeArray( data, [ event ] );\n\n\t\t// Allow special events to draw outside the lines\n\t\tspecial = jQuery.event.special[ type ] || {};\n\t\tif ( !onlyHandlers && special.trigger && special.trigger.apply( elem, data ) === false ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Determine event propagation path in advance, per W3C events spec (#9951)\n\t\t// Bubble up to document, then to window; watch for a global ownerDocument var (#9724)\n\t\tif ( !onlyHandlers && !special.noBubble && !jQuery.isWindow( elem ) ) {\n\n\t\t\tbubbleType = special.delegateType || type;\n\t\t\tif ( !rfocusMorph.test( bubbleType + type ) ) {\n\t\t\t\tcur = cur.parentNode;\n\t\t\t}\n\t\t\tfor ( ; cur; cur = cur.parentNode ) {\n\t\t\t\teventPath.push( cur );\n\t\t\t\ttmp = cur;\n\t\t\t}\n\n\t\t\t// Only add window if we got to document (e.g., not plain obj or detached DOM)\n\t\t\tif ( tmp === (elem.ownerDocument || document) ) {\n\t\t\t\teventPath.push( tmp.defaultView || tmp.parentWindow || window );\n\t\t\t}\n\t\t}\n\n\t\t// Fire handlers on the event path\n\t\ti = 0;\n\t\twhile ( (cur = eventPath[i++]) && !event.isPropagationStopped() ) {\n\n\t\t\tevent.type = i > 1 ?\n\t\t\t\tbubbleType :\n\t\t\t\tspecial.bindType || type;\n\n\t\t\t// jQuery handler\n\t\t\thandle = ( jQuery._data( cur, \"events\" ) || {} )[ event.type ] && jQuery._data( cur, \"handle\" );\n\t\t\tif ( handle ) {\n\t\t\t\thandle.apply( cur, data );\n\t\t\t}\n\n\t\t\t// Native handler\n\t\t\thandle = ontype && cur[ ontype ];\n\t\t\tif ( handle && handle.apply && jQuery.acceptData( cur ) ) {\n\t\t\t\tevent.result = handle.apply( cur, data );\n\t\t\t\tif ( event.result === false ) {\n\t\t\t\t\tevent.preventDefault();\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tevent.type = type;\n\n\t\t// If nobody prevented the default action, do it now\n\t\tif ( !onlyHandlers && !event.isDefaultPrevented() ) {\n\n\t\t\tif ( (!special._default || special._default.apply( eventPath.pop(), data ) === false) &&\n\t\t\t\tjQuery.acceptData( elem ) ) {\n\n\t\t\t\t// Call a native DOM method on the target with the same name name as the event.\n\t\t\t\t// Can't use an .isFunction() check here because IE6/7 fails that test.\n\t\t\t\t// Don't do default actions on window, that's where global variables be (#6170)\n\t\t\t\tif ( ontype && elem[ type ] && !jQuery.isWindow( elem ) ) {\n\n\t\t\t\t\t// Don't re-trigger an onFOO event when we call its FOO() method\n\t\t\t\t\ttmp = elem[ ontype ];\n\n\t\t\t\t\tif ( tmp ) {\n\t\t\t\t\t\telem[ ontype ] = null;\n\t\t\t\t\t}\n\n\t\t\t\t\t// Prevent re-triggering of the same event, since we already bubbled it above\n\t\t\t\t\tjQuery.event.triggered = type;\n\t\t\t\t\ttry {\n\t\t\t\t\t\telem[ type ]();\n\t\t\t\t\t} catch ( e ) {\n\t\t\t\t\t\t// IE<9 dies on focus/blur to hidden element (#1486,#12518)\n\t\t\t\t\t\t// only reproducible on winXP IE8 native, not IE9 in IE8 mode\n\t\t\t\t\t}\n\t\t\t\t\tjQuery.event.triggered = undefined;\n\n\t\t\t\t\tif ( tmp ) {\n\t\t\t\t\t\telem[ ontype ] = tmp;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn event.result;\n\t},\n\n\tdispatch: function( event ) {\n\n\t\t// Make a writable jQuery.Event from the native event object\n\t\tevent = jQuery.event.fix( event );\n\n\t\tvar i, ret, handleObj, matched, j,\n\t\t\thandlerQueue = [],\n\t\t\targs = slice.call( arguments ),\n\t\t\thandlers = ( jQuery._data( this, \"events\" ) || {} )[ event.type ] || [],\n\t\t\tspecial = jQuery.event.special[ event.type ] || {};\n\n\t\t// Use the fix-ed jQuery.Event rather than the (read-only) native event\n\t\targs[0] = event;\n\t\tevent.delegateTarget = this;\n\n\t\t// Call the preDispatch hook for the mapped type, and let it bail if desired\n\t\tif ( special.preDispatch && special.preDispatch.call( this, event ) === false ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Determine handlers\n\t\thandlerQueue = jQuery.event.handlers.call( this, event, handlers );\n\n\t\t// Run delegates first; they may want to stop propagation beneath us\n\t\ti = 0;\n\t\twhile ( (matched = handlerQueue[ i++ ]) && !event.isPropagationStopped() ) {\n\t\t\tevent.currentTarget = matched.elem;\n\n\t\t\tj = 0;\n\t\t\twhile ( (handleObj = matched.handlers[ j++ ]) && !event.isImmediatePropagationStopped() ) {\n\n\t\t\t\t// Triggered event must either 1) have no namespace, or\n\t\t\t\t// 2) have namespace(s) a subset or equal to those in the bound event (both can have no namespace).\n\t\t\t\tif ( !event.namespace_re || event.namespace_re.test( handleObj.namespace ) ) {\n\n\t\t\t\t\tevent.handleObj = handleObj;\n\t\t\t\t\tevent.data = handleObj.data;\n\n\t\t\t\t\tret = ( (jQuery.event.special[ handleObj.origType ] || {}).handle || handleObj.handler )\n\t\t\t\t\t\t\t.apply( matched.elem, args );\n\n\t\t\t\t\tif ( ret !== undefined ) {\n\t\t\t\t\t\tif ( (event.result = ret) === false ) {\n\t\t\t\t\t\t\tevent.preventDefault();\n\t\t\t\t\t\t\tevent.stopPropagation();\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Call the postDispatch hook for the mapped type\n\t\tif ( special.postDispatch ) {\n\t\t\tspecial.postDispatch.call( this, event );\n\t\t}\n\n\t\treturn event.result;\n\t},\n\n\thandlers: function( event, handlers ) {\n\t\tvar sel, handleObj, matches, i,\n\t\t\thandlerQueue = [],\n\t\t\tdelegateCount = handlers.delegateCount,\n\t\t\tcur = event.target;\n\n\t\t// Find delegate handlers\n\t\t// Black-hole SVG <use> instance trees (#13180)\n\t\t// Avoid non-left-click bubbling in Firefox (#3861)\n\t\tif ( delegateCount && cur.nodeType && (!event.button || event.type !== \"click\") ) {\n\n\t\t\t/* jshint eqeqeq: false */\n\t\t\tfor ( ; cur != this; cur = cur.parentNode || this ) {\n\t\t\t\t/* jshint eqeqeq: true */\n\n\t\t\t\t// Don't check non-elements (#13208)\n\t\t\t\t// Don't process clicks on disabled elements (#6911, #8165, #11382, #11764)\n\t\t\t\tif ( cur.nodeType === 1 && (cur.disabled !== true || event.type !== \"click\") ) {\n\t\t\t\t\tmatches = [];\n\t\t\t\t\tfor ( i = 0; i < delegateCount; i++ ) {\n\t\t\t\t\t\thandleObj = handlers[ i ];\n\n\t\t\t\t\t\t// Don't conflict with Object.prototype properties (#13203)\n\t\t\t\t\t\tsel = handleObj.selector + \" \";\n\n\t\t\t\t\t\tif ( matches[ sel ] === undefined ) {\n\t\t\t\t\t\t\tmatches[ sel ] = handleObj.needsContext ?\n\t\t\t\t\t\t\t\tjQuery( sel, this ).index( cur ) >= 0 :\n\t\t\t\t\t\t\t\tjQuery.find( sel, this, null, [ cur ] ).length;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif ( matches[ sel ] ) {\n\t\t\t\t\t\t\tmatches.push( handleObj );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tif ( matches.length ) {\n\t\t\t\t\t\thandlerQueue.push({ elem: cur, handlers: matches });\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Add the remaining (directly-bound) handlers\n\t\tif ( delegateCount < handlers.length ) {\n\t\t\thandlerQueue.push({ elem: this, handlers: handlers.slice( delegateCount ) });\n\t\t}\n\n\t\treturn handlerQueue;\n\t},\n\n\tfix: function( event ) {\n\t\tif ( event[ jQuery.expando ] ) {\n\t\t\treturn event;\n\t\t}\n\n\t\t// Create a writable copy of the event object and normalize some properties\n\t\tvar i, prop, copy,\n\t\t\ttype = event.type,\n\t\t\toriginalEvent = event,\n\t\t\tfixHook = this.fixHooks[ type ];\n\n\t\tif ( !fixHook ) {\n\t\t\tthis.fixHooks[ type ] = fixHook =\n\t\t\t\trmouseEvent.test( type ) ? this.mouseHooks :\n\t\t\t\trkeyEvent.test( type ) ? this.keyHooks :\n\t\t\t\t{};\n\t\t}\n\t\tcopy = fixHook.props ? this.props.concat( fixHook.props ) : this.props;\n\n\t\tevent = new jQuery.Event( originalEvent );\n\n\t\ti = copy.length;\n\t\twhile ( i-- ) {\n\t\t\tprop = copy[ i ];\n\t\t\tevent[ prop ] = originalEvent[ prop ];\n\t\t}\n\n\t\t// Support: IE<9\n\t\t// Fix target property (#1925)\n\t\tif ( !event.target ) {\n\t\t\tevent.target = originalEvent.srcElement || document;\n\t\t}\n\n\t\t// Support: Chrome 23+, Safari?\n\t\t// Target should not be a text node (#504, #13143)\n\t\tif ( event.target.nodeType === 3 ) {\n\t\t\tevent.target = event.target.parentNode;\n\t\t}\n\n\t\t// Support: IE<9\n\t\t// For mouse/key events, metaKey==false if it's undefined (#3368, #11328)\n\t\tevent.metaKey = !!event.metaKey;\n\n\t\treturn fixHook.filter ? fixHook.filter( event, originalEvent ) : event;\n\t},\n\n\t// Includes some event props shared by KeyEvent and MouseEvent\n\tprops: \"altKey bubbles cancelable ctrlKey currentTarget eventPhase metaKey relatedTarget shiftKey target timeStamp view which\".split(\" \"),\n\n\tfixHooks: {},\n\n\tkeyHooks: {\n\t\tprops: \"char charCode key keyCode\".split(\" \"),\n\t\tfilter: function( event, original ) {\n\n\t\t\t// Add which for key events\n\t\t\tif ( event.which == null ) {\n\t\t\t\tevent.which = original.charCode != null ? original.charCode : original.keyCode;\n\t\t\t}\n\n\t\t\treturn event;\n\t\t}\n\t},\n\n\tmouseHooks: {\n\t\tprops: \"button buttons clientX clientY fromElement offsetX offsetY pageX pageY screenX screenY toElement\".split(\" \"),\n\t\tfilter: function( event, original ) {\n\t\t\tvar body, eventDoc, doc,\n\t\t\t\tbutton = original.button,\n\t\t\t\tfromElement = original.fromElement;\n\n\t\t\t// Calculate pageX/Y if missing and clientX/Y available\n\t\t\tif ( event.pageX == null && original.clientX != null ) {\n\t\t\t\teventDoc = event.target.ownerDocument || document;\n\t\t\t\tdoc = eventDoc.documentElement;\n\t\t\t\tbody = eventDoc.body;\n\n\t\t\t\tevent.pageX = original.clientX + ( doc && doc.scrollLeft || body && body.scrollLeft || 0 ) - ( doc && doc.clientLeft || body && body.clientLeft || 0 );\n\t\t\t\tevent.pageY = original.clientY + ( doc && doc.scrollTop  || body && body.scrollTop  || 0 ) - ( doc && doc.clientTop  || body && body.clientTop  || 0 );\n\t\t\t}\n\n\t\t\t// Add relatedTarget, if necessary\n\t\t\tif ( !event.relatedTarget && fromElement ) {\n\t\t\t\tevent.relatedTarget = fromElement === event.target ? original.toElement : fromElement;\n\t\t\t}\n\n\t\t\t// Add which for click: 1 === left; 2 === middle; 3 === right\n\t\t\t// Note: button is not normalized, so don't use it\n\t\t\tif ( !event.which && button !== undefined ) {\n\t\t\t\tevent.which = ( button & 1 ? 1 : ( button & 2 ? 3 : ( button & 4 ? 2 : 0 ) ) );\n\t\t\t}\n\n\t\t\treturn event;\n\t\t}\n\t},\n\n\tspecial: {\n\t\tload: {\n\t\t\t// Prevent triggered image.load events from bubbling to window.load\n\t\t\tnoBubble: true\n\t\t},\n\t\tfocus: {\n\t\t\t// Fire native event if possible so blur/focus sequence is correct\n\t\t\ttrigger: function() {\n\t\t\t\tif ( this !== safeActiveElement() && this.focus ) {\n\t\t\t\t\ttry {\n\t\t\t\t\t\tthis.focus();\n\t\t\t\t\t\treturn false;\n\t\t\t\t\t} catch ( e ) {\n\t\t\t\t\t\t// Support: IE<9\n\t\t\t\t\t\t// If we error on focus to hidden element (#1486, #12518),\n\t\t\t\t\t\t// let .trigger() run the handlers\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t},\n\t\t\tdelegateType: \"focusin\"\n\t\t},\n\t\tblur: {\n\t\t\ttrigger: function() {\n\t\t\t\tif ( this === safeActiveElement() && this.blur ) {\n\t\t\t\t\tthis.blur();\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t},\n\t\t\tdelegateType: \"focusout\"\n\t\t},\n\t\tclick: {\n\t\t\t// For checkbox, fire native event so checked state will be right\n\t\t\ttrigger: function() {\n\t\t\t\tif ( jQuery.nodeName( this, \"input\" ) && this.type === \"checkbox\" && this.click ) {\n\t\t\t\t\tthis.click();\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t},\n\n\t\t\t// For cross-browser consistency, don't fire native .click() on links\n\t\t\t_default: function( event ) {\n\t\t\t\treturn jQuery.nodeName( event.target, \"a\" );\n\t\t\t}\n\t\t},\n\n\t\tbeforeunload: {\n\t\t\tpostDispatch: function( event ) {\n\n\t\t\t\t// Support: Firefox 20+\n\t\t\t\t// Firefox doesn't alert if the returnValue field is not set.\n\t\t\t\tif ( event.result !== undefined && event.originalEvent ) {\n\t\t\t\t\tevent.originalEvent.returnValue = event.result;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t},\n\n\tsimulate: function( type, elem, event, bubble ) {\n\t\t// Piggyback on a donor event to simulate a different one.\n\t\t// Fake originalEvent to avoid donor's stopPropagation, but if the\n\t\t// simulated event prevents default then we do the same on the donor.\n\t\tvar e = jQuery.extend(\n\t\t\tnew jQuery.Event(),\n\t\t\tevent,\n\t\t\t{\n\t\t\t\ttype: type,\n\t\t\t\tisSimulated: true,\n\t\t\t\toriginalEvent: {}\n\t\t\t}\n\t\t);\n\t\tif ( bubble ) {\n\t\t\tjQuery.event.trigger( e, null, elem );\n\t\t} else {\n\t\t\tjQuery.event.dispatch.call( elem, e );\n\t\t}\n\t\tif ( e.isDefaultPrevented() ) {\n\t\t\tevent.preventDefault();\n\t\t}\n\t}\n};\n\njQuery.removeEvent = document.removeEventListener ?\n\tfunction( elem, type, handle ) {\n\t\tif ( elem.removeEventListener ) {\n\t\t\telem.removeEventListener( type, handle, false );\n\t\t}\n\t} :\n\tfunction( elem, type, handle ) {\n\t\tvar name = \"on\" + type;\n\n\t\tif ( elem.detachEvent ) {\n\n\t\t\t// #8545, #7054, preventing memory leaks for custom events in IE6-8\n\t\t\t// detachEvent needed property on element, by name of that event, to properly expose it to GC\n\t\t\tif ( typeof elem[ name ] === strundefined ) {\n\t\t\t\telem[ name ] = null;\n\t\t\t}\n\n\t\t\telem.detachEvent( name, handle );\n\t\t}\n\t};\n\njQuery.Event = function( src, props ) {\n\t// Allow instantiation without the 'new' keyword\n\tif ( !(this instanceof jQuery.Event) ) {\n\t\treturn new jQuery.Event( src, props );\n\t}\n\n\t// Event object\n\tif ( src && src.type ) {\n\t\tthis.originalEvent = src;\n\t\tthis.type = src.type;\n\n\t\t// Events bubbling up the document may have been marked as prevented\n\t\t// by a handler lower down the tree; reflect the correct value.\n\t\tthis.isDefaultPrevented = src.defaultPrevented ||\n\t\t\t\tsrc.defaultPrevented === undefined &&\n\t\t\t\t// Support: IE < 9, Android < 4.0\n\t\t\t\tsrc.returnValue === false ?\n\t\t\treturnTrue :\n\t\t\treturnFalse;\n\n\t// Event type\n\t} else {\n\t\tthis.type = src;\n\t}\n\n\t// Put explicitly provided properties onto the event object\n\tif ( props ) {\n\t\tjQuery.extend( this, props );\n\t}\n\n\t// Create a timestamp if incoming event doesn't have one\n\tthis.timeStamp = src && src.timeStamp || jQuery.now();\n\n\t// Mark it as fixed\n\tthis[ jQuery.expando ] = true;\n};\n\n// jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding\n// http://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html\njQuery.Event.prototype = {\n\tisDefaultPrevented: returnFalse,\n\tisPropagationStopped: returnFalse,\n\tisImmediatePropagationStopped: returnFalse,\n\n\tpreventDefault: function() {\n\t\tvar e = this.originalEvent;\n\n\t\tthis.isDefaultPrevented = returnTrue;\n\t\tif ( !e ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// If preventDefault exists, run it on the original event\n\t\tif ( e.preventDefault ) {\n\t\t\te.preventDefault();\n\n\t\t// Support: IE\n\t\t// Otherwise set the returnValue property of the original event to false\n\t\t} else {\n\t\t\te.returnValue = false;\n\t\t}\n\t},\n\tstopPropagation: function() {\n\t\tvar e = this.originalEvent;\n\n\t\tthis.isPropagationStopped = returnTrue;\n\t\tif ( !e ) {\n\t\t\treturn;\n\t\t}\n\t\t// If stopPropagation exists, run it on the original event\n\t\tif ( e.stopPropagation ) {\n\t\t\te.stopPropagation();\n\t\t}\n\n\t\t// Support: IE\n\t\t// Set the cancelBubble property of the original event to true\n\t\te.cancelBubble = true;\n\t},\n\tstopImmediatePropagation: function() {\n\t\tvar e = this.originalEvent;\n\n\t\tthis.isImmediatePropagationStopped = returnTrue;\n\n\t\tif ( e && e.stopImmediatePropagation ) {\n\t\t\te.stopImmediatePropagation();\n\t\t}\n\n\t\tthis.stopPropagation();\n\t}\n};\n\n// Create mouseenter/leave events using mouseover/out and event-time checks\njQuery.each({\n\tmouseenter: \"mouseover\",\n\tmouseleave: \"mouseout\",\n\tpointerenter: \"pointerover\",\n\tpointerleave: \"pointerout\"\n}, function( orig, fix ) {\n\tjQuery.event.special[ orig ] = {\n\t\tdelegateType: fix,\n\t\tbindType: fix,\n\n\t\thandle: function( event ) {\n\t\t\tvar ret,\n\t\t\t\ttarget = this,\n\t\t\t\trelated = event.relatedTarget,\n\t\t\t\thandleObj = event.handleObj;\n\n\t\t\t// For mousenter/leave call the handler if related is outside the target.\n\t\t\t// NB: No relatedTarget if the mouse left/entered the browser window\n\t\t\tif ( !related || (related !== target && !jQuery.contains( target, related )) ) {\n\t\t\t\tevent.type = handleObj.origType;\n\t\t\t\tret = handleObj.handler.apply( this, arguments );\n\t\t\t\tevent.type = fix;\n\t\t\t}\n\t\t\treturn ret;\n\t\t}\n\t};\n});\n\n// IE submit delegation\nif ( !support.submitBubbles ) {\n\n\tjQuery.event.special.submit = {\n\t\tsetup: function() {\n\t\t\t// Only need this for delegated form submit events\n\t\t\tif ( jQuery.nodeName( this, \"form\" ) ) {\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\t// Lazy-add a submit handler when a descendant form may potentially be submitted\n\t\t\tjQuery.event.add( this, \"click._submit keypress._submit\", function( e ) {\n\t\t\t\t// Node name check avoids a VML-related crash in IE (#9807)\n\t\t\t\tvar elem = e.target,\n\t\t\t\t\tform = jQuery.nodeName( elem, \"input\" ) || jQuery.nodeName( elem, \"button\" ) ? elem.form : undefined;\n\t\t\t\tif ( form && !jQuery._data( form, \"submitBubbles\" ) ) {\n\t\t\t\t\tjQuery.event.add( form, \"submit._submit\", function( event ) {\n\t\t\t\t\t\tevent._submit_bubble = true;\n\t\t\t\t\t});\n\t\t\t\t\tjQuery._data( form, \"submitBubbles\", true );\n\t\t\t\t}\n\t\t\t});\n\t\t\t// return undefined since we don't need an event listener\n\t\t},\n\n\t\tpostDispatch: function( event ) {\n\t\t\t// If form was submitted by the user, bubble the event up the tree\n\t\t\tif ( event._submit_bubble ) {\n\t\t\t\tdelete event._submit_bubble;\n\t\t\t\tif ( this.parentNode && !event.isTrigger ) {\n\t\t\t\t\tjQuery.event.simulate( \"submit\", this.parentNode, event, true );\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\n\t\tteardown: function() {\n\t\t\t// Only need this for delegated form submit events\n\t\t\tif ( jQuery.nodeName( this, \"form\" ) ) {\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\t// Remove delegated handlers; cleanData eventually reaps submit handlers attached above\n\t\t\tjQuery.event.remove( this, \"._submit\" );\n\t\t}\n\t};\n}\n\n// IE change delegation and checkbox/radio fix\nif ( !support.changeBubbles ) {\n\n\tjQuery.event.special.change = {\n\n\t\tsetup: function() {\n\n\t\t\tif ( rformElems.test( this.nodeName ) ) {\n\t\t\t\t// IE doesn't fire change on a check/radio until blur; trigger it on click\n\t\t\t\t// after a propertychange. Eat the blur-change in special.change.handle.\n\t\t\t\t// This still fires onchange a second time for check/radio after blur.\n\t\t\t\tif ( this.type === \"checkbox\" || this.type === \"radio\" ) {\n\t\t\t\t\tjQuery.event.add( this, \"propertychange._change\", function( event ) {\n\t\t\t\t\t\tif ( event.originalEvent.propertyName === \"checked\" ) {\n\t\t\t\t\t\t\tthis._just_changed = true;\n\t\t\t\t\t\t}\n\t\t\t\t\t});\n\t\t\t\t\tjQuery.event.add( this, \"click._change\", function( event ) {\n\t\t\t\t\t\tif ( this._just_changed && !event.isTrigger ) {\n\t\t\t\t\t\t\tthis._just_changed = false;\n\t\t\t\t\t\t}\n\t\t\t\t\t\t// Allow triggered, simulated change events (#11500)\n\t\t\t\t\t\tjQuery.event.simulate( \"change\", this, event, true );\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\t// Delegated event; lazy-add a change handler on descendant inputs\n\t\t\tjQuery.event.add( this, \"beforeactivate._change\", function( e ) {\n\t\t\t\tvar elem = e.target;\n\n\t\t\t\tif ( rformElems.test( elem.nodeName ) && !jQuery._data( elem, \"changeBubbles\" ) ) {\n\t\t\t\t\tjQuery.event.add( elem, \"change._change\", function( event ) {\n\t\t\t\t\t\tif ( this.parentNode && !event.isSimulated && !event.isTrigger ) {\n\t\t\t\t\t\t\tjQuery.event.simulate( \"change\", this.parentNode, event, true );\n\t\t\t\t\t\t}\n\t\t\t\t\t});\n\t\t\t\t\tjQuery._data( elem, \"changeBubbles\", true );\n\t\t\t\t}\n\t\t\t});\n\t\t},\n\n\t\thandle: function( event ) {\n\t\t\tvar elem = event.target;\n\n\t\t\t// Swallow native change events from checkbox/radio, we already triggered them above\n\t\t\tif ( this !== elem || event.isSimulated || event.isTrigger || (elem.type !== \"radio\" && elem.type !== \"checkbox\") ) {\n\t\t\t\treturn event.handleObj.handler.apply( this, arguments );\n\t\t\t}\n\t\t},\n\n\t\tteardown: function() {\n\t\t\tjQuery.event.remove( this, \"._change\" );\n\n\t\t\treturn !rformElems.test( this.nodeName );\n\t\t}\n\t};\n}\n\n// Create \"bubbling\" focus and blur events\nif ( !support.focusinBubbles ) {\n\tjQuery.each({ focus: \"focusin\", blur: \"focusout\" }, function( orig, fix ) {\n\n\t\t// Attach a single capturing handler on the document while someone wants focusin/focusout\n\t\tvar handler = function( event ) {\n\t\t\t\tjQuery.event.simulate( fix, event.target, jQuery.event.fix( event ), true );\n\t\t\t};\n\n\t\tjQuery.event.special[ fix ] = {\n\t\t\tsetup: function() {\n\t\t\t\tvar doc = this.ownerDocument || this,\n\t\t\t\t\tattaches = jQuery._data( doc, fix );\n\n\t\t\t\tif ( !attaches ) {\n\t\t\t\t\tdoc.addEventListener( orig, handler, true );\n\t\t\t\t}\n\t\t\t\tjQuery._data( doc, fix, ( attaches || 0 ) + 1 );\n\t\t\t},\n\t\t\tteardown: function() {\n\t\t\t\tvar doc = this.ownerDocument || this,\n\t\t\t\t\tattaches = jQuery._data( doc, fix ) - 1;\n\n\t\t\t\tif ( !attaches ) {\n\t\t\t\t\tdoc.removeEventListener( orig, handler, true );\n\t\t\t\t\tjQuery._removeData( doc, fix );\n\t\t\t\t} else {\n\t\t\t\t\tjQuery._data( doc, fix, attaches );\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\t});\n}\n\njQuery.fn.extend({\n\n\ton: function( types, selector, data, fn, /*INTERNAL*/ one ) {\n\t\tvar type, origFn;\n\n\t\t// Types can be a map of types/handlers\n\t\tif ( typeof types === \"object\" ) {\n\t\t\t// ( types-Object, selector, data )\n\t\t\tif ( typeof selector !== \"string\" ) {\n\t\t\t\t// ( types-Object, data )\n\t\t\t\tdata = data || selector;\n\t\t\t\tselector = undefined;\n\t\t\t}\n\t\t\tfor ( type in types ) {\n\t\t\t\tthis.on( type, selector, data, types[ type ], one );\n\t\t\t}\n\t\t\treturn this;\n\t\t}\n\n\t\tif ( data == null && fn == null ) {\n\t\t\t// ( types, fn )\n\t\t\tfn = selector;\n\t\t\tdata = selector = undefined;\n\t\t} else if ( fn == null ) {\n\t\t\tif ( typeof selector === \"string\" ) {\n\t\t\t\t// ( types, selector, fn )\n\t\t\t\tfn = data;\n\t\t\t\tdata = undefined;\n\t\t\t} else {\n\t\t\t\t// ( types, data, fn )\n\t\t\t\tfn = data;\n\t\t\t\tdata = selector;\n\t\t\t\tselector = undefined;\n\t\t\t}\n\t\t}\n\t\tif ( fn === false ) {\n\t\t\tfn = returnFalse;\n\t\t} else if ( !fn ) {\n\t\t\treturn this;\n\t\t}\n\n\t\tif ( one === 1 ) {\n\t\t\torigFn = fn;\n\t\t\tfn = function( event ) {\n\t\t\t\t// Can use an empty set, since event contains the info\n\t\t\t\tjQuery().off( event );\n\t\t\t\treturn origFn.apply( this, arguments );\n\t\t\t};\n\t\t\t// Use same guid so caller can remove using origFn\n\t\t\tfn.guid = origFn.guid || ( origFn.guid = jQuery.guid++ );\n\t\t}\n\t\treturn this.each( function() {\n\t\t\tjQuery.event.add( this, types, fn, data, selector );\n\t\t});\n\t},\n\tone: function( types, selector, data, fn ) {\n\t\treturn this.on( types, selector, data, fn, 1 );\n\t},\n\toff: function( types, selector, fn ) {\n\t\tvar handleObj, type;\n\t\tif ( types && types.preventDefault && types.handleObj ) {\n\t\t\t// ( event )  dispatched jQuery.Event\n\t\t\thandleObj = types.handleObj;\n\t\t\tjQuery( types.delegateTarget ).off(\n\t\t\t\thandleObj.namespace ? handleObj.origType + \".\" + handleObj.namespace : handleObj.origType,\n\t\t\t\thandleObj.selector,\n\t\t\t\thandleObj.handler\n\t\t\t);\n\t\t\treturn this;\n\t\t}\n\t\tif ( typeof types === \"object\" ) {\n\t\t\t// ( types-object [, selector] )\n\t\t\tfor ( type in types ) {\n\t\t\t\tthis.off( type, selector, types[ type ] );\n\t\t\t}\n\t\t\treturn this;\n\t\t}\n\t\tif ( selector === false || typeof selector === \"function\" ) {\n\t\t\t// ( types [, fn] )\n\t\t\tfn = selector;\n\t\t\tselector = undefined;\n\t\t}\n\t\tif ( fn === false ) {\n\t\t\tfn = returnFalse;\n\t\t}\n\t\treturn this.each(function() {\n\t\t\tjQuery.event.remove( this, types, fn, selector );\n\t\t});\n\t},\n\n\ttrigger: function( type, data ) {\n\t\treturn this.each(function() {\n\t\t\tjQuery.event.trigger( type, data, this );\n\t\t});\n\t},\n\ttriggerHandler: function( type, data ) {\n\t\tvar elem = this[0];\n\t\tif ( elem ) {\n\t\t\treturn jQuery.event.trigger( type, data, elem, true );\n\t\t}\n\t}\n});\n\n\nfunction createSafeFragment( document ) {\n\tvar list = nodeNames.split( \"|\" ),\n\t\tsafeFrag = document.createDocumentFragment();\n\n\tif ( safeFrag.createElement ) {\n\t\twhile ( list.length ) {\n\t\t\tsafeFrag.createElement(\n\t\t\t\tlist.pop()\n\t\t\t);\n\t\t}\n\t}\n\treturn safeFrag;\n}\n\nvar nodeNames = \"abbr|article|aside|audio|bdi|canvas|data|datalist|details|figcaption|figure|footer|\" +\n\t\t\"header|hgroup|mark|meter|nav|output|progress|section|summary|time|video\",\n\trinlinejQuery = / jQuery\\d+=\"(?:null|\\d+)\"/g,\n\trnoshimcache = new RegExp(\"<(?:\" + nodeNames + \")[\\\\s/>]\", \"i\"),\n\trleadingWhitespace = /^\\s+/,\n\trxhtmlTag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\\w:]+)[^>]*)\\/>/gi,\n\trtagName = /<([\\w:]+)/,\n\trtbody = /<tbody/i,\n\trhtml = /<|&#?\\w+;/,\n\trnoInnerhtml = /<(?:script|style|link)/i,\n\t// checked=\"checked\" or checked\n\trchecked = /checked\\s*(?:[^=]|=\\s*.checked.)/i,\n\trscriptType = /^$|\\/(?:java|ecma)script/i,\n\trscriptTypeMasked = /^true\\/(.*)/,\n\trcleanScript = /^\\s*<!(?:\\[CDATA\\[|--)|(?:\\]\\]|--)>\\s*$/g,\n\n\t// We have to close these tags to support XHTML (#13200)\n\twrapMap = {\n\t\toption: [ 1, \"<select multiple='multiple'>\", \"</select>\" ],\n\t\tlegend: [ 1, \"<fieldset>\", \"</fieldset>\" ],\n\t\tarea: [ 1, \"<map>\", \"</map>\" ],\n\t\tparam: [ 1, \"<object>\", \"</object>\" ],\n\t\tthead: [ 1, \"<table>\", \"</table>\" ],\n\t\ttr: [ 2, \"<table><tbody>\", \"</tbody></table>\" ],\n\t\tcol: [ 2, \"<table><tbody></tbody><colgroup>\", \"</colgroup></table>\" ],\n\t\ttd: [ 3, \"<table><tbody><tr>\", \"</tr></tbody></table>\" ],\n\n\t\t// IE6-8 can't serialize link, script, style, or any html5 (NoScope) tags,\n\t\t// unless wrapped in a div with non-breaking characters in front of it.\n\t\t_default: support.htmlSerialize ? [ 0, \"\", \"\" ] : [ 1, \"X<div>\", \"</div>\"  ]\n\t},\n\tsafeFragment = createSafeFragment( document ),\n\tfragmentDiv = safeFragment.appendChild( document.createElement(\"div\") );\n\nwrapMap.optgroup = wrapMap.option;\nwrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead;\nwrapMap.th = wrapMap.td;\n\nfunction getAll( context, tag ) {\n\tvar elems, elem,\n\t\ti = 0,\n\t\tfound = typeof context.getElementsByTagName !== strundefined ? context.getElementsByTagName( tag || \"*\" ) :\n\t\t\ttypeof context.querySelectorAll !== strundefined ? context.querySelectorAll( tag || \"*\" ) :\n\t\t\tundefined;\n\n\tif ( !found ) {\n\t\tfor ( found = [], elems = context.childNodes || context; (elem = elems[i]) != null; i++ ) {\n\t\t\tif ( !tag || jQuery.nodeName( elem, tag ) ) {\n\t\t\t\tfound.push( elem );\n\t\t\t} else {\n\t\t\t\tjQuery.merge( found, getAll( elem, tag ) );\n\t\t\t}\n\t\t}\n\t}\n\n\treturn tag === undefined || tag && jQuery.nodeName( context, tag ) ?\n\t\tjQuery.merge( [ context ], found ) :\n\t\tfound;\n}\n\n// Used in buildFragment, fixes the defaultChecked property\nfunction fixDefaultChecked( elem ) {\n\tif ( rcheckableType.test( elem.type ) ) {\n\t\telem.defaultChecked = elem.checked;\n\t}\n}\n\n// Support: IE<8\n// Manipulating tables requires a tbody\nfunction manipulationTarget( elem, content ) {\n\treturn jQuery.nodeName( elem, \"table\" ) &&\n\t\tjQuery.nodeName( content.nodeType !== 11 ? content : content.firstChild, \"tr\" ) ?\n\n\t\telem.getElementsByTagName(\"tbody\")[0] ||\n\t\t\telem.appendChild( elem.ownerDocument.createElement(\"tbody\") ) :\n\t\telem;\n}\n\n// Replace/restore the type attribute of script elements for safe DOM manipulation\nfunction disableScript( elem ) {\n\telem.type = (jQuery.find.attr( elem, \"type\" ) !== null) + \"/\" + elem.type;\n\treturn elem;\n}\nfunction restoreScript( elem ) {\n\tvar match = rscriptTypeMasked.exec( elem.type );\n\tif ( match ) {\n\t\telem.type = match[1];\n\t} else {\n\t\telem.removeAttribute(\"type\");\n\t}\n\treturn elem;\n}\n\n// Mark scripts as having already been evaluated\nfunction setGlobalEval( elems, refElements ) {\n\tvar elem,\n\t\ti = 0;\n\tfor ( ; (elem = elems[i]) != null; i++ ) {\n\t\tjQuery._data( elem, \"globalEval\", !refElements || jQuery._data( refElements[i], \"globalEval\" ) );\n\t}\n}\n\nfunction cloneCopyEvent( src, dest ) {\n\n\tif ( dest.nodeType !== 1 || !jQuery.hasData( src ) ) {\n\t\treturn;\n\t}\n\n\tvar type, i, l,\n\t\toldData = jQuery._data( src ),\n\t\tcurData = jQuery._data( dest, oldData ),\n\t\tevents = oldData.events;\n\n\tif ( events ) {\n\t\tdelete curData.handle;\n\t\tcurData.events = {};\n\n\t\tfor ( type in events ) {\n\t\t\tfor ( i = 0, l = events[ type ].length; i < l; i++ ) {\n\t\t\t\tjQuery.event.add( dest, type, events[ type ][ i ] );\n\t\t\t}\n\t\t}\n\t}\n\n\t// make the cloned public data object a copy from the original\n\tif ( curData.data ) {\n\t\tcurData.data = jQuery.extend( {}, curData.data );\n\t}\n}\n\nfunction fixCloneNodeIssues( src, dest ) {\n\tvar nodeName, e, data;\n\n\t// We do not need to do anything for non-Elements\n\tif ( dest.nodeType !== 1 ) {\n\t\treturn;\n\t}\n\n\tnodeName = dest.nodeName.toLowerCase();\n\n\t// IE6-8 copies events bound via attachEvent when using cloneNode.\n\tif ( !support.noCloneEvent && dest[ jQuery.expando ] ) {\n\t\tdata = jQuery._data( dest );\n\n\t\tfor ( e in data.events ) {\n\t\t\tjQuery.removeEvent( dest, e, data.handle );\n\t\t}\n\n\t\t// Event data gets referenced instead of copied if the expando gets copied too\n\t\tdest.removeAttribute( jQuery.expando );\n\t}\n\n\t// IE blanks contents when cloning scripts, and tries to evaluate newly-set text\n\tif ( nodeName === \"script\" && dest.text !== src.text ) {\n\t\tdisableScript( dest ).text = src.text;\n\t\trestoreScript( dest );\n\n\t// IE6-10 improperly clones children of object elements using classid.\n\t// IE10 throws NoModificationAllowedError if parent is null, #12132.\n\t} else if ( nodeName === \"object\" ) {\n\t\tif ( dest.parentNode ) {\n\t\t\tdest.outerHTML = src.outerHTML;\n\t\t}\n\n\t\t// This path appears unavoidable for IE9. When cloning an object\n\t\t// element in IE9, the outerHTML strategy above is not sufficient.\n\t\t// If the src has innerHTML and the destination does not,\n\t\t// copy the src.innerHTML into the dest.innerHTML. #10324\n\t\tif ( support.html5Clone && ( src.innerHTML && !jQuery.trim(dest.innerHTML) ) ) {\n\t\t\tdest.innerHTML = src.innerHTML;\n\t\t}\n\n\t} else if ( nodeName === \"input\" && rcheckableType.test( src.type ) ) {\n\t\t// IE6-8 fails to persist the checked state of a cloned checkbox\n\t\t// or radio button. Worse, IE6-7 fail to give the cloned element\n\t\t// a checked appearance if the defaultChecked value isn't also set\n\n\t\tdest.defaultChecked = dest.checked = src.checked;\n\n\t\t// IE6-7 get confused and end up setting the value of a cloned\n\t\t// checkbox/radio button to an empty string instead of \"on\"\n\t\tif ( dest.value !== src.value ) {\n\t\t\tdest.value = src.value;\n\t\t}\n\n\t// IE6-8 fails to return the selected option to the default selected\n\t// state when cloning options\n\t} else if ( nodeName === \"option\" ) {\n\t\tdest.defaultSelected = dest.selected = src.defaultSelected;\n\n\t// IE6-8 fails to set the defaultValue to the correct value when\n\t// cloning other types of input fields\n\t} else if ( nodeName === \"input\" || nodeName === \"textarea\" ) {\n\t\tdest.defaultValue = src.defaultValue;\n\t}\n}\n\njQuery.extend({\n\tclone: function( elem, dataAndEvents, deepDataAndEvents ) {\n\t\tvar destElements, node, clone, i, srcElements,\n\t\t\tinPage = jQuery.contains( elem.ownerDocument, elem );\n\n\t\tif ( support.html5Clone || jQuery.isXMLDoc(elem) || !rnoshimcache.test( \"<\" + elem.nodeName + \">\" ) ) {\n\t\t\tclone = elem.cloneNode( true );\n\n\t\t// IE<=8 does not properly clone detached, unknown element nodes\n\t\t} else {\n\t\t\tfragmentDiv.innerHTML = elem.outerHTML;\n\t\t\tfragmentDiv.removeChild( clone = fragmentDiv.firstChild );\n\t\t}\n\n\t\tif ( (!support.noCloneEvent || !support.noCloneChecked) &&\n\t\t\t\t(elem.nodeType === 1 || elem.nodeType === 11) && !jQuery.isXMLDoc(elem) ) {\n\n\t\t\t// We eschew Sizzle here for performance reasons: http://jsperf.com/getall-vs-sizzle/2\n\t\t\tdestElements = getAll( clone );\n\t\t\tsrcElements = getAll( elem );\n\n\t\t\t// Fix all IE cloning issues\n\t\t\tfor ( i = 0; (node = srcElements[i]) != null; ++i ) {\n\t\t\t\t// Ensure that the destination node is not null; Fixes #9587\n\t\t\t\tif ( destElements[i] ) {\n\t\t\t\t\tfixCloneNodeIssues( node, destElements[i] );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Copy the events from the original to the clone\n\t\tif ( dataAndEvents ) {\n\t\t\tif ( deepDataAndEvents ) {\n\t\t\t\tsrcElements = srcElements || getAll( elem );\n\t\t\t\tdestElements = destElements || getAll( clone );\n\n\t\t\t\tfor ( i = 0; (node = srcElements[i]) != null; i++ ) {\n\t\t\t\t\tcloneCopyEvent( node, destElements[i] );\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tcloneCopyEvent( elem, clone );\n\t\t\t}\n\t\t}\n\n\t\t// Preserve script evaluation history\n\t\tdestElements = getAll( clone, \"script\" );\n\t\tif ( destElements.length > 0 ) {\n\t\t\tsetGlobalEval( destElements, !inPage && getAll( elem, \"script\" ) );\n\t\t}\n\n\t\tdestElements = srcElements = node = null;\n\n\t\t// Return the cloned set\n\t\treturn clone;\n\t},\n\n\tbuildFragment: function( elems, context, scripts, selection ) {\n\t\tvar j, elem, contains,\n\t\t\ttmp, tag, tbody, wrap,\n\t\t\tl = elems.length,\n\n\t\t\t// Ensure a safe fragment\n\t\t\tsafe = createSafeFragment( context ),\n\n\t\t\tnodes = [],\n\t\t\ti = 0;\n\n\t\tfor ( ; i < l; i++ ) {\n\t\t\telem = elems[ i ];\n\n\t\t\tif ( elem || elem === 0 ) {\n\n\t\t\t\t// Add nodes directly\n\t\t\t\tif ( jQuery.type( elem ) === \"object\" ) {\n\t\t\t\t\tjQuery.merge( nodes, elem.nodeType ? [ elem ] : elem );\n\n\t\t\t\t// Convert non-html into a text node\n\t\t\t\t} else if ( !rhtml.test( elem ) ) {\n\t\t\t\t\tnodes.push( context.createTextNode( elem ) );\n\n\t\t\t\t// Convert html into DOM nodes\n\t\t\t\t} else {\n\t\t\t\t\ttmp = tmp || safe.appendChild( context.createElement(\"div\") );\n\n\t\t\t\t\t// Deserialize a standard representation\n\t\t\t\t\ttag = (rtagName.exec( elem ) || [ \"\", \"\" ])[ 1 ].toLowerCase();\n\t\t\t\t\twrap = wrapMap[ tag ] || wrapMap._default;\n\n\t\t\t\t\ttmp.innerHTML = wrap[1] + elem.replace( rxhtmlTag, \"<$1></$2>\" ) + wrap[2];\n\n\t\t\t\t\t// Descend through wrappers to the right content\n\t\t\t\t\tj = wrap[0];\n\t\t\t\t\twhile ( j-- ) {\n\t\t\t\t\t\ttmp = tmp.lastChild;\n\t\t\t\t\t}\n\n\t\t\t\t\t// Manually add leading whitespace removed by IE\n\t\t\t\t\tif ( !support.leadingWhitespace && rleadingWhitespace.test( elem ) ) {\n\t\t\t\t\t\tnodes.push( context.createTextNode( rleadingWhitespace.exec( elem )[0] ) );\n\t\t\t\t\t}\n\n\t\t\t\t\t// Remove IE's autoinserted <tbody> from table fragments\n\t\t\t\t\tif ( !support.tbody ) {\n\n\t\t\t\t\t\t// String was a <table>, *may* have spurious <tbody>\n\t\t\t\t\t\telem = tag === \"table\" && !rtbody.test( elem ) ?\n\t\t\t\t\t\t\ttmp.firstChild :\n\n\t\t\t\t\t\t\t// String was a bare <thead> or <tfoot>\n\t\t\t\t\t\t\twrap[1] === \"<table>\" && !rtbody.test( elem ) ?\n\t\t\t\t\t\t\t\ttmp :\n\t\t\t\t\t\t\t\t0;\n\n\t\t\t\t\t\tj = elem && elem.childNodes.length;\n\t\t\t\t\t\twhile ( j-- ) {\n\t\t\t\t\t\t\tif ( jQuery.nodeName( (tbody = elem.childNodes[j]), \"tbody\" ) && !tbody.childNodes.length ) {\n\t\t\t\t\t\t\t\telem.removeChild( tbody );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tjQuery.merge( nodes, tmp.childNodes );\n\n\t\t\t\t\t// Fix #12392 for WebKit and IE > 9\n\t\t\t\t\ttmp.textContent = \"\";\n\n\t\t\t\t\t// Fix #12392 for oldIE\n\t\t\t\t\twhile ( tmp.firstChild ) {\n\t\t\t\t\t\ttmp.removeChild( tmp.firstChild );\n\t\t\t\t\t}\n\n\t\t\t\t\t// Remember the top-level container for proper cleanup\n\t\t\t\t\ttmp = safe.lastChild;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Fix #11356: Clear elements from fragment\n\t\tif ( tmp ) {\n\t\t\tsafe.removeChild( tmp );\n\t\t}\n\n\t\t// Reset defaultChecked for any radios and checkboxes\n\t\t// about to be appended to the DOM in IE 6/7 (#8060)\n\t\tif ( !support.appendChecked ) {\n\t\t\tjQuery.grep( getAll( nodes, \"input\" ), fixDefaultChecked );\n\t\t}\n\n\t\ti = 0;\n\t\twhile ( (elem = nodes[ i++ ]) ) {\n\n\t\t\t// #4087 - If origin and destination elements are the same, and this is\n\t\t\t// that element, do not do anything\n\t\t\tif ( selection && jQuery.inArray( elem, selection ) !== -1 ) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tcontains = jQuery.contains( elem.ownerDocument, elem );\n\n\t\t\t// Append to fragment\n\t\t\ttmp = getAll( safe.appendChild( elem ), \"script\" );\n\n\t\t\t// Preserve script evaluation history\n\t\t\tif ( contains ) {\n\t\t\t\tsetGlobalEval( tmp );\n\t\t\t}\n\n\t\t\t// Capture executables\n\t\t\tif ( scripts ) {\n\t\t\t\tj = 0;\n\t\t\t\twhile ( (elem = tmp[ j++ ]) ) {\n\t\t\t\t\tif ( rscriptType.test( elem.type || \"\" ) ) {\n\t\t\t\t\t\tscripts.push( elem );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\ttmp = null;\n\n\t\treturn safe;\n\t},\n\n\tcleanData: function( elems, /* internal */ acceptData ) {\n\t\tvar elem, type, id, data,\n\t\t\ti = 0,\n\t\t\tinternalKey = jQuery.expando,\n\t\t\tcache = jQuery.cache,\n\t\t\tdeleteExpando = support.deleteExpando,\n\t\t\tspecial = jQuery.event.special;\n\n\t\tfor ( ; (elem = elems[i]) != null; i++ ) {\n\t\t\tif ( acceptData || jQuery.acceptData( elem ) ) {\n\n\t\t\t\tid = elem[ internalKey ];\n\t\t\t\tdata = id && cache[ id ];\n\n\t\t\t\tif ( data ) {\n\t\t\t\t\tif ( data.events ) {\n\t\t\t\t\t\tfor ( type in data.events ) {\n\t\t\t\t\t\t\tif ( special[ type ] ) {\n\t\t\t\t\t\t\t\tjQuery.event.remove( elem, type );\n\n\t\t\t\t\t\t\t// This is a shortcut to avoid jQuery.event.remove's overhead\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tjQuery.removeEvent( elem, type, data.handle );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\t// Remove cache only if it was not already removed by jQuery.event.remove\n\t\t\t\t\tif ( cache[ id ] ) {\n\n\t\t\t\t\t\tdelete cache[ id ];\n\n\t\t\t\t\t\t// IE does not allow us to delete expando properties from nodes,\n\t\t\t\t\t\t// nor does it have a removeAttribute function on Document nodes;\n\t\t\t\t\t\t// we must handle all of these cases\n\t\t\t\t\t\tif ( deleteExpando ) {\n\t\t\t\t\t\t\tdelete elem[ internalKey ];\n\n\t\t\t\t\t\t} else if ( typeof elem.removeAttribute !== strundefined ) {\n\t\t\t\t\t\t\telem.removeAttribute( internalKey );\n\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\telem[ internalKey ] = null;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tdeletedIds.push( id );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n});\n\njQuery.fn.extend({\n\ttext: function( value ) {\n\t\treturn access( this, function( value ) {\n\t\t\treturn value === undefined ?\n\t\t\t\tjQuery.text( this ) :\n\t\t\t\tthis.empty().append( ( this[0] && this[0].ownerDocument || document ).createTextNode( value ) );\n\t\t}, null, value, arguments.length );\n\t},\n\n\tappend: function() {\n\t\treturn this.domManip( arguments, function( elem ) {\n\t\t\tif ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) {\n\t\t\t\tvar target = manipulationTarget( this, elem );\n\t\t\t\ttarget.appendChild( elem );\n\t\t\t}\n\t\t});\n\t},\n\n\tprepend: function() {\n\t\treturn this.domManip( arguments, function( elem ) {\n\t\t\tif ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) {\n\t\t\t\tvar target = manipulationTarget( this, elem );\n\t\t\t\ttarget.insertBefore( elem, target.firstChild );\n\t\t\t}\n\t\t});\n\t},\n\n\tbefore: function() {\n\t\treturn this.domManip( arguments, function( elem ) {\n\t\t\tif ( this.parentNode ) {\n\t\t\t\tthis.parentNode.insertBefore( elem, this );\n\t\t\t}\n\t\t});\n\t},\n\n\tafter: function() {\n\t\treturn this.domManip( arguments, function( elem ) {\n\t\t\tif ( this.parentNode ) {\n\t\t\t\tthis.parentNode.insertBefore( elem, this.nextSibling );\n\t\t\t}\n\t\t});\n\t},\n\n\tremove: function( selector, keepData /* Internal Use Only */ ) {\n\t\tvar elem,\n\t\t\telems = selector ? jQuery.filter( selector, this ) : this,\n\t\t\ti = 0;\n\n\t\tfor ( ; (elem = elems[i]) != null; i++ ) {\n\n\t\t\tif ( !keepData && elem.nodeType === 1 ) {\n\t\t\t\tjQuery.cleanData( getAll( elem ) );\n\t\t\t}\n\n\t\t\tif ( elem.parentNode ) {\n\t\t\t\tif ( keepData && jQuery.contains( elem.ownerDocument, elem ) ) {\n\t\t\t\t\tsetGlobalEval( getAll( elem, \"script\" ) );\n\t\t\t\t}\n\t\t\t\telem.parentNode.removeChild( elem );\n\t\t\t}\n\t\t}\n\n\t\treturn this;\n\t},\n\n\tempty: function() {\n\t\tvar elem,\n\t\t\ti = 0;\n\n\t\tfor ( ; (elem = this[i]) != null; i++ ) {\n\t\t\t// Remove element nodes and prevent memory leaks\n\t\t\tif ( elem.nodeType === 1 ) {\n\t\t\t\tjQuery.cleanData( getAll( elem, false ) );\n\t\t\t}\n\n\t\t\t// Remove any remaining nodes\n\t\t\twhile ( elem.firstChild ) {\n\t\t\t\telem.removeChild( elem.firstChild );\n\t\t\t}\n\n\t\t\t// If this is a select, ensure that it displays empty (#12336)\n\t\t\t// Support: IE<9\n\t\t\tif ( elem.options && jQuery.nodeName( elem, \"select\" ) ) {\n\t\t\t\telem.options.length = 0;\n\t\t\t}\n\t\t}\n\n\t\treturn this;\n\t},\n\n\tclone: function( dataAndEvents, deepDataAndEvents ) {\n\t\tdataAndEvents = dataAndEvents == null ? false : dataAndEvents;\n\t\tdeepDataAndEvents = deepDataAndEvents == null ? dataAndEvents : deepDataAndEvents;\n\n\t\treturn this.map(function() {\n\t\t\treturn jQuery.clone( this, dataAndEvents, deepDataAndEvents );\n\t\t});\n\t},\n\n\thtml: function( value ) {\n\t\treturn access( this, function( value ) {\n\t\t\tvar elem = this[ 0 ] || {},\n\t\t\t\ti = 0,\n\t\t\t\tl = this.length;\n\n\t\t\tif ( value === undefined ) {\n\t\t\t\treturn elem.nodeType === 1 ?\n\t\t\t\t\telem.innerHTML.replace( rinlinejQuery, \"\" ) :\n\t\t\t\t\tundefined;\n\t\t\t}\n\n\t\t\t// See if we can take a shortcut and just use innerHTML\n\t\t\tif ( typeof value === \"string\" && !rnoInnerhtml.test( value ) &&\n\t\t\t\t( support.htmlSerialize || !rnoshimcache.test( value )  ) &&\n\t\t\t\t( support.leadingWhitespace || !rleadingWhitespace.test( value ) ) &&\n\t\t\t\t!wrapMap[ (rtagName.exec( value ) || [ \"\", \"\" ])[ 1 ].toLowerCase() ] ) {\n\n\t\t\t\tvalue = value.replace( rxhtmlTag, \"<$1></$2>\" );\n\n\t\t\t\ttry {\n\t\t\t\t\tfor (; i < l; i++ ) {\n\t\t\t\t\t\t// Remove element nodes and prevent memory leaks\n\t\t\t\t\t\telem = this[i] || {};\n\t\t\t\t\t\tif ( elem.nodeType === 1 ) {\n\t\t\t\t\t\t\tjQuery.cleanData( getAll( elem, false ) );\n\t\t\t\t\t\t\telem.innerHTML = value;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\telem = 0;\n\n\t\t\t\t// If using innerHTML throws an exception, use the fallback method\n\t\t\t\t} catch(e) {}\n\t\t\t}\n\n\t\t\tif ( elem ) {\n\t\t\t\tthis.empty().append( value );\n\t\t\t}\n\t\t}, null, value, arguments.length );\n\t},\n\n\treplaceWith: function() {\n\t\tvar arg = arguments[ 0 ];\n\n\t\t// Make the changes, replacing each context element with the new content\n\t\tthis.domManip( arguments, function( elem ) {\n\t\t\targ = this.parentNode;\n\n\t\t\tjQuery.cleanData( getAll( this ) );\n\n\t\t\tif ( arg ) {\n\t\t\t\targ.replaceChild( elem, this );\n\t\t\t}\n\t\t});\n\n\t\t// Force removal if there was no new content (e.g., from empty arguments)\n\t\treturn arg && (arg.length || arg.nodeType) ? this : this.remove();\n\t},\n\n\tdetach: function( selector ) {\n\t\treturn this.remove( selector, true );\n\t},\n\n\tdomManip: function( args, callback ) {\n\n\t\t// Flatten any nested arrays\n\t\targs = concat.apply( [], args );\n\n\t\tvar first, node, hasScripts,\n\t\t\tscripts, doc, fragment,\n\t\t\ti = 0,\n\t\t\tl = this.length,\n\t\t\tset = this,\n\t\t\tiNoClone = l - 1,\n\t\t\tvalue = args[0],\n\t\t\tisFunction = jQuery.isFunction( value );\n\n\t\t// We can't cloneNode fragments that contain checked, in WebKit\n\t\tif ( isFunction ||\n\t\t\t\t( l > 1 && typeof value === \"string\" &&\n\t\t\t\t\t!support.checkClone && rchecked.test( value ) ) ) {\n\t\t\treturn this.each(function( index ) {\n\t\t\t\tvar self = set.eq( index );\n\t\t\t\tif ( isFunction ) {\n\t\t\t\t\targs[0] = value.call( this, index, self.html() );\n\t\t\t\t}\n\t\t\t\tself.domManip( args, callback );\n\t\t\t});\n\t\t}\n\n\t\tif ( l ) {\n\t\t\tfragment = jQuery.buildFragment( args, this[ 0 ].ownerDocument, false, this );\n\t\t\tfirst = fragment.firstChild;\n\n\t\t\tif ( fragment.childNodes.length === 1 ) {\n\t\t\t\tfragment = first;\n\t\t\t}\n\n\t\t\tif ( first ) {\n\t\t\t\tscripts = jQuery.map( getAll( fragment, \"script\" ), disableScript );\n\t\t\t\thasScripts = scripts.length;\n\n\t\t\t\t// Use the original fragment for the last item instead of the first because it can end up\n\t\t\t\t// being emptied incorrectly in certain situations (#8070).\n\t\t\t\tfor ( ; i < l; i++ ) {\n\t\t\t\t\tnode = fragment;\n\n\t\t\t\t\tif ( i !== iNoClone ) {\n\t\t\t\t\t\tnode = jQuery.clone( node, true, true );\n\n\t\t\t\t\t\t// Keep references to cloned scripts for later restoration\n\t\t\t\t\t\tif ( hasScripts ) {\n\t\t\t\t\t\t\tjQuery.merge( scripts, getAll( node, \"script\" ) );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tcallback.call( this[i], node, i );\n\t\t\t\t}\n\n\t\t\t\tif ( hasScripts ) {\n\t\t\t\t\tdoc = scripts[ scripts.length - 1 ].ownerDocument;\n\n\t\t\t\t\t// Reenable scripts\n\t\t\t\t\tjQuery.map( scripts, restoreScript );\n\n\t\t\t\t\t// Evaluate executable scripts on first document insertion\n\t\t\t\t\tfor ( i = 0; i < hasScripts; i++ ) {\n\t\t\t\t\t\tnode = scripts[ i ];\n\t\t\t\t\t\tif ( rscriptType.test( node.type || \"\" ) &&\n\t\t\t\t\t\t\t!jQuery._data( node, \"globalEval\" ) && jQuery.contains( doc, node ) ) {\n\n\t\t\t\t\t\t\tif ( node.src ) {\n\t\t\t\t\t\t\t\t// Optional AJAX dependency, but won't run scripts if not present\n\t\t\t\t\t\t\t\tif ( jQuery._evalUrl ) {\n\t\t\t\t\t\t\t\t\tjQuery._evalUrl( node.src );\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tjQuery.globalEval( ( node.text || node.textContent || node.innerHTML || \"\" ).replace( rcleanScript, \"\" ) );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// Fix #11809: Avoid leaking memory\n\t\t\t\tfragment = first = null;\n\t\t\t}\n\t\t}\n\n\t\treturn this;\n\t}\n});\n\njQuery.each({\n\tappendTo: \"append\",\n\tprependTo: \"prepend\",\n\tinsertBefore: \"before\",\n\tinsertAfter: \"after\",\n\treplaceAll: \"replaceWith\"\n}, function( name, original ) {\n\tjQuery.fn[ name ] = function( selector ) {\n\t\tvar elems,\n\t\t\ti = 0,\n\t\t\tret = [],\n\t\t\tinsert = jQuery( selector ),\n\t\t\tlast = insert.length - 1;\n\n\t\tfor ( ; i <= last; i++ ) {\n\t\t\telems = i === last ? this : this.clone(true);\n\t\t\tjQuery( insert[i] )[ original ]( elems );\n\n\t\t\t// Modern browsers can apply jQuery collections as arrays, but oldIE needs a .get()\n\t\t\tpush.apply( ret, elems.get() );\n\t\t}\n\n\t\treturn this.pushStack( ret );\n\t};\n});\n\n\nvar iframe,\n\telemdisplay = {};\n\n/**\n * Retrieve the actual display of a element\n * @param {String} name nodeName of the element\n * @param {Object} doc Document object\n */\n// Called only from within defaultDisplay\nfunction actualDisplay( name, doc ) {\n\tvar style,\n\t\telem = jQuery( doc.createElement( name ) ).appendTo( doc.body ),\n\n\t\t// getDefaultComputedStyle might be reliably used only on attached element\n\t\tdisplay = window.getDefaultComputedStyle && ( style = window.getDefaultComputedStyle( elem[ 0 ] ) ) ?\n\n\t\t\t// Use of this method is a temporary fix (more like optmization) until something better comes along,\n\t\t\t// since it was removed from specification and supported only in FF\n\t\t\tstyle.display : jQuery.css( elem[ 0 ], \"display\" );\n\n\t// We don't have any data stored on the element,\n\t// so use \"detach\" method as fast way to get rid of the element\n\telem.detach();\n\n\treturn display;\n}\n\n/**\n * Try to determine the default display value of an element\n * @param {String} nodeName\n */\nfunction defaultDisplay( nodeName ) {\n\tvar doc = document,\n\t\tdisplay = elemdisplay[ nodeName ];\n\n\tif ( !display ) {\n\t\tdisplay = actualDisplay( nodeName, doc );\n\n\t\t// If the simple way fails, read from inside an iframe\n\t\tif ( display === \"none\" || !display ) {\n\n\t\t\t// Use the already-created iframe if possible\n\t\t\tiframe = (iframe || jQuery( \"<iframe frameborder='0' width='0' height='0'/>\" )).appendTo( doc.documentElement );\n\n\t\t\t// Always write a new HTML skeleton so Webkit and Firefox don't choke on reuse\n\t\t\tdoc = ( iframe[ 0 ].contentWindow || iframe[ 0 ].contentDocument ).document;\n\n\t\t\t// Support: IE\n\t\t\tdoc.write();\n\t\t\tdoc.close();\n\n\t\t\tdisplay = actualDisplay( nodeName, doc );\n\t\t\tiframe.detach();\n\t\t}\n\n\t\t// Store the correct default display\n\t\telemdisplay[ nodeName ] = display;\n\t}\n\n\treturn display;\n}\n\n\n(function() {\n\tvar shrinkWrapBlocksVal;\n\n\tsupport.shrinkWrapBlocks = function() {\n\t\tif ( shrinkWrapBlocksVal != null ) {\n\t\t\treturn shrinkWrapBlocksVal;\n\t\t}\n\n\t\t// Will be changed later if needed.\n\t\tshrinkWrapBlocksVal = false;\n\n\t\t// Minified: var b,c,d\n\t\tvar div, body, container;\n\n\t\tbody = document.getElementsByTagName( \"body\" )[ 0 ];\n\t\tif ( !body || !body.style ) {\n\t\t\t// Test fired too early or in an unsupported environment, exit.\n\t\t\treturn;\n\t\t}\n\n\t\t// Setup\n\t\tdiv = document.createElement( \"div\" );\n\t\tcontainer = document.createElement( \"div\" );\n\t\tcontainer.style.cssText = \"position:absolute;border:0;width:0;height:0;top:0;left:-9999px\";\n\t\tbody.appendChild( container ).appendChild( div );\n\n\t\t// Support: IE6\n\t\t// Check if elements with layout shrink-wrap their children\n\t\tif ( typeof div.style.zoom !== strundefined ) {\n\t\t\t// Reset CSS: box-sizing; display; margin; border\n\t\t\tdiv.style.cssText =\n\t\t\t\t// Support: Firefox<29, Android 2.3\n\t\t\t\t// Vendor-prefix box-sizing\n\t\t\t\t\"-webkit-box-sizing:content-box;-moz-box-sizing:content-box;\" +\n\t\t\t\t\"box-sizing:content-box;display:block;margin:0;border:0;\" +\n\t\t\t\t\"padding:1px;width:1px;zoom:1\";\n\t\t\tdiv.appendChild( document.createElement( \"div\" ) ).style.width = \"5px\";\n\t\t\tshrinkWrapBlocksVal = div.offsetWidth !== 3;\n\t\t}\n\n\t\tbody.removeChild( container );\n\n\t\treturn shrinkWrapBlocksVal;\n\t};\n\n})();\nvar rmargin = (/^margin/);\n\nvar rnumnonpx = new RegExp( \"^(\" + pnum + \")(?!px)[a-z%]+$\", \"i\" );\n\n\n\nvar getStyles, curCSS,\n\trposition = /^(top|right|bottom|left)$/;\n\nif ( window.getComputedStyle ) {\n\tgetStyles = function( elem ) {\n\t\t// Support: IE<=11+, Firefox<=30+ (#15098, #14150)\n\t\t// IE throws on elements created in popups\n\t\t// FF meanwhile throws on frame elements through \"defaultView.getComputedStyle\"\n\t\tif ( elem.ownerDocument.defaultView.opener ) {\n\t\t\treturn elem.ownerDocument.defaultView.getComputedStyle( elem, null );\n\t\t}\n\n\t\treturn window.getComputedStyle( elem, null );\n\t};\n\n\tcurCSS = function( elem, name, computed ) {\n\t\tvar width, minWidth, maxWidth, ret,\n\t\t\tstyle = elem.style;\n\n\t\tcomputed = computed || getStyles( elem );\n\n\t\t// getPropertyValue is only needed for .css('filter') in IE9, see #12537\n\t\tret = computed ? computed.getPropertyValue( name ) || computed[ name ] : undefined;\n\n\t\tif ( computed ) {\n\n\t\t\tif ( ret === \"\" && !jQuery.contains( elem.ownerDocument, elem ) ) {\n\t\t\t\tret = jQuery.style( elem, name );\n\t\t\t}\n\n\t\t\t// A tribute to the \"awesome hack by Dean Edwards\"\n\t\t\t// Chrome < 17 and Safari 5.0 uses \"computed value\" instead of \"used value\" for margin-right\n\t\t\t// Safari 5.1.7 (at least) returns percentage for a larger set of values, but width seems to be reliably pixels\n\t\t\t// this is against the CSSOM draft spec: http://dev.w3.org/csswg/cssom/#resolved-values\n\t\t\tif ( rnumnonpx.test( ret ) && rmargin.test( name ) ) {\n\n\t\t\t\t// Remember the original values\n\t\t\t\twidth = style.width;\n\t\t\t\tminWidth = style.minWidth;\n\t\t\t\tmaxWidth = style.maxWidth;\n\n\t\t\t\t// Put in the new values to get a computed value out\n\t\t\t\tstyle.minWidth = style.maxWidth = style.width = ret;\n\t\t\t\tret = computed.width;\n\n\t\t\t\t// Revert the changed values\n\t\t\t\tstyle.width = width;\n\t\t\t\tstyle.minWidth = minWidth;\n\t\t\t\tstyle.maxWidth = maxWidth;\n\t\t\t}\n\t\t}\n\n\t\t// Support: IE\n\t\t// IE returns zIndex value as an integer.\n\t\treturn ret === undefined ?\n\t\t\tret :\n\t\t\tret + \"\";\n\t};\n} else if ( document.documentElement.currentStyle ) {\n\tgetStyles = function( elem ) {\n\t\treturn elem.currentStyle;\n\t};\n\n\tcurCSS = function( elem, name, computed ) {\n\t\tvar left, rs, rsLeft, ret,\n\t\t\tstyle = elem.style;\n\n\t\tcomputed = computed || getStyles( elem );\n\t\tret = computed ? computed[ name ] : undefined;\n\n\t\t// Avoid setting ret to empty string here\n\t\t// so we don't default to auto\n\t\tif ( ret == null && style && style[ name ] ) {\n\t\t\tret = style[ name ];\n\t\t}\n\n\t\t// From the awesome hack by Dean Edwards\n\t\t// http://erik.eae.net/archives/2007/07/27/18.54.15/#comment-102291\n\n\t\t// If we're not dealing with a regular pixel number\n\t\t// but a number that has a weird ending, we need to convert it to pixels\n\t\t// but not position css attributes, as those are proportional to the parent element instead\n\t\t// and we can't measure the parent instead because it might trigger a \"stacking dolls\" problem\n\t\tif ( rnumnonpx.test( ret ) && !rposition.test( name ) ) {\n\n\t\t\t// Remember the original values\n\t\t\tleft = style.left;\n\t\t\trs = elem.runtimeStyle;\n\t\t\trsLeft = rs && rs.left;\n\n\t\t\t// Put in the new values to get a computed value out\n\t\t\tif ( rsLeft ) {\n\t\t\t\trs.left = elem.currentStyle.left;\n\t\t\t}\n\t\t\tstyle.left = name === \"fontSize\" ? \"1em\" : ret;\n\t\t\tret = style.pixelLeft + \"px\";\n\n\t\t\t// Revert the changed values\n\t\t\tstyle.left = left;\n\t\t\tif ( rsLeft ) {\n\t\t\t\trs.left = rsLeft;\n\t\t\t}\n\t\t}\n\n\t\t// Support: IE\n\t\t// IE returns zIndex value as an integer.\n\t\treturn ret === undefined ?\n\t\t\tret :\n\t\t\tret + \"\" || \"auto\";\n\t};\n}\n\n\n\n\nfunction addGetHookIf( conditionFn, hookFn ) {\n\t// Define the hook, we'll check on the first run if it's really needed.\n\treturn {\n\t\tget: function() {\n\t\t\tvar condition = conditionFn();\n\n\t\t\tif ( condition == null ) {\n\t\t\t\t// The test was not ready at this point; screw the hook this time\n\t\t\t\t// but check again when needed next time.\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif ( condition ) {\n\t\t\t\t// Hook not needed (or it's not possible to use it due to missing dependency),\n\t\t\t\t// remove it.\n\t\t\t\t// Since there are no other hooks for marginRight, remove the whole object.\n\t\t\t\tdelete this.get;\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// Hook needed; redefine it so that the support test is not executed again.\n\n\t\t\treturn (this.get = hookFn).apply( this, arguments );\n\t\t}\n\t};\n}\n\n\n(function() {\n\t// Minified: var b,c,d,e,f,g, h,i\n\tvar div, style, a, pixelPositionVal, boxSizingReliableVal,\n\t\treliableHiddenOffsetsVal, reliableMarginRightVal;\n\n\t// Setup\n\tdiv = document.createElement( \"div\" );\n\tdiv.innerHTML = \"  <link/><table></table><a href='/a'>a</a><input type='checkbox'/>\";\n\ta = div.getElementsByTagName( \"a\" )[ 0 ];\n\tstyle = a && a.style;\n\n\t// Finish early in limited (non-browser) environments\n\tif ( !style ) {\n\t\treturn;\n\t}\n\n\tstyle.cssText = \"float:left;opacity:.5\";\n\n\t// Support: IE<9\n\t// Make sure that element opacity exists (as opposed to filter)\n\tsupport.opacity = style.opacity === \"0.5\";\n\n\t// Verify style float existence\n\t// (IE uses styleFloat instead of cssFloat)\n\tsupport.cssFloat = !!style.cssFloat;\n\n\tdiv.style.backgroundClip = \"content-box\";\n\tdiv.cloneNode( true ).style.backgroundClip = \"\";\n\tsupport.clearCloneStyle = div.style.backgroundClip === \"content-box\";\n\n\t// Support: Firefox<29, Android 2.3\n\t// Vendor-prefix box-sizing\n\tsupport.boxSizing = style.boxSizing === \"\" || style.MozBoxSizing === \"\" ||\n\t\tstyle.WebkitBoxSizing === \"\";\n\n\tjQuery.extend(support, {\n\t\treliableHiddenOffsets: function() {\n\t\t\tif ( reliableHiddenOffsetsVal == null ) {\n\t\t\t\tcomputeStyleTests();\n\t\t\t}\n\t\t\treturn reliableHiddenOffsetsVal;\n\t\t},\n\n\t\tboxSizingReliable: function() {\n\t\t\tif ( boxSizingReliableVal == null ) {\n\t\t\t\tcomputeStyleTests();\n\t\t\t}\n\t\t\treturn boxSizingReliableVal;\n\t\t},\n\n\t\tpixelPosition: function() {\n\t\t\tif ( pixelPositionVal == null ) {\n\t\t\t\tcomputeStyleTests();\n\t\t\t}\n\t\t\treturn pixelPositionVal;\n\t\t},\n\n\t\t// Support: Android 2.3\n\t\treliableMarginRight: function() {\n\t\t\tif ( reliableMarginRightVal == null ) {\n\t\t\t\tcomputeStyleTests();\n\t\t\t}\n\t\t\treturn reliableMarginRightVal;\n\t\t}\n\t});\n\n\tfunction computeStyleTests() {\n\t\t// Minified: var b,c,d,j\n\t\tvar div, body, container, contents;\n\n\t\tbody = document.getElementsByTagName( \"body\" )[ 0 ];\n\t\tif ( !body || !body.style ) {\n\t\t\t// Test fired too early or in an unsupported environment, exit.\n\t\t\treturn;\n\t\t}\n\n\t\t// Setup\n\t\tdiv = document.createElement( \"div\" );\n\t\tcontainer = document.createElement( \"div\" );\n\t\tcontainer.style.cssText = \"position:absolute;border:0;width:0;height:0;top:0;left:-9999px\";\n\t\tbody.appendChild( container ).appendChild( div );\n\n\t\tdiv.style.cssText =\n\t\t\t// Support: Firefox<29, Android 2.3\n\t\t\t// Vendor-prefix box-sizing\n\t\t\t\"-webkit-box-sizing:border-box;-moz-box-sizing:border-box;\" +\n\t\t\t\"box-sizing:border-box;display:block;margin-top:1%;top:1%;\" +\n\t\t\t\"border:1px;padding:1px;width:4px;position:absolute\";\n\n\t\t// Support: IE<9\n\t\t// Assume reasonable values in the absence of getComputedStyle\n\t\tpixelPositionVal = boxSizingReliableVal = false;\n\t\treliableMarginRightVal = true;\n\n\t\t// Check for getComputedStyle so that this code is not run in IE<9.\n\t\tif ( window.getComputedStyle ) {\n\t\t\tpixelPositionVal = ( window.getComputedStyle( div, null ) || {} ).top !== \"1%\";\n\t\t\tboxSizingReliableVal =\n\t\t\t\t( window.getComputedStyle( div, null ) || { width: \"4px\" } ).width === \"4px\";\n\n\t\t\t// Support: Android 2.3\n\t\t\t// Div with explicit width and no margin-right incorrectly\n\t\t\t// gets computed margin-right based on width of container (#3333)\n\t\t\t// WebKit Bug 13343 - getComputedStyle returns wrong value for margin-right\n\t\t\tcontents = div.appendChild( document.createElement( \"div\" ) );\n\n\t\t\t// Reset CSS: box-sizing; display; margin; border; padding\n\t\t\tcontents.style.cssText = div.style.cssText =\n\t\t\t\t// Support: Firefox<29, Android 2.3\n\t\t\t\t// Vendor-prefix box-sizing\n\t\t\t\t\"-webkit-box-sizing:content-box;-moz-box-sizing:content-box;\" +\n\t\t\t\t\"box-sizing:content-box;display:block;margin:0;border:0;padding:0\";\n\t\t\tcontents.style.marginRight = contents.style.width = \"0\";\n\t\t\tdiv.style.width = \"1px\";\n\n\t\t\treliableMarginRightVal =\n\t\t\t\t!parseFloat( ( window.getComputedStyle( contents, null ) || {} ).marginRight );\n\n\t\t\tdiv.removeChild( contents );\n\t\t}\n\n\t\t// Support: IE8\n\t\t// Check if table cells still have offsetWidth/Height when they are set\n\t\t// to display:none and there are still other visible table cells in a\n\t\t// table row; if so, offsetWidth/Height are not reliable for use when\n\t\t// determining if an element has been hidden directly using\n\t\t// display:none (it is still safe to use offsets if a parent element is\n\t\t// hidden; don safety goggles and see bug #4512 for more information).\n\t\tdiv.innerHTML = \"<table><tr><td></td><td>t</td></tr></table>\";\n\t\tcontents = div.getElementsByTagName( \"td\" );\n\t\tcontents[ 0 ].style.cssText = \"margin:0;border:0;padding:0;display:none\";\n\t\treliableHiddenOffsetsVal = contents[ 0 ].offsetHeight === 0;\n\t\tif ( reliableHiddenOffsetsVal ) {\n\t\t\tcontents[ 0 ].style.display = \"\";\n\t\t\tcontents[ 1 ].style.display = \"none\";\n\t\t\treliableHiddenOffsetsVal = contents[ 0 ].offsetHeight === 0;\n\t\t}\n\n\t\tbody.removeChild( container );\n\t}\n\n})();\n\n\n// A method for quickly swapping in/out CSS properties to get correct calculations.\njQuery.swap = function( elem, options, callback, args ) {\n\tvar ret, name,\n\t\told = {};\n\n\t// Remember the old values, and insert the new ones\n\tfor ( name in options ) {\n\t\told[ name ] = elem.style[ name ];\n\t\telem.style[ name ] = options[ name ];\n\t}\n\n\tret = callback.apply( elem, args || [] );\n\n\t// Revert the old values\n\tfor ( name in options ) {\n\t\telem.style[ name ] = old[ name ];\n\t}\n\n\treturn ret;\n};\n\n\nvar\n\t\tralpha = /alpha\\([^)]*\\)/i,\n\tropacity = /opacity\\s*=\\s*([^)]*)/,\n\n\t// swappable if display is none or starts with table except \"table\", \"table-cell\", or \"table-caption\"\n\t// see here for display values: https://developer.mozilla.org/en-US/docs/CSS/display\n\trdisplayswap = /^(none|table(?!-c[ea]).+)/,\n\trnumsplit = new RegExp( \"^(\" + pnum + \")(.*)$\", \"i\" ),\n\trrelNum = new RegExp( \"^([+-])=(\" + pnum + \")\", \"i\" ),\n\n\tcssShow = { position: \"absolute\", visibility: \"hidden\", display: \"block\" },\n\tcssNormalTransform = {\n\t\tletterSpacing: \"0\",\n\t\tfontWeight: \"400\"\n\t},\n\n\tcssPrefixes = [ \"Webkit\", \"O\", \"Moz\", \"ms\" ];\n\n\n// return a css property mapped to a potentially vendor prefixed property\nfunction vendorPropName( style, name ) {\n\n\t// shortcut for names that are not vendor prefixed\n\tif ( name in style ) {\n\t\treturn name;\n\t}\n\n\t// check for vendor prefixed names\n\tvar capName = name.charAt(0).toUpperCase() + name.slice(1),\n\t\torigName = name,\n\t\ti = cssPrefixes.length;\n\n\twhile ( i-- ) {\n\t\tname = cssPrefixes[ i ] + capName;\n\t\tif ( name in style ) {\n\t\t\treturn name;\n\t\t}\n\t}\n\n\treturn origName;\n}\n\nfunction showHide( elements, show ) {\n\tvar display, elem, hidden,\n\t\tvalues = [],\n\t\tindex = 0,\n\t\tlength = elements.length;\n\n\tfor ( ; index < length; index++ ) {\n\t\telem = elements[ index ];\n\t\tif ( !elem.style ) {\n\t\t\tcontinue;\n\t\t}\n\n\t\tvalues[ index ] = jQuery._data( elem, \"olddisplay\" );\n\t\tdisplay = elem.style.display;\n\t\tif ( show ) {\n\t\t\t// Reset the inline display of this element to learn if it is\n\t\t\t// being hidden by cascaded rules or not\n\t\t\tif ( !values[ index ] && display === \"none\" ) {\n\t\t\t\telem.style.display = \"\";\n\t\t\t}\n\n\t\t\t// Set elements which have been overridden with display: none\n\t\t\t// in a stylesheet to whatever the default browser style is\n\t\t\t// for such an element\n\t\t\tif ( elem.style.display === \"\" && isHidden( elem ) ) {\n\t\t\t\tvalues[ index ] = jQuery._data( elem, \"olddisplay\", defaultDisplay(elem.nodeName) );\n\t\t\t}\n\t\t} else {\n\t\t\thidden = isHidden( elem );\n\n\t\t\tif ( display && display !== \"none\" || !hidden ) {\n\t\t\t\tjQuery._data( elem, \"olddisplay\", hidden ? display : jQuery.css( elem, \"display\" ) );\n\t\t\t}\n\t\t}\n\t}\n\n\t// Set the display of most of the elements in a second loop\n\t// to avoid the constant reflow\n\tfor ( index = 0; index < length; index++ ) {\n\t\telem = elements[ index ];\n\t\tif ( !elem.style ) {\n\t\t\tcontinue;\n\t\t}\n\t\tif ( !show || elem.style.display === \"none\" || elem.style.display === \"\" ) {\n\t\t\telem.style.display = show ? values[ index ] || \"\" : \"none\";\n\t\t}\n\t}\n\n\treturn elements;\n}\n\nfunction setPositiveNumber( elem, value, subtract ) {\n\tvar matches = rnumsplit.exec( value );\n\treturn matches ?\n\t\t// Guard against undefined \"subtract\", e.g., when used as in cssHooks\n\t\tMath.max( 0, matches[ 1 ] - ( subtract || 0 ) ) + ( matches[ 2 ] || \"px\" ) :\n\t\tvalue;\n}\n\nfunction augmentWidthOrHeight( elem, name, extra, isBorderBox, styles ) {\n\tvar i = extra === ( isBorderBox ? \"border\" : \"content\" ) ?\n\t\t// If we already have the right measurement, avoid augmentation\n\t\t4 :\n\t\t// Otherwise initialize for horizontal or vertical properties\n\t\tname === \"width\" ? 1 : 0,\n\n\t\tval = 0;\n\n\tfor ( ; i < 4; i += 2 ) {\n\t\t// both box models exclude margin, so add it if we want it\n\t\tif ( extra === \"margin\" ) {\n\t\t\tval += jQuery.css( elem, extra + cssExpand[ i ], true, styles );\n\t\t}\n\n\t\tif ( isBorderBox ) {\n\t\t\t// border-box includes padding, so remove it if we want content\n\t\t\tif ( extra === \"content\" ) {\n\t\t\t\tval -= jQuery.css( elem, \"padding\" + cssExpand[ i ], true, styles );\n\t\t\t}\n\n\t\t\t// at this point, extra isn't border nor margin, so remove border\n\t\t\tif ( extra !== \"margin\" ) {\n\t\t\t\tval -= jQuery.css( elem, \"border\" + cssExpand[ i ] + \"Width\", true, styles );\n\t\t\t}\n\t\t} else {\n\t\t\t// at this point, extra isn't content, so add padding\n\t\t\tval += jQuery.css( elem, \"padding\" + cssExpand[ i ], true, styles );\n\n\t\t\t// at this point, extra isn't content nor padding, so add border\n\t\t\tif ( extra !== \"padding\" ) {\n\t\t\t\tval += jQuery.css( elem, \"border\" + cssExpand[ i ] + \"Width\", true, styles );\n\t\t\t}\n\t\t}\n\t}\n\n\treturn val;\n}\n\nfunction getWidthOrHeight( elem, name, extra ) {\n\n\t// Start with offset property, which is equivalent to the border-box value\n\tvar valueIsBorderBox = true,\n\t\tval = name === \"width\" ? elem.offsetWidth : elem.offsetHeight,\n\t\tstyles = getStyles( elem ),\n\t\tisBorderBox = support.boxSizing && jQuery.css( elem, \"boxSizing\", false, styles ) === \"border-box\";\n\n\t// some non-html elements return undefined for offsetWidth, so check for null/undefined\n\t// svg - https://bugzilla.mozilla.org/show_bug.cgi?id=649285\n\t// MathML - https://bugzilla.mozilla.org/show_bug.cgi?id=491668\n\tif ( val <= 0 || val == null ) {\n\t\t// Fall back to computed then uncomputed css if necessary\n\t\tval = curCSS( elem, name, styles );\n\t\tif ( val < 0 || val == null ) {\n\t\t\tval = elem.style[ name ];\n\t\t}\n\n\t\t// Computed unit is not pixels. Stop here and return.\n\t\tif ( rnumnonpx.test(val) ) {\n\t\t\treturn val;\n\t\t}\n\n\t\t// we need the check for style in case a browser which returns unreliable values\n\t\t// for getComputedStyle silently falls back to the reliable elem.style\n\t\tvalueIsBorderBox = isBorderBox && ( support.boxSizingReliable() || val === elem.style[ name ] );\n\n\t\t// Normalize \"\", auto, and prepare for extra\n\t\tval = parseFloat( val ) || 0;\n\t}\n\n\t// use the active box-sizing model to add/subtract irrelevant styles\n\treturn ( val +\n\t\taugmentWidthOrHeight(\n\t\t\telem,\n\t\t\tname,\n\t\t\textra || ( isBorderBox ? \"border\" : \"content\" ),\n\t\t\tvalueIsBorderBox,\n\t\t\tstyles\n\t\t)\n\t) + \"px\";\n}\n\njQuery.extend({\n\t// Add in style property hooks for overriding the default\n\t// behavior of getting and setting a style property\n\tcssHooks: {\n\t\topacity: {\n\t\t\tget: function( elem, computed ) {\n\t\t\t\tif ( computed ) {\n\t\t\t\t\t// We should always get a number back from opacity\n\t\t\t\t\tvar ret = curCSS( elem, \"opacity\" );\n\t\t\t\t\treturn ret === \"\" ? \"1\" : ret;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t},\n\n\t// Don't automatically add \"px\" to these possibly-unitless properties\n\tcssNumber: {\n\t\t\"columnCount\": true,\n\t\t\"fillOpacity\": true,\n\t\t\"flexGrow\": true,\n\t\t\"flexShrink\": true,\n\t\t\"fontWeight\": true,\n\t\t\"lineHeight\": true,\n\t\t\"opacity\": true,\n\t\t\"order\": true,\n\t\t\"orphans\": true,\n\t\t\"widows\": true,\n\t\t\"zIndex\": true,\n\t\t\"zoom\": true\n\t},\n\n\t// Add in properties whose names you wish to fix before\n\t// setting or getting the value\n\tcssProps: {\n\t\t// normalize float css property\n\t\t\"float\": support.cssFloat ? \"cssFloat\" : \"styleFloat\"\n\t},\n\n\t// Get and set the style property on a DOM Node\n\tstyle: function( elem, name, value, extra ) {\n\t\t// Don't set styles on text and comment nodes\n\t\tif ( !elem || elem.nodeType === 3 || elem.nodeType === 8 || !elem.style ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Make sure that we're working with the right name\n\t\tvar ret, type, hooks,\n\t\t\torigName = jQuery.camelCase( name ),\n\t\t\tstyle = elem.style;\n\n\t\tname = jQuery.cssProps[ origName ] || ( jQuery.cssProps[ origName ] = vendorPropName( style, origName ) );\n\n\t\t// gets hook for the prefixed version\n\t\t// followed by the unprefixed version\n\t\thooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ];\n\n\t\t// Check if we're setting a value\n\t\tif ( value !== undefined ) {\n\t\t\ttype = typeof value;\n\n\t\t\t// convert relative number strings (+= or -=) to relative numbers. #7345\n\t\t\tif ( type === \"string\" && (ret = rrelNum.exec( value )) ) {\n\t\t\t\tvalue = ( ret[1] + 1 ) * ret[2] + parseFloat( jQuery.css( elem, name ) );\n\t\t\t\t// Fixes bug #9237\n\t\t\t\ttype = \"number\";\n\t\t\t}\n\n\t\t\t// Make sure that null and NaN values aren't set. See: #7116\n\t\t\tif ( value == null || value !== value ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// If a number was passed in, add 'px' to the (except for certain CSS properties)\n\t\t\tif ( type === \"number\" && !jQuery.cssNumber[ origName ] ) {\n\t\t\t\tvalue += \"px\";\n\t\t\t}\n\n\t\t\t// Fixes #8908, it can be done more correctly by specifing setters in cssHooks,\n\t\t\t// but it would mean to define eight (for every problematic property) identical functions\n\t\t\tif ( !support.clearCloneStyle && value === \"\" && name.indexOf(\"background\") === 0 ) {\n\t\t\t\tstyle[ name ] = \"inherit\";\n\t\t\t}\n\n\t\t\t// If a hook was provided, use that value, otherwise just set the specified value\n\t\t\tif ( !hooks || !(\"set\" in hooks) || (value = hooks.set( elem, value, extra )) !== undefined ) {\n\n\t\t\t\t// Support: IE\n\t\t\t\t// Swallow errors from 'invalid' CSS values (#5509)\n\t\t\t\ttry {\n\t\t\t\t\tstyle[ name ] = value;\n\t\t\t\t} catch(e) {}\n\t\t\t}\n\n\t\t} else {\n\t\t\t// If a hook was provided get the non-computed value from there\n\t\t\tif ( hooks && \"get\" in hooks && (ret = hooks.get( elem, false, extra )) !== undefined ) {\n\t\t\t\treturn ret;\n\t\t\t}\n\n\t\t\t// Otherwise just get the value from the style object\n\t\t\treturn style[ name ];\n\t\t}\n\t},\n\n\tcss: function( elem, name, extra, styles ) {\n\t\tvar num, val, hooks,\n\t\t\torigName = jQuery.camelCase( name );\n\n\t\t// Make sure that we're working with the right name\n\t\tname = jQuery.cssProps[ origName ] || ( jQuery.cssProps[ origName ] = vendorPropName( elem.style, origName ) );\n\n\t\t// gets hook for the prefixed version\n\t\t// followed by the unprefixed version\n\t\thooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ];\n\n\t\t// If a hook was provided get the computed value from there\n\t\tif ( hooks && \"get\" in hooks ) {\n\t\t\tval = hooks.get( elem, true, extra );\n\t\t}\n\n\t\t// Otherwise, if a way to get the computed value exists, use that\n\t\tif ( val === undefined ) {\n\t\t\tval = curCSS( elem, name, styles );\n\t\t}\n\n\t\t//convert \"normal\" to computed value\n\t\tif ( val === \"normal\" && name in cssNormalTransform ) {\n\t\t\tval = cssNormalTransform[ name ];\n\t\t}\n\n\t\t// Return, converting to number if forced or a qualifier was provided and val looks numeric\n\t\tif ( extra === \"\" || extra ) {\n\t\t\tnum = parseFloat( val );\n\t\t\treturn extra === true || jQuery.isNumeric( num ) ? num || 0 : val;\n\t\t}\n\t\treturn val;\n\t}\n});\n\njQuery.each([ \"height\", \"width\" ], function( i, name ) {\n\tjQuery.cssHooks[ name ] = {\n\t\tget: function( elem, computed, extra ) {\n\t\t\tif ( computed ) {\n\t\t\t\t// certain elements can have dimension info if we invisibly show them\n\t\t\t\t// however, it must have a current display style that would benefit from this\n\t\t\t\treturn rdisplayswap.test( jQuery.css( elem, \"display\" ) ) && elem.offsetWidth === 0 ?\n\t\t\t\t\tjQuery.swap( elem, cssShow, function() {\n\t\t\t\t\t\treturn getWidthOrHeight( elem, name, extra );\n\t\t\t\t\t}) :\n\t\t\t\t\tgetWidthOrHeight( elem, name, extra );\n\t\t\t}\n\t\t},\n\n\t\tset: function( elem, value, extra ) {\n\t\t\tvar styles = extra && getStyles( elem );\n\t\t\treturn setPositiveNumber( elem, value, extra ?\n\t\t\t\taugmentWidthOrHeight(\n\t\t\t\t\telem,\n\t\t\t\t\tname,\n\t\t\t\t\textra,\n\t\t\t\t\tsupport.boxSizing && jQuery.css( elem, \"boxSizing\", false, styles ) === \"border-box\",\n\t\t\t\t\tstyles\n\t\t\t\t) : 0\n\t\t\t);\n\t\t}\n\t};\n});\n\nif ( !support.opacity ) {\n\tjQuery.cssHooks.opacity = {\n\t\tget: function( elem, computed ) {\n\t\t\t// IE uses filters for opacity\n\t\t\treturn ropacity.test( (computed && elem.currentStyle ? elem.currentStyle.filter : elem.style.filter) || \"\" ) ?\n\t\t\t\t( 0.01 * parseFloat( RegExp.$1 ) ) + \"\" :\n\t\t\t\tcomputed ? \"1\" : \"\";\n\t\t},\n\n\t\tset: function( elem, value ) {\n\t\t\tvar style = elem.style,\n\t\t\t\tcurrentStyle = elem.currentStyle,\n\t\t\t\topacity = jQuery.isNumeric( value ) ? \"alpha(opacity=\" + value * 100 + \")\" : \"\",\n\t\t\t\tfilter = currentStyle && currentStyle.filter || style.filter || \"\";\n\n\t\t\t// IE has trouble with opacity if it does not have layout\n\t\t\t// Force it by setting the zoom level\n\t\t\tstyle.zoom = 1;\n\n\t\t\t// if setting opacity to 1, and no other filters exist - attempt to remove filter attribute #6652\n\t\t\t// if value === \"\", then remove inline opacity #12685\n\t\t\tif ( ( value >= 1 || value === \"\" ) &&\n\t\t\t\t\tjQuery.trim( filter.replace( ralpha, \"\" ) ) === \"\" &&\n\t\t\t\t\tstyle.removeAttribute ) {\n\n\t\t\t\t// Setting style.filter to null, \"\" & \" \" still leave \"filter:\" in the cssText\n\t\t\t\t// if \"filter:\" is present at all, clearType is disabled, we want to avoid this\n\t\t\t\t// style.removeAttribute is IE Only, but so apparently is this code path...\n\t\t\t\tstyle.removeAttribute( \"filter\" );\n\n\t\t\t\t// if there is no filter style applied in a css rule or unset inline opacity, we are done\n\t\t\t\tif ( value === \"\" || currentStyle && !currentStyle.filter ) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// otherwise, set new filter values\n\t\t\tstyle.filter = ralpha.test( filter ) ?\n\t\t\t\tfilter.replace( ralpha, opacity ) :\n\t\t\t\tfilter + \" \" + opacity;\n\t\t}\n\t};\n}\n\njQuery.cssHooks.marginRight = addGetHookIf( support.reliableMarginRight,\n\tfunction( elem, computed ) {\n\t\tif ( computed ) {\n\t\t\t// WebKit Bug 13343 - getComputedStyle returns wrong value for margin-right\n\t\t\t// Work around by temporarily setting element display to inline-block\n\t\t\treturn jQuery.swap( elem, { \"display\": \"inline-block\" },\n\t\t\t\tcurCSS, [ elem, \"marginRight\" ] );\n\t\t}\n\t}\n);\n\n// These hooks are used by animate to expand properties\njQuery.each({\n\tmargin: \"\",\n\tpadding: \"\",\n\tborder: \"Width\"\n}, function( prefix, suffix ) {\n\tjQuery.cssHooks[ prefix + suffix ] = {\n\t\texpand: function( value ) {\n\t\t\tvar i = 0,\n\t\t\t\texpanded = {},\n\n\t\t\t\t// assumes a single number if not a string\n\t\t\t\tparts = typeof value === \"string\" ? value.split(\" \") : [ value ];\n\n\t\t\tfor ( ; i < 4; i++ ) {\n\t\t\t\texpanded[ prefix + cssExpand[ i ] + suffix ] =\n\t\t\t\t\tparts[ i ] || parts[ i - 2 ] || parts[ 0 ];\n\t\t\t}\n\n\t\t\treturn expanded;\n\t\t}\n\t};\n\n\tif ( !rmargin.test( prefix ) ) {\n\t\tjQuery.cssHooks[ prefix + suffix ].set = setPositiveNumber;\n\t}\n});\n\njQuery.fn.extend({\n\tcss: function( name, value ) {\n\t\treturn access( this, function( elem, name, value ) {\n\t\t\tvar styles, len,\n\t\t\t\tmap = {},\n\t\t\t\ti = 0;\n\n\t\t\tif ( jQuery.isArray( name ) ) {\n\t\t\t\tstyles = getStyles( elem );\n\t\t\t\tlen = name.length;\n\n\t\t\t\tfor ( ; i < len; i++ ) {\n\t\t\t\t\tmap[ name[ i ] ] = jQuery.css( elem, name[ i ], false, styles );\n\t\t\t\t}\n\n\t\t\t\treturn map;\n\t\t\t}\n\n\t\t\treturn value !== undefined ?\n\t\t\t\tjQuery.style( elem, name, value ) :\n\t\t\t\tjQuery.css( elem, name );\n\t\t}, name, value, arguments.length > 1 );\n\t},\n\tshow: function() {\n\t\treturn showHide( this, true );\n\t},\n\thide: function() {\n\t\treturn showHide( this );\n\t},\n\ttoggle: function( state ) {\n\t\tif ( typeof state === \"boolean\" ) {\n\t\t\treturn state ? this.show() : this.hide();\n\t\t}\n\n\t\treturn this.each(function() {\n\t\t\tif ( isHidden( this ) ) {\n\t\t\t\tjQuery( this ).show();\n\t\t\t} else {\n\t\t\t\tjQuery( this ).hide();\n\t\t\t}\n\t\t});\n\t}\n});\n\n\nfunction Tween( elem, options, prop, end, easing ) {\n\treturn new Tween.prototype.init( elem, options, prop, end, easing );\n}\njQuery.Tween = Tween;\n\nTween.prototype = {\n\tconstructor: Tween,\n\tinit: function( elem, options, prop, end, easing, unit ) {\n\t\tthis.elem = elem;\n\t\tthis.prop = prop;\n\t\tthis.easing = easing || \"swing\";\n\t\tthis.options = options;\n\t\tthis.start = this.now = this.cur();\n\t\tthis.end = end;\n\t\tthis.unit = unit || ( jQuery.cssNumber[ prop ] ? \"\" : \"px\" );\n\t},\n\tcur: function() {\n\t\tvar hooks = Tween.propHooks[ this.prop ];\n\n\t\treturn hooks && hooks.get ?\n\t\t\thooks.get( this ) :\n\t\t\tTween.propHooks._default.get( this );\n\t},\n\trun: function( percent ) {\n\t\tvar eased,\n\t\t\thooks = Tween.propHooks[ this.prop ];\n\n\t\tif ( this.options.duration ) {\n\t\t\tthis.pos = eased = jQuery.easing[ this.easing ](\n\t\t\t\tpercent, this.options.duration * percent, 0, 1, this.options.duration\n\t\t\t);\n\t\t} else {\n\t\t\tthis.pos = eased = percent;\n\t\t}\n\t\tthis.now = ( this.end - this.start ) * eased + this.start;\n\n\t\tif ( this.options.step ) {\n\t\t\tthis.options.step.call( this.elem, this.now, this );\n\t\t}\n\n\t\tif ( hooks && hooks.set ) {\n\t\t\thooks.set( this );\n\t\t} else {\n\t\t\tTween.propHooks._default.set( this );\n\t\t}\n\t\treturn this;\n\t}\n};\n\nTween.prototype.init.prototype = Tween.prototype;\n\nTween.propHooks = {\n\t_default: {\n\t\tget: function( tween ) {\n\t\t\tvar result;\n\n\t\t\tif ( tween.elem[ tween.prop ] != null &&\n\t\t\t\t(!tween.elem.style || tween.elem.style[ tween.prop ] == null) ) {\n\t\t\t\treturn tween.elem[ tween.prop ];\n\t\t\t}\n\n\t\t\t// passing an empty string as a 3rd parameter to .css will automatically\n\t\t\t// attempt a parseFloat and fallback to a string if the parse fails\n\t\t\t// so, simple values such as \"10px\" are parsed to Float.\n\t\t\t// complex values such as \"rotate(1rad)\" are returned as is.\n\t\t\tresult = jQuery.css( tween.elem, tween.prop, \"\" );\n\t\t\t// Empty strings, null, undefined and \"auto\" are converted to 0.\n\t\t\treturn !result || result === \"auto\" ? 0 : result;\n\t\t},\n\t\tset: function( tween ) {\n\t\t\t// use step hook for back compat - use cssHook if its there - use .style if its\n\t\t\t// available and use plain properties where available\n\t\t\tif ( jQuery.fx.step[ tween.prop ] ) {\n\t\t\t\tjQuery.fx.step[ tween.prop ]( tween );\n\t\t\t} else if ( tween.elem.style && ( tween.elem.style[ jQuery.cssProps[ tween.prop ] ] != null || jQuery.cssHooks[ tween.prop ] ) ) {\n\t\t\t\tjQuery.style( tween.elem, tween.prop, tween.now + tween.unit );\n\t\t\t} else {\n\t\t\t\ttween.elem[ tween.prop ] = tween.now;\n\t\t\t}\n\t\t}\n\t}\n};\n\n// Support: IE <=9\n// Panic based approach to setting things on disconnected nodes\n\nTween.propHooks.scrollTop = Tween.propHooks.scrollLeft = {\n\tset: function( tween ) {\n\t\tif ( tween.elem.nodeType && tween.elem.parentNode ) {\n\t\t\ttween.elem[ tween.prop ] = tween.now;\n\t\t}\n\t}\n};\n\njQuery.easing = {\n\tlinear: function( p ) {\n\t\treturn p;\n\t},\n\tswing: function( p ) {\n\t\treturn 0.5 - Math.cos( p * Math.PI ) / 2;\n\t}\n};\n\njQuery.fx = Tween.prototype.init;\n\n// Back Compat <1.8 extension point\njQuery.fx.step = {};\n\n\n\n\nvar\n\tfxNow, timerId,\n\trfxtypes = /^(?:toggle|show|hide)$/,\n\trfxnum = new RegExp( \"^(?:([+-])=|)(\" + pnum + \")([a-z%]*)$\", \"i\" ),\n\trrun = /queueHooks$/,\n\tanimationPrefilters = [ defaultPrefilter ],\n\ttweeners = {\n\t\t\"*\": [ function( prop, value ) {\n\t\t\tvar tween = this.createTween( prop, value ),\n\t\t\t\ttarget = tween.cur(),\n\t\t\t\tparts = rfxnum.exec( value ),\n\t\t\t\tunit = parts && parts[ 3 ] || ( jQuery.cssNumber[ prop ] ? \"\" : \"px\" ),\n\n\t\t\t\t// Starting value computation is required for potential unit mismatches\n\t\t\t\tstart = ( jQuery.cssNumber[ prop ] || unit !== \"px\" && +target ) &&\n\t\t\t\t\trfxnum.exec( jQuery.css( tween.elem, prop ) ),\n\t\t\t\tscale = 1,\n\t\t\t\tmaxIterations = 20;\n\n\t\t\tif ( start && start[ 3 ] !== unit ) {\n\t\t\t\t// Trust units reported by jQuery.css\n\t\t\t\tunit = unit || start[ 3 ];\n\n\t\t\t\t// Make sure we update the tween properties later on\n\t\t\t\tparts = parts || [];\n\n\t\t\t\t// Iteratively approximate from a nonzero starting point\n\t\t\t\tstart = +target || 1;\n\n\t\t\t\tdo {\n\t\t\t\t\t// If previous iteration zeroed out, double until we get *something*\n\t\t\t\t\t// Use a string for doubling factor so we don't accidentally see scale as unchanged below\n\t\t\t\t\tscale = scale || \".5\";\n\n\t\t\t\t\t// Adjust and apply\n\t\t\t\t\tstart = start / scale;\n\t\t\t\t\tjQuery.style( tween.elem, prop, start + unit );\n\n\t\t\t\t// Update scale, tolerating zero or NaN from tween.cur()\n\t\t\t\t// And breaking the loop if scale is unchanged or perfect, or if we've just had enough\n\t\t\t\t} while ( scale !== (scale = tween.cur() / target) && scale !== 1 && --maxIterations );\n\t\t\t}\n\n\t\t\t// Update tween properties\n\t\t\tif ( parts ) {\n\t\t\t\tstart = tween.start = +start || +target || 0;\n\t\t\t\ttween.unit = unit;\n\t\t\t\t// If a +=/-= token was provided, we're doing a relative animation\n\t\t\t\ttween.end = parts[ 1 ] ?\n\t\t\t\t\tstart + ( parts[ 1 ] + 1 ) * parts[ 2 ] :\n\t\t\t\t\t+parts[ 2 ];\n\t\t\t}\n\n\t\t\treturn tween;\n\t\t} ]\n\t};\n\n// Animations created synchronously will run synchronously\nfunction createFxNow() {\n\tsetTimeout(function() {\n\t\tfxNow = undefined;\n\t});\n\treturn ( fxNow = jQuery.now() );\n}\n\n// Generate parameters to create a standard animation\nfunction genFx( type, includeWidth ) {\n\tvar which,\n\t\tattrs = { height: type },\n\t\ti = 0;\n\n\t// if we include width, step value is 1 to do all cssExpand values,\n\t// if we don't include width, step value is 2 to skip over Left and Right\n\tincludeWidth = includeWidth ? 1 : 0;\n\tfor ( ; i < 4 ; i += 2 - includeWidth ) {\n\t\twhich = cssExpand[ i ];\n\t\tattrs[ \"margin\" + which ] = attrs[ \"padding\" + which ] = type;\n\t}\n\n\tif ( includeWidth ) {\n\t\tattrs.opacity = attrs.width = type;\n\t}\n\n\treturn attrs;\n}\n\nfunction createTween( value, prop, animation ) {\n\tvar tween,\n\t\tcollection = ( tweeners[ prop ] || [] ).concat( tweeners[ \"*\" ] ),\n\t\tindex = 0,\n\t\tlength = collection.length;\n\tfor ( ; index < length; index++ ) {\n\t\tif ( (tween = collection[ index ].call( animation, prop, value )) ) {\n\n\t\t\t// we're done with this property\n\t\t\treturn tween;\n\t\t}\n\t}\n}\n\nfunction defaultPrefilter( elem, props, opts ) {\n\t/* jshint validthis: true */\n\tvar prop, value, toggle, tween, hooks, oldfire, display, checkDisplay,\n\t\tanim = this,\n\t\torig = {},\n\t\tstyle = elem.style,\n\t\thidden = elem.nodeType && isHidden( elem ),\n\t\tdataShow = jQuery._data( elem, \"fxshow\" );\n\n\t// handle queue: false promises\n\tif ( !opts.queue ) {\n\t\thooks = jQuery._queueHooks( elem, \"fx\" );\n\t\tif ( hooks.unqueued == null ) {\n\t\t\thooks.unqueued = 0;\n\t\t\toldfire = hooks.empty.fire;\n\t\t\thooks.empty.fire = function() {\n\t\t\t\tif ( !hooks.unqueued ) {\n\t\t\t\t\toldfire();\n\t\t\t\t}\n\t\t\t};\n\t\t}\n\t\thooks.unqueued++;\n\n\t\tanim.always(function() {\n\t\t\t// doing this makes sure that the complete handler will be called\n\t\t\t// before this completes\n\t\t\tanim.always(function() {\n\t\t\t\thooks.unqueued--;\n\t\t\t\tif ( !jQuery.queue( elem, \"fx\" ).length ) {\n\t\t\t\t\thooks.empty.fire();\n\t\t\t\t}\n\t\t\t});\n\t\t});\n\t}\n\n\t// height/width overflow pass\n\tif ( elem.nodeType === 1 && ( \"height\" in props || \"width\" in props ) ) {\n\t\t// Make sure that nothing sneaks out\n\t\t// Record all 3 overflow attributes because IE does not\n\t\t// change the overflow attribute when overflowX and\n\t\t// overflowY are set to the same value\n\t\topts.overflow = [ style.overflow, style.overflowX, style.overflowY ];\n\n\t\t// Set display property to inline-block for height/width\n\t\t// animations on inline elements that are having width/height animated\n\t\tdisplay = jQuery.css( elem, \"display\" );\n\n\t\t// Test default display if display is currently \"none\"\n\t\tcheckDisplay = display === \"none\" ?\n\t\t\tjQuery._data( elem, \"olddisplay\" ) || defaultDisplay( elem.nodeName ) : display;\n\n\t\tif ( checkDisplay === \"inline\" && jQuery.css( elem, \"float\" ) === \"none\" ) {\n\n\t\t\t// inline-level elements accept inline-block;\n\t\t\t// block-level elements need to be inline with layout\n\t\t\tif ( !support.inlineBlockNeedsLayout || defaultDisplay( elem.nodeName ) === \"inline\" ) {\n\t\t\t\tstyle.display = \"inline-block\";\n\t\t\t} else {\n\t\t\t\tstyle.zoom = 1;\n\t\t\t}\n\t\t}\n\t}\n\n\tif ( opts.overflow ) {\n\t\tstyle.overflow = \"hidden\";\n\t\tif ( !support.shrinkWrapBlocks() ) {\n\t\t\tanim.always(function() {\n\t\t\t\tstyle.overflow = opts.overflow[ 0 ];\n\t\t\t\tstyle.overflowX = opts.overflow[ 1 ];\n\t\t\t\tstyle.overflowY = opts.overflow[ 2 ];\n\t\t\t});\n\t\t}\n\t}\n\n\t// show/hide pass\n\tfor ( prop in props ) {\n\t\tvalue = props[ prop ];\n\t\tif ( rfxtypes.exec( value ) ) {\n\t\t\tdelete props[ prop ];\n\t\t\ttoggle = toggle || value === \"toggle\";\n\t\t\tif ( value === ( hidden ? \"hide\" : \"show\" ) ) {\n\n\t\t\t\t// If there is dataShow left over from a stopped hide or show and we are going to proceed with show, we should pretend to be hidden\n\t\t\t\tif ( value === \"show\" && dataShow && dataShow[ prop ] !== undefined ) {\n\t\t\t\t\thidden = true;\n\t\t\t\t} else {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t}\n\t\t\torig[ prop ] = dataShow && dataShow[ prop ] || jQuery.style( elem, prop );\n\n\t\t// Any non-fx value stops us from restoring the original display value\n\t\t} else {\n\t\t\tdisplay = undefined;\n\t\t}\n\t}\n\n\tif ( !jQuery.isEmptyObject( orig ) ) {\n\t\tif ( dataShow ) {\n\t\t\tif ( \"hidden\" in dataShow ) {\n\t\t\t\thidden = dataShow.hidden;\n\t\t\t}\n\t\t} else {\n\t\t\tdataShow = jQuery._data( elem, \"fxshow\", {} );\n\t\t}\n\n\t\t// store state if its toggle - enables .stop().toggle() to \"reverse\"\n\t\tif ( toggle ) {\n\t\t\tdataShow.hidden = !hidden;\n\t\t}\n\t\tif ( hidden ) {\n\t\t\tjQuery( elem ).show();\n\t\t} else {\n\t\t\tanim.done(function() {\n\t\t\t\tjQuery( elem ).hide();\n\t\t\t});\n\t\t}\n\t\tanim.done(function() {\n\t\t\tvar prop;\n\t\t\tjQuery._removeData( elem, \"fxshow\" );\n\t\t\tfor ( prop in orig ) {\n\t\t\t\tjQuery.style( elem, prop, orig[ prop ] );\n\t\t\t}\n\t\t});\n\t\tfor ( prop in orig ) {\n\t\t\ttween = createTween( hidden ? dataShow[ prop ] : 0, prop, anim );\n\n\t\t\tif ( !( prop in dataShow ) ) {\n\t\t\t\tdataShow[ prop ] = tween.start;\n\t\t\t\tif ( hidden ) {\n\t\t\t\t\ttween.end = tween.start;\n\t\t\t\t\ttween.start = prop === \"width\" || prop === \"height\" ? 1 : 0;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t// If this is a noop like .hide().hide(), restore an overwritten display value\n\t} else if ( (display === \"none\" ? defaultDisplay( elem.nodeName ) : display) === \"inline\" ) {\n\t\tstyle.display = display;\n\t}\n}\n\nfunction propFilter( props, specialEasing ) {\n\tvar index, name, easing, value, hooks;\n\n\t// camelCase, specialEasing and expand cssHook pass\n\tfor ( index in props ) {\n\t\tname = jQuery.camelCase( index );\n\t\teasing = specialEasing[ name ];\n\t\tvalue = props[ index ];\n\t\tif ( jQuery.isArray( value ) ) {\n\t\t\teasing = value[ 1 ];\n\t\t\tvalue = props[ index ] = value[ 0 ];\n\t\t}\n\n\t\tif ( index !== name ) {\n\t\t\tprops[ name ] = value;\n\t\t\tdelete props[ index ];\n\t\t}\n\n\t\thooks = jQuery.cssHooks[ name ];\n\t\tif ( hooks && \"expand\" in hooks ) {\n\t\t\tvalue = hooks.expand( value );\n\t\t\tdelete props[ name ];\n\n\t\t\t// not quite $.extend, this wont overwrite keys already present.\n\t\t\t// also - reusing 'index' from above because we have the correct \"name\"\n\t\t\tfor ( index in value ) {\n\t\t\t\tif ( !( index in props ) ) {\n\t\t\t\t\tprops[ index ] = value[ index ];\n\t\t\t\t\tspecialEasing[ index ] = easing;\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\tspecialEasing[ name ] = easing;\n\t\t}\n\t}\n}\n\nfunction Animation( elem, properties, options ) {\n\tvar result,\n\t\tstopped,\n\t\tindex = 0,\n\t\tlength = animationPrefilters.length,\n\t\tdeferred = jQuery.Deferred().always( function() {\n\t\t\t// don't match elem in the :animated selector\n\t\t\tdelete tick.elem;\n\t\t}),\n\t\ttick = function() {\n\t\t\tif ( stopped ) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\tvar currentTime = fxNow || createFxNow(),\n\t\t\t\tremaining = Math.max( 0, animation.startTime + animation.duration - currentTime ),\n\t\t\t\t// archaic crash bug won't allow us to use 1 - ( 0.5 || 0 ) (#12497)\n\t\t\t\ttemp = remaining / animation.duration || 0,\n\t\t\t\tpercent = 1 - temp,\n\t\t\t\tindex = 0,\n\t\t\t\tlength = animation.tweens.length;\n\n\t\t\tfor ( ; index < length ; index++ ) {\n\t\t\t\tanimation.tweens[ index ].run( percent );\n\t\t\t}\n\n\t\t\tdeferred.notifyWith( elem, [ animation, percent, remaining ]);\n\n\t\t\tif ( percent < 1 && length ) {\n\t\t\t\treturn remaining;\n\t\t\t} else {\n\t\t\t\tdeferred.resolveWith( elem, [ animation ] );\n\t\t\t\treturn false;\n\t\t\t}\n\t\t},\n\t\tanimation = deferred.promise({\n\t\t\telem: elem,\n\t\t\tprops: jQuery.extend( {}, properties ),\n\t\t\topts: jQuery.extend( true, { specialEasing: {} }, options ),\n\t\t\toriginalProperties: properties,\n\t\t\toriginalOptions: options,\n\t\t\tstartTime: fxNow || createFxNow(),\n\t\t\tduration: options.duration,\n\t\t\ttweens: [],\n\t\t\tcreateTween: function( prop, end ) {\n\t\t\t\tvar tween = jQuery.Tween( elem, animation.opts, prop, end,\n\t\t\t\t\t\tanimation.opts.specialEasing[ prop ] || animation.opts.easing );\n\t\t\t\tanimation.tweens.push( tween );\n\t\t\t\treturn tween;\n\t\t\t},\n\t\t\tstop: function( gotoEnd ) {\n\t\t\t\tvar index = 0,\n\t\t\t\t\t// if we are going to the end, we want to run all the tweens\n\t\t\t\t\t// otherwise we skip this part\n\t\t\t\t\tlength = gotoEnd ? animation.tweens.length : 0;\n\t\t\t\tif ( stopped ) {\n\t\t\t\t\treturn this;\n\t\t\t\t}\n\t\t\t\tstopped = true;\n\t\t\t\tfor ( ; index < length ; index++ ) {\n\t\t\t\t\tanimation.tweens[ index ].run( 1 );\n\t\t\t\t}\n\n\t\t\t\t// resolve when we played the last frame\n\t\t\t\t// otherwise, reject\n\t\t\t\tif ( gotoEnd ) {\n\t\t\t\t\tdeferred.resolveWith( elem, [ animation, gotoEnd ] );\n\t\t\t\t} else {\n\t\t\t\t\tdeferred.rejectWith( elem, [ animation, gotoEnd ] );\n\t\t\t\t}\n\t\t\t\treturn this;\n\t\t\t}\n\t\t}),\n\t\tprops = animation.props;\n\n\tpropFilter( props, animation.opts.specialEasing );\n\n\tfor ( ; index < length ; index++ ) {\n\t\tresult = animationPrefilters[ index ].call( animation, elem, props, animation.opts );\n\t\tif ( result ) {\n\t\t\treturn result;\n\t\t}\n\t}\n\n\tjQuery.map( props, createTween, animation );\n\n\tif ( jQuery.isFunction( animation.opts.start ) ) {\n\t\tanimation.opts.start.call( elem, animation );\n\t}\n\n\tjQuery.fx.timer(\n\t\tjQuery.extend( tick, {\n\t\t\telem: elem,\n\t\t\tanim: animation,\n\t\t\tqueue: animation.opts.queue\n\t\t})\n\t);\n\n\t// attach callbacks from options\n\treturn animation.progress( animation.opts.progress )\n\t\t.done( animation.opts.done, animation.opts.complete )\n\t\t.fail( animation.opts.fail )\n\t\t.always( animation.opts.always );\n}\n\njQuery.Animation = jQuery.extend( Animation, {\n\ttweener: function( props, callback ) {\n\t\tif ( jQuery.isFunction( props ) ) {\n\t\t\tcallback = props;\n\t\t\tprops = [ \"*\" ];\n\t\t} else {\n\t\t\tprops = props.split(\" \");\n\t\t}\n\n\t\tvar prop,\n\t\t\tindex = 0,\n\t\t\tlength = props.length;\n\n\t\tfor ( ; index < length ; index++ ) {\n\t\t\tprop = props[ index ];\n\t\t\ttweeners[ prop ] = tweeners[ prop ] || [];\n\t\t\ttweeners[ prop ].unshift( callback );\n\t\t}\n\t},\n\n\tprefilter: function( callback, prepend ) {\n\t\tif ( prepend ) {\n\t\t\tanimationPrefilters.unshift( callback );\n\t\t} else {\n\t\t\tanimationPrefilters.push( callback );\n\t\t}\n\t}\n});\n\njQuery.speed = function( speed, easing, fn ) {\n\tvar opt = speed && typeof speed === \"object\" ? jQuery.extend( {}, speed ) : {\n\t\tcomplete: fn || !fn && easing ||\n\t\t\tjQuery.isFunction( speed ) && speed,\n\t\tduration: speed,\n\t\teasing: fn && easing || easing && !jQuery.isFunction( easing ) && easing\n\t};\n\n\topt.duration = jQuery.fx.off ? 0 : typeof opt.duration === \"number\" ? opt.duration :\n\t\topt.duration in jQuery.fx.speeds ? jQuery.fx.speeds[ opt.duration ] : jQuery.fx.speeds._default;\n\n\t// normalize opt.queue - true/undefined/null -> \"fx\"\n\tif ( opt.queue == null || opt.queue === true ) {\n\t\topt.queue = \"fx\";\n\t}\n\n\t// Queueing\n\topt.old = opt.complete;\n\n\topt.complete = function() {\n\t\tif ( jQuery.isFunction( opt.old ) ) {\n\t\t\topt.old.call( this );\n\t\t}\n\n\t\tif ( opt.queue ) {\n\t\t\tjQuery.dequeue( this, opt.queue );\n\t\t}\n\t};\n\n\treturn opt;\n};\n\njQuery.fn.extend({\n\tfadeTo: function( speed, to, easing, callback ) {\n\n\t\t// show any hidden elements after setting opacity to 0\n\t\treturn this.filter( isHidden ).css( \"opacity\", 0 ).show()\n\n\t\t\t// animate to the value specified\n\t\t\t.end().animate({ opacity: to }, speed, easing, callback );\n\t},\n\tanimate: function( prop, speed, easing, callback ) {\n\t\tvar empty = jQuery.isEmptyObject( prop ),\n\t\t\toptall = jQuery.speed( speed, easing, callback ),\n\t\t\tdoAnimation = function() {\n\t\t\t\t// Operate on a copy of prop so per-property easing won't be lost\n\t\t\t\tvar anim = Animation( this, jQuery.extend( {}, prop ), optall );\n\n\t\t\t\t// Empty animations, or finishing resolves immediately\n\t\t\t\tif ( empty || jQuery._data( this, \"finish\" ) ) {\n\t\t\t\t\tanim.stop( true );\n\t\t\t\t}\n\t\t\t};\n\t\t\tdoAnimation.finish = doAnimation;\n\n\t\treturn empty || optall.queue === false ?\n\t\t\tthis.each( doAnimation ) :\n\t\t\tthis.queue( optall.queue, doAnimation );\n\t},\n\tstop: function( type, clearQueue, gotoEnd ) {\n\t\tvar stopQueue = function( hooks ) {\n\t\t\tvar stop = hooks.stop;\n\t\t\tdelete hooks.stop;\n\t\t\tstop( gotoEnd );\n\t\t};\n\n\t\tif ( typeof type !== \"string\" ) {\n\t\t\tgotoEnd = clearQueue;\n\t\t\tclearQueue = type;\n\t\t\ttype = undefined;\n\t\t}\n\t\tif ( clearQueue && type !== false ) {\n\t\t\tthis.queue( type || \"fx\", [] );\n\t\t}\n\n\t\treturn this.each(function() {\n\t\t\tvar dequeue = true,\n\t\t\t\tindex = type != null && type + \"queueHooks\",\n\t\t\t\ttimers = jQuery.timers,\n\t\t\t\tdata = jQuery._data( this );\n\n\t\t\tif ( index ) {\n\t\t\t\tif ( data[ index ] && data[ index ].stop ) {\n\t\t\t\t\tstopQueue( data[ index ] );\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tfor ( index in data ) {\n\t\t\t\t\tif ( data[ index ] && data[ index ].stop && rrun.test( index ) ) {\n\t\t\t\t\t\tstopQueue( data[ index ] );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tfor ( index = timers.length; index--; ) {\n\t\t\t\tif ( timers[ index ].elem === this && (type == null || timers[ index ].queue === type) ) {\n\t\t\t\t\ttimers[ index ].anim.stop( gotoEnd );\n\t\t\t\t\tdequeue = false;\n\t\t\t\t\ttimers.splice( index, 1 );\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// start the next in the queue if the last step wasn't forced\n\t\t\t// timers currently will call their complete callbacks, which will dequeue\n\t\t\t// but only if they were gotoEnd\n\t\t\tif ( dequeue || !gotoEnd ) {\n\t\t\t\tjQuery.dequeue( this, type );\n\t\t\t}\n\t\t});\n\t},\n\tfinish: function( type ) {\n\t\tif ( type !== false ) {\n\t\t\ttype = type || \"fx\";\n\t\t}\n\t\treturn this.each(function() {\n\t\t\tvar index,\n\t\t\t\tdata = jQuery._data( this ),\n\t\t\t\tqueue = data[ type + \"queue\" ],\n\t\t\t\thooks = data[ type + \"queueHooks\" ],\n\t\t\t\ttimers = jQuery.timers,\n\t\t\t\tlength = queue ? queue.length : 0;\n\n\t\t\t// enable finishing flag on private data\n\t\t\tdata.finish = true;\n\n\t\t\t// empty the queue first\n\t\t\tjQuery.queue( this, type, [] );\n\n\t\t\tif ( hooks && hooks.stop ) {\n\t\t\t\thooks.stop.call( this, true );\n\t\t\t}\n\n\t\t\t// look for any active animations, and finish them\n\t\t\tfor ( index = timers.length; index--; ) {\n\t\t\t\tif ( timers[ index ].elem === this && timers[ index ].queue === type ) {\n\t\t\t\t\ttimers[ index ].anim.stop( true );\n\t\t\t\t\ttimers.splice( index, 1 );\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// look for any animations in the old queue and finish them\n\t\t\tfor ( index = 0; index < length; index++ ) {\n\t\t\t\tif ( queue[ index ] && queue[ index ].finish ) {\n\t\t\t\t\tqueue[ index ].finish.call( this );\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// turn off finishing flag\n\t\t\tdelete data.finish;\n\t\t});\n\t}\n});\n\njQuery.each([ \"toggle\", \"show\", \"hide\" ], function( i, name ) {\n\tvar cssFn = jQuery.fn[ name ];\n\tjQuery.fn[ name ] = function( speed, easing, callback ) {\n\t\treturn speed == null || typeof speed === \"boolean\" ?\n\t\t\tcssFn.apply( this, arguments ) :\n\t\t\tthis.animate( genFx( name, true ), speed, easing, callback );\n\t};\n});\n\n// Generate shortcuts for custom animations\njQuery.each({\n\tslideDown: genFx(\"show\"),\n\tslideUp: genFx(\"hide\"),\n\tslideToggle: genFx(\"toggle\"),\n\tfadeIn: { opacity: \"show\" },\n\tfadeOut: { opacity: \"hide\" },\n\tfadeToggle: { opacity: \"toggle\" }\n}, function( name, props ) {\n\tjQuery.fn[ name ] = function( speed, easing, callback ) {\n\t\treturn this.animate( props, speed, easing, callback );\n\t};\n});\n\njQuery.timers = [];\njQuery.fx.tick = function() {\n\tvar timer,\n\t\ttimers = jQuery.timers,\n\t\ti = 0;\n\n\tfxNow = jQuery.now();\n\n\tfor ( ; i < timers.length; i++ ) {\n\t\ttimer = timers[ i ];\n\t\t// Checks the timer has not already been removed\n\t\tif ( !timer() && timers[ i ] === timer ) {\n\t\t\ttimers.splice( i--, 1 );\n\t\t}\n\t}\n\n\tif ( !timers.length ) {\n\t\tjQuery.fx.stop();\n\t}\n\tfxNow = undefined;\n};\n\njQuery.fx.timer = function( timer ) {\n\tjQuery.timers.push( timer );\n\tif ( timer() ) {\n\t\tjQuery.fx.start();\n\t} else {\n\t\tjQuery.timers.pop();\n\t}\n};\n\njQuery.fx.interval = 13;\n\njQuery.fx.start = function() {\n\tif ( !timerId ) {\n\t\ttimerId = setInterval( jQuery.fx.tick, jQuery.fx.interval );\n\t}\n};\n\njQuery.fx.stop = function() {\n\tclearInterval( timerId );\n\ttimerId = null;\n};\n\njQuery.fx.speeds = {\n\tslow: 600,\n\tfast: 200,\n\t// Default speed\n\t_default: 400\n};\n\n\n// Based off of the plugin by Clint Helfers, with permission.\n// http://blindsignals.com/index.php/2009/07/jquery-delay/\njQuery.fn.delay = function( time, type ) {\n\ttime = jQuery.fx ? jQuery.fx.speeds[ time ] || time : time;\n\ttype = type || \"fx\";\n\n\treturn this.queue( type, function( next, hooks ) {\n\t\tvar timeout = setTimeout( next, time );\n\t\thooks.stop = function() {\n\t\t\tclearTimeout( timeout );\n\t\t};\n\t});\n};\n\n\n(function() {\n\t// Minified: var a,b,c,d,e\n\tvar input, div, select, a, opt;\n\n\t// Setup\n\tdiv = document.createElement( \"div\" );\n\tdiv.setAttribute( \"className\", \"t\" );\n\tdiv.innerHTML = \"  <link/><table></table><a href='/a'>a</a><input type='checkbox'/>\";\n\ta = div.getElementsByTagName(\"a\")[ 0 ];\n\n\t// First batch of tests.\n\tselect = document.createElement(\"select\");\n\topt = select.appendChild( document.createElement(\"option\") );\n\tinput = div.getElementsByTagName(\"input\")[ 0 ];\n\n\ta.style.cssText = \"top:1px\";\n\n\t// Test setAttribute on camelCase class. If it works, we need attrFixes when doing get/setAttribute (ie6/7)\n\tsupport.getSetAttribute = div.className !== \"t\";\n\n\t// Get the style information from getAttribute\n\t// (IE uses .cssText instead)\n\tsupport.style = /top/.test( a.getAttribute(\"style\") );\n\n\t// Make sure that URLs aren't manipulated\n\t// (IE normalizes it by default)\n\tsupport.hrefNormalized = a.getAttribute(\"href\") === \"/a\";\n\n\t// Check the default checkbox/radio value (\"\" on WebKit; \"on\" elsewhere)\n\tsupport.checkOn = !!input.value;\n\n\t// Make sure that a selected-by-default option has a working selected property.\n\t// (WebKit defaults to false instead of true, IE too, if it's in an optgroup)\n\tsupport.optSelected = opt.selected;\n\n\t// Tests for enctype support on a form (#6743)\n\tsupport.enctype = !!document.createElement(\"form\").enctype;\n\n\t// Make sure that the options inside disabled selects aren't marked as disabled\n\t// (WebKit marks them as disabled)\n\tselect.disabled = true;\n\tsupport.optDisabled = !opt.disabled;\n\n\t// Support: IE8 only\n\t// Check if we can trust getAttribute(\"value\")\n\tinput = document.createElement( \"input\" );\n\tinput.setAttribute( \"value\", \"\" );\n\tsupport.input = input.getAttribute( \"value\" ) === \"\";\n\n\t// Check if an input maintains its value after becoming a radio\n\tinput.value = \"t\";\n\tinput.setAttribute( \"type\", \"radio\" );\n\tsupport.radioValue = input.value === \"t\";\n})();\n\n\nvar rreturn = /\\r/g;\n\njQuery.fn.extend({\n\tval: function( value ) {\n\t\tvar hooks, ret, isFunction,\n\t\t\telem = this[0];\n\n\t\tif ( !arguments.length ) {\n\t\t\tif ( elem ) {\n\t\t\t\thooks = jQuery.valHooks[ elem.type ] || jQuery.valHooks[ elem.nodeName.toLowerCase() ];\n\n\t\t\t\tif ( hooks && \"get\" in hooks && (ret = hooks.get( elem, \"value\" )) !== undefined ) {\n\t\t\t\t\treturn ret;\n\t\t\t\t}\n\n\t\t\t\tret = elem.value;\n\n\t\t\t\treturn typeof ret === \"string\" ?\n\t\t\t\t\t// handle most common string cases\n\t\t\t\t\tret.replace(rreturn, \"\") :\n\t\t\t\t\t// handle cases where value is null/undef or number\n\t\t\t\t\tret == null ? \"\" : ret;\n\t\t\t}\n\n\t\t\treturn;\n\t\t}\n\n\t\tisFunction = jQuery.isFunction( value );\n\n\t\treturn this.each(function( i ) {\n\t\t\tvar val;\n\n\t\t\tif ( this.nodeType !== 1 ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif ( isFunction ) {\n\t\t\t\tval = value.call( this, i, jQuery( this ).val() );\n\t\t\t} else {\n\t\t\t\tval = value;\n\t\t\t}\n\n\t\t\t// Treat null/undefined as \"\"; convert numbers to string\n\t\t\tif ( val == null ) {\n\t\t\t\tval = \"\";\n\t\t\t} else if ( typeof val === \"number\" ) {\n\t\t\t\tval += \"\";\n\t\t\t} else if ( jQuery.isArray( val ) ) {\n\t\t\t\tval = jQuery.map( val, function( value ) {\n\t\t\t\t\treturn value == null ? \"\" : value + \"\";\n\t\t\t\t});\n\t\t\t}\n\n\t\t\thooks = jQuery.valHooks[ this.type ] || jQuery.valHooks[ this.nodeName.toLowerCase() ];\n\n\t\t\t// If set returns undefined, fall back to normal setting\n\t\t\tif ( !hooks || !(\"set\" in hooks) || hooks.set( this, val, \"value\" ) === undefined ) {\n\t\t\t\tthis.value = val;\n\t\t\t}\n\t\t});\n\t}\n});\n\njQuery.extend({\n\tvalHooks: {\n\t\toption: {\n\t\t\tget: function( elem ) {\n\t\t\t\tvar val = jQuery.find.attr( elem, \"value\" );\n\t\t\t\treturn val != null ?\n\t\t\t\t\tval :\n\t\t\t\t\t// Support: IE10-11+\n\t\t\t\t\t// option.text throws exceptions (#14686, #14858)\n\t\t\t\t\tjQuery.trim( jQuery.text( elem ) );\n\t\t\t}\n\t\t},\n\t\tselect: {\n\t\t\tget: function( elem ) {\n\t\t\t\tvar value, option,\n\t\t\t\t\toptions = elem.options,\n\t\t\t\t\tindex = elem.selectedIndex,\n\t\t\t\t\tone = elem.type === \"select-one\" || index < 0,\n\t\t\t\t\tvalues = one ? null : [],\n\t\t\t\t\tmax = one ? index + 1 : options.length,\n\t\t\t\t\ti = index < 0 ?\n\t\t\t\t\t\tmax :\n\t\t\t\t\t\tone ? index : 0;\n\n\t\t\t\t// Loop through all the selected options\n\t\t\t\tfor ( ; i < max; i++ ) {\n\t\t\t\t\toption = options[ i ];\n\n\t\t\t\t\t// oldIE doesn't update selected after form reset (#2551)\n\t\t\t\t\tif ( ( option.selected || i === index ) &&\n\t\t\t\t\t\t\t// Don't return options that are disabled or in a disabled optgroup\n\t\t\t\t\t\t\t( support.optDisabled ? !option.disabled : option.getAttribute(\"disabled\") === null ) &&\n\t\t\t\t\t\t\t( !option.parentNode.disabled || !jQuery.nodeName( option.parentNode, \"optgroup\" ) ) ) {\n\n\t\t\t\t\t\t// Get the specific value for the option\n\t\t\t\t\t\tvalue = jQuery( option ).val();\n\n\t\t\t\t\t\t// We don't need an array for one selects\n\t\t\t\t\t\tif ( one ) {\n\t\t\t\t\t\t\treturn value;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// Multi-Selects return an array\n\t\t\t\t\t\tvalues.push( value );\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\treturn values;\n\t\t\t},\n\n\t\t\tset: function( elem, value ) {\n\t\t\t\tvar optionSet, option,\n\t\t\t\t\toptions = elem.options,\n\t\t\t\t\tvalues = jQuery.makeArray( value ),\n\t\t\t\t\ti = options.length;\n\n\t\t\t\twhile ( i-- ) {\n\t\t\t\t\toption = options[ i ];\n\n\t\t\t\t\tif ( jQuery.inArray( jQuery.valHooks.option.get( option ), values ) >= 0 ) {\n\n\t\t\t\t\t\t// Support: IE6\n\t\t\t\t\t\t// When new option element is added to select box we need to\n\t\t\t\t\t\t// force reflow of newly added node in order to workaround delay\n\t\t\t\t\t\t// of initialization properties\n\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\toption.selected = optionSet = true;\n\n\t\t\t\t\t\t} catch ( _ ) {\n\n\t\t\t\t\t\t\t// Will be executed only in IE6\n\t\t\t\t\t\t\toption.scrollHeight;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t} else {\n\t\t\t\t\t\toption.selected = false;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// Force browsers to behave consistently when non-matching value is set\n\t\t\t\tif ( !optionSet ) {\n\t\t\t\t\telem.selectedIndex = -1;\n\t\t\t\t}\n\n\t\t\t\treturn options;\n\t\t\t}\n\t\t}\n\t}\n});\n\n// Radios and checkboxes getter/setter\njQuery.each([ \"radio\", \"checkbox\" ], function() {\n\tjQuery.valHooks[ this ] = {\n\t\tset: function( elem, value ) {\n\t\t\tif ( jQuery.isArray( value ) ) {\n\t\t\t\treturn ( elem.checked = jQuery.inArray( jQuery(elem).val(), value ) >= 0 );\n\t\t\t}\n\t\t}\n\t};\n\tif ( !support.checkOn ) {\n\t\tjQuery.valHooks[ this ].get = function( elem ) {\n\t\t\t// Support: Webkit\n\t\t\t// \"\" is returned instead of \"on\" if a value isn't specified\n\t\t\treturn elem.getAttribute(\"value\") === null ? \"on\" : elem.value;\n\t\t};\n\t}\n});\n\n\n\n\nvar nodeHook, boolHook,\n\tattrHandle = jQuery.expr.attrHandle,\n\truseDefault = /^(?:checked|selected)$/i,\n\tgetSetAttribute = support.getSetAttribute,\n\tgetSetInput = support.input;\n\njQuery.fn.extend({\n\tattr: function( name, value ) {\n\t\treturn access( this, jQuery.attr, name, value, arguments.length > 1 );\n\t},\n\n\tremoveAttr: function( name ) {\n\t\treturn this.each(function() {\n\t\t\tjQuery.removeAttr( this, name );\n\t\t});\n\t}\n});\n\njQuery.extend({\n\tattr: function( elem, name, value ) {\n\t\tvar hooks, ret,\n\t\t\tnType = elem.nodeType;\n\n\t\t// don't get/set attributes on text, comment and attribute nodes\n\t\tif ( !elem || nType === 3 || nType === 8 || nType === 2 ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Fallback to prop when attributes are not supported\n\t\tif ( typeof elem.getAttribute === strundefined ) {\n\t\t\treturn jQuery.prop( elem, name, value );\n\t\t}\n\n\t\t// All attributes are lowercase\n\t\t// Grab necessary hook if one is defined\n\t\tif ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) {\n\t\t\tname = name.toLowerCase();\n\t\t\thooks = jQuery.attrHooks[ name ] ||\n\t\t\t\t( jQuery.expr.match.bool.test( name ) ? boolHook : nodeHook );\n\t\t}\n\n\t\tif ( value !== undefined ) {\n\n\t\t\tif ( value === null ) {\n\t\t\t\tjQuery.removeAttr( elem, name );\n\n\t\t\t} else if ( hooks && \"set\" in hooks && (ret = hooks.set( elem, value, name )) !== undefined ) {\n\t\t\t\treturn ret;\n\n\t\t\t} else {\n\t\t\t\telem.setAttribute( name, value + \"\" );\n\t\t\t\treturn value;\n\t\t\t}\n\n\t\t} else if ( hooks && \"get\" in hooks && (ret = hooks.get( elem, name )) !== null ) {\n\t\t\treturn ret;\n\n\t\t} else {\n\t\t\tret = jQuery.find.attr( elem, name );\n\n\t\t\t// Non-existent attributes return null, we normalize to undefined\n\t\t\treturn ret == null ?\n\t\t\t\tundefined :\n\t\t\t\tret;\n\t\t}\n\t},\n\n\tremoveAttr: function( elem, value ) {\n\t\tvar name, propName,\n\t\t\ti = 0,\n\t\t\tattrNames = value && value.match( rnotwhite );\n\n\t\tif ( attrNames && elem.nodeType === 1 ) {\n\t\t\twhile ( (name = attrNames[i++]) ) {\n\t\t\t\tpropName = jQuery.propFix[ name ] || name;\n\n\t\t\t\t// Boolean attributes get special treatment (#10870)\n\t\t\t\tif ( jQuery.expr.match.bool.test( name ) ) {\n\t\t\t\t\t// Set corresponding property to false\n\t\t\t\t\tif ( getSetInput && getSetAttribute || !ruseDefault.test( name ) ) {\n\t\t\t\t\t\telem[ propName ] = false;\n\t\t\t\t\t// Support: IE<9\n\t\t\t\t\t// Also clear defaultChecked/defaultSelected (if appropriate)\n\t\t\t\t\t} else {\n\t\t\t\t\t\telem[ jQuery.camelCase( \"default-\" + name ) ] =\n\t\t\t\t\t\t\telem[ propName ] = false;\n\t\t\t\t\t}\n\n\t\t\t\t// See #9699 for explanation of this approach (setting first, then removal)\n\t\t\t\t} else {\n\t\t\t\t\tjQuery.attr( elem, name, \"\" );\n\t\t\t\t}\n\n\t\t\t\telem.removeAttribute( getSetAttribute ? name : propName );\n\t\t\t}\n\t\t}\n\t},\n\n\tattrHooks: {\n\t\ttype: {\n\t\t\tset: function( elem, value ) {\n\t\t\t\tif ( !support.radioValue && value === \"radio\" && jQuery.nodeName(elem, \"input\") ) {\n\t\t\t\t\t// Setting the type on a radio button after the value resets the value in IE6-9\n\t\t\t\t\t// Reset value to default in case type is set after value during creation\n\t\t\t\t\tvar val = elem.value;\n\t\t\t\t\telem.setAttribute( \"type\", value );\n\t\t\t\t\tif ( val ) {\n\t\t\t\t\t\telem.value = val;\n\t\t\t\t\t}\n\t\t\t\t\treturn value;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n});\n\n// Hook for boolean attributes\nboolHook = {\n\tset: function( elem, value, name ) {\n\t\tif ( value === false ) {\n\t\t\t// Remove boolean attributes when set to false\n\t\t\tjQuery.removeAttr( elem, name );\n\t\t} else if ( getSetInput && getSetAttribute || !ruseDefault.test( name ) ) {\n\t\t\t// IE<8 needs the *property* name\n\t\t\telem.setAttribute( !getSetAttribute && jQuery.propFix[ name ] || name, name );\n\n\t\t// Use defaultChecked and defaultSelected for oldIE\n\t\t} else {\n\t\t\telem[ jQuery.camelCase( \"default-\" + name ) ] = elem[ name ] = true;\n\t\t}\n\n\t\treturn name;\n\t}\n};\n\n// Retrieve booleans specially\njQuery.each( jQuery.expr.match.bool.source.match( /\\w+/g ), function( i, name ) {\n\n\tvar getter = attrHandle[ name ] || jQuery.find.attr;\n\n\tattrHandle[ name ] = getSetInput && getSetAttribute || !ruseDefault.test( name ) ?\n\t\tfunction( elem, name, isXML ) {\n\t\t\tvar ret, handle;\n\t\t\tif ( !isXML ) {\n\t\t\t\t// Avoid an infinite loop by temporarily removing this function from the getter\n\t\t\t\thandle = attrHandle[ name ];\n\t\t\t\tattrHandle[ name ] = ret;\n\t\t\t\tret = getter( elem, name, isXML ) != null ?\n\t\t\t\t\tname.toLowerCase() :\n\t\t\t\t\tnull;\n\t\t\t\tattrHandle[ name ] = handle;\n\t\t\t}\n\t\t\treturn ret;\n\t\t} :\n\t\tfunction( elem, name, isXML ) {\n\t\t\tif ( !isXML ) {\n\t\t\t\treturn elem[ jQuery.camelCase( \"default-\" + name ) ] ?\n\t\t\t\t\tname.toLowerCase() :\n\t\t\t\t\tnull;\n\t\t\t}\n\t\t};\n});\n\n// fix oldIE attroperties\nif ( !getSetInput || !getSetAttribute ) {\n\tjQuery.attrHooks.value = {\n\t\tset: function( elem, value, name ) {\n\t\t\tif ( jQuery.nodeName( elem, \"input\" ) ) {\n\t\t\t\t// Does not return so that setAttribute is also used\n\t\t\t\telem.defaultValue = value;\n\t\t\t} else {\n\t\t\t\t// Use nodeHook if defined (#1954); otherwise setAttribute is fine\n\t\t\t\treturn nodeHook && nodeHook.set( elem, value, name );\n\t\t\t}\n\t\t}\n\t};\n}\n\n// IE6/7 do not support getting/setting some attributes with get/setAttribute\nif ( !getSetAttribute ) {\n\n\t// Use this for any attribute in IE6/7\n\t// This fixes almost every IE6/7 issue\n\tnodeHook = {\n\t\tset: function( elem, value, name ) {\n\t\t\t// Set the existing or create a new attribute node\n\t\t\tvar ret = elem.getAttributeNode( name );\n\t\t\tif ( !ret ) {\n\t\t\t\telem.setAttributeNode(\n\t\t\t\t\t(ret = elem.ownerDocument.createAttribute( name ))\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tret.value = value += \"\";\n\n\t\t\t// Break association with cloned elements by also using setAttribute (#9646)\n\t\t\tif ( name === \"value\" || value === elem.getAttribute( name ) ) {\n\t\t\t\treturn value;\n\t\t\t}\n\t\t}\n\t};\n\n\t// Some attributes are constructed with empty-string values when not defined\n\tattrHandle.id = attrHandle.name = attrHandle.coords =\n\t\tfunction( elem, name, isXML ) {\n\t\t\tvar ret;\n\t\t\tif ( !isXML ) {\n\t\t\t\treturn (ret = elem.getAttributeNode( name )) && ret.value !== \"\" ?\n\t\t\t\t\tret.value :\n\t\t\t\t\tnull;\n\t\t\t}\n\t\t};\n\n\t// Fixing value retrieval on a button requires this module\n\tjQuery.valHooks.button = {\n\t\tget: function( elem, name ) {\n\t\t\tvar ret = elem.getAttributeNode( name );\n\t\t\tif ( ret && ret.specified ) {\n\t\t\t\treturn ret.value;\n\t\t\t}\n\t\t},\n\t\tset: nodeHook.set\n\t};\n\n\t// Set contenteditable to false on removals(#10429)\n\t// Setting to empty string throws an error as an invalid value\n\tjQuery.attrHooks.contenteditable = {\n\t\tset: function( elem, value, name ) {\n\t\t\tnodeHook.set( elem, value === \"\" ? false : value, name );\n\t\t}\n\t};\n\n\t// Set width and height to auto instead of 0 on empty string( Bug #8150 )\n\t// This is for removals\n\tjQuery.each([ \"width\", \"height\" ], function( i, name ) {\n\t\tjQuery.attrHooks[ name ] = {\n\t\t\tset: function( elem, value ) {\n\t\t\t\tif ( value === \"\" ) {\n\t\t\t\t\telem.setAttribute( name, \"auto\" );\n\t\t\t\t\treturn value;\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\t});\n}\n\nif ( !support.style ) {\n\tjQuery.attrHooks.style = {\n\t\tget: function( elem ) {\n\t\t\t// Return undefined in the case of empty string\n\t\t\t// Note: IE uppercases css property names, but if we were to .toLowerCase()\n\t\t\t// .cssText, that would destroy case senstitivity in URL's, like in \"background\"\n\t\t\treturn elem.style.cssText || undefined;\n\t\t},\n\t\tset: function( elem, value ) {\n\t\t\treturn ( elem.style.cssText = value + \"\" );\n\t\t}\n\t};\n}\n\n\n\n\nvar rfocusable = /^(?:input|select|textarea|button|object)$/i,\n\trclickable = /^(?:a|area)$/i;\n\njQuery.fn.extend({\n\tprop: function( name, value ) {\n\t\treturn access( this, jQuery.prop, name, value, arguments.length > 1 );\n\t},\n\n\tremoveProp: function( name ) {\n\t\tname = jQuery.propFix[ name ] || name;\n\t\treturn this.each(function() {\n\t\t\t// try/catch handles cases where IE balks (such as removing a property on window)\n\t\t\ttry {\n\t\t\t\tthis[ name ] = undefined;\n\t\t\t\tdelete this[ name ];\n\t\t\t} catch( e ) {}\n\t\t});\n\t}\n});\n\njQuery.extend({\n\tpropFix: {\n\t\t\"for\": \"htmlFor\",\n\t\t\"class\": \"className\"\n\t},\n\n\tprop: function( elem, name, value ) {\n\t\tvar ret, hooks, notxml,\n\t\t\tnType = elem.nodeType;\n\n\t\t// don't get/set properties on text, comment and attribute nodes\n\t\tif ( !elem || nType === 3 || nType === 8 || nType === 2 ) {\n\t\t\treturn;\n\t\t}\n\n\t\tnotxml = nType !== 1 || !jQuery.isXMLDoc( elem );\n\n\t\tif ( notxml ) {\n\t\t\t// Fix name and attach hooks\n\t\t\tname = jQuery.propFix[ name ] || name;\n\t\t\thooks = jQuery.propHooks[ name ];\n\t\t}\n\n\t\tif ( value !== undefined ) {\n\t\t\treturn hooks && \"set\" in hooks && (ret = hooks.set( elem, value, name )) !== undefined ?\n\t\t\t\tret :\n\t\t\t\t( elem[ name ] = value );\n\n\t\t} else {\n\t\t\treturn hooks && \"get\" in hooks && (ret = hooks.get( elem, name )) !== null ?\n\t\t\t\tret :\n\t\t\t\telem[ name ];\n\t\t}\n\t},\n\n\tpropHooks: {\n\t\ttabIndex: {\n\t\t\tget: function( elem ) {\n\t\t\t\t// elem.tabIndex doesn't always return the correct value when it hasn't been explicitly set\n\t\t\t\t// http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/\n\t\t\t\t// Use proper attribute retrieval(#12072)\n\t\t\t\tvar tabindex = jQuery.find.attr( elem, \"tabindex\" );\n\n\t\t\t\treturn tabindex ?\n\t\t\t\t\tparseInt( tabindex, 10 ) :\n\t\t\t\t\trfocusable.test( elem.nodeName ) || rclickable.test( elem.nodeName ) && elem.href ?\n\t\t\t\t\t\t0 :\n\t\t\t\t\t\t-1;\n\t\t\t}\n\t\t}\n\t}\n});\n\n// Some attributes require a special call on IE\n// http://msdn.microsoft.com/en-us/library/ms536429%28VS.85%29.aspx\nif ( !support.hrefNormalized ) {\n\t// href/src property should get the full normalized URL (#10299/#12915)\n\tjQuery.each([ \"href\", \"src\" ], function( i, name ) {\n\t\tjQuery.propHooks[ name ] = {\n\t\t\tget: function( elem ) {\n\t\t\t\treturn elem.getAttribute( name, 4 );\n\t\t\t}\n\t\t};\n\t});\n}\n\n// Support: Safari, IE9+\n// mis-reports the default selected property of an option\n// Accessing the parent's selectedIndex property fixes it\nif ( !support.optSelected ) {\n\tjQuery.propHooks.selected = {\n\t\tget: function( elem ) {\n\t\t\tvar parent = elem.parentNode;\n\n\t\t\tif ( parent ) {\n\t\t\t\tparent.selectedIndex;\n\n\t\t\t\t// Make sure that it also works with optgroups, see #5701\n\t\t\t\tif ( parent.parentNode ) {\n\t\t\t\t\tparent.parentNode.selectedIndex;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn null;\n\t\t}\n\t};\n}\n\njQuery.each([\n\t\"tabIndex\",\n\t\"readOnly\",\n\t\"maxLength\",\n\t\"cellSpacing\",\n\t\"cellPadding\",\n\t\"rowSpan\",\n\t\"colSpan\",\n\t\"useMap\",\n\t\"frameBorder\",\n\t\"contentEditable\"\n], function() {\n\tjQuery.propFix[ this.toLowerCase() ] = this;\n});\n\n// IE6/7 call enctype encoding\nif ( !support.enctype ) {\n\tjQuery.propFix.enctype = \"encoding\";\n}\n\n\n\n\nvar rclass = /[\\t\\r\\n\\f]/g;\n\njQuery.fn.extend({\n\taddClass: function( value ) {\n\t\tvar classes, elem, cur, clazz, j, finalValue,\n\t\t\ti = 0,\n\t\t\tlen = this.length,\n\t\t\tproceed = typeof value === \"string\" && value;\n\n\t\tif ( jQuery.isFunction( value ) ) {\n\t\t\treturn this.each(function( j ) {\n\t\t\t\tjQuery( this ).addClass( value.call( this, j, this.className ) );\n\t\t\t});\n\t\t}\n\n\t\tif ( proceed ) {\n\t\t\t// The disjunction here is for better compressibility (see removeClass)\n\t\t\tclasses = ( value || \"\" ).match( rnotwhite ) || [];\n\n\t\t\tfor ( ; i < len; i++ ) {\n\t\t\t\telem = this[ i ];\n\t\t\t\tcur = elem.nodeType === 1 && ( elem.className ?\n\t\t\t\t\t( \" \" + elem.className + \" \" ).replace( rclass, \" \" ) :\n\t\t\t\t\t\" \"\n\t\t\t\t);\n\n\t\t\t\tif ( cur ) {\n\t\t\t\t\tj = 0;\n\t\t\t\t\twhile ( (clazz = classes[j++]) ) {\n\t\t\t\t\t\tif ( cur.indexOf( \" \" + clazz + \" \" ) < 0 ) {\n\t\t\t\t\t\t\tcur += clazz + \" \";\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\t// only assign if different to avoid unneeded rendering.\n\t\t\t\t\tfinalValue = jQuery.trim( cur );\n\t\t\t\t\tif ( elem.className !== finalValue ) {\n\t\t\t\t\t\telem.className = finalValue;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn this;\n\t},\n\n\tremoveClass: function( value ) {\n\t\tvar classes, elem, cur, clazz, j, finalValue,\n\t\t\ti = 0,\n\t\t\tlen = this.length,\n\t\t\tproceed = arguments.length === 0 || typeof value === \"string\" && value;\n\n\t\tif ( jQuery.isFunction( value ) ) {\n\t\t\treturn this.each(function( j ) {\n\t\t\t\tjQuery( this ).removeClass( value.call( this, j, this.className ) );\n\t\t\t});\n\t\t}\n\t\tif ( proceed ) {\n\t\t\tclasses = ( value || \"\" ).match( rnotwhite ) || [];\n\n\t\t\tfor ( ; i < len; i++ ) {\n\t\t\t\telem = this[ i ];\n\t\t\t\t// This expression is here for better compressibility (see addClass)\n\t\t\t\tcur = elem.nodeType === 1 && ( elem.className ?\n\t\t\t\t\t( \" \" + elem.className + \" \" ).replace( rclass, \" \" ) :\n\t\t\t\t\t\"\"\n\t\t\t\t);\n\n\t\t\t\tif ( cur ) {\n\t\t\t\t\tj = 0;\n\t\t\t\t\twhile ( (clazz = classes[j++]) ) {\n\t\t\t\t\t\t// Remove *all* instances\n\t\t\t\t\t\twhile ( cur.indexOf( \" \" + clazz + \" \" ) >= 0 ) {\n\t\t\t\t\t\t\tcur = cur.replace( \" \" + clazz + \" \", \" \" );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\t// only assign if different to avoid unneeded rendering.\n\t\t\t\t\tfinalValue = value ? jQuery.trim( cur ) : \"\";\n\t\t\t\t\tif ( elem.className !== finalValue ) {\n\t\t\t\t\t\telem.className = finalValue;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn this;\n\t},\n\n\ttoggleClass: function( value, stateVal ) {\n\t\tvar type = typeof value;\n\n\t\tif ( typeof stateVal === \"boolean\" && type === \"string\" ) {\n\t\t\treturn stateVal ? this.addClass( value ) : this.removeClass( value );\n\t\t}\n\n\t\tif ( jQuery.isFunction( value ) ) {\n\t\t\treturn this.each(function( i ) {\n\t\t\t\tjQuery( this ).toggleClass( value.call(this, i, this.className, stateVal), stateVal );\n\t\t\t});\n\t\t}\n\n\t\treturn this.each(function() {\n\t\t\tif ( type === \"string\" ) {\n\t\t\t\t// toggle individual class names\n\t\t\t\tvar className,\n\t\t\t\t\ti = 0,\n\t\t\t\t\tself = jQuery( this ),\n\t\t\t\t\tclassNames = value.match( rnotwhite ) || [];\n\n\t\t\t\twhile ( (className = classNames[ i++ ]) ) {\n\t\t\t\t\t// check each className given, space separated list\n\t\t\t\t\tif ( self.hasClass( className ) ) {\n\t\t\t\t\t\tself.removeClass( className );\n\t\t\t\t\t} else {\n\t\t\t\t\t\tself.addClass( className );\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t// Toggle whole class name\n\t\t\t} else if ( type === strundefined || type === \"boolean\" ) {\n\t\t\t\tif ( this.className ) {\n\t\t\t\t\t// store className if set\n\t\t\t\t\tjQuery._data( this, \"__className__\", this.className );\n\t\t\t\t}\n\n\t\t\t\t// If the element has a class name or if we're passed \"false\",\n\t\t\t\t// then remove the whole classname (if there was one, the above saved it).\n\t\t\t\t// Otherwise bring back whatever was previously saved (if anything),\n\t\t\t\t// falling back to the empty string if nothing was stored.\n\t\t\t\tthis.className = this.className || value === false ? \"\" : jQuery._data( this, \"__className__\" ) || \"\";\n\t\t\t}\n\t\t});\n\t},\n\n\thasClass: function( selector ) {\n\t\tvar className = \" \" + selector + \" \",\n\t\t\ti = 0,\n\t\t\tl = this.length;\n\t\tfor ( ; i < l; i++ ) {\n\t\t\tif ( this[i].nodeType === 1 && (\" \" + this[i].className + \" \").replace(rclass, \" \").indexOf( className ) >= 0 ) {\n\t\t\t\treturn true;\n\t\t\t}\n\t\t}\n\n\t\treturn false;\n\t}\n});\n\n\n\n\n// Return jQuery for attributes-only inclusion\n\n\njQuery.each( (\"blur focus focusin focusout load resize scroll unload click dblclick \" +\n\t\"mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave \" +\n\t\"change select submit keydown keypress keyup error contextmenu\").split(\" \"), function( i, name ) {\n\n\t// Handle event binding\n\tjQuery.fn[ name ] = function( data, fn ) {\n\t\treturn arguments.length > 0 ?\n\t\t\tthis.on( name, null, data, fn ) :\n\t\t\tthis.trigger( name );\n\t};\n});\n\njQuery.fn.extend({\n\thover: function( fnOver, fnOut ) {\n\t\treturn this.mouseenter( fnOver ).mouseleave( fnOut || fnOver );\n\t},\n\n\tbind: function( types, data, fn ) {\n\t\treturn this.on( types, null, data, fn );\n\t},\n\tunbind: function( types, fn ) {\n\t\treturn this.off( types, null, fn );\n\t},\n\n\tdelegate: function( selector, types, data, fn ) {\n\t\treturn this.on( types, selector, data, fn );\n\t},\n\tundelegate: function( selector, types, fn ) {\n\t\t// ( namespace ) or ( selector, types [, fn] )\n\t\treturn arguments.length === 1 ? this.off( selector, \"**\" ) : this.off( types, selector || \"**\", fn );\n\t}\n});\n\n\nvar nonce = jQuery.now();\n\nvar rquery = (/\\?/);\n\n\n\nvar rvalidtokens = /(,)|(\\[|{)|(}|])|\"(?:[^\"\\\\\\r\\n]|\\\\[\"\\\\\\/bfnrt]|\\\\u[\\da-fA-F]{4})*\"\\s*:?|true|false|null|-?(?!0\\d)\\d+(?:\\.\\d+|)(?:[eE][+-]?\\d+|)/g;\n\njQuery.parseJSON = function( data ) {\n\t// Attempt to parse using the native JSON parser first\n\tif ( window.JSON && window.JSON.parse ) {\n\t\t// Support: Android 2.3\n\t\t// Workaround failure to string-cast null input\n\t\treturn window.JSON.parse( data + \"\" );\n\t}\n\n\tvar requireNonComma,\n\t\tdepth = null,\n\t\tstr = jQuery.trim( data + \"\" );\n\n\t// Guard against invalid (and possibly dangerous) input by ensuring that nothing remains\n\t// after removing valid tokens\n\treturn str && !jQuery.trim( str.replace( rvalidtokens, function( token, comma, open, close ) {\n\n\t\t// Force termination if we see a misplaced comma\n\t\tif ( requireNonComma && comma ) {\n\t\t\tdepth = 0;\n\t\t}\n\n\t\t// Perform no more replacements after returning to outermost depth\n\t\tif ( depth === 0 ) {\n\t\t\treturn token;\n\t\t}\n\n\t\t// Commas must not follow \"[\", \"{\", or \",\"\n\t\trequireNonComma = open || comma;\n\n\t\t// Determine new depth\n\t\t// array/object open (\"[\" or \"{\"): depth += true - false (increment)\n\t\t// array/object close (\"]\" or \"}\"): depth += false - true (decrement)\n\t\t// other cases (\",\" or primitive): depth += true - true (numeric cast)\n\t\tdepth += !close - !open;\n\n\t\t// Remove this token\n\t\treturn \"\";\n\t}) ) ?\n\t\t( Function( \"return \" + str ) )() :\n\t\tjQuery.error( \"Invalid JSON: \" + data );\n};\n\n\n// Cross-browser xml parsing\njQuery.parseXML = function( data ) {\n\tvar xml, tmp;\n\tif ( !data || typeof data !== \"string\" ) {\n\t\treturn null;\n\t}\n\ttry {\n\t\tif ( window.DOMParser ) { // Standard\n\t\t\ttmp = new DOMParser();\n\t\t\txml = tmp.parseFromString( data, \"text/xml\" );\n\t\t} else { // IE\n\t\t\txml = new ActiveXObject( \"Microsoft.XMLDOM\" );\n\t\t\txml.async = \"false\";\n\t\t\txml.loadXML( data );\n\t\t}\n\t} catch( e ) {\n\t\txml = undefined;\n\t}\n\tif ( !xml || !xml.documentElement || xml.getElementsByTagName( \"parsererror\" ).length ) {\n\t\tjQuery.error( \"Invalid XML: \" + data );\n\t}\n\treturn xml;\n};\n\n\nvar\n\t// Document location\n\tajaxLocParts,\n\tajaxLocation,\n\n\trhash = /#.*$/,\n\trts = /([?&])_=[^&]*/,\n\trheaders = /^(.*?):[ \\t]*([^\\r\\n]*)\\r?$/mg, // IE leaves an \\r character at EOL\n\t// #7653, #8125, #8152: local protocol detection\n\trlocalProtocol = /^(?:about|app|app-storage|.+-extension|file|res|widget):$/,\n\trnoContent = /^(?:GET|HEAD)$/,\n\trprotocol = /^\\/\\//,\n\trurl = /^([\\w.+-]+:)(?:\\/\\/(?:[^\\/?#]*@|)([^\\/?#:]*)(?::(\\d+)|)|)/,\n\n\t/* Prefilters\n\t * 1) They are useful to introduce custom dataTypes (see ajax/jsonp.js for an example)\n\t * 2) These are called:\n\t *    - BEFORE asking for a transport\n\t *    - AFTER param serialization (s.data is a string if s.processData is true)\n\t * 3) key is the dataType\n\t * 4) the catchall symbol \"*\" can be used\n\t * 5) execution will start with transport dataType and THEN continue down to \"*\" if needed\n\t */\n\tprefilters = {},\n\n\t/* Transports bindings\n\t * 1) key is the dataType\n\t * 2) the catchall symbol \"*\" can be used\n\t * 3) selection will start with transport dataType and THEN go to \"*\" if needed\n\t */\n\ttransports = {},\n\n\t// Avoid comment-prolog char sequence (#10098); must appease lint and evade compression\n\tallTypes = \"*/\".concat(\"*\");\n\n// #8138, IE may throw an exception when accessing\n// a field from window.location if document.domain has been set\ntry {\n\tajaxLocation = location.href;\n} catch( e ) {\n\t// Use the href attribute of an A element\n\t// since IE will modify it given document.location\n\tajaxLocation = document.createElement( \"a\" );\n\tajaxLocation.href = \"\";\n\tajaxLocation = ajaxLocation.href;\n}\n\n// Segment location into parts\najaxLocParts = rurl.exec( ajaxLocation.toLowerCase() ) || [];\n\n// Base \"constructor\" for jQuery.ajaxPrefilter and jQuery.ajaxTransport\nfunction addToPrefiltersOrTransports( structure ) {\n\n\t// dataTypeExpression is optional and defaults to \"*\"\n\treturn function( dataTypeExpression, func ) {\n\n\t\tif ( typeof dataTypeExpression !== \"string\" ) {\n\t\t\tfunc = dataTypeExpression;\n\t\t\tdataTypeExpression = \"*\";\n\t\t}\n\n\t\tvar dataType,\n\t\t\ti = 0,\n\t\t\tdataTypes = dataTypeExpression.toLowerCase().match( rnotwhite ) || [];\n\n\t\tif ( jQuery.isFunction( func ) ) {\n\t\t\t// For each dataType in the dataTypeExpression\n\t\t\twhile ( (dataType = dataTypes[i++]) ) {\n\t\t\t\t// Prepend if requested\n\t\t\t\tif ( dataType.charAt( 0 ) === \"+\" ) {\n\t\t\t\t\tdataType = dataType.slice( 1 ) || \"*\";\n\t\t\t\t\t(structure[ dataType ] = structure[ dataType ] || []).unshift( func );\n\n\t\t\t\t// Otherwise append\n\t\t\t\t} else {\n\t\t\t\t\t(structure[ dataType ] = structure[ dataType ] || []).push( func );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t};\n}\n\n// Base inspection function for prefilters and transports\nfunction inspectPrefiltersOrTransports( structure, options, originalOptions, jqXHR ) {\n\n\tvar inspected = {},\n\t\tseekingTransport = ( structure === transports );\n\n\tfunction inspect( dataType ) {\n\t\tvar selected;\n\t\tinspected[ dataType ] = true;\n\t\tjQuery.each( structure[ dataType ] || [], function( _, prefilterOrFactory ) {\n\t\t\tvar dataTypeOrTransport = prefilterOrFactory( options, originalOptions, jqXHR );\n\t\t\tif ( typeof dataTypeOrTransport === \"string\" && !seekingTransport && !inspected[ dataTypeOrTransport ] ) {\n\t\t\t\toptions.dataTypes.unshift( dataTypeOrTransport );\n\t\t\t\tinspect( dataTypeOrTransport );\n\t\t\t\treturn false;\n\t\t\t} else if ( seekingTransport ) {\n\t\t\t\treturn !( selected = dataTypeOrTransport );\n\t\t\t}\n\t\t});\n\t\treturn selected;\n\t}\n\n\treturn inspect( options.dataTypes[ 0 ] ) || !inspected[ \"*\" ] && inspect( \"*\" );\n}\n\n// A special extend for ajax options\n// that takes \"flat\" options (not to be deep extended)\n// Fixes #9887\nfunction ajaxExtend( target, src ) {\n\tvar deep, key,\n\t\tflatOptions = jQuery.ajaxSettings.flatOptions || {};\n\n\tfor ( key in src ) {\n\t\tif ( src[ key ] !== undefined ) {\n\t\t\t( flatOptions[ key ] ? target : ( deep || (deep = {}) ) )[ key ] = src[ key ];\n\t\t}\n\t}\n\tif ( deep ) {\n\t\tjQuery.extend( true, target, deep );\n\t}\n\n\treturn target;\n}\n\n/* Handles responses to an ajax request:\n * - finds the right dataType (mediates between content-type and expected dataType)\n * - returns the corresponding response\n */\nfunction ajaxHandleResponses( s, jqXHR, responses ) {\n\tvar firstDataType, ct, finalDataType, type,\n\t\tcontents = s.contents,\n\t\tdataTypes = s.dataTypes;\n\n\t// Remove auto dataType and get content-type in the process\n\twhile ( dataTypes[ 0 ] === \"*\" ) {\n\t\tdataTypes.shift();\n\t\tif ( ct === undefined ) {\n\t\t\tct = s.mimeType || jqXHR.getResponseHeader(\"Content-Type\");\n\t\t}\n\t}\n\n\t// Check if we're dealing with a known content-type\n\tif ( ct ) {\n\t\tfor ( type in contents ) {\n\t\t\tif ( contents[ type ] && contents[ type ].test( ct ) ) {\n\t\t\t\tdataTypes.unshift( type );\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t}\n\n\t// Check to see if we have a response for the expected dataType\n\tif ( dataTypes[ 0 ] in responses ) {\n\t\tfinalDataType = dataTypes[ 0 ];\n\t} else {\n\t\t// Try convertible dataTypes\n\t\tfor ( type in responses ) {\n\t\t\tif ( !dataTypes[ 0 ] || s.converters[ type + \" \" + dataTypes[0] ] ) {\n\t\t\t\tfinalDataType = type;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tif ( !firstDataType ) {\n\t\t\t\tfirstDataType = type;\n\t\t\t}\n\t\t}\n\t\t// Or just use first one\n\t\tfinalDataType = finalDataType || firstDataType;\n\t}\n\n\t// If we found a dataType\n\t// We add the dataType to the list if needed\n\t// and return the corresponding response\n\tif ( finalDataType ) {\n\t\tif ( finalDataType !== dataTypes[ 0 ] ) {\n\t\t\tdataTypes.unshift( finalDataType );\n\t\t}\n\t\treturn responses[ finalDataType ];\n\t}\n}\n\n/* Chain conversions given the request and the original response\n * Also sets the responseXXX fields on the jqXHR instance\n */\nfunction ajaxConvert( s, response, jqXHR, isSuccess ) {\n\tvar conv2, current, conv, tmp, prev,\n\t\tconverters = {},\n\t\t// Work with a copy of dataTypes in case we need to modify it for conversion\n\t\tdataTypes = s.dataTypes.slice();\n\n\t// Create converters map with lowercased keys\n\tif ( dataTypes[ 1 ] ) {\n\t\tfor ( conv in s.converters ) {\n\t\t\tconverters[ conv.toLowerCase() ] = s.converters[ conv ];\n\t\t}\n\t}\n\n\tcurrent = dataTypes.shift();\n\n\t// Convert to each sequential dataType\n\twhile ( current ) {\n\n\t\tif ( s.responseFields[ current ] ) {\n\t\t\tjqXHR[ s.responseFields[ current ] ] = response;\n\t\t}\n\n\t\t// Apply the dataFilter if provided\n\t\tif ( !prev && isSuccess && s.dataFilter ) {\n\t\t\tresponse = s.dataFilter( response, s.dataType );\n\t\t}\n\n\t\tprev = current;\n\t\tcurrent = dataTypes.shift();\n\n\t\tif ( current ) {\n\n\t\t\t// There's only work to do if current dataType is non-auto\n\t\t\tif ( current === \"*\" ) {\n\n\t\t\t\tcurrent = prev;\n\n\t\t\t// Convert response if prev dataType is non-auto and differs from current\n\t\t\t} else if ( prev !== \"*\" && prev !== current ) {\n\n\t\t\t\t// Seek a direct converter\n\t\t\t\tconv = converters[ prev + \" \" + current ] || converters[ \"* \" + current ];\n\n\t\t\t\t// If none found, seek a pair\n\t\t\t\tif ( !conv ) {\n\t\t\t\t\tfor ( conv2 in converters ) {\n\n\t\t\t\t\t\t// If conv2 outputs current\n\t\t\t\t\t\ttmp = conv2.split( \" \" );\n\t\t\t\t\t\tif ( tmp[ 1 ] === current ) {\n\n\t\t\t\t\t\t\t// If prev can be converted to accepted input\n\t\t\t\t\t\t\tconv = converters[ prev + \" \" + tmp[ 0 ] ] ||\n\t\t\t\t\t\t\t\tconverters[ \"* \" + tmp[ 0 ] ];\n\t\t\t\t\t\t\tif ( conv ) {\n\t\t\t\t\t\t\t\t// Condense equivalence converters\n\t\t\t\t\t\t\t\tif ( conv === true ) {\n\t\t\t\t\t\t\t\t\tconv = converters[ conv2 ];\n\n\t\t\t\t\t\t\t\t// Otherwise, insert the intermediate dataType\n\t\t\t\t\t\t\t\t} else if ( converters[ conv2 ] !== true ) {\n\t\t\t\t\t\t\t\t\tcurrent = tmp[ 0 ];\n\t\t\t\t\t\t\t\t\tdataTypes.unshift( tmp[ 1 ] );\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// Apply converter (if not an equivalence)\n\t\t\t\tif ( conv !== true ) {\n\n\t\t\t\t\t// Unless errors are allowed to bubble, catch and return them\n\t\t\t\t\tif ( conv && s[ \"throws\" ] ) {\n\t\t\t\t\t\tresponse = conv( response );\n\t\t\t\t\t} else {\n\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\tresponse = conv( response );\n\t\t\t\t\t\t} catch ( e ) {\n\t\t\t\t\t\t\treturn { state: \"parsererror\", error: conv ? e : \"No conversion from \" + prev + \" to \" + current };\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\treturn { state: \"success\", data: response };\n}\n\njQuery.extend({\n\n\t// Counter for holding the number of active queries\n\tactive: 0,\n\n\t// Last-Modified header cache for next request\n\tlastModified: {},\n\tetag: {},\n\n\tajaxSettings: {\n\t\turl: ajaxLocation,\n\t\ttype: \"GET\",\n\t\tisLocal: rlocalProtocol.test( ajaxLocParts[ 1 ] ),\n\t\tglobal: true,\n\t\tprocessData: true,\n\t\tasync: true,\n\t\tcontentType: \"application/x-www-form-urlencoded; charset=UTF-8\",\n\t\t/*\n\t\ttimeout: 0,\n\t\tdata: null,\n\t\tdataType: null,\n\t\tusername: null,\n\t\tpassword: null,\n\t\tcache: null,\n\t\tthrows: false,\n\t\ttraditional: false,\n\t\theaders: {},\n\t\t*/\n\n\t\taccepts: {\n\t\t\t\"*\": allTypes,\n\t\t\ttext: \"text/plain\",\n\t\t\thtml: \"text/html\",\n\t\t\txml: \"application/xml, text/xml\",\n\t\t\tjson: \"application/json, text/javascript\"\n\t\t},\n\n\t\tcontents: {\n\t\t\txml: /xml/,\n\t\t\thtml: /html/,\n\t\t\tjson: /json/\n\t\t},\n\n\t\tresponseFields: {\n\t\t\txml: \"responseXML\",\n\t\t\ttext: \"responseText\",\n\t\t\tjson: \"responseJSON\"\n\t\t},\n\n\t\t// Data converters\n\t\t// Keys separate source (or catchall \"*\") and destination types with a single space\n\t\tconverters: {\n\n\t\t\t// Convert anything to text\n\t\t\t\"* text\": String,\n\n\t\t\t// Text to html (true = no transformation)\n\t\t\t\"text html\": true,\n\n\t\t\t// Evaluate text as a json expression\n\t\t\t\"text json\": jQuery.parseJSON,\n\n\t\t\t// Parse text as xml\n\t\t\t\"text xml\": jQuery.parseXML\n\t\t},\n\n\t\t// For options that shouldn't be deep extended:\n\t\t// you can add your own custom options here if\n\t\t// and when you create one that shouldn't be\n\t\t// deep extended (see ajaxExtend)\n\t\tflatOptions: {\n\t\t\turl: true,\n\t\t\tcontext: true\n\t\t}\n\t},\n\n\t// Creates a full fledged settings object into target\n\t// with both ajaxSettings and settings fields.\n\t// If target is omitted, writes into ajaxSettings.\n\tajaxSetup: function( target, settings ) {\n\t\treturn settings ?\n\n\t\t\t// Building a settings object\n\t\t\tajaxExtend( ajaxExtend( target, jQuery.ajaxSettings ), settings ) :\n\n\t\t\t// Extending ajaxSettings\n\t\t\tajaxExtend( jQuery.ajaxSettings, target );\n\t},\n\n\tajaxPrefilter: addToPrefiltersOrTransports( prefilters ),\n\tajaxTransport: addToPrefiltersOrTransports( transports ),\n\n\t// Main method\n\tajax: function( url, options ) {\n\n\t\t// If url is an object, simulate pre-1.5 signature\n\t\tif ( typeof url === \"object\" ) {\n\t\t\toptions = url;\n\t\t\turl = undefined;\n\t\t}\n\n\t\t// Force options to be an object\n\t\toptions = options || {};\n\n\t\tvar // Cross-domain detection vars\n\t\t\tparts,\n\t\t\t// Loop variable\n\t\t\ti,\n\t\t\t// URL without anti-cache param\n\t\t\tcacheURL,\n\t\t\t// Response headers as string\n\t\t\tresponseHeadersString,\n\t\t\t// timeout handle\n\t\t\ttimeoutTimer,\n\n\t\t\t// To know if global events are to be dispatched\n\t\t\tfireGlobals,\n\n\t\t\ttransport,\n\t\t\t// Response headers\n\t\t\tresponseHeaders,\n\t\t\t// Create the final options object\n\t\t\ts = jQuery.ajaxSetup( {}, options ),\n\t\t\t// Callbacks context\n\t\t\tcallbackContext = s.context || s,\n\t\t\t// Context for global events is callbackContext if it is a DOM node or jQuery collection\n\t\t\tglobalEventContext = s.context && ( callbackContext.nodeType || callbackContext.jquery ) ?\n\t\t\t\tjQuery( callbackContext ) :\n\t\t\t\tjQuery.event,\n\t\t\t// Deferreds\n\t\t\tdeferred = jQuery.Deferred(),\n\t\t\tcompleteDeferred = jQuery.Callbacks(\"once memory\"),\n\t\t\t// Status-dependent callbacks\n\t\t\tstatusCode = s.statusCode || {},\n\t\t\t// Headers (they are sent all at once)\n\t\t\trequestHeaders = {},\n\t\t\trequestHeadersNames = {},\n\t\t\t// The jqXHR state\n\t\t\tstate = 0,\n\t\t\t// Default abort message\n\t\t\tstrAbort = \"canceled\",\n\t\t\t// Fake xhr\n\t\t\tjqXHR = {\n\t\t\t\treadyState: 0,\n\n\t\t\t\t// Builds headers hashtable if needed\n\t\t\t\tgetResponseHeader: function( key ) {\n\t\t\t\t\tvar match;\n\t\t\t\t\tif ( state === 2 ) {\n\t\t\t\t\t\tif ( !responseHeaders ) {\n\t\t\t\t\t\t\tresponseHeaders = {};\n\t\t\t\t\t\t\twhile ( (match = rheaders.exec( responseHeadersString )) ) {\n\t\t\t\t\t\t\t\tresponseHeaders[ match[1].toLowerCase() ] = match[ 2 ];\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\tmatch = responseHeaders[ key.toLowerCase() ];\n\t\t\t\t\t}\n\t\t\t\t\treturn match == null ? null : match;\n\t\t\t\t},\n\n\t\t\t\t// Raw string\n\t\t\t\tgetAllResponseHeaders: function() {\n\t\t\t\t\treturn state === 2 ? responseHeadersString : null;\n\t\t\t\t},\n\n\t\t\t\t// Caches the header\n\t\t\t\tsetRequestHeader: function( name, value ) {\n\t\t\t\t\tvar lname = name.toLowerCase();\n\t\t\t\t\tif ( !state ) {\n\t\t\t\t\t\tname = requestHeadersNames[ lname ] = requestHeadersNames[ lname ] || name;\n\t\t\t\t\t\trequestHeaders[ name ] = value;\n\t\t\t\t\t}\n\t\t\t\t\treturn this;\n\t\t\t\t},\n\n\t\t\t\t// Overrides response content-type header\n\t\t\t\toverrideMimeType: function( type ) {\n\t\t\t\t\tif ( !state ) {\n\t\t\t\t\t\ts.mimeType = type;\n\t\t\t\t\t}\n\t\t\t\t\treturn this;\n\t\t\t\t},\n\n\t\t\t\t// Status-dependent callbacks\n\t\t\t\tstatusCode: function( map ) {\n\t\t\t\t\tvar code;\n\t\t\t\t\tif ( map ) {\n\t\t\t\t\t\tif ( state < 2 ) {\n\t\t\t\t\t\t\tfor ( code in map ) {\n\t\t\t\t\t\t\t\t// Lazy-add the new callback in a way that preserves old ones\n\t\t\t\t\t\t\t\tstatusCode[ code ] = [ statusCode[ code ], map[ code ] ];\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t// Execute the appropriate callbacks\n\t\t\t\t\t\t\tjqXHR.always( map[ jqXHR.status ] );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\treturn this;\n\t\t\t\t},\n\n\t\t\t\t// Cancel the request\n\t\t\t\tabort: function( statusText ) {\n\t\t\t\t\tvar finalText = statusText || strAbort;\n\t\t\t\t\tif ( transport ) {\n\t\t\t\t\t\ttransport.abort( finalText );\n\t\t\t\t\t}\n\t\t\t\t\tdone( 0, finalText );\n\t\t\t\t\treturn this;\n\t\t\t\t}\n\t\t\t};\n\n\t\t// Attach deferreds\n\t\tdeferred.promise( jqXHR ).complete = completeDeferred.add;\n\t\tjqXHR.success = jqXHR.done;\n\t\tjqXHR.error = jqXHR.fail;\n\n\t\t// Remove hash character (#7531: and string promotion)\n\t\t// Add protocol if not provided (#5866: IE7 issue with protocol-less urls)\n\t\t// Handle falsy url in the settings object (#10093: consistency with old signature)\n\t\t// We also use the url parameter if available\n\t\ts.url = ( ( url || s.url || ajaxLocation ) + \"\" ).replace( rhash, \"\" ).replace( rprotocol, ajaxLocParts[ 1 ] + \"//\" );\n\n\t\t// Alias method option to type as per ticket #12004\n\t\ts.type = options.method || options.type || s.method || s.type;\n\n\t\t// Extract dataTypes list\n\t\ts.dataTypes = jQuery.trim( s.dataType || \"*\" ).toLowerCase().match( rnotwhite ) || [ \"\" ];\n\n\t\t// A cross-domain request is in order when we have a protocol:host:port mismatch\n\t\tif ( s.crossDomain == null ) {\n\t\t\tparts = rurl.exec( s.url.toLowerCase() );\n\t\t\ts.crossDomain = !!( parts &&\n\t\t\t\t( parts[ 1 ] !== ajaxLocParts[ 1 ] || parts[ 2 ] !== ajaxLocParts[ 2 ] ||\n\t\t\t\t\t( parts[ 3 ] || ( parts[ 1 ] === \"http:\" ? \"80\" : \"443\" ) ) !==\n\t\t\t\t\t\t( ajaxLocParts[ 3 ] || ( ajaxLocParts[ 1 ] === \"http:\" ? \"80\" : \"443\" ) ) )\n\t\t\t);\n\t\t}\n\n\t\t// Convert data if not already a string\n\t\tif ( s.data && s.processData && typeof s.data !== \"string\" ) {\n\t\t\ts.data = jQuery.param( s.data, s.traditional );\n\t\t}\n\n\t\t// Apply prefilters\n\t\tinspectPrefiltersOrTransports( prefilters, s, options, jqXHR );\n\n\t\t// If request was aborted inside a prefilter, stop there\n\t\tif ( state === 2 ) {\n\t\t\treturn jqXHR;\n\t\t}\n\n\t\t// We can fire global events as of now if asked to\n\t\t// Don't fire events if jQuery.event is undefined in an AMD-usage scenario (#15118)\n\t\tfireGlobals = jQuery.event && s.global;\n\n\t\t// Watch for a new set of requests\n\t\tif ( fireGlobals && jQuery.active++ === 0 ) {\n\t\t\tjQuery.event.trigger(\"ajaxStart\");\n\t\t}\n\n\t\t// Uppercase the type\n\t\ts.type = s.type.toUpperCase();\n\n\t\t// Determine if request has content\n\t\ts.hasContent = !rnoContent.test( s.type );\n\n\t\t// Save the URL in case we're toying with the If-Modified-Since\n\t\t// and/or If-None-Match header later on\n\t\tcacheURL = s.url;\n\n\t\t// More options handling for requests with no content\n\t\tif ( !s.hasContent ) {\n\n\t\t\t// If data is available, append data to url\n\t\t\tif ( s.data ) {\n\t\t\t\tcacheURL = ( s.url += ( rquery.test( cacheURL ) ? \"&\" : \"?\" ) + s.data );\n\t\t\t\t// #9682: remove data so that it's not used in an eventual retry\n\t\t\t\tdelete s.data;\n\t\t\t}\n\n\t\t\t// Add anti-cache in url if needed\n\t\t\tif ( s.cache === false ) {\n\t\t\t\ts.url = rts.test( cacheURL ) ?\n\n\t\t\t\t\t// If there is already a '_' parameter, set its value\n\t\t\t\t\tcacheURL.replace( rts, \"$1_=\" + nonce++ ) :\n\n\t\t\t\t\t// Otherwise add one to the end\n\t\t\t\t\tcacheURL + ( rquery.test( cacheURL ) ? \"&\" : \"?\" ) + \"_=\" + nonce++;\n\t\t\t}\n\t\t}\n\n\t\t// Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.\n\t\tif ( s.ifModified ) {\n\t\t\tif ( jQuery.lastModified[ cacheURL ] ) {\n\t\t\t\tjqXHR.setRequestHeader( \"If-Modified-Since\", jQuery.lastModified[ cacheURL ] );\n\t\t\t}\n\t\t\tif ( jQuery.etag[ cacheURL ] ) {\n\t\t\t\tjqXHR.setRequestHeader( \"If-None-Match\", jQuery.etag[ cacheURL ] );\n\t\t\t}\n\t\t}\n\n\t\t// Set the correct header, if data is being sent\n\t\tif ( s.data && s.hasContent && s.contentType !== false || options.contentType ) {\n\t\t\tjqXHR.setRequestHeader( \"Content-Type\", s.contentType );\n\t\t}\n\n\t\t// Set the Accepts header for the server, depending on the dataType\n\t\tjqXHR.setRequestHeader(\n\t\t\t\"Accept\",\n\t\t\ts.dataTypes[ 0 ] && s.accepts[ s.dataTypes[0] ] ?\n\t\t\t\ts.accepts[ s.dataTypes[0] ] + ( s.dataTypes[ 0 ] !== \"*\" ? \", \" + allTypes + \"; q=0.01\" : \"\" ) :\n\t\t\t\ts.accepts[ \"*\" ]\n\t\t);\n\n\t\t// Check for headers option\n\t\tfor ( i in s.headers ) {\n\t\t\tjqXHR.setRequestHeader( i, s.headers[ i ] );\n\t\t}\n\n\t\t// Allow custom headers/mimetypes and early abort\n\t\tif ( s.beforeSend && ( s.beforeSend.call( callbackContext, jqXHR, s ) === false || state === 2 ) ) {\n\t\t\t// Abort if not done already and return\n\t\t\treturn jqXHR.abort();\n\t\t}\n\n\t\t// aborting is no longer a cancellation\n\t\tstrAbort = \"abort\";\n\n\t\t// Install callbacks on deferreds\n\t\tfor ( i in { success: 1, error: 1, complete: 1 } ) {\n\t\t\tjqXHR[ i ]( s[ i ] );\n\t\t}\n\n\t\t// Get transport\n\t\ttransport = inspectPrefiltersOrTransports( transports, s, options, jqXHR );\n\n\t\t// If no transport, we auto-abort\n\t\tif ( !transport ) {\n\t\t\tdone( -1, \"No Transport\" );\n\t\t} else {\n\t\t\tjqXHR.readyState = 1;\n\n\t\t\t// Send global event\n\t\t\tif ( fireGlobals ) {\n\t\t\t\tglobalEventContext.trigger( \"ajaxSend\", [ jqXHR, s ] );\n\t\t\t}\n\t\t\t// Timeout\n\t\t\tif ( s.async && s.timeout > 0 ) {\n\t\t\t\ttimeoutTimer = setTimeout(function() {\n\t\t\t\t\tjqXHR.abort(\"timeout\");\n\t\t\t\t}, s.timeout );\n\t\t\t}\n\n\t\t\ttry {\n\t\t\t\tstate = 1;\n\t\t\t\ttransport.send( requestHeaders, done );\n\t\t\t} catch ( e ) {\n\t\t\t\t// Propagate exception as error if not done\n\t\t\t\tif ( state < 2 ) {\n\t\t\t\t\tdone( -1, e );\n\t\t\t\t// Simply rethrow otherwise\n\t\t\t\t} else {\n\t\t\t\t\tthrow e;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Callback for when everything is done\n\t\tfunction done( status, nativeStatusText, responses, headers ) {\n\t\t\tvar isSuccess, success, error, response, modified,\n\t\t\t\tstatusText = nativeStatusText;\n\n\t\t\t// Called once\n\t\t\tif ( state === 2 ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// State is \"done\" now\n\t\t\tstate = 2;\n\n\t\t\t// Clear timeout if it exists\n\t\t\tif ( timeoutTimer ) {\n\t\t\t\tclearTimeout( timeoutTimer );\n\t\t\t}\n\n\t\t\t// Dereference transport for early garbage collection\n\t\t\t// (no matter how long the jqXHR object will be used)\n\t\t\ttransport = undefined;\n\n\t\t\t// Cache response headers\n\t\t\tresponseHeadersString = headers || \"\";\n\n\t\t\t// Set readyState\n\t\t\tjqXHR.readyState = status > 0 ? 4 : 0;\n\n\t\t\t// Determine if successful\n\t\t\tisSuccess = status >= 200 && status < 300 || status === 304;\n\n\t\t\t// Get response data\n\t\t\tif ( responses ) {\n\t\t\t\tresponse = ajaxHandleResponses( s, jqXHR, responses );\n\t\t\t}\n\n\t\t\t// Convert no matter what (that way responseXXX fields are always set)\n\t\t\tresponse = ajaxConvert( s, response, jqXHR, isSuccess );\n\n\t\t\t// If successful, handle type chaining\n\t\t\tif ( isSuccess ) {\n\n\t\t\t\t// Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.\n\t\t\t\tif ( s.ifModified ) {\n\t\t\t\t\tmodified = jqXHR.getResponseHeader(\"Last-Modified\");\n\t\t\t\t\tif ( modified ) {\n\t\t\t\t\t\tjQuery.lastModified[ cacheURL ] = modified;\n\t\t\t\t\t}\n\t\t\t\t\tmodified = jqXHR.getResponseHeader(\"etag\");\n\t\t\t\t\tif ( modified ) {\n\t\t\t\t\t\tjQuery.etag[ cacheURL ] = modified;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// if no content\n\t\t\t\tif ( status === 204 || s.type === \"HEAD\" ) {\n\t\t\t\t\tstatusText = \"nocontent\";\n\n\t\t\t\t// if not modified\n\t\t\t\t} else if ( status === 304 ) {\n\t\t\t\t\tstatusText = \"notmodified\";\n\n\t\t\t\t// If we have data, let's convert it\n\t\t\t\t} else {\n\t\t\t\t\tstatusText = response.state;\n\t\t\t\t\tsuccess = response.data;\n\t\t\t\t\terror = response.error;\n\t\t\t\t\tisSuccess = !error;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t// We extract error from statusText\n\t\t\t\t// then normalize statusText and status for non-aborts\n\t\t\t\terror = statusText;\n\t\t\t\tif ( status || !statusText ) {\n\t\t\t\t\tstatusText = \"error\";\n\t\t\t\t\tif ( status < 0 ) {\n\t\t\t\t\t\tstatus = 0;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Set data for the fake xhr object\n\t\t\tjqXHR.status = status;\n\t\t\tjqXHR.statusText = ( nativeStatusText || statusText ) + \"\";\n\n\t\t\t// Success/Error\n\t\t\tif ( isSuccess ) {\n\t\t\t\tdeferred.resolveWith( callbackContext, [ success, statusText, jqXHR ] );\n\t\t\t} else {\n\t\t\t\tdeferred.rejectWith( callbackContext, [ jqXHR, statusText, error ] );\n\t\t\t}\n\n\t\t\t// Status-dependent callbacks\n\t\t\tjqXHR.statusCode( statusCode );\n\t\t\tstatusCode = undefined;\n\n\t\t\tif ( fireGlobals ) {\n\t\t\t\tglobalEventContext.trigger( isSuccess ? \"ajaxSuccess\" : \"ajaxError\",\n\t\t\t\t\t[ jqXHR, s, isSuccess ? success : error ] );\n\t\t\t}\n\n\t\t\t// Complete\n\t\t\tcompleteDeferred.fireWith( callbackContext, [ jqXHR, statusText ] );\n\n\t\t\tif ( fireGlobals ) {\n\t\t\t\tglobalEventContext.trigger( \"ajaxComplete\", [ jqXHR, s ] );\n\t\t\t\t// Handle the global AJAX counter\n\t\t\t\tif ( !( --jQuery.active ) ) {\n\t\t\t\t\tjQuery.event.trigger(\"ajaxStop\");\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn jqXHR;\n\t},\n\n\tgetJSON: function( url, data, callback ) {\n\t\treturn jQuery.get( url, data, callback, \"json\" );\n\t},\n\n\tgetScript: function( url, callback ) {\n\t\treturn jQuery.get( url, undefined, callback, \"script\" );\n\t}\n});\n\njQuery.each( [ \"get\", \"post\" ], function( i, method ) {\n\tjQuery[ method ] = function( url, data, callback, type ) {\n\t\t// shift arguments if data argument was omitted\n\t\tif ( jQuery.isFunction( data ) ) {\n\t\t\ttype = type || callback;\n\t\t\tcallback = data;\n\t\t\tdata = undefined;\n\t\t}\n\n\t\treturn jQuery.ajax({\n\t\t\turl: url,\n\t\t\ttype: method,\n\t\t\tdataType: type,\n\t\t\tdata: data,\n\t\t\tsuccess: callback\n\t\t});\n\t};\n});\n\n\njQuery._evalUrl = function( url ) {\n\treturn jQuery.ajax({\n\t\turl: url,\n\t\ttype: \"GET\",\n\t\tdataType: \"script\",\n\t\tasync: false,\n\t\tglobal: false,\n\t\t\"throws\": true\n\t});\n};\n\n\njQuery.fn.extend({\n\twrapAll: function( html ) {\n\t\tif ( jQuery.isFunction( html ) ) {\n\t\t\treturn this.each(function(i) {\n\t\t\t\tjQuery(this).wrapAll( html.call(this, i) );\n\t\t\t});\n\t\t}\n\n\t\tif ( this[0] ) {\n\t\t\t// The elements to wrap the target around\n\t\t\tvar wrap = jQuery( html, this[0].ownerDocument ).eq(0).clone(true);\n\n\t\t\tif ( this[0].parentNode ) {\n\t\t\t\twrap.insertBefore( this[0] );\n\t\t\t}\n\n\t\t\twrap.map(function() {\n\t\t\t\tvar elem = this;\n\n\t\t\t\twhile ( elem.firstChild && elem.firstChild.nodeType === 1 ) {\n\t\t\t\t\telem = elem.firstChild;\n\t\t\t\t}\n\n\t\t\t\treturn elem;\n\t\t\t}).append( this );\n\t\t}\n\n\t\treturn this;\n\t},\n\n\twrapInner: function( html ) {\n\t\tif ( jQuery.isFunction( html ) ) {\n\t\t\treturn this.each(function(i) {\n\t\t\t\tjQuery(this).wrapInner( html.call(this, i) );\n\t\t\t});\n\t\t}\n\n\t\treturn this.each(function() {\n\t\t\tvar self = jQuery( this ),\n\t\t\t\tcontents = self.contents();\n\n\t\t\tif ( contents.length ) {\n\t\t\t\tcontents.wrapAll( html );\n\n\t\t\t} else {\n\t\t\t\tself.append( html );\n\t\t\t}\n\t\t});\n\t},\n\n\twrap: function( html ) {\n\t\tvar isFunction = jQuery.isFunction( html );\n\n\t\treturn this.each(function(i) {\n\t\t\tjQuery( this ).wrapAll( isFunction ? html.call(this, i) : html );\n\t\t});\n\t},\n\n\tunwrap: function() {\n\t\treturn this.parent().each(function() {\n\t\t\tif ( !jQuery.nodeName( this, \"body\" ) ) {\n\t\t\t\tjQuery( this ).replaceWith( this.childNodes );\n\t\t\t}\n\t\t}).end();\n\t}\n});\n\n\njQuery.expr.filters.hidden = function( elem ) {\n\t// Support: Opera <= 12.12\n\t// Opera reports offsetWidths and offsetHeights less than zero on some elements\n\treturn elem.offsetWidth <= 0 && elem.offsetHeight <= 0 ||\n\t\t(!support.reliableHiddenOffsets() &&\n\t\t\t((elem.style && elem.style.display) || jQuery.css( elem, \"display\" )) === \"none\");\n};\n\njQuery.expr.filters.visible = function( elem ) {\n\treturn !jQuery.expr.filters.hidden( elem );\n};\n\n\n\n\nvar r20 = /%20/g,\n\trbracket = /\\[\\]$/,\n\trCRLF = /\\r?\\n/g,\n\trsubmitterTypes = /^(?:submit|button|image|reset|file)$/i,\n\trsubmittable = /^(?:input|select|textarea|keygen)/i;\n\nfunction buildParams( prefix, obj, traditional, add ) {\n\tvar name;\n\n\tif ( jQuery.isArray( obj ) ) {\n\t\t// Serialize array item.\n\t\tjQuery.each( obj, function( i, v ) {\n\t\t\tif ( traditional || rbracket.test( prefix ) ) {\n\t\t\t\t// Treat each array item as a scalar.\n\t\t\t\tadd( prefix, v );\n\n\t\t\t} else {\n\t\t\t\t// Item is non-scalar (array or object), encode its numeric index.\n\t\t\t\tbuildParams( prefix + \"[\" + ( typeof v === \"object\" ? i : \"\" ) + \"]\", v, traditional, add );\n\t\t\t}\n\t\t});\n\n\t} else if ( !traditional && jQuery.type( obj ) === \"object\" ) {\n\t\t// Serialize object item.\n\t\tfor ( name in obj ) {\n\t\t\tbuildParams( prefix + \"[\" + name + \"]\", obj[ name ], traditional, add );\n\t\t}\n\n\t} else {\n\t\t// Serialize scalar item.\n\t\tadd( prefix, obj );\n\t}\n}\n\n// Serialize an array of form elements or a set of\n// key/values into a query string\njQuery.param = function( a, traditional ) {\n\tvar prefix,\n\t\ts = [],\n\t\tadd = function( key, value ) {\n\t\t\t// If value is a function, invoke it and return its value\n\t\t\tvalue = jQuery.isFunction( value ) ? value() : ( value == null ? \"\" : value );\n\t\t\ts[ s.length ] = encodeURIComponent( key ) + \"=\" + encodeURIComponent( value );\n\t\t};\n\n\t// Set traditional to true for jQuery <= 1.3.2 behavior.\n\tif ( traditional === undefined ) {\n\t\ttraditional = jQuery.ajaxSettings && jQuery.ajaxSettings.traditional;\n\t}\n\n\t// If an array was passed in, assume that it is an array of form elements.\n\tif ( jQuery.isArray( a ) || ( a.jquery && !jQuery.isPlainObject( a ) ) ) {\n\t\t// Serialize the form elements\n\t\tjQuery.each( a, function() {\n\t\t\tadd( this.name, this.value );\n\t\t});\n\n\t} else {\n\t\t// If traditional, encode the \"old\" way (the way 1.3.2 or older\n\t\t// did it), otherwise encode params recursively.\n\t\tfor ( prefix in a ) {\n\t\t\tbuildParams( prefix, a[ prefix ], traditional, add );\n\t\t}\n\t}\n\n\t// Return the resulting serialization\n\treturn s.join( \"&\" ).replace( r20, \"+\" );\n};\n\njQuery.fn.extend({\n\tserialize: function() {\n\t\treturn jQuery.param( this.serializeArray() );\n\t},\n\tserializeArray: function() {\n\t\treturn this.map(function() {\n\t\t\t// Can add propHook for \"elements\" to filter or add form elements\n\t\t\tvar elements = jQuery.prop( this, \"elements\" );\n\t\t\treturn elements ? jQuery.makeArray( elements ) : this;\n\t\t})\n\t\t.filter(function() {\n\t\t\tvar type = this.type;\n\t\t\t// Use .is(\":disabled\") so that fieldset[disabled] works\n\t\t\treturn this.name && !jQuery( this ).is( \":disabled\" ) &&\n\t\t\t\trsubmittable.test( this.nodeName ) && !rsubmitterTypes.test( type ) &&\n\t\t\t\t( this.checked || !rcheckableType.test( type ) );\n\t\t})\n\t\t.map(function( i, elem ) {\n\t\t\tvar val = jQuery( this ).val();\n\n\t\t\treturn val == null ?\n\t\t\t\tnull :\n\t\t\t\tjQuery.isArray( val ) ?\n\t\t\t\t\tjQuery.map( val, function( val ) {\n\t\t\t\t\t\treturn { name: elem.name, value: val.replace( rCRLF, \"\\r\\n\" ) };\n\t\t\t\t\t}) :\n\t\t\t\t\t{ name: elem.name, value: val.replace( rCRLF, \"\\r\\n\" ) };\n\t\t}).get();\n\t}\n});\n\n\n// Create the request object\n// (This is still attached to ajaxSettings for backward compatibility)\njQuery.ajaxSettings.xhr = window.ActiveXObject !== undefined ?\n\t// Support: IE6+\n\tfunction() {\n\n\t\t// XHR cannot access local files, always use ActiveX for that case\n\t\treturn !this.isLocal &&\n\n\t\t\t// Support: IE7-8\n\t\t\t// oldIE XHR does not support non-RFC2616 methods (#13240)\n\t\t\t// See http://msdn.microsoft.com/en-us/library/ie/ms536648(v=vs.85).aspx\n\t\t\t// and http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html#sec9\n\t\t\t// Although this check for six methods instead of eight\n\t\t\t// since IE also does not support \"trace\" and \"connect\"\n\t\t\t/^(get|post|head|put|delete|options)$/i.test( this.type ) &&\n\n\t\t\tcreateStandardXHR() || createActiveXHR();\n\t} :\n\t// For all other browsers, use the standard XMLHttpRequest object\n\tcreateStandardXHR;\n\nvar xhrId = 0,\n\txhrCallbacks = {},\n\txhrSupported = jQuery.ajaxSettings.xhr();\n\n// Support: IE<10\n// Open requests must be manually aborted on unload (#5280)\n// See https://support.microsoft.com/kb/2856746 for more info\nif ( window.attachEvent ) {\n\twindow.attachEvent( \"onunload\", function() {\n\t\tfor ( var key in xhrCallbacks ) {\n\t\t\txhrCallbacks[ key ]( undefined, true );\n\t\t}\n\t});\n}\n\n// Determine support properties\nsupport.cors = !!xhrSupported && ( \"withCredentials\" in xhrSupported );\nxhrSupported = support.ajax = !!xhrSupported;\n\n// Create transport if the browser can provide an xhr\nif ( xhrSupported ) {\n\n\tjQuery.ajaxTransport(function( options ) {\n\t\t// Cross domain only allowed if supported through XMLHttpRequest\n\t\tif ( !options.crossDomain || support.cors ) {\n\n\t\t\tvar callback;\n\n\t\t\treturn {\n\t\t\t\tsend: function( headers, complete ) {\n\t\t\t\t\tvar i,\n\t\t\t\t\t\txhr = options.xhr(),\n\t\t\t\t\t\tid = ++xhrId;\n\n\t\t\t\t\t// Open the socket\n\t\t\t\t\txhr.open( options.type, options.url, options.async, options.username, options.password );\n\n\t\t\t\t\t// Apply custom fields if provided\n\t\t\t\t\tif ( options.xhrFields ) {\n\t\t\t\t\t\tfor ( i in options.xhrFields ) {\n\t\t\t\t\t\t\txhr[ i ] = options.xhrFields[ i ];\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\t// Override mime type if needed\n\t\t\t\t\tif ( options.mimeType && xhr.overrideMimeType ) {\n\t\t\t\t\t\txhr.overrideMimeType( options.mimeType );\n\t\t\t\t\t}\n\n\t\t\t\t\t// X-Requested-With header\n\t\t\t\t\t// For cross-domain requests, seeing as conditions for a preflight are\n\t\t\t\t\t// akin to a jigsaw puzzle, we simply never set it to be sure.\n\t\t\t\t\t// (it can always be set on a per-request basis or even using ajaxSetup)\n\t\t\t\t\t// For same-domain requests, won't change header if already provided.\n\t\t\t\t\tif ( !options.crossDomain && !headers[\"X-Requested-With\"] ) {\n\t\t\t\t\t\theaders[\"X-Requested-With\"] = \"XMLHttpRequest\";\n\t\t\t\t\t}\n\n\t\t\t\t\t// Set headers\n\t\t\t\t\tfor ( i in headers ) {\n\t\t\t\t\t\t// Support: IE<9\n\t\t\t\t\t\t// IE's ActiveXObject throws a 'Type Mismatch' exception when setting\n\t\t\t\t\t\t// request header to a null-value.\n\t\t\t\t\t\t//\n\t\t\t\t\t\t// To keep consistent with other XHR implementations, cast the value\n\t\t\t\t\t\t// to string and ignore `undefined`.\n\t\t\t\t\t\tif ( headers[ i ] !== undefined ) {\n\t\t\t\t\t\t\txhr.setRequestHeader( i, headers[ i ] + \"\" );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\t// Do send the request\n\t\t\t\t\t// This may raise an exception which is actually\n\t\t\t\t\t// handled in jQuery.ajax (so no try/catch here)\n\t\t\t\t\txhr.send( ( options.hasContent && options.data ) || null );\n\n\t\t\t\t\t// Listener\n\t\t\t\t\tcallback = function( _, isAbort ) {\n\t\t\t\t\t\tvar status, statusText, responses;\n\n\t\t\t\t\t\t// Was never called and is aborted or complete\n\t\t\t\t\t\tif ( callback && ( isAbort || xhr.readyState === 4 ) ) {\n\t\t\t\t\t\t\t// Clean up\n\t\t\t\t\t\t\tdelete xhrCallbacks[ id ];\n\t\t\t\t\t\t\tcallback = undefined;\n\t\t\t\t\t\t\txhr.onreadystatechange = jQuery.noop;\n\n\t\t\t\t\t\t\t// Abort manually if needed\n\t\t\t\t\t\t\tif ( isAbort ) {\n\t\t\t\t\t\t\t\tif ( xhr.readyState !== 4 ) {\n\t\t\t\t\t\t\t\t\txhr.abort();\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tresponses = {};\n\t\t\t\t\t\t\t\tstatus = xhr.status;\n\n\t\t\t\t\t\t\t\t// Support: IE<10\n\t\t\t\t\t\t\t\t// Accessing binary-data responseText throws an exception\n\t\t\t\t\t\t\t\t// (#11426)\n\t\t\t\t\t\t\t\tif ( typeof xhr.responseText === \"string\" ) {\n\t\t\t\t\t\t\t\t\tresponses.text = xhr.responseText;\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t// Firefox throws an exception when accessing\n\t\t\t\t\t\t\t\t// statusText for faulty cross-domain requests\n\t\t\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t\t\tstatusText = xhr.statusText;\n\t\t\t\t\t\t\t\t} catch( e ) {\n\t\t\t\t\t\t\t\t\t// We normalize with Webkit giving an empty statusText\n\t\t\t\t\t\t\t\t\tstatusText = \"\";\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t// Filter status for non standard behaviors\n\n\t\t\t\t\t\t\t\t// If the request is local and we have data: assume a success\n\t\t\t\t\t\t\t\t// (success with no data won't get notified, that's the best we\n\t\t\t\t\t\t\t\t// can do given current implementations)\n\t\t\t\t\t\t\t\tif ( !status && options.isLocal && !options.crossDomain ) {\n\t\t\t\t\t\t\t\t\tstatus = responses.text ? 200 : 404;\n\t\t\t\t\t\t\t\t// IE - #1450: sometimes returns 1223 when it should be 204\n\t\t\t\t\t\t\t\t} else if ( status === 1223 ) {\n\t\t\t\t\t\t\t\t\tstatus = 204;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// Call complete if needed\n\t\t\t\t\t\tif ( responses ) {\n\t\t\t\t\t\t\tcomplete( status, statusText, responses, xhr.getAllResponseHeaders() );\n\t\t\t\t\t\t}\n\t\t\t\t\t};\n\n\t\t\t\t\tif ( !options.async ) {\n\t\t\t\t\t\t// if we're in sync mode we fire the callback\n\t\t\t\t\t\tcallback();\n\t\t\t\t\t} else if ( xhr.readyState === 4 ) {\n\t\t\t\t\t\t// (IE6 & IE7) if it's in cache and has been\n\t\t\t\t\t\t// retrieved directly we need to fire the callback\n\t\t\t\t\t\tsetTimeout( callback );\n\t\t\t\t\t} else {\n\t\t\t\t\t\t// Add to the list of active xhr callbacks\n\t\t\t\t\t\txhr.onreadystatechange = xhrCallbacks[ id ] = callback;\n\t\t\t\t\t}\n\t\t\t\t},\n\n\t\t\t\tabort: function() {\n\t\t\t\t\tif ( callback ) {\n\t\t\t\t\t\tcallback( undefined, true );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t};\n\t\t}\n\t});\n}\n\n// Functions to create xhrs\nfunction createStandardXHR() {\n\ttry {\n\t\treturn new window.XMLHttpRequest();\n\t} catch( e ) {}\n}\n\nfunction createActiveXHR() {\n\ttry {\n\t\treturn new window.ActiveXObject( \"Microsoft.XMLHTTP\" );\n\t} catch( e ) {}\n}\n\n\n\n\n// Install script dataType\njQuery.ajaxSetup({\n\taccepts: {\n\t\tscript: \"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript\"\n\t},\n\tcontents: {\n\t\tscript: /(?:java|ecma)script/\n\t},\n\tconverters: {\n\t\t\"text script\": function( text ) {\n\t\t\tjQuery.globalEval( text );\n\t\t\treturn text;\n\t\t}\n\t}\n});\n\n// Handle cache's special case and global\njQuery.ajaxPrefilter( \"script\", function( s ) {\n\tif ( s.cache === undefined ) {\n\t\ts.cache = false;\n\t}\n\tif ( s.crossDomain ) {\n\t\ts.type = \"GET\";\n\t\ts.global = false;\n\t}\n});\n\n// Bind script tag hack transport\njQuery.ajaxTransport( \"script\", function(s) {\n\n\t// This transport only deals with cross domain requests\n\tif ( s.crossDomain ) {\n\n\t\tvar script,\n\t\t\thead = document.head || jQuery(\"head\")[0] || document.documentElement;\n\n\t\treturn {\n\n\t\t\tsend: function( _, callback ) {\n\n\t\t\t\tscript = document.createElement(\"script\");\n\n\t\t\t\tscript.async = true;\n\n\t\t\t\tif ( s.scriptCharset ) {\n\t\t\t\t\tscript.charset = s.scriptCharset;\n\t\t\t\t}\n\n\t\t\t\tscript.src = s.url;\n\n\t\t\t\t// Attach handlers for all browsers\n\t\t\t\tscript.onload = script.onreadystatechange = function( _, isAbort ) {\n\n\t\t\t\t\tif ( isAbort || !script.readyState || /loaded|complete/.test( script.readyState ) ) {\n\n\t\t\t\t\t\t// Handle memory leak in IE\n\t\t\t\t\t\tscript.onload = script.onreadystatechange = null;\n\n\t\t\t\t\t\t// Remove the script\n\t\t\t\t\t\tif ( script.parentNode ) {\n\t\t\t\t\t\t\tscript.parentNode.removeChild( script );\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// Dereference the script\n\t\t\t\t\t\tscript = null;\n\n\t\t\t\t\t\t// Callback if not abort\n\t\t\t\t\t\tif ( !isAbort ) {\n\t\t\t\t\t\t\tcallback( 200, \"success\" );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t};\n\n\t\t\t\t// Circumvent IE6 bugs with base elements (#2709 and #4378) by prepending\n\t\t\t\t// Use native DOM manipulation to avoid our domManip AJAX trickery\n\t\t\t\thead.insertBefore( script, head.firstChild );\n\t\t\t},\n\n\t\t\tabort: function() {\n\t\t\t\tif ( script ) {\n\t\t\t\t\tscript.onload( undefined, true );\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\t}\n});\n\n\n\n\nvar oldCallbacks = [],\n\trjsonp = /(=)\\?(?=&|$)|\\?\\?/;\n\n// Default jsonp settings\njQuery.ajaxSetup({\n\tjsonp: \"callback\",\n\tjsonpCallback: function() {\n\t\tvar callback = oldCallbacks.pop() || ( jQuery.expando + \"_\" + ( nonce++ ) );\n\t\tthis[ callback ] = true;\n\t\treturn callback;\n\t}\n});\n\n// Detect, normalize options and install callbacks for jsonp requests\njQuery.ajaxPrefilter( \"json jsonp\", function( s, originalSettings, jqXHR ) {\n\n\tvar callbackName, overwritten, responseContainer,\n\t\tjsonProp = s.jsonp !== false && ( rjsonp.test( s.url ) ?\n\t\t\t\"url\" :\n\t\t\ttypeof s.data === \"string\" && !( s.contentType || \"\" ).indexOf(\"application/x-www-form-urlencoded\") && rjsonp.test( s.data ) && \"data\"\n\t\t);\n\n\t// Handle iff the expected data type is \"jsonp\" or we have a parameter to set\n\tif ( jsonProp || s.dataTypes[ 0 ] === \"jsonp\" ) {\n\n\t\t// Get callback name, remembering preexisting value associated with it\n\t\tcallbackName = s.jsonpCallback = jQuery.isFunction( s.jsonpCallback ) ?\n\t\t\ts.jsonpCallback() :\n\t\t\ts.jsonpCallback;\n\n\t\t// Insert callback into url or form data\n\t\tif ( jsonProp ) {\n\t\t\ts[ jsonProp ] = s[ jsonProp ].replace( rjsonp, \"$1\" + callbackName );\n\t\t} else if ( s.jsonp !== false ) {\n\t\t\ts.url += ( rquery.test( s.url ) ? \"&\" : \"?\" ) + s.jsonp + \"=\" + callbackName;\n\t\t}\n\n\t\t// Use data converter to retrieve json after script execution\n\t\ts.converters[\"script json\"] = function() {\n\t\t\tif ( !responseContainer ) {\n\t\t\t\tjQuery.error( callbackName + \" was not called\" );\n\t\t\t}\n\t\t\treturn responseContainer[ 0 ];\n\t\t};\n\n\t\t// force json dataType\n\t\ts.dataTypes[ 0 ] = \"json\";\n\n\t\t// Install callback\n\t\toverwritten = window[ callbackName ];\n\t\twindow[ callbackName ] = function() {\n\t\t\tresponseContainer = arguments;\n\t\t};\n\n\t\t// Clean-up function (fires after converters)\n\t\tjqXHR.always(function() {\n\t\t\t// Restore preexisting value\n\t\t\twindow[ callbackName ] = overwritten;\n\n\t\t\t// Save back as free\n\t\t\tif ( s[ callbackName ] ) {\n\t\t\t\t// make sure that re-using the options doesn't screw things around\n\t\t\t\ts.jsonpCallback = originalSettings.jsonpCallback;\n\n\t\t\t\t// save the callback name for future use\n\t\t\t\toldCallbacks.push( callbackName );\n\t\t\t}\n\n\t\t\t// Call if it was a function and we have a response\n\t\t\tif ( responseContainer && jQuery.isFunction( overwritten ) ) {\n\t\t\t\toverwritten( responseContainer[ 0 ] );\n\t\t\t}\n\n\t\t\tresponseContainer = overwritten = undefined;\n\t\t});\n\n\t\t// Delegate to script\n\t\treturn \"script\";\n\t}\n});\n\n\n\n\n// data: string of html\n// context (optional): If specified, the fragment will be created in this context, defaults to document\n// keepScripts (optional): If true, will include scripts passed in the html string\njQuery.parseHTML = function( data, context, keepScripts ) {\n\tif ( !data || typeof data !== \"string\" ) {\n\t\treturn null;\n\t}\n\tif ( typeof context === \"boolean\" ) {\n\t\tkeepScripts = context;\n\t\tcontext = false;\n\t}\n\tcontext = context || document;\n\n\tvar parsed = rsingleTag.exec( data ),\n\t\tscripts = !keepScripts && [];\n\n\t// Single tag\n\tif ( parsed ) {\n\t\treturn [ context.createElement( parsed[1] ) ];\n\t}\n\n\tparsed = jQuery.buildFragment( [ data ], context, scripts );\n\n\tif ( scripts && scripts.length ) {\n\t\tjQuery( scripts ).remove();\n\t}\n\n\treturn jQuery.merge( [], parsed.childNodes );\n};\n\n\n// Keep a copy of the old load method\nvar _load = jQuery.fn.load;\n\n/**\n * Load a url into a page\n */\njQuery.fn.load = function( url, params, callback ) {\n\tif ( typeof url !== \"string\" && _load ) {\n\t\treturn _load.apply( this, arguments );\n\t}\n\n\tvar selector, response, type,\n\t\tself = this,\n\t\toff = url.indexOf(\" \");\n\n\tif ( off >= 0 ) {\n\t\tselector = jQuery.trim( url.slice( off, url.length ) );\n\t\turl = url.slice( 0, off );\n\t}\n\n\t// If it's a function\n\tif ( jQuery.isFunction( params ) ) {\n\n\t\t// We assume that it's the callback\n\t\tcallback = params;\n\t\tparams = undefined;\n\n\t// Otherwise, build a param string\n\t} else if ( params && typeof params === \"object\" ) {\n\t\ttype = \"POST\";\n\t}\n\n\t// If we have elements to modify, make the request\n\tif ( self.length > 0 ) {\n\t\tjQuery.ajax({\n\t\t\turl: url,\n\n\t\t\t// if \"type\" variable is undefined, then \"GET\" method will be used\n\t\t\ttype: type,\n\t\t\tdataType: \"html\",\n\t\t\tdata: params\n\t\t}).done(function( responseText ) {\n\n\t\t\t// Save response for use in complete callback\n\t\t\tresponse = arguments;\n\n\t\t\tself.html( selector ?\n\n\t\t\t\t// If a selector was specified, locate the right elements in a dummy div\n\t\t\t\t// Exclude scripts to avoid IE 'Permission Denied' errors\n\t\t\t\tjQuery(\"<div>\").append( jQuery.parseHTML( responseText ) ).find( selector ) :\n\n\t\t\t\t// Otherwise use the full result\n\t\t\t\tresponseText );\n\n\t\t}).complete( callback && function( jqXHR, status ) {\n\t\t\tself.each( callback, response || [ jqXHR.responseText, status, jqXHR ] );\n\t\t});\n\t}\n\n\treturn this;\n};\n\n\n\n\n// Attach a bunch of functions for handling common AJAX events\njQuery.each( [ \"ajaxStart\", \"ajaxStop\", \"ajaxComplete\", \"ajaxError\", \"ajaxSuccess\", \"ajaxSend\" ], function( i, type ) {\n\tjQuery.fn[ type ] = function( fn ) {\n\t\treturn this.on( type, fn );\n\t};\n});\n\n\n\n\njQuery.expr.filters.animated = function( elem ) {\n\treturn jQuery.grep(jQuery.timers, function( fn ) {\n\t\treturn elem === fn.elem;\n\t}).length;\n};\n\n\n\n\n\nvar docElem = window.document.documentElement;\n\n/**\n * Gets a window from an element\n */\nfunction getWindow( elem ) {\n\treturn jQuery.isWindow( elem ) ?\n\t\telem :\n\t\telem.nodeType === 9 ?\n\t\t\telem.defaultView || elem.parentWindow :\n\t\t\tfalse;\n}\n\njQuery.offset = {\n\tsetOffset: function( elem, options, i ) {\n\t\tvar curPosition, curLeft, curCSSTop, curTop, curOffset, curCSSLeft, calculatePosition,\n\t\t\tposition = jQuery.css( elem, \"position\" ),\n\t\t\tcurElem = jQuery( elem ),\n\t\t\tprops = {};\n\n\t\t// set position first, in-case top/left are set even on static elem\n\t\tif ( position === \"static\" ) {\n\t\t\telem.style.position = \"relative\";\n\t\t}\n\n\t\tcurOffset = curElem.offset();\n\t\tcurCSSTop = jQuery.css( elem, \"top\" );\n\t\tcurCSSLeft = jQuery.css( elem, \"left\" );\n\t\tcalculatePosition = ( position === \"absolute\" || position === \"fixed\" ) &&\n\t\t\tjQuery.inArray(\"auto\", [ curCSSTop, curCSSLeft ] ) > -1;\n\n\t\t// need to be able to calculate position if either top or left is auto and position is either absolute or fixed\n\t\tif ( calculatePosition ) {\n\t\t\tcurPosition = curElem.position();\n\t\t\tcurTop = curPosition.top;\n\t\t\tcurLeft = curPosition.left;\n\t\t} else {\n\t\t\tcurTop = parseFloat( curCSSTop ) || 0;\n\t\t\tcurLeft = parseFloat( curCSSLeft ) || 0;\n\t\t}\n\n\t\tif ( jQuery.isFunction( options ) ) {\n\t\t\toptions = options.call( elem, i, curOffset );\n\t\t}\n\n\t\tif ( options.top != null ) {\n\t\t\tprops.top = ( options.top - curOffset.top ) + curTop;\n\t\t}\n\t\tif ( options.left != null ) {\n\t\t\tprops.left = ( options.left - curOffset.left ) + curLeft;\n\t\t}\n\n\t\tif ( \"using\" in options ) {\n\t\t\toptions.using.call( elem, props );\n\t\t} else {\n\t\t\tcurElem.css( props );\n\t\t}\n\t}\n};\n\njQuery.fn.extend({\n\toffset: function( options ) {\n\t\tif ( arguments.length ) {\n\t\t\treturn options === undefined ?\n\t\t\t\tthis :\n\t\t\t\tthis.each(function( i ) {\n\t\t\t\t\tjQuery.offset.setOffset( this, options, i );\n\t\t\t\t});\n\t\t}\n\n\t\tvar docElem, win,\n\t\t\tbox = { top: 0, left: 0 },\n\t\t\telem = this[ 0 ],\n\t\t\tdoc = elem && elem.ownerDocument;\n\n\t\tif ( !doc ) {\n\t\t\treturn;\n\t\t}\n\n\t\tdocElem = doc.documentElement;\n\n\t\t// Make sure it's not a disconnected DOM node\n\t\tif ( !jQuery.contains( docElem, elem ) ) {\n\t\t\treturn box;\n\t\t}\n\n\t\t// If we don't have gBCR, just use 0,0 rather than error\n\t\t// BlackBerry 5, iOS 3 (original iPhone)\n\t\tif ( typeof elem.getBoundingClientRect !== strundefined ) {\n\t\t\tbox = elem.getBoundingClientRect();\n\t\t}\n\t\twin = getWindow( doc );\n\t\treturn {\n\t\t\ttop: box.top  + ( win.pageYOffset || docElem.scrollTop )  - ( docElem.clientTop  || 0 ),\n\t\t\tleft: box.left + ( win.pageXOffset || docElem.scrollLeft ) - ( docElem.clientLeft || 0 )\n\t\t};\n\t},\n\n\tposition: function() {\n\t\tif ( !this[ 0 ] ) {\n\t\t\treturn;\n\t\t}\n\n\t\tvar offsetParent, offset,\n\t\t\tparentOffset = { top: 0, left: 0 },\n\t\t\telem = this[ 0 ];\n\n\t\t// fixed elements are offset from window (parentOffset = {top:0, left: 0}, because it is its only offset parent\n\t\tif ( jQuery.css( elem, \"position\" ) === \"fixed\" ) {\n\t\t\t// we assume that getBoundingClientRect is available when computed position is fixed\n\t\t\toffset = elem.getBoundingClientRect();\n\t\t} else {\n\t\t\t// Get *real* offsetParent\n\t\t\toffsetParent = this.offsetParent();\n\n\t\t\t// Get correct offsets\n\t\t\toffset = this.offset();\n\t\t\tif ( !jQuery.nodeName( offsetParent[ 0 ], \"html\" ) ) {\n\t\t\t\tparentOffset = offsetParent.offset();\n\t\t\t}\n\n\t\t\t// Add offsetParent borders\n\t\t\tparentOffset.top  += jQuery.css( offsetParent[ 0 ], \"borderTopWidth\", true );\n\t\t\tparentOffset.left += jQuery.css( offsetParent[ 0 ], \"borderLeftWidth\", true );\n\t\t}\n\n\t\t// Subtract parent offsets and element margins\n\t\t// note: when an element has margin: auto the offsetLeft and marginLeft\n\t\t// are the same in Safari causing offset.left to incorrectly be 0\n\t\treturn {\n\t\t\ttop:  offset.top  - parentOffset.top - jQuery.css( elem, \"marginTop\", true ),\n\t\t\tleft: offset.left - parentOffset.left - jQuery.css( elem, \"marginLeft\", true)\n\t\t};\n\t},\n\n\toffsetParent: function() {\n\t\treturn this.map(function() {\n\t\t\tvar offsetParent = this.offsetParent || docElem;\n\n\t\t\twhile ( offsetParent && ( !jQuery.nodeName( offsetParent, \"html\" ) && jQuery.css( offsetParent, \"position\" ) === \"static\" ) ) {\n\t\t\t\toffsetParent = offsetParent.offsetParent;\n\t\t\t}\n\t\t\treturn offsetParent || docElem;\n\t\t});\n\t}\n});\n\n// Create scrollLeft and scrollTop methods\njQuery.each( { scrollLeft: \"pageXOffset\", scrollTop: \"pageYOffset\" }, function( method, prop ) {\n\tvar top = /Y/.test( prop );\n\n\tjQuery.fn[ method ] = function( val ) {\n\t\treturn access( this, function( elem, method, val ) {\n\t\t\tvar win = getWindow( elem );\n\n\t\t\tif ( val === undefined ) {\n\t\t\t\treturn win ? (prop in win) ? win[ prop ] :\n\t\t\t\t\twin.document.documentElement[ method ] :\n\t\t\t\t\telem[ method ];\n\t\t\t}\n\n\t\t\tif ( win ) {\n\t\t\t\twin.scrollTo(\n\t\t\t\t\t!top ? val : jQuery( win ).scrollLeft(),\n\t\t\t\t\ttop ? val : jQuery( win ).scrollTop()\n\t\t\t\t);\n\n\t\t\t} else {\n\t\t\t\telem[ method ] = val;\n\t\t\t}\n\t\t}, method, val, arguments.length, null );\n\t};\n});\n\n// Add the top/left cssHooks using jQuery.fn.position\n// Webkit bug: https://bugs.webkit.org/show_bug.cgi?id=29084\n// getComputedStyle returns percent when specified for top/left/bottom/right\n// rather than make the css module depend on the offset module, we just check for it here\njQuery.each( [ \"top\", \"left\" ], function( i, prop ) {\n\tjQuery.cssHooks[ prop ] = addGetHookIf( support.pixelPosition,\n\t\tfunction( elem, computed ) {\n\t\t\tif ( computed ) {\n\t\t\t\tcomputed = curCSS( elem, prop );\n\t\t\t\t// if curCSS returns percentage, fallback to offset\n\t\t\t\treturn rnumnonpx.test( computed ) ?\n\t\t\t\t\tjQuery( elem ).position()[ prop ] + \"px\" :\n\t\t\t\t\tcomputed;\n\t\t\t}\n\t\t}\n\t);\n});\n\n\n// Create innerHeight, innerWidth, height, width, outerHeight and outerWidth methods\njQuery.each( { Height: \"height\", Width: \"width\" }, function( name, type ) {\n\tjQuery.each( { padding: \"inner\" + name, content: type, \"\": \"outer\" + name }, function( defaultExtra, funcName ) {\n\t\t// margin is only for outerHeight, outerWidth\n\t\tjQuery.fn[ funcName ] = function( margin, value ) {\n\t\t\tvar chainable = arguments.length && ( defaultExtra || typeof margin !== \"boolean\" ),\n\t\t\t\textra = defaultExtra || ( margin === true || value === true ? \"margin\" : \"border\" );\n\n\t\t\treturn access( this, function( elem, type, value ) {\n\t\t\t\tvar doc;\n\n\t\t\t\tif ( jQuery.isWindow( elem ) ) {\n\t\t\t\t\t// As of 5/8/2012 this will yield incorrect results for Mobile Safari, but there\n\t\t\t\t\t// isn't a whole lot we can do. See pull request at this URL for discussion:\n\t\t\t\t\t// https://github.com/jquery/jquery/pull/764\n\t\t\t\t\treturn elem.document.documentElement[ \"client\" + name ];\n\t\t\t\t}\n\n\t\t\t\t// Get document width or height\n\t\t\t\tif ( elem.nodeType === 9 ) {\n\t\t\t\t\tdoc = elem.documentElement;\n\n\t\t\t\t\t// Either scroll[Width/Height] or offset[Width/Height] or client[Width/Height], whichever is greatest\n\t\t\t\t\t// unfortunately, this causes bug #3838 in IE6/8 only, but there is currently no good, small way to fix it.\n\t\t\t\t\treturn Math.max(\n\t\t\t\t\t\telem.body[ \"scroll\" + name ], doc[ \"scroll\" + name ],\n\t\t\t\t\t\telem.body[ \"offset\" + name ], doc[ \"offset\" + name ],\n\t\t\t\t\t\tdoc[ \"client\" + name ]\n\t\t\t\t\t);\n\t\t\t\t}\n\n\t\t\t\treturn value === undefined ?\n\t\t\t\t\t// Get width or height on the element, requesting but not forcing parseFloat\n\t\t\t\t\tjQuery.css( elem, type, extra ) :\n\n\t\t\t\t\t// Set width or height on the element\n\t\t\t\t\tjQuery.style( elem, type, value, extra );\n\t\t\t}, type, chainable ? margin : undefined, chainable, null );\n\t\t};\n\t});\n});\n\n\n// The number of elements contained in the matched element set\njQuery.fn.size = function() {\n\treturn this.length;\n};\n\njQuery.fn.andSelf = jQuery.fn.addBack;\n\n\n\n\n// Register as a named AMD module, since jQuery can be concatenated with other\n// files that may use define, but not via a proper concatenation script that\n// understands anonymous AMD modules. A named AMD is safest and most robust\n// way to register. Lowercase jquery is used because AMD module names are\n// derived from file names, and jQuery is normally delivered in a lowercase\n// file name. Do this after creating the global so that if an AMD module wants\n// to call noConflict to hide this version of jQuery, it will work.\n\n// Note that for maximum portability, libraries that are not jQuery should\n// declare themselves as anonymous modules, and avoid setting a global if an\n// AMD loader is present. jQuery is a special case. For more information, see\n// https://github.com/jrburke/requirejs/wiki/Updating-existing-libraries#wiki-anon\n\nif ( typeof define === \"function\" && define.amd ) {\n\tdefine( \"jquery\", [], function() {\n\t\treturn jQuery;\n\t});\n}\n\n\n\n\nvar\n\t// Map over jQuery in case of overwrite\n\t_jQuery = window.jQuery,\n\n\t// Map over the $ in case of overwrite\n\t_$ = window.$;\n\njQuery.noConflict = function( deep ) {\n\tif ( window.$ === jQuery ) {\n\t\twindow.$ = _$;\n\t}\n\n\tif ( deep && window.jQuery === jQuery ) {\n\t\twindow.jQuery = _jQuery;\n\t}\n\n\treturn jQuery;\n};\n\n// Expose jQuery and $ identifiers, even in\n// AMD (#7102#comment:10, https://github.com/jquery/jquery/pull/557)\n// and CommonJS for browser emulators (#13566)\nif ( typeof noGlobal === strundefined ) {\n\twindow.jQuery = window.$ = jQuery;\n}\n\n\n\n\nreturn jQuery;\n\n}));\n"
  },
  {
    "path": "app_backend/static/plugin/JavaScript-Load-Image-2.12.2/package.json",
    "content": "{\n  \"name\": \"blueimp-load-image\",\n  \"version\": \"2.12.2\",\n  \"title\": \"JavaScript Load Image\",\n  \"description\": \"JavaScript Load Image is a library to load images provided as File or Blob objects or via URL. It returns an optionally scaled and/or cropped HTML img or canvas element. It also provides a method to parse image meta data to extract Exif tags and thumbnails and to restore the complete image header after resizing.\",\n  \"keywords\": [\n    \"javascript\",\n    \"load\",\n    \"loading\",\n    \"image\",\n    \"file\",\n    \"blob\",\n    \"url\",\n    \"scale\",\n    \"crop\",\n    \"img\",\n    \"canvas\",\n    \"meta\",\n    \"exif\",\n    \"thumbnail\",\n    \"resizing\"\n  ],\n  \"homepage\": \"https://github.com/blueimp/JavaScript-Load-Image\",\n  \"author\": {\n    \"name\": \"Sebastian Tschan\",\n    \"url\": \"https://blueimp.net\"\n  },\n  \"repository\": {\n    \"type\": \"git\",\n    \"url\": \"git://github.com/blueimp/JavaScript-Load-Image.git\"\n  },\n  \"license\": \"MIT\",\n  \"devDependencies\": {\n    \"phantomjs-prebuilt\": \"2.1.13\",\n    \"mocha-phantomjs-core\": \"1.3.1\",\n    \"standard\": \"8.3.0\",\n    \"uglify-js\": \"2.7.3\"\n  },\n  \"scripts\": {\n    \"lint\": \"standard *.js js/*.js test/*.js\",\n    \"unit\": \"phantomjs node_modules/mocha-phantomjs-core/mocha-phantomjs-core.js test/index.html\",\n    \"test\": \"npm run lint && npm run unit\",\n    \"build\": \"cd js && uglifyjs load-image.js load-image-scale.js load-image-meta.js load-image-fetch.js load-image-exif.js load-image-exif-map.js load-image-orientation.js -c -m -o load-image.all.min.js --source-map load-image.all.min.js.map\",\n    \"preversion\": \"npm test\",\n    \"version\": \"npm run build && git add -A js\",\n    \"postversion\": \"git push --tags origin master master:gh-pages && npm publish\"\n  },\n  \"main\": \"js/index.js\"\n}\n"
  },
  {
    "path": "app_backend/static/plugin/JavaScript-Load-Image-2.12.2/test/index.html",
    "content": "<!DOCTYPE HTML>\n<!--\n/*\n * JavaScript Load Image Test\n * https://github.com/blueimp/JavaScript-Load-Image\n *\n * Copyright 2011, Sebastian Tschan\n * https://blueimp.net\n *\n * Licensed under the MIT license:\n * https://opensource.org/licenses/MIT\n */\n-->\n<html lang=\"en\">\n<head>\n<!--[if IE]>\n<meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge,chrome=1\">\n<![endif]-->\n<meta charset=\"utf-8\">\n<title>JavaScript Load Image Test</title>\n<meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n<link rel=\"stylesheet\" href=\"vendor/mocha.css\">\n</head>\n<body>\n<div id=\"mocha\"></div>\n<script src=\"vendor/mocha.js\"></script>\n<script src=\"vendor/chai.js\"></script>\n<script>\nwindow.initMochaPhantomJS && initMochaPhantomJS();\nmocha.setup('bdd');\n</script>\n<script src=\"vendor/canvas-to-blob.js\"></script>\n<script src=\"../js/load-image.js\"></script>\n<script src=\"../js/load-image-scale.js\"></script>\n<script src=\"../js/load-image-meta.js\"></script>\n<script src=\"../js/load-image-fetch.js\"></script>\n<script src=\"../js/load-image-exif.js\"></script>\n<script src=\"../js/load-image-exif-map.js\"></script>\n<script src=\"../js/load-image-orientation.js\"></script>\n<script src=\"test.js\"></script>\n<script>\nmocha.checkLeaks();\nmocha.run();\n</script>\n</body>\n</html>\n"
  },
  {
    "path": "app_backend/static/plugin/JavaScript-Load-Image-2.12.2/test/test.js",
    "content": "/*\n * JavaScript Load Image Test\n * https://github.com/blueimp/JavaScript-Load-Image\n *\n * Copyright 2011, Sebastian Tschan\n * https://blueimp.net\n *\n * Licensed under the MIT license:\n * https://opensource.org/licenses/MIT\n */\n\n/* global describe, it, Blob */\n\n;(function (expect, loadImage) {\n  'use strict'\n\n  var canCreateBlob = !!window.dataURLtoBlob\n  // 80x60px GIF image (color black, base64 data):\n  var b64DataGIF = 'R0lGODdhUAA8AIABAAAAAP///ywAAAAAUAA8AAACS4SPqcvtD6' +\n                    'OctNqLs968+w+G4kiW5omm6sq27gvH8kzX9o3n+s73/g8MCofE' +\n                    'ovGITCqXzKbzCY1Kp9Sq9YrNarfcrvcLDovH5PKsAAA7'\n  var imageUrlGIF = 'data:image/gif;base64,' + b64DataGIF\n  var blobGIF = canCreateBlob && window.dataURLtoBlob(imageUrlGIF)\n  // 2x1px JPEG (color white, with the Exif orientation flag set to 6):\n  var b64DataJPEG = '/9j/4AAQSkZJRgABAQEAYABgAAD/4QAiRXhpZgAASUkqAAgAAA' +\n                    'ABABIBAwABAAAABgASAAAAAAD/2wBDAAEBAQEBAQEBAQEBAQEB' +\n                    'AQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQ' +\n                    'EBAQEBAQEBAQEBAQH/2wBDAQEBAQEBAQEBAQEBAQEBAQEBAQEB' +\n                    'AQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQ' +\n                    'EBAQEBAQH/wAARCAABAAIDASIAAhEBAxEB/8QAHwAAAQUBAQEB' +\n                    'AQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUFBA' +\n                    'QAAAF9AQIDAAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAk' +\n                    'M2JyggkKFhcYGRolJicoKSo0NTY3ODk6Q0RFRkdISUpTVFVWV1' +\n                    'hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJWWl5iZmqKj' +\n                    'pKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uHi4+' +\n                    'Tl5ufo6erx8vP09fb3+Pn6/8QAHwEAAwEBAQEBAQEBAQAAAAAA' +\n                    'AAECAwQFBgcICQoL/8QAtREAAgECBAQDBAcFBAQAAQJ3AAECAx' +\n                    'EEBSExBhJBUQdhcRMiMoEIFEKRobHBCSMzUvAVYnLRChYkNOEl' +\n                    '8RcYGRomJygpKjU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2' +\n                    'hpanN0dXZ3eHl6goOEhYaHiImKkpOUlZaXmJmaoqOkpaanqKmq' +\n                    'srO0tba3uLm6wsPExcbHyMnK0tPU1dbX2Nna4uPk5ebn6Onq8v' +\n                    'P09fb3+Pn6/9oADAMBAAIRAxEAPwD+/iiiigD/2Q=='\n  var imageUrlJPEG = 'data:image/jpeg;base64,' + b64DataJPEG\n  var blobJPEG = canCreateBlob && window.dataURLtoBlob(imageUrlJPEG)\n  function createBlob (data, type) {\n    try {\n      return new Blob([data], {type: type})\n    } catch (e) {\n      var BlobBuilder = window.BlobBuilder || window.WebKitBlobBuilder ||\n      window.MozBlobBuilder || window.MSBlobBuilder\n      var builder = new BlobBuilder()\n      builder.append(data.buffer || data)\n      return builder.getBlob(type)\n    }\n  }\n\n  describe('Loading', function () {\n    it('Return the img element or FileReader object to allow aborting the image load', function () {\n      var img = loadImage(blobGIF, function () {\n        return\n      })\n      expect(img).to.be.an.instanceOf(Object)\n      expect(img.onload).to.be.a('function')\n      expect(img.onerror).to.be.a('function')\n    })\n\n    it('Load image url', function (done) {\n      expect(loadImage(imageUrlGIF, function (img) {\n        expect(img.width).to.equal(80)\n        expect(img.height).to.equal(60)\n        done()\n      })).to.be.ok\n    })\n\n    it('Load image blob', function (done) {\n      expect(loadImage(blobGIF, function (img) {\n        expect(img.width).to.equal(80)\n        expect(img.height).to.equal(60)\n        done()\n      })).to.be.ok\n    })\n\n    it('Return image loading error to callback', function (done) {\n      expect(loadImage('404', function (img) {\n        expect(img).to.be.an.instanceOf(window.Event)\n        expect(img.type).to.equal('error')\n        done()\n      })).to.be.ok\n    })\n\n    it('Keep object URL if noRevoke is true', function (done) {\n      expect(loadImage(blobGIF, function (img) {\n        loadImage(img.src, function (img2) {\n          expect(img.width).to.equal(img2.width)\n          expect(img.height).to.equal(img2.height)\n          done()\n        })\n      }, {noRevoke: true})).to.be.ok\n    })\n\n    it('Discard object URL if noRevoke is undefined or false', function (done) {\n      expect(loadImage(blobGIF, function (img) {\n        loadImage(img.src, function (img2) {\n          if (!window.callPhantom) {\n            // revokeObjectUrl doesn't seem to have an effect in PhantomJS\n            expect(img2).to.be.an.instanceOf(window.Event)\n            expect(img2.type).to.equal('error')\n          }\n          done()\n        })\n      })).to.be.ok\n    })\n  })\n\n  describe('Scaling', function () {\n    describe('max/min', function () {\n      it('Scale to maxWidth', function (done) {\n        expect(loadImage(blobGIF, function (img) {\n          expect(img.width).to.equal(40)\n          expect(img.height).to.equal(30)\n          done()\n        }, {maxWidth: 40})).to.be.ok\n      })\n\n      it('Scale to maxHeight', function (done) {\n        expect(loadImage(blobGIF, function (img) {\n          expect(img.width).to.equal(20)\n          expect(img.height).to.equal(15)\n          done()\n        }, {maxHeight: 15})).to.be.ok\n      })\n\n      it('Scale to minWidth', function (done) {\n        expect(loadImage(blobGIF, function (img) {\n          expect(img.width).to.equal(160)\n          expect(img.height).to.equal(120)\n          done()\n        }, {minWidth: 160})).to.be.ok\n      })\n\n      it('Scale to minHeight', function (done) {\n        expect(loadImage(blobGIF, function (img) {\n          expect(img.width).to.equal(320)\n          expect(img.height).to.equal(240)\n          done()\n        }, {minHeight: 240})).to.be.ok\n      })\n\n      it('Scale to minWidth but respect maxWidth', function (done) {\n        expect(loadImage(blobGIF, function (img) {\n          expect(img.width).to.equal(160)\n          expect(img.height).to.equal(120)\n          done()\n        }, {minWidth: 240, maxWidth: 160})).to.be.ok\n      })\n\n      it('Scale to minHeight but respect maxHeight', function (done) {\n        expect(loadImage(blobGIF, function (img) {\n          expect(img.width).to.equal(160)\n          expect(img.height).to.equal(120)\n          done()\n        }, {minHeight: 180, maxHeight: 120})).to.be.ok\n      })\n\n      it('Scale to minWidth but respect maxHeight', function (done) {\n        expect(loadImage(blobGIF, function (img) {\n          expect(img.width).to.equal(160)\n          expect(img.height).to.equal(120)\n          done()\n        }, {minWidth: 240, maxHeight: 120})).to.be.ok\n      })\n\n      it('Scale to minHeight but respect maxWidth', function (done) {\n        expect(loadImage(blobGIF, function (img) {\n          expect(img.width).to.equal(160)\n          expect(img.height).to.equal(120)\n          done()\n        }, {minHeight: 180, maxWidth: 160})).to.be.ok\n      })\n\n      it('Scale up with the given pixelRatio', function (done) {\n        expect(loadImage(blobGIF, function (img) {\n          expect(img.width).to.equal(320)\n          expect(img.height).to.equal(240)\n          expect(img.style.width).to.equal('160px')\n          expect(img.style.height).to.equal('120px')\n          done()\n        }, {minWidth: 160, canvas: true, pixelRatio: 2})).to.be.ok\n      })\n\n      it('Scale down with the given pixelRatio', function (done) {\n        expect(loadImage(blobGIF, function (img) {\n          expect(img.width).to.equal(80)\n          expect(img.height).to.equal(60)\n          expect(img.style.width).to.equal('40px')\n          expect(img.style.height).to.equal('30px')\n          done()\n        }, {maxWidth: 40, canvas: true, pixelRatio: 2})).to.be.ok\n      })\n\n      it('Scale down with the given downsamplingRatio', function (done) {\n        expect(loadImage(blobGIF, function (img) {\n          expect(img.width).to.equal(20)\n          expect(img.height).to.equal(15)\n          done()\n        }, {maxWidth: 20, canvas: true, downsamplingRatio: 0.5})).to.be.ok\n      })\n\n      it('Ignore max settings if image dimensions are smaller', function (done) {\n        expect(loadImage(blobGIF, function (img) {\n          expect(img.width).to.equal(80)\n          expect(img.height).to.equal(60)\n          done()\n        }, {maxWidth: 160, maxHeight: 120})).to.be.ok\n      })\n\n      it('Ignore min settings if image dimensions are larger', function (done) {\n        expect(loadImage(blobGIF, function (img) {\n          expect(img.width).to.equal(80)\n          expect(img.height).to.equal(60)\n          done()\n        }, {minWidth: 40, minHeight: 30})).to.be.ok\n      })\n    })\n\n    describe('contain', function () {\n      it('Scale up to contain image in max dimensions', function (done) {\n        expect(loadImage(blobGIF, function (img) {\n          expect(img.width).to.equal(160)\n          expect(img.height).to.equal(120)\n          done()\n        }, {maxWidth: 160, maxHeight: 160, contain: true})).to.be.ok\n      })\n\n      it('Scale down to contain image in max dimensions', function (done) {\n        expect(loadImage(blobGIF, function (img) {\n          expect(img.width).to.equal(40)\n          expect(img.height).to.equal(30)\n          done()\n        }, {maxWidth: 40, maxHeight: 40, contain: true})).to.be.ok\n      })\n    })\n\n    describe('cover', function () {\n      it('Scale up to cover max dimensions with image dimensions', function (done) {\n        expect(loadImage(blobGIF, function (img) {\n          expect(img.width).to.equal(160)\n          expect(img.height).to.equal(120)\n          done()\n        }, {maxWidth: 120, maxHeight: 120, cover: true})).to.be.ok\n      })\n\n      it('Scale down to cover max dimensions with image dimensions', function (done) {\n        expect(loadImage(blobGIF, function (img) {\n          expect(img.width).to.equal(40)\n          expect(img.height).to.equal(30)\n          done()\n        }, {maxWidth: 30, maxHeight: 30, cover: true})).to.be.ok\n      })\n    })\n  })\n\n  describe('Cropping', function () {\n    it('Crop to same values for maxWidth and maxHeight', function (done) {\n      expect(loadImage(blobGIF, function (img) {\n        expect(img.width).to.equal(40)\n        expect(img.height).to.equal(40)\n        done()\n      }, {maxWidth: 40, maxHeight: 40, crop: true})).to.be.ok\n    })\n\n    it('Crop to different values for maxWidth and maxHeight', function (done) {\n      expect(loadImage(blobGIF, function (img) {\n        expect(img.width).to.equal(40)\n        expect(img.height).to.equal(60)\n        done()\n      }, {maxWidth: 40, maxHeight: 60, crop: true})).to.be.ok\n    })\n\n    it('Crop using the given sourceWidth and sourceHeight dimensions', function (done) {\n      expect(loadImage(blobGIF, function (img) {\n        expect(img.width).to.equal(40)\n        expect(img.height).to.equal(40)\n        done()\n      }, {sourceWidth: 40, sourceHeight: 40, crop: true})).to.be.ok\n    })\n\n    it('Crop using the given left and top coordinates', function (done) {\n      expect(loadImage(blobGIF, function (img) {\n        expect(img.width).to.equal(40)\n        expect(img.height).to.equal(20)\n        done()\n      }, {left: 40, top: 40, crop: true})).to.be.ok\n    })\n\n    it('Crop using the given right and bottom coordinates', function (done) {\n      expect(loadImage(blobGIF, function (img) {\n        expect(img.width).to.equal(40)\n        expect(img.height).to.equal(20)\n        done()\n      }, {right: 40, bottom: 40, crop: true})).to.be.ok\n    })\n\n    it('Crop using the given 2:1 aspectRatio', function (done) {\n      expect(loadImage(blobGIF, function (img) {\n        expect(img.width).to.equal(80)\n        expect(img.height).to.equal(40)\n        done()\n      }, {aspectRatio: 2})).to.be.ok\n    })\n\n    it('Crop using the given 2:3 aspectRatio', function (done) {\n      expect(loadImage(blobGIF, function (img) {\n        expect(img.width).to.equal(40)\n        expect(img.height).to.equal(60)\n        done()\n      }, {aspectRatio: 2 / 3})).to.be.ok\n    })\n\n    it('Crop using maxWidth/maxHeight with the given pixelRatio', function (done) {\n      expect(loadImage(blobGIF, function (img) {\n        expect(img.width).to.equal(80)\n        expect(img.height).to.equal(80)\n        expect(img.style.width).to.equal('40px')\n        expect(img.style.height).to.equal('40px')\n        done()\n      }, {maxWidth: 40, maxHeight: 40, crop: true, pixelRatio: 2})).to.be.ok\n    })\n\n    it('Crop using sourceWidth/sourceHeight with the given pixelRatio', function (done) {\n      expect(loadImage(blobGIF, function (img) {\n        expect(img.width).to.equal(80)\n        expect(img.height).to.equal(80)\n        expect(img.style.width).to.equal('40px')\n        expect(img.style.height).to.equal('40px')\n        done()\n      }, {sourceWidth: 40, sourceHeight: 40, crop: true, pixelRatio: 2})).to.be.ok\n    })\n\n    it('Crop using maxWidth/maxHeight with the given downsamplingRatio', function (done) {\n      expect(loadImage(blobGIF, function (img) {\n        expect(img.width).to.equal(10)\n        expect(img.height).to.equal(10)\n\n        var data = img.getContext('2d').getImageData(0, 0, 10, 10).data\n        for (var i = 0; i < data.length / 4; i += 4) {\n          expect(data[i]).to.equal(0)\n          expect(data[i + 1]).to.equal(0)\n          expect(data[i + 2]).to.equal(0)\n          expect(data[i + 3]).to.equal(255)\n        }\n\n        done()\n      }, {maxWidth: 10, maxHeight: 10, crop: true, downsamplingRatio: 0.5})).to.be.ok\n    })\n  })\n\n  describe('Orientation', function () {\n    it('Should keep the orientation', function (done) {\n      expect(loadImage(blobGIF, function (img) {\n        expect(img.width).to.equal(80)\n        expect(img.height).to.equal(60)\n        done()\n      }, {orientation: 1})).to.be.ok\n    })\n\n    it('Should rotate left', function (done) {\n      expect(loadImage(blobGIF, function (img) {\n        expect(img.width).to.equal(60)\n        expect(img.height).to.equal(80)\n        done()\n      }, {orientation: 8})).to.be.ok\n    })\n\n    it('Should rotate right', function (done) {\n      expect(loadImage(blobGIF, function (img) {\n        expect(img.width).to.equal(60)\n        expect(img.height).to.equal(80)\n        done()\n      }, {orientation: 6})).to.be.ok\n    })\n\n    it('Should adjust constraints to new coordinates', function (done) {\n      expect(loadImage(blobGIF, function (img) {\n        expect(img.width).to.equal(30)\n        expect(img.height).to.equal(40)\n        done()\n      }, {orientation: 6, maxWidth: 30, maxHeight: 40})).to.be.ok\n    })\n\n    it('Should adjust left and top to new coordinates', function (done) {\n      expect(loadImage(blobGIF, function (img) {\n        expect(img.width).to.equal(30)\n        expect(img.height).to.equal(60)\n        done()\n      }, {orientation: 5, left: 30, top: 20})).to.be.ok\n    })\n\n    it('Should adjust right and bottom to new coordinates', function (done) {\n      expect(loadImage(blobGIF, function (img) {\n        expect(img.width).to.equal(30)\n        expect(img.height).to.equal(60)\n        done()\n      }, {orientation: 5, right: 30, bottom: 20})).to.be.ok\n    })\n\n    it('Should adjust left and bottom to new coordinates', function (done) {\n      expect(loadImage(blobGIF, function (img) {\n        expect(img.width).to.equal(30)\n        expect(img.height).to.equal(60)\n        done()\n      }, {orientation: 7, left: 30, bottom: 20})).to.be.ok\n    })\n\n    it('Should adjust right and top to new coordinates', function (done) {\n      expect(loadImage(blobGIF, function (img) {\n        expect(img.width).to.equal(30)\n        expect(img.height).to.equal(60)\n        done()\n      }, {orientation: 7, right: 30, top: 20})).to.be.ok\n    })\n\n    it('Should rotate left with the given pixelRatio', function (done) {\n      expect(loadImage(blobGIF, function (img) {\n        expect(img.width).to.equal(120)\n        expect(img.height).to.equal(160)\n        expect(img.style.width).to.equal('60px')\n        expect(img.style.height).to.equal('80px')\n        done()\n      }, {orientation: 8, pixelRatio: 2})).to.be.ok\n    })\n\n    it('Should rotate right with the given pixelRatio', function (done) {\n      expect(loadImage(blobGIF, function (img) {\n        expect(img.width).to.equal(120)\n        expect(img.height).to.equal(160)\n        expect(img.style.width).to.equal('60px')\n        expect(img.style.height).to.equal('80px')\n        done()\n      }, {orientation: 6, pixelRatio: 2})).to.be.ok\n    })\n\n    it('Should ignore too small orientation value', function (done) {\n      expect(loadImage(blobGIF, function (img) {\n        expect(img.width).to.equal(80)\n        expect(img.height).to.equal(60)\n        done()\n      }, {orientation: -1})).to.be.ok\n    })\n\n    it('Should ignore too large orientation value', function (done) {\n      expect(loadImage(blobGIF, function (img) {\n        expect(img.width).to.equal(80)\n        expect(img.height).to.equal(60)\n        done()\n      }, {orientation: 9})).to.be.ok\n    })\n\n    it('Should rotate right based on the exif orientation value', function (done) {\n      expect(loadImage(blobJPEG, function (img, data) {\n        expect(data).to.be.ok\n        expect(data.exif).to.be.ok\n        expect(data.exif.get('Orientation')).to.equal(6)\n        expect(img.width).to.equal(1)\n        expect(img.height).to.equal(2)\n        done()\n      }, {orientation: true})).to.be.ok\n    })\n\n    it('Should adjust constraints based on the exif orientation value', function (done) {\n      expect(loadImage(blobJPEG, function (img) {\n        expect(img.width).to.equal(10)\n        expect(img.height).to.equal(20)\n        done()\n      }, {orientation: true, minWidth: 10, minHeight: 20})).to.be.ok\n    })\n  })\n\n  describe('Canvas', function () {\n    it('Return img element to callback if canvas is not true', function (done) {\n      expect(loadImage(blobGIF, function (img) {\n        expect(img.getContext).to.be.falsy\n        expect(img.nodeName.toLowerCase()).to.equal('img')\n        done()\n      })).to.be.ok\n    })\n\n    it('Return canvas element to callback if canvas is true', function (done) {\n      expect(loadImage(blobGIF, function (img) {\n        expect(img.getContext).to.be.ok\n        expect(img.nodeName.toLowerCase()).to.equal('canvas')\n        done()\n      }, {canvas: true})).to.be.ok\n    })\n\n    it('Return scaled canvas element to callback', function (done) {\n      expect(loadImage(blobGIF, function (img) {\n        expect(img.getContext).to.be.ok\n        expect(img.nodeName.toLowerCase()).to.equal('canvas')\n        expect(img.width).to.equal(40)\n        expect(img.height).to.equal(30)\n        done()\n      }, {canvas: true, maxWidth: 40})).to.be.ok\n    })\n\n    it('Accept a canvas element as parameter for loadImage.scale', function (done) {\n      expect(loadImage(blobGIF, function (img) {\n        img = loadImage.scale(img, {\n          maxWidth: 40\n        })\n        expect(img.getContext).to.be.ok\n        expect(img.nodeName.toLowerCase()).to.equal('canvas')\n        expect(img.width).to.equal(40)\n        expect(img.height).to.equal(30)\n        done()\n      }, {canvas: true})).to.be.ok\n    })\n  })\n\n  describe('Metadata', function () {\n    it('Should parse Exif information', function (done) {\n      loadImage.parseMetaData(blobJPEG, function (data) {\n        expect(data.exif).to.be.ok\n        expect(data.exif.get('Orientation')).to.equal(6)\n        done()\n      })\n    })\n\n    it('Should parse the complete image head', function (done) {\n      loadImage.parseMetaData(blobJPEG, function (data) {\n        expect(data.imageHead).to.be.ok\n        loadImage.parseMetaData(\n          createBlob(data.imageHead, 'image/jpeg'),\n          function (data) {\n            expect(data.exif).to.be.ok\n            expect(data.exif.get('Orientation')).to.equal(6)\n            done()\n          }\n        )\n      })\n    })\n\n    it('Should parse meta data automatically', function (done) {\n      expect(loadImage(blobJPEG, function (img, data) {\n        expect(data).to.be.ok\n        expect(data.imageHead).to.be.ok\n        expect(data.exif).to.be.ok\n        expect(data.exif.get('Orientation')).to.equal(6)\n        done()\n      }, {meta: true})).to.be.ok\n    })\n  })\n\n  if ('fetch' in window && 'Request' in window) {\n    describe('Fetch', function () {\n      it('Should fetch blob from URL if meta is true', function (done) {\n        expect(loadImage(imageUrlJPEG, function (img, data) {\n          expect(data).to.be.ok\n          expect(data.imageHead).to.be.ok\n          expect(data.exif).to.be.ok\n          expect(data.exif.get('Orientation')).to.equal(6)\n          done()\n        }, {meta: true})).to.be.ok\n      })\n\n      it('Should not fetch blob from URL if meta is false', function (done) {\n        expect(loadImage(imageUrlJPEG, function (img, data) {\n          expect(data.imageHead).to.be.falsy\n          expect(data.exif).to.be.falsy\n          expect(img.width).to.equal(2)\n          expect(img.height).to.equal(1)\n          done()\n        })).to.be.ok\n      })\n    })\n  }\n}(\n  this.chai.expect,\n  this.loadImage\n))\n"
  },
  {
    "path": "app_backend/static/plugin/JavaScript-Load-Image-2.12.2/test/vendor/canvas-to-blob.js",
    "content": "/*\n * JavaScript Canvas to Blob\n * https://github.com/blueimp/JavaScript-Canvas-to-Blob\n *\n * Copyright 2012, Sebastian Tschan\n * https://blueimp.net\n *\n * Licensed under the MIT license:\n * https://opensource.org/licenses/MIT\n *\n * Based on stackoverflow user Stoive's code snippet:\n * http://stackoverflow.com/q/4998908\n */\n\n/*global window, atob, Blob, ArrayBuffer, Uint8Array, define, module */\n\n;(function (window) {\n  'use strict'\n\n  var CanvasPrototype = window.HTMLCanvasElement &&\n                          window.HTMLCanvasElement.prototype\n  var hasBlobConstructor = window.Blob && (function () {\n    try {\n      return Boolean(new Blob())\n    } catch (e) {\n      return false\n    }\n  }())\n  var hasArrayBufferViewSupport = hasBlobConstructor && window.Uint8Array &&\n    (function () {\n      try {\n        return new Blob([new Uint8Array(100)]).size === 100\n      } catch (e) {\n        return false\n      }\n    }())\n  var BlobBuilder = window.BlobBuilder || window.WebKitBlobBuilder ||\n                      window.MozBlobBuilder || window.MSBlobBuilder\n  var dataURIPattern = /^data:((.*?)(;charset=.*?)?)(;base64)?,/\n  var dataURLtoBlob = (hasBlobConstructor || BlobBuilder) && window.atob &&\n    window.ArrayBuffer && window.Uint8Array &&\n    function (dataURI) {\n      var matches,\n        mediaType,\n        isBase64,\n        dataString,\n        byteString,\n        arrayBuffer,\n        intArray,\n        i,\n        bb\n      // Parse the dataURI components as per RFC 2397\n      matches = dataURI.match(dataURIPattern)\n      if (!matches) {\n        throw new Error('invalid data URI')\n      }\n      // Default to text/plain;charset=US-ASCII\n      mediaType = matches[2]\n        ? matches[1]\n        : 'text/plain' + (matches[3] || ';charset=US-ASCII')\n      isBase64 = !!matches[4]\n      dataString = dataURI.slice(matches[0].length)\n      if (isBase64) {\n        // Convert base64 to raw binary data held in a string:\n        byteString = atob(dataString)\n      } else {\n        // Convert base64/URLEncoded data component to raw binary:\n        byteString = decodeURIComponent(dataString)\n      }\n      // Write the bytes of the string to an ArrayBuffer:\n      arrayBuffer = new ArrayBuffer(byteString.length)\n      intArray = new Uint8Array(arrayBuffer)\n      for (i = 0; i < byteString.length; i += 1) {\n        intArray[i] = byteString.charCodeAt(i)\n      }\n      // Write the ArrayBuffer (or ArrayBufferView) to a blob:\n      if (hasBlobConstructor) {\n        return new Blob(\n          [hasArrayBufferViewSupport ? intArray : arrayBuffer],\n          {type: mediaType}\n        )\n      }\n      bb = new BlobBuilder()\n      bb.append(arrayBuffer)\n      return bb.getBlob(mediaType)\n    }\n  if (window.HTMLCanvasElement && !CanvasPrototype.toBlob) {\n    if (CanvasPrototype.mozGetAsFile) {\n      CanvasPrototype.toBlob = function (callback, type, quality) {\n        if (quality && CanvasPrototype.toDataURL && dataURLtoBlob) {\n          callback(dataURLtoBlob(this.toDataURL(type, quality)))\n        } else {\n          callback(this.mozGetAsFile('blob', type))\n        }\n      }\n    } else if (CanvasPrototype.toDataURL && dataURLtoBlob) {\n      CanvasPrototype.toBlob = function (callback, type, quality) {\n        callback(dataURLtoBlob(this.toDataURL(type, quality)))\n      }\n    }\n  }\n  if (typeof define === 'function' && define.amd) {\n    define(function () {\n      return dataURLtoBlob\n    })\n  } else if (typeof module === 'object' && module.exports) {\n    module.exports = dataURLtoBlob\n  } else {\n    window.dataURLtoBlob = dataURLtoBlob\n  }\n}(window))\n"
  },
  {
    "path": "app_backend/static/plugin/JavaScript-Load-Image-2.12.2/test/vendor/chai.js",
    "content": "(function(f){if(typeof exports===\"object\"&&typeof module!==\"undefined\"){module.exports=f()}else if(typeof define===\"function\"&&define.amd){define([],f)}else{var g;if(typeof window!==\"undefined\"){g=window}else if(typeof global!==\"undefined\"){g=global}else if(typeof self!==\"undefined\"){g=self}else{g=this}g.chai = f()}})(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require==\"function\"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error(\"Cannot find module '\"+o+\"'\");throw f.code=\"MODULE_NOT_FOUND\",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require==\"function\"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){\nmodule.exports = require('./lib/chai');\n\n},{\"./lib/chai\":2}],2:[function(require,module,exports){\n/*!\n * chai\n * Copyright(c) 2011-2014 Jake Luer <jake@alogicalparadox.com>\n * MIT Licensed\n */\n\nvar used = []\n  , exports = module.exports = {};\n\n/*!\n * Chai version\n */\n\nexports.version = '3.5.0';\n\n/*!\n * Assertion Error\n */\n\nexports.AssertionError = require('assertion-error');\n\n/*!\n * Utils for plugins (not exported)\n */\n\nvar util = require('./chai/utils');\n\n/**\n * # .use(function)\n *\n * Provides a way to extend the internals of Chai\n *\n * @param {Function}\n * @returns {this} for chaining\n * @api public\n */\n\nexports.use = function (fn) {\n  if (!~used.indexOf(fn)) {\n    fn(this, util);\n    used.push(fn);\n  }\n\n  return this;\n};\n\n/*!\n * Utility Functions\n */\n\nexports.util = util;\n\n/*!\n * Configuration\n */\n\nvar config = require('./chai/config');\nexports.config = config;\n\n/*!\n * Primary `Assertion` prototype\n */\n\nvar assertion = require('./chai/assertion');\nexports.use(assertion);\n\n/*!\n * Core Assertions\n */\n\nvar core = require('./chai/core/assertions');\nexports.use(core);\n\n/*!\n * Expect interface\n */\n\nvar expect = require('./chai/interface/expect');\nexports.use(expect);\n\n/*!\n * Should interface\n */\n\nvar should = require('./chai/interface/should');\nexports.use(should);\n\n/*!\n * Assert interface\n */\n\nvar assert = require('./chai/interface/assert');\nexports.use(assert);\n\n},{\"./chai/assertion\":3,\"./chai/config\":4,\"./chai/core/assertions\":5,\"./chai/interface/assert\":6,\"./chai/interface/expect\":7,\"./chai/interface/should\":8,\"./chai/utils\":22,\"assertion-error\":30}],3:[function(require,module,exports){\n/*!\n * chai\n * http://chaijs.com\n * Copyright(c) 2011-2014 Jake Luer <jake@alogicalparadox.com>\n * MIT Licensed\n */\n\nvar config = require('./config');\n\nmodule.exports = function (_chai, util) {\n  /*!\n   * Module dependencies.\n   */\n\n  var AssertionError = _chai.AssertionError\n    , flag = util.flag;\n\n  /*!\n   * Module export.\n   */\n\n  _chai.Assertion = Assertion;\n\n  /*!\n   * Assertion Constructor\n   *\n   * Creates object for chaining.\n   *\n   * @api private\n   */\n\n  function Assertion (obj, msg, stack) {\n    flag(this, 'ssfi', stack || arguments.callee);\n    flag(this, 'object', obj);\n    flag(this, 'message', msg);\n  }\n\n  Object.defineProperty(Assertion, 'includeStack', {\n    get: function() {\n      console.warn('Assertion.includeStack is deprecated, use chai.config.includeStack instead.');\n      return config.includeStack;\n    },\n    set: function(value) {\n      console.warn('Assertion.includeStack is deprecated, use chai.config.includeStack instead.');\n      config.includeStack = value;\n    }\n  });\n\n  Object.defineProperty(Assertion, 'showDiff', {\n    get: function() {\n      console.warn('Assertion.showDiff is deprecated, use chai.config.showDiff instead.');\n      return config.showDiff;\n    },\n    set: function(value) {\n      console.warn('Assertion.showDiff is deprecated, use chai.config.showDiff instead.');\n      config.showDiff = value;\n    }\n  });\n\n  Assertion.addProperty = function (name, fn) {\n    util.addProperty(this.prototype, name, fn);\n  };\n\n  Assertion.addMethod = function (name, fn) {\n    util.addMethod(this.prototype, name, fn);\n  };\n\n  Assertion.addChainableMethod = function (name, fn, chainingBehavior) {\n    util.addChainableMethod(this.prototype, name, fn, chainingBehavior);\n  };\n\n  Assertion.overwriteProperty = function (name, fn) {\n    util.overwriteProperty(this.prototype, name, fn);\n  };\n\n  Assertion.overwriteMethod = function (name, fn) {\n    util.overwriteMethod(this.prototype, name, fn);\n  };\n\n  Assertion.overwriteChainableMethod = function (name, fn, chainingBehavior) {\n    util.overwriteChainableMethod(this.prototype, name, fn, chainingBehavior);\n  };\n\n  /**\n   * ### .assert(expression, message, negateMessage, expected, actual, showDiff)\n   *\n   * Executes an expression and check expectations. Throws AssertionError for reporting if test doesn't pass.\n   *\n   * @name assert\n   * @param {Philosophical} expression to be tested\n   * @param {String|Function} message or function that returns message to display if expression fails\n   * @param {String|Function} negatedMessage or function that returns negatedMessage to display if negated expression fails\n   * @param {Mixed} expected value (remember to check for negation)\n   * @param {Mixed} actual (optional) will default to `this.obj`\n   * @param {Boolean} showDiff (optional) when set to `true`, assert will display a diff in addition to the message if expression fails\n   * @api private\n   */\n\n  Assertion.prototype.assert = function (expr, msg, negateMsg, expected, _actual, showDiff) {\n    var ok = util.test(this, arguments);\n    if (true !== showDiff) showDiff = false;\n    if (true !== config.showDiff) showDiff = false;\n\n    if (!ok) {\n      var msg = util.getMessage(this, arguments)\n        , actual = util.getActual(this, arguments);\n      throw new AssertionError(msg, {\n          actual: actual\n        , expected: expected\n        , showDiff: showDiff\n      }, (config.includeStack) ? this.assert : flag(this, 'ssfi'));\n    }\n  };\n\n  /*!\n   * ### ._obj\n   *\n   * Quick reference to stored `actual` value for plugin developers.\n   *\n   * @api private\n   */\n\n  Object.defineProperty(Assertion.prototype, '_obj',\n    { get: function () {\n        return flag(this, 'object');\n      }\n    , set: function (val) {\n        flag(this, 'object', val);\n      }\n  });\n};\n\n},{\"./config\":4}],4:[function(require,module,exports){\nmodule.exports = {\n\n  /**\n   * ### config.includeStack\n   *\n   * User configurable property, influences whether stack trace\n   * is included in Assertion error message. Default of false\n   * suppresses stack trace in the error message.\n   *\n   *     chai.config.includeStack = true;  // enable stack on error\n   *\n   * @param {Boolean}\n   * @api public\n   */\n\n   includeStack: false,\n\n  /**\n   * ### config.showDiff\n   *\n   * User configurable property, influences whether or not\n   * the `showDiff` flag should be included in the thrown\n   * AssertionErrors. `false` will always be `false`; `true`\n   * will be true when the assertion has requested a diff\n   * be shown.\n   *\n   * @param {Boolean}\n   * @api public\n   */\n\n  showDiff: true,\n\n  /**\n   * ### config.truncateThreshold\n   *\n   * User configurable property, sets length threshold for actual and\n   * expected values in assertion errors. If this threshold is exceeded, for\n   * example for large data structures, the value is replaced with something\n   * like `[ Array(3) ]` or `{ Object (prop1, prop2) }`.\n   *\n   * Set it to zero if you want to disable truncating altogether.\n   *\n   * This is especially userful when doing assertions on arrays: having this\n   * set to a reasonable large value makes the failure messages readily\n   * inspectable.\n   *\n   *     chai.config.truncateThreshold = 0;  // disable truncating\n   *\n   * @param {Number}\n   * @api public\n   */\n\n  truncateThreshold: 40\n\n};\n\n},{}],5:[function(require,module,exports){\n/*!\n * chai\n * http://chaijs.com\n * Copyright(c) 2011-2014 Jake Luer <jake@alogicalparadox.com>\n * MIT Licensed\n */\n\nmodule.exports = function (chai, _) {\n  var Assertion = chai.Assertion\n    , toString = Object.prototype.toString\n    , flag = _.flag;\n\n  /**\n   * ### Language Chains\n   *\n   * The following are provided as chainable getters to\n   * improve the readability of your assertions. They\n   * do not provide testing capabilities unless they\n   * have been overwritten by a plugin.\n   *\n   * **Chains**\n   *\n   * - to\n   * - be\n   * - been\n   * - is\n   * - that\n   * - which\n   * - and\n   * - has\n   * - have\n   * - with\n   * - at\n   * - of\n   * - same\n   *\n   * @name language chains\n   * @namespace BDD\n   * @api public\n   */\n\n  [ 'to', 'be', 'been'\n  , 'is', 'and', 'has', 'have'\n  , 'with', 'that', 'which', 'at'\n  , 'of', 'same' ].forEach(function (chain) {\n    Assertion.addProperty(chain, function () {\n      return this;\n    });\n  });\n\n  /**\n   * ### .not\n   *\n   * Negates any of assertions following in the chain.\n   *\n   *     expect(foo).to.not.equal('bar');\n   *     expect(goodFn).to.not.throw(Error);\n   *     expect({ foo: 'baz' }).to.have.property('foo')\n   *       .and.not.equal('bar');\n   *\n   * @name not\n   * @namespace BDD\n   * @api public\n   */\n\n  Assertion.addProperty('not', function () {\n    flag(this, 'negate', true);\n  });\n\n  /**\n   * ### .deep\n   *\n   * Sets the `deep` flag, later used by the `equal` and\n   * `property` assertions.\n   *\n   *     expect(foo).to.deep.equal({ bar: 'baz' });\n   *     expect({ foo: { bar: { baz: 'quux' } } })\n   *       .to.have.deep.property('foo.bar.baz', 'quux');\n   *\n   * `.deep.property` special characters can be escaped\n   * by adding two slashes before the `.` or `[]`.\n   *\n   *     var deepCss = { '.link': { '[target]': 42 }};\n   *     expect(deepCss).to.have.deep.property('\\\\.link.\\\\[target\\\\]', 42);\n   *\n   * @name deep\n   * @namespace BDD\n   * @api public\n   */\n\n  Assertion.addProperty('deep', function () {\n    flag(this, 'deep', true);\n  });\n\n  /**\n   * ### .any\n   *\n   * Sets the `any` flag, (opposite of the `all` flag)\n   * later used in the `keys` assertion.\n   *\n   *     expect(foo).to.have.any.keys('bar', 'baz');\n   *\n   * @name any\n   * @namespace BDD\n   * @api public\n   */\n\n  Assertion.addProperty('any', function () {\n    flag(this, 'any', true);\n    flag(this, 'all', false)\n  });\n\n\n  /**\n   * ### .all\n   *\n   * Sets the `all` flag (opposite of the `any` flag)\n   * later used by the `keys` assertion.\n   *\n   *     expect(foo).to.have.all.keys('bar', 'baz');\n   *\n   * @name all\n   * @namespace BDD\n   * @api public\n   */\n\n  Assertion.addProperty('all', function () {\n    flag(this, 'all', true);\n    flag(this, 'any', false);\n  });\n\n  /**\n   * ### .a(type)\n   *\n   * The `a` and `an` assertions are aliases that can be\n   * used either as language chains or to assert a value's\n   * type.\n   *\n   *     // typeof\n   *     expect('test').to.be.a('string');\n   *     expect({ foo: 'bar' }).to.be.an('object');\n   *     expect(null).to.be.a('null');\n   *     expect(undefined).to.be.an('undefined');\n   *     expect(new Error).to.be.an('error');\n   *     expect(new Promise).to.be.a('promise');\n   *     expect(new Float32Array()).to.be.a('float32array');\n   *     expect(Symbol()).to.be.a('symbol');\n   *\n   *     // es6 overrides\n   *     expect({[Symbol.toStringTag]:()=>'foo'}).to.be.a('foo');\n   *\n   *     // language chain\n   *     expect(foo).to.be.an.instanceof(Foo);\n   *\n   * @name a\n   * @alias an\n   * @param {String} type\n   * @param {String} message _optional_\n   * @namespace BDD\n   * @api public\n   */\n\n  function an (type, msg) {\n    if (msg) flag(this, 'message', msg);\n    type = type.toLowerCase();\n    var obj = flag(this, 'object')\n      , article = ~[ 'a', 'e', 'i', 'o', 'u' ].indexOf(type.charAt(0)) ? 'an ' : 'a ';\n\n    this.assert(\n        type === _.type(obj)\n      , 'expected #{this} to be ' + article + type\n      , 'expected #{this} not to be ' + article + type\n    );\n  }\n\n  Assertion.addChainableMethod('an', an);\n  Assertion.addChainableMethod('a', an);\n\n  /**\n   * ### .include(value)\n   *\n   * The `include` and `contain` assertions can be used as either property\n   * based language chains or as methods to assert the inclusion of an object\n   * in an array or a substring in a string. When used as language chains,\n   * they toggle the `contains` flag for the `keys` assertion.\n   *\n   *     expect([1,2,3]).to.include(2);\n   *     expect('foobar').to.contain('foo');\n   *     expect({ foo: 'bar', hello: 'universe' }).to.include.keys('foo');\n   *\n   * @name include\n   * @alias contain\n   * @alias includes\n   * @alias contains\n   * @param {Object|String|Number} obj\n   * @param {String} message _optional_\n   * @namespace BDD\n   * @api public\n   */\n\n  function includeChainingBehavior () {\n    flag(this, 'contains', true);\n  }\n\n  function include (val, msg) {\n    _.expectTypes(this, ['array', 'object', 'string']);\n\n    if (msg) flag(this, 'message', msg);\n    var obj = flag(this, 'object');\n    var expected = false;\n\n    if (_.type(obj) === 'array' && _.type(val) === 'object') {\n      for (var i in obj) {\n        if (_.eql(obj[i], val)) {\n          expected = true;\n          break;\n        }\n      }\n    } else if (_.type(val) === 'object') {\n      if (!flag(this, 'negate')) {\n        for (var k in val) new Assertion(obj).property(k, val[k]);\n        return;\n      }\n      var subset = {};\n      for (var k in val) subset[k] = obj[k];\n      expected = _.eql(subset, val);\n    } else {\n      expected = (obj != undefined) && ~obj.indexOf(val);\n    }\n    this.assert(\n        expected\n      , 'expected #{this} to include ' + _.inspect(val)\n      , 'expected #{this} to not include ' + _.inspect(val));\n  }\n\n  Assertion.addChainableMethod('include', include, includeChainingBehavior);\n  Assertion.addChainableMethod('contain', include, includeChainingBehavior);\n  Assertion.addChainableMethod('contains', include, includeChainingBehavior);\n  Assertion.addChainableMethod('includes', include, includeChainingBehavior);\n\n  /**\n   * ### .ok\n   *\n   * Asserts that the target is truthy.\n   *\n   *     expect('everything').to.be.ok;\n   *     expect(1).to.be.ok;\n   *     expect(false).to.not.be.ok;\n   *     expect(undefined).to.not.be.ok;\n   *     expect(null).to.not.be.ok;\n   *\n   * @name ok\n   * @namespace BDD\n   * @api public\n   */\n\n  Assertion.addProperty('ok', function () {\n    this.assert(\n        flag(this, 'object')\n      , 'expected #{this} to be truthy'\n      , 'expected #{this} to be falsy');\n  });\n\n  /**\n   * ### .true\n   *\n   * Asserts that the target is `true`.\n   *\n   *     expect(true).to.be.true;\n   *     expect(1).to.not.be.true;\n   *\n   * @name true\n   * @namespace BDD\n   * @api public\n   */\n\n  Assertion.addProperty('true', function () {\n    this.assert(\n        true === flag(this, 'object')\n      , 'expected #{this} to be true'\n      , 'expected #{this} to be false'\n      , this.negate ? false : true\n    );\n  });\n\n  /**\n   * ### .false\n   *\n   * Asserts that the target is `false`.\n   *\n   *     expect(false).to.be.false;\n   *     expect(0).to.not.be.false;\n   *\n   * @name false\n   * @namespace BDD\n   * @api public\n   */\n\n  Assertion.addProperty('false', function () {\n    this.assert(\n        false === flag(this, 'object')\n      , 'expected #{this} to be false'\n      , 'expected #{this} to be true'\n      , this.negate ? true : false\n    );\n  });\n\n  /**\n   * ### .null\n   *\n   * Asserts that the target is `null`.\n   *\n   *     expect(null).to.be.null;\n   *     expect(undefined).to.not.be.null;\n   *\n   * @name null\n   * @namespace BDD\n   * @api public\n   */\n\n  Assertion.addProperty('null', function () {\n    this.assert(\n        null === flag(this, 'object')\n      , 'expected #{this} to be null'\n      , 'expected #{this} not to be null'\n    );\n  });\n\n  /**\n   * ### .undefined\n   *\n   * Asserts that the target is `undefined`.\n   *\n   *     expect(undefined).to.be.undefined;\n   *     expect(null).to.not.be.undefined;\n   *\n   * @name undefined\n   * @namespace BDD\n   * @api public\n   */\n\n  Assertion.addProperty('undefined', function () {\n    this.assert(\n        undefined === flag(this, 'object')\n      , 'expected #{this} to be undefined'\n      , 'expected #{this} not to be undefined'\n    );\n  });\n\n  /**\n   * ### .NaN\n   * Asserts that the target is `NaN`.\n   *\n   *     expect('foo').to.be.NaN;\n   *     expect(4).not.to.be.NaN;\n   *\n   * @name NaN\n   * @namespace BDD\n   * @api public\n   */\n\n  Assertion.addProperty('NaN', function () {\n    this.assert(\n        isNaN(flag(this, 'object'))\n        , 'expected #{this} to be NaN'\n        , 'expected #{this} not to be NaN'\n    );\n  });\n\n  /**\n   * ### .exist\n   *\n   * Asserts that the target is neither `null` nor `undefined`.\n   *\n   *     var foo = 'hi'\n   *       , bar = null\n   *       , baz;\n   *\n   *     expect(foo).to.exist;\n   *     expect(bar).to.not.exist;\n   *     expect(baz).to.not.exist;\n   *\n   * @name exist\n   * @namespace BDD\n   * @api public\n   */\n\n  Assertion.addProperty('exist', function () {\n    this.assert(\n        null != flag(this, 'object')\n      , 'expected #{this} to exist'\n      , 'expected #{this} to not exist'\n    );\n  });\n\n\n  /**\n   * ### .empty\n   *\n   * Asserts that the target's length is `0`. For arrays and strings, it checks\n   * the `length` property. For objects, it gets the count of\n   * enumerable keys.\n   *\n   *     expect([]).to.be.empty;\n   *     expect('').to.be.empty;\n   *     expect({}).to.be.empty;\n   *\n   * @name empty\n   * @namespace BDD\n   * @api public\n   */\n\n  Assertion.addProperty('empty', function () {\n    var obj = flag(this, 'object')\n      , expected = obj;\n\n    if (Array.isArray(obj) || 'string' === typeof object) {\n      expected = obj.length;\n    } else if (typeof obj === 'object') {\n      expected = Object.keys(obj).length;\n    }\n\n    this.assert(\n        !expected\n      , 'expected #{this} to be empty'\n      , 'expected #{this} not to be empty'\n    );\n  });\n\n  /**\n   * ### .arguments\n   *\n   * Asserts that the target is an arguments object.\n   *\n   *     function test () {\n   *       expect(arguments).to.be.arguments;\n   *     }\n   *\n   * @name arguments\n   * @alias Arguments\n   * @namespace BDD\n   * @api public\n   */\n\n  function checkArguments () {\n    var obj = flag(this, 'object')\n      , type = Object.prototype.toString.call(obj);\n    this.assert(\n        '[object Arguments]' === type\n      , 'expected #{this} to be arguments but got ' + type\n      , 'expected #{this} to not be arguments'\n    );\n  }\n\n  Assertion.addProperty('arguments', checkArguments);\n  Assertion.addProperty('Arguments', checkArguments);\n\n  /**\n   * ### .equal(value)\n   *\n   * Asserts that the target is strictly equal (`===`) to `value`.\n   * Alternately, if the `deep` flag is set, asserts that\n   * the target is deeply equal to `value`.\n   *\n   *     expect('hello').to.equal('hello');\n   *     expect(42).to.equal(42);\n   *     expect(1).to.not.equal(true);\n   *     expect({ foo: 'bar' }).to.not.equal({ foo: 'bar' });\n   *     expect({ foo: 'bar' }).to.deep.equal({ foo: 'bar' });\n   *\n   * @name equal\n   * @alias equals\n   * @alias eq\n   * @alias deep.equal\n   * @param {Mixed} value\n   * @param {String} message _optional_\n   * @namespace BDD\n   * @api public\n   */\n\n  function assertEqual (val, msg) {\n    if (msg) flag(this, 'message', msg);\n    var obj = flag(this, 'object');\n    if (flag(this, 'deep')) {\n      return this.eql(val);\n    } else {\n      this.assert(\n          val === obj\n        , 'expected #{this} to equal #{exp}'\n        , 'expected #{this} to not equal #{exp}'\n        , val\n        , this._obj\n        , true\n      );\n    }\n  }\n\n  Assertion.addMethod('equal', assertEqual);\n  Assertion.addMethod('equals', assertEqual);\n  Assertion.addMethod('eq', assertEqual);\n\n  /**\n   * ### .eql(value)\n   *\n   * Asserts that the target is deeply equal to `value`.\n   *\n   *     expect({ foo: 'bar' }).to.eql({ foo: 'bar' });\n   *     expect([ 1, 2, 3 ]).to.eql([ 1, 2, 3 ]);\n   *\n   * @name eql\n   * @alias eqls\n   * @param {Mixed} value\n   * @param {String} message _optional_\n   * @namespace BDD\n   * @api public\n   */\n\n  function assertEql(obj, msg) {\n    if (msg) flag(this, 'message', msg);\n    this.assert(\n        _.eql(obj, flag(this, 'object'))\n      , 'expected #{this} to deeply equal #{exp}'\n      , 'expected #{this} to not deeply equal #{exp}'\n      , obj\n      , this._obj\n      , true\n    );\n  }\n\n  Assertion.addMethod('eql', assertEql);\n  Assertion.addMethod('eqls', assertEql);\n\n  /**\n   * ### .above(value)\n   *\n   * Asserts that the target is greater than `value`.\n   *\n   *     expect(10).to.be.above(5);\n   *\n   * Can also be used in conjunction with `length` to\n   * assert a minimum length. The benefit being a\n   * more informative error message than if the length\n   * was supplied directly.\n   *\n   *     expect('foo').to.have.length.above(2);\n   *     expect([ 1, 2, 3 ]).to.have.length.above(2);\n   *\n   * @name above\n   * @alias gt\n   * @alias greaterThan\n   * @param {Number} value\n   * @param {String} message _optional_\n   * @namespace BDD\n   * @api public\n   */\n\n  function assertAbove (n, msg) {\n    if (msg) flag(this, 'message', msg);\n    var obj = flag(this, 'object');\n    if (flag(this, 'doLength')) {\n      new Assertion(obj, msg).to.have.property('length');\n      var len = obj.length;\n      this.assert(\n          len > n\n        , 'expected #{this} to have a length above #{exp} but got #{act}'\n        , 'expected #{this} to not have a length above #{exp}'\n        , n\n        , len\n      );\n    } else {\n      this.assert(\n          obj > n\n        , 'expected #{this} to be above ' + n\n        , 'expected #{this} to be at most ' + n\n      );\n    }\n  }\n\n  Assertion.addMethod('above', assertAbove);\n  Assertion.addMethod('gt', assertAbove);\n  Assertion.addMethod('greaterThan', assertAbove);\n\n  /**\n   * ### .least(value)\n   *\n   * Asserts that the target is greater than or equal to `value`.\n   *\n   *     expect(10).to.be.at.least(10);\n   *\n   * Can also be used in conjunction with `length` to\n   * assert a minimum length. The benefit being a\n   * more informative error message than if the length\n   * was supplied directly.\n   *\n   *     expect('foo').to.have.length.of.at.least(2);\n   *     expect([ 1, 2, 3 ]).to.have.length.of.at.least(3);\n   *\n   * @name least\n   * @alias gte\n   * @param {Number} value\n   * @param {String} message _optional_\n   * @namespace BDD\n   * @api public\n   */\n\n  function assertLeast (n, msg) {\n    if (msg) flag(this, 'message', msg);\n    var obj = flag(this, 'object');\n    if (flag(this, 'doLength')) {\n      new Assertion(obj, msg).to.have.property('length');\n      var len = obj.length;\n      this.assert(\n          len >= n\n        , 'expected #{this} to have a length at least #{exp} but got #{act}'\n        , 'expected #{this} to have a length below #{exp}'\n        , n\n        , len\n      );\n    } else {\n      this.assert(\n          obj >= n\n        , 'expected #{this} to be at least ' + n\n        , 'expected #{this} to be below ' + n\n      );\n    }\n  }\n\n  Assertion.addMethod('least', assertLeast);\n  Assertion.addMethod('gte', assertLeast);\n\n  /**\n   * ### .below(value)\n   *\n   * Asserts that the target is less than `value`.\n   *\n   *     expect(5).to.be.below(10);\n   *\n   * Can also be used in conjunction with `length` to\n   * assert a maximum length. The benefit being a\n   * more informative error message than if the length\n   * was supplied directly.\n   *\n   *     expect('foo').to.have.length.below(4);\n   *     expect([ 1, 2, 3 ]).to.have.length.below(4);\n   *\n   * @name below\n   * @alias lt\n   * @alias lessThan\n   * @param {Number} value\n   * @param {String} message _optional_\n   * @namespace BDD\n   * @api public\n   */\n\n  function assertBelow (n, msg) {\n    if (msg) flag(this, 'message', msg);\n    var obj = flag(this, 'object');\n    if (flag(this, 'doLength')) {\n      new Assertion(obj, msg).to.have.property('length');\n      var len = obj.length;\n      this.assert(\n          len < n\n        , 'expected #{this} to have a length below #{exp} but got #{act}'\n        , 'expected #{this} to not have a length below #{exp}'\n        , n\n        , len\n      );\n    } else {\n      this.assert(\n          obj < n\n        , 'expected #{this} to be below ' + n\n        , 'expected #{this} to be at least ' + n\n      );\n    }\n  }\n\n  Assertion.addMethod('below', assertBelow);\n  Assertion.addMethod('lt', assertBelow);\n  Assertion.addMethod('lessThan', assertBelow);\n\n  /**\n   * ### .most(value)\n   *\n   * Asserts that the target is less than or equal to `value`.\n   *\n   *     expect(5).to.be.at.most(5);\n   *\n   * Can also be used in conjunction with `length` to\n   * assert a maximum length. The benefit being a\n   * more informative error message than if the length\n   * was supplied directly.\n   *\n   *     expect('foo').to.have.length.of.at.most(4);\n   *     expect([ 1, 2, 3 ]).to.have.length.of.at.most(3);\n   *\n   * @name most\n   * @alias lte\n   * @param {Number} value\n   * @param {String} message _optional_\n   * @namespace BDD\n   * @api public\n   */\n\n  function assertMost (n, msg) {\n    if (msg) flag(this, 'message', msg);\n    var obj = flag(this, 'object');\n    if (flag(this, 'doLength')) {\n      new Assertion(obj, msg).to.have.property('length');\n      var len = obj.length;\n      this.assert(\n          len <= n\n        , 'expected #{this} to have a length at most #{exp} but got #{act}'\n        , 'expected #{this} to have a length above #{exp}'\n        , n\n        , len\n      );\n    } else {\n      this.assert(\n          obj <= n\n        , 'expected #{this} to be at most ' + n\n        , 'expected #{this} to be above ' + n\n      );\n    }\n  }\n\n  Assertion.addMethod('most', assertMost);\n  Assertion.addMethod('lte', assertMost);\n\n  /**\n   * ### .within(start, finish)\n   *\n   * Asserts that the target is within a range.\n   *\n   *     expect(7).to.be.within(5,10);\n   *\n   * Can also be used in conjunction with `length` to\n   * assert a length range. The benefit being a\n   * more informative error message than if the length\n   * was supplied directly.\n   *\n   *     expect('foo').to.have.length.within(2,4);\n   *     expect([ 1, 2, 3 ]).to.have.length.within(2,4);\n   *\n   * @name within\n   * @param {Number} start lowerbound inclusive\n   * @param {Number} finish upperbound inclusive\n   * @param {String} message _optional_\n   * @namespace BDD\n   * @api public\n   */\n\n  Assertion.addMethod('within', function (start, finish, msg) {\n    if (msg) flag(this, 'message', msg);\n    var obj = flag(this, 'object')\n      , range = start + '..' + finish;\n    if (flag(this, 'doLength')) {\n      new Assertion(obj, msg).to.have.property('length');\n      var len = obj.length;\n      this.assert(\n          len >= start && len <= finish\n        , 'expected #{this} to have a length within ' + range\n        , 'expected #{this} to not have a length within ' + range\n      );\n    } else {\n      this.assert(\n          obj >= start && obj <= finish\n        , 'expected #{this} to be within ' + range\n        , 'expected #{this} to not be within ' + range\n      );\n    }\n  });\n\n  /**\n   * ### .instanceof(constructor)\n   *\n   * Asserts that the target is an instance of `constructor`.\n   *\n   *     var Tea = function (name) { this.name = name; }\n   *       , Chai = new Tea('chai');\n   *\n   *     expect(Chai).to.be.an.instanceof(Tea);\n   *     expect([ 1, 2, 3 ]).to.be.instanceof(Array);\n   *\n   * @name instanceof\n   * @param {Constructor} constructor\n   * @param {String} message _optional_\n   * @alias instanceOf\n   * @namespace BDD\n   * @api public\n   */\n\n  function assertInstanceOf (constructor, msg) {\n    if (msg) flag(this, 'message', msg);\n    var name = _.getName(constructor);\n    this.assert(\n        flag(this, 'object') instanceof constructor\n      , 'expected #{this} to be an instance of ' + name\n      , 'expected #{this} to not be an instance of ' + name\n    );\n  };\n\n  Assertion.addMethod('instanceof', assertInstanceOf);\n  Assertion.addMethod('instanceOf', assertInstanceOf);\n\n  /**\n   * ### .property(name, [value])\n   *\n   * Asserts that the target has a property `name`, optionally asserting that\n   * the value of that property is strictly equal to  `value`.\n   * If the `deep` flag is set, you can use dot- and bracket-notation for deep\n   * references into objects and arrays.\n   *\n   *     // simple referencing\n   *     var obj = { foo: 'bar' };\n   *     expect(obj).to.have.property('foo');\n   *     expect(obj).to.have.property('foo', 'bar');\n   *\n   *     // deep referencing\n   *     var deepObj = {\n   *         green: { tea: 'matcha' }\n   *       , teas: [ 'chai', 'matcha', { tea: 'konacha' } ]\n   *     };\n   *\n   *     expect(deepObj).to.have.deep.property('green.tea', 'matcha');\n   *     expect(deepObj).to.have.deep.property('teas[1]', 'matcha');\n   *     expect(deepObj).to.have.deep.property('teas[2].tea', 'konacha');\n   *\n   * You can also use an array as the starting point of a `deep.property`\n   * assertion, or traverse nested arrays.\n   *\n   *     var arr = [\n   *         [ 'chai', 'matcha', 'konacha' ]\n   *       , [ { tea: 'chai' }\n   *         , { tea: 'matcha' }\n   *         , { tea: 'konacha' } ]\n   *     ];\n   *\n   *     expect(arr).to.have.deep.property('[0][1]', 'matcha');\n   *     expect(arr).to.have.deep.property('[1][2].tea', 'konacha');\n   *\n   * Furthermore, `property` changes the subject of the assertion\n   * to be the value of that property from the original object. This\n   * permits for further chainable assertions on that property.\n   *\n   *     expect(obj).to.have.property('foo')\n   *       .that.is.a('string');\n   *     expect(deepObj).to.have.property('green')\n   *       .that.is.an('object')\n   *       .that.deep.equals({ tea: 'matcha' });\n   *     expect(deepObj).to.have.property('teas')\n   *       .that.is.an('array')\n   *       .with.deep.property('[2]')\n   *         .that.deep.equals({ tea: 'konacha' });\n   *\n   * Note that dots and bracket in `name` must be backslash-escaped when\n   * the `deep` flag is set, while they must NOT be escaped when the `deep`\n   * flag is not set.\n   *\n   *     // simple referencing\n   *     var css = { '.link[target]': 42 };\n   *     expect(css).to.have.property('.link[target]', 42);\n   *\n   *     // deep referencing\n   *     var deepCss = { '.link': { '[target]': 42 }};\n   *     expect(deepCss).to.have.deep.property('\\\\.link.\\\\[target\\\\]', 42);\n   *\n   * @name property\n   * @alias deep.property\n   * @param {String} name\n   * @param {Mixed} value (optional)\n   * @param {String} message _optional_\n   * @returns value of property for chaining\n   * @namespace BDD\n   * @api public\n   */\n\n  Assertion.addMethod('property', function (name, val, msg) {\n    if (msg) flag(this, 'message', msg);\n\n    var isDeep = !!flag(this, 'deep')\n      , descriptor = isDeep ? 'deep property ' : 'property '\n      , negate = flag(this, 'negate')\n      , obj = flag(this, 'object')\n      , pathInfo = isDeep ? _.getPathInfo(name, obj) : null\n      , hasProperty = isDeep\n        ? pathInfo.exists\n        : _.hasProperty(name, obj)\n      , value = isDeep\n        ? pathInfo.value\n        : obj[name];\n\n    if (negate && arguments.length > 1) {\n      if (undefined === value) {\n        msg = (msg != null) ? msg + ': ' : '';\n        throw new Error(msg + _.inspect(obj) + ' has no ' + descriptor + _.inspect(name));\n      }\n    } else {\n      this.assert(\n          hasProperty\n        , 'expected #{this} to have a ' + descriptor + _.inspect(name)\n        , 'expected #{this} to not have ' + descriptor + _.inspect(name));\n    }\n\n    if (arguments.length > 1) {\n      this.assert(\n          val === value\n        , 'expected #{this} to have a ' + descriptor + _.inspect(name) + ' of #{exp}, but got #{act}'\n        , 'expected #{this} to not have a ' + descriptor + _.inspect(name) + ' of #{act}'\n        , val\n        , value\n      );\n    }\n\n    flag(this, 'object', value);\n  });\n\n\n  /**\n   * ### .ownProperty(name)\n   *\n   * Asserts that the target has an own property `name`.\n   *\n   *     expect('test').to.have.ownProperty('length');\n   *\n   * @name ownProperty\n   * @alias haveOwnProperty\n   * @param {String} name\n   * @param {String} message _optional_\n   * @namespace BDD\n   * @api public\n   */\n\n  function assertOwnProperty (name, msg) {\n    if (msg) flag(this, 'message', msg);\n    var obj = flag(this, 'object');\n    this.assert(\n        obj.hasOwnProperty(name)\n      , 'expected #{this} to have own property ' + _.inspect(name)\n      , 'expected #{this} to not have own property ' + _.inspect(name)\n    );\n  }\n\n  Assertion.addMethod('ownProperty', assertOwnProperty);\n  Assertion.addMethod('haveOwnProperty', assertOwnProperty);\n\n  /**\n   * ### .ownPropertyDescriptor(name[, descriptor[, message]])\n   *\n   * Asserts that the target has an own property descriptor `name`, that optionally matches `descriptor`.\n   *\n   *     expect('test').to.have.ownPropertyDescriptor('length');\n   *     expect('test').to.have.ownPropertyDescriptor('length', { enumerable: false, configurable: false, writable: false, value: 4 });\n   *     expect('test').not.to.have.ownPropertyDescriptor('length', { enumerable: false, configurable: false, writable: false, value: 3 });\n   *     expect('test').ownPropertyDescriptor('length').to.have.property('enumerable', false);\n   *     expect('test').ownPropertyDescriptor('length').to.have.keys('value');\n   *\n   * @name ownPropertyDescriptor\n   * @alias haveOwnPropertyDescriptor\n   * @param {String} name\n   * @param {Object} descriptor _optional_\n   * @param {String} message _optional_\n   * @namespace BDD\n   * @api public\n   */\n\n  function assertOwnPropertyDescriptor (name, descriptor, msg) {\n    if (typeof descriptor === 'string') {\n      msg = descriptor;\n      descriptor = null;\n    }\n    if (msg) flag(this, 'message', msg);\n    var obj = flag(this, 'object');\n    var actualDescriptor = Object.getOwnPropertyDescriptor(Object(obj), name);\n    if (actualDescriptor && descriptor) {\n      this.assert(\n          _.eql(descriptor, actualDescriptor)\n        , 'expected the own property descriptor for ' + _.inspect(name) + ' on #{this} to match ' + _.inspect(descriptor) + ', got ' + _.inspect(actualDescriptor)\n        , 'expected the own property descriptor for ' + _.inspect(name) + ' on #{this} to not match ' + _.inspect(descriptor)\n        , descriptor\n        , actualDescriptor\n        , true\n      );\n    } else {\n      this.assert(\n          actualDescriptor\n        , 'expected #{this} to have an own property descriptor for ' + _.inspect(name)\n        , 'expected #{this} to not have an own property descriptor for ' + _.inspect(name)\n      );\n    }\n    flag(this, 'object', actualDescriptor);\n  }\n\n  Assertion.addMethod('ownPropertyDescriptor', assertOwnPropertyDescriptor);\n  Assertion.addMethod('haveOwnPropertyDescriptor', assertOwnPropertyDescriptor);\n\n  /**\n   * ### .length\n   *\n   * Sets the `doLength` flag later used as a chain precursor to a value\n   * comparison for the `length` property.\n   *\n   *     expect('foo').to.have.length.above(2);\n   *     expect([ 1, 2, 3 ]).to.have.length.above(2);\n   *     expect('foo').to.have.length.below(4);\n   *     expect([ 1, 2, 3 ]).to.have.length.below(4);\n   *     expect('foo').to.have.length.within(2,4);\n   *     expect([ 1, 2, 3 ]).to.have.length.within(2,4);\n   *\n   * *Deprecation notice:* Using `length` as an assertion will be deprecated\n   * in version 2.4.0 and removed in 3.0.0. Code using the old style of\n   * asserting for `length` property value using `length(value)` should be\n   * switched to use `lengthOf(value)` instead.\n   *\n   * @name length\n   * @namespace BDD\n   * @api public\n   */\n\n  /**\n   * ### .lengthOf(value[, message])\n   *\n   * Asserts that the target's `length` property has\n   * the expected value.\n   *\n   *     expect([ 1, 2, 3]).to.have.lengthOf(3);\n   *     expect('foobar').to.have.lengthOf(6);\n   *\n   * @name lengthOf\n   * @param {Number} length\n   * @param {String} message _optional_\n   * @namespace BDD\n   * @api public\n   */\n\n  function assertLengthChain () {\n    flag(this, 'doLength', true);\n  }\n\n  function assertLength (n, msg) {\n    if (msg) flag(this, 'message', msg);\n    var obj = flag(this, 'object');\n    new Assertion(obj, msg).to.have.property('length');\n    var len = obj.length;\n\n    this.assert(\n        len == n\n      , 'expected #{this} to have a length of #{exp} but got #{act}'\n      , 'expected #{this} to not have a length of #{act}'\n      , n\n      , len\n    );\n  }\n\n  Assertion.addChainableMethod('length', assertLength, assertLengthChain);\n  Assertion.addMethod('lengthOf', assertLength);\n\n  /**\n   * ### .match(regexp)\n   *\n   * Asserts that the target matches a regular expression.\n   *\n   *     expect('foobar').to.match(/^foo/);\n   *\n   * @name match\n   * @alias matches\n   * @param {RegExp} RegularExpression\n   * @param {String} message _optional_\n   * @namespace BDD\n   * @api public\n   */\n  function assertMatch(re, msg) {\n    if (msg) flag(this, 'message', msg);\n    var obj = flag(this, 'object');\n    this.assert(\n        re.exec(obj)\n      , 'expected #{this} to match ' + re\n      , 'expected #{this} not to match ' + re\n    );\n  }\n\n  Assertion.addMethod('match', assertMatch);\n  Assertion.addMethod('matches', assertMatch);\n\n  /**\n   * ### .string(string)\n   *\n   * Asserts that the string target contains another string.\n   *\n   *     expect('foobar').to.have.string('bar');\n   *\n   * @name string\n   * @param {String} string\n   * @param {String} message _optional_\n   * @namespace BDD\n   * @api public\n   */\n\n  Assertion.addMethod('string', function (str, msg) {\n    if (msg) flag(this, 'message', msg);\n    var obj = flag(this, 'object');\n    new Assertion(obj, msg).is.a('string');\n\n    this.assert(\n        ~obj.indexOf(str)\n      , 'expected #{this} to contain ' + _.inspect(str)\n      , 'expected #{this} to not contain ' + _.inspect(str)\n    );\n  });\n\n\n  /**\n   * ### .keys(key1, [key2], [...])\n   *\n   * Asserts that the target contains any or all of the passed-in keys.\n   * Use in combination with `any`, `all`, `contains`, or `have` will affect\n   * what will pass.\n   *\n   * When used in conjunction with `any`, at least one key that is passed\n   * in must exist in the target object. This is regardless whether or not\n   * the `have` or `contain` qualifiers are used. Note, either `any` or `all`\n   * should be used in the assertion. If neither are used, the assertion is\n   * defaulted to `all`.\n   *\n   * When both `all` and `contain` are used, the target object must have at\n   * least all of the passed-in keys but may have more keys not listed.\n   *\n   * When both `all` and `have` are used, the target object must both contain\n   * all of the passed-in keys AND the number of keys in the target object must\n   * match the number of keys passed in (in other words, a target object must\n   * have all and only all of the passed-in keys).\n   *\n   *     expect({ foo: 1, bar: 2 }).to.have.any.keys('foo', 'baz');\n   *     expect({ foo: 1, bar: 2 }).to.have.any.keys('foo');\n   *     expect({ foo: 1, bar: 2 }).to.contain.any.keys('bar', 'baz');\n   *     expect({ foo: 1, bar: 2 }).to.contain.any.keys(['foo']);\n   *     expect({ foo: 1, bar: 2 }).to.contain.any.keys({'foo': 6});\n   *     expect({ foo: 1, bar: 2 }).to.have.all.keys(['bar', 'foo']);\n   *     expect({ foo: 1, bar: 2 }).to.have.all.keys({'bar': 6, 'foo': 7});\n   *     expect({ foo: 1, bar: 2, baz: 3 }).to.contain.all.keys(['bar', 'foo']);\n   *     expect({ foo: 1, bar: 2, baz: 3 }).to.contain.all.keys({'bar': 6});\n   *\n   *\n   * @name keys\n   * @alias key\n   * @param {...String|Array|Object} keys\n   * @namespace BDD\n   * @api public\n   */\n\n  function assertKeys (keys) {\n    var obj = flag(this, 'object')\n      , str\n      , ok = true\n      , mixedArgsMsg = 'keys must be given single argument of Array|Object|String, or multiple String arguments';\n\n    switch (_.type(keys)) {\n      case \"array\":\n        if (arguments.length > 1) throw (new Error(mixedArgsMsg));\n        break;\n      case \"object\":\n        if (arguments.length > 1) throw (new Error(mixedArgsMsg));\n        keys = Object.keys(keys);\n        break;\n      default:\n        keys = Array.prototype.slice.call(arguments);\n    }\n\n    if (!keys.length) throw new Error('keys required');\n\n    var actual = Object.keys(obj)\n      , expected = keys\n      , len = keys.length\n      , any = flag(this, 'any')\n      , all = flag(this, 'all');\n\n    if (!any && !all) {\n      all = true;\n    }\n\n    // Has any\n    if (any) {\n      var intersection = expected.filter(function(key) {\n        return ~actual.indexOf(key);\n      });\n      ok = intersection.length > 0;\n    }\n\n    // Has all\n    if (all) {\n      ok = keys.every(function(key){\n        return ~actual.indexOf(key);\n      });\n      if (!flag(this, 'negate') && !flag(this, 'contains')) {\n        ok = ok && keys.length == actual.length;\n      }\n    }\n\n    // Key string\n    if (len > 1) {\n      keys = keys.map(function(key){\n        return _.inspect(key);\n      });\n      var last = keys.pop();\n      if (all) {\n        str = keys.join(', ') + ', and ' + last;\n      }\n      if (any) {\n        str = keys.join(', ') + ', or ' + last;\n      }\n    } else {\n      str = _.inspect(keys[0]);\n    }\n\n    // Form\n    str = (len > 1 ? 'keys ' : 'key ') + str;\n\n    // Have / include\n    str = (flag(this, 'contains') ? 'contain ' : 'have ') + str;\n\n    // Assertion\n    this.assert(\n        ok\n      , 'expected #{this} to ' + str\n      , 'expected #{this} to not ' + str\n      , expected.slice(0).sort()\n      , actual.sort()\n      , true\n    );\n  }\n\n  Assertion.addMethod('keys', assertKeys);\n  Assertion.addMethod('key', assertKeys);\n\n  /**\n   * ### .throw(constructor)\n   *\n   * Asserts that the function target will throw a specific error, or specific type of error\n   * (as determined using `instanceof`), optionally with a RegExp or string inclusion test\n   * for the error's message.\n   *\n   *     var err = new ReferenceError('This is a bad function.');\n   *     var fn = function () { throw err; }\n   *     expect(fn).to.throw(ReferenceError);\n   *     expect(fn).to.throw(Error);\n   *     expect(fn).to.throw(/bad function/);\n   *     expect(fn).to.not.throw('good function');\n   *     expect(fn).to.throw(ReferenceError, /bad function/);\n   *     expect(fn).to.throw(err);\n   *\n   * Please note that when a throw expectation is negated, it will check each\n   * parameter independently, starting with error constructor type. The appropriate way\n   * to check for the existence of a type of error but for a message that does not match\n   * is to use `and`.\n   *\n   *     expect(fn).to.throw(ReferenceError)\n   *        .and.not.throw(/good function/);\n   *\n   * @name throw\n   * @alias throws\n   * @alias Throw\n   * @param {ErrorConstructor} constructor\n   * @param {String|RegExp} expected error message\n   * @param {String} message _optional_\n   * @see https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Error#Error_types\n   * @returns error for chaining (null if no error)\n   * @namespace BDD\n   * @api public\n   */\n\n  function assertThrows (constructor, errMsg, msg) {\n    if (msg) flag(this, 'message', msg);\n    var obj = flag(this, 'object');\n    new Assertion(obj, msg).is.a('function');\n\n    var thrown = false\n      , desiredError = null\n      , name = null\n      , thrownError = null;\n\n    if (arguments.length === 0) {\n      errMsg = null;\n      constructor = null;\n    } else if (constructor && (constructor instanceof RegExp || 'string' === typeof constructor)) {\n      errMsg = constructor;\n      constructor = null;\n    } else if (constructor && constructor instanceof Error) {\n      desiredError = constructor;\n      constructor = null;\n      errMsg = null;\n    } else if (typeof constructor === 'function') {\n      name = constructor.prototype.name;\n      if (!name || (name === 'Error' && constructor !== Error)) {\n        name = constructor.name || (new constructor()).name;\n      }\n    } else {\n      constructor = null;\n    }\n\n    try {\n      obj();\n    } catch (err) {\n      // first, check desired error\n      if (desiredError) {\n        this.assert(\n            err === desiredError\n          , 'expected #{this} to throw #{exp} but #{act} was thrown'\n          , 'expected #{this} to not throw #{exp}'\n          , (desiredError instanceof Error ? desiredError.toString() : desiredError)\n          , (err instanceof Error ? err.toString() : err)\n        );\n\n        flag(this, 'object', err);\n        return this;\n      }\n\n      // next, check constructor\n      if (constructor) {\n        this.assert(\n            err instanceof constructor\n          , 'expected #{this} to throw #{exp} but #{act} was thrown'\n          , 'expected #{this} to not throw #{exp} but #{act} was thrown'\n          , name\n          , (err instanceof Error ? err.toString() : err)\n        );\n\n        if (!errMsg) {\n          flag(this, 'object', err);\n          return this;\n        }\n      }\n\n      // next, check message\n      var message = 'error' === _.type(err) && \"message\" in err\n        ? err.message\n        : '' + err;\n\n      if ((message != null) && errMsg && errMsg instanceof RegExp) {\n        this.assert(\n            errMsg.exec(message)\n          , 'expected #{this} to throw error matching #{exp} but got #{act}'\n          , 'expected #{this} to throw error not matching #{exp}'\n          , errMsg\n          , message\n        );\n\n        flag(this, 'object', err);\n        return this;\n      } else if ((message != null) && errMsg && 'string' === typeof errMsg) {\n        this.assert(\n            ~message.indexOf(errMsg)\n          , 'expected #{this} to throw error including #{exp} but got #{act}'\n          , 'expected #{this} to throw error not including #{act}'\n          , errMsg\n          , message\n        );\n\n        flag(this, 'object', err);\n        return this;\n      } else {\n        thrown = true;\n        thrownError = err;\n      }\n    }\n\n    var actuallyGot = ''\n      , expectedThrown = name !== null\n        ? name\n        : desiredError\n          ? '#{exp}' //_.inspect(desiredError)\n          : 'an error';\n\n    if (thrown) {\n      actuallyGot = ' but #{act} was thrown'\n    }\n\n    this.assert(\n        thrown === true\n      , 'expected #{this} to throw ' + expectedThrown + actuallyGot\n      , 'expected #{this} to not throw ' + expectedThrown + actuallyGot\n      , (desiredError instanceof Error ? desiredError.toString() : desiredError)\n      , (thrownError instanceof Error ? thrownError.toString() : thrownError)\n    );\n\n    flag(this, 'object', thrownError);\n  };\n\n  Assertion.addMethod('throw', assertThrows);\n  Assertion.addMethod('throws', assertThrows);\n  Assertion.addMethod('Throw', assertThrows);\n\n  /**\n   * ### .respondTo(method)\n   *\n   * Asserts that the object or class target will respond to a method.\n   *\n   *     Klass.prototype.bar = function(){};\n   *     expect(Klass).to.respondTo('bar');\n   *     expect(obj).to.respondTo('bar');\n   *\n   * To check if a constructor will respond to a static function,\n   * set the `itself` flag.\n   *\n   *     Klass.baz = function(){};\n   *     expect(Klass).itself.to.respondTo('baz');\n   *\n   * @name respondTo\n   * @alias respondsTo\n   * @param {String} method\n   * @param {String} message _optional_\n   * @namespace BDD\n   * @api public\n   */\n\n  function respondTo (method, msg) {\n    if (msg) flag(this, 'message', msg);\n    var obj = flag(this, 'object')\n      , itself = flag(this, 'itself')\n      , context = ('function' === _.type(obj) && !itself)\n        ? obj.prototype[method]\n        : obj[method];\n\n    this.assert(\n        'function' === typeof context\n      , 'expected #{this} to respond to ' + _.inspect(method)\n      , 'expected #{this} to not respond to ' + _.inspect(method)\n    );\n  }\n\n  Assertion.addMethod('respondTo', respondTo);\n  Assertion.addMethod('respondsTo', respondTo);\n\n  /**\n   * ### .itself\n   *\n   * Sets the `itself` flag, later used by the `respondTo` assertion.\n   *\n   *     function Foo() {}\n   *     Foo.bar = function() {}\n   *     Foo.prototype.baz = function() {}\n   *\n   *     expect(Foo).itself.to.respondTo('bar');\n   *     expect(Foo).itself.not.to.respondTo('baz');\n   *\n   * @name itself\n   * @namespace BDD\n   * @api public\n   */\n\n  Assertion.addProperty('itself', function () {\n    flag(this, 'itself', true);\n  });\n\n  /**\n   * ### .satisfy(method)\n   *\n   * Asserts that the target passes a given truth test.\n   *\n   *     expect(1).to.satisfy(function(num) { return num > 0; });\n   *\n   * @name satisfy\n   * @alias satisfies\n   * @param {Function} matcher\n   * @param {String} message _optional_\n   * @namespace BDD\n   * @api public\n   */\n\n  function satisfy (matcher, msg) {\n    if (msg) flag(this, 'message', msg);\n    var obj = flag(this, 'object');\n    var result = matcher(obj);\n    this.assert(\n        result\n      , 'expected #{this} to satisfy ' + _.objDisplay(matcher)\n      , 'expected #{this} to not satisfy' + _.objDisplay(matcher)\n      , this.negate ? false : true\n      , result\n    );\n  }\n\n  Assertion.addMethod('satisfy', satisfy);\n  Assertion.addMethod('satisfies', satisfy);\n\n  /**\n   * ### .closeTo(expected, delta)\n   *\n   * Asserts that the target is equal `expected`, to within a +/- `delta` range.\n   *\n   *     expect(1.5).to.be.closeTo(1, 0.5);\n   *\n   * @name closeTo\n   * @alias approximately\n   * @param {Number} expected\n   * @param {Number} delta\n   * @param {String} message _optional_\n   * @namespace BDD\n   * @api public\n   */\n\n  function closeTo(expected, delta, msg) {\n    if (msg) flag(this, 'message', msg);\n    var obj = flag(this, 'object');\n\n    new Assertion(obj, msg).is.a('number');\n    if (_.type(expected) !== 'number' || _.type(delta) !== 'number') {\n      throw new Error('the arguments to closeTo or approximately must be numbers');\n    }\n\n    this.assert(\n        Math.abs(obj - expected) <= delta\n      , 'expected #{this} to be close to ' + expected + ' +/- ' + delta\n      , 'expected #{this} not to be close to ' + expected + ' +/- ' + delta\n    );\n  }\n\n  Assertion.addMethod('closeTo', closeTo);\n  Assertion.addMethod('approximately', closeTo);\n\n  function isSubsetOf(subset, superset, cmp) {\n    return subset.every(function(elem) {\n      if (!cmp) return superset.indexOf(elem) !== -1;\n\n      return superset.some(function(elem2) {\n        return cmp(elem, elem2);\n      });\n    })\n  }\n\n  /**\n   * ### .members(set)\n   *\n   * Asserts that the target is a superset of `set`,\n   * or that the target and `set` have the same strictly-equal (===) members.\n   * Alternately, if the `deep` flag is set, set members are compared for deep\n   * equality.\n   *\n   *     expect([1, 2, 3]).to.include.members([3, 2]);\n   *     expect([1, 2, 3]).to.not.include.members([3, 2, 8]);\n   *\n   *     expect([4, 2]).to.have.members([2, 4]);\n   *     expect([5, 2]).to.not.have.members([5, 2, 1]);\n   *\n   *     expect([{ id: 1 }]).to.deep.include.members([{ id: 1 }]);\n   *\n   * @name members\n   * @param {Array} set\n   * @param {String} message _optional_\n   * @namespace BDD\n   * @api public\n   */\n\n  Assertion.addMethod('members', function (subset, msg) {\n    if (msg) flag(this, 'message', msg);\n    var obj = flag(this, 'object');\n\n    new Assertion(obj).to.be.an('array');\n    new Assertion(subset).to.be.an('array');\n\n    var cmp = flag(this, 'deep') ? _.eql : undefined;\n\n    if (flag(this, 'contains')) {\n      return this.assert(\n          isSubsetOf(subset, obj, cmp)\n        , 'expected #{this} to be a superset of #{act}'\n        , 'expected #{this} to not be a superset of #{act}'\n        , obj\n        , subset\n      );\n    }\n\n    this.assert(\n        isSubsetOf(obj, subset, cmp) && isSubsetOf(subset, obj, cmp)\n        , 'expected #{this} to have the same members as #{act}'\n        , 'expected #{this} to not have the same members as #{act}'\n        , obj\n        , subset\n    );\n  });\n\n  /**\n   * ### .oneOf(list)\n   *\n   * Assert that a value appears somewhere in the top level of array `list`.\n   *\n   *     expect('a').to.be.oneOf(['a', 'b', 'c']);\n   *     expect(9).to.not.be.oneOf(['z']);\n   *     expect([3]).to.not.be.oneOf([1, 2, [3]]);\n   *\n   *     var three = [3];\n   *     // for object-types, contents are not compared\n   *     expect(three).to.not.be.oneOf([1, 2, [3]]);\n   *     // comparing references works\n   *     expect(three).to.be.oneOf([1, 2, three]);\n   *\n   * @name oneOf\n   * @param {Array<*>} list\n   * @param {String} message _optional_\n   * @namespace BDD\n   * @api public\n   */\n\n  function oneOf (list, msg) {\n    if (msg) flag(this, 'message', msg);\n    var expected = flag(this, 'object');\n    new Assertion(list).to.be.an('array');\n\n    this.assert(\n        list.indexOf(expected) > -1\n      , 'expected #{this} to be one of #{exp}'\n      , 'expected #{this} to not be one of #{exp}'\n      , list\n      , expected\n    );\n  }\n\n  Assertion.addMethod('oneOf', oneOf);\n\n\n  /**\n   * ### .change(function)\n   *\n   * Asserts that a function changes an object property\n   *\n   *     var obj = { val: 10 };\n   *     var fn = function() { obj.val += 3 };\n   *     var noChangeFn = function() { return 'foo' + 'bar'; }\n   *     expect(fn).to.change(obj, 'val');\n   *     expect(noChangeFn).to.not.change(obj, 'val')\n   *\n   * @name change\n   * @alias changes\n   * @alias Change\n   * @param {String} object\n   * @param {String} property name\n   * @param {String} message _optional_\n   * @namespace BDD\n   * @api public\n   */\n\n  function assertChanges (object, prop, msg) {\n    if (msg) flag(this, 'message', msg);\n    var fn = flag(this, 'object');\n    new Assertion(object, msg).to.have.property(prop);\n    new Assertion(fn).is.a('function');\n\n    var initial = object[prop];\n    fn();\n\n    this.assert(\n      initial !== object[prop]\n      , 'expected .' + prop + ' to change'\n      , 'expected .' + prop + ' to not change'\n    );\n  }\n\n  Assertion.addChainableMethod('change', assertChanges);\n  Assertion.addChainableMethod('changes', assertChanges);\n\n  /**\n   * ### .increase(function)\n   *\n   * Asserts that a function increases an object property\n   *\n   *     var obj = { val: 10 };\n   *     var fn = function() { obj.val = 15 };\n   *     expect(fn).to.increase(obj, 'val');\n   *\n   * @name increase\n   * @alias increases\n   * @alias Increase\n   * @param {String} object\n   * @param {String} property name\n   * @param {String} message _optional_\n   * @namespace BDD\n   * @api public\n   */\n\n  function assertIncreases (object, prop, msg) {\n    if (msg) flag(this, 'message', msg);\n    var fn = flag(this, 'object');\n    new Assertion(object, msg).to.have.property(prop);\n    new Assertion(fn).is.a('function');\n\n    var initial = object[prop];\n    fn();\n\n    this.assert(\n      object[prop] - initial > 0\n      , 'expected .' + prop + ' to increase'\n      , 'expected .' + prop + ' to not increase'\n    );\n  }\n\n  Assertion.addChainableMethod('increase', assertIncreases);\n  Assertion.addChainableMethod('increases', assertIncreases);\n\n  /**\n   * ### .decrease(function)\n   *\n   * Asserts that a function decreases an object property\n   *\n   *     var obj = { val: 10 };\n   *     var fn = function() { obj.val = 5 };\n   *     expect(fn).to.decrease(obj, 'val');\n   *\n   * @name decrease\n   * @alias decreases\n   * @alias Decrease\n   * @param {String} object\n   * @param {String} property name\n   * @param {String} message _optional_\n   * @namespace BDD\n   * @api public\n   */\n\n  function assertDecreases (object, prop, msg) {\n    if (msg) flag(this, 'message', msg);\n    var fn = flag(this, 'object');\n    new Assertion(object, msg).to.have.property(prop);\n    new Assertion(fn).is.a('function');\n\n    var initial = object[prop];\n    fn();\n\n    this.assert(\n      object[prop] - initial < 0\n      , 'expected .' + prop + ' to decrease'\n      , 'expected .' + prop + ' to not decrease'\n    );\n  }\n\n  Assertion.addChainableMethod('decrease', assertDecreases);\n  Assertion.addChainableMethod('decreases', assertDecreases);\n\n  /**\n   * ### .extensible\n   *\n   * Asserts that the target is extensible (can have new properties added to\n   * it).\n   *\n   *     var nonExtensibleObject = Object.preventExtensions({});\n   *     var sealedObject = Object.seal({});\n   *     var frozenObject = Object.freeze({});\n   *\n   *     expect({}).to.be.extensible;\n   *     expect(nonExtensibleObject).to.not.be.extensible;\n   *     expect(sealedObject).to.not.be.extensible;\n   *     expect(frozenObject).to.not.be.extensible;\n   *\n   * @name extensible\n   * @namespace BDD\n   * @api public\n   */\n\n  Assertion.addProperty('extensible', function() {\n    var obj = flag(this, 'object');\n\n    // In ES5, if the argument to this method is not an object (a primitive), then it will cause a TypeError.\n    // In ES6, a non-object argument will be treated as if it was a non-extensible ordinary object, simply return false.\n    // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/isExtensible\n    // The following provides ES6 behavior when a TypeError is thrown under ES5.\n\n    var isExtensible;\n\n    try {\n      isExtensible = Object.isExtensible(obj);\n    } catch (err) {\n      if (err instanceof TypeError) isExtensible = false;\n      else throw err;\n    }\n\n    this.assert(\n      isExtensible\n      , 'expected #{this} to be extensible'\n      , 'expected #{this} to not be extensible'\n    );\n  });\n\n  /**\n   * ### .sealed\n   *\n   * Asserts that the target is sealed (cannot have new properties added to it\n   * and its existing properties cannot be removed).\n   *\n   *     var sealedObject = Object.seal({});\n   *     var frozenObject = Object.freeze({});\n   *\n   *     expect(sealedObject).to.be.sealed;\n   *     expect(frozenObject).to.be.sealed;\n   *     expect({}).to.not.be.sealed;\n   *\n   * @name sealed\n   * @namespace BDD\n   * @api public\n   */\n\n  Assertion.addProperty('sealed', function() {\n    var obj = flag(this, 'object');\n\n    // In ES5, if the argument to this method is not an object (a primitive), then it will cause a TypeError.\n    // In ES6, a non-object argument will be treated as if it was a sealed ordinary object, simply return true.\n    // See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/isSealed\n    // The following provides ES6 behavior when a TypeError is thrown under ES5.\n\n    var isSealed;\n\n    try {\n      isSealed = Object.isSealed(obj);\n    } catch (err) {\n      if (err instanceof TypeError) isSealed = true;\n      else throw err;\n    }\n\n    this.assert(\n      isSealed\n      , 'expected #{this} to be sealed'\n      , 'expected #{this} to not be sealed'\n    );\n  });\n\n  /**\n   * ### .frozen\n   *\n   * Asserts that the target is frozen (cannot have new properties added to it\n   * and its existing properties cannot be modified).\n   *\n   *     var frozenObject = Object.freeze({});\n   *\n   *     expect(frozenObject).to.be.frozen;\n   *     expect({}).to.not.be.frozen;\n   *\n   * @name frozen\n   * @namespace BDD\n   * @api public\n   */\n\n  Assertion.addProperty('frozen', function() {\n    var obj = flag(this, 'object');\n\n    // In ES5, if the argument to this method is not an object (a primitive), then it will cause a TypeError.\n    // In ES6, a non-object argument will be treated as if it was a frozen ordinary object, simply return true.\n    // See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/isFrozen\n    // The following provides ES6 behavior when a TypeError is thrown under ES5.\n\n    var isFrozen;\n\n    try {\n      isFrozen = Object.isFrozen(obj);\n    } catch (err) {\n      if (err instanceof TypeError) isFrozen = true;\n      else throw err;\n    }\n\n    this.assert(\n      isFrozen\n      , 'expected #{this} to be frozen'\n      , 'expected #{this} to not be frozen'\n    );\n  });\n};\n\n},{}],6:[function(require,module,exports){\n/*!\n * chai\n * Copyright(c) 2011-2014 Jake Luer <jake@alogicalparadox.com>\n * MIT Licensed\n */\n\n\nmodule.exports = function (chai, util) {\n\n  /*!\n   * Chai dependencies.\n   */\n\n  var Assertion = chai.Assertion\n    , flag = util.flag;\n\n  /*!\n   * Module export.\n   */\n\n  /**\n   * ### assert(expression, message)\n   *\n   * Write your own test expressions.\n   *\n   *     assert('foo' !== 'bar', 'foo is not bar');\n   *     assert(Array.isArray([]), 'empty arrays are arrays');\n   *\n   * @param {Mixed} expression to test for truthiness\n   * @param {String} message to display on error\n   * @name assert\n   * @namespace Assert\n   * @api public\n   */\n\n  var assert = chai.assert = function (express, errmsg) {\n    var test = new Assertion(null, null, chai.assert);\n    test.assert(\n        express\n      , errmsg\n      , '[ negation message unavailable ]'\n    );\n  };\n\n  /**\n   * ### .fail(actual, expected, [message], [operator])\n   *\n   * Throw a failure. Node.js `assert` module-compatible.\n   *\n   * @name fail\n   * @param {Mixed} actual\n   * @param {Mixed} expected\n   * @param {String} message\n   * @param {String} operator\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.fail = function (actual, expected, message, operator) {\n    message = message || 'assert.fail()';\n    throw new chai.AssertionError(message, {\n        actual: actual\n      , expected: expected\n      , operator: operator\n    }, assert.fail);\n  };\n\n  /**\n   * ### .isOk(object, [message])\n   *\n   * Asserts that `object` is truthy.\n   *\n   *     assert.isOk('everything', 'everything is ok');\n   *     assert.isOk(false, 'this will fail');\n   *\n   * @name isOk\n   * @alias ok\n   * @param {Mixed} object to test\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.isOk = function (val, msg) {\n    new Assertion(val, msg).is.ok;\n  };\n\n  /**\n   * ### .isNotOk(object, [message])\n   *\n   * Asserts that `object` is falsy.\n   *\n   *     assert.isNotOk('everything', 'this will fail');\n   *     assert.isNotOk(false, 'this will pass');\n   *\n   * @name isNotOk\n   * @alias notOk\n   * @param {Mixed} object to test\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.isNotOk = function (val, msg) {\n    new Assertion(val, msg).is.not.ok;\n  };\n\n  /**\n   * ### .equal(actual, expected, [message])\n   *\n   * Asserts non-strict equality (`==`) of `actual` and `expected`.\n   *\n   *     assert.equal(3, '3', '== coerces values to strings');\n   *\n   * @name equal\n   * @param {Mixed} actual\n   * @param {Mixed} expected\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.equal = function (act, exp, msg) {\n    var test = new Assertion(act, msg, assert.equal);\n\n    test.assert(\n        exp == flag(test, 'object')\n      , 'expected #{this} to equal #{exp}'\n      , 'expected #{this} to not equal #{act}'\n      , exp\n      , act\n    );\n  };\n\n  /**\n   * ### .notEqual(actual, expected, [message])\n   *\n   * Asserts non-strict inequality (`!=`) of `actual` and `expected`.\n   *\n   *     assert.notEqual(3, 4, 'these numbers are not equal');\n   *\n   * @name notEqual\n   * @param {Mixed} actual\n   * @param {Mixed} expected\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.notEqual = function (act, exp, msg) {\n    var test = new Assertion(act, msg, assert.notEqual);\n\n    test.assert(\n        exp != flag(test, 'object')\n      , 'expected #{this} to not equal #{exp}'\n      , 'expected #{this} to equal #{act}'\n      , exp\n      , act\n    );\n  };\n\n  /**\n   * ### .strictEqual(actual, expected, [message])\n   *\n   * Asserts strict equality (`===`) of `actual` and `expected`.\n   *\n   *     assert.strictEqual(true, true, 'these booleans are strictly equal');\n   *\n   * @name strictEqual\n   * @param {Mixed} actual\n   * @param {Mixed} expected\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.strictEqual = function (act, exp, msg) {\n    new Assertion(act, msg).to.equal(exp);\n  };\n\n  /**\n   * ### .notStrictEqual(actual, expected, [message])\n   *\n   * Asserts strict inequality (`!==`) of `actual` and `expected`.\n   *\n   *     assert.notStrictEqual(3, '3', 'no coercion for strict equality');\n   *\n   * @name notStrictEqual\n   * @param {Mixed} actual\n   * @param {Mixed} expected\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.notStrictEqual = function (act, exp, msg) {\n    new Assertion(act, msg).to.not.equal(exp);\n  };\n\n  /**\n   * ### .deepEqual(actual, expected, [message])\n   *\n   * Asserts that `actual` is deeply equal to `expected`.\n   *\n   *     assert.deepEqual({ tea: 'green' }, { tea: 'green' });\n   *\n   * @name deepEqual\n   * @param {Mixed} actual\n   * @param {Mixed} expected\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.deepEqual = function (act, exp, msg) {\n    new Assertion(act, msg).to.eql(exp);\n  };\n\n  /**\n   * ### .notDeepEqual(actual, expected, [message])\n   *\n   * Assert that `actual` is not deeply equal to `expected`.\n   *\n   *     assert.notDeepEqual({ tea: 'green' }, { tea: 'jasmine' });\n   *\n   * @name notDeepEqual\n   * @param {Mixed} actual\n   * @param {Mixed} expected\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.notDeepEqual = function (act, exp, msg) {\n    new Assertion(act, msg).to.not.eql(exp);\n  };\n\n   /**\n   * ### .isAbove(valueToCheck, valueToBeAbove, [message])\n   *\n   * Asserts `valueToCheck` is strictly greater than (>) `valueToBeAbove`\n   *\n   *     assert.isAbove(5, 2, '5 is strictly greater than 2');\n   *\n   * @name isAbove\n   * @param {Mixed} valueToCheck\n   * @param {Mixed} valueToBeAbove\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.isAbove = function (val, abv, msg) {\n    new Assertion(val, msg).to.be.above(abv);\n  };\n\n   /**\n   * ### .isAtLeast(valueToCheck, valueToBeAtLeast, [message])\n   *\n   * Asserts `valueToCheck` is greater than or equal to (>=) `valueToBeAtLeast`\n   *\n   *     assert.isAtLeast(5, 2, '5 is greater or equal to 2');\n   *     assert.isAtLeast(3, 3, '3 is greater or equal to 3');\n   *\n   * @name isAtLeast\n   * @param {Mixed} valueToCheck\n   * @param {Mixed} valueToBeAtLeast\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.isAtLeast = function (val, atlst, msg) {\n    new Assertion(val, msg).to.be.least(atlst);\n  };\n\n   /**\n   * ### .isBelow(valueToCheck, valueToBeBelow, [message])\n   *\n   * Asserts `valueToCheck` is strictly less than (<) `valueToBeBelow`\n   *\n   *     assert.isBelow(3, 6, '3 is strictly less than 6');\n   *\n   * @name isBelow\n   * @param {Mixed} valueToCheck\n   * @param {Mixed} valueToBeBelow\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.isBelow = function (val, blw, msg) {\n    new Assertion(val, msg).to.be.below(blw);\n  };\n\n   /**\n   * ### .isAtMost(valueToCheck, valueToBeAtMost, [message])\n   *\n   * Asserts `valueToCheck` is less than or equal to (<=) `valueToBeAtMost`\n   *\n   *     assert.isAtMost(3, 6, '3 is less than or equal to 6');\n   *     assert.isAtMost(4, 4, '4 is less than or equal to 4');\n   *\n   * @name isAtMost\n   * @param {Mixed} valueToCheck\n   * @param {Mixed} valueToBeAtMost\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.isAtMost = function (val, atmst, msg) {\n    new Assertion(val, msg).to.be.most(atmst);\n  };\n\n  /**\n   * ### .isTrue(value, [message])\n   *\n   * Asserts that `value` is true.\n   *\n   *     var teaServed = true;\n   *     assert.isTrue(teaServed, 'the tea has been served');\n   *\n   * @name isTrue\n   * @param {Mixed} value\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.isTrue = function (val, msg) {\n    new Assertion(val, msg).is['true'];\n  };\n\n  /**\n   * ### .isNotTrue(value, [message])\n   *\n   * Asserts that `value` is not true.\n   *\n   *     var tea = 'tasty chai';\n   *     assert.isNotTrue(tea, 'great, time for tea!');\n   *\n   * @name isNotTrue\n   * @param {Mixed} value\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.isNotTrue = function (val, msg) {\n    new Assertion(val, msg).to.not.equal(true);\n  };\n\n  /**\n   * ### .isFalse(value, [message])\n   *\n   * Asserts that `value` is false.\n   *\n   *     var teaServed = false;\n   *     assert.isFalse(teaServed, 'no tea yet? hmm...');\n   *\n   * @name isFalse\n   * @param {Mixed} value\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.isFalse = function (val, msg) {\n    new Assertion(val, msg).is['false'];\n  };\n\n  /**\n   * ### .isNotFalse(value, [message])\n   *\n   * Asserts that `value` is not false.\n   *\n   *     var tea = 'tasty chai';\n   *     assert.isNotFalse(tea, 'great, time for tea!');\n   *\n   * @name isNotFalse\n   * @param {Mixed} value\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.isNotFalse = function (val, msg) {\n    new Assertion(val, msg).to.not.equal(false);\n  };\n\n  /**\n   * ### .isNull(value, [message])\n   *\n   * Asserts that `value` is null.\n   *\n   *     assert.isNull(err, 'there was no error');\n   *\n   * @name isNull\n   * @param {Mixed} value\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.isNull = function (val, msg) {\n    new Assertion(val, msg).to.equal(null);\n  };\n\n  /**\n   * ### .isNotNull(value, [message])\n   *\n   * Asserts that `value` is not null.\n   *\n   *     var tea = 'tasty chai';\n   *     assert.isNotNull(tea, 'great, time for tea!');\n   *\n   * @name isNotNull\n   * @param {Mixed} value\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.isNotNull = function (val, msg) {\n    new Assertion(val, msg).to.not.equal(null);\n  };\n\n  /**\n   * ### .isNaN\n   * Asserts that value is NaN\n   *\n   *    assert.isNaN('foo', 'foo is NaN');\n   *\n   * @name isNaN\n   * @param {Mixed} value\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.isNaN = function (val, msg) {\n    new Assertion(val, msg).to.be.NaN;\n  };\n\n  /**\n   * ### .isNotNaN\n   * Asserts that value is not NaN\n   *\n   *    assert.isNotNaN(4, '4 is not NaN');\n   *\n   * @name isNotNaN\n   * @param {Mixed} value\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n  assert.isNotNaN = function (val, msg) {\n    new Assertion(val, msg).not.to.be.NaN;\n  };\n\n  /**\n   * ### .isUndefined(value, [message])\n   *\n   * Asserts that `value` is `undefined`.\n   *\n   *     var tea;\n   *     assert.isUndefined(tea, 'no tea defined');\n   *\n   * @name isUndefined\n   * @param {Mixed} value\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.isUndefined = function (val, msg) {\n    new Assertion(val, msg).to.equal(undefined);\n  };\n\n  /**\n   * ### .isDefined(value, [message])\n   *\n   * Asserts that `value` is not `undefined`.\n   *\n   *     var tea = 'cup of chai';\n   *     assert.isDefined(tea, 'tea has been defined');\n   *\n   * @name isDefined\n   * @param {Mixed} value\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.isDefined = function (val, msg) {\n    new Assertion(val, msg).to.not.equal(undefined);\n  };\n\n  /**\n   * ### .isFunction(value, [message])\n   *\n   * Asserts that `value` is a function.\n   *\n   *     function serveTea() { return 'cup of tea'; };\n   *     assert.isFunction(serveTea, 'great, we can have tea now');\n   *\n   * @name isFunction\n   * @param {Mixed} value\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.isFunction = function (val, msg) {\n    new Assertion(val, msg).to.be.a('function');\n  };\n\n  /**\n   * ### .isNotFunction(value, [message])\n   *\n   * Asserts that `value` is _not_ a function.\n   *\n   *     var serveTea = [ 'heat', 'pour', 'sip' ];\n   *     assert.isNotFunction(serveTea, 'great, we have listed the steps');\n   *\n   * @name isNotFunction\n   * @param {Mixed} value\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.isNotFunction = function (val, msg) {\n    new Assertion(val, msg).to.not.be.a('function');\n  };\n\n  /**\n   * ### .isObject(value, [message])\n   *\n   * Asserts that `value` is an object of type 'Object' (as revealed by `Object.prototype.toString`).\n   * _The assertion does not match subclassed objects._\n   *\n   *     var selection = { name: 'Chai', serve: 'with spices' };\n   *     assert.isObject(selection, 'tea selection is an object');\n   *\n   * @name isObject\n   * @param {Mixed} value\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.isObject = function (val, msg) {\n    new Assertion(val, msg).to.be.a('object');\n  };\n\n  /**\n   * ### .isNotObject(value, [message])\n   *\n   * Asserts that `value` is _not_ an object of type 'Object' (as revealed by `Object.prototype.toString`).\n   *\n   *     var selection = 'chai'\n   *     assert.isNotObject(selection, 'tea selection is not an object');\n   *     assert.isNotObject(null, 'null is not an object');\n   *\n   * @name isNotObject\n   * @param {Mixed} value\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.isNotObject = function (val, msg) {\n    new Assertion(val, msg).to.not.be.a('object');\n  };\n\n  /**\n   * ### .isArray(value, [message])\n   *\n   * Asserts that `value` is an array.\n   *\n   *     var menu = [ 'green', 'chai', 'oolong' ];\n   *     assert.isArray(menu, 'what kind of tea do we want?');\n   *\n   * @name isArray\n   * @param {Mixed} value\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.isArray = function (val, msg) {\n    new Assertion(val, msg).to.be.an('array');\n  };\n\n  /**\n   * ### .isNotArray(value, [message])\n   *\n   * Asserts that `value` is _not_ an array.\n   *\n   *     var menu = 'green|chai|oolong';\n   *     assert.isNotArray(menu, 'what kind of tea do we want?');\n   *\n   * @name isNotArray\n   * @param {Mixed} value\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.isNotArray = function (val, msg) {\n    new Assertion(val, msg).to.not.be.an('array');\n  };\n\n  /**\n   * ### .isString(value, [message])\n   *\n   * Asserts that `value` is a string.\n   *\n   *     var teaOrder = 'chai';\n   *     assert.isString(teaOrder, 'order placed');\n   *\n   * @name isString\n   * @param {Mixed} value\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.isString = function (val, msg) {\n    new Assertion(val, msg).to.be.a('string');\n  };\n\n  /**\n   * ### .isNotString(value, [message])\n   *\n   * Asserts that `value` is _not_ a string.\n   *\n   *     var teaOrder = 4;\n   *     assert.isNotString(teaOrder, 'order placed');\n   *\n   * @name isNotString\n   * @param {Mixed} value\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.isNotString = function (val, msg) {\n    new Assertion(val, msg).to.not.be.a('string');\n  };\n\n  /**\n   * ### .isNumber(value, [message])\n   *\n   * Asserts that `value` is a number.\n   *\n   *     var cups = 2;\n   *     assert.isNumber(cups, 'how many cups');\n   *\n   * @name isNumber\n   * @param {Number} value\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.isNumber = function (val, msg) {\n    new Assertion(val, msg).to.be.a('number');\n  };\n\n  /**\n   * ### .isNotNumber(value, [message])\n   *\n   * Asserts that `value` is _not_ a number.\n   *\n   *     var cups = '2 cups please';\n   *     assert.isNotNumber(cups, 'how many cups');\n   *\n   * @name isNotNumber\n   * @param {Mixed} value\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.isNotNumber = function (val, msg) {\n    new Assertion(val, msg).to.not.be.a('number');\n  };\n\n  /**\n   * ### .isBoolean(value, [message])\n   *\n   * Asserts that `value` is a boolean.\n   *\n   *     var teaReady = true\n   *       , teaServed = false;\n   *\n   *     assert.isBoolean(teaReady, 'is the tea ready');\n   *     assert.isBoolean(teaServed, 'has tea been served');\n   *\n   * @name isBoolean\n   * @param {Mixed} value\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.isBoolean = function (val, msg) {\n    new Assertion(val, msg).to.be.a('boolean');\n  };\n\n  /**\n   * ### .isNotBoolean(value, [message])\n   *\n   * Asserts that `value` is _not_ a boolean.\n   *\n   *     var teaReady = 'yep'\n   *       , teaServed = 'nope';\n   *\n   *     assert.isNotBoolean(teaReady, 'is the tea ready');\n   *     assert.isNotBoolean(teaServed, 'has tea been served');\n   *\n   * @name isNotBoolean\n   * @param {Mixed} value\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.isNotBoolean = function (val, msg) {\n    new Assertion(val, msg).to.not.be.a('boolean');\n  };\n\n  /**\n   * ### .typeOf(value, name, [message])\n   *\n   * Asserts that `value`'s type is `name`, as determined by\n   * `Object.prototype.toString`.\n   *\n   *     assert.typeOf({ tea: 'chai' }, 'object', 'we have an object');\n   *     assert.typeOf(['chai', 'jasmine'], 'array', 'we have an array');\n   *     assert.typeOf('tea', 'string', 'we have a string');\n   *     assert.typeOf(/tea/, 'regexp', 'we have a regular expression');\n   *     assert.typeOf(null, 'null', 'we have a null');\n   *     assert.typeOf(undefined, 'undefined', 'we have an undefined');\n   *\n   * @name typeOf\n   * @param {Mixed} value\n   * @param {String} name\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.typeOf = function (val, type, msg) {\n    new Assertion(val, msg).to.be.a(type);\n  };\n\n  /**\n   * ### .notTypeOf(value, name, [message])\n   *\n   * Asserts that `value`'s type is _not_ `name`, as determined by\n   * `Object.prototype.toString`.\n   *\n   *     assert.notTypeOf('tea', 'number', 'strings are not numbers');\n   *\n   * @name notTypeOf\n   * @param {Mixed} value\n   * @param {String} typeof name\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.notTypeOf = function (val, type, msg) {\n    new Assertion(val, msg).to.not.be.a(type);\n  };\n\n  /**\n   * ### .instanceOf(object, constructor, [message])\n   *\n   * Asserts that `value` is an instance of `constructor`.\n   *\n   *     var Tea = function (name) { this.name = name; }\n   *       , chai = new Tea('chai');\n   *\n   *     assert.instanceOf(chai, Tea, 'chai is an instance of tea');\n   *\n   * @name instanceOf\n   * @param {Object} object\n   * @param {Constructor} constructor\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.instanceOf = function (val, type, msg) {\n    new Assertion(val, msg).to.be.instanceOf(type);\n  };\n\n  /**\n   * ### .notInstanceOf(object, constructor, [message])\n   *\n   * Asserts `value` is not an instance of `constructor`.\n   *\n   *     var Tea = function (name) { this.name = name; }\n   *       , chai = new String('chai');\n   *\n   *     assert.notInstanceOf(chai, Tea, 'chai is not an instance of tea');\n   *\n   * @name notInstanceOf\n   * @param {Object} object\n   * @param {Constructor} constructor\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.notInstanceOf = function (val, type, msg) {\n    new Assertion(val, msg).to.not.be.instanceOf(type);\n  };\n\n  /**\n   * ### .include(haystack, needle, [message])\n   *\n   * Asserts that `haystack` includes `needle`. Works\n   * for strings and arrays.\n   *\n   *     assert.include('foobar', 'bar', 'foobar contains string \"bar\"');\n   *     assert.include([ 1, 2, 3 ], 3, 'array contains value');\n   *\n   * @name include\n   * @param {Array|String} haystack\n   * @param {Mixed} needle\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.include = function (exp, inc, msg) {\n    new Assertion(exp, msg, assert.include).include(inc);\n  };\n\n  /**\n   * ### .notInclude(haystack, needle, [message])\n   *\n   * Asserts that `haystack` does not include `needle`. Works\n   * for strings and arrays.\n   *\n   *     assert.notInclude('foobar', 'baz', 'string not include substring');\n   *     assert.notInclude([ 1, 2, 3 ], 4, 'array not include contain value');\n   *\n   * @name notInclude\n   * @param {Array|String} haystack\n   * @param {Mixed} needle\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.notInclude = function (exp, inc, msg) {\n    new Assertion(exp, msg, assert.notInclude).not.include(inc);\n  };\n\n  /**\n   * ### .match(value, regexp, [message])\n   *\n   * Asserts that `value` matches the regular expression `regexp`.\n   *\n   *     assert.match('foobar', /^foo/, 'regexp matches');\n   *\n   * @name match\n   * @param {Mixed} value\n   * @param {RegExp} regexp\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.match = function (exp, re, msg) {\n    new Assertion(exp, msg).to.match(re);\n  };\n\n  /**\n   * ### .notMatch(value, regexp, [message])\n   *\n   * Asserts that `value` does not match the regular expression `regexp`.\n   *\n   *     assert.notMatch('foobar', /^foo/, 'regexp does not match');\n   *\n   * @name notMatch\n   * @param {Mixed} value\n   * @param {RegExp} regexp\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.notMatch = function (exp, re, msg) {\n    new Assertion(exp, msg).to.not.match(re);\n  };\n\n  /**\n   * ### .property(object, property, [message])\n   *\n   * Asserts that `object` has a property named by `property`.\n   *\n   *     assert.property({ tea: { green: 'matcha' }}, 'tea');\n   *\n   * @name property\n   * @param {Object} object\n   * @param {String} property\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.property = function (obj, prop, msg) {\n    new Assertion(obj, msg).to.have.property(prop);\n  };\n\n  /**\n   * ### .notProperty(object, property, [message])\n   *\n   * Asserts that `object` does _not_ have a property named by `property`.\n   *\n   *     assert.notProperty({ tea: { green: 'matcha' }}, 'coffee');\n   *\n   * @name notProperty\n   * @param {Object} object\n   * @param {String} property\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.notProperty = function (obj, prop, msg) {\n    new Assertion(obj, msg).to.not.have.property(prop);\n  };\n\n  /**\n   * ### .deepProperty(object, property, [message])\n   *\n   * Asserts that `object` has a property named by `property`, which can be a\n   * string using dot- and bracket-notation for deep reference.\n   *\n   *     assert.deepProperty({ tea: { green: 'matcha' }}, 'tea.green');\n   *\n   * @name deepProperty\n   * @param {Object} object\n   * @param {String} property\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.deepProperty = function (obj, prop, msg) {\n    new Assertion(obj, msg).to.have.deep.property(prop);\n  };\n\n  /**\n   * ### .notDeepProperty(object, property, [message])\n   *\n   * Asserts that `object` does _not_ have a property named by `property`, which\n   * can be a string using dot- and bracket-notation for deep reference.\n   *\n   *     assert.notDeepProperty({ tea: { green: 'matcha' }}, 'tea.oolong');\n   *\n   * @name notDeepProperty\n   * @param {Object} object\n   * @param {String} property\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.notDeepProperty = function (obj, prop, msg) {\n    new Assertion(obj, msg).to.not.have.deep.property(prop);\n  };\n\n  /**\n   * ### .propertyVal(object, property, value, [message])\n   *\n   * Asserts that `object` has a property named by `property` with value given\n   * by `value`.\n   *\n   *     assert.propertyVal({ tea: 'is good' }, 'tea', 'is good');\n   *\n   * @name propertyVal\n   * @param {Object} object\n   * @param {String} property\n   * @param {Mixed} value\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.propertyVal = function (obj, prop, val, msg) {\n    new Assertion(obj, msg).to.have.property(prop, val);\n  };\n\n  /**\n   * ### .propertyNotVal(object, property, value, [message])\n   *\n   * Asserts that `object` has a property named by `property`, but with a value\n   * different from that given by `value`.\n   *\n   *     assert.propertyNotVal({ tea: 'is good' }, 'tea', 'is bad');\n   *\n   * @name propertyNotVal\n   * @param {Object} object\n   * @param {String} property\n   * @param {Mixed} value\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.propertyNotVal = function (obj, prop, val, msg) {\n    new Assertion(obj, msg).to.not.have.property(prop, val);\n  };\n\n  /**\n   * ### .deepPropertyVal(object, property, value, [message])\n   *\n   * Asserts that `object` has a property named by `property` with value given\n   * by `value`. `property` can use dot- and bracket-notation for deep\n   * reference.\n   *\n   *     assert.deepPropertyVal({ tea: { green: 'matcha' }}, 'tea.green', 'matcha');\n   *\n   * @name deepPropertyVal\n   * @param {Object} object\n   * @param {String} property\n   * @param {Mixed} value\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.deepPropertyVal = function (obj, prop, val, msg) {\n    new Assertion(obj, msg).to.have.deep.property(prop, val);\n  };\n\n  /**\n   * ### .deepPropertyNotVal(object, property, value, [message])\n   *\n   * Asserts that `object` has a property named by `property`, but with a value\n   * different from that given by `value`. `property` can use dot- and\n   * bracket-notation for deep reference.\n   *\n   *     assert.deepPropertyNotVal({ tea: { green: 'matcha' }}, 'tea.green', 'konacha');\n   *\n   * @name deepPropertyNotVal\n   * @param {Object} object\n   * @param {String} property\n   * @param {Mixed} value\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.deepPropertyNotVal = function (obj, prop, val, msg) {\n    new Assertion(obj, msg).to.not.have.deep.property(prop, val);\n  };\n\n  /**\n   * ### .lengthOf(object, length, [message])\n   *\n   * Asserts that `object` has a `length` property with the expected value.\n   *\n   *     assert.lengthOf([1,2,3], 3, 'array has length of 3');\n   *     assert.lengthOf('foobar', 6, 'string has length of 6');\n   *\n   * @name lengthOf\n   * @param {Mixed} object\n   * @param {Number} length\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.lengthOf = function (exp, len, msg) {\n    new Assertion(exp, msg).to.have.length(len);\n  };\n\n  /**\n   * ### .throws(function, [constructor/string/regexp], [string/regexp], [message])\n   *\n   * Asserts that `function` will throw an error that is an instance of\n   * `constructor`, or alternately that it will throw an error with message\n   * matching `regexp`.\n   *\n   *     assert.throws(fn, 'function throws a reference error');\n   *     assert.throws(fn, /function throws a reference error/);\n   *     assert.throws(fn, ReferenceError);\n   *     assert.throws(fn, ReferenceError, 'function throws a reference error');\n   *     assert.throws(fn, ReferenceError, /function throws a reference error/);\n   *\n   * @name throws\n   * @alias throw\n   * @alias Throw\n   * @param {Function} function\n   * @param {ErrorConstructor} constructor\n   * @param {RegExp} regexp\n   * @param {String} message\n   * @see https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Error#Error_types\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.throws = function (fn, errt, errs, msg) {\n    if ('string' === typeof errt || errt instanceof RegExp) {\n      errs = errt;\n      errt = null;\n    }\n\n    var assertErr = new Assertion(fn, msg).to.throw(errt, errs);\n    return flag(assertErr, 'object');\n  };\n\n  /**\n   * ### .doesNotThrow(function, [constructor/regexp], [message])\n   *\n   * Asserts that `function` will _not_ throw an error that is an instance of\n   * `constructor`, or alternately that it will not throw an error with message\n   * matching `regexp`.\n   *\n   *     assert.doesNotThrow(fn, Error, 'function does not throw');\n   *\n   * @name doesNotThrow\n   * @param {Function} function\n   * @param {ErrorConstructor} constructor\n   * @param {RegExp} regexp\n   * @param {String} message\n   * @see https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Error#Error_types\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.doesNotThrow = function (fn, type, msg) {\n    if ('string' === typeof type) {\n      msg = type;\n      type = null;\n    }\n\n    new Assertion(fn, msg).to.not.Throw(type);\n  };\n\n  /**\n   * ### .operator(val1, operator, val2, [message])\n   *\n   * Compares two values using `operator`.\n   *\n   *     assert.operator(1, '<', 2, 'everything is ok');\n   *     assert.operator(1, '>', 2, 'this will fail');\n   *\n   * @name operator\n   * @param {Mixed} val1\n   * @param {String} operator\n   * @param {Mixed} val2\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.operator = function (val, operator, val2, msg) {\n    var ok;\n    switch(operator) {\n      case '==':\n        ok = val == val2;\n        break;\n      case '===':\n        ok = val === val2;\n        break;\n      case '>':\n        ok = val > val2;\n        break;\n      case '>=':\n        ok = val >= val2;\n        break;\n      case '<':\n        ok = val < val2;\n        break;\n      case '<=':\n        ok = val <= val2;\n        break;\n      case '!=':\n        ok = val != val2;\n        break;\n      case '!==':\n        ok = val !== val2;\n        break;\n      default:\n        throw new Error('Invalid operator \"' + operator + '\"');\n    }\n    var test = new Assertion(ok, msg);\n    test.assert(\n        true === flag(test, 'object')\n      , 'expected ' + util.inspect(val) + ' to be ' + operator + ' ' + util.inspect(val2)\n      , 'expected ' + util.inspect(val) + ' to not be ' + operator + ' ' + util.inspect(val2) );\n  };\n\n  /**\n   * ### .closeTo(actual, expected, delta, [message])\n   *\n   * Asserts that the target is equal `expected`, to within a +/- `delta` range.\n   *\n   *     assert.closeTo(1.5, 1, 0.5, 'numbers are close');\n   *\n   * @name closeTo\n   * @param {Number} actual\n   * @param {Number} expected\n   * @param {Number} delta\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.closeTo = function (act, exp, delta, msg) {\n    new Assertion(act, msg).to.be.closeTo(exp, delta);\n  };\n\n  /**\n   * ### .approximately(actual, expected, delta, [message])\n   *\n   * Asserts that the target is equal `expected`, to within a +/- `delta` range.\n   *\n   *     assert.approximately(1.5, 1, 0.5, 'numbers are close');\n   *\n   * @name approximately\n   * @param {Number} actual\n   * @param {Number} expected\n   * @param {Number} delta\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.approximately = function (act, exp, delta, msg) {\n    new Assertion(act, msg).to.be.approximately(exp, delta);\n  };\n\n  /**\n   * ### .sameMembers(set1, set2, [message])\n   *\n   * Asserts that `set1` and `set2` have the same members.\n   * Order is not taken into account.\n   *\n   *     assert.sameMembers([ 1, 2, 3 ], [ 2, 1, 3 ], 'same members');\n   *\n   * @name sameMembers\n   * @param {Array} set1\n   * @param {Array} set2\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.sameMembers = function (set1, set2, msg) {\n    new Assertion(set1, msg).to.have.same.members(set2);\n  }\n\n  /**\n   * ### .sameDeepMembers(set1, set2, [message])\n   *\n   * Asserts that `set1` and `set2` have the same members - using a deep equality checking.\n   * Order is not taken into account.\n   *\n   *     assert.sameDeepMembers([ {b: 3}, {a: 2}, {c: 5} ], [ {c: 5}, {b: 3}, {a: 2} ], 'same deep members');\n   *\n   * @name sameDeepMembers\n   * @param {Array} set1\n   * @param {Array} set2\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.sameDeepMembers = function (set1, set2, msg) {\n    new Assertion(set1, msg).to.have.same.deep.members(set2);\n  }\n\n  /**\n   * ### .includeMembers(superset, subset, [message])\n   *\n   * Asserts that `subset` is included in `superset`.\n   * Order is not taken into account.\n   *\n   *     assert.includeMembers([ 1, 2, 3 ], [ 2, 1 ], 'include members');\n   *\n   * @name includeMembers\n   * @param {Array} superset\n   * @param {Array} subset\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.includeMembers = function (superset, subset, msg) {\n    new Assertion(superset, msg).to.include.members(subset);\n  }\n\n  /**\n   * ### .includeDeepMembers(superset, subset, [message])\n   *\n   * Asserts that `subset` is included in `superset` - using deep equality checking.\n   * Order is not taken into account.\n   * Duplicates are ignored.\n   *\n   *     assert.includeDeepMembers([ {a: 1}, {b: 2}, {c: 3} ], [ {b: 2}, {a: 1}, {b: 2} ], 'include deep members');\n   *\n   * @name includeDeepMembers\n   * @param {Array} superset\n   * @param {Array} subset\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.includeDeepMembers = function (superset, subset, msg) {\n    new Assertion(superset, msg).to.include.deep.members(subset);\n  }\n\n  /**\n   * ### .oneOf(inList, list, [message])\n   *\n   * Asserts that non-object, non-array value `inList` appears in the flat array `list`.\n   *\n   *     assert.oneOf(1, [ 2, 1 ], 'Not found in list');\n   *\n   * @name oneOf\n   * @param {*} inList\n   * @param {Array<*>} list\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.oneOf = function (inList, list, msg) {\n    new Assertion(inList, msg).to.be.oneOf(list);\n  }\n\n   /**\n   * ### .changes(function, object, property)\n   *\n   * Asserts that a function changes the value of a property\n   *\n   *     var obj = { val: 10 };\n   *     var fn = function() { obj.val = 22 };\n   *     assert.changes(fn, obj, 'val');\n   *\n   * @name changes\n   * @param {Function} modifier function\n   * @param {Object} object\n   * @param {String} property name\n   * @param {String} message _optional_\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.changes = function (fn, obj, prop) {\n    new Assertion(fn).to.change(obj, prop);\n  }\n\n   /**\n   * ### .doesNotChange(function, object, property)\n   *\n   * Asserts that a function does not changes the value of a property\n   *\n   *     var obj = { val: 10 };\n   *     var fn = function() { console.log('foo'); };\n   *     assert.doesNotChange(fn, obj, 'val');\n   *\n   * @name doesNotChange\n   * @param {Function} modifier function\n   * @param {Object} object\n   * @param {String} property name\n   * @param {String} message _optional_\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.doesNotChange = function (fn, obj, prop) {\n    new Assertion(fn).to.not.change(obj, prop);\n  }\n\n   /**\n   * ### .increases(function, object, property)\n   *\n   * Asserts that a function increases an object property\n   *\n   *     var obj = { val: 10 };\n   *     var fn = function() { obj.val = 13 };\n   *     assert.increases(fn, obj, 'val');\n   *\n   * @name increases\n   * @param {Function} modifier function\n   * @param {Object} object\n   * @param {String} property name\n   * @param {String} message _optional_\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.increases = function (fn, obj, prop) {\n    new Assertion(fn).to.increase(obj, prop);\n  }\n\n   /**\n   * ### .doesNotIncrease(function, object, property)\n   *\n   * Asserts that a function does not increase object property\n   *\n   *     var obj = { val: 10 };\n   *     var fn = function() { obj.val = 8 };\n   *     assert.doesNotIncrease(fn, obj, 'val');\n   *\n   * @name doesNotIncrease\n   * @param {Function} modifier function\n   * @param {Object} object\n   * @param {String} property name\n   * @param {String} message _optional_\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.doesNotIncrease = function (fn, obj, prop) {\n    new Assertion(fn).to.not.increase(obj, prop);\n  }\n\n   /**\n   * ### .decreases(function, object, property)\n   *\n   * Asserts that a function decreases an object property\n   *\n   *     var obj = { val: 10 };\n   *     var fn = function() { obj.val = 5 };\n   *     assert.decreases(fn, obj, 'val');\n   *\n   * @name decreases\n   * @param {Function} modifier function\n   * @param {Object} object\n   * @param {String} property name\n   * @param {String} message _optional_\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.decreases = function (fn, obj, prop) {\n    new Assertion(fn).to.decrease(obj, prop);\n  }\n\n   /**\n   * ### .doesNotDecrease(function, object, property)\n   *\n   * Asserts that a function does not decreases an object property\n   *\n   *     var obj = { val: 10 };\n   *     var fn = function() { obj.val = 15 };\n   *     assert.doesNotDecrease(fn, obj, 'val');\n   *\n   * @name doesNotDecrease\n   * @param {Function} modifier function\n   * @param {Object} object\n   * @param {String} property name\n   * @param {String} message _optional_\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.doesNotDecrease = function (fn, obj, prop) {\n    new Assertion(fn).to.not.decrease(obj, prop);\n  }\n\n  /*!\n   * ### .ifError(object)\n   *\n   * Asserts if value is not a false value, and throws if it is a true value.\n   * This is added to allow for chai to be a drop-in replacement for Node's\n   * assert class.\n   *\n   *     var err = new Error('I am a custom error');\n   *     assert.ifError(err); // Rethrows err!\n   *\n   * @name ifError\n   * @param {Object} object\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.ifError = function (val) {\n    if (val) {\n      throw(val);\n    }\n  };\n\n  /**\n   * ### .isExtensible(object)\n   *\n   * Asserts that `object` is extensible (can have new properties added to it).\n   *\n   *     assert.isExtensible({});\n   *\n   * @name isExtensible\n   * @alias extensible\n   * @param {Object} object\n   * @param {String} message _optional_\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.isExtensible = function (obj, msg) {\n    new Assertion(obj, msg).to.be.extensible;\n  };\n\n  /**\n   * ### .isNotExtensible(object)\n   *\n   * Asserts that `object` is _not_ extensible.\n   *\n   *     var nonExtensibleObject = Object.preventExtensions({});\n   *     var sealedObject = Object.seal({});\n   *     var frozenObject = Object.freese({});\n   *\n   *     assert.isNotExtensible(nonExtensibleObject);\n   *     assert.isNotExtensible(sealedObject);\n   *     assert.isNotExtensible(frozenObject);\n   *\n   * @name isNotExtensible\n   * @alias notExtensible\n   * @param {Object} object\n   * @param {String} message _optional_\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.isNotExtensible = function (obj, msg) {\n    new Assertion(obj, msg).to.not.be.extensible;\n  };\n\n  /**\n   * ### .isSealed(object)\n   *\n   * Asserts that `object` is sealed (cannot have new properties added to it\n   * and its existing properties cannot be removed).\n   *\n   *     var sealedObject = Object.seal({});\n   *     var frozenObject = Object.seal({});\n   *\n   *     assert.isSealed(sealedObject);\n   *     assert.isSealed(frozenObject);\n   *\n   * @name isSealed\n   * @alias sealed\n   * @param {Object} object\n   * @param {String} message _optional_\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.isSealed = function (obj, msg) {\n    new Assertion(obj, msg).to.be.sealed;\n  };\n\n  /**\n   * ### .isNotSealed(object)\n   *\n   * Asserts that `object` is _not_ sealed.\n   *\n   *     assert.isNotSealed({});\n   *\n   * @name isNotSealed\n   * @alias notSealed\n   * @param {Object} object\n   * @param {String} message _optional_\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.isNotSealed = function (obj, msg) {\n    new Assertion(obj, msg).to.not.be.sealed;\n  };\n\n  /**\n   * ### .isFrozen(object)\n   *\n   * Asserts that `object` is frozen (cannot have new properties added to it\n   * and its existing properties cannot be modified).\n   *\n   *     var frozenObject = Object.freeze({});\n   *     assert.frozen(frozenObject);\n   *\n   * @name isFrozen\n   * @alias frozen\n   * @param {Object} object\n   * @param {String} message _optional_\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.isFrozen = function (obj, msg) {\n    new Assertion(obj, msg).to.be.frozen;\n  };\n\n  /**\n   * ### .isNotFrozen(object)\n   *\n   * Asserts that `object` is _not_ frozen.\n   *\n   *     assert.isNotFrozen({});\n   *\n   * @name isNotFrozen\n   * @alias notFrozen\n   * @param {Object} object\n   * @param {String} message _optional_\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.isNotFrozen = function (obj, msg) {\n    new Assertion(obj, msg).to.not.be.frozen;\n  };\n\n  /*!\n   * Aliases.\n   */\n\n  (function alias(name, as){\n    assert[as] = assert[name];\n    return alias;\n  })\n  ('isOk', 'ok')\n  ('isNotOk', 'notOk')\n  ('throws', 'throw')\n  ('throws', 'Throw')\n  ('isExtensible', 'extensible')\n  ('isNotExtensible', 'notExtensible')\n  ('isSealed', 'sealed')\n  ('isNotSealed', 'notSealed')\n  ('isFrozen', 'frozen')\n  ('isNotFrozen', 'notFrozen');\n};\n\n},{}],7:[function(require,module,exports){\n/*!\n * chai\n * Copyright(c) 2011-2014 Jake Luer <jake@alogicalparadox.com>\n * MIT Licensed\n */\n\nmodule.exports = function (chai, util) {\n  chai.expect = function (val, message) {\n    return new chai.Assertion(val, message);\n  };\n\n  /**\n   * ### .fail(actual, expected, [message], [operator])\n   *\n   * Throw a failure.\n   *\n   * @name fail\n   * @param {Mixed} actual\n   * @param {Mixed} expected\n   * @param {String} message\n   * @param {String} operator\n   * @namespace Expect\n   * @api public\n   */\n\n  chai.expect.fail = function (actual, expected, message, operator) {\n    message = message || 'expect.fail()';\n    throw new chai.AssertionError(message, {\n        actual: actual\n      , expected: expected\n      , operator: operator\n    }, chai.expect.fail);\n  };\n};\n\n},{}],8:[function(require,module,exports){\n/*!\n * chai\n * Copyright(c) 2011-2014 Jake Luer <jake@alogicalparadox.com>\n * MIT Licensed\n */\n\nmodule.exports = function (chai, util) {\n  var Assertion = chai.Assertion;\n\n  function loadShould () {\n    // explicitly define this method as function as to have it's name to include as `ssfi`\n    function shouldGetter() {\n      if (this instanceof String || this instanceof Number || this instanceof Boolean ) {\n        return new Assertion(this.valueOf(), null, shouldGetter);\n      }\n      return new Assertion(this, null, shouldGetter);\n    }\n    function shouldSetter(value) {\n      // See https://github.com/chaijs/chai/issues/86: this makes\n      // `whatever.should = someValue` actually set `someValue`, which is\n      // especially useful for `global.should = require('chai').should()`.\n      //\n      // Note that we have to use [[DefineProperty]] instead of [[Put]]\n      // since otherwise we would trigger this very setter!\n      Object.defineProperty(this, 'should', {\n        value: value,\n        enumerable: true,\n        configurable: true,\n        writable: true\n      });\n    }\n    // modify Object.prototype to have `should`\n    Object.defineProperty(Object.prototype, 'should', {\n      set: shouldSetter\n      , get: shouldGetter\n      , configurable: true\n    });\n\n    var should = {};\n\n    /**\n     * ### .fail(actual, expected, [message], [operator])\n     *\n     * Throw a failure.\n     *\n     * @name fail\n     * @param {Mixed} actual\n     * @param {Mixed} expected\n     * @param {String} message\n     * @param {String} operator\n     * @namespace Should\n     * @api public\n     */\n\n    should.fail = function (actual, expected, message, operator) {\n      message = message || 'should.fail()';\n      throw new chai.AssertionError(message, {\n          actual: actual\n        , expected: expected\n        , operator: operator\n      }, should.fail);\n    };\n\n    /**\n     * ### .equal(actual, expected, [message])\n     *\n     * Asserts non-strict equality (`==`) of `actual` and `expected`.\n     *\n     *     should.equal(3, '3', '== coerces values to strings');\n     *\n     * @name equal\n     * @param {Mixed} actual\n     * @param {Mixed} expected\n     * @param {String} message\n     * @namespace Should\n     * @api public\n     */\n\n    should.equal = function (val1, val2, msg) {\n      new Assertion(val1, msg).to.equal(val2);\n    };\n\n    /**\n     * ### .throw(function, [constructor/string/regexp], [string/regexp], [message])\n     *\n     * Asserts that `function` will throw an error that is an instance of\n     * `constructor`, or alternately that it will throw an error with message\n     * matching `regexp`.\n     *\n     *     should.throw(fn, 'function throws a reference error');\n     *     should.throw(fn, /function throws a reference error/);\n     *     should.throw(fn, ReferenceError);\n     *     should.throw(fn, ReferenceError, 'function throws a reference error');\n     *     should.throw(fn, ReferenceError, /function throws a reference error/);\n     *\n     * @name throw\n     * @alias Throw\n     * @param {Function} function\n     * @param {ErrorConstructor} constructor\n     * @param {RegExp} regexp\n     * @param {String} message\n     * @see https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Error#Error_types\n     * @namespace Should\n     * @api public\n     */\n\n    should.Throw = function (fn, errt, errs, msg) {\n      new Assertion(fn, msg).to.Throw(errt, errs);\n    };\n\n    /**\n     * ### .exist\n     *\n     * Asserts that the target is neither `null` nor `undefined`.\n     *\n     *     var foo = 'hi';\n     *\n     *     should.exist(foo, 'foo exists');\n     *\n     * @name exist\n     * @namespace Should\n     * @api public\n     */\n\n    should.exist = function (val, msg) {\n      new Assertion(val, msg).to.exist;\n    }\n\n    // negation\n    should.not = {}\n\n    /**\n     * ### .not.equal(actual, expected, [message])\n     *\n     * Asserts non-strict inequality (`!=`) of `actual` and `expected`.\n     *\n     *     should.not.equal(3, 4, 'these numbers are not equal');\n     *\n     * @name not.equal\n     * @param {Mixed} actual\n     * @param {Mixed} expected\n     * @param {String} message\n     * @namespace Should\n     * @api public\n     */\n\n    should.not.equal = function (val1, val2, msg) {\n      new Assertion(val1, msg).to.not.equal(val2);\n    };\n\n    /**\n     * ### .throw(function, [constructor/regexp], [message])\n     *\n     * Asserts that `function` will _not_ throw an error that is an instance of\n     * `constructor`, or alternately that it will not throw an error with message\n     * matching `regexp`.\n     *\n     *     should.not.throw(fn, Error, 'function does not throw');\n     *\n     * @name not.throw\n     * @alias not.Throw\n     * @param {Function} function\n     * @param {ErrorConstructor} constructor\n     * @param {RegExp} regexp\n     * @param {String} message\n     * @see https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Error#Error_types\n     * @namespace Should\n     * @api public\n     */\n\n    should.not.Throw = function (fn, errt, errs, msg) {\n      new Assertion(fn, msg).to.not.Throw(errt, errs);\n    };\n\n    /**\n     * ### .not.exist\n     *\n     * Asserts that the target is neither `null` nor `undefined`.\n     *\n     *     var bar = null;\n     *\n     *     should.not.exist(bar, 'bar does not exist');\n     *\n     * @name not.exist\n     * @namespace Should\n     * @api public\n     */\n\n    should.not.exist = function (val, msg) {\n      new Assertion(val, msg).to.not.exist;\n    }\n\n    should['throw'] = should['Throw'];\n    should.not['throw'] = should.not['Throw'];\n\n    return should;\n  };\n\n  chai.should = loadShould;\n  chai.Should = loadShould;\n};\n\n},{}],9:[function(require,module,exports){\n/*!\n * Chai - addChainingMethod utility\n * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com>\n * MIT Licensed\n */\n\n/*!\n * Module dependencies\n */\n\nvar transferFlags = require('./transferFlags');\nvar flag = require('./flag');\nvar config = require('../config');\n\n/*!\n * Module variables\n */\n\n// Check whether `__proto__` is supported\nvar hasProtoSupport = '__proto__' in Object;\n\n// Without `__proto__` support, this module will need to add properties to a function.\n// However, some Function.prototype methods cannot be overwritten,\n// and there seems no easy cross-platform way to detect them (@see chaijs/chai/issues/69).\nvar excludeNames = /^(?:length|name|arguments|caller)$/;\n\n// Cache `Function` properties\nvar call  = Function.prototype.call,\n    apply = Function.prototype.apply;\n\n/**\n * ### addChainableMethod (ctx, name, method, chainingBehavior)\n *\n * Adds a method to an object, such that the method can also be chained.\n *\n *     utils.addChainableMethod(chai.Assertion.prototype, 'foo', function (str) {\n *       var obj = utils.flag(this, 'object');\n *       new chai.Assertion(obj).to.be.equal(str);\n *     });\n *\n * Can also be accessed directly from `chai.Assertion`.\n *\n *     chai.Assertion.addChainableMethod('foo', fn, chainingBehavior);\n *\n * The result can then be used as both a method assertion, executing both `method` and\n * `chainingBehavior`, or as a language chain, which only executes `chainingBehavior`.\n *\n *     expect(fooStr).to.be.foo('bar');\n *     expect(fooStr).to.be.foo.equal('foo');\n *\n * @param {Object} ctx object to which the method is added\n * @param {String} name of method to add\n * @param {Function} method function to be used for `name`, when called\n * @param {Function} chainingBehavior function to be called every time the property is accessed\n * @namespace Utils\n * @name addChainableMethod\n * @api public\n */\n\nmodule.exports = function (ctx, name, method, chainingBehavior) {\n  if (typeof chainingBehavior !== 'function') {\n    chainingBehavior = function () { };\n  }\n\n  var chainableBehavior = {\n      method: method\n    , chainingBehavior: chainingBehavior\n  };\n\n  // save the methods so we can overwrite them later, if we need to.\n  if (!ctx.__methods) {\n    ctx.__methods = {};\n  }\n  ctx.__methods[name] = chainableBehavior;\n\n  Object.defineProperty(ctx, name,\n    { get: function () {\n        chainableBehavior.chainingBehavior.call(this);\n\n        var assert = function assert() {\n          var old_ssfi = flag(this, 'ssfi');\n          if (old_ssfi && config.includeStack === false)\n            flag(this, 'ssfi', assert);\n          var result = chainableBehavior.method.apply(this, arguments);\n          return result === undefined ? this : result;\n        };\n\n        // Use `__proto__` if available\n        if (hasProtoSupport) {\n          // Inherit all properties from the object by replacing the `Function` prototype\n          var prototype = assert.__proto__ = Object.create(this);\n          // Restore the `call` and `apply` methods from `Function`\n          prototype.call = call;\n          prototype.apply = apply;\n        }\n        // Otherwise, redefine all properties (slow!)\n        else {\n          var asserterNames = Object.getOwnPropertyNames(ctx);\n          asserterNames.forEach(function (asserterName) {\n            if (!excludeNames.test(asserterName)) {\n              var pd = Object.getOwnPropertyDescriptor(ctx, asserterName);\n              Object.defineProperty(assert, asserterName, pd);\n            }\n          });\n        }\n\n        transferFlags(this, assert);\n        return assert;\n      }\n    , configurable: true\n  });\n};\n\n},{\"../config\":4,\"./flag\":13,\"./transferFlags\":29}],10:[function(require,module,exports){\n/*!\n * Chai - addMethod utility\n * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com>\n * MIT Licensed\n */\n\nvar config = require('../config');\n\n/**\n * ### .addMethod (ctx, name, method)\n *\n * Adds a method to the prototype of an object.\n *\n *     utils.addMethod(chai.Assertion.prototype, 'foo', function (str) {\n *       var obj = utils.flag(this, 'object');\n *       new chai.Assertion(obj).to.be.equal(str);\n *     });\n *\n * Can also be accessed directly from `chai.Assertion`.\n *\n *     chai.Assertion.addMethod('foo', fn);\n *\n * Then can be used as any other assertion.\n *\n *     expect(fooStr).to.be.foo('bar');\n *\n * @param {Object} ctx object to which the method is added\n * @param {String} name of method to add\n * @param {Function} method function to be used for name\n * @namespace Utils\n * @name addMethod\n * @api public\n */\nvar flag = require('./flag');\n\nmodule.exports = function (ctx, name, method) {\n  ctx[name] = function () {\n    var old_ssfi = flag(this, 'ssfi');\n    if (old_ssfi && config.includeStack === false)\n      flag(this, 'ssfi', ctx[name]);\n    var result = method.apply(this, arguments);\n    return result === undefined ? this : result;\n  };\n};\n\n},{\"../config\":4,\"./flag\":13}],11:[function(require,module,exports){\n/*!\n * Chai - addProperty utility\n * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com>\n * MIT Licensed\n */\n\nvar config = require('../config');\nvar flag = require('./flag');\n\n/**\n * ### addProperty (ctx, name, getter)\n *\n * Adds a property to the prototype of an object.\n *\n *     utils.addProperty(chai.Assertion.prototype, 'foo', function () {\n *       var obj = utils.flag(this, 'object');\n *       new chai.Assertion(obj).to.be.instanceof(Foo);\n *     });\n *\n * Can also be accessed directly from `chai.Assertion`.\n *\n *     chai.Assertion.addProperty('foo', fn);\n *\n * Then can be used as any other assertion.\n *\n *     expect(myFoo).to.be.foo;\n *\n * @param {Object} ctx object to which the property is added\n * @param {String} name of property to add\n * @param {Function} getter function to be used for name\n * @namespace Utils\n * @name addProperty\n * @api public\n */\n\nmodule.exports = function (ctx, name, getter) {\n  Object.defineProperty(ctx, name,\n    { get: function addProperty() {\n        var old_ssfi = flag(this, 'ssfi');\n        if (old_ssfi && config.includeStack === false)\n          flag(this, 'ssfi', addProperty);\n\n        var result = getter.call(this);\n        return result === undefined ? this : result;\n      }\n    , configurable: true\n  });\n};\n\n},{\"../config\":4,\"./flag\":13}],12:[function(require,module,exports){\n/*!\n * Chai - expectTypes utility\n * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com>\n * MIT Licensed\n */\n\n/**\n * ### expectTypes(obj, types)\n *\n * Ensures that the object being tested against is of a valid type.\n *\n *     utils.expectTypes(this, ['array', 'object', 'string']);\n *\n * @param {Mixed} obj constructed Assertion\n * @param {Array} type A list of allowed types for this assertion\n * @namespace Utils\n * @name expectTypes\n * @api public\n */\n\nvar AssertionError = require('assertion-error');\nvar flag = require('./flag');\nvar type = require('type-detect');\n\nmodule.exports = function (obj, types) {\n  var obj = flag(obj, 'object');\n  types = types.map(function (t) { return t.toLowerCase(); });\n  types.sort();\n\n  // Transforms ['lorem', 'ipsum'] into 'a lirum, or an ipsum'\n  var str = types.map(function (t, index) {\n    var art = ~[ 'a', 'e', 'i', 'o', 'u' ].indexOf(t.charAt(0)) ? 'an' : 'a';\n    var or = types.length > 1 && index === types.length - 1 ? 'or ' : '';\n    return or + art + ' ' + t;\n  }).join(', ');\n\n  if (!types.some(function (expected) { return type(obj) === expected; })) {\n    throw new AssertionError(\n      'object tested must be ' + str + ', but ' + type(obj) + ' given'\n    );\n  }\n};\n\n},{\"./flag\":13,\"assertion-error\":30,\"type-detect\":35}],13:[function(require,module,exports){\n/*!\n * Chai - flag utility\n * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com>\n * MIT Licensed\n */\n\n/**\n * ### flag(object, key, [value])\n *\n * Get or set a flag value on an object. If a\n * value is provided it will be set, else it will\n * return the currently set value or `undefined` if\n * the value is not set.\n *\n *     utils.flag(this, 'foo', 'bar'); // setter\n *     utils.flag(this, 'foo'); // getter, returns `bar`\n *\n * @param {Object} object constructed Assertion\n * @param {String} key\n * @param {Mixed} value (optional)\n * @namespace Utils\n * @name flag\n * @api private\n */\n\nmodule.exports = function (obj, key, value) {\n  var flags = obj.__flags || (obj.__flags = Object.create(null));\n  if (arguments.length === 3) {\n    flags[key] = value;\n  } else {\n    return flags[key];\n  }\n};\n\n},{}],14:[function(require,module,exports){\n/*!\n * Chai - getActual utility\n * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com>\n * MIT Licensed\n */\n\n/**\n * # getActual(object, [actual])\n *\n * Returns the `actual` value for an Assertion\n *\n * @param {Object} object (constructed Assertion)\n * @param {Arguments} chai.Assertion.prototype.assert arguments\n * @namespace Utils\n * @name getActual\n */\n\nmodule.exports = function (obj, args) {\n  return args.length > 4 ? args[4] : obj._obj;\n};\n\n},{}],15:[function(require,module,exports){\n/*!\n * Chai - getEnumerableProperties utility\n * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com>\n * MIT Licensed\n */\n\n/**\n * ### .getEnumerableProperties(object)\n *\n * This allows the retrieval of enumerable property names of an object,\n * inherited or not.\n *\n * @param {Object} object\n * @returns {Array}\n * @namespace Utils\n * @name getEnumerableProperties\n * @api public\n */\n\nmodule.exports = function getEnumerableProperties(object) {\n  var result = [];\n  for (var name in object) {\n    result.push(name);\n  }\n  return result;\n};\n\n},{}],16:[function(require,module,exports){\n/*!\n * Chai - message composition utility\n * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com>\n * MIT Licensed\n */\n\n/*!\n * Module dependancies\n */\n\nvar flag = require('./flag')\n  , getActual = require('./getActual')\n  , inspect = require('./inspect')\n  , objDisplay = require('./objDisplay');\n\n/**\n * ### .getMessage(object, message, negateMessage)\n *\n * Construct the error message based on flags\n * and template tags. Template tags will return\n * a stringified inspection of the object referenced.\n *\n * Message template tags:\n * - `#{this}` current asserted object\n * - `#{act}` actual value\n * - `#{exp}` expected value\n *\n * @param {Object} object (constructed Assertion)\n * @param {Arguments} chai.Assertion.prototype.assert arguments\n * @namespace Utils\n * @name getMessage\n * @api public\n */\n\nmodule.exports = function (obj, args) {\n  var negate = flag(obj, 'negate')\n    , val = flag(obj, 'object')\n    , expected = args[3]\n    , actual = getActual(obj, args)\n    , msg = negate ? args[2] : args[1]\n    , flagMsg = flag(obj, 'message');\n\n  if(typeof msg === \"function\") msg = msg();\n  msg = msg || '';\n  msg = msg\n    .replace(/#\\{this\\}/g, function () { return objDisplay(val); })\n    .replace(/#\\{act\\}/g, function () { return objDisplay(actual); })\n    .replace(/#\\{exp\\}/g, function () { return objDisplay(expected); });\n\n  return flagMsg ? flagMsg + ': ' + msg : msg;\n};\n\n},{\"./flag\":13,\"./getActual\":14,\"./inspect\":23,\"./objDisplay\":24}],17:[function(require,module,exports){\n/*!\n * Chai - getName utility\n * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com>\n * MIT Licensed\n */\n\n/**\n * # getName(func)\n *\n * Gets the name of a function, in a cross-browser way.\n *\n * @param {Function} a function (usually a constructor)\n * @namespace Utils\n * @name getName\n */\n\nmodule.exports = function (func) {\n  if (func.name) return func.name;\n\n  var match = /^\\s?function ([^(]*)\\(/.exec(func);\n  return match && match[1] ? match[1] : \"\";\n};\n\n},{}],18:[function(require,module,exports){\n/*!\n * Chai - getPathInfo utility\n * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com>\n * MIT Licensed\n */\n\nvar hasProperty = require('./hasProperty');\n\n/**\n * ### .getPathInfo(path, object)\n *\n * This allows the retrieval of property info in an\n * object given a string path.\n *\n * The path info consists of an object with the\n * following properties:\n *\n * * parent - The parent object of the property referenced by `path`\n * * name - The name of the final property, a number if it was an array indexer\n * * value - The value of the property, if it exists, otherwise `undefined`\n * * exists - Whether the property exists or not\n *\n * @param {String} path\n * @param {Object} object\n * @returns {Object} info\n * @namespace Utils\n * @name getPathInfo\n * @api public\n */\n\nmodule.exports = function getPathInfo(path, obj) {\n  var parsed = parsePath(path),\n      last = parsed[parsed.length - 1];\n\n  var info = {\n    parent: parsed.length > 1 ? _getPathValue(parsed, obj, parsed.length - 1) : obj,\n    name: last.p || last.i,\n    value: _getPathValue(parsed, obj)\n  };\n  info.exists = hasProperty(info.name, info.parent);\n\n  return info;\n};\n\n\n/*!\n * ## parsePath(path)\n *\n * Helper function used to parse string object\n * paths. Use in conjunction with `_getPathValue`.\n *\n *      var parsed = parsePath('myobject.property.subprop');\n *\n * ### Paths:\n *\n * * Can be as near infinitely deep and nested\n * * Arrays are also valid using the formal `myobject.document[3].property`.\n * * Literal dots and brackets (not delimiter) must be backslash-escaped.\n *\n * @param {String} path\n * @returns {Object} parsed\n * @api private\n */\n\nfunction parsePath (path) {\n  var str = path.replace(/([^\\\\])\\[/g, '$1.[')\n    , parts = str.match(/(\\\\\\.|[^.]+?)+/g);\n  return parts.map(function (value) {\n    var re = /^\\[(\\d+)\\]$/\n      , mArr = re.exec(value);\n    if (mArr) return { i: parseFloat(mArr[1]) };\n    else return { p: value.replace(/\\\\([.\\[\\]])/g, '$1') };\n  });\n}\n\n\n/*!\n * ## _getPathValue(parsed, obj)\n *\n * Helper companion function for `.parsePath` that returns\n * the value located at the parsed address.\n *\n *      var value = getPathValue(parsed, obj);\n *\n * @param {Object} parsed definition from `parsePath`.\n * @param {Object} object to search against\n * @param {Number} object to search against\n * @returns {Object|Undefined} value\n * @api private\n */\n\nfunction _getPathValue (parsed, obj, index) {\n  var tmp = obj\n    , res;\n\n  index = (index === undefined ? parsed.length : index);\n\n  for (var i = 0, l = index; i < l; i++) {\n    var part = parsed[i];\n    if (tmp) {\n      if ('undefined' !== typeof part.p)\n        tmp = tmp[part.p];\n      else if ('undefined' !== typeof part.i)\n        tmp = tmp[part.i];\n      if (i == (l - 1)) res = tmp;\n    } else {\n      res = undefined;\n    }\n  }\n  return res;\n}\n\n},{\"./hasProperty\":21}],19:[function(require,module,exports){\n/*!\n * Chai - getPathValue utility\n * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com>\n * @see https://github.com/logicalparadox/filtr\n * MIT Licensed\n */\n\nvar getPathInfo = require('./getPathInfo');\n\n/**\n * ### .getPathValue(path, object)\n *\n * This allows the retrieval of values in an\n * object given a string path.\n *\n *     var obj = {\n *         prop1: {\n *             arr: ['a', 'b', 'c']\n *           , str: 'Hello'\n *         }\n *       , prop2: {\n *             arr: [ { nested: 'Universe' } ]\n *           , str: 'Hello again!'\n *         }\n *     }\n *\n * The following would be the results.\n *\n *     getPathValue('prop1.str', obj); // Hello\n *     getPathValue('prop1.att[2]', obj); // b\n *     getPathValue('prop2.arr[0].nested', obj); // Universe\n *\n * @param {String} path\n * @param {Object} object\n * @returns {Object} value or `undefined`\n * @namespace Utils\n * @name getPathValue\n * @api public\n */\nmodule.exports = function(path, obj) {\n  var info = getPathInfo(path, obj);\n  return info.value;\n};\n\n},{\"./getPathInfo\":18}],20:[function(require,module,exports){\n/*!\n * Chai - getProperties utility\n * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com>\n * MIT Licensed\n */\n\n/**\n * ### .getProperties(object)\n *\n * This allows the retrieval of property names of an object, enumerable or not,\n * inherited or not.\n *\n * @param {Object} object\n * @returns {Array}\n * @namespace Utils\n * @name getProperties\n * @api public\n */\n\nmodule.exports = function getProperties(object) {\n  var result = Object.getOwnPropertyNames(object);\n\n  function addProperty(property) {\n    if (result.indexOf(property) === -1) {\n      result.push(property);\n    }\n  }\n\n  var proto = Object.getPrototypeOf(object);\n  while (proto !== null) {\n    Object.getOwnPropertyNames(proto).forEach(addProperty);\n    proto = Object.getPrototypeOf(proto);\n  }\n\n  return result;\n};\n\n},{}],21:[function(require,module,exports){\n/*!\n * Chai - hasProperty utility\n * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com>\n * MIT Licensed\n */\n\nvar type = require('type-detect');\n\n/**\n * ### .hasProperty(object, name)\n *\n * This allows checking whether an object has\n * named property or numeric array index.\n *\n * Basically does the same thing as the `in`\n * operator but works properly with natives\n * and null/undefined values.\n *\n *     var obj = {\n *         arr: ['a', 'b', 'c']\n *       , str: 'Hello'\n *     }\n *\n * The following would be the results.\n *\n *     hasProperty('str', obj);  // true\n *     hasProperty('constructor', obj);  // true\n *     hasProperty('bar', obj);  // false\n *\n *     hasProperty('length', obj.str); // true\n *     hasProperty(1, obj.str);  // true\n *     hasProperty(5, obj.str);  // false\n *\n *     hasProperty('length', obj.arr);  // true\n *     hasProperty(2, obj.arr);  // true\n *     hasProperty(3, obj.arr);  // false\n *\n * @param {Objuect} object\n * @param {String|Number} name\n * @returns {Boolean} whether it exists\n * @namespace Utils\n * @name getPathInfo\n * @api public\n */\n\nvar literals = {\n    'number': Number\n  , 'string': String\n};\n\nmodule.exports = function hasProperty(name, obj) {\n  var ot = type(obj);\n\n  // Bad Object, obviously no props at all\n  if(ot === 'null' || ot === 'undefined')\n    return false;\n\n  // The `in` operator does not work with certain literals\n  // box these before the check\n  if(literals[ot] && typeof obj !== 'object')\n    obj = new literals[ot](obj);\n\n  return name in obj;\n};\n\n},{\"type-detect\":35}],22:[function(require,module,exports){\n/*!\n * chai\n * Copyright(c) 2011 Jake Luer <jake@alogicalparadox.com>\n * MIT Licensed\n */\n\n/*!\n * Main exports\n */\n\nvar exports = module.exports = {};\n\n/*!\n * test utility\n */\n\nexports.test = require('./test');\n\n/*!\n * type utility\n */\n\nexports.type = require('type-detect');\n\n/*!\n * expectTypes utility\n */\nexports.expectTypes = require('./expectTypes');\n\n/*!\n * message utility\n */\n\nexports.getMessage = require('./getMessage');\n\n/*!\n * actual utility\n */\n\nexports.getActual = require('./getActual');\n\n/*!\n * Inspect util\n */\n\nexports.inspect = require('./inspect');\n\n/*!\n * Object Display util\n */\n\nexports.objDisplay = require('./objDisplay');\n\n/*!\n * Flag utility\n */\n\nexports.flag = require('./flag');\n\n/*!\n * Flag transferring utility\n */\n\nexports.transferFlags = require('./transferFlags');\n\n/*!\n * Deep equal utility\n */\n\nexports.eql = require('deep-eql');\n\n/*!\n * Deep path value\n */\n\nexports.getPathValue = require('./getPathValue');\n\n/*!\n * Deep path info\n */\n\nexports.getPathInfo = require('./getPathInfo');\n\n/*!\n * Check if a property exists\n */\n\nexports.hasProperty = require('./hasProperty');\n\n/*!\n * Function name\n */\n\nexports.getName = require('./getName');\n\n/*!\n * add Property\n */\n\nexports.addProperty = require('./addProperty');\n\n/*!\n * add Method\n */\n\nexports.addMethod = require('./addMethod');\n\n/*!\n * overwrite Property\n */\n\nexports.overwriteProperty = require('./overwriteProperty');\n\n/*!\n * overwrite Method\n */\n\nexports.overwriteMethod = require('./overwriteMethod');\n\n/*!\n * Add a chainable method\n */\n\nexports.addChainableMethod = require('./addChainableMethod');\n\n/*!\n * Overwrite chainable method\n */\n\nexports.overwriteChainableMethod = require('./overwriteChainableMethod');\n\n},{\"./addChainableMethod\":9,\"./addMethod\":10,\"./addProperty\":11,\"./expectTypes\":12,\"./flag\":13,\"./getActual\":14,\"./getMessage\":16,\"./getName\":17,\"./getPathInfo\":18,\"./getPathValue\":19,\"./hasProperty\":21,\"./inspect\":23,\"./objDisplay\":24,\"./overwriteChainableMethod\":25,\"./overwriteMethod\":26,\"./overwriteProperty\":27,\"./test\":28,\"./transferFlags\":29,\"deep-eql\":31,\"type-detect\":35}],23:[function(require,module,exports){\n// This is (almost) directly from Node.js utils\n// https://github.com/joyent/node/blob/f8c335d0caf47f16d31413f89aa28eda3878e3aa/lib/util.js\n\nvar getName = require('./getName');\nvar getProperties = require('./getProperties');\nvar getEnumerableProperties = require('./getEnumerableProperties');\n\nmodule.exports = inspect;\n\n/**\n * Echos the value of a value. Trys to print the value out\n * in the best way possible given the different types.\n *\n * @param {Object} obj The object to print out.\n * @param {Boolean} showHidden Flag that shows hidden (not enumerable)\n *    properties of objects.\n * @param {Number} depth Depth in which to descend in object. Default is 2.\n * @param {Boolean} colors Flag to turn on ANSI escape codes to color the\n *    output. Default is false (no coloring).\n * @namespace Utils\n * @name inspect\n */\nfunction inspect(obj, showHidden, depth, colors) {\n  var ctx = {\n    showHidden: showHidden,\n    seen: [],\n    stylize: function (str) { return str; }\n  };\n  return formatValue(ctx, obj, (typeof depth === 'undefined' ? 2 : depth));\n}\n\n// Returns true if object is a DOM element.\nvar isDOMElement = function (object) {\n  if (typeof HTMLElement === 'object') {\n    return object instanceof HTMLElement;\n  } else {\n    return object &&\n      typeof object === 'object' &&\n      object.nodeType === 1 &&\n      typeof object.nodeName === 'string';\n  }\n};\n\nfunction formatValue(ctx, value, recurseTimes) {\n  // Provide a hook for user-specified inspect functions.\n  // Check that value is an object with an inspect function on it\n  if (value && typeof value.inspect === 'function' &&\n      // Filter out the util module, it's inspect function is special\n      value.inspect !== exports.inspect &&\n      // Also filter out any prototype objects using the circular check.\n      !(value.constructor && value.constructor.prototype === value)) {\n    var ret = value.inspect(recurseTimes);\n    if (typeof ret !== 'string') {\n      ret = formatValue(ctx, ret, recurseTimes);\n    }\n    return ret;\n  }\n\n  // Primitive types cannot have properties\n  var primitive = formatPrimitive(ctx, value);\n  if (primitive) {\n    return primitive;\n  }\n\n  // If this is a DOM element, try to get the outer HTML.\n  if (isDOMElement(value)) {\n    if ('outerHTML' in value) {\n      return value.outerHTML;\n      // This value does not have an outerHTML attribute,\n      //   it could still be an XML element\n    } else {\n      // Attempt to serialize it\n      try {\n        if (document.xmlVersion) {\n          var xmlSerializer = new XMLSerializer();\n          return xmlSerializer.serializeToString(value);\n        } else {\n          // Firefox 11- do not support outerHTML\n          //   It does, however, support innerHTML\n          //   Use the following to render the element\n          var ns = \"http://www.w3.org/1999/xhtml\";\n          var container = document.createElementNS(ns, '_');\n\n          container.appendChild(value.cloneNode(false));\n          html = container.innerHTML\n            .replace('><', '>' + value.innerHTML + '<');\n          container.innerHTML = '';\n          return html;\n        }\n      } catch (err) {\n        // This could be a non-native DOM implementation,\n        //   continue with the normal flow:\n        //   printing the element as if it is an object.\n      }\n    }\n  }\n\n  // Look up the keys of the object.\n  var visibleKeys = getEnumerableProperties(value);\n  var keys = ctx.showHidden ? getProperties(value) : visibleKeys;\n\n  // Some type of object without properties can be shortcutted.\n  // In IE, errors have a single `stack` property, or if they are vanilla `Error`,\n  // a `stack` plus `description` property; ignore those for consistency.\n  if (keys.length === 0 || (isError(value) && (\n      (keys.length === 1 && keys[0] === 'stack') ||\n      (keys.length === 2 && keys[0] === 'description' && keys[1] === 'stack')\n     ))) {\n    if (typeof value === 'function') {\n      var name = getName(value);\n      var nameSuffix = name ? ': ' + name : '';\n      return ctx.stylize('[Function' + nameSuffix + ']', 'special');\n    }\n    if (isRegExp(value)) {\n      return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp');\n    }\n    if (isDate(value)) {\n      return ctx.stylize(Date.prototype.toUTCString.call(value), 'date');\n    }\n    if (isError(value)) {\n      return formatError(value);\n    }\n  }\n\n  var base = '', array = false, braces = ['{', '}'];\n\n  // Make Array say that they are Array\n  if (isArray(value)) {\n    array = true;\n    braces = ['[', ']'];\n  }\n\n  // Make functions say that they are functions\n  if (typeof value === 'function') {\n    var name = getName(value);\n    var nameSuffix = name ? ': ' + name : '';\n    base = ' [Function' + nameSuffix + ']';\n  }\n\n  // Make RegExps say that they are RegExps\n  if (isRegExp(value)) {\n    base = ' ' + RegExp.prototype.toString.call(value);\n  }\n\n  // Make dates with properties first say the date\n  if (isDate(value)) {\n    base = ' ' + Date.prototype.toUTCString.call(value);\n  }\n\n  // Make error with message first say the error\n  if (isError(value)) {\n    return formatError(value);\n  }\n\n  if (keys.length === 0 && (!array || value.length == 0)) {\n    return braces[0] + base + braces[1];\n  }\n\n  if (recurseTimes < 0) {\n    if (isRegExp(value)) {\n      return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp');\n    } else {\n      return ctx.stylize('[Object]', 'special');\n    }\n  }\n\n  ctx.seen.push(value);\n\n  var output;\n  if (array) {\n    output = formatArray(ctx, value, recurseTimes, visibleKeys, keys);\n  } else {\n    output = keys.map(function(key) {\n      return formatProperty(ctx, value, recurseTimes, visibleKeys, key, array);\n    });\n  }\n\n  ctx.seen.pop();\n\n  return reduceToSingleString(output, base, braces);\n}\n\n\nfunction formatPrimitive(ctx, value) {\n  switch (typeof value) {\n    case 'undefined':\n      return ctx.stylize('undefined', 'undefined');\n\n    case 'string':\n      var simple = '\\'' + JSON.stringify(value).replace(/^\"|\"$/g, '')\n                                               .replace(/'/g, \"\\\\'\")\n                                               .replace(/\\\\\"/g, '\"') + '\\'';\n      return ctx.stylize(simple, 'string');\n\n    case 'number':\n      if (value === 0 && (1/value) === -Infinity) {\n        return ctx.stylize('-0', 'number');\n      }\n      return ctx.stylize('' + value, 'number');\n\n    case 'boolean':\n      return ctx.stylize('' + value, 'boolean');\n  }\n  // For some reason typeof null is \"object\", so special case here.\n  if (value === null) {\n    return ctx.stylize('null', 'null');\n  }\n}\n\n\nfunction formatError(value) {\n  return '[' + Error.prototype.toString.call(value) + ']';\n}\n\n\nfunction formatArray(ctx, value, recurseTimes, visibleKeys, keys) {\n  var output = [];\n  for (var i = 0, l = value.length; i < l; ++i) {\n    if (Object.prototype.hasOwnProperty.call(value, String(i))) {\n      output.push(formatProperty(ctx, value, recurseTimes, visibleKeys,\n          String(i), true));\n    } else {\n      output.push('');\n    }\n  }\n  keys.forEach(function(key) {\n    if (!key.match(/^\\d+$/)) {\n      output.push(formatProperty(ctx, value, recurseTimes, visibleKeys,\n          key, true));\n    }\n  });\n  return output;\n}\n\n\nfunction formatProperty(ctx, value, recurseTimes, visibleKeys, key, array) {\n  var name, str;\n  if (value.__lookupGetter__) {\n    if (value.__lookupGetter__(key)) {\n      if (value.__lookupSetter__(key)) {\n        str = ctx.stylize('[Getter/Setter]', 'special');\n      } else {\n        str = ctx.stylize('[Getter]', 'special');\n      }\n    } else {\n      if (value.__lookupSetter__(key)) {\n        str = ctx.stylize('[Setter]', 'special');\n      }\n    }\n  }\n  if (visibleKeys.indexOf(key) < 0) {\n    name = '[' + key + ']';\n  }\n  if (!str) {\n    if (ctx.seen.indexOf(value[key]) < 0) {\n      if (recurseTimes === null) {\n        str = formatValue(ctx, value[key], null);\n      } else {\n        str = formatValue(ctx, value[key], recurseTimes - 1);\n      }\n      if (str.indexOf('\\n') > -1) {\n        if (array) {\n          str = str.split('\\n').map(function(line) {\n            return '  ' + line;\n          }).join('\\n').substr(2);\n        } else {\n          str = '\\n' + str.split('\\n').map(function(line) {\n            return '   ' + line;\n          }).join('\\n');\n        }\n      }\n    } else {\n      str = ctx.stylize('[Circular]', 'special');\n    }\n  }\n  if (typeof name === 'undefined') {\n    if (array && key.match(/^\\d+$/)) {\n      return str;\n    }\n    name = JSON.stringify('' + key);\n    if (name.match(/^\"([a-zA-Z_][a-zA-Z_0-9]*)\"$/)) {\n      name = name.substr(1, name.length - 2);\n      name = ctx.stylize(name, 'name');\n    } else {\n      name = name.replace(/'/g, \"\\\\'\")\n                 .replace(/\\\\\"/g, '\"')\n                 .replace(/(^\"|\"$)/g, \"'\");\n      name = ctx.stylize(name, 'string');\n    }\n  }\n\n  return name + ': ' + str;\n}\n\n\nfunction reduceToSingleString(output, base, braces) {\n  var numLinesEst = 0;\n  var length = output.reduce(function(prev, cur) {\n    numLinesEst++;\n    if (cur.indexOf('\\n') >= 0) numLinesEst++;\n    return prev + cur.length + 1;\n  }, 0);\n\n  if (length > 60) {\n    return braces[0] +\n           (base === '' ? '' : base + '\\n ') +\n           ' ' +\n           output.join(',\\n  ') +\n           ' ' +\n           braces[1];\n  }\n\n  return braces[0] + base + ' ' + output.join(', ') + ' ' + braces[1];\n}\n\nfunction isArray(ar) {\n  return Array.isArray(ar) ||\n         (typeof ar === 'object' && objectToString(ar) === '[object Array]');\n}\n\nfunction isRegExp(re) {\n  return typeof re === 'object' && objectToString(re) === '[object RegExp]';\n}\n\nfunction isDate(d) {\n  return typeof d === 'object' && objectToString(d) === '[object Date]';\n}\n\nfunction isError(e) {\n  return typeof e === 'object' && objectToString(e) === '[object Error]';\n}\n\nfunction objectToString(o) {\n  return Object.prototype.toString.call(o);\n}\n\n},{\"./getEnumerableProperties\":15,\"./getName\":17,\"./getProperties\":20}],24:[function(require,module,exports){\n/*!\n * Chai - flag utility\n * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com>\n * MIT Licensed\n */\n\n/*!\n * Module dependancies\n */\n\nvar inspect = require('./inspect');\nvar config = require('../config');\n\n/**\n * ### .objDisplay (object)\n *\n * Determines if an object or an array matches\n * criteria to be inspected in-line for error\n * messages or should be truncated.\n *\n * @param {Mixed} javascript object to inspect\n * @name objDisplay\n * @namespace Utils\n * @api public\n */\n\nmodule.exports = function (obj) {\n  var str = inspect(obj)\n    , type = Object.prototype.toString.call(obj);\n\n  if (config.truncateThreshold && str.length >= config.truncateThreshold) {\n    if (type === '[object Function]') {\n      return !obj.name || obj.name === ''\n        ? '[Function]'\n        : '[Function: ' + obj.name + ']';\n    } else if (type === '[object Array]') {\n      return '[ Array(' + obj.length + ') ]';\n    } else if (type === '[object Object]') {\n      var keys = Object.keys(obj)\n        , kstr = keys.length > 2\n          ? keys.splice(0, 2).join(', ') + ', ...'\n          : keys.join(', ');\n      return '{ Object (' + kstr + ') }';\n    } else {\n      return str;\n    }\n  } else {\n    return str;\n  }\n};\n\n},{\"../config\":4,\"./inspect\":23}],25:[function(require,module,exports){\n/*!\n * Chai - overwriteChainableMethod utility\n * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com>\n * MIT Licensed\n */\n\n/**\n * ### overwriteChainableMethod (ctx, name, method, chainingBehavior)\n *\n * Overwites an already existing chainable method\n * and provides access to the previous function or\n * property.  Must return functions to be used for\n * name.\n *\n *     utils.overwriteChainableMethod(chai.Assertion.prototype, 'length',\n *       function (_super) {\n *       }\n *     , function (_super) {\n *       }\n *     );\n *\n * Can also be accessed directly from `chai.Assertion`.\n *\n *     chai.Assertion.overwriteChainableMethod('foo', fn, fn);\n *\n * Then can be used as any other assertion.\n *\n *     expect(myFoo).to.have.length(3);\n *     expect(myFoo).to.have.length.above(3);\n *\n * @param {Object} ctx object whose method / property is to be overwritten\n * @param {String} name of method / property to overwrite\n * @param {Function} method function that returns a function to be used for name\n * @param {Function} chainingBehavior function that returns a function to be used for property\n * @namespace Utils\n * @name overwriteChainableMethod\n * @api public\n */\n\nmodule.exports = function (ctx, name, method, chainingBehavior) {\n  var chainableBehavior = ctx.__methods[name];\n\n  var _chainingBehavior = chainableBehavior.chainingBehavior;\n  chainableBehavior.chainingBehavior = function () {\n    var result = chainingBehavior(_chainingBehavior).call(this);\n    return result === undefined ? this : result;\n  };\n\n  var _method = chainableBehavior.method;\n  chainableBehavior.method = function () {\n    var result = method(_method).apply(this, arguments);\n    return result === undefined ? this : result;\n  };\n};\n\n},{}],26:[function(require,module,exports){\n/*!\n * Chai - overwriteMethod utility\n * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com>\n * MIT Licensed\n */\n\n/**\n * ### overwriteMethod (ctx, name, fn)\n *\n * Overwites an already existing method and provides\n * access to previous function. Must return function\n * to be used for name.\n *\n *     utils.overwriteMethod(chai.Assertion.prototype, 'equal', function (_super) {\n *       return function (str) {\n *         var obj = utils.flag(this, 'object');\n *         if (obj instanceof Foo) {\n *           new chai.Assertion(obj.value).to.equal(str);\n *         } else {\n *           _super.apply(this, arguments);\n *         }\n *       }\n *     });\n *\n * Can also be accessed directly from `chai.Assertion`.\n *\n *     chai.Assertion.overwriteMethod('foo', fn);\n *\n * Then can be used as any other assertion.\n *\n *     expect(myFoo).to.equal('bar');\n *\n * @param {Object} ctx object whose method is to be overwritten\n * @param {String} name of method to overwrite\n * @param {Function} method function that returns a function to be used for name\n * @namespace Utils\n * @name overwriteMethod\n * @api public\n */\n\nmodule.exports = function (ctx, name, method) {\n  var _method = ctx[name]\n    , _super = function () { return this; };\n\n  if (_method && 'function' === typeof _method)\n    _super = _method;\n\n  ctx[name] = function () {\n    var result = method(_super).apply(this, arguments);\n    return result === undefined ? this : result;\n  }\n};\n\n},{}],27:[function(require,module,exports){\n/*!\n * Chai - overwriteProperty utility\n * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com>\n * MIT Licensed\n */\n\n/**\n * ### overwriteProperty (ctx, name, fn)\n *\n * Overwites an already existing property getter and provides\n * access to previous value. Must return function to use as getter.\n *\n *     utils.overwriteProperty(chai.Assertion.prototype, 'ok', function (_super) {\n *       return function () {\n *         var obj = utils.flag(this, 'object');\n *         if (obj instanceof Foo) {\n *           new chai.Assertion(obj.name).to.equal('bar');\n *         } else {\n *           _super.call(this);\n *         }\n *       }\n *     });\n *\n *\n * Can also be accessed directly from `chai.Assertion`.\n *\n *     chai.Assertion.overwriteProperty('foo', fn);\n *\n * Then can be used as any other assertion.\n *\n *     expect(myFoo).to.be.ok;\n *\n * @param {Object} ctx object whose property is to be overwritten\n * @param {String} name of property to overwrite\n * @param {Function} getter function that returns a getter function to be used for name\n * @namespace Utils\n * @name overwriteProperty\n * @api public\n */\n\nmodule.exports = function (ctx, name, getter) {\n  var _get = Object.getOwnPropertyDescriptor(ctx, name)\n    , _super = function () {};\n\n  if (_get && 'function' === typeof _get.get)\n    _super = _get.get\n\n  Object.defineProperty(ctx, name,\n    { get: function () {\n        var result = getter(_super).call(this);\n        return result === undefined ? this : result;\n      }\n    , configurable: true\n  });\n};\n\n},{}],28:[function(require,module,exports){\n/*!\n * Chai - test utility\n * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com>\n * MIT Licensed\n */\n\n/*!\n * Module dependancies\n */\n\nvar flag = require('./flag');\n\n/**\n * # test(object, expression)\n *\n * Test and object for expression.\n *\n * @param {Object} object (constructed Assertion)\n * @param {Arguments} chai.Assertion.prototype.assert arguments\n * @namespace Utils\n * @name test\n */\n\nmodule.exports = function (obj, args) {\n  var negate = flag(obj, 'negate')\n    , expr = args[0];\n  return negate ? !expr : expr;\n};\n\n},{\"./flag\":13}],29:[function(require,module,exports){\n/*!\n * Chai - transferFlags utility\n * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com>\n * MIT Licensed\n */\n\n/**\n * ### transferFlags(assertion, object, includeAll = true)\n *\n * Transfer all the flags for `assertion` to `object`. If\n * `includeAll` is set to `false`, then the base Chai\n * assertion flags (namely `object`, `ssfi`, and `message`)\n * will not be transferred.\n *\n *\n *     var newAssertion = new Assertion();\n *     utils.transferFlags(assertion, newAssertion);\n *\n *     var anotherAsseriton = new Assertion(myObj);\n *     utils.transferFlags(assertion, anotherAssertion, false);\n *\n * @param {Assertion} assertion the assertion to transfer the flags from\n * @param {Object} object the object to transfer the flags to; usually a new assertion\n * @param {Boolean} includeAll\n * @namespace Utils\n * @name transferFlags\n * @api private\n */\n\nmodule.exports = function (assertion, object, includeAll) {\n  var flags = assertion.__flags || (assertion.__flags = Object.create(null));\n\n  if (!object.__flags) {\n    object.__flags = Object.create(null);\n  }\n\n  includeAll = arguments.length === 3 ? includeAll : true;\n\n  for (var flag in flags) {\n    if (includeAll ||\n        (flag !== 'object' && flag !== 'ssfi' && flag != 'message')) {\n      object.__flags[flag] = flags[flag];\n    }\n  }\n};\n\n},{}],30:[function(require,module,exports){\n/*!\n * assertion-error\n * Copyright(c) 2013 Jake Luer <jake@qualiancy.com>\n * MIT Licensed\n */\n\n/*!\n * Return a function that will copy properties from\n * one object to another excluding any originally\n * listed. Returned function will create a new `{}`.\n *\n * @param {String} excluded properties ...\n * @return {Function}\n */\n\nfunction exclude () {\n  var excludes = [].slice.call(arguments);\n\n  function excludeProps (res, obj) {\n    Object.keys(obj).forEach(function (key) {\n      if (!~excludes.indexOf(key)) res[key] = obj[key];\n    });\n  }\n\n  return function extendExclude () {\n    var args = [].slice.call(arguments)\n      , i = 0\n      , res = {};\n\n    for (; i < args.length; i++) {\n      excludeProps(res, args[i]);\n    }\n\n    return res;\n  };\n};\n\n/*!\n * Primary Exports\n */\n\nmodule.exports = AssertionError;\n\n/**\n * ### AssertionError\n *\n * An extension of the JavaScript `Error` constructor for\n * assertion and validation scenarios.\n *\n * @param {String} message\n * @param {Object} properties to include (optional)\n * @param {callee} start stack function (optional)\n */\n\nfunction AssertionError (message, _props, ssf) {\n  var extend = exclude('name', 'message', 'stack', 'constructor', 'toJSON')\n    , props = extend(_props || {});\n\n  // default values\n  this.message = message || 'Unspecified AssertionError';\n  this.showDiff = false;\n\n  // copy from properties\n  for (var key in props) {\n    this[key] = props[key];\n  }\n\n  // capture stack trace\n  ssf = ssf || arguments.callee;\n  if (ssf && Error.captureStackTrace) {\n    Error.captureStackTrace(this, ssf);\n  } else {\n    this.stack = new Error().stack;\n  }\n}\n\n/*!\n * Inherit from Error.prototype\n */\n\nAssertionError.prototype = Object.create(Error.prototype);\n\n/*!\n * Statically set name\n */\n\nAssertionError.prototype.name = 'AssertionError';\n\n/*!\n * Ensure correct constructor\n */\n\nAssertionError.prototype.constructor = AssertionError;\n\n/**\n * Allow errors to be converted to JSON for static transfer.\n *\n * @param {Boolean} include stack (default: `true`)\n * @return {Object} object that can be `JSON.stringify`\n */\n\nAssertionError.prototype.toJSON = function (stack) {\n  var extend = exclude('constructor', 'toJSON', 'stack')\n    , props = extend({ name: this.name }, this);\n\n  // include stack if exists and not turned off\n  if (false !== stack && this.stack) {\n    props.stack = this.stack;\n  }\n\n  return props;\n};\n\n},{}],31:[function(require,module,exports){\nmodule.exports = require('./lib/eql');\n\n},{\"./lib/eql\":32}],32:[function(require,module,exports){\n/*!\n * deep-eql\n * Copyright(c) 2013 Jake Luer <jake@alogicalparadox.com>\n * MIT Licensed\n */\n\n/*!\n * Module dependencies\n */\n\nvar type = require('type-detect');\n\n/*!\n * Buffer.isBuffer browser shim\n */\n\nvar Buffer;\ntry { Buffer = require('buffer').Buffer; }\ncatch(ex) {\n  Buffer = {};\n  Buffer.isBuffer = function() { return false; }\n}\n\n/*!\n * Primary Export\n */\n\nmodule.exports = deepEqual;\n\n/**\n * Assert super-strict (egal) equality between\n * two objects of any type.\n *\n * @param {Mixed} a\n * @param {Mixed} b\n * @param {Array} memoised (optional)\n * @return {Boolean} equal match\n */\n\nfunction deepEqual(a, b, m) {\n  if (sameValue(a, b)) {\n    return true;\n  } else if ('date' === type(a)) {\n    return dateEqual(a, b);\n  } else if ('regexp' === type(a)) {\n    return regexpEqual(a, b);\n  } else if (Buffer.isBuffer(a)) {\n    return bufferEqual(a, b);\n  } else if ('arguments' === type(a)) {\n    return argumentsEqual(a, b, m);\n  } else if (!typeEqual(a, b)) {\n    return false;\n  } else if (('object' !== type(a) && 'object' !== type(b))\n  && ('array' !== type(a) && 'array' !== type(b))) {\n    return sameValue(a, b);\n  } else {\n    return objectEqual(a, b, m);\n  }\n}\n\n/*!\n * Strict (egal) equality test. Ensures that NaN always\n * equals NaN and `-0` does not equal `+0`.\n *\n * @param {Mixed} a\n * @param {Mixed} b\n * @return {Boolean} equal match\n */\n\nfunction sameValue(a, b) {\n  if (a === b) return a !== 0 || 1 / a === 1 / b;\n  return a !== a && b !== b;\n}\n\n/*!\n * Compare the types of two given objects and\n * return if they are equal. Note that an Array\n * has a type of `array` (not `object`) and arguments\n * have a type of `arguments` (not `array`/`object`).\n *\n * @param {Mixed} a\n * @param {Mixed} b\n * @return {Boolean} result\n */\n\nfunction typeEqual(a, b) {\n  return type(a) === type(b);\n}\n\n/*!\n * Compare two Date objects by asserting that\n * the time values are equal using `saveValue`.\n *\n * @param {Date} a\n * @param {Date} b\n * @return {Boolean} result\n */\n\nfunction dateEqual(a, b) {\n  if ('date' !== type(b)) return false;\n  return sameValue(a.getTime(), b.getTime());\n}\n\n/*!\n * Compare two regular expressions by converting them\n * to string and checking for `sameValue`.\n *\n * @param {RegExp} a\n * @param {RegExp} b\n * @return {Boolean} result\n */\n\nfunction regexpEqual(a, b) {\n  if ('regexp' !== type(b)) return false;\n  return sameValue(a.toString(), b.toString());\n}\n\n/*!\n * Assert deep equality of two `arguments` objects.\n * Unfortunately, these must be sliced to arrays\n * prior to test to ensure no bad behavior.\n *\n * @param {Arguments} a\n * @param {Arguments} b\n * @param {Array} memoize (optional)\n * @return {Boolean} result\n */\n\nfunction argumentsEqual(a, b, m) {\n  if ('arguments' !== type(b)) return false;\n  a = [].slice.call(a);\n  b = [].slice.call(b);\n  return deepEqual(a, b, m);\n}\n\n/*!\n * Get enumerable properties of a given object.\n *\n * @param {Object} a\n * @return {Array} property names\n */\n\nfunction enumerable(a) {\n  var res = [];\n  for (var key in a) res.push(key);\n  return res;\n}\n\n/*!\n * Simple equality for flat iterable objects\n * such as Arrays or Node.js buffers.\n *\n * @param {Iterable} a\n * @param {Iterable} b\n * @return {Boolean} result\n */\n\nfunction iterableEqual(a, b) {\n  if (a.length !==  b.length) return false;\n\n  var i = 0;\n  var match = true;\n\n  for (; i < a.length; i++) {\n    if (a[i] !== b[i]) {\n      match = false;\n      break;\n    }\n  }\n\n  return match;\n}\n\n/*!\n * Extension to `iterableEqual` specifically\n * for Node.js Buffers.\n *\n * @param {Buffer} a\n * @param {Mixed} b\n * @return {Boolean} result\n */\n\nfunction bufferEqual(a, b) {\n  if (!Buffer.isBuffer(b)) return false;\n  return iterableEqual(a, b);\n}\n\n/*!\n * Block for `objectEqual` ensuring non-existing\n * values don't get in.\n *\n * @param {Mixed} object\n * @return {Boolean} result\n */\n\nfunction isValue(a) {\n  return a !== null && a !== undefined;\n}\n\n/*!\n * Recursively check the equality of two objects.\n * Once basic sameness has been established it will\n * defer to `deepEqual` for each enumerable key\n * in the object.\n *\n * @param {Mixed} a\n * @param {Mixed} b\n * @return {Boolean} result\n */\n\nfunction objectEqual(a, b, m) {\n  if (!isValue(a) || !isValue(b)) {\n    return false;\n  }\n\n  if (a.prototype !== b.prototype) {\n    return false;\n  }\n\n  var i;\n  if (m) {\n    for (i = 0; i < m.length; i++) {\n      if ((m[i][0] === a && m[i][1] === b)\n      ||  (m[i][0] === b && m[i][1] === a)) {\n        return true;\n      }\n    }\n  } else {\n    m = [];\n  }\n\n  try {\n    var ka = enumerable(a);\n    var kb = enumerable(b);\n  } catch (ex) {\n    return false;\n  }\n\n  ka.sort();\n  kb.sort();\n\n  if (!iterableEqual(ka, kb)) {\n    return false;\n  }\n\n  m.push([ a, b ]);\n\n  var key;\n  for (i = ka.length - 1; i >= 0; i--) {\n    key = ka[i];\n    if (!deepEqual(a[key], b[key], m)) {\n      return false;\n    }\n  }\n\n  return true;\n}\n\n},{\"buffer\":undefined,\"type-detect\":33}],33:[function(require,module,exports){\nmodule.exports = require('./lib/type');\n\n},{\"./lib/type\":34}],34:[function(require,module,exports){\n/*!\n * type-detect\n * Copyright(c) 2013 jake luer <jake@alogicalparadox.com>\n * MIT Licensed\n */\n\n/*!\n * Primary Exports\n */\n\nvar exports = module.exports = getType;\n\n/*!\n * Detectable javascript natives\n */\n\nvar natives = {\n    '[object Array]': 'array'\n  , '[object RegExp]': 'regexp'\n  , '[object Function]': 'function'\n  , '[object Arguments]': 'arguments'\n  , '[object Date]': 'date'\n};\n\n/**\n * ### typeOf (obj)\n *\n * Use several different techniques to determine\n * the type of object being tested.\n *\n *\n * @param {Mixed} object\n * @return {String} object type\n * @api public\n */\n\nfunction getType (obj) {\n  var str = Object.prototype.toString.call(obj);\n  if (natives[str]) return natives[str];\n  if (obj === null) return 'null';\n  if (obj === undefined) return 'undefined';\n  if (obj === Object(obj)) return 'object';\n  return typeof obj;\n}\n\nexports.Library = Library;\n\n/**\n * ### Library\n *\n * Create a repository for custom type detection.\n *\n * ```js\n * var lib = new type.Library;\n * ```\n *\n */\n\nfunction Library () {\n  this.tests = {};\n}\n\n/**\n * #### .of (obj)\n *\n * Expose replacement `typeof` detection to the library.\n *\n * ```js\n * if ('string' === lib.of('hello world')) {\n *   // ...\n * }\n * ```\n *\n * @param {Mixed} object to test\n * @return {String} type\n */\n\nLibrary.prototype.of = getType;\n\n/**\n * #### .define (type, test)\n *\n * Add a test to for the `.test()` assertion.\n *\n * Can be defined as a regular expression:\n *\n * ```js\n * lib.define('int', /^[0-9]+$/);\n * ```\n *\n * ... or as a function:\n *\n * ```js\n * lib.define('bln', function (obj) {\n *   if ('boolean' === lib.of(obj)) return true;\n *   var blns = [ 'yes', 'no', 'true', 'false', 1, 0 ];\n *   if ('string' === lib.of(obj)) obj = obj.toLowerCase();\n *   return !! ~blns.indexOf(obj);\n * });\n * ```\n *\n * @param {String} type\n * @param {RegExp|Function} test\n * @api public\n */\n\nLibrary.prototype.define = function (type, test) {\n  if (arguments.length === 1) return this.tests[type];\n  this.tests[type] = test;\n  return this;\n};\n\n/**\n * #### .test (obj, test)\n *\n * Assert that an object is of type. Will first\n * check natives, and if that does not pass it will\n * use the user defined custom tests.\n *\n * ```js\n * assert(lib.test('1', 'int'));\n * assert(lib.test('yes', 'bln'));\n * ```\n *\n * @param {Mixed} object\n * @param {String} type\n * @return {Boolean} result\n * @api public\n */\n\nLibrary.prototype.test = function (obj, type) {\n  if (type === getType(obj)) return true;\n  var test = this.tests[type];\n\n  if (test && 'regexp' === getType(test)) {\n    return test.test(obj);\n  } else if (test && 'function' === getType(test)) {\n    return test(obj);\n  } else {\n    throw new ReferenceError('Type test \"' + type + '\" not defined or invalid.');\n  }\n};\n\n},{}],35:[function(require,module,exports){\narguments[4][33][0].apply(exports,arguments)\n},{\"./lib/type\":36,\"dup\":33}],36:[function(require,module,exports){\n/*!\n * type-detect\n * Copyright(c) 2013 jake luer <jake@alogicalparadox.com>\n * MIT Licensed\n */\n\n/*!\n * Primary Exports\n */\n\nvar exports = module.exports = getType;\n\n/**\n * ### typeOf (obj)\n *\n * Use several different techniques to determine\n * the type of object being tested.\n *\n *\n * @param {Mixed} object\n * @return {String} object type\n * @api public\n */\nvar objectTypeRegexp = /^\\[object (.*)\\]$/;\n\nfunction getType(obj) {\n  var type = Object.prototype.toString.call(obj).match(objectTypeRegexp)[1].toLowerCase();\n  // Let \"new String('')\" return 'object'\n  if (typeof Promise === 'function' && obj instanceof Promise) return 'promise';\n  // PhantomJS has type \"DOMWindow\" for null\n  if (obj === null) return 'null';\n  // PhantomJS has type \"DOMWindow\" for undefined\n  if (obj === undefined) return 'undefined';\n  return type;\n}\n\nexports.Library = Library;\n\n/**\n * ### Library\n *\n * Create a repository for custom type detection.\n *\n * ```js\n * var lib = new type.Library;\n * ```\n *\n */\n\nfunction Library() {\n  if (!(this instanceof Library)) return new Library();\n  this.tests = {};\n}\n\n/**\n * #### .of (obj)\n *\n * Expose replacement `typeof` detection to the library.\n *\n * ```js\n * if ('string' === lib.of('hello world')) {\n *   // ...\n * }\n * ```\n *\n * @param {Mixed} object to test\n * @return {String} type\n */\n\nLibrary.prototype.of = getType;\n\n/**\n * #### .define (type, test)\n *\n * Add a test to for the `.test()` assertion.\n *\n * Can be defined as a regular expression:\n *\n * ```js\n * lib.define('int', /^[0-9]+$/);\n * ```\n *\n * ... or as a function:\n *\n * ```js\n * lib.define('bln', function (obj) {\n *   if ('boolean' === lib.of(obj)) return true;\n *   var blns = [ 'yes', 'no', 'true', 'false', 1, 0 ];\n *   if ('string' === lib.of(obj)) obj = obj.toLowerCase();\n *   return !! ~blns.indexOf(obj);\n * });\n * ```\n *\n * @param {String} type\n * @param {RegExp|Function} test\n * @api public\n */\n\nLibrary.prototype.define = function(type, test) {\n  if (arguments.length === 1) return this.tests[type];\n  this.tests[type] = test;\n  return this;\n};\n\n/**\n * #### .test (obj, test)\n *\n * Assert that an object is of type. Will first\n * check natives, and if that does not pass it will\n * use the user defined custom tests.\n *\n * ```js\n * assert(lib.test('1', 'int'));\n * assert(lib.test('yes', 'bln'));\n * ```\n *\n * @param {Mixed} object\n * @param {String} type\n * @return {Boolean} result\n * @api public\n */\n\nLibrary.prototype.test = function(obj, type) {\n  if (type === getType(obj)) return true;\n  var test = this.tests[type];\n\n  if (test && 'regexp' === getType(test)) {\n    return test.test(obj);\n  } else if (test && 'function' === getType(test)) {\n    return test(obj);\n  } else {\n    throw new ReferenceError('Type test \"' + type + '\" not defined or invalid.');\n  }\n};\n\n},{}]},{},[1])(1)\n});\n"
  },
  {
    "path": "app_backend/static/plugin/JavaScript-Load-Image-2.12.2/test/vendor/mocha.css",
    "content": "@charset \"utf-8\";\n\nbody {\n  margin:0;\n}\n\n#mocha {\n  font: 20px/1.5 \"Helvetica Neue\", Helvetica, Arial, sans-serif;\n  margin: 60px 50px;\n}\n\n#mocha ul,\n#mocha li {\n  margin: 0;\n  padding: 0;\n}\n\n#mocha ul {\n  list-style: none;\n}\n\n#mocha h1,\n#mocha h2 {\n  margin: 0;\n}\n\n#mocha h1 {\n  margin-top: 15px;\n  font-size: 1em;\n  font-weight: 200;\n}\n\n#mocha h1 a {\n  text-decoration: none;\n  color: inherit;\n}\n\n#mocha h1 a:hover {\n  text-decoration: underline;\n}\n\n#mocha .suite .suite h1 {\n  margin-top: 0;\n  font-size: .8em;\n}\n\n#mocha .hidden {\n  display: none;\n}\n\n#mocha h2 {\n  font-size: 12px;\n  font-weight: normal;\n  cursor: pointer;\n}\n\n#mocha .suite {\n  margin-left: 15px;\n}\n\n#mocha .test {\n  margin-left: 15px;\n  overflow: hidden;\n}\n\n#mocha .test.pending:hover h2::after {\n  content: '(pending)';\n  font-family: arial, sans-serif;\n}\n\n#mocha .test.pass.medium .duration {\n  background: #c09853;\n}\n\n#mocha .test.pass.slow .duration {\n  background: #b94a48;\n}\n\n#mocha .test.pass::before {\n  content: '✓';\n  font-size: 12px;\n  display: block;\n  float: left;\n  margin-right: 5px;\n  color: #00d6b2;\n}\n\n#mocha .test.pass .duration {\n  font-size: 9px;\n  margin-left: 5px;\n  padding: 2px 5px;\n  color: #fff;\n  -webkit-box-shadow: inset 0 1px 1px rgba(0,0,0,.2);\n  -moz-box-shadow: inset 0 1px 1px rgba(0,0,0,.2);\n  box-shadow: inset 0 1px 1px rgba(0,0,0,.2);\n  -webkit-border-radius: 5px;\n  -moz-border-radius: 5px;\n  -ms-border-radius: 5px;\n  -o-border-radius: 5px;\n  border-radius: 5px;\n}\n\n#mocha .test.pass.fast .duration {\n  display: none;\n}\n\n#mocha .test.pending {\n  color: #0b97c4;\n}\n\n#mocha .test.pending::before {\n  content: '◦';\n  color: #0b97c4;\n}\n\n#mocha .test.fail {\n  color: #c00;\n}\n\n#mocha .test.fail pre {\n  color: black;\n}\n\n#mocha .test.fail::before {\n  content: '✖';\n  font-size: 12px;\n  display: block;\n  float: left;\n  margin-right: 5px;\n  color: #c00;\n}\n\n#mocha .test pre.error {\n  color: #c00;\n  max-height: 300px;\n  overflow: auto;\n}\n\n#mocha .test .html-error {\n  overflow: auto;\n  color: black;\n  line-height: 1.5;\n  display: block;\n  float: left;\n  clear: left;\n  font: 12px/1.5 monaco, monospace;\n  margin: 5px;\n  padding: 15px;\n  border: 1px solid #eee;\n  max-width: 85%; /*(1)*/\n  max-width: -webkit-calc(100% - 42px);\n  max-width: -moz-calc(100% - 42px);\n  max-width: calc(100% - 42px); /*(2)*/\n  max-height: 300px;\n  word-wrap: break-word;\n  border-bottom-color: #ddd;\n  -webkit-box-shadow: 0 1px 3px #eee;\n  -moz-box-shadow: 0 1px 3px #eee;\n  box-shadow: 0 1px 3px #eee;\n  -webkit-border-radius: 3px;\n  -moz-border-radius: 3px;\n  border-radius: 3px;\n}\n\n#mocha .test .html-error pre.error {\n  border: none;\n  -webkit-border-radius: 0;\n  -moz-border-radius: 0;\n  border-radius: 0;\n  -webkit-box-shadow: 0;\n  -moz-box-shadow: 0;\n  box-shadow: 0;\n  padding: 0;\n  margin: 0;\n  margin-top: 18px;\n  max-height: none;\n}\n\n/**\n * (1): approximate for browsers not supporting calc\n * (2): 42 = 2*15 + 2*10 + 2*1 (padding + margin + border)\n *      ^^ seriously\n */\n#mocha .test pre {\n  display: block;\n  float: left;\n  clear: left;\n  font: 12px/1.5 monaco, monospace;\n  margin: 5px;\n  padding: 15px;\n  border: 1px solid #eee;\n  max-width: 85%; /*(1)*/\n  max-width: -webkit-calc(100% - 42px);\n  max-width: -moz-calc(100% - 42px);\n  max-width: calc(100% - 42px); /*(2)*/\n  word-wrap: break-word;\n  border-bottom-color: #ddd;\n  -webkit-box-shadow: 0 1px 3px #eee;\n  -moz-box-shadow: 0 1px 3px #eee;\n  box-shadow: 0 1px 3px #eee;\n  -webkit-border-radius: 3px;\n  -moz-border-radius: 3px;\n  border-radius: 3px;\n}\n\n#mocha .test h2 {\n  position: relative;\n}\n\n#mocha .test a.replay {\n  position: absolute;\n  top: 3px;\n  right: 0;\n  text-decoration: none;\n  vertical-align: middle;\n  display: block;\n  width: 15px;\n  height: 15px;\n  line-height: 15px;\n  text-align: center;\n  background: #eee;\n  font-size: 15px;\n  -webkit-border-radius: 15px;\n  -moz-border-radius: 15px;\n  border-radius: 15px;\n  -webkit-transition:opacity 200ms;\n  -moz-transition:opacity 200ms;\n  -o-transition:opacity 200ms;\n  transition: opacity 200ms;\n  opacity: 0.3;\n  color: #888;\n}\n\n#mocha .test:hover a.replay {\n  opacity: 1;\n}\n\n#mocha-report.pass .test.fail {\n  display: none;\n}\n\n#mocha-report.fail .test.pass {\n  display: none;\n}\n\n#mocha-report.pending .test.pass,\n#mocha-report.pending .test.fail {\n  display: none;\n}\n#mocha-report.pending .test.pass.pending {\n  display: block;\n}\n\n#mocha-error {\n  color: #c00;\n  font-size: 1.5em;\n  font-weight: 100;\n  letter-spacing: 1px;\n}\n\n#mocha-stats {\n  position: fixed;\n  top: 15px;\n  right: 10px;\n  font-size: 12px;\n  margin: 0;\n  color: #888;\n  z-index: 1;\n}\n\n#mocha-stats .progress {\n  float: right;\n  padding-top: 0;\n\n  /**\n   * Set safe initial values, so mochas .progress does not inherit these\n   * properties from Bootstrap .progress (which causes .progress height to\n   * equal line height set in Bootstrap).\n   */\n  height: auto;\n  -webkit-box-shadow: none;\n  -moz-box-shadow: none;\n  box-shadow: none;\n  background-color: initial;\n}\n\n#mocha-stats em {\n  color: black;\n}\n\n#mocha-stats a {\n  text-decoration: none;\n  color: inherit;\n}\n\n#mocha-stats a:hover {\n  border-bottom: 1px solid #eee;\n}\n\n#mocha-stats li {\n  display: inline-block;\n  margin: 0 5px;\n  list-style: none;\n  padding-top: 11px;\n}\n\n#mocha-stats canvas {\n  width: 40px;\n  height: 40px;\n}\n\n#mocha code .comment { color: #ddd; }\n#mocha code .init { color: #2f6fad; }\n#mocha code .string { color: #5890ad; }\n#mocha code .keyword { color: #8a6343; }\n#mocha code .number { color: #2f6fad; }\n\n@media screen and (max-device-width: 480px) {\n  #mocha {\n    margin: 60px 0px;\n  }\n\n  #mocha #stats {\n    position: absolute;\n  }\n}\n"
  },
  {
    "path": "app_backend/static/plugin/JavaScript-Load-Image-2.12.2/test/vendor/mocha.js",
    "content": "(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require==\"function\"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error(\"Cannot find module '\"+o+\"'\");throw f.code=\"MODULE_NOT_FOUND\",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require==\"function\"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){\n(function (process,global){\n/* eslint no-unused-vars: off */\n\n/**\n * Shim process.stdout.\n */\n\nprocess.stdout = require('browser-stdout')();\n\nvar Mocha = require('./lib/mocha');\n\n/**\n * Create a Mocha instance.\n *\n * @return {undefined}\n */\n\nvar mocha = new Mocha({ reporter: 'html' });\n\n/**\n * Save timer references to avoid Sinon interfering (see GH-237).\n */\n\nvar Date = global.Date;\nvar setTimeout = global.setTimeout;\nvar setInterval = global.setInterval;\nvar clearTimeout = global.clearTimeout;\nvar clearInterval = global.clearInterval;\n\nvar uncaughtExceptionHandlers = [];\n\nvar originalOnerrorHandler = global.onerror;\n\n/**\n * Remove uncaughtException listener.\n * Revert to original onerror handler if previously defined.\n */\n\nprocess.removeListener = function(e, fn) {\n  if (e === 'uncaughtException') {\n    if (originalOnerrorHandler) {\n      global.onerror = originalOnerrorHandler;\n    } else {\n      global.onerror = function() {};\n    }\n    var i = Mocha.utils.indexOf(uncaughtExceptionHandlers, fn);\n    if (i !== -1) {\n      uncaughtExceptionHandlers.splice(i, 1);\n    }\n  }\n};\n\n/**\n * Implements uncaughtException listener.\n */\n\nprocess.on = function(e, fn) {\n  if (e === 'uncaughtException') {\n    global.onerror = function(err, url, line) {\n      fn(new Error(err + ' (' + url + ':' + line + ')'));\n      return !mocha.allowUncaught;\n    };\n    uncaughtExceptionHandlers.push(fn);\n  }\n};\n\n// The BDD UI is registered by default, but no UI will be functional in the\n// browser without an explicit call to the overridden `mocha.ui` (see below).\n// Ensure that this default UI does not expose its methods to the global scope.\nmocha.suite.removeAllListeners('pre-require');\n\nvar immediateQueue = [];\nvar immediateTimeout;\n\nfunction timeslice() {\n  var immediateStart = new Date().getTime();\n  while (immediateQueue.length && (new Date().getTime() - immediateStart) < 100) {\n    immediateQueue.shift()();\n  }\n  if (immediateQueue.length) {\n    immediateTimeout = setTimeout(timeslice, 0);\n  } else {\n    immediateTimeout = null;\n  }\n}\n\n/**\n * High-performance override of Runner.immediately.\n */\n\nMocha.Runner.immediately = function(callback) {\n  immediateQueue.push(callback);\n  if (!immediateTimeout) {\n    immediateTimeout = setTimeout(timeslice, 0);\n  }\n};\n\n/**\n * Function to allow assertion libraries to throw errors directly into mocha.\n * This is useful when running tests in a browser because window.onerror will\n * only receive the 'message' attribute of the Error.\n */\nmocha.throwError = function(err) {\n  Mocha.utils.forEach(uncaughtExceptionHandlers, function(fn) {\n    fn(err);\n  });\n  throw err;\n};\n\n/**\n * Override ui to ensure that the ui functions are initialized.\n * Normally this would happen in Mocha.prototype.loadFiles.\n */\n\nmocha.ui = function(ui) {\n  Mocha.prototype.ui.call(this, ui);\n  this.suite.emit('pre-require', global, null, this);\n  return this;\n};\n\n/**\n * Setup mocha with the given setting options.\n */\n\nmocha.setup = function(opts) {\n  if (typeof opts === 'string') {\n    opts = { ui: opts };\n  }\n  for (var opt in opts) {\n    if (opts.hasOwnProperty(opt)) {\n      this[opt](opts[opt]);\n    }\n  }\n  return this;\n};\n\n/**\n * Run mocha, returning the Runner.\n */\n\nmocha.run = function(fn) {\n  var options = mocha.options;\n  mocha.globals('location');\n\n  var query = Mocha.utils.parseQuery(global.location.search || '');\n  if (query.grep) {\n    mocha.grep(query.grep);\n  }\n  if (query.fgrep) {\n    mocha.fgrep(query.fgrep);\n  }\n  if (query.invert) {\n    mocha.invert();\n  }\n\n  return Mocha.prototype.run.call(mocha, function(err) {\n    // The DOM Document is not available in Web Workers.\n    var document = global.document;\n    if (document && document.getElementById('mocha') && options.noHighlighting !== true) {\n      Mocha.utils.highlightTags('code');\n    }\n    if (fn) {\n      fn(err);\n    }\n  });\n};\n\n/**\n * Expose the process shim.\n * https://github.com/mochajs/mocha/pull/916\n */\n\nMocha.process = process;\n\n/**\n * Expose mocha.\n */\n\nglobal.Mocha = Mocha;\nglobal.mocha = mocha;\n\n// this allows test/acceptance/required-tokens.js to pass; thus,\n// you can now do `const describe = require('mocha').describe` in a\n// browser context (assuming browserification).  should fix #880\nmodule.exports = global;\n\n}).call(this,require('_process'),typeof global !== \"undefined\" ? global : typeof self !== \"undefined\" ? self : typeof window !== \"undefined\" ? window : {})\n},{\"./lib/mocha\":14,\"_process\":67,\"browser-stdout\":41}],2:[function(require,module,exports){\n/* eslint-disable no-unused-vars */\nmodule.exports = function(type) {\n  return function() {};\n};\n\n},{}],3:[function(require,module,exports){\n/**\n * Module exports.\n */\n\nexports.EventEmitter = EventEmitter;\n\n/**\n * Object#toString reference.\n */\nvar objToString = Object.prototype.toString;\n\n/**\n * Check if a value is an array.\n *\n * @api private\n * @param {*} val The value to test.\n * @return {boolean} true if the value is an array, otherwise false.\n */\nfunction isArray(val) {\n  return objToString.call(val) === '[object Array]';\n}\n\n/**\n * Event emitter constructor.\n *\n * @api public\n */\nfunction EventEmitter() {}\n\n/**\n * Add a listener.\n *\n * @api public\n * @param {string} name Event name.\n * @param {Function} fn Event handler.\n * @return {EventEmitter} Emitter instance.\n */\nEventEmitter.prototype.on = function(name, fn) {\n  if (!this.$events) {\n    this.$events = {};\n  }\n\n  if (!this.$events[name]) {\n    this.$events[name] = fn;\n  } else if (isArray(this.$events[name])) {\n    this.$events[name].push(fn);\n  } else {\n    this.$events[name] = [this.$events[name], fn];\n  }\n\n  return this;\n};\n\nEventEmitter.prototype.addListener = EventEmitter.prototype.on;\n\n/**\n * Adds a volatile listener.\n *\n * @api public\n * @param {string} name Event name.\n * @param {Function} fn Event handler.\n * @return {EventEmitter} Emitter instance.\n */\nEventEmitter.prototype.once = function(name, fn) {\n  var self = this;\n\n  function on() {\n    self.removeListener(name, on);\n    fn.apply(this, arguments);\n  }\n\n  on.listener = fn;\n  this.on(name, on);\n\n  return this;\n};\n\n/**\n * Remove a listener.\n *\n * @api public\n * @param {string} name Event name.\n * @param {Function} fn Event handler.\n * @return {EventEmitter} Emitter instance.\n */\nEventEmitter.prototype.removeListener = function(name, fn) {\n  if (this.$events && this.$events[name]) {\n    var list = this.$events[name];\n\n    if (isArray(list)) {\n      var pos = -1;\n\n      for (var i = 0, l = list.length; i < l; i++) {\n        if (list[i] === fn || (list[i].listener && list[i].listener === fn)) {\n          pos = i;\n          break;\n        }\n      }\n\n      if (pos < 0) {\n        return this;\n      }\n\n      list.splice(pos, 1);\n\n      if (!list.length) {\n        delete this.$events[name];\n      }\n    } else if (list === fn || (list.listener && list.listener === fn)) {\n      delete this.$events[name];\n    }\n  }\n\n  return this;\n};\n\n/**\n * Remove all listeners for an event.\n *\n * @api public\n * @param {string} name Event name.\n * @return {EventEmitter} Emitter instance.\n */\nEventEmitter.prototype.removeAllListeners = function(name) {\n  if (name === undefined) {\n    this.$events = {};\n    return this;\n  }\n\n  if (this.$events && this.$events[name]) {\n    this.$events[name] = null;\n  }\n\n  return this;\n};\n\n/**\n * Get all listeners for a given event.\n *\n * @api public\n * @param {string} name Event name.\n * @return {EventEmitter} Emitter instance.\n */\nEventEmitter.prototype.listeners = function(name) {\n  if (!this.$events) {\n    this.$events = {};\n  }\n\n  if (!this.$events[name]) {\n    this.$events[name] = [];\n  }\n\n  if (!isArray(this.$events[name])) {\n    this.$events[name] = [this.$events[name]];\n  }\n\n  return this.$events[name];\n};\n\n/**\n * Emit an event.\n *\n * @api public\n * @param {string} name Event name.\n * @return {boolean} true if at least one handler was invoked, else false.\n */\nEventEmitter.prototype.emit = function(name) {\n  if (!this.$events) {\n    return false;\n  }\n\n  var handler = this.$events[name];\n\n  if (!handler) {\n    return false;\n  }\n\n  var args = Array.prototype.slice.call(arguments, 1);\n\n  if (typeof handler === 'function') {\n    handler.apply(this, args);\n  } else if (isArray(handler)) {\n    var listeners = handler.slice();\n\n    for (var i = 0, l = listeners.length; i < l; i++) {\n      listeners[i].apply(this, args);\n    }\n  } else {\n    return false;\n  }\n\n  return true;\n};\n\n},{}],4:[function(require,module,exports){\n/**\n * Expose `Progress`.\n */\n\nmodule.exports = Progress;\n\n/**\n * Initialize a new `Progress` indicator.\n */\nfunction Progress() {\n  this.percent = 0;\n  this.size(0);\n  this.fontSize(11);\n  this.font('helvetica, arial, sans-serif');\n}\n\n/**\n * Set progress size to `size`.\n *\n * @api public\n * @param {number} size\n * @return {Progress} Progress instance.\n */\nProgress.prototype.size = function(size) {\n  this._size = size;\n  return this;\n};\n\n/**\n * Set text to `text`.\n *\n * @api public\n * @param {string} text\n * @return {Progress} Progress instance.\n */\nProgress.prototype.text = function(text) {\n  this._text = text;\n  return this;\n};\n\n/**\n * Set font size to `size`.\n *\n * @api public\n * @param {number} size\n * @return {Progress} Progress instance.\n */\nProgress.prototype.fontSize = function(size) {\n  this._fontSize = size;\n  return this;\n};\n\n/**\n * Set font to `family`.\n *\n * @param {string} family\n * @return {Progress} Progress instance.\n */\nProgress.prototype.font = function(family) {\n  this._font = family;\n  return this;\n};\n\n/**\n * Update percentage to `n`.\n *\n * @param {number} n\n * @return {Progress} Progress instance.\n */\nProgress.prototype.update = function(n) {\n  this.percent = n;\n  return this;\n};\n\n/**\n * Draw on `ctx`.\n *\n * @param {CanvasRenderingContext2d} ctx\n * @return {Progress} Progress instance.\n */\nProgress.prototype.draw = function(ctx) {\n  try {\n    var percent = Math.min(this.percent, 100);\n    var size = this._size;\n    var half = size / 2;\n    var x = half;\n    var y = half;\n    var rad = half - 1;\n    var fontSize = this._fontSize;\n\n    ctx.font = fontSize + 'px ' + this._font;\n\n    var angle = Math.PI * 2 * (percent / 100);\n    ctx.clearRect(0, 0, size, size);\n\n    // outer circle\n    ctx.strokeStyle = '#9f9f9f';\n    ctx.beginPath();\n    ctx.arc(x, y, rad, 0, angle, false);\n    ctx.stroke();\n\n    // inner circle\n    ctx.strokeStyle = '#eee';\n    ctx.beginPath();\n    ctx.arc(x, y, rad - 1, 0, angle, true);\n    ctx.stroke();\n\n    // text\n    var text = this._text || (percent | 0) + '%';\n    var w = ctx.measureText(text).width;\n\n    ctx.fillText(text, x - w / 2 + 1, y + fontSize / 2 - 1);\n  } catch (err) {\n    // don't fail if we can't render progress\n  }\n  return this;\n};\n\n},{}],5:[function(require,module,exports){\n(function (global){\nexports.isatty = function isatty() {\n  return true;\n};\n\nexports.getWindowSize = function getWindowSize() {\n  if ('innerHeight' in global) {\n    return [global.innerHeight, global.innerWidth];\n  }\n  // In a Web Worker, the DOM Window is not available.\n  return [640, 480];\n};\n\n}).call(this,typeof global !== \"undefined\" ? global : typeof self !== \"undefined\" ? self : typeof window !== \"undefined\" ? window : {})\n},{}],6:[function(require,module,exports){\n/**\n * Module dependencies.\n */\n\nvar JSON = require('json3');\n\n/**\n * Expose `Context`.\n */\n\nmodule.exports = Context;\n\n/**\n * Initialize a new `Context`.\n *\n * @api private\n */\nfunction Context() {}\n\n/**\n * Set or get the context `Runnable` to `runnable`.\n *\n * @api private\n * @param {Runnable} runnable\n * @return {Context}\n */\nContext.prototype.runnable = function(runnable) {\n  if (!arguments.length) {\n    return this._runnable;\n  }\n  this.test = this._runnable = runnable;\n  return this;\n};\n\n/**\n * Set test timeout `ms`.\n *\n * @api private\n * @param {number} ms\n * @return {Context} self\n */\nContext.prototype.timeout = function(ms) {\n  if (!arguments.length) {\n    return this.runnable().timeout();\n  }\n  this.runnable().timeout(ms);\n  return this;\n};\n\n/**\n * Set test timeout `enabled`.\n *\n * @api private\n * @param {boolean} enabled\n * @return {Context} self\n */\nContext.prototype.enableTimeouts = function(enabled) {\n  this.runnable().enableTimeouts(enabled);\n  return this;\n};\n\n/**\n * Set test slowness threshold `ms`.\n *\n * @api private\n * @param {number} ms\n * @return {Context} self\n */\nContext.prototype.slow = function(ms) {\n  this.runnable().slow(ms);\n  return this;\n};\n\n/**\n * Mark a test as skipped.\n *\n * @api private\n * @return {Context} self\n */\nContext.prototype.skip = function() {\n  this.runnable().skip();\n  return this;\n};\n\n/**\n * Allow a number of retries on failed tests\n *\n * @api private\n * @param {number} n\n * @return {Context} self\n */\nContext.prototype.retries = function(n) {\n  if (!arguments.length) {\n    return this.runnable().retries();\n  }\n  this.runnable().retries(n);\n  return this;\n};\n\n/**\n * Inspect the context void of `._runnable`.\n *\n * @api private\n * @return {string}\n */\nContext.prototype.inspect = function() {\n  return JSON.stringify(this, function(key, val) {\n    return key === 'runnable' || key === 'test' ? undefined : val;\n  }, 2);\n};\n\n},{\"json3\":54}],7:[function(require,module,exports){\n/**\n * Module dependencies.\n */\n\nvar Runnable = require('./runnable');\nvar inherits = require('./utils').inherits;\n\n/**\n * Expose `Hook`.\n */\n\nmodule.exports = Hook;\n\n/**\n * Initialize a new `Hook` with the given `title` and callback `fn`.\n *\n * @param {String} title\n * @param {Function} fn\n * @api private\n */\nfunction Hook(title, fn) {\n  Runnable.call(this, title, fn);\n  this.type = 'hook';\n}\n\n/**\n * Inherit from `Runnable.prototype`.\n */\ninherits(Hook, Runnable);\n\n/**\n * Get or set the test `err`.\n *\n * @param {Error} err\n * @return {Error}\n * @api public\n */\nHook.prototype.error = function(err) {\n  if (!arguments.length) {\n    err = this._error;\n    this._error = null;\n    return err;\n  }\n\n  this._error = err;\n};\n\n},{\"./runnable\":33,\"./utils\":38}],8:[function(require,module,exports){\n/**\n * Module dependencies.\n */\n\nvar Test = require('../test');\n\n/**\n * BDD-style interface:\n *\n *      describe('Array', function() {\n *        describe('#indexOf()', function() {\n *          it('should return -1 when not present', function() {\n *            // ...\n *          });\n *\n *          it('should return the index when present', function() {\n *            // ...\n *          });\n *        });\n *      });\n *\n * @param {Suite} suite Root suite.\n */\nmodule.exports = function(suite) {\n  var suites = [suite];\n\n  suite.on('pre-require', function(context, file, mocha) {\n    var common = require('./common')(suites, context, mocha);\n\n    context.before = common.before;\n    context.after = common.after;\n    context.beforeEach = common.beforeEach;\n    context.afterEach = common.afterEach;\n    context.run = mocha.options.delay && common.runWithSuite(suite);\n    /**\n     * Describe a \"suite\" with the given `title`\n     * and callback `fn` containing nested suites\n     * and/or tests.\n     */\n\n    context.describe = context.context = function(title, fn) {\n      return common.suite.create({\n        title: title,\n        file: file,\n        fn: fn\n      });\n    };\n\n    /**\n     * Pending describe.\n     */\n\n    context.xdescribe = context.xcontext = context.describe.skip = function(title, fn) {\n      return common.suite.skip({\n        title: title,\n        file: file,\n        fn: fn\n      });\n    };\n\n    /**\n     * Exclusive suite.\n     */\n\n    context.describe.only = function(title, fn) {\n      return common.suite.only({\n        title: title,\n        file: file,\n        fn: fn\n      });\n    };\n\n    /**\n     * Describe a specification or test-case\n     * with the given `title` and callback `fn`\n     * acting as a thunk.\n     */\n\n    context.it = context.specify = function(title, fn) {\n      var suite = suites[0];\n      if (suite.isPending()) {\n        fn = null;\n      }\n      var test = new Test(title, fn);\n      test.file = file;\n      suite.addTest(test);\n      return test;\n    };\n\n    /**\n     * Exclusive test-case.\n     */\n\n    context.it.only = function(title, fn) {\n      return common.test.only(mocha, context.it(title, fn));\n    };\n\n    /**\n     * Pending test case.\n     */\n\n    context.xit = context.xspecify = context.it.skip = function(title) {\n      context.it(title);\n    };\n\n    /**\n     * Number of attempts to retry.\n     */\n    context.it.retries = function(n) {\n      context.retries(n);\n    };\n  });\n};\n\n},{\"../test\":36,\"./common\":9}],9:[function(require,module,exports){\n'use strict';\n\nvar Suite = require('../suite');\n\n/**\n * Functions common to more than one interface.\n *\n * @param {Suite[]} suites\n * @param {Context} context\n * @param {Mocha} mocha\n * @return {Object} An object containing common functions.\n */\nmodule.exports = function(suites, context, mocha) {\n  return {\n    /**\n     * This is only present if flag --delay is passed into Mocha. It triggers\n     * root suite execution.\n     *\n     * @param {Suite} suite The root wuite.\n     * @return {Function} A function which runs the root suite\n     */\n    runWithSuite: function runWithSuite(suite) {\n      return function run() {\n        suite.run();\n      };\n    },\n\n    /**\n     * Execute before running tests.\n     *\n     * @param {string} name\n     * @param {Function} fn\n     */\n    before: function(name, fn) {\n      suites[0].beforeAll(name, fn);\n    },\n\n    /**\n     * Execute after running tests.\n     *\n     * @param {string} name\n     * @param {Function} fn\n     */\n    after: function(name, fn) {\n      suites[0].afterAll(name, fn);\n    },\n\n    /**\n     * Execute before each test case.\n     *\n     * @param {string} name\n     * @param {Function} fn\n     */\n    beforeEach: function(name, fn) {\n      suites[0].beforeEach(name, fn);\n    },\n\n    /**\n     * Execute after each test case.\n     *\n     * @param {string} name\n     * @param {Function} fn\n     */\n    afterEach: function(name, fn) {\n      suites[0].afterEach(name, fn);\n    },\n\n    suite: {\n      /**\n       * Create an exclusive Suite; convenience function\n       * See docstring for create() below.\n       *\n       * @param {Object} opts\n       * @returns {Suite}\n       */\n      only: function only(opts) {\n        mocha.options.hasOnly = true;\n        opts.isOnly = true;\n        return this.create(opts);\n      },\n\n      /**\n       * Create a Suite, but skip it; convenience function\n       * See docstring for create() below.\n       *\n       * @param {Object} opts\n       * @returns {Suite}\n       */\n      skip: function skip(opts) {\n        opts.pending = true;\n        return this.create(opts);\n      },\n\n      /**\n       * Creates a suite.\n       * @param {Object} opts Options\n       * @param {string} opts.title Title of Suite\n       * @param {Function} [opts.fn] Suite Function (not always applicable)\n       * @param {boolean} [opts.pending] Is Suite pending?\n       * @param {string} [opts.file] Filepath where this Suite resides\n       * @param {boolean} [opts.isOnly] Is Suite exclusive?\n       * @returns {Suite}\n       */\n      create: function create(opts) {\n        var suite = Suite.create(suites[0], opts.title);\n        suite.pending = Boolean(opts.pending);\n        suite.file = opts.file;\n        suites.unshift(suite);\n        if (opts.isOnly) {\n          suite.parent._onlySuites = suite.parent._onlySuites.concat(suite);\n          mocha.options.hasOnly = true;\n        }\n        if (typeof opts.fn === 'function') {\n          opts.fn.call(suite);\n          suites.shift();\n        } else if (typeof opts.fn === 'undefined' && !suite.pending) {\n          throw new Error('Suite \"' + suite.fullTitle() + '\" was defined but no callback was supplied. Supply a callback or explicitly skip the suite.');\n        }\n\n        return suite;\n      }\n    },\n\n    test: {\n\n      /**\n       * Exclusive test-case.\n       *\n       * @param {Object} mocha\n       * @param {Function} test\n       * @returns {*}\n       */\n      only: function(mocha, test) {\n        test.parent._onlyTests = test.parent._onlyTests.concat(test);\n        mocha.options.hasOnly = true;\n        return test;\n      },\n\n      /**\n       * Pending test case.\n       *\n       * @param {string} title\n       */\n      skip: function(title) {\n        context.test(title);\n      },\n\n      /**\n       * Number of retry attempts\n       *\n       * @param {number} n\n       */\n      retries: function(n) {\n        context.retries(n);\n      }\n    }\n  };\n};\n\n},{\"../suite\":35}],10:[function(require,module,exports){\n/**\n * Module dependencies.\n */\n\nvar Suite = require('../suite');\nvar Test = require('../test');\n\n/**\n * Exports-style (as Node.js module) interface:\n *\n *     exports.Array = {\n *       '#indexOf()': {\n *         'should return -1 when the value is not present': function() {\n *\n *         },\n *\n *         'should return the correct index when the value is present': function() {\n *\n *         }\n *       }\n *     };\n *\n * @param {Suite} suite Root suite.\n */\nmodule.exports = function(suite) {\n  var suites = [suite];\n\n  suite.on('require', visit);\n\n  function visit(obj, file) {\n    var suite;\n    for (var key in obj) {\n      if (typeof obj[key] === 'function') {\n        var fn = obj[key];\n        switch (key) {\n          case 'before':\n            suites[0].beforeAll(fn);\n            break;\n          case 'after':\n            suites[0].afterAll(fn);\n            break;\n          case 'beforeEach':\n            suites[0].beforeEach(fn);\n            break;\n          case 'afterEach':\n            suites[0].afterEach(fn);\n            break;\n          default:\n            var test = new Test(key, fn);\n            test.file = file;\n            suites[0].addTest(test);\n        }\n      } else {\n        suite = Suite.create(suites[0], key);\n        suites.unshift(suite);\n        visit(obj[key], file);\n        suites.shift();\n      }\n    }\n  }\n};\n\n},{\"../suite\":35,\"../test\":36}],11:[function(require,module,exports){\nexports.bdd = require('./bdd');\nexports.tdd = require('./tdd');\nexports.qunit = require('./qunit');\nexports.exports = require('./exports');\n\n},{\"./bdd\":8,\"./exports\":10,\"./qunit\":12,\"./tdd\":13}],12:[function(require,module,exports){\n/**\n * Module dependencies.\n */\n\nvar Test = require('../test');\n\n/**\n * QUnit-style interface:\n *\n *     suite('Array');\n *\n *     test('#length', function() {\n *       var arr = [1,2,3];\n *       ok(arr.length == 3);\n *     });\n *\n *     test('#indexOf()', function() {\n *       var arr = [1,2,3];\n *       ok(arr.indexOf(1) == 0);\n *       ok(arr.indexOf(2) == 1);\n *       ok(arr.indexOf(3) == 2);\n *     });\n *\n *     suite('String');\n *\n *     test('#length', function() {\n *       ok('foo'.length == 3);\n *     });\n *\n * @param {Suite} suite Root suite.\n */\nmodule.exports = function(suite) {\n  var suites = [suite];\n\n  suite.on('pre-require', function(context, file, mocha) {\n    var common = require('./common')(suites, context, mocha);\n\n    context.before = common.before;\n    context.after = common.after;\n    context.beforeEach = common.beforeEach;\n    context.afterEach = common.afterEach;\n    context.run = mocha.options.delay && common.runWithSuite(suite);\n    /**\n     * Describe a \"suite\" with the given `title`.\n     */\n\n    context.suite = function(title) {\n      if (suites.length > 1) {\n        suites.shift();\n      }\n      return common.suite.create({\n        title: title,\n        file: file,\n        fn: false\n      });\n    };\n\n    /**\n     * Exclusive Suite.\n     */\n\n    context.suite.only = function(title) {\n      if (suites.length > 1) {\n        suites.shift();\n      }\n      return common.suite.only({\n        title: title,\n        file: file,\n        fn: false\n      });\n    };\n\n    /**\n     * Describe a specification or test-case\n     * with the given `title` and callback `fn`\n     * acting as a thunk.\n     */\n\n    context.test = function(title, fn) {\n      var test = new Test(title, fn);\n      test.file = file;\n      suites[0].addTest(test);\n      return test;\n    };\n\n    /**\n     * Exclusive test-case.\n     */\n\n    context.test.only = function(title, fn) {\n      return common.test.only(mocha, context.test(title, fn));\n    };\n\n    context.test.skip = common.test.skip;\n    context.test.retries = common.test.retries;\n  });\n};\n\n},{\"../test\":36,\"./common\":9}],13:[function(require,module,exports){\n/**\n * Module dependencies.\n */\n\nvar Test = require('../test');\n\n/**\n * TDD-style interface:\n *\n *      suite('Array', function() {\n *        suite('#indexOf()', function() {\n *          suiteSetup(function() {\n *\n *          });\n *\n *          test('should return -1 when not present', function() {\n *\n *          });\n *\n *          test('should return the index when present', function() {\n *\n *          });\n *\n *          suiteTeardown(function() {\n *\n *          });\n *        });\n *      });\n *\n * @param {Suite} suite Root suite.\n */\nmodule.exports = function(suite) {\n  var suites = [suite];\n\n  suite.on('pre-require', function(context, file, mocha) {\n    var common = require('./common')(suites, context, mocha);\n\n    context.setup = common.beforeEach;\n    context.teardown = common.afterEach;\n    context.suiteSetup = common.before;\n    context.suiteTeardown = common.after;\n    context.run = mocha.options.delay && common.runWithSuite(suite);\n\n    /**\n     * Describe a \"suite\" with the given `title` and callback `fn` containing\n     * nested suites and/or tests.\n     */\n    context.suite = function(title, fn) {\n      return common.suite.create({\n        title: title,\n        file: file,\n        fn: fn\n      });\n    };\n\n    /**\n     * Pending suite.\n     */\n    context.suite.skip = function(title, fn) {\n      return common.suite.skip({\n        title: title,\n        file: file,\n        fn: fn\n      });\n    };\n\n    /**\n     * Exclusive test-case.\n     */\n    context.suite.only = function(title, fn) {\n      return common.suite.only({\n        title: title,\n        file: file,\n        fn: fn\n      });\n    };\n\n    /**\n     * Describe a specification or test-case with the given `title` and\n     * callback `fn` acting as a thunk.\n     */\n    context.test = function(title, fn) {\n      var suite = suites[0];\n      if (suite.isPending()) {\n        fn = null;\n      }\n      var test = new Test(title, fn);\n      test.file = file;\n      suite.addTest(test);\n      return test;\n    };\n\n    /**\n     * Exclusive test-case.\n     */\n\n    context.test.only = function(title, fn) {\n      return common.test.only(mocha, context.test(title, fn));\n    };\n\n    context.test.skip = common.test.skip;\n    context.test.retries = common.test.retries;\n  });\n};\n\n},{\"../test\":36,\"./common\":9}],14:[function(require,module,exports){\n(function (process,global,__dirname){\n/*!\n * mocha\n * Copyright(c) 2011 TJ Holowaychuk <tj@vision-media.ca>\n * MIT Licensed\n */\n\n/**\n * Module dependencies.\n */\n\nvar escapeRe = require('escape-string-regexp');\nvar path = require('path');\nvar reporters = require('./reporters');\nvar utils = require('./utils');\n\n/**\n * Expose `Mocha`.\n */\n\nexports = module.exports = Mocha;\n\n/**\n * To require local UIs and reporters when running in node.\n */\n\nif (!process.browser) {\n  var cwd = process.cwd();\n  module.paths.push(cwd, path.join(cwd, 'node_modules'));\n}\n\n/**\n * Expose internals.\n */\n\nexports.utils = utils;\nexports.interfaces = require('./interfaces');\nexports.reporters = reporters;\nexports.Runnable = require('./runnable');\nexports.Context = require('./context');\nexports.Runner = require('./runner');\nexports.Suite = require('./suite');\nexports.Hook = require('./hook');\nexports.Test = require('./test');\n\n/**\n * Return image `name` path.\n *\n * @api private\n * @param {string} name\n * @return {string}\n */\nfunction image(name) {\n  return path.join(__dirname, '../images', name + '.png');\n}\n\n/**\n * Set up mocha with `options`.\n *\n * Options:\n *\n *   - `ui` name \"bdd\", \"tdd\", \"exports\" etc\n *   - `reporter` reporter instance, defaults to `mocha.reporters.spec`\n *   - `globals` array of accepted globals\n *   - `timeout` timeout in milliseconds\n *   - `retries` number of times to retry failed tests\n *   - `bail` bail on the first test failure\n *   - `slow` milliseconds to wait before considering a test slow\n *   - `ignoreLeaks` ignore global leaks\n *   - `fullTrace` display the full stack-trace on failing\n *   - `grep` string or regexp to filter tests with\n *\n * @param {Object} options\n * @api public\n */\nfunction Mocha(options) {\n  options = options || {};\n  this.files = [];\n  this.options = options;\n  if (options.grep) {\n    this.grep(new RegExp(options.grep));\n  }\n  if (options.fgrep) {\n    this.fgrep(options.fgrep);\n  }\n  this.suite = new exports.Suite('', new exports.Context());\n  this.ui(options.ui);\n  this.bail(options.bail);\n  this.reporter(options.reporter, options.reporterOptions);\n  if (typeof options.timeout !== 'undefined' && options.timeout !== null) {\n    this.timeout(options.timeout);\n  }\n  if (typeof options.retries !== 'undefined' && options.retries !== null) {\n    this.retries(options.retries);\n  }\n  this.useColors(options.useColors);\n  if (options.enableTimeouts !== null) {\n    this.enableTimeouts(options.enableTimeouts);\n  }\n  if (options.slow) {\n    this.slow(options.slow);\n  }\n}\n\n/**\n * Enable or disable bailing on the first failure.\n *\n * @api public\n * @param {boolean} [bail]\n */\nMocha.prototype.bail = function(bail) {\n  if (!arguments.length) {\n    bail = true;\n  }\n  this.suite.bail(bail);\n  return this;\n};\n\n/**\n * Add test `file`.\n *\n * @api public\n * @param {string} file\n */\nMocha.prototype.addFile = function(file) {\n  this.files.push(file);\n  return this;\n};\n\n/**\n * Set reporter to `reporter`, defaults to \"spec\".\n *\n * @param {String|Function} reporter name or constructor\n * @param {Object} reporterOptions optional options\n * @api public\n * @param {string|Function} reporter name or constructor\n * @param {Object} reporterOptions optional options\n */\nMocha.prototype.reporter = function(reporter, reporterOptions) {\n  if (typeof reporter === 'function') {\n    this._reporter = reporter;\n  } else {\n    reporter = reporter || 'spec';\n    var _reporter;\n    // Try to load a built-in reporter.\n    if (reporters[reporter]) {\n      _reporter = reporters[reporter];\n    }\n    // Try to load reporters from process.cwd() and node_modules\n    if (!_reporter) {\n      try {\n        _reporter = require(reporter);\n      } catch (err) {\n        err.message.indexOf('Cannot find module') !== -1\n          ? console.warn('\"' + reporter + '\" reporter not found')\n          : console.warn('\"' + reporter + '\" reporter blew up with error:\\n' + err.stack);\n      }\n    }\n    if (!_reporter && reporter === 'teamcity') {\n      console.warn('The Teamcity reporter was moved to a package named '\n        + 'mocha-teamcity-reporter '\n        + '(https://npmjs.org/package/mocha-teamcity-reporter).');\n    }\n    if (!_reporter) {\n      throw new Error('invalid reporter \"' + reporter + '\"');\n    }\n    this._reporter = _reporter;\n  }\n  this.options.reporterOptions = reporterOptions;\n  return this;\n};\n\n/**\n * Set test UI `name`, defaults to \"bdd\".\n *\n * @api public\n * @param {string} bdd\n */\nMocha.prototype.ui = function(name) {\n  name = name || 'bdd';\n  this._ui = exports.interfaces[name];\n  if (!this._ui) {\n    try {\n      this._ui = require(name);\n    } catch (err) {\n      throw new Error('invalid interface \"' + name + '\"');\n    }\n  }\n  this._ui = this._ui(this.suite);\n\n  this.suite.on('pre-require', function(context) {\n    exports.afterEach = context.afterEach || context.teardown;\n    exports.after = context.after || context.suiteTeardown;\n    exports.beforeEach = context.beforeEach || context.setup;\n    exports.before = context.before || context.suiteSetup;\n    exports.describe = context.describe || context.suite;\n    exports.it = context.it || context.test;\n    exports.setup = context.setup || context.beforeEach;\n    exports.suiteSetup = context.suiteSetup || context.before;\n    exports.suiteTeardown = context.suiteTeardown || context.after;\n    exports.suite = context.suite || context.describe;\n    exports.teardown = context.teardown || context.afterEach;\n    exports.test = context.test || context.it;\n    exports.run = context.run;\n  });\n\n  return this;\n};\n\n/**\n * Load registered files.\n *\n * @api private\n */\nMocha.prototype.loadFiles = function(fn) {\n  var self = this;\n  var suite = this.suite;\n  this.files.forEach(function(file) {\n    file = path.resolve(file);\n    suite.emit('pre-require', global, file, self);\n    suite.emit('require', require(file), file, self);\n    suite.emit('post-require', global, file, self);\n  });\n  fn && fn();\n};\n\n/**\n * Enable growl support.\n *\n * @api private\n */\nMocha.prototype._growl = function(runner, reporter) {\n  var notify = require('growl');\n\n  runner.on('end', function() {\n    var stats = reporter.stats;\n    if (stats.failures) {\n      var msg = stats.failures + ' of ' + runner.total + ' tests failed';\n      notify(msg, { name: 'mocha', title: 'Failed', image: image('error') });\n    } else {\n      notify(stats.passes + ' tests passed in ' + stats.duration + 'ms', {\n        name: 'mocha',\n        title: 'Passed',\n        image: image('ok')\n      });\n    }\n  });\n};\n\n/**\n * Escape string and add it to grep as a regexp.\n *\n * @api public\n * @param str\n * @returns {Mocha}\n */\nMocha.prototype.fgrep = function(str) {\n  return this.grep(new RegExp(escapeRe(str)));\n};\n\n/**\n * Add regexp to grep, if `re` is a string it is escaped.\n *\n * @param {RegExp|String} re\n * @return {Mocha}\n * @api public\n * @param {RegExp|string} re\n * @return {Mocha}\n */\nMocha.prototype.grep = function(re) {\n  if (utils.isString(re)) {\n    // extract args if it's regex-like, i.e: [string, pattern, flag]\n    var arg = re.match(/^\\/(.*)\\/(g|i|)$|.*/);\n    this.options.grep = new RegExp(arg[1] || arg[0], arg[2]);\n  } else {\n    this.options.grep = re;\n  }\n  return this;\n};\n/**\n * Invert `.grep()` matches.\n *\n * @return {Mocha}\n * @api public\n */\nMocha.prototype.invert = function() {\n  this.options.invert = true;\n  return this;\n};\n\n/**\n * Ignore global leaks.\n *\n * @param {Boolean} ignore\n * @return {Mocha}\n * @api public\n * @param {boolean} ignore\n * @return {Mocha}\n */\nMocha.prototype.ignoreLeaks = function(ignore) {\n  this.options.ignoreLeaks = Boolean(ignore);\n  return this;\n};\n\n/**\n * Enable global leak checking.\n *\n * @return {Mocha}\n * @api public\n */\nMocha.prototype.checkLeaks = function() {\n  this.options.ignoreLeaks = false;\n  return this;\n};\n\n/**\n * Display long stack-trace on failing\n *\n * @return {Mocha}\n * @api public\n */\nMocha.prototype.fullTrace = function() {\n  this.options.fullStackTrace = true;\n  return this;\n};\n\n/**\n * Enable growl support.\n *\n * @return {Mocha}\n * @api public\n */\nMocha.prototype.growl = function() {\n  this.options.growl = true;\n  return this;\n};\n\n/**\n * Ignore `globals` array or string.\n *\n * @param {Array|String} globals\n * @return {Mocha}\n * @api public\n * @param {Array|string} globals\n * @return {Mocha}\n */\nMocha.prototype.globals = function(globals) {\n  this.options.globals = (this.options.globals || []).concat(globals);\n  return this;\n};\n\n/**\n * Emit color output.\n *\n * @param {Boolean} colors\n * @return {Mocha}\n * @api public\n * @param {boolean} colors\n * @return {Mocha}\n */\nMocha.prototype.useColors = function(colors) {\n  if (colors !== undefined) {\n    this.options.useColors = colors;\n  }\n  return this;\n};\n\n/**\n * Use inline diffs rather than +/-.\n *\n * @param {Boolean} inlineDiffs\n * @return {Mocha}\n * @api public\n * @param {boolean} inlineDiffs\n * @return {Mocha}\n */\nMocha.prototype.useInlineDiffs = function(inlineDiffs) {\n  this.options.useInlineDiffs = inlineDiffs !== undefined && inlineDiffs;\n  return this;\n};\n\n/**\n * Set the timeout in milliseconds.\n *\n * @param {Number} timeout\n * @return {Mocha}\n * @api public\n * @param {number} timeout\n * @return {Mocha}\n */\nMocha.prototype.timeout = function(timeout) {\n  this.suite.timeout(timeout);\n  return this;\n};\n\n/**\n * Set the number of times to retry failed tests.\n *\n * @param {Number} retry times\n * @return {Mocha}\n * @api public\n */\nMocha.prototype.retries = function(n) {\n  this.suite.retries(n);\n  return this;\n};\n\n/**\n * Set slowness threshold in milliseconds.\n *\n * @param {Number} slow\n * @return {Mocha}\n * @api public\n * @param {number} slow\n * @return {Mocha}\n */\nMocha.prototype.slow = function(slow) {\n  this.suite.slow(slow);\n  return this;\n};\n\n/**\n * Enable timeouts.\n *\n * @param {Boolean} enabled\n * @return {Mocha}\n * @api public\n * @param {boolean} enabled\n * @return {Mocha}\n */\nMocha.prototype.enableTimeouts = function(enabled) {\n  this.suite.enableTimeouts(arguments.length && enabled !== undefined ? enabled : true);\n  return this;\n};\n\n/**\n * Makes all tests async (accepting a callback)\n *\n * @return {Mocha}\n * @api public\n */\nMocha.prototype.asyncOnly = function() {\n  this.options.asyncOnly = true;\n  return this;\n};\n\n/**\n * Disable syntax highlighting (in browser).\n *\n * @api public\n */\nMocha.prototype.noHighlighting = function() {\n  this.options.noHighlighting = true;\n  return this;\n};\n\n/**\n * Enable uncaught errors to propagate (in browser).\n *\n * @return {Mocha}\n * @api public\n */\nMocha.prototype.allowUncaught = function() {\n  this.options.allowUncaught = true;\n  return this;\n};\n\n/**\n * Delay root suite execution.\n * @returns {Mocha}\n */\nMocha.prototype.delay = function delay() {\n  this.options.delay = true;\n  return this;\n};\n\n/**\n * Run tests and invoke `fn()` when complete.\n *\n * @api public\n * @param {Function} fn\n * @return {Runner}\n */\nMocha.prototype.run = function(fn) {\n  if (this.files.length) {\n    this.loadFiles();\n  }\n  var suite = this.suite;\n  var options = this.options;\n  options.files = this.files;\n  var runner = new exports.Runner(suite, options.delay);\n  var reporter = new this._reporter(runner, options);\n  runner.ignoreLeaks = options.ignoreLeaks !== false;\n  runner.fullStackTrace = options.fullStackTrace;\n  runner.hasOnly = options.hasOnly;\n  runner.asyncOnly = options.asyncOnly;\n  runner.allowUncaught = options.allowUncaught;\n  if (options.grep) {\n    runner.grep(options.grep, options.invert);\n  }\n  if (options.globals) {\n    runner.globals(options.globals);\n  }\n  if (options.growl) {\n    this._growl(runner, reporter);\n  }\n  if (options.useColors !== undefined) {\n    exports.reporters.Base.useColors = options.useColors;\n  }\n  exports.reporters.Base.inlineDiffs = options.useInlineDiffs;\n\n  function done(failures) {\n    if (reporter.done) {\n      reporter.done(failures, fn);\n    } else {\n      fn && fn(failures);\n    }\n  }\n\n  return runner.run(done);\n};\n\n}).call(this,require('_process'),typeof global !== \"undefined\" ? global : typeof self !== \"undefined\" ? self : typeof window !== \"undefined\" ? window : {},\"/lib\")\n},{\"./context\":6,\"./hook\":7,\"./interfaces\":11,\"./reporters\":21,\"./runnable\":33,\"./runner\":34,\"./suite\":35,\"./test\":36,\"./utils\":38,\"_process\":67,\"escape-string-regexp\":47,\"growl\":49,\"path\":42}],15:[function(require,module,exports){\n/**\n * Helpers.\n */\n\nvar s = 1000;\nvar m = s * 60;\nvar h = m * 60;\nvar d = h * 24;\nvar y = d * 365.25;\n\n/**\n * Parse or format the given `val`.\n *\n * Options:\n *\n *  - `long` verbose formatting [false]\n *\n * @api public\n * @param {string|number} val\n * @param {Object} options\n * @return {string|number}\n */\nmodule.exports = function(val, options) {\n  options = options || {};\n  if (typeof val === 'string') {\n    return parse(val);\n  }\n  // https://github.com/mochajs/mocha/pull/1035\n  return options['long'] ? longFormat(val) : shortFormat(val);\n};\n\n/**\n * Parse the given `str` and return milliseconds.\n *\n * @api private\n * @param {string} str\n * @return {number}\n */\nfunction parse(str) {\n  var match = (/^((?:\\d+)?\\.?\\d+) *(ms|seconds?|s|minutes?|m|hours?|h|days?|d|years?|y)?$/i).exec(str);\n  if (!match) {\n    return;\n  }\n  var n = parseFloat(match[1]);\n  var type = (match[2] || 'ms').toLowerCase();\n  switch (type) {\n    case 'years':\n    case 'year':\n    case 'y':\n      return n * y;\n    case 'days':\n    case 'day':\n    case 'd':\n      return n * d;\n    case 'hours':\n    case 'hour':\n    case 'h':\n      return n * h;\n    case 'minutes':\n    case 'minute':\n    case 'm':\n      return n * m;\n    case 'seconds':\n    case 'second':\n    case 's':\n      return n * s;\n    case 'ms':\n      return n;\n    default:\n      // No default case\n  }\n}\n\n/**\n * Short format for `ms`.\n *\n * @api private\n * @param {number} ms\n * @return {string}\n */\nfunction shortFormat(ms) {\n  if (ms >= d) {\n    return Math.round(ms / d) + 'd';\n  }\n  if (ms >= h) {\n    return Math.round(ms / h) + 'h';\n  }\n  if (ms >= m) {\n    return Math.round(ms / m) + 'm';\n  }\n  if (ms >= s) {\n    return Math.round(ms / s) + 's';\n  }\n  return ms + 'ms';\n}\n\n/**\n * Long format for `ms`.\n *\n * @api private\n * @param {number} ms\n * @return {string}\n */\nfunction longFormat(ms) {\n  return plural(ms, d, 'day')\n    || plural(ms, h, 'hour')\n    || plural(ms, m, 'minute')\n    || plural(ms, s, 'second')\n    || ms + ' ms';\n}\n\n/**\n * Pluralization helper.\n *\n * @api private\n * @param {number} ms\n * @param {number} n\n * @param {string} name\n */\nfunction plural(ms, n, name) {\n  if (ms < n) {\n    return;\n  }\n  if (ms < n * 1.5) {\n    return Math.floor(ms / n) + ' ' + name;\n  }\n  return Math.ceil(ms / n) + ' ' + name + 's';\n}\n\n},{}],16:[function(require,module,exports){\n\n/**\n * Expose `Pending`.\n */\n\nmodule.exports = Pending;\n\n/**\n * Initialize a new `Pending` error with the given message.\n *\n * @param {string} message\n */\nfunction Pending(message) {\n  this.message = message;\n}\n\n},{}],17:[function(require,module,exports){\n(function (process,global){\n/**\n * Module dependencies.\n */\n\nvar tty = require('tty');\nvar diff = require('diff');\nvar ms = require('../ms');\nvar utils = require('../utils');\nvar supportsColor = process.browser ? null : require('supports-color');\n\n/**\n * Expose `Base`.\n */\n\nexports = module.exports = Base;\n\n/**\n * Save timer references to avoid Sinon interfering.\n * See: https://github.com/mochajs/mocha/issues/237\n */\n\n/* eslint-disable no-unused-vars, no-native-reassign */\nvar Date = global.Date;\nvar setTimeout = global.setTimeout;\nvar setInterval = global.setInterval;\nvar clearTimeout = global.clearTimeout;\nvar clearInterval = global.clearInterval;\n/* eslint-enable no-unused-vars, no-native-reassign */\n\n/**\n * Check if both stdio streams are associated with a tty.\n */\n\nvar isatty = tty.isatty(1) && tty.isatty(2);\n\n/**\n * Enable coloring by default, except in the browser interface.\n */\n\nexports.useColors = !process.browser && (supportsColor || (process.env.MOCHA_COLORS !== undefined));\n\n/**\n * Inline diffs instead of +/-\n */\n\nexports.inlineDiffs = false;\n\n/**\n * Default color map.\n */\n\nexports.colors = {\n  pass: 90,\n  fail: 31,\n  'bright pass': 92,\n  'bright fail': 91,\n  'bright yellow': 93,\n  pending: 36,\n  suite: 0,\n  'error title': 0,\n  'error message': 31,\n  'error stack': 90,\n  checkmark: 32,\n  fast: 90,\n  medium: 33,\n  slow: 31,\n  green: 32,\n  light: 90,\n  'diff gutter': 90,\n  'diff added': 32,\n  'diff removed': 31\n};\n\n/**\n * Default symbol map.\n */\n\nexports.symbols = {\n  ok: '✓',\n  err: '✖',\n  dot: '․',\n  comma: ',',\n  bang: '!'\n};\n\n// With node.js on Windows: use symbols available in terminal default fonts\nif (process.platform === 'win32') {\n  exports.symbols.ok = '\\u221A';\n  exports.symbols.err = '\\u00D7';\n  exports.symbols.dot = '.';\n}\n\n/**\n * Color `str` with the given `type`,\n * allowing colors to be disabled,\n * as well as user-defined color\n * schemes.\n *\n * @param {string} type\n * @param {string} str\n * @return {string}\n * @api private\n */\nvar color = exports.color = function(type, str) {\n  if (!exports.useColors) {\n    return String(str);\n  }\n  return '\\u001b[' + exports.colors[type] + 'm' + str + '\\u001b[0m';\n};\n\n/**\n * Expose term window size, with some defaults for when stderr is not a tty.\n */\n\nexports.window = {\n  width: 75\n};\n\nif (isatty) {\n  exports.window.width = process.stdout.getWindowSize\n      ? process.stdout.getWindowSize(1)[0]\n      : tty.getWindowSize()[1];\n}\n\n/**\n * Expose some basic cursor interactions that are common among reporters.\n */\n\nexports.cursor = {\n  hide: function() {\n    isatty && process.stdout.write('\\u001b[?25l');\n  },\n\n  show: function() {\n    isatty && process.stdout.write('\\u001b[?25h');\n  },\n\n  deleteLine: function() {\n    isatty && process.stdout.write('\\u001b[2K');\n  },\n\n  beginningOfLine: function() {\n    isatty && process.stdout.write('\\u001b[0G');\n  },\n\n  CR: function() {\n    if (isatty) {\n      exports.cursor.deleteLine();\n      exports.cursor.beginningOfLine();\n    } else {\n      process.stdout.write('\\r');\n    }\n  }\n};\n\n/**\n * Outut the given `failures` as a list.\n *\n * @param {Array} failures\n * @api public\n */\n\nexports.list = function(failures) {\n  console.log();\n  failures.forEach(function(test, i) {\n    // format\n    var fmt = color('error title', '  %s) %s:\\n')\n      + color('error message', '     %s')\n      + color('error stack', '\\n%s\\n');\n\n    // msg\n    var msg;\n    var err = test.err;\n    var message;\n    if (err.message && typeof err.message.toString === 'function') {\n      message = err.message + '';\n    } else if (typeof err.inspect === 'function') {\n      message = err.inspect() + '';\n    } else {\n      message = '';\n    }\n    var stack = err.stack || message;\n    var index = message ? stack.indexOf(message) : -1;\n    var actual = err.actual;\n    var expected = err.expected;\n    var escape = true;\n\n    if (index === -1) {\n      msg = message;\n    } else {\n      index += message.length;\n      msg = stack.slice(0, index);\n      // remove msg from stack\n      stack = stack.slice(index + 1);\n    }\n\n    // uncaught\n    if (err.uncaught) {\n      msg = 'Uncaught ' + msg;\n    }\n    // explicitly show diff\n    if (err.showDiff !== false && sameType(actual, expected) && expected !== undefined) {\n      escape = false;\n      if (!(utils.isString(actual) && utils.isString(expected))) {\n        err.actual = actual = utils.stringify(actual);\n        err.expected = expected = utils.stringify(expected);\n      }\n\n      fmt = color('error title', '  %s) %s:\\n%s') + color('error stack', '\\n%s\\n');\n      var match = message.match(/^([^:]+): expected/);\n      msg = '\\n      ' + color('error message', match ? match[1] : msg);\n\n      if (exports.inlineDiffs) {\n        msg += inlineDiff(err, escape);\n      } else {\n        msg += unifiedDiff(err, escape);\n      }\n    }\n\n    // indent stack trace\n    stack = stack.replace(/^/gm, '  ');\n\n    console.log(fmt, (i + 1), test.fullTitle(), msg, stack);\n  });\n};\n\n/**\n * Initialize a new `Base` reporter.\n *\n * All other reporters generally\n * inherit from this reporter, providing\n * stats such as test duration, number\n * of tests passed / failed etc.\n *\n * @param {Runner} runner\n * @api public\n */\n\nfunction Base(runner) {\n  var stats = this.stats = { suites: 0, tests: 0, passes: 0, pending: 0, failures: 0 };\n  var failures = this.failures = [];\n\n  if (!runner) {\n    return;\n  }\n  this.runner = runner;\n\n  runner.stats = stats;\n\n  runner.on('start', function() {\n    stats.start = new Date();\n  });\n\n  runner.on('suite', function(suite) {\n    stats.suites = stats.suites || 0;\n    suite.root || stats.suites++;\n  });\n\n  runner.on('test end', function() {\n    stats.tests = stats.tests || 0;\n    stats.tests++;\n  });\n\n  runner.on('pass', function(test) {\n    stats.passes = stats.passes || 0;\n\n    if (test.duration > test.slow()) {\n      test.speed = 'slow';\n    } else if (test.duration > test.slow() / 2) {\n      test.speed = 'medium';\n    } else {\n      test.speed = 'fast';\n    }\n\n    stats.passes++;\n  });\n\n  runner.on('fail', function(test, err) {\n    stats.failures = stats.failures || 0;\n    stats.failures++;\n    test.err = err;\n    failures.push(test);\n  });\n\n  runner.on('end', function() {\n    stats.end = new Date();\n    stats.duration = new Date() - stats.start;\n  });\n\n  runner.on('pending', function() {\n    stats.pending++;\n  });\n}\n\n/**\n * Output common epilogue used by many of\n * the bundled reporters.\n *\n * @api public\n */\nBase.prototype.epilogue = function() {\n  var stats = this.stats;\n  var fmt;\n\n  console.log();\n\n  // passes\n  fmt = color('bright pass', ' ')\n    + color('green', ' %d passing')\n    + color('light', ' (%s)');\n\n  console.log(fmt,\n    stats.passes || 0,\n    ms(stats.duration));\n\n  // pending\n  if (stats.pending) {\n    fmt = color('pending', ' ')\n      + color('pending', ' %d pending');\n\n    console.log(fmt, stats.pending);\n  }\n\n  // failures\n  if (stats.failures) {\n    fmt = color('fail', '  %d failing');\n\n    console.log(fmt, stats.failures);\n\n    Base.list(this.failures);\n    console.log();\n  }\n\n  console.log();\n};\n\n/**\n * Pad the given `str` to `len`.\n *\n * @api private\n * @param {string} str\n * @param {string} len\n * @return {string}\n */\nfunction pad(str, len) {\n  str = String(str);\n  return Array(len - str.length + 1).join(' ') + str;\n}\n\n/**\n * Returns an inline diff between 2 strings with coloured ANSI output\n *\n * @api private\n * @param {Error} err with actual/expected\n * @param {boolean} escape\n * @return {string} Diff\n */\nfunction inlineDiff(err, escape) {\n  var msg = errorDiff(err, 'WordsWithSpace', escape);\n\n  // linenos\n  var lines = msg.split('\\n');\n  if (lines.length > 4) {\n    var width = String(lines.length).length;\n    msg = lines.map(function(str, i) {\n      return pad(++i, width) + ' |' + ' ' + str;\n    }).join('\\n');\n  }\n\n  // legend\n  msg = '\\n'\n    + color('diff removed', 'actual')\n    + ' '\n    + color('diff added', 'expected')\n    + '\\n\\n'\n    + msg\n    + '\\n';\n\n  // indent\n  msg = msg.replace(/^/gm, '      ');\n  return msg;\n}\n\n/**\n * Returns a unified diff between two strings.\n *\n * @api private\n * @param {Error} err with actual/expected\n * @param {boolean} escape\n * @return {string} The diff.\n */\nfunction unifiedDiff(err, escape) {\n  var indent = '      ';\n  function cleanUp(line) {\n    if (escape) {\n      line = escapeInvisibles(line);\n    }\n    if (line[0] === '+') {\n      return indent + colorLines('diff added', line);\n    }\n    if (line[0] === '-') {\n      return indent + colorLines('diff removed', line);\n    }\n    if (line.match(/\\@\\@/)) {\n      return null;\n    }\n    if (line.match(/\\\\ No newline/)) {\n      return null;\n    }\n    return indent + line;\n  }\n  function notBlank(line) {\n    return typeof line !== 'undefined' && line !== null;\n  }\n  var msg = diff.createPatch('string', err.actual, err.expected);\n  var lines = msg.split('\\n').splice(4);\n  return '\\n      '\n    + colorLines('diff added', '+ expected') + ' '\n    + colorLines('diff removed', '- actual')\n    + '\\n\\n'\n    + lines.map(cleanUp).filter(notBlank).join('\\n');\n}\n\n/**\n * Return a character diff for `err`.\n *\n * @api private\n * @param {Error} err\n * @param {string} type\n * @param {boolean} escape\n * @return {string}\n */\nfunction errorDiff(err, type, escape) {\n  var actual = escape ? escapeInvisibles(err.actual) : err.actual;\n  var expected = escape ? escapeInvisibles(err.expected) : err.expected;\n  return diff['diff' + type](actual, expected).map(function(str) {\n    if (str.added) {\n      return colorLines('diff added', str.value);\n    }\n    if (str.removed) {\n      return colorLines('diff removed', str.value);\n    }\n    return str.value;\n  }).join('');\n}\n\n/**\n * Returns a string with all invisible characters in plain text\n *\n * @api private\n * @param {string} line\n * @return {string}\n */\nfunction escapeInvisibles(line) {\n  return line.replace(/\\t/g, '<tab>')\n    .replace(/\\r/g, '<CR>')\n    .replace(/\\n/g, '<LF>\\n');\n}\n\n/**\n * Color lines for `str`, using the color `name`.\n *\n * @api private\n * @param {string} name\n * @param {string} str\n * @return {string}\n */\nfunction colorLines(name, str) {\n  return str.split('\\n').map(function(str) {\n    return color(name, str);\n  }).join('\\n');\n}\n\n/**\n * Object#toString reference.\n */\nvar objToString = Object.prototype.toString;\n\n/**\n * Check that a / b have the same type.\n *\n * @api private\n * @param {Object} a\n * @param {Object} b\n * @return {boolean}\n */\nfunction sameType(a, b) {\n  return objToString.call(a) === objToString.call(b);\n}\n\n}).call(this,require('_process'),typeof global !== \"undefined\" ? global : typeof self !== \"undefined\" ? self : typeof window !== \"undefined\" ? window : {})\n},{\"../ms\":15,\"../utils\":38,\"_process\":67,\"diff\":46,\"supports-color\":42,\"tty\":5}],18:[function(require,module,exports){\n/**\n * Module dependencies.\n */\n\nvar Base = require('./base');\nvar utils = require('../utils');\n\n/**\n * Expose `Doc`.\n */\n\nexports = module.exports = Doc;\n\n/**\n * Initialize a new `Doc` reporter.\n *\n * @param {Runner} runner\n * @api public\n */\nfunction Doc(runner) {\n  Base.call(this, runner);\n\n  var indents = 2;\n\n  function indent() {\n    return Array(indents).join('  ');\n  }\n\n  runner.on('suite', function(suite) {\n    if (suite.root) {\n      return;\n    }\n    ++indents;\n    console.log('%s<section class=\"suite\">', indent());\n    ++indents;\n    console.log('%s<h1>%s</h1>', indent(), utils.escape(suite.title));\n    console.log('%s<dl>', indent());\n  });\n\n  runner.on('suite end', function(suite) {\n    if (suite.root) {\n      return;\n    }\n    console.log('%s</dl>', indent());\n    --indents;\n    console.log('%s</section>', indent());\n    --indents;\n  });\n\n  runner.on('pass', function(test) {\n    console.log('%s  <dt>%s</dt>', indent(), utils.escape(test.title));\n    var code = utils.escape(utils.clean(test.body));\n    console.log('%s  <dd><pre><code>%s</code></pre></dd>', indent(), code);\n  });\n\n  runner.on('fail', function(test, err) {\n    console.log('%s  <dt class=\"error\">%s</dt>', indent(), utils.escape(test.title));\n    var code = utils.escape(utils.clean(test.body));\n    console.log('%s  <dd class=\"error\"><pre><code>%s</code></pre></dd>', indent(), code);\n    console.log('%s  <dd class=\"error\">%s</dd>', indent(), utils.escape(err));\n  });\n}\n\n},{\"../utils\":38,\"./base\":17}],19:[function(require,module,exports){\n(function (process){\n/**\n * Module dependencies.\n */\n\nvar Base = require('./base');\nvar inherits = require('../utils').inherits;\nvar color = Base.color;\n\n/**\n * Expose `Dot`.\n */\n\nexports = module.exports = Dot;\n\n/**\n * Initialize a new `Dot` matrix test reporter.\n *\n * @api public\n * @param {Runner} runner\n */\nfunction Dot(runner) {\n  Base.call(this, runner);\n\n  var self = this;\n  var width = Base.window.width * .75 | 0;\n  var n = -1;\n\n  runner.on('start', function() {\n    process.stdout.write('\\n');\n  });\n\n  runner.on('pending', function() {\n    if (++n % width === 0) {\n      process.stdout.write('\\n  ');\n    }\n    process.stdout.write(color('pending', Base.symbols.comma));\n  });\n\n  runner.on('pass', function(test) {\n    if (++n % width === 0) {\n      process.stdout.write('\\n  ');\n    }\n    if (test.speed === 'slow') {\n      process.stdout.write(color('bright yellow', Base.symbols.dot));\n    } else {\n      process.stdout.write(color(test.speed, Base.symbols.dot));\n    }\n  });\n\n  runner.on('fail', function() {\n    if (++n % width === 0) {\n      process.stdout.write('\\n  ');\n    }\n    process.stdout.write(color('fail', Base.symbols.bang));\n  });\n\n  runner.on('end', function() {\n    console.log();\n    self.epilogue();\n  });\n}\n\n/**\n * Inherit from `Base.prototype`.\n */\ninherits(Dot, Base);\n\n}).call(this,require('_process'))\n},{\"../utils\":38,\"./base\":17,\"_process\":67}],20:[function(require,module,exports){\n(function (global){\n/* eslint-env browser */\n\n/**\n * Module dependencies.\n */\n\nvar Base = require('./base');\nvar utils = require('../utils');\nvar Progress = require('../browser/progress');\nvar escapeRe = require('escape-string-regexp');\nvar escape = utils.escape;\n\n/**\n * Save timer references to avoid Sinon interfering (see GH-237).\n */\n\n/* eslint-disable no-unused-vars, no-native-reassign */\nvar Date = global.Date;\nvar setTimeout = global.setTimeout;\nvar setInterval = global.setInterval;\nvar clearTimeout = global.clearTimeout;\nvar clearInterval = global.clearInterval;\n/* eslint-enable no-unused-vars, no-native-reassign */\n\n/**\n * Expose `HTML`.\n */\n\nexports = module.exports = HTML;\n\n/**\n * Stats template.\n */\n\nvar statsTemplate = '<ul id=\"mocha-stats\">'\n  + '<li class=\"progress\"><canvas width=\"40\" height=\"40\"></canvas></li>'\n  + '<li class=\"passes\"><a href=\"javascript:void(0);\">passes:</a> <em>0</em></li>'\n  + '<li class=\"failures\"><a href=\"javascript:void(0);\">failures:</a> <em>0</em></li>'\n  + '<li class=\"duration\">duration: <em>0</em>s</li>'\n  + '</ul>';\n\n/**\n * Initialize a new `HTML` reporter.\n *\n * @api public\n * @param {Runner} runner\n */\nfunction HTML(runner) {\n  Base.call(this, runner);\n\n  var self = this;\n  var stats = this.stats;\n  var stat = fragment(statsTemplate);\n  var items = stat.getElementsByTagName('li');\n  var passes = items[1].getElementsByTagName('em')[0];\n  var passesLink = items[1].getElementsByTagName('a')[0];\n  var failures = items[2].getElementsByTagName('em')[0];\n  var failuresLink = items[2].getElementsByTagName('a')[0];\n  var duration = items[3].getElementsByTagName('em')[0];\n  var canvas = stat.getElementsByTagName('canvas')[0];\n  var report = fragment('<ul id=\"mocha-report\"></ul>');\n  var stack = [report];\n  var progress;\n  var ctx;\n  var root = document.getElementById('mocha');\n\n  if (canvas.getContext) {\n    var ratio = window.devicePixelRatio || 1;\n    canvas.style.width = canvas.width;\n    canvas.style.height = canvas.height;\n    canvas.width *= ratio;\n    canvas.height *= ratio;\n    ctx = canvas.getContext('2d');\n    ctx.scale(ratio, ratio);\n    progress = new Progress();\n  }\n\n  if (!root) {\n    return error('#mocha div missing, add it to your document');\n  }\n\n  // pass toggle\n  on(passesLink, 'click', function(evt) {\n    evt.preventDefault();\n    unhide();\n    var name = (/pass/).test(report.className) ? '' : ' pass';\n    report.className = report.className.replace(/fail|pass/g, '') + name;\n    if (report.className.trim()) {\n      hideSuitesWithout('test pass');\n    }\n  });\n\n  // failure toggle\n  on(failuresLink, 'click', function(evt) {\n    evt.preventDefault();\n    unhide();\n    var name = (/fail/).test(report.className) ? '' : ' fail';\n    report.className = report.className.replace(/fail|pass/g, '') + name;\n    if (report.className.trim()) {\n      hideSuitesWithout('test fail');\n    }\n  });\n\n  root.appendChild(stat);\n  root.appendChild(report);\n\n  if (progress) {\n    progress.size(40);\n  }\n\n  runner.on('suite', function(suite) {\n    if (suite.root) {\n      return;\n    }\n\n    // suite\n    var url = self.suiteURL(suite);\n    var el = fragment('<li class=\"suite\"><h1><a href=\"%s\">%s</a></h1></li>', url, escape(suite.title));\n\n    // container\n    stack[0].appendChild(el);\n    stack.unshift(document.createElement('ul'));\n    el.appendChild(stack[0]);\n  });\n\n  runner.on('suite end', function(suite) {\n    if (suite.root) {\n      updateStats();\n      return;\n    }\n    stack.shift();\n  });\n\n  runner.on('pass', function(test) {\n    var url = self.testURL(test);\n    var markup = '<li class=\"test pass %e\"><h2>%e<span class=\"duration\">%ems</span> '\n      + '<a href=\"%s\" class=\"replay\">‣</a></h2></li>';\n    var el = fragment(markup, test.speed, test.title, test.duration, url);\n    self.addCodeToggle(el, test.body);\n    appendToStack(el);\n    updateStats();\n  });\n\n  runner.on('fail', function(test) {\n    var el = fragment('<li class=\"test fail\"><h2>%e <a href=\"%e\" class=\"replay\">‣</a></h2></li>',\n      test.title, self.testURL(test));\n    var stackString; // Note: Includes leading newline\n    var message = test.err.toString();\n\n    // <=IE7 stringifies to [Object Error]. Since it can be overloaded, we\n    // check for the result of the stringifying.\n    if (message === '[object Error]') {\n      message = test.err.message;\n    }\n\n    if (test.err.stack) {\n      var indexOfMessage = test.err.stack.indexOf(test.err.message);\n      if (indexOfMessage === -1) {\n        stackString = test.err.stack;\n      } else {\n        stackString = test.err.stack.substr(test.err.message.length + indexOfMessage);\n      }\n    } else if (test.err.sourceURL && test.err.line !== undefined) {\n      // Safari doesn't give you a stack. Let's at least provide a source line.\n      stackString = '\\n(' + test.err.sourceURL + ':' + test.err.line + ')';\n    }\n\n    stackString = stackString || '';\n\n    if (test.err.htmlMessage && stackString) {\n      el.appendChild(fragment('<div class=\"html-error\">%s\\n<pre class=\"error\">%e</pre></div>',\n        test.err.htmlMessage, stackString));\n    } else if (test.err.htmlMessage) {\n      el.appendChild(fragment('<div class=\"html-error\">%s</div>', test.err.htmlMessage));\n    } else {\n      el.appendChild(fragment('<pre class=\"error\">%e%e</pre>', message, stackString));\n    }\n\n    self.addCodeToggle(el, test.body);\n    appendToStack(el);\n    updateStats();\n  });\n\n  runner.on('pending', function(test) {\n    var el = fragment('<li class=\"test pass pending\"><h2>%e</h2></li>', test.title);\n    appendToStack(el);\n    updateStats();\n  });\n\n  function appendToStack(el) {\n    // Don't call .appendChild if #mocha-report was already .shift()'ed off the stack.\n    if (stack[0]) {\n      stack[0].appendChild(el);\n    }\n  }\n\n  function updateStats() {\n    // TODO: add to stats\n    var percent = stats.tests / runner.total * 100 | 0;\n    if (progress) {\n      progress.update(percent).draw(ctx);\n    }\n\n    // update stats\n    var ms = new Date() - stats.start;\n    text(passes, stats.passes);\n    text(failures, stats.failures);\n    text(duration, (ms / 1000).toFixed(2));\n  }\n}\n\n/**\n * Makes a URL, preserving querystring (\"search\") parameters.\n *\n * @param {string} s\n * @return {string} A new URL.\n */\nfunction makeUrl(s) {\n  var search = window.location.search;\n\n  // Remove previous grep query parameter if present\n  if (search) {\n    search = search.replace(/[?&]grep=[^&\\s]*/g, '').replace(/^&/, '?');\n  }\n\n  return window.location.pathname + (search ? search + '&' : '?') + 'grep=' + encodeURIComponent(escapeRe(s));\n}\n\n/**\n * Provide suite URL.\n *\n * @param {Object} [suite]\n */\nHTML.prototype.suiteURL = function(suite) {\n  return makeUrl(suite.fullTitle());\n};\n\n/**\n * Provide test URL.\n *\n * @param {Object} [test]\n */\nHTML.prototype.testURL = function(test) {\n  return makeUrl(test.fullTitle());\n};\n\n/**\n * Adds code toggle functionality for the provided test's list element.\n *\n * @param {HTMLLIElement} el\n * @param {string} contents\n */\nHTML.prototype.addCodeToggle = function(el, contents) {\n  var h2 = el.getElementsByTagName('h2')[0];\n\n  on(h2, 'click', function() {\n    pre.style.display = pre.style.display === 'none' ? 'block' : 'none';\n  });\n\n  var pre = fragment('<pre><code>%e</code></pre>', utils.clean(contents));\n  el.appendChild(pre);\n  pre.style.display = 'none';\n};\n\n/**\n * Display error `msg`.\n *\n * @param {string} msg\n */\nfunction error(msg) {\n  document.body.appendChild(fragment('<div id=\"mocha-error\">%s</div>', msg));\n}\n\n/**\n * Return a DOM fragment from `html`.\n *\n * @param {string} html\n */\nfunction fragment(html) {\n  var args = arguments;\n  var div = document.createElement('div');\n  var i = 1;\n\n  div.innerHTML = html.replace(/%([se])/g, function(_, type) {\n    switch (type) {\n      case 's': return String(args[i++]);\n      case 'e': return escape(args[i++]);\n      // no default\n    }\n  });\n\n  return div.firstChild;\n}\n\n/**\n * Check for suites that do not have elements\n * with `classname`, and hide them.\n *\n * @param {text} classname\n */\nfunction hideSuitesWithout(classname) {\n  var suites = document.getElementsByClassName('suite');\n  for (var i = 0; i < suites.length; i++) {\n    var els = suites[i].getElementsByClassName(classname);\n    if (!els.length) {\n      suites[i].className += ' hidden';\n    }\n  }\n}\n\n/**\n * Unhide .hidden suites.\n */\nfunction unhide() {\n  var els = document.getElementsByClassName('suite hidden');\n  for (var i = 0; i < els.length; ++i) {\n    els[i].className = els[i].className.replace('suite hidden', 'suite');\n  }\n}\n\n/**\n * Set an element's text contents.\n *\n * @param {HTMLElement} el\n * @param {string} contents\n */\nfunction text(el, contents) {\n  if (el.textContent) {\n    el.textContent = contents;\n  } else {\n    el.innerText = contents;\n  }\n}\n\n/**\n * Listen on `event` with callback `fn`.\n */\nfunction on(el, event, fn) {\n  if (el.addEventListener) {\n    el.addEventListener(event, fn, false);\n  } else {\n    el.attachEvent('on' + event, fn);\n  }\n}\n\n}).call(this,typeof global !== \"undefined\" ? global : typeof self !== \"undefined\" ? self : typeof window !== \"undefined\" ? window : {})\n},{\"../browser/progress\":4,\"../utils\":38,\"./base\":17,\"escape-string-regexp\":47}],21:[function(require,module,exports){\n// Alias exports to a their normalized format Mocha#reporter to prevent a need\n// for dynamic (try/catch) requires, which Browserify doesn't handle.\nexports.Base = exports.base = require('./base');\nexports.Dot = exports.dot = require('./dot');\nexports.Doc = exports.doc = require('./doc');\nexports.TAP = exports.tap = require('./tap');\nexports.JSON = exports.json = require('./json');\nexports.HTML = exports.html = require('./html');\nexports.List = exports.list = require('./list');\nexports.Min = exports.min = require('./min');\nexports.Spec = exports.spec = require('./spec');\nexports.Nyan = exports.nyan = require('./nyan');\nexports.XUnit = exports.xunit = require('./xunit');\nexports.Markdown = exports.markdown = require('./markdown');\nexports.Progress = exports.progress = require('./progress');\nexports.Landing = exports.landing = require('./landing');\nexports.JSONStream = exports['json-stream'] = require('./json-stream');\n\n},{\"./base\":17,\"./doc\":18,\"./dot\":19,\"./html\":20,\"./json\":23,\"./json-stream\":22,\"./landing\":24,\"./list\":25,\"./markdown\":26,\"./min\":27,\"./nyan\":28,\"./progress\":29,\"./spec\":30,\"./tap\":31,\"./xunit\":32}],22:[function(require,module,exports){\n(function (process){\n/**\n * Module dependencies.\n */\n\nvar Base = require('./base');\nvar JSON = require('json3');\n\n/**\n * Expose `List`.\n */\n\nexports = module.exports = List;\n\n/**\n * Initialize a new `List` test reporter.\n *\n * @api public\n * @param {Runner} runner\n */\nfunction List(runner) {\n  Base.call(this, runner);\n\n  var self = this;\n  var total = runner.total;\n\n  runner.on('start', function() {\n    console.log(JSON.stringify(['start', { total: total }]));\n  });\n\n  runner.on('pass', function(test) {\n    console.log(JSON.stringify(['pass', clean(test)]));\n  });\n\n  runner.on('fail', function(test, err) {\n    test = clean(test);\n    test.err = err.message;\n    test.stack = err.stack || null;\n    console.log(JSON.stringify(['fail', test]));\n  });\n\n  runner.on('end', function() {\n    process.stdout.write(JSON.stringify(['end', self.stats]));\n  });\n}\n\n/**\n * Return a plain-object representation of `test`\n * free of cyclic properties etc.\n *\n * @api private\n * @param {Object} test\n * @return {Object}\n */\nfunction clean(test) {\n  return {\n    title: test.title,\n    fullTitle: test.fullTitle(),\n    duration: test.duration,\n    currentRetry: test.currentRetry()\n  };\n}\n\n}).call(this,require('_process'))\n},{\"./base\":17,\"_process\":67,\"json3\":54}],23:[function(require,module,exports){\n(function (process){\n/**\n * Module dependencies.\n */\n\nvar Base = require('./base');\n\n/**\n * Expose `JSON`.\n */\n\nexports = module.exports = JSONReporter;\n\n/**\n * Initialize a new `JSON` reporter.\n *\n * @api public\n * @param {Runner} runner\n */\nfunction JSONReporter(runner) {\n  Base.call(this, runner);\n\n  var self = this;\n  var tests = [];\n  var pending = [];\n  var failures = [];\n  var passes = [];\n\n  runner.on('test end', function(test) {\n    tests.push(test);\n  });\n\n  runner.on('pass', function(test) {\n    passes.push(test);\n  });\n\n  runner.on('fail', function(test) {\n    failures.push(test);\n  });\n\n  runner.on('pending', function(test) {\n    pending.push(test);\n  });\n\n  runner.on('end', function() {\n    var obj = {\n      stats: self.stats,\n      tests: tests.map(clean),\n      pending: pending.map(clean),\n      failures: failures.map(clean),\n      passes: passes.map(clean)\n    };\n\n    runner.testResults = obj;\n\n    process.stdout.write(JSON.stringify(obj, null, 2));\n  });\n}\n\n/**\n * Return a plain-object representation of `test`\n * free of cyclic properties etc.\n *\n * @api private\n * @param {Object} test\n * @return {Object}\n */\nfunction clean(test) {\n  return {\n    title: test.title,\n    fullTitle: test.fullTitle(),\n    duration: test.duration,\n    currentRetry: test.currentRetry(),\n    err: errorJSON(test.err || {})\n  };\n}\n\n/**\n * Transform `error` into a JSON object.\n *\n * @api private\n * @param {Error} err\n * @return {Object}\n */\nfunction errorJSON(err) {\n  var res = {};\n  Object.getOwnPropertyNames(err).forEach(function(key) {\n    res[key] = err[key];\n  }, err);\n  return res;\n}\n\n}).call(this,require('_process'))\n},{\"./base\":17,\"_process\":67}],24:[function(require,module,exports){\n(function (process){\n/**\n * Module dependencies.\n */\n\nvar Base = require('./base');\nvar inherits = require('../utils').inherits;\nvar cursor = Base.cursor;\nvar color = Base.color;\n\n/**\n * Expose `Landing`.\n */\n\nexports = module.exports = Landing;\n\n/**\n * Airplane color.\n */\n\nBase.colors.plane = 0;\n\n/**\n * Airplane crash color.\n */\n\nBase.colors['plane crash'] = 31;\n\n/**\n * Runway color.\n */\n\nBase.colors.runway = 90;\n\n/**\n * Initialize a new `Landing` reporter.\n *\n * @api public\n * @param {Runner} runner\n */\nfunction Landing(runner) {\n  Base.call(this, runner);\n\n  var self = this;\n  var width = Base.window.width * .75 | 0;\n  var total = runner.total;\n  var stream = process.stdout;\n  var plane = color('plane', '✈');\n  var crashed = -1;\n  var n = 0;\n\n  function runway() {\n    var buf = Array(width).join('-');\n    return '  ' + color('runway', buf);\n  }\n\n  runner.on('start', function() {\n    stream.write('\\n\\n\\n  ');\n    cursor.hide();\n  });\n\n  runner.on('test end', function(test) {\n    // check if the plane crashed\n    var col = crashed === -1 ? width * ++n / total | 0 : crashed;\n\n    // show the crash\n    if (test.state === 'failed') {\n      plane = color('plane crash', '✈');\n      crashed = col;\n    }\n\n    // render landing strip\n    stream.write('\\u001b[' + (width + 1) + 'D\\u001b[2A');\n    stream.write(runway());\n    stream.write('\\n  ');\n    stream.write(color('runway', Array(col).join('⋅')));\n    stream.write(plane);\n    stream.write(color('runway', Array(width - col).join('⋅') + '\\n'));\n    stream.write(runway());\n    stream.write('\\u001b[0m');\n  });\n\n  runner.on('end', function() {\n    cursor.show();\n    console.log();\n    self.epilogue();\n  });\n}\n\n/**\n * Inherit from `Base.prototype`.\n */\ninherits(Landing, Base);\n\n}).call(this,require('_process'))\n},{\"../utils\":38,\"./base\":17,\"_process\":67}],25:[function(require,module,exports){\n(function (process){\n/**\n * Module dependencies.\n */\n\nvar Base = require('./base');\nvar inherits = require('../utils').inherits;\nvar color = Base.color;\nvar cursor = Base.cursor;\n\n/**\n * Expose `List`.\n */\n\nexports = module.exports = List;\n\n/**\n * Initialize a new `List` test reporter.\n *\n * @api public\n * @param {Runner} runner\n */\nfunction List(runner) {\n  Base.call(this, runner);\n\n  var self = this;\n  var n = 0;\n\n  runner.on('start', function() {\n    console.log();\n  });\n\n  runner.on('test', function(test) {\n    process.stdout.write(color('pass', '    ' + test.fullTitle() + ': '));\n  });\n\n  runner.on('pending', function(test) {\n    var fmt = color('checkmark', '  -')\n      + color('pending', ' %s');\n    console.log(fmt, test.fullTitle());\n  });\n\n  runner.on('pass', function(test) {\n    var fmt = color('checkmark', '  ' + Base.symbols.dot)\n      + color('pass', ' %s: ')\n      + color(test.speed, '%dms');\n    cursor.CR();\n    console.log(fmt, test.fullTitle(), test.duration);\n  });\n\n  runner.on('fail', function(test) {\n    cursor.CR();\n    console.log(color('fail', '  %d) %s'), ++n, test.fullTitle());\n  });\n\n  runner.on('end', self.epilogue.bind(self));\n}\n\n/**\n * Inherit from `Base.prototype`.\n */\ninherits(List, Base);\n\n}).call(this,require('_process'))\n},{\"../utils\":38,\"./base\":17,\"_process\":67}],26:[function(require,module,exports){\n(function (process){\n/**\n * Module dependencies.\n */\n\nvar Base = require('./base');\nvar utils = require('../utils');\n\n/**\n * Constants\n */\n\nvar SUITE_PREFIX = '$';\n\n/**\n * Expose `Markdown`.\n */\n\nexports = module.exports = Markdown;\n\n/**\n * Initialize a new `Markdown` reporter.\n *\n * @api public\n * @param {Runner} runner\n */\nfunction Markdown(runner) {\n  Base.call(this, runner);\n\n  var level = 0;\n  var buf = '';\n\n  function title(str) {\n    return Array(level).join('#') + ' ' + str;\n  }\n\n  function mapTOC(suite, obj) {\n    var ret = obj;\n    var key = SUITE_PREFIX + suite.title;\n\n    obj = obj[key] = obj[key] || { suite: suite };\n    suite.suites.forEach(function(suite) {\n      mapTOC(suite, obj);\n    });\n\n    return ret;\n  }\n\n  function stringifyTOC(obj, level) {\n    ++level;\n    var buf = '';\n    var link;\n    for (var key in obj) {\n      if (key === 'suite') {\n        continue;\n      }\n      if (key !== SUITE_PREFIX) {\n        link = ' - [' + key.substring(1) + ']';\n        link += '(#' + utils.slug(obj[key].suite.fullTitle()) + ')\\n';\n        buf += Array(level).join('  ') + link;\n      }\n      buf += stringifyTOC(obj[key], level);\n    }\n    return buf;\n  }\n\n  function generateTOC(suite) {\n    var obj = mapTOC(suite, {});\n    return stringifyTOC(obj, 0);\n  }\n\n  generateTOC(runner.suite);\n\n  runner.on('suite', function(suite) {\n    ++level;\n    var slug = utils.slug(suite.fullTitle());\n    buf += '<a name=\"' + slug + '\"></a>' + '\\n';\n    buf += title(suite.title) + '\\n';\n  });\n\n  runner.on('suite end', function() {\n    --level;\n  });\n\n  runner.on('pass', function(test) {\n    var code = utils.clean(test.body);\n    buf += test.title + '.\\n';\n    buf += '\\n```js\\n';\n    buf += code + '\\n';\n    buf += '```\\n\\n';\n  });\n\n  runner.on('end', function() {\n    process.stdout.write('# TOC\\n');\n    process.stdout.write(generateTOC(runner.suite));\n    process.stdout.write(buf);\n  });\n}\n\n}).call(this,require('_process'))\n},{\"../utils\":38,\"./base\":17,\"_process\":67}],27:[function(require,module,exports){\n(function (process){\n/**\n * Module dependencies.\n */\n\nvar Base = require('./base');\nvar inherits = require('../utils').inherits;\n\n/**\n * Expose `Min`.\n */\n\nexports = module.exports = Min;\n\n/**\n * Initialize a new `Min` minimal test reporter (best used with --watch).\n *\n * @api public\n * @param {Runner} runner\n */\nfunction Min(runner) {\n  Base.call(this, runner);\n\n  runner.on('start', function() {\n    // clear screen\n    process.stdout.write('\\u001b[2J');\n    // set cursor position\n    process.stdout.write('\\u001b[1;3H');\n  });\n\n  runner.on('end', this.epilogue.bind(this));\n}\n\n/**\n * Inherit from `Base.prototype`.\n */\ninherits(Min, Base);\n\n}).call(this,require('_process'))\n},{\"../utils\":38,\"./base\":17,\"_process\":67}],28:[function(require,module,exports){\n(function (process){\n/**\n * Module dependencies.\n */\n\nvar Base = require('./base');\nvar inherits = require('../utils').inherits;\n\n/**\n * Expose `Dot`.\n */\n\nexports = module.exports = NyanCat;\n\n/**\n * Initialize a new `Dot` matrix test reporter.\n *\n * @param {Runner} runner\n * @api public\n */\n\nfunction NyanCat(runner) {\n  Base.call(this, runner);\n\n  var self = this;\n  var width = Base.window.width * .75 | 0;\n  var nyanCatWidth = this.nyanCatWidth = 11;\n\n  this.colorIndex = 0;\n  this.numberOfLines = 4;\n  this.rainbowColors = self.generateColors();\n  this.scoreboardWidth = 5;\n  this.tick = 0;\n  this.trajectories = [[], [], [], []];\n  this.trajectoryWidthMax = (width - nyanCatWidth);\n\n  runner.on('start', function() {\n    Base.cursor.hide();\n    self.draw();\n  });\n\n  runner.on('pending', function() {\n    self.draw();\n  });\n\n  runner.on('pass', function() {\n    self.draw();\n  });\n\n  runner.on('fail', function() {\n    self.draw();\n  });\n\n  runner.on('end', function() {\n    Base.cursor.show();\n    for (var i = 0; i < self.numberOfLines; i++) {\n      write('\\n');\n    }\n    self.epilogue();\n  });\n}\n\n/**\n * Inherit from `Base.prototype`.\n */\ninherits(NyanCat, Base);\n\n/**\n * Draw the nyan cat\n *\n * @api private\n */\n\nNyanCat.prototype.draw = function() {\n  this.appendRainbow();\n  this.drawScoreboard();\n  this.drawRainbow();\n  this.drawNyanCat();\n  this.tick = !this.tick;\n};\n\n/**\n * Draw the \"scoreboard\" showing the number\n * of passes, failures and pending tests.\n *\n * @api private\n */\n\nNyanCat.prototype.drawScoreboard = function() {\n  var stats = this.stats;\n\n  function draw(type, n) {\n    write(' ');\n    write(Base.color(type, n));\n    write('\\n');\n  }\n\n  draw('green', stats.passes);\n  draw('fail', stats.failures);\n  draw('pending', stats.pending);\n  write('\\n');\n\n  this.cursorUp(this.numberOfLines);\n};\n\n/**\n * Append the rainbow.\n *\n * @api private\n */\n\nNyanCat.prototype.appendRainbow = function() {\n  var segment = this.tick ? '_' : '-';\n  var rainbowified = this.rainbowify(segment);\n\n  for (var index = 0; index < this.numberOfLines; index++) {\n    var trajectory = this.trajectories[index];\n    if (trajectory.length >= this.trajectoryWidthMax) {\n      trajectory.shift();\n    }\n    trajectory.push(rainbowified);\n  }\n};\n\n/**\n * Draw the rainbow.\n *\n * @api private\n */\n\nNyanCat.prototype.drawRainbow = function() {\n  var self = this;\n\n  this.trajectories.forEach(function(line) {\n    write('\\u001b[' + self.scoreboardWidth + 'C');\n    write(line.join(''));\n    write('\\n');\n  });\n\n  this.cursorUp(this.numberOfLines);\n};\n\n/**\n * Draw the nyan cat\n *\n * @api private\n */\nNyanCat.prototype.drawNyanCat = function() {\n  var self = this;\n  var startWidth = this.scoreboardWidth + this.trajectories[0].length;\n  var dist = '\\u001b[' + startWidth + 'C';\n  var padding = '';\n\n  write(dist);\n  write('_,------,');\n  write('\\n');\n\n  write(dist);\n  padding = self.tick ? '  ' : '   ';\n  write('_|' + padding + '/\\\\_/\\\\ ');\n  write('\\n');\n\n  write(dist);\n  padding = self.tick ? '_' : '__';\n  var tail = self.tick ? '~' : '^';\n  write(tail + '|' + padding + this.face() + ' ');\n  write('\\n');\n\n  write(dist);\n  padding = self.tick ? ' ' : '  ';\n  write(padding + '\"\"  \"\" ');\n  write('\\n');\n\n  this.cursorUp(this.numberOfLines);\n};\n\n/**\n * Draw nyan cat face.\n *\n * @api private\n * @return {string}\n */\n\nNyanCat.prototype.face = function() {\n  var stats = this.stats;\n  if (stats.failures) {\n    return '( x .x)';\n  } else if (stats.pending) {\n    return '( o .o)';\n  } else if (stats.passes) {\n    return '( ^ .^)';\n  }\n  return '( - .-)';\n};\n\n/**\n * Move cursor up `n`.\n *\n * @api private\n * @param {number} n\n */\n\nNyanCat.prototype.cursorUp = function(n) {\n  write('\\u001b[' + n + 'A');\n};\n\n/**\n * Move cursor down `n`.\n *\n * @api private\n * @param {number} n\n */\n\nNyanCat.prototype.cursorDown = function(n) {\n  write('\\u001b[' + n + 'B');\n};\n\n/**\n * Generate rainbow colors.\n *\n * @api private\n * @return {Array}\n */\nNyanCat.prototype.generateColors = function() {\n  var colors = [];\n\n  for (var i = 0; i < (6 * 7); i++) {\n    var pi3 = Math.floor(Math.PI / 3);\n    var n = (i * (1.0 / 6));\n    var r = Math.floor(3 * Math.sin(n) + 3);\n    var g = Math.floor(3 * Math.sin(n + 2 * pi3) + 3);\n    var b = Math.floor(3 * Math.sin(n + 4 * pi3) + 3);\n    colors.push(36 * r + 6 * g + b + 16);\n  }\n\n  return colors;\n};\n\n/**\n * Apply rainbow to the given `str`.\n *\n * @api private\n * @param {string} str\n * @return {string}\n */\nNyanCat.prototype.rainbowify = function(str) {\n  if (!Base.useColors) {\n    return str;\n  }\n  var color = this.rainbowColors[this.colorIndex % this.rainbowColors.length];\n  this.colorIndex += 1;\n  return '\\u001b[38;5;' + color + 'm' + str + '\\u001b[0m';\n};\n\n/**\n * Stdout helper.\n *\n * @param {string} string A message to write to stdout.\n */\nfunction write(string) {\n  process.stdout.write(string);\n}\n\n}).call(this,require('_process'))\n},{\"../utils\":38,\"./base\":17,\"_process\":67}],29:[function(require,module,exports){\n(function (process){\n/**\n * Module dependencies.\n */\n\nvar Base = require('./base');\nvar inherits = require('../utils').inherits;\nvar color = Base.color;\nvar cursor = Base.cursor;\n\n/**\n * Expose `Progress`.\n */\n\nexports = module.exports = Progress;\n\n/**\n * General progress bar color.\n */\n\nBase.colors.progress = 90;\n\n/**\n * Initialize a new `Progress` bar test reporter.\n *\n * @api public\n * @param {Runner} runner\n * @param {Object} options\n */\nfunction Progress(runner, options) {\n  Base.call(this, runner);\n\n  var self = this;\n  var width = Base.window.width * .50 | 0;\n  var total = runner.total;\n  var complete = 0;\n  var lastN = -1;\n\n  // default chars\n  options = options || {};\n  options.open = options.open || '[';\n  options.complete = options.complete || '▬';\n  options.incomplete = options.incomplete || Base.symbols.dot;\n  options.close = options.close || ']';\n  options.verbose = false;\n\n  // tests started\n  runner.on('start', function() {\n    console.log();\n    cursor.hide();\n  });\n\n  // tests complete\n  runner.on('test end', function() {\n    complete++;\n\n    var percent = complete / total;\n    var n = width * percent | 0;\n    var i = width - n;\n\n    if (n === lastN && !options.verbose) {\n      // Don't re-render the line if it hasn't changed\n      return;\n    }\n    lastN = n;\n\n    cursor.CR();\n    process.stdout.write('\\u001b[J');\n    process.stdout.write(color('progress', '  ' + options.open));\n    process.stdout.write(Array(n).join(options.complete));\n    process.stdout.write(Array(i).join(options.incomplete));\n    process.stdout.write(color('progress', options.close));\n    if (options.verbose) {\n      process.stdout.write(color('progress', ' ' + complete + ' of ' + total));\n    }\n  });\n\n  // tests are complete, output some stats\n  // and the failures if any\n  runner.on('end', function() {\n    cursor.show();\n    console.log();\n    self.epilogue();\n  });\n}\n\n/**\n * Inherit from `Base.prototype`.\n */\ninherits(Progress, Base);\n\n}).call(this,require('_process'))\n},{\"../utils\":38,\"./base\":17,\"_process\":67}],30:[function(require,module,exports){\n/**\n * Module dependencies.\n */\n\nvar Base = require('./base');\nvar inherits = require('../utils').inherits;\nvar color = Base.color;\n\n/**\n * Expose `Spec`.\n */\n\nexports = module.exports = Spec;\n\n/**\n * Initialize a new `Spec` test reporter.\n *\n * @api public\n * @param {Runner} runner\n */\nfunction Spec(runner) {\n  Base.call(this, runner);\n\n  var self = this;\n  var indents = 0;\n  var n = 0;\n\n  function indent() {\n    return Array(indents).join('  ');\n  }\n\n  runner.on('start', function() {\n    console.log();\n  });\n\n  runner.on('suite', function(suite) {\n    ++indents;\n    console.log(color('suite', '%s%s'), indent(), suite.title);\n  });\n\n  runner.on('suite end', function() {\n    --indents;\n    if (indents === 1) {\n      console.log();\n    }\n  });\n\n  runner.on('pending', function(test) {\n    var fmt = indent() + color('pending', '  - %s');\n    console.log(fmt, test.title);\n  });\n\n  runner.on('pass', function(test) {\n    var fmt;\n    if (test.speed === 'fast') {\n      fmt = indent()\n        + color('checkmark', '  ' + Base.symbols.ok)\n        + color('pass', ' %s');\n      console.log(fmt, test.title);\n    } else {\n      fmt = indent()\n        + color('checkmark', '  ' + Base.symbols.ok)\n        + color('pass', ' %s')\n        + color(test.speed, ' (%dms)');\n      console.log(fmt, test.title, test.duration);\n    }\n  });\n\n  runner.on('fail', function(test) {\n    console.log(indent() + color('fail', '  %d) %s'), ++n, test.title);\n  });\n\n  runner.on('end', self.epilogue.bind(self));\n}\n\n/**\n * Inherit from `Base.prototype`.\n */\ninherits(Spec, Base);\n\n},{\"../utils\":38,\"./base\":17}],31:[function(require,module,exports){\n/**\n * Module dependencies.\n */\n\nvar Base = require('./base');\n\n/**\n * Expose `TAP`.\n */\n\nexports = module.exports = TAP;\n\n/**\n * Initialize a new `TAP` reporter.\n *\n * @api public\n * @param {Runner} runner\n */\nfunction TAP(runner) {\n  Base.call(this, runner);\n\n  var n = 1;\n  var passes = 0;\n  var failures = 0;\n\n  runner.on('start', function() {\n    var total = runner.grepTotal(runner.suite);\n    console.log('%d..%d', 1, total);\n  });\n\n  runner.on('test end', function() {\n    ++n;\n  });\n\n  runner.on('pending', function(test) {\n    console.log('ok %d %s # SKIP -', n, title(test));\n  });\n\n  runner.on('pass', function(test) {\n    passes++;\n    console.log('ok %d %s', n, title(test));\n  });\n\n  runner.on('fail', function(test, err) {\n    failures++;\n    console.log('not ok %d %s', n, title(test));\n    if (err.stack) {\n      console.log(err.stack.replace(/^/gm, '  '));\n    }\n  });\n\n  runner.on('end', function() {\n    console.log('# tests ' + (passes + failures));\n    console.log('# pass ' + passes);\n    console.log('# fail ' + failures);\n  });\n}\n\n/**\n * Return a TAP-safe title of `test`\n *\n * @api private\n * @param {Object} test\n * @return {String}\n */\nfunction title(test) {\n  return test.fullTitle().replace(/#/g, '');\n}\n\n},{\"./base\":17}],32:[function(require,module,exports){\n(function (process,global){\n/**\n * Module dependencies.\n */\n\nvar Base = require('./base');\nvar utils = require('../utils');\nvar inherits = utils.inherits;\nvar fs = require('fs');\nvar escape = utils.escape;\nvar mkdirp = require('mkdirp');\nvar path = require('path');\n\n/**\n * Save timer references to avoid Sinon interfering (see GH-237).\n */\n\n/* eslint-disable no-unused-vars, no-native-reassign */\nvar Date = global.Date;\nvar setTimeout = global.setTimeout;\nvar setInterval = global.setInterval;\nvar clearTimeout = global.clearTimeout;\nvar clearInterval = global.clearInterval;\n/* eslint-enable no-unused-vars, no-native-reassign */\n\n/**\n * Expose `XUnit`.\n */\n\nexports = module.exports = XUnit;\n\n/**\n * Initialize a new `XUnit` reporter.\n *\n * @api public\n * @param {Runner} runner\n */\nfunction XUnit(runner, options) {\n  Base.call(this, runner);\n\n  var stats = this.stats;\n  var tests = [];\n  var self = this;\n\n  if (options.reporterOptions && options.reporterOptions.output) {\n    if (!fs.createWriteStream) {\n      throw new Error('file output not supported in browser');\n    }\n    mkdirp.sync(path.dirname(options.reporterOptions.output));\n    self.fileStream = fs.createWriteStream(options.reporterOptions.output);\n  }\n\n  runner.on('pending', function(test) {\n    tests.push(test);\n  });\n\n  runner.on('pass', function(test) {\n    tests.push(test);\n  });\n\n  runner.on('fail', function(test) {\n    tests.push(test);\n  });\n\n  runner.on('end', function() {\n    self.write(tag('testsuite', {\n      name: 'Mocha Tests',\n      tests: stats.tests,\n      failures: stats.failures,\n      errors: stats.failures,\n      skipped: stats.tests - stats.failures - stats.passes,\n      timestamp: (new Date()).toUTCString(),\n      time: (stats.duration / 1000) || 0\n    }, false));\n\n    tests.forEach(function(t) {\n      self.test(t);\n    });\n\n    self.write('</testsuite>');\n  });\n}\n\n/**\n * Inherit from `Base.prototype`.\n */\ninherits(XUnit, Base);\n\n/**\n * Override done to close the stream (if it's a file).\n *\n * @param failures\n * @param {Function} fn\n */\nXUnit.prototype.done = function(failures, fn) {\n  if (this.fileStream) {\n    this.fileStream.end(function() {\n      fn(failures);\n    });\n  } else {\n    fn(failures);\n  }\n};\n\n/**\n * Write out the given line.\n *\n * @param {string} line\n */\nXUnit.prototype.write = function(line) {\n  if (this.fileStream) {\n    this.fileStream.write(line + '\\n');\n  } else if (typeof process === 'object' && process.stdout) {\n    process.stdout.write(line + '\\n');\n  } else {\n    console.log(line);\n  }\n};\n\n/**\n * Output tag for the given `test.`\n *\n * @param {Test} test\n */\nXUnit.prototype.test = function(test) {\n  var attrs = {\n    classname: test.parent.fullTitle(),\n    name: test.title,\n    time: (test.duration / 1000) || 0\n  };\n\n  if (test.state === 'failed') {\n    var err = test.err;\n    this.write(tag('testcase', attrs, false, tag('failure', {}, false, escape(err.message) + '\\n' + escape(err.stack))));\n  } else if (test.isPending()) {\n    this.write(tag('testcase', attrs, false, tag('skipped', {}, true)));\n  } else {\n    this.write(tag('testcase', attrs, true));\n  }\n};\n\n/**\n * HTML tag helper.\n *\n * @param name\n * @param attrs\n * @param close\n * @param content\n * @return {string}\n */\nfunction tag(name, attrs, close, content) {\n  var end = close ? '/>' : '>';\n  var pairs = [];\n  var tag;\n\n  for (var key in attrs) {\n    if (Object.prototype.hasOwnProperty.call(attrs, key)) {\n      pairs.push(key + '=\"' + escape(attrs[key]) + '\"');\n    }\n  }\n\n  tag = '<' + name + (pairs.length ? ' ' + pairs.join(' ') : '') + end;\n  if (content) {\n    tag += content + '</' + name + end;\n  }\n  return tag;\n}\n\n}).call(this,require('_process'),typeof global !== \"undefined\" ? global : typeof self !== \"undefined\" ? self : typeof window !== \"undefined\" ? window : {})\n},{\"../utils\":38,\"./base\":17,\"_process\":67,\"fs\":42,\"mkdirp\":64,\"path\":42}],33:[function(require,module,exports){\n(function (global){\n/**\n * Module dependencies.\n */\n\nvar EventEmitter = require('events').EventEmitter;\nvar JSON = require('json3');\nvar Pending = require('./pending');\nvar debug = require('debug')('mocha:runnable');\nvar milliseconds = require('./ms');\nvar utils = require('./utils');\nvar create = require('lodash.create');\n\n/**\n * Save timer references to avoid Sinon interfering (see GH-237).\n */\n\n/* eslint-disable no-unused-vars, no-native-reassign */\nvar Date = global.Date;\nvar setTimeout = global.setTimeout;\nvar setInterval = global.setInterval;\nvar clearTimeout = global.clearTimeout;\nvar clearInterval = global.clearInterval;\n/* eslint-enable no-unused-vars, no-native-reassign */\n\n/**\n * Object#toString().\n */\n\nvar toString = Object.prototype.toString;\n\n/**\n * Expose `Runnable`.\n */\n\nmodule.exports = Runnable;\n\n/**\n * Initialize a new `Runnable` with the given `title` and callback `fn`.\n *\n * @param {String} title\n * @param {Function} fn\n * @api private\n * @param {string} title\n * @param {Function} fn\n */\nfunction Runnable(title, fn) {\n  this.title = title;\n  this.fn = fn;\n  this.body = (fn || '').toString();\n  this.async = fn && fn.length;\n  this.sync = !this.async;\n  this._timeout = 2000;\n  this._slow = 75;\n  this._enableTimeouts = true;\n  this.timedOut = false;\n  this._trace = new Error('done() called multiple times');\n  this._retries = -1;\n  this._currentRetry = 0;\n  this.pending = false;\n}\n\n/**\n * Inherit from `EventEmitter.prototype`.\n */\nRunnable.prototype = create(EventEmitter.prototype, {\n  constructor: Runnable\n});\n\n/**\n * Set & get timeout `ms`.\n *\n * @api private\n * @param {number|string} ms\n * @return {Runnable|number} ms or Runnable instance.\n */\nRunnable.prototype.timeout = function(ms) {\n  if (!arguments.length) {\n    return this._timeout;\n  }\n  // see #1652 for reasoning\n  if (ms === 0 || ms > Math.pow(2, 31)) {\n    this._enableTimeouts = false;\n  }\n  if (typeof ms === 'string') {\n    ms = milliseconds(ms);\n  }\n  debug('timeout %d', ms);\n  this._timeout = ms;\n  if (this.timer) {\n    this.resetTimeout();\n  }\n  return this;\n};\n\n/**\n * Set & get slow `ms`.\n *\n * @api private\n * @param {number|string} ms\n * @return {Runnable|number} ms or Runnable instance.\n */\nRunnable.prototype.slow = function(ms) {\n  if (typeof ms === 'undefined') {\n    return this._slow;\n  }\n  if (typeof ms === 'string') {\n    ms = milliseconds(ms);\n  }\n  debug('timeout %d', ms);\n  this._slow = ms;\n  return this;\n};\n\n/**\n * Set and get whether timeout is `enabled`.\n *\n * @api private\n * @param {boolean} enabled\n * @return {Runnable|boolean} enabled or Runnable instance.\n */\nRunnable.prototype.enableTimeouts = function(enabled) {\n  if (!arguments.length) {\n    return this._enableTimeouts;\n  }\n  debug('enableTimeouts %s', enabled);\n  this._enableTimeouts = enabled;\n  return this;\n};\n\n/**\n * Halt and mark as pending.\n *\n * @api public\n */\nRunnable.prototype.skip = function() {\n  throw new Pending('sync skip');\n};\n\n/**\n * Check if this runnable or its parent suite is marked as pending.\n *\n * @api private\n */\nRunnable.prototype.isPending = function() {\n  return this.pending || (this.parent && this.parent.isPending());\n};\n\n/**\n * Set number of retries.\n *\n * @api private\n */\nRunnable.prototype.retries = function(n) {\n  if (!arguments.length) {\n    return this._retries;\n  }\n  this._retries = n;\n};\n\n/**\n * Get current retry\n *\n * @api private\n */\nRunnable.prototype.currentRetry = function(n) {\n  if (!arguments.length) {\n    return this._currentRetry;\n  }\n  this._currentRetry = n;\n};\n\n/**\n * Return the full title generated by recursively concatenating the parent's\n * full title.\n *\n * @api public\n * @return {string}\n */\nRunnable.prototype.fullTitle = function() {\n  return this.parent.fullTitle() + ' ' + this.title;\n};\n\n/**\n * Clear the timeout.\n *\n * @api private\n */\nRunnable.prototype.clearTimeout = function() {\n  clearTimeout(this.timer);\n};\n\n/**\n * Inspect the runnable void of private properties.\n *\n * @api private\n * @return {string}\n */\nRunnable.prototype.inspect = function() {\n  return JSON.stringify(this, function(key, val) {\n    if (key[0] === '_') {\n      return;\n    }\n    if (key === 'parent') {\n      return '#<Suite>';\n    }\n    if (key === 'ctx') {\n      return '#<Context>';\n    }\n    return val;\n  }, 2);\n};\n\n/**\n * Reset the timeout.\n *\n * @api private\n */\nRunnable.prototype.resetTimeout = function() {\n  var self = this;\n  var ms = this.timeout() || 1e9;\n\n  if (!this._enableTimeouts) {\n    return;\n  }\n  this.clearTimeout();\n  this.timer = setTimeout(function() {\n    if (!self._enableTimeouts) {\n      return;\n    }\n    self.callback(new Error('timeout of ' + ms + 'ms exceeded. Ensure the done() callback is being called in this test.'));\n    self.timedOut = true;\n  }, ms);\n};\n\n/**\n * Whitelist a list of globals for this test run.\n *\n * @api private\n * @param {string[]} globals\n */\nRunnable.prototype.globals = function(globals) {\n  if (!arguments.length) {\n    return this._allowedGlobals;\n  }\n  this._allowedGlobals = globals;\n};\n\n/**\n * Run the test and invoke `fn(err)`.\n *\n * @param {Function} fn\n * @api private\n */\nRunnable.prototype.run = function(fn) {\n  var self = this;\n  var start = new Date();\n  var ctx = this.ctx;\n  var finished;\n  var emitted;\n\n  // Sometimes the ctx exists, but it is not runnable\n  if (ctx && ctx.runnable) {\n    ctx.runnable(this);\n  }\n\n  // called multiple times\n  function multiple(err) {\n    if (emitted) {\n      return;\n    }\n    emitted = true;\n    self.emit('error', err || new Error('done() called multiple times; stacktrace may be inaccurate'));\n  }\n\n  // finished\n  function done(err) {\n    var ms = self.timeout();\n    if (self.timedOut) {\n      return;\n    }\n    if (finished) {\n      return multiple(err || self._trace);\n    }\n\n    self.clearTimeout();\n    self.duration = new Date() - start;\n    finished = true;\n    if (!err && self.duration > ms && self._enableTimeouts) {\n      err = new Error('timeout of ' + ms + 'ms exceeded. Ensure the done() callback is being called in this test.');\n    }\n    fn(err);\n  }\n\n  // for .resetTimeout()\n  this.callback = done;\n\n  // explicit async with `done` argument\n  if (this.async) {\n    this.resetTimeout();\n\n    // allows skip() to be used in an explicit async context\n    this.skip = function asyncSkip() {\n      done(new Pending('async skip call'));\n      // halt execution.  the Runnable will be marked pending\n      // by the previous call, and the uncaught handler will ignore\n      // the failure.\n      throw new Pending('async skip; aborting execution');\n    };\n\n    if (this.allowUncaught) {\n      return callFnAsync(this.fn);\n    }\n    try {\n      callFnAsync(this.fn);\n    } catch (err) {\n      done(utils.getError(err));\n    }\n    return;\n  }\n\n  if (this.allowUncaught) {\n    callFn(this.fn);\n    done();\n    return;\n  }\n\n  // sync or promise-returning\n  try {\n    if (this.isPending()) {\n      done();\n    } else {\n      callFn(this.fn);\n    }\n  } catch (err) {\n    done(utils.getError(err));\n  }\n\n  function callFn(fn) {\n    var result = fn.call(ctx);\n    if (result && typeof result.then === 'function') {\n      self.resetTimeout();\n      result\n        .then(function() {\n          done();\n          // Return null so libraries like bluebird do not warn about\n          // subsequently constructed Promises.\n          return null;\n        },\n        function(reason) {\n          done(reason || new Error('Promise rejected with no or falsy reason'));\n        });\n    } else {\n      if (self.asyncOnly) {\n        return done(new Error('--async-only option in use without declaring `done()` or returning a promise'));\n      }\n\n      done();\n    }\n  }\n\n  function callFnAsync(fn) {\n    var result = fn.call(ctx, function(err) {\n      if (err instanceof Error || toString.call(err) === '[object Error]') {\n        return done(err);\n      }\n      if (err) {\n        if (Object.prototype.toString.call(err) === '[object Object]') {\n          return done(new Error('done() invoked with non-Error: '\n            + JSON.stringify(err)));\n        }\n        return done(new Error('done() invoked with non-Error: ' + err));\n      }\n      if (result && utils.isPromise(result)) {\n        return done(new Error('Resolution method is overspecified. Specify a callback *or* return a Promise; not both.'));\n      }\n\n      done();\n    });\n  }\n};\n\n}).call(this,typeof global !== \"undefined\" ? global : typeof self !== \"undefined\" ? self : typeof window !== \"undefined\" ? window : {})\n},{\"./ms\":15,\"./pending\":16,\"./utils\":38,\"debug\":2,\"events\":3,\"json3\":54,\"lodash.create\":60}],34:[function(require,module,exports){\n(function (process,global){\n/**\n * Module dependencies.\n */\n\nvar EventEmitter = require('events').EventEmitter;\nvar Pending = require('./pending');\nvar utils = require('./utils');\nvar inherits = utils.inherits;\nvar debug = require('debug')('mocha:runner');\nvar Runnable = require('./runnable');\nvar filter = utils.filter;\nvar indexOf = utils.indexOf;\nvar some = utils.some;\nvar keys = utils.keys;\nvar stackFilter = utils.stackTraceFilter();\nvar stringify = utils.stringify;\nvar type = utils.type;\nvar undefinedError = utils.undefinedError;\nvar isArray = utils.isArray;\n\n/**\n * Non-enumerable globals.\n */\n\nvar globals = [\n  'setTimeout',\n  'clearTimeout',\n  'setInterval',\n  'clearInterval',\n  'XMLHttpRequest',\n  'Date',\n  'setImmediate',\n  'clearImmediate'\n];\n\n/**\n * Expose `Runner`.\n */\n\nmodule.exports = Runner;\n\n/**\n * Initialize a `Runner` for the given `suite`.\n *\n * Events:\n *\n *   - `start`  execution started\n *   - `end`  execution complete\n *   - `suite`  (suite) test suite execution started\n *   - `suite end`  (suite) all tests (and sub-suites) have finished\n *   - `test`  (test) test execution started\n *   - `test end`  (test) test completed\n *   - `hook`  (hook) hook execution started\n *   - `hook end`  (hook) hook complete\n *   - `pass`  (test) test passed\n *   - `fail`  (test, err) test failed\n *   - `pending`  (test) test pending\n *\n * @api public\n * @param {Suite} suite Root suite\n * @param {boolean} [delay] Whether or not to delay execution of root suite\n * until ready.\n */\nfunction Runner(suite, delay) {\n  var self = this;\n  this._globals = [];\n  this._abort = false;\n  this._delay = delay;\n  this.suite = suite;\n  this.started = false;\n  this.total = suite.total();\n  this.failures = 0;\n  this.on('test end', function(test) {\n    self.checkGlobals(test);\n  });\n  this.on('hook end', function(hook) {\n    self.checkGlobals(hook);\n  });\n  this._defaultGrep = /.*/;\n  this.grep(this._defaultGrep);\n  this.globals(this.globalProps().concat(extraGlobals()));\n}\n\n/**\n * Wrapper for setImmediate, process.nextTick, or browser polyfill.\n *\n * @param {Function} fn\n * @api private\n */\nRunner.immediately = global.setImmediate || process.nextTick;\n\n/**\n * Inherit from `EventEmitter.prototype`.\n */\ninherits(Runner, EventEmitter);\n\n/**\n * Run tests with full titles matching `re`. Updates runner.total\n * with number of tests matched.\n *\n * @param {RegExp} re\n * @param {Boolean} invert\n * @return {Runner} for chaining\n * @api public\n * @param {RegExp} re\n * @param {boolean} invert\n * @return {Runner} Runner instance.\n */\nRunner.prototype.grep = function(re, invert) {\n  debug('grep %s', re);\n  this._grep = re;\n  this._invert = invert;\n  this.total = this.grepTotal(this.suite);\n  return this;\n};\n\n/**\n * Returns the number of tests matching the grep search for the\n * given suite.\n *\n * @param {Suite} suite\n * @return {Number}\n * @api public\n * @param {Suite} suite\n * @return {number}\n */\nRunner.prototype.grepTotal = function(suite) {\n  var self = this;\n  var total = 0;\n\n  suite.eachTest(function(test) {\n    var match = self._grep.test(test.fullTitle());\n    if (self._invert) {\n      match = !match;\n    }\n    if (match) {\n      total++;\n    }\n  });\n\n  return total;\n};\n\n/**\n * Return a list of global properties.\n *\n * @return {Array}\n * @api private\n */\nRunner.prototype.globalProps = function() {\n  var props = keys(global);\n\n  // non-enumerables\n  for (var i = 0; i < globals.length; ++i) {\n    if (~indexOf(props, globals[i])) {\n      continue;\n    }\n    props.push(globals[i]);\n  }\n\n  return props;\n};\n\n/**\n * Allow the given `arr` of globals.\n *\n * @param {Array} arr\n * @return {Runner} for chaining\n * @api public\n * @param {Array} arr\n * @return {Runner} Runner instance.\n */\nRunner.prototype.globals = function(arr) {\n  if (!arguments.length) {\n    return this._globals;\n  }\n  debug('globals %j', arr);\n  this._globals = this._globals.concat(arr);\n  return this;\n};\n\n/**\n * Check for global variable leaks.\n *\n * @api private\n */\nRunner.prototype.checkGlobals = function(test) {\n  if (this.ignoreLeaks) {\n    return;\n  }\n  var ok = this._globals;\n\n  var globals = this.globalProps();\n  var leaks;\n\n  if (test) {\n    ok = ok.concat(test._allowedGlobals || []);\n  }\n\n  if (this.prevGlobalsLength === globals.length) {\n    return;\n  }\n  this.prevGlobalsLength = globals.length;\n\n  leaks = filterLeaks(ok, globals);\n  this._globals = this._globals.concat(leaks);\n\n  if (leaks.length > 1) {\n    this.fail(test, new Error('global leaks detected: ' + leaks.join(', ') + ''));\n  } else if (leaks.length) {\n    this.fail(test, new Error('global leak detected: ' + leaks[0]));\n  }\n};\n\n/**\n * Fail the given `test`.\n *\n * @api private\n * @param {Test} test\n * @param {Error} err\n */\nRunner.prototype.fail = function(test, err) {\n  if (test.isPending()) {\n    return;\n  }\n\n  ++this.failures;\n  test.state = 'failed';\n\n  if (!(err instanceof Error || err && typeof err.message === 'string')) {\n    err = new Error('the ' + type(err) + ' ' + stringify(err) + ' was thrown, throw an Error :)');\n  }\n\n  err.stack = (this.fullStackTrace || !err.stack)\n    ? err.stack\n    : stackFilter(err.stack);\n\n  this.emit('fail', test, err);\n};\n\n/**\n * Fail the given `hook` with `err`.\n *\n * Hook failures work in the following pattern:\n * - If bail, then exit\n * - Failed `before` hook skips all tests in a suite and subsuites,\n *   but jumps to corresponding `after` hook\n * - Failed `before each` hook skips remaining tests in a\n *   suite and jumps to corresponding `after each` hook,\n *   which is run only once\n * - Failed `after` hook does not alter\n *   execution order\n * - Failed `after each` hook skips remaining tests in a\n *   suite and subsuites, but executes other `after each`\n *   hooks\n *\n * @api private\n * @param {Hook} hook\n * @param {Error} err\n */\nRunner.prototype.failHook = function(hook, err) {\n  if (hook.ctx && hook.ctx.currentTest) {\n    hook.originalTitle = hook.originalTitle || hook.title;\n    hook.title = hook.originalTitle + ' for \"' + hook.ctx.currentTest.title + '\"';\n  }\n\n  this.fail(hook, err);\n  if (this.suite.bail()) {\n    this.emit('end');\n  }\n};\n\n/**\n * Run hook `name` callbacks and then invoke `fn()`.\n *\n * @api private\n * @param {string} name\n * @param {Function} fn\n */\n\nRunner.prototype.hook = function(name, fn) {\n  var suite = this.suite;\n  var hooks = suite['_' + name];\n  var self = this;\n\n  function next(i) {\n    var hook = hooks[i];\n    if (!hook) {\n      return fn();\n    }\n    self.currentRunnable = hook;\n\n    hook.ctx.currentTest = self.test;\n\n    self.emit('hook', hook);\n\n    if (!hook.listeners('error').length) {\n      hook.on('error', function(err) {\n        self.failHook(hook, err);\n      });\n    }\n\n    hook.run(function(err) {\n      var testError = hook.error();\n      if (testError) {\n        self.fail(self.test, testError);\n      }\n      if (err) {\n        if (err instanceof Pending) {\n          if (name === 'beforeEach' || name === 'afterEach') {\n            self.test.pending = true;\n          } else {\n            utils.forEach(suite.tests, function(test) {\n              test.pending = true;\n            });\n            // a pending hook won't be executed twice.\n            hook.pending = true;\n          }\n        } else {\n          self.failHook(hook, err);\n\n          // stop executing hooks, notify callee of hook err\n          return fn(err);\n        }\n      }\n      self.emit('hook end', hook);\n      delete hook.ctx.currentTest;\n      next(++i);\n    });\n  }\n\n  Runner.immediately(function() {\n    next(0);\n  });\n};\n\n/**\n * Run hook `name` for the given array of `suites`\n * in order, and callback `fn(err, errSuite)`.\n *\n * @api private\n * @param {string} name\n * @param {Array} suites\n * @param {Function} fn\n */\nRunner.prototype.hooks = function(name, suites, fn) {\n  var self = this;\n  var orig = this.suite;\n\n  function next(suite) {\n    self.suite = suite;\n\n    if (!suite) {\n      self.suite = orig;\n      return fn();\n    }\n\n    self.hook(name, function(err) {\n      if (err) {\n        var errSuite = self.suite;\n        self.suite = orig;\n        return fn(err, errSuite);\n      }\n\n      next(suites.pop());\n    });\n  }\n\n  next(suites.pop());\n};\n\n/**\n * Run hooks from the top level down.\n *\n * @param {String} name\n * @param {Function} fn\n * @api private\n */\nRunner.prototype.hookUp = function(name, fn) {\n  var suites = [this.suite].concat(this.parents()).reverse();\n  this.hooks(name, suites, fn);\n};\n\n/**\n * Run hooks from the bottom up.\n *\n * @param {String} name\n * @param {Function} fn\n * @api private\n */\nRunner.prototype.hookDown = function(name, fn) {\n  var suites = [this.suite].concat(this.parents());\n  this.hooks(name, suites, fn);\n};\n\n/**\n * Return an array of parent Suites from\n * closest to furthest.\n *\n * @return {Array}\n * @api private\n */\nRunner.prototype.parents = function() {\n  var suite = this.suite;\n  var suites = [];\n  while (suite.parent) {\n    suite = suite.parent;\n    suites.push(suite);\n  }\n  return suites;\n};\n\n/**\n * Run the current test and callback `fn(err)`.\n *\n * @param {Function} fn\n * @api private\n */\nRunner.prototype.runTest = function(fn) {\n  var self = this;\n  var test = this.test;\n\n  if (!test) {\n    return;\n  }\n  if (this.asyncOnly) {\n    test.asyncOnly = true;\n  }\n\n  if (this.allowUncaught) {\n    test.allowUncaught = true;\n    return test.run(fn);\n  }\n  try {\n    test.on('error', function(err) {\n      self.fail(test, err);\n    });\n    test.run(fn);\n  } catch (err) {\n    fn(err);\n  }\n};\n\n/**\n * Run tests in the given `suite` and invoke the callback `fn()` when complete.\n *\n * @api private\n * @param {Suite} suite\n * @param {Function} fn\n */\nRunner.prototype.runTests = function(suite, fn) {\n  var self = this;\n  var tests = suite.tests.slice();\n  var test;\n\n  function hookErr(_, errSuite, after) {\n    // before/after Each hook for errSuite failed:\n    var orig = self.suite;\n\n    // for failed 'after each' hook start from errSuite parent,\n    // otherwise start from errSuite itself\n    self.suite = after ? errSuite.parent : errSuite;\n\n    if (self.suite) {\n      // call hookUp afterEach\n      self.hookUp('afterEach', function(err2, errSuite2) {\n        self.suite = orig;\n        // some hooks may fail even now\n        if (err2) {\n          return hookErr(err2, errSuite2, true);\n        }\n        // report error suite\n        fn(errSuite);\n      });\n    } else {\n      // there is no need calling other 'after each' hooks\n      self.suite = orig;\n      fn(errSuite);\n    }\n  }\n\n  function next(err, errSuite) {\n    // if we bail after first err\n    if (self.failures && suite._bail) {\n      return fn();\n    }\n\n    if (self._abort) {\n      return fn();\n    }\n\n    if (err) {\n      return hookErr(err, errSuite, true);\n    }\n\n    // next test\n    test = tests.shift();\n\n    // all done\n    if (!test) {\n      return fn();\n    }\n\n    // grep\n    var match = self._grep.test(test.fullTitle());\n    if (self._invert) {\n      match = !match;\n    }\n    if (!match) {\n      // Run immediately only if we have defined a grep. When we\n      // define a grep — It can cause maximum callstack error if\n      // the grep is doing a large recursive loop by neglecting\n      // all tests. The run immediately function also comes with\n      // a performance cost. So we don't want to run immediately\n      // if we run the whole test suite, because running the whole\n      // test suite don't do any immediate recursive loops. Thus,\n      // allowing a JS runtime to breathe.\n      if (self._grep !== self._defaultGrep) {\n        Runner.immediately(next);\n      } else {\n        next();\n      }\n      return;\n    }\n\n    if (test.isPending()) {\n      self.emit('pending', test);\n      self.emit('test end', test);\n      return next();\n    }\n\n    // execute test and hook(s)\n    self.emit('test', self.test = test);\n    self.hookDown('beforeEach', function(err, errSuite) {\n      if (test.isPending()) {\n        self.emit('pending', test);\n        self.emit('test end', test);\n        return next();\n      }\n      if (err) {\n        return hookErr(err, errSuite, false);\n      }\n      self.currentRunnable = self.test;\n      self.runTest(function(err) {\n        test = self.test;\n        if (err) {\n          var retry = test.currentRetry();\n          if (err instanceof Pending) {\n            test.pending = true;\n            self.emit('pending', test);\n          } else if (retry < test.retries()) {\n            var clonedTest = test.clone();\n            clonedTest.currentRetry(retry + 1);\n            tests.unshift(clonedTest);\n\n            // Early return + hook trigger so that it doesn't\n            // increment the count wrong\n            return self.hookUp('afterEach', next);\n          } else {\n            self.fail(test, err);\n          }\n          self.emit('test end', test);\n\n          if (err instanceof Pending) {\n            return next();\n          }\n\n          return self.hookUp('afterEach', next);\n        }\n\n        test.state = 'passed';\n        self.emit('pass', test);\n        self.emit('test end', test);\n        self.hookUp('afterEach', next);\n      });\n    });\n  }\n\n  this.next = next;\n  this.hookErr = hookErr;\n  next();\n};\n\n/**\n * Run the given `suite` and invoke the callback `fn()` when complete.\n *\n * @api private\n * @param {Suite} suite\n * @param {Function} fn\n */\nRunner.prototype.runSuite = function(suite, fn) {\n  var i = 0;\n  var self = this;\n  var total = this.grepTotal(suite);\n  var afterAllHookCalled = false;\n\n  debug('run suite %s', suite.fullTitle());\n\n  if (!total || (self.failures && suite._bail)) {\n    return fn();\n  }\n\n  this.emit('suite', this.suite = suite);\n\n  function next(errSuite) {\n    if (errSuite) {\n      // current suite failed on a hook from errSuite\n      if (errSuite === suite) {\n        // if errSuite is current suite\n        // continue to the next sibling suite\n        return done();\n      }\n      // errSuite is among the parents of current suite\n      // stop execution of errSuite and all sub-suites\n      return done(errSuite);\n    }\n\n    if (self._abort) {\n      return done();\n    }\n\n    var curr = suite.suites[i++];\n    if (!curr) {\n      return done();\n    }\n\n    // Avoid grep neglecting large number of tests causing a\n    // huge recursive loop and thus a maximum call stack error.\n    // See comment in `this.runTests()` for more information.\n    if (self._grep !== self._defaultGrep) {\n      Runner.immediately(function() {\n        self.runSuite(curr, next);\n      });\n    } else {\n      self.runSuite(curr, next);\n    }\n  }\n\n  function done(errSuite) {\n    self.suite = suite;\n    self.nextSuite = next;\n\n    if (afterAllHookCalled) {\n      fn(errSuite);\n    } else {\n      // mark that the afterAll block has been called once\n      // and so can be skipped if there is an error in it.\n      afterAllHookCalled = true;\n\n      // remove reference to test\n      delete self.test;\n\n      self.hook('afterAll', function() {\n        self.emit('suite end', suite);\n        fn(errSuite);\n      });\n    }\n  }\n\n  this.nextSuite = next;\n\n  this.hook('beforeAll', function(err) {\n    if (err) {\n      return done();\n    }\n    self.runTests(suite, next);\n  });\n};\n\n/**\n * Handle uncaught exceptions.\n *\n * @param {Error} err\n * @api private\n */\nRunner.prototype.uncaught = function(err) {\n  if (err) {\n    debug('uncaught exception %s', err !== function() {\n      return this;\n    }.call(err) ? err : (err.message || err));\n  } else {\n    debug('uncaught undefined exception');\n    err = undefinedError();\n  }\n  err.uncaught = true;\n\n  var runnable = this.currentRunnable;\n\n  if (!runnable) {\n    runnable = new Runnable('Uncaught error outside test suite');\n    runnable.parent = this.suite;\n\n    if (this.started) {\n      this.fail(runnable, err);\n    } else {\n      // Can't recover from this failure\n      this.emit('start');\n      this.fail(runnable, err);\n      this.emit('end');\n    }\n\n    return;\n  }\n\n  runnable.clearTimeout();\n\n  // Ignore errors if complete or pending\n  if (runnable.state || runnable.isPending()) {\n    return;\n  }\n  this.fail(runnable, err);\n\n  // recover from test\n  if (runnable.type === 'test') {\n    this.emit('test end', runnable);\n    this.hookUp('afterEach', this.next);\n    return;\n  }\n\n // recover from hooks\n  if (runnable.type === 'hook') {\n    var errSuite = this.suite;\n    // if hook failure is in afterEach block\n    if (runnable.fullTitle().indexOf('after each') > -1) {\n      return this.hookErr(err, errSuite, true);\n    }\n    // if hook failure is in beforeEach block\n    if (runnable.fullTitle().indexOf('before each') > -1) {\n      return this.hookErr(err, errSuite, false);\n    }\n    // if hook failure is in after or before blocks\n    return this.nextSuite(errSuite);\n  }\n\n  // bail\n  this.emit('end');\n};\n\n/**\n * Cleans up the references to all the deferred functions\n * (before/after/beforeEach/afterEach) and tests of a Suite.\n * These must be deleted otherwise a memory leak can happen,\n * as those functions may reference variables from closures,\n * thus those variables can never be garbage collected as long\n * as the deferred functions exist.\n *\n * @param {Suite} suite\n */\nfunction cleanSuiteReferences(suite) {\n  function cleanArrReferences(arr) {\n    for (var i = 0; i < arr.length; i++) {\n      delete arr[i].fn;\n    }\n  }\n\n  if (isArray(suite._beforeAll)) {\n    cleanArrReferences(suite._beforeAll);\n  }\n\n  if (isArray(suite._beforeEach)) {\n    cleanArrReferences(suite._beforeEach);\n  }\n\n  if (isArray(suite._afterAll)) {\n    cleanArrReferences(suite._afterAll);\n  }\n\n  if (isArray(suite._afterEach)) {\n    cleanArrReferences(suite._afterEach);\n  }\n\n  for (var i = 0; i < suite.tests.length; i++) {\n    delete suite.tests[i].fn;\n  }\n}\n\n/**\n * Run the root suite and invoke `fn(failures)`\n * on completion.\n *\n * @param {Function} fn\n * @return {Runner} for chaining\n * @api public\n * @param {Function} fn\n * @return {Runner} Runner instance.\n */\nRunner.prototype.run = function(fn) {\n  var self = this;\n  var rootSuite = this.suite;\n\n  // If there is an `only` filter\n  if (this.hasOnly) {\n    filterOnly(rootSuite);\n  }\n\n  fn = fn || function() {};\n\n  function uncaught(err) {\n    self.uncaught(err);\n  }\n\n  function start() {\n    self.started = true;\n    self.emit('start');\n    self.runSuite(rootSuite, function() {\n      debug('finished running');\n      self.emit('end');\n    });\n  }\n\n  debug('start');\n\n  // references cleanup to avoid memory leaks\n  this.on('suite end', cleanSuiteReferences);\n\n  // callback\n  this.on('end', function() {\n    debug('end');\n    process.removeListener('uncaughtException', uncaught);\n    fn(self.failures);\n  });\n\n  // uncaught exception\n  process.on('uncaughtException', uncaught);\n\n  if (this._delay) {\n    // for reporters, I guess.\n    // might be nice to debounce some dots while we wait.\n    this.emit('waiting', rootSuite);\n    rootSuite.once('run', start);\n  } else {\n    start();\n  }\n\n  return this;\n};\n\n/**\n * Cleanly abort execution.\n *\n * @api public\n * @return {Runner} Runner instance.\n */\nRunner.prototype.abort = function() {\n  debug('aborting');\n  this._abort = true;\n\n  return this;\n};\n\n/**\n * Filter suites based on `isOnly` logic.\n *\n * @param {Array} suite\n * @returns {Boolean}\n * @api private\n */\nfunction filterOnly(suite) {\n  if (suite._onlyTests.length) {\n    // If the suite contains `only` tests, run those and ignore any nested suites.\n    suite.tests = suite._onlyTests;\n    suite.suites = [];\n  } else {\n    // Otherwise, do not run any of the tests in this suite.\n    suite.tests = [];\n    utils.forEach(suite._onlySuites, function(onlySuite) {\n      // If there are other `only` tests/suites nested in the current `only` suite, then filter that `only` suite.\n      // Otherwise, all of the tests on this `only` suite should be run, so don't filter it.\n      if (hasOnly(onlySuite)) {\n        filterOnly(onlySuite);\n      }\n    });\n    // Run the `only` suites, as well as any other suites that have `only` tests/suites as descendants.\n    suite.suites = filter(suite.suites, function(childSuite) {\n      return indexOf(suite._onlySuites, childSuite) !== -1 || filterOnly(childSuite);\n    });\n  }\n  // Keep the suite only if there is something to run\n  return suite.tests.length || suite.suites.length;\n}\n\n/**\n * Determines whether a suite has an `only` test or suite as a descendant.\n *\n * @param {Array} suite\n * @returns {Boolean}\n * @api private\n */\nfunction hasOnly(suite) {\n  return suite._onlyTests.length || suite._onlySuites.length || some(suite.suites, hasOnly);\n}\n\n/**\n * Filter leaks with the given globals flagged as `ok`.\n *\n * @api private\n * @param {Array} ok\n * @param {Array} globals\n * @return {Array}\n */\nfunction filterLeaks(ok, globals) {\n  return filter(globals, function(key) {\n    // Firefox and Chrome exposes iframes as index inside the window object\n    if (/^\\d+/.test(key)) {\n      return false;\n    }\n\n    // in firefox\n    // if runner runs in an iframe, this iframe's window.getInterface method\n    // not init at first it is assigned in some seconds\n    if (global.navigator && (/^getInterface/).test(key)) {\n      return false;\n    }\n\n    // an iframe could be approached by window[iframeIndex]\n    // in ie6,7,8 and opera, iframeIndex is enumerable, this could cause leak\n    if (global.navigator && (/^\\d+/).test(key)) {\n      return false;\n    }\n\n    // Opera and IE expose global variables for HTML element IDs (issue #243)\n    if (/^mocha-/.test(key)) {\n      return false;\n    }\n\n    var matched = filter(ok, function(ok) {\n      if (~ok.indexOf('*')) {\n        return key.indexOf(ok.split('*')[0]) === 0;\n      }\n      return key === ok;\n    });\n    return !matched.length && (!global.navigator || key !== 'onerror');\n  });\n}\n\n/**\n * Array of globals dependent on the environment.\n *\n * @return {Array}\n * @api private\n */\nfunction extraGlobals() {\n  if (typeof process === 'object' && typeof process.version === 'string') {\n    var parts = process.version.split('.');\n    var nodeVersion = utils.reduce(parts, function(a, v) {\n      return a << 8 | v;\n    });\n\n    // 'errno' was renamed to process._errno in v0.9.11.\n\n    if (nodeVersion < 0x00090B) {\n      return ['errno'];\n    }\n  }\n\n  return [];\n}\n\n}).call(this,require('_process'),typeof global !== \"undefined\" ? global : typeof self !== \"undefined\" ? self : typeof window !== \"undefined\" ? window : {})\n},{\"./pending\":16,\"./runnable\":33,\"./utils\":38,\"_process\":67,\"debug\":2,\"events\":3}],35:[function(require,module,exports){\n/**\n * Module dependencies.\n */\n\nvar EventEmitter = require('events').EventEmitter;\nvar Hook = require('./hook');\nvar utils = require('./utils');\nvar inherits = utils.inherits;\nvar debug = require('debug')('mocha:suite');\nvar milliseconds = require('./ms');\n\n/**\n * Expose `Suite`.\n */\n\nexports = module.exports = Suite;\n\n/**\n * Create a new `Suite` with the given `title` and parent `Suite`. When a suite\n * with the same title is already present, that suite is returned to provide\n * nicer reporter and more flexible meta-testing.\n *\n * @api public\n * @param {Suite} parent\n * @param {string} title\n * @return {Suite}\n */\nexports.create = function(parent, title) {\n  var suite = new Suite(title, parent.ctx);\n  suite.parent = parent;\n  title = suite.fullTitle();\n  parent.addSuite(suite);\n  return suite;\n};\n\n/**\n * Initialize a new `Suite` with the given `title` and `ctx`.\n *\n * @api private\n * @param {string} title\n * @param {Context} parentContext\n */\nfunction Suite(title, parentContext) {\n  if (!utils.isString(title)) {\n    throw new Error('Suite `title` should be a \"string\" but \"' + typeof title + '\" was given instead.');\n  }\n  this.title = title;\n  function Context() {}\n  Context.prototype = parentContext;\n  this.ctx = new Context();\n  this.suites = [];\n  this.tests = [];\n  this.pending = false;\n  this._beforeEach = [];\n  this._beforeAll = [];\n  this._afterEach = [];\n  this._afterAll = [];\n  this.root = !title;\n  this._timeout = 2000;\n  this._enableTimeouts = true;\n  this._slow = 75;\n  this._bail = false;\n  this._retries = -1;\n  this._onlyTests = [];\n  this._onlySuites = [];\n  this.delayed = false;\n}\n\n/**\n * Inherit from `EventEmitter.prototype`.\n */\ninherits(Suite, EventEmitter);\n\n/**\n * Return a clone of this `Suite`.\n *\n * @api private\n * @return {Suite}\n */\nSuite.prototype.clone = function() {\n  var suite = new Suite(this.title);\n  debug('clone');\n  suite.ctx = this.ctx;\n  suite.timeout(this.timeout());\n  suite.retries(this.retries());\n  suite.enableTimeouts(this.enableTimeouts());\n  suite.slow(this.slow());\n  suite.bail(this.bail());\n  return suite;\n};\n\n/**\n * Set timeout `ms` or short-hand such as \"2s\".\n *\n * @api private\n * @param {number|string} ms\n * @return {Suite|number} for chaining\n */\nSuite.prototype.timeout = function(ms) {\n  if (!arguments.length) {\n    return this._timeout;\n  }\n  if (ms.toString() === '0') {\n    this._enableTimeouts = false;\n  }\n  if (typeof ms === 'string') {\n    ms = milliseconds(ms);\n  }\n  debug('timeout %d', ms);\n  this._timeout = parseInt(ms, 10);\n  return this;\n};\n\n/**\n * Set number of times to retry a failed test.\n *\n * @api private\n * @param {number|string} n\n * @return {Suite|number} for chaining\n */\nSuite.prototype.retries = function(n) {\n  if (!arguments.length) {\n    return this._retries;\n  }\n  debug('retries %d', n);\n  this._retries = parseInt(n, 10) || 0;\n  return this;\n};\n\n/**\n  * Set timeout to `enabled`.\n  *\n  * @api private\n  * @param {boolean} enabled\n  * @return {Suite|boolean} self or enabled\n  */\nSuite.prototype.enableTimeouts = function(enabled) {\n  if (!arguments.length) {\n    return this._enableTimeouts;\n  }\n  debug('enableTimeouts %s', enabled);\n  this._enableTimeouts = enabled;\n  return this;\n};\n\n/**\n * Set slow `ms` or short-hand such as \"2s\".\n *\n * @api private\n * @param {number|string} ms\n * @return {Suite|number} for chaining\n */\nSuite.prototype.slow = function(ms) {\n  if (!arguments.length) {\n    return this._slow;\n  }\n  if (typeof ms === 'string') {\n    ms = milliseconds(ms);\n  }\n  debug('slow %d', ms);\n  this._slow = ms;\n  return this;\n};\n\n/**\n * Sets whether to bail after first error.\n *\n * @api private\n * @param {boolean} bail\n * @return {Suite|number} for chaining\n */\nSuite.prototype.bail = function(bail) {\n  if (!arguments.length) {\n    return this._bail;\n  }\n  debug('bail %s', bail);\n  this._bail = bail;\n  return this;\n};\n\n/**\n * Check if this suite or its parent suite is marked as pending.\n *\n * @api private\n */\nSuite.prototype.isPending = function() {\n  return this.pending || (this.parent && this.parent.isPending());\n};\n\n/**\n * Run `fn(test[, done])` before running tests.\n *\n * @api private\n * @param {string} title\n * @param {Function} fn\n * @return {Suite} for chaining\n */\nSuite.prototype.beforeAll = function(title, fn) {\n  if (this.isPending()) {\n    return this;\n  }\n  if (typeof title === 'function') {\n    fn = title;\n    title = fn.name;\n  }\n  title = '\"before all\" hook' + (title ? ': ' + title : '');\n\n  var hook = new Hook(title, fn);\n  hook.parent = this;\n  hook.timeout(this.timeout());\n  hook.retries(this.retries());\n  hook.enableTimeouts(this.enableTimeouts());\n  hook.slow(this.slow());\n  hook.ctx = this.ctx;\n  this._beforeAll.push(hook);\n  this.emit('beforeAll', hook);\n  return this;\n};\n\n/**\n * Run `fn(test[, done])` after running tests.\n *\n * @api private\n * @param {string} title\n * @param {Function} fn\n * @return {Suite} for chaining\n */\nSuite.prototype.afterAll = function(title, fn) {\n  if (this.isPending()) {\n    return this;\n  }\n  if (typeof title === 'function') {\n    fn = title;\n    title = fn.name;\n  }\n  title = '\"after all\" hook' + (title ? ': ' + title : '');\n\n  var hook = new Hook(title, fn);\n  hook.parent = this;\n  hook.timeout(this.timeout());\n  hook.retries(this.retries());\n  hook.enableTimeouts(this.enableTimeouts());\n  hook.slow(this.slow());\n  hook.ctx = this.ctx;\n  this._afterAll.push(hook);\n  this.emit('afterAll', hook);\n  return this;\n};\n\n/**\n * Run `fn(test[, done])` before each test case.\n *\n * @api private\n * @param {string} title\n * @param {Function} fn\n * @return {Suite} for chaining\n */\nSuite.prototype.beforeEach = function(title, fn) {\n  if (this.isPending()) {\n    return this;\n  }\n  if (typeof title === 'function') {\n    fn = title;\n    title = fn.name;\n  }\n  title = '\"before each\" hook' + (title ? ': ' + title : '');\n\n  var hook = new Hook(title, fn);\n  hook.parent = this;\n  hook.timeout(this.timeout());\n  hook.retries(this.retries());\n  hook.enableTimeouts(this.enableTimeouts());\n  hook.slow(this.slow());\n  hook.ctx = this.ctx;\n  this._beforeEach.push(hook);\n  this.emit('beforeEach', hook);\n  return this;\n};\n\n/**\n * Run `fn(test[, done])` after each test case.\n *\n * @api private\n * @param {string} title\n * @param {Function} fn\n * @return {Suite} for chaining\n */\nSuite.prototype.afterEach = function(title, fn) {\n  if (this.isPending()) {\n    return this;\n  }\n  if (typeof title === 'function') {\n    fn = title;\n    title = fn.name;\n  }\n  title = '\"after each\" hook' + (title ? ': ' + title : '');\n\n  var hook = new Hook(title, fn);\n  hook.parent = this;\n  hook.timeout(this.timeout());\n  hook.retries(this.retries());\n  hook.enableTimeouts(this.enableTimeouts());\n  hook.slow(this.slow());\n  hook.ctx = this.ctx;\n  this._afterEach.push(hook);\n  this.emit('afterEach', hook);\n  return this;\n};\n\n/**\n * Add a test `suite`.\n *\n * @api private\n * @param {Suite} suite\n * @return {Suite} for chaining\n */\nSuite.prototype.addSuite = function(suite) {\n  suite.parent = this;\n  suite.timeout(this.timeout());\n  suite.retries(this.retries());\n  suite.enableTimeouts(this.enableTimeouts());\n  suite.slow(this.slow());\n  suite.bail(this.bail());\n  this.suites.push(suite);\n  this.emit('suite', suite);\n  return this;\n};\n\n/**\n * Add a `test` to this suite.\n *\n * @api private\n * @param {Test} test\n * @return {Suite} for chaining\n */\nSuite.prototype.addTest = function(test) {\n  test.parent = this;\n  test.timeout(this.timeout());\n  test.retries(this.retries());\n  test.enableTimeouts(this.enableTimeouts());\n  test.slow(this.slow());\n  test.ctx = this.ctx;\n  this.tests.push(test);\n  this.emit('test', test);\n  return this;\n};\n\n/**\n * Return the full title generated by recursively concatenating the parent's\n * full title.\n *\n * @api public\n * @return {string}\n */\nSuite.prototype.fullTitle = function() {\n  if (this.parent) {\n    var full = this.parent.fullTitle();\n    if (full) {\n      return full + ' ' + this.title;\n    }\n  }\n  return this.title;\n};\n\n/**\n * Return the total number of tests.\n *\n * @api public\n * @return {number}\n */\nSuite.prototype.total = function() {\n  return utils.reduce(this.suites, function(sum, suite) {\n    return sum + suite.total();\n  }, 0) + this.tests.length;\n};\n\n/**\n * Iterates through each suite recursively to find all tests. Applies a\n * function in the format `fn(test)`.\n *\n * @api private\n * @param {Function} fn\n * @return {Suite}\n */\nSuite.prototype.eachTest = function(fn) {\n  utils.forEach(this.tests, fn);\n  utils.forEach(this.suites, function(suite) {\n    suite.eachTest(fn);\n  });\n  return this;\n};\n\n/**\n * This will run the root suite if we happen to be running in delayed mode.\n */\nSuite.prototype.run = function run() {\n  if (this.root) {\n    this.emit('run');\n  }\n};\n\n},{\"./hook\":7,\"./ms\":15,\"./utils\":38,\"debug\":2,\"events\":3}],36:[function(require,module,exports){\n/**\n * Module dependencies.\n */\n\nvar Runnable = require('./runnable');\nvar create = require('lodash.create');\nvar isString = require('./utils').isString;\n\n/**\n * Expose `Test`.\n */\n\nmodule.exports = Test;\n\n/**\n * Initialize a new `Test` with the given `title` and callback `fn`.\n *\n * @api private\n * @param {String} title\n * @param {Function} fn\n */\nfunction Test(title, fn) {\n  if (!isString(title)) {\n    throw new Error('Test `title` should be a \"string\" but \"' + typeof title + '\" was given instead.');\n  }\n  Runnable.call(this, title, fn);\n  this.pending = !fn;\n  this.type = 'test';\n}\n\n/**\n * Inherit from `Runnable.prototype`.\n */\nTest.prototype = create(Runnable.prototype, {\n  constructor: Test\n});\n\nTest.prototype.clone = function() {\n  var test = new Test(this.title, this.fn);\n  test.timeout(this.timeout());\n  test.slow(this.slow());\n  test.enableTimeouts(this.enableTimeouts());\n  test.retries(this.retries());\n  test.currentRetry(this.currentRetry());\n  test.globals(this.globals());\n  test.parent = this.parent;\n  test.file = this.file;\n  test.ctx = this.ctx;\n  return test;\n};\n\n},{\"./runnable\":33,\"./utils\":38,\"lodash.create\":60}],37:[function(require,module,exports){\n'use strict';\n\n/**\n * Pad a `number` with a ten's place zero.\n *\n * @param {number} number\n * @return {string}\n */\nfunction pad(number) {\n  var n = number.toString();\n  return n.length === 1 ? '0' + n : n;\n}\n\n/**\n * Turn a `date` into an ISO string.\n *\n * https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/toISOString\n *\n * @param {Date} date\n * @return {string}\n */\nfunction toISOString(date) {\n  return date.getUTCFullYear()\n    + '-' + pad(date.getUTCMonth() + 1)\n    + '-' + pad(date.getUTCDate())\n    + 'T' + pad(date.getUTCHours())\n    + ':' + pad(date.getUTCMinutes())\n    + ':' + pad(date.getUTCSeconds())\n    + '.' + String((date.getUTCMilliseconds()/1000).toFixed(3)).slice(2, 5)\n    + 'Z';\n}\n\n/*\n * Exports.\n */\n\nmodule.exports = toISOString;\n\n},{}],38:[function(require,module,exports){\n(function (process,Buffer){\n/* eslint-env browser */\n\n/**\n * Module dependencies.\n */\n\nvar JSON = require('json3');\nvar basename = require('path').basename;\nvar debug = require('debug')('mocha:watch');\nvar exists = require('fs').existsSync || require('path').existsSync;\nvar glob = require('glob');\nvar path = require('path');\nvar join = path.join;\nvar readdirSync = require('fs').readdirSync;\nvar statSync = require('fs').statSync;\nvar watchFile = require('fs').watchFile;\nvar toISOString = require('./to-iso-string');\n\n/**\n * Ignored directories.\n */\n\nvar ignore = ['node_modules', '.git'];\n\nexports.inherits = require('util').inherits;\n\n/**\n * Escape special characters in the given string of html.\n *\n * @api private\n * @param  {string} html\n * @return {string}\n */\nexports.escape = function(html) {\n  return String(html)\n    .replace(/&/g, '&amp;')\n    .replace(/\"/g, '&quot;')\n    .replace(/</g, '&lt;')\n    .replace(/>/g, '&gt;');\n};\n\n/**\n * Array#forEach (<=IE8)\n *\n * @api private\n * @param {Array} arr\n * @param {Function} fn\n * @param {Object} scope\n */\nexports.forEach = function(arr, fn, scope) {\n  for (var i = 0, l = arr.length; i < l; i++) {\n    fn.call(scope, arr[i], i);\n  }\n};\n\n/**\n * Test if the given obj is type of string.\n *\n * @api private\n * @param {Object} obj\n * @return {boolean}\n */\nexports.isString = function(obj) {\n  return typeof obj === 'string';\n};\n\n/**\n * Array#map (<=IE8)\n *\n * @api private\n * @param {Array} arr\n * @param {Function} fn\n * @param {Object} scope\n * @return {Array}\n */\nexports.map = function(arr, fn, scope) {\n  var result = [];\n  for (var i = 0, l = arr.length; i < l; i++) {\n    result.push(fn.call(scope, arr[i], i, arr));\n  }\n  return result;\n};\n\n/**\n * Array#indexOf (<=IE8)\n *\n * @api private\n * @param {Array} arr\n * @param {Object} obj to find index of\n * @param {number} start\n * @return {number}\n */\nvar indexOf = exports.indexOf = function(arr, obj, start) {\n  for (var i = start || 0, l = arr.length; i < l; i++) {\n    if (arr[i] === obj) {\n      return i;\n    }\n  }\n  return -1;\n};\n\n/**\n * Array#reduce (<=IE8)\n *\n * @api private\n * @param {Array} arr\n * @param {Function} fn\n * @param {Object} val Initial value.\n * @return {*}\n */\nvar reduce = exports.reduce = function(arr, fn, val) {\n  var rval = val;\n\n  for (var i = 0, l = arr.length; i < l; i++) {\n    rval = fn(rval, arr[i], i, arr);\n  }\n\n  return rval;\n};\n\n/**\n * Array#filter (<=IE8)\n *\n * @api private\n * @param {Array} arr\n * @param {Function} fn\n * @return {Array}\n */\nexports.filter = function(arr, fn) {\n  var ret = [];\n\n  for (var i = 0, l = arr.length; i < l; i++) {\n    var val = arr[i];\n    if (fn(val, i, arr)) {\n      ret.push(val);\n    }\n  }\n\n  return ret;\n};\n\n/**\n * Array#some (<=IE8)\n *\n * @api private\n * @param {Array} arr\n * @param {Function} fn\n * @return {Array}\n */\nexports.some = function(arr, fn) {\n  for (var i = 0, l = arr.length; i < l; i++) {\n    if (fn(arr[i])) {\n      return true;\n    }\n  }\n  return false;\n};\n\n/**\n * Object.keys (<=IE8)\n *\n * @api private\n * @param {Object} obj\n * @return {Array} keys\n */\nexports.keys = typeof Object.keys === 'function' ? Object.keys : function(obj) {\n  var keys = [];\n  var has = Object.prototype.hasOwnProperty; // for `window` on <=IE8\n\n  for (var key in obj) {\n    if (has.call(obj, key)) {\n      keys.push(key);\n    }\n  }\n\n  return keys;\n};\n\n/**\n * Watch the given `files` for changes\n * and invoke `fn(file)` on modification.\n *\n * @api private\n * @param {Array} files\n * @param {Function} fn\n */\nexports.watch = function(files, fn) {\n  var options = { interval: 100 };\n  files.forEach(function(file) {\n    debug('file %s', file);\n    watchFile(file, options, function(curr, prev) {\n      if (prev.mtime < curr.mtime) {\n        fn(file);\n      }\n    });\n  });\n};\n\n/**\n * Array.isArray (<=IE8)\n *\n * @api private\n * @param {Object} obj\n * @return {Boolean}\n */\nvar isArray = typeof Array.isArray === 'function' ? Array.isArray : function(obj) {\n  return Object.prototype.toString.call(obj) === '[object Array]';\n};\n\nexports.isArray = isArray;\n\n/**\n * Buffer.prototype.toJSON polyfill.\n *\n * @type {Function}\n */\nif (typeof Buffer !== 'undefined' && Buffer.prototype) {\n  Buffer.prototype.toJSON = Buffer.prototype.toJSON || function() {\n    return Array.prototype.slice.call(this, 0);\n  };\n}\n\n/**\n * Ignored files.\n *\n * @api private\n * @param {string} path\n * @return {boolean}\n */\nfunction ignored(path) {\n  return !~ignore.indexOf(path);\n}\n\n/**\n * Lookup files in the given `dir`.\n *\n * @api private\n * @param {string} dir\n * @param {string[]} [ext=['.js']]\n * @param {Array} [ret=[]]\n * @return {Array}\n */\nexports.files = function(dir, ext, ret) {\n  ret = ret || [];\n  ext = ext || ['js'];\n\n  var re = new RegExp('\\\\.(' + ext.join('|') + ')$');\n\n  readdirSync(dir)\n    .filter(ignored)\n    .forEach(function(path) {\n      path = join(dir, path);\n      if (statSync(path).isDirectory()) {\n        exports.files(path, ext, ret);\n      } else if (path.match(re)) {\n        ret.push(path);\n      }\n    });\n\n  return ret;\n};\n\n/**\n * Compute a slug from the given `str`.\n *\n * @api private\n * @param {string} str\n * @return {string}\n */\nexports.slug = function(str) {\n  return str\n    .toLowerCase()\n    .replace(/ +/g, '-')\n    .replace(/[^-\\w]/g, '');\n};\n\n/**\n * Strip the function definition from `str`, and re-indent for pre whitespace.\n *\n * @param {string} str\n * @return {string}\n */\nexports.clean = function(str) {\n  str = str\n    .replace(/\\r\\n?|[\\n\\u2028\\u2029]/g, '\\n').replace(/^\\uFEFF/, '')\n    // (traditional)->  space/name     parameters    body     (lambda)-> parameters       body   multi-statement/single          keep body content\n    .replace(/^function(?:\\s*|\\s+[^(]*)\\([^)]*\\)\\s*\\{((?:.|\\n)*?)\\s*\\}$|^\\([^)]*\\)\\s*=>\\s*(?:\\{((?:.|\\n)*?)\\s*\\}|((?:.|\\n)*))$/, '$1$2$3');\n\n  var spaces = str.match(/^\\n?( *)/)[1].length;\n  var tabs = str.match(/^\\n?(\\t*)/)[1].length;\n  var re = new RegExp('^\\n?' + (tabs ? '\\t' : ' ') + '{' + (tabs ? tabs : spaces) + '}', 'gm');\n\n  str = str.replace(re, '');\n\n  return exports.trim(str);\n};\n\n/**\n * Trim the given `str`.\n *\n * @api private\n * @param {string} str\n * @return {string}\n */\nexports.trim = function(str) {\n  return str.replace(/^\\s+|\\s+$/g, '');\n};\n\n/**\n * Parse the given `qs`.\n *\n * @api private\n * @param {string} qs\n * @return {Object}\n */\nexports.parseQuery = function(qs) {\n  return reduce(qs.replace('?', '').split('&'), function(obj, pair) {\n    var i = pair.indexOf('=');\n    var key = pair.slice(0, i);\n    var val = pair.slice(++i);\n\n    obj[key] = decodeURIComponent(val);\n    return obj;\n  }, {});\n};\n\n/**\n * Highlight the given string of `js`.\n *\n * @api private\n * @param {string} js\n * @return {string}\n */\nfunction highlight(js) {\n  return js\n    .replace(/</g, '&lt;')\n    .replace(/>/g, '&gt;')\n    .replace(/\\/\\/(.*)/gm, '<span class=\"comment\">//$1</span>')\n    .replace(/('.*?')/gm, '<span class=\"string\">$1</span>')\n    .replace(/(\\d+\\.\\d+)/gm, '<span class=\"number\">$1</span>')\n    .replace(/(\\d+)/gm, '<span class=\"number\">$1</span>')\n    .replace(/\\bnew[ \\t]+(\\w+)/gm, '<span class=\"keyword\">new</span> <span class=\"init\">$1</span>')\n    .replace(/\\b(function|new|throw|return|var|if|else)\\b/gm, '<span class=\"keyword\">$1</span>');\n}\n\n/**\n * Highlight the contents of tag `name`.\n *\n * @api private\n * @param {string} name\n */\nexports.highlightTags = function(name) {\n  var code = document.getElementById('mocha').getElementsByTagName(name);\n  for (var i = 0, len = code.length; i < len; ++i) {\n    code[i].innerHTML = highlight(code[i].innerHTML);\n  }\n};\n\n/**\n * If a value could have properties, and has none, this function is called,\n * which returns a string representation of the empty value.\n *\n * Functions w/ no properties return `'[Function]'`\n * Arrays w/ length === 0 return `'[]'`\n * Objects w/ no properties return `'{}'`\n * All else: return result of `value.toString()`\n *\n * @api private\n * @param {*} value The value to inspect.\n * @param {string} typeHint The type of the value\n * @returns {string}\n */\nfunction emptyRepresentation(value, typeHint) {\n  switch (typeHint) {\n    case 'function':\n      return '[Function]';\n    case 'object':\n      return '{}';\n    case 'array':\n      return '[]';\n    default:\n      return value.toString();\n  }\n}\n\n/**\n * Takes some variable and asks `Object.prototype.toString()` what it thinks it\n * is.\n *\n * @api private\n * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/toString\n * @param {*} value The value to test.\n * @returns {string} Computed type\n * @example\n * type({}) // 'object'\n * type([]) // 'array'\n * type(1) // 'number'\n * type(false) // 'boolean'\n * type(Infinity) // 'number'\n * type(null) // 'null'\n * type(new Date()) // 'date'\n * type(/foo/) // 'regexp'\n * type('type') // 'string'\n * type(global) // 'global'\n * type(new String('foo') // 'object'\n */\nvar type = exports.type = function type(value) {\n  if (value === undefined) {\n    return 'undefined';\n  } else if (value === null) {\n    return 'null';\n  } else if (typeof Buffer !== 'undefined' && Buffer.isBuffer(value)) {\n    return 'buffer';\n  }\n  return Object.prototype.toString.call(value)\n    .replace(/^\\[.+\\s(.+?)\\]$/, '$1')\n    .toLowerCase();\n};\n\n/**\n * Stringify `value`. Different behavior depending on type of value:\n *\n * - If `value` is undefined or null, return `'[undefined]'` or `'[null]'`, respectively.\n * - If `value` is not an object, function or array, return result of `value.toString()` wrapped in double-quotes.\n * - If `value` is an *empty* object, function, or array, return result of function\n *   {@link emptyRepresentation}.\n * - If `value` has properties, call {@link exports.canonicalize} on it, then return result of\n *   JSON.stringify().\n *\n * @api private\n * @see exports.type\n * @param {*} value\n * @return {string}\n */\nexports.stringify = function(value) {\n  var typeHint = type(value);\n\n  if (!~indexOf(['object', 'array', 'function'], typeHint)) {\n    if (typeHint === 'buffer') {\n      var json = value.toJSON();\n      // Based on the toJSON result\n      return jsonStringify(json.data && json.type ? json.data : json, 2)\n        .replace(/,(\\n|$)/g, '$1');\n    }\n\n    // IE7/IE8 has a bizarre String constructor; needs to be coerced\n    // into an array and back to obj.\n    if (typeHint === 'string' && typeof value === 'object') {\n      value = reduce(value.split(''), function(acc, char, idx) {\n        acc[idx] = char;\n        return acc;\n      }, {});\n      typeHint = 'object';\n    } else {\n      return jsonStringify(value);\n    }\n  }\n\n  for (var prop in value) {\n    if (Object.prototype.hasOwnProperty.call(value, prop)) {\n      return jsonStringify(exports.canonicalize(value, null, typeHint), 2).replace(/,(\\n|$)/g, '$1');\n    }\n  }\n\n  return emptyRepresentation(value, typeHint);\n};\n\n/**\n * like JSON.stringify but more sense.\n *\n * @api private\n * @param {Object}  object\n * @param {number=} spaces\n * @param {number=} depth\n * @returns {*}\n */\nfunction jsonStringify(object, spaces, depth) {\n  if (typeof spaces === 'undefined') {\n    // primitive types\n    return _stringify(object);\n  }\n\n  depth = depth || 1;\n  var space = spaces * depth;\n  var str = isArray(object) ? '[' : '{';\n  var end = isArray(object) ? ']' : '}';\n  var length = typeof object.length === 'number' ? object.length : exports.keys(object).length;\n  // `.repeat()` polyfill\n  function repeat(s, n) {\n    return new Array(n).join(s);\n  }\n\n  function _stringify(val) {\n    switch (type(val)) {\n      case 'null':\n      case 'undefined':\n        val = '[' + val + ']';\n        break;\n      case 'array':\n      case 'object':\n        val = jsonStringify(val, spaces, depth + 1);\n        break;\n      case 'boolean':\n      case 'regexp':\n      case 'symbol':\n      case 'number':\n        val = val === 0 && (1 / val) === -Infinity // `-0`\n          ? '-0'\n          : val.toString();\n        break;\n      case 'date':\n        var sDate;\n        if (isNaN(val.getTime())) { // Invalid date\n          sDate = val.toString();\n        } else {\n          sDate = val.toISOString ? val.toISOString() : toISOString(val);\n        }\n        val = '[Date: ' + sDate + ']';\n        break;\n      case 'buffer':\n        var json = val.toJSON();\n        // Based on the toJSON result\n        json = json.data && json.type ? json.data : json;\n        val = '[Buffer: ' + jsonStringify(json, 2, depth + 1) + ']';\n        break;\n      default:\n        val = (val === '[Function]' || val === '[Circular]')\n          ? val\n          : JSON.stringify(val); // string\n    }\n    return val;\n  }\n\n  for (var i in object) {\n    if (!Object.prototype.hasOwnProperty.call(object, i)) {\n      continue; // not my business\n    }\n    --length;\n    str += '\\n ' + repeat(' ', space)\n      + (isArray(object) ? '' : '\"' + i + '\": ') // key\n      + _stringify(object[i])                     // value\n      + (length ? ',' : '');                     // comma\n  }\n\n  return str\n    // [], {}\n    + (str.length !== 1 ? '\\n' + repeat(' ', --space) + end : end);\n}\n\n/**\n * Test if a value is a buffer.\n *\n * @api private\n * @param {*} value The value to test.\n * @return {boolean} True if `value` is a buffer, otherwise false\n */\nexports.isBuffer = function(value) {\n  return typeof Buffer !== 'undefined' && Buffer.isBuffer(value);\n};\n\n/**\n * Return a new Thing that has the keys in sorted order. Recursive.\n *\n * If the Thing...\n * - has already been seen, return string `'[Circular]'`\n * - is `undefined`, return string `'[undefined]'`\n * - is `null`, return value `null`\n * - is some other primitive, return the value\n * - is not a primitive or an `Array`, `Object`, or `Function`, return the value of the Thing's `toString()` method\n * - is a non-empty `Array`, `Object`, or `Function`, return the result of calling this function again.\n * - is an empty `Array`, `Object`, or `Function`, return the result of calling `emptyRepresentation()`\n *\n * @api private\n * @see {@link exports.stringify}\n * @param {*} value Thing to inspect.  May or may not have properties.\n * @param {Array} [stack=[]] Stack of seen values\n * @param {string} [typeHint] Type hint\n * @return {(Object|Array|Function|string|undefined)}\n */\nexports.canonicalize = function canonicalize(value, stack, typeHint) {\n  var canonicalizedObj;\n  /* eslint-disable no-unused-vars */\n  var prop;\n  /* eslint-enable no-unused-vars */\n  typeHint = typeHint || type(value);\n  function withStack(value, fn) {\n    stack.push(value);\n    fn();\n    stack.pop();\n  }\n\n  stack = stack || [];\n\n  if (indexOf(stack, value) !== -1) {\n    return '[Circular]';\n  }\n\n  switch (typeHint) {\n    case 'undefined':\n    case 'buffer':\n    case 'null':\n      canonicalizedObj = value;\n      break;\n    case 'array':\n      withStack(value, function() {\n        canonicalizedObj = exports.map(value, function(item) {\n          return exports.canonicalize(item, stack);\n        });\n      });\n      break;\n    case 'function':\n      /* eslint-disable guard-for-in */\n      for (prop in value) {\n        canonicalizedObj = {};\n        break;\n      }\n      /* eslint-enable guard-for-in */\n      if (!canonicalizedObj) {\n        canonicalizedObj = emptyRepresentation(value, typeHint);\n        break;\n      }\n    /* falls through */\n    case 'object':\n      canonicalizedObj = canonicalizedObj || {};\n      withStack(value, function() {\n        exports.forEach(exports.keys(value).sort(), function(key) {\n          canonicalizedObj[key] = exports.canonicalize(value[key], stack);\n        });\n      });\n      break;\n    case 'date':\n    case 'number':\n    case 'regexp':\n    case 'boolean':\n    case 'symbol':\n      canonicalizedObj = value;\n      break;\n    default:\n      canonicalizedObj = value + '';\n  }\n\n  return canonicalizedObj;\n};\n\n/**\n * Lookup file names at the given `path`.\n *\n * @api public\n * @param {string} path Base path to start searching from.\n * @param {string[]} extensions File extensions to look for.\n * @param {boolean} recursive Whether or not to recurse into subdirectories.\n * @return {string[]} An array of paths.\n */\nexports.lookupFiles = function lookupFiles(path, extensions, recursive) {\n  var files = [];\n  var re = new RegExp('\\\\.(' + extensions.join('|') + ')$');\n\n  if (!exists(path)) {\n    if (exists(path + '.js')) {\n      path += '.js';\n    } else {\n      files = glob.sync(path);\n      if (!files.length) {\n        throw new Error(\"cannot resolve path (or pattern) '\" + path + \"'\");\n      }\n      return files;\n    }\n  }\n\n  try {\n    var stat = statSync(path);\n    if (stat.isFile()) {\n      return path;\n    }\n  } catch (err) {\n    // ignore error\n    return;\n  }\n\n  readdirSync(path).forEach(function(file) {\n    file = join(path, file);\n    try {\n      var stat = statSync(file);\n      if (stat.isDirectory()) {\n        if (recursive) {\n          files = files.concat(lookupFiles(file, extensions, recursive));\n        }\n        return;\n      }\n    } catch (err) {\n      // ignore error\n      return;\n    }\n    if (!stat.isFile() || !re.test(file) || basename(file)[0] === '.') {\n      return;\n    }\n    files.push(file);\n  });\n\n  return files;\n};\n\n/**\n * Generate an undefined error with a message warning the user.\n *\n * @return {Error}\n */\n\nexports.undefinedError = function() {\n  return new Error('Caught undefined error, did you throw without specifying what?');\n};\n\n/**\n * Generate an undefined error if `err` is not defined.\n *\n * @param {Error} err\n * @return {Error}\n */\n\nexports.getError = function(err) {\n  return err || exports.undefinedError();\n};\n\n/**\n * @summary\n * This Filter based on `mocha-clean` module.(see: `github.com/rstacruz/mocha-clean`)\n * @description\n * When invoking this function you get a filter function that get the Error.stack as an input,\n * and return a prettify output.\n * (i.e: strip Mocha and internal node functions from stack trace).\n * @returns {Function}\n */\nexports.stackTraceFilter = function() {\n  // TODO: Replace with `process.browser`\n  var is = typeof document === 'undefined' ? { node: true } : { browser: true };\n  var slash = path.sep;\n  var cwd;\n  if (is.node) {\n    cwd = process.cwd() + slash;\n  } else {\n    cwd = (typeof location === 'undefined' ? window.location : location).href.replace(/\\/[^\\/]*$/, '/');\n    slash = '/';\n  }\n\n  function isMochaInternal(line) {\n    return (~line.indexOf('node_modules' + slash + 'mocha' + slash))\n      || (~line.indexOf('node_modules' + slash + 'mocha.js'))\n      || (~line.indexOf('bower_components' + slash + 'mocha.js'))\n      || (~line.indexOf(slash + 'mocha.js'));\n  }\n\n  function isNodeInternal(line) {\n    return (~line.indexOf('(timers.js:'))\n      || (~line.indexOf('(events.js:'))\n      || (~line.indexOf('(node.js:'))\n      || (~line.indexOf('(module.js:'))\n      || (~line.indexOf('GeneratorFunctionPrototype.next (native)'))\n      || false;\n  }\n\n  return function(stack) {\n    stack = stack.split('\\n');\n\n    stack = reduce(stack, function(list, line) {\n      if (isMochaInternal(line)) {\n        return list;\n      }\n\n      if (is.node && isNodeInternal(line)) {\n        return list;\n      }\n\n      // Clean up cwd(absolute)\n      if (/\\(?.+:\\d+:\\d+\\)?$/.test(line)) {\n        line = line.replace(cwd, '');\n      }\n\n      list.push(line);\n      return list;\n    }, []);\n\n    return stack.join('\\n');\n  };\n};\n\n/**\n * Crude, but effective.\n * @api\n * @param {*} value\n * @returns {boolean} Whether or not `value` is a Promise\n */\nexports.isPromise = function isPromise(value) {\n  return typeof value === 'object' && typeof value.then === 'function';\n};\n\n}).call(this,require('_process'),require(\"buffer\").Buffer)\n},{\"./to-iso-string\":37,\"_process\":67,\"buffer\":44,\"debug\":2,\"fs\":42,\"glob\":42,\"json3\":54,\"path\":42,\"util\":84}],39:[function(require,module,exports){\n'use strict'\n\nexports.toByteArray = toByteArray\nexports.fromByteArray = fromByteArray\n\nvar lookup = []\nvar revLookup = []\nvar Arr = typeof Uint8Array !== 'undefined' ? Uint8Array : Array\n\nfunction init () {\n  var code = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'\n  for (var i = 0, len = code.length; i < len; ++i) {\n    lookup[i] = code[i]\n    revLookup[code.charCodeAt(i)] = i\n  }\n\n  revLookup['-'.charCodeAt(0)] = 62\n  revLookup['_'.charCodeAt(0)] = 63\n}\n\ninit()\n\nfunction toByteArray (b64) {\n  var i, j, l, tmp, placeHolders, arr\n  var len = b64.length\n\n  if (len % 4 > 0) {\n    throw new Error('Invalid string. Length must be a multiple of 4')\n  }\n\n  // the number of equal signs (place holders)\n  // if there are two placeholders, than the two characters before it\n  // represent one byte\n  // if there is only one, then the three characters before it represent 2 bytes\n  // this is just a cheap hack to not do indexOf twice\n  placeHolders = b64[len - 2] === '=' ? 2 : b64[len - 1] === '=' ? 1 : 0\n\n  // base64 is 4/3 + up to two characters of the original data\n  arr = new Arr(len * 3 / 4 - placeHolders)\n\n  // if there are placeholders, only get up to the last complete 4 chars\n  l = placeHolders > 0 ? len - 4 : len\n\n  var L = 0\n\n  for (i = 0, j = 0; i < l; i += 4, j += 3) {\n    tmp = (revLookup[b64.charCodeAt(i)] << 18) | (revLookup[b64.charCodeAt(i + 1)] << 12) | (revLookup[b64.charCodeAt(i + 2)] << 6) | revLookup[b64.charCodeAt(i + 3)]\n    arr[L++] = (tmp >> 16) & 0xFF\n    arr[L++] = (tmp >> 8) & 0xFF\n    arr[L++] = tmp & 0xFF\n  }\n\n  if (placeHolders === 2) {\n    tmp = (revLookup[b64.charCodeAt(i)] << 2) | (revLookup[b64.charCodeAt(i + 1)] >> 4)\n    arr[L++] = tmp & 0xFF\n  } else if (placeHolders === 1) {\n    tmp = (revLookup[b64.charCodeAt(i)] << 10) | (revLookup[b64.charCodeAt(i + 1)] << 4) | (revLookup[b64.charCodeAt(i + 2)] >> 2)\n    arr[L++] = (tmp >> 8) & 0xFF\n    arr[L++] = tmp & 0xFF\n  }\n\n  return arr\n}\n\nfunction tripletToBase64 (num) {\n  return lookup[num >> 18 & 0x3F] + lookup[num >> 12 & 0x3F] + lookup[num >> 6 & 0x3F] + lookup[num & 0x3F]\n}\n\nfunction encodeChunk (uint8, start, end) {\n  var tmp\n  var output = []\n  for (var i = start; i < end; i += 3) {\n    tmp = (uint8[i] << 16) + (uint8[i + 1] << 8) + (uint8[i + 2])\n    output.push(tripletToBase64(tmp))\n  }\n  return output.join('')\n}\n\nfunction fromByteArray (uint8) {\n  var tmp\n  var len = uint8.length\n  var extraBytes = len % 3 // if we have 1 byte left, pad 2 bytes\n  var output = ''\n  var parts = []\n  var maxChunkLength = 16383 // must be multiple of 3\n\n  // go through the array every three bytes, we'll deal with trailing stuff later\n  for (var i = 0, len2 = len - extraBytes; i < len2; i += maxChunkLength) {\n    parts.push(encodeChunk(uint8, i, (i + maxChunkLength) > len2 ? len2 : (i + maxChunkLength)))\n  }\n\n  // pad the end with zeros, but make sure to not forget the extra bytes\n  if (extraBytes === 1) {\n    tmp = uint8[len - 1]\n    output += lookup[tmp >> 2]\n    output += lookup[(tmp << 4) & 0x3F]\n    output += '=='\n  } else if (extraBytes === 2) {\n    tmp = (uint8[len - 2] << 8) + (uint8[len - 1])\n    output += lookup[tmp >> 10]\n    output += lookup[(tmp >> 4) & 0x3F]\n    output += lookup[(tmp << 2) & 0x3F]\n    output += '='\n  }\n\n  parts.push(output)\n\n  return parts.join('')\n}\n\n},{}],40:[function(require,module,exports){\n\n},{}],41:[function(require,module,exports){\n(function (process){\nvar WritableStream = require('stream').Writable\nvar inherits = require('util').inherits\n\nmodule.exports = BrowserStdout\n\n\ninherits(BrowserStdout, WritableStream)\n\nfunction BrowserStdout(opts) {\n  if (!(this instanceof BrowserStdout)) return new BrowserStdout(opts)\n\n  opts = opts || {}\n  WritableStream.call(this, opts)\n  this.label = (opts.label !== undefined) ? opts.label : 'stdout'\n}\n\nBrowserStdout.prototype._write = function(chunks, encoding, cb) {\n  var output = chunks.toString ? chunks.toString() : chunks\n  if (this.label === false) {\n    console.log(output)\n  } else {\n    console.log(this.label+':', output)\n  }\n  process.nextTick(cb)\n}\n\n}).call(this,require('_process'))\n},{\"_process\":67,\"stream\":79,\"util\":84}],42:[function(require,module,exports){\narguments[4][40][0].apply(exports,arguments)\n},{\"dup\":40}],43:[function(require,module,exports){\n(function (global){\n'use strict';\n\nvar buffer = require('buffer');\nvar Buffer = buffer.Buffer;\nvar SlowBuffer = buffer.SlowBuffer;\nvar MAX_LEN = buffer.kMaxLength || 2147483647;\nexports.alloc = function alloc(size, fill, encoding) {\n  if (typeof Buffer.alloc === 'function') {\n    return Buffer.alloc(size, fill, encoding);\n  }\n  if (typeof encoding === 'number') {\n    throw new TypeError('encoding must not be number');\n  }\n  if (typeof size !== 'number') {\n    throw new TypeError('size must be a number');\n  }\n  if (size > MAX_LEN) {\n    throw new RangeError('size is too large');\n  }\n  var enc = encoding;\n  var _fill = fill;\n  if (_fill === undefined) {\n    enc = undefined;\n    _fill = 0;\n  }\n  var buf = new Buffer(size);\n  if (typeof _fill === 'string') {\n    var fillBuf = new Buffer(_fill, enc);\n    var flen = fillBuf.length;\n    var i = -1;\n    while (++i < size) {\n      buf[i] = fillBuf[i % flen];\n    }\n  } else {\n    buf.fill(_fill);\n  }\n  return buf;\n}\nexports.allocUnsafe = function allocUnsafe(size) {\n  if (typeof Buffer.allocUnsafe === 'function') {\n    return Buffer.allocUnsafe(size);\n  }\n  if (typeof size !== 'number') {\n    throw new TypeError('size must be a number');\n  }\n  if (size > MAX_LEN) {\n    throw new RangeError('size is too large');\n  }\n  return new Buffer(size);\n}\nexports.from = function from(value, encodingOrOffset, length) {\n  if (typeof Buffer.from === 'function' && (!global.Uint8Array || Uint8Array.from !== Buffer.from)) {\n    return Buffer.from(value, encodingOrOffset, length);\n  }\n  if (typeof value === 'number') {\n    throw new TypeError('\"value\" argument must not be a number');\n  }\n  if (typeof value === 'string') {\n    return new Buffer(value, encodingOrOffset);\n  }\n  if (typeof ArrayBuffer !== 'undefined' && value instanceof ArrayBuffer) {\n    var offset = encodingOrOffset;\n    if (arguments.length === 1) {\n      return new Buffer(value);\n    }\n    if (typeof offset === 'undefined') {\n      offset = 0;\n    }\n    var len = length;\n    if (typeof len === 'undefined') {\n      len = value.byteLength - offset;\n    }\n    if (offset >= value.byteLength) {\n      throw new RangeError('\\'offset\\' is out of bounds');\n    }\n    if (len > value.byteLength - offset) {\n      throw new RangeError('\\'length\\' is out of bounds');\n    }\n    return new Buffer(value.slice(offset, offset + len));\n  }\n  if (Buffer.isBuffer(value)) {\n    var out = new Buffer(value.length);\n    value.copy(out, 0, 0, value.length);\n    return out;\n  }\n  if (value) {\n    if (Array.isArray(value) || (typeof ArrayBuffer !== 'undefined' && value.buffer instanceof ArrayBuffer) || 'length' in value) {\n      return new Buffer(value);\n    }\n    if (value.type === 'Buffer' && Array.isArray(value.data)) {\n      return new Buffer(value.data);\n    }\n  }\n\n  throw new TypeError('First argument must be a string, Buffer, ' + 'ArrayBuffer, Array, or array-like object.');\n}\nexports.allocUnsafeSlow = function allocUnsafeSlow(size) {\n  if (typeof Buffer.allocUnsafeSlow === 'function') {\n    return Buffer.allocUnsafeSlow(size);\n  }\n  if (typeof size !== 'number') {\n    throw new TypeError('size must be a number');\n  }\n  if (size >= MAX_LEN) {\n    throw new RangeError('size is too large');\n  }\n  return new SlowBuffer(size);\n}\n\n}).call(this,typeof global !== \"undefined\" ? global : typeof self !== \"undefined\" ? self : typeof window !== \"undefined\" ? window : {})\n},{\"buffer\":44}],44:[function(require,module,exports){\n(function (global){\n/*!\n * The buffer module from node.js, for the browser.\n *\n * @author   Feross Aboukhadijeh <feross@feross.org> <http://feross.org>\n * @license  MIT\n */\n/* eslint-disable no-proto */\n\n'use strict'\n\nvar base64 = require('base64-js')\nvar ieee754 = require('ieee754')\nvar isArray = require('isarray')\n\nexports.Buffer = Buffer\nexports.SlowBuffer = SlowBuffer\nexports.INSPECT_MAX_BYTES = 50\n\n/**\n * If `Buffer.TYPED_ARRAY_SUPPORT`:\n *   === true    Use Uint8Array implementation (fastest)\n *   === false   Use Object implementation (most compatible, even IE6)\n *\n * Browsers that support typed arrays are IE 10+, Firefox 4+, Chrome 7+, Safari 5.1+,\n * Opera 11.6+, iOS 4.2+.\n *\n * Due to various browser bugs, sometimes the Object implementation will be used even\n * when the browser supports typed arrays.\n *\n * Note:\n *\n *   - Firefox 4-29 lacks support for adding new properties to `Uint8Array` instances,\n *     See: https://bugzilla.mozilla.org/show_bug.cgi?id=695438.\n *\n *   - Chrome 9-10 is missing the `TypedArray.prototype.subarray` function.\n *\n *   - IE10 has a broken `TypedArray.prototype.subarray` function which returns arrays of\n *     incorrect length in some situations.\n\n * We detect these buggy browsers and set `Buffer.TYPED_ARRAY_SUPPORT` to `false` so they\n * get the Object implementation, which is slower but behaves correctly.\n */\nBuffer.TYPED_ARRAY_SUPPORT = global.TYPED_ARRAY_SUPPORT !== undefined\n  ? global.TYPED_ARRAY_SUPPORT\n  : typedArraySupport()\n\n/*\n * Export kMaxLength after typed array support is determined.\n */\nexports.kMaxLength = kMaxLength()\n\nfunction typedArraySupport () {\n  try {\n    var arr = new Uint8Array(1)\n    arr.__proto__ = {__proto__: Uint8Array.prototype, foo: function () { return 42 }}\n    return arr.foo() === 42 && // typed array instances can be augmented\n        typeof arr.subarray === 'function' && // chrome 9-10 lack `subarray`\n        arr.subarray(1, 1).byteLength === 0 // ie10 has broken `subarray`\n  } catch (e) {\n    return false\n  }\n}\n\nfunction kMaxLength () {\n  return Buffer.TYPED_ARRAY_SUPPORT\n    ? 0x7fffffff\n    : 0x3fffffff\n}\n\nfunction createBuffer (that, length) {\n  if (kMaxLength() < length) {\n    throw new RangeError('Invalid typed array length')\n  }\n  if (Buffer.TYPED_ARRAY_SUPPORT) {\n    // Return an augmented `Uint8Array` instance, for best performance\n    that = new Uint8Array(length)\n    that.__proto__ = Buffer.prototype\n  } else {\n    // Fallback: Return an object instance of the Buffer class\n    if (that === null) {\n      that = new Buffer(length)\n    }\n    that.length = length\n  }\n\n  return that\n}\n\n/**\n * The Buffer constructor returns instances of `Uint8Array` that have their\n * prototype changed to `Buffer.prototype`. Furthermore, `Buffer` is a subclass of\n * `Uint8Array`, so the returned instances will have all the node `Buffer` methods\n * and the `Uint8Array` methods. Square bracket notation works as expected -- it\n * returns a single octet.\n *\n * The `Uint8Array` prototype remains unmodified.\n */\n\nfunction Buffer (arg, encodingOrOffset, length) {\n  if (!Buffer.TYPED_ARRAY_SUPPORT && !(this instanceof Buffer)) {\n    return new Buffer(arg, encodingOrOffset, length)\n  }\n\n  // Common case.\n  if (typeof arg === 'number') {\n    if (typeof encodingOrOffset === 'string') {\n      throw new Error(\n        'If encoding is specified then the first argument must be a string'\n      )\n    }\n    return allocUnsafe(this, arg)\n  }\n  return from(this, arg, encodingOrOffset, length)\n}\n\nBuffer.poolSize = 8192 // not used by this implementation\n\n// TODO: Legacy, not needed anymore. Remove in next major version.\nBuffer._augment = function (arr) {\n  arr.__proto__ = Buffer.prototype\n  return arr\n}\n\nfunction from (that, value, encodingOrOffset, length) {\n  if (typeof value === 'number') {\n    throw new TypeError('\"value\" argument must not be a number')\n  }\n\n  if (typeof ArrayBuffer !== 'undefined' && value instanceof ArrayBuffer) {\n    return fromArrayBuffer(that, value, encodingOrOffset, length)\n  }\n\n  if (typeof value === 'string') {\n    return fromString(that, value, encodingOrOffset)\n  }\n\n  return fromObject(that, value)\n}\n\n/**\n * Functionally equivalent to Buffer(arg, encoding) but throws a TypeError\n * if value is a number.\n * Buffer.from(str[, encoding])\n * Buffer.from(array)\n * Buffer.from(buffer)\n * Buffer.from(arrayBuffer[, byteOffset[, length]])\n **/\nBuffer.from = function (value, encodingOrOffset, length) {\n  return from(null, value, encodingOrOffset, length)\n}\n\nif (Buffer.TYPED_ARRAY_SUPPORT) {\n  Buffer.prototype.__proto__ = Uint8Array.prototype\n  Buffer.__proto__ = Uint8Array\n  if (typeof Symbol !== 'undefined' && Symbol.species &&\n      Buffer[Symbol.species] === Buffer) {\n    // Fix subarray() in ES2016. See: https://github.com/feross/buffer/pull/97\n    Object.defineProperty(Buffer, Symbol.species, {\n      value: null,\n      configurable: true\n    })\n  }\n}\n\nfunction assertSize (size) {\n  if (typeof size !== 'number') {\n    throw new TypeError('\"size\" argument must be a number')\n  } else if (size < 0) {\n    throw new RangeError('\"size\" argument must not be negative')\n  }\n}\n\nfunction alloc (that, size, fill, encoding) {\n  assertSize(size)\n  if (size <= 0) {\n    return createBuffer(that, size)\n  }\n  if (fill !== undefined) {\n    // Only pay attention to encoding if it's a string. This\n    // prevents accidentally sending in a number that would\n    // be interpretted as a start offset.\n    return typeof encoding === 'string'\n      ? createBuffer(that, size).fill(fill, encoding)\n      : createBuffer(that, size).fill(fill)\n  }\n  return createBuffer(that, size)\n}\n\n/**\n * Creates a new filled Buffer instance.\n * alloc(size[, fill[, encoding]])\n **/\nBuffer.alloc = function (size, fill, encoding) {\n  return alloc(null, size, fill, encoding)\n}\n\nfunction allocUnsafe (that, size) {\n  assertSize(size)\n  that = createBuffer(that, size < 0 ? 0 : checked(size) | 0)\n  if (!Buffer.TYPED_ARRAY_SUPPORT) {\n    for (var i = 0; i < size; ++i) {\n      that[i] = 0\n    }\n  }\n  return that\n}\n\n/**\n * Equivalent to Buffer(num), by default creates a non-zero-filled Buffer instance.\n * */\nBuffer.allocUnsafe = function (size) {\n  return allocUnsafe(null, size)\n}\n/**\n * Equivalent to SlowBuffer(num), by default creates a non-zero-filled Buffer instance.\n */\nBuffer.allocUnsafeSlow = function (size) {\n  return allocUnsafe(null, size)\n}\n\nfunction fromString (that, string, encoding) {\n  if (typeof encoding !== 'string' || encoding === '') {\n    encoding = 'utf8'\n  }\n\n  if (!Buffer.isEncoding(encoding)) {\n    throw new TypeError('\"encoding\" must be a valid string encoding')\n  }\n\n  var length = byteLength(string, encoding) | 0\n  that = createBuffer(that, length)\n\n  var actual = that.write(string, encoding)\n\n  if (actual !== length) {\n    // Writing a hex string, for example, that contains invalid characters will\n    // cause everything after the first invalid character to be ignored. (e.g.\n    // 'abxxcd' will be treated as 'ab')\n    that = that.slice(0, actual)\n  }\n\n  return that\n}\n\nfunction fromArrayLike (that, array) {\n  var length = array.length < 0 ? 0 : checked(array.length) | 0\n  that = createBuffer(that, length)\n  for (var i = 0; i < length; i += 1) {\n    that[i] = array[i] & 255\n  }\n  return that\n}\n\nfunction fromArrayBuffer (that, array, byteOffset, length) {\n  array.byteLength // this throws if `array` is not a valid ArrayBuffer\n\n  if (byteOffset < 0 || array.byteLength < byteOffset) {\n    throw new RangeError('\\'offset\\' is out of bounds')\n  }\n\n  if (array.byteLength < byteOffset + (length || 0)) {\n    throw new RangeError('\\'length\\' is out of bounds')\n  }\n\n  if (byteOffset === undefined && length === undefined) {\n    array = new Uint8Array(array)\n  } else if (length === undefined) {\n    array = new Uint8Array(array, byteOffset)\n  } else {\n    array = new Uint8Array(array, byteOffset, length)\n  }\n\n  if (Buffer.TYPED_ARRAY_SUPPORT) {\n    // Return an augmented `Uint8Array` instance, for best performance\n    that = array\n    that.__proto__ = Buffer.prototype\n  } else {\n    // Fallback: Return an object instance of the Buffer class\n    that = fromArrayLike(that, array)\n  }\n  return that\n}\n\nfunction fromObject (that, obj) {\n  if (Buffer.isBuffer(obj)) {\n    var len = checked(obj.length) | 0\n    that = createBuffer(that, len)\n\n    if (that.length === 0) {\n      return that\n    }\n\n    obj.copy(that, 0, 0, len)\n    return that\n  }\n\n  if (obj) {\n    if ((typeof ArrayBuffer !== 'undefined' &&\n        obj.buffer instanceof ArrayBuffer) || 'length' in obj) {\n      if (typeof obj.length !== 'number' || isnan(obj.length)) {\n        return createBuffer(that, 0)\n      }\n      return fromArrayLike(that, obj)\n    }\n\n    if (obj.type === 'Buffer' && isArray(obj.data)) {\n      return fromArrayLike(that, obj.data)\n    }\n  }\n\n  throw new TypeError('First argument must be a string, Buffer, ArrayBuffer, Array, or array-like object.')\n}\n\nfunction checked (length) {\n  // Note: cannot use `length < kMaxLength()` here because that fails when\n  // length is NaN (which is otherwise coerced to zero.)\n  if (length >= kMaxLength()) {\n    throw new RangeError('Attempt to allocate Buffer larger than maximum ' +\n                         'size: 0x' + kMaxLength().toString(16) + ' bytes')\n  }\n  return length | 0\n}\n\nfunction SlowBuffer (length) {\n  if (+length != length) { // eslint-disable-line eqeqeq\n    length = 0\n  }\n  return Buffer.alloc(+length)\n}\n\nBuffer.isBuffer = function isBuffer (b) {\n  return !!(b != null && b._isBuffer)\n}\n\nBuffer.compare = function compare (a, b) {\n  if (!Buffer.isBuffer(a) || !Buffer.isBuffer(b)) {\n    throw new TypeError('Arguments must be Buffers')\n  }\n\n  if (a === b) return 0\n\n  var x = a.length\n  var y = b.length\n\n  for (var i = 0, len = Math.min(x, y); i < len; ++i) {\n    if (a[i] !== b[i]) {\n      x = a[i]\n      y = b[i]\n      break\n    }\n  }\n\n  if (x < y) return -1\n  if (y < x) return 1\n  return 0\n}\n\nBuffer.isEncoding = function isEncoding (encoding) {\n  switch (String(encoding).toLowerCase()) {\n    case 'hex':\n    case 'utf8':\n    case 'utf-8':\n    case 'ascii':\n    case 'latin1':\n    case 'binary':\n    case 'base64':\n    case 'ucs2':\n    case 'ucs-2':\n    case 'utf16le':\n    case 'utf-16le':\n      return true\n    default:\n      return false\n  }\n}\n\nBuffer.concat = function concat (list, length) {\n  if (!isArray(list)) {\n    throw new TypeError('\"list\" argument must be an Array of Buffers')\n  }\n\n  if (list.length === 0) {\n    return Buffer.alloc(0)\n  }\n\n  var i\n  if (length === undefined) {\n    length = 0\n    for (i = 0; i < list.length; ++i) {\n      length += list[i].length\n    }\n  }\n\n  var buffer = Buffer.allocUnsafe(length)\n  var pos = 0\n  for (i = 0; i < list.length; ++i) {\n    var buf = list[i]\n    if (!Buffer.isBuffer(buf)) {\n      throw new TypeError('\"list\" argument must be an Array of Buffers')\n    }\n    buf.copy(buffer, pos)\n    pos += buf.length\n  }\n  return buffer\n}\n\nfunction byteLength (string, encoding) {\n  if (Buffer.isBuffer(string)) {\n    return string.length\n  }\n  if (typeof ArrayBuffer !== 'undefined' && typeof ArrayBuffer.isView === 'function' &&\n      (ArrayBuffer.isView(string) || string instanceof ArrayBuffer)) {\n    return string.byteLength\n  }\n  if (typeof string !== 'string') {\n    string = '' + string\n  }\n\n  var len = string.length\n  if (len === 0) return 0\n\n  // Use a for loop to avoid recursion\n  var loweredCase = false\n  for (;;) {\n    switch (encoding) {\n      case 'ascii':\n      case 'latin1':\n      case 'binary':\n        return len\n      case 'utf8':\n      case 'utf-8':\n      case undefined:\n        return utf8ToBytes(string).length\n      case 'ucs2':\n      case 'ucs-2':\n      case 'utf16le':\n      case 'utf-16le':\n        return len * 2\n      case 'hex':\n        return len >>> 1\n      case 'base64':\n        return base64ToBytes(string).length\n      default:\n        if (loweredCase) return utf8ToBytes(string).length // assume utf8\n        encoding = ('' + encoding).toLowerCase()\n        loweredCase = true\n    }\n  }\n}\nBuffer.byteLength = byteLength\n\nfunction slowToString (encoding, start, end) {\n  var loweredCase = false\n\n  // No need to verify that \"this.length <= MAX_UINT32\" since it's a read-only\n  // property of a typed array.\n\n  // This behaves neither like String nor Uint8Array in that we set start/end\n  // to their upper/lower bounds if the value passed is out of range.\n  // undefined is handled specially as per ECMA-262 6th Edition,\n  // Section 13.3.3.7 Runtime Semantics: KeyedBindingInitialization.\n  if (start === undefined || start < 0) {\n    start = 0\n  }\n  // Return early if start > this.length. Done here to prevent potential uint32\n  // coercion fail below.\n  if (start > this.length) {\n    return ''\n  }\n\n  if (end === undefined || end > this.length) {\n    end = this.length\n  }\n\n  if (end <= 0) {\n    return ''\n  }\n\n  // Force coersion to uint32. This will also coerce falsey/NaN values to 0.\n  end >>>= 0\n  start >>>= 0\n\n  if (end <= start) {\n    return ''\n  }\n\n  if (!encoding) encoding = 'utf8'\n\n  while (true) {\n    switch (encoding) {\n      case 'hex':\n        return hexSlice(this, start, end)\n\n      case 'utf8':\n      case 'utf-8':\n        return utf8Slice(this, start, end)\n\n      case 'ascii':\n        return asciiSlice(this, start, end)\n\n      case 'latin1':\n      case 'binary':\n        return latin1Slice(this, start, end)\n\n      case 'base64':\n        return base64Slice(this, start, end)\n\n      case 'ucs2':\n      case 'ucs-2':\n      case 'utf16le':\n      case 'utf-16le':\n        return utf16leSlice(this, start, end)\n\n      default:\n        if (loweredCase) throw new TypeError('Unknown encoding: ' + encoding)\n        encoding = (encoding + '').toLowerCase()\n        loweredCase = true\n    }\n  }\n}\n\n// The property is used by `Buffer.isBuffer` and `is-buffer` (in Safari 5-7) to detect\n// Buffer instances.\nBuffer.prototype._isBuffer = true\n\nfunction swap (b, n, m) {\n  var i = b[n]\n  b[n] = b[m]\n  b[m] = i\n}\n\nBuffer.prototype.swap16 = function swap16 () {\n  var len = this.length\n  if (len % 2 !== 0) {\n    throw new RangeError('Buffer size must be a multiple of 16-bits')\n  }\n  for (var i = 0; i < len; i += 2) {\n    swap(this, i, i + 1)\n  }\n  return this\n}\n\nBuffer.prototype.swap32 = function swap32 () {\n  var len = this.length\n  if (len % 4 !== 0) {\n    throw new RangeError('Buffer size must be a multiple of 32-bits')\n  }\n  for (var i = 0; i < len; i += 4) {\n    swap(this, i, i + 3)\n    swap(this, i + 1, i + 2)\n  }\n  return this\n}\n\nBuffer.prototype.swap64 = function swap64 () {\n  var len = this.length\n  if (len % 8 !== 0) {\n    throw new RangeError('Buffer size must be a multiple of 64-bits')\n  }\n  for (var i = 0; i < len; i += 8) {\n    swap(this, i, i + 7)\n    swap(this, i + 1, i + 6)\n    swap(this, i + 2, i + 5)\n    swap(this, i + 3, i + 4)\n  }\n  return this\n}\n\nBuffer.prototype.toString = function toString () {\n  var length = this.length | 0\n  if (length === 0) return ''\n  if (arguments.length === 0) return utf8Slice(this, 0, length)\n  return slowToString.apply(this, arguments)\n}\n\nBuffer.prototype.equals = function equals (b) {\n  if (!Buffer.isBuffer(b)) throw new TypeError('Argument must be a Buffer')\n  if (this === b) return true\n  return Buffer.compare(this, b) === 0\n}\n\nBuffer.prototype.inspect = function inspect () {\n  var str = ''\n  var max = exports.INSPECT_MAX_BYTES\n  if (this.length > 0) {\n    str = this.toString('hex', 0, max).match(/.{2}/g).join(' ')\n    if (this.length > max) str += ' ... '\n  }\n  return '<Buffer ' + str + '>'\n}\n\nBuffer.prototype.compare = function compare (target, start, end, thisStart, thisEnd) {\n  if (!Buffer.isBuffer(target)) {\n    throw new TypeError('Argument must be a Buffer')\n  }\n\n  if (start === undefined) {\n    start = 0\n  }\n  if (end === undefined) {\n    end = target ? target.length : 0\n  }\n  if (thisStart === undefined) {\n    thisStart = 0\n  }\n  if (thisEnd === undefined) {\n    thisEnd = this.length\n  }\n\n  if (start < 0 || end > target.length || thisStart < 0 || thisEnd > this.length) {\n    throw new RangeError('out of range index')\n  }\n\n  if (thisStart >= thisEnd && start >= end) {\n    return 0\n  }\n  if (thisStart >= thisEnd) {\n    return -1\n  }\n  if (start >= end) {\n    return 1\n  }\n\n  start >>>= 0\n  end >>>= 0\n  thisStart >>>= 0\n  thisEnd >>>= 0\n\n  if (this === target) return 0\n\n  var x = thisEnd - thisStart\n  var y = end - start\n  var len = Math.min(x, y)\n\n  var thisCopy = this.slice(thisStart, thisEnd)\n  var targetCopy = target.slice(start, end)\n\n  for (var i = 0; i < len; ++i) {\n    if (thisCopy[i] !== targetCopy[i]) {\n      x = thisCopy[i]\n      y = targetCopy[i]\n      break\n    }\n  }\n\n  if (x < y) return -1\n  if (y < x) return 1\n  return 0\n}\n\n// Finds either the first index of `val` in `buffer` at offset >= `byteOffset`,\n// OR the last index of `val` in `buffer` at offset <= `byteOffset`.\n//\n// Arguments:\n// - buffer - a Buffer to search\n// - val - a string, Buffer, or number\n// - byteOffset - an index into `buffer`; will be clamped to an int32\n// - encoding - an optional encoding, relevant is val is a string\n// - dir - true for indexOf, false for lastIndexOf\nfunction bidirectionalIndexOf (buffer, val, byteOffset, encoding, dir) {\n  // Empty buffer means no match\n  if (buffer.length === 0) return -1\n\n  // Normalize byteOffset\n  if (typeof byteOffset === 'string') {\n    encoding = byteOffset\n    byteOffset = 0\n  } else if (byteOffset > 0x7fffffff) {\n    byteOffset = 0x7fffffff\n  } else if (byteOffset < -0x80000000) {\n    byteOffset = -0x80000000\n  }\n  byteOffset = +byteOffset  // Coerce to Number.\n  if (isNaN(byteOffset)) {\n    // byteOffset: it it's undefined, null, NaN, \"foo\", etc, search whole buffer\n    byteOffset = dir ? 0 : (buffer.length - 1)\n  }\n\n  // Normalize byteOffset: negative offsets start from the end of the buffer\n  if (byteOffset < 0) byteOffset = buffer.length + byteOffset\n  if (byteOffset >= buffer.length) {\n    if (dir) return -1\n    else byteOffset = buffer.length - 1\n  } else if (byteOffset < 0) {\n    if (dir) byteOffset = 0\n    else return -1\n  }\n\n  // Normalize val\n  if (typeof val === 'string') {\n    val = Buffer.from(val, encoding)\n  }\n\n  // Finally, search either indexOf (if dir is true) or lastIndexOf\n  if (Buffer.isBuffer(val)) {\n    // Special case: looking for empty string/buffer always fails\n    if (val.length === 0) {\n      return -1\n    }\n    return arrayIndexOf(buffer, val, byteOffset, encoding, dir)\n  } else if (typeof val === 'number') {\n    val = val & 0xFF // Search for a byte value [0-255]\n    if (Buffer.TYPED_ARRAY_SUPPORT &&\n        typeof Uint8Array.prototype.indexOf === 'function') {\n      if (dir) {\n        return Uint8Array.prototype.indexOf.call(buffer, val, byteOffset)\n      } else {\n        return Uint8Array.prototype.lastIndexOf.call(buffer, val, byteOffset)\n      }\n    }\n    return arrayIndexOf(buffer, [ val ], byteOffset, encoding, dir)\n  }\n\n  throw new TypeError('val must be string, number or Buffer')\n}\n\nfunction arrayIndexOf (arr, val, byteOffset, encoding, dir) {\n  var indexSize = 1\n  var arrLength = arr.length\n  var valLength = val.length\n\n  if (encoding !== undefined) {\n    encoding = String(encoding).toLowerCase()\n    if (encoding === 'ucs2' || encoding === 'ucs-2' ||\n        encoding === 'utf16le' || encoding === 'utf-16le') {\n      if (arr.length < 2 || val.length < 2) {\n        return -1\n      }\n      indexSize = 2\n      arrLength /= 2\n      valLength /= 2\n      byteOffset /= 2\n    }\n  }\n\n  function read (buf, i) {\n    if (indexSize === 1) {\n      return buf[i]\n    } else {\n      return buf.readUInt16BE(i * indexSize)\n    }\n  }\n\n  var i\n  if (dir) {\n    var foundIndex = -1\n    for (i = byteOffset; i < arrLength; i++) {\n      if (read(arr, i) === read(val, foundIndex === -1 ? 0 : i - foundIndex)) {\n        if (foundIndex === -1) foundIndex = i\n        if (i - foundIndex + 1 === valLength) return foundIndex * indexSize\n      } else {\n        if (foundIndex !== -1) i -= i - foundIndex\n        foundIndex = -1\n      }\n    }\n  } else {\n    if (byteOffset + valLength > arrLength) byteOffset = arrLength - valLength\n    for (i = byteOffset; i >= 0; i--) {\n      var found = true\n      for (var j = 0; j < valLength; j++) {\n        if (read(arr, i + j) !== read(val, j)) {\n          found = false\n          break\n        }\n      }\n      if (found) return i\n    }\n  }\n\n  return -1\n}\n\nBuffer.prototype.includes = function includes (val, byteOffset, encoding) {\n  return this.indexOf(val, byteOffset, encoding) !== -1\n}\n\nBuffer.prototype.indexOf = function indexOf (val, byteOffset, encoding) {\n  return bidirectionalIndexOf(this, val, byteOffset, encoding, true)\n}\n\nBuffer.prototype.lastIndexOf = function lastIndexOf (val, byteOffset, encoding) {\n  return bidirectionalIndexOf(this, val, byteOffset, encoding, false)\n}\n\nfunction hexWrite (buf, string, offset, length) {\n  offset = Number(offset) || 0\n  var remaining = buf.length - offset\n  if (!length) {\n    length = remaining\n  } else {\n    length = Number(length)\n    if (length > remaining) {\n      length = remaining\n    }\n  }\n\n  // must be an even number of digits\n  var strLen = string.length\n  if (strLen % 2 !== 0) throw new TypeError('Invalid hex string')\n\n  if (length > strLen / 2) {\n    length = strLen / 2\n  }\n  for (var i = 0; i < length; ++i) {\n    var parsed = parseInt(string.substr(i * 2, 2), 16)\n    if (isNaN(parsed)) return i\n    buf[offset + i] = parsed\n  }\n  return i\n}\n\nfunction utf8Write (buf, string, offset, length) {\n  return blitBuffer(utf8ToBytes(string, buf.length - offset), buf, offset, length)\n}\n\nfunction asciiWrite (buf, string, offset, length) {\n  return blitBuffer(asciiToBytes(string), buf, offset, length)\n}\n\nfunction latin1Write (buf, string, offset, length) {\n  return asciiWrite(buf, string, offset, length)\n}\n\nfunction base64Write (buf, string, offset, length) {\n  return blitBuffer(base64ToBytes(string), buf, offset, length)\n}\n\nfunction ucs2Write (buf, string, offset, length) {\n  return blitBuffer(utf16leToBytes(string, buf.length - offset), buf, offset, length)\n}\n\nBuffer.prototype.write = function write (string, offset, length, encoding) {\n  // Buffer#write(string)\n  if (offset === undefined) {\n    encoding = 'utf8'\n    length = this.length\n    offset = 0\n  // Buffer#write(string, encoding)\n  } else if (length === undefined && typeof offset === 'string') {\n    encoding = offset\n    length = this.length\n    offset = 0\n  // Buffer#write(string, offset[, length][, encoding])\n  } else if (isFinite(offset)) {\n    offset = offset | 0\n    if (isFinite(length)) {\n      length = length | 0\n      if (encoding === undefined) encoding = 'utf8'\n    } else {\n      encoding = length\n      length = undefined\n    }\n  // legacy write(string, encoding, offset, length) - remove in v0.13\n  } else {\n    throw new Error(\n      'Buffer.write(string, encoding, offset[, length]) is no longer supported'\n    )\n  }\n\n  var remaining = this.length - offset\n  if (length === undefined || length > remaining) length = remaining\n\n  if ((string.length > 0 && (length < 0 || offset < 0)) || offset > this.length) {\n    throw new RangeError('Attempt to write outside buffer bounds')\n  }\n\n  if (!encoding) encoding = 'utf8'\n\n  var loweredCase = false\n  for (;;) {\n    switch (encoding) {\n      case 'hex':\n        return hexWrite(this, string, offset, length)\n\n      case 'utf8':\n      case 'utf-8':\n        return utf8Write(this, string, offset, length)\n\n      case 'ascii':\n        return asciiWrite(this, string, offset, length)\n\n      case 'latin1':\n      case 'binary':\n        return latin1Write(this, string, offset, length)\n\n      case 'base64':\n        // Warning: maxLength not taken into account in base64Write\n        return base64Write(this, string, offset, length)\n\n      case 'ucs2':\n      case 'ucs-2':\n      case 'utf16le':\n      case 'utf-16le':\n        return ucs2Write(this, string, offset, length)\n\n      default:\n        if (loweredCase) throw new TypeError('Unknown encoding: ' + encoding)\n        encoding = ('' + encoding).toLowerCase()\n        loweredCase = true\n    }\n  }\n}\n\nBuffer.prototype.toJSON = function toJSON () {\n  return {\n    type: 'Buffer',\n    data: Array.prototype.slice.call(this._arr || this, 0)\n  }\n}\n\nfunction base64Slice (buf, start, end) {\n  if (start === 0 && end === buf.length) {\n    return base64.fromByteArray(buf)\n  } else {\n    return base64.fromByteArray(buf.slice(start, end))\n  }\n}\n\nfunction utf8Slice (buf, start, end) {\n  end = Math.min(buf.length, end)\n  var res = []\n\n  var i = start\n  while (i < end) {\n    var firstByte = buf[i]\n    var codePoint = null\n    var bytesPerSequence = (firstByte > 0xEF) ? 4\n      : (firstByte > 0xDF) ? 3\n      : (firstByte > 0xBF) ? 2\n      : 1\n\n    if (i + bytesPerSequence <= end) {\n      var secondByte, thirdByte, fourthByte, tempCodePoint\n\n      switch (bytesPerSequence) {\n        case 1:\n          if (firstByte < 0x80) {\n            codePoint = firstByte\n          }\n          break\n        case 2:\n          secondByte = buf[i + 1]\n          if ((secondByte & 0xC0) === 0x80) {\n            tempCodePoint = (firstByte & 0x1F) << 0x6 | (secondByte & 0x3F)\n            if (tempCodePoint > 0x7F) {\n              codePoint = tempCodePoint\n            }\n          }\n          break\n        case 3:\n          secondByte = buf[i + 1]\n          thirdByte = buf[i + 2]\n          if ((secondByte & 0xC0) === 0x80 && (thirdByte & 0xC0) === 0x80) {\n            tempCodePoint = (firstByte & 0xF) << 0xC | (secondByte & 0x3F) << 0x6 | (thirdByte & 0x3F)\n            if (tempCodePoint > 0x7FF && (tempCodePoint < 0xD800 || tempCodePoint > 0xDFFF)) {\n              codePoint = tempCodePoint\n            }\n          }\n          break\n        case 4:\n          secondByte = buf[i + 1]\n          thirdByte = buf[i + 2]\n          fourthByte = buf[i + 3]\n          if ((secondByte & 0xC0) === 0x80 && (thirdByte & 0xC0) === 0x80 && (fourthByte & 0xC0) === 0x80) {\n            tempCodePoint = (firstByte & 0xF) << 0x12 | (secondByte & 0x3F) << 0xC | (thirdByte & 0x3F) << 0x6 | (fourthByte & 0x3F)\n            if (tempCodePoint > 0xFFFF && tempCodePoint < 0x110000) {\n              codePoint = tempCodePoint\n            }\n          }\n      }\n    }\n\n    if (codePoint === null) {\n      // we did not generate a valid codePoint so insert a\n      // replacement char (U+FFFD) and advance only 1 byte\n      codePoint = 0xFFFD\n      bytesPerSequence = 1\n    } else if (codePoint > 0xFFFF) {\n      // encode to utf16 (surrogate pair dance)\n      codePoint -= 0x10000\n      res.push(codePoint >>> 10 & 0x3FF | 0xD800)\n      codePoint = 0xDC00 | codePoint & 0x3FF\n    }\n\n    res.push(codePoint)\n    i += bytesPerSequence\n  }\n\n  return decodeCodePointsArray(res)\n}\n\n// Based on http://stackoverflow.com/a/22747272/680742, the browser with\n// the lowest limit is Chrome, with 0x10000 args.\n// We go 1 magnitude less, for safety\nvar MAX_ARGUMENTS_LENGTH = 0x1000\n\nfunction decodeCodePointsArray (codePoints) {\n  var len = codePoints.length\n  if (len <= MAX_ARGUMENTS_LENGTH) {\n    return String.fromCharCode.apply(String, codePoints) // avoid extra slice()\n  }\n\n  // Decode in chunks to avoid \"call stack size exceeded\".\n  var res = ''\n  var i = 0\n  while (i < len) {\n    res += String.fromCharCode.apply(\n      String,\n      codePoints.slice(i, i += MAX_ARGUMENTS_LENGTH)\n    )\n  }\n  return res\n}\n\nfunction asciiSlice (buf, start, end) {\n  var ret = ''\n  end = Math.min(buf.length, end)\n\n  for (var i = start; i < end; ++i) {\n    ret += String.fromCharCode(buf[i] & 0x7F)\n  }\n  return ret\n}\n\nfunction latin1Slice (buf, start, end) {\n  var ret = ''\n  end = Math.min(buf.length, end)\n\n  for (var i = start; i < end; ++i) {\n    ret += String.fromCharCode(buf[i])\n  }\n  return ret\n}\n\nfunction hexSlice (buf, start, end) {\n  var len = buf.length\n\n  if (!start || start < 0) start = 0\n  if (!end || end < 0 || end > len) end = len\n\n  var out = ''\n  for (var i = start; i < end; ++i) {\n    out += toHex(buf[i])\n  }\n  return out\n}\n\nfunction utf16leSlice (buf, start, end) {\n  var bytes = buf.slice(start, end)\n  var res = ''\n  for (var i = 0; i < bytes.length; i += 2) {\n    res += String.fromCharCode(bytes[i] + bytes[i + 1] * 256)\n  }\n  return res\n}\n\nBuffer.prototype.slice = function slice (start, end) {\n  var len = this.length\n  start = ~~start\n  end = end === undefined ? len : ~~end\n\n  if (start < 0) {\n    start += len\n    if (start < 0) start = 0\n  } else if (start > len) {\n    start = len\n  }\n\n  if (end < 0) {\n    end += len\n    if (end < 0) end = 0\n  } else if (end > len) {\n    end = len\n  }\n\n  if (end < start) end = start\n\n  var newBuf\n  if (Buffer.TYPED_ARRAY_SUPPORT) {\n    newBuf = this.subarray(start, end)\n    newBuf.__proto__ = Buffer.prototype\n  } else {\n    var sliceLen = end - start\n    newBuf = new Buffer(sliceLen, undefined)\n    for (var i = 0; i < sliceLen; ++i) {\n      newBuf[i] = this[i + start]\n    }\n  }\n\n  return newBuf\n}\n\n/*\n * Need to make sure that buffer isn't trying to write out of bounds.\n */\nfunction checkOffset (offset, ext, length) {\n  if ((offset % 1) !== 0 || offset < 0) throw new RangeError('offset is not uint')\n  if (offset + ext > length) throw new RangeError('Trying to access beyond buffer length')\n}\n\nBuffer.prototype.readUIntLE = function readUIntLE (offset, byteLength, noAssert) {\n  offset = offset | 0\n  byteLength = byteLength | 0\n  if (!noAssert) checkOffset(offset, byteLength, this.length)\n\n  var val = this[offset]\n  var mul = 1\n  var i = 0\n  while (++i < byteLength && (mul *= 0x100)) {\n    val += this[offset + i] * mul\n  }\n\n  return val\n}\n\nBuffer.prototype.readUIntBE = function readUIntBE (offset, byteLength, noAssert) {\n  offset = offset | 0\n  byteLength = byteLength | 0\n  if (!noAssert) {\n    checkOffset(offset, byteLength, this.length)\n  }\n\n  var val = this[offset + --byteLength]\n  var mul = 1\n  while (byteLength > 0 && (mul *= 0x100)) {\n    val += this[offset + --byteLength] * mul\n  }\n\n  return val\n}\n\nBuffer.prototype.readUInt8 = function readUInt8 (offset, noAssert) {\n  if (!noAssert) checkOffset(offset, 1, this.length)\n  return this[offset]\n}\n\nBuffer.prototype.readUInt16LE = function readUInt16LE (offset, noAssert) {\n  if (!noAssert) checkOffset(offset, 2, this.length)\n  return this[offset] | (this[offset + 1] << 8)\n}\n\nBuffer.prototype.readUInt16BE = function readUInt16BE (offset, noAssert) {\n  if (!noAssert) checkOffset(offset, 2, this.length)\n  return (this[offset] << 8) | this[offset + 1]\n}\n\nBuffer.prototype.readUInt32LE = function readUInt32LE (offset, noAssert) {\n  if (!noAssert) checkOffset(offset, 4, this.length)\n\n  return ((this[offset]) |\n      (this[offset + 1] << 8) |\n      (this[offset + 2] << 16)) +\n      (this[offset + 3] * 0x1000000)\n}\n\nBuffer.prototype.readUInt32BE = function readUInt32BE (offset, noAssert) {\n  if (!noAssert) checkOffset(offset, 4, this.length)\n\n  return (this[offset] * 0x1000000) +\n    ((this[offset + 1] << 16) |\n    (this[offset + 2] << 8) |\n    this[offset + 3])\n}\n\nBuffer.prototype.readIntLE = function readIntLE (offset, byteLength, noAssert) {\n  offset = offset | 0\n  byteLength = byteLength | 0\n  if (!noAssert) checkOffset(offset, byteLength, this.length)\n\n  var val = this[offset]\n  var mul = 1\n  var i = 0\n  while (++i < byteLength && (mul *= 0x100)) {\n    val += this[offset + i] * mul\n  }\n  mul *= 0x80\n\n  if (val >= mul) val -= Math.pow(2, 8 * byteLength)\n\n  return val\n}\n\nBuffer.prototype.readIntBE = function readIntBE (offset, byteLength, noAssert) {\n  offset = offset | 0\n  byteLength = byteLength | 0\n  if (!noAssert) checkOffset(offset, byteLength, this.length)\n\n  var i = byteLength\n  var mul = 1\n  var val = this[offset + --i]\n  while (i > 0 && (mul *= 0x100)) {\n    val += this[offset + --i] * mul\n  }\n  mul *= 0x80\n\n  if (val >= mul) val -= Math.pow(2, 8 * byteLength)\n\n  return val\n}\n\nBuffer.prototype.readInt8 = function readInt8 (offset, noAssert) {\n  if (!noAssert) checkOffset(offset, 1, this.length)\n  if (!(this[offset] & 0x80)) return (this[offset])\n  return ((0xff - this[offset] + 1) * -1)\n}\n\nBuffer.prototype.readInt16LE = function readInt16LE (offset, noAssert) {\n  if (!noAssert) checkOffset(offset, 2, this.length)\n  var val = this[offset] | (this[offset + 1] << 8)\n  return (val & 0x8000) ? val | 0xFFFF0000 : val\n}\n\nBuffer.prototype.readInt16BE = function readInt16BE (offset, noAssert) {\n  if (!noAssert) checkOffset(offset, 2, this.length)\n  var val = this[offset + 1] | (this[offset] << 8)\n  return (val & 0x8000) ? val | 0xFFFF0000 : val\n}\n\nBuffer.prototype.readInt32LE = function readInt32LE (offset, noAssert) {\n  if (!noAssert) checkOffset(offset, 4, this.length)\n\n  return (this[offset]) |\n    (this[offset + 1] << 8) |\n    (this[offset + 2] << 16) |\n    (this[offset + 3] << 24)\n}\n\nBuffer.prototype.readInt32BE = function readInt32BE (offset, noAssert) {\n  if (!noAssert) checkOffset(offset, 4, this.length)\n\n  return (this[offset] << 24) |\n    (this[offset + 1] << 16) |\n    (this[offset + 2] << 8) |\n    (this[offset + 3])\n}\n\nBuffer.prototype.readFloatLE = function readFloatLE (offset, noAssert) {\n  if (!noAssert) checkOffset(offset, 4, this.length)\n  return ieee754.read(this, offset, true, 23, 4)\n}\n\nBuffer.prototype.readFloatBE = function readFloatBE (offset, noAssert) {\n  if (!noAssert) checkOffset(offset, 4, this.length)\n  return ieee754.read(this, offset, false, 23, 4)\n}\n\nBuffer.prototype.readDoubleLE = function readDoubleLE (offset, noAssert) {\n  if (!noAssert) checkOffset(offset, 8, this.length)\n  return ieee754.read(this, offset, true, 52, 8)\n}\n\nBuffer.prototype.readDoubleBE = function readDoubleBE (offset, noAssert) {\n  if (!noAssert) checkOffset(offset, 8, this.length)\n  return ieee754.read(this, offset, false, 52, 8)\n}\n\nfunction checkInt (buf, value, offset, ext, max, min) {\n  if (!Buffer.isBuffer(buf)) throw new TypeError('\"buffer\" argument must be a Buffer instance')\n  if (value > max || value < min) throw new RangeError('\"value\" argument is out of bounds')\n  if (offset + ext > buf.length) throw new RangeError('Index out of range')\n}\n\nBuffer.prototype.writeUIntLE = function writeUIntLE (value, offset, byteLength, noAssert) {\n  value = +value\n  offset = offset | 0\n  byteLength = byteLength | 0\n  if (!noAssert) {\n    var maxBytes = Math.pow(2, 8 * byteLength) - 1\n    checkInt(this, value, offset, byteLength, maxBytes, 0)\n  }\n\n  var mul = 1\n  var i = 0\n  this[offset] = value & 0xFF\n  while (++i < byteLength && (mul *= 0x100)) {\n    this[offset + i] = (value / mul) & 0xFF\n  }\n\n  return offset + byteLength\n}\n\nBuffer.prototype.writeUIntBE = function writeUIntBE (value, offset, byteLength, noAssert) {\n  value = +value\n  offset = offset | 0\n  byteLength = byteLength | 0\n  if (!noAssert) {\n    var maxBytes = Math.pow(2, 8 * byteLength) - 1\n    checkInt(this, value, offset, byteLength, maxBytes, 0)\n  }\n\n  var i = byteLength - 1\n  var mul = 1\n  this[offset + i] = value & 0xFF\n  while (--i >= 0 && (mul *= 0x100)) {\n    this[offset + i] = (value / mul) & 0xFF\n  }\n\n  return offset + byteLength\n}\n\nBuffer.prototype.writeUInt8 = function writeUInt8 (value, offset, noAssert) {\n  value = +value\n  offset = offset | 0\n  if (!noAssert) checkInt(this, value, offset, 1, 0xff, 0)\n  if (!Buffer.TYPED_ARRAY_SUPPORT) value = Math.floor(value)\n  this[offset] = (value & 0xff)\n  return offset + 1\n}\n\nfunction objectWriteUInt16 (buf, value, offset, littleEndian) {\n  if (value < 0) value = 0xffff + value + 1\n  for (var i = 0, j = Math.min(buf.length - offset, 2); i < j; ++i) {\n    buf[offset + i] = (value & (0xff << (8 * (littleEndian ? i : 1 - i)))) >>>\n      (littleEndian ? i : 1 - i) * 8\n  }\n}\n\nBuffer.prototype.writeUInt16LE = function writeUInt16LE (value, offset, noAssert) {\n  value = +value\n  offset = offset | 0\n  if (!noAssert) checkInt(this, value, offset, 2, 0xffff, 0)\n  if (Buffer.TYPED_ARRAY_SUPPORT) {\n    this[offset] = (value & 0xff)\n    this[offset + 1] = (value >>> 8)\n  } else {\n    objectWriteUInt16(this, value, offset, true)\n  }\n  return offset + 2\n}\n\nBuffer.prototype.writeUInt16BE = function writeUInt16BE (value, offset, noAssert) {\n  value = +value\n  offset = offset | 0\n  if (!noAssert) checkInt(this, value, offset, 2, 0xffff, 0)\n  if (Buffer.TYPED_ARRAY_SUPPORT) {\n    this[offset] = (value >>> 8)\n    this[offset + 1] = (value & 0xff)\n  } else {\n    objectWriteUInt16(this, value, offset, false)\n  }\n  return offset + 2\n}\n\nfunction objectWriteUInt32 (buf, value, offset, littleEndian) {\n  if (value < 0) value = 0xffffffff + value + 1\n  for (var i = 0, j = Math.min(buf.length - offset, 4); i < j; ++i) {\n    buf[offset + i] = (value >>> (littleEndian ? i : 3 - i) * 8) & 0xff\n  }\n}\n\nBuffer.prototype.writeUInt32LE = function writeUInt32LE (value, offset, noAssert) {\n  value = +value\n  offset = offset | 0\n  if (!noAssert) checkInt(this, value, offset, 4, 0xffffffff, 0)\n  if (Buffer.TYPED_ARRAY_SUPPORT) {\n    this[offset + 3] = (value >>> 24)\n    this[offset + 2] = (value >>> 16)\n    this[offset + 1] = (value >>> 8)\n    this[offset] = (value & 0xff)\n  } else {\n    objectWriteUInt32(this, value, offset, true)\n  }\n  return offset + 4\n}\n\nBuffer.prototype.writeUInt32BE = function writeUInt32BE (value, offset, noAssert) {\n  value = +value\n  offset = offset | 0\n  if (!noAssert) checkInt(this, value, offset, 4, 0xffffffff, 0)\n  if (Buffer.TYPED_ARRAY_SUPPORT) {\n    this[offset] = (value >>> 24)\n    this[offset + 1] = (value >>> 16)\n    this[offset + 2] = (value >>> 8)\n    this[offset + 3] = (value & 0xff)\n  } else {\n    objectWriteUInt32(this, value, offset, false)\n  }\n  return offset + 4\n}\n\nBuffer.prototype.writeIntLE = function writeIntLE (value, offset, byteLength, noAssert) {\n  value = +value\n  offset = offset | 0\n  if (!noAssert) {\n    var limit = Math.pow(2, 8 * byteLength - 1)\n\n    checkInt(this, value, offset, byteLength, limit - 1, -limit)\n  }\n\n  var i = 0\n  var mul = 1\n  var sub = 0\n  this[offset] = value & 0xFF\n  while (++i < byteLength && (mul *= 0x100)) {\n    if (value < 0 && sub === 0 && this[offset + i - 1] !== 0) {\n      sub = 1\n    }\n    this[offset + i] = ((value / mul) >> 0) - sub & 0xFF\n  }\n\n  return offset + byteLength\n}\n\nBuffer.prototype.writeIntBE = function writeIntBE (value, offset, byteLength, noAssert) {\n  value = +value\n  offset = offset | 0\n  if (!noAssert) {\n    var limit = Math.pow(2, 8 * byteLength - 1)\n\n    checkInt(this, value, offset, byteLength, limit - 1, -limit)\n  }\n\n  var i = byteLength - 1\n  var mul = 1\n  var sub = 0\n  this[offset + i] = value & 0xFF\n  while (--i >= 0 && (mul *= 0x100)) {\n    if (value < 0 && sub === 0 && this[offset + i + 1] !== 0) {\n      sub = 1\n    }\n    this[offset + i] = ((value / mul) >> 0) - sub & 0xFF\n  }\n\n  return offset + byteLength\n}\n\nBuffer.prototype.writeInt8 = function writeInt8 (value, offset, noAssert) {\n  value = +value\n  offset = offset | 0\n  if (!noAssert) checkInt(this, value, offset, 1, 0x7f, -0x80)\n  if (!Buffer.TYPED_ARRAY_SUPPORT) value = Math.floor(value)\n  if (value < 0) value = 0xff + value + 1\n  this[offset] = (value & 0xff)\n  return offset + 1\n}\n\nBuffer.prototype.writeInt16LE = function writeInt16LE (value, offset, noAssert) {\n  value = +value\n  offset = offset | 0\n  if (!noAssert) checkInt(this, value, offset, 2, 0x7fff, -0x8000)\n  if (Buffer.TYPED_ARRAY_SUPPORT) {\n    this[offset] = (value & 0xff)\n    this[offset + 1] = (value >>> 8)\n  } else {\n    objectWriteUInt16(this, value, offset, true)\n  }\n  return offset + 2\n}\n\nBuffer.prototype.writeInt16BE = function writeInt16BE (value, offset, noAssert) {\n  value = +value\n  offset = offset | 0\n  if (!noAssert) checkInt(this, value, offset, 2, 0x7fff, -0x8000)\n  if (Buffer.TYPED_ARRAY_SUPPORT) {\n    this[offset] = (value >>> 8)\n    this[offset + 1] = (value & 0xff)\n  } else {\n    objectWriteUInt16(this, value, offset, false)\n  }\n  return offset + 2\n}\n\nBuffer.prototype.writeInt32LE = function writeInt32LE (value, offset, noAssert) {\n  value = +value\n  offset = offset | 0\n  if (!noAssert) checkInt(this, value, offset, 4, 0x7fffffff, -0x80000000)\n  if (Buffer.TYPED_ARRAY_SUPPORT) {\n    this[offset] = (value & 0xff)\n    this[offset + 1] = (value >>> 8)\n    this[offset + 2] = (value >>> 16)\n    this[offset + 3] = (value >>> 24)\n  } else {\n    objectWriteUInt32(this, value, offset, true)\n  }\n  return offset + 4\n}\n\nBuffer.prototype.writeInt32BE = function writeInt32BE (value, offset, noAssert) {\n  value = +value\n  offset = offset | 0\n  if (!noAssert) checkInt(this, value, offset, 4, 0x7fffffff, -0x80000000)\n  if (value < 0) value = 0xffffffff + value + 1\n  if (Buffer.TYPED_ARRAY_SUPPORT) {\n    this[offset] = (value >>> 24)\n    this[offset + 1] = (value >>> 16)\n    this[offset + 2] = (value >>> 8)\n    this[offset + 3] = (value & 0xff)\n  } else {\n    objectWriteUInt32(this, value, offset, false)\n  }\n  return offset + 4\n}\n\nfunction checkIEEE754 (buf, value, offset, ext, max, min) {\n  if (offset + ext > buf.length) throw new RangeError('Index out of range')\n  if (offset < 0) throw new RangeError('Index out of range')\n}\n\nfunction writeFloat (buf, value, offset, littleEndian, noAssert) {\n  if (!noAssert) {\n    checkIEEE754(buf, value, offset, 4, 3.4028234663852886e+38, -3.4028234663852886e+38)\n  }\n  ieee754.write(buf, value, offset, littleEndian, 23, 4)\n  return offset + 4\n}\n\nBuffer.prototype.writeFloatLE = function writeFloatLE (value, offset, noAssert) {\n  return writeFloat(this, value, offset, true, noAssert)\n}\n\nBuffer.prototype.writeFloatBE = function writeFloatBE (value, offset, noAssert) {\n  return writeFloat(this, value, offset, false, noAssert)\n}\n\nfunction writeDouble (buf, value, offset, littleEndian, noAssert) {\n  if (!noAssert) {\n    checkIEEE754(buf, value, offset, 8, 1.7976931348623157E+308, -1.7976931348623157E+308)\n  }\n  ieee754.write(buf, value, offset, littleEndian, 52, 8)\n  return offset + 8\n}\n\nBuffer.prototype.writeDoubleLE = function writeDoubleLE (value, offset, noAssert) {\n  return writeDouble(this, value, offset, true, noAssert)\n}\n\nBuffer.prototype.writeDoubleBE = function writeDoubleBE (value, offset, noAssert) {\n  return writeDouble(this, value, offset, false, noAssert)\n}\n\n// copy(targetBuffer, targetStart=0, sourceStart=0, sourceEnd=buffer.length)\nBuffer.prototype.copy = function copy (target, targetStart, start, end) {\n  if (!start) start = 0\n  if (!end && end !== 0) end = this.length\n  if (targetStart >= target.length) targetStart = target.length\n  if (!targetStart) targetStart = 0\n  if (end > 0 && end < start) end = start\n\n  // Copy 0 bytes; we're done\n  if (end === start) return 0\n  if (target.length === 0 || this.length === 0) return 0\n\n  // Fatal error conditions\n  if (targetStart < 0) {\n    throw new RangeError('targetStart out of bounds')\n  }\n  if (start < 0 || start >= this.length) throw new RangeError('sourceStart out of bounds')\n  if (end < 0) throw new RangeError('sourceEnd out of bounds')\n\n  // Are we oob?\n  if (end > this.length) end = this.length\n  if (target.length - targetStart < end - start) {\n    end = target.length - targetStart + start\n  }\n\n  var len = end - start\n  var i\n\n  if (this === target && start < targetStart && targetStart < end) {\n    // descending copy from end\n    for (i = len - 1; i >= 0; --i) {\n      target[i + targetStart] = this[i + start]\n    }\n  } else if (len < 1000 || !Buffer.TYPED_ARRAY_SUPPORT) {\n    // ascending copy from start\n    for (i = 0; i < len; ++i) {\n      target[i + targetStart] = this[i + start]\n    }\n  } else {\n    Uint8Array.prototype.set.call(\n      target,\n      this.subarray(start, start + len),\n      targetStart\n    )\n  }\n\n  return len\n}\n\n// Usage:\n//    buffer.fill(number[, offset[, end]])\n//    buffer.fill(buffer[, offset[, end]])\n//    buffer.fill(string[, offset[, end]][, encoding])\nBuffer.prototype.fill = function fill (val, start, end, encoding) {\n  // Handle string cases:\n  if (typeof val === 'string') {\n    if (typeof start === 'string') {\n      encoding = start\n      start = 0\n      end = this.length\n    } else if (typeof end === 'string') {\n      encoding = end\n      end = this.length\n    }\n    if (val.length === 1) {\n      var code = val.charCodeAt(0)\n      if (code < 256) {\n        val = code\n      }\n    }\n    if (encoding !== undefined && typeof encoding !== 'string') {\n      throw new TypeError('encoding must be a string')\n    }\n    if (typeof encoding === 'string' && !Buffer.isEncoding(encoding)) {\n      throw new TypeError('Unknown encoding: ' + encoding)\n    }\n  } else if (typeof val === 'number') {\n    val = val & 255\n  }\n\n  // Invalid ranges are not set to a default, so can range check early.\n  if (start < 0 || this.length < start || this.length < end) {\n    throw new RangeError('Out of range index')\n  }\n\n  if (end <= start) {\n    return this\n  }\n\n  start = start >>> 0\n  end = end === undefined ? this.length : end >>> 0\n\n  if (!val) val = 0\n\n  var i\n  if (typeof val === 'number') {\n    for (i = start; i < end; ++i) {\n      this[i] = val\n    }\n  } else {\n    var bytes = Buffer.isBuffer(val)\n      ? val\n      : utf8ToBytes(new Buffer(val, encoding).toString())\n    var len = bytes.length\n    for (i = 0; i < end - start; ++i) {\n      this[i + start] = bytes[i % len]\n    }\n  }\n\n  return this\n}\n\n// HELPER FUNCTIONS\n// ================\n\nvar INVALID_BASE64_RE = /[^+\\/0-9A-Za-z-_]/g\n\nfunction base64clean (str) {\n  // Node strips out invalid characters like \\n and \\t from the string, base64-js does not\n  str = stringtrim(str).replace(INVALID_BASE64_RE, '')\n  // Node converts strings with length < 2 to ''\n  if (str.length < 2) return ''\n  // Node allows for non-padded base64 strings (missing trailing ===), base64-js does not\n  while (str.length % 4 !== 0) {\n    str = str + '='\n  }\n  return str\n}\n\nfunction stringtrim (str) {\n  if (str.trim) return str.trim()\n  return str.replace(/^\\s+|\\s+$/g, '')\n}\n\nfunction toHex (n) {\n  if (n < 16) return '0' + n.toString(16)\n  return n.toString(16)\n}\n\nfunction utf8ToBytes (string, units) {\n  units = units || Infinity\n  var codePoint\n  var length = string.length\n  var leadSurrogate = null\n  var bytes = []\n\n  for (var i = 0; i < length; ++i) {\n    codePoint = string.charCodeAt(i)\n\n    // is surrogate component\n    if (codePoint > 0xD7FF && codePoint < 0xE000) {\n      // last char was a lead\n      if (!leadSurrogate) {\n        // no lead yet\n        if (codePoint > 0xDBFF) {\n          // unexpected trail\n          if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD)\n          continue\n        } else if (i + 1 === length) {\n          // unpaired lead\n          if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD)\n          continue\n        }\n\n        // valid lead\n        leadSurrogate = codePoint\n\n        continue\n      }\n\n      // 2 leads in a row\n      if (codePoint < 0xDC00) {\n        if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD)\n        leadSurrogate = codePoint\n        continue\n      }\n\n      // valid surrogate pair\n      codePoint = (leadSurrogate - 0xD800 << 10 | codePoint - 0xDC00) + 0x10000\n    } else if (leadSurrogate) {\n      // valid bmp char, but last char was a lead\n      if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD)\n    }\n\n    leadSurrogate = null\n\n    // encode utf8\n    if (codePoint < 0x80) {\n      if ((units -= 1) < 0) break\n      bytes.push(codePoint)\n    } else if (codePoint < 0x800) {\n      if ((units -= 2) < 0) break\n      bytes.push(\n        codePoint >> 0x6 | 0xC0,\n        codePoint & 0x3F | 0x80\n      )\n    } else if (codePoint < 0x10000) {\n      if ((units -= 3) < 0) break\n      bytes.push(\n        codePoint >> 0xC | 0xE0,\n        codePoint >> 0x6 & 0x3F | 0x80,\n        codePoint & 0x3F | 0x80\n      )\n    } else if (codePoint < 0x110000) {\n      if ((units -= 4) < 0) break\n      bytes.push(\n        codePoint >> 0x12 | 0xF0,\n        codePoint >> 0xC & 0x3F | 0x80,\n        codePoint >> 0x6 & 0x3F | 0x80,\n        codePoint & 0x3F | 0x80\n      )\n    } else {\n      throw new Error('Invalid code point')\n    }\n  }\n\n  return bytes\n}\n\nfunction asciiToBytes (str) {\n  var byteArray = []\n  for (var i = 0; i < str.length; ++i) {\n    // Node's code seems to be doing this and not & 0x7F..\n    byteArray.push(str.charCodeAt(i) & 0xFF)\n  }\n  return byteArray\n}\n\nfunction utf16leToBytes (str, units) {\n  var c, hi, lo\n  var byteArray = []\n  for (var i = 0; i < str.length; ++i) {\n    if ((units -= 2) < 0) break\n\n    c = str.charCodeAt(i)\n    hi = c >> 8\n    lo = c % 256\n    byteArray.push(lo)\n    byteArray.push(hi)\n  }\n\n  return byteArray\n}\n\nfunction base64ToBytes (str) {\n  return base64.toByteArray(base64clean(str))\n}\n\nfunction blitBuffer (src, dst, offset, length) {\n  for (var i = 0; i < length; ++i) {\n    if ((i + offset >= dst.length) || (i >= src.length)) break\n    dst[i + offset] = src[i]\n  }\n  return i\n}\n\nfunction isnan (val) {\n  return val !== val // eslint-disable-line no-self-compare\n}\n\n}).call(this,typeof global !== \"undefined\" ? global : typeof self !== \"undefined\" ? self : typeof window !== \"undefined\" ? window : {})\n},{\"base64-js\":39,\"ieee754\":50,\"isarray\":53}],45:[function(require,module,exports){\n(function (Buffer){\n// Copyright Joyent, Inc. and other Node contributors.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a\n// copy of this software and associated documentation files (the\n// \"Software\"), to deal in the Software without restriction, including\n// without limitation the rights to use, copy, modify, merge, publish,\n// distribute, sublicense, and/or sell copies of the Software, and to permit\n// persons to whom the Software is furnished to do so, subject to the\n// following conditions:\n//\n// The above copyright notice and this permission notice shall be included\n// in all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS\n// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN\n// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,\n// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE\n// USE OR OTHER DEALINGS IN THE SOFTWARE.\n\n// NOTE: These type checking functions intentionally don't use `instanceof`\n// because it is fragile and can be easily faked with `Object.create()`.\n\nfunction isArray(arg) {\n  if (Array.isArray) {\n    return Array.isArray(arg);\n  }\n  return objectToString(arg) === '[object Array]';\n}\nexports.isArray = isArray;\n\nfunction isBoolean(arg) {\n  return typeof arg === 'boolean';\n}\nexports.isBoolean = isBoolean;\n\nfunction isNull(arg) {\n  return arg === null;\n}\nexports.isNull = isNull;\n\nfunction isNullOrUndefined(arg) {\n  return arg == null;\n}\nexports.isNullOrUndefined = isNullOrUndefined;\n\nfunction isNumber(arg) {\n  return typeof arg === 'number';\n}\nexports.isNumber = isNumber;\n\nfunction isString(arg) {\n  return typeof arg === 'string';\n}\nexports.isString = isString;\n\nfunction isSymbol(arg) {\n  return typeof arg === 'symbol';\n}\nexports.isSymbol = isSymbol;\n\nfunction isUndefined(arg) {\n  return arg === void 0;\n}\nexports.isUndefined = isUndefined;\n\nfunction isRegExp(re) {\n  return objectToString(re) === '[object RegExp]';\n}\nexports.isRegExp = isRegExp;\n\nfunction isObject(arg) {\n  return typeof arg === 'object' && arg !== null;\n}\nexports.isObject = isObject;\n\nfunction isDate(d) {\n  return objectToString(d) === '[object Date]';\n}\nexports.isDate = isDate;\n\nfunction isError(e) {\n  return (objectToString(e) === '[object Error]' || e instanceof Error);\n}\nexports.isError = isError;\n\nfunction isFunction(arg) {\n  return typeof arg === 'function';\n}\nexports.isFunction = isFunction;\n\nfunction isPrimitive(arg) {\n  return arg === null ||\n         typeof arg === 'boolean' ||\n         typeof arg === 'number' ||\n         typeof arg === 'string' ||\n         typeof arg === 'symbol' ||  // ES6 symbol\n         typeof arg === 'undefined';\n}\nexports.isPrimitive = isPrimitive;\n\nexports.isBuffer = Buffer.isBuffer;\n\nfunction objectToString(o) {\n  return Object.prototype.toString.call(o);\n}\n\n}).call(this,{\"isBuffer\":require(\"../../is-buffer/index.js\")})\n},{\"../../is-buffer/index.js\":52}],46:[function(require,module,exports){\n/* See LICENSE file for terms of use */\n\n/*\n * Text diff implementation.\n *\n * This library supports the following APIS:\n * JsDiff.diffChars: Character by character diff\n * JsDiff.diffWords: Word (as defined by \\b regex) diff which ignores whitespace\n * JsDiff.diffLines: Line based diff\n *\n * JsDiff.diffCss: Diff targeted at CSS content\n *\n * These methods are based on the implementation proposed in\n * \"An O(ND) Difference Algorithm and its Variations\" (Myers, 1986).\n * http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.4.6927\n */\n(function(global, undefined) {\n  var objectPrototypeToString = Object.prototype.toString;\n\n  /*istanbul ignore next*/\n  function map(arr, mapper, that) {\n    if (Array.prototype.map) {\n      return Array.prototype.map.call(arr, mapper, that);\n    }\n\n    var other = new Array(arr.length);\n\n    for (var i = 0, n = arr.length; i < n; i++) {\n      other[i] = mapper.call(that, arr[i], i, arr);\n    }\n    return other;\n  }\n  function clonePath(path) {\n    return { newPos: path.newPos, components: path.components.slice(0) };\n  }\n  function removeEmpty(array) {\n    var ret = [];\n    for (var i = 0; i < array.length; i++) {\n      if (array[i]) {\n        ret.push(array[i]);\n      }\n    }\n    return ret;\n  }\n  function escapeHTML(s) {\n    var n = s;\n    n = n.replace(/&/g, '&amp;');\n    n = n.replace(/</g, '&lt;');\n    n = n.replace(/>/g, '&gt;');\n    n = n.replace(/\"/g, '&quot;');\n\n    return n;\n  }\n\n  // This function handles the presence of circular references by bailing out when encountering an\n  // object that is already on the \"stack\" of items being processed.\n  function canonicalize(obj, stack, replacementStack) {\n    stack = stack || [];\n    replacementStack = replacementStack || [];\n\n    var i;\n\n    for (i = 0; i < stack.length; i += 1) {\n      if (stack[i] === obj) {\n        return replacementStack[i];\n      }\n    }\n\n    var canonicalizedObj;\n\n    if ('[object Array]' === objectPrototypeToString.call(obj)) {\n      stack.push(obj);\n      canonicalizedObj = new Array(obj.length);\n      replacementStack.push(canonicalizedObj);\n      for (i = 0; i < obj.length; i += 1) {\n        canonicalizedObj[i] = canonicalize(obj[i], stack, replacementStack);\n      }\n      stack.pop();\n      replacementStack.pop();\n    } else if (typeof obj === 'object' && obj !== null) {\n      stack.push(obj);\n      canonicalizedObj = {};\n      replacementStack.push(canonicalizedObj);\n      var sortedKeys = [],\n          key;\n      for (key in obj) {\n        sortedKeys.push(key);\n      }\n      sortedKeys.sort();\n      for (i = 0; i < sortedKeys.length; i += 1) {\n        key = sortedKeys[i];\n        canonicalizedObj[key] = canonicalize(obj[key], stack, replacementStack);\n      }\n      stack.pop();\n      replacementStack.pop();\n    } else {\n      canonicalizedObj = obj;\n    }\n    return canonicalizedObj;\n  }\n\n  function buildValues(components, newString, oldString, useLongestToken) {\n    var componentPos = 0,\n        componentLen = components.length,\n        newPos = 0,\n        oldPos = 0;\n\n    for (; componentPos < componentLen; componentPos++) {\n      var component = components[componentPos];\n      if (!component.removed) {\n        if (!component.added && useLongestToken) {\n          var value = newString.slice(newPos, newPos + component.count);\n          value = map(value, function(value, i) {\n            var oldValue = oldString[oldPos + i];\n            return oldValue.length > value.length ? oldValue : value;\n          });\n\n          component.value = value.join('');\n        } else {\n          component.value = newString.slice(newPos, newPos + component.count).join('');\n        }\n        newPos += component.count;\n\n        // Common case\n        if (!component.added) {\n          oldPos += component.count;\n        }\n      } else {\n        component.value = oldString.slice(oldPos, oldPos + component.count).join('');\n        oldPos += component.count;\n\n        // Reverse add and remove so removes are output first to match common convention\n        // The diffing algorithm is tied to add then remove output and this is the simplest\n        // route to get the desired output with minimal overhead.\n        if (componentPos && components[componentPos - 1].added) {\n          var tmp = components[componentPos - 1];\n          components[componentPos - 1] = components[componentPos];\n          components[componentPos] = tmp;\n        }\n      }\n    }\n\n    return components;\n  }\n\n  function Diff(ignoreWhitespace) {\n    this.ignoreWhitespace = ignoreWhitespace;\n  }\n  Diff.prototype = {\n    diff: function(oldString, newString, callback) {\n      var self = this;\n\n      function done(value) {\n        if (callback) {\n          setTimeout(function() { callback(undefined, value); }, 0);\n          return true;\n        } else {\n          return value;\n        }\n      }\n\n      // Handle the identity case (this is due to unrolling editLength == 0\n      if (newString === oldString) {\n        return done([{ value: newString }]);\n      }\n      if (!newString) {\n        return done([{ value: oldString, removed: true }]);\n      }\n      if (!oldString) {\n        return done([{ value: newString, added: true }]);\n      }\n\n      newString = this.tokenize(newString);\n      oldString = this.tokenize(oldString);\n\n      var newLen = newString.length, oldLen = oldString.length;\n      var editLength = 1;\n      var maxEditLength = newLen + oldLen;\n      var bestPath = [{ newPos: -1, components: [] }];\n\n      // Seed editLength = 0, i.e. the content starts with the same values\n      var oldPos = this.extractCommon(bestPath[0], newString, oldString, 0);\n      if (bestPath[0].newPos + 1 >= newLen && oldPos + 1 >= oldLen) {\n        // Identity per the equality and tokenizer\n        return done([{value: newString.join('')}]);\n      }\n\n      // Main worker method. checks all permutations of a given edit length for acceptance.\n      function execEditLength() {\n        for (var diagonalPath = -1 * editLength; diagonalPath <= editLength; diagonalPath += 2) {\n          var basePath;\n          var addPath = bestPath[diagonalPath - 1],\n              removePath = bestPath[diagonalPath + 1],\n              oldPos = (removePath ? removePath.newPos : 0) - diagonalPath;\n          if (addPath) {\n            // No one else is going to attempt to use this value, clear it\n            bestPath[diagonalPath - 1] = undefined;\n          }\n\n          var canAdd = addPath && addPath.newPos + 1 < newLen,\n              canRemove = removePath && 0 <= oldPos && oldPos < oldLen;\n          if (!canAdd && !canRemove) {\n            // If this path is a terminal then prune\n            bestPath[diagonalPath] = undefined;\n            continue;\n          }\n\n          // Select the diagonal that we want to branch from. We select the prior\n          // path whose position in the new string is the farthest from the origin\n          // and does not pass the bounds of the diff graph\n          if (!canAdd || (canRemove && addPath.newPos < removePath.newPos)) {\n            basePath = clonePath(removePath);\n            self.pushComponent(basePath.components, undefined, true);\n          } else {\n            basePath = addPath;   // No need to clone, we've pulled it from the list\n            basePath.newPos++;\n            self.pushComponent(basePath.components, true, undefined);\n          }\n\n          oldPos = self.extractCommon(basePath, newString, oldString, diagonalPath);\n\n          // If we have hit the end of both strings, then we are done\n          if (basePath.newPos + 1 >= newLen && oldPos + 1 >= oldLen) {\n            return done(buildValues(basePath.components, newString, oldString, self.useLongestToken));\n          } else {\n            // Otherwise track this path as a potential candidate and continue.\n            bestPath[diagonalPath] = basePath;\n          }\n        }\n\n        editLength++;\n      }\n\n      // Performs the length of edit iteration. Is a bit fugly as this has to support the\n      // sync and async mode which is never fun. Loops over execEditLength until a value\n      // is produced.\n      if (callback) {\n        (function exec() {\n          setTimeout(function() {\n            // This should not happen, but we want to be safe.\n            /*istanbul ignore next */\n            if (editLength > maxEditLength) {\n              return callback();\n            }\n\n            if (!execEditLength()) {\n              exec();\n            }\n          }, 0);\n        }());\n      } else {\n        while (editLength <= maxEditLength) {\n          var ret = execEditLength();\n          if (ret) {\n            return ret;\n          }\n        }\n      }\n    },\n\n    pushComponent: function(components, added, removed) {\n      var last = components[components.length - 1];\n      if (last && last.added === added && last.removed === removed) {\n        // We need to clone here as the component clone operation is just\n        // as shallow array clone\n        components[components.length - 1] = {count: last.count + 1, added: added, removed: removed };\n      } else {\n        components.push({count: 1, added: added, removed: removed });\n      }\n    },\n    extractCommon: function(basePath, newString, oldString, diagonalPath) {\n      var newLen = newString.length,\n          oldLen = oldString.length,\n          newPos = basePath.newPos,\n          oldPos = newPos - diagonalPath,\n\n          commonCount = 0;\n      while (newPos + 1 < newLen && oldPos + 1 < oldLen && this.equals(newString[newPos + 1], oldString[oldPos + 1])) {\n        newPos++;\n        oldPos++;\n        commonCount++;\n      }\n\n      if (commonCount) {\n        basePath.components.push({count: commonCount});\n      }\n\n      basePath.newPos = newPos;\n      return oldPos;\n    },\n\n    equals: function(left, right) {\n      var reWhitespace = /\\S/;\n      return left === right || (this.ignoreWhitespace && !reWhitespace.test(left) && !reWhitespace.test(right));\n    },\n    tokenize: function(value) {\n      return value.split('');\n    }\n  };\n\n  var CharDiff = new Diff();\n\n  var WordDiff = new Diff(true);\n  var WordWithSpaceDiff = new Diff();\n  WordDiff.tokenize = WordWithSpaceDiff.tokenize = function(value) {\n    return removeEmpty(value.split(/(\\s+|\\b)/));\n  };\n\n  var CssDiff = new Diff(true);\n  CssDiff.tokenize = function(value) {\n    return removeEmpty(value.split(/([{}:;,]|\\s+)/));\n  };\n\n  var LineDiff = new Diff();\n\n  var TrimmedLineDiff = new Diff();\n  TrimmedLineDiff.ignoreTrim = true;\n\n  LineDiff.tokenize = TrimmedLineDiff.tokenize = function(value) {\n    var retLines = [],\n        lines = value.split(/^/m);\n    for (var i = 0; i < lines.length; i++) {\n      var line = lines[i],\n          lastLine = lines[i - 1],\n          lastLineLastChar = lastLine && lastLine[lastLine.length - 1];\n\n      // Merge lines that may contain windows new lines\n      if (line === '\\n' && lastLineLastChar === '\\r') {\n          retLines[retLines.length - 1] = retLines[retLines.length - 1].slice(0, -1) + '\\r\\n';\n      } else {\n        if (this.ignoreTrim) {\n          line = line.trim();\n          // add a newline unless this is the last line.\n          if (i < lines.length - 1) {\n            line += '\\n';\n          }\n        }\n        retLines.push(line);\n      }\n    }\n\n    return retLines;\n  };\n\n  var PatchDiff = new Diff();\n  PatchDiff.tokenize = function(value) {\n    var ret = [],\n        linesAndNewlines = value.split(/(\\n|\\r\\n)/);\n\n    // Ignore the final empty token that occurs if the string ends with a new line\n    if (!linesAndNewlines[linesAndNewlines.length - 1]) {\n      linesAndNewlines.pop();\n    }\n\n    // Merge the content and line separators into single tokens\n    for (var i = 0; i < linesAndNewlines.length; i++) {\n      var line = linesAndNewlines[i];\n\n      if (i % 2) {\n        ret[ret.length - 1] += line;\n      } else {\n        ret.push(line);\n      }\n    }\n    return ret;\n  };\n\n  var SentenceDiff = new Diff();\n  SentenceDiff.tokenize = function(value) {\n    return removeEmpty(value.split(/(\\S.+?[.!?])(?=\\s+|$)/));\n  };\n\n  var JsonDiff = new Diff();\n  // Discriminate between two lines of pretty-printed, serialized JSON where one of them has a\n  // dangling comma and the other doesn't. Turns out including the dangling comma yields the nicest output:\n  JsonDiff.useLongestToken = true;\n  JsonDiff.tokenize = LineDiff.tokenize;\n  JsonDiff.equals = function(left, right) {\n    return LineDiff.equals(left.replace(/,([\\r\\n])/g, '$1'), right.replace(/,([\\r\\n])/g, '$1'));\n  };\n\n  var JsDiff = {\n    Diff: Diff,\n\n    diffChars: function(oldStr, newStr, callback) { return CharDiff.diff(oldStr, newStr, callback); },\n    diffWords: function(oldStr, newStr, callback) { return WordDiff.diff(oldStr, newStr, callback); },\n    diffWordsWithSpace: function(oldStr, newStr, callback) { return WordWithSpaceDiff.diff(oldStr, newStr, callback); },\n    diffLines: function(oldStr, newStr, callback) { return LineDiff.diff(oldStr, newStr, callback); },\n    diffTrimmedLines: function(oldStr, newStr, callback) { return TrimmedLineDiff.diff(oldStr, newStr, callback); },\n\n    diffSentences: function(oldStr, newStr, callback) { return SentenceDiff.diff(oldStr, newStr, callback); },\n\n    diffCss: function(oldStr, newStr, callback) { return CssDiff.diff(oldStr, newStr, callback); },\n    diffJson: function(oldObj, newObj, callback) {\n      return JsonDiff.diff(\n        typeof oldObj === 'string' ? oldObj : JSON.stringify(canonicalize(oldObj), undefined, '  '),\n        typeof newObj === 'string' ? newObj : JSON.stringify(canonicalize(newObj), undefined, '  '),\n        callback\n      );\n    },\n\n    createTwoFilesPatch: function(oldFileName, newFileName, oldStr, newStr, oldHeader, newHeader) {\n      var ret = [];\n\n      if (oldFileName == newFileName) {\n        ret.push('Index: ' + oldFileName);\n      }\n      ret.push('===================================================================');\n      ret.push('--- ' + oldFileName + (typeof oldHeader === 'undefined' ? '' : '\\t' + oldHeader));\n      ret.push('+++ ' + newFileName + (typeof newHeader === 'undefined' ? '' : '\\t' + newHeader));\n\n      var diff = PatchDiff.diff(oldStr, newStr);\n      diff.push({value: '', lines: []});   // Append an empty value to make cleanup easier\n\n      // Formats a given set of lines for printing as context lines in a patch\n      function contextLines(lines) {\n        return map(lines, function(entry) { return ' ' + entry; });\n      }\n\n      // Outputs the no newline at end of file warning if needed\n      function eofNL(curRange, i, current) {\n        var last = diff[diff.length - 2],\n            isLast = i === diff.length - 2,\n            isLastOfType = i === diff.length - 3 && current.added !== last.added;\n\n        // Figure out if this is the last line for the given file and missing NL\n        if (!(/\\n$/.test(current.value)) && (isLast || isLastOfType)) {\n          curRange.push('\\\\ No newline at end of file');\n        }\n      }\n\n      var oldRangeStart = 0, newRangeStart = 0, curRange = [],\n          oldLine = 1, newLine = 1;\n      for (var i = 0; i < diff.length; i++) {\n        var current = diff[i],\n            lines = current.lines || current.value.replace(/\\n$/, '').split('\\n');\n        current.lines = lines;\n\n        if (current.added || current.removed) {\n          // If we have previous context, start with that\n          if (!oldRangeStart) {\n            var prev = diff[i - 1];\n            oldRangeStart = oldLine;\n            newRangeStart = newLine;\n\n            if (prev) {\n              curRange = contextLines(prev.lines.slice(-4));\n              oldRangeStart -= curRange.length;\n              newRangeStart -= curRange.length;\n            }\n          }\n\n          // Output our changes\n          curRange.push.apply(curRange, map(lines, function(entry) {\n            return (current.added ? '+' : '-') + entry;\n          }));\n          eofNL(curRange, i, current);\n\n          // Track the updated file position\n          if (current.added) {\n            newLine += lines.length;\n          } else {\n            oldLine += lines.length;\n          }\n        } else {\n          // Identical context lines. Track line changes\n          if (oldRangeStart) {\n            // Close out any changes that have been output (or join overlapping)\n            if (lines.length <= 8 && i < diff.length - 2) {\n              // Overlapping\n              curRange.push.apply(curRange, contextLines(lines));\n            } else {\n              // end the range and output\n              var contextSize = Math.min(lines.length, 4);\n              ret.push(\n                  '@@ -' + oldRangeStart + ',' + (oldLine - oldRangeStart + contextSize)\n                  + ' +' + newRangeStart + ',' + (newLine - newRangeStart + contextSize)\n                  + ' @@');\n              ret.push.apply(ret, curRange);\n              ret.push.apply(ret, contextLines(lines.slice(0, contextSize)));\n              if (lines.length <= 4) {\n                eofNL(ret, i, current);\n              }\n\n              oldRangeStart = 0;\n              newRangeStart = 0;\n              curRange = [];\n            }\n          }\n          oldLine += lines.length;\n          newLine += lines.length;\n        }\n      }\n\n      return ret.join('\\n') + '\\n';\n    },\n\n    createPatch: function(fileName, oldStr, newStr, oldHeader, newHeader) {\n      return JsDiff.createTwoFilesPatch(fileName, fileName, oldStr, newStr, oldHeader, newHeader);\n    },\n\n    applyPatch: function(oldStr, uniDiff) {\n      var diffstr = uniDiff.split('\\n'),\n          hunks = [],\n          i = 0,\n          remEOFNL = false,\n          addEOFNL = false;\n\n      // Skip to the first change hunk\n      while (i < diffstr.length && !(/^@@/.test(diffstr[i]))) {\n        i++;\n      }\n\n      // Parse the unified diff\n      for (; i < diffstr.length; i++) {\n        if (diffstr[i][0] === '@') {\n          var chnukHeader = diffstr[i].split(/@@ -(\\d+),(\\d+) \\+(\\d+),(\\d+) @@/);\n          hunks.unshift({\n            start: chnukHeader[3],\n            oldlength: +chnukHeader[2],\n            removed: [],\n            newlength: chnukHeader[4],\n            added: []\n          });\n        } else if (diffstr[i][0] === '+') {\n          hunks[0].added.push(diffstr[i].substr(1));\n        } else if (diffstr[i][0] === '-') {\n          hunks[0].removed.push(diffstr[i].substr(1));\n        } else if (diffstr[i][0] === ' ') {\n          hunks[0].added.push(diffstr[i].substr(1));\n          hunks[0].removed.push(diffstr[i].substr(1));\n        } else if (diffstr[i][0] === '\\\\') {\n          if (diffstr[i - 1][0] === '+') {\n            remEOFNL = true;\n          } else if (diffstr[i - 1][0] === '-') {\n            addEOFNL = true;\n          }\n        }\n      }\n\n      // Apply the diff to the input\n      var lines = oldStr.split('\\n');\n      for (i = hunks.length - 1; i >= 0; i--) {\n        var hunk = hunks[i];\n        // Sanity check the input string. Bail if we don't match.\n        for (var j = 0; j < hunk.oldlength; j++) {\n          if (lines[hunk.start - 1 + j] !== hunk.removed[j]) {\n            return false;\n          }\n        }\n        Array.prototype.splice.apply(lines, [hunk.start - 1, hunk.oldlength].concat(hunk.added));\n      }\n\n      // Handle EOFNL insertion/removal\n      if (remEOFNL) {\n        while (!lines[lines.length - 1]) {\n          lines.pop();\n        }\n      } else if (addEOFNL) {\n        lines.push('');\n      }\n      return lines.join('\\n');\n    },\n\n    convertChangesToXML: function(changes) {\n      var ret = [];\n      for (var i = 0; i < changes.length; i++) {\n        var change = changes[i];\n        if (change.added) {\n          ret.push('<ins>');\n        } else if (change.removed) {\n          ret.push('<del>');\n        }\n\n        ret.push(escapeHTML(change.value));\n\n        if (change.added) {\n          ret.push('</ins>');\n        } else if (change.removed) {\n          ret.push('</del>');\n        }\n      }\n      return ret.join('');\n    },\n\n    // See: http://code.google.com/p/google-diff-match-patch/wiki/API\n    convertChangesToDMP: function(changes) {\n      var ret = [],\n          change,\n          operation;\n      for (var i = 0; i < changes.length; i++) {\n        change = changes[i];\n        if (change.added) {\n          operation = 1;\n        } else if (change.removed) {\n          operation = -1;\n        } else {\n          operation = 0;\n        }\n\n        ret.push([operation, change.value]);\n      }\n      return ret;\n    },\n\n    canonicalize: canonicalize\n  };\n\n  /*istanbul ignore next */\n  /*global module */\n  if (typeof module !== 'undefined' && module.exports) {\n    module.exports = JsDiff;\n  } else if (false) {\n    /*global define */\n    define([], function() { return JsDiff; });\n  } else if (typeof global.JsDiff === 'undefined') {\n    global.JsDiff = JsDiff;\n  }\n}(this));\n\n},{}],47:[function(require,module,exports){\n'use strict';\n\nvar matchOperatorsRe = /[|\\\\{}()[\\]^$+*?.]/g;\n\nmodule.exports = function (str) {\n\tif (typeof str !== 'string') {\n\t\tthrow new TypeError('Expected a string');\n\t}\n\n\treturn str.replace(matchOperatorsRe, '\\\\$&');\n};\n\n},{}],48:[function(require,module,exports){\n// Copyright Joyent, Inc. and other Node contributors.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a\n// copy of this software and associated documentation files (the\n// \"Software\"), to deal in the Software without restriction, including\n// without limitation the rights to use, copy, modify, merge, publish,\n// distribute, sublicense, and/or sell copies of the Software, and to permit\n// persons to whom the Software is furnished to do so, subject to the\n// following conditions:\n//\n// The above copyright notice and this permission notice shall be included\n// in all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS\n// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN\n// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,\n// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE\n// USE OR OTHER DEALINGS IN THE SOFTWARE.\n\nfunction EventEmitter() {\n  this._events = this._events || {};\n  this._maxListeners = this._maxListeners || undefined;\n}\nmodule.exports = EventEmitter;\n\n// Backwards-compat with node 0.10.x\nEventEmitter.EventEmitter = EventEmitter;\n\nEventEmitter.prototype._events = undefined;\nEventEmitter.prototype._maxListeners = undefined;\n\n// By default EventEmitters will print a warning if more than 10 listeners are\n// added to it. This is a useful default which helps finding memory leaks.\nEventEmitter.defaultMaxListeners = 10;\n\n// Obviously not all Emitters should be limited to 10. This function allows\n// that to be increased. Set to zero for unlimited.\nEventEmitter.prototype.setMaxListeners = function(n) {\n  if (!isNumber(n) || n < 0 || isNaN(n))\n    throw TypeError('n must be a positive number');\n  this._maxListeners = n;\n  return this;\n};\n\nEventEmitter.prototype.emit = function(type) {\n  var er, handler, len, args, i, listeners;\n\n  if (!this._events)\n    this._events = {};\n\n  // If there is no 'error' event listener then throw.\n  if (type === 'error') {\n    if (!this._events.error ||\n        (isObject(this._events.error) && !this._events.error.length)) {\n      er = arguments[1];\n      if (er instanceof Error) {\n        throw er; // Unhandled 'error' event\n      } else {\n        // At least give some kind of context to the user\n        var err = new Error('Uncaught, unspecified \"error\" event. (' + er + ')');\n        err.context = er;\n        throw err;\n      }\n    }\n  }\n\n  handler = this._events[type];\n\n  if (isUndefined(handler))\n    return false;\n\n  if (isFunction(handler)) {\n    switch (arguments.length) {\n      // fast cases\n      case 1:\n        handler.call(this);\n        break;\n      case 2:\n        handler.call(this, arguments[1]);\n        break;\n      case 3:\n        handler.call(this, arguments[1], arguments[2]);\n        break;\n      // slower\n      default:\n        args = Array.prototype.slice.call(arguments, 1);\n        handler.apply(this, args);\n    }\n  } else if (isObject(handler)) {\n    args = Array.prototype.slice.call(arguments, 1);\n    listeners = handler.slice();\n    len = listeners.length;\n    for (i = 0; i < len; i++)\n      listeners[i].apply(this, args);\n  }\n\n  return true;\n};\n\nEventEmitter.prototype.addListener = function(type, listener) {\n  var m;\n\n  if (!isFunction(listener))\n    throw TypeError('listener must be a function');\n\n  if (!this._events)\n    this._events = {};\n\n  // To avoid recursion in the case that type === \"newListener\"! Before\n  // adding it to the listeners, first emit \"newListener\".\n  if (this._events.newListener)\n    this.emit('newListener', type,\n              isFunction(listener.listener) ?\n              listener.listener : listener);\n\n  if (!this._events[type])\n    // Optimize the case of one listener. Don't need the extra array object.\n    this._events[type] = listener;\n  else if (isObject(this._events[type]))\n    // If we've already got an array, just append.\n    this._events[type].push(listener);\n  else\n    // Adding the second element, need to change to array.\n    this._events[type] = [this._events[type], listener];\n\n  // Check for listener leak\n  if (isObject(this._events[type]) && !this._events[type].warned) {\n    if (!isUndefined(this._maxListeners)) {\n      m = this._maxListeners;\n    } else {\n      m = EventEmitter.defaultMaxListeners;\n    }\n\n    if (m && m > 0 && this._events[type].length > m) {\n      this._events[type].warned = true;\n      console.error('(node) warning: possible EventEmitter memory ' +\n                    'leak detected. %d listeners added. ' +\n                    'Use emitter.setMaxListeners() to increase limit.',\n                    this._events[type].length);\n      if (typeof console.trace === 'function') {\n        // not supported in IE 10\n        console.trace();\n      }\n    }\n  }\n\n  return this;\n};\n\nEventEmitter.prototype.on = EventEmitter.prototype.addListener;\n\nEventEmitter.prototype.once = function(type, listener) {\n  if (!isFunction(listener))\n    throw TypeError('listener must be a function');\n\n  var fired = false;\n\n  function g() {\n    this.removeListener(type, g);\n\n    if (!fired) {\n      fired = true;\n      listener.apply(this, arguments);\n    }\n  }\n\n  g.listener = listener;\n  this.on(type, g);\n\n  return this;\n};\n\n// emits a 'removeListener' event iff the listener was removed\nEventEmitter.prototype.removeListener = function(type, listener) {\n  var list, position, length, i;\n\n  if (!isFunction(listener))\n    throw TypeError('listener must be a function');\n\n  if (!this._events || !this._events[type])\n    return this;\n\n  list = this._events[type];\n  length = list.length;\n  position = -1;\n\n  if (list === listener ||\n      (isFunction(list.listener) && list.listener === listener)) {\n    delete this._events[type];\n    if (this._events.removeListener)\n      this.emit('removeListener', type, listener);\n\n  } else if (isObject(list)) {\n    for (i = length; i-- > 0;) {\n      if (list[i] === listener ||\n          (list[i].listener && list[i].listener === listener)) {\n        position = i;\n        break;\n      }\n    }\n\n    if (position < 0)\n      return this;\n\n    if (list.length === 1) {\n      list.length = 0;\n      delete this._events[type];\n    } else {\n      list.splice(position, 1);\n    }\n\n    if (this._events.removeListener)\n      this.emit('removeListener', type, listener);\n  }\n\n  return this;\n};\n\nEventEmitter.prototype.removeAllListeners = function(type) {\n  var key, listeners;\n\n  if (!this._events)\n    return this;\n\n  // not listening for removeListener, no need to emit\n  if (!this._events.removeListener) {\n    if (arguments.length === 0)\n      this._events = {};\n    else if (this._events[type])\n      delete this._events[type];\n    return this;\n  }\n\n  // emit removeListener for all listeners on all events\n  if (arguments.length === 0) {\n    for (key in this._events) {\n      if (key === 'removeListener') continue;\n      this.removeAllListeners(key);\n    }\n    this.removeAllListeners('removeListener');\n    this._events = {};\n    return this;\n  }\n\n  listeners = this._events[type];\n\n  if (isFunction(listeners)) {\n    this.removeListener(type, listeners);\n  } else if (listeners) {\n    // LIFO order\n    while (listeners.length)\n      this.removeListener(type, listeners[listeners.length - 1]);\n  }\n  delete this._events[type];\n\n  return this;\n};\n\nEventEmitter.prototype.listeners = function(type) {\n  var ret;\n  if (!this._events || !this._events[type])\n    ret = [];\n  else if (isFunction(this._events[type]))\n    ret = [this._events[type]];\n  else\n    ret = this._events[type].slice();\n  return ret;\n};\n\nEventEmitter.prototype.listenerCount = function(type) {\n  if (this._events) {\n    var evlistener = this._events[type];\n\n    if (isFunction(evlistener))\n      return 1;\n    else if (evlistener)\n      return evlistener.length;\n  }\n  return 0;\n};\n\nEventEmitter.listenerCount = function(emitter, type) {\n  return emitter.listenerCount(type);\n};\n\nfunction isFunction(arg) {\n  return typeof arg === 'function';\n}\n\nfunction isNumber(arg) {\n  return typeof arg === 'number';\n}\n\nfunction isObject(arg) {\n  return typeof arg === 'object' && arg !== null;\n}\n\nfunction isUndefined(arg) {\n  return arg === void 0;\n}\n\n},{}],49:[function(require,module,exports){\n(function (process){\n// Growl - Copyright TJ Holowaychuk <tj@vision-media.ca> (MIT Licensed)\n\n/**\n * Module dependencies.\n */\n\nvar exec = require('child_process').exec\n  , fs = require('fs')\n  , path = require('path')\n  , exists = fs.existsSync || path.existsSync\n  , os = require('os')\n  , quote = JSON.stringify\n  , cmd;\n\nfunction which(name) {\n  var paths = process.env.PATH.split(':');\n  var loc;\n\n  for (var i = 0, len = paths.length; i < len; ++i) {\n    loc = path.join(paths[i], name);\n    if (exists(loc)) return loc;\n  }\n}\n\nswitch(os.type()) {\n  case 'Darwin':\n    if (which('terminal-notifier')) {\n      cmd = {\n          type: \"Darwin-NotificationCenter\"\n        , pkg: \"terminal-notifier\"\n        , msg: '-message'\n        , title: '-title'\n        , subtitle: '-subtitle'\n        , icon: '-appIcon'\n        , sound:  '-sound'\n        , url: '-open'\n        , priority: {\n              cmd: '-execute'\n            , range: []\n          }\n      };\n    } else {\n      cmd = {\n          type: \"Darwin-Growl\"\n        , pkg: \"growlnotify\"\n        , msg: '-m'\n        , sticky: '--sticky'\n        , priority: {\n              cmd: '--priority'\n            , range: [\n                -2\n              , -1\n              , 0\n              , 1\n              , 2\n              , \"Very Low\"\n              , \"Moderate\"\n              , \"Normal\"\n              , \"High\"\n              , \"Emergency\"\n            ]\n          }\n      };\n    }\n    break;\n  case 'Linux':\n    if (which('growl')) {\n      cmd = {\n          type: \"Linux-Growl\"\n        , pkg: \"growl\"\n        , msg: '-m'\n        , title: '-title'\n        , subtitle: '-subtitle'\n        , host: {\n            cmd: '-H'\n          , hostname: '192.168.33.1'\n        }\n      };\n    } else {\n      cmd = {\n          type: \"Linux\"\n        , pkg: \"notify-send\"\n        , msg: ''\n        , sticky: '-t 0'\n        , icon: '-i'\n        , priority: {\n            cmd: '-u'\n          , range: [\n              \"low\"\n            , \"normal\"\n            , \"critical\"\n          ]\n        }\n      };\n    }\n    break;\n  case 'Windows_NT':\n    cmd = {\n        type: \"Windows\"\n      , pkg: \"growlnotify\"\n      , msg: ''\n      , sticky: '/s:true'\n      , title: '/t:'\n      , icon: '/i:'\n      , url: '/cu:'\n      , priority: {\n            cmd: '/p:'\n          , range: [\n              -2\n            , -1\n            , 0\n            , 1\n            , 2\n          ]\n        }\n    };\n    break;\n}\n\n/**\n * Expose `growl`.\n */\n\nexports = module.exports = growl;\n\n/**\n * Node-growl version.\n */\n\nexports.version = '1.4.1'\n\n/**\n * Send growl notification _msg_ with _options_.\n *\n * Options:\n *\n *  - title   Notification title\n *  - sticky  Make the notification stick (defaults to false)\n *  - priority  Specify an int or named key (default is 0)\n *  - name    Application name (defaults to growlnotify)\n *  - sound   Sound efect ( in OSx defined in preferences -> sound -> effects) * works only in OSX > 10.8x\n *  - image\n *    - path to an icon sets --iconpath\n *    - path to an image sets --image\n *    - capitalized word sets --appIcon\n *    - filename uses extname as --icon\n *    - otherwise treated as --icon\n *\n * Examples:\n *\n *   growl('New email')\n *   growl('5 new emails', { title: 'Thunderbird' })\n *   growl('5 new emails', { title: 'Thunderbird', sound: 'Purr' })\n *   growl('Email sent', function(){\n *     // ... notification sent\n *   })\n *\n * @param {string} msg\n * @param {object} options\n * @param {function} fn\n * @api public\n */\n\nfunction growl(msg, options, fn) {\n  var image\n    , args\n    , options = options || {}\n    , fn = fn || function(){};\n\n  if (options.exec) {\n    cmd = {\n        type: \"Custom\"\n      , pkg: options.exec\n      , range: []\n    };\n  }\n\n  // noop\n  if (!cmd) return fn(new Error('growl not supported on this platform'));\n  args = [cmd.pkg];\n\n  // image\n  if (image = options.image) {\n    switch(cmd.type) {\n      case 'Darwin-Growl':\n        var flag, ext = path.extname(image).substr(1)\n        flag = flag || ext == 'icns' && 'iconpath'\n        flag = flag || /^[A-Z]/.test(image) && 'appIcon'\n        flag = flag || /^png|gif|jpe?g$/.test(ext) && 'image'\n        flag = flag || ext && (image = ext) && 'icon'\n        flag = flag || 'icon'\n        args.push('--' + flag, quote(image))\n        break;\n      case 'Darwin-NotificationCenter':\n        args.push(cmd.icon, quote(image));\n        break;\n      case 'Linux':\n        args.push(cmd.icon, quote(image));\n        // libnotify defaults to sticky, set a hint for transient notifications\n        if (!options.sticky) args.push('--hint=int:transient:1');\n        break;\n      case 'Windows':\n        args.push(cmd.icon + quote(image));\n        break;\n    }\n  }\n\n  // sticky\n  if (options.sticky) args.push(cmd.sticky);\n\n  // priority\n  if (options.priority) {\n    var priority = options.priority + '';\n    var checkindexOf = cmd.priority.range.indexOf(priority);\n    if (~cmd.priority.range.indexOf(priority)) {\n      args.push(cmd.priority, options.priority);\n    }\n  }\n\n  //sound\n  if(options.sound && cmd.type === 'Darwin-NotificationCenter'){\n    args.push(cmd.sound, options.sound)\n  }\n\n  // name\n  if (options.name && cmd.type === \"Darwin-Growl\") {\n    args.push('--name', options.name);\n  }\n\n  switch(cmd.type) {\n    case 'Darwin-Growl':\n      args.push(cmd.msg);\n      args.push(quote(msg).replace(/\\\\n/g, '\\n'));\n      if (options.title) args.push(quote(options.title));\n      break;\n    case 'Darwin-NotificationCenter':\n      args.push(cmd.msg);\n      var stringifiedMsg = quote(msg);\n      var escapedMsg = stringifiedMsg.replace(/\\\\n/g, '\\n');\n      args.push(escapedMsg);\n      if (options.title) {\n        args.push(cmd.title);\n        args.push(quote(options.title));\n      }\n      if (options.subtitle) {\n        args.push(cmd.subtitle);\n        args.push(quote(options.subtitle));\n      }\n      if (options.url) {\n        args.push(cmd.url);\n        args.push(quote(options.url));\n      }\n      break;\n    case 'Linux-Growl':\n      args.push(cmd.msg);\n      args.push(quote(msg).replace(/\\\\n/g, '\\n'));\n      if (options.title) args.push(quote(options.title));\n      if (cmd.host) {\n        args.push(cmd.host.cmd, cmd.host.hostname)\n      }\n      break;\n    case 'Linux':\n      if (options.title) {\n        args.push(quote(options.title));\n        args.push(cmd.msg);\n        args.push(quote(msg).replace(/\\\\n/g, '\\n'));\n      } else {\n        args.push(quote(msg).replace(/\\\\n/g, '\\n'));\n      }\n      break;\n    case 'Windows':\n      args.push(quote(msg).replace(/\\\\n/g, '\\n'));\n      if (options.title) args.push(cmd.title + quote(options.title));\n      if (options.url) args.push(cmd.url + quote(options.url));\n      break;\n    case 'Custom':\n      args[0] = (function(origCommand) {\n        var message = options.title\n          ? options.title + ': ' + msg\n          : msg;\n        var command = origCommand.replace(/(^|[^%])%s/g, '$1' + quote(message));\n        if (command === origCommand) args.push(quote(message));\n        return command;\n      })(args[0]);\n      break;\n  }\n\n  // execute\n  exec(args.join(' '), fn);\n};\n\n}).call(this,require('_process'))\n},{\"_process\":67,\"child_process\":42,\"fs\":42,\"os\":65,\"path\":42}],50:[function(require,module,exports){\nexports.read = function (buffer, offset, isLE, mLen, nBytes) {\n  var e, m\n  var eLen = nBytes * 8 - mLen - 1\n  var eMax = (1 << eLen) - 1\n  var eBias = eMax >> 1\n  var nBits = -7\n  var i = isLE ? (nBytes - 1) : 0\n  var d = isLE ? -1 : 1\n  var s = buffer[offset + i]\n\n  i += d\n\n  e = s & ((1 << (-nBits)) - 1)\n  s >>= (-nBits)\n  nBits += eLen\n  for (; nBits > 0; e = e * 256 + buffer[offset + i], i += d, nBits -= 8) {}\n\n  m = e & ((1 << (-nBits)) - 1)\n  e >>= (-nBits)\n  nBits += mLen\n  for (; nBits > 0; m = m * 256 + buffer[offset + i], i += d, nBits -= 8) {}\n\n  if (e === 0) {\n    e = 1 - eBias\n  } else if (e === eMax) {\n    return m ? NaN : ((s ? -1 : 1) * Infinity)\n  } else {\n    m = m + Math.pow(2, mLen)\n    e = e - eBias\n  }\n  return (s ? -1 : 1) * m * Math.pow(2, e - mLen)\n}\n\nexports.write = function (buffer, value, offset, isLE, mLen, nBytes) {\n  var e, m, c\n  var eLen = nBytes * 8 - mLen - 1\n  var eMax = (1 << eLen) - 1\n  var eBias = eMax >> 1\n  var rt = (mLen === 23 ? Math.pow(2, -24) - Math.pow(2, -77) : 0)\n  var i = isLE ? 0 : (nBytes - 1)\n  var d = isLE ? 1 : -1\n  var s = value < 0 || (value === 0 && 1 / value < 0) ? 1 : 0\n\n  value = Math.abs(value)\n\n  if (isNaN(value) || value === Infinity) {\n    m = isNaN(value) ? 1 : 0\n    e = eMax\n  } else {\n    e = Math.floor(Math.log(value) / Math.LN2)\n    if (value * (c = Math.pow(2, -e)) < 1) {\n      e--\n      c *= 2\n    }\n    if (e + eBias >= 1) {\n      value += rt / c\n    } else {\n      value += rt * Math.pow(2, 1 - eBias)\n    }\n    if (value * c >= 2) {\n      e++\n      c /= 2\n    }\n\n    if (e + eBias >= eMax) {\n      m = 0\n      e = eMax\n    } else if (e + eBias >= 1) {\n      m = (value * c - 1) * Math.pow(2, mLen)\n      e = e + eBias\n    } else {\n      m = value * Math.pow(2, eBias - 1) * Math.pow(2, mLen)\n      e = 0\n    }\n  }\n\n  for (; mLen >= 8; buffer[offset + i] = m & 0xff, i += d, m /= 256, mLen -= 8) {}\n\n  e = (e << mLen) | m\n  eLen += mLen\n  for (; eLen > 0; buffer[offset + i] = e & 0xff, i += d, e /= 256, eLen -= 8) {}\n\n  buffer[offset + i - d] |= s * 128\n}\n\n},{}],51:[function(require,module,exports){\nif (typeof Object.create === 'function') {\n  // implementation from standard node.js 'util' module\n  module.exports = function inherits(ctor, superCtor) {\n    ctor.super_ = superCtor\n    ctor.prototype = Object.create(superCtor.prototype, {\n      constructor: {\n        value: ctor,\n        enumerable: false,\n        writable: true,\n        configurable: true\n      }\n    });\n  };\n} else {\n  // old school shim for old browsers\n  module.exports = function inherits(ctor, superCtor) {\n    ctor.super_ = superCtor\n    var TempCtor = function () {}\n    TempCtor.prototype = superCtor.prototype\n    ctor.prototype = new TempCtor()\n    ctor.prototype.constructor = ctor\n  }\n}\n\n},{}],52:[function(require,module,exports){\n/*!\n * Determine if an object is a Buffer\n *\n * @author   Feross Aboukhadijeh <feross@feross.org> <http://feross.org>\n * @license  MIT\n */\n\n// The _isBuffer check is for Safari 5-7 support, because it's missing\n// Object.prototype.constructor. Remove this eventually\nmodule.exports = function (obj) {\n  return obj != null && (isBuffer(obj) || isSlowBuffer(obj) || !!obj._isBuffer)\n}\n\nfunction isBuffer (obj) {\n  return !!obj.constructor && typeof obj.constructor.isBuffer === 'function' && obj.constructor.isBuffer(obj)\n}\n\n// For Node v0.10 support. Remove this eventually.\nfunction isSlowBuffer (obj) {\n  return typeof obj.readFloatLE === 'function' && typeof obj.slice === 'function' && isBuffer(obj.slice(0, 0))\n}\n\n},{}],53:[function(require,module,exports){\nvar toString = {}.toString;\n\nmodule.exports = Array.isArray || function (arr) {\n  return toString.call(arr) == '[object Array]';\n};\n\n},{}],54:[function(require,module,exports){\n(function (global){\n/*! JSON v3.3.2 | http://bestiejs.github.io/json3 | Copyright 2012-2014, Kit Cambridge | http://kit.mit-license.org */\n;(function () {\n  // Detect the `define` function exposed by asynchronous module loaders. The\n  // strict `define` check is necessary for compatibility with `r.js`.\n  var isLoader = false;\n\n  // A set of types used to distinguish objects from primitives.\n  var objectTypes = {\n    \"function\": true,\n    \"object\": true\n  };\n\n  // Detect the `exports` object exposed by CommonJS implementations.\n  var freeExports = objectTypes[typeof exports] && exports && !exports.nodeType && exports;\n\n  // Use the `global` object exposed by Node (including Browserify via\n  // `insert-module-globals`), Narwhal, and Ringo as the default context,\n  // and the `window` object in browsers. Rhino exports a `global` function\n  // instead.\n  var root = objectTypes[typeof window] && window || this,\n      freeGlobal = freeExports && objectTypes[typeof module] && module && !module.nodeType && typeof global == \"object\" && global;\n\n  if (freeGlobal && (freeGlobal[\"global\"] === freeGlobal || freeGlobal[\"window\"] === freeGlobal || freeGlobal[\"self\"] === freeGlobal)) {\n    root = freeGlobal;\n  }\n\n  // Public: Initializes JSON 3 using the given `context` object, attaching the\n  // `stringify` and `parse` functions to the specified `exports` object.\n  function runInContext(context, exports) {\n    context || (context = root[\"Object\"]());\n    exports || (exports = root[\"Object\"]());\n\n    // Native constructor aliases.\n    var Number = context[\"Number\"] || root[\"Number\"],\n        String = context[\"String\"] || root[\"String\"],\n        Object = context[\"Object\"] || root[\"Object\"],\n        Date = context[\"Date\"] || root[\"Date\"],\n        SyntaxError = context[\"SyntaxError\"] || root[\"SyntaxError\"],\n        TypeError = context[\"TypeError\"] || root[\"TypeError\"],\n        Math = context[\"Math\"] || root[\"Math\"],\n        nativeJSON = context[\"JSON\"] || root[\"JSON\"];\n\n    // Delegate to the native `stringify` and `parse` implementations.\n    if (typeof nativeJSON == \"object\" && nativeJSON) {\n      exports.stringify = nativeJSON.stringify;\n      exports.parse = nativeJSON.parse;\n    }\n\n    // Convenience aliases.\n    var objectProto = Object.prototype,\n        getClass = objectProto.toString,\n        isProperty, forEach, undef;\n\n    // Test the `Date#getUTC*` methods. Based on work by @Yaffle.\n    var isExtended = new Date(-3509827334573292);\n    try {\n      // The `getUTCFullYear`, `Month`, and `Date` methods return nonsensical\n      // results for certain dates in Opera >= 10.53.\n      isExtended = isExtended.getUTCFullYear() == -109252 && isExtended.getUTCMonth() === 0 && isExtended.getUTCDate() === 1 &&\n        // Safari < 2.0.2 stores the internal millisecond time value correctly,\n        // but clips the values returned by the date methods to the range of\n        // signed 32-bit integers ([-2 ** 31, 2 ** 31 - 1]).\n        isExtended.getUTCHours() == 10 && isExtended.getUTCMinutes() == 37 && isExtended.getUTCSeconds() == 6 && isExtended.getUTCMilliseconds() == 708;\n    } catch (exception) {}\n\n    // Internal: Determines whether the native `JSON.stringify` and `parse`\n    // implementations are spec-compliant. Based on work by Ken Snyder.\n    function has(name) {\n      if (has[name] !== undef) {\n        // Return cached feature test result.\n        return has[name];\n      }\n      var isSupported;\n      if (name == \"bug-string-char-index\") {\n        // IE <= 7 doesn't support accessing string characters using square\n        // bracket notation. IE 8 only supports this for primitives.\n        isSupported = \"a\"[0] != \"a\";\n      } else if (name == \"json\") {\n        // Indicates whether both `JSON.stringify` and `JSON.parse` are\n        // supported.\n        isSupported = has(\"json-stringify\") && has(\"json-parse\");\n      } else {\n        var value, serialized = '{\"a\":[1,true,false,null,\"\\\\u0000\\\\b\\\\n\\\\f\\\\r\\\\t\"]}';\n        // Test `JSON.stringify`.\n        if (name == \"json-stringify\") {\n          var stringify = exports.stringify, stringifySupported = typeof stringify == \"function\" && isExtended;\n          if (stringifySupported) {\n            // A test function object with a custom `toJSON` method.\n            (value = function () {\n              return 1;\n            }).toJSON = value;\n            try {\n              stringifySupported =\n                // Firefox 3.1b1 and b2 serialize string, number, and boolean\n                // primitives as object literals.\n                stringify(0) === \"0\" &&\n                // FF 3.1b1, b2, and JSON 2 serialize wrapped primitives as object\n                // literals.\n                stringify(new Number()) === \"0\" &&\n                stringify(new String()) == '\"\"' &&\n                // FF 3.1b1, 2 throw an error if the value is `null`, `undefined`, or\n                // does not define a canonical JSON representation (this applies to\n                // objects with `toJSON` properties as well, *unless* they are nested\n                // within an object or array).\n                stringify(getClass) === undef &&\n                // IE 8 serializes `undefined` as `\"undefined\"`. Safari <= 5.1.7 and\n                // FF 3.1b3 pass this test.\n                stringify(undef) === undef &&\n                // Safari <= 5.1.7 and FF 3.1b3 throw `Error`s and `TypeError`s,\n                // respectively, if the value is omitted entirely.\n                stringify() === undef &&\n                // FF 3.1b1, 2 throw an error if the given value is not a number,\n                // string, array, object, Boolean, or `null` literal. This applies to\n                // objects with custom `toJSON` methods as well, unless they are nested\n                // inside object or array literals. YUI 3.0.0b1 ignores custom `toJSON`\n                // methods entirely.\n                stringify(value) === \"1\" &&\n                stringify([value]) == \"[1]\" &&\n                // Prototype <= 1.6.1 serializes `[undefined]` as `\"[]\"` instead of\n                // `\"[null]\"`.\n                stringify([undef]) == \"[null]\" &&\n                // YUI 3.0.0b1 fails to serialize `null` literals.\n                stringify(null) == \"null\" &&\n                // FF 3.1b1, 2 halts serialization if an array contains a function:\n                // `[1, true, getClass, 1]` serializes as \"[1,true,],\". FF 3.1b3\n                // elides non-JSON values from objects and arrays, unless they\n                // define custom `toJSON` methods.\n                stringify([undef, getClass, null]) == \"[null,null,null]\" &&\n                // Simple serialization test. FF 3.1b1 uses Unicode escape sequences\n                // where character escape codes are expected (e.g., `\\b` => `\\u0008`).\n                stringify({ \"a\": [value, true, false, null, \"\\x00\\b\\n\\f\\r\\t\"] }) == serialized &&\n                // FF 3.1b1 and b2 ignore the `filter` and `width` arguments.\n                stringify(null, value) === \"1\" &&\n                stringify([1, 2], null, 1) == \"[\\n 1,\\n 2\\n]\" &&\n                // JSON 2, Prototype <= 1.7, and older WebKit builds incorrectly\n                // serialize extended years.\n                stringify(new Date(-8.64e15)) == '\"-271821-04-20T00:00:00.000Z\"' &&\n                // The milliseconds are optional in ES 5, but required in 5.1.\n                stringify(new Date(8.64e15)) == '\"+275760-09-13T00:00:00.000Z\"' &&\n                // Firefox <= 11.0 incorrectly serializes years prior to 0 as negative\n                // four-digit years instead of six-digit years. Credits: @Yaffle.\n                stringify(new Date(-621987552e5)) == '\"-000001-01-01T00:00:00.000Z\"' &&\n                // Safari <= 5.1.5 and Opera >= 10.53 incorrectly serialize millisecond\n                // values less than 1000. Credits: @Yaffle.\n                stringify(new Date(-1)) == '\"1969-12-31T23:59:59.999Z\"';\n            } catch (exception) {\n              stringifySupported = false;\n            }\n          }\n          isSupported = stringifySupported;\n        }\n        // Test `JSON.parse`.\n        if (name == \"json-parse\") {\n          var parse = exports.parse;\n          if (typeof parse == \"function\") {\n            try {\n              // FF 3.1b1, b2 will throw an exception if a bare literal is provided.\n              // Conforming implementations should also coerce the initial argument to\n              // a string prior to parsing.\n              if (parse(\"0\") === 0 && !parse(false)) {\n                // Simple parsing test.\n                value = parse(serialized);\n                var parseSupported = value[\"a\"].length == 5 && value[\"a\"][0] === 1;\n                if (parseSupported) {\n                  try {\n                    // Safari <= 5.1.2 and FF 3.1b1 allow unescaped tabs in strings.\n                    parseSupported = !parse('\"\\t\"');\n                  } catch (exception) {}\n                  if (parseSupported) {\n                    try {\n                      // FF 4.0 and 4.0.1 allow leading `+` signs and leading\n                      // decimal points. FF 4.0, 4.0.1, and IE 9-10 also allow\n                      // certain octal literals.\n                      parseSupported = parse(\"01\") !== 1;\n                    } catch (exception) {}\n                  }\n                  if (parseSupported) {\n                    try {\n                      // FF 4.0, 4.0.1, and Rhino 1.7R3-R4 allow trailing decimal\n                      // points. These environments, along with FF 3.1b1 and 2,\n                      // also allow trailing commas in JSON objects and arrays.\n                      parseSupported = parse(\"1.\") !== 1;\n                    } catch (exception) {}\n                  }\n                }\n              }\n            } catch (exception) {\n              parseSupported = false;\n            }\n          }\n          isSupported = parseSupported;\n        }\n      }\n      return has[name] = !!isSupported;\n    }\n\n    if (!has(\"json\")) {\n      // Common `[[Class]]` name aliases.\n      var functionClass = \"[object Function]\",\n          dateClass = \"[object Date]\",\n          numberClass = \"[object Number]\",\n          stringClass = \"[object String]\",\n          arrayClass = \"[object Array]\",\n          booleanClass = \"[object Boolean]\";\n\n      // Detect incomplete support for accessing string characters by index.\n      var charIndexBuggy = has(\"bug-string-char-index\");\n\n      // Define additional utility methods if the `Date` methods are buggy.\n      if (!isExtended) {\n        var floor = Math.floor;\n        // A mapping between the months of the year and the number of days between\n        // January 1st and the first of the respective month.\n        var Months = [0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334];\n        // Internal: Calculates the number of days between the Unix epoch and the\n        // first day of the given month.\n        var getDay = function (year, month) {\n          return Months[month] + 365 * (year - 1970) + floor((year - 1969 + (month = +(month > 1))) / 4) - floor((year - 1901 + month) / 100) + floor((year - 1601 + month) / 400);\n        };\n      }\n\n      // Internal: Determines if a property is a direct property of the given\n      // object. Delegates to the native `Object#hasOwnProperty` method.\n      if (!(isProperty = objectProto.hasOwnProperty)) {\n        isProperty = function (property) {\n          var members = {}, constructor;\n          if ((members.__proto__ = null, members.__proto__ = {\n            // The *proto* property cannot be set multiple times in recent\n            // versions of Firefox and SeaMonkey.\n            \"toString\": 1\n          }, members).toString != getClass) {\n            // Safari <= 2.0.3 doesn't implement `Object#hasOwnProperty`, but\n            // supports the mutable *proto* property.\n            isProperty = function (property) {\n              // Capture and break the object's prototype chain (see section 8.6.2\n              // of the ES 5.1 spec). The parenthesized expression prevents an\n              // unsafe transformation by the Closure Compiler.\n              var original = this.__proto__, result = property in (this.__proto__ = null, this);\n              // Restore the original prototype chain.\n              this.__proto__ = original;\n              return result;\n            };\n          } else {\n            // Capture a reference to the top-level `Object` constructor.\n            constructor = members.constructor;\n            // Use the `constructor` property to simulate `Object#hasOwnProperty` in\n            // other environments.\n            isProperty = function (property) {\n              var parent = (this.constructor || constructor).prototype;\n              return property in this && !(property in parent && this[property] === parent[property]);\n            };\n          }\n          members = null;\n          return isProperty.call(this, property);\n        };\n      }\n\n      // Internal: Normalizes the `for...in` iteration algorithm across\n      // environments. Each enumerated key is yielded to a `callback` function.\n      forEach = function (object, callback) {\n        var size = 0, Properties, members, property;\n\n        // Tests for bugs in the current environment's `for...in` algorithm. The\n        // `valueOf` property inherits the non-enumerable flag from\n        // `Object.prototype` in older versions of IE, Netscape, and Mozilla.\n        (Properties = function () {\n          this.valueOf = 0;\n        }).prototype.valueOf = 0;\n\n        // Iterate over a new instance of the `Properties` class.\n        members = new Properties();\n        for (property in members) {\n          // Ignore all properties inherited from `Object.prototype`.\n          if (isProperty.call(members, property)) {\n            size++;\n          }\n        }\n        Properties = members = null;\n\n        // Normalize the iteration algorithm.\n        if (!size) {\n          // A list of non-enumerable properties inherited from `Object.prototype`.\n          members = [\"valueOf\", \"toString\", \"toLocaleString\", \"propertyIsEnumerable\", \"isPrototypeOf\", \"hasOwnProperty\", \"constructor\"];\n          // IE <= 8, Mozilla 1.0, and Netscape 6.2 ignore shadowed non-enumerable\n          // properties.\n          forEach = function (object, callback) {\n            var isFunction = getClass.call(object) == functionClass, property, length;\n            var hasProperty = !isFunction && typeof object.constructor != \"function\" && objectTypes[typeof object.hasOwnProperty] && object.hasOwnProperty || isProperty;\n            for (property in object) {\n              // Gecko <= 1.0 enumerates the `prototype` property of functions under\n              // certain conditions; IE does not.\n              if (!(isFunction && property == \"prototype\") && hasProperty.call(object, property)) {\n                callback(property);\n              }\n            }\n            // Manually invoke the callback for each non-enumerable property.\n            for (length = members.length; property = members[--length]; hasProperty.call(object, property) && callback(property));\n          };\n        } else if (size == 2) {\n          // Safari <= 2.0.4 enumerates shadowed properties twice.\n          forEach = function (object, callback) {\n            // Create a set of iterated properties.\n            var members = {}, isFunction = getClass.call(object) == functionClass, property;\n            for (property in object) {\n              // Store each property name to prevent double enumeration. The\n              // `prototype` property of functions is not enumerated due to cross-\n              // environment inconsistencies.\n              if (!(isFunction && property == \"prototype\") && !isProperty.call(members, property) && (members[property] = 1) && isProperty.call(object, property)) {\n                callback(property);\n              }\n            }\n          };\n        } else {\n          // No bugs detected; use the standard `for...in` algorithm.\n          forEach = function (object, callback) {\n            var isFunction = getClass.call(object) == functionClass, property, isConstructor;\n            for (property in object) {\n              if (!(isFunction && property == \"prototype\") && isProperty.call(object, property) && !(isConstructor = property === \"constructor\")) {\n                callback(property);\n              }\n            }\n            // Manually invoke the callback for the `constructor` property due to\n            // cross-environment inconsistencies.\n            if (isConstructor || isProperty.call(object, (property = \"constructor\"))) {\n              callback(property);\n            }\n          };\n        }\n        return forEach(object, callback);\n      };\n\n      // Public: Serializes a JavaScript `value` as a JSON string. The optional\n      // `filter` argument may specify either a function that alters how object and\n      // array members are serialized, or an array of strings and numbers that\n      // indicates which properties should be serialized. The optional `width`\n      // argument may be either a string or number that specifies the indentation\n      // level of the output.\n      if (!has(\"json-stringify\")) {\n        // Internal: A map of control characters and their escaped equivalents.\n        var Escapes = {\n          92: \"\\\\\\\\\",\n          34: '\\\\\"',\n          8: \"\\\\b\",\n          12: \"\\\\f\",\n          10: \"\\\\n\",\n          13: \"\\\\r\",\n          9: \"\\\\t\"\n        };\n\n        // Internal: Converts `value` into a zero-padded string such that its\n        // length is at least equal to `width`. The `width` must be <= 6.\n        var leadingZeroes = \"000000\";\n        var toPaddedString = function (width, value) {\n          // The `|| 0` expression is necessary to work around a bug in\n          // Opera <= 7.54u2 where `0 == -0`, but `String(-0) !== \"0\"`.\n          return (leadingZeroes + (value || 0)).slice(-width);\n        };\n\n        // Internal: Double-quotes a string `value`, replacing all ASCII control\n        // characters (characters with code unit values between 0 and 31) with\n        // their escaped equivalents. This is an implementation of the\n        // `Quote(value)` operation defined in ES 5.1 section 15.12.3.\n        var unicodePrefix = \"\\\\u00\";\n        var quote = function (value) {\n          var result = '\"', index = 0, length = value.length, useCharIndex = !charIndexBuggy || length > 10;\n          var symbols = useCharIndex && (charIndexBuggy ? value.split(\"\") : value);\n          for (; index < length; index++) {\n            var charCode = value.charCodeAt(index);\n            // If the character is a control character, append its Unicode or\n            // shorthand escape sequence; otherwise, append the character as-is.\n            switch (charCode) {\n              case 8: case 9: case 10: case 12: case 13: case 34: case 92:\n                result += Escapes[charCode];\n                break;\n              default:\n                if (charCode < 32) {\n                  result += unicodePrefix + toPaddedString(2, charCode.toString(16));\n                  break;\n                }\n                result += useCharIndex ? symbols[index] : value.charAt(index);\n            }\n          }\n          return result + '\"';\n        };\n\n        // Internal: Recursively serializes an object. Implements the\n        // `Str(key, holder)`, `JO(value)`, and `JA(value)` operations.\n        var serialize = function (property, object, callback, properties, whitespace, indentation, stack) {\n          var value, className, year, month, date, time, hours, minutes, seconds, milliseconds, results, element, index, length, prefix, result;\n          try {\n            // Necessary for host object support.\n            value = object[property];\n          } catch (exception) {}\n          if (typeof value == \"object\" && value) {\n            className = getClass.call(value);\n            if (className == dateClass && !isProperty.call(value, \"toJSON\")) {\n              if (value > -1 / 0 && value < 1 / 0) {\n                // Dates are serialized according to the `Date#toJSON` method\n                // specified in ES 5.1 section 15.9.5.44. See section 15.9.1.15\n                // for the ISO 8601 date time string format.\n                if (getDay) {\n                  // Manually compute the year, month, date, hours, minutes,\n                  // seconds, and milliseconds if the `getUTC*` methods are\n                  // buggy. Adapted from @Yaffle's `date-shim` project.\n                  date = floor(value / 864e5);\n                  for (year = floor(date / 365.2425) + 1970 - 1; getDay(year + 1, 0) <= date; year++);\n                  for (month = floor((date - getDay(year, 0)) / 30.42); getDay(year, month + 1) <= date; month++);\n                  date = 1 + date - getDay(year, month);\n                  // The `time` value specifies the time within the day (see ES\n                  // 5.1 section 15.9.1.2). The formula `(A % B + B) % B` is used\n                  // to compute `A modulo B`, as the `%` operator does not\n                  // correspond to the `modulo` operation for negative numbers.\n                  time = (value % 864e5 + 864e5) % 864e5;\n                  // The hours, minutes, seconds, and milliseconds are obtained by\n                  // decomposing the time within the day. See section 15.9.1.10.\n                  hours = floor(time / 36e5) % 24;\n                  minutes = floor(time / 6e4) % 60;\n                  seconds = floor(time / 1e3) % 60;\n                  milliseconds = time % 1e3;\n                } else {\n                  year = value.getUTCFullYear();\n                  month = value.getUTCMonth();\n                  date = value.getUTCDate();\n                  hours = value.getUTCHours();\n                  minutes = value.getUTCMinutes();\n                  seconds = value.getUTCSeconds();\n                  milliseconds = value.getUTCMilliseconds();\n                }\n                // Serialize extended years correctly.\n                value = (year <= 0 || year >= 1e4 ? (year < 0 ? \"-\" : \"+\") + toPaddedString(6, year < 0 ? -year : year) : toPaddedString(4, year)) +\n                  \"-\" + toPaddedString(2, month + 1) + \"-\" + toPaddedString(2, date) +\n                  // Months, dates, hours, minutes, and seconds should have two\n                  // digits; milliseconds should have three.\n                  \"T\" + toPaddedString(2, hours) + \":\" + toPaddedString(2, minutes) + \":\" + toPaddedString(2, seconds) +\n                  // Milliseconds are optional in ES 5.0, but required in 5.1.\n                  \".\" + toPaddedString(3, milliseconds) + \"Z\";\n              } else {\n                value = null;\n              }\n            } else if (typeof value.toJSON == \"function\" && ((className != numberClass && className != stringClass && className != arrayClass) || isProperty.call(value, \"toJSON\"))) {\n              // Prototype <= 1.6.1 adds non-standard `toJSON` methods to the\n              // `Number`, `String`, `Date`, and `Array` prototypes. JSON 3\n              // ignores all `toJSON` methods on these objects unless they are\n              // defined directly on an instance.\n              value = value.toJSON(property);\n            }\n          }\n          if (callback) {\n            // If a replacement function was provided, call it to obtain the value\n            // for serialization.\n            value = callback.call(object, property, value);\n          }\n          if (value === null) {\n            return \"null\";\n          }\n          className = getClass.call(value);\n          if (className == booleanClass) {\n            // Booleans are represented literally.\n            return \"\" + value;\n          } else if (className == numberClass) {\n            // JSON numbers must be finite. `Infinity` and `NaN` are serialized as\n            // `\"null\"`.\n            return value > -1 / 0 && value < 1 / 0 ? \"\" + value : \"null\";\n          } else if (className == stringClass) {\n            // Strings are double-quoted and escaped.\n            return quote(\"\" + value);\n          }\n          // Recursively serialize objects and arrays.\n          if (typeof value == \"object\") {\n            // Check for cyclic structures. This is a linear search; performance\n            // is inversely proportional to the number of unique nested objects.\n            for (length = stack.length; length--;) {\n              if (stack[length] === value) {\n                // Cyclic structures cannot be serialized by `JSON.stringify`.\n                throw TypeError();\n              }\n            }\n            // Add the object to the stack of traversed objects.\n            stack.push(value);\n            results = [];\n            // Save the current indentation level and indent one additional level.\n            prefix = indentation;\n            indentation += whitespace;\n            if (className == arrayClass) {\n              // Recursively serialize array elements.\n              for (index = 0, length = value.length; index < length; index++) {\n                element = serialize(index, value, callback, properties, whitespace, indentation, stack);\n                results.push(element === undef ? \"null\" : element);\n              }\n              result = results.length ? (whitespace ? \"[\\n\" + indentation + results.join(\",\\n\" + indentation) + \"\\n\" + prefix + \"]\" : (\"[\" + results.join(\",\") + \"]\")) : \"[]\";\n            } else {\n              // Recursively serialize object members. Members are selected from\n              // either a user-specified list of property names, or the object\n              // itself.\n              forEach(properties || value, function (property) {\n                var element = serialize(property, value, callback, properties, whitespace, indentation, stack);\n                if (element !== undef) {\n                  // According to ES 5.1 section 15.12.3: \"If `gap` {whitespace}\n                  // is not the empty string, let `member` {quote(property) + \":\"}\n                  // be the concatenation of `member` and the `space` character.\"\n                  // The \"`space` character\" refers to the literal space\n                  // character, not the `space` {width} argument provided to\n                  // `JSON.stringify`.\n                  results.push(quote(property) + \":\" + (whitespace ? \" \" : \"\") + element);\n                }\n              });\n              result = results.length ? (whitespace ? \"{\\n\" + indentation + results.join(\",\\n\" + indentation) + \"\\n\" + prefix + \"}\" : (\"{\" + results.join(\",\") + \"}\")) : \"{}\";\n            }\n            // Remove the object from the traversed object stack.\n            stack.pop();\n            return result;\n          }\n        };\n\n        // Public: `JSON.stringify`. See ES 5.1 section 15.12.3.\n        exports.stringify = function (source, filter, width) {\n          var whitespace, callback, properties, className;\n          if (objectTypes[typeof filter] && filter) {\n            if ((className = getClass.call(filter)) == functionClass) {\n              callback = filter;\n            } else if (className == arrayClass) {\n              // Convert the property names array into a makeshift set.\n              properties = {};\n              for (var index = 0, length = filter.length, value; index < length; value = filter[index++], ((className = getClass.call(value)), className == stringClass || className == numberClass) && (properties[value] = 1));\n            }\n          }\n          if (width) {\n            if ((className = getClass.call(width)) == numberClass) {\n              // Convert the `width` to an integer and create a string containing\n              // `width` number of space characters.\n              if ((width -= width % 1) > 0) {\n                for (whitespace = \"\", width > 10 && (width = 10); whitespace.length < width; whitespace += \" \");\n              }\n            } else if (className == stringClass) {\n              whitespace = width.length <= 10 ? width : width.slice(0, 10);\n            }\n          }\n          // Opera <= 7.54u2 discards the values associated with empty string keys\n          // (`\"\"`) only if they are used directly within an object member list\n          // (e.g., `!(\"\" in { \"\": 1})`).\n          return serialize(\"\", (value = {}, value[\"\"] = source, value), callback, properties, whitespace, \"\", []);\n        };\n      }\n\n      // Public: Parses a JSON source string.\n      if (!has(\"json-parse\")) {\n        var fromCharCode = String.fromCharCode;\n\n        // Internal: A map of escaped control characters and their unescaped\n        // equivalents.\n        var Unescapes = {\n          92: \"\\\\\",\n          34: '\"',\n          47: \"/\",\n          98: \"\\b\",\n          116: \"\\t\",\n          110: \"\\n\",\n          102: \"\\f\",\n          114: \"\\r\"\n        };\n\n        // Internal: Stores the parser state.\n        var Index, Source;\n\n        // Internal: Resets the parser state and throws a `SyntaxError`.\n        var abort = function () {\n          Index = Source = null;\n          throw SyntaxError();\n        };\n\n        // Internal: Returns the next token, or `\"$\"` if the parser has reached\n        // the end of the source string. A token may be a string, number, `null`\n        // literal, or Boolean literal.\n        var lex = function () {\n          var source = Source, length = source.length, value, begin, position, isSigned, charCode;\n          while (Index < length) {\n            charCode = source.charCodeAt(Index);\n            switch (charCode) {\n              case 9: case 10: case 13: case 32:\n                // Skip whitespace tokens, including tabs, carriage returns, line\n                // feeds, and space characters.\n                Index++;\n                break;\n              case 123: case 125: case 91: case 93: case 58: case 44:\n                // Parse a punctuator token (`{`, `}`, `[`, `]`, `:`, or `,`) at\n                // the current position.\n                value = charIndexBuggy ? source.charAt(Index) : source[Index];\n                Index++;\n                return value;\n              case 34:\n                // `\"` delimits a JSON string; advance to the next character and\n                // begin parsing the string. String tokens are prefixed with the\n                // sentinel `@` character to distinguish them from punctuators and\n                // end-of-string tokens.\n                for (value = \"@\", Index++; Index < length;) {\n                  charCode = source.charCodeAt(Index);\n                  if (charCode < 32) {\n                    // Unescaped ASCII control characters (those with a code unit\n                    // less than the space character) are not permitted.\n                    abort();\n                  } else if (charCode == 92) {\n                    // A reverse solidus (`\\`) marks the beginning of an escaped\n                    // control character (including `\"`, `\\`, and `/`) or Unicode\n                    // escape sequence.\n                    charCode = source.charCodeAt(++Index);\n                    switch (charCode) {\n                      case 92: case 34: case 47: case 98: case 116: case 110: case 102: case 114:\n                        // Revive escaped control characters.\n                        value += Unescapes[charCode];\n                        Index++;\n                        break;\n                      case 117:\n                        // `\\u` marks the beginning of a Unicode escape sequence.\n                        // Advance to the first character and validate the\n                        // four-digit code point.\n                        begin = ++Index;\n                        for (position = Index + 4; Index < position; Index++) {\n                          charCode = source.charCodeAt(Index);\n                          // A valid sequence comprises four hexdigits (case-\n                          // insensitive) that form a single hexadecimal value.\n                          if (!(charCode >= 48 && charCode <= 57 || charCode >= 97 && charCode <= 102 || charCode >= 65 && charCode <= 70)) {\n                            // Invalid Unicode escape sequence.\n                            abort();\n                          }\n                        }\n                        // Revive the escaped character.\n                        value += fromCharCode(\"0x\" + source.slice(begin, Index));\n                        break;\n                      default:\n                        // Invalid escape sequence.\n                        abort();\n                    }\n                  } else {\n                    if (charCode == 34) {\n                      // An unescaped double-quote character marks the end of the\n                      // string.\n                      break;\n                    }\n                    charCode = source.charCodeAt(Index);\n                    begin = Index;\n                    // Optimize for the common case where a string is valid.\n                    while (charCode >= 32 && charCode != 92 && charCode != 34) {\n                      charCode = source.charCodeAt(++Index);\n                    }\n                    // Append the string as-is.\n                    value += source.slice(begin, Index);\n                  }\n                }\n                if (source.charCodeAt(Index) == 34) {\n                  // Advance to the next character and return the revived string.\n                  Index++;\n                  return value;\n                }\n                // Unterminated string.\n                abort();\n              default:\n                // Parse numbers and literals.\n                begin = Index;\n                // Advance past the negative sign, if one is specified.\n                if (charCode == 45) {\n                  isSigned = true;\n                  charCode = source.charCodeAt(++Index);\n                }\n                // Parse an integer or floating-point value.\n                if (charCode >= 48 && charCode <= 57) {\n                  // Leading zeroes are interpreted as octal literals.\n                  if (charCode == 48 && ((charCode = source.charCodeAt(Index + 1)), charCode >= 48 && charCode <= 57)) {\n                    // Illegal octal literal.\n                    abort();\n                  }\n                  isSigned = false;\n                  // Parse the integer component.\n                  for (; Index < length && ((charCode = source.charCodeAt(Index)), charCode >= 48 && charCode <= 57); Index++);\n                  // Floats cannot contain a leading decimal point; however, this\n                  // case is already accounted for by the parser.\n                  if (source.charCodeAt(Index) == 46) {\n                    position = ++Index;\n                    // Parse the decimal component.\n                    for (; position < length && ((charCode = source.charCodeAt(position)), charCode >= 48 && charCode <= 57); position++);\n                    if (position == Index) {\n                      // Illegal trailing decimal.\n                      abort();\n                    }\n                    Index = position;\n                  }\n                  // Parse exponents. The `e` denoting the exponent is\n                  // case-insensitive.\n                  charCode = source.charCodeAt(Index);\n                  if (charCode == 101 || charCode == 69) {\n                    charCode = source.charCodeAt(++Index);\n                    // Skip past the sign following the exponent, if one is\n                    // specified.\n                    if (charCode == 43 || charCode == 45) {\n                      Index++;\n                    }\n                    // Parse the exponential component.\n                    for (position = Index; position < length && ((charCode = source.charCodeAt(position)), charCode >= 48 && charCode <= 57); position++);\n                    if (position == Index) {\n                      // Illegal empty exponent.\n                      abort();\n                    }\n                    Index = position;\n                  }\n                  // Coerce the parsed value to a JavaScript number.\n                  return +source.slice(begin, Index);\n                }\n                // A negative sign may only precede numbers.\n                if (isSigned) {\n                  abort();\n                }\n                // `true`, `false`, and `null` literals.\n                if (source.slice(Index, Index + 4) == \"true\") {\n                  Index += 4;\n                  return true;\n                } else if (source.slice(Index, Index + 5) == \"false\") {\n                  Index += 5;\n                  return false;\n                } else if (source.slice(Index, Index + 4) == \"null\") {\n                  Index += 4;\n                  return null;\n                }\n                // Unrecognized token.\n                abort();\n            }\n          }\n          // Return the sentinel `$` character if the parser has reached the end\n          // of the source string.\n          return \"$\";\n        };\n\n        // Internal: Parses a JSON `value` token.\n        var get = function (value) {\n          var results, hasMembers;\n          if (value == \"$\") {\n            // Unexpected end of input.\n            abort();\n          }\n          if (typeof value == \"string\") {\n            if ((charIndexBuggy ? value.charAt(0) : value[0]) == \"@\") {\n              // Remove the sentinel `@` character.\n              return value.slice(1);\n            }\n            // Parse object and array literals.\n            if (value == \"[\") {\n              // Parses a JSON array, returning a new JavaScript array.\n              results = [];\n              for (;; hasMembers || (hasMembers = true)) {\n                value = lex();\n                // A closing square bracket marks the end of the array literal.\n                if (value == \"]\") {\n                  break;\n                }\n                // If the array literal contains elements, the current token\n                // should be a comma separating the previous element from the\n                // next.\n                if (hasMembers) {\n                  if (value == \",\") {\n                    value = lex();\n                    if (value == \"]\") {\n                      // Unexpected trailing `,` in array literal.\n                      abort();\n                    }\n                  } else {\n                    // A `,` must separate each array element.\n                    abort();\n                  }\n                }\n                // Elisions and leading commas are not permitted.\n                if (value == \",\") {\n                  abort();\n                }\n                results.push(get(value));\n              }\n              return results;\n            } else if (value == \"{\") {\n              // Parses a JSON object, returning a new JavaScript object.\n              results = {};\n              for (;; hasMembers || (hasMembers = true)) {\n                value = lex();\n                // A closing curly brace marks the end of the object literal.\n                if (value == \"}\") {\n                  break;\n                }\n                // If the object literal contains members, the current token\n                // should be a comma separator.\n                if (hasMembers) {\n                  if (value == \",\") {\n                    value = lex();\n                    if (value == \"}\") {\n                      // Unexpected trailing `,` in object literal.\n                      abort();\n                    }\n                  } else {\n                    // A `,` must separate each object member.\n                    abort();\n                  }\n                }\n                // Leading commas are not permitted, object property names must be\n                // double-quoted strings, and a `:` must separate each property\n                // name and value.\n                if (value == \",\" || typeof value != \"string\" || (charIndexBuggy ? value.charAt(0) : value[0]) != \"@\" || lex() != \":\") {\n                  abort();\n                }\n                results[value.slice(1)] = get(lex());\n              }\n              return results;\n            }\n            // Unexpected token encountered.\n            abort();\n          }\n          return value;\n        };\n\n        // Internal: Updates a traversed object member.\n        var update = function (source, property, callback) {\n          var element = walk(source, property, callback);\n          if (element === undef) {\n            delete source[property];\n          } else {\n            source[property] = element;\n          }\n        };\n\n        // Internal: Recursively traverses a parsed JSON object, invoking the\n        // `callback` function for each value. This is an implementation of the\n        // `Walk(holder, name)` operation defined in ES 5.1 section 15.12.2.\n        var walk = function (source, property, callback) {\n          var value = source[property], length;\n          if (typeof value == \"object\" && value) {\n            // `forEach` can't be used to traverse an array in Opera <= 8.54\n            // because its `Object#hasOwnProperty` implementation returns `false`\n            // for array indices (e.g., `![1, 2, 3].hasOwnProperty(\"0\")`).\n            if (getClass.call(value) == arrayClass) {\n              for (length = value.length; length--;) {\n                update(value, length, callback);\n              }\n            } else {\n              forEach(value, function (property) {\n                update(value, property, callback);\n              });\n            }\n          }\n          return callback.call(source, property, value);\n        };\n\n        // Public: `JSON.parse`. See ES 5.1 section 15.12.2.\n        exports.parse = function (source, callback) {\n          var result, value;\n          Index = 0;\n          Source = \"\" + source;\n          result = get(lex());\n          // If a JSON string contains multiple tokens, it is invalid.\n          if (lex() != \"$\") {\n            abort();\n          }\n          // Reset the parser state.\n          Index = Source = null;\n          return callback && getClass.call(callback) == functionClass ? walk((value = {}, value[\"\"] = result, value), \"\", callback) : result;\n        };\n      }\n    }\n\n    exports[\"runInContext\"] = runInContext;\n    return exports;\n  }\n\n  if (freeExports && !isLoader) {\n    // Export for CommonJS environments.\n    runInContext(root, freeExports);\n  } else {\n    // Export for web browsers and JavaScript engines.\n    var nativeJSON = root.JSON,\n        previousJSON = root[\"JSON3\"],\n        isRestored = false;\n\n    var JSON3 = runInContext(root, (root[\"JSON3\"] = {\n      // Public: Restores the original value of the global `JSON` object and\n      // returns a reference to the `JSON3` object.\n      \"noConflict\": function () {\n        if (!isRestored) {\n          isRestored = true;\n          root.JSON = nativeJSON;\n          root[\"JSON3\"] = previousJSON;\n          nativeJSON = previousJSON = null;\n        }\n        return JSON3;\n      }\n    }));\n\n    root.JSON = {\n      \"parse\": JSON3.parse,\n      \"stringify\": JSON3.stringify\n    };\n  }\n\n  // Export for asynchronous module loaders.\n  if (isLoader) {\n    define(function () {\n      return JSON3;\n    });\n  }\n}).call(this);\n\n}).call(this,typeof global !== \"undefined\" ? global : typeof self !== \"undefined\" ? self : typeof window !== \"undefined\" ? window : {})\n},{}],55:[function(require,module,exports){\n/**\n * lodash 3.2.0 (Custom Build) <https://lodash.com/>\n * Build: `lodash modern modularize exports=\"npm\" -o ./`\n * Copyright 2012-2015 The Dojo Foundation <http://dojofoundation.org/>\n * Based on Underscore.js 1.8.3 <http://underscorejs.org/LICENSE>\n * Copyright 2009-2015 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors\n * Available under MIT license <https://lodash.com/license>\n */\nvar baseCopy = require('lodash._basecopy'),\n    keys = require('lodash.keys');\n\n/**\n * The base implementation of `_.assign` without support for argument juggling,\n * multiple sources, and `customizer` functions.\n *\n * @private\n * @param {Object} object The destination object.\n * @param {Object} source The source object.\n * @returns {Object} Returns `object`.\n */\nfunction baseAssign(object, source) {\n  return source == null\n    ? object\n    : baseCopy(source, keys(source), object);\n}\n\nmodule.exports = baseAssign;\n\n},{\"lodash._basecopy\":56,\"lodash.keys\":63}],56:[function(require,module,exports){\n/**\n * lodash 3.0.1 (Custom Build) <https://lodash.com/>\n * Build: `lodash modern modularize exports=\"npm\" -o ./`\n * Copyright 2012-2015 The Dojo Foundation <http://dojofoundation.org/>\n * Based on Underscore.js 1.8.3 <http://underscorejs.org/LICENSE>\n * Copyright 2009-2015 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors\n * Available under MIT license <https://lodash.com/license>\n */\n\n/**\n * Copies properties of `source` to `object`.\n *\n * @private\n * @param {Object} source The object to copy properties from.\n * @param {Array} props The property names to copy.\n * @param {Object} [object={}] The object to copy properties to.\n * @returns {Object} Returns `object`.\n */\nfunction baseCopy(source, props, object) {\n  object || (object = {});\n\n  var index = -1,\n      length = props.length;\n\n  while (++index < length) {\n    var key = props[index];\n    object[key] = source[key];\n  }\n  return object;\n}\n\nmodule.exports = baseCopy;\n\n},{}],57:[function(require,module,exports){\n/**\n * lodash 3.0.3 (Custom Build) <https://lodash.com/>\n * Build: `lodash modern modularize exports=\"npm\" -o ./`\n * Copyright 2012-2015 The Dojo Foundation <http://dojofoundation.org/>\n * Based on Underscore.js 1.8.3 <http://underscorejs.org/LICENSE>\n * Copyright 2009-2015 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors\n * Available under MIT license <https://lodash.com/license>\n */\n\n/**\n * The base implementation of `_.create` without support for assigning\n * properties to the created object.\n *\n * @private\n * @param {Object} prototype The object to inherit from.\n * @returns {Object} Returns the new object.\n */\nvar baseCreate = (function() {\n  function object() {}\n  return function(prototype) {\n    if (isObject(prototype)) {\n      object.prototype = prototype;\n      var result = new object;\n      object.prototype = undefined;\n    }\n    return result || {};\n  };\n}());\n\n/**\n * Checks if `value` is the [language type](https://es5.github.io/#x8) of `Object`.\n * (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)\n *\n * @static\n * @memberOf _\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is an object, else `false`.\n * @example\n *\n * _.isObject({});\n * // => true\n *\n * _.isObject([1, 2, 3]);\n * // => true\n *\n * _.isObject(1);\n * // => false\n */\nfunction isObject(value) {\n  // Avoid a V8 JIT bug in Chrome 19-20.\n  // See https://code.google.com/p/v8/issues/detail?id=2291 for more details.\n  var type = typeof value;\n  return !!value && (type == 'object' || type == 'function');\n}\n\nmodule.exports = baseCreate;\n\n},{}],58:[function(require,module,exports){\n/**\n * lodash 3.9.1 (Custom Build) <https://lodash.com/>\n * Build: `lodash modern modularize exports=\"npm\" -o ./`\n * Copyright 2012-2015 The Dojo Foundation <http://dojofoundation.org/>\n * Based on Underscore.js 1.8.3 <http://underscorejs.org/LICENSE>\n * Copyright 2009-2015 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors\n * Available under MIT license <https://lodash.com/license>\n */\n\n/** `Object#toString` result references. */\nvar funcTag = '[object Function]';\n\n/** Used to detect host constructors (Safari > 5). */\nvar reIsHostCtor = /^\\[object .+?Constructor\\]$/;\n\n/**\n * Checks if `value` is object-like.\n *\n * @private\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is object-like, else `false`.\n */\nfunction isObjectLike(value) {\n  return !!value && typeof value == 'object';\n}\n\n/** Used for native method references. */\nvar objectProto = Object.prototype;\n\n/** Used to resolve the decompiled source of functions. */\nvar fnToString = Function.prototype.toString;\n\n/** Used to check objects for own properties. */\nvar hasOwnProperty = objectProto.hasOwnProperty;\n\n/**\n * Used to resolve the [`toStringTag`](http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring)\n * of values.\n */\nvar objToString = objectProto.toString;\n\n/** Used to detect if a method is native. */\nvar reIsNative = RegExp('^' +\n  fnToString.call(hasOwnProperty).replace(/[\\\\^$.*+?()[\\]{}|]/g, '\\\\$&')\n  .replace(/hasOwnProperty|(function).*?(?=\\\\\\()| for .+?(?=\\\\\\])/g, '$1.*?') + '$'\n);\n\n/**\n * Gets the native function at `key` of `object`.\n *\n * @private\n * @param {Object} object The object to query.\n * @param {string} key The key of the method to get.\n * @returns {*} Returns the function if it's native, else `undefined`.\n */\nfunction getNative(object, key) {\n  var value = object == null ? undefined : object[key];\n  return isNative(value) ? value : undefined;\n}\n\n/**\n * Checks if `value` is classified as a `Function` object.\n *\n * @static\n * @memberOf _\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`.\n * @example\n *\n * _.isFunction(_);\n * // => true\n *\n * _.isFunction(/abc/);\n * // => false\n */\nfunction isFunction(value) {\n  // The use of `Object#toString` avoids issues with the `typeof` operator\n  // in older versions of Chrome and Safari which return 'function' for regexes\n  // and Safari 8 equivalents which return 'object' for typed array constructors.\n  return isObject(value) && objToString.call(value) == funcTag;\n}\n\n/**\n * Checks if `value` is the [language type](https://es5.github.io/#x8) of `Object`.\n * (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)\n *\n * @static\n * @memberOf _\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is an object, else `false`.\n * @example\n *\n * _.isObject({});\n * // => true\n *\n * _.isObject([1, 2, 3]);\n * // => true\n *\n * _.isObject(1);\n * // => false\n */\nfunction isObject(value) {\n  // Avoid a V8 JIT bug in Chrome 19-20.\n  // See https://code.google.com/p/v8/issues/detail?id=2291 for more details.\n  var type = typeof value;\n  return !!value && (type == 'object' || type == 'function');\n}\n\n/**\n * Checks if `value` is a native function.\n *\n * @static\n * @memberOf _\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a native function, else `false`.\n * @example\n *\n * _.isNative(Array.prototype.push);\n * // => true\n *\n * _.isNative(_);\n * // => false\n */\nfunction isNative(value) {\n  if (value == null) {\n    return false;\n  }\n  if (isFunction(value)) {\n    return reIsNative.test(fnToString.call(value));\n  }\n  return isObjectLike(value) && reIsHostCtor.test(value);\n}\n\nmodule.exports = getNative;\n\n},{}],59:[function(require,module,exports){\n/**\n * lodash 3.0.9 (Custom Build) <https://lodash.com/>\n * Build: `lodash modern modularize exports=\"npm\" -o ./`\n * Copyright 2012-2015 The Dojo Foundation <http://dojofoundation.org/>\n * Based on Underscore.js 1.8.3 <http://underscorejs.org/LICENSE>\n * Copyright 2009-2015 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors\n * Available under MIT license <https://lodash.com/license>\n */\n\n/** Used to detect unsigned integer values. */\nvar reIsUint = /^\\d+$/;\n\n/**\n * Used as the [maximum length](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-number.max_safe_integer)\n * of an array-like value.\n */\nvar MAX_SAFE_INTEGER = 9007199254740991;\n\n/**\n * The base implementation of `_.property` without support for deep paths.\n *\n * @private\n * @param {string} key The key of the property to get.\n * @returns {Function} Returns the new function.\n */\nfunction baseProperty(key) {\n  return function(object) {\n    return object == null ? undefined : object[key];\n  };\n}\n\n/**\n * Gets the \"length\" property value of `object`.\n *\n * **Note:** This function is used to avoid a [JIT bug](https://bugs.webkit.org/show_bug.cgi?id=142792)\n * that affects Safari on at least iOS 8.1-8.3 ARM64.\n *\n * @private\n * @param {Object} object The object to query.\n * @returns {*} Returns the \"length\" value.\n */\nvar getLength = baseProperty('length');\n\n/**\n * Checks if `value` is array-like.\n *\n * @private\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is array-like, else `false`.\n */\nfunction isArrayLike(value) {\n  return value != null && isLength(getLength(value));\n}\n\n/**\n * Checks if `value` is a valid array-like index.\n *\n * @private\n * @param {*} value The value to check.\n * @param {number} [length=MAX_SAFE_INTEGER] The upper bounds of a valid index.\n * @returns {boolean} Returns `true` if `value` is a valid index, else `false`.\n */\nfunction isIndex(value, length) {\n  value = (typeof value == 'number' || reIsUint.test(value)) ? +value : -1;\n  length = length == null ? MAX_SAFE_INTEGER : length;\n  return value > -1 && value % 1 == 0 && value < length;\n}\n\n/**\n * Checks if the provided arguments are from an iteratee call.\n *\n * @private\n * @param {*} value The potential iteratee value argument.\n * @param {*} index The potential iteratee index or key argument.\n * @param {*} object The potential iteratee object argument.\n * @returns {boolean} Returns `true` if the arguments are from an iteratee call, else `false`.\n */\nfunction isIterateeCall(value, index, object) {\n  if (!isObject(object)) {\n    return false;\n  }\n  var type = typeof index;\n  if (type == 'number'\n      ? (isArrayLike(object) && isIndex(index, object.length))\n      : (type == 'string' && index in object)) {\n    var other = object[index];\n    return value === value ? (value === other) : (other !== other);\n  }\n  return false;\n}\n\n/**\n * Checks if `value` is a valid array-like length.\n *\n * **Note:** This function is based on [`ToLength`](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-tolength).\n *\n * @private\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a valid length, else `false`.\n */\nfunction isLength(value) {\n  return typeof value == 'number' && value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER;\n}\n\n/**\n * Checks if `value` is the [language type](https://es5.github.io/#x8) of `Object`.\n * (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)\n *\n * @static\n * @memberOf _\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is an object, else `false`.\n * @example\n *\n * _.isObject({});\n * // => true\n *\n * _.isObject([1, 2, 3]);\n * // => true\n *\n * _.isObject(1);\n * // => false\n */\nfunction isObject(value) {\n  // Avoid a V8 JIT bug in Chrome 19-20.\n  // See https://code.google.com/p/v8/issues/detail?id=2291 for more details.\n  var type = typeof value;\n  return !!value && (type == 'object' || type == 'function');\n}\n\nmodule.exports = isIterateeCall;\n\n},{}],60:[function(require,module,exports){\n/**\n * lodash 3.1.1 (Custom Build) <https://lodash.com/>\n * Build: `lodash modern modularize exports=\"npm\" -o ./`\n * Copyright 2012-2015 The Dojo Foundation <http://dojofoundation.org/>\n * Based on Underscore.js 1.8.3 <http://underscorejs.org/LICENSE>\n * Copyright 2009-2015 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors\n * Available under MIT license <https://lodash.com/license>\n */\nvar baseAssign = require('lodash._baseassign'),\n    baseCreate = require('lodash._basecreate'),\n    isIterateeCall = require('lodash._isiterateecall');\n\n/**\n * Creates an object that inherits from the given `prototype` object. If a\n * `properties` object is provided its own enumerable properties are assigned\n * to the created object.\n *\n * @static\n * @memberOf _\n * @category Object\n * @param {Object} prototype The object to inherit from.\n * @param {Object} [properties] The properties to assign to the object.\n * @param- {Object} [guard] Enables use as a callback for functions like `_.map`.\n * @returns {Object} Returns the new object.\n * @example\n *\n * function Shape() {\n *   this.x = 0;\n *   this.y = 0;\n * }\n *\n * function Circle() {\n *   Shape.call(this);\n * }\n *\n * Circle.prototype = _.create(Shape.prototype, {\n *   'constructor': Circle\n * });\n *\n * var circle = new Circle;\n * circle instanceof Circle;\n * // => true\n *\n * circle instanceof Shape;\n * // => true\n */\nfunction create(prototype, properties, guard) {\n  var result = baseCreate(prototype);\n  if (guard && isIterateeCall(prototype, properties, guard)) {\n    properties = undefined;\n  }\n  return properties ? baseAssign(result, properties) : result;\n}\n\nmodule.exports = create;\n\n},{\"lodash._baseassign\":55,\"lodash._basecreate\":57,\"lodash._isiterateecall\":59}],61:[function(require,module,exports){\n/**\n * lodash (Custom Build) <https://lodash.com/>\n * Build: `lodash modularize exports=\"npm\" -o ./`\n * Copyright jQuery Foundation and other contributors <https://jquery.org/>\n * Released under MIT license <https://lodash.com/license>\n * Based on Underscore.js 1.8.3 <http://underscorejs.org/LICENSE>\n * Copyright Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors\n */\n\n/** Used as references for various `Number` constants. */\nvar MAX_SAFE_INTEGER = 9007199254740991;\n\n/** `Object#toString` result references. */\nvar argsTag = '[object Arguments]',\n    funcTag = '[object Function]',\n    genTag = '[object GeneratorFunction]';\n\n/** Used for built-in method references. */\nvar objectProto = Object.prototype;\n\n/** Used to check objects for own properties. */\nvar hasOwnProperty = objectProto.hasOwnProperty;\n\n/**\n * Used to resolve the\n * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring)\n * of values.\n */\nvar objectToString = objectProto.toString;\n\n/** Built-in value references. */\nvar propertyIsEnumerable = objectProto.propertyIsEnumerable;\n\n/**\n * Checks if `value` is likely an `arguments` object.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is an `arguments` object,\n *  else `false`.\n * @example\n *\n * _.isArguments(function() { return arguments; }());\n * // => true\n *\n * _.isArguments([1, 2, 3]);\n * // => false\n */\nfunction isArguments(value) {\n  // Safari 8.1 makes `arguments.callee` enumerable in strict mode.\n  return isArrayLikeObject(value) && hasOwnProperty.call(value, 'callee') &&\n    (!propertyIsEnumerable.call(value, 'callee') || objectToString.call(value) == argsTag);\n}\n\n/**\n * Checks if `value` is array-like. A value is considered array-like if it's\n * not a function and has a `value.length` that's an integer greater than or\n * equal to `0` and less than or equal to `Number.MAX_SAFE_INTEGER`.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is array-like, else `false`.\n * @example\n *\n * _.isArrayLike([1, 2, 3]);\n * // => true\n *\n * _.isArrayLike(document.body.children);\n * // => true\n *\n * _.isArrayLike('abc');\n * // => true\n *\n * _.isArrayLike(_.noop);\n * // => false\n */\nfunction isArrayLike(value) {\n  return value != null && isLength(value.length) && !isFunction(value);\n}\n\n/**\n * This method is like `_.isArrayLike` except that it also checks if `value`\n * is an object.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is an array-like object,\n *  else `false`.\n * @example\n *\n * _.isArrayLikeObject([1, 2, 3]);\n * // => true\n *\n * _.isArrayLikeObject(document.body.children);\n * // => true\n *\n * _.isArrayLikeObject('abc');\n * // => false\n *\n * _.isArrayLikeObject(_.noop);\n * // => false\n */\nfunction isArrayLikeObject(value) {\n  return isObjectLike(value) && isArrayLike(value);\n}\n\n/**\n * Checks if `value` is classified as a `Function` object.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a function, else `false`.\n * @example\n *\n * _.isFunction(_);\n * // => true\n *\n * _.isFunction(/abc/);\n * // => false\n */\nfunction isFunction(value) {\n  // The use of `Object#toString` avoids issues with the `typeof` operator\n  // in Safari 8-9 which returns 'object' for typed array and other constructors.\n  var tag = isObject(value) ? objectToString.call(value) : '';\n  return tag == funcTag || tag == genTag;\n}\n\n/**\n * Checks if `value` is a valid array-like length.\n *\n * **Note:** This method is loosely based on\n * [`ToLength`](http://ecma-international.org/ecma-262/7.0/#sec-tolength).\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a valid length, else `false`.\n * @example\n *\n * _.isLength(3);\n * // => true\n *\n * _.isLength(Number.MIN_VALUE);\n * // => false\n *\n * _.isLength(Infinity);\n * // => false\n *\n * _.isLength('3');\n * // => false\n */\nfunction isLength(value) {\n  return typeof value == 'number' &&\n    value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER;\n}\n\n/**\n * Checks if `value` is the\n * [language type](http://www.ecma-international.org/ecma-262/7.0/#sec-ecmascript-language-types)\n * of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is an object, else `false`.\n * @example\n *\n * _.isObject({});\n * // => true\n *\n * _.isObject([1, 2, 3]);\n * // => true\n *\n * _.isObject(_.noop);\n * // => true\n *\n * _.isObject(null);\n * // => false\n */\nfunction isObject(value) {\n  var type = typeof value;\n  return !!value && (type == 'object' || type == 'function');\n}\n\n/**\n * Checks if `value` is object-like. A value is object-like if it's not `null`\n * and has a `typeof` result of \"object\".\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is object-like, else `false`.\n * @example\n *\n * _.isObjectLike({});\n * // => true\n *\n * _.isObjectLike([1, 2, 3]);\n * // => true\n *\n * _.isObjectLike(_.noop);\n * // => false\n *\n * _.isObjectLike(null);\n * // => false\n */\nfunction isObjectLike(value) {\n  return !!value && typeof value == 'object';\n}\n\nmodule.exports = isArguments;\n\n},{}],62:[function(require,module,exports){\n/**\n * lodash 3.0.4 (Custom Build) <https://lodash.com/>\n * Build: `lodash modern modularize exports=\"npm\" -o ./`\n * Copyright 2012-2015 The Dojo Foundation <http://dojofoundation.org/>\n * Based on Underscore.js 1.8.3 <http://underscorejs.org/LICENSE>\n * Copyright 2009-2015 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors\n * Available under MIT license <https://lodash.com/license>\n */\n\n/** `Object#toString` result references. */\nvar arrayTag = '[object Array]',\n    funcTag = '[object Function]';\n\n/** Used to detect host constructors (Safari > 5). */\nvar reIsHostCtor = /^\\[object .+?Constructor\\]$/;\n\n/**\n * Checks if `value` is object-like.\n *\n * @private\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is object-like, else `false`.\n */\nfunction isObjectLike(value) {\n  return !!value && typeof value == 'object';\n}\n\n/** Used for native method references. */\nvar objectProto = Object.prototype;\n\n/** Used to resolve the decompiled source of functions. */\nvar fnToString = Function.prototype.toString;\n\n/** Used to check objects for own properties. */\nvar hasOwnProperty = objectProto.hasOwnProperty;\n\n/**\n * Used to resolve the [`toStringTag`](http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring)\n * of values.\n */\nvar objToString = objectProto.toString;\n\n/** Used to detect if a method is native. */\nvar reIsNative = RegExp('^' +\n  fnToString.call(hasOwnProperty).replace(/[\\\\^$.*+?()[\\]{}|]/g, '\\\\$&')\n  .replace(/hasOwnProperty|(function).*?(?=\\\\\\()| for .+?(?=\\\\\\])/g, '$1.*?') + '$'\n);\n\n/* Native method references for those with the same name as other `lodash` methods. */\nvar nativeIsArray = getNative(Array, 'isArray');\n\n/**\n * Used as the [maximum length](http://ecma-international.org/ecma-262/6.0/#sec-number.max_safe_integer)\n * of an array-like value.\n */\nvar MAX_SAFE_INTEGER = 9007199254740991;\n\n/**\n * Gets the native function at `key` of `object`.\n *\n * @private\n * @param {Object} object The object to query.\n * @param {string} key The key of the method to get.\n * @returns {*} Returns the function if it's native, else `undefined`.\n */\nfunction getNative(object, key) {\n  var value = object == null ? undefined : object[key];\n  return isNative(value) ? value : undefined;\n}\n\n/**\n * Checks if `value` is a valid array-like length.\n *\n * **Note:** This function is based on [`ToLength`](http://ecma-international.org/ecma-262/6.0/#sec-tolength).\n *\n * @private\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a valid length, else `false`.\n */\nfunction isLength(value) {\n  return typeof value == 'number' && value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER;\n}\n\n/**\n * Checks if `value` is classified as an `Array` object.\n *\n * @static\n * @memberOf _\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`.\n * @example\n *\n * _.isArray([1, 2, 3]);\n * // => true\n *\n * _.isArray(function() { return arguments; }());\n * // => false\n */\nvar isArray = nativeIsArray || function(value) {\n  return isObjectLike(value) && isLength(value.length) && objToString.call(value) == arrayTag;\n};\n\n/**\n * Checks if `value` is classified as a `Function` object.\n *\n * @static\n * @memberOf _\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`.\n * @example\n *\n * _.isFunction(_);\n * // => true\n *\n * _.isFunction(/abc/);\n * // => false\n */\nfunction isFunction(value) {\n  // The use of `Object#toString` avoids issues with the `typeof` operator\n  // in older versions of Chrome and Safari which return 'function' for regexes\n  // and Safari 8 equivalents which return 'object' for typed array constructors.\n  return isObject(value) && objToString.call(value) == funcTag;\n}\n\n/**\n * Checks if `value` is the [language type](https://es5.github.io/#x8) of `Object`.\n * (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)\n *\n * @static\n * @memberOf _\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is an object, else `false`.\n * @example\n *\n * _.isObject({});\n * // => true\n *\n * _.isObject([1, 2, 3]);\n * // => true\n *\n * _.isObject(1);\n * // => false\n */\nfunction isObject(value) {\n  // Avoid a V8 JIT bug in Chrome 19-20.\n  // See https://code.google.com/p/v8/issues/detail?id=2291 for more details.\n  var type = typeof value;\n  return !!value && (type == 'object' || type == 'function');\n}\n\n/**\n * Checks if `value` is a native function.\n *\n * @static\n * @memberOf _\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a native function, else `false`.\n * @example\n *\n * _.isNative(Array.prototype.push);\n * // => true\n *\n * _.isNative(_);\n * // => false\n */\nfunction isNative(value) {\n  if (value == null) {\n    return false;\n  }\n  if (isFunction(value)) {\n    return reIsNative.test(fnToString.call(value));\n  }\n  return isObjectLike(value) && reIsHostCtor.test(value);\n}\n\nmodule.exports = isArray;\n\n},{}],63:[function(require,module,exports){\n/**\n * lodash 3.1.2 (Custom Build) <https://lodash.com/>\n * Build: `lodash modern modularize exports=\"npm\" -o ./`\n * Copyright 2012-2015 The Dojo Foundation <http://dojofoundation.org/>\n * Based on Underscore.js 1.8.3 <http://underscorejs.org/LICENSE>\n * Copyright 2009-2015 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors\n * Available under MIT license <https://lodash.com/license>\n */\nvar getNative = require('lodash._getnative'),\n    isArguments = require('lodash.isarguments'),\n    isArray = require('lodash.isarray');\n\n/** Used to detect unsigned integer values. */\nvar reIsUint = /^\\d+$/;\n\n/** Used for native method references. */\nvar objectProto = Object.prototype;\n\n/** Used to check objects for own properties. */\nvar hasOwnProperty = objectProto.hasOwnProperty;\n\n/* Native method references for those with the same name as other `lodash` methods. */\nvar nativeKeys = getNative(Object, 'keys');\n\n/**\n * Used as the [maximum length](http://ecma-international.org/ecma-262/6.0/#sec-number.max_safe_integer)\n * of an array-like value.\n */\nvar MAX_SAFE_INTEGER = 9007199254740991;\n\n/**\n * The base implementation of `_.property` without support for deep paths.\n *\n * @private\n * @param {string} key The key of the property to get.\n * @returns {Function} Returns the new function.\n */\nfunction baseProperty(key) {\n  return function(object) {\n    return object == null ? undefined : object[key];\n  };\n}\n\n/**\n * Gets the \"length\" property value of `object`.\n *\n * **Note:** This function is used to avoid a [JIT bug](https://bugs.webkit.org/show_bug.cgi?id=142792)\n * that affects Safari on at least iOS 8.1-8.3 ARM64.\n *\n * @private\n * @param {Object} object The object to query.\n * @returns {*} Returns the \"length\" value.\n */\nvar getLength = baseProperty('length');\n\n/**\n * Checks if `value` is array-like.\n *\n * @private\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is array-like, else `false`.\n */\nfunction isArrayLike(value) {\n  return value != null && isLength(getLength(value));\n}\n\n/**\n * Checks if `value` is a valid array-like index.\n *\n * @private\n * @param {*} value The value to check.\n * @param {number} [length=MAX_SAFE_INTEGER] The upper bounds of a valid index.\n * @returns {boolean} Returns `true` if `value` is a valid index, else `false`.\n */\nfunction isIndex(value, length) {\n  value = (typeof value == 'number' || reIsUint.test(value)) ? +value : -1;\n  length = length == null ? MAX_SAFE_INTEGER : length;\n  return value > -1 && value % 1 == 0 && value < length;\n}\n\n/**\n * Checks if `value` is a valid array-like length.\n *\n * **Note:** This function is based on [`ToLength`](http://ecma-international.org/ecma-262/6.0/#sec-tolength).\n *\n * @private\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a valid length, else `false`.\n */\nfunction isLength(value) {\n  return typeof value == 'number' && value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER;\n}\n\n/**\n * A fallback implementation of `Object.keys` which creates an array of the\n * own enumerable property names of `object`.\n *\n * @private\n * @param {Object} object The object to query.\n * @returns {Array} Returns the array of property names.\n */\nfunction shimKeys(object) {\n  var props = keysIn(object),\n      propsLength = props.length,\n      length = propsLength && object.length;\n\n  var allowIndexes = !!length && isLength(length) &&\n    (isArray(object) || isArguments(object));\n\n  var index = -1,\n      result = [];\n\n  while (++index < propsLength) {\n    var key = props[index];\n    if ((allowIndexes && isIndex(key, length)) || hasOwnProperty.call(object, key)) {\n      result.push(key);\n    }\n  }\n  return result;\n}\n\n/**\n * Checks if `value` is the [language type](https://es5.github.io/#x8) of `Object`.\n * (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)\n *\n * @static\n * @memberOf _\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is an object, else `false`.\n * @example\n *\n * _.isObject({});\n * // => true\n *\n * _.isObject([1, 2, 3]);\n * // => true\n *\n * _.isObject(1);\n * // => false\n */\nfunction isObject(value) {\n  // Avoid a V8 JIT bug in Chrome 19-20.\n  // See https://code.google.com/p/v8/issues/detail?id=2291 for more details.\n  var type = typeof value;\n  return !!value && (type == 'object' || type == 'function');\n}\n\n/**\n * Creates an array of the own enumerable property names of `object`.\n *\n * **Note:** Non-object values are coerced to objects. See the\n * [ES spec](http://ecma-international.org/ecma-262/6.0/#sec-object.keys)\n * for more details.\n *\n * @static\n * @memberOf _\n * @category Object\n * @param {Object} object The object to query.\n * @returns {Array} Returns the array of property names.\n * @example\n *\n * function Foo() {\n *   this.a = 1;\n *   this.b = 2;\n * }\n *\n * Foo.prototype.c = 3;\n *\n * _.keys(new Foo);\n * // => ['a', 'b'] (iteration order is not guaranteed)\n *\n * _.keys('hi');\n * // => ['0', '1']\n */\nvar keys = !nativeKeys ? shimKeys : function(object) {\n  var Ctor = object == null ? undefined : object.constructor;\n  if ((typeof Ctor == 'function' && Ctor.prototype === object) ||\n      (typeof object != 'function' && isArrayLike(object))) {\n    return shimKeys(object);\n  }\n  return isObject(object) ? nativeKeys(object) : [];\n};\n\n/**\n * Creates an array of the own and inherited enumerable property names of `object`.\n *\n * **Note:** Non-object values are coerced to objects.\n *\n * @static\n * @memberOf _\n * @category Object\n * @param {Object} object The object to query.\n * @returns {Array} Returns the array of property names.\n * @example\n *\n * function Foo() {\n *   this.a = 1;\n *   this.b = 2;\n * }\n *\n * Foo.prototype.c = 3;\n *\n * _.keysIn(new Foo);\n * // => ['a', 'b', 'c'] (iteration order is not guaranteed)\n */\nfunction keysIn(object) {\n  if (object == null) {\n    return [];\n  }\n  if (!isObject(object)) {\n    object = Object(object);\n  }\n  var length = object.length;\n  length = (length && isLength(length) &&\n    (isArray(object) || isArguments(object)) && length) || 0;\n\n  var Ctor = object.constructor,\n      index = -1,\n      isProto = typeof Ctor == 'function' && Ctor.prototype === object,\n      result = Array(length),\n      skipIndexes = length > 0;\n\n  while (++index < length) {\n    result[index] = (index + '');\n  }\n  for (var key in object) {\n    if (!(skipIndexes && isIndex(key, length)) &&\n        !(key == 'constructor' && (isProto || !hasOwnProperty.call(object, key)))) {\n      result.push(key);\n    }\n  }\n  return result;\n}\n\nmodule.exports = keys;\n\n},{\"lodash._getnative\":58,\"lodash.isarguments\":61,\"lodash.isarray\":62}],64:[function(require,module,exports){\n(function (process){\nvar path = require('path');\nvar fs = require('fs');\nvar _0777 = parseInt('0777', 8);\n\nmodule.exports = mkdirP.mkdirp = mkdirP.mkdirP = mkdirP;\n\nfunction mkdirP (p, opts, f, made) {\n    if (typeof opts === 'function') {\n        f = opts;\n        opts = {};\n    }\n    else if (!opts || typeof opts !== 'object') {\n        opts = { mode: opts };\n    }\n\n    var mode = opts.mode;\n    var xfs = opts.fs || fs;\n\n    if (mode === undefined) {\n        mode = _0777 & (~process.umask());\n    }\n    if (!made) made = null;\n\n    var cb = f || function () {};\n    p = path.resolve(p);\n\n    xfs.mkdir(p, mode, function (er) {\n        if (!er) {\n            made = made || p;\n            return cb(null, made);\n        }\n        switch (er.code) {\n            case 'ENOENT':\n                mkdirP(path.dirname(p), opts, function (er, made) {\n                    if (er) cb(er, made);\n                    else mkdirP(p, opts, cb, made);\n                });\n                break;\n\n            // In the case of any other error, just see if there's a dir\n            // there already.  If so, then hooray!  If not, then something\n            // is borked.\n            default:\n                xfs.stat(p, function (er2, stat) {\n                    // if the stat fails, then that's super weird.\n                    // let the original error be the failure reason.\n                    if (er2 || !stat.isDirectory()) cb(er, made)\n                    else cb(null, made);\n                });\n                break;\n        }\n    });\n}\n\nmkdirP.sync = function sync (p, opts, made) {\n    if (!opts || typeof opts !== 'object') {\n        opts = { mode: opts };\n    }\n\n    var mode = opts.mode;\n    var xfs = opts.fs || fs;\n\n    if (mode === undefined) {\n        mode = _0777 & (~process.umask());\n    }\n    if (!made) made = null;\n\n    p = path.resolve(p);\n\n    try {\n        xfs.mkdirSync(p, mode);\n        made = made || p;\n    }\n    catch (err0) {\n        switch (err0.code) {\n            case 'ENOENT' :\n                made = sync(path.dirname(p), opts, made);\n                sync(p, opts, made);\n                break;\n\n            // In the case of any other error, just see if there's a dir\n            // there already.  If so, then hooray!  If not, then something\n            // is borked.\n            default:\n                var stat;\n                try {\n                    stat = xfs.statSync(p);\n                }\n                catch (err1) {\n                    throw err0;\n                }\n                if (!stat.isDirectory()) throw err0;\n                break;\n        }\n    }\n\n    return made;\n};\n\n}).call(this,require('_process'))\n},{\"_process\":67,\"fs\":42,\"path\":42}],65:[function(require,module,exports){\nexports.endianness = function () { return 'LE' };\n\nexports.hostname = function () {\n    if (typeof location !== 'undefined') {\n        return location.hostname\n    }\n    else return '';\n};\n\nexports.loadavg = function () { return [] };\n\nexports.uptime = function () { return 0 };\n\nexports.freemem = function () {\n    return Number.MAX_VALUE;\n};\n\nexports.totalmem = function () {\n    return Number.MAX_VALUE;\n};\n\nexports.cpus = function () { return [] };\n\nexports.type = function () { return 'Browser' };\n\nexports.release = function () {\n    if (typeof navigator !== 'undefined') {\n        return navigator.appVersion;\n    }\n    return '';\n};\n\nexports.networkInterfaces\n= exports.getNetworkInterfaces\n= function () { return {} };\n\nexports.arch = function () { return 'javascript' };\n\nexports.platform = function () { return 'browser' };\n\nexports.tmpdir = exports.tmpDir = function () {\n    return '/tmp';\n};\n\nexports.EOL = '\\n';\n\n},{}],66:[function(require,module,exports){\n(function (process){\n'use strict';\n\nif (!process.version ||\n    process.version.indexOf('v0.') === 0 ||\n    process.version.indexOf('v1.') === 0 && process.version.indexOf('v1.8.') !== 0) {\n  module.exports = nextTick;\n} else {\n  module.exports = process.nextTick;\n}\n\nfunction nextTick(fn, arg1, arg2, arg3) {\n  if (typeof fn !== 'function') {\n    throw new TypeError('\"callback\" argument must be a function');\n  }\n  var len = arguments.length;\n  var args, i;\n  switch (len) {\n  case 0:\n  case 1:\n    return process.nextTick(fn);\n  case 2:\n    return process.nextTick(function afterTickOne() {\n      fn.call(null, arg1);\n    });\n  case 3:\n    return process.nextTick(function afterTickTwo() {\n      fn.call(null, arg1, arg2);\n    });\n  case 4:\n    return process.nextTick(function afterTickThree() {\n      fn.call(null, arg1, arg2, arg3);\n    });\n  default:\n    args = new Array(len - 1);\n    i = 0;\n    while (i < args.length) {\n      args[i++] = arguments[i];\n    }\n    return process.nextTick(function afterTick() {\n      fn.apply(null, args);\n    });\n  }\n}\n\n}).call(this,require('_process'))\n},{\"_process\":67}],67:[function(require,module,exports){\n// shim for using process in browser\nvar process = module.exports = {};\n\n// cached from whatever global is present so that test runners that stub it\n// don't break things.  But we need to wrap it in a try catch in case it is\n// wrapped in strict mode code which doesn't define any globals.  It's inside a\n// function because try/catches deoptimize in certain engines.\n\nvar cachedSetTimeout;\nvar cachedClearTimeout;\n\nfunction defaultSetTimout() {\n    throw new Error('setTimeout has not been defined');\n}\nfunction defaultClearTimeout () {\n    throw new Error('clearTimeout has not been defined');\n}\n(function () {\n    try {\n        if (typeof setTimeout === 'function') {\n            cachedSetTimeout = setTimeout;\n        } else {\n            cachedSetTimeout = defaultSetTimout;\n        }\n    } catch (e) {\n        cachedSetTimeout = defaultSetTimout;\n    }\n    try {\n        if (typeof clearTimeout === 'function') {\n            cachedClearTimeout = clearTimeout;\n        } else {\n            cachedClearTimeout = defaultClearTimeout;\n        }\n    } catch (e) {\n        cachedClearTimeout = defaultClearTimeout;\n    }\n} ())\nfunction runTimeout(fun) {\n    if (cachedSetTimeout === setTimeout) {\n        //normal enviroments in sane situations\n        return setTimeout(fun, 0);\n    }\n    // if setTimeout wasn't available but was latter defined\n    if ((cachedSetTimeout === defaultSetTimout || !cachedSetTimeout) && setTimeout) {\n        cachedSetTimeout = setTimeout;\n        return setTimeout(fun, 0);\n    }\n    try {\n        // when when somebody has screwed with setTimeout but no I.E. maddness\n        return cachedSetTimeout(fun, 0);\n    } catch(e){\n        try {\n            // When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally\n            return cachedSetTimeout.call(null, fun, 0);\n        } catch(e){\n            // same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error\n            return cachedSetTimeout.call(this, fun, 0);\n        }\n    }\n\n\n}\nfunction runClearTimeout(marker) {\n    if (cachedClearTimeout === clearTimeout) {\n        //normal enviroments in sane situations\n        return clearTimeout(marker);\n    }\n    // if clearTimeout wasn't available but was latter defined\n    if ((cachedClearTimeout === defaultClearTimeout || !cachedClearTimeout) && clearTimeout) {\n        cachedClearTimeout = clearTimeout;\n        return clearTimeout(marker);\n    }\n    try {\n        // when when somebody has screwed with setTimeout but no I.E. maddness\n        return cachedClearTimeout(marker);\n    } catch (e){\n        try {\n            // When we are in I.E. but the script has been evaled so I.E. doesn't  trust the global object when called normally\n            return cachedClearTimeout.call(null, marker);\n        } catch (e){\n            // same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error.\n            // Some versions of I.E. have different rules for clearTimeout vs setTimeout\n            return cachedClearTimeout.call(this, marker);\n        }\n    }\n\n\n\n}\nvar queue = [];\nvar draining = false;\nvar currentQueue;\nvar queueIndex = -1;\n\nfunction cleanUpNextTick() {\n    if (!draining || !currentQueue) {\n        return;\n    }\n    draining = false;\n    if (currentQueue.length) {\n        queue = currentQueue.concat(queue);\n    } else {\n        queueIndex = -1;\n    }\n    if (queue.length) {\n        drainQueue();\n    }\n}\n\nfunction drainQueue() {\n    if (draining) {\n        return;\n    }\n    var timeout = runTimeout(cleanUpNextTick);\n    draining = true;\n\n    var len = queue.length;\n    while(len) {\n        currentQueue = queue;\n        queue = [];\n        while (++queueIndex < len) {\n            if (currentQueue) {\n                currentQueue[queueIndex].run();\n            }\n        }\n        queueIndex = -1;\n        len = queue.length;\n    }\n    currentQueue = null;\n    draining = false;\n    runClearTimeout(timeout);\n}\n\nprocess.nextTick = function (fun) {\n    var args = new Array(arguments.length - 1);\n    if (arguments.length > 1) {\n        for (var i = 1; i < arguments.length; i++) {\n            args[i - 1] = arguments[i];\n        }\n    }\n    queue.push(new Item(fun, args));\n    if (queue.length === 1 && !draining) {\n        runTimeout(drainQueue);\n    }\n};\n\n// v8 likes predictible objects\nfunction Item(fun, array) {\n    this.fun = fun;\n    this.array = array;\n}\nItem.prototype.run = function () {\n    this.fun.apply(null, this.array);\n};\nprocess.title = 'browser';\nprocess.browser = true;\nprocess.env = {};\nprocess.argv = [];\nprocess.version = ''; // empty string to avoid regexp issues\nprocess.versions = {};\n\nfunction noop() {}\n\nprocess.on = noop;\nprocess.addListener = noop;\nprocess.once = noop;\nprocess.off = noop;\nprocess.removeListener = noop;\nprocess.removeAllListeners = noop;\nprocess.emit = noop;\n\nprocess.binding = function (name) {\n    throw new Error('process.binding is not supported');\n};\n\nprocess.cwd = function () { return '/' };\nprocess.chdir = function (dir) {\n    throw new Error('process.chdir is not supported');\n};\nprocess.umask = function() { return 0; };\n\n},{}],68:[function(require,module,exports){\nmodule.exports = require(\"./lib/_stream_duplex.js\")\n\n},{\"./lib/_stream_duplex.js\":69}],69:[function(require,module,exports){\n// a duplex stream is just a stream that is both readable and writable.\n// Since JS doesn't have multiple prototypal inheritance, this class\n// prototypally inherits from Readable, and then parasitically from\n// Writable.\n\n'use strict';\n\n/*<replacement>*/\n\nvar objectKeys = Object.keys || function (obj) {\n  var keys = [];\n  for (var key in obj) {\n    keys.push(key);\n  }return keys;\n};\n/*</replacement>*/\n\nmodule.exports = Duplex;\n\n/*<replacement>*/\nvar processNextTick = require('process-nextick-args');\n/*</replacement>*/\n\n/*<replacement>*/\nvar util = require('core-util-is');\nutil.inherits = require('inherits');\n/*</replacement>*/\n\nvar Readable = require('./_stream_readable');\nvar Writable = require('./_stream_writable');\n\nutil.inherits(Duplex, Readable);\n\nvar keys = objectKeys(Writable.prototype);\nfor (var v = 0; v < keys.length; v++) {\n  var method = keys[v];\n  if (!Duplex.prototype[method]) Duplex.prototype[method] = Writable.prototype[method];\n}\n\nfunction Duplex(options) {\n  if (!(this instanceof Duplex)) return new Duplex(options);\n\n  Readable.call(this, options);\n  Writable.call(this, options);\n\n  if (options && options.readable === false) this.readable = false;\n\n  if (options && options.writable === false) this.writable = false;\n\n  this.allowHalfOpen = true;\n  if (options && options.allowHalfOpen === false) this.allowHalfOpen = false;\n\n  this.once('end', onend);\n}\n\n// the no-half-open enforcer\nfunction onend() {\n  // if we allow half-open state, or if the writable side ended,\n  // then we're ok.\n  if (this.allowHalfOpen || this._writableState.ended) return;\n\n  // no more data can be written.\n  // But allow more writes to happen in this tick.\n  processNextTick(onEndNT, this);\n}\n\nfunction onEndNT(self) {\n  self.end();\n}\n\nfunction forEach(xs, f) {\n  for (var i = 0, l = xs.length; i < l; i++) {\n    f(xs[i], i);\n  }\n}\n},{\"./_stream_readable\":71,\"./_stream_writable\":73,\"core-util-is\":45,\"inherits\":51,\"process-nextick-args\":66}],70:[function(require,module,exports){\n// a passthrough stream.\n// basically just the most minimal sort of Transform stream.\n// Every written chunk gets output as-is.\n\n'use strict';\n\nmodule.exports = PassThrough;\n\nvar Transform = require('./_stream_transform');\n\n/*<replacement>*/\nvar util = require('core-util-is');\nutil.inherits = require('inherits');\n/*</replacement>*/\n\nutil.inherits(PassThrough, Transform);\n\nfunction PassThrough(options) {\n  if (!(this instanceof PassThrough)) return new PassThrough(options);\n\n  Transform.call(this, options);\n}\n\nPassThrough.prototype._transform = function (chunk, encoding, cb) {\n  cb(null, chunk);\n};\n},{\"./_stream_transform\":72,\"core-util-is\":45,\"inherits\":51}],71:[function(require,module,exports){\n(function (process){\n'use strict';\n\nmodule.exports = Readable;\n\n/*<replacement>*/\nvar processNextTick = require('process-nextick-args');\n/*</replacement>*/\n\n/*<replacement>*/\nvar isArray = require('isarray');\n/*</replacement>*/\n\nReadable.ReadableState = ReadableState;\n\n/*<replacement>*/\nvar EE = require('events').EventEmitter;\n\nvar EElistenerCount = function (emitter, type) {\n  return emitter.listeners(type).length;\n};\n/*</replacement>*/\n\n/*<replacement>*/\nvar Stream;\n(function () {\n  try {\n    Stream = require('st' + 'ream');\n  } catch (_) {} finally {\n    if (!Stream) Stream = require('events').EventEmitter;\n  }\n})();\n/*</replacement>*/\n\nvar Buffer = require('buffer').Buffer;\n/*<replacement>*/\nvar bufferShim = require('buffer-shims');\n/*</replacement>*/\n\n/*<replacement>*/\nvar util = require('core-util-is');\nutil.inherits = require('inherits');\n/*</replacement>*/\n\n/*<replacement>*/\nvar debugUtil = require('util');\nvar debug = void 0;\nif (debugUtil && debugUtil.debuglog) {\n  debug = debugUtil.debuglog('stream');\n} else {\n  debug = function () {};\n}\n/*</replacement>*/\n\nvar BufferList = require('./internal/streams/BufferList');\nvar StringDecoder;\n\nutil.inherits(Readable, Stream);\n\nfunction prependListener(emitter, event, fn) {\n  if (typeof emitter.prependListener === 'function') {\n    return emitter.prependListener(event, fn);\n  } else {\n    // This is a hack to make sure that our error handler is attached before any\n    // userland ones.  NEVER DO THIS. This is here only because this code needs\n    // to continue to work with older versions of Node.js that do not include\n    // the prependListener() method. The goal is to eventually remove this hack.\n    if (!emitter._events || !emitter._events[event]) emitter.on(event, fn);else if (isArray(emitter._events[event])) emitter._events[event].unshift(fn);else emitter._events[event] = [fn, emitter._events[event]];\n  }\n}\n\nvar Duplex;\nfunction ReadableState(options, stream) {\n  Duplex = Duplex || require('./_stream_duplex');\n\n  options = options || {};\n\n  // object stream flag. Used to make read(n) ignore n and to\n  // make all the buffer merging and length checks go away\n  this.objectMode = !!options.objectMode;\n\n  if (stream instanceof Duplex) this.objectMode = this.objectMode || !!options.readableObjectMode;\n\n  // the point at which it stops calling _read() to fill the buffer\n  // Note: 0 is a valid value, means \"don't call _read preemptively ever\"\n  var hwm = options.highWaterMark;\n  var defaultHwm = this.objectMode ? 16 : 16 * 1024;\n  this.highWaterMark = hwm || hwm === 0 ? hwm : defaultHwm;\n\n  // cast to ints.\n  this.highWaterMark = ~ ~this.highWaterMark;\n\n  // A linked list is used to store data chunks instead of an array because the\n  // linked list can remove elements from the beginning faster than\n  // array.shift()\n  this.buffer = new BufferList();\n  this.length = 0;\n  this.pipes = null;\n  this.pipesCount = 0;\n  this.flowing = null;\n  this.ended = false;\n  this.endEmitted = false;\n  this.reading = false;\n\n  // a flag to be able to tell if the onwrite cb is called immediately,\n  // or on a later tick.  We set this to true at first, because any\n  // actions that shouldn't happen until \"later\" should generally also\n  // not happen before the first write call.\n  this.sync = true;\n\n  // whenever we return null, then we set a flag to say\n  // that we're awaiting a 'readable' event emission.\n  this.needReadable = false;\n  this.emittedReadable = false;\n  this.readableListening = false;\n  this.resumeScheduled = false;\n\n  // Crypto is kind of old and crusty.  Historically, its default string\n  // encoding is 'binary' so we have to make this configurable.\n  // Everything else in the universe uses 'utf8', though.\n  this.defaultEncoding = options.defaultEncoding || 'utf8';\n\n  // when piping, we only care about 'readable' events that happen\n  // after read()ing all the bytes and not getting any pushback.\n  this.ranOut = false;\n\n  // the number of writers that are awaiting a drain event in .pipe()s\n  this.awaitDrain = 0;\n\n  // if true, a maybeReadMore has been scheduled\n  this.readingMore = false;\n\n  this.decoder = null;\n  this.encoding = null;\n  if (options.encoding) {\n    if (!StringDecoder) StringDecoder = require('string_decoder/').StringDecoder;\n    this.decoder = new StringDecoder(options.encoding);\n    this.encoding = options.encoding;\n  }\n}\n\nvar Duplex;\nfunction Readable(options) {\n  Duplex = Duplex || require('./_stream_duplex');\n\n  if (!(this instanceof Readable)) return new Readable(options);\n\n  this._readableState = new ReadableState(options, this);\n\n  // legacy\n  this.readable = true;\n\n  if (options && typeof options.read === 'function') this._read = options.read;\n\n  Stream.call(this);\n}\n\n// Manually shove something into the read() buffer.\n// This returns true if the highWaterMark has not been hit yet,\n// similar to how Writable.write() returns true if you should\n// write() some more.\nReadable.prototype.push = function (chunk, encoding) {\n  var state = this._readableState;\n\n  if (!state.objectMode && typeof chunk === 'string') {\n    encoding = encoding || state.defaultEncoding;\n    if (encoding !== state.encoding) {\n      chunk = bufferShim.from(chunk, encoding);\n      encoding = '';\n    }\n  }\n\n  return readableAddChunk(this, state, chunk, encoding, false);\n};\n\n// Unshift should *always* be something directly out of read()\nReadable.prototype.unshift = function (chunk) {\n  var state = this._readableState;\n  return readableAddChunk(this, state, chunk, '', true);\n};\n\nReadable.prototype.isPaused = function () {\n  return this._readableState.flowing === false;\n};\n\nfunction readableAddChunk(stream, state, chunk, encoding, addToFront) {\n  var er = chunkInvalid(state, chunk);\n  if (er) {\n    stream.emit('error', er);\n  } else if (chunk === null) {\n    state.reading = false;\n    onEofChunk(stream, state);\n  } else if (state.objectMode || chunk && chunk.length > 0) {\n    if (state.ended && !addToFront) {\n      var e = new Error('stream.push() after EOF');\n      stream.emit('error', e);\n    } else if (state.endEmitted && addToFront) {\n      var _e = new Error('stream.unshift() after end event');\n      stream.emit('error', _e);\n    } else {\n      var skipAdd;\n      if (state.decoder && !addToFront && !encoding) {\n        chunk = state.decoder.write(chunk);\n        skipAdd = !state.objectMode && chunk.length === 0;\n      }\n\n      if (!addToFront) state.reading = false;\n\n      // Don't add to the buffer if we've decoded to an empty string chunk and\n      // we're not in object mode\n      if (!skipAdd) {\n        // if we want the data now, just emit it.\n        if (state.flowing && state.length === 0 && !state.sync) {\n          stream.emit('data', chunk);\n          stream.read(0);\n        } else {\n          // update the buffer info.\n          state.length += state.objectMode ? 1 : chunk.length;\n          if (addToFront) state.buffer.unshift(chunk);else state.buffer.push(chunk);\n\n          if (state.needReadable) emitReadable(stream);\n        }\n      }\n\n      maybeReadMore(stream, state);\n    }\n  } else if (!addToFront) {\n    state.reading = false;\n  }\n\n  return needMoreData(state);\n}\n\n// if it's past the high water mark, we can push in some more.\n// Also, if we have no data yet, we can stand some\n// more bytes.  This is to work around cases where hwm=0,\n// such as the repl.  Also, if the push() triggered a\n// readable event, and the user called read(largeNumber) such that\n// needReadable was set, then we ought to push more, so that another\n// 'readable' event will be triggered.\nfunction needMoreData(state) {\n  return !state.ended && (state.needReadable || state.length < state.highWaterMark || state.length === 0);\n}\n\n// backwards compatibility.\nReadable.prototype.setEncoding = function (enc) {\n  if (!StringDecoder) StringDecoder = require('string_decoder/').StringDecoder;\n  this._readableState.decoder = new StringDecoder(enc);\n  this._readableState.encoding = enc;\n  return this;\n};\n\n// Don't raise the hwm > 8MB\nvar MAX_HWM = 0x800000;\nfunction computeNewHighWaterMark(n) {\n  if (n >= MAX_HWM) {\n    n = MAX_HWM;\n  } else {\n    // Get the next highest power of 2 to prevent increasing hwm excessively in\n    // tiny amounts\n    n--;\n    n |= n >>> 1;\n    n |= n >>> 2;\n    n |= n >>> 4;\n    n |= n >>> 8;\n    n |= n >>> 16;\n    n++;\n  }\n  return n;\n}\n\n// This function is designed to be inlinable, so please take care when making\n// changes to the function body.\nfunction howMuchToRead(n, state) {\n  if (n <= 0 || state.length === 0 && state.ended) return 0;\n  if (state.objectMode) return 1;\n  if (n !== n) {\n    // Only flow one buffer at a time\n    if (state.flowing && state.length) return state.buffer.head.data.length;else return state.length;\n  }\n  // If we're asking for more than the current hwm, then raise the hwm.\n  if (n > state.highWaterMark) state.highWaterMark = computeNewHighWaterMark(n);\n  if (n <= state.length) return n;\n  // Don't have enough\n  if (!state.ended) {\n    state.needReadable = true;\n    return 0;\n  }\n  return state.length;\n}\n\n// you can override either this method, or the async _read(n) below.\nReadable.prototype.read = function (n) {\n  debug('read', n);\n  n = parseInt(n, 10);\n  var state = this._readableState;\n  var nOrig = n;\n\n  if (n !== 0) state.emittedReadable = false;\n\n  // if we're doing read(0) to trigger a readable event, but we\n  // already have a bunch of data in the buffer, then just trigger\n  // the 'readable' event and move on.\n  if (n === 0 && state.needReadable && (state.length >= state.highWaterMark || state.ended)) {\n    debug('read: emitReadable', state.length, state.ended);\n    if (state.length === 0 && state.ended) endReadable(this);else emitReadable(this);\n    return null;\n  }\n\n  n = howMuchToRead(n, state);\n\n  // if we've ended, and we're now clear, then finish it up.\n  if (n === 0 && state.ended) {\n    if (state.length === 0) endReadable(this);\n    return null;\n  }\n\n  // All the actual chunk generation logic needs to be\n  // *below* the call to _read.  The reason is that in certain\n  // synthetic stream cases, such as passthrough streams, _read\n  // may be a completely synchronous operation which may change\n  // the state of the read buffer, providing enough data when\n  // before there was *not* enough.\n  //\n  // So, the steps are:\n  // 1. Figure out what the state of things will be after we do\n  // a read from the buffer.\n  //\n  // 2. If that resulting state will trigger a _read, then call _read.\n  // Note that this may be asynchronous, or synchronous.  Yes, it is\n  // deeply ugly to write APIs this way, but that still doesn't mean\n  // that the Readable class should behave improperly, as streams are\n  // designed to be sync/async agnostic.\n  // Take note if the _read call is sync or async (ie, if the read call\n  // has returned yet), so that we know whether or not it's safe to emit\n  // 'readable' etc.\n  //\n  // 3. Actually pull the requested chunks out of the buffer and return.\n\n  // if we need a readable event, then we need to do some reading.\n  var doRead = state.needReadable;\n  debug('need readable', doRead);\n\n  // if we currently have less than the highWaterMark, then also read some\n  if (state.length === 0 || state.length - n < state.highWaterMark) {\n    doRead = true;\n    debug('length less than watermark', doRead);\n  }\n\n  // however, if we've ended, then there's no point, and if we're already\n  // reading, then it's unnecessary.\n  if (state.ended || state.reading) {\n    doRead = false;\n    debug('reading or ended', doRead);\n  } else if (doRead) {\n    debug('do read');\n    state.reading = true;\n    state.sync = true;\n    // if the length is currently zero, then we *need* a readable event.\n    if (state.length === 0) state.needReadable = true;\n    // call internal read method\n    this._read(state.highWaterMark);\n    state.sync = false;\n    // If _read pushed data synchronously, then `reading` will be false,\n    // and we need to re-evaluate how much data we can return to the user.\n    if (!state.reading) n = howMuchToRead(nOrig, state);\n  }\n\n  var ret;\n  if (n > 0) ret = fromList(n, state);else ret = null;\n\n  if (ret === null) {\n    state.needReadable = true;\n    n = 0;\n  } else {\n    state.length -= n;\n  }\n\n  if (state.length === 0) {\n    // If we have nothing in the buffer, then we want to know\n    // as soon as we *do* get something into the buffer.\n    if (!state.ended) state.needReadable = true;\n\n    // If we tried to read() past the EOF, then emit end on the next tick.\n    if (nOrig !== n && state.ended) endReadable(this);\n  }\n\n  if (ret !== null) this.emit('data', ret);\n\n  return ret;\n};\n\nfunction chunkInvalid(state, chunk) {\n  var er = null;\n  if (!Buffer.isBuffer(chunk) && typeof chunk !== 'string' && chunk !== null && chunk !== undefined && !state.objectMode) {\n    er = new TypeError('Invalid non-string/buffer chunk');\n  }\n  return er;\n}\n\nfunction onEofChunk(stream, state) {\n  if (state.ended) return;\n  if (state.decoder) {\n    var chunk = state.decoder.end();\n    if (chunk && chunk.length) {\n      state.buffer.push(chunk);\n      state.length += state.objectMode ? 1 : chunk.length;\n    }\n  }\n  state.ended = true;\n\n  // emit 'readable' now to make sure it gets picked up.\n  emitReadable(stream);\n}\n\n// Don't emit readable right away in sync mode, because this can trigger\n// another read() call => stack overflow.  This way, it might trigger\n// a nextTick recursion warning, but that's not so bad.\nfunction emitReadable(stream) {\n  var state = stream._readableState;\n  state.needReadable = false;\n  if (!state.emittedReadable) {\n    debug('emitReadable', state.flowing);\n    state.emittedReadable = true;\n    if (state.sync) processNextTick(emitReadable_, stream);else emitReadable_(stream);\n  }\n}\n\nfunction emitReadable_(stream) {\n  debug('emit readable');\n  stream.emit('readable');\n  flow(stream);\n}\n\n// at this point, the user has presumably seen the 'readable' event,\n// and called read() to consume some data.  that may have triggered\n// in turn another _read(n) call, in which case reading = true if\n// it's in progress.\n// However, if we're not ended, or reading, and the length < hwm,\n// then go ahead and try to read some more preemptively.\nfunction maybeReadMore(stream, state) {\n  if (!state.readingMore) {\n    state.readingMore = true;\n    processNextTick(maybeReadMore_, stream, state);\n  }\n}\n\nfunction maybeReadMore_(stream, state) {\n  var len = state.length;\n  while (!state.reading && !state.flowing && !state.ended && state.length < state.highWaterMark) {\n    debug('maybeReadMore read 0');\n    stream.read(0);\n    if (len === state.length)\n      // didn't get any data, stop spinning.\n      break;else len = state.length;\n  }\n  state.readingMore = false;\n}\n\n// abstract method.  to be overridden in specific implementation classes.\n// call cb(er, data) where data is <= n in length.\n// for virtual (non-string, non-buffer) streams, \"length\" is somewhat\n// arbitrary, and perhaps not very meaningful.\nReadable.prototype._read = function (n) {\n  this.emit('error', new Error('not implemented'));\n};\n\nReadable.prototype.pipe = function (dest, pipeOpts) {\n  var src = this;\n  var state = this._readableState;\n\n  switch (state.pipesCount) {\n    case 0:\n      state.pipes = dest;\n      break;\n    case 1:\n      state.pipes = [state.pipes, dest];\n      break;\n    default:\n      state.pipes.push(dest);\n      break;\n  }\n  state.pipesCount += 1;\n  debug('pipe count=%d opts=%j', state.pipesCount, pipeOpts);\n\n  var doEnd = (!pipeOpts || pipeOpts.end !== false) && dest !== process.stdout && dest !== process.stderr;\n\n  var endFn = doEnd ? onend : cleanup;\n  if (state.endEmitted) processNextTick(endFn);else src.once('end', endFn);\n\n  dest.on('unpipe', onunpipe);\n  function onunpipe(readable) {\n    debug('onunpipe');\n    if (readable === src) {\n      cleanup();\n    }\n  }\n\n  function onend() {\n    debug('onend');\n    dest.end();\n  }\n\n  // when the dest drains, it reduces the awaitDrain counter\n  // on the source.  This would be more elegant with a .once()\n  // handler in flow(), but adding and removing repeatedly is\n  // too slow.\n  var ondrain = pipeOnDrain(src);\n  dest.on('drain', ondrain);\n\n  var cleanedUp = false;\n  function cleanup() {\n    debug('cleanup');\n    // cleanup event handlers once the pipe is broken\n    dest.removeListener('close', onclose);\n    dest.removeListener('finish', onfinish);\n    dest.removeListener('drain', ondrain);\n    dest.removeListener('error', onerror);\n    dest.removeListener('unpipe', onunpipe);\n    src.removeListener('end', onend);\n    src.removeListener('end', cleanup);\n    src.removeListener('data', ondata);\n\n    cleanedUp = true;\n\n    // if the reader is waiting for a drain event from this\n    // specific writer, then it would cause it to never start\n    // flowing again.\n    // So, if this is awaiting a drain, then we just call it now.\n    // If we don't know, then assume that we are waiting for one.\n    if (state.awaitDrain && (!dest._writableState || dest._writableState.needDrain)) ondrain();\n  }\n\n  // If the user pushes more data while we're writing to dest then we'll end up\n  // in ondata again. However, we only want to increase awaitDrain once because\n  // dest will only emit one 'drain' event for the multiple writes.\n  // => Introduce a guard on increasing awaitDrain.\n  var increasedAwaitDrain = false;\n  src.on('data', ondata);\n  function ondata(chunk) {\n    debug('ondata');\n    increasedAwaitDrain = false;\n    var ret = dest.write(chunk);\n    if (false === ret && !increasedAwaitDrain) {\n      // If the user unpiped during `dest.write()`, it is possible\n      // to get stuck in a permanently paused state if that write\n      // also returned false.\n      // => Check whether `dest` is still a piping destination.\n      if ((state.pipesCount === 1 && state.pipes === dest || state.pipesCount > 1 && indexOf(state.pipes, dest) !== -1) && !cleanedUp) {\n        debug('false write response, pause', src._readableState.awaitDrain);\n        src._readableState.awaitDrain++;\n        increasedAwaitDrain = true;\n      }\n      src.pause();\n    }\n  }\n\n  // if the dest has an error, then stop piping into it.\n  // however, don't suppress the throwing behavior for this.\n  function onerror(er) {\n    debug('onerror', er);\n    unpipe();\n    dest.removeListener('error', onerror);\n    if (EElistenerCount(dest, 'error') === 0) dest.emit('error', er);\n  }\n\n  // Make sure our error handler is attached before userland ones.\n  prependListener(dest, 'error', onerror);\n\n  // Both close and finish should trigger unpipe, but only once.\n  function onclose() {\n    dest.removeListener('finish', onfinish);\n    unpipe();\n  }\n  dest.once('close', onclose);\n  function onfinish() {\n    debug('onfinish');\n    dest.removeListener('close', onclose);\n    unpipe();\n  }\n  dest.once('finish', onfinish);\n\n  function unpipe() {\n    debug('unpipe');\n    src.unpipe(dest);\n  }\n\n  // tell the dest that it's being piped to\n  dest.emit('pipe', src);\n\n  // start the flow if it hasn't been started already.\n  if (!state.flowing) {\n    debug('pipe resume');\n    src.resume();\n  }\n\n  return dest;\n};\n\nfunction pipeOnDrain(src) {\n  return function () {\n    var state = src._readableState;\n    debug('pipeOnDrain', state.awaitDrain);\n    if (state.awaitDrain) state.awaitDrain--;\n    if (state.awaitDrain === 0 && EElistenerCount(src, 'data')) {\n      state.flowing = true;\n      flow(src);\n    }\n  };\n}\n\nReadable.prototype.unpipe = function (dest) {\n  var state = this._readableState;\n\n  // if we're not piping anywhere, then do nothing.\n  if (state.pipesCount === 0) return this;\n\n  // just one destination.  most common case.\n  if (state.pipesCount === 1) {\n    // passed in one, but it's not the right one.\n    if (dest && dest !== state.pipes) return this;\n\n    if (!dest) dest = state.pipes;\n\n    // got a match.\n    state.pipes = null;\n    state.pipesCount = 0;\n    state.flowing = false;\n    if (dest) dest.emit('unpipe', this);\n    return this;\n  }\n\n  // slow case. multiple pipe destinations.\n\n  if (!dest) {\n    // remove all.\n    var dests = state.pipes;\n    var len = state.pipesCount;\n    state.pipes = null;\n    state.pipesCount = 0;\n    state.flowing = false;\n\n    for (var _i = 0; _i < len; _i++) {\n      dests[_i].emit('unpipe', this);\n    }return this;\n  }\n\n  // try to find the right one.\n  var i = indexOf(state.pipes, dest);\n  if (i === -1) return this;\n\n  state.pipes.splice(i, 1);\n  state.pipesCount -= 1;\n  if (state.pipesCount === 1) state.pipes = state.pipes[0];\n\n  dest.emit('unpipe', this);\n\n  return this;\n};\n\n// set up data events if they are asked for\n// Ensure readable listeners eventually get something\nReadable.prototype.on = function (ev, fn) {\n  var res = Stream.prototype.on.call(this, ev, fn);\n\n  if (ev === 'data') {\n    // Start flowing on next tick if stream isn't explicitly paused\n    if (this._readableState.flowing !== false) this.resume();\n  } else if (ev === 'readable') {\n    var state = this._readableState;\n    if (!state.endEmitted && !state.readableListening) {\n      state.readableListening = state.needReadable = true;\n      state.emittedReadable = false;\n      if (!state.reading) {\n        processNextTick(nReadingNextTick, this);\n      } else if (state.length) {\n        emitReadable(this, state);\n      }\n    }\n  }\n\n  return res;\n};\nReadable.prototype.addListener = Readable.prototype.on;\n\nfunction nReadingNextTick(self) {\n  debug('readable nexttick read 0');\n  self.read(0);\n}\n\n// pause() and resume() are remnants of the legacy readable stream API\n// If the user uses them, then switch into old mode.\nReadable.prototype.resume = function () {\n  var state = this._readableState;\n  if (!state.flowing) {\n    debug('resume');\n    state.flowing = true;\n    resume(this, state);\n  }\n  return this;\n};\n\nfunction resume(stream, state) {\n  if (!state.resumeScheduled) {\n    state.resumeScheduled = true;\n    processNextTick(resume_, stream, state);\n  }\n}\n\nfunction resume_(stream, state) {\n  if (!state.reading) {\n    debug('resume read 0');\n    stream.read(0);\n  }\n\n  state.resumeScheduled = false;\n  state.awaitDrain = 0;\n  stream.emit('resume');\n  flow(stream);\n  if (state.flowing && !state.reading) stream.read(0);\n}\n\nReadable.prototype.pause = function () {\n  debug('call pause flowing=%j', this._readableState.flowing);\n  if (false !== this._readableState.flowing) {\n    debug('pause');\n    this._readableState.flowing = false;\n    this.emit('pause');\n  }\n  return this;\n};\n\nfunction flow(stream) {\n  var state = stream._readableState;\n  debug('flow', state.flowing);\n  while (state.flowing && stream.read() !== null) {}\n}\n\n// wrap an old-style stream as the async data source.\n// This is *not* part of the readable stream interface.\n// It is an ugly unfortunate mess of history.\nReadable.prototype.wrap = function (stream) {\n  var state = this._readableState;\n  var paused = false;\n\n  var self = this;\n  stream.on('end', function () {\n    debug('wrapped end');\n    if (state.decoder && !state.ended) {\n      var chunk = state.decoder.end();\n      if (chunk && chunk.length) self.push(chunk);\n    }\n\n    self.push(null);\n  });\n\n  stream.on('data', function (chunk) {\n    debug('wrapped data');\n    if (state.decoder) chunk = state.decoder.write(chunk);\n\n    // don't skip over falsy values in objectMode\n    if (state.objectMode && (chunk === null || chunk === undefined)) return;else if (!state.objectMode && (!chunk || !chunk.length)) return;\n\n    var ret = self.push(chunk);\n    if (!ret) {\n      paused = true;\n      stream.pause();\n    }\n  });\n\n  // proxy all the other methods.\n  // important when wrapping filters and duplexes.\n  for (var i in stream) {\n    if (this[i] === undefined && typeof stream[i] === 'function') {\n      this[i] = function (method) {\n        return function () {\n          return stream[method].apply(stream, arguments);\n        };\n      }(i);\n    }\n  }\n\n  // proxy certain important events.\n  var events = ['error', 'close', 'destroy', 'pause', 'resume'];\n  forEach(events, function (ev) {\n    stream.on(ev, self.emit.bind(self, ev));\n  });\n\n  // when we try to consume some more bytes, simply unpause the\n  // underlying stream.\n  self._read = function (n) {\n    debug('wrapped _read', n);\n    if (paused) {\n      paused = false;\n      stream.resume();\n    }\n  };\n\n  return self;\n};\n\n// exposed for testing purposes only.\nReadable._fromList = fromList;\n\n// Pluck off n bytes from an array of buffers.\n// Length is the combined lengths of all the buffers in the list.\n// This function is designed to be inlinable, so please take care when making\n// changes to the function body.\nfunction fromList(n, state) {\n  // nothing buffered\n  if (state.length === 0) return null;\n\n  var ret;\n  if (state.objectMode) ret = state.buffer.shift();else if (!n || n >= state.length) {\n    // read it all, truncate the list\n    if (state.decoder) ret = state.buffer.join('');else if (state.buffer.length === 1) ret = state.buffer.head.data;else ret = state.buffer.concat(state.length);\n    state.buffer.clear();\n  } else {\n    // read part of list\n    ret = fromListPartial(n, state.buffer, state.decoder);\n  }\n\n  return ret;\n}\n\n// Extracts only enough buffered data to satisfy the amount requested.\n// This function is designed to be inlinable, so please take care when making\n// changes to the function body.\nfunction fromListPartial(n, list, hasStrings) {\n  var ret;\n  if (n < list.head.data.length) {\n    // slice is the same for buffers and strings\n    ret = list.head.data.slice(0, n);\n    list.head.data = list.head.data.slice(n);\n  } else if (n === list.head.data.length) {\n    // first chunk is a perfect match\n    ret = list.shift();\n  } else {\n    // result spans more than one buffer\n    ret = hasStrings ? copyFromBufferString(n, list) : copyFromBuffer(n, list);\n  }\n  return ret;\n}\n\n// Copies a specified amount of characters from the list of buffered data\n// chunks.\n// This function is designed to be inlinable, so please take care when making\n// changes to the function body.\nfunction copyFromBufferString(n, list) {\n  var p = list.head;\n  var c = 1;\n  var ret = p.data;\n  n -= ret.length;\n  while (p = p.next) {\n    var str = p.data;\n    var nb = n > str.length ? str.length : n;\n    if (nb === str.length) ret += str;else ret += str.slice(0, n);\n    n -= nb;\n    if (n === 0) {\n      if (nb === str.length) {\n        ++c;\n        if (p.next) list.head = p.next;else list.head = list.tail = null;\n      } else {\n        list.head = p;\n        p.data = str.slice(nb);\n      }\n      break;\n    }\n    ++c;\n  }\n  list.length -= c;\n  return ret;\n}\n\n// Copies a specified amount of bytes from the list of buffered data chunks.\n// This function is designed to be inlinable, so please take care when making\n// changes to the function body.\nfunction copyFromBuffer(n, list) {\n  var ret = bufferShim.allocUnsafe(n);\n  var p = list.head;\n  var c = 1;\n  p.data.copy(ret);\n  n -= p.data.length;\n  while (p = p.next) {\n    var buf = p.data;\n    var nb = n > buf.length ? buf.length : n;\n    buf.copy(ret, ret.length - n, 0, nb);\n    n -= nb;\n    if (n === 0) {\n      if (nb === buf.length) {\n        ++c;\n        if (p.next) list.head = p.next;else list.head = list.tail = null;\n      } else {\n        list.head = p;\n        p.data = buf.slice(nb);\n      }\n      break;\n    }\n    ++c;\n  }\n  list.length -= c;\n  return ret;\n}\n\nfunction endReadable(stream) {\n  var state = stream._readableState;\n\n  // If we get here before consuming all the bytes, then that is a\n  // bug in node.  Should never happen.\n  if (state.length > 0) throw new Error('\"endReadable()\" called on non-empty stream');\n\n  if (!state.endEmitted) {\n    state.ended = true;\n    processNextTick(endReadableNT, state, stream);\n  }\n}\n\nfunction endReadableNT(state, stream) {\n  // Check that we didn't get one last unshift.\n  if (!state.endEmitted && state.length === 0) {\n    state.endEmitted = true;\n    stream.readable = false;\n    stream.emit('end');\n  }\n}\n\nfunction forEach(xs, f) {\n  for (var i = 0, l = xs.length; i < l; i++) {\n    f(xs[i], i);\n  }\n}\n\nfunction indexOf(xs, x) {\n  for (var i = 0, l = xs.length; i < l; i++) {\n    if (xs[i] === x) return i;\n  }\n  return -1;\n}\n}).call(this,require('_process'))\n},{\"./_stream_duplex\":69,\"./internal/streams/BufferList\":74,\"_process\":67,\"buffer\":44,\"buffer-shims\":43,\"core-util-is\":45,\"events\":48,\"inherits\":51,\"isarray\":53,\"process-nextick-args\":66,\"string_decoder/\":80,\"util\":40}],72:[function(require,module,exports){\n// a transform stream is a readable/writable stream where you do\n// something with the data.  Sometimes it's called a \"filter\",\n// but that's not a great name for it, since that implies a thing where\n// some bits pass through, and others are simply ignored.  (That would\n// be a valid example of a transform, of course.)\n//\n// While the output is causally related to the input, it's not a\n// necessarily symmetric or synchronous transformation.  For example,\n// a zlib stream might take multiple plain-text writes(), and then\n// emit a single compressed chunk some time in the future.\n//\n// Here's how this works:\n//\n// The Transform stream has all the aspects of the readable and writable\n// stream classes.  When you write(chunk), that calls _write(chunk,cb)\n// internally, and returns false if there's a lot of pending writes\n// buffered up.  When you call read(), that calls _read(n) until\n// there's enough pending readable data buffered up.\n//\n// In a transform stream, the written data is placed in a buffer.  When\n// _read(n) is called, it transforms the queued up data, calling the\n// buffered _write cb's as it consumes chunks.  If consuming a single\n// written chunk would result in multiple output chunks, then the first\n// outputted bit calls the readcb, and subsequent chunks just go into\n// the read buffer, and will cause it to emit 'readable' if necessary.\n//\n// This way, back-pressure is actually determined by the reading side,\n// since _read has to be called to start processing a new chunk.  However,\n// a pathological inflate type of transform can cause excessive buffering\n// here.  For example, imagine a stream where every byte of input is\n// interpreted as an integer from 0-255, and then results in that many\n// bytes of output.  Writing the 4 bytes {ff,ff,ff,ff} would result in\n// 1kb of data being output.  In this case, you could write a very small\n// amount of input, and end up with a very large amount of output.  In\n// such a pathological inflating mechanism, there'd be no way to tell\n// the system to stop doing the transform.  A single 4MB write could\n// cause the system to run out of memory.\n//\n// However, even in such a pathological case, only a single written chunk\n// would be consumed, and then the rest would wait (un-transformed) until\n// the results of the previous transformed chunk were consumed.\n\n'use strict';\n\nmodule.exports = Transform;\n\nvar Duplex = require('./_stream_duplex');\n\n/*<replacement>*/\nvar util = require('core-util-is');\nutil.inherits = require('inherits');\n/*</replacement>*/\n\nutil.inherits(Transform, Duplex);\n\nfunction TransformState(stream) {\n  this.afterTransform = function (er, data) {\n    return afterTransform(stream, er, data);\n  };\n\n  this.needTransform = false;\n  this.transforming = false;\n  this.writecb = null;\n  this.writechunk = null;\n  this.writeencoding = null;\n}\n\nfunction afterTransform(stream, er, data) {\n  var ts = stream._transformState;\n  ts.transforming = false;\n\n  var cb = ts.writecb;\n\n  if (!cb) return stream.emit('error', new Error('no writecb in Transform class'));\n\n  ts.writechunk = null;\n  ts.writecb = null;\n\n  if (data !== null && data !== undefined) stream.push(data);\n\n  cb(er);\n\n  var rs = stream._readableState;\n  rs.reading = false;\n  if (rs.needReadable || rs.length < rs.highWaterMark) {\n    stream._read(rs.highWaterMark);\n  }\n}\n\nfunction Transform(options) {\n  if (!(this instanceof Transform)) return new Transform(options);\n\n  Duplex.call(this, options);\n\n  this._transformState = new TransformState(this);\n\n  // when the writable side finishes, then flush out anything remaining.\n  var stream = this;\n\n  // start out asking for a readable event once data is transformed.\n  this._readableState.needReadable = true;\n\n  // we have implemented the _read method, and done the other things\n  // that Readable wants before the first _read call, so unset the\n  // sync guard flag.\n  this._readableState.sync = false;\n\n  if (options) {\n    if (typeof options.transform === 'function') this._transform = options.transform;\n\n    if (typeof options.flush === 'function') this._flush = options.flush;\n  }\n\n  this.once('prefinish', function () {\n    if (typeof this._flush === 'function') this._flush(function (er) {\n      done(stream, er);\n    });else done(stream);\n  });\n}\n\nTransform.prototype.push = function (chunk, encoding) {\n  this._transformState.needTransform = false;\n  return Duplex.prototype.push.call(this, chunk, encoding);\n};\n\n// This is the part where you do stuff!\n// override this function in implementation classes.\n// 'chunk' is an input chunk.\n//\n// Call `push(newChunk)` to pass along transformed output\n// to the readable side.  You may call 'push' zero or more times.\n//\n// Call `cb(err)` when you are done with this chunk.  If you pass\n// an error, then that'll put the hurt on the whole operation.  If you\n// never call cb(), then you'll never get another chunk.\nTransform.prototype._transform = function (chunk, encoding, cb) {\n  throw new Error('Not implemented');\n};\n\nTransform.prototype._write = function (chunk, encoding, cb) {\n  var ts = this._transformState;\n  ts.writecb = cb;\n  ts.writechunk = chunk;\n  ts.writeencoding = encoding;\n  if (!ts.transforming) {\n    var rs = this._readableState;\n    if (ts.needTransform || rs.needReadable || rs.length < rs.highWaterMark) this._read(rs.highWaterMark);\n  }\n};\n\n// Doesn't matter what the args are here.\n// _transform does all the work.\n// That we got here means that the readable side wants more data.\nTransform.prototype._read = function (n) {\n  var ts = this._transformState;\n\n  if (ts.writechunk !== null && ts.writecb && !ts.transforming) {\n    ts.transforming = true;\n    this._transform(ts.writechunk, ts.writeencoding, ts.afterTransform);\n  } else {\n    // mark that we need a transform, so that any data that comes in\n    // will get processed, now that we've asked for it.\n    ts.needTransform = true;\n  }\n};\n\nfunction done(stream, er) {\n  if (er) return stream.emit('error', er);\n\n  // if there's nothing in the write buffer, then that means\n  // that nothing more will ever be provided\n  var ws = stream._writableState;\n  var ts = stream._transformState;\n\n  if (ws.length) throw new Error('Calling transform done when ws.length != 0');\n\n  if (ts.transforming) throw new Error('Calling transform done when still transforming');\n\n  return stream.push(null);\n}\n},{\"./_stream_duplex\":69,\"core-util-is\":45,\"inherits\":51}],73:[function(require,module,exports){\n(function (process){\n// A bit simpler than readable streams.\n// Implement an async ._write(chunk, encoding, cb), and it'll handle all\n// the drain event emission and buffering.\n\n'use strict';\n\nmodule.exports = Writable;\n\n/*<replacement>*/\nvar processNextTick = require('process-nextick-args');\n/*</replacement>*/\n\n/*<replacement>*/\nvar asyncWrite = !process.browser && ['v0.10', 'v0.9.'].indexOf(process.version.slice(0, 5)) > -1 ? setImmediate : processNextTick;\n/*</replacement>*/\n\nWritable.WritableState = WritableState;\n\n/*<replacement>*/\nvar util = require('core-util-is');\nutil.inherits = require('inherits');\n/*</replacement>*/\n\n/*<replacement>*/\nvar internalUtil = {\n  deprecate: require('util-deprecate')\n};\n/*</replacement>*/\n\n/*<replacement>*/\nvar Stream;\n(function () {\n  try {\n    Stream = require('st' + 'ream');\n  } catch (_) {} finally {\n    if (!Stream) Stream = require('events').EventEmitter;\n  }\n})();\n/*</replacement>*/\n\nvar Buffer = require('buffer').Buffer;\n/*<replacement>*/\nvar bufferShim = require('buffer-shims');\n/*</replacement>*/\n\nutil.inherits(Writable, Stream);\n\nfunction nop() {}\n\nfunction WriteReq(chunk, encoding, cb) {\n  this.chunk = chunk;\n  this.encoding = encoding;\n  this.callback = cb;\n  this.next = null;\n}\n\nvar Duplex;\nfunction WritableState(options, stream) {\n  Duplex = Duplex || require('./_stream_duplex');\n\n  options = options || {};\n\n  // object stream flag to indicate whether or not this stream\n  // contains buffers or objects.\n  this.objectMode = !!options.objectMode;\n\n  if (stream instanceof Duplex) this.objectMode = this.objectMode || !!options.writableObjectMode;\n\n  // the point at which write() starts returning false\n  // Note: 0 is a valid value, means that we always return false if\n  // the entire buffer is not flushed immediately on write()\n  var hwm = options.highWaterMark;\n  var defaultHwm = this.objectMode ? 16 : 16 * 1024;\n  this.highWaterMark = hwm || hwm === 0 ? hwm : defaultHwm;\n\n  // cast to ints.\n  this.highWaterMark = ~ ~this.highWaterMark;\n\n  this.needDrain = false;\n  // at the start of calling end()\n  this.ending = false;\n  // when end() has been called, and returned\n  this.ended = false;\n  // when 'finish' is emitted\n  this.finished = false;\n\n  // should we decode strings into buffers before passing to _write?\n  // this is here so that some node-core streams can optimize string\n  // handling at a lower level.\n  var noDecode = options.decodeStrings === false;\n  this.decodeStrings = !noDecode;\n\n  // Crypto is kind of old and crusty.  Historically, its default string\n  // encoding is 'binary' so we have to make this configurable.\n  // Everything else in the universe uses 'utf8', though.\n  this.defaultEncoding = options.defaultEncoding || 'utf8';\n\n  // not an actual buffer we keep track of, but a measurement\n  // of how much we're waiting to get pushed to some underlying\n  // socket or file.\n  this.length = 0;\n\n  // a flag to see when we're in the middle of a write.\n  this.writing = false;\n\n  // when true all writes will be buffered until .uncork() call\n  this.corked = 0;\n\n  // a flag to be able to tell if the onwrite cb is called immediately,\n  // or on a later tick.  We set this to true at first, because any\n  // actions that shouldn't happen until \"later\" should generally also\n  // not happen before the first write call.\n  this.sync = true;\n\n  // a flag to know if we're processing previously buffered items, which\n  // may call the _write() callback in the same tick, so that we don't\n  // end up in an overlapped onwrite situation.\n  this.bufferProcessing = false;\n\n  // the callback that's passed to _write(chunk,cb)\n  this.onwrite = function (er) {\n    onwrite(stream, er);\n  };\n\n  // the callback that the user supplies to write(chunk,encoding,cb)\n  this.writecb = null;\n\n  // the amount that is being written when _write is called.\n  this.writelen = 0;\n\n  this.bufferedRequest = null;\n  this.lastBufferedRequest = null;\n\n  // number of pending user-supplied write callbacks\n  // this must be 0 before 'finish' can be emitted\n  this.pendingcb = 0;\n\n  // emit prefinish if the only thing we're waiting for is _write cbs\n  // This is relevant for synchronous Transform streams\n  this.prefinished = false;\n\n  // True if the error was already emitted and should not be thrown again\n  this.errorEmitted = false;\n\n  // count buffered requests\n  this.bufferedRequestCount = 0;\n\n  // allocate the first CorkedRequest, there is always\n  // one allocated and free to use, and we maintain at most two\n  this.corkedRequestsFree = new CorkedRequest(this);\n}\n\nWritableState.prototype.getBuffer = function writableStateGetBuffer() {\n  var current = this.bufferedRequest;\n  var out = [];\n  while (current) {\n    out.push(current);\n    current = current.next;\n  }\n  return out;\n};\n\n(function () {\n  try {\n    Object.defineProperty(WritableState.prototype, 'buffer', {\n      get: internalUtil.deprecate(function () {\n        return this.getBuffer();\n      }, '_writableState.buffer is deprecated. Use _writableState.getBuffer ' + 'instead.')\n    });\n  } catch (_) {}\n})();\n\nvar Duplex;\nfunction Writable(options) {\n  Duplex = Duplex || require('./_stream_duplex');\n\n  // Writable ctor is applied to Duplexes, though they're not\n  // instanceof Writable, they're instanceof Readable.\n  if (!(this instanceof Writable) && !(this instanceof Duplex)) return new Writable(options);\n\n  this._writableState = new WritableState(options, this);\n\n  // legacy.\n  this.writable = true;\n\n  if (options) {\n    if (typeof options.write === 'function') this._write = options.write;\n\n    if (typeof options.writev === 'function') this._writev = options.writev;\n  }\n\n  Stream.call(this);\n}\n\n// Otherwise people can pipe Writable streams, which is just wrong.\nWritable.prototype.pipe = function () {\n  this.emit('error', new Error('Cannot pipe, not readable'));\n};\n\nfunction writeAfterEnd(stream, cb) {\n  var er = new Error('write after end');\n  // TODO: defer error events consistently everywhere, not just the cb\n  stream.emit('error', er);\n  processNextTick(cb, er);\n}\n\n// If we get something that is not a buffer, string, null, or undefined,\n// and we're not in objectMode, then that's an error.\n// Otherwise stream chunks are all considered to be of length=1, and the\n// watermarks determine how many objects to keep in the buffer, rather than\n// how many bytes or characters.\nfunction validChunk(stream, state, chunk, cb) {\n  var valid = true;\n  var er = false;\n  // Always throw error if a null is written\n  // if we are not in object mode then throw\n  // if it is not a buffer, string, or undefined.\n  if (chunk === null) {\n    er = new TypeError('May not write null values to stream');\n  } else if (!Buffer.isBuffer(chunk) && typeof chunk !== 'string' && chunk !== undefined && !state.objectMode) {\n    er = new TypeError('Invalid non-string/buffer chunk');\n  }\n  if (er) {\n    stream.emit('error', er);\n    processNextTick(cb, er);\n    valid = false;\n  }\n  return valid;\n}\n\nWritable.prototype.write = function (chunk, encoding, cb) {\n  var state = this._writableState;\n  var ret = false;\n\n  if (typeof encoding === 'function') {\n    cb = encoding;\n    encoding = null;\n  }\n\n  if (Buffer.isBuffer(chunk)) encoding = 'buffer';else if (!encoding) encoding = state.defaultEncoding;\n\n  if (typeof cb !== 'function') cb = nop;\n\n  if (state.ended) writeAfterEnd(this, cb);else if (validChunk(this, state, chunk, cb)) {\n    state.pendingcb++;\n    ret = writeOrBuffer(this, state, chunk, encoding, cb);\n  }\n\n  return ret;\n};\n\nWritable.prototype.cork = function () {\n  var state = this._writableState;\n\n  state.corked++;\n};\n\nWritable.prototype.uncork = function () {\n  var state = this._writableState;\n\n  if (state.corked) {\n    state.corked--;\n\n    if (!state.writing && !state.corked && !state.finished && !state.bufferProcessing && state.bufferedRequest) clearBuffer(this, state);\n  }\n};\n\nWritable.prototype.setDefaultEncoding = function setDefaultEncoding(encoding) {\n  // node::ParseEncoding() requires lower case.\n  if (typeof encoding === 'string') encoding = encoding.toLowerCase();\n  if (!(['hex', 'utf8', 'utf-8', 'ascii', 'binary', 'base64', 'ucs2', 'ucs-2', 'utf16le', 'utf-16le', 'raw'].indexOf((encoding + '').toLowerCase()) > -1)) throw new TypeError('Unknown encoding: ' + encoding);\n  this._writableState.defaultEncoding = encoding;\n  return this;\n};\n\nfunction decodeChunk(state, chunk, encoding) {\n  if (!state.objectMode && state.decodeStrings !== false && typeof chunk === 'string') {\n    chunk = bufferShim.from(chunk, encoding);\n  }\n  return chunk;\n}\n\n// if we're already writing something, then just put this\n// in the queue, and wait our turn.  Otherwise, call _write\n// If we return false, then we need a drain event, so set that flag.\nfunction writeOrBuffer(stream, state, chunk, encoding, cb) {\n  chunk = decodeChunk(state, chunk, encoding);\n\n  if (Buffer.isBuffer(chunk)) encoding = 'buffer';\n  var len = state.objectMode ? 1 : chunk.length;\n\n  state.length += len;\n\n  var ret = state.length < state.highWaterMark;\n  // we must ensure that previous needDrain will not be reset to false.\n  if (!ret) state.needDrain = true;\n\n  if (state.writing || state.corked) {\n    var last = state.lastBufferedRequest;\n    state.lastBufferedRequest = new WriteReq(chunk, encoding, cb);\n    if (last) {\n      last.next = state.lastBufferedRequest;\n    } else {\n      state.bufferedRequest = state.lastBufferedRequest;\n    }\n    state.bufferedRequestCount += 1;\n  } else {\n    doWrite(stream, state, false, len, chunk, encoding, cb);\n  }\n\n  return ret;\n}\n\nfunction doWrite(stream, state, writev, len, chunk, encoding, cb) {\n  state.writelen = len;\n  state.writecb = cb;\n  state.writing = true;\n  state.sync = true;\n  if (writev) stream._writev(chunk, state.onwrite);else stream._write(chunk, encoding, state.onwrite);\n  state.sync = false;\n}\n\nfunction onwriteError(stream, state, sync, er, cb) {\n  --state.pendingcb;\n  if (sync) processNextTick(cb, er);else cb(er);\n\n  stream._writableState.errorEmitted = true;\n  stream.emit('error', er);\n}\n\nfunction onwriteStateUpdate(state) {\n  state.writing = false;\n  state.writecb = null;\n  state.length -= state.writelen;\n  state.writelen = 0;\n}\n\nfunction onwrite(stream, er) {\n  var state = stream._writableState;\n  var sync = state.sync;\n  var cb = state.writecb;\n\n  onwriteStateUpdate(state);\n\n  if (er) onwriteError(stream, state, sync, er, cb);else {\n    // Check if we're actually ready to finish, but don't emit yet\n    var finished = needFinish(state);\n\n    if (!finished && !state.corked && !state.bufferProcessing && state.bufferedRequest) {\n      clearBuffer(stream, state);\n    }\n\n    if (sync) {\n      /*<replacement>*/\n      asyncWrite(afterWrite, stream, state, finished, cb);\n      /*</replacement>*/\n    } else {\n        afterWrite(stream, state, finished, cb);\n      }\n  }\n}\n\nfunction afterWrite(stream, state, finished, cb) {\n  if (!finished) onwriteDrain(stream, state);\n  state.pendingcb--;\n  cb();\n  finishMaybe(stream, state);\n}\n\n// Must force callback to be called on nextTick, so that we don't\n// emit 'drain' before the write() consumer gets the 'false' return\n// value, and has a chance to attach a 'drain' listener.\nfunction onwriteDrain(stream, state) {\n  if (state.length === 0 && state.needDrain) {\n    state.needDrain = false;\n    stream.emit('drain');\n  }\n}\n\n// if there's something in the buffer waiting, then process it\nfunction clearBuffer(stream, state) {\n  state.bufferProcessing = true;\n  var entry = state.bufferedRequest;\n\n  if (stream._writev && entry && entry.next) {\n    // Fast case, write everything using _writev()\n    var l = state.bufferedRequestCount;\n    var buffer = new Array(l);\n    var holder = state.corkedRequestsFree;\n    holder.entry = entry;\n\n    var count = 0;\n    while (entry) {\n      buffer[count] = entry;\n      entry = entry.next;\n      count += 1;\n    }\n\n    doWrite(stream, state, true, state.length, buffer, '', holder.finish);\n\n    // doWrite is almost always async, defer these to save a bit of time\n    // as the hot path ends with doWrite\n    state.pendingcb++;\n    state.lastBufferedRequest = null;\n    if (holder.next) {\n      state.corkedRequestsFree = holder.next;\n      holder.next = null;\n    } else {\n      state.corkedRequestsFree = new CorkedRequest(state);\n    }\n  } else {\n    // Slow case, write chunks one-by-one\n    while (entry) {\n      var chunk = entry.chunk;\n      var encoding = entry.encoding;\n      var cb = entry.callback;\n      var len = state.objectMode ? 1 : chunk.length;\n\n      doWrite(stream, state, false, len, chunk, encoding, cb);\n      entry = entry.next;\n      // if we didn't call the onwrite immediately, then\n      // it means that we need to wait until it does.\n      // also, that means that the chunk and cb are currently\n      // being processed, so move the buffer counter past them.\n      if (state.writing) {\n        break;\n      }\n    }\n\n    if (entry === null) state.lastBufferedRequest = null;\n  }\n\n  state.bufferedRequestCount = 0;\n  state.bufferedRequest = entry;\n  state.bufferProcessing = false;\n}\n\nWritable.prototype._write = function (chunk, encoding, cb) {\n  cb(new Error('not implemented'));\n};\n\nWritable.prototype._writev = null;\n\nWritable.prototype.end = function (chunk, encoding, cb) {\n  var state = this._writableState;\n\n  if (typeof chunk === 'function') {\n    cb = chunk;\n    chunk = null;\n    encoding = null;\n  } else if (typeof encoding === 'function') {\n    cb = encoding;\n    encoding = null;\n  }\n\n  if (chunk !== null && chunk !== undefined) this.write(chunk, encoding);\n\n  // .end() fully uncorks\n  if (state.corked) {\n    state.corked = 1;\n    this.uncork();\n  }\n\n  // ignore unnecessary end() calls.\n  if (!state.ending && !state.finished) endWritable(this, state, cb);\n};\n\nfunction needFinish(state) {\n  return state.ending && state.length === 0 && state.bufferedRequest === null && !state.finished && !state.writing;\n}\n\nfunction prefinish(stream, state) {\n  if (!state.prefinished) {\n    state.prefinished = true;\n    stream.emit('prefinish');\n  }\n}\n\nfunction finishMaybe(stream, state) {\n  var need = needFinish(state);\n  if (need) {\n    if (state.pendingcb === 0) {\n      prefinish(stream, state);\n      state.finished = true;\n      stream.emit('finish');\n    } else {\n      prefinish(stream, state);\n    }\n  }\n  return need;\n}\n\nfunction endWritable(stream, state, cb) {\n  state.ending = true;\n  finishMaybe(stream, state);\n  if (cb) {\n    if (state.finished) processNextTick(cb);else stream.once('finish', cb);\n  }\n  state.ended = true;\n  stream.writable = false;\n}\n\n// It seems a linked list but it is not\n// there will be only 2 of these for each stream\nfunction CorkedRequest(state) {\n  var _this = this;\n\n  this.next = null;\n  this.entry = null;\n\n  this.finish = function (err) {\n    var entry = _this.entry;\n    _this.entry = null;\n    while (entry) {\n      var cb = entry.callback;\n      state.pendingcb--;\n      cb(err);\n      entry = entry.next;\n    }\n    if (state.corkedRequestsFree) {\n      state.corkedRequestsFree.next = _this;\n    } else {\n      state.corkedRequestsFree = _this;\n    }\n  };\n}\n}).call(this,require('_process'))\n},{\"./_stream_duplex\":69,\"_process\":67,\"buffer\":44,\"buffer-shims\":43,\"core-util-is\":45,\"events\":48,\"inherits\":51,\"process-nextick-args\":66,\"util-deprecate\":81}],74:[function(require,module,exports){\n'use strict';\n\nvar Buffer = require('buffer').Buffer;\n/*<replacement>*/\nvar bufferShim = require('buffer-shims');\n/*</replacement>*/\n\nmodule.exports = BufferList;\n\nfunction BufferList() {\n  this.head = null;\n  this.tail = null;\n  this.length = 0;\n}\n\nBufferList.prototype.push = function (v) {\n  var entry = { data: v, next: null };\n  if (this.length > 0) this.tail.next = entry;else this.head = entry;\n  this.tail = entry;\n  ++this.length;\n};\n\nBufferList.prototype.unshift = function (v) {\n  var entry = { data: v, next: this.head };\n  if (this.length === 0) this.tail = entry;\n  this.head = entry;\n  ++this.length;\n};\n\nBufferList.prototype.shift = function () {\n  if (this.length === 0) return;\n  var ret = this.head.data;\n  if (this.length === 1) this.head = this.tail = null;else this.head = this.head.next;\n  --this.length;\n  return ret;\n};\n\nBufferList.prototype.clear = function () {\n  this.head = this.tail = null;\n  this.length = 0;\n};\n\nBufferList.prototype.join = function (s) {\n  if (this.length === 0) return '';\n  var p = this.head;\n  var ret = '' + p.data;\n  while (p = p.next) {\n    ret += s + p.data;\n  }return ret;\n};\n\nBufferList.prototype.concat = function (n) {\n  if (this.length === 0) return bufferShim.alloc(0);\n  if (this.length === 1) return this.head.data;\n  var ret = bufferShim.allocUnsafe(n >>> 0);\n  var p = this.head;\n  var i = 0;\n  while (p) {\n    p.data.copy(ret, i);\n    i += p.data.length;\n    p = p.next;\n  }\n  return ret;\n};\n},{\"buffer\":44,\"buffer-shims\":43}],75:[function(require,module,exports){\nmodule.exports = require(\"./lib/_stream_passthrough.js\")\n\n},{\"./lib/_stream_passthrough.js\":70}],76:[function(require,module,exports){\n(function (process){\nvar Stream = (function (){\n  try {\n    return require('st' + 'ream'); // hack to fix a circular dependency issue when used with browserify\n  } catch(_){}\n}());\nexports = module.exports = require('./lib/_stream_readable.js');\nexports.Stream = Stream || exports;\nexports.Readable = exports;\nexports.Writable = require('./lib/_stream_writable.js');\nexports.Duplex = require('./lib/_stream_duplex.js');\nexports.Transform = require('./lib/_stream_transform.js');\nexports.PassThrough = require('./lib/_stream_passthrough.js');\n\nif (!process.browser && process.env.READABLE_STREAM === 'disable' && Stream) {\n  module.exports = Stream;\n}\n\n}).call(this,require('_process'))\n},{\"./lib/_stream_duplex.js\":69,\"./lib/_stream_passthrough.js\":70,\"./lib/_stream_readable.js\":71,\"./lib/_stream_transform.js\":72,\"./lib/_stream_writable.js\":73,\"_process\":67}],77:[function(require,module,exports){\nmodule.exports = require(\"./lib/_stream_transform.js\")\n\n},{\"./lib/_stream_transform.js\":72}],78:[function(require,module,exports){\nmodule.exports = require(\"./lib/_stream_writable.js\")\n\n},{\"./lib/_stream_writable.js\":73}],79:[function(require,module,exports){\n// Copyright Joyent, Inc. and other Node contributors.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a\n// copy of this software and associated documentation files (the\n// \"Software\"), to deal in the Software without restriction, including\n// without limitation the rights to use, copy, modify, merge, publish,\n// distribute, sublicense, and/or sell copies of the Software, and to permit\n// persons to whom the Software is furnished to do so, subject to the\n// following conditions:\n//\n// The above copyright notice and this permission notice shall be included\n// in all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS\n// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN\n// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,\n// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE\n// USE OR OTHER DEALINGS IN THE SOFTWARE.\n\nmodule.exports = Stream;\n\nvar EE = require('events').EventEmitter;\nvar inherits = require('inherits');\n\ninherits(Stream, EE);\nStream.Readable = require('readable-stream/readable.js');\nStream.Writable = require('readable-stream/writable.js');\nStream.Duplex = require('readable-stream/duplex.js');\nStream.Transform = require('readable-stream/transform.js');\nStream.PassThrough = require('readable-stream/passthrough.js');\n\n// Backwards-compat with node 0.4.x\nStream.Stream = Stream;\n\n\n\n// old-style streams.  Note that the pipe method (the only relevant\n// part of this class) is overridden in the Readable class.\n\nfunction Stream() {\n  EE.call(this);\n}\n\nStream.prototype.pipe = function(dest, options) {\n  var source = this;\n\n  function ondata(chunk) {\n    if (dest.writable) {\n      if (false === dest.write(chunk) && source.pause) {\n        source.pause();\n      }\n    }\n  }\n\n  source.on('data', ondata);\n\n  function ondrain() {\n    if (source.readable && source.resume) {\n      source.resume();\n    }\n  }\n\n  dest.on('drain', ondrain);\n\n  // If the 'end' option is not supplied, dest.end() will be called when\n  // source gets the 'end' or 'close' events.  Only dest.end() once.\n  if (!dest._isStdio && (!options || options.end !== false)) {\n    source.on('end', onend);\n    source.on('close', onclose);\n  }\n\n  var didOnEnd = false;\n  function onend() {\n    if (didOnEnd) return;\n    didOnEnd = true;\n\n    dest.end();\n  }\n\n\n  function onclose() {\n    if (didOnEnd) return;\n    didOnEnd = true;\n\n    if (typeof dest.destroy === 'function') dest.destroy();\n  }\n\n  // don't leave dangling pipes when there are errors.\n  function onerror(er) {\n    cleanup();\n    if (EE.listenerCount(this, 'error') === 0) {\n      throw er; // Unhandled stream error in pipe.\n    }\n  }\n\n  source.on('error', onerror);\n  dest.on('error', onerror);\n\n  // remove all the event listeners that were added.\n  function cleanup() {\n    source.removeListener('data', ondata);\n    dest.removeListener('drain', ondrain);\n\n    source.removeListener('end', onend);\n    source.removeListener('close', onclose);\n\n    source.removeListener('error', onerror);\n    dest.removeListener('error', onerror);\n\n    source.removeListener('end', cleanup);\n    source.removeListener('close', cleanup);\n\n    dest.removeListener('close', cleanup);\n  }\n\n  source.on('end', cleanup);\n  source.on('close', cleanup);\n\n  dest.on('close', cleanup);\n\n  dest.emit('pipe', source);\n\n  // Allow for unix-like usage: A.pipe(B).pipe(C)\n  return dest;\n};\n\n},{\"events\":48,\"inherits\":51,\"readable-stream/duplex.js\":68,\"readable-stream/passthrough.js\":75,\"readable-stream/readable.js\":76,\"readable-stream/transform.js\":77,\"readable-stream/writable.js\":78}],80:[function(require,module,exports){\n// Copyright Joyent, Inc. and other Node contributors.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a\n// copy of this software and associated documentation files (the\n// \"Software\"), to deal in the Software without restriction, including\n// without limitation the rights to use, copy, modify, merge, publish,\n// distribute, sublicense, and/or sell copies of the Software, and to permit\n// persons to whom the Software is furnished to do so, subject to the\n// following conditions:\n//\n// The above copyright notice and this permission notice shall be included\n// in all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS\n// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN\n// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,\n// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE\n// USE OR OTHER DEALINGS IN THE SOFTWARE.\n\nvar Buffer = require('buffer').Buffer;\n\nvar isBufferEncoding = Buffer.isEncoding\n  || function(encoding) {\n       switch (encoding && encoding.toLowerCase()) {\n         case 'hex': case 'utf8': case 'utf-8': case 'ascii': case 'binary': case 'base64': case 'ucs2': case 'ucs-2': case 'utf16le': case 'utf-16le': case 'raw': return true;\n         default: return false;\n       }\n     }\n\n\nfunction assertEncoding(encoding) {\n  if (encoding && !isBufferEncoding(encoding)) {\n    throw new Error('Unknown encoding: ' + encoding);\n  }\n}\n\n// StringDecoder provides an interface for efficiently splitting a series of\n// buffers into a series of JS strings without breaking apart multi-byte\n// characters. CESU-8 is handled as part of the UTF-8 encoding.\n//\n// @TODO Handling all encodings inside a single object makes it very difficult\n// to reason about this code, so it should be split up in the future.\n// @TODO There should be a utf8-strict encoding that rejects invalid UTF-8 code\n// points as used by CESU-8.\nvar StringDecoder = exports.StringDecoder = function(encoding) {\n  this.encoding = (encoding || 'utf8').toLowerCase().replace(/[-_]/, '');\n  assertEncoding(encoding);\n  switch (this.encoding) {\n    case 'utf8':\n      // CESU-8 represents each of Surrogate Pair by 3-bytes\n      this.surrogateSize = 3;\n      break;\n    case 'ucs2':\n    case 'utf16le':\n      // UTF-16 represents each of Surrogate Pair by 2-bytes\n      this.surrogateSize = 2;\n      this.detectIncompleteChar = utf16DetectIncompleteChar;\n      break;\n    case 'base64':\n      // Base-64 stores 3 bytes in 4 chars, and pads the remainder.\n      this.surrogateSize = 3;\n      this.detectIncompleteChar = base64DetectIncompleteChar;\n      break;\n    default:\n      this.write = passThroughWrite;\n      return;\n  }\n\n  // Enough space to store all bytes of a single character. UTF-8 needs 4\n  // bytes, but CESU-8 may require up to 6 (3 bytes per surrogate).\n  this.charBuffer = new Buffer(6);\n  // Number of bytes received for the current incomplete multi-byte character.\n  this.charReceived = 0;\n  // Number of bytes expected for the current incomplete multi-byte character.\n  this.charLength = 0;\n};\n\n\n// write decodes the given buffer and returns it as JS string that is\n// guaranteed to not contain any partial multi-byte characters. Any partial\n// character found at the end of the buffer is buffered up, and will be\n// returned when calling write again with the remaining bytes.\n//\n// Note: Converting a Buffer containing an orphan surrogate to a String\n// currently works, but converting a String to a Buffer (via `new Buffer`, or\n// Buffer#write) will replace incomplete surrogates with the unicode\n// replacement character. See https://codereview.chromium.org/121173009/ .\nStringDecoder.prototype.write = function(buffer) {\n  var charStr = '';\n  // if our last write ended with an incomplete multibyte character\n  while (this.charLength) {\n    // determine how many remaining bytes this buffer has to offer for this char\n    var available = (buffer.length >= this.charLength - this.charReceived) ?\n        this.charLength - this.charReceived :\n        buffer.length;\n\n    // add the new bytes to the char buffer\n    buffer.copy(this.charBuffer, this.charReceived, 0, available);\n    this.charReceived += available;\n\n    if (this.charReceived < this.charLength) {\n      // still not enough chars in this buffer? wait for more ...\n      return '';\n    }\n\n    // remove bytes belonging to the current character from the buffer\n    buffer = buffer.slice(available, buffer.length);\n\n    // get the character that was split\n    charStr = this.charBuffer.slice(0, this.charLength).toString(this.encoding);\n\n    // CESU-8: lead surrogate (D800-DBFF) is also the incomplete character\n    var charCode = charStr.charCodeAt(charStr.length - 1);\n    if (charCode >= 0xD800 && charCode <= 0xDBFF) {\n      this.charLength += this.surrogateSize;\n      charStr = '';\n      continue;\n    }\n    this.charReceived = this.charLength = 0;\n\n    // if there are no more bytes in this buffer, just emit our char\n    if (buffer.length === 0) {\n      return charStr;\n    }\n    break;\n  }\n\n  // determine and set charLength / charReceived\n  this.detectIncompleteChar(buffer);\n\n  var end = buffer.length;\n  if (this.charLength) {\n    // buffer the incomplete character bytes we got\n    buffer.copy(this.charBuffer, 0, buffer.length - this.charReceived, end);\n    end -= this.charReceived;\n  }\n\n  charStr += buffer.toString(this.encoding, 0, end);\n\n  var end = charStr.length - 1;\n  var charCode = charStr.charCodeAt(end);\n  // CESU-8: lead surrogate (D800-DBFF) is also the incomplete character\n  if (charCode >= 0xD800 && charCode <= 0xDBFF) {\n    var size = this.surrogateSize;\n    this.charLength += size;\n    this.charReceived += size;\n    this.charBuffer.copy(this.charBuffer, size, 0, size);\n    buffer.copy(this.charBuffer, 0, 0, size);\n    return charStr.substring(0, end);\n  }\n\n  // or just emit the charStr\n  return charStr;\n};\n\n// detectIncompleteChar determines if there is an incomplete UTF-8 character at\n// the end of the given buffer. If so, it sets this.charLength to the byte\n// length that character, and sets this.charReceived to the number of bytes\n// that are available for this character.\nStringDecoder.prototype.detectIncompleteChar = function(buffer) {\n  // determine how many bytes we have to check at the end of this buffer\n  var i = (buffer.length >= 3) ? 3 : buffer.length;\n\n  // Figure out if one of the last i bytes of our buffer announces an\n  // incomplete char.\n  for (; i > 0; i--) {\n    var c = buffer[buffer.length - i];\n\n    // See http://en.wikipedia.org/wiki/UTF-8#Description\n\n    // 110XXXXX\n    if (i == 1 && c >> 5 == 0x06) {\n      this.charLength = 2;\n      break;\n    }\n\n    // 1110XXXX\n    if (i <= 2 && c >> 4 == 0x0E) {\n      this.charLength = 3;\n      break;\n    }\n\n    // 11110XXX\n    if (i <= 3 && c >> 3 == 0x1E) {\n      this.charLength = 4;\n      break;\n    }\n  }\n  this.charReceived = i;\n};\n\nStringDecoder.prototype.end = function(buffer) {\n  var res = '';\n  if (buffer && buffer.length)\n    res = this.write(buffer);\n\n  if (this.charReceived) {\n    var cr = this.charReceived;\n    var buf = this.charBuffer;\n    var enc = this.encoding;\n    res += buf.slice(0, cr).toString(enc);\n  }\n\n  return res;\n};\n\nfunction passThroughWrite(buffer) {\n  return buffer.toString(this.encoding);\n}\n\nfunction utf16DetectIncompleteChar(buffer) {\n  this.charReceived = buffer.length % 2;\n  this.charLength = this.charReceived ? 2 : 0;\n}\n\nfunction base64DetectIncompleteChar(buffer) {\n  this.charReceived = buffer.length % 3;\n  this.charLength = this.charReceived ? 3 : 0;\n}\n\n},{\"buffer\":44}],81:[function(require,module,exports){\n(function (global){\n\n/**\n * Module exports.\n */\n\nmodule.exports = deprecate;\n\n/**\n * Mark that a method should not be used.\n * Returns a modified function which warns once by default.\n *\n * If `localStorage.noDeprecation = true` is set, then it is a no-op.\n *\n * If `localStorage.throwDeprecation = true` is set, then deprecated functions\n * will throw an Error when invoked.\n *\n * If `localStorage.traceDeprecation = true` is set, then deprecated functions\n * will invoke `console.trace()` instead of `console.error()`.\n *\n * @param {Function} fn - the function to deprecate\n * @param {String} msg - the string to print to the console when `fn` is invoked\n * @returns {Function} a new \"deprecated\" version of `fn`\n * @api public\n */\n\nfunction deprecate (fn, msg) {\n  if (config('noDeprecation')) {\n    return fn;\n  }\n\n  var warned = false;\n  function deprecated() {\n    if (!warned) {\n      if (config('throwDeprecation')) {\n        throw new Error(msg);\n      } else if (config('traceDeprecation')) {\n        console.trace(msg);\n      } else {\n        console.warn(msg);\n      }\n      warned = true;\n    }\n    return fn.apply(this, arguments);\n  }\n\n  return deprecated;\n}\n\n/**\n * Checks `localStorage` for boolean values for the given `name`.\n *\n * @param {String} name\n * @returns {Boolean}\n * @api private\n */\n\nfunction config (name) {\n  // accessing global.localStorage can trigger a DOMException in sandboxed iframes\n  try {\n    if (!global.localStorage) return false;\n  } catch (_) {\n    return false;\n  }\n  var val = global.localStorage[name];\n  if (null == val) return false;\n  return String(val).toLowerCase() === 'true';\n}\n\n}).call(this,typeof global !== \"undefined\" ? global : typeof self !== \"undefined\" ? self : typeof window !== \"undefined\" ? window : {})\n},{}],82:[function(require,module,exports){\narguments[4][51][0].apply(exports,arguments)\n},{\"dup\":51}],83:[function(require,module,exports){\nmodule.exports = function isBuffer(arg) {\n  return arg && typeof arg === 'object'\n    && typeof arg.copy === 'function'\n    && typeof arg.fill === 'function'\n    && typeof arg.readUInt8 === 'function';\n}\n},{}],84:[function(require,module,exports){\n(function (process,global){\n// Copyright Joyent, Inc. and other Node contributors.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a\n// copy of this software and associated documentation files (the\n// \"Software\"), to deal in the Software without restriction, including\n// without limitation the rights to use, copy, modify, merge, publish,\n// distribute, sublicense, and/or sell copies of the Software, and to permit\n// persons to whom the Software is furnished to do so, subject to the\n// following conditions:\n//\n// The above copyright notice and this permission notice shall be included\n// in all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS\n// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN\n// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,\n// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE\n// USE OR OTHER DEALINGS IN THE SOFTWARE.\n\nvar formatRegExp = /%[sdj%]/g;\nexports.format = function(f) {\n  if (!isString(f)) {\n    var objects = [];\n    for (var i = 0; i < arguments.length; i++) {\n      objects.push(inspect(arguments[i]));\n    }\n    return objects.join(' ');\n  }\n\n  var i = 1;\n  var args = arguments;\n  var len = args.length;\n  var str = String(f).replace(formatRegExp, function(x) {\n    if (x === '%%') return '%';\n    if (i >= len) return x;\n    switch (x) {\n      case '%s': return String(args[i++]);\n      case '%d': return Number(args[i++]);\n      case '%j':\n        try {\n          return JSON.stringify(args[i++]);\n        } catch (_) {\n          return '[Circular]';\n        }\n      default:\n        return x;\n    }\n  });\n  for (var x = args[i]; i < len; x = args[++i]) {\n    if (isNull(x) || !isObject(x)) {\n      str += ' ' + x;\n    } else {\n      str += ' ' + inspect(x);\n    }\n  }\n  return str;\n};\n\n\n// Mark that a method should not be used.\n// Returns a modified function which warns once by default.\n// If --no-deprecation is set, then it is a no-op.\nexports.deprecate = function(fn, msg) {\n  // Allow for deprecating things in the process of starting up.\n  if (isUndefined(global.process)) {\n    return function() {\n      return exports.deprecate(fn, msg).apply(this, arguments);\n    };\n  }\n\n  if (process.noDeprecation === true) {\n    return fn;\n  }\n\n  var warned = false;\n  function deprecated() {\n    if (!warned) {\n      if (process.throwDeprecation) {\n        throw new Error(msg);\n      } else if (process.traceDeprecation) {\n        console.trace(msg);\n      } else {\n        console.error(msg);\n      }\n      warned = true;\n    }\n    return fn.apply(this, arguments);\n  }\n\n  return deprecated;\n};\n\n\nvar debugs = {};\nvar debugEnviron;\nexports.debuglog = function(set) {\n  if (isUndefined(debugEnviron))\n    debugEnviron = process.env.NODE_DEBUG || '';\n  set = set.toUpperCase();\n  if (!debugs[set]) {\n    if (new RegExp('\\\\b' + set + '\\\\b', 'i').test(debugEnviron)) {\n      var pid = process.pid;\n      debugs[set] = function() {\n        var msg = exports.format.apply(exports, arguments);\n        console.error('%s %d: %s', set, pid, msg);\n      };\n    } else {\n      debugs[set] = function() {};\n    }\n  }\n  return debugs[set];\n};\n\n\n/**\n * Echos the value of a value. Trys to print the value out\n * in the best way possible given the different types.\n *\n * @param {Object} obj The object to print out.\n * @param {Object} opts Optional options object that alters the output.\n */\n/* legacy: obj, showHidden, depth, colors*/\nfunction inspect(obj, opts) {\n  // default options\n  var ctx = {\n    seen: [],\n    stylize: stylizeNoColor\n  };\n  // legacy...\n  if (arguments.length >= 3) ctx.depth = arguments[2];\n  if (arguments.length >= 4) ctx.colors = arguments[3];\n  if (isBoolean(opts)) {\n    // legacy...\n    ctx.showHidden = opts;\n  } else if (opts) {\n    // got an \"options\" object\n    exports._extend(ctx, opts);\n  }\n  // set default options\n  if (isUndefined(ctx.showHidden)) ctx.showHidden = false;\n  if (isUndefined(ctx.depth)) ctx.depth = 2;\n  if (isUndefined(ctx.colors)) ctx.colors = false;\n  if (isUndefined(ctx.customInspect)) ctx.customInspect = true;\n  if (ctx.colors) ctx.stylize = stylizeWithColor;\n  return formatValue(ctx, obj, ctx.depth);\n}\nexports.inspect = inspect;\n\n\n// http://en.wikipedia.org/wiki/ANSI_escape_code#graphics\ninspect.colors = {\n  'bold' : [1, 22],\n  'italic' : [3, 23],\n  'underline' : [4, 24],\n  'inverse' : [7, 27],\n  'white' : [37, 39],\n  'grey' : [90, 39],\n  'black' : [30, 39],\n  'blue' : [34, 39],\n  'cyan' : [36, 39],\n  'green' : [32, 39],\n  'magenta' : [35, 39],\n  'red' : [31, 39],\n  'yellow' : [33, 39]\n};\n\n// Don't use 'blue' not visible on cmd.exe\ninspect.styles = {\n  'special': 'cyan',\n  'number': 'yellow',\n  'boolean': 'yellow',\n  'undefined': 'grey',\n  'null': 'bold',\n  'string': 'green',\n  'date': 'magenta',\n  // \"name\": intentionally not styling\n  'regexp': 'red'\n};\n\n\nfunction stylizeWithColor(str, styleType) {\n  var style = inspect.styles[styleType];\n\n  if (style) {\n    return '\\u001b[' + inspect.colors[style][0] + 'm' + str +\n           '\\u001b[' + inspect.colors[style][1] + 'm';\n  } else {\n    return str;\n  }\n}\n\n\nfunction stylizeNoColor(str, styleType) {\n  return str;\n}\n\n\nfunction arrayToHash(array) {\n  var hash = {};\n\n  array.forEach(function(val, idx) {\n    hash[val] = true;\n  });\n\n  return hash;\n}\n\n\nfunction formatValue(ctx, value, recurseTimes) {\n  // Provide a hook for user-specified inspect functions.\n  // Check that value is an object with an inspect function on it\n  if (ctx.customInspect &&\n      value &&\n      isFunction(value.inspect) &&\n      // Filter out the util module, it's inspect function is special\n      value.inspect !== exports.inspect &&\n      // Also filter out any prototype objects using the circular check.\n      !(value.constructor && value.constructor.prototype === value)) {\n    var ret = value.inspect(recurseTimes, ctx);\n    if (!isString(ret)) {\n      ret = formatValue(ctx, ret, recurseTimes);\n    }\n    return ret;\n  }\n\n  // Primitive types cannot have properties\n  var primitive = formatPrimitive(ctx, value);\n  if (primitive) {\n    return primitive;\n  }\n\n  // Look up the keys of the object.\n  var keys = Object.keys(value);\n  var visibleKeys = arrayToHash(keys);\n\n  if (ctx.showHidden) {\n    keys = Object.getOwnPropertyNames(value);\n  }\n\n  // IE doesn't make error fields non-enumerable\n  // http://msdn.microsoft.com/en-us/library/ie/dww52sbt(v=vs.94).aspx\n  if (isError(value)\n      && (keys.indexOf('message') >= 0 || keys.indexOf('description') >= 0)) {\n    return formatError(value);\n  }\n\n  // Some type of object without properties can be shortcutted.\n  if (keys.length === 0) {\n    if (isFunction(value)) {\n      var name = value.name ? ': ' + value.name : '';\n      return ctx.stylize('[Function' + name + ']', 'special');\n    }\n    if (isRegExp(value)) {\n      return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp');\n    }\n    if (isDate(value)) {\n      return ctx.stylize(Date.prototype.toString.call(value), 'date');\n    }\n    if (isError(value)) {\n      return formatError(value);\n    }\n  }\n\n  var base = '', array = false, braces = ['{', '}'];\n\n  // Make Array say that they are Array\n  if (isArray(value)) {\n    array = true;\n    braces = ['[', ']'];\n  }\n\n  // Make functions say that they are functions\n  if (isFunction(value)) {\n    var n = value.name ? ': ' + value.name : '';\n    base = ' [Function' + n + ']';\n  }\n\n  // Make RegExps say that they are RegExps\n  if (isRegExp(value)) {\n    base = ' ' + RegExp.prototype.toString.call(value);\n  }\n\n  // Make dates with properties first say the date\n  if (isDate(value)) {\n    base = ' ' + Date.prototype.toUTCString.call(value);\n  }\n\n  // Make error with message first say the error\n  if (isError(value)) {\n    base = ' ' + formatError(value);\n  }\n\n  if (keys.length === 0 && (!array || value.length == 0)) {\n    return braces[0] + base + braces[1];\n  }\n\n  if (recurseTimes < 0) {\n    if (isRegExp(value)) {\n      return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp');\n    } else {\n      return ctx.stylize('[Object]', 'special');\n    }\n  }\n\n  ctx.seen.push(value);\n\n  var output;\n  if (array) {\n    output = formatArray(ctx, value, recurseTimes, visibleKeys, keys);\n  } else {\n    output = keys.map(function(key) {\n      return formatProperty(ctx, value, recurseTimes, visibleKeys, key, array);\n    });\n  }\n\n  ctx.seen.pop();\n\n  return reduceToSingleString(output, base, braces);\n}\n\n\nfunction formatPrimitive(ctx, value) {\n  if (isUndefined(value))\n    return ctx.stylize('undefined', 'undefined');\n  if (isString(value)) {\n    var simple = '\\'' + JSON.stringify(value).replace(/^\"|\"$/g, '')\n                                             .replace(/'/g, \"\\\\'\")\n                                             .replace(/\\\\\"/g, '\"') + '\\'';\n    return ctx.stylize(simple, 'string');\n  }\n  if (isNumber(value))\n    return ctx.stylize('' + value, 'number');\n  if (isBoolean(value))\n    return ctx.stylize('' + value, 'boolean');\n  // For some reason typeof null is \"object\", so special case here.\n  if (isNull(value))\n    return ctx.stylize('null', 'null');\n}\n\n\nfunction formatError(value) {\n  return '[' + Error.prototype.toString.call(value) + ']';\n}\n\n\nfunction formatArray(ctx, value, recurseTimes, visibleKeys, keys) {\n  var output = [];\n  for (var i = 0, l = value.length; i < l; ++i) {\n    if (hasOwnProperty(value, String(i))) {\n      output.push(formatProperty(ctx, value, recurseTimes, visibleKeys,\n          String(i), true));\n    } else {\n      output.push('');\n    }\n  }\n  keys.forEach(function(key) {\n    if (!key.match(/^\\d+$/)) {\n      output.push(formatProperty(ctx, value, recurseTimes, visibleKeys,\n          key, true));\n    }\n  });\n  return output;\n}\n\n\nfunction formatProperty(ctx, value, recurseTimes, visibleKeys, key, array) {\n  var name, str, desc;\n  desc = Object.getOwnPropertyDescriptor(value, key) || { value: value[key] };\n  if (desc.get) {\n    if (desc.set) {\n      str = ctx.stylize('[Getter/Setter]', 'special');\n    } else {\n      str = ctx.stylize('[Getter]', 'special');\n    }\n  } else {\n    if (desc.set) {\n      str = ctx.stylize('[Setter]', 'special');\n    }\n  }\n  if (!hasOwnProperty(visibleKeys, key)) {\n    name = '[' + key + ']';\n  }\n  if (!str) {\n    if (ctx.seen.indexOf(desc.value) < 0) {\n      if (isNull(recurseTimes)) {\n        str = formatValue(ctx, desc.value, null);\n      } else {\n        str = formatValue(ctx, desc.value, recurseTimes - 1);\n      }\n      if (str.indexOf('\\n') > -1) {\n        if (array) {\n          str = str.split('\\n').map(function(line) {\n            return '  ' + line;\n          }).join('\\n').substr(2);\n        } else {\n          str = '\\n' + str.split('\\n').map(function(line) {\n            return '   ' + line;\n          }).join('\\n');\n        }\n      }\n    } else {\n      str = ctx.stylize('[Circular]', 'special');\n    }\n  }\n  if (isUndefined(name)) {\n    if (array && key.match(/^\\d+$/)) {\n      return str;\n    }\n    name = JSON.stringify('' + key);\n    if (name.match(/^\"([a-zA-Z_][a-zA-Z_0-9]*)\"$/)) {\n      name = name.substr(1, name.length - 2);\n      name = ctx.stylize(name, 'name');\n    } else {\n      name = name.replace(/'/g, \"\\\\'\")\n                 .replace(/\\\\\"/g, '\"')\n                 .replace(/(^\"|\"$)/g, \"'\");\n      name = ctx.stylize(name, 'string');\n    }\n  }\n\n  return name + ': ' + str;\n}\n\n\nfunction reduceToSingleString(output, base, braces) {\n  var numLinesEst = 0;\n  var length = output.reduce(function(prev, cur) {\n    numLinesEst++;\n    if (cur.indexOf('\\n') >= 0) numLinesEst++;\n    return prev + cur.replace(/\\u001b\\[\\d\\d?m/g, '').length + 1;\n  }, 0);\n\n  if (length > 60) {\n    return braces[0] +\n           (base === '' ? '' : base + '\\n ') +\n           ' ' +\n           output.join(',\\n  ') +\n           ' ' +\n           braces[1];\n  }\n\n  return braces[0] + base + ' ' + output.join(', ') + ' ' + braces[1];\n}\n\n\n// NOTE: These type checking functions intentionally don't use `instanceof`\n// because it is fragile and can be easily faked with `Object.create()`.\nfunction isArray(ar) {\n  return Array.isArray(ar);\n}\nexports.isArray = isArray;\n\nfunction isBoolean(arg) {\n  return typeof arg === 'boolean';\n}\nexports.isBoolean = isBoolean;\n\nfunction isNull(arg) {\n  return arg === null;\n}\nexports.isNull = isNull;\n\nfunction isNullOrUndefined(arg) {\n  return arg == null;\n}\nexports.isNullOrUndefined = isNullOrUndefined;\n\nfunction isNumber(arg) {\n  return typeof arg === 'number';\n}\nexports.isNumber = isNumber;\n\nfunction isString(arg) {\n  return typeof arg === 'string';\n}\nexports.isString = isString;\n\nfunction isSymbol(arg) {\n  return typeof arg === 'symbol';\n}\nexports.isSymbol = isSymbol;\n\nfunction isUndefined(arg) {\n  return arg === void 0;\n}\nexports.isUndefined = isUndefined;\n\nfunction isRegExp(re) {\n  return isObject(re) && objectToString(re) === '[object RegExp]';\n}\nexports.isRegExp = isRegExp;\n\nfunction isObject(arg) {\n  return typeof arg === 'object' && arg !== null;\n}\nexports.isObject = isObject;\n\nfunction isDate(d) {\n  return isObject(d) && objectToString(d) === '[object Date]';\n}\nexports.isDate = isDate;\n\nfunction isError(e) {\n  return isObject(e) &&\n      (objectToString(e) === '[object Error]' || e instanceof Error);\n}\nexports.isError = isError;\n\nfunction isFunction(arg) {\n  return typeof arg === 'function';\n}\nexports.isFunction = isFunction;\n\nfunction isPrimitive(arg) {\n  return arg === null ||\n         typeof arg === 'boolean' ||\n         typeof arg === 'number' ||\n         typeof arg === 'string' ||\n         typeof arg === 'symbol' ||  // ES6 symbol\n         typeof arg === 'undefined';\n}\nexports.isPrimitive = isPrimitive;\n\nexports.isBuffer = require('./support/isBuffer');\n\nfunction objectToString(o) {\n  return Object.prototype.toString.call(o);\n}\n\n\nfunction pad(n) {\n  return n < 10 ? '0' + n.toString(10) : n.toString(10);\n}\n\n\nvar months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep',\n              'Oct', 'Nov', 'Dec'];\n\n// 26 Feb 16:19:34\nfunction timestamp() {\n  var d = new Date();\n  var time = [pad(d.getHours()),\n              pad(d.getMinutes()),\n              pad(d.getSeconds())].join(':');\n  return [d.getDate(), months[d.getMonth()], time].join(' ');\n}\n\n\n// log is just a thin wrapper to console.log that prepends a timestamp\nexports.log = function() {\n  console.log('%s - %s', timestamp(), exports.format.apply(exports, arguments));\n};\n\n\n/**\n * Inherit the prototype methods from one constructor into another.\n *\n * The Function.prototype.inherits from lang.js rewritten as a standalone\n * function (not on Function.prototype). NOTE: If this file is to be loaded\n * during bootstrapping this function needs to be rewritten using some native\n * functions as prototype setup using normal JavaScript does not work as\n * expected during bootstrapping (see mirror.js in r114903).\n *\n * @param {function} ctor Constructor function which needs to inherit the\n *     prototype.\n * @param {function} superCtor Constructor function to inherit prototype from.\n */\nexports.inherits = require('inherits');\n\nexports._extend = function(origin, add) {\n  // Don't do anything if add isn't an object\n  if (!add || !isObject(add)) return origin;\n\n  var keys = Object.keys(add);\n  var i = keys.length;\n  while (i--) {\n    origin[keys[i]] = add[keys[i]];\n  }\n  return origin;\n};\n\nfunction hasOwnProperty(obj, prop) {\n  return Object.prototype.hasOwnProperty.call(obj, prop);\n}\n\n}).call(this,require('_process'),typeof global !== \"undefined\" ? global : typeof self !== \"undefined\" ? self : typeof window !== \"undefined\" ? window : {})\n},{\"./support/isBuffer\":83,\"_process\":67,\"inherits\":82}]},{},[1]);\n"
  },
  {
    "path": "app_backend/static/plugin/JavaScript-Templates/.gitignore",
    "content": ".DS_Store\nnode_modules\n"
  },
  {
    "path": "app_backend/static/plugin/JavaScript-Templates/.travis.yml",
    "content": "language: node_js\nnode_js:\n  - \"stable\"\n"
  },
  {
    "path": "app_backend/static/plugin/JavaScript-Templates/README.md",
    "content": "# JavaScript Templates\n\n## Demo\n[JavaScript Templates Demo](https://blueimp.github.io/JavaScript-Templates/)\n\n## Description\n1KB lightweight, fast & powerful JavaScript templating engine with zero\ndependencies. Compatible with server-side environments like Node.js, module\nloaders like RequireJS, Browserify or webpack and all web browsers.\n\n## Usage\n\n### Client-side\nInclude the (minified) JavaScript Templates script in your HTML markup:\n\n```html\n<script src=\"js/tmpl.min.js\"></script>\n```\n\nAdd a script section with type **\"text/x-tmpl\"**, a unique **id** property and\nyour template definition as content:\n\n```html\n<script type=\"text/x-tmpl\" id=\"tmpl-demo\">\n<h3>{%=o.title%}</h3>\n<p>Released under the\n<a href=\"{%=o.license.url%}\">{%=o.license.name%}</a>.</p>\n<h4>Features</h4>\n<ul>\n{% for (var i=0; i<o.features.length; i++) { %}\n    <li>{%=o.features[i]%}</li>\n{% } %}\n</ul>\n</script>\n```\n\n**\"o\"** (the lowercase letter) is a reference to the data parameter of the\ntemplate function (see the API section on how to modify this identifier).\n\nIn your application code, create a JavaScript object to use as data for the\ntemplate:\n\n```js\nvar data = {\n    \"title\": \"JavaScript Templates\",\n    \"license\": {\n        \"name\": \"MIT license\",\n        \"url\": \"http://www.opensource.org/licenses/MIT\"\n    },\n    \"features\": [\n        \"lightweight & fast\",\n        \"powerful\",\n        \"zero dependencies\"\n    ]\n};\n```\n\nIn a real application, this data could be the result of retrieving a\n[JSON](http://json.org/) resource.\n\nRender the result by calling the **tmpl()** method with the id of the template\nand the data object as arguments:\n\n```js\ndocument.getElementById(\"result\").innerHTML = tmpl(\"tmpl-demo\", data);\n```\n\n### Server-side\n\nThe following is an example how to use the JavaScript Templates engine on the\nserver-side with [node.js](http://nodejs.org/).\n\nCreate a new directory and add the **tmpl.js** file. Or alternatively, install\nthe **blueimp-tmpl** package with [npm](https://www.npmjs.org/):\n\n```sh\nnpm install blueimp-tmpl\n```\n\nAdd a file **template.html** with the following content:\n\n```html\n<!DOCTYPE HTML>\n<title>{%=o.title%}</title>\n<h3><a href=\"{%=o.url%}\">{%=o.title%}</a></h3>\n<h4>Features</h4>\n<ul>\n{% for (var i=0; i<o.features.length; i++) { %}\n    <li>{%=o.features[i]%}</li>\n{% } %}\n</ul>\n```\n\nAdd a file **server.js** with the following content:\n\n```js\nrequire(\"http\").createServer(function (req, res) {\n    var fs = require(\"fs\"),\n        // The tmpl module exports the tmpl() function:\n        tmpl = require(\"./tmpl\"),\n        // Use the following version if you installed the package with npm:\n        // tmpl = require(\"blueimp-tmpl\"),\n        // Sample data:\n        data = {\n            \"title\": \"JavaScript Templates\",\n            \"url\": \"https://github.com/blueimp/JavaScript-Templates\",\n            \"features\": [\n                \"lightweight & fast\",\n                \"powerful\",\n                \"zero dependencies\"\n            ]\n        };\n    // Override the template loading method:\n    tmpl.load = function (id) {\n        var filename = id + \".html\";\n        console.log(\"Loading \" + filename);\n        return fs.readFileSync(filename, \"utf8\");\n    };\n    res.writeHead(200, {\"Content-Type\": \"text/x-tmpl\"});\n    // Render the content:\n    res.end(tmpl(\"template\", data));\n}).listen(8080, \"localhost\");\nconsole.log(\"Server running at http://localhost:8080/\");\n```\n\nRun the application with the following command:\n\n```sh\nnode server.js\n```\n\n## Requirements\nThe JavaScript Templates script has zero dependencies.\n\n## API\n\n### tmpl() function\nThe **tmpl()** function is added to the global **window** object and can be\ncalled as global function:\n\n```js\nvar result = tmpl(\"tmpl-demo\", data);\n```\n\nThe **tmpl()** function can be called with the id of a template, or with a\ntemplate string:\n\n```js\nvar result = tmpl(\"<h3>{%=o.title%}</h3>\", data);\n```\n\nIf called without second argument, **tmpl()** returns a reusable template\nfunction:\n\n```js\nvar func = tmpl(\"<h3>{%=o.title%}</h3>\");\ndocument.getElementById(\"result\").innerHTML = func(data);\n```\n\n### Templates cache\nTemplates loaded by id are cached in the map **tmpl.cache**:\n\n```js\nvar func = tmpl(\"tmpl-demo\"), // Loads and parses the template\n    cached = typeof tmpl.cache[\"tmpl-demo\"] === \"function\", // true\n    result = tmpl(\"tmpl-demo\", data); // Uses cached template function\n\ntmpl.cache[\"tmpl-demo\"] = null;\nresult = tmpl(\"tmpl-demo\", data); // Loads and parses the template again\n```\n\n### Output encoding\nThe method **tmpl.encode** is used to escape HTML special characters in the\ntemplate output:\n\n```js\nvar output = tmpl.encode(\"<>&\\\"'\\x00\"); // Renders \"&lt;&gt;&amp;&quot;&#39;\"\n```\n\n**tmpl.encode** makes use of the regular expression **tmpl.encReg** and the\nencoding map **tmpl.encMap** to match and replace special characters, which can\nbe modified to change the behavior of the output encoding.  \nStrings matched by the regular expression, but not found in the encoding map are\nremoved from the output. This allows for example to automatically trim input\nvalues (removing whitespace from the start and end of the string):\n\n```js\ntmpl.encReg = /(^\\s+)|(\\s+$)|[<>&\"'\\x00]/g;\nvar output = tmpl.encode(\"    Banana!    \"); // Renders \"Banana\" (without whitespace)\n```\n\n### Local helper variables\nThe local variables available inside the templates are the following:\n\n* **o**: The data object given as parameter to the template function\n(see the next section on how to modify the parameter name).\n* **tmpl**: A reference to the **tmpl** function object.\n* **_s**: The string for the rendered result content.\n* **_e**: A reference to the **tmpl.encode** method.\n* **print**: Helper function to add content to the rendered result string.\n* **include**: Helper function to include the return value of a different\ntemplate in the result.\n\nTo introduce additional local helper variables, the string **tmpl.helper** can\nbe extended. The following adds a convenience function for *console.log* and a\nstreaming function, that streams the template rendering result back to the\ncallback argument\n(note the comma at the beginning of each variable declaration):\n\n```js\ntmpl.helper += \",log=function(){console.log.apply(console, arguments)}\" +\n    \",st='',stream=function(cb){var l=st.length;st=_s;cb( _s.slice(l));}\";\n```\n\nThose new helper functions could be used to stream the template contents to the\nconsole output:\n\n```html\n<script type=\"text/x-tmpl\" id=\"tmpl-demo\">\n<h3>{%=o.title%}</h3>\n{% stream(log); %}\n<p>Released under the\n<a href=\"{%=o.license.url%}\">{%=o.license.name%}</a>.</p>\n{% stream(log); %}\n<h4>Features</h4>\n<ul>\n{% stream(log); %}\n{% for (var i=0; i<o.features.length; i++) { %}\n    <li>{%=o.features[i]%}</li>\n    {% stream(log); %}\n{% } %}\n</ul>\n{% stream(log); %}\n</script>\n```\n\n### Template function argument\nThe generated template functions accept one argument, which is the data object\ngiven to the **tmpl(id, data)** function. This argument is available inside the\ntemplate definitions as parameter **o** (the lowercase letter).\n\nThe argument name can be modified by overriding **tmpl.arg**:\n\n```js\ntmpl.arg = \"p\";\n\n// Renders \"<h3>JavaScript Templates</h3>\":\nvar result = tmpl(\"<h3>{%=p.title%}</h3>\", {title: \"JavaScript Templates\"});\n```\n\n### Template parsing\nThe template contents are matched and replaced using the regular expression\n**tmpl.regexp** and the replacement function **tmpl.func**.\nThe replacement function operates based on the\n[parenthesized submatch strings](https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/String/replace#Specifying_a_function_as_a_parameter).\n\nTo use different tags for the template syntax, override **tmpl.regexp** with a\nmodified regular expression, by exchanging all occurrences of \"{%\" and \"%}\",\ne.g. with \"[%\" and \"%]\":\n\n```js\ntmpl.regexp = /([\\s'\\\\])(?!(?:[^[]|\\[(?!%))*%\\])|(?:\\[%(=|#)([\\s\\S]+?)%\\])|(\\[%)|(%\\])/g;\n```\n\nBy default, the plugin preserves whitespace\n(newlines, carriage returns, tabs and spaces).\nTo strip unnecessary whitespace, you can override the **tmpl.func** function,\ne.g. with the following code:\n\n```js\nvar originalFunc = tmpl.func;\ntmpl.func = function (s, p1, p2, p3, p4, p5, offset, str) {\n    if (p1 && /\\s/.test(p1)) {\n        if (!offset || /\\s/.test(str.charAt(offset - 1)) ||\n                /^\\s+$/g.test(str.slice(offset))) {\n            return '';\n        }\n        return ' ';\n    }\n    return originalFunc.apply(tmpl, arguments);\n};\n```\n\n## Templates syntax\n\n### Interpolation\nPrint variable with HTML special characters escaped:\n\n```html\n<h3>{%=o.title%}</h3>\n```\n\nPrint variable without escaping:\n\n```html\n<h3>{%#o.user_id%}</h3>\n```\n\nPrint output of function calls:\n\n```html\n<a href=\"{%=encodeURI(o.url)%}\">Website</a>\n```\n\nUse dot notation to print nested properties:\n\n```html\n<strong>{%=o.author.name%}</strong>\n```\n\n### Evaluation\nUse **print(str)** to add escaped content to the output:\n\n```html\n<span>Year: {% var d=new Date(); print(d.getFullYear()); %}</span>\n```\n\nUse **print(str, true)** to add unescaped content to the output:\n\n```html\n<span>{% print(\"Fast &amp; powerful\", true); %}</span>\n```\n\nUse **include(str, obj)** to include content from a different template:\n\n```html\n<div>\n{% include('tmpl-link', {name: \"Website\", url: \"https://example.org\"}); %}\n</div>\n```\n\n**If else condition**:\n\n```html\n{% if (o.author.url) { %}\n    <a href=\"{%=encodeURI(o.author.url)%}\">{%=o.author.name%}</a>\n{% } else { %}\n    <em>No author url.</em>\n{% } %}\n```\n\n**For loop**:\n\n```html\n<ul>\n{% for (var i=0; i<o.features.length; i++) { %}\n    <li>{%=o.features[i]%}</li>\n{% } %}\n</ul>\n```\n\n## Compiled templates\nThe JavaScript Templates project comes with a compilation script, that allows\nyou to compile your templates into JavaScript code and combine them with a\nminimal Templates runtime into one combined JavaScript file.\n\nThe compilation script is built for [node.js](http://nodejs.org/).  \nTo use it, first install the JavaScript Templates project via\n[npm](https://www.npmjs.org/):\n\n```sh\nnpm install blueimp-tmpl\n```\n\nThis will put the executable **tmpl.js** into the folder **node_modules/.bin**.\nIt will also make it available on your PATH if you install the package globally\n(by adding the **-g** flag to the install command).\n\nThe **tmpl.js** executable accepts the paths to one or multiple template files\nas command line arguments and prints the generated JavaScript code to the\nconsole output. The following command line shows you how to store the generated\ncode in a new JavaScript file that can be included in your project:\n\n```sh\ntmpl.js index.html > tmpl.js\n```\n\nThe files given as command line arguments to **tmpl.js** can either be pure\ntemplate files or HTML documents with embedded template script sections.\nFor the pure template files, the file names (without extension) serve as\ntemplate ids.  \nThe generated file can be included in your project as a replacement for the\noriginal **tmpl.js** runtime. It provides you with the same API and provides a\n**tmpl(id, data)** function that accepts the id of one of your templates as\nfirst and a data object as optional second parameter.\n\n## Tests\nThe JavaScript Templates project comes with\n[Unit Tests](https://en.wikipedia.org/wiki/Unit_testing).  \nThere are two different ways to run the tests:\n\n* Open test/index.html in your browser or\n* run `npm test` in the Terminal in the root path of the repository package.\n\nThe first one tests the browser integration,\nthe second one the [node.js](http://nodejs.org/) integration.\n\n## License\nThe JavaScript Templates script is released under the\n[MIT license](http://www.opensource.org/licenses/MIT).\n"
  },
  {
    "path": "app_backend/static/plugin/JavaScript-Templates/css/demo.css",
    "content": "/*\n * JavaScript Templates Demo CSS\n * https://github.com/blueimp/JavaScript-Templates\n *\n * Copyright 2013, Sebastian Tschan\n * https://blueimp.net\n *\n * Licensed under the MIT license:\n * http://www.opensource.org/licenses/MIT\n */\n\nbody {\n  max-width: 750px;\n  margin: 0 auto;\n  padding: 1em;\n  font-family: 'Lucida Grande', 'Lucida Sans Unicode', Arial, sans-serif;\n  font-size: 1em;\n  line-height: 1.4em;\n  background: #222;\n  color: #fff;\n  -webkit-text-size-adjust: 100%;\n      -ms-text-size-adjust: 100%;\n}\na {\n  color: orange;\n  text-decoration: none;\n}\nimg {\n  border: 0;\n  vertical-align: middle;\n}\nh1 {\n  line-height: 1em;\n}\ntextarea,\ninput {\n  display: inline-block;\n  width: 100%;\n  -webkit-box-sizing: border-box;\n     -moz-box-sizing: border-box;\n          box-sizing: border-box;\n  padding: 10px;\n  margin: 0 0 10px;\n  font-family: \"Lucida Console\", Monaco, monospace;\n}\n.result {\n  padding: 20px 40px;\n  background: #fff;\n  color: #222;\n}\n.error {\n  color: red;\n}\n\n@media (min-width: 481px) {\n  .navigation {\n    list-style: none;\n    padding: 0;\n  }\n  .navigation li {\n    display: inline-block;\n  }\n  .navigation li:not(:first-child):before {\n    content: '| ';\n  }\n}\n\n/* IE7 fixes */\n*+html textarea,\n*+html input {\n  width: 460px;\n}\n*+html .result {\n  width: 400px;\n}\n"
  },
  {
    "path": "app_backend/static/plugin/JavaScript-Templates/index.html",
    "content": "<!DOCTYPE HTML>\n<!--\n/*\n * JavaScript Templates Demo\n * https://github.com/blueimp/JavaScript-Templates\n *\n * Copyright 2011, Sebastian Tschan\n * https://blueimp.net\n *\n * Licensed under the MIT license:\n * http://www.opensource.org/licenses/MIT\n */\n-->\n<html lang=\"en\">\n<head>\n<!--[if IE]>\n<meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge,chrome=1\">\n<![endif]-->\n<meta charset=\"utf-8\">\n<title>JavaScript Templates Demo</title>\n<meta name=\"description\" content=\"1KB lightweight, fast &amp; powerful JavaScript templating engine with zero dependencies. Compatible with server-side environments like Node.js, module loaders like RequireJS, Browserify or webpack and all web browsers.\">\n<meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n<link rel=\"stylesheet\" href=\"css/demo.css\">\n</head>\n<body>\n<h1>JavaScript Templates Demo</h1>\n<p><strong>1KB</strong> lightweight, fast &amp; powerful <a href=\"https://developer.mozilla.org/en/JavaScript/\">JavaScript</a> templating engine with zero dependencies.<br>\nCompatible with server-side environments like <a href=\"http://nodejs.org/\">Node.js</a>, module loaders like <a href=\"http://requirejs.org/\">RequireJS</a>, <a href=\"http://browserify.org/\">Browserify</a> or <a href=\"https://webpack.github.io/\">webpack</a> and all web browsers.</p>\n<ul class=\"navigation\">\n    <li><a href=\"https://github.com/blueimp/JavaScript-Templates/tags\">Download</a></li>\n    <li><a href=\"https://github.com/blueimp/JavaScript-Templates\">Source Code</a></li>\n    <li><a href=\"https://github.com/blueimp/JavaScript-Templates/blob/master/README.md\">Documentation</a></li>\n    <li><a href=\"test/\">Test</a></li>\n    <li><a href=\"https://blueimp.net\">&copy; Sebastian Tschan</a></li>\n</ul>\n<form>\n    <h2>Template</h2>\n    <textarea rows=\"12\" id=\"template\"></textarea>\n    <br>\n    <h2>Data (JSON)</h2>\n    <textarea rows=\"14\" id=\"data\"></textarea>\n    <br>\n    <button type=\"submit\" id=\"render\">Render</button>\n    <button type=\"reset\" id=\"reset\">Reset</button>\n    <h2>Result</h2>\n    <div id=\"result\" class=\"result\"></div>\n    <br>\n</form>\n<script type=\"text/x-tmpl\" id=\"tmpl-demo\">\n<h3>{%=o.title%}</h3>\n<p>Released under the\n<a href=\"{%=o.license.url%}\">{%=o.license.name%}</a>.</p>\n<h4>Features</h4>\n<ul>\n{% for (var i=0; i<o.features.length; i++) { %}\n    <li>{%=o.features[i]%}</li>\n{% } %}\n</ul>\n</script>\n<script type=\"text/x-tmpl\" id=\"tmpl-data\">\n{\n    \"title\": \"JavaScript Templates\",\n    \"license\": {\n        \"name\": \"MIT license\",\n        \"url\": \"http://www.opensource.org/licenses/MIT\"\n    },\n    \"features\": [\n        \"lightweight & fast\",\n        \"powerful\",\n        \"zero dependencies\"\n    ]\n}\n</script>\n<script type=\"text/x-tmpl\" id=\"tmpl-error\">\n<h3 class=\"error\">{%=o.title%}</h3>\n<code>{%=o.error%}</code>\n</script>\n<script src=\"js/tmpl.js\"></script>\n<script src=\"js/demo.js\"></script>\n</body>\n</html>\n"
  },
  {
    "path": "app_backend/static/plugin/JavaScript-Templates/js/compile.js",
    "content": "#!/usr/bin/env node\n/*\n * JavaScript Templates Compiler\n * https://github.com/blueimp/JavaScript-Templates\n *\n * Copyright 2011, Sebastian Tschan\n * https://blueimp.net\n *\n * Licensed under the MIT license:\n * http://www.opensource.org/licenses/MIT\n */\n\n/*global require, __dirname, process, console */\n\n;(function () {\n  'use strict'\n  var path = require('path')\n  var tmpl = require(path.join(__dirname, 'tmpl.js'))\n  var fs = require('fs')\n  // Retrieve the content of the minimal runtime:\n  var runtime = fs.readFileSync(path.join(__dirname, 'runtime.js'), 'utf8')\n  // A regular expression to parse templates from script tags in a HTML page:\n  var regexp = /<script( id=\"([\\w\\-]+)\")? type=\"text\\/x-tmpl\"( id=\"([\\w\\-]+)\")?>([\\s\\S]+?)<\\/script>/gi\n  // A regular expression to match the helper function names:\n  var helperRegexp = new RegExp(\n    tmpl.helper.match(/\\w+(?=\\s*=\\s*function\\s*\\()/g).join('\\\\s*\\\\(|') + '\\\\s*\\\\('\n  )\n  // A list to store the function bodies:\n  var list = []\n  var code\n  // Extend the Templating engine with a print method for the generated functions:\n  tmpl.print = function (str) {\n    // Only add helper functions if they are used inside of the template:\n    var helper = helperRegexp.test(str) ? tmpl.helper : ''\n    var body = str.replace(tmpl.regexp, tmpl.func)\n    if (helper || (/_e\\s*\\(/.test(body))) {\n      helper = '_e=tmpl.encode' + helper + ','\n    }\n    return 'function(' + tmpl.arg + ',tmpl){' +\n    ('var ' + helper + \"_s='\" + body + \"';return _s;\")\n      .split(\"_s+='';\").join('') + '}'\n  }\n  // Loop through the command line arguments:\n  process.argv.forEach(function (file, index) {\n    var listLength = list.length\n    var stats\n    var content\n    var result\n    var id\n    // Skip the first two arguments, which are \"node\" and the script:\n    if (index > 1) {\n      stats = fs.statSync(file)\n      if (!stats.isFile()) {\n        console.error(file + ' is not a file.')\n        return\n      }\n      content = fs.readFileSync(file, 'utf8')\n      while (true) {\n        // Find templates in script tags:\n        result = regexp.exec(content)\n        if (!result) {\n          break\n        }\n        id = result[2] || result[4]\n        list.push(\"'\" + id + \"':\" + tmpl.print(result[5]))\n      }\n      if (listLength === list.length) {\n        // No template script tags found, use the complete content:\n        id = path.basename(file, path.extname(file))\n        list.push(\"'\" + id + \"':\" + tmpl.print(content))\n      }\n    }\n  })\n  if (!list.length) {\n    console.error('Missing input file.')\n    return\n  }\n  // Combine the generated functions as cache of the minimal runtime:\n  code = runtime.replace('{}', '{' + list.join(',') + '}')\n  // Print the resulting code to the console output:\n  console.log(code)\n}())\n"
  },
  {
    "path": "app_backend/static/plugin/JavaScript-Templates/js/demo.js",
    "content": "/*\n * JavaScript Templates Demo\n * https://github.com/blueimp/JavaScript-Templates\n *\n * Copyright 2013, Sebastian Tschan\n * https://blueimp.net\n *\n * Licensed under the MIT license:\n * http://www.opensource.org/licenses/MIT\n */\n\n/* global document, tmpl */\n\n;(function () {\n  'use strict'\n\n  var templateInput = document.getElementById('template')\n  var dataInput = document.getElementById('data')\n  var resultNode = document.getElementById('result')\n  var templateDemoNode = document.getElementById('tmpl-demo')\n  var templateDataNode = document.getElementById('tmpl-data')\n\n  function renderError (title, error) {\n    resultNode.innerHTML = tmpl(\n      'tmpl-error',\n      {title: title, error: error}\n    )\n  }\n\n  function render (event) {\n    event.preventDefault()\n    var data\n    try {\n      data = JSON.parse(dataInput.value)\n    } catch (e) {\n      renderError('JSON parsing failed', e)\n      return\n    }\n    try {\n      resultNode.innerHTML = tmpl(\n        templateInput.value,\n        data\n      )\n    } catch (e) {\n      renderError('Template rendering failed', e)\n    }\n  }\n\n  function empty (node) {\n    while (node.lastChild) {\n      node.removeChild(node.lastChild)\n    }\n  }\n\n  function init (event) {\n    if (event) {\n      event.preventDefault()\n    }\n    templateInput.value = templateDemoNode.innerHTML.trim()\n    dataInput.value = templateDataNode.innerHTML.trim()\n    empty(resultNode)\n  }\n\n  document.getElementById('render').addEventListener('click', render)\n  document.getElementById('reset').addEventListener('click', init)\n\n  init()\n}())\n"
  },
  {
    "path": "app_backend/static/plugin/JavaScript-Templates/js/runtime.js",
    "content": "/*\n * JavaScript Templates Runtime\n * https://github.com/blueimp/JavaScript-Templates\n *\n * Copyright 2011, Sebastian Tschan\n * https://blueimp.net\n *\n * Licensed under the MIT license:\n * http://www.opensource.org/licenses/MIT\n */\n\n/*global define, module */\n\n;(function ($) {\n  'use strict'\n  var tmpl = function (id, data) {\n    var f = tmpl.cache[id]\n    return data ? f(data, tmpl) : function (data) {\n      return f(data, tmpl)\n    }\n  }\n  tmpl.cache = {}\n  tmpl.encReg = /[<>&\"'\\x00]/g\n  tmpl.encMap = {\n    '<': '&lt;',\n    '>': '&gt;',\n    '&': '&amp;',\n    '\"': '&quot;',\n    \"'\": '&#39;'\n  }\n  tmpl.encode = function (s) {\n    return (s == null ? '' : '' + s).replace(\n      tmpl.encReg,\n      function (c) {\n        return tmpl.encMap[c] || ''\n      }\n    )\n  }\n  if (typeof define === 'function' && define.amd) {\n    define(function () {\n      return tmpl\n    })\n  } else if (typeof module === 'object' && module.exports) {\n    module.exports = tmpl\n  } else {\n    $.tmpl = tmpl\n  }\n}(this))\n"
  },
  {
    "path": "app_backend/static/plugin/JavaScript-Templates/js/tmpl.js",
    "content": "/*\n * JavaScript Templates\n * https://github.com/blueimp/JavaScript-Templates\n *\n * Copyright 2011, Sebastian Tschan\n * https://blueimp.net\n *\n * Licensed under the MIT license:\n * http://www.opensource.org/licenses/MIT\n *\n * Inspired by John Resig's JavaScript Micro-Templating:\n * http://ejohn.org/blog/javascript-micro-templating/\n */\n\n/*global document, define, module */\n\n;(function ($) {\n  'use strict'\n  var tmpl = function (str, data) {\n    var f = !/[^\\w\\-\\.:]/.test(str)\n      ? tmpl.cache[str] = tmpl.cache[str] || tmpl(tmpl.load(str))\n      : new Function(// eslint-disable-line no-new-func\n        tmpl.arg + ',tmpl',\n        'var _e=tmpl.encode' + tmpl.helper + \",_s='\" +\n          str.replace(tmpl.regexp, tmpl.func) + \"';return _s;\"\n      )\n    return data ? f(data, tmpl) : function (data) {\n      return f(data, tmpl)\n    }\n  }\n  tmpl.cache = {}\n  tmpl.load = function (id) {\n    return document.getElementById(id).innerHTML\n  }\n  tmpl.regexp = /([\\s'\\\\])(?!(?:[^{]|\\{(?!%))*%\\})|(?:\\{%(=|#)([\\s\\S]+?)%\\})|(\\{%)|(%\\})/g\n  tmpl.func = function (s, p1, p2, p3, p4, p5) {\n    if (p1) { // whitespace, quote and backspace in HTML context\n      return {\n        '\\n': '\\\\n',\n        '\\r': '\\\\r',\n        '\\t': '\\\\t',\n        ' ': ' '\n      }[p1] || '\\\\' + p1\n    }\n    if (p2) { // interpolation: {%=prop%}, or unescaped: {%#prop%}\n      if (p2 === '=') {\n        return \"'+_e(\" + p3 + \")+'\"\n      }\n      return \"'+(\" + p3 + \"==null?'':\" + p3 + \")+'\"\n    }\n    if (p4) { // evaluation start tag: {%\n      return \"';\"\n    }\n    if (p5) { // evaluation end tag: %}\n      return \"_s+='\"\n    }\n  }\n  tmpl.encReg = /[<>&\"'\\x00]/g\n  tmpl.encMap = {\n    '<': '&lt;',\n    '>': '&gt;',\n    '&': '&amp;',\n    '\"': '&quot;',\n    \"'\": '&#39;'\n  }\n  tmpl.encode = function (s) {\n    return (s == null ? '' : '' + s).replace(\n      tmpl.encReg,\n      function (c) {\n        return tmpl.encMap[c] || ''\n      }\n    )\n  }\n  tmpl.arg = 'o'\n  tmpl.helper = \",print=function(s,e){_s+=e?(s==null?'':s):_e(s);}\" +\n                  ',include=function(s,d){_s+=tmpl(s,d);}'\n  if (typeof define === 'function' && define.amd) {\n    define(function () {\n      return tmpl\n    })\n  } else if (typeof module === 'object' && module.exports) {\n    module.exports = tmpl\n  } else {\n    $.tmpl = tmpl\n  }\n}(this))\n"
  },
  {
    "path": "app_backend/static/plugin/JavaScript-Templates/package.json",
    "content": "{\n  \"name\": \"blueimp-tmpl\",\n  \"version\": \"3.4.0\",\n  \"title\": \"JavaScript Templates\",\n  \"description\": \"1KB lightweight, fast & powerful JavaScript templating engine with zero dependencies. Compatible with server-side environments like Node.js, module loaders like RequireJS, Browserify or webpack and all web browsers.\",\n  \"keywords\": [\n    \"javascript\",\n    \"templates\",\n    \"templating\"\n  ],\n  \"homepage\": \"https://github.com/blueimp/JavaScript-Templates\",\n  \"author\": {\n    \"name\": \"Sebastian Tschan\",\n    \"url\": \"https://blueimp.net\"\n  },\n  \"repository\": {\n    \"type\": \"git\",\n    \"url\": \"git://github.com/blueimp/JavaScript-Templates.git\"\n  },\n  \"license\": \"MIT\",\n  \"devDependencies\": {\n    \"expect.js\": \"0.3.1\",\n    \"mocha\": \"2.3.4\",\n    \"standard\": \"6.0.7\",\n    \"uglify-js\": \"2.6.1\"\n  },\n  \"scripts\": {\n    \"test\": \"standard js/*.js test/*.js && mocha\",\n    \"build\": \"cd js && uglifyjs tmpl.js -c -m -o tmpl.min.js --source-map tmpl.min.js.map\",\n    \"preversion\": \"npm test\",\n    \"version\": \"npm run build && git add -A js\",\n    \"postversion\": \"git push --tags origin master master:gh-pages && npm publish\"\n  },\n  \"bin\": {\n    \"tmpl.js\": \"js/compile.js\"\n  },\n  \"main\": \"js/tmpl.js\"\n}\n"
  },
  {
    "path": "app_backend/static/plugin/JavaScript-Templates/test/index.html",
    "content": "<!DOCTYPE HTML>\n<!--\n/*\n * JavaScript Templates Test\n * https://github.com/blueimp/JavaScript-Templates\n *\n * Copyright 2011, Sebastian Tschan\n * https://blueimp.net\n *\n * Licensed under the MIT license:\n * http://www.opensource.org/licenses/MIT\n */\n-->\n<html lang=\"en\">\n<head>\n<!--[if IE]>\n<meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge,chrome=1\">\n<![endif]-->\n<meta charset=\"utf-8\">\n<title>JavaScript Templates Test</title>\n<meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n<link rel=\"stylesheet\" href=\"vendor/mocha.css\">\n</head>\n<body>\n<div id=\"mocha\"></div>\n<script src=\"vendor/mocha.js\"></script>\n<script src=\"vendor/expect.js\"></script>\n<script>\nmocha.setup('bdd');\n</script>\n<script type=\"text/x-tmpl\" id=\"template\">{%=o.value%}</script>\n<script src=\"../js/tmpl.js\"></script>\n<script src=\"test.js\"></script>\n<script>\nmocha.checkLeaks();\nmocha.run();\n</script>\n</body>\n</html>\n"
  },
  {
    "path": "app_backend/static/plugin/JavaScript-Templates/test/test.js",
    "content": "/*\n * JavaScript Templates Test\n * https://github.com/blueimp/JavaScript-Templates\n *\n * Copyright 2011, Sebastian Tschan\n * https://blueimp.net\n *\n * Licensed under the MIT license:\n * http://www.opensource.org/licenses/MIT\n */\n\n/*global beforeEach, afterEach, describe, it, require */\n\n;(function (context, expect, tmpl) {\n  'use strict'\n\n  if (context.require === undefined) {\n    // Override the template loading method:\n    tmpl.load = function (id) {\n      switch (id) {\n        case 'template':\n          return '{%=o.value%}'\n      }\n    }\n  }\n\n  var data\n\n  beforeEach(function () {\n    // Initialize the sample data:\n    data = {\n      value: 'value',\n      nullValue: null,\n      falseValue: false,\n      zeroValue: 0,\n      special: '<>&\"\\'\\x00',\n      list: [1, 2, 3, 4, 5],\n      func: function () {\n        return this.value\n      },\n      deep: {\n        value: 'value'\n      }\n    }\n  })\n\n  afterEach(function () {\n    // Purge the template cache:\n    tmpl.cache = {}\n  })\n\n  describe('Template loading', function () {\n    it('String template', function () {\n      expect(\n        tmpl('{%=o.value%}', data)\n      ).to.be(\n        'value'\n      )\n    })\n\n    it('Load template by id', function () {\n      expect(\n        tmpl('template', data)\n      ).to.be(\n        'value'\n      )\n    })\n\n    it('Retun function when called without data parameter', function () {\n      expect(\n        tmpl('{%=o.value%}')(data)\n      ).to.be(\n        'value'\n      )\n    })\n\n    it('Cache templates loaded by id', function () {\n      tmpl('template')\n      expect(\n        tmpl.cache.template\n      ).to.be.a('function')\n    })\n  })\n\n  describe('Interpolation', function () {\n    it('Escape HTML special characters with {%=o.prop%}', function () {\n      expect(\n        tmpl('{%=o.special%}', data)\n      ).to.be(\n        '&lt;&gt;&amp;&quot;&#39;'\n      )\n    })\n\n    it('Allow HTML special characters with {%#o.prop%}', function () {\n      expect(\n        tmpl('{%#o.special%}', data)\n      ).to.be(\n        '<>&\"\\'\\x00'\n      )\n    })\n\n    it('Function call', function () {\n      expect(\n        tmpl('{%=o.func()%}', data)\n      ).to.be(\n        'value'\n      )\n    })\n\n    it('Dot notation', function () {\n      expect(\n        tmpl('{%=o.deep.value%}', data)\n      ).to.be(\n        'value'\n      )\n    })\n\n    it('Handle single quotes', function () {\n      expect(\n        tmpl('\\'single quotes\\'{%=\": \\'\"%}', data)\n      ).to.be(\n        \"'single quotes': &#39;\"\n      )\n    })\n\n    it('Handle double quotes', function () {\n      expect(\n        tmpl('\"double quotes\"{%=\": \\\\\"\"%}', data)\n      ).to.be(\n        '\"double quotes\": &quot;'\n      )\n    })\n\n    it('Handle backslashes', function () {\n      expect(\n        tmpl('\\\\backslashes\\\\{%=\": \\\\\\\\\"%}', data)\n      ).to.be(\n        '\\\\backslashes\\\\: \\\\'\n      )\n    })\n\n    it('Interpolate escaped falsy values except undefined or null', function () {\n      expect(\n        tmpl(\n          '{%=o.undefinedValue%}' +\n          '{%=o.nullValue%}' +\n          '{%=o.falseValue%}' +\n          '{%=o.zeroValue%}',\n          data\n        )\n      ).to.be(\n        'false0'\n      )\n    })\n\n    it('Interpolate unescaped falsy values except undefined or null', function () {\n      expect(\n        tmpl(\n          '{%#o.undefinedValue%}' +\n          '{%#o.nullValue%}' +\n          '{%#o.falseValue%}' +\n          '{%#o.zeroValue%}',\n          data\n        )\n      ).to.be(\n        'false0'\n      )\n    })\n\n    it('Preserve whitespace', function () {\n      expect(\n        tmpl(\n          '\\n\\r\\t{%=o.value%}  \\n\\r\\t{%=o.value%}  ',\n          data\n        )\n      ).to.be(\n        '\\n\\r\\tvalue  \\n\\r\\tvalue  '\n      )\n    })\n  })\n\n  describe('Evaluation', function () {\n    it('Escape HTML special characters with print(data)', function () {\n      expect(\n        tmpl('{% print(o.special); %}', data)\n      ).to.be(\n        '&lt;&gt;&amp;&quot;&#39;'\n      )\n    })\n\n    it('Allow HTML special characters with print(data, true)', function () {\n      expect(\n        tmpl('{% print(o.special, true); %}', data)\n      ).to.be(\n        '<>&\"\\'\\x00'\n      )\n    })\n\n    it('Print out escaped falsy values except undefined or null', function () {\n      expect(\n        tmpl(\n          '{% print(o.undefinedValue); %}' +\n          '{% print(o.nullValue); %}' +\n          '{% print(o.falseValue); %}' +\n          '{% print(o.zeroValue); %}',\n          data\n        )\n      ).to.be(\n        'false0'\n      )\n    })\n\n    it('Print out unescaped falsy values except undefined or null', function () {\n      expect(\n        tmpl(\n          '{% print(o.undefinedValue, true); %}' +\n          '{% print(o.nullValue, true); %}' +\n          '{% print(o.falseValue, true); %}' +\n          '{% print(o.zeroValue, true); %}',\n          data\n        )\n      ).to.be(\n        'false0'\n      )\n    })\n\n    it('Include template', function () {\n      expect(\n        tmpl('{% include(\"template\", {value: \"value\"}); %}', data)\n      ).to.be(\n        'value'\n      )\n    })\n\n    it('If condition', function () {\n      expect(\n        tmpl('{% if (o.value) { %}true{% } else { %}false{% } %}', data)\n      ).to.be(\n        'true'\n      )\n    })\n\n    it('Else condition', function () {\n      expect(\n        tmpl(\n          '{% if (o.undefinedValue) { %}false{% } else { %}true{% } %}',\n          data\n        )\n      ).to.be(\n        'true'\n      )\n    })\n\n    it('For loop', function () {\n      expect(\n        tmpl(\n          '{% for (var i=0; i<o.list.length; i++) { %}' +\n          '{%=o.list[i]%}{% } %}',\n          data\n        )\n      ).to.be(\n        '12345'\n      )\n    })\n\n    it('For loop print call', function () {\n      expect(\n        tmpl(\n          '{% for (var i=0; i<o.list.length; i++) {' +\n          'print(o.list[i]);} %}',\n          data\n        )\n      ).to.be(\n        '12345'\n      )\n    })\n\n    it('For loop include template', function () {\n      expect(\n        tmpl(\n          '{% for (var i=0; i<o.list.length; i++) {' +\n          'include(\"template\", {value: o.list[i]});} %}',\n          data\n        ).replace(/[\\r\\n]/g, '')\n      ).to.be(\n        '12345'\n      )\n    })\n\n    it('Modulo operator', function () {\n      expect(\n        tmpl(\n          '{% if (o.list.length % 5 === 0) { %}5 list items{% } %}',\n          data\n        ).replace(/[\\r\\n]/g, '')\n      ).to.be(\n        '5 list items'\n      )\n    })\n  })\n}(\n  this,\n  this.expect || require('expect.js'),\n  this.tmpl || require('../js/tmpl')\n))\n"
  },
  {
    "path": "app_backend/static/plugin/JavaScript-Templates/test/vendor/expect.js",
    "content": "(function (global, module) {\n\n  var exports = module.exports;\n\n  /**\n   * Exports.\n   */\n\n  module.exports = expect;\n  expect.Assertion = Assertion;\n\n  /**\n   * Exports version.\n   */\n\n  expect.version = '0.3.1';\n\n  /**\n   * Possible assertion flags.\n   */\n\n  var flags = {\n      not: ['to', 'be', 'have', 'include', 'only']\n    , to: ['be', 'have', 'include', 'only', 'not']\n    , only: ['have']\n    , have: ['own']\n    , be: ['an']\n  };\n\n  function expect (obj) {\n    return new Assertion(obj);\n  }\n\n  /**\n   * Constructor\n   *\n   * @api private\n   */\n\n  function Assertion (obj, flag, parent) {\n    this.obj = obj;\n    this.flags = {};\n\n    if (undefined != parent) {\n      this.flags[flag] = true;\n\n      for (var i in parent.flags) {\n        if (parent.flags.hasOwnProperty(i)) {\n          this.flags[i] = true;\n        }\n      }\n    }\n\n    var $flags = flag ? flags[flag] : keys(flags)\n      , self = this;\n\n    if ($flags) {\n      for (var i = 0, l = $flags.length; i < l; i++) {\n        // avoid recursion\n        if (this.flags[$flags[i]]) continue;\n\n        var name = $flags[i]\n          , assertion = new Assertion(this.obj, name, this)\n\n        if ('function' == typeof Assertion.prototype[name]) {\n          // clone the function, make sure we dont touch the prot reference\n          var old = this[name];\n          this[name] = function () {\n            return old.apply(self, arguments);\n          };\n\n          for (var fn in Assertion.prototype) {\n            if (Assertion.prototype.hasOwnProperty(fn) && fn != name) {\n              this[name][fn] = bind(assertion[fn], assertion);\n            }\n          }\n        } else {\n          this[name] = assertion;\n        }\n      }\n    }\n  }\n\n  /**\n   * Performs an assertion\n   *\n   * @api private\n   */\n\n  Assertion.prototype.assert = function (truth, msg, error, expected) {\n    var msg = this.flags.not ? error : msg\n      , ok = this.flags.not ? !truth : truth\n      , err;\n\n    if (!ok) {\n      err = new Error(msg.call(this));\n      if (arguments.length > 3) {\n        err.actual = this.obj;\n        err.expected = expected;\n        err.showDiff = true;\n      }\n      throw err;\n    }\n\n    this.and = new Assertion(this.obj);\n  };\n\n  /**\n   * Check if the value is truthy\n   *\n   * @api public\n   */\n\n  Assertion.prototype.ok = function () {\n    this.assert(\n        !!this.obj\n      , function(){ return 'expected ' + i(this.obj) + ' to be truthy' }\n      , function(){ return 'expected ' + i(this.obj) + ' to be falsy' });\n  };\n\n  /**\n   * Creates an anonymous function which calls fn with arguments.\n   *\n   * @api public\n   */\n\n  Assertion.prototype.withArgs = function() {\n    expect(this.obj).to.be.a('function');\n    var fn = this.obj;\n    var args = Array.prototype.slice.call(arguments);\n    return expect(function() { fn.apply(null, args); });\n  };\n\n  /**\n   * Assert that the function throws.\n   *\n   * @param {Function|RegExp} callback, or regexp to match error string against\n   * @api public\n   */\n\n  Assertion.prototype.throwError =\n  Assertion.prototype.throwException = function (fn) {\n    expect(this.obj).to.be.a('function');\n\n    var thrown = false\n      , not = this.flags.not;\n\n    try {\n      this.obj();\n    } catch (e) {\n      if (isRegExp(fn)) {\n        var subject = 'string' == typeof e ? e : e.message;\n        if (not) {\n          expect(subject).to.not.match(fn);\n        } else {\n          expect(subject).to.match(fn);\n        }\n      } else if ('function' == typeof fn) {\n        fn(e);\n      }\n      thrown = true;\n    }\n\n    if (isRegExp(fn) && not) {\n      // in the presence of a matcher, ensure the `not` only applies to\n      // the matching.\n      this.flags.not = false;\n    }\n\n    var name = this.obj.name || 'fn';\n    this.assert(\n        thrown\n      , function(){ return 'expected ' + name + ' to throw an exception' }\n      , function(){ return 'expected ' + name + ' not to throw an exception' });\n  };\n\n  /**\n   * Checks if the array is empty.\n   *\n   * @api public\n   */\n\n  Assertion.prototype.empty = function () {\n    var expectation;\n\n    if ('object' == typeof this.obj && null !== this.obj && !isArray(this.obj)) {\n      if ('number' == typeof this.obj.length) {\n        expectation = !this.obj.length;\n      } else {\n        expectation = !keys(this.obj).length;\n      }\n    } else {\n      if ('string' != typeof this.obj) {\n        expect(this.obj).to.be.an('object');\n      }\n\n      expect(this.obj).to.have.property('length');\n      expectation = !this.obj.length;\n    }\n\n    this.assert(\n        expectation\n      , function(){ return 'expected ' + i(this.obj) + ' to be empty' }\n      , function(){ return 'expected ' + i(this.obj) + ' to not be empty' });\n    return this;\n  };\n\n  /**\n   * Checks if the obj exactly equals another.\n   *\n   * @api public\n   */\n\n  Assertion.prototype.be =\n  Assertion.prototype.equal = function (obj) {\n    this.assert(\n        obj === this.obj\n      , function(){ return 'expected ' + i(this.obj) + ' to equal ' + i(obj) }\n      , function(){ return 'expected ' + i(this.obj) + ' to not equal ' + i(obj) });\n    return this;\n  };\n\n  /**\n   * Checks if the obj sortof equals another.\n   *\n   * @api public\n   */\n\n  Assertion.prototype.eql = function (obj) {\n    this.assert(\n        expect.eql(this.obj, obj)\n      , function(){ return 'expected ' + i(this.obj) + ' to sort of equal ' + i(obj) }\n      , function(){ return 'expected ' + i(this.obj) + ' to sort of not equal ' + i(obj) }\n      , obj);\n    return this;\n  };\n\n  /**\n   * Assert within start to finish (inclusive).\n   *\n   * @param {Number} start\n   * @param {Number} finish\n   * @api public\n   */\n\n  Assertion.prototype.within = function (start, finish) {\n    var range = start + '..' + finish;\n    this.assert(\n        this.obj >= start && this.obj <= finish\n      , function(){ return 'expected ' + i(this.obj) + ' to be within ' + range }\n      , function(){ return 'expected ' + i(this.obj) + ' to not be within ' + range });\n    return this;\n  };\n\n  /**\n   * Assert typeof / instance of\n   *\n   * @api public\n   */\n\n  Assertion.prototype.a =\n  Assertion.prototype.an = function (type) {\n    if ('string' == typeof type) {\n      // proper english in error msg\n      var n = /^[aeiou]/.test(type) ? 'n' : '';\n\n      // typeof with support for 'array'\n      this.assert(\n          'array' == type ? isArray(this.obj) :\n            'regexp' == type ? isRegExp(this.obj) :\n              'object' == type\n                ? 'object' == typeof this.obj && null !== this.obj\n                : type == typeof this.obj\n        , function(){ return 'expected ' + i(this.obj) + ' to be a' + n + ' ' + type }\n        , function(){ return 'expected ' + i(this.obj) + ' not to be a' + n + ' ' + type });\n    } else {\n      // instanceof\n      var name = type.name || 'supplied constructor';\n      this.assert(\n          this.obj instanceof type\n        , function(){ return 'expected ' + i(this.obj) + ' to be an instance of ' + name }\n        , function(){ return 'expected ' + i(this.obj) + ' not to be an instance of ' + name });\n    }\n\n    return this;\n  };\n\n  /**\n   * Assert numeric value above _n_.\n   *\n   * @param {Number} n\n   * @api public\n   */\n\n  Assertion.prototype.greaterThan =\n  Assertion.prototype.above = function (n) {\n    this.assert(\n        this.obj > n\n      , function(){ return 'expected ' + i(this.obj) + ' to be above ' + n }\n      , function(){ return 'expected ' + i(this.obj) + ' to be below ' + n });\n    return this;\n  };\n\n  /**\n   * Assert numeric value below _n_.\n   *\n   * @param {Number} n\n   * @api public\n   */\n\n  Assertion.prototype.lessThan =\n  Assertion.prototype.below = function (n) {\n    this.assert(\n        this.obj < n\n      , function(){ return 'expected ' + i(this.obj) + ' to be below ' + n }\n      , function(){ return 'expected ' + i(this.obj) + ' to be above ' + n });\n    return this;\n  };\n\n  /**\n   * Assert string value matches _regexp_.\n   *\n   * @param {RegExp} regexp\n   * @api public\n   */\n\n  Assertion.prototype.match = function (regexp) {\n    this.assert(\n        regexp.exec(this.obj)\n      , function(){ return 'expected ' + i(this.obj) + ' to match ' + regexp }\n      , function(){ return 'expected ' + i(this.obj) + ' not to match ' + regexp });\n    return this;\n  };\n\n  /**\n   * Assert property \"length\" exists and has value of _n_.\n   *\n   * @param {Number} n\n   * @api public\n   */\n\n  Assertion.prototype.length = function (n) {\n    expect(this.obj).to.have.property('length');\n    var len = this.obj.length;\n    this.assert(\n        n == len\n      , function(){ return 'expected ' + i(this.obj) + ' to have a length of ' + n + ' but got ' + len }\n      , function(){ return 'expected ' + i(this.obj) + ' to not have a length of ' + len });\n    return this;\n  };\n\n  /**\n   * Assert property _name_ exists, with optional _val_.\n   *\n   * @param {String} name\n   * @param {Mixed} val\n   * @api public\n   */\n\n  Assertion.prototype.property = function (name, val) {\n    if (this.flags.own) {\n      this.assert(\n          Object.prototype.hasOwnProperty.call(this.obj, name)\n        , function(){ return 'expected ' + i(this.obj) + ' to have own property ' + i(name) }\n        , function(){ return 'expected ' + i(this.obj) + ' to not have own property ' + i(name) });\n      return this;\n    }\n\n    if (this.flags.not && undefined !== val) {\n      if (undefined === this.obj[name]) {\n        throw new Error(i(this.obj) + ' has no property ' + i(name));\n      }\n    } else {\n      var hasProp;\n      try {\n        hasProp = name in this.obj\n      } catch (e) {\n        hasProp = undefined !== this.obj[name]\n      }\n\n      this.assert(\n          hasProp\n        , function(){ return 'expected ' + i(this.obj) + ' to have a property ' + i(name) }\n        , function(){ return 'expected ' + i(this.obj) + ' to not have a property ' + i(name) });\n    }\n\n    if (undefined !== val) {\n      this.assert(\n          val === this.obj[name]\n        , function(){ return 'expected ' + i(this.obj) + ' to have a property ' + i(name)\n          + ' of ' + i(val) + ', but got ' + i(this.obj[name]) }\n        , function(){ return 'expected ' + i(this.obj) + ' to not have a property ' + i(name)\n          + ' of ' + i(val) });\n    }\n\n    this.obj = this.obj[name];\n    return this;\n  };\n\n  /**\n   * Assert that the array contains _obj_ or string contains _obj_.\n   *\n   * @param {Mixed} obj|string\n   * @api public\n   */\n\n  Assertion.prototype.string =\n  Assertion.prototype.contain = function (obj) {\n    if ('string' == typeof this.obj) {\n      this.assert(\n          ~this.obj.indexOf(obj)\n        , function(){ return 'expected ' + i(this.obj) + ' to contain ' + i(obj) }\n        , function(){ return 'expected ' + i(this.obj) + ' to not contain ' + i(obj) });\n    } else {\n      this.assert(\n          ~indexOf(this.obj, obj)\n        , function(){ return 'expected ' + i(this.obj) + ' to contain ' + i(obj) }\n        , function(){ return 'expected ' + i(this.obj) + ' to not contain ' + i(obj) });\n    }\n    return this;\n  };\n\n  /**\n   * Assert exact keys or inclusion of keys by using\n   * the `.own` modifier.\n   *\n   * @param {Array|String ...} keys\n   * @api public\n   */\n\n  Assertion.prototype.key =\n  Assertion.prototype.keys = function ($keys) {\n    var str\n      , ok = true;\n\n    $keys = isArray($keys)\n      ? $keys\n      : Array.prototype.slice.call(arguments);\n\n    if (!$keys.length) throw new Error('keys required');\n\n    var actual = keys(this.obj)\n      , len = $keys.length;\n\n    // Inclusion\n    ok = every($keys, function (key) {\n      return ~indexOf(actual, key);\n    });\n\n    // Strict\n    if (!this.flags.not && this.flags.only) {\n      ok = ok && $keys.length == actual.length;\n    }\n\n    // Key string\n    if (len > 1) {\n      $keys = map($keys, function (key) {\n        return i(key);\n      });\n      var last = $keys.pop();\n      str = $keys.join(', ') + ', and ' + last;\n    } else {\n      str = i($keys[0]);\n    }\n\n    // Form\n    str = (len > 1 ? 'keys ' : 'key ') + str;\n\n    // Have / include\n    str = (!this.flags.only ? 'include ' : 'only have ') + str;\n\n    // Assertion\n    this.assert(\n        ok\n      , function(){ return 'expected ' + i(this.obj) + ' to ' + str }\n      , function(){ return 'expected ' + i(this.obj) + ' to not ' + str });\n\n    return this;\n  };\n\n  /**\n   * Assert a failure.\n   *\n   * @param {String ...} custom message\n   * @api public\n   */\n  Assertion.prototype.fail = function (msg) {\n    var error = function() { return msg || \"explicit failure\"; }\n    this.assert(false, error, error);\n    return this;\n  };\n\n  /**\n   * Function bind implementation.\n   */\n\n  function bind (fn, scope) {\n    return function () {\n      return fn.apply(scope, arguments);\n    }\n  }\n\n  /**\n   * Array every compatibility\n   *\n   * @see bit.ly/5Fq1N2\n   * @api public\n   */\n\n  function every (arr, fn, thisObj) {\n    var scope = thisObj || global;\n    for (var i = 0, j = arr.length; i < j; ++i) {\n      if (!fn.call(scope, arr[i], i, arr)) {\n        return false;\n      }\n    }\n    return true;\n  }\n\n  /**\n   * Array indexOf compatibility.\n   *\n   * @see bit.ly/a5Dxa2\n   * @api public\n   */\n\n  function indexOf (arr, o, i) {\n    if (Array.prototype.indexOf) {\n      return Array.prototype.indexOf.call(arr, o, i);\n    }\n\n    if (arr.length === undefined) {\n      return -1;\n    }\n\n    for (var j = arr.length, i = i < 0 ? i + j < 0 ? 0 : i + j : i || 0\n        ; i < j && arr[i] !== o; i++);\n\n    return j <= i ? -1 : i;\n  }\n\n  // https://gist.github.com/1044128/\n  var getOuterHTML = function(element) {\n    if ('outerHTML' in element) return element.outerHTML;\n    var ns = \"http://www.w3.org/1999/xhtml\";\n    var container = document.createElementNS(ns, '_');\n    var xmlSerializer = new XMLSerializer();\n    var html;\n    if (document.xmlVersion) {\n      return xmlSerializer.serializeToString(element);\n    } else {\n      container.appendChild(element.cloneNode(false));\n      html = container.innerHTML.replace('><', '>' + element.innerHTML + '<');\n      container.innerHTML = '';\n      return html;\n    }\n  };\n\n  // Returns true if object is a DOM element.\n  var isDOMElement = function (object) {\n    if (typeof HTMLElement === 'object') {\n      return object instanceof HTMLElement;\n    } else {\n      return object &&\n        typeof object === 'object' &&\n        object.nodeType === 1 &&\n        typeof object.nodeName === 'string';\n    }\n  };\n\n  /**\n   * Inspects an object.\n   *\n   * @see taken from node.js `util` module (copyright Joyent, MIT license)\n   * @api private\n   */\n\n  function i (obj, showHidden, depth) {\n    var seen = [];\n\n    function stylize (str) {\n      return str;\n    }\n\n    function format (value, recurseTimes) {\n      // Provide a hook for user-specified inspect functions.\n      // Check that value is an object with an inspect function on it\n      if (value && typeof value.inspect === 'function' &&\n          // Filter out the util module, it's inspect function is special\n          value !== exports &&\n          // Also filter out any prototype objects using the circular check.\n          !(value.constructor && value.constructor.prototype === value)) {\n        return value.inspect(recurseTimes);\n      }\n\n      // Primitive types cannot have properties\n      switch (typeof value) {\n        case 'undefined':\n          return stylize('undefined', 'undefined');\n\n        case 'string':\n          var simple = '\\'' + json.stringify(value).replace(/^\"|\"$/g, '')\n                                                   .replace(/'/g, \"\\\\'\")\n                                                   .replace(/\\\\\"/g, '\"') + '\\'';\n          return stylize(simple, 'string');\n\n        case 'number':\n          return stylize('' + value, 'number');\n\n        case 'boolean':\n          return stylize('' + value, 'boolean');\n      }\n      // For some reason typeof null is \"object\", so special case here.\n      if (value === null) {\n        return stylize('null', 'null');\n      }\n\n      if (isDOMElement(value)) {\n        return getOuterHTML(value);\n      }\n\n      // Look up the keys of the object.\n      var visible_keys = keys(value);\n      var $keys = showHidden ? Object.getOwnPropertyNames(value) : visible_keys;\n\n      // Functions without properties can be shortcutted.\n      if (typeof value === 'function' && $keys.length === 0) {\n        if (isRegExp(value)) {\n          return stylize('' + value, 'regexp');\n        } else {\n          var name = value.name ? ': ' + value.name : '';\n          return stylize('[Function' + name + ']', 'special');\n        }\n      }\n\n      // Dates without properties can be shortcutted\n      if (isDate(value) && $keys.length === 0) {\n        return stylize(value.toUTCString(), 'date');\n      }\n      \n      // Error objects can be shortcutted\n      if (value instanceof Error) {\n        return stylize(\"[\"+value.toString()+\"]\", 'Error');\n      }\n\n      var base, type, braces;\n      // Determine the object type\n      if (isArray(value)) {\n        type = 'Array';\n        braces = ['[', ']'];\n      } else {\n        type = 'Object';\n        braces = ['{', '}'];\n      }\n\n      // Make functions say that they are functions\n      if (typeof value === 'function') {\n        var n = value.name ? ': ' + value.name : '';\n        base = (isRegExp(value)) ? ' ' + value : ' [Function' + n + ']';\n      } else {\n        base = '';\n      }\n\n      // Make dates with properties first say the date\n      if (isDate(value)) {\n        base = ' ' + value.toUTCString();\n      }\n\n      if ($keys.length === 0) {\n        return braces[0] + base + braces[1];\n      }\n\n      if (recurseTimes < 0) {\n        if (isRegExp(value)) {\n          return stylize('' + value, 'regexp');\n        } else {\n          return stylize('[Object]', 'special');\n        }\n      }\n\n      seen.push(value);\n\n      var output = map($keys, function (key) {\n        var name, str;\n        if (value.__lookupGetter__) {\n          if (value.__lookupGetter__(key)) {\n            if (value.__lookupSetter__(key)) {\n              str = stylize('[Getter/Setter]', 'special');\n            } else {\n              str = stylize('[Getter]', 'special');\n            }\n          } else {\n            if (value.__lookupSetter__(key)) {\n              str = stylize('[Setter]', 'special');\n            }\n          }\n        }\n        if (indexOf(visible_keys, key) < 0) {\n          name = '[' + key + ']';\n        }\n        if (!str) {\n          if (indexOf(seen, value[key]) < 0) {\n            if (recurseTimes === null) {\n              str = format(value[key]);\n            } else {\n              str = format(value[key], recurseTimes - 1);\n            }\n            if (str.indexOf('\\n') > -1) {\n              if (isArray(value)) {\n                str = map(str.split('\\n'), function (line) {\n                  return '  ' + line;\n                }).join('\\n').substr(2);\n              } else {\n                str = '\\n' + map(str.split('\\n'), function (line) {\n                  return '   ' + line;\n                }).join('\\n');\n              }\n            }\n          } else {\n            str = stylize('[Circular]', 'special');\n          }\n        }\n        if (typeof name === 'undefined') {\n          if (type === 'Array' && key.match(/^\\d+$/)) {\n            return str;\n          }\n          name = json.stringify('' + key);\n          if (name.match(/^\"([a-zA-Z_][a-zA-Z_0-9]*)\"$/)) {\n            name = name.substr(1, name.length - 2);\n            name = stylize(name, 'name');\n          } else {\n            name = name.replace(/'/g, \"\\\\'\")\n                       .replace(/\\\\\"/g, '\"')\n                       .replace(/(^\"|\"$)/g, \"'\");\n            name = stylize(name, 'string');\n          }\n        }\n\n        return name + ': ' + str;\n      });\n\n      seen.pop();\n\n      var numLinesEst = 0;\n      var length = reduce(output, function (prev, cur) {\n        numLinesEst++;\n        if (indexOf(cur, '\\n') >= 0) numLinesEst++;\n        return prev + cur.length + 1;\n      }, 0);\n\n      if (length > 50) {\n        output = braces[0] +\n                 (base === '' ? '' : base + '\\n ') +\n                 ' ' +\n                 output.join(',\\n  ') +\n                 ' ' +\n                 braces[1];\n\n      } else {\n        output = braces[0] + base + ' ' + output.join(', ') + ' ' + braces[1];\n      }\n\n      return output;\n    }\n    return format(obj, (typeof depth === 'undefined' ? 2 : depth));\n  }\n\n  expect.stringify = i;\n\n  function isArray (ar) {\n    return Object.prototype.toString.call(ar) === '[object Array]';\n  }\n\n  function isRegExp(re) {\n    var s;\n    try {\n      s = '' + re;\n    } catch (e) {\n      return false;\n    }\n\n    return re instanceof RegExp || // easy case\n           // duck-type for context-switching evalcx case\n           typeof(re) === 'function' &&\n           re.constructor.name === 'RegExp' &&\n           re.compile &&\n           re.test &&\n           re.exec &&\n           s.match(/^\\/.*\\/[gim]{0,3}$/);\n  }\n\n  function isDate(d) {\n    return d instanceof Date;\n  }\n\n  function keys (obj) {\n    if (Object.keys) {\n      return Object.keys(obj);\n    }\n\n    var keys = [];\n\n    for (var i in obj) {\n      if (Object.prototype.hasOwnProperty.call(obj, i)) {\n        keys.push(i);\n      }\n    }\n\n    return keys;\n  }\n\n  function map (arr, mapper, that) {\n    if (Array.prototype.map) {\n      return Array.prototype.map.call(arr, mapper, that);\n    }\n\n    var other= new Array(arr.length);\n\n    for (var i= 0, n = arr.length; i<n; i++)\n      if (i in arr)\n        other[i] = mapper.call(that, arr[i], i, arr);\n\n    return other;\n  }\n\n  function reduce (arr, fun) {\n    if (Array.prototype.reduce) {\n      return Array.prototype.reduce.apply(\n          arr\n        , Array.prototype.slice.call(arguments, 1)\n      );\n    }\n\n    var len = +this.length;\n\n    if (typeof fun !== \"function\")\n      throw new TypeError();\n\n    // no value to return if no initial value and an empty array\n    if (len === 0 && arguments.length === 1)\n      throw new TypeError();\n\n    var i = 0;\n    if (arguments.length >= 2) {\n      var rv = arguments[1];\n    } else {\n      do {\n        if (i in this) {\n          rv = this[i++];\n          break;\n        }\n\n        // if array contains no values, no initial value to return\n        if (++i >= len)\n          throw new TypeError();\n      } while (true);\n    }\n\n    for (; i < len; i++) {\n      if (i in this)\n        rv = fun.call(null, rv, this[i], i, this);\n    }\n\n    return rv;\n  }\n\n  /**\n   * Asserts deep equality\n   *\n   * @see taken from node.js `assert` module (copyright Joyent, MIT license)\n   * @api private\n   */\n\n  expect.eql = function eql(actual, expected) {\n    // 7.1. All identical values are equivalent, as determined by ===.\n    if (actual === expected) {\n      return true;\n    } else if ('undefined' != typeof Buffer\n      && Buffer.isBuffer(actual) && Buffer.isBuffer(expected)) {\n      if (actual.length != expected.length) return false;\n\n      for (var i = 0; i < actual.length; i++) {\n        if (actual[i] !== expected[i]) return false;\n      }\n\n      return true;\n\n      // 7.2. If the expected value is a Date object, the actual value is\n      // equivalent if it is also a Date object that refers to the same time.\n    } else if (actual instanceof Date && expected instanceof Date) {\n      return actual.getTime() === expected.getTime();\n\n      // 7.3. Other pairs that do not both pass typeof value == \"object\",\n      // equivalence is determined by ==.\n    } else if (typeof actual != 'object' && typeof expected != 'object') {\n      return actual == expected;\n    // If both are regular expression use the special `regExpEquiv` method\n    // to determine equivalence.\n    } else if (isRegExp(actual) && isRegExp(expected)) {\n      return regExpEquiv(actual, expected);\n    // 7.4. For all other Object pairs, including Array objects, equivalence is\n    // determined by having the same number of owned properties (as verified\n    // with Object.prototype.hasOwnProperty.call), the same set of keys\n    // (although not necessarily the same order), equivalent values for every\n    // corresponding key, and an identical \"prototype\" property. Note: this\n    // accounts for both named and indexed properties on Arrays.\n    } else {\n      return objEquiv(actual, expected);\n    }\n  };\n\n  function isUndefinedOrNull (value) {\n    return value === null || value === undefined;\n  }\n\n  function isArguments (object) {\n    return Object.prototype.toString.call(object) == '[object Arguments]';\n  }\n\n  function regExpEquiv (a, b) {\n    return a.source === b.source && a.global === b.global &&\n           a.ignoreCase === b.ignoreCase && a.multiline === b.multiline;\n  }\n\n  function objEquiv (a, b) {\n    if (isUndefinedOrNull(a) || isUndefinedOrNull(b))\n      return false;\n    // an identical \"prototype\" property.\n    if (a.prototype !== b.prototype) return false;\n    //~~~I've managed to break Object.keys through screwy arguments passing.\n    //   Converting to array solves the problem.\n    if (isArguments(a)) {\n      if (!isArguments(b)) {\n        return false;\n      }\n      a = pSlice.call(a);\n      b = pSlice.call(b);\n      return expect.eql(a, b);\n    }\n    try{\n      var ka = keys(a),\n        kb = keys(b),\n        key, i;\n    } catch (e) {//happens when one is a string literal and the other isn't\n      return false;\n    }\n    // having the same number of owned properties (keys incorporates hasOwnProperty)\n    if (ka.length != kb.length)\n      return false;\n    //the same set of keys (although not necessarily the same order),\n    ka.sort();\n    kb.sort();\n    //~~~cheap key test\n    for (i = ka.length - 1; i >= 0; i--) {\n      if (ka[i] != kb[i])\n        return false;\n    }\n    //equivalent values for every corresponding key, and\n    //~~~possibly expensive deep test\n    for (i = ka.length - 1; i >= 0; i--) {\n      key = ka[i];\n      if (!expect.eql(a[key], b[key]))\n         return false;\n    }\n    return true;\n  }\n\n  var json = (function () {\n    \"use strict\";\n\n    if ('object' == typeof JSON && JSON.parse && JSON.stringify) {\n      return {\n          parse: nativeJSON.parse\n        , stringify: nativeJSON.stringify\n      }\n    }\n\n    var JSON = {};\n\n    function f(n) {\n        // Format integers to have at least two digits.\n        return n < 10 ? '0' + n : n;\n    }\n\n    function date(d, key) {\n      return isFinite(d.valueOf()) ?\n          d.getUTCFullYear()     + '-' +\n          f(d.getUTCMonth() + 1) + '-' +\n          f(d.getUTCDate())      + 'T' +\n          f(d.getUTCHours())     + ':' +\n          f(d.getUTCMinutes())   + ':' +\n          f(d.getUTCSeconds())   + 'Z' : null;\n    }\n\n    var cx = /[\\u0000\\u00ad\\u0600-\\u0604\\u070f\\u17b4\\u17b5\\u200c-\\u200f\\u2028-\\u202f\\u2060-\\u206f\\ufeff\\ufff0-\\uffff]/g,\n        escapable = /[\\\\\\\"\\x00-\\x1f\\x7f-\\x9f\\u00ad\\u0600-\\u0604\\u070f\\u17b4\\u17b5\\u200c-\\u200f\\u2028-\\u202f\\u2060-\\u206f\\ufeff\\ufff0-\\uffff]/g,\n        gap,\n        indent,\n        meta = {    // table of character substitutions\n            '\\b': '\\\\b',\n            '\\t': '\\\\t',\n            '\\n': '\\\\n',\n            '\\f': '\\\\f',\n            '\\r': '\\\\r',\n            '\"' : '\\\\\"',\n            '\\\\': '\\\\\\\\'\n        },\n        rep;\n\n\n    function quote(string) {\n\n  // If the string contains no control characters, no quote characters, and no\n  // backslash characters, then we can safely slap some quotes around it.\n  // Otherwise we must also replace the offending characters with safe escape\n  // sequences.\n\n        escapable.lastIndex = 0;\n        return escapable.test(string) ? '\"' + string.replace(escapable, function (a) {\n            var c = meta[a];\n            return typeof c === 'string' ? c :\n                '\\\\u' + ('0000' + a.charCodeAt(0).toString(16)).slice(-4);\n        }) + '\"' : '\"' + string + '\"';\n    }\n\n\n    function str(key, holder) {\n\n  // Produce a string from holder[key].\n\n        var i,          // The loop counter.\n            k,          // The member key.\n            v,          // The member value.\n            length,\n            mind = gap,\n            partial,\n            value = holder[key];\n\n  // If the value has a toJSON method, call it to obtain a replacement value.\n\n        if (value instanceof Date) {\n            value = date(key);\n        }\n\n  // If we were called with a replacer function, then call the replacer to\n  // obtain a replacement value.\n\n        if (typeof rep === 'function') {\n            value = rep.call(holder, key, value);\n        }\n\n  // What happens next depends on the value's type.\n\n        switch (typeof value) {\n        case 'string':\n            return quote(value);\n\n        case 'number':\n\n  // JSON numbers must be finite. Encode non-finite numbers as null.\n\n            return isFinite(value) ? String(value) : 'null';\n\n        case 'boolean':\n        case 'null':\n\n  // If the value is a boolean or null, convert it to a string. Note:\n  // typeof null does not produce 'null'. The case is included here in\n  // the remote chance that this gets fixed someday.\n\n            return String(value);\n\n  // If the type is 'object', we might be dealing with an object or an array or\n  // null.\n\n        case 'object':\n\n  // Due to a specification blunder in ECMAScript, typeof null is 'object',\n  // so watch out for that case.\n\n            if (!value) {\n                return 'null';\n            }\n\n  // Make an array to hold the partial results of stringifying this object value.\n\n            gap += indent;\n            partial = [];\n\n  // Is the value an array?\n\n            if (Object.prototype.toString.apply(value) === '[object Array]') {\n\n  // The value is an array. Stringify every element. Use null as a placeholder\n  // for non-JSON values.\n\n                length = value.length;\n                for (i = 0; i < length; i += 1) {\n                    partial[i] = str(i, value) || 'null';\n                }\n\n  // Join all of the elements together, separated with commas, and wrap them in\n  // brackets.\n\n                v = partial.length === 0 ? '[]' : gap ?\n                    '[\\n' + gap + partial.join(',\\n' + gap) + '\\n' + mind + ']' :\n                    '[' + partial.join(',') + ']';\n                gap = mind;\n                return v;\n            }\n\n  // If the replacer is an array, use it to select the members to be stringified.\n\n            if (rep && typeof rep === 'object') {\n                length = rep.length;\n                for (i = 0; i < length; i += 1) {\n                    if (typeof rep[i] === 'string') {\n                        k = rep[i];\n                        v = str(k, value);\n                        if (v) {\n                            partial.push(quote(k) + (gap ? ': ' : ':') + v);\n                        }\n                    }\n                }\n            } else {\n\n  // Otherwise, iterate through all of the keys in the object.\n\n                for (k in value) {\n                    if (Object.prototype.hasOwnProperty.call(value, k)) {\n                        v = str(k, value);\n                        if (v) {\n                            partial.push(quote(k) + (gap ? ': ' : ':') + v);\n                        }\n                    }\n                }\n            }\n\n  // Join all of the member texts together, separated with commas,\n  // and wrap them in braces.\n\n            v = partial.length === 0 ? '{}' : gap ?\n                '{\\n' + gap + partial.join(',\\n' + gap) + '\\n' + mind + '}' :\n                '{' + partial.join(',') + '}';\n            gap = mind;\n            return v;\n        }\n    }\n\n  // If the JSON object does not yet have a stringify method, give it one.\n\n    JSON.stringify = function (value, replacer, space) {\n\n  // The stringify method takes a value and an optional replacer, and an optional\n  // space parameter, and returns a JSON text. The replacer can be a function\n  // that can replace values, or an array of strings that will select the keys.\n  // A default replacer method can be provided. Use of the space parameter can\n  // produce text that is more easily readable.\n\n        var i;\n        gap = '';\n        indent = '';\n\n  // If the space parameter is a number, make an indent string containing that\n  // many spaces.\n\n        if (typeof space === 'number') {\n            for (i = 0; i < space; i += 1) {\n                indent += ' ';\n            }\n\n  // If the space parameter is a string, it will be used as the indent string.\n\n        } else if (typeof space === 'string') {\n            indent = space;\n        }\n\n  // If there is a replacer, it must be a function or an array.\n  // Otherwise, throw an error.\n\n        rep = replacer;\n        if (replacer && typeof replacer !== 'function' &&\n                (typeof replacer !== 'object' ||\n                typeof replacer.length !== 'number')) {\n            throw new Error('JSON.stringify');\n        }\n\n  // Make a fake root object containing our value under the key of ''.\n  // Return the result of stringifying the value.\n\n        return str('', {'': value});\n    };\n\n  // If the JSON object does not yet have a parse method, give it one.\n\n    JSON.parse = function (text, reviver) {\n    // The parse method takes a text and an optional reviver function, and returns\n    // a JavaScript value if the text is a valid JSON text.\n\n        var j;\n\n        function walk(holder, key) {\n\n    // The walk method is used to recursively walk the resulting structure so\n    // that modifications can be made.\n\n            var k, v, value = holder[key];\n            if (value && typeof value === 'object') {\n                for (k in value) {\n                    if (Object.prototype.hasOwnProperty.call(value, k)) {\n                        v = walk(value, k);\n                        if (v !== undefined) {\n                            value[k] = v;\n                        } else {\n                            delete value[k];\n                        }\n                    }\n                }\n            }\n            return reviver.call(holder, key, value);\n        }\n\n\n    // Parsing happens in four stages. In the first stage, we replace certain\n    // Unicode characters with escape sequences. JavaScript handles many characters\n    // incorrectly, either silently deleting them, or treating them as line endings.\n\n        text = String(text);\n        cx.lastIndex = 0;\n        if (cx.test(text)) {\n            text = text.replace(cx, function (a) {\n                return '\\\\u' +\n                    ('0000' + a.charCodeAt(0).toString(16)).slice(-4);\n            });\n        }\n\n    // In the second stage, we run the text against regular expressions that look\n    // for non-JSON patterns. We are especially concerned with '()' and 'new'\n    // because they can cause invocation, and '=' because it can cause mutation.\n    // But just to be safe, we want to reject all unexpected forms.\n\n    // We split the second stage into 4 regexp operations in order to work around\n    // crippling inefficiencies in IE's and Safari's regexp engines. First we\n    // replace the JSON backslash pairs with '@' (a non-JSON character). Second, we\n    // replace all simple value tokens with ']' characters. Third, we delete all\n    // open brackets that follow a colon or comma or that begin the text. Finally,\n    // we look to see that the remaining characters are only whitespace or ']' or\n    // ',' or ':' or '{' or '}'. If that is so, then the text is safe for eval.\n\n        if (/^[\\],:{}\\s]*$/\n                .test(text.replace(/\\\\(?:[\"\\\\\\/bfnrt]|u[0-9a-fA-F]{4})/g, '@')\n                    .replace(/\"[^\"\\\\\\n\\r]*\"|true|false|null|-?\\d+(?:\\.\\d*)?(?:[eE][+\\-]?\\d+)?/g, ']')\n                    .replace(/(?:^|:|,)(?:\\s*\\[)+/g, ''))) {\n\n    // In the third stage we use the eval function to compile the text into a\n    // JavaScript structure. The '{' operator is subject to a syntactic ambiguity\n    // in JavaScript: it can begin a block or an object literal. We wrap the text\n    // in parens to eliminate the ambiguity.\n\n            j = eval('(' + text + ')');\n\n    // In the optional fourth stage, we recursively walk the new structure, passing\n    // each name/value pair to a reviver function for possible transformation.\n\n            return typeof reviver === 'function' ?\n                walk({'': j}, '') : j;\n        }\n\n    // If the text is not JSON parseable, then a SyntaxError is thrown.\n\n        throw new SyntaxError('JSON.parse');\n    };\n\n    return JSON;\n  })();\n\n  if ('undefined' != typeof window) {\n    window.expect = module.exports;\n  }\n\n})(\n    this\n  , 'undefined' != typeof module ? module : {exports: {}}\n);\n"
  },
  {
    "path": "app_backend/static/plugin/JavaScript-Templates/test/vendor/mocha.css",
    "content": "@charset \"utf-8\";\n\nbody {\n  margin:0;\n}\n\n#mocha {\n  font: 20px/1.5 \"Helvetica Neue\", Helvetica, Arial, sans-serif;\n  margin: 60px 50px;\n}\n\n#mocha ul,\n#mocha li {\n  margin: 0;\n  padding: 0;\n}\n\n#mocha ul {\n  list-style: none;\n}\n\n#mocha h1,\n#mocha h2 {\n  margin: 0;\n}\n\n#mocha h1 {\n  margin-top: 15px;\n  font-size: 1em;\n  font-weight: 200;\n}\n\n#mocha h1 a {\n  text-decoration: none;\n  color: inherit;\n}\n\n#mocha h1 a:hover {\n  text-decoration: underline;\n}\n\n#mocha .suite .suite h1 {\n  margin-top: 0;\n  font-size: .8em;\n}\n\n#mocha .hidden {\n  display: none;\n}\n\n#mocha h2 {\n  font-size: 12px;\n  font-weight: normal;\n  cursor: pointer;\n}\n\n#mocha .suite {\n  margin-left: 15px;\n}\n\n#mocha .test {\n  margin-left: 15px;\n  overflow: hidden;\n}\n\n#mocha .test.pending:hover h2::after {\n  content: '(pending)';\n  font-family: arial, sans-serif;\n}\n\n#mocha .test.pass.medium .duration {\n  background: #c09853;\n}\n\n#mocha .test.pass.slow .duration {\n  background: #b94a48;\n}\n\n#mocha .test.pass::before {\n  content: '✓';\n  font-size: 12px;\n  display: block;\n  float: left;\n  margin-right: 5px;\n  color: #00d6b2;\n}\n\n#mocha .test.pass .duration {\n  font-size: 9px;\n  margin-left: 5px;\n  padding: 2px 5px;\n  color: #fff;\n  -webkit-box-shadow: inset 0 1px 1px rgba(0,0,0,.2);\n  -moz-box-shadow: inset 0 1px 1px rgba(0,0,0,.2);\n  box-shadow: inset 0 1px 1px rgba(0,0,0,.2);\n  -webkit-border-radius: 5px;\n  -moz-border-radius: 5px;\n  -ms-border-radius: 5px;\n  -o-border-radius: 5px;\n  border-radius: 5px;\n}\n\n#mocha .test.pass.fast .duration {\n  display: none;\n}\n\n#mocha .test.pending {\n  color: #0b97c4;\n}\n\n#mocha .test.pending::before {\n  content: '◦';\n  color: #0b97c4;\n}\n\n#mocha .test.fail {\n  color: #c00;\n}\n\n#mocha .test.fail pre {\n  color: black;\n}\n\n#mocha .test.fail::before {\n  content: '✖';\n  font-size: 12px;\n  display: block;\n  float: left;\n  margin-right: 5px;\n  color: #c00;\n}\n\n#mocha .test pre.error {\n  color: #c00;\n  max-height: 300px;\n  overflow: auto;\n}\n\n#mocha .test .html-error {\n  overflow: auto;\n  color: black;\n  line-height: 1.5;\n  display: block;\n  float: left;\n  clear: left;\n  font: 12px/1.5 monaco, monospace;\n  margin: 5px;\n  padding: 15px;\n  border: 1px solid #eee;\n  max-width: 85%; /*(1)*/\n  max-width: calc(100% - 42px); /*(2)*/\n  max-height: 300px;\n  word-wrap: break-word;\n  border-bottom-color: #ddd;\n  -webkit-border-radius: 3px;\n  -webkit-box-shadow: 0 1px 3px #eee;\n  -moz-border-radius: 3px;\n  -moz-box-shadow: 0 1px 3px #eee;\n  border-radius: 3px;\n}\n\n#mocha .test .html-error pre.error {\n  border: none;\n  -webkit-border-radius: none;\n  -webkit-box-shadow: none;\n  -moz-border-radius: none;\n  -moz-box-shadow: none;\n  padding: 0;\n  margin: 0;\n  margin-top: 18px;\n  max-height: none;\n}\n\n/**\n * (1): approximate for browsers not supporting calc\n * (2): 42 = 2*15 + 2*10 + 2*1 (padding + margin + border)\n *      ^^ seriously\n */\n#mocha .test pre {\n  display: block;\n  float: left;\n  clear: left;\n  font: 12px/1.5 monaco, monospace;\n  margin: 5px;\n  padding: 15px;\n  border: 1px solid #eee;\n  max-width: 85%; /*(1)*/\n  max-width: calc(100% - 42px); /*(2)*/\n  word-wrap: break-word;\n  border-bottom-color: #ddd;\n  -webkit-border-radius: 3px;\n  -webkit-box-shadow: 0 1px 3px #eee;\n  -moz-border-radius: 3px;\n  -moz-box-shadow: 0 1px 3px #eee;\n  border-radius: 3px;\n}\n\n#mocha .test h2 {\n  position: relative;\n}\n\n#mocha .test a.replay {\n  position: absolute;\n  top: 3px;\n  right: 0;\n  text-decoration: none;\n  vertical-align: middle;\n  display: block;\n  width: 15px;\n  height: 15px;\n  line-height: 15px;\n  text-align: center;\n  background: #eee;\n  font-size: 15px;\n  -moz-border-radius: 15px;\n  border-radius: 15px;\n  -webkit-transition: opacity 200ms;\n  -moz-transition: opacity 200ms;\n  transition: opacity 200ms;\n  opacity: 0.3;\n  color: #888;\n}\n\n#mocha .test:hover a.replay {\n  opacity: 1;\n}\n\n#mocha-report.pass .test.fail {\n  display: none;\n}\n\n#mocha-report.fail .test.pass {\n  display: none;\n}\n\n#mocha-report.pending .test.pass,\n#mocha-report.pending .test.fail {\n  display: none;\n}\n#mocha-report.pending .test.pass.pending {\n  display: block;\n}\n\n#mocha-error {\n  color: #c00;\n  font-size: 1.5em;\n  font-weight: 100;\n  letter-spacing: 1px;\n}\n\n#mocha-stats {\n  position: fixed;\n  top: 15px;\n  right: 10px;\n  font-size: 12px;\n  margin: 0;\n  color: #888;\n  z-index: 1;\n}\n\n#mocha-stats .progress {\n  float: right;\n  padding-top: 0;\n}\n\n#mocha-stats em {\n  color: black;\n}\n\n#mocha-stats a {\n  text-decoration: none;\n  color: inherit;\n}\n\n#mocha-stats a:hover {\n  border-bottom: 1px solid #eee;\n}\n\n#mocha-stats li {\n  display: inline-block;\n  margin: 0 5px;\n  list-style: none;\n  padding-top: 11px;\n}\n\n#mocha-stats canvas {\n  width: 40px;\n  height: 40px;\n}\n\n#mocha code .comment { color: #ddd; }\n#mocha code .init { color: #2f6fad; }\n#mocha code .string { color: #5890ad; }\n#mocha code .keyword { color: #8a6343; }\n#mocha code .number { color: #2f6fad; }\n\n@media screen and (max-device-width: 480px) {\n  #mocha {\n    margin: 60px 0px;\n  }\n\n  #mocha #stats {\n    position: absolute;\n  }\n}\n"
  },
  {
    "path": "app_backend/static/plugin/JavaScript-Templates/test/vendor/mocha.js",
    "content": "(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require==\"function\"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error(\"Cannot find module '\"+o+\"'\");throw f.code=\"MODULE_NOT_FOUND\",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require==\"function\"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){\n(function (process){\nmodule.exports = process.env.COV\n  ? require('./lib-cov/mocha')\n  : require('./lib/mocha');\n\n}).call(this,require('_process'))\n},{\"./lib-cov/mocha\":undefined,\"./lib/mocha\":14,\"_process\":51}],2:[function(require,module,exports){\n/* eslint-disable no-unused-vars */\nmodule.exports = function(type) {\n  return function() {};\n};\n\n},{}],3:[function(require,module,exports){\n/**\n * Module exports.\n */\n\nexports.EventEmitter = EventEmitter;\n\n/**\n * Object#hasOwnProperty reference.\n */\nvar objToString = Object.prototype.toString;\n\n/**\n * Check if a value is an array.\n *\n * @api private\n * @param {*} val The value to test.\n * @return {boolean} true if the value is a boolean, otherwise false.\n */\nfunction isArray(val) {\n  return objToString.call(val) === '[object Array]';\n}\n\n/**\n * Event emitter constructor.\n *\n * @api public\n */\nfunction EventEmitter() {}\n\n/**\n * Add a listener.\n *\n * @api public\n * @param {string} name Event name.\n * @param {Function} fn Event handler.\n * @return {EventEmitter} Emitter instance.\n */\nEventEmitter.prototype.on = function(name, fn) {\n  if (!this.$events) {\n    this.$events = {};\n  }\n\n  if (!this.$events[name]) {\n    this.$events[name] = fn;\n  } else if (isArray(this.$events[name])) {\n    this.$events[name].push(fn);\n  } else {\n    this.$events[name] = [this.$events[name], fn];\n  }\n\n  return this;\n};\n\nEventEmitter.prototype.addListener = EventEmitter.prototype.on;\n\n/**\n * Adds a volatile listener.\n *\n * @api public\n * @param {string} name Event name.\n * @param {Function} fn Event handler.\n * @return {EventEmitter} Emitter instance.\n */\nEventEmitter.prototype.once = function(name, fn) {\n  var self = this;\n\n  function on() {\n    self.removeListener(name, on);\n    fn.apply(this, arguments);\n  }\n\n  on.listener = fn;\n  this.on(name, on);\n\n  return this;\n};\n\n/**\n * Remove a listener.\n *\n * @api public\n * @param {string} name Event name.\n * @param {Function} fn Event handler.\n * @return {EventEmitter} Emitter instance.\n */\nEventEmitter.prototype.removeListener = function(name, fn) {\n  if (this.$events && this.$events[name]) {\n    var list = this.$events[name];\n\n    if (isArray(list)) {\n      var pos = -1;\n\n      for (var i = 0, l = list.length; i < l; i++) {\n        if (list[i] === fn || (list[i].listener && list[i].listener === fn)) {\n          pos = i;\n          break;\n        }\n      }\n\n      if (pos < 0) {\n        return this;\n      }\n\n      list.splice(pos, 1);\n\n      if (!list.length) {\n        delete this.$events[name];\n      }\n    } else if (list === fn || (list.listener && list.listener === fn)) {\n      delete this.$events[name];\n    }\n  }\n\n  return this;\n};\n\n/**\n * Remove all listeners for an event.\n *\n * @api public\n * @param {string} name Event name.\n * @return {EventEmitter} Emitter instance.\n */\nEventEmitter.prototype.removeAllListeners = function(name) {\n  if (name === undefined) {\n    this.$events = {};\n    return this;\n  }\n\n  if (this.$events && this.$events[name]) {\n    this.$events[name] = null;\n  }\n\n  return this;\n};\n\n/**\n * Get all listeners for a given event.\n *\n * @api public\n * @param {string} name Event name.\n * @return {EventEmitter} Emitter instance.\n */\nEventEmitter.prototype.listeners = function(name) {\n  if (!this.$events) {\n    this.$events = {};\n  }\n\n  if (!this.$events[name]) {\n    this.$events[name] = [];\n  }\n\n  if (!isArray(this.$events[name])) {\n    this.$events[name] = [this.$events[name]];\n  }\n\n  return this.$events[name];\n};\n\n/**\n * Emit an event.\n *\n * @api public\n * @param {string} name Event name.\n * @return {boolean} true if at least one handler was invoked, else false.\n */\nEventEmitter.prototype.emit = function(name) {\n  if (!this.$events) {\n    return false;\n  }\n\n  var handler = this.$events[name];\n\n  if (!handler) {\n    return false;\n  }\n\n  var args = Array.prototype.slice.call(arguments, 1);\n\n  if (typeof handler === 'function') {\n    handler.apply(this, args);\n  } else if (isArray(handler)) {\n    var listeners = handler.slice();\n\n    for (var i = 0, l = listeners.length; i < l; i++) {\n      listeners[i].apply(this, args);\n    }\n  } else {\n    return false;\n  }\n\n  return true;\n};\n\n},{}],4:[function(require,module,exports){\n/**\n * Expose `Progress`.\n */\n\nmodule.exports = Progress;\n\n/**\n * Initialize a new `Progress` indicator.\n */\nfunction Progress() {\n  this.percent = 0;\n  this.size(0);\n  this.fontSize(11);\n  this.font('helvetica, arial, sans-serif');\n}\n\n/**\n * Set progress size to `size`.\n *\n * @api public\n * @param {number} size\n * @return {Progress} Progress instance.\n */\nProgress.prototype.size = function(size) {\n  this._size = size;\n  return this;\n};\n\n/**\n * Set text to `text`.\n *\n * @api public\n * @param {string} text\n * @return {Progress} Progress instance.\n */\nProgress.prototype.text = function(text) {\n  this._text = text;\n  return this;\n};\n\n/**\n * Set font size to `size`.\n *\n * @api public\n * @param {number} size\n * @return {Progress} Progress instance.\n */\nProgress.prototype.fontSize = function(size) {\n  this._fontSize = size;\n  return this;\n};\n\n/**\n * Set font to `family`.\n *\n * @param {string} family\n * @return {Progress} Progress instance.\n */\nProgress.prototype.font = function(family) {\n  this._font = family;\n  return this;\n};\n\n/**\n * Update percentage to `n`.\n *\n * @param {number} n\n * @return {Progress} Progress instance.\n */\nProgress.prototype.update = function(n) {\n  this.percent = n;\n  return this;\n};\n\n/**\n * Draw on `ctx`.\n *\n * @param {CanvasRenderingContext2d} ctx\n * @return {Progress} Progress instance.\n */\nProgress.prototype.draw = function(ctx) {\n  try {\n    var percent = Math.min(this.percent, 100);\n    var size = this._size;\n    var half = size / 2;\n    var x = half;\n    var y = half;\n    var rad = half - 1;\n    var fontSize = this._fontSize;\n\n    ctx.font = fontSize + 'px ' + this._font;\n\n    var angle = Math.PI * 2 * (percent / 100);\n    ctx.clearRect(0, 0, size, size);\n\n    // outer circle\n    ctx.strokeStyle = '#9f9f9f';\n    ctx.beginPath();\n    ctx.arc(x, y, rad, 0, angle, false);\n    ctx.stroke();\n\n    // inner circle\n    ctx.strokeStyle = '#eee';\n    ctx.beginPath();\n    ctx.arc(x, y, rad - 1, 0, angle, true);\n    ctx.stroke();\n\n    // text\n    var text = this._text || (percent | 0) + '%';\n    var w = ctx.measureText(text).width;\n\n    ctx.fillText(text, x - w / 2 + 1, y + fontSize / 2 - 1);\n  } catch (err) {\n    // don't fail if we can't render progress\n  }\n  return this;\n};\n\n},{}],5:[function(require,module,exports){\n(function (global){\nexports.isatty = function isatty() {\n  return true;\n};\n\nexports.getWindowSize = function getWindowSize() {\n  if ('innerHeight' in global) {\n    return [global.innerHeight, global.innerWidth];\n  }\n  // In a Web Worker, the DOM Window is not available.\n  return [640, 480];\n};\n\n}).call(this,typeof global !== \"undefined\" ? global : typeof self !== \"undefined\" ? self : typeof window !== \"undefined\" ? window : {})\n},{}],6:[function(require,module,exports){\n/**\n * Expose `Context`.\n */\n\nmodule.exports = Context;\n\n/**\n * Initialize a new `Context`.\n *\n * @api private\n */\nfunction Context() {}\n\n/**\n * Set or get the context `Runnable` to `runnable`.\n *\n * @api private\n * @param {Runnable} runnable\n * @return {Context}\n */\nContext.prototype.runnable = function(runnable) {\n  if (!arguments.length) {\n    return this._runnable;\n  }\n  this.test = this._runnable = runnable;\n  return this;\n};\n\n/**\n * Set test timeout `ms`.\n *\n * @api private\n * @param {number} ms\n * @return {Context} self\n */\nContext.prototype.timeout = function(ms) {\n  if (!arguments.length) {\n    return this.runnable().timeout();\n  }\n  this.runnable().timeout(ms);\n  return this;\n};\n\n/**\n * Set test timeout `enabled`.\n *\n * @api private\n * @param {boolean} enabled\n * @return {Context} self\n */\nContext.prototype.enableTimeouts = function(enabled) {\n  this.runnable().enableTimeouts(enabled);\n  return this;\n};\n\n/**\n * Set test slowness threshold `ms`.\n *\n * @api private\n * @param {number} ms\n * @return {Context} self\n */\nContext.prototype.slow = function(ms) {\n  this.runnable().slow(ms);\n  return this;\n};\n\n/**\n * Mark a test as skipped.\n *\n * @api private\n * @return {Context} self\n */\nContext.prototype.skip = function() {\n  this.runnable().skip();\n  return this;\n};\n\n/**\n * Inspect the context void of `._runnable`.\n *\n * @api private\n * @return {string}\n */\nContext.prototype.inspect = function() {\n  return JSON.stringify(this, function(key, val) {\n    return key === 'runnable' || key === 'test' ? undefined : val;\n  }, 2);\n};\n\n},{}],7:[function(require,module,exports){\n/**\n * Module dependencies.\n */\n\nvar Runnable = require('./runnable');\nvar inherits = require('./utils').inherits;\n\n/**\n * Expose `Hook`.\n */\n\nmodule.exports = Hook;\n\n/**\n * Initialize a new `Hook` with the given `title` and callback `fn`.\n *\n * @param {String} title\n * @param {Function} fn\n * @api private\n */\nfunction Hook(title, fn) {\n  Runnable.call(this, title, fn);\n  this.type = 'hook';\n}\n\n/**\n * Inherit from `Runnable.prototype`.\n */\ninherits(Hook, Runnable);\n\n/**\n * Get or set the test `err`.\n *\n * @param {Error} err\n * @return {Error}\n * @api public\n */\nHook.prototype.error = function(err) {\n  if (!arguments.length) {\n    err = this._error;\n    this._error = null;\n    return err;\n  }\n\n  this._error = err;\n};\n\n},{\"./runnable\":35,\"./utils\":39}],8:[function(require,module,exports){\n/**\n * Module dependencies.\n */\n\nvar Suite = require('../suite');\nvar Test = require('../test');\nvar escapeRe = require('escape-string-regexp');\n\n/**\n * BDD-style interface:\n *\n *      describe('Array', function() {\n *        describe('#indexOf()', function() {\n *          it('should return -1 when not present', function() {\n *            // ...\n *          });\n *\n *          it('should return the index when present', function() {\n *            // ...\n *          });\n *        });\n *      });\n *\n * @param {Suite} suite Root suite.\n */\nmodule.exports = function(suite) {\n  var suites = [suite];\n\n  suite.on('pre-require', function(context, file, mocha) {\n    var common = require('./common')(suites, context);\n\n    context.before = common.before;\n    context.after = common.after;\n    context.beforeEach = common.beforeEach;\n    context.afterEach = common.afterEach;\n    context.run = mocha.options.delay && common.runWithSuite(suite);\n    /**\n     * Describe a \"suite\" with the given `title`\n     * and callback `fn` containing nested suites\n     * and/or tests.\n     */\n\n    context.describe = context.context = function(title, fn) {\n      var suite = Suite.create(suites[0], title);\n      suite.file = file;\n      suites.unshift(suite);\n      fn.call(suite);\n      suites.shift();\n      return suite;\n    };\n\n    /**\n     * Pending describe.\n     */\n\n    context.xdescribe = context.xcontext = context.describe.skip = function(title, fn) {\n      var suite = Suite.create(suites[0], title);\n      suite.pending = true;\n      suites.unshift(suite);\n      fn.call(suite);\n      suites.shift();\n    };\n\n    /**\n     * Exclusive suite.\n     */\n\n    context.describe.only = function(title, fn) {\n      var suite = context.describe(title, fn);\n      mocha.grep(suite.fullTitle());\n      return suite;\n    };\n\n    /**\n     * Describe a specification or test-case\n     * with the given `title` and callback `fn`\n     * acting as a thunk.\n     */\n\n    context.it = context.specify = function(title, fn) {\n      var suite = suites[0];\n      if (suite.pending) {\n        fn = null;\n      }\n      var test = new Test(title, fn);\n      test.file = file;\n      suite.addTest(test);\n      return test;\n    };\n\n    /**\n     * Exclusive test-case.\n     */\n\n    context.it.only = function(title, fn) {\n      var test = context.it(title, fn);\n      var reString = '^' + escapeRe(test.fullTitle()) + '$';\n      mocha.grep(new RegExp(reString));\n      return test;\n    };\n\n    /**\n     * Pending test case.\n     */\n\n    context.xit = context.xspecify = context.it.skip = function(title) {\n      context.it(title);\n    };\n  });\n};\n\n},{\"../suite\":37,\"../test\":38,\"./common\":9,\"escape-string-regexp\":68}],9:[function(require,module,exports){\n'use strict';\n\n/**\n * Functions common to more than one interface.\n *\n * @param {Suite[]} suites\n * @param {Context} context\n * @return {Object} An object containing common functions.\n */\nmodule.exports = function(suites, context) {\n  return {\n    /**\n     * This is only present if flag --delay is passed into Mocha. It triggers\n     * root suite execution.\n     *\n     * @param {Suite} suite The root wuite.\n     * @return {Function} A function which runs the root suite\n     */\n    runWithSuite: function runWithSuite(suite) {\n      return function run() {\n        suite.run();\n      };\n    },\n\n    /**\n     * Execute before running tests.\n     *\n     * @param {string} name\n     * @param {Function} fn\n     */\n    before: function(name, fn) {\n      suites[0].beforeAll(name, fn);\n    },\n\n    /**\n     * Execute after running tests.\n     *\n     * @param {string} name\n     * @param {Function} fn\n     */\n    after: function(name, fn) {\n      suites[0].afterAll(name, fn);\n    },\n\n    /**\n     * Execute before each test case.\n     *\n     * @param {string} name\n     * @param {Function} fn\n     */\n    beforeEach: function(name, fn) {\n      suites[0].beforeEach(name, fn);\n    },\n\n    /**\n     * Execute after each test case.\n     *\n     * @param {string} name\n     * @param {Function} fn\n     */\n    afterEach: function(name, fn) {\n      suites[0].afterEach(name, fn);\n    },\n\n    test: {\n      /**\n       * Pending test case.\n       *\n       * @param {string} title\n       */\n      skip: function(title) {\n        context.test(title);\n      }\n    }\n  };\n};\n\n},{}],10:[function(require,module,exports){\n/**\n * Module dependencies.\n */\n\nvar Suite = require('../suite');\nvar Test = require('../test');\n\n/**\n * TDD-style interface:\n *\n *     exports.Array = {\n *       '#indexOf()': {\n *         'should return -1 when the value is not present': function() {\n *\n *         },\n *\n *         'should return the correct index when the value is present': function() {\n *\n *         }\n *       }\n *     };\n *\n * @param {Suite} suite Root suite.\n */\nmodule.exports = function(suite) {\n  var suites = [suite];\n\n  suite.on('require', visit);\n\n  function visit(obj, file) {\n    var suite;\n    for (var key in obj) {\n      if (typeof obj[key] === 'function') {\n        var fn = obj[key];\n        switch (key) {\n          case 'before':\n            suites[0].beforeAll(fn);\n            break;\n          case 'after':\n            suites[0].afterAll(fn);\n            break;\n          case 'beforeEach':\n            suites[0].beforeEach(fn);\n            break;\n          case 'afterEach':\n            suites[0].afterEach(fn);\n            break;\n          default:\n            var test = new Test(key, fn);\n            test.file = file;\n            suites[0].addTest(test);\n        }\n      } else {\n        suite = Suite.create(suites[0], key);\n        suites.unshift(suite);\n        visit(obj[key]);\n        suites.shift();\n      }\n    }\n  }\n};\n\n},{\"../suite\":37,\"../test\":38}],11:[function(require,module,exports){\nexports.bdd = require('./bdd');\nexports.tdd = require('./tdd');\nexports.qunit = require('./qunit');\nexports.exports = require('./exports');\n\n},{\"./bdd\":8,\"./exports\":10,\"./qunit\":12,\"./tdd\":13}],12:[function(require,module,exports){\n/**\n * Module dependencies.\n */\n\nvar Suite = require('../suite');\nvar Test = require('../test');\nvar escapeRe = require('escape-string-regexp');\n\n/**\n * QUnit-style interface:\n *\n *     suite('Array');\n *\n *     test('#length', function() {\n *       var arr = [1,2,3];\n *       ok(arr.length == 3);\n *     });\n *\n *     test('#indexOf()', function() {\n *       var arr = [1,2,3];\n *       ok(arr.indexOf(1) == 0);\n *       ok(arr.indexOf(2) == 1);\n *       ok(arr.indexOf(3) == 2);\n *     });\n *\n *     suite('String');\n *\n *     test('#length', function() {\n *       ok('foo'.length == 3);\n *     });\n *\n * @param {Suite} suite Root suite.\n */\nmodule.exports = function(suite) {\n  var suites = [suite];\n\n  suite.on('pre-require', function(context, file, mocha) {\n    var common = require('./common')(suites, context);\n\n    context.before = common.before;\n    context.after = common.after;\n    context.beforeEach = common.beforeEach;\n    context.afterEach = common.afterEach;\n    context.run = mocha.options.delay && common.runWithSuite(suite);\n    /**\n     * Describe a \"suite\" with the given `title`.\n     */\n\n    context.suite = function(title) {\n      if (suites.length > 1) {\n        suites.shift();\n      }\n      var suite = Suite.create(suites[0], title);\n      suite.file = file;\n      suites.unshift(suite);\n      return suite;\n    };\n\n    /**\n     * Exclusive test-case.\n     */\n\n    context.suite.only = function(title, fn) {\n      var suite = context.suite(title, fn);\n      mocha.grep(suite.fullTitle());\n    };\n\n    /**\n     * Describe a specification or test-case\n     * with the given `title` and callback `fn`\n     * acting as a thunk.\n     */\n\n    context.test = function(title, fn) {\n      var test = new Test(title, fn);\n      test.file = file;\n      suites[0].addTest(test);\n      return test;\n    };\n\n    /**\n     * Exclusive test-case.\n     */\n\n    context.test.only = function(title, fn) {\n      var test = context.test(title, fn);\n      var reString = '^' + escapeRe(test.fullTitle()) + '$';\n      mocha.grep(new RegExp(reString));\n    };\n\n    context.test.skip = common.test.skip;\n  });\n};\n\n},{\"../suite\":37,\"../test\":38,\"./common\":9,\"escape-string-regexp\":68}],13:[function(require,module,exports){\n/**\n * Module dependencies.\n */\n\nvar Suite = require('../suite');\nvar Test = require('../test');\nvar escapeRe = require('escape-string-regexp');\n\n/**\n * TDD-style interface:\n *\n *      suite('Array', function() {\n *        suite('#indexOf()', function() {\n *          suiteSetup(function() {\n *\n *          });\n *\n *          test('should return -1 when not present', function() {\n *\n *          });\n *\n *          test('should return the index when present', function() {\n *\n *          });\n *\n *          suiteTeardown(function() {\n *\n *          });\n *        });\n *      });\n *\n * @param {Suite} suite Root suite.\n */\nmodule.exports = function(suite) {\n  var suites = [suite];\n\n  suite.on('pre-require', function(context, file, mocha) {\n    var common = require('./common')(suites, context);\n\n    context.setup = common.beforeEach;\n    context.teardown = common.afterEach;\n    context.suiteSetup = common.before;\n    context.suiteTeardown = common.after;\n    context.run = mocha.options.delay && common.runWithSuite(suite);\n\n    /**\n     * Describe a \"suite\" with the given `title` and callback `fn` containing\n     * nested suites and/or tests.\n     */\n    context.suite = function(title, fn) {\n      var suite = Suite.create(suites[0], title);\n      suite.file = file;\n      suites.unshift(suite);\n      fn.call(suite);\n      suites.shift();\n      return suite;\n    };\n\n    /**\n     * Pending suite.\n     */\n    context.suite.skip = function(title, fn) {\n      var suite = Suite.create(suites[0], title);\n      suite.pending = true;\n      suites.unshift(suite);\n      fn.call(suite);\n      suites.shift();\n    };\n\n    /**\n     * Exclusive test-case.\n     */\n    context.suite.only = function(title, fn) {\n      var suite = context.suite(title, fn);\n      mocha.grep(suite.fullTitle());\n    };\n\n    /**\n     * Describe a specification or test-case with the given `title` and\n     * callback `fn` acting as a thunk.\n     */\n    context.test = function(title, fn) {\n      var suite = suites[0];\n      if (suite.pending) {\n        fn = null;\n      }\n      var test = new Test(title, fn);\n      test.file = file;\n      suite.addTest(test);\n      return test;\n    };\n\n    /**\n     * Exclusive test-case.\n     */\n\n    context.test.only = function(title, fn) {\n      var test = context.test(title, fn);\n      var reString = '^' + escapeRe(test.fullTitle()) + '$';\n      mocha.grep(new RegExp(reString));\n    };\n\n    context.test.skip = common.test.skip;\n  });\n};\n\n},{\"../suite\":37,\"../test\":38,\"./common\":9,\"escape-string-regexp\":68}],14:[function(require,module,exports){\n(function (process,global,__dirname){\n/*!\n * mocha\n * Copyright(c) 2011 TJ Holowaychuk <tj@vision-media.ca>\n * MIT Licensed\n */\n\n/**\n * Module dependencies.\n */\n\nvar escapeRe = require('escape-string-regexp');\nvar path = require('path');\nvar reporters = require('./reporters');\nvar utils = require('./utils');\n\n/**\n * Expose `Mocha`.\n */\n\nexports = module.exports = Mocha;\n\n/**\n * To require local UIs and reporters when running in node.\n */\n\nif (!process.browser) {\n  var cwd = process.cwd();\n  module.paths.push(cwd, path.join(cwd, 'node_modules'));\n}\n\n/**\n * Expose internals.\n */\n\nexports.utils = utils;\nexports.interfaces = require('./interfaces');\nexports.reporters = reporters;\nexports.Runnable = require('./runnable');\nexports.Context = require('./context');\nexports.Runner = require('./runner');\nexports.Suite = require('./suite');\nexports.Hook = require('./hook');\nexports.Test = require('./test');\n\n/**\n * Return image `name` path.\n *\n * @api private\n * @param {string} name\n * @return {string}\n */\nfunction image(name) {\n  return path.join(__dirname, '../images', name + '.png');\n}\n\n/**\n * Set up mocha with `options`.\n *\n * Options:\n *\n *   - `ui` name \"bdd\", \"tdd\", \"exports\" etc\n *   - `reporter` reporter instance, defaults to `mocha.reporters.spec`\n *   - `globals` array of accepted globals\n *   - `timeout` timeout in milliseconds\n *   - `bail` bail on the first test failure\n *   - `slow` milliseconds to wait before considering a test slow\n *   - `ignoreLeaks` ignore global leaks\n *   - `fullTrace` display the full stack-trace on failing\n *   - `grep` string or regexp to filter tests with\n *\n * @param {Object} options\n * @api public\n */\nfunction Mocha(options) {\n  options = options || {};\n  this.files = [];\n  this.options = options;\n  if (options.grep) {\n    this.grep(new RegExp(options.grep));\n  }\n  if (options.fgrep) {\n    this.grep(options.fgrep);\n  }\n  this.suite = new exports.Suite('', new exports.Context());\n  this.ui(options.ui);\n  this.bail(options.bail);\n  this.reporter(options.reporter, options.reporterOptions);\n  if (typeof options.timeout !== 'undefined' && options.timeout !== null) {\n    this.timeout(options.timeout);\n  }\n  this.useColors(options.useColors);\n  if (options.enableTimeouts !== null) {\n    this.enableTimeouts(options.enableTimeouts);\n  }\n  if (options.slow) {\n    this.slow(options.slow);\n  }\n\n  this.suite.on('pre-require', function(context) {\n    exports.afterEach = context.afterEach || context.teardown;\n    exports.after = context.after || context.suiteTeardown;\n    exports.beforeEach = context.beforeEach || context.setup;\n    exports.before = context.before || context.suiteSetup;\n    exports.describe = context.describe || context.suite;\n    exports.it = context.it || context.test;\n    exports.setup = context.setup || context.beforeEach;\n    exports.suiteSetup = context.suiteSetup || context.before;\n    exports.suiteTeardown = context.suiteTeardown || context.after;\n    exports.suite = context.suite || context.describe;\n    exports.teardown = context.teardown || context.afterEach;\n    exports.test = context.test || context.it;\n    exports.run = context.run;\n  });\n}\n\n/**\n * Enable or disable bailing on the first failure.\n *\n * @api public\n * @param {boolean} [bail]\n */\nMocha.prototype.bail = function(bail) {\n  if (!arguments.length) {\n    bail = true;\n  }\n  this.suite.bail(bail);\n  return this;\n};\n\n/**\n * Add test `file`.\n *\n * @api public\n * @param {string} file\n */\nMocha.prototype.addFile = function(file) {\n  this.files.push(file);\n  return this;\n};\n\n/**\n * Set reporter to `reporter`, defaults to \"spec\".\n *\n * @param {String|Function} reporter name or constructor\n * @param {Object} reporterOptions optional options\n * @api public\n * @param {string|Function} reporter name or constructor\n * @param {Object} reporterOptions optional options\n */\nMocha.prototype.reporter = function(reporter, reporterOptions) {\n  if (typeof reporter === 'function') {\n    this._reporter = reporter;\n  } else {\n    reporter = reporter || 'spec';\n    var _reporter;\n    // Try to load a built-in reporter.\n    if (reporters[reporter]) {\n      _reporter = reporters[reporter];\n    }\n    // Try to load reporters from process.cwd() and node_modules\n    if (!_reporter) {\n      try {\n        _reporter = require(reporter);\n      } catch (err) {\n        err.message.indexOf('Cannot find module') !== -1\n          ? console.warn('\"' + reporter + '\" reporter not found')\n          : console.warn('\"' + reporter + '\" reporter blew up with error:\\n' + err.stack);\n      }\n    }\n    if (!_reporter && reporter === 'teamcity') {\n      console.warn('The Teamcity reporter was moved to a package named '\n        + 'mocha-teamcity-reporter '\n        + '(https://npmjs.org/package/mocha-teamcity-reporter).');\n    }\n    if (!_reporter) {\n      throw new Error('invalid reporter \"' + reporter + '\"');\n    }\n    this._reporter = _reporter;\n  }\n  this.options.reporterOptions = reporterOptions;\n  return this;\n};\n\n/**\n * Set test UI `name`, defaults to \"bdd\".\n *\n * @api public\n * @param {string} bdd\n */\nMocha.prototype.ui = function(name) {\n  name = name || 'bdd';\n  this._ui = exports.interfaces[name];\n  if (!this._ui) {\n    try {\n      this._ui = require(name);\n    } catch (err) {\n      throw new Error('invalid interface \"' + name + '\"');\n    }\n  }\n  this._ui = this._ui(this.suite);\n  return this;\n};\n\n/**\n * Load registered files.\n *\n * @api private\n */\nMocha.prototype.loadFiles = function(fn) {\n  var self = this;\n  var suite = this.suite;\n  var pending = this.files.length;\n  this.files.forEach(function(file) {\n    file = path.resolve(file);\n    suite.emit('pre-require', global, file, self);\n    suite.emit('require', require(file), file, self);\n    suite.emit('post-require', global, file, self);\n    --pending || (fn && fn());\n  });\n};\n\n/**\n * Enable growl support.\n *\n * @api private\n */\nMocha.prototype._growl = function(runner, reporter) {\n  var notify = require('growl');\n\n  runner.on('end', function() {\n    var stats = reporter.stats;\n    if (stats.failures) {\n      var msg = stats.failures + ' of ' + runner.total + ' tests failed';\n      notify(msg, { name: 'mocha', title: 'Failed', image: image('error') });\n    } else {\n      notify(stats.passes + ' tests passed in ' + stats.duration + 'ms', {\n        name: 'mocha',\n        title: 'Passed',\n        image: image('ok')\n      });\n    }\n  });\n};\n\n/**\n * Add regexp to grep, if `re` is a string it is escaped.\n *\n * @param {RegExp|String} re\n * @return {Mocha}\n * @api public\n * @param {RegExp|string} re\n * @return {Mocha}\n */\nMocha.prototype.grep = function(re) {\n  this.options.grep = typeof re === 'string' ? new RegExp(escapeRe(re)) : re;\n  return this;\n};\n\n/**\n * Invert `.grep()` matches.\n *\n * @return {Mocha}\n * @api public\n */\nMocha.prototype.invert = function() {\n  this.options.invert = true;\n  return this;\n};\n\n/**\n * Ignore global leaks.\n *\n * @param {Boolean} ignore\n * @return {Mocha}\n * @api public\n * @param {boolean} ignore\n * @return {Mocha}\n */\nMocha.prototype.ignoreLeaks = function(ignore) {\n  this.options.ignoreLeaks = Boolean(ignore);\n  return this;\n};\n\n/**\n * Enable global leak checking.\n *\n * @return {Mocha}\n * @api public\n */\nMocha.prototype.checkLeaks = function() {\n  this.options.ignoreLeaks = false;\n  return this;\n};\n\n/**\n * Display long stack-trace on failing\n *\n * @return {Mocha}\n * @api public\n */\nMocha.prototype.fullTrace = function() {\n  this.options.fullStackTrace = true;\n  return this;\n};\n\n/**\n * Enable growl support.\n *\n * @return {Mocha}\n * @api public\n */\nMocha.prototype.growl = function() {\n  this.options.growl = true;\n  return this;\n};\n\n/**\n * Ignore `globals` array or string.\n *\n * @param {Array|String} globals\n * @return {Mocha}\n * @api public\n * @param {Array|string} globals\n * @return {Mocha}\n */\nMocha.prototype.globals = function(globals) {\n  this.options.globals = (this.options.globals || []).concat(globals);\n  return this;\n};\n\n/**\n * Emit color output.\n *\n * @param {Boolean} colors\n * @return {Mocha}\n * @api public\n * @param {boolean} colors\n * @return {Mocha}\n */\nMocha.prototype.useColors = function(colors) {\n  if (colors !== undefined) {\n    this.options.useColors = colors;\n  }\n  return this;\n};\n\n/**\n * Use inline diffs rather than +/-.\n *\n * @param {Boolean} inlineDiffs\n * @return {Mocha}\n * @api public\n * @param {boolean} inlineDiffs\n * @return {Mocha}\n */\nMocha.prototype.useInlineDiffs = function(inlineDiffs) {\n  this.options.useInlineDiffs = inlineDiffs !== undefined && inlineDiffs;\n  return this;\n};\n\n/**\n * Set the timeout in milliseconds.\n *\n * @param {Number} timeout\n * @return {Mocha}\n * @api public\n * @param {number} timeout\n * @return {Mocha}\n */\nMocha.prototype.timeout = function(timeout) {\n  this.suite.timeout(timeout);\n  return this;\n};\n\n/**\n * Set slowness threshold in milliseconds.\n *\n * @param {Number} slow\n * @return {Mocha}\n * @api public\n * @param {number} slow\n * @return {Mocha}\n */\nMocha.prototype.slow = function(slow) {\n  this.suite.slow(slow);\n  return this;\n};\n\n/**\n * Enable timeouts.\n *\n * @param {Boolean} enabled\n * @return {Mocha}\n * @api public\n * @param {boolean} enabled\n * @return {Mocha}\n */\nMocha.prototype.enableTimeouts = function(enabled) {\n  this.suite.enableTimeouts(arguments.length && enabled !== undefined ? enabled : true);\n  return this;\n};\n\n/**\n * Makes all tests async (accepting a callback)\n *\n * @return {Mocha}\n * @api public\n */\nMocha.prototype.asyncOnly = function() {\n  this.options.asyncOnly = true;\n  return this;\n};\n\n/**\n * Disable syntax highlighting (in browser).\n *\n * @api public\n */\nMocha.prototype.noHighlighting = function() {\n  this.options.noHighlighting = true;\n  return this;\n};\n\n/**\n * Enable uncaught errors to propagate (in browser).\n *\n * @return {Mocha}\n * @api public\n */\nMocha.prototype.allowUncaught = function() {\n  this.options.allowUncaught = true;\n  return this;\n};\n\n/**\n * Delay root suite execution.\n * @returns {Mocha}\n */\nMocha.prototype.delay = function delay() {\n  this.options.delay = true;\n  return this;\n};\n\n/**\n * Run tests and invoke `fn()` when complete.\n *\n * @api public\n * @param {Function} fn\n * @return {Runner}\n */\nMocha.prototype.run = function(fn) {\n  if (this.files.length) {\n    this.loadFiles();\n  }\n  var suite = this.suite;\n  var options = this.options;\n  options.files = this.files;\n  var runner = new exports.Runner(suite, options.delay);\n  var reporter = new this._reporter(runner, options);\n  runner.ignoreLeaks = options.ignoreLeaks !== false;\n  runner.fullStackTrace = options.fullStackTrace;\n  runner.asyncOnly = options.asyncOnly;\n  runner.allowUncaught = options.allowUncaught;\n  if (options.grep) {\n    runner.grep(options.grep, options.invert);\n  }\n  if (options.globals) {\n    runner.globals(options.globals);\n  }\n  if (options.growl) {\n    this._growl(runner, reporter);\n  }\n  if (options.useColors !== undefined) {\n    exports.reporters.Base.useColors = options.useColors;\n  }\n  exports.reporters.Base.inlineDiffs = options.useInlineDiffs;\n\n  function done(failures) {\n    if (reporter.done) {\n      reporter.done(failures, fn);\n    } else {\n      fn && fn(failures);\n    }\n  }\n\n  return runner.run(done);\n};\n\n}).call(this,require('_process'),typeof global !== \"undefined\" ? global : typeof self !== \"undefined\" ? self : typeof window !== \"undefined\" ? window : {},\"/lib\")\n},{\"./context\":6,\"./hook\":7,\"./interfaces\":11,\"./reporters\":22,\"./runnable\":35,\"./runner\":36,\"./suite\":37,\"./test\":38,\"./utils\":39,\"_process\":51,\"escape-string-regexp\":68,\"growl\":69,\"path\":41}],15:[function(require,module,exports){\n/**\n * Helpers.\n */\n\nvar s = 1000;\nvar m = s * 60;\nvar h = m * 60;\nvar d = h * 24;\nvar y = d * 365.25;\n\n/**\n * Parse or format the given `val`.\n *\n * Options:\n *\n *  - `long` verbose formatting [false]\n *\n * @api public\n * @param {string|number} val\n * @param {Object} options\n * @return {string|number}\n */\nmodule.exports = function(val, options) {\n  options = options || {};\n  if (typeof val === 'string') {\n    return parse(val);\n  }\n  // https://github.com/mochajs/mocha/pull/1035\n  return options['long'] ? longFormat(val) : shortFormat(val);\n};\n\n/**\n * Parse the given `str` and return milliseconds.\n *\n * @api private\n * @param {string} str\n * @return {number}\n */\nfunction parse(str) {\n  var match = (/^((?:\\d+)?\\.?\\d+) *(ms|seconds?|s|minutes?|m|hours?|h|days?|d|years?|y)?$/i).exec(str);\n  if (!match) {\n    return;\n  }\n  var n = parseFloat(match[1]);\n  var type = (match[2] || 'ms').toLowerCase();\n  switch (type) {\n    case 'years':\n    case 'year':\n    case 'y':\n      return n * y;\n    case 'days':\n    case 'day':\n    case 'd':\n      return n * d;\n    case 'hours':\n    case 'hour':\n    case 'h':\n      return n * h;\n    case 'minutes':\n    case 'minute':\n    case 'm':\n      return n * m;\n    case 'seconds':\n    case 'second':\n    case 's':\n      return n * s;\n    case 'ms':\n      return n;\n    default:\n      // No default case\n  }\n}\n\n/**\n * Short format for `ms`.\n *\n * @api private\n * @param {number} ms\n * @return {string}\n */\nfunction shortFormat(ms) {\n  if (ms >= d) {\n    return Math.round(ms / d) + 'd';\n  }\n  if (ms >= h) {\n    return Math.round(ms / h) + 'h';\n  }\n  if (ms >= m) {\n    return Math.round(ms / m) + 'm';\n  }\n  if (ms >= s) {\n    return Math.round(ms / s) + 's';\n  }\n  return ms + 'ms';\n}\n\n/**\n * Long format for `ms`.\n *\n * @api private\n * @param {number} ms\n * @return {string}\n */\nfunction longFormat(ms) {\n  return plural(ms, d, 'day')\n    || plural(ms, h, 'hour')\n    || plural(ms, m, 'minute')\n    || plural(ms, s, 'second')\n    || ms + ' ms';\n}\n\n/**\n * Pluralization helper.\n *\n * @api private\n * @param {number} ms\n * @param {number} n\n * @param {string} name\n */\nfunction plural(ms, n, name) {\n  if (ms < n) {\n    return;\n  }\n  if (ms < n * 1.5) {\n    return Math.floor(ms / n) + ' ' + name;\n  }\n  return Math.ceil(ms / n) + ' ' + name + 's';\n}\n\n},{}],16:[function(require,module,exports){\n\n/**\n * Expose `Pending`.\n */\n\nmodule.exports = Pending;\n\n/**\n * Initialize a new `Pending` error with the given message.\n *\n * @param {string} message\n */\nfunction Pending(message) {\n  this.message = message;\n}\n\n},{}],17:[function(require,module,exports){\n(function (process,global){\n/**\n * Module dependencies.\n */\n\nvar tty = require('tty');\nvar diff = require('diff');\nvar ms = require('../ms');\nvar utils = require('../utils');\nvar supportsColor = process.browser ? null : require('supports-color');\n\n/**\n * Expose `Base`.\n */\n\nexports = module.exports = Base;\n\n/**\n * Save timer references to avoid Sinon interfering.\n * See: https://github.com/mochajs/mocha/issues/237\n */\n\n/* eslint-disable no-unused-vars, no-native-reassign */\nvar Date = global.Date;\nvar setTimeout = global.setTimeout;\nvar setInterval = global.setInterval;\nvar clearTimeout = global.clearTimeout;\nvar clearInterval = global.clearInterval;\n/* eslint-enable no-unused-vars, no-native-reassign */\n\n/**\n * Check if both stdio streams are associated with a tty.\n */\n\nvar isatty = tty.isatty(1) && tty.isatty(2);\n\n/**\n * Enable coloring by default, except in the browser interface.\n */\n\nexports.useColors = !process.browser && (supportsColor || (process.env.MOCHA_COLORS !== undefined));\n\n/**\n * Inline diffs instead of +/-\n */\n\nexports.inlineDiffs = false;\n\n/**\n * Default color map.\n */\n\nexports.colors = {\n  pass: 90,\n  fail: 31,\n  'bright pass': 92,\n  'bright fail': 91,\n  'bright yellow': 93,\n  pending: 36,\n  suite: 0,\n  'error title': 0,\n  'error message': 31,\n  'error stack': 90,\n  checkmark: 32,\n  fast: 90,\n  medium: 33,\n  slow: 31,\n  green: 32,\n  light: 90,\n  'diff gutter': 90,\n  'diff added': 32,\n  'diff removed': 31\n};\n\n/**\n * Default symbol map.\n */\n\nexports.symbols = {\n  ok: '✓',\n  err: '✖',\n  dot: '․'\n};\n\n// With node.js on Windows: use symbols available in terminal default fonts\nif (process.platform === 'win32') {\n  exports.symbols.ok = '\\u221A';\n  exports.symbols.err = '\\u00D7';\n  exports.symbols.dot = '.';\n}\n\n/**\n * Color `str` with the given `type`,\n * allowing colors to be disabled,\n * as well as user-defined color\n * schemes.\n *\n * @param {string} type\n * @param {string} str\n * @return {string}\n * @api private\n */\nvar color = exports.color = function(type, str) {\n  if (!exports.useColors) {\n    return String(str);\n  }\n  return '\\u001b[' + exports.colors[type] + 'm' + str + '\\u001b[0m';\n};\n\n/**\n * Expose term window size, with some defaults for when stderr is not a tty.\n */\n\nexports.window = {\n  width: 75\n};\n\nif (isatty) {\n  exports.window.width = process.stdout.getWindowSize\n      ? process.stdout.getWindowSize(1)[0]\n      : tty.getWindowSize()[1];\n}\n\n/**\n * Expose some basic cursor interactions that are common among reporters.\n */\n\nexports.cursor = {\n  hide: function() {\n    isatty && process.stdout.write('\\u001b[?25l');\n  },\n\n  show: function() {\n    isatty && process.stdout.write('\\u001b[?25h');\n  },\n\n  deleteLine: function() {\n    isatty && process.stdout.write('\\u001b[2K');\n  },\n\n  beginningOfLine: function() {\n    isatty && process.stdout.write('\\u001b[0G');\n  },\n\n  CR: function() {\n    if (isatty) {\n      exports.cursor.deleteLine();\n      exports.cursor.beginningOfLine();\n    } else {\n      process.stdout.write('\\r');\n    }\n  }\n};\n\n/**\n * Outut the given `failures` as a list.\n *\n * @param {Array} failures\n * @api public\n */\n\nexports.list = function(failures) {\n  console.log();\n  failures.forEach(function(test, i) {\n    // format\n    var fmt = color('error title', '  %s) %s:\\n')\n      + color('error message', '     %s')\n      + color('error stack', '\\n%s\\n');\n\n    // msg\n    var msg;\n    var err = test.err;\n    var message;\n    if (err.message) {\n      message = err.message;\n    } else if (typeof err.inspect === 'function') {\n      message = err.inspect() + '';\n    } else {\n      message = '';\n    }\n    var stack = err.stack || message;\n    var index = stack.indexOf(message);\n    var actual = err.actual;\n    var expected = err.expected;\n    var escape = true;\n\n    if (index === -1) {\n      msg = message;\n    } else {\n      index += message.length;\n      msg = stack.slice(0, index);\n      // remove msg from stack\n      stack = stack.slice(index + 1);\n    }\n\n    // uncaught\n    if (err.uncaught) {\n      msg = 'Uncaught ' + msg;\n    }\n    // explicitly show diff\n    if (err.showDiff !== false && sameType(actual, expected) && expected !== undefined) {\n      escape = false;\n      if (!(utils.isString(actual) && utils.isString(expected))) {\n        err.actual = actual = utils.stringify(actual);\n        err.expected = expected = utils.stringify(expected);\n      }\n\n      fmt = color('error title', '  %s) %s:\\n%s') + color('error stack', '\\n%s\\n');\n      var match = message.match(/^([^:]+): expected/);\n      msg = '\\n      ' + color('error message', match ? match[1] : msg);\n\n      if (exports.inlineDiffs) {\n        msg += inlineDiff(err, escape);\n      } else {\n        msg += unifiedDiff(err, escape);\n      }\n    }\n\n    // indent stack trace\n    stack = stack.replace(/^/gm, '  ');\n\n    console.log(fmt, (i + 1), test.fullTitle(), msg, stack);\n  });\n};\n\n/**\n * Initialize a new `Base` reporter.\n *\n * All other reporters generally\n * inherit from this reporter, providing\n * stats such as test duration, number\n * of tests passed / failed etc.\n *\n * @param {Runner} runner\n * @api public\n */\n\nfunction Base(runner) {\n  var stats = this.stats = { suites: 0, tests: 0, passes: 0, pending: 0, failures: 0 };\n  var failures = this.failures = [];\n\n  if (!runner) {\n    return;\n  }\n  this.runner = runner;\n\n  runner.stats = stats;\n\n  runner.on('start', function() {\n    stats.start = new Date();\n  });\n\n  runner.on('suite', function(suite) {\n    stats.suites = stats.suites || 0;\n    suite.root || stats.suites++;\n  });\n\n  runner.on('test end', function() {\n    stats.tests = stats.tests || 0;\n    stats.tests++;\n  });\n\n  runner.on('pass', function(test) {\n    stats.passes = stats.passes || 0;\n\n    if (test.duration > test.slow()) {\n      test.speed = 'slow';\n    } else if (test.duration > test.slow() / 2) {\n      test.speed = 'medium';\n    } else {\n      test.speed = 'fast';\n    }\n\n    stats.passes++;\n  });\n\n  runner.on('fail', function(test, err) {\n    stats.failures = stats.failures || 0;\n    stats.failures++;\n    test.err = err;\n    failures.push(test);\n  });\n\n  runner.on('end', function() {\n    stats.end = new Date();\n    stats.duration = new Date() - stats.start;\n  });\n\n  runner.on('pending', function() {\n    stats.pending++;\n  });\n}\n\n/**\n * Output common epilogue used by many of\n * the bundled reporters.\n *\n * @api public\n */\nBase.prototype.epilogue = function() {\n  var stats = this.stats;\n  var fmt;\n\n  console.log();\n\n  // passes\n  fmt = color('bright pass', ' ')\n    + color('green', ' %d passing')\n    + color('light', ' (%s)');\n\n  console.log(fmt,\n    stats.passes || 0,\n    ms(stats.duration));\n\n  // pending\n  if (stats.pending) {\n    fmt = color('pending', ' ')\n      + color('pending', ' %d pending');\n\n    console.log(fmt, stats.pending);\n  }\n\n  // failures\n  if (stats.failures) {\n    fmt = color('fail', '  %d failing');\n\n    console.log(fmt, stats.failures);\n\n    Base.list(this.failures);\n    console.log();\n  }\n\n  console.log();\n};\n\n/**\n * Pad the given `str` to `len`.\n *\n * @api private\n * @param {string} str\n * @param {string} len\n * @return {string}\n */\nfunction pad(str, len) {\n  str = String(str);\n  return Array(len - str.length + 1).join(' ') + str;\n}\n\n/**\n * Returns an inline diff between 2 strings with coloured ANSI output\n *\n * @api private\n * @param {Error} err with actual/expected\n * @param {boolean} escape\n * @return {string} Diff\n */\nfunction inlineDiff(err, escape) {\n  var msg = errorDiff(err, 'WordsWithSpace', escape);\n\n  // linenos\n  var lines = msg.split('\\n');\n  if (lines.length > 4) {\n    var width = String(lines.length).length;\n    msg = lines.map(function(str, i) {\n      return pad(++i, width) + ' |' + ' ' + str;\n    }).join('\\n');\n  }\n\n  // legend\n  msg = '\\n'\n    + color('diff removed', 'actual')\n    + ' '\n    + color('diff added', 'expected')\n    + '\\n\\n'\n    + msg\n    + '\\n';\n\n  // indent\n  msg = msg.replace(/^/gm, '      ');\n  return msg;\n}\n\n/**\n * Returns a unified diff between two strings.\n *\n * @api private\n * @param {Error} err with actual/expected\n * @param {boolean} escape\n * @return {string} The diff.\n */\nfunction unifiedDiff(err, escape) {\n  var indent = '      ';\n  function cleanUp(line) {\n    if (escape) {\n      line = escapeInvisibles(line);\n    }\n    if (line[0] === '+') {\n      return indent + colorLines('diff added', line);\n    }\n    if (line[0] === '-') {\n      return indent + colorLines('diff removed', line);\n    }\n    if (line.match(/\\@\\@/)) {\n      return null;\n    }\n    if (line.match(/\\\\ No newline/)) {\n      return null;\n    }\n    return indent + line;\n  }\n  function notBlank(line) {\n    return typeof line !== 'undefined' && line !== null;\n  }\n  var msg = diff.createPatch('string', err.actual, err.expected);\n  var lines = msg.split('\\n').splice(4);\n  return '\\n      '\n    + colorLines('diff added', '+ expected') + ' '\n    + colorLines('diff removed', '- actual')\n    + '\\n\\n'\n    + lines.map(cleanUp).filter(notBlank).join('\\n');\n}\n\n/**\n * Return a character diff for `err`.\n *\n * @api private\n * @param {Error} err\n * @param {string} type\n * @param {boolean} escape\n * @return {string}\n */\nfunction errorDiff(err, type, escape) {\n  var actual = escape ? escapeInvisibles(err.actual) : err.actual;\n  var expected = escape ? escapeInvisibles(err.expected) : err.expected;\n  return diff['diff' + type](actual, expected).map(function(str) {\n    if (str.added) {\n      return colorLines('diff added', str.value);\n    }\n    if (str.removed) {\n      return colorLines('diff removed', str.value);\n    }\n    return str.value;\n  }).join('');\n}\n\n/**\n * Returns a string with all invisible characters in plain text\n *\n * @api private\n * @param {string} line\n * @return {string}\n */\nfunction escapeInvisibles(line) {\n  return line.replace(/\\t/g, '<tab>')\n    .replace(/\\r/g, '<CR>')\n    .replace(/\\n/g, '<LF>\\n');\n}\n\n/**\n * Color lines for `str`, using the color `name`.\n *\n * @api private\n * @param {string} name\n * @param {string} str\n * @return {string}\n */\nfunction colorLines(name, str) {\n  return str.split('\\n').map(function(str) {\n    return color(name, str);\n  }).join('\\n');\n}\n\n/**\n * Object#toString reference.\n */\nvar objToString = Object.prototype.toString;\n\n/**\n * Check that a / b have the same type.\n *\n * @api private\n * @param {Object} a\n * @param {Object} b\n * @return {boolean}\n */\nfunction sameType(a, b) {\n  return objToString.call(a) === objToString.call(b);\n}\n\n}).call(this,require('_process'),typeof global !== \"undefined\" ? global : typeof self !== \"undefined\" ? self : typeof window !== \"undefined\" ? window : {})\n},{\"../ms\":15,\"../utils\":39,\"_process\":51,\"diff\":67,\"supports-color\":41,\"tty\":5}],18:[function(require,module,exports){\n/**\n * Module dependencies.\n */\n\nvar Base = require('./base');\nvar utils = require('../utils');\n\n/**\n * Expose `Doc`.\n */\n\nexports = module.exports = Doc;\n\n/**\n * Initialize a new `Doc` reporter.\n *\n * @param {Runner} runner\n * @api public\n */\nfunction Doc(runner) {\n  Base.call(this, runner);\n\n  var indents = 2;\n\n  function indent() {\n    return Array(indents).join('  ');\n  }\n\n  runner.on('suite', function(suite) {\n    if (suite.root) {\n      return;\n    }\n    ++indents;\n    console.log('%s<section class=\"suite\">', indent());\n    ++indents;\n    console.log('%s<h1>%s</h1>', indent(), utils.escape(suite.title));\n    console.log('%s<dl>', indent());\n  });\n\n  runner.on('suite end', function(suite) {\n    if (suite.root) {\n      return;\n    }\n    console.log('%s</dl>', indent());\n    --indents;\n    console.log('%s</section>', indent());\n    --indents;\n  });\n\n  runner.on('pass', function(test) {\n    console.log('%s  <dt>%s</dt>', indent(), utils.escape(test.title));\n    var code = utils.escape(utils.clean(test.fn.toString()));\n    console.log('%s  <dd><pre><code>%s</code></pre></dd>', indent(), code);\n  });\n\n  runner.on('fail', function(test, err) {\n    console.log('%s  <dt class=\"error\">%s</dt>', indent(), utils.escape(test.title));\n    var code = utils.escape(utils.clean(test.fn.toString()));\n    console.log('%s  <dd class=\"error\"><pre><code>%s</code></pre></dd>', indent(), code);\n    console.log('%s  <dd class=\"error\">%s</dd>', indent(), utils.escape(err));\n  });\n}\n\n},{\"../utils\":39,\"./base\":17}],19:[function(require,module,exports){\n(function (process){\n/**\n * Module dependencies.\n */\n\nvar Base = require('./base');\nvar inherits = require('../utils').inherits;\nvar color = Base.color;\n\n/**\n * Expose `Dot`.\n */\n\nexports = module.exports = Dot;\n\n/**\n * Initialize a new `Dot` matrix test reporter.\n *\n * @api public\n * @param {Runner} runner\n */\nfunction Dot(runner) {\n  Base.call(this, runner);\n\n  var self = this;\n  var width = Base.window.width * .75 | 0;\n  var n = -1;\n\n  runner.on('start', function() {\n    process.stdout.write('\\n');\n  });\n\n  runner.on('pending', function() {\n    if (++n % width === 0) {\n      process.stdout.write('\\n  ');\n    }\n    process.stdout.write(color('pending', Base.symbols.dot));\n  });\n\n  runner.on('pass', function(test) {\n    if (++n % width === 0) {\n      process.stdout.write('\\n  ');\n    }\n    if (test.speed === 'slow') {\n      process.stdout.write(color('bright yellow', Base.symbols.dot));\n    } else {\n      process.stdout.write(color(test.speed, Base.symbols.dot));\n    }\n  });\n\n  runner.on('fail', function() {\n    if (++n % width === 0) {\n      process.stdout.write('\\n  ');\n    }\n    process.stdout.write(color('fail', Base.symbols.dot));\n  });\n\n  runner.on('end', function() {\n    console.log();\n    self.epilogue();\n  });\n}\n\n/**\n * Inherit from `Base.prototype`.\n */\ninherits(Dot, Base);\n\n}).call(this,require('_process'))\n},{\"../utils\":39,\"./base\":17,\"_process\":51}],20:[function(require,module,exports){\n(function (process,__dirname){\n/**\n * Module dependencies.\n */\n\nvar JSONCov = require('./json-cov');\nvar readFileSync = require('fs').readFileSync;\nvar join = require('path').join;\n\n/**\n * Expose `HTMLCov`.\n */\n\nexports = module.exports = HTMLCov;\n\n/**\n * Initialize a new `JsCoverage` reporter.\n *\n * @api public\n * @param {Runner} runner\n */\nfunction HTMLCov(runner) {\n  var jade = require('jade');\n  var file = join(__dirname, '/templates/coverage.jade');\n  var str = readFileSync(file, 'utf8');\n  var fn = jade.compile(str, { filename: file });\n  var self = this;\n\n  JSONCov.call(this, runner, false);\n\n  runner.on('end', function() {\n    process.stdout.write(fn({\n      cov: self.cov,\n      coverageClass: coverageClass\n    }));\n  });\n}\n\n/**\n * Return coverage class for a given coverage percentage.\n *\n * @api private\n * @param {number} coveragePctg\n * @return {string}\n */\nfunction coverageClass(coveragePctg) {\n  if (coveragePctg >= 75) {\n    return 'high';\n  }\n  if (coveragePctg >= 50) {\n    return 'medium';\n  }\n  if (coveragePctg >= 25) {\n    return 'low';\n  }\n  return 'terrible';\n}\n\n}).call(this,require('_process'),\"/lib/reporters\")\n},{\"./json-cov\":23,\"_process\":51,\"fs\":41,\"jade\":41,\"path\":41}],21:[function(require,module,exports){\n(function (global){\n/* eslint-env browser */\n\n/**\n * Module dependencies.\n */\n\nvar Base = require('./base');\nvar utils = require('../utils');\nvar Progress = require('../browser/progress');\nvar escapeRe = require('escape-string-regexp');\nvar escape = utils.escape;\n\n/**\n * Save timer references to avoid Sinon interfering (see GH-237).\n */\n\n/* eslint-disable no-unused-vars, no-native-reassign */\nvar Date = global.Date;\nvar setTimeout = global.setTimeout;\nvar setInterval = global.setInterval;\nvar clearTimeout = global.clearTimeout;\nvar clearInterval = global.clearInterval;\n/* eslint-enable no-unused-vars, no-native-reassign */\n\n/**\n * Expose `HTML`.\n */\n\nexports = module.exports = HTML;\n\n/**\n * Stats template.\n */\n\nvar statsTemplate = '<ul id=\"mocha-stats\">'\n  + '<li class=\"progress\"><canvas width=\"40\" height=\"40\"></canvas></li>'\n  + '<li class=\"passes\"><a href=\"javascript:void(0);\">passes:</a> <em>0</em></li>'\n  + '<li class=\"failures\"><a href=\"javascript:void(0);\">failures:</a> <em>0</em></li>'\n  + '<li class=\"duration\">duration: <em>0</em>s</li>'\n  + '</ul>';\n\n/**\n * Initialize a new `HTML` reporter.\n *\n * @api public\n * @param {Runner} runner\n */\nfunction HTML(runner) {\n  Base.call(this, runner);\n\n  var self = this;\n  var stats = this.stats;\n  var stat = fragment(statsTemplate);\n  var items = stat.getElementsByTagName('li');\n  var passes = items[1].getElementsByTagName('em')[0];\n  var passesLink = items[1].getElementsByTagName('a')[0];\n  var failures = items[2].getElementsByTagName('em')[0];\n  var failuresLink = items[2].getElementsByTagName('a')[0];\n  var duration = items[3].getElementsByTagName('em')[0];\n  var canvas = stat.getElementsByTagName('canvas')[0];\n  var report = fragment('<ul id=\"mocha-report\"></ul>');\n  var stack = [report];\n  var progress;\n  var ctx;\n  var root = document.getElementById('mocha');\n\n  if (canvas.getContext) {\n    var ratio = window.devicePixelRatio || 1;\n    canvas.style.width = canvas.width;\n    canvas.style.height = canvas.height;\n    canvas.width *= ratio;\n    canvas.height *= ratio;\n    ctx = canvas.getContext('2d');\n    ctx.scale(ratio, ratio);\n    progress = new Progress();\n  }\n\n  if (!root) {\n    return error('#mocha div missing, add it to your document');\n  }\n\n  // pass toggle\n  on(passesLink, 'click', function() {\n    unhide();\n    var name = (/pass/).test(report.className) ? '' : ' pass';\n    report.className = report.className.replace(/fail|pass/g, '') + name;\n    if (report.className.trim()) {\n      hideSuitesWithout('test pass');\n    }\n  });\n\n  // failure toggle\n  on(failuresLink, 'click', function() {\n    unhide();\n    var name = (/fail/).test(report.className) ? '' : ' fail';\n    report.className = report.className.replace(/fail|pass/g, '') + name;\n    if (report.className.trim()) {\n      hideSuitesWithout('test fail');\n    }\n  });\n\n  root.appendChild(stat);\n  root.appendChild(report);\n\n  if (progress) {\n    progress.size(40);\n  }\n\n  runner.on('suite', function(suite) {\n    if (suite.root) {\n      return;\n    }\n\n    // suite\n    var url = self.suiteURL(suite);\n    var el = fragment('<li class=\"suite\"><h1><a href=\"%s\">%s</a></h1></li>', url, escape(suite.title));\n\n    // container\n    stack[0].appendChild(el);\n    stack.unshift(document.createElement('ul'));\n    el.appendChild(stack[0]);\n  });\n\n  runner.on('suite end', function(suite) {\n    if (suite.root) {\n      return;\n    }\n    stack.shift();\n  });\n\n  runner.on('fail', function(test) {\n    if (test.type === 'hook') {\n      runner.emit('test end', test);\n    }\n  });\n\n  runner.on('test end', function(test) {\n    // TODO: add to stats\n    var percent = stats.tests / this.total * 100 | 0;\n    if (progress) {\n      progress.update(percent).draw(ctx);\n    }\n\n    // update stats\n    var ms = new Date() - stats.start;\n    text(passes, stats.passes);\n    text(failures, stats.failures);\n    text(duration, (ms / 1000).toFixed(2));\n\n    // test\n    var el;\n    if (test.state === 'passed') {\n      var url = self.testURL(test);\n      el = fragment('<li class=\"test pass %e\"><h2>%e<span class=\"duration\">%ems</span> <a href=\"%s\" class=\"replay\">‣</a></h2></li>', test.speed, test.title, test.duration, url);\n    } else if (test.pending) {\n      el = fragment('<li class=\"test pass pending\"><h2>%e</h2></li>', test.title);\n    } else {\n      el = fragment('<li class=\"test fail\"><h2>%e <a href=\"%e\" class=\"replay\">‣</a></h2></li>', test.title, self.testURL(test));\n      var stackString; // Note: Includes leading newline\n      var message = test.err.toString();\n\n      // <=IE7 stringifies to [Object Error]. Since it can be overloaded, we\n      // check for the result of the stringifying.\n      if (message === '[object Error]') {\n        message = test.err.message;\n      }\n\n      if (test.err.stack) {\n        var indexOfMessage = test.err.stack.indexOf(test.err.message);\n        if (indexOfMessage === -1) {\n          stackString = test.err.stack;\n        } else {\n          stackString = test.err.stack.substr(test.err.message.length + indexOfMessage);\n        }\n      } else if (test.err.sourceURL && test.err.line !== undefined) {\n        // Safari doesn't give you a stack. Let's at least provide a source line.\n        stackString = '\\n(' + test.err.sourceURL + ':' + test.err.line + ')';\n      }\n\n      stackString = stackString || '';\n\n      if (test.err.htmlMessage && stackString) {\n        el.appendChild(fragment('<div class=\"html-error\">%s\\n<pre class=\"error\">%e</pre></div>', test.err.htmlMessage, stackString));\n      } else if (test.err.htmlMessage) {\n        el.appendChild(fragment('<div class=\"html-error\">%s</div>', test.err.htmlMessage));\n      } else {\n        el.appendChild(fragment('<pre class=\"error\">%e%e</pre>', message, stackString));\n      }\n    }\n\n    // toggle code\n    // TODO: defer\n    if (!test.pending) {\n      var h2 = el.getElementsByTagName('h2')[0];\n\n      on(h2, 'click', function() {\n        pre.style.display = pre.style.display === 'none' ? 'block' : 'none';\n      });\n\n      var pre = fragment('<pre><code>%e</code></pre>', utils.clean(test.fn.toString()));\n      el.appendChild(pre);\n      pre.style.display = 'none';\n    }\n\n    // Don't call .appendChild if #mocha-report was already .shift()'ed off the stack.\n    if (stack[0]) {\n      stack[0].appendChild(el);\n    }\n  });\n}\n\n/**\n * Makes a URL, preserving querystring (\"search\") parameters.\n *\n * @param {string} s\n * @return {string} A new URL.\n */\nfunction makeUrl(s) {\n  var search = window.location.search;\n\n  // Remove previous grep query parameter if present\n  if (search) {\n    search = search.replace(/[?&]grep=[^&\\s]*/g, '').replace(/^&/, '?');\n  }\n\n  return window.location.pathname + (search ? search + '&' : '?') + 'grep=' + encodeURIComponent(escapeRe(s));\n}\n\n/**\n * Provide suite URL.\n *\n * @param {Object} [suite]\n */\nHTML.prototype.suiteURL = function(suite) {\n  return makeUrl(suite.fullTitle());\n};\n\n/**\n * Provide test URL.\n *\n * @param {Object} [test]\n */\nHTML.prototype.testURL = function(test) {\n  return makeUrl(test.fullTitle());\n};\n\n/**\n * Display error `msg`.\n *\n * @param {string} msg\n */\nfunction error(msg) {\n  document.body.appendChild(fragment('<div id=\"mocha-error\">%s</div>', msg));\n}\n\n/**\n * Return a DOM fragment from `html`.\n *\n * @param {string} html\n */\nfunction fragment(html) {\n  var args = arguments;\n  var div = document.createElement('div');\n  var i = 1;\n\n  div.innerHTML = html.replace(/%([se])/g, function(_, type) {\n    switch (type) {\n      case 's': return String(args[i++]);\n      case 'e': return escape(args[i++]);\n      // no default\n    }\n  });\n\n  return div.firstChild;\n}\n\n/**\n * Check for suites that do not have elements\n * with `classname`, and hide them.\n *\n * @param {text} classname\n */\nfunction hideSuitesWithout(classname) {\n  var suites = document.getElementsByClassName('suite');\n  for (var i = 0; i < suites.length; i++) {\n    var els = suites[i].getElementsByClassName(classname);\n    if (!els.length) {\n      suites[i].className += ' hidden';\n    }\n  }\n}\n\n/**\n * Unhide .hidden suites.\n */\nfunction unhide() {\n  var els = document.getElementsByClassName('suite hidden');\n  for (var i = 0; i < els.length; ++i) {\n    els[i].className = els[i].className.replace('suite hidden', 'suite');\n  }\n}\n\n/**\n * Set an element's text contents.\n *\n * @param {HTMLElement} el\n * @param {string} contents\n */\nfunction text(el, contents) {\n  if (el.textContent) {\n    el.textContent = contents;\n  } else {\n    el.innerText = contents;\n  }\n}\n\n/**\n * Listen on `event` with callback `fn`.\n */\nfunction on(el, event, fn) {\n  if (el.addEventListener) {\n    el.addEventListener(event, fn, false);\n  } else {\n    el.attachEvent('on' + event, fn);\n  }\n}\n\n}).call(this,typeof global !== \"undefined\" ? global : typeof self !== \"undefined\" ? self : typeof window !== \"undefined\" ? window : {})\n},{\"../browser/progress\":4,\"../utils\":39,\"./base\":17,\"escape-string-regexp\":68}],22:[function(require,module,exports){\n// Alias exports to a their normalized format Mocha#reporter to prevent a need\n// for dynamic (try/catch) requires, which Browserify doesn't handle.\nexports.Base = exports.base = require('./base');\nexports.Dot = exports.dot = require('./dot');\nexports.Doc = exports.doc = require('./doc');\nexports.TAP = exports.tap = require('./tap');\nexports.JSON = exports.json = require('./json');\nexports.HTML = exports.html = require('./html');\nexports.List = exports.list = require('./list');\nexports.Min = exports.min = require('./min');\nexports.Spec = exports.spec = require('./spec');\nexports.Nyan = exports.nyan = require('./nyan');\nexports.XUnit = exports.xunit = require('./xunit');\nexports.Markdown = exports.markdown = require('./markdown');\nexports.Progress = exports.progress = require('./progress');\nexports.Landing = exports.landing = require('./landing');\nexports.JSONCov = exports['json-cov'] = require('./json-cov');\nexports.HTMLCov = exports['html-cov'] = require('./html-cov');\nexports.JSONStream = exports['json-stream'] = require('./json-stream');\n\n},{\"./base\":17,\"./doc\":18,\"./dot\":19,\"./html\":21,\"./html-cov\":20,\"./json\":25,\"./json-cov\":23,\"./json-stream\":24,\"./landing\":26,\"./list\":27,\"./markdown\":28,\"./min\":29,\"./nyan\":30,\"./progress\":31,\"./spec\":32,\"./tap\":33,\"./xunit\":34}],23:[function(require,module,exports){\n(function (process,global){\n/**\n * Module dependencies.\n */\n\nvar Base = require('./base');\n\n/**\n * Expose `JSONCov`.\n */\n\nexports = module.exports = JSONCov;\n\n/**\n * Initialize a new `JsCoverage` reporter.\n *\n * @api public\n * @param {Runner} runner\n * @param {boolean} output\n */\nfunction JSONCov(runner, output) {\n  Base.call(this, runner);\n\n  output = arguments.length === 1 || output;\n  var self = this;\n  var tests = [];\n  var failures = [];\n  var passes = [];\n\n  runner.on('test end', function(test) {\n    tests.push(test);\n  });\n\n  runner.on('pass', function(test) {\n    passes.push(test);\n  });\n\n  runner.on('fail', function(test) {\n    failures.push(test);\n  });\n\n  runner.on('end', function() {\n    var cov = global._$jscoverage || {};\n    var result = self.cov = map(cov);\n    result.stats = self.stats;\n    result.tests = tests.map(clean);\n    result.failures = failures.map(clean);\n    result.passes = passes.map(clean);\n    if (!output) {\n      return;\n    }\n    process.stdout.write(JSON.stringify(result, null, 2));\n  });\n}\n\n/**\n * Map jscoverage data to a JSON structure\n * suitable for reporting.\n *\n * @api private\n * @param {Object} cov\n * @return {Object}\n */\n\nfunction map(cov) {\n  var ret = {\n    instrumentation: 'node-jscoverage',\n    sloc: 0,\n    hits: 0,\n    misses: 0,\n    coverage: 0,\n    files: []\n  };\n\n  for (var filename in cov) {\n    if (Object.prototype.hasOwnProperty.call(cov, filename)) {\n      var data = coverage(filename, cov[filename]);\n      ret.files.push(data);\n      ret.hits += data.hits;\n      ret.misses += data.misses;\n      ret.sloc += data.sloc;\n    }\n  }\n\n  ret.files.sort(function(a, b) {\n    return a.filename.localeCompare(b.filename);\n  });\n\n  if (ret.sloc > 0) {\n    ret.coverage = (ret.hits / ret.sloc) * 100;\n  }\n\n  return ret;\n}\n\n/**\n * Map jscoverage data for a single source file\n * to a JSON structure suitable for reporting.\n *\n * @api private\n * @param {string} filename name of the source file\n * @param {Object} data jscoverage coverage data\n * @return {Object}\n */\nfunction coverage(filename, data) {\n  var ret = {\n    filename: filename,\n    coverage: 0,\n    hits: 0,\n    misses: 0,\n    sloc: 0,\n    source: {}\n  };\n\n  data.source.forEach(function(line, num) {\n    num++;\n\n    if (data[num] === 0) {\n      ret.misses++;\n      ret.sloc++;\n    } else if (data[num] !== undefined) {\n      ret.hits++;\n      ret.sloc++;\n    }\n\n    ret.source[num] = {\n      source: line,\n      coverage: data[num] === undefined ? '' : data[num]\n    };\n  });\n\n  ret.coverage = ret.hits / ret.sloc * 100;\n\n  return ret;\n}\n\n/**\n * Return a plain-object representation of `test`\n * free of cyclic properties etc.\n *\n * @api private\n * @param {Object} test\n * @return {Object}\n */\nfunction clean(test) {\n  return {\n    duration: test.duration,\n    fullTitle: test.fullTitle(),\n    title: test.title\n  };\n}\n\n}).call(this,require('_process'),typeof global !== \"undefined\" ? global : typeof self !== \"undefined\" ? self : typeof window !== \"undefined\" ? window : {})\n},{\"./base\":17,\"_process\":51}],24:[function(require,module,exports){\n(function (process){\n/**\n * Module dependencies.\n */\n\nvar Base = require('./base');\n\n/**\n * Expose `List`.\n */\n\nexports = module.exports = List;\n\n/**\n * Initialize a new `List` test reporter.\n *\n * @api public\n * @param {Runner} runner\n */\nfunction List(runner) {\n  Base.call(this, runner);\n\n  var self = this;\n  var total = runner.total;\n\n  runner.on('start', function() {\n    console.log(JSON.stringify(['start', { total: total }]));\n  });\n\n  runner.on('pass', function(test) {\n    console.log(JSON.stringify(['pass', clean(test)]));\n  });\n\n  runner.on('fail', function(test, err) {\n    test = clean(test);\n    test.err = err.message;\n    test.stack = err.stack || null;\n    console.log(JSON.stringify(['fail', test]));\n  });\n\n  runner.on('end', function() {\n    process.stdout.write(JSON.stringify(['end', self.stats]));\n  });\n}\n\n/**\n * Return a plain-object representation of `test`\n * free of cyclic properties etc.\n *\n * @api private\n * @param {Object} test\n * @return {Object}\n */\nfunction clean(test) {\n  return {\n    title: test.title,\n    fullTitle: test.fullTitle(),\n    duration: test.duration\n  };\n}\n\n}).call(this,require('_process'))\n},{\"./base\":17,\"_process\":51}],25:[function(require,module,exports){\n(function (process){\n/**\n * Module dependencies.\n */\n\nvar Base = require('./base');\n\n/**\n * Expose `JSON`.\n */\n\nexports = module.exports = JSONReporter;\n\n/**\n * Initialize a new `JSON` reporter.\n *\n * @api public\n * @param {Runner} runner\n */\nfunction JSONReporter(runner) {\n  Base.call(this, runner);\n\n  var self = this;\n  var tests = [];\n  var pending = [];\n  var failures = [];\n  var passes = [];\n\n  runner.on('test end', function(test) {\n    tests.push(test);\n  });\n\n  runner.on('pass', function(test) {\n    passes.push(test);\n  });\n\n  runner.on('fail', function(test) {\n    failures.push(test);\n  });\n\n  runner.on('pending', function(test) {\n    pending.push(test);\n  });\n\n  runner.on('end', function() {\n    var obj = {\n      stats: self.stats,\n      tests: tests.map(clean),\n      pending: pending.map(clean),\n      failures: failures.map(clean),\n      passes: passes.map(clean)\n    };\n\n    runner.testResults = obj;\n\n    process.stdout.write(JSON.stringify(obj, null, 2));\n  });\n}\n\n/**\n * Return a plain-object representation of `test`\n * free of cyclic properties etc.\n *\n * @api private\n * @param {Object} test\n * @return {Object}\n */\nfunction clean(test) {\n  return {\n    title: test.title,\n    fullTitle: test.fullTitle(),\n    duration: test.duration,\n    err: errorJSON(test.err || {})\n  };\n}\n\n/**\n * Transform `error` into a JSON object.\n *\n * @api private\n * @param {Error} err\n * @return {Object}\n */\nfunction errorJSON(err) {\n  var res = {};\n  Object.getOwnPropertyNames(err).forEach(function(key) {\n    res[key] = err[key];\n  }, err);\n  return res;\n}\n\n}).call(this,require('_process'))\n},{\"./base\":17,\"_process\":51}],26:[function(require,module,exports){\n(function (process){\n/**\n * Module dependencies.\n */\n\nvar Base = require('./base');\nvar inherits = require('../utils').inherits;\nvar cursor = Base.cursor;\nvar color = Base.color;\n\n/**\n * Expose `Landing`.\n */\n\nexports = module.exports = Landing;\n\n/**\n * Airplane color.\n */\n\nBase.colors.plane = 0;\n\n/**\n * Airplane crash color.\n */\n\nBase.colors['plane crash'] = 31;\n\n/**\n * Runway color.\n */\n\nBase.colors.runway = 90;\n\n/**\n * Initialize a new `Landing` reporter.\n *\n * @api public\n * @param {Runner} runner\n */\nfunction Landing(runner) {\n  Base.call(this, runner);\n\n  var self = this;\n  var width = Base.window.width * .75 | 0;\n  var total = runner.total;\n  var stream = process.stdout;\n  var plane = color('plane', '✈');\n  var crashed = -1;\n  var n = 0;\n\n  function runway() {\n    var buf = Array(width).join('-');\n    return '  ' + color('runway', buf);\n  }\n\n  runner.on('start', function() {\n    stream.write('\\n\\n\\n  ');\n    cursor.hide();\n  });\n\n  runner.on('test end', function(test) {\n    // check if the plane crashed\n    var col = crashed === -1 ? width * ++n / total | 0 : crashed;\n\n    // show the crash\n    if (test.state === 'failed') {\n      plane = color('plane crash', '✈');\n      crashed = col;\n    }\n\n    // render landing strip\n    stream.write('\\u001b[' + (width + 1) + 'D\\u001b[2A');\n    stream.write(runway());\n    stream.write('\\n  ');\n    stream.write(color('runway', Array(col).join('⋅')));\n    stream.write(plane);\n    stream.write(color('runway', Array(width - col).join('⋅') + '\\n'));\n    stream.write(runway());\n    stream.write('\\u001b[0m');\n  });\n\n  runner.on('end', function() {\n    cursor.show();\n    console.log();\n    self.epilogue();\n  });\n}\n\n/**\n * Inherit from `Base.prototype`.\n */\ninherits(Landing, Base);\n\n}).call(this,require('_process'))\n},{\"../utils\":39,\"./base\":17,\"_process\":51}],27:[function(require,module,exports){\n(function (process){\n/**\n * Module dependencies.\n */\n\nvar Base = require('./base');\nvar inherits = require('../utils').inherits;\nvar color = Base.color;\nvar cursor = Base.cursor;\n\n/**\n * Expose `List`.\n */\n\nexports = module.exports = List;\n\n/**\n * Initialize a new `List` test reporter.\n *\n * @api public\n * @param {Runner} runner\n */\nfunction List(runner) {\n  Base.call(this, runner);\n\n  var self = this;\n  var n = 0;\n\n  runner.on('start', function() {\n    console.log();\n  });\n\n  runner.on('test', function(test) {\n    process.stdout.write(color('pass', '    ' + test.fullTitle() + ': '));\n  });\n\n  runner.on('pending', function(test) {\n    var fmt = color('checkmark', '  -')\n      + color('pending', ' %s');\n    console.log(fmt, test.fullTitle());\n  });\n\n  runner.on('pass', function(test) {\n    var fmt = color('checkmark', '  ' + Base.symbols.dot)\n      + color('pass', ' %s: ')\n      + color(test.speed, '%dms');\n    cursor.CR();\n    console.log(fmt, test.fullTitle(), test.duration);\n  });\n\n  runner.on('fail', function(test) {\n    cursor.CR();\n    console.log(color('fail', '  %d) %s'), ++n, test.fullTitle());\n  });\n\n  runner.on('end', self.epilogue.bind(self));\n}\n\n/**\n * Inherit from `Base.prototype`.\n */\ninherits(List, Base);\n\n}).call(this,require('_process'))\n},{\"../utils\":39,\"./base\":17,\"_process\":51}],28:[function(require,module,exports){\n(function (process){\n/**\n * Module dependencies.\n */\n\nvar Base = require('./base');\nvar utils = require('../utils');\n\n/**\n * Constants\n */\n\nvar SUITE_PREFIX = '$';\n\n/**\n * Expose `Markdown`.\n */\n\nexports = module.exports = Markdown;\n\n/**\n * Initialize a new `Markdown` reporter.\n *\n * @api public\n * @param {Runner} runner\n */\nfunction Markdown(runner) {\n  Base.call(this, runner);\n\n  var level = 0;\n  var buf = '';\n\n  function title(str) {\n    return Array(level).join('#') + ' ' + str;\n  }\n\n  function mapTOC(suite, obj) {\n    var ret = obj;\n    var key = SUITE_PREFIX + suite.title;\n\n    obj = obj[key] = obj[key] || { suite: suite };\n    suite.suites.forEach(function(suite) {\n      mapTOC(suite, obj);\n    });\n\n    return ret;\n  }\n\n  function stringifyTOC(obj, level) {\n    ++level;\n    var buf = '';\n    var link;\n    for (var key in obj) {\n      if (key === 'suite') {\n        continue;\n      }\n      if (key !== SUITE_PREFIX) {\n        link = ' - [' + key.substring(1) + ']';\n        link += '(#' + utils.slug(obj[key].suite.fullTitle()) + ')\\n';\n        buf += Array(level).join('  ') + link;\n      }\n      buf += stringifyTOC(obj[key], level);\n    }\n    return buf;\n  }\n\n  function generateTOC(suite) {\n    var obj = mapTOC(suite, {});\n    return stringifyTOC(obj, 0);\n  }\n\n  generateTOC(runner.suite);\n\n  runner.on('suite', function(suite) {\n    ++level;\n    var slug = utils.slug(suite.fullTitle());\n    buf += '<a name=\"' + slug + '\"></a>' + '\\n';\n    buf += title(suite.title) + '\\n';\n  });\n\n  runner.on('suite end', function() {\n    --level;\n  });\n\n  runner.on('pass', function(test) {\n    var code = utils.clean(test.fn.toString());\n    buf += test.title + '.\\n';\n    buf += '\\n```js\\n';\n    buf += code + '\\n';\n    buf += '```\\n\\n';\n  });\n\n  runner.on('end', function() {\n    process.stdout.write('# TOC\\n');\n    process.stdout.write(generateTOC(runner.suite));\n    process.stdout.write(buf);\n  });\n}\n\n}).call(this,require('_process'))\n},{\"../utils\":39,\"./base\":17,\"_process\":51}],29:[function(require,module,exports){\n(function (process){\n/**\n * Module dependencies.\n */\n\nvar Base = require('./base');\nvar inherits = require('../utils').inherits;\n\n/**\n * Expose `Min`.\n */\n\nexports = module.exports = Min;\n\n/**\n * Initialize a new `Min` minimal test reporter (best used with --watch).\n *\n * @api public\n * @param {Runner} runner\n */\nfunction Min(runner) {\n  Base.call(this, runner);\n\n  runner.on('start', function() {\n    // clear screen\n    process.stdout.write('\\u001b[2J');\n    // set cursor position\n    process.stdout.write('\\u001b[1;3H');\n  });\n\n  runner.on('end', this.epilogue.bind(this));\n}\n\n/**\n * Inherit from `Base.prototype`.\n */\ninherits(Min, Base);\n\n}).call(this,require('_process'))\n},{\"../utils\":39,\"./base\":17,\"_process\":51}],30:[function(require,module,exports){\n(function (process){\n/**\n * Module dependencies.\n */\n\nvar Base = require('./base');\nvar inherits = require('../utils').inherits;\n\n/**\n * Expose `Dot`.\n */\n\nexports = module.exports = NyanCat;\n\n/**\n * Initialize a new `Dot` matrix test reporter.\n *\n * @param {Runner} runner\n * @api public\n */\n\nfunction NyanCat(runner) {\n  Base.call(this, runner);\n\n  var self = this;\n  var width = Base.window.width * .75 | 0;\n  var nyanCatWidth = this.nyanCatWidth = 11;\n\n  this.colorIndex = 0;\n  this.numberOfLines = 4;\n  this.rainbowColors = self.generateColors();\n  this.scoreboardWidth = 5;\n  this.tick = 0;\n  this.trajectories = [[], [], [], []];\n  this.trajectoryWidthMax = (width - nyanCatWidth);\n\n  runner.on('start', function() {\n    Base.cursor.hide();\n    self.draw();\n  });\n\n  runner.on('pending', function() {\n    self.draw();\n  });\n\n  runner.on('pass', function() {\n    self.draw();\n  });\n\n  runner.on('fail', function() {\n    self.draw();\n  });\n\n  runner.on('end', function() {\n    Base.cursor.show();\n    for (var i = 0; i < self.numberOfLines; i++) {\n      write('\\n');\n    }\n    self.epilogue();\n  });\n}\n\n/**\n * Inherit from `Base.prototype`.\n */\ninherits(NyanCat, Base);\n\n/**\n * Draw the nyan cat\n *\n * @api private\n */\n\nNyanCat.prototype.draw = function() {\n  this.appendRainbow();\n  this.drawScoreboard();\n  this.drawRainbow();\n  this.drawNyanCat();\n  this.tick = !this.tick;\n};\n\n/**\n * Draw the \"scoreboard\" showing the number\n * of passes, failures and pending tests.\n *\n * @api private\n */\n\nNyanCat.prototype.drawScoreboard = function() {\n  var stats = this.stats;\n\n  function draw(type, n) {\n    write(' ');\n    write(Base.color(type, n));\n    write('\\n');\n  }\n\n  draw('green', stats.passes);\n  draw('fail', stats.failures);\n  draw('pending', stats.pending);\n  write('\\n');\n\n  this.cursorUp(this.numberOfLines);\n};\n\n/**\n * Append the rainbow.\n *\n * @api private\n */\n\nNyanCat.prototype.appendRainbow = function() {\n  var segment = this.tick ? '_' : '-';\n  var rainbowified = this.rainbowify(segment);\n\n  for (var index = 0; index < this.numberOfLines; index++) {\n    var trajectory = this.trajectories[index];\n    if (trajectory.length >= this.trajectoryWidthMax) {\n      trajectory.shift();\n    }\n    trajectory.push(rainbowified);\n  }\n};\n\n/**\n * Draw the rainbow.\n *\n * @api private\n */\n\nNyanCat.prototype.drawRainbow = function() {\n  var self = this;\n\n  this.trajectories.forEach(function(line) {\n    write('\\u001b[' + self.scoreboardWidth + 'C');\n    write(line.join(''));\n    write('\\n');\n  });\n\n  this.cursorUp(this.numberOfLines);\n};\n\n/**\n * Draw the nyan cat\n *\n * @api private\n */\nNyanCat.prototype.drawNyanCat = function() {\n  var self = this;\n  var startWidth = this.scoreboardWidth + this.trajectories[0].length;\n  var dist = '\\u001b[' + startWidth + 'C';\n  var padding = '';\n\n  write(dist);\n  write('_,------,');\n  write('\\n');\n\n  write(dist);\n  padding = self.tick ? '  ' : '   ';\n  write('_|' + padding + '/\\\\_/\\\\ ');\n  write('\\n');\n\n  write(dist);\n  padding = self.tick ? '_' : '__';\n  var tail = self.tick ? '~' : '^';\n  write(tail + '|' + padding + this.face() + ' ');\n  write('\\n');\n\n  write(dist);\n  padding = self.tick ? ' ' : '  ';\n  write(padding + '\"\"  \"\" ');\n  write('\\n');\n\n  this.cursorUp(this.numberOfLines);\n};\n\n/**\n * Draw nyan cat face.\n *\n * @api private\n * @return {string}\n */\n\nNyanCat.prototype.face = function() {\n  var stats = this.stats;\n  if (stats.failures) {\n    return '( x .x)';\n  } else if (stats.pending) {\n    return '( o .o)';\n  } else if (stats.passes) {\n    return '( ^ .^)';\n  }\n  return '( - .-)';\n};\n\n/**\n * Move cursor up `n`.\n *\n * @api private\n * @param {number} n\n */\n\nNyanCat.prototype.cursorUp = function(n) {\n  write('\\u001b[' + n + 'A');\n};\n\n/**\n * Move cursor down `n`.\n *\n * @api private\n * @param {number} n\n */\n\nNyanCat.prototype.cursorDown = function(n) {\n  write('\\u001b[' + n + 'B');\n};\n\n/**\n * Generate rainbow colors.\n *\n * @api private\n * @return {Array}\n */\nNyanCat.prototype.generateColors = function() {\n  var colors = [];\n\n  for (var i = 0; i < (6 * 7); i++) {\n    var pi3 = Math.floor(Math.PI / 3);\n    var n = (i * (1.0 / 6));\n    var r = Math.floor(3 * Math.sin(n) + 3);\n    var g = Math.floor(3 * Math.sin(n + 2 * pi3) + 3);\n    var b = Math.floor(3 * Math.sin(n + 4 * pi3) + 3);\n    colors.push(36 * r + 6 * g + b + 16);\n  }\n\n  return colors;\n};\n\n/**\n * Apply rainbow to the given `str`.\n *\n * @api private\n * @param {string} str\n * @return {string}\n */\nNyanCat.prototype.rainbowify = function(str) {\n  if (!Base.useColors) {\n    return str;\n  }\n  var color = this.rainbowColors[this.colorIndex % this.rainbowColors.length];\n  this.colorIndex += 1;\n  return '\\u001b[38;5;' + color + 'm' + str + '\\u001b[0m';\n};\n\n/**\n * Stdout helper.\n *\n * @param {string} string A message to write to stdout.\n */\nfunction write(string) {\n  process.stdout.write(string);\n}\n\n}).call(this,require('_process'))\n},{\"../utils\":39,\"./base\":17,\"_process\":51}],31:[function(require,module,exports){\n(function (process){\n/**\n * Module dependencies.\n */\n\nvar Base = require('./base');\nvar inherits = require('../utils').inherits;\nvar color = Base.color;\nvar cursor = Base.cursor;\n\n/**\n * Expose `Progress`.\n */\n\nexports = module.exports = Progress;\n\n/**\n * General progress bar color.\n */\n\nBase.colors.progress = 90;\n\n/**\n * Initialize a new `Progress` bar test reporter.\n *\n * @api public\n * @param {Runner} runner\n * @param {Object} options\n */\nfunction Progress(runner, options) {\n  Base.call(this, runner);\n\n  var self = this;\n  var width = Base.window.width * .50 | 0;\n  var total = runner.total;\n  var complete = 0;\n  var lastN = -1;\n\n  // default chars\n  options = options || {};\n  options.open = options.open || '[';\n  options.complete = options.complete || '▬';\n  options.incomplete = options.incomplete || Base.symbols.dot;\n  options.close = options.close || ']';\n  options.verbose = false;\n\n  // tests started\n  runner.on('start', function() {\n    console.log();\n    cursor.hide();\n  });\n\n  // tests complete\n  runner.on('test end', function() {\n    complete++;\n\n    var percent = complete / total;\n    var n = width * percent | 0;\n    var i = width - n;\n\n    if (n === lastN && !options.verbose) {\n      // Don't re-render the line if it hasn't changed\n      return;\n    }\n    lastN = n;\n\n    cursor.CR();\n    process.stdout.write('\\u001b[J');\n    process.stdout.write(color('progress', '  ' + options.open));\n    process.stdout.write(Array(n).join(options.complete));\n    process.stdout.write(Array(i).join(options.incomplete));\n    process.stdout.write(color('progress', options.close));\n    if (options.verbose) {\n      process.stdout.write(color('progress', ' ' + complete + ' of ' + total));\n    }\n  });\n\n  // tests are complete, output some stats\n  // and the failures if any\n  runner.on('end', function() {\n    cursor.show();\n    console.log();\n    self.epilogue();\n  });\n}\n\n/**\n * Inherit from `Base.prototype`.\n */\ninherits(Progress, Base);\n\n}).call(this,require('_process'))\n},{\"../utils\":39,\"./base\":17,\"_process\":51}],32:[function(require,module,exports){\n/**\n * Module dependencies.\n */\n\nvar Base = require('./base');\nvar inherits = require('../utils').inherits;\nvar color = Base.color;\nvar cursor = Base.cursor;\n\n/**\n * Expose `Spec`.\n */\n\nexports = module.exports = Spec;\n\n/**\n * Initialize a new `Spec` test reporter.\n *\n * @api public\n * @param {Runner} runner\n */\nfunction Spec(runner) {\n  Base.call(this, runner);\n\n  var self = this;\n  var indents = 0;\n  var n = 0;\n\n  function indent() {\n    return Array(indents).join('  ');\n  }\n\n  runner.on('start', function() {\n    console.log();\n  });\n\n  runner.on('suite', function(suite) {\n    ++indents;\n    console.log(color('suite', '%s%s'), indent(), suite.title);\n  });\n\n  runner.on('suite end', function() {\n    --indents;\n    if (indents === 1) {\n      console.log();\n    }\n  });\n\n  runner.on('pending', function(test) {\n    var fmt = indent() + color('pending', '  - %s');\n    console.log(fmt, test.title);\n  });\n\n  runner.on('pass', function(test) {\n    var fmt;\n    if (test.speed === 'fast') {\n      fmt = indent()\n        + color('checkmark', '  ' + Base.symbols.ok)\n        + color('pass', ' %s');\n      cursor.CR();\n      console.log(fmt, test.title);\n    } else {\n      fmt = indent()\n        + color('checkmark', '  ' + Base.symbols.ok)\n        + color('pass', ' %s')\n        + color(test.speed, ' (%dms)');\n      cursor.CR();\n      console.log(fmt, test.title, test.duration);\n    }\n  });\n\n  runner.on('fail', function(test) {\n    cursor.CR();\n    console.log(indent() + color('fail', '  %d) %s'), ++n, test.title);\n  });\n\n  runner.on('end', self.epilogue.bind(self));\n}\n\n/**\n * Inherit from `Base.prototype`.\n */\ninherits(Spec, Base);\n\n},{\"../utils\":39,\"./base\":17}],33:[function(require,module,exports){\n/**\n * Module dependencies.\n */\n\nvar Base = require('./base');\n\n/**\n * Expose `TAP`.\n */\n\nexports = module.exports = TAP;\n\n/**\n * Initialize a new `TAP` reporter.\n *\n * @api public\n * @param {Runner} runner\n */\nfunction TAP(runner) {\n  Base.call(this, runner);\n\n  var n = 1;\n  var passes = 0;\n  var failures = 0;\n\n  runner.on('start', function() {\n    var total = runner.grepTotal(runner.suite);\n    console.log('%d..%d', 1, total);\n  });\n\n  runner.on('test end', function() {\n    ++n;\n  });\n\n  runner.on('pending', function(test) {\n    console.log('ok %d %s # SKIP -', n, title(test));\n  });\n\n  runner.on('pass', function(test) {\n    passes++;\n    console.log('ok %d %s', n, title(test));\n  });\n\n  runner.on('fail', function(test, err) {\n    failures++;\n    console.log('not ok %d %s', n, title(test));\n    if (err.stack) {\n      console.log(err.stack.replace(/^/gm, '  '));\n    }\n  });\n\n  runner.on('end', function() {\n    console.log('# tests ' + (passes + failures));\n    console.log('# pass ' + passes);\n    console.log('# fail ' + failures);\n  });\n}\n\n/**\n * Return a TAP-safe title of `test`\n *\n * @api private\n * @param {Object} test\n * @return {String}\n */\nfunction title(test) {\n  return test.fullTitle().replace(/#/g, '');\n}\n\n},{\"./base\":17}],34:[function(require,module,exports){\n(function (global){\n/**\n * Module dependencies.\n */\n\nvar Base = require('./base');\nvar utils = require('../utils');\nvar inherits = utils.inherits;\nvar fs = require('fs');\nvar escape = utils.escape;\n\n/**\n * Save timer references to avoid Sinon interfering (see GH-237).\n */\n\n/* eslint-disable no-unused-vars, no-native-reassign */\nvar Date = global.Date;\nvar setTimeout = global.setTimeout;\nvar setInterval = global.setInterval;\nvar clearTimeout = global.clearTimeout;\nvar clearInterval = global.clearInterval;\n/* eslint-enable no-unused-vars, no-native-reassign */\n\n/**\n * Expose `XUnit`.\n */\n\nexports = module.exports = XUnit;\n\n/**\n * Initialize a new `XUnit` reporter.\n *\n * @api public\n * @param {Runner} runner\n */\nfunction XUnit(runner, options) {\n  Base.call(this, runner);\n\n  var stats = this.stats;\n  var tests = [];\n  var self = this;\n\n  if (options.reporterOptions && options.reporterOptions.output) {\n    if (!fs.createWriteStream) {\n      throw new Error('file output not supported in browser');\n    }\n    self.fileStream = fs.createWriteStream(options.reporterOptions.output);\n  }\n\n  runner.on('pending', function(test) {\n    tests.push(test);\n  });\n\n  runner.on('pass', function(test) {\n    tests.push(test);\n  });\n\n  runner.on('fail', function(test) {\n    tests.push(test);\n  });\n\n  runner.on('end', function() {\n    self.write(tag('testsuite', {\n      name: 'Mocha Tests',\n      tests: stats.tests,\n      failures: stats.failures,\n      errors: stats.failures,\n      skipped: stats.tests - stats.failures - stats.passes,\n      timestamp: (new Date()).toUTCString(),\n      time: (stats.duration / 1000) || 0\n    }, false));\n\n    tests.forEach(function(t) {\n      self.test(t);\n    });\n\n    self.write('</testsuite>');\n  });\n}\n\n/**\n * Inherit from `Base.prototype`.\n */\ninherits(XUnit, Base);\n\n/**\n * Override done to close the stream (if it's a file).\n *\n * @param failures\n * @param {Function} fn\n */\nXUnit.prototype.done = function(failures, fn) {\n  if (this.fileStream) {\n    this.fileStream.end(function() {\n      fn(failures);\n    });\n  } else {\n    fn(failures);\n  }\n};\n\n/**\n * Write out the given line.\n *\n * @param {string} line\n */\nXUnit.prototype.write = function(line) {\n  if (this.fileStream) {\n    this.fileStream.write(line + '\\n');\n  } else {\n    console.log(line);\n  }\n};\n\n/**\n * Output tag for the given `test.`\n *\n * @param {Test} test\n */\nXUnit.prototype.test = function(test) {\n  var attrs = {\n    classname: test.parent.fullTitle(),\n    name: test.title,\n    time: (test.duration / 1000) || 0\n  };\n\n  if (test.state === 'failed') {\n    var err = test.err;\n    this.write(tag('testcase', attrs, false, tag('failure', {}, false, cdata(escape(err.message) + '\\n' + err.stack))));\n  } else if (test.pending) {\n    this.write(tag('testcase', attrs, false, tag('skipped', {}, true)));\n  } else {\n    this.write(tag('testcase', attrs, true));\n  }\n};\n\n/**\n * HTML tag helper.\n *\n * @param name\n * @param attrs\n * @param close\n * @param content\n * @return {string}\n */\nfunction tag(name, attrs, close, content) {\n  var end = close ? '/>' : '>';\n  var pairs = [];\n  var tag;\n\n  for (var key in attrs) {\n    if (Object.prototype.hasOwnProperty.call(attrs, key)) {\n      pairs.push(key + '=\"' + escape(attrs[key]) + '\"');\n    }\n  }\n\n  tag = '<' + name + (pairs.length ? ' ' + pairs.join(' ') : '') + end;\n  if (content) {\n    tag += content + '</' + name + end;\n  }\n  return tag;\n}\n\n/**\n * Return cdata escaped CDATA `str`.\n */\n\nfunction cdata(str) {\n  return '<![CDATA[' + escape(str) + ']]>';\n}\n\n}).call(this,typeof global !== \"undefined\" ? global : typeof self !== \"undefined\" ? self : typeof window !== \"undefined\" ? window : {})\n},{\"../utils\":39,\"./base\":17,\"fs\":41}],35:[function(require,module,exports){\n(function (global){\n/**\n * Module dependencies.\n */\n\nvar EventEmitter = require('events').EventEmitter;\nvar Pending = require('./pending');\nvar debug = require('debug')('mocha:runnable');\nvar milliseconds = require('./ms');\nvar utils = require('./utils');\nvar inherits = utils.inherits;\n\n/**\n * Save timer references to avoid Sinon interfering (see GH-237).\n */\n\n/* eslint-disable no-unused-vars, no-native-reassign */\nvar Date = global.Date;\nvar setTimeout = global.setTimeout;\nvar setInterval = global.setInterval;\nvar clearTimeout = global.clearTimeout;\nvar clearInterval = global.clearInterval;\n/* eslint-enable no-unused-vars, no-native-reassign */\n\n/**\n * Object#toString().\n */\n\nvar toString = Object.prototype.toString;\n\n/**\n * Expose `Runnable`.\n */\n\nmodule.exports = Runnable;\n\n/**\n * Initialize a new `Runnable` with the given `title` and callback `fn`.\n *\n * @param {String} title\n * @param {Function} fn\n * @api private\n * @param {string} title\n * @param {Function} fn\n */\nfunction Runnable(title, fn) {\n  this.title = title;\n  this.fn = fn;\n  this.async = fn && fn.length;\n  this.sync = !this.async;\n  this._timeout = 2000;\n  this._slow = 75;\n  this._enableTimeouts = true;\n  this.timedOut = false;\n  this._trace = new Error('done() called multiple times');\n}\n\n/**\n * Inherit from `EventEmitter.prototype`.\n */\ninherits(Runnable, EventEmitter);\n\n/**\n * Set & get timeout `ms`.\n *\n * @api private\n * @param {number|string} ms\n * @return {Runnable|number} ms or Runnable instance.\n */\nRunnable.prototype.timeout = function(ms) {\n  if (!arguments.length) {\n    return this._timeout;\n  }\n  if (ms === 0) {\n    this._enableTimeouts = false;\n  }\n  if (typeof ms === 'string') {\n    ms = milliseconds(ms);\n  }\n  debug('timeout %d', ms);\n  this._timeout = ms;\n  if (this.timer) {\n    this.resetTimeout();\n  }\n  return this;\n};\n\n/**\n * Set & get slow `ms`.\n *\n * @api private\n * @param {number|string} ms\n * @return {Runnable|number} ms or Runnable instance.\n */\nRunnable.prototype.slow = function(ms) {\n  if (!arguments.length) {\n    return this._slow;\n  }\n  if (typeof ms === 'string') {\n    ms = milliseconds(ms);\n  }\n  debug('timeout %d', ms);\n  this._slow = ms;\n  return this;\n};\n\n/**\n * Set and get whether timeout is `enabled`.\n *\n * @api private\n * @param {boolean} enabled\n * @return {Runnable|boolean} enabled or Runnable instance.\n */\nRunnable.prototype.enableTimeouts = function(enabled) {\n  if (!arguments.length) {\n    return this._enableTimeouts;\n  }\n  debug('enableTimeouts %s', enabled);\n  this._enableTimeouts = enabled;\n  return this;\n};\n\n/**\n * Halt and mark as pending.\n *\n * @api private\n */\nRunnable.prototype.skip = function() {\n  throw new Pending();\n};\n\n/**\n * Return the full title generated by recursively concatenating the parent's\n * full title.\n *\n * @api public\n * @return {string}\n */\nRunnable.prototype.fullTitle = function() {\n  return this.parent.fullTitle() + ' ' + this.title;\n};\n\n/**\n * Clear the timeout.\n *\n * @api private\n */\nRunnable.prototype.clearTimeout = function() {\n  clearTimeout(this.timer);\n};\n\n/**\n * Inspect the runnable void of private properties.\n *\n * @api private\n * @return {string}\n */\nRunnable.prototype.inspect = function() {\n  return JSON.stringify(this, function(key, val) {\n    if (key[0] === '_') {\n      return;\n    }\n    if (key === 'parent') {\n      return '#<Suite>';\n    }\n    if (key === 'ctx') {\n      return '#<Context>';\n    }\n    return val;\n  }, 2);\n};\n\n/**\n * Reset the timeout.\n *\n * @api private\n */\nRunnable.prototype.resetTimeout = function() {\n  var self = this;\n  var ms = this.timeout() || 1e9;\n\n  if (!this._enableTimeouts) {\n    return;\n  }\n  this.clearTimeout();\n  this.timer = setTimeout(function() {\n    if (!self._enableTimeouts) {\n      return;\n    }\n    self.callback(new Error('timeout of ' + ms + 'ms exceeded. Ensure the done() callback is being called in this test.'));\n    self.timedOut = true;\n  }, ms);\n};\n\n/**\n * Whitelist a list of globals for this test run.\n *\n * @api private\n * @param {string[]} globals\n */\nRunnable.prototype.globals = function(globals) {\n  this._allowedGlobals = globals;\n};\n\n/**\n * Run the test and invoke `fn(err)`.\n *\n * @param {Function} fn\n * @api private\n */\nRunnable.prototype.run = function(fn) {\n  var self = this;\n  var start = new Date();\n  var ctx = this.ctx;\n  var finished;\n  var emitted;\n\n  // Sometimes the ctx exists, but it is not runnable\n  if (ctx && ctx.runnable) {\n    ctx.runnable(this);\n  }\n\n  // called multiple times\n  function multiple(err) {\n    if (emitted) {\n      return;\n    }\n    emitted = true;\n    self.emit('error', err || new Error('done() called multiple times; stacktrace may be inaccurate'));\n  }\n\n  // finished\n  function done(err) {\n    var ms = self.timeout();\n    if (self.timedOut) {\n      return;\n    }\n    if (finished) {\n      return multiple(err || self._trace);\n    }\n\n    self.clearTimeout();\n    self.duration = new Date() - start;\n    finished = true;\n    if (!err && self.duration > ms && self._enableTimeouts) {\n      err = new Error('timeout of ' + ms + 'ms exceeded. Ensure the done() callback is being called in this test.');\n    }\n    fn(err);\n  }\n\n  // for .resetTimeout()\n  this.callback = done;\n\n  // explicit async with `done` argument\n  if (this.async) {\n    this.resetTimeout();\n\n    if (this.allowUncaught) {\n      return callFnAsync(this.fn);\n    }\n    try {\n      callFnAsync(this.fn);\n    } catch (err) {\n      done(utils.getError(err));\n    }\n    return;\n  }\n\n  if (this.allowUncaught) {\n    callFn(this.fn);\n    done();\n    return;\n  }\n\n  // sync or promise-returning\n  try {\n    if (this.pending) {\n      done();\n    } else {\n      callFn(this.fn);\n    }\n  } catch (err) {\n    done(utils.getError(err));\n  }\n\n  function callFn(fn) {\n    var result = fn.call(ctx);\n    if (result && typeof result.then === 'function') {\n      self.resetTimeout();\n      result\n        .then(function() {\n          done();\n        },\n        function(reason) {\n          done(reason || new Error('Promise rejected with no or falsy reason'));\n        });\n    } else {\n      if (self.asyncOnly) {\n        return done(new Error('--async-only option in use without declaring `done()` or returning a promise'));\n      }\n\n      done();\n    }\n  }\n\n  function callFnAsync(fn) {\n    fn.call(ctx, function(err) {\n      if (err instanceof Error || toString.call(err) === '[object Error]') {\n        return done(err);\n      }\n      if (err) {\n        if (Object.prototype.toString.call(err) === '[object Object]') {\n          return done(new Error('done() invoked with non-Error: '\n            + JSON.stringify(err)));\n        }\n        return done(new Error('done() invoked with non-Error: ' + err));\n      }\n      done();\n    });\n  }\n};\n\n}).call(this,typeof global !== \"undefined\" ? global : typeof self !== \"undefined\" ? self : typeof window !== \"undefined\" ? window : {})\n},{\"./ms\":15,\"./pending\":16,\"./utils\":39,\"debug\":2,\"events\":3}],36:[function(require,module,exports){\n(function (process,global){\n/**\n * Module dependencies.\n */\n\nvar EventEmitter = require('events').EventEmitter;\nvar Pending = require('./pending');\nvar utils = require('./utils');\nvar inherits = utils.inherits;\nvar debug = require('debug')('mocha:runner');\nvar Runnable = require('./runnable');\nvar filter = utils.filter;\nvar indexOf = utils.indexOf;\nvar keys = utils.keys;\nvar stackFilter = utils.stackTraceFilter();\nvar stringify = utils.stringify;\nvar type = utils.type;\nvar undefinedError = utils.undefinedError;\n\n/**\n * Non-enumerable globals.\n */\n\nvar globals = [\n  'setTimeout',\n  'clearTimeout',\n  'setInterval',\n  'clearInterval',\n  'XMLHttpRequest',\n  'Date',\n  'setImmediate',\n  'clearImmediate'\n];\n\n/**\n * Expose `Runner`.\n */\n\nmodule.exports = Runner;\n\n/**\n * Initialize a `Runner` for the given `suite`.\n *\n * Events:\n *\n *   - `start`  execution started\n *   - `end`  execution complete\n *   - `suite`  (suite) test suite execution started\n *   - `suite end`  (suite) all tests (and sub-suites) have finished\n *   - `test`  (test) test execution started\n *   - `test end`  (test) test completed\n *   - `hook`  (hook) hook execution started\n *   - `hook end`  (hook) hook complete\n *   - `pass`  (test) test passed\n *   - `fail`  (test, err) test failed\n *   - `pending`  (test) test pending\n *\n * @api public\n * @param {Suite} suite Root suite\n * @param {boolean} [delay] Whether or not to delay execution of root suite\n * until ready.\n */\nfunction Runner(suite, delay) {\n  var self = this;\n  this._globals = [];\n  this._abort = false;\n  this._delay = delay;\n  this.suite = suite;\n  this.started = false;\n  this.total = suite.total();\n  this.failures = 0;\n  this.on('test end', function(test) {\n    self.checkGlobals(test);\n  });\n  this.on('hook end', function(hook) {\n    self.checkGlobals(hook);\n  });\n  this._defaultGrep = /.*/;\n  this.grep(this._defaultGrep);\n  this.globals(this.globalProps().concat(extraGlobals()));\n}\n\n/**\n * Wrapper for setImmediate, process.nextTick, or browser polyfill.\n *\n * @param {Function} fn\n * @api private\n */\nRunner.immediately = global.setImmediate || process.nextTick;\n\n/**\n * Inherit from `EventEmitter.prototype`.\n */\ninherits(Runner, EventEmitter);\n\n/**\n * Run tests with full titles matching `re`. Updates runner.total\n * with number of tests matched.\n *\n * @param {RegExp} re\n * @param {Boolean} invert\n * @return {Runner} for chaining\n * @api public\n * @param {RegExp} re\n * @param {boolean} invert\n * @return {Runner} Runner instance.\n */\nRunner.prototype.grep = function(re, invert) {\n  debug('grep %s', re);\n  this._grep = re;\n  this._invert = invert;\n  this.total = this.grepTotal(this.suite);\n  return this;\n};\n\n/**\n * Returns the number of tests matching the grep search for the\n * given suite.\n *\n * @param {Suite} suite\n * @return {Number}\n * @api public\n * @param {Suite} suite\n * @return {number}\n */\nRunner.prototype.grepTotal = function(suite) {\n  var self = this;\n  var total = 0;\n\n  suite.eachTest(function(test) {\n    var match = self._grep.test(test.fullTitle());\n    if (self._invert) {\n      match = !match;\n    }\n    if (match) {\n      total++;\n    }\n  });\n\n  return total;\n};\n\n/**\n * Return a list of global properties.\n *\n * @return {Array}\n * @api private\n */\nRunner.prototype.globalProps = function() {\n  var props = keys(global);\n\n  // non-enumerables\n  for (var i = 0; i < globals.length; ++i) {\n    if (~indexOf(props, globals[i])) {\n      continue;\n    }\n    props.push(globals[i]);\n  }\n\n  return props;\n};\n\n/**\n * Allow the given `arr` of globals.\n *\n * @param {Array} arr\n * @return {Runner} for chaining\n * @api public\n * @param {Array} arr\n * @return {Runner} Runner instance.\n */\nRunner.prototype.globals = function(arr) {\n  if (!arguments.length) {\n    return this._globals;\n  }\n  debug('globals %j', arr);\n  this._globals = this._globals.concat(arr);\n  return this;\n};\n\n/**\n * Check for global variable leaks.\n *\n * @api private\n */\nRunner.prototype.checkGlobals = function(test) {\n  if (this.ignoreLeaks) {\n    return;\n  }\n  var ok = this._globals;\n\n  var globals = this.globalProps();\n  var leaks;\n\n  if (test) {\n    ok = ok.concat(test._allowedGlobals || []);\n  }\n\n  if (this.prevGlobalsLength === globals.length) {\n    return;\n  }\n  this.prevGlobalsLength = globals.length;\n\n  leaks = filterLeaks(ok, globals);\n  this._globals = this._globals.concat(leaks);\n\n  if (leaks.length > 1) {\n    this.fail(test, new Error('global leaks detected: ' + leaks.join(', ') + ''));\n  } else if (leaks.length) {\n    this.fail(test, new Error('global leak detected: ' + leaks[0]));\n  }\n};\n\n/**\n * Fail the given `test`.\n *\n * @api private\n * @param {Test} test\n * @param {Error} err\n */\nRunner.prototype.fail = function(test, err) {\n  ++this.failures;\n  test.state = 'failed';\n\n  if (!(err instanceof Error || err && typeof err.message === 'string')) {\n    err = new Error('the ' + type(err) + ' ' + stringify(err) + ' was thrown, throw an Error :)');\n  }\n\n  err.stack = (this.fullStackTrace || !err.stack)\n    ? err.stack\n    : stackFilter(err.stack);\n\n  this.emit('fail', test, err);\n};\n\n/**\n * Fail the given `hook` with `err`.\n *\n * Hook failures work in the following pattern:\n * - If bail, then exit\n * - Failed `before` hook skips all tests in a suite and subsuites,\n *   but jumps to corresponding `after` hook\n * - Failed `before each` hook skips remaining tests in a\n *   suite and jumps to corresponding `after each` hook,\n *   which is run only once\n * - Failed `after` hook does not alter\n *   execution order\n * - Failed `after each` hook skips remaining tests in a\n *   suite and subsuites, but executes other `after each`\n *   hooks\n *\n * @api private\n * @param {Hook} hook\n * @param {Error} err\n */\nRunner.prototype.failHook = function(hook, err) {\n  if (hook.ctx && hook.ctx.currentTest) {\n    hook.originalTitle = hook.originalTitle || hook.title;\n    hook.title = hook.originalTitle + ' for \"' + hook.ctx.currentTest.title + '\"';\n  }\n\n  this.fail(hook, err);\n  if (this.suite.bail()) {\n    this.emit('end');\n  }\n};\n\n/**\n * Run hook `name` callbacks and then invoke `fn()`.\n *\n * @api private\n * @param {string} name\n * @param {Function} fn\n */\n\nRunner.prototype.hook = function(name, fn) {\n  var suite = this.suite;\n  var hooks = suite['_' + name];\n  var self = this;\n\n  function next(i) {\n    var hook = hooks[i];\n    if (!hook) {\n      return fn();\n    }\n    self.currentRunnable = hook;\n\n    hook.ctx.currentTest = self.test;\n\n    self.emit('hook', hook);\n\n    if (!hook.listeners('error').length) {\n      hook.on('error', function(err) {\n        self.failHook(hook, err);\n      });\n    }\n\n    hook.run(function(err) {\n      var testError = hook.error();\n      if (testError) {\n        self.fail(self.test, testError);\n      }\n      if (err) {\n        if (err instanceof Pending) {\n          suite.pending = true;\n        } else {\n          self.failHook(hook, err);\n\n          // stop executing hooks, notify callee of hook err\n          return fn(err);\n        }\n      }\n      self.emit('hook end', hook);\n      delete hook.ctx.currentTest;\n      next(++i);\n    });\n  }\n\n  Runner.immediately(function() {\n    next(0);\n  });\n};\n\n/**\n * Run hook `name` for the given array of `suites`\n * in order, and callback `fn(err, errSuite)`.\n *\n * @api private\n * @param {string} name\n * @param {Array} suites\n * @param {Function} fn\n */\nRunner.prototype.hooks = function(name, suites, fn) {\n  var self = this;\n  var orig = this.suite;\n\n  function next(suite) {\n    self.suite = suite;\n\n    if (!suite) {\n      self.suite = orig;\n      return fn();\n    }\n\n    self.hook(name, function(err) {\n      if (err) {\n        var errSuite = self.suite;\n        self.suite = orig;\n        return fn(err, errSuite);\n      }\n\n      next(suites.pop());\n    });\n  }\n\n  next(suites.pop());\n};\n\n/**\n * Run hooks from the top level down.\n *\n * @param {String} name\n * @param {Function} fn\n * @api private\n */\nRunner.prototype.hookUp = function(name, fn) {\n  var suites = [this.suite].concat(this.parents()).reverse();\n  this.hooks(name, suites, fn);\n};\n\n/**\n * Run hooks from the bottom up.\n *\n * @param {String} name\n * @param {Function} fn\n * @api private\n */\nRunner.prototype.hookDown = function(name, fn) {\n  var suites = [this.suite].concat(this.parents());\n  this.hooks(name, suites, fn);\n};\n\n/**\n * Return an array of parent Suites from\n * closest to furthest.\n *\n * @return {Array}\n * @api private\n */\nRunner.prototype.parents = function() {\n  var suite = this.suite;\n  var suites = [];\n  while (suite.parent) {\n    suite = suite.parent;\n    suites.push(suite);\n  }\n  return suites;\n};\n\n/**\n * Run the current test and callback `fn(err)`.\n *\n * @param {Function} fn\n * @api private\n */\nRunner.prototype.runTest = function(fn) {\n  var self = this;\n  var test = this.test;\n\n  if (this.asyncOnly) {\n    test.asyncOnly = true;\n  }\n\n  if (this.allowUncaught) {\n    test.allowUncaught = true;\n    return test.run(fn);\n  }\n  try {\n    test.on('error', function(err) {\n      self.fail(test, err);\n    });\n    test.run(fn);\n  } catch (err) {\n    fn(err);\n  }\n};\n\n/**\n * Run tests in the given `suite` and invoke the callback `fn()` when complete.\n *\n * @api private\n * @param {Suite} suite\n * @param {Function} fn\n */\nRunner.prototype.runTests = function(suite, fn) {\n  var self = this;\n  var tests = suite.tests.slice();\n  var test;\n\n  function hookErr(_, errSuite, after) {\n    // before/after Each hook for errSuite failed:\n    var orig = self.suite;\n\n    // for failed 'after each' hook start from errSuite parent,\n    // otherwise start from errSuite itself\n    self.suite = after ? errSuite.parent : errSuite;\n\n    if (self.suite) {\n      // call hookUp afterEach\n      self.hookUp('afterEach', function(err2, errSuite2) {\n        self.suite = orig;\n        // some hooks may fail even now\n        if (err2) {\n          return hookErr(err2, errSuite2, true);\n        }\n        // report error suite\n        fn(errSuite);\n      });\n    } else {\n      // there is no need calling other 'after each' hooks\n      self.suite = orig;\n      fn(errSuite);\n    }\n  }\n\n  function next(err, errSuite) {\n    // if we bail after first err\n    if (self.failures && suite._bail) {\n      return fn();\n    }\n\n    if (self._abort) {\n      return fn();\n    }\n\n    if (err) {\n      return hookErr(err, errSuite, true);\n    }\n\n    // next test\n    test = tests.shift();\n\n    // all done\n    if (!test) {\n      return fn();\n    }\n\n    // grep\n    var match = self._grep.test(test.fullTitle());\n    if (self._invert) {\n      match = !match;\n    }\n    if (!match) {\n      // Run immediately only if we have defined a grep. When we\n      // define a grep — It can cause maximum callstack error if\n      // the grep is doing a large recursive loop by neglecting\n      // all tests. The run immediately function also comes with\n      // a performance cost. So we don't want to run immediately\n      // if we run the whole test suite, because running the whole\n      // test suite don't do any immediate recursive loops. Thus,\n      // allowing a JS runtime to breathe.\n      if (self._grep !== self._defaultGrep) {\n        Runner.immediately(next);\n      } else {\n        next();\n      }\n      return;\n    }\n\n    // pending\n    if (test.pending) {\n      self.emit('pending', test);\n      self.emit('test end', test);\n      return next();\n    }\n\n    // execute test and hook(s)\n    self.emit('test', self.test = test);\n    self.hookDown('beforeEach', function(err, errSuite) {\n      if (suite.pending) {\n        self.emit('pending', test);\n        self.emit('test end', test);\n        return next();\n      }\n      if (err) {\n        return hookErr(err, errSuite, false);\n      }\n      self.currentRunnable = self.test;\n      self.runTest(function(err) {\n        test = self.test;\n\n        if (err) {\n          if (err instanceof Pending) {\n            self.emit('pending', test);\n          } else {\n            self.fail(test, err);\n          }\n          self.emit('test end', test);\n\n          if (err instanceof Pending) {\n            return next();\n          }\n\n          return self.hookUp('afterEach', next);\n        }\n\n        test.state = 'passed';\n        self.emit('pass', test);\n        self.emit('test end', test);\n        self.hookUp('afterEach', next);\n      });\n    });\n  }\n\n  this.next = next;\n  this.hookErr = hookErr;\n  next();\n};\n\n/**\n * Run the given `suite` and invoke the callback `fn()` when complete.\n *\n * @api private\n * @param {Suite} suite\n * @param {Function} fn\n */\nRunner.prototype.runSuite = function(suite, fn) {\n  var i = 0;\n  var self = this;\n  var total = this.grepTotal(suite);\n  var afterAllHookCalled = false;\n\n  debug('run suite %s', suite.fullTitle());\n\n  if (!total || (self.failures && suite._bail)) {\n    return fn();\n  }\n\n  this.emit('suite', this.suite = suite);\n\n  function next(errSuite) {\n    if (errSuite) {\n      // current suite failed on a hook from errSuite\n      if (errSuite === suite) {\n        // if errSuite is current suite\n        // continue to the next sibling suite\n        return done();\n      }\n      // errSuite is among the parents of current suite\n      // stop execution of errSuite and all sub-suites\n      return done(errSuite);\n    }\n\n    if (self._abort) {\n      return done();\n    }\n\n    var curr = suite.suites[i++];\n    if (!curr) {\n      return done();\n    }\n\n    // Avoid grep neglecting large number of tests causing a\n    // huge recursive loop and thus a maximum call stack error.\n    // See comment in `this.runTests()` for more information.\n    if (self._grep !== self._defaultGrep) {\n      Runner.immediately(function() {\n        self.runSuite(curr, next);\n      });\n    } else {\n      self.runSuite(curr, next);\n    }\n  }\n\n  function done(errSuite) {\n    self.suite = suite;\n    self.nextSuite = next;\n\n    if (afterAllHookCalled) {\n      fn(errSuite);\n    } else {\n      // mark that the afterAll block has been called once\n      // and so can be skipped if there is an error in it.\n      afterAllHookCalled = true;\n      self.hook('afterAll', function() {\n        self.emit('suite end', suite);\n        fn(errSuite);\n      });\n    }\n  }\n\n  this.nextSuite = next;\n\n  this.hook('beforeAll', function(err) {\n    if (err) {\n      return done();\n    }\n    self.runTests(suite, next);\n  });\n};\n\n/**\n * Handle uncaught exceptions.\n *\n * @param {Error} err\n * @api private\n */\nRunner.prototype.uncaught = function(err) {\n  if (err) {\n    debug('uncaught exception %s', err !== function() {\n      return this;\n    }.call(err) ? err : (err.message || err));\n  } else {\n    debug('uncaught undefined exception');\n    err = undefinedError();\n  }\n  err.uncaught = true;\n\n  var runnable = this.currentRunnable;\n\n  if (!runnable) {\n    runnable = new Runnable('Uncaught error outside test suite');\n    runnable.parent = this.suite;\n\n    if (this.started) {\n      this.fail(runnable, err);\n    } else {\n      // Can't recover from this failure\n      this.emit('start');\n      this.fail(runnable, err);\n      this.emit('end');\n    }\n\n    return;\n  }\n\n  runnable.clearTimeout();\n\n  // Ignore errors if complete\n  if (runnable.state) {\n    return;\n  }\n  this.fail(runnable, err);\n\n  // recover from test\n  if (runnable.type === 'test') {\n    this.emit('test end', runnable);\n    this.hookUp('afterEach', this.next);\n    return;\n  }\n\n // recover from hooks\n  if (runnable.type === 'hook') {\n    var errSuite = this.suite;\n    // if hook failure is in afterEach block\n    if (runnable.fullTitle().indexOf('after each') > -1) {\n      return this.hookErr(err, errSuite, true);\n    }\n    // if hook failure is in beforeEach block\n    if (runnable.fullTitle().indexOf('before each') > -1) {\n      return this.hookErr(err, errSuite, false);\n    }\n    // if hook failure is in after or before blocks\n    return this.nextSuite(errSuite);\n  }\n\n  // bail\n  this.emit('end');\n};\n\n/**\n * Run the root suite and invoke `fn(failures)`\n * on completion.\n *\n * @param {Function} fn\n * @return {Runner} for chaining\n * @api public\n * @param {Function} fn\n * @return {Runner} Runner instance.\n */\nRunner.prototype.run = function(fn) {\n  var self = this;\n  var rootSuite = this.suite;\n\n  fn = fn || function() {};\n\n  function uncaught(err) {\n    self.uncaught(err);\n  }\n\n  function start() {\n    self.started = true;\n    self.emit('start');\n    self.runSuite(rootSuite, function() {\n      debug('finished running');\n      self.emit('end');\n    });\n  }\n\n  debug('start');\n\n  // callback\n  this.on('end', function() {\n    debug('end');\n    process.removeListener('uncaughtException', uncaught);\n    fn(self.failures);\n  });\n\n  // uncaught exception\n  process.on('uncaughtException', uncaught);\n\n  if (this._delay) {\n    // for reporters, I guess.\n    // might be nice to debounce some dots while we wait.\n    this.emit('waiting', rootSuite);\n    rootSuite.once('run', start);\n  } else {\n    start();\n  }\n\n  return this;\n};\n\n/**\n * Cleanly abort execution.\n *\n * @api public\n * @return {Runner} Runner instance.\n */\nRunner.prototype.abort = function() {\n  debug('aborting');\n  this._abort = true;\n\n  return this;\n};\n\n/**\n * Filter leaks with the given globals flagged as `ok`.\n *\n * @api private\n * @param {Array} ok\n * @param {Array} globals\n * @return {Array}\n */\nfunction filterLeaks(ok, globals) {\n  return filter(globals, function(key) {\n    // Firefox and Chrome exposes iframes as index inside the window object\n    if (/^d+/.test(key)) {\n      return false;\n    }\n\n    // in firefox\n    // if runner runs in an iframe, this iframe's window.getInterface method not init at first\n    // it is assigned in some seconds\n    if (global.navigator && (/^getInterface/).test(key)) {\n      return false;\n    }\n\n    // an iframe could be approached by window[iframeIndex]\n    // in ie6,7,8 and opera, iframeIndex is enumerable, this could cause leak\n    if (global.navigator && (/^\\d+/).test(key)) {\n      return false;\n    }\n\n    // Opera and IE expose global variables for HTML element IDs (issue #243)\n    if (/^mocha-/.test(key)) {\n      return false;\n    }\n\n    var matched = filter(ok, function(ok) {\n      if (~ok.indexOf('*')) {\n        return key.indexOf(ok.split('*')[0]) === 0;\n      }\n      return key === ok;\n    });\n    return !matched.length && (!global.navigator || key !== 'onerror');\n  });\n}\n\n/**\n * Array of globals dependent on the environment.\n *\n * @return {Array}\n * @api private\n */\nfunction extraGlobals() {\n  if (typeof process === 'object' && typeof process.version === 'string') {\n    var parts = process.version.split('.');\n    var nodeVersion = utils.reduce(parts, function(a, v) {\n      return a << 8 | v;\n    });\n\n    // 'errno' was renamed to process._errno in v0.9.11.\n\n    if (nodeVersion < 0x00090B) {\n      return ['errno'];\n    }\n  }\n\n  return [];\n}\n\n}).call(this,require('_process'),typeof global !== \"undefined\" ? global : typeof self !== \"undefined\" ? self : typeof window !== \"undefined\" ? window : {})\n},{\"./pending\":16,\"./runnable\":35,\"./utils\":39,\"_process\":51,\"debug\":2,\"events\":3}],37:[function(require,module,exports){\n/**\n * Module dependencies.\n */\n\nvar EventEmitter = require('events').EventEmitter;\nvar Hook = require('./hook');\nvar utils = require('./utils');\nvar inherits = utils.inherits;\nvar debug = require('debug')('mocha:suite');\nvar milliseconds = require('./ms');\n\n/**\n * Expose `Suite`.\n */\n\nexports = module.exports = Suite;\n\n/**\n * Create a new `Suite` with the given `title` and parent `Suite`. When a suite\n * with the same title is already present, that suite is returned to provide\n * nicer reporter and more flexible meta-testing.\n *\n * @api public\n * @param {Suite} parent\n * @param {string} title\n * @return {Suite}\n */\nexports.create = function(parent, title) {\n  var suite = new Suite(title, parent.ctx);\n  suite.parent = parent;\n  if (parent.pending) {\n    suite.pending = true;\n  }\n  title = suite.fullTitle();\n  parent.addSuite(suite);\n  return suite;\n};\n\n/**\n * Initialize a new `Suite` with the given `title` and `ctx`.\n *\n * @api private\n * @param {string} title\n * @param {Context} parentContext\n */\nfunction Suite(title, parentContext) {\n  this.title = title;\n  function Context() {}\n  Context.prototype = parentContext;\n  this.ctx = new Context();\n  this.suites = [];\n  this.tests = [];\n  this.pending = false;\n  this._beforeEach = [];\n  this._beforeAll = [];\n  this._afterEach = [];\n  this._afterAll = [];\n  this.root = !title;\n  this._timeout = 2000;\n  this._enableTimeouts = true;\n  this._slow = 75;\n  this._bail = false;\n  this.delayed = false;\n}\n\n/**\n * Inherit from `EventEmitter.prototype`.\n */\ninherits(Suite, EventEmitter);\n\n/**\n * Return a clone of this `Suite`.\n *\n * @api private\n * @return {Suite}\n */\nSuite.prototype.clone = function() {\n  var suite = new Suite(this.title);\n  debug('clone');\n  suite.ctx = this.ctx;\n  suite.timeout(this.timeout());\n  suite.enableTimeouts(this.enableTimeouts());\n  suite.slow(this.slow());\n  suite.bail(this.bail());\n  return suite;\n};\n\n/**\n * Set timeout `ms` or short-hand such as \"2s\".\n *\n * @api private\n * @param {number|string} ms\n * @return {Suite|number} for chaining\n */\nSuite.prototype.timeout = function(ms) {\n  if (!arguments.length) {\n    return this._timeout;\n  }\n  if (ms.toString() === '0') {\n    this._enableTimeouts = false;\n  }\n  if (typeof ms === 'string') {\n    ms = milliseconds(ms);\n  }\n  debug('timeout %d', ms);\n  this._timeout = parseInt(ms, 10);\n  return this;\n};\n\n/**\n  * Set timeout to `enabled`.\n  *\n  * @api private\n  * @param {boolean} enabled\n  * @return {Suite|boolean} self or enabled\n  */\nSuite.prototype.enableTimeouts = function(enabled) {\n  if (!arguments.length) {\n    return this._enableTimeouts;\n  }\n  debug('enableTimeouts %s', enabled);\n  this._enableTimeouts = enabled;\n  return this;\n};\n\n/**\n * Set slow `ms` or short-hand such as \"2s\".\n *\n * @api private\n * @param {number|string} ms\n * @return {Suite|number} for chaining\n */\nSuite.prototype.slow = function(ms) {\n  if (!arguments.length) {\n    return this._slow;\n  }\n  if (typeof ms === 'string') {\n    ms = milliseconds(ms);\n  }\n  debug('slow %d', ms);\n  this._slow = ms;\n  return this;\n};\n\n/**\n * Sets whether to bail after first error.\n *\n * @api private\n * @param {boolean} bail\n * @return {Suite|number} for chaining\n */\nSuite.prototype.bail = function(bail) {\n  if (!arguments.length) {\n    return this._bail;\n  }\n  debug('bail %s', bail);\n  this._bail = bail;\n  return this;\n};\n\n/**\n * Run `fn(test[, done])` before running tests.\n *\n * @api private\n * @param {string} title\n * @param {Function} fn\n * @return {Suite} for chaining\n */\nSuite.prototype.beforeAll = function(title, fn) {\n  if (this.pending) {\n    return this;\n  }\n  if (typeof title === 'function') {\n    fn = title;\n    title = fn.name;\n  }\n  title = '\"before all\" hook' + (title ? ': ' + title : '');\n\n  var hook = new Hook(title, fn);\n  hook.parent = this;\n  hook.timeout(this.timeout());\n  hook.enableTimeouts(this.enableTimeouts());\n  hook.slow(this.slow());\n  hook.ctx = this.ctx;\n  this._beforeAll.push(hook);\n  this.emit('beforeAll', hook);\n  return this;\n};\n\n/**\n * Run `fn(test[, done])` after running tests.\n *\n * @api private\n * @param {string} title\n * @param {Function} fn\n * @return {Suite} for chaining\n */\nSuite.prototype.afterAll = function(title, fn) {\n  if (this.pending) {\n    return this;\n  }\n  if (typeof title === 'function') {\n    fn = title;\n    title = fn.name;\n  }\n  title = '\"after all\" hook' + (title ? ': ' + title : '');\n\n  var hook = new Hook(title, fn);\n  hook.parent = this;\n  hook.timeout(this.timeout());\n  hook.enableTimeouts(this.enableTimeouts());\n  hook.slow(this.slow());\n  hook.ctx = this.ctx;\n  this._afterAll.push(hook);\n  this.emit('afterAll', hook);\n  return this;\n};\n\n/**\n * Run `fn(test[, done])` before each test case.\n *\n * @api private\n * @param {string} title\n * @param {Function} fn\n * @return {Suite} for chaining\n */\nSuite.prototype.beforeEach = function(title, fn) {\n  if (this.pending) {\n    return this;\n  }\n  if (typeof title === 'function') {\n    fn = title;\n    title = fn.name;\n  }\n  title = '\"before each\" hook' + (title ? ': ' + title : '');\n\n  var hook = new Hook(title, fn);\n  hook.parent = this;\n  hook.timeout(this.timeout());\n  hook.enableTimeouts(this.enableTimeouts());\n  hook.slow(this.slow());\n  hook.ctx = this.ctx;\n  this._beforeEach.push(hook);\n  this.emit('beforeEach', hook);\n  return this;\n};\n\n/**\n * Run `fn(test[, done])` after each test case.\n *\n * @api private\n * @param {string} title\n * @param {Function} fn\n * @return {Suite} for chaining\n */\nSuite.prototype.afterEach = function(title, fn) {\n  if (this.pending) {\n    return this;\n  }\n  if (typeof title === 'function') {\n    fn = title;\n    title = fn.name;\n  }\n  title = '\"after each\" hook' + (title ? ': ' + title : '');\n\n  var hook = new Hook(title, fn);\n  hook.parent = this;\n  hook.timeout(this.timeout());\n  hook.enableTimeouts(this.enableTimeouts());\n  hook.slow(this.slow());\n  hook.ctx = this.ctx;\n  this._afterEach.push(hook);\n  this.emit('afterEach', hook);\n  return this;\n};\n\n/**\n * Add a test `suite`.\n *\n * @api private\n * @param {Suite} suite\n * @return {Suite} for chaining\n */\nSuite.prototype.addSuite = function(suite) {\n  suite.parent = this;\n  suite.timeout(this.timeout());\n  suite.enableTimeouts(this.enableTimeouts());\n  suite.slow(this.slow());\n  suite.bail(this.bail());\n  this.suites.push(suite);\n  this.emit('suite', suite);\n  return this;\n};\n\n/**\n * Add a `test` to this suite.\n *\n * @api private\n * @param {Test} test\n * @return {Suite} for chaining\n */\nSuite.prototype.addTest = function(test) {\n  test.parent = this;\n  test.timeout(this.timeout());\n  test.enableTimeouts(this.enableTimeouts());\n  test.slow(this.slow());\n  test.ctx = this.ctx;\n  this.tests.push(test);\n  this.emit('test', test);\n  return this;\n};\n\n/**\n * Return the full title generated by recursively concatenating the parent's\n * full title.\n *\n * @api public\n * @return {string}\n */\nSuite.prototype.fullTitle = function() {\n  if (this.parent) {\n    var full = this.parent.fullTitle();\n    if (full) {\n      return full + ' ' + this.title;\n    }\n  }\n  return this.title;\n};\n\n/**\n * Return the total number of tests.\n *\n * @api public\n * @return {number}\n */\nSuite.prototype.total = function() {\n  return utils.reduce(this.suites, function(sum, suite) {\n    return sum + suite.total();\n  }, 0) + this.tests.length;\n};\n\n/**\n * Iterates through each suite recursively to find all tests. Applies a\n * function in the format `fn(test)`.\n *\n * @api private\n * @param {Function} fn\n * @return {Suite}\n */\nSuite.prototype.eachTest = function(fn) {\n  utils.forEach(this.tests, fn);\n  utils.forEach(this.suites, function(suite) {\n    suite.eachTest(fn);\n  });\n  return this;\n};\n\n/**\n * This will run the root suite if we happen to be running in delayed mode.\n */\nSuite.prototype.run = function run() {\n  if (this.root) {\n    this.emit('run');\n  }\n};\n\n},{\"./hook\":7,\"./ms\":15,\"./utils\":39,\"debug\":2,\"events\":3}],38:[function(require,module,exports){\n/**\n * Module dependencies.\n */\n\nvar Runnable = require('./runnable');\nvar inherits = require('./utils').inherits;\n\n/**\n * Expose `Test`.\n */\n\nmodule.exports = Test;\n\n/**\n * Initialize a new `Test` with the given `title` and callback `fn`.\n *\n * @api private\n * @param {String} title\n * @param {Function} fn\n */\nfunction Test(title, fn) {\n  Runnable.call(this, title, fn);\n  this.pending = !fn;\n  this.type = 'test';\n}\n\n/**\n * Inherit from `Runnable.prototype`.\n */\ninherits(Test, Runnable);\n\n},{\"./runnable\":35,\"./utils\":39}],39:[function(require,module,exports){\n(function (process,Buffer){\n/* eslint-env browser */\n\n/**\n * Module dependencies.\n */\n\nvar basename = require('path').basename;\nvar debug = require('debug')('mocha:watch');\nvar exists = require('fs').existsSync || require('path').existsSync;\nvar glob = require('glob');\nvar join = require('path').join;\nvar readdirSync = require('fs').readdirSync;\nvar statSync = require('fs').statSync;\nvar watchFile = require('fs').watchFile;\n\n/**\n * Ignored directories.\n */\n\nvar ignore = ['node_modules', '.git'];\n\nexports.inherits = require('util').inherits;\n\n/**\n * Escape special characters in the given string of html.\n *\n * @api private\n * @param  {string} html\n * @return {string}\n */\nexports.escape = function(html) {\n  return String(html)\n    .replace(/&/g, '&amp;')\n    .replace(/\"/g, '&quot;')\n    .replace(/</g, '&lt;')\n    .replace(/>/g, '&gt;');\n};\n\n/**\n * Array#forEach (<=IE8)\n *\n * @api private\n * @param {Array} arr\n * @param {Function} fn\n * @param {Object} scope\n */\nexports.forEach = function(arr, fn, scope) {\n  for (var i = 0, l = arr.length; i < l; i++) {\n    fn.call(scope, arr[i], i);\n  }\n};\n\n/**\n * Test if the given obj is type of string.\n *\n * @api private\n * @param {Object} obj\n * @return {boolean}\n */\nexports.isString = function(obj) {\n  return typeof obj === 'string';\n};\n\n/**\n * Array#map (<=IE8)\n *\n * @api private\n * @param {Array} arr\n * @param {Function} fn\n * @param {Object} scope\n * @return {Array}\n */\nexports.map = function(arr, fn, scope) {\n  var result = [];\n  for (var i = 0, l = arr.length; i < l; i++) {\n    result.push(fn.call(scope, arr[i], i, arr));\n  }\n  return result;\n};\n\n/**\n * Array#indexOf (<=IE8)\n *\n * @api private\n * @param {Array} arr\n * @param {Object} obj to find index of\n * @param {number} start\n * @return {number}\n */\nexports.indexOf = function(arr, obj, start) {\n  for (var i = start || 0, l = arr.length; i < l; i++) {\n    if (arr[i] === obj) {\n      return i;\n    }\n  }\n  return -1;\n};\n\n/**\n * Array#reduce (<=IE8)\n *\n * @api private\n * @param {Array} arr\n * @param {Function} fn\n * @param {Object} val Initial value.\n * @return {*}\n */\nexports.reduce = function(arr, fn, val) {\n  var rval = val;\n\n  for (var i = 0, l = arr.length; i < l; i++) {\n    rval = fn(rval, arr[i], i, arr);\n  }\n\n  return rval;\n};\n\n/**\n * Array#filter (<=IE8)\n *\n * @api private\n * @param {Array} arr\n * @param {Function} fn\n * @return {Array}\n */\nexports.filter = function(arr, fn) {\n  var ret = [];\n\n  for (var i = 0, l = arr.length; i < l; i++) {\n    var val = arr[i];\n    if (fn(val, i, arr)) {\n      ret.push(val);\n    }\n  }\n\n  return ret;\n};\n\n/**\n * Object.keys (<=IE8)\n *\n * @api private\n * @param {Object} obj\n * @return {Array} keys\n */\nexports.keys = typeof Object.keys === 'function' ? Object.keys : function(obj) {\n  var keys = [];\n  var has = Object.prototype.hasOwnProperty; // for `window` on <=IE8\n\n  for (var key in obj) {\n    if (has.call(obj, key)) {\n      keys.push(key);\n    }\n  }\n\n  return keys;\n};\n\n/**\n * Watch the given `files` for changes\n * and invoke `fn(file)` on modification.\n *\n * @api private\n * @param {Array} files\n * @param {Function} fn\n */\nexports.watch = function(files, fn) {\n  var options = { interval: 100 };\n  files.forEach(function(file) {\n    debug('file %s', file);\n    watchFile(file, options, function(curr, prev) {\n      if (prev.mtime < curr.mtime) {\n        fn(file);\n      }\n    });\n  });\n};\n\n/**\n * Array.isArray (<=IE8)\n *\n * @api private\n * @param {Object} obj\n * @return {Boolean}\n */\nvar isArray = typeof Array.isArray === 'function' ? Array.isArray : function(obj) {\n  return Object.prototype.toString.call(obj) === '[object Array]';\n};\n\n/**\n * Buffer.prototype.toJSON polyfill.\n *\n * @type {Function}\n */\nif (typeof Buffer !== 'undefined' && Buffer.prototype) {\n  Buffer.prototype.toJSON = Buffer.prototype.toJSON || function() {\n    return Array.prototype.slice.call(this, 0);\n  };\n}\n\n/**\n * Ignored files.\n *\n * @api private\n * @param {string} path\n * @return {boolean}\n */\nfunction ignored(path) {\n  return !~ignore.indexOf(path);\n}\n\n/**\n * Lookup files in the given `dir`.\n *\n * @api private\n * @param {string} dir\n * @param {string[]} [ext=['.js']]\n * @param {Array} [ret=[]]\n * @return {Array}\n */\nexports.files = function(dir, ext, ret) {\n  ret = ret || [];\n  ext = ext || ['js'];\n\n  var re = new RegExp('\\\\.(' + ext.join('|') + ')$');\n\n  readdirSync(dir)\n    .filter(ignored)\n    .forEach(function(path) {\n      path = join(dir, path);\n      if (statSync(path).isDirectory()) {\n        exports.files(path, ext, ret);\n      } else if (path.match(re)) {\n        ret.push(path);\n      }\n    });\n\n  return ret;\n};\n\n/**\n * Compute a slug from the given `str`.\n *\n * @api private\n * @param {string} str\n * @return {string}\n */\nexports.slug = function(str) {\n  return str\n    .toLowerCase()\n    .replace(/ +/g, '-')\n    .replace(/[^-\\w]/g, '');\n};\n\n/**\n * Strip the function definition from `str`, and re-indent for pre whitespace.\n *\n * @param {string} str\n * @return {string}\n */\nexports.clean = function(str) {\n  str = str\n    .replace(/\\r\\n?|[\\n\\u2028\\u2029]/g, '\\n').replace(/^\\uFEFF/, '')\n    .replace(/^function *\\(.*\\)\\s*{|\\(.*\\) *=> *{?/, '')\n    .replace(/\\s+\\}$/, '');\n\n  var spaces = str.match(/^\\n?( *)/)[1].length;\n  var tabs = str.match(/^\\n?(\\t*)/)[1].length;\n  var re = new RegExp('^\\n?' + (tabs ? '\\t' : ' ') + '{' + (tabs ? tabs : spaces) + '}', 'gm');\n\n  str = str.replace(re, '');\n\n  return exports.trim(str);\n};\n\n/**\n * Trim the given `str`.\n *\n * @api private\n * @param {string} str\n * @return {string}\n */\nexports.trim = function(str) {\n  return str.replace(/^\\s+|\\s+$/g, '');\n};\n\n/**\n * Parse the given `qs`.\n *\n * @api private\n * @param {string} qs\n * @return {Object}\n */\nexports.parseQuery = function(qs) {\n  return exports.reduce(qs.replace('?', '').split('&'), function(obj, pair) {\n    var i = pair.indexOf('=');\n    var key = pair.slice(0, i);\n    var val = pair.slice(++i);\n\n    obj[key] = decodeURIComponent(val);\n    return obj;\n  }, {});\n};\n\n/**\n * Highlight the given string of `js`.\n *\n * @api private\n * @param {string} js\n * @return {string}\n */\nfunction highlight(js) {\n  return js\n    .replace(/</g, '&lt;')\n    .replace(/>/g, '&gt;')\n    .replace(/\\/\\/(.*)/gm, '<span class=\"comment\">//$1</span>')\n    .replace(/('.*?')/gm, '<span class=\"string\">$1</span>')\n    .replace(/(\\d+\\.\\d+)/gm, '<span class=\"number\">$1</span>')\n    .replace(/(\\d+)/gm, '<span class=\"number\">$1</span>')\n    .replace(/\\bnew[ \\t]+(\\w+)/gm, '<span class=\"keyword\">new</span> <span class=\"init\">$1</span>')\n    .replace(/\\b(function|new|throw|return|var|if|else)\\b/gm, '<span class=\"keyword\">$1</span>');\n}\n\n/**\n * Highlight the contents of tag `name`.\n *\n * @api private\n * @param {string} name\n */\nexports.highlightTags = function(name) {\n  var code = document.getElementById('mocha').getElementsByTagName(name);\n  for (var i = 0, len = code.length; i < len; ++i) {\n    code[i].innerHTML = highlight(code[i].innerHTML);\n  }\n};\n\n/**\n * If a value could have properties, and has none, this function is called,\n * which returns a string representation of the empty value.\n *\n * Functions w/ no properties return `'[Function]'`\n * Arrays w/ length === 0 return `'[]'`\n * Objects w/ no properties return `'{}'`\n * All else: return result of `value.toString()`\n *\n * @api private\n * @param {*} value The value to inspect.\n * @param {string} [type] The type of the value, if known.\n * @returns {string}\n */\nfunction emptyRepresentation(value, type) {\n  type = type || exports.type(value);\n\n  switch (type) {\n    case 'function':\n      return '[Function]';\n    case 'object':\n      return '{}';\n    case 'array':\n      return '[]';\n    default:\n      return value.toString();\n  }\n}\n\n/**\n * Takes some variable and asks `Object.prototype.toString()` what it thinks it\n * is.\n *\n * @api private\n * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/toString\n * @param {*} value The value to test.\n * @returns {string}\n * @example\n * type({}) // 'object'\n * type([]) // 'array'\n * type(1) // 'number'\n * type(false) // 'boolean'\n * type(Infinity) // 'number'\n * type(null) // 'null'\n * type(new Date()) // 'date'\n * type(/foo/) // 'regexp'\n * type('type') // 'string'\n * type(global) // 'global'\n */\nexports.type = function type(value) {\n  if (value === undefined) {\n    return 'undefined';\n  } else if (value === null) {\n    return 'null';\n  } else if (typeof Buffer !== 'undefined' && Buffer.isBuffer(value)) {\n    return 'buffer';\n  }\n  return Object.prototype.toString.call(value)\n    .replace(/^\\[.+\\s(.+?)\\]$/, '$1')\n    .toLowerCase();\n};\n\n/**\n * Stringify `value`. Different behavior depending on type of value:\n *\n * - If `value` is undefined or null, return `'[undefined]'` or `'[null]'`, respectively.\n * - If `value` is not an object, function or array, return result of `value.toString()` wrapped in double-quotes.\n * - If `value` is an *empty* object, function, or array, return result of function\n *   {@link emptyRepresentation}.\n * - If `value` has properties, call {@link exports.canonicalize} on it, then return result of\n *   JSON.stringify().\n *\n * @api private\n * @see exports.type\n * @param {*} value\n * @return {string}\n */\nexports.stringify = function(value) {\n  var type = exports.type(value);\n\n  if (!~exports.indexOf(['object', 'array', 'function'], type)) {\n    if (type !== 'buffer') {\n      return jsonStringify(value);\n    }\n    var json = value.toJSON();\n    // Based on the toJSON result\n    return jsonStringify(json.data && json.type ? json.data : json, 2)\n      .replace(/,(\\n|$)/g, '$1');\n  }\n\n  for (var prop in value) {\n    if (Object.prototype.hasOwnProperty.call(value, prop)) {\n      return jsonStringify(exports.canonicalize(value), 2).replace(/,(\\n|$)/g, '$1');\n    }\n  }\n\n  return emptyRepresentation(value, type);\n};\n\n/**\n * like JSON.stringify but more sense.\n *\n * @api private\n * @param {Object}  object\n * @param {number=} spaces\n * @param {number=} depth\n * @returns {*}\n */\nfunction jsonStringify(object, spaces, depth) {\n  if (typeof spaces === 'undefined') {\n    // primitive types\n    return _stringify(object);\n  }\n\n  depth = depth || 1;\n  var space = spaces * depth;\n  var str = isArray(object) ? '[' : '{';\n  var end = isArray(object) ? ']' : '}';\n  var length = object.length || exports.keys(object).length;\n  // `.repeat()` polyfill\n  function repeat(s, n) {\n    return new Array(n).join(s);\n  }\n\n  function _stringify(val) {\n    switch (exports.type(val)) {\n      case 'null':\n      case 'undefined':\n        val = '[' + val + ']';\n        break;\n      case 'array':\n      case 'object':\n        val = jsonStringify(val, spaces, depth + 1);\n        break;\n      case 'boolean':\n      case 'regexp':\n      case 'number':\n        val = val === 0 && (1 / val) === -Infinity // `-0`\n          ? '-0'\n          : val.toString();\n        break;\n      case 'date':\n        var sDate = isNaN(val.getTime())        // Invalid date\n          ? val.toString()\n          : val.toISOString();\n        val = '[Date: ' + sDate + ']';\n        break;\n      case 'buffer':\n        var json = val.toJSON();\n        // Based on the toJSON result\n        json = json.data && json.type ? json.data : json;\n        val = '[Buffer: ' + jsonStringify(json, 2, depth + 1) + ']';\n        break;\n      default:\n        val = (val === '[Function]' || val === '[Circular]')\n          ? val\n          : JSON.stringify(val); // string\n    }\n    return val;\n  }\n\n  for (var i in object) {\n    if (!object.hasOwnProperty(i)) {\n      continue; // not my business\n    }\n    --length;\n    str += '\\n ' + repeat(' ', space)\n      + (isArray(object) ? '' : '\"' + i + '\": ') // key\n      + _stringify(object[i])                     // value\n      + (length ? ',' : '');                     // comma\n  }\n\n  return str\n    // [], {}\n    + (str.length !== 1 ? '\\n' + repeat(' ', --space) + end : end);\n}\n\n/**\n * Test if a value is a buffer.\n *\n * @api private\n * @param {*} value The value to test.\n * @return {boolean} True if `value` is a buffer, otherwise false\n */\nexports.isBuffer = function(value) {\n  return typeof Buffer !== 'undefined' && Buffer.isBuffer(value);\n};\n\n/**\n * Return a new Thing that has the keys in sorted order. Recursive.\n *\n * If the Thing...\n * - has already been seen, return string `'[Circular]'`\n * - is `undefined`, return string `'[undefined]'`\n * - is `null`, return value `null`\n * - is some other primitive, return the value\n * - is not a primitive or an `Array`, `Object`, or `Function`, return the value of the Thing's `toString()` method\n * - is a non-empty `Array`, `Object`, or `Function`, return the result of calling this function again.\n * - is an empty `Array`, `Object`, or `Function`, return the result of calling `emptyRepresentation()`\n *\n * @api private\n * @see {@link exports.stringify}\n * @param {*} value Thing to inspect.  May or may not have properties.\n * @param {Array} [stack=[]] Stack of seen values\n * @return {(Object|Array|Function|string|undefined)}\n */\nexports.canonicalize = function(value, stack) {\n  var canonicalizedObj;\n  /* eslint-disable no-unused-vars */\n  var prop;\n  /* eslint-enable no-unused-vars */\n  var type = exports.type(value);\n  function withStack(value, fn) {\n    stack.push(value);\n    fn();\n    stack.pop();\n  }\n\n  stack = stack || [];\n\n  if (exports.indexOf(stack, value) !== -1) {\n    return '[Circular]';\n  }\n\n  switch (type) {\n    case 'undefined':\n    case 'buffer':\n    case 'null':\n      canonicalizedObj = value;\n      break;\n    case 'array':\n      withStack(value, function() {\n        canonicalizedObj = exports.map(value, function(item) {\n          return exports.canonicalize(item, stack);\n        });\n      });\n      break;\n    case 'function':\n      /* eslint-disable guard-for-in */\n      for (prop in value) {\n        canonicalizedObj = {};\n        break;\n      }\n      /* eslint-enable guard-for-in */\n      if (!canonicalizedObj) {\n        canonicalizedObj = emptyRepresentation(value, type);\n        break;\n      }\n    /* falls through */\n    case 'object':\n      canonicalizedObj = canonicalizedObj || {};\n      withStack(value, function() {\n        exports.forEach(exports.keys(value).sort(), function(key) {\n          canonicalizedObj[key] = exports.canonicalize(value[key], stack);\n        });\n      });\n      break;\n    case 'date':\n    case 'number':\n    case 'regexp':\n    case 'boolean':\n      canonicalizedObj = value;\n      break;\n    default:\n      canonicalizedObj = value.toString();\n  }\n\n  return canonicalizedObj;\n};\n\n/**\n * Lookup file names at the given `path`.\n *\n * @api public\n * @param {string} path Base path to start searching from.\n * @param {string[]} extensions File extensions to look for.\n * @param {boolean} recursive Whether or not to recurse into subdirectories.\n * @return {string[]} An array of paths.\n */\nexports.lookupFiles = function lookupFiles(path, extensions, recursive) {\n  var files = [];\n  var re = new RegExp('\\\\.(' + extensions.join('|') + ')$');\n\n  if (!exists(path)) {\n    if (exists(path + '.js')) {\n      path += '.js';\n    } else {\n      files = glob.sync(path);\n      if (!files.length) {\n        throw new Error(\"cannot resolve path (or pattern) '\" + path + \"'\");\n      }\n      return files;\n    }\n  }\n\n  try {\n    var stat = statSync(path);\n    if (stat.isFile()) {\n      return path;\n    }\n  } catch (err) {\n    // ignore error\n    return;\n  }\n\n  readdirSync(path).forEach(function(file) {\n    file = join(path, file);\n    try {\n      var stat = statSync(file);\n      if (stat.isDirectory()) {\n        if (recursive) {\n          files = files.concat(lookupFiles(file, extensions, recursive));\n        }\n        return;\n      }\n    } catch (err) {\n      // ignore error\n      return;\n    }\n    if (!stat.isFile() || !re.test(file) || basename(file)[0] === '.') {\n      return;\n    }\n    files.push(file);\n  });\n\n  return files;\n};\n\n/**\n * Generate an undefined error with a message warning the user.\n *\n * @return {Error}\n */\n\nexports.undefinedError = function() {\n  return new Error('Caught undefined error, did you throw without specifying what?');\n};\n\n/**\n * Generate an undefined error if `err` is not defined.\n *\n * @param {Error} err\n * @return {Error}\n */\n\nexports.getError = function(err) {\n  return err || exports.undefinedError();\n};\n\n/**\n * @summary\n * This Filter based on `mocha-clean` module.(see: `github.com/rstacruz/mocha-clean`)\n * @description\n * When invoking this function you get a filter function that get the Error.stack as an input,\n * and return a prettify output.\n * (i.e: strip Mocha and internal node functions from stack trace).\n * @returns {Function}\n */\nexports.stackTraceFilter = function() {\n  // TODO: Replace with `process.browser`\n  var slash = '/';\n  var is = typeof document === 'undefined' ? { node: true } : { browser: true };\n  var cwd = is.node\n      ? process.cwd() + slash\n      : (typeof location === 'undefined' ? window.location : location).href.replace(/\\/[^\\/]*$/, '/');\n\n  function isMochaInternal(line) {\n    return (~line.indexOf('node_modules' + slash + 'mocha' + slash))\n      || (~line.indexOf('components' + slash + 'mochajs' + slash))\n      || (~line.indexOf('components' + slash + 'mocha' + slash))\n      || (~line.indexOf(slash + 'mocha.js'));\n  }\n\n  function isNodeInternal(line) {\n    return (~line.indexOf('(timers.js:'))\n      || (~line.indexOf('(events.js:'))\n      || (~line.indexOf('(node.js:'))\n      || (~line.indexOf('(module.js:'))\n      || (~line.indexOf('GeneratorFunctionPrototype.next (native)'))\n      || false;\n  }\n\n  return function(stack) {\n    stack = stack.split('\\n');\n\n    stack = exports.reduce(stack, function(list, line) {\n      if (isMochaInternal(line)) {\n        return list;\n      }\n\n      if (is.node && isNodeInternal(line)) {\n        return list;\n      }\n\n      // Clean up cwd(absolute)\n      list.push(line.replace(cwd, ''));\n      return list;\n    }, []);\n\n    return stack.join('\\n');\n  };\n};\n\n}).call(this,require('_process'),require(\"buffer\").Buffer)\n},{\"_process\":51,\"buffer\":43,\"debug\":2,\"fs\":41,\"glob\":41,\"path\":41,\"util\":66}],40:[function(require,module,exports){\n(function (process){\nvar WritableStream = require('stream').Writable\nvar inherits = require('util').inherits\n\nmodule.exports = BrowserStdout\n\n\ninherits(BrowserStdout, WritableStream)\n\nfunction BrowserStdout(opts) {\n  if (!(this instanceof BrowserStdout)) return new BrowserStdout(opts)\n\n  opts = opts || {}\n  WritableStream.call(this, opts)\n  this.label = (opts.label !== undefined) ? opts.label : 'stdout'\n}\n\nBrowserStdout.prototype._write = function(chunks, encoding, cb) {\n  var output = chunks.toString ? chunks.toString() : chunks\n  if (this.label === false) {\n    console.log(output)\n  } else {\n    console.log(this.label+':', output)\n  }\n  process.nextTick(cb)\n}\n\n}).call(this,require('_process'))\n},{\"_process\":51,\"stream\":63,\"util\":66}],41:[function(require,module,exports){\n\n},{}],42:[function(require,module,exports){\narguments[4][41][0].apply(exports,arguments)\n},{\"dup\":41}],43:[function(require,module,exports){\n/*!\n * The buffer module from node.js, for the browser.\n *\n * @author   Feross Aboukhadijeh <feross@feross.org> <http://feross.org>\n * @license  MIT\n */\n\nvar base64 = require('base64-js')\nvar ieee754 = require('ieee754')\nvar isArray = require('is-array')\n\nexports.Buffer = Buffer\nexports.SlowBuffer = SlowBuffer\nexports.INSPECT_MAX_BYTES = 50\nBuffer.poolSize = 8192 // not used by this implementation\n\nvar rootParent = {}\n\n/**\n * If `Buffer.TYPED_ARRAY_SUPPORT`:\n *   === true    Use Uint8Array implementation (fastest)\n *   === false   Use Object implementation (most compatible, even IE6)\n *\n * Browsers that support typed arrays are IE 10+, Firefox 4+, Chrome 7+, Safari 5.1+,\n * Opera 11.6+, iOS 4.2+.\n *\n * Due to various browser bugs, sometimes the Object implementation will be used even\n * when the browser supports typed arrays.\n *\n * Note:\n *\n *   - Firefox 4-29 lacks support for adding new properties to `Uint8Array` instances,\n *     See: https://bugzilla.mozilla.org/show_bug.cgi?id=695438.\n *\n *   - Safari 5-7 lacks support for changing the `Object.prototype.constructor` property\n *     on objects.\n *\n *   - Chrome 9-10 is missing the `TypedArray.prototype.subarray` function.\n *\n *   - IE10 has a broken `TypedArray.prototype.subarray` function which returns arrays of\n *     incorrect length in some situations.\n\n * We detect these buggy browsers and set `Buffer.TYPED_ARRAY_SUPPORT` to `false` so they\n * get the Object implementation, which is slower but behaves correctly.\n */\nBuffer.TYPED_ARRAY_SUPPORT = (function () {\n  function Bar () {}\n  try {\n    var arr = new Uint8Array(1)\n    arr.foo = function () { return 42 }\n    arr.constructor = Bar\n    return arr.foo() === 42 && // typed array instances can be augmented\n        arr.constructor === Bar && // constructor can be set\n        typeof arr.subarray === 'function' && // chrome 9-10 lack `subarray`\n        arr.subarray(1, 1).byteLength === 0 // ie10 has broken `subarray`\n  } catch (e) {\n    return false\n  }\n})()\n\nfunction kMaxLength () {\n  return Buffer.TYPED_ARRAY_SUPPORT\n    ? 0x7fffffff\n    : 0x3fffffff\n}\n\n/**\n * Class: Buffer\n * =============\n *\n * The Buffer constructor returns instances of `Uint8Array` that are augmented\n * with function properties for all the node `Buffer` API functions. We use\n * `Uint8Array` so that square bracket notation works as expected -- it returns\n * a single octet.\n *\n * By augmenting the instances, we can avoid modifying the `Uint8Array`\n * prototype.\n */\nfunction Buffer (arg) {\n  if (!(this instanceof Buffer)) {\n    // Avoid going through an ArgumentsAdaptorTrampoline in the common case.\n    if (arguments.length > 1) return new Buffer(arg, arguments[1])\n    return new Buffer(arg)\n  }\n\n  this.length = 0\n  this.parent = undefined\n\n  // Common case.\n  if (typeof arg === 'number') {\n    return fromNumber(this, arg)\n  }\n\n  // Slightly less common case.\n  if (typeof arg === 'string') {\n    return fromString(this, arg, arguments.length > 1 ? arguments[1] : 'utf8')\n  }\n\n  // Unusual.\n  return fromObject(this, arg)\n}\n\nfunction fromNumber (that, length) {\n  that = allocate(that, length < 0 ? 0 : checked(length) | 0)\n  if (!Buffer.TYPED_ARRAY_SUPPORT) {\n    for (var i = 0; i < length; i++) {\n      that[i] = 0\n    }\n  }\n  return that\n}\n\nfunction fromString (that, string, encoding) {\n  if (typeof encoding !== 'string' || encoding === '') encoding = 'utf8'\n\n  // Assumption: byteLength() return value is always < kMaxLength.\n  var length = byteLength(string, encoding) | 0\n  that = allocate(that, length)\n\n  that.write(string, encoding)\n  return that\n}\n\nfunction fromObject (that, object) {\n  if (Buffer.isBuffer(object)) return fromBuffer(that, object)\n\n  if (isArray(object)) return fromArray(that, object)\n\n  if (object == null) {\n    throw new TypeError('must start with number, buffer, array or string')\n  }\n\n  if (typeof ArrayBuffer !== 'undefined') {\n    if (object.buffer instanceof ArrayBuffer) {\n      return fromTypedArray(that, object)\n    }\n    if (object instanceof ArrayBuffer) {\n      return fromArrayBuffer(that, object)\n    }\n  }\n\n  if (object.length) return fromArrayLike(that, object)\n\n  return fromJsonObject(that, object)\n}\n\nfunction fromBuffer (that, buffer) {\n  var length = checked(buffer.length) | 0\n  that = allocate(that, length)\n  buffer.copy(that, 0, 0, length)\n  return that\n}\n\nfunction fromArray (that, array) {\n  var length = checked(array.length) | 0\n  that = allocate(that, length)\n  for (var i = 0; i < length; i += 1) {\n    that[i] = array[i] & 255\n  }\n  return that\n}\n\n// Duplicate of fromArray() to keep fromArray() monomorphic.\nfunction fromTypedArray (that, array) {\n  var length = checked(array.length) | 0\n  that = allocate(that, length)\n  // Truncating the elements is probably not what people expect from typed\n  // arrays with BYTES_PER_ELEMENT > 1 but it's compatible with the behavior\n  // of the old Buffer constructor.\n  for (var i = 0; i < length; i += 1) {\n    that[i] = array[i] & 255\n  }\n  return that\n}\n\nfunction fromArrayBuffer (that, array) {\n  if (Buffer.TYPED_ARRAY_SUPPORT) {\n    // Return an augmented `Uint8Array` instance, for best performance\n    array.byteLength\n    that = Buffer._augment(new Uint8Array(array))\n  } else {\n    // Fallback: Return an object instance of the Buffer class\n    that = fromTypedArray(that, new Uint8Array(array))\n  }\n  return that\n}\n\nfunction fromArrayLike (that, array) {\n  var length = checked(array.length) | 0\n  that = allocate(that, length)\n  for (var i = 0; i < length; i += 1) {\n    that[i] = array[i] & 255\n  }\n  return that\n}\n\n// Deserialize { type: 'Buffer', data: [1,2,3,...] } into a Buffer object.\n// Returns a zero-length buffer for inputs that don't conform to the spec.\nfunction fromJsonObject (that, object) {\n  var array\n  var length = 0\n\n  if (object.type === 'Buffer' && isArray(object.data)) {\n    array = object.data\n    length = checked(array.length) | 0\n  }\n  that = allocate(that, length)\n\n  for (var i = 0; i < length; i += 1) {\n    that[i] = array[i] & 255\n  }\n  return that\n}\n\nfunction allocate (that, length) {\n  if (Buffer.TYPED_ARRAY_SUPPORT) {\n    // Return an augmented `Uint8Array` instance, for best performance\n    that = Buffer._augment(new Uint8Array(length))\n  } else {\n    // Fallback: Return an object instance of the Buffer class\n    that.length = length\n    that._isBuffer = true\n  }\n\n  var fromPool = length !== 0 && length <= Buffer.poolSize >>> 1\n  if (fromPool) that.parent = rootParent\n\n  return that\n}\n\nfunction checked (length) {\n  // Note: cannot use `length < kMaxLength` here because that fails when\n  // length is NaN (which is otherwise coerced to zero.)\n  if (length >= kMaxLength()) {\n    throw new RangeError('Attempt to allocate Buffer larger than maximum ' +\n                         'size: 0x' + kMaxLength().toString(16) + ' bytes')\n  }\n  return length | 0\n}\n\nfunction SlowBuffer (subject, encoding) {\n  if (!(this instanceof SlowBuffer)) return new SlowBuffer(subject, encoding)\n\n  var buf = new Buffer(subject, encoding)\n  delete buf.parent\n  return buf\n}\n\nBuffer.isBuffer = function isBuffer (b) {\n  return !!(b != null && b._isBuffer)\n}\n\nBuffer.compare = function compare (a, b) {\n  if (!Buffer.isBuffer(a) || !Buffer.isBuffer(b)) {\n    throw new TypeError('Arguments must be Buffers')\n  }\n\n  if (a === b) return 0\n\n  var x = a.length\n  var y = b.length\n\n  var i = 0\n  var len = Math.min(x, y)\n  while (i < len) {\n    if (a[i] !== b[i]) break\n\n    ++i\n  }\n\n  if (i !== len) {\n    x = a[i]\n    y = b[i]\n  }\n\n  if (x < y) return -1\n  if (y < x) return 1\n  return 0\n}\n\nBuffer.isEncoding = function isEncoding (encoding) {\n  switch (String(encoding).toLowerCase()) {\n    case 'hex':\n    case 'utf8':\n    case 'utf-8':\n    case 'ascii':\n    case 'binary':\n    case 'base64':\n    case 'raw':\n    case 'ucs2':\n    case 'ucs-2':\n    case 'utf16le':\n    case 'utf-16le':\n      return true\n    default:\n      return false\n  }\n}\n\nBuffer.concat = function concat (list, length) {\n  if (!isArray(list)) throw new TypeError('list argument must be an Array of Buffers.')\n\n  if (list.length === 0) {\n    return new Buffer(0)\n  }\n\n  var i\n  if (length === undefined) {\n    length = 0\n    for (i = 0; i < list.length; i++) {\n      length += list[i].length\n    }\n  }\n\n  var buf = new Buffer(length)\n  var pos = 0\n  for (i = 0; i < list.length; i++) {\n    var item = list[i]\n    item.copy(buf, pos)\n    pos += item.length\n  }\n  return buf\n}\n\nfunction byteLength (string, encoding) {\n  if (typeof string !== 'string') string = '' + string\n\n  var len = string.length\n  if (len === 0) return 0\n\n  // Use a for loop to avoid recursion\n  var loweredCase = false\n  for (;;) {\n    switch (encoding) {\n      case 'ascii':\n      case 'binary':\n      // Deprecated\n      case 'raw':\n      case 'raws':\n        return len\n      case 'utf8':\n      case 'utf-8':\n        return utf8ToBytes(string).length\n      case 'ucs2':\n      case 'ucs-2':\n      case 'utf16le':\n      case 'utf-16le':\n        return len * 2\n      case 'hex':\n        return len >>> 1\n      case 'base64':\n        return base64ToBytes(string).length\n      default:\n        if (loweredCase) return utf8ToBytes(string).length // assume utf8\n        encoding = ('' + encoding).toLowerCase()\n        loweredCase = true\n    }\n  }\n}\nBuffer.byteLength = byteLength\n\n// pre-set for values that may exist in the future\nBuffer.prototype.length = undefined\nBuffer.prototype.parent = undefined\n\nfunction slowToString (encoding, start, end) {\n  var loweredCase = false\n\n  start = start | 0\n  end = end === undefined || end === Infinity ? this.length : end | 0\n\n  if (!encoding) encoding = 'utf8'\n  if (start < 0) start = 0\n  if (end > this.length) end = this.length\n  if (end <= start) return ''\n\n  while (true) {\n    switch (encoding) {\n      case 'hex':\n        return hexSlice(this, start, end)\n\n      case 'utf8':\n      case 'utf-8':\n        return utf8Slice(this, start, end)\n\n      case 'ascii':\n        return asciiSlice(this, start, end)\n\n      case 'binary':\n        return binarySlice(this, start, end)\n\n      case 'base64':\n        return base64Slice(this, start, end)\n\n      case 'ucs2':\n      case 'ucs-2':\n      case 'utf16le':\n      case 'utf-16le':\n        return utf16leSlice(this, start, end)\n\n      default:\n        if (loweredCase) throw new TypeError('Unknown encoding: ' + encoding)\n        encoding = (encoding + '').toLowerCase()\n        loweredCase = true\n    }\n  }\n}\n\nBuffer.prototype.toString = function toString () {\n  var length = this.length | 0\n  if (length === 0) return ''\n  if (arguments.length === 0) return utf8Slice(this, 0, length)\n  return slowToString.apply(this, arguments)\n}\n\nBuffer.prototype.equals = function equals (b) {\n  if (!Buffer.isBuffer(b)) throw new TypeError('Argument must be a Buffer')\n  if (this === b) return true\n  return Buffer.compare(this, b) === 0\n}\n\nBuffer.prototype.inspect = function inspect () {\n  var str = ''\n  var max = exports.INSPECT_MAX_BYTES\n  if (this.length > 0) {\n    str = this.toString('hex', 0, max).match(/.{2}/g).join(' ')\n    if (this.length > max) str += ' ... '\n  }\n  return '<Buffer ' + str + '>'\n}\n\nBuffer.prototype.compare = function compare (b) {\n  if (!Buffer.isBuffer(b)) throw new TypeError('Argument must be a Buffer')\n  if (this === b) return 0\n  return Buffer.compare(this, b)\n}\n\nBuffer.prototype.indexOf = function indexOf (val, byteOffset) {\n  if (byteOffset > 0x7fffffff) byteOffset = 0x7fffffff\n  else if (byteOffset < -0x80000000) byteOffset = -0x80000000\n  byteOffset >>= 0\n\n  if (this.length === 0) return -1\n  if (byteOffset >= this.length) return -1\n\n  // Negative offsets start from the end of the buffer\n  if (byteOffset < 0) byteOffset = Math.max(this.length + byteOffset, 0)\n\n  if (typeof val === 'string') {\n    if (val.length === 0) return -1 // special case: looking for empty string always fails\n    return String.prototype.indexOf.call(this, val, byteOffset)\n  }\n  if (Buffer.isBuffer(val)) {\n    return arrayIndexOf(this, val, byteOffset)\n  }\n  if (typeof val === 'number') {\n    if (Buffer.TYPED_ARRAY_SUPPORT && Uint8Array.prototype.indexOf === 'function') {\n      return Uint8Array.prototype.indexOf.call(this, val, byteOffset)\n    }\n    return arrayIndexOf(this, [ val ], byteOffset)\n  }\n\n  function arrayIndexOf (arr, val, byteOffset) {\n    var foundIndex = -1\n    for (var i = 0; byteOffset + i < arr.length; i++) {\n      if (arr[byteOffset + i] === val[foundIndex === -1 ? 0 : i - foundIndex]) {\n        if (foundIndex === -1) foundIndex = i\n        if (i - foundIndex + 1 === val.length) return byteOffset + foundIndex\n      } else {\n        foundIndex = -1\n      }\n    }\n    return -1\n  }\n\n  throw new TypeError('val must be string, number or Buffer')\n}\n\n// `get` is deprecated\nBuffer.prototype.get = function get (offset) {\n  console.log('.get() is deprecated. Access using array indexes instead.')\n  return this.readUInt8(offset)\n}\n\n// `set` is deprecated\nBuffer.prototype.set = function set (v, offset) {\n  console.log('.set() is deprecated. Access using array indexes instead.')\n  return this.writeUInt8(v, offset)\n}\n\nfunction hexWrite (buf, string, offset, length) {\n  offset = Number(offset) || 0\n  var remaining = buf.length - offset\n  if (!length) {\n    length = remaining\n  } else {\n    length = Number(length)\n    if (length > remaining) {\n      length = remaining\n    }\n  }\n\n  // must be an even number of digits\n  var strLen = string.length\n  if (strLen % 2 !== 0) throw new Error('Invalid hex string')\n\n  if (length > strLen / 2) {\n    length = strLen / 2\n  }\n  for (var i = 0; i < length; i++) {\n    var parsed = parseInt(string.substr(i * 2, 2), 16)\n    if (isNaN(parsed)) throw new Error('Invalid hex string')\n    buf[offset + i] = parsed\n  }\n  return i\n}\n\nfunction utf8Write (buf, string, offset, length) {\n  return blitBuffer(utf8ToBytes(string, buf.length - offset), buf, offset, length)\n}\n\nfunction asciiWrite (buf, string, offset, length) {\n  return blitBuffer(asciiToBytes(string), buf, offset, length)\n}\n\nfunction binaryWrite (buf, string, offset, length) {\n  return asciiWrite(buf, string, offset, length)\n}\n\nfunction base64Write (buf, string, offset, length) {\n  return blitBuffer(base64ToBytes(string), buf, offset, length)\n}\n\nfunction ucs2Write (buf, string, offset, length) {\n  return blitBuffer(utf16leToBytes(string, buf.length - offset), buf, offset, length)\n}\n\nBuffer.prototype.write = function write (string, offset, length, encoding) {\n  // Buffer#write(string)\n  if (offset === undefined) {\n    encoding = 'utf8'\n    length = this.length\n    offset = 0\n  // Buffer#write(string, encoding)\n  } else if (length === undefined && typeof offset === 'string') {\n    encoding = offset\n    length = this.length\n    offset = 0\n  // Buffer#write(string, offset[, length][, encoding])\n  } else if (isFinite(offset)) {\n    offset = offset | 0\n    if (isFinite(length)) {\n      length = length | 0\n      if (encoding === undefined) encoding = 'utf8'\n    } else {\n      encoding = length\n      length = undefined\n    }\n  // legacy write(string, encoding, offset, length) - remove in v0.13\n  } else {\n    var swap = encoding\n    encoding = offset\n    offset = length | 0\n    length = swap\n  }\n\n  var remaining = this.length - offset\n  if (length === undefined || length > remaining) length = remaining\n\n  if ((string.length > 0 && (length < 0 || offset < 0)) || offset > this.length) {\n    throw new RangeError('attempt to write outside buffer bounds')\n  }\n\n  if (!encoding) encoding = 'utf8'\n\n  var loweredCase = false\n  for (;;) {\n    switch (encoding) {\n      case 'hex':\n        return hexWrite(this, string, offset, length)\n\n      case 'utf8':\n      case 'utf-8':\n        return utf8Write(this, string, offset, length)\n\n      case 'ascii':\n        return asciiWrite(this, string, offset, length)\n\n      case 'binary':\n        return binaryWrite(this, string, offset, length)\n\n      case 'base64':\n        // Warning: maxLength not taken into account in base64Write\n        return base64Write(this, string, offset, length)\n\n      case 'ucs2':\n      case 'ucs-2':\n      case 'utf16le':\n      case 'utf-16le':\n        return ucs2Write(this, string, offset, length)\n\n      default:\n        if (loweredCase) throw new TypeError('Unknown encoding: ' + encoding)\n        encoding = ('' + encoding).toLowerCase()\n        loweredCase = true\n    }\n  }\n}\n\nBuffer.prototype.toJSON = function toJSON () {\n  return {\n    type: 'Buffer',\n    data: Array.prototype.slice.call(this._arr || this, 0)\n  }\n}\n\nfunction base64Slice (buf, start, end) {\n  if (start === 0 && end === buf.length) {\n    return base64.fromByteArray(buf)\n  } else {\n    return base64.fromByteArray(buf.slice(start, end))\n  }\n}\n\nfunction utf8Slice (buf, start, end) {\n  end = Math.min(buf.length, end)\n  var res = []\n\n  var i = start\n  while (i < end) {\n    var firstByte = buf[i]\n    var codePoint = null\n    var bytesPerSequence = (firstByte > 0xEF) ? 4\n      : (firstByte > 0xDF) ? 3\n      : (firstByte > 0xBF) ? 2\n      : 1\n\n    if (i + bytesPerSequence <= end) {\n      var secondByte, thirdByte, fourthByte, tempCodePoint\n\n      switch (bytesPerSequence) {\n        case 1:\n          if (firstByte < 0x80) {\n            codePoint = firstByte\n          }\n          break\n        case 2:\n          secondByte = buf[i + 1]\n          if ((secondByte & 0xC0) === 0x80) {\n            tempCodePoint = (firstByte & 0x1F) << 0x6 | (secondByte & 0x3F)\n            if (tempCodePoint > 0x7F) {\n              codePoint = tempCodePoint\n            }\n          }\n          break\n        case 3:\n          secondByte = buf[i + 1]\n          thirdByte = buf[i + 2]\n          if ((secondByte & 0xC0) === 0x80 && (thirdByte & 0xC0) === 0x80) {\n            tempCodePoint = (firstByte & 0xF) << 0xC | (secondByte & 0x3F) << 0x6 | (thirdByte & 0x3F)\n            if (tempCodePoint > 0x7FF && (tempCodePoint < 0xD800 || tempCodePoint > 0xDFFF)) {\n              codePoint = tempCodePoint\n            }\n          }\n          break\n        case 4:\n          secondByte = buf[i + 1]\n          thirdByte = buf[i + 2]\n          fourthByte = buf[i + 3]\n          if ((secondByte & 0xC0) === 0x80 && (thirdByte & 0xC0) === 0x80 && (fourthByte & 0xC0) === 0x80) {\n            tempCodePoint = (firstByte & 0xF) << 0x12 | (secondByte & 0x3F) << 0xC | (thirdByte & 0x3F) << 0x6 | (fourthByte & 0x3F)\n            if (tempCodePoint > 0xFFFF && tempCodePoint < 0x110000) {\n              codePoint = tempCodePoint\n            }\n          }\n      }\n    }\n\n    if (codePoint === null) {\n      // we did not generate a valid codePoint so insert a\n      // replacement char (U+FFFD) and advance only 1 byte\n      codePoint = 0xFFFD\n      bytesPerSequence = 1\n    } else if (codePoint > 0xFFFF) {\n      // encode to utf16 (surrogate pair dance)\n      codePoint -= 0x10000\n      res.push(codePoint >>> 10 & 0x3FF | 0xD800)\n      codePoint = 0xDC00 | codePoint & 0x3FF\n    }\n\n    res.push(codePoint)\n    i += bytesPerSequence\n  }\n\n  return decodeCodePointsArray(res)\n}\n\n// Based on http://stackoverflow.com/a/22747272/680742, the browser with\n// the lowest limit is Chrome, with 0x10000 args.\n// We go 1 magnitude less, for safety\nvar MAX_ARGUMENTS_LENGTH = 0x1000\n\nfunction decodeCodePointsArray (codePoints) {\n  var len = codePoints.length\n  if (len <= MAX_ARGUMENTS_LENGTH) {\n    return String.fromCharCode.apply(String, codePoints) // avoid extra slice()\n  }\n\n  // Decode in chunks to avoid \"call stack size exceeded\".\n  var res = ''\n  var i = 0\n  while (i < len) {\n    res += String.fromCharCode.apply(\n      String,\n      codePoints.slice(i, i += MAX_ARGUMENTS_LENGTH)\n    )\n  }\n  return res\n}\n\nfunction asciiSlice (buf, start, end) {\n  var ret = ''\n  end = Math.min(buf.length, end)\n\n  for (var i = start; i < end; i++) {\n    ret += String.fromCharCode(buf[i] & 0x7F)\n  }\n  return ret\n}\n\nfunction binarySlice (buf, start, end) {\n  var ret = ''\n  end = Math.min(buf.length, end)\n\n  for (var i = start; i < end; i++) {\n    ret += String.fromCharCode(buf[i])\n  }\n  return ret\n}\n\nfunction hexSlice (buf, start, end) {\n  var len = buf.length\n\n  if (!start || start < 0) start = 0\n  if (!end || end < 0 || end > len) end = len\n\n  var out = ''\n  for (var i = start; i < end; i++) {\n    out += toHex(buf[i])\n  }\n  return out\n}\n\nfunction utf16leSlice (buf, start, end) {\n  var bytes = buf.slice(start, end)\n  var res = ''\n  for (var i = 0; i < bytes.length; i += 2) {\n    res += String.fromCharCode(bytes[i] + bytes[i + 1] * 256)\n  }\n  return res\n}\n\nBuffer.prototype.slice = function slice (start, end) {\n  var len = this.length\n  start = ~~start\n  end = end === undefined ? len : ~~end\n\n  if (start < 0) {\n    start += len\n    if (start < 0) start = 0\n  } else if (start > len) {\n    start = len\n  }\n\n  if (end < 0) {\n    end += len\n    if (end < 0) end = 0\n  } else if (end > len) {\n    end = len\n  }\n\n  if (end < start) end = start\n\n  var newBuf\n  if (Buffer.TYPED_ARRAY_SUPPORT) {\n    newBuf = Buffer._augment(this.subarray(start, end))\n  } else {\n    var sliceLen = end - start\n    newBuf = new Buffer(sliceLen, undefined)\n    for (var i = 0; i < sliceLen; i++) {\n      newBuf[i] = this[i + start]\n    }\n  }\n\n  if (newBuf.length) newBuf.parent = this.parent || this\n\n  return newBuf\n}\n\n/*\n * Need to make sure that buffer isn't trying to write out of bounds.\n */\nfunction checkOffset (offset, ext, length) {\n  if ((offset % 1) !== 0 || offset < 0) throw new RangeError('offset is not uint')\n  if (offset + ext > length) throw new RangeError('Trying to access beyond buffer length')\n}\n\nBuffer.prototype.readUIntLE = function readUIntLE (offset, byteLength, noAssert) {\n  offset = offset | 0\n  byteLength = byteLength | 0\n  if (!noAssert) checkOffset(offset, byteLength, this.length)\n\n  var val = this[offset]\n  var mul = 1\n  var i = 0\n  while (++i < byteLength && (mul *= 0x100)) {\n    val += this[offset + i] * mul\n  }\n\n  return val\n}\n\nBuffer.prototype.readUIntBE = function readUIntBE (offset, byteLength, noAssert) {\n  offset = offset | 0\n  byteLength = byteLength | 0\n  if (!noAssert) {\n    checkOffset(offset, byteLength, this.length)\n  }\n\n  var val = this[offset + --byteLength]\n  var mul = 1\n  while (byteLength > 0 && (mul *= 0x100)) {\n    val += this[offset + --byteLength] * mul\n  }\n\n  return val\n}\n\nBuffer.prototype.readUInt8 = function readUInt8 (offset, noAssert) {\n  if (!noAssert) checkOffset(offset, 1, this.length)\n  return this[offset]\n}\n\nBuffer.prototype.readUInt16LE = function readUInt16LE (offset, noAssert) {\n  if (!noAssert) checkOffset(offset, 2, this.length)\n  return this[offset] | (this[offset + 1] << 8)\n}\n\nBuffer.prototype.readUInt16BE = function readUInt16BE (offset, noAssert) {\n  if (!noAssert) checkOffset(offset, 2, this.length)\n  return (this[offset] << 8) | this[offset + 1]\n}\n\nBuffer.prototype.readUInt32LE = function readUInt32LE (offset, noAssert) {\n  if (!noAssert) checkOffset(offset, 4, this.length)\n\n  return ((this[offset]) |\n      (this[offset + 1] << 8) |\n      (this[offset + 2] << 16)) +\n      (this[offset + 3] * 0x1000000)\n}\n\nBuffer.prototype.readUInt32BE = function readUInt32BE (offset, noAssert) {\n  if (!noAssert) checkOffset(offset, 4, this.length)\n\n  return (this[offset] * 0x1000000) +\n    ((this[offset + 1] << 16) |\n    (this[offset + 2] << 8) |\n    this[offset + 3])\n}\n\nBuffer.prototype.readIntLE = function readIntLE (offset, byteLength, noAssert) {\n  offset = offset | 0\n  byteLength = byteLength | 0\n  if (!noAssert) checkOffset(offset, byteLength, this.length)\n\n  var val = this[offset]\n  var mul = 1\n  var i = 0\n  while (++i < byteLength && (mul *= 0x100)) {\n    val += this[offset + i] * mul\n  }\n  mul *= 0x80\n\n  if (val >= mul) val -= Math.pow(2, 8 * byteLength)\n\n  return val\n}\n\nBuffer.prototype.readIntBE = function readIntBE (offset, byteLength, noAssert) {\n  offset = offset | 0\n  byteLength = byteLength | 0\n  if (!noAssert) checkOffset(offset, byteLength, this.length)\n\n  var i = byteLength\n  var mul = 1\n  var val = this[offset + --i]\n  while (i > 0 && (mul *= 0x100)) {\n    val += this[offset + --i] * mul\n  }\n  mul *= 0x80\n\n  if (val >= mul) val -= Math.pow(2, 8 * byteLength)\n\n  return val\n}\n\nBuffer.prototype.readInt8 = function readInt8 (offset, noAssert) {\n  if (!noAssert) checkOffset(offset, 1, this.length)\n  if (!(this[offset] & 0x80)) return (this[offset])\n  return ((0xff - this[offset] + 1) * -1)\n}\n\nBuffer.prototype.readInt16LE = function readInt16LE (offset, noAssert) {\n  if (!noAssert) checkOffset(offset, 2, this.length)\n  var val = this[offset] | (this[offset + 1] << 8)\n  return (val & 0x8000) ? val | 0xFFFF0000 : val\n}\n\nBuffer.prototype.readInt16BE = function readInt16BE (offset, noAssert) {\n  if (!noAssert) checkOffset(offset, 2, this.length)\n  var val = this[offset + 1] | (this[offset] << 8)\n  return (val & 0x8000) ? val | 0xFFFF0000 : val\n}\n\nBuffer.prototype.readInt32LE = function readInt32LE (offset, noAssert) {\n  if (!noAssert) checkOffset(offset, 4, this.length)\n\n  return (this[offset]) |\n    (this[offset + 1] << 8) |\n    (this[offset + 2] << 16) |\n    (this[offset + 3] << 24)\n}\n\nBuffer.prototype.readInt32BE = function readInt32BE (offset, noAssert) {\n  if (!noAssert) checkOffset(offset, 4, this.length)\n\n  return (this[offset] << 24) |\n    (this[offset + 1] << 16) |\n    (this[offset + 2] << 8) |\n    (this[offset + 3])\n}\n\nBuffer.prototype.readFloatLE = function readFloatLE (offset, noAssert) {\n  if (!noAssert) checkOffset(offset, 4, this.length)\n  return ieee754.read(this, offset, true, 23, 4)\n}\n\nBuffer.prototype.readFloatBE = function readFloatBE (offset, noAssert) {\n  if (!noAssert) checkOffset(offset, 4, this.length)\n  return ieee754.read(this, offset, false, 23, 4)\n}\n\nBuffer.prototype.readDoubleLE = function readDoubleLE (offset, noAssert) {\n  if (!noAssert) checkOffset(offset, 8, this.length)\n  return ieee754.read(this, offset, true, 52, 8)\n}\n\nBuffer.prototype.readDoubleBE = function readDoubleBE (offset, noAssert) {\n  if (!noAssert) checkOffset(offset, 8, this.length)\n  return ieee754.read(this, offset, false, 52, 8)\n}\n\nfunction checkInt (buf, value, offset, ext, max, min) {\n  if (!Buffer.isBuffer(buf)) throw new TypeError('buffer must be a Buffer instance')\n  if (value > max || value < min) throw new RangeError('value is out of bounds')\n  if (offset + ext > buf.length) throw new RangeError('index out of range')\n}\n\nBuffer.prototype.writeUIntLE = function writeUIntLE (value, offset, byteLength, noAssert) {\n  value = +value\n  offset = offset | 0\n  byteLength = byteLength | 0\n  if (!noAssert) checkInt(this, value, offset, byteLength, Math.pow(2, 8 * byteLength), 0)\n\n  var mul = 1\n  var i = 0\n  this[offset] = value & 0xFF\n  while (++i < byteLength && (mul *= 0x100)) {\n    this[offset + i] = (value / mul) & 0xFF\n  }\n\n  return offset + byteLength\n}\n\nBuffer.prototype.writeUIntBE = function writeUIntBE (value, offset, byteLength, noAssert) {\n  value = +value\n  offset = offset | 0\n  byteLength = byteLength | 0\n  if (!noAssert) checkInt(this, value, offset, byteLength, Math.pow(2, 8 * byteLength), 0)\n\n  var i = byteLength - 1\n  var mul = 1\n  this[offset + i] = value & 0xFF\n  while (--i >= 0 && (mul *= 0x100)) {\n    this[offset + i] = (value / mul) & 0xFF\n  }\n\n  return offset + byteLength\n}\n\nBuffer.prototype.writeUInt8 = function writeUInt8 (value, offset, noAssert) {\n  value = +value\n  offset = offset | 0\n  if (!noAssert) checkInt(this, value, offset, 1, 0xff, 0)\n  if (!Buffer.TYPED_ARRAY_SUPPORT) value = Math.floor(value)\n  this[offset] = value\n  return offset + 1\n}\n\nfunction objectWriteUInt16 (buf, value, offset, littleEndian) {\n  if (value < 0) value = 0xffff + value + 1\n  for (var i = 0, j = Math.min(buf.length - offset, 2); i < j; i++) {\n    buf[offset + i] = (value & (0xff << (8 * (littleEndian ? i : 1 - i)))) >>>\n      (littleEndian ? i : 1 - i) * 8\n  }\n}\n\nBuffer.prototype.writeUInt16LE = function writeUInt16LE (value, offset, noAssert) {\n  value = +value\n  offset = offset | 0\n  if (!noAssert) checkInt(this, value, offset, 2, 0xffff, 0)\n  if (Buffer.TYPED_ARRAY_SUPPORT) {\n    this[offset] = value\n    this[offset + 1] = (value >>> 8)\n  } else {\n    objectWriteUInt16(this, value, offset, true)\n  }\n  return offset + 2\n}\n\nBuffer.prototype.writeUInt16BE = function writeUInt16BE (value, offset, noAssert) {\n  value = +value\n  offset = offset | 0\n  if (!noAssert) checkInt(this, value, offset, 2, 0xffff, 0)\n  if (Buffer.TYPED_ARRAY_SUPPORT) {\n    this[offset] = (value >>> 8)\n    this[offset + 1] = value\n  } else {\n    objectWriteUInt16(this, value, offset, false)\n  }\n  return offset + 2\n}\n\nfunction objectWriteUInt32 (buf, value, offset, littleEndian) {\n  if (value < 0) value = 0xffffffff + value + 1\n  for (var i = 0, j = Math.min(buf.length - offset, 4); i < j; i++) {\n    buf[offset + i] = (value >>> (littleEndian ? i : 3 - i) * 8) & 0xff\n  }\n}\n\nBuffer.prototype.writeUInt32LE = function writeUInt32LE (value, offset, noAssert) {\n  value = +value\n  offset = offset | 0\n  if (!noAssert) checkInt(this, value, offset, 4, 0xffffffff, 0)\n  if (Buffer.TYPED_ARRAY_SUPPORT) {\n    this[offset + 3] = (value >>> 24)\n    this[offset + 2] = (value >>> 16)\n    this[offset + 1] = (value >>> 8)\n    this[offset] = value\n  } else {\n    objectWriteUInt32(this, value, offset, true)\n  }\n  return offset + 4\n}\n\nBuffer.prototype.writeUInt32BE = function writeUInt32BE (value, offset, noAssert) {\n  value = +value\n  offset = offset | 0\n  if (!noAssert) checkInt(this, value, offset, 4, 0xffffffff, 0)\n  if (Buffer.TYPED_ARRAY_SUPPORT) {\n    this[offset] = (value >>> 24)\n    this[offset + 1] = (value >>> 16)\n    this[offset + 2] = (value >>> 8)\n    this[offset + 3] = value\n  } else {\n    objectWriteUInt32(this, value, offset, false)\n  }\n  return offset + 4\n}\n\nBuffer.prototype.writeIntLE = function writeIntLE (value, offset, byteLength, noAssert) {\n  value = +value\n  offset = offset | 0\n  if (!noAssert) {\n    var limit = Math.pow(2, 8 * byteLength - 1)\n\n    checkInt(this, value, offset, byteLength, limit - 1, -limit)\n  }\n\n  var i = 0\n  var mul = 1\n  var sub = value < 0 ? 1 : 0\n  this[offset] = value & 0xFF\n  while (++i < byteLength && (mul *= 0x100)) {\n    this[offset + i] = ((value / mul) >> 0) - sub & 0xFF\n  }\n\n  return offset + byteLength\n}\n\nBuffer.prototype.writeIntBE = function writeIntBE (value, offset, byteLength, noAssert) {\n  value = +value\n  offset = offset | 0\n  if (!noAssert) {\n    var limit = Math.pow(2, 8 * byteLength - 1)\n\n    checkInt(this, value, offset, byteLength, limit - 1, -limit)\n  }\n\n  var i = byteLength - 1\n  var mul = 1\n  var sub = value < 0 ? 1 : 0\n  this[offset + i] = value & 0xFF\n  while (--i >= 0 && (mul *= 0x100)) {\n    this[offset + i] = ((value / mul) >> 0) - sub & 0xFF\n  }\n\n  return offset + byteLength\n}\n\nBuffer.prototype.writeInt8 = function writeInt8 (value, offset, noAssert) {\n  value = +value\n  offset = offset | 0\n  if (!noAssert) checkInt(this, value, offset, 1, 0x7f, -0x80)\n  if (!Buffer.TYPED_ARRAY_SUPPORT) value = Math.floor(value)\n  if (value < 0) value = 0xff + value + 1\n  this[offset] = value\n  return offset + 1\n}\n\nBuffer.prototype.writeInt16LE = function writeInt16LE (value, offset, noAssert) {\n  value = +value\n  offset = offset | 0\n  if (!noAssert) checkInt(this, value, offset, 2, 0x7fff, -0x8000)\n  if (Buffer.TYPED_ARRAY_SUPPORT) {\n    this[offset] = value\n    this[offset + 1] = (value >>> 8)\n  } else {\n    objectWriteUInt16(this, value, offset, true)\n  }\n  return offset + 2\n}\n\nBuffer.prototype.writeInt16BE = function writeInt16BE (value, offset, noAssert) {\n  value = +value\n  offset = offset | 0\n  if (!noAssert) checkInt(this, value, offset, 2, 0x7fff, -0x8000)\n  if (Buffer.TYPED_ARRAY_SUPPORT) {\n    this[offset] = (value >>> 8)\n    this[offset + 1] = value\n  } else {\n    objectWriteUInt16(this, value, offset, false)\n  }\n  return offset + 2\n}\n\nBuffer.prototype.writeInt32LE = function writeInt32LE (value, offset, noAssert) {\n  value = +value\n  offset = offset | 0\n  if (!noAssert) checkInt(this, value, offset, 4, 0x7fffffff, -0x80000000)\n  if (Buffer.TYPED_ARRAY_SUPPORT) {\n    this[offset] = value\n    this[offset + 1] = (value >>> 8)\n    this[offset + 2] = (value >>> 16)\n    this[offset + 3] = (value >>> 24)\n  } else {\n    objectWriteUInt32(this, value, offset, true)\n  }\n  return offset + 4\n}\n\nBuffer.prototype.writeInt32BE = function writeInt32BE (value, offset, noAssert) {\n  value = +value\n  offset = offset | 0\n  if (!noAssert) checkInt(this, value, offset, 4, 0x7fffffff, -0x80000000)\n  if (value < 0) value = 0xffffffff + value + 1\n  if (Buffer.TYPED_ARRAY_SUPPORT) {\n    this[offset] = (value >>> 24)\n    this[offset + 1] = (value >>> 16)\n    this[offset + 2] = (value >>> 8)\n    this[offset + 3] = value\n  } else {\n    objectWriteUInt32(this, value, offset, false)\n  }\n  return offset + 4\n}\n\nfunction checkIEEE754 (buf, value, offset, ext, max, min) {\n  if (value > max || value < min) throw new RangeError('value is out of bounds')\n  if (offset + ext > buf.length) throw new RangeError('index out of range')\n  if (offset < 0) throw new RangeError('index out of range')\n}\n\nfunction writeFloat (buf, value, offset, littleEndian, noAssert) {\n  if (!noAssert) {\n    checkIEEE754(buf, value, offset, 4, 3.4028234663852886e+38, -3.4028234663852886e+38)\n  }\n  ieee754.write(buf, value, offset, littleEndian, 23, 4)\n  return offset + 4\n}\n\nBuffer.prototype.writeFloatLE = function writeFloatLE (value, offset, noAssert) {\n  return writeFloat(this, value, offset, true, noAssert)\n}\n\nBuffer.prototype.writeFloatBE = function writeFloatBE (value, offset, noAssert) {\n  return writeFloat(this, value, offset, false, noAssert)\n}\n\nfunction writeDouble (buf, value, offset, littleEndian, noAssert) {\n  if (!noAssert) {\n    checkIEEE754(buf, value, offset, 8, 1.7976931348623157E+308, -1.7976931348623157E+308)\n  }\n  ieee754.write(buf, value, offset, littleEndian, 52, 8)\n  return offset + 8\n}\n\nBuffer.prototype.writeDoubleLE = function writeDoubleLE (value, offset, noAssert) {\n  return writeDouble(this, value, offset, true, noAssert)\n}\n\nBuffer.prototype.writeDoubleBE = function writeDoubleBE (value, offset, noAssert) {\n  return writeDouble(this, value, offset, false, noAssert)\n}\n\n// copy(targetBuffer, targetStart=0, sourceStart=0, sourceEnd=buffer.length)\nBuffer.prototype.copy = function copy (target, targetStart, start, end) {\n  if (!start) start = 0\n  if (!end && end !== 0) end = this.length\n  if (targetStart >= target.length) targetStart = target.length\n  if (!targetStart) targetStart = 0\n  if (end > 0 && end < start) end = start\n\n  // Copy 0 bytes; we're done\n  if (end === start) return 0\n  if (target.length === 0 || this.length === 0) return 0\n\n  // Fatal error conditions\n  if (targetStart < 0) {\n    throw new RangeError('targetStart out of bounds')\n  }\n  if (start < 0 || start >= this.length) throw new RangeError('sourceStart out of bounds')\n  if (end < 0) throw new RangeError('sourceEnd out of bounds')\n\n  // Are we oob?\n  if (end > this.length) end = this.length\n  if (target.length - targetStart < end - start) {\n    end = target.length - targetStart + start\n  }\n\n  var len = end - start\n  var i\n\n  if (this === target && start < targetStart && targetStart < end) {\n    // descending copy from end\n    for (i = len - 1; i >= 0; i--) {\n      target[i + targetStart] = this[i + start]\n    }\n  } else if (len < 1000 || !Buffer.TYPED_ARRAY_SUPPORT) {\n    // ascending copy from start\n    for (i = 0; i < len; i++) {\n      target[i + targetStart] = this[i + start]\n    }\n  } else {\n    target._set(this.subarray(start, start + len), targetStart)\n  }\n\n  return len\n}\n\n// fill(value, start=0, end=buffer.length)\nBuffer.prototype.fill = function fill (value, start, end) {\n  if (!value) value = 0\n  if (!start) start = 0\n  if (!end) end = this.length\n\n  if (end < start) throw new RangeError('end < start')\n\n  // Fill 0 bytes; we're done\n  if (end === start) return\n  if (this.length === 0) return\n\n  if (start < 0 || start >= this.length) throw new RangeError('start out of bounds')\n  if (end < 0 || end > this.length) throw new RangeError('end out of bounds')\n\n  var i\n  if (typeof value === 'number') {\n    for (i = start; i < end; i++) {\n      this[i] = value\n    }\n  } else {\n    var bytes = utf8ToBytes(value.toString())\n    var len = bytes.length\n    for (i = start; i < end; i++) {\n      this[i] = bytes[i % len]\n    }\n  }\n\n  return this\n}\n\n/**\n * Creates a new `ArrayBuffer` with the *copied* memory of the buffer instance.\n * Added in Node 0.12. Only available in browsers that support ArrayBuffer.\n */\nBuffer.prototype.toArrayBuffer = function toArrayBuffer () {\n  if (typeof Uint8Array !== 'undefined') {\n    if (Buffer.TYPED_ARRAY_SUPPORT) {\n      return (new Buffer(this)).buffer\n    } else {\n      var buf = new Uint8Array(this.length)\n      for (var i = 0, len = buf.length; i < len; i += 1) {\n        buf[i] = this[i]\n      }\n      return buf.buffer\n    }\n  } else {\n    throw new TypeError('Buffer.toArrayBuffer not supported in this browser')\n  }\n}\n\n// HELPER FUNCTIONS\n// ================\n\nvar BP = Buffer.prototype\n\n/**\n * Augment a Uint8Array *instance* (not the Uint8Array class!) with Buffer methods\n */\nBuffer._augment = function _augment (arr) {\n  arr.constructor = Buffer\n  arr._isBuffer = true\n\n  // save reference to original Uint8Array set method before overwriting\n  arr._set = arr.set\n\n  // deprecated\n  arr.get = BP.get\n  arr.set = BP.set\n\n  arr.write = BP.write\n  arr.toString = BP.toString\n  arr.toLocaleString = BP.toString\n  arr.toJSON = BP.toJSON\n  arr.equals = BP.equals\n  arr.compare = BP.compare\n  arr.indexOf = BP.indexOf\n  arr.copy = BP.copy\n  arr.slice = BP.slice\n  arr.readUIntLE = BP.readUIntLE\n  arr.readUIntBE = BP.readUIntBE\n  arr.readUInt8 = BP.readUInt8\n  arr.readUInt16LE = BP.readUInt16LE\n  arr.readUInt16BE = BP.readUInt16BE\n  arr.readUInt32LE = BP.readUInt32LE\n  arr.readUInt32BE = BP.readUInt32BE\n  arr.readIntLE = BP.readIntLE\n  arr.readIntBE = BP.readIntBE\n  arr.readInt8 = BP.readInt8\n  arr.readInt16LE = BP.readInt16LE\n  arr.readInt16BE = BP.readInt16BE\n  arr.readInt32LE = BP.readInt32LE\n  arr.readInt32BE = BP.readInt32BE\n  arr.readFloatLE = BP.readFloatLE\n  arr.readFloatBE = BP.readFloatBE\n  arr.readDoubleLE = BP.readDoubleLE\n  arr.readDoubleBE = BP.readDoubleBE\n  arr.writeUInt8 = BP.writeUInt8\n  arr.writeUIntLE = BP.writeUIntLE\n  arr.writeUIntBE = BP.writeUIntBE\n  arr.writeUInt16LE = BP.writeUInt16LE\n  arr.writeUInt16BE = BP.writeUInt16BE\n  arr.writeUInt32LE = BP.writeUInt32LE\n  arr.writeUInt32BE = BP.writeUInt32BE\n  arr.writeIntLE = BP.writeIntLE\n  arr.writeIntBE = BP.writeIntBE\n  arr.writeInt8 = BP.writeInt8\n  arr.writeInt16LE = BP.writeInt16LE\n  arr.writeInt16BE = BP.writeInt16BE\n  arr.writeInt32LE = BP.writeInt32LE\n  arr.writeInt32BE = BP.writeInt32BE\n  arr.writeFloatLE = BP.writeFloatLE\n  arr.writeFloatBE = BP.writeFloatBE\n  arr.writeDoubleLE = BP.writeDoubleLE\n  arr.writeDoubleBE = BP.writeDoubleBE\n  arr.fill = BP.fill\n  arr.inspect = BP.inspect\n  arr.toArrayBuffer = BP.toArrayBuffer\n\n  return arr\n}\n\nvar INVALID_BASE64_RE = /[^+\\/0-9A-Za-z-_]/g\n\nfunction base64clean (str) {\n  // Node strips out invalid characters like \\n and \\t from the string, base64-js does not\n  str = stringtrim(str).replace(INVALID_BASE64_RE, '')\n  // Node converts strings with length < 2 to ''\n  if (str.length < 2) return ''\n  // Node allows for non-padded base64 strings (missing trailing ===), base64-js does not\n  while (str.length % 4 !== 0) {\n    str = str + '='\n  }\n  return str\n}\n\nfunction stringtrim (str) {\n  if (str.trim) return str.trim()\n  return str.replace(/^\\s+|\\s+$/g, '')\n}\n\nfunction toHex (n) {\n  if (n < 16) return '0' + n.toString(16)\n  return n.toString(16)\n}\n\nfunction utf8ToBytes (string, units) {\n  units = units || Infinity\n  var codePoint\n  var length = string.length\n  var leadSurrogate = null\n  var bytes = []\n\n  for (var i = 0; i < length; i++) {\n    codePoint = string.charCodeAt(i)\n\n    // is surrogate component\n    if (codePoint > 0xD7FF && codePoint < 0xE000) {\n      // last char was a lead\n      if (!leadSurrogate) {\n        // no lead yet\n        if (codePoint > 0xDBFF) {\n          // unexpected trail\n          if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD)\n          continue\n        } else if (i + 1 === length) {\n          // unpaired lead\n          if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD)\n          continue\n        }\n\n        // valid lead\n        leadSurrogate = codePoint\n\n        continue\n      }\n\n      // 2 leads in a row\n      if (codePoint < 0xDC00) {\n        if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD)\n        leadSurrogate = codePoint\n        continue\n      }\n\n      // valid surrogate pair\n      codePoint = leadSurrogate - 0xD800 << 10 | codePoint - 0xDC00 | 0x10000\n    } else if (leadSurrogate) {\n      // valid bmp char, but last char was a lead\n      if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD)\n    }\n\n    leadSurrogate = null\n\n    // encode utf8\n    if (codePoint < 0x80) {\n      if ((units -= 1) < 0) break\n      bytes.push(codePoint)\n    } else if (codePoint < 0x800) {\n      if ((units -= 2) < 0) break\n      bytes.push(\n        codePoint >> 0x6 | 0xC0,\n        codePoint & 0x3F | 0x80\n      )\n    } else if (codePoint < 0x10000) {\n      if ((units -= 3) < 0) break\n      bytes.push(\n        codePoint >> 0xC | 0xE0,\n        codePoint >> 0x6 & 0x3F | 0x80,\n        codePoint & 0x3F | 0x80\n      )\n    } else if (codePoint < 0x110000) {\n      if ((units -= 4) < 0) break\n      bytes.push(\n        codePoint >> 0x12 | 0xF0,\n        codePoint >> 0xC & 0x3F | 0x80,\n        codePoint >> 0x6 & 0x3F | 0x80,\n        codePoint & 0x3F | 0x80\n      )\n    } else {\n      throw new Error('Invalid code point')\n    }\n  }\n\n  return bytes\n}\n\nfunction asciiToBytes (str) {\n  var byteArray = []\n  for (var i = 0; i < str.length; i++) {\n    // Node's code seems to be doing this and not & 0x7F..\n    byteArray.push(str.charCodeAt(i) & 0xFF)\n  }\n  return byteArray\n}\n\nfunction utf16leToBytes (str, units) {\n  var c, hi, lo\n  var byteArray = []\n  for (var i = 0; i < str.length; i++) {\n    if ((units -= 2) < 0) break\n\n    c = str.charCodeAt(i)\n    hi = c >> 8\n    lo = c % 256\n    byteArray.push(lo)\n    byteArray.push(hi)\n  }\n\n  return byteArray\n}\n\nfunction base64ToBytes (str) {\n  return base64.toByteArray(base64clean(str))\n}\n\nfunction blitBuffer (src, dst, offset, length) {\n  for (var i = 0; i < length; i++) {\n    if ((i + offset >= dst.length) || (i >= src.length)) break\n    dst[i + offset] = src[i]\n  }\n  return i\n}\n\n},{\"base64-js\":44,\"ieee754\":45,\"is-array\":46}],44:[function(require,module,exports){\nvar lookup = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';\n\n;(function (exports) {\n\t'use strict';\n\n  var Arr = (typeof Uint8Array !== 'undefined')\n    ? Uint8Array\n    : Array\n\n\tvar PLUS   = '+'.charCodeAt(0)\n\tvar SLASH  = '/'.charCodeAt(0)\n\tvar NUMBER = '0'.charCodeAt(0)\n\tvar LOWER  = 'a'.charCodeAt(0)\n\tvar UPPER  = 'A'.charCodeAt(0)\n\tvar PLUS_URL_SAFE = '-'.charCodeAt(0)\n\tvar SLASH_URL_SAFE = '_'.charCodeAt(0)\n\n\tfunction decode (elt) {\n\t\tvar code = elt.charCodeAt(0)\n\t\tif (code === PLUS ||\n\t\t    code === PLUS_URL_SAFE)\n\t\t\treturn 62 // '+'\n\t\tif (code === SLASH ||\n\t\t    code === SLASH_URL_SAFE)\n\t\t\treturn 63 // '/'\n\t\tif (code < NUMBER)\n\t\t\treturn -1 //no match\n\t\tif (code < NUMBER + 10)\n\t\t\treturn code - NUMBER + 26 + 26\n\t\tif (code < UPPER + 26)\n\t\t\treturn code - UPPER\n\t\tif (code < LOWER + 26)\n\t\t\treturn code - LOWER + 26\n\t}\n\n\tfunction b64ToByteArray (b64) {\n\t\tvar i, j, l, tmp, placeHolders, arr\n\n\t\tif (b64.length % 4 > 0) {\n\t\t\tthrow new Error('Invalid string. Length must be a multiple of 4')\n\t\t}\n\n\t\t// the number of equal signs (place holders)\n\t\t// if there are two placeholders, than the two characters before it\n\t\t// represent one byte\n\t\t// if there is only one, then the three characters before it represent 2 bytes\n\t\t// this is just a cheap hack to not do indexOf twice\n\t\tvar len = b64.length\n\t\tplaceHolders = '=' === b64.charAt(len - 2) ? 2 : '=' === b64.charAt(len - 1) ? 1 : 0\n\n\t\t// base64 is 4/3 + up to two characters of the original data\n\t\tarr = new Arr(b64.length * 3 / 4 - placeHolders)\n\n\t\t// if there are placeholders, only get up to the last complete 4 chars\n\t\tl = placeHolders > 0 ? b64.length - 4 : b64.length\n\n\t\tvar L = 0\n\n\t\tfunction push (v) {\n\t\t\tarr[L++] = v\n\t\t}\n\n\t\tfor (i = 0, j = 0; i < l; i += 4, j += 3) {\n\t\t\ttmp = (decode(b64.charAt(i)) << 18) | (decode(b64.charAt(i + 1)) << 12) | (decode(b64.charAt(i + 2)) << 6) | decode(b64.charAt(i + 3))\n\t\t\tpush((tmp & 0xFF0000) >> 16)\n\t\t\tpush((tmp & 0xFF00) >> 8)\n\t\t\tpush(tmp & 0xFF)\n\t\t}\n\n\t\tif (placeHolders === 2) {\n\t\t\ttmp = (decode(b64.charAt(i)) << 2) | (decode(b64.charAt(i + 1)) >> 4)\n\t\t\tpush(tmp & 0xFF)\n\t\t} else if (placeHolders === 1) {\n\t\t\ttmp = (decode(b64.charAt(i)) << 10) | (decode(b64.charAt(i + 1)) << 4) | (decode(b64.charAt(i + 2)) >> 2)\n\t\t\tpush((tmp >> 8) & 0xFF)\n\t\t\tpush(tmp & 0xFF)\n\t\t}\n\n\t\treturn arr\n\t}\n\n\tfunction uint8ToBase64 (uint8) {\n\t\tvar i,\n\t\t\textraBytes = uint8.length % 3, // if we have 1 byte left, pad 2 bytes\n\t\t\toutput = \"\",\n\t\t\ttemp, length\n\n\t\tfunction encode (num) {\n\t\t\treturn lookup.charAt(num)\n\t\t}\n\n\t\tfunction tripletToBase64 (num) {\n\t\t\treturn encode(num >> 18 & 0x3F) + encode(num >> 12 & 0x3F) + encode(num >> 6 & 0x3F) + encode(num & 0x3F)\n\t\t}\n\n\t\t// go through the array every three bytes, we'll deal with trailing stuff later\n\t\tfor (i = 0, length = uint8.length - extraBytes; i < length; i += 3) {\n\t\t\ttemp = (uint8[i] << 16) + (uint8[i + 1] << 8) + (uint8[i + 2])\n\t\t\toutput += tripletToBase64(temp)\n\t\t}\n\n\t\t// pad the end with zeros, but make sure to not forget the extra bytes\n\t\tswitch (extraBytes) {\n\t\t\tcase 1:\n\t\t\t\ttemp = uint8[uint8.length - 1]\n\t\t\t\toutput += encode(temp >> 2)\n\t\t\t\toutput += encode((temp << 4) & 0x3F)\n\t\t\t\toutput += '=='\n\t\t\t\tbreak\n\t\t\tcase 2:\n\t\t\t\ttemp = (uint8[uint8.length - 2] << 8) + (uint8[uint8.length - 1])\n\t\t\t\toutput += encode(temp >> 10)\n\t\t\t\toutput += encode((temp >> 4) & 0x3F)\n\t\t\t\toutput += encode((temp << 2) & 0x3F)\n\t\t\t\toutput += '='\n\t\t\t\tbreak\n\t\t}\n\n\t\treturn output\n\t}\n\n\texports.toByteArray = b64ToByteArray\n\texports.fromByteArray = uint8ToBase64\n}(typeof exports === 'undefined' ? (this.base64js = {}) : exports))\n\n},{}],45:[function(require,module,exports){\nexports.read = function (buffer, offset, isLE, mLen, nBytes) {\n  var e, m\n  var eLen = nBytes * 8 - mLen - 1\n  var eMax = (1 << eLen) - 1\n  var eBias = eMax >> 1\n  var nBits = -7\n  var i = isLE ? (nBytes - 1) : 0\n  var d = isLE ? -1 : 1\n  var s = buffer[offset + i]\n\n  i += d\n\n  e = s & ((1 << (-nBits)) - 1)\n  s >>= (-nBits)\n  nBits += eLen\n  for (; nBits > 0; e = e * 256 + buffer[offset + i], i += d, nBits -= 8) {}\n\n  m = e & ((1 << (-nBits)) - 1)\n  e >>= (-nBits)\n  nBits += mLen\n  for (; nBits > 0; m = m * 256 + buffer[offset + i], i += d, nBits -= 8) {}\n\n  if (e === 0) {\n    e = 1 - eBias\n  } else if (e === eMax) {\n    return m ? NaN : ((s ? -1 : 1) * Infinity)\n  } else {\n    m = m + Math.pow(2, mLen)\n    e = e - eBias\n  }\n  return (s ? -1 : 1) * m * Math.pow(2, e - mLen)\n}\n\nexports.write = function (buffer, value, offset, isLE, mLen, nBytes) {\n  var e, m, c\n  var eLen = nBytes * 8 - mLen - 1\n  var eMax = (1 << eLen) - 1\n  var eBias = eMax >> 1\n  var rt = (mLen === 23 ? Math.pow(2, -24) - Math.pow(2, -77) : 0)\n  var i = isLE ? 0 : (nBytes - 1)\n  var d = isLE ? 1 : -1\n  var s = value < 0 || (value === 0 && 1 / value < 0) ? 1 : 0\n\n  value = Math.abs(value)\n\n  if (isNaN(value) || value === Infinity) {\n    m = isNaN(value) ? 1 : 0\n    e = eMax\n  } else {\n    e = Math.floor(Math.log(value) / Math.LN2)\n    if (value * (c = Math.pow(2, -e)) < 1) {\n      e--\n      c *= 2\n    }\n    if (e + eBias >= 1) {\n      value += rt / c\n    } else {\n      value += rt * Math.pow(2, 1 - eBias)\n    }\n    if (value * c >= 2) {\n      e++\n      c /= 2\n    }\n\n    if (e + eBias >= eMax) {\n      m = 0\n      e = eMax\n    } else if (e + eBias >= 1) {\n      m = (value * c - 1) * Math.pow(2, mLen)\n      e = e + eBias\n    } else {\n      m = value * Math.pow(2, eBias - 1) * Math.pow(2, mLen)\n      e = 0\n    }\n  }\n\n  for (; mLen >= 8; buffer[offset + i] = m & 0xff, i += d, m /= 256, mLen -= 8) {}\n\n  e = (e << mLen) | m\n  eLen += mLen\n  for (; eLen > 0; buffer[offset + i] = e & 0xff, i += d, e /= 256, eLen -= 8) {}\n\n  buffer[offset + i - d] |= s * 128\n}\n\n},{}],46:[function(require,module,exports){\n\n/**\n * isArray\n */\n\nvar isArray = Array.isArray;\n\n/**\n * toString\n */\n\nvar str = Object.prototype.toString;\n\n/**\n * Whether or not the given `val`\n * is an array.\n *\n * example:\n *\n *        isArray([]);\n *        // > true\n *        isArray(arguments);\n *        // > false\n *        isArray('');\n *        // > false\n *\n * @param {mixed} val\n * @return {bool}\n */\n\nmodule.exports = isArray || function (val) {\n  return !! val && '[object Array]' == str.call(val);\n};\n\n},{}],47:[function(require,module,exports){\n// Copyright Joyent, Inc. and other Node contributors.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a\n// copy of this software and associated documentation files (the\n// \"Software\"), to deal in the Software without restriction, including\n// without limitation the rights to use, copy, modify, merge, publish,\n// distribute, sublicense, and/or sell copies of the Software, and to permit\n// persons to whom the Software is furnished to do so, subject to the\n// following conditions:\n//\n// The above copyright notice and this permission notice shall be included\n// in all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS\n// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN\n// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,\n// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE\n// USE OR OTHER DEALINGS IN THE SOFTWARE.\n\nfunction EventEmitter() {\n  this._events = this._events || {};\n  this._maxListeners = this._maxListeners || undefined;\n}\nmodule.exports = EventEmitter;\n\n// Backwards-compat with node 0.10.x\nEventEmitter.EventEmitter = EventEmitter;\n\nEventEmitter.prototype._events = undefined;\nEventEmitter.prototype._maxListeners = undefined;\n\n// By default EventEmitters will print a warning if more than 10 listeners are\n// added to it. This is a useful default which helps finding memory leaks.\nEventEmitter.defaultMaxListeners = 10;\n\n// Obviously not all Emitters should be limited to 10. This function allows\n// that to be increased. Set to zero for unlimited.\nEventEmitter.prototype.setMaxListeners = function(n) {\n  if (!isNumber(n) || n < 0 || isNaN(n))\n    throw TypeError('n must be a positive number');\n  this._maxListeners = n;\n  return this;\n};\n\nEventEmitter.prototype.emit = function(type) {\n  var er, handler, len, args, i, listeners;\n\n  if (!this._events)\n    this._events = {};\n\n  // If there is no 'error' event listener then throw.\n  if (type === 'error') {\n    if (!this._events.error ||\n        (isObject(this._events.error) && !this._events.error.length)) {\n      er = arguments[1];\n      if (er instanceof Error) {\n        throw er; // Unhandled 'error' event\n      }\n      throw TypeError('Uncaught, unspecified \"error\" event.');\n    }\n  }\n\n  handler = this._events[type];\n\n  if (isUndefined(handler))\n    return false;\n\n  if (isFunction(handler)) {\n    switch (arguments.length) {\n      // fast cases\n      case 1:\n        handler.call(this);\n        break;\n      case 2:\n        handler.call(this, arguments[1]);\n        break;\n      case 3:\n        handler.call(this, arguments[1], arguments[2]);\n        break;\n      // slower\n      default:\n        len = arguments.length;\n        args = new Array(len - 1);\n        for (i = 1; i < len; i++)\n          args[i - 1] = arguments[i];\n        handler.apply(this, args);\n    }\n  } else if (isObject(handler)) {\n    len = arguments.length;\n    args = new Array(len - 1);\n    for (i = 1; i < len; i++)\n      args[i - 1] = arguments[i];\n\n    listeners = handler.slice();\n    len = listeners.length;\n    for (i = 0; i < len; i++)\n      listeners[i].apply(this, args);\n  }\n\n  return true;\n};\n\nEventEmitter.prototype.addListener = function(type, listener) {\n  var m;\n\n  if (!isFunction(listener))\n    throw TypeError('listener must be a function');\n\n  if (!this._events)\n    this._events = {};\n\n  // To avoid recursion in the case that type === \"newListener\"! Before\n  // adding it to the listeners, first emit \"newListener\".\n  if (this._events.newListener)\n    this.emit('newListener', type,\n              isFunction(listener.listener) ?\n              listener.listener : listener);\n\n  if (!this._events[type])\n    // Optimize the case of one listener. Don't need the extra array object.\n    this._events[type] = listener;\n  else if (isObject(this._events[type]))\n    // If we've already got an array, just append.\n    this._events[type].push(listener);\n  else\n    // Adding the second element, need to change to array.\n    this._events[type] = [this._events[type], listener];\n\n  // Check for listener leak\n  if (isObject(this._events[type]) && !this._events[type].warned) {\n    var m;\n    if (!isUndefined(this._maxListeners)) {\n      m = this._maxListeners;\n    } else {\n      m = EventEmitter.defaultMaxListeners;\n    }\n\n    if (m && m > 0 && this._events[type].length > m) {\n      this._events[type].warned = true;\n      console.error('(node) warning: possible EventEmitter memory ' +\n                    'leak detected. %d listeners added. ' +\n                    'Use emitter.setMaxListeners() to increase limit.',\n                    this._events[type].length);\n      if (typeof console.trace === 'function') {\n        // not supported in IE 10\n        console.trace();\n      }\n    }\n  }\n\n  return this;\n};\n\nEventEmitter.prototype.on = EventEmitter.prototype.addListener;\n\nEventEmitter.prototype.once = function(type, listener) {\n  if (!isFunction(listener))\n    throw TypeError('listener must be a function');\n\n  var fired = false;\n\n  function g() {\n    this.removeListener(type, g);\n\n    if (!fired) {\n      fired = true;\n      listener.apply(this, arguments);\n    }\n  }\n\n  g.listener = listener;\n  this.on(type, g);\n\n  return this;\n};\n\n// emits a 'removeListener' event iff the listener was removed\nEventEmitter.prototype.removeListener = function(type, listener) {\n  var list, position, length, i;\n\n  if (!isFunction(listener))\n    throw TypeError('listener must be a function');\n\n  if (!this._events || !this._events[type])\n    return this;\n\n  list = this._events[type];\n  length = list.length;\n  position = -1;\n\n  if (list === listener ||\n      (isFunction(list.listener) && list.listener === listener)) {\n    delete this._events[type];\n    if (this._events.removeListener)\n      this.emit('removeListener', type, listener);\n\n  } else if (isObject(list)) {\n    for (i = length; i-- > 0;) {\n      if (list[i] === listener ||\n          (list[i].listener && list[i].listener === listener)) {\n        position = i;\n        break;\n      }\n    }\n\n    if (position < 0)\n      return this;\n\n    if (list.length === 1) {\n      list.length = 0;\n      delete this._events[type];\n    } else {\n      list.splice(position, 1);\n    }\n\n    if (this._events.removeListener)\n      this.emit('removeListener', type, listener);\n  }\n\n  return this;\n};\n\nEventEmitter.prototype.removeAllListeners = function(type) {\n  var key, listeners;\n\n  if (!this._events)\n    return this;\n\n  // not listening for removeListener, no need to emit\n  if (!this._events.removeListener) {\n    if (arguments.length === 0)\n      this._events = {};\n    else if (this._events[type])\n      delete this._events[type];\n    return this;\n  }\n\n  // emit removeListener for all listeners on all events\n  if (arguments.length === 0) {\n    for (key in this._events) {\n      if (key === 'removeListener') continue;\n      this.removeAllListeners(key);\n    }\n    this.removeAllListeners('removeListener');\n    this._events = {};\n    return this;\n  }\n\n  listeners = this._events[type];\n\n  if (isFunction(listeners)) {\n    this.removeListener(type, listeners);\n  } else {\n    // LIFO order\n    while (listeners.length)\n      this.removeListener(type, listeners[listeners.length - 1]);\n  }\n  delete this._events[type];\n\n  return this;\n};\n\nEventEmitter.prototype.listeners = function(type) {\n  var ret;\n  if (!this._events || !this._events[type])\n    ret = [];\n  else if (isFunction(this._events[type]))\n    ret = [this._events[type]];\n  else\n    ret = this._events[type].slice();\n  return ret;\n};\n\nEventEmitter.listenerCount = function(emitter, type) {\n  var ret;\n  if (!emitter._events || !emitter._events[type])\n    ret = 0;\n  else if (isFunction(emitter._events[type]))\n    ret = 1;\n  else\n    ret = emitter._events[type].length;\n  return ret;\n};\n\nfunction isFunction(arg) {\n  return typeof arg === 'function';\n}\n\nfunction isNumber(arg) {\n  return typeof arg === 'number';\n}\n\nfunction isObject(arg) {\n  return typeof arg === 'object' && arg !== null;\n}\n\nfunction isUndefined(arg) {\n  return arg === void 0;\n}\n\n},{}],48:[function(require,module,exports){\nif (typeof Object.create === 'function') {\n  // implementation from standard node.js 'util' module\n  module.exports = function inherits(ctor, superCtor) {\n    ctor.super_ = superCtor\n    ctor.prototype = Object.create(superCtor.prototype, {\n      constructor: {\n        value: ctor,\n        enumerable: false,\n        writable: true,\n        configurable: true\n      }\n    });\n  };\n} else {\n  // old school shim for old browsers\n  module.exports = function inherits(ctor, superCtor) {\n    ctor.super_ = superCtor\n    var TempCtor = function () {}\n    TempCtor.prototype = superCtor.prototype\n    ctor.prototype = new TempCtor()\n    ctor.prototype.constructor = ctor\n  }\n}\n\n},{}],49:[function(require,module,exports){\nmodule.exports = Array.isArray || function (arr) {\n  return Object.prototype.toString.call(arr) == '[object Array]';\n};\n\n},{}],50:[function(require,module,exports){\nexports.endianness = function () { return 'LE' };\n\nexports.hostname = function () {\n    if (typeof location !== 'undefined') {\n        return location.hostname\n    }\n    else return '';\n};\n\nexports.loadavg = function () { return [] };\n\nexports.uptime = function () { return 0 };\n\nexports.freemem = function () {\n    return Number.MAX_VALUE;\n};\n\nexports.totalmem = function () {\n    return Number.MAX_VALUE;\n};\n\nexports.cpus = function () { return [] };\n\nexports.type = function () { return 'Browser' };\n\nexports.release = function () {\n    if (typeof navigator !== 'undefined') {\n        return navigator.appVersion;\n    }\n    return '';\n};\n\nexports.networkInterfaces\n= exports.getNetworkInterfaces\n= function () { return {} };\n\nexports.arch = function () { return 'javascript' };\n\nexports.platform = function () { return 'browser' };\n\nexports.tmpdir = exports.tmpDir = function () {\n    return '/tmp';\n};\n\nexports.EOL = '\\n';\n\n},{}],51:[function(require,module,exports){\n// shim for using process in browser\n\nvar process = module.exports = {};\nvar queue = [];\nvar draining = false;\nvar currentQueue;\nvar queueIndex = -1;\n\nfunction cleanUpNextTick() {\n    draining = false;\n    if (currentQueue.length) {\n        queue = currentQueue.concat(queue);\n    } else {\n        queueIndex = -1;\n    }\n    if (queue.length) {\n        drainQueue();\n    }\n}\n\nfunction drainQueue() {\n    if (draining) {\n        return;\n    }\n    var timeout = setTimeout(cleanUpNextTick);\n    draining = true;\n\n    var len = queue.length;\n    while(len) {\n        currentQueue = queue;\n        queue = [];\n        while (++queueIndex < len) {\n            if (currentQueue) {\n                currentQueue[queueIndex].run();\n            }\n        }\n        queueIndex = -1;\n        len = queue.length;\n    }\n    currentQueue = null;\n    draining = false;\n    clearTimeout(timeout);\n}\n\nprocess.nextTick = function (fun) {\n    var args = new Array(arguments.length - 1);\n    if (arguments.length > 1) {\n        for (var i = 1; i < arguments.length; i++) {\n            args[i - 1] = arguments[i];\n        }\n    }\n    queue.push(new Item(fun, args));\n    if (queue.length === 1 && !draining) {\n        setTimeout(drainQueue, 0);\n    }\n};\n\n// v8 likes predictible objects\nfunction Item(fun, array) {\n    this.fun = fun;\n    this.array = array;\n}\nItem.prototype.run = function () {\n    this.fun.apply(null, this.array);\n};\nprocess.title = 'browser';\nprocess.browser = true;\nprocess.env = {};\nprocess.argv = [];\nprocess.version = ''; // empty string to avoid regexp issues\nprocess.versions = {};\n\nfunction noop() {}\n\nprocess.on = noop;\nprocess.addListener = noop;\nprocess.once = noop;\nprocess.off = noop;\nprocess.removeListener = noop;\nprocess.removeAllListeners = noop;\nprocess.emit = noop;\n\nprocess.binding = function (name) {\n    throw new Error('process.binding is not supported');\n};\n\nprocess.cwd = function () { return '/' };\nprocess.chdir = function (dir) {\n    throw new Error('process.chdir is not supported');\n};\nprocess.umask = function() { return 0; };\n\n},{}],52:[function(require,module,exports){\nmodule.exports = require(\"./lib/_stream_duplex.js\")\n\n},{\"./lib/_stream_duplex.js\":53}],53:[function(require,module,exports){\n(function (process){\n// Copyright Joyent, Inc. and other Node contributors.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a\n// copy of this software and associated documentation files (the\n// \"Software\"), to deal in the Software without restriction, including\n// without limitation the rights to use, copy, modify, merge, publish,\n// distribute, sublicense, and/or sell copies of the Software, and to permit\n// persons to whom the Software is furnished to do so, subject to the\n// following conditions:\n//\n// The above copyright notice and this permission notice shall be included\n// in all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS\n// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN\n// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,\n// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE\n// USE OR OTHER DEALINGS IN THE SOFTWARE.\n\n// a duplex stream is just a stream that is both readable and writable.\n// Since JS doesn't have multiple prototypal inheritance, this class\n// prototypally inherits from Readable, and then parasitically from\n// Writable.\n\nmodule.exports = Duplex;\n\n/*<replacement>*/\nvar objectKeys = Object.keys || function (obj) {\n  var keys = [];\n  for (var key in obj) keys.push(key);\n  return keys;\n}\n/*</replacement>*/\n\n\n/*<replacement>*/\nvar util = require('core-util-is');\nutil.inherits = require('inherits');\n/*</replacement>*/\n\nvar Readable = require('./_stream_readable');\nvar Writable = require('./_stream_writable');\n\nutil.inherits(Duplex, Readable);\n\nforEach(objectKeys(Writable.prototype), function(method) {\n  if (!Duplex.prototype[method])\n    Duplex.prototype[method] = Writable.prototype[method];\n});\n\nfunction Duplex(options) {\n  if (!(this instanceof Duplex))\n    return new Duplex(options);\n\n  Readable.call(this, options);\n  Writable.call(this, options);\n\n  if (options && options.readable === false)\n    this.readable = false;\n\n  if (options && options.writable === false)\n    this.writable = false;\n\n  this.allowHalfOpen = true;\n  if (options && options.allowHalfOpen === false)\n    this.allowHalfOpen = false;\n\n  this.once('end', onend);\n}\n\n// the no-half-open enforcer\nfunction onend() {\n  // if we allow half-open state, or if the writable side ended,\n  // then we're ok.\n  if (this.allowHalfOpen || this._writableState.ended)\n    return;\n\n  // no more data can be written.\n  // But allow more writes to happen in this tick.\n  process.nextTick(this.end.bind(this));\n}\n\nfunction forEach (xs, f) {\n  for (var i = 0, l = xs.length; i < l; i++) {\n    f(xs[i], i);\n  }\n}\n\n}).call(this,require('_process'))\n},{\"./_stream_readable\":55,\"./_stream_writable\":57,\"_process\":51,\"core-util-is\":58,\"inherits\":48}],54:[function(require,module,exports){\n// Copyright Joyent, Inc. and other Node contributors.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a\n// copy of this software and associated documentation files (the\n// \"Software\"), to deal in the Software without restriction, including\n// without limitation the rights to use, copy, modify, merge, publish,\n// distribute, sublicense, and/or sell copies of the Software, and to permit\n// persons to whom the Software is furnished to do so, subject to the\n// following conditions:\n//\n// The above copyright notice and this permission notice shall be included\n// in all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS\n// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN\n// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,\n// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE\n// USE OR OTHER DEALINGS IN THE SOFTWARE.\n\n// a passthrough stream.\n// basically just the most minimal sort of Transform stream.\n// Every written chunk gets output as-is.\n\nmodule.exports = PassThrough;\n\nvar Transform = require('./_stream_transform');\n\n/*<replacement>*/\nvar util = require('core-util-is');\nutil.inherits = require('inherits');\n/*</replacement>*/\n\nutil.inherits(PassThrough, Transform);\n\nfunction PassThrough(options) {\n  if (!(this instanceof PassThrough))\n    return new PassThrough(options);\n\n  Transform.call(this, options);\n}\n\nPassThrough.prototype._transform = function(chunk, encoding, cb) {\n  cb(null, chunk);\n};\n\n},{\"./_stream_transform\":56,\"core-util-is\":58,\"inherits\":48}],55:[function(require,module,exports){\n(function (process){\n// Copyright Joyent, Inc. and other Node contributors.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a\n// copy of this software and associated documentation files (the\n// \"Software\"), to deal in the Software without restriction, including\n// without limitation the rights to use, copy, modify, merge, publish,\n// distribute, sublicense, and/or sell copies of the Software, and to permit\n// persons to whom the Software is furnished to do so, subject to the\n// following conditions:\n//\n// The above copyright notice and this permission notice shall be included\n// in all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS\n// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN\n// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,\n// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE\n// USE OR OTHER DEALINGS IN THE SOFTWARE.\n\nmodule.exports = Readable;\n\n/*<replacement>*/\nvar isArray = require('isarray');\n/*</replacement>*/\n\n\n/*<replacement>*/\nvar Buffer = require('buffer').Buffer;\n/*</replacement>*/\n\nReadable.ReadableState = ReadableState;\n\nvar EE = require('events').EventEmitter;\n\n/*<replacement>*/\nif (!EE.listenerCount) EE.listenerCount = function(emitter, type) {\n  return emitter.listeners(type).length;\n};\n/*</replacement>*/\n\nvar Stream = require('stream');\n\n/*<replacement>*/\nvar util = require('core-util-is');\nutil.inherits = require('inherits');\n/*</replacement>*/\n\nvar StringDecoder;\n\n\n/*<replacement>*/\nvar debug = require('util');\nif (debug && debug.debuglog) {\n  debug = debug.debuglog('stream');\n} else {\n  debug = function () {};\n}\n/*</replacement>*/\n\n\nutil.inherits(Readable, Stream);\n\nfunction ReadableState(options, stream) {\n  var Duplex = require('./_stream_duplex');\n\n  options = options || {};\n\n  // the point at which it stops calling _read() to fill the buffer\n  // Note: 0 is a valid value, means \"don't call _read preemptively ever\"\n  var hwm = options.highWaterMark;\n  var defaultHwm = options.objectMode ? 16 : 16 * 1024;\n  this.highWaterMark = (hwm || hwm === 0) ? hwm : defaultHwm;\n\n  // cast to ints.\n  this.highWaterMark = ~~this.highWaterMark;\n\n  this.buffer = [];\n  this.length = 0;\n  this.pipes = null;\n  this.pipesCount = 0;\n  this.flowing = null;\n  this.ended = false;\n  this.endEmitted = false;\n  this.reading = false;\n\n  // a flag to be able to tell if the onwrite cb is called immediately,\n  // or on a later tick.  We set this to true at first, because any\n  // actions that shouldn't happen until \"later\" should generally also\n  // not happen before the first write call.\n  this.sync = true;\n\n  // whenever we return null, then we set a flag to say\n  // that we're awaiting a 'readable' event emission.\n  this.needReadable = false;\n  this.emittedReadable = false;\n  this.readableListening = false;\n\n\n  // object stream flag. Used to make read(n) ignore n and to\n  // make all the buffer merging and length checks go away\n  this.objectMode = !!options.objectMode;\n\n  if (stream instanceof Duplex)\n    this.objectMode = this.objectMode || !!options.readableObjectMode;\n\n  // Crypto is kind of old and crusty.  Historically, its default string\n  // encoding is 'binary' so we have to make this configurable.\n  // Everything else in the universe uses 'utf8', though.\n  this.defaultEncoding = options.defaultEncoding || 'utf8';\n\n  // when piping, we only care about 'readable' events that happen\n  // after read()ing all the bytes and not getting any pushback.\n  this.ranOut = false;\n\n  // the number of writers that are awaiting a drain event in .pipe()s\n  this.awaitDrain = 0;\n\n  // if true, a maybeReadMore has been scheduled\n  this.readingMore = false;\n\n  this.decoder = null;\n  this.encoding = null;\n  if (options.encoding) {\n    if (!StringDecoder)\n      StringDecoder = require('string_decoder/').StringDecoder;\n    this.decoder = new StringDecoder(options.encoding);\n    this.encoding = options.encoding;\n  }\n}\n\nfunction Readable(options) {\n  var Duplex = require('./_stream_duplex');\n\n  if (!(this instanceof Readable))\n    return new Readable(options);\n\n  this._readableState = new ReadableState(options, this);\n\n  // legacy\n  this.readable = true;\n\n  Stream.call(this);\n}\n\n// Manually shove something into the read() buffer.\n// This returns true if the highWaterMark has not been hit yet,\n// similar to how Writable.write() returns true if you should\n// write() some more.\nReadable.prototype.push = function(chunk, encoding) {\n  var state = this._readableState;\n\n  if (util.isString(chunk) && !state.objectMode) {\n    encoding = encoding || state.defaultEncoding;\n    if (encoding !== state.encoding) {\n      chunk = new Buffer(chunk, encoding);\n      encoding = '';\n    }\n  }\n\n  return readableAddChunk(this, state, chunk, encoding, false);\n};\n\n// Unshift should *always* be something directly out of read()\nReadable.prototype.unshift = function(chunk) {\n  var state = this._readableState;\n  return readableAddChunk(this, state, chunk, '', true);\n};\n\nfunction readableAddChunk(stream, state, chunk, encoding, addToFront) {\n  var er = chunkInvalid(state, chunk);\n  if (er) {\n    stream.emit('error', er);\n  } else if (util.isNullOrUndefined(chunk)) {\n    state.reading = false;\n    if (!state.ended)\n      onEofChunk(stream, state);\n  } else if (state.objectMode || chunk && chunk.length > 0) {\n    if (state.ended && !addToFront) {\n      var e = new Error('stream.push() after EOF');\n      stream.emit('error', e);\n    } else if (state.endEmitted && addToFront) {\n      var e = new Error('stream.unshift() after end event');\n      stream.emit('error', e);\n    } else {\n      if (state.decoder && !addToFront && !encoding)\n        chunk = state.decoder.write(chunk);\n\n      if (!addToFront)\n        state.reading = false;\n\n      // if we want the data now, just emit it.\n      if (state.flowing && state.length === 0 && !state.sync) {\n        stream.emit('data', chunk);\n        stream.read(0);\n      } else {\n        // update the buffer info.\n        state.length += state.objectMode ? 1 : chunk.length;\n        if (addToFront)\n          state.buffer.unshift(chunk);\n        else\n          state.buffer.push(chunk);\n\n        if (state.needReadable)\n          emitReadable(stream);\n      }\n\n      maybeReadMore(stream, state);\n    }\n  } else if (!addToFront) {\n    state.reading = false;\n  }\n\n  return needMoreData(state);\n}\n\n\n\n// if it's past the high water mark, we can push in some more.\n// Also, if we have no data yet, we can stand some\n// more bytes.  This is to work around cases where hwm=0,\n// such as the repl.  Also, if the push() triggered a\n// readable event, and the user called read(largeNumber) such that\n// needReadable was set, then we ought to push more, so that another\n// 'readable' event will be triggered.\nfunction needMoreData(state) {\n  return !state.ended &&\n         (state.needReadable ||\n          state.length < state.highWaterMark ||\n          state.length === 0);\n}\n\n// backwards compatibility.\nReadable.prototype.setEncoding = function(enc) {\n  if (!StringDecoder)\n    StringDecoder = require('string_decoder/').StringDecoder;\n  this._readableState.decoder = new StringDecoder(enc);\n  this._readableState.encoding = enc;\n  return this;\n};\n\n// Don't raise the hwm > 128MB\nvar MAX_HWM = 0x800000;\nfunction roundUpToNextPowerOf2(n) {\n  if (n >= MAX_HWM) {\n    n = MAX_HWM;\n  } else {\n    // Get the next highest power of 2\n    n--;\n    for (var p = 1; p < 32; p <<= 1) n |= n >> p;\n    n++;\n  }\n  return n;\n}\n\nfunction howMuchToRead(n, state) {\n  if (state.length === 0 && state.ended)\n    return 0;\n\n  if (state.objectMode)\n    return n === 0 ? 0 : 1;\n\n  if (isNaN(n) || util.isNull(n)) {\n    // only flow one buffer at a time\n    if (state.flowing && state.buffer.length)\n      return state.buffer[0].length;\n    else\n      return state.length;\n  }\n\n  if (n <= 0)\n    return 0;\n\n  // If we're asking for more than the target buffer level,\n  // then raise the water mark.  Bump up to the next highest\n  // power of 2, to prevent increasing it excessively in tiny\n  // amounts.\n  if (n > state.highWaterMark)\n    state.highWaterMark = roundUpToNextPowerOf2(n);\n\n  // don't have that much.  return null, unless we've ended.\n  if (n > state.length) {\n    if (!state.ended) {\n      state.needReadable = true;\n      return 0;\n    } else\n      return state.length;\n  }\n\n  return n;\n}\n\n// you can override either this method, or the async _read(n) below.\nReadable.prototype.read = function(n) {\n  debug('read', n);\n  var state = this._readableState;\n  var nOrig = n;\n\n  if (!util.isNumber(n) || n > 0)\n    state.emittedReadable = false;\n\n  // if we're doing read(0) to trigger a readable event, but we\n  // already have a bunch of data in the buffer, then just trigger\n  // the 'readable' event and move on.\n  if (n === 0 &&\n      state.needReadable &&\n      (state.length >= state.highWaterMark || state.ended)) {\n    debug('read: emitReadable', state.length, state.ended);\n    if (state.length === 0 && state.ended)\n      endReadable(this);\n    else\n      emitReadable(this);\n    return null;\n  }\n\n  n = howMuchToRead(n, state);\n\n  // if we've ended, and we're now clear, then finish it up.\n  if (n === 0 && state.ended) {\n    if (state.length === 0)\n      endReadable(this);\n    return null;\n  }\n\n  // All the actual chunk generation logic needs to be\n  // *below* the call to _read.  The reason is that in certain\n  // synthetic stream cases, such as passthrough streams, _read\n  // may be a completely synchronous operation which may change\n  // the state of the read buffer, providing enough data when\n  // before there was *not* enough.\n  //\n  // So, the steps are:\n  // 1. Figure out what the state of things will be after we do\n  // a read from the buffer.\n  //\n  // 2. If that resulting state will trigger a _read, then call _read.\n  // Note that this may be asynchronous, or synchronous.  Yes, it is\n  // deeply ugly to write APIs this way, but that still doesn't mean\n  // that the Readable class should behave improperly, as streams are\n  // designed to be sync/async agnostic.\n  // Take note if the _read call is sync or async (ie, if the read call\n  // has returned yet), so that we know whether or not it's safe to emit\n  // 'readable' etc.\n  //\n  // 3. Actually pull the requested chunks out of the buffer and return.\n\n  // if we need a readable event, then we need to do some reading.\n  var doRead = state.needReadable;\n  debug('need readable', doRead);\n\n  // if we currently have less than the highWaterMark, then also read some\n  if (state.length === 0 || state.length - n < state.highWaterMark) {\n    doRead = true;\n    debug('length less than watermark', doRead);\n  }\n\n  // however, if we've ended, then there's no point, and if we're already\n  // reading, then it's unnecessary.\n  if (state.ended || state.reading) {\n    doRead = false;\n    debug('reading or ended', doRead);\n  }\n\n  if (doRead) {\n    debug('do read');\n    state.reading = true;\n    state.sync = true;\n    // if the length is currently zero, then we *need* a readable event.\n    if (state.length === 0)\n      state.needReadable = true;\n    // call internal read method\n    this._read(state.highWaterMark);\n    state.sync = false;\n  }\n\n  // If _read pushed data synchronously, then `reading` will be false,\n  // and we need to re-evaluate how much data we can return to the user.\n  if (doRead && !state.reading)\n    n = howMuchToRead(nOrig, state);\n\n  var ret;\n  if (n > 0)\n    ret = fromList(n, state);\n  else\n    ret = null;\n\n  if (util.isNull(ret)) {\n    state.needReadable = true;\n    n = 0;\n  }\n\n  state.length -= n;\n\n  // If we have nothing in the buffer, then we want to know\n  // as soon as we *do* get something into the buffer.\n  if (state.length === 0 && !state.ended)\n    state.needReadable = true;\n\n  // If we tried to read() past the EOF, then emit end on the next tick.\n  if (nOrig !== n && state.ended && state.length === 0)\n    endReadable(this);\n\n  if (!util.isNull(ret))\n    this.emit('data', ret);\n\n  return ret;\n};\n\nfunction chunkInvalid(state, chunk) {\n  var er = null;\n  if (!util.isBuffer(chunk) &&\n      !util.isString(chunk) &&\n      !util.isNullOrUndefined(chunk) &&\n      !state.objectMode) {\n    er = new TypeError('Invalid non-string/buffer chunk');\n  }\n  return er;\n}\n\n\nfunction onEofChunk(stream, state) {\n  if (state.decoder && !state.ended) {\n    var chunk = state.decoder.end();\n    if (chunk && chunk.length) {\n      state.buffer.push(chunk);\n      state.length += state.objectMode ? 1 : chunk.length;\n    }\n  }\n  state.ended = true;\n\n  // emit 'readable' now to make sure it gets picked up.\n  emitReadable(stream);\n}\n\n// Don't emit readable right away in sync mode, because this can trigger\n// another read() call => stack overflow.  This way, it might trigger\n// a nextTick recursion warning, but that's not so bad.\nfunction emitReadable(stream) {\n  var state = stream._readableState;\n  state.needReadable = false;\n  if (!state.emittedReadable) {\n    debug('emitReadable', state.flowing);\n    state.emittedReadable = true;\n    if (state.sync)\n      process.nextTick(function() {\n        emitReadable_(stream);\n      });\n    else\n      emitReadable_(stream);\n  }\n}\n\nfunction emitReadable_(stream) {\n  debug('emit readable');\n  stream.emit('readable');\n  flow(stream);\n}\n\n\n// at this point, the user has presumably seen the 'readable' event,\n// and called read() to consume some data.  that may have triggered\n// in turn another _read(n) call, in which case reading = true if\n// it's in progress.\n// However, if we're not ended, or reading, and the length < hwm,\n// then go ahead and try to read some more preemptively.\nfunction maybeReadMore(stream, state) {\n  if (!state.readingMore) {\n    state.readingMore = true;\n    process.nextTick(function() {\n      maybeReadMore_(stream, state);\n    });\n  }\n}\n\nfunction maybeReadMore_(stream, state) {\n  var len = state.length;\n  while (!state.reading && !state.flowing && !state.ended &&\n         state.length < state.highWaterMark) {\n    debug('maybeReadMore read 0');\n    stream.read(0);\n    if (len === state.length)\n      // didn't get any data, stop spinning.\n      break;\n    else\n      len = state.length;\n  }\n  state.readingMore = false;\n}\n\n// abstract method.  to be overridden in specific implementation classes.\n// call cb(er, data) where data is <= n in length.\n// for virtual (non-string, non-buffer) streams, \"length\" is somewhat\n// arbitrary, and perhaps not very meaningful.\nReadable.prototype._read = function(n) {\n  this.emit('error', new Error('not implemented'));\n};\n\nReadable.prototype.pipe = function(dest, pipeOpts) {\n  var src = this;\n  var state = this._readableState;\n\n  switch (state.pipesCount) {\n    case 0:\n      state.pipes = dest;\n      break;\n    case 1:\n      state.pipes = [state.pipes, dest];\n      break;\n    default:\n      state.pipes.push(dest);\n      break;\n  }\n  state.pipesCount += 1;\n  debug('pipe count=%d opts=%j', state.pipesCount, pipeOpts);\n\n  var doEnd = (!pipeOpts || pipeOpts.end !== false) &&\n              dest !== process.stdout &&\n              dest !== process.stderr;\n\n  var endFn = doEnd ? onend : cleanup;\n  if (state.endEmitted)\n    process.nextTick(endFn);\n  else\n    src.once('end', endFn);\n\n  dest.on('unpipe', onunpipe);\n  function onunpipe(readable) {\n    debug('onunpipe');\n    if (readable === src) {\n      cleanup();\n    }\n  }\n\n  function onend() {\n    debug('onend');\n    dest.end();\n  }\n\n  // when the dest drains, it reduces the awaitDrain counter\n  // on the source.  This would be more elegant with a .once()\n  // handler in flow(), but adding and removing repeatedly is\n  // too slow.\n  var ondrain = pipeOnDrain(src);\n  dest.on('drain', ondrain);\n\n  function cleanup() {\n    debug('cleanup');\n    // cleanup event handlers once the pipe is broken\n    dest.removeListener('close', onclose);\n    dest.removeListener('finish', onfinish);\n    dest.removeListener('drain', ondrain);\n    dest.removeListener('error', onerror);\n    dest.removeListener('unpipe', onunpipe);\n    src.removeListener('end', onend);\n    src.removeListener('end', cleanup);\n    src.removeListener('data', ondata);\n\n    // if the reader is waiting for a drain event from this\n    // specific writer, then it would cause it to never start\n    // flowing again.\n    // So, if this is awaiting a drain, then we just call it now.\n    // If we don't know, then assume that we are waiting for one.\n    if (state.awaitDrain &&\n        (!dest._writableState || dest._writableState.needDrain))\n      ondrain();\n  }\n\n  src.on('data', ondata);\n  function ondata(chunk) {\n    debug('ondata');\n    var ret = dest.write(chunk);\n    if (false === ret) {\n      debug('false write response, pause',\n            src._readableState.awaitDrain);\n      src._readableState.awaitDrain++;\n      src.pause();\n    }\n  }\n\n  // if the dest has an error, then stop piping into it.\n  // however, don't suppress the throwing behavior for this.\n  function onerror(er) {\n    debug('onerror', er);\n    unpipe();\n    dest.removeListener('error', onerror);\n    if (EE.listenerCount(dest, 'error') === 0)\n      dest.emit('error', er);\n  }\n  // This is a brutally ugly hack to make sure that our error handler\n  // is attached before any userland ones.  NEVER DO THIS.\n  if (!dest._events || !dest._events.error)\n    dest.on('error', onerror);\n  else if (isArray(dest._events.error))\n    dest._events.error.unshift(onerror);\n  else\n    dest._events.error = [onerror, dest._events.error];\n\n\n\n  // Both close and finish should trigger unpipe, but only once.\n  function onclose() {\n    dest.removeListener('finish', onfinish);\n    unpipe();\n  }\n  dest.once('close', onclose);\n  function onfinish() {\n    debug('onfinish');\n    dest.removeListener('close', onclose);\n    unpipe();\n  }\n  dest.once('finish', onfinish);\n\n  function unpipe() {\n    debug('unpipe');\n    src.unpipe(dest);\n  }\n\n  // tell the dest that it's being piped to\n  dest.emit('pipe', src);\n\n  // start the flow if it hasn't been started already.\n  if (!state.flowing) {\n    debug('pipe resume');\n    src.resume();\n  }\n\n  return dest;\n};\n\nfunction pipeOnDrain(src) {\n  return function() {\n    var state = src._readableState;\n    debug('pipeOnDrain', state.awaitDrain);\n    if (state.awaitDrain)\n      state.awaitDrain--;\n    if (state.awaitDrain === 0 && EE.listenerCount(src, 'data')) {\n      state.flowing = true;\n      flow(src);\n    }\n  };\n}\n\n\nReadable.prototype.unpipe = function(dest) {\n  var state = this._readableState;\n\n  // if we're not piping anywhere, then do nothing.\n  if (state.pipesCount === 0)\n    return this;\n\n  // just one destination.  most common case.\n  if (state.pipesCount === 1) {\n    // passed in one, but it's not the right one.\n    if (dest && dest !== state.pipes)\n      return this;\n\n    if (!dest)\n      dest = state.pipes;\n\n    // got a match.\n    state.pipes = null;\n    state.pipesCount = 0;\n    state.flowing = false;\n    if (dest)\n      dest.emit('unpipe', this);\n    return this;\n  }\n\n  // slow case. multiple pipe destinations.\n\n  if (!dest) {\n    // remove all.\n    var dests = state.pipes;\n    var len = state.pipesCount;\n    state.pipes = null;\n    state.pipesCount = 0;\n    state.flowing = false;\n\n    for (var i = 0; i < len; i++)\n      dests[i].emit('unpipe', this);\n    return this;\n  }\n\n  // try to find the right one.\n  var i = indexOf(state.pipes, dest);\n  if (i === -1)\n    return this;\n\n  state.pipes.splice(i, 1);\n  state.pipesCount -= 1;\n  if (state.pipesCount === 1)\n    state.pipes = state.pipes[0];\n\n  dest.emit('unpipe', this);\n\n  return this;\n};\n\n// set up data events if they are asked for\n// Ensure readable listeners eventually get something\nReadable.prototype.on = function(ev, fn) {\n  var res = Stream.prototype.on.call(this, ev, fn);\n\n  // If listening to data, and it has not explicitly been paused,\n  // then call resume to start the flow of data on the next tick.\n  if (ev === 'data' && false !== this._readableState.flowing) {\n    this.resume();\n  }\n\n  if (ev === 'readable' && this.readable) {\n    var state = this._readableState;\n    if (!state.readableListening) {\n      state.readableListening = true;\n      state.emittedReadable = false;\n      state.needReadable = true;\n      if (!state.reading) {\n        var self = this;\n        process.nextTick(function() {\n          debug('readable nexttick read 0');\n          self.read(0);\n        });\n      } else if (state.length) {\n        emitReadable(this, state);\n      }\n    }\n  }\n\n  return res;\n};\nReadable.prototype.addListener = Readable.prototype.on;\n\n// pause() and resume() are remnants of the legacy readable stream API\n// If the user uses them, then switch into old mode.\nReadable.prototype.resume = function() {\n  var state = this._readableState;\n  if (!state.flowing) {\n    debug('resume');\n    state.flowing = true;\n    if (!state.reading) {\n      debug('resume read 0');\n      this.read(0);\n    }\n    resume(this, state);\n  }\n  return this;\n};\n\nfunction resume(stream, state) {\n  if (!state.resumeScheduled) {\n    state.resumeScheduled = true;\n    process.nextTick(function() {\n      resume_(stream, state);\n    });\n  }\n}\n\nfunction resume_(stream, state) {\n  state.resumeScheduled = false;\n  stream.emit('resume');\n  flow(stream);\n  if (state.flowing && !state.reading)\n    stream.read(0);\n}\n\nReadable.prototype.pause = function() {\n  debug('call pause flowing=%j', this._readableState.flowing);\n  if (false !== this._readableState.flowing) {\n    debug('pause');\n    this._readableState.flowing = false;\n    this.emit('pause');\n  }\n  return this;\n};\n\nfunction flow(stream) {\n  var state = stream._readableState;\n  debug('flow', state.flowing);\n  if (state.flowing) {\n    do {\n      var chunk = stream.read();\n    } while (null !== chunk && state.flowing);\n  }\n}\n\n// wrap an old-style stream as the async data source.\n// This is *not* part of the readable stream interface.\n// It is an ugly unfortunate mess of history.\nReadable.prototype.wrap = function(stream) {\n  var state = this._readableState;\n  var paused = false;\n\n  var self = this;\n  stream.on('end', function() {\n    debug('wrapped end');\n    if (state.decoder && !state.ended) {\n      var chunk = state.decoder.end();\n      if (chunk && chunk.length)\n        self.push(chunk);\n    }\n\n    self.push(null);\n  });\n\n  stream.on('data', function(chunk) {\n    debug('wrapped data');\n    if (state.decoder)\n      chunk = state.decoder.write(chunk);\n    if (!chunk || !state.objectMode && !chunk.length)\n      return;\n\n    var ret = self.push(chunk);\n    if (!ret) {\n      paused = true;\n      stream.pause();\n    }\n  });\n\n  // proxy all the other methods.\n  // important when wrapping filters and duplexes.\n  for (var i in stream) {\n    if (util.isFunction(stream[i]) && util.isUndefined(this[i])) {\n      this[i] = function(method) { return function() {\n        return stream[method].apply(stream, arguments);\n      }}(i);\n    }\n  }\n\n  // proxy certain important events.\n  var events = ['error', 'close', 'destroy', 'pause', 'resume'];\n  forEach(events, function(ev) {\n    stream.on(ev, self.emit.bind(self, ev));\n  });\n\n  // when we try to consume some more bytes, simply unpause the\n  // underlying stream.\n  self._read = function(n) {\n    debug('wrapped _read', n);\n    if (paused) {\n      paused = false;\n      stream.resume();\n    }\n  };\n\n  return self;\n};\n\n\n\n// exposed for testing purposes only.\nReadable._fromList = fromList;\n\n// Pluck off n bytes from an array of buffers.\n// Length is the combined lengths of all the buffers in the list.\nfunction fromList(n, state) {\n  var list = state.buffer;\n  var length = state.length;\n  var stringMode = !!state.decoder;\n  var objectMode = !!state.objectMode;\n  var ret;\n\n  // nothing in the list, definitely empty.\n  if (list.length === 0)\n    return null;\n\n  if (length === 0)\n    ret = null;\n  else if (objectMode)\n    ret = list.shift();\n  else if (!n || n >= length) {\n    // read it all, truncate the array.\n    if (stringMode)\n      ret = list.join('');\n    else\n      ret = Buffer.concat(list, length);\n    list.length = 0;\n  } else {\n    // read just some of it.\n    if (n < list[0].length) {\n      // just take a part of the first list item.\n      // slice is the same for buffers and strings.\n      var buf = list[0];\n      ret = buf.slice(0, n);\n      list[0] = buf.slice(n);\n    } else if (n === list[0].length) {\n      // first list is a perfect match\n      ret = list.shift();\n    } else {\n      // complex case.\n      // we have enough to cover it, but it spans past the first buffer.\n      if (stringMode)\n        ret = '';\n      else\n        ret = new Buffer(n);\n\n      var c = 0;\n      for (var i = 0, l = list.length; i < l && c < n; i++) {\n        var buf = list[0];\n        var cpy = Math.min(n - c, buf.length);\n\n        if (stringMode)\n          ret += buf.slice(0, cpy);\n        else\n          buf.copy(ret, c, 0, cpy);\n\n        if (cpy < buf.length)\n          list[0] = buf.slice(cpy);\n        else\n          list.shift();\n\n        c += cpy;\n      }\n    }\n  }\n\n  return ret;\n}\n\nfunction endReadable(stream) {\n  var state = stream._readableState;\n\n  // If we get here before consuming all the bytes, then that is a\n  // bug in node.  Should never happen.\n  if (state.length > 0)\n    throw new Error('endReadable called on non-empty stream');\n\n  if (!state.endEmitted) {\n    state.ended = true;\n    process.nextTick(function() {\n      // Check that we didn't get one last unshift.\n      if (!state.endEmitted && state.length === 0) {\n        state.endEmitted = true;\n        stream.readable = false;\n        stream.emit('end');\n      }\n    });\n  }\n}\n\nfunction forEach (xs, f) {\n  for (var i = 0, l = xs.length; i < l; i++) {\n    f(xs[i], i);\n  }\n}\n\nfunction indexOf (xs, x) {\n  for (var i = 0, l = xs.length; i < l; i++) {\n    if (xs[i] === x) return i;\n  }\n  return -1;\n}\n\n}).call(this,require('_process'))\n},{\"./_stream_duplex\":53,\"_process\":51,\"buffer\":43,\"core-util-is\":58,\"events\":47,\"inherits\":48,\"isarray\":49,\"stream\":63,\"string_decoder/\":64,\"util\":42}],56:[function(require,module,exports){\n// Copyright Joyent, Inc. and other Node contributors.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a\n// copy of this software and associated documentation files (the\n// \"Software\"), to deal in the Software without restriction, including\n// without limitation the rights to use, copy, modify, merge, publish,\n// distribute, sublicense, and/or sell copies of the Software, and to permit\n// persons to whom the Software is furnished to do so, subject to the\n// following conditions:\n//\n// The above copyright notice and this permission notice shall be included\n// in all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS\n// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN\n// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,\n// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE\n// USE OR OTHER DEALINGS IN THE SOFTWARE.\n\n\n// a transform stream is a readable/writable stream where you do\n// something with the data.  Sometimes it's called a \"filter\",\n// but that's not a great name for it, since that implies a thing where\n// some bits pass through, and others are simply ignored.  (That would\n// be a valid example of a transform, of course.)\n//\n// While the output is causally related to the input, it's not a\n// necessarily symmetric or synchronous transformation.  For example,\n// a zlib stream might take multiple plain-text writes(), and then\n// emit a single compressed chunk some time in the future.\n//\n// Here's how this works:\n//\n// The Transform stream has all the aspects of the readable and writable\n// stream classes.  When you write(chunk), that calls _write(chunk,cb)\n// internally, and returns false if there's a lot of pending writes\n// buffered up.  When you call read(), that calls _read(n) until\n// there's enough pending readable data buffered up.\n//\n// In a transform stream, the written data is placed in a buffer.  When\n// _read(n) is called, it transforms the queued up data, calling the\n// buffered _write cb's as it consumes chunks.  If consuming a single\n// written chunk would result in multiple output chunks, then the first\n// outputted bit calls the readcb, and subsequent chunks just go into\n// the read buffer, and will cause it to emit 'readable' if necessary.\n//\n// This way, back-pressure is actually determined by the reading side,\n// since _read has to be called to start processing a new chunk.  However,\n// a pathological inflate type of transform can cause excessive buffering\n// here.  For example, imagine a stream where every byte of input is\n// interpreted as an integer from 0-255, and then results in that many\n// bytes of output.  Writing the 4 bytes {ff,ff,ff,ff} would result in\n// 1kb of data being output.  In this case, you could write a very small\n// amount of input, and end up with a very large amount of output.  In\n// such a pathological inflating mechanism, there'd be no way to tell\n// the system to stop doing the transform.  A single 4MB write could\n// cause the system to run out of memory.\n//\n// However, even in such a pathological case, only a single written chunk\n// would be consumed, and then the rest would wait (un-transformed) until\n// the results of the previous transformed chunk were consumed.\n\nmodule.exports = Transform;\n\nvar Duplex = require('./_stream_duplex');\n\n/*<replacement>*/\nvar util = require('core-util-is');\nutil.inherits = require('inherits');\n/*</replacement>*/\n\nutil.inherits(Transform, Duplex);\n\n\nfunction TransformState(options, stream) {\n  this.afterTransform = function(er, data) {\n    return afterTransform(stream, er, data);\n  };\n\n  this.needTransform = false;\n  this.transforming = false;\n  this.writecb = null;\n  this.writechunk = null;\n}\n\nfunction afterTransform(stream, er, data) {\n  var ts = stream._transformState;\n  ts.transforming = false;\n\n  var cb = ts.writecb;\n\n  if (!cb)\n    return stream.emit('error', new Error('no writecb in Transform class'));\n\n  ts.writechunk = null;\n  ts.writecb = null;\n\n  if (!util.isNullOrUndefined(data))\n    stream.push(data);\n\n  if (cb)\n    cb(er);\n\n  var rs = stream._readableState;\n  rs.reading = false;\n  if (rs.needReadable || rs.length < rs.highWaterMark) {\n    stream._read(rs.highWaterMark);\n  }\n}\n\n\nfunction Transform(options) {\n  if (!(this instanceof Transform))\n    return new Transform(options);\n\n  Duplex.call(this, options);\n\n  this._transformState = new TransformState(options, this);\n\n  // when the writable side finishes, then flush out anything remaining.\n  var stream = this;\n\n  // start out asking for a readable event once data is transformed.\n  this._readableState.needReadable = true;\n\n  // we have implemented the _read method, and done the other things\n  // that Readable wants before the first _read call, so unset the\n  // sync guard flag.\n  this._readableState.sync = false;\n\n  this.once('prefinish', function() {\n    if (util.isFunction(this._flush))\n      this._flush(function(er) {\n        done(stream, er);\n      });\n    else\n      done(stream);\n  });\n}\n\nTransform.prototype.push = function(chunk, encoding) {\n  this._transformState.needTransform = false;\n  return Duplex.prototype.push.call(this, chunk, encoding);\n};\n\n// This is the part where you do stuff!\n// override this function in implementation classes.\n// 'chunk' is an input chunk.\n//\n// Call `push(newChunk)` to pass along transformed output\n// to the readable side.  You may call 'push' zero or more times.\n//\n// Call `cb(err)` when you are done with this chunk.  If you pass\n// an error, then that'll put the hurt on the whole operation.  If you\n// never call cb(), then you'll never get another chunk.\nTransform.prototype._transform = function(chunk, encoding, cb) {\n  throw new Error('not implemented');\n};\n\nTransform.prototype._write = function(chunk, encoding, cb) {\n  var ts = this._transformState;\n  ts.writecb = cb;\n  ts.writechunk = chunk;\n  ts.writeencoding = encoding;\n  if (!ts.transforming) {\n    var rs = this._readableState;\n    if (ts.needTransform ||\n        rs.needReadable ||\n        rs.length < rs.highWaterMark)\n      this._read(rs.highWaterMark);\n  }\n};\n\n// Doesn't matter what the args are here.\n// _transform does all the work.\n// That we got here means that the readable side wants more data.\nTransform.prototype._read = function(n) {\n  var ts = this._transformState;\n\n  if (!util.isNull(ts.writechunk) && ts.writecb && !ts.transforming) {\n    ts.transforming = true;\n    this._transform(ts.writechunk, ts.writeencoding, ts.afterTransform);\n  } else {\n    // mark that we need a transform, so that any data that comes in\n    // will get processed, now that we've asked for it.\n    ts.needTransform = true;\n  }\n};\n\n\nfunction done(stream, er) {\n  if (er)\n    return stream.emit('error', er);\n\n  // if there's nothing in the write buffer, then that means\n  // that nothing more will ever be provided\n  var ws = stream._writableState;\n  var ts = stream._transformState;\n\n  if (ws.length)\n    throw new Error('calling transform done when ws.length != 0');\n\n  if (ts.transforming)\n    throw new Error('calling transform done when still transforming');\n\n  return stream.push(null);\n}\n\n},{\"./_stream_duplex\":53,\"core-util-is\":58,\"inherits\":48}],57:[function(require,module,exports){\n(function (process){\n// Copyright Joyent, Inc. and other Node contributors.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a\n// copy of this software and associated documentation files (the\n// \"Software\"), to deal in the Software without restriction, including\n// without limitation the rights to use, copy, modify, merge, publish,\n// distribute, sublicense, and/or sell copies of the Software, and to permit\n// persons to whom the Software is furnished to do so, subject to the\n// following conditions:\n//\n// The above copyright notice and this permission notice shall be included\n// in all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS\n// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN\n// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,\n// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE\n// USE OR OTHER DEALINGS IN THE SOFTWARE.\n\n// A bit simpler than readable streams.\n// Implement an async ._write(chunk, cb), and it'll handle all\n// the drain event emission and buffering.\n\nmodule.exports = Writable;\n\n/*<replacement>*/\nvar Buffer = require('buffer').Buffer;\n/*</replacement>*/\n\nWritable.WritableState = WritableState;\n\n\n/*<replacement>*/\nvar util = require('core-util-is');\nutil.inherits = require('inherits');\n/*</replacement>*/\n\nvar Stream = require('stream');\n\nutil.inherits(Writable, Stream);\n\nfunction WriteReq(chunk, encoding, cb) {\n  this.chunk = chunk;\n  this.encoding = encoding;\n  this.callback = cb;\n}\n\nfunction WritableState(options, stream) {\n  var Duplex = require('./_stream_duplex');\n\n  options = options || {};\n\n  // the point at which write() starts returning false\n  // Note: 0 is a valid value, means that we always return false if\n  // the entire buffer is not flushed immediately on write()\n  var hwm = options.highWaterMark;\n  var defaultHwm = options.objectMode ? 16 : 16 * 1024;\n  this.highWaterMark = (hwm || hwm === 0) ? hwm : defaultHwm;\n\n  // object stream flag to indicate whether or not this stream\n  // contains buffers or objects.\n  this.objectMode = !!options.objectMode;\n\n  if (stream instanceof Duplex)\n    this.objectMode = this.objectMode || !!options.writableObjectMode;\n\n  // cast to ints.\n  this.highWaterMark = ~~this.highWaterMark;\n\n  this.needDrain = false;\n  // at the start of calling end()\n  this.ending = false;\n  // when end() has been called, and returned\n  this.ended = false;\n  // when 'finish' is emitted\n  this.finished = false;\n\n  // should we decode strings into buffers before passing to _write?\n  // this is here so that some node-core streams can optimize string\n  // handling at a lower level.\n  var noDecode = options.decodeStrings === false;\n  this.decodeStrings = !noDecode;\n\n  // Crypto is kind of old and crusty.  Historically, its default string\n  // encoding is 'binary' so we have to make this configurable.\n  // Everything else in the universe uses 'utf8', though.\n  this.defaultEncoding = options.defaultEncoding || 'utf8';\n\n  // not an actual buffer we keep track of, but a measurement\n  // of how much we're waiting to get pushed to some underlying\n  // socket or file.\n  this.length = 0;\n\n  // a flag to see when we're in the middle of a write.\n  this.writing = false;\n\n  // when true all writes will be buffered until .uncork() call\n  this.corked = 0;\n\n  // a flag to be able to tell if the onwrite cb is called immediately,\n  // or on a later tick.  We set this to true at first, because any\n  // actions that shouldn't happen until \"later\" should generally also\n  // not happen before the first write call.\n  this.sync = true;\n\n  // a flag to know if we're processing previously buffered items, which\n  // may call the _write() callback in the same tick, so that we don't\n  // end up in an overlapped onwrite situation.\n  this.bufferProcessing = false;\n\n  // the callback that's passed to _write(chunk,cb)\n  this.onwrite = function(er) {\n    onwrite(stream, er);\n  };\n\n  // the callback that the user supplies to write(chunk,encoding,cb)\n  this.writecb = null;\n\n  // the amount that is being written when _write is called.\n  this.writelen = 0;\n\n  this.buffer = [];\n\n  // number of pending user-supplied write callbacks\n  // this must be 0 before 'finish' can be emitted\n  this.pendingcb = 0;\n\n  // emit prefinish if the only thing we're waiting for is _write cbs\n  // This is relevant for synchronous Transform streams\n  this.prefinished = false;\n\n  // True if the error was already emitted and should not be thrown again\n  this.errorEmitted = false;\n}\n\nfunction Writable(options) {\n  var Duplex = require('./_stream_duplex');\n\n  // Writable ctor is applied to Duplexes, though they're not\n  // instanceof Writable, they're instanceof Readable.\n  if (!(this instanceof Writable) && !(this instanceof Duplex))\n    return new Writable(options);\n\n  this._writableState = new WritableState(options, this);\n\n  // legacy.\n  this.writable = true;\n\n  Stream.call(this);\n}\n\n// Otherwise people can pipe Writable streams, which is just wrong.\nWritable.prototype.pipe = function() {\n  this.emit('error', new Error('Cannot pipe. Not readable.'));\n};\n\n\nfunction writeAfterEnd(stream, state, cb) {\n  var er = new Error('write after end');\n  // TODO: defer error events consistently everywhere, not just the cb\n  stream.emit('error', er);\n  process.nextTick(function() {\n    cb(er);\n  });\n}\n\n// If we get something that is not a buffer, string, null, or undefined,\n// and we're not in objectMode, then that's an error.\n// Otherwise stream chunks are all considered to be of length=1, and the\n// watermarks determine how many objects to keep in the buffer, rather than\n// how many bytes or characters.\nfunction validChunk(stream, state, chunk, cb) {\n  var valid = true;\n  if (!util.isBuffer(chunk) &&\n      !util.isString(chunk) &&\n      !util.isNullOrUndefined(chunk) &&\n      !state.objectMode) {\n    var er = new TypeError('Invalid non-string/buffer chunk');\n    stream.emit('error', er);\n    process.nextTick(function() {\n      cb(er);\n    });\n    valid = false;\n  }\n  return valid;\n}\n\nWritable.prototype.write = function(chunk, encoding, cb) {\n  var state = this._writableState;\n  var ret = false;\n\n  if (util.isFunction(encoding)) {\n    cb = encoding;\n    encoding = null;\n  }\n\n  if (util.isBuffer(chunk))\n    encoding = 'buffer';\n  else if (!encoding)\n    encoding = state.defaultEncoding;\n\n  if (!util.isFunction(cb))\n    cb = function() {};\n\n  if (state.ended)\n    writeAfterEnd(this, state, cb);\n  else if (validChunk(this, state, chunk, cb)) {\n    state.pendingcb++;\n    ret = writeOrBuffer(this, state, chunk, encoding, cb);\n  }\n\n  return ret;\n};\n\nWritable.prototype.cork = function() {\n  var state = this._writableState;\n\n  state.corked++;\n};\n\nWritable.prototype.uncork = function() {\n  var state = this._writableState;\n\n  if (state.corked) {\n    state.corked--;\n\n    if (!state.writing &&\n        !state.corked &&\n        !state.finished &&\n        !state.bufferProcessing &&\n        state.buffer.length)\n      clearBuffer(this, state);\n  }\n};\n\nfunction decodeChunk(state, chunk, encoding) {\n  if (!state.objectMode &&\n      state.decodeStrings !== false &&\n      util.isString(chunk)) {\n    chunk = new Buffer(chunk, encoding);\n  }\n  return chunk;\n}\n\n// if we're already writing something, then just put this\n// in the queue, and wait our turn.  Otherwise, call _write\n// If we return false, then we need a drain event, so set that flag.\nfunction writeOrBuffer(stream, state, chunk, encoding, cb) {\n  chunk = decodeChunk(state, chunk, encoding);\n  if (util.isBuffer(chunk))\n    encoding = 'buffer';\n  var len = state.objectMode ? 1 : chunk.length;\n\n  state.length += len;\n\n  var ret = state.length < state.highWaterMark;\n  // we must ensure that previous needDrain will not be reset to false.\n  if (!ret)\n    state.needDrain = true;\n\n  if (state.writing || state.corked)\n    state.buffer.push(new WriteReq(chunk, encoding, cb));\n  else\n    doWrite(stream, state, false, len, chunk, encoding, cb);\n\n  return ret;\n}\n\nfunction doWrite(stream, state, writev, len, chunk, encoding, cb) {\n  state.writelen = len;\n  state.writecb = cb;\n  state.writing = true;\n  state.sync = true;\n  if (writev)\n    stream._writev(chunk, state.onwrite);\n  else\n    stream._write(chunk, encoding, state.onwrite);\n  state.sync = false;\n}\n\nfunction onwriteError(stream, state, sync, er, cb) {\n  if (sync)\n    process.nextTick(function() {\n      state.pendingcb--;\n      cb(er);\n    });\n  else {\n    state.pendingcb--;\n    cb(er);\n  }\n\n  stream._writableState.errorEmitted = true;\n  stream.emit('error', er);\n}\n\nfunction onwriteStateUpdate(state) {\n  state.writing = false;\n  state.writecb = null;\n  state.length -= state.writelen;\n  state.writelen = 0;\n}\n\nfunction onwrite(stream, er) {\n  var state = stream._writableState;\n  var sync = state.sync;\n  var cb = state.writecb;\n\n  onwriteStateUpdate(state);\n\n  if (er)\n    onwriteError(stream, state, sync, er, cb);\n  else {\n    // Check if we're actually ready to finish, but don't emit yet\n    var finished = needFinish(stream, state);\n\n    if (!finished &&\n        !state.corked &&\n        !state.bufferProcessing &&\n        state.buffer.length) {\n      clearBuffer(stream, state);\n    }\n\n    if (sync) {\n      process.nextTick(function() {\n        afterWrite(stream, state, finished, cb);\n      });\n    } else {\n      afterWrite(stream, state, finished, cb);\n    }\n  }\n}\n\nfunction afterWrite(stream, state, finished, cb) {\n  if (!finished)\n    onwriteDrain(stream, state);\n  state.pendingcb--;\n  cb();\n  finishMaybe(stream, state);\n}\n\n// Must force callback to be called on nextTick, so that we don't\n// emit 'drain' before the write() consumer gets the 'false' return\n// value, and has a chance to attach a 'drain' listener.\nfunction onwriteDrain(stream, state) {\n  if (state.length === 0 && state.needDrain) {\n    state.needDrain = false;\n    stream.emit('drain');\n  }\n}\n\n\n// if there's something in the buffer waiting, then process it\nfunction clearBuffer(stream, state) {\n  state.bufferProcessing = true;\n\n  if (stream._writev && state.buffer.length > 1) {\n    // Fast case, write everything using _writev()\n    var cbs = [];\n    for (var c = 0; c < state.buffer.length; c++)\n      cbs.push(state.buffer[c].callback);\n\n    // count the one we are adding, as well.\n    // TODO(isaacs) clean this up\n    state.pendingcb++;\n    doWrite(stream, state, true, state.length, state.buffer, '', function(err) {\n      for (var i = 0; i < cbs.length; i++) {\n        state.pendingcb--;\n        cbs[i](err);\n      }\n    });\n\n    // Clear buffer\n    state.buffer = [];\n  } else {\n    // Slow case, write chunks one-by-one\n    for (var c = 0; c < state.buffer.length; c++) {\n      var entry = state.buffer[c];\n      var chunk = entry.chunk;\n      var encoding = entry.encoding;\n      var cb = entry.callback;\n      var len = state.objectMode ? 1 : chunk.length;\n\n      doWrite(stream, state, false, len, chunk, encoding, cb);\n\n      // if we didn't call the onwrite immediately, then\n      // it means that we need to wait until it does.\n      // also, that means that the chunk and cb are currently\n      // being processed, so move the buffer counter past them.\n      if (state.writing) {\n        c++;\n        break;\n      }\n    }\n\n    if (c < state.buffer.length)\n      state.buffer = state.buffer.slice(c);\n    else\n      state.buffer.length = 0;\n  }\n\n  state.bufferProcessing = false;\n}\n\nWritable.prototype._write = function(chunk, encoding, cb) {\n  cb(new Error('not implemented'));\n\n};\n\nWritable.prototype._writev = null;\n\nWritable.prototype.end = function(chunk, encoding, cb) {\n  var state = this._writableState;\n\n  if (util.isFunction(chunk)) {\n    cb = chunk;\n    chunk = null;\n    encoding = null;\n  } else if (util.isFunction(encoding)) {\n    cb = encoding;\n    encoding = null;\n  }\n\n  if (!util.isNullOrUndefined(chunk))\n    this.write(chunk, encoding);\n\n  // .end() fully uncorks\n  if (state.corked) {\n    state.corked = 1;\n    this.uncork();\n  }\n\n  // ignore unnecessary end() calls.\n  if (!state.ending && !state.finished)\n    endWritable(this, state, cb);\n};\n\n\nfunction needFinish(stream, state) {\n  return (state.ending &&\n          state.length === 0 &&\n          !state.finished &&\n          !state.writing);\n}\n\nfunction prefinish(stream, state) {\n  if (!state.prefinished) {\n    state.prefinished = true;\n    stream.emit('prefinish');\n  }\n}\n\nfunction finishMaybe(stream, state) {\n  var need = needFinish(stream, state);\n  if (need) {\n    if (state.pendingcb === 0) {\n      prefinish(stream, state);\n      state.finished = true;\n      stream.emit('finish');\n    } else\n      prefinish(stream, state);\n  }\n  return need;\n}\n\nfunction endWritable(stream, state, cb) {\n  state.ending = true;\n  finishMaybe(stream, state);\n  if (cb) {\n    if (state.finished)\n      process.nextTick(cb);\n    else\n      stream.once('finish', cb);\n  }\n  state.ended = true;\n}\n\n}).call(this,require('_process'))\n},{\"./_stream_duplex\":53,\"_process\":51,\"buffer\":43,\"core-util-is\":58,\"inherits\":48,\"stream\":63}],58:[function(require,module,exports){\n(function (Buffer){\n// Copyright Joyent, Inc. and other Node contributors.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a\n// copy of this software and associated documentation files (the\n// \"Software\"), to deal in the Software without restriction, including\n// without limitation the rights to use, copy, modify, merge, publish,\n// distribute, sublicense, and/or sell copies of the Software, and to permit\n// persons to whom the Software is furnished to do so, subject to the\n// following conditions:\n//\n// The above copyright notice and this permission notice shall be included\n// in all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS\n// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN\n// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,\n// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE\n// USE OR OTHER DEALINGS IN THE SOFTWARE.\n\n// NOTE: These type checking functions intentionally don't use `instanceof`\n// because it is fragile and can be easily faked with `Object.create()`.\nfunction isArray(ar) {\n  return Array.isArray(ar);\n}\nexports.isArray = isArray;\n\nfunction isBoolean(arg) {\n  return typeof arg === 'boolean';\n}\nexports.isBoolean = isBoolean;\n\nfunction isNull(arg) {\n  return arg === null;\n}\nexports.isNull = isNull;\n\nfunction isNullOrUndefined(arg) {\n  return arg == null;\n}\nexports.isNullOrUndefined = isNullOrUndefined;\n\nfunction isNumber(arg) {\n  return typeof arg === 'number';\n}\nexports.isNumber = isNumber;\n\nfunction isString(arg) {\n  return typeof arg === 'string';\n}\nexports.isString = isString;\n\nfunction isSymbol(arg) {\n  return typeof arg === 'symbol';\n}\nexports.isSymbol = isSymbol;\n\nfunction isUndefined(arg) {\n  return arg === void 0;\n}\nexports.isUndefined = isUndefined;\n\nfunction isRegExp(re) {\n  return isObject(re) && objectToString(re) === '[object RegExp]';\n}\nexports.isRegExp = isRegExp;\n\nfunction isObject(arg) {\n  return typeof arg === 'object' && arg !== null;\n}\nexports.isObject = isObject;\n\nfunction isDate(d) {\n  return isObject(d) && objectToString(d) === '[object Date]';\n}\nexports.isDate = isDate;\n\nfunction isError(e) {\n  return isObject(e) &&\n      (objectToString(e) === '[object Error]' || e instanceof Error);\n}\nexports.isError = isError;\n\nfunction isFunction(arg) {\n  return typeof arg === 'function';\n}\nexports.isFunction = isFunction;\n\nfunction isPrimitive(arg) {\n  return arg === null ||\n         typeof arg === 'boolean' ||\n         typeof arg === 'number' ||\n         typeof arg === 'string' ||\n         typeof arg === 'symbol' ||  // ES6 symbol\n         typeof arg === 'undefined';\n}\nexports.isPrimitive = isPrimitive;\n\nfunction isBuffer(arg) {\n  return Buffer.isBuffer(arg);\n}\nexports.isBuffer = isBuffer;\n\nfunction objectToString(o) {\n  return Object.prototype.toString.call(o);\n}\n}).call(this,require(\"buffer\").Buffer)\n},{\"buffer\":43}],59:[function(require,module,exports){\nmodule.exports = require(\"./lib/_stream_passthrough.js\")\n\n},{\"./lib/_stream_passthrough.js\":54}],60:[function(require,module,exports){\nexports = module.exports = require('./lib/_stream_readable.js');\nexports.Stream = require('stream');\nexports.Readable = exports;\nexports.Writable = require('./lib/_stream_writable.js');\nexports.Duplex = require('./lib/_stream_duplex.js');\nexports.Transform = require('./lib/_stream_transform.js');\nexports.PassThrough = require('./lib/_stream_passthrough.js');\n\n},{\"./lib/_stream_duplex.js\":53,\"./lib/_stream_passthrough.js\":54,\"./lib/_stream_readable.js\":55,\"./lib/_stream_transform.js\":56,\"./lib/_stream_writable.js\":57,\"stream\":63}],61:[function(require,module,exports){\nmodule.exports = require(\"./lib/_stream_transform.js\")\n\n},{\"./lib/_stream_transform.js\":56}],62:[function(require,module,exports){\nmodule.exports = require(\"./lib/_stream_writable.js\")\n\n},{\"./lib/_stream_writable.js\":57}],63:[function(require,module,exports){\n// Copyright Joyent, Inc. and other Node contributors.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a\n// copy of this software and associated documentation files (the\n// \"Software\"), to deal in the Software without restriction, including\n// without limitation the rights to use, copy, modify, merge, publish,\n// distribute, sublicense, and/or sell copies of the Software, and to permit\n// persons to whom the Software is furnished to do so, subject to the\n// following conditions:\n//\n// The above copyright notice and this permission notice shall be included\n// in all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS\n// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN\n// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,\n// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE\n// USE OR OTHER DEALINGS IN THE SOFTWARE.\n\nmodule.exports = Stream;\n\nvar EE = require('events').EventEmitter;\nvar inherits = require('inherits');\n\ninherits(Stream, EE);\nStream.Readable = require('readable-stream/readable.js');\nStream.Writable = require('readable-stream/writable.js');\nStream.Duplex = require('readable-stream/duplex.js');\nStream.Transform = require('readable-stream/transform.js');\nStream.PassThrough = require('readable-stream/passthrough.js');\n\n// Backwards-compat with node 0.4.x\nStream.Stream = Stream;\n\n\n\n// old-style streams.  Note that the pipe method (the only relevant\n// part of this class) is overridden in the Readable class.\n\nfunction Stream() {\n  EE.call(this);\n}\n\nStream.prototype.pipe = function(dest, options) {\n  var source = this;\n\n  function ondata(chunk) {\n    if (dest.writable) {\n      if (false === dest.write(chunk) && source.pause) {\n        source.pause();\n      }\n    }\n  }\n\n  source.on('data', ondata);\n\n  function ondrain() {\n    if (source.readable && source.resume) {\n      source.resume();\n    }\n  }\n\n  dest.on('drain', ondrain);\n\n  // If the 'end' option is not supplied, dest.end() will be called when\n  // source gets the 'end' or 'close' events.  Only dest.end() once.\n  if (!dest._isStdio && (!options || options.end !== false)) {\n    source.on('end', onend);\n    source.on('close', onclose);\n  }\n\n  var didOnEnd = false;\n  function onend() {\n    if (didOnEnd) return;\n    didOnEnd = true;\n\n    dest.end();\n  }\n\n\n  function onclose() {\n    if (didOnEnd) return;\n    didOnEnd = true;\n\n    if (typeof dest.destroy === 'function') dest.destroy();\n  }\n\n  // don't leave dangling pipes when there are errors.\n  function onerror(er) {\n    cleanup();\n    if (EE.listenerCount(this, 'error') === 0) {\n      throw er; // Unhandled stream error in pipe.\n    }\n  }\n\n  source.on('error', onerror);\n  dest.on('error', onerror);\n\n  // remove all the event listeners that were added.\n  function cleanup() {\n    source.removeListener('data', ondata);\n    dest.removeListener('drain', ondrain);\n\n    source.removeListener('end', onend);\n    source.removeListener('close', onclose);\n\n    source.removeListener('error', onerror);\n    dest.removeListener('error', onerror);\n\n    source.removeListener('end', cleanup);\n    source.removeListener('close', cleanup);\n\n    dest.removeListener('close', cleanup);\n  }\n\n  source.on('end', cleanup);\n  source.on('close', cleanup);\n\n  dest.on('close', cleanup);\n\n  dest.emit('pipe', source);\n\n  // Allow for unix-like usage: A.pipe(B).pipe(C)\n  return dest;\n};\n\n},{\"events\":47,\"inherits\":48,\"readable-stream/duplex.js\":52,\"readable-stream/passthrough.js\":59,\"readable-stream/readable.js\":60,\"readable-stream/transform.js\":61,\"readable-stream/writable.js\":62}],64:[function(require,module,exports){\n// Copyright Joyent, Inc. and other Node contributors.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a\n// copy of this software and associated documentation files (the\n// \"Software\"), to deal in the Software without restriction, including\n// without limitation the rights to use, copy, modify, merge, publish,\n// distribute, sublicense, and/or sell copies of the Software, and to permit\n// persons to whom the Software is furnished to do so, subject to the\n// following conditions:\n//\n// The above copyright notice and this permission notice shall be included\n// in all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS\n// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN\n// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,\n// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE\n// USE OR OTHER DEALINGS IN THE SOFTWARE.\n\nvar Buffer = require('buffer').Buffer;\n\nvar isBufferEncoding = Buffer.isEncoding\n  || function(encoding) {\n       switch (encoding && encoding.toLowerCase()) {\n         case 'hex': case 'utf8': case 'utf-8': case 'ascii': case 'binary': case 'base64': case 'ucs2': case 'ucs-2': case 'utf16le': case 'utf-16le': case 'raw': return true;\n         default: return false;\n       }\n     }\n\n\nfunction assertEncoding(encoding) {\n  if (encoding && !isBufferEncoding(encoding)) {\n    throw new Error('Unknown encoding: ' + encoding);\n  }\n}\n\n// StringDecoder provides an interface for efficiently splitting a series of\n// buffers into a series of JS strings without breaking apart multi-byte\n// characters. CESU-8 is handled as part of the UTF-8 encoding.\n//\n// @TODO Handling all encodings inside a single object makes it very difficult\n// to reason about this code, so it should be split up in the future.\n// @TODO There should be a utf8-strict encoding that rejects invalid UTF-8 code\n// points as used by CESU-8.\nvar StringDecoder = exports.StringDecoder = function(encoding) {\n  this.encoding = (encoding || 'utf8').toLowerCase().replace(/[-_]/, '');\n  assertEncoding(encoding);\n  switch (this.encoding) {\n    case 'utf8':\n      // CESU-8 represents each of Surrogate Pair by 3-bytes\n      this.surrogateSize = 3;\n      break;\n    case 'ucs2':\n    case 'utf16le':\n      // UTF-16 represents each of Surrogate Pair by 2-bytes\n      this.surrogateSize = 2;\n      this.detectIncompleteChar = utf16DetectIncompleteChar;\n      break;\n    case 'base64':\n      // Base-64 stores 3 bytes in 4 chars, and pads the remainder.\n      this.surrogateSize = 3;\n      this.detectIncompleteChar = base64DetectIncompleteChar;\n      break;\n    default:\n      this.write = passThroughWrite;\n      return;\n  }\n\n  // Enough space to store all bytes of a single character. UTF-8 needs 4\n  // bytes, but CESU-8 may require up to 6 (3 bytes per surrogate).\n  this.charBuffer = new Buffer(6);\n  // Number of bytes received for the current incomplete multi-byte character.\n  this.charReceived = 0;\n  // Number of bytes expected for the current incomplete multi-byte character.\n  this.charLength = 0;\n};\n\n\n// write decodes the given buffer and returns it as JS string that is\n// guaranteed to not contain any partial multi-byte characters. Any partial\n// character found at the end of the buffer is buffered up, and will be\n// returned when calling write again with the remaining bytes.\n//\n// Note: Converting a Buffer containing an orphan surrogate to a String\n// currently works, but converting a String to a Buffer (via `new Buffer`, or\n// Buffer#write) will replace incomplete surrogates with the unicode\n// replacement character. See https://codereview.chromium.org/121173009/ .\nStringDecoder.prototype.write = function(buffer) {\n  var charStr = '';\n  // if our last write ended with an incomplete multibyte character\n  while (this.charLength) {\n    // determine how many remaining bytes this buffer has to offer for this char\n    var available = (buffer.length >= this.charLength - this.charReceived) ?\n        this.charLength - this.charReceived :\n        buffer.length;\n\n    // add the new bytes to the char buffer\n    buffer.copy(this.charBuffer, this.charReceived, 0, available);\n    this.charReceived += available;\n\n    if (this.charReceived < this.charLength) {\n      // still not enough chars in this buffer? wait for more ...\n      return '';\n    }\n\n    // remove bytes belonging to the current character from the buffer\n    buffer = buffer.slice(available, buffer.length);\n\n    // get the character that was split\n    charStr = this.charBuffer.slice(0, this.charLength).toString(this.encoding);\n\n    // CESU-8: lead surrogate (D800-DBFF) is also the incomplete character\n    var charCode = charStr.charCodeAt(charStr.length - 1);\n    if (charCode >= 0xD800 && charCode <= 0xDBFF) {\n      this.charLength += this.surrogateSize;\n      charStr = '';\n      continue;\n    }\n    this.charReceived = this.charLength = 0;\n\n    // if there are no more bytes in this buffer, just emit our char\n    if (buffer.length === 0) {\n      return charStr;\n    }\n    break;\n  }\n\n  // determine and set charLength / charReceived\n  this.detectIncompleteChar(buffer);\n\n  var end = buffer.length;\n  if (this.charLength) {\n    // buffer the incomplete character bytes we got\n    buffer.copy(this.charBuffer, 0, buffer.length - this.charReceived, end);\n    end -= this.charReceived;\n  }\n\n  charStr += buffer.toString(this.encoding, 0, end);\n\n  var end = charStr.length - 1;\n  var charCode = charStr.charCodeAt(end);\n  // CESU-8: lead surrogate (D800-DBFF) is also the incomplete character\n  if (charCode >= 0xD800 && charCode <= 0xDBFF) {\n    var size = this.surrogateSize;\n    this.charLength += size;\n    this.charReceived += size;\n    this.charBuffer.copy(this.charBuffer, size, 0, size);\n    buffer.copy(this.charBuffer, 0, 0, size);\n    return charStr.substring(0, end);\n  }\n\n  // or just emit the charStr\n  return charStr;\n};\n\n// detectIncompleteChar determines if there is an incomplete UTF-8 character at\n// the end of the given buffer. If so, it sets this.charLength to the byte\n// length that character, and sets this.charReceived to the number of bytes\n// that are available for this character.\nStringDecoder.prototype.detectIncompleteChar = function(buffer) {\n  // determine how many bytes we have to check at the end of this buffer\n  var i = (buffer.length >= 3) ? 3 : buffer.length;\n\n  // Figure out if one of the last i bytes of our buffer announces an\n  // incomplete char.\n  for (; i > 0; i--) {\n    var c = buffer[buffer.length - i];\n\n    // See http://en.wikipedia.org/wiki/UTF-8#Description\n\n    // 110XXXXX\n    if (i == 1 && c >> 5 == 0x06) {\n      this.charLength = 2;\n      break;\n    }\n\n    // 1110XXXX\n    if (i <= 2 && c >> 4 == 0x0E) {\n      this.charLength = 3;\n      break;\n    }\n\n    // 11110XXX\n    if (i <= 3 && c >> 3 == 0x1E) {\n      this.charLength = 4;\n      break;\n    }\n  }\n  this.charReceived = i;\n};\n\nStringDecoder.prototype.end = function(buffer) {\n  var res = '';\n  if (buffer && buffer.length)\n    res = this.write(buffer);\n\n  if (this.charReceived) {\n    var cr = this.charReceived;\n    var buf = this.charBuffer;\n    var enc = this.encoding;\n    res += buf.slice(0, cr).toString(enc);\n  }\n\n  return res;\n};\n\nfunction passThroughWrite(buffer) {\n  return buffer.toString(this.encoding);\n}\n\nfunction utf16DetectIncompleteChar(buffer) {\n  this.charReceived = buffer.length % 2;\n  this.charLength = this.charReceived ? 2 : 0;\n}\n\nfunction base64DetectIncompleteChar(buffer) {\n  this.charReceived = buffer.length % 3;\n  this.charLength = this.charReceived ? 3 : 0;\n}\n\n},{\"buffer\":43}],65:[function(require,module,exports){\nmodule.exports = function isBuffer(arg) {\n  return arg && typeof arg === 'object'\n    && typeof arg.copy === 'function'\n    && typeof arg.fill === 'function'\n    && typeof arg.readUInt8 === 'function';\n}\n},{}],66:[function(require,module,exports){\n(function (process,global){\n// Copyright Joyent, Inc. and other Node contributors.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a\n// copy of this software and associated documentation files (the\n// \"Software\"), to deal in the Software without restriction, including\n// without limitation the rights to use, copy, modify, merge, publish,\n// distribute, sublicense, and/or sell copies of the Software, and to permit\n// persons to whom the Software is furnished to do so, subject to the\n// following conditions:\n//\n// The above copyright notice and this permission notice shall be included\n// in all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS\n// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN\n// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,\n// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE\n// USE OR OTHER DEALINGS IN THE SOFTWARE.\n\nvar formatRegExp = /%[sdj%]/g;\nexports.format = function(f) {\n  if (!isString(f)) {\n    var objects = [];\n    for (var i = 0; i < arguments.length; i++) {\n      objects.push(inspect(arguments[i]));\n    }\n    return objects.join(' ');\n  }\n\n  var i = 1;\n  var args = arguments;\n  var len = args.length;\n  var str = String(f).replace(formatRegExp, function(x) {\n    if (x === '%%') return '%';\n    if (i >= len) return x;\n    switch (x) {\n      case '%s': return String(args[i++]);\n      case '%d': return Number(args[i++]);\n      case '%j':\n        try {\n          return JSON.stringify(args[i++]);\n        } catch (_) {\n          return '[Circular]';\n        }\n      default:\n        return x;\n    }\n  });\n  for (var x = args[i]; i < len; x = args[++i]) {\n    if (isNull(x) || !isObject(x)) {\n      str += ' ' + x;\n    } else {\n      str += ' ' + inspect(x);\n    }\n  }\n  return str;\n};\n\n\n// Mark that a method should not be used.\n// Returns a modified function which warns once by default.\n// If --no-deprecation is set, then it is a no-op.\nexports.deprecate = function(fn, msg) {\n  // Allow for deprecating things in the process of starting up.\n  if (isUndefined(global.process)) {\n    return function() {\n      return exports.deprecate(fn, msg).apply(this, arguments);\n    };\n  }\n\n  if (process.noDeprecation === true) {\n    return fn;\n  }\n\n  var warned = false;\n  function deprecated() {\n    if (!warned) {\n      if (process.throwDeprecation) {\n        throw new Error(msg);\n      } else if (process.traceDeprecation) {\n        console.trace(msg);\n      } else {\n        console.error(msg);\n      }\n      warned = true;\n    }\n    return fn.apply(this, arguments);\n  }\n\n  return deprecated;\n};\n\n\nvar debugs = {};\nvar debugEnviron;\nexports.debuglog = function(set) {\n  if (isUndefined(debugEnviron))\n    debugEnviron = process.env.NODE_DEBUG || '';\n  set = set.toUpperCase();\n  if (!debugs[set]) {\n    if (new RegExp('\\\\b' + set + '\\\\b', 'i').test(debugEnviron)) {\n      var pid = process.pid;\n      debugs[set] = function() {\n        var msg = exports.format.apply(exports, arguments);\n        console.error('%s %d: %s', set, pid, msg);\n      };\n    } else {\n      debugs[set] = function() {};\n    }\n  }\n  return debugs[set];\n};\n\n\n/**\n * Echos the value of a value. Trys to print the value out\n * in the best way possible given the different types.\n *\n * @param {Object} obj The object to print out.\n * @param {Object} opts Optional options object that alters the output.\n */\n/* legacy: obj, showHidden, depth, colors*/\nfunction inspect(obj, opts) {\n  // default options\n  var ctx = {\n    seen: [],\n    stylize: stylizeNoColor\n  };\n  // legacy...\n  if (arguments.length >= 3) ctx.depth = arguments[2];\n  if (arguments.length >= 4) ctx.colors = arguments[3];\n  if (isBoolean(opts)) {\n    // legacy...\n    ctx.showHidden = opts;\n  } else if (opts) {\n    // got an \"options\" object\n    exports._extend(ctx, opts);\n  }\n  // set default options\n  if (isUndefined(ctx.showHidden)) ctx.showHidden = false;\n  if (isUndefined(ctx.depth)) ctx.depth = 2;\n  if (isUndefined(ctx.colors)) ctx.colors = false;\n  if (isUndefined(ctx.customInspect)) ctx.customInspect = true;\n  if (ctx.colors) ctx.stylize = stylizeWithColor;\n  return formatValue(ctx, obj, ctx.depth);\n}\nexports.inspect = inspect;\n\n\n// http://en.wikipedia.org/wiki/ANSI_escape_code#graphics\ninspect.colors = {\n  'bold' : [1, 22],\n  'italic' : [3, 23],\n  'underline' : [4, 24],\n  'inverse' : [7, 27],\n  'white' : [37, 39],\n  'grey' : [90, 39],\n  'black' : [30, 39],\n  'blue' : [34, 39],\n  'cyan' : [36, 39],\n  'green' : [32, 39],\n  'magenta' : [35, 39],\n  'red' : [31, 39],\n  'yellow' : [33, 39]\n};\n\n// Don't use 'blue' not visible on cmd.exe\ninspect.styles = {\n  'special': 'cyan',\n  'number': 'yellow',\n  'boolean': 'yellow',\n  'undefined': 'grey',\n  'null': 'bold',\n  'string': 'green',\n  'date': 'magenta',\n  // \"name\": intentionally not styling\n  'regexp': 'red'\n};\n\n\nfunction stylizeWithColor(str, styleType) {\n  var style = inspect.styles[styleType];\n\n  if (style) {\n    return '\\u001b[' + inspect.colors[style][0] + 'm' + str +\n           '\\u001b[' + inspect.colors[style][1] + 'm';\n  } else {\n    return str;\n  }\n}\n\n\nfunction stylizeNoColor(str, styleType) {\n  return str;\n}\n\n\nfunction arrayToHash(array) {\n  var hash = {};\n\n  array.forEach(function(val, idx) {\n    hash[val] = true;\n  });\n\n  return hash;\n}\n\n\nfunction formatValue(ctx, value, recurseTimes) {\n  // Provide a hook for user-specified inspect functions.\n  // Check that value is an object with an inspect function on it\n  if (ctx.customInspect &&\n      value &&\n      isFunction(value.inspect) &&\n      // Filter out the util module, it's inspect function is special\n      value.inspect !== exports.inspect &&\n      // Also filter out any prototype objects using the circular check.\n      !(value.constructor && value.constructor.prototype === value)) {\n    var ret = value.inspect(recurseTimes, ctx);\n    if (!isString(ret)) {\n      ret = formatValue(ctx, ret, recurseTimes);\n    }\n    return ret;\n  }\n\n  // Primitive types cannot have properties\n  var primitive = formatPrimitive(ctx, value);\n  if (primitive) {\n    return primitive;\n  }\n\n  // Look up the keys of the object.\n  var keys = Object.keys(value);\n  var visibleKeys = arrayToHash(keys);\n\n  if (ctx.showHidden) {\n    keys = Object.getOwnPropertyNames(value);\n  }\n\n  // IE doesn't make error fields non-enumerable\n  // http://msdn.microsoft.com/en-us/library/ie/dww52sbt(v=vs.94).aspx\n  if (isError(value)\n      && (keys.indexOf('message') >= 0 || keys.indexOf('description') >= 0)) {\n    return formatError(value);\n  }\n\n  // Some type of object without properties can be shortcutted.\n  if (keys.length === 0) {\n    if (isFunction(value)) {\n      var name = value.name ? ': ' + value.name : '';\n      return ctx.stylize('[Function' + name + ']', 'special');\n    }\n    if (isRegExp(value)) {\n      return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp');\n    }\n    if (isDate(value)) {\n      return ctx.stylize(Date.prototype.toString.call(value), 'date');\n    }\n    if (isError(value)) {\n      return formatError(value);\n    }\n  }\n\n  var base = '', array = false, braces = ['{', '}'];\n\n  // Make Array say that they are Array\n  if (isArray(value)) {\n    array = true;\n    braces = ['[', ']'];\n  }\n\n  // Make functions say that they are functions\n  if (isFunction(value)) {\n    var n = value.name ? ': ' + value.name : '';\n    base = ' [Function' + n + ']';\n  }\n\n  // Make RegExps say that they are RegExps\n  if (isRegExp(value)) {\n    base = ' ' + RegExp.prototype.toString.call(value);\n  }\n\n  // Make dates with properties first say the date\n  if (isDate(value)) {\n    base = ' ' + Date.prototype.toUTCString.call(value);\n  }\n\n  // Make error with message first say the error\n  if (isError(value)) {\n    base = ' ' + formatError(value);\n  }\n\n  if (keys.length === 0 && (!array || value.length == 0)) {\n    return braces[0] + base + braces[1];\n  }\n\n  if (recurseTimes < 0) {\n    if (isRegExp(value)) {\n      return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp');\n    } else {\n      return ctx.stylize('[Object]', 'special');\n    }\n  }\n\n  ctx.seen.push(value);\n\n  var output;\n  if (array) {\n    output = formatArray(ctx, value, recurseTimes, visibleKeys, keys);\n  } else {\n    output = keys.map(function(key) {\n      return formatProperty(ctx, value, recurseTimes, visibleKeys, key, array);\n    });\n  }\n\n  ctx.seen.pop();\n\n  return reduceToSingleString(output, base, braces);\n}\n\n\nfunction formatPrimitive(ctx, value) {\n  if (isUndefined(value))\n    return ctx.stylize('undefined', 'undefined');\n  if (isString(value)) {\n    var simple = '\\'' + JSON.stringify(value).replace(/^\"|\"$/g, '')\n                                             .replace(/'/g, \"\\\\'\")\n                                             .replace(/\\\\\"/g, '\"') + '\\'';\n    return ctx.stylize(simple, 'string');\n  }\n  if (isNumber(value))\n    return ctx.stylize('' + value, 'number');\n  if (isBoolean(value))\n    return ctx.stylize('' + value, 'boolean');\n  // For some reason typeof null is \"object\", so special case here.\n  if (isNull(value))\n    return ctx.stylize('null', 'null');\n}\n\n\nfunction formatError(value) {\n  return '[' + Error.prototype.toString.call(value) + ']';\n}\n\n\nfunction formatArray(ctx, value, recurseTimes, visibleKeys, keys) {\n  var output = [];\n  for (var i = 0, l = value.length; i < l; ++i) {\n    if (hasOwnProperty(value, String(i))) {\n      output.push(formatProperty(ctx, value, recurseTimes, visibleKeys,\n          String(i), true));\n    } else {\n      output.push('');\n    }\n  }\n  keys.forEach(function(key) {\n    if (!key.match(/^\\d+$/)) {\n      output.push(formatProperty(ctx, value, recurseTimes, visibleKeys,\n          key, true));\n    }\n  });\n  return output;\n}\n\n\nfunction formatProperty(ctx, value, recurseTimes, visibleKeys, key, array) {\n  var name, str, desc;\n  desc = Object.getOwnPropertyDescriptor(value, key) || { value: value[key] };\n  if (desc.get) {\n    if (desc.set) {\n      str = ctx.stylize('[Getter/Setter]', 'special');\n    } else {\n      str = ctx.stylize('[Getter]', 'special');\n    }\n  } else {\n    if (desc.set) {\n      str = ctx.stylize('[Setter]', 'special');\n    }\n  }\n  if (!hasOwnProperty(visibleKeys, key)) {\n    name = '[' + key + ']';\n  }\n  if (!str) {\n    if (ctx.seen.indexOf(desc.value) < 0) {\n      if (isNull(recurseTimes)) {\n        str = formatValue(ctx, desc.value, null);\n      } else {\n        str = formatValue(ctx, desc.value, recurseTimes - 1);\n      }\n      if (str.indexOf('\\n') > -1) {\n        if (array) {\n          str = str.split('\\n').map(function(line) {\n            return '  ' + line;\n          }).join('\\n').substr(2);\n        } else {\n          str = '\\n' + str.split('\\n').map(function(line) {\n            return '   ' + line;\n          }).join('\\n');\n        }\n      }\n    } else {\n      str = ctx.stylize('[Circular]', 'special');\n    }\n  }\n  if (isUndefined(name)) {\n    if (array && key.match(/^\\d+$/)) {\n      return str;\n    }\n    name = JSON.stringify('' + key);\n    if (name.match(/^\"([a-zA-Z_][a-zA-Z_0-9]*)\"$/)) {\n      name = name.substr(1, name.length - 2);\n      name = ctx.stylize(name, 'name');\n    } else {\n      name = name.replace(/'/g, \"\\\\'\")\n                 .replace(/\\\\\"/g, '\"')\n                 .replace(/(^\"|\"$)/g, \"'\");\n      name = ctx.stylize(name, 'string');\n    }\n  }\n\n  return name + ': ' + str;\n}\n\n\nfunction reduceToSingleString(output, base, braces) {\n  var numLinesEst = 0;\n  var length = output.reduce(function(prev, cur) {\n    numLinesEst++;\n    if (cur.indexOf('\\n') >= 0) numLinesEst++;\n    return prev + cur.replace(/\\u001b\\[\\d\\d?m/g, '').length + 1;\n  }, 0);\n\n  if (length > 60) {\n    return braces[0] +\n           (base === '' ? '' : base + '\\n ') +\n           ' ' +\n           output.join(',\\n  ') +\n           ' ' +\n           braces[1];\n  }\n\n  return braces[0] + base + ' ' + output.join(', ') + ' ' + braces[1];\n}\n\n\n// NOTE: These type checking functions intentionally don't use `instanceof`\n// because it is fragile and can be easily faked with `Object.create()`.\nfunction isArray(ar) {\n  return Array.isArray(ar);\n}\nexports.isArray = isArray;\n\nfunction isBoolean(arg) {\n  return typeof arg === 'boolean';\n}\nexports.isBoolean = isBoolean;\n\nfunction isNull(arg) {\n  return arg === null;\n}\nexports.isNull = isNull;\n\nfunction isNullOrUndefined(arg) {\n  return arg == null;\n}\nexports.isNullOrUndefined = isNullOrUndefined;\n\nfunction isNumber(arg) {\n  return typeof arg === 'number';\n}\nexports.isNumber = isNumber;\n\nfunction isString(arg) {\n  return typeof arg === 'string';\n}\nexports.isString = isString;\n\nfunction isSymbol(arg) {\n  return typeof arg === 'symbol';\n}\nexports.isSymbol = isSymbol;\n\nfunction isUndefined(arg) {\n  return arg === void 0;\n}\nexports.isUndefined = isUndefined;\n\nfunction isRegExp(re) {\n  return isObject(re) && objectToString(re) === '[object RegExp]';\n}\nexports.isRegExp = isRegExp;\n\nfunction isObject(arg) {\n  return typeof arg === 'object' && arg !== null;\n}\nexports.isObject = isObject;\n\nfunction isDate(d) {\n  return isObject(d) && objectToString(d) === '[object Date]';\n}\nexports.isDate = isDate;\n\nfunction isError(e) {\n  return isObject(e) &&\n      (objectToString(e) === '[object Error]' || e instanceof Error);\n}\nexports.isError = isError;\n\nfunction isFunction(arg) {\n  return typeof arg === 'function';\n}\nexports.isFunction = isFunction;\n\nfunction isPrimitive(arg) {\n  return arg === null ||\n         typeof arg === 'boolean' ||\n         typeof arg === 'number' ||\n         typeof arg === 'string' ||\n         typeof arg === 'symbol' ||  // ES6 symbol\n         typeof arg === 'undefined';\n}\nexports.isPrimitive = isPrimitive;\n\nexports.isBuffer = require('./support/isBuffer');\n\nfunction objectToString(o) {\n  return Object.prototype.toString.call(o);\n}\n\n\nfunction pad(n) {\n  return n < 10 ? '0' + n.toString(10) : n.toString(10);\n}\n\n\nvar months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep',\n              'Oct', 'Nov', 'Dec'];\n\n// 26 Feb 16:19:34\nfunction timestamp() {\n  var d = new Date();\n  var time = [pad(d.getHours()),\n              pad(d.getMinutes()),\n              pad(d.getSeconds())].join(':');\n  return [d.getDate(), months[d.getMonth()], time].join(' ');\n}\n\n\n// log is just a thin wrapper to console.log that prepends a timestamp\nexports.log = function() {\n  console.log('%s - %s', timestamp(), exports.format.apply(exports, arguments));\n};\n\n\n/**\n * Inherit the prototype methods from one constructor into another.\n *\n * The Function.prototype.inherits from lang.js rewritten as a standalone\n * function (not on Function.prototype). NOTE: If this file is to be loaded\n * during bootstrapping this function needs to be rewritten using some native\n * functions as prototype setup using normal JavaScript does not work as\n * expected during bootstrapping (see mirror.js in r114903).\n *\n * @param {function} ctor Constructor function which needs to inherit the\n *     prototype.\n * @param {function} superCtor Constructor function to inherit prototype from.\n */\nexports.inherits = require('inherits');\n\nexports._extend = function(origin, add) {\n  // Don't do anything if add isn't an object\n  if (!add || !isObject(add)) return origin;\n\n  var keys = Object.keys(add);\n  var i = keys.length;\n  while (i--) {\n    origin[keys[i]] = add[keys[i]];\n  }\n  return origin;\n};\n\nfunction hasOwnProperty(obj, prop) {\n  return Object.prototype.hasOwnProperty.call(obj, prop);\n}\n\n}).call(this,require('_process'),typeof global !== \"undefined\" ? global : typeof self !== \"undefined\" ? self : typeof window !== \"undefined\" ? window : {})\n},{\"./support/isBuffer\":65,\"_process\":51,\"inherits\":48}],67:[function(require,module,exports){\n/* See LICENSE file for terms of use */\n\n/*\n * Text diff implementation.\n *\n * This library supports the following APIS:\n * JsDiff.diffChars: Character by character diff\n * JsDiff.diffWords: Word (as defined by \\b regex) diff which ignores whitespace\n * JsDiff.diffLines: Line based diff\n *\n * JsDiff.diffCss: Diff targeted at CSS content\n *\n * These methods are based on the implementation proposed in\n * \"An O(ND) Difference Algorithm and its Variations\" (Myers, 1986).\n * http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.4.6927\n */\n(function(global, undefined) {\n  var objectPrototypeToString = Object.prototype.toString;\n\n  /*istanbul ignore next*/\n  function map(arr, mapper, that) {\n    if (Array.prototype.map) {\n      return Array.prototype.map.call(arr, mapper, that);\n    }\n\n    var other = new Array(arr.length);\n\n    for (var i = 0, n = arr.length; i < n; i++) {\n      other[i] = mapper.call(that, arr[i], i, arr);\n    }\n    return other;\n  }\n  function clonePath(path) {\n    return { newPos: path.newPos, components: path.components.slice(0) };\n  }\n  function removeEmpty(array) {\n    var ret = [];\n    for (var i = 0; i < array.length; i++) {\n      if (array[i]) {\n        ret.push(array[i]);\n      }\n    }\n    return ret;\n  }\n  function escapeHTML(s) {\n    var n = s;\n    n = n.replace(/&/g, '&amp;');\n    n = n.replace(/</g, '&lt;');\n    n = n.replace(/>/g, '&gt;');\n    n = n.replace(/\"/g, '&quot;');\n\n    return n;\n  }\n\n  // This function handles the presence of circular references by bailing out when encountering an\n  // object that is already on the \"stack\" of items being processed.\n  function canonicalize(obj, stack, replacementStack) {\n    stack = stack || [];\n    replacementStack = replacementStack || [];\n\n    var i;\n\n    for (i = 0; i < stack.length; i += 1) {\n      if (stack[i] === obj) {\n        return replacementStack[i];\n      }\n    }\n\n    var canonicalizedObj;\n\n    if ('[object Array]' === objectPrototypeToString.call(obj)) {\n      stack.push(obj);\n      canonicalizedObj = new Array(obj.length);\n      replacementStack.push(canonicalizedObj);\n      for (i = 0; i < obj.length; i += 1) {\n        canonicalizedObj[i] = canonicalize(obj[i], stack, replacementStack);\n      }\n      stack.pop();\n      replacementStack.pop();\n    } else if (typeof obj === 'object' && obj !== null) {\n      stack.push(obj);\n      canonicalizedObj = {};\n      replacementStack.push(canonicalizedObj);\n      var sortedKeys = [],\n          key;\n      for (key in obj) {\n        sortedKeys.push(key);\n      }\n      sortedKeys.sort();\n      for (i = 0; i < sortedKeys.length; i += 1) {\n        key = sortedKeys[i];\n        canonicalizedObj[key] = canonicalize(obj[key], stack, replacementStack);\n      }\n      stack.pop();\n      replacementStack.pop();\n    } else {\n      canonicalizedObj = obj;\n    }\n    return canonicalizedObj;\n  }\n\n  function buildValues(components, newString, oldString, useLongestToken) {\n    var componentPos = 0,\n        componentLen = components.length,\n        newPos = 0,\n        oldPos = 0;\n\n    for (; componentPos < componentLen; componentPos++) {\n      var component = components[componentPos];\n      if (!component.removed) {\n        if (!component.added && useLongestToken) {\n          var value = newString.slice(newPos, newPos + component.count);\n          value = map(value, function(value, i) {\n            var oldValue = oldString[oldPos + i];\n            return oldValue.length > value.length ? oldValue : value;\n          });\n\n          component.value = value.join('');\n        } else {\n          component.value = newString.slice(newPos, newPos + component.count).join('');\n        }\n        newPos += component.count;\n\n        // Common case\n        if (!component.added) {\n          oldPos += component.count;\n        }\n      } else {\n        component.value = oldString.slice(oldPos, oldPos + component.count).join('');\n        oldPos += component.count;\n\n        // Reverse add and remove so removes are output first to match common convention\n        // The diffing algorithm is tied to add then remove output and this is the simplest\n        // route to get the desired output with minimal overhead.\n        if (componentPos && components[componentPos - 1].added) {\n          var tmp = components[componentPos - 1];\n          components[componentPos - 1] = components[componentPos];\n          components[componentPos] = tmp;\n        }\n      }\n    }\n\n    return components;\n  }\n\n  function Diff(ignoreWhitespace) {\n    this.ignoreWhitespace = ignoreWhitespace;\n  }\n  Diff.prototype = {\n    diff: function(oldString, newString, callback) {\n      var self = this;\n\n      function done(value) {\n        if (callback) {\n          setTimeout(function() { callback(undefined, value); }, 0);\n          return true;\n        } else {\n          return value;\n        }\n      }\n\n      // Handle the identity case (this is due to unrolling editLength == 0\n      if (newString === oldString) {\n        return done([{ value: newString }]);\n      }\n      if (!newString) {\n        return done([{ value: oldString, removed: true }]);\n      }\n      if (!oldString) {\n        return done([{ value: newString, added: true }]);\n      }\n\n      newString = this.tokenize(newString);\n      oldString = this.tokenize(oldString);\n\n      var newLen = newString.length, oldLen = oldString.length;\n      var editLength = 1;\n      var maxEditLength = newLen + oldLen;\n      var bestPath = [{ newPos: -1, components: [] }];\n\n      // Seed editLength = 0, i.e. the content starts with the same values\n      var oldPos = this.extractCommon(bestPath[0], newString, oldString, 0);\n      if (bestPath[0].newPos + 1 >= newLen && oldPos + 1 >= oldLen) {\n        // Identity per the equality and tokenizer\n        return done([{value: newString.join('')}]);\n      }\n\n      // Main worker method. checks all permutations of a given edit length for acceptance.\n      function execEditLength() {\n        for (var diagonalPath = -1 * editLength; diagonalPath <= editLength; diagonalPath += 2) {\n          var basePath;\n          var addPath = bestPath[diagonalPath - 1],\n              removePath = bestPath[diagonalPath + 1],\n              oldPos = (removePath ? removePath.newPos : 0) - diagonalPath;\n          if (addPath) {\n            // No one else is going to attempt to use this value, clear it\n            bestPath[diagonalPath - 1] = undefined;\n          }\n\n          var canAdd = addPath && addPath.newPos + 1 < newLen,\n              canRemove = removePath && 0 <= oldPos && oldPos < oldLen;\n          if (!canAdd && !canRemove) {\n            // If this path is a terminal then prune\n            bestPath[diagonalPath] = undefined;\n            continue;\n          }\n\n          // Select the diagonal that we want to branch from. We select the prior\n          // path whose position in the new string is the farthest from the origin\n          // and does not pass the bounds of the diff graph\n          if (!canAdd || (canRemove && addPath.newPos < removePath.newPos)) {\n            basePath = clonePath(removePath);\n            self.pushComponent(basePath.components, undefined, true);\n          } else {\n            basePath = addPath;   // No need to clone, we've pulled it from the list\n            basePath.newPos++;\n            self.pushComponent(basePath.components, true, undefined);\n          }\n\n          oldPos = self.extractCommon(basePath, newString, oldString, diagonalPath);\n\n          // If we have hit the end of both strings, then we are done\n          if (basePath.newPos + 1 >= newLen && oldPos + 1 >= oldLen) {\n            return done(buildValues(basePath.components, newString, oldString, self.useLongestToken));\n          } else {\n            // Otherwise track this path as a potential candidate and continue.\n            bestPath[diagonalPath] = basePath;\n          }\n        }\n\n        editLength++;\n      }\n\n      // Performs the length of edit iteration. Is a bit fugly as this has to support the\n      // sync and async mode which is never fun. Loops over execEditLength until a value\n      // is produced.\n      if (callback) {\n        (function exec() {\n          setTimeout(function() {\n            // This should not happen, but we want to be safe.\n            /*istanbul ignore next */\n            if (editLength > maxEditLength) {\n              return callback();\n            }\n\n            if (!execEditLength()) {\n              exec();\n            }\n          }, 0);\n        }());\n      } else {\n        while (editLength <= maxEditLength) {\n          var ret = execEditLength();\n          if (ret) {\n            return ret;\n          }\n        }\n      }\n    },\n\n    pushComponent: function(components, added, removed) {\n      var last = components[components.length - 1];\n      if (last && last.added === added && last.removed === removed) {\n        // We need to clone here as the component clone operation is just\n        // as shallow array clone\n        components[components.length - 1] = {count: last.count + 1, added: added, removed: removed };\n      } else {\n        components.push({count: 1, added: added, removed: removed });\n      }\n    },\n    extractCommon: function(basePath, newString, oldString, diagonalPath) {\n      var newLen = newString.length,\n          oldLen = oldString.length,\n          newPos = basePath.newPos,\n          oldPos = newPos - diagonalPath,\n\n          commonCount = 0;\n      while (newPos + 1 < newLen && oldPos + 1 < oldLen && this.equals(newString[newPos + 1], oldString[oldPos + 1])) {\n        newPos++;\n        oldPos++;\n        commonCount++;\n      }\n\n      if (commonCount) {\n        basePath.components.push({count: commonCount});\n      }\n\n      basePath.newPos = newPos;\n      return oldPos;\n    },\n\n    equals: function(left, right) {\n      var reWhitespace = /\\S/;\n      return left === right || (this.ignoreWhitespace && !reWhitespace.test(left) && !reWhitespace.test(right));\n    },\n    tokenize: function(value) {\n      return value.split('');\n    }\n  };\n\n  var CharDiff = new Diff();\n\n  var WordDiff = new Diff(true);\n  var WordWithSpaceDiff = new Diff();\n  WordDiff.tokenize = WordWithSpaceDiff.tokenize = function(value) {\n    return removeEmpty(value.split(/(\\s+|\\b)/));\n  };\n\n  var CssDiff = new Diff(true);\n  CssDiff.tokenize = function(value) {\n    return removeEmpty(value.split(/([{}:;,]|\\s+)/));\n  };\n\n  var LineDiff = new Diff();\n\n  var TrimmedLineDiff = new Diff();\n  TrimmedLineDiff.ignoreTrim = true;\n\n  LineDiff.tokenize = TrimmedLineDiff.tokenize = function(value) {\n    var retLines = [],\n        lines = value.split(/^/m);\n    for (var i = 0; i < lines.length; i++) {\n      var line = lines[i],\n          lastLine = lines[i - 1],\n          lastLineLastChar = lastLine && lastLine[lastLine.length - 1];\n\n      // Merge lines that may contain windows new lines\n      if (line === '\\n' && lastLineLastChar === '\\r') {\n          retLines[retLines.length - 1] = retLines[retLines.length - 1].slice(0, -1) + '\\r\\n';\n      } else {\n        if (this.ignoreTrim) {\n          line = line.trim();\n          // add a newline unless this is the last line.\n          if (i < lines.length - 1) {\n            line += '\\n';\n          }\n        }\n        retLines.push(line);\n      }\n    }\n\n    return retLines;\n  };\n\n  var PatchDiff = new Diff();\n  PatchDiff.tokenize = function(value) {\n    var ret = [],\n        linesAndNewlines = value.split(/(\\n|\\r\\n)/);\n\n    // Ignore the final empty token that occurs if the string ends with a new line\n    if (!linesAndNewlines[linesAndNewlines.length - 1]) {\n      linesAndNewlines.pop();\n    }\n\n    // Merge the content and line separators into single tokens\n    for (var i = 0; i < linesAndNewlines.length; i++) {\n      var line = linesAndNewlines[i];\n\n      if (i % 2) {\n        ret[ret.length - 1] += line;\n      } else {\n        ret.push(line);\n      }\n    }\n    return ret;\n  };\n\n  var SentenceDiff = new Diff();\n  SentenceDiff.tokenize = function(value) {\n    return removeEmpty(value.split(/(\\S.+?[.!?])(?=\\s+|$)/));\n  };\n\n  var JsonDiff = new Diff();\n  // Discriminate between two lines of pretty-printed, serialized JSON where one of them has a\n  // dangling comma and the other doesn't. Turns out including the dangling comma yields the nicest output:\n  JsonDiff.useLongestToken = true;\n  JsonDiff.tokenize = LineDiff.tokenize;\n  JsonDiff.equals = function(left, right) {\n    return LineDiff.equals(left.replace(/,([\\r\\n])/g, '$1'), right.replace(/,([\\r\\n])/g, '$1'));\n  };\n\n  var JsDiff = {\n    Diff: Diff,\n\n    diffChars: function(oldStr, newStr, callback) { return CharDiff.diff(oldStr, newStr, callback); },\n    diffWords: function(oldStr, newStr, callback) { return WordDiff.diff(oldStr, newStr, callback); },\n    diffWordsWithSpace: function(oldStr, newStr, callback) { return WordWithSpaceDiff.diff(oldStr, newStr, callback); },\n    diffLines: function(oldStr, newStr, callback) { return LineDiff.diff(oldStr, newStr, callback); },\n    diffTrimmedLines: function(oldStr, newStr, callback) { return TrimmedLineDiff.diff(oldStr, newStr, callback); },\n\n    diffSentences: function(oldStr, newStr, callback) { return SentenceDiff.diff(oldStr, newStr, callback); },\n\n    diffCss: function(oldStr, newStr, callback) { return CssDiff.diff(oldStr, newStr, callback); },\n    diffJson: function(oldObj, newObj, callback) {\n      return JsonDiff.diff(\n        typeof oldObj === 'string' ? oldObj : JSON.stringify(canonicalize(oldObj), undefined, '  '),\n        typeof newObj === 'string' ? newObj : JSON.stringify(canonicalize(newObj), undefined, '  '),\n        callback\n      );\n    },\n\n    createTwoFilesPatch: function(oldFileName, newFileName, oldStr, newStr, oldHeader, newHeader) {\n      var ret = [];\n\n      if (oldFileName == newFileName) {\n        ret.push('Index: ' + oldFileName);\n      }\n      ret.push('===================================================================');\n      ret.push('--- ' + oldFileName + (typeof oldHeader === 'undefined' ? '' : '\\t' + oldHeader));\n      ret.push('+++ ' + newFileName + (typeof newHeader === 'undefined' ? '' : '\\t' + newHeader));\n\n      var diff = PatchDiff.diff(oldStr, newStr);\n      diff.push({value: '', lines: []});   // Append an empty value to make cleanup easier\n\n      // Formats a given set of lines for printing as context lines in a patch\n      function contextLines(lines) {\n        return map(lines, function(entry) { return ' ' + entry; });\n      }\n\n      // Outputs the no newline at end of file warning if needed\n      function eofNL(curRange, i, current) {\n        var last = diff[diff.length - 2],\n            isLast = i === diff.length - 2,\n            isLastOfType = i === diff.length - 3 && current.added !== last.added;\n\n        // Figure out if this is the last line for the given file and missing NL\n        if (!(/\\n$/.test(current.value)) && (isLast || isLastOfType)) {\n          curRange.push('\\\\ No newline at end of file');\n        }\n      }\n\n      var oldRangeStart = 0, newRangeStart = 0, curRange = [],\n          oldLine = 1, newLine = 1;\n      for (var i = 0; i < diff.length; i++) {\n        var current = diff[i],\n            lines = current.lines || current.value.replace(/\\n$/, '').split('\\n');\n        current.lines = lines;\n\n        if (current.added || current.removed) {\n          // If we have previous context, start with that\n          if (!oldRangeStart) {\n            var prev = diff[i - 1];\n            oldRangeStart = oldLine;\n            newRangeStart = newLine;\n\n            if (prev) {\n              curRange = contextLines(prev.lines.slice(-4));\n              oldRangeStart -= curRange.length;\n              newRangeStart -= curRange.length;\n            }\n          }\n\n          // Output our changes\n          curRange.push.apply(curRange, map(lines, function(entry) {\n            return (current.added ? '+' : '-') + entry;\n          }));\n          eofNL(curRange, i, current);\n\n          // Track the updated file position\n          if (current.added) {\n            newLine += lines.length;\n          } else {\n            oldLine += lines.length;\n          }\n        } else {\n          // Identical context lines. Track line changes\n          if (oldRangeStart) {\n            // Close out any changes that have been output (or join overlapping)\n            if (lines.length <= 8 && i < diff.length - 2) {\n              // Overlapping\n              curRange.push.apply(curRange, contextLines(lines));\n            } else {\n              // end the range and output\n              var contextSize = Math.min(lines.length, 4);\n              ret.push(\n                  '@@ -' + oldRangeStart + ',' + (oldLine - oldRangeStart + contextSize)\n                  + ' +' + newRangeStart + ',' + (newLine - newRangeStart + contextSize)\n                  + ' @@');\n              ret.push.apply(ret, curRange);\n              ret.push.apply(ret, contextLines(lines.slice(0, contextSize)));\n              if (lines.length <= 4) {\n                eofNL(ret, i, current);\n              }\n\n              oldRangeStart = 0;\n              newRangeStart = 0;\n              curRange = [];\n            }\n          }\n          oldLine += lines.length;\n          newLine += lines.length;\n        }\n      }\n\n      return ret.join('\\n') + '\\n';\n    },\n\n    createPatch: function(fileName, oldStr, newStr, oldHeader, newHeader) {\n      return JsDiff.createTwoFilesPatch(fileName, fileName, oldStr, newStr, oldHeader, newHeader);\n    },\n\n    applyPatch: function(oldStr, uniDiff) {\n      var diffstr = uniDiff.split('\\n'),\n          hunks = [],\n          i = 0,\n          remEOFNL = false,\n          addEOFNL = false;\n\n      // Skip to the first change hunk\n      while (i < diffstr.length && !(/^@@/.test(diffstr[i]))) {\n        i++;\n      }\n\n      // Parse the unified diff\n      for (; i < diffstr.length; i++) {\n        if (diffstr[i][0] === '@') {\n          var chnukHeader = diffstr[i].split(/@@ -(\\d+),(\\d+) \\+(\\d+),(\\d+) @@/);\n          hunks.unshift({\n            start: chnukHeader[3],\n            oldlength: +chnukHeader[2],\n            removed: [],\n            newlength: chnukHeader[4],\n            added: []\n          });\n        } else if (diffstr[i][0] === '+') {\n          hunks[0].added.push(diffstr[i].substr(1));\n        } else if (diffstr[i][0] === '-') {\n          hunks[0].removed.push(diffstr[i].substr(1));\n        } else if (diffstr[i][0] === ' ') {\n          hunks[0].added.push(diffstr[i].substr(1));\n          hunks[0].removed.push(diffstr[i].substr(1));\n        } else if (diffstr[i][0] === '\\\\') {\n          if (diffstr[i - 1][0] === '+') {\n            remEOFNL = true;\n          } else if (diffstr[i - 1][0] === '-') {\n            addEOFNL = true;\n          }\n        }\n      }\n\n      // Apply the diff to the input\n      var lines = oldStr.split('\\n');\n      for (i = hunks.length - 1; i >= 0; i--) {\n        var hunk = hunks[i];\n        // Sanity check the input string. Bail if we don't match.\n        for (var j = 0; j < hunk.oldlength; j++) {\n          if (lines[hunk.start - 1 + j] !== hunk.removed[j]) {\n            return false;\n          }\n        }\n        Array.prototype.splice.apply(lines, [hunk.start - 1, hunk.oldlength].concat(hunk.added));\n      }\n\n      // Handle EOFNL insertion/removal\n      if (remEOFNL) {\n        while (!lines[lines.length - 1]) {\n          lines.pop();\n        }\n      } else if (addEOFNL) {\n        lines.push('');\n      }\n      return lines.join('\\n');\n    },\n\n    convertChangesToXML: function(changes) {\n      var ret = [];\n      for (var i = 0; i < changes.length; i++) {\n        var change = changes[i];\n        if (change.added) {\n          ret.push('<ins>');\n        } else if (change.removed) {\n          ret.push('<del>');\n        }\n\n        ret.push(escapeHTML(change.value));\n\n        if (change.added) {\n          ret.push('</ins>');\n        } else if (change.removed) {\n          ret.push('</del>');\n        }\n      }\n      return ret.join('');\n    },\n\n    // See: http://code.google.com/p/google-diff-match-patch/wiki/API\n    convertChangesToDMP: function(changes) {\n      var ret = [],\n          change,\n          operation;\n      for (var i = 0; i < changes.length; i++) {\n        change = changes[i];\n        if (change.added) {\n          operation = 1;\n        } else if (change.removed) {\n          operation = -1;\n        } else {\n          operation = 0;\n        }\n\n        ret.push([operation, change.value]);\n      }\n      return ret;\n    },\n\n    canonicalize: canonicalize\n  };\n\n  /*istanbul ignore next */\n  /*global module */\n  if (typeof module !== 'undefined' && module.exports) {\n    module.exports = JsDiff;\n  } else if (typeof define === 'function' && define.amd) {\n    /*global define */\n    define([], function() { return JsDiff; });\n  } else if (typeof global.JsDiff === 'undefined') {\n    global.JsDiff = JsDiff;\n  }\n}(this));\n\n},{}],68:[function(require,module,exports){\n'use strict';\n\nvar matchOperatorsRe = /[|\\\\{}()[\\]^$+*?.]/g;\n\nmodule.exports = function (str) {\n\tif (typeof str !== 'string') {\n\t\tthrow new TypeError('Expected a string');\n\t}\n\n\treturn str.replace(matchOperatorsRe,  '\\\\$&');\n};\n\n},{}],69:[function(require,module,exports){\n(function (process){\n// Growl - Copyright TJ Holowaychuk <tj@vision-media.ca> (MIT Licensed)\n\n/**\n * Module dependencies.\n */\n\nvar exec = require('child_process').exec\n  , fs = require('fs')\n  , path = require('path')\n  , exists = fs.existsSync || path.existsSync\n  , os = require('os')\n  , quote = JSON.stringify\n  , cmd;\n\nfunction which(name) {\n  var paths = process.env.PATH.split(':');\n  var loc;\n  \n  for (var i = 0, len = paths.length; i < len; ++i) {\n    loc = path.join(paths[i], name);\n    if (exists(loc)) return loc;\n  }\n}\n\nswitch(os.type()) {\n  case 'Darwin':\n    if (which('terminal-notifier')) {\n      cmd = {\n          type: \"Darwin-NotificationCenter\"\n        , pkg: \"terminal-notifier\"\n        , msg: '-message'\n        , title: '-title'\n        , subtitle: '-subtitle'\n        , priority: {\n              cmd: '-execute'\n            , range: []\n          }\n      };\n    } else {\n      cmd = {\n          type: \"Darwin-Growl\"\n        , pkg: \"growlnotify\"\n        , msg: '-m'\n        , sticky: '--sticky'\n        , priority: {\n              cmd: '--priority'\n            , range: [\n                -2\n              , -1\n              , 0\n              , 1\n              , 2\n              , \"Very Low\"\n              , \"Moderate\"\n              , \"Normal\"\n              , \"High\"\n              , \"Emergency\"\n            ]\n          }\n      };\n    }\n    break;\n  case 'Linux':\n    cmd = {\n        type: \"Linux\"\n      , pkg: \"notify-send\"\n      , msg: ''\n      , sticky: '-t 0'\n      , icon: '-i'\n      , priority: {\n          cmd: '-u'\n        , range: [\n            \"low\"\n          , \"normal\"\n          , \"critical\"\n        ]\n      }\n    };\n    break;\n  case 'Windows_NT':\n    cmd = {\n        type: \"Windows\"\n      , pkg: \"growlnotify\"\n      , msg: ''\n      , sticky: '/s:true'\n      , title: '/t:'\n      , icon: '/i:'\n      , priority: {\n            cmd: '/p:'\n          , range: [\n              -2\n            , -1\n            , 0\n            , 1\n            , 2\n          ]\n        }\n    };\n    break;\n}\n\n/**\n * Expose `growl`.\n */\n\nexports = module.exports = growl;\n\n/**\n * Node-growl version.\n */\n\nexports.version = '1.4.1'\n\n/**\n * Send growl notification _msg_ with _options_.\n *\n * Options:\n *\n *  - title   Notification title\n *  - sticky  Make the notification stick (defaults to false)\n *  - priority  Specify an int or named key (default is 0)\n *  - name    Application name (defaults to growlnotify)\n *  - image\n *    - path to an icon sets --iconpath\n *    - path to an image sets --image\n *    - capitalized word sets --appIcon\n *    - filename uses extname as --icon\n *    - otherwise treated as --icon\n *\n * Examples:\n *\n *   growl('New email')\n *   growl('5 new emails', { title: 'Thunderbird' })\n *   growl('Email sent', function(){\n *     // ... notification sent\n *   })\n *\n * @param {string} msg\n * @param {object} options\n * @param {function} fn\n * @api public\n */\n\nfunction growl(msg, options, fn) {\n  var image\n    , args\n    , options = options || {}\n    , fn = fn || function(){};\n\n  // noop\n  if (!cmd) return fn(new Error('growl not supported on this platform'));\n  args = [cmd.pkg];\n\n  // image\n  if (image = options.image) {\n    switch(cmd.type) {\n      case 'Darwin-Growl':\n        var flag, ext = path.extname(image).substr(1)\n        flag = flag || ext == 'icns' && 'iconpath'\n        flag = flag || /^[A-Z]/.test(image) && 'appIcon'\n        flag = flag || /^png|gif|jpe?g$/.test(ext) && 'image'\n        flag = flag || ext && (image = ext) && 'icon'\n        flag = flag || 'icon'\n        args.push('--' + flag, quote(image))\n        break;\n      case 'Linux':\n        args.push(cmd.icon, quote(image));\n        // libnotify defaults to sticky, set a hint for transient notifications\n        if (!options.sticky) args.push('--hint=int:transient:1');\n        break;\n      case 'Windows':\n        args.push(cmd.icon + quote(image));\n        break;\n    }\n  }\n\n  // sticky\n  if (options.sticky) args.push(cmd.sticky);\n\n  // priority\n  if (options.priority) {\n    var priority = options.priority + '';\n    var checkindexOf = cmd.priority.range.indexOf(priority);\n    if (~cmd.priority.range.indexOf(priority)) {\n      args.push(cmd.priority, options.priority);\n    }\n  }\n\n  // name\n  if (options.name && cmd.type === \"Darwin-Growl\") {\n    args.push('--name', options.name);\n  }\n\n  switch(cmd.type) {\n    case 'Darwin-Growl':\n      args.push(cmd.msg);\n      args.push(quote(msg));\n      if (options.title) args.push(quote(options.title));\n      break;\n    case 'Darwin-NotificationCenter':\n      args.push(cmd.msg);\n      args.push(quote(msg));\n      if (options.title) {\n        args.push(cmd.title);\n        args.push(quote(options.title));\n      }\n      if (options.subtitle) {\n        args.push(cmd.subtitle);\n        args.push(quote(options.subtitle));\n      }\n      break;\n    case 'Darwin-Growl':\n      args.push(cmd.msg);\n      args.push(quote(msg));\n      if (options.title) args.push(quote(options.title));\n      break;\n    case 'Linux':\n      if (options.title) {\n        args.push(quote(options.title));\n        args.push(cmd.msg);\n        args.push(quote(msg));\n      } else {\n        args.push(quote(msg));\n      }\n      break;\n    case 'Windows':\n      args.push(quote(msg));\n      if (options.title) args.push(cmd.title + quote(options.title));\n      break;\n  }\n\n  // execute\n  exec(args.join(' '), fn);\n};\n\n}).call(this,require('_process'))\n},{\"_process\":51,\"child_process\":41,\"fs\":41,\"os\":50,\"path\":41}],70:[function(require,module,exports){\n(function (process,global){\n/**\n * Shim process.stdout.\n */\n\nprocess.stdout = require('browser-stdout')();\n\nvar Mocha = require('../');\n\n/**\n * Create a Mocha instance.\n *\n * @return {undefined}\n */\n\nvar mocha = new Mocha({ reporter: 'html' });\n\n/**\n * Save timer references to avoid Sinon interfering (see GH-237).\n */\n\nvar Date = global.Date;\nvar setTimeout = global.setTimeout;\nvar setInterval = global.setInterval;\nvar clearTimeout = global.clearTimeout;\nvar clearInterval = global.clearInterval;\n\nvar uncaughtExceptionHandlers = [];\n\nvar originalOnerrorHandler = global.onerror;\n\n/**\n * Remove uncaughtException listener.\n * Revert to original onerror handler if previously defined.\n */\n\nprocess.removeListener = function(e, fn){\n  if ('uncaughtException' == e) {\n    if (originalOnerrorHandler) {\n      global.onerror = originalOnerrorHandler;\n    } else {\n      global.onerror = function() {};\n    }\n    var i = Mocha.utils.indexOf(uncaughtExceptionHandlers, fn);\n    if (i != -1) { uncaughtExceptionHandlers.splice(i, 1); }\n  }\n};\n\n/**\n * Implements uncaughtException listener.\n */\n\nprocess.on = function(e, fn){\n  if ('uncaughtException' == e) {\n    global.onerror = function(err, url, line){\n      fn(new Error(err + ' (' + url + ':' + line + ')'));\n      return !mocha.allowUncaught;\n    };\n    uncaughtExceptionHandlers.push(fn);\n  }\n};\n\n// The BDD UI is registered by default, but no UI will be functional in the\n// browser without an explicit call to the overridden `mocha.ui` (see below).\n// Ensure that this default UI does not expose its methods to the global scope.\nmocha.suite.removeAllListeners('pre-require');\n\nvar immediateQueue = []\n  , immediateTimeout;\n\nfunction timeslice() {\n  var immediateStart = new Date().getTime();\n  while (immediateQueue.length && (new Date().getTime() - immediateStart) < 100) {\n    immediateQueue.shift()();\n  }\n  if (immediateQueue.length) {\n    immediateTimeout = setTimeout(timeslice, 0);\n  } else {\n    immediateTimeout = null;\n  }\n}\n\n/**\n * High-performance override of Runner.immediately.\n */\n\nMocha.Runner.immediately = function(callback) {\n  immediateQueue.push(callback);\n  if (!immediateTimeout) {\n    immediateTimeout = setTimeout(timeslice, 0);\n  }\n};\n\n/**\n * Function to allow assertion libraries to throw errors directly into mocha.\n * This is useful when running tests in a browser because window.onerror will\n * only receive the 'message' attribute of the Error.\n */\nmocha.throwError = function(err) {\n  Mocha.utils.forEach(uncaughtExceptionHandlers, function (fn) {\n    fn(err);\n  });\n  throw err;\n};\n\n/**\n * Override ui to ensure that the ui functions are initialized.\n * Normally this would happen in Mocha.prototype.loadFiles.\n */\n\nmocha.ui = function(ui){\n  Mocha.prototype.ui.call(this, ui);\n  this.suite.emit('pre-require', global, null, this);\n  return this;\n};\n\n/**\n * Setup mocha with the given setting options.\n */\n\nmocha.setup = function(opts){\n  if ('string' == typeof opts) opts = { ui: opts };\n  for (var opt in opts) this[opt](opts[opt]);\n  return this;\n};\n\n/**\n * Run mocha, returning the Runner.\n */\n\nmocha.run = function(fn){\n  var options = mocha.options;\n  mocha.globals('location');\n\n  var query = Mocha.utils.parseQuery(global.location.search || '');\n  if (query.grep) mocha.grep(new RegExp(query.grep));\n  if (query.fgrep) mocha.grep(query.fgrep);\n  if (query.invert) mocha.invert();\n\n  return Mocha.prototype.run.call(mocha, function(err){\n    // The DOM Document is not available in Web Workers.\n    var document = global.document;\n    if (document && document.getElementById('mocha') && options.noHighlighting !== true) {\n      Mocha.utils.highlightTags('code');\n    }\n    if (fn) fn(err);\n  });\n};\n\n/**\n * Expose the process shim.\n * https://github.com/mochajs/mocha/pull/916\n */\n\nMocha.process = process;\n\n/**\n * Expose mocha.\n */\n\nwindow.Mocha = Mocha;\nwindow.mocha = mocha;\n\n}).call(this,require('_process'),typeof global !== \"undefined\" ? global : typeof self !== \"undefined\" ? self : typeof window !== \"undefined\" ? window : {})\n},{\"../\":1,\"_process\":51,\"browser-stdout\":40}]},{},[70]);\n"
  },
  {
    "path": "app_backend/static/plugin/JavaScript-Templates-3.8.0/.gitignore",
    "content": ".DS_Store\nnode_modules\n"
  },
  {
    "path": "app_backend/static/plugin/JavaScript-Templates-3.8.0/.npmignore",
    "content": "*\n!js/*.js\n!js/*.js.map\n"
  },
  {
    "path": "app_backend/static/plugin/JavaScript-Templates-3.8.0/.travis.yml",
    "content": "language: node_js\nnode_js:\n  - \"stable\"\n"
  },
  {
    "path": "app_backend/static/plugin/JavaScript-Templates-3.8.0/README.md",
    "content": "# JavaScript Templates\n\n## Demo\n[JavaScript Templates Demo](https://blueimp.github.io/JavaScript-Templates/)\n\n## Description\n1KB lightweight, fast & powerful JavaScript templating engine with zero\ndependencies. Compatible with server-side environments like Node.js, module\nloaders like RequireJS, Browserify or webpack and all web browsers.\n\n## Usage\n\n### Client-side\nInclude the (minified) JavaScript Templates script in your HTML markup:\n\n```html\n<script src=\"js/tmpl.min.js\"></script>\n```\n\nAdd a script section with type **\"text/x-tmpl\"**, a unique **id** property and\nyour template definition as content:\n\n```html\n<script type=\"text/x-tmpl\" id=\"tmpl-demo\">\n<h3>{%=o.title%}</h3>\n<p>Released under the\n<a href=\"{%=o.license.url%}\">{%=o.license.name%}</a>.</p>\n<h4>Features</h4>\n<ul>\n{% for (var i=0; i<o.features.length; i++) { %}\n    <li>{%=o.features[i]%}</li>\n{% } %}\n</ul>\n</script>\n```\n\n**\"o\"** (the lowercase letter) is a reference to the data parameter of the\ntemplate function (see the API section on how to modify this identifier).\n\nIn your application code, create a JavaScript object to use as data for the\ntemplate:\n\n```js\nvar data = {\n    \"title\": \"JavaScript Templates\",\n    \"license\": {\n        \"name\": \"MIT license\",\n        \"url\": \"https://opensource.org/licenses/MIT\"\n    },\n    \"features\": [\n        \"lightweight & fast\",\n        \"powerful\",\n        \"zero dependencies\"\n    ]\n};\n```\n\nIn a real application, this data could be the result of retrieving a\n[JSON](http://json.org/) resource.\n\nRender the result by calling the **tmpl()** method with the id of the template\nand the data object as arguments:\n\n```js\ndocument.getElementById(\"result\").innerHTML = tmpl(\"tmpl-demo\", data);\n```\n\n### Server-side\n\nThe following is an example how to use the JavaScript Templates engine on the\nserver-side with [node.js](http://nodejs.org/).\n\nCreate a new directory and add the **tmpl.js** file. Or alternatively, install\nthe **blueimp-tmpl** package with [npm](https://www.npmjs.org/):\n\n```sh\nnpm install blueimp-tmpl\n```\n\nAdd a file **template.html** with the following content:\n\n```html\n<!DOCTYPE HTML>\n<title>{%=o.title%}</title>\n<h3><a href=\"{%=o.url%}\">{%=o.title%}</a></h3>\n<h4>Features</h4>\n<ul>\n{% for (var i=0; i<o.features.length; i++) { %}\n    <li>{%=o.features[i]%}</li>\n{% } %}\n</ul>\n```\n\nAdd a file **server.js** with the following content:\n\n```js\nrequire(\"http\").createServer(function (req, res) {\n    var fs = require(\"fs\"),\n        // The tmpl module exports the tmpl() function:\n        tmpl = require(\"./tmpl\"),\n        // Use the following version if you installed the package with npm:\n        // tmpl = require(\"blueimp-tmpl\"),\n        // Sample data:\n        data = {\n            \"title\": \"JavaScript Templates\",\n            \"url\": \"https://github.com/blueimp/JavaScript-Templates\",\n            \"features\": [\n                \"lightweight & fast\",\n                \"powerful\",\n                \"zero dependencies\"\n            ]\n        };\n    // Override the template loading method:\n    tmpl.load = function (id) {\n        var filename = id + \".html\";\n        console.log(\"Loading \" + filename);\n        return fs.readFileSync(filename, \"utf8\");\n    };\n    res.writeHead(200, {\"Content-Type\": \"text/x-tmpl\"});\n    // Render the content:\n    res.end(tmpl(\"template\", data));\n}).listen(8080, \"localhost\");\nconsole.log(\"Server running at http://localhost:8080/\");\n```\n\nRun the application with the following command:\n\n```sh\nnode server.js\n```\n\n## Requirements\nThe JavaScript Templates script has zero dependencies.\n\n## API\n\n### tmpl() function\nThe **tmpl()** function is added to the global **window** object and can be\ncalled as global function:\n\n```js\nvar result = tmpl(\"tmpl-demo\", data);\n```\n\nThe **tmpl()** function can be called with the id of a template, or with a\ntemplate string:\n\n```js\nvar result = tmpl(\"<h3>{%=o.title%}</h3>\", data);\n```\n\nIf called without second argument, **tmpl()** returns a reusable template\nfunction:\n\n```js\nvar func = tmpl(\"<h3>{%=o.title%}</h3>\");\ndocument.getElementById(\"result\").innerHTML = func(data);\n```\n\n### Templates cache\nTemplates loaded by id are cached in the map **tmpl.cache**:\n\n```js\nvar func = tmpl(\"tmpl-demo\"), // Loads and parses the template\n    cached = typeof tmpl.cache[\"tmpl-demo\"] === \"function\", // true\n    result = tmpl(\"tmpl-demo\", data); // Uses cached template function\n\ntmpl.cache[\"tmpl-demo\"] = null;\nresult = tmpl(\"tmpl-demo\", data); // Loads and parses the template again\n```\n\n### Output encoding\nThe method **tmpl.encode** is used to escape HTML special characters in the\ntemplate output:\n\n```js\nvar output = tmpl.encode(\"<>&\\\"'\\x00\"); // Renders \"&lt;&gt;&amp;&quot;&#39;\"\n```\n\n**tmpl.encode** makes use of the regular expression **tmpl.encReg** and the\nencoding map **tmpl.encMap** to match and replace special characters, which can\nbe modified to change the behavior of the output encoding.  \nStrings matched by the regular expression, but not found in the encoding map are\nremoved from the output. This allows for example to automatically trim input\nvalues (removing whitespace from the start and end of the string):\n\n```js\ntmpl.encReg = /(^\\s+)|(\\s+$)|[<>&\"'\\x00]/g;\nvar output = tmpl.encode(\"    Banana!    \"); // Renders \"Banana\" (without whitespace)\n```\n\n### Local helper variables\nThe local variables available inside the templates are the following:\n\n* **o**: The data object given as parameter to the template function\n(see the next section on how to modify the parameter name).\n* **tmpl**: A reference to the **tmpl** function object.\n* **_s**: The string for the rendered result content.\n* **_e**: A reference to the **tmpl.encode** method.\n* **print**: Helper function to add content to the rendered result string.\n* **include**: Helper function to include the return value of a different\ntemplate in the result.\n\nTo introduce additional local helper variables, the string **tmpl.helper** can\nbe extended. The following adds a convenience function for *console.log* and a\nstreaming function, that streams the template rendering result back to the\ncallback argument\n(note the comma at the beginning of each variable declaration):\n\n```js\ntmpl.helper += \",log=function(){console.log.apply(console, arguments)}\" +\n    \",st='',stream=function(cb){var l=st.length;st=_s;cb( _s.slice(l));}\";\n```\n\nThose new helper functions could be used to stream the template contents to the\nconsole output:\n\n```html\n<script type=\"text/x-tmpl\" id=\"tmpl-demo\">\n<h3>{%=o.title%}</h3>\n{% stream(log); %}\n<p>Released under the\n<a href=\"{%=o.license.url%}\">{%=o.license.name%}</a>.</p>\n{% stream(log); %}\n<h4>Features</h4>\n<ul>\n{% stream(log); %}\n{% for (var i=0; i<o.features.length; i++) { %}\n    <li>{%=o.features[i]%}</li>\n    {% stream(log); %}\n{% } %}\n</ul>\n{% stream(log); %}\n</script>\n```\n\n### Template function argument\nThe generated template functions accept one argument, which is the data object\ngiven to the **tmpl(id, data)** function. This argument is available inside the\ntemplate definitions as parameter **o** (the lowercase letter).\n\nThe argument name can be modified by overriding **tmpl.arg**:\n\n```js\ntmpl.arg = \"p\";\n\n// Renders \"<h3>JavaScript Templates</h3>\":\nvar result = tmpl(\"<h3>{%=p.title%}</h3>\", {title: \"JavaScript Templates\"});\n```\n\n### Template parsing\nThe template contents are matched and replaced using the regular expression\n**tmpl.regexp** and the replacement function **tmpl.func**.\nThe replacement function operates based on the\n[parenthesized submatch strings](https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/String/replace#Specifying_a_function_as_a_parameter).\n\nTo use different tags for the template syntax, override **tmpl.regexp** with a\nmodified regular expression, by exchanging all occurrences of \"{%\" and \"%}\",\ne.g. with \"[%\" and \"%]\":\n\n```js\ntmpl.regexp = /([\\s'\\\\])(?!(?:[^[]|\\[(?!%))*%\\])|(?:\\[%(=|#)([\\s\\S]+?)%\\])|(\\[%)|(%\\])/g;\n```\n\nBy default, the plugin preserves whitespace\n(newlines, carriage returns, tabs and spaces).\nTo strip unnecessary whitespace, you can override the **tmpl.func** function,\ne.g. with the following code:\n\n```js\nvar originalFunc = tmpl.func;\ntmpl.func = function (s, p1, p2, p3, p4, p5, offset, str) {\n    if (p1 && /\\s/.test(p1)) {\n        if (!offset || /\\s/.test(str.charAt(offset - 1)) ||\n                /^\\s+$/g.test(str.slice(offset))) {\n            return '';\n        }\n        return ' ';\n    }\n    return originalFunc.apply(tmpl, arguments);\n};\n```\n\n## Templates syntax\n\n### Interpolation\nPrint variable with HTML special characters escaped:\n\n```html\n<h3>{%=o.title%}</h3>\n```\n\nPrint variable without escaping:\n\n```html\n<h3>{%#o.user_id%}</h3>\n```\n\nPrint output of function calls:\n\n```html\n<a href=\"{%=encodeURI(o.url)%}\">Website</a>\n```\n\nUse dot notation to print nested properties:\n\n```html\n<strong>{%=o.author.name%}</strong>\n```\n\n### Evaluation\nUse **print(str)** to add escaped content to the output:\n\n```html\n<span>Year: {% var d=new Date(); print(d.getFullYear()); %}</span>\n```\n\nUse **print(str, true)** to add unescaped content to the output:\n\n```html\n<span>{% print(\"Fast &amp; powerful\", true); %}</span>\n```\n\nUse **include(str, obj)** to include content from a different template:\n\n```html\n<div>\n{% include('tmpl-link', {name: \"Website\", url: \"https://example.org\"}); %}\n</div>\n```\n\n**If else condition**:\n\n```html\n{% if (o.author.url) { %}\n    <a href=\"{%=encodeURI(o.author.url)%}\">{%=o.author.name%}</a>\n{% } else { %}\n    <em>No author url.</em>\n{% } %}\n```\n\n**For loop**:\n\n```html\n<ul>\n{% for (var i=0; i<o.features.length; i++) { %}\n    <li>{%=o.features[i]%}</li>\n{% } %}\n</ul>\n```\n\n## Compiled templates\nThe JavaScript Templates project comes with a compilation script, that allows\nyou to compile your templates into JavaScript code and combine them with a\nminimal Templates runtime into one combined JavaScript file.\n\nThe compilation script is built for [node.js](http://nodejs.org/).  \nTo use it, first install the JavaScript Templates project via\n[npm](https://www.npmjs.org/):\n\n```sh\nnpm install blueimp-tmpl\n```\n\nThis will put the executable **tmpl.js** into the folder **node_modules/.bin**.\nIt will also make it available on your PATH if you install the package globally\n(by adding the **-g** flag to the install command).\n\nThe **tmpl.js** executable accepts the paths to one or multiple template files\nas command line arguments and prints the generated JavaScript code to the\nconsole output. The following command line shows you how to store the generated\ncode in a new JavaScript file that can be included in your project:\n\n```sh\ntmpl.js index.html > tmpl.js\n```\n\nThe files given as command line arguments to **tmpl.js** can either be pure\ntemplate files or HTML documents with embedded template script sections.\nFor the pure template files, the file names (without extension) serve as\ntemplate ids.  \nThe generated file can be included in your project as a replacement for the\noriginal **tmpl.js** runtime. It provides you with the same API and provides a\n**tmpl(id, data)** function that accepts the id of one of your templates as\nfirst and a data object as optional second parameter.\n\n## Tests\nThe JavaScript Templates project comes with\n[Unit Tests](https://en.wikipedia.org/wiki/Unit_testing).  \nThere are two different ways to run the tests:\n\n* Open test/index.html in your browser or\n* run `npm test` in the Terminal in the root path of the repository package.\n\nThe first one tests the browser integration,\nthe second one the [node.js](http://nodejs.org/) integration.\n\n## License\nThe JavaScript Templates script is released under the\n[MIT license](https://opensource.org/licenses/MIT).\n"
  },
  {
    "path": "app_backend/static/plugin/JavaScript-Templates-3.8.0/css/demo.css",
    "content": "/*\n * JavaScript Templates Demo CSS\n * https://github.com/blueimp/JavaScript-Templates\n *\n * Copyright 2013, Sebastian Tschan\n * https://blueimp.net\n *\n * Licensed under the MIT license:\n * https://opensource.org/licenses/MIT\n */\n\nbody {\n  max-width: 750px;\n  margin: 0 auto;\n  padding: 1em;\n  font-family: 'Lucida Grande', 'Lucida Sans Unicode', Arial, sans-serif;\n  font-size: 1em;\n  line-height: 1.4em;\n  background: #222;\n  color: #fff;\n  -webkit-text-size-adjust: 100%;\n      -ms-text-size-adjust: 100%;\n}\na {\n  color: orange;\n  text-decoration: none;\n}\nimg {\n  border: 0;\n  vertical-align: middle;\n}\nh1 {\n  line-height: 1em;\n}\ntextarea,\ninput {\n  display: inline-block;\n  width: 100%;\n  -webkit-box-sizing: border-box;\n     -moz-box-sizing: border-box;\n          box-sizing: border-box;\n  padding: 10px;\n  margin: 0 0 10px;\n  font-family: \"Lucida Console\", Monaco, monospace;\n}\n.result {\n  padding: 20px 40px;\n  background: #fff;\n  color: #222;\n}\n.error {\n  color: red;\n}\n\n@media (min-width: 481px) {\n  .navigation {\n    list-style: none;\n    padding: 0;\n  }\n  .navigation li {\n    display: inline-block;\n  }\n  .navigation li:not(:first-child):before {\n    content: '| ';\n  }\n}\n\n/* IE7 fixes */\n*+html textarea,\n*+html input {\n  width: 460px;\n}\n*+html .result {\n  width: 400px;\n}\n"
  },
  {
    "path": "app_backend/static/plugin/JavaScript-Templates-3.8.0/index.html",
    "content": "<!DOCTYPE HTML>\n<!--\n/*\n * JavaScript Templates Demo\n * https://github.com/blueimp/JavaScript-Templates\n *\n * Copyright 2011, Sebastian Tschan\n * https://blueimp.net\n *\n * Licensed under the MIT license:\n * https://opensource.org/licenses/MIT\n */\n-->\n<html lang=\"en\">\n<head>\n<!--[if IE]>\n<meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge,chrome=1\">\n<![endif]-->\n<meta charset=\"utf-8\">\n<title>JavaScript Templates Demo</title>\n<meta name=\"description\" content=\"1KB lightweight, fast &amp; powerful JavaScript templating engine with zero dependencies. Compatible with server-side environments like Node.js, module loaders like RequireJS, Browserify or webpack and all web browsers.\">\n<meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n<link rel=\"stylesheet\" href=\"css/demo.css\">\n</head>\n<body>\n<h1>JavaScript Templates Demo</h1>\n<p><strong>1KB</strong> lightweight, fast &amp; powerful <a href=\"https://developer.mozilla.org/en/JavaScript/\">JavaScript</a> templating engine with zero dependencies.<br>\nCompatible with server-side environments like <a href=\"http://nodejs.org/\">Node.js</a>, module loaders like <a href=\"http://requirejs.org/\">RequireJS</a>, <a href=\"http://browserify.org/\">Browserify</a> or <a href=\"https://webpack.github.io/\">webpack</a> and all web browsers.</p>\n<ul class=\"navigation\">\n    <li><a href=\"https://github.com/blueimp/JavaScript-Templates/tags\">Download</a></li>\n    <li><a href=\"https://github.com/blueimp/JavaScript-Templates\">Source Code</a></li>\n    <li><a href=\"https://github.com/blueimp/JavaScript-Templates/blob/master/README.md\">Documentation</a></li>\n    <li><a href=\"test/\">Test</a></li>\n    <li><a href=\"https://blueimp.net\">&copy; Sebastian Tschan</a></li>\n</ul>\n<form>\n    <h2>Template</h2>\n    <textarea rows=\"12\" id=\"template\"></textarea>\n    <br>\n    <h2>Data (JSON)</h2>\n    <textarea rows=\"14\" id=\"data\"></textarea>\n    <br>\n    <button type=\"submit\" id=\"render\">Render</button>\n    <button type=\"reset\" id=\"reset\">Reset</button>\n    <h2>Result</h2>\n    <div id=\"result\" class=\"result\"></div>\n    <br>\n</form>\n<script type=\"text/x-tmpl\" id=\"tmpl-demo\">\n<h3>{%=o.title%}</h3>\n<p>Released under the\n<a href=\"{%=o.license.url%}\">{%=o.license.name%}</a>.</p>\n<h4>Features</h4>\n<ul>\n{% for (var i=0; i<o.features.length; i++) { %}\n    <li>{%=o.features[i]%}</li>\n{% } %}\n</ul>\n</script>\n<script type=\"text/x-tmpl\" id=\"tmpl-data\">\n{\n    \"title\": \"JavaScript Templates\",\n    \"license\": {\n        \"name\": \"MIT license\",\n        \"url\": \"https://opensource.org/licenses/MIT\"\n    },\n    \"features\": [\n        \"lightweight & fast\",\n        \"powerful\",\n        \"zero dependencies\"\n    ]\n}\n</script>\n<script type=\"text/x-tmpl\" id=\"tmpl-error\">\n<h3 class=\"error\">{%=o.title%}</h3>\n<code>{%=o.error%}</code>\n</script>\n<script src=\"js/tmpl.js\"></script>\n<script src=\"js/demo/demo.js\"></script>\n</body>\n</html>\n"
  },
  {
    "path": "app_backend/static/plugin/JavaScript-Templates-3.8.0/js/compile.js",
    "content": "#!/usr/bin/env node\n/*\n * JavaScript Templates Compiler\n * https://github.com/blueimp/JavaScript-Templates\n *\n * Copyright 2011, Sebastian Tschan\n * https://blueimp.net\n *\n * Licensed under the MIT license:\n * https://opensource.org/licenses/MIT\n */\n\n;(function () {\n  'use strict'\n  var path = require('path')\n  var tmpl = require(path.join(__dirname, 'tmpl.js'))\n  var fs = require('fs')\n  // Retrieve the content of the minimal runtime:\n  var runtime = fs.readFileSync(path.join(__dirname, 'runtime.js'), 'utf8')\n  // A regular expression to parse templates from script tags in a HTML page:\n  var regexp = /<script( id=\"([\\w\\-]+)\")? type=\"text\\/x-tmpl\"( id=\"([\\w\\-]+)\")?>([\\s\\S]+?)<\\/script>/gi\n  // A regular expression to match the helper function names:\n  var helperRegexp = new RegExp(\n    tmpl.helper.match(/\\w+(?=\\s*=\\s*function\\s*\\()/g).join('\\\\s*\\\\(|') + '\\\\s*\\\\('\n  )\n  // A list to store the function bodies:\n  var list = []\n  var code\n  // Extend the Templating engine with a print method for the generated functions:\n  tmpl.print = function (str) {\n    // Only add helper functions if they are used inside of the template:\n    var helper = helperRegexp.test(str) ? tmpl.helper : ''\n    var body = str.replace(tmpl.regexp, tmpl.func)\n    if (helper || (/_e\\s*\\(/.test(body))) {\n      helper = '_e=tmpl.encode' + helper + ','\n    }\n    return 'function(' + tmpl.arg + ',tmpl){' +\n    ('var ' + helper + \"_s='\" + body + \"';return _s;\")\n      .split(\"_s+='';\").join('') + '}'\n  }\n  // Loop through the command line arguments:\n  process.argv.forEach(function (file, index) {\n    var listLength = list.length\n    var stats\n    var content\n    var result\n    var id\n    // Skip the first two arguments, which are \"node\" and the script:\n    if (index > 1) {\n      stats = fs.statSync(file)\n      if (!stats.isFile()) {\n        console.error(file + ' is not a file.')\n        return\n      }\n      content = fs.readFileSync(file, 'utf8')\n      while (true) {\n        // Find templates in script tags:\n        result = regexp.exec(content)\n        if (!result) {\n          break\n        }\n        id = result[2] || result[4]\n        list.push(\"'\" + id + \"':\" + tmpl.print(result[5]))\n      }\n      if (listLength === list.length) {\n        // No template script tags found, use the complete content:\n        id = path.basename(file, path.extname(file))\n        list.push(\"'\" + id + \"':\" + tmpl.print(content))\n      }\n    }\n  })\n  if (!list.length) {\n    console.error('Missing input file.')\n    return\n  }\n  // Combine the generated functions as cache of the minimal runtime:\n  code = runtime.replace('{}', '{' + list.join(',') + '}')\n  // Print the resulting code to the console output:\n  console.log(code)\n}())\n"
  },
  {
    "path": "app_backend/static/plugin/JavaScript-Templates-3.8.0/js/demo/demo.js",
    "content": "/*\n * JavaScript Templates Demo\n * https://github.com/blueimp/JavaScript-Templates\n *\n * Copyright 2013, Sebastian Tschan\n * https://blueimp.net\n *\n * Licensed under the MIT license:\n * https://opensource.org/licenses/MIT\n */\n\n/* global tmpl */\n\n;(function () {\n  'use strict'\n\n  var templateInput = document.getElementById('template')\n  var dataInput = document.getElementById('data')\n  var resultNode = document.getElementById('result')\n  var templateDemoNode = document.getElementById('tmpl-demo')\n  var templateDataNode = document.getElementById('tmpl-data')\n\n  function renderError (title, error) {\n    resultNode.innerHTML = tmpl(\n      'tmpl-error',\n      {title: title, error: error}\n    )\n  }\n\n  function render (event) {\n    event.preventDefault()\n    var data\n    try {\n      data = JSON.parse(dataInput.value)\n    } catch (e) {\n      renderError('JSON parsing failed', e)\n      return\n    }\n    try {\n      resultNode.innerHTML = tmpl(\n        templateInput.value,\n        data\n      )\n    } catch (e) {\n      renderError('Template rendering failed', e)\n    }\n  }\n\n  function empty (node) {\n    while (node.lastChild) {\n      node.removeChild(node.lastChild)\n    }\n  }\n\n  function init (event) {\n    if (event) {\n      event.preventDefault()\n    }\n    templateInput.value = templateDemoNode.innerHTML.trim()\n    dataInput.value = templateDataNode.innerHTML.trim()\n    empty(resultNode)\n  }\n\n  document.getElementById('render').addEventListener('click', render)\n  document.getElementById('reset').addEventListener('click', init)\n\n  init()\n}())\n"
  },
  {
    "path": "app_backend/static/plugin/JavaScript-Templates-3.8.0/js/runtime.js",
    "content": "/*\n * JavaScript Templates Runtime\n * https://github.com/blueimp/JavaScript-Templates\n *\n * Copyright 2011, Sebastian Tschan\n * https://blueimp.net\n *\n * Licensed under the MIT license:\n * https://opensource.org/licenses/MIT\n */\n\n/* global define */\n\n;(function ($) {\n  'use strict'\n  var tmpl = function (id, data) {\n    var f = tmpl.cache[id]\n    return data ? f(data, tmpl) : function (data) {\n      return f(data, tmpl)\n    }\n  }\n  tmpl.cache = {}\n  tmpl.encReg = /[<>&\"'\\x00]/g // eslint-disable-line no-control-regex\n  tmpl.encMap = {\n    '<': '&lt;',\n    '>': '&gt;',\n    '&': '&amp;',\n    '\"': '&quot;',\n    \"'\": '&#39;'\n  }\n  tmpl.encode = function (s) {\n    return (s == null ? '' : '' + s).replace(\n      tmpl.encReg,\n      function (c) {\n        return tmpl.encMap[c] || ''\n      }\n    )\n  }\n  if (typeof define === 'function' && define.amd) {\n    define(function () {\n      return tmpl\n    })\n  } else if (typeof module === 'object' && module.exports) {\n    module.exports = tmpl\n  } else {\n    $.tmpl = tmpl\n  }\n}(this))\n"
  },
  {
    "path": "app_backend/static/plugin/JavaScript-Templates-3.8.0/js/tmpl.js",
    "content": "/*\n * JavaScript Templates\n * https://github.com/blueimp/JavaScript-Templates\n *\n * Copyright 2011, Sebastian Tschan\n * https://blueimp.net\n *\n * Licensed under the MIT license:\n * https://opensource.org/licenses/MIT\n *\n * Inspired by John Resig's JavaScript Micro-Templating:\n * http://ejohn.org/blog/javascript-micro-templating/\n */\n\n/* global define */\n\n;(function ($) {\n  'use strict'\n  var tmpl = function (str, data) {\n    var f = !/[^\\w\\-\\.:]/.test(str)\n      ? tmpl.cache[str] = tmpl.cache[str] || tmpl(tmpl.load(str))\n      : new Function(// eslint-disable-line no-new-func\n        tmpl.arg + ',tmpl',\n        'var _e=tmpl.encode' + tmpl.helper + \",_s='\" +\n          str.replace(tmpl.regexp, tmpl.func) + \"';return _s;\"\n      )\n    return data ? f(data, tmpl) : function (data) {\n      return f(data, tmpl)\n    }\n  }\n  tmpl.cache = {}\n  tmpl.load = function (id) {\n    return document.getElementById(id).innerHTML\n  }\n  tmpl.regexp = /([\\s'\\\\])(?!(?:[^{]|\\{(?!%))*%\\})|(?:\\{%(=|#)([\\s\\S]+?)%\\})|(\\{%)|(%\\})/g\n  tmpl.func = function (s, p1, p2, p3, p4, p5) {\n    if (p1) { // whitespace, quote and backspace in HTML context\n      return {\n        '\\n': '\\\\n',\n        '\\r': '\\\\r',\n        '\\t': '\\\\t',\n        ' ': ' '\n      }[p1] || '\\\\' + p1\n    }\n    if (p2) { // interpolation: {%=prop%}, or unescaped: {%#prop%}\n      if (p2 === '=') {\n        return \"'+_e(\" + p3 + \")+'\"\n      }\n      return \"'+(\" + p3 + \"==null?'':\" + p3 + \")+'\"\n    }\n    if (p4) { // evaluation start tag: {%\n      return \"';\"\n    }\n    if (p5) { // evaluation end tag: %}\n      return \"_s+='\"\n    }\n  }\n  tmpl.encReg = /[<>&\"'\\x00]/g // eslint-disable-line no-control-regex\n  tmpl.encMap = {\n    '<': '&lt;',\n    '>': '&gt;',\n    '&': '&amp;',\n    '\"': '&quot;',\n    \"'\": '&#39;'\n  }\n  tmpl.encode = function (s) {\n    return (s == null ? '' : '' + s).replace(\n      tmpl.encReg,\n      function (c) {\n        return tmpl.encMap[c] || ''\n      }\n    )\n  }\n  tmpl.arg = 'o'\n  tmpl.helper = \",print=function(s,e){_s+=e?(s==null?'':s):_e(s);}\" +\n                  ',include=function(s,d){_s+=tmpl(s,d);}'\n  if (typeof define === 'function' && define.amd) {\n    define(function () {\n      return tmpl\n    })\n  } else if (typeof module === 'object' && module.exports) {\n    module.exports = tmpl\n  } else {\n    $.tmpl = tmpl\n  }\n}(this))\n"
  },
  {
    "path": "app_backend/static/plugin/JavaScript-Templates-3.8.0/package.json",
    "content": "{\n  \"name\": \"blueimp-tmpl\",\n  \"version\": \"3.8.0\",\n  \"title\": \"JavaScript Templates\",\n  \"description\": \"1KB lightweight, fast & powerful JavaScript templating engine with zero dependencies. Compatible with server-side environments like Node.js, module loaders like RequireJS, Browserify or webpack and all web browsers.\",\n  \"keywords\": [\n    \"javascript\",\n    \"templates\",\n    \"templating\"\n  ],\n  \"homepage\": \"https://github.com/blueimp/JavaScript-Templates\",\n  \"author\": {\n    \"name\": \"Sebastian Tschan\",\n    \"url\": \"https://blueimp.net\"\n  },\n  \"repository\": {\n    \"type\": \"git\",\n    \"url\": \"git://github.com/blueimp/JavaScript-Templates.git\"\n  },\n  \"license\": \"MIT\",\n  \"devDependencies\": {\n    \"chai\": \"3.5.0\",\n    \"mocha\": \"3.1.0\",\n    \"standard\": \"8.3.0\",\n    \"uglify-js\": \"2.7.3\"\n  },\n  \"scripts\": {\n    \"lint\": \"standard js/*.js test/*.js\",\n    \"unit\": \"mocha\",\n    \"test\": \"npm run lint && npm run unit\",\n    \"build\": \"cd js && uglifyjs tmpl.js -c -m -o tmpl.min.js --source-map tmpl.min.js.map\",\n    \"preversion\": \"npm test\",\n    \"version\": \"npm run build && git add -A js\",\n    \"postversion\": \"git push --tags origin master master:gh-pages && npm publish\"\n  },\n  \"bin\": {\n    \"tmpl.js\": \"js/compile.js\"\n  },\n  \"main\": \"js/tmpl.js\"\n}\n"
  },
  {
    "path": "app_backend/static/plugin/JavaScript-Templates-3.8.0/test/index.html",
    "content": "<!DOCTYPE HTML>\n<!--\n/*\n * JavaScript Templates Test\n * https://github.com/blueimp/JavaScript-Templates\n *\n * Copyright 2011, Sebastian Tschan\n * https://blueimp.net\n *\n * Licensed under the MIT license:\n * https://opensource.org/licenses/MIT\n */\n-->\n<html lang=\"en\">\n<head>\n<!--[if IE]>\n<meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge,chrome=1\">\n<![endif]-->\n<meta charset=\"utf-8\">\n<title>JavaScript Templates Test</title>\n<meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n<link rel=\"stylesheet\" href=\"vendor/mocha.css\">\n</head>\n<body>\n<div id=\"mocha\"></div>\n<script src=\"vendor/mocha.js\"></script>\n<script src=\"vendor/chai.js\"></script>\n<script>\nmocha.setup('bdd');\n</script>\n<script type=\"text/x-tmpl\" id=\"template\">{%=o.value%}</script>\n<script src=\"../js/tmpl.js\"></script>\n<script src=\"test.js\"></script>\n<script>\nmocha.checkLeaks();\nmocha.run();\n</script>\n</body>\n</html>\n"
  },
  {
    "path": "app_backend/static/plugin/JavaScript-Templates-3.8.0/test/test.js",
    "content": "/*\n * JavaScript Templates Test\n * https://github.com/blueimp/JavaScript-Templates\n *\n * Copyright 2011, Sebastian Tschan\n * https://blueimp.net\n *\n * Licensed under the MIT license:\n * https://opensource.org/licenses/MIT\n */\n\n/* global beforeEach, afterEach, describe, it */\n\n;(function (context, expect, tmpl) {\n  'use strict'\n\n  if (context.require === undefined) {\n    // Override the template loading method:\n    tmpl.load = function (id) {\n      switch (id) {\n        case 'template':\n          return '{%=o.value%}'\n      }\n    }\n  }\n\n  var data\n\n  beforeEach(function () {\n    // Initialize the sample data:\n    data = {\n      value: 'value',\n      nullValue: null,\n      falseValue: false,\n      zeroValue: 0,\n      special: '<>&\"\\'\\x00',\n      list: [1, 2, 3, 4, 5],\n      func: function () {\n        return this.value\n      },\n      deep: {\n        value: 'value'\n      }\n    }\n  })\n\n  afterEach(function () {\n    // Purge the template cache:\n    tmpl.cache = {}\n  })\n\n  describe('Template loading', function () {\n    it('String template', function () {\n      expect(\n        tmpl('{%=o.value%}', data)\n      ).to.equal(\n        'value'\n      )\n    })\n\n    it('Load template by id', function () {\n      expect(\n        tmpl('template', data)\n      ).to.equal(\n        'value'\n      )\n    })\n\n    it('Retun function when called without data parameter', function () {\n      expect(\n        tmpl('{%=o.value%}')(data)\n      ).to.equal(\n        'value'\n      )\n    })\n\n    it('Cache templates loaded by id', function () {\n      tmpl('template')\n      expect(\n        tmpl.cache.template\n      ).to.be.a('function')\n    })\n  })\n\n  describe('Interpolation', function () {\n    it('Escape HTML special characters with {%=o.prop%}', function () {\n      expect(\n        tmpl('{%=o.special%}', data)\n      ).to.equal(\n        '&lt;&gt;&amp;&quot;&#39;'\n      )\n    })\n\n    it('Allow HTML special characters with {%#o.prop%}', function () {\n      expect(\n        tmpl('{%#o.special%}', data)\n      ).to.equal(\n        '<>&\"\\'\\x00'\n      )\n    })\n\n    it('Function call', function () {\n      expect(\n        tmpl('{%=o.func()%}', data)\n      ).to.equal(\n        'value'\n      )\n    })\n\n    it('Dot notation', function () {\n      expect(\n        tmpl('{%=o.deep.value%}', data)\n      ).to.equal(\n        'value'\n      )\n    })\n\n    it('Handle single quotes', function () {\n      expect(\n        tmpl('\\'single quotes\\'{%=\": \\'\"%}', data)\n      ).to.equal(\n        \"'single quotes': &#39;\"\n      )\n    })\n\n    it('Handle double quotes', function () {\n      expect(\n        tmpl('\"double quotes\"{%=\": \\\\\"\"%}', data)\n      ).to.equal(\n        '\"double quotes\": &quot;'\n      )\n    })\n\n    it('Handle backslashes', function () {\n      expect(\n        tmpl('\\\\backslashes\\\\{%=\": \\\\\\\\\"%}', data)\n      ).to.equal(\n        '\\\\backslashes\\\\: \\\\'\n      )\n    })\n\n    it('Interpolate escaped falsy values except undefined or null', function () {\n      expect(\n        tmpl(\n          '{%=o.undefinedValue%}' +\n          '{%=o.nullValue%}' +\n          '{%=o.falseValue%}' +\n          '{%=o.zeroValue%}',\n          data\n        )\n      ).to.equal(\n        'false0'\n      )\n    })\n\n    it('Interpolate unescaped falsy values except undefined or null', function () {\n      expect(\n        tmpl(\n          '{%#o.undefinedValue%}' +\n          '{%#o.nullValue%}' +\n          '{%#o.falseValue%}' +\n          '{%#o.zeroValue%}',\n          data\n        )\n      ).to.equal(\n        'false0'\n      )\n    })\n\n    it('Preserve whitespace', function () {\n      expect(\n        tmpl(\n          '\\n\\r\\t{%=o.value%}  \\n\\r\\t{%=o.value%}  ',\n          data\n        )\n      ).to.equal(\n        '\\n\\r\\tvalue  \\n\\r\\tvalue  '\n      )\n    })\n  })\n\n  describe('Evaluation', function () {\n    it('Escape HTML special characters with print(data)', function () {\n      expect(\n        tmpl('{% print(o.special); %}', data)\n      ).to.equal(\n        '&lt;&gt;&amp;&quot;&#39;'\n      )\n    })\n\n    it('Allow HTML special characters with print(data, true)', function () {\n      expect(\n        tmpl('{% print(o.special, true); %}', data)\n      ).to.equal(\n        '<>&\"\\'\\x00'\n      )\n    })\n\n    it('Print out escaped falsy values except undefined or null', function () {\n      expect(\n        tmpl(\n          '{% print(o.undefinedValue); %}' +\n          '{% print(o.nullValue); %}' +\n          '{% print(o.falseValue); %}' +\n          '{% print(o.zeroValue); %}',\n          data\n        )\n      ).to.equal(\n        'false0'\n      )\n    })\n\n    it('Print out unescaped falsy values except undefined or null', function () {\n      expect(\n        tmpl(\n          '{% print(o.undefinedValue, true); %}' +\n          '{% print(o.nullValue, true); %}' +\n          '{% print(o.falseValue, true); %}' +\n          '{% print(o.zeroValue, true); %}',\n          data\n        )\n      ).to.equal(\n        'false0'\n      )\n    })\n\n    it('Include template', function () {\n      expect(\n        tmpl('{% include(\"template\", {value: \"value\"}); %}', data)\n      ).to.equal(\n        'value'\n      )\n    })\n\n    it('If condition', function () {\n      expect(\n        tmpl('{% if (o.value) { %}true{% } else { %}false{% } %}', data)\n      ).to.equal(\n        'true'\n      )\n    })\n\n    it('Else condition', function () {\n      expect(\n        tmpl(\n          '{% if (o.undefinedValue) { %}false{% } else { %}true{% } %}',\n          data\n        )\n      ).to.equal(\n        'true'\n      )\n    })\n\n    it('For loop', function () {\n      expect(\n        tmpl(\n          '{% for (var i=0; i<o.list.length; i++) { %}' +\n          '{%=o.list[i]%}{% } %}',\n          data\n        )\n      ).to.equal(\n        '12345'\n      )\n    })\n\n    it('For loop print call', function () {\n      expect(\n        tmpl(\n          '{% for (var i=0; i<o.list.length; i++) {' +\n          'print(o.list[i]);} %}',\n          data\n        )\n      ).to.equal(\n        '12345'\n      )\n    })\n\n    it('For loop include template', function () {\n      expect(\n        tmpl(\n          '{% for (var i=0; i<o.list.length; i++) {' +\n          'include(\"template\", {value: o.list[i]});} %}',\n          data\n        ).replace(/[\\r\\n]/g, '')\n      ).to.equal(\n        '12345'\n      )\n    })\n\n    it('Modulo operator', function () {\n      expect(\n        tmpl(\n          '{% if (o.list.length % 5 === 0) { %}5 list items{% } %}',\n          data\n        ).replace(/[\\r\\n]/g, '')\n      ).to.equal(\n        '5 list items'\n      )\n    })\n  })\n}(\n  this,\n  (this.chai || require('chai')).expect,\n  this.tmpl || require('../js/tmpl')\n))\n"
  },
  {
    "path": "app_backend/static/plugin/JavaScript-Templates-3.8.0/test/vendor/chai.js",
    "content": "(function(f){if(typeof exports===\"object\"&&typeof module!==\"undefined\"){module.exports=f()}else if(typeof define===\"function\"&&define.amd){define([],f)}else{var g;if(typeof window!==\"undefined\"){g=window}else if(typeof global!==\"undefined\"){g=global}else if(typeof self!==\"undefined\"){g=self}else{g=this}g.chai = f()}})(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require==\"function\"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error(\"Cannot find module '\"+o+\"'\");throw f.code=\"MODULE_NOT_FOUND\",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require==\"function\"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){\nmodule.exports = require('./lib/chai');\n\n},{\"./lib/chai\":2}],2:[function(require,module,exports){\n/*!\n * chai\n * Copyright(c) 2011-2014 Jake Luer <jake@alogicalparadox.com>\n * MIT Licensed\n */\n\nvar used = []\n  , exports = module.exports = {};\n\n/*!\n * Chai version\n */\n\nexports.version = '3.5.0';\n\n/*!\n * Assertion Error\n */\n\nexports.AssertionError = require('assertion-error');\n\n/*!\n * Utils for plugins (not exported)\n */\n\nvar util = require('./chai/utils');\n\n/**\n * # .use(function)\n *\n * Provides a way to extend the internals of Chai\n *\n * @param {Function}\n * @returns {this} for chaining\n * @api public\n */\n\nexports.use = function (fn) {\n  if (!~used.indexOf(fn)) {\n    fn(this, util);\n    used.push(fn);\n  }\n\n  return this;\n};\n\n/*!\n * Utility Functions\n */\n\nexports.util = util;\n\n/*!\n * Configuration\n */\n\nvar config = require('./chai/config');\nexports.config = config;\n\n/*!\n * Primary `Assertion` prototype\n */\n\nvar assertion = require('./chai/assertion');\nexports.use(assertion);\n\n/*!\n * Core Assertions\n */\n\nvar core = require('./chai/core/assertions');\nexports.use(core);\n\n/*!\n * Expect interface\n */\n\nvar expect = require('./chai/interface/expect');\nexports.use(expect);\n\n/*!\n * Should interface\n */\n\nvar should = require('./chai/interface/should');\nexports.use(should);\n\n/*!\n * Assert interface\n */\n\nvar assert = require('./chai/interface/assert');\nexports.use(assert);\n\n},{\"./chai/assertion\":3,\"./chai/config\":4,\"./chai/core/assertions\":5,\"./chai/interface/assert\":6,\"./chai/interface/expect\":7,\"./chai/interface/should\":8,\"./chai/utils\":22,\"assertion-error\":30}],3:[function(require,module,exports){\n/*!\n * chai\n * http://chaijs.com\n * Copyright(c) 2011-2014 Jake Luer <jake@alogicalparadox.com>\n * MIT Licensed\n */\n\nvar config = require('./config');\n\nmodule.exports = function (_chai, util) {\n  /*!\n   * Module dependencies.\n   */\n\n  var AssertionError = _chai.AssertionError\n    , flag = util.flag;\n\n  /*!\n   * Module export.\n   */\n\n  _chai.Assertion = Assertion;\n\n  /*!\n   * Assertion Constructor\n   *\n   * Creates object for chaining.\n   *\n   * @api private\n   */\n\n  function Assertion (obj, msg, stack) {\n    flag(this, 'ssfi', stack || arguments.callee);\n    flag(this, 'object', obj);\n    flag(this, 'message', msg);\n  }\n\n  Object.defineProperty(Assertion, 'includeStack', {\n    get: function() {\n      console.warn('Assertion.includeStack is deprecated, use chai.config.includeStack instead.');\n      return config.includeStack;\n    },\n    set: function(value) {\n      console.warn('Assertion.includeStack is deprecated, use chai.config.includeStack instead.');\n      config.includeStack = value;\n    }\n  });\n\n  Object.defineProperty(Assertion, 'showDiff', {\n    get: function() {\n      console.warn('Assertion.showDiff is deprecated, use chai.config.showDiff instead.');\n      return config.showDiff;\n    },\n    set: function(value) {\n      console.warn('Assertion.showDiff is deprecated, use chai.config.showDiff instead.');\n      config.showDiff = value;\n    }\n  });\n\n  Assertion.addProperty = function (name, fn) {\n    util.addProperty(this.prototype, name, fn);\n  };\n\n  Assertion.addMethod = function (name, fn) {\n    util.addMethod(this.prototype, name, fn);\n  };\n\n  Assertion.addChainableMethod = function (name, fn, chainingBehavior) {\n    util.addChainableMethod(this.prototype, name, fn, chainingBehavior);\n  };\n\n  Assertion.overwriteProperty = function (name, fn) {\n    util.overwriteProperty(this.prototype, name, fn);\n  };\n\n  Assertion.overwriteMethod = function (name, fn) {\n    util.overwriteMethod(this.prototype, name, fn);\n  };\n\n  Assertion.overwriteChainableMethod = function (name, fn, chainingBehavior) {\n    util.overwriteChainableMethod(this.prototype, name, fn, chainingBehavior);\n  };\n\n  /**\n   * ### .assert(expression, message, negateMessage, expected, actual, showDiff)\n   *\n   * Executes an expression and check expectations. Throws AssertionError for reporting if test doesn't pass.\n   *\n   * @name assert\n   * @param {Philosophical} expression to be tested\n   * @param {String|Function} message or function that returns message to display if expression fails\n   * @param {String|Function} negatedMessage or function that returns negatedMessage to display if negated expression fails\n   * @param {Mixed} expected value (remember to check for negation)\n   * @param {Mixed} actual (optional) will default to `this.obj`\n   * @param {Boolean} showDiff (optional) when set to `true`, assert will display a diff in addition to the message if expression fails\n   * @api private\n   */\n\n  Assertion.prototype.assert = function (expr, msg, negateMsg, expected, _actual, showDiff) {\n    var ok = util.test(this, arguments);\n    if (true !== showDiff) showDiff = false;\n    if (true !== config.showDiff) showDiff = false;\n\n    if (!ok) {\n      var msg = util.getMessage(this, arguments)\n        , actual = util.getActual(this, arguments);\n      throw new AssertionError(msg, {\n          actual: actual\n        , expected: expected\n        , showDiff: showDiff\n      }, (config.includeStack) ? this.assert : flag(this, 'ssfi'));\n    }\n  };\n\n  /*!\n   * ### ._obj\n   *\n   * Quick reference to stored `actual` value for plugin developers.\n   *\n   * @api private\n   */\n\n  Object.defineProperty(Assertion.prototype, '_obj',\n    { get: function () {\n        return flag(this, 'object');\n      }\n    , set: function (val) {\n        flag(this, 'object', val);\n      }\n  });\n};\n\n},{\"./config\":4}],4:[function(require,module,exports){\nmodule.exports = {\n\n  /**\n   * ### config.includeStack\n   *\n   * User configurable property, influences whether stack trace\n   * is included in Assertion error message. Default of false\n   * suppresses stack trace in the error message.\n   *\n   *     chai.config.includeStack = true;  // enable stack on error\n   *\n   * @param {Boolean}\n   * @api public\n   */\n\n   includeStack: false,\n\n  /**\n   * ### config.showDiff\n   *\n   * User configurable property, influences whether or not\n   * the `showDiff` flag should be included in the thrown\n   * AssertionErrors. `false` will always be `false`; `true`\n   * will be true when the assertion has requested a diff\n   * be shown.\n   *\n   * @param {Boolean}\n   * @api public\n   */\n\n  showDiff: true,\n\n  /**\n   * ### config.truncateThreshold\n   *\n   * User configurable property, sets length threshold for actual and\n   * expected values in assertion errors. If this threshold is exceeded, for\n   * example for large data structures, the value is replaced with something\n   * like `[ Array(3) ]` or `{ Object (prop1, prop2) }`.\n   *\n   * Set it to zero if you want to disable truncating altogether.\n   *\n   * This is especially userful when doing assertions on arrays: having this\n   * set to a reasonable large value makes the failure messages readily\n   * inspectable.\n   *\n   *     chai.config.truncateThreshold = 0;  // disable truncating\n   *\n   * @param {Number}\n   * @api public\n   */\n\n  truncateThreshold: 40\n\n};\n\n},{}],5:[function(require,module,exports){\n/*!\n * chai\n * http://chaijs.com\n * Copyright(c) 2011-2014 Jake Luer <jake@alogicalparadox.com>\n * MIT Licensed\n */\n\nmodule.exports = function (chai, _) {\n  var Assertion = chai.Assertion\n    , toString = Object.prototype.toString\n    , flag = _.flag;\n\n  /**\n   * ### Language Chains\n   *\n   * The following are provided as chainable getters to\n   * improve the readability of your assertions. They\n   * do not provide testing capabilities unless they\n   * have been overwritten by a plugin.\n   *\n   * **Chains**\n   *\n   * - to\n   * - be\n   * - been\n   * - is\n   * - that\n   * - which\n   * - and\n   * - has\n   * - have\n   * - with\n   * - at\n   * - of\n   * - same\n   *\n   * @name language chains\n   * @namespace BDD\n   * @api public\n   */\n\n  [ 'to', 'be', 'been'\n  , 'is', 'and', 'has', 'have'\n  , 'with', 'that', 'which', 'at'\n  , 'of', 'same' ].forEach(function (chain) {\n    Assertion.addProperty(chain, function () {\n      return this;\n    });\n  });\n\n  /**\n   * ### .not\n   *\n   * Negates any of assertions following in the chain.\n   *\n   *     expect(foo).to.not.equal('bar');\n   *     expect(goodFn).to.not.throw(Error);\n   *     expect({ foo: 'baz' }).to.have.property('foo')\n   *       .and.not.equal('bar');\n   *\n   * @name not\n   * @namespace BDD\n   * @api public\n   */\n\n  Assertion.addProperty('not', function () {\n    flag(this, 'negate', true);\n  });\n\n  /**\n   * ### .deep\n   *\n   * Sets the `deep` flag, later used by the `equal` and\n   * `property` assertions.\n   *\n   *     expect(foo).to.deep.equal({ bar: 'baz' });\n   *     expect({ foo: { bar: { baz: 'quux' } } })\n   *       .to.have.deep.property('foo.bar.baz', 'quux');\n   *\n   * `.deep.property` special characters can be escaped\n   * by adding two slashes before the `.` or `[]`.\n   *\n   *     var deepCss = { '.link': { '[target]': 42 }};\n   *     expect(deepCss).to.have.deep.property('\\\\.link.\\\\[target\\\\]', 42);\n   *\n   * @name deep\n   * @namespace BDD\n   * @api public\n   */\n\n  Assertion.addProperty('deep', function () {\n    flag(this, 'deep', true);\n  });\n\n  /**\n   * ### .any\n   *\n   * Sets the `any` flag, (opposite of the `all` flag)\n   * later used in the `keys` assertion.\n   *\n   *     expect(foo).to.have.any.keys('bar', 'baz');\n   *\n   * @name any\n   * @namespace BDD\n   * @api public\n   */\n\n  Assertion.addProperty('any', function () {\n    flag(this, 'any', true);\n    flag(this, 'all', false)\n  });\n\n\n  /**\n   * ### .all\n   *\n   * Sets the `all` flag (opposite of the `any` flag)\n   * later used by the `keys` assertion.\n   *\n   *     expect(foo).to.have.all.keys('bar', 'baz');\n   *\n   * @name all\n   * @namespace BDD\n   * @api public\n   */\n\n  Assertion.addProperty('all', function () {\n    flag(this, 'all', true);\n    flag(this, 'any', false);\n  });\n\n  /**\n   * ### .a(type)\n   *\n   * The `a` and `an` assertions are aliases that can be\n   * used either as language chains or to assert a value's\n   * type.\n   *\n   *     // typeof\n   *     expect('test').to.be.a('string');\n   *     expect({ foo: 'bar' }).to.be.an('object');\n   *     expect(null).to.be.a('null');\n   *     expect(undefined).to.be.an('undefined');\n   *     expect(new Error).to.be.an('error');\n   *     expect(new Promise).to.be.a('promise');\n   *     expect(new Float32Array()).to.be.a('float32array');\n   *     expect(Symbol()).to.be.a('symbol');\n   *\n   *     // es6 overrides\n   *     expect({[Symbol.toStringTag]:()=>'foo'}).to.be.a('foo');\n   *\n   *     // language chain\n   *     expect(foo).to.be.an.instanceof(Foo);\n   *\n   * @name a\n   * @alias an\n   * @param {String} type\n   * @param {String} message _optional_\n   * @namespace BDD\n   * @api public\n   */\n\n  function an (type, msg) {\n    if (msg) flag(this, 'message', msg);\n    type = type.toLowerCase();\n    var obj = flag(this, 'object')\n      , article = ~[ 'a', 'e', 'i', 'o', 'u' ].indexOf(type.charAt(0)) ? 'an ' : 'a ';\n\n    this.assert(\n        type === _.type(obj)\n      , 'expected #{this} to be ' + article + type\n      , 'expected #{this} not to be ' + article + type\n    );\n  }\n\n  Assertion.addChainableMethod('an', an);\n  Assertion.addChainableMethod('a', an);\n\n  /**\n   * ### .include(value)\n   *\n   * The `include` and `contain` assertions can be used as either property\n   * based language chains or as methods to assert the inclusion of an object\n   * in an array or a substring in a string. When used as language chains,\n   * they toggle the `contains` flag for the `keys` assertion.\n   *\n   *     expect([1,2,3]).to.include(2);\n   *     expect('foobar').to.contain('foo');\n   *     expect({ foo: 'bar', hello: 'universe' }).to.include.keys('foo');\n   *\n   * @name include\n   * @alias contain\n   * @alias includes\n   * @alias contains\n   * @param {Object|String|Number} obj\n   * @param {String} message _optional_\n   * @namespace BDD\n   * @api public\n   */\n\n  function includeChainingBehavior () {\n    flag(this, 'contains', true);\n  }\n\n  function include (val, msg) {\n    _.expectTypes(this, ['array', 'object', 'string']);\n\n    if (msg) flag(this, 'message', msg);\n    var obj = flag(this, 'object');\n    var expected = false;\n\n    if (_.type(obj) === 'array' && _.type(val) === 'object') {\n      for (var i in obj) {\n        if (_.eql(obj[i], val)) {\n          expected = true;\n          break;\n        }\n      }\n    } else if (_.type(val) === 'object') {\n      if (!flag(this, 'negate')) {\n        for (var k in val) new Assertion(obj).property(k, val[k]);\n        return;\n      }\n      var subset = {};\n      for (var k in val) subset[k] = obj[k];\n      expected = _.eql(subset, val);\n    } else {\n      expected = (obj != undefined) && ~obj.indexOf(val);\n    }\n    this.assert(\n        expected\n      , 'expected #{this} to include ' + _.inspect(val)\n      , 'expected #{this} to not include ' + _.inspect(val));\n  }\n\n  Assertion.addChainableMethod('include', include, includeChainingBehavior);\n  Assertion.addChainableMethod('contain', include, includeChainingBehavior);\n  Assertion.addChainableMethod('contains', include, includeChainingBehavior);\n  Assertion.addChainableMethod('includes', include, includeChainingBehavior);\n\n  /**\n   * ### .ok\n   *\n   * Asserts that the target is truthy.\n   *\n   *     expect('everything').to.be.ok;\n   *     expect(1).to.be.ok;\n   *     expect(false).to.not.be.ok;\n   *     expect(undefined).to.not.be.ok;\n   *     expect(null).to.not.be.ok;\n   *\n   * @name ok\n   * @namespace BDD\n   * @api public\n   */\n\n  Assertion.addProperty('ok', function () {\n    this.assert(\n        flag(this, 'object')\n      , 'expected #{this} to be truthy'\n      , 'expected #{this} to be falsy');\n  });\n\n  /**\n   * ### .true\n   *\n   * Asserts that the target is `true`.\n   *\n   *     expect(true).to.be.true;\n   *     expect(1).to.not.be.true;\n   *\n   * @name true\n   * @namespace BDD\n   * @api public\n   */\n\n  Assertion.addProperty('true', function () {\n    this.assert(\n        true === flag(this, 'object')\n      , 'expected #{this} to be true'\n      , 'expected #{this} to be false'\n      , this.negate ? false : true\n    );\n  });\n\n  /**\n   * ### .false\n   *\n   * Asserts that the target is `false`.\n   *\n   *     expect(false).to.be.false;\n   *     expect(0).to.not.be.false;\n   *\n   * @name false\n   * @namespace BDD\n   * @api public\n   */\n\n  Assertion.addProperty('false', function () {\n    this.assert(\n        false === flag(this, 'object')\n      , 'expected #{this} to be false'\n      , 'expected #{this} to be true'\n      , this.negate ? true : false\n    );\n  });\n\n  /**\n   * ### .null\n   *\n   * Asserts that the target is `null`.\n   *\n   *     expect(null).to.be.null;\n   *     expect(undefined).to.not.be.null;\n   *\n   * @name null\n   * @namespace BDD\n   * @api public\n   */\n\n  Assertion.addProperty('null', function () {\n    this.assert(\n        null === flag(this, 'object')\n      , 'expected #{this} to be null'\n      , 'expected #{this} not to be null'\n    );\n  });\n\n  /**\n   * ### .undefined\n   *\n   * Asserts that the target is `undefined`.\n   *\n   *     expect(undefined).to.be.undefined;\n   *     expect(null).to.not.be.undefined;\n   *\n   * @name undefined\n   * @namespace BDD\n   * @api public\n   */\n\n  Assertion.addProperty('undefined', function () {\n    this.assert(\n        undefined === flag(this, 'object')\n      , 'expected #{this} to be undefined'\n      , 'expected #{this} not to be undefined'\n    );\n  });\n\n  /**\n   * ### .NaN\n   * Asserts that the target is `NaN`.\n   *\n   *     expect('foo').to.be.NaN;\n   *     expect(4).not.to.be.NaN;\n   *\n   * @name NaN\n   * @namespace BDD\n   * @api public\n   */\n\n  Assertion.addProperty('NaN', function () {\n    this.assert(\n        isNaN(flag(this, 'object'))\n        , 'expected #{this} to be NaN'\n        , 'expected #{this} not to be NaN'\n    );\n  });\n\n  /**\n   * ### .exist\n   *\n   * Asserts that the target is neither `null` nor `undefined`.\n   *\n   *     var foo = 'hi'\n   *       , bar = null\n   *       , baz;\n   *\n   *     expect(foo).to.exist;\n   *     expect(bar).to.not.exist;\n   *     expect(baz).to.not.exist;\n   *\n   * @name exist\n   * @namespace BDD\n   * @api public\n   */\n\n  Assertion.addProperty('exist', function () {\n    this.assert(\n        null != flag(this, 'object')\n      , 'expected #{this} to exist'\n      , 'expected #{this} to not exist'\n    );\n  });\n\n\n  /**\n   * ### .empty\n   *\n   * Asserts that the target's length is `0`. For arrays and strings, it checks\n   * the `length` property. For objects, it gets the count of\n   * enumerable keys.\n   *\n   *     expect([]).to.be.empty;\n   *     expect('').to.be.empty;\n   *     expect({}).to.be.empty;\n   *\n   * @name empty\n   * @namespace BDD\n   * @api public\n   */\n\n  Assertion.addProperty('empty', function () {\n    var obj = flag(this, 'object')\n      , expected = obj;\n\n    if (Array.isArray(obj) || 'string' === typeof object) {\n      expected = obj.length;\n    } else if (typeof obj === 'object') {\n      expected = Object.keys(obj).length;\n    }\n\n    this.assert(\n        !expected\n      , 'expected #{this} to be empty'\n      , 'expected #{this} not to be empty'\n    );\n  });\n\n  /**\n   * ### .arguments\n   *\n   * Asserts that the target is an arguments object.\n   *\n   *     function test () {\n   *       expect(arguments).to.be.arguments;\n   *     }\n   *\n   * @name arguments\n   * @alias Arguments\n   * @namespace BDD\n   * @api public\n   */\n\n  function checkArguments () {\n    var obj = flag(this, 'object')\n      , type = Object.prototype.toString.call(obj);\n    this.assert(\n        '[object Arguments]' === type\n      , 'expected #{this} to be arguments but got ' + type\n      , 'expected #{this} to not be arguments'\n    );\n  }\n\n  Assertion.addProperty('arguments', checkArguments);\n  Assertion.addProperty('Arguments', checkArguments);\n\n  /**\n   * ### .equal(value)\n   *\n   * Asserts that the target is strictly equal (`===`) to `value`.\n   * Alternately, if the `deep` flag is set, asserts that\n   * the target is deeply equal to `value`.\n   *\n   *     expect('hello').to.equal('hello');\n   *     expect(42).to.equal(42);\n   *     expect(1).to.not.equal(true);\n   *     expect({ foo: 'bar' }).to.not.equal({ foo: 'bar' });\n   *     expect({ foo: 'bar' }).to.deep.equal({ foo: 'bar' });\n   *\n   * @name equal\n   * @alias equals\n   * @alias eq\n   * @alias deep.equal\n   * @param {Mixed} value\n   * @param {String} message _optional_\n   * @namespace BDD\n   * @api public\n   */\n\n  function assertEqual (val, msg) {\n    if (msg) flag(this, 'message', msg);\n    var obj = flag(this, 'object');\n    if (flag(this, 'deep')) {\n      return this.eql(val);\n    } else {\n      this.assert(\n          val === obj\n        , 'expected #{this} to equal #{exp}'\n        , 'expected #{this} to not equal #{exp}'\n        , val\n        , this._obj\n        , true\n      );\n    }\n  }\n\n  Assertion.addMethod('equal', assertEqual);\n  Assertion.addMethod('equals', assertEqual);\n  Assertion.addMethod('eq', assertEqual);\n\n  /**\n   * ### .eql(value)\n   *\n   * Asserts that the target is deeply equal to `value`.\n   *\n   *     expect({ foo: 'bar' }).to.eql({ foo: 'bar' });\n   *     expect([ 1, 2, 3 ]).to.eql([ 1, 2, 3 ]);\n   *\n   * @name eql\n   * @alias eqls\n   * @param {Mixed} value\n   * @param {String} message _optional_\n   * @namespace BDD\n   * @api public\n   */\n\n  function assertEql(obj, msg) {\n    if (msg) flag(this, 'message', msg);\n    this.assert(\n        _.eql(obj, flag(this, 'object'))\n      , 'expected #{this} to deeply equal #{exp}'\n      , 'expected #{this} to not deeply equal #{exp}'\n      , obj\n      , this._obj\n      , true\n    );\n  }\n\n  Assertion.addMethod('eql', assertEql);\n  Assertion.addMethod('eqls', assertEql);\n\n  /**\n   * ### .above(value)\n   *\n   * Asserts that the target is greater than `value`.\n   *\n   *     expect(10).to.be.above(5);\n   *\n   * Can also be used in conjunction with `length` to\n   * assert a minimum length. The benefit being a\n   * more informative error message than if the length\n   * was supplied directly.\n   *\n   *     expect('foo').to.have.length.above(2);\n   *     expect([ 1, 2, 3 ]).to.have.length.above(2);\n   *\n   * @name above\n   * @alias gt\n   * @alias greaterThan\n   * @param {Number} value\n   * @param {String} message _optional_\n   * @namespace BDD\n   * @api public\n   */\n\n  function assertAbove (n, msg) {\n    if (msg) flag(this, 'message', msg);\n    var obj = flag(this, 'object');\n    if (flag(this, 'doLength')) {\n      new Assertion(obj, msg).to.have.property('length');\n      var len = obj.length;\n      this.assert(\n          len > n\n        , 'expected #{this} to have a length above #{exp} but got #{act}'\n        , 'expected #{this} to not have a length above #{exp}'\n        , n\n        , len\n      );\n    } else {\n      this.assert(\n          obj > n\n        , 'expected #{this} to be above ' + n\n        , 'expected #{this} to be at most ' + n\n      );\n    }\n  }\n\n  Assertion.addMethod('above', assertAbove);\n  Assertion.addMethod('gt', assertAbove);\n  Assertion.addMethod('greaterThan', assertAbove);\n\n  /**\n   * ### .least(value)\n   *\n   * Asserts that the target is greater than or equal to `value`.\n   *\n   *     expect(10).to.be.at.least(10);\n   *\n   * Can also be used in conjunction with `length` to\n   * assert a minimum length. The benefit being a\n   * more informative error message than if the length\n   * was supplied directly.\n   *\n   *     expect('foo').to.have.length.of.at.least(2);\n   *     expect([ 1, 2, 3 ]).to.have.length.of.at.least(3);\n   *\n   * @name least\n   * @alias gte\n   * @param {Number} value\n   * @param {String} message _optional_\n   * @namespace BDD\n   * @api public\n   */\n\n  function assertLeast (n, msg) {\n    if (msg) flag(this, 'message', msg);\n    var obj = flag(this, 'object');\n    if (flag(this, 'doLength')) {\n      new Assertion(obj, msg).to.have.property('length');\n      var len = obj.length;\n      this.assert(\n          len >= n\n        , 'expected #{this} to have a length at least #{exp} but got #{act}'\n        , 'expected #{this} to have a length below #{exp}'\n        , n\n        , len\n      );\n    } else {\n      this.assert(\n          obj >= n\n        , 'expected #{this} to be at least ' + n\n        , 'expected #{this} to be below ' + n\n      );\n    }\n  }\n\n  Assertion.addMethod('least', assertLeast);\n  Assertion.addMethod('gte', assertLeast);\n\n  /**\n   * ### .below(value)\n   *\n   * Asserts that the target is less than `value`.\n   *\n   *     expect(5).to.be.below(10);\n   *\n   * Can also be used in conjunction with `length` to\n   * assert a maximum length. The benefit being a\n   * more informative error message than if the length\n   * was supplied directly.\n   *\n   *     expect('foo').to.have.length.below(4);\n   *     expect([ 1, 2, 3 ]).to.have.length.below(4);\n   *\n   * @name below\n   * @alias lt\n   * @alias lessThan\n   * @param {Number} value\n   * @param {String} message _optional_\n   * @namespace BDD\n   * @api public\n   */\n\n  function assertBelow (n, msg) {\n    if (msg) flag(this, 'message', msg);\n    var obj = flag(this, 'object');\n    if (flag(this, 'doLength')) {\n      new Assertion(obj, msg).to.have.property('length');\n      var len = obj.length;\n      this.assert(\n          len < n\n        , 'expected #{this} to have a length below #{exp} but got #{act}'\n        , 'expected #{this} to not have a length below #{exp}'\n        , n\n        , len\n      );\n    } else {\n      this.assert(\n          obj < n\n        , 'expected #{this} to be below ' + n\n        , 'expected #{this} to be at least ' + n\n      );\n    }\n  }\n\n  Assertion.addMethod('below', assertBelow);\n  Assertion.addMethod('lt', assertBelow);\n  Assertion.addMethod('lessThan', assertBelow);\n\n  /**\n   * ### .most(value)\n   *\n   * Asserts that the target is less than or equal to `value`.\n   *\n   *     expect(5).to.be.at.most(5);\n   *\n   * Can also be used in conjunction with `length` to\n   * assert a maximum length. The benefit being a\n   * more informative error message than if the length\n   * was supplied directly.\n   *\n   *     expect('foo').to.have.length.of.at.most(4);\n   *     expect([ 1, 2, 3 ]).to.have.length.of.at.most(3);\n   *\n   * @name most\n   * @alias lte\n   * @param {Number} value\n   * @param {String} message _optional_\n   * @namespace BDD\n   * @api public\n   */\n\n  function assertMost (n, msg) {\n    if (msg) flag(this, 'message', msg);\n    var obj = flag(this, 'object');\n    if (flag(this, 'doLength')) {\n      new Assertion(obj, msg).to.have.property('length');\n      var len = obj.length;\n      this.assert(\n          len <= n\n        , 'expected #{this} to have a length at most #{exp} but got #{act}'\n        , 'expected #{this} to have a length above #{exp}'\n        , n\n        , len\n      );\n    } else {\n      this.assert(\n          obj <= n\n        , 'expected #{this} to be at most ' + n\n        , 'expected #{this} to be above ' + n\n      );\n    }\n  }\n\n  Assertion.addMethod('most', assertMost);\n  Assertion.addMethod('lte', assertMost);\n\n  /**\n   * ### .within(start, finish)\n   *\n   * Asserts that the target is within a range.\n   *\n   *     expect(7).to.be.within(5,10);\n   *\n   * Can also be used in conjunction with `length` to\n   * assert a length range. The benefit being a\n   * more informative error message than if the length\n   * was supplied directly.\n   *\n   *     expect('foo').to.have.length.within(2,4);\n   *     expect([ 1, 2, 3 ]).to.have.length.within(2,4);\n   *\n   * @name within\n   * @param {Number} start lowerbound inclusive\n   * @param {Number} finish upperbound inclusive\n   * @param {String} message _optional_\n   * @namespace BDD\n   * @api public\n   */\n\n  Assertion.addMethod('within', function (start, finish, msg) {\n    if (msg) flag(this, 'message', msg);\n    var obj = flag(this, 'object')\n      , range = start + '..' + finish;\n    if (flag(this, 'doLength')) {\n      new Assertion(obj, msg).to.have.property('length');\n      var len = obj.length;\n      this.assert(\n          len >= start && len <= finish\n        , 'expected #{this} to have a length within ' + range\n        , 'expected #{this} to not have a length within ' + range\n      );\n    } else {\n      this.assert(\n          obj >= start && obj <= finish\n        , 'expected #{this} to be within ' + range\n        , 'expected #{this} to not be within ' + range\n      );\n    }\n  });\n\n  /**\n   * ### .instanceof(constructor)\n   *\n   * Asserts that the target is an instance of `constructor`.\n   *\n   *     var Tea = function (name) { this.name = name; }\n   *       , Chai = new Tea('chai');\n   *\n   *     expect(Chai).to.be.an.instanceof(Tea);\n   *     expect([ 1, 2, 3 ]).to.be.instanceof(Array);\n   *\n   * @name instanceof\n   * @param {Constructor} constructor\n   * @param {String} message _optional_\n   * @alias instanceOf\n   * @namespace BDD\n   * @api public\n   */\n\n  function assertInstanceOf (constructor, msg) {\n    if (msg) flag(this, 'message', msg);\n    var name = _.getName(constructor);\n    this.assert(\n        flag(this, 'object') instanceof constructor\n      , 'expected #{this} to be an instance of ' + name\n      , 'expected #{this} to not be an instance of ' + name\n    );\n  };\n\n  Assertion.addMethod('instanceof', assertInstanceOf);\n  Assertion.addMethod('instanceOf', assertInstanceOf);\n\n  /**\n   * ### .property(name, [value])\n   *\n   * Asserts that the target has a property `name`, optionally asserting that\n   * the value of that property is strictly equal to  `value`.\n   * If the `deep` flag is set, you can use dot- and bracket-notation for deep\n   * references into objects and arrays.\n   *\n   *     // simple referencing\n   *     var obj = { foo: 'bar' };\n   *     expect(obj).to.have.property('foo');\n   *     expect(obj).to.have.property('foo', 'bar');\n   *\n   *     // deep referencing\n   *     var deepObj = {\n   *         green: { tea: 'matcha' }\n   *       , teas: [ 'chai', 'matcha', { tea: 'konacha' } ]\n   *     };\n   *\n   *     expect(deepObj).to.have.deep.property('green.tea', 'matcha');\n   *     expect(deepObj).to.have.deep.property('teas[1]', 'matcha');\n   *     expect(deepObj).to.have.deep.property('teas[2].tea', 'konacha');\n   *\n   * You can also use an array as the starting point of a `deep.property`\n   * assertion, or traverse nested arrays.\n   *\n   *     var arr = [\n   *         [ 'chai', 'matcha', 'konacha' ]\n   *       , [ { tea: 'chai' }\n   *         , { tea: 'matcha' }\n   *         , { tea: 'konacha' } ]\n   *     ];\n   *\n   *     expect(arr).to.have.deep.property('[0][1]', 'matcha');\n   *     expect(arr).to.have.deep.property('[1][2].tea', 'konacha');\n   *\n   * Furthermore, `property` changes the subject of the assertion\n   * to be the value of that property from the original object. This\n   * permits for further chainable assertions on that property.\n   *\n   *     expect(obj).to.have.property('foo')\n   *       .that.is.a('string');\n   *     expect(deepObj).to.have.property('green')\n   *       .that.is.an('object')\n   *       .that.deep.equals({ tea: 'matcha' });\n   *     expect(deepObj).to.have.property('teas')\n   *       .that.is.an('array')\n   *       .with.deep.property('[2]')\n   *         .that.deep.equals({ tea: 'konacha' });\n   *\n   * Note that dots and bracket in `name` must be backslash-escaped when\n   * the `deep` flag is set, while they must NOT be escaped when the `deep`\n   * flag is not set.\n   *\n   *     // simple referencing\n   *     var css = { '.link[target]': 42 };\n   *     expect(css).to.have.property('.link[target]', 42);\n   *\n   *     // deep referencing\n   *     var deepCss = { '.link': { '[target]': 42 }};\n   *     expect(deepCss).to.have.deep.property('\\\\.link.\\\\[target\\\\]', 42);\n   *\n   * @name property\n   * @alias deep.property\n   * @param {String} name\n   * @param {Mixed} value (optional)\n   * @param {String} message _optional_\n   * @returns value of property for chaining\n   * @namespace BDD\n   * @api public\n   */\n\n  Assertion.addMethod('property', function (name, val, msg) {\n    if (msg) flag(this, 'message', msg);\n\n    var isDeep = !!flag(this, 'deep')\n      , descriptor = isDeep ? 'deep property ' : 'property '\n      , negate = flag(this, 'negate')\n      , obj = flag(this, 'object')\n      , pathInfo = isDeep ? _.getPathInfo(name, obj) : null\n      , hasProperty = isDeep\n        ? pathInfo.exists\n        : _.hasProperty(name, obj)\n      , value = isDeep\n        ? pathInfo.value\n        : obj[name];\n\n    if (negate && arguments.length > 1) {\n      if (undefined === value) {\n        msg = (msg != null) ? msg + ': ' : '';\n        throw new Error(msg + _.inspect(obj) + ' has no ' + descriptor + _.inspect(name));\n      }\n    } else {\n      this.assert(\n          hasProperty\n        , 'expected #{this} to have a ' + descriptor + _.inspect(name)\n        , 'expected #{this} to not have ' + descriptor + _.inspect(name));\n    }\n\n    if (arguments.length > 1) {\n      this.assert(\n          val === value\n        , 'expected #{this} to have a ' + descriptor + _.inspect(name) + ' of #{exp}, but got #{act}'\n        , 'expected #{this} to not have a ' + descriptor + _.inspect(name) + ' of #{act}'\n        , val\n        , value\n      );\n    }\n\n    flag(this, 'object', value);\n  });\n\n\n  /**\n   * ### .ownProperty(name)\n   *\n   * Asserts that the target has an own property `name`.\n   *\n   *     expect('test').to.have.ownProperty('length');\n   *\n   * @name ownProperty\n   * @alias haveOwnProperty\n   * @param {String} name\n   * @param {String} message _optional_\n   * @namespace BDD\n   * @api public\n   */\n\n  function assertOwnProperty (name, msg) {\n    if (msg) flag(this, 'message', msg);\n    var obj = flag(this, 'object');\n    this.assert(\n        obj.hasOwnProperty(name)\n      , 'expected #{this} to have own property ' + _.inspect(name)\n      , 'expected #{this} to not have own property ' + _.inspect(name)\n    );\n  }\n\n  Assertion.addMethod('ownProperty', assertOwnProperty);\n  Assertion.addMethod('haveOwnProperty', assertOwnProperty);\n\n  /**\n   * ### .ownPropertyDescriptor(name[, descriptor[, message]])\n   *\n   * Asserts that the target has an own property descriptor `name`, that optionally matches `descriptor`.\n   *\n   *     expect('test').to.have.ownPropertyDescriptor('length');\n   *     expect('test').to.have.ownPropertyDescriptor('length', { enumerable: false, configurable: false, writable: false, value: 4 });\n   *     expect('test').not.to.have.ownPropertyDescriptor('length', { enumerable: false, configurable: false, writable: false, value: 3 });\n   *     expect('test').ownPropertyDescriptor('length').to.have.property('enumerable', false);\n   *     expect('test').ownPropertyDescriptor('length').to.have.keys('value');\n   *\n   * @name ownPropertyDescriptor\n   * @alias haveOwnPropertyDescriptor\n   * @param {String} name\n   * @param {Object} descriptor _optional_\n   * @param {String} message _optional_\n   * @namespace BDD\n   * @api public\n   */\n\n  function assertOwnPropertyDescriptor (name, descriptor, msg) {\n    if (typeof descriptor === 'string') {\n      msg = descriptor;\n      descriptor = null;\n    }\n    if (msg) flag(this, 'message', msg);\n    var obj = flag(this, 'object');\n    var actualDescriptor = Object.getOwnPropertyDescriptor(Object(obj), name);\n    if (actualDescriptor && descriptor) {\n      this.assert(\n          _.eql(descriptor, actualDescriptor)\n        , 'expected the own property descriptor for ' + _.inspect(name) + ' on #{this} to match ' + _.inspect(descriptor) + ', got ' + _.inspect(actualDescriptor)\n        , 'expected the own property descriptor for ' + _.inspect(name) + ' on #{this} to not match ' + _.inspect(descriptor)\n        , descriptor\n        , actualDescriptor\n        , true\n      );\n    } else {\n      this.assert(\n          actualDescriptor\n        , 'expected #{this} to have an own property descriptor for ' + _.inspect(name)\n        , 'expected #{this} to not have an own property descriptor for ' + _.inspect(name)\n      );\n    }\n    flag(this, 'object', actualDescriptor);\n  }\n\n  Assertion.addMethod('ownPropertyDescriptor', assertOwnPropertyDescriptor);\n  Assertion.addMethod('haveOwnPropertyDescriptor', assertOwnPropertyDescriptor);\n\n  /**\n   * ### .length\n   *\n   * Sets the `doLength` flag later used as a chain precursor to a value\n   * comparison for the `length` property.\n   *\n   *     expect('foo').to.have.length.above(2);\n   *     expect([ 1, 2, 3 ]).to.have.length.above(2);\n   *     expect('foo').to.have.length.below(4);\n   *     expect([ 1, 2, 3 ]).to.have.length.below(4);\n   *     expect('foo').to.have.length.within(2,4);\n   *     expect([ 1, 2, 3 ]).to.have.length.within(2,4);\n   *\n   * *Deprecation notice:* Using `length` as an assertion will be deprecated\n   * in version 2.4.0 and removed in 3.0.0. Code using the old style of\n   * asserting for `length` property value using `length(value)` should be\n   * switched to use `lengthOf(value)` instead.\n   *\n   * @name length\n   * @namespace BDD\n   * @api public\n   */\n\n  /**\n   * ### .lengthOf(value[, message])\n   *\n   * Asserts that the target's `length` property has\n   * the expected value.\n   *\n   *     expect([ 1, 2, 3]).to.have.lengthOf(3);\n   *     expect('foobar').to.have.lengthOf(6);\n   *\n   * @name lengthOf\n   * @param {Number} length\n   * @param {String} message _optional_\n   * @namespace BDD\n   * @api public\n   */\n\n  function assertLengthChain () {\n    flag(this, 'doLength', true);\n  }\n\n  function assertLength (n, msg) {\n    if (msg) flag(this, 'message', msg);\n    var obj = flag(this, 'object');\n    new Assertion(obj, msg).to.have.property('length');\n    var len = obj.length;\n\n    this.assert(\n        len == n\n      , 'expected #{this} to have a length of #{exp} but got #{act}'\n      , 'expected #{this} to not have a length of #{act}'\n      , n\n      , len\n    );\n  }\n\n  Assertion.addChainableMethod('length', assertLength, assertLengthChain);\n  Assertion.addMethod('lengthOf', assertLength);\n\n  /**\n   * ### .match(regexp)\n   *\n   * Asserts that the target matches a regular expression.\n   *\n   *     expect('foobar').to.match(/^foo/);\n   *\n   * @name match\n   * @alias matches\n   * @param {RegExp} RegularExpression\n   * @param {String} message _optional_\n   * @namespace BDD\n   * @api public\n   */\n  function assertMatch(re, msg) {\n    if (msg) flag(this, 'message', msg);\n    var obj = flag(this, 'object');\n    this.assert(\n        re.exec(obj)\n      , 'expected #{this} to match ' + re\n      , 'expected #{this} not to match ' + re\n    );\n  }\n\n  Assertion.addMethod('match', assertMatch);\n  Assertion.addMethod('matches', assertMatch);\n\n  /**\n   * ### .string(string)\n   *\n   * Asserts that the string target contains another string.\n   *\n   *     expect('foobar').to.have.string('bar');\n   *\n   * @name string\n   * @param {String} string\n   * @param {String} message _optional_\n   * @namespace BDD\n   * @api public\n   */\n\n  Assertion.addMethod('string', function (str, msg) {\n    if (msg) flag(this, 'message', msg);\n    var obj = flag(this, 'object');\n    new Assertion(obj, msg).is.a('string');\n\n    this.assert(\n        ~obj.indexOf(str)\n      , 'expected #{this} to contain ' + _.inspect(str)\n      , 'expected #{this} to not contain ' + _.inspect(str)\n    );\n  });\n\n\n  /**\n   * ### .keys(key1, [key2], [...])\n   *\n   * Asserts that the target contains any or all of the passed-in keys.\n   * Use in combination with `any`, `all`, `contains`, or `have` will affect\n   * what will pass.\n   *\n   * When used in conjunction with `any`, at least one key that is passed\n   * in must exist in the target object. This is regardless whether or not\n   * the `have` or `contain` qualifiers are used. Note, either `any` or `all`\n   * should be used in the assertion. If neither are used, the assertion is\n   * defaulted to `all`.\n   *\n   * When both `all` and `contain` are used, the target object must have at\n   * least all of the passed-in keys but may have more keys not listed.\n   *\n   * When both `all` and `have` are used, the target object must both contain\n   * all of the passed-in keys AND the number of keys in the target object must\n   * match the number of keys passed in (in other words, a target object must\n   * have all and only all of the passed-in keys).\n   *\n   *     expect({ foo: 1, bar: 2 }).to.have.any.keys('foo', 'baz');\n   *     expect({ foo: 1, bar: 2 }).to.have.any.keys('foo');\n   *     expect({ foo: 1, bar: 2 }).to.contain.any.keys('bar', 'baz');\n   *     expect({ foo: 1, bar: 2 }).to.contain.any.keys(['foo']);\n   *     expect({ foo: 1, bar: 2 }).to.contain.any.keys({'foo': 6});\n   *     expect({ foo: 1, bar: 2 }).to.have.all.keys(['bar', 'foo']);\n   *     expect({ foo: 1, bar: 2 }).to.have.all.keys({'bar': 6, 'foo': 7});\n   *     expect({ foo: 1, bar: 2, baz: 3 }).to.contain.all.keys(['bar', 'foo']);\n   *     expect({ foo: 1, bar: 2, baz: 3 }).to.contain.all.keys({'bar': 6});\n   *\n   *\n   * @name keys\n   * @alias key\n   * @param {...String|Array|Object} keys\n   * @namespace BDD\n   * @api public\n   */\n\n  function assertKeys (keys) {\n    var obj = flag(this, 'object')\n      , str\n      , ok = true\n      , mixedArgsMsg = 'keys must be given single argument of Array|Object|String, or multiple String arguments';\n\n    switch (_.type(keys)) {\n      case \"array\":\n        if (arguments.length > 1) throw (new Error(mixedArgsMsg));\n        break;\n      case \"object\":\n        if (arguments.length > 1) throw (new Error(mixedArgsMsg));\n        keys = Object.keys(keys);\n        break;\n      default:\n        keys = Array.prototype.slice.call(arguments);\n    }\n\n    if (!keys.length) throw new Error('keys required');\n\n    var actual = Object.keys(obj)\n      , expected = keys\n      , len = keys.length\n      , any = flag(this, 'any')\n      , all = flag(this, 'all');\n\n    if (!any && !all) {\n      all = true;\n    }\n\n    // Has any\n    if (any) {\n      var intersection = expected.filter(function(key) {\n        return ~actual.indexOf(key);\n      });\n      ok = intersection.length > 0;\n    }\n\n    // Has all\n    if (all) {\n      ok = keys.every(function(key){\n        return ~actual.indexOf(key);\n      });\n      if (!flag(this, 'negate') && !flag(this, 'contains')) {\n        ok = ok && keys.length == actual.length;\n      }\n    }\n\n    // Key string\n    if (len > 1) {\n      keys = keys.map(function(key){\n        return _.inspect(key);\n      });\n      var last = keys.pop();\n      if (all) {\n        str = keys.join(', ') + ', and ' + last;\n      }\n      if (any) {\n        str = keys.join(', ') + ', or ' + last;\n      }\n    } else {\n      str = _.inspect(keys[0]);\n    }\n\n    // Form\n    str = (len > 1 ? 'keys ' : 'key ') + str;\n\n    // Have / include\n    str = (flag(this, 'contains') ? 'contain ' : 'have ') + str;\n\n    // Assertion\n    this.assert(\n        ok\n      , 'expected #{this} to ' + str\n      , 'expected #{this} to not ' + str\n      , expected.slice(0).sort()\n      , actual.sort()\n      , true\n    );\n  }\n\n  Assertion.addMethod('keys', assertKeys);\n  Assertion.addMethod('key', assertKeys);\n\n  /**\n   * ### .throw(constructor)\n   *\n   * Asserts that the function target will throw a specific error, or specific type of error\n   * (as determined using `instanceof`), optionally with a RegExp or string inclusion test\n   * for the error's message.\n   *\n   *     var err = new ReferenceError('This is a bad function.');\n   *     var fn = function () { throw err; }\n   *     expect(fn).to.throw(ReferenceError);\n   *     expect(fn).to.throw(Error);\n   *     expect(fn).to.throw(/bad function/);\n   *     expect(fn).to.not.throw('good function');\n   *     expect(fn).to.throw(ReferenceError, /bad function/);\n   *     expect(fn).to.throw(err);\n   *\n   * Please note that when a throw expectation is negated, it will check each\n   * parameter independently, starting with error constructor type. The appropriate way\n   * to check for the existence of a type of error but for a message that does not match\n   * is to use `and`.\n   *\n   *     expect(fn).to.throw(ReferenceError)\n   *        .and.not.throw(/good function/);\n   *\n   * @name throw\n   * @alias throws\n   * @alias Throw\n   * @param {ErrorConstructor} constructor\n   * @param {String|RegExp} expected error message\n   * @param {String} message _optional_\n   * @see https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Error#Error_types\n   * @returns error for chaining (null if no error)\n   * @namespace BDD\n   * @api public\n   */\n\n  function assertThrows (constructor, errMsg, msg) {\n    if (msg) flag(this, 'message', msg);\n    var obj = flag(this, 'object');\n    new Assertion(obj, msg).is.a('function');\n\n    var thrown = false\n      , desiredError = null\n      , name = null\n      , thrownError = null;\n\n    if (arguments.length === 0) {\n      errMsg = null;\n      constructor = null;\n    } else if (constructor && (constructor instanceof RegExp || 'string' === typeof constructor)) {\n      errMsg = constructor;\n      constructor = null;\n    } else if (constructor && constructor instanceof Error) {\n      desiredError = constructor;\n      constructor = null;\n      errMsg = null;\n    } else if (typeof constructor === 'function') {\n      name = constructor.prototype.name;\n      if (!name || (name === 'Error' && constructor !== Error)) {\n        name = constructor.name || (new constructor()).name;\n      }\n    } else {\n      constructor = null;\n    }\n\n    try {\n      obj();\n    } catch (err) {\n      // first, check desired error\n      if (desiredError) {\n        this.assert(\n            err === desiredError\n          , 'expected #{this} to throw #{exp} but #{act} was thrown'\n          , 'expected #{this} to not throw #{exp}'\n          , (desiredError instanceof Error ? desiredError.toString() : desiredError)\n          , (err instanceof Error ? err.toString() : err)\n        );\n\n        flag(this, 'object', err);\n        return this;\n      }\n\n      // next, check constructor\n      if (constructor) {\n        this.assert(\n            err instanceof constructor\n          , 'expected #{this} to throw #{exp} but #{act} was thrown'\n          , 'expected #{this} to not throw #{exp} but #{act} was thrown'\n          , name\n          , (err instanceof Error ? err.toString() : err)\n        );\n\n        if (!errMsg) {\n          flag(this, 'object', err);\n          return this;\n        }\n      }\n\n      // next, check message\n      var message = 'error' === _.type(err) && \"message\" in err\n        ? err.message\n        : '' + err;\n\n      if ((message != null) && errMsg && errMsg instanceof RegExp) {\n        this.assert(\n            errMsg.exec(message)\n          , 'expected #{this} to throw error matching #{exp} but got #{act}'\n          , 'expected #{this} to throw error not matching #{exp}'\n          , errMsg\n          , message\n        );\n\n        flag(this, 'object', err);\n        return this;\n      } else if ((message != null) && errMsg && 'string' === typeof errMsg) {\n        this.assert(\n            ~message.indexOf(errMsg)\n          , 'expected #{this} to throw error including #{exp} but got #{act}'\n          , 'expected #{this} to throw error not including #{act}'\n          , errMsg\n          , message\n        );\n\n        flag(this, 'object', err);\n        return this;\n      } else {\n        thrown = true;\n        thrownError = err;\n      }\n    }\n\n    var actuallyGot = ''\n      , expectedThrown = name !== null\n        ? name\n        : desiredError\n          ? '#{exp}' //_.inspect(desiredError)\n          : 'an error';\n\n    if (thrown) {\n      actuallyGot = ' but #{act} was thrown'\n    }\n\n    this.assert(\n        thrown === true\n      , 'expected #{this} to throw ' + expectedThrown + actuallyGot\n      , 'expected #{this} to not throw ' + expectedThrown + actuallyGot\n      , (desiredError instanceof Error ? desiredError.toString() : desiredError)\n      , (thrownError instanceof Error ? thrownError.toString() : thrownError)\n    );\n\n    flag(this, 'object', thrownError);\n  };\n\n  Assertion.addMethod('throw', assertThrows);\n  Assertion.addMethod('throws', assertThrows);\n  Assertion.addMethod('Throw', assertThrows);\n\n  /**\n   * ### .respondTo(method)\n   *\n   * Asserts that the object or class target will respond to a method.\n   *\n   *     Klass.prototype.bar = function(){};\n   *     expect(Klass).to.respondTo('bar');\n   *     expect(obj).to.respondTo('bar');\n   *\n   * To check if a constructor will respond to a static function,\n   * set the `itself` flag.\n   *\n   *     Klass.baz = function(){};\n   *     expect(Klass).itself.to.respondTo('baz');\n   *\n   * @name respondTo\n   * @alias respondsTo\n   * @param {String} method\n   * @param {String} message _optional_\n   * @namespace BDD\n   * @api public\n   */\n\n  function respondTo (method, msg) {\n    if (msg) flag(this, 'message', msg);\n    var obj = flag(this, 'object')\n      , itself = flag(this, 'itself')\n      , context = ('function' === _.type(obj) && !itself)\n        ? obj.prototype[method]\n        : obj[method];\n\n    this.assert(\n        'function' === typeof context\n      , 'expected #{this} to respond to ' + _.inspect(method)\n      , 'expected #{this} to not respond to ' + _.inspect(method)\n    );\n  }\n\n  Assertion.addMethod('respondTo', respondTo);\n  Assertion.addMethod('respondsTo', respondTo);\n\n  /**\n   * ### .itself\n   *\n   * Sets the `itself` flag, later used by the `respondTo` assertion.\n   *\n   *     function Foo() {}\n   *     Foo.bar = function() {}\n   *     Foo.prototype.baz = function() {}\n   *\n   *     expect(Foo).itself.to.respondTo('bar');\n   *     expect(Foo).itself.not.to.respondTo('baz');\n   *\n   * @name itself\n   * @namespace BDD\n   * @api public\n   */\n\n  Assertion.addProperty('itself', function () {\n    flag(this, 'itself', true);\n  });\n\n  /**\n   * ### .satisfy(method)\n   *\n   * Asserts that the target passes a given truth test.\n   *\n   *     expect(1).to.satisfy(function(num) { return num > 0; });\n   *\n   * @name satisfy\n   * @alias satisfies\n   * @param {Function} matcher\n   * @param {String} message _optional_\n   * @namespace BDD\n   * @api public\n   */\n\n  function satisfy (matcher, msg) {\n    if (msg) flag(this, 'message', msg);\n    var obj = flag(this, 'object');\n    var result = matcher(obj);\n    this.assert(\n        result\n      , 'expected #{this} to satisfy ' + _.objDisplay(matcher)\n      , 'expected #{this} to not satisfy' + _.objDisplay(matcher)\n      , this.negate ? false : true\n      , result\n    );\n  }\n\n  Assertion.addMethod('satisfy', satisfy);\n  Assertion.addMethod('satisfies', satisfy);\n\n  /**\n   * ### .closeTo(expected, delta)\n   *\n   * Asserts that the target is equal `expected`, to within a +/- `delta` range.\n   *\n   *     expect(1.5).to.be.closeTo(1, 0.5);\n   *\n   * @name closeTo\n   * @alias approximately\n   * @param {Number} expected\n   * @param {Number} delta\n   * @param {String} message _optional_\n   * @namespace BDD\n   * @api public\n   */\n\n  function closeTo(expected, delta, msg) {\n    if (msg) flag(this, 'message', msg);\n    var obj = flag(this, 'object');\n\n    new Assertion(obj, msg).is.a('number');\n    if (_.type(expected) !== 'number' || _.type(delta) !== 'number') {\n      throw new Error('the arguments to closeTo or approximately must be numbers');\n    }\n\n    this.assert(\n        Math.abs(obj - expected) <= delta\n      , 'expected #{this} to be close to ' + expected + ' +/- ' + delta\n      , 'expected #{this} not to be close to ' + expected + ' +/- ' + delta\n    );\n  }\n\n  Assertion.addMethod('closeTo', closeTo);\n  Assertion.addMethod('approximately', closeTo);\n\n  function isSubsetOf(subset, superset, cmp) {\n    return subset.every(function(elem) {\n      if (!cmp) return superset.indexOf(elem) !== -1;\n\n      return superset.some(function(elem2) {\n        return cmp(elem, elem2);\n      });\n    })\n  }\n\n  /**\n   * ### .members(set)\n   *\n   * Asserts that the target is a superset of `set`,\n   * or that the target and `set` have the same strictly-equal (===) members.\n   * Alternately, if the `deep` flag is set, set members are compared for deep\n   * equality.\n   *\n   *     expect([1, 2, 3]).to.include.members([3, 2]);\n   *     expect([1, 2, 3]).to.not.include.members([3, 2, 8]);\n   *\n   *     expect([4, 2]).to.have.members([2, 4]);\n   *     expect([5, 2]).to.not.have.members([5, 2, 1]);\n   *\n   *     expect([{ id: 1 }]).to.deep.include.members([{ id: 1 }]);\n   *\n   * @name members\n   * @param {Array} set\n   * @param {String} message _optional_\n   * @namespace BDD\n   * @api public\n   */\n\n  Assertion.addMethod('members', function (subset, msg) {\n    if (msg) flag(this, 'message', msg);\n    var obj = flag(this, 'object');\n\n    new Assertion(obj).to.be.an('array');\n    new Assertion(subset).to.be.an('array');\n\n    var cmp = flag(this, 'deep') ? _.eql : undefined;\n\n    if (flag(this, 'contains')) {\n      return this.assert(\n          isSubsetOf(subset, obj, cmp)\n        , 'expected #{this} to be a superset of #{act}'\n        , 'expected #{this} to not be a superset of #{act}'\n        , obj\n        , subset\n      );\n    }\n\n    this.assert(\n        isSubsetOf(obj, subset, cmp) && isSubsetOf(subset, obj, cmp)\n        , 'expected #{this} to have the same members as #{act}'\n        , 'expected #{this} to not have the same members as #{act}'\n        , obj\n        , subset\n    );\n  });\n\n  /**\n   * ### .oneOf(list)\n   *\n   * Assert that a value appears somewhere in the top level of array `list`.\n   *\n   *     expect('a').to.be.oneOf(['a', 'b', 'c']);\n   *     expect(9).to.not.be.oneOf(['z']);\n   *     expect([3]).to.not.be.oneOf([1, 2, [3]]);\n   *\n   *     var three = [3];\n   *     // for object-types, contents are not compared\n   *     expect(three).to.not.be.oneOf([1, 2, [3]]);\n   *     // comparing references works\n   *     expect(three).to.be.oneOf([1, 2, three]);\n   *\n   * @name oneOf\n   * @param {Array<*>} list\n   * @param {String} message _optional_\n   * @namespace BDD\n   * @api public\n   */\n\n  function oneOf (list, msg) {\n    if (msg) flag(this, 'message', msg);\n    var expected = flag(this, 'object');\n    new Assertion(list).to.be.an('array');\n\n    this.assert(\n        list.indexOf(expected) > -1\n      , 'expected #{this} to be one of #{exp}'\n      , 'expected #{this} to not be one of #{exp}'\n      , list\n      , expected\n    );\n  }\n\n  Assertion.addMethod('oneOf', oneOf);\n\n\n  /**\n   * ### .change(function)\n   *\n   * Asserts that a function changes an object property\n   *\n   *     var obj = { val: 10 };\n   *     var fn = function() { obj.val += 3 };\n   *     var noChangeFn = function() { return 'foo' + 'bar'; }\n   *     expect(fn).to.change(obj, 'val');\n   *     expect(noChangeFn).to.not.change(obj, 'val')\n   *\n   * @name change\n   * @alias changes\n   * @alias Change\n   * @param {String} object\n   * @param {String} property name\n   * @param {String} message _optional_\n   * @namespace BDD\n   * @api public\n   */\n\n  function assertChanges (object, prop, msg) {\n    if (msg) flag(this, 'message', msg);\n    var fn = flag(this, 'object');\n    new Assertion(object, msg).to.have.property(prop);\n    new Assertion(fn).is.a('function');\n\n    var initial = object[prop];\n    fn();\n\n    this.assert(\n      initial !== object[prop]\n      , 'expected .' + prop + ' to change'\n      , 'expected .' + prop + ' to not change'\n    );\n  }\n\n  Assertion.addChainableMethod('change', assertChanges);\n  Assertion.addChainableMethod('changes', assertChanges);\n\n  /**\n   * ### .increase(function)\n   *\n   * Asserts that a function increases an object property\n   *\n   *     var obj = { val: 10 };\n   *     var fn = function() { obj.val = 15 };\n   *     expect(fn).to.increase(obj, 'val');\n   *\n   * @name increase\n   * @alias increases\n   * @alias Increase\n   * @param {String} object\n   * @param {String} property name\n   * @param {String} message _optional_\n   * @namespace BDD\n   * @api public\n   */\n\n  function assertIncreases (object, prop, msg) {\n    if (msg) flag(this, 'message', msg);\n    var fn = flag(this, 'object');\n    new Assertion(object, msg).to.have.property(prop);\n    new Assertion(fn).is.a('function');\n\n    var initial = object[prop];\n    fn();\n\n    this.assert(\n      object[prop] - initial > 0\n      , 'expected .' + prop + ' to increase'\n      , 'expected .' + prop + ' to not increase'\n    );\n  }\n\n  Assertion.addChainableMethod('increase', assertIncreases);\n  Assertion.addChainableMethod('increases', assertIncreases);\n\n  /**\n   * ### .decrease(function)\n   *\n   * Asserts that a function decreases an object property\n   *\n   *     var obj = { val: 10 };\n   *     var fn = function() { obj.val = 5 };\n   *     expect(fn).to.decrease(obj, 'val');\n   *\n   * @name decrease\n   * @alias decreases\n   * @alias Decrease\n   * @param {String} object\n   * @param {String} property name\n   * @param {String} message _optional_\n   * @namespace BDD\n   * @api public\n   */\n\n  function assertDecreases (object, prop, msg) {\n    if (msg) flag(this, 'message', msg);\n    var fn = flag(this, 'object');\n    new Assertion(object, msg).to.have.property(prop);\n    new Assertion(fn).is.a('function');\n\n    var initial = object[prop];\n    fn();\n\n    this.assert(\n      object[prop] - initial < 0\n      , 'expected .' + prop + ' to decrease'\n      , 'expected .' + prop + ' to not decrease'\n    );\n  }\n\n  Assertion.addChainableMethod('decrease', assertDecreases);\n  Assertion.addChainableMethod('decreases', assertDecreases);\n\n  /**\n   * ### .extensible\n   *\n   * Asserts that the target is extensible (can have new properties added to\n   * it).\n   *\n   *     var nonExtensibleObject = Object.preventExtensions({});\n   *     var sealedObject = Object.seal({});\n   *     var frozenObject = Object.freeze({});\n   *\n   *     expect({}).to.be.extensible;\n   *     expect(nonExtensibleObject).to.not.be.extensible;\n   *     expect(sealedObject).to.not.be.extensible;\n   *     expect(frozenObject).to.not.be.extensible;\n   *\n   * @name extensible\n   * @namespace BDD\n   * @api public\n   */\n\n  Assertion.addProperty('extensible', function() {\n    var obj = flag(this, 'object');\n\n    // In ES5, if the argument to this method is not an object (a primitive), then it will cause a TypeError.\n    // In ES6, a non-object argument will be treated as if it was a non-extensible ordinary object, simply return false.\n    // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/isExtensible\n    // The following provides ES6 behavior when a TypeError is thrown under ES5.\n\n    var isExtensible;\n\n    try {\n      isExtensible = Object.isExtensible(obj);\n    } catch (err) {\n      if (err instanceof TypeError) isExtensible = false;\n      else throw err;\n    }\n\n    this.assert(\n      isExtensible\n      , 'expected #{this} to be extensible'\n      , 'expected #{this} to not be extensible'\n    );\n  });\n\n  /**\n   * ### .sealed\n   *\n   * Asserts that the target is sealed (cannot have new properties added to it\n   * and its existing properties cannot be removed).\n   *\n   *     var sealedObject = Object.seal({});\n   *     var frozenObject = Object.freeze({});\n   *\n   *     expect(sealedObject).to.be.sealed;\n   *     expect(frozenObject).to.be.sealed;\n   *     expect({}).to.not.be.sealed;\n   *\n   * @name sealed\n   * @namespace BDD\n   * @api public\n   */\n\n  Assertion.addProperty('sealed', function() {\n    var obj = flag(this, 'object');\n\n    // In ES5, if the argument to this method is not an object (a primitive), then it will cause a TypeError.\n    // In ES6, a non-object argument will be treated as if it was a sealed ordinary object, simply return true.\n    // See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/isSealed\n    // The following provides ES6 behavior when a TypeError is thrown under ES5.\n\n    var isSealed;\n\n    try {\n      isSealed = Object.isSealed(obj);\n    } catch (err) {\n      if (err instanceof TypeError) isSealed = true;\n      else throw err;\n    }\n\n    this.assert(\n      isSealed\n      , 'expected #{this} to be sealed'\n      , 'expected #{this} to not be sealed'\n    );\n  });\n\n  /**\n   * ### .frozen\n   *\n   * Asserts that the target is frozen (cannot have new properties added to it\n   * and its existing properties cannot be modified).\n   *\n   *     var frozenObject = Object.freeze({});\n   *\n   *     expect(frozenObject).to.be.frozen;\n   *     expect({}).to.not.be.frozen;\n   *\n   * @name frozen\n   * @namespace BDD\n   * @api public\n   */\n\n  Assertion.addProperty('frozen', function() {\n    var obj = flag(this, 'object');\n\n    // In ES5, if the argument to this method is not an object (a primitive), then it will cause a TypeError.\n    // In ES6, a non-object argument will be treated as if it was a frozen ordinary object, simply return true.\n    // See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/isFrozen\n    // The following provides ES6 behavior when a TypeError is thrown under ES5.\n\n    var isFrozen;\n\n    try {\n      isFrozen = Object.isFrozen(obj);\n    } catch (err) {\n      if (err instanceof TypeError) isFrozen = true;\n      else throw err;\n    }\n\n    this.assert(\n      isFrozen\n      , 'expected #{this} to be frozen'\n      , 'expected #{this} to not be frozen'\n    );\n  });\n};\n\n},{}],6:[function(require,module,exports){\n/*!\n * chai\n * Copyright(c) 2011-2014 Jake Luer <jake@alogicalparadox.com>\n * MIT Licensed\n */\n\n\nmodule.exports = function (chai, util) {\n\n  /*!\n   * Chai dependencies.\n   */\n\n  var Assertion = chai.Assertion\n    , flag = util.flag;\n\n  /*!\n   * Module export.\n   */\n\n  /**\n   * ### assert(expression, message)\n   *\n   * Write your own test expressions.\n   *\n   *     assert('foo' !== 'bar', 'foo is not bar');\n   *     assert(Array.isArray([]), 'empty arrays are arrays');\n   *\n   * @param {Mixed} expression to test for truthiness\n   * @param {String} message to display on error\n   * @name assert\n   * @namespace Assert\n   * @api public\n   */\n\n  var assert = chai.assert = function (express, errmsg) {\n    var test = new Assertion(null, null, chai.assert);\n    test.assert(\n        express\n      , errmsg\n      , '[ negation message unavailable ]'\n    );\n  };\n\n  /**\n   * ### .fail(actual, expected, [message], [operator])\n   *\n   * Throw a failure. Node.js `assert` module-compatible.\n   *\n   * @name fail\n   * @param {Mixed} actual\n   * @param {Mixed} expected\n   * @param {String} message\n   * @param {String} operator\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.fail = function (actual, expected, message, operator) {\n    message = message || 'assert.fail()';\n    throw new chai.AssertionError(message, {\n        actual: actual\n      , expected: expected\n      , operator: operator\n    }, assert.fail);\n  };\n\n  /**\n   * ### .isOk(object, [message])\n   *\n   * Asserts that `object` is truthy.\n   *\n   *     assert.isOk('everything', 'everything is ok');\n   *     assert.isOk(false, 'this will fail');\n   *\n   * @name isOk\n   * @alias ok\n   * @param {Mixed} object to test\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.isOk = function (val, msg) {\n    new Assertion(val, msg).is.ok;\n  };\n\n  /**\n   * ### .isNotOk(object, [message])\n   *\n   * Asserts that `object` is falsy.\n   *\n   *     assert.isNotOk('everything', 'this will fail');\n   *     assert.isNotOk(false, 'this will pass');\n   *\n   * @name isNotOk\n   * @alias notOk\n   * @param {Mixed} object to test\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.isNotOk = function (val, msg) {\n    new Assertion(val, msg).is.not.ok;\n  };\n\n  /**\n   * ### .equal(actual, expected, [message])\n   *\n   * Asserts non-strict equality (`==`) of `actual` and `expected`.\n   *\n   *     assert.equal(3, '3', '== coerces values to strings');\n   *\n   * @name equal\n   * @param {Mixed} actual\n   * @param {Mixed} expected\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.equal = function (act, exp, msg) {\n    var test = new Assertion(act, msg, assert.equal);\n\n    test.assert(\n        exp == flag(test, 'object')\n      , 'expected #{this} to equal #{exp}'\n      , 'expected #{this} to not equal #{act}'\n      , exp\n      , act\n    );\n  };\n\n  /**\n   * ### .notEqual(actual, expected, [message])\n   *\n   * Asserts non-strict inequality (`!=`) of `actual` and `expected`.\n   *\n   *     assert.notEqual(3, 4, 'these numbers are not equal');\n   *\n   * @name notEqual\n   * @param {Mixed} actual\n   * @param {Mixed} expected\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.notEqual = function (act, exp, msg) {\n    var test = new Assertion(act, msg, assert.notEqual);\n\n    test.assert(\n        exp != flag(test, 'object')\n      , 'expected #{this} to not equal #{exp}'\n      , 'expected #{this} to equal #{act}'\n      , exp\n      , act\n    );\n  };\n\n  /**\n   * ### .strictEqual(actual, expected, [message])\n   *\n   * Asserts strict equality (`===`) of `actual` and `expected`.\n   *\n   *     assert.strictEqual(true, true, 'these booleans are strictly equal');\n   *\n   * @name strictEqual\n   * @param {Mixed} actual\n   * @param {Mixed} expected\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.strictEqual = function (act, exp, msg) {\n    new Assertion(act, msg).to.equal(exp);\n  };\n\n  /**\n   * ### .notStrictEqual(actual, expected, [message])\n   *\n   * Asserts strict inequality (`!==`) of `actual` and `expected`.\n   *\n   *     assert.notStrictEqual(3, '3', 'no coercion for strict equality');\n   *\n   * @name notStrictEqual\n   * @param {Mixed} actual\n   * @param {Mixed} expected\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.notStrictEqual = function (act, exp, msg) {\n    new Assertion(act, msg).to.not.equal(exp);\n  };\n\n  /**\n   * ### .deepEqual(actual, expected, [message])\n   *\n   * Asserts that `actual` is deeply equal to `expected`.\n   *\n   *     assert.deepEqual({ tea: 'green' }, { tea: 'green' });\n   *\n   * @name deepEqual\n   * @param {Mixed} actual\n   * @param {Mixed} expected\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.deepEqual = function (act, exp, msg) {\n    new Assertion(act, msg).to.eql(exp);\n  };\n\n  /**\n   * ### .notDeepEqual(actual, expected, [message])\n   *\n   * Assert that `actual` is not deeply equal to `expected`.\n   *\n   *     assert.notDeepEqual({ tea: 'green' }, { tea: 'jasmine' });\n   *\n   * @name notDeepEqual\n   * @param {Mixed} actual\n   * @param {Mixed} expected\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.notDeepEqual = function (act, exp, msg) {\n    new Assertion(act, msg).to.not.eql(exp);\n  };\n\n   /**\n   * ### .isAbove(valueToCheck, valueToBeAbove, [message])\n   *\n   * Asserts `valueToCheck` is strictly greater than (>) `valueToBeAbove`\n   *\n   *     assert.isAbove(5, 2, '5 is strictly greater than 2');\n   *\n   * @name isAbove\n   * @param {Mixed} valueToCheck\n   * @param {Mixed} valueToBeAbove\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.isAbove = function (val, abv, msg) {\n    new Assertion(val, msg).to.be.above(abv);\n  };\n\n   /**\n   * ### .isAtLeast(valueToCheck, valueToBeAtLeast, [message])\n   *\n   * Asserts `valueToCheck` is greater than or equal to (>=) `valueToBeAtLeast`\n   *\n   *     assert.isAtLeast(5, 2, '5 is greater or equal to 2');\n   *     assert.isAtLeast(3, 3, '3 is greater or equal to 3');\n   *\n   * @name isAtLeast\n   * @param {Mixed} valueToCheck\n   * @param {Mixed} valueToBeAtLeast\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.isAtLeast = function (val, atlst, msg) {\n    new Assertion(val, msg).to.be.least(atlst);\n  };\n\n   /**\n   * ### .isBelow(valueToCheck, valueToBeBelow, [message])\n   *\n   * Asserts `valueToCheck` is strictly less than (<) `valueToBeBelow`\n   *\n   *     assert.isBelow(3, 6, '3 is strictly less than 6');\n   *\n   * @name isBelow\n   * @param {Mixed} valueToCheck\n   * @param {Mixed} valueToBeBelow\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.isBelow = function (val, blw, msg) {\n    new Assertion(val, msg).to.be.below(blw);\n  };\n\n   /**\n   * ### .isAtMost(valueToCheck, valueToBeAtMost, [message])\n   *\n   * Asserts `valueToCheck` is less than or equal to (<=) `valueToBeAtMost`\n   *\n   *     assert.isAtMost(3, 6, '3 is less than or equal to 6');\n   *     assert.isAtMost(4, 4, '4 is less than or equal to 4');\n   *\n   * @name isAtMost\n   * @param {Mixed} valueToCheck\n   * @param {Mixed} valueToBeAtMost\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.isAtMost = function (val, atmst, msg) {\n    new Assertion(val, msg).to.be.most(atmst);\n  };\n\n  /**\n   * ### .isTrue(value, [message])\n   *\n   * Asserts that `value` is true.\n   *\n   *     var teaServed = true;\n   *     assert.isTrue(teaServed, 'the tea has been served');\n   *\n   * @name isTrue\n   * @param {Mixed} value\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.isTrue = function (val, msg) {\n    new Assertion(val, msg).is['true'];\n  };\n\n  /**\n   * ### .isNotTrue(value, [message])\n   *\n   * Asserts that `value` is not true.\n   *\n   *     var tea = 'tasty chai';\n   *     assert.isNotTrue(tea, 'great, time for tea!');\n   *\n   * @name isNotTrue\n   * @param {Mixed} value\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.isNotTrue = function (val, msg) {\n    new Assertion(val, msg).to.not.equal(true);\n  };\n\n  /**\n   * ### .isFalse(value, [message])\n   *\n   * Asserts that `value` is false.\n   *\n   *     var teaServed = false;\n   *     assert.isFalse(teaServed, 'no tea yet? hmm...');\n   *\n   * @name isFalse\n   * @param {Mixed} value\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.isFalse = function (val, msg) {\n    new Assertion(val, msg).is['false'];\n  };\n\n  /**\n   * ### .isNotFalse(value, [message])\n   *\n   * Asserts that `value` is not false.\n   *\n   *     var tea = 'tasty chai';\n   *     assert.isNotFalse(tea, 'great, time for tea!');\n   *\n   * @name isNotFalse\n   * @param {Mixed} value\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.isNotFalse = function (val, msg) {\n    new Assertion(val, msg).to.not.equal(false);\n  };\n\n  /**\n   * ### .isNull(value, [message])\n   *\n   * Asserts that `value` is null.\n   *\n   *     assert.isNull(err, 'there was no error');\n   *\n   * @name isNull\n   * @param {Mixed} value\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.isNull = function (val, msg) {\n    new Assertion(val, msg).to.equal(null);\n  };\n\n  /**\n   * ### .isNotNull(value, [message])\n   *\n   * Asserts that `value` is not null.\n   *\n   *     var tea = 'tasty chai';\n   *     assert.isNotNull(tea, 'great, time for tea!');\n   *\n   * @name isNotNull\n   * @param {Mixed} value\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.isNotNull = function (val, msg) {\n    new Assertion(val, msg).to.not.equal(null);\n  };\n\n  /**\n   * ### .isNaN\n   * Asserts that value is NaN\n   *\n   *    assert.isNaN('foo', 'foo is NaN');\n   *\n   * @name isNaN\n   * @param {Mixed} value\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.isNaN = function (val, msg) {\n    new Assertion(val, msg).to.be.NaN;\n  };\n\n  /**\n   * ### .isNotNaN\n   * Asserts that value is not NaN\n   *\n   *    assert.isNotNaN(4, '4 is not NaN');\n   *\n   * @name isNotNaN\n   * @param {Mixed} value\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n  assert.isNotNaN = function (val, msg) {\n    new Assertion(val, msg).not.to.be.NaN;\n  };\n\n  /**\n   * ### .isUndefined(value, [message])\n   *\n   * Asserts that `value` is `undefined`.\n   *\n   *     var tea;\n   *     assert.isUndefined(tea, 'no tea defined');\n   *\n   * @name isUndefined\n   * @param {Mixed} value\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.isUndefined = function (val, msg) {\n    new Assertion(val, msg).to.equal(undefined);\n  };\n\n  /**\n   * ### .isDefined(value, [message])\n   *\n   * Asserts that `value` is not `undefined`.\n   *\n   *     var tea = 'cup of chai';\n   *     assert.isDefined(tea, 'tea has been defined');\n   *\n   * @name isDefined\n   * @param {Mixed} value\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.isDefined = function (val, msg) {\n    new Assertion(val, msg).to.not.equal(undefined);\n  };\n\n  /**\n   * ### .isFunction(value, [message])\n   *\n   * Asserts that `value` is a function.\n   *\n   *     function serveTea() { return 'cup of tea'; };\n   *     assert.isFunction(serveTea, 'great, we can have tea now');\n   *\n   * @name isFunction\n   * @param {Mixed} value\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.isFunction = function (val, msg) {\n    new Assertion(val, msg).to.be.a('function');\n  };\n\n  /**\n   * ### .isNotFunction(value, [message])\n   *\n   * Asserts that `value` is _not_ a function.\n   *\n   *     var serveTea = [ 'heat', 'pour', 'sip' ];\n   *     assert.isNotFunction(serveTea, 'great, we have listed the steps');\n   *\n   * @name isNotFunction\n   * @param {Mixed} value\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.isNotFunction = function (val, msg) {\n    new Assertion(val, msg).to.not.be.a('function');\n  };\n\n  /**\n   * ### .isObject(value, [message])\n   *\n   * Asserts that `value` is an object of type 'Object' (as revealed by `Object.prototype.toString`).\n   * _The assertion does not match subclassed objects._\n   *\n   *     var selection = { name: 'Chai', serve: 'with spices' };\n   *     assert.isObject(selection, 'tea selection is an object');\n   *\n   * @name isObject\n   * @param {Mixed} value\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.isObject = function (val, msg) {\n    new Assertion(val, msg).to.be.a('object');\n  };\n\n  /**\n   * ### .isNotObject(value, [message])\n   *\n   * Asserts that `value` is _not_ an object of type 'Object' (as revealed by `Object.prototype.toString`).\n   *\n   *     var selection = 'chai'\n   *     assert.isNotObject(selection, 'tea selection is not an object');\n   *     assert.isNotObject(null, 'null is not an object');\n   *\n   * @name isNotObject\n   * @param {Mixed} value\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.isNotObject = function (val, msg) {\n    new Assertion(val, msg).to.not.be.a('object');\n  };\n\n  /**\n   * ### .isArray(value, [message])\n   *\n   * Asserts that `value` is an array.\n   *\n   *     var menu = [ 'green', 'chai', 'oolong' ];\n   *     assert.isArray(menu, 'what kind of tea do we want?');\n   *\n   * @name isArray\n   * @param {Mixed} value\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.isArray = function (val, msg) {\n    new Assertion(val, msg).to.be.an('array');\n  };\n\n  /**\n   * ### .isNotArray(value, [message])\n   *\n   * Asserts that `value` is _not_ an array.\n   *\n   *     var menu = 'green|chai|oolong';\n   *     assert.isNotArray(menu, 'what kind of tea do we want?');\n   *\n   * @name isNotArray\n   * @param {Mixed} value\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.isNotArray = function (val, msg) {\n    new Assertion(val, msg).to.not.be.an('array');\n  };\n\n  /**\n   * ### .isString(value, [message])\n   *\n   * Asserts that `value` is a string.\n   *\n   *     var teaOrder = 'chai';\n   *     assert.isString(teaOrder, 'order placed');\n   *\n   * @name isString\n   * @param {Mixed} value\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.isString = function (val, msg) {\n    new Assertion(val, msg).to.be.a('string');\n  };\n\n  /**\n   * ### .isNotString(value, [message])\n   *\n   * Asserts that `value` is _not_ a string.\n   *\n   *     var teaOrder = 4;\n   *     assert.isNotString(teaOrder, 'order placed');\n   *\n   * @name isNotString\n   * @param {Mixed} value\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.isNotString = function (val, msg) {\n    new Assertion(val, msg).to.not.be.a('string');\n  };\n\n  /**\n   * ### .isNumber(value, [message])\n   *\n   * Asserts that `value` is a number.\n   *\n   *     var cups = 2;\n   *     assert.isNumber(cups, 'how many cups');\n   *\n   * @name isNumber\n   * @param {Number} value\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.isNumber = function (val, msg) {\n    new Assertion(val, msg).to.be.a('number');\n  };\n\n  /**\n   * ### .isNotNumber(value, [message])\n   *\n   * Asserts that `value` is _not_ a number.\n   *\n   *     var cups = '2 cups please';\n   *     assert.isNotNumber(cups, 'how many cups');\n   *\n   * @name isNotNumber\n   * @param {Mixed} value\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.isNotNumber = function (val, msg) {\n    new Assertion(val, msg).to.not.be.a('number');\n  };\n\n  /**\n   * ### .isBoolean(value, [message])\n   *\n   * Asserts that `value` is a boolean.\n   *\n   *     var teaReady = true\n   *       , teaServed = false;\n   *\n   *     assert.isBoolean(teaReady, 'is the tea ready');\n   *     assert.isBoolean(teaServed, 'has tea been served');\n   *\n   * @name isBoolean\n   * @param {Mixed} value\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.isBoolean = function (val, msg) {\n    new Assertion(val, msg).to.be.a('boolean');\n  };\n\n  /**\n   * ### .isNotBoolean(value, [message])\n   *\n   * Asserts that `value` is _not_ a boolean.\n   *\n   *     var teaReady = 'yep'\n   *       , teaServed = 'nope';\n   *\n   *     assert.isNotBoolean(teaReady, 'is the tea ready');\n   *     assert.isNotBoolean(teaServed, 'has tea been served');\n   *\n   * @name isNotBoolean\n   * @param {Mixed} value\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.isNotBoolean = function (val, msg) {\n    new Assertion(val, msg).to.not.be.a('boolean');\n  };\n\n  /**\n   * ### .typeOf(value, name, [message])\n   *\n   * Asserts that `value`'s type is `name`, as determined by\n   * `Object.prototype.toString`.\n   *\n   *     assert.typeOf({ tea: 'chai' }, 'object', 'we have an object');\n   *     assert.typeOf(['chai', 'jasmine'], 'array', 'we have an array');\n   *     assert.typeOf('tea', 'string', 'we have a string');\n   *     assert.typeOf(/tea/, 'regexp', 'we have a regular expression');\n   *     assert.typeOf(null, 'null', 'we have a null');\n   *     assert.typeOf(undefined, 'undefined', 'we have an undefined');\n   *\n   * @name typeOf\n   * @param {Mixed} value\n   * @param {String} name\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.typeOf = function (val, type, msg) {\n    new Assertion(val, msg).to.be.a(type);\n  };\n\n  /**\n   * ### .notTypeOf(value, name, [message])\n   *\n   * Asserts that `value`'s type is _not_ `name`, as determined by\n   * `Object.prototype.toString`.\n   *\n   *     assert.notTypeOf('tea', 'number', 'strings are not numbers');\n   *\n   * @name notTypeOf\n   * @param {Mixed} value\n   * @param {String} typeof name\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.notTypeOf = function (val, type, msg) {\n    new Assertion(val, msg).to.not.be.a(type);\n  };\n\n  /**\n   * ### .instanceOf(object, constructor, [message])\n   *\n   * Asserts that `value` is an instance of `constructor`.\n   *\n   *     var Tea = function (name) { this.name = name; }\n   *       , chai = new Tea('chai');\n   *\n   *     assert.instanceOf(chai, Tea, 'chai is an instance of tea');\n   *\n   * @name instanceOf\n   * @param {Object} object\n   * @param {Constructor} constructor\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.instanceOf = function (val, type, msg) {\n    new Assertion(val, msg).to.be.instanceOf(type);\n  };\n\n  /**\n   * ### .notInstanceOf(object, constructor, [message])\n   *\n   * Asserts `value` is not an instance of `constructor`.\n   *\n   *     var Tea = function (name) { this.name = name; }\n   *       , chai = new String('chai');\n   *\n   *     assert.notInstanceOf(chai, Tea, 'chai is not an instance of tea');\n   *\n   * @name notInstanceOf\n   * @param {Object} object\n   * @param {Constructor} constructor\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.notInstanceOf = function (val, type, msg) {\n    new Assertion(val, msg).to.not.be.instanceOf(type);\n  };\n\n  /**\n   * ### .include(haystack, needle, [message])\n   *\n   * Asserts that `haystack` includes `needle`. Works\n   * for strings and arrays.\n   *\n   *     assert.include('foobar', 'bar', 'foobar contains string \"bar\"');\n   *     assert.include([ 1, 2, 3 ], 3, 'array contains value');\n   *\n   * @name include\n   * @param {Array|String} haystack\n   * @param {Mixed} needle\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.include = function (exp, inc, msg) {\n    new Assertion(exp, msg, assert.include).include(inc);\n  };\n\n  /**\n   * ### .notInclude(haystack, needle, [message])\n   *\n   * Asserts that `haystack` does not include `needle`. Works\n   * for strings and arrays.\n   *\n   *     assert.notInclude('foobar', 'baz', 'string not include substring');\n   *     assert.notInclude([ 1, 2, 3 ], 4, 'array not include contain value');\n   *\n   * @name notInclude\n   * @param {Array|String} haystack\n   * @param {Mixed} needle\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.notInclude = function (exp, inc, msg) {\n    new Assertion(exp, msg, assert.notInclude).not.include(inc);\n  };\n\n  /**\n   * ### .match(value, regexp, [message])\n   *\n   * Asserts that `value` matches the regular expression `regexp`.\n   *\n   *     assert.match('foobar', /^foo/, 'regexp matches');\n   *\n   * @name match\n   * @param {Mixed} value\n   * @param {RegExp} regexp\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.match = function (exp, re, msg) {\n    new Assertion(exp, msg).to.match(re);\n  };\n\n  /**\n   * ### .notMatch(value, regexp, [message])\n   *\n   * Asserts that `value` does not match the regular expression `regexp`.\n   *\n   *     assert.notMatch('foobar', /^foo/, 'regexp does not match');\n   *\n   * @name notMatch\n   * @param {Mixed} value\n   * @param {RegExp} regexp\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.notMatch = function (exp, re, msg) {\n    new Assertion(exp, msg).to.not.match(re);\n  };\n\n  /**\n   * ### .property(object, property, [message])\n   *\n   * Asserts that `object` has a property named by `property`.\n   *\n   *     assert.property({ tea: { green: 'matcha' }}, 'tea');\n   *\n   * @name property\n   * @param {Object} object\n   * @param {String} property\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.property = function (obj, prop, msg) {\n    new Assertion(obj, msg).to.have.property(prop);\n  };\n\n  /**\n   * ### .notProperty(object, property, [message])\n   *\n   * Asserts that `object` does _not_ have a property named by `property`.\n   *\n   *     assert.notProperty({ tea: { green: 'matcha' }}, 'coffee');\n   *\n   * @name notProperty\n   * @param {Object} object\n   * @param {String} property\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.notProperty = function (obj, prop, msg) {\n    new Assertion(obj, msg).to.not.have.property(prop);\n  };\n\n  /**\n   * ### .deepProperty(object, property, [message])\n   *\n   * Asserts that `object` has a property named by `property`, which can be a\n   * string using dot- and bracket-notation for deep reference.\n   *\n   *     assert.deepProperty({ tea: { green: 'matcha' }}, 'tea.green');\n   *\n   * @name deepProperty\n   * @param {Object} object\n   * @param {String} property\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.deepProperty = function (obj, prop, msg) {\n    new Assertion(obj, msg).to.have.deep.property(prop);\n  };\n\n  /**\n   * ### .notDeepProperty(object, property, [message])\n   *\n   * Asserts that `object` does _not_ have a property named by `property`, which\n   * can be a string using dot- and bracket-notation for deep reference.\n   *\n   *     assert.notDeepProperty({ tea: { green: 'matcha' }}, 'tea.oolong');\n   *\n   * @name notDeepProperty\n   * @param {Object} object\n   * @param {String} property\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.notDeepProperty = function (obj, prop, msg) {\n    new Assertion(obj, msg).to.not.have.deep.property(prop);\n  };\n\n  /**\n   * ### .propertyVal(object, property, value, [message])\n   *\n   * Asserts that `object` has a property named by `property` with value given\n   * by `value`.\n   *\n   *     assert.propertyVal({ tea: 'is good' }, 'tea', 'is good');\n   *\n   * @name propertyVal\n   * @param {Object} object\n   * @param {String} property\n   * @param {Mixed} value\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.propertyVal = function (obj, prop, val, msg) {\n    new Assertion(obj, msg).to.have.property(prop, val);\n  };\n\n  /**\n   * ### .propertyNotVal(object, property, value, [message])\n   *\n   * Asserts that `object` has a property named by `property`, but with a value\n   * different from that given by `value`.\n   *\n   *     assert.propertyNotVal({ tea: 'is good' }, 'tea', 'is bad');\n   *\n   * @name propertyNotVal\n   * @param {Object} object\n   * @param {String} property\n   * @param {Mixed} value\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.propertyNotVal = function (obj, prop, val, msg) {\n    new Assertion(obj, msg).to.not.have.property(prop, val);\n  };\n\n  /**\n   * ### .deepPropertyVal(object, property, value, [message])\n   *\n   * Asserts that `object` has a property named by `property` with value given\n   * by `value`. `property` can use dot- and bracket-notation for deep\n   * reference.\n   *\n   *     assert.deepPropertyVal({ tea: { green: 'matcha' }}, 'tea.green', 'matcha');\n   *\n   * @name deepPropertyVal\n   * @param {Object} object\n   * @param {String} property\n   * @param {Mixed} value\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.deepPropertyVal = function (obj, prop, val, msg) {\n    new Assertion(obj, msg).to.have.deep.property(prop, val);\n  };\n\n  /**\n   * ### .deepPropertyNotVal(object, property, value, [message])\n   *\n   * Asserts that `object` has a property named by `property`, but with a value\n   * different from that given by `value`. `property` can use dot- and\n   * bracket-notation for deep reference.\n   *\n   *     assert.deepPropertyNotVal({ tea: { green: 'matcha' }}, 'tea.green', 'konacha');\n   *\n   * @name deepPropertyNotVal\n   * @param {Object} object\n   * @param {String} property\n   * @param {Mixed} value\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.deepPropertyNotVal = function (obj, prop, val, msg) {\n    new Assertion(obj, msg).to.not.have.deep.property(prop, val);\n  };\n\n  /**\n   * ### .lengthOf(object, length, [message])\n   *\n   * Asserts that `object` has a `length` property with the expected value.\n   *\n   *     assert.lengthOf([1,2,3], 3, 'array has length of 3');\n   *     assert.lengthOf('foobar', 6, 'string has length of 6');\n   *\n   * @name lengthOf\n   * @param {Mixed} object\n   * @param {Number} length\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.lengthOf = function (exp, len, msg) {\n    new Assertion(exp, msg).to.have.length(len);\n  };\n\n  /**\n   * ### .throws(function, [constructor/string/regexp], [string/regexp], [message])\n   *\n   * Asserts that `function` will throw an error that is an instance of\n   * `constructor`, or alternately that it will throw an error with message\n   * matching `regexp`.\n   *\n   *     assert.throws(fn, 'function throws a reference error');\n   *     assert.throws(fn, /function throws a reference error/);\n   *     assert.throws(fn, ReferenceError);\n   *     assert.throws(fn, ReferenceError, 'function throws a reference error');\n   *     assert.throws(fn, ReferenceError, /function throws a reference error/);\n   *\n   * @name throws\n   * @alias throw\n   * @alias Throw\n   * @param {Function} function\n   * @param {ErrorConstructor} constructor\n   * @param {RegExp} regexp\n   * @param {String} message\n   * @see https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Error#Error_types\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.throws = function (fn, errt, errs, msg) {\n    if ('string' === typeof errt || errt instanceof RegExp) {\n      errs = errt;\n      errt = null;\n    }\n\n    var assertErr = new Assertion(fn, msg).to.throw(errt, errs);\n    return flag(assertErr, 'object');\n  };\n\n  /**\n   * ### .doesNotThrow(function, [constructor/regexp], [message])\n   *\n   * Asserts that `function` will _not_ throw an error that is an instance of\n   * `constructor`, or alternately that it will not throw an error with message\n   * matching `regexp`.\n   *\n   *     assert.doesNotThrow(fn, Error, 'function does not throw');\n   *\n   * @name doesNotThrow\n   * @param {Function} function\n   * @param {ErrorConstructor} constructor\n   * @param {RegExp} regexp\n   * @param {String} message\n   * @see https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Error#Error_types\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.doesNotThrow = function (fn, type, msg) {\n    if ('string' === typeof type) {\n      msg = type;\n      type = null;\n    }\n\n    new Assertion(fn, msg).to.not.Throw(type);\n  };\n\n  /**\n   * ### .operator(val1, operator, val2, [message])\n   *\n   * Compares two values using `operator`.\n   *\n   *     assert.operator(1, '<', 2, 'everything is ok');\n   *     assert.operator(1, '>', 2, 'this will fail');\n   *\n   * @name operator\n   * @param {Mixed} val1\n   * @param {String} operator\n   * @param {Mixed} val2\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.operator = function (val, operator, val2, msg) {\n    var ok;\n    switch(operator) {\n      case '==':\n        ok = val == val2;\n        break;\n      case '===':\n        ok = val === val2;\n        break;\n      case '>':\n        ok = val > val2;\n        break;\n      case '>=':\n        ok = val >= val2;\n        break;\n      case '<':\n        ok = val < val2;\n        break;\n      case '<=':\n        ok = val <= val2;\n        break;\n      case '!=':\n        ok = val != val2;\n        break;\n      case '!==':\n        ok = val !== val2;\n        break;\n      default:\n        throw new Error('Invalid operator \"' + operator + '\"');\n    }\n    var test = new Assertion(ok, msg);\n    test.assert(\n        true === flag(test, 'object')\n      , 'expected ' + util.inspect(val) + ' to be ' + operator + ' ' + util.inspect(val2)\n      , 'expected ' + util.inspect(val) + ' to not be ' + operator + ' ' + util.inspect(val2) );\n  };\n\n  /**\n   * ### .closeTo(actual, expected, delta, [message])\n   *\n   * Asserts that the target is equal `expected`, to within a +/- `delta` range.\n   *\n   *     assert.closeTo(1.5, 1, 0.5, 'numbers are close');\n   *\n   * @name closeTo\n   * @param {Number} actual\n   * @param {Number} expected\n   * @param {Number} delta\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.closeTo = function (act, exp, delta, msg) {\n    new Assertion(act, msg).to.be.closeTo(exp, delta);\n  };\n\n  /**\n   * ### .approximately(actual, expected, delta, [message])\n   *\n   * Asserts that the target is equal `expected`, to within a +/- `delta` range.\n   *\n   *     assert.approximately(1.5, 1, 0.5, 'numbers are close');\n   *\n   * @name approximately\n   * @param {Number} actual\n   * @param {Number} expected\n   * @param {Number} delta\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.approximately = function (act, exp, delta, msg) {\n    new Assertion(act, msg).to.be.approximately(exp, delta);\n  };\n\n  /**\n   * ### .sameMembers(set1, set2, [message])\n   *\n   * Asserts that `set1` and `set2` have the same members.\n   * Order is not taken into account.\n   *\n   *     assert.sameMembers([ 1, 2, 3 ], [ 2, 1, 3 ], 'same members');\n   *\n   * @name sameMembers\n   * @param {Array} set1\n   * @param {Array} set2\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.sameMembers = function (set1, set2, msg) {\n    new Assertion(set1, msg).to.have.same.members(set2);\n  }\n\n  /**\n   * ### .sameDeepMembers(set1, set2, [message])\n   *\n   * Asserts that `set1` and `set2` have the same members - using a deep equality checking.\n   * Order is not taken into account.\n   *\n   *     assert.sameDeepMembers([ {b: 3}, {a: 2}, {c: 5} ], [ {c: 5}, {b: 3}, {a: 2} ], 'same deep members');\n   *\n   * @name sameDeepMembers\n   * @param {Array} set1\n   * @param {Array} set2\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.sameDeepMembers = function (set1, set2, msg) {\n    new Assertion(set1, msg).to.have.same.deep.members(set2);\n  }\n\n  /**\n   * ### .includeMembers(superset, subset, [message])\n   *\n   * Asserts that `subset` is included in `superset`.\n   * Order is not taken into account.\n   *\n   *     assert.includeMembers([ 1, 2, 3 ], [ 2, 1 ], 'include members');\n   *\n   * @name includeMembers\n   * @param {Array} superset\n   * @param {Array} subset\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.includeMembers = function (superset, subset, msg) {\n    new Assertion(superset, msg).to.include.members(subset);\n  }\n\n  /**\n   * ### .includeDeepMembers(superset, subset, [message])\n   *\n   * Asserts that `subset` is included in `superset` - using deep equality checking.\n   * Order is not taken into account.\n   * Duplicates are ignored.\n   *\n   *     assert.includeDeepMembers([ {a: 1}, {b: 2}, {c: 3} ], [ {b: 2}, {a: 1}, {b: 2} ], 'include deep members');\n   *\n   * @name includeDeepMembers\n   * @param {Array} superset\n   * @param {Array} subset\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.includeDeepMembers = function (superset, subset, msg) {\n    new Assertion(superset, msg).to.include.deep.members(subset);\n  }\n\n  /**\n   * ### .oneOf(inList, list, [message])\n   *\n   * Asserts that non-object, non-array value `inList` appears in the flat array `list`.\n   *\n   *     assert.oneOf(1, [ 2, 1 ], 'Not found in list');\n   *\n   * @name oneOf\n   * @param {*} inList\n   * @param {Array<*>} list\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.oneOf = function (inList, list, msg) {\n    new Assertion(inList, msg).to.be.oneOf(list);\n  }\n\n   /**\n   * ### .changes(function, object, property)\n   *\n   * Asserts that a function changes the value of a property\n   *\n   *     var obj = { val: 10 };\n   *     var fn = function() { obj.val = 22 };\n   *     assert.changes(fn, obj, 'val');\n   *\n   * @name changes\n   * @param {Function} modifier function\n   * @param {Object} object\n   * @param {String} property name\n   * @param {String} message _optional_\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.changes = function (fn, obj, prop) {\n    new Assertion(fn).to.change(obj, prop);\n  }\n\n   /**\n   * ### .doesNotChange(function, object, property)\n   *\n   * Asserts that a function does not changes the value of a property\n   *\n   *     var obj = { val: 10 };\n   *     var fn = function() { console.log('foo'); };\n   *     assert.doesNotChange(fn, obj, 'val');\n   *\n   * @name doesNotChange\n   * @param {Function} modifier function\n   * @param {Object} object\n   * @param {String} property name\n   * @param {String} message _optional_\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.doesNotChange = function (fn, obj, prop) {\n    new Assertion(fn).to.not.change(obj, prop);\n  }\n\n   /**\n   * ### .increases(function, object, property)\n   *\n   * Asserts that a function increases an object property\n   *\n   *     var obj = { val: 10 };\n   *     var fn = function() { obj.val = 13 };\n   *     assert.increases(fn, obj, 'val');\n   *\n   * @name increases\n   * @param {Function} modifier function\n   * @param {Object} object\n   * @param {String} property name\n   * @param {String} message _optional_\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.increases = function (fn, obj, prop) {\n    new Assertion(fn).to.increase(obj, prop);\n  }\n\n   /**\n   * ### .doesNotIncrease(function, object, property)\n   *\n   * Asserts that a function does not increase object property\n   *\n   *     var obj = { val: 10 };\n   *     var fn = function() { obj.val = 8 };\n   *     assert.doesNotIncrease(fn, obj, 'val');\n   *\n   * @name doesNotIncrease\n   * @param {Function} modifier function\n   * @param {Object} object\n   * @param {String} property name\n   * @param {String} message _optional_\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.doesNotIncrease = function (fn, obj, prop) {\n    new Assertion(fn).to.not.increase(obj, prop);\n  }\n\n   /**\n   * ### .decreases(function, object, property)\n   *\n   * Asserts that a function decreases an object property\n   *\n   *     var obj = { val: 10 };\n   *     var fn = function() { obj.val = 5 };\n   *     assert.decreases(fn, obj, 'val');\n   *\n   * @name decreases\n   * @param {Function} modifier function\n   * @param {Object} object\n   * @param {String} property name\n   * @param {String} message _optional_\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.decreases = function (fn, obj, prop) {\n    new Assertion(fn).to.decrease(obj, prop);\n  }\n\n   /**\n   * ### .doesNotDecrease(function, object, property)\n   *\n   * Asserts that a function does not decreases an object property\n   *\n   *     var obj = { val: 10 };\n   *     var fn = function() { obj.val = 15 };\n   *     assert.doesNotDecrease(fn, obj, 'val');\n   *\n   * @name doesNotDecrease\n   * @param {Function} modifier function\n   * @param {Object} object\n   * @param {String} property name\n   * @param {String} message _optional_\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.doesNotDecrease = function (fn, obj, prop) {\n    new Assertion(fn).to.not.decrease(obj, prop);\n  }\n\n  /*!\n   * ### .ifError(object)\n   *\n   * Asserts if value is not a false value, and throws if it is a true value.\n   * This is added to allow for chai to be a drop-in replacement for Node's\n   * assert class.\n   *\n   *     var err = new Error('I am a custom error');\n   *     assert.ifError(err); // Rethrows err!\n   *\n   * @name ifError\n   * @param {Object} object\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.ifError = function (val) {\n    if (val) {\n      throw(val);\n    }\n  };\n\n  /**\n   * ### .isExtensible(object)\n   *\n   * Asserts that `object` is extensible (can have new properties added to it).\n   *\n   *     assert.isExtensible({});\n   *\n   * @name isExtensible\n   * @alias extensible\n   * @param {Object} object\n   * @param {String} message _optional_\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.isExtensible = function (obj, msg) {\n    new Assertion(obj, msg).to.be.extensible;\n  };\n\n  /**\n   * ### .isNotExtensible(object)\n   *\n   * Asserts that `object` is _not_ extensible.\n   *\n   *     var nonExtensibleObject = Object.preventExtensions({});\n   *     var sealedObject = Object.seal({});\n   *     var frozenObject = Object.freese({});\n   *\n   *     assert.isNotExtensible(nonExtensibleObject);\n   *     assert.isNotExtensible(sealedObject);\n   *     assert.isNotExtensible(frozenObject);\n   *\n   * @name isNotExtensible\n   * @alias notExtensible\n   * @param {Object} object\n   * @param {String} message _optional_\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.isNotExtensible = function (obj, msg) {\n    new Assertion(obj, msg).to.not.be.extensible;\n  };\n\n  /**\n   * ### .isSealed(object)\n   *\n   * Asserts that `object` is sealed (cannot have new properties added to it\n   * and its existing properties cannot be removed).\n   *\n   *     var sealedObject = Object.seal({});\n   *     var frozenObject = Object.seal({});\n   *\n   *     assert.isSealed(sealedObject);\n   *     assert.isSealed(frozenObject);\n   *\n   * @name isSealed\n   * @alias sealed\n   * @param {Object} object\n   * @param {String} message _optional_\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.isSealed = function (obj, msg) {\n    new Assertion(obj, msg).to.be.sealed;\n  };\n\n  /**\n   * ### .isNotSealed(object)\n   *\n   * Asserts that `object` is _not_ sealed.\n   *\n   *     assert.isNotSealed({});\n   *\n   * @name isNotSealed\n   * @alias notSealed\n   * @param {Object} object\n   * @param {String} message _optional_\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.isNotSealed = function (obj, msg) {\n    new Assertion(obj, msg).to.not.be.sealed;\n  };\n\n  /**\n   * ### .isFrozen(object)\n   *\n   * Asserts that `object` is frozen (cannot have new properties added to it\n   * and its existing properties cannot be modified).\n   *\n   *     var frozenObject = Object.freeze({});\n   *     assert.frozen(frozenObject);\n   *\n   * @name isFrozen\n   * @alias frozen\n   * @param {Object} object\n   * @param {String} message _optional_\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.isFrozen = function (obj, msg) {\n    new Assertion(obj, msg).to.be.frozen;\n  };\n\n  /**\n   * ### .isNotFrozen(object)\n   *\n   * Asserts that `object` is _not_ frozen.\n   *\n   *     assert.isNotFrozen({});\n   *\n   * @name isNotFrozen\n   * @alias notFrozen\n   * @param {Object} object\n   * @param {String} message _optional_\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.isNotFrozen = function (obj, msg) {\n    new Assertion(obj, msg).to.not.be.frozen;\n  };\n\n  /*!\n   * Aliases.\n   */\n\n  (function alias(name, as){\n    assert[as] = assert[name];\n    return alias;\n  })\n  ('isOk', 'ok')\n  ('isNotOk', 'notOk')\n  ('throws', 'throw')\n  ('throws', 'Throw')\n  ('isExtensible', 'extensible')\n  ('isNotExtensible', 'notExtensible')\n  ('isSealed', 'sealed')\n  ('isNotSealed', 'notSealed')\n  ('isFrozen', 'frozen')\n  ('isNotFrozen', 'notFrozen');\n};\n\n},{}],7:[function(require,module,exports){\n/*!\n * chai\n * Copyright(c) 2011-2014 Jake Luer <jake@alogicalparadox.com>\n * MIT Licensed\n */\n\nmodule.exports = function (chai, util) {\n  chai.expect = function (val, message) {\n    return new chai.Assertion(val, message);\n  };\n\n  /**\n   * ### .fail(actual, expected, [message], [operator])\n   *\n   * Throw a failure.\n   *\n   * @name fail\n   * @param {Mixed} actual\n   * @param {Mixed} expected\n   * @param {String} message\n   * @param {String} operator\n   * @namespace Expect\n   * @api public\n   */\n\n  chai.expect.fail = function (actual, expected, message, operator) {\n    message = message || 'expect.fail()';\n    throw new chai.AssertionError(message, {\n        actual: actual\n      , expected: expected\n      , operator: operator\n    }, chai.expect.fail);\n  };\n};\n\n},{}],8:[function(require,module,exports){\n/*!\n * chai\n * Copyright(c) 2011-2014 Jake Luer <jake@alogicalparadox.com>\n * MIT Licensed\n */\n\nmodule.exports = function (chai, util) {\n  var Assertion = chai.Assertion;\n\n  function loadShould () {\n    // explicitly define this method as function as to have it's name to include as `ssfi`\n    function shouldGetter() {\n      if (this instanceof String || this instanceof Number || this instanceof Boolean ) {\n        return new Assertion(this.valueOf(), null, shouldGetter);\n      }\n      return new Assertion(this, null, shouldGetter);\n    }\n    function shouldSetter(value) {\n      // See https://github.com/chaijs/chai/issues/86: this makes\n      // `whatever.should = someValue` actually set `someValue`, which is\n      // especially useful for `global.should = require('chai').should()`.\n      //\n      // Note that we have to use [[DefineProperty]] instead of [[Put]]\n      // since otherwise we would trigger this very setter!\n      Object.defineProperty(this, 'should', {\n        value: value,\n        enumerable: true,\n        configurable: true,\n        writable: true\n      });\n    }\n    // modify Object.prototype to have `should`\n    Object.defineProperty(Object.prototype, 'should', {\n      set: shouldSetter\n      , get: shouldGetter\n      , configurable: true\n    });\n\n    var should = {};\n\n    /**\n     * ### .fail(actual, expected, [message], [operator])\n     *\n     * Throw a failure.\n     *\n     * @name fail\n     * @param {Mixed} actual\n     * @param {Mixed} expected\n     * @param {String} message\n     * @param {String} operator\n     * @namespace Should\n     * @api public\n     */\n\n    should.fail = function (actual, expected, message, operator) {\n      message = message || 'should.fail()';\n      throw new chai.AssertionError(message, {\n          actual: actual\n        , expected: expected\n        , operator: operator\n      }, should.fail);\n    };\n\n    /**\n     * ### .equal(actual, expected, [message])\n     *\n     * Asserts non-strict equality (`==`) of `actual` and `expected`.\n     *\n     *     should.equal(3, '3', '== coerces values to strings');\n     *\n     * @name equal\n     * @param {Mixed} actual\n     * @param {Mixed} expected\n     * @param {String} message\n     * @namespace Should\n     * @api public\n     */\n\n    should.equal = function (val1, val2, msg) {\n      new Assertion(val1, msg).to.equal(val2);\n    };\n\n    /**\n     * ### .throw(function, [constructor/string/regexp], [string/regexp], [message])\n     *\n     * Asserts that `function` will throw an error that is an instance of\n     * `constructor`, or alternately that it will throw an error with message\n     * matching `regexp`.\n     *\n     *     should.throw(fn, 'function throws a reference error');\n     *     should.throw(fn, /function throws a reference error/);\n     *     should.throw(fn, ReferenceError);\n     *     should.throw(fn, ReferenceError, 'function throws a reference error');\n     *     should.throw(fn, ReferenceError, /function throws a reference error/);\n     *\n     * @name throw\n     * @alias Throw\n     * @param {Function} function\n     * @param {ErrorConstructor} constructor\n     * @param {RegExp} regexp\n     * @param {String} message\n     * @see https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Error#Error_types\n     * @namespace Should\n     * @api public\n     */\n\n    should.Throw = function (fn, errt, errs, msg) {\n      new Assertion(fn, msg).to.Throw(errt, errs);\n    };\n\n    /**\n     * ### .exist\n     *\n     * Asserts that the target is neither `null` nor `undefined`.\n     *\n     *     var foo = 'hi';\n     *\n     *     should.exist(foo, 'foo exists');\n     *\n     * @name exist\n     * @namespace Should\n     * @api public\n     */\n\n    should.exist = function (val, msg) {\n      new Assertion(val, msg).to.exist;\n    }\n\n    // negation\n    should.not = {}\n\n    /**\n     * ### .not.equal(actual, expected, [message])\n     *\n     * Asserts non-strict inequality (`!=`) of `actual` and `expected`.\n     *\n     *     should.not.equal(3, 4, 'these numbers are not equal');\n     *\n     * @name not.equal\n     * @param {Mixed} actual\n     * @param {Mixed} expected\n     * @param {String} message\n     * @namespace Should\n     * @api public\n     */\n\n    should.not.equal = function (val1, val2, msg) {\n      new Assertion(val1, msg).to.not.equal(val2);\n    };\n\n    /**\n     * ### .throw(function, [constructor/regexp], [message])\n     *\n     * Asserts that `function` will _not_ throw an error that is an instance of\n     * `constructor`, or alternately that it will not throw an error with message\n     * matching `regexp`.\n     *\n     *     should.not.throw(fn, Error, 'function does not throw');\n     *\n     * @name not.throw\n     * @alias not.Throw\n     * @param {Function} function\n     * @param {ErrorConstructor} constructor\n     * @param {RegExp} regexp\n     * @param {String} message\n     * @see https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Error#Error_types\n     * @namespace Should\n     * @api public\n     */\n\n    should.not.Throw = function (fn, errt, errs, msg) {\n      new Assertion(fn, msg).to.not.Throw(errt, errs);\n    };\n\n    /**\n     * ### .not.exist\n     *\n     * Asserts that the target is neither `null` nor `undefined`.\n     *\n     *     var bar = null;\n     *\n     *     should.not.exist(bar, 'bar does not exist');\n     *\n     * @name not.exist\n     * @namespace Should\n     * @api public\n     */\n\n    should.not.exist = function (val, msg) {\n      new Assertion(val, msg).to.not.exist;\n    }\n\n    should['throw'] = should['Throw'];\n    should.not['throw'] = should.not['Throw'];\n\n    return should;\n  };\n\n  chai.should = loadShould;\n  chai.Should = loadShould;\n};\n\n},{}],9:[function(require,module,exports){\n/*!\n * Chai - addChainingMethod utility\n * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com>\n * MIT Licensed\n */\n\n/*!\n * Module dependencies\n */\n\nvar transferFlags = require('./transferFlags');\nvar flag = require('./flag');\nvar config = require('../config');\n\n/*!\n * Module variables\n */\n\n// Check whether `__proto__` is supported\nvar hasProtoSupport = '__proto__' in Object;\n\n// Without `__proto__` support, this module will need to add properties to a function.\n// However, some Function.prototype methods cannot be overwritten,\n// and there seems no easy cross-platform way to detect them (@see chaijs/chai/issues/69).\nvar excludeNames = /^(?:length|name|arguments|caller)$/;\n\n// Cache `Function` properties\nvar call  = Function.prototype.call,\n    apply = Function.prototype.apply;\n\n/**\n * ### addChainableMethod (ctx, name, method, chainingBehavior)\n *\n * Adds a method to an object, such that the method can also be chained.\n *\n *     utils.addChainableMethod(chai.Assertion.prototype, 'foo', function (str) {\n *       var obj = utils.flag(this, 'object');\n *       new chai.Assertion(obj).to.be.equal(str);\n *     });\n *\n * Can also be accessed directly from `chai.Assertion`.\n *\n *     chai.Assertion.addChainableMethod('foo', fn, chainingBehavior);\n *\n * The result can then be used as both a method assertion, executing both `method` and\n * `chainingBehavior`, or as a language chain, which only executes `chainingBehavior`.\n *\n *     expect(fooStr).to.be.foo('bar');\n *     expect(fooStr).to.be.foo.equal('foo');\n *\n * @param {Object} ctx object to which the method is added\n * @param {String} name of method to add\n * @param {Function} method function to be used for `name`, when called\n * @param {Function} chainingBehavior function to be called every time the property is accessed\n * @namespace Utils\n * @name addChainableMethod\n * @api public\n */\n\nmodule.exports = function (ctx, name, method, chainingBehavior) {\n  if (typeof chainingBehavior !== 'function') {\n    chainingBehavior = function () { };\n  }\n\n  var chainableBehavior = {\n      method: method\n    , chainingBehavior: chainingBehavior\n  };\n\n  // save the methods so we can overwrite them later, if we need to.\n  if (!ctx.__methods) {\n    ctx.__methods = {};\n  }\n  ctx.__methods[name] = chainableBehavior;\n\n  Object.defineProperty(ctx, name,\n    { get: function () {\n        chainableBehavior.chainingBehavior.call(this);\n\n        var assert = function assert() {\n          var old_ssfi = flag(this, 'ssfi');\n          if (old_ssfi && config.includeStack === false)\n            flag(this, 'ssfi', assert);\n          var result = chainableBehavior.method.apply(this, arguments);\n          return result === undefined ? this : result;\n        };\n\n        // Use `__proto__` if available\n        if (hasProtoSupport) {\n          // Inherit all properties from the object by replacing the `Function` prototype\n          var prototype = assert.__proto__ = Object.create(this);\n          // Restore the `call` and `apply` methods from `Function`\n          prototype.call = call;\n          prototype.apply = apply;\n        }\n        // Otherwise, redefine all properties (slow!)\n        else {\n          var asserterNames = Object.getOwnPropertyNames(ctx);\n          asserterNames.forEach(function (asserterName) {\n            if (!excludeNames.test(asserterName)) {\n              var pd = Object.getOwnPropertyDescriptor(ctx, asserterName);\n              Object.defineProperty(assert, asserterName, pd);\n            }\n          });\n        }\n\n        transferFlags(this, assert);\n        return assert;\n      }\n    , configurable: true\n  });\n};\n\n},{\"../config\":4,\"./flag\":13,\"./transferFlags\":29}],10:[function(require,module,exports){\n/*!\n * Chai - addMethod utility\n * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com>\n * MIT Licensed\n */\n\nvar config = require('../config');\n\n/**\n * ### .addMethod (ctx, name, method)\n *\n * Adds a method to the prototype of an object.\n *\n *     utils.addMethod(chai.Assertion.prototype, 'foo', function (str) {\n *       var obj = utils.flag(this, 'object');\n *       new chai.Assertion(obj).to.be.equal(str);\n *     });\n *\n * Can also be accessed directly from `chai.Assertion`.\n *\n *     chai.Assertion.addMethod('foo', fn);\n *\n * Then can be used as any other assertion.\n *\n *     expect(fooStr).to.be.foo('bar');\n *\n * @param {Object} ctx object to which the method is added\n * @param {String} name of method to add\n * @param {Function} method function to be used for name\n * @namespace Utils\n * @name addMethod\n * @api public\n */\nvar flag = require('./flag');\n\nmodule.exports = function (ctx, name, method) {\n  ctx[name] = function () {\n    var old_ssfi = flag(this, 'ssfi');\n    if (old_ssfi && config.includeStack === false)\n      flag(this, 'ssfi', ctx[name]);\n    var result = method.apply(this, arguments);\n    return result === undefined ? this : result;\n  };\n};\n\n},{\"../config\":4,\"./flag\":13}],11:[function(require,module,exports){\n/*!\n * Chai - addProperty utility\n * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com>\n * MIT Licensed\n */\n\nvar config = require('../config');\nvar flag = require('./flag');\n\n/**\n * ### addProperty (ctx, name, getter)\n *\n * Adds a property to the prototype of an object.\n *\n *     utils.addProperty(chai.Assertion.prototype, 'foo', function () {\n *       var obj = utils.flag(this, 'object');\n *       new chai.Assertion(obj).to.be.instanceof(Foo);\n *     });\n *\n * Can also be accessed directly from `chai.Assertion`.\n *\n *     chai.Assertion.addProperty('foo', fn);\n *\n * Then can be used as any other assertion.\n *\n *     expect(myFoo).to.be.foo;\n *\n * @param {Object} ctx object to which the property is added\n * @param {String} name of property to add\n * @param {Function} getter function to be used for name\n * @namespace Utils\n * @name addProperty\n * @api public\n */\n\nmodule.exports = function (ctx, name, getter) {\n  Object.defineProperty(ctx, name,\n    { get: function addProperty() {\n        var old_ssfi = flag(this, 'ssfi');\n        if (old_ssfi && config.includeStack === false)\n          flag(this, 'ssfi', addProperty);\n\n        var result = getter.call(this);\n        return result === undefined ? this : result;\n      }\n    , configurable: true\n  });\n};\n\n},{\"../config\":4,\"./flag\":13}],12:[function(require,module,exports){\n/*!\n * Chai - expectTypes utility\n * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com>\n * MIT Licensed\n */\n\n/**\n * ### expectTypes(obj, types)\n *\n * Ensures that the object being tested against is of a valid type.\n *\n *     utils.expectTypes(this, ['array', 'object', 'string']);\n *\n * @param {Mixed} obj constructed Assertion\n * @param {Array} type A list of allowed types for this assertion\n * @namespace Utils\n * @name expectTypes\n * @api public\n */\n\nvar AssertionError = require('assertion-error');\nvar flag = require('./flag');\nvar type = require('type-detect');\n\nmodule.exports = function (obj, types) {\n  var obj = flag(obj, 'object');\n  types = types.map(function (t) { return t.toLowerCase(); });\n  types.sort();\n\n  // Transforms ['lorem', 'ipsum'] into 'a lirum, or an ipsum'\n  var str = types.map(function (t, index) {\n    var art = ~[ 'a', 'e', 'i', 'o', 'u' ].indexOf(t.charAt(0)) ? 'an' : 'a';\n    var or = types.length > 1 && index === types.length - 1 ? 'or ' : '';\n    return or + art + ' ' + t;\n  }).join(', ');\n\n  if (!types.some(function (expected) { return type(obj) === expected; })) {\n    throw new AssertionError(\n      'object tested must be ' + str + ', but ' + type(obj) + ' given'\n    );\n  }\n};\n\n},{\"./flag\":13,\"assertion-error\":30,\"type-detect\":35}],13:[function(require,module,exports){\n/*!\n * Chai - flag utility\n * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com>\n * MIT Licensed\n */\n\n/**\n * ### flag(object, key, [value])\n *\n * Get or set a flag value on an object. If a\n * value is provided it will be set, else it will\n * return the currently set value or `undefined` if\n * the value is not set.\n *\n *     utils.flag(this, 'foo', 'bar'); // setter\n *     utils.flag(this, 'foo'); // getter, returns `bar`\n *\n * @param {Object} object constructed Assertion\n * @param {String} key\n * @param {Mixed} value (optional)\n * @namespace Utils\n * @name flag\n * @api private\n */\n\nmodule.exports = function (obj, key, value) {\n  var flags = obj.__flags || (obj.__flags = Object.create(null));\n  if (arguments.length === 3) {\n    flags[key] = value;\n  } else {\n    return flags[key];\n  }\n};\n\n},{}],14:[function(require,module,exports){\n/*!\n * Chai - getActual utility\n * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com>\n * MIT Licensed\n */\n\n/**\n * # getActual(object, [actual])\n *\n * Returns the `actual` value for an Assertion\n *\n * @param {Object} object (constructed Assertion)\n * @param {Arguments} chai.Assertion.prototype.assert arguments\n * @namespace Utils\n * @name getActual\n */\n\nmodule.exports = function (obj, args) {\n  return args.length > 4 ? args[4] : obj._obj;\n};\n\n},{}],15:[function(require,module,exports){\n/*!\n * Chai - getEnumerableProperties utility\n * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com>\n * MIT Licensed\n */\n\n/**\n * ### .getEnumerableProperties(object)\n *\n * This allows the retrieval of enumerable property names of an object,\n * inherited or not.\n *\n * @param {Object} object\n * @returns {Array}\n * @namespace Utils\n * @name getEnumerableProperties\n * @api public\n */\n\nmodule.exports = function getEnumerableProperties(object) {\n  var result = [];\n  for (var name in object) {\n    result.push(name);\n  }\n  return result;\n};\n\n},{}],16:[function(require,module,exports){\n/*!\n * Chai - message composition utility\n * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com>\n * MIT Licensed\n */\n\n/*!\n * Module dependancies\n */\n\nvar flag = require('./flag')\n  , getActual = require('./getActual')\n  , inspect = require('./inspect')\n  , objDisplay = require('./objDisplay');\n\n/**\n * ### .getMessage(object, message, negateMessage)\n *\n * Construct the error message based on flags\n * and template tags. Template tags will return\n * a stringified inspection of the object referenced.\n *\n * Message template tags:\n * - `#{this}` current asserted object\n * - `#{act}` actual value\n * - `#{exp}` expected value\n *\n * @param {Object} object (constructed Assertion)\n * @param {Arguments} chai.Assertion.prototype.assert arguments\n * @namespace Utils\n * @name getMessage\n * @api public\n */\n\nmodule.exports = function (obj, args) {\n  var negate = flag(obj, 'negate')\n    , val = flag(obj, 'object')\n    , expected = args[3]\n    , actual = getActual(obj, args)\n    , msg = negate ? args[2] : args[1]\n    , flagMsg = flag(obj, 'message');\n\n  if(typeof msg === \"function\") msg = msg();\n  msg = msg || '';\n  msg = msg\n    .replace(/#\\{this\\}/g, function () { return objDisplay(val); })\n    .replace(/#\\{act\\}/g, function () { return objDisplay(actual); })\n    .replace(/#\\{exp\\}/g, function () { return objDisplay(expected); });\n\n  return flagMsg ? flagMsg + ': ' + msg : msg;\n};\n\n},{\"./flag\":13,\"./getActual\":14,\"./inspect\":23,\"./objDisplay\":24}],17:[function(require,module,exports){\n/*!\n * Chai - getName utility\n * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com>\n * MIT Licensed\n */\n\n/**\n * # getName(func)\n *\n * Gets the name of a function, in a cross-browser way.\n *\n * @param {Function} a function (usually a constructor)\n * @namespace Utils\n * @name getName\n */\n\nmodule.exports = function (func) {\n  if (func.name) return func.name;\n\n  var match = /^\\s?function ([^(]*)\\(/.exec(func);\n  return match && match[1] ? match[1] : \"\";\n};\n\n},{}],18:[function(require,module,exports){\n/*!\n * Chai - getPathInfo utility\n * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com>\n * MIT Licensed\n */\n\nvar hasProperty = require('./hasProperty');\n\n/**\n * ### .getPathInfo(path, object)\n *\n * This allows the retrieval of property info in an\n * object given a string path.\n *\n * The path info consists of an object with the\n * following properties:\n *\n * * parent - The parent object of the property referenced by `path`\n * * name - The name of the final property, a number if it was an array indexer\n * * value - The value of the property, if it exists, otherwise `undefined`\n * * exists - Whether the property exists or not\n *\n * @param {String} path\n * @param {Object} object\n * @returns {Object} info\n * @namespace Utils\n * @name getPathInfo\n * @api public\n */\n\nmodule.exports = function getPathInfo(path, obj) {\n  var parsed = parsePath(path),\n      last = parsed[parsed.length - 1];\n\n  var info = {\n    parent: parsed.length > 1 ? _getPathValue(parsed, obj, parsed.length - 1) : obj,\n    name: last.p || last.i,\n    value: _getPathValue(parsed, obj)\n  };\n  info.exists = hasProperty(info.name, info.parent);\n\n  return info;\n};\n\n\n/*!\n * ## parsePath(path)\n *\n * Helper function used to parse string object\n * paths. Use in conjunction with `_getPathValue`.\n *\n *      var parsed = parsePath('myobject.property.subprop');\n *\n * ### Paths:\n *\n * * Can be as near infinitely deep and nested\n * * Arrays are also valid using the formal `myobject.document[3].property`.\n * * Literal dots and brackets (not delimiter) must be backslash-escaped.\n *\n * @param {String} path\n * @returns {Object} parsed\n * @api private\n */\n\nfunction parsePath (path) {\n  var str = path.replace(/([^\\\\])\\[/g, '$1.[')\n    , parts = str.match(/(\\\\\\.|[^.]+?)+/g);\n  return parts.map(function (value) {\n    var re = /^\\[(\\d+)\\]$/\n      , mArr = re.exec(value);\n    if (mArr) return { i: parseFloat(mArr[1]) };\n    else return { p: value.replace(/\\\\([.\\[\\]])/g, '$1') };\n  });\n}\n\n\n/*!\n * ## _getPathValue(parsed, obj)\n *\n * Helper companion function for `.parsePath` that returns\n * the value located at the parsed address.\n *\n *      var value = getPathValue(parsed, obj);\n *\n * @param {Object} parsed definition from `parsePath`.\n * @param {Object} object to search against\n * @param {Number} object to search against\n * @returns {Object|Undefined} value\n * @api private\n */\n\nfunction _getPathValue (parsed, obj, index) {\n  var tmp = obj\n    , res;\n\n  index = (index === undefined ? parsed.length : index);\n\n  for (var i = 0, l = index; i < l; i++) {\n    var part = parsed[i];\n    if (tmp) {\n      if ('undefined' !== typeof part.p)\n        tmp = tmp[part.p];\n      else if ('undefined' !== typeof part.i)\n        tmp = tmp[part.i];\n      if (i == (l - 1)) res = tmp;\n    } else {\n      res = undefined;\n    }\n  }\n  return res;\n}\n\n},{\"./hasProperty\":21}],19:[function(require,module,exports){\n/*!\n * Chai - getPathValue utility\n * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com>\n * @see https://github.com/logicalparadox/filtr\n * MIT Licensed\n */\n\nvar getPathInfo = require('./getPathInfo');\n\n/**\n * ### .getPathValue(path, object)\n *\n * This allows the retrieval of values in an\n * object given a string path.\n *\n *     var obj = {\n *         prop1: {\n *             arr: ['a', 'b', 'c']\n *           , str: 'Hello'\n *         }\n *       , prop2: {\n *             arr: [ { nested: 'Universe' } ]\n *           , str: 'Hello again!'\n *         }\n *     }\n *\n * The following would be the results.\n *\n *     getPathValue('prop1.str', obj); // Hello\n *     getPathValue('prop1.att[2]', obj); // b\n *     getPathValue('prop2.arr[0].nested', obj); // Universe\n *\n * @param {String} path\n * @param {Object} object\n * @returns {Object} value or `undefined`\n * @namespace Utils\n * @name getPathValue\n * @api public\n */\nmodule.exports = function(path, obj) {\n  var info = getPathInfo(path, obj);\n  return info.value;\n};\n\n},{\"./getPathInfo\":18}],20:[function(require,module,exports){\n/*!\n * Chai - getProperties utility\n * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com>\n * MIT Licensed\n */\n\n/**\n * ### .getProperties(object)\n *\n * This allows the retrieval of property names of an object, enumerable or not,\n * inherited or not.\n *\n * @param {Object} object\n * @returns {Array}\n * @namespace Utils\n * @name getProperties\n * @api public\n */\n\nmodule.exports = function getProperties(object) {\n  var result = Object.getOwnPropertyNames(object);\n\n  function addProperty(property) {\n    if (result.indexOf(property) === -1) {\n      result.push(property);\n    }\n  }\n\n  var proto = Object.getPrototypeOf(object);\n  while (proto !== null) {\n    Object.getOwnPropertyNames(proto).forEach(addProperty);\n    proto = Object.getPrototypeOf(proto);\n  }\n\n  return result;\n};\n\n},{}],21:[function(require,module,exports){\n/*!\n * Chai - hasProperty utility\n * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com>\n * MIT Licensed\n */\n\nvar type = require('type-detect');\n\n/**\n * ### .hasProperty(object, name)\n *\n * This allows checking whether an object has\n * named property or numeric array index.\n *\n * Basically does the same thing as the `in`\n * operator but works properly with natives\n * and null/undefined values.\n *\n *     var obj = {\n *         arr: ['a', 'b', 'c']\n *       , str: 'Hello'\n *     }\n *\n * The following would be the results.\n *\n *     hasProperty('str', obj);  // true\n *     hasProperty('constructor', obj);  // true\n *     hasProperty('bar', obj);  // false\n *\n *     hasProperty('length', obj.str); // true\n *     hasProperty(1, obj.str);  // true\n *     hasProperty(5, obj.str);  // false\n *\n *     hasProperty('length', obj.arr);  // true\n *     hasProperty(2, obj.arr);  // true\n *     hasProperty(3, obj.arr);  // false\n *\n * @param {Objuect} object\n * @param {String|Number} name\n * @returns {Boolean} whether it exists\n * @namespace Utils\n * @name getPathInfo\n * @api public\n */\n\nvar literals = {\n    'number': Number\n  , 'string': String\n};\n\nmodule.exports = function hasProperty(name, obj) {\n  var ot = type(obj);\n\n  // Bad Object, obviously no props at all\n  if(ot === 'null' || ot === 'undefined')\n    return false;\n\n  // The `in` operator does not work with certain literals\n  // box these before the check\n  if(literals[ot] && typeof obj !== 'object')\n    obj = new literals[ot](obj);\n\n  return name in obj;\n};\n\n},{\"type-detect\":35}],22:[function(require,module,exports){\n/*!\n * chai\n * Copyright(c) 2011 Jake Luer <jake@alogicalparadox.com>\n * MIT Licensed\n */\n\n/*!\n * Main exports\n */\n\nvar exports = module.exports = {};\n\n/*!\n * test utility\n */\n\nexports.test = require('./test');\n\n/*!\n * type utility\n */\n\nexports.type = require('type-detect');\n\n/*!\n * expectTypes utility\n */\nexports.expectTypes = require('./expectTypes');\n\n/*!\n * message utility\n */\n\nexports.getMessage = require('./getMessage');\n\n/*!\n * actual utility\n */\n\nexports.getActual = require('./getActual');\n\n/*!\n * Inspect util\n */\n\nexports.inspect = require('./inspect');\n\n/*!\n * Object Display util\n */\n\nexports.objDisplay = require('./objDisplay');\n\n/*!\n * Flag utility\n */\n\nexports.flag = require('./flag');\n\n/*!\n * Flag transferring utility\n */\n\nexports.transferFlags = require('./transferFlags');\n\n/*!\n * Deep equal utility\n */\n\nexports.eql = require('deep-eql');\n\n/*!\n * Deep path value\n */\n\nexports.getPathValue = require('./getPathValue');\n\n/*!\n * Deep path info\n */\n\nexports.getPathInfo = require('./getPathInfo');\n\n/*!\n * Check if a property exists\n */\n\nexports.hasProperty = require('./hasProperty');\n\n/*!\n * Function name\n */\n\nexports.getName = require('./getName');\n\n/*!\n * add Property\n */\n\nexports.addProperty = require('./addProperty');\n\n/*!\n * add Method\n */\n\nexports.addMethod = require('./addMethod');\n\n/*!\n * overwrite Property\n */\n\nexports.overwriteProperty = require('./overwriteProperty');\n\n/*!\n * overwrite Method\n */\n\nexports.overwriteMethod = require('./overwriteMethod');\n\n/*!\n * Add a chainable method\n */\n\nexports.addChainableMethod = require('./addChainableMethod');\n\n/*!\n * Overwrite chainable method\n */\n\nexports.overwriteChainableMethod = require('./overwriteChainableMethod');\n\n},{\"./addChainableMethod\":9,\"./addMethod\":10,\"./addProperty\":11,\"./expectTypes\":12,\"./flag\":13,\"./getActual\":14,\"./getMessage\":16,\"./getName\":17,\"./getPathInfo\":18,\"./getPathValue\":19,\"./hasProperty\":21,\"./inspect\":23,\"./objDisplay\":24,\"./overwriteChainableMethod\":25,\"./overwriteMethod\":26,\"./overwriteProperty\":27,\"./test\":28,\"./transferFlags\":29,\"deep-eql\":31,\"type-detect\":35}],23:[function(require,module,exports){\n// This is (almost) directly from Node.js utils\n// https://github.com/joyent/node/blob/f8c335d0caf47f16d31413f89aa28eda3878e3aa/lib/util.js\n\nvar getName = require('./getName');\nvar getProperties = require('./getProperties');\nvar getEnumerableProperties = require('./getEnumerableProperties');\n\nmodule.exports = inspect;\n\n/**\n * Echos the value of a value. Trys to print the value out\n * in the best way possible given the different types.\n *\n * @param {Object} obj The object to print out.\n * @param {Boolean} showHidden Flag that shows hidden (not enumerable)\n *    properties of objects.\n * @param {Number} depth Depth in which to descend in object. Default is 2.\n * @param {Boolean} colors Flag to turn on ANSI escape codes to color the\n *    output. Default is false (no coloring).\n * @namespace Utils\n * @name inspect\n */\nfunction inspect(obj, showHidden, depth, colors) {\n  var ctx = {\n    showHidden: showHidden,\n    seen: [],\n    stylize: function (str) { return str; }\n  };\n  return formatValue(ctx, obj, (typeof depth === 'undefined' ? 2 : depth));\n}\n\n// Returns true if object is a DOM element.\nvar isDOMElement = function (object) {\n  if (typeof HTMLElement === 'object') {\n    return object instanceof HTMLElement;\n  } else {\n    return object &&\n      typeof object === 'object' &&\n      object.nodeType === 1 &&\n      typeof object.nodeName === 'string';\n  }\n};\n\nfunction formatValue(ctx, value, recurseTimes) {\n  // Provide a hook for user-specified inspect functions.\n  // Check that value is an object with an inspect function on it\n  if (value && typeof value.inspect === 'function' &&\n      // Filter out the util module, it's inspect function is special\n      value.inspect !== exports.inspect &&\n      // Also filter out any prototype objects using the circular check.\n      !(value.constructor && value.constructor.prototype === value)) {\n    var ret = value.inspect(recurseTimes);\n    if (typeof ret !== 'string') {\n      ret = formatValue(ctx, ret, recurseTimes);\n    }\n    return ret;\n  }\n\n  // Primitive types cannot have properties\n  var primitive = formatPrimitive(ctx, value);\n  if (primitive) {\n    return primitive;\n  }\n\n  // If this is a DOM element, try to get the outer HTML.\n  if (isDOMElement(value)) {\n    if ('outerHTML' in value) {\n      return value.outerHTML;\n      // This value does not have an outerHTML attribute,\n      //   it could still be an XML element\n    } else {\n      // Attempt to serialize it\n      try {\n        if (document.xmlVersion) {\n          var xmlSerializer = new XMLSerializer();\n          return xmlSerializer.serializeToString(value);\n        } else {\n          // Firefox 11- do not support outerHTML\n          //   It does, however, support innerHTML\n          //   Use the following to render the element\n          var ns = \"http://www.w3.org/1999/xhtml\";\n          var container = document.createElementNS(ns, '_');\n\n          container.appendChild(value.cloneNode(false));\n          html = container.innerHTML\n            .replace('><', '>' + value.innerHTML + '<');\n          container.innerHTML = '';\n          return html;\n        }\n      } catch (err) {\n        // This could be a non-native DOM implementation,\n        //   continue with the normal flow:\n        //   printing the element as if it is an object.\n      }\n    }\n  }\n\n  // Look up the keys of the object.\n  var visibleKeys = getEnumerableProperties(value);\n  var keys = ctx.showHidden ? getProperties(value) : visibleKeys;\n\n  // Some type of object without properties can be shortcutted.\n  // In IE, errors have a single `stack` property, or if they are vanilla `Error`,\n  // a `stack` plus `description` property; ignore those for consistency.\n  if (keys.length === 0 || (isError(value) && (\n      (keys.length === 1 && keys[0] === 'stack') ||\n      (keys.length === 2 && keys[0] === 'description' && keys[1] === 'stack')\n     ))) {\n    if (typeof value === 'function') {\n      var name = getName(value);\n      var nameSuffix = name ? ': ' + name : '';\n      return ctx.stylize('[Function' + nameSuffix + ']', 'special');\n    }\n    if (isRegExp(value)) {\n      return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp');\n    }\n    if (isDate(value)) {\n      return ctx.stylize(Date.prototype.toUTCString.call(value), 'date');\n    }\n    if (isError(value)) {\n      return formatError(value);\n    }\n  }\n\n  var base = '', array = false, braces = ['{', '}'];\n\n  // Make Array say that they are Array\n  if (isArray(value)) {\n    array = true;\n    braces = ['[', ']'];\n  }\n\n  // Make functions say that they are functions\n  if (typeof value === 'function') {\n    var name = getName(value);\n    var nameSuffix = name ? ': ' + name : '';\n    base = ' [Function' + nameSuffix + ']';\n  }\n\n  // Make RegExps say that they are RegExps\n  if (isRegExp(value)) {\n    base = ' ' + RegExp.prototype.toString.call(value);\n  }\n\n  // Make dates with properties first say the date\n  if (isDate(value)) {\n    base = ' ' + Date.prototype.toUTCString.call(value);\n  }\n\n  // Make error with message first say the error\n  if (isError(value)) {\n    return formatError(value);\n  }\n\n  if (keys.length === 0 && (!array || value.length == 0)) {\n    return braces[0] + base + braces[1];\n  }\n\n  if (recurseTimes < 0) {\n    if (isRegExp(value)) {\n      return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp');\n    } else {\n      return ctx.stylize('[Object]', 'special');\n    }\n  }\n\n  ctx.seen.push(value);\n\n  var output;\n  if (array) {\n    output = formatArray(ctx, value, recurseTimes, visibleKeys, keys);\n  } else {\n    output = keys.map(function(key) {\n      return formatProperty(ctx, value, recurseTimes, visibleKeys, key, array);\n    });\n  }\n\n  ctx.seen.pop();\n\n  return reduceToSingleString(output, base, braces);\n}\n\n\nfunction formatPrimitive(ctx, value) {\n  switch (typeof value) {\n    case 'undefined':\n      return ctx.stylize('undefined', 'undefined');\n\n    case 'string':\n      var simple = '\\'' + JSON.stringify(value).replace(/^\"|\"$/g, '')\n                                               .replace(/'/g, \"\\\\'\")\n                                               .replace(/\\\\\"/g, '\"') + '\\'';\n      return ctx.stylize(simple, 'string');\n\n    case 'number':\n      if (value === 0 && (1/value) === -Infinity) {\n        return ctx.stylize('-0', 'number');\n      }\n      return ctx.stylize('' + value, 'number');\n\n    case 'boolean':\n      return ctx.stylize('' + value, 'boolean');\n  }\n  // For some reason typeof null is \"object\", so special case here.\n  if (value === null) {\n    return ctx.stylize('null', 'null');\n  }\n}\n\n\nfunction formatError(value) {\n  return '[' + Error.prototype.toString.call(value) + ']';\n}\n\n\nfunction formatArray(ctx, value, recurseTimes, visibleKeys, keys) {\n  var output = [];\n  for (var i = 0, l = value.length; i < l; ++i) {\n    if (Object.prototype.hasOwnProperty.call(value, String(i))) {\n      output.push(formatProperty(ctx, value, recurseTimes, visibleKeys,\n          String(i), true));\n    } else {\n      output.push('');\n    }\n  }\n  keys.forEach(function(key) {\n    if (!key.match(/^\\d+$/)) {\n      output.push(formatProperty(ctx, value, recurseTimes, visibleKeys,\n          key, true));\n    }\n  });\n  return output;\n}\n\n\nfunction formatProperty(ctx, value, recurseTimes, visibleKeys, key, array) {\n  var name, str;\n  if (value.__lookupGetter__) {\n    if (value.__lookupGetter__(key)) {\n      if (value.__lookupSetter__(key)) {\n        str = ctx.stylize('[Getter/Setter]', 'special');\n      } else {\n        str = ctx.stylize('[Getter]', 'special');\n      }\n    } else {\n      if (value.__lookupSetter__(key)) {\n        str = ctx.stylize('[Setter]', 'special');\n      }\n    }\n  }\n  if (visibleKeys.indexOf(key) < 0) {\n    name = '[' + key + ']';\n  }\n  if (!str) {\n    if (ctx.seen.indexOf(value[key]) < 0) {\n      if (recurseTimes === null) {\n        str = formatValue(ctx, value[key], null);\n      } else {\n        str = formatValue(ctx, value[key], recurseTimes - 1);\n      }\n      if (str.indexOf('\\n') > -1) {\n        if (array) {\n          str = str.split('\\n').map(function(line) {\n            return '  ' + line;\n          }).join('\\n').substr(2);\n        } else {\n          str = '\\n' + str.split('\\n').map(function(line) {\n            return '   ' + line;\n          }).join('\\n');\n        }\n      }\n    } else {\n      str = ctx.stylize('[Circular]', 'special');\n    }\n  }\n  if (typeof name === 'undefined') {\n    if (array && key.match(/^\\d+$/)) {\n      return str;\n    }\n    name = JSON.stringify('' + key);\n    if (name.match(/^\"([a-zA-Z_][a-zA-Z_0-9]*)\"$/)) {\n      name = name.substr(1, name.length - 2);\n      name = ctx.stylize(name, 'name');\n    } else {\n      name = name.replace(/'/g, \"\\\\'\")\n                 .replace(/\\\\\"/g, '\"')\n                 .replace(/(^\"|\"$)/g, \"'\");\n      name = ctx.stylize(name, 'string');\n    }\n  }\n\n  return name + ': ' + str;\n}\n\n\nfunction reduceToSingleString(output, base, braces) {\n  var numLinesEst = 0;\n  var length = output.reduce(function(prev, cur) {\n    numLinesEst++;\n    if (cur.indexOf('\\n') >= 0) numLinesEst++;\n    return prev + cur.length + 1;\n  }, 0);\n\n  if (length > 60) {\n    return braces[0] +\n           (base === '' ? '' : base + '\\n ') +\n           ' ' +\n           output.join(',\\n  ') +\n           ' ' +\n           braces[1];\n  }\n\n  return braces[0] + base + ' ' + output.join(', ') + ' ' + braces[1];\n}\n\nfunction isArray(ar) {\n  return Array.isArray(ar) ||\n         (typeof ar === 'object' && objectToString(ar) === '[object Array]');\n}\n\nfunction isRegExp(re) {\n  return typeof re === 'object' && objectToString(re) === '[object RegExp]';\n}\n\nfunction isDate(d) {\n  return typeof d === 'object' && objectToString(d) === '[object Date]';\n}\n\nfunction isError(e) {\n  return typeof e === 'object' && objectToString(e) === '[object Error]';\n}\n\nfunction objectToString(o) {\n  return Object.prototype.toString.call(o);\n}\n\n},{\"./getEnumerableProperties\":15,\"./getName\":17,\"./getProperties\":20}],24:[function(require,module,exports){\n/*!\n * Chai - flag utility\n * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com>\n * MIT Licensed\n */\n\n/*!\n * Module dependancies\n */\n\nvar inspect = require('./inspect');\nvar config = require('../config');\n\n/**\n * ### .objDisplay (object)\n *\n * Determines if an object or an array matches\n * criteria to be inspected in-line for error\n * messages or should be truncated.\n *\n * @param {Mixed} javascript object to inspect\n * @name objDisplay\n * @namespace Utils\n * @api public\n */\n\nmodule.exports = function (obj) {\n  var str = inspect(obj)\n    , type = Object.prototype.toString.call(obj);\n\n  if (config.truncateThreshold && str.length >= config.truncateThreshold) {\n    if (type === '[object Function]') {\n      return !obj.name || obj.name === ''\n        ? '[Function]'\n        : '[Function: ' + obj.name + ']';\n    } else if (type === '[object Array]') {\n      return '[ Array(' + obj.length + ') ]';\n    } else if (type === '[object Object]') {\n      var keys = Object.keys(obj)\n        , kstr = keys.length > 2\n          ? keys.splice(0, 2).join(', ') + ', ...'\n          : keys.join(', ');\n      return '{ Object (' + kstr + ') }';\n    } else {\n      return str;\n    }\n  } else {\n    return str;\n  }\n};\n\n},{\"../config\":4,\"./inspect\":23}],25:[function(require,module,exports){\n/*!\n * Chai - overwriteChainableMethod utility\n * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com>\n * MIT Licensed\n */\n\n/**\n * ### overwriteChainableMethod (ctx, name, method, chainingBehavior)\n *\n * Overwites an already existing chainable method\n * and provides access to the previous function or\n * property.  Must return functions to be used for\n * name.\n *\n *     utils.overwriteChainableMethod(chai.Assertion.prototype, 'length',\n *       function (_super) {\n *       }\n *     , function (_super) {\n *       }\n *     );\n *\n * Can also be accessed directly from `chai.Assertion`.\n *\n *     chai.Assertion.overwriteChainableMethod('foo', fn, fn);\n *\n * Then can be used as any other assertion.\n *\n *     expect(myFoo).to.have.length(3);\n *     expect(myFoo).to.have.length.above(3);\n *\n * @param {Object} ctx object whose method / property is to be overwritten\n * @param {String} name of method / property to overwrite\n * @param {Function} method function that returns a function to be used for name\n * @param {Function} chainingBehavior function that returns a function to be used for property\n * @namespace Utils\n * @name overwriteChainableMethod\n * @api public\n */\n\nmodule.exports = function (ctx, name, method, chainingBehavior) {\n  var chainableBehavior = ctx.__methods[name];\n\n  var _chainingBehavior = chainableBehavior.chainingBehavior;\n  chainableBehavior.chainingBehavior = function () {\n    var result = chainingBehavior(_chainingBehavior).call(this);\n    return result === undefined ? this : result;\n  };\n\n  var _method = chainableBehavior.method;\n  chainableBehavior.method = function () {\n    var result = method(_method).apply(this, arguments);\n    return result === undefined ? this : result;\n  };\n};\n\n},{}],26:[function(require,module,exports){\n/*!\n * Chai - overwriteMethod utility\n * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com>\n * MIT Licensed\n */\n\n/**\n * ### overwriteMethod (ctx, name, fn)\n *\n * Overwites an already existing method and provides\n * access to previous function. Must return function\n * to be used for name.\n *\n *     utils.overwriteMethod(chai.Assertion.prototype, 'equal', function (_super) {\n *       return function (str) {\n *         var obj = utils.flag(this, 'object');\n *         if (obj instanceof Foo) {\n *           new chai.Assertion(obj.value).to.equal(str);\n *         } else {\n *           _super.apply(this, arguments);\n *         }\n *       }\n *     });\n *\n * Can also be accessed directly from `chai.Assertion`.\n *\n *     chai.Assertion.overwriteMethod('foo', fn);\n *\n * Then can be used as any other assertion.\n *\n *     expect(myFoo).to.equal('bar');\n *\n * @param {Object} ctx object whose method is to be overwritten\n * @param {String} name of method to overwrite\n * @param {Function} method function that returns a function to be used for name\n * @namespace Utils\n * @name overwriteMethod\n * @api public\n */\n\nmodule.exports = function (ctx, name, method) {\n  var _method = ctx[name]\n    , _super = function () { return this; };\n\n  if (_method && 'function' === typeof _method)\n    _super = _method;\n\n  ctx[name] = function () {\n    var result = method(_super).apply(this, arguments);\n    return result === undefined ? this : result;\n  }\n};\n\n},{}],27:[function(require,module,exports){\n/*!\n * Chai - overwriteProperty utility\n * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com>\n * MIT Licensed\n */\n\n/**\n * ### overwriteProperty (ctx, name, fn)\n *\n * Overwites an already existing property getter and provides\n * access to previous value. Must return function to use as getter.\n *\n *     utils.overwriteProperty(chai.Assertion.prototype, 'ok', function (_super) {\n *       return function () {\n *         var obj = utils.flag(this, 'object');\n *         if (obj instanceof Foo) {\n *           new chai.Assertion(obj.name).to.equal('bar');\n *         } else {\n *           _super.call(this);\n *         }\n *       }\n *     });\n *\n *\n * Can also be accessed directly from `chai.Assertion`.\n *\n *     chai.Assertion.overwriteProperty('foo', fn);\n *\n * Then can be used as any other assertion.\n *\n *     expect(myFoo).to.be.ok;\n *\n * @param {Object} ctx object whose property is to be overwritten\n * @param {String} name of property to overwrite\n * @param {Function} getter function that returns a getter function to be used for name\n * @namespace Utils\n * @name overwriteProperty\n * @api public\n */\n\nmodule.exports = function (ctx, name, getter) {\n  var _get = Object.getOwnPropertyDescriptor(ctx, name)\n    , _super = function () {};\n\n  if (_get && 'function' === typeof _get.get)\n    _super = _get.get\n\n  Object.defineProperty(ctx, name,\n    { get: function () {\n        var result = getter(_super).call(this);\n        return result === undefined ? this : result;\n      }\n    , configurable: true\n  });\n};\n\n},{}],28:[function(require,module,exports){\n/*!\n * Chai - test utility\n * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com>\n * MIT Licensed\n */\n\n/*!\n * Module dependancies\n */\n\nvar flag = require('./flag');\n\n/**\n * # test(object, expression)\n *\n * Test and object for expression.\n *\n * @param {Object} object (constructed Assertion)\n * @param {Arguments} chai.Assertion.prototype.assert arguments\n * @namespace Utils\n * @name test\n */\n\nmodule.exports = function (obj, args) {\n  var negate = flag(obj, 'negate')\n    , expr = args[0];\n  return negate ? !expr : expr;\n};\n\n},{\"./flag\":13}],29:[function(require,module,exports){\n/*!\n * Chai - transferFlags utility\n * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com>\n * MIT Licensed\n */\n\n/**\n * ### transferFlags(assertion, object, includeAll = true)\n *\n * Transfer all the flags for `assertion` to `object`. If\n * `includeAll` is set to `false`, then the base Chai\n * assertion flags (namely `object`, `ssfi`, and `message`)\n * will not be transferred.\n *\n *\n *     var newAssertion = new Assertion();\n *     utils.transferFlags(assertion, newAssertion);\n *\n *     var anotherAsseriton = new Assertion(myObj);\n *     utils.transferFlags(assertion, anotherAssertion, false);\n *\n * @param {Assertion} assertion the assertion to transfer the flags from\n * @param {Object} object the object to transfer the flags to; usually a new assertion\n * @param {Boolean} includeAll\n * @namespace Utils\n * @name transferFlags\n * @api private\n */\n\nmodule.exports = function (assertion, object, includeAll) {\n  var flags = assertion.__flags || (assertion.__flags = Object.create(null));\n\n  if (!object.__flags) {\n    object.__flags = Object.create(null);\n  }\n\n  includeAll = arguments.length === 3 ? includeAll : true;\n\n  for (var flag in flags) {\n    if (includeAll ||\n        (flag !== 'object' && flag !== 'ssfi' && flag != 'message')) {\n      object.__flags[flag] = flags[flag];\n    }\n  }\n};\n\n},{}],30:[function(require,module,exports){\n/*!\n * assertion-error\n * Copyright(c) 2013 Jake Luer <jake@qualiancy.com>\n * MIT Licensed\n */\n\n/*!\n * Return a function that will copy properties from\n * one object to another excluding any originally\n * listed. Returned function will create a new `{}`.\n *\n * @param {String} excluded properties ...\n * @return {Function}\n */\n\nfunction exclude () {\n  var excludes = [].slice.call(arguments);\n\n  function excludeProps (res, obj) {\n    Object.keys(obj).forEach(function (key) {\n      if (!~excludes.indexOf(key)) res[key] = obj[key];\n    });\n  }\n\n  return function extendExclude () {\n    var args = [].slice.call(arguments)\n      , i = 0\n      , res = {};\n\n    for (; i < args.length; i++) {\n      excludeProps(res, args[i]);\n    }\n\n    return res;\n  };\n};\n\n/*!\n * Primary Exports\n */\n\nmodule.exports = AssertionError;\n\n/**\n * ### AssertionError\n *\n * An extension of the JavaScript `Error` constructor for\n * assertion and validation scenarios.\n *\n * @param {String} message\n * @param {Object} properties to include (optional)\n * @param {callee} start stack function (optional)\n */\n\nfunction AssertionError (message, _props, ssf) {\n  var extend = exclude('name', 'message', 'stack', 'constructor', 'toJSON')\n    , props = extend(_props || {});\n\n  // default values\n  this.message = message || 'Unspecified AssertionError';\n  this.showDiff = false;\n\n  // copy from properties\n  for (var key in props) {\n    this[key] = props[key];\n  }\n\n  // capture stack trace\n  ssf = ssf || arguments.callee;\n  if (ssf && Error.captureStackTrace) {\n    Error.captureStackTrace(this, ssf);\n  } else {\n    this.stack = new Error().stack;\n  }\n}\n\n/*!\n * Inherit from Error.prototype\n */\n\nAssertionError.prototype = Object.create(Error.prototype);\n\n/*!\n * Statically set name\n */\n\nAssertionError.prototype.name = 'AssertionError';\n\n/*!\n * Ensure correct constructor\n */\n\nAssertionError.prototype.constructor = AssertionError;\n\n/**\n * Allow errors to be converted to JSON for static transfer.\n *\n * @param {Boolean} include stack (default: `true`)\n * @return {Object} object that can be `JSON.stringify`\n */\n\nAssertionError.prototype.toJSON = function (stack) {\n  var extend = exclude('constructor', 'toJSON', 'stack')\n    , props = extend({ name: this.name }, this);\n\n  // include stack if exists and not turned off\n  if (false !== stack && this.stack) {\n    props.stack = this.stack;\n  }\n\n  return props;\n};\n\n},{}],31:[function(require,module,exports){\nmodule.exports = require('./lib/eql');\n\n},{\"./lib/eql\":32}],32:[function(require,module,exports){\n/*!\n * deep-eql\n * Copyright(c) 2013 Jake Luer <jake@alogicalparadox.com>\n * MIT Licensed\n */\n\n/*!\n * Module dependencies\n */\n\nvar type = require('type-detect');\n\n/*!\n * Buffer.isBuffer browser shim\n */\n\nvar Buffer;\ntry { Buffer = require('buffer').Buffer; }\ncatch(ex) {\n  Buffer = {};\n  Buffer.isBuffer = function() { return false; }\n}\n\n/*!\n * Primary Export\n */\n\nmodule.exports = deepEqual;\n\n/**\n * Assert super-strict (egal) equality between\n * two objects of any type.\n *\n * @param {Mixed} a\n * @param {Mixed} b\n * @param {Array} memoised (optional)\n * @return {Boolean} equal match\n */\n\nfunction deepEqual(a, b, m) {\n  if (sameValue(a, b)) {\n    return true;\n  } else if ('date' === type(a)) {\n    return dateEqual(a, b);\n  } else if ('regexp' === type(a)) {\n    return regexpEqual(a, b);\n  } else if (Buffer.isBuffer(a)) {\n    return bufferEqual(a, b);\n  } else if ('arguments' === type(a)) {\n    return argumentsEqual(a, b, m);\n  } else if (!typeEqual(a, b)) {\n    return false;\n  } else if (('object' !== type(a) && 'object' !== type(b))\n  && ('array' !== type(a) && 'array' !== type(b))) {\n    return sameValue(a, b);\n  } else {\n    return objectEqual(a, b, m);\n  }\n}\n\n/*!\n * Strict (egal) equality test. Ensures that NaN always\n * equals NaN and `-0` does not equal `+0`.\n *\n * @param {Mixed} a\n * @param {Mixed} b\n * @return {Boolean} equal match\n */\n\nfunction sameValue(a, b) {\n  if (a === b) return a !== 0 || 1 / a === 1 / b;\n  return a !== a && b !== b;\n}\n\n/*!\n * Compare the types of two given objects and\n * return if they are equal. Note that an Array\n * has a type of `array` (not `object`) and arguments\n * have a type of `arguments` (not `array`/`object`).\n *\n * @param {Mixed} a\n * @param {Mixed} b\n * @return {Boolean} result\n */\n\nfunction typeEqual(a, b) {\n  return type(a) === type(b);\n}\n\n/*!\n * Compare two Date objects by asserting that\n * the time values are equal using `saveValue`.\n *\n * @param {Date} a\n * @param {Date} b\n * @return {Boolean} result\n */\n\nfunction dateEqual(a, b) {\n  if ('date' !== type(b)) return false;\n  return sameValue(a.getTime(), b.getTime());\n}\n\n/*!\n * Compare two regular expressions by converting them\n * to string and checking for `sameValue`.\n *\n * @param {RegExp} a\n * @param {RegExp} b\n * @return {Boolean} result\n */\n\nfunction regexpEqual(a, b) {\n  if ('regexp' !== type(b)) return false;\n  return sameValue(a.toString(), b.toString());\n}\n\n/*!\n * Assert deep equality of two `arguments` objects.\n * Unfortunately, these must be sliced to arrays\n * prior to test to ensure no bad behavior.\n *\n * @param {Arguments} a\n * @param {Arguments} b\n * @param {Array} memoize (optional)\n * @return {Boolean} result\n */\n\nfunction argumentsEqual(a, b, m) {\n  if ('arguments' !== type(b)) return false;\n  a = [].slice.call(a);\n  b = [].slice.call(b);\n  return deepEqual(a, b, m);\n}\n\n/*!\n * Get enumerable properties of a given object.\n *\n * @param {Object} a\n * @return {Array} property names\n */\n\nfunction enumerable(a) {\n  var res = [];\n  for (var key in a) res.push(key);\n  return res;\n}\n\n/*!\n * Simple equality for flat iterable objects\n * such as Arrays or Node.js buffers.\n *\n * @param {Iterable} a\n * @param {Iterable} b\n * @return {Boolean} result\n */\n\nfunction iterableEqual(a, b) {\n  if (a.length !==  b.length) return false;\n\n  var i = 0;\n  var match = true;\n\n  for (; i < a.length; i++) {\n    if (a[i] !== b[i]) {\n      match = false;\n      break;\n    }\n  }\n\n  return match;\n}\n\n/*!\n * Extension to `iterableEqual` specifically\n * for Node.js Buffers.\n *\n * @param {Buffer} a\n * @param {Mixed} b\n * @return {Boolean} result\n */\n\nfunction bufferEqual(a, b) {\n  if (!Buffer.isBuffer(b)) return false;\n  return iterableEqual(a, b);\n}\n\n/*!\n * Block for `objectEqual` ensuring non-existing\n * values don't get in.\n *\n * @param {Mixed} object\n * @return {Boolean} result\n */\n\nfunction isValue(a) {\n  return a !== null && a !== undefined;\n}\n\n/*!\n * Recursively check the equality of two objects.\n * Once basic sameness has been established it will\n * defer to `deepEqual` for each enumerable key\n * in the object.\n *\n * @param {Mixed} a\n * @param {Mixed} b\n * @return {Boolean} result\n */\n\nfunction objectEqual(a, b, m) {\n  if (!isValue(a) || !isValue(b)) {\n    return false;\n  }\n\n  if (a.prototype !== b.prototype) {\n    return false;\n  }\n\n  var i;\n  if (m) {\n    for (i = 0; i < m.length; i++) {\n      if ((m[i][0] === a && m[i][1] === b)\n      ||  (m[i][0] === b && m[i][1] === a)) {\n        return true;\n      }\n    }\n  } else {\n    m = [];\n  }\n\n  try {\n    var ka = enumerable(a);\n    var kb = enumerable(b);\n  } catch (ex) {\n    return false;\n  }\n\n  ka.sort();\n  kb.sort();\n\n  if (!iterableEqual(ka, kb)) {\n    return false;\n  }\n\n  m.push([ a, b ]);\n\n  var key;\n  for (i = ka.length - 1; i >= 0; i--) {\n    key = ka[i];\n    if (!deepEqual(a[key], b[key], m)) {\n      return false;\n    }\n  }\n\n  return true;\n}\n\n},{\"buffer\":undefined,\"type-detect\":33}],33:[function(require,module,exports){\nmodule.exports = require('./lib/type');\n\n},{\"./lib/type\":34}],34:[function(require,module,exports){\n/*!\n * type-detect\n * Copyright(c) 2013 jake luer <jake@alogicalparadox.com>\n * MIT Licensed\n */\n\n/*!\n * Primary Exports\n */\n\nvar exports = module.exports = getType;\n\n/*!\n * Detectable javascript natives\n */\n\nvar natives = {\n    '[object Array]': 'array'\n  , '[object RegExp]': 'regexp'\n  , '[object Function]': 'function'\n  , '[object Arguments]': 'arguments'\n  , '[object Date]': 'date'\n};\n\n/**\n * ### typeOf (obj)\n *\n * Use several different techniques to determine\n * the type of object being tested.\n *\n *\n * @param {Mixed} object\n * @return {String} object type\n * @api public\n */\n\nfunction getType (obj) {\n  var str = Object.prototype.toString.call(obj);\n  if (natives[str]) return natives[str];\n  if (obj === null) return 'null';\n  if (obj === undefined) return 'undefined';\n  if (obj === Object(obj)) return 'object';\n  return typeof obj;\n}\n\nexports.Library = Library;\n\n/**\n * ### Library\n *\n * Create a repository for custom type detection.\n *\n * ```js\n * var lib = new type.Library;\n * ```\n *\n */\n\nfunction Library () {\n  this.tests = {};\n}\n\n/**\n * #### .of (obj)\n *\n * Expose replacement `typeof` detection to the library.\n *\n * ```js\n * if ('string' === lib.of('hello world')) {\n *   // ...\n * }\n * ```\n *\n * @param {Mixed} object to test\n * @return {String} type\n */\n\nLibrary.prototype.of = getType;\n\n/**\n * #### .define (type, test)\n *\n * Add a test to for the `.test()` assertion.\n *\n * Can be defined as a regular expression:\n *\n * ```js\n * lib.define('int', /^[0-9]+$/);\n * ```\n *\n * ... or as a function:\n *\n * ```js\n * lib.define('bln', function (obj) {\n *   if ('boolean' === lib.of(obj)) return true;\n *   var blns = [ 'yes', 'no', 'true', 'false', 1, 0 ];\n *   if ('string' === lib.of(obj)) obj = obj.toLowerCase();\n *   return !! ~blns.indexOf(obj);\n * });\n * ```\n *\n * @param {String} type\n * @param {RegExp|Function} test\n * @api public\n */\n\nLibrary.prototype.define = function (type, test) {\n  if (arguments.length === 1) return this.tests[type];\n  this.tests[type] = test;\n  return this;\n};\n\n/**\n * #### .test (obj, test)\n *\n * Assert that an object is of type. Will first\n * check natives, and if that does not pass it will\n * use the user defined custom tests.\n *\n * ```js\n * assert(lib.test('1', 'int'));\n * assert(lib.test('yes', 'bln'));\n * ```\n *\n * @param {Mixed} object\n * @param {String} type\n * @return {Boolean} result\n * @api public\n */\n\nLibrary.prototype.test = function (obj, type) {\n  if (type === getType(obj)) return true;\n  var test = this.tests[type];\n\n  if (test && 'regexp' === getType(test)) {\n    return test.test(obj);\n  } else if (test && 'function' === getType(test)) {\n    return test(obj);\n  } else {\n    throw new ReferenceError('Type test \"' + type + '\" not defined or invalid.');\n  }\n};\n\n},{}],35:[function(require,module,exports){\narguments[4][33][0].apply(exports,arguments)\n},{\"./lib/type\":36,\"dup\":33}],36:[function(require,module,exports){\n/*!\n * type-detect\n * Copyright(c) 2013 jake luer <jake@alogicalparadox.com>\n * MIT Licensed\n */\n\n/*!\n * Primary Exports\n */\n\nvar exports = module.exports = getType;\n\n/**\n * ### typeOf (obj)\n *\n * Use several different techniques to determine\n * the type of object being tested.\n *\n *\n * @param {Mixed} object\n * @return {String} object type\n * @api public\n */\nvar objectTypeRegexp = /^\\[object (.*)\\]$/;\n\nfunction getType(obj) {\n  var type = Object.prototype.toString.call(obj).match(objectTypeRegexp)[1].toLowerCase();\n  // Let \"new String('')\" return 'object'\n  if (typeof Promise === 'function' && obj instanceof Promise) return 'promise';\n  // PhantomJS has type \"DOMWindow\" for null\n  if (obj === null) return 'null';\n  // PhantomJS has type \"DOMWindow\" for undefined\n  if (obj === undefined) return 'undefined';\n  return type;\n}\n\nexports.Library = Library;\n\n/**\n * ### Library\n *\n * Create a repository for custom type detection.\n *\n * ```js\n * var lib = new type.Library;\n * ```\n *\n */\n\nfunction Library() {\n  if (!(this instanceof Library)) return new Library();\n  this.tests = {};\n}\n\n/**\n * #### .of (obj)\n *\n * Expose replacement `typeof` detection to the library.\n *\n * ```js\n * if ('string' === lib.of('hello world')) {\n *   // ...\n * }\n * ```\n *\n * @param {Mixed} object to test\n * @return {String} type\n */\n\nLibrary.prototype.of = getType;\n\n/**\n * #### .define (type, test)\n *\n * Add a test to for the `.test()` assertion.\n *\n * Can be defined as a regular expression:\n *\n * ```js\n * lib.define('int', /^[0-9]+$/);\n * ```\n *\n * ... or as a function:\n *\n * ```js\n * lib.define('bln', function (obj) {\n *   if ('boolean' === lib.of(obj)) return true;\n *   var blns = [ 'yes', 'no', 'true', 'false', 1, 0 ];\n *   if ('string' === lib.of(obj)) obj = obj.toLowerCase();\n *   return !! ~blns.indexOf(obj);\n * });\n * ```\n *\n * @param {String} type\n * @param {RegExp|Function} test\n * @api public\n */\n\nLibrary.prototype.define = function(type, test) {\n  if (arguments.length === 1) return this.tests[type];\n  this.tests[type] = test;\n  return this;\n};\n\n/**\n * #### .test (obj, test)\n *\n * Assert that an object is of type. Will first\n * check natives, and if that does not pass it will\n * use the user defined custom tests.\n *\n * ```js\n * assert(lib.test('1', 'int'));\n * assert(lib.test('yes', 'bln'));\n * ```\n *\n * @param {Mixed} object\n * @param {String} type\n * @return {Boolean} result\n * @api public\n */\n\nLibrary.prototype.test = function(obj, type) {\n  if (type === getType(obj)) return true;\n  var test = this.tests[type];\n\n  if (test && 'regexp' === getType(test)) {\n    return test.test(obj);\n  } else if (test && 'function' === getType(test)) {\n    return test(obj);\n  } else {\n    throw new ReferenceError('Type test \"' + type + '\" not defined or invalid.');\n  }\n};\n\n},{}]},{},[1])(1)\n});\n"
  },
  {
    "path": "app_backend/static/plugin/JavaScript-Templates-3.8.0/test/vendor/mocha.css",
    "content": "@charset \"utf-8\";\n\nbody {\n  margin:0;\n}\n\n#mocha {\n  font: 20px/1.5 \"Helvetica Neue\", Helvetica, Arial, sans-serif;\n  margin: 60px 50px;\n}\n\n#mocha ul,\n#mocha li {\n  margin: 0;\n  padding: 0;\n}\n\n#mocha ul {\n  list-style: none;\n}\n\n#mocha h1,\n#mocha h2 {\n  margin: 0;\n}\n\n#mocha h1 {\n  margin-top: 15px;\n  font-size: 1em;\n  font-weight: 200;\n}\n\n#mocha h1 a {\n  text-decoration: none;\n  color: inherit;\n}\n\n#mocha h1 a:hover {\n  text-decoration: underline;\n}\n\n#mocha .suite .suite h1 {\n  margin-top: 0;\n  font-size: .8em;\n}\n\n#mocha .hidden {\n  display: none;\n}\n\n#mocha h2 {\n  font-size: 12px;\n  font-weight: normal;\n  cursor: pointer;\n}\n\n#mocha .suite {\n  margin-left: 15px;\n}\n\n#mocha .test {\n  margin-left: 15px;\n  overflow: hidden;\n}\n\n#mocha .test.pending:hover h2::after {\n  content: '(pending)';\n  font-family: arial, sans-serif;\n}\n\n#mocha .test.pass.medium .duration {\n  background: #c09853;\n}\n\n#mocha .test.pass.slow .duration {\n  background: #b94a48;\n}\n\n#mocha .test.pass::before {\n  content: '✓';\n  font-size: 12px;\n  display: block;\n  float: left;\n  margin-right: 5px;\n  color: #00d6b2;\n}\n\n#mocha .test.pass .duration {\n  font-size: 9px;\n  margin-left: 5px;\n  padding: 2px 5px;\n  color: #fff;\n  -webkit-box-shadow: inset 0 1px 1px rgba(0,0,0,.2);\n  -moz-box-shadow: inset 0 1px 1px rgba(0,0,0,.2);\n  box-shadow: inset 0 1px 1px rgba(0,0,0,.2);\n  -webkit-border-radius: 5px;\n  -moz-border-radius: 5px;\n  -ms-border-radius: 5px;\n  -o-border-radius: 5px;\n  border-radius: 5px;\n}\n\n#mocha .test.pass.fast .duration {\n  display: none;\n}\n\n#mocha .test.pending {\n  color: #0b97c4;\n}\n\n#mocha .test.pending::before {\n  content: '◦';\n  color: #0b97c4;\n}\n\n#mocha .test.fail {\n  color: #c00;\n}\n\n#mocha .test.fail pre {\n  color: black;\n}\n\n#mocha .test.fail::before {\n  content: '✖';\n  font-size: 12px;\n  display: block;\n  float: left;\n  margin-right: 5px;\n  color: #c00;\n}\n\n#mocha .test pre.error {\n  color: #c00;\n  max-height: 300px;\n  overflow: auto;\n}\n\n#mocha .test .html-error {\n  overflow: auto;\n  color: black;\n  line-height: 1.5;\n  display: block;\n  float: left;\n  clear: left;\n  font: 12px/1.5 monaco, monospace;\n  margin: 5px;\n  padding: 15px;\n  border: 1px solid #eee;\n  max-width: 85%; /*(1)*/\n  max-width: -webkit-calc(100% - 42px);\n  max-width: -moz-calc(100% - 42px);\n  max-width: calc(100% - 42px); /*(2)*/\n  max-height: 300px;\n  word-wrap: break-word;\n  border-bottom-color: #ddd;\n  -webkit-box-shadow: 0 1px 3px #eee;\n  -moz-box-shadow: 0 1px 3px #eee;\n  box-shadow: 0 1px 3px #eee;\n  -webkit-border-radius: 3px;\n  -moz-border-radius: 3px;\n  border-radius: 3px;\n}\n\n#mocha .test .html-error pre.error {\n  border: none;\n  -webkit-border-radius: 0;\n  -moz-border-radius: 0;\n  border-radius: 0;\n  -webkit-box-shadow: 0;\n  -moz-box-shadow: 0;\n  box-shadow: 0;\n  padding: 0;\n  margin: 0;\n  margin-top: 18px;\n  max-height: none;\n}\n\n/**\n * (1): approximate for browsers not supporting calc\n * (2): 42 = 2*15 + 2*10 + 2*1 (padding + margin + border)\n *      ^^ seriously\n */\n#mocha .test pre {\n  display: block;\n  float: left;\n  clear: left;\n  font: 12px/1.5 monaco, monospace;\n  margin: 5px;\n  padding: 15px;\n  border: 1px solid #eee;\n  max-width: 85%; /*(1)*/\n  max-width: -webkit-calc(100% - 42px);\n  max-width: -moz-calc(100% - 42px);\n  max-width: calc(100% - 42px); /*(2)*/\n  word-wrap: break-word;\n  border-bottom-color: #ddd;\n  -webkit-box-shadow: 0 1px 3px #eee;\n  -moz-box-shadow: 0 1px 3px #eee;\n  box-shadow: 0 1px 3px #eee;\n  -webkit-border-radius: 3px;\n  -moz-border-radius: 3px;\n  border-radius: 3px;\n}\n\n#mocha .test h2 {\n  position: relative;\n}\n\n#mocha .test a.replay {\n  position: absolute;\n  top: 3px;\n  right: 0;\n  text-decoration: none;\n  vertical-align: middle;\n  display: block;\n  width: 15px;\n  height: 15px;\n  line-height: 15px;\n  text-align: center;\n  background: #eee;\n  font-size: 15px;\n  -webkit-border-radius: 15px;\n  -moz-border-radius: 15px;\n  border-radius: 15px;\n  -webkit-transition:opacity 200ms;\n  -moz-transition:opacity 200ms;\n  -o-transition:opacity 200ms;\n  transition: opacity 200ms;\n  opacity: 0.3;\n  color: #888;\n}\n\n#mocha .test:hover a.replay {\n  opacity: 1;\n}\n\n#mocha-report.pass .test.fail {\n  display: none;\n}\n\n#mocha-report.fail .test.pass {\n  display: none;\n}\n\n#mocha-report.pending .test.pass,\n#mocha-report.pending .test.fail {\n  display: none;\n}\n#mocha-report.pending .test.pass.pending {\n  display: block;\n}\n\n#mocha-error {\n  color: #c00;\n  font-size: 1.5em;\n  font-weight: 100;\n  letter-spacing: 1px;\n}\n\n#mocha-stats {\n  position: fixed;\n  top: 15px;\n  right: 10px;\n  font-size: 12px;\n  margin: 0;\n  color: #888;\n  z-index: 1;\n}\n\n#mocha-stats .progress {\n  float: right;\n  padding-top: 0;\n\n  /**\n   * Set safe initial values, so mochas .progress does not inherit these\n   * properties from Bootstrap .progress (which causes .progress height to\n   * equal line height set in Bootstrap).\n   */\n  height: auto;\n  -webkit-box-shadow: none;\n  -moz-box-shadow: none;\n  box-shadow: none;\n  background-color: initial;\n}\n\n#mocha-stats em {\n  color: black;\n}\n\n#mocha-stats a {\n  text-decoration: none;\n  color: inherit;\n}\n\n#mocha-stats a:hover {\n  border-bottom: 1px solid #eee;\n}\n\n#mocha-stats li {\n  display: inline-block;\n  margin: 0 5px;\n  list-style: none;\n  padding-top: 11px;\n}\n\n#mocha-stats canvas {\n  width: 40px;\n  height: 40px;\n}\n\n#mocha code .comment { color: #ddd; }\n#mocha code .init { color: #2f6fad; }\n#mocha code .string { color: #5890ad; }\n#mocha code .keyword { color: #8a6343; }\n#mocha code .number { color: #2f6fad; }\n\n@media screen and (max-device-width: 480px) {\n  #mocha {\n    margin: 60px 0px;\n  }\n\n  #mocha #stats {\n    position: absolute;\n  }\n}\n"
  },
  {
    "path": "app_backend/static/plugin/JavaScript-Templates-3.8.0/test/vendor/mocha.js",
    "content": "(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require==\"function\"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error(\"Cannot find module '\"+o+\"'\");throw f.code=\"MODULE_NOT_FOUND\",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require==\"function\"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){\n(function (process,global){\n/* eslint no-unused-vars: off */\n\n/**\n * Shim process.stdout.\n */\n\nprocess.stdout = require('browser-stdout')();\n\nvar Mocha = require('./lib/mocha');\n\n/**\n * Create a Mocha instance.\n *\n * @return {undefined}\n */\n\nvar mocha = new Mocha({ reporter: 'html' });\n\n/**\n * Save timer references to avoid Sinon interfering (see GH-237).\n */\n\nvar Date = global.Date;\nvar setTimeout = global.setTimeout;\nvar setInterval = global.setInterval;\nvar clearTimeout = global.clearTimeout;\nvar clearInterval = global.clearInterval;\n\nvar uncaughtExceptionHandlers = [];\n\nvar originalOnerrorHandler = global.onerror;\n\n/**\n * Remove uncaughtException listener.\n * Revert to original onerror handler if previously defined.\n */\n\nprocess.removeListener = function(e, fn) {\n  if (e === 'uncaughtException') {\n    if (originalOnerrorHandler) {\n      global.onerror = originalOnerrorHandler;\n    } else {\n      global.onerror = function() {};\n    }\n    var i = Mocha.utils.indexOf(uncaughtExceptionHandlers, fn);\n    if (i !== -1) {\n      uncaughtExceptionHandlers.splice(i, 1);\n    }\n  }\n};\n\n/**\n * Implements uncaughtException listener.\n */\n\nprocess.on = function(e, fn) {\n  if (e === 'uncaughtException') {\n    global.onerror = function(err, url, line) {\n      fn(new Error(err + ' (' + url + ':' + line + ')'));\n      return !mocha.allowUncaught;\n    };\n    uncaughtExceptionHandlers.push(fn);\n  }\n};\n\n// The BDD UI is registered by default, but no UI will be functional in the\n// browser without an explicit call to the overridden `mocha.ui` (see below).\n// Ensure that this default UI does not expose its methods to the global scope.\nmocha.suite.removeAllListeners('pre-require');\n\nvar immediateQueue = [];\nvar immediateTimeout;\n\nfunction timeslice() {\n  var immediateStart = new Date().getTime();\n  while (immediateQueue.length && (new Date().getTime() - immediateStart) < 100) {\n    immediateQueue.shift()();\n  }\n  if (immediateQueue.length) {\n    immediateTimeout = setTimeout(timeslice, 0);\n  } else {\n    immediateTimeout = null;\n  }\n}\n\n/**\n * High-performance override of Runner.immediately.\n */\n\nMocha.Runner.immediately = function(callback) {\n  immediateQueue.push(callback);\n  if (!immediateTimeout) {\n    immediateTimeout = setTimeout(timeslice, 0);\n  }\n};\n\n/**\n * Function to allow assertion libraries to throw errors directly into mocha.\n * This is useful when running tests in a browser because window.onerror will\n * only receive the 'message' attribute of the Error.\n */\nmocha.throwError = function(err) {\n  Mocha.utils.forEach(uncaughtExceptionHandlers, function(fn) {\n    fn(err);\n  });\n  throw err;\n};\n\n/**\n * Override ui to ensure that the ui functions are initialized.\n * Normally this would happen in Mocha.prototype.loadFiles.\n */\n\nmocha.ui = function(ui) {\n  Mocha.prototype.ui.call(this, ui);\n  this.suite.emit('pre-require', global, null, this);\n  return this;\n};\n\n/**\n * Setup mocha with the given setting options.\n */\n\nmocha.setup = function(opts) {\n  if (typeof opts === 'string') {\n    opts = { ui: opts };\n  }\n  for (var opt in opts) {\n    if (opts.hasOwnProperty(opt)) {\n      this[opt](opts[opt]);\n    }\n  }\n  return this;\n};\n\n/**\n * Run mocha, returning the Runner.\n */\n\nmocha.run = function(fn) {\n  var options = mocha.options;\n  mocha.globals('location');\n\n  var query = Mocha.utils.parseQuery(global.location.search || '');\n  if (query.grep) {\n    mocha.grep(query.grep);\n  }\n  if (query.fgrep) {\n    mocha.fgrep(query.fgrep);\n  }\n  if (query.invert) {\n    mocha.invert();\n  }\n\n  return Mocha.prototype.run.call(mocha, function(err) {\n    // The DOM Document is not available in Web Workers.\n    var document = global.document;\n    if (document && document.getElementById('mocha') && options.noHighlighting !== true) {\n      Mocha.utils.highlightTags('code');\n    }\n    if (fn) {\n      fn(err);\n    }\n  });\n};\n\n/**\n * Expose the process shim.\n * https://github.com/mochajs/mocha/pull/916\n */\n\nMocha.process = process;\n\n/**\n * Expose mocha.\n */\n\nglobal.Mocha = Mocha;\nglobal.mocha = mocha;\n\n// this allows test/acceptance/required-tokens.js to pass; thus,\n// you can now do `const describe = require('mocha').describe` in a\n// browser context (assuming browserification).  should fix #880\nmodule.exports = global;\n\n}).call(this,require('_process'),typeof global !== \"undefined\" ? global : typeof self !== \"undefined\" ? self : typeof window !== \"undefined\" ? window : {})\n},{\"./lib/mocha\":14,\"_process\":67,\"browser-stdout\":41}],2:[function(require,module,exports){\n/* eslint-disable no-unused-vars */\nmodule.exports = function(type) {\n  return function() {};\n};\n\n},{}],3:[function(require,module,exports){\n/**\n * Module exports.\n */\n\nexports.EventEmitter = EventEmitter;\n\n/**\n * Object#toString reference.\n */\nvar objToString = Object.prototype.toString;\n\n/**\n * Check if a value is an array.\n *\n * @api private\n * @param {*} val The value to test.\n * @return {boolean} true if the value is an array, otherwise false.\n */\nfunction isArray(val) {\n  return objToString.call(val) === '[object Array]';\n}\n\n/**\n * Event emitter constructor.\n *\n * @api public\n */\nfunction EventEmitter() {}\n\n/**\n * Add a listener.\n *\n * @api public\n * @param {string} name Event name.\n * @param {Function} fn Event handler.\n * @return {EventEmitter} Emitter instance.\n */\nEventEmitter.prototype.on = function(name, fn) {\n  if (!this.$events) {\n    this.$events = {};\n  }\n\n  if (!this.$events[name]) {\n    this.$events[name] = fn;\n  } else if (isArray(this.$events[name])) {\n    this.$events[name].push(fn);\n  } else {\n    this.$events[name] = [this.$events[name], fn];\n  }\n\n  return this;\n};\n\nEventEmitter.prototype.addListener = EventEmitter.prototype.on;\n\n/**\n * Adds a volatile listener.\n *\n * @api public\n * @param {string} name Event name.\n * @param {Function} fn Event handler.\n * @return {EventEmitter} Emitter instance.\n */\nEventEmitter.prototype.once = function(name, fn) {\n  var self = this;\n\n  function on() {\n    self.removeListener(name, on);\n    fn.apply(this, arguments);\n  }\n\n  on.listener = fn;\n  this.on(name, on);\n\n  return this;\n};\n\n/**\n * Remove a listener.\n *\n * @api public\n * @param {string} name Event name.\n * @param {Function} fn Event handler.\n * @return {EventEmitter} Emitter instance.\n */\nEventEmitter.prototype.removeListener = function(name, fn) {\n  if (this.$events && this.$events[name]) {\n    var list = this.$events[name];\n\n    if (isArray(list)) {\n      var pos = -1;\n\n      for (var i = 0, l = list.length; i < l; i++) {\n        if (list[i] === fn || (list[i].listener && list[i].listener === fn)) {\n          pos = i;\n          break;\n        }\n      }\n\n      if (pos < 0) {\n        return this;\n      }\n\n      list.splice(pos, 1);\n\n      if (!list.length) {\n        delete this.$events[name];\n      }\n    } else if (list === fn || (list.listener && list.listener === fn)) {\n      delete this.$events[name];\n    }\n  }\n\n  return this;\n};\n\n/**\n * Remove all listeners for an event.\n *\n * @api public\n * @param {string} name Event name.\n * @return {EventEmitter} Emitter instance.\n */\nEventEmitter.prototype.removeAllListeners = function(name) {\n  if (name === undefined) {\n    this.$events = {};\n    return this;\n  }\n\n  if (this.$events && this.$events[name]) {\n    this.$events[name] = null;\n  }\n\n  return this;\n};\n\n/**\n * Get all listeners for a given event.\n *\n * @api public\n * @param {string} name Event name.\n * @return {EventEmitter} Emitter instance.\n */\nEventEmitter.prototype.listeners = function(name) {\n  if (!this.$events) {\n    this.$events = {};\n  }\n\n  if (!this.$events[name]) {\n    this.$events[name] = [];\n  }\n\n  if (!isArray(this.$events[name])) {\n    this.$events[name] = [this.$events[name]];\n  }\n\n  return this.$events[name];\n};\n\n/**\n * Emit an event.\n *\n * @api public\n * @param {string} name Event name.\n * @return {boolean} true if at least one handler was invoked, else false.\n */\nEventEmitter.prototype.emit = function(name) {\n  if (!this.$events) {\n    return false;\n  }\n\n  var handler = this.$events[name];\n\n  if (!handler) {\n    return false;\n  }\n\n  var args = Array.prototype.slice.call(arguments, 1);\n\n  if (typeof handler === 'function') {\n    handler.apply(this, args);\n  } else if (isArray(handler)) {\n    var listeners = handler.slice();\n\n    for (var i = 0, l = listeners.length; i < l; i++) {\n      listeners[i].apply(this, args);\n    }\n  } else {\n    return false;\n  }\n\n  return true;\n};\n\n},{}],4:[function(require,module,exports){\n/**\n * Expose `Progress`.\n */\n\nmodule.exports = Progress;\n\n/**\n * Initialize a new `Progress` indicator.\n */\nfunction Progress() {\n  this.percent = 0;\n  this.size(0);\n  this.fontSize(11);\n  this.font('helvetica, arial, sans-serif');\n}\n\n/**\n * Set progress size to `size`.\n *\n * @api public\n * @param {number} size\n * @return {Progress} Progress instance.\n */\nProgress.prototype.size = function(size) {\n  this._size = size;\n  return this;\n};\n\n/**\n * Set text to `text`.\n *\n * @api public\n * @param {string} text\n * @return {Progress} Progress instance.\n */\nProgress.prototype.text = function(text) {\n  this._text = text;\n  return this;\n};\n\n/**\n * Set font size to `size`.\n *\n * @api public\n * @param {number} size\n * @return {Progress} Progress instance.\n */\nProgress.prototype.fontSize = function(size) {\n  this._fontSize = size;\n  return this;\n};\n\n/**\n * Set font to `family`.\n *\n * @param {string} family\n * @return {Progress} Progress instance.\n */\nProgress.prototype.font = function(family) {\n  this._font = family;\n  return this;\n};\n\n/**\n * Update percentage to `n`.\n *\n * @param {number} n\n * @return {Progress} Progress instance.\n */\nProgress.prototype.update = function(n) {\n  this.percent = n;\n  return this;\n};\n\n/**\n * Draw on `ctx`.\n *\n * @param {CanvasRenderingContext2d} ctx\n * @return {Progress} Progress instance.\n */\nProgress.prototype.draw = function(ctx) {\n  try {\n    var percent = Math.min(this.percent, 100);\n    var size = this._size;\n    var half = size / 2;\n    var x = half;\n    var y = half;\n    var rad = half - 1;\n    var fontSize = this._fontSize;\n\n    ctx.font = fontSize + 'px ' + this._font;\n\n    var angle = Math.PI * 2 * (percent / 100);\n    ctx.clearRect(0, 0, size, size);\n\n    // outer circle\n    ctx.strokeStyle = '#9f9f9f';\n    ctx.beginPath();\n    ctx.arc(x, y, rad, 0, angle, false);\n    ctx.stroke();\n\n    // inner circle\n    ctx.strokeStyle = '#eee';\n    ctx.beginPath();\n    ctx.arc(x, y, rad - 1, 0, angle, true);\n    ctx.stroke();\n\n    // text\n    var text = this._text || (percent | 0) + '%';\n    var w = ctx.measureText(text).width;\n\n    ctx.fillText(text, x - w / 2 + 1, y + fontSize / 2 - 1);\n  } catch (err) {\n    // don't fail if we can't render progress\n  }\n  return this;\n};\n\n},{}],5:[function(require,module,exports){\n(function (global){\nexports.isatty = function isatty() {\n  return true;\n};\n\nexports.getWindowSize = function getWindowSize() {\n  if ('innerHeight' in global) {\n    return [global.innerHeight, global.innerWidth];\n  }\n  // In a Web Worker, the DOM Window is not available.\n  return [640, 480];\n};\n\n}).call(this,typeof global !== \"undefined\" ? global : typeof self !== \"undefined\" ? self : typeof window !== \"undefined\" ? window : {})\n},{}],6:[function(require,module,exports){\n/**\n * Module dependencies.\n */\n\nvar JSON = require('json3');\n\n/**\n * Expose `Context`.\n */\n\nmodule.exports = Context;\n\n/**\n * Initialize a new `Context`.\n *\n * @api private\n */\nfunction Context() {}\n\n/**\n * Set or get the context `Runnable` to `runnable`.\n *\n * @api private\n * @param {Runnable} runnable\n * @return {Context}\n */\nContext.prototype.runnable = function(runnable) {\n  if (!arguments.length) {\n    return this._runnable;\n  }\n  this.test = this._runnable = runnable;\n  return this;\n};\n\n/**\n * Set test timeout `ms`.\n *\n * @api private\n * @param {number} ms\n * @return {Context} self\n */\nContext.prototype.timeout = function(ms) {\n  if (!arguments.length) {\n    return this.runnable().timeout();\n  }\n  this.runnable().timeout(ms);\n  return this;\n};\n\n/**\n * Set test timeout `enabled`.\n *\n * @api private\n * @param {boolean} enabled\n * @return {Context} self\n */\nContext.prototype.enableTimeouts = function(enabled) {\n  this.runnable().enableTimeouts(enabled);\n  return this;\n};\n\n/**\n * Set test slowness threshold `ms`.\n *\n * @api private\n * @param {number} ms\n * @return {Context} self\n */\nContext.prototype.slow = function(ms) {\n  this.runnable().slow(ms);\n  return this;\n};\n\n/**\n * Mark a test as skipped.\n *\n * @api private\n * @return {Context} self\n */\nContext.prototype.skip = function() {\n  this.runnable().skip();\n  return this;\n};\n\n/**\n * Allow a number of retries on failed tests\n *\n * @api private\n * @param {number} n\n * @return {Context} self\n */\nContext.prototype.retries = function(n) {\n  if (!arguments.length) {\n    return this.runnable().retries();\n  }\n  this.runnable().retries(n);\n  return this;\n};\n\n/**\n * Inspect the context void of `._runnable`.\n *\n * @api private\n * @return {string}\n */\nContext.prototype.inspect = function() {\n  return JSON.stringify(this, function(key, val) {\n    return key === 'runnable' || key === 'test' ? undefined : val;\n  }, 2);\n};\n\n},{\"json3\":54}],7:[function(require,module,exports){\n/**\n * Module dependencies.\n */\n\nvar Runnable = require('./runnable');\nvar inherits = require('./utils').inherits;\n\n/**\n * Expose `Hook`.\n */\n\nmodule.exports = Hook;\n\n/**\n * Initialize a new `Hook` with the given `title` and callback `fn`.\n *\n * @param {String} title\n * @param {Function} fn\n * @api private\n */\nfunction Hook(title, fn) {\n  Runnable.call(this, title, fn);\n  this.type = 'hook';\n}\n\n/**\n * Inherit from `Runnable.prototype`.\n */\ninherits(Hook, Runnable);\n\n/**\n * Get or set the test `err`.\n *\n * @param {Error} err\n * @return {Error}\n * @api public\n */\nHook.prototype.error = function(err) {\n  if (!arguments.length) {\n    err = this._error;\n    this._error = null;\n    return err;\n  }\n\n  this._error = err;\n};\n\n},{\"./runnable\":33,\"./utils\":38}],8:[function(require,module,exports){\n/**\n * Module dependencies.\n */\n\nvar Test = require('../test');\n\n/**\n * BDD-style interface:\n *\n *      describe('Array', function() {\n *        describe('#indexOf()', function() {\n *          it('should return -1 when not present', function() {\n *            // ...\n *          });\n *\n *          it('should return the index when present', function() {\n *            // ...\n *          });\n *        });\n *      });\n *\n * @param {Suite} suite Root suite.\n */\nmodule.exports = function(suite) {\n  var suites = [suite];\n\n  suite.on('pre-require', function(context, file, mocha) {\n    var common = require('./common')(suites, context, mocha);\n\n    context.before = common.before;\n    context.after = common.after;\n    context.beforeEach = common.beforeEach;\n    context.afterEach = common.afterEach;\n    context.run = mocha.options.delay && common.runWithSuite(suite);\n    /**\n     * Describe a \"suite\" with the given `title`\n     * and callback `fn` containing nested suites\n     * and/or tests.\n     */\n\n    context.describe = context.context = function(title, fn) {\n      return common.suite.create({\n        title: title,\n        file: file,\n        fn: fn\n      });\n    };\n\n    /**\n     * Pending describe.\n     */\n\n    context.xdescribe = context.xcontext = context.describe.skip = function(title, fn) {\n      return common.suite.skip({\n        title: title,\n        file: file,\n        fn: fn\n      });\n    };\n\n    /**\n     * Exclusive suite.\n     */\n\n    context.describe.only = function(title, fn) {\n      return common.suite.only({\n        title: title,\n        file: file,\n        fn: fn\n      });\n    };\n\n    /**\n     * Describe a specification or test-case\n     * with the given `title` and callback `fn`\n     * acting as a thunk.\n     */\n\n    context.it = context.specify = function(title, fn) {\n      var suite = suites[0];\n      if (suite.isPending()) {\n        fn = null;\n      }\n      var test = new Test(title, fn);\n      test.file = file;\n      suite.addTest(test);\n      return test;\n    };\n\n    /**\n     * Exclusive test-case.\n     */\n\n    context.it.only = function(title, fn) {\n      return common.test.only(mocha, context.it(title, fn));\n    };\n\n    /**\n     * Pending test case.\n     */\n\n    context.xit = context.xspecify = context.it.skip = function(title) {\n      context.it(title);\n    };\n\n    /**\n     * Number of attempts to retry.\n     */\n    context.it.retries = function(n) {\n      context.retries(n);\n    };\n  });\n};\n\n},{\"../test\":36,\"./common\":9}],9:[function(require,module,exports){\n'use strict';\n\nvar Suite = require('../suite');\n\n/**\n * Functions common to more than one interface.\n *\n * @param {Suite[]} suites\n * @param {Context} context\n * @param {Mocha} mocha\n * @return {Object} An object containing common functions.\n */\nmodule.exports = function(suites, context, mocha) {\n  return {\n    /**\n     * This is only present if flag --delay is passed into Mocha. It triggers\n     * root suite execution.\n     *\n     * @param {Suite} suite The root wuite.\n     * @return {Function} A function which runs the root suite\n     */\n    runWithSuite: function runWithSuite(suite) {\n      return function run() {\n        suite.run();\n      };\n    },\n\n    /**\n     * Execute before running tests.\n     *\n     * @param {string} name\n     * @param {Function} fn\n     */\n    before: function(name, fn) {\n      suites[0].beforeAll(name, fn);\n    },\n\n    /**\n     * Execute after running tests.\n     *\n     * @param {string} name\n     * @param {Function} fn\n     */\n    after: function(name, fn) {\n      suites[0].afterAll(name, fn);\n    },\n\n    /**\n     * Execute before each test case.\n     *\n     * @param {string} name\n     * @param {Function} fn\n     */\n    beforeEach: function(name, fn) {\n      suites[0].beforeEach(name, fn);\n    },\n\n    /**\n     * Execute after each test case.\n     *\n     * @param {string} name\n     * @param {Function} fn\n     */\n    afterEach: function(name, fn) {\n      suites[0].afterEach(name, fn);\n    },\n\n    suite: {\n      /**\n       * Create an exclusive Suite; convenience function\n       * See docstring for create() below.\n       *\n       * @param {Object} opts\n       * @returns {Suite}\n       */\n      only: function only(opts) {\n        mocha.options.hasOnly = true;\n        opts.isOnly = true;\n        return this.create(opts);\n      },\n\n      /**\n       * Create a Suite, but skip it; convenience function\n       * See docstring for create() below.\n       *\n       * @param {Object} opts\n       * @returns {Suite}\n       */\n      skip: function skip(opts) {\n        opts.pending = true;\n        return this.create(opts);\n      },\n\n      /**\n       * Creates a suite.\n       * @param {Object} opts Options\n       * @param {string} opts.title Title of Suite\n       * @param {Function} [opts.fn] Suite Function (not always applicable)\n       * @param {boolean} [opts.pending] Is Suite pending?\n       * @param {string} [opts.file] Filepath where this Suite resides\n       * @param {boolean} [opts.isOnly] Is Suite exclusive?\n       * @returns {Suite}\n       */\n      create: function create(opts) {\n        var suite = Suite.create(suites[0], opts.title);\n        suite.pending = Boolean(opts.pending);\n        suite.file = opts.file;\n        suites.unshift(suite);\n        if (opts.isOnly) {\n          suite.parent._onlySuites = suite.parent._onlySuites.concat(suite);\n          mocha.options.hasOnly = true;\n        }\n        if (typeof opts.fn === 'function') {\n          opts.fn.call(suite);\n          suites.shift();\n        } else if (typeof opts.fn === 'undefined' && !suite.pending) {\n          throw new Error('Suite \"' + suite.fullTitle() + '\" was defined but no callback was supplied. Supply a callback or explicitly skip the suite.');\n        }\n\n        return suite;\n      }\n    },\n\n    test: {\n\n      /**\n       * Exclusive test-case.\n       *\n       * @param {Object} mocha\n       * @param {Function} test\n       * @returns {*}\n       */\n      only: function(mocha, test) {\n        test.parent._onlyTests = test.parent._onlyTests.concat(test);\n        mocha.options.hasOnly = true;\n        return test;\n      },\n\n      /**\n       * Pending test case.\n       *\n       * @param {string} title\n       */\n      skip: function(title) {\n        context.test(title);\n      },\n\n      /**\n       * Number of retry attempts\n       *\n       * @param {number} n\n       */\n      retries: function(n) {\n        context.retries(n);\n      }\n    }\n  };\n};\n\n},{\"../suite\":35}],10:[function(require,module,exports){\n/**\n * Module dependencies.\n */\n\nvar Suite = require('../suite');\nvar Test = require('../test');\n\n/**\n * Exports-style (as Node.js module) interface:\n *\n *     exports.Array = {\n *       '#indexOf()': {\n *         'should return -1 when the value is not present': function() {\n *\n *         },\n *\n *         'should return the correct index when the value is present': function() {\n *\n *         }\n *       }\n *     };\n *\n * @param {Suite} suite Root suite.\n */\nmodule.exports = function(suite) {\n  var suites = [suite];\n\n  suite.on('require', visit);\n\n  function visit(obj, file) {\n    var suite;\n    for (var key in obj) {\n      if (typeof obj[key] === 'function') {\n        var fn = obj[key];\n        switch (key) {\n          case 'before':\n            suites[0].beforeAll(fn);\n            break;\n          case 'after':\n            suites[0].afterAll(fn);\n            break;\n          case 'beforeEach':\n            suites[0].beforeEach(fn);\n            break;\n          case 'afterEach':\n            suites[0].afterEach(fn);\n            break;\n          default:\n            var test = new Test(key, fn);\n            test.file = file;\n            suites[0].addTest(test);\n        }\n      } else {\n        suite = Suite.create(suites[0], key);\n        suites.unshift(suite);\n        visit(obj[key], file);\n        suites.shift();\n      }\n    }\n  }\n};\n\n},{\"../suite\":35,\"../test\":36}],11:[function(require,module,exports){\nexports.bdd = require('./bdd');\nexports.tdd = require('./tdd');\nexports.qunit = require('./qunit');\nexports.exports = require('./exports');\n\n},{\"./bdd\":8,\"./exports\":10,\"./qunit\":12,\"./tdd\":13}],12:[function(require,module,exports){\n/**\n * Module dependencies.\n */\n\nvar Test = require('../test');\n\n/**\n * QUnit-style interface:\n *\n *     suite('Array');\n *\n *     test('#length', function() {\n *       var arr = [1,2,3];\n *       ok(arr.length == 3);\n *     });\n *\n *     test('#indexOf()', function() {\n *       var arr = [1,2,3];\n *       ok(arr.indexOf(1) == 0);\n *       ok(arr.indexOf(2) == 1);\n *       ok(arr.indexOf(3) == 2);\n *     });\n *\n *     suite('String');\n *\n *     test('#length', function() {\n *       ok('foo'.length == 3);\n *     });\n *\n * @param {Suite} suite Root suite.\n */\nmodule.exports = function(suite) {\n  var suites = [suite];\n\n  suite.on('pre-require', function(context, file, mocha) {\n    var common = require('./common')(suites, context, mocha);\n\n    context.before = common.before;\n    context.after = common.after;\n    context.beforeEach = common.beforeEach;\n    context.afterEach = common.afterEach;\n    context.run = mocha.options.delay && common.runWithSuite(suite);\n    /**\n     * Describe a \"suite\" with the given `title`.\n     */\n\n    context.suite = function(title) {\n      if (suites.length > 1) {\n        suites.shift();\n      }\n      return common.suite.create({\n        title: title,\n        file: file,\n        fn: false\n      });\n    };\n\n    /**\n     * Exclusive Suite.\n     */\n\n    context.suite.only = function(title) {\n      if (suites.length > 1) {\n        suites.shift();\n      }\n      return common.suite.only({\n        title: title,\n        file: file,\n        fn: false\n      });\n    };\n\n    /**\n     * Describe a specification or test-case\n     * with the given `title` and callback `fn`\n     * acting as a thunk.\n     */\n\n    context.test = function(title, fn) {\n      var test = new Test(title, fn);\n      test.file = file;\n      suites[0].addTest(test);\n      return test;\n    };\n\n    /**\n     * Exclusive test-case.\n     */\n\n    context.test.only = function(title, fn) {\n      return common.test.only(mocha, context.test(title, fn));\n    };\n\n    context.test.skip = common.test.skip;\n    context.test.retries = common.test.retries;\n  });\n};\n\n},{\"../test\":36,\"./common\":9}],13:[function(require,module,exports){\n/**\n * Module dependencies.\n */\n\nvar Test = require('../test');\n\n/**\n * TDD-style interface:\n *\n *      suite('Array', function() {\n *        suite('#indexOf()', function() {\n *          suiteSetup(function() {\n *\n *          });\n *\n *          test('should return -1 when not present', function() {\n *\n *          });\n *\n *          test('should return the index when present', function() {\n *\n *          });\n *\n *          suiteTeardown(function() {\n *\n *          });\n *        });\n *      });\n *\n * @param {Suite} suite Root suite.\n */\nmodule.exports = function(suite) {\n  var suites = [suite];\n\n  suite.on('pre-require', function(context, file, mocha) {\n    var common = require('./common')(suites, context, mocha);\n\n    context.setup = common.beforeEach;\n    context.teardown = common.afterEach;\n    context.suiteSetup = common.before;\n    context.suiteTeardown = common.after;\n    context.run = mocha.options.delay && common.runWithSuite(suite);\n\n    /**\n     * Describe a \"suite\" with the given `title` and callback `fn` containing\n     * nested suites and/or tests.\n     */\n    context.suite = function(title, fn) {\n      return common.suite.create({\n        title: title,\n        file: file,\n        fn: fn\n      });\n    };\n\n    /**\n     * Pending suite.\n     */\n    context.suite.skip = function(title, fn) {\n      return common.suite.skip({\n        title: title,\n        file: file,\n        fn: fn\n      });\n    };\n\n    /**\n     * Exclusive test-case.\n     */\n    context.suite.only = function(title, fn) {\n      return common.suite.only({\n        title: title,\n        file: file,\n        fn: fn\n      });\n    };\n\n    /**\n     * Describe a specification or test-case with the given `title` and\n     * callback `fn` acting as a thunk.\n     */\n    context.test = function(title, fn) {\n      var suite = suites[0];\n      if (suite.isPending()) {\n        fn = null;\n      }\n      var test = new Test(title, fn);\n      test.file = file;\n      suite.addTest(test);\n      return test;\n    };\n\n    /**\n     * Exclusive test-case.\n     */\n\n    context.test.only = function(title, fn) {\n      return common.test.only(mocha, context.test(title, fn));\n    };\n\n    context.test.skip = common.test.skip;\n    context.test.retries = common.test.retries;\n  });\n};\n\n},{\"../test\":36,\"./common\":9}],14:[function(require,module,exports){\n(function (process,global,__dirname){\n/*!\n * mocha\n * Copyright(c) 2011 TJ Holowaychuk <tj@vision-media.ca>\n * MIT Licensed\n */\n\n/**\n * Module dependencies.\n */\n\nvar escapeRe = require('escape-string-regexp');\nvar path = require('path');\nvar reporters = require('./reporters');\nvar utils = require('./utils');\n\n/**\n * Expose `Mocha`.\n */\n\nexports = module.exports = Mocha;\n\n/**\n * To require local UIs and reporters when running in node.\n */\n\nif (!process.browser) {\n  var cwd = process.cwd();\n  module.paths.push(cwd, path.join(cwd, 'node_modules'));\n}\n\n/**\n * Expose internals.\n */\n\nexports.utils = utils;\nexports.interfaces = require('./interfaces');\nexports.reporters = reporters;\nexports.Runnable = require('./runnable');\nexports.Context = require('./context');\nexports.Runner = require('./runner');\nexports.Suite = require('./suite');\nexports.Hook = require('./hook');\nexports.Test = require('./test');\n\n/**\n * Return image `name` path.\n *\n * @api private\n * @param {string} name\n * @return {string}\n */\nfunction image(name) {\n  return path.join(__dirname, '../images', name + '.png');\n}\n\n/**\n * Set up mocha with `options`.\n *\n * Options:\n *\n *   - `ui` name \"bdd\", \"tdd\", \"exports\" etc\n *   - `reporter` reporter instance, defaults to `mocha.reporters.spec`\n *   - `globals` array of accepted globals\n *   - `timeout` timeout in milliseconds\n *   - `retries` number of times to retry failed tests\n *   - `bail` bail on the first test failure\n *   - `slow` milliseconds to wait before considering a test slow\n *   - `ignoreLeaks` ignore global leaks\n *   - `fullTrace` display the full stack-trace on failing\n *   - `grep` string or regexp to filter tests with\n *\n * @param {Object} options\n * @api public\n */\nfunction Mocha(options) {\n  options = options || {};\n  this.files = [];\n  this.options = options;\n  if (options.grep) {\n    this.grep(new RegExp(options.grep));\n  }\n  if (options.fgrep) {\n    this.fgrep(options.fgrep);\n  }\n  this.suite = new exports.Suite('', new exports.Context());\n  this.ui(options.ui);\n  this.bail(options.bail);\n  this.reporter(options.reporter, options.reporterOptions);\n  if (typeof options.timeout !== 'undefined' && options.timeout !== null) {\n    this.timeout(options.timeout);\n  }\n  if (typeof options.retries !== 'undefined' && options.retries !== null) {\n    this.retries(options.retries);\n  }\n  this.useColors(options.useColors);\n  if (options.enableTimeouts !== null) {\n    this.enableTimeouts(options.enableTimeouts);\n  }\n  if (options.slow) {\n    this.slow(options.slow);\n  }\n}\n\n/**\n * Enable or disable bailing on the first failure.\n *\n * @api public\n * @param {boolean} [bail]\n */\nMocha.prototype.bail = function(bail) {\n  if (!arguments.length) {\n    bail = true;\n  }\n  this.suite.bail(bail);\n  return this;\n};\n\n/**\n * Add test `file`.\n *\n * @api public\n * @param {string} file\n */\nMocha.prototype.addFile = function(file) {\n  this.files.push(file);\n  return this;\n};\n\n/**\n * Set reporter to `reporter`, defaults to \"spec\".\n *\n * @param {String|Function} reporter name or constructor\n * @param {Object} reporterOptions optional options\n * @api public\n * @param {string|Function} reporter name or constructor\n * @param {Object} reporterOptions optional options\n */\nMocha.prototype.reporter = function(reporter, reporterOptions) {\n  if (typeof reporter === 'function') {\n    this._reporter = reporter;\n  } else {\n    reporter = reporter || 'spec';\n    var _reporter;\n    // Try to load a built-in reporter.\n    if (reporters[reporter]) {\n      _reporter = reporters[reporter];\n    }\n    // Try to load reporters from process.cwd() and node_modules\n    if (!_reporter) {\n      try {\n        _reporter = require(reporter);\n      } catch (err) {\n        err.message.indexOf('Cannot find module') !== -1\n          ? console.warn('\"' + reporter + '\" reporter not found')\n          : console.warn('\"' + reporter + '\" reporter blew up with error:\\n' + err.stack);\n      }\n    }\n    if (!_reporter && reporter === 'teamcity') {\n      console.warn('The Teamcity reporter was moved to a package named '\n        + 'mocha-teamcity-reporter '\n        + '(https://npmjs.org/package/mocha-teamcity-reporter).');\n    }\n    if (!_reporter) {\n      throw new Error('invalid reporter \"' + reporter + '\"');\n    }\n    this._reporter = _reporter;\n  }\n  this.options.reporterOptions = reporterOptions;\n  return this;\n};\n\n/**\n * Set test UI `name`, defaults to \"bdd\".\n *\n * @api public\n * @param {string} bdd\n */\nMocha.prototype.ui = function(name) {\n  name = name || 'bdd';\n  this._ui = exports.interfaces[name];\n  if (!this._ui) {\n    try {\n      this._ui = require(name);\n    } catch (err) {\n      throw new Error('invalid interface \"' + name + '\"');\n    }\n  }\n  this._ui = this._ui(this.suite);\n\n  this.suite.on('pre-require', function(context) {\n    exports.afterEach = context.afterEach || context.teardown;\n    exports.after = context.after || context.suiteTeardown;\n    exports.beforeEach = context.beforeEach || context.setup;\n    exports.before = context.before || context.suiteSetup;\n    exports.describe = context.describe || context.suite;\n    exports.it = context.it || context.test;\n    exports.setup = context.setup || context.beforeEach;\n    exports.suiteSetup = context.suiteSetup || context.before;\n    exports.suiteTeardown = context.suiteTeardown || context.after;\n    exports.suite = context.suite || context.describe;\n    exports.teardown = context.teardown || context.afterEach;\n    exports.test = context.test || context.it;\n    exports.run = context.run;\n  });\n\n  return this;\n};\n\n/**\n * Load registered files.\n *\n * @api private\n */\nMocha.prototype.loadFiles = function(fn) {\n  var self = this;\n  var suite = this.suite;\n  this.files.forEach(function(file) {\n    file = path.resolve(file);\n    suite.emit('pre-require', global, file, self);\n    suite.emit('require', require(file), file, self);\n    suite.emit('post-require', global, file, self);\n  });\n  fn && fn();\n};\n\n/**\n * Enable growl support.\n *\n * @api private\n */\nMocha.prototype._growl = function(runner, reporter) {\n  var notify = require('growl');\n\n  runner.on('end', function() {\n    var stats = reporter.stats;\n    if (stats.failures) {\n      var msg = stats.failures + ' of ' + runner.total + ' tests failed';\n      notify(msg, { name: 'mocha', title: 'Failed', image: image('error') });\n    } else {\n      notify(stats.passes + ' tests passed in ' + stats.duration + 'ms', {\n        name: 'mocha',\n        title: 'Passed',\n        image: image('ok')\n      });\n    }\n  });\n};\n\n/**\n * Escape string and add it to grep as a regexp.\n *\n * @api public\n * @param str\n * @returns {Mocha}\n */\nMocha.prototype.fgrep = function(str) {\n  return this.grep(new RegExp(escapeRe(str)));\n};\n\n/**\n * Add regexp to grep, if `re` is a string it is escaped.\n *\n * @param {RegExp|String} re\n * @return {Mocha}\n * @api public\n * @param {RegExp|string} re\n * @return {Mocha}\n */\nMocha.prototype.grep = function(re) {\n  if (utils.isString(re)) {\n    // extract args if it's regex-like, i.e: [string, pattern, flag]\n    var arg = re.match(/^\\/(.*)\\/(g|i|)$|.*/);\n    this.options.grep = new RegExp(arg[1] || arg[0], arg[2]);\n  } else {\n    this.options.grep = re;\n  }\n  return this;\n};\n/**\n * Invert `.grep()` matches.\n *\n * @return {Mocha}\n * @api public\n */\nMocha.prototype.invert = function() {\n  this.options.invert = true;\n  return this;\n};\n\n/**\n * Ignore global leaks.\n *\n * @param {Boolean} ignore\n * @return {Mocha}\n * @api public\n * @param {boolean} ignore\n * @return {Mocha}\n */\nMocha.prototype.ignoreLeaks = function(ignore) {\n  this.options.ignoreLeaks = Boolean(ignore);\n  return this;\n};\n\n/**\n * Enable global leak checking.\n *\n * @return {Mocha}\n * @api public\n */\nMocha.prototype.checkLeaks = function() {\n  this.options.ignoreLeaks = false;\n  return this;\n};\n\n/**\n * Display long stack-trace on failing\n *\n * @return {Mocha}\n * @api public\n */\nMocha.prototype.fullTrace = function() {\n  this.options.fullStackTrace = true;\n  return this;\n};\n\n/**\n * Enable growl support.\n *\n * @return {Mocha}\n * @api public\n */\nMocha.prototype.growl = function() {\n  this.options.growl = true;\n  return this;\n};\n\n/**\n * Ignore `globals` array or string.\n *\n * @param {Array|String} globals\n * @return {Mocha}\n * @api public\n * @param {Array|string} globals\n * @return {Mocha}\n */\nMocha.prototype.globals = function(globals) {\n  this.options.globals = (this.options.globals || []).concat(globals);\n  return this;\n};\n\n/**\n * Emit color output.\n *\n * @param {Boolean} colors\n * @return {Mocha}\n * @api public\n * @param {boolean} colors\n * @return {Mocha}\n */\nMocha.prototype.useColors = function(colors) {\n  if (colors !== undefined) {\n    this.options.useColors = colors;\n  }\n  return this;\n};\n\n/**\n * Use inline diffs rather than +/-.\n *\n * @param {Boolean} inlineDiffs\n * @return {Mocha}\n * @api public\n * @param {boolean} inlineDiffs\n * @return {Mocha}\n */\nMocha.prototype.useInlineDiffs = function(inlineDiffs) {\n  this.options.useInlineDiffs = inlineDiffs !== undefined && inlineDiffs;\n  return this;\n};\n\n/**\n * Set the timeout in milliseconds.\n *\n * @param {Number} timeout\n * @return {Mocha}\n * @api public\n * @param {number} timeout\n * @return {Mocha}\n */\nMocha.prototype.timeout = function(timeout) {\n  this.suite.timeout(timeout);\n  return this;\n};\n\n/**\n * Set the number of times to retry failed tests.\n *\n * @param {Number} retry times\n * @return {Mocha}\n * @api public\n */\nMocha.prototype.retries = function(n) {\n  this.suite.retries(n);\n  return this;\n};\n\n/**\n * Set slowness threshold in milliseconds.\n *\n * @param {Number} slow\n * @return {Mocha}\n * @api public\n * @param {number} slow\n * @return {Mocha}\n */\nMocha.prototype.slow = function(slow) {\n  this.suite.slow(slow);\n  return this;\n};\n\n/**\n * Enable timeouts.\n *\n * @param {Boolean} enabled\n * @return {Mocha}\n * @api public\n * @param {boolean} enabled\n * @return {Mocha}\n */\nMocha.prototype.enableTimeouts = function(enabled) {\n  this.suite.enableTimeouts(arguments.length && enabled !== undefined ? enabled : true);\n  return this;\n};\n\n/**\n * Makes all tests async (accepting a callback)\n *\n * @return {Mocha}\n * @api public\n */\nMocha.prototype.asyncOnly = function() {\n  this.options.asyncOnly = true;\n  return this;\n};\n\n/**\n * Disable syntax highlighting (in browser).\n *\n * @api public\n */\nMocha.prototype.noHighlighting = function() {\n  this.options.noHighlighting = true;\n  return this;\n};\n\n/**\n * Enable uncaught errors to propagate (in browser).\n *\n * @return {Mocha}\n * @api public\n */\nMocha.prototype.allowUncaught = function() {\n  this.options.allowUncaught = true;\n  return this;\n};\n\n/**\n * Delay root suite execution.\n * @returns {Mocha}\n */\nMocha.prototype.delay = function delay() {\n  this.options.delay = true;\n  return this;\n};\n\n/**\n * Run tests and invoke `fn()` when complete.\n *\n * @api public\n * @param {Function} fn\n * @return {Runner}\n */\nMocha.prototype.run = function(fn) {\n  if (this.files.length) {\n    this.loadFiles();\n  }\n  var suite = this.suite;\n  var options = this.options;\n  options.files = this.files;\n  var runner = new exports.Runner(suite, options.delay);\n  var reporter = new this._reporter(runner, options);\n  runner.ignoreLeaks = options.ignoreLeaks !== false;\n  runner.fullStackTrace = options.fullStackTrace;\n  runner.hasOnly = options.hasOnly;\n  runner.asyncOnly = options.asyncOnly;\n  runner.allowUncaught = options.allowUncaught;\n  if (options.grep) {\n    runner.grep(options.grep, options.invert);\n  }\n  if (options.globals) {\n    runner.globals(options.globals);\n  }\n  if (options.growl) {\n    this._growl(runner, reporter);\n  }\n  if (options.useColors !== undefined) {\n    exports.reporters.Base.useColors = options.useColors;\n  }\n  exports.reporters.Base.inlineDiffs = options.useInlineDiffs;\n\n  function done(failures) {\n    if (reporter.done) {\n      reporter.done(failures, fn);\n    } else {\n      fn && fn(failures);\n    }\n  }\n\n  return runner.run(done);\n};\n\n}).call(this,require('_process'),typeof global !== \"undefined\" ? global : typeof self !== \"undefined\" ? self : typeof window !== \"undefined\" ? window : {},\"/lib\")\n},{\"./context\":6,\"./hook\":7,\"./interfaces\":11,\"./reporters\":21,\"./runnable\":33,\"./runner\":34,\"./suite\":35,\"./test\":36,\"./utils\":38,\"_process\":67,\"escape-string-regexp\":47,\"growl\":49,\"path\":42}],15:[function(require,module,exports){\n/**\n * Helpers.\n */\n\nvar s = 1000;\nvar m = s * 60;\nvar h = m * 60;\nvar d = h * 24;\nvar y = d * 365.25;\n\n/**\n * Parse or format the given `val`.\n *\n * Options:\n *\n *  - `long` verbose formatting [false]\n *\n * @api public\n * @param {string|number} val\n * @param {Object} options\n * @return {string|number}\n */\nmodule.exports = function(val, options) {\n  options = options || {};\n  if (typeof val === 'string') {\n    return parse(val);\n  }\n  // https://github.com/mochajs/mocha/pull/1035\n  return options['long'] ? longFormat(val) : shortFormat(val);\n};\n\n/**\n * Parse the given `str` and return milliseconds.\n *\n * @api private\n * @param {string} str\n * @return {number}\n */\nfunction parse(str) {\n  var match = (/^((?:\\d+)?\\.?\\d+) *(ms|seconds?|s|minutes?|m|hours?|h|days?|d|years?|y)?$/i).exec(str);\n  if (!match) {\n    return;\n  }\n  var n = parseFloat(match[1]);\n  var type = (match[2] || 'ms').toLowerCase();\n  switch (type) {\n    case 'years':\n    case 'year':\n    case 'y':\n      return n * y;\n    case 'days':\n    case 'day':\n    case 'd':\n      return n * d;\n    case 'hours':\n    case 'hour':\n    case 'h':\n      return n * h;\n    case 'minutes':\n    case 'minute':\n    case 'm':\n      return n * m;\n    case 'seconds':\n    case 'second':\n    case 's':\n      return n * s;\n    case 'ms':\n      return n;\n    default:\n      // No default case\n  }\n}\n\n/**\n * Short format for `ms`.\n *\n * @api private\n * @param {number} ms\n * @return {string}\n */\nfunction shortFormat(ms) {\n  if (ms >= d) {\n    return Math.round(ms / d) + 'd';\n  }\n  if (ms >= h) {\n    return Math.round(ms / h) + 'h';\n  }\n  if (ms >= m) {\n    return Math.round(ms / m) + 'm';\n  }\n  if (ms >= s) {\n    return Math.round(ms / s) + 's';\n  }\n  return ms + 'ms';\n}\n\n/**\n * Long format for `ms`.\n *\n * @api private\n * @param {number} ms\n * @return {string}\n */\nfunction longFormat(ms) {\n  return plural(ms, d, 'day')\n    || plural(ms, h, 'hour')\n    || plural(ms, m, 'minute')\n    || plural(ms, s, 'second')\n    || ms + ' ms';\n}\n\n/**\n * Pluralization helper.\n *\n * @api private\n * @param {number} ms\n * @param {number} n\n * @param {string} name\n */\nfunction plural(ms, n, name) {\n  if (ms < n) {\n    return;\n  }\n  if (ms < n * 1.5) {\n    return Math.floor(ms / n) + ' ' + name;\n  }\n  return Math.ceil(ms / n) + ' ' + name + 's';\n}\n\n},{}],16:[function(require,module,exports){\n\n/**\n * Expose `Pending`.\n */\n\nmodule.exports = Pending;\n\n/**\n * Initialize a new `Pending` error with the given message.\n *\n * @param {string} message\n */\nfunction Pending(message) {\n  this.message = message;\n}\n\n},{}],17:[function(require,module,exports){\n(function (process,global){\n/**\n * Module dependencies.\n */\n\nvar tty = require('tty');\nvar diff = require('diff');\nvar ms = require('../ms');\nvar utils = require('../utils');\nvar supportsColor = process.browser ? null : require('supports-color');\n\n/**\n * Expose `Base`.\n */\n\nexports = module.exports = Base;\n\n/**\n * Save timer references to avoid Sinon interfering.\n * See: https://github.com/mochajs/mocha/issues/237\n */\n\n/* eslint-disable no-unused-vars, no-native-reassign */\nvar Date = global.Date;\nvar setTimeout = global.setTimeout;\nvar setInterval = global.setInterval;\nvar clearTimeout = global.clearTimeout;\nvar clearInterval = global.clearInterval;\n/* eslint-enable no-unused-vars, no-native-reassign */\n\n/**\n * Check if both stdio streams are associated with a tty.\n */\n\nvar isatty = tty.isatty(1) && tty.isatty(2);\n\n/**\n * Enable coloring by default, except in the browser interface.\n */\n\nexports.useColors = !process.browser && (supportsColor || (process.env.MOCHA_COLORS !== undefined));\n\n/**\n * Inline diffs instead of +/-\n */\n\nexports.inlineDiffs = false;\n\n/**\n * Default color map.\n */\n\nexports.colors = {\n  pass: 90,\n  fail: 31,\n  'bright pass': 92,\n  'bright fail': 91,\n  'bright yellow': 93,\n  pending: 36,\n  suite: 0,\n  'error title': 0,\n  'error message': 31,\n  'error stack': 90,\n  checkmark: 32,\n  fast: 90,\n  medium: 33,\n  slow: 31,\n  green: 32,\n  light: 90,\n  'diff gutter': 90,\n  'diff added': 32,\n  'diff removed': 31\n};\n\n/**\n * Default symbol map.\n */\n\nexports.symbols = {\n  ok: '✓',\n  err: '✖',\n  dot: '․',\n  comma: ',',\n  bang: '!'\n};\n\n// With node.js on Windows: use symbols available in terminal default fonts\nif (process.platform === 'win32') {\n  exports.symbols.ok = '\\u221A';\n  exports.symbols.err = '\\u00D7';\n  exports.symbols.dot = '.';\n}\n\n/**\n * Color `str` with the given `type`,\n * allowing colors to be disabled,\n * as well as user-defined color\n * schemes.\n *\n * @param {string} type\n * @param {string} str\n * @return {string}\n * @api private\n */\nvar color = exports.color = function(type, str) {\n  if (!exports.useColors) {\n    return String(str);\n  }\n  return '\\u001b[' + exports.colors[type] + 'm' + str + '\\u001b[0m';\n};\n\n/**\n * Expose term window size, with some defaults for when stderr is not a tty.\n */\n\nexports.window = {\n  width: 75\n};\n\nif (isatty) {\n  exports.window.width = process.stdout.getWindowSize\n      ? process.stdout.getWindowSize(1)[0]\n      : tty.getWindowSize()[1];\n}\n\n/**\n * Expose some basic cursor interactions that are common among reporters.\n */\n\nexports.cursor = {\n  hide: function() {\n    isatty && process.stdout.write('\\u001b[?25l');\n  },\n\n  show: function() {\n    isatty && process.stdout.write('\\u001b[?25h');\n  },\n\n  deleteLine: function() {\n    isatty && process.stdout.write('\\u001b[2K');\n  },\n\n  beginningOfLine: function() {\n    isatty && process.stdout.write('\\u001b[0G');\n  },\n\n  CR: function() {\n    if (isatty) {\n      exports.cursor.deleteLine();\n      exports.cursor.beginningOfLine();\n    } else {\n      process.stdout.write('\\r');\n    }\n  }\n};\n\n/**\n * Outut the given `failures` as a list.\n *\n * @param {Array} failures\n * @api public\n */\n\nexports.list = function(failures) {\n  console.log();\n  failures.forEach(function(test, i) {\n    // format\n    var fmt = color('error title', '  %s) %s:\\n')\n      + color('error message', '     %s')\n      + color('error stack', '\\n%s\\n');\n\n    // msg\n    var msg;\n    var err = test.err;\n    var message;\n    if (err.message && typeof err.message.toString === 'function') {\n      message = err.message + '';\n    } else if (typeof err.inspect === 'function') {\n      message = err.inspect() + '';\n    } else {\n      message = '';\n    }\n    var stack = err.stack || message;\n    var index = message ? stack.indexOf(message) : -1;\n    var actual = err.actual;\n    var expected = err.expected;\n    var escape = true;\n\n    if (index === -1) {\n      msg = message;\n    } else {\n      index += message.length;\n      msg = stack.slice(0, index);\n      // remove msg from stack\n      stack = stack.slice(index + 1);\n    }\n\n    // uncaught\n    if (err.uncaught) {\n      msg = 'Uncaught ' + msg;\n    }\n    // explicitly show diff\n    if (err.showDiff !== false && sameType(actual, expected) && expected !== undefined) {\n      escape = false;\n      if (!(utils.isString(actual) && utils.isString(expected))) {\n        err.actual = actual = utils.stringify(actual);\n        err.expected = expected = utils.stringify(expected);\n      }\n\n      fmt = color('error title', '  %s) %s:\\n%s') + color('error stack', '\\n%s\\n');\n      var match = message.match(/^([^:]+): expected/);\n      msg = '\\n      ' + color('error message', match ? match[1] : msg);\n\n      if (exports.inlineDiffs) {\n        msg += inlineDiff(err, escape);\n      } else {\n        msg += unifiedDiff(err, escape);\n      }\n    }\n\n    // indent stack trace\n    stack = stack.replace(/^/gm, '  ');\n\n    console.log(fmt, (i + 1), test.fullTitle(), msg, stack);\n  });\n};\n\n/**\n * Initialize a new `Base` reporter.\n *\n * All other reporters generally\n * inherit from this reporter, providing\n * stats such as test duration, number\n * of tests passed / failed etc.\n *\n * @param {Runner} runner\n * @api public\n */\n\nfunction Base(runner) {\n  var stats = this.stats = { suites: 0, tests: 0, passes: 0, pending: 0, failures: 0 };\n  var failures = this.failures = [];\n\n  if (!runner) {\n    return;\n  }\n  this.runner = runner;\n\n  runner.stats = stats;\n\n  runner.on('start', function() {\n    stats.start = new Date();\n  });\n\n  runner.on('suite', function(suite) {\n    stats.suites = stats.suites || 0;\n    suite.root || stats.suites++;\n  });\n\n  runner.on('test end', function() {\n    stats.tests = stats.tests || 0;\n    stats.tests++;\n  });\n\n  runner.on('pass', function(test) {\n    stats.passes = stats.passes || 0;\n\n    if (test.duration > test.slow()) {\n      test.speed = 'slow';\n    } else if (test.duration > test.slow() / 2) {\n      test.speed = 'medium';\n    } else {\n      test.speed = 'fast';\n    }\n\n    stats.passes++;\n  });\n\n  runner.on('fail', function(test, err) {\n    stats.failures = stats.failures || 0;\n    stats.failures++;\n    test.err = err;\n    failures.push(test);\n  });\n\n  runner.on('end', function() {\n    stats.end = new Date();\n    stats.duration = new Date() - stats.start;\n  });\n\n  runner.on('pending', function() {\n    stats.pending++;\n  });\n}\n\n/**\n * Output common epilogue used by many of\n * the bundled reporters.\n *\n * @api public\n */\nBase.prototype.epilogue = function() {\n  var stats = this.stats;\n  var fmt;\n\n  console.log();\n\n  // passes\n  fmt = color('bright pass', ' ')\n    + color('green', ' %d passing')\n    + color('light', ' (%s)');\n\n  console.log(fmt,\n    stats.passes || 0,\n    ms(stats.duration));\n\n  // pending\n  if (stats.pending) {\n    fmt = color('pending', ' ')\n      + color('pending', ' %d pending');\n\n    console.log(fmt, stats.pending);\n  }\n\n  // failures\n  if (stats.failures) {\n    fmt = color('fail', '  %d failing');\n\n    console.log(fmt, stats.failures);\n\n    Base.list(this.failures);\n    console.log();\n  }\n\n  console.log();\n};\n\n/**\n * Pad the given `str` to `len`.\n *\n * @api private\n * @param {string} str\n * @param {string} len\n * @return {string}\n */\nfunction pad(str, len) {\n  str = String(str);\n  return Array(len - str.length + 1).join(' ') + str;\n}\n\n/**\n * Returns an inline diff between 2 strings with coloured ANSI output\n *\n * @api private\n * @param {Error} err with actual/expected\n * @param {boolean} escape\n * @return {string} Diff\n */\nfunction inlineDiff(err, escape) {\n  var msg = errorDiff(err, 'WordsWithSpace', escape);\n\n  // linenos\n  var lines = msg.split('\\n');\n  if (lines.length > 4) {\n    var width = String(lines.length).length;\n    msg = lines.map(function(str, i) {\n      return pad(++i, width) + ' |' + ' ' + str;\n    }).join('\\n');\n  }\n\n  // legend\n  msg = '\\n'\n    + color('diff removed', 'actual')\n    + ' '\n    + color('diff added', 'expected')\n    + '\\n\\n'\n    + msg\n    + '\\n';\n\n  // indent\n  msg = msg.replace(/^/gm, '      ');\n  return msg;\n}\n\n/**\n * Returns a unified diff between two strings.\n *\n * @api private\n * @param {Error} err with actual/expected\n * @param {boolean} escape\n * @return {string} The diff.\n */\nfunction unifiedDiff(err, escape) {\n  var indent = '      ';\n  function cleanUp(line) {\n    if (escape) {\n      line = escapeInvisibles(line);\n    }\n    if (line[0] === '+') {\n      return indent + colorLines('diff added', line);\n    }\n    if (line[0] === '-') {\n      return indent + colorLines('diff removed', line);\n    }\n    if (line.match(/\\@\\@/)) {\n      return null;\n    }\n    if (line.match(/\\\\ No newline/)) {\n      return null;\n    }\n    return indent + line;\n  }\n  function notBlank(line) {\n    return typeof line !== 'undefined' && line !== null;\n  }\n  var msg = diff.createPatch('string', err.actual, err.expected);\n  var lines = msg.split('\\n').splice(4);\n  return '\\n      '\n    + colorLines('diff added', '+ expected') + ' '\n    + colorLines('diff removed', '- actual')\n    + '\\n\\n'\n    + lines.map(cleanUp).filter(notBlank).join('\\n');\n}\n\n/**\n * Return a character diff for `err`.\n *\n * @api private\n * @param {Error} err\n * @param {string} type\n * @param {boolean} escape\n * @return {string}\n */\nfunction errorDiff(err, type, escape) {\n  var actual = escape ? escapeInvisibles(err.actual) : err.actual;\n  var expected = escape ? escapeInvisibles(err.expected) : err.expected;\n  return diff['diff' + type](actual, expected).map(function(str) {\n    if (str.added) {\n      return colorLines('diff added', str.value);\n    }\n    if (str.removed) {\n      return colorLines('diff removed', str.value);\n    }\n    return str.value;\n  }).join('');\n}\n\n/**\n * Returns a string with all invisible characters in plain text\n *\n * @api private\n * @param {string} line\n * @return {string}\n */\nfunction escapeInvisibles(line) {\n  return line.replace(/\\t/g, '<tab>')\n    .replace(/\\r/g, '<CR>')\n    .replace(/\\n/g, '<LF>\\n');\n}\n\n/**\n * Color lines for `str`, using the color `name`.\n *\n * @api private\n * @param {string} name\n * @param {string} str\n * @return {string}\n */\nfunction colorLines(name, str) {\n  return str.split('\\n').map(function(str) {\n    return color(name, str);\n  }).join('\\n');\n}\n\n/**\n * Object#toString reference.\n */\nvar objToString = Object.prototype.toString;\n\n/**\n * Check that a / b have the same type.\n *\n * @api private\n * @param {Object} a\n * @param {Object} b\n * @return {boolean}\n */\nfunction sameType(a, b) {\n  return objToString.call(a) === objToString.call(b);\n}\n\n}).call(this,require('_process'),typeof global !== \"undefined\" ? global : typeof self !== \"undefined\" ? self : typeof window !== \"undefined\" ? window : {})\n},{\"../ms\":15,\"../utils\":38,\"_process\":67,\"diff\":46,\"supports-color\":42,\"tty\":5}],18:[function(require,module,exports){\n/**\n * Module dependencies.\n */\n\nvar Base = require('./base');\nvar utils = require('../utils');\n\n/**\n * Expose `Doc`.\n */\n\nexports = module.exports = Doc;\n\n/**\n * Initialize a new `Doc` reporter.\n *\n * @param {Runner} runner\n * @api public\n */\nfunction Doc(runner) {\n  Base.call(this, runner);\n\n  var indents = 2;\n\n  function indent() {\n    return Array(indents).join('  ');\n  }\n\n  runner.on('suite', function(suite) {\n    if (suite.root) {\n      return;\n    }\n    ++indents;\n    console.log('%s<section class=\"suite\">', indent());\n    ++indents;\n    console.log('%s<h1>%s</h1>', indent(), utils.escape(suite.title));\n    console.log('%s<dl>', indent());\n  });\n\n  runner.on('suite end', function(suite) {\n    if (suite.root) {\n      return;\n    }\n    console.log('%s</dl>', indent());\n    --indents;\n    console.log('%s</section>', indent());\n    --indents;\n  });\n\n  runner.on('pass', function(test) {\n    console.log('%s  <dt>%s</dt>', indent(), utils.escape(test.title));\n    var code = utils.escape(utils.clean(test.body));\n    console.log('%s  <dd><pre><code>%s</code></pre></dd>', indent(), code);\n  });\n\n  runner.on('fail', function(test, err) {\n    console.log('%s  <dt class=\"error\">%s</dt>', indent(), utils.escape(test.title));\n    var code = utils.escape(utils.clean(test.body));\n    console.log('%s  <dd class=\"error\"><pre><code>%s</code></pre></dd>', indent(), code);\n    console.log('%s  <dd class=\"error\">%s</dd>', indent(), utils.escape(err));\n  });\n}\n\n},{\"../utils\":38,\"./base\":17}],19:[function(require,module,exports){\n(function (process){\n/**\n * Module dependencies.\n */\n\nvar Base = require('./base');\nvar inherits = require('../utils').inherits;\nvar color = Base.color;\n\n/**\n * Expose `Dot`.\n */\n\nexports = module.exports = Dot;\n\n/**\n * Initialize a new `Dot` matrix test reporter.\n *\n * @api public\n * @param {Runner} runner\n */\nfunction Dot(runner) {\n  Base.call(this, runner);\n\n  var self = this;\n  var width = Base.window.width * .75 | 0;\n  var n = -1;\n\n  runner.on('start', function() {\n    process.stdout.write('\\n');\n  });\n\n  runner.on('pending', function() {\n    if (++n % width === 0) {\n      process.stdout.write('\\n  ');\n    }\n    process.stdout.write(color('pending', Base.symbols.comma));\n  });\n\n  runner.on('pass', function(test) {\n    if (++n % width === 0) {\n      process.stdout.write('\\n  ');\n    }\n    if (test.speed === 'slow') {\n      process.stdout.write(color('bright yellow', Base.symbols.dot));\n    } else {\n      process.stdout.write(color(test.speed, Base.symbols.dot));\n    }\n  });\n\n  runner.on('fail', function() {\n    if (++n % width === 0) {\n      process.stdout.write('\\n  ');\n    }\n    process.stdout.write(color('fail', Base.symbols.bang));\n  });\n\n  runner.on('end', function() {\n    console.log();\n    self.epilogue();\n  });\n}\n\n/**\n * Inherit from `Base.prototype`.\n */\ninherits(Dot, Base);\n\n}).call(this,require('_process'))\n},{\"../utils\":38,\"./base\":17,\"_process\":67}],20:[function(require,module,exports){\n(function (global){\n/* eslint-env browser */\n\n/**\n * Module dependencies.\n */\n\nvar Base = require('./base');\nvar utils = require('../utils');\nvar Progress = require('../browser/progress');\nvar escapeRe = require('escape-string-regexp');\nvar escape = utils.escape;\n\n/**\n * Save timer references to avoid Sinon interfering (see GH-237).\n */\n\n/* eslint-disable no-unused-vars, no-native-reassign */\nvar Date = global.Date;\nvar setTimeout = global.setTimeout;\nvar setInterval = global.setInterval;\nvar clearTimeout = global.clearTimeout;\nvar clearInterval = global.clearInterval;\n/* eslint-enable no-unused-vars, no-native-reassign */\n\n/**\n * Expose `HTML`.\n */\n\nexports = module.exports = HTML;\n\n/**\n * Stats template.\n */\n\nvar statsTemplate = '<ul id=\"mocha-stats\">'\n  + '<li class=\"progress\"><canvas width=\"40\" height=\"40\"></canvas></li>'\n  + '<li class=\"passes\"><a href=\"javascript:void(0);\">passes:</a> <em>0</em></li>'\n  + '<li class=\"failures\"><a href=\"javascript:void(0);\">failures:</a> <em>0</em></li>'\n  + '<li class=\"duration\">duration: <em>0</em>s</li>'\n  + '</ul>';\n\n/**\n * Initialize a new `HTML` reporter.\n *\n * @api public\n * @param {Runner} runner\n */\nfunction HTML(runner) {\n  Base.call(this, runner);\n\n  var self = this;\n  var stats = this.stats;\n  var stat = fragment(statsTemplate);\n  var items = stat.getElementsByTagName('li');\n  var passes = items[1].getElementsByTagName('em')[0];\n  var passesLink = items[1].getElementsByTagName('a')[0];\n  var failures = items[2].getElementsByTagName('em')[0];\n  var failuresLink = items[2].getElementsByTagName('a')[0];\n  var duration = items[3].getElementsByTagName('em')[0];\n  var canvas = stat.getElementsByTagName('canvas')[0];\n  var report = fragment('<ul id=\"mocha-report\"></ul>');\n  var stack = [report];\n  var progress;\n  var ctx;\n  var root = document.getElementById('mocha');\n\n  if (canvas.getContext) {\n    var ratio = window.devicePixelRatio || 1;\n    canvas.style.width = canvas.width;\n    canvas.style.height = canvas.height;\n    canvas.width *= ratio;\n    canvas.height *= ratio;\n    ctx = canvas.getContext('2d');\n    ctx.scale(ratio, ratio);\n    progress = new Progress();\n  }\n\n  if (!root) {\n    return error('#mocha div missing, add it to your document');\n  }\n\n  // pass toggle\n  on(passesLink, 'click', function(evt) {\n    evt.preventDefault();\n    unhide();\n    var name = (/pass/).test(report.className) ? '' : ' pass';\n    report.className = report.className.replace(/fail|pass/g, '') + name;\n    if (report.className.trim()) {\n      hideSuitesWithout('test pass');\n    }\n  });\n\n  // failure toggle\n  on(failuresLink, 'click', function(evt) {\n    evt.preventDefault();\n    unhide();\n    var name = (/fail/).test(report.className) ? '' : ' fail';\n    report.className = report.className.replace(/fail|pass/g, '') + name;\n    if (report.className.trim()) {\n      hideSuitesWithout('test fail');\n    }\n  });\n\n  root.appendChild(stat);\n  root.appendChild(report);\n\n  if (progress) {\n    progress.size(40);\n  }\n\n  runner.on('suite', function(suite) {\n    if (suite.root) {\n      return;\n    }\n\n    // suite\n    var url = self.suiteURL(suite);\n    var el = fragment('<li class=\"suite\"><h1><a href=\"%s\">%s</a></h1></li>', url, escape(suite.title));\n\n    // container\n    stack[0].appendChild(el);\n    stack.unshift(document.createElement('ul'));\n    el.appendChild(stack[0]);\n  });\n\n  runner.on('suite end', function(suite) {\n    if (suite.root) {\n      updateStats();\n      return;\n    }\n    stack.shift();\n  });\n\n  runner.on('pass', function(test) {\n    var url = self.testURL(test);\n    var markup = '<li class=\"test pass %e\"><h2>%e<span class=\"duration\">%ems</span> '\n      + '<a href=\"%s\" class=\"replay\">‣</a></h2></li>';\n    var el = fragment(markup, test.speed, test.title, test.duration, url);\n    self.addCodeToggle(el, test.body);\n    appendToStack(el);\n    updateStats();\n  });\n\n  runner.on('fail', function(test) {\n    var el = fragment('<li class=\"test fail\"><h2>%e <a href=\"%e\" class=\"replay\">‣</a></h2></li>',\n      test.title, self.testURL(test));\n    var stackString; // Note: Includes leading newline\n    var message = test.err.toString();\n\n    // <=IE7 stringifies to [Object Error]. Since it can be overloaded, we\n    // check for the result of the stringifying.\n    if (message === '[object Error]') {\n      message = test.err.message;\n    }\n\n    if (test.err.stack) {\n      var indexOfMessage = test.err.stack.indexOf(test.err.message);\n      if (indexOfMessage === -1) {\n        stackString = test.err.stack;\n      } else {\n        stackString = test.err.stack.substr(test.err.message.length + indexOfMessage);\n      }\n    } else if (test.err.sourceURL && test.err.line !== undefined) {\n      // Safari doesn't give you a stack. Let's at least provide a source line.\n      stackString = '\\n(' + test.err.sourceURL + ':' + test.err.line + ')';\n    }\n\n    stackString = stackString || '';\n\n    if (test.err.htmlMessage && stackString) {\n      el.appendChild(fragment('<div class=\"html-error\">%s\\n<pre class=\"error\">%e</pre></div>',\n        test.err.htmlMessage, stackString));\n    } else if (test.err.htmlMessage) {\n      el.appendChild(fragment('<div class=\"html-error\">%s</div>', test.err.htmlMessage));\n    } else {\n      el.appendChild(fragment('<pre class=\"error\">%e%e</pre>', message, stackString));\n    }\n\n    self.addCodeToggle(el, test.body);\n    appendToStack(el);\n    updateStats();\n  });\n\n  runner.on('pending', function(test) {\n    var el = fragment('<li class=\"test pass pending\"><h2>%e</h2></li>', test.title);\n    appendToStack(el);\n    updateStats();\n  });\n\n  function appendToStack(el) {\n    // Don't call .appendChild if #mocha-report was already .shift()'ed off the stack.\n    if (stack[0]) {\n      stack[0].appendChild(el);\n    }\n  }\n\n  function updateStats() {\n    // TODO: add to stats\n    var percent = stats.tests / runner.total * 100 | 0;\n    if (progress) {\n      progress.update(percent).draw(ctx);\n    }\n\n    // update stats\n    var ms = new Date() - stats.start;\n    text(passes, stats.passes);\n    text(failures, stats.failures);\n    text(duration, (ms / 1000).toFixed(2));\n  }\n}\n\n/**\n * Makes a URL, preserving querystring (\"search\") parameters.\n *\n * @param {string} s\n * @return {string} A new URL.\n */\nfunction makeUrl(s) {\n  var search = window.location.search;\n\n  // Remove previous grep query parameter if present\n  if (search) {\n    search = search.replace(/[?&]grep=[^&\\s]*/g, '').replace(/^&/, '?');\n  }\n\n  return window.location.pathname + (search ? search + '&' : '?') + 'grep=' + encodeURIComponent(escapeRe(s));\n}\n\n/**\n * Provide suite URL.\n *\n * @param {Object} [suite]\n */\nHTML.prototype.suiteURL = function(suite) {\n  return makeUrl(suite.fullTitle());\n};\n\n/**\n * Provide test URL.\n *\n * @param {Object} [test]\n */\nHTML.prototype.testURL = function(test) {\n  return makeUrl(test.fullTitle());\n};\n\n/**\n * Adds code toggle functionality for the provided test's list element.\n *\n * @param {HTMLLIElement} el\n * @param {string} contents\n */\nHTML.prototype.addCodeToggle = function(el, contents) {\n  var h2 = el.getElementsByTagName('h2')[0];\n\n  on(h2, 'click', function() {\n    pre.style.display = pre.style.display === 'none' ? 'block' : 'none';\n  });\n\n  var pre = fragment('<pre><code>%e</code></pre>', utils.clean(contents));\n  el.appendChild(pre);\n  pre.style.display = 'none';\n};\n\n/**\n * Display error `msg`.\n *\n * @param {string} msg\n */\nfunction error(msg) {\n  document.body.appendChild(fragment('<div id=\"mocha-error\">%s</div>', msg));\n}\n\n/**\n * Return a DOM fragment from `html`.\n *\n * @param {string} html\n */\nfunction fragment(html) {\n  var args = arguments;\n  var div = document.createElement('div');\n  var i = 1;\n\n  div.innerHTML = html.replace(/%([se])/g, function(_, type) {\n    switch (type) {\n      case 's': return String(args[i++]);\n      case 'e': return escape(args[i++]);\n      // no default\n    }\n  });\n\n  return div.firstChild;\n}\n\n/**\n * Check for suites that do not have elements\n * with `classname`, and hide them.\n *\n * @param {text} classname\n */\nfunction hideSuitesWithout(classname) {\n  var suites = document.getElementsByClassName('suite');\n  for (var i = 0; i < suites.length; i++) {\n    var els = suites[i].getElementsByClassName(classname);\n    if (!els.length) {\n      suites[i].className += ' hidden';\n    }\n  }\n}\n\n/**\n * Unhide .hidden suites.\n */\nfunction unhide() {\n  var els = document.getElementsByClassName('suite hidden');\n  for (var i = 0; i < els.length; ++i) {\n    els[i].className = els[i].className.replace('suite hidden', 'suite');\n  }\n}\n\n/**\n * Set an element's text contents.\n *\n * @param {HTMLElement} el\n * @param {string} contents\n */\nfunction text(el, contents) {\n  if (el.textContent) {\n    el.textContent = contents;\n  } else {\n    el.innerText = contents;\n  }\n}\n\n/**\n * Listen on `event` with callback `fn`.\n */\nfunction on(el, event, fn) {\n  if (el.addEventListener) {\n    el.addEventListener(event, fn, false);\n  } else {\n    el.attachEvent('on' + event, fn);\n  }\n}\n\n}).call(this,typeof global !== \"undefined\" ? global : typeof self !== \"undefined\" ? self : typeof window !== \"undefined\" ? window : {})\n},{\"../browser/progress\":4,\"../utils\":38,\"./base\":17,\"escape-string-regexp\":47}],21:[function(require,module,exports){\n// Alias exports to a their normalized format Mocha#reporter to prevent a need\n// for dynamic (try/catch) requires, which Browserify doesn't handle.\nexports.Base = exports.base = require('./base');\nexports.Dot = exports.dot = require('./dot');\nexports.Doc = exports.doc = require('./doc');\nexports.TAP = exports.tap = require('./tap');\nexports.JSON = exports.json = require('./json');\nexports.HTML = exports.html = require('./html');\nexports.List = exports.list = require('./list');\nexports.Min = exports.min = require('./min');\nexports.Spec = exports.spec = require('./spec');\nexports.Nyan = exports.nyan = require('./nyan');\nexports.XUnit = exports.xunit = require('./xunit');\nexports.Markdown = exports.markdown = require('./markdown');\nexports.Progress = exports.progress = require('./progress');\nexports.Landing = exports.landing = require('./landing');\nexports.JSONStream = exports['json-stream'] = require('./json-stream');\n\n},{\"./base\":17,\"./doc\":18,\"./dot\":19,\"./html\":20,\"./json\":23,\"./json-stream\":22,\"./landing\":24,\"./list\":25,\"./markdown\":26,\"./min\":27,\"./nyan\":28,\"./progress\":29,\"./spec\":30,\"./tap\":31,\"./xunit\":32}],22:[function(require,module,exports){\n(function (process){\n/**\n * Module dependencies.\n */\n\nvar Base = require('./base');\nvar JSON = require('json3');\n\n/**\n * Expose `List`.\n */\n\nexports = module.exports = List;\n\n/**\n * Initialize a new `List` test reporter.\n *\n * @api public\n * @param {Runner} runner\n */\nfunction List(runner) {\n  Base.call(this, runner);\n\n  var self = this;\n  var total = runner.total;\n\n  runner.on('start', function() {\n    console.log(JSON.stringify(['start', { total: total }]));\n  });\n\n  runner.on('pass', function(test) {\n    console.log(JSON.stringify(['pass', clean(test)]));\n  });\n\n  runner.on('fail', function(test, err) {\n    test = clean(test);\n    test.err = err.message;\n    test.stack = err.stack || null;\n    console.log(JSON.stringify(['fail', test]));\n  });\n\n  runner.on('end', function() {\n    process.stdout.write(JSON.stringify(['end', self.stats]));\n  });\n}\n\n/**\n * Return a plain-object representation of `test`\n * free of cyclic properties etc.\n *\n * @api private\n * @param {Object} test\n * @return {Object}\n */\nfunction clean(test) {\n  return {\n    title: test.title,\n    fullTitle: test.fullTitle(),\n    duration: test.duration,\n    currentRetry: test.currentRetry()\n  };\n}\n\n}).call(this,require('_process'))\n},{\"./base\":17,\"_process\":67,\"json3\":54}],23:[function(require,module,exports){\n(function (process){\n/**\n * Module dependencies.\n */\n\nvar Base = require('./base');\n\n/**\n * Expose `JSON`.\n */\n\nexports = module.exports = JSONReporter;\n\n/**\n * Initialize a new `JSON` reporter.\n *\n * @api public\n * @param {Runner} runner\n */\nfunction JSONReporter(runner) {\n  Base.call(this, runner);\n\n  var self = this;\n  var tests = [];\n  var pending = [];\n  var failures = [];\n  var passes = [];\n\n  runner.on('test end', function(test) {\n    tests.push(test);\n  });\n\n  runner.on('pass', function(test) {\n    passes.push(test);\n  });\n\n  runner.on('fail', function(test) {\n    failures.push(test);\n  });\n\n  runner.on('pending', function(test) {\n    pending.push(test);\n  });\n\n  runner.on('end', function() {\n    var obj = {\n      stats: self.stats,\n      tests: tests.map(clean),\n      pending: pending.map(clean),\n      failures: failures.map(clean),\n      passes: passes.map(clean)\n    };\n\n    runner.testResults = obj;\n\n    process.stdout.write(JSON.stringify(obj, null, 2));\n  });\n}\n\n/**\n * Return a plain-object representation of `test`\n * free of cyclic properties etc.\n *\n * @api private\n * @param {Object} test\n * @return {Object}\n */\nfunction clean(test) {\n  return {\n    title: test.title,\n    fullTitle: test.fullTitle(),\n    duration: test.duration,\n    currentRetry: test.currentRetry(),\n    err: errorJSON(test.err || {})\n  };\n}\n\n/**\n * Transform `error` into a JSON object.\n *\n * @api private\n * @param {Error} err\n * @return {Object}\n */\nfunction errorJSON(err) {\n  var res = {};\n  Object.getOwnPropertyNames(err).forEach(function(key) {\n    res[key] = err[key];\n  }, err);\n  return res;\n}\n\n}).call(this,require('_process'))\n},{\"./base\":17,\"_process\":67}],24:[function(require,module,exports){\n(function (process){\n/**\n * Module dependencies.\n */\n\nvar Base = require('./base');\nvar inherits = require('../utils').inherits;\nvar cursor = Base.cursor;\nvar color = Base.color;\n\n/**\n * Expose `Landing`.\n */\n\nexports = module.exports = Landing;\n\n/**\n * Airplane color.\n */\n\nBase.colors.plane = 0;\n\n/**\n * Airplane crash color.\n */\n\nBase.colors['plane crash'] = 31;\n\n/**\n * Runway color.\n */\n\nBase.colors.runway = 90;\n\n/**\n * Initialize a new `Landing` reporter.\n *\n * @api public\n * @param {Runner} runner\n */\nfunction Landing(runner) {\n  Base.call(this, runner);\n\n  var self = this;\n  var width = Base.window.width * .75 | 0;\n  var total = runner.total;\n  var stream = process.stdout;\n  var plane = color('plane', '✈');\n  var crashed = -1;\n  var n = 0;\n\n  function runway() {\n    var buf = Array(width).join('-');\n    return '  ' + color('runway', buf);\n  }\n\n  runner.on('start', function() {\n    stream.write('\\n\\n\\n  ');\n    cursor.hide();\n  });\n\n  runner.on('test end', function(test) {\n    // check if the plane crashed\n    var col = crashed === -1 ? width * ++n / total | 0 : crashed;\n\n    // show the crash\n    if (test.state === 'failed') {\n      plane = color('plane crash', '✈');\n      crashed = col;\n    }\n\n    // render landing strip\n    stream.write('\\u001b[' + (width + 1) + 'D\\u001b[2A');\n    stream.write(runway());\n    stream.write('\\n  ');\n    stream.write(color('runway', Array(col).join('⋅')));\n    stream.write(plane);\n    stream.write(color('runway', Array(width - col).join('⋅') + '\\n'));\n    stream.write(runway());\n    stream.write('\\u001b[0m');\n  });\n\n  runner.on('end', function() {\n    cursor.show();\n    console.log();\n    self.epilogue();\n  });\n}\n\n/**\n * Inherit from `Base.prototype`.\n */\ninherits(Landing, Base);\n\n}).call(this,require('_process'))\n},{\"../utils\":38,\"./base\":17,\"_process\":67}],25:[function(require,module,exports){\n(function (process){\n/**\n * Module dependencies.\n */\n\nvar Base = require('./base');\nvar inherits = require('../utils').inherits;\nvar color = Base.color;\nvar cursor = Base.cursor;\n\n/**\n * Expose `List`.\n */\n\nexports = module.exports = List;\n\n/**\n * Initialize a new `List` test reporter.\n *\n * @api public\n * @param {Runner} runner\n */\nfunction List(runner) {\n  Base.call(this, runner);\n\n  var self = this;\n  var n = 0;\n\n  runner.on('start', function() {\n    console.log();\n  });\n\n  runner.on('test', function(test) {\n    process.stdout.write(color('pass', '    ' + test.fullTitle() + ': '));\n  });\n\n  runner.on('pending', function(test) {\n    var fmt = color('checkmark', '  -')\n      + color('pending', ' %s');\n    console.log(fmt, test.fullTitle());\n  });\n\n  runner.on('pass', function(test) {\n    var fmt = color('checkmark', '  ' + Base.symbols.dot)\n      + color('pass', ' %s: ')\n      + color(test.speed, '%dms');\n    cursor.CR();\n    console.log(fmt, test.fullTitle(), test.duration);\n  });\n\n  runner.on('fail', function(test) {\n    cursor.CR();\n    console.log(color('fail', '  %d) %s'), ++n, test.fullTitle());\n  });\n\n  runner.on('end', self.epilogue.bind(self));\n}\n\n/**\n * Inherit from `Base.prototype`.\n */\ninherits(List, Base);\n\n}).call(this,require('_process'))\n},{\"../utils\":38,\"./base\":17,\"_process\":67}],26:[function(require,module,exports){\n(function (process){\n/**\n * Module dependencies.\n */\n\nvar Base = require('./base');\nvar utils = require('../utils');\n\n/**\n * Constants\n */\n\nvar SUITE_PREFIX = '$';\n\n/**\n * Expose `Markdown`.\n */\n\nexports = module.exports = Markdown;\n\n/**\n * Initialize a new `Markdown` reporter.\n *\n * @api public\n * @param {Runner} runner\n */\nfunction Markdown(runner) {\n  Base.call(this, runner);\n\n  var level = 0;\n  var buf = '';\n\n  function title(str) {\n    return Array(level).join('#') + ' ' + str;\n  }\n\n  function mapTOC(suite, obj) {\n    var ret = obj;\n    var key = SUITE_PREFIX + suite.title;\n\n    obj = obj[key] = obj[key] || { suite: suite };\n    suite.suites.forEach(function(suite) {\n      mapTOC(suite, obj);\n    });\n\n    return ret;\n  }\n\n  function stringifyTOC(obj, level) {\n    ++level;\n    var buf = '';\n    var link;\n    for (var key in obj) {\n      if (key === 'suite') {\n        continue;\n      }\n      if (key !== SUITE_PREFIX) {\n        link = ' - [' + key.substring(1) + ']';\n        link += '(#' + utils.slug(obj[key].suite.fullTitle()) + ')\\n';\n        buf += Array(level).join('  ') + link;\n      }\n      buf += stringifyTOC(obj[key], level);\n    }\n    return buf;\n  }\n\n  function generateTOC(suite) {\n    var obj = mapTOC(suite, {});\n    return stringifyTOC(obj, 0);\n  }\n\n  generateTOC(runner.suite);\n\n  runner.on('suite', function(suite) {\n    ++level;\n    var slug = utils.slug(suite.fullTitle());\n    buf += '<a name=\"' + slug + '\"></a>' + '\\n';\n    buf += title(suite.title) + '\\n';\n  });\n\n  runner.on('suite end', function() {\n    --level;\n  });\n\n  runner.on('pass', function(test) {\n    var code = utils.clean(test.body);\n    buf += test.title + '.\\n';\n    buf += '\\n```js\\n';\n    buf += code + '\\n';\n    buf += '```\\n\\n';\n  });\n\n  runner.on('end', function() {\n    process.stdout.write('# TOC\\n');\n    process.stdout.write(generateTOC(runner.suite));\n    process.stdout.write(buf);\n  });\n}\n\n}).call(this,require('_process'))\n},{\"../utils\":38,\"./base\":17,\"_process\":67}],27:[function(require,module,exports){\n(function (process){\n/**\n * Module dependencies.\n */\n\nvar Base = require('./base');\nvar inherits = require('../utils').inherits;\n\n/**\n * Expose `Min`.\n */\n\nexports = module.exports = Min;\n\n/**\n * Initialize a new `Min` minimal test reporter (best used with --watch).\n *\n * @api public\n * @param {Runner} runner\n */\nfunction Min(runner) {\n  Base.call(this, runner);\n\n  runner.on('start', function() {\n    // clear screen\n    process.stdout.write('\\u001b[2J');\n    // set cursor position\n    process.stdout.write('\\u001b[1;3H');\n  });\n\n  runner.on('end', this.epilogue.bind(this));\n}\n\n/**\n * Inherit from `Base.prototype`.\n */\ninherits(Min, Base);\n\n}).call(this,require('_process'))\n},{\"../utils\":38,\"./base\":17,\"_process\":67}],28:[function(require,module,exports){\n(function (process){\n/**\n * Module dependencies.\n */\n\nvar Base = require('./base');\nvar inherits = require('../utils').inherits;\n\n/**\n * Expose `Dot`.\n */\n\nexports = module.exports = NyanCat;\n\n/**\n * Initialize a new `Dot` matrix test reporter.\n *\n * @param {Runner} runner\n * @api public\n */\n\nfunction NyanCat(runner) {\n  Base.call(this, runner);\n\n  var self = this;\n  var width = Base.window.width * .75 | 0;\n  var nyanCatWidth = this.nyanCatWidth = 11;\n\n  this.colorIndex = 0;\n  this.numberOfLines = 4;\n  this.rainbowColors = self.generateColors();\n  this.scoreboardWidth = 5;\n  this.tick = 0;\n  this.trajectories = [[], [], [], []];\n  this.trajectoryWidthMax = (width - nyanCatWidth);\n\n  runner.on('start', function() {\n    Base.cursor.hide();\n    self.draw();\n  });\n\n  runner.on('pending', function() {\n    self.draw();\n  });\n\n  runner.on('pass', function() {\n    self.draw();\n  });\n\n  runner.on('fail', function() {\n    self.draw();\n  });\n\n  runner.on('end', function() {\n    Base.cursor.show();\n    for (var i = 0; i < self.numberOfLines; i++) {\n      write('\\n');\n    }\n    self.epilogue();\n  });\n}\n\n/**\n * Inherit from `Base.prototype`.\n */\ninherits(NyanCat, Base);\n\n/**\n * Draw the nyan cat\n *\n * @api private\n */\n\nNyanCat.prototype.draw = function() {\n  this.appendRainbow();\n  this.drawScoreboard();\n  this.drawRainbow();\n  this.drawNyanCat();\n  this.tick = !this.tick;\n};\n\n/**\n * Draw the \"scoreboard\" showing the number\n * of passes, failures and pending tests.\n *\n * @api private\n */\n\nNyanCat.prototype.drawScoreboard = function() {\n  var stats = this.stats;\n\n  function draw(type, n) {\n    write(' ');\n    write(Base.color(type, n));\n    write('\\n');\n  }\n\n  draw('green', stats.passes);\n  draw('fail', stats.failures);\n  draw('pending', stats.pending);\n  write('\\n');\n\n  this.cursorUp(this.numberOfLines);\n};\n\n/**\n * Append the rainbow.\n *\n * @api private\n */\n\nNyanCat.prototype.appendRainbow = function() {\n  var segment = this.tick ? '_' : '-';\n  var rainbowified = this.rainbowify(segment);\n\n  for (var index = 0; index < this.numberOfLines; index++) {\n    var trajectory = this.trajectories[index];\n    if (trajectory.length >= this.trajectoryWidthMax) {\n      trajectory.shift();\n    }\n    trajectory.push(rainbowified);\n  }\n};\n\n/**\n * Draw the rainbow.\n *\n * @api private\n */\n\nNyanCat.prototype.drawRainbow = function() {\n  var self = this;\n\n  this.trajectories.forEach(function(line) {\n    write('\\u001b[' + self.scoreboardWidth + 'C');\n    write(line.join(''));\n    write('\\n');\n  });\n\n  this.cursorUp(this.numberOfLines);\n};\n\n/**\n * Draw the nyan cat\n *\n * @api private\n */\nNyanCat.prototype.drawNyanCat = function() {\n  var self = this;\n  var startWidth = this.scoreboardWidth + this.trajectories[0].length;\n  var dist = '\\u001b[' + startWidth + 'C';\n  var padding = '';\n\n  write(dist);\n  write('_,------,');\n  write('\\n');\n\n  write(dist);\n  padding = self.tick ? '  ' : '   ';\n  write('_|' + padding + '/\\\\_/\\\\ ');\n  write('\\n');\n\n  write(dist);\n  padding = self.tick ? '_' : '__';\n  var tail = self.tick ? '~' : '^';\n  write(tail + '|' + padding + this.face() + ' ');\n  write('\\n');\n\n  write(dist);\n  padding = self.tick ? ' ' : '  ';\n  write(padding + '\"\"  \"\" ');\n  write('\\n');\n\n  this.cursorUp(this.numberOfLines);\n};\n\n/**\n * Draw nyan cat face.\n *\n * @api private\n * @return {string}\n */\n\nNyanCat.prototype.face = function() {\n  var stats = this.stats;\n  if (stats.failures) {\n    return '( x .x)';\n  } else if (stats.pending) {\n    return '( o .o)';\n  } else if (stats.passes) {\n    return '( ^ .^)';\n  }\n  return '( - .-)';\n};\n\n/**\n * Move cursor up `n`.\n *\n * @api private\n * @param {number} n\n */\n\nNyanCat.prototype.cursorUp = function(n) {\n  write('\\u001b[' + n + 'A');\n};\n\n/**\n * Move cursor down `n`.\n *\n * @api private\n * @param {number} n\n */\n\nNyanCat.prototype.cursorDown = function(n) {\n  write('\\u001b[' + n + 'B');\n};\n\n/**\n * Generate rainbow colors.\n *\n * @api private\n * @return {Array}\n */\nNyanCat.prototype.generateColors = function() {\n  var colors = [];\n\n  for (var i = 0; i < (6 * 7); i++) {\n    var pi3 = Math.floor(Math.PI / 3);\n    var n = (i * (1.0 / 6));\n    var r = Math.floor(3 * Math.sin(n) + 3);\n    var g = Math.floor(3 * Math.sin(n + 2 * pi3) + 3);\n    var b = Math.floor(3 * Math.sin(n + 4 * pi3) + 3);\n    colors.push(36 * r + 6 * g + b + 16);\n  }\n\n  return colors;\n};\n\n/**\n * Apply rainbow to the given `str`.\n *\n * @api private\n * @param {string} str\n * @return {string}\n */\nNyanCat.prototype.rainbowify = function(str) {\n  if (!Base.useColors) {\n    return str;\n  }\n  var color = this.rainbowColors[this.colorIndex % this.rainbowColors.length];\n  this.colorIndex += 1;\n  return '\\u001b[38;5;' + color + 'm' + str + '\\u001b[0m';\n};\n\n/**\n * Stdout helper.\n *\n * @param {string} string A message to write to stdout.\n */\nfunction write(string) {\n  process.stdout.write(string);\n}\n\n}).call(this,require('_process'))\n},{\"../utils\":38,\"./base\":17,\"_process\":67}],29:[function(require,module,exports){\n(function (process){\n/**\n * Module dependencies.\n */\n\nvar Base = require('./base');\nvar inherits = require('../utils').inherits;\nvar color = Base.color;\nvar cursor = Base.cursor;\n\n/**\n * Expose `Progress`.\n */\n\nexports = module.exports = Progress;\n\n/**\n * General progress bar color.\n */\n\nBase.colors.progress = 90;\n\n/**\n * Initialize a new `Progress` bar test reporter.\n *\n * @api public\n * @param {Runner} runner\n * @param {Object} options\n */\nfunction Progress(runner, options) {\n  Base.call(this, runner);\n\n  var self = this;\n  var width = Base.window.width * .50 | 0;\n  var total = runner.total;\n  var complete = 0;\n  var lastN = -1;\n\n  // default chars\n  options = options || {};\n  options.open = options.open || '[';\n  options.complete = options.complete || '▬';\n  options.incomplete = options.incomplete || Base.symbols.dot;\n  options.close = options.close || ']';\n  options.verbose = false;\n\n  // tests started\n  runner.on('start', function() {\n    console.log();\n    cursor.hide();\n  });\n\n  // tests complete\n  runner.on('test end', function() {\n    complete++;\n\n    var percent = complete / total;\n    var n = width * percent | 0;\n    var i = width - n;\n\n    if (n === lastN && !options.verbose) {\n      // Don't re-render the line if it hasn't changed\n      return;\n    }\n    lastN = n;\n\n    cursor.CR();\n    process.stdout.write('\\u001b[J');\n    process.stdout.write(color('progress', '  ' + options.open));\n    process.stdout.write(Array(n).join(options.complete));\n    process.stdout.write(Array(i).join(options.incomplete));\n    process.stdout.write(color('progress', options.close));\n    if (options.verbose) {\n      process.stdout.write(color('progress', ' ' + complete + ' of ' + total));\n    }\n  });\n\n  // tests are complete, output some stats\n  // and the failures if any\n  runner.on('end', function() {\n    cursor.show();\n    console.log();\n    self.epilogue();\n  });\n}\n\n/**\n * Inherit from `Base.prototype`.\n */\ninherits(Progress, Base);\n\n}).call(this,require('_process'))\n},{\"../utils\":38,\"./base\":17,\"_process\":67}],30:[function(require,module,exports){\n/**\n * Module dependencies.\n */\n\nvar Base = require('./base');\nvar inherits = require('../utils').inherits;\nvar color = Base.color;\n\n/**\n * Expose `Spec`.\n */\n\nexports = module.exports = Spec;\n\n/**\n * Initialize a new `Spec` test reporter.\n *\n * @api public\n * @param {Runner} runner\n */\nfunction Spec(runner) {\n  Base.call(this, runner);\n\n  var self = this;\n  var indents = 0;\n  var n = 0;\n\n  function indent() {\n    return Array(indents).join('  ');\n  }\n\n  runner.on('start', function() {\n    console.log();\n  });\n\n  runner.on('suite', function(suite) {\n    ++indents;\n    console.log(color('suite', '%s%s'), indent(), suite.title);\n  });\n\n  runner.on('suite end', function() {\n    --indents;\n    if (indents === 1) {\n      console.log();\n    }\n  });\n\n  runner.on('pending', function(test) {\n    var fmt = indent() + color('pending', '  - %s');\n    console.log(fmt, test.title);\n  });\n\n  runner.on('pass', function(test) {\n    var fmt;\n    if (test.speed === 'fast') {\n      fmt = indent()\n        + color('checkmark', '  ' + Base.symbols.ok)\n        + color('pass', ' %s');\n      console.log(fmt, test.title);\n    } else {\n      fmt = indent()\n        + color('checkmark', '  ' + Base.symbols.ok)\n        + color('pass', ' %s')\n        + color(test.speed, ' (%dms)');\n      console.log(fmt, test.title, test.duration);\n    }\n  });\n\n  runner.on('fail', function(test) {\n    console.log(indent() + color('fail', '  %d) %s'), ++n, test.title);\n  });\n\n  runner.on('end', self.epilogue.bind(self));\n}\n\n/**\n * Inherit from `Base.prototype`.\n */\ninherits(Spec, Base);\n\n},{\"../utils\":38,\"./base\":17}],31:[function(require,module,exports){\n/**\n * Module dependencies.\n */\n\nvar Base = require('./base');\n\n/**\n * Expose `TAP`.\n */\n\nexports = module.exports = TAP;\n\n/**\n * Initialize a new `TAP` reporter.\n *\n * @api public\n * @param {Runner} runner\n */\nfunction TAP(runner) {\n  Base.call(this, runner);\n\n  var n = 1;\n  var passes = 0;\n  var failures = 0;\n\n  runner.on('start', function() {\n    var total = runner.grepTotal(runner.suite);\n    console.log('%d..%d', 1, total);\n  });\n\n  runner.on('test end', function() {\n    ++n;\n  });\n\n  runner.on('pending', function(test) {\n    console.log('ok %d %s # SKIP -', n, title(test));\n  });\n\n  runner.on('pass', function(test) {\n    passes++;\n    console.log('ok %d %s', n, title(test));\n  });\n\n  runner.on('fail', function(test, err) {\n    failures++;\n    console.log('not ok %d %s', n, title(test));\n    if (err.stack) {\n      console.log(err.stack.replace(/^/gm, '  '));\n    }\n  });\n\n  runner.on('end', function() {\n    console.log('# tests ' + (passes + failures));\n    console.log('# pass ' + passes);\n    console.log('# fail ' + failures);\n  });\n}\n\n/**\n * Return a TAP-safe title of `test`\n *\n * @api private\n * @param {Object} test\n * @return {String}\n */\nfunction title(test) {\n  return test.fullTitle().replace(/#/g, '');\n}\n\n},{\"./base\":17}],32:[function(require,module,exports){\n(function (process,global){\n/**\n * Module dependencies.\n */\n\nvar Base = require('./base');\nvar utils = require('../utils');\nvar inherits = utils.inherits;\nvar fs = require('fs');\nvar escape = utils.escape;\nvar mkdirp = require('mkdirp');\nvar path = require('path');\n\n/**\n * Save timer references to avoid Sinon interfering (see GH-237).\n */\n\n/* eslint-disable no-unused-vars, no-native-reassign */\nvar Date = global.Date;\nvar setTimeout = global.setTimeout;\nvar setInterval = global.setInterval;\nvar clearTimeout = global.clearTimeout;\nvar clearInterval = global.clearInterval;\n/* eslint-enable no-unused-vars, no-native-reassign */\n\n/**\n * Expose `XUnit`.\n */\n\nexports = module.exports = XUnit;\n\n/**\n * Initialize a new `XUnit` reporter.\n *\n * @api public\n * @param {Runner} runner\n */\nfunction XUnit(runner, options) {\n  Base.call(this, runner);\n\n  var stats = this.stats;\n  var tests = [];\n  var self = this;\n\n  if (options.reporterOptions && options.reporterOptions.output) {\n    if (!fs.createWriteStream) {\n      throw new Error('file output not supported in browser');\n    }\n    mkdirp.sync(path.dirname(options.reporterOptions.output));\n    self.fileStream = fs.createWriteStream(options.reporterOptions.output);\n  }\n\n  runner.on('pending', function(test) {\n    tests.push(test);\n  });\n\n  runner.on('pass', function(test) {\n    tests.push(test);\n  });\n\n  runner.on('fail', function(test) {\n    tests.push(test);\n  });\n\n  runner.on('end', function() {\n    self.write(tag('testsuite', {\n      name: 'Mocha Tests',\n      tests: stats.tests,\n      failures: stats.failures,\n      errors: stats.failures,\n      skipped: stats.tests - stats.failures - stats.passes,\n      timestamp: (new Date()).toUTCString(),\n      time: (stats.duration / 1000) || 0\n    }, false));\n\n    tests.forEach(function(t) {\n      self.test(t);\n    });\n\n    self.write('</testsuite>');\n  });\n}\n\n/**\n * Inherit from `Base.prototype`.\n */\ninherits(XUnit, Base);\n\n/**\n * Override done to close the stream (if it's a file).\n *\n * @param failures\n * @param {Function} fn\n */\nXUnit.prototype.done = function(failures, fn) {\n  if (this.fileStream) {\n    this.fileStream.end(function() {\n      fn(failures);\n    });\n  } else {\n    fn(failures);\n  }\n};\n\n/**\n * Write out the given line.\n *\n * @param {string} line\n */\nXUnit.prototype.write = function(line) {\n  if (this.fileStream) {\n    this.fileStream.write(line + '\\n');\n  } else if (typeof process === 'object' && process.stdout) {\n    process.stdout.write(line + '\\n');\n  } else {\n    console.log(line);\n  }\n};\n\n/**\n * Output tag for the given `test.`\n *\n * @param {Test} test\n */\nXUnit.prototype.test = function(test) {\n  var attrs = {\n    classname: test.parent.fullTitle(),\n    name: test.title,\n    time: (test.duration / 1000) || 0\n  };\n\n  if (test.state === 'failed') {\n    var err = test.err;\n    this.write(tag('testcase', attrs, false, tag('failure', {}, false, escape(err.message) + '\\n' + escape(err.stack))));\n  } else if (test.isPending()) {\n    this.write(tag('testcase', attrs, false, tag('skipped', {}, true)));\n  } else {\n    this.write(tag('testcase', attrs, true));\n  }\n};\n\n/**\n * HTML tag helper.\n *\n * @param name\n * @param attrs\n * @param close\n * @param content\n * @return {string}\n */\nfunction tag(name, attrs, close, content) {\n  var end = close ? '/>' : '>';\n  var pairs = [];\n  var tag;\n\n  for (var key in attrs) {\n    if (Object.prototype.hasOwnProperty.call(attrs, key)) {\n      pairs.push(key + '=\"' + escape(attrs[key]) + '\"');\n    }\n  }\n\n  tag = '<' + name + (pairs.length ? ' ' + pairs.join(' ') : '') + end;\n  if (content) {\n    tag += content + '</' + name + end;\n  }\n  return tag;\n}\n\n}).call(this,require('_process'),typeof global !== \"undefined\" ? global : typeof self !== \"undefined\" ? self : typeof window !== \"undefined\" ? window : {})\n},{\"../utils\":38,\"./base\":17,\"_process\":67,\"fs\":42,\"mkdirp\":64,\"path\":42}],33:[function(require,module,exports){\n(function (global){\n/**\n * Module dependencies.\n */\n\nvar EventEmitter = require('events').EventEmitter;\nvar JSON = require('json3');\nvar Pending = require('./pending');\nvar debug = require('debug')('mocha:runnable');\nvar milliseconds = require('./ms');\nvar utils = require('./utils');\nvar create = require('lodash.create');\n\n/**\n * Save timer references to avoid Sinon interfering (see GH-237).\n */\n\n/* eslint-disable no-unused-vars, no-native-reassign */\nvar Date = global.Date;\nvar setTimeout = global.setTimeout;\nvar setInterval = global.setInterval;\nvar clearTimeout = global.clearTimeout;\nvar clearInterval = global.clearInterval;\n/* eslint-enable no-unused-vars, no-native-reassign */\n\n/**\n * Object#toString().\n */\n\nvar toString = Object.prototype.toString;\n\n/**\n * Expose `Runnable`.\n */\n\nmodule.exports = Runnable;\n\n/**\n * Initialize a new `Runnable` with the given `title` and callback `fn`.\n *\n * @param {String} title\n * @param {Function} fn\n * @api private\n * @param {string} title\n * @param {Function} fn\n */\nfunction Runnable(title, fn) {\n  this.title = title;\n  this.fn = fn;\n  this.body = (fn || '').toString();\n  this.async = fn && fn.length;\n  this.sync = !this.async;\n  this._timeout = 2000;\n  this._slow = 75;\n  this._enableTimeouts = true;\n  this.timedOut = false;\n  this._trace = new Error('done() called multiple times');\n  this._retries = -1;\n  this._currentRetry = 0;\n  this.pending = false;\n}\n\n/**\n * Inherit from `EventEmitter.prototype`.\n */\nRunnable.prototype = create(EventEmitter.prototype, {\n  constructor: Runnable\n});\n\n/**\n * Set & get timeout `ms`.\n *\n * @api private\n * @param {number|string} ms\n * @return {Runnable|number} ms or Runnable instance.\n */\nRunnable.prototype.timeout = function(ms) {\n  if (!arguments.length) {\n    return this._timeout;\n  }\n  // see #1652 for reasoning\n  if (ms === 0 || ms > Math.pow(2, 31)) {\n    this._enableTimeouts = false;\n  }\n  if (typeof ms === 'string') {\n    ms = milliseconds(ms);\n  }\n  debug('timeout %d', ms);\n  this._timeout = ms;\n  if (this.timer) {\n    this.resetTimeout();\n  }\n  return this;\n};\n\n/**\n * Set & get slow `ms`.\n *\n * @api private\n * @param {number|string} ms\n * @return {Runnable|number} ms or Runnable instance.\n */\nRunnable.prototype.slow = function(ms) {\n  if (typeof ms === 'undefined') {\n    return this._slow;\n  }\n  if (typeof ms === 'string') {\n    ms = milliseconds(ms);\n  }\n  debug('timeout %d', ms);\n  this._slow = ms;\n  return this;\n};\n\n/**\n * Set and get whether timeout is `enabled`.\n *\n * @api private\n * @param {boolean} enabled\n * @return {Runnable|boolean} enabled or Runnable instance.\n */\nRunnable.prototype.enableTimeouts = function(enabled) {\n  if (!arguments.length) {\n    return this._enableTimeouts;\n  }\n  debug('enableTimeouts %s', enabled);\n  this._enableTimeouts = enabled;\n  return this;\n};\n\n/**\n * Halt and mark as pending.\n *\n * @api public\n */\nRunnable.prototype.skip = function() {\n  throw new Pending('sync skip');\n};\n\n/**\n * Check if this runnable or its parent suite is marked as pending.\n *\n * @api private\n */\nRunnable.prototype.isPending = function() {\n  return this.pending || (this.parent && this.parent.isPending());\n};\n\n/**\n * Set number of retries.\n *\n * @api private\n */\nRunnable.prototype.retries = function(n) {\n  if (!arguments.length) {\n    return this._retries;\n  }\n  this._retries = n;\n};\n\n/**\n * Get current retry\n *\n * @api private\n */\nRunnable.prototype.currentRetry = function(n) {\n  if (!arguments.length) {\n    return this._currentRetry;\n  }\n  this._currentRetry = n;\n};\n\n/**\n * Return the full title generated by recursively concatenating the parent's\n * full title.\n *\n * @api public\n * @return {string}\n */\nRunnable.prototype.fullTitle = function() {\n  return this.parent.fullTitle() + ' ' + this.title;\n};\n\n/**\n * Clear the timeout.\n *\n * @api private\n */\nRunnable.prototype.clearTimeout = function() {\n  clearTimeout(this.timer);\n};\n\n/**\n * Inspect the runnable void of private properties.\n *\n * @api private\n * @return {string}\n */\nRunnable.prototype.inspect = function() {\n  return JSON.stringify(this, function(key, val) {\n    if (key[0] === '_') {\n      return;\n    }\n    if (key === 'parent') {\n      return '#<Suite>';\n    }\n    if (key === 'ctx') {\n      return '#<Context>';\n    }\n    return val;\n  }, 2);\n};\n\n/**\n * Reset the timeout.\n *\n * @api private\n */\nRunnable.prototype.resetTimeout = function() {\n  var self = this;\n  var ms = this.timeout() || 1e9;\n\n  if (!this._enableTimeouts) {\n    return;\n  }\n  this.clearTimeout();\n  this.timer = setTimeout(function() {\n    if (!self._enableTimeouts) {\n      return;\n    }\n    self.callback(new Error('timeout of ' + ms + 'ms exceeded. Ensure the done() callback is being called in this test.'));\n    self.timedOut = true;\n  }, ms);\n};\n\n/**\n * Whitelist a list of globals for this test run.\n *\n * @api private\n * @param {string[]} globals\n */\nRunnable.prototype.globals = function(globals) {\n  if (!arguments.length) {\n    return this._allowedGlobals;\n  }\n  this._allowedGlobals = globals;\n};\n\n/**\n * Run the test and invoke `fn(err)`.\n *\n * @param {Function} fn\n * @api private\n */\nRunnable.prototype.run = function(fn) {\n  var self = this;\n  var start = new Date();\n  var ctx = this.ctx;\n  var finished;\n  var emitted;\n\n  // Sometimes the ctx exists, but it is not runnable\n  if (ctx && ctx.runnable) {\n    ctx.runnable(this);\n  }\n\n  // called multiple times\n  function multiple(err) {\n    if (emitted) {\n      return;\n    }\n    emitted = true;\n    self.emit('error', err || new Error('done() called multiple times; stacktrace may be inaccurate'));\n  }\n\n  // finished\n  function done(err) {\n    var ms = self.timeout();\n    if (self.timedOut) {\n      return;\n    }\n    if (finished) {\n      return multiple(err || self._trace);\n    }\n\n    self.clearTimeout();\n    self.duration = new Date() - start;\n    finished = true;\n    if (!err && self.duration > ms && self._enableTimeouts) {\n      err = new Error('timeout of ' + ms + 'ms exceeded. Ensure the done() callback is being called in this test.');\n    }\n    fn(err);\n  }\n\n  // for .resetTimeout()\n  this.callback = done;\n\n  // explicit async with `done` argument\n  if (this.async) {\n    this.resetTimeout();\n\n    // allows skip() to be used in an explicit async context\n    this.skip = function asyncSkip() {\n      done(new Pending('async skip call'));\n      // halt execution.  the Runnable will be marked pending\n      // by the previous call, and the uncaught handler will ignore\n      // the failure.\n      throw new Pending('async skip; aborting execution');\n    };\n\n    if (this.allowUncaught) {\n      return callFnAsync(this.fn);\n    }\n    try {\n      callFnAsync(this.fn);\n    } catch (err) {\n      done(utils.getError(err));\n    }\n    return;\n  }\n\n  if (this.allowUncaught) {\n    callFn(this.fn);\n    done();\n    return;\n  }\n\n  // sync or promise-returning\n  try {\n    if (this.isPending()) {\n      done();\n    } else {\n      callFn(this.fn);\n    }\n  } catch (err) {\n    done(utils.getError(err));\n  }\n\n  function callFn(fn) {\n    var result = fn.call(ctx);\n    if (result && typeof result.then === 'function') {\n      self.resetTimeout();\n      result\n        .then(function() {\n          done();\n          // Return null so libraries like bluebird do not warn about\n          // subsequently constructed Promises.\n          return null;\n        },\n        function(reason) {\n          done(reason || new Error('Promise rejected with no or falsy reason'));\n        });\n    } else {\n      if (self.asyncOnly) {\n        return done(new Error('--async-only option in use without declaring `done()` or returning a promise'));\n      }\n\n      done();\n    }\n  }\n\n  function callFnAsync(fn) {\n    var result = fn.call(ctx, function(err) {\n      if (err instanceof Error || toString.call(err) === '[object Error]') {\n        return done(err);\n      }\n      if (err) {\n        if (Object.prototype.toString.call(err) === '[object Object]') {\n          return done(new Error('done() invoked with non-Error: '\n            + JSON.stringify(err)));\n        }\n        return done(new Error('done() invoked with non-Error: ' + err));\n      }\n      if (result && utils.isPromise(result)) {\n        return done(new Error('Resolution method is overspecified. Specify a callback *or* return a Promise; not both.'));\n      }\n\n      done();\n    });\n  }\n};\n\n}).call(this,typeof global !== \"undefined\" ? global : typeof self !== \"undefined\" ? self : typeof window !== \"undefined\" ? window : {})\n},{\"./ms\":15,\"./pending\":16,\"./utils\":38,\"debug\":2,\"events\":3,\"json3\":54,\"lodash.create\":60}],34:[function(require,module,exports){\n(function (process,global){\n/**\n * Module dependencies.\n */\n\nvar EventEmitter = require('events').EventEmitter;\nvar Pending = require('./pending');\nvar utils = require('./utils');\nvar inherits = utils.inherits;\nvar debug = require('debug')('mocha:runner');\nvar Runnable = require('./runnable');\nvar filter = utils.filter;\nvar indexOf = utils.indexOf;\nvar some = utils.some;\nvar keys = utils.keys;\nvar stackFilter = utils.stackTraceFilter();\nvar stringify = utils.stringify;\nvar type = utils.type;\nvar undefinedError = utils.undefinedError;\nvar isArray = utils.isArray;\n\n/**\n * Non-enumerable globals.\n */\n\nvar globals = [\n  'setTimeout',\n  'clearTimeout',\n  'setInterval',\n  'clearInterval',\n  'XMLHttpRequest',\n  'Date',\n  'setImmediate',\n  'clearImmediate'\n];\n\n/**\n * Expose `Runner`.\n */\n\nmodule.exports = Runner;\n\n/**\n * Initialize a `Runner` for the given `suite`.\n *\n * Events:\n *\n *   - `start`  execution started\n *   - `end`  execution complete\n *   - `suite`  (suite) test suite execution started\n *   - `suite end`  (suite) all tests (and sub-suites) have finished\n *   - `test`  (test) test execution started\n *   - `test end`  (test) test completed\n *   - `hook`  (hook) hook execution started\n *   - `hook end`  (hook) hook complete\n *   - `pass`  (test) test passed\n *   - `fail`  (test, err) test failed\n *   - `pending`  (test) test pending\n *\n * @api public\n * @param {Suite} suite Root suite\n * @param {boolean} [delay] Whether or not to delay execution of root suite\n * until ready.\n */\nfunction Runner(suite, delay) {\n  var self = this;\n  this._globals = [];\n  this._abort = false;\n  this._delay = delay;\n  this.suite = suite;\n  this.started = false;\n  this.total = suite.total();\n  this.failures = 0;\n  this.on('test end', function(test) {\n    self.checkGlobals(test);\n  });\n  this.on('hook end', function(hook) {\n    self.checkGlobals(hook);\n  });\n  this._defaultGrep = /.*/;\n  this.grep(this._defaultGrep);\n  this.globals(this.globalProps().concat(extraGlobals()));\n}\n\n/**\n * Wrapper for setImmediate, process.nextTick, or browser polyfill.\n *\n * @param {Function} fn\n * @api private\n */\nRunner.immediately = global.setImmediate || process.nextTick;\n\n/**\n * Inherit from `EventEmitter.prototype`.\n */\ninherits(Runner, EventEmitter);\n\n/**\n * Run tests with full titles matching `re`. Updates runner.total\n * with number of tests matched.\n *\n * @param {RegExp} re\n * @param {Boolean} invert\n * @return {Runner} for chaining\n * @api public\n * @param {RegExp} re\n * @param {boolean} invert\n * @return {Runner} Runner instance.\n */\nRunner.prototype.grep = function(re, invert) {\n  debug('grep %s', re);\n  this._grep = re;\n  this._invert = invert;\n  this.total = this.grepTotal(this.suite);\n  return this;\n};\n\n/**\n * Returns the number of tests matching the grep search for the\n * given suite.\n *\n * @param {Suite} suite\n * @return {Number}\n * @api public\n * @param {Suite} suite\n * @return {number}\n */\nRunner.prototype.grepTotal = function(suite) {\n  var self = this;\n  var total = 0;\n\n  suite.eachTest(function(test) {\n    var match = self._grep.test(test.fullTitle());\n    if (self._invert) {\n      match = !match;\n    }\n    if (match) {\n      total++;\n    }\n  });\n\n  return total;\n};\n\n/**\n * Return a list of global properties.\n *\n * @return {Array}\n * @api private\n */\nRunner.prototype.globalProps = function() {\n  var props = keys(global);\n\n  // non-enumerables\n  for (var i = 0; i < globals.length; ++i) {\n    if (~indexOf(props, globals[i])) {\n      continue;\n    }\n    props.push(globals[i]);\n  }\n\n  return props;\n};\n\n/**\n * Allow the given `arr` of globals.\n *\n * @param {Array} arr\n * @return {Runner} for chaining\n * @api public\n * @param {Array} arr\n * @return {Runner} Runner instance.\n */\nRunner.prototype.globals = function(arr) {\n  if (!arguments.length) {\n    return this._globals;\n  }\n  debug('globals %j', arr);\n  this._globals = this._globals.concat(arr);\n  return this;\n};\n\n/**\n * Check for global variable leaks.\n *\n * @api private\n */\nRunner.prototype.checkGlobals = function(test) {\n  if (this.ignoreLeaks) {\n    return;\n  }\n  var ok = this._globals;\n\n  var globals = this.globalProps();\n  var leaks;\n\n  if (test) {\n    ok = ok.concat(test._allowedGlobals || []);\n  }\n\n  if (this.prevGlobalsLength === globals.length) {\n    return;\n  }\n  this.prevGlobalsLength = globals.length;\n\n  leaks = filterLeaks(ok, globals);\n  this._globals = this._globals.concat(leaks);\n\n  if (leaks.length > 1) {\n    this.fail(test, new Error('global leaks detected: ' + leaks.join(', ') + ''));\n  } else if (leaks.length) {\n    this.fail(test, new Error('global leak detected: ' + leaks[0]));\n  }\n};\n\n/**\n * Fail the given `test`.\n *\n * @api private\n * @param {Test} test\n * @param {Error} err\n */\nRunner.prototype.fail = function(test, err) {\n  if (test.isPending()) {\n    return;\n  }\n\n  ++this.failures;\n  test.state = 'failed';\n\n  if (!(err instanceof Error || err && typeof err.message === 'string')) {\n    err = new Error('the ' + type(err) + ' ' + stringify(err) + ' was thrown, throw an Error :)');\n  }\n\n  err.stack = (this.fullStackTrace || !err.stack)\n    ? err.stack\n    : stackFilter(err.stack);\n\n  this.emit('fail', test, err);\n};\n\n/**\n * Fail the given `hook` with `err`.\n *\n * Hook failures work in the following pattern:\n * - If bail, then exit\n * - Failed `before` hook skips all tests in a suite and subsuites,\n *   but jumps to corresponding `after` hook\n * - Failed `before each` hook skips remaining tests in a\n *   suite and jumps to corresponding `after each` hook,\n *   which is run only once\n * - Failed `after` hook does not alter\n *   execution order\n * - Failed `after each` hook skips remaining tests in a\n *   suite and subsuites, but executes other `after each`\n *   hooks\n *\n * @api private\n * @param {Hook} hook\n * @param {Error} err\n */\nRunner.prototype.failHook = function(hook, err) {\n  if (hook.ctx && hook.ctx.currentTest) {\n    hook.originalTitle = hook.originalTitle || hook.title;\n    hook.title = hook.originalTitle + ' for \"' + hook.ctx.currentTest.title + '\"';\n  }\n\n  this.fail(hook, err);\n  if (this.suite.bail()) {\n    this.emit('end');\n  }\n};\n\n/**\n * Run hook `name` callbacks and then invoke `fn()`.\n *\n * @api private\n * @param {string} name\n * @param {Function} fn\n */\n\nRunner.prototype.hook = function(name, fn) {\n  var suite = this.suite;\n  var hooks = suite['_' + name];\n  var self = this;\n\n  function next(i) {\n    var hook = hooks[i];\n    if (!hook) {\n      return fn();\n    }\n    self.currentRunnable = hook;\n\n    hook.ctx.currentTest = self.test;\n\n    self.emit('hook', hook);\n\n    if (!hook.listeners('error').length) {\n      hook.on('error', function(err) {\n        self.failHook(hook, err);\n      });\n    }\n\n    hook.run(function(err) {\n      var testError = hook.error();\n      if (testError) {\n        self.fail(self.test, testError);\n      }\n      if (err) {\n        if (err instanceof Pending) {\n          if (name === 'beforeEach' || name === 'afterEach') {\n            self.test.pending = true;\n          } else {\n            utils.forEach(suite.tests, function(test) {\n              test.pending = true;\n            });\n            // a pending hook won't be executed twice.\n            hook.pending = true;\n          }\n        } else {\n          self.failHook(hook, err);\n\n          // stop executing hooks, notify callee of hook err\n          return fn(err);\n        }\n      }\n      self.emit('hook end', hook);\n      delete hook.ctx.currentTest;\n      next(++i);\n    });\n  }\n\n  Runner.immediately(function() {\n    next(0);\n  });\n};\n\n/**\n * Run hook `name` for the given array of `suites`\n * in order, and callback `fn(err, errSuite)`.\n *\n * @api private\n * @param {string} name\n * @param {Array} suites\n * @param {Function} fn\n */\nRunner.prototype.hooks = function(name, suites, fn) {\n  var self = this;\n  var orig = this.suite;\n\n  function next(suite) {\n    self.suite = suite;\n\n    if (!suite) {\n      self.suite = orig;\n      return fn();\n    }\n\n    self.hook(name, function(err) {\n      if (err) {\n        var errSuite = self.suite;\n        self.suite = orig;\n        return fn(err, errSuite);\n      }\n\n      next(suites.pop());\n    });\n  }\n\n  next(suites.pop());\n};\n\n/**\n * Run hooks from the top level down.\n *\n * @param {String} name\n * @param {Function} fn\n * @api private\n */\nRunner.prototype.hookUp = function(name, fn) {\n  var suites = [this.suite].concat(this.parents()).reverse();\n  this.hooks(name, suites, fn);\n};\n\n/**\n * Run hooks from the bottom up.\n *\n * @param {String} name\n * @param {Function} fn\n * @api private\n */\nRunner.prototype.hookDown = function(name, fn) {\n  var suites = [this.suite].concat(this.parents());\n  this.hooks(name, suites, fn);\n};\n\n/**\n * Return an array of parent Suites from\n * closest to furthest.\n *\n * @return {Array}\n * @api private\n */\nRunner.prototype.parents = function() {\n  var suite = this.suite;\n  var suites = [];\n  while (suite.parent) {\n    suite = suite.parent;\n    suites.push(suite);\n  }\n  return suites;\n};\n\n/**\n * Run the current test and callback `fn(err)`.\n *\n * @param {Function} fn\n * @api private\n */\nRunner.prototype.runTest = function(fn) {\n  var self = this;\n  var test = this.test;\n\n  if (!test) {\n    return;\n  }\n  if (this.asyncOnly) {\n    test.asyncOnly = true;\n  }\n\n  if (this.allowUncaught) {\n    test.allowUncaught = true;\n    return test.run(fn);\n  }\n  try {\n    test.on('error', function(err) {\n      self.fail(test, err);\n    });\n    test.run(fn);\n  } catch (err) {\n    fn(err);\n  }\n};\n\n/**\n * Run tests in the given `suite` and invoke the callback `fn()` when complete.\n *\n * @api private\n * @param {Suite} suite\n * @param {Function} fn\n */\nRunner.prototype.runTests = function(suite, fn) {\n  var self = this;\n  var tests = suite.tests.slice();\n  var test;\n\n  function hookErr(_, errSuite, after) {\n    // before/after Each hook for errSuite failed:\n    var orig = self.suite;\n\n    // for failed 'after each' hook start from errSuite parent,\n    // otherwise start from errSuite itself\n    self.suite = after ? errSuite.parent : errSuite;\n\n    if (self.suite) {\n      // call hookUp afterEach\n      self.hookUp('afterEach', function(err2, errSuite2) {\n        self.suite = orig;\n        // some hooks may fail even now\n        if (err2) {\n          return hookErr(err2, errSuite2, true);\n        }\n        // report error suite\n        fn(errSuite);\n      });\n    } else {\n      // there is no need calling other 'after each' hooks\n      self.suite = orig;\n      fn(errSuite);\n    }\n  }\n\n  function next(err, errSuite) {\n    // if we bail after first err\n    if (self.failures && suite._bail) {\n      return fn();\n    }\n\n    if (self._abort) {\n      return fn();\n    }\n\n    if (err) {\n      return hookErr(err, errSuite, true);\n    }\n\n    // next test\n    test = tests.shift();\n\n    // all done\n    if (!test) {\n      return fn();\n    }\n\n    // grep\n    var match = self._grep.test(test.fullTitle());\n    if (self._invert) {\n      match = !match;\n    }\n    if (!match) {\n      // Run immediately only if we have defined a grep. When we\n      // define a grep — It can cause maximum callstack error if\n      // the grep is doing a large recursive loop by neglecting\n      // all tests. The run immediately function also comes with\n      // a performance cost. So we don't want to run immediately\n      // if we run the whole test suite, because running the whole\n      // test suite don't do any immediate recursive loops. Thus,\n      // allowing a JS runtime to breathe.\n      if (self._grep !== self._defaultGrep) {\n        Runner.immediately(next);\n      } else {\n        next();\n      }\n      return;\n    }\n\n    if (test.isPending()) {\n      self.emit('pending', test);\n      self.emit('test end', test);\n      return next();\n    }\n\n    // execute test and hook(s)\n    self.emit('test', self.test = test);\n    self.hookDown('beforeEach', function(err, errSuite) {\n      if (test.isPending()) {\n        self.emit('pending', test);\n        self.emit('test end', test);\n        return next();\n      }\n      if (err) {\n        return hookErr(err, errSuite, false);\n      }\n      self.currentRunnable = self.test;\n      self.runTest(function(err) {\n        test = self.test;\n        if (err) {\n          var retry = test.currentRetry();\n          if (err instanceof Pending) {\n            test.pending = true;\n            self.emit('pending', test);\n          } else if (retry < test.retries()) {\n            var clonedTest = test.clone();\n            clonedTest.currentRetry(retry + 1);\n            tests.unshift(clonedTest);\n\n            // Early return + hook trigger so that it doesn't\n            // increment the count wrong\n            return self.hookUp('afterEach', next);\n          } else {\n            self.fail(test, err);\n          }\n          self.emit('test end', test);\n\n          if (err instanceof Pending) {\n            return next();\n          }\n\n          return self.hookUp('afterEach', next);\n        }\n\n        test.state = 'passed';\n        self.emit('pass', test);\n        self.emit('test end', test);\n        self.hookUp('afterEach', next);\n      });\n    });\n  }\n\n  this.next = next;\n  this.hookErr = hookErr;\n  next();\n};\n\n/**\n * Run the given `suite` and invoke the callback `fn()` when complete.\n *\n * @api private\n * @param {Suite} suite\n * @param {Function} fn\n */\nRunner.prototype.runSuite = function(suite, fn) {\n  var i = 0;\n  var self = this;\n  var total = this.grepTotal(suite);\n  var afterAllHookCalled = false;\n\n  debug('run suite %s', suite.fullTitle());\n\n  if (!total || (self.failures && suite._bail)) {\n    return fn();\n  }\n\n  this.emit('suite', this.suite = suite);\n\n  function next(errSuite) {\n    if (errSuite) {\n      // current suite failed on a hook from errSuite\n      if (errSuite === suite) {\n        // if errSuite is current suite\n        // continue to the next sibling suite\n        return done();\n      }\n      // errSuite is among the parents of current suite\n      // stop execution of errSuite and all sub-suites\n      return done(errSuite);\n    }\n\n    if (self._abort) {\n      return done();\n    }\n\n    var curr = suite.suites[i++];\n    if (!curr) {\n      return done();\n    }\n\n    // Avoid grep neglecting large number of tests causing a\n    // huge recursive loop and thus a maximum call stack error.\n    // See comment in `this.runTests()` for more information.\n    if (self._grep !== self._defaultGrep) {\n      Runner.immediately(function() {\n        self.runSuite(curr, next);\n      });\n    } else {\n      self.runSuite(curr, next);\n    }\n  }\n\n  function done(errSuite) {\n    self.suite = suite;\n    self.nextSuite = next;\n\n    if (afterAllHookCalled) {\n      fn(errSuite);\n    } else {\n      // mark that the afterAll block has been called once\n      // and so can be skipped if there is an error in it.\n      afterAllHookCalled = true;\n\n      // remove reference to test\n      delete self.test;\n\n      self.hook('afterAll', function() {\n        self.emit('suite end', suite);\n        fn(errSuite);\n      });\n    }\n  }\n\n  this.nextSuite = next;\n\n  this.hook('beforeAll', function(err) {\n    if (err) {\n      return done();\n    }\n    self.runTests(suite, next);\n  });\n};\n\n/**\n * Handle uncaught exceptions.\n *\n * @param {Error} err\n * @api private\n */\nRunner.prototype.uncaught = function(err) {\n  if (err) {\n    debug('uncaught exception %s', err !== function() {\n      return this;\n    }.call(err) ? err : (err.message || err));\n  } else {\n    debug('uncaught undefined exception');\n    err = undefinedError();\n  }\n  err.uncaught = true;\n\n  var runnable = this.currentRunnable;\n\n  if (!runnable) {\n    runnable = new Runnable('Uncaught error outside test suite');\n    runnable.parent = this.suite;\n\n    if (this.started) {\n      this.fail(runnable, err);\n    } else {\n      // Can't recover from this failure\n      this.emit('start');\n      this.fail(runnable, err);\n      this.emit('end');\n    }\n\n    return;\n  }\n\n  runnable.clearTimeout();\n\n  // Ignore errors if complete or pending\n  if (runnable.state || runnable.isPending()) {\n    return;\n  }\n  this.fail(runnable, err);\n\n  // recover from test\n  if (runnable.type === 'test') {\n    this.emit('test end', runnable);\n    this.hookUp('afterEach', this.next);\n    return;\n  }\n\n // recover from hooks\n  if (runnable.type === 'hook') {\n    var errSuite = this.suite;\n    // if hook failure is in afterEach block\n    if (runnable.fullTitle().indexOf('after each') > -1) {\n      return this.hookErr(err, errSuite, true);\n    }\n    // if hook failure is in beforeEach block\n    if (runnable.fullTitle().indexOf('before each') > -1) {\n      return this.hookErr(err, errSuite, false);\n    }\n    // if hook failure is in after or before blocks\n    return this.nextSuite(errSuite);\n  }\n\n  // bail\n  this.emit('end');\n};\n\n/**\n * Cleans up the references to all the deferred functions\n * (before/after/beforeEach/afterEach) and tests of a Suite.\n * These must be deleted otherwise a memory leak can happen,\n * as those functions may reference variables from closures,\n * thus those variables can never be garbage collected as long\n * as the deferred functions exist.\n *\n * @param {Suite} suite\n */\nfunction cleanSuiteReferences(suite) {\n  function cleanArrReferences(arr) {\n    for (var i = 0; i < arr.length; i++) {\n      delete arr[i].fn;\n    }\n  }\n\n  if (isArray(suite._beforeAll)) {\n    cleanArrReferences(suite._beforeAll);\n  }\n\n  if (isArray(suite._beforeEach)) {\n    cleanArrReferences(suite._beforeEach);\n  }\n\n  if (isArray(suite._afterAll)) {\n    cleanArrReferences(suite._afterAll);\n  }\n\n  if (isArray(suite._afterEach)) {\n    cleanArrReferences(suite._afterEach);\n  }\n\n  for (var i = 0; i < suite.tests.length; i++) {\n    delete suite.tests[i].fn;\n  }\n}\n\n/**\n * Run the root suite and invoke `fn(failures)`\n * on completion.\n *\n * @param {Function} fn\n * @return {Runner} for chaining\n * @api public\n * @param {Function} fn\n * @return {Runner} Runner instance.\n */\nRunner.prototype.run = function(fn) {\n  var self = this;\n  var rootSuite = this.suite;\n\n  // If there is an `only` filter\n  if (this.hasOnly) {\n    filterOnly(rootSuite);\n  }\n\n  fn = fn || function() {};\n\n  function uncaught(err) {\n    self.uncaught(err);\n  }\n\n  function start() {\n    self.started = true;\n    self.emit('start');\n    self.runSuite(rootSuite, function() {\n      debug('finished running');\n      self.emit('end');\n    });\n  }\n\n  debug('start');\n\n  // references cleanup to avoid memory leaks\n  this.on('suite end', cleanSuiteReferences);\n\n  // callback\n  this.on('end', function() {\n    debug('end');\n    process.removeListener('uncaughtException', uncaught);\n    fn(self.failures);\n  });\n\n  // uncaught exception\n  process.on('uncaughtException', uncaught);\n\n  if (this._delay) {\n    // for reporters, I guess.\n    // might be nice to debounce some dots while we wait.\n    this.emit('waiting', rootSuite);\n    rootSuite.once('run', start);\n  } else {\n    start();\n  }\n\n  return this;\n};\n\n/**\n * Cleanly abort execution.\n *\n * @api public\n * @return {Runner} Runner instance.\n */\nRunner.prototype.abort = function() {\n  debug('aborting');\n  this._abort = true;\n\n  return this;\n};\n\n/**\n * Filter suites based on `isOnly` logic.\n *\n * @param {Array} suite\n * @returns {Boolean}\n * @api private\n */\nfunction filterOnly(suite) {\n  if (suite._onlyTests.length) {\n    // If the suite contains `only` tests, run those and ignore any nested suites.\n    suite.tests = suite._onlyTests;\n    suite.suites = [];\n  } else {\n    // Otherwise, do not run any of the tests in this suite.\n    suite.tests = [];\n    utils.forEach(suite._onlySuites, function(onlySuite) {\n      // If there are other `only` tests/suites nested in the current `only` suite, then filter that `only` suite.\n      // Otherwise, all of the tests on this `only` suite should be run, so don't filter it.\n      if (hasOnly(onlySuite)) {\n        filterOnly(onlySuite);\n      }\n    });\n    // Run the `only` suites, as well as any other suites that have `only` tests/suites as descendants.\n    suite.suites = filter(suite.suites, function(childSuite) {\n      return indexOf(suite._onlySuites, childSuite) !== -1 || filterOnly(childSuite);\n    });\n  }\n  // Keep the suite only if there is something to run\n  return suite.tests.length || suite.suites.length;\n}\n\n/**\n * Determines whether a suite has an `only` test or suite as a descendant.\n *\n * @param {Array} suite\n * @returns {Boolean}\n * @api private\n */\nfunction hasOnly(suite) {\n  return suite._onlyTests.length || suite._onlySuites.length || some(suite.suites, hasOnly);\n}\n\n/**\n * Filter leaks with the given globals flagged as `ok`.\n *\n * @api private\n * @param {Array} ok\n * @param {Array} globals\n * @return {Array}\n */\nfunction filterLeaks(ok, globals) {\n  return filter(globals, function(key) {\n    // Firefox and Chrome exposes iframes as index inside the window object\n    if (/^\\d+/.test(key)) {\n      return false;\n    }\n\n    // in firefox\n    // if runner runs in an iframe, this iframe's window.getInterface method\n    // not init at first it is assigned in some seconds\n    if (global.navigator && (/^getInterface/).test(key)) {\n      return false;\n    }\n\n    // an iframe could be approached by window[iframeIndex]\n    // in ie6,7,8 and opera, iframeIndex is enumerable, this could cause leak\n    if (global.navigator && (/^\\d+/).test(key)) {\n      return false;\n    }\n\n    // Opera and IE expose global variables for HTML element IDs (issue #243)\n    if (/^mocha-/.test(key)) {\n      return false;\n    }\n\n    var matched = filter(ok, function(ok) {\n      if (~ok.indexOf('*')) {\n        return key.indexOf(ok.split('*')[0]) === 0;\n      }\n      return key === ok;\n    });\n    return !matched.length && (!global.navigator || key !== 'onerror');\n  });\n}\n\n/**\n * Array of globals dependent on the environment.\n *\n * @return {Array}\n * @api private\n */\nfunction extraGlobals() {\n  if (typeof process === 'object' && typeof process.version === 'string') {\n    var parts = process.version.split('.');\n    var nodeVersion = utils.reduce(parts, function(a, v) {\n      return a << 8 | v;\n    });\n\n    // 'errno' was renamed to process._errno in v0.9.11.\n\n    if (nodeVersion < 0x00090B) {\n      return ['errno'];\n    }\n  }\n\n  return [];\n}\n\n}).call(this,require('_process'),typeof global !== \"undefined\" ? global : typeof self !== \"undefined\" ? self : typeof window !== \"undefined\" ? window : {})\n},{\"./pending\":16,\"./runnable\":33,\"./utils\":38,\"_process\":67,\"debug\":2,\"events\":3}],35:[function(require,module,exports){\n/**\n * Module dependencies.\n */\n\nvar EventEmitter = require('events').EventEmitter;\nvar Hook = require('./hook');\nvar utils = require('./utils');\nvar inherits = utils.inherits;\nvar debug = require('debug')('mocha:suite');\nvar milliseconds = require('./ms');\n\n/**\n * Expose `Suite`.\n */\n\nexports = module.exports = Suite;\n\n/**\n * Create a new `Suite` with the given `title` and parent `Suite`. When a suite\n * with the same title is already present, that suite is returned to provide\n * nicer reporter and more flexible meta-testing.\n *\n * @api public\n * @param {Suite} parent\n * @param {string} title\n * @return {Suite}\n */\nexports.create = function(parent, title) {\n  var suite = new Suite(title, parent.ctx);\n  suite.parent = parent;\n  title = suite.fullTitle();\n  parent.addSuite(suite);\n  return suite;\n};\n\n/**\n * Initialize a new `Suite` with the given `title` and `ctx`.\n *\n * @api private\n * @param {string} title\n * @param {Context} parentContext\n */\nfunction Suite(title, parentContext) {\n  if (!utils.isString(title)) {\n    throw new Error('Suite `title` should be a \"string\" but \"' + typeof title + '\" was given instead.');\n  }\n  this.title = title;\n  function Context() {}\n  Context.prototype = parentContext;\n  this.ctx = new Context();\n  this.suites = [];\n  this.tests = [];\n  this.pending = false;\n  this._beforeEach = [];\n  this._beforeAll = [];\n  this._afterEach = [];\n  this._afterAll = [];\n  this.root = !title;\n  this._timeout = 2000;\n  this._enableTimeouts = true;\n  this._slow = 75;\n  this._bail = false;\n  this._retries = -1;\n  this._onlyTests = [];\n  this._onlySuites = [];\n  this.delayed = false;\n}\n\n/**\n * Inherit from `EventEmitter.prototype`.\n */\ninherits(Suite, EventEmitter);\n\n/**\n * Return a clone of this `Suite`.\n *\n * @api private\n * @return {Suite}\n */\nSuite.prototype.clone = function() {\n  var suite = new Suite(this.title);\n  debug('clone');\n  suite.ctx = this.ctx;\n  suite.timeout(this.timeout());\n  suite.retries(this.retries());\n  suite.enableTimeouts(this.enableTimeouts());\n  suite.slow(this.slow());\n  suite.bail(this.bail());\n  return suite;\n};\n\n/**\n * Set timeout `ms` or short-hand such as \"2s\".\n *\n * @api private\n * @param {number|string} ms\n * @return {Suite|number} for chaining\n */\nSuite.prototype.timeout = function(ms) {\n  if (!arguments.length) {\n    return this._timeout;\n  }\n  if (ms.toString() === '0') {\n    this._enableTimeouts = false;\n  }\n  if (typeof ms === 'string') {\n    ms = milliseconds(ms);\n  }\n  debug('timeout %d', ms);\n  this._timeout = parseInt(ms, 10);\n  return this;\n};\n\n/**\n * Set number of times to retry a failed test.\n *\n * @api private\n * @param {number|string} n\n * @return {Suite|number} for chaining\n */\nSuite.prototype.retries = function(n) {\n  if (!arguments.length) {\n    return this._retries;\n  }\n  debug('retries %d', n);\n  this._retries = parseInt(n, 10) || 0;\n  return this;\n};\n\n/**\n  * Set timeout to `enabled`.\n  *\n  * @api private\n  * @param {boolean} enabled\n  * @return {Suite|boolean} self or enabled\n  */\nSuite.prototype.enableTimeouts = function(enabled) {\n  if (!arguments.length) {\n    return this._enableTimeouts;\n  }\n  debug('enableTimeouts %s', enabled);\n  this._enableTimeouts = enabled;\n  return this;\n};\n\n/**\n * Set slow `ms` or short-hand such as \"2s\".\n *\n * @api private\n * @param {number|string} ms\n * @return {Suite|number} for chaining\n */\nSuite.prototype.slow = function(ms) {\n  if (!arguments.length) {\n    return this._slow;\n  }\n  if (typeof ms === 'string') {\n    ms = milliseconds(ms);\n  }\n  debug('slow %d', ms);\n  this._slow = ms;\n  return this;\n};\n\n/**\n * Sets whether to bail after first error.\n *\n * @api private\n * @param {boolean} bail\n * @return {Suite|number} for chaining\n */\nSuite.prototype.bail = function(bail) {\n  if (!arguments.length) {\n    return this._bail;\n  }\n  debug('bail %s', bail);\n  this._bail = bail;\n  return this;\n};\n\n/**\n * Check if this suite or its parent suite is marked as pending.\n *\n * @api private\n */\nSuite.prototype.isPending = function() {\n  return this.pending || (this.parent && this.parent.isPending());\n};\n\n/**\n * Run `fn(test[, done])` before running tests.\n *\n * @api private\n * @param {string} title\n * @param {Function} fn\n * @return {Suite} for chaining\n */\nSuite.prototype.beforeAll = function(title, fn) {\n  if (this.isPending()) {\n    return this;\n  }\n  if (typeof title === 'function') {\n    fn = title;\n    title = fn.name;\n  }\n  title = '\"before all\" hook' + (title ? ': ' + title : '');\n\n  var hook = new Hook(title, fn);\n  hook.parent = this;\n  hook.timeout(this.timeout());\n  hook.retries(this.retries());\n  hook.enableTimeouts(this.enableTimeouts());\n  hook.slow(this.slow());\n  hook.ctx = this.ctx;\n  this._beforeAll.push(hook);\n  this.emit('beforeAll', hook);\n  return this;\n};\n\n/**\n * Run `fn(test[, done])` after running tests.\n *\n * @api private\n * @param {string} title\n * @param {Function} fn\n * @return {Suite} for chaining\n */\nSuite.prototype.afterAll = function(title, fn) {\n  if (this.isPending()) {\n    return this;\n  }\n  if (typeof title === 'function') {\n    fn = title;\n    title = fn.name;\n  }\n  title = '\"after all\" hook' + (title ? ': ' + title : '');\n\n  var hook = new Hook(title, fn);\n  hook.parent = this;\n  hook.timeout(this.timeout());\n  hook.retries(this.retries());\n  hook.enableTimeouts(this.enableTimeouts());\n  hook.slow(this.slow());\n  hook.ctx = this.ctx;\n  this._afterAll.push(hook);\n  this.emit('afterAll', hook);\n  return this;\n};\n\n/**\n * Run `fn(test[, done])` before each test case.\n *\n * @api private\n * @param {string} title\n * @param {Function} fn\n * @return {Suite} for chaining\n */\nSuite.prototype.beforeEach = function(title, fn) {\n  if (this.isPending()) {\n    return this;\n  }\n  if (typeof title === 'function') {\n    fn = title;\n    title = fn.name;\n  }\n  title = '\"before each\" hook' + (title ? ': ' + title : '');\n\n  var hook = new Hook(title, fn);\n  hook.parent = this;\n  hook.timeout(this.timeout());\n  hook.retries(this.retries());\n  hook.enableTimeouts(this.enableTimeouts());\n  hook.slow(this.slow());\n  hook.ctx = this.ctx;\n  this._beforeEach.push(hook);\n  this.emit('beforeEach', hook);\n  return this;\n};\n\n/**\n * Run `fn(test[, done])` after each test case.\n *\n * @api private\n * @param {string} title\n * @param {Function} fn\n * @return {Suite} for chaining\n */\nSuite.prototype.afterEach = function(title, fn) {\n  if (this.isPending()) {\n    return this;\n  }\n  if (typeof title === 'function') {\n    fn = title;\n    title = fn.name;\n  }\n  title = '\"after each\" hook' + (title ? ': ' + title : '');\n\n  var hook = new Hook(title, fn);\n  hook.parent = this;\n  hook.timeout(this.timeout());\n  hook.retries(this.retries());\n  hook.enableTimeouts(this.enableTimeouts());\n  hook.slow(this.slow());\n  hook.ctx = this.ctx;\n  this._afterEach.push(hook);\n  this.emit('afterEach', hook);\n  return this;\n};\n\n/**\n * Add a test `suite`.\n *\n * @api private\n * @param {Suite} suite\n * @return {Suite} for chaining\n */\nSuite.prototype.addSuite = function(suite) {\n  suite.parent = this;\n  suite.timeout(this.timeout());\n  suite.retries(this.retries());\n  suite.enableTimeouts(this.enableTimeouts());\n  suite.slow(this.slow());\n  suite.bail(this.bail());\n  this.suites.push(suite);\n  this.emit('suite', suite);\n  return this;\n};\n\n/**\n * Add a `test` to this suite.\n *\n * @api private\n * @param {Test} test\n * @return {Suite} for chaining\n */\nSuite.prototype.addTest = function(test) {\n  test.parent = this;\n  test.timeout(this.timeout());\n  test.retries(this.retries());\n  test.enableTimeouts(this.enableTimeouts());\n  test.slow(this.slow());\n  test.ctx = this.ctx;\n  this.tests.push(test);\n  this.emit('test', test);\n  return this;\n};\n\n/**\n * Return the full title generated by recursively concatenating the parent's\n * full title.\n *\n * @api public\n * @return {string}\n */\nSuite.prototype.fullTitle = function() {\n  if (this.parent) {\n    var full = this.parent.fullTitle();\n    if (full) {\n      return full + ' ' + this.title;\n    }\n  }\n  return this.title;\n};\n\n/**\n * Return the total number of tests.\n *\n * @api public\n * @return {number}\n */\nSuite.prototype.total = function() {\n  return utils.reduce(this.suites, function(sum, suite) {\n    return sum + suite.total();\n  }, 0) + this.tests.length;\n};\n\n/**\n * Iterates through each suite recursively to find all tests. Applies a\n * function in the format `fn(test)`.\n *\n * @api private\n * @param {Function} fn\n * @return {Suite}\n */\nSuite.prototype.eachTest = function(fn) {\n  utils.forEach(this.tests, fn);\n  utils.forEach(this.suites, function(suite) {\n    suite.eachTest(fn);\n  });\n  return this;\n};\n\n/**\n * This will run the root suite if we happen to be running in delayed mode.\n */\nSuite.prototype.run = function run() {\n  if (this.root) {\n    this.emit('run');\n  }\n};\n\n},{\"./hook\":7,\"./ms\":15,\"./utils\":38,\"debug\":2,\"events\":3}],36:[function(require,module,exports){\n/**\n * Module dependencies.\n */\n\nvar Runnable = require('./runnable');\nvar create = require('lodash.create');\nvar isString = require('./utils').isString;\n\n/**\n * Expose `Test`.\n */\n\nmodule.exports = Test;\n\n/**\n * Initialize a new `Test` with the given `title` and callback `fn`.\n *\n * @api private\n * @param {String} title\n * @param {Function} fn\n */\nfunction Test(title, fn) {\n  if (!isString(title)) {\n    throw new Error('Test `title` should be a \"string\" but \"' + typeof title + '\" was given instead.');\n  }\n  Runnable.call(this, title, fn);\n  this.pending = !fn;\n  this.type = 'test';\n}\n\n/**\n * Inherit from `Runnable.prototype`.\n */\nTest.prototype = create(Runnable.prototype, {\n  constructor: Test\n});\n\nTest.prototype.clone = function() {\n  var test = new Test(this.title, this.fn);\n  test.timeout(this.timeout());\n  test.slow(this.slow());\n  test.enableTimeouts(this.enableTimeouts());\n  test.retries(this.retries());\n  test.currentRetry(this.currentRetry());\n  test.globals(this.globals());\n  test.parent = this.parent;\n  test.file = this.file;\n  test.ctx = this.ctx;\n  return test;\n};\n\n},{\"./runnable\":33,\"./utils\":38,\"lodash.create\":60}],37:[function(require,module,exports){\n'use strict';\n\n/**\n * Pad a `number` with a ten's place zero.\n *\n * @param {number} number\n * @return {string}\n */\nfunction pad(number) {\n  var n = number.toString();\n  return n.length === 1 ? '0' + n : n;\n}\n\n/**\n * Turn a `date` into an ISO string.\n *\n * https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/toISOString\n *\n * @param {Date} date\n * @return {string}\n */\nfunction toISOString(date) {\n  return date.getUTCFullYear()\n    + '-' + pad(date.getUTCMonth() + 1)\n    + '-' + pad(date.getUTCDate())\n    + 'T' + pad(date.getUTCHours())\n    + ':' + pad(date.getUTCMinutes())\n    + ':' + pad(date.getUTCSeconds())\n    + '.' + String((date.getUTCMilliseconds()/1000).toFixed(3)).slice(2, 5)\n    + 'Z';\n}\n\n/*\n * Exports.\n */\n\nmodule.exports = toISOString;\n\n},{}],38:[function(require,module,exports){\n(function (process,Buffer){\n/* eslint-env browser */\n\n/**\n * Module dependencies.\n */\n\nvar JSON = require('json3');\nvar basename = require('path').basename;\nvar debug = require('debug')('mocha:watch');\nvar exists = require('fs').existsSync || require('path').existsSync;\nvar glob = require('glob');\nvar path = require('path');\nvar join = path.join;\nvar readdirSync = require('fs').readdirSync;\nvar statSync = require('fs').statSync;\nvar watchFile = require('fs').watchFile;\nvar toISOString = require('./to-iso-string');\n\n/**\n * Ignored directories.\n */\n\nvar ignore = ['node_modules', '.git'];\n\nexports.inherits = require('util').inherits;\n\n/**\n * Escape special characters in the given string of html.\n *\n * @api private\n * @param  {string} html\n * @return {string}\n */\nexports.escape = function(html) {\n  return String(html)\n    .replace(/&/g, '&amp;')\n    .replace(/\"/g, '&quot;')\n    .replace(/</g, '&lt;')\n    .replace(/>/g, '&gt;');\n};\n\n/**\n * Array#forEach (<=IE8)\n *\n * @api private\n * @param {Array} arr\n * @param {Function} fn\n * @param {Object} scope\n */\nexports.forEach = function(arr, fn, scope) {\n  for (var i = 0, l = arr.length; i < l; i++) {\n    fn.call(scope, arr[i], i);\n  }\n};\n\n/**\n * Test if the given obj is type of string.\n *\n * @api private\n * @param {Object} obj\n * @return {boolean}\n */\nexports.isString = function(obj) {\n  return typeof obj === 'string';\n};\n\n/**\n * Array#map (<=IE8)\n *\n * @api private\n * @param {Array} arr\n * @param {Function} fn\n * @param {Object} scope\n * @return {Array}\n */\nexports.map = function(arr, fn, scope) {\n  var result = [];\n  for (var i = 0, l = arr.length; i < l; i++) {\n    result.push(fn.call(scope, arr[i], i, arr));\n  }\n  return result;\n};\n\n/**\n * Array#indexOf (<=IE8)\n *\n * @api private\n * @param {Array} arr\n * @param {Object} obj to find index of\n * @param {number} start\n * @return {number}\n */\nvar indexOf = exports.indexOf = function(arr, obj, start) {\n  for (var i = start || 0, l = arr.length; i < l; i++) {\n    if (arr[i] === obj) {\n      return i;\n    }\n  }\n  return -1;\n};\n\n/**\n * Array#reduce (<=IE8)\n *\n * @api private\n * @param {Array} arr\n * @param {Function} fn\n * @param {Object} val Initial value.\n * @return {*}\n */\nvar reduce = exports.reduce = function(arr, fn, val) {\n  var rval = val;\n\n  for (var i = 0, l = arr.length; i < l; i++) {\n    rval = fn(rval, arr[i], i, arr);\n  }\n\n  return rval;\n};\n\n/**\n * Array#filter (<=IE8)\n *\n * @api private\n * @param {Array} arr\n * @param {Function} fn\n * @return {Array}\n */\nexports.filter = function(arr, fn) {\n  var ret = [];\n\n  for (var i = 0, l = arr.length; i < l; i++) {\n    var val = arr[i];\n    if (fn(val, i, arr)) {\n      ret.push(val);\n    }\n  }\n\n  return ret;\n};\n\n/**\n * Array#some (<=IE8)\n *\n * @api private\n * @param {Array} arr\n * @param {Function} fn\n * @return {Array}\n */\nexports.some = function(arr, fn) {\n  for (var i = 0, l = arr.length; i < l; i++) {\n    if (fn(arr[i])) {\n      return true;\n    }\n  }\n  return false;\n};\n\n/**\n * Object.keys (<=IE8)\n *\n * @api private\n * @param {Object} obj\n * @return {Array} keys\n */\nexports.keys = typeof Object.keys === 'function' ? Object.keys : function(obj) {\n  var keys = [];\n  var has = Object.prototype.hasOwnProperty; // for `window` on <=IE8\n\n  for (var key in obj) {\n    if (has.call(obj, key)) {\n      keys.push(key);\n    }\n  }\n\n  return keys;\n};\n\n/**\n * Watch the given `files` for changes\n * and invoke `fn(file)` on modification.\n *\n * @api private\n * @param {Array} files\n * @param {Function} fn\n */\nexports.watch = function(files, fn) {\n  var options = { interval: 100 };\n  files.forEach(function(file) {\n    debug('file %s', file);\n    watchFile(file, options, function(curr, prev) {\n      if (prev.mtime < curr.mtime) {\n        fn(file);\n      }\n    });\n  });\n};\n\n/**\n * Array.isArray (<=IE8)\n *\n * @api private\n * @param {Object} obj\n * @return {Boolean}\n */\nvar isArray = typeof Array.isArray === 'function' ? Array.isArray : function(obj) {\n  return Object.prototype.toString.call(obj) === '[object Array]';\n};\n\nexports.isArray = isArray;\n\n/**\n * Buffer.prototype.toJSON polyfill.\n *\n * @type {Function}\n */\nif (typeof Buffer !== 'undefined' && Buffer.prototype) {\n  Buffer.prototype.toJSON = Buffer.prototype.toJSON || function() {\n    return Array.prototype.slice.call(this, 0);\n  };\n}\n\n/**\n * Ignored files.\n *\n * @api private\n * @param {string} path\n * @return {boolean}\n */\nfunction ignored(path) {\n  return !~ignore.indexOf(path);\n}\n\n/**\n * Lookup files in the given `dir`.\n *\n * @api private\n * @param {string} dir\n * @param {string[]} [ext=['.js']]\n * @param {Array} [ret=[]]\n * @return {Array}\n */\nexports.files = function(dir, ext, ret) {\n  ret = ret || [];\n  ext = ext || ['js'];\n\n  var re = new RegExp('\\\\.(' + ext.join('|') + ')$');\n\n  readdirSync(dir)\n    .filter(ignored)\n    .forEach(function(path) {\n      path = join(dir, path);\n      if (statSync(path).isDirectory()) {\n        exports.files(path, ext, ret);\n      } else if (path.match(re)) {\n        ret.push(path);\n      }\n    });\n\n  return ret;\n};\n\n/**\n * Compute a slug from the given `str`.\n *\n * @api private\n * @param {string} str\n * @return {string}\n */\nexports.slug = function(str) {\n  return str\n    .toLowerCase()\n    .replace(/ +/g, '-')\n    .replace(/[^-\\w]/g, '');\n};\n\n/**\n * Strip the function definition from `str`, and re-indent for pre whitespace.\n *\n * @param {string} str\n * @return {string}\n */\nexports.clean = function(str) {\n  str = str\n    .replace(/\\r\\n?|[\\n\\u2028\\u2029]/g, '\\n').replace(/^\\uFEFF/, '')\n    // (traditional)->  space/name     parameters    body     (lambda)-> parameters       body   multi-statement/single          keep body content\n    .replace(/^function(?:\\s*|\\s+[^(]*)\\([^)]*\\)\\s*\\{((?:.|\\n)*?)\\s*\\}$|^\\([^)]*\\)\\s*=>\\s*(?:\\{((?:.|\\n)*?)\\s*\\}|((?:.|\\n)*))$/, '$1$2$3');\n\n  var spaces = str.match(/^\\n?( *)/)[1].length;\n  var tabs = str.match(/^\\n?(\\t*)/)[1].length;\n  var re = new RegExp('^\\n?' + (tabs ? '\\t' : ' ') + '{' + (tabs ? tabs : spaces) + '}', 'gm');\n\n  str = str.replace(re, '');\n\n  return exports.trim(str);\n};\n\n/**\n * Trim the given `str`.\n *\n * @api private\n * @param {string} str\n * @return {string}\n */\nexports.trim = function(str) {\n  return str.replace(/^\\s+|\\s+$/g, '');\n};\n\n/**\n * Parse the given `qs`.\n *\n * @api private\n * @param {string} qs\n * @return {Object}\n */\nexports.parseQuery = function(qs) {\n  return reduce(qs.replace('?', '').split('&'), function(obj, pair) {\n    var i = pair.indexOf('=');\n    var key = pair.slice(0, i);\n    var val = pair.slice(++i);\n\n    obj[key] = decodeURIComponent(val);\n    return obj;\n  }, {});\n};\n\n/**\n * Highlight the given string of `js`.\n *\n * @api private\n * @param {string} js\n * @return {string}\n */\nfunction highlight(js) {\n  return js\n    .replace(/</g, '&lt;')\n    .replace(/>/g, '&gt;')\n    .replace(/\\/\\/(.*)/gm, '<span class=\"comment\">//$1</span>')\n    .replace(/('.*?')/gm, '<span class=\"string\">$1</span>')\n    .replace(/(\\d+\\.\\d+)/gm, '<span class=\"number\">$1</span>')\n    .replace(/(\\d+)/gm, '<span class=\"number\">$1</span>')\n    .replace(/\\bnew[ \\t]+(\\w+)/gm, '<span class=\"keyword\">new</span> <span class=\"init\">$1</span>')\n    .replace(/\\b(function|new|throw|return|var|if|else)\\b/gm, '<span class=\"keyword\">$1</span>');\n}\n\n/**\n * Highlight the contents of tag `name`.\n *\n * @api private\n * @param {string} name\n */\nexports.highlightTags = function(name) {\n  var code = document.getElementById('mocha').getElementsByTagName(name);\n  for (var i = 0, len = code.length; i < len; ++i) {\n    code[i].innerHTML = highlight(code[i].innerHTML);\n  }\n};\n\n/**\n * If a value could have properties, and has none, this function is called,\n * which returns a string representation of the empty value.\n *\n * Functions w/ no properties return `'[Function]'`\n * Arrays w/ length === 0 return `'[]'`\n * Objects w/ no properties return `'{}'`\n * All else: return result of `value.toString()`\n *\n * @api private\n * @param {*} value The value to inspect.\n * @param {string} typeHint The type of the value\n * @returns {string}\n */\nfunction emptyRepresentation(value, typeHint) {\n  switch (typeHint) {\n    case 'function':\n      return '[Function]';\n    case 'object':\n      return '{}';\n    case 'array':\n      return '[]';\n    default:\n      return value.toString();\n  }\n}\n\n/**\n * Takes some variable and asks `Object.prototype.toString()` what it thinks it\n * is.\n *\n * @api private\n * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/toString\n * @param {*} value The value to test.\n * @returns {string} Computed type\n * @example\n * type({}) // 'object'\n * type([]) // 'array'\n * type(1) // 'number'\n * type(false) // 'boolean'\n * type(Infinity) // 'number'\n * type(null) // 'null'\n * type(new Date()) // 'date'\n * type(/foo/) // 'regexp'\n * type('type') // 'string'\n * type(global) // 'global'\n * type(new String('foo') // 'object'\n */\nvar type = exports.type = function type(value) {\n  if (value === undefined) {\n    return 'undefined';\n  } else if (value === null) {\n    return 'null';\n  } else if (typeof Buffer !== 'undefined' && Buffer.isBuffer(value)) {\n    return 'buffer';\n  }\n  return Object.prototype.toString.call(value)\n    .replace(/^\\[.+\\s(.+?)\\]$/, '$1')\n    .toLowerCase();\n};\n\n/**\n * Stringify `value`. Different behavior depending on type of value:\n *\n * - If `value` is undefined or null, return `'[undefined]'` or `'[null]'`, respectively.\n * - If `value` is not an object, function or array, return result of `value.toString()` wrapped in double-quotes.\n * - If `value` is an *empty* object, function, or array, return result of function\n *   {@link emptyRepresentation}.\n * - If `value` has properties, call {@link exports.canonicalize} on it, then return result of\n *   JSON.stringify().\n *\n * @api private\n * @see exports.type\n * @param {*} value\n * @return {string}\n */\nexports.stringify = function(value) {\n  var typeHint = type(value);\n\n  if (!~indexOf(['object', 'array', 'function'], typeHint)) {\n    if (typeHint === 'buffer') {\n      var json = value.toJSON();\n      // Based on the toJSON result\n      return jsonStringify(json.data && json.type ? json.data : json, 2)\n        .replace(/,(\\n|$)/g, '$1');\n    }\n\n    // IE7/IE8 has a bizarre String constructor; needs to be coerced\n    // into an array and back to obj.\n    if (typeHint === 'string' && typeof value === 'object') {\n      value = reduce(value.split(''), function(acc, char, idx) {\n        acc[idx] = char;\n        return acc;\n      }, {});\n      typeHint = 'object';\n    } else {\n      return jsonStringify(value);\n    }\n  }\n\n  for (var prop in value) {\n    if (Object.prototype.hasOwnProperty.call(value, prop)) {\n      return jsonStringify(exports.canonicalize(value, null, typeHint), 2).replace(/,(\\n|$)/g, '$1');\n    }\n  }\n\n  return emptyRepresentation(value, typeHint);\n};\n\n/**\n * like JSON.stringify but more sense.\n *\n * @api private\n * @param {Object}  object\n * @param {number=} spaces\n * @param {number=} depth\n * @returns {*}\n */\nfunction jsonStringify(object, spaces, depth) {\n  if (typeof spaces === 'undefined') {\n    // primitive types\n    return _stringify(object);\n  }\n\n  depth = depth || 1;\n  var space = spaces * depth;\n  var str = isArray(object) ? '[' : '{';\n  var end = isArray(object) ? ']' : '}';\n  var length = typeof object.length === 'number' ? object.length : exports.keys(object).length;\n  // `.repeat()` polyfill\n  function repeat(s, n) {\n    return new Array(n).join(s);\n  }\n\n  function _stringify(val) {\n    switch (type(val)) {\n      case 'null':\n      case 'undefined':\n        val = '[' + val + ']';\n        break;\n      case 'array':\n      case 'object':\n        val = jsonStringify(val, spaces, depth + 1);\n        break;\n      case 'boolean':\n      case 'regexp':\n      case 'symbol':\n      case 'number':\n        val = val === 0 && (1 / val) === -Infinity // `-0`\n          ? '-0'\n          : val.toString();\n        break;\n      case 'date':\n        var sDate;\n        if (isNaN(val.getTime())) { // Invalid date\n          sDate = val.toString();\n        } else {\n          sDate = val.toISOString ? val.toISOString() : toISOString(val);\n        }\n        val = '[Date: ' + sDate + ']';\n        break;\n      case 'buffer':\n        var json = val.toJSON();\n        // Based on the toJSON result\n        json = json.data && json.type ? json.data : json;\n        val = '[Buffer: ' + jsonStringify(json, 2, depth + 1) + ']';\n        break;\n      default:\n        val = (val === '[Function]' || val === '[Circular]')\n          ? val\n          : JSON.stringify(val); // string\n    }\n    return val;\n  }\n\n  for (var i in object) {\n    if (!Object.prototype.hasOwnProperty.call(object, i)) {\n      continue; // not my business\n    }\n    --length;\n    str += '\\n ' + repeat(' ', space)\n      + (isArray(object) ? '' : '\"' + i + '\": ') // key\n      + _stringify(object[i])                     // value\n      + (length ? ',' : '');                     // comma\n  }\n\n  return str\n    // [], {}\n    + (str.length !== 1 ? '\\n' + repeat(' ', --space) + end : end);\n}\n\n/**\n * Test if a value is a buffer.\n *\n * @api private\n * @param {*} value The value to test.\n * @return {boolean} True if `value` is a buffer, otherwise false\n */\nexports.isBuffer = function(value) {\n  return typeof Buffer !== 'undefined' && Buffer.isBuffer(value);\n};\n\n/**\n * Return a new Thing that has the keys in sorted order. Recursive.\n *\n * If the Thing...\n * - has already been seen, return string `'[Circular]'`\n * - is `undefined`, return string `'[undefined]'`\n * - is `null`, return value `null`\n * - is some other primitive, return the value\n * - is not a primitive or an `Array`, `Object`, or `Function`, return the value of the Thing's `toString()` method\n * - is a non-empty `Array`, `Object`, or `Function`, return the result of calling this function again.\n * - is an empty `Array`, `Object`, or `Function`, return the result of calling `emptyRepresentation()`\n *\n * @api private\n * @see {@link exports.stringify}\n * @param {*} value Thing to inspect.  May or may not have properties.\n * @param {Array} [stack=[]] Stack of seen values\n * @param {string} [typeHint] Type hint\n * @return {(Object|Array|Function|string|undefined)}\n */\nexports.canonicalize = function canonicalize(value, stack, typeHint) {\n  var canonicalizedObj;\n  /* eslint-disable no-unused-vars */\n  var prop;\n  /* eslint-enable no-unused-vars */\n  typeHint = typeHint || type(value);\n  function withStack(value, fn) {\n    stack.push(value);\n    fn();\n    stack.pop();\n  }\n\n  stack = stack || [];\n\n  if (indexOf(stack, value) !== -1) {\n    return '[Circular]';\n  }\n\n  switch (typeHint) {\n    case 'undefined':\n    case 'buffer':\n    case 'null':\n      canonicalizedObj = value;\n      break;\n    case 'array':\n      withStack(value, function() {\n        canonicalizedObj = exports.map(value, function(item) {\n          return exports.canonicalize(item, stack);\n        });\n      });\n      break;\n    case 'function':\n      /* eslint-disable guard-for-in */\n      for (prop in value) {\n        canonicalizedObj = {};\n        break;\n      }\n      /* eslint-enable guard-for-in */\n      if (!canonicalizedObj) {\n        canonicalizedObj = emptyRepresentation(value, typeHint);\n        break;\n      }\n    /* falls through */\n    case 'object':\n      canonicalizedObj = canonicalizedObj || {};\n      withStack(value, function() {\n        exports.forEach(exports.keys(value).sort(), function(key) {\n          canonicalizedObj[key] = exports.canonicalize(value[key], stack);\n        });\n      });\n      break;\n    case 'date':\n    case 'number':\n    case 'regexp':\n    case 'boolean':\n    case 'symbol':\n      canonicalizedObj = value;\n      break;\n    default:\n      canonicalizedObj = value + '';\n  }\n\n  return canonicalizedObj;\n};\n\n/**\n * Lookup file names at the given `path`.\n *\n * @api public\n * @param {string} path Base path to start searching from.\n * @param {string[]} extensions File extensions to look for.\n * @param {boolean} recursive Whether or not to recurse into subdirectories.\n * @return {string[]} An array of paths.\n */\nexports.lookupFiles = function lookupFiles(path, extensions, recursive) {\n  var files = [];\n  var re = new RegExp('\\\\.(' + extensions.join('|') + ')$');\n\n  if (!exists(path)) {\n    if (exists(path + '.js')) {\n      path += '.js';\n    } else {\n      files = glob.sync(path);\n      if (!files.length) {\n        throw new Error(\"cannot resolve path (or pattern) '\" + path + \"'\");\n      }\n      return files;\n    }\n  }\n\n  try {\n    var stat = statSync(path);\n    if (stat.isFile()) {\n      return path;\n    }\n  } catch (err) {\n    // ignore error\n    return;\n  }\n\n  readdirSync(path).forEach(function(file) {\n    file = join(path, file);\n    try {\n      var stat = statSync(file);\n      if (stat.isDirectory()) {\n        if (recursive) {\n          files = files.concat(lookupFiles(file, extensions, recursive));\n        }\n        return;\n      }\n    } catch (err) {\n      // ignore error\n      return;\n    }\n    if (!stat.isFile() || !re.test(file) || basename(file)[0] === '.') {\n      return;\n    }\n    files.push(file);\n  });\n\n  return files;\n};\n\n/**\n * Generate an undefined error with a message warning the user.\n *\n * @return {Error}\n */\n\nexports.undefinedError = function() {\n  return new Error('Caught undefined error, did you throw without specifying what?');\n};\n\n/**\n * Generate an undefined error if `err` is not defined.\n *\n * @param {Error} err\n * @return {Error}\n */\n\nexports.getError = function(err) {\n  return err || exports.undefinedError();\n};\n\n/**\n * @summary\n * This Filter based on `mocha-clean` module.(see: `github.com/rstacruz/mocha-clean`)\n * @description\n * When invoking this function you get a filter function that get the Error.stack as an input,\n * and return a prettify output.\n * (i.e: strip Mocha and internal node functions from stack trace).\n * @returns {Function}\n */\nexports.stackTraceFilter = function() {\n  // TODO: Replace with `process.browser`\n  var is = typeof document === 'undefined' ? { node: true } : { browser: true };\n  var slash = path.sep;\n  var cwd;\n  if (is.node) {\n    cwd = process.cwd() + slash;\n  } else {\n    cwd = (typeof location === 'undefined' ? window.location : location).href.replace(/\\/[^\\/]*$/, '/');\n    slash = '/';\n  }\n\n  function isMochaInternal(line) {\n    return (~line.indexOf('node_modules' + slash + 'mocha' + slash))\n      || (~line.indexOf('node_modules' + slash + 'mocha.js'))\n      || (~line.indexOf('bower_components' + slash + 'mocha.js'))\n      || (~line.indexOf(slash + 'mocha.js'));\n  }\n\n  function isNodeInternal(line) {\n    return (~line.indexOf('(timers.js:'))\n      || (~line.indexOf('(events.js:'))\n      || (~line.indexOf('(node.js:'))\n      || (~line.indexOf('(module.js:'))\n      || (~line.indexOf('GeneratorFunctionPrototype.next (native)'))\n      || false;\n  }\n\n  return function(stack) {\n    stack = stack.split('\\n');\n\n    stack = reduce(stack, function(list, line) {\n      if (isMochaInternal(line)) {\n        return list;\n      }\n\n      if (is.node && isNodeInternal(line)) {\n        return list;\n      }\n\n      // Clean up cwd(absolute)\n      if (/\\(?.+:\\d+:\\d+\\)?$/.test(line)) {\n        line = line.replace(cwd, '');\n      }\n\n      list.push(line);\n      return list;\n    }, []);\n\n    return stack.join('\\n');\n  };\n};\n\n/**\n * Crude, but effective.\n * @api\n * @param {*} value\n * @returns {boolean} Whether or not `value` is a Promise\n */\nexports.isPromise = function isPromise(value) {\n  return typeof value === 'object' && typeof value.then === 'function';\n};\n\n}).call(this,require('_process'),require(\"buffer\").Buffer)\n},{\"./to-iso-string\":37,\"_process\":67,\"buffer\":44,\"debug\":2,\"fs\":42,\"glob\":42,\"json3\":54,\"path\":42,\"util\":84}],39:[function(require,module,exports){\n'use strict'\n\nexports.toByteArray = toByteArray\nexports.fromByteArray = fromByteArray\n\nvar lookup = []\nvar revLookup = []\nvar Arr = typeof Uint8Array !== 'undefined' ? Uint8Array : Array\n\nfunction init () {\n  var code = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'\n  for (var i = 0, len = code.length; i < len; ++i) {\n    lookup[i] = code[i]\n    revLookup[code.charCodeAt(i)] = i\n  }\n\n  revLookup['-'.charCodeAt(0)] = 62\n  revLookup['_'.charCodeAt(0)] = 63\n}\n\ninit()\n\nfunction toByteArray (b64) {\n  var i, j, l, tmp, placeHolders, arr\n  var len = b64.length\n\n  if (len % 4 > 0) {\n    throw new Error('Invalid string. Length must be a multiple of 4')\n  }\n\n  // the number of equal signs (place holders)\n  // if there are two placeholders, than the two characters before it\n  // represent one byte\n  // if there is only one, then the three characters before it represent 2 bytes\n  // this is just a cheap hack to not do indexOf twice\n  placeHolders = b64[len - 2] === '=' ? 2 : b64[len - 1] === '=' ? 1 : 0\n\n  // base64 is 4/3 + up to two characters of the original data\n  arr = new Arr(len * 3 / 4 - placeHolders)\n\n  // if there are placeholders, only get up to the last complete 4 chars\n  l = placeHolders > 0 ? len - 4 : len\n\n  var L = 0\n\n  for (i = 0, j = 0; i < l; i += 4, j += 3) {\n    tmp = (revLookup[b64.charCodeAt(i)] << 18) | (revLookup[b64.charCodeAt(i + 1)] << 12) | (revLookup[b64.charCodeAt(i + 2)] << 6) | revLookup[b64.charCodeAt(i + 3)]\n    arr[L++] = (tmp >> 16) & 0xFF\n    arr[L++] = (tmp >> 8) & 0xFF\n    arr[L++] = tmp & 0xFF\n  }\n\n  if (placeHolders === 2) {\n    tmp = (revLookup[b64.charCodeAt(i)] << 2) | (revLookup[b64.charCodeAt(i + 1)] >> 4)\n    arr[L++] = tmp & 0xFF\n  } else if (placeHolders === 1) {\n    tmp = (revLookup[b64.charCodeAt(i)] << 10) | (revLookup[b64.charCodeAt(i + 1)] << 4) | (revLookup[b64.charCodeAt(i + 2)] >> 2)\n    arr[L++] = (tmp >> 8) & 0xFF\n    arr[L++] = tmp & 0xFF\n  }\n\n  return arr\n}\n\nfunction tripletToBase64 (num) {\n  return lookup[num >> 18 & 0x3F] + lookup[num >> 12 & 0x3F] + lookup[num >> 6 & 0x3F] + lookup[num & 0x3F]\n}\n\nfunction encodeChunk (uint8, start, end) {\n  var tmp\n  var output = []\n  for (var i = start; i < end; i += 3) {\n    tmp = (uint8[i] << 16) + (uint8[i + 1] << 8) + (uint8[i + 2])\n    output.push(tripletToBase64(tmp))\n  }\n  return output.join('')\n}\n\nfunction fromByteArray (uint8) {\n  var tmp\n  var len = uint8.length\n  var extraBytes = len % 3 // if we have 1 byte left, pad 2 bytes\n  var output = ''\n  var parts = []\n  var maxChunkLength = 16383 // must be multiple of 3\n\n  // go through the array every three bytes, we'll deal with trailing stuff later\n  for (var i = 0, len2 = len - extraBytes; i < len2; i += maxChunkLength) {\n    parts.push(encodeChunk(uint8, i, (i + maxChunkLength) > len2 ? len2 : (i + maxChunkLength)))\n  }\n\n  // pad the end with zeros, but make sure to not forget the extra bytes\n  if (extraBytes === 1) {\n    tmp = uint8[len - 1]\n    output += lookup[tmp >> 2]\n    output += lookup[(tmp << 4) & 0x3F]\n    output += '=='\n  } else if (extraBytes === 2) {\n    tmp = (uint8[len - 2] << 8) + (uint8[len - 1])\n    output += lookup[tmp >> 10]\n    output += lookup[(tmp >> 4) & 0x3F]\n    output += lookup[(tmp << 2) & 0x3F]\n    output += '='\n  }\n\n  parts.push(output)\n\n  return parts.join('')\n}\n\n},{}],40:[function(require,module,exports){\n\n},{}],41:[function(require,module,exports){\n(function (process){\nvar WritableStream = require('stream').Writable\nvar inherits = require('util').inherits\n\nmodule.exports = BrowserStdout\n\n\ninherits(BrowserStdout, WritableStream)\n\nfunction BrowserStdout(opts) {\n  if (!(this instanceof BrowserStdout)) return new BrowserStdout(opts)\n\n  opts = opts || {}\n  WritableStream.call(this, opts)\n  this.label = (opts.label !== undefined) ? opts.label : 'stdout'\n}\n\nBrowserStdout.prototype._write = function(chunks, encoding, cb) {\n  var output = chunks.toString ? chunks.toString() : chunks\n  if (this.label === false) {\n    console.log(output)\n  } else {\n    console.log(this.label+':', output)\n  }\n  process.nextTick(cb)\n}\n\n}).call(this,require('_process'))\n},{\"_process\":67,\"stream\":79,\"util\":84}],42:[function(require,module,exports){\narguments[4][40][0].apply(exports,arguments)\n},{\"dup\":40}],43:[function(require,module,exports){\n(function (global){\n'use strict';\n\nvar buffer = require('buffer');\nvar Buffer = buffer.Buffer;\nvar SlowBuffer = buffer.SlowBuffer;\nvar MAX_LEN = buffer.kMaxLength || 2147483647;\nexports.alloc = function alloc(size, fill, encoding) {\n  if (typeof Buffer.alloc === 'function') {\n    return Buffer.alloc(size, fill, encoding);\n  }\n  if (typeof encoding === 'number') {\n    throw new TypeError('encoding must not be number');\n  }\n  if (typeof size !== 'number') {\n    throw new TypeError('size must be a number');\n  }\n  if (size > MAX_LEN) {\n    throw new RangeError('size is too large');\n  }\n  var enc = encoding;\n  var _fill = fill;\n  if (_fill === undefined) {\n    enc = undefined;\n    _fill = 0;\n  }\n  var buf = new Buffer(size);\n  if (typeof _fill === 'string') {\n    var fillBuf = new Buffer(_fill, enc);\n    var flen = fillBuf.length;\n    var i = -1;\n    while (++i < size) {\n      buf[i] = fillBuf[i % flen];\n    }\n  } else {\n    buf.fill(_fill);\n  }\n  return buf;\n}\nexports.allocUnsafe = function allocUnsafe(size) {\n  if (typeof Buffer.allocUnsafe === 'function') {\n    return Buffer.allocUnsafe(size);\n  }\n  if (typeof size !== 'number') {\n    throw new TypeError('size must be a number');\n  }\n  if (size > MAX_LEN) {\n    throw new RangeError('size is too large');\n  }\n  return new Buffer(size);\n}\nexports.from = function from(value, encodingOrOffset, length) {\n  if (typeof Buffer.from === 'function' && (!global.Uint8Array || Uint8Array.from !== Buffer.from)) {\n    return Buffer.from(value, encodingOrOffset, length);\n  }\n  if (typeof value === 'number') {\n    throw new TypeError('\"value\" argument must not be a number');\n  }\n  if (typeof value === 'string') {\n    return new Buffer(value, encodingOrOffset);\n  }\n  if (typeof ArrayBuffer !== 'undefined' && value instanceof ArrayBuffer) {\n    var offset = encodingOrOffset;\n    if (arguments.length === 1) {\n      return new Buffer(value);\n    }\n    if (typeof offset === 'undefined') {\n      offset = 0;\n    }\n    var len = length;\n    if (typeof len === 'undefined') {\n      len = value.byteLength - offset;\n    }\n    if (offset >= value.byteLength) {\n      throw new RangeError('\\'offset\\' is out of bounds');\n    }\n    if (len > value.byteLength - offset) {\n      throw new RangeError('\\'length\\' is out of bounds');\n    }\n    return new Buffer(value.slice(offset, offset + len));\n  }\n  if (Buffer.isBuffer(value)) {\n    var out = new Buffer(value.length);\n    value.copy(out, 0, 0, value.length);\n    return out;\n  }\n  if (value) {\n    if (Array.isArray(value) || (typeof ArrayBuffer !== 'undefined' && value.buffer instanceof ArrayBuffer) || 'length' in value) {\n      return new Buffer(value);\n    }\n    if (value.type === 'Buffer' && Array.isArray(value.data)) {\n      return new Buffer(value.data);\n    }\n  }\n\n  throw new TypeError('First argument must be a string, Buffer, ' + 'ArrayBuffer, Array, or array-like object.');\n}\nexports.allocUnsafeSlow = function allocUnsafeSlow(size) {\n  if (typeof Buffer.allocUnsafeSlow === 'function') {\n    return Buffer.allocUnsafeSlow(size);\n  }\n  if (typeof size !== 'number') {\n    throw new TypeError('size must be a number');\n  }\n  if (size >= MAX_LEN) {\n    throw new RangeError('size is too large');\n  }\n  return new SlowBuffer(size);\n}\n\n}).call(this,typeof global !== \"undefined\" ? global : typeof self !== \"undefined\" ? self : typeof window !== \"undefined\" ? window : {})\n},{\"buffer\":44}],44:[function(require,module,exports){\n(function (global){\n/*!\n * The buffer module from node.js, for the browser.\n *\n * @author   Feross Aboukhadijeh <feross@feross.org> <http://feross.org>\n * @license  MIT\n */\n/* eslint-disable no-proto */\n\n'use strict'\n\nvar base64 = require('base64-js')\nvar ieee754 = require('ieee754')\nvar isArray = require('isarray')\n\nexports.Buffer = Buffer\nexports.SlowBuffer = SlowBuffer\nexports.INSPECT_MAX_BYTES = 50\n\n/**\n * If `Buffer.TYPED_ARRAY_SUPPORT`:\n *   === true    Use Uint8Array implementation (fastest)\n *   === false   Use Object implementation (most compatible, even IE6)\n *\n * Browsers that support typed arrays are IE 10+, Firefox 4+, Chrome 7+, Safari 5.1+,\n * Opera 11.6+, iOS 4.2+.\n *\n * Due to various browser bugs, sometimes the Object implementation will be used even\n * when the browser supports typed arrays.\n *\n * Note:\n *\n *   - Firefox 4-29 lacks support for adding new properties to `Uint8Array` instances,\n *     See: https://bugzilla.mozilla.org/show_bug.cgi?id=695438.\n *\n *   - Chrome 9-10 is missing the `TypedArray.prototype.subarray` function.\n *\n *   - IE10 has a broken `TypedArray.prototype.subarray` function which returns arrays of\n *     incorrect length in some situations.\n\n * We detect these buggy browsers and set `Buffer.TYPED_ARRAY_SUPPORT` to `false` so they\n * get the Object implementation, which is slower but behaves correctly.\n */\nBuffer.TYPED_ARRAY_SUPPORT = global.TYPED_ARRAY_SUPPORT !== undefined\n  ? global.TYPED_ARRAY_SUPPORT\n  : typedArraySupport()\n\n/*\n * Export kMaxLength after typed array support is determined.\n */\nexports.kMaxLength = kMaxLength()\n\nfunction typedArraySupport () {\n  try {\n    var arr = new Uint8Array(1)\n    arr.__proto__ = {__proto__: Uint8Array.prototype, foo: function () { return 42 }}\n    return arr.foo() === 42 && // typed array instances can be augmented\n        typeof arr.subarray === 'function' && // chrome 9-10 lack `subarray`\n        arr.subarray(1, 1).byteLength === 0 // ie10 has broken `subarray`\n  } catch (e) {\n    return false\n  }\n}\n\nfunction kMaxLength () {\n  return Buffer.TYPED_ARRAY_SUPPORT\n    ? 0x7fffffff\n    : 0x3fffffff\n}\n\nfunction createBuffer (that, length) {\n  if (kMaxLength() < length) {\n    throw new RangeError('Invalid typed array length')\n  }\n  if (Buffer.TYPED_ARRAY_SUPPORT) {\n    // Return an augmented `Uint8Array` instance, for best performance\n    that = new Uint8Array(length)\n    that.__proto__ = Buffer.prototype\n  } else {\n    // Fallback: Return an object instance of the Buffer class\n    if (that === null) {\n      that = new Buffer(length)\n    }\n    that.length = length\n  }\n\n  return that\n}\n\n/**\n * The Buffer constructor returns instances of `Uint8Array` that have their\n * prototype changed to `Buffer.prototype`. Furthermore, `Buffer` is a subclass of\n * `Uint8Array`, so the returned instances will have all the node `Buffer` methods\n * and the `Uint8Array` methods. Square bracket notation works as expected -- it\n * returns a single octet.\n *\n * The `Uint8Array` prototype remains unmodified.\n */\n\nfunction Buffer (arg, encodingOrOffset, length) {\n  if (!Buffer.TYPED_ARRAY_SUPPORT && !(this instanceof Buffer)) {\n    return new Buffer(arg, encodingOrOffset, length)\n  }\n\n  // Common case.\n  if (typeof arg === 'number') {\n    if (typeof encodingOrOffset === 'string') {\n      throw new Error(\n        'If encoding is specified then the first argument must be a string'\n      )\n    }\n    return allocUnsafe(this, arg)\n  }\n  return from(this, arg, encodingOrOffset, length)\n}\n\nBuffer.poolSize = 8192 // not used by this implementation\n\n// TODO: Legacy, not needed anymore. Remove in next major version.\nBuffer._augment = function (arr) {\n  arr.__proto__ = Buffer.prototype\n  return arr\n}\n\nfunction from (that, value, encodingOrOffset, length) {\n  if (typeof value === 'number') {\n    throw new TypeError('\"value\" argument must not be a number')\n  }\n\n  if (typeof ArrayBuffer !== 'undefined' && value instanceof ArrayBuffer) {\n    return fromArrayBuffer(that, value, encodingOrOffset, length)\n  }\n\n  if (typeof value === 'string') {\n    return fromString(that, value, encodingOrOffset)\n  }\n\n  return fromObject(that, value)\n}\n\n/**\n * Functionally equivalent to Buffer(arg, encoding) but throws a TypeError\n * if value is a number.\n * Buffer.from(str[, encoding])\n * Buffer.from(array)\n * Buffer.from(buffer)\n * Buffer.from(arrayBuffer[, byteOffset[, length]])\n **/\nBuffer.from = function (value, encodingOrOffset, length) {\n  return from(null, value, encodingOrOffset, length)\n}\n\nif (Buffer.TYPED_ARRAY_SUPPORT) {\n  Buffer.prototype.__proto__ = Uint8Array.prototype\n  Buffer.__proto__ = Uint8Array\n  if (typeof Symbol !== 'undefined' && Symbol.species &&\n      Buffer[Symbol.species] === Buffer) {\n    // Fix subarray() in ES2016. See: https://github.com/feross/buffer/pull/97\n    Object.defineProperty(Buffer, Symbol.species, {\n      value: null,\n      configurable: true\n    })\n  }\n}\n\nfunction assertSize (size) {\n  if (typeof size !== 'number') {\n    throw new TypeError('\"size\" argument must be a number')\n  } else if (size < 0) {\n    throw new RangeError('\"size\" argument must not be negative')\n  }\n}\n\nfunction alloc (that, size, fill, encoding) {\n  assertSize(size)\n  if (size <= 0) {\n    return createBuffer(that, size)\n  }\n  if (fill !== undefined) {\n    // Only pay attention to encoding if it's a string. This\n    // prevents accidentally sending in a number that would\n    // be interpretted as a start offset.\n    return typeof encoding === 'string'\n      ? createBuffer(that, size).fill(fill, encoding)\n      : createBuffer(that, size).fill(fill)\n  }\n  return createBuffer(that, size)\n}\n\n/**\n * Creates a new filled Buffer instance.\n * alloc(size[, fill[, encoding]])\n **/\nBuffer.alloc = function (size, fill, encoding) {\n  return alloc(null, size, fill, encoding)\n}\n\nfunction allocUnsafe (that, size) {\n  assertSize(size)\n  that = createBuffer(that, size < 0 ? 0 : checked(size) | 0)\n  if (!Buffer.TYPED_ARRAY_SUPPORT) {\n    for (var i = 0; i < size; ++i) {\n      that[i] = 0\n    }\n  }\n  return that\n}\n\n/**\n * Equivalent to Buffer(num), by default creates a non-zero-filled Buffer instance.\n * */\nBuffer.allocUnsafe = function (size) {\n  return allocUnsafe(null, size)\n}\n/**\n * Equivalent to SlowBuffer(num), by default creates a non-zero-filled Buffer instance.\n */\nBuffer.allocUnsafeSlow = function (size) {\n  return allocUnsafe(null, size)\n}\n\nfunction fromString (that, string, encoding) {\n  if (typeof encoding !== 'string' || encoding === '') {\n    encoding = 'utf8'\n  }\n\n  if (!Buffer.isEncoding(encoding)) {\n    throw new TypeError('\"encoding\" must be a valid string encoding')\n  }\n\n  var length = byteLength(string, encoding) | 0\n  that = createBuffer(that, length)\n\n  var actual = that.write(string, encoding)\n\n  if (actual !== length) {\n    // Writing a hex string, for example, that contains invalid characters will\n    // cause everything after the first invalid character to be ignored. (e.g.\n    // 'abxxcd' will be treated as 'ab')\n    that = that.slice(0, actual)\n  }\n\n  return that\n}\n\nfunction fromArrayLike (that, array) {\n  var length = array.length < 0 ? 0 : checked(array.length) | 0\n  that = createBuffer(that, length)\n  for (var i = 0; i < length; i += 1) {\n    that[i] = array[i] & 255\n  }\n  return that\n}\n\nfunction fromArrayBuffer (that, array, byteOffset, length) {\n  array.byteLength // this throws if `array` is not a valid ArrayBuffer\n\n  if (byteOffset < 0 || array.byteLength < byteOffset) {\n    throw new RangeError('\\'offset\\' is out of bounds')\n  }\n\n  if (array.byteLength < byteOffset + (length || 0)) {\n    throw new RangeError('\\'length\\' is out of bounds')\n  }\n\n  if (byteOffset === undefined && length === undefined) {\n    array = new Uint8Array(array)\n  } else if (length === undefined) {\n    array = new Uint8Array(array, byteOffset)\n  } else {\n    array = new Uint8Array(array, byteOffset, length)\n  }\n\n  if (Buffer.TYPED_ARRAY_SUPPORT) {\n    // Return an augmented `Uint8Array` instance, for best performance\n    that = array\n    that.__proto__ = Buffer.prototype\n  } else {\n    // Fallback: Return an object instance of the Buffer class\n    that = fromArrayLike(that, array)\n  }\n  return that\n}\n\nfunction fromObject (that, obj) {\n  if (Buffer.isBuffer(obj)) {\n    var len = checked(obj.length) | 0\n    that = createBuffer(that, len)\n\n    if (that.length === 0) {\n      return that\n    }\n\n    obj.copy(that, 0, 0, len)\n    return that\n  }\n\n  if (obj) {\n    if ((typeof ArrayBuffer !== 'undefined' &&\n        obj.buffer instanceof ArrayBuffer) || 'length' in obj) {\n      if (typeof obj.length !== 'number' || isnan(obj.length)) {\n        return createBuffer(that, 0)\n      }\n      return fromArrayLike(that, obj)\n    }\n\n    if (obj.type === 'Buffer' && isArray(obj.data)) {\n      return fromArrayLike(that, obj.data)\n    }\n  }\n\n  throw new TypeError('First argument must be a string, Buffer, ArrayBuffer, Array, or array-like object.')\n}\n\nfunction checked (length) {\n  // Note: cannot use `length < kMaxLength()` here because that fails when\n  // length is NaN (which is otherwise coerced to zero.)\n  if (length >= kMaxLength()) {\n    throw new RangeError('Attempt to allocate Buffer larger than maximum ' +\n                         'size: 0x' + kMaxLength().toString(16) + ' bytes')\n  }\n  return length | 0\n}\n\nfunction SlowBuffer (length) {\n  if (+length != length) { // eslint-disable-line eqeqeq\n    length = 0\n  }\n  return Buffer.alloc(+length)\n}\n\nBuffer.isBuffer = function isBuffer (b) {\n  return !!(b != null && b._isBuffer)\n}\n\nBuffer.compare = function compare (a, b) {\n  if (!Buffer.isBuffer(a) || !Buffer.isBuffer(b)) {\n    throw new TypeError('Arguments must be Buffers')\n  }\n\n  if (a === b) return 0\n\n  var x = a.length\n  var y = b.length\n\n  for (var i = 0, len = Math.min(x, y); i < len; ++i) {\n    if (a[i] !== b[i]) {\n      x = a[i]\n      y = b[i]\n      break\n    }\n  }\n\n  if (x < y) return -1\n  if (y < x) return 1\n  return 0\n}\n\nBuffer.isEncoding = function isEncoding (encoding) {\n  switch (String(encoding).toLowerCase()) {\n    case 'hex':\n    case 'utf8':\n    case 'utf-8':\n    case 'ascii':\n    case 'latin1':\n    case 'binary':\n    case 'base64':\n    case 'ucs2':\n    case 'ucs-2':\n    case 'utf16le':\n    case 'utf-16le':\n      return true\n    default:\n      return false\n  }\n}\n\nBuffer.concat = function concat (list, length) {\n  if (!isArray(list)) {\n    throw new TypeError('\"list\" argument must be an Array of Buffers')\n  }\n\n  if (list.length === 0) {\n    return Buffer.alloc(0)\n  }\n\n  var i\n  if (length === undefined) {\n    length = 0\n    for (i = 0; i < list.length; ++i) {\n      length += list[i].length\n    }\n  }\n\n  var buffer = Buffer.allocUnsafe(length)\n  var pos = 0\n  for (i = 0; i < list.length; ++i) {\n    var buf = list[i]\n    if (!Buffer.isBuffer(buf)) {\n      throw new TypeError('\"list\" argument must be an Array of Buffers')\n    }\n    buf.copy(buffer, pos)\n    pos += buf.length\n  }\n  return buffer\n}\n\nfunction byteLength (string, encoding) {\n  if (Buffer.isBuffer(string)) {\n    return string.length\n  }\n  if (typeof ArrayBuffer !== 'undefined' && typeof ArrayBuffer.isView === 'function' &&\n      (ArrayBuffer.isView(string) || string instanceof ArrayBuffer)) {\n    return string.byteLength\n  }\n  if (typeof string !== 'string') {\n    string = '' + string\n  }\n\n  var len = string.length\n  if (len === 0) return 0\n\n  // Use a for loop to avoid recursion\n  var loweredCase = false\n  for (;;) {\n    switch (encoding) {\n      case 'ascii':\n      case 'latin1':\n      case 'binary':\n        return len\n      case 'utf8':\n      case 'utf-8':\n      case undefined:\n        return utf8ToBytes(string).length\n      case 'ucs2':\n      case 'ucs-2':\n      case 'utf16le':\n      case 'utf-16le':\n        return len * 2\n      case 'hex':\n        return len >>> 1\n      case 'base64':\n        return base64ToBytes(string).length\n      default:\n        if (loweredCase) return utf8ToBytes(string).length // assume utf8\n        encoding = ('' + encoding).toLowerCase()\n        loweredCase = true\n    }\n  }\n}\nBuffer.byteLength = byteLength\n\nfunction slowToString (encoding, start, end) {\n  var loweredCase = false\n\n  // No need to verify that \"this.length <= MAX_UINT32\" since it's a read-only\n  // property of a typed array.\n\n  // This behaves neither like String nor Uint8Array in that we set start/end\n  // to their upper/lower bounds if the value passed is out of range.\n  // undefined is handled specially as per ECMA-262 6th Edition,\n  // Section 13.3.3.7 Runtime Semantics: KeyedBindingInitialization.\n  if (start === undefined || start < 0) {\n    start = 0\n  }\n  // Return early if start > this.length. Done here to prevent potential uint32\n  // coercion fail below.\n  if (start > this.length) {\n    return ''\n  }\n\n  if (end === undefined || end > this.length) {\n    end = this.length\n  }\n\n  if (end <= 0) {\n    return ''\n  }\n\n  // Force coersion to uint32. This will also coerce falsey/NaN values to 0.\n  end >>>= 0\n  start >>>= 0\n\n  if (end <= start) {\n    return ''\n  }\n\n  if (!encoding) encoding = 'utf8'\n\n  while (true) {\n    switch (encoding) {\n      case 'hex':\n        return hexSlice(this, start, end)\n\n      case 'utf8':\n      case 'utf-8':\n        return utf8Slice(this, start, end)\n\n      case 'ascii':\n        return asciiSlice(this, start, end)\n\n      case 'latin1':\n      case 'binary':\n        return latin1Slice(this, start, end)\n\n      case 'base64':\n        return base64Slice(this, start, end)\n\n      case 'ucs2':\n      case 'ucs-2':\n      case 'utf16le':\n      case 'utf-16le':\n        return utf16leSlice(this, start, end)\n\n      default:\n        if (loweredCase) throw new TypeError('Unknown encoding: ' + encoding)\n        encoding = (encoding + '').toLowerCase()\n        loweredCase = true\n    }\n  }\n}\n\n// The property is used by `Buffer.isBuffer` and `is-buffer` (in Safari 5-7) to detect\n// Buffer instances.\nBuffer.prototype._isBuffer = true\n\nfunction swap (b, n, m) {\n  var i = b[n]\n  b[n] = b[m]\n  b[m] = i\n}\n\nBuffer.prototype.swap16 = function swap16 () {\n  var len = this.length\n  if (len % 2 !== 0) {\n    throw new RangeError('Buffer size must be a multiple of 16-bits')\n  }\n  for (var i = 0; i < len; i += 2) {\n    swap(this, i, i + 1)\n  }\n  return this\n}\n\nBuffer.prototype.swap32 = function swap32 () {\n  var len = this.length\n  if (len % 4 !== 0) {\n    throw new RangeError('Buffer size must be a multiple of 32-bits')\n  }\n  for (var i = 0; i < len; i += 4) {\n    swap(this, i, i + 3)\n    swap(this, i + 1, i + 2)\n  }\n  return this\n}\n\nBuffer.prototype.swap64 = function swap64 () {\n  var len = this.length\n  if (len % 8 !== 0) {\n    throw new RangeError('Buffer size must be a multiple of 64-bits')\n  }\n  for (var i = 0; i < len; i += 8) {\n    swap(this, i, i + 7)\n    swap(this, i + 1, i + 6)\n    swap(this, i + 2, i + 5)\n    swap(this, i + 3, i + 4)\n  }\n  return this\n}\n\nBuffer.prototype.toString = function toString () {\n  var length = this.length | 0\n  if (length === 0) return ''\n  if (arguments.length === 0) return utf8Slice(this, 0, length)\n  return slowToString.apply(this, arguments)\n}\n\nBuffer.prototype.equals = function equals (b) {\n  if (!Buffer.isBuffer(b)) throw new TypeError('Argument must be a Buffer')\n  if (this === b) return true\n  return Buffer.compare(this, b) === 0\n}\n\nBuffer.prototype.inspect = function inspect () {\n  var str = ''\n  var max = exports.INSPECT_MAX_BYTES\n  if (this.length > 0) {\n    str = this.toString('hex', 0, max).match(/.{2}/g).join(' ')\n    if (this.length > max) str += ' ... '\n  }\n  return '<Buffer ' + str + '>'\n}\n\nBuffer.prototype.compare = function compare (target, start, end, thisStart, thisEnd) {\n  if (!Buffer.isBuffer(target)) {\n    throw new TypeError('Argument must be a Buffer')\n  }\n\n  if (start === undefined) {\n    start = 0\n  }\n  if (end === undefined) {\n    end = target ? target.length : 0\n  }\n  if (thisStart === undefined) {\n    thisStart = 0\n  }\n  if (thisEnd === undefined) {\n    thisEnd = this.length\n  }\n\n  if (start < 0 || end > target.length || thisStart < 0 || thisEnd > this.length) {\n    throw new RangeError('out of range index')\n  }\n\n  if (thisStart >= thisEnd && start >= end) {\n    return 0\n  }\n  if (thisStart >= thisEnd) {\n    return -1\n  }\n  if (start >= end) {\n    return 1\n  }\n\n  start >>>= 0\n  end >>>= 0\n  thisStart >>>= 0\n  thisEnd >>>= 0\n\n  if (this === target) return 0\n\n  var x = thisEnd - thisStart\n  var y = end - start\n  var len = Math.min(x, y)\n\n  var thisCopy = this.slice(thisStart, thisEnd)\n  var targetCopy = target.slice(start, end)\n\n  for (var i = 0; i < len; ++i) {\n    if (thisCopy[i] !== targetCopy[i]) {\n      x = thisCopy[i]\n      y = targetCopy[i]\n      break\n    }\n  }\n\n  if (x < y) return -1\n  if (y < x) return 1\n  return 0\n}\n\n// Finds either the first index of `val` in `buffer` at offset >= `byteOffset`,\n// OR the last index of `val` in `buffer` at offset <= `byteOffset`.\n//\n// Arguments:\n// - buffer - a Buffer to search\n// - val - a string, Buffer, or number\n// - byteOffset - an index into `buffer`; will be clamped to an int32\n// - encoding - an optional encoding, relevant is val is a string\n// - dir - true for indexOf, false for lastIndexOf\nfunction bidirectionalIndexOf (buffer, val, byteOffset, encoding, dir) {\n  // Empty buffer means no match\n  if (buffer.length === 0) return -1\n\n  // Normalize byteOffset\n  if (typeof byteOffset === 'string') {\n    encoding = byteOffset\n    byteOffset = 0\n  } else if (byteOffset > 0x7fffffff) {\n    byteOffset = 0x7fffffff\n  } else if (byteOffset < -0x80000000) {\n    byteOffset = -0x80000000\n  }\n  byteOffset = +byteOffset  // Coerce to Number.\n  if (isNaN(byteOffset)) {\n    // byteOffset: it it's undefined, null, NaN, \"foo\", etc, search whole buffer\n    byteOffset = dir ? 0 : (buffer.length - 1)\n  }\n\n  // Normalize byteOffset: negative offsets start from the end of the buffer\n  if (byteOffset < 0) byteOffset = buffer.length + byteOffset\n  if (byteOffset >= buffer.length) {\n    if (dir) return -1\n    else byteOffset = buffer.length - 1\n  } else if (byteOffset < 0) {\n    if (dir) byteOffset = 0\n    else return -1\n  }\n\n  // Normalize val\n  if (typeof val === 'string') {\n    val = Buffer.from(val, encoding)\n  }\n\n  // Finally, search either indexOf (if dir is true) or lastIndexOf\n  if (Buffer.isBuffer(val)) {\n    // Special case: looking for empty string/buffer always fails\n    if (val.length === 0) {\n      return -1\n    }\n    return arrayIndexOf(buffer, val, byteOffset, encoding, dir)\n  } else if (typeof val === 'number') {\n    val = val & 0xFF // Search for a byte value [0-255]\n    if (Buffer.TYPED_ARRAY_SUPPORT &&\n        typeof Uint8Array.prototype.indexOf === 'function') {\n      if (dir) {\n        return Uint8Array.prototype.indexOf.call(buffer, val, byteOffset)\n      } else {\n        return Uint8Array.prototype.lastIndexOf.call(buffer, val, byteOffset)\n      }\n    }\n    return arrayIndexOf(buffer, [ val ], byteOffset, encoding, dir)\n  }\n\n  throw new TypeError('val must be string, number or Buffer')\n}\n\nfunction arrayIndexOf (arr, val, byteOffset, encoding, dir) {\n  var indexSize = 1\n  var arrLength = arr.length\n  var valLength = val.length\n\n  if (encoding !== undefined) {\n    encoding = String(encoding).toLowerCase()\n    if (encoding === 'ucs2' || encoding === 'ucs-2' ||\n        encoding === 'utf16le' || encoding === 'utf-16le') {\n      if (arr.length < 2 || val.length < 2) {\n        return -1\n      }\n      indexSize = 2\n      arrLength /= 2\n      valLength /= 2\n      byteOffset /= 2\n    }\n  }\n\n  function read (buf, i) {\n    if (indexSize === 1) {\n      return buf[i]\n    } else {\n      return buf.readUInt16BE(i * indexSize)\n    }\n  }\n\n  var i\n  if (dir) {\n    var foundIndex = -1\n    for (i = byteOffset; i < arrLength; i++) {\n      if (read(arr, i) === read(val, foundIndex === -1 ? 0 : i - foundIndex)) {\n        if (foundIndex === -1) foundIndex = i\n        if (i - foundIndex + 1 === valLength) return foundIndex * indexSize\n      } else {\n        if (foundIndex !== -1) i -= i - foundIndex\n        foundIndex = -1\n      }\n    }\n  } else {\n    if (byteOffset + valLength > arrLength) byteOffset = arrLength - valLength\n    for (i = byteOffset; i >= 0; i--) {\n      var found = true\n      for (var j = 0; j < valLength; j++) {\n        if (read(arr, i + j) !== read(val, j)) {\n          found = false\n          break\n        }\n      }\n      if (found) return i\n    }\n  }\n\n  return -1\n}\n\nBuffer.prototype.includes = function includes (val, byteOffset, encoding) {\n  return this.indexOf(val, byteOffset, encoding) !== -1\n}\n\nBuffer.prototype.indexOf = function indexOf (val, byteOffset, encoding) {\n  return bidirectionalIndexOf(this, val, byteOffset, encoding, true)\n}\n\nBuffer.prototype.lastIndexOf = function lastIndexOf (val, byteOffset, encoding) {\n  return bidirectionalIndexOf(this, val, byteOffset, encoding, false)\n}\n\nfunction hexWrite (buf, string, offset, length) {\n  offset = Number(offset) || 0\n  var remaining = buf.length - offset\n  if (!length) {\n    length = remaining\n  } else {\n    length = Number(length)\n    if (length > remaining) {\n      length = remaining\n    }\n  }\n\n  // must be an even number of digits\n  var strLen = string.length\n  if (strLen % 2 !== 0) throw new TypeError('Invalid hex string')\n\n  if (length > strLen / 2) {\n    length = strLen / 2\n  }\n  for (var i = 0; i < length; ++i) {\n    var parsed = parseInt(string.substr(i * 2, 2), 16)\n    if (isNaN(parsed)) return i\n    buf[offset + i] = parsed\n  }\n  return i\n}\n\nfunction utf8Write (buf, string, offset, length) {\n  return blitBuffer(utf8ToBytes(string, buf.length - offset), buf, offset, length)\n}\n\nfunction asciiWrite (buf, string, offset, length) {\n  return blitBuffer(asciiToBytes(string), buf, offset, length)\n}\n\nfunction latin1Write (buf, string, offset, length) {\n  return asciiWrite(buf, string, offset, length)\n}\n\nfunction base64Write (buf, string, offset, length) {\n  return blitBuffer(base64ToBytes(string), buf, offset, length)\n}\n\nfunction ucs2Write (buf, string, offset, length) {\n  return blitBuffer(utf16leToBytes(string, buf.length - offset), buf, offset, length)\n}\n\nBuffer.prototype.write = function write (string, offset, length, encoding) {\n  // Buffer#write(string)\n  if (offset === undefined) {\n    encoding = 'utf8'\n    length = this.length\n    offset = 0\n  // Buffer#write(string, encoding)\n  } else if (length === undefined && typeof offset === 'string') {\n    encoding = offset\n    length = this.length\n    offset = 0\n  // Buffer#write(string, offset[, length][, encoding])\n  } else if (isFinite(offset)) {\n    offset = offset | 0\n    if (isFinite(length)) {\n      length = length | 0\n      if (encoding === undefined) encoding = 'utf8'\n    } else {\n      encoding = length\n      length = undefined\n    }\n  // legacy write(string, encoding, offset, length) - remove in v0.13\n  } else {\n    throw new Error(\n      'Buffer.write(string, encoding, offset[, length]) is no longer supported'\n    )\n  }\n\n  var remaining = this.length - offset\n  if (length === undefined || length > remaining) length = remaining\n\n  if ((string.length > 0 && (length < 0 || offset < 0)) || offset > this.length) {\n    throw new RangeError('Attempt to write outside buffer bounds')\n  }\n\n  if (!encoding) encoding = 'utf8'\n\n  var loweredCase = false\n  for (;;) {\n    switch (encoding) {\n      case 'hex':\n        return hexWrite(this, string, offset, length)\n\n      case 'utf8':\n      case 'utf-8':\n        return utf8Write(this, string, offset, length)\n\n      case 'ascii':\n        return asciiWrite(this, string, offset, length)\n\n      case 'latin1':\n      case 'binary':\n        return latin1Write(this, string, offset, length)\n\n      case 'base64':\n        // Warning: maxLength not taken into account in base64Write\n        return base64Write(this, string, offset, length)\n\n      case 'ucs2':\n      case 'ucs-2':\n      case 'utf16le':\n      case 'utf-16le':\n        return ucs2Write(this, string, offset, length)\n\n      default:\n        if (loweredCase) throw new TypeError('Unknown encoding: ' + encoding)\n        encoding = ('' + encoding).toLowerCase()\n        loweredCase = true\n    }\n  }\n}\n\nBuffer.prototype.toJSON = function toJSON () {\n  return {\n    type: 'Buffer',\n    data: Array.prototype.slice.call(this._arr || this, 0)\n  }\n}\n\nfunction base64Slice (buf, start, end) {\n  if (start === 0 && end === buf.length) {\n    return base64.fromByteArray(buf)\n  } else {\n    return base64.fromByteArray(buf.slice(start, end))\n  }\n}\n\nfunction utf8Slice (buf, start, end) {\n  end = Math.min(buf.length, end)\n  var res = []\n\n  var i = start\n  while (i < end) {\n    var firstByte = buf[i]\n    var codePoint = null\n    var bytesPerSequence = (firstByte > 0xEF) ? 4\n      : (firstByte > 0xDF) ? 3\n      : (firstByte > 0xBF) ? 2\n      : 1\n\n    if (i + bytesPerSequence <= end) {\n      var secondByte, thirdByte, fourthByte, tempCodePoint\n\n      switch (bytesPerSequence) {\n        case 1:\n          if (firstByte < 0x80) {\n            codePoint = firstByte\n          }\n          break\n        case 2:\n          secondByte = buf[i + 1]\n          if ((secondByte & 0xC0) === 0x80) {\n            tempCodePoint = (firstByte & 0x1F) << 0x6 | (secondByte & 0x3F)\n            if (tempCodePoint > 0x7F) {\n              codePoint = tempCodePoint\n            }\n          }\n          break\n        case 3:\n          secondByte = buf[i + 1]\n          thirdByte = buf[i + 2]\n          if ((secondByte & 0xC0) === 0x80 && (thirdByte & 0xC0) === 0x80) {\n            tempCodePoint = (firstByte & 0xF) << 0xC | (secondByte & 0x3F) << 0x6 | (thirdByte & 0x3F)\n            if (tempCodePoint > 0x7FF && (tempCodePoint < 0xD800 || tempCodePoint > 0xDFFF)) {\n              codePoint = tempCodePoint\n            }\n          }\n          break\n        case 4:\n          secondByte = buf[i + 1]\n          thirdByte = buf[i + 2]\n          fourthByte = buf[i + 3]\n          if ((secondByte & 0xC0) === 0x80 && (thirdByte & 0xC0) === 0x80 && (fourthByte & 0xC0) === 0x80) {\n            tempCodePoint = (firstByte & 0xF) << 0x12 | (secondByte & 0x3F) << 0xC | (thirdByte & 0x3F) << 0x6 | (fourthByte & 0x3F)\n            if (tempCodePoint > 0xFFFF && tempCodePoint < 0x110000) {\n              codePoint = tempCodePoint\n            }\n          }\n      }\n    }\n\n    if (codePoint === null) {\n      // we did not generate a valid codePoint so insert a\n      // replacement char (U+FFFD) and advance only 1 byte\n      codePoint = 0xFFFD\n      bytesPerSequence = 1\n    } else if (codePoint > 0xFFFF) {\n      // encode to utf16 (surrogate pair dance)\n      codePoint -= 0x10000\n      res.push(codePoint >>> 10 & 0x3FF | 0xD800)\n      codePoint = 0xDC00 | codePoint & 0x3FF\n    }\n\n    res.push(codePoint)\n    i += bytesPerSequence\n  }\n\n  return decodeCodePointsArray(res)\n}\n\n// Based on http://stackoverflow.com/a/22747272/680742, the browser with\n// the lowest limit is Chrome, with 0x10000 args.\n// We go 1 magnitude less, for safety\nvar MAX_ARGUMENTS_LENGTH = 0x1000\n\nfunction decodeCodePointsArray (codePoints) {\n  var len = codePoints.length\n  if (len <= MAX_ARGUMENTS_LENGTH) {\n    return String.fromCharCode.apply(String, codePoints) // avoid extra slice()\n  }\n\n  // Decode in chunks to avoid \"call stack size exceeded\".\n  var res = ''\n  var i = 0\n  while (i < len) {\n    res += String.fromCharCode.apply(\n      String,\n      codePoints.slice(i, i += MAX_ARGUMENTS_LENGTH)\n    )\n  }\n  return res\n}\n\nfunction asciiSlice (buf, start, end) {\n  var ret = ''\n  end = Math.min(buf.length, end)\n\n  for (var i = start; i < end; ++i) {\n    ret += String.fromCharCode(buf[i] & 0x7F)\n  }\n  return ret\n}\n\nfunction latin1Slice (buf, start, end) {\n  var ret = ''\n  end = Math.min(buf.length, end)\n\n  for (var i = start; i < end; ++i) {\n    ret += String.fromCharCode(buf[i])\n  }\n  return ret\n}\n\nfunction hexSlice (buf, start, end) {\n  var len = buf.length\n\n  if (!start || start < 0) start = 0\n  if (!end || end < 0 || end > len) end = len\n\n  var out = ''\n  for (var i = start; i < end; ++i) {\n    out += toHex(buf[i])\n  }\n  return out\n}\n\nfunction utf16leSlice (buf, start, end) {\n  var bytes = buf.slice(start, end)\n  var res = ''\n  for (var i = 0; i < bytes.length; i += 2) {\n    res += String.fromCharCode(bytes[i] + bytes[i + 1] * 256)\n  }\n  return res\n}\n\nBuffer.prototype.slice = function slice (start, end) {\n  var len = this.length\n  start = ~~start\n  end = end === undefined ? len : ~~end\n\n  if (start < 0) {\n    start += len\n    if (start < 0) start = 0\n  } else if (start > len) {\n    start = len\n  }\n\n  if (end < 0) {\n    end += len\n    if (end < 0) end = 0\n  } else if (end > len) {\n    end = len\n  }\n\n  if (end < start) end = start\n\n  var newBuf\n  if (Buffer.TYPED_ARRAY_SUPPORT) {\n    newBuf = this.subarray(start, end)\n    newBuf.__proto__ = Buffer.prototype\n  } else {\n    var sliceLen = end - start\n    newBuf = new Buffer(sliceLen, undefined)\n    for (var i = 0; i < sliceLen; ++i) {\n      newBuf[i] = this[i + start]\n    }\n  }\n\n  return newBuf\n}\n\n/*\n * Need to make sure that buffer isn't trying to write out of bounds.\n */\nfunction checkOffset (offset, ext, length) {\n  if ((offset % 1) !== 0 || offset < 0) throw new RangeError('offset is not uint')\n  if (offset + ext > length) throw new RangeError('Trying to access beyond buffer length')\n}\n\nBuffer.prototype.readUIntLE = function readUIntLE (offset, byteLength, noAssert) {\n  offset = offset | 0\n  byteLength = byteLength | 0\n  if (!noAssert) checkOffset(offset, byteLength, this.length)\n\n  var val = this[offset]\n  var mul = 1\n  var i = 0\n  while (++i < byteLength && (mul *= 0x100)) {\n    val += this[offset + i] * mul\n  }\n\n  return val\n}\n\nBuffer.prototype.readUIntBE = function readUIntBE (offset, byteLength, noAssert) {\n  offset = offset | 0\n  byteLength = byteLength | 0\n  if (!noAssert) {\n    checkOffset(offset, byteLength, this.length)\n  }\n\n  var val = this[offset + --byteLength]\n  var mul = 1\n  while (byteLength > 0 && (mul *= 0x100)) {\n    val += this[offset + --byteLength] * mul\n  }\n\n  return val\n}\n\nBuffer.prototype.readUInt8 = function readUInt8 (offset, noAssert) {\n  if (!noAssert) checkOffset(offset, 1, this.length)\n  return this[offset]\n}\n\nBuffer.prototype.readUInt16LE = function readUInt16LE (offset, noAssert) {\n  if (!noAssert) checkOffset(offset, 2, this.length)\n  return this[offset] | (this[offset + 1] << 8)\n}\n\nBuffer.prototype.readUInt16BE = function readUInt16BE (offset, noAssert) {\n  if (!noAssert) checkOffset(offset, 2, this.length)\n  return (this[offset] << 8) | this[offset + 1]\n}\n\nBuffer.prototype.readUInt32LE = function readUInt32LE (offset, noAssert) {\n  if (!noAssert) checkOffset(offset, 4, this.length)\n\n  return ((this[offset]) |\n      (this[offset + 1] << 8) |\n      (this[offset + 2] << 16)) +\n      (this[offset + 3] * 0x1000000)\n}\n\nBuffer.prototype.readUInt32BE = function readUInt32BE (offset, noAssert) {\n  if (!noAssert) checkOffset(offset, 4, this.length)\n\n  return (this[offset] * 0x1000000) +\n    ((this[offset + 1] << 16) |\n    (this[offset + 2] << 8) |\n    this[offset + 3])\n}\n\nBuffer.prototype.readIntLE = function readIntLE (offset, byteLength, noAssert) {\n  offset = offset | 0\n  byteLength = byteLength | 0\n  if (!noAssert) checkOffset(offset, byteLength, this.length)\n\n  var val = this[offset]\n  var mul = 1\n  var i = 0\n  while (++i < byteLength && (mul *= 0x100)) {\n    val += this[offset + i] * mul\n  }\n  mul *= 0x80\n\n  if (val >= mul) val -= Math.pow(2, 8 * byteLength)\n\n  return val\n}\n\nBuffer.prototype.readIntBE = function readIntBE (offset, byteLength, noAssert) {\n  offset = offset | 0\n  byteLength = byteLength | 0\n  if (!noAssert) checkOffset(offset, byteLength, this.length)\n\n  var i = byteLength\n  var mul = 1\n  var val = this[offset + --i]\n  while (i > 0 && (mul *= 0x100)) {\n    val += this[offset + --i] * mul\n  }\n  mul *= 0x80\n\n  if (val >= mul) val -= Math.pow(2, 8 * byteLength)\n\n  return val\n}\n\nBuffer.prototype.readInt8 = function readInt8 (offset, noAssert) {\n  if (!noAssert) checkOffset(offset, 1, this.length)\n  if (!(this[offset] & 0x80)) return (this[offset])\n  return ((0xff - this[offset] + 1) * -1)\n}\n\nBuffer.prototype.readInt16LE = function readInt16LE (offset, noAssert) {\n  if (!noAssert) checkOffset(offset, 2, this.length)\n  var val = this[offset] | (this[offset + 1] << 8)\n  return (val & 0x8000) ? val | 0xFFFF0000 : val\n}\n\nBuffer.prototype.readInt16BE = function readInt16BE (offset, noAssert) {\n  if (!noAssert) checkOffset(offset, 2, this.length)\n  var val = this[offset + 1] | (this[offset] << 8)\n  return (val & 0x8000) ? val | 0xFFFF0000 : val\n}\n\nBuffer.prototype.readInt32LE = function readInt32LE (offset, noAssert) {\n  if (!noAssert) checkOffset(offset, 4, this.length)\n\n  return (this[offset]) |\n    (this[offset + 1] << 8) |\n    (this[offset + 2] << 16) |\n    (this[offset + 3] << 24)\n}\n\nBuffer.prototype.readInt32BE = function readInt32BE (offset, noAssert) {\n  if (!noAssert) checkOffset(offset, 4, this.length)\n\n  return (this[offset] << 24) |\n    (this[offset + 1] << 16) |\n    (this[offset + 2] << 8) |\n    (this[offset + 3])\n}\n\nBuffer.prototype.readFloatLE = function readFloatLE (offset, noAssert) {\n  if (!noAssert) checkOffset(offset, 4, this.length)\n  return ieee754.read(this, offset, true, 23, 4)\n}\n\nBuffer.prototype.readFloatBE = function readFloatBE (offset, noAssert) {\n  if (!noAssert) checkOffset(offset, 4, this.length)\n  return ieee754.read(this, offset, false, 23, 4)\n}\n\nBuffer.prototype.readDoubleLE = function readDoubleLE (offset, noAssert) {\n  if (!noAssert) checkOffset(offset, 8, this.length)\n  return ieee754.read(this, offset, true, 52, 8)\n}\n\nBuffer.prototype.readDoubleBE = function readDoubleBE (offset, noAssert) {\n  if (!noAssert) checkOffset(offset, 8, this.length)\n  return ieee754.read(this, offset, false, 52, 8)\n}\n\nfunction checkInt (buf, value, offset, ext, max, min) {\n  if (!Buffer.isBuffer(buf)) throw new TypeError('\"buffer\" argument must be a Buffer instance')\n  if (value > max || value < min) throw new RangeError('\"value\" argument is out of bounds')\n  if (offset + ext > buf.length) throw new RangeError('Index out of range')\n}\n\nBuffer.prototype.writeUIntLE = function writeUIntLE (value, offset, byteLength, noAssert) {\n  value = +value\n  offset = offset | 0\n  byteLength = byteLength | 0\n  if (!noAssert) {\n    var maxBytes = Math.pow(2, 8 * byteLength) - 1\n    checkInt(this, value, offset, byteLength, maxBytes, 0)\n  }\n\n  var mul = 1\n  var i = 0\n  this[offset] = value & 0xFF\n  while (++i < byteLength && (mul *= 0x100)) {\n    this[offset + i] = (value / mul) & 0xFF\n  }\n\n  return offset + byteLength\n}\n\nBuffer.prototype.writeUIntBE = function writeUIntBE (value, offset, byteLength, noAssert) {\n  value = +value\n  offset = offset | 0\n  byteLength = byteLength | 0\n  if (!noAssert) {\n    var maxBytes = Math.pow(2, 8 * byteLength) - 1\n    checkInt(this, value, offset, byteLength, maxBytes, 0)\n  }\n\n  var i = byteLength - 1\n  var mul = 1\n  this[offset + i] = value & 0xFF\n  while (--i >= 0 && (mul *= 0x100)) {\n    this[offset + i] = (value / mul) & 0xFF\n  }\n\n  return offset + byteLength\n}\n\nBuffer.prototype.writeUInt8 = function writeUInt8 (value, offset, noAssert) {\n  value = +value\n  offset = offset | 0\n  if (!noAssert) checkInt(this, value, offset, 1, 0xff, 0)\n  if (!Buffer.TYPED_ARRAY_SUPPORT) value = Math.floor(value)\n  this[offset] = (value & 0xff)\n  return offset + 1\n}\n\nfunction objectWriteUInt16 (buf, value, offset, littleEndian) {\n  if (value < 0) value = 0xffff + value + 1\n  for (var i = 0, j = Math.min(buf.length - offset, 2); i < j; ++i) {\n    buf[offset + i] = (value & (0xff << (8 * (littleEndian ? i : 1 - i)))) >>>\n      (littleEndian ? i : 1 - i) * 8\n  }\n}\n\nBuffer.prototype.writeUInt16LE = function writeUInt16LE (value, offset, noAssert) {\n  value = +value\n  offset = offset | 0\n  if (!noAssert) checkInt(this, value, offset, 2, 0xffff, 0)\n  if (Buffer.TYPED_ARRAY_SUPPORT) {\n    this[offset] = (value & 0xff)\n    this[offset + 1] = (value >>> 8)\n  } else {\n    objectWriteUInt16(this, value, offset, true)\n  }\n  return offset + 2\n}\n\nBuffer.prototype.writeUInt16BE = function writeUInt16BE (value, offset, noAssert) {\n  value = +value\n  offset = offset | 0\n  if (!noAssert) checkInt(this, value, offset, 2, 0xffff, 0)\n  if (Buffer.TYPED_ARRAY_SUPPORT) {\n    this[offset] = (value >>> 8)\n    this[offset + 1] = (value & 0xff)\n  } else {\n    objectWriteUInt16(this, value, offset, false)\n  }\n  return offset + 2\n}\n\nfunction objectWriteUInt32 (buf, value, offset, littleEndian) {\n  if (value < 0) value = 0xffffffff + value + 1\n  for (var i = 0, j = Math.min(buf.length - offset, 4); i < j; ++i) {\n    buf[offset + i] = (value >>> (littleEndian ? i : 3 - i) * 8) & 0xff\n  }\n}\n\nBuffer.prototype.writeUInt32LE = function writeUInt32LE (value, offset, noAssert) {\n  value = +value\n  offset = offset | 0\n  if (!noAssert) checkInt(this, value, offset, 4, 0xffffffff, 0)\n  if (Buffer.TYPED_ARRAY_SUPPORT) {\n    this[offset + 3] = (value >>> 24)\n    this[offset + 2] = (value >>> 16)\n    this[offset + 1] = (value >>> 8)\n    this[offset] = (value & 0xff)\n  } else {\n    objectWriteUInt32(this, value, offset, true)\n  }\n  return offset + 4\n}\n\nBuffer.prototype.writeUInt32BE = function writeUInt32BE (value, offset, noAssert) {\n  value = +value\n  offset = offset | 0\n  if (!noAssert) checkInt(this, value, offset, 4, 0xffffffff, 0)\n  if (Buffer.TYPED_ARRAY_SUPPORT) {\n    this[offset] = (value >>> 24)\n    this[offset + 1] = (value >>> 16)\n    this[offset + 2] = (value >>> 8)\n    this[offset + 3] = (value & 0xff)\n  } else {\n    objectWriteUInt32(this, value, offset, false)\n  }\n  return offset + 4\n}\n\nBuffer.prototype.writeIntLE = function writeIntLE (value, offset, byteLength, noAssert) {\n  value = +value\n  offset = offset | 0\n  if (!noAssert) {\n    var limit = Math.pow(2, 8 * byteLength - 1)\n\n    checkInt(this, value, offset, byteLength, limit - 1, -limit)\n  }\n\n  var i = 0\n  var mul = 1\n  var sub = 0\n  this[offset] = value & 0xFF\n  while (++i < byteLength && (mul *= 0x100)) {\n    if (value < 0 && sub === 0 && this[offset + i - 1] !== 0) {\n      sub = 1\n    }\n    this[offset + i] = ((value / mul) >> 0) - sub & 0xFF\n  }\n\n  return offset + byteLength\n}\n\nBuffer.prototype.writeIntBE = function writeIntBE (value, offset, byteLength, noAssert) {\n  value = +value\n  offset = offset | 0\n  if (!noAssert) {\n    var limit = Math.pow(2, 8 * byteLength - 1)\n\n    checkInt(this, value, offset, byteLength, limit - 1, -limit)\n  }\n\n  var i = byteLength - 1\n  var mul = 1\n  var sub = 0\n  this[offset + i] = value & 0xFF\n  while (--i >= 0 && (mul *= 0x100)) {\n    if (value < 0 && sub === 0 && this[offset + i + 1] !== 0) {\n      sub = 1\n    }\n    this[offset + i] = ((value / mul) >> 0) - sub & 0xFF\n  }\n\n  return offset + byteLength\n}\n\nBuffer.prototype.writeInt8 = function writeInt8 (value, offset, noAssert) {\n  value = +value\n  offset = offset | 0\n  if (!noAssert) checkInt(this, value, offset, 1, 0x7f, -0x80)\n  if (!Buffer.TYPED_ARRAY_SUPPORT) value = Math.floor(value)\n  if (value < 0) value = 0xff + value + 1\n  this[offset] = (value & 0xff)\n  return offset + 1\n}\n\nBuffer.prototype.writeInt16LE = function writeInt16LE (value, offset, noAssert) {\n  value = +value\n  offset = offset | 0\n  if (!noAssert) checkInt(this, value, offset, 2, 0x7fff, -0x8000)\n  if (Buffer.TYPED_ARRAY_SUPPORT) {\n    this[offset] = (value & 0xff)\n    this[offset + 1] = (value >>> 8)\n  } else {\n    objectWriteUInt16(this, value, offset, true)\n  }\n  return offset + 2\n}\n\nBuffer.prototype.writeInt16BE = function writeInt16BE (value, offset, noAssert) {\n  value = +value\n  offset = offset | 0\n  if (!noAssert) checkInt(this, value, offset, 2, 0x7fff, -0x8000)\n  if (Buffer.TYPED_ARRAY_SUPPORT) {\n    this[offset] = (value >>> 8)\n    this[offset + 1] = (value & 0xff)\n  } else {\n    objectWriteUInt16(this, value, offset, false)\n  }\n  return offset + 2\n}\n\nBuffer.prototype.writeInt32LE = function writeInt32LE (value, offset, noAssert) {\n  value = +value\n  offset = offset | 0\n  if (!noAssert) checkInt(this, value, offset, 4, 0x7fffffff, -0x80000000)\n  if (Buffer.TYPED_ARRAY_SUPPORT) {\n    this[offset] = (value & 0xff)\n    this[offset + 1] = (value >>> 8)\n    this[offset + 2] = (value >>> 16)\n    this[offset + 3] = (value >>> 24)\n  } else {\n    objectWriteUInt32(this, value, offset, true)\n  }\n  return offset + 4\n}\n\nBuffer.prototype.writeInt32BE = function writeInt32BE (value, offset, noAssert) {\n  value = +value\n  offset = offset | 0\n  if (!noAssert) checkInt(this, value, offset, 4, 0x7fffffff, -0x80000000)\n  if (value < 0) value = 0xffffffff + value + 1\n  if (Buffer.TYPED_ARRAY_SUPPORT) {\n    this[offset] = (value >>> 24)\n    this[offset + 1] = (value >>> 16)\n    this[offset + 2] = (value >>> 8)\n    this[offset + 3] = (value & 0xff)\n  } else {\n    objectWriteUInt32(this, value, offset, false)\n  }\n  return offset + 4\n}\n\nfunction checkIEEE754 (buf, value, offset, ext, max, min) {\n  if (offset + ext > buf.length) throw new RangeError('Index out of range')\n  if (offset < 0) throw new RangeError('Index out of range')\n}\n\nfunction writeFloat (buf, value, offset, littleEndian, noAssert) {\n  if (!noAssert) {\n    checkIEEE754(buf, value, offset, 4, 3.4028234663852886e+38, -3.4028234663852886e+38)\n  }\n  ieee754.write(buf, value, offset, littleEndian, 23, 4)\n  return offset + 4\n}\n\nBuffer.prototype.writeFloatLE = function writeFloatLE (value, offset, noAssert) {\n  return writeFloat(this, value, offset, true, noAssert)\n}\n\nBuffer.prototype.writeFloatBE = function writeFloatBE (value, offset, noAssert) {\n  return writeFloat(this, value, offset, false, noAssert)\n}\n\nfunction writeDouble (buf, value, offset, littleEndian, noAssert) {\n  if (!noAssert) {\n    checkIEEE754(buf, value, offset, 8, 1.7976931348623157E+308, -1.7976931348623157E+308)\n  }\n  ieee754.write(buf, value, offset, littleEndian, 52, 8)\n  return offset + 8\n}\n\nBuffer.prototype.writeDoubleLE = function writeDoubleLE (value, offset, noAssert) {\n  return writeDouble(this, value, offset, true, noAssert)\n}\n\nBuffer.prototype.writeDoubleBE = function writeDoubleBE (value, offset, noAssert) {\n  return writeDouble(this, value, offset, false, noAssert)\n}\n\n// copy(targetBuffer, targetStart=0, sourceStart=0, sourceEnd=buffer.length)\nBuffer.prototype.copy = function copy (target, targetStart, start, end) {\n  if (!start) start = 0\n  if (!end && end !== 0) end = this.length\n  if (targetStart >= target.length) targetStart = target.length\n  if (!targetStart) targetStart = 0\n  if (end > 0 && end < start) end = start\n\n  // Copy 0 bytes; we're done\n  if (end === start) return 0\n  if (target.length === 0 || this.length === 0) return 0\n\n  // Fatal error conditions\n  if (targetStart < 0) {\n    throw new RangeError('targetStart out of bounds')\n  }\n  if (start < 0 || start >= this.length) throw new RangeError('sourceStart out of bounds')\n  if (end < 0) throw new RangeError('sourceEnd out of bounds')\n\n  // Are we oob?\n  if (end > this.length) end = this.length\n  if (target.length - targetStart < end - start) {\n    end = target.length - targetStart + start\n  }\n\n  var len = end - start\n  var i\n\n  if (this === target && start < targetStart && targetStart < end) {\n    // descending copy from end\n    for (i = len - 1; i >= 0; --i) {\n      target[i + targetStart] = this[i + start]\n    }\n  } else if (len < 1000 || !Buffer.TYPED_ARRAY_SUPPORT) {\n    // ascending copy from start\n    for (i = 0; i < len; ++i) {\n      target[i + targetStart] = this[i + start]\n    }\n  } else {\n    Uint8Array.prototype.set.call(\n      target,\n      this.subarray(start, start + len),\n      targetStart\n    )\n  }\n\n  return len\n}\n\n// Usage:\n//    buffer.fill(number[, offset[, end]])\n//    buffer.fill(buffer[, offset[, end]])\n//    buffer.fill(string[, offset[, end]][, encoding])\nBuffer.prototype.fill = function fill (val, start, end, encoding) {\n  // Handle string cases:\n  if (typeof val === 'string') {\n    if (typeof start === 'string') {\n      encoding = start\n      start = 0\n      end = this.length\n    } else if (typeof end === 'string') {\n      encoding = end\n      end = this.length\n    }\n    if (val.length === 1) {\n      var code = val.charCodeAt(0)\n      if (code < 256) {\n        val = code\n      }\n    }\n    if (encoding !== undefined && typeof encoding !== 'string') {\n      throw new TypeError('encoding must be a string')\n    }\n    if (typeof encoding === 'string' && !Buffer.isEncoding(encoding)) {\n      throw new TypeError('Unknown encoding: ' + encoding)\n    }\n  } else if (typeof val === 'number') {\n    val = val & 255\n  }\n\n  // Invalid ranges are not set to a default, so can range check early.\n  if (start < 0 || this.length < start || this.length < end) {\n    throw new RangeError('Out of range index')\n  }\n\n  if (end <= start) {\n    return this\n  }\n\n  start = start >>> 0\n  end = end === undefined ? this.length : end >>> 0\n\n  if (!val) val = 0\n\n  var i\n  if (typeof val === 'number') {\n    for (i = start; i < end; ++i) {\n      this[i] = val\n    }\n  } else {\n    var bytes = Buffer.isBuffer(val)\n      ? val\n      : utf8ToBytes(new Buffer(val, encoding).toString())\n    var len = bytes.length\n    for (i = 0; i < end - start; ++i) {\n      this[i + start] = bytes[i % len]\n    }\n  }\n\n  return this\n}\n\n// HELPER FUNCTIONS\n// ================\n\nvar INVALID_BASE64_RE = /[^+\\/0-9A-Za-z-_]/g\n\nfunction base64clean (str) {\n  // Node strips out invalid characters like \\n and \\t from the string, base64-js does not\n  str = stringtrim(str).replace(INVALID_BASE64_RE, '')\n  // Node converts strings with length < 2 to ''\n  if (str.length < 2) return ''\n  // Node allows for non-padded base64 strings (missing trailing ===), base64-js does not\n  while (str.length % 4 !== 0) {\n    str = str + '='\n  }\n  return str\n}\n\nfunction stringtrim (str) {\n  if (str.trim) return str.trim()\n  return str.replace(/^\\s+|\\s+$/g, '')\n}\n\nfunction toHex (n) {\n  if (n < 16) return '0' + n.toString(16)\n  return n.toString(16)\n}\n\nfunction utf8ToBytes (string, units) {\n  units = units || Infinity\n  var codePoint\n  var length = string.length\n  var leadSurrogate = null\n  var bytes = []\n\n  for (var i = 0; i < length; ++i) {\n    codePoint = string.charCodeAt(i)\n\n    // is surrogate component\n    if (codePoint > 0xD7FF && codePoint < 0xE000) {\n      // last char was a lead\n      if (!leadSurrogate) {\n        // no lead yet\n        if (codePoint > 0xDBFF) {\n          // unexpected trail\n          if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD)\n          continue\n        } else if (i + 1 === length) {\n          // unpaired lead\n          if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD)\n          continue\n        }\n\n        // valid lead\n        leadSurrogate = codePoint\n\n        continue\n      }\n\n      // 2 leads in a row\n      if (codePoint < 0xDC00) {\n        if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD)\n        leadSurrogate = codePoint\n        continue\n      }\n\n      // valid surrogate pair\n      codePoint = (leadSurrogate - 0xD800 << 10 | codePoint - 0xDC00) + 0x10000\n    } else if (leadSurrogate) {\n      // valid bmp char, but last char was a lead\n      if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD)\n    }\n\n    leadSurrogate = null\n\n    // encode utf8\n    if (codePoint < 0x80) {\n      if ((units -= 1) < 0) break\n      bytes.push(codePoint)\n    } else if (codePoint < 0x800) {\n      if ((units -= 2) < 0) break\n      bytes.push(\n        codePoint >> 0x6 | 0xC0,\n        codePoint & 0x3F | 0x80\n      )\n    } else if (codePoint < 0x10000) {\n      if ((units -= 3) < 0) break\n      bytes.push(\n        codePoint >> 0xC | 0xE0,\n        codePoint >> 0x6 & 0x3F | 0x80,\n        codePoint & 0x3F | 0x80\n      )\n    } else if (codePoint < 0x110000) {\n      if ((units -= 4) < 0) break\n      bytes.push(\n        codePoint >> 0x12 | 0xF0,\n        codePoint >> 0xC & 0x3F | 0x80,\n        codePoint >> 0x6 & 0x3F | 0x80,\n        codePoint & 0x3F | 0x80\n      )\n    } else {\n      throw new Error('Invalid code point')\n    }\n  }\n\n  return bytes\n}\n\nfunction asciiToBytes (str) {\n  var byteArray = []\n  for (var i = 0; i < str.length; ++i) {\n    // Node's code seems to be doing this and not & 0x7F..\n    byteArray.push(str.charCodeAt(i) & 0xFF)\n  }\n  return byteArray\n}\n\nfunction utf16leToBytes (str, units) {\n  var c, hi, lo\n  var byteArray = []\n  for (var i = 0; i < str.length; ++i) {\n    if ((units -= 2) < 0) break\n\n    c = str.charCodeAt(i)\n    hi = c >> 8\n    lo = c % 256\n    byteArray.push(lo)\n    byteArray.push(hi)\n  }\n\n  return byteArray\n}\n\nfunction base64ToBytes (str) {\n  return base64.toByteArray(base64clean(str))\n}\n\nfunction blitBuffer (src, dst, offset, length) {\n  for (var i = 0; i < length; ++i) {\n    if ((i + offset >= dst.length) || (i >= src.length)) break\n    dst[i + offset] = src[i]\n  }\n  return i\n}\n\nfunction isnan (val) {\n  return val !== val // eslint-disable-line no-self-compare\n}\n\n}).call(this,typeof global !== \"undefined\" ? global : typeof self !== \"undefined\" ? self : typeof window !== \"undefined\" ? window : {})\n},{\"base64-js\":39,\"ieee754\":50,\"isarray\":53}],45:[function(require,module,exports){\n(function (Buffer){\n// Copyright Joyent, Inc. and other Node contributors.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a\n// copy of this software and associated documentation files (the\n// \"Software\"), to deal in the Software without restriction, including\n// without limitation the rights to use, copy, modify, merge, publish,\n// distribute, sublicense, and/or sell copies of the Software, and to permit\n// persons to whom the Software is furnished to do so, subject to the\n// following conditions:\n//\n// The above copyright notice and this permission notice shall be included\n// in all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS\n// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN\n// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,\n// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE\n// USE OR OTHER DEALINGS IN THE SOFTWARE.\n\n// NOTE: These type checking functions intentionally don't use `instanceof`\n// because it is fragile and can be easily faked with `Object.create()`.\n\nfunction isArray(arg) {\n  if (Array.isArray) {\n    return Array.isArray(arg);\n  }\n  return objectToString(arg) === '[object Array]';\n}\nexports.isArray = isArray;\n\nfunction isBoolean(arg) {\n  return typeof arg === 'boolean';\n}\nexports.isBoolean = isBoolean;\n\nfunction isNull(arg) {\n  return arg === null;\n}\nexports.isNull = isNull;\n\nfunction isNullOrUndefined(arg) {\n  return arg == null;\n}\nexports.isNullOrUndefined = isNullOrUndefined;\n\nfunction isNumber(arg) {\n  return typeof arg === 'number';\n}\nexports.isNumber = isNumber;\n\nfunction isString(arg) {\n  return typeof arg === 'string';\n}\nexports.isString = isString;\n\nfunction isSymbol(arg) {\n  return typeof arg === 'symbol';\n}\nexports.isSymbol = isSymbol;\n\nfunction isUndefined(arg) {\n  return arg === void 0;\n}\nexports.isUndefined = isUndefined;\n\nfunction isRegExp(re) {\n  return objectToString(re) === '[object RegExp]';\n}\nexports.isRegExp = isRegExp;\n\nfunction isObject(arg) {\n  return typeof arg === 'object' && arg !== null;\n}\nexports.isObject = isObject;\n\nfunction isDate(d) {\n  return objectToString(d) === '[object Date]';\n}\nexports.isDate = isDate;\n\nfunction isError(e) {\n  return (objectToString(e) === '[object Error]' || e instanceof Error);\n}\nexports.isError = isError;\n\nfunction isFunction(arg) {\n  return typeof arg === 'function';\n}\nexports.isFunction = isFunction;\n\nfunction isPrimitive(arg) {\n  return arg === null ||\n         typeof arg === 'boolean' ||\n         typeof arg === 'number' ||\n         typeof arg === 'string' ||\n         typeof arg === 'symbol' ||  // ES6 symbol\n         typeof arg === 'undefined';\n}\nexports.isPrimitive = isPrimitive;\n\nexports.isBuffer = Buffer.isBuffer;\n\nfunction objectToString(o) {\n  return Object.prototype.toString.call(o);\n}\n\n}).call(this,{\"isBuffer\":require(\"../../is-buffer/index.js\")})\n},{\"../../is-buffer/index.js\":52}],46:[function(require,module,exports){\n/* See LICENSE file for terms of use */\n\n/*\n * Text diff implementation.\n *\n * This library supports the following APIS:\n * JsDiff.diffChars: Character by character diff\n * JsDiff.diffWords: Word (as defined by \\b regex) diff which ignores whitespace\n * JsDiff.diffLines: Line based diff\n *\n * JsDiff.diffCss: Diff targeted at CSS content\n *\n * These methods are based on the implementation proposed in\n * \"An O(ND) Difference Algorithm and its Variations\" (Myers, 1986).\n * http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.4.6927\n */\n(function(global, undefined) {\n  var objectPrototypeToString = Object.prototype.toString;\n\n  /*istanbul ignore next*/\n  function map(arr, mapper, that) {\n    if (Array.prototype.map) {\n      return Array.prototype.map.call(arr, mapper, that);\n    }\n\n    var other = new Array(arr.length);\n\n    for (var i = 0, n = arr.length; i < n; i++) {\n      other[i] = mapper.call(that, arr[i], i, arr);\n    }\n    return other;\n  }\n  function clonePath(path) {\n    return { newPos: path.newPos, components: path.components.slice(0) };\n  }\n  function removeEmpty(array) {\n    var ret = [];\n    for (var i = 0; i < array.length; i++) {\n      if (array[i]) {\n        ret.push(array[i]);\n      }\n    }\n    return ret;\n  }\n  function escapeHTML(s) {\n    var n = s;\n    n = n.replace(/&/g, '&amp;');\n    n = n.replace(/</g, '&lt;');\n    n = n.replace(/>/g, '&gt;');\n    n = n.replace(/\"/g, '&quot;');\n\n    return n;\n  }\n\n  // This function handles the presence of circular references by bailing out when encountering an\n  // object that is already on the \"stack\" of items being processed.\n  function canonicalize(obj, stack, replacementStack) {\n    stack = stack || [];\n    replacementStack = replacementStack || [];\n\n    var i;\n\n    for (i = 0; i < stack.length; i += 1) {\n      if (stack[i] === obj) {\n        return replacementStack[i];\n      }\n    }\n\n    var canonicalizedObj;\n\n    if ('[object Array]' === objectPrototypeToString.call(obj)) {\n      stack.push(obj);\n      canonicalizedObj = new Array(obj.length);\n      replacementStack.push(canonicalizedObj);\n      for (i = 0; i < obj.length; i += 1) {\n        canonicalizedObj[i] = canonicalize(obj[i], stack, replacementStack);\n      }\n      stack.pop();\n      replacementStack.pop();\n    } else if (typeof obj === 'object' && obj !== null) {\n      stack.push(obj);\n      canonicalizedObj = {};\n      replacementStack.push(canonicalizedObj);\n      var sortedKeys = [],\n          key;\n      for (key in obj) {\n        sortedKeys.push(key);\n      }\n      sortedKeys.sort();\n      for (i = 0; i < sortedKeys.length; i += 1) {\n        key = sortedKeys[i];\n        canonicalizedObj[key] = canonicalize(obj[key], stack, replacementStack);\n      }\n      stack.pop();\n      replacementStack.pop();\n    } else {\n      canonicalizedObj = obj;\n    }\n    return canonicalizedObj;\n  }\n\n  function buildValues(components, newString, oldString, useLongestToken) {\n    var componentPos = 0,\n        componentLen = components.length,\n        newPos = 0,\n        oldPos = 0;\n\n    for (; componentPos < componentLen; componentPos++) {\n      var component = components[componentPos];\n      if (!component.removed) {\n        if (!component.added && useLongestToken) {\n          var value = newString.slice(newPos, newPos + component.count);\n          value = map(value, function(value, i) {\n            var oldValue = oldString[oldPos + i];\n            return oldValue.length > value.length ? oldValue : value;\n          });\n\n          component.value = value.join('');\n        } else {\n          component.value = newString.slice(newPos, newPos + component.count).join('');\n        }\n        newPos += component.count;\n\n        // Common case\n        if (!component.added) {\n          oldPos += component.count;\n        }\n      } else {\n        component.value = oldString.slice(oldPos, oldPos + component.count).join('');\n        oldPos += component.count;\n\n        // Reverse add and remove so removes are output first to match common convention\n        // The diffing algorithm is tied to add then remove output and this is the simplest\n        // route to get the desired output with minimal overhead.\n        if (componentPos && components[componentPos - 1].added) {\n          var tmp = components[componentPos - 1];\n          components[componentPos - 1] = components[componentPos];\n          components[componentPos] = tmp;\n        }\n      }\n    }\n\n    return components;\n  }\n\n  function Diff(ignoreWhitespace) {\n    this.ignoreWhitespace = ignoreWhitespace;\n  }\n  Diff.prototype = {\n    diff: function(oldString, newString, callback) {\n      var self = this;\n\n      function done(value) {\n        if (callback) {\n          setTimeout(function() { callback(undefined, value); }, 0);\n          return true;\n        } else {\n          return value;\n        }\n      }\n\n      // Handle the identity case (this is due to unrolling editLength == 0\n      if (newString === oldString) {\n        return done([{ value: newString }]);\n      }\n      if (!newString) {\n        return done([{ value: oldString, removed: true }]);\n      }\n      if (!oldString) {\n        return done([{ value: newString, added: true }]);\n      }\n\n      newString = this.tokenize(newString);\n      oldString = this.tokenize(oldString);\n\n      var newLen = newString.length, oldLen = oldString.length;\n      var editLength = 1;\n      var maxEditLength = newLen + oldLen;\n      var bestPath = [{ newPos: -1, components: [] }];\n\n      // Seed editLength = 0, i.e. the content starts with the same values\n      var oldPos = this.extractCommon(bestPath[0], newString, oldString, 0);\n      if (bestPath[0].newPos + 1 >= newLen && oldPos + 1 >= oldLen) {\n        // Identity per the equality and tokenizer\n        return done([{value: newString.join('')}]);\n      }\n\n      // Main worker method. checks all permutations of a given edit length for acceptance.\n      function execEditLength() {\n        for (var diagonalPath = -1 * editLength; diagonalPath <= editLength; diagonalPath += 2) {\n          var basePath;\n          var addPath = bestPath[diagonalPath - 1],\n              removePath = bestPath[diagonalPath + 1],\n              oldPos = (removePath ? removePath.newPos : 0) - diagonalPath;\n          if (addPath) {\n            // No one else is going to attempt to use this value, clear it\n            bestPath[diagonalPath - 1] = undefined;\n          }\n\n          var canAdd = addPath && addPath.newPos + 1 < newLen,\n              canRemove = removePath && 0 <= oldPos && oldPos < oldLen;\n          if (!canAdd && !canRemove) {\n            // If this path is a terminal then prune\n            bestPath[diagonalPath] = undefined;\n            continue;\n          }\n\n          // Select the diagonal that we want to branch from. We select the prior\n          // path whose position in the new string is the farthest from the origin\n          // and does not pass the bounds of the diff graph\n          if (!canAdd || (canRemove && addPath.newPos < removePath.newPos)) {\n            basePath = clonePath(removePath);\n            self.pushComponent(basePath.components, undefined, true);\n          } else {\n            basePath = addPath;   // No need to clone, we've pulled it from the list\n            basePath.newPos++;\n            self.pushComponent(basePath.components, true, undefined);\n          }\n\n          oldPos = self.extractCommon(basePath, newString, oldString, diagonalPath);\n\n          // If we have hit the end of both strings, then we are done\n          if (basePath.newPos + 1 >= newLen && oldPos + 1 >= oldLen) {\n            return done(buildValues(basePath.components, newString, oldString, self.useLongestToken));\n          } else {\n            // Otherwise track this path as a potential candidate and continue.\n            bestPath[diagonalPath] = basePath;\n          }\n        }\n\n        editLength++;\n      }\n\n      // Performs the length of edit iteration. Is a bit fugly as this has to support the\n      // sync and async mode which is never fun. Loops over execEditLength until a value\n      // is produced.\n      if (callback) {\n        (function exec() {\n          setTimeout(function() {\n            // This should not happen, but we want to be safe.\n            /*istanbul ignore next */\n            if (editLength > maxEditLength) {\n              return callback();\n            }\n\n            if (!execEditLength()) {\n              exec();\n            }\n          }, 0);\n        }());\n      } else {\n        while (editLength <= maxEditLength) {\n          var ret = execEditLength();\n          if (ret) {\n            return ret;\n          }\n        }\n      }\n    },\n\n    pushComponent: function(components, added, removed) {\n      var last = components[components.length - 1];\n      if (last && last.added === added && last.removed === removed) {\n        // We need to clone here as the component clone operation is just\n        // as shallow array clone\n        components[components.length - 1] = {count: last.count + 1, added: added, removed: removed };\n      } else {\n        components.push({count: 1, added: added, removed: removed });\n      }\n    },\n    extractCommon: function(basePath, newString, oldString, diagonalPath) {\n      var newLen = newString.length,\n          oldLen = oldString.length,\n          newPos = basePath.newPos,\n          oldPos = newPos - diagonalPath,\n\n          commonCount = 0;\n      while (newPos + 1 < newLen && oldPos + 1 < oldLen && this.equals(newString[newPos + 1], oldString[oldPos + 1])) {\n        newPos++;\n        oldPos++;\n        commonCount++;\n      }\n\n      if (commonCount) {\n        basePath.components.push({count: commonCount});\n      }\n\n      basePath.newPos = newPos;\n      return oldPos;\n    },\n\n    equals: function(left, right) {\n      var reWhitespace = /\\S/;\n      return left === right || (this.ignoreWhitespace && !reWhitespace.test(left) && !reWhitespace.test(right));\n    },\n    tokenize: function(value) {\n      return value.split('');\n    }\n  };\n\n  var CharDiff = new Diff();\n\n  var WordDiff = new Diff(true);\n  var WordWithSpaceDiff = new Diff();\n  WordDiff.tokenize = WordWithSpaceDiff.tokenize = function(value) {\n    return removeEmpty(value.split(/(\\s+|\\b)/));\n  };\n\n  var CssDiff = new Diff(true);\n  CssDiff.tokenize = function(value) {\n    return removeEmpty(value.split(/([{}:;,]|\\s+)/));\n  };\n\n  var LineDiff = new Diff();\n\n  var TrimmedLineDiff = new Diff();\n  TrimmedLineDiff.ignoreTrim = true;\n\n  LineDiff.tokenize = TrimmedLineDiff.tokenize = function(value) {\n    var retLines = [],\n        lines = value.split(/^/m);\n    for (var i = 0; i < lines.length; i++) {\n      var line = lines[i],\n          lastLine = lines[i - 1],\n          lastLineLastChar = lastLine && lastLine[lastLine.length - 1];\n\n      // Merge lines that may contain windows new lines\n      if (line === '\\n' && lastLineLastChar === '\\r') {\n          retLines[retLines.length - 1] = retLines[retLines.length - 1].slice(0, -1) + '\\r\\n';\n      } else {\n        if (this.ignoreTrim) {\n          line = line.trim();\n          // add a newline unless this is the last line.\n          if (i < lines.length - 1) {\n            line += '\\n';\n          }\n        }\n        retLines.push(line);\n      }\n    }\n\n    return retLines;\n  };\n\n  var PatchDiff = new Diff();\n  PatchDiff.tokenize = function(value) {\n    var ret = [],\n        linesAndNewlines = value.split(/(\\n|\\r\\n)/);\n\n    // Ignore the final empty token that occurs if the string ends with a new line\n    if (!linesAndNewlines[linesAndNewlines.length - 1]) {\n      linesAndNewlines.pop();\n    }\n\n    // Merge the content and line separators into single tokens\n    for (var i = 0; i < linesAndNewlines.length; i++) {\n      var line = linesAndNewlines[i];\n\n      if (i % 2) {\n        ret[ret.length - 1] += line;\n      } else {\n        ret.push(line);\n      }\n    }\n    return ret;\n  };\n\n  var SentenceDiff = new Diff();\n  SentenceDiff.tokenize = function(value) {\n    return removeEmpty(value.split(/(\\S.+?[.!?])(?=\\s+|$)/));\n  };\n\n  var JsonDiff = new Diff();\n  // Discriminate between two lines of pretty-printed, serialized JSON where one of them has a\n  // dangling comma and the other doesn't. Turns out including the dangling comma yields the nicest output:\n  JsonDiff.useLongestToken = true;\n  JsonDiff.tokenize = LineDiff.tokenize;\n  JsonDiff.equals = function(left, right) {\n    return LineDiff.equals(left.replace(/,([\\r\\n])/g, '$1'), right.replace(/,([\\r\\n])/g, '$1'));\n  };\n\n  var JsDiff = {\n    Diff: Diff,\n\n    diffChars: function(oldStr, newStr, callback) { return CharDiff.diff(oldStr, newStr, callback); },\n    diffWords: function(oldStr, newStr, callback) { return WordDiff.diff(oldStr, newStr, callback); },\n    diffWordsWithSpace: function(oldStr, newStr, callback) { return WordWithSpaceDiff.diff(oldStr, newStr, callback); },\n    diffLines: function(oldStr, newStr, callback) { return LineDiff.diff(oldStr, newStr, callback); },\n    diffTrimmedLines: function(oldStr, newStr, callback) { return TrimmedLineDiff.diff(oldStr, newStr, callback); },\n\n    diffSentences: function(oldStr, newStr, callback) { return SentenceDiff.diff(oldStr, newStr, callback); },\n\n    diffCss: function(oldStr, newStr, callback) { return CssDiff.diff(oldStr, newStr, callback); },\n    diffJson: function(oldObj, newObj, callback) {\n      return JsonDiff.diff(\n        typeof oldObj === 'string' ? oldObj : JSON.stringify(canonicalize(oldObj), undefined, '  '),\n        typeof newObj === 'string' ? newObj : JSON.stringify(canonicalize(newObj), undefined, '  '),\n        callback\n      );\n    },\n\n    createTwoFilesPatch: function(oldFileName, newFileName, oldStr, newStr, oldHeader, newHeader) {\n      var ret = [];\n\n      if (oldFileName == newFileName) {\n        ret.push('Index: ' + oldFileName);\n      }\n      ret.push('===================================================================');\n      ret.push('--- ' + oldFileName + (typeof oldHeader === 'undefined' ? '' : '\\t' + oldHeader));\n      ret.push('+++ ' + newFileName + (typeof newHeader === 'undefined' ? '' : '\\t' + newHeader));\n\n      var diff = PatchDiff.diff(oldStr, newStr);\n      diff.push({value: '', lines: []});   // Append an empty value to make cleanup easier\n\n      // Formats a given set of lines for printing as context lines in a patch\n      function contextLines(lines) {\n        return map(lines, function(entry) { return ' ' + entry; });\n      }\n\n      // Outputs the no newline at end of file warning if needed\n      function eofNL(curRange, i, current) {\n        var last = diff[diff.length - 2],\n            isLast = i === diff.length - 2,\n            isLastOfType = i === diff.length - 3 && current.added !== last.added;\n\n        // Figure out if this is the last line for the given file and missing NL\n        if (!(/\\n$/.test(current.value)) && (isLast || isLastOfType)) {\n          curRange.push('\\\\ No newline at end of file');\n        }\n      }\n\n      var oldRangeStart = 0, newRangeStart = 0, curRange = [],\n          oldLine = 1, newLine = 1;\n      for (var i = 0; i < diff.length; i++) {\n        var current = diff[i],\n            lines = current.lines || current.value.replace(/\\n$/, '').split('\\n');\n        current.lines = lines;\n\n        if (current.added || current.removed) {\n          // If we have previous context, start with that\n          if (!oldRangeStart) {\n            var prev = diff[i - 1];\n            oldRangeStart = oldLine;\n            newRangeStart = newLine;\n\n            if (prev) {\n              curRange = contextLines(prev.lines.slice(-4));\n              oldRangeStart -= curRange.length;\n              newRangeStart -= curRange.length;\n            }\n          }\n\n          // Output our changes\n          curRange.push.apply(curRange, map(lines, function(entry) {\n            return (current.added ? '+' : '-') + entry;\n          }));\n          eofNL(curRange, i, current);\n\n          // Track the updated file position\n          if (current.added) {\n            newLine += lines.length;\n          } else {\n            oldLine += lines.length;\n          }\n        } else {\n          // Identical context lines. Track line changes\n          if (oldRangeStart) {\n            // Close out any changes that have been output (or join overlapping)\n            if (lines.length <= 8 && i < diff.length - 2) {\n              // Overlapping\n              curRange.push.apply(curRange, contextLines(lines));\n            } else {\n              // end the range and output\n              var contextSize = Math.min(lines.length, 4);\n              ret.push(\n                  '@@ -' + oldRangeStart + ',' + (oldLine - oldRangeStart + contextSize)\n                  + ' +' + newRangeStart + ',' + (newLine - newRangeStart + contextSize)\n                  + ' @@');\n              ret.push.apply(ret, curRange);\n              ret.push.apply(ret, contextLines(lines.slice(0, contextSize)));\n              if (lines.length <= 4) {\n                eofNL(ret, i, current);\n              }\n\n              oldRangeStart = 0;\n              newRangeStart = 0;\n              curRange = [];\n            }\n          }\n          oldLine += lines.length;\n          newLine += lines.length;\n        }\n      }\n\n      return ret.join('\\n') + '\\n';\n    },\n\n    createPatch: function(fileName, oldStr, newStr, oldHeader, newHeader) {\n      return JsDiff.createTwoFilesPatch(fileName, fileName, oldStr, newStr, oldHeader, newHeader);\n    },\n\n    applyPatch: function(oldStr, uniDiff) {\n      var diffstr = uniDiff.split('\\n'),\n          hunks = [],\n          i = 0,\n          remEOFNL = false,\n          addEOFNL = false;\n\n      // Skip to the first change hunk\n      while (i < diffstr.length && !(/^@@/.test(diffstr[i]))) {\n        i++;\n      }\n\n      // Parse the unified diff\n      for (; i < diffstr.length; i++) {\n        if (diffstr[i][0] === '@') {\n          var chnukHeader = diffstr[i].split(/@@ -(\\d+),(\\d+) \\+(\\d+),(\\d+) @@/);\n          hunks.unshift({\n            start: chnukHeader[3],\n            oldlength: +chnukHeader[2],\n            removed: [],\n            newlength: chnukHeader[4],\n            added: []\n          });\n        } else if (diffstr[i][0] === '+') {\n          hunks[0].added.push(diffstr[i].substr(1));\n        } else if (diffstr[i][0] === '-') {\n          hunks[0].removed.push(diffstr[i].substr(1));\n        } else if (diffstr[i][0] === ' ') {\n          hunks[0].added.push(diffstr[i].substr(1));\n          hunks[0].removed.push(diffstr[i].substr(1));\n        } else if (diffstr[i][0] === '\\\\') {\n          if (diffstr[i - 1][0] === '+') {\n            remEOFNL = true;\n          } else if (diffstr[i - 1][0] === '-') {\n            addEOFNL = true;\n          }\n        }\n      }\n\n      // Apply the diff to the input\n      var lines = oldStr.split('\\n');\n      for (i = hunks.length - 1; i >= 0; i--) {\n        var hunk = hunks[i];\n        // Sanity check the input string. Bail if we don't match.\n        for (var j = 0; j < hunk.oldlength; j++) {\n          if (lines[hunk.start - 1 + j] !== hunk.removed[j]) {\n            return false;\n          }\n        }\n        Array.prototype.splice.apply(lines, [hunk.start - 1, hunk.oldlength].concat(hunk.added));\n      }\n\n      // Handle EOFNL insertion/removal\n      if (remEOFNL) {\n        while (!lines[lines.length - 1]) {\n          lines.pop();\n        }\n      } else if (addEOFNL) {\n        lines.push('');\n      }\n      return lines.join('\\n');\n    },\n\n    convertChangesToXML: function(changes) {\n      var ret = [];\n      for (var i = 0; i < changes.length; i++) {\n        var change = changes[i];\n        if (change.added) {\n          ret.push('<ins>');\n        } else if (change.removed) {\n          ret.push('<del>');\n        }\n\n        ret.push(escapeHTML(change.value));\n\n        if (change.added) {\n          ret.push('</ins>');\n        } else if (change.removed) {\n          ret.push('</del>');\n        }\n      }\n      return ret.join('');\n    },\n\n    // See: http://code.google.com/p/google-diff-match-patch/wiki/API\n    convertChangesToDMP: function(changes) {\n      var ret = [],\n          change,\n          operation;\n      for (var i = 0; i < changes.length; i++) {\n        change = changes[i];\n        if (change.added) {\n          operation = 1;\n        } else if (change.removed) {\n          operation = -1;\n        } else {\n          operation = 0;\n        }\n\n        ret.push([operation, change.value]);\n      }\n      return ret;\n    },\n\n    canonicalize: canonicalize\n  };\n\n  /*istanbul ignore next */\n  /*global module */\n  if (typeof module !== 'undefined' && module.exports) {\n    module.exports = JsDiff;\n  } else if (false) {\n    /*global define */\n    define([], function() { return JsDiff; });\n  } else if (typeof global.JsDiff === 'undefined') {\n    global.JsDiff = JsDiff;\n  }\n}(this));\n\n},{}],47:[function(require,module,exports){\n'use strict';\n\nvar matchOperatorsRe = /[|\\\\{}()[\\]^$+*?.]/g;\n\nmodule.exports = function (str) {\n\tif (typeof str !== 'string') {\n\t\tthrow new TypeError('Expected a string');\n\t}\n\n\treturn str.replace(matchOperatorsRe, '\\\\$&');\n};\n\n},{}],48:[function(require,module,exports){\n// Copyright Joyent, Inc. and other Node contributors.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a\n// copy of this software and associated documentation files (the\n// \"Software\"), to deal in the Software without restriction, including\n// without limitation the rights to use, copy, modify, merge, publish,\n// distribute, sublicense, and/or sell copies of the Software, and to permit\n// persons to whom the Software is furnished to do so, subject to the\n// following conditions:\n//\n// The above copyright notice and this permission notice shall be included\n// in all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS\n// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN\n// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,\n// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE\n// USE OR OTHER DEALINGS IN THE SOFTWARE.\n\nfunction EventEmitter() {\n  this._events = this._events || {};\n  this._maxListeners = this._maxListeners || undefined;\n}\nmodule.exports = EventEmitter;\n\n// Backwards-compat with node 0.10.x\nEventEmitter.EventEmitter = EventEmitter;\n\nEventEmitter.prototype._events = undefined;\nEventEmitter.prototype._maxListeners = undefined;\n\n// By default EventEmitters will print a warning if more than 10 listeners are\n// added to it. This is a useful default which helps finding memory leaks.\nEventEmitter.defaultMaxListeners = 10;\n\n// Obviously not all Emitters should be limited to 10. This function allows\n// that to be increased. Set to zero for unlimited.\nEventEmitter.prototype.setMaxListeners = function(n) {\n  if (!isNumber(n) || n < 0 || isNaN(n))\n    throw TypeError('n must be a positive number');\n  this._maxListeners = n;\n  return this;\n};\n\nEventEmitter.prototype.emit = function(type) {\n  var er, handler, len, args, i, listeners;\n\n  if (!this._events)\n    this._events = {};\n\n  // If there is no 'error' event listener then throw.\n  if (type === 'error') {\n    if (!this._events.error ||\n        (isObject(this._events.error) && !this._events.error.length)) {\n      er = arguments[1];\n      if (er instanceof Error) {\n        throw er; // Unhandled 'error' event\n      } else {\n        // At least give some kind of context to the user\n        var err = new Error('Uncaught, unspecified \"error\" event. (' + er + ')');\n        err.context = er;\n        throw err;\n      }\n    }\n  }\n\n  handler = this._events[type];\n\n  if (isUndefined(handler))\n    return false;\n\n  if (isFunction(handler)) {\n    switch (arguments.length) {\n      // fast cases\n      case 1:\n        handler.call(this);\n        break;\n      case 2:\n        handler.call(this, arguments[1]);\n        break;\n      case 3:\n        handler.call(this, arguments[1], arguments[2]);\n        break;\n      // slower\n      default:\n        args = Array.prototype.slice.call(arguments, 1);\n        handler.apply(this, args);\n    }\n  } else if (isObject(handler)) {\n    args = Array.prototype.slice.call(arguments, 1);\n    listeners = handler.slice();\n    len = listeners.length;\n    for (i = 0; i < len; i++)\n      listeners[i].apply(this, args);\n  }\n\n  return true;\n};\n\nEventEmitter.prototype.addListener = function(type, listener) {\n  var m;\n\n  if (!isFunction(listener))\n    throw TypeError('listener must be a function');\n\n  if (!this._events)\n    this._events = {};\n\n  // To avoid recursion in the case that type === \"newListener\"! Before\n  // adding it to the listeners, first emit \"newListener\".\n  if (this._events.newListener)\n    this.emit('newListener', type,\n              isFunction(listener.listener) ?\n              listener.listener : listener);\n\n  if (!this._events[type])\n    // Optimize the case of one listener. Don't need the extra array object.\n    this._events[type] = listener;\n  else if (isObject(this._events[type]))\n    // If we've already got an array, just append.\n    this._events[type].push(listener);\n  else\n    // Adding the second element, need to change to array.\n    this._events[type] = [this._events[type], listener];\n\n  // Check for listener leak\n  if (isObject(this._events[type]) && !this._events[type].warned) {\n    if (!isUndefined(this._maxListeners)) {\n      m = this._maxListeners;\n    } else {\n      m = EventEmitter.defaultMaxListeners;\n    }\n\n    if (m && m > 0 && this._events[type].length > m) {\n      this._events[type].warned = true;\n      console.error('(node) warning: possible EventEmitter memory ' +\n                    'leak detected. %d listeners added. ' +\n                    'Use emitter.setMaxListeners() to increase limit.',\n                    this._events[type].length);\n      if (typeof console.trace === 'function') {\n        // not supported in IE 10\n        console.trace();\n      }\n    }\n  }\n\n  return this;\n};\n\nEventEmitter.prototype.on = EventEmitter.prototype.addListener;\n\nEventEmitter.prototype.once = function(type, listener) {\n  if (!isFunction(listener))\n    throw TypeError('listener must be a function');\n\n  var fired = false;\n\n  function g() {\n    this.removeListener(type, g);\n\n    if (!fired) {\n      fired = true;\n      listener.apply(this, arguments);\n    }\n  }\n\n  g.listener = listener;\n  this.on(type, g);\n\n  return this;\n};\n\n// emits a 'removeListener' event iff the listener was removed\nEventEmitter.prototype.removeListener = function(type, listener) {\n  var list, position, length, i;\n\n  if (!isFunction(listener))\n    throw TypeError('listener must be a function');\n\n  if (!this._events || !this._events[type])\n    return this;\n\n  list = this._events[type];\n  length = list.length;\n  position = -1;\n\n  if (list === listener ||\n      (isFunction(list.listener) && list.listener === listener)) {\n    delete this._events[type];\n    if (this._events.removeListener)\n      this.emit('removeListener', type, listener);\n\n  } else if (isObject(list)) {\n    for (i = length; i-- > 0;) {\n      if (list[i] === listener ||\n          (list[i].listener && list[i].listener === listener)) {\n        position = i;\n        break;\n      }\n    }\n\n    if (position < 0)\n      return this;\n\n    if (list.length === 1) {\n      list.length = 0;\n      delete this._events[type];\n    } else {\n      list.splice(position, 1);\n    }\n\n    if (this._events.removeListener)\n      this.emit('removeListener', type, listener);\n  }\n\n  return this;\n};\n\nEventEmitter.prototype.removeAllListeners = function(type) {\n  var key, listeners;\n\n  if (!this._events)\n    return this;\n\n  // not listening for removeListener, no need to emit\n  if (!this._events.removeListener) {\n    if (arguments.length === 0)\n      this._events = {};\n    else if (this._events[type])\n      delete this._events[type];\n    return this;\n  }\n\n  // emit removeListener for all listeners on all events\n  if (arguments.length === 0) {\n    for (key in this._events) {\n      if (key === 'removeListener') continue;\n      this.removeAllListeners(key);\n    }\n    this.removeAllListeners('removeListener');\n    this._events = {};\n    return this;\n  }\n\n  listeners = this._events[type];\n\n  if (isFunction(listeners)) {\n    this.removeListener(type, listeners);\n  } else if (listeners) {\n    // LIFO order\n    while (listeners.length)\n      this.removeListener(type, listeners[listeners.length - 1]);\n  }\n  delete this._events[type];\n\n  return this;\n};\n\nEventEmitter.prototype.listeners = function(type) {\n  var ret;\n  if (!this._events || !this._events[type])\n    ret = [];\n  else if (isFunction(this._events[type]))\n    ret = [this._events[type]];\n  else\n    ret = this._events[type].slice();\n  return ret;\n};\n\nEventEmitter.prototype.listenerCount = function(type) {\n  if (this._events) {\n    var evlistener = this._events[type];\n\n    if (isFunction(evlistener))\n      return 1;\n    else if (evlistener)\n      return evlistener.length;\n  }\n  return 0;\n};\n\nEventEmitter.listenerCount = function(emitter, type) {\n  return emitter.listenerCount(type);\n};\n\nfunction isFunction(arg) {\n  return typeof arg === 'function';\n}\n\nfunction isNumber(arg) {\n  return typeof arg === 'number';\n}\n\nfunction isObject(arg) {\n  return typeof arg === 'object' && arg !== null;\n}\n\nfunction isUndefined(arg) {\n  return arg === void 0;\n}\n\n},{}],49:[function(require,module,exports){\n(function (process){\n// Growl - Copyright TJ Holowaychuk <tj@vision-media.ca> (MIT Licensed)\n\n/**\n * Module dependencies.\n */\n\nvar exec = require('child_process').exec\n  , fs = require('fs')\n  , path = require('path')\n  , exists = fs.existsSync || path.existsSync\n  , os = require('os')\n  , quote = JSON.stringify\n  , cmd;\n\nfunction which(name) {\n  var paths = process.env.PATH.split(':');\n  var loc;\n\n  for (var i = 0, len = paths.length; i < len; ++i) {\n    loc = path.join(paths[i], name);\n    if (exists(loc)) return loc;\n  }\n}\n\nswitch(os.type()) {\n  case 'Darwin':\n    if (which('terminal-notifier')) {\n      cmd = {\n          type: \"Darwin-NotificationCenter\"\n        , pkg: \"terminal-notifier\"\n        , msg: '-message'\n        , title: '-title'\n        , subtitle: '-subtitle'\n        , icon: '-appIcon'\n        , sound:  '-sound'\n        , url: '-open'\n        , priority: {\n              cmd: '-execute'\n            , range: []\n          }\n      };\n    } else {\n      cmd = {\n          type: \"Darwin-Growl\"\n        , pkg: \"growlnotify\"\n        , msg: '-m'\n        , sticky: '--sticky'\n        , priority: {\n              cmd: '--priority'\n            , range: [\n                -2\n              , -1\n              , 0\n              , 1\n              , 2\n              , \"Very Low\"\n              , \"Moderate\"\n              , \"Normal\"\n              , \"High\"\n              , \"Emergency\"\n            ]\n          }\n      };\n    }\n    break;\n  case 'Linux':\n    if (which('growl')) {\n      cmd = {\n          type: \"Linux-Growl\"\n        , pkg: \"growl\"\n        , msg: '-m'\n        , title: '-title'\n        , subtitle: '-subtitle'\n        , host: {\n            cmd: '-H'\n          , hostname: '192.168.33.1'\n        }\n      };\n    } else {\n      cmd = {\n          type: \"Linux\"\n        , pkg: \"notify-send\"\n        , msg: ''\n        , sticky: '-t 0'\n        , icon: '-i'\n        , priority: {\n            cmd: '-u'\n          , range: [\n              \"low\"\n            , \"normal\"\n            , \"critical\"\n          ]\n        }\n      };\n    }\n    break;\n  case 'Windows_NT':\n    cmd = {\n        type: \"Windows\"\n      , pkg: \"growlnotify\"\n      , msg: ''\n      , sticky: '/s:true'\n      , title: '/t:'\n      , icon: '/i:'\n      , url: '/cu:'\n      , priority: {\n            cmd: '/p:'\n          , range: [\n              -2\n            , -1\n            , 0\n            , 1\n            , 2\n          ]\n        }\n    };\n    break;\n}\n\n/**\n * Expose `growl`.\n */\n\nexports = module.exports = growl;\n\n/**\n * Node-growl version.\n */\n\nexports.version = '1.4.1'\n\n/**\n * Send growl notification _msg_ with _options_.\n *\n * Options:\n *\n *  - title   Notification title\n *  - sticky  Make the notification stick (defaults to false)\n *  - priority  Specify an int or named key (default is 0)\n *  - name    Application name (defaults to growlnotify)\n *  - sound   Sound efect ( in OSx defined in preferences -> sound -> effects) * works only in OSX > 10.8x\n *  - image\n *    - path to an icon sets --iconpath\n *    - path to an image sets --image\n *    - capitalized word sets --appIcon\n *    - filename uses extname as --icon\n *    - otherwise treated as --icon\n *\n * Examples:\n *\n *   growl('New email')\n *   growl('5 new emails', { title: 'Thunderbird' })\n *   growl('5 new emails', { title: 'Thunderbird', sound: 'Purr' })\n *   growl('Email sent', function(){\n *     // ... notification sent\n *   })\n *\n * @param {string} msg\n * @param {object} options\n * @param {function} fn\n * @api public\n */\n\nfunction growl(msg, options, fn) {\n  var image\n    , args\n    , options = options || {}\n    , fn = fn || function(){};\n\n  if (options.exec) {\n    cmd = {\n        type: \"Custom\"\n      , pkg: options.exec\n      , range: []\n    };\n  }\n\n  // noop\n  if (!cmd) return fn(new Error('growl not supported on this platform'));\n  args = [cmd.pkg];\n\n  // image\n  if (image = options.image) {\n    switch(cmd.type) {\n      case 'Darwin-Growl':\n        var flag, ext = path.extname(image).substr(1)\n        flag = flag || ext == 'icns' && 'iconpath'\n        flag = flag || /^[A-Z]/.test(image) && 'appIcon'\n        flag = flag || /^png|gif|jpe?g$/.test(ext) && 'image'\n        flag = flag || ext && (image = ext) && 'icon'\n        flag = flag || 'icon'\n        args.push('--' + flag, quote(image))\n        break;\n      case 'Darwin-NotificationCenter':\n        args.push(cmd.icon, quote(image));\n        break;\n      case 'Linux':\n        args.push(cmd.icon, quote(image));\n        // libnotify defaults to sticky, set a hint for transient notifications\n        if (!options.sticky) args.push('--hint=int:transient:1');\n        break;\n      case 'Windows':\n        args.push(cmd.icon + quote(image));\n        break;\n    }\n  }\n\n  // sticky\n  if (options.sticky) args.push(cmd.sticky);\n\n  // priority\n  if (options.priority) {\n    var priority = options.priority + '';\n    var checkindexOf = cmd.priority.range.indexOf(priority);\n    if (~cmd.priority.range.indexOf(priority)) {\n      args.push(cmd.priority, options.priority);\n    }\n  }\n\n  //sound\n  if(options.sound && cmd.type === 'Darwin-NotificationCenter'){\n    args.push(cmd.sound, options.sound)\n  }\n\n  // name\n  if (options.name && cmd.type === \"Darwin-Growl\") {\n    args.push('--name', options.name);\n  }\n\n  switch(cmd.type) {\n    case 'Darwin-Growl':\n      args.push(cmd.msg);\n      args.push(quote(msg).replace(/\\\\n/g, '\\n'));\n      if (options.title) args.push(quote(options.title));\n      break;\n    case 'Darwin-NotificationCenter':\n      args.push(cmd.msg);\n      var stringifiedMsg = quote(msg);\n      var escapedMsg = stringifiedMsg.replace(/\\\\n/g, '\\n');\n      args.push(escapedMsg);\n      if (options.title) {\n        args.push(cmd.title);\n        args.push(quote(options.title));\n      }\n      if (options.subtitle) {\n        args.push(cmd.subtitle);\n        args.push(quote(options.subtitle));\n      }\n      if (options.url) {\n        args.push(cmd.url);\n        args.push(quote(options.url));\n      }\n      break;\n    case 'Linux-Growl':\n      args.push(cmd.msg);\n      args.push(quote(msg).replace(/\\\\n/g, '\\n'));\n      if (options.title) args.push(quote(options.title));\n      if (cmd.host) {\n        args.push(cmd.host.cmd, cmd.host.hostname)\n      }\n      break;\n    case 'Linux':\n      if (options.title) {\n        args.push(quote(options.title));\n        args.push(cmd.msg);\n        args.push(quote(msg).replace(/\\\\n/g, '\\n'));\n      } else {\n        args.push(quote(msg).replace(/\\\\n/g, '\\n'));\n      }\n      break;\n    case 'Windows':\n      args.push(quote(msg).replace(/\\\\n/g, '\\n'));\n      if (options.title) args.push(cmd.title + quote(options.title));\n      if (options.url) args.push(cmd.url + quote(options.url));\n      break;\n    case 'Custom':\n      args[0] = (function(origCommand) {\n        var message = options.title\n          ? options.title + ': ' + msg\n          : msg;\n        var command = origCommand.replace(/(^|[^%])%s/g, '$1' + quote(message));\n        if (command === origCommand) args.push(quote(message));\n        return command;\n      })(args[0]);\n      break;\n  }\n\n  // execute\n  exec(args.join(' '), fn);\n};\n\n}).call(this,require('_process'))\n},{\"_process\":67,\"child_process\":42,\"fs\":42,\"os\":65,\"path\":42}],50:[function(require,module,exports){\nexports.read = function (buffer, offset, isLE, mLen, nBytes) {\n  var e, m\n  var eLen = nBytes * 8 - mLen - 1\n  var eMax = (1 << eLen) - 1\n  var eBias = eMax >> 1\n  var nBits = -7\n  var i = isLE ? (nBytes - 1) : 0\n  var d = isLE ? -1 : 1\n  var s = buffer[offset + i]\n\n  i += d\n\n  e = s & ((1 << (-nBits)) - 1)\n  s >>= (-nBits)\n  nBits += eLen\n  for (; nBits > 0; e = e * 256 + buffer[offset + i], i += d, nBits -= 8) {}\n\n  m = e & ((1 << (-nBits)) - 1)\n  e >>= (-nBits)\n  nBits += mLen\n  for (; nBits > 0; m = m * 256 + buffer[offset + i], i += d, nBits -= 8) {}\n\n  if (e === 0) {\n    e = 1 - eBias\n  } else if (e === eMax) {\n    return m ? NaN : ((s ? -1 : 1) * Infinity)\n  } else {\n    m = m + Math.pow(2, mLen)\n    e = e - eBias\n  }\n  return (s ? -1 : 1) * m * Math.pow(2, e - mLen)\n}\n\nexports.write = function (buffer, value, offset, isLE, mLen, nBytes) {\n  var e, m, c\n  var eLen = nBytes * 8 - mLen - 1\n  var eMax = (1 << eLen) - 1\n  var eBias = eMax >> 1\n  var rt = (mLen === 23 ? Math.pow(2, -24) - Math.pow(2, -77) : 0)\n  var i = isLE ? 0 : (nBytes - 1)\n  var d = isLE ? 1 : -1\n  var s = value < 0 || (value === 0 && 1 / value < 0) ? 1 : 0\n\n  value = Math.abs(value)\n\n  if (isNaN(value) || value === Infinity) {\n    m = isNaN(value) ? 1 : 0\n    e = eMax\n  } else {\n    e = Math.floor(Math.log(value) / Math.LN2)\n    if (value * (c = Math.pow(2, -e)) < 1) {\n      e--\n      c *= 2\n    }\n    if (e + eBias >= 1) {\n      value += rt / c\n    } else {\n      value += rt * Math.pow(2, 1 - eBias)\n    }\n    if (value * c >= 2) {\n      e++\n      c /= 2\n    }\n\n    if (e + eBias >= eMax) {\n      m = 0\n      e = eMax\n    } else if (e + eBias >= 1) {\n      m = (value * c - 1) * Math.pow(2, mLen)\n      e = e + eBias\n    } else {\n      m = value * Math.pow(2, eBias - 1) * Math.pow(2, mLen)\n      e = 0\n    }\n  }\n\n  for (; mLen >= 8; buffer[offset + i] = m & 0xff, i += d, m /= 256, mLen -= 8) {}\n\n  e = (e << mLen) | m\n  eLen += mLen\n  for (; eLen > 0; buffer[offset + i] = e & 0xff, i += d, e /= 256, eLen -= 8) {}\n\n  buffer[offset + i - d] |= s * 128\n}\n\n},{}],51:[function(require,module,exports){\nif (typeof Object.create === 'function') {\n  // implementation from standard node.js 'util' module\n  module.exports = function inherits(ctor, superCtor) {\n    ctor.super_ = superCtor\n    ctor.prototype = Object.create(superCtor.prototype, {\n      constructor: {\n        value: ctor,\n        enumerable: false,\n        writable: true,\n        configurable: true\n      }\n    });\n  };\n} else {\n  // old school shim for old browsers\n  module.exports = function inherits(ctor, superCtor) {\n    ctor.super_ = superCtor\n    var TempCtor = function () {}\n    TempCtor.prototype = superCtor.prototype\n    ctor.prototype = new TempCtor()\n    ctor.prototype.constructor = ctor\n  }\n}\n\n},{}],52:[function(require,module,exports){\n/*!\n * Determine if an object is a Buffer\n *\n * @author   Feross Aboukhadijeh <feross@feross.org> <http://feross.org>\n * @license  MIT\n */\n\n// The _isBuffer check is for Safari 5-7 support, because it's missing\n// Object.prototype.constructor. Remove this eventually\nmodule.exports = function (obj) {\n  return obj != null && (isBuffer(obj) || isSlowBuffer(obj) || !!obj._isBuffer)\n}\n\nfunction isBuffer (obj) {\n  return !!obj.constructor && typeof obj.constructor.isBuffer === 'function' && obj.constructor.isBuffer(obj)\n}\n\n// For Node v0.10 support. Remove this eventually.\nfunction isSlowBuffer (obj) {\n  return typeof obj.readFloatLE === 'function' && typeof obj.slice === 'function' && isBuffer(obj.slice(0, 0))\n}\n\n},{}],53:[function(require,module,exports){\nvar toString = {}.toString;\n\nmodule.exports = Array.isArray || function (arr) {\n  return toString.call(arr) == '[object Array]';\n};\n\n},{}],54:[function(require,module,exports){\n(function (global){\n/*! JSON v3.3.2 | http://bestiejs.github.io/json3 | Copyright 2012-2014, Kit Cambridge | http://kit.mit-license.org */\n;(function () {\n  // Detect the `define` function exposed by asynchronous module loaders. The\n  // strict `define` check is necessary for compatibility with `r.js`.\n  var isLoader = false;\n\n  // A set of types used to distinguish objects from primitives.\n  var objectTypes = {\n    \"function\": true,\n    \"object\": true\n  };\n\n  // Detect the `exports` object exposed by CommonJS implementations.\n  var freeExports = objectTypes[typeof exports] && exports && !exports.nodeType && exports;\n\n  // Use the `global` object exposed by Node (including Browserify via\n  // `insert-module-globals`), Narwhal, and Ringo as the default context,\n  // and the `window` object in browsers. Rhino exports a `global` function\n  // instead.\n  var root = objectTypes[typeof window] && window || this,\n      freeGlobal = freeExports && objectTypes[typeof module] && module && !module.nodeType && typeof global == \"object\" && global;\n\n  if (freeGlobal && (freeGlobal[\"global\"] === freeGlobal || freeGlobal[\"window\"] === freeGlobal || freeGlobal[\"self\"] === freeGlobal)) {\n    root = freeGlobal;\n  }\n\n  // Public: Initializes JSON 3 using the given `context` object, attaching the\n  // `stringify` and `parse` functions to the specified `exports` object.\n  function runInContext(context, exports) {\n    context || (context = root[\"Object\"]());\n    exports || (exports = root[\"Object\"]());\n\n    // Native constructor aliases.\n    var Number = context[\"Number\"] || root[\"Number\"],\n        String = context[\"String\"] || root[\"String\"],\n        Object = context[\"Object\"] || root[\"Object\"],\n        Date = context[\"Date\"] || root[\"Date\"],\n        SyntaxError = context[\"SyntaxError\"] || root[\"SyntaxError\"],\n        TypeError = context[\"TypeError\"] || root[\"TypeError\"],\n        Math = context[\"Math\"] || root[\"Math\"],\n        nativeJSON = context[\"JSON\"] || root[\"JSON\"];\n\n    // Delegate to the native `stringify` and `parse` implementations.\n    if (typeof nativeJSON == \"object\" && nativeJSON) {\n      exports.stringify = nativeJSON.stringify;\n      exports.parse = nativeJSON.parse;\n    }\n\n    // Convenience aliases.\n    var objectProto = Object.prototype,\n        getClass = objectProto.toString,\n        isProperty, forEach, undef;\n\n    // Test the `Date#getUTC*` methods. Based on work by @Yaffle.\n    var isExtended = new Date(-3509827334573292);\n    try {\n      // The `getUTCFullYear`, `Month`, and `Date` methods return nonsensical\n      // results for certain dates in Opera >= 10.53.\n      isExtended = isExtended.getUTCFullYear() == -109252 && isExtended.getUTCMonth() === 0 && isExtended.getUTCDate() === 1 &&\n        // Safari < 2.0.2 stores the internal millisecond time value correctly,\n        // but clips the values returned by the date methods to the range of\n        // signed 32-bit integers ([-2 ** 31, 2 ** 31 - 1]).\n        isExtended.getUTCHours() == 10 && isExtended.getUTCMinutes() == 37 && isExtended.getUTCSeconds() == 6 && isExtended.getUTCMilliseconds() == 708;\n    } catch (exception) {}\n\n    // Internal: Determines whether the native `JSON.stringify` and `parse`\n    // implementations are spec-compliant. Based on work by Ken Snyder.\n    function has(name) {\n      if (has[name] !== undef) {\n        // Return cached feature test result.\n        return has[name];\n      }\n      var isSupported;\n      if (name == \"bug-string-char-index\") {\n        // IE <= 7 doesn't support accessing string characters using square\n        // bracket notation. IE 8 only supports this for primitives.\n        isSupported = \"a\"[0] != \"a\";\n      } else if (name == \"json\") {\n        // Indicates whether both `JSON.stringify` and `JSON.parse` are\n        // supported.\n        isSupported = has(\"json-stringify\") && has(\"json-parse\");\n      } else {\n        var value, serialized = '{\"a\":[1,true,false,null,\"\\\\u0000\\\\b\\\\n\\\\f\\\\r\\\\t\"]}';\n        // Test `JSON.stringify`.\n        if (name == \"json-stringify\") {\n          var stringify = exports.stringify, stringifySupported = typeof stringify == \"function\" && isExtended;\n          if (stringifySupported) {\n            // A test function object with a custom `toJSON` method.\n            (value = function () {\n              return 1;\n            }).toJSON = value;\n            try {\n              stringifySupported =\n                // Firefox 3.1b1 and b2 serialize string, number, and boolean\n                // primitives as object literals.\n                stringify(0) === \"0\" &&\n                // FF 3.1b1, b2, and JSON 2 serialize wrapped primitives as object\n                // literals.\n                stringify(new Number()) === \"0\" &&\n                stringify(new String()) == '\"\"' &&\n                // FF 3.1b1, 2 throw an error if the value is `null`, `undefined`, or\n                // does not define a canonical JSON representation (this applies to\n                // objects with `toJSON` properties as well, *unless* they are nested\n                // within an object or array).\n                stringify(getClass) === undef &&\n                // IE 8 serializes `undefined` as `\"undefined\"`. Safari <= 5.1.7 and\n                // FF 3.1b3 pass this test.\n                stringify(undef) === undef &&\n                // Safari <= 5.1.7 and FF 3.1b3 throw `Error`s and `TypeError`s,\n                // respectively, if the value is omitted entirely.\n                stringify() === undef &&\n                // FF 3.1b1, 2 throw an error if the given value is not a number,\n                // string, array, object, Boolean, or `null` literal. This applies to\n                // objects with custom `toJSON` methods as well, unless they are nested\n                // inside object or array literals. YUI 3.0.0b1 ignores custom `toJSON`\n                // methods entirely.\n                stringify(value) === \"1\" &&\n                stringify([value]) == \"[1]\" &&\n                // Prototype <= 1.6.1 serializes `[undefined]` as `\"[]\"` instead of\n                // `\"[null]\"`.\n                stringify([undef]) == \"[null]\" &&\n                // YUI 3.0.0b1 fails to serialize `null` literals.\n                stringify(null) == \"null\" &&\n                // FF 3.1b1, 2 halts serialization if an array contains a function:\n                // `[1, true, getClass, 1]` serializes as \"[1,true,],\". FF 3.1b3\n                // elides non-JSON values from objects and arrays, unless they\n                // define custom `toJSON` methods.\n                stringify([undef, getClass, null]) == \"[null,null,null]\" &&\n                // Simple serialization test. FF 3.1b1 uses Unicode escape sequences\n                // where character escape codes are expected (e.g., `\\b` => `\\u0008`).\n                stringify({ \"a\": [value, true, false, null, \"\\x00\\b\\n\\f\\r\\t\"] }) == serialized &&\n                // FF 3.1b1 and b2 ignore the `filter` and `width` arguments.\n                stringify(null, value) === \"1\" &&\n                stringify([1, 2], null, 1) == \"[\\n 1,\\n 2\\n]\" &&\n                // JSON 2, Prototype <= 1.7, and older WebKit builds incorrectly\n                // serialize extended years.\n                stringify(new Date(-8.64e15)) == '\"-271821-04-20T00:00:00.000Z\"' &&\n                // The milliseconds are optional in ES 5, but required in 5.1.\n                stringify(new Date(8.64e15)) == '\"+275760-09-13T00:00:00.000Z\"' &&\n                // Firefox <= 11.0 incorrectly serializes years prior to 0 as negative\n                // four-digit years instead of six-digit years. Credits: @Yaffle.\n                stringify(new Date(-621987552e5)) == '\"-000001-01-01T00:00:00.000Z\"' &&\n                // Safari <= 5.1.5 and Opera >= 10.53 incorrectly serialize millisecond\n                // values less than 1000. Credits: @Yaffle.\n                stringify(new Date(-1)) == '\"1969-12-31T23:59:59.999Z\"';\n            } catch (exception) {\n              stringifySupported = false;\n            }\n          }\n          isSupported = stringifySupported;\n        }\n        // Test `JSON.parse`.\n        if (name == \"json-parse\") {\n          var parse = exports.parse;\n          if (typeof parse == \"function\") {\n            try {\n              // FF 3.1b1, b2 will throw an exception if a bare literal is provided.\n              // Conforming implementations should also coerce the initial argument to\n              // a string prior to parsing.\n              if (parse(\"0\") === 0 && !parse(false)) {\n                // Simple parsing test.\n                value = parse(serialized);\n                var parseSupported = value[\"a\"].length == 5 && value[\"a\"][0] === 1;\n                if (parseSupported) {\n                  try {\n                    // Safari <= 5.1.2 and FF 3.1b1 allow unescaped tabs in strings.\n                    parseSupported = !parse('\"\\t\"');\n                  } catch (exception) {}\n                  if (parseSupported) {\n                    try {\n                      // FF 4.0 and 4.0.1 allow leading `+` signs and leading\n                      // decimal points. FF 4.0, 4.0.1, and IE 9-10 also allow\n                      // certain octal literals.\n                      parseSupported = parse(\"01\") !== 1;\n                    } catch (exception) {}\n                  }\n                  if (parseSupported) {\n                    try {\n                      // FF 4.0, 4.0.1, and Rhino 1.7R3-R4 allow trailing decimal\n                      // points. These environments, along with FF 3.1b1 and 2,\n                      // also allow trailing commas in JSON objects and arrays.\n                      parseSupported = parse(\"1.\") !== 1;\n                    } catch (exception) {}\n                  }\n                }\n              }\n            } catch (exception) {\n              parseSupported = false;\n            }\n          }\n          isSupported = parseSupported;\n        }\n      }\n      return has[name] = !!isSupported;\n    }\n\n    if (!has(\"json\")) {\n      // Common `[[Class]]` name aliases.\n      var functionClass = \"[object Function]\",\n          dateClass = \"[object Date]\",\n          numberClass = \"[object Number]\",\n          stringClass = \"[object String]\",\n          arrayClass = \"[object Array]\",\n          booleanClass = \"[object Boolean]\";\n\n      // Detect incomplete support for accessing string characters by index.\n      var charIndexBuggy = has(\"bug-string-char-index\");\n\n      // Define additional utility methods if the `Date` methods are buggy.\n      if (!isExtended) {\n        var floor = Math.floor;\n        // A mapping between the months of the year and the number of days between\n        // January 1st and the first of the respective month.\n        var Months = [0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334];\n        // Internal: Calculates the number of days between the Unix epoch and the\n        // first day of the given month.\n        var getDay = function (year, month) {\n          return Months[month] + 365 * (year - 1970) + floor((year - 1969 + (month = +(month > 1))) / 4) - floor((year - 1901 + month) / 100) + floor((year - 1601 + month) / 400);\n        };\n      }\n\n      // Internal: Determines if a property is a direct property of the given\n      // object. Delegates to the native `Object#hasOwnProperty` method.\n      if (!(isProperty = objectProto.hasOwnProperty)) {\n        isProperty = function (property) {\n          var members = {}, constructor;\n          if ((members.__proto__ = null, members.__proto__ = {\n            // The *proto* property cannot be set multiple times in recent\n            // versions of Firefox and SeaMonkey.\n            \"toString\": 1\n          }, members).toString != getClass) {\n            // Safari <= 2.0.3 doesn't implement `Object#hasOwnProperty`, but\n            // supports the mutable *proto* property.\n            isProperty = function (property) {\n              // Capture and break the object's prototype chain (see section 8.6.2\n              // of the ES 5.1 spec). The parenthesized expression prevents an\n              // unsafe transformation by the Closure Compiler.\n              var original = this.__proto__, result = property in (this.__proto__ = null, this);\n              // Restore the original prototype chain.\n              this.__proto__ = original;\n              return result;\n            };\n          } else {\n            // Capture a reference to the top-level `Object` constructor.\n            constructor = members.constructor;\n            // Use the `constructor` property to simulate `Object#hasOwnProperty` in\n            // other environments.\n            isProperty = function (property) {\n              var parent = (this.constructor || constructor).prototype;\n              return property in this && !(property in parent && this[property] === parent[property]);\n            };\n          }\n          members = null;\n          return isProperty.call(this, property);\n        };\n      }\n\n      // Internal: Normalizes the `for...in` iteration algorithm across\n      // environments. Each enumerated key is yielded to a `callback` function.\n      forEach = function (object, callback) {\n        var size = 0, Properties, members, property;\n\n        // Tests for bugs in the current environment's `for...in` algorithm. The\n        // `valueOf` property inherits the non-enumerable flag from\n        // `Object.prototype` in older versions of IE, Netscape, and Mozilla.\n        (Properties = function () {\n          this.valueOf = 0;\n        }).prototype.valueOf = 0;\n\n        // Iterate over a new instance of the `Properties` class.\n        members = new Properties();\n        for (property in members) {\n          // Ignore all properties inherited from `Object.prototype`.\n          if (isProperty.call(members, property)) {\n            size++;\n          }\n        }\n        Properties = members = null;\n\n        // Normalize the iteration algorithm.\n        if (!size) {\n          // A list of non-enumerable properties inherited from `Object.prototype`.\n          members = [\"valueOf\", \"toString\", \"toLocaleString\", \"propertyIsEnumerable\", \"isPrototypeOf\", \"hasOwnProperty\", \"constructor\"];\n          // IE <= 8, Mozilla 1.0, and Netscape 6.2 ignore shadowed non-enumerable\n          // properties.\n          forEach = function (object, callback) {\n            var isFunction = getClass.call(object) == functionClass, property, length;\n            var hasProperty = !isFunction && typeof object.constructor != \"function\" && objectTypes[typeof object.hasOwnProperty] && object.hasOwnProperty || isProperty;\n            for (property in object) {\n              // Gecko <= 1.0 enumerates the `prototype` property of functions under\n              // certain conditions; IE does not.\n              if (!(isFunction && property == \"prototype\") && hasProperty.call(object, property)) {\n                callback(property);\n              }\n            }\n            // Manually invoke the callback for each non-enumerable property.\n            for (length = members.length; property = members[--length]; hasProperty.call(object, property) && callback(property));\n          };\n        } else if (size == 2) {\n          // Safari <= 2.0.4 enumerates shadowed properties twice.\n          forEach = function (object, callback) {\n            // Create a set of iterated properties.\n            var members = {}, isFunction = getClass.call(object) == functionClass, property;\n            for (property in object) {\n              // Store each property name to prevent double enumeration. The\n              // `prototype` property of functions is not enumerated due to cross-\n              // environment inconsistencies.\n              if (!(isFunction && property == \"prototype\") && !isProperty.call(members, property) && (members[property] = 1) && isProperty.call(object, property)) {\n                callback(property);\n              }\n            }\n          };\n        } else {\n          // No bugs detected; use the standard `for...in` algorithm.\n          forEach = function (object, callback) {\n            var isFunction = getClass.call(object) == functionClass, property, isConstructor;\n            for (property in object) {\n              if (!(isFunction && property == \"prototype\") && isProperty.call(object, property) && !(isConstructor = property === \"constructor\")) {\n                callback(property);\n              }\n            }\n            // Manually invoke the callback for the `constructor` property due to\n            // cross-environment inconsistencies.\n            if (isConstructor || isProperty.call(object, (property = \"constructor\"))) {\n              callback(property);\n            }\n          };\n        }\n        return forEach(object, callback);\n      };\n\n      // Public: Serializes a JavaScript `value` as a JSON string. The optional\n      // `filter` argument may specify either a function that alters how object and\n      // array members are serialized, or an array of strings and numbers that\n      // indicates which properties should be serialized. The optional `width`\n      // argument may be either a string or number that specifies the indentation\n      // level of the output.\n      if (!has(\"json-stringify\")) {\n        // Internal: A map of control characters and their escaped equivalents.\n        var Escapes = {\n          92: \"\\\\\\\\\",\n          34: '\\\\\"',\n          8: \"\\\\b\",\n          12: \"\\\\f\",\n          10: \"\\\\n\",\n          13: \"\\\\r\",\n          9: \"\\\\t\"\n        };\n\n        // Internal: Converts `value` into a zero-padded string such that its\n        // length is at least equal to `width`. The `width` must be <= 6.\n        var leadingZeroes = \"000000\";\n        var toPaddedString = function (width, value) {\n          // The `|| 0` expression is necessary to work around a bug in\n          // Opera <= 7.54u2 where `0 == -0`, but `String(-0) !== \"0\"`.\n          return (leadingZeroes + (value || 0)).slice(-width);\n        };\n\n        // Internal: Double-quotes a string `value`, replacing all ASCII control\n        // characters (characters with code unit values between 0 and 31) with\n        // their escaped equivalents. This is an implementation of the\n        // `Quote(value)` operation defined in ES 5.1 section 15.12.3.\n        var unicodePrefix = \"\\\\u00\";\n        var quote = function (value) {\n          var result = '\"', index = 0, length = value.length, useCharIndex = !charIndexBuggy || length > 10;\n          var symbols = useCharIndex && (charIndexBuggy ? value.split(\"\") : value);\n          for (; index < length; index++) {\n            var charCode = value.charCodeAt(index);\n            // If the character is a control character, append its Unicode or\n            // shorthand escape sequence; otherwise, append the character as-is.\n            switch (charCode) {\n              case 8: case 9: case 10: case 12: case 13: case 34: case 92:\n                result += Escapes[charCode];\n                break;\n              default:\n                if (charCode < 32) {\n                  result += unicodePrefix + toPaddedString(2, charCode.toString(16));\n                  break;\n                }\n                result += useCharIndex ? symbols[index] : value.charAt(index);\n            }\n          }\n          return result + '\"';\n        };\n\n        // Internal: Recursively serializes an object. Implements the\n        // `Str(key, holder)`, `JO(value)`, and `JA(value)` operations.\n        var serialize = function (property, object, callback, properties, whitespace, indentation, stack) {\n          var value, className, year, month, date, time, hours, minutes, seconds, milliseconds, results, element, index, length, prefix, result;\n          try {\n            // Necessary for host object support.\n            value = object[property];\n          } catch (exception) {}\n          if (typeof value == \"object\" && value) {\n            className = getClass.call(value);\n            if (className == dateClass && !isProperty.call(value, \"toJSON\")) {\n              if (value > -1 / 0 && value < 1 / 0) {\n                // Dates are serialized according to the `Date#toJSON` method\n                // specified in ES 5.1 section 15.9.5.44. See section 15.9.1.15\n                // for the ISO 8601 date time string format.\n                if (getDay) {\n                  // Manually compute the year, month, date, hours, minutes,\n                  // seconds, and milliseconds if the `getUTC*` methods are\n                  // buggy. Adapted from @Yaffle's `date-shim` project.\n                  date = floor(value / 864e5);\n                  for (year = floor(date / 365.2425) + 1970 - 1; getDay(year + 1, 0) <= date; year++);\n                  for (month = floor((date - getDay(year, 0)) / 30.42); getDay(year, month + 1) <= date; month++);\n                  date = 1 + date - getDay(year, month);\n                  // The `time` value specifies the time within the day (see ES\n                  // 5.1 section 15.9.1.2). The formula `(A % B + B) % B` is used\n                  // to compute `A modulo B`, as the `%` operator does not\n                  // correspond to the `modulo` operation for negative numbers.\n                  time = (value % 864e5 + 864e5) % 864e5;\n                  // The hours, minutes, seconds, and milliseconds are obtained by\n                  // decomposing the time within the day. See section 15.9.1.10.\n                  hours = floor(time / 36e5) % 24;\n                  minutes = floor(time / 6e4) % 60;\n                  seconds = floor(time / 1e3) % 60;\n                  milliseconds = time % 1e3;\n                } else {\n                  year = value.getUTCFullYear();\n                  month = value.getUTCMonth();\n                  date = value.getUTCDate();\n                  hours = value.getUTCHours();\n                  minutes = value.getUTCMinutes();\n                  seconds = value.getUTCSeconds();\n                  milliseconds = value.getUTCMilliseconds();\n                }\n                // Serialize extended years correctly.\n                value = (year <= 0 || year >= 1e4 ? (year < 0 ? \"-\" : \"+\") + toPaddedString(6, year < 0 ? -year : year) : toPaddedString(4, year)) +\n                  \"-\" + toPaddedString(2, month + 1) + \"-\" + toPaddedString(2, date) +\n                  // Months, dates, hours, minutes, and seconds should have two\n                  // digits; milliseconds should have three.\n                  \"T\" + toPaddedString(2, hours) + \":\" + toPaddedString(2, minutes) + \":\" + toPaddedString(2, seconds) +\n                  // Milliseconds are optional in ES 5.0, but required in 5.1.\n                  \".\" + toPaddedString(3, milliseconds) + \"Z\";\n              } else {\n                value = null;\n              }\n            } else if (typeof value.toJSON == \"function\" && ((className != numberClass && className != stringClass && className != arrayClass) || isProperty.call(value, \"toJSON\"))) {\n              // Prototype <= 1.6.1 adds non-standard `toJSON` methods to the\n              // `Number`, `String`, `Date`, and `Array` prototypes. JSON 3\n              // ignores all `toJSON` methods on these objects unless they are\n              // defined directly on an instance.\n              value = value.toJSON(property);\n            }\n          }\n          if (callback) {\n            // If a replacement function was provided, call it to obtain the value\n            // for serialization.\n            value = callback.call(object, property, value);\n          }\n          if (value === null) {\n            return \"null\";\n          }\n          className = getClass.call(value);\n          if (className == booleanClass) {\n            // Booleans are represented literally.\n            return \"\" + value;\n          } else if (className == numberClass) {\n            // JSON numbers must be finite. `Infinity` and `NaN` are serialized as\n            // `\"null\"`.\n            return value > -1 / 0 && value < 1 / 0 ? \"\" + value : \"null\";\n          } else if (className == stringClass) {\n            // Strings are double-quoted and escaped.\n            return quote(\"\" + value);\n          }\n          // Recursively serialize objects and arrays.\n          if (typeof value == \"object\") {\n            // Check for cyclic structures. This is a linear search; performance\n            // is inversely proportional to the number of unique nested objects.\n            for (length = stack.length; length--;) {\n              if (stack[length] === value) {\n                // Cyclic structures cannot be serialized by `JSON.stringify`.\n                throw TypeError();\n              }\n            }\n            // Add the object to the stack of traversed objects.\n            stack.push(value);\n            results = [];\n            // Save the current indentation level and indent one additional level.\n            prefix = indentation;\n            indentation += whitespace;\n            if (className == arrayClass) {\n              // Recursively serialize array elements.\n              for (index = 0, length = value.length; index < length; index++) {\n                element = serialize(index, value, callback, properties, whitespace, indentation, stack);\n                results.push(element === undef ? \"null\" : element);\n              }\n              result = results.length ? (whitespace ? \"[\\n\" + indentation + results.join(\",\\n\" + indentation) + \"\\n\" + prefix + \"]\" : (\"[\" + results.join(\",\") + \"]\")) : \"[]\";\n            } else {\n              // Recursively serialize object members. Members are selected from\n              // either a user-specified list of property names, or the object\n              // itself.\n              forEach(properties || value, function (property) {\n                var element = serialize(property, value, callback, properties, whitespace, indentation, stack);\n                if (element !== undef) {\n                  // According to ES 5.1 section 15.12.3: \"If `gap` {whitespace}\n                  // is not the empty string, let `member` {quote(property) + \":\"}\n                  // be the concatenation of `member` and the `space` character.\"\n                  // The \"`space` character\" refers to the literal space\n                  // character, not the `space` {width} argument provided to\n                  // `JSON.stringify`.\n                  results.push(quote(property) + \":\" + (whitespace ? \" \" : \"\") + element);\n                }\n              });\n              result = results.length ? (whitespace ? \"{\\n\" + indentation + results.join(\",\\n\" + indentation) + \"\\n\" + prefix + \"}\" : (\"{\" + results.join(\",\") + \"}\")) : \"{}\";\n            }\n            // Remove the object from the traversed object stack.\n            stack.pop();\n            return result;\n          }\n        };\n\n        // Public: `JSON.stringify`. See ES 5.1 section 15.12.3.\n        exports.stringify = function (source, filter, width) {\n          var whitespace, callback, properties, className;\n          if (objectTypes[typeof filter] && filter) {\n            if ((className = getClass.call(filter)) == functionClass) {\n              callback = filter;\n            } else if (className == arrayClass) {\n              // Convert the property names array into a makeshift set.\n              properties = {};\n              for (var index = 0, length = filter.length, value; index < length; value = filter[index++], ((className = getClass.call(value)), className == stringClass || className == numberClass) && (properties[value] = 1));\n            }\n          }\n          if (width) {\n            if ((className = getClass.call(width)) == numberClass) {\n              // Convert the `width` to an integer and create a string containing\n              // `width` number of space characters.\n              if ((width -= width % 1) > 0) {\n                for (whitespace = \"\", width > 10 && (width = 10); whitespace.length < width; whitespace += \" \");\n              }\n            } else if (className == stringClass) {\n              whitespace = width.length <= 10 ? width : width.slice(0, 10);\n            }\n          }\n          // Opera <= 7.54u2 discards the values associated with empty string keys\n          // (`\"\"`) only if they are used directly within an object member list\n          // (e.g., `!(\"\" in { \"\": 1})`).\n          return serialize(\"\", (value = {}, value[\"\"] = source, value), callback, properties, whitespace, \"\", []);\n        };\n      }\n\n      // Public: Parses a JSON source string.\n      if (!has(\"json-parse\")) {\n        var fromCharCode = String.fromCharCode;\n\n        // Internal: A map of escaped control characters and their unescaped\n        // equivalents.\n        var Unescapes = {\n          92: \"\\\\\",\n          34: '\"',\n          47: \"/\",\n          98: \"\\b\",\n          116: \"\\t\",\n          110: \"\\n\",\n          102: \"\\f\",\n          114: \"\\r\"\n        };\n\n        // Internal: Stores the parser state.\n        var Index, Source;\n\n        // Internal: Resets the parser state and throws a `SyntaxError`.\n        var abort = function () {\n          Index = Source = null;\n          throw SyntaxError();\n        };\n\n        // Internal: Returns the next token, or `\"$\"` if the parser has reached\n        // the end of the source string. A token may be a string, number, `null`\n        // literal, or Boolean literal.\n        var lex = function () {\n          var source = Source, length = source.length, value, begin, position, isSigned, charCode;\n          while (Index < length) {\n            charCode = source.charCodeAt(Index);\n            switch (charCode) {\n              case 9: case 10: case 13: case 32:\n                // Skip whitespace tokens, including tabs, carriage returns, line\n                // feeds, and space characters.\n                Index++;\n                break;\n              case 123: case 125: case 91: case 93: case 58: case 44:\n                // Parse a punctuator token (`{`, `}`, `[`, `]`, `:`, or `,`) at\n                // the current position.\n                value = charIndexBuggy ? source.charAt(Index) : source[Index];\n                Index++;\n                return value;\n              case 34:\n                // `\"` delimits a JSON string; advance to the next character and\n                // begin parsing the string. String tokens are prefixed with the\n                // sentinel `@` character to distinguish them from punctuators and\n                // end-of-string tokens.\n                for (value = \"@\", Index++; Index < length;) {\n                  charCode = source.charCodeAt(Index);\n                  if (charCode < 32) {\n                    // Unescaped ASCII control characters (those with a code unit\n                    // less than the space character) are not permitted.\n                    abort();\n                  } else if (charCode == 92) {\n                    // A reverse solidus (`\\`) marks the beginning of an escaped\n                    // control character (including `\"`, `\\`, and `/`) or Unicode\n                    // escape sequence.\n                    charCode = source.charCodeAt(++Index);\n                    switch (charCode) {\n                      case 92: case 34: case 47: case 98: case 116: case 110: case 102: case 114:\n                        // Revive escaped control characters.\n                        value += Unescapes[charCode];\n                        Index++;\n                        break;\n                      case 117:\n                        // `\\u` marks the beginning of a Unicode escape sequence.\n                        // Advance to the first character and validate the\n                        // four-digit code point.\n                        begin = ++Index;\n                        for (position = Index + 4; Index < position; Index++) {\n                          charCode = source.charCodeAt(Index);\n                          // A valid sequence comprises four hexdigits (case-\n                          // insensitive) that form a single hexadecimal value.\n                          if (!(charCode >= 48 && charCode <= 57 || charCode >= 97 && charCode <= 102 || charCode >= 65 && charCode <= 70)) {\n                            // Invalid Unicode escape sequence.\n                            abort();\n                          }\n                        }\n                        // Revive the escaped character.\n                        value += fromCharCode(\"0x\" + source.slice(begin, Index));\n                        break;\n                      default:\n                        // Invalid escape sequence.\n                        abort();\n                    }\n                  } else {\n                    if (charCode == 34) {\n                      // An unescaped double-quote character marks the end of the\n                      // string.\n                      break;\n                    }\n                    charCode = source.charCodeAt(Index);\n                    begin = Index;\n                    // Optimize for the common case where a string is valid.\n                    while (charCode >= 32 && charCode != 92 && charCode != 34) {\n                      charCode = source.charCodeAt(++Index);\n                    }\n                    // Append the string as-is.\n                    value += source.slice(begin, Index);\n                  }\n                }\n                if (source.charCodeAt(Index) == 34) {\n                  // Advance to the next character and return the revived string.\n                  Index++;\n                  return value;\n                }\n                // Unterminated string.\n                abort();\n              default:\n                // Parse numbers and literals.\n                begin = Index;\n                // Advance past the negative sign, if one is specified.\n                if (charCode == 45) {\n                  isSigned = true;\n                  charCode = source.charCodeAt(++Index);\n                }\n                // Parse an integer or floating-point value.\n                if (charCode >= 48 && charCode <= 57) {\n                  // Leading zeroes are interpreted as octal literals.\n                  if (charCode == 48 && ((charCode = source.charCodeAt(Index + 1)), charCode >= 48 && charCode <= 57)) {\n                    // Illegal octal literal.\n                    abort();\n                  }\n                  isSigned = false;\n                  // Parse the integer component.\n                  for (; Index < length && ((charCode = source.charCodeAt(Index)), charCode >= 48 && charCode <= 57); Index++);\n                  // Floats cannot contain a leading decimal point; however, this\n                  // case is already accounted for by the parser.\n                  if (source.charCodeAt(Index) == 46) {\n                    position = ++Index;\n                    // Parse the decimal component.\n                    for (; position < length && ((charCode = source.charCodeAt(position)), charCode >= 48 && charCode <= 57); position++);\n                    if (position == Index) {\n                      // Illegal trailing decimal.\n                      abort();\n                    }\n                    Index = position;\n                  }\n                  // Parse exponents. The `e` denoting the exponent is\n                  // case-insensitive.\n                  charCode = source.charCodeAt(Index);\n                  if (charCode == 101 || charCode == 69) {\n                    charCode = source.charCodeAt(++Index);\n                    // Skip past the sign following the exponent, if one is\n                    // specified.\n                    if (charCode == 43 || charCode == 45) {\n                      Index++;\n                    }\n                    // Parse the exponential component.\n                    for (position = Index; position < length && ((charCode = source.charCodeAt(position)), charCode >= 48 && charCode <= 57); position++);\n                    if (position == Index) {\n                      // Illegal empty exponent.\n                      abort();\n                    }\n                    Index = position;\n                  }\n                  // Coerce the parsed value to a JavaScript number.\n                  return +source.slice(begin, Index);\n                }\n                // A negative sign may only precede numbers.\n                if (isSigned) {\n                  abort();\n                }\n                // `true`, `false`, and `null` literals.\n                if (source.slice(Index, Index + 4) == \"true\") {\n                  Index += 4;\n                  return true;\n                } else if (source.slice(Index, Index + 5) == \"false\") {\n                  Index += 5;\n                  return false;\n                } else if (source.slice(Index, Index + 4) == \"null\") {\n                  Index += 4;\n                  return null;\n                }\n                // Unrecognized token.\n                abort();\n            }\n          }\n          // Return the sentinel `$` character if the parser has reached the end\n          // of the source string.\n          return \"$\";\n        };\n\n        // Internal: Parses a JSON `value` token.\n        var get = function (value) {\n          var results, hasMembers;\n          if (value == \"$\") {\n            // Unexpected end of input.\n            abort();\n          }\n          if (typeof value == \"string\") {\n            if ((charIndexBuggy ? value.charAt(0) : value[0]) == \"@\") {\n              // Remove the sentinel `@` character.\n              return value.slice(1);\n            }\n            // Parse object and array literals.\n            if (value == \"[\") {\n              // Parses a JSON array, returning a new JavaScript array.\n              results = [];\n              for (;; hasMembers || (hasMembers = true)) {\n                value = lex();\n                // A closing square bracket marks the end of the array literal.\n                if (value == \"]\") {\n                  break;\n                }\n                // If the array literal contains elements, the current token\n                // should be a comma separating the previous element from the\n                // next.\n                if (hasMembers) {\n                  if (value == \",\") {\n                    value = lex();\n                    if (value == \"]\") {\n                      // Unexpected trailing `,` in array literal.\n                      abort();\n                    }\n                  } else {\n                    // A `,` must separate each array element.\n                    abort();\n                  }\n                }\n                // Elisions and leading commas are not permitted.\n                if (value == \",\") {\n                  abort();\n                }\n                results.push(get(value));\n              }\n              return results;\n            } else if (value == \"{\") {\n              // Parses a JSON object, returning a new JavaScript object.\n              results = {};\n              for (;; hasMembers || (hasMembers = true)) {\n                value = lex();\n                // A closing curly brace marks the end of the object literal.\n                if (value == \"}\") {\n                  break;\n                }\n                // If the object literal contains members, the current token\n                // should be a comma separator.\n                if (hasMembers) {\n                  if (value == \",\") {\n                    value = lex();\n                    if (value == \"}\") {\n                      // Unexpected trailing `,` in object literal.\n                      abort();\n                    }\n                  } else {\n                    // A `,` must separate each object member.\n                    abort();\n                  }\n                }\n                // Leading commas are not permitted, object property names must be\n                // double-quoted strings, and a `:` must separate each property\n                // name and value.\n                if (value == \",\" || typeof value != \"string\" || (charIndexBuggy ? value.charAt(0) : value[0]) != \"@\" || lex() != \":\") {\n                  abort();\n                }\n                results[value.slice(1)] = get(lex());\n              }\n              return results;\n            }\n            // Unexpected token encountered.\n            abort();\n          }\n          return value;\n        };\n\n        // Internal: Updates a traversed object member.\n        var update = function (source, property, callback) {\n          var element = walk(source, property, callback);\n          if (element === undef) {\n            delete source[property];\n          } else {\n            source[property] = element;\n          }\n        };\n\n        // Internal: Recursively traverses a parsed JSON object, invoking the\n        // `callback` function for each value. This is an implementation of the\n        // `Walk(holder, name)` operation defined in ES 5.1 section 15.12.2.\n        var walk = function (source, property, callback) {\n          var value = source[property], length;\n          if (typeof value == \"object\" && value) {\n            // `forEach` can't be used to traverse an array in Opera <= 8.54\n            // because its `Object#hasOwnProperty` implementation returns `false`\n            // for array indices (e.g., `![1, 2, 3].hasOwnProperty(\"0\")`).\n            if (getClass.call(value) == arrayClass) {\n              for (length = value.length; length--;) {\n                update(value, length, callback);\n              }\n            } else {\n              forEach(value, function (property) {\n                update(value, property, callback);\n              });\n            }\n          }\n          return callback.call(source, property, value);\n        };\n\n        // Public: `JSON.parse`. See ES 5.1 section 15.12.2.\n        exports.parse = function (source, callback) {\n          var result, value;\n          Index = 0;\n          Source = \"\" + source;\n          result = get(lex());\n          // If a JSON string contains multiple tokens, it is invalid.\n          if (lex() != \"$\") {\n            abort();\n          }\n          // Reset the parser state.\n          Index = Source = null;\n          return callback && getClass.call(callback) == functionClass ? walk((value = {}, value[\"\"] = result, value), \"\", callback) : result;\n        };\n      }\n    }\n\n    exports[\"runInContext\"] = runInContext;\n    return exports;\n  }\n\n  if (freeExports && !isLoader) {\n    // Export for CommonJS environments.\n    runInContext(root, freeExports);\n  } else {\n    // Export for web browsers and JavaScript engines.\n    var nativeJSON = root.JSON,\n        previousJSON = root[\"JSON3\"],\n        isRestored = false;\n\n    var JSON3 = runInContext(root, (root[\"JSON3\"] = {\n      // Public: Restores the original value of the global `JSON` object and\n      // returns a reference to the `JSON3` object.\n      \"noConflict\": function () {\n        if (!isRestored) {\n          isRestored = true;\n          root.JSON = nativeJSON;\n          root[\"JSON3\"] = previousJSON;\n          nativeJSON = previousJSON = null;\n        }\n        return JSON3;\n      }\n    }));\n\n    root.JSON = {\n      \"parse\": JSON3.parse,\n      \"stringify\": JSON3.stringify\n    };\n  }\n\n  // Export for asynchronous module loaders.\n  if (isLoader) {\n    define(function () {\n      return JSON3;\n    });\n  }\n}).call(this);\n\n}).call(this,typeof global !== \"undefined\" ? global : typeof self !== \"undefined\" ? self : typeof window !== \"undefined\" ? window : {})\n},{}],55:[function(require,module,exports){\n/**\n * lodash 3.2.0 (Custom Build) <https://lodash.com/>\n * Build: `lodash modern modularize exports=\"npm\" -o ./`\n * Copyright 2012-2015 The Dojo Foundation <http://dojofoundation.org/>\n * Based on Underscore.js 1.8.3 <http://underscorejs.org/LICENSE>\n * Copyright 2009-2015 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors\n * Available under MIT license <https://lodash.com/license>\n */\nvar baseCopy = require('lodash._basecopy'),\n    keys = require('lodash.keys');\n\n/**\n * The base implementation of `_.assign` without support for argument juggling,\n * multiple sources, and `customizer` functions.\n *\n * @private\n * @param {Object} object The destination object.\n * @param {Object} source The source object.\n * @returns {Object} Returns `object`.\n */\nfunction baseAssign(object, source) {\n  return source == null\n    ? object\n    : baseCopy(source, keys(source), object);\n}\n\nmodule.exports = baseAssign;\n\n},{\"lodash._basecopy\":56,\"lodash.keys\":63}],56:[function(require,module,exports){\n/**\n * lodash 3.0.1 (Custom Build) <https://lodash.com/>\n * Build: `lodash modern modularize exports=\"npm\" -o ./`\n * Copyright 2012-2015 The Dojo Foundation <http://dojofoundation.org/>\n * Based on Underscore.js 1.8.3 <http://underscorejs.org/LICENSE>\n * Copyright 2009-2015 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors\n * Available under MIT license <https://lodash.com/license>\n */\n\n/**\n * Copies properties of `source` to `object`.\n *\n * @private\n * @param {Object} source The object to copy properties from.\n * @param {Array} props The property names to copy.\n * @param {Object} [object={}] The object to copy properties to.\n * @returns {Object} Returns `object`.\n */\nfunction baseCopy(source, props, object) {\n  object || (object = {});\n\n  var index = -1,\n      length = props.length;\n\n  while (++index < length) {\n    var key = props[index];\n    object[key] = source[key];\n  }\n  return object;\n}\n\nmodule.exports = baseCopy;\n\n},{}],57:[function(require,module,exports){\n/**\n * lodash 3.0.3 (Custom Build) <https://lodash.com/>\n * Build: `lodash modern modularize exports=\"npm\" -o ./`\n * Copyright 2012-2015 The Dojo Foundation <http://dojofoundation.org/>\n * Based on Underscore.js 1.8.3 <http://underscorejs.org/LICENSE>\n * Copyright 2009-2015 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors\n * Available under MIT license <https://lodash.com/license>\n */\n\n/**\n * The base implementation of `_.create` without support for assigning\n * properties to the created object.\n *\n * @private\n * @param {Object} prototype The object to inherit from.\n * @returns {Object} Returns the new object.\n */\nvar baseCreate = (function() {\n  function object() {}\n  return function(prototype) {\n    if (isObject(prototype)) {\n      object.prototype = prototype;\n      var result = new object;\n      object.prototype = undefined;\n    }\n    return result || {};\n  };\n}());\n\n/**\n * Checks if `value` is the [language type](https://es5.github.io/#x8) of `Object`.\n * (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)\n *\n * @static\n * @memberOf _\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is an object, else `false`.\n * @example\n *\n * _.isObject({});\n * // => true\n *\n * _.isObject([1, 2, 3]);\n * // => true\n *\n * _.isObject(1);\n * // => false\n */\nfunction isObject(value) {\n  // Avoid a V8 JIT bug in Chrome 19-20.\n  // See https://code.google.com/p/v8/issues/detail?id=2291 for more details.\n  var type = typeof value;\n  return !!value && (type == 'object' || type == 'function');\n}\n\nmodule.exports = baseCreate;\n\n},{}],58:[function(require,module,exports){\n/**\n * lodash 3.9.1 (Custom Build) <https://lodash.com/>\n * Build: `lodash modern modularize exports=\"npm\" -o ./`\n * Copyright 2012-2015 The Dojo Foundation <http://dojofoundation.org/>\n * Based on Underscore.js 1.8.3 <http://underscorejs.org/LICENSE>\n * Copyright 2009-2015 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors\n * Available under MIT license <https://lodash.com/license>\n */\n\n/** `Object#toString` result references. */\nvar funcTag = '[object Function]';\n\n/** Used to detect host constructors (Safari > 5). */\nvar reIsHostCtor = /^\\[object .+?Constructor\\]$/;\n\n/**\n * Checks if `value` is object-like.\n *\n * @private\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is object-like, else `false`.\n */\nfunction isObjectLike(value) {\n  return !!value && typeof value == 'object';\n}\n\n/** Used for native method references. */\nvar objectProto = Object.prototype;\n\n/** Used to resolve the decompiled source of functions. */\nvar fnToString = Function.prototype.toString;\n\n/** Used to check objects for own properties. */\nvar hasOwnProperty = objectProto.hasOwnProperty;\n\n/**\n * Used to resolve the [`toStringTag`](http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring)\n * of values.\n */\nvar objToString = objectProto.toString;\n\n/** Used to detect if a method is native. */\nvar reIsNative = RegExp('^' +\n  fnToString.call(hasOwnProperty).replace(/[\\\\^$.*+?()[\\]{}|]/g, '\\\\$&')\n  .replace(/hasOwnProperty|(function).*?(?=\\\\\\()| for .+?(?=\\\\\\])/g, '$1.*?') + '$'\n);\n\n/**\n * Gets the native function at `key` of `object`.\n *\n * @private\n * @param {Object} object The object to query.\n * @param {string} key The key of the method to get.\n * @returns {*} Returns the function if it's native, else `undefined`.\n */\nfunction getNative(object, key) {\n  var value = object == null ? undefined : object[key];\n  return isNative(value) ? value : undefined;\n}\n\n/**\n * Checks if `value` is classified as a `Function` object.\n *\n * @static\n * @memberOf _\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`.\n * @example\n *\n * _.isFunction(_);\n * // => true\n *\n * _.isFunction(/abc/);\n * // => false\n */\nfunction isFunction(value) {\n  // The use of `Object#toString` avoids issues with the `typeof` operator\n  // in older versions of Chrome and Safari which return 'function' for regexes\n  // and Safari 8 equivalents which return 'object' for typed array constructors.\n  return isObject(value) && objToString.call(value) == funcTag;\n}\n\n/**\n * Checks if `value` is the [language type](https://es5.github.io/#x8) of `Object`.\n * (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)\n *\n * @static\n * @memberOf _\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is an object, else `false`.\n * @example\n *\n * _.isObject({});\n * // => true\n *\n * _.isObject([1, 2, 3]);\n * // => true\n *\n * _.isObject(1);\n * // => false\n */\nfunction isObject(value) {\n  // Avoid a V8 JIT bug in Chrome 19-20.\n  // See https://code.google.com/p/v8/issues/detail?id=2291 for more details.\n  var type = typeof value;\n  return !!value && (type == 'object' || type == 'function');\n}\n\n/**\n * Checks if `value` is a native function.\n *\n * @static\n * @memberOf _\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a native function, else `false`.\n * @example\n *\n * _.isNative(Array.prototype.push);\n * // => true\n *\n * _.isNative(_);\n * // => false\n */\nfunction isNative(value) {\n  if (value == null) {\n    return false;\n  }\n  if (isFunction(value)) {\n    return reIsNative.test(fnToString.call(value));\n  }\n  return isObjectLike(value) && reIsHostCtor.test(value);\n}\n\nmodule.exports = getNative;\n\n},{}],59:[function(require,module,exports){\n/**\n * lodash 3.0.9 (Custom Build) <https://lodash.com/>\n * Build: `lodash modern modularize exports=\"npm\" -o ./`\n * Copyright 2012-2015 The Dojo Foundation <http://dojofoundation.org/>\n * Based on Underscore.js 1.8.3 <http://underscorejs.org/LICENSE>\n * Copyright 2009-2015 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors\n * Available under MIT license <https://lodash.com/license>\n */\n\n/** Used to detect unsigned integer values. */\nvar reIsUint = /^\\d+$/;\n\n/**\n * Used as the [maximum length](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-number.max_safe_integer)\n * of an array-like value.\n */\nvar MAX_SAFE_INTEGER = 9007199254740991;\n\n/**\n * The base implementation of `_.property` without support for deep paths.\n *\n * @private\n * @param {string} key The key of the property to get.\n * @returns {Function} Returns the new function.\n */\nfunction baseProperty(key) {\n  return function(object) {\n    return object == null ? undefined : object[key];\n  };\n}\n\n/**\n * Gets the \"length\" property value of `object`.\n *\n * **Note:** This function is used to avoid a [JIT bug](https://bugs.webkit.org/show_bug.cgi?id=142792)\n * that affects Safari on at least iOS 8.1-8.3 ARM64.\n *\n * @private\n * @param {Object} object The object to query.\n * @returns {*} Returns the \"length\" value.\n */\nvar getLength = baseProperty('length');\n\n/**\n * Checks if `value` is array-like.\n *\n * @private\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is array-like, else `false`.\n */\nfunction isArrayLike(value) {\n  return value != null && isLength(getLength(value));\n}\n\n/**\n * Checks if `value` is a valid array-like index.\n *\n * @private\n * @param {*} value The value to check.\n * @param {number} [length=MAX_SAFE_INTEGER] The upper bounds of a valid index.\n * @returns {boolean} Returns `true` if `value` is a valid index, else `false`.\n */\nfunction isIndex(value, length) {\n  value = (typeof value == 'number' || reIsUint.test(value)) ? +value : -1;\n  length = length == null ? MAX_SAFE_INTEGER : length;\n  return value > -1 && value % 1 == 0 && value < length;\n}\n\n/**\n * Checks if the provided arguments are from an iteratee call.\n *\n * @private\n * @param {*} value The potential iteratee value argument.\n * @param {*} index The potential iteratee index or key argument.\n * @param {*} object The potential iteratee object argument.\n * @returns {boolean} Returns `true` if the arguments are from an iteratee call, else `false`.\n */\nfunction isIterateeCall(value, index, object) {\n  if (!isObject(object)) {\n    return false;\n  }\n  var type = typeof index;\n  if (type == 'number'\n      ? (isArrayLike(object) && isIndex(index, object.length))\n      : (type == 'string' && index in object)) {\n    var other = object[index];\n    return value === value ? (value === other) : (other !== other);\n  }\n  return false;\n}\n\n/**\n * Checks if `value` is a valid array-like length.\n *\n * **Note:** This function is based on [`ToLength`](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-tolength).\n *\n * @private\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a valid length, else `false`.\n */\nfunction isLength(value) {\n  return typeof value == 'number' && value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER;\n}\n\n/**\n * Checks if `value` is the [language type](https://es5.github.io/#x8) of `Object`.\n * (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)\n *\n * @static\n * @memberOf _\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is an object, else `false`.\n * @example\n *\n * _.isObject({});\n * // => true\n *\n * _.isObject([1, 2, 3]);\n * // => true\n *\n * _.isObject(1);\n * // => false\n */\nfunction isObject(value) {\n  // Avoid a V8 JIT bug in Chrome 19-20.\n  // See https://code.google.com/p/v8/issues/detail?id=2291 for more details.\n  var type = typeof value;\n  return !!value && (type == 'object' || type == 'function');\n}\n\nmodule.exports = isIterateeCall;\n\n},{}],60:[function(require,module,exports){\n/**\n * lodash 3.1.1 (Custom Build) <https://lodash.com/>\n * Build: `lodash modern modularize exports=\"npm\" -o ./`\n * Copyright 2012-2015 The Dojo Foundation <http://dojofoundation.org/>\n * Based on Underscore.js 1.8.3 <http://underscorejs.org/LICENSE>\n * Copyright 2009-2015 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors\n * Available under MIT license <https://lodash.com/license>\n */\nvar baseAssign = require('lodash._baseassign'),\n    baseCreate = require('lodash._basecreate'),\n    isIterateeCall = require('lodash._isiterateecall');\n\n/**\n * Creates an object that inherits from the given `prototype` object. If a\n * `properties` object is provided its own enumerable properties are assigned\n * to the created object.\n *\n * @static\n * @memberOf _\n * @category Object\n * @param {Object} prototype The object to inherit from.\n * @param {Object} [properties] The properties to assign to the object.\n * @param- {Object} [guard] Enables use as a callback for functions like `_.map`.\n * @returns {Object} Returns the new object.\n * @example\n *\n * function Shape() {\n *   this.x = 0;\n *   this.y = 0;\n * }\n *\n * function Circle() {\n *   Shape.call(this);\n * }\n *\n * Circle.prototype = _.create(Shape.prototype, {\n *   'constructor': Circle\n * });\n *\n * var circle = new Circle;\n * circle instanceof Circle;\n * // => true\n *\n * circle instanceof Shape;\n * // => true\n */\nfunction create(prototype, properties, guard) {\n  var result = baseCreate(prototype);\n  if (guard && isIterateeCall(prototype, properties, guard)) {\n    properties = undefined;\n  }\n  return properties ? baseAssign(result, properties) : result;\n}\n\nmodule.exports = create;\n\n},{\"lodash._baseassign\":55,\"lodash._basecreate\":57,\"lodash._isiterateecall\":59}],61:[function(require,module,exports){\n/**\n * lodash (Custom Build) <https://lodash.com/>\n * Build: `lodash modularize exports=\"npm\" -o ./`\n * Copyright jQuery Foundation and other contributors <https://jquery.org/>\n * Released under MIT license <https://lodash.com/license>\n * Based on Underscore.js 1.8.3 <http://underscorejs.org/LICENSE>\n * Copyright Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors\n */\n\n/** Used as references for various `Number` constants. */\nvar MAX_SAFE_INTEGER = 9007199254740991;\n\n/** `Object#toString` result references. */\nvar argsTag = '[object Arguments]',\n    funcTag = '[object Function]',\n    genTag = '[object GeneratorFunction]';\n\n/** Used for built-in method references. */\nvar objectProto = Object.prototype;\n\n/** Used to check objects for own properties. */\nvar hasOwnProperty = objectProto.hasOwnProperty;\n\n/**\n * Used to resolve the\n * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring)\n * of values.\n */\nvar objectToString = objectProto.toString;\n\n/** Built-in value references. */\nvar propertyIsEnumerable = objectProto.propertyIsEnumerable;\n\n/**\n * Checks if `value` is likely an `arguments` object.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is an `arguments` object,\n *  else `false`.\n * @example\n *\n * _.isArguments(function() { return arguments; }());\n * // => true\n *\n * _.isArguments([1, 2, 3]);\n * // => false\n */\nfunction isArguments(value) {\n  // Safari 8.1 makes `arguments.callee` enumerable in strict mode.\n  return isArrayLikeObject(value) && hasOwnProperty.call(value, 'callee') &&\n    (!propertyIsEnumerable.call(value, 'callee') || objectToString.call(value) == argsTag);\n}\n\n/**\n * Checks if `value` is array-like. A value is considered array-like if it's\n * not a function and has a `value.length` that's an integer greater than or\n * equal to `0` and less than or equal to `Number.MAX_SAFE_INTEGER`.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is array-like, else `false`.\n * @example\n *\n * _.isArrayLike([1, 2, 3]);\n * // => true\n *\n * _.isArrayLike(document.body.children);\n * // => true\n *\n * _.isArrayLike('abc');\n * // => true\n *\n * _.isArrayLike(_.noop);\n * // => false\n */\nfunction isArrayLike(value) {\n  return value != null && isLength(value.length) && !isFunction(value);\n}\n\n/**\n * This method is like `_.isArrayLike` except that it also checks if `value`\n * is an object.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is an array-like object,\n *  else `false`.\n * @example\n *\n * _.isArrayLikeObject([1, 2, 3]);\n * // => true\n *\n * _.isArrayLikeObject(document.body.children);\n * // => true\n *\n * _.isArrayLikeObject('abc');\n * // => false\n *\n * _.isArrayLikeObject(_.noop);\n * // => false\n */\nfunction isArrayLikeObject(value) {\n  return isObjectLike(value) && isArrayLike(value);\n}\n\n/**\n * Checks if `value` is classified as a `Function` object.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a function, else `false`.\n * @example\n *\n * _.isFunction(_);\n * // => true\n *\n * _.isFunction(/abc/);\n * // => false\n */\nfunction isFunction(value) {\n  // The use of `Object#toString` avoids issues with the `typeof` operator\n  // in Safari 8-9 which returns 'object' for typed array and other constructors.\n  var tag = isObject(value) ? objectToString.call(value) : '';\n  return tag == funcTag || tag == genTag;\n}\n\n/**\n * Checks if `value` is a valid array-like length.\n *\n * **Note:** This method is loosely based on\n * [`ToLength`](http://ecma-international.org/ecma-262/7.0/#sec-tolength).\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a valid length, else `false`.\n * @example\n *\n * _.isLength(3);\n * // => true\n *\n * _.isLength(Number.MIN_VALUE);\n * // => false\n *\n * _.isLength(Infinity);\n * // => false\n *\n * _.isLength('3');\n * // => false\n */\nfunction isLength(value) {\n  return typeof value == 'number' &&\n    value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER;\n}\n\n/**\n * Checks if `value` is the\n * [language type](http://www.ecma-international.org/ecma-262/7.0/#sec-ecmascript-language-types)\n * of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is an object, else `false`.\n * @example\n *\n * _.isObject({});\n * // => true\n *\n * _.isObject([1, 2, 3]);\n * // => true\n *\n * _.isObject(_.noop);\n * // => true\n *\n * _.isObject(null);\n * // => false\n */\nfunction isObject(value) {\n  var type = typeof value;\n  return !!value && (type == 'object' || type == 'function');\n}\n\n/**\n * Checks if `value` is object-like. A value is object-like if it's not `null`\n * and has a `typeof` result of \"object\".\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is object-like, else `false`.\n * @example\n *\n * _.isObjectLike({});\n * // => true\n *\n * _.isObjectLike([1, 2, 3]);\n * // => true\n *\n * _.isObjectLike(_.noop);\n * // => false\n *\n * _.isObjectLike(null);\n * // => false\n */\nfunction isObjectLike(value) {\n  return !!value && typeof value == 'object';\n}\n\nmodule.exports = isArguments;\n\n},{}],62:[function(require,module,exports){\n/**\n * lodash 3.0.4 (Custom Build) <https://lodash.com/>\n * Build: `lodash modern modularize exports=\"npm\" -o ./`\n * Copyright 2012-2015 The Dojo Foundation <http://dojofoundation.org/>\n * Based on Underscore.js 1.8.3 <http://underscorejs.org/LICENSE>\n * Copyright 2009-2015 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors\n * Available under MIT license <https://lodash.com/license>\n */\n\n/** `Object#toString` result references. */\nvar arrayTag = '[object Array]',\n    funcTag = '[object Function]';\n\n/** Used to detect host constructors (Safari > 5). */\nvar reIsHostCtor = /^\\[object .+?Constructor\\]$/;\n\n/**\n * Checks if `value` is object-like.\n *\n * @private\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is object-like, else `false`.\n */\nfunction isObjectLike(value) {\n  return !!value && typeof value == 'object';\n}\n\n/** Used for native method references. */\nvar objectProto = Object.prototype;\n\n/** Used to resolve the decompiled source of functions. */\nvar fnToString = Function.prototype.toString;\n\n/** Used to check objects for own properties. */\nvar hasOwnProperty = objectProto.hasOwnProperty;\n\n/**\n * Used to resolve the [`toStringTag`](http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring)\n * of values.\n */\nvar objToString = objectProto.toString;\n\n/** Used to detect if a method is native. */\nvar reIsNative = RegExp('^' +\n  fnToString.call(hasOwnProperty).replace(/[\\\\^$.*+?()[\\]{}|]/g, '\\\\$&')\n  .replace(/hasOwnProperty|(function).*?(?=\\\\\\()| for .+?(?=\\\\\\])/g, '$1.*?') + '$'\n);\n\n/* Native method references for those with the same name as other `lodash` methods. */\nvar nativeIsArray = getNative(Array, 'isArray');\n\n/**\n * Used as the [maximum length](http://ecma-international.org/ecma-262/6.0/#sec-number.max_safe_integer)\n * of an array-like value.\n */\nvar MAX_SAFE_INTEGER = 9007199254740991;\n\n/**\n * Gets the native function at `key` of `object`.\n *\n * @private\n * @param {Object} object The object to query.\n * @param {string} key The key of the method to get.\n * @returns {*} Returns the function if it's native, else `undefined`.\n */\nfunction getNative(object, key) {\n  var value = object == null ? undefined : object[key];\n  return isNative(value) ? value : undefined;\n}\n\n/**\n * Checks if `value` is a valid array-like length.\n *\n * **Note:** This function is based on [`ToLength`](http://ecma-international.org/ecma-262/6.0/#sec-tolength).\n *\n * @private\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a valid length, else `false`.\n */\nfunction isLength(value) {\n  return typeof value == 'number' && value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER;\n}\n\n/**\n * Checks if `value` is classified as an `Array` object.\n *\n * @static\n * @memberOf _\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`.\n * @example\n *\n * _.isArray([1, 2, 3]);\n * // => true\n *\n * _.isArray(function() { return arguments; }());\n * // => false\n */\nvar isArray = nativeIsArray || function(value) {\n  return isObjectLike(value) && isLength(value.length) && objToString.call(value) == arrayTag;\n};\n\n/**\n * Checks if `value` is classified as a `Function` object.\n *\n * @static\n * @memberOf _\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`.\n * @example\n *\n * _.isFunction(_);\n * // => true\n *\n * _.isFunction(/abc/);\n * // => false\n */\nfunction isFunction(value) {\n  // The use of `Object#toString` avoids issues with the `typeof` operator\n  // in older versions of Chrome and Safari which return 'function' for regexes\n  // and Safari 8 equivalents which return 'object' for typed array constructors.\n  return isObject(value) && objToString.call(value) == funcTag;\n}\n\n/**\n * Checks if `value` is the [language type](https://es5.github.io/#x8) of `Object`.\n * (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)\n *\n * @static\n * @memberOf _\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is an object, else `false`.\n * @example\n *\n * _.isObject({});\n * // => true\n *\n * _.isObject([1, 2, 3]);\n * // => true\n *\n * _.isObject(1);\n * // => false\n */\nfunction isObject(value) {\n  // Avoid a V8 JIT bug in Chrome 19-20.\n  // See https://code.google.com/p/v8/issues/detail?id=2291 for more details.\n  var type = typeof value;\n  return !!value && (type == 'object' || type == 'function');\n}\n\n/**\n * Checks if `value` is a native function.\n *\n * @static\n * @memberOf _\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a native function, else `false`.\n * @example\n *\n * _.isNative(Array.prototype.push);\n * // => true\n *\n * _.isNative(_);\n * // => false\n */\nfunction isNative(value) {\n  if (value == null) {\n    return false;\n  }\n  if (isFunction(value)) {\n    return reIsNative.test(fnToString.call(value));\n  }\n  return isObjectLike(value) && reIsHostCtor.test(value);\n}\n\nmodule.exports = isArray;\n\n},{}],63:[function(require,module,exports){\n/**\n * lodash 3.1.2 (Custom Build) <https://lodash.com/>\n * Build: `lodash modern modularize exports=\"npm\" -o ./`\n * Copyright 2012-2015 The Dojo Foundation <http://dojofoundation.org/>\n * Based on Underscore.js 1.8.3 <http://underscorejs.org/LICENSE>\n * Copyright 2009-2015 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors\n * Available under MIT license <https://lodash.com/license>\n */\nvar getNative = require('lodash._getnative'),\n    isArguments = require('lodash.isarguments'),\n    isArray = require('lodash.isarray');\n\n/** Used to detect unsigned integer values. */\nvar reIsUint = /^\\d+$/;\n\n/** Used for native method references. */\nvar objectProto = Object.prototype;\n\n/** Used to check objects for own properties. */\nvar hasOwnProperty = objectProto.hasOwnProperty;\n\n/* Native method references for those with the same name as other `lodash` methods. */\nvar nativeKeys = getNative(Object, 'keys');\n\n/**\n * Used as the [maximum length](http://ecma-international.org/ecma-262/6.0/#sec-number.max_safe_integer)\n * of an array-like value.\n */\nvar MAX_SAFE_INTEGER = 9007199254740991;\n\n/**\n * The base implementation of `_.property` without support for deep paths.\n *\n * @private\n * @param {string} key The key of the property to get.\n * @returns {Function} Returns the new function.\n */\nfunction baseProperty(key) {\n  return function(object) {\n    return object == null ? undefined : object[key];\n  };\n}\n\n/**\n * Gets the \"length\" property value of `object`.\n *\n * **Note:** This function is used to avoid a [JIT bug](https://bugs.webkit.org/show_bug.cgi?id=142792)\n * that affects Safari on at least iOS 8.1-8.3 ARM64.\n *\n * @private\n * @param {Object} object The object to query.\n * @returns {*} Returns the \"length\" value.\n */\nvar getLength = baseProperty('length');\n\n/**\n * Checks if `value` is array-like.\n *\n * @private\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is array-like, else `false`.\n */\nfunction isArrayLike(value) {\n  return value != null && isLength(getLength(value));\n}\n\n/**\n * Checks if `value` is a valid array-like index.\n *\n * @private\n * @param {*} value The value to check.\n * @param {number} [length=MAX_SAFE_INTEGER] The upper bounds of a valid index.\n * @returns {boolean} Returns `true` if `value` is a valid index, else `false`.\n */\nfunction isIndex(value, length) {\n  value = (typeof value == 'number' || reIsUint.test(value)) ? +value : -1;\n  length = length == null ? MAX_SAFE_INTEGER : length;\n  return value > -1 && value % 1 == 0 && value < length;\n}\n\n/**\n * Checks if `value` is a valid array-like length.\n *\n * **Note:** This function is based on [`ToLength`](http://ecma-international.org/ecma-262/6.0/#sec-tolength).\n *\n * @private\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a valid length, else `false`.\n */\nfunction isLength(value) {\n  return typeof value == 'number' && value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER;\n}\n\n/**\n * A fallback implementation of `Object.keys` which creates an array of the\n * own enumerable property names of `object`.\n *\n * @private\n * @param {Object} object The object to query.\n * @returns {Array} Returns the array of property names.\n */\nfunction shimKeys(object) {\n  var props = keysIn(object),\n      propsLength = props.length,\n      length = propsLength && object.length;\n\n  var allowIndexes = !!length && isLength(length) &&\n    (isArray(object) || isArguments(object));\n\n  var index = -1,\n      result = [];\n\n  while (++index < propsLength) {\n    var key = props[index];\n    if ((allowIndexes && isIndex(key, length)) || hasOwnProperty.call(object, key)) {\n      result.push(key);\n    }\n  }\n  return result;\n}\n\n/**\n * Checks if `value` is the [language type](https://es5.github.io/#x8) of `Object`.\n * (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)\n *\n * @static\n * @memberOf _\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is an object, else `false`.\n * @example\n *\n * _.isObject({});\n * // => true\n *\n * _.isObject([1, 2, 3]);\n * // => true\n *\n * _.isObject(1);\n * // => false\n */\nfunction isObject(value) {\n  // Avoid a V8 JIT bug in Chrome 19-20.\n  // See https://code.google.com/p/v8/issues/detail?id=2291 for more details.\n  var type = typeof value;\n  return !!value && (type == 'object' || type == 'function');\n}\n\n/**\n * Creates an array of the own enumerable property names of `object`.\n *\n * **Note:** Non-object values are coerced to objects. See the\n * [ES spec](http://ecma-international.org/ecma-262/6.0/#sec-object.keys)\n * for more details.\n *\n * @static\n * @memberOf _\n * @category Object\n * @param {Object} object The object to query.\n * @returns {Array} Returns the array of property names.\n * @example\n *\n * function Foo() {\n *   this.a = 1;\n *   this.b = 2;\n * }\n *\n * Foo.prototype.c = 3;\n *\n * _.keys(new Foo);\n * // => ['a', 'b'] (iteration order is not guaranteed)\n *\n * _.keys('hi');\n * // => ['0', '1']\n */\nvar keys = !nativeKeys ? shimKeys : function(object) {\n  var Ctor = object == null ? undefined : object.constructor;\n  if ((typeof Ctor == 'function' && Ctor.prototype === object) ||\n      (typeof object != 'function' && isArrayLike(object))) {\n    return shimKeys(object);\n  }\n  return isObject(object) ? nativeKeys(object) : [];\n};\n\n/**\n * Creates an array of the own and inherited enumerable property names of `object`.\n *\n * **Note:** Non-object values are coerced to objects.\n *\n * @static\n * @memberOf _\n * @category Object\n * @param {Object} object The object to query.\n * @returns {Array} Returns the array of property names.\n * @example\n *\n * function Foo() {\n *   this.a = 1;\n *   this.b = 2;\n * }\n *\n * Foo.prototype.c = 3;\n *\n * _.keysIn(new Foo);\n * // => ['a', 'b', 'c'] (iteration order is not guaranteed)\n */\nfunction keysIn(object) {\n  if (object == null) {\n    return [];\n  }\n  if (!isObject(object)) {\n    object = Object(object);\n  }\n  var length = object.length;\n  length = (length && isLength(length) &&\n    (isArray(object) || isArguments(object)) && length) || 0;\n\n  var Ctor = object.constructor,\n      index = -1,\n      isProto = typeof Ctor == 'function' && Ctor.prototype === object,\n      result = Array(length),\n      skipIndexes = length > 0;\n\n  while (++index < length) {\n    result[index] = (index + '');\n  }\n  for (var key in object) {\n    if (!(skipIndexes && isIndex(key, length)) &&\n        !(key == 'constructor' && (isProto || !hasOwnProperty.call(object, key)))) {\n      result.push(key);\n    }\n  }\n  return result;\n}\n\nmodule.exports = keys;\n\n},{\"lodash._getnative\":58,\"lodash.isarguments\":61,\"lodash.isarray\":62}],64:[function(require,module,exports){\n(function (process){\nvar path = require('path');\nvar fs = require('fs');\nvar _0777 = parseInt('0777', 8);\n\nmodule.exports = mkdirP.mkdirp = mkdirP.mkdirP = mkdirP;\n\nfunction mkdirP (p, opts, f, made) {\n    if (typeof opts === 'function') {\n        f = opts;\n        opts = {};\n    }\n    else if (!opts || typeof opts !== 'object') {\n        opts = { mode: opts };\n    }\n\n    var mode = opts.mode;\n    var xfs = opts.fs || fs;\n\n    if (mode === undefined) {\n        mode = _0777 & (~process.umask());\n    }\n    if (!made) made = null;\n\n    var cb = f || function () {};\n    p = path.resolve(p);\n\n    xfs.mkdir(p, mode, function (er) {\n        if (!er) {\n            made = made || p;\n            return cb(null, made);\n        }\n        switch (er.code) {\n            case 'ENOENT':\n                mkdirP(path.dirname(p), opts, function (er, made) {\n                    if (er) cb(er, made);\n                    else mkdirP(p, opts, cb, made);\n                });\n                break;\n\n            // In the case of any other error, just see if there's a dir\n            // there already.  If so, then hooray!  If not, then something\n            // is borked.\n            default:\n                xfs.stat(p, function (er2, stat) {\n                    // if the stat fails, then that's super weird.\n                    // let the original error be the failure reason.\n                    if (er2 || !stat.isDirectory()) cb(er, made)\n                    else cb(null, made);\n                });\n                break;\n        }\n    });\n}\n\nmkdirP.sync = function sync (p, opts, made) {\n    if (!opts || typeof opts !== 'object') {\n        opts = { mode: opts };\n    }\n\n    var mode = opts.mode;\n    var xfs = opts.fs || fs;\n\n    if (mode === undefined) {\n        mode = _0777 & (~process.umask());\n    }\n    if (!made) made = null;\n\n    p = path.resolve(p);\n\n    try {\n        xfs.mkdirSync(p, mode);\n        made = made || p;\n    }\n    catch (err0) {\n        switch (err0.code) {\n            case 'ENOENT' :\n                made = sync(path.dirname(p), opts, made);\n                sync(p, opts, made);\n                break;\n\n            // In the case of any other error, just see if there's a dir\n            // there already.  If so, then hooray!  If not, then something\n            // is borked.\n            default:\n                var stat;\n                try {\n                    stat = xfs.statSync(p);\n                }\n                catch (err1) {\n                    throw err0;\n                }\n                if (!stat.isDirectory()) throw err0;\n                break;\n        }\n    }\n\n    return made;\n};\n\n}).call(this,require('_process'))\n},{\"_process\":67,\"fs\":42,\"path\":42}],65:[function(require,module,exports){\nexports.endianness = function () { return 'LE' };\n\nexports.hostname = function () {\n    if (typeof location !== 'undefined') {\n        return location.hostname\n    }\n    else return '';\n};\n\nexports.loadavg = function () { return [] };\n\nexports.uptime = function () { return 0 };\n\nexports.freemem = function () {\n    return Number.MAX_VALUE;\n};\n\nexports.totalmem = function () {\n    return Number.MAX_VALUE;\n};\n\nexports.cpus = function () { return [] };\n\nexports.type = function () { return 'Browser' };\n\nexports.release = function () {\n    if (typeof navigator !== 'undefined') {\n        return navigator.appVersion;\n    }\n    return '';\n};\n\nexports.networkInterfaces\n= exports.getNetworkInterfaces\n= function () { return {} };\n\nexports.arch = function () { return 'javascript' };\n\nexports.platform = function () { return 'browser' };\n\nexports.tmpdir = exports.tmpDir = function () {\n    return '/tmp';\n};\n\nexports.EOL = '\\n';\n\n},{}],66:[function(require,module,exports){\n(function (process){\n'use strict';\n\nif (!process.version ||\n    process.version.indexOf('v0.') === 0 ||\n    process.version.indexOf('v1.') === 0 && process.version.indexOf('v1.8.') !== 0) {\n  module.exports = nextTick;\n} else {\n  module.exports = process.nextTick;\n}\n\nfunction nextTick(fn, arg1, arg2, arg3) {\n  if (typeof fn !== 'function') {\n    throw new TypeError('\"callback\" argument must be a function');\n  }\n  var len = arguments.length;\n  var args, i;\n  switch (len) {\n  case 0:\n  case 1:\n    return process.nextTick(fn);\n  case 2:\n    return process.nextTick(function afterTickOne() {\n      fn.call(null, arg1);\n    });\n  case 3:\n    return process.nextTick(function afterTickTwo() {\n      fn.call(null, arg1, arg2);\n    });\n  case 4:\n    return process.nextTick(function afterTickThree() {\n      fn.call(null, arg1, arg2, arg3);\n    });\n  default:\n    args = new Array(len - 1);\n    i = 0;\n    while (i < args.length) {\n      args[i++] = arguments[i];\n    }\n    return process.nextTick(function afterTick() {\n      fn.apply(null, args);\n    });\n  }\n}\n\n}).call(this,require('_process'))\n},{\"_process\":67}],67:[function(require,module,exports){\n// shim for using process in browser\nvar process = module.exports = {};\n\n// cached from whatever global is present so that test runners that stub it\n// don't break things.  But we need to wrap it in a try catch in case it is\n// wrapped in strict mode code which doesn't define any globals.  It's inside a\n// function because try/catches deoptimize in certain engines.\n\nvar cachedSetTimeout;\nvar cachedClearTimeout;\n\nfunction defaultSetTimout() {\n    throw new Error('setTimeout has not been defined');\n}\nfunction defaultClearTimeout () {\n    throw new Error('clearTimeout has not been defined');\n}\n(function () {\n    try {\n        if (typeof setTimeout === 'function') {\n            cachedSetTimeout = setTimeout;\n        } else {\n            cachedSetTimeout = defaultSetTimout;\n        }\n    } catch (e) {\n        cachedSetTimeout = defaultSetTimout;\n    }\n    try {\n        if (typeof clearTimeout === 'function') {\n            cachedClearTimeout = clearTimeout;\n        } else {\n            cachedClearTimeout = defaultClearTimeout;\n        }\n    } catch (e) {\n        cachedClearTimeout = defaultClearTimeout;\n    }\n} ())\nfunction runTimeout(fun) {\n    if (cachedSetTimeout === setTimeout) {\n        //normal enviroments in sane situations\n        return setTimeout(fun, 0);\n    }\n    // if setTimeout wasn't available but was latter defined\n    if ((cachedSetTimeout === defaultSetTimout || !cachedSetTimeout) && setTimeout) {\n        cachedSetTimeout = setTimeout;\n        return setTimeout(fun, 0);\n    }\n    try {\n        // when when somebody has screwed with setTimeout but no I.E. maddness\n        return cachedSetTimeout(fun, 0);\n    } catch(e){\n        try {\n            // When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally\n            return cachedSetTimeout.call(null, fun, 0);\n        } catch(e){\n            // same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error\n            return cachedSetTimeout.call(this, fun, 0);\n        }\n    }\n\n\n}\nfunction runClearTimeout(marker) {\n    if (cachedClearTimeout === clearTimeout) {\n        //normal enviroments in sane situations\n        return clearTimeout(marker);\n    }\n    // if clearTimeout wasn't available but was latter defined\n    if ((cachedClearTimeout === defaultClearTimeout || !cachedClearTimeout) && clearTimeout) {\n        cachedClearTimeout = clearTimeout;\n        return clearTimeout(marker);\n    }\n    try {\n        // when when somebody has screwed with setTimeout but no I.E. maddness\n        return cachedClearTimeout(marker);\n    } catch (e){\n        try {\n            // When we are in I.E. but the script has been evaled so I.E. doesn't  trust the global object when called normally\n            return cachedClearTimeout.call(null, marker);\n        } catch (e){\n            // same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error.\n            // Some versions of I.E. have different rules for clearTimeout vs setTimeout\n            return cachedClearTimeout.call(this, marker);\n        }\n    }\n\n\n\n}\nvar queue = [];\nvar draining = false;\nvar currentQueue;\nvar queueIndex = -1;\n\nfunction cleanUpNextTick() {\n    if (!draining || !currentQueue) {\n        return;\n    }\n    draining = false;\n    if (currentQueue.length) {\n        queue = currentQueue.concat(queue);\n    } else {\n        queueIndex = -1;\n    }\n    if (queue.length) {\n        drainQueue();\n    }\n}\n\nfunction drainQueue() {\n    if (draining) {\n        return;\n    }\n    var timeout = runTimeout(cleanUpNextTick);\n    draining = true;\n\n    var len = queue.length;\n    while(len) {\n        currentQueue = queue;\n        queue = [];\n        while (++queueIndex < len) {\n            if (currentQueue) {\n                currentQueue[queueIndex].run();\n            }\n        }\n        queueIndex = -1;\n        len = queue.length;\n    }\n    currentQueue = null;\n    draining = false;\n    runClearTimeout(timeout);\n}\n\nprocess.nextTick = function (fun) {\n    var args = new Array(arguments.length - 1);\n    if (arguments.length > 1) {\n        for (var i = 1; i < arguments.length; i++) {\n            args[i - 1] = arguments[i];\n        }\n    }\n    queue.push(new Item(fun, args));\n    if (queue.length === 1 && !draining) {\n        runTimeout(drainQueue);\n    }\n};\n\n// v8 likes predictible objects\nfunction Item(fun, array) {\n    this.fun = fun;\n    this.array = array;\n}\nItem.prototype.run = function () {\n    this.fun.apply(null, this.array);\n};\nprocess.title = 'browser';\nprocess.browser = true;\nprocess.env = {};\nprocess.argv = [];\nprocess.version = ''; // empty string to avoid regexp issues\nprocess.versions = {};\n\nfunction noop() {}\n\nprocess.on = noop;\nprocess.addListener = noop;\nprocess.once = noop;\nprocess.off = noop;\nprocess.removeListener = noop;\nprocess.removeAllListeners = noop;\nprocess.emit = noop;\n\nprocess.binding = function (name) {\n    throw new Error('process.binding is not supported');\n};\n\nprocess.cwd = function () { return '/' };\nprocess.chdir = function (dir) {\n    throw new Error('process.chdir is not supported');\n};\nprocess.umask = function() { return 0; };\n\n},{}],68:[function(require,module,exports){\nmodule.exports = require(\"./lib/_stream_duplex.js\")\n\n},{\"./lib/_stream_duplex.js\":69}],69:[function(require,module,exports){\n// a duplex stream is just a stream that is both readable and writable.\n// Since JS doesn't have multiple prototypal inheritance, this class\n// prototypally inherits from Readable, and then parasitically from\n// Writable.\n\n'use strict';\n\n/*<replacement>*/\n\nvar objectKeys = Object.keys || function (obj) {\n  var keys = [];\n  for (var key in obj) {\n    keys.push(key);\n  }return keys;\n};\n/*</replacement>*/\n\nmodule.exports = Duplex;\n\n/*<replacement>*/\nvar processNextTick = require('process-nextick-args');\n/*</replacement>*/\n\n/*<replacement>*/\nvar util = require('core-util-is');\nutil.inherits = require('inherits');\n/*</replacement>*/\n\nvar Readable = require('./_stream_readable');\nvar Writable = require('./_stream_writable');\n\nutil.inherits(Duplex, Readable);\n\nvar keys = objectKeys(Writable.prototype);\nfor (var v = 0; v < keys.length; v++) {\n  var method = keys[v];\n  if (!Duplex.prototype[method]) Duplex.prototype[method] = Writable.prototype[method];\n}\n\nfunction Duplex(options) {\n  if (!(this instanceof Duplex)) return new Duplex(options);\n\n  Readable.call(this, options);\n  Writable.call(this, options);\n\n  if (options && options.readable === false) this.readable = false;\n\n  if (options && options.writable === false) this.writable = false;\n\n  this.allowHalfOpen = true;\n  if (options && options.allowHalfOpen === false) this.allowHalfOpen = false;\n\n  this.once('end', onend);\n}\n\n// the no-half-open enforcer\nfunction onend() {\n  // if we allow half-open state, or if the writable side ended,\n  // then we're ok.\n  if (this.allowHalfOpen || this._writableState.ended) return;\n\n  // no more data can be written.\n  // But allow more writes to happen in this tick.\n  processNextTick(onEndNT, this);\n}\n\nfunction onEndNT(self) {\n  self.end();\n}\n\nfunction forEach(xs, f) {\n  for (var i = 0, l = xs.length; i < l; i++) {\n    f(xs[i], i);\n  }\n}\n},{\"./_stream_readable\":71,\"./_stream_writable\":73,\"core-util-is\":45,\"inherits\":51,\"process-nextick-args\":66}],70:[function(require,module,exports){\n// a passthrough stream.\n// basically just the most minimal sort of Transform stream.\n// Every written chunk gets output as-is.\n\n'use strict';\n\nmodule.exports = PassThrough;\n\nvar Transform = require('./_stream_transform');\n\n/*<replacement>*/\nvar util = require('core-util-is');\nutil.inherits = require('inherits');\n/*</replacement>*/\n\nutil.inherits(PassThrough, Transform);\n\nfunction PassThrough(options) {\n  if (!(this instanceof PassThrough)) return new PassThrough(options);\n\n  Transform.call(this, options);\n}\n\nPassThrough.prototype._transform = function (chunk, encoding, cb) {\n  cb(null, chunk);\n};\n},{\"./_stream_transform\":72,\"core-util-is\":45,\"inherits\":51}],71:[function(require,module,exports){\n(function (process){\n'use strict';\n\nmodule.exports = Readable;\n\n/*<replacement>*/\nvar processNextTick = require('process-nextick-args');\n/*</replacement>*/\n\n/*<replacement>*/\nvar isArray = require('isarray');\n/*</replacement>*/\n\nReadable.ReadableState = ReadableState;\n\n/*<replacement>*/\nvar EE = require('events').EventEmitter;\n\nvar EElistenerCount = function (emitter, type) {\n  return emitter.listeners(type).length;\n};\n/*</replacement>*/\n\n/*<replacement>*/\nvar Stream;\n(function () {\n  try {\n    Stream = require('st' + 'ream');\n  } catch (_) {} finally {\n    if (!Stream) Stream = require('events').EventEmitter;\n  }\n})();\n/*</replacement>*/\n\nvar Buffer = require('buffer').Buffer;\n/*<replacement>*/\nvar bufferShim = require('buffer-shims');\n/*</replacement>*/\n\n/*<replacement>*/\nvar util = require('core-util-is');\nutil.inherits = require('inherits');\n/*</replacement>*/\n\n/*<replacement>*/\nvar debugUtil = require('util');\nvar debug = void 0;\nif (debugUtil && debugUtil.debuglog) {\n  debug = debugUtil.debuglog('stream');\n} else {\n  debug = function () {};\n}\n/*</replacement>*/\n\nvar BufferList = require('./internal/streams/BufferList');\nvar StringDecoder;\n\nutil.inherits(Readable, Stream);\n\nfunction prependListener(emitter, event, fn) {\n  if (typeof emitter.prependListener === 'function') {\n    return emitter.prependListener(event, fn);\n  } else {\n    // This is a hack to make sure that our error handler is attached before any\n    // userland ones.  NEVER DO THIS. This is here only because this code needs\n    // to continue to work with older versions of Node.js that do not include\n    // the prependListener() method. The goal is to eventually remove this hack.\n    if (!emitter._events || !emitter._events[event]) emitter.on(event, fn);else if (isArray(emitter._events[event])) emitter._events[event].unshift(fn);else emitter._events[event] = [fn, emitter._events[event]];\n  }\n}\n\nvar Duplex;\nfunction ReadableState(options, stream) {\n  Duplex = Duplex || require('./_stream_duplex');\n\n  options = options || {};\n\n  // object stream flag. Used to make read(n) ignore n and to\n  // make all the buffer merging and length checks go away\n  this.objectMode = !!options.objectMode;\n\n  if (stream instanceof Duplex) this.objectMode = this.objectMode || !!options.readableObjectMode;\n\n  // the point at which it stops calling _read() to fill the buffer\n  // Note: 0 is a valid value, means \"don't call _read preemptively ever\"\n  var hwm = options.highWaterMark;\n  var defaultHwm = this.objectMode ? 16 : 16 * 1024;\n  this.highWaterMark = hwm || hwm === 0 ? hwm : defaultHwm;\n\n  // cast to ints.\n  this.highWaterMark = ~ ~this.highWaterMark;\n\n  // A linked list is used to store data chunks instead of an array because the\n  // linked list can remove elements from the beginning faster than\n  // array.shift()\n  this.buffer = new BufferList();\n  this.length = 0;\n  this.pipes = null;\n  this.pipesCount = 0;\n  this.flowing = null;\n  this.ended = false;\n  this.endEmitted = false;\n  this.reading = false;\n\n  // a flag to be able to tell if the onwrite cb is called immediately,\n  // or on a later tick.  We set this to true at first, because any\n  // actions that shouldn't happen until \"later\" should generally also\n  // not happen before the first write call.\n  this.sync = true;\n\n  // whenever we return null, then we set a flag to say\n  // that we're awaiting a 'readable' event emission.\n  this.needReadable = false;\n  this.emittedReadable = false;\n  this.readableListening = false;\n  this.resumeScheduled = false;\n\n  // Crypto is kind of old and crusty.  Historically, its default string\n  // encoding is 'binary' so we have to make this configurable.\n  // Everything else in the universe uses 'utf8', though.\n  this.defaultEncoding = options.defaultEncoding || 'utf8';\n\n  // when piping, we only care about 'readable' events that happen\n  // after read()ing all the bytes and not getting any pushback.\n  this.ranOut = false;\n\n  // the number of writers that are awaiting a drain event in .pipe()s\n  this.awaitDrain = 0;\n\n  // if true, a maybeReadMore has been scheduled\n  this.readingMore = false;\n\n  this.decoder = null;\n  this.encoding = null;\n  if (options.encoding) {\n    if (!StringDecoder) StringDecoder = require('string_decoder/').StringDecoder;\n    this.decoder = new StringDecoder(options.encoding);\n    this.encoding = options.encoding;\n  }\n}\n\nvar Duplex;\nfunction Readable(options) {\n  Duplex = Duplex || require('./_stream_duplex');\n\n  if (!(this instanceof Readable)) return new Readable(options);\n\n  this._readableState = new ReadableState(options, this);\n\n  // legacy\n  this.readable = true;\n\n  if (options && typeof options.read === 'function') this._read = options.read;\n\n  Stream.call(this);\n}\n\n// Manually shove something into the read() buffer.\n// This returns true if the highWaterMark has not been hit yet,\n// similar to how Writable.write() returns true if you should\n// write() some more.\nReadable.prototype.push = function (chunk, encoding) {\n  var state = this._readableState;\n\n  if (!state.objectMode && typeof chunk === 'string') {\n    encoding = encoding || state.defaultEncoding;\n    if (encoding !== state.encoding) {\n      chunk = bufferShim.from(chunk, encoding);\n      encoding = '';\n    }\n  }\n\n  return readableAddChunk(this, state, chunk, encoding, false);\n};\n\n// Unshift should *always* be something directly out of read()\nReadable.prototype.unshift = function (chunk) {\n  var state = this._readableState;\n  return readableAddChunk(this, state, chunk, '', true);\n};\n\nReadable.prototype.isPaused = function () {\n  return this._readableState.flowing === false;\n};\n\nfunction readableAddChunk(stream, state, chunk, encoding, addToFront) {\n  var er = chunkInvalid(state, chunk);\n  if (er) {\n    stream.emit('error', er);\n  } else if (chunk === null) {\n    state.reading = false;\n    onEofChunk(stream, state);\n  } else if (state.objectMode || chunk && chunk.length > 0) {\n    if (state.ended && !addToFront) {\n      var e = new Error('stream.push() after EOF');\n      stream.emit('error', e);\n    } else if (state.endEmitted && addToFront) {\n      var _e = new Error('stream.unshift() after end event');\n      stream.emit('error', _e);\n    } else {\n      var skipAdd;\n      if (state.decoder && !addToFront && !encoding) {\n        chunk = state.decoder.write(chunk);\n        skipAdd = !state.objectMode && chunk.length === 0;\n      }\n\n      if (!addToFront) state.reading = false;\n\n      // Don't add to the buffer if we've decoded to an empty string chunk and\n      // we're not in object mode\n      if (!skipAdd) {\n        // if we want the data now, just emit it.\n        if (state.flowing && state.length === 0 && !state.sync) {\n          stream.emit('data', chunk);\n          stream.read(0);\n        } else {\n          // update the buffer info.\n          state.length += state.objectMode ? 1 : chunk.length;\n          if (addToFront) state.buffer.unshift(chunk);else state.buffer.push(chunk);\n\n          if (state.needReadable) emitReadable(stream);\n        }\n      }\n\n      maybeReadMore(stream, state);\n    }\n  } else if (!addToFront) {\n    state.reading = false;\n  }\n\n  return needMoreData(state);\n}\n\n// if it's past the high water mark, we can push in some more.\n// Also, if we have no data yet, we can stand some\n// more bytes.  This is to work around cases where hwm=0,\n// such as the repl.  Also, if the push() triggered a\n// readable event, and the user called read(largeNumber) such that\n// needReadable was set, then we ought to push more, so that another\n// 'readable' event will be triggered.\nfunction needMoreData(state) {\n  return !state.ended && (state.needReadable || state.length < state.highWaterMark || state.length === 0);\n}\n\n// backwards compatibility.\nReadable.prototype.setEncoding = function (enc) {\n  if (!StringDecoder) StringDecoder = require('string_decoder/').StringDecoder;\n  this._readableState.decoder = new StringDecoder(enc);\n  this._readableState.encoding = enc;\n  return this;\n};\n\n// Don't raise the hwm > 8MB\nvar MAX_HWM = 0x800000;\nfunction computeNewHighWaterMark(n) {\n  if (n >= MAX_HWM) {\n    n = MAX_HWM;\n  } else {\n    // Get the next highest power of 2 to prevent increasing hwm excessively in\n    // tiny amounts\n    n--;\n    n |= n >>> 1;\n    n |= n >>> 2;\n    n |= n >>> 4;\n    n |= n >>> 8;\n    n |= n >>> 16;\n    n++;\n  }\n  return n;\n}\n\n// This function is designed to be inlinable, so please take care when making\n// changes to the function body.\nfunction howMuchToRead(n, state) {\n  if (n <= 0 || state.length === 0 && state.ended) return 0;\n  if (state.objectMode) return 1;\n  if (n !== n) {\n    // Only flow one buffer at a time\n    if (state.flowing && state.length) return state.buffer.head.data.length;else return state.length;\n  }\n  // If we're asking for more than the current hwm, then raise the hwm.\n  if (n > state.highWaterMark) state.highWaterMark = computeNewHighWaterMark(n);\n  if (n <= state.length) return n;\n  // Don't have enough\n  if (!state.ended) {\n    state.needReadable = true;\n    return 0;\n  }\n  return state.length;\n}\n\n// you can override either this method, or the async _read(n) below.\nReadable.prototype.read = function (n) {\n  debug('read', n);\n  n = parseInt(n, 10);\n  var state = this._readableState;\n  var nOrig = n;\n\n  if (n !== 0) state.emittedReadable = false;\n\n  // if we're doing read(0) to trigger a readable event, but we\n  // already have a bunch of data in the buffer, then just trigger\n  // the 'readable' event and move on.\n  if (n === 0 && state.needReadable && (state.length >= state.highWaterMark || state.ended)) {\n    debug('read: emitReadable', state.length, state.ended);\n    if (state.length === 0 && state.ended) endReadable(this);else emitReadable(this);\n    return null;\n  }\n\n  n = howMuchToRead(n, state);\n\n  // if we've ended, and we're now clear, then finish it up.\n  if (n === 0 && state.ended) {\n    if (state.length === 0) endReadable(this);\n    return null;\n  }\n\n  // All the actual chunk generation logic needs to be\n  // *below* the call to _read.  The reason is that in certain\n  // synthetic stream cases, such as passthrough streams, _read\n  // may be a completely synchronous operation which may change\n  // the state of the read buffer, providing enough data when\n  // before there was *not* enough.\n  //\n  // So, the steps are:\n  // 1. Figure out what the state of things will be after we do\n  // a read from the buffer.\n  //\n  // 2. If that resulting state will trigger a _read, then call _read.\n  // Note that this may be asynchronous, or synchronous.  Yes, it is\n  // deeply ugly to write APIs this way, but that still doesn't mean\n  // that the Readable class should behave improperly, as streams are\n  // designed to be sync/async agnostic.\n  // Take note if the _read call is sync or async (ie, if the read call\n  // has returned yet), so that we know whether or not it's safe to emit\n  // 'readable' etc.\n  //\n  // 3. Actually pull the requested chunks out of the buffer and return.\n\n  // if we need a readable event, then we need to do some reading.\n  var doRead = state.needReadable;\n  debug('need readable', doRead);\n\n  // if we currently have less than the highWaterMark, then also read some\n  if (state.length === 0 || state.length - n < state.highWaterMark) {\n    doRead = true;\n    debug('length less than watermark', doRead);\n  }\n\n  // however, if we've ended, then there's no point, and if we're already\n  // reading, then it's unnecessary.\n  if (state.ended || state.reading) {\n    doRead = false;\n    debug('reading or ended', doRead);\n  } else if (doRead) {\n    debug('do read');\n    state.reading = true;\n    state.sync = true;\n    // if the length is currently zero, then we *need* a readable event.\n    if (state.length === 0) state.needReadable = true;\n    // call internal read method\n    this._read(state.highWaterMark);\n    state.sync = false;\n    // If _read pushed data synchronously, then `reading` will be false,\n    // and we need to re-evaluate how much data we can return to the user.\n    if (!state.reading) n = howMuchToRead(nOrig, state);\n  }\n\n  var ret;\n  if (n > 0) ret = fromList(n, state);else ret = null;\n\n  if (ret === null) {\n    state.needReadable = true;\n    n = 0;\n  } else {\n    state.length -= n;\n  }\n\n  if (state.length === 0) {\n    // If we have nothing in the buffer, then we want to know\n    // as soon as we *do* get something into the buffer.\n    if (!state.ended) state.needReadable = true;\n\n    // If we tried to read() past the EOF, then emit end on the next tick.\n    if (nOrig !== n && state.ended) endReadable(this);\n  }\n\n  if (ret !== null) this.emit('data', ret);\n\n  return ret;\n};\n\nfunction chunkInvalid(state, chunk) {\n  var er = null;\n  if (!Buffer.isBuffer(chunk) && typeof chunk !== 'string' && chunk !== null && chunk !== undefined && !state.objectMode) {\n    er = new TypeError('Invalid non-string/buffer chunk');\n  }\n  return er;\n}\n\nfunction onEofChunk(stream, state) {\n  if (state.ended) return;\n  if (state.decoder) {\n    var chunk = state.decoder.end();\n    if (chunk && chunk.length) {\n      state.buffer.push(chunk);\n      state.length += state.objectMode ? 1 : chunk.length;\n    }\n  }\n  state.ended = true;\n\n  // emit 'readable' now to make sure it gets picked up.\n  emitReadable(stream);\n}\n\n// Don't emit readable right away in sync mode, because this can trigger\n// another read() call => stack overflow.  This way, it might trigger\n// a nextTick recursion warning, but that's not so bad.\nfunction emitReadable(stream) {\n  var state = stream._readableState;\n  state.needReadable = false;\n  if (!state.emittedReadable) {\n    debug('emitReadable', state.flowing);\n    state.emittedReadable = true;\n    if (state.sync) processNextTick(emitReadable_, stream);else emitReadable_(stream);\n  }\n}\n\nfunction emitReadable_(stream) {\n  debug('emit readable');\n  stream.emit('readable');\n  flow(stream);\n}\n\n// at this point, the user has presumably seen the 'readable' event,\n// and called read() to consume some data.  that may have triggered\n// in turn another _read(n) call, in which case reading = true if\n// it's in progress.\n// However, if we're not ended, or reading, and the length < hwm,\n// then go ahead and try to read some more preemptively.\nfunction maybeReadMore(stream, state) {\n  if (!state.readingMore) {\n    state.readingMore = true;\n    processNextTick(maybeReadMore_, stream, state);\n  }\n}\n\nfunction maybeReadMore_(stream, state) {\n  var len = state.length;\n  while (!state.reading && !state.flowing && !state.ended && state.length < state.highWaterMark) {\n    debug('maybeReadMore read 0');\n    stream.read(0);\n    if (len === state.length)\n      // didn't get any data, stop spinning.\n      break;else len = state.length;\n  }\n  state.readingMore = false;\n}\n\n// abstract method.  to be overridden in specific implementation classes.\n// call cb(er, data) where data is <= n in length.\n// for virtual (non-string, non-buffer) streams, \"length\" is somewhat\n// arbitrary, and perhaps not very meaningful.\nReadable.prototype._read = function (n) {\n  this.emit('error', new Error('not implemented'));\n};\n\nReadable.prototype.pipe = function (dest, pipeOpts) {\n  var src = this;\n  var state = this._readableState;\n\n  switch (state.pipesCount) {\n    case 0:\n      state.pipes = dest;\n      break;\n    case 1:\n      state.pipes = [state.pipes, dest];\n      break;\n    default:\n      state.pipes.push(dest);\n      break;\n  }\n  state.pipesCount += 1;\n  debug('pipe count=%d opts=%j', state.pipesCount, pipeOpts);\n\n  var doEnd = (!pipeOpts || pipeOpts.end !== false) && dest !== process.stdout && dest !== process.stderr;\n\n  var endFn = doEnd ? onend : cleanup;\n  if (state.endEmitted) processNextTick(endFn);else src.once('end', endFn);\n\n  dest.on('unpipe', onunpipe);\n  function onunpipe(readable) {\n    debug('onunpipe');\n    if (readable === src) {\n      cleanup();\n    }\n  }\n\n  function onend() {\n    debug('onend');\n    dest.end();\n  }\n\n  // when the dest drains, it reduces the awaitDrain counter\n  // on the source.  This would be more elegant with a .once()\n  // handler in flow(), but adding and removing repeatedly is\n  // too slow.\n  var ondrain = pipeOnDrain(src);\n  dest.on('drain', ondrain);\n\n  var cleanedUp = false;\n  function cleanup() {\n    debug('cleanup');\n    // cleanup event handlers once the pipe is broken\n    dest.removeListener('close', onclose);\n    dest.removeListener('finish', onfinish);\n    dest.removeListener('drain', ondrain);\n    dest.removeListener('error', onerror);\n    dest.removeListener('unpipe', onunpipe);\n    src.removeListener('end', onend);\n    src.removeListener('end', cleanup);\n    src.removeListener('data', ondata);\n\n    cleanedUp = true;\n\n    // if the reader is waiting for a drain event from this\n    // specific writer, then it would cause it to never start\n    // flowing again.\n    // So, if this is awaiting a drain, then we just call it now.\n    // If we don't know, then assume that we are waiting for one.\n    if (state.awaitDrain && (!dest._writableState || dest._writableState.needDrain)) ondrain();\n  }\n\n  // If the user pushes more data while we're writing to dest then we'll end up\n  // in ondata again. However, we only want to increase awaitDrain once because\n  // dest will only emit one 'drain' event for the multiple writes.\n  // => Introduce a guard on increasing awaitDrain.\n  var increasedAwaitDrain = false;\n  src.on('data', ondata);\n  function ondata(chunk) {\n    debug('ondata');\n    increasedAwaitDrain = false;\n    var ret = dest.write(chunk);\n    if (false === ret && !increasedAwaitDrain) {\n      // If the user unpiped during `dest.write()`, it is possible\n      // to get stuck in a permanently paused state if that write\n      // also returned false.\n      // => Check whether `dest` is still a piping destination.\n      if ((state.pipesCount === 1 && state.pipes === dest || state.pipesCount > 1 && indexOf(state.pipes, dest) !== -1) && !cleanedUp) {\n        debug('false write response, pause', src._readableState.awaitDrain);\n        src._readableState.awaitDrain++;\n        increasedAwaitDrain = true;\n      }\n      src.pause();\n    }\n  }\n\n  // if the dest has an error, then stop piping into it.\n  // however, don't suppress the throwing behavior for this.\n  function onerror(er) {\n    debug('onerror', er);\n    unpipe();\n    dest.removeListener('error', onerror);\n    if (EElistenerCount(dest, 'error') === 0) dest.emit('error', er);\n  }\n\n  // Make sure our error handler is attached before userland ones.\n  prependListener(dest, 'error', onerror);\n\n  // Both close and finish should trigger unpipe, but only once.\n  function onclose() {\n    dest.removeListener('finish', onfinish);\n    unpipe();\n  }\n  dest.once('close', onclose);\n  function onfinish() {\n    debug('onfinish');\n    dest.removeListener('close', onclose);\n    unpipe();\n  }\n  dest.once('finish', onfinish);\n\n  function unpipe() {\n    debug('unpipe');\n    src.unpipe(dest);\n  }\n\n  // tell the dest that it's being piped to\n  dest.emit('pipe', src);\n\n  // start the flow if it hasn't been started already.\n  if (!state.flowing) {\n    debug('pipe resume');\n    src.resume();\n  }\n\n  return dest;\n};\n\nfunction pipeOnDrain(src) {\n  return function () {\n    var state = src._readableState;\n    debug('pipeOnDrain', state.awaitDrain);\n    if (state.awaitDrain) state.awaitDrain--;\n    if (state.awaitDrain === 0 && EElistenerCount(src, 'data')) {\n      state.flowing = true;\n      flow(src);\n    }\n  };\n}\n\nReadable.prototype.unpipe = function (dest) {\n  var state = this._readableState;\n\n  // if we're not piping anywhere, then do nothing.\n  if (state.pipesCount === 0) return this;\n\n  // just one destination.  most common case.\n  if (state.pipesCount === 1) {\n    // passed in one, but it's not the right one.\n    if (dest && dest !== state.pipes) return this;\n\n    if (!dest) dest = state.pipes;\n\n    // got a match.\n    state.pipes = null;\n    state.pipesCount = 0;\n    state.flowing = false;\n    if (dest) dest.emit('unpipe', this);\n    return this;\n  }\n\n  // slow case. multiple pipe destinations.\n\n  if (!dest) {\n    // remove all.\n    var dests = state.pipes;\n    var len = state.pipesCount;\n    state.pipes = null;\n    state.pipesCount = 0;\n    state.flowing = false;\n\n    for (var _i = 0; _i < len; _i++) {\n      dests[_i].emit('unpipe', this);\n    }return this;\n  }\n\n  // try to find the right one.\n  var i = indexOf(state.pipes, dest);\n  if (i === -1) return this;\n\n  state.pipes.splice(i, 1);\n  state.pipesCount -= 1;\n  if (state.pipesCount === 1) state.pipes = state.pipes[0];\n\n  dest.emit('unpipe', this);\n\n  return this;\n};\n\n// set up data events if they are asked for\n// Ensure readable listeners eventually get something\nReadable.prototype.on = function (ev, fn) {\n  var res = Stream.prototype.on.call(this, ev, fn);\n\n  if (ev === 'data') {\n    // Start flowing on next tick if stream isn't explicitly paused\n    if (this._readableState.flowing !== false) this.resume();\n  } else if (ev === 'readable') {\n    var state = this._readableState;\n    if (!state.endEmitted && !state.readableListening) {\n      state.readableListening = state.needReadable = true;\n      state.emittedReadable = false;\n      if (!state.reading) {\n        processNextTick(nReadingNextTick, this);\n      } else if (state.length) {\n        emitReadable(this, state);\n      }\n    }\n  }\n\n  return res;\n};\nReadable.prototype.addListener = Readable.prototype.on;\n\nfunction nReadingNextTick(self) {\n  debug('readable nexttick read 0');\n  self.read(0);\n}\n\n// pause() and resume() are remnants of the legacy readable stream API\n// If the user uses them, then switch into old mode.\nReadable.prototype.resume = function () {\n  var state = this._readableState;\n  if (!state.flowing) {\n    debug('resume');\n    state.flowing = true;\n    resume(this, state);\n  }\n  return this;\n};\n\nfunction resume(stream, state) {\n  if (!state.resumeScheduled) {\n    state.resumeScheduled = true;\n    processNextTick(resume_, stream, state);\n  }\n}\n\nfunction resume_(stream, state) {\n  if (!state.reading) {\n    debug('resume read 0');\n    stream.read(0);\n  }\n\n  state.resumeScheduled = false;\n  state.awaitDrain = 0;\n  stream.emit('resume');\n  flow(stream);\n  if (state.flowing && !state.reading) stream.read(0);\n}\n\nReadable.prototype.pause = function () {\n  debug('call pause flowing=%j', this._readableState.flowing);\n  if (false !== this._readableState.flowing) {\n    debug('pause');\n    this._readableState.flowing = false;\n    this.emit('pause');\n  }\n  return this;\n};\n\nfunction flow(stream) {\n  var state = stream._readableState;\n  debug('flow', state.flowing);\n  while (state.flowing && stream.read() !== null) {}\n}\n\n// wrap an old-style stream as the async data source.\n// This is *not* part of the readable stream interface.\n// It is an ugly unfortunate mess of history.\nReadable.prototype.wrap = function (stream) {\n  var state = this._readableState;\n  var paused = false;\n\n  var self = this;\n  stream.on('end', function () {\n    debug('wrapped end');\n    if (state.decoder && !state.ended) {\n      var chunk = state.decoder.end();\n      if (chunk && chunk.length) self.push(chunk);\n    }\n\n    self.push(null);\n  });\n\n  stream.on('data', function (chunk) {\n    debug('wrapped data');\n    if (state.decoder) chunk = state.decoder.write(chunk);\n\n    // don't skip over falsy values in objectMode\n    if (state.objectMode && (chunk === null || chunk === undefined)) return;else if (!state.objectMode && (!chunk || !chunk.length)) return;\n\n    var ret = self.push(chunk);\n    if (!ret) {\n      paused = true;\n      stream.pause();\n    }\n  });\n\n  // proxy all the other methods.\n  // important when wrapping filters and duplexes.\n  for (var i in stream) {\n    if (this[i] === undefined && typeof stream[i] === 'function') {\n      this[i] = function (method) {\n        return function () {\n          return stream[method].apply(stream, arguments);\n        };\n      }(i);\n    }\n  }\n\n  // proxy certain important events.\n  var events = ['error', 'close', 'destroy', 'pause', 'resume'];\n  forEach(events, function (ev) {\n    stream.on(ev, self.emit.bind(self, ev));\n  });\n\n  // when we try to consume some more bytes, simply unpause the\n  // underlying stream.\n  self._read = function (n) {\n    debug('wrapped _read', n);\n    if (paused) {\n      paused = false;\n      stream.resume();\n    }\n  };\n\n  return self;\n};\n\n// exposed for testing purposes only.\nReadable._fromList = fromList;\n\n// Pluck off n bytes from an array of buffers.\n// Length is the combined lengths of all the buffers in the list.\n// This function is designed to be inlinable, so please take care when making\n// changes to the function body.\nfunction fromList(n, state) {\n  // nothing buffered\n  if (state.length === 0) return null;\n\n  var ret;\n  if (state.objectMode) ret = state.buffer.shift();else if (!n || n >= state.length) {\n    // read it all, truncate the list\n    if (state.decoder) ret = state.buffer.join('');else if (state.buffer.length === 1) ret = state.buffer.head.data;else ret = state.buffer.concat(state.length);\n    state.buffer.clear();\n  } else {\n    // read part of list\n    ret = fromListPartial(n, state.buffer, state.decoder);\n  }\n\n  return ret;\n}\n\n// Extracts only enough buffered data to satisfy the amount requested.\n// This function is designed to be inlinable, so please take care when making\n// changes to the function body.\nfunction fromListPartial(n, list, hasStrings) {\n  var ret;\n  if (n < list.head.data.length) {\n    // slice is the same for buffers and strings\n    ret = list.head.data.slice(0, n);\n    list.head.data = list.head.data.slice(n);\n  } else if (n === list.head.data.length) {\n    // first chunk is a perfect match\n    ret = list.shift();\n  } else {\n    // result spans more than one buffer\n    ret = hasStrings ? copyFromBufferString(n, list) : copyFromBuffer(n, list);\n  }\n  return ret;\n}\n\n// Copies a specified amount of characters from the list of buffered data\n// chunks.\n// This function is designed to be inlinable, so please take care when making\n// changes to the function body.\nfunction copyFromBufferString(n, list) {\n  var p = list.head;\n  var c = 1;\n  var ret = p.data;\n  n -= ret.length;\n  while (p = p.next) {\n    var str = p.data;\n    var nb = n > str.length ? str.length : n;\n    if (nb === str.length) ret += str;else ret += str.slice(0, n);\n    n -= nb;\n    if (n === 0) {\n      if (nb === str.length) {\n        ++c;\n        if (p.next) list.head = p.next;else list.head = list.tail = null;\n      } else {\n        list.head = p;\n        p.data = str.slice(nb);\n      }\n      break;\n    }\n    ++c;\n  }\n  list.length -= c;\n  return ret;\n}\n\n// Copies a specified amount of bytes from the list of buffered data chunks.\n// This function is designed to be inlinable, so please take care when making\n// changes to the function body.\nfunction copyFromBuffer(n, list) {\n  var ret = bufferShim.allocUnsafe(n);\n  var p = list.head;\n  var c = 1;\n  p.data.copy(ret);\n  n -= p.data.length;\n  while (p = p.next) {\n    var buf = p.data;\n    var nb = n > buf.length ? buf.length : n;\n    buf.copy(ret, ret.length - n, 0, nb);\n    n -= nb;\n    if (n === 0) {\n      if (nb === buf.length) {\n        ++c;\n        if (p.next) list.head = p.next;else list.head = list.tail = null;\n      } else {\n        list.head = p;\n        p.data = buf.slice(nb);\n      }\n      break;\n    }\n    ++c;\n  }\n  list.length -= c;\n  return ret;\n}\n\nfunction endReadable(stream) {\n  var state = stream._readableState;\n\n  // If we get here before consuming all the bytes, then that is a\n  // bug in node.  Should never happen.\n  if (state.length > 0) throw new Error('\"endReadable()\" called on non-empty stream');\n\n  if (!state.endEmitted) {\n    state.ended = true;\n    processNextTick(endReadableNT, state, stream);\n  }\n}\n\nfunction endReadableNT(state, stream) {\n  // Check that we didn't get one last unshift.\n  if (!state.endEmitted && state.length === 0) {\n    state.endEmitted = true;\n    stream.readable = false;\n    stream.emit('end');\n  }\n}\n\nfunction forEach(xs, f) {\n  for (var i = 0, l = xs.length; i < l; i++) {\n    f(xs[i], i);\n  }\n}\n\nfunction indexOf(xs, x) {\n  for (var i = 0, l = xs.length; i < l; i++) {\n    if (xs[i] === x) return i;\n  }\n  return -1;\n}\n}).call(this,require('_process'))\n},{\"./_stream_duplex\":69,\"./internal/streams/BufferList\":74,\"_process\":67,\"buffer\":44,\"buffer-shims\":43,\"core-util-is\":45,\"events\":48,\"inherits\":51,\"isarray\":53,\"process-nextick-args\":66,\"string_decoder/\":80,\"util\":40}],72:[function(require,module,exports){\n// a transform stream is a readable/writable stream where you do\n// something with the data.  Sometimes it's called a \"filter\",\n// but that's not a great name for it, since that implies a thing where\n// some bits pass through, and others are simply ignored.  (That would\n// be a valid example of a transform, of course.)\n//\n// While the output is causally related to the input, it's not a\n// necessarily symmetric or synchronous transformation.  For example,\n// a zlib stream might take multiple plain-text writes(), and then\n// emit a single compressed chunk some time in the future.\n//\n// Here's how this works:\n//\n// The Transform stream has all the aspects of the readable and writable\n// stream classes.  When you write(chunk), that calls _write(chunk,cb)\n// internally, and returns false if there's a lot of pending writes\n// buffered up.  When you call read(), that calls _read(n) until\n// there's enough pending readable data buffered up.\n//\n// In a transform stream, the written data is placed in a buffer.  When\n// _read(n) is called, it transforms the queued up data, calling the\n// buffered _write cb's as it consumes chunks.  If consuming a single\n// written chunk would result in multiple output chunks, then the first\n// outputted bit calls the readcb, and subsequent chunks just go into\n// the read buffer, and will cause it to emit 'readable' if necessary.\n//\n// This way, back-pressure is actually determined by the reading side,\n// since _read has to be called to start processing a new chunk.  However,\n// a pathological inflate type of transform can cause excessive buffering\n// here.  For example, imagine a stream where every byte of input is\n// interpreted as an integer from 0-255, and then results in that many\n// bytes of output.  Writing the 4 bytes {ff,ff,ff,ff} would result in\n// 1kb of data being output.  In this case, you could write a very small\n// amount of input, and end up with a very large amount of output.  In\n// such a pathological inflating mechanism, there'd be no way to tell\n// the system to stop doing the transform.  A single 4MB write could\n// cause the system to run out of memory.\n//\n// However, even in such a pathological case, only a single written chunk\n// would be consumed, and then the rest would wait (un-transformed) until\n// the results of the previous transformed chunk were consumed.\n\n'use strict';\n\nmodule.exports = Transform;\n\nvar Duplex = require('./_stream_duplex');\n\n/*<replacement>*/\nvar util = require('core-util-is');\nutil.inherits = require('inherits');\n/*</replacement>*/\n\nutil.inherits(Transform, Duplex);\n\nfunction TransformState(stream) {\n  this.afterTransform = function (er, data) {\n    return afterTransform(stream, er, data);\n  };\n\n  this.needTransform = false;\n  this.transforming = false;\n  this.writecb = null;\n  this.writechunk = null;\n  this.writeencoding = null;\n}\n\nfunction afterTransform(stream, er, data) {\n  var ts = stream._transformState;\n  ts.transforming = false;\n\n  var cb = ts.writecb;\n\n  if (!cb) return stream.emit('error', new Error('no writecb in Transform class'));\n\n  ts.writechunk = null;\n  ts.writecb = null;\n\n  if (data !== null && data !== undefined) stream.push(data);\n\n  cb(er);\n\n  var rs = stream._readableState;\n  rs.reading = false;\n  if (rs.needReadable || rs.length < rs.highWaterMark) {\n    stream._read(rs.highWaterMark);\n  }\n}\n\nfunction Transform(options) {\n  if (!(this instanceof Transform)) return new Transform(options);\n\n  Duplex.call(this, options);\n\n  this._transformState = new TransformState(this);\n\n  // when the writable side finishes, then flush out anything remaining.\n  var stream = this;\n\n  // start out asking for a readable event once data is transformed.\n  this._readableState.needReadable = true;\n\n  // we have implemented the _read method, and done the other things\n  // that Readable wants before the first _read call, so unset the\n  // sync guard flag.\n  this._readableState.sync = false;\n\n  if (options) {\n    if (typeof options.transform === 'function') this._transform = options.transform;\n\n    if (typeof options.flush === 'function') this._flush = options.flush;\n  }\n\n  this.once('prefinish', function () {\n    if (typeof this._flush === 'function') this._flush(function (er) {\n      done(stream, er);\n    });else done(stream);\n  });\n}\n\nTransform.prototype.push = function (chunk, encoding) {\n  this._transformState.needTransform = false;\n  return Duplex.prototype.push.call(this, chunk, encoding);\n};\n\n// This is the part where you do stuff!\n// override this function in implementation classes.\n// 'chunk' is an input chunk.\n//\n// Call `push(newChunk)` to pass along transformed output\n// to the readable side.  You may call 'push' zero or more times.\n//\n// Call `cb(err)` when you are done with this chunk.  If you pass\n// an error, then that'll put the hurt on the whole operation.  If you\n// never call cb(), then you'll never get another chunk.\nTransform.prototype._transform = function (chunk, encoding, cb) {\n  throw new Error('Not implemented');\n};\n\nTransform.prototype._write = function (chunk, encoding, cb) {\n  var ts = this._transformState;\n  ts.writecb = cb;\n  ts.writechunk = chunk;\n  ts.writeencoding = encoding;\n  if (!ts.transforming) {\n    var rs = this._readableState;\n    if (ts.needTransform || rs.needReadable || rs.length < rs.highWaterMark) this._read(rs.highWaterMark);\n  }\n};\n\n// Doesn't matter what the args are here.\n// _transform does all the work.\n// That we got here means that the readable side wants more data.\nTransform.prototype._read = function (n) {\n  var ts = this._transformState;\n\n  if (ts.writechunk !== null && ts.writecb && !ts.transforming) {\n    ts.transforming = true;\n    this._transform(ts.writechunk, ts.writeencoding, ts.afterTransform);\n  } else {\n    // mark that we need a transform, so that any data that comes in\n    // will get processed, now that we've asked for it.\n    ts.needTransform = true;\n  }\n};\n\nfunction done(stream, er) {\n  if (er) return stream.emit('error', er);\n\n  // if there's nothing in the write buffer, then that means\n  // that nothing more will ever be provided\n  var ws = stream._writableState;\n  var ts = stream._transformState;\n\n  if (ws.length) throw new Error('Calling transform done when ws.length != 0');\n\n  if (ts.transforming) throw new Error('Calling transform done when still transforming');\n\n  return stream.push(null);\n}\n},{\"./_stream_duplex\":69,\"core-util-is\":45,\"inherits\":51}],73:[function(require,module,exports){\n(function (process){\n// A bit simpler than readable streams.\n// Implement an async ._write(chunk, encoding, cb), and it'll handle all\n// the drain event emission and buffering.\n\n'use strict';\n\nmodule.exports = Writable;\n\n/*<replacement>*/\nvar processNextTick = require('process-nextick-args');\n/*</replacement>*/\n\n/*<replacement>*/\nvar asyncWrite = !process.browser && ['v0.10', 'v0.9.'].indexOf(process.version.slice(0, 5)) > -1 ? setImmediate : processNextTick;\n/*</replacement>*/\n\nWritable.WritableState = WritableState;\n\n/*<replacement>*/\nvar util = require('core-util-is');\nutil.inherits = require('inherits');\n/*</replacement>*/\n\n/*<replacement>*/\nvar internalUtil = {\n  deprecate: require('util-deprecate')\n};\n/*</replacement>*/\n\n/*<replacement>*/\nvar Stream;\n(function () {\n  try {\n    Stream = require('st' + 'ream');\n  } catch (_) {} finally {\n    if (!Stream) Stream = require('events').EventEmitter;\n  }\n})();\n/*</replacement>*/\n\nvar Buffer = require('buffer').Buffer;\n/*<replacement>*/\nvar bufferShim = require('buffer-shims');\n/*</replacement>*/\n\nutil.inherits(Writable, Stream);\n\nfunction nop() {}\n\nfunction WriteReq(chunk, encoding, cb) {\n  this.chunk = chunk;\n  this.encoding = encoding;\n  this.callback = cb;\n  this.next = null;\n}\n\nvar Duplex;\nfunction WritableState(options, stream) {\n  Duplex = Duplex || require('./_stream_duplex');\n\n  options = options || {};\n\n  // object stream flag to indicate whether or not this stream\n  // contains buffers or objects.\n  this.objectMode = !!options.objectMode;\n\n  if (stream instanceof Duplex) this.objectMode = this.objectMode || !!options.writableObjectMode;\n\n  // the point at which write() starts returning false\n  // Note: 0 is a valid value, means that we always return false if\n  // the entire buffer is not flushed immediately on write()\n  var hwm = options.highWaterMark;\n  var defaultHwm = this.objectMode ? 16 : 16 * 1024;\n  this.highWaterMark = hwm || hwm === 0 ? hwm : defaultHwm;\n\n  // cast to ints.\n  this.highWaterMark = ~ ~this.highWaterMark;\n\n  this.needDrain = false;\n  // at the start of calling end()\n  this.ending = false;\n  // when end() has been called, and returned\n  this.ended = false;\n  // when 'finish' is emitted\n  this.finished = false;\n\n  // should we decode strings into buffers before passing to _write?\n  // this is here so that some node-core streams can optimize string\n  // handling at a lower level.\n  var noDecode = options.decodeStrings === false;\n  this.decodeStrings = !noDecode;\n\n  // Crypto is kind of old and crusty.  Historically, its default string\n  // encoding is 'binary' so we have to make this configurable.\n  // Everything else in the universe uses 'utf8', though.\n  this.defaultEncoding = options.defaultEncoding || 'utf8';\n\n  // not an actual buffer we keep track of, but a measurement\n  // of how much we're waiting to get pushed to some underlying\n  // socket or file.\n  this.length = 0;\n\n  // a flag to see when we're in the middle of a write.\n  this.writing = false;\n\n  // when true all writes will be buffered until .uncork() call\n  this.corked = 0;\n\n  // a flag to be able to tell if the onwrite cb is called immediately,\n  // or on a later tick.  We set this to true at first, because any\n  // actions that shouldn't happen until \"later\" should generally also\n  // not happen before the first write call.\n  this.sync = true;\n\n  // a flag to know if we're processing previously buffered items, which\n  // may call the _write() callback in the same tick, so that we don't\n  // end up in an overlapped onwrite situation.\n  this.bufferProcessing = false;\n\n  // the callback that's passed to _write(chunk,cb)\n  this.onwrite = function (er) {\n    onwrite(stream, er);\n  };\n\n  // the callback that the user supplies to write(chunk,encoding,cb)\n  this.writecb = null;\n\n  // the amount that is being written when _write is called.\n  this.writelen = 0;\n\n  this.bufferedRequest = null;\n  this.lastBufferedRequest = null;\n\n  // number of pending user-supplied write callbacks\n  // this must be 0 before 'finish' can be emitted\n  this.pendingcb = 0;\n\n  // emit prefinish if the only thing we're waiting for is _write cbs\n  // This is relevant for synchronous Transform streams\n  this.prefinished = false;\n\n  // True if the error was already emitted and should not be thrown again\n  this.errorEmitted = false;\n\n  // count buffered requests\n  this.bufferedRequestCount = 0;\n\n  // allocate the first CorkedRequest, there is always\n  // one allocated and free to use, and we maintain at most two\n  this.corkedRequestsFree = new CorkedRequest(this);\n}\n\nWritableState.prototype.getBuffer = function writableStateGetBuffer() {\n  var current = this.bufferedRequest;\n  var out = [];\n  while (current) {\n    out.push(current);\n    current = current.next;\n  }\n  return out;\n};\n\n(function () {\n  try {\n    Object.defineProperty(WritableState.prototype, 'buffer', {\n      get: internalUtil.deprecate(function () {\n        return this.getBuffer();\n      }, '_writableState.buffer is deprecated. Use _writableState.getBuffer ' + 'instead.')\n    });\n  } catch (_) {}\n})();\n\nvar Duplex;\nfunction Writable(options) {\n  Duplex = Duplex || require('./_stream_duplex');\n\n  // Writable ctor is applied to Duplexes, though they're not\n  // instanceof Writable, they're instanceof Readable.\n  if (!(this instanceof Writable) && !(this instanceof Duplex)) return new Writable(options);\n\n  this._writableState = new WritableState(options, this);\n\n  // legacy.\n  this.writable = true;\n\n  if (options) {\n    if (typeof options.write === 'function') this._write = options.write;\n\n    if (typeof options.writev === 'function') this._writev = options.writev;\n  }\n\n  Stream.call(this);\n}\n\n// Otherwise people can pipe Writable streams, which is just wrong.\nWritable.prototype.pipe = function () {\n  this.emit('error', new Error('Cannot pipe, not readable'));\n};\n\nfunction writeAfterEnd(stream, cb) {\n  var er = new Error('write after end');\n  // TODO: defer error events consistently everywhere, not just the cb\n  stream.emit('error', er);\n  processNextTick(cb, er);\n}\n\n// If we get something that is not a buffer, string, null, or undefined,\n// and we're not in objectMode, then that's an error.\n// Otherwise stream chunks are all considered to be of length=1, and the\n// watermarks determine how many objects to keep in the buffer, rather than\n// how many bytes or characters.\nfunction validChunk(stream, state, chunk, cb) {\n  var valid = true;\n  var er = false;\n  // Always throw error if a null is written\n  // if we are not in object mode then throw\n  // if it is not a buffer, string, or undefined.\n  if (chunk === null) {\n    er = new TypeError('May not write null values to stream');\n  } else if (!Buffer.isBuffer(chunk) && typeof chunk !== 'string' && chunk !== undefined && !state.objectMode) {\n    er = new TypeError('Invalid non-string/buffer chunk');\n  }\n  if (er) {\n    stream.emit('error', er);\n    processNextTick(cb, er);\n    valid = false;\n  }\n  return valid;\n}\n\nWritable.prototype.write = function (chunk, encoding, cb) {\n  var state = this._writableState;\n  var ret = false;\n\n  if (typeof encoding === 'function') {\n    cb = encoding;\n    encoding = null;\n  }\n\n  if (Buffer.isBuffer(chunk)) encoding = 'buffer';else if (!encoding) encoding = state.defaultEncoding;\n\n  if (typeof cb !== 'function') cb = nop;\n\n  if (state.ended) writeAfterEnd(this, cb);else if (validChunk(this, state, chunk, cb)) {\n    state.pendingcb++;\n    ret = writeOrBuffer(this, state, chunk, encoding, cb);\n  }\n\n  return ret;\n};\n\nWritable.prototype.cork = function () {\n  var state = this._writableState;\n\n  state.corked++;\n};\n\nWritable.prototype.uncork = function () {\n  var state = this._writableState;\n\n  if (state.corked) {\n    state.corked--;\n\n    if (!state.writing && !state.corked && !state.finished && !state.bufferProcessing && state.bufferedRequest) clearBuffer(this, state);\n  }\n};\n\nWritable.prototype.setDefaultEncoding = function setDefaultEncoding(encoding) {\n  // node::ParseEncoding() requires lower case.\n  if (typeof encoding === 'string') encoding = encoding.toLowerCase();\n  if (!(['hex', 'utf8', 'utf-8', 'ascii', 'binary', 'base64', 'ucs2', 'ucs-2', 'utf16le', 'utf-16le', 'raw'].indexOf((encoding + '').toLowerCase()) > -1)) throw new TypeError('Unknown encoding: ' + encoding);\n  this._writableState.defaultEncoding = encoding;\n  return this;\n};\n\nfunction decodeChunk(state, chunk, encoding) {\n  if (!state.objectMode && state.decodeStrings !== false && typeof chunk === 'string') {\n    chunk = bufferShim.from(chunk, encoding);\n  }\n  return chunk;\n}\n\n// if we're already writing something, then just put this\n// in the queue, and wait our turn.  Otherwise, call _write\n// If we return false, then we need a drain event, so set that flag.\nfunction writeOrBuffer(stream, state, chunk, encoding, cb) {\n  chunk = decodeChunk(state, chunk, encoding);\n\n  if (Buffer.isBuffer(chunk)) encoding = 'buffer';\n  var len = state.objectMode ? 1 : chunk.length;\n\n  state.length += len;\n\n  var ret = state.length < state.highWaterMark;\n  // we must ensure that previous needDrain will not be reset to false.\n  if (!ret) state.needDrain = true;\n\n  if (state.writing || state.corked) {\n    var last = state.lastBufferedRequest;\n    state.lastBufferedRequest = new WriteReq(chunk, encoding, cb);\n    if (last) {\n      last.next = state.lastBufferedRequest;\n    } else {\n      state.bufferedRequest = state.lastBufferedRequest;\n    }\n    state.bufferedRequestCount += 1;\n  } else {\n    doWrite(stream, state, false, len, chunk, encoding, cb);\n  }\n\n  return ret;\n}\n\nfunction doWrite(stream, state, writev, len, chunk, encoding, cb) {\n  state.writelen = len;\n  state.writecb = cb;\n  state.writing = true;\n  state.sync = true;\n  if (writev) stream._writev(chunk, state.onwrite);else stream._write(chunk, encoding, state.onwrite);\n  state.sync = false;\n}\n\nfunction onwriteError(stream, state, sync, er, cb) {\n  --state.pendingcb;\n  if (sync) processNextTick(cb, er);else cb(er);\n\n  stream._writableState.errorEmitted = true;\n  stream.emit('error', er);\n}\n\nfunction onwriteStateUpdate(state) {\n  state.writing = false;\n  state.writecb = null;\n  state.length -= state.writelen;\n  state.writelen = 0;\n}\n\nfunction onwrite(stream, er) {\n  var state = stream._writableState;\n  var sync = state.sync;\n  var cb = state.writecb;\n\n  onwriteStateUpdate(state);\n\n  if (er) onwriteError(stream, state, sync, er, cb);else {\n    // Check if we're actually ready to finish, but don't emit yet\n    var finished = needFinish(state);\n\n    if (!finished && !state.corked && !state.bufferProcessing && state.bufferedRequest) {\n      clearBuffer(stream, state);\n    }\n\n    if (sync) {\n      /*<replacement>*/\n      asyncWrite(afterWrite, stream, state, finished, cb);\n      /*</replacement>*/\n    } else {\n        afterWrite(stream, state, finished, cb);\n      }\n  }\n}\n\nfunction afterWrite(stream, state, finished, cb) {\n  if (!finished) onwriteDrain(stream, state);\n  state.pendingcb--;\n  cb();\n  finishMaybe(stream, state);\n}\n\n// Must force callback to be called on nextTick, so that we don't\n// emit 'drain' before the write() consumer gets the 'false' return\n// value, and has a chance to attach a 'drain' listener.\nfunction onwriteDrain(stream, state) {\n  if (state.length === 0 && state.needDrain) {\n    state.needDrain = false;\n    stream.emit('drain');\n  }\n}\n\n// if there's something in the buffer waiting, then process it\nfunction clearBuffer(stream, state) {\n  state.bufferProcessing = true;\n  var entry = state.bufferedRequest;\n\n  if (stream._writev && entry && entry.next) {\n    // Fast case, write everything using _writev()\n    var l = state.bufferedRequestCount;\n    var buffer = new Array(l);\n    var holder = state.corkedRequestsFree;\n    holder.entry = entry;\n\n    var count = 0;\n    while (entry) {\n      buffer[count] = entry;\n      entry = entry.next;\n      count += 1;\n    }\n\n    doWrite(stream, state, true, state.length, buffer, '', holder.finish);\n\n    // doWrite is almost always async, defer these to save a bit of time\n    // as the hot path ends with doWrite\n    state.pendingcb++;\n    state.lastBufferedRequest = null;\n    if (holder.next) {\n      state.corkedRequestsFree = holder.next;\n      holder.next = null;\n    } else {\n      state.corkedRequestsFree = new CorkedRequest(state);\n    }\n  } else {\n    // Slow case, write chunks one-by-one\n    while (entry) {\n      var chunk = entry.chunk;\n      var encoding = entry.encoding;\n      var cb = entry.callback;\n      var len = state.objectMode ? 1 : chunk.length;\n\n      doWrite(stream, state, false, len, chunk, encoding, cb);\n      entry = entry.next;\n      // if we didn't call the onwrite immediately, then\n      // it means that we need to wait until it does.\n      // also, that means that the chunk and cb are currently\n      // being processed, so move the buffer counter past them.\n      if (state.writing) {\n        break;\n      }\n    }\n\n    if (entry === null) state.lastBufferedRequest = null;\n  }\n\n  state.bufferedRequestCount = 0;\n  state.bufferedRequest = entry;\n  state.bufferProcessing = false;\n}\n\nWritable.prototype._write = function (chunk, encoding, cb) {\n  cb(new Error('not implemented'));\n};\n\nWritable.prototype._writev = null;\n\nWritable.prototype.end = function (chunk, encoding, cb) {\n  var state = this._writableState;\n\n  if (typeof chunk === 'function') {\n    cb = chunk;\n    chunk = null;\n    encoding = null;\n  } else if (typeof encoding === 'function') {\n    cb = encoding;\n    encoding = null;\n  }\n\n  if (chunk !== null && chunk !== undefined) this.write(chunk, encoding);\n\n  // .end() fully uncorks\n  if (state.corked) {\n    state.corked = 1;\n    this.uncork();\n  }\n\n  // ignore unnecessary end() calls.\n  if (!state.ending && !state.finished) endWritable(this, state, cb);\n};\n\nfunction needFinish(state) {\n  return state.ending && state.length === 0 && state.bufferedRequest === null && !state.finished && !state.writing;\n}\n\nfunction prefinish(stream, state) {\n  if (!state.prefinished) {\n    state.prefinished = true;\n    stream.emit('prefinish');\n  }\n}\n\nfunction finishMaybe(stream, state) {\n  var need = needFinish(state);\n  if (need) {\n    if (state.pendingcb === 0) {\n      prefinish(stream, state);\n      state.finished = true;\n      stream.emit('finish');\n    } else {\n      prefinish(stream, state);\n    }\n  }\n  return need;\n}\n\nfunction endWritable(stream, state, cb) {\n  state.ending = true;\n  finishMaybe(stream, state);\n  if (cb) {\n    if (state.finished) processNextTick(cb);else stream.once('finish', cb);\n  }\n  state.ended = true;\n  stream.writable = false;\n}\n\n// It seems a linked list but it is not\n// there will be only 2 of these for each stream\nfunction CorkedRequest(state) {\n  var _this = this;\n\n  this.next = null;\n  this.entry = null;\n\n  this.finish = function (err) {\n    var entry = _this.entry;\n    _this.entry = null;\n    while (entry) {\n      var cb = entry.callback;\n      state.pendingcb--;\n      cb(err);\n      entry = entry.next;\n    }\n    if (state.corkedRequestsFree) {\n      state.corkedRequestsFree.next = _this;\n    } else {\n      state.corkedRequestsFree = _this;\n    }\n  };\n}\n}).call(this,require('_process'))\n},{\"./_stream_duplex\":69,\"_process\":67,\"buffer\":44,\"buffer-shims\":43,\"core-util-is\":45,\"events\":48,\"inherits\":51,\"process-nextick-args\":66,\"util-deprecate\":81}],74:[function(require,module,exports){\n'use strict';\n\nvar Buffer = require('buffer').Buffer;\n/*<replacement>*/\nvar bufferShim = require('buffer-shims');\n/*</replacement>*/\n\nmodule.exports = BufferList;\n\nfunction BufferList() {\n  this.head = null;\n  this.tail = null;\n  this.length = 0;\n}\n\nBufferList.prototype.push = function (v) {\n  var entry = { data: v, next: null };\n  if (this.length > 0) this.tail.next = entry;else this.head = entry;\n  this.tail = entry;\n  ++this.length;\n};\n\nBufferList.prototype.unshift = function (v) {\n  var entry = { data: v, next: this.head };\n  if (this.length === 0) this.tail = entry;\n  this.head = entry;\n  ++this.length;\n};\n\nBufferList.prototype.shift = function () {\n  if (this.length === 0) return;\n  var ret = this.head.data;\n  if (this.length === 1) this.head = this.tail = null;else this.head = this.head.next;\n  --this.length;\n  return ret;\n};\n\nBufferList.prototype.clear = function () {\n  this.head = this.tail = null;\n  this.length = 0;\n};\n\nBufferList.prototype.join = function (s) {\n  if (this.length === 0) return '';\n  var p = this.head;\n  var ret = '' + p.data;\n  while (p = p.next) {\n    ret += s + p.data;\n  }return ret;\n};\n\nBufferList.prototype.concat = function (n) {\n  if (this.length === 0) return bufferShim.alloc(0);\n  if (this.length === 1) return this.head.data;\n  var ret = bufferShim.allocUnsafe(n >>> 0);\n  var p = this.head;\n  var i = 0;\n  while (p) {\n    p.data.copy(ret, i);\n    i += p.data.length;\n    p = p.next;\n  }\n  return ret;\n};\n},{\"buffer\":44,\"buffer-shims\":43}],75:[function(require,module,exports){\nmodule.exports = require(\"./lib/_stream_passthrough.js\")\n\n},{\"./lib/_stream_passthrough.js\":70}],76:[function(require,module,exports){\n(function (process){\nvar Stream = (function (){\n  try {\n    return require('st' + 'ream'); // hack to fix a circular dependency issue when used with browserify\n  } catch(_){}\n}());\nexports = module.exports = require('./lib/_stream_readable.js');\nexports.Stream = Stream || exports;\nexports.Readable = exports;\nexports.Writable = require('./lib/_stream_writable.js');\nexports.Duplex = require('./lib/_stream_duplex.js');\nexports.Transform = require('./lib/_stream_transform.js');\nexports.PassThrough = require('./lib/_stream_passthrough.js');\n\nif (!process.browser && process.env.READABLE_STREAM === 'disable' && Stream) {\n  module.exports = Stream;\n}\n\n}).call(this,require('_process'))\n},{\"./lib/_stream_duplex.js\":69,\"./lib/_stream_passthrough.js\":70,\"./lib/_stream_readable.js\":71,\"./lib/_stream_transform.js\":72,\"./lib/_stream_writable.js\":73,\"_process\":67}],77:[function(require,module,exports){\nmodule.exports = require(\"./lib/_stream_transform.js\")\n\n},{\"./lib/_stream_transform.js\":72}],78:[function(require,module,exports){\nmodule.exports = require(\"./lib/_stream_writable.js\")\n\n},{\"./lib/_stream_writable.js\":73}],79:[function(require,module,exports){\n// Copyright Joyent, Inc. and other Node contributors.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a\n// copy of this software and associated documentation files (the\n// \"Software\"), to deal in the Software without restriction, including\n// without limitation the rights to use, copy, modify, merge, publish,\n// distribute, sublicense, and/or sell copies of the Software, and to permit\n// persons to whom the Software is furnished to do so, subject to the\n// following conditions:\n//\n// The above copyright notice and this permission notice shall be included\n// in all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS\n// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN\n// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,\n// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE\n// USE OR OTHER DEALINGS IN THE SOFTWARE.\n\nmodule.exports = Stream;\n\nvar EE = require('events').EventEmitter;\nvar inherits = require('inherits');\n\ninherits(Stream, EE);\nStream.Readable = require('readable-stream/readable.js');\nStream.Writable = require('readable-stream/writable.js');\nStream.Duplex = require('readable-stream/duplex.js');\nStream.Transform = require('readable-stream/transform.js');\nStream.PassThrough = require('readable-stream/passthrough.js');\n\n// Backwards-compat with node 0.4.x\nStream.Stream = Stream;\n\n\n\n// old-style streams.  Note that the pipe method (the only relevant\n// part of this class) is overridden in the Readable class.\n\nfunction Stream() {\n  EE.call(this);\n}\n\nStream.prototype.pipe = function(dest, options) {\n  var source = this;\n\n  function ondata(chunk) {\n    if (dest.writable) {\n      if (false === dest.write(chunk) && source.pause) {\n        source.pause();\n      }\n    }\n  }\n\n  source.on('data', ondata);\n\n  function ondrain() {\n    if (source.readable && source.resume) {\n      source.resume();\n    }\n  }\n\n  dest.on('drain', ondrain);\n\n  // If the 'end' option is not supplied, dest.end() will be called when\n  // source gets the 'end' or 'close' events.  Only dest.end() once.\n  if (!dest._isStdio && (!options || options.end !== false)) {\n    source.on('end', onend);\n    source.on('close', onclose);\n  }\n\n  var didOnEnd = false;\n  function onend() {\n    if (didOnEnd) return;\n    didOnEnd = true;\n\n    dest.end();\n  }\n\n\n  function onclose() {\n    if (didOnEnd) return;\n    didOnEnd = true;\n\n    if (typeof dest.destroy === 'function') dest.destroy();\n  }\n\n  // don't leave dangling pipes when there are errors.\n  function onerror(er) {\n    cleanup();\n    if (EE.listenerCount(this, 'error') === 0) {\n      throw er; // Unhandled stream error in pipe.\n    }\n  }\n\n  source.on('error', onerror);\n  dest.on('error', onerror);\n\n  // remove all the event listeners that were added.\n  function cleanup() {\n    source.removeListener('data', ondata);\n    dest.removeListener('drain', ondrain);\n\n    source.removeListener('end', onend);\n    source.removeListener('close', onclose);\n\n    source.removeListener('error', onerror);\n    dest.removeListener('error', onerror);\n\n    source.removeListener('end', cleanup);\n    source.removeListener('close', cleanup);\n\n    dest.removeListener('close', cleanup);\n  }\n\n  source.on('end', cleanup);\n  source.on('close', cleanup);\n\n  dest.on('close', cleanup);\n\n  dest.emit('pipe', source);\n\n  // Allow for unix-like usage: A.pipe(B).pipe(C)\n  return dest;\n};\n\n},{\"events\":48,\"inherits\":51,\"readable-stream/duplex.js\":68,\"readable-stream/passthrough.js\":75,\"readable-stream/readable.js\":76,\"readable-stream/transform.js\":77,\"readable-stream/writable.js\":78}],80:[function(require,module,exports){\n// Copyright Joyent, Inc. and other Node contributors.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a\n// copy of this software and associated documentation files (the\n// \"Software\"), to deal in the Software without restriction, including\n// without limitation the rights to use, copy, modify, merge, publish,\n// distribute, sublicense, and/or sell copies of the Software, and to permit\n// persons to whom the Software is furnished to do so, subject to the\n// following conditions:\n//\n// The above copyright notice and this permission notice shall be included\n// in all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS\n// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN\n// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,\n// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE\n// USE OR OTHER DEALINGS IN THE SOFTWARE.\n\nvar Buffer = require('buffer').Buffer;\n\nvar isBufferEncoding = Buffer.isEncoding\n  || function(encoding) {\n       switch (encoding && encoding.toLowerCase()) {\n         case 'hex': case 'utf8': case 'utf-8': case 'ascii': case 'binary': case 'base64': case 'ucs2': case 'ucs-2': case 'utf16le': case 'utf-16le': case 'raw': return true;\n         default: return false;\n       }\n     }\n\n\nfunction assertEncoding(encoding) {\n  if (encoding && !isBufferEncoding(encoding)) {\n    throw new Error('Unknown encoding: ' + encoding);\n  }\n}\n\n// StringDecoder provides an interface for efficiently splitting a series of\n// buffers into a series of JS strings without breaking apart multi-byte\n// characters. CESU-8 is handled as part of the UTF-8 encoding.\n//\n// @TODO Handling all encodings inside a single object makes it very difficult\n// to reason about this code, so it should be split up in the future.\n// @TODO There should be a utf8-strict encoding that rejects invalid UTF-8 code\n// points as used by CESU-8.\nvar StringDecoder = exports.StringDecoder = function(encoding) {\n  this.encoding = (encoding || 'utf8').toLowerCase().replace(/[-_]/, '');\n  assertEncoding(encoding);\n  switch (this.encoding) {\n    case 'utf8':\n      // CESU-8 represents each of Surrogate Pair by 3-bytes\n      this.surrogateSize = 3;\n      break;\n    case 'ucs2':\n    case 'utf16le':\n      // UTF-16 represents each of Surrogate Pair by 2-bytes\n      this.surrogateSize = 2;\n      this.detectIncompleteChar = utf16DetectIncompleteChar;\n      break;\n    case 'base64':\n      // Base-64 stores 3 bytes in 4 chars, and pads the remainder.\n      this.surrogateSize = 3;\n      this.detectIncompleteChar = base64DetectIncompleteChar;\n      break;\n    default:\n      this.write = passThroughWrite;\n      return;\n  }\n\n  // Enough space to store all bytes of a single character. UTF-8 needs 4\n  // bytes, but CESU-8 may require up to 6 (3 bytes per surrogate).\n  this.charBuffer = new Buffer(6);\n  // Number of bytes received for the current incomplete multi-byte character.\n  this.charReceived = 0;\n  // Number of bytes expected for the current incomplete multi-byte character.\n  this.charLength = 0;\n};\n\n\n// write decodes the given buffer and returns it as JS string that is\n// guaranteed to not contain any partial multi-byte characters. Any partial\n// character found at the end of the buffer is buffered up, and will be\n// returned when calling write again with the remaining bytes.\n//\n// Note: Converting a Buffer containing an orphan surrogate to a String\n// currently works, but converting a String to a Buffer (via `new Buffer`, or\n// Buffer#write) will replace incomplete surrogates with the unicode\n// replacement character. See https://codereview.chromium.org/121173009/ .\nStringDecoder.prototype.write = function(buffer) {\n  var charStr = '';\n  // if our last write ended with an incomplete multibyte character\n  while (this.charLength) {\n    // determine how many remaining bytes this buffer has to offer for this char\n    var available = (buffer.length >= this.charLength - this.charReceived) ?\n        this.charLength - this.charReceived :\n        buffer.length;\n\n    // add the new bytes to the char buffer\n    buffer.copy(this.charBuffer, this.charReceived, 0, available);\n    this.charReceived += available;\n\n    if (this.charReceived < this.charLength) {\n      // still not enough chars in this buffer? wait for more ...\n      return '';\n    }\n\n    // remove bytes belonging to the current character from the buffer\n    buffer = buffer.slice(available, buffer.length);\n\n    // get the character that was split\n    charStr = this.charBuffer.slice(0, this.charLength).toString(this.encoding);\n\n    // CESU-8: lead surrogate (D800-DBFF) is also the incomplete character\n    var charCode = charStr.charCodeAt(charStr.length - 1);\n    if (charCode >= 0xD800 && charCode <= 0xDBFF) {\n      this.charLength += this.surrogateSize;\n      charStr = '';\n      continue;\n    }\n    this.charReceived = this.charLength = 0;\n\n    // if there are no more bytes in this buffer, just emit our char\n    if (buffer.length === 0) {\n      return charStr;\n    }\n    break;\n  }\n\n  // determine and set charLength / charReceived\n  this.detectIncompleteChar(buffer);\n\n  var end = buffer.length;\n  if (this.charLength) {\n    // buffer the incomplete character bytes we got\n    buffer.copy(this.charBuffer, 0, buffer.length - this.charReceived, end);\n    end -= this.charReceived;\n  }\n\n  charStr += buffer.toString(this.encoding, 0, end);\n\n  var end = charStr.length - 1;\n  var charCode = charStr.charCodeAt(end);\n  // CESU-8: lead surrogate (D800-DBFF) is also the incomplete character\n  if (charCode >= 0xD800 && charCode <= 0xDBFF) {\n    var size = this.surrogateSize;\n    this.charLength += size;\n    this.charReceived += size;\n    this.charBuffer.copy(this.charBuffer, size, 0, size);\n    buffer.copy(this.charBuffer, 0, 0, size);\n    return charStr.substring(0, end);\n  }\n\n  // or just emit the charStr\n  return charStr;\n};\n\n// detectIncompleteChar determines if there is an incomplete UTF-8 character at\n// the end of the given buffer. If so, it sets this.charLength to the byte\n// length that character, and sets this.charReceived to the number of bytes\n// that are available for this character.\nStringDecoder.prototype.detectIncompleteChar = function(buffer) {\n  // determine how many bytes we have to check at the end of this buffer\n  var i = (buffer.length >= 3) ? 3 : buffer.length;\n\n  // Figure out if one of the last i bytes of our buffer announces an\n  // incomplete char.\n  for (; i > 0; i--) {\n    var c = buffer[buffer.length - i];\n\n    // See http://en.wikipedia.org/wiki/UTF-8#Description\n\n    // 110XXXXX\n    if (i == 1 && c >> 5 == 0x06) {\n      this.charLength = 2;\n      break;\n    }\n\n    // 1110XXXX\n    if (i <= 2 && c >> 4 == 0x0E) {\n      this.charLength = 3;\n      break;\n    }\n\n    // 11110XXX\n    if (i <= 3 && c >> 3 == 0x1E) {\n      this.charLength = 4;\n      break;\n    }\n  }\n  this.charReceived = i;\n};\n\nStringDecoder.prototype.end = function(buffer) {\n  var res = '';\n  if (buffer && buffer.length)\n    res = this.write(buffer);\n\n  if (this.charReceived) {\n    var cr = this.charReceived;\n    var buf = this.charBuffer;\n    var enc = this.encoding;\n    res += buf.slice(0, cr).toString(enc);\n  }\n\n  return res;\n};\n\nfunction passThroughWrite(buffer) {\n  return buffer.toString(this.encoding);\n}\n\nfunction utf16DetectIncompleteChar(buffer) {\n  this.charReceived = buffer.length % 2;\n  this.charLength = this.charReceived ? 2 : 0;\n}\n\nfunction base64DetectIncompleteChar(buffer) {\n  this.charReceived = buffer.length % 3;\n  this.charLength = this.charReceived ? 3 : 0;\n}\n\n},{\"buffer\":44}],81:[function(require,module,exports){\n(function (global){\n\n/**\n * Module exports.\n */\n\nmodule.exports = deprecate;\n\n/**\n * Mark that a method should not be used.\n * Returns a modified function which warns once by default.\n *\n * If `localStorage.noDeprecation = true` is set, then it is a no-op.\n *\n * If `localStorage.throwDeprecation = true` is set, then deprecated functions\n * will throw an Error when invoked.\n *\n * If `localStorage.traceDeprecation = true` is set, then deprecated functions\n * will invoke `console.trace()` instead of `console.error()`.\n *\n * @param {Function} fn - the function to deprecate\n * @param {String} msg - the string to print to the console when `fn` is invoked\n * @returns {Function} a new \"deprecated\" version of `fn`\n * @api public\n */\n\nfunction deprecate (fn, msg) {\n  if (config('noDeprecation')) {\n    return fn;\n  }\n\n  var warned = false;\n  function deprecated() {\n    if (!warned) {\n      if (config('throwDeprecation')) {\n        throw new Error(msg);\n      } else if (config('traceDeprecation')) {\n        console.trace(msg);\n      } else {\n        console.warn(msg);\n      }\n      warned = true;\n    }\n    return fn.apply(this, arguments);\n  }\n\n  return deprecated;\n}\n\n/**\n * Checks `localStorage` for boolean values for the given `name`.\n *\n * @param {String} name\n * @returns {Boolean}\n * @api private\n */\n\nfunction config (name) {\n  // accessing global.localStorage can trigger a DOMException in sandboxed iframes\n  try {\n    if (!global.localStorage) return false;\n  } catch (_) {\n    return false;\n  }\n  var val = global.localStorage[name];\n  if (null == val) return false;\n  return String(val).toLowerCase() === 'true';\n}\n\n}).call(this,typeof global !== \"undefined\" ? global : typeof self !== \"undefined\" ? self : typeof window !== \"undefined\" ? window : {})\n},{}],82:[function(require,module,exports){\narguments[4][51][0].apply(exports,arguments)\n},{\"dup\":51}],83:[function(require,module,exports){\nmodule.exports = function isBuffer(arg) {\n  return arg && typeof arg === 'object'\n    && typeof arg.copy === 'function'\n    && typeof arg.fill === 'function'\n    && typeof arg.readUInt8 === 'function';\n}\n},{}],84:[function(require,module,exports){\n(function (process,global){\n// Copyright Joyent, Inc. and other Node contributors.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a\n// copy of this software and associated documentation files (the\n// \"Software\"), to deal in the Software without restriction, including\n// without limitation the rights to use, copy, modify, merge, publish,\n// distribute, sublicense, and/or sell copies of the Software, and to permit\n// persons to whom the Software is furnished to do so, subject to the\n// following conditions:\n//\n// The above copyright notice and this permission notice shall be included\n// in all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS\n// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN\n// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,\n// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE\n// USE OR OTHER DEALINGS IN THE SOFTWARE.\n\nvar formatRegExp = /%[sdj%]/g;\nexports.format = function(f) {\n  if (!isString(f)) {\n    var objects = [];\n    for (var i = 0; i < arguments.length; i++) {\n      objects.push(inspect(arguments[i]));\n    }\n    return objects.join(' ');\n  }\n\n  var i = 1;\n  var args = arguments;\n  var len = args.length;\n  var str = String(f).replace(formatRegExp, function(x) {\n    if (x === '%%') return '%';\n    if (i >= len) return x;\n    switch (x) {\n      case '%s': return String(args[i++]);\n      case '%d': return Number(args[i++]);\n      case '%j':\n        try {\n          return JSON.stringify(args[i++]);\n        } catch (_) {\n          return '[Circular]';\n        }\n      default:\n        return x;\n    }\n  });\n  for (var x = args[i]; i < len; x = args[++i]) {\n    if (isNull(x) || !isObject(x)) {\n      str += ' ' + x;\n    } else {\n      str += ' ' + inspect(x);\n    }\n  }\n  return str;\n};\n\n\n// Mark that a method should not be used.\n// Returns a modified function which warns once by default.\n// If --no-deprecation is set, then it is a no-op.\nexports.deprecate = function(fn, msg) {\n  // Allow for deprecating things in the process of starting up.\n  if (isUndefined(global.process)) {\n    return function() {\n      return exports.deprecate(fn, msg).apply(this, arguments);\n    };\n  }\n\n  if (process.noDeprecation === true) {\n    return fn;\n  }\n\n  var warned = false;\n  function deprecated() {\n    if (!warned) {\n      if (process.throwDeprecation) {\n        throw new Error(msg);\n      } else if (process.traceDeprecation) {\n        console.trace(msg);\n      } else {\n        console.error(msg);\n      }\n      warned = true;\n    }\n    return fn.apply(this, arguments);\n  }\n\n  return deprecated;\n};\n\n\nvar debugs = {};\nvar debugEnviron;\nexports.debuglog = function(set) {\n  if (isUndefined(debugEnviron))\n    debugEnviron = process.env.NODE_DEBUG || '';\n  set = set.toUpperCase();\n  if (!debugs[set]) {\n    if (new RegExp('\\\\b' + set + '\\\\b', 'i').test(debugEnviron)) {\n      var pid = process.pid;\n      debugs[set] = function() {\n        var msg = exports.format.apply(exports, arguments);\n        console.error('%s %d: %s', set, pid, msg);\n      };\n    } else {\n      debugs[set] = function() {};\n    }\n  }\n  return debugs[set];\n};\n\n\n/**\n * Echos the value of a value. Trys to print the value out\n * in the best way possible given the different types.\n *\n * @param {Object} obj The object to print out.\n * @param {Object} opts Optional options object that alters the output.\n */\n/* legacy: obj, showHidden, depth, colors*/\nfunction inspect(obj, opts) {\n  // default options\n  var ctx = {\n    seen: [],\n    stylize: stylizeNoColor\n  };\n  // legacy...\n  if (arguments.length >= 3) ctx.depth = arguments[2];\n  if (arguments.length >= 4) ctx.colors = arguments[3];\n  if (isBoolean(opts)) {\n    // legacy...\n    ctx.showHidden = opts;\n  } else if (opts) {\n    // got an \"options\" object\n    exports._extend(ctx, opts);\n  }\n  // set default options\n  if (isUndefined(ctx.showHidden)) ctx.showHidden = false;\n  if (isUndefined(ctx.depth)) ctx.depth = 2;\n  if (isUndefined(ctx.colors)) ctx.colors = false;\n  if (isUndefined(ctx.customInspect)) ctx.customInspect = true;\n  if (ctx.colors) ctx.stylize = stylizeWithColor;\n  return formatValue(ctx, obj, ctx.depth);\n}\nexports.inspect = inspect;\n\n\n// http://en.wikipedia.org/wiki/ANSI_escape_code#graphics\ninspect.colors = {\n  'bold' : [1, 22],\n  'italic' : [3, 23],\n  'underline' : [4, 24],\n  'inverse' : [7, 27],\n  'white' : [37, 39],\n  'grey' : [90, 39],\n  'black' : [30, 39],\n  'blue' : [34, 39],\n  'cyan' : [36, 39],\n  'green' : [32, 39],\n  'magenta' : [35, 39],\n  'red' : [31, 39],\n  'yellow' : [33, 39]\n};\n\n// Don't use 'blue' not visible on cmd.exe\ninspect.styles = {\n  'special': 'cyan',\n  'number': 'yellow',\n  'boolean': 'yellow',\n  'undefined': 'grey',\n  'null': 'bold',\n  'string': 'green',\n  'date': 'magenta',\n  // \"name\": intentionally not styling\n  'regexp': 'red'\n};\n\n\nfunction stylizeWithColor(str, styleType) {\n  var style = inspect.styles[styleType];\n\n  if (style) {\n    return '\\u001b[' + inspect.colors[style][0] + 'm' + str +\n           '\\u001b[' + inspect.colors[style][1] + 'm';\n  } else {\n    return str;\n  }\n}\n\n\nfunction stylizeNoColor(str, styleType) {\n  return str;\n}\n\n\nfunction arrayToHash(array) {\n  var hash = {};\n\n  array.forEach(function(val, idx) {\n    hash[val] = true;\n  });\n\n  return hash;\n}\n\n\nfunction formatValue(ctx, value, recurseTimes) {\n  // Provide a hook for user-specified inspect functions.\n  // Check that value is an object with an inspect function on it\n  if (ctx.customInspect &&\n      value &&\n      isFunction(value.inspect) &&\n      // Filter out the util module, it's inspect function is special\n      value.inspect !== exports.inspect &&\n      // Also filter out any prototype objects using the circular check.\n      !(value.constructor && value.constructor.prototype === value)) {\n    var ret = value.inspect(recurseTimes, ctx);\n    if (!isString(ret)) {\n      ret = formatValue(ctx, ret, recurseTimes);\n    }\n    return ret;\n  }\n\n  // Primitive types cannot have properties\n  var primitive = formatPrimitive(ctx, value);\n  if (primitive) {\n    return primitive;\n  }\n\n  // Look up the keys of the object.\n  var keys = Object.keys(value);\n  var visibleKeys = arrayToHash(keys);\n\n  if (ctx.showHidden) {\n    keys = Object.getOwnPropertyNames(value);\n  }\n\n  // IE doesn't make error fields non-enumerable\n  // http://msdn.microsoft.com/en-us/library/ie/dww52sbt(v=vs.94).aspx\n  if (isError(value)\n      && (keys.indexOf('message') >= 0 || keys.indexOf('description') >= 0)) {\n    return formatError(value);\n  }\n\n  // Some type of object without properties can be shortcutted.\n  if (keys.length === 0) {\n    if (isFunction(value)) {\n      var name = value.name ? ': ' + value.name : '';\n      return ctx.stylize('[Function' + name + ']', 'special');\n    }\n    if (isRegExp(value)) {\n      return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp');\n    }\n    if (isDate(value)) {\n      return ctx.stylize(Date.prototype.toString.call(value), 'date');\n    }\n    if (isError(value)) {\n      return formatError(value);\n    }\n  }\n\n  var base = '', array = false, braces = ['{', '}'];\n\n  // Make Array say that they are Array\n  if (isArray(value)) {\n    array = true;\n    braces = ['[', ']'];\n  }\n\n  // Make functions say that they are functions\n  if (isFunction(value)) {\n    var n = value.name ? ': ' + value.name : '';\n    base = ' [Function' + n + ']';\n  }\n\n  // Make RegExps say that they are RegExps\n  if (isRegExp(value)) {\n    base = ' ' + RegExp.prototype.toString.call(value);\n  }\n\n  // Make dates with properties first say the date\n  if (isDate(value)) {\n    base = ' ' + Date.prototype.toUTCString.call(value);\n  }\n\n  // Make error with message first say the error\n  if (isError(value)) {\n    base = ' ' + formatError(value);\n  }\n\n  if (keys.length === 0 && (!array || value.length == 0)) {\n    return braces[0] + base + braces[1];\n  }\n\n  if (recurseTimes < 0) {\n    if (isRegExp(value)) {\n      return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp');\n    } else {\n      return ctx.stylize('[Object]', 'special');\n    }\n  }\n\n  ctx.seen.push(value);\n\n  var output;\n  if (array) {\n    output = formatArray(ctx, value, recurseTimes, visibleKeys, keys);\n  } else {\n    output = keys.map(function(key) {\n      return formatProperty(ctx, value, recurseTimes, visibleKeys, key, array);\n    });\n  }\n\n  ctx.seen.pop();\n\n  return reduceToSingleString(output, base, braces);\n}\n\n\nfunction formatPrimitive(ctx, value) {\n  if (isUndefined(value))\n    return ctx.stylize('undefined', 'undefined');\n  if (isString(value)) {\n    var simple = '\\'' + JSON.stringify(value).replace(/^\"|\"$/g, '')\n                                             .replace(/'/g, \"\\\\'\")\n                                             .replace(/\\\\\"/g, '\"') + '\\'';\n    return ctx.stylize(simple, 'string');\n  }\n  if (isNumber(value))\n    return ctx.stylize('' + value, 'number');\n  if (isBoolean(value))\n    return ctx.stylize('' + value, 'boolean');\n  // For some reason typeof null is \"object\", so special case here.\n  if (isNull(value))\n    return ctx.stylize('null', 'null');\n}\n\n\nfunction formatError(value) {\n  return '[' + Error.prototype.toString.call(value) + ']';\n}\n\n\nfunction formatArray(ctx, value, recurseTimes, visibleKeys, keys) {\n  var output = [];\n  for (var i = 0, l = value.length; i < l; ++i) {\n    if (hasOwnProperty(value, String(i))) {\n      output.push(formatProperty(ctx, value, recurseTimes, visibleKeys,\n          String(i), true));\n    } else {\n      output.push('');\n    }\n  }\n  keys.forEach(function(key) {\n    if (!key.match(/^\\d+$/)) {\n      output.push(formatProperty(ctx, value, recurseTimes, visibleKeys,\n          key, true));\n    }\n  });\n  return output;\n}\n\n\nfunction formatProperty(ctx, value, recurseTimes, visibleKeys, key, array) {\n  var name, str, desc;\n  desc = Object.getOwnPropertyDescriptor(value, key) || { value: value[key] };\n  if (desc.get) {\n    if (desc.set) {\n      str = ctx.stylize('[Getter/Setter]', 'special');\n    } else {\n      str = ctx.stylize('[Getter]', 'special');\n    }\n  } else {\n    if (desc.set) {\n      str = ctx.stylize('[Setter]', 'special');\n    }\n  }\n  if (!hasOwnProperty(visibleKeys, key)) {\n    name = '[' + key + ']';\n  }\n  if (!str) {\n    if (ctx.seen.indexOf(desc.value) < 0) {\n      if (isNull(recurseTimes)) {\n        str = formatValue(ctx, desc.value, null);\n      } else {\n        str = formatValue(ctx, desc.value, recurseTimes - 1);\n      }\n      if (str.indexOf('\\n') > -1) {\n        if (array) {\n          str = str.split('\\n').map(function(line) {\n            return '  ' + line;\n          }).join('\\n').substr(2);\n        } else {\n          str = '\\n' + str.split('\\n').map(function(line) {\n            return '   ' + line;\n          }).join('\\n');\n        }\n      }\n    } else {\n      str = ctx.stylize('[Circular]', 'special');\n    }\n  }\n  if (isUndefined(name)) {\n    if (array && key.match(/^\\d+$/)) {\n      return str;\n    }\n    name = JSON.stringify('' + key);\n    if (name.match(/^\"([a-zA-Z_][a-zA-Z_0-9]*)\"$/)) {\n      name = name.substr(1, name.length - 2);\n      name = ctx.stylize(name, 'name');\n    } else {\n      name = name.replace(/'/g, \"\\\\'\")\n                 .replace(/\\\\\"/g, '\"')\n                 .replace(/(^\"|\"$)/g, \"'\");\n      name = ctx.stylize(name, 'string');\n    }\n  }\n\n  return name + ': ' + str;\n}\n\n\nfunction reduceToSingleString(output, base, braces) {\n  var numLinesEst = 0;\n  var length = output.reduce(function(prev, cur) {\n    numLinesEst++;\n    if (cur.indexOf('\\n') >= 0) numLinesEst++;\n    return prev + cur.replace(/\\u001b\\[\\d\\d?m/g, '').length + 1;\n  }, 0);\n\n  if (length > 60) {\n    return braces[0] +\n           (base === '' ? '' : base + '\\n ') +\n           ' ' +\n           output.join(',\\n  ') +\n           ' ' +\n           braces[1];\n  }\n\n  return braces[0] + base + ' ' + output.join(', ') + ' ' + braces[1];\n}\n\n\n// NOTE: These type checking functions intentionally don't use `instanceof`\n// because it is fragile and can be easily faked with `Object.create()`.\nfunction isArray(ar) {\n  return Array.isArray(ar);\n}\nexports.isArray = isArray;\n\nfunction isBoolean(arg) {\n  return typeof arg === 'boolean';\n}\nexports.isBoolean = isBoolean;\n\nfunction isNull(arg) {\n  return arg === null;\n}\nexports.isNull = isNull;\n\nfunction isNullOrUndefined(arg) {\n  return arg == null;\n}\nexports.isNullOrUndefined = isNullOrUndefined;\n\nfunction isNumber(arg) {\n  return typeof arg === 'number';\n}\nexports.isNumber = isNumber;\n\nfunction isString(arg) {\n  return typeof arg === 'string';\n}\nexports.isString = isString;\n\nfunction isSymbol(arg) {\n  return typeof arg === 'symbol';\n}\nexports.isSymbol = isSymbol;\n\nfunction isUndefined(arg) {\n  return arg === void 0;\n}\nexports.isUndefined = isUndefined;\n\nfunction isRegExp(re) {\n  return isObject(re) && objectToString(re) === '[object RegExp]';\n}\nexports.isRegExp = isRegExp;\n\nfunction isObject(arg) {\n  return typeof arg === 'object' && arg !== null;\n}\nexports.isObject = isObject;\n\nfunction isDate(d) {\n  return isObject(d) && objectToString(d) === '[object Date]';\n}\nexports.isDate = isDate;\n\nfunction isError(e) {\n  return isObject(e) &&\n      (objectToString(e) === '[object Error]' || e instanceof Error);\n}\nexports.isError = isError;\n\nfunction isFunction(arg) {\n  return typeof arg === 'function';\n}\nexports.isFunction = isFunction;\n\nfunction isPrimitive(arg) {\n  return arg === null ||\n         typeof arg === 'boolean' ||\n         typeof arg === 'number' ||\n         typeof arg === 'string' ||\n         typeof arg === 'symbol' ||  // ES6 symbol\n         typeof arg === 'undefined';\n}\nexports.isPrimitive = isPrimitive;\n\nexports.isBuffer = require('./support/isBuffer');\n\nfunction objectToString(o) {\n  return Object.prototype.toString.call(o);\n}\n\n\nfunction pad(n) {\n  return n < 10 ? '0' + n.toString(10) : n.toString(10);\n}\n\n\nvar months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep',\n              'Oct', 'Nov', 'Dec'];\n\n// 26 Feb 16:19:34\nfunction timestamp() {\n  var d = new Date();\n  var time = [pad(d.getHours()),\n              pad(d.getMinutes()),\n              pad(d.getSeconds())].join(':');\n  return [d.getDate(), months[d.getMonth()], time].join(' ');\n}\n\n\n// log is just a thin wrapper to console.log that prepends a timestamp\nexports.log = function() {\n  console.log('%s - %s', timestamp(), exports.format.apply(exports, arguments));\n};\n\n\n/**\n * Inherit the prototype methods from one constructor into another.\n *\n * The Function.prototype.inherits from lang.js rewritten as a standalone\n * function (not on Function.prototype). NOTE: If this file is to be loaded\n * during bootstrapping this function needs to be rewritten using some native\n * functions as prototype setup using normal JavaScript does not work as\n * expected during bootstrapping (see mirror.js in r114903).\n *\n * @param {function} ctor Constructor function which needs to inherit the\n *     prototype.\n * @param {function} superCtor Constructor function to inherit prototype from.\n */\nexports.inherits = require('inherits');\n\nexports._extend = function(origin, add) {\n  // Don't do anything if add isn't an object\n  if (!add || !isObject(add)) return origin;\n\n  var keys = Object.keys(add);\n  var i = keys.length;\n  while (i--) {\n    origin[keys[i]] = add[keys[i]];\n  }\n  return origin;\n};\n\nfunction hasOwnProperty(obj, prop) {\n  return Object.prototype.hasOwnProperty.call(obj, prop);\n}\n\n}).call(this,require('_process'),typeof global !== \"undefined\" ? global : typeof self !== \"undefined\" ? self : typeof window !== \"undefined\" ? window : {})\n},{\"./support/isBuffer\":83,\"_process\":67,\"inherits\":82}]},{},[1]);\n"
  },
  {
    "path": "app_backend/static/plugin/Lightbox/lightbox.js",
    "content": "/*!\n * Lightbox v2.8.2\n * by Lokesh Dhakar\n *\n * More info:\n * http://lokeshdhakar.com/projects/lightbox2/\n *\n * Copyright 2007, 2015 Lokesh Dhakar\n * Released under the MIT license\n * https://github.com/lokesh/lightbox2/blob/master/LICENSE\n */\n\n// Uses Node, AMD or browser globals to create a module.\n(function (root, factory) {\n    if (typeof define === 'function' && define.amd) {\n        // AMD. Register as an anonymous module.\n        define(['jquery'], factory);\n    } else if (typeof exports === 'object') {\n        // Node. Does not work with strict CommonJS, but\n        // only CommonJS-like environments that support module.exports,\n        // like Node.\n        module.exports = factory(require('jquery'));\n    } else {\n        // Browser globals (root is window)\n        root.lightbox = factory(root.jQuery);\n    }\n}(this, function ($) {\n\n  function Lightbox(options) {\n    this.album = [];\n    this.currentImageIndex = void 0;\n    this.init();\n\n    // options\n    this.options = $.extend({}, this.constructor.defaults);\n    this.option(options);\n  }\n\n  // Descriptions of all options available on the demo site:\n  // http://lokeshdhakar.com/projects/lightbox2/index.html#options\n  Lightbox.defaults = {\n    albumLabel: 'Image %1 of %2',\n    alwaysShowNavOnTouchDevices: false,\n    fadeDuration: 500,\n    fitImagesInViewport: true,\n    // maxWidth: 800,\n    // maxHeight: 600,\n    positionFromTop: 50,\n    resizeDuration: 700,\n    showImageNumberLabel: true,\n    wrapAround: false,\n    disableScrolling: false\n  };\n\n  Lightbox.prototype.option = function(options) {\n    $.extend(this.options, options);\n  };\n\n  Lightbox.prototype.imageCountLabel = function(currentImageNum, totalImages) {\n    return this.options.albumLabel.replace(/%1/g, currentImageNum).replace(/%2/g, totalImages);\n  };\n\n  Lightbox.prototype.init = function() {\n    this.enable();\n    this.build();\n  };\n\n  // Loop through anchors and areamaps looking for either data-lightbox attributes or rel attributes\n  // that contain 'lightbox'. When these are clicked, start lightbox.\n  Lightbox.prototype.enable = function() {\n    var self = this;\n    $('body').on('click', 'a[rel^=lightbox], area[rel^=lightbox], a[data-lightbox], area[data-lightbox]', function(event) {\n      self.start($(event.currentTarget));\n      return false;\n    });\n  };\n\n  // Build html for the lightbox and the overlay.\n  // Attach event handlers to the new DOM elements. click click click\n  Lightbox.prototype.build = function() {\n    var self = this;\n    $('<div id=\"lightboxOverlay\" class=\"lightboxOverlay\"></div><div id=\"lightbox\" class=\"lightbox\"><div class=\"lb-outerContainer\"><div class=\"lb-container\"><img class=\"lb-image\" src=\"data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw==\" /><div class=\"lb-nav\"><a class=\"lb-prev\" href=\"\" ></a><a class=\"lb-next\" href=\"\" ></a></div><div class=\"lb-loader\"><a class=\"lb-cancel\"></a></div></div></div><div class=\"lb-dataContainer\"><div class=\"lb-data\"><div class=\"lb-details\"><span class=\"lb-caption\"></span><span class=\"lb-number\"></span></div><div class=\"lb-closeContainer\"><a class=\"lb-close\"></a></div></div></div></div>').appendTo($('body'));\n\n    // Cache jQuery objects\n    this.$lightbox       = $('#lightbox');\n    this.$overlay        = $('#lightboxOverlay');\n    this.$outerContainer = this.$lightbox.find('.lb-outerContainer');\n    this.$container      = this.$lightbox.find('.lb-container');\n\n    // Store css values for future lookup\n    this.containerTopPadding = parseInt(this.$container.css('padding-top'), 10);\n    this.containerRightPadding = parseInt(this.$container.css('padding-right'), 10);\n    this.containerBottomPadding = parseInt(this.$container.css('padding-bottom'), 10);\n    this.containerLeftPadding = parseInt(this.$container.css('padding-left'), 10);\n\n    // Attach event handlers to the newly minted DOM elements\n    this.$overlay.hide().on('click', function() {\n      self.end();\n      return false;\n    });\n\n    this.$lightbox.hide().on('click', function(event) {\n      if ($(event.target).attr('id') === 'lightbox') {\n        self.end();\n      }\n      return false;\n    });\n\n    this.$outerContainer.on('click', function(event) {\n      if ($(event.target).attr('id') === 'lightbox') {\n        self.end();\n      }\n      return false;\n    });\n\n    this.$lightbox.find('.lb-prev').on('click', function() {\n      if (self.currentImageIndex === 0) {\n        self.changeImage(self.album.length - 1);\n      } else {\n        self.changeImage(self.currentImageIndex - 1);\n      }\n      return false;\n    });\n\n    this.$lightbox.find('.lb-next').on('click', function() {\n      if (self.currentImageIndex === self.album.length - 1) {\n        self.changeImage(0);\n      } else {\n        self.changeImage(self.currentImageIndex + 1);\n      }\n      return false;\n    });\n\n    this.$lightbox.find('.lb-loader, .lb-close').on('click', function() {\n      self.end();\n      return false;\n    });\n  };\n\n  // Show overlay and lightbox. If the image is part of a set, add siblings to album array.\n  Lightbox.prototype.start = function($link) {\n    var self    = this;\n    var $window = $(window);\n\n    $window.on('resize', $.proxy(this.sizeOverlay, this));\n\n    $('select, object, embed').css({\n      visibility: 'hidden'\n    });\n\n    this.sizeOverlay();\n\n    this.album = [];\n    var imageNumber = 0;\n\n    function addToAlbum($link) {\n      self.album.push({\n        link: $link.attr('href'),\n        title: $link.attr('data-title') || $link.attr('title')\n      });\n    }\n\n    // Support both data-lightbox attribute and rel attribute implementations\n    var dataLightboxValue = $link.attr('data-lightbox');\n    var $links;\n\n    if (dataLightboxValue) {\n      $links = $($link.prop('tagName') + '[data-lightbox=\"' + dataLightboxValue + '\"]');\n      for (var i = 0; i < $links.length; i = ++i) {\n        addToAlbum($($links[i]));\n        if ($links[i] === $link[0]) {\n          imageNumber = i;\n        }\n      }\n    } else {\n      if ($link.attr('rel') === 'lightbox') {\n        // If image is not part of a set\n        addToAlbum($link);\n      } else {\n        // If image is part of a set\n        $links = $($link.prop('tagName') + '[rel=\"' + $link.attr('rel') + '\"]');\n        for (var j = 0; j < $links.length; j = ++j) {\n          addToAlbum($($links[j]));\n          if ($links[j] === $link[0]) {\n            imageNumber = j;\n          }\n        }\n      }\n    }\n\n    // Position Lightbox\n    var top  = $window.scrollTop() + this.options.positionFromTop;\n    var left = $window.scrollLeft();\n    this.$lightbox.css({\n      top: top + 'px',\n      left: left + 'px'\n    }).fadeIn(this.options.fadeDuration);\n\n    // Disable scrolling of the page while open\n    if (this.options.disableScrolling) {\n      $('body').addClass('lb-disable-scrolling');\n    }\n\n    this.changeImage(imageNumber);\n  };\n\n  // Hide most UI elements in preparation for the animated resizing of the lightbox.\n  Lightbox.prototype.changeImage = function(imageNumber) {\n    var self = this;\n\n    this.disableKeyboardNav();\n    var $image = this.$lightbox.find('.lb-image');\n\n    this.$overlay.fadeIn(this.options.fadeDuration);\n\n    $('.lb-loader').fadeIn('slow');\n    this.$lightbox.find('.lb-image, .lb-nav, .lb-prev, .lb-next, .lb-dataContainer, .lb-numbers, .lb-caption').hide();\n\n    this.$outerContainer.addClass('animating');\n\n    // When image to show is preloaded, we send the width and height to sizeContainer()\n    var preloader = new Image();\n    preloader.onload = function() {\n      var $preloader;\n      var imageHeight;\n      var imageWidth;\n      var maxImageHeight;\n      var maxImageWidth;\n      var windowHeight;\n      var windowWidth;\n\n      $image.attr('src', self.album[imageNumber].link);\n\n      $preloader = $(preloader);\n\n      $image.width(preloader.width);\n      $image.height(preloader.height);\n\n      if (self.options.fitImagesInViewport) {\n        // Fit image inside the viewport.\n        // Take into account the border around the image and an additional 10px gutter on each side.\n\n        windowWidth    = $(window).width();\n        windowHeight   = $(window).height();\n        maxImageWidth  = windowWidth - self.containerLeftPadding - self.containerRightPadding - 20;\n        maxImageHeight = windowHeight - self.containerTopPadding - self.containerBottomPadding - 120;\n\n        // Check if image size is larger then maxWidth|maxHeight in settings\n        if (self.options.maxWidth && self.options.maxWidth < maxImageWidth) {\n          maxImageWidth = self.options.maxWidth;\n        }\n        if (self.options.maxHeight && self.options.maxHeight < maxImageWidth) {\n          maxImageHeight = self.options.maxHeight;\n        }\n\n        // Is there a fitting issue?\n        if ((preloader.width > maxImageWidth) || (preloader.height > maxImageHeight)) {\n          if ((preloader.width / maxImageWidth) > (preloader.height / maxImageHeight)) {\n            imageWidth  = maxImageWidth;\n            imageHeight = parseInt(preloader.height / (preloader.width / imageWidth), 10);\n            $image.width(imageWidth);\n            $image.height(imageHeight);\n          } else {\n            imageHeight = maxImageHeight;\n            imageWidth = parseInt(preloader.width / (preloader.height / imageHeight), 10);\n            $image.width(imageWidth);\n            $image.height(imageHeight);\n          }\n        }\n      }\n      self.sizeContainer($image.width(), $image.height());\n    };\n\n    preloader.src          = this.album[imageNumber].link;\n    this.currentImageIndex = imageNumber;\n  };\n\n  // Stretch overlay to fit the viewport\n  Lightbox.prototype.sizeOverlay = function() {\n    this.$overlay\n      .width($(document).width())\n      .height($(document).height());\n  };\n\n  // Animate the size of the lightbox to fit the image we are showing\n  Lightbox.prototype.sizeContainer = function(imageWidth, imageHeight) {\n    var self = this;\n\n    var oldWidth  = this.$outerContainer.outerWidth();\n    var oldHeight = this.$outerContainer.outerHeight();\n    var newWidth  = imageWidth + this.containerLeftPadding + this.containerRightPadding;\n    var newHeight = imageHeight + this.containerTopPadding + this.containerBottomPadding;\n\n    function postResize() {\n      self.$lightbox.find('.lb-dataContainer').width(newWidth);\n      self.$lightbox.find('.lb-prevLink').height(newHeight);\n      self.$lightbox.find('.lb-nextLink').height(newHeight);\n      self.showImage();\n    }\n\n    if (oldWidth !== newWidth || oldHeight !== newHeight) {\n      this.$outerContainer.animate({\n        width: newWidth,\n        height: newHeight\n      }, this.options.resizeDuration, 'swing', function() {\n        postResize();\n      });\n    } else {\n      postResize();\n    }\n  };\n\n  // Display the image and its details and begin preload neighboring images.\n  Lightbox.prototype.showImage = function() {\n    this.$lightbox.find('.lb-loader').stop(true).hide();\n    this.$lightbox.find('.lb-image').fadeIn('slow');\n\n    this.updateNav();\n    this.updateDetails();\n    this.preloadNeighboringImages();\n    this.enableKeyboardNav();\n  };\n\n  // Display previous and next navigation if appropriate.\n  Lightbox.prototype.updateNav = function() {\n    // Check to see if the browser supports touch events. If so, we take the conservative approach\n    // and assume that mouse hover events are not supported and always show prev/next navigation\n    // arrows in image sets.\n    var alwaysShowNav = false;\n    try {\n      document.createEvent('TouchEvent');\n      alwaysShowNav = (this.options.alwaysShowNavOnTouchDevices) ? true : false;\n    } catch (e) {}\n\n    this.$lightbox.find('.lb-nav').show();\n\n    if (this.album.length > 1) {\n      if (this.options.wrapAround) {\n        if (alwaysShowNav) {\n          this.$lightbox.find('.lb-prev, .lb-next').css('opacity', '1');\n        }\n        this.$lightbox.find('.lb-prev, .lb-next').show();\n      } else {\n        if (this.currentImageIndex > 0) {\n          this.$lightbox.find('.lb-prev').show();\n          if (alwaysShowNav) {\n            this.$lightbox.find('.lb-prev').css('opacity', '1');\n          }\n        }\n        if (this.currentImageIndex < this.album.length - 1) {\n          this.$lightbox.find('.lb-next').show();\n          if (alwaysShowNav) {\n            this.$lightbox.find('.lb-next').css('opacity', '1');\n          }\n        }\n      }\n    }\n  };\n\n  // Display caption, image number, and closing button.\n  Lightbox.prototype.updateDetails = function() {\n    var self = this;\n\n    // Enable anchor clicks in the injected caption html.\n    // Thanks Nate Wright for the fix. @https://github.com/NateWr\n    if (typeof this.album[this.currentImageIndex].title !== 'undefined' &&\n      this.album[this.currentImageIndex].title !== '') {\n      this.$lightbox.find('.lb-caption')\n        .html(this.album[this.currentImageIndex].title)\n        .fadeIn('fast')\n        .find('a').on('click', function(event) {\n          if ($(this).attr('target') !== undefined) {\n            window.open($(this).attr('href'), $(this).attr('target'));\n          } else {\n            location.href = $(this).attr('href');\n          }\n        });\n    }\n\n    if (this.album.length > 1 && this.options.showImageNumberLabel) {\n      var labelText = this.imageCountLabel(this.currentImageIndex + 1, this.album.length);\n      this.$lightbox.find('.lb-number').text(labelText).fadeIn('fast');\n    } else {\n      this.$lightbox.find('.lb-number').hide();\n    }\n\n    this.$outerContainer.removeClass('animating');\n\n    this.$lightbox.find('.lb-dataContainer').fadeIn(this.options.resizeDuration, function() {\n      return self.sizeOverlay();\n    });\n  };\n\n  // Preload previous and next images in set.\n  Lightbox.prototype.preloadNeighboringImages = function() {\n    if (this.album.length > this.currentImageIndex + 1) {\n      var preloadNext = new Image();\n      preloadNext.src = this.album[this.currentImageIndex + 1].link;\n    }\n    if (this.currentImageIndex > 0) {\n      var preloadPrev = new Image();\n      preloadPrev.src = this.album[this.currentImageIndex - 1].link;\n    }\n  };\n\n  Lightbox.prototype.enableKeyboardNav = function() {\n    $(document).on('keyup.keyboard', $.proxy(this.keyboardAction, this));\n  };\n\n  Lightbox.prototype.disableKeyboardNav = function() {\n    $(document).off('.keyboard');\n  };\n\n  Lightbox.prototype.keyboardAction = function(event) {\n    var KEYCODE_ESC        = 27;\n    var KEYCODE_LEFTARROW  = 37;\n    var KEYCODE_RIGHTARROW = 39;\n\n    var keycode = event.keyCode;\n    var key     = String.fromCharCode(keycode).toLowerCase();\n    if (keycode === KEYCODE_ESC || key.match(/x|o|c/)) {\n      this.end();\n    } else if (key === 'p' || keycode === KEYCODE_LEFTARROW) {\n      if (this.currentImageIndex !== 0) {\n        this.changeImage(this.currentImageIndex - 1);\n      } else if (this.options.wrapAround && this.album.length > 1) {\n        this.changeImage(this.album.length - 1);\n      }\n    } else if (key === 'n' || keycode === KEYCODE_RIGHTARROW) {\n      if (this.currentImageIndex !== this.album.length - 1) {\n        this.changeImage(this.currentImageIndex + 1);\n      } else if (this.options.wrapAround && this.album.length > 1) {\n        this.changeImage(0);\n      }\n    }\n  };\n\n  // Closing time. :-(\n  Lightbox.prototype.end = function() {\n    this.disableKeyboardNav();\n    $(window).off('resize', this.sizeOverlay);\n    this.$lightbox.fadeOut(this.options.fadeDuration);\n    this.$overlay.fadeOut(this.options.fadeDuration);\n    $('select, object, embed').css({\n      visibility: 'visible'\n    });\n    if (this.options.disableScrolling) {\n      $('body').removeClass('lb-disable-scrolling');\n    }\n  };\n\n  return new Lightbox();\n}));\n"
  },
  {
    "path": "app_backend/static/plugin/Slideout/slideout.js",
    "content": "!function(e){if(\"object\"==typeof exports&&\"undefined\"!=typeof module)module.exports=e();else if(\"function\"==typeof define&&define.amd)define([],e);else{var f;\"undefined\"!=typeof window?f=window:\"undefined\"!=typeof global?f=global:\"undefined\"!=typeof self&&(f=self),f.Slideout=e()}}(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require==\"function\"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error(\"Cannot find module '\"+o+\"'\");throw f.code=\"MODULE_NOT_FOUND\",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require==\"function\"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){\n'use strict';\n\n/**\n * Module dependencies\n */\nvar decouple = require('decouple');\nvar Emitter = require('emitter');\n\n/**\n * Privates\n */\nvar scrollTimeout;\nvar scrolling = false;\nvar doc = window.document;\nvar html = doc.documentElement;\nvar msPointerSupported = window.navigator.msPointerEnabled;\nvar touch = {\n  'start': msPointerSupported ? 'MSPointerDown' : 'touchstart',\n  'move': msPointerSupported ? 'MSPointerMove' : 'touchmove',\n  'end': msPointerSupported ? 'MSPointerUp' : 'touchend'\n};\nvar prefix = (function prefix() {\n  var regex = /^(Webkit|Khtml|Moz|ms|O)(?=[A-Z])/;\n  var styleDeclaration = doc.getElementsByTagName('script')[0].style;\n  for (var prop in styleDeclaration) {\n    if (regex.test(prop)) {\n      return '-' + prop.match(regex)[0].toLowerCase() + '-';\n    }\n  }\n  // Nothing found so far? Webkit does not enumerate over the CSS properties of the style object.\n  // However (prop in style) returns the correct value, so we'll have to test for\n  // the precence of a specific property\n  if ('WebkitOpacity' in styleDeclaration) { return '-webkit-'; }\n  if ('KhtmlOpacity' in styleDeclaration) { return '-khtml-'; }\n  return '';\n}());\nfunction extend(destination, from) {\n  for (var prop in from) {\n    if (from[prop]) {\n      destination[prop] = from[prop];\n    }\n  }\n  return destination;\n}\nfunction inherits(child, uber) {\n  child.prototype = extend(child.prototype || {}, uber.prototype);\n}\n\n/**\n * Slideout constructor\n */\nfunction Slideout(options) {\n  options = options || {};\n\n  // Sets default values\n  this._startOffsetX = 0;\n  this._currentOffsetX = 0;\n  this._opening = false;\n  this._moved = false;\n  this._opened = false;\n  this._preventOpen = false;\n  this._touch = options.touch === undefined ? true : options.touch && true;\n\n  // Sets panel\n  this.panel = options.panel;\n  this.menu = options.menu;\n\n  // Sets  classnames\n  if(this.panel.className.search('slideout-panel') === -1) { this.panel.className += ' slideout-panel'; }\n  if(this.menu.className.search('slideout-menu') === -1) { this.menu.className += ' slideout-menu'; }\n\n\n  // Sets options\n  this._fx = options.fx || 'ease';\n  this._duration = parseInt(options.duration, 10) || 300;\n  this._tolerance = parseInt(options.tolerance, 10) || 70;\n  this._padding = this._translateTo = parseInt(options.padding, 10) || 256;\n  this._orientation = options.side === 'right' ? -1 : 1;\n  this._translateTo *= this._orientation;\n\n  // Init touch events\n  if (this._touch) {\n    this._initTouchEvents();\n  }\n}\n\n/**\n * Inherits from Emitter\n */\ninherits(Slideout, Emitter);\n\n/**\n * Opens the slideout menu.\n */\nSlideout.prototype.open = function() {\n  var self = this;\n  this.emit('beforeopen');\n  if (html.className.search('slideout-open') === -1) { html.className += ' slideout-open'; }\n  this._setTransition();\n  this._translateXTo(this._translateTo);\n  this._opened = true;\n  setTimeout(function() {\n    self.panel.style.transition = self.panel.style['-webkit-transition'] = '';\n    self.emit('open');\n  }, this._duration + 50);\n  return this;\n};\n\n/**\n * Closes slideout menu.\n */\nSlideout.prototype.close = function() {\n  var self = this;\n  if (!this.isOpen() && !this._opening) {\n    return this;\n  }\n  this.emit('beforeclose');\n  this._setTransition();\n  this._translateXTo(0);\n  this._opened = false;\n  setTimeout(function() {\n    html.className = html.className.replace(/ slideout-open/, '');\n    self.panel.style.transition = self.panel.style['-webkit-transition'] = self.panel.style[prefix + 'transform'] = self.panel.style.transform = '';\n    self.emit('close');\n  }, this._duration + 50);\n  return this;\n};\n\n/**\n * Toggles (open/close) slideout menu.\n */\nSlideout.prototype.toggle = function() {\n  return this.isOpen() ? this.close() : this.open();\n};\n\n/**\n * Returns true if the slideout is currently open, and false if it is closed.\n */\nSlideout.prototype.isOpen = function() {\n  return this._opened;\n};\n\n/**\n * Translates panel and updates currentOffset with a given X point\n */\nSlideout.prototype._translateXTo = function(translateX) {\n  this._currentOffsetX = translateX;\n  this.panel.style[prefix + 'transform'] = this.panel.style.transform = 'translateX(' + translateX + 'px)';\n  return this;\n};\n\n/**\n * Set transition properties\n */\nSlideout.prototype._setTransition = function() {\n  this.panel.style[prefix + 'transition'] = this.panel.style.transition = prefix + 'transform ' + this._duration + 'ms ' + this._fx;\n  return this;\n};\n\n/**\n * Initializes touch event\n */\nSlideout.prototype._initTouchEvents = function() {\n  var self = this;\n\n  /**\n   * Decouple scroll event\n   */\n  this._onScrollFn = decouple(doc, 'scroll', function() {\n    if (!self._moved) {\n      clearTimeout(scrollTimeout);\n      scrolling = true;\n      scrollTimeout = setTimeout(function() {\n        scrolling = false;\n      }, 250);\n    }\n  });\n\n  /**\n   * Prevents touchmove event if slideout is moving\n   */\n  this._preventMove = function(eve) {\n    if (self._moved) {\n      eve.preventDefault();\n    }\n  };\n\n  doc.addEventListener(touch.move, this._preventMove);\n\n  /**\n   * Resets values on touchstart\n   */\n  this._resetTouchFn = function(eve) {\n    if (typeof eve.touches === 'undefined') {\n      return;\n    }\n\n    self._moved = false;\n    self._opening = false;\n    self._startOffsetX = eve.touches[0].pageX;\n    self._preventOpen = (!self._touch || (!self.isOpen() && self.menu.clientWidth !== 0));\n  };\n\n  this.panel.addEventListener(touch.start, this._resetTouchFn);\n\n  /**\n   * Resets values on touchcancel\n   */\n  this._onTouchCancelFn = function() {\n    self._moved = false;\n    self._opening = false;\n  };\n\n  this.panel.addEventListener('touchcancel', this._onTouchCancelFn);\n\n  /**\n   * Toggles slideout on touchend\n   */\n  this._onTouchEndFn = function() {\n    if (self._moved) {\n      (self._opening && Math.abs(self._currentOffsetX) > self._tolerance) ? self.open() : self.close();\n    }\n    self._moved = false;\n  };\n\n  this.panel.addEventListener(touch.end, this._onTouchEndFn);\n\n  /**\n   * Translates panel on touchmove\n   */\n  this._onTouchMoveFn = function(eve) {\n\n    if (scrolling || self._preventOpen || typeof eve.touches === 'undefined') {\n      return;\n    }\n\n    var dif_x = eve.touches[0].clientX - self._startOffsetX;\n    var translateX = self._currentOffsetX = dif_x;\n\n    if (Math.abs(translateX) > self._padding) {\n      return;\n    }\n\n    if (Math.abs(dif_x) > 20) {\n\n      self._opening = true;\n\n      var oriented_dif_x = dif_x * self._orientation;\n\n      if (self._opened && oriented_dif_x > 0 || !self._opened && oriented_dif_x < 0) {\n        return;\n      }\n\n      if (oriented_dif_x <= 0) {\n        translateX = dif_x + self._padding * self._orientation;\n        self._opening = false;\n      }\n\n      if (!self._moved && html.className.search('slideout-open') === -1) {\n        html.className += ' slideout-open';\n      }\n\n      self.panel.style[prefix + 'transform'] = self.panel.style.transform = 'translateX(' + translateX + 'px)';\n      self.emit('translate', translateX);\n      self._moved = true;\n    }\n\n  };\n\n  this.panel.addEventListener(touch.move, this._onTouchMoveFn);\n\n  return this;\n};\n\n/**\n * Enable opening the slideout via touch events.\n */\nSlideout.prototype.enableTouch = function() {\n  this._touch = true;\n  return this;\n};\n\n/**\n * Disable opening the slideout via touch events.\n */\nSlideout.prototype.disableTouch = function() {\n  this._touch = false;\n  return this;\n};\n\n/**\n * Destroy an instance of slideout.\n */\nSlideout.prototype.destroy = function() {\n  // Close before clean\n  this.close();\n\n  // Remove event listeners\n  doc.removeEventListener(touch.move, this._preventMove);\n  this.panel.removeEventListener(touch.start, this._resetTouchFn);\n  this.panel.removeEventListener('touchcancel', this._onTouchCancelFn);\n  this.panel.removeEventListener(touch.end, this._onTouchEndFn);\n  this.panel.removeEventListener(touch.move, this._onTouchMoveFn);\n  doc.removeEventListener('scroll', this._onScrollFn);\n\n  // Remove methods\n  this.open = this.close = function() {};\n\n  // Return the instance so it can be easily dereferenced\n  return this;\n};\n\n/**\n * Expose Slideout\n */\nmodule.exports = Slideout;\n\n},{\"decouple\":2,\"emitter\":3}],2:[function(require,module,exports){\n'use strict';\n\nvar requestAnimFrame = (function() {\n  return window.requestAnimationFrame ||\n    window.webkitRequestAnimationFrame ||\n    function (callback) {\n      window.setTimeout(callback, 1000 / 60);\n    };\n}());\n\nfunction decouple(node, event, fn) {\n  var eve,\n      tracking = false;\n\n  function captureEvent(e) {\n    eve = e;\n    track();\n  }\n\n  function track() {\n    if (!tracking) {\n      requestAnimFrame(update);\n      tracking = true;\n    }\n  }\n\n  function update() {\n    fn.call(node, eve);\n    tracking = false;\n  }\n\n  node.addEventListener(event, captureEvent, false);\n\n  return captureEvent;\n}\n\n/**\n * Expose decouple\n */\nmodule.exports = decouple;\n\n},{}],3:[function(require,module,exports){\n\"use strict\";\n\nvar _classCallCheck = function (instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } };\n\nexports.__esModule = true;\n/**\n * Creates a new instance of Emitter.\n * @class\n * @returns {Object} Returns a new instance of Emitter.\n * @example\n * // Creates a new instance of Emitter.\n * var Emitter = require('emitter');\n *\n * var emitter = new Emitter();\n */\n\nvar Emitter = (function () {\n  function Emitter() {\n    _classCallCheck(this, Emitter);\n  }\n\n  /**\n   * Adds a listener to the collection for the specified event.\n   * @memberof! Emitter.prototype\n   * @function\n   * @param {String} event - The event name.\n   * @param {Function} listener - A listener function to add.\n   * @returns {Object} Returns an instance of Emitter.\n   * @example\n   * // Add an event listener to \"foo\" event.\n   * emitter.on('foo', listener);\n   */\n\n  Emitter.prototype.on = function on(event, listener) {\n    // Use the current collection or create it.\n    this._eventCollection = this._eventCollection || {};\n\n    // Use the current collection of an event or create it.\n    this._eventCollection[event] = this._eventCollection[event] || [];\n\n    // Appends the listener into the collection of the given event\n    this._eventCollection[event].push(listener);\n\n    return this;\n  };\n\n  /**\n   * Adds a listener to the collection for the specified event that will be called only once.\n   * @memberof! Emitter.prototype\n   * @function\n   * @param {String} event - The event name.\n   * @param {Function} listener - A listener function to add.\n   * @returns {Object} Returns an instance of Emitter.\n   * @example\n   * // Will add an event handler to \"foo\" event once.\n   * emitter.once('foo', listener);\n   */\n\n  Emitter.prototype.once = function once(event, listener) {\n    var self = this;\n\n    function fn() {\n      self.off(event, fn);\n      listener.apply(this, arguments);\n    }\n\n    fn.listener = listener;\n\n    this.on(event, fn);\n\n    return this;\n  };\n\n  /**\n   * Removes a listener from the collection for the specified event.\n   * @memberof! Emitter.prototype\n   * @function\n   * @param {String} event - The event name.\n   * @param {Function} listener - A listener function to remove.\n   * @returns {Object} Returns an instance of Emitter.\n   * @example\n   * // Remove a given listener.\n   * emitter.off('foo', listener);\n   */\n\n  Emitter.prototype.off = function off(event, listener) {\n\n    var listeners = undefined;\n\n    // Defines listeners value.\n    if (!this._eventCollection || !(listeners = this._eventCollection[event])) {\n      return this;\n    }\n\n    listeners.forEach(function (fn, i) {\n      if (fn === listener || fn.listener === listener) {\n        // Removes the given listener.\n        listeners.splice(i, 1);\n      }\n    });\n\n    // Removes an empty event collection.\n    if (listeners.length === 0) {\n      delete this._eventCollection[event];\n    }\n\n    return this;\n  };\n\n  /**\n   * Execute each item in the listener collection in order with the specified data.\n   * @memberof! Emitter.prototype\n   * @function\n   * @param {String} event - The name of the event you want to emit.\n   * @param {...Object} data - Data to pass to the listeners.\n   * @returns {Object} Returns an instance of Emitter.\n   * @example\n   * // Emits the \"foo\" event with 'param1' and 'param2' as arguments.\n   * emitter.emit('foo', 'param1', 'param2');\n   */\n\n  Emitter.prototype.emit = function emit(event) {\n    var _this = this;\n\n    for (var _len = arguments.length, args = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {\n      args[_key - 1] = arguments[_key];\n    }\n\n    var listeners = undefined;\n\n    // Defines listeners value.\n    if (!this._eventCollection || !(listeners = this._eventCollection[event])) {\n      return this;\n    }\n\n    // Clone listeners\n    listeners = listeners.slice(0);\n\n    listeners.forEach(function (fn) {\n      return fn.apply(_this, args);\n    });\n\n    return this;\n  };\n\n  return Emitter;\n})();\n\n/**\n * Exports Emitter\n */\nexports[\"default\"] = Emitter;\nmodule.exports = exports[\"default\"];\n},{}]},{},[1])(1)\n});\n//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIm5vZGVfbW9kdWxlcy9icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9icm93c2VyLXBhY2svX3ByZWx1ZGUuanMiLCJpbmRleC5qcyIsIm5vZGVfbW9kdWxlcy9kZWNvdXBsZS9pbmRleC5qcyIsIm5vZGVfbW9kdWxlcy9lbWl0dGVyL2Rpc3QvaW5kZXguanMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7QUNBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzVUQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3hDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EiLCJmaWxlIjoiZ2VuZXJhdGVkLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXNDb250ZW50IjpbIihmdW5jdGlvbiBlKHQsbixyKXtmdW5jdGlvbiBzKG8sdSl7aWYoIW5bb10pe2lmKCF0W29dKXt2YXIgYT10eXBlb2YgcmVxdWlyZT09XCJmdW5jdGlvblwiJiZyZXF1aXJlO2lmKCF1JiZhKXJldHVybiBhKG8sITApO2lmKGkpcmV0dXJuIGkobywhMCk7dmFyIGY9bmV3IEVycm9yKFwiQ2Fubm90IGZpbmQgbW9kdWxlICdcIitvK1wiJ1wiKTt0aHJvdyBmLmNvZGU9XCJNT0RVTEVfTk9UX0ZPVU5EXCIsZn12YXIgbD1uW29dPXtleHBvcnRzOnt9fTt0W29dWzBdLmNhbGwobC5leHBvcnRzLGZ1bmN0aW9uKGUpe3ZhciBuPXRbb11bMV1bZV07cmV0dXJuIHMobj9uOmUpfSxsLGwuZXhwb3J0cyxlLHQsbixyKX1yZXR1cm4gbltvXS5leHBvcnRzfXZhciBpPXR5cGVvZiByZXF1aXJlPT1cImZ1bmN0aW9uXCImJnJlcXVpcmU7Zm9yKHZhciBvPTA7bzxyLmxlbmd0aDtvKyspcyhyW29dKTtyZXR1cm4gc30pIiwiJ3VzZSBzdHJpY3QnO1xuXG4vKipcbiAqIE1vZHVsZSBkZXBlbmRlbmNpZXNcbiAqL1xudmFyIGRlY291cGxlID0gcmVxdWlyZSgnZGVjb3VwbGUnKTtcbnZhciBFbWl0dGVyID0gcmVxdWlyZSgnZW1pdHRlcicpO1xuXG4vKipcbiAqIFByaXZhdGVzXG4gKi9cbnZhciBzY3JvbGxUaW1lb3V0O1xudmFyIHNjcm9sbGluZyA9IGZhbHNlO1xudmFyIGRvYyA9IHdpbmRvdy5kb2N1bWVudDtcbnZhciBodG1sID0gZG9jLmRvY3VtZW50RWxlbWVudDtcbnZhciBtc1BvaW50ZXJTdXBwb3J0ZWQgPSB3aW5kb3cubmF2aWdhdG9yLm1zUG9pbnRlckVuYWJsZWQ7XG52YXIgdG91Y2ggPSB7XG4gICdzdGFydCc6IG1zUG9pbnRlclN1cHBvcnRlZCA/ICdNU1BvaW50ZXJEb3duJyA6ICd0b3VjaHN0YXJ0JyxcbiAgJ21vdmUnOiBtc1BvaW50ZXJTdXBwb3J0ZWQgPyAnTVNQb2ludGVyTW92ZScgOiAndG91Y2htb3ZlJyxcbiAgJ2VuZCc6IG1zUG9pbnRlclN1cHBvcnRlZCA/ICdNU1BvaW50ZXJVcCcgOiAndG91Y2hlbmQnXG59O1xudmFyIHByZWZpeCA9IChmdW5jdGlvbiBwcmVmaXgoKSB7XG4gIHZhciByZWdleCA9IC9eKFdlYmtpdHxLaHRtbHxNb3p8bXN8TykoPz1bQS1aXSkvO1xuICB2YXIgc3R5bGVEZWNsYXJhdGlvbiA9IGRvYy5nZXRFbGVtZW50c0J5VGFnTmFtZSgnc2NyaXB0JylbMF0uc3R5bGU7XG4gIGZvciAodmFyIHByb3AgaW4gc3R5bGVEZWNsYXJhdGlvbikge1xuICAgIGlmIChyZWdleC50ZXN0KHByb3ApKSB7XG4gICAgICByZXR1cm4gJy0nICsgcHJvcC5tYXRjaChyZWdleClbMF0udG9Mb3dlckNhc2UoKSArICctJztcbiAgICB9XG4gIH1cbiAgLy8gTm90aGluZyBmb3VuZCBzbyBmYXI/IFdlYmtpdCBkb2VzIG5vdCBlbnVtZXJhdGUgb3ZlciB0aGUgQ1NTIHByb3BlcnRpZXMgb2YgdGhlIHN0eWxlIG9iamVjdC5cbiAgLy8gSG93ZXZlciAocHJvcCBpbiBzdHlsZSkgcmV0dXJucyB0aGUgY29ycmVjdCB2YWx1ZSwgc28gd2UnbGwgaGF2ZSB0byB0ZXN0IGZvclxuICAvLyB0aGUgcHJlY2VuY2Ugb2YgYSBzcGVjaWZpYyBwcm9wZXJ0eVxuICBpZiAoJ1dlYmtpdE9wYWNpdHknIGluIHN0eWxlRGVjbGFyYXRpb24pIHsgcmV0dXJuICctd2Via2l0LSc7IH1cbiAgaWYgKCdLaHRtbE9wYWNpdHknIGluIHN0eWxlRGVjbGFyYXRpb24pIHsgcmV0dXJuICcta2h0bWwtJzsgfVxuICByZXR1cm4gJyc7XG59KCkpO1xuZnVuY3Rpb24gZXh0ZW5kKGRlc3RpbmF0aW9uLCBmcm9tKSB7XG4gIGZvciAodmFyIHByb3AgaW4gZnJvbSkge1xuICAgIGlmIChmcm9tW3Byb3BdKSB7XG4gICAgICBkZXN0aW5hdGlvbltwcm9wXSA9IGZyb21bcHJvcF07XG4gICAgfVxuICB9XG4gIHJldHVybiBkZXN0aW5hdGlvbjtcbn1cbmZ1bmN0aW9uIGluaGVyaXRzKGNoaWxkLCB1YmVyKSB7XG4gIGNoaWxkLnByb3RvdHlwZSA9IGV4dGVuZChjaGlsZC5wcm90b3R5cGUgfHwge30sIHViZXIucHJvdG90eXBlKTtcbn1cblxuLyoqXG4gKiBTbGlkZW91dCBjb25zdHJ1Y3RvclxuICovXG5mdW5jdGlvbiBTbGlkZW91dChvcHRpb25zKSB7XG4gIG9wdGlvbnMgPSBvcHRpb25zIHx8IHt9O1xuXG4gIC8vIFNldHMgZGVmYXVsdCB2YWx1ZXNcbiAgdGhpcy5fc3RhcnRPZmZzZXRYID0gMDtcbiAgdGhpcy5fY3VycmVudE9mZnNldFggPSAwO1xuICB0aGlzLl9vcGVuaW5nID0gZmFsc2U7XG4gIHRoaXMuX21vdmVkID0gZmFsc2U7XG4gIHRoaXMuX29wZW5lZCA9IGZhbHNlO1xuICB0aGlzLl9wcmV2ZW50T3BlbiA9IGZhbHNlO1xuICB0aGlzLl90b3VjaCA9IG9wdGlvbnMudG91Y2ggPT09IHVuZGVmaW5lZCA/IHRydWUgOiBvcHRpb25zLnRvdWNoICYmIHRydWU7XG5cbiAgLy8gU2V0cyBwYW5lbFxuICB0aGlzLnBhbmVsID0gb3B0aW9ucy5wYW5lbDtcbiAgdGhpcy5tZW51ID0gb3B0aW9ucy5tZW51O1xuXG4gIC8vIFNldHMgIGNsYXNzbmFtZXNcbiAgaWYodGhpcy5wYW5lbC5jbGFzc05hbWUuc2VhcmNoKCdzbGlkZW91dC1wYW5lbCcpID09PSAtMSkgeyB0aGlzLnBhbmVsLmNsYXNzTmFtZSArPSAnIHNsaWRlb3V0LXBhbmVsJzsgfVxuICBpZih0aGlzLm1lbnUuY2xhc3NOYW1lLnNlYXJjaCgnc2xpZGVvdXQtbWVudScpID09PSAtMSkgeyB0aGlzLm1lbnUuY2xhc3NOYW1lICs9ICcgc2xpZGVvdXQtbWVudSc7IH1cblxuXG4gIC8vIFNldHMgb3B0aW9uc1xuICB0aGlzLl9meCA9IG9wdGlvbnMuZnggfHwgJ2Vhc2UnO1xuICB0aGlzLl9kdXJhdGlvbiA9IHBhcnNlSW50KG9wdGlvbnMuZHVyYXRpb24sIDEwKSB8fCAzMDA7XG4gIHRoaXMuX3RvbGVyYW5jZSA9IHBhcnNlSW50KG9wdGlvbnMudG9sZXJhbmNlLCAxMCkgfHwgNzA7XG4gIHRoaXMuX3BhZGRpbmcgPSB0aGlzLl90cmFuc2xhdGVUbyA9IHBhcnNlSW50KG9wdGlvbnMucGFkZGluZywgMTApIHx8IDI1NjtcbiAgdGhpcy5fb3JpZW50YXRpb24gPSBvcHRpb25zLnNpZGUgPT09ICdyaWdodCcgPyAtMSA6IDE7XG4gIHRoaXMuX3RyYW5zbGF0ZVRvICo9IHRoaXMuX29yaWVudGF0aW9uO1xuXG4gIC8vIEluaXQgdG91Y2ggZXZlbnRzXG4gIGlmICh0aGlzLl90b3VjaCkge1xuICAgIHRoaXMuX2luaXRUb3VjaEV2ZW50cygpO1xuICB9XG59XG5cbi8qKlxuICogSW5oZXJpdHMgZnJvbSBFbWl0dGVyXG4gKi9cbmluaGVyaXRzKFNsaWRlb3V0LCBFbWl0dGVyKTtcblxuLyoqXG4gKiBPcGVucyB0aGUgc2xpZGVvdXQgbWVudS5cbiAqL1xuU2xpZGVvdXQucHJvdG90eXBlLm9wZW4gPSBmdW5jdGlvbigpIHtcbiAgdmFyIHNlbGYgPSB0aGlzO1xuICB0aGlzLmVtaXQoJ2JlZm9yZW9wZW4nKTtcbiAgaWYgKGh0bWwuY2xhc3NOYW1lLnNlYXJjaCgnc2xpZGVvdXQtb3BlbicpID09PSAtMSkgeyBodG1sLmNsYXNzTmFtZSArPSAnIHNsaWRlb3V0LW9wZW4nOyB9XG4gIHRoaXMuX3NldFRyYW5zaXRpb24oKTtcbiAgdGhpcy5fdHJhbnNsYXRlWFRvKHRoaXMuX3RyYW5zbGF0ZVRvKTtcbiAgdGhpcy5fb3BlbmVkID0gdHJ1ZTtcbiAgc2V0VGltZW91dChmdW5jdGlvbigpIHtcbiAgICBzZWxmLnBhbmVsLnN0eWxlLnRyYW5zaXRpb24gPSBzZWxmLnBhbmVsLnN0eWxlWyctd2Via2l0LXRyYW5zaXRpb24nXSA9ICcnO1xuICAgIHNlbGYuZW1pdCgnb3BlbicpO1xuICB9LCB0aGlzLl9kdXJhdGlvbiArIDUwKTtcbiAgcmV0dXJuIHRoaXM7XG59O1xuXG4vKipcbiAqIENsb3NlcyBzbGlkZW91dCBtZW51LlxuICovXG5TbGlkZW91dC5wcm90b3R5cGUuY2xvc2UgPSBmdW5jdGlvbigpIHtcbiAgdmFyIHNlbGYgPSB0aGlzO1xuICBpZiAoIXRoaXMuaXNPcGVuKCkgJiYgIXRoaXMuX29wZW5pbmcpIHtcbiAgICByZXR1cm4gdGhpcztcbiAgfVxuICB0aGlzLmVtaXQoJ2JlZm9yZWNsb3NlJyk7XG4gIHRoaXMuX3NldFRyYW5zaXRpb24oKTtcbiAgdGhpcy5fdHJhbnNsYXRlWFRvKDApO1xuICB0aGlzLl9vcGVuZWQgPSBmYWxzZTtcbiAgc2V0VGltZW91dChmdW5jdGlvbigpIHtcbiAgICBodG1sLmNsYXNzTmFtZSA9IGh0bWwuY2xhc3NOYW1lLnJlcGxhY2UoLyBzbGlkZW91dC1vcGVuLywgJycpO1xuICAgIHNlbGYucGFuZWwuc3R5bGUudHJhbnNpdGlvbiA9IHNlbGYucGFuZWwuc3R5bGVbJy13ZWJraXQtdHJhbnNpdGlvbiddID0gc2VsZi5wYW5lbC5zdHlsZVtwcmVmaXggKyAndHJhbnNmb3JtJ10gPSBzZWxmLnBhbmVsLnN0eWxlLnRyYW5zZm9ybSA9ICcnO1xuICAgIHNlbGYuZW1pdCgnY2xvc2UnKTtcbiAgfSwgdGhpcy5fZHVyYXRpb24gKyA1MCk7XG4gIHJldHVybiB0aGlzO1xufTtcblxuLyoqXG4gKiBUb2dnbGVzIChvcGVuL2Nsb3NlKSBzbGlkZW91dCBtZW51LlxuICovXG5TbGlkZW91dC5wcm90b3R5cGUudG9nZ2xlID0gZnVuY3Rpb24oKSB7XG4gIHJldHVybiB0aGlzLmlzT3BlbigpID8gdGhpcy5jbG9zZSgpIDogdGhpcy5vcGVuKCk7XG59O1xuXG4vKipcbiAqIFJldHVybnMgdHJ1ZSBpZiB0aGUgc2xpZGVvdXQgaXMgY3VycmVudGx5IG9wZW4sIGFuZCBmYWxzZSBpZiBpdCBpcyBjbG9zZWQuXG4gKi9cblNsaWRlb3V0LnByb3RvdHlwZS5pc09wZW4gPSBmdW5jdGlvbigpIHtcbiAgcmV0dXJuIHRoaXMuX29wZW5lZDtcbn07XG5cbi8qKlxuICogVHJhbnNsYXRlcyBwYW5lbCBhbmQgdXBkYXRlcyBjdXJyZW50T2Zmc2V0IHdpdGggYSBnaXZlbiBYIHBvaW50XG4gKi9cblNsaWRlb3V0LnByb3RvdHlwZS5fdHJhbnNsYXRlWFRvID0gZnVuY3Rpb24odHJhbnNsYXRlWCkge1xuICB0aGlzLl9jdXJyZW50T2Zmc2V0WCA9IHRyYW5zbGF0ZVg7XG4gIHRoaXMucGFuZWwuc3R5bGVbcHJlZml4ICsgJ3RyYW5zZm9ybSddID0gdGhpcy5wYW5lbC5zdHlsZS50cmFuc2Zvcm0gPSAndHJhbnNsYXRlWCgnICsgdHJhbnNsYXRlWCArICdweCknO1xuICByZXR1cm4gdGhpcztcbn07XG5cbi8qKlxuICogU2V0IHRyYW5zaXRpb24gcHJvcGVydGllc1xuICovXG5TbGlkZW91dC5wcm90b3R5cGUuX3NldFRyYW5zaXRpb24gPSBmdW5jdGlvbigpIHtcbiAgdGhpcy5wYW5lbC5zdHlsZVtwcmVmaXggKyAndHJhbnNpdGlvbiddID0gdGhpcy5wYW5lbC5zdHlsZS50cmFuc2l0aW9uID0gcHJlZml4ICsgJ3RyYW5zZm9ybSAnICsgdGhpcy5fZHVyYXRpb24gKyAnbXMgJyArIHRoaXMuX2Z4O1xuICByZXR1cm4gdGhpcztcbn07XG5cbi8qKlxuICogSW5pdGlhbGl6ZXMgdG91Y2ggZXZlbnRcbiAqL1xuU2xpZGVvdXQucHJvdG90eXBlLl9pbml0VG91Y2hFdmVudHMgPSBmdW5jdGlvbigpIHtcbiAgdmFyIHNlbGYgPSB0aGlzO1xuXG4gIC8qKlxuICAgKiBEZWNvdXBsZSBzY3JvbGwgZXZlbnRcbiAgICovXG4gIHRoaXMuX29uU2Nyb2xsRm4gPSBkZWNvdXBsZShkb2MsICdzY3JvbGwnLCBmdW5jdGlvbigpIHtcbiAgICBpZiAoIXNlbGYuX21vdmVkKSB7XG4gICAgICBjbGVhclRpbWVvdXQoc2Nyb2xsVGltZW91dCk7XG4gICAgICBzY3JvbGxpbmcgPSB0cnVlO1xuICAgICAgc2Nyb2xsVGltZW91dCA9IHNldFRpbWVvdXQoZnVuY3Rpb24oKSB7XG4gICAgICAgIHNjcm9sbGluZyA9IGZhbHNlO1xuICAgICAgfSwgMjUwKTtcbiAgICB9XG4gIH0pO1xuXG4gIC8qKlxuICAgKiBQcmV2ZW50cyB0b3VjaG1vdmUgZXZlbnQgaWYgc2xpZGVvdXQgaXMgbW92aW5nXG4gICAqL1xuICB0aGlzLl9wcmV2ZW50TW92ZSA9IGZ1bmN0aW9uKGV2ZSkge1xuICAgIGlmIChzZWxmLl9tb3ZlZCkge1xuICAgICAgZXZlLnByZXZlbnREZWZhdWx0KCk7XG4gICAgfVxuICB9O1xuXG4gIGRvYy5hZGRFdmVudExpc3RlbmVyKHRvdWNoLm1vdmUsIHRoaXMuX3ByZXZlbnRNb3ZlKTtcblxuICAvKipcbiAgICogUmVzZXRzIHZhbHVlcyBvbiB0b3VjaHN0YXJ0XG4gICAqL1xuICB0aGlzLl9yZXNldFRvdWNoRm4gPSBmdW5jdGlvbihldmUpIHtcbiAgICBpZiAodHlwZW9mIGV2ZS50b3VjaGVzID09PSAndW5kZWZpbmVkJykge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHNlbGYuX21vdmVkID0gZmFsc2U7XG4gICAgc2VsZi5fb3BlbmluZyA9IGZhbHNlO1xuICAgIHNlbGYuX3N0YXJ0T2Zmc2V0WCA9IGV2ZS50b3VjaGVzWzBdLnBhZ2VYO1xuICAgIHNlbGYuX3ByZXZlbnRPcGVuID0gKCFzZWxmLl90b3VjaCB8fCAoIXNlbGYuaXNPcGVuKCkgJiYgc2VsZi5tZW51LmNsaWVudFdpZHRoICE9PSAwKSk7XG4gIH07XG5cbiAgdGhpcy5wYW5lbC5hZGRFdmVudExpc3RlbmVyKHRvdWNoLnN0YXJ0LCB0aGlzLl9yZXNldFRvdWNoRm4pO1xuXG4gIC8qKlxuICAgKiBSZXNldHMgdmFsdWVzIG9uIHRvdWNoY2FuY2VsXG4gICAqL1xuICB0aGlzLl9vblRvdWNoQ2FuY2VsRm4gPSBmdW5jdGlvbigpIHtcbiAgICBzZWxmLl9tb3ZlZCA9IGZhbHNlO1xuICAgIHNlbGYuX29wZW5pbmcgPSBmYWxzZTtcbiAgfTtcblxuICB0aGlzLnBhbmVsLmFkZEV2ZW50TGlzdGVuZXIoJ3RvdWNoY2FuY2VsJywgdGhpcy5fb25Ub3VjaENhbmNlbEZuKTtcblxuICAvKipcbiAgICogVG9nZ2xlcyBzbGlkZW91dCBvbiB0b3VjaGVuZFxuICAgKi9cbiAgdGhpcy5fb25Ub3VjaEVuZEZuID0gZnVuY3Rpb24oKSB7XG4gICAgaWYgKHNlbGYuX21vdmVkKSB7XG4gICAgICAoc2VsZi5fb3BlbmluZyAmJiBNYXRoLmFicyhzZWxmLl9jdXJyZW50T2Zmc2V0WCkgPiBzZWxmLl90b2xlcmFuY2UpID8gc2VsZi5vcGVuKCkgOiBzZWxmLmNsb3NlKCk7XG4gICAgfVxuICAgIHNlbGYuX21vdmVkID0gZmFsc2U7XG4gIH07XG5cbiAgdGhpcy5wYW5lbC5hZGRFdmVudExpc3RlbmVyKHRvdWNoLmVuZCwgdGhpcy5fb25Ub3VjaEVuZEZuKTtcblxuICAvKipcbiAgICogVHJhbnNsYXRlcyBwYW5lbCBvbiB0b3VjaG1vdmVcbiAgICovXG4gIHRoaXMuX29uVG91Y2hNb3ZlRm4gPSBmdW5jdGlvbihldmUpIHtcblxuICAgIGlmIChzY3JvbGxpbmcgfHwgc2VsZi5fcHJldmVudE9wZW4gfHwgdHlwZW9mIGV2ZS50b3VjaGVzID09PSAndW5kZWZpbmVkJykge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHZhciBkaWZfeCA9IGV2ZS50b3VjaGVzWzBdLmNsaWVudFggLSBzZWxmLl9zdGFydE9mZnNldFg7XG4gICAgdmFyIHRyYW5zbGF0ZVggPSBzZWxmLl9jdXJyZW50T2Zmc2V0WCA9IGRpZl94O1xuXG4gICAgaWYgKE1hdGguYWJzKHRyYW5zbGF0ZVgpID4gc2VsZi5fcGFkZGluZykge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGlmIChNYXRoLmFicyhkaWZfeCkgPiAyMCkge1xuXG4gICAgICBzZWxmLl9vcGVuaW5nID0gdHJ1ZTtcblxuICAgICAgdmFyIG9yaWVudGVkX2RpZl94ID0gZGlmX3ggKiBzZWxmLl9vcmllbnRhdGlvbjtcblxuICAgICAgaWYgKHNlbGYuX29wZW5lZCAmJiBvcmllbnRlZF9kaWZfeCA+IDAgfHwgIXNlbGYuX29wZW5lZCAmJiBvcmllbnRlZF9kaWZfeCA8IDApIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICBpZiAob3JpZW50ZWRfZGlmX3ggPD0gMCkge1xuICAgICAgICB0cmFuc2xhdGVYID0gZGlmX3ggKyBzZWxmLl9wYWRkaW5nICogc2VsZi5fb3JpZW50YXRpb247XG4gICAgICAgIHNlbGYuX29wZW5pbmcgPSBmYWxzZTtcbiAgICAgIH1cblxuICAgICAgaWYgKCFzZWxmLl9tb3ZlZCAmJiBodG1sLmNsYXNzTmFtZS5zZWFyY2goJ3NsaWRlb3V0LW9wZW4nKSA9PT0gLTEpIHtcbiAgICAgICAgaHRtbC5jbGFzc05hbWUgKz0gJyBzbGlkZW91dC1vcGVuJztcbiAgICAgIH1cblxuICAgICAgc2VsZi5wYW5lbC5zdHlsZVtwcmVmaXggKyAndHJhbnNmb3JtJ10gPSBzZWxmLnBhbmVsLnN0eWxlLnRyYW5zZm9ybSA9ICd0cmFuc2xhdGVYKCcgKyB0cmFuc2xhdGVYICsgJ3B4KSc7XG4gICAgICBzZWxmLmVtaXQoJ3RyYW5zbGF0ZScsIHRyYW5zbGF0ZVgpO1xuICAgICAgc2VsZi5fbW92ZWQgPSB0cnVlO1xuICAgIH1cblxuICB9O1xuXG4gIHRoaXMucGFuZWwuYWRkRXZlbnRMaXN0ZW5lcih0b3VjaC5tb3ZlLCB0aGlzLl9vblRvdWNoTW92ZUZuKTtcblxuICByZXR1cm4gdGhpcztcbn07XG5cbi8qKlxuICogRW5hYmxlIG9wZW5pbmcgdGhlIHNsaWRlb3V0IHZpYSB0b3VjaCBldmVudHMuXG4gKi9cblNsaWRlb3V0LnByb3RvdHlwZS5lbmFibGVUb3VjaCA9IGZ1bmN0aW9uKCkge1xuICB0aGlzLl90b3VjaCA9IHRydWU7XG4gIHJldHVybiB0aGlzO1xufTtcblxuLyoqXG4gKiBEaXNhYmxlIG9wZW5pbmcgdGhlIHNsaWRlb3V0IHZpYSB0b3VjaCBldmVudHMuXG4gKi9cblNsaWRlb3V0LnByb3RvdHlwZS5kaXNhYmxlVG91Y2ggPSBmdW5jdGlvbigpIHtcbiAgdGhpcy5fdG91Y2ggPSBmYWxzZTtcbiAgcmV0dXJuIHRoaXM7XG59O1xuXG4vKipcbiAqIERlc3Ryb3kgYW4gaW5zdGFuY2Ugb2Ygc2xpZGVvdXQuXG4gKi9cblNsaWRlb3V0LnByb3RvdHlwZS5kZXN0cm95ID0gZnVuY3Rpb24oKSB7XG4gIC8vIENsb3NlIGJlZm9yZSBjbGVhblxuICB0aGlzLmNsb3NlKCk7XG5cbiAgLy8gUmVtb3ZlIGV2ZW50IGxpc3RlbmVyc1xuICBkb2MucmVtb3ZlRXZlbnRMaXN0ZW5lcih0b3VjaC5tb3ZlLCB0aGlzLl9wcmV2ZW50TW92ZSk7XG4gIHRoaXMucGFuZWwucmVtb3ZlRXZlbnRMaXN0ZW5lcih0b3VjaC5zdGFydCwgdGhpcy5fcmVzZXRUb3VjaEZuKTtcbiAgdGhpcy5wYW5lbC5yZW1vdmVFdmVudExpc3RlbmVyKCd0b3VjaGNhbmNlbCcsIHRoaXMuX29uVG91Y2hDYW5jZWxGbik7XG4gIHRoaXMucGFuZWwucmVtb3ZlRXZlbnRMaXN0ZW5lcih0b3VjaC5lbmQsIHRoaXMuX29uVG91Y2hFbmRGbik7XG4gIHRoaXMucGFuZWwucmVtb3ZlRXZlbnRMaXN0ZW5lcih0b3VjaC5tb3ZlLCB0aGlzLl9vblRvdWNoTW92ZUZuKTtcbiAgZG9jLnJlbW92ZUV2ZW50TGlzdGVuZXIoJ3Njcm9sbCcsIHRoaXMuX29uU2Nyb2xsRm4pO1xuXG4gIC8vIFJlbW92ZSBtZXRob2RzXG4gIHRoaXMub3BlbiA9IHRoaXMuY2xvc2UgPSBmdW5jdGlvbigpIHt9O1xuXG4gIC8vIFJldHVybiB0aGUgaW5zdGFuY2Ugc28gaXQgY2FuIGJlIGVhc2lseSBkZXJlZmVyZW5jZWRcbiAgcmV0dXJuIHRoaXM7XG59O1xuXG4vKipcbiAqIEV4cG9zZSBTbGlkZW91dFxuICovXG5tb2R1bGUuZXhwb3J0cyA9IFNsaWRlb3V0O1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgcmVxdWVzdEFuaW1GcmFtZSA9IChmdW5jdGlvbigpIHtcbiAgcmV0dXJuIHdpbmRvdy5yZXF1ZXN0QW5pbWF0aW9uRnJhbWUgfHxcbiAgICB3aW5kb3cud2Via2l0UmVxdWVzdEFuaW1hdGlvbkZyYW1lIHx8XG4gICAgZnVuY3Rpb24gKGNhbGxiYWNrKSB7XG4gICAgICB3aW5kb3cuc2V0VGltZW91dChjYWxsYmFjaywgMTAwMCAvIDYwKTtcbiAgICB9O1xufSgpKTtcblxuZnVuY3Rpb24gZGVjb3VwbGUobm9kZSwgZXZlbnQsIGZuKSB7XG4gIHZhciBldmUsXG4gICAgICB0cmFja2luZyA9IGZhbHNlO1xuXG4gIGZ1bmN0aW9uIGNhcHR1cmVFdmVudChlKSB7XG4gICAgZXZlID0gZTtcbiAgICB0cmFjaygpO1xuICB9XG5cbiAgZnVuY3Rpb24gdHJhY2soKSB7XG4gICAgaWYgKCF0cmFja2luZykge1xuICAgICAgcmVxdWVzdEFuaW1GcmFtZSh1cGRhdGUpO1xuICAgICAgdHJhY2tpbmcgPSB0cnVlO1xuICAgIH1cbiAgfVxuXG4gIGZ1bmN0aW9uIHVwZGF0ZSgpIHtcbiAgICBmbi5jYWxsKG5vZGUsIGV2ZSk7XG4gICAgdHJhY2tpbmcgPSBmYWxzZTtcbiAgfVxuXG4gIG5vZGUuYWRkRXZlbnRMaXN0ZW5lcihldmVudCwgY2FwdHVyZUV2ZW50LCBmYWxzZSk7XG5cbiAgcmV0dXJuIGNhcHR1cmVFdmVudDtcbn1cblxuLyoqXG4gKiBFeHBvc2UgZGVjb3VwbGVcbiAqL1xubW9kdWxlLmV4cG9ydHMgPSBkZWNvdXBsZTtcbiIsIlwidXNlIHN0cmljdFwiO1xuXG52YXIgX2NsYXNzQ2FsbENoZWNrID0gZnVuY3Rpb24gKGluc3RhbmNlLCBDb25zdHJ1Y3RvcikgeyBpZiAoIShpbnN0YW5jZSBpbnN0YW5jZW9mIENvbnN0cnVjdG9yKSkgeyB0aHJvdyBuZXcgVHlwZUVycm9yKFwiQ2Fubm90IGNhbGwgYSBjbGFzcyBhcyBhIGZ1bmN0aW9uXCIpOyB9IH07XG5cbmV4cG9ydHMuX19lc01vZHVsZSA9IHRydWU7XG4vKipcbiAqIENyZWF0ZXMgYSBuZXcgaW5zdGFuY2Ugb2YgRW1pdHRlci5cbiAqIEBjbGFzc1xuICogQHJldHVybnMge09iamVjdH0gUmV0dXJucyBhIG5ldyBpbnN0YW5jZSBvZiBFbWl0dGVyLlxuICogQGV4YW1wbGVcbiAqIC8vIENyZWF0ZXMgYSBuZXcgaW5zdGFuY2Ugb2YgRW1pdHRlci5cbiAqIHZhciBFbWl0dGVyID0gcmVxdWlyZSgnZW1pdHRlcicpO1xuICpcbiAqIHZhciBlbWl0dGVyID0gbmV3IEVtaXR0ZXIoKTtcbiAqL1xuXG52YXIgRW1pdHRlciA9IChmdW5jdGlvbiAoKSB7XG4gIGZ1bmN0aW9uIEVtaXR0ZXIoKSB7XG4gICAgX2NsYXNzQ2FsbENoZWNrKHRoaXMsIEVtaXR0ZXIpO1xuICB9XG5cbiAgLyoqXG4gICAqIEFkZHMgYSBsaXN0ZW5lciB0byB0aGUgY29sbGVjdGlvbiBmb3IgdGhlIHNwZWNpZmllZCBldmVudC5cbiAgICogQG1lbWJlcm9mISBFbWl0dGVyLnByb3RvdHlwZVxuICAgKiBAZnVuY3Rpb25cbiAgICogQHBhcmFtIHtTdHJpbmd9IGV2ZW50IC0gVGhlIGV2ZW50IG5hbWUuXG4gICAqIEBwYXJhbSB7RnVuY3Rpb259IGxpc3RlbmVyIC0gQSBsaXN0ZW5lciBmdW5jdGlvbiB0byBhZGQuXG4gICAqIEByZXR1cm5zIHtPYmplY3R9IFJldHVybnMgYW4gaW5zdGFuY2Ugb2YgRW1pdHRlci5cbiAgICogQGV4YW1wbGVcbiAgICogLy8gQWRkIGFuIGV2ZW50IGxpc3RlbmVyIHRvIFwiZm9vXCIgZXZlbnQuXG4gICAqIGVtaXR0ZXIub24oJ2ZvbycsIGxpc3RlbmVyKTtcbiAgICovXG5cbiAgRW1pdHRlci5wcm90b3R5cGUub24gPSBmdW5jdGlvbiBvbihldmVudCwgbGlzdGVuZXIpIHtcbiAgICAvLyBVc2UgdGhlIGN1cnJlbnQgY29sbGVjdGlvbiBvciBjcmVhdGUgaXQuXG4gICAgdGhpcy5fZXZlbnRDb2xsZWN0aW9uID0gdGhpcy5fZXZlbnRDb2xsZWN0aW9uIHx8IHt9O1xuXG4gICAgLy8gVXNlIHRoZSBjdXJyZW50IGNvbGxlY3Rpb24gb2YgYW4gZXZlbnQgb3IgY3JlYXRlIGl0LlxuICAgIHRoaXMuX2V2ZW50Q29sbGVjdGlvbltldmVudF0gPSB0aGlzLl9ldmVudENvbGxlY3Rpb25bZXZlbnRdIHx8IFtdO1xuXG4gICAgLy8gQXBwZW5kcyB0aGUgbGlzdGVuZXIgaW50byB0aGUgY29sbGVjdGlvbiBvZiB0aGUgZ2l2ZW4gZXZlbnRcbiAgICB0aGlzLl9ldmVudENvbGxlY3Rpb25bZXZlbnRdLnB1c2gobGlzdGVuZXIpO1xuXG4gICAgcmV0dXJuIHRoaXM7XG4gIH07XG5cbiAgLyoqXG4gICAqIEFkZHMgYSBsaXN0ZW5lciB0byB0aGUgY29sbGVjdGlvbiBmb3IgdGhlIHNwZWNpZmllZCBldmVudCB0aGF0IHdpbGwgYmUgY2FsbGVkIG9ubHkgb25jZS5cbiAgICogQG1lbWJlcm9mISBFbWl0dGVyLnByb3RvdHlwZVxuICAgKiBAZnVuY3Rpb25cbiAgICogQHBhcmFtIHtTdHJpbmd9IGV2ZW50IC0gVGhlIGV2ZW50IG5hbWUuXG4gICAqIEBwYXJhbSB7RnVuY3Rpb259IGxpc3RlbmVyIC0gQSBsaXN0ZW5lciBmdW5jdGlvbiB0byBhZGQuXG4gICAqIEByZXR1cm5zIHtPYmplY3R9IFJldHVybnMgYW4gaW5zdGFuY2Ugb2YgRW1pdHRlci5cbiAgICogQGV4YW1wbGVcbiAgICogLy8gV2lsbCBhZGQgYW4gZXZlbnQgaGFuZGxlciB0byBcImZvb1wiIGV2ZW50IG9uY2UuXG4gICAqIGVtaXR0ZXIub25jZSgnZm9vJywgbGlzdGVuZXIpO1xuICAgKi9cblxuICBFbWl0dGVyLnByb3RvdHlwZS5vbmNlID0gZnVuY3Rpb24gb25jZShldmVudCwgbGlzdGVuZXIpIHtcbiAgICB2YXIgc2VsZiA9IHRoaXM7XG5cbiAgICBmdW5jdGlvbiBmbigpIHtcbiAgICAgIHNlbGYub2ZmKGV2ZW50LCBmbik7XG4gICAgICBsaXN0ZW5lci5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuICAgIH1cblxuICAgIGZuLmxpc3RlbmVyID0gbGlzdGVuZXI7XG5cbiAgICB0aGlzLm9uKGV2ZW50LCBmbik7XG5cbiAgICByZXR1cm4gdGhpcztcbiAgfTtcblxuICAvKipcbiAgICogUmVtb3ZlcyBhIGxpc3RlbmVyIGZyb20gdGhlIGNvbGxlY3Rpb24gZm9yIHRoZSBzcGVjaWZpZWQgZXZlbnQuXG4gICAqIEBtZW1iZXJvZiEgRW1pdHRlci5wcm90b3R5cGVcbiAgICogQGZ1bmN0aW9uXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBldmVudCAtIFRoZSBldmVudCBuYW1lLlxuICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBsaXN0ZW5lciAtIEEgbGlzdGVuZXIgZnVuY3Rpb24gdG8gcmVtb3ZlLlxuICAgKiBAcmV0dXJucyB7T2JqZWN0fSBSZXR1cm5zIGFuIGluc3RhbmNlIG9mIEVtaXR0ZXIuXG4gICAqIEBleGFtcGxlXG4gICAqIC8vIFJlbW92ZSBhIGdpdmVuIGxpc3RlbmVyLlxuICAgKiBlbWl0dGVyLm9mZignZm9vJywgbGlzdGVuZXIpO1xuICAgKi9cblxuICBFbWl0dGVyLnByb3RvdHlwZS5vZmYgPSBmdW5jdGlvbiBvZmYoZXZlbnQsIGxpc3RlbmVyKSB7XG5cbiAgICB2YXIgbGlzdGVuZXJzID0gdW5kZWZpbmVkO1xuXG4gICAgLy8gRGVmaW5lcyBsaXN0ZW5lcnMgdmFsdWUuXG4gICAgaWYgKCF0aGlzLl9ldmVudENvbGxlY3Rpb24gfHwgIShsaXN0ZW5lcnMgPSB0aGlzLl9ldmVudENvbGxlY3Rpb25bZXZlbnRdKSkge1xuICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgbGlzdGVuZXJzLmZvckVhY2goZnVuY3Rpb24gKGZuLCBpKSB7XG4gICAgICBpZiAoZm4gPT09IGxpc3RlbmVyIHx8IGZuLmxpc3RlbmVyID09PSBsaXN0ZW5lcikge1xuICAgICAgICAvLyBSZW1vdmVzIHRoZSBnaXZlbiBsaXN0ZW5lci5cbiAgICAgICAgbGlzdGVuZXJzLnNwbGljZShpLCAxKTtcbiAgICAgIH1cbiAgICB9KTtcblxuICAgIC8vIFJlbW92ZXMgYW4gZW1wdHkgZXZlbnQgY29sbGVjdGlvbi5cbiAgICBpZiAobGlzdGVuZXJzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgZGVsZXRlIHRoaXMuX2V2ZW50Q29sbGVjdGlvbltldmVudF07XG4gICAgfVxuXG4gICAgcmV0dXJuIHRoaXM7XG4gIH07XG5cbiAgLyoqXG4gICAqIEV4ZWN1dGUgZWFjaCBpdGVtIGluIHRoZSBsaXN0ZW5lciBjb2xsZWN0aW9uIGluIG9yZGVyIHdpdGggdGhlIHNwZWNpZmllZCBkYXRhLlxuICAgKiBAbWVtYmVyb2YhIEVtaXR0ZXIucHJvdG90eXBlXG4gICAqIEBmdW5jdGlvblxuICAgKiBAcGFyYW0ge1N0cmluZ30gZXZlbnQgLSBUaGUgbmFtZSBvZiB0aGUgZXZlbnQgeW91IHdhbnQgdG8gZW1pdC5cbiAgICogQHBhcmFtIHsuLi5PYmplY3R9IGRhdGEgLSBEYXRhIHRvIHBhc3MgdG8gdGhlIGxpc3RlbmVycy5cbiAgICogQHJldHVybnMge09iamVjdH0gUmV0dXJucyBhbiBpbnN0YW5jZSBvZiBFbWl0dGVyLlxuICAgKiBAZXhhbXBsZVxuICAgKiAvLyBFbWl0cyB0aGUgXCJmb29cIiBldmVudCB3aXRoICdwYXJhbTEnIGFuZCAncGFyYW0yJyBhcyBhcmd1bWVudHMuXG4gICAqIGVtaXR0ZXIuZW1pdCgnZm9vJywgJ3BhcmFtMScsICdwYXJhbTInKTtcbiAgICovXG5cbiAgRW1pdHRlci5wcm90b3R5cGUuZW1pdCA9IGZ1bmN0aW9uIGVtaXQoZXZlbnQpIHtcbiAgICB2YXIgX3RoaXMgPSB0aGlzO1xuXG4gICAgZm9yICh2YXIgX2xlbiA9IGFyZ3VtZW50cy5sZW5ndGgsIGFyZ3MgPSBBcnJheShfbGVuID4gMSA/IF9sZW4gLSAxIDogMCksIF9rZXkgPSAxOyBfa2V5IDwgX2xlbjsgX2tleSsrKSB7XG4gICAgICBhcmdzW19rZXkgLSAxXSA9IGFyZ3VtZW50c1tfa2V5XTtcbiAgICB9XG5cbiAgICB2YXIgbGlzdGVuZXJzID0gdW5kZWZpbmVkO1xuXG4gICAgLy8gRGVmaW5lcyBsaXN0ZW5lcnMgdmFsdWUuXG4gICAgaWYgKCF0aGlzLl9ldmVudENvbGxlY3Rpb24gfHwgIShsaXN0ZW5lcnMgPSB0aGlzLl9ldmVudENvbGxlY3Rpb25bZXZlbnRdKSkge1xuICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLy8gQ2xvbmUgbGlzdGVuZXJzXG4gICAgbGlzdGVuZXJzID0gbGlzdGVuZXJzLnNsaWNlKDApO1xuXG4gICAgbGlzdGVuZXJzLmZvckVhY2goZnVuY3Rpb24gKGZuKSB7XG4gICAgICByZXR1cm4gZm4uYXBwbHkoX3RoaXMsIGFyZ3MpO1xuICAgIH0pO1xuXG4gICAgcmV0dXJuIHRoaXM7XG4gIH07XG5cbiAgcmV0dXJuIEVtaXR0ZXI7XG59KSgpO1xuXG4vKipcbiAqIEV4cG9ydHMgRW1pdHRlclxuICovXG5leHBvcnRzW1wiZGVmYXVsdFwiXSA9IEVtaXR0ZXI7XG5tb2R1bGUuZXhwb3J0cyA9IGV4cG9ydHNbXCJkZWZhdWx0XCJdOyJdfQ==\n"
  },
  {
    "path": "app_backend/static/plugin/Swiper-3.3.1/.gitignore",
    "content": ".DS_Store\nnode_modules\nbuild\n*.log\n\n.versions\n"
  },
  {
    "path": "app_backend/static/plugin/Swiper-3.3.1/.jshintrc",
    "content": "{\n  \"node\"         : true,\n  \"browser\"      : true,\n  \"esnext\"       : true,\n  \"bitwise\"      : false,\n  \"curly\"        : false,\n  \"eqeqeq\"       : true,\n  \"eqnull\"       : true,\n  \"immed\"        : true,\n  \"newcap\"       : true,\n  \"noarg\"        : true,\n  \"undef\"        : true,\n  \"strict\"       : true,\n  \"smarttabs\"    : true,\n  \"quotmark\"     : \"single\",\n  \"indent\"       : 4,\n  \"globals\":{\n    \"document\": true,\n    \"define\": true,\n    \"Swiper\": true,\n    \"window\": true,\n    \"HTMLElement\": true,\n    \"XMLSerializer\": true,\n    \"Image\": true,\n    \"WheelEvent\": true,\n    \"navigator\": true,\n    \"DocumentTouch\": true,\n    \"Modernizr\": true,\n    \"WebKitCSSMatrix\": true,\n    \"s\": true,\n    \"jQuery\": true,\n    \"Dom7\": true,\n    \"$\": true\n  }\n}\n"
  },
  {
    "path": "app_backend/static/plugin/Swiper-3.3.1/.travis.yml",
    "content": "language: node_js\nnode_js:\n  - \"0.10\"\nbefore_script:\n  - npm install --global gulp"
  },
  {
    "path": "app_backend/static/plugin/Swiper-3.3.1/CHANGELOG.md",
    "content": "# Change Log\n\n## Swiper 3.3.1 - Released on February 7, 2016\n  * New `uniqueNavElements` parameter. If enabled (by default) and navigation elements' parameters passed as the string (like `.pagination`) then Swiper will look for such elements through child elements first. Applies for pagination, prev/next buttons and scrollbar\n  * New `onPaginationRendered` callback. Will be fired after pagination elements generated and added to DOM\n  * New `.reLoop()` method, which combines `.destroyLoop()` + `.createLoop()` methods with additional positioning fixes. Useful to call after you have changed `slidesPerView` parameter, it will dynamically recreate duplicated slides required for loop\n  * Fixed not working mousewheel control in IE 11\n  * Fixed issue with lazy loading images not being recalculated after window resize\n  * Fixed issues when using loop with breakpoints changing `slidesPerView/Group` parameters\n  * Numerous minor fixes\n\n## Swiper 3.3.0 - Released on January 10, 2016\n  * New 3D Flip effect. Can be enabled with `effect: 'flip' parameter\n  * New types of pagination with new parameters:\n    * `paginationType` - type of pagination. Can be `'bullets'` (default) or `'fraction'` or `'progress'` or `'custom'`\n    * `paginationFractionRender(swiper, currentClass, totalClass)` - custom function to render \"fraction\" type pagination\n    * `paginationProgressRender(swiper, progressbarClass)` - custom function to render \"progress\" type pagination\n    * `paginationCustomRender(swiper, current, total)` - custom function to render \"custom\" type pagination\n  * New `lazyLoadingInPrevNextAmount` parameter allows to lazy load images in specified amount of next/prev slides\n  * New `autoplayStopOnLast` parameter (`true` by default) tells to autoplay should it stop on last slide or start from first slide\n  * New `onAutoplay(swiper)` callback\n  * Minor fixes\n\n## Swiper 3.2.7 - Released on December 7, 2015\n  * Fixed issue with using HTMLElements for next/prevButton parameters with breakpoints\n  * Fixed issue with not working Auto Height when using Controller\n\n## Swiper 3.2.6 - Released on November 28, 2015\n  * Fixed issue in RTL layout using `mousewheelControl`\n  * Fixed issue in RTL layout using Parallax\n\n## Swiper 3.2.5 - Released on November 21, 2015\n  * New \"Auto Height\" mode when container/wrapper adopts to the height of currently active slide. Can be enabled with `autoHeight: true` parameter\n  * Fixed issue with break points in FireFox\n  * Fixed issue with wrong slides position when using effects\n  * Fixed issue with none-updated scroll bar after using `setWrapperTranslate`\n  * Minor fixes\n\n## Swiper 3.2.0 - Released on November 7, 2015\n  * Added responsive breakpoints support using new `breakpoints` parameter. Now you can specify different `slidesPerView` and other similar parameters for different sizes:\n    ```js\n    slidesPerView: 5,\n    spaceBetween: 50,\n    breakpoints: {\n      1024: {\n        slidesPerView: 4,\n        spaceBetween: 40\n      },\n      768: {\n        slidesPerView: 3,\n        spaceBetween: 30\n      },\n      320: {\n        slidesPerView: 1,\n        spaceBetween: 10\n      }\n    }\n    ```\n\n  * New callbacks: `onSlideNextStart`, `onSlideNextEnd`, `onSlidePrevStart`, `onSlidePrevEnd`\n  * Added Meteor package `meteor add nolimits4web:swiper`\n  * Fixed issue with mouse touchMove/End callbacks firing all the time\n  * Fixed issue with mousewheel in Chrome\n  * Minor fixes\n\n## Swiper 3.1.7 - Released on October 10, 2015\n  * Fixed issue with lazy loading trying to download `undefined`-src images\n  * Fixed lazy loading on slides using jQuery version\n  * Fixed issue with `slideToClickedSlide` with `loop` and `centeredSlides`\n  * Fixed issue with wrong slides fill when number of slides less than `slidesPerView * slidesPerColumn` with `slidesPerColumnFill: 'row'`\n  * Minor fixes\n\n## Swiper 3.1.5 - Released on September 28, 2015\n  * Added support for images `srcset` with lazy loading using `data-srcset` attribute\n  * Fixed new Chrome errors with `WebkitCSSMatrix`\n  * Fixed issue with `slideToClickedSlide` with `loop` and `centeredSlides`\n  * New `freeModeMinimumVelocity` parameter to set minimum required touch velocity to trigger free mode momentum\n  * Ability to make the Scrollbar draggable using new paramaters:\n    * `scrollbarDraggable` - (boolean) by default is `false`. Allows to enable draggable scrollbar\n    * `scrollbarSnapOnRelease` - (boolean) by default is `false`. Control slider snap on scrollbar release\n  * Minor fixes\n\n## Swiper 3.1.2 - Released on August 22, 2015\n  * Fixed issues with loop and mousewheel when swiper stopped on last slide\n  * Imporved mouse wheel behavior in latest Chrome\n  * Fixed issue with `slidesPerView: 'auto'` and enabled `loop:true` mode to set `loopedSlides` to the amount of slides by default (if not specified)\n  * New `mousewheelSensitivity: 1` parameter allows to tweak mouse wheel sensitivity\n  * Fixed issue with updating swiper when swiping is locked (with `allowSwipeToNext`/`allowSwipeToPrev`)\n  * Fixed issue with wrong calculating of \"visible\" slides with enabled `centeredSlides`\n  * CSS fixes for 3D effects\n  * New options to release Swiper events for swipe-to-go-back work in iOS UIWebView with two options:\n    * `iOSEdgeSwipeDetection` (by default is `false`) - enable ios edge detection and release Swiper events\n    * `iOSEdgeSwipeThreshold` (default value is `20`) - area in `px` from left edge of screen to release events\n  * Improved source maps\n  * Minor fixes\n\n## Swiper 3.1.0 - Released on July 14, 2015\n  * Accessibility (a11y)\n    * Fixed issue with wrong buttons labels\n    * Added support for pagination bullets\n    * New accessibility parameter for pagination label `paginationBulletMessage: 'Go to slide {{index}}'`\n  * Controler\n    * New parameter `controlBy` which can be 'slide' (by default) or 'container'. Defines a way how to control another slider: slide by slide or depending on all slides/container (like before)\n    * Now controllers in `controlBy: 'slide'` (default) mode will respect grid of each other\n  * Pagination\n    * New `paginationElement` parameter defines which HTML tag will be use to represent single pagination bullet. By default it is `span`\n  * New `roundLengths` parameter (by default is `false`) to round values of slides width and height to prevent blurry texts on usual resolution screens\n  * New `slidesOffsetBefore: 0` and `slidesOffsetAfter: 0` (in px) parameters to add additional slide offset within a container\n  * Correct calculation for slides size when use CSS padding on `.swiper-container`\n  * Fixed issue with not working onResize handler when swipes are locked\n  * Fixed issue with \"jumping\" effect when you disable `onlyExternal` during touchmove\n  * Fixed issue when slider goes to previos slide from last slide after window resize\n  * Added new `swiper.jquery.umd.js` version for the environment where both Swiper and jQuery included as modules\n  * Minor fixes\n\n## Swiper 3.0.8 - Released on June 14, 2015\n  * Fixed issue with wrong active index and callbacks in Fade effect\n  * New mousewheel parameters:\n    * `mousewheelReleaseOnEdges` - will release mousewheel event and allow page scrolling when swiper is on edge positions (in the beginning or in the end)\n    * `mousewheelInvert` - option to invert mousewheel slides\n  * Fixed issue with lazy loading in next slides when `slidesPerView` > 1\n  * Fixed issue with resistance bounds when swiping is locked\n  * Fixed issue with wrong slides order in multi-row mode (when `slidesPerColumn` > 1)\n  * Fixed issue with not working keyboard control in RTL mode\n  * Fixed issue with nested fade-effect swipers\n  * Minor fixes\n\n## Swiper 3.0.7 - Released on April 25, 2015\n  * New `width` and `height` parameters to force Swiper size, useful when it is hidden on intialization\n  * Better support for \"Scroll Container\". So now Swiper can be used as a scroll container with one single \"scrollable\"/\"swipeable\" slide\n  * Added lazy loading for background images with `data-background` attribute on required elements\n  * New \"Sticky Free Mode\" (with `freeModeSticky` parameter) which will snap to slides positions in free mode\n  * Fixed issues with lazy loading  \n  * Fixed slide removing when loop mode is enabled\n  * Fixed issues with Autoplay and Fade effect\n  * Minor fixes\n\n## Swiper 3.0.6 - Released on March 27, 2015\n  * Fixed sometimes wrong slides position when using \"Fade\" effect\n  * `.destroy(deleteInstance, cleanupStyles)` method now has second `cleanupStyles` argument, when passed - all custom styles will be removed from slides, wrapper and container. Useful if you need to destroy Swiper and to init again with new options or in different direction\n  * Minor fixes\n\n## Swiper 3.0.5 - Released on March 21, 2015\n  * New Keyboard accessibility module to provide foucsable navigation buttons and basic ARIA for screen readers with new parameters:\n    * `a11y: false` - enable accessibility\n    * `prevSlideMessage: 'Previous slide'` - message for screen readers for previous button\n    * `nextSlideMessage: 'Next slide'` - message for screen readers for next button\n    * `firstSlideMessage: 'This is the first slide'` - message for screen readers for previous button when swiper is on first slide\n    * `lastSlideMessage: 'This is the last slide'` - message for screen readers for next button when swiper is on last slide\n  * New Emitter module. It allows to work with callbacks like with events, even adding them after initialization with new methods:\n    * `.on(event, handler)` - add event/callback\n    * `.off(event, handler)` - remove this event/callback\n    * `.once(event, handler)` - add event/callback that will be executed only once\n  * Plugins API is back. It allows to write custom Swiper plugins\n  * Better support for browser that don't support flexbox layout\n  * New parameter `setWrapperSize` (be default it is `false`) to provide better compatibility with browser without flexbox support. Enabled this option and plugin will set width/height on swiper wrapper equal to total size of all slides\n  * New `virtualTranslate` parameter. When it is enabled swiper will be operated as usual except it will not move. Useful when you may need to create custom slide transition\n  * Added support for multiple Pagination containers\n  * Fixed `onLazyImage...` callbacks\n  * Fixed issue with not accessible links inside of Slides on Android < 4.4\n  * Fixed pagination bullets behavior in loop mode with specified `slidesPerGroup`\n  * Fixed issues with clicks on IE 10+ touch devices\n  * Fixed issues with Coverflow support on IE 10+\n  * Hashnav now will update document hash after transition to prevent browsers UI lags, not in the beginning like before\n  * Super basic support for IE 9 with swiper.jquery version. No animation and transitions, but basic stuff like switching slides/pagination/scrollbars works\n  \n\n## Swiper 3.0.4 - Released on March 6, 2015\n  * New Images Lazy Load component\n    * With new parameters `lazyLoading`, `lazyLoadingInPrevNext`, `lazyLoadingOnTransitionStart` (all disabled by default)\n    * With new callbacks `onLazyImageLoad` and `onLazyImageReady`\n  * `updateOnImages` ready split into 2 parameters:\n    * `preloadImages` (by default is true) - to preload all images on swiper init\n    * `updateOnImages` (by default is true) - update swiper when all images loaded\n  * Fixed issues with touchmove on fouces form elements\n  * New `onObserverUpdate` callback function to be called after updates by ovserver\n  * Fixed issue with not working inputs with keyboard control for jQuery version\n  * New `paginationBulletRender` parameter that accepts function which allow custom pagination elements layout\n  * Hash Navigation will run callback dpending on `runCallbacksOnInit` parameter\n  * `watchVisibility` parameter renamed to `watchSlidesVisibility`\n\n## Swiper 3.0.3 - Released on March 1, 2015\n  * Fixed issue with not firing onSlideChangeEnd callback after calling .slideTo with\nrunCallbacks=false\n  * Fixed values of isBeginning/isEnd when there is only one slide\n  * New `crossFade` option for fade effect\n  * Improved support for devices with both touch and mouse inputs, not yet on IE\n  * Fixed not correctly working mousewheel and keyobard control in swiper.jquery version\n  * New parallax module for transitions with parallax effects on internal elements\n  * Improved .update and .onResize methods\n  * Minor fixes\n\n## Swiper 3.0.2 - Released on February 22, 2015\n  * Fixed issue with keyboard events not cleaned up with Swiper.destroy\n  * Encoded inline SVG images for IE support\n  * New callbacks\n    * onInit (swiper)\n    * onTouchMoveOpposite (swiper, e)\n  * Fixed free mode momentum in RTL layout\n  * `.update` method improved to fully cover what `onResize` do for full and correct update\n  * Exposed `swiper.touches` object with the following properties: `startX`, `startY`, `currentX`, `currentY`, `diff`\n  * New methods to remove slides\n    * `.removeSlide(index)` or `.removeSlide([indexes])` - to remove selected slides\n    * `.removeAllSlides()` - to remove all slides\n\n## Swiper 3.0.1 - Released on February 13, 2015\n  * Fixed issue with navigation buttons in Firefox in loop mode\n  * Fixed issue with image dragging in IE 10+\n\n## Swiper 3.0.0 - Released on February 11, 2015\n  * Initial release of all new Swiper 3\n  * Removed features\n    * Dropped support for old browsers. Now it is compatible with:\n      * iOS 7+\n      * Android 4+ (multirow mode only for Android 4.4+)\n      * Latest Chrome, Safari, Firefox and Opera desktop browsers\n      * WP 8+, IE 10+ (3D effects may not work correctly on IE because of wrong nested 3D transform support)\n    * Scroll Container. Removed in favor of pure CSS `overflow: auto` with `-webkit-overflow-scrolling: touch`\n  * New features\n    * Swiper now uses modern flexbox layout, which by itself give more features and advantages\n    * Such Swiper 2.x plugins as Hash Navigation, Smooth Progress, 3D Flow and Scrollbar are now incoroporated into Swiper 3.x core\n    * Full RTL support\n    * Built-in navigation buttons/arrows\n    * Controller. Now one Swiper could be controlled (or control itself) by another Swiper\n    * Multi row slides layout with `slidesPerColumn` option\n    * Better support for nested Swipers, now it is possible to use same-direction nested Swipers, like horizontal in horizontal\n    * Space between slides\n    * New transition effects: 3D Coverflow, 3D Cube and Fade transitions\n    * Slides are `border-box` now, so it is possible to use borders and paddings directly on slides\n    * Auto layout mode (`slidesPerView: 'auto'`) now gives more freedom, you can even specify slides sizes in % and use margins on them\n    * Mutation Observers. If enabled, Swiper will watch for changes in Dom and update its layout automatically\n    * Better clicks prevention during swiping\n  * Many of API methods, parameters and callbacks are changed\n  * Added a bit lightweight jQuery/Zepto version of Swiper that can be used if you use jQuery/Zepto in your project\n\n\n"
  },
  {
    "path": "app_backend/static/plugin/Swiper-3.3.1/LICENSE",
    "content": "The MIT License (MIT)\n\nCopyright (c) 2014 Vladimir Kharlampidi\n\nPermission is hereby granted, free of charge, to any person obtaining a copy of\nthis software and associated documentation files (the \"Software\"), to deal in\nthe Software without restriction, including without limitation the rights to\nuse, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of\nthe Software, and to permit persons to whom the Software is furnished to do so,\nsubject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS\nFOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR\nCOPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER\nIN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN\nCONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n"
  },
  {
    "path": "app_backend/static/plugin/Swiper-3.3.1/README.md",
    "content": "[![Join the chat at https://gitter.im/nolimits4web/Swiper](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/nolimits4web/Swiper?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)\n[![Build Status](https://travis-ci.org/nolimits4web/Swiper.svg?branch=master)](https://travis-ci.org/nolimits4web/Swiper)\n[![devDependency Status](https://david-dm.org/nolimits4web/swiper/dev-status.svg)](https://david-dm.org/nolimits4web/swiper#info=devDependencies)\n[![Flattr this git repo](http://api.flattr.com/button/flattr-badge-large.png)](https://flattr.com/submit/auto?user_id=nolimits4web&url=https://github.com/nolimits4web/swiper/&title=Framework7&language=JavaScript&tags=github&category=software)\n\nSwiper\n==========\n\nSwiper - is the free and most modern mobile touch slider with hardware accelerated transitions and amazing native behavior. It is intended to be used in mobile websites, mobile web apps, and mobile native/hybrid apps. Designed mostly for iOS, but also works great on latest Android, Windows Phone 8 and modern Desktop browsers\n\nSwiper is not compatible with all platforms, it is a modern touch slider which is focused only on modern apps/platforms to bring the best experience and simplicity.\n\n# Getting Started\n  * [Getting Started Guide](http://www.idangero.us/swiper/get-started/)\n  * [API](http://www.idangero.us/swiper/api/)\n  * [Demos](http://www.idangero.us/swiper/demos/)\n  * [Forum](http://www.idangero.us/swiper/forum/)\n\n# Dist / Build\n\nOn production use files (JS and CSS) only from `dist/` folder, there will be the most stable versions, `build/` folder is only for development purpose\n\n### Build\n\nSwiper uses `gulp` to build a development (build) and dist versions.\n\nFirst you need to have `gulp-cli` which you should install globally.\n\n```\n$ npm install --global gulp\n```\n\nThen install all dependencies, in repo's root:\n\n```\n$ npm install\n```\n\nAnd build development version of Swiper:\n```\n$ gulp build\n```\n\nThe result is available in `build/` folder.\n\n### Dist/Release\n\nAfter you have made build:\n\n```\n$ gulp dist\n```\n\nDistributable version will available in `dist/` folder.\n\n# Contributing\n\nAll changes should be commited to `src/` files. Swiper uses LESS for CSS compliations, and concatenated JS files (look at gulpfile.js for concat files order)\n\nSwiper 2.x.x\n==========\n\nIf you still using Swiper 2.x.x or you need old browsers support, you may find it in [Swiper2 Branch](https://github.com/nolimits4web/Swiper/tree/Swiper2)\n* [Download Latest Swiper 2.7.6](https://github.com/nolimits4web/Swiper/archive/v2.7.6.zip)\n* [Source Files](https://github.com/nolimits4web/Swiper/tree/Swiper2/src)\n* [API](https://github.com/nolimits4web/Swiper/blob/Swiper2/API.md)"
  },
  {
    "path": "app_backend/static/plugin/Swiper-3.3.1/bower.json",
    "content": "{\n  \"name\": \"Swiper\",\n  \"repository\": {\n    \"type\": \"git\",\n    \"url\": \"https://github.com/nolimits4web/Swiper.git\"\n  },\n  \"description\": \"Most modern mobile touch slider and framework with hardware accelerated transitions\",\n  \"version\": \"3.3.1\",\n  \"author\": \"Vladimir Kharlampidi\",\n  \"homepage\": \"http://www.idangero.us/swiper/\",\n  \"keywords\": [\"swiper\", \"swipe\", \"slider\", \"touch\", \"ios\", \"mobile\", \"cordova\", \"phonegap\", \"app\", \"framework\", \"carousel\", \"gallery\"],\n  \"dependencies\": {\n  },\n  \"scripts\": [\n    \"dist/js/swiper.js\"\n  ],\n  \"main\": [\n    \"dist/js/swiper.js\",\n    \"dist/css/swiper.css\"\n  ],\n  \"styles\": [\n    \"dist/css/swiper.css\"\n  ],\n  \"license\": [\"MIT\"],\n  \"dependencies\": {},\n  \"ignore\": [\n    \".*\",\n    \"demos\",\n    \"gulpfile\",\n    \"build\",\n    \"node_modules\",\n    \"playground\",\n    \"package.json\"\n  ]\n}"
  },
  {
    "path": "app_backend/static/plugin/Swiper-3.3.1/component.json",
    "content": "{\n  \"name\": \"swiper\",\n  \"repo\": \"https://github.com/nolimits4web/Swiper.git\",\n  \"description\": \"Most modern mobile touch slider and framework with hardware accelerated transitions\",\n  \"version\": \"3.3.1\",\n  \"keywords\": [\"swiper\", \"swipe\", \"slider\", \"touch\", \"ios\", \"mobile\", \"cordova\", \"phonegap\", \"app\", \"framework\", \"carousel\", \"gallery\"],\n  \"dependencies\": {\n  },\n  \"scripts\": [\n    \"dist/js/swiper.js\"\n  ],\n  \"main\": \"dist/js/swiper.js\",\n  \"styles\": [\n    \"dist/css/swiper.css\"\n  ],\n  \"license\": [\"MIT\"]\n}\n"
  },
  {
    "path": "app_backend/static/plugin/Swiper-3.3.1/demos/01-default.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n    <meta charset=\"utf-8\">\n    <title>Swiper demo</title>\n    <!-- Link Swiper's CSS -->\n    <link rel=\"stylesheet\" href=\"../dist/css/swiper.min.css\">\n\n    <!-- Demo styles -->\n    <style>\n    body {\n        background: #eee;\n        font-family: Helvetica Neue, Helvetica, Arial, sans-serif;\n        font-size: 14px;\n        color:#000;\n        margin: 0;\n        padding: 0;\n    }\n    .swiper-container {\n        width: 500px;\n        height: 300px;\n        margin: 20px auto;\n    }\n    .swiper-slide {\n        text-align: center;\n        font-size: 18px;\n        background: #fff;\n        \n        /* Center slide text vertically */\n        display: -webkit-box;\n        display: -ms-flexbox;\n        display: -webkit-flex;\n        display: flex;\n        -webkit-box-pack: center;\n        -ms-flex-pack: center;\n        -webkit-justify-content: center;\n        justify-content: center;\n        -webkit-box-align: center;\n        -ms-flex-align: center;\n        -webkit-align-items: center;\n        align-items: center;\n    }\n    </style>\n</head>\n<body>\n    <!-- Swiper -->\n    <div class=\"swiper-container\">\n        <div class=\"swiper-wrapper\">\n            <div class=\"swiper-slide\">Slide 1</div>\n            <div class=\"swiper-slide\">Slide 2</div>\n            <div class=\"swiper-slide\">Slide 3</div>\n            <div class=\"swiper-slide\">Slide 4</div>\n            <div class=\"swiper-slide\">Slide 5</div>\n            <div class=\"swiper-slide\">Slide 6</div>\n            <div class=\"swiper-slide\">Slide 7</div>\n            <div class=\"swiper-slide\">Slide 8</div>\n            <div class=\"swiper-slide\">Slide 9</div>\n            <div class=\"swiper-slide\">Slide 10</div>\n        </div>\n    </div>\n\n    <!-- Swiper JS -->\n    <script src=\"../dist/js/swiper.min.js\"></script>\n\n    <!-- Initialize Swiper -->\n    <script>\n    var swiper = new Swiper('.swiper-container');\n    </script>\n</body>\n</html>"
  },
  {
    "path": "app_backend/static/plugin/Swiper-3.3.1/demos/02-responsive.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n    <meta charset=\"utf-8\">\n    <title>Swiper demo</title>\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1, minimum-scale=1, maximum-scale=1\">\n\n    <!-- Link Swiper's CSS -->\n    <link rel=\"stylesheet\" href=\"../dist/css/swiper.min.css\">\n\n    <!-- Demo styles -->\n    <style>\n    html, body {\n        position: relative;\n        height: 100%;\n    }\n    body {\n        background: #eee;\n        font-family: Helvetica Neue, Helvetica, Arial, sans-serif;\n        font-size: 14px;\n        color:#000;\n        margin: 0;\n        padding: 0;\n    }\n    .swiper-container {\n        width: 100%;\n        height: 100%;\n    }\n    .swiper-slide {\n        text-align: center;\n        font-size: 18px;\n        background: #fff;\n\n        /* Center slide text vertically */\n        display: -webkit-box;\n        display: -ms-flexbox;\n        display: -webkit-flex;\n        display: flex;\n        -webkit-box-pack: center;\n        -ms-flex-pack: center;\n        -webkit-justify-content: center;\n        justify-content: center;\n        -webkit-box-align: center;\n        -ms-flex-align: center;\n        -webkit-align-items: center;\n        align-items: center;\n    }\n    </style>\n</head>\n<body>\n    <!-- Swiper -->\n    <div class=\"swiper-container\">\n        <div class=\"swiper-wrapper\">\n            <div class=\"swiper-slide\">Slide 1</div>\n            <div class=\"swiper-slide\">Slide 2</div>\n            <div class=\"swiper-slide\">Slide 3</div>\n            <div class=\"swiper-slide\">Slide 4</div>\n            <div class=\"swiper-slide\">Slide 5</div>\n            <div class=\"swiper-slide\">Slide 6</div>\n            <div class=\"swiper-slide\">Slide 7</div>\n            <div class=\"swiper-slide\">Slide 8</div>\n            <div class=\"swiper-slide\">Slide 9</div>\n            <div class=\"swiper-slide\">Slide 10</div>\n        </div>\n        <!-- Add Pagination -->\n        <div class=\"swiper-pagination\"></div>\n    </div>\n\n    <!-- Swiper JS -->\n    <script src=\"../dist/js/swiper.min.js\"></script>\n\n    <!-- Initialize Swiper -->\n    <script>\n    var swiper = new Swiper('.swiper-container', {\n        pagination: '.swiper-pagination',\n        paginationClickable: true\n    });\n    </script>\n</body>\n</html>"
  },
  {
    "path": "app_backend/static/plugin/Swiper-3.3.1/demos/03-vertical.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n    <meta charset=\"utf-8\">\n    <title>Swiper demo</title>\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1, minimum-scale=1, maximum-scale=1\">\n\n    <!-- Link Swiper's CSS -->\n    <link rel=\"stylesheet\" href=\"../dist/css/swiper.min.css\">\n\n    <!-- Demo styles -->\n    <style>\n    html, body {\n        position: relative;\n        height: 100%;\n    }\n    body {\n        background: #eee;\n        font-family: Helvetica Neue, Helvetica, Arial, sans-serif;\n        font-size: 14px;\n        color:#000;\n        margin: 0;\n        padding: 0;\n    }\n    .swiper-container {\n        width: 100%;\n        height: 100%;\n    }\n    .swiper-slide {\n        text-align: center;\n        font-size: 18px;\n        background: #fff;\n\n        /* Center slide text vertically */\n        display: -webkit-box;\n        display: -ms-flexbox;\n        display: -webkit-flex;\n        display: flex;\n        -webkit-box-pack: center;\n        -ms-flex-pack: center;\n        -webkit-justify-content: center;\n        justify-content: center;\n        -webkit-box-align: center;\n        -ms-flex-align: center;\n        -webkit-align-items: center;\n        align-items: center;\n    }\n    </style>\n</head>\n<body>\n    <!-- Swiper -->\n    <div class=\"swiper-container\">\n        <div class=\"swiper-wrapper\">\n            <div class=\"swiper-slide\">Slide 1</div>\n            <div class=\"swiper-slide\">Slide 2</div>\n            <div class=\"swiper-slide\">Slide 3</div>\n            <div class=\"swiper-slide\">Slide 4</div>\n            <div class=\"swiper-slide\">Slide 5</div>\n            <div class=\"swiper-slide\">Slide 6</div>\n            <div class=\"swiper-slide\">Slide 7</div>\n            <div class=\"swiper-slide\">Slide 8</div>\n            <div class=\"swiper-slide\">Slide 9</div>\n            <div class=\"swiper-slide\">Slide 10</div>\n        </div>\n        <!-- Add Pagination -->\n        <div class=\"swiper-pagination\"></div>\n    </div>\n\n    <!-- Swiper JS -->\n    <script src=\"../dist/js/swiper.min.js\"></script>\n\n    <!-- Initialize Swiper -->\n    <script>\n    var swiper = new Swiper('.swiper-container', {\n        pagination: '.swiper-pagination',\n        paginationClickable: true,\n        direction: 'vertical'\n    });\n    </script>\n</body>\n</html>"
  },
  {
    "path": "app_backend/static/plugin/Swiper-3.3.1/demos/04-space-between.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n    <meta charset=\"utf-8\">\n    <title>Swiper demo</title>\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1, minimum-scale=1, maximum-scale=1\">\n\n    <!-- Link Swiper's CSS -->\n    <link rel=\"stylesheet\" href=\"../dist/css/swiper.min.css\">\n\n    <!-- Demo styles -->\n    <style>\n    body {\n        background: #eee;\n        font-family: Helvetica Neue, Helvetica, Arial, sans-serif;\n        font-size: 14px;\n        color:#000;\n        margin: 0;\n        padding: 0;\n    }\n    .swiper-container {\n        width: 500px;\n        height: 300px;\n        margin: 20px auto;\n    }\n    .swiper-slide {\n        text-align: center;\n        font-size: 18px;\n        background: #fff;\n\n        /* Center slide text vertically */\n        display: -webkit-box;\n        display: -ms-flexbox;\n        display: -webkit-flex;\n        display: flex;\n        -webkit-box-pack: center;\n        -ms-flex-pack: center;\n        -webkit-justify-content: center;\n        justify-content: center;\n        -webkit-box-align: center;\n        -ms-flex-align: center;\n        -webkit-align-items: center;\n        align-items: center;\n    }\n    </style>\n</head>\n<body>\n    <!-- Swiper -->\n    <div class=\"swiper-container\">\n        <div class=\"swiper-wrapper\">\n            <div class=\"swiper-slide\">Slide 1</div>\n            <div class=\"swiper-slide\">Slide 2</div>\n            <div class=\"swiper-slide\">Slide 3</div>\n            <div class=\"swiper-slide\">Slide 4</div>\n            <div class=\"swiper-slide\">Slide 5</div>\n            <div class=\"swiper-slide\">Slide 6</div>\n            <div class=\"swiper-slide\">Slide 7</div>\n            <div class=\"swiper-slide\">Slide 8</div>\n            <div class=\"swiper-slide\">Slide 9</div>\n            <div class=\"swiper-slide\">Slide 10</div>\n        </div>\n        <!-- Add Pagination -->\n        <div class=\"swiper-pagination\"></div>\n    </div>\n\n    <!-- Swiper JS -->\n    <script src=\"../dist/js/swiper.min.js\"></script>\n\n    <!-- Initialize Swiper -->\n    <script>\n    var swiper = new Swiper('.swiper-container', {\n        pagination: '.swiper-pagination',\n        paginationClickable: true,\n        spaceBetween: 30,\n    });\n    </script>\n</body>\n</html>"
  },
  {
    "path": "app_backend/static/plugin/Swiper-3.3.1/demos/05-slides-per-view.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n    <meta charset=\"utf-8\">\n    <title>Swiper demo</title>\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1, minimum-scale=1, maximum-scale=1\">\n\n    <!-- Link Swiper's CSS -->\n    <link rel=\"stylesheet\" href=\"../dist/css/swiper.min.css\">\n\n    <!-- Demo styles -->\n    <style>\n    html, body {\n        position: relative;\n        height: 100%;\n    }\n    body {\n        background: #eee;\n        font-family: Helvetica Neue, Helvetica, Arial, sans-serif;\n        font-size: 14px;\n        color:#000;\n        margin: 0;\n        padding: 0;\n    }\n    .swiper-container {\n        width: 100%;\n        height: 100%;\n    }\n    .swiper-slide {\n        text-align: center;\n        font-size: 18px;\n        background: #fff;\n        \n        /* Center slide text vertically */\n        display: -webkit-box;\n        display: -ms-flexbox;\n        display: -webkit-flex;\n        display: flex;\n        -webkit-box-pack: center;\n        -ms-flex-pack: center;\n        -webkit-justify-content: center;\n        justify-content: center;\n        -webkit-box-align: center;\n        -ms-flex-align: center;\n        -webkit-align-items: center;\n        align-items: center;\n    }\n    </style>\n</head>\n<body>\n    <!-- Swiper -->\n    <div class=\"swiper-container\">\n        <div class=\"swiper-wrapper\">\n            <div class=\"swiper-slide\">Slide 1</div>\n            <div class=\"swiper-slide\">Slide 2</div>\n            <div class=\"swiper-slide\">Slide 3</div>\n            <div class=\"swiper-slide\">Slide 4</div>\n            <div class=\"swiper-slide\">Slide 5</div>\n            <div class=\"swiper-slide\">Slide 6</div>\n            <div class=\"swiper-slide\">Slide 7</div>\n            <div class=\"swiper-slide\">Slide 8</div>\n            <div class=\"swiper-slide\">Slide 9</div>\n            <div class=\"swiper-slide\">Slide 10</div>\n        </div>\n        <!-- Add Pagination -->\n        <div class=\"swiper-pagination\"></div>\n    </div>\n\n    <!-- Swiper JS -->\n    <script src=\"../dist/js/swiper.min.js\"></script>\n\n    <!-- Initialize Swiper -->\n    <script>\n    var swiper = new Swiper('.swiper-container', {\n        pagination: '.swiper-pagination',\n        slidesPerView: 3,\n        paginationClickable: true,\n        spaceBetween: 30\n    });\n    </script>\n</body>\n</html>"
  },
  {
    "path": "app_backend/static/plugin/Swiper-3.3.1/demos/06-slides-per-view-auto.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n    <meta charset=\"utf-8\">\n    <title>Swiper demo</title>\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1, minimum-scale=1, maximum-scale=1\">\n\n    <!-- Link Swiper's CSS -->\n    <link rel=\"stylesheet\" href=\"../dist/css/swiper.min.css\">\n\n    <!-- Demo styles -->\n    <style>\n    html, body {\n        position: relative;\n        height: 100%;\n    }\n    body {\n        background: #eee;\n        font-family: Helvetica Neue, Helvetica, Arial, sans-serif;\n        font-size: 14px;\n        color:#000;\n        margin: 0;\n        padding: 0;\n    }\n    .swiper-container {\n        width: 100%;\n        height: 100%;\n    }\n    .swiper-slide {\n        text-align: center;\n        font-size: 18px;\n        background: #fff;\n        width: 80%;\n\n        /* Center slide text vertically */\n        display: -webkit-box;\n        display: -ms-flexbox;\n        display: -webkit-flex;\n        display: flex;\n        -webkit-box-pack: center;\n        -ms-flex-pack: center;\n        -webkit-justify-content: center;\n        justify-content: center;\n        -webkit-box-align: center;\n        -ms-flex-align: center;\n        -webkit-align-items: center;\n        align-items: center;\n    }\n    .swiper-slide:nth-child(2n) {\n        width: 60%;\n    }\n    .swiper-slide:nth-child(3n) {\n        width: 40%;\n    }\n    </style>\n</head>\n<body>\n    <!-- Swiper -->\n    <div class=\"swiper-container\">\n        <div class=\"swiper-wrapper\">\n            <div class=\"swiper-slide\">Slide 1</div>\n            <div class=\"swiper-slide\">Slide 2</div>\n            <div class=\"swiper-slide\">Slide 3</div>\n            <div class=\"swiper-slide\">Slide 4</div>\n            <div class=\"swiper-slide\">Slide 5</div>\n            <div class=\"swiper-slide\">Slide 6</div>\n            <div class=\"swiper-slide\">Slide 7</div>\n            <div class=\"swiper-slide\">Slide 8</div>\n            <div class=\"swiper-slide\">Slide 9</div>\n            <div class=\"swiper-slide\">Slide 10</div>\n        </div>\n        <!-- Add Pagination -->\n        <div class=\"swiper-pagination\"></div>\n    </div>\n\n    <!-- Swiper JS -->\n    <script src=\"../dist/js/swiper.min.js\"></script>\n\n    <!-- Initialize Swiper -->\n    <script>\n    var swiper = new Swiper('.swiper-container', {\n        pagination: '.swiper-pagination',\n        slidesPerView: 'auto',\n        paginationClickable: true,\n        spaceBetween: 30\n    });\n    </script>\n</body>\n</html>"
  },
  {
    "path": "app_backend/static/plugin/Swiper-3.3.1/demos/07-centered.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n    <meta charset=\"utf-8\">\n    <title>Swiper demo</title>\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1, minimum-scale=1, maximum-scale=1\">\n\n    <!-- Link Swiper's CSS -->\n    <link rel=\"stylesheet\" href=\"../dist/css/swiper.min.css\">\n\n    <!-- Demo styles -->\n    <style>\n    body {\n        background: #eee;\n        font-family: Helvetica Neue, Helvetica, Arial, sans-serif;\n        font-size: 14px;\n        color:#000;\n        margin: 0;\n        padding: 0;\n    }\n    .swiper-container {\n        width: 100%;\n        height: 300px;\n        margin: 20px auto;\n    }\n    .swiper-slide {\n        text-align: center;\n        font-size: 18px;\n        background: #fff;\n        width: 60%;\n\n        /* Center slide text vertically */\n        display: -webkit-box;\n        display: -ms-flexbox;\n        display: -webkit-flex;\n        display: flex;\n        -webkit-box-pack: center;\n        -ms-flex-pack: center;\n        -webkit-justify-content: center;\n        justify-content: center;\n        -webkit-box-align: center;\n        -ms-flex-align: center;\n        -webkit-align-items: center;\n        align-items: center;\n    }\n    .swiper-slide:nth-child(2n) {\n        width: 40%;\n    }\n    .swiper-slide:nth-child(3n) {\n        width: 20%;\n    }\n    </style>\n</head>\n<body>\n    <!-- Swiper -->\n    <div class=\"swiper-container\">\n        <div class=\"swiper-wrapper\">\n            <div class=\"swiper-slide\">Slide 1</div>\n            <div class=\"swiper-slide\">Slide 2</div>\n            <div class=\"swiper-slide\">Slide 3</div>\n            <div class=\"swiper-slide\">Slide 4</div>\n            <div class=\"swiper-slide\">Slide 5</div>\n            <div class=\"swiper-slide\">Slide 6</div>\n            <div class=\"swiper-slide\">Slide 7</div>\n            <div class=\"swiper-slide\">Slide 8</div>\n            <div class=\"swiper-slide\">Slide 9</div>\n            <div class=\"swiper-slide\">Slide 10</div>\n        </div>\n        <!-- Add Pagination -->\n        <div class=\"swiper-pagination\"></div>\n    </div>\n\n    <!-- Swiper JS -->\n    <script src=\"../dist/js/swiper.min.js\"></script>\n\n    <!-- Initialize Swiper -->\n    <script>\n    var swiper = new Swiper('.swiper-container', {\n        pagination: '.swiper-pagination',\n        slidesPerView: 4,\n        centeredSlides: true,\n        paginationClickable: true,\n        spaceBetween: 30\n    });\n    </script>\n</body>\n</html>"
  },
  {
    "path": "app_backend/static/plugin/Swiper-3.3.1/demos/08-centered-auto.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n    <meta charset=\"utf-8\">\n    <title>Swiper demo</title>\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1, minimum-scale=1, maximum-scale=1\">\n\n    <!-- Link Swiper's CSS -->\n    <link rel=\"stylesheet\" href=\"../dist/css/swiper.min.css\">\n\n    <!-- Demo styles -->\n    <style>\n    body {\n        background: #eee;\n        font-family: Helvetica Neue, Helvetica, Arial, sans-serif;\n        font-size: 14px;\n        color:#000;\n        margin: 0;\n        padding: 0;\n    }\n    .swiper-container {\n        width: 100%;\n        height: 300px;\n        margin: 20px auto;\n    }\n    .swiper-slide {\n        text-align: center;\n        font-size: 18px;\n        background: #fff;\n        width: 60%;\n\n        /* Center slide text vertically */\n        display: -webkit-box;\n        display: -ms-flexbox;\n        display: -webkit-flex;\n        display: flex;\n        -webkit-box-pack: center;\n        -ms-flex-pack: center;\n        -webkit-justify-content: center;\n        justify-content: center;\n        -webkit-box-align: center;\n        -ms-flex-align: center;\n        -webkit-align-items: center;\n        align-items: center;\n    }\n    .swiper-slide:nth-child(2n) {\n        width: 40%;\n    }\n    .swiper-slide:nth-child(3n) {\n        width: 20%;\n    }\n    </style>\n</head>\n<body>\n    <!-- Swiper -->\n    <div class=\"swiper-container\">\n        <div class=\"swiper-wrapper\">\n            <div class=\"swiper-slide\">Slide 1</div>\n            <div class=\"swiper-slide\">Slide 2</div>\n            <div class=\"swiper-slide\">Slide 3</div>\n            <div class=\"swiper-slide\">Slide 4</div>\n            <div class=\"swiper-slide\">Slide 5</div>\n            <div class=\"swiper-slide\">Slide 6</div>\n            <div class=\"swiper-slide\">Slide 7</div>\n            <div class=\"swiper-slide\">Slide 8</div>\n            <div class=\"swiper-slide\">Slide 9</div>\n            <div class=\"swiper-slide\">Slide 10</div>\n        </div>\n        <!-- Add Pagination -->\n        <div class=\"swiper-pagination\"></div>\n    </div>\n\n    <!-- Swiper JS -->\n    <script src=\"../dist/js/swiper.min.js\"></script>\n\n    <!-- Initialize Swiper -->\n    <script>\n    var swiper = new Swiper('.swiper-container', {\n        pagination: '.swiper-pagination',\n        slidesPerView: 'auto',\n        centeredSlides: true,\n        paginationClickable: true,\n        spaceBetween: 30\n    });\n    </script>\n</body>\n</html>"
  },
  {
    "path": "app_backend/static/plugin/Swiper-3.3.1/demos/09-freemode.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n    <meta charset=\"utf-8\">\n    <title>Swiper demo</title>\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1, minimum-scale=1, maximum-scale=1\">\n\n    <!-- Link Swiper's CSS -->\n    <link rel=\"stylesheet\" href=\"../dist/css/swiper.min.css\">\n\n    <!-- Demo styles -->\n    <style>\n    body {\n        background: #eee;\n        font-family: Helvetica Neue, Helvetica, Arial, sans-serif;\n        font-size: 14px;\n        color:#000;\n        margin: 0;\n        padding: 0;\n    }\n    .swiper-container {\n        width: 100%;\n        height: 300px;\n        margin: 20px auto;\n    }\n    .swiper-slide {\n        text-align: center;\n        font-size: 18px;\n        background: #fff;\n        \n        /* Center slide text vertically */\n        display: -webkit-box;\n        display: -ms-flexbox;\n        display: -webkit-flex;\n        display: flex;\n        -webkit-box-pack: center;\n        -ms-flex-pack: center;\n        -webkit-justify-content: center;\n        justify-content: center;\n        -webkit-box-align: center;\n        -ms-flex-align: center;\n        -webkit-align-items: center;\n        align-items: center;\n    }\n    </style>\n</head>\n<body>\n    <!-- Swiper -->\n    <div class=\"swiper-container\">\n        <div class=\"swiper-wrapper\">\n            <div class=\"swiper-slide\">Slide 1</div>\n            <div class=\"swiper-slide\">Slide 2</div>\n            <div class=\"swiper-slide\">Slide 3</div>\n            <div class=\"swiper-slide\">Slide 4</div>\n            <div class=\"swiper-slide\">Slide 5</div>\n            <div class=\"swiper-slide\">Slide 6</div>\n            <div class=\"swiper-slide\">Slide 7</div>\n            <div class=\"swiper-slide\">Slide 8</div>\n            <div class=\"swiper-slide\">Slide 9</div>\n            <div class=\"swiper-slide\">Slide 10</div>\n        </div>\n        <!-- Add Pagination -->\n        <div class=\"swiper-pagination\"></div>\n    </div>\n\n    <!-- Swiper JS -->\n    <script src=\"../dist/js/swiper.min.js\"></script>\n\n    <!-- Initialize Swiper -->\n    <script>\n    var swiper = new Swiper('.swiper-container', {\n        pagination: '.swiper-pagination',\n        slidesPerView: 3,\n        paginationClickable: true,\n        spaceBetween: 30,\n        freeMode: true\n    });\n    </script>\n</body>\n</html>"
  },
  {
    "path": "app_backend/static/plugin/Swiper-3.3.1/demos/10-slides-per-column.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n    <meta charset=\"utf-8\">\n    <title>Swiper demo</title>\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1, minimum-scale=1, maximum-scale=1\">\n\n    <!-- Link Swiper's CSS -->\n    <link rel=\"stylesheet\" href=\"../dist/css/swiper.min.css\">\n\n    <!-- Demo styles -->\n    <style>\n    body {\n        background: #eee;\n        font-family: Helvetica Neue, Helvetica, Arial, sans-serif;\n        font-size: 14px;\n        color:#000;\n        margin: 0;\n        padding: 0;\n    }\n    .swiper-container {\n        width: 100%;\n        height: auto;\n        margin-left: auto;\n        margin-right: auto;\n    }\n    .swiper-slide {\n        text-align: center;\n        font-size: 18px;\n        background: #fff;\n        height: 200px;\n        \n        /* Center slide text vertically */\n        display: -webkit-box;\n        display: -ms-flexbox;\n        display: -webkit-flex;\n        display: flex;\n        -webkit-box-pack: center;\n        -ms-flex-pack: center;\n        -webkit-justify-content: center;\n        justify-content: center;\n        -webkit-box-align: center;\n        -ms-flex-align: center;\n        -webkit-align-items: center;\n        align-items: center;\n    }\n    </style>\n</head>\n<body>\n    <!-- Swiper -->\n    <div class=\"swiper-container\">\n        <div class=\"swiper-wrapper\">\n            <div class=\"swiper-slide\">Slide 1</div>\n            <div class=\"swiper-slide\">Slide 2</div>\n            <div class=\"swiper-slide\">Slide 3</div>\n            <div class=\"swiper-slide\">Slide 4</div>\n            <div class=\"swiper-slide\">Slide 5</div>\n            <div class=\"swiper-slide\">Slide 6</div>\n            <div class=\"swiper-slide\">Slide 7</div>\n            <div class=\"swiper-slide\">Slide 8</div>\n            <div class=\"swiper-slide\">Slide 9</div>\n            <div class=\"swiper-slide\">Slide 10</div>\n        </div>\n        <!-- Add Pagination -->\n        <div class=\"swiper-pagination\"></div>\n    </div>\n\n    <!-- Swiper JS -->\n    <script src=\"../dist/js/swiper.min.js\"></script>\n\n    <!-- Initialize Swiper -->\n    <script>\n    var swiper = new Swiper('.swiper-container', {\n        pagination: '.swiper-pagination',\n        slidesPerView: 3,\n        slidesPerColumn: 2,\n        paginationClickable: true,\n        spaceBetween: 30\n    });\n    </script>\n</body>\n</html>"
  },
  {
    "path": "app_backend/static/plugin/Swiper-3.3.1/demos/11-nested.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n    <meta charset=\"utf-8\">\n    <title>Swiper demo</title>\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1, minimum-scale=1, maximum-scale=1\">\n\n    <!-- Link Swiper's CSS -->\n    <link rel=\"stylesheet\" href=\"../dist/css/swiper.min.css\">\n\n    <!-- Demo styles -->\n    <style>\n    html, body {\n        position: relative;\n        height: 100%;\n    }\n    body {\n        background: #eee;\n        font-family: Helvetica Neue, Helvetica, Arial, sans-serif;\n        font-size: 14px;\n        color:#000;\n        margin: 0;\n        padding: 0;\n    }\n    .swiper-container {\n        width: 100%;\n        height: 100%;\n    }\n    .swiper-slide {\n        text-align: center;\n        font-size: 18px;\n        background: #fff;\n\n        /* Center slide text vertically */\n        display: -webkit-box;\n        display: -ms-flexbox;\n        display: -webkit-flex;\n        display: flex;\n        -webkit-box-pack: center;\n        -ms-flex-pack: center;\n        -webkit-justify-content: center;\n        justify-content: center;\n        -webkit-box-align: center;\n        -ms-flex-align: center;\n        -webkit-align-items: center;\n        align-items: center;\n    }\n    .swiper-container-v {\n        background: #eee;\n    }\n    </style>\n</head>\n<body>\n    <!-- Swiper -->\n    <div class=\"swiper-container swiper-container-h\">\n        <div class=\"swiper-wrapper\">\n            <div class=\"swiper-slide\">Horizontal Slide 1</div>\n            <div class=\"swiper-slide\">\n                <div class=\"swiper-container swiper-container-v\">\n                    <div class=\"swiper-wrapper\">\n                        <div class=\"swiper-slide\">Vertical Slide 1</div>\n                        <div class=\"swiper-slide\">Vertical Slide 2</div>\n                        <div class=\"swiper-slide\">Vertical Slide 3</div>\n                        <div class=\"swiper-slide\">Vertical Slide 4</div>\n                        <div class=\"swiper-slide\">Vertical Slide 5</div>\n                    </div>\n                    <div class=\"swiper-pagination swiper-pagination-v\"></div>\n                </div>\n            </div>\n            <div class=\"swiper-slide\">Horizontal Slide 3</div>\n            <div class=\"swiper-slide\">Horizontal Slide 4</div>\n        </div>\n        <!-- Add Pagination -->\n        <div class=\"swiper-pagination swiper-pagination-h\"></div>\n    </div>\n\n    <!-- Swiper JS -->\n    <script src=\"../dist/js/swiper.min.js\"></script>\n\n    <!-- Initialize Swiper -->\n    <script>\n    var swiperH = new Swiper('.swiper-container-h', {\n        pagination: '.swiper-pagination-h',\n        paginationClickable: true,\n        spaceBetween: 50\n    });\n    var swiperV = new Swiper('.swiper-container-v', {\n        pagination: '.swiper-pagination-v',\n        paginationClickable: true,\n        direction: 'vertical',\n        spaceBetween: 50\n    });\n    </script>\n</body>\n</html>"
  },
  {
    "path": "app_backend/static/plugin/Swiper-3.3.1/demos/12-grab-cursor.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n    <meta charset=\"utf-8\">\n    <title>Swiper demo</title>\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1, minimum-scale=1, maximum-scale=1\">\n\n    <!-- Link Swiper's CSS -->\n    <link rel=\"stylesheet\" href=\"../dist/css/swiper.min.css\">\n\n    <!-- Demo styles -->\n    <style>\n    body {\n        background: #eee;\n        font-family: Helvetica Neue, Helvetica, Arial, sans-serif;\n        font-size: 14px;\n        color:#000;\n        margin: 0;\n        padding: 0;\n    }\n    .swiper-container {\n        width: 100%;\n        height: 300px;\n        margin: 20px auto;\n    }\n    .swiper-slide {\n        text-align: center;\n        font-size: 18px;\n        background: #fff;\n        width: 60%;\n\n        /* Center slide text vertically */\n        display: -webkit-box;\n        display: -ms-flexbox;\n        display: -webkit-flex;\n        display: flex;\n        -webkit-box-pack: center;\n        -ms-flex-pack: center;\n        -webkit-justify-content: center;\n        justify-content: center;\n        -webkit-box-align: center;\n        -ms-flex-align: center;\n        -webkit-align-items: center;\n        align-items: center;\n    }\n    .swiper-slide:nth-child(2n) {\n        width: 40%;\n    }\n    .swiper-slide:nth-child(3n) {\n        width: 20%;\n    }\n    </style>\n</head>\n<body>\n    <!-- Swiper -->\n    <div class=\"swiper-container\">\n        <div class=\"swiper-wrapper\">\n            <div class=\"swiper-slide\">Slide 1</div>\n            <div class=\"swiper-slide\">Slide 2</div>\n            <div class=\"swiper-slide\">Slide 3</div>\n            <div class=\"swiper-slide\">Slide 4</div>\n            <div class=\"swiper-slide\">Slide 5</div>\n            <div class=\"swiper-slide\">Slide 6</div>\n            <div class=\"swiper-slide\">Slide 7</div>\n            <div class=\"swiper-slide\">Slide 8</div>\n            <div class=\"swiper-slide\">Slide 9</div>\n            <div class=\"swiper-slide\">Slide 10</div>\n        </div>\n        <!-- Add Pagination -->\n        <div class=\"swiper-pagination\"></div>\n    </div>\n\n    <!-- Swiper JS -->\n    <script src=\"../dist/js/swiper.min.js\"></script>\n\n    <!-- Initialize Swiper -->\n    <script>\n    var swiper = new Swiper('.swiper-container', {\n        pagination: '.swiper-pagination',\n        slidesPerView: 4,\n        centeredSlides: true,\n        paginationClickable: true,\n        spaceBetween: 30,\n        grabCursor: true\n    });\n    </script>\n</body>\n</html>"
  },
  {
    "path": "app_backend/static/plugin/Swiper-3.3.1/demos/13-scrollbar.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n    <meta charset=\"utf-8\">\n    <title>Swiper demo</title>\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1, minimum-scale=1, maximum-scale=1\">\n\n    <!-- Link Swiper's CSS -->\n    <link rel=\"stylesheet\" href=\"../dist/css/swiper.min.css\">\n\n    <!-- Demo styles -->\n    <style>\n    body {\n        background: #eee;\n        font-family: Helvetica Neue, Helvetica, Arial, sans-serif;\n        font-size: 14px;\n        color:#000;\n        margin: 0;\n        padding: 0;\n    }\n    .swiper-container {\n        width: 100%;\n        height: 300px;\n        margin: 20px auto;\n    }\n    .swiper-slide {\n        text-align: center;\n        font-size: 18px;\n        background: #fff;\n        width: 250px;\n\n        /* Center slide text vertically */\n        display: -webkit-box;\n        display: -ms-flexbox;\n        display: -webkit-flex;\n        display: flex;\n        -webkit-box-pack: center;\n        -ms-flex-pack: center;\n        -webkit-justify-content: center;\n        justify-content: center;\n        -webkit-box-align: center;\n        -ms-flex-align: center;\n        -webkit-align-items: center;\n        align-items: center;\n    }\n    </style>\n</head>\n<body>\n    <!-- Swiper -->\n    <div class=\"swiper-container\">\n        <div class=\"swiper-wrapper\">\n            <div class=\"swiper-slide\">Slide 1</div>\n            <div class=\"swiper-slide\">Slide 2</div>\n            <div class=\"swiper-slide\">Slide 3</div>\n            <div class=\"swiper-slide\">Slide 4</div>\n            <div class=\"swiper-slide\">Slide 5</div>\n            <div class=\"swiper-slide\">Slide 6</div>\n            <div class=\"swiper-slide\">Slide 7</div>\n            <div class=\"swiper-slide\">Slide 8</div>\n            <div class=\"swiper-slide\">Slide 9</div>\n            <div class=\"swiper-slide\">Slide 10</div>\n        </div>\n        <!-- Add Scrollbar -->\n        <div class=\"swiper-scrollbar\"></div>\n    </div>\n\n    <!-- Swiper JS -->\n    <script src=\"../dist/js/swiper.min.js\"></script>\n\n    <!-- Initialize Swiper -->\n    <script>\n    var swiper = new Swiper('.swiper-container', {\n        scrollbar: '.swiper-scrollbar',\n        scrollbarHide: true,\n        slidesPerView: 'auto',\n        centeredSlides: true,\n        spaceBetween: 30,\n        grabCursor: true\n    });\n    </script>\n</body>\n</html>"
  },
  {
    "path": "app_backend/static/plugin/Swiper-3.3.1/demos/14-nav-arrows.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n    <meta charset=\"utf-8\">\n    <title>Swiper demo</title>\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1, minimum-scale=1, maximum-scale=1\">\n\n    <!-- Link Swiper's CSS -->\n    <link rel=\"stylesheet\" href=\"../dist/css/swiper.min.css\">\n\n    <!-- Demo styles -->\n    <style>\n    html, body {\n        position: relative;\n        height: 100%;\n    }\n    body {\n        background: #eee;\n        font-family: Helvetica Neue, Helvetica, Arial, sans-serif;\n        font-size: 14px;\n        color:#000;\n        margin: 0;\n        padding: 0;\n    }\n    .swiper-container {\n        width: 100%;\n        height: 100%;\n    }\n    .swiper-slide {\n        text-align: center;\n        font-size: 18px;\n        background: #fff;\n\n        /* Center slide text vertically */\n        display: -webkit-box;\n        display: -ms-flexbox;\n        display: -webkit-flex;\n        display: flex;\n        -webkit-box-pack: center;\n        -ms-flex-pack: center;\n        -webkit-justify-content: center;\n        justify-content: center;\n        -webkit-box-align: center;\n        -ms-flex-align: center;\n        -webkit-align-items: center;\n        align-items: center;\n    }\n    </style>\n</head>\n<body>\n    <!-- Swiper -->\n    <div class=\"swiper-container\">\n        <div class=\"swiper-wrapper\">\n            <div class=\"swiper-slide\">Slide 1</div>\n            <div class=\"swiper-slide\">Slide 2</div>\n            <div class=\"swiper-slide\">Slide 3</div>\n            <div class=\"swiper-slide\">Slide 4</div>\n            <div class=\"swiper-slide\">Slide 5</div>\n            <div class=\"swiper-slide\">Slide 6</div>\n            <div class=\"swiper-slide\">Slide 7</div>\n            <div class=\"swiper-slide\">Slide 8</div>\n            <div class=\"swiper-slide\">Slide 9</div>\n            <div class=\"swiper-slide\">Slide 10</div>\n        </div>\n        <!-- Add Pagination -->\n        <div class=\"swiper-pagination\"></div>\n        <!-- Add Arrows -->\n        <div class=\"swiper-button-next\"></div>\n        <div class=\"swiper-button-prev\"></div>\n    </div>\n\n    <!-- Swiper JS -->\n    <script src=\"../dist/js/swiper.min.js\"></script>\n\n    <!-- Initialize Swiper -->\n    <script>\n    var swiper = new Swiper('.swiper-container', {\n        pagination: '.swiper-pagination',\n        paginationClickable: true,\n        nextButton: '.swiper-button-next',\n        prevButton: '.swiper-button-prev',\n        spaceBetween: 30\n    });\n    </script>\n</body>\n</html>"
  },
  {
    "path": "app_backend/static/plugin/Swiper-3.3.1/demos/15-infinite-loop.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n    <meta charset=\"utf-8\">\n    <title>Swiper demo</title>\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1, minimum-scale=1, maximum-scale=1\">\n\n    <!-- Link Swiper's CSS -->\n    <link rel=\"stylesheet\" href=\"../dist/css/swiper.min.css\">\n\n    <!-- Demo styles -->\n    <style>\n    html, body {\n        position: relative;\n        height: 100%;\n    }\n    body {\n        background: #eee;\n        font-family: Helvetica Neue, Helvetica, Arial, sans-serif;\n        font-size: 14px;\n        color:#000;\n        margin: 0;\n        padding: 0;\n    }\n    .swiper-container {\n        width: 100%;\n        height: 100%;\n        margin-left: auto;\n        margin-right: auto;\n    }\n    .swiper-slide {\n        text-align: center;\n        font-size: 18px;\n        background: #fff;\n\n        /* Center slide text vertically */\n        display: -webkit-box;\n        display: -ms-flexbox;\n        display: -webkit-flex;\n        display: flex;\n        -webkit-box-pack: center;\n        -ms-flex-pack: center;\n        -webkit-justify-content: center;\n        justify-content: center;\n        -webkit-box-align: center;\n        -ms-flex-align: center;\n        -webkit-align-items: center;\n        align-items: center;\n    }\n    </style>\n</head>\n<body>\n    <!-- Swiper -->\n    <div class=\"swiper-container\">\n        <div class=\"swiper-wrapper\">\n            <div class=\"swiper-slide\">Slide 1</div>\n            <div class=\"swiper-slide\">Slide 2</div>\n            <div class=\"swiper-slide\">Slide 3</div>\n            <div class=\"swiper-slide\">Slide 4</div>\n            <div class=\"swiper-slide\">Slide 5</div>\n            <div class=\"swiper-slide\">Slide 6</div>\n            <div class=\"swiper-slide\">Slide 7</div>\n            <div class=\"swiper-slide\">Slide 8</div>\n            <div class=\"swiper-slide\">Slide 9</div>\n            <div class=\"swiper-slide\">Slide 10</div>\n        </div>\n        <!-- Add Pagination -->\n        <div class=\"swiper-pagination\"></div>\n        <!-- Add Arrows -->\n        <div class=\"swiper-button-next\"></div>\n        <div class=\"swiper-button-prev\"></div>\n    </div>\n\n    <!-- Swiper JS -->\n    <script src=\"../dist/js/swiper.min.js\"></script>\n\n    <!-- Initialize Swiper -->\n    <script>\n    var swiper = new Swiper('.swiper-container', {\n        pagination: '.swiper-pagination',\n        nextButton: '.swiper-button-next',\n        prevButton: '.swiper-button-prev',\n        slidesPerView: 1,\n        paginationClickable: true,\n        spaceBetween: 30,\n        loop: true\n    });\n    </script>\n</body>\n</html>"
  },
  {
    "path": "app_backend/static/plugin/Swiper-3.3.1/demos/16-effect-fade.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n    <meta charset=\"utf-8\">\n    <title>Swiper demo</title>\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1, minimum-scale=1, maximum-scale=1\">\n\n    <!-- Link Swiper's CSS -->\n    <link rel=\"stylesheet\" href=\"../dist/css/swiper.min.css\">\n\n    <!-- Demo styles -->\n    <style>\n    html, body {\n        position: relative;\n        height: 100%;\n    }\n    body {\n        background: #eee;\n        font-family: Helvetica Neue, Helvetica, Arial, sans-serif;\n        font-size: 14px;\n        color:#000;\n        margin: 0;\n        padding: 0;\n    }\n    .swiper-container {\n        width: 100%;\n        height: 100%;\n    }\n    .swiper-slide {\n        background-position: center;\n        background-size: cover;\n    }\n    </style>\n</head>\n<body>\n    <!-- Swiper -->\n    <div class=\"swiper-container\">\n        <div class=\"swiper-wrapper\">\n            <div class=\"swiper-slide\" style=\"background-image:url(http://lorempixel.com/1000/1000/nightlife/1)\"></div>\n            <div class=\"swiper-slide\" style=\"background-image:url(http://lorempixel.com/1000/1000/nightlife/2)\"></div>\n            <div class=\"swiper-slide\" style=\"background-image:url(http://lorempixel.com/1000/1000/nightlife/3)\"></div>\n            <div class=\"swiper-slide\" style=\"background-image:url(http://lorempixel.com/1000/1000/nightlife/4)\"></div>\n            <div class=\"swiper-slide\" style=\"background-image:url(http://lorempixel.com/1000/1000/nightlife/5)\"></div>\n        </div>\n        <!-- Add Pagination -->\n        <div class=\"swiper-pagination swiper-pagination-white\"></div>\n        <!-- Add Arrows -->\n        <div class=\"swiper-button-next swiper-button-white\"></div>\n        <div class=\"swiper-button-prev swiper-button-white\"></div>\n    </div>\n\n    <!-- Swiper JS -->\n    <script src=\"../dist/js/swiper.min.js\"></script>\n\n    <!-- Initialize Swiper -->\n    <script>\n    var swiper = new Swiper('.swiper-container', {\n        pagination: '.swiper-pagination',\n        paginationClickable: true,\n        nextButton: '.swiper-button-next',\n        prevButton: '.swiper-button-prev',\n        spaceBetween: 30,\n        effect: 'fade'\n    });\n    </script>\n</body>\n</html>"
  },
  {
    "path": "app_backend/static/plugin/Swiper-3.3.1/demos/17-effect-cube.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n    <meta charset=\"utf-8\">\n    <title>Swiper demo</title>\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1, minimum-scale=1, maximum-scale=1\">\n\n    <!-- Link Swiper's CSS -->\n    <link rel=\"stylesheet\" href=\"../dist/css/swiper.min.css\">\n\n    <!-- Demo styles -->\n    <style>\n    html, body {\n        position: relative;\n        height: 100%;\n    }\n    body {\n        background: #fff;\n        font-family: Helvetica Neue, Helvetica, Arial, sans-serif;\n        font-size: 14px;\n        color:#000;\n        margin: 0;\n        padding: 0;\n    }\n    .swiper-container {\n        width: 300px;\n        height: 300px;\n        position: absolute;\n        left: 50%;\n        top: 50%;\n        margin-left: -150px;\n        margin-top: -150px;\n    }\n    .swiper-slide {\n        background-position: center;\n        background-size: cover;\n    }\n    </style>\n</head>\n<body>\n    <!-- Swiper -->\n    <div class=\"swiper-container\">\n        <div class=\"swiper-wrapper\">\n            <div class=\"swiper-slide\" style=\"background-image:url(http://lorempixel.com/600/600/nature/1)\"></div>\n            <div class=\"swiper-slide\" style=\"background-image:url(http://lorempixel.com/600/600/nature/2)\"></div>\n            <div class=\"swiper-slide\" style=\"background-image:url(http://lorempixel.com/600/600/nature/3)\"></div>\n            <div class=\"swiper-slide\" style=\"background-image:url(http://lorempixel.com/600/600/nature/4)\"></div>\n            <div class=\"swiper-slide\" style=\"background-image:url(http://lorempixel.com/600/600/nature/5)\"></div>\n        </div>\n        <!-- Add Pagination -->\n        <div class=\"swiper-pagination\"></div>\n    </div>\n\n    <!-- Swiper JS -->\n    <script src=\"../dist/js/swiper.min.js\"></script>\n\n    <!-- Initialize Swiper -->\n    <script>\n    var swiper = new Swiper('.swiper-container', {\n        pagination: '.swiper-pagination',\n        effect: 'cube',\n        grabCursor: true,\n        cube: {\n            shadow: true,\n            slideShadows: true,\n            shadowOffset: 20,\n            shadowScale: 0.94\n        }\n    });\n    </script>\n</body>\n</html>"
  },
  {
    "path": "app_backend/static/plugin/Swiper-3.3.1/demos/18-effect-coverflow.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n    <meta charset=\"utf-8\">\n    <title>Swiper demo</title>\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1, minimum-scale=1, maximum-scale=1\">\n\n    <!-- Link Swiper's CSS -->\n    <link rel=\"stylesheet\" href=\"../dist/css/swiper.min.css\">\n\n    <!-- Demo styles -->\n    <style>\n    body {\n        background: #fff;\n        font-family: Helvetica Neue, Helvetica, Arial, sans-serif;\n        font-size: 14px;\n        color:#000;\n        margin: 0;\n        padding: 0;\n    }\n    .swiper-container {\n        width: 100%;\n        padding-top: 50px;\n        padding-bottom: 50px;\n    }\n    .swiper-slide {\n        background-position: center;\n        background-size: cover;\n        width: 300px;\n        height: 300px;\n\n    }\n    </style>\n</head>\n<body>\n    <!-- Swiper -->\n    <div class=\"swiper-container\">\n        <div class=\"swiper-wrapper\">\n            <div class=\"swiper-slide\" style=\"background-image:url(http://lorempixel.com/600/600/nature/1)\"></div>\n            <div class=\"swiper-slide\" style=\"background-image:url(http://lorempixel.com/600/600/nature/2)\"></div>\n            <div class=\"swiper-slide\" style=\"background-image:url(http://lorempixel.com/600/600/nature/3)\"></div>\n            <div class=\"swiper-slide\" style=\"background-image:url(http://lorempixel.com/600/600/nature/4)\"></div>\n            <div class=\"swiper-slide\" style=\"background-image:url(http://lorempixel.com/600/600/nature/5)\"></div>\n            <div class=\"swiper-slide\" style=\"background-image:url(http://lorempixel.com/600/600/nature/6)\"></div>\n            <div class=\"swiper-slide\" style=\"background-image:url(http://lorempixel.com/600/600/nature/7)\"></div>\n            <div class=\"swiper-slide\" style=\"background-image:url(http://lorempixel.com/600/600/nature/8)\"></div>\n            <div class=\"swiper-slide\" style=\"background-image:url(http://lorempixel.com/600/600/nature/9)\"></div>\n            <div class=\"swiper-slide\" style=\"background-image:url(http://lorempixel.com/600/600/nature/10)\"></div>\n        </div>\n        <!-- Add Pagination -->\n        <div class=\"swiper-pagination\"></div>\n    </div>\n\n    <!-- Swiper JS -->\n    <script src=\"../dist/js/swiper.min.js\"></script>\n\n    <!-- Initialize Swiper -->\n    <script>\n    var swiper = new Swiper('.swiper-container', {\n        pagination: '.swiper-pagination',\n        effect: 'coverflow',\n        grabCursor: true,\n        centeredSlides: true,\n        slidesPerView: 'auto',\n        coverflow: {\n            rotate: 50,\n            stretch: 0,\n            depth: 100,\n            modifier: 1,\n            slideShadows : true\n        }\n    });\n    </script>\n</body>\n</html>"
  },
  {
    "path": "app_backend/static/plugin/Swiper-3.3.1/demos/19-keyboard-control.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n    <meta charset=\"utf-8\">\n    <title>Swiper demo</title>\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1, minimum-scale=1, maximum-scale=1\">\n\n    <!-- Link Swiper's CSS -->\n    <link rel=\"stylesheet\" href=\"../dist/css/swiper.min.css\">\n\n    <!-- Demo styles -->\n    <style>\n    html, body {\n        position: relative;\n        height: 100%;\n    }\n    body {\n        background: #eee;\n        font-family: Helvetica Neue, Helvetica, Arial, sans-serif;\n        font-size: 14px;\n        color:#000;\n        margin: 0;\n        padding: 0;\n    }\n    .swiper-container {\n        width: 100%;\n        height: 100%;\n        margin-left: auto;\n        margin-right: auto;\n    }\n    .swiper-slide {\n        text-align: center;\n        font-size: 18px;\n        background: #fff;\n\n        /* Center slide text vertically */\n        display: -webkit-box;\n        display: -ms-flexbox;\n        display: -webkit-flex;\n        display: flex;\n        -webkit-box-pack: center;\n        -ms-flex-pack: center;\n        -webkit-justify-content: center;\n        justify-content: center;\n        -webkit-box-align: center;\n        -ms-flex-align: center;\n        -webkit-align-items: center;\n        align-items: center;\n    }\n    </style>\n</head>\n<body>\n    <!-- Swiper -->\n    <div class=\"swiper-container\">\n        <div class=\"swiper-wrapper\">\n            <div class=\"swiper-slide\">Slide 1</div>\n            <div class=\"swiper-slide\">Slide 2</div>\n            <div class=\"swiper-slide\">Slide 3</div>\n            <div class=\"swiper-slide\">Slide 4</div>\n            <div class=\"swiper-slide\">Slide 5</div>\n            <div class=\"swiper-slide\">Slide 6</div>\n            <div class=\"swiper-slide\">Slide 7</div>\n            <div class=\"swiper-slide\">Slide 8</div>\n            <div class=\"swiper-slide\">Slide 9</div>\n            <div class=\"swiper-slide\">Slide 10</div>\n        </div>\n        <!-- Add Pagination -->\n        <div class=\"swiper-pagination\"></div>\n        <!-- Add Arrows -->\n        <div class=\"swiper-button-next\"></div>\n        <div class=\"swiper-button-prev\"></div>\n    </div>\n\n    <!-- Swiper JS -->\n    <script src=\"../dist/js/swiper.min.js\"></script>\n\n    <!-- Initialize Swiper -->\n    <script>\n    var swiper = new Swiper('.swiper-container', {\n        pagination: '.swiper-pagination',\n        slidesPerView: 1,\n        paginationClickable: true,\n        spaceBetween: 30,\n        keyboardControl: true,\n        nextButton: '.swiper-button-next',\n        prevButton: '.swiper-button-prev',\n    });\n    </script>\n</body>\n</html>"
  },
  {
    "path": "app_backend/static/plugin/Swiper-3.3.1/demos/20-mousewheel-control.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n    <meta charset=\"utf-8\">\n    <title>Swiper demo</title>\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1, minimum-scale=1, maximum-scale=1\">\n\n    <!-- Link Swiper's CSS -->\n    <link rel=\"stylesheet\" href=\"../dist/css/swiper.min.css\">\n\n    <!-- Demo styles -->\n    <style>\n    html, body {\n        position: relative;\n        height: 100%;\n    }\n    body {\n        background: #eee;\n        font-family: Helvetica Neue, Helvetica, Arial, sans-serif;\n        font-size: 14px;\n        color:#000;\n        margin: 0;\n        padding: 0;\n    }\n    .swiper-container {\n        width: 100%;\n        height: 100%;\n        margin-left: auto;\n        margin-right: auto;\n    }\n    .swiper-slide {\n        text-align: center;\n        font-size: 18px;\n        background: #fff;\n\n        /* Center slide text vertically */\n        display: -webkit-box;\n        display: -ms-flexbox;\n        display: -webkit-flex;\n        display: flex;\n        -webkit-box-pack: center;\n        -ms-flex-pack: center;\n        -webkit-justify-content: center;\n        justify-content: center;\n        -webkit-box-align: center;\n        -ms-flex-align: center;\n        -webkit-align-items: center;\n        align-items: center;\n    }\n    </style>\n</head>\n<body>\n    <!-- Swiper -->\n    <div class=\"swiper-container\">\n        <div class=\"swiper-wrapper\">\n            <div class=\"swiper-slide\">Slide 1</div>\n            <div class=\"swiper-slide\">Slide 2</div>\n            <div class=\"swiper-slide\">Slide 3</div>\n            <div class=\"swiper-slide\">Slide 4</div>\n            <div class=\"swiper-slide\">Slide 5</div>\n            <div class=\"swiper-slide\">Slide 6</div>\n            <div class=\"swiper-slide\">Slide 7</div>\n            <div class=\"swiper-slide\">Slide 8</div>\n            <div class=\"swiper-slide\">Slide 9</div>\n            <div class=\"swiper-slide\">Slide 10</div>\n        </div>\n        <!-- Add Pagination -->\n        <div class=\"swiper-pagination\"></div>\n    </div>\n\n    <!-- Swiper JS -->\n    <script src=\"../dist/js/swiper.min.js\"></script>\n\n    <!-- Initialize Swiper -->\n    <script>\n    var swiper = new Swiper('.swiper-container', {\n        pagination: '.swiper-pagination',\n        direction: 'vertical',\n        slidesPerView: 1,\n        paginationClickable: true,\n        spaceBetween: 30,\n        mousewheelControl: true\n    });\n    </script>\n</body>\n</html>"
  },
  {
    "path": "app_backend/static/plugin/Swiper-3.3.1/demos/21-autoplay.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n    <meta charset=\"utf-8\">\n    <title>Swiper demo</title>\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1, minimum-scale=1, maximum-scale=1\">\n\n    <!-- Link Swiper's CSS -->\n    <link rel=\"stylesheet\" href=\"../dist/css/swiper.min.css\">\n\n    <!-- Demo styles -->\n    <style>\n    html, body {\n        position: relative;\n        height: 100%;\n    }\n    body {\n        background: #eee;\n        font-family: Helvetica Neue, Helvetica, Arial, sans-serif;\n        font-size: 14px;\n        color:#000;\n        margin: 0;\n        padding: 0;\n    }\n    .swiper-container {\n        width: 100%;\n        height: 100%;\n        \n    }\n    .swiper-slide {\n        text-align: center;\n        font-size: 18px;\n        background: #fff;\n        \n        /* Center slide text vertically */\n        display: -webkit-box;\n        display: -ms-flexbox;\n        display: -webkit-flex;\n        display: flex;\n        -webkit-box-pack: center;\n        -ms-flex-pack: center;\n        -webkit-justify-content: center;\n        justify-content: center;\n        -webkit-box-align: center;\n        -ms-flex-align: center;\n        -webkit-align-items: center;\n        align-items: center;\n    }\n    </style>\n</head>\n<body>\n    <!-- Swiper -->\n    <div class=\"swiper-container\">\n        <div class=\"swiper-wrapper\">\n            <div class=\"swiper-slide\">Slide 1</div>\n            <div class=\"swiper-slide\">Slide 2</div>\n            <div class=\"swiper-slide\">Slide 3</div>\n            <div class=\"swiper-slide\">Slide 4</div>\n            <div class=\"swiper-slide\">Slide 5</div>\n            <div class=\"swiper-slide\">Slide 6</div>\n            <div class=\"swiper-slide\">Slide 7</div>\n            <div class=\"swiper-slide\">Slide 8</div>\n            <div class=\"swiper-slide\">Slide 9</div>\n            <div class=\"swiper-slide\">Slide 10</div>\n        </div>\n        <!-- Add Pagination -->\n        <div class=\"swiper-pagination\"></div>\n        <!-- Add Arrows -->\n        <div class=\"swiper-button-next\"></div>\n        <div class=\"swiper-button-prev\"></div>\n    </div>\n\n    <!-- Swiper JS -->\n    <script src=\"../dist/js/swiper.min.js\"></script>\n\n    <!-- Initialize Swiper -->\n    <script>\n    var swiper = new Swiper('.swiper-container', {\n        pagination: '.swiper-pagination',\n        nextButton: '.swiper-button-next',\n        prevButton: '.swiper-button-prev',\n        paginationClickable: true,\n        spaceBetween: 30,\n        centeredSlides: true,\n        autoplay: 2500,\n        autoplayDisableOnInteraction: false\n    });\n    </script>\n</body>\n</html>"
  },
  {
    "path": "app_backend/static/plugin/Swiper-3.3.1/demos/22-dynamic-slides.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n    <meta charset=\"utf-8\">\n    <title>Swiper demo</title>\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1, minimum-scale=1, maximum-scale=1\">\n\n    <!-- Link Swiper's CSS -->\n    <link rel=\"stylesheet\" href=\"../dist/css/swiper.min.css\">\n\n    <!-- Demo styles -->\n    <style>\n    body {\n        background: #eee;\n        font-family: Helvetica Neue, Helvetica, Arial, sans-serif;\n        font-size: 14px;\n        color:#000;\n        margin: 0;\n        padding: 0;\n    }\n    .swiper-container {\n        width: 100%;\n        height: 300px;\n        margin: 20px auto;\n    }\n    .swiper-slide {\n        text-align: center;\n        font-size: 18px;\n        background: #fff;\n        \n        /* Center slide text vertically */\n        display: -webkit-box;\n        display: -ms-flexbox;\n        display: -webkit-flex;\n        display: flex;\n        -webkit-box-pack: center;\n        -ms-flex-pack: center;\n        -webkit-justify-content: center;\n        justify-content: center;\n        -webkit-box-align: center;\n        -ms-flex-align: center;\n        -webkit-align-items: center;\n        align-items: center;\n    }\n    .append-buttons {\n        text-align: center;\n        margin-top: 20px;\n    }\n    .append-buttons a {\n        display: inline-block;\n        border: 1px solid #007aff;\n        color: #007aff;\n        text-decoration: none;\n        padding: 4px 10px;\n        border-radius: 4px;\n        margin: 0 10px;\n        font-size: 13px;\n    }\n    </style>\n</head>\n<body>\n    <!-- Swiper -->\n    <div class=\"swiper-container\">\n        <div class=\"swiper-wrapper\">\n            <div class=\"swiper-slide\">Slide 1</div>\n            <div class=\"swiper-slide\">Slide 2</div>\n            <div class=\"swiper-slide\">Slide 3</div>\n            <div class=\"swiper-slide\">Slide 4</div>\n        </div>\n        <!-- Add Pagination -->\n        <div class=\"swiper-pagination\"></div>\n        <!-- Add Arrows -->\n        <div class=\"swiper-button-next\"></div>\n        <div class=\"swiper-button-prev\"></div>\n    </div>\n    <p class=\"append-buttons\">\n        <a href=\"#\" class=\"prepend-2-slides\">Prepend 2 Slides</a>\n        <a href=\"#\" class=\"prepend-slide\">Prepend Slide</a>\n        <a href=\"#\" class=\"append-slide\">Append Slide</a>\n        <a href=\"#\" class=\"append-2-slides\">Append 2 Slides</a>\n    </p>\n    <!-- Swiper JS -->\n    <script src=\"../dist/js/swiper.min.js\"></script>\n\n    <!-- Initialize Swiper -->\n    <script>\n    var appendNumber = 4;\n    var prependNumber = 1;\n    var swiper = new Swiper('.swiper-container', {\n        pagination: '.swiper-pagination',\n        nextButton: '.swiper-button-next',\n        prevButton: '.swiper-button-prev',\n        slidesPerView: 3,\n        centeredSlides: true,\n        paginationClickable: true,\n        spaceBetween: 30,\n    });\n    document.querySelector('.prepend-2-slides').addEventListener('click', function (e) {\n        e.preventDefault();\n        swiper.prependSlide([\n            '<div class=\"swiper-slide\">Slide ' + (--prependNumber) + '</div>',\n            '<div class=\"swiper-slide\">Slide ' + (--prependNumber) + '</div>'\n        ]);\n    });\n    document.querySelector('.prepend-slide').addEventListener('click', function (e) {\n        e.preventDefault();\n        swiper.prependSlide('<div class=\"swiper-slide\">Slide ' + (--prependNumber) + '</div>');\n    });\n    document.querySelector('.append-slide').addEventListener('click', function (e) {\n        e.preventDefault();\n        swiper.appendSlide('<div class=\"swiper-slide\">Slide ' + (++appendNumber) + '</div>');\n    });\n    document.querySelector('.append-2-slides').addEventListener('click', function (e) {\n        e.preventDefault();\n        swiper.appendSlide([\n            '<div class=\"swiper-slide\">Slide ' + (++appendNumber) + '</div>',\n            '<div class=\"swiper-slide\">Slide ' + (++appendNumber) + '</div>'\n        ]);\n    });\n    </script>\n</body>\n</html>"
  },
  {
    "path": "app_backend/static/plugin/Swiper-3.3.1/demos/23-thumbs-gallery-loop.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n    <meta charset=\"utf-8\">\n    <title>Swiper demo</title>\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1, minimum-scale=1, maximum-scale=1\">\n    <!-- Link Swiper's CSS -->\n    <link rel=\"stylesheet\" href=\"../dist/css/swiper.min.css\">\n\n    <!-- Demo styles -->\n    <style>\n    html, body {\n        position: relative;\n        height: 100%;\n    }\n    body {\n        background: #000;\n        font-family: Helvetica Neue, Helvetica, Arial, sans-serif;\n        font-size: 14px;\n        color:#000;\n        margin: 0;\n        padding: 0;\n    }\n    .swiper-container {\n        width: 100%;\n        height: 300px;\n        margin-left: auto;\n        margin-right: auto;\n    }\n    .swiper-slide {\n        background-size: cover;\n        background-position: center;\n    }\n    .gallery-top {\n        height: 80%;\n        width: 100%;\n    }\n    .gallery-thumbs {\n        height: 20%;\n        box-sizing: border-box;\n        padding: 10px 0;\n    }\n    .gallery-thumbs .swiper-slide {\n        height: 100%;\n        opacity: 0.4;\n    }\n    .gallery-thumbs .swiper-slide-active {\n        opacity: 1;\n    }\n    \n    </style>\n</head>\n<body>\n    <!-- Swiper -->\n    <div class=\"swiper-container gallery-top\">\n        <div class=\"swiper-wrapper\">\n            <div class=\"swiper-slide\" style=\"background-image:url(http://lorempixel.com/1200/1200/nature/1)\"></div>\n            <div class=\"swiper-slide\" style=\"background-image:url(http://lorempixel.com/1200/1200/nature/2)\"></div>\n            <div class=\"swiper-slide\" style=\"background-image:url(http://lorempixel.com/1200/1200/nature/3)\"></div>\n            <div class=\"swiper-slide\" style=\"background-image:url(http://lorempixel.com/1200/1200/nature/4)\"></div>\n            <div class=\"swiper-slide\" style=\"background-image:url(http://lorempixel.com/1200/1200/nature/5)\"></div>\n            <div class=\"swiper-slide\" style=\"background-image:url(http://lorempixel.com/1200/1200/nature/6)\"></div>\n            <div class=\"swiper-slide\" style=\"background-image:url(http://lorempixel.com/1200/1200/nature/7)\"></div>\n            <div class=\"swiper-slide\" style=\"background-image:url(http://lorempixel.com/1200/1200/nature/8)\"></div>\n            <div class=\"swiper-slide\" style=\"background-image:url(http://lorempixel.com/1200/1200/nature/9)\"></div>\n            <div class=\"swiper-slide\" style=\"background-image:url(http://lorempixel.com/1200/1200/nature/10)\"></div>\n        </div>\n        <!-- Add Arrows -->\n        <div class=\"swiper-button-next swiper-button-white\"></div>\n        <div class=\"swiper-button-prev swiper-button-white\"></div>\n    </div>\n    <div class=\"swiper-container gallery-thumbs\">\n        <div class=\"swiper-wrapper\">\n            <div class=\"swiper-slide\" style=\"background-image:url(http://lorempixel.com/1200/1200/nature/1)\"></div>\n            <div class=\"swiper-slide\" style=\"background-image:url(http://lorempixel.com/1200/1200/nature/2)\"></div>\n            <div class=\"swiper-slide\" style=\"background-image:url(http://lorempixel.com/1200/1200/nature/3)\"></div>\n            <div class=\"swiper-slide\" style=\"background-image:url(http://lorempixel.com/1200/1200/nature/4)\"></div>\n            <div class=\"swiper-slide\" style=\"background-image:url(http://lorempixel.com/1200/1200/nature/5)\"></div>\n            <div class=\"swiper-slide\" style=\"background-image:url(http://lorempixel.com/1200/1200/nature/6)\"></div>\n            <div class=\"swiper-slide\" style=\"background-image:url(http://lorempixel.com/1200/1200/nature/7)\"></div>\n            <div class=\"swiper-slide\" style=\"background-image:url(http://lorempixel.com/1200/1200/nature/8)\"></div>\n            <div class=\"swiper-slide\" style=\"background-image:url(http://lorempixel.com/1200/1200/nature/9)\"></div>\n            <div class=\"swiper-slide\" style=\"background-image:url(http://lorempixel.com/1200/1200/nature/10)\"></div>\n        </div>\n    </div>\n\n    <!-- Swiper JS -->\n    <script src=\"../dist/js/swiper.js\"></script>\n\n    <!-- Initialize Swiper -->\n    <script>\n    var galleryTop = new Swiper('.gallery-top', {\n        nextButton: '.swiper-button-next',\n        prevButton: '.swiper-button-prev',\n        spaceBetween: 10,\n        loop:true,\n        loopedSlides: 5, //looped slides should be the same     \n    });\n    var galleryThumbs = new Swiper('.gallery-thumbs', {\n        spaceBetween: 10,\n        slidesPerView: 4,\n        touchRatio: 0.2,\n        loop:true,\n        loopedSlides: 5, //looped slides should be the same\n        slideToClickedSlide: true\n    });\n    galleryTop.params.control = galleryThumbs;\n    galleryThumbs.params.control = galleryTop;\n    \n    </script>\n</body>\n</html>\n"
  },
  {
    "path": "app_backend/static/plugin/Swiper-3.3.1/demos/23-thumbs-gallery.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n    <meta charset=\"utf-8\">\n    <title>Swiper demo</title>\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1, minimum-scale=1, maximum-scale=1\">\n    <!-- Link Swiper's CSS -->\n    <link rel=\"stylesheet\" href=\"../dist/css/swiper.min.css\">\n\n    <!-- Demo styles -->\n    <style>\n    html, body {\n        position: relative;\n        height: 100%;\n    }\n    body {\n        background: #000;\n        font-family: Helvetica Neue, Helvetica, Arial, sans-serif;\n        font-size: 14px;\n        color:#000;\n        margin: 0;\n        padding: 0;\n    }\n    .swiper-container {\n        width: 100%;\n        height: 300px;\n        margin-left: auto;\n        margin-right: auto;\n    }\n    .swiper-slide {\n        background-size: cover;\n        background-position: center;\n    }\n    .gallery-top {\n        height: 80%;\n        width: 100%;\n    }\n    .gallery-thumbs {\n        height: 20%;\n        box-sizing: border-box;\n        padding: 10px 0;\n    }\n    .gallery-thumbs .swiper-slide {\n        width: 25%;\n        height: 100%;\n        opacity: 0.4;\n    }\n    .gallery-thumbs .swiper-slide-active {\n        opacity: 1;\n    }\n    \n    </style>\n</head>\n<body>\n    <!-- Swiper -->\n    <div class=\"swiper-container gallery-top\">\n        <div class=\"swiper-wrapper\">\n            <div class=\"swiper-slide\" style=\"background-image:url(http://lorempixel.com/1200/1200/nature/1)\"></div>\n            <div class=\"swiper-slide\" style=\"background-image:url(http://lorempixel.com/1200/1200/nature/2)\"></div>\n            <div class=\"swiper-slide\" style=\"background-image:url(http://lorempixel.com/1200/1200/nature/3)\"></div>\n            <div class=\"swiper-slide\" style=\"background-image:url(http://lorempixel.com/1200/1200/nature/4)\"></div>\n            <div class=\"swiper-slide\" style=\"background-image:url(http://lorempixel.com/1200/1200/nature/5)\"></div>\n            <div class=\"swiper-slide\" style=\"background-image:url(http://lorempixel.com/1200/1200/nature/6)\"></div>\n            <div class=\"swiper-slide\" style=\"background-image:url(http://lorempixel.com/1200/1200/nature/7)\"></div>\n            <div class=\"swiper-slide\" style=\"background-image:url(http://lorempixel.com/1200/1200/nature/8)\"></div>\n            <div class=\"swiper-slide\" style=\"background-image:url(http://lorempixel.com/1200/1200/nature/9)\"></div>\n            <div class=\"swiper-slide\" style=\"background-image:url(http://lorempixel.com/1200/1200/nature/10)\"></div>\n        </div>\n        <!-- Add Arrows -->\n        <div class=\"swiper-button-next swiper-button-white\"></div>\n        <div class=\"swiper-button-prev swiper-button-white\"></div>\n    </div>\n    <div class=\"swiper-container gallery-thumbs\">\n        <div class=\"swiper-wrapper\">\n            <div class=\"swiper-slide\" style=\"background-image:url(http://lorempixel.com/1200/1200/nature/1)\"></div>\n            <div class=\"swiper-slide\" style=\"background-image:url(http://lorempixel.com/1200/1200/nature/2)\"></div>\n            <div class=\"swiper-slide\" style=\"background-image:url(http://lorempixel.com/1200/1200/nature/3)\"></div>\n            <div class=\"swiper-slide\" style=\"background-image:url(http://lorempixel.com/1200/1200/nature/4)\"></div>\n            <div class=\"swiper-slide\" style=\"background-image:url(http://lorempixel.com/1200/1200/nature/5)\"></div>\n            <div class=\"swiper-slide\" style=\"background-image:url(http://lorempixel.com/1200/1200/nature/6)\"></div>\n            <div class=\"swiper-slide\" style=\"background-image:url(http://lorempixel.com/1200/1200/nature/7)\"></div>\n            <div class=\"swiper-slide\" style=\"background-image:url(http://lorempixel.com/1200/1200/nature/8)\"></div>\n            <div class=\"swiper-slide\" style=\"background-image:url(http://lorempixel.com/1200/1200/nature/9)\"></div>\n            <div class=\"swiper-slide\" style=\"background-image:url(http://lorempixel.com/1200/1200/nature/10)\"></div>\n        </div>\n    </div>\n\n    <!-- Swiper JS -->\n    <script src=\"../dist/js/swiper.min.js\"></script>\n\n    <!-- Initialize Swiper -->\n    <script>\n    var galleryTop = new Swiper('.gallery-top', {\n        nextButton: '.swiper-button-next',\n        prevButton: '.swiper-button-prev',\n        spaceBetween: 10,\n    });\n    var galleryThumbs = new Swiper('.gallery-thumbs', {\n        spaceBetween: 10,\n        centeredSlides: true,\n        slidesPerView: 'auto',\n        touchRatio: 0.2,\n        slideToClickedSlide: true\n    });\n    galleryTop.params.control = galleryThumbs;\n    galleryThumbs.params.control = galleryTop;\n    \n    </script>\n</body>\n</html>\n"
  },
  {
    "path": "app_backend/static/plugin/Swiper-3.3.1/demos/24-multiple-swipers.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n    <meta charset=\"utf-8\">\n    <title>Swiper demo</title>\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1, minimum-scale=1, maximum-scale=1\">\n\n    <!-- Link Swiper's CSS -->\n    <link rel=\"stylesheet\" href=\"../dist/css/swiper.min.css\">\n\n    <!-- Demo styles -->\n    <style>\n    body {\n        background: #eee;\n        font-family: Helvetica Neue, Helvetica, Arial, sans-serif;\n        font-size: 14px;\n        color:#000;\n        margin: 0;\n        padding: 0;\n    }\n    .swiper-container {\n        width: 100%;\n        height: 300px;\n        margin: 20px 0;\n    }\n    .swiper-slide {\n        text-align: center;\n        font-size: 18px;\n        background: #fff;\n\n        /* Center slide text vertically */\n        display: -webkit-box;\n        display: -ms-flexbox;\n        display: -webkit-flex;\n        display: flex;\n        -webkit-box-pack: center;\n        -ms-flex-pack: center;\n        -webkit-justify-content: center;\n        justify-content: center;\n        -webkit-box-align: center;\n        -ms-flex-align: center;\n        -webkit-align-items: center;\n        align-items: center;\n    }\n    </style>\n</head>\n<body>\n    <!-- Swiper -->\n    <div class=\"swiper-container swiper1\">\n        <div class=\"swiper-wrapper\">\n            <div class=\"swiper-slide\">Slide 1</div>\n            <div class=\"swiper-slide\">Slide 2</div>\n            <div class=\"swiper-slide\">Slide 3</div>\n            <div class=\"swiper-slide\">Slide 4</div>\n            <div class=\"swiper-slide\">Slide 5</div>\n            <div class=\"swiper-slide\">Slide 6</div>\n            <div class=\"swiper-slide\">Slide 7</div>\n            <div class=\"swiper-slide\">Slide 8</div>\n            <div class=\"swiper-slide\">Slide 9</div>\n            <div class=\"swiper-slide\">Slide 10</div>\n        </div>\n        <!-- Add Pagination -->\n        <div class=\"swiper-pagination swiper-pagination1\"></div>\n    </div>\n\n    <!-- Swiper -->\n    <div class=\"swiper-container swiper2\">\n        <div class=\"swiper-wrapper\">\n            <div class=\"swiper-slide\">Slide 1</div>\n            <div class=\"swiper-slide\">Slide 2</div>\n            <div class=\"swiper-slide\">Slide 3</div>\n            <div class=\"swiper-slide\">Slide 4</div>\n            <div class=\"swiper-slide\">Slide 5</div>\n            <div class=\"swiper-slide\">Slide 6</div>\n            <div class=\"swiper-slide\">Slide 7</div>\n            <div class=\"swiper-slide\">Slide 8</div>\n            <div class=\"swiper-slide\">Slide 9</div>\n            <div class=\"swiper-slide\">Slide 10</div>\n        </div>\n        <!-- Add Pagination -->\n        <div class=\"swiper-pagination swiper-pagination2\"></div>\n    </div>\n\n    <!-- Swiper -->\n    <div class=\"swiper-container swiper3\">\n        <div class=\"swiper-wrapper\">\n            <div class=\"swiper-slide\">Slide 1</div>\n            <div class=\"swiper-slide\">Slide 2</div>\n            <div class=\"swiper-slide\">Slide 3</div>\n            <div class=\"swiper-slide\">Slide 4</div>\n            <div class=\"swiper-slide\">Slide 5</div>\n            <div class=\"swiper-slide\">Slide 6</div>\n            <div class=\"swiper-slide\">Slide 7</div>\n            <div class=\"swiper-slide\">Slide 8</div>\n            <div class=\"swiper-slide\">Slide 9</div>\n            <div class=\"swiper-slide\">Slide 10</div>\n        </div>\n        <!-- Add Pagination -->\n        <div class=\"swiper-pagination swiper-pagination3\"></div>\n    </div>\n\n    <!-- Swiper JS -->\n    <script src=\"../dist/js/swiper.min.js\"></script>\n\n    <!-- Initialize Swiper -->\n    <script>\n    var swiper1 = new Swiper('.swiper1', {\n        pagination: '.swiper-pagination1',\n        paginationClickable: true,\n        spaceBetween: 30,\n    });\n    var swiper2 = new Swiper('.swiper2', {\n        pagination: '.swiper-pagination2',\n        paginationClickable: true,\n        spaceBetween: 30,\n    });\n    var swiper3 = new Swiper('.swiper3', {\n        pagination: '.swiper-pagination3',\n        paginationClickable: true,\n        spaceBetween: 30,\n    });\n    </script>\n</body>\n</html>"
  },
  {
    "path": "app_backend/static/plugin/Swiper-3.3.1/demos/25-hash-navigation.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n    <meta charset=\"utf-8\">\n    <title>Swiper demo</title>\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1, minimum-scale=1, maximum-scale=1\">\n\n    <!-- Link Swiper's CSS -->\n    <link rel=\"stylesheet\" href=\"../dist/css/swiper.min.css\">\n\n    <!-- Demo styles -->\n    <style>\n    html, body {\n        position: relative;\n        height: 100%;\n    }\n    body {\n        background: #eee;\n        font-family: Helvetica Neue, Helvetica, Arial, sans-serif;\n        font-size: 14px;\n        color:#000;\n        margin: 0;\n        padding: 0;\n    }\n    .swiper-container {\n        width: 100%;\n        height: 100%;\n    }\n    .swiper-slide {\n        text-align: center;\n        font-size: 18px;\n        background: #fff;\n        \n        /* Center slide text vertically */\n        display: -webkit-box;\n        display: -ms-flexbox;\n        display: -webkit-flex;\n        display: flex;\n        -webkit-box-pack: center;\n        -ms-flex-pack: center;\n        -webkit-justify-content: center;\n        justify-content: center;\n        -webkit-box-align: center;\n        -ms-flex-align: center;\n        -webkit-align-items: center;\n        align-items: center;\n    }\n    </style>\n</head>\n<body>\n    <!-- Swiper -->\n    <div class=\"swiper-container\">\n        <div class=\"swiper-wrapper\">\n            <div class=\"swiper-slide\" data-hash=\"slide1\">Slide 1</div>\n            <div class=\"swiper-slide\" data-hash=\"slide2\">Slide 2</div>\n            <div class=\"swiper-slide\" data-hash=\"slide3\">Slide 3</div>\n            <div class=\"swiper-slide\" data-hash=\"slide4\">Slide 4</div>\n            <div class=\"swiper-slide\" data-hash=\"slide5\">Slide 5</div>\n            <div class=\"swiper-slide\" data-hash=\"slide6\">Slide 6</div>\n            <div class=\"swiper-slide\" data-hash=\"slide7\">Slide 7</div>\n            <div class=\"swiper-slide\" data-hash=\"slide8\">Slide 8</div>\n            <div class=\"swiper-slide\" data-hash=\"slide9\">Slide 9</div>\n            <div class=\"swiper-slide\" data-hash=\"slide10\">Slide 10</div>\n        </div>\n        <!-- Add Pagination -->\n        <div class=\"swiper-pagination\"></div>\n        <!-- Add Arrows -->\n        <div class=\"swiper-button-next\"></div>\n        <div class=\"swiper-button-prev\"></div>\n    </div>\n\n    <!-- Swiper JS -->\n    <script src=\"../dist/js/swiper.min.js\"></script>\n\n    <!-- Initialize Swiper -->\n    <script>\n    var swiper = new Swiper('.swiper-container', {\n        pagination: '.swiper-pagination',\n        paginationClickable: true,\n        nextButton: '.swiper-button-next',\n        prevButton: '.swiper-button-prev',\n        spaceBetween: 30,\n        hashnav: true\n    });\n    </script>\n</body>\n</html>"
  },
  {
    "path": "app_backend/static/plugin/Swiper-3.3.1/demos/26-rtl.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n    <meta charset=\"utf-8\">\n    <title>Swiper demo</title>\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1, minimum-scale=1, maximum-scale=1\">\n\n    <!-- Link Swiper's CSS -->\n    <link rel=\"stylesheet\" href=\"../dist/css/swiper.min.css\">\n\n    <!-- Demo styles -->\n    <style>\n    html, body {\n        position: relative;\n        height: 100%;\n    }\n    body {\n        background: #eee;\n        font-family: Helvetica Neue, Helvetica, Arial, sans-serif;\n        font-size: 14px;\n        color:#000;\n        margin: 0;\n        padding: 0;\n    }\n    .swiper-container {\n        width: 100%;\n        height: 100%;\n    }\n    .swiper-slide {\n        text-align: center;\n        font-size: 18px;\n        background: #fff;\n\n        /* Center slide text vertically */\n        display: -webkit-box;\n        display: -ms-flexbox;\n        display: -webkit-flex;\n        display: flex;\n        -webkit-box-pack: center;\n        -ms-flex-pack: center;\n        -webkit-justify-content: center;\n        justify-content: center;\n        -webkit-box-align: center;\n        -ms-flex-align: center;\n        -webkit-align-items: center;\n        align-items: center;\n    }\n    </style>\n</head>\n<body>\n    <!-- Swiper -->\n    <div class=\"swiper-container\" dir=\"rtl\">\n        <div class=\"swiper-wrapper\">\n            <div class=\"swiper-slide\">Slide 1</div>\n            <div class=\"swiper-slide\">Slide 2</div>\n            <div class=\"swiper-slide\">Slide 3</div>\n            <div class=\"swiper-slide\">Slide 4</div>\n            <div class=\"swiper-slide\">Slide 5</div>\n            <div class=\"swiper-slide\">Slide 6</div>\n            <div class=\"swiper-slide\">Slide 7</div>\n            <div class=\"swiper-slide\">Slide 8</div>\n            <div class=\"swiper-slide\">Slide 9</div>\n            <div class=\"swiper-slide\">Slide 10</div>\n        </div>\n        <!-- Add Pagination -->\n        <div class=\"swiper-pagination\"></div>\n        <!-- Add Navigation -->\n        <div class=\"swiper-button-prev\"></div>\n        <div class=\"swiper-button-next\"></div>\n    </div>\n\n    <!-- Swiper JS -->\n    <script src=\"../dist/js/swiper.min.js\"></script>\n\n    <!-- Initialize Swiper -->\n    <script>\n    var swiper = new Swiper('.swiper-container', {\n        pagination: '.swiper-pagination',\n        paginationClickable: true,\n        nextButton: '.swiper-button-next',\n        prevButton: '.swiper-button-prev'\n    });\n    </script>\n</body>\n</html>"
  },
  {
    "path": "app_backend/static/plugin/Swiper-3.3.1/demos/27-jquery.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n    <meta charset=\"utf-8\">\n    <title>Swiper demo</title>\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1, minimum-scale=1, maximum-scale=1\">\n\n    <!-- Link Swiper's CSS -->\n    <link rel=\"stylesheet\" href=\"../dist/css/swiper.min.css\">\n\n    <!-- Demo styles -->\n    <style>\n    html, body {\n        position: relative;\n        height: 100%;\n    }\n    body {\n        background: #eee;\n        font-family: Helvetica Neue, Helvetica, Arial, sans-serif;\n        font-size: 14px;\n        color:#000;\n        margin: 0;\n        padding: 0;\n    }\n    .swiper-container {\n        width: 100%;\n        height: 100%;\n    }\n    .swiper-slide {\n        text-align: center;\n        font-size: 18px;\n        background: #fff;\n\n        /* Center slide text vertically */\n        display: -webkit-box;\n        display: -ms-flexbox;\n        display: -webkit-flex;\n        display: flex;\n        -webkit-box-pack: center;\n        -ms-flex-pack: center;\n        -webkit-justify-content: center;\n        justify-content: center;\n        -webkit-box-align: center;\n        -ms-flex-align: center;\n        -webkit-align-items: center;\n        align-items: center;\n    }\n    </style>\n</head>\n<body>\n    <!-- Swiper -->\n    <div class=\"swiper-container\">\n        <div class=\"swiper-wrapper\">\n            <div class=\"swiper-slide\">Slide 1</div>\n            <div class=\"swiper-slide\">Slide 2</div>\n            <div class=\"swiper-slide\">Slide 3</div>\n            <div class=\"swiper-slide\">Slide 4</div>\n            <div class=\"swiper-slide\">Slide 5</div>\n            <div class=\"swiper-slide\">Slide 6</div>\n            <div class=\"swiper-slide\">Slide 7</div>\n            <div class=\"swiper-slide\">Slide 8</div>\n            <div class=\"swiper-slide\">Slide 9</div>\n            <div class=\"swiper-slide\">Slide 10</div>\n        </div>\n        <!-- Add Pagination -->\n        <div class=\"swiper-pagination\"></div>\n        <!-- Add Navigation -->\n        <div class=\"swiper-button-prev\"></div>\n        <div class=\"swiper-button-next\"></div>\n    </div>\n\n    <!-- jQuery -->\n    <script src=\"http://code.jquery.com/jquery-2.1.3.min.js\"></script>\n    <!-- Swiper JS -->\n    <script src=\"../dist/js/swiper.jquery.min.js\"></script>\n\n    <!-- Initialize Swiper -->\n    <script>\n    var swiper = new Swiper('.swiper-container', {\n        pagination: '.swiper-pagination',\n        paginationClickable: true,\n        nextButton: '.swiper-button-next',\n        prevButton: '.swiper-button-prev'\n    });\n    </script>\n</body>\n</html>"
  },
  {
    "path": "app_backend/static/plugin/Swiper-3.3.1/demos/28-parallax.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n    <meta charset=\"utf-8\">\n    <title>Swiper demo</title>\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1, minimum-scale=1, maximum-scale=1\">\n\n    <!-- Link Swiper's CSS -->\n    <link rel=\"stylesheet\" href=\"../dist/css/swiper.min.css\">\n\n    <!-- Demo styles -->\n    <style>\n    html, body {\n        position: relative;\n        height: 100%;\n    }\n    body {\n        background: #eee;\n        font-family: Helvetica Neue, Helvetica, Arial, sans-serif;\n        font-size: 14px;\n        color:#000;\n        margin: 0;\n        padding: 0;\n    }\n    .swiper-container {\n        width: 100%;\n        height: 100%;\n        background: #000;\n    }\n    .swiper-slide {\n        font-size: 18px;\n        color:#fff;\n        -webkit-box-sizing: border-box;\n        box-sizing: border-box;\n        padding: 40px 60px;\n    }\n    .parallax-bg {\n        position: absolute;\n        left: 0;\n        top: 0;\n        width: 130%;\n        height: 100%;\n        -webkit-background-size: cover;\n        background-size: cover;\n        background-position: center;\n    }\n    .swiper-slide .title {\n        font-size: 41px;\n        font-weight: 300;\n    }\n    .swiper-slide .subtitle {\n        font-size: 21px;\n    }\n    .swiper-slide .text {\n        font-size: 14px;\n        max-width: 400px;\n        line-height: 1.3;\n    }\n    \n    </style>\n</head>\n<body>\n    <!-- Swiper -->\n    <div class=\"swiper-container\">\n        <div class=\"parallax-bg\" style=\"background-image:url(http://lorempixel.com/900/600/nightlife/2/)\" data-swiper-parallax=\"-23%\"></div>\n        <div class=\"swiper-wrapper\">\n            <div class=\"swiper-slide\">\n                <div class=\"title\" data-swiper-parallax=\"-100\">Slide 1</div>\n                <div class=\"subtitle\" data-swiper-parallax=\"-200\">Subtitle</div>\n                <div class=\"text\" data-swiper-parallax=\"-300\">\n                    <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aliquam dictum mattis velit, sit amet faucibus felis iaculis nec. Nulla laoreet justo vitae porttitor porttitor. Suspendisse in sem justo. Integer laoreet magna nec elit suscipit, ac laoreet nibh euismod. Aliquam hendrerit lorem at elit facilisis rutrum. Ut at ullamcorper velit. Nulla ligula nisi, imperdiet ut lacinia nec, tincidunt ut libero. Aenean feugiat non eros quis feugiat.</p>\n                </div>\n            </div>\n            <div class=\"swiper-slide\">\n                <div class=\"title\" data-swiper-parallax=\"-100\">Slide 2</div>\n                <div class=\"subtitle\" data-swiper-parallax=\"-200\">Subtitle</div>\n                <div class=\"text\" data-swiper-parallax=\"-300\">\n                    <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aliquam dictum mattis velit, sit amet faucibus felis iaculis nec. Nulla laoreet justo vitae porttitor porttitor. Suspendisse in sem justo. Integer laoreet magna nec elit suscipit, ac laoreet nibh euismod. Aliquam hendrerit lorem at elit facilisis rutrum. Ut at ullamcorper velit. Nulla ligula nisi, imperdiet ut lacinia nec, tincidunt ut libero. Aenean feugiat non eros quis feugiat.</p>\n                </div>\n            </div>\n            <div class=\"swiper-slide\">\n                <div class=\"title\" data-swiper-parallax=\"-100\">Slide 3</div>\n                <div class=\"subtitle\" data-swiper-parallax=\"-200\">Subtitle</div>\n                <div class=\"text\" data-swiper-parallax=\"-300\">\n                    <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aliquam dictum mattis velit, sit amet faucibus felis iaculis nec. Nulla laoreet justo vitae porttitor porttitor. Suspendisse in sem justo. Integer laoreet magna nec elit suscipit, ac laoreet nibh euismod. Aliquam hendrerit lorem at elit facilisis rutrum. Ut at ullamcorper velit. Nulla ligula nisi, imperdiet ut lacinia nec, tincidunt ut libero. Aenean feugiat non eros quis feugiat.</p>\n                </div>\n            </div>\n        </div>\n        <!-- Add Pagination -->\n        <div class=\"swiper-pagination swiper-pagination-white\"></div>\n        <!-- Add Navigation -->\n        <div class=\"swiper-button-prev swiper-button-white\"></div>\n        <div class=\"swiper-button-next swiper-button-white\"></div>\n    </div>\n\n    <!-- Swiper JS -->\n    <script src=\"../dist/js/swiper.min.js\"></script>\n\n    <!-- Initialize Swiper -->\n    <script>\n    var swiper = new Swiper('.swiper-container', {\n        pagination: '.swiper-pagination',\n        paginationClickable: true,\n        nextButton: '.swiper-button-next',\n        prevButton: '.swiper-button-prev',\n        parallax: true,\n        speed: 600,\n    });\n    </script>\n</body>\n</html>"
  },
  {
    "path": "app_backend/static/plugin/Swiper-3.3.1/demos/29-custom-pagination.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n    <meta charset=\"utf-8\">\n    <title>Swiper demo</title>\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1, minimum-scale=1, maximum-scale=1\">\n\n    <!-- Link Swiper's CSS -->\n    <link rel=\"stylesheet\" href=\"../dist/css/swiper.min.css\">\n\n    <!-- Demo styles -->\n    <style>\n    html, body {\n        position: relative;\n        height: 100%;\n    }\n    body {\n        background: #eee;\n        font-family: Helvetica Neue, Helvetica, Arial, sans-serif;\n        font-size: 14px;\n        color:#000;\n        margin: 0;\n        padding: 0;\n    }\n    .swiper-container {\n        width: 100%;\n        height: 100%;\n    }\n    .swiper-slide {\n        text-align: center;\n        font-size: 18px;\n        background: #fff;\n\n        /* Center slide text vertically */\n        display: -webkit-box;\n        display: -ms-flexbox;\n        display: -webkit-flex;\n        display: flex;\n        -webkit-box-pack: center;\n        -ms-flex-pack: center;\n        -webkit-justify-content: center;\n        justify-content: center;\n        -webkit-box-align: center;\n        -ms-flex-align: center;\n        -webkit-align-items: center;\n        align-items: center;\n    }\n    .swiper-pagination-bullet {\n        width: 20px;\n        height: 20px;\n        text-align: center;\n        line-height: 20px;\n        font-size: 12px;\n        color:#000;\n        opacity: 1;\n        background: rgba(0,0,0,0.2);\n    }\n    .swiper-pagination-bullet-active {\n        color:#fff;\n        background: #007aff;\n    }\n    </style>\n</head>\n<body>\n    <!-- Swiper -->\n    <div class=\"swiper-container\">\n        <div class=\"swiper-wrapper\">\n            <div class=\"swiper-slide\">Slide 1</div>\n            <div class=\"swiper-slide\">Slide 2</div>\n            <div class=\"swiper-slide\">Slide 3</div>\n            <div class=\"swiper-slide\">Slide 4</div>\n            <div class=\"swiper-slide\">Slide 5</div>\n            <div class=\"swiper-slide\">Slide 6</div>\n            <div class=\"swiper-slide\">Slide 7</div>\n            <div class=\"swiper-slide\">Slide 8</div>\n            <div class=\"swiper-slide\">Slide 9</div>\n            <div class=\"swiper-slide\">Slide 10</div>\n        </div>\n        <!-- Add Pagination -->\n        <div class=\"swiper-pagination\"></div>\n    </div>\n\n    <!-- Swiper JS -->\n    <script src=\"../dist/js/swiper.min.js\"></script>\n\n    <!-- Initialize Swiper -->\n    <script>\n    var swiper = new Swiper('.swiper-container', {\n        pagination: '.swiper-pagination',\n        paginationClickable: true,\n        paginationBulletRender: function (index, className) {\n            return '<span class=\"' + className + '\">' + (index + 1) + '</span>';\n        }\n    });\n    </script>\n</body>\n</html>"
  },
  {
    "path": "app_backend/static/plugin/Swiper-3.3.1/demos/30-lazy-load-images.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n    <meta charset=\"utf-8\">\n    <title>Swiper demo</title>\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1, minimum-scale=1, maximum-scale=1\">\n\n    <!-- Link Swiper's CSS -->\n    <link rel=\"stylesheet\" href=\"../dist/css/swiper.min.css\">\n\n    <!-- Demo styles -->\n    <style>\n    html, body {\n        position: relative;\n        height: 100%;\n    }\n    body {\n        background: #000;\n        font-family: Helvetica Neue, Helvetica, Arial, sans-serif;\n        font-size: 14px;\n        color:#000;\n        margin: 0;\n        padding: 0;\n    }\n    .swiper-container {\n        width: 100%;\n        height: 100%;\n    }\n    .swiper-slide {\n        text-align: center;\n        font-size: 18px;\n        background: #000;\n        \n    }\n    .swiper-slide img {\n      width: auto;\n      height: auto;\n      max-width: 100%;\n      max-height: 100%;\n      -ms-transform: translate(-50%, -50%);\n      -webkit-transform: translate(-50%, -50%);\n      -moz-transform: translate(-50%, -50%);\n      transform: translate(-50%, -50%);\n      position: absolute;\n      left: 50%;\n      top: 50%;\n    }\n    </style>\n</head>\n<body>\n    <!-- Swiper -->\n    <div class=\"swiper-container\">\n        <div class=\"swiper-wrapper\">\n            <div class=\"swiper-slide\">\n                <!-- Required swiper-lazy class and image source specified in data-src attribute -->\n                <img data-src=\"http://lorempixel.com/1600/1200/nature/1\" class=\"swiper-lazy\">\n                <!-- Preloader image -->\n                <div class=\"swiper-lazy-preloader swiper-lazy-preloader-white\"></div>\n            </div>\n            <div class=\"swiper-slide\">\n                <img data-src=\"http://lorempixel.com/1600/1200/nature/2\" class=\"swiper-lazy\">\n                <div class=\"swiper-lazy-preloader swiper-lazy-preloader-white\"></div>\n            </div>\n            <div class=\"swiper-slide\">\n                <img data-src=\"http://lorempixel.com/1600/1200/nature/3\" class=\"swiper-lazy\">\n                <div class=\"swiper-lazy-preloader swiper-lazy-preloader-white\"></div>\n            </div>\n            <div class=\"swiper-slide\">\n                <img data-src=\"http://lorempixel.com/1600/1200/nature/4\" class=\"swiper-lazy\">\n                <div class=\"swiper-lazy-preloader swiper-lazy-preloader-white\"></div>\n            </div>\n            <div class=\"swiper-slide\">\n                <img data-src=\"http://lorempixel.com/1600/1200/nature/5\" class=\"swiper-lazy\">\n                <div class=\"swiper-lazy-preloader swiper-lazy-preloader-white\"></div>\n            </div>\n            <div class=\"swiper-slide\">\n                <img data-src=\"http://lorempixel.com/1600/1200/nature/6\" class=\"swiper-lazy\">\n                <div class=\"swiper-lazy-preloader swiper-lazy-preloader-white\"></div>\n            </div>\n            \n        </div>\n        <!-- Add Pagination -->\n        <div class=\"swiper-pagination swiper-pagination-white\"></div>\n        <!-- Navigation -->\n        <div class=\"swiper-button-next swiper-button-white\"></div>\n        <div class=\"swiper-button-prev swiper-button-white\"></div>\n    </div>\n\n    <!-- Swiper JS -->\n    <script src=\"../dist/js/swiper.min.js\"></script>\n\n    <!-- Initialize Swiper -->\n    <script>\n    var swiper = new Swiper('.swiper-container', {\n        nextButton: '.swiper-button-next',\n        prevButton: '.swiper-button-prev',\n        pagination: '.swiper-pagination',\n        paginationClickable: true,\n        // Disable preloading of all images\n        preloadImages: false,\n        // Enable lazy loading\n        lazyLoading: true\n    });\n    </script>\n</body>\n</html>"
  },
  {
    "path": "app_backend/static/plugin/Swiper-3.3.1/demos/31-custom-plugin.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n    <meta charset=\"utf-8\">\n    <title>Swiper demo</title>\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1, minimum-scale=1, maximum-scale=1\">\n\n    <!-- Link Swiper's CSS -->\n    <link rel=\"stylesheet\" href=\"../dist/css/swiper.min.css\">\n\n    <!-- Demo styles -->\n    <style>\n    html, body {\n        position: relative;\n        height: 100%;\n    }\n    body {\n        background: #eee;\n        font-family: Helvetica Neue, Helvetica, Arial, sans-serif;\n        font-size: 14px;\n        color:#000;\n        margin: 0;\n        padding: 0;\n    }\n    .swiper-container {\n        width: 100%;\n        height: 100%;\n    }\n    .swiper-slide {\n        text-align: center;\n        font-size: 18px;\n        background: #fff;\n\n        /* Center slide text vertically */\n        display: -webkit-box;\n        display: -ms-flexbox;\n        display: -webkit-flex;\n        display: flex;\n        -webkit-box-pack: center;\n        -ms-flex-pack: center;\n        -webkit-justify-content: center;\n        justify-content: center;\n        -webkit-box-align: center;\n        -ms-flex-align: center;\n        -webkit-align-items: center;\n        align-items: center;\n    }\n    </style>\n</head>\n<body>\n    <!-- Swiper -->\n    <div class=\"swiper-container\">\n        <div class=\"swiper-wrapper\">\n            <div class=\"swiper-slide\">Slide 1</div>\n            <div class=\"swiper-slide\">Slide 2</div>\n            <div class=\"swiper-slide\">Slide 3</div>\n            <div class=\"swiper-slide\">Slide 4</div>\n            <div class=\"swiper-slide\">Slide 5</div>\n            <div class=\"swiper-slide\">Slide 6</div>\n            <div class=\"swiper-slide\">Slide 7</div>\n            <div class=\"swiper-slide\">Slide 8</div>\n            <div class=\"swiper-slide\">Slide 9</div>\n            <div class=\"swiper-slide\">Slide 10</div>\n        </div>\n        <!-- Add Pagination -->\n        <div class=\"swiper-pagination\"></div>\n        <!-- Add Navigation -->\n        <div class=\"swiper-button-prev\"></div>\n        <div class=\"swiper-button-next\"></div>\n    </div>\n\n    <!-- Swiper JS -->\n    <script src=\"../dist/js/swiper.min.js\"></script>\n\n    <!-- Include plugin after Swiper -->\n    <script>\n    /* ========\n    Debugger plugin, simple demo plugin to console.log some of callbacks\n    ======== */\n    Swiper.prototype.plugins.debugger = function (swiper, params) {\n        if (!params) return;\n        // Need to return object with properties that names are the same as callbacks\n        return {\n            onInit: function (swiper){\n                console.log('onInit');\n            },\n            onClick: function (swiper, e) {\n                console.log('onClick');\n            },\n            onTap: function (swiper, e) {\n                console.log('onTap');\n            },\n            onDoubleTap: function (swiper, e) {\n                console.log('onDoubleTap');\n            },\n            onSliderMove: function (swiper, e) {\n                console.log('onSliderMove');\n            },\n            onSlideChangeStart: function (swiper) {\n                console.log('onSlideChangeStart');\n            },\n            onSlideChangeEnd: function (swiper) {\n                console.log('onSlideChangeEnd');\n            },\n            onTransitionStart: function (swiper) {\n                console.log('onTransitionStart');\n            },\n            onTransitionEnd: function (swiper) {\n                console.log('onTransitionEnd');\n            },\n            onReachBeginning: function (swiper) {\n                console.log('onReachBeginning');\n            },\n            onReachEnd: function (swiper) {\n                console.log('onReachEnd');\n            }\n        };\n    };\n    </script>\n\n    <!-- Initialize Swiper -->\n    <script>\n    var swiper = new Swiper('.swiper-container', {\n        pagination: '.swiper-pagination',\n        paginationClickable: true,\n        nextButton: '.swiper-button-next',\n        prevButton: '.swiper-button-prev',\n        // Enable debugger\n        debugger: true\n    });\n    </script>\n</body>\n</html>"
  },
  {
    "path": "app_backend/static/plugin/Swiper-3.3.1/demos/32-scroll-container.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n    <meta charset=\"utf-8\">\n    <title>Swiper demo</title>\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1, minimum-scale=1, maximum-scale=1\">\n\n    <!-- Link Swiper's CSS -->\n    <link rel=\"stylesheet\" href=\"../dist/css/swiper.min.css\">\n\n    <!-- Demo styles -->\n    <style>\n    html, body {\n        position: relative;\n        height: 100%;\n    }\n    body {\n        background: #fff;\n        font-family: Helvetica Neue, Helvetica, Arial, sans-serif;\n        font-size: 14px;\n        color:#000;\n        margin: 0;\n        padding: 0;\n    }\n    .swiper-container {\n        width: 100%;\n        height: 100%;\n    }\n    .swiper-slide {\n        font-size: 18px;\n        height: auto;\n        -webkit-box-sizing: border-box;\n        box-sizing: border-box;\n        padding: 30px;\n    }\n    </style>\n</head>\n<body>\n    <!-- Swiper -->\n    <div class=\"swiper-container\">\n        <div class=\"swiper-wrapper\">\n            <div class=\"swiper-slide\">\n                <h4>Scroll Container</h4>\n                <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. In luctus, ex eu sagittis faucibus, ligula ipsum sagittis magna, et imperdiet dolor lectus eu libero. Vestibulum venenatis eget turpis sed faucibus. Maecenas in ullamcorper orci, eu ullamcorper sem. Etiam elit ante, luctus non ante sit amet, sodales vulputate odio. Aenean tristique nisl tellus, sit amet fringilla nisl volutpat cursus. Quisque dignissim lectus ac nunc consectetur mattis. Proin vel hendrerit ipsum, et lobortis dolor. Vestibulum convallis, nibh et tincidunt tristique, nisl risus facilisis lectus, ut interdum orci nisl ac nunc. Cras et aliquam felis. Quisque vel ipsum at elit sodales posuere eget non est. Fusce convallis vestibulum dolor non volutpat. Vivamus vestibulum quam ut ultricies pretium.</p>\n                <p>Suspendisse rhoncus fringilla nisl. Mauris eget lorem ac urna consectetur convallis non vel mi. Donec libero dolor, volutpat ut urna sit amet, aliquet molestie purus. Phasellus faucibus, leo vel scelerisque lobortis, ipsum leo sollicitudin metus, eget sagittis ante orci eu ipsum. Nulla ac mauris eu risus sagittis scelerisque iaculis bibendum mauris. Cras ut egestas orci. Cras odio risus, sagittis ut nunc vitae, aliquam consectetur purus. Vivamus ornare nunc vel tellus facilisis, quis dictum elit tincidunt. Donec accumsan nisi at laoreet sodales. Cras at ullamcorper massa. Maecenas at facilisis ex. Nam mollis dignissim purus id efficitur.</p>\n                <p>Curabitur eget aliquam erat. Curabitur a neque vitae purus volutpat elementum. Vivamus quis vestibulum leo, efficitur ullamcorper velit. Integer tincidunt finibus metus vel porta. Mauris sed mauris congue, pretium est nec, malesuada purus. Nulla hendrerit consectetur arcu et lacinia. Suspendisse augue justo, convallis eget arcu in, pretium tempor ligula. Nullam vulputate tincidunt est ut ullamcorper.</p>\n                <p>Curabitur sed sodales leo. Nulla facilisi. Etiam condimentum, nisi id tempor vulputate, nisi justo cursus justo, pellentesque condimentum diam arcu sit amet leo. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. In placerat tellus a posuere vehicula. Donec diam massa, efficitur vitae mattis et, pretium in augue. Fusce iaculis mi quis ante venenatis, sit amet pellentesque orci aliquam. Vestibulum elementum posuere vehicula.</p>\n                <p>Sed tincidunt diam a massa pharetra faucibus. Praesent condimentum id arcu nec fringilla. Maecenas faucibus, ante et venenatis interdum, erat mi eleifend dui, at convallis nisl est nec arcu. Duis vitae arcu rhoncus, faucibus magna ut, tempus metus. Cras in nibh sed ipsum consequat rhoncus. Proin fringilla nulla ut augue tempor fermentum. Nunc hendrerit non nisi vitae finibus. Donec eget ornare libero. Aliquam auctor erat enim, a semper risus semper at. In ut dui in metus tincidunt euismod eget et lacus. Aenean et dictum urna, sed rhoncus lorem. Duis pharetra sagittis odio. Etiam a libero ut nisi feugiat tincidunt vel vitae turpis. Maecenas vel orci sit amet lorem hendrerit venenatis sollicitudin ut dui. Quisque rhoncus nibh in massa pretium scelerisque.</p>\n                <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. In luctus, ex eu sagittis faucibus, ligula ipsum sagittis magna, et imperdiet dolor lectus eu libero. Vestibulum venenatis eget turpis sed faucibus. Maecenas in ullamcorper orci, eu ullamcorper sem. Etiam elit ante, luctus non ante sit amet, sodales vulputate odio. Aenean tristique nisl tellus, sit amet fringilla nisl volutpat cursus. Quisque dignissim lectus ac nunc consectetur mattis. Proin vel hendrerit ipsum, et lobortis dolor. Vestibulum convallis, nibh et tincidunt tristique, nisl risus facilisis lectus, ut interdum orci nisl ac nunc. Cras et aliquam felis. Quisque vel ipsum at elit sodales posuere eget non est. Fusce convallis vestibulum dolor non volutpat. Vivamus vestibulum quam ut ultricies pretium.</p>\n                <p>Suspendisse rhoncus fringilla nisl. Mauris eget lorem ac urna consectetur convallis non vel mi. Donec libero dolor, volutpat ut urna sit amet, aliquet molestie purus. Phasellus faucibus, leo vel scelerisque lobortis, ipsum leo sollicitudin metus, eget sagittis ante orci eu ipsum. Nulla ac mauris eu risus sagittis scelerisque iaculis bibendum mauris. Cras ut egestas orci. Cras odio risus, sagittis ut nunc vitae, aliquam consectetur purus. Vivamus ornare nunc vel tellus facilisis, quis dictum elit tincidunt. Donec accumsan nisi at laoreet sodales. Cras at ullamcorper massa. Maecenas at facilisis ex. Nam mollis dignissim purus id efficitur.</p>\n                <p>Curabitur eget aliquam erat. Curabitur a neque vitae purus volutpat elementum. Vivamus quis vestibulum leo, efficitur ullamcorper velit. Integer tincidunt finibus metus vel porta. Mauris sed mauris congue, pretium est nec, malesuada purus. Nulla hendrerit consectetur arcu et lacinia. Suspendisse augue justo, convallis eget arcu in, pretium tempor ligula. Nullam vulputate tincidunt est ut ullamcorper.</p>\n                <p>Curabitur sed sodales leo. Nulla facilisi. Etiam condimentum, nisi id tempor vulputate, nisi justo cursus justo, pellentesque condimentum diam arcu sit amet leo. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. In placerat tellus a posuere vehicula. Donec diam massa, efficitur vitae mattis et, pretium in augue. Fusce iaculis mi quis ante venenatis, sit amet pellentesque orci aliquam. Vestibulum elementum posuere vehicula.</p>\n                <p>Sed tincidunt diam a massa pharetra faucibus. Praesent condimentum id arcu nec fringilla. Maecenas faucibus, ante et venenatis interdum, erat mi eleifend dui, at convallis nisl est nec arcu. Duis vitae arcu rhoncus, faucibus magna ut, tempus metus. Cras in nibh sed ipsum consequat rhoncus. Proin fringilla nulla ut augue tempor fermentum. Nunc hendrerit non nisi vitae finibus. Donec eget ornare libero. Aliquam auctor erat enim, a semper risus semper at. In ut dui in metus tincidunt euismod eget et lacus. Aenean et dictum urna, sed rhoncus lorem. Duis pharetra sagittis odio. Etiam a libero ut nisi feugiat tincidunt vel vitae turpis. Maecenas vel orci sit amet lorem hendrerit venenatis sollicitudin ut dui. Quisque rhoncus nibh in massa pretium scelerisque.</p>\n            </div>\n        </div>\n        <!-- Add Scroll Bar -->\n        <div class=\"swiper-scrollbar\"></div>\n    </div>\n\n    <!-- Swiper JS -->\n    <script src=\"../dist/js/swiper.min.js\"></script>\n\n    <!-- Initialize Swiper -->\n    <script>\n    var swiper = new Swiper('.swiper-container', {\n        scrollbar: '.swiper-scrollbar',\n        direction: 'vertical',\n        slidesPerView: 'auto',\n        mousewheelControl: true,\n        freeMode: true\n    });\n    </script>\n</body>\n</html>"
  },
  {
    "path": "app_backend/static/plugin/Swiper-3.3.1/demos/33-responsive-breakpoints.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n    <meta charset=\"utf-8\">\n    <title>Swiper demo</title>\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1, minimum-scale=1, maximum-scale=1\">\n\n    <!-- Link Swiper's CSS -->\n    <link rel=\"stylesheet\" href=\"../dist/css/swiper.min.css\">\n\n    <!-- Demo styles -->\n    <style>\n    html, body {\n        position: relative;\n        height: 100%;\n    }\n    body {\n        background: #eee;\n        font-family: Helvetica Neue, Helvetica, Arial, sans-serif;\n        font-size: 14px;\n        color:#000;\n        margin: 0;\n        padding: 0;\n    }\n    .swiper-container {\n        width: 100%;\n        height: 100%;\n    }\n    .swiper-slide {\n        text-align: center;\n        font-size: 18px;\n        background: #fff;\n\n        /* Center slide text vertically */\n        display: -webkit-box;\n        display: -ms-flexbox;\n        display: -webkit-flex;\n        display: flex;\n        -webkit-box-pack: center;\n        -ms-flex-pack: center;\n        -webkit-justify-content: center;\n        justify-content: center;\n        -webkit-box-align: center;\n        -ms-flex-align: center;\n        -webkit-align-items: center;\n        align-items: center;\n    }\n    </style>\n</head>\n<body>\n    <!-- Swiper -->\n    <div class=\"swiper-container\">\n        <div class=\"swiper-wrapper\">\n            <div class=\"swiper-slide\">Slide 1</div>\n            <div class=\"swiper-slide\">Slide 2</div>\n            <div class=\"swiper-slide\">Slide 3</div>\n            <div class=\"swiper-slide\">Slide 4</div>\n            <div class=\"swiper-slide\">Slide 5</div>\n            <div class=\"swiper-slide\">Slide 6</div>\n            <div class=\"swiper-slide\">Slide 7</div>\n            <div class=\"swiper-slide\">Slide 8</div>\n            <div class=\"swiper-slide\">Slide 9</div>\n            <div class=\"swiper-slide\">Slide 10</div>\n        </div>\n        <!-- Add Pagination -->\n        <div class=\"swiper-pagination\"></div>\n    </div>\n\n    <!-- Swiper JS -->\n    <script src=\"../dist/js/swiper.min.js\"></script>\n\n    <!-- Initialize Swiper -->\n    <script>\n    var swiper = new Swiper('.swiper-container', {\n        pagination: '.swiper-pagination',\n        paginationClickable: true,\n        slidesPerView: 5,\n        spaceBetween: 50,\n        breakpoints: {\n            1024: {\n                slidesPerView: 4,\n                spaceBetween: 40\n            },\n            768: {\n                slidesPerView: 3,\n                spaceBetween: 30\n            },\n            640: {\n                slidesPerView: 2,\n                spaceBetween: 20\n            },\n            320: {\n                slidesPerView: 1,\n                spaceBetween: 10\n            }\n        }\n    });\n    </script>\n</body>\n</html>"
  },
  {
    "path": "app_backend/static/plugin/Swiper-3.3.1/demos/34-autoheight.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n    <meta charset=\"utf-8\">\n    <title>Swiper demo</title>\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1, minimum-scale=1, maximum-scale=1\">\n\n    <!-- Link Swiper's CSS -->\n    <link rel=\"stylesheet\" href=\"../dist/css/swiper.min.css\">\n\n    <!-- Demo styles -->\n    <style>\n    body {\n        background: #eee;\n        font-family: Helvetica Neue, Helvetica, Arial, sans-serif;\n        font-size: 14px;\n        color:#000;\n        margin: 0;\n        padding: 0;\n    }\n    .swiper-container {\n        width: 100%;\n        height: auto;\n    }\n    .swiper-slide {\n        text-align: center;\n        font-size: 18px;\n        background: #fff;\n\n    }\n    .swiper-container .swiper-slide {\n        height: 300px;\n        line-height: 300px;\n    }\n    .swiper-container .swiper-slide:nth-child(2n) {\n        height: 500px;\n        line-height: 500px;\n    }\n    \n    </style>\n</head>\n<body>\n    <!-- Swiper -->\n    <div class=\"swiper-container\">\n        <div class=\"swiper-wrapper\">\n            <div class=\"swiper-slide\">Slide 1</div>\n            <div class=\"swiper-slide\">Slide 2</div>\n            <div class=\"swiper-slide\">Slide 3</div>\n            <div class=\"swiper-slide\">Slide 4</div>\n            <div class=\"swiper-slide\">Slide 5</div>\n            <div class=\"swiper-slide\">Slide 6</div>\n            <div class=\"swiper-slide\">Slide 7</div>\n            <div class=\"swiper-slide\">Slide 8</div>\n            <div class=\"swiper-slide\">Slide 9</div>\n            <div class=\"swiper-slide\">Slide 10</div>\n        </div>\n        <!-- Add Pagination -->\n        <div class=\"swiper-pagination\"></div>\n        <!-- Add Pagination -->\n        <div class=\"swiper-button-next\"></div>\n        <div class=\"swiper-button-prev\"></div>\n    </div>\n\n    <!-- Swiper JS -->\n    <script src=\"../dist/js/swiper.min.js\"></script>\n\n    <!-- Initialize Swiper -->\n    <script>\n    var swiper = new Swiper('.swiper-container', {\n        pagination: '.swiper-pagination',\n        paginationClickable: true,\n        nextButton: '.swiper-button-next',\n        prevButton: '.swiper-button-prev',\n        autoHeight: true, //enable auto height\n    });\n    </script>\n</body>\n</html>"
  },
  {
    "path": "app_backend/static/plugin/Swiper-3.3.1/demos/35-effect-flip.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n    <meta charset=\"utf-8\">\n    <title>Swiper demo</title>\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1, minimum-scale=1, maximum-scale=1\">\n\n    <!-- Link Swiper's CSS -->\n    <link rel=\"stylesheet\" href=\"../dist/css/swiper.min.css\">\n\n    <!-- Demo styles -->\n    <style>\n    body {\n        background: #fff;\n        font-family: Helvetica Neue, Helvetica, Arial, sans-serif;\n        font-size: 14px;\n        color:#000;\n        margin: 0;\n        padding: 0;\n    }\n    .swiper-container {\n        width: 300px;\n        height: 300px;\n        padding: 50px;\n    }\n    .swiper-slide {\n        background-position: center;\n        background-size: cover;\n        width: 300px;\n        height: 300px;\n    }\n    </style>\n</head>\n<body>\n    <!-- Swiper -->\n    <div class=\"swiper-container\">\n        <div class=\"swiper-wrapper\">\n            <div class=\"swiper-slide\" style=\"background-image:url(http://lorempixel.com/600/600/nature/1)\"></div>\n            <div class=\"swiper-slide\" style=\"background-image:url(http://lorempixel.com/600/600/nature/2)\"></div>\n            <div class=\"swiper-slide\" style=\"background-image:url(http://lorempixel.com/600/600/nature/3)\"></div>\n            <div class=\"swiper-slide\" style=\"background-image:url(http://lorempixel.com/600/600/nature/4)\"></div>\n            <div class=\"swiper-slide\" style=\"background-image:url(http://lorempixel.com/600/600/nature/5)\"></div>\n            <div class=\"swiper-slide\" style=\"background-image:url(http://lorempixel.com/600/600/nature/6)\"></div>\n        </div>\n\n        <!-- Add Pagination -->\n        <div class=\"swiper-pagination\"></div>\n\n        <!-- Add Arrows -->\n        <div class=\"swiper-button-prev\"></div>\n        <div class=\"swiper-button-next\"></div>\n    </div>\n\n    <!-- Swiper JS -->\n    <script src=\"../dist/js/swiper.min.js\"></script>\n\n    <!-- Initialize Swiper -->\n    <script>\n    var swiper = new Swiper('.swiper-container', {\n        pagination: '.swiper-pagination',\n        effect: 'flip',\n        grabCursor: true,\n        nextButton: '.swiper-button-next',\n        prevButton: '.swiper-button-prev'\n    });\n    </script>\n</body>\n</html>"
  },
  {
    "path": "app_backend/static/plugin/Swiper-3.3.1/demos/36-pagination-fraction.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n    <meta charset=\"utf-8\">\n    <title>Swiper demo</title>\n    <!-- Link Swiper's CSS -->\n    <link rel=\"stylesheet\" href=\"../dist/css/swiper.min.css\">\n\n    <!-- Demo styles -->\n    <style>\n    body {\n        background: #eee;\n        font-family: Helvetica Neue, Helvetica, Arial, sans-serif;\n        font-size: 14px;\n        color:#000;\n        margin: 0;\n        padding: 0;\n    }\n    .swiper-container {\n        width: 500px;\n        height: 300px;\n        margin: 20px auto;\n    }\n    .swiper-slide {\n        text-align: center;\n        font-size: 18px;\n        background: #fff;\n        line-height: 300px;\n    }\n    </style>\n</head>\n<body>\n    <!-- Swiper -->\n    <div class=\"swiper-container\">\n        <div class=\"swiper-wrapper\">\n            <div class=\"swiper-slide\">Slide 1</div>\n            <div class=\"swiper-slide\">Slide 2</div>\n            <div class=\"swiper-slide\">Slide 3</div>\n            <div class=\"swiper-slide\">Slide 4</div>\n            <div class=\"swiper-slide\">Slide 5</div>\n            <div class=\"swiper-slide\">Slide 6</div>\n            <div class=\"swiper-slide\">Slide 7</div>\n            <div class=\"swiper-slide\">Slide 8</div>\n            <div class=\"swiper-slide\">Slide 9</div>\n            <div class=\"swiper-slide\">Slide 10</div>\n        </div>\n        <!-- Add Pagination -->\n        <div class=\"swiper-pagination\"></div>\n        <!-- Add Arrows -->\n        <div class=\"swiper-button-next\"></div>\n        <div class=\"swiper-button-prev\"></div>\n    </div>\n\n    <!-- Swiper JS -->\n    <script src=\"../dist/js/swiper.min.js\"></script>\n\n    <!-- Initialize Swiper -->\n    <script>\n    var swiper = new Swiper('.swiper-container', {\n        nextButton: '.swiper-button-next',\n        prevButton: '.swiper-button-prev',\n        pagination: '.swiper-pagination',\n        paginationType: 'fraction'\n    });\n    </script>\n</body>\n</html>"
  },
  {
    "path": "app_backend/static/plugin/Swiper-3.3.1/demos/37-pagination-progress.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n    <meta charset=\"utf-8\">\n    <title>Swiper demo</title>\n    <!-- Link Swiper's CSS -->\n    <link rel=\"stylesheet\" href=\"../dist/css/swiper.min.css\">\n\n    <!-- Demo styles -->\n    <style>\n    body {\n        background: #eee;\n        font-family: Helvetica Neue, Helvetica, Arial, sans-serif;\n        font-size: 14px;\n        color:#000;\n        margin: 0;\n        padding: 0;\n    }\n    .swiper-container {\n        width: 500px;\n        height: 300px;\n        margin: 20px auto;\n    }\n    .swiper-slide {\n        text-align: center;\n        font-size: 18px;\n        background: #fff;\n        line-height: 300px;\n    }\n    </style>\n</head>\n<body>\n    <!-- Swiper -->\n    <div class=\"swiper-container\">\n        <div class=\"swiper-wrapper\">\n            <div class=\"swiper-slide\">Slide 1</div>\n            <div class=\"swiper-slide\">Slide 2</div>\n            <div class=\"swiper-slide\">Slide 3</div>\n            <div class=\"swiper-slide\">Slide 4</div>\n            <div class=\"swiper-slide\">Slide 5</div>\n            <div class=\"swiper-slide\">Slide 6</div>\n            <div class=\"swiper-slide\">Slide 7</div>\n            <div class=\"swiper-slide\">Slide 8</div>\n            <div class=\"swiper-slide\">Slide 9</div>\n            <div class=\"swiper-slide\">Slide 10</div>\n        </div>\n        <!-- Add Pagination -->\n        <div class=\"swiper-pagination\"></div>\n        <!-- Add Arrows -->\n        <div class=\"swiper-button-next\"></div>\n        <div class=\"swiper-button-prev\"></div>\n    </div>\n\n    <!-- Swiper JS -->\n    <script src=\"../dist/js/swiper.min.js\"></script>\n\n    <!-- Initialize Swiper -->\n    <script>\n    var swiper = new Swiper('.swiper-container', {\n        nextButton: '.swiper-button-next',\n        prevButton: '.swiper-button-prev',\n        pagination: '.swiper-pagination',\n        paginationType: 'progress'\n    });\n    </script>\n</body>\n</html>"
  },
  {
    "path": "app_backend/static/plugin/Swiper-3.3.1/dist/css/swiper.css",
    "content": "/**\n * Swiper 3.3.1\n * Most modern mobile touch slider and framework with hardware accelerated transitions\n * \n * http://www.idangero.us/swiper/\n * \n * Copyright 2016, Vladimir Kharlampidi\n * The iDangero.us\n * http://www.idangero.us/\n * \n * Licensed under MIT\n * \n * Released on: February 7, 2016\n */\n.swiper-container {\n  margin: 0 auto;\n  position: relative;\n  overflow: hidden;\n  /* Fix of Webkit flickering */\n  z-index: 1;\n}\n.swiper-container-no-flexbox .swiper-slide {\n  float: left;\n}\n.swiper-container-vertical > .swiper-wrapper {\n  -webkit-box-orient: vertical;\n  -moz-box-orient: vertical;\n  -ms-flex-direction: column;\n  -webkit-flex-direction: column;\n  flex-direction: column;\n}\n.swiper-wrapper {\n  position: relative;\n  width: 100%;\n  height: 100%;\n  z-index: 1;\n  display: -webkit-box;\n  display: -moz-box;\n  display: -ms-flexbox;\n  display: -webkit-flex;\n  display: flex;\n  -webkit-transition-property: -webkit-transform;\n  -moz-transition-property: -moz-transform;\n  -o-transition-property: -o-transform;\n  -ms-transition-property: -ms-transform;\n  transition-property: transform;\n  -webkit-box-sizing: content-box;\n  -moz-box-sizing: content-box;\n  box-sizing: content-box;\n}\n.swiper-container-android .swiper-slide,\n.swiper-wrapper {\n  -webkit-transform: translate3d(0px, 0, 0);\n  -moz-transform: translate3d(0px, 0, 0);\n  -o-transform: translate(0px, 0px);\n  -ms-transform: translate3d(0px, 0, 0);\n  transform: translate3d(0px, 0, 0);\n}\n.swiper-container-multirow > .swiper-wrapper {\n  -webkit-box-lines: multiple;\n  -moz-box-lines: multiple;\n  -ms-flex-wrap: wrap;\n  -webkit-flex-wrap: wrap;\n  flex-wrap: wrap;\n}\n.swiper-container-free-mode > .swiper-wrapper {\n  -webkit-transition-timing-function: ease-out;\n  -moz-transition-timing-function: ease-out;\n  -ms-transition-timing-function: ease-out;\n  -o-transition-timing-function: ease-out;\n  transition-timing-function: ease-out;\n  margin: 0 auto;\n}\n.swiper-slide {\n  -webkit-flex-shrink: 0;\n  -ms-flex: 0 0 auto;\n  flex-shrink: 0;\n  width: 100%;\n  height: 100%;\n  position: relative;\n}\n/* Auto Height */\n.swiper-container-autoheight,\n.swiper-container-autoheight .swiper-slide {\n  height: auto;\n}\n.swiper-container-autoheight .swiper-wrapper {\n  -webkit-box-align: start;\n  -ms-flex-align: start;\n  -webkit-align-items: flex-start;\n  align-items: flex-start;\n  -webkit-transition-property: -webkit-transform, height;\n  -moz-transition-property: -moz-transform;\n  -o-transition-property: -o-transform;\n  -ms-transition-property: -ms-transform;\n  transition-property: transform, height;\n}\n/* a11y */\n.swiper-container .swiper-notification {\n  position: absolute;\n  left: 0;\n  top: 0;\n  pointer-events: none;\n  opacity: 0;\n  z-index: -1000;\n}\n/* IE10 Windows Phone 8 Fixes */\n.swiper-wp8-horizontal {\n  -ms-touch-action: pan-y;\n  touch-action: pan-y;\n}\n.swiper-wp8-vertical {\n  -ms-touch-action: pan-x;\n  touch-action: pan-x;\n}\n/* Arrows */\n.swiper-button-prev,\n.swiper-button-next {\n  position: absolute;\n  top: 50%;\n  width: 27px;\n  height: 44px;\n  margin-top: -22px;\n  z-index: 10;\n  cursor: pointer;\n  -moz-background-size: 27px 44px;\n  -webkit-background-size: 27px 44px;\n  background-size: 27px 44px;\n  background-position: center;\n  background-repeat: no-repeat;\n}\n.swiper-button-prev.swiper-button-disabled,\n.swiper-button-next.swiper-button-disabled {\n  opacity: 0.35;\n  cursor: auto;\n  pointer-events: none;\n}\n.swiper-button-prev,\n.swiper-container-rtl .swiper-button-next {\n  background-image: url(\"data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20viewBox%3D'0%200%2027%2044'%3E%3Cpath%20d%3D'M0%2C22L22%2C0l2.1%2C2.1L4.2%2C22l19.9%2C19.9L22%2C44L0%2C22L0%2C22L0%2C22z'%20fill%3D'%23007aff'%2F%3E%3C%2Fsvg%3E\");\n  left: 10px;\n  right: auto;\n}\n.swiper-button-prev.swiper-button-black,\n.swiper-container-rtl .swiper-button-next.swiper-button-black {\n  background-image: url(\"data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20viewBox%3D'0%200%2027%2044'%3E%3Cpath%20d%3D'M0%2C22L22%2C0l2.1%2C2.1L4.2%2C22l19.9%2C19.9L22%2C44L0%2C22L0%2C22L0%2C22z'%20fill%3D'%23000000'%2F%3E%3C%2Fsvg%3E\");\n}\n.swiper-button-prev.swiper-button-white,\n.swiper-container-rtl .swiper-button-next.swiper-button-white {\n  background-image: url(\"data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20viewBox%3D'0%200%2027%2044'%3E%3Cpath%20d%3D'M0%2C22L22%2C0l2.1%2C2.1L4.2%2C22l19.9%2C19.9L22%2C44L0%2C22L0%2C22L0%2C22z'%20fill%3D'%23ffffff'%2F%3E%3C%2Fsvg%3E\");\n}\n.swiper-button-next,\n.swiper-container-rtl .swiper-button-prev {\n  background-image: url(\"data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20viewBox%3D'0%200%2027%2044'%3E%3Cpath%20d%3D'M27%2C22L27%2C22L5%2C44l-2.1-2.1L22.8%2C22L2.9%2C2.1L5%2C0L27%2C22L27%2C22z'%20fill%3D'%23007aff'%2F%3E%3C%2Fsvg%3E\");\n  right: 10px;\n  left: auto;\n}\n.swiper-button-next.swiper-button-black,\n.swiper-container-rtl .swiper-button-prev.swiper-button-black {\n  background-image: url(\"data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20viewBox%3D'0%200%2027%2044'%3E%3Cpath%20d%3D'M27%2C22L27%2C22L5%2C44l-2.1-2.1L22.8%2C22L2.9%2C2.1L5%2C0L27%2C22L27%2C22z'%20fill%3D'%23000000'%2F%3E%3C%2Fsvg%3E\");\n}\n.swiper-button-next.swiper-button-white,\n.swiper-container-rtl .swiper-button-prev.swiper-button-white {\n  background-image: url(\"data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20viewBox%3D'0%200%2027%2044'%3E%3Cpath%20d%3D'M27%2C22L27%2C22L5%2C44l-2.1-2.1L22.8%2C22L2.9%2C2.1L5%2C0L27%2C22L27%2C22z'%20fill%3D'%23ffffff'%2F%3E%3C%2Fsvg%3E\");\n}\n/* Pagination Styles */\n.swiper-pagination {\n  position: absolute;\n  text-align: center;\n  -webkit-transition: 300ms;\n  -moz-transition: 300ms;\n  -o-transition: 300ms;\n  transition: 300ms;\n  -webkit-transform: translate3d(0, 0, 0);\n  -ms-transform: translate3d(0, 0, 0);\n  -o-transform: translate3d(0, 0, 0);\n  transform: translate3d(0, 0, 0);\n  z-index: 10;\n}\n.swiper-pagination.swiper-pagination-hidden {\n  opacity: 0;\n}\n/* Common Styles */\n.swiper-pagination-fraction,\n.swiper-pagination-custom,\n.swiper-container-horizontal > .swiper-pagination-bullets {\n  bottom: 10px;\n  left: 0;\n  width: 100%;\n}\n/* Bullets */\n.swiper-pagination-bullet {\n  width: 8px;\n  height: 8px;\n  display: inline-block;\n  border-radius: 100%;\n  background: #000;\n  opacity: 0.2;\n}\nbutton.swiper-pagination-bullet {\n  border: none;\n  margin: 0;\n  padding: 0;\n  box-shadow: none;\n  -moz-appearance: none;\n  -ms-appearance: none;\n  -webkit-appearance: none;\n  appearance: none;\n}\n.swiper-pagination-clickable .swiper-pagination-bullet {\n  cursor: pointer;\n}\n.swiper-pagination-white .swiper-pagination-bullet {\n  background: #fff;\n}\n.swiper-pagination-bullet-active {\n  opacity: 1;\n  background: #007aff;\n}\n.swiper-pagination-white .swiper-pagination-bullet-active {\n  background: #fff;\n}\n.swiper-pagination-black .swiper-pagination-bullet-active {\n  background: #000;\n}\n.swiper-container-vertical > .swiper-pagination-bullets {\n  right: 10px;\n  top: 50%;\n  -webkit-transform: translate3d(0px, -50%, 0);\n  -moz-transform: translate3d(0px, -50%, 0);\n  -o-transform: translate(0px, -50%);\n  -ms-transform: translate3d(0px, -50%, 0);\n  transform: translate3d(0px, -50%, 0);\n}\n.swiper-container-vertical > .swiper-pagination-bullets .swiper-pagination-bullet {\n  margin: 5px 0;\n  display: block;\n}\n.swiper-container-horizontal > .swiper-pagination-bullets .swiper-pagination-bullet {\n  margin: 0 5px;\n}\n/* Progress */\n.swiper-pagination-progress {\n  background: rgba(0, 0, 0, 0.25);\n  position: absolute;\n}\n.swiper-pagination-progress .swiper-pagination-progressbar {\n  background: #007aff;\n  position: absolute;\n  left: 0;\n  top: 0;\n  width: 100%;\n  height: 100%;\n  -webkit-transform: scale(0);\n  -ms-transform: scale(0);\n  -o-transform: scale(0);\n  transform: scale(0);\n  -webkit-transform-origin: left top;\n  -moz-transform-origin: left top;\n  -ms-transform-origin: left top;\n  -o-transform-origin: left top;\n  transform-origin: left top;\n}\n.swiper-container-rtl .swiper-pagination-progress .swiper-pagination-progressbar {\n  -webkit-transform-origin: right top;\n  -moz-transform-origin: right top;\n  -ms-transform-origin: right top;\n  -o-transform-origin: right top;\n  transform-origin: right top;\n}\n.swiper-container-horizontal > .swiper-pagination-progress {\n  width: 100%;\n  height: 4px;\n  left: 0;\n  top: 0;\n}\n.swiper-container-vertical > .swiper-pagination-progress {\n  width: 4px;\n  height: 100%;\n  left: 0;\n  top: 0;\n}\n.swiper-pagination-progress.swiper-pagination-white {\n  background: rgba(255, 255, 255, 0.5);\n}\n.swiper-pagination-progress.swiper-pagination-white .swiper-pagination-progressbar {\n  background: #fff;\n}\n.swiper-pagination-progress.swiper-pagination-black .swiper-pagination-progressbar {\n  background: #000;\n}\n/* 3D Container */\n.swiper-container-3d {\n  -webkit-perspective: 1200px;\n  -moz-perspective: 1200px;\n  -o-perspective: 1200px;\n  perspective: 1200px;\n}\n.swiper-container-3d .swiper-wrapper,\n.swiper-container-3d .swiper-slide,\n.swiper-container-3d .swiper-slide-shadow-left,\n.swiper-container-3d .swiper-slide-shadow-right,\n.swiper-container-3d .swiper-slide-shadow-top,\n.swiper-container-3d .swiper-slide-shadow-bottom,\n.swiper-container-3d .swiper-cube-shadow {\n  -webkit-transform-style: preserve-3d;\n  -moz-transform-style: preserve-3d;\n  -ms-transform-style: preserve-3d;\n  transform-style: preserve-3d;\n}\n.swiper-container-3d .swiper-slide-shadow-left,\n.swiper-container-3d .swiper-slide-shadow-right,\n.swiper-container-3d .swiper-slide-shadow-top,\n.swiper-container-3d .swiper-slide-shadow-bottom {\n  position: absolute;\n  left: 0;\n  top: 0;\n  width: 100%;\n  height: 100%;\n  pointer-events: none;\n  z-index: 10;\n}\n.swiper-container-3d .swiper-slide-shadow-left {\n  background-image: -webkit-gradient(linear, left top, right top, from(rgba(0, 0, 0, 0.5)), to(rgba(0, 0, 0, 0)));\n  /* Safari 4+, Chrome */\n  background-image: -webkit-linear-gradient(right, rgba(0, 0, 0, 0.5), rgba(0, 0, 0, 0));\n  /* Chrome 10+, Safari 5.1+, iOS 5+ */\n  background-image: -moz-linear-gradient(right, rgba(0, 0, 0, 0.5), rgba(0, 0, 0, 0));\n  /* Firefox 3.6-15 */\n  background-image: -o-linear-gradient(right, rgba(0, 0, 0, 0.5), rgba(0, 0, 0, 0));\n  /* Opera 11.10-12.00 */\n  background-image: linear-gradient(to left, rgba(0, 0, 0, 0.5), rgba(0, 0, 0, 0));\n  /* Firefox 16+, IE10, Opera 12.50+ */\n}\n.swiper-container-3d .swiper-slide-shadow-right {\n  background-image: -webkit-gradient(linear, right top, left top, from(rgba(0, 0, 0, 0.5)), to(rgba(0, 0, 0, 0)));\n  /* Safari 4+, Chrome */\n  background-image: -webkit-linear-gradient(left, rgba(0, 0, 0, 0.5), rgba(0, 0, 0, 0));\n  /* Chrome 10+, Safari 5.1+, iOS 5+ */\n  background-image: -moz-linear-gradient(left, rgba(0, 0, 0, 0.5), rgba(0, 0, 0, 0));\n  /* Firefox 3.6-15 */\n  background-image: -o-linear-gradient(left, rgba(0, 0, 0, 0.5), rgba(0, 0, 0, 0));\n  /* Opera 11.10-12.00 */\n  background-image: linear-gradient(to right, rgba(0, 0, 0, 0.5), rgba(0, 0, 0, 0));\n  /* Firefox 16+, IE10, Opera 12.50+ */\n}\n.swiper-container-3d .swiper-slide-shadow-top {\n  background-image: -webkit-gradient(linear, left top, left bottom, from(rgba(0, 0, 0, 0.5)), to(rgba(0, 0, 0, 0)));\n  /* Safari 4+, Chrome */\n  background-image: -webkit-linear-gradient(bottom, rgba(0, 0, 0, 0.5), rgba(0, 0, 0, 0));\n  /* Chrome 10+, Safari 5.1+, iOS 5+ */\n  background-image: -moz-linear-gradient(bottom, rgba(0, 0, 0, 0.5), rgba(0, 0, 0, 0));\n  /* Firefox 3.6-15 */\n  background-image: -o-linear-gradient(bottom, rgba(0, 0, 0, 0.5), rgba(0, 0, 0, 0));\n  /* Opera 11.10-12.00 */\n  background-image: linear-gradient(to top, rgba(0, 0, 0, 0.5), rgba(0, 0, 0, 0));\n  /* Firefox 16+, IE10, Opera 12.50+ */\n}\n.swiper-container-3d .swiper-slide-shadow-bottom {\n  background-image: -webkit-gradient(linear, left bottom, left top, from(rgba(0, 0, 0, 0.5)), to(rgba(0, 0, 0, 0)));\n  /* Safari 4+, Chrome */\n  background-image: -webkit-linear-gradient(top, rgba(0, 0, 0, 0.5), rgba(0, 0, 0, 0));\n  /* Chrome 10+, Safari 5.1+, iOS 5+ */\n  background-image: -moz-linear-gradient(top, rgba(0, 0, 0, 0.5), rgba(0, 0, 0, 0));\n  /* Firefox 3.6-15 */\n  background-image: -o-linear-gradient(top, rgba(0, 0, 0, 0.5), rgba(0, 0, 0, 0));\n  /* Opera 11.10-12.00 */\n  background-image: linear-gradient(to bottom, rgba(0, 0, 0, 0.5), rgba(0, 0, 0, 0));\n  /* Firefox 16+, IE10, Opera 12.50+ */\n}\n/* Coverflow */\n.swiper-container-coverflow .swiper-wrapper,\n.swiper-container-flip .swiper-wrapper {\n  /* Windows 8 IE 10 fix */\n  -ms-perspective: 1200px;\n}\n/* Cube + Flip */\n.swiper-container-cube,\n.swiper-container-flip {\n  overflow: visible;\n}\n.swiper-container-cube .swiper-slide,\n.swiper-container-flip .swiper-slide {\n  pointer-events: none;\n  -webkit-backface-visibility: hidden;\n  -moz-backface-visibility: hidden;\n  -ms-backface-visibility: hidden;\n  backface-visibility: hidden;\n  z-index: 1;\n}\n.swiper-container-cube .swiper-slide .swiper-slide,\n.swiper-container-flip .swiper-slide .swiper-slide {\n  pointer-events: none;\n}\n.swiper-container-cube .swiper-slide-active,\n.swiper-container-flip .swiper-slide-active,\n.swiper-container-cube .swiper-slide-active .swiper-slide-active,\n.swiper-container-flip .swiper-slide-active .swiper-slide-active {\n  pointer-events: auto;\n}\n.swiper-container-cube .swiper-slide-shadow-top,\n.swiper-container-flip .swiper-slide-shadow-top,\n.swiper-container-cube .swiper-slide-shadow-bottom,\n.swiper-container-flip .swiper-slide-shadow-bottom,\n.swiper-container-cube .swiper-slide-shadow-left,\n.swiper-container-flip .swiper-slide-shadow-left,\n.swiper-container-cube .swiper-slide-shadow-right,\n.swiper-container-flip .swiper-slide-shadow-right {\n  z-index: 0;\n  -webkit-backface-visibility: hidden;\n  -moz-backface-visibility: hidden;\n  -ms-backface-visibility: hidden;\n  backface-visibility: hidden;\n}\n/* Cube */\n.swiper-container-cube .swiper-slide {\n  visibility: hidden;\n  -webkit-transform-origin: 0 0;\n  -moz-transform-origin: 0 0;\n  -ms-transform-origin: 0 0;\n  transform-origin: 0 0;\n  width: 100%;\n  height: 100%;\n}\n.swiper-container-cube.swiper-container-rtl .swiper-slide {\n  -webkit-transform-origin: 100% 0;\n  -moz-transform-origin: 100% 0;\n  -ms-transform-origin: 100% 0;\n  transform-origin: 100% 0;\n}\n.swiper-container-cube .swiper-slide-active,\n.swiper-container-cube .swiper-slide-next,\n.swiper-container-cube .swiper-slide-prev,\n.swiper-container-cube .swiper-slide-next + .swiper-slide {\n  pointer-events: auto;\n  visibility: visible;\n}\n.swiper-container-cube .swiper-cube-shadow {\n  position: absolute;\n  left: 0;\n  bottom: 0px;\n  width: 100%;\n  height: 100%;\n  background: #000;\n  opacity: 0.6;\n  -webkit-filter: blur(50px);\n  filter: blur(50px);\n  z-index: 0;\n}\n/* Fade */\n.swiper-container-fade.swiper-container-free-mode .swiper-slide {\n  -webkit-transition-timing-function: ease-out;\n  -moz-transition-timing-function: ease-out;\n  -ms-transition-timing-function: ease-out;\n  -o-transition-timing-function: ease-out;\n  transition-timing-function: ease-out;\n}\n.swiper-container-fade .swiper-slide {\n  pointer-events: none;\n  -webkit-transition-property: opacity;\n  -moz-transition-property: opacity;\n  -o-transition-property: opacity;\n  transition-property: opacity;\n}\n.swiper-container-fade .swiper-slide .swiper-slide {\n  pointer-events: none;\n}\n.swiper-container-fade .swiper-slide-active,\n.swiper-container-fade .swiper-slide-active .swiper-slide-active {\n  pointer-events: auto;\n}\n/* Scrollbar */\n.swiper-scrollbar {\n  border-radius: 10px;\n  position: relative;\n  -ms-touch-action: none;\n  background: rgba(0, 0, 0, 0.1);\n}\n.swiper-container-horizontal > .swiper-scrollbar {\n  position: absolute;\n  left: 1%;\n  bottom: 3px;\n  z-index: 50;\n  height: 5px;\n  width: 98%;\n}\n.swiper-container-vertical > .swiper-scrollbar {\n  position: absolute;\n  right: 3px;\n  top: 1%;\n  z-index: 50;\n  width: 5px;\n  height: 98%;\n}\n.swiper-scrollbar-drag {\n  height: 100%;\n  width: 100%;\n  position: relative;\n  background: rgba(0, 0, 0, 0.5);\n  border-radius: 10px;\n  left: 0;\n  top: 0;\n}\n.swiper-scrollbar-cursor-drag {\n  cursor: move;\n}\n/* Preloader */\n.swiper-lazy-preloader {\n  width: 42px;\n  height: 42px;\n  position: absolute;\n  left: 50%;\n  top: 50%;\n  margin-left: -21px;\n  margin-top: -21px;\n  z-index: 10;\n  -webkit-transform-origin: 50%;\n  -moz-transform-origin: 50%;\n  transform-origin: 50%;\n  -webkit-animation: swiper-preloader-spin 1s steps(12, end) infinite;\n  -moz-animation: swiper-preloader-spin 1s steps(12, end) infinite;\n  animation: swiper-preloader-spin 1s steps(12, end) infinite;\n}\n.swiper-lazy-preloader:after {\n  display: block;\n  content: \"\";\n  width: 100%;\n  height: 100%;\n  background-image: url(\"data:image/svg+xml;charset=utf-8,%3Csvg%20viewBox%3D'0%200%20120%20120'%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20xmlns%3Axlink%3D'http%3A%2F%2Fwww.w3.org%2F1999%2Fxlink'%3E%3Cdefs%3E%3Cline%20id%3D'l'%20x1%3D'60'%20x2%3D'60'%20y1%3D'7'%20y2%3D'27'%20stroke%3D'%236c6c6c'%20stroke-width%3D'11'%20stroke-linecap%3D'round'%2F%3E%3C%2Fdefs%3E%3Cg%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.27'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.27'%20transform%3D'rotate(30%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.27'%20transform%3D'rotate(60%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.27'%20transform%3D'rotate(90%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.27'%20transform%3D'rotate(120%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.27'%20transform%3D'rotate(150%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.37'%20transform%3D'rotate(180%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.46'%20transform%3D'rotate(210%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.56'%20transform%3D'rotate(240%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.66'%20transform%3D'rotate(270%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.75'%20transform%3D'rotate(300%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.85'%20transform%3D'rotate(330%2060%2C60)'%2F%3E%3C%2Fg%3E%3C%2Fsvg%3E\");\n  background-position: 50%;\n  -webkit-background-size: 100%;\n  background-size: 100%;\n  background-repeat: no-repeat;\n}\n.swiper-lazy-preloader-white:after {\n  background-image: url(\"data:image/svg+xml;charset=utf-8,%3Csvg%20viewBox%3D'0%200%20120%20120'%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20xmlns%3Axlink%3D'http%3A%2F%2Fwww.w3.org%2F1999%2Fxlink'%3E%3Cdefs%3E%3Cline%20id%3D'l'%20x1%3D'60'%20x2%3D'60'%20y1%3D'7'%20y2%3D'27'%20stroke%3D'%23fff'%20stroke-width%3D'11'%20stroke-linecap%3D'round'%2F%3E%3C%2Fdefs%3E%3Cg%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.27'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.27'%20transform%3D'rotate(30%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.27'%20transform%3D'rotate(60%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.27'%20transform%3D'rotate(90%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.27'%20transform%3D'rotate(120%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.27'%20transform%3D'rotate(150%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.37'%20transform%3D'rotate(180%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.46'%20transform%3D'rotate(210%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.56'%20transform%3D'rotate(240%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.66'%20transform%3D'rotate(270%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.75'%20transform%3D'rotate(300%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.85'%20transform%3D'rotate(330%2060%2C60)'%2F%3E%3C%2Fg%3E%3C%2Fsvg%3E\");\n}\n@-webkit-keyframes swiper-preloader-spin {\n  100% {\n    -webkit-transform: rotate(360deg);\n  }\n}\n@keyframes swiper-preloader-spin {\n  100% {\n    transform: rotate(360deg);\n  }\n}\n"
  },
  {
    "path": "app_backend/static/plugin/Swiper-3.3.1/dist/js/swiper.jquery.js",
    "content": "/**\n * Swiper 3.3.1\n * Most modern mobile touch slider and framework with hardware accelerated transitions\n * \n * http://www.idangero.us/swiper/\n * \n * Copyright 2016, Vladimir Kharlampidi\n * The iDangero.us\n * http://www.idangero.us/\n * \n * Licensed under MIT\n * \n * Released on: February 7, 2016\n */\n(function () {\n    'use strict';\n    var $;\n    /*===========================\n    Swiper\n    ===========================*/\n    var Swiper = function (container, params) {\n        if (!(this instanceof Swiper)) return new Swiper(container, params);\n\n        var defaults = {\n            direction: 'horizontal',\n            touchEventsTarget: 'container',\n            initialSlide: 0,\n            speed: 300,\n            // autoplay\n            autoplay: false,\n            autoplayDisableOnInteraction: true,\n            autoplayStopOnLast: false,\n            // To support iOS's swipe-to-go-back gesture (when being used in-app, with UIWebView).\n            iOSEdgeSwipeDetection: false,\n            iOSEdgeSwipeThreshold: 20,\n            // Free mode\n            freeMode: false,\n            freeModeMomentum: true,\n            freeModeMomentumRatio: 1,\n            freeModeMomentumBounce: true,\n            freeModeMomentumBounceRatio: 1,\n            freeModeSticky: false,\n            freeModeMinimumVelocity: 0.02,\n            // Autoheight\n            autoHeight: false,\n            // Set wrapper width\n            setWrapperSize: false,\n            // Virtual Translate\n            virtualTranslate: false,\n            // Effects\n            effect: 'slide', // 'slide' or 'fade' or 'cube' or 'coverflow' or 'flip'\n            coverflow: {\n                rotate: 50,\n                stretch: 0,\n                depth: 100,\n                modifier: 1,\n                slideShadows : true\n            },\n            flip: {\n                slideShadows : true,\n                limitRotation: true\n            },\n            cube: {\n                slideShadows: true,\n                shadow: true,\n                shadowOffset: 20,\n                shadowScale: 0.94\n            },\n            fade: {\n                crossFade: false\n            },\n            // Parallax\n            parallax: false,\n            // Scrollbar\n            scrollbar: null,\n            scrollbarHide: true,\n            scrollbarDraggable: false,\n            scrollbarSnapOnRelease: false,\n            // Keyboard Mousewheel\n            keyboardControl: false,\n            mousewheelControl: false,\n            mousewheelReleaseOnEdges: false,\n            mousewheelInvert: false,\n            mousewheelForceToAxis: false,\n            mousewheelSensitivity: 1,\n            // Hash Navigation\n            hashnav: false,\n            // Breakpoints\n            breakpoints: undefined,\n            // Slides grid\n            spaceBetween: 0,\n            slidesPerView: 1,\n            slidesPerColumn: 1,\n            slidesPerColumnFill: 'column',\n            slidesPerGroup: 1,\n            centeredSlides: false,\n            slidesOffsetBefore: 0, // in px\n            slidesOffsetAfter: 0, // in px\n            // Round length\n            roundLengths: false,\n            // Touches\n            touchRatio: 1,\n            touchAngle: 45,\n            simulateTouch: true,\n            shortSwipes: true,\n            longSwipes: true,\n            longSwipesRatio: 0.5,\n            longSwipesMs: 300,\n            followFinger: true,\n            onlyExternal: false,\n            threshold: 0,\n            touchMoveStopPropagation: true,\n            // Unique Navigation Elements\n            uniqueNavElements: true,\n            // Pagination\n            pagination: null,\n            paginationElement: 'span',\n            paginationClickable: false,\n            paginationHide: false,\n            paginationBulletRender: null,\n            paginationProgressRender: null,\n            paginationFractionRender: null,\n            paginationCustomRender: null,\n            paginationType: 'bullets', // 'bullets' or 'progress' or 'fraction' or 'custom'\n            // Resistance\n            resistance: true,\n            resistanceRatio: 0.85,\n            // Next/prev buttons\n            nextButton: null,\n            prevButton: null,\n            // Progress\n            watchSlidesProgress: false,\n            watchSlidesVisibility: false,\n            // Cursor\n            grabCursor: false,\n            // Clicks\n            preventClicks: true,\n            preventClicksPropagation: true,\n            slideToClickedSlide: false,\n            // Lazy Loading\n            lazyLoading: false,\n            lazyLoadingInPrevNext: false,\n            lazyLoadingInPrevNextAmount: 1,\n            lazyLoadingOnTransitionStart: false,\n            // Images\n            preloadImages: true,\n            updateOnImagesReady: true,\n            // loop\n            loop: false,\n            loopAdditionalSlides: 0,\n            loopedSlides: null,\n            // Control\n            control: undefined,\n            controlInverse: false,\n            controlBy: 'slide', //or 'container'\n            // Swiping/no swiping\n            allowSwipeToPrev: true,\n            allowSwipeToNext: true,\n            swipeHandler: null, //'.swipe-handler',\n            noSwiping: true,\n            noSwipingClass: 'swiper-no-swiping',\n            // NS\n            slideClass: 'swiper-slide',\n            slideActiveClass: 'swiper-slide-active',\n            slideVisibleClass: 'swiper-slide-visible',\n            slideDuplicateClass: 'swiper-slide-duplicate',\n            slideNextClass: 'swiper-slide-next',\n            slidePrevClass: 'swiper-slide-prev',\n            wrapperClass: 'swiper-wrapper',\n            bulletClass: 'swiper-pagination-bullet',\n            bulletActiveClass: 'swiper-pagination-bullet-active',\n            buttonDisabledClass: 'swiper-button-disabled',\n            paginationCurrentClass: 'swiper-pagination-current',\n            paginationTotalClass: 'swiper-pagination-total',\n            paginationHiddenClass: 'swiper-pagination-hidden',\n            paginationProgressbarClass: 'swiper-pagination-progressbar',\n            // Observer\n            observer: false,\n            observeParents: false,\n            // Accessibility\n            a11y: false,\n            prevSlideMessage: 'Previous slide',\n            nextSlideMessage: 'Next slide',\n            firstSlideMessage: 'This is the first slide',\n            lastSlideMessage: 'This is the last slide',\n            paginationBulletMessage: 'Go to slide {{index}}',\n            // Callbacks\n            runCallbacksOnInit: true\n            /*\n            Callbacks:\n            onInit: function (swiper)\n            onDestroy: function (swiper)\n            onClick: function (swiper, e)\n            onTap: function (swiper, e)\n            onDoubleTap: function (swiper, e)\n            onSliderMove: function (swiper, e)\n            onSlideChangeStart: function (swiper)\n            onSlideChangeEnd: function (swiper)\n            onTransitionStart: function (swiper)\n            onTransitionEnd: function (swiper)\n            onImagesReady: function (swiper)\n            onProgress: function (swiper, progress)\n            onTouchStart: function (swiper, e)\n            onTouchMove: function (swiper, e)\n            onTouchMoveOpposite: function (swiper, e)\n            onTouchEnd: function (swiper, e)\n            onReachBeginning: function (swiper)\n            onReachEnd: function (swiper)\n            onSetTransition: function (swiper, duration)\n            onSetTranslate: function (swiper, translate)\n            onAutoplayStart: function (swiper)\n            onAutoplayStop: function (swiper),\n            onLazyImageLoad: function (swiper, slide, image)\n            onLazyImageReady: function (swiper, slide, image)\n            */\n        \n        };\n        var initialVirtualTranslate = params && params.virtualTranslate;\n        \n        params = params || {};\n        var originalParams = {};\n        for (var param in params) {\n            if (typeof params[param] === 'object' && params[param] !== null && !(params[param].nodeType || params[param] === window || params[param] === document || (typeof Dom7 !== 'undefined' && params[param] instanceof Dom7) || (typeof jQuery !== 'undefined' && params[param] instanceof jQuery))) {\n                originalParams[param] = {};\n                for (var deepParam in params[param]) {\n                    originalParams[param][deepParam] = params[param][deepParam];\n                }\n            }\n            else {\n                originalParams[param] = params[param];\n            }\n        }\n        for (var def in defaults) {\n            if (typeof params[def] === 'undefined') {\n                params[def] = defaults[def];\n            }\n            else if (typeof params[def] === 'object') {\n                for (var deepDef in defaults[def]) {\n                    if (typeof params[def][deepDef] === 'undefined') {\n                        params[def][deepDef] = defaults[def][deepDef];\n                    }\n                }\n            }\n        }\n        \n        // Swiper\n        var s = this;\n        \n        // Params\n        s.params = params;\n        s.originalParams = originalParams;\n        \n        // Classname\n        s.classNames = [];\n        /*=========================\n          Dom Library and plugins\n          ===========================*/\n        if (typeof $ !== 'undefined' && typeof Dom7 !== 'undefined'){\n            $ = Dom7;\n        }\n        if (typeof $ === 'undefined') {\n            if (typeof Dom7 === 'undefined') {\n                $ = window.Dom7 || window.Zepto || window.jQuery;\n            }\n            else {\n                $ = Dom7;\n            }\n            if (!$) return;\n        }\n        // Export it to Swiper instance\n        s.$ = $;\n        \n        /*=========================\n          Breakpoints\n          ===========================*/\n        s.currentBreakpoint = undefined;\n        s.getActiveBreakpoint = function () {\n            //Get breakpoint for window width\n            if (!s.params.breakpoints) return false;\n            var breakpoint = false;\n            var points = [], point;\n            for ( point in s.params.breakpoints ) {\n                if (s.params.breakpoints.hasOwnProperty(point)) {\n                    points.push(point);\n                }\n            }\n            points.sort(function (a, b) {\n                return parseInt(a, 10) > parseInt(b, 10);\n            });\n            for (var i = 0; i < points.length; i++) {\n                point = points[i];\n                if (point >= window.innerWidth && !breakpoint) {\n                    breakpoint = point;\n                }\n            }\n            return breakpoint || 'max';\n        };\n        s.setBreakpoint = function () {\n            //Set breakpoint for window width and update parameters\n            var breakpoint = s.getActiveBreakpoint();\n            if (breakpoint && s.currentBreakpoint !== breakpoint) {\n                var breakPointsParams = breakpoint in s.params.breakpoints ? s.params.breakpoints[breakpoint] : s.originalParams;\n                var needsReLoop = s.params.loop && (breakPointsParams.slidesPerView !== s.params.slidesPerView);\n                for ( var param in breakPointsParams ) {\n                    s.params[param] = breakPointsParams[param];\n                }\n                s.currentBreakpoint = breakpoint;\n                if(needsReLoop && s.destroyLoop) {\n                    s.reLoop(true);\n                }\n            }\n        };\n        // Set breakpoint on load\n        if (s.params.breakpoints) {\n            s.setBreakpoint();\n        }\n        \n        /*=========================\n          Preparation - Define Container, Wrapper and Pagination\n          ===========================*/\n        s.container = $(container);\n        if (s.container.length === 0) return;\n        if (s.container.length > 1) {\n            var swipers = [];\n            s.container.each(function () {\n                var container = this;\n                swipers.push(new Swiper(this, params));\n            });\n            return swipers;\n        }\n        \n        // Save instance in container HTML Element and in data\n        s.container[0].swiper = s;\n        s.container.data('swiper', s);\n        \n        s.classNames.push('swiper-container-' + s.params.direction);\n        \n        if (s.params.freeMode) {\n            s.classNames.push('swiper-container-free-mode');\n        }\n        if (!s.support.flexbox) {\n            s.classNames.push('swiper-container-no-flexbox');\n            s.params.slidesPerColumn = 1;\n        }\n        if (s.params.autoHeight) {\n            s.classNames.push('swiper-container-autoheight');\n        }\n        // Enable slides progress when required\n        if (s.params.parallax || s.params.watchSlidesVisibility) {\n            s.params.watchSlidesProgress = true;\n        }\n        // Coverflow / 3D\n        if (['cube', 'coverflow', 'flip'].indexOf(s.params.effect) >= 0) {\n            if (s.support.transforms3d) {\n                s.params.watchSlidesProgress = true;\n                s.classNames.push('swiper-container-3d');\n            }\n            else {\n                s.params.effect = 'slide';\n            }\n        }\n        if (s.params.effect !== 'slide') {\n            s.classNames.push('swiper-container-' + s.params.effect);\n        }\n        if (s.params.effect === 'cube') {\n            s.params.resistanceRatio = 0;\n            s.params.slidesPerView = 1;\n            s.params.slidesPerColumn = 1;\n            s.params.slidesPerGroup = 1;\n            s.params.centeredSlides = false;\n            s.params.spaceBetween = 0;\n            s.params.virtualTranslate = true;\n            s.params.setWrapperSize = false;\n        }\n        if (s.params.effect === 'fade' || s.params.effect === 'flip') {\n            s.params.slidesPerView = 1;\n            s.params.slidesPerColumn = 1;\n            s.params.slidesPerGroup = 1;\n            s.params.watchSlidesProgress = true;\n            s.params.spaceBetween = 0;\n            s.params.setWrapperSize = false;\n            if (typeof initialVirtualTranslate === 'undefined') {\n                s.params.virtualTranslate = true;\n            }\n        }\n        \n        // Grab Cursor\n        if (s.params.grabCursor && s.support.touch) {\n            s.params.grabCursor = false;\n        }\n        \n        // Wrapper\n        s.wrapper = s.container.children('.' + s.params.wrapperClass);\n        \n        // Pagination\n        if (s.params.pagination) {\n            s.paginationContainer = $(s.params.pagination);\n            if (s.params.uniqueNavElements && typeof s.params.pagination === 'string' && s.paginationContainer.length > 1 && s.container.find(s.params.pagination).length === 1) {\n                s.paginationContainer = s.container.find(s.params.pagination);\n            }\n        \n            if (s.params.paginationType === 'bullets' && s.params.paginationClickable) {\n                s.paginationContainer.addClass('swiper-pagination-clickable');\n            }\n            else {\n                s.params.paginationClickable = false;\n            }\n            s.paginationContainer.addClass('swiper-pagination-' + s.params.paginationType);\n        }\n        // Next/Prev Buttons\n        if (s.params.nextButton || s.params.prevButton) {\n            if (s.params.nextButton) {\n                s.nextButton = $(s.params.nextButton);\n                if (s.params.uniqueNavElements && typeof s.params.nextButton === 'string' && s.nextButton.length > 1 && s.container.find(s.params.nextButton).length === 1) {\n                    s.nextButton = s.container.find(s.params.nextButton);\n                }\n            }\n            if (s.params.prevButton) {\n                s.prevButton = $(s.params.prevButton);\n                if (s.params.uniqueNavElements && typeof s.params.prevButton === 'string' && s.prevButton.length > 1 && s.container.find(s.params.prevButton).length === 1) {\n                    s.prevButton = s.container.find(s.params.prevButton);\n                }\n            }\n        }\n        \n        // Is Horizontal\n        s.isHorizontal = function () {\n            return s.params.direction === 'horizontal';\n        };\n        // s.isH = isH;\n        \n        // RTL\n        s.rtl = s.isHorizontal() && (s.container[0].dir.toLowerCase() === 'rtl' || s.container.css('direction') === 'rtl');\n        if (s.rtl) {\n            s.classNames.push('swiper-container-rtl');\n        }\n        \n        // Wrong RTL support\n        if (s.rtl) {\n            s.wrongRTL = s.wrapper.css('display') === '-webkit-box';\n        }\n        \n        // Columns\n        if (s.params.slidesPerColumn > 1) {\n            s.classNames.push('swiper-container-multirow');\n        }\n        \n        // Check for Android\n        if (s.device.android) {\n            s.classNames.push('swiper-container-android');\n        }\n        \n        // Add classes\n        s.container.addClass(s.classNames.join(' '));\n        \n        // Translate\n        s.translate = 0;\n        \n        // Progress\n        s.progress = 0;\n        \n        // Velocity\n        s.velocity = 0;\n        \n        /*=========================\n          Locks, unlocks\n          ===========================*/\n        s.lockSwipeToNext = function () {\n            s.params.allowSwipeToNext = false;\n        };\n        s.lockSwipeToPrev = function () {\n            s.params.allowSwipeToPrev = false;\n        };\n        s.lockSwipes = function () {\n            s.params.allowSwipeToNext = s.params.allowSwipeToPrev = false;\n        };\n        s.unlockSwipeToNext = function () {\n            s.params.allowSwipeToNext = true;\n        };\n        s.unlockSwipeToPrev = function () {\n            s.params.allowSwipeToPrev = true;\n        };\n        s.unlockSwipes = function () {\n            s.params.allowSwipeToNext = s.params.allowSwipeToPrev = true;\n        };\n        \n        /*=========================\n          Round helper\n          ===========================*/\n        function round(a) {\n            return Math.floor(a);\n        }\n        /*=========================\n          Set grab cursor\n          ===========================*/\n        if (s.params.grabCursor) {\n            s.container[0].style.cursor = 'move';\n            s.container[0].style.cursor = '-webkit-grab';\n            s.container[0].style.cursor = '-moz-grab';\n            s.container[0].style.cursor = 'grab';\n        }\n        /*=========================\n          Update on Images Ready\n          ===========================*/\n        s.imagesToLoad = [];\n        s.imagesLoaded = 0;\n        \n        s.loadImage = function (imgElement, src, srcset, checkForComplete, callback) {\n            var image;\n            function onReady () {\n                if (callback) callback();\n            }\n            if (!imgElement.complete || !checkForComplete) {\n                if (src) {\n                    image = new window.Image();\n                    image.onload = onReady;\n                    image.onerror = onReady;\n                    if (srcset) {\n                        image.srcset = srcset;\n                    }\n                    if (src) {\n                        image.src = src;\n                    }\n                } else {\n                    onReady();\n                }\n        \n            } else {//image already loaded...\n                onReady();\n            }\n        };\n        s.preloadImages = function () {\n            s.imagesToLoad = s.container.find('img');\n            function _onReady() {\n                if (typeof s === 'undefined' || s === null) return;\n                if (s.imagesLoaded !== undefined) s.imagesLoaded++;\n                if (s.imagesLoaded === s.imagesToLoad.length) {\n                    if (s.params.updateOnImagesReady) s.update();\n                    s.emit('onImagesReady', s);\n                }\n            }\n            for (var i = 0; i < s.imagesToLoad.length; i++) {\n                s.loadImage(s.imagesToLoad[i], (s.imagesToLoad[i].currentSrc || s.imagesToLoad[i].getAttribute('src')), (s.imagesToLoad[i].srcset || s.imagesToLoad[i].getAttribute('srcset')), true, _onReady);\n            }\n        };\n        \n        /*=========================\n          Autoplay\n          ===========================*/\n        s.autoplayTimeoutId = undefined;\n        s.autoplaying = false;\n        s.autoplayPaused = false;\n        function autoplay() {\n            s.autoplayTimeoutId = setTimeout(function () {\n                if (s.params.loop) {\n                    s.fixLoop();\n                    s._slideNext();\n                    s.emit('onAutoplay', s);\n                }\n                else {\n                    if (!s.isEnd) {\n                        s._slideNext();\n                        s.emit('onAutoplay', s);\n                    }\n                    else {\n                        if (!params.autoplayStopOnLast) {\n                            s._slideTo(0);\n                            s.emit('onAutoplay', s);\n                        }\n                        else {\n                            s.stopAutoplay();\n                        }\n                    }\n                }\n            }, s.params.autoplay);\n        }\n        s.startAutoplay = function () {\n            if (typeof s.autoplayTimeoutId !== 'undefined') return false;\n            if (!s.params.autoplay) return false;\n            if (s.autoplaying) return false;\n            s.autoplaying = true;\n            s.emit('onAutoplayStart', s);\n            autoplay();\n        };\n        s.stopAutoplay = function (internal) {\n            if (!s.autoplayTimeoutId) return;\n            if (s.autoplayTimeoutId) clearTimeout(s.autoplayTimeoutId);\n            s.autoplaying = false;\n            s.autoplayTimeoutId = undefined;\n            s.emit('onAutoplayStop', s);\n        };\n        s.pauseAutoplay = function (speed) {\n            if (s.autoplayPaused) return;\n            if (s.autoplayTimeoutId) clearTimeout(s.autoplayTimeoutId);\n            s.autoplayPaused = true;\n            if (speed === 0) {\n                s.autoplayPaused = false;\n                autoplay();\n            }\n            else {\n                s.wrapper.transitionEnd(function () {\n                    if (!s) return;\n                    s.autoplayPaused = false;\n                    if (!s.autoplaying) {\n                        s.stopAutoplay();\n                    }\n                    else {\n                        autoplay();\n                    }\n                });\n            }\n        };\n        /*=========================\n          Min/Max Translate\n          ===========================*/\n        s.minTranslate = function () {\n            return (-s.snapGrid[0]);\n        };\n        s.maxTranslate = function () {\n            return (-s.snapGrid[s.snapGrid.length - 1]);\n        };\n        /*=========================\n          Slider/slides sizes\n          ===========================*/\n        s.updateAutoHeight = function () {\n            // Update Height\n            var slide = s.slides.eq(s.activeIndex)[0];\n            if (typeof slide !== 'undefined') {\n                var newHeight = slide.offsetHeight;\n                if (newHeight) s.wrapper.css('height', newHeight + 'px');\n            }\n        };\n        s.updateContainerSize = function () {\n            var width, height;\n            if (typeof s.params.width !== 'undefined') {\n                width = s.params.width;\n            }\n            else {\n                width = s.container[0].clientWidth;\n            }\n            if (typeof s.params.height !== 'undefined') {\n                height = s.params.height;\n            }\n            else {\n                height = s.container[0].clientHeight;\n            }\n            if (width === 0 && s.isHorizontal() || height === 0 && !s.isHorizontal()) {\n                return;\n            }\n        \n            //Subtract paddings\n            width = width - parseInt(s.container.css('padding-left'), 10) - parseInt(s.container.css('padding-right'), 10);\n            height = height - parseInt(s.container.css('padding-top'), 10) - parseInt(s.container.css('padding-bottom'), 10);\n        \n            // Store values\n            s.width = width;\n            s.height = height;\n            s.size = s.isHorizontal() ? s.width : s.height;\n        };\n        \n        s.updateSlidesSize = function () {\n            s.slides = s.wrapper.children('.' + s.params.slideClass);\n            s.snapGrid = [];\n            s.slidesGrid = [];\n            s.slidesSizesGrid = [];\n        \n            var spaceBetween = s.params.spaceBetween,\n                slidePosition = -s.params.slidesOffsetBefore,\n                i,\n                prevSlideSize = 0,\n                index = 0;\n            if (typeof s.size === 'undefined') return;\n            if (typeof spaceBetween === 'string' && spaceBetween.indexOf('%') >= 0) {\n                spaceBetween = parseFloat(spaceBetween.replace('%', '')) / 100 * s.size;\n            }\n        \n            s.virtualSize = -spaceBetween;\n            // reset margins\n            if (s.rtl) s.slides.css({marginLeft: '', marginTop: ''});\n            else s.slides.css({marginRight: '', marginBottom: ''});\n        \n            var slidesNumberEvenToRows;\n            if (s.params.slidesPerColumn > 1) {\n                if (Math.floor(s.slides.length / s.params.slidesPerColumn) === s.slides.length / s.params.slidesPerColumn) {\n                    slidesNumberEvenToRows = s.slides.length;\n                }\n                else {\n                    slidesNumberEvenToRows = Math.ceil(s.slides.length / s.params.slidesPerColumn) * s.params.slidesPerColumn;\n                }\n                if (s.params.slidesPerView !== 'auto' && s.params.slidesPerColumnFill === 'row') {\n                    slidesNumberEvenToRows = Math.max(slidesNumberEvenToRows, s.params.slidesPerView * s.params.slidesPerColumn);\n                }\n            }\n        \n            // Calc slides\n            var slideSize;\n            var slidesPerColumn = s.params.slidesPerColumn;\n            var slidesPerRow = slidesNumberEvenToRows / slidesPerColumn;\n            var numFullColumns = slidesPerRow - (s.params.slidesPerColumn * slidesPerRow - s.slides.length);\n            for (i = 0; i < s.slides.length; i++) {\n                slideSize = 0;\n                var slide = s.slides.eq(i);\n                if (s.params.slidesPerColumn > 1) {\n                    // Set slides order\n                    var newSlideOrderIndex;\n                    var column, row;\n                    if (s.params.slidesPerColumnFill === 'column') {\n                        column = Math.floor(i / slidesPerColumn);\n                        row = i - column * slidesPerColumn;\n                        if (column > numFullColumns || (column === numFullColumns && row === slidesPerColumn-1)) {\n                            if (++row >= slidesPerColumn) {\n                                row = 0;\n                                column++;\n                            }\n                        }\n                        newSlideOrderIndex = column + row * slidesNumberEvenToRows / slidesPerColumn;\n                        slide\n                            .css({\n                                '-webkit-box-ordinal-group': newSlideOrderIndex,\n                                '-moz-box-ordinal-group': newSlideOrderIndex,\n                                '-ms-flex-order': newSlideOrderIndex,\n                                '-webkit-order': newSlideOrderIndex,\n                                'order': newSlideOrderIndex\n                            });\n                    }\n                    else {\n                        row = Math.floor(i / slidesPerRow);\n                        column = i - row * slidesPerRow;\n                    }\n                    slide\n                        .css({\n                            'margin-top': (row !== 0 && s.params.spaceBetween) && (s.params.spaceBetween + 'px')\n                        })\n                        .attr('data-swiper-column', column)\n                        .attr('data-swiper-row', row);\n        \n                }\n                if (slide.css('display') === 'none') continue;\n                if (s.params.slidesPerView === 'auto') {\n                    slideSize = s.isHorizontal() ? slide.outerWidth(true) : slide.outerHeight(true);\n                    if (s.params.roundLengths) slideSize = round(slideSize);\n                }\n                else {\n                    slideSize = (s.size - (s.params.slidesPerView - 1) * spaceBetween) / s.params.slidesPerView;\n                    if (s.params.roundLengths) slideSize = round(slideSize);\n        \n                    if (s.isHorizontal()) {\n                        s.slides[i].style.width = slideSize + 'px';\n                    }\n                    else {\n                        s.slides[i].style.height = slideSize + 'px';\n                    }\n                }\n                s.slides[i].swiperSlideSize = slideSize;\n                s.slidesSizesGrid.push(slideSize);\n        \n        \n                if (s.params.centeredSlides) {\n                    slidePosition = slidePosition + slideSize / 2 + prevSlideSize / 2 + spaceBetween;\n                    if (i === 0) slidePosition = slidePosition - s.size / 2 - spaceBetween;\n                    if (Math.abs(slidePosition) < 1 / 1000) slidePosition = 0;\n                    if ((index) % s.params.slidesPerGroup === 0) s.snapGrid.push(slidePosition);\n                    s.slidesGrid.push(slidePosition);\n                }\n                else {\n                    if ((index) % s.params.slidesPerGroup === 0) s.snapGrid.push(slidePosition);\n                    s.slidesGrid.push(slidePosition);\n                    slidePosition = slidePosition + slideSize + spaceBetween;\n                }\n        \n                s.virtualSize += slideSize + spaceBetween;\n        \n                prevSlideSize = slideSize;\n        \n                index ++;\n            }\n            s.virtualSize = Math.max(s.virtualSize, s.size) + s.params.slidesOffsetAfter;\n            var newSlidesGrid;\n        \n            if (\n                s.rtl && s.wrongRTL && (s.params.effect === 'slide' || s.params.effect === 'coverflow')) {\n                s.wrapper.css({width: s.virtualSize + s.params.spaceBetween + 'px'});\n            }\n            if (!s.support.flexbox || s.params.setWrapperSize) {\n                if (s.isHorizontal()) s.wrapper.css({width: s.virtualSize + s.params.spaceBetween + 'px'});\n                else s.wrapper.css({height: s.virtualSize + s.params.spaceBetween + 'px'});\n            }\n        \n            if (s.params.slidesPerColumn > 1) {\n                s.virtualSize = (slideSize + s.params.spaceBetween) * slidesNumberEvenToRows;\n                s.virtualSize = Math.ceil(s.virtualSize / s.params.slidesPerColumn) - s.params.spaceBetween;\n                s.wrapper.css({width: s.virtualSize + s.params.spaceBetween + 'px'});\n                if (s.params.centeredSlides) {\n                    newSlidesGrid = [];\n                    for (i = 0; i < s.snapGrid.length; i++) {\n                        if (s.snapGrid[i] < s.virtualSize + s.snapGrid[0]) newSlidesGrid.push(s.snapGrid[i]);\n                    }\n                    s.snapGrid = newSlidesGrid;\n                }\n            }\n        \n            // Remove last grid elements depending on width\n            if (!s.params.centeredSlides) {\n                newSlidesGrid = [];\n                for (i = 0; i < s.snapGrid.length; i++) {\n                    if (s.snapGrid[i] <= s.virtualSize - s.size) {\n                        newSlidesGrid.push(s.snapGrid[i]);\n                    }\n                }\n                s.snapGrid = newSlidesGrid;\n                if (Math.floor(s.virtualSize - s.size) - Math.floor(s.snapGrid[s.snapGrid.length - 1]) > 1) {\n                    s.snapGrid.push(s.virtualSize - s.size);\n                }\n            }\n            if (s.snapGrid.length === 0) s.snapGrid = [0];\n        \n            if (s.params.spaceBetween !== 0) {\n                if (s.isHorizontal()) {\n                    if (s.rtl) s.slides.css({marginLeft: spaceBetween + 'px'});\n                    else s.slides.css({marginRight: spaceBetween + 'px'});\n                }\n                else s.slides.css({marginBottom: spaceBetween + 'px'});\n            }\n            if (s.params.watchSlidesProgress) {\n                s.updateSlidesOffset();\n            }\n        };\n        s.updateSlidesOffset = function () {\n            for (var i = 0; i < s.slides.length; i++) {\n                s.slides[i].swiperSlideOffset = s.isHorizontal() ? s.slides[i].offsetLeft : s.slides[i].offsetTop;\n            }\n        };\n        \n        /*=========================\n          Slider/slides progress\n          ===========================*/\n        s.updateSlidesProgress = function (translate) {\n            if (typeof translate === 'undefined') {\n                translate = s.translate || 0;\n            }\n            if (s.slides.length === 0) return;\n            if (typeof s.slides[0].swiperSlideOffset === 'undefined') s.updateSlidesOffset();\n        \n            var offsetCenter = -translate;\n            if (s.rtl) offsetCenter = translate;\n        \n            // Visible Slides\n            s.slides.removeClass(s.params.slideVisibleClass);\n            for (var i = 0; i < s.slides.length; i++) {\n                var slide = s.slides[i];\n                var slideProgress = (offsetCenter - slide.swiperSlideOffset) / (slide.swiperSlideSize + s.params.spaceBetween);\n                if (s.params.watchSlidesVisibility) {\n                    var slideBefore = -(offsetCenter - slide.swiperSlideOffset);\n                    var slideAfter = slideBefore + s.slidesSizesGrid[i];\n                    var isVisible =\n                        (slideBefore >= 0 && slideBefore < s.size) ||\n                        (slideAfter > 0 && slideAfter <= s.size) ||\n                        (slideBefore <= 0 && slideAfter >= s.size);\n                    if (isVisible) {\n                        s.slides.eq(i).addClass(s.params.slideVisibleClass);\n                    }\n                }\n                slide.progress = s.rtl ? -slideProgress : slideProgress;\n            }\n        };\n        s.updateProgress = function (translate) {\n            if (typeof translate === 'undefined') {\n                translate = s.translate || 0;\n            }\n            var translatesDiff = s.maxTranslate() - s.minTranslate();\n            var wasBeginning = s.isBeginning;\n            var wasEnd = s.isEnd;\n            if (translatesDiff === 0) {\n                s.progress = 0;\n                s.isBeginning = s.isEnd = true;\n            }\n            else {\n                s.progress = (translate - s.minTranslate()) / (translatesDiff);\n                s.isBeginning = s.progress <= 0;\n                s.isEnd = s.progress >= 1;\n            }\n            if (s.isBeginning && !wasBeginning) s.emit('onReachBeginning', s);\n            if (s.isEnd && !wasEnd) s.emit('onReachEnd', s);\n        \n            if (s.params.watchSlidesProgress) s.updateSlidesProgress(translate);\n            s.emit('onProgress', s, s.progress);\n        };\n        s.updateActiveIndex = function () {\n            var translate = s.rtl ? s.translate : -s.translate;\n            var newActiveIndex, i, snapIndex;\n            for (i = 0; i < s.slidesGrid.length; i ++) {\n                if (typeof s.slidesGrid[i + 1] !== 'undefined') {\n                    if (translate >= s.slidesGrid[i] && translate < s.slidesGrid[i + 1] - (s.slidesGrid[i + 1] - s.slidesGrid[i]) / 2) {\n                        newActiveIndex = i;\n                    }\n                    else if (translate >= s.slidesGrid[i] && translate < s.slidesGrid[i + 1]) {\n                        newActiveIndex = i + 1;\n                    }\n                }\n                else {\n                    if (translate >= s.slidesGrid[i]) {\n                        newActiveIndex = i;\n                    }\n                }\n            }\n            // Normalize slideIndex\n            if (newActiveIndex < 0 || typeof newActiveIndex === 'undefined') newActiveIndex = 0;\n            // for (i = 0; i < s.slidesGrid.length; i++) {\n                // if (- translate >= s.slidesGrid[i]) {\n                    // newActiveIndex = i;\n                // }\n            // }\n            snapIndex = Math.floor(newActiveIndex / s.params.slidesPerGroup);\n            if (snapIndex >= s.snapGrid.length) snapIndex = s.snapGrid.length - 1;\n        \n            if (newActiveIndex === s.activeIndex) {\n                return;\n            }\n            s.snapIndex = snapIndex;\n            s.previousIndex = s.activeIndex;\n            s.activeIndex = newActiveIndex;\n            s.updateClasses();\n        };\n        \n        /*=========================\n          Classes\n          ===========================*/\n        s.updateClasses = function () {\n            s.slides.removeClass(s.params.slideActiveClass + ' ' + s.params.slideNextClass + ' ' + s.params.slidePrevClass);\n            var activeSlide = s.slides.eq(s.activeIndex);\n            // Active classes\n            activeSlide.addClass(s.params.slideActiveClass);\n            // Next Slide\n            var nextSlide = activeSlide.next('.' + s.params.slideClass).addClass(s.params.slideNextClass);\n            if (s.params.loop && nextSlide.length === 0) {\n                s.slides.eq(0).addClass(s.params.slideNextClass);\n            }\n            // Prev Slide\n            var prevSlide = activeSlide.prev('.' + s.params.slideClass).addClass(s.params.slidePrevClass);\n            if (s.params.loop && prevSlide.length === 0) {\n                s.slides.eq(-1).addClass(s.params.slidePrevClass);\n            }\n        \n            // Pagination\n            if (s.paginationContainer && s.paginationContainer.length > 0) {\n                // Current/Total\n                var current,\n                    total = s.params.loop ? Math.ceil((s.slides.length - s.loopedSlides * 2) / s.params.slidesPerGroup) : s.snapGrid.length;\n                if (s.params.loop) {\n                    current = Math.ceil((s.activeIndex - s.loopedSlides)/s.params.slidesPerGroup);\n                    if (current > s.slides.length - 1 - s.loopedSlides * 2) {\n                        current = current - (s.slides.length - s.loopedSlides * 2);\n                    }\n                    if (current > total - 1) current = current - total;\n                    if (current < 0 && s.params.paginationType !== 'bullets') current = total + current;\n                }\n                else {\n                    if (typeof s.snapIndex !== 'undefined') {\n                        current = s.snapIndex;\n                    }\n                    else {\n                        current = s.activeIndex || 0;\n                    }\n                }\n                // Types\n                if (s.params.paginationType === 'bullets' && s.bullets && s.bullets.length > 0) {\n                    s.bullets.removeClass(s.params.bulletActiveClass);\n                    if (s.paginationContainer.length > 1) {\n                        s.bullets.each(function () {\n                            if ($(this).index() === current) $(this).addClass(s.params.bulletActiveClass);\n                        });\n                    }\n                    else {\n                        s.bullets.eq(current).addClass(s.params.bulletActiveClass);\n                    }\n                }\n                if (s.params.paginationType === 'fraction') {\n                    s.paginationContainer.find('.' + s.params.paginationCurrentClass).text(current + 1);\n                    s.paginationContainer.find('.' + s.params.paginationTotalClass).text(total);\n                }\n                if (s.params.paginationType === 'progress') {\n                    var scale = (current + 1) / total,\n                        scaleX = scale,\n                        scaleY = 1;\n                    if (!s.isHorizontal()) {\n                        scaleY = scale;\n                        scaleX = 1;\n                    }\n                    s.paginationContainer.find('.' + s.params.paginationProgressbarClass).transform('translate3d(0,0,0) scaleX(' + scaleX + ') scaleY(' + scaleY + ')').transition(s.params.speed);\n                }\n                if (s.params.paginationType === 'custom' && s.params.paginationCustomRender) {\n                    s.paginationContainer.html(s.params.paginationCustomRender(s, current + 1, total));\n                    s.emit('onPaginationRendered', s, s.paginationContainer[0]);\n                }\n            }\n        \n            // Next/active buttons\n            if (!s.params.loop) {\n                if (s.params.prevButton && s.prevButton && s.prevButton.length > 0) {\n                    if (s.isBeginning) {\n                        s.prevButton.addClass(s.params.buttonDisabledClass);\n                        if (s.params.a11y && s.a11y) s.a11y.disable(s.prevButton);\n                    }\n                    else {\n                        s.prevButton.removeClass(s.params.buttonDisabledClass);\n                        if (s.params.a11y && s.a11y) s.a11y.enable(s.prevButton);\n                    }\n                }\n                if (s.params.nextButton && s.nextButton && s.nextButton.length > 0) {\n                    if (s.isEnd) {\n                        s.nextButton.addClass(s.params.buttonDisabledClass);\n                        if (s.params.a11y && s.a11y) s.a11y.disable(s.nextButton);\n                    }\n                    else {\n                        s.nextButton.removeClass(s.params.buttonDisabledClass);\n                        if (s.params.a11y && s.a11y) s.a11y.enable(s.nextButton);\n                    }\n                }\n            }\n        };\n        \n        /*=========================\n          Pagination\n          ===========================*/\n        s.updatePagination = function () {\n            if (!s.params.pagination) return;\n            if (s.paginationContainer && s.paginationContainer.length > 0) {\n                var paginationHTML = '';\n                if (s.params.paginationType === 'bullets') {\n                    var numberOfBullets = s.params.loop ? Math.ceil((s.slides.length - s.loopedSlides * 2) / s.params.slidesPerGroup) : s.snapGrid.length;\n                    for (var i = 0; i < numberOfBullets; i++) {\n                        if (s.params.paginationBulletRender) {\n                            paginationHTML += s.params.paginationBulletRender(i, s.params.bulletClass);\n                        }\n                        else {\n                            paginationHTML += '<' + s.params.paginationElement+' class=\"' + s.params.bulletClass + '\"></' + s.params.paginationElement + '>';\n                        }\n                    }\n                    s.paginationContainer.html(paginationHTML);\n                    s.bullets = s.paginationContainer.find('.' + s.params.bulletClass);\n                    if (s.params.paginationClickable && s.params.a11y && s.a11y) {\n                        s.a11y.initPagination();\n                    }\n                }\n                if (s.params.paginationType === 'fraction') {\n                    if (s.params.paginationFractionRender) {\n                        paginationHTML = s.params.paginationFractionRender(s, s.params.paginationCurrentClass, s.params.paginationTotalClass);\n                    }\n                    else {\n                        paginationHTML =\n                            '<span class=\"' + s.params.paginationCurrentClass + '\"></span>' +\n                            ' / ' +\n                            '<span class=\"' + s.params.paginationTotalClass+'\"></span>';\n                    }\n                    s.paginationContainer.html(paginationHTML);\n                }\n                if (s.params.paginationType === 'progress') {\n                    if (s.params.paginationProgressRender) {\n                        paginationHTML = s.params.paginationProgressRender(s, s.params.paginationProgressbarClass);\n                    }\n                    else {\n                        paginationHTML = '<span class=\"' + s.params.paginationProgressbarClass + '\"></span>';\n                    }\n                    s.paginationContainer.html(paginationHTML);\n                }\n                if (s.params.paginationType !== 'custom') {\n                    s.emit('onPaginationRendered', s, s.paginationContainer[0]);\n                }\n            }\n        };\n        /*=========================\n          Common update method\n          ===========================*/\n        s.update = function (updateTranslate) {\n            s.updateContainerSize();\n            s.updateSlidesSize();\n            s.updateProgress();\n            s.updatePagination();\n            s.updateClasses();\n            if (s.params.scrollbar && s.scrollbar) {\n                s.scrollbar.set();\n            }\n            function forceSetTranslate() {\n                newTranslate = Math.min(Math.max(s.translate, s.maxTranslate()), s.minTranslate());\n                s.setWrapperTranslate(newTranslate);\n                s.updateActiveIndex();\n                s.updateClasses();\n            }\n            if (updateTranslate) {\n                var translated, newTranslate;\n                if (s.controller && s.controller.spline) {\n                    s.controller.spline = undefined;\n                }\n                if (s.params.freeMode) {\n                    forceSetTranslate();\n                    if (s.params.autoHeight) {\n                        s.updateAutoHeight();\n                    }\n                }\n                else {\n                    if ((s.params.slidesPerView === 'auto' || s.params.slidesPerView > 1) && s.isEnd && !s.params.centeredSlides) {\n                        translated = s.slideTo(s.slides.length - 1, 0, false, true);\n                    }\n                    else {\n                        translated = s.slideTo(s.activeIndex, 0, false, true);\n                    }\n                    if (!translated) {\n                        forceSetTranslate();\n                    }\n                }\n            }\n            else if (s.params.autoHeight) {\n                s.updateAutoHeight();\n            }\n        };\n        \n        /*=========================\n          Resize Handler\n          ===========================*/\n        s.onResize = function (forceUpdatePagination) {\n            //Breakpoints\n            if (s.params.breakpoints) {\n                s.setBreakpoint();\n            }\n        \n            // Disable locks on resize\n            var allowSwipeToPrev = s.params.allowSwipeToPrev;\n            var allowSwipeToNext = s.params.allowSwipeToNext;\n            s.params.allowSwipeToPrev = s.params.allowSwipeToNext = true;\n        \n            s.updateContainerSize();\n            s.updateSlidesSize();\n            if (s.params.slidesPerView === 'auto' || s.params.freeMode || forceUpdatePagination) s.updatePagination();\n            if (s.params.scrollbar && s.scrollbar) {\n                s.scrollbar.set();\n            }\n            if (s.controller && s.controller.spline) {\n                s.controller.spline = undefined;\n            }\n            var slideChangedBySlideTo = false;\n            if (s.params.freeMode) {\n                var newTranslate = Math.min(Math.max(s.translate, s.maxTranslate()), s.minTranslate());\n                s.setWrapperTranslate(newTranslate);\n                s.updateActiveIndex();\n                s.updateClasses();\n        \n                if (s.params.autoHeight) {\n                    s.updateAutoHeight();\n                }\n            }\n            else {\n                s.updateClasses();\n                if ((s.params.slidesPerView === 'auto' || s.params.slidesPerView > 1) && s.isEnd && !s.params.centeredSlides) {\n                    slideChangedBySlideTo = s.slideTo(s.slides.length - 1, 0, false, true);\n                }\n                else {\n                    slideChangedBySlideTo = s.slideTo(s.activeIndex, 0, false, true);\n                }\n            }\n            if (s.params.lazyLoading && !slideChangedBySlideTo && s.lazy) {\n                s.lazy.load();\n            }\n            // Return locks after resize\n            s.params.allowSwipeToPrev = allowSwipeToPrev;\n            s.params.allowSwipeToNext = allowSwipeToNext;\n        };\n        \n        /*=========================\n          Events\n          ===========================*/\n        \n        //Define Touch Events\n        var desktopEvents = ['mousedown', 'mousemove', 'mouseup'];\n        if (window.navigator.pointerEnabled) desktopEvents = ['pointerdown', 'pointermove', 'pointerup'];\n        else if (window.navigator.msPointerEnabled) desktopEvents = ['MSPointerDown', 'MSPointerMove', 'MSPointerUp'];\n        s.touchEvents = {\n            start : s.support.touch || !s.params.simulateTouch  ? 'touchstart' : desktopEvents[0],\n            move : s.support.touch || !s.params.simulateTouch ? 'touchmove' : desktopEvents[1],\n            end : s.support.touch || !s.params.simulateTouch ? 'touchend' : desktopEvents[2]\n        };\n        \n        \n        // WP8 Touch Events Fix\n        if (window.navigator.pointerEnabled || window.navigator.msPointerEnabled) {\n            (s.params.touchEventsTarget === 'container' ? s.container : s.wrapper).addClass('swiper-wp8-' + s.params.direction);\n        }\n        \n        // Attach/detach events\n        s.initEvents = function (detach) {\n            var actionDom = detach ? 'off' : 'on';\n            var action = detach ? 'removeEventListener' : 'addEventListener';\n            var touchEventsTarget = s.params.touchEventsTarget === 'container' ? s.container[0] : s.wrapper[0];\n            var target = s.support.touch ? touchEventsTarget : document;\n        \n            var moveCapture = s.params.nested ? true : false;\n        \n            //Touch Events\n            if (s.browser.ie) {\n                touchEventsTarget[action](s.touchEvents.start, s.onTouchStart, false);\n                target[action](s.touchEvents.move, s.onTouchMove, moveCapture);\n                target[action](s.touchEvents.end, s.onTouchEnd, false);\n            }\n            else {\n                if (s.support.touch) {\n                    touchEventsTarget[action](s.touchEvents.start, s.onTouchStart, false);\n                    touchEventsTarget[action](s.touchEvents.move, s.onTouchMove, moveCapture);\n                    touchEventsTarget[action](s.touchEvents.end, s.onTouchEnd, false);\n                }\n                if (params.simulateTouch && !s.device.ios && !s.device.android) {\n                    touchEventsTarget[action]('mousedown', s.onTouchStart, false);\n                    document[action]('mousemove', s.onTouchMove, moveCapture);\n                    document[action]('mouseup', s.onTouchEnd, false);\n                }\n            }\n            window[action]('resize', s.onResize);\n        \n            // Next, Prev, Index\n            if (s.params.nextButton && s.nextButton && s.nextButton.length > 0) {\n                s.nextButton[actionDom]('click', s.onClickNext);\n                if (s.params.a11y && s.a11y) s.nextButton[actionDom]('keydown', s.a11y.onEnterKey);\n            }\n            if (s.params.prevButton && s.prevButton && s.prevButton.length > 0) {\n                s.prevButton[actionDom]('click', s.onClickPrev);\n                if (s.params.a11y && s.a11y) s.prevButton[actionDom]('keydown', s.a11y.onEnterKey);\n            }\n            if (s.params.pagination && s.params.paginationClickable) {\n                s.paginationContainer[actionDom]('click', '.' + s.params.bulletClass, s.onClickIndex);\n                if (s.params.a11y && s.a11y) s.paginationContainer[actionDom]('keydown', '.' + s.params.bulletClass, s.a11y.onEnterKey);\n            }\n        \n            // Prevent Links Clicks\n            if (s.params.preventClicks || s.params.preventClicksPropagation) touchEventsTarget[action]('click', s.preventClicks, true);\n        };\n        s.attachEvents = function () {\n            s.initEvents();\n        };\n        s.detachEvents = function () {\n            s.initEvents(true);\n        };\n        \n        /*=========================\n          Handle Clicks\n          ===========================*/\n        // Prevent Clicks\n        s.allowClick = true;\n        s.preventClicks = function (e) {\n            if (!s.allowClick) {\n                if (s.params.preventClicks) e.preventDefault();\n                if (s.params.preventClicksPropagation && s.animating) {\n                    e.stopPropagation();\n                    e.stopImmediatePropagation();\n                }\n            }\n        };\n        // Clicks\n        s.onClickNext = function (e) {\n            e.preventDefault();\n            if (s.isEnd && !s.params.loop) return;\n            s.slideNext();\n        };\n        s.onClickPrev = function (e) {\n            e.preventDefault();\n            if (s.isBeginning && !s.params.loop) return;\n            s.slidePrev();\n        };\n        s.onClickIndex = function (e) {\n            e.preventDefault();\n            var index = $(this).index() * s.params.slidesPerGroup;\n            if (s.params.loop) index = index + s.loopedSlides;\n            s.slideTo(index);\n        };\n        \n        /*=========================\n          Handle Touches\n          ===========================*/\n        function findElementInEvent(e, selector) {\n            var el = $(e.target);\n            if (!el.is(selector)) {\n                if (typeof selector === 'string') {\n                    el = el.parents(selector);\n                }\n                else if (selector.nodeType) {\n                    var found;\n                    el.parents().each(function (index, _el) {\n                        if (_el === selector) found = selector;\n                    });\n                    if (!found) return undefined;\n                    else return selector;\n                }\n            }\n            if (el.length === 0) {\n                return undefined;\n            }\n            return el[0];\n        }\n        s.updateClickedSlide = function (e) {\n            var slide = findElementInEvent(e, '.' + s.params.slideClass);\n            var slideFound = false;\n            if (slide) {\n                for (var i = 0; i < s.slides.length; i++) {\n                    if (s.slides[i] === slide) slideFound = true;\n                }\n            }\n        \n            if (slide && slideFound) {\n                s.clickedSlide = slide;\n                s.clickedIndex = $(slide).index();\n            }\n            else {\n                s.clickedSlide = undefined;\n                s.clickedIndex = undefined;\n                return;\n            }\n            if (s.params.slideToClickedSlide && s.clickedIndex !== undefined && s.clickedIndex !== s.activeIndex) {\n                var slideToIndex = s.clickedIndex,\n                    realIndex,\n                    duplicatedSlides;\n                if (s.params.loop) {\n                    if (s.animating) return;\n                    realIndex = $(s.clickedSlide).attr('data-swiper-slide-index');\n                    if (s.params.centeredSlides) {\n                        if ((slideToIndex < s.loopedSlides - s.params.slidesPerView/2) || (slideToIndex > s.slides.length - s.loopedSlides + s.params.slidesPerView/2)) {\n                            s.fixLoop();\n                            slideToIndex = s.wrapper.children('.' + s.params.slideClass + '[data-swiper-slide-index=\"' + realIndex + '\"]:not(.swiper-slide-duplicate)').eq(0).index();\n                            setTimeout(function () {\n                                s.slideTo(slideToIndex);\n                            }, 0);\n                        }\n                        else {\n                            s.slideTo(slideToIndex);\n                        }\n                    }\n                    else {\n                        if (slideToIndex > s.slides.length - s.params.slidesPerView) {\n                            s.fixLoop();\n                            slideToIndex = s.wrapper.children('.' + s.params.slideClass + '[data-swiper-slide-index=\"' + realIndex + '\"]:not(.swiper-slide-duplicate)').eq(0).index();\n                            setTimeout(function () {\n                                s.slideTo(slideToIndex);\n                            }, 0);\n                        }\n                        else {\n                            s.slideTo(slideToIndex);\n                        }\n                    }\n                }\n                else {\n                    s.slideTo(slideToIndex);\n                }\n            }\n        };\n        \n        var isTouched,\n            isMoved,\n            allowTouchCallbacks,\n            touchStartTime,\n            isScrolling,\n            currentTranslate,\n            startTranslate,\n            allowThresholdMove,\n            // Form elements to match\n            formElements = 'input, select, textarea, button',\n            // Last click time\n            lastClickTime = Date.now(), clickTimeout,\n            //Velocities\n            velocities = [],\n            allowMomentumBounce;\n        \n        // Animating Flag\n        s.animating = false;\n        \n        // Touches information\n        s.touches = {\n            startX: 0,\n            startY: 0,\n            currentX: 0,\n            currentY: 0,\n            diff: 0\n        };\n        \n        // Touch handlers\n        var isTouchEvent, startMoving;\n        s.onTouchStart = function (e) {\n            if (e.originalEvent) e = e.originalEvent;\n            isTouchEvent = e.type === 'touchstart';\n            if (!isTouchEvent && 'which' in e && e.which === 3) return;\n            if (s.params.noSwiping && findElementInEvent(e, '.' + s.params.noSwipingClass)) {\n                s.allowClick = true;\n                return;\n            }\n            if (s.params.swipeHandler) {\n                if (!findElementInEvent(e, s.params.swipeHandler)) return;\n            }\n        \n            var startX = s.touches.currentX = e.type === 'touchstart' ? e.targetTouches[0].pageX : e.pageX;\n            var startY = s.touches.currentY = e.type === 'touchstart' ? e.targetTouches[0].pageY : e.pageY;\n        \n            // Do NOT start if iOS edge swipe is detected. Otherwise iOS app (UIWebView) cannot swipe-to-go-back anymore\n            if(s.device.ios && s.params.iOSEdgeSwipeDetection && startX <= s.params.iOSEdgeSwipeThreshold) {\n                return;\n            }\n        \n            isTouched = true;\n            isMoved = false;\n            allowTouchCallbacks = true;\n            isScrolling = undefined;\n            startMoving = undefined;\n            s.touches.startX = startX;\n            s.touches.startY = startY;\n            touchStartTime = Date.now();\n            s.allowClick = true;\n            s.updateContainerSize();\n            s.swipeDirection = undefined;\n            if (s.params.threshold > 0) allowThresholdMove = false;\n            if (e.type !== 'touchstart') {\n                var preventDefault = true;\n                if ($(e.target).is(formElements)) preventDefault = false;\n                if (document.activeElement && $(document.activeElement).is(formElements)) {\n                    document.activeElement.blur();\n                }\n                if (preventDefault) {\n                    e.preventDefault();\n                }\n            }\n            s.emit('onTouchStart', s, e);\n        };\n        \n        s.onTouchMove = function (e) {\n            if (e.originalEvent) e = e.originalEvent;\n            if (isTouchEvent && e.type === 'mousemove') return;\n            if (e.preventedByNestedSwiper) {\n                s.touches.startX = e.type === 'touchmove' ? e.targetTouches[0].pageX : e.pageX;\n                s.touches.startY = e.type === 'touchmove' ? e.targetTouches[0].pageY : e.pageY;\n                return;\n            }\n            if (s.params.onlyExternal) {\n                // isMoved = true;\n                s.allowClick = false;\n                if (isTouched) {\n                    s.touches.startX = s.touches.currentX = e.type === 'touchmove' ? e.targetTouches[0].pageX : e.pageX;\n                    s.touches.startY = s.touches.currentY = e.type === 'touchmove' ? e.targetTouches[0].pageY : e.pageY;\n                    touchStartTime = Date.now();\n                }\n                return;\n            }\n            if (isTouchEvent && document.activeElement) {\n                if (e.target === document.activeElement && $(e.target).is(formElements)) {\n                    isMoved = true;\n                    s.allowClick = false;\n                    return;\n                }\n            }\n            if (allowTouchCallbacks) {\n                s.emit('onTouchMove', s, e);\n            }\n            if (e.targetTouches && e.targetTouches.length > 1) return;\n        \n            s.touches.currentX = e.type === 'touchmove' ? e.targetTouches[0].pageX : e.pageX;\n            s.touches.currentY = e.type === 'touchmove' ? e.targetTouches[0].pageY : e.pageY;\n        \n            if (typeof isScrolling === 'undefined') {\n                var touchAngle = Math.atan2(Math.abs(s.touches.currentY - s.touches.startY), Math.abs(s.touches.currentX - s.touches.startX)) * 180 / Math.PI;\n                isScrolling = s.isHorizontal() ? touchAngle > s.params.touchAngle : (90 - touchAngle > s.params.touchAngle);\n            }\n            if (isScrolling) {\n                s.emit('onTouchMoveOpposite', s, e);\n            }\n            if (typeof startMoving === 'undefined' && s.browser.ieTouch) {\n                if (s.touches.currentX !== s.touches.startX || s.touches.currentY !== s.touches.startY) {\n                    startMoving = true;\n                }\n            }\n            if (!isTouched) return;\n            if (isScrolling)  {\n                isTouched = false;\n                return;\n            }\n            if (!startMoving && s.browser.ieTouch) {\n                return;\n            }\n            s.allowClick = false;\n            s.emit('onSliderMove', s, e);\n            e.preventDefault();\n            if (s.params.touchMoveStopPropagation && !s.params.nested) {\n                e.stopPropagation();\n            }\n        \n            if (!isMoved) {\n                if (params.loop) {\n                    s.fixLoop();\n                }\n                startTranslate = s.getWrapperTranslate();\n                s.setWrapperTransition(0);\n                if (s.animating) {\n                    s.wrapper.trigger('webkitTransitionEnd transitionend oTransitionEnd MSTransitionEnd msTransitionEnd');\n                }\n                if (s.params.autoplay && s.autoplaying) {\n                    if (s.params.autoplayDisableOnInteraction) {\n                        s.stopAutoplay();\n                    }\n                    else {\n                        s.pauseAutoplay();\n                    }\n                }\n                allowMomentumBounce = false;\n                //Grab Cursor\n                if (s.params.grabCursor) {\n                    s.container[0].style.cursor = 'move';\n                    s.container[0].style.cursor = '-webkit-grabbing';\n                    s.container[0].style.cursor = '-moz-grabbin';\n                    s.container[0].style.cursor = 'grabbing';\n                }\n            }\n            isMoved = true;\n        \n            var diff = s.touches.diff = s.isHorizontal() ? s.touches.currentX - s.touches.startX : s.touches.currentY - s.touches.startY;\n        \n            diff = diff * s.params.touchRatio;\n            if (s.rtl) diff = -diff;\n        \n            s.swipeDirection = diff > 0 ? 'prev' : 'next';\n            currentTranslate = diff + startTranslate;\n        \n            var disableParentSwiper = true;\n            if ((diff > 0 && currentTranslate > s.minTranslate())) {\n                disableParentSwiper = false;\n                if (s.params.resistance) currentTranslate = s.minTranslate() - 1 + Math.pow(-s.minTranslate() + startTranslate + diff, s.params.resistanceRatio);\n            }\n            else if (diff < 0 && currentTranslate < s.maxTranslate()) {\n                disableParentSwiper = false;\n                if (s.params.resistance) currentTranslate = s.maxTranslate() + 1 - Math.pow(s.maxTranslate() - startTranslate - diff, s.params.resistanceRatio);\n            }\n        \n            if (disableParentSwiper) {\n                e.preventedByNestedSwiper = true;\n            }\n        \n            // Directions locks\n            if (!s.params.allowSwipeToNext && s.swipeDirection === 'next' && currentTranslate < startTranslate) {\n                currentTranslate = startTranslate;\n            }\n            if (!s.params.allowSwipeToPrev && s.swipeDirection === 'prev' && currentTranslate > startTranslate) {\n                currentTranslate = startTranslate;\n            }\n        \n            if (!s.params.followFinger) return;\n        \n            // Threshold\n            if (s.params.threshold > 0) {\n                if (Math.abs(diff) > s.params.threshold || allowThresholdMove) {\n                    if (!allowThresholdMove) {\n                        allowThresholdMove = true;\n                        s.touches.startX = s.touches.currentX;\n                        s.touches.startY = s.touches.currentY;\n                        currentTranslate = startTranslate;\n                        s.touches.diff = s.isHorizontal() ? s.touches.currentX - s.touches.startX : s.touches.currentY - s.touches.startY;\n                        return;\n                    }\n                }\n                else {\n                    currentTranslate = startTranslate;\n                    return;\n                }\n            }\n            // Update active index in free mode\n            if (s.params.freeMode || s.params.watchSlidesProgress) {\n                s.updateActiveIndex();\n            }\n            if (s.params.freeMode) {\n                //Velocity\n                if (velocities.length === 0) {\n                    velocities.push({\n                        position: s.touches[s.isHorizontal() ? 'startX' : 'startY'],\n                        time: touchStartTime\n                    });\n                }\n                velocities.push({\n                    position: s.touches[s.isHorizontal() ? 'currentX' : 'currentY'],\n                    time: (new window.Date()).getTime()\n                });\n            }\n            // Update progress\n            s.updateProgress(currentTranslate);\n            // Update translate\n            s.setWrapperTranslate(currentTranslate);\n        };\n        s.onTouchEnd = function (e) {\n            if (e.originalEvent) e = e.originalEvent;\n            if (allowTouchCallbacks) {\n                s.emit('onTouchEnd', s, e);\n            }\n            allowTouchCallbacks = false;\n            if (!isTouched) return;\n            //Return Grab Cursor\n            if (s.params.grabCursor && isMoved && isTouched) {\n                s.container[0].style.cursor = 'move';\n                s.container[0].style.cursor = '-webkit-grab';\n                s.container[0].style.cursor = '-moz-grab';\n                s.container[0].style.cursor = 'grab';\n            }\n        \n            // Time diff\n            var touchEndTime = Date.now();\n            var timeDiff = touchEndTime - touchStartTime;\n        \n            // Tap, doubleTap, Click\n            if (s.allowClick) {\n                s.updateClickedSlide(e);\n                s.emit('onTap', s, e);\n                if (timeDiff < 300 && (touchEndTime - lastClickTime) > 300) {\n                    if (clickTimeout) clearTimeout(clickTimeout);\n                    clickTimeout = setTimeout(function () {\n                        if (!s) return;\n                        if (s.params.paginationHide && s.paginationContainer.length > 0 && !$(e.target).hasClass(s.params.bulletClass)) {\n                            s.paginationContainer.toggleClass(s.params.paginationHiddenClass);\n                        }\n                        s.emit('onClick', s, e);\n                    }, 300);\n        \n                }\n                if (timeDiff < 300 && (touchEndTime - lastClickTime) < 300) {\n                    if (clickTimeout) clearTimeout(clickTimeout);\n                    s.emit('onDoubleTap', s, e);\n                }\n            }\n        \n            lastClickTime = Date.now();\n            setTimeout(function () {\n                if (s) s.allowClick = true;\n            }, 0);\n        \n            if (!isTouched || !isMoved || !s.swipeDirection || s.touches.diff === 0 || currentTranslate === startTranslate) {\n                isTouched = isMoved = false;\n                return;\n            }\n            isTouched = isMoved = false;\n        \n            var currentPos;\n            if (s.params.followFinger) {\n                currentPos = s.rtl ? s.translate : -s.translate;\n            }\n            else {\n                currentPos = -currentTranslate;\n            }\n            if (s.params.freeMode) {\n                if (currentPos < -s.minTranslate()) {\n                    s.slideTo(s.activeIndex);\n                    return;\n                }\n                else if (currentPos > -s.maxTranslate()) {\n                    if (s.slides.length < s.snapGrid.length) {\n                        s.slideTo(s.snapGrid.length - 1);\n                    }\n                    else {\n                        s.slideTo(s.slides.length - 1);\n                    }\n                    return;\n                }\n        \n                if (s.params.freeModeMomentum) {\n                    if (velocities.length > 1) {\n                        var lastMoveEvent = velocities.pop(), velocityEvent = velocities.pop();\n        \n                        var distance = lastMoveEvent.position - velocityEvent.position;\n                        var time = lastMoveEvent.time - velocityEvent.time;\n                        s.velocity = distance / time;\n                        s.velocity = s.velocity / 2;\n                        if (Math.abs(s.velocity) < s.params.freeModeMinimumVelocity) {\n                            s.velocity = 0;\n                        }\n                        // this implies that the user stopped moving a finger then released.\n                        // There would be no events with distance zero, so the last event is stale.\n                        if (time > 150 || (new window.Date().getTime() - lastMoveEvent.time) > 300) {\n                            s.velocity = 0;\n                        }\n                    } else {\n                        s.velocity = 0;\n                    }\n        \n                    velocities.length = 0;\n                    var momentumDuration = 1000 * s.params.freeModeMomentumRatio;\n                    var momentumDistance = s.velocity * momentumDuration;\n        \n                    var newPosition = s.translate + momentumDistance;\n                    if (s.rtl) newPosition = - newPosition;\n                    var doBounce = false;\n                    var afterBouncePosition;\n                    var bounceAmount = Math.abs(s.velocity) * 20 * s.params.freeModeMomentumBounceRatio;\n                    if (newPosition < s.maxTranslate()) {\n                        if (s.params.freeModeMomentumBounce) {\n                            if (newPosition + s.maxTranslate() < -bounceAmount) {\n                                newPosition = s.maxTranslate() - bounceAmount;\n                            }\n                            afterBouncePosition = s.maxTranslate();\n                            doBounce = true;\n                            allowMomentumBounce = true;\n                        }\n                        else {\n                            newPosition = s.maxTranslate();\n                        }\n                    }\n                    else if (newPosition > s.minTranslate()) {\n                        if (s.params.freeModeMomentumBounce) {\n                            if (newPosition - s.minTranslate() > bounceAmount) {\n                                newPosition = s.minTranslate() + bounceAmount;\n                            }\n                            afterBouncePosition = s.minTranslate();\n                            doBounce = true;\n                            allowMomentumBounce = true;\n                        }\n                        else {\n                            newPosition = s.minTranslate();\n                        }\n                    }\n                    else if (s.params.freeModeSticky) {\n                        var j = 0,\n                            nextSlide;\n                        for (j = 0; j < s.snapGrid.length; j += 1) {\n                            if (s.snapGrid[j] > -newPosition) {\n                                nextSlide = j;\n                                break;\n                            }\n        \n                        }\n                        if (Math.abs(s.snapGrid[nextSlide] - newPosition) < Math.abs(s.snapGrid[nextSlide - 1] - newPosition) || s.swipeDirection === 'next') {\n                            newPosition = s.snapGrid[nextSlide];\n                        } else {\n                            newPosition = s.snapGrid[nextSlide - 1];\n                        }\n                        if (!s.rtl) newPosition = - newPosition;\n                    }\n                    //Fix duration\n                    if (s.velocity !== 0) {\n                        if (s.rtl) {\n                            momentumDuration = Math.abs((-newPosition - s.translate) / s.velocity);\n                        }\n                        else {\n                            momentumDuration = Math.abs((newPosition - s.translate) / s.velocity);\n                        }\n                    }\n                    else if (s.params.freeModeSticky) {\n                        s.slideReset();\n                        return;\n                    }\n        \n                    if (s.params.freeModeMomentumBounce && doBounce) {\n                        s.updateProgress(afterBouncePosition);\n                        s.setWrapperTransition(momentumDuration);\n                        s.setWrapperTranslate(newPosition);\n                        s.onTransitionStart();\n                        s.animating = true;\n                        s.wrapper.transitionEnd(function () {\n                            if (!s || !allowMomentumBounce) return;\n                            s.emit('onMomentumBounce', s);\n        \n                            s.setWrapperTransition(s.params.speed);\n                            s.setWrapperTranslate(afterBouncePosition);\n                            s.wrapper.transitionEnd(function () {\n                                if (!s) return;\n                                s.onTransitionEnd();\n                            });\n                        });\n                    } else if (s.velocity) {\n                        s.updateProgress(newPosition);\n                        s.setWrapperTransition(momentumDuration);\n                        s.setWrapperTranslate(newPosition);\n                        s.onTransitionStart();\n                        if (!s.animating) {\n                            s.animating = true;\n                            s.wrapper.transitionEnd(function () {\n                                if (!s) return;\n                                s.onTransitionEnd();\n                            });\n                        }\n        \n                    } else {\n                        s.updateProgress(newPosition);\n                    }\n        \n                    s.updateActiveIndex();\n                }\n                if (!s.params.freeModeMomentum || timeDiff >= s.params.longSwipesMs) {\n                    s.updateProgress();\n                    s.updateActiveIndex();\n                }\n                return;\n            }\n        \n            // Find current slide\n            var i, stopIndex = 0, groupSize = s.slidesSizesGrid[0];\n            for (i = 0; i < s.slidesGrid.length; i += s.params.slidesPerGroup) {\n                if (typeof s.slidesGrid[i + s.params.slidesPerGroup] !== 'undefined') {\n                    if (currentPos >= s.slidesGrid[i] && currentPos < s.slidesGrid[i + s.params.slidesPerGroup]) {\n                        stopIndex = i;\n                        groupSize = s.slidesGrid[i + s.params.slidesPerGroup] - s.slidesGrid[i];\n                    }\n                }\n                else {\n                    if (currentPos >= s.slidesGrid[i]) {\n                        stopIndex = i;\n                        groupSize = s.slidesGrid[s.slidesGrid.length - 1] - s.slidesGrid[s.slidesGrid.length - 2];\n                    }\n                }\n            }\n        \n            // Find current slide size\n            var ratio = (currentPos - s.slidesGrid[stopIndex]) / groupSize;\n        \n            if (timeDiff > s.params.longSwipesMs) {\n                // Long touches\n                if (!s.params.longSwipes) {\n                    s.slideTo(s.activeIndex);\n                    return;\n                }\n                if (s.swipeDirection === 'next') {\n                    if (ratio >= s.params.longSwipesRatio) s.slideTo(stopIndex + s.params.slidesPerGroup);\n                    else s.slideTo(stopIndex);\n        \n                }\n                if (s.swipeDirection === 'prev') {\n                    if (ratio > (1 - s.params.longSwipesRatio)) s.slideTo(stopIndex + s.params.slidesPerGroup);\n                    else s.slideTo(stopIndex);\n                }\n            }\n            else {\n                // Short swipes\n                if (!s.params.shortSwipes) {\n                    s.slideTo(s.activeIndex);\n                    return;\n                }\n                if (s.swipeDirection === 'next') {\n                    s.slideTo(stopIndex + s.params.slidesPerGroup);\n        \n                }\n                if (s.swipeDirection === 'prev') {\n                    s.slideTo(stopIndex);\n                }\n            }\n        };\n        /*=========================\n          Transitions\n          ===========================*/\n        s._slideTo = function (slideIndex, speed) {\n            return s.slideTo(slideIndex, speed, true, true);\n        };\n        s.slideTo = function (slideIndex, speed, runCallbacks, internal) {\n            if (typeof runCallbacks === 'undefined') runCallbacks = true;\n            if (typeof slideIndex === 'undefined') slideIndex = 0;\n            if (slideIndex < 0) slideIndex = 0;\n            s.snapIndex = Math.floor(slideIndex / s.params.slidesPerGroup);\n            if (s.snapIndex >= s.snapGrid.length) s.snapIndex = s.snapGrid.length - 1;\n        \n            var translate = - s.snapGrid[s.snapIndex];\n            // Stop autoplay\n            if (s.params.autoplay && s.autoplaying) {\n                if (internal || !s.params.autoplayDisableOnInteraction) {\n                    s.pauseAutoplay(speed);\n                }\n                else {\n                    s.stopAutoplay();\n                }\n            }\n            // Update progress\n            s.updateProgress(translate);\n        \n            // Normalize slideIndex\n            for (var i = 0; i < s.slidesGrid.length; i++) {\n                if (- Math.floor(translate * 100) >= Math.floor(s.slidesGrid[i] * 100)) {\n                    slideIndex = i;\n                }\n            }\n        \n            // Directions locks\n            if (!s.params.allowSwipeToNext && translate < s.translate && translate < s.minTranslate()) {\n                return false;\n            }\n            if (!s.params.allowSwipeToPrev && translate > s.translate && translate > s.maxTranslate()) {\n                if ((s.activeIndex || 0) !== slideIndex ) return false;\n            }\n        \n            // Update Index\n            if (typeof speed === 'undefined') speed = s.params.speed;\n            s.previousIndex = s.activeIndex || 0;\n            s.activeIndex = slideIndex;\n        \n            if ((s.rtl && -translate === s.translate) || (!s.rtl && translate === s.translate)) {\n                // Update Height\n                if (s.params.autoHeight) {\n                    s.updateAutoHeight();\n                }\n                s.updateClasses();\n                if (s.params.effect !== 'slide') {\n                    s.setWrapperTranslate(translate);\n                }\n                return false;\n            }\n            s.updateClasses();\n            s.onTransitionStart(runCallbacks);\n        \n            if (speed === 0) {\n                s.setWrapperTranslate(translate);\n                s.setWrapperTransition(0);\n                s.onTransitionEnd(runCallbacks);\n            }\n            else {\n                s.setWrapperTranslate(translate);\n                s.setWrapperTransition(speed);\n                if (!s.animating) {\n                    s.animating = true;\n                    s.wrapper.transitionEnd(function () {\n                        if (!s) return;\n                        s.onTransitionEnd(runCallbacks);\n                    });\n                }\n        \n            }\n        \n            return true;\n        };\n        \n        s.onTransitionStart = function (runCallbacks) {\n            if (typeof runCallbacks === 'undefined') runCallbacks = true;\n            if (s.params.autoHeight) {\n                s.updateAutoHeight();\n            }\n            if (s.lazy) s.lazy.onTransitionStart();\n            if (runCallbacks) {\n                s.emit('onTransitionStart', s);\n                if (s.activeIndex !== s.previousIndex) {\n                    s.emit('onSlideChangeStart', s);\n                    if (s.activeIndex > s.previousIndex) {\n                        s.emit('onSlideNextStart', s);\n                    }\n                    else {\n                        s.emit('onSlidePrevStart', s);\n                    }\n                }\n        \n            }\n        };\n        s.onTransitionEnd = function (runCallbacks) {\n            s.animating = false;\n            s.setWrapperTransition(0);\n            if (typeof runCallbacks === 'undefined') runCallbacks = true;\n            if (s.lazy) s.lazy.onTransitionEnd();\n            if (runCallbacks) {\n                s.emit('onTransitionEnd', s);\n                if (s.activeIndex !== s.previousIndex) {\n                    s.emit('onSlideChangeEnd', s);\n                    if (s.activeIndex > s.previousIndex) {\n                        s.emit('onSlideNextEnd', s);\n                    }\n                    else {\n                        s.emit('onSlidePrevEnd', s);\n                    }\n                }\n            }\n            if (s.params.hashnav && s.hashnav) {\n                s.hashnav.setHash();\n            }\n        \n        };\n        s.slideNext = function (runCallbacks, speed, internal) {\n            if (s.params.loop) {\n                if (s.animating) return false;\n                s.fixLoop();\n                var clientLeft = s.container[0].clientLeft;\n                return s.slideTo(s.activeIndex + s.params.slidesPerGroup, speed, runCallbacks, internal);\n            }\n            else return s.slideTo(s.activeIndex + s.params.slidesPerGroup, speed, runCallbacks, internal);\n        };\n        s._slideNext = function (speed) {\n            return s.slideNext(true, speed, true);\n        };\n        s.slidePrev = function (runCallbacks, speed, internal) {\n            if (s.params.loop) {\n                if (s.animating) return false;\n                s.fixLoop();\n                var clientLeft = s.container[0].clientLeft;\n                return s.slideTo(s.activeIndex - 1, speed, runCallbacks, internal);\n            }\n            else return s.slideTo(s.activeIndex - 1, speed, runCallbacks, internal);\n        };\n        s._slidePrev = function (speed) {\n            return s.slidePrev(true, speed, true);\n        };\n        s.slideReset = function (runCallbacks, speed, internal) {\n            return s.slideTo(s.activeIndex, speed, runCallbacks);\n        };\n        \n        /*=========================\n          Translate/transition helpers\n          ===========================*/\n        s.setWrapperTransition = function (duration, byController) {\n            s.wrapper.transition(duration);\n            if (s.params.effect !== 'slide' && s.effects[s.params.effect]) {\n                s.effects[s.params.effect].setTransition(duration);\n            }\n            if (s.params.parallax && s.parallax) {\n                s.parallax.setTransition(duration);\n            }\n            if (s.params.scrollbar && s.scrollbar) {\n                s.scrollbar.setTransition(duration);\n            }\n            if (s.params.control && s.controller) {\n                s.controller.setTransition(duration, byController);\n            }\n            s.emit('onSetTransition', s, duration);\n        };\n        s.setWrapperTranslate = function (translate, updateActiveIndex, byController) {\n            var x = 0, y = 0, z = 0;\n            if (s.isHorizontal()) {\n                x = s.rtl ? -translate : translate;\n            }\n            else {\n                y = translate;\n            }\n        \n            if (s.params.roundLengths) {\n                x = round(x);\n                y = round(y);\n            }\n        \n            if (!s.params.virtualTranslate) {\n                if (s.support.transforms3d) s.wrapper.transform('translate3d(' + x + 'px, ' + y + 'px, ' + z + 'px)');\n                else s.wrapper.transform('translate(' + x + 'px, ' + y + 'px)');\n            }\n        \n            s.translate = s.isHorizontal() ? x : y;\n        \n            // Check if we need to update progress\n            var progress;\n            var translatesDiff = s.maxTranslate() - s.minTranslate();\n            if (translatesDiff === 0) {\n                progress = 0;\n            }\n            else {\n                progress = (translate - s.minTranslate()) / (translatesDiff);\n            }\n            if (progress !== s.progress) {\n                s.updateProgress(translate);\n            }\n        \n            if (updateActiveIndex) s.updateActiveIndex();\n            if (s.params.effect !== 'slide' && s.effects[s.params.effect]) {\n                s.effects[s.params.effect].setTranslate(s.translate);\n            }\n            if (s.params.parallax && s.parallax) {\n                s.parallax.setTranslate(s.translate);\n            }\n            if (s.params.scrollbar && s.scrollbar) {\n                s.scrollbar.setTranslate(s.translate);\n            }\n            if (s.params.control && s.controller) {\n                s.controller.setTranslate(s.translate, byController);\n            }\n            s.emit('onSetTranslate', s, s.translate);\n        };\n        \n        s.getTranslate = function (el, axis) {\n            var matrix, curTransform, curStyle, transformMatrix;\n        \n            // automatic axis detection\n            if (typeof axis === 'undefined') {\n                axis = 'x';\n            }\n        \n            if (s.params.virtualTranslate) {\n                return s.rtl ? -s.translate : s.translate;\n            }\n        \n            curStyle = window.getComputedStyle(el, null);\n            if (window.WebKitCSSMatrix) {\n                curTransform = curStyle.transform || curStyle.webkitTransform;\n                if (curTransform.split(',').length > 6) {\n                    curTransform = curTransform.split(', ').map(function(a){\n                        return a.replace(',','.');\n                    }).join(', ');\n                }\n                // Some old versions of Webkit choke when 'none' is passed; pass\n                // empty string instead in this case\n                transformMatrix = new window.WebKitCSSMatrix(curTransform === 'none' ? '' : curTransform);\n            }\n            else {\n                transformMatrix = curStyle.MozTransform || curStyle.OTransform || curStyle.MsTransform || curStyle.msTransform  || curStyle.transform || curStyle.getPropertyValue('transform').replace('translate(', 'matrix(1, 0, 0, 1,');\n                matrix = transformMatrix.toString().split(',');\n            }\n        \n            if (axis === 'x') {\n                //Latest Chrome and webkits Fix\n                if (window.WebKitCSSMatrix)\n                    curTransform = transformMatrix.m41;\n                //Crazy IE10 Matrix\n                else if (matrix.length === 16)\n                    curTransform = parseFloat(matrix[12]);\n                //Normal Browsers\n                else\n                    curTransform = parseFloat(matrix[4]);\n            }\n            if (axis === 'y') {\n                //Latest Chrome and webkits Fix\n                if (window.WebKitCSSMatrix)\n                    curTransform = transformMatrix.m42;\n                //Crazy IE10 Matrix\n                else if (matrix.length === 16)\n                    curTransform = parseFloat(matrix[13]);\n                //Normal Browsers\n                else\n                    curTransform = parseFloat(matrix[5]);\n            }\n            if (s.rtl && curTransform) curTransform = -curTransform;\n            return curTransform || 0;\n        };\n        s.getWrapperTranslate = function (axis) {\n            if (typeof axis === 'undefined') {\n                axis = s.isHorizontal() ? 'x' : 'y';\n            }\n            return s.getTranslate(s.wrapper[0], axis);\n        };\n        \n        /*=========================\n          Observer\n          ===========================*/\n        s.observers = [];\n        function initObserver(target, options) {\n            options = options || {};\n            // create an observer instance\n            var ObserverFunc = window.MutationObserver || window.WebkitMutationObserver;\n            var observer = new ObserverFunc(function (mutations) {\n                mutations.forEach(function (mutation) {\n                    s.onResize(true);\n                    s.emit('onObserverUpdate', s, mutation);\n                });\n            });\n        \n            observer.observe(target, {\n                attributes: typeof options.attributes === 'undefined' ? true : options.attributes,\n                childList: typeof options.childList === 'undefined' ? true : options.childList,\n                characterData: typeof options.characterData === 'undefined' ? true : options.characterData\n            });\n        \n            s.observers.push(observer);\n        }\n        s.initObservers = function () {\n            if (s.params.observeParents) {\n                var containerParents = s.container.parents();\n                for (var i = 0; i < containerParents.length; i++) {\n                    initObserver(containerParents[i]);\n                }\n            }\n        \n            // Observe container\n            initObserver(s.container[0], {childList: false});\n        \n            // Observe wrapper\n            initObserver(s.wrapper[0], {attributes: false});\n        };\n        s.disconnectObservers = function () {\n            for (var i = 0; i < s.observers.length; i++) {\n                s.observers[i].disconnect();\n            }\n            s.observers = [];\n        };\n        /*=========================\n          Loop\n          ===========================*/\n        // Create looped slides\n        s.createLoop = function () {\n            // Remove duplicated slides\n            s.wrapper.children('.' + s.params.slideClass + '.' + s.params.slideDuplicateClass).remove();\n        \n            var slides = s.wrapper.children('.' + s.params.slideClass);\n        \n            if(s.params.slidesPerView === 'auto' && !s.params.loopedSlides) s.params.loopedSlides = slides.length;\n        \n            s.loopedSlides = parseInt(s.params.loopedSlides || s.params.slidesPerView, 10);\n            s.loopedSlides = s.loopedSlides + s.params.loopAdditionalSlides;\n            if (s.loopedSlides > slides.length) {\n                s.loopedSlides = slides.length;\n            }\n        \n            var prependSlides = [], appendSlides = [], i;\n            slides.each(function (index, el) {\n                var slide = $(this);\n                if (index < s.loopedSlides) appendSlides.push(el);\n                if (index < slides.length && index >= slides.length - s.loopedSlides) prependSlides.push(el);\n                slide.attr('data-swiper-slide-index', index);\n            });\n            for (i = 0; i < appendSlides.length; i++) {\n                s.wrapper.append($(appendSlides[i].cloneNode(true)).addClass(s.params.slideDuplicateClass));\n            }\n            for (i = prependSlides.length - 1; i >= 0; i--) {\n                s.wrapper.prepend($(prependSlides[i].cloneNode(true)).addClass(s.params.slideDuplicateClass));\n            }\n        };\n        s.destroyLoop = function () {\n            s.wrapper.children('.' + s.params.slideClass + '.' + s.params.slideDuplicateClass).remove();\n            s.slides.removeAttr('data-swiper-slide-index');\n        };\n        s.reLoop = function (updatePosition) {\n            var oldIndex = s.activeIndex - s.loopedSlides;\n            s.destroyLoop();\n            s.createLoop();\n            s.updateSlidesSize();\n            if (updatePosition) {\n                s.slideTo(oldIndex + s.loopedSlides, 0, false);\n            }\n        \n        };\n        s.fixLoop = function () {\n            var newIndex;\n            //Fix For Negative Oversliding\n            if (s.activeIndex < s.loopedSlides) {\n                newIndex = s.slides.length - s.loopedSlides * 3 + s.activeIndex;\n                newIndex = newIndex + s.loopedSlides;\n                s.slideTo(newIndex, 0, false, true);\n            }\n            //Fix For Positive Oversliding\n            else if ((s.params.slidesPerView === 'auto' && s.activeIndex >= s.loopedSlides * 2) || (s.activeIndex > s.slides.length - s.params.slidesPerView * 2)) {\n                newIndex = -s.slides.length + s.activeIndex + s.loopedSlides;\n                newIndex = newIndex + s.loopedSlides;\n                s.slideTo(newIndex, 0, false, true);\n            }\n        };\n        /*=========================\n          Append/Prepend/Remove Slides\n          ===========================*/\n        s.appendSlide = function (slides) {\n            if (s.params.loop) {\n                s.destroyLoop();\n            }\n            if (typeof slides === 'object' && slides.length) {\n                for (var i = 0; i < slides.length; i++) {\n                    if (slides[i]) s.wrapper.append(slides[i]);\n                }\n            }\n            else {\n                s.wrapper.append(slides);\n            }\n            if (s.params.loop) {\n                s.createLoop();\n            }\n            if (!(s.params.observer && s.support.observer)) {\n                s.update(true);\n            }\n        };\n        s.prependSlide = function (slides) {\n            if (s.params.loop) {\n                s.destroyLoop();\n            }\n            var newActiveIndex = s.activeIndex + 1;\n            if (typeof slides === 'object' && slides.length) {\n                for (var i = 0; i < slides.length; i++) {\n                    if (slides[i]) s.wrapper.prepend(slides[i]);\n                }\n                newActiveIndex = s.activeIndex + slides.length;\n            }\n            else {\n                s.wrapper.prepend(slides);\n            }\n            if (s.params.loop) {\n                s.createLoop();\n            }\n            if (!(s.params.observer && s.support.observer)) {\n                s.update(true);\n            }\n            s.slideTo(newActiveIndex, 0, false);\n        };\n        s.removeSlide = function (slidesIndexes) {\n            if (s.params.loop) {\n                s.destroyLoop();\n                s.slides = s.wrapper.children('.' + s.params.slideClass);\n            }\n            var newActiveIndex = s.activeIndex,\n                indexToRemove;\n            if (typeof slidesIndexes === 'object' && slidesIndexes.length) {\n                for (var i = 0; i < slidesIndexes.length; i++) {\n                    indexToRemove = slidesIndexes[i];\n                    if (s.slides[indexToRemove]) s.slides.eq(indexToRemove).remove();\n                    if (indexToRemove < newActiveIndex) newActiveIndex--;\n                }\n                newActiveIndex = Math.max(newActiveIndex, 0);\n            }\n            else {\n                indexToRemove = slidesIndexes;\n                if (s.slides[indexToRemove]) s.slides.eq(indexToRemove).remove();\n                if (indexToRemove < newActiveIndex) newActiveIndex--;\n                newActiveIndex = Math.max(newActiveIndex, 0);\n            }\n        \n            if (s.params.loop) {\n                s.createLoop();\n            }\n        \n            if (!(s.params.observer && s.support.observer)) {\n                s.update(true);\n            }\n            if (s.params.loop) {\n                s.slideTo(newActiveIndex + s.loopedSlides, 0, false);\n            }\n            else {\n                s.slideTo(newActiveIndex, 0, false);\n            }\n        \n        };\n        s.removeAllSlides = function () {\n            var slidesIndexes = [];\n            for (var i = 0; i < s.slides.length; i++) {\n                slidesIndexes.push(i);\n            }\n            s.removeSlide(slidesIndexes);\n        };\n        \n\n        /*=========================\n          Effects\n          ===========================*/\n        s.effects = {\n            fade: {\n                setTranslate: function () {\n                    for (var i = 0; i < s.slides.length; i++) {\n                        var slide = s.slides.eq(i);\n                        var offset = slide[0].swiperSlideOffset;\n                        var tx = -offset;\n                        if (!s.params.virtualTranslate) tx = tx - s.translate;\n                        var ty = 0;\n                        if (!s.isHorizontal()) {\n                            ty = tx;\n                            tx = 0;\n                        }\n                        var slideOpacity = s.params.fade.crossFade ?\n                                Math.max(1 - Math.abs(slide[0].progress), 0) :\n                                1 + Math.min(Math.max(slide[0].progress, -1), 0);\n                        slide\n                            .css({\n                                opacity: slideOpacity\n                            })\n                            .transform('translate3d(' + tx + 'px, ' + ty + 'px, 0px)');\n        \n                    }\n        \n                },\n                setTransition: function (duration) {\n                    s.slides.transition(duration);\n                    if (s.params.virtualTranslate && duration !== 0) {\n                        var eventTriggered = false;\n                        s.slides.transitionEnd(function () {\n                            if (eventTriggered) return;\n                            if (!s) return;\n                            eventTriggered = true;\n                            s.animating = false;\n                            var triggerEvents = ['webkitTransitionEnd', 'transitionend', 'oTransitionEnd', 'MSTransitionEnd', 'msTransitionEnd'];\n                            for (var i = 0; i < triggerEvents.length; i++) {\n                                s.wrapper.trigger(triggerEvents[i]);\n                            }\n                        });\n                    }\n                }\n            },\n            flip: {\n                setTranslate: function () {\n                    for (var i = 0; i < s.slides.length; i++) {\n                        var slide = s.slides.eq(i);\n                        var progress = slide[0].progress;\n                        if (s.params.flip.limitRotation) {\n                            progress = Math.max(Math.min(slide[0].progress, 1), -1);\n                        }\n                        var offset = slide[0].swiperSlideOffset;\n                        var rotate = -180 * progress,\n                            rotateY = rotate,\n                            rotateX = 0,\n                            tx = -offset,\n                            ty = 0;\n                        if (!s.isHorizontal()) {\n                            ty = tx;\n                            tx = 0;\n                            rotateX = -rotateY;\n                            rotateY = 0;\n                        }\n                        else if (s.rtl) {\n                            rotateY = -rotateY;\n                        }\n        \n                        slide[0].style.zIndex = -Math.abs(Math.round(progress)) + s.slides.length;\n        \n                        if (s.params.flip.slideShadows) {\n                            //Set shadows\n                            var shadowBefore = s.isHorizontal() ? slide.find('.swiper-slide-shadow-left') : slide.find('.swiper-slide-shadow-top');\n                            var shadowAfter = s.isHorizontal() ? slide.find('.swiper-slide-shadow-right') : slide.find('.swiper-slide-shadow-bottom');\n                            if (shadowBefore.length === 0) {\n                                shadowBefore = $('<div class=\"swiper-slide-shadow-' + (s.isHorizontal() ? 'left' : 'top') + '\"></div>');\n                                slide.append(shadowBefore);\n                            }\n                            if (shadowAfter.length === 0) {\n                                shadowAfter = $('<div class=\"swiper-slide-shadow-' + (s.isHorizontal() ? 'right' : 'bottom') + '\"></div>');\n                                slide.append(shadowAfter);\n                            }\n                            if (shadowBefore.length) shadowBefore[0].style.opacity = Math.max(-progress, 0);\n                            if (shadowAfter.length) shadowAfter[0].style.opacity = Math.max(progress, 0);\n                        }\n        \n                        slide\n                            .transform('translate3d(' + tx + 'px, ' + ty + 'px, 0px) rotateX(' + rotateX + 'deg) rotateY(' + rotateY + 'deg)');\n                    }\n                },\n                setTransition: function (duration) {\n                    s.slides.transition(duration).find('.swiper-slide-shadow-top, .swiper-slide-shadow-right, .swiper-slide-shadow-bottom, .swiper-slide-shadow-left').transition(duration);\n                    if (s.params.virtualTranslate && duration !== 0) {\n                        var eventTriggered = false;\n                        s.slides.eq(s.activeIndex).transitionEnd(function () {\n                            if (eventTriggered) return;\n                            if (!s) return;\n                            if (!$(this).hasClass(s.params.slideActiveClass)) return;\n                            eventTriggered = true;\n                            s.animating = false;\n                            var triggerEvents = ['webkitTransitionEnd', 'transitionend', 'oTransitionEnd', 'MSTransitionEnd', 'msTransitionEnd'];\n                            for (var i = 0; i < triggerEvents.length; i++) {\n                                s.wrapper.trigger(triggerEvents[i]);\n                            }\n                        });\n                    }\n                }\n            },\n            cube: {\n                setTranslate: function () {\n                    var wrapperRotate = 0, cubeShadow;\n                    if (s.params.cube.shadow) {\n                        if (s.isHorizontal()) {\n                            cubeShadow = s.wrapper.find('.swiper-cube-shadow');\n                            if (cubeShadow.length === 0) {\n                                cubeShadow = $('<div class=\"swiper-cube-shadow\"></div>');\n                                s.wrapper.append(cubeShadow);\n                            }\n                            cubeShadow.css({height: s.width + 'px'});\n                        }\n                        else {\n                            cubeShadow = s.container.find('.swiper-cube-shadow');\n                            if (cubeShadow.length === 0) {\n                                cubeShadow = $('<div class=\"swiper-cube-shadow\"></div>');\n                                s.container.append(cubeShadow);\n                            }\n                        }\n                    }\n                    for (var i = 0; i < s.slides.length; i++) {\n                        var slide = s.slides.eq(i);\n                        var slideAngle = i * 90;\n                        var round = Math.floor(slideAngle / 360);\n                        if (s.rtl) {\n                            slideAngle = -slideAngle;\n                            round = Math.floor(-slideAngle / 360);\n                        }\n                        var progress = Math.max(Math.min(slide[0].progress, 1), -1);\n                        var tx = 0, ty = 0, tz = 0;\n                        if (i % 4 === 0) {\n                            tx = - round * 4 * s.size;\n                            tz = 0;\n                        }\n                        else if ((i - 1) % 4 === 0) {\n                            tx = 0;\n                            tz = - round * 4 * s.size;\n                        }\n                        else if ((i - 2) % 4 === 0) {\n                            tx = s.size + round * 4 * s.size;\n                            tz = s.size;\n                        }\n                        else if ((i - 3) % 4 === 0) {\n                            tx = - s.size;\n                            tz = 3 * s.size + s.size * 4 * round;\n                        }\n                        if (s.rtl) {\n                            tx = -tx;\n                        }\n        \n                        if (!s.isHorizontal()) {\n                            ty = tx;\n                            tx = 0;\n                        }\n        \n                        var transform = 'rotateX(' + (s.isHorizontal() ? 0 : -slideAngle) + 'deg) rotateY(' + (s.isHorizontal() ? slideAngle : 0) + 'deg) translate3d(' + tx + 'px, ' + ty + 'px, ' + tz + 'px)';\n                        if (progress <= 1 && progress > -1) {\n                            wrapperRotate = i * 90 + progress * 90;\n                            if (s.rtl) wrapperRotate = -i * 90 - progress * 90;\n                        }\n                        slide.transform(transform);\n                        if (s.params.cube.slideShadows) {\n                            //Set shadows\n                            var shadowBefore = s.isHorizontal() ? slide.find('.swiper-slide-shadow-left') : slide.find('.swiper-slide-shadow-top');\n                            var shadowAfter = s.isHorizontal() ? slide.find('.swiper-slide-shadow-right') : slide.find('.swiper-slide-shadow-bottom');\n                            if (shadowBefore.length === 0) {\n                                shadowBefore = $('<div class=\"swiper-slide-shadow-' + (s.isHorizontal() ? 'left' : 'top') + '\"></div>');\n                                slide.append(shadowBefore);\n                            }\n                            if (shadowAfter.length === 0) {\n                                shadowAfter = $('<div class=\"swiper-slide-shadow-' + (s.isHorizontal() ? 'right' : 'bottom') + '\"></div>');\n                                slide.append(shadowAfter);\n                            }\n                            if (shadowBefore.length) shadowBefore[0].style.opacity = Math.max(-progress, 0);\n                            if (shadowAfter.length) shadowAfter[0].style.opacity = Math.max(progress, 0);\n                        }\n                    }\n                    s.wrapper.css({\n                        '-webkit-transform-origin': '50% 50% -' + (s.size / 2) + 'px',\n                        '-moz-transform-origin': '50% 50% -' + (s.size / 2) + 'px',\n                        '-ms-transform-origin': '50% 50% -' + (s.size / 2) + 'px',\n                        'transform-origin': '50% 50% -' + (s.size / 2) + 'px'\n                    });\n        \n                    if (s.params.cube.shadow) {\n                        if (s.isHorizontal()) {\n                            cubeShadow.transform('translate3d(0px, ' + (s.width / 2 + s.params.cube.shadowOffset) + 'px, ' + (-s.width / 2) + 'px) rotateX(90deg) rotateZ(0deg) scale(' + (s.params.cube.shadowScale) + ')');\n                        }\n                        else {\n                            var shadowAngle = Math.abs(wrapperRotate) - Math.floor(Math.abs(wrapperRotate) / 90) * 90;\n                            var multiplier = 1.5 - (Math.sin(shadowAngle * 2 * Math.PI / 360) / 2 + Math.cos(shadowAngle * 2 * Math.PI / 360) / 2);\n                            var scale1 = s.params.cube.shadowScale,\n                                scale2 = s.params.cube.shadowScale / multiplier,\n                                offset = s.params.cube.shadowOffset;\n                            cubeShadow.transform('scale3d(' + scale1 + ', 1, ' + scale2 + ') translate3d(0px, ' + (s.height / 2 + offset) + 'px, ' + (-s.height / 2 / scale2) + 'px) rotateX(-90deg)');\n                        }\n                    }\n                    var zFactor = (s.isSafari || s.isUiWebView) ? (-s.size / 2) : 0;\n                    s.wrapper.transform('translate3d(0px,0,' + zFactor + 'px) rotateX(' + (s.isHorizontal() ? 0 : wrapperRotate) + 'deg) rotateY(' + (s.isHorizontal() ? -wrapperRotate : 0) + 'deg)');\n                },\n                setTransition: function (duration) {\n                    s.slides.transition(duration).find('.swiper-slide-shadow-top, .swiper-slide-shadow-right, .swiper-slide-shadow-bottom, .swiper-slide-shadow-left').transition(duration);\n                    if (s.params.cube.shadow && !s.isHorizontal()) {\n                        s.container.find('.swiper-cube-shadow').transition(duration);\n                    }\n                }\n            },\n            coverflow: {\n                setTranslate: function () {\n                    var transform = s.translate;\n                    var center = s.isHorizontal() ? -transform + s.width / 2 : -transform + s.height / 2;\n                    var rotate = s.isHorizontal() ? s.params.coverflow.rotate: -s.params.coverflow.rotate;\n                    var translate = s.params.coverflow.depth;\n                    //Each slide offset from center\n                    for (var i = 0, length = s.slides.length; i < length; i++) {\n                        var slide = s.slides.eq(i);\n                        var slideSize = s.slidesSizesGrid[i];\n                        var slideOffset = slide[0].swiperSlideOffset;\n                        var offsetMultiplier = (center - slideOffset - slideSize / 2) / slideSize * s.params.coverflow.modifier;\n        \n                        var rotateY = s.isHorizontal() ? rotate * offsetMultiplier : 0;\n                        var rotateX = s.isHorizontal() ? 0 : rotate * offsetMultiplier;\n                        // var rotateZ = 0\n                        var translateZ = -translate * Math.abs(offsetMultiplier);\n        \n                        var translateY = s.isHorizontal() ? 0 : s.params.coverflow.stretch * (offsetMultiplier);\n                        var translateX = s.isHorizontal() ? s.params.coverflow.stretch * (offsetMultiplier) : 0;\n        \n                        //Fix for ultra small values\n                        if (Math.abs(translateX) < 0.001) translateX = 0;\n                        if (Math.abs(translateY) < 0.001) translateY = 0;\n                        if (Math.abs(translateZ) < 0.001) translateZ = 0;\n                        if (Math.abs(rotateY) < 0.001) rotateY = 0;\n                        if (Math.abs(rotateX) < 0.001) rotateX = 0;\n        \n                        var slideTransform = 'translate3d(' + translateX + 'px,' + translateY + 'px,' + translateZ + 'px)  rotateX(' + rotateX + 'deg) rotateY(' + rotateY + 'deg)';\n        \n                        slide.transform(slideTransform);\n                        slide[0].style.zIndex = -Math.abs(Math.round(offsetMultiplier)) + 1;\n                        if (s.params.coverflow.slideShadows) {\n                            //Set shadows\n                            var shadowBefore = s.isHorizontal() ? slide.find('.swiper-slide-shadow-left') : slide.find('.swiper-slide-shadow-top');\n                            var shadowAfter = s.isHorizontal() ? slide.find('.swiper-slide-shadow-right') : slide.find('.swiper-slide-shadow-bottom');\n                            if (shadowBefore.length === 0) {\n                                shadowBefore = $('<div class=\"swiper-slide-shadow-' + (s.isHorizontal() ? 'left' : 'top') + '\"></div>');\n                                slide.append(shadowBefore);\n                            }\n                            if (shadowAfter.length === 0) {\n                                shadowAfter = $('<div class=\"swiper-slide-shadow-' + (s.isHorizontal() ? 'right' : 'bottom') + '\"></div>');\n                                slide.append(shadowAfter);\n                            }\n                            if (shadowBefore.length) shadowBefore[0].style.opacity = offsetMultiplier > 0 ? offsetMultiplier : 0;\n                            if (shadowAfter.length) shadowAfter[0].style.opacity = (-offsetMultiplier) > 0 ? -offsetMultiplier : 0;\n                        }\n                    }\n        \n                    //Set correct perspective for IE10\n                    if (s.browser.ie) {\n                        var ws = s.wrapper[0].style;\n                        ws.perspectiveOrigin = center + 'px 50%';\n                    }\n                },\n                setTransition: function (duration) {\n                    s.slides.transition(duration).find('.swiper-slide-shadow-top, .swiper-slide-shadow-right, .swiper-slide-shadow-bottom, .swiper-slide-shadow-left').transition(duration);\n                }\n            }\n        };\n\n        /*=========================\n          Images Lazy Loading\n          ===========================*/\n        s.lazy = {\n            initialImageLoaded: false,\n            loadImageInSlide: function (index, loadInDuplicate) {\n                if (typeof index === 'undefined') return;\n                if (typeof loadInDuplicate === 'undefined') loadInDuplicate = true;\n                if (s.slides.length === 0) return;\n        \n                var slide = s.slides.eq(index);\n                var img = slide.find('.swiper-lazy:not(.swiper-lazy-loaded):not(.swiper-lazy-loading)');\n                if (slide.hasClass('swiper-lazy') && !slide.hasClass('swiper-lazy-loaded') && !slide.hasClass('swiper-lazy-loading')) {\n                    img = img.add(slide[0]);\n                }\n                if (img.length === 0) return;\n        \n                img.each(function () {\n                    var _img = $(this);\n                    _img.addClass('swiper-lazy-loading');\n                    var background = _img.attr('data-background');\n                    var src = _img.attr('data-src'),\n                        srcset = _img.attr('data-srcset');\n                    s.loadImage(_img[0], (src || background), srcset, false, function () {\n                        if (background) {\n                            _img.css('background-image', 'url(\"' + background + '\")');\n                            _img.removeAttr('data-background');\n                        }\n                        else {\n                            if (srcset) {\n                                _img.attr('srcset', srcset);\n                                _img.removeAttr('data-srcset');\n                            }\n                            if (src) {\n                                _img.attr('src', src);\n                                _img.removeAttr('data-src');\n                            }\n        \n                        }\n        \n                        _img.addClass('swiper-lazy-loaded').removeClass('swiper-lazy-loading');\n                        slide.find('.swiper-lazy-preloader, .preloader').remove();\n                        if (s.params.loop && loadInDuplicate) {\n                            var slideOriginalIndex = slide.attr('data-swiper-slide-index');\n                            if (slide.hasClass(s.params.slideDuplicateClass)) {\n                                var originalSlide = s.wrapper.children('[data-swiper-slide-index=\"' + slideOriginalIndex + '\"]:not(.' + s.params.slideDuplicateClass + ')');\n                                s.lazy.loadImageInSlide(originalSlide.index(), false);\n                            }\n                            else {\n                                var duplicatedSlide = s.wrapper.children('.' + s.params.slideDuplicateClass + '[data-swiper-slide-index=\"' + slideOriginalIndex + '\"]');\n                                s.lazy.loadImageInSlide(duplicatedSlide.index(), false);\n                            }\n                        }\n                        s.emit('onLazyImageReady', s, slide[0], _img[0]);\n                    });\n        \n                    s.emit('onLazyImageLoad', s, slide[0], _img[0]);\n                });\n        \n            },\n            load: function () {\n                var i;\n                if (s.params.watchSlidesVisibility) {\n                    s.wrapper.children('.' + s.params.slideVisibleClass).each(function () {\n                        s.lazy.loadImageInSlide($(this).index());\n                    });\n                }\n                else {\n                    if (s.params.slidesPerView > 1) {\n                        for (i = s.activeIndex; i < s.activeIndex + s.params.slidesPerView ; i++) {\n                            if (s.slides[i]) s.lazy.loadImageInSlide(i);\n                        }\n                    }\n                    else {\n                        s.lazy.loadImageInSlide(s.activeIndex);\n                    }\n                }\n                if (s.params.lazyLoadingInPrevNext) {\n                    if (s.params.slidesPerView > 1 || (s.params.lazyLoadingInPrevNextAmount && s.params.lazyLoadingInPrevNextAmount > 1)) {\n                        var amount = s.params.lazyLoadingInPrevNextAmount;\n                        var spv = s.params.slidesPerView;\n                        var maxIndex = Math.min(s.activeIndex + spv + Math.max(amount, spv), s.slides.length);\n                        var minIndex = Math.max(s.activeIndex - Math.max(spv, amount), 0);\n                        // Next Slides\n                        for (i = s.activeIndex + s.params.slidesPerView; i < maxIndex; i++) {\n                            if (s.slides[i]) s.lazy.loadImageInSlide(i);\n                        }\n                        // Prev Slides\n                        for (i = minIndex; i < s.activeIndex ; i++) {\n                            if (s.slides[i]) s.lazy.loadImageInSlide(i);\n                        }\n                    }\n                    else {\n                        var nextSlide = s.wrapper.children('.' + s.params.slideNextClass);\n                        if (nextSlide.length > 0) s.lazy.loadImageInSlide(nextSlide.index());\n        \n                        var prevSlide = s.wrapper.children('.' + s.params.slidePrevClass);\n                        if (prevSlide.length > 0) s.lazy.loadImageInSlide(prevSlide.index());\n                    }\n                }\n            },\n            onTransitionStart: function () {\n                if (s.params.lazyLoading) {\n                    if (s.params.lazyLoadingOnTransitionStart || (!s.params.lazyLoadingOnTransitionStart && !s.lazy.initialImageLoaded)) {\n                        s.lazy.load();\n                    }\n                }\n            },\n            onTransitionEnd: function () {\n                if (s.params.lazyLoading && !s.params.lazyLoadingOnTransitionStart) {\n                    s.lazy.load();\n                }\n            }\n        };\n        \n\n        /*=========================\n          Scrollbar\n          ===========================*/\n        s.scrollbar = {\n            isTouched: false,\n            setDragPosition: function (e) {\n                var sb = s.scrollbar;\n                var x = 0, y = 0;\n                var translate;\n                var pointerPosition = s.isHorizontal() ?\n                    ((e.type === 'touchstart' || e.type === 'touchmove') ? e.targetTouches[0].pageX : e.pageX || e.clientX) :\n                    ((e.type === 'touchstart' || e.type === 'touchmove') ? e.targetTouches[0].pageY : e.pageY || e.clientY) ;\n                var position = (pointerPosition) - sb.track.offset()[s.isHorizontal() ? 'left' : 'top'] - sb.dragSize / 2;\n                var positionMin = -s.minTranslate() * sb.moveDivider;\n                var positionMax = -s.maxTranslate() * sb.moveDivider;\n                if (position < positionMin) {\n                    position = positionMin;\n                }\n                else if (position > positionMax) {\n                    position = positionMax;\n                }\n                position = -position / sb.moveDivider;\n                s.updateProgress(position);\n                s.setWrapperTranslate(position, true);\n            },\n            dragStart: function (e) {\n                var sb = s.scrollbar;\n                sb.isTouched = true;\n                e.preventDefault();\n                e.stopPropagation();\n        \n                sb.setDragPosition(e);\n                clearTimeout(sb.dragTimeout);\n        \n                sb.track.transition(0);\n                if (s.params.scrollbarHide) {\n                    sb.track.css('opacity', 1);\n                }\n                s.wrapper.transition(100);\n                sb.drag.transition(100);\n                s.emit('onScrollbarDragStart', s);\n            },\n            dragMove: function (e) {\n                var sb = s.scrollbar;\n                if (!sb.isTouched) return;\n                if (e.preventDefault) e.preventDefault();\n                else e.returnValue = false;\n                sb.setDragPosition(e);\n                s.wrapper.transition(0);\n                sb.track.transition(0);\n                sb.drag.transition(0);\n                s.emit('onScrollbarDragMove', s);\n            },\n            dragEnd: function (e) {\n                var sb = s.scrollbar;\n                if (!sb.isTouched) return;\n                sb.isTouched = false;\n                if (s.params.scrollbarHide) {\n                    clearTimeout(sb.dragTimeout);\n                    sb.dragTimeout = setTimeout(function () {\n                        sb.track.css('opacity', 0);\n                        sb.track.transition(400);\n                    }, 1000);\n        \n                }\n                s.emit('onScrollbarDragEnd', s);\n                if (s.params.scrollbarSnapOnRelease) {\n                    s.slideReset();\n                }\n            },\n            enableDraggable: function () {\n                var sb = s.scrollbar;\n                var target = s.support.touch ? sb.track : document;\n                $(sb.track).on(s.touchEvents.start, sb.dragStart);\n                $(target).on(s.touchEvents.move, sb.dragMove);\n                $(target).on(s.touchEvents.end, sb.dragEnd);\n            },\n            disableDraggable: function () {\n                var sb = s.scrollbar;\n                var target = s.support.touch ? sb.track : document;\n                $(sb.track).off(s.touchEvents.start, sb.dragStart);\n                $(target).off(s.touchEvents.move, sb.dragMove);\n                $(target).off(s.touchEvents.end, sb.dragEnd);\n            },\n            set: function () {\n                if (!s.params.scrollbar) return;\n                var sb = s.scrollbar;\n                sb.track = $(s.params.scrollbar);\n                if (s.params.uniqueNavElements && typeof s.params.scrollbar === 'string' && sb.track.length > 1 && s.container.find(s.params.scrollbar).length === 1) {\n                    sb.track = s.container.find(s.params.scrollbar);\n                }\n                sb.drag = sb.track.find('.swiper-scrollbar-drag');\n                if (sb.drag.length === 0) {\n                    sb.drag = $('<div class=\"swiper-scrollbar-drag\"></div>');\n                    sb.track.append(sb.drag);\n                }\n                sb.drag[0].style.width = '';\n                sb.drag[0].style.height = '';\n                sb.trackSize = s.isHorizontal() ? sb.track[0].offsetWidth : sb.track[0].offsetHeight;\n        \n                sb.divider = s.size / s.virtualSize;\n                sb.moveDivider = sb.divider * (sb.trackSize / s.size);\n                sb.dragSize = sb.trackSize * sb.divider;\n        \n                if (s.isHorizontal()) {\n                    sb.drag[0].style.width = sb.dragSize + 'px';\n                }\n                else {\n                    sb.drag[0].style.height = sb.dragSize + 'px';\n                }\n        \n                if (sb.divider >= 1) {\n                    sb.track[0].style.display = 'none';\n                }\n                else {\n                    sb.track[0].style.display = '';\n                }\n                if (s.params.scrollbarHide) {\n                    sb.track[0].style.opacity = 0;\n                }\n            },\n            setTranslate: function () {\n                if (!s.params.scrollbar) return;\n                var diff;\n                var sb = s.scrollbar;\n                var translate = s.translate || 0;\n                var newPos;\n        \n                var newSize = sb.dragSize;\n                newPos = (sb.trackSize - sb.dragSize) * s.progress;\n                if (s.rtl && s.isHorizontal()) {\n                    newPos = -newPos;\n                    if (newPos > 0) {\n                        newSize = sb.dragSize - newPos;\n                        newPos = 0;\n                    }\n                    else if (-newPos + sb.dragSize > sb.trackSize) {\n                        newSize = sb.trackSize + newPos;\n                    }\n                }\n                else {\n                    if (newPos < 0) {\n                        newSize = sb.dragSize + newPos;\n                        newPos = 0;\n                    }\n                    else if (newPos + sb.dragSize > sb.trackSize) {\n                        newSize = sb.trackSize - newPos;\n                    }\n                }\n                if (s.isHorizontal()) {\n                    if (s.support.transforms3d) {\n                        sb.drag.transform('translate3d(' + (newPos) + 'px, 0, 0)');\n                    }\n                    else {\n                        sb.drag.transform('translateX(' + (newPos) + 'px)');\n                    }\n                    sb.drag[0].style.width = newSize + 'px';\n                }\n                else {\n                    if (s.support.transforms3d) {\n                        sb.drag.transform('translate3d(0px, ' + (newPos) + 'px, 0)');\n                    }\n                    else {\n                        sb.drag.transform('translateY(' + (newPos) + 'px)');\n                    }\n                    sb.drag[0].style.height = newSize + 'px';\n                }\n                if (s.params.scrollbarHide) {\n                    clearTimeout(sb.timeout);\n                    sb.track[0].style.opacity = 1;\n                    sb.timeout = setTimeout(function () {\n                        sb.track[0].style.opacity = 0;\n                        sb.track.transition(400);\n                    }, 1000);\n                }\n            },\n            setTransition: function (duration) {\n                if (!s.params.scrollbar) return;\n                s.scrollbar.drag.transition(duration);\n            }\n        };\n\n        /*=========================\n          Controller\n          ===========================*/\n        s.controller = {\n            LinearSpline: function (x, y) {\n                this.x = x;\n                this.y = y;\n                this.lastIndex = x.length - 1;\n                // Given an x value (x2), return the expected y2 value:\n                // (x1,y1) is the known point before given value,\n                // (x3,y3) is the known point after given value.\n                var i1, i3;\n                var l = this.x.length;\n        \n                this.interpolate = function (x2) {\n                    if (!x2) return 0;\n        \n                    // Get the indexes of x1 and x3 (the array indexes before and after given x2):\n                    i3 = binarySearch(this.x, x2);\n                    i1 = i3 - 1;\n        \n                    // We have our indexes i1 & i3, so we can calculate already:\n                    // y2 := ((x2−x1) × (y3−y1)) ÷ (x3−x1) + y1\n                    return ((x2 - this.x[i1]) * (this.y[i3] - this.y[i1])) / (this.x[i3] - this.x[i1]) + this.y[i1];\n                };\n        \n                var binarySearch = (function() {\n                    var maxIndex, minIndex, guess;\n                    return function(array, val) {\n                        minIndex = -1;\n                        maxIndex = array.length;\n                        while (maxIndex - minIndex > 1)\n                            if (array[guess = maxIndex + minIndex >> 1] <= val) {\n                                minIndex = guess;\n                            } else {\n                                maxIndex = guess;\n                            }\n                        return maxIndex;\n                    };\n                })();\n            },\n            //xxx: for now i will just save one spline function to to\n            getInterpolateFunction: function(c){\n                if(!s.controller.spline) s.controller.spline = s.params.loop ?\n                    new s.controller.LinearSpline(s.slidesGrid, c.slidesGrid) :\n                    new s.controller.LinearSpline(s.snapGrid, c.snapGrid);\n            },\n            setTranslate: function (translate, byController) {\n               var controlled = s.params.control;\n               var multiplier, controlledTranslate;\n               function setControlledTranslate(c) {\n                    // this will create an Interpolate function based on the snapGrids\n                    // x is the Grid of the scrolled scroller and y will be the controlled scroller\n                    // it makes sense to create this only once and recall it for the interpolation\n                    // the function does a lot of value caching for performance\n                    translate = c.rtl && c.params.direction === 'horizontal' ? -s.translate : s.translate;\n                    if (s.params.controlBy === 'slide') {\n                        s.controller.getInterpolateFunction(c);\n                        // i am not sure why the values have to be multiplicated this way, tried to invert the snapGrid\n                        // but it did not work out\n                        controlledTranslate = -s.controller.spline.interpolate(-translate);\n                    }\n        \n                    if(!controlledTranslate || s.params.controlBy === 'container'){\n                        multiplier = (c.maxTranslate() - c.minTranslate()) / (s.maxTranslate() - s.minTranslate());\n                        controlledTranslate = (translate - s.minTranslate()) * multiplier + c.minTranslate();\n                    }\n        \n                    if (s.params.controlInverse) {\n                        controlledTranslate = c.maxTranslate() - controlledTranslate;\n                    }\n                    c.updateProgress(controlledTranslate);\n                    c.setWrapperTranslate(controlledTranslate, false, s);\n                    c.updateActiveIndex();\n               }\n               if (s.isArray(controlled)) {\n                   for (var i = 0; i < controlled.length; i++) {\n                       if (controlled[i] !== byController && controlled[i] instanceof Swiper) {\n                           setControlledTranslate(controlled[i]);\n                       }\n                   }\n               }\n               else if (controlled instanceof Swiper && byController !== controlled) {\n        \n                   setControlledTranslate(controlled);\n               }\n            },\n            setTransition: function (duration, byController) {\n                var controlled = s.params.control;\n                var i;\n                function setControlledTransition(c) {\n                    c.setWrapperTransition(duration, s);\n                    if (duration !== 0) {\n                        c.onTransitionStart();\n                        c.wrapper.transitionEnd(function(){\n                            if (!controlled) return;\n                            if (c.params.loop && s.params.controlBy === 'slide') {\n                                c.fixLoop();\n                            }\n                            c.onTransitionEnd();\n        \n                        });\n                    }\n                }\n                if (s.isArray(controlled)) {\n                    for (i = 0; i < controlled.length; i++) {\n                        if (controlled[i] !== byController && controlled[i] instanceof Swiper) {\n                            setControlledTransition(controlled[i]);\n                        }\n                    }\n                }\n                else if (controlled instanceof Swiper && byController !== controlled) {\n                    setControlledTransition(controlled);\n                }\n            }\n        };\n\n        /*=========================\n          Hash Navigation\n          ===========================*/\n        s.hashnav = {\n            init: function () {\n                if (!s.params.hashnav) return;\n                s.hashnav.initialized = true;\n                var hash = document.location.hash.replace('#', '');\n                if (!hash) return;\n                var speed = 0;\n                for (var i = 0, length = s.slides.length; i < length; i++) {\n                    var slide = s.slides.eq(i);\n                    var slideHash = slide.attr('data-hash');\n                    if (slideHash === hash && !slide.hasClass(s.params.slideDuplicateClass)) {\n                        var index = slide.index();\n                        s.slideTo(index, speed, s.params.runCallbacksOnInit, true);\n                    }\n                }\n            },\n            setHash: function () {\n                if (!s.hashnav.initialized || !s.params.hashnav) return;\n                document.location.hash = s.slides.eq(s.activeIndex).attr('data-hash') || '';\n            }\n        };\n\n        /*=========================\n          Keyboard Control\n          ===========================*/\n        function handleKeyboard(e) {\n            if (e.originalEvent) e = e.originalEvent; //jquery fix\n            var kc = e.keyCode || e.charCode;\n            // Directions locks\n            if (!s.params.allowSwipeToNext && (s.isHorizontal() && kc === 39 || !s.isHorizontal() && kc === 40)) {\n                return false;\n            }\n            if (!s.params.allowSwipeToPrev && (s.isHorizontal() && kc === 37 || !s.isHorizontal() && kc === 38)) {\n                return false;\n            }\n            if (e.shiftKey || e.altKey || e.ctrlKey || e.metaKey) {\n                return;\n            }\n            if (document.activeElement && document.activeElement.nodeName && (document.activeElement.nodeName.toLowerCase() === 'input' || document.activeElement.nodeName.toLowerCase() === 'textarea')) {\n                return;\n            }\n            if (kc === 37 || kc === 39 || kc === 38 || kc === 40) {\n                var inView = false;\n                //Check that swiper should be inside of visible area of window\n                if (s.container.parents('.swiper-slide').length > 0 && s.container.parents('.swiper-slide-active').length === 0) {\n                    return;\n                }\n                var windowScroll = {\n                    left: window.pageXOffset,\n                    top: window.pageYOffset\n                };\n                var windowWidth = window.innerWidth;\n                var windowHeight = window.innerHeight;\n                var swiperOffset = s.container.offset();\n                if (s.rtl) swiperOffset.left = swiperOffset.left - s.container[0].scrollLeft;\n                var swiperCoord = [\n                    [swiperOffset.left, swiperOffset.top],\n                    [swiperOffset.left + s.width, swiperOffset.top],\n                    [swiperOffset.left, swiperOffset.top + s.height],\n                    [swiperOffset.left + s.width, swiperOffset.top + s.height]\n                ];\n                for (var i = 0; i < swiperCoord.length; i++) {\n                    var point = swiperCoord[i];\n                    if (\n                        point[0] >= windowScroll.left && point[0] <= windowScroll.left + windowWidth &&\n                        point[1] >= windowScroll.top && point[1] <= windowScroll.top + windowHeight\n                    ) {\n                        inView = true;\n                    }\n        \n                }\n                if (!inView) return;\n            }\n            if (s.isHorizontal()) {\n                if (kc === 37 || kc === 39) {\n                    if (e.preventDefault) e.preventDefault();\n                    else e.returnValue = false;\n                }\n                if ((kc === 39 && !s.rtl) || (kc === 37 && s.rtl)) s.slideNext();\n                if ((kc === 37 && !s.rtl) || (kc === 39 && s.rtl)) s.slidePrev();\n            }\n            else {\n                if (kc === 38 || kc === 40) {\n                    if (e.preventDefault) e.preventDefault();\n                    else e.returnValue = false;\n                }\n                if (kc === 40) s.slideNext();\n                if (kc === 38) s.slidePrev();\n            }\n        }\n        s.disableKeyboardControl = function () {\n            s.params.keyboardControl = false;\n            $(document).off('keydown', handleKeyboard);\n        };\n        s.enableKeyboardControl = function () {\n            s.params.keyboardControl = true;\n            $(document).on('keydown', handleKeyboard);\n        };\n        \n\n        /*=========================\n          Mousewheel Control\n          ===========================*/\n        s.mousewheel = {\n            event: false,\n            lastScrollTime: (new window.Date()).getTime()\n        };\n        if (s.params.mousewheelControl) {\n            try {\n                new window.WheelEvent('wheel');\n                s.mousewheel.event = 'wheel';\n            } catch (e) {\n                if (window.WheelEvent || (s.container[0] && 'wheel' in s.container[0])) {\n                    s.mousewheel.event = 'wheel';\n                }\n            }\n            if (!s.mousewheel.event && window.WheelEvent) {\n        \n            }\n            if (!s.mousewheel.event && document.onmousewheel !== undefined) {\n                s.mousewheel.event = 'mousewheel';\n            }\n            if (!s.mousewheel.event) {\n                s.mousewheel.event = 'DOMMouseScroll';\n            }\n        }\n        function handleMousewheel(e) {\n            if (e.originalEvent) e = e.originalEvent; //jquery fix\n            var we = s.mousewheel.event;\n            var delta = 0;\n            var rtlFactor = s.rtl ? -1 : 1;\n        \n            //WebKits\n            if (we === 'mousewheel') {\n                if (s.params.mousewheelForceToAxis) {\n                    if (s.isHorizontal()) {\n                        if (Math.abs(e.wheelDeltaX) > Math.abs(e.wheelDeltaY)) delta = e.wheelDeltaX * rtlFactor;\n                        else return;\n                    }\n                    else {\n                        if (Math.abs(e.wheelDeltaY) > Math.abs(e.wheelDeltaX)) delta = e.wheelDeltaY;\n                        else return;\n                    }\n                }\n                else {\n                    delta = Math.abs(e.wheelDeltaX) > Math.abs(e.wheelDeltaY) ? - e.wheelDeltaX * rtlFactor : - e.wheelDeltaY;\n                }\n            }\n            //Old FireFox\n            else if (we === 'DOMMouseScroll') delta = -e.detail;\n            //New FireFox\n            else if (we === 'wheel') {\n                if (s.params.mousewheelForceToAxis) {\n                    if (s.isHorizontal()) {\n                        if (Math.abs(e.deltaX) > Math.abs(e.deltaY)) delta = -e.deltaX * rtlFactor;\n                        else return;\n                    }\n                    else {\n                        if (Math.abs(e.deltaY) > Math.abs(e.deltaX)) delta = -e.deltaY;\n                        else return;\n                    }\n                }\n                else {\n                    delta = Math.abs(e.deltaX) > Math.abs(e.deltaY) ? - e.deltaX * rtlFactor : - e.deltaY;\n                }\n            }\n            if (delta === 0) return;\n        \n            if (s.params.mousewheelInvert) delta = -delta;\n        \n            if (!s.params.freeMode) {\n                if ((new window.Date()).getTime() - s.mousewheel.lastScrollTime > 60) {\n                    if (delta < 0) {\n                        if ((!s.isEnd || s.params.loop) && !s.animating) s.slideNext();\n                        else if (s.params.mousewheelReleaseOnEdges) return true;\n                    }\n                    else {\n                        if ((!s.isBeginning || s.params.loop) && !s.animating) s.slidePrev();\n                        else if (s.params.mousewheelReleaseOnEdges) return true;\n                    }\n                }\n                s.mousewheel.lastScrollTime = (new window.Date()).getTime();\n        \n            }\n            else {\n                //Freemode or scrollContainer:\n                var position = s.getWrapperTranslate() + delta * s.params.mousewheelSensitivity;\n                var wasBeginning = s.isBeginning,\n                    wasEnd = s.isEnd;\n        \n                if (position >= s.minTranslate()) position = s.minTranslate();\n                if (position <= s.maxTranslate()) position = s.maxTranslate();\n        \n                s.setWrapperTransition(0);\n                s.setWrapperTranslate(position);\n                s.updateProgress();\n                s.updateActiveIndex();\n        \n                if (!wasBeginning && s.isBeginning || !wasEnd && s.isEnd) {\n                    s.updateClasses();\n                }\n        \n                if (s.params.freeModeSticky) {\n                    clearTimeout(s.mousewheel.timeout);\n                    s.mousewheel.timeout = setTimeout(function () {\n                        s.slideReset();\n                    }, 300);\n                }\n                else {\n                    if (s.params.lazyLoading && s.lazy) {\n                        s.lazy.load();\n                    }\n                }\n        \n                // Return page scroll on edge positions\n                if (position === 0 || position === s.maxTranslate()) return;\n            }\n            if (s.params.autoplay) s.stopAutoplay();\n        \n            if (e.preventDefault) e.preventDefault();\n            else e.returnValue = false;\n            return false;\n        }\n        s.disableMousewheelControl = function () {\n            if (!s.mousewheel.event) return false;\n            s.container.off(s.mousewheel.event, handleMousewheel);\n            return true;\n        };\n        \n        s.enableMousewheelControl = function () {\n            if (!s.mousewheel.event) return false;\n            s.container.on(s.mousewheel.event, handleMousewheel);\n            return true;\n        };\n        \n\n        /*=========================\n          Parallax\n          ===========================*/\n        function setParallaxTransform(el, progress) {\n            el = $(el);\n            var p, pX, pY;\n            var rtlFactor = s.rtl ? -1 : 1;\n        \n            p = el.attr('data-swiper-parallax') || '0';\n            pX = el.attr('data-swiper-parallax-x');\n            pY = el.attr('data-swiper-parallax-y');\n            if (pX || pY) {\n                pX = pX || '0';\n                pY = pY || '0';\n            }\n            else {\n                if (s.isHorizontal()) {\n                    pX = p;\n                    pY = '0';\n                }\n                else {\n                    pY = p;\n                    pX = '0';\n                }\n            }\n        \n            if ((pX).indexOf('%') >= 0) {\n                pX = parseInt(pX, 10) * progress * rtlFactor + '%';\n            }\n            else {\n                pX = pX * progress * rtlFactor + 'px' ;\n            }\n            if ((pY).indexOf('%') >= 0) {\n                pY = parseInt(pY, 10) * progress + '%';\n            }\n            else {\n                pY = pY * progress + 'px' ;\n            }\n        \n            el.transform('translate3d(' + pX + ', ' + pY + ',0px)');\n        }\n        s.parallax = {\n            setTranslate: function () {\n                s.container.children('[data-swiper-parallax], [data-swiper-parallax-x], [data-swiper-parallax-y]').each(function(){\n                    setParallaxTransform(this, s.progress);\n        \n                });\n                s.slides.each(function () {\n                    var slide = $(this);\n                    slide.find('[data-swiper-parallax], [data-swiper-parallax-x], [data-swiper-parallax-y]').each(function () {\n                        var progress = Math.min(Math.max(slide[0].progress, -1), 1);\n                        setParallaxTransform(this, progress);\n                    });\n                });\n            },\n            setTransition: function (duration) {\n                if (typeof duration === 'undefined') duration = s.params.speed;\n                s.container.find('[data-swiper-parallax], [data-swiper-parallax-x], [data-swiper-parallax-y]').each(function(){\n                    var el = $(this);\n                    var parallaxDuration = parseInt(el.attr('data-swiper-parallax-duration'), 10) || duration;\n                    if (duration === 0) parallaxDuration = 0;\n                    el.transition(parallaxDuration);\n                });\n            }\n        };\n        \n\n        /*=========================\n          Plugins API. Collect all and init all plugins\n          ===========================*/\n        s._plugins = [];\n        for (var plugin in s.plugins) {\n            var p = s.plugins[plugin](s, s.params[plugin]);\n            if (p) s._plugins.push(p);\n        }\n        // Method to call all plugins event/method\n        s.callPlugins = function (eventName) {\n            for (var i = 0; i < s._plugins.length; i++) {\n                if (eventName in s._plugins[i]) {\n                    s._plugins[i][eventName](arguments[1], arguments[2], arguments[3], arguments[4], arguments[5]);\n                }\n            }\n        };\n\n        /*=========================\n          Events/Callbacks/Plugins Emitter\n          ===========================*/\n        function normalizeEventName (eventName) {\n            if (eventName.indexOf('on') !== 0) {\n                if (eventName[0] !== eventName[0].toUpperCase()) {\n                    eventName = 'on' + eventName[0].toUpperCase() + eventName.substring(1);\n                }\n                else {\n                    eventName = 'on' + eventName;\n                }\n            }\n            return eventName;\n        }\n        s.emitterEventListeners = {\n        \n        };\n        s.emit = function (eventName) {\n            // Trigger callbacks\n            if (s.params[eventName]) {\n                s.params[eventName](arguments[1], arguments[2], arguments[3], arguments[4], arguments[5]);\n            }\n            var i;\n            // Trigger events\n            if (s.emitterEventListeners[eventName]) {\n                for (i = 0; i < s.emitterEventListeners[eventName].length; i++) {\n                    s.emitterEventListeners[eventName][i](arguments[1], arguments[2], arguments[3], arguments[4], arguments[5]);\n                }\n            }\n            // Trigger plugins\n            if (s.callPlugins) s.callPlugins(eventName, arguments[1], arguments[2], arguments[3], arguments[4], arguments[5]);\n        };\n        s.on = function (eventName, handler) {\n            eventName = normalizeEventName(eventName);\n            if (!s.emitterEventListeners[eventName]) s.emitterEventListeners[eventName] = [];\n            s.emitterEventListeners[eventName].push(handler);\n            return s;\n        };\n        s.off = function (eventName, handler) {\n            var i;\n            eventName = normalizeEventName(eventName);\n            if (typeof handler === 'undefined') {\n                // Remove all handlers for such event\n                s.emitterEventListeners[eventName] = [];\n                return s;\n            }\n            if (!s.emitterEventListeners[eventName] || s.emitterEventListeners[eventName].length === 0) return;\n            for (i = 0; i < s.emitterEventListeners[eventName].length; i++) {\n                if(s.emitterEventListeners[eventName][i] === handler) s.emitterEventListeners[eventName].splice(i, 1);\n            }\n            return s;\n        };\n        s.once = function (eventName, handler) {\n            eventName = normalizeEventName(eventName);\n            var _handler = function () {\n                handler(arguments[0], arguments[1], arguments[2], arguments[3], arguments[4]);\n                s.off(eventName, _handler);\n            };\n            s.on(eventName, _handler);\n            return s;\n        };\n\n        // Accessibility tools\n        s.a11y = {\n            makeFocusable: function ($el) {\n                $el.attr('tabIndex', '0');\n                return $el;\n            },\n            addRole: function ($el, role) {\n                $el.attr('role', role);\n                return $el;\n            },\n        \n            addLabel: function ($el, label) {\n                $el.attr('aria-label', label);\n                return $el;\n            },\n        \n            disable: function ($el) {\n                $el.attr('aria-disabled', true);\n                return $el;\n            },\n        \n            enable: function ($el) {\n                $el.attr('aria-disabled', false);\n                return $el;\n            },\n        \n            onEnterKey: function (event) {\n                if (event.keyCode !== 13) return;\n                if ($(event.target).is(s.params.nextButton)) {\n                    s.onClickNext(event);\n                    if (s.isEnd) {\n                        s.a11y.notify(s.params.lastSlideMessage);\n                    }\n                    else {\n                        s.a11y.notify(s.params.nextSlideMessage);\n                    }\n                }\n                else if ($(event.target).is(s.params.prevButton)) {\n                    s.onClickPrev(event);\n                    if (s.isBeginning) {\n                        s.a11y.notify(s.params.firstSlideMessage);\n                    }\n                    else {\n                        s.a11y.notify(s.params.prevSlideMessage);\n                    }\n                }\n                if ($(event.target).is('.' + s.params.bulletClass)) {\n                    $(event.target)[0].click();\n                }\n            },\n        \n            liveRegion: $('<span class=\"swiper-notification\" aria-live=\"assertive\" aria-atomic=\"true\"></span>'),\n        \n            notify: function (message) {\n                var notification = s.a11y.liveRegion;\n                if (notification.length === 0) return;\n                notification.html('');\n                notification.html(message);\n            },\n            init: function () {\n                // Setup accessibility\n                if (s.params.nextButton && s.nextButton && s.nextButton.length > 0) {\n                    s.a11y.makeFocusable(s.nextButton);\n                    s.a11y.addRole(s.nextButton, 'button');\n                    s.a11y.addLabel(s.nextButton, s.params.nextSlideMessage);\n                }\n                if (s.params.prevButton && s.prevButton && s.prevButton.length > 0) {\n                    s.a11y.makeFocusable(s.prevButton);\n                    s.a11y.addRole(s.prevButton, 'button');\n                    s.a11y.addLabel(s.prevButton, s.params.prevSlideMessage);\n                }\n        \n                $(s.container).append(s.a11y.liveRegion);\n            },\n            initPagination: function () {\n                if (s.params.pagination && s.params.paginationClickable && s.bullets && s.bullets.length) {\n                    s.bullets.each(function () {\n                        var bullet = $(this);\n                        s.a11y.makeFocusable(bullet);\n                        s.a11y.addRole(bullet, 'button');\n                        s.a11y.addLabel(bullet, s.params.paginationBulletMessage.replace(/{{index}}/, bullet.index() + 1));\n                    });\n                }\n            },\n            destroy: function () {\n                if (s.a11y.liveRegion && s.a11y.liveRegion.length > 0) s.a11y.liveRegion.remove();\n            }\n        };\n        \n\n        /*=========================\n          Init/Destroy\n          ===========================*/\n        s.init = function () {\n            if (s.params.loop) s.createLoop();\n            s.updateContainerSize();\n            s.updateSlidesSize();\n            s.updatePagination();\n            if (s.params.scrollbar && s.scrollbar) {\n                s.scrollbar.set();\n                if (s.params.scrollbarDraggable) {\n                    s.scrollbar.enableDraggable();\n                }\n            }\n            if (s.params.effect !== 'slide' && s.effects[s.params.effect]) {\n                if (!s.params.loop) s.updateProgress();\n                s.effects[s.params.effect].setTranslate();\n            }\n            if (s.params.loop) {\n                s.slideTo(s.params.initialSlide + s.loopedSlides, 0, s.params.runCallbacksOnInit);\n            }\n            else {\n                s.slideTo(s.params.initialSlide, 0, s.params.runCallbacksOnInit);\n                if (s.params.initialSlide === 0) {\n                    if (s.parallax && s.params.parallax) s.parallax.setTranslate();\n                    if (s.lazy && s.params.lazyLoading) {\n                        s.lazy.load();\n                        s.lazy.initialImageLoaded = true;\n                    }\n                }\n            }\n            s.attachEvents();\n            if (s.params.observer && s.support.observer) {\n                s.initObservers();\n            }\n            if (s.params.preloadImages && !s.params.lazyLoading) {\n                s.preloadImages();\n            }\n            if (s.params.autoplay) {\n                s.startAutoplay();\n            }\n            if (s.params.keyboardControl) {\n                if (s.enableKeyboardControl) s.enableKeyboardControl();\n            }\n            if (s.params.mousewheelControl) {\n                if (s.enableMousewheelControl) s.enableMousewheelControl();\n            }\n            if (s.params.hashnav) {\n                if (s.hashnav) s.hashnav.init();\n            }\n            if (s.params.a11y && s.a11y) s.a11y.init();\n            s.emit('onInit', s);\n        };\n        \n        // Cleanup dynamic styles\n        s.cleanupStyles = function () {\n            // Container\n            s.container.removeClass(s.classNames.join(' ')).removeAttr('style');\n        \n            // Wrapper\n            s.wrapper.removeAttr('style');\n        \n            // Slides\n            if (s.slides && s.slides.length) {\n                s.slides\n                    .removeClass([\n                      s.params.slideVisibleClass,\n                      s.params.slideActiveClass,\n                      s.params.slideNextClass,\n                      s.params.slidePrevClass\n                    ].join(' '))\n                    .removeAttr('style')\n                    .removeAttr('data-swiper-column')\n                    .removeAttr('data-swiper-row');\n            }\n        \n            // Pagination/Bullets\n            if (s.paginationContainer && s.paginationContainer.length) {\n                s.paginationContainer.removeClass(s.params.paginationHiddenClass);\n            }\n            if (s.bullets && s.bullets.length) {\n                s.bullets.removeClass(s.params.bulletActiveClass);\n            }\n        \n            // Buttons\n            if (s.params.prevButton) $(s.params.prevButton).removeClass(s.params.buttonDisabledClass);\n            if (s.params.nextButton) $(s.params.nextButton).removeClass(s.params.buttonDisabledClass);\n        \n            // Scrollbar\n            if (s.params.scrollbar && s.scrollbar) {\n                if (s.scrollbar.track && s.scrollbar.track.length) s.scrollbar.track.removeAttr('style');\n                if (s.scrollbar.drag && s.scrollbar.drag.length) s.scrollbar.drag.removeAttr('style');\n            }\n        };\n        \n        // Destroy\n        s.destroy = function (deleteInstance, cleanupStyles) {\n            // Detach evebts\n            s.detachEvents();\n            // Stop autoplay\n            s.stopAutoplay();\n            // Disable draggable\n            if (s.params.scrollbar && s.scrollbar) {\n                if (s.params.scrollbarDraggable) {\n                    s.scrollbar.disableDraggable();\n                }\n            }\n            // Destroy loop\n            if (s.params.loop) {\n                s.destroyLoop();\n            }\n            // Cleanup styles\n            if (cleanupStyles) {\n                s.cleanupStyles();\n            }\n            // Disconnect observer\n            s.disconnectObservers();\n            // Disable keyboard/mousewheel\n            if (s.params.keyboardControl) {\n                if (s.disableKeyboardControl) s.disableKeyboardControl();\n            }\n            if (s.params.mousewheelControl) {\n                if (s.disableMousewheelControl) s.disableMousewheelControl();\n            }\n            // Disable a11y\n            if (s.params.a11y && s.a11y) s.a11y.destroy();\n            // Destroy callback\n            s.emit('onDestroy');\n            // Delete instance\n            if (deleteInstance !== false) s = null;\n        };\n        \n        s.init();\n        \n\n    \n        // Return swiper instance\n        return s;\n    };\n    \n\n    /*==================================================\n        Prototype\n    ====================================================*/\n    Swiper.prototype = {\n        isSafari: (function () {\n            var ua = navigator.userAgent.toLowerCase();\n            return (ua.indexOf('safari') >= 0 && ua.indexOf('chrome') < 0 && ua.indexOf('android') < 0);\n        })(),\n        isUiWebView: /(iPhone|iPod|iPad).*AppleWebKit(?!.*Safari)/i.test(navigator.userAgent),\n        isArray: function (arr) {\n            return Object.prototype.toString.apply(arr) === '[object Array]';\n        },\n        /*==================================================\n        Browser\n        ====================================================*/\n        browser: {\n            ie: window.navigator.pointerEnabled || window.navigator.msPointerEnabled,\n            ieTouch: (window.navigator.msPointerEnabled && window.navigator.msMaxTouchPoints > 1) || (window.navigator.pointerEnabled && window.navigator.maxTouchPoints > 1)\n        },\n        /*==================================================\n        Devices\n        ====================================================*/\n        device: (function () {\n            var ua = navigator.userAgent;\n            var android = ua.match(/(Android);?[\\s\\/]+([\\d.]+)?/);\n            var ipad = ua.match(/(iPad).*OS\\s([\\d_]+)/);\n            var ipod = ua.match(/(iPod)(.*OS\\s([\\d_]+))?/);\n            var iphone = !ipad && ua.match(/(iPhone\\sOS)\\s([\\d_]+)/);\n            return {\n                ios: ipad || iphone || ipod,\n                android: android\n            };\n        })(),\n        /*==================================================\n        Feature Detection\n        ====================================================*/\n        support: {\n            touch : (window.Modernizr && Modernizr.touch === true) || (function () {\n                return !!(('ontouchstart' in window) || window.DocumentTouch && document instanceof DocumentTouch);\n            })(),\n    \n            transforms3d : (window.Modernizr && Modernizr.csstransforms3d === true) || (function () {\n                var div = document.createElement('div').style;\n                return ('webkitPerspective' in div || 'MozPerspective' in div || 'OPerspective' in div || 'MsPerspective' in div || 'perspective' in div);\n            })(),\n    \n            flexbox: (function () {\n                var div = document.createElement('div').style;\n                var styles = ('alignItems webkitAlignItems webkitBoxAlign msFlexAlign mozBoxAlign webkitFlexDirection msFlexDirection mozBoxDirection mozBoxOrient webkitBoxDirection webkitBoxOrient').split(' ');\n                for (var i = 0; i < styles.length; i++) {\n                    if (styles[i] in div) return true;\n                }\n            })(),\n    \n            observer: (function () {\n                return ('MutationObserver' in window || 'WebkitMutationObserver' in window);\n            })()\n        },\n        /*==================================================\n        Plugins\n        ====================================================*/\n        plugins: {}\n    };\n    \n\n    /*===========================\n     Get Dom libraries\n     ===========================*/\n    var swiperDomPlugins = ['jQuery', 'Zepto', 'Dom7'];\n    for (var i = 0; i < swiperDomPlugins.length; i++) {\n    \tif (window[swiperDomPlugins[i]]) {\n    \t\taddLibraryPlugin(window[swiperDomPlugins[i]]);\n    \t}\n    }\n    // Required DOM Plugins\n    var domLib;\n    if (typeof Dom7 === 'undefined') {\n    \tdomLib = window.Dom7 || window.Zepto || window.jQuery;\n    }\n    else {\n    \tdomLib = Dom7;\n    }\n\n    /*===========================\n    Add .swiper plugin from Dom libraries\n    ===========================*/\n    function addLibraryPlugin(lib) {\n        lib.fn.swiper = function (params) {\n            var firstInstance;\n            lib(this).each(function () {\n                var s = new Swiper(this, params);\n                if (!firstInstance) firstInstance = s;\n            });\n            return firstInstance;\n        };\n    }\n    \n    if (domLib) {\n        if (!('transitionEnd' in domLib.fn)) {\n            domLib.fn.transitionEnd = function (callback) {\n                var events = ['webkitTransitionEnd', 'transitionend', 'oTransitionEnd', 'MSTransitionEnd', 'msTransitionEnd'],\n                    i, j, dom = this;\n                function fireCallBack(e) {\n                    /*jshint validthis:true */\n                    if (e.target !== this) return;\n                    callback.call(this, e);\n                    for (i = 0; i < events.length; i++) {\n                        dom.off(events[i], fireCallBack);\n                    }\n                }\n                if (callback) {\n                    for (i = 0; i < events.length; i++) {\n                        dom.on(events[i], fireCallBack);\n                    }\n                }\n                return this;\n            };\n        }\n        if (!('transform' in domLib.fn)) {\n            domLib.fn.transform = function (transform) {\n                for (var i = 0; i < this.length; i++) {\n                    var elStyle = this[i].style;\n                    elStyle.webkitTransform = elStyle.MsTransform = elStyle.msTransform = elStyle.MozTransform = elStyle.OTransform = elStyle.transform = transform;\n                }\n                return this;\n            };\n        }\n        if (!('transition' in domLib.fn)) {\n            domLib.fn.transition = function (duration) {\n                if (typeof duration !== 'string') {\n                    duration = duration + 'ms';\n                }\n                for (var i = 0; i < this.length; i++) {\n                    var elStyle = this[i].style;\n                    elStyle.webkitTransitionDuration = elStyle.MsTransitionDuration = elStyle.msTransitionDuration = elStyle.MozTransitionDuration = elStyle.OTransitionDuration = elStyle.transitionDuration = duration;\n                }\n                return this;\n            };\n        }\n    }\n\n    window.Swiper = Swiper;\n})();\n/*===========================\nSwiper AMD Export\n===========================*/\nif (typeof(module) !== 'undefined')\n{\n    module.exports = window.Swiper;\n}\nelse if (typeof define === 'function' && define.amd) {\n    define([], function () {\n        'use strict';\n        return window.Swiper;\n    });\n}\n//# sourceMappingURL=maps/swiper.jquery.js.map\n"
  },
  {
    "path": "app_backend/static/plugin/Swiper-3.3.1/dist/js/swiper.jquery.umd.js",
    "content": "/**\n * Swiper 3.3.1\n * Most modern mobile touch slider and framework with hardware accelerated transitions\n * \n * http://www.idangero.us/swiper/\n * \n * Copyright 2016, Vladimir Kharlampidi\n * The iDangero.us\n * http://www.idangero.us/\n * \n * Licensed under MIT\n * \n * Released on: February 7, 2016\n */\n(function (root, factory) {\n\t'use strict';\n\n\tif (typeof define === 'function' && define.amd) {\n\t\t// AMD. Register as an anonymous module.\n\t\tdefine(['jquery'], factory);\n\t} else if (typeof exports === 'object') {\n\t\t// Node. Does not work with strict CommonJS, but\n\t\t// only CommonJS-like environments that support module.exports,\n\t\t// like Node.\n\t\tmodule.exports = factory(require('jquery'));\n\t} else {\n\t\t// Browser globals (root is window)\n\t\troot.Swiper = factory(root.jQuery);\n\t}\n}(this, function ($) {\n\t'use strict';\n\n    /*===========================\n    Swiper\n    ===========================*/\n    var Swiper = function (container, params) {\n        if (!(this instanceof Swiper)) return new Swiper(container, params);\n\n        var defaults = {\n            direction: 'horizontal',\n            touchEventsTarget: 'container',\n            initialSlide: 0,\n            speed: 300,\n            // autoplay\n            autoplay: false,\n            autoplayDisableOnInteraction: true,\n            autoplayStopOnLast: false,\n            // To support iOS's swipe-to-go-back gesture (when being used in-app, with UIWebView).\n            iOSEdgeSwipeDetection: false,\n            iOSEdgeSwipeThreshold: 20,\n            // Free mode\n            freeMode: false,\n            freeModeMomentum: true,\n            freeModeMomentumRatio: 1,\n            freeModeMomentumBounce: true,\n            freeModeMomentumBounceRatio: 1,\n            freeModeSticky: false,\n            freeModeMinimumVelocity: 0.02,\n            // Autoheight\n            autoHeight: false,\n            // Set wrapper width\n            setWrapperSize: false,\n            // Virtual Translate\n            virtualTranslate: false,\n            // Effects\n            effect: 'slide', // 'slide' or 'fade' or 'cube' or 'coverflow' or 'flip'\n            coverflow: {\n                rotate: 50,\n                stretch: 0,\n                depth: 100,\n                modifier: 1,\n                slideShadows : true\n            },\n            flip: {\n                slideShadows : true,\n                limitRotation: true\n            },\n            cube: {\n                slideShadows: true,\n                shadow: true,\n                shadowOffset: 20,\n                shadowScale: 0.94\n            },\n            fade: {\n                crossFade: false\n            },\n            // Parallax\n            parallax: false,\n            // Scrollbar\n            scrollbar: null,\n            scrollbarHide: true,\n            scrollbarDraggable: false,\n            scrollbarSnapOnRelease: false,\n            // Keyboard Mousewheel\n            keyboardControl: false,\n            mousewheelControl: false,\n            mousewheelReleaseOnEdges: false,\n            mousewheelInvert: false,\n            mousewheelForceToAxis: false,\n            mousewheelSensitivity: 1,\n            // Hash Navigation\n            hashnav: false,\n            // Breakpoints\n            breakpoints: undefined,\n            // Slides grid\n            spaceBetween: 0,\n            slidesPerView: 1,\n            slidesPerColumn: 1,\n            slidesPerColumnFill: 'column',\n            slidesPerGroup: 1,\n            centeredSlides: false,\n            slidesOffsetBefore: 0, // in px\n            slidesOffsetAfter: 0, // in px\n            // Round length\n            roundLengths: false,\n            // Touches\n            touchRatio: 1,\n            touchAngle: 45,\n            simulateTouch: true,\n            shortSwipes: true,\n            longSwipes: true,\n            longSwipesRatio: 0.5,\n            longSwipesMs: 300,\n            followFinger: true,\n            onlyExternal: false,\n            threshold: 0,\n            touchMoveStopPropagation: true,\n            // Unique Navigation Elements\n            uniqueNavElements: true,\n            // Pagination\n            pagination: null,\n            paginationElement: 'span',\n            paginationClickable: false,\n            paginationHide: false,\n            paginationBulletRender: null,\n            paginationProgressRender: null,\n            paginationFractionRender: null,\n            paginationCustomRender: null,\n            paginationType: 'bullets', // 'bullets' or 'progress' or 'fraction' or 'custom'\n            // Resistance\n            resistance: true,\n            resistanceRatio: 0.85,\n            // Next/prev buttons\n            nextButton: null,\n            prevButton: null,\n            // Progress\n            watchSlidesProgress: false,\n            watchSlidesVisibility: false,\n            // Cursor\n            grabCursor: false,\n            // Clicks\n            preventClicks: true,\n            preventClicksPropagation: true,\n            slideToClickedSlide: false,\n            // Lazy Loading\n            lazyLoading: false,\n            lazyLoadingInPrevNext: false,\n            lazyLoadingInPrevNextAmount: 1,\n            lazyLoadingOnTransitionStart: false,\n            // Images\n            preloadImages: true,\n            updateOnImagesReady: true,\n            // loop\n            loop: false,\n            loopAdditionalSlides: 0,\n            loopedSlides: null,\n            // Control\n            control: undefined,\n            controlInverse: false,\n            controlBy: 'slide', //or 'container'\n            // Swiping/no swiping\n            allowSwipeToPrev: true,\n            allowSwipeToNext: true,\n            swipeHandler: null, //'.swipe-handler',\n            noSwiping: true,\n            noSwipingClass: 'swiper-no-swiping',\n            // NS\n            slideClass: 'swiper-slide',\n            slideActiveClass: 'swiper-slide-active',\n            slideVisibleClass: 'swiper-slide-visible',\n            slideDuplicateClass: 'swiper-slide-duplicate',\n            slideNextClass: 'swiper-slide-next',\n            slidePrevClass: 'swiper-slide-prev',\n            wrapperClass: 'swiper-wrapper',\n            bulletClass: 'swiper-pagination-bullet',\n            bulletActiveClass: 'swiper-pagination-bullet-active',\n            buttonDisabledClass: 'swiper-button-disabled',\n            paginationCurrentClass: 'swiper-pagination-current',\n            paginationTotalClass: 'swiper-pagination-total',\n            paginationHiddenClass: 'swiper-pagination-hidden',\n            paginationProgressbarClass: 'swiper-pagination-progressbar',\n            // Observer\n            observer: false,\n            observeParents: false,\n            // Accessibility\n            a11y: false,\n            prevSlideMessage: 'Previous slide',\n            nextSlideMessage: 'Next slide',\n            firstSlideMessage: 'This is the first slide',\n            lastSlideMessage: 'This is the last slide',\n            paginationBulletMessage: 'Go to slide {{index}}',\n            // Callbacks\n            runCallbacksOnInit: true\n            /*\n            Callbacks:\n            onInit: function (swiper)\n            onDestroy: function (swiper)\n            onClick: function (swiper, e)\n            onTap: function (swiper, e)\n            onDoubleTap: function (swiper, e)\n            onSliderMove: function (swiper, e)\n            onSlideChangeStart: function (swiper)\n            onSlideChangeEnd: function (swiper)\n            onTransitionStart: function (swiper)\n            onTransitionEnd: function (swiper)\n            onImagesReady: function (swiper)\n            onProgress: function (swiper, progress)\n            onTouchStart: function (swiper, e)\n            onTouchMove: function (swiper, e)\n            onTouchMoveOpposite: function (swiper, e)\n            onTouchEnd: function (swiper, e)\n            onReachBeginning: function (swiper)\n            onReachEnd: function (swiper)\n            onSetTransition: function (swiper, duration)\n            onSetTranslate: function (swiper, translate)\n            onAutoplayStart: function (swiper)\n            onAutoplayStop: function (swiper),\n            onLazyImageLoad: function (swiper, slide, image)\n            onLazyImageReady: function (swiper, slide, image)\n            */\n        \n        };\n        var initialVirtualTranslate = params && params.virtualTranslate;\n        \n        params = params || {};\n        var originalParams = {};\n        for (var param in params) {\n            if (typeof params[param] === 'object' && params[param] !== null && !(params[param].nodeType || params[param] === window || params[param] === document || (typeof Dom7 !== 'undefined' && params[param] instanceof Dom7) || (typeof jQuery !== 'undefined' && params[param] instanceof jQuery))) {\n                originalParams[param] = {};\n                for (var deepParam in params[param]) {\n                    originalParams[param][deepParam] = params[param][deepParam];\n                }\n            }\n            else {\n                originalParams[param] = params[param];\n            }\n        }\n        for (var def in defaults) {\n            if (typeof params[def] === 'undefined') {\n                params[def] = defaults[def];\n            }\n            else if (typeof params[def] === 'object') {\n                for (var deepDef in defaults[def]) {\n                    if (typeof params[def][deepDef] === 'undefined') {\n                        params[def][deepDef] = defaults[def][deepDef];\n                    }\n                }\n            }\n        }\n        \n        // Swiper\n        var s = this;\n        \n        // Params\n        s.params = params;\n        s.originalParams = originalParams;\n        \n        // Classname\n        s.classNames = [];\n        /*=========================\n          Dom Library and plugins\n          ===========================*/\n        if (typeof $ !== 'undefined' && typeof Dom7 !== 'undefined'){\n            $ = Dom7;\n        }\n        if (typeof $ === 'undefined') {\n            if (typeof Dom7 === 'undefined') {\n                $ = window.Dom7 || window.Zepto || window.jQuery;\n            }\n            else {\n                $ = Dom7;\n            }\n            if (!$) return;\n        }\n        // Export it to Swiper instance\n        s.$ = $;\n        \n        /*=========================\n          Breakpoints\n          ===========================*/\n        s.currentBreakpoint = undefined;\n        s.getActiveBreakpoint = function () {\n            //Get breakpoint for window width\n            if (!s.params.breakpoints) return false;\n            var breakpoint = false;\n            var points = [], point;\n            for ( point in s.params.breakpoints ) {\n                if (s.params.breakpoints.hasOwnProperty(point)) {\n                    points.push(point);\n                }\n            }\n            points.sort(function (a, b) {\n                return parseInt(a, 10) > parseInt(b, 10);\n            });\n            for (var i = 0; i < points.length; i++) {\n                point = points[i];\n                if (point >= window.innerWidth && !breakpoint) {\n                    breakpoint = point;\n                }\n            }\n            return breakpoint || 'max';\n        };\n        s.setBreakpoint = function () {\n            //Set breakpoint for window width and update parameters\n            var breakpoint = s.getActiveBreakpoint();\n            if (breakpoint && s.currentBreakpoint !== breakpoint) {\n                var breakPointsParams = breakpoint in s.params.breakpoints ? s.params.breakpoints[breakpoint] : s.originalParams;\n                var needsReLoop = s.params.loop && (breakPointsParams.slidesPerView !== s.params.slidesPerView);\n                for ( var param in breakPointsParams ) {\n                    s.params[param] = breakPointsParams[param];\n                }\n                s.currentBreakpoint = breakpoint;\n                if(needsReLoop && s.destroyLoop) {\n                    s.reLoop(true);\n                }\n            }\n        };\n        // Set breakpoint on load\n        if (s.params.breakpoints) {\n            s.setBreakpoint();\n        }\n        \n        /*=========================\n          Preparation - Define Container, Wrapper and Pagination\n          ===========================*/\n        s.container = $(container);\n        if (s.container.length === 0) return;\n        if (s.container.length > 1) {\n            var swipers = [];\n            s.container.each(function () {\n                var container = this;\n                swipers.push(new Swiper(this, params));\n            });\n            return swipers;\n        }\n        \n        // Save instance in container HTML Element and in data\n        s.container[0].swiper = s;\n        s.container.data('swiper', s);\n        \n        s.classNames.push('swiper-container-' + s.params.direction);\n        \n        if (s.params.freeMode) {\n            s.classNames.push('swiper-container-free-mode');\n        }\n        if (!s.support.flexbox) {\n            s.classNames.push('swiper-container-no-flexbox');\n            s.params.slidesPerColumn = 1;\n        }\n        if (s.params.autoHeight) {\n            s.classNames.push('swiper-container-autoheight');\n        }\n        // Enable slides progress when required\n        if (s.params.parallax || s.params.watchSlidesVisibility) {\n            s.params.watchSlidesProgress = true;\n        }\n        // Coverflow / 3D\n        if (['cube', 'coverflow', 'flip'].indexOf(s.params.effect) >= 0) {\n            if (s.support.transforms3d) {\n                s.params.watchSlidesProgress = true;\n                s.classNames.push('swiper-container-3d');\n            }\n            else {\n                s.params.effect = 'slide';\n            }\n        }\n        if (s.params.effect !== 'slide') {\n            s.classNames.push('swiper-container-' + s.params.effect);\n        }\n        if (s.params.effect === 'cube') {\n            s.params.resistanceRatio = 0;\n            s.params.slidesPerView = 1;\n            s.params.slidesPerColumn = 1;\n            s.params.slidesPerGroup = 1;\n            s.params.centeredSlides = false;\n            s.params.spaceBetween = 0;\n            s.params.virtualTranslate = true;\n            s.params.setWrapperSize = false;\n        }\n        if (s.params.effect === 'fade' || s.params.effect === 'flip') {\n            s.params.slidesPerView = 1;\n            s.params.slidesPerColumn = 1;\n            s.params.slidesPerGroup = 1;\n            s.params.watchSlidesProgress = true;\n            s.params.spaceBetween = 0;\n            s.params.setWrapperSize = false;\n            if (typeof initialVirtualTranslate === 'undefined') {\n                s.params.virtualTranslate = true;\n            }\n        }\n        \n        // Grab Cursor\n        if (s.params.grabCursor && s.support.touch) {\n            s.params.grabCursor = false;\n        }\n        \n        // Wrapper\n        s.wrapper = s.container.children('.' + s.params.wrapperClass);\n        \n        // Pagination\n        if (s.params.pagination) {\n            s.paginationContainer = $(s.params.pagination);\n            if (s.params.uniqueNavElements && typeof s.params.pagination === 'string' && s.paginationContainer.length > 1 && s.container.find(s.params.pagination).length === 1) {\n                s.paginationContainer = s.container.find(s.params.pagination);\n            }\n        \n            if (s.params.paginationType === 'bullets' && s.params.paginationClickable) {\n                s.paginationContainer.addClass('swiper-pagination-clickable');\n            }\n            else {\n                s.params.paginationClickable = false;\n            }\n            s.paginationContainer.addClass('swiper-pagination-' + s.params.paginationType);\n        }\n        // Next/Prev Buttons\n        if (s.params.nextButton || s.params.prevButton) {\n            if (s.params.nextButton) {\n                s.nextButton = $(s.params.nextButton);\n                if (s.params.uniqueNavElements && typeof s.params.nextButton === 'string' && s.nextButton.length > 1 && s.container.find(s.params.nextButton).length === 1) {\n                    s.nextButton = s.container.find(s.params.nextButton);\n                }\n            }\n            if (s.params.prevButton) {\n                s.prevButton = $(s.params.prevButton);\n                if (s.params.uniqueNavElements && typeof s.params.prevButton === 'string' && s.prevButton.length > 1 && s.container.find(s.params.prevButton).length === 1) {\n                    s.prevButton = s.container.find(s.params.prevButton);\n                }\n            }\n        }\n        \n        // Is Horizontal\n        s.isHorizontal = function () {\n            return s.params.direction === 'horizontal';\n        };\n        // s.isH = isH;\n        \n        // RTL\n        s.rtl = s.isHorizontal() && (s.container[0].dir.toLowerCase() === 'rtl' || s.container.css('direction') === 'rtl');\n        if (s.rtl) {\n            s.classNames.push('swiper-container-rtl');\n        }\n        \n        // Wrong RTL support\n        if (s.rtl) {\n            s.wrongRTL = s.wrapper.css('display') === '-webkit-box';\n        }\n        \n        // Columns\n        if (s.params.slidesPerColumn > 1) {\n            s.classNames.push('swiper-container-multirow');\n        }\n        \n        // Check for Android\n        if (s.device.android) {\n            s.classNames.push('swiper-container-android');\n        }\n        \n        // Add classes\n        s.container.addClass(s.classNames.join(' '));\n        \n        // Translate\n        s.translate = 0;\n        \n        // Progress\n        s.progress = 0;\n        \n        // Velocity\n        s.velocity = 0;\n        \n        /*=========================\n          Locks, unlocks\n          ===========================*/\n        s.lockSwipeToNext = function () {\n            s.params.allowSwipeToNext = false;\n        };\n        s.lockSwipeToPrev = function () {\n            s.params.allowSwipeToPrev = false;\n        };\n        s.lockSwipes = function () {\n            s.params.allowSwipeToNext = s.params.allowSwipeToPrev = false;\n        };\n        s.unlockSwipeToNext = function () {\n            s.params.allowSwipeToNext = true;\n        };\n        s.unlockSwipeToPrev = function () {\n            s.params.allowSwipeToPrev = true;\n        };\n        s.unlockSwipes = function () {\n            s.params.allowSwipeToNext = s.params.allowSwipeToPrev = true;\n        };\n        \n        /*=========================\n          Round helper\n          ===========================*/\n        function round(a) {\n            return Math.floor(a);\n        }\n        /*=========================\n          Set grab cursor\n          ===========================*/\n        if (s.params.grabCursor) {\n            s.container[0].style.cursor = 'move';\n            s.container[0].style.cursor = '-webkit-grab';\n            s.container[0].style.cursor = '-moz-grab';\n            s.container[0].style.cursor = 'grab';\n        }\n        /*=========================\n          Update on Images Ready\n          ===========================*/\n        s.imagesToLoad = [];\n        s.imagesLoaded = 0;\n        \n        s.loadImage = function (imgElement, src, srcset, checkForComplete, callback) {\n            var image;\n            function onReady () {\n                if (callback) callback();\n            }\n            if (!imgElement.complete || !checkForComplete) {\n                if (src) {\n                    image = new window.Image();\n                    image.onload = onReady;\n                    image.onerror = onReady;\n                    if (srcset) {\n                        image.srcset = srcset;\n                    }\n                    if (src) {\n                        image.src = src;\n                    }\n                } else {\n                    onReady();\n                }\n        \n            } else {//image already loaded...\n                onReady();\n            }\n        };\n        s.preloadImages = function () {\n            s.imagesToLoad = s.container.find('img');\n            function _onReady() {\n                if (typeof s === 'undefined' || s === null) return;\n                if (s.imagesLoaded !== undefined) s.imagesLoaded++;\n                if (s.imagesLoaded === s.imagesToLoad.length) {\n                    if (s.params.updateOnImagesReady) s.update();\n                    s.emit('onImagesReady', s);\n                }\n            }\n            for (var i = 0; i < s.imagesToLoad.length; i++) {\n                s.loadImage(s.imagesToLoad[i], (s.imagesToLoad[i].currentSrc || s.imagesToLoad[i].getAttribute('src')), (s.imagesToLoad[i].srcset || s.imagesToLoad[i].getAttribute('srcset')), true, _onReady);\n            }\n        };\n        \n        /*=========================\n          Autoplay\n          ===========================*/\n        s.autoplayTimeoutId = undefined;\n        s.autoplaying = false;\n        s.autoplayPaused = false;\n        function autoplay() {\n            s.autoplayTimeoutId = setTimeout(function () {\n                if (s.params.loop) {\n                    s.fixLoop();\n                    s._slideNext();\n                    s.emit('onAutoplay', s);\n                }\n                else {\n                    if (!s.isEnd) {\n                        s._slideNext();\n                        s.emit('onAutoplay', s);\n                    }\n                    else {\n                        if (!params.autoplayStopOnLast) {\n                            s._slideTo(0);\n                            s.emit('onAutoplay', s);\n                        }\n                        else {\n                            s.stopAutoplay();\n                        }\n                    }\n                }\n            }, s.params.autoplay);\n        }\n        s.startAutoplay = function () {\n            if (typeof s.autoplayTimeoutId !== 'undefined') return false;\n            if (!s.params.autoplay) return false;\n            if (s.autoplaying) return false;\n            s.autoplaying = true;\n            s.emit('onAutoplayStart', s);\n            autoplay();\n        };\n        s.stopAutoplay = function (internal) {\n            if (!s.autoplayTimeoutId) return;\n            if (s.autoplayTimeoutId) clearTimeout(s.autoplayTimeoutId);\n            s.autoplaying = false;\n            s.autoplayTimeoutId = undefined;\n            s.emit('onAutoplayStop', s);\n        };\n        s.pauseAutoplay = function (speed) {\n            if (s.autoplayPaused) return;\n            if (s.autoplayTimeoutId) clearTimeout(s.autoplayTimeoutId);\n            s.autoplayPaused = true;\n            if (speed === 0) {\n                s.autoplayPaused = false;\n                autoplay();\n            }\n            else {\n                s.wrapper.transitionEnd(function () {\n                    if (!s) return;\n                    s.autoplayPaused = false;\n                    if (!s.autoplaying) {\n                        s.stopAutoplay();\n                    }\n                    else {\n                        autoplay();\n                    }\n                });\n            }\n        };\n        /*=========================\n          Min/Max Translate\n          ===========================*/\n        s.minTranslate = function () {\n            return (-s.snapGrid[0]);\n        };\n        s.maxTranslate = function () {\n            return (-s.snapGrid[s.snapGrid.length - 1]);\n        };\n        /*=========================\n          Slider/slides sizes\n          ===========================*/\n        s.updateAutoHeight = function () {\n            // Update Height\n            var slide = s.slides.eq(s.activeIndex)[0];\n            if (typeof slide !== 'undefined') {\n                var newHeight = slide.offsetHeight;\n                if (newHeight) s.wrapper.css('height', newHeight + 'px');\n            }\n        };\n        s.updateContainerSize = function () {\n            var width, height;\n            if (typeof s.params.width !== 'undefined') {\n                width = s.params.width;\n            }\n            else {\n                width = s.container[0].clientWidth;\n            }\n            if (typeof s.params.height !== 'undefined') {\n                height = s.params.height;\n            }\n            else {\n                height = s.container[0].clientHeight;\n            }\n            if (width === 0 && s.isHorizontal() || height === 0 && !s.isHorizontal()) {\n                return;\n            }\n        \n            //Subtract paddings\n            width = width - parseInt(s.container.css('padding-left'), 10) - parseInt(s.container.css('padding-right'), 10);\n            height = height - parseInt(s.container.css('padding-top'), 10) - parseInt(s.container.css('padding-bottom'), 10);\n        \n            // Store values\n            s.width = width;\n            s.height = height;\n            s.size = s.isHorizontal() ? s.width : s.height;\n        };\n        \n        s.updateSlidesSize = function () {\n            s.slides = s.wrapper.children('.' + s.params.slideClass);\n            s.snapGrid = [];\n            s.slidesGrid = [];\n            s.slidesSizesGrid = [];\n        \n            var spaceBetween = s.params.spaceBetween,\n                slidePosition = -s.params.slidesOffsetBefore,\n                i,\n                prevSlideSize = 0,\n                index = 0;\n            if (typeof s.size === 'undefined') return;\n            if (typeof spaceBetween === 'string' && spaceBetween.indexOf('%') >= 0) {\n                spaceBetween = parseFloat(spaceBetween.replace('%', '')) / 100 * s.size;\n            }\n        \n            s.virtualSize = -spaceBetween;\n            // reset margins\n            if (s.rtl) s.slides.css({marginLeft: '', marginTop: ''});\n            else s.slides.css({marginRight: '', marginBottom: ''});\n        \n            var slidesNumberEvenToRows;\n            if (s.params.slidesPerColumn > 1) {\n                if (Math.floor(s.slides.length / s.params.slidesPerColumn) === s.slides.length / s.params.slidesPerColumn) {\n                    slidesNumberEvenToRows = s.slides.length;\n                }\n                else {\n                    slidesNumberEvenToRows = Math.ceil(s.slides.length / s.params.slidesPerColumn) * s.params.slidesPerColumn;\n                }\n                if (s.params.slidesPerView !== 'auto' && s.params.slidesPerColumnFill === 'row') {\n                    slidesNumberEvenToRows = Math.max(slidesNumberEvenToRows, s.params.slidesPerView * s.params.slidesPerColumn);\n                }\n            }\n        \n            // Calc slides\n            var slideSize;\n            var slidesPerColumn = s.params.slidesPerColumn;\n            var slidesPerRow = slidesNumberEvenToRows / slidesPerColumn;\n            var numFullColumns = slidesPerRow - (s.params.slidesPerColumn * slidesPerRow - s.slides.length);\n            for (i = 0; i < s.slides.length; i++) {\n                slideSize = 0;\n                var slide = s.slides.eq(i);\n                if (s.params.slidesPerColumn > 1) {\n                    // Set slides order\n                    var newSlideOrderIndex;\n                    var column, row;\n                    if (s.params.slidesPerColumnFill === 'column') {\n                        column = Math.floor(i / slidesPerColumn);\n                        row = i - column * slidesPerColumn;\n                        if (column > numFullColumns || (column === numFullColumns && row === slidesPerColumn-1)) {\n                            if (++row >= slidesPerColumn) {\n                                row = 0;\n                                column++;\n                            }\n                        }\n                        newSlideOrderIndex = column + row * slidesNumberEvenToRows / slidesPerColumn;\n                        slide\n                            .css({\n                                '-webkit-box-ordinal-group': newSlideOrderIndex,\n                                '-moz-box-ordinal-group': newSlideOrderIndex,\n                                '-ms-flex-order': newSlideOrderIndex,\n                                '-webkit-order': newSlideOrderIndex,\n                                'order': newSlideOrderIndex\n                            });\n                    }\n                    else {\n                        row = Math.floor(i / slidesPerRow);\n                        column = i - row * slidesPerRow;\n                    }\n                    slide\n                        .css({\n                            'margin-top': (row !== 0 && s.params.spaceBetween) && (s.params.spaceBetween + 'px')\n                        })\n                        .attr('data-swiper-column', column)\n                        .attr('data-swiper-row', row);\n        \n                }\n                if (slide.css('display') === 'none') continue;\n                if (s.params.slidesPerView === 'auto') {\n                    slideSize = s.isHorizontal() ? slide.outerWidth(true) : slide.outerHeight(true);\n                    if (s.params.roundLengths) slideSize = round(slideSize);\n                }\n                else {\n                    slideSize = (s.size - (s.params.slidesPerView - 1) * spaceBetween) / s.params.slidesPerView;\n                    if (s.params.roundLengths) slideSize = round(slideSize);\n        \n                    if (s.isHorizontal()) {\n                        s.slides[i].style.width = slideSize + 'px';\n                    }\n                    else {\n                        s.slides[i].style.height = slideSize + 'px';\n                    }\n                }\n                s.slides[i].swiperSlideSize = slideSize;\n                s.slidesSizesGrid.push(slideSize);\n        \n        \n                if (s.params.centeredSlides) {\n                    slidePosition = slidePosition + slideSize / 2 + prevSlideSize / 2 + spaceBetween;\n                    if (i === 0) slidePosition = slidePosition - s.size / 2 - spaceBetween;\n                    if (Math.abs(slidePosition) < 1 / 1000) slidePosition = 0;\n                    if ((index) % s.params.slidesPerGroup === 0) s.snapGrid.push(slidePosition);\n                    s.slidesGrid.push(slidePosition);\n                }\n                else {\n                    if ((index) % s.params.slidesPerGroup === 0) s.snapGrid.push(slidePosition);\n                    s.slidesGrid.push(slidePosition);\n                    slidePosition = slidePosition + slideSize + spaceBetween;\n                }\n        \n                s.virtualSize += slideSize + spaceBetween;\n        \n                prevSlideSize = slideSize;\n        \n                index ++;\n            }\n            s.virtualSize = Math.max(s.virtualSize, s.size) + s.params.slidesOffsetAfter;\n            var newSlidesGrid;\n        \n            if (\n                s.rtl && s.wrongRTL && (s.params.effect === 'slide' || s.params.effect === 'coverflow')) {\n                s.wrapper.css({width: s.virtualSize + s.params.spaceBetween + 'px'});\n            }\n            if (!s.support.flexbox || s.params.setWrapperSize) {\n                if (s.isHorizontal()) s.wrapper.css({width: s.virtualSize + s.params.spaceBetween + 'px'});\n                else s.wrapper.css({height: s.virtualSize + s.params.spaceBetween + 'px'});\n            }\n        \n            if (s.params.slidesPerColumn > 1) {\n                s.virtualSize = (slideSize + s.params.spaceBetween) * slidesNumberEvenToRows;\n                s.virtualSize = Math.ceil(s.virtualSize / s.params.slidesPerColumn) - s.params.spaceBetween;\n                s.wrapper.css({width: s.virtualSize + s.params.spaceBetween + 'px'});\n                if (s.params.centeredSlides) {\n                    newSlidesGrid = [];\n                    for (i = 0; i < s.snapGrid.length; i++) {\n                        if (s.snapGrid[i] < s.virtualSize + s.snapGrid[0]) newSlidesGrid.push(s.snapGrid[i]);\n                    }\n                    s.snapGrid = newSlidesGrid;\n                }\n            }\n        \n            // Remove last grid elements depending on width\n            if (!s.params.centeredSlides) {\n                newSlidesGrid = [];\n                for (i = 0; i < s.snapGrid.length; i++) {\n                    if (s.snapGrid[i] <= s.virtualSize - s.size) {\n                        newSlidesGrid.push(s.snapGrid[i]);\n                    }\n                }\n                s.snapGrid = newSlidesGrid;\n                if (Math.floor(s.virtualSize - s.size) - Math.floor(s.snapGrid[s.snapGrid.length - 1]) > 1) {\n                    s.snapGrid.push(s.virtualSize - s.size);\n                }\n            }\n            if (s.snapGrid.length === 0) s.snapGrid = [0];\n        \n            if (s.params.spaceBetween !== 0) {\n                if (s.isHorizontal()) {\n                    if (s.rtl) s.slides.css({marginLeft: spaceBetween + 'px'});\n                    else s.slides.css({marginRight: spaceBetween + 'px'});\n                }\n                else s.slides.css({marginBottom: spaceBetween + 'px'});\n            }\n            if (s.params.watchSlidesProgress) {\n                s.updateSlidesOffset();\n            }\n        };\n        s.updateSlidesOffset = function () {\n            for (var i = 0; i < s.slides.length; i++) {\n                s.slides[i].swiperSlideOffset = s.isHorizontal() ? s.slides[i].offsetLeft : s.slides[i].offsetTop;\n            }\n        };\n        \n        /*=========================\n          Slider/slides progress\n          ===========================*/\n        s.updateSlidesProgress = function (translate) {\n            if (typeof translate === 'undefined') {\n                translate = s.translate || 0;\n            }\n            if (s.slides.length === 0) return;\n            if (typeof s.slides[0].swiperSlideOffset === 'undefined') s.updateSlidesOffset();\n        \n            var offsetCenter = -translate;\n            if (s.rtl) offsetCenter = translate;\n        \n            // Visible Slides\n            s.slides.removeClass(s.params.slideVisibleClass);\n            for (var i = 0; i < s.slides.length; i++) {\n                var slide = s.slides[i];\n                var slideProgress = (offsetCenter - slide.swiperSlideOffset) / (slide.swiperSlideSize + s.params.spaceBetween);\n                if (s.params.watchSlidesVisibility) {\n                    var slideBefore = -(offsetCenter - slide.swiperSlideOffset);\n                    var slideAfter = slideBefore + s.slidesSizesGrid[i];\n                    var isVisible =\n                        (slideBefore >= 0 && slideBefore < s.size) ||\n                        (slideAfter > 0 && slideAfter <= s.size) ||\n                        (slideBefore <= 0 && slideAfter >= s.size);\n                    if (isVisible) {\n                        s.slides.eq(i).addClass(s.params.slideVisibleClass);\n                    }\n                }\n                slide.progress = s.rtl ? -slideProgress : slideProgress;\n            }\n        };\n        s.updateProgress = function (translate) {\n            if (typeof translate === 'undefined') {\n                translate = s.translate || 0;\n            }\n            var translatesDiff = s.maxTranslate() - s.minTranslate();\n            var wasBeginning = s.isBeginning;\n            var wasEnd = s.isEnd;\n            if (translatesDiff === 0) {\n                s.progress = 0;\n                s.isBeginning = s.isEnd = true;\n            }\n            else {\n                s.progress = (translate - s.minTranslate()) / (translatesDiff);\n                s.isBeginning = s.progress <= 0;\n                s.isEnd = s.progress >= 1;\n            }\n            if (s.isBeginning && !wasBeginning) s.emit('onReachBeginning', s);\n            if (s.isEnd && !wasEnd) s.emit('onReachEnd', s);\n        \n            if (s.params.watchSlidesProgress) s.updateSlidesProgress(translate);\n            s.emit('onProgress', s, s.progress);\n        };\n        s.updateActiveIndex = function () {\n            var translate = s.rtl ? s.translate : -s.translate;\n            var newActiveIndex, i, snapIndex;\n            for (i = 0; i < s.slidesGrid.length; i ++) {\n                if (typeof s.slidesGrid[i + 1] !== 'undefined') {\n                    if (translate >= s.slidesGrid[i] && translate < s.slidesGrid[i + 1] - (s.slidesGrid[i + 1] - s.slidesGrid[i]) / 2) {\n                        newActiveIndex = i;\n                    }\n                    else if (translate >= s.slidesGrid[i] && translate < s.slidesGrid[i + 1]) {\n                        newActiveIndex = i + 1;\n                    }\n                }\n                else {\n                    if (translate >= s.slidesGrid[i]) {\n                        newActiveIndex = i;\n                    }\n                }\n            }\n            // Normalize slideIndex\n            if (newActiveIndex < 0 || typeof newActiveIndex === 'undefined') newActiveIndex = 0;\n            // for (i = 0; i < s.slidesGrid.length; i++) {\n                // if (- translate >= s.slidesGrid[i]) {\n                    // newActiveIndex = i;\n                // }\n            // }\n            snapIndex = Math.floor(newActiveIndex / s.params.slidesPerGroup);\n            if (snapIndex >= s.snapGrid.length) snapIndex = s.snapGrid.length - 1;\n        \n            if (newActiveIndex === s.activeIndex) {\n                return;\n            }\n            s.snapIndex = snapIndex;\n            s.previousIndex = s.activeIndex;\n            s.activeIndex = newActiveIndex;\n            s.updateClasses();\n        };\n        \n        /*=========================\n          Classes\n          ===========================*/\n        s.updateClasses = function () {\n            s.slides.removeClass(s.params.slideActiveClass + ' ' + s.params.slideNextClass + ' ' + s.params.slidePrevClass);\n            var activeSlide = s.slides.eq(s.activeIndex);\n            // Active classes\n            activeSlide.addClass(s.params.slideActiveClass);\n            // Next Slide\n            var nextSlide = activeSlide.next('.' + s.params.slideClass).addClass(s.params.slideNextClass);\n            if (s.params.loop && nextSlide.length === 0) {\n                s.slides.eq(0).addClass(s.params.slideNextClass);\n            }\n            // Prev Slide\n            var prevSlide = activeSlide.prev('.' + s.params.slideClass).addClass(s.params.slidePrevClass);\n            if (s.params.loop && prevSlide.length === 0) {\n                s.slides.eq(-1).addClass(s.params.slidePrevClass);\n            }\n        \n            // Pagination\n            if (s.paginationContainer && s.paginationContainer.length > 0) {\n                // Current/Total\n                var current,\n                    total = s.params.loop ? Math.ceil((s.slides.length - s.loopedSlides * 2) / s.params.slidesPerGroup) : s.snapGrid.length;\n                if (s.params.loop) {\n                    current = Math.ceil((s.activeIndex - s.loopedSlides)/s.params.slidesPerGroup);\n                    if (current > s.slides.length - 1 - s.loopedSlides * 2) {\n                        current = current - (s.slides.length - s.loopedSlides * 2);\n                    }\n                    if (current > total - 1) current = current - total;\n                    if (current < 0 && s.params.paginationType !== 'bullets') current = total + current;\n                }\n                else {\n                    if (typeof s.snapIndex !== 'undefined') {\n                        current = s.snapIndex;\n                    }\n                    else {\n                        current = s.activeIndex || 0;\n                    }\n                }\n                // Types\n                if (s.params.paginationType === 'bullets' && s.bullets && s.bullets.length > 0) {\n                    s.bullets.removeClass(s.params.bulletActiveClass);\n                    if (s.paginationContainer.length > 1) {\n                        s.bullets.each(function () {\n                            if ($(this).index() === current) $(this).addClass(s.params.bulletActiveClass);\n                        });\n                    }\n                    else {\n                        s.bullets.eq(current).addClass(s.params.bulletActiveClass);\n                    }\n                }\n                if (s.params.paginationType === 'fraction') {\n                    s.paginationContainer.find('.' + s.params.paginationCurrentClass).text(current + 1);\n                    s.paginationContainer.find('.' + s.params.paginationTotalClass).text(total);\n                }\n                if (s.params.paginationType === 'progress') {\n                    var scale = (current + 1) / total,\n                        scaleX = scale,\n                        scaleY = 1;\n                    if (!s.isHorizontal()) {\n                        scaleY = scale;\n                        scaleX = 1;\n                    }\n                    s.paginationContainer.find('.' + s.params.paginationProgressbarClass).transform('translate3d(0,0,0) scaleX(' + scaleX + ') scaleY(' + scaleY + ')').transition(s.params.speed);\n                }\n                if (s.params.paginationType === 'custom' && s.params.paginationCustomRender) {\n                    s.paginationContainer.html(s.params.paginationCustomRender(s, current + 1, total));\n                    s.emit('onPaginationRendered', s, s.paginationContainer[0]);\n                }\n            }\n        \n            // Next/active buttons\n            if (!s.params.loop) {\n                if (s.params.prevButton && s.prevButton && s.prevButton.length > 0) {\n                    if (s.isBeginning) {\n                        s.prevButton.addClass(s.params.buttonDisabledClass);\n                        if (s.params.a11y && s.a11y) s.a11y.disable(s.prevButton);\n                    }\n                    else {\n                        s.prevButton.removeClass(s.params.buttonDisabledClass);\n                        if (s.params.a11y && s.a11y) s.a11y.enable(s.prevButton);\n                    }\n                }\n                if (s.params.nextButton && s.nextButton && s.nextButton.length > 0) {\n                    if (s.isEnd) {\n                        s.nextButton.addClass(s.params.buttonDisabledClass);\n                        if (s.params.a11y && s.a11y) s.a11y.disable(s.nextButton);\n                    }\n                    else {\n                        s.nextButton.removeClass(s.params.buttonDisabledClass);\n                        if (s.params.a11y && s.a11y) s.a11y.enable(s.nextButton);\n                    }\n                }\n            }\n        };\n        \n        /*=========================\n          Pagination\n          ===========================*/\n        s.updatePagination = function () {\n            if (!s.params.pagination) return;\n            if (s.paginationContainer && s.paginationContainer.length > 0) {\n                var paginationHTML = '';\n                if (s.params.paginationType === 'bullets') {\n                    var numberOfBullets = s.params.loop ? Math.ceil((s.slides.length - s.loopedSlides * 2) / s.params.slidesPerGroup) : s.snapGrid.length;\n                    for (var i = 0; i < numberOfBullets; i++) {\n                        if (s.params.paginationBulletRender) {\n                            paginationHTML += s.params.paginationBulletRender(i, s.params.bulletClass);\n                        }\n                        else {\n                            paginationHTML += '<' + s.params.paginationElement+' class=\"' + s.params.bulletClass + '\"></' + s.params.paginationElement + '>';\n                        }\n                    }\n                    s.paginationContainer.html(paginationHTML);\n                    s.bullets = s.paginationContainer.find('.' + s.params.bulletClass);\n                    if (s.params.paginationClickable && s.params.a11y && s.a11y) {\n                        s.a11y.initPagination();\n                    }\n                }\n                if (s.params.paginationType === 'fraction') {\n                    if (s.params.paginationFractionRender) {\n                        paginationHTML = s.params.paginationFractionRender(s, s.params.paginationCurrentClass, s.params.paginationTotalClass);\n                    }\n                    else {\n                        paginationHTML =\n                            '<span class=\"' + s.params.paginationCurrentClass + '\"></span>' +\n                            ' / ' +\n                            '<span class=\"' + s.params.paginationTotalClass+'\"></span>';\n                    }\n                    s.paginationContainer.html(paginationHTML);\n                }\n                if (s.params.paginationType === 'progress') {\n                    if (s.params.paginationProgressRender) {\n                        paginationHTML = s.params.paginationProgressRender(s, s.params.paginationProgressbarClass);\n                    }\n                    else {\n                        paginationHTML = '<span class=\"' + s.params.paginationProgressbarClass + '\"></span>';\n                    }\n                    s.paginationContainer.html(paginationHTML);\n                }\n                if (s.params.paginationType !== 'custom') {\n                    s.emit('onPaginationRendered', s, s.paginationContainer[0]);\n                }\n            }\n        };\n        /*=========================\n          Common update method\n          ===========================*/\n        s.update = function (updateTranslate) {\n            s.updateContainerSize();\n            s.updateSlidesSize();\n            s.updateProgress();\n            s.updatePagination();\n            s.updateClasses();\n            if (s.params.scrollbar && s.scrollbar) {\n                s.scrollbar.set();\n            }\n            function forceSetTranslate() {\n                newTranslate = Math.min(Math.max(s.translate, s.maxTranslate()), s.minTranslate());\n                s.setWrapperTranslate(newTranslate);\n                s.updateActiveIndex();\n                s.updateClasses();\n            }\n            if (updateTranslate) {\n                var translated, newTranslate;\n                if (s.controller && s.controller.spline) {\n                    s.controller.spline = undefined;\n                }\n                if (s.params.freeMode) {\n                    forceSetTranslate();\n                    if (s.params.autoHeight) {\n                        s.updateAutoHeight();\n                    }\n                }\n                else {\n                    if ((s.params.slidesPerView === 'auto' || s.params.slidesPerView > 1) && s.isEnd && !s.params.centeredSlides) {\n                        translated = s.slideTo(s.slides.length - 1, 0, false, true);\n                    }\n                    else {\n                        translated = s.slideTo(s.activeIndex, 0, false, true);\n                    }\n                    if (!translated) {\n                        forceSetTranslate();\n                    }\n                }\n            }\n            else if (s.params.autoHeight) {\n                s.updateAutoHeight();\n            }\n        };\n        \n        /*=========================\n          Resize Handler\n          ===========================*/\n        s.onResize = function (forceUpdatePagination) {\n            //Breakpoints\n            if (s.params.breakpoints) {\n                s.setBreakpoint();\n            }\n        \n            // Disable locks on resize\n            var allowSwipeToPrev = s.params.allowSwipeToPrev;\n            var allowSwipeToNext = s.params.allowSwipeToNext;\n            s.params.allowSwipeToPrev = s.params.allowSwipeToNext = true;\n        \n            s.updateContainerSize();\n            s.updateSlidesSize();\n            if (s.params.slidesPerView === 'auto' || s.params.freeMode || forceUpdatePagination) s.updatePagination();\n            if (s.params.scrollbar && s.scrollbar) {\n                s.scrollbar.set();\n            }\n            if (s.controller && s.controller.spline) {\n                s.controller.spline = undefined;\n            }\n            var slideChangedBySlideTo = false;\n            if (s.params.freeMode) {\n                var newTranslate = Math.min(Math.max(s.translate, s.maxTranslate()), s.minTranslate());\n                s.setWrapperTranslate(newTranslate);\n                s.updateActiveIndex();\n                s.updateClasses();\n        \n                if (s.params.autoHeight) {\n                    s.updateAutoHeight();\n                }\n            }\n            else {\n                s.updateClasses();\n                if ((s.params.slidesPerView === 'auto' || s.params.slidesPerView > 1) && s.isEnd && !s.params.centeredSlides) {\n                    slideChangedBySlideTo = s.slideTo(s.slides.length - 1, 0, false, true);\n                }\n                else {\n                    slideChangedBySlideTo = s.slideTo(s.activeIndex, 0, false, true);\n                }\n            }\n            if (s.params.lazyLoading && !slideChangedBySlideTo && s.lazy) {\n                s.lazy.load();\n            }\n            // Return locks after resize\n            s.params.allowSwipeToPrev = allowSwipeToPrev;\n            s.params.allowSwipeToNext = allowSwipeToNext;\n        };\n        \n        /*=========================\n          Events\n          ===========================*/\n        \n        //Define Touch Events\n        var desktopEvents = ['mousedown', 'mousemove', 'mouseup'];\n        if (window.navigator.pointerEnabled) desktopEvents = ['pointerdown', 'pointermove', 'pointerup'];\n        else if (window.navigator.msPointerEnabled) desktopEvents = ['MSPointerDown', 'MSPointerMove', 'MSPointerUp'];\n        s.touchEvents = {\n            start : s.support.touch || !s.params.simulateTouch  ? 'touchstart' : desktopEvents[0],\n            move : s.support.touch || !s.params.simulateTouch ? 'touchmove' : desktopEvents[1],\n            end : s.support.touch || !s.params.simulateTouch ? 'touchend' : desktopEvents[2]\n        };\n        \n        \n        // WP8 Touch Events Fix\n        if (window.navigator.pointerEnabled || window.navigator.msPointerEnabled) {\n            (s.params.touchEventsTarget === 'container' ? s.container : s.wrapper).addClass('swiper-wp8-' + s.params.direction);\n        }\n        \n        // Attach/detach events\n        s.initEvents = function (detach) {\n            var actionDom = detach ? 'off' : 'on';\n            var action = detach ? 'removeEventListener' : 'addEventListener';\n            var touchEventsTarget = s.params.touchEventsTarget === 'container' ? s.container[0] : s.wrapper[0];\n            var target = s.support.touch ? touchEventsTarget : document;\n        \n            var moveCapture = s.params.nested ? true : false;\n        \n            //Touch Events\n            if (s.browser.ie) {\n                touchEventsTarget[action](s.touchEvents.start, s.onTouchStart, false);\n                target[action](s.touchEvents.move, s.onTouchMove, moveCapture);\n                target[action](s.touchEvents.end, s.onTouchEnd, false);\n            }\n            else {\n                if (s.support.touch) {\n                    touchEventsTarget[action](s.touchEvents.start, s.onTouchStart, false);\n                    touchEventsTarget[action](s.touchEvents.move, s.onTouchMove, moveCapture);\n                    touchEventsTarget[action](s.touchEvents.end, s.onTouchEnd, false);\n                }\n                if (params.simulateTouch && !s.device.ios && !s.device.android) {\n                    touchEventsTarget[action]('mousedown', s.onTouchStart, false);\n                    document[action]('mousemove', s.onTouchMove, moveCapture);\n                    document[action]('mouseup', s.onTouchEnd, false);\n                }\n            }\n            window[action]('resize', s.onResize);\n        \n            // Next, Prev, Index\n            if (s.params.nextButton && s.nextButton && s.nextButton.length > 0) {\n                s.nextButton[actionDom]('click', s.onClickNext);\n                if (s.params.a11y && s.a11y) s.nextButton[actionDom]('keydown', s.a11y.onEnterKey);\n            }\n            if (s.params.prevButton && s.prevButton && s.prevButton.length > 0) {\n                s.prevButton[actionDom]('click', s.onClickPrev);\n                if (s.params.a11y && s.a11y) s.prevButton[actionDom]('keydown', s.a11y.onEnterKey);\n            }\n            if (s.params.pagination && s.params.paginationClickable) {\n                s.paginationContainer[actionDom]('click', '.' + s.params.bulletClass, s.onClickIndex);\n                if (s.params.a11y && s.a11y) s.paginationContainer[actionDom]('keydown', '.' + s.params.bulletClass, s.a11y.onEnterKey);\n            }\n        \n            // Prevent Links Clicks\n            if (s.params.preventClicks || s.params.preventClicksPropagation) touchEventsTarget[action]('click', s.preventClicks, true);\n        };\n        s.attachEvents = function () {\n            s.initEvents();\n        };\n        s.detachEvents = function () {\n            s.initEvents(true);\n        };\n        \n        /*=========================\n          Handle Clicks\n          ===========================*/\n        // Prevent Clicks\n        s.allowClick = true;\n        s.preventClicks = function (e) {\n            if (!s.allowClick) {\n                if (s.params.preventClicks) e.preventDefault();\n                if (s.params.preventClicksPropagation && s.animating) {\n                    e.stopPropagation();\n                    e.stopImmediatePropagation();\n                }\n            }\n        };\n        // Clicks\n        s.onClickNext = function (e) {\n            e.preventDefault();\n            if (s.isEnd && !s.params.loop) return;\n            s.slideNext();\n        };\n        s.onClickPrev = function (e) {\n            e.preventDefault();\n            if (s.isBeginning && !s.params.loop) return;\n            s.slidePrev();\n        };\n        s.onClickIndex = function (e) {\n            e.preventDefault();\n            var index = $(this).index() * s.params.slidesPerGroup;\n            if (s.params.loop) index = index + s.loopedSlides;\n            s.slideTo(index);\n        };\n        \n        /*=========================\n          Handle Touches\n          ===========================*/\n        function findElementInEvent(e, selector) {\n            var el = $(e.target);\n            if (!el.is(selector)) {\n                if (typeof selector === 'string') {\n                    el = el.parents(selector);\n                }\n                else if (selector.nodeType) {\n                    var found;\n                    el.parents().each(function (index, _el) {\n                        if (_el === selector) found = selector;\n                    });\n                    if (!found) return undefined;\n                    else return selector;\n                }\n            }\n            if (el.length === 0) {\n                return undefined;\n            }\n            return el[0];\n        }\n        s.updateClickedSlide = function (e) {\n            var slide = findElementInEvent(e, '.' + s.params.slideClass);\n            var slideFound = false;\n            if (slide) {\n                for (var i = 0; i < s.slides.length; i++) {\n                    if (s.slides[i] === slide) slideFound = true;\n                }\n            }\n        \n            if (slide && slideFound) {\n                s.clickedSlide = slide;\n                s.clickedIndex = $(slide).index();\n            }\n            else {\n                s.clickedSlide = undefined;\n                s.clickedIndex = undefined;\n                return;\n            }\n            if (s.params.slideToClickedSlide && s.clickedIndex !== undefined && s.clickedIndex !== s.activeIndex) {\n                var slideToIndex = s.clickedIndex,\n                    realIndex,\n                    duplicatedSlides;\n                if (s.params.loop) {\n                    if (s.animating) return;\n                    realIndex = $(s.clickedSlide).attr('data-swiper-slide-index');\n                    if (s.params.centeredSlides) {\n                        if ((slideToIndex < s.loopedSlides - s.params.slidesPerView/2) || (slideToIndex > s.slides.length - s.loopedSlides + s.params.slidesPerView/2)) {\n                            s.fixLoop();\n                            slideToIndex = s.wrapper.children('.' + s.params.slideClass + '[data-swiper-slide-index=\"' + realIndex + '\"]:not(.swiper-slide-duplicate)').eq(0).index();\n                            setTimeout(function () {\n                                s.slideTo(slideToIndex);\n                            }, 0);\n                        }\n                        else {\n                            s.slideTo(slideToIndex);\n                        }\n                    }\n                    else {\n                        if (slideToIndex > s.slides.length - s.params.slidesPerView) {\n                            s.fixLoop();\n                            slideToIndex = s.wrapper.children('.' + s.params.slideClass + '[data-swiper-slide-index=\"' + realIndex + '\"]:not(.swiper-slide-duplicate)').eq(0).index();\n                            setTimeout(function () {\n                                s.slideTo(slideToIndex);\n                            }, 0);\n                        }\n                        else {\n                            s.slideTo(slideToIndex);\n                        }\n                    }\n                }\n                else {\n                    s.slideTo(slideToIndex);\n                }\n            }\n        };\n        \n        var isTouched,\n            isMoved,\n            allowTouchCallbacks,\n            touchStartTime,\n            isScrolling,\n            currentTranslate,\n            startTranslate,\n            allowThresholdMove,\n            // Form elements to match\n            formElements = 'input, select, textarea, button',\n            // Last click time\n            lastClickTime = Date.now(), clickTimeout,\n            //Velocities\n            velocities = [],\n            allowMomentumBounce;\n        \n        // Animating Flag\n        s.animating = false;\n        \n        // Touches information\n        s.touches = {\n            startX: 0,\n            startY: 0,\n            currentX: 0,\n            currentY: 0,\n            diff: 0\n        };\n        \n        // Touch handlers\n        var isTouchEvent, startMoving;\n        s.onTouchStart = function (e) {\n            if (e.originalEvent) e = e.originalEvent;\n            isTouchEvent = e.type === 'touchstart';\n            if (!isTouchEvent && 'which' in e && e.which === 3) return;\n            if (s.params.noSwiping && findElementInEvent(e, '.' + s.params.noSwipingClass)) {\n                s.allowClick = true;\n                return;\n            }\n            if (s.params.swipeHandler) {\n                if (!findElementInEvent(e, s.params.swipeHandler)) return;\n            }\n        \n            var startX = s.touches.currentX = e.type === 'touchstart' ? e.targetTouches[0].pageX : e.pageX;\n            var startY = s.touches.currentY = e.type === 'touchstart' ? e.targetTouches[0].pageY : e.pageY;\n        \n            // Do NOT start if iOS edge swipe is detected. Otherwise iOS app (UIWebView) cannot swipe-to-go-back anymore\n            if(s.device.ios && s.params.iOSEdgeSwipeDetection && startX <= s.params.iOSEdgeSwipeThreshold) {\n                return;\n            }\n        \n            isTouched = true;\n            isMoved = false;\n            allowTouchCallbacks = true;\n            isScrolling = undefined;\n            startMoving = undefined;\n            s.touches.startX = startX;\n            s.touches.startY = startY;\n            touchStartTime = Date.now();\n            s.allowClick = true;\n            s.updateContainerSize();\n            s.swipeDirection = undefined;\n            if (s.params.threshold > 0) allowThresholdMove = false;\n            if (e.type !== 'touchstart') {\n                var preventDefault = true;\n                if ($(e.target).is(formElements)) preventDefault = false;\n                if (document.activeElement && $(document.activeElement).is(formElements)) {\n                    document.activeElement.blur();\n                }\n                if (preventDefault) {\n                    e.preventDefault();\n                }\n            }\n            s.emit('onTouchStart', s, e);\n        };\n        \n        s.onTouchMove = function (e) {\n            if (e.originalEvent) e = e.originalEvent;\n            if (isTouchEvent && e.type === 'mousemove') return;\n            if (e.preventedByNestedSwiper) {\n                s.touches.startX = e.type === 'touchmove' ? e.targetTouches[0].pageX : e.pageX;\n                s.touches.startY = e.type === 'touchmove' ? e.targetTouches[0].pageY : e.pageY;\n                return;\n            }\n            if (s.params.onlyExternal) {\n                // isMoved = true;\n                s.allowClick = false;\n                if (isTouched) {\n                    s.touches.startX = s.touches.currentX = e.type === 'touchmove' ? e.targetTouches[0].pageX : e.pageX;\n                    s.touches.startY = s.touches.currentY = e.type === 'touchmove' ? e.targetTouches[0].pageY : e.pageY;\n                    touchStartTime = Date.now();\n                }\n                return;\n            }\n            if (isTouchEvent && document.activeElement) {\n                if (e.target === document.activeElement && $(e.target).is(formElements)) {\n                    isMoved = true;\n                    s.allowClick = false;\n                    return;\n                }\n            }\n            if (allowTouchCallbacks) {\n                s.emit('onTouchMove', s, e);\n            }\n            if (e.targetTouches && e.targetTouches.length > 1) return;\n        \n            s.touches.currentX = e.type === 'touchmove' ? e.targetTouches[0].pageX : e.pageX;\n            s.touches.currentY = e.type === 'touchmove' ? e.targetTouches[0].pageY : e.pageY;\n        \n            if (typeof isScrolling === 'undefined') {\n                var touchAngle = Math.atan2(Math.abs(s.touches.currentY - s.touches.startY), Math.abs(s.touches.currentX - s.touches.startX)) * 180 / Math.PI;\n                isScrolling = s.isHorizontal() ? touchAngle > s.params.touchAngle : (90 - touchAngle > s.params.touchAngle);\n            }\n            if (isScrolling) {\n                s.emit('onTouchMoveOpposite', s, e);\n            }\n            if (typeof startMoving === 'undefined' && s.browser.ieTouch) {\n                if (s.touches.currentX !== s.touches.startX || s.touches.currentY !== s.touches.startY) {\n                    startMoving = true;\n                }\n            }\n            if (!isTouched) return;\n            if (isScrolling)  {\n                isTouched = false;\n                return;\n            }\n            if (!startMoving && s.browser.ieTouch) {\n                return;\n            }\n            s.allowClick = false;\n            s.emit('onSliderMove', s, e);\n            e.preventDefault();\n            if (s.params.touchMoveStopPropagation && !s.params.nested) {\n                e.stopPropagation();\n            }\n        \n            if (!isMoved) {\n                if (params.loop) {\n                    s.fixLoop();\n                }\n                startTranslate = s.getWrapperTranslate();\n                s.setWrapperTransition(0);\n                if (s.animating) {\n                    s.wrapper.trigger('webkitTransitionEnd transitionend oTransitionEnd MSTransitionEnd msTransitionEnd');\n                }\n                if (s.params.autoplay && s.autoplaying) {\n                    if (s.params.autoplayDisableOnInteraction) {\n                        s.stopAutoplay();\n                    }\n                    else {\n                        s.pauseAutoplay();\n                    }\n                }\n                allowMomentumBounce = false;\n                //Grab Cursor\n                if (s.params.grabCursor) {\n                    s.container[0].style.cursor = 'move';\n                    s.container[0].style.cursor = '-webkit-grabbing';\n                    s.container[0].style.cursor = '-moz-grabbin';\n                    s.container[0].style.cursor = 'grabbing';\n                }\n            }\n            isMoved = true;\n        \n            var diff = s.touches.diff = s.isHorizontal() ? s.touches.currentX - s.touches.startX : s.touches.currentY - s.touches.startY;\n        \n            diff = diff * s.params.touchRatio;\n            if (s.rtl) diff = -diff;\n        \n            s.swipeDirection = diff > 0 ? 'prev' : 'next';\n            currentTranslate = diff + startTranslate;\n        \n            var disableParentSwiper = true;\n            if ((diff > 0 && currentTranslate > s.minTranslate())) {\n                disableParentSwiper = false;\n                if (s.params.resistance) currentTranslate = s.minTranslate() - 1 + Math.pow(-s.minTranslate() + startTranslate + diff, s.params.resistanceRatio);\n            }\n            else if (diff < 0 && currentTranslate < s.maxTranslate()) {\n                disableParentSwiper = false;\n                if (s.params.resistance) currentTranslate = s.maxTranslate() + 1 - Math.pow(s.maxTranslate() - startTranslate - diff, s.params.resistanceRatio);\n            }\n        \n            if (disableParentSwiper) {\n                e.preventedByNestedSwiper = true;\n            }\n        \n            // Directions locks\n            if (!s.params.allowSwipeToNext && s.swipeDirection === 'next' && currentTranslate < startTranslate) {\n                currentTranslate = startTranslate;\n            }\n            if (!s.params.allowSwipeToPrev && s.swipeDirection === 'prev' && currentTranslate > startTranslate) {\n                currentTranslate = startTranslate;\n            }\n        \n            if (!s.params.followFinger) return;\n        \n            // Threshold\n            if (s.params.threshold > 0) {\n                if (Math.abs(diff) > s.params.threshold || allowThresholdMove) {\n                    if (!allowThresholdMove) {\n                        allowThresholdMove = true;\n                        s.touches.startX = s.touches.currentX;\n                        s.touches.startY = s.touches.currentY;\n                        currentTranslate = startTranslate;\n                        s.touches.diff = s.isHorizontal() ? s.touches.currentX - s.touches.startX : s.touches.currentY - s.touches.startY;\n                        return;\n                    }\n                }\n                else {\n                    currentTranslate = startTranslate;\n                    return;\n                }\n            }\n            // Update active index in free mode\n            if (s.params.freeMode || s.params.watchSlidesProgress) {\n                s.updateActiveIndex();\n            }\n            if (s.params.freeMode) {\n                //Velocity\n                if (velocities.length === 0) {\n                    velocities.push({\n                        position: s.touches[s.isHorizontal() ? 'startX' : 'startY'],\n                        time: touchStartTime\n                    });\n                }\n                velocities.push({\n                    position: s.touches[s.isHorizontal() ? 'currentX' : 'currentY'],\n                    time: (new window.Date()).getTime()\n                });\n            }\n            // Update progress\n            s.updateProgress(currentTranslate);\n            // Update translate\n            s.setWrapperTranslate(currentTranslate);\n        };\n        s.onTouchEnd = function (e) {\n            if (e.originalEvent) e = e.originalEvent;\n            if (allowTouchCallbacks) {\n                s.emit('onTouchEnd', s, e);\n            }\n            allowTouchCallbacks = false;\n            if (!isTouched) return;\n            //Return Grab Cursor\n            if (s.params.grabCursor && isMoved && isTouched) {\n                s.container[0].style.cursor = 'move';\n                s.container[0].style.cursor = '-webkit-grab';\n                s.container[0].style.cursor = '-moz-grab';\n                s.container[0].style.cursor = 'grab';\n            }\n        \n            // Time diff\n            var touchEndTime = Date.now();\n            var timeDiff = touchEndTime - touchStartTime;\n        \n            // Tap, doubleTap, Click\n            if (s.allowClick) {\n                s.updateClickedSlide(e);\n                s.emit('onTap', s, e);\n                if (timeDiff < 300 && (touchEndTime - lastClickTime) > 300) {\n                    if (clickTimeout) clearTimeout(clickTimeout);\n                    clickTimeout = setTimeout(function () {\n                        if (!s) return;\n                        if (s.params.paginationHide && s.paginationContainer.length > 0 && !$(e.target).hasClass(s.params.bulletClass)) {\n                            s.paginationContainer.toggleClass(s.params.paginationHiddenClass);\n                        }\n                        s.emit('onClick', s, e);\n                    }, 300);\n        \n                }\n                if (timeDiff < 300 && (touchEndTime - lastClickTime) < 300) {\n                    if (clickTimeout) clearTimeout(clickTimeout);\n                    s.emit('onDoubleTap', s, e);\n                }\n            }\n        \n            lastClickTime = Date.now();\n            setTimeout(function () {\n                if (s) s.allowClick = true;\n            }, 0);\n        \n            if (!isTouched || !isMoved || !s.swipeDirection || s.touches.diff === 0 || currentTranslate === startTranslate) {\n                isTouched = isMoved = false;\n                return;\n            }\n            isTouched = isMoved = false;\n        \n            var currentPos;\n            if (s.params.followFinger) {\n                currentPos = s.rtl ? s.translate : -s.translate;\n            }\n            else {\n                currentPos = -currentTranslate;\n            }\n            if (s.params.freeMode) {\n                if (currentPos < -s.minTranslate()) {\n                    s.slideTo(s.activeIndex);\n                    return;\n                }\n                else if (currentPos > -s.maxTranslate()) {\n                    if (s.slides.length < s.snapGrid.length) {\n                        s.slideTo(s.snapGrid.length - 1);\n                    }\n                    else {\n                        s.slideTo(s.slides.length - 1);\n                    }\n                    return;\n                }\n        \n                if (s.params.freeModeMomentum) {\n                    if (velocities.length > 1) {\n                        var lastMoveEvent = velocities.pop(), velocityEvent = velocities.pop();\n        \n                        var distance = lastMoveEvent.position - velocityEvent.position;\n                        var time = lastMoveEvent.time - velocityEvent.time;\n                        s.velocity = distance / time;\n                        s.velocity = s.velocity / 2;\n                        if (Math.abs(s.velocity) < s.params.freeModeMinimumVelocity) {\n                            s.velocity = 0;\n                        }\n                        // this implies that the user stopped moving a finger then released.\n                        // There would be no events with distance zero, so the last event is stale.\n                        if (time > 150 || (new window.Date().getTime() - lastMoveEvent.time) > 300) {\n                            s.velocity = 0;\n                        }\n                    } else {\n                        s.velocity = 0;\n                    }\n        \n                    velocities.length = 0;\n                    var momentumDuration = 1000 * s.params.freeModeMomentumRatio;\n                    var momentumDistance = s.velocity * momentumDuration;\n        \n                    var newPosition = s.translate + momentumDistance;\n                    if (s.rtl) newPosition = - newPosition;\n                    var doBounce = false;\n                    var afterBouncePosition;\n                    var bounceAmount = Math.abs(s.velocity) * 20 * s.params.freeModeMomentumBounceRatio;\n                    if (newPosition < s.maxTranslate()) {\n                        if (s.params.freeModeMomentumBounce) {\n                            if (newPosition + s.maxTranslate() < -bounceAmount) {\n                                newPosition = s.maxTranslate() - bounceAmount;\n                            }\n                            afterBouncePosition = s.maxTranslate();\n                            doBounce = true;\n                            allowMomentumBounce = true;\n                        }\n                        else {\n                            newPosition = s.maxTranslate();\n                        }\n                    }\n                    else if (newPosition > s.minTranslate()) {\n                        if (s.params.freeModeMomentumBounce) {\n                            if (newPosition - s.minTranslate() > bounceAmount) {\n                                newPosition = s.minTranslate() + bounceAmount;\n                            }\n                            afterBouncePosition = s.minTranslate();\n                            doBounce = true;\n                            allowMomentumBounce = true;\n                        }\n                        else {\n                            newPosition = s.minTranslate();\n                        }\n                    }\n                    else if (s.params.freeModeSticky) {\n                        var j = 0,\n                            nextSlide;\n                        for (j = 0; j < s.snapGrid.length; j += 1) {\n                            if (s.snapGrid[j] > -newPosition) {\n                                nextSlide = j;\n                                break;\n                            }\n        \n                        }\n                        if (Math.abs(s.snapGrid[nextSlide] - newPosition) < Math.abs(s.snapGrid[nextSlide - 1] - newPosition) || s.swipeDirection === 'next') {\n                            newPosition = s.snapGrid[nextSlide];\n                        } else {\n                            newPosition = s.snapGrid[nextSlide - 1];\n                        }\n                        if (!s.rtl) newPosition = - newPosition;\n                    }\n                    //Fix duration\n                    if (s.velocity !== 0) {\n                        if (s.rtl) {\n                            momentumDuration = Math.abs((-newPosition - s.translate) / s.velocity);\n                        }\n                        else {\n                            momentumDuration = Math.abs((newPosition - s.translate) / s.velocity);\n                        }\n                    }\n                    else if (s.params.freeModeSticky) {\n                        s.slideReset();\n                        return;\n                    }\n        \n                    if (s.params.freeModeMomentumBounce && doBounce) {\n                        s.updateProgress(afterBouncePosition);\n                        s.setWrapperTransition(momentumDuration);\n                        s.setWrapperTranslate(newPosition);\n                        s.onTransitionStart();\n                        s.animating = true;\n                        s.wrapper.transitionEnd(function () {\n                            if (!s || !allowMomentumBounce) return;\n                            s.emit('onMomentumBounce', s);\n        \n                            s.setWrapperTransition(s.params.speed);\n                            s.setWrapperTranslate(afterBouncePosition);\n                            s.wrapper.transitionEnd(function () {\n                                if (!s) return;\n                                s.onTransitionEnd();\n                            });\n                        });\n                    } else if (s.velocity) {\n                        s.updateProgress(newPosition);\n                        s.setWrapperTransition(momentumDuration);\n                        s.setWrapperTranslate(newPosition);\n                        s.onTransitionStart();\n                        if (!s.animating) {\n                            s.animating = true;\n                            s.wrapper.transitionEnd(function () {\n                                if (!s) return;\n                                s.onTransitionEnd();\n                            });\n                        }\n        \n                    } else {\n                        s.updateProgress(newPosition);\n                    }\n        \n                    s.updateActiveIndex();\n                }\n                if (!s.params.freeModeMomentum || timeDiff >= s.params.longSwipesMs) {\n                    s.updateProgress();\n                    s.updateActiveIndex();\n                }\n                return;\n            }\n        \n            // Find current slide\n            var i, stopIndex = 0, groupSize = s.slidesSizesGrid[0];\n            for (i = 0; i < s.slidesGrid.length; i += s.params.slidesPerGroup) {\n                if (typeof s.slidesGrid[i + s.params.slidesPerGroup] !== 'undefined') {\n                    if (currentPos >= s.slidesGrid[i] && currentPos < s.slidesGrid[i + s.params.slidesPerGroup]) {\n                        stopIndex = i;\n                        groupSize = s.slidesGrid[i + s.params.slidesPerGroup] - s.slidesGrid[i];\n                    }\n                }\n                else {\n                    if (currentPos >= s.slidesGrid[i]) {\n                        stopIndex = i;\n                        groupSize = s.slidesGrid[s.slidesGrid.length - 1] - s.slidesGrid[s.slidesGrid.length - 2];\n                    }\n                }\n            }\n        \n            // Find current slide size\n            var ratio = (currentPos - s.slidesGrid[stopIndex]) / groupSize;\n        \n            if (timeDiff > s.params.longSwipesMs) {\n                // Long touches\n                if (!s.params.longSwipes) {\n                    s.slideTo(s.activeIndex);\n                    return;\n                }\n                if (s.swipeDirection === 'next') {\n                    if (ratio >= s.params.longSwipesRatio) s.slideTo(stopIndex + s.params.slidesPerGroup);\n                    else s.slideTo(stopIndex);\n        \n                }\n                if (s.swipeDirection === 'prev') {\n                    if (ratio > (1 - s.params.longSwipesRatio)) s.slideTo(stopIndex + s.params.slidesPerGroup);\n                    else s.slideTo(stopIndex);\n                }\n            }\n            else {\n                // Short swipes\n                if (!s.params.shortSwipes) {\n                    s.slideTo(s.activeIndex);\n                    return;\n                }\n                if (s.swipeDirection === 'next') {\n                    s.slideTo(stopIndex + s.params.slidesPerGroup);\n        \n                }\n                if (s.swipeDirection === 'prev') {\n                    s.slideTo(stopIndex);\n                }\n            }\n        };\n        /*=========================\n          Transitions\n          ===========================*/\n        s._slideTo = function (slideIndex, speed) {\n            return s.slideTo(slideIndex, speed, true, true);\n        };\n        s.slideTo = function (slideIndex, speed, runCallbacks, internal) {\n            if (typeof runCallbacks === 'undefined') runCallbacks = true;\n            if (typeof slideIndex === 'undefined') slideIndex = 0;\n            if (slideIndex < 0) slideIndex = 0;\n            s.snapIndex = Math.floor(slideIndex / s.params.slidesPerGroup);\n            if (s.snapIndex >= s.snapGrid.length) s.snapIndex = s.snapGrid.length - 1;\n        \n            var translate = - s.snapGrid[s.snapIndex];\n            // Stop autoplay\n            if (s.params.autoplay && s.autoplaying) {\n                if (internal || !s.params.autoplayDisableOnInteraction) {\n                    s.pauseAutoplay(speed);\n                }\n                else {\n                    s.stopAutoplay();\n                }\n            }\n            // Update progress\n            s.updateProgress(translate);\n        \n            // Normalize slideIndex\n            for (var i = 0; i < s.slidesGrid.length; i++) {\n                if (- Math.floor(translate * 100) >= Math.floor(s.slidesGrid[i] * 100)) {\n                    slideIndex = i;\n                }\n            }\n        \n            // Directions locks\n            if (!s.params.allowSwipeToNext && translate < s.translate && translate < s.minTranslate()) {\n                return false;\n            }\n            if (!s.params.allowSwipeToPrev && translate > s.translate && translate > s.maxTranslate()) {\n                if ((s.activeIndex || 0) !== slideIndex ) return false;\n            }\n        \n            // Update Index\n            if (typeof speed === 'undefined') speed = s.params.speed;\n            s.previousIndex = s.activeIndex || 0;\n            s.activeIndex = slideIndex;\n        \n            if ((s.rtl && -translate === s.translate) || (!s.rtl && translate === s.translate)) {\n                // Update Height\n                if (s.params.autoHeight) {\n                    s.updateAutoHeight();\n                }\n                s.updateClasses();\n                if (s.params.effect !== 'slide') {\n                    s.setWrapperTranslate(translate);\n                }\n                return false;\n            }\n            s.updateClasses();\n            s.onTransitionStart(runCallbacks);\n        \n            if (speed === 0) {\n                s.setWrapperTranslate(translate);\n                s.setWrapperTransition(0);\n                s.onTransitionEnd(runCallbacks);\n            }\n            else {\n                s.setWrapperTranslate(translate);\n                s.setWrapperTransition(speed);\n                if (!s.animating) {\n                    s.animating = true;\n                    s.wrapper.transitionEnd(function () {\n                        if (!s) return;\n                        s.onTransitionEnd(runCallbacks);\n                    });\n                }\n        \n            }\n        \n            return true;\n        };\n        \n        s.onTransitionStart = function (runCallbacks) {\n            if (typeof runCallbacks === 'undefined') runCallbacks = true;\n            if (s.params.autoHeight) {\n                s.updateAutoHeight();\n            }\n            if (s.lazy) s.lazy.onTransitionStart();\n            if (runCallbacks) {\n                s.emit('onTransitionStart', s);\n                if (s.activeIndex !== s.previousIndex) {\n                    s.emit('onSlideChangeStart', s);\n                    if (s.activeIndex > s.previousIndex) {\n                        s.emit('onSlideNextStart', s);\n                    }\n                    else {\n                        s.emit('onSlidePrevStart', s);\n                    }\n                }\n        \n            }\n        };\n        s.onTransitionEnd = function (runCallbacks) {\n            s.animating = false;\n            s.setWrapperTransition(0);\n            if (typeof runCallbacks === 'undefined') runCallbacks = true;\n            if (s.lazy) s.lazy.onTransitionEnd();\n            if (runCallbacks) {\n                s.emit('onTransitionEnd', s);\n                if (s.activeIndex !== s.previousIndex) {\n                    s.emit('onSlideChangeEnd', s);\n                    if (s.activeIndex > s.previousIndex) {\n                        s.emit('onSlideNextEnd', s);\n                    }\n                    else {\n                        s.emit('onSlidePrevEnd', s);\n                    }\n                }\n            }\n            if (s.params.hashnav && s.hashnav) {\n                s.hashnav.setHash();\n            }\n        \n        };\n        s.slideNext = function (runCallbacks, speed, internal) {\n            if (s.params.loop) {\n                if (s.animating) return false;\n                s.fixLoop();\n                var clientLeft = s.container[0].clientLeft;\n                return s.slideTo(s.activeIndex + s.params.slidesPerGroup, speed, runCallbacks, internal);\n            }\n            else return s.slideTo(s.activeIndex + s.params.slidesPerGroup, speed, runCallbacks, internal);\n        };\n        s._slideNext = function (speed) {\n            return s.slideNext(true, speed, true);\n        };\n        s.slidePrev = function (runCallbacks, speed, internal) {\n            if (s.params.loop) {\n                if (s.animating) return false;\n                s.fixLoop();\n                var clientLeft = s.container[0].clientLeft;\n                return s.slideTo(s.activeIndex - 1, speed, runCallbacks, internal);\n            }\n            else return s.slideTo(s.activeIndex - 1, speed, runCallbacks, internal);\n        };\n        s._slidePrev = function (speed) {\n            return s.slidePrev(true, speed, true);\n        };\n        s.slideReset = function (runCallbacks, speed, internal) {\n            return s.slideTo(s.activeIndex, speed, runCallbacks);\n        };\n        \n        /*=========================\n          Translate/transition helpers\n          ===========================*/\n        s.setWrapperTransition = function (duration, byController) {\n            s.wrapper.transition(duration);\n            if (s.params.effect !== 'slide' && s.effects[s.params.effect]) {\n                s.effects[s.params.effect].setTransition(duration);\n            }\n            if (s.params.parallax && s.parallax) {\n                s.parallax.setTransition(duration);\n            }\n            if (s.params.scrollbar && s.scrollbar) {\n                s.scrollbar.setTransition(duration);\n            }\n            if (s.params.control && s.controller) {\n                s.controller.setTransition(duration, byController);\n            }\n            s.emit('onSetTransition', s, duration);\n        };\n        s.setWrapperTranslate = function (translate, updateActiveIndex, byController) {\n            var x = 0, y = 0, z = 0;\n            if (s.isHorizontal()) {\n                x = s.rtl ? -translate : translate;\n            }\n            else {\n                y = translate;\n            }\n        \n            if (s.params.roundLengths) {\n                x = round(x);\n                y = round(y);\n            }\n        \n            if (!s.params.virtualTranslate) {\n                if (s.support.transforms3d) s.wrapper.transform('translate3d(' + x + 'px, ' + y + 'px, ' + z + 'px)');\n                else s.wrapper.transform('translate(' + x + 'px, ' + y + 'px)');\n            }\n        \n            s.translate = s.isHorizontal() ? x : y;\n        \n            // Check if we need to update progress\n            var progress;\n            var translatesDiff = s.maxTranslate() - s.minTranslate();\n            if (translatesDiff === 0) {\n                progress = 0;\n            }\n            else {\n                progress = (translate - s.minTranslate()) / (translatesDiff);\n            }\n            if (progress !== s.progress) {\n                s.updateProgress(translate);\n            }\n        \n            if (updateActiveIndex) s.updateActiveIndex();\n            if (s.params.effect !== 'slide' && s.effects[s.params.effect]) {\n                s.effects[s.params.effect].setTranslate(s.translate);\n            }\n            if (s.params.parallax && s.parallax) {\n                s.parallax.setTranslate(s.translate);\n            }\n            if (s.params.scrollbar && s.scrollbar) {\n                s.scrollbar.setTranslate(s.translate);\n            }\n            if (s.params.control && s.controller) {\n                s.controller.setTranslate(s.translate, byController);\n            }\n            s.emit('onSetTranslate', s, s.translate);\n        };\n        \n        s.getTranslate = function (el, axis) {\n            var matrix, curTransform, curStyle, transformMatrix;\n        \n            // automatic axis detection\n            if (typeof axis === 'undefined') {\n                axis = 'x';\n            }\n        \n            if (s.params.virtualTranslate) {\n                return s.rtl ? -s.translate : s.translate;\n            }\n        \n            curStyle = window.getComputedStyle(el, null);\n            if (window.WebKitCSSMatrix) {\n                curTransform = curStyle.transform || curStyle.webkitTransform;\n                if (curTransform.split(',').length > 6) {\n                    curTransform = curTransform.split(', ').map(function(a){\n                        return a.replace(',','.');\n                    }).join(', ');\n                }\n                // Some old versions of Webkit choke when 'none' is passed; pass\n                // empty string instead in this case\n                transformMatrix = new window.WebKitCSSMatrix(curTransform === 'none' ? '' : curTransform);\n            }\n            else {\n                transformMatrix = curStyle.MozTransform || curStyle.OTransform || curStyle.MsTransform || curStyle.msTransform  || curStyle.transform || curStyle.getPropertyValue('transform').replace('translate(', 'matrix(1, 0, 0, 1,');\n                matrix = transformMatrix.toString().split(',');\n            }\n        \n            if (axis === 'x') {\n                //Latest Chrome and webkits Fix\n                if (window.WebKitCSSMatrix)\n                    curTransform = transformMatrix.m41;\n                //Crazy IE10 Matrix\n                else if (matrix.length === 16)\n                    curTransform = parseFloat(matrix[12]);\n                //Normal Browsers\n                else\n                    curTransform = parseFloat(matrix[4]);\n            }\n            if (axis === 'y') {\n                //Latest Chrome and webkits Fix\n                if (window.WebKitCSSMatrix)\n                    curTransform = transformMatrix.m42;\n                //Crazy IE10 Matrix\n                else if (matrix.length === 16)\n                    curTransform = parseFloat(matrix[13]);\n                //Normal Browsers\n                else\n                    curTransform = parseFloat(matrix[5]);\n            }\n            if (s.rtl && curTransform) curTransform = -curTransform;\n            return curTransform || 0;\n        };\n        s.getWrapperTranslate = function (axis) {\n            if (typeof axis === 'undefined') {\n                axis = s.isHorizontal() ? 'x' : 'y';\n            }\n            return s.getTranslate(s.wrapper[0], axis);\n        };\n        \n        /*=========================\n          Observer\n          ===========================*/\n        s.observers = [];\n        function initObserver(target, options) {\n            options = options || {};\n            // create an observer instance\n            var ObserverFunc = window.MutationObserver || window.WebkitMutationObserver;\n            var observer = new ObserverFunc(function (mutations) {\n                mutations.forEach(function (mutation) {\n                    s.onResize(true);\n                    s.emit('onObserverUpdate', s, mutation);\n                });\n            });\n        \n            observer.observe(target, {\n                attributes: typeof options.attributes === 'undefined' ? true : options.attributes,\n                childList: typeof options.childList === 'undefined' ? true : options.childList,\n                characterData: typeof options.characterData === 'undefined' ? true : options.characterData\n            });\n        \n            s.observers.push(observer);\n        }\n        s.initObservers = function () {\n            if (s.params.observeParents) {\n                var containerParents = s.container.parents();\n                for (var i = 0; i < containerParents.length; i++) {\n                    initObserver(containerParents[i]);\n                }\n            }\n        \n            // Observe container\n            initObserver(s.container[0], {childList: false});\n        \n            // Observe wrapper\n            initObserver(s.wrapper[0], {attributes: false});\n        };\n        s.disconnectObservers = function () {\n            for (var i = 0; i < s.observers.length; i++) {\n                s.observers[i].disconnect();\n            }\n            s.observers = [];\n        };\n        /*=========================\n          Loop\n          ===========================*/\n        // Create looped slides\n        s.createLoop = function () {\n            // Remove duplicated slides\n            s.wrapper.children('.' + s.params.slideClass + '.' + s.params.slideDuplicateClass).remove();\n        \n            var slides = s.wrapper.children('.' + s.params.slideClass);\n        \n            if(s.params.slidesPerView === 'auto' && !s.params.loopedSlides) s.params.loopedSlides = slides.length;\n        \n            s.loopedSlides = parseInt(s.params.loopedSlides || s.params.slidesPerView, 10);\n            s.loopedSlides = s.loopedSlides + s.params.loopAdditionalSlides;\n            if (s.loopedSlides > slides.length) {\n                s.loopedSlides = slides.length;\n            }\n        \n            var prependSlides = [], appendSlides = [], i;\n            slides.each(function (index, el) {\n                var slide = $(this);\n                if (index < s.loopedSlides) appendSlides.push(el);\n                if (index < slides.length && index >= slides.length - s.loopedSlides) prependSlides.push(el);\n                slide.attr('data-swiper-slide-index', index);\n            });\n            for (i = 0; i < appendSlides.length; i++) {\n                s.wrapper.append($(appendSlides[i].cloneNode(true)).addClass(s.params.slideDuplicateClass));\n            }\n            for (i = prependSlides.length - 1; i >= 0; i--) {\n                s.wrapper.prepend($(prependSlides[i].cloneNode(true)).addClass(s.params.slideDuplicateClass));\n            }\n        };\n        s.destroyLoop = function () {\n            s.wrapper.children('.' + s.params.slideClass + '.' + s.params.slideDuplicateClass).remove();\n            s.slides.removeAttr('data-swiper-slide-index');\n        };\n        s.reLoop = function (updatePosition) {\n            var oldIndex = s.activeIndex - s.loopedSlides;\n            s.destroyLoop();\n            s.createLoop();\n            s.updateSlidesSize();\n            if (updatePosition) {\n                s.slideTo(oldIndex + s.loopedSlides, 0, false);\n            }\n        \n        };\n        s.fixLoop = function () {\n            var newIndex;\n            //Fix For Negative Oversliding\n            if (s.activeIndex < s.loopedSlides) {\n                newIndex = s.slides.length - s.loopedSlides * 3 + s.activeIndex;\n                newIndex = newIndex + s.loopedSlides;\n                s.slideTo(newIndex, 0, false, true);\n            }\n            //Fix For Positive Oversliding\n            else if ((s.params.slidesPerView === 'auto' && s.activeIndex >= s.loopedSlides * 2) || (s.activeIndex > s.slides.length - s.params.slidesPerView * 2)) {\n                newIndex = -s.slides.length + s.activeIndex + s.loopedSlides;\n                newIndex = newIndex + s.loopedSlides;\n                s.slideTo(newIndex, 0, false, true);\n            }\n        };\n        /*=========================\n          Append/Prepend/Remove Slides\n          ===========================*/\n        s.appendSlide = function (slides) {\n            if (s.params.loop) {\n                s.destroyLoop();\n            }\n            if (typeof slides === 'object' && slides.length) {\n                for (var i = 0; i < slides.length; i++) {\n                    if (slides[i]) s.wrapper.append(slides[i]);\n                }\n            }\n            else {\n                s.wrapper.append(slides);\n            }\n            if (s.params.loop) {\n                s.createLoop();\n            }\n            if (!(s.params.observer && s.support.observer)) {\n                s.update(true);\n            }\n        };\n        s.prependSlide = function (slides) {\n            if (s.params.loop) {\n                s.destroyLoop();\n            }\n            var newActiveIndex = s.activeIndex + 1;\n            if (typeof slides === 'object' && slides.length) {\n                for (var i = 0; i < slides.length; i++) {\n                    if (slides[i]) s.wrapper.prepend(slides[i]);\n                }\n                newActiveIndex = s.activeIndex + slides.length;\n            }\n            else {\n                s.wrapper.prepend(slides);\n            }\n            if (s.params.loop) {\n                s.createLoop();\n            }\n            if (!(s.params.observer && s.support.observer)) {\n                s.update(true);\n            }\n            s.slideTo(newActiveIndex, 0, false);\n        };\n        s.removeSlide = function (slidesIndexes) {\n            if (s.params.loop) {\n                s.destroyLoop();\n                s.slides = s.wrapper.children('.' + s.params.slideClass);\n            }\n            var newActiveIndex = s.activeIndex,\n                indexToRemove;\n            if (typeof slidesIndexes === 'object' && slidesIndexes.length) {\n                for (var i = 0; i < slidesIndexes.length; i++) {\n                    indexToRemove = slidesIndexes[i];\n                    if (s.slides[indexToRemove]) s.slides.eq(indexToRemove).remove();\n                    if (indexToRemove < newActiveIndex) newActiveIndex--;\n                }\n                newActiveIndex = Math.max(newActiveIndex, 0);\n            }\n            else {\n                indexToRemove = slidesIndexes;\n                if (s.slides[indexToRemove]) s.slides.eq(indexToRemove).remove();\n                if (indexToRemove < newActiveIndex) newActiveIndex--;\n                newActiveIndex = Math.max(newActiveIndex, 0);\n            }\n        \n            if (s.params.loop) {\n                s.createLoop();\n            }\n        \n            if (!(s.params.observer && s.support.observer)) {\n                s.update(true);\n            }\n            if (s.params.loop) {\n                s.slideTo(newActiveIndex + s.loopedSlides, 0, false);\n            }\n            else {\n                s.slideTo(newActiveIndex, 0, false);\n            }\n        \n        };\n        s.removeAllSlides = function () {\n            var slidesIndexes = [];\n            for (var i = 0; i < s.slides.length; i++) {\n                slidesIndexes.push(i);\n            }\n            s.removeSlide(slidesIndexes);\n        };\n        \n\n        /*=========================\n          Effects\n          ===========================*/\n        s.effects = {\n            fade: {\n                setTranslate: function () {\n                    for (var i = 0; i < s.slides.length; i++) {\n                        var slide = s.slides.eq(i);\n                        var offset = slide[0].swiperSlideOffset;\n                        var tx = -offset;\n                        if (!s.params.virtualTranslate) tx = tx - s.translate;\n                        var ty = 0;\n                        if (!s.isHorizontal()) {\n                            ty = tx;\n                            tx = 0;\n                        }\n                        var slideOpacity = s.params.fade.crossFade ?\n                                Math.max(1 - Math.abs(slide[0].progress), 0) :\n                                1 + Math.min(Math.max(slide[0].progress, -1), 0);\n                        slide\n                            .css({\n                                opacity: slideOpacity\n                            })\n                            .transform('translate3d(' + tx + 'px, ' + ty + 'px, 0px)');\n        \n                    }\n        \n                },\n                setTransition: function (duration) {\n                    s.slides.transition(duration);\n                    if (s.params.virtualTranslate && duration !== 0) {\n                        var eventTriggered = false;\n                        s.slides.transitionEnd(function () {\n                            if (eventTriggered) return;\n                            if (!s) return;\n                            eventTriggered = true;\n                            s.animating = false;\n                            var triggerEvents = ['webkitTransitionEnd', 'transitionend', 'oTransitionEnd', 'MSTransitionEnd', 'msTransitionEnd'];\n                            for (var i = 0; i < triggerEvents.length; i++) {\n                                s.wrapper.trigger(triggerEvents[i]);\n                            }\n                        });\n                    }\n                }\n            },\n            flip: {\n                setTranslate: function () {\n                    for (var i = 0; i < s.slides.length; i++) {\n                        var slide = s.slides.eq(i);\n                        var progress = slide[0].progress;\n                        if (s.params.flip.limitRotation) {\n                            progress = Math.max(Math.min(slide[0].progress, 1), -1);\n                        }\n                        var offset = slide[0].swiperSlideOffset;\n                        var rotate = -180 * progress,\n                            rotateY = rotate,\n                            rotateX = 0,\n                            tx = -offset,\n                            ty = 0;\n                        if (!s.isHorizontal()) {\n                            ty = tx;\n                            tx = 0;\n                            rotateX = -rotateY;\n                            rotateY = 0;\n                        }\n                        else if (s.rtl) {\n                            rotateY = -rotateY;\n                        }\n        \n                        slide[0].style.zIndex = -Math.abs(Math.round(progress)) + s.slides.length;\n        \n                        if (s.params.flip.slideShadows) {\n                            //Set shadows\n                            var shadowBefore = s.isHorizontal() ? slide.find('.swiper-slide-shadow-left') : slide.find('.swiper-slide-shadow-top');\n                            var shadowAfter = s.isHorizontal() ? slide.find('.swiper-slide-shadow-right') : slide.find('.swiper-slide-shadow-bottom');\n                            if (shadowBefore.length === 0) {\n                                shadowBefore = $('<div class=\"swiper-slide-shadow-' + (s.isHorizontal() ? 'left' : 'top') + '\"></div>');\n                                slide.append(shadowBefore);\n                            }\n                            if (shadowAfter.length === 0) {\n                                shadowAfter = $('<div class=\"swiper-slide-shadow-' + (s.isHorizontal() ? 'right' : 'bottom') + '\"></div>');\n                                slide.append(shadowAfter);\n                            }\n                            if (shadowBefore.length) shadowBefore[0].style.opacity = Math.max(-progress, 0);\n                            if (shadowAfter.length) shadowAfter[0].style.opacity = Math.max(progress, 0);\n                        }\n        \n                        slide\n                            .transform('translate3d(' + tx + 'px, ' + ty + 'px, 0px) rotateX(' + rotateX + 'deg) rotateY(' + rotateY + 'deg)');\n                    }\n                },\n                setTransition: function (duration) {\n                    s.slides.transition(duration).find('.swiper-slide-shadow-top, .swiper-slide-shadow-right, .swiper-slide-shadow-bottom, .swiper-slide-shadow-left').transition(duration);\n                    if (s.params.virtualTranslate && duration !== 0) {\n                        var eventTriggered = false;\n                        s.slides.eq(s.activeIndex).transitionEnd(function () {\n                            if (eventTriggered) return;\n                            if (!s) return;\n                            if (!$(this).hasClass(s.params.slideActiveClass)) return;\n                            eventTriggered = true;\n                            s.animating = false;\n                            var triggerEvents = ['webkitTransitionEnd', 'transitionend', 'oTransitionEnd', 'MSTransitionEnd', 'msTransitionEnd'];\n                            for (var i = 0; i < triggerEvents.length; i++) {\n                                s.wrapper.trigger(triggerEvents[i]);\n                            }\n                        });\n                    }\n                }\n            },\n            cube: {\n                setTranslate: function () {\n                    var wrapperRotate = 0, cubeShadow;\n                    if (s.params.cube.shadow) {\n                        if (s.isHorizontal()) {\n                            cubeShadow = s.wrapper.find('.swiper-cube-shadow');\n                            if (cubeShadow.length === 0) {\n                                cubeShadow = $('<div class=\"swiper-cube-shadow\"></div>');\n                                s.wrapper.append(cubeShadow);\n                            }\n                            cubeShadow.css({height: s.width + 'px'});\n                        }\n                        else {\n                            cubeShadow = s.container.find('.swiper-cube-shadow');\n                            if (cubeShadow.length === 0) {\n                                cubeShadow = $('<div class=\"swiper-cube-shadow\"></div>');\n                                s.container.append(cubeShadow);\n                            }\n                        }\n                    }\n                    for (var i = 0; i < s.slides.length; i++) {\n                        var slide = s.slides.eq(i);\n                        var slideAngle = i * 90;\n                        var round = Math.floor(slideAngle / 360);\n                        if (s.rtl) {\n                            slideAngle = -slideAngle;\n                            round = Math.floor(-slideAngle / 360);\n                        }\n                        var progress = Math.max(Math.min(slide[0].progress, 1), -1);\n                        var tx = 0, ty = 0, tz = 0;\n                        if (i % 4 === 0) {\n                            tx = - round * 4 * s.size;\n                            tz = 0;\n                        }\n                        else if ((i - 1) % 4 === 0) {\n                            tx = 0;\n                            tz = - round * 4 * s.size;\n                        }\n                        else if ((i - 2) % 4 === 0) {\n                            tx = s.size + round * 4 * s.size;\n                            tz = s.size;\n                        }\n                        else if ((i - 3) % 4 === 0) {\n                            tx = - s.size;\n                            tz = 3 * s.size + s.size * 4 * round;\n                        }\n                        if (s.rtl) {\n                            tx = -tx;\n                        }\n        \n                        if (!s.isHorizontal()) {\n                            ty = tx;\n                            tx = 0;\n                        }\n        \n                        var transform = 'rotateX(' + (s.isHorizontal() ? 0 : -slideAngle) + 'deg) rotateY(' + (s.isHorizontal() ? slideAngle : 0) + 'deg) translate3d(' + tx + 'px, ' + ty + 'px, ' + tz + 'px)';\n                        if (progress <= 1 && progress > -1) {\n                            wrapperRotate = i * 90 + progress * 90;\n                            if (s.rtl) wrapperRotate = -i * 90 - progress * 90;\n                        }\n                        slide.transform(transform);\n                        if (s.params.cube.slideShadows) {\n                            //Set shadows\n                            var shadowBefore = s.isHorizontal() ? slide.find('.swiper-slide-shadow-left') : slide.find('.swiper-slide-shadow-top');\n                            var shadowAfter = s.isHorizontal() ? slide.find('.swiper-slide-shadow-right') : slide.find('.swiper-slide-shadow-bottom');\n                            if (shadowBefore.length === 0) {\n                                shadowBefore = $('<div class=\"swiper-slide-shadow-' + (s.isHorizontal() ? 'left' : 'top') + '\"></div>');\n                                slide.append(shadowBefore);\n                            }\n                            if (shadowAfter.length === 0) {\n                                shadowAfter = $('<div class=\"swiper-slide-shadow-' + (s.isHorizontal() ? 'right' : 'bottom') + '\"></div>');\n                                slide.append(shadowAfter);\n                            }\n                            if (shadowBefore.length) shadowBefore[0].style.opacity = Math.max(-progress, 0);\n                            if (shadowAfter.length) shadowAfter[0].style.opacity = Math.max(progress, 0);\n                        }\n                    }\n                    s.wrapper.css({\n                        '-webkit-transform-origin': '50% 50% -' + (s.size / 2) + 'px',\n                        '-moz-transform-origin': '50% 50% -' + (s.size / 2) + 'px',\n                        '-ms-transform-origin': '50% 50% -' + (s.size / 2) + 'px',\n                        'transform-origin': '50% 50% -' + (s.size / 2) + 'px'\n                    });\n        \n                    if (s.params.cube.shadow) {\n                        if (s.isHorizontal()) {\n                            cubeShadow.transform('translate3d(0px, ' + (s.width / 2 + s.params.cube.shadowOffset) + 'px, ' + (-s.width / 2) + 'px) rotateX(90deg) rotateZ(0deg) scale(' + (s.params.cube.shadowScale) + ')');\n                        }\n                        else {\n                            var shadowAngle = Math.abs(wrapperRotate) - Math.floor(Math.abs(wrapperRotate) / 90) * 90;\n                            var multiplier = 1.5 - (Math.sin(shadowAngle * 2 * Math.PI / 360) / 2 + Math.cos(shadowAngle * 2 * Math.PI / 360) / 2);\n                            var scale1 = s.params.cube.shadowScale,\n                                scale2 = s.params.cube.shadowScale / multiplier,\n                                offset = s.params.cube.shadowOffset;\n                            cubeShadow.transform('scale3d(' + scale1 + ', 1, ' + scale2 + ') translate3d(0px, ' + (s.height / 2 + offset) + 'px, ' + (-s.height / 2 / scale2) + 'px) rotateX(-90deg)');\n                        }\n                    }\n                    var zFactor = (s.isSafari || s.isUiWebView) ? (-s.size / 2) : 0;\n                    s.wrapper.transform('translate3d(0px,0,' + zFactor + 'px) rotateX(' + (s.isHorizontal() ? 0 : wrapperRotate) + 'deg) rotateY(' + (s.isHorizontal() ? -wrapperRotate : 0) + 'deg)');\n                },\n                setTransition: function (duration) {\n                    s.slides.transition(duration).find('.swiper-slide-shadow-top, .swiper-slide-shadow-right, .swiper-slide-shadow-bottom, .swiper-slide-shadow-left').transition(duration);\n                    if (s.params.cube.shadow && !s.isHorizontal()) {\n                        s.container.find('.swiper-cube-shadow').transition(duration);\n                    }\n                }\n            },\n            coverflow: {\n                setTranslate: function () {\n                    var transform = s.translate;\n                    var center = s.isHorizontal() ? -transform + s.width / 2 : -transform + s.height / 2;\n                    var rotate = s.isHorizontal() ? s.params.coverflow.rotate: -s.params.coverflow.rotate;\n                    var translate = s.params.coverflow.depth;\n                    //Each slide offset from center\n                    for (var i = 0, length = s.slides.length; i < length; i++) {\n                        var slide = s.slides.eq(i);\n                        var slideSize = s.slidesSizesGrid[i];\n                        var slideOffset = slide[0].swiperSlideOffset;\n                        var offsetMultiplier = (center - slideOffset - slideSize / 2) / slideSize * s.params.coverflow.modifier;\n        \n                        var rotateY = s.isHorizontal() ? rotate * offsetMultiplier : 0;\n                        var rotateX = s.isHorizontal() ? 0 : rotate * offsetMultiplier;\n                        // var rotateZ = 0\n                        var translateZ = -translate * Math.abs(offsetMultiplier);\n        \n                        var translateY = s.isHorizontal() ? 0 : s.params.coverflow.stretch * (offsetMultiplier);\n                        var translateX = s.isHorizontal() ? s.params.coverflow.stretch * (offsetMultiplier) : 0;\n        \n                        //Fix for ultra small values\n                        if (Math.abs(translateX) < 0.001) translateX = 0;\n                        if (Math.abs(translateY) < 0.001) translateY = 0;\n                        if (Math.abs(translateZ) < 0.001) translateZ = 0;\n                        if (Math.abs(rotateY) < 0.001) rotateY = 0;\n                        if (Math.abs(rotateX) < 0.001) rotateX = 0;\n        \n                        var slideTransform = 'translate3d(' + translateX + 'px,' + translateY + 'px,' + translateZ + 'px)  rotateX(' + rotateX + 'deg) rotateY(' + rotateY + 'deg)';\n        \n                        slide.transform(slideTransform);\n                        slide[0].style.zIndex = -Math.abs(Math.round(offsetMultiplier)) + 1;\n                        if (s.params.coverflow.slideShadows) {\n                            //Set shadows\n                            var shadowBefore = s.isHorizontal() ? slide.find('.swiper-slide-shadow-left') : slide.find('.swiper-slide-shadow-top');\n                            var shadowAfter = s.isHorizontal() ? slide.find('.swiper-slide-shadow-right') : slide.find('.swiper-slide-shadow-bottom');\n                            if (shadowBefore.length === 0) {\n                                shadowBefore = $('<div class=\"swiper-slide-shadow-' + (s.isHorizontal() ? 'left' : 'top') + '\"></div>');\n                                slide.append(shadowBefore);\n                            }\n                            if (shadowAfter.length === 0) {\n                                shadowAfter = $('<div class=\"swiper-slide-shadow-' + (s.isHorizontal() ? 'right' : 'bottom') + '\"></div>');\n                                slide.append(shadowAfter);\n                            }\n                            if (shadowBefore.length) shadowBefore[0].style.opacity = offsetMultiplier > 0 ? offsetMultiplier : 0;\n                            if (shadowAfter.length) shadowAfter[0].style.opacity = (-offsetMultiplier) > 0 ? -offsetMultiplier : 0;\n                        }\n                    }\n        \n                    //Set correct perspective for IE10\n                    if (s.browser.ie) {\n                        var ws = s.wrapper[0].style;\n                        ws.perspectiveOrigin = center + 'px 50%';\n                    }\n                },\n                setTransition: function (duration) {\n                    s.slides.transition(duration).find('.swiper-slide-shadow-top, .swiper-slide-shadow-right, .swiper-slide-shadow-bottom, .swiper-slide-shadow-left').transition(duration);\n                }\n            }\n        };\n\n        /*=========================\n          Images Lazy Loading\n          ===========================*/\n        s.lazy = {\n            initialImageLoaded: false,\n            loadImageInSlide: function (index, loadInDuplicate) {\n                if (typeof index === 'undefined') return;\n                if (typeof loadInDuplicate === 'undefined') loadInDuplicate = true;\n                if (s.slides.length === 0) return;\n        \n                var slide = s.slides.eq(index);\n                var img = slide.find('.swiper-lazy:not(.swiper-lazy-loaded):not(.swiper-lazy-loading)');\n                if (slide.hasClass('swiper-lazy') && !slide.hasClass('swiper-lazy-loaded') && !slide.hasClass('swiper-lazy-loading')) {\n                    img = img.add(slide[0]);\n                }\n                if (img.length === 0) return;\n        \n                img.each(function () {\n                    var _img = $(this);\n                    _img.addClass('swiper-lazy-loading');\n                    var background = _img.attr('data-background');\n                    var src = _img.attr('data-src'),\n                        srcset = _img.attr('data-srcset');\n                    s.loadImage(_img[0], (src || background), srcset, false, function () {\n                        if (background) {\n                            _img.css('background-image', 'url(\"' + background + '\")');\n                            _img.removeAttr('data-background');\n                        }\n                        else {\n                            if (srcset) {\n                                _img.attr('srcset', srcset);\n                                _img.removeAttr('data-srcset');\n                            }\n                            if (src) {\n                                _img.attr('src', src);\n                                _img.removeAttr('data-src');\n                            }\n        \n                        }\n        \n                        _img.addClass('swiper-lazy-loaded').removeClass('swiper-lazy-loading');\n                        slide.find('.swiper-lazy-preloader, .preloader').remove();\n                        if (s.params.loop && loadInDuplicate) {\n                            var slideOriginalIndex = slide.attr('data-swiper-slide-index');\n                            if (slide.hasClass(s.params.slideDuplicateClass)) {\n                                var originalSlide = s.wrapper.children('[data-swiper-slide-index=\"' + slideOriginalIndex + '\"]:not(.' + s.params.slideDuplicateClass + ')');\n                                s.lazy.loadImageInSlide(originalSlide.index(), false);\n                            }\n                            else {\n                                var duplicatedSlide = s.wrapper.children('.' + s.params.slideDuplicateClass + '[data-swiper-slide-index=\"' + slideOriginalIndex + '\"]');\n                                s.lazy.loadImageInSlide(duplicatedSlide.index(), false);\n                            }\n                        }\n                        s.emit('onLazyImageReady', s, slide[0], _img[0]);\n                    });\n        \n                    s.emit('onLazyImageLoad', s, slide[0], _img[0]);\n                });\n        \n            },\n            load: function () {\n                var i;\n                if (s.params.watchSlidesVisibility) {\n                    s.wrapper.children('.' + s.params.slideVisibleClass).each(function () {\n                        s.lazy.loadImageInSlide($(this).index());\n                    });\n                }\n                else {\n                    if (s.params.slidesPerView > 1) {\n                        for (i = s.activeIndex; i < s.activeIndex + s.params.slidesPerView ; i++) {\n                            if (s.slides[i]) s.lazy.loadImageInSlide(i);\n                        }\n                    }\n                    else {\n                        s.lazy.loadImageInSlide(s.activeIndex);\n                    }\n                }\n                if (s.params.lazyLoadingInPrevNext) {\n                    if (s.params.slidesPerView > 1 || (s.params.lazyLoadingInPrevNextAmount && s.params.lazyLoadingInPrevNextAmount > 1)) {\n                        var amount = s.params.lazyLoadingInPrevNextAmount;\n                        var spv = s.params.slidesPerView;\n                        var maxIndex = Math.min(s.activeIndex + spv + Math.max(amount, spv), s.slides.length);\n                        var minIndex = Math.max(s.activeIndex - Math.max(spv, amount), 0);\n                        // Next Slides\n                        for (i = s.activeIndex + s.params.slidesPerView; i < maxIndex; i++) {\n                            if (s.slides[i]) s.lazy.loadImageInSlide(i);\n                        }\n                        // Prev Slides\n                        for (i = minIndex; i < s.activeIndex ; i++) {\n                            if (s.slides[i]) s.lazy.loadImageInSlide(i);\n                        }\n                    }\n                    else {\n                        var nextSlide = s.wrapper.children('.' + s.params.slideNextClass);\n                        if (nextSlide.length > 0) s.lazy.loadImageInSlide(nextSlide.index());\n        \n                        var prevSlide = s.wrapper.children('.' + s.params.slidePrevClass);\n                        if (prevSlide.length > 0) s.lazy.loadImageInSlide(prevSlide.index());\n                    }\n                }\n            },\n            onTransitionStart: function () {\n                if (s.params.lazyLoading) {\n                    if (s.params.lazyLoadingOnTransitionStart || (!s.params.lazyLoadingOnTransitionStart && !s.lazy.initialImageLoaded)) {\n                        s.lazy.load();\n                    }\n                }\n            },\n            onTransitionEnd: function () {\n                if (s.params.lazyLoading && !s.params.lazyLoadingOnTransitionStart) {\n                    s.lazy.load();\n                }\n            }\n        };\n        \n\n        /*=========================\n          Scrollbar\n          ===========================*/\n        s.scrollbar = {\n            isTouched: false,\n            setDragPosition: function (e) {\n                var sb = s.scrollbar;\n                var x = 0, y = 0;\n                var translate;\n                var pointerPosition = s.isHorizontal() ?\n                    ((e.type === 'touchstart' || e.type === 'touchmove') ? e.targetTouches[0].pageX : e.pageX || e.clientX) :\n                    ((e.type === 'touchstart' || e.type === 'touchmove') ? e.targetTouches[0].pageY : e.pageY || e.clientY) ;\n                var position = (pointerPosition) - sb.track.offset()[s.isHorizontal() ? 'left' : 'top'] - sb.dragSize / 2;\n                var positionMin = -s.minTranslate() * sb.moveDivider;\n                var positionMax = -s.maxTranslate() * sb.moveDivider;\n                if (position < positionMin) {\n                    position = positionMin;\n                }\n                else if (position > positionMax) {\n                    position = positionMax;\n                }\n                position = -position / sb.moveDivider;\n                s.updateProgress(position);\n                s.setWrapperTranslate(position, true);\n            },\n            dragStart: function (e) {\n                var sb = s.scrollbar;\n                sb.isTouched = true;\n                e.preventDefault();\n                e.stopPropagation();\n        \n                sb.setDragPosition(e);\n                clearTimeout(sb.dragTimeout);\n        \n                sb.track.transition(0);\n                if (s.params.scrollbarHide) {\n                    sb.track.css('opacity', 1);\n                }\n                s.wrapper.transition(100);\n                sb.drag.transition(100);\n                s.emit('onScrollbarDragStart', s);\n            },\n            dragMove: function (e) {\n                var sb = s.scrollbar;\n                if (!sb.isTouched) return;\n                if (e.preventDefault) e.preventDefault();\n                else e.returnValue = false;\n                sb.setDragPosition(e);\n                s.wrapper.transition(0);\n                sb.track.transition(0);\n                sb.drag.transition(0);\n                s.emit('onScrollbarDragMove', s);\n            },\n            dragEnd: function (e) {\n                var sb = s.scrollbar;\n                if (!sb.isTouched) return;\n                sb.isTouched = false;\n                if (s.params.scrollbarHide) {\n                    clearTimeout(sb.dragTimeout);\n                    sb.dragTimeout = setTimeout(function () {\n                        sb.track.css('opacity', 0);\n                        sb.track.transition(400);\n                    }, 1000);\n        \n                }\n                s.emit('onScrollbarDragEnd', s);\n                if (s.params.scrollbarSnapOnRelease) {\n                    s.slideReset();\n                }\n            },\n            enableDraggable: function () {\n                var sb = s.scrollbar;\n                var target = s.support.touch ? sb.track : document;\n                $(sb.track).on(s.touchEvents.start, sb.dragStart);\n                $(target).on(s.touchEvents.move, sb.dragMove);\n                $(target).on(s.touchEvents.end, sb.dragEnd);\n            },\n            disableDraggable: function () {\n                var sb = s.scrollbar;\n                var target = s.support.touch ? sb.track : document;\n                $(sb.track).off(s.touchEvents.start, sb.dragStart);\n                $(target).off(s.touchEvents.move, sb.dragMove);\n                $(target).off(s.touchEvents.end, sb.dragEnd);\n            },\n            set: function () {\n                if (!s.params.scrollbar) return;\n                var sb = s.scrollbar;\n                sb.track = $(s.params.scrollbar);\n                if (s.params.uniqueNavElements && typeof s.params.scrollbar === 'string' && sb.track.length > 1 && s.container.find(s.params.scrollbar).length === 1) {\n                    sb.track = s.container.find(s.params.scrollbar);\n                }\n                sb.drag = sb.track.find('.swiper-scrollbar-drag');\n                if (sb.drag.length === 0) {\n                    sb.drag = $('<div class=\"swiper-scrollbar-drag\"></div>');\n                    sb.track.append(sb.drag);\n                }\n                sb.drag[0].style.width = '';\n                sb.drag[0].style.height = '';\n                sb.trackSize = s.isHorizontal() ? sb.track[0].offsetWidth : sb.track[0].offsetHeight;\n        \n                sb.divider = s.size / s.virtualSize;\n                sb.moveDivider = sb.divider * (sb.trackSize / s.size);\n                sb.dragSize = sb.trackSize * sb.divider;\n        \n                if (s.isHorizontal()) {\n                    sb.drag[0].style.width = sb.dragSize + 'px';\n                }\n                else {\n                    sb.drag[0].style.height = sb.dragSize + 'px';\n                }\n        \n                if (sb.divider >= 1) {\n                    sb.track[0].style.display = 'none';\n                }\n                else {\n                    sb.track[0].style.display = '';\n                }\n                if (s.params.scrollbarHide) {\n                    sb.track[0].style.opacity = 0;\n                }\n            },\n            setTranslate: function () {\n                if (!s.params.scrollbar) return;\n                var diff;\n                var sb = s.scrollbar;\n                var translate = s.translate || 0;\n                var newPos;\n        \n                var newSize = sb.dragSize;\n                newPos = (sb.trackSize - sb.dragSize) * s.progress;\n                if (s.rtl && s.isHorizontal()) {\n                    newPos = -newPos;\n                    if (newPos > 0) {\n                        newSize = sb.dragSize - newPos;\n                        newPos = 0;\n                    }\n                    else if (-newPos + sb.dragSize > sb.trackSize) {\n                        newSize = sb.trackSize + newPos;\n                    }\n                }\n                else {\n                    if (newPos < 0) {\n                        newSize = sb.dragSize + newPos;\n                        newPos = 0;\n                    }\n                    else if (newPos + sb.dragSize > sb.trackSize) {\n                        newSize = sb.trackSize - newPos;\n                    }\n                }\n                if (s.isHorizontal()) {\n                    if (s.support.transforms3d) {\n                        sb.drag.transform('translate3d(' + (newPos) + 'px, 0, 0)');\n                    }\n                    else {\n                        sb.drag.transform('translateX(' + (newPos) + 'px)');\n                    }\n                    sb.drag[0].style.width = newSize + 'px';\n                }\n                else {\n                    if (s.support.transforms3d) {\n                        sb.drag.transform('translate3d(0px, ' + (newPos) + 'px, 0)');\n                    }\n                    else {\n                        sb.drag.transform('translateY(' + (newPos) + 'px)');\n                    }\n                    sb.drag[0].style.height = newSize + 'px';\n                }\n                if (s.params.scrollbarHide) {\n                    clearTimeout(sb.timeout);\n                    sb.track[0].style.opacity = 1;\n                    sb.timeout = setTimeout(function () {\n                        sb.track[0].style.opacity = 0;\n                        sb.track.transition(400);\n                    }, 1000);\n                }\n            },\n            setTransition: function (duration) {\n                if (!s.params.scrollbar) return;\n                s.scrollbar.drag.transition(duration);\n            }\n        };\n\n        /*=========================\n          Controller\n          ===========================*/\n        s.controller = {\n            LinearSpline: function (x, y) {\n                this.x = x;\n                this.y = y;\n                this.lastIndex = x.length - 1;\n                // Given an x value (x2), return the expected y2 value:\n                // (x1,y1) is the known point before given value,\n                // (x3,y3) is the known point after given value.\n                var i1, i3;\n                var l = this.x.length;\n        \n                this.interpolate = function (x2) {\n                    if (!x2) return 0;\n        \n                    // Get the indexes of x1 and x3 (the array indexes before and after given x2):\n                    i3 = binarySearch(this.x, x2);\n                    i1 = i3 - 1;\n        \n                    // We have our indexes i1 & i3, so we can calculate already:\n                    // y2 := ((x2−x1) × (y3−y1)) ÷ (x3−x1) + y1\n                    return ((x2 - this.x[i1]) * (this.y[i3] - this.y[i1])) / (this.x[i3] - this.x[i1]) + this.y[i1];\n                };\n        \n                var binarySearch = (function() {\n                    var maxIndex, minIndex, guess;\n                    return function(array, val) {\n                        minIndex = -1;\n                        maxIndex = array.length;\n                        while (maxIndex - minIndex > 1)\n                            if (array[guess = maxIndex + minIndex >> 1] <= val) {\n                                minIndex = guess;\n                            } else {\n                                maxIndex = guess;\n                            }\n                        return maxIndex;\n                    };\n                })();\n            },\n            //xxx: for now i will just save one spline function to to\n            getInterpolateFunction: function(c){\n                if(!s.controller.spline) s.controller.spline = s.params.loop ?\n                    new s.controller.LinearSpline(s.slidesGrid, c.slidesGrid) :\n                    new s.controller.LinearSpline(s.snapGrid, c.snapGrid);\n            },\n            setTranslate: function (translate, byController) {\n               var controlled = s.params.control;\n               var multiplier, controlledTranslate;\n               function setControlledTranslate(c) {\n                    // this will create an Interpolate function based on the snapGrids\n                    // x is the Grid of the scrolled scroller and y will be the controlled scroller\n                    // it makes sense to create this only once and recall it for the interpolation\n                    // the function does a lot of value caching for performance\n                    translate = c.rtl && c.params.direction === 'horizontal' ? -s.translate : s.translate;\n                    if (s.params.controlBy === 'slide') {\n                        s.controller.getInterpolateFunction(c);\n                        // i am not sure why the values have to be multiplicated this way, tried to invert the snapGrid\n                        // but it did not work out\n                        controlledTranslate = -s.controller.spline.interpolate(-translate);\n                    }\n        \n                    if(!controlledTranslate || s.params.controlBy === 'container'){\n                        multiplier = (c.maxTranslate() - c.minTranslate()) / (s.maxTranslate() - s.minTranslate());\n                        controlledTranslate = (translate - s.minTranslate()) * multiplier + c.minTranslate();\n                    }\n        \n                    if (s.params.controlInverse) {\n                        controlledTranslate = c.maxTranslate() - controlledTranslate;\n                    }\n                    c.updateProgress(controlledTranslate);\n                    c.setWrapperTranslate(controlledTranslate, false, s);\n                    c.updateActiveIndex();\n               }\n               if (s.isArray(controlled)) {\n                   for (var i = 0; i < controlled.length; i++) {\n                       if (controlled[i] !== byController && controlled[i] instanceof Swiper) {\n                           setControlledTranslate(controlled[i]);\n                       }\n                   }\n               }\n               else if (controlled instanceof Swiper && byController !== controlled) {\n        \n                   setControlledTranslate(controlled);\n               }\n            },\n            setTransition: function (duration, byController) {\n                var controlled = s.params.control;\n                var i;\n                function setControlledTransition(c) {\n                    c.setWrapperTransition(duration, s);\n                    if (duration !== 0) {\n                        c.onTransitionStart();\n                        c.wrapper.transitionEnd(function(){\n                            if (!controlled) return;\n                            if (c.params.loop && s.params.controlBy === 'slide') {\n                                c.fixLoop();\n                            }\n                            c.onTransitionEnd();\n        \n                        });\n                    }\n                }\n                if (s.isArray(controlled)) {\n                    for (i = 0; i < controlled.length; i++) {\n                        if (controlled[i] !== byController && controlled[i] instanceof Swiper) {\n                            setControlledTransition(controlled[i]);\n                        }\n                    }\n                }\n                else if (controlled instanceof Swiper && byController !== controlled) {\n                    setControlledTransition(controlled);\n                }\n            }\n        };\n\n        /*=========================\n          Hash Navigation\n          ===========================*/\n        s.hashnav = {\n            init: function () {\n                if (!s.params.hashnav) return;\n                s.hashnav.initialized = true;\n                var hash = document.location.hash.replace('#', '');\n                if (!hash) return;\n                var speed = 0;\n                for (var i = 0, length = s.slides.length; i < length; i++) {\n                    var slide = s.slides.eq(i);\n                    var slideHash = slide.attr('data-hash');\n                    if (slideHash === hash && !slide.hasClass(s.params.slideDuplicateClass)) {\n                        var index = slide.index();\n                        s.slideTo(index, speed, s.params.runCallbacksOnInit, true);\n                    }\n                }\n            },\n            setHash: function () {\n                if (!s.hashnav.initialized || !s.params.hashnav) return;\n                document.location.hash = s.slides.eq(s.activeIndex).attr('data-hash') || '';\n            }\n        };\n\n        /*=========================\n          Keyboard Control\n          ===========================*/\n        function handleKeyboard(e) {\n            if (e.originalEvent) e = e.originalEvent; //jquery fix\n            var kc = e.keyCode || e.charCode;\n            // Directions locks\n            if (!s.params.allowSwipeToNext && (s.isHorizontal() && kc === 39 || !s.isHorizontal() && kc === 40)) {\n                return false;\n            }\n            if (!s.params.allowSwipeToPrev && (s.isHorizontal() && kc === 37 || !s.isHorizontal() && kc === 38)) {\n                return false;\n            }\n            if (e.shiftKey || e.altKey || e.ctrlKey || e.metaKey) {\n                return;\n            }\n            if (document.activeElement && document.activeElement.nodeName && (document.activeElement.nodeName.toLowerCase() === 'input' || document.activeElement.nodeName.toLowerCase() === 'textarea')) {\n                return;\n            }\n            if (kc === 37 || kc === 39 || kc === 38 || kc === 40) {\n                var inView = false;\n                //Check that swiper should be inside of visible area of window\n                if (s.container.parents('.swiper-slide').length > 0 && s.container.parents('.swiper-slide-active').length === 0) {\n                    return;\n                }\n                var windowScroll = {\n                    left: window.pageXOffset,\n                    top: window.pageYOffset\n                };\n                var windowWidth = window.innerWidth;\n                var windowHeight = window.innerHeight;\n                var swiperOffset = s.container.offset();\n                if (s.rtl) swiperOffset.left = swiperOffset.left - s.container[0].scrollLeft;\n                var swiperCoord = [\n                    [swiperOffset.left, swiperOffset.top],\n                    [swiperOffset.left + s.width, swiperOffset.top],\n                    [swiperOffset.left, swiperOffset.top + s.height],\n                    [swiperOffset.left + s.width, swiperOffset.top + s.height]\n                ];\n                for (var i = 0; i < swiperCoord.length; i++) {\n                    var point = swiperCoord[i];\n                    if (\n                        point[0] >= windowScroll.left && point[0] <= windowScroll.left + windowWidth &&\n                        point[1] >= windowScroll.top && point[1] <= windowScroll.top + windowHeight\n                    ) {\n                        inView = true;\n                    }\n        \n                }\n                if (!inView) return;\n            }\n            if (s.isHorizontal()) {\n                if (kc === 37 || kc === 39) {\n                    if (e.preventDefault) e.preventDefault();\n                    else e.returnValue = false;\n                }\n                if ((kc === 39 && !s.rtl) || (kc === 37 && s.rtl)) s.slideNext();\n                if ((kc === 37 && !s.rtl) || (kc === 39 && s.rtl)) s.slidePrev();\n            }\n            else {\n                if (kc === 38 || kc === 40) {\n                    if (e.preventDefault) e.preventDefault();\n                    else e.returnValue = false;\n                }\n                if (kc === 40) s.slideNext();\n                if (kc === 38) s.slidePrev();\n            }\n        }\n        s.disableKeyboardControl = function () {\n            s.params.keyboardControl = false;\n            $(document).off('keydown', handleKeyboard);\n        };\n        s.enableKeyboardControl = function () {\n            s.params.keyboardControl = true;\n            $(document).on('keydown', handleKeyboard);\n        };\n        \n\n        /*=========================\n          Mousewheel Control\n          ===========================*/\n        s.mousewheel = {\n            event: false,\n            lastScrollTime: (new window.Date()).getTime()\n        };\n        if (s.params.mousewheelControl) {\n            try {\n                new window.WheelEvent('wheel');\n                s.mousewheel.event = 'wheel';\n            } catch (e) {\n                if (window.WheelEvent || (s.container[0] && 'wheel' in s.container[0])) {\n                    s.mousewheel.event = 'wheel';\n                }\n            }\n            if (!s.mousewheel.event && window.WheelEvent) {\n        \n            }\n            if (!s.mousewheel.event && document.onmousewheel !== undefined) {\n                s.mousewheel.event = 'mousewheel';\n            }\n            if (!s.mousewheel.event) {\n                s.mousewheel.event = 'DOMMouseScroll';\n            }\n        }\n        function handleMousewheel(e) {\n            if (e.originalEvent) e = e.originalEvent; //jquery fix\n            var we = s.mousewheel.event;\n            var delta = 0;\n            var rtlFactor = s.rtl ? -1 : 1;\n        \n            //WebKits\n            if (we === 'mousewheel') {\n                if (s.params.mousewheelForceToAxis) {\n                    if (s.isHorizontal()) {\n                        if (Math.abs(e.wheelDeltaX) > Math.abs(e.wheelDeltaY)) delta = e.wheelDeltaX * rtlFactor;\n                        else return;\n                    }\n                    else {\n                        if (Math.abs(e.wheelDeltaY) > Math.abs(e.wheelDeltaX)) delta = e.wheelDeltaY;\n                        else return;\n                    }\n                }\n                else {\n                    delta = Math.abs(e.wheelDeltaX) > Math.abs(e.wheelDeltaY) ? - e.wheelDeltaX * rtlFactor : - e.wheelDeltaY;\n                }\n            }\n            //Old FireFox\n            else if (we === 'DOMMouseScroll') delta = -e.detail;\n            //New FireFox\n            else if (we === 'wheel') {\n                if (s.params.mousewheelForceToAxis) {\n                    if (s.isHorizontal()) {\n                        if (Math.abs(e.deltaX) > Math.abs(e.deltaY)) delta = -e.deltaX * rtlFactor;\n                        else return;\n                    }\n                    else {\n                        if (Math.abs(e.deltaY) > Math.abs(e.deltaX)) delta = -e.deltaY;\n                        else return;\n                    }\n                }\n                else {\n                    delta = Math.abs(e.deltaX) > Math.abs(e.deltaY) ? - e.deltaX * rtlFactor : - e.deltaY;\n                }\n            }\n            if (delta === 0) return;\n        \n            if (s.params.mousewheelInvert) delta = -delta;\n        \n            if (!s.params.freeMode) {\n                if ((new window.Date()).getTime() - s.mousewheel.lastScrollTime > 60) {\n                    if (delta < 0) {\n                        if ((!s.isEnd || s.params.loop) && !s.animating) s.slideNext();\n                        else if (s.params.mousewheelReleaseOnEdges) return true;\n                    }\n                    else {\n                        if ((!s.isBeginning || s.params.loop) && !s.animating) s.slidePrev();\n                        else if (s.params.mousewheelReleaseOnEdges) return true;\n                    }\n                }\n                s.mousewheel.lastScrollTime = (new window.Date()).getTime();\n        \n            }\n            else {\n                //Freemode or scrollContainer:\n                var position = s.getWrapperTranslate() + delta * s.params.mousewheelSensitivity;\n                var wasBeginning = s.isBeginning,\n                    wasEnd = s.isEnd;\n        \n                if (position >= s.minTranslate()) position = s.minTranslate();\n                if (position <= s.maxTranslate()) position = s.maxTranslate();\n        \n                s.setWrapperTransition(0);\n                s.setWrapperTranslate(position);\n                s.updateProgress();\n                s.updateActiveIndex();\n        \n                if (!wasBeginning && s.isBeginning || !wasEnd && s.isEnd) {\n                    s.updateClasses();\n                }\n        \n                if (s.params.freeModeSticky) {\n                    clearTimeout(s.mousewheel.timeout);\n                    s.mousewheel.timeout = setTimeout(function () {\n                        s.slideReset();\n                    }, 300);\n                }\n                else {\n                    if (s.params.lazyLoading && s.lazy) {\n                        s.lazy.load();\n                    }\n                }\n        \n                // Return page scroll on edge positions\n                if (position === 0 || position === s.maxTranslate()) return;\n            }\n            if (s.params.autoplay) s.stopAutoplay();\n        \n            if (e.preventDefault) e.preventDefault();\n            else e.returnValue = false;\n            return false;\n        }\n        s.disableMousewheelControl = function () {\n            if (!s.mousewheel.event) return false;\n            s.container.off(s.mousewheel.event, handleMousewheel);\n            return true;\n        };\n        \n        s.enableMousewheelControl = function () {\n            if (!s.mousewheel.event) return false;\n            s.container.on(s.mousewheel.event, handleMousewheel);\n            return true;\n        };\n        \n\n        /*=========================\n          Parallax\n          ===========================*/\n        function setParallaxTransform(el, progress) {\n            el = $(el);\n            var p, pX, pY;\n            var rtlFactor = s.rtl ? -1 : 1;\n        \n            p = el.attr('data-swiper-parallax') || '0';\n            pX = el.attr('data-swiper-parallax-x');\n            pY = el.attr('data-swiper-parallax-y');\n            if (pX || pY) {\n                pX = pX || '0';\n                pY = pY || '0';\n            }\n            else {\n                if (s.isHorizontal()) {\n                    pX = p;\n                    pY = '0';\n                }\n                else {\n                    pY = p;\n                    pX = '0';\n                }\n            }\n        \n            if ((pX).indexOf('%') >= 0) {\n                pX = parseInt(pX, 10) * progress * rtlFactor + '%';\n            }\n            else {\n                pX = pX * progress * rtlFactor + 'px' ;\n            }\n            if ((pY).indexOf('%') >= 0) {\n                pY = parseInt(pY, 10) * progress + '%';\n            }\n            else {\n                pY = pY * progress + 'px' ;\n            }\n        \n            el.transform('translate3d(' + pX + ', ' + pY + ',0px)');\n        }\n        s.parallax = {\n            setTranslate: function () {\n                s.container.children('[data-swiper-parallax], [data-swiper-parallax-x], [data-swiper-parallax-y]').each(function(){\n                    setParallaxTransform(this, s.progress);\n        \n                });\n                s.slides.each(function () {\n                    var slide = $(this);\n                    slide.find('[data-swiper-parallax], [data-swiper-parallax-x], [data-swiper-parallax-y]').each(function () {\n                        var progress = Math.min(Math.max(slide[0].progress, -1), 1);\n                        setParallaxTransform(this, progress);\n                    });\n                });\n            },\n            setTransition: function (duration) {\n                if (typeof duration === 'undefined') duration = s.params.speed;\n                s.container.find('[data-swiper-parallax], [data-swiper-parallax-x], [data-swiper-parallax-y]').each(function(){\n                    var el = $(this);\n                    var parallaxDuration = parseInt(el.attr('data-swiper-parallax-duration'), 10) || duration;\n                    if (duration === 0) parallaxDuration = 0;\n                    el.transition(parallaxDuration);\n                });\n            }\n        };\n        \n\n        /*=========================\n          Plugins API. Collect all and init all plugins\n          ===========================*/\n        s._plugins = [];\n        for (var plugin in s.plugins) {\n            var p = s.plugins[plugin](s, s.params[plugin]);\n            if (p) s._plugins.push(p);\n        }\n        // Method to call all plugins event/method\n        s.callPlugins = function (eventName) {\n            for (var i = 0; i < s._plugins.length; i++) {\n                if (eventName in s._plugins[i]) {\n                    s._plugins[i][eventName](arguments[1], arguments[2], arguments[3], arguments[4], arguments[5]);\n                }\n            }\n        };\n\n        /*=========================\n          Events/Callbacks/Plugins Emitter\n          ===========================*/\n        function normalizeEventName (eventName) {\n            if (eventName.indexOf('on') !== 0) {\n                if (eventName[0] !== eventName[0].toUpperCase()) {\n                    eventName = 'on' + eventName[0].toUpperCase() + eventName.substring(1);\n                }\n                else {\n                    eventName = 'on' + eventName;\n                }\n            }\n            return eventName;\n        }\n        s.emitterEventListeners = {\n        \n        };\n        s.emit = function (eventName) {\n            // Trigger callbacks\n            if (s.params[eventName]) {\n                s.params[eventName](arguments[1], arguments[2], arguments[3], arguments[4], arguments[5]);\n            }\n            var i;\n            // Trigger events\n            if (s.emitterEventListeners[eventName]) {\n                for (i = 0; i < s.emitterEventListeners[eventName].length; i++) {\n                    s.emitterEventListeners[eventName][i](arguments[1], arguments[2], arguments[3], arguments[4], arguments[5]);\n                }\n            }\n            // Trigger plugins\n            if (s.callPlugins) s.callPlugins(eventName, arguments[1], arguments[2], arguments[3], arguments[4], arguments[5]);\n        };\n        s.on = function (eventName, handler) {\n            eventName = normalizeEventName(eventName);\n            if (!s.emitterEventListeners[eventName]) s.emitterEventListeners[eventName] = [];\n            s.emitterEventListeners[eventName].push(handler);\n            return s;\n        };\n        s.off = function (eventName, handler) {\n            var i;\n            eventName = normalizeEventName(eventName);\n            if (typeof handler === 'undefined') {\n                // Remove all handlers for such event\n                s.emitterEventListeners[eventName] = [];\n                return s;\n            }\n            if (!s.emitterEventListeners[eventName] || s.emitterEventListeners[eventName].length === 0) return;\n            for (i = 0; i < s.emitterEventListeners[eventName].length; i++) {\n                if(s.emitterEventListeners[eventName][i] === handler) s.emitterEventListeners[eventName].splice(i, 1);\n            }\n            return s;\n        };\n        s.once = function (eventName, handler) {\n            eventName = normalizeEventName(eventName);\n            var _handler = function () {\n                handler(arguments[0], arguments[1], arguments[2], arguments[3], arguments[4]);\n                s.off(eventName, _handler);\n            };\n            s.on(eventName, _handler);\n            return s;\n        };\n\n        // Accessibility tools\n        s.a11y = {\n            makeFocusable: function ($el) {\n                $el.attr('tabIndex', '0');\n                return $el;\n            },\n            addRole: function ($el, role) {\n                $el.attr('role', role);\n                return $el;\n            },\n        \n            addLabel: function ($el, label) {\n                $el.attr('aria-label', label);\n                return $el;\n            },\n        \n            disable: function ($el) {\n                $el.attr('aria-disabled', true);\n                return $el;\n            },\n        \n            enable: function ($el) {\n                $el.attr('aria-disabled', false);\n                return $el;\n            },\n        \n            onEnterKey: function (event) {\n                if (event.keyCode !== 13) return;\n                if ($(event.target).is(s.params.nextButton)) {\n                    s.onClickNext(event);\n                    if (s.isEnd) {\n                        s.a11y.notify(s.params.lastSlideMessage);\n                    }\n                    else {\n                        s.a11y.notify(s.params.nextSlideMessage);\n                    }\n                }\n                else if ($(event.target).is(s.params.prevButton)) {\n                    s.onClickPrev(event);\n                    if (s.isBeginning) {\n                        s.a11y.notify(s.params.firstSlideMessage);\n                    }\n                    else {\n                        s.a11y.notify(s.params.prevSlideMessage);\n                    }\n                }\n                if ($(event.target).is('.' + s.params.bulletClass)) {\n                    $(event.target)[0].click();\n                }\n            },\n        \n            liveRegion: $('<span class=\"swiper-notification\" aria-live=\"assertive\" aria-atomic=\"true\"></span>'),\n        \n            notify: function (message) {\n                var notification = s.a11y.liveRegion;\n                if (notification.length === 0) return;\n                notification.html('');\n                notification.html(message);\n            },\n            init: function () {\n                // Setup accessibility\n                if (s.params.nextButton && s.nextButton && s.nextButton.length > 0) {\n                    s.a11y.makeFocusable(s.nextButton);\n                    s.a11y.addRole(s.nextButton, 'button');\n                    s.a11y.addLabel(s.nextButton, s.params.nextSlideMessage);\n                }\n                if (s.params.prevButton && s.prevButton && s.prevButton.length > 0) {\n                    s.a11y.makeFocusable(s.prevButton);\n                    s.a11y.addRole(s.prevButton, 'button');\n                    s.a11y.addLabel(s.prevButton, s.params.prevSlideMessage);\n                }\n        \n                $(s.container).append(s.a11y.liveRegion);\n            },\n            initPagination: function () {\n                if (s.params.pagination && s.params.paginationClickable && s.bullets && s.bullets.length) {\n                    s.bullets.each(function () {\n                        var bullet = $(this);\n                        s.a11y.makeFocusable(bullet);\n                        s.a11y.addRole(bullet, 'button');\n                        s.a11y.addLabel(bullet, s.params.paginationBulletMessage.replace(/{{index}}/, bullet.index() + 1));\n                    });\n                }\n            },\n            destroy: function () {\n                if (s.a11y.liveRegion && s.a11y.liveRegion.length > 0) s.a11y.liveRegion.remove();\n            }\n        };\n        \n\n        /*=========================\n          Init/Destroy\n          ===========================*/\n        s.init = function () {\n            if (s.params.loop) s.createLoop();\n            s.updateContainerSize();\n            s.updateSlidesSize();\n            s.updatePagination();\n            if (s.params.scrollbar && s.scrollbar) {\n                s.scrollbar.set();\n                if (s.params.scrollbarDraggable) {\n                    s.scrollbar.enableDraggable();\n                }\n            }\n            if (s.params.effect !== 'slide' && s.effects[s.params.effect]) {\n                if (!s.params.loop) s.updateProgress();\n                s.effects[s.params.effect].setTranslate();\n            }\n            if (s.params.loop) {\n                s.slideTo(s.params.initialSlide + s.loopedSlides, 0, s.params.runCallbacksOnInit);\n            }\n            else {\n                s.slideTo(s.params.initialSlide, 0, s.params.runCallbacksOnInit);\n                if (s.params.initialSlide === 0) {\n                    if (s.parallax && s.params.parallax) s.parallax.setTranslate();\n                    if (s.lazy && s.params.lazyLoading) {\n                        s.lazy.load();\n                        s.lazy.initialImageLoaded = true;\n                    }\n                }\n            }\n            s.attachEvents();\n            if (s.params.observer && s.support.observer) {\n                s.initObservers();\n            }\n            if (s.params.preloadImages && !s.params.lazyLoading) {\n                s.preloadImages();\n            }\n            if (s.params.autoplay) {\n                s.startAutoplay();\n            }\n            if (s.params.keyboardControl) {\n                if (s.enableKeyboardControl) s.enableKeyboardControl();\n            }\n            if (s.params.mousewheelControl) {\n                if (s.enableMousewheelControl) s.enableMousewheelControl();\n            }\n            if (s.params.hashnav) {\n                if (s.hashnav) s.hashnav.init();\n            }\n            if (s.params.a11y && s.a11y) s.a11y.init();\n            s.emit('onInit', s);\n        };\n        \n        // Cleanup dynamic styles\n        s.cleanupStyles = function () {\n            // Container\n            s.container.removeClass(s.classNames.join(' ')).removeAttr('style');\n        \n            // Wrapper\n            s.wrapper.removeAttr('style');\n        \n            // Slides\n            if (s.slides && s.slides.length) {\n                s.slides\n                    .removeClass([\n                      s.params.slideVisibleClass,\n                      s.params.slideActiveClass,\n                      s.params.slideNextClass,\n                      s.params.slidePrevClass\n                    ].join(' '))\n                    .removeAttr('style')\n                    .removeAttr('data-swiper-column')\n                    .removeAttr('data-swiper-row');\n            }\n        \n            // Pagination/Bullets\n            if (s.paginationContainer && s.paginationContainer.length) {\n                s.paginationContainer.removeClass(s.params.paginationHiddenClass);\n            }\n            if (s.bullets && s.bullets.length) {\n                s.bullets.removeClass(s.params.bulletActiveClass);\n            }\n        \n            // Buttons\n            if (s.params.prevButton) $(s.params.prevButton).removeClass(s.params.buttonDisabledClass);\n            if (s.params.nextButton) $(s.params.nextButton).removeClass(s.params.buttonDisabledClass);\n        \n            // Scrollbar\n            if (s.params.scrollbar && s.scrollbar) {\n                if (s.scrollbar.track && s.scrollbar.track.length) s.scrollbar.track.removeAttr('style');\n                if (s.scrollbar.drag && s.scrollbar.drag.length) s.scrollbar.drag.removeAttr('style');\n            }\n        };\n        \n        // Destroy\n        s.destroy = function (deleteInstance, cleanupStyles) {\n            // Detach evebts\n            s.detachEvents();\n            // Stop autoplay\n            s.stopAutoplay();\n            // Disable draggable\n            if (s.params.scrollbar && s.scrollbar) {\n                if (s.params.scrollbarDraggable) {\n                    s.scrollbar.disableDraggable();\n                }\n            }\n            // Destroy loop\n            if (s.params.loop) {\n                s.destroyLoop();\n            }\n            // Cleanup styles\n            if (cleanupStyles) {\n                s.cleanupStyles();\n            }\n            // Disconnect observer\n            s.disconnectObservers();\n            // Disable keyboard/mousewheel\n            if (s.params.keyboardControl) {\n                if (s.disableKeyboardControl) s.disableKeyboardControl();\n            }\n            if (s.params.mousewheelControl) {\n                if (s.disableMousewheelControl) s.disableMousewheelControl();\n            }\n            // Disable a11y\n            if (s.params.a11y && s.a11y) s.a11y.destroy();\n            // Destroy callback\n            s.emit('onDestroy');\n            // Delete instance\n            if (deleteInstance !== false) s = null;\n        };\n        \n        s.init();\n        \n\n    \n        // Return swiper instance\n        return s;\n    };\n    \n\n    /*==================================================\n        Prototype\n    ====================================================*/\n    Swiper.prototype = {\n        isSafari: (function () {\n            var ua = navigator.userAgent.toLowerCase();\n            return (ua.indexOf('safari') >= 0 && ua.indexOf('chrome') < 0 && ua.indexOf('android') < 0);\n        })(),\n        isUiWebView: /(iPhone|iPod|iPad).*AppleWebKit(?!.*Safari)/i.test(navigator.userAgent),\n        isArray: function (arr) {\n            return Object.prototype.toString.apply(arr) === '[object Array]';\n        },\n        /*==================================================\n        Browser\n        ====================================================*/\n        browser: {\n            ie: window.navigator.pointerEnabled || window.navigator.msPointerEnabled,\n            ieTouch: (window.navigator.msPointerEnabled && window.navigator.msMaxTouchPoints > 1) || (window.navigator.pointerEnabled && window.navigator.maxTouchPoints > 1)\n        },\n        /*==================================================\n        Devices\n        ====================================================*/\n        device: (function () {\n            var ua = navigator.userAgent;\n            var android = ua.match(/(Android);?[\\s\\/]+([\\d.]+)?/);\n            var ipad = ua.match(/(iPad).*OS\\s([\\d_]+)/);\n            var ipod = ua.match(/(iPod)(.*OS\\s([\\d_]+))?/);\n            var iphone = !ipad && ua.match(/(iPhone\\sOS)\\s([\\d_]+)/);\n            return {\n                ios: ipad || iphone || ipod,\n                android: android\n            };\n        })(),\n        /*==================================================\n        Feature Detection\n        ====================================================*/\n        support: {\n            touch : (window.Modernizr && Modernizr.touch === true) || (function () {\n                return !!(('ontouchstart' in window) || window.DocumentTouch && document instanceof DocumentTouch);\n            })(),\n    \n            transforms3d : (window.Modernizr && Modernizr.csstransforms3d === true) || (function () {\n                var div = document.createElement('div').style;\n                return ('webkitPerspective' in div || 'MozPerspective' in div || 'OPerspective' in div || 'MsPerspective' in div || 'perspective' in div);\n            })(),\n    \n            flexbox: (function () {\n                var div = document.createElement('div').style;\n                var styles = ('alignItems webkitAlignItems webkitBoxAlign msFlexAlign mozBoxAlign webkitFlexDirection msFlexDirection mozBoxDirection mozBoxOrient webkitBoxDirection webkitBoxOrient').split(' ');\n                for (var i = 0; i < styles.length; i++) {\n                    if (styles[i] in div) return true;\n                }\n            })(),\n    \n            observer: (function () {\n                return ('MutationObserver' in window || 'WebkitMutationObserver' in window);\n            })()\n        },\n        /*==================================================\n        Plugins\n        ====================================================*/\n        plugins: {}\n    };\n    \n\n    /*===========================\n     Get jQuery\n     ===========================*/\n    \n    addLibraryPlugin($);\n    \n    var domLib = $;\n\n    /*===========================\n    Add .swiper plugin from Dom libraries\n    ===========================*/\n    function addLibraryPlugin(lib) {\n        lib.fn.swiper = function (params) {\n            var firstInstance;\n            lib(this).each(function () {\n                var s = new Swiper(this, params);\n                if (!firstInstance) firstInstance = s;\n            });\n            return firstInstance;\n        };\n    }\n    \n    if (domLib) {\n        if (!('transitionEnd' in domLib.fn)) {\n            domLib.fn.transitionEnd = function (callback) {\n                var events = ['webkitTransitionEnd', 'transitionend', 'oTransitionEnd', 'MSTransitionEnd', 'msTransitionEnd'],\n                    i, j, dom = this;\n                function fireCallBack(e) {\n                    /*jshint validthis:true */\n                    if (e.target !== this) return;\n                    callback.call(this, e);\n                    for (i = 0; i < events.length; i++) {\n                        dom.off(events[i], fireCallBack);\n                    }\n                }\n                if (callback) {\n                    for (i = 0; i < events.length; i++) {\n                        dom.on(events[i], fireCallBack);\n                    }\n                }\n                return this;\n            };\n        }\n        if (!('transform' in domLib.fn)) {\n            domLib.fn.transform = function (transform) {\n                for (var i = 0; i < this.length; i++) {\n                    var elStyle = this[i].style;\n                    elStyle.webkitTransform = elStyle.MsTransform = elStyle.msTransform = elStyle.MozTransform = elStyle.OTransform = elStyle.transform = transform;\n                }\n                return this;\n            };\n        }\n        if (!('transition' in domLib.fn)) {\n            domLib.fn.transition = function (duration) {\n                if (typeof duration !== 'string') {\n                    duration = duration + 'ms';\n                }\n                for (var i = 0; i < this.length; i++) {\n                    var elStyle = this[i].style;\n                    elStyle.webkitTransitionDuration = elStyle.MsTransitionDuration = elStyle.msTransitionDuration = elStyle.MozTransitionDuration = elStyle.OTransitionDuration = elStyle.transitionDuration = duration;\n                }\n                return this;\n            };\n        }\n    }\n\n\treturn Swiper;\n}));\n//# sourceMappingURL=maps/swiper.jquery.umd.js.map\n"
  },
  {
    "path": "app_backend/static/plugin/Swiper-3.3.1/dist/js/swiper.js",
    "content": "/**\n * Swiper 3.3.1\n * Most modern mobile touch slider and framework with hardware accelerated transitions\n * \n * http://www.idangero.us/swiper/\n * \n * Copyright 2016, Vladimir Kharlampidi\n * The iDangero.us\n * http://www.idangero.us/\n * \n * Licensed under MIT\n * \n * Released on: February 7, 2016\n */\n(function () {\n    'use strict';\n    var $;\n    /*===========================\n    Swiper\n    ===========================*/\n    var Swiper = function (container, params) {\n        if (!(this instanceof Swiper)) return new Swiper(container, params);\n\n        var defaults = {\n            direction: 'horizontal',\n            touchEventsTarget: 'container',\n            initialSlide: 0,\n            speed: 300,\n            // autoplay\n            autoplay: false,\n            autoplayDisableOnInteraction: true,\n            autoplayStopOnLast: false,\n            // To support iOS's swipe-to-go-back gesture (when being used in-app, with UIWebView).\n            iOSEdgeSwipeDetection: false,\n            iOSEdgeSwipeThreshold: 20,\n            // Free mode\n            freeMode: false,\n            freeModeMomentum: true,\n            freeModeMomentumRatio: 1,\n            freeModeMomentumBounce: true,\n            freeModeMomentumBounceRatio: 1,\n            freeModeSticky: false,\n            freeModeMinimumVelocity: 0.02,\n            // Autoheight\n            autoHeight: false,\n            // Set wrapper width\n            setWrapperSize: false,\n            // Virtual Translate\n            virtualTranslate: false,\n            // Effects\n            effect: 'slide', // 'slide' or 'fade' or 'cube' or 'coverflow' or 'flip'\n            coverflow: {\n                rotate: 50,\n                stretch: 0,\n                depth: 100,\n                modifier: 1,\n                slideShadows : true\n            },\n            flip: {\n                slideShadows : true,\n                limitRotation: true\n            },\n            cube: {\n                slideShadows: true,\n                shadow: true,\n                shadowOffset: 20,\n                shadowScale: 0.94\n            },\n            fade: {\n                crossFade: false\n            },\n            // Parallax\n            parallax: false,\n            // Scrollbar\n            scrollbar: null,\n            scrollbarHide: true,\n            scrollbarDraggable: false,\n            scrollbarSnapOnRelease: false,\n            // Keyboard Mousewheel\n            keyboardControl: false,\n            mousewheelControl: false,\n            mousewheelReleaseOnEdges: false,\n            mousewheelInvert: false,\n            mousewheelForceToAxis: false,\n            mousewheelSensitivity: 1,\n            // Hash Navigation\n            hashnav: false,\n            // Breakpoints\n            breakpoints: undefined,\n            // Slides grid\n            spaceBetween: 0,\n            slidesPerView: 1,\n            slidesPerColumn: 1,\n            slidesPerColumnFill: 'column',\n            slidesPerGroup: 1,\n            centeredSlides: false,\n            slidesOffsetBefore: 0, // in px\n            slidesOffsetAfter: 0, // in px\n            // Round length\n            roundLengths: false,\n            // Touches\n            touchRatio: 1,\n            touchAngle: 45,\n            simulateTouch: true,\n            shortSwipes: true,\n            longSwipes: true,\n            longSwipesRatio: 0.5,\n            longSwipesMs: 300,\n            followFinger: true,\n            onlyExternal: false,\n            threshold: 0,\n            touchMoveStopPropagation: true,\n            // Unique Navigation Elements\n            uniqueNavElements: true,\n            // Pagination\n            pagination: null,\n            paginationElement: 'span',\n            paginationClickable: false,\n            paginationHide: false,\n            paginationBulletRender: null,\n            paginationProgressRender: null,\n            paginationFractionRender: null,\n            paginationCustomRender: null,\n            paginationType: 'bullets', // 'bullets' or 'progress' or 'fraction' or 'custom'\n            // Resistance\n            resistance: true,\n            resistanceRatio: 0.85,\n            // Next/prev buttons\n            nextButton: null,\n            prevButton: null,\n            // Progress\n            watchSlidesProgress: false,\n            watchSlidesVisibility: false,\n            // Cursor\n            grabCursor: false,\n            // Clicks\n            preventClicks: true,\n            preventClicksPropagation: true,\n            slideToClickedSlide: false,\n            // Lazy Loading\n            lazyLoading: false,\n            lazyLoadingInPrevNext: false,\n            lazyLoadingInPrevNextAmount: 1,\n            lazyLoadingOnTransitionStart: false,\n            // Images\n            preloadImages: true,\n            updateOnImagesReady: true,\n            // loop\n            loop: false,\n            loopAdditionalSlides: 0,\n            loopedSlides: null,\n            // Control\n            control: undefined,\n            controlInverse: false,\n            controlBy: 'slide', //or 'container'\n            // Swiping/no swiping\n            allowSwipeToPrev: true,\n            allowSwipeToNext: true,\n            swipeHandler: null, //'.swipe-handler',\n            noSwiping: true,\n            noSwipingClass: 'swiper-no-swiping',\n            // NS\n            slideClass: 'swiper-slide',\n            slideActiveClass: 'swiper-slide-active',\n            slideVisibleClass: 'swiper-slide-visible',\n            slideDuplicateClass: 'swiper-slide-duplicate',\n            slideNextClass: 'swiper-slide-next',\n            slidePrevClass: 'swiper-slide-prev',\n            wrapperClass: 'swiper-wrapper',\n            bulletClass: 'swiper-pagination-bullet',\n            bulletActiveClass: 'swiper-pagination-bullet-active',\n            buttonDisabledClass: 'swiper-button-disabled',\n            paginationCurrentClass: 'swiper-pagination-current',\n            paginationTotalClass: 'swiper-pagination-total',\n            paginationHiddenClass: 'swiper-pagination-hidden',\n            paginationProgressbarClass: 'swiper-pagination-progressbar',\n            // Observer\n            observer: false,\n            observeParents: false,\n            // Accessibility\n            a11y: false,\n            prevSlideMessage: 'Previous slide',\n            nextSlideMessage: 'Next slide',\n            firstSlideMessage: 'This is the first slide',\n            lastSlideMessage: 'This is the last slide',\n            paginationBulletMessage: 'Go to slide {{index}}',\n            // Callbacks\n            runCallbacksOnInit: true\n            /*\n            Callbacks:\n            onInit: function (swiper)\n            onDestroy: function (swiper)\n            onClick: function (swiper, e)\n            onTap: function (swiper, e)\n            onDoubleTap: function (swiper, e)\n            onSliderMove: function (swiper, e)\n            onSlideChangeStart: function (swiper)\n            onSlideChangeEnd: function (swiper)\n            onTransitionStart: function (swiper)\n            onTransitionEnd: function (swiper)\n            onImagesReady: function (swiper)\n            onProgress: function (swiper, progress)\n            onTouchStart: function (swiper, e)\n            onTouchMove: function (swiper, e)\n            onTouchMoveOpposite: function (swiper, e)\n            onTouchEnd: function (swiper, e)\n            onReachBeginning: function (swiper)\n            onReachEnd: function (swiper)\n            onSetTransition: function (swiper, duration)\n            onSetTranslate: function (swiper, translate)\n            onAutoplayStart: function (swiper)\n            onAutoplayStop: function (swiper),\n            onLazyImageLoad: function (swiper, slide, image)\n            onLazyImageReady: function (swiper, slide, image)\n            */\n        \n        };\n        var initialVirtualTranslate = params && params.virtualTranslate;\n        \n        params = params || {};\n        var originalParams = {};\n        for (var param in params) {\n            if (typeof params[param] === 'object' && params[param] !== null && !(params[param].nodeType || params[param] === window || params[param] === document || (typeof Dom7 !== 'undefined' && params[param] instanceof Dom7) || (typeof jQuery !== 'undefined' && params[param] instanceof jQuery))) {\n                originalParams[param] = {};\n                for (var deepParam in params[param]) {\n                    originalParams[param][deepParam] = params[param][deepParam];\n                }\n            }\n            else {\n                originalParams[param] = params[param];\n            }\n        }\n        for (var def in defaults) {\n            if (typeof params[def] === 'undefined') {\n                params[def] = defaults[def];\n            }\n            else if (typeof params[def] === 'object') {\n                for (var deepDef in defaults[def]) {\n                    if (typeof params[def][deepDef] === 'undefined') {\n                        params[def][deepDef] = defaults[def][deepDef];\n                    }\n                }\n            }\n        }\n        \n        // Swiper\n        var s = this;\n        \n        // Params\n        s.params = params;\n        s.originalParams = originalParams;\n        \n        // Classname\n        s.classNames = [];\n        /*=========================\n          Dom Library and plugins\n          ===========================*/\n        if (typeof $ !== 'undefined' && typeof Dom7 !== 'undefined'){\n            $ = Dom7;\n        }\n        if (typeof $ === 'undefined') {\n            if (typeof Dom7 === 'undefined') {\n                $ = window.Dom7 || window.Zepto || window.jQuery;\n            }\n            else {\n                $ = Dom7;\n            }\n            if (!$) return;\n        }\n        // Export it to Swiper instance\n        s.$ = $;\n        \n        /*=========================\n          Breakpoints\n          ===========================*/\n        s.currentBreakpoint = undefined;\n        s.getActiveBreakpoint = function () {\n            //Get breakpoint for window width\n            if (!s.params.breakpoints) return false;\n            var breakpoint = false;\n            var points = [], point;\n            for ( point in s.params.breakpoints ) {\n                if (s.params.breakpoints.hasOwnProperty(point)) {\n                    points.push(point);\n                }\n            }\n            points.sort(function (a, b) {\n                return parseInt(a, 10) > parseInt(b, 10);\n            });\n            for (var i = 0; i < points.length; i++) {\n                point = points[i];\n                if (point >= window.innerWidth && !breakpoint) {\n                    breakpoint = point;\n                }\n            }\n            return breakpoint || 'max';\n        };\n        s.setBreakpoint = function () {\n            //Set breakpoint for window width and update parameters\n            var breakpoint = s.getActiveBreakpoint();\n            if (breakpoint && s.currentBreakpoint !== breakpoint) {\n                var breakPointsParams = breakpoint in s.params.breakpoints ? s.params.breakpoints[breakpoint] : s.originalParams;\n                var needsReLoop = s.params.loop && (breakPointsParams.slidesPerView !== s.params.slidesPerView);\n                for ( var param in breakPointsParams ) {\n                    s.params[param] = breakPointsParams[param];\n                }\n                s.currentBreakpoint = breakpoint;\n                if(needsReLoop && s.destroyLoop) {\n                    s.reLoop(true);\n                }\n            }\n        };\n        // Set breakpoint on load\n        if (s.params.breakpoints) {\n            s.setBreakpoint();\n        }\n        \n        /*=========================\n          Preparation - Define Container, Wrapper and Pagination\n          ===========================*/\n        s.container = $(container);\n        if (s.container.length === 0) return;\n        if (s.container.length > 1) {\n            var swipers = [];\n            s.container.each(function () {\n                var container = this;\n                swipers.push(new Swiper(this, params));\n            });\n            return swipers;\n        }\n        \n        // Save instance in container HTML Element and in data\n        s.container[0].swiper = s;\n        s.container.data('swiper', s);\n        \n        s.classNames.push('swiper-container-' + s.params.direction);\n        \n        if (s.params.freeMode) {\n            s.classNames.push('swiper-container-free-mode');\n        }\n        if (!s.support.flexbox) {\n            s.classNames.push('swiper-container-no-flexbox');\n            s.params.slidesPerColumn = 1;\n        }\n        if (s.params.autoHeight) {\n            s.classNames.push('swiper-container-autoheight');\n        }\n        // Enable slides progress when required\n        if (s.params.parallax || s.params.watchSlidesVisibility) {\n            s.params.watchSlidesProgress = true;\n        }\n        // Coverflow / 3D\n        if (['cube', 'coverflow', 'flip'].indexOf(s.params.effect) >= 0) {\n            if (s.support.transforms3d) {\n                s.params.watchSlidesProgress = true;\n                s.classNames.push('swiper-container-3d');\n            }\n            else {\n                s.params.effect = 'slide';\n            }\n        }\n        if (s.params.effect !== 'slide') {\n            s.classNames.push('swiper-container-' + s.params.effect);\n        }\n        if (s.params.effect === 'cube') {\n            s.params.resistanceRatio = 0;\n            s.params.slidesPerView = 1;\n            s.params.slidesPerColumn = 1;\n            s.params.slidesPerGroup = 1;\n            s.params.centeredSlides = false;\n            s.params.spaceBetween = 0;\n            s.params.virtualTranslate = true;\n            s.params.setWrapperSize = false;\n        }\n        if (s.params.effect === 'fade' || s.params.effect === 'flip') {\n            s.params.slidesPerView = 1;\n            s.params.slidesPerColumn = 1;\n            s.params.slidesPerGroup = 1;\n            s.params.watchSlidesProgress = true;\n            s.params.spaceBetween = 0;\n            s.params.setWrapperSize = false;\n            if (typeof initialVirtualTranslate === 'undefined') {\n                s.params.virtualTranslate = true;\n            }\n        }\n        \n        // Grab Cursor\n        if (s.params.grabCursor && s.support.touch) {\n            s.params.grabCursor = false;\n        }\n        \n        // Wrapper\n        s.wrapper = s.container.children('.' + s.params.wrapperClass);\n        \n        // Pagination\n        if (s.params.pagination) {\n            s.paginationContainer = $(s.params.pagination);\n            if (s.params.uniqueNavElements && typeof s.params.pagination === 'string' && s.paginationContainer.length > 1 && s.container.find(s.params.pagination).length === 1) {\n                s.paginationContainer = s.container.find(s.params.pagination);\n            }\n        \n            if (s.params.paginationType === 'bullets' && s.params.paginationClickable) {\n                s.paginationContainer.addClass('swiper-pagination-clickable');\n            }\n            else {\n                s.params.paginationClickable = false;\n            }\n            s.paginationContainer.addClass('swiper-pagination-' + s.params.paginationType);\n        }\n        // Next/Prev Buttons\n        if (s.params.nextButton || s.params.prevButton) {\n            if (s.params.nextButton) {\n                s.nextButton = $(s.params.nextButton);\n                if (s.params.uniqueNavElements && typeof s.params.nextButton === 'string' && s.nextButton.length > 1 && s.container.find(s.params.nextButton).length === 1) {\n                    s.nextButton = s.container.find(s.params.nextButton);\n                }\n            }\n            if (s.params.prevButton) {\n                s.prevButton = $(s.params.prevButton);\n                if (s.params.uniqueNavElements && typeof s.params.prevButton === 'string' && s.prevButton.length > 1 && s.container.find(s.params.prevButton).length === 1) {\n                    s.prevButton = s.container.find(s.params.prevButton);\n                }\n            }\n        }\n        \n        // Is Horizontal\n        s.isHorizontal = function () {\n            return s.params.direction === 'horizontal';\n        };\n        // s.isH = isH;\n        \n        // RTL\n        s.rtl = s.isHorizontal() && (s.container[0].dir.toLowerCase() === 'rtl' || s.container.css('direction') === 'rtl');\n        if (s.rtl) {\n            s.classNames.push('swiper-container-rtl');\n        }\n        \n        // Wrong RTL support\n        if (s.rtl) {\n            s.wrongRTL = s.wrapper.css('display') === '-webkit-box';\n        }\n        \n        // Columns\n        if (s.params.slidesPerColumn > 1) {\n            s.classNames.push('swiper-container-multirow');\n        }\n        \n        // Check for Android\n        if (s.device.android) {\n            s.classNames.push('swiper-container-android');\n        }\n        \n        // Add classes\n        s.container.addClass(s.classNames.join(' '));\n        \n        // Translate\n        s.translate = 0;\n        \n        // Progress\n        s.progress = 0;\n        \n        // Velocity\n        s.velocity = 0;\n        \n        /*=========================\n          Locks, unlocks\n          ===========================*/\n        s.lockSwipeToNext = function () {\n            s.params.allowSwipeToNext = false;\n        };\n        s.lockSwipeToPrev = function () {\n            s.params.allowSwipeToPrev = false;\n        };\n        s.lockSwipes = function () {\n            s.params.allowSwipeToNext = s.params.allowSwipeToPrev = false;\n        };\n        s.unlockSwipeToNext = function () {\n            s.params.allowSwipeToNext = true;\n        };\n        s.unlockSwipeToPrev = function () {\n            s.params.allowSwipeToPrev = true;\n        };\n        s.unlockSwipes = function () {\n            s.params.allowSwipeToNext = s.params.allowSwipeToPrev = true;\n        };\n        \n        /*=========================\n          Round helper\n          ===========================*/\n        function round(a) {\n            return Math.floor(a);\n        }\n        /*=========================\n          Set grab cursor\n          ===========================*/\n        if (s.params.grabCursor) {\n            s.container[0].style.cursor = 'move';\n            s.container[0].style.cursor = '-webkit-grab';\n            s.container[0].style.cursor = '-moz-grab';\n            s.container[0].style.cursor = 'grab';\n        }\n        /*=========================\n          Update on Images Ready\n          ===========================*/\n        s.imagesToLoad = [];\n        s.imagesLoaded = 0;\n        \n        s.loadImage = function (imgElement, src, srcset, checkForComplete, callback) {\n            var image;\n            function onReady () {\n                if (callback) callback();\n            }\n            if (!imgElement.complete || !checkForComplete) {\n                if (src) {\n                    image = new window.Image();\n                    image.onload = onReady;\n                    image.onerror = onReady;\n                    if (srcset) {\n                        image.srcset = srcset;\n                    }\n                    if (src) {\n                        image.src = src;\n                    }\n                } else {\n                    onReady();\n                }\n        \n            } else {//image already loaded...\n                onReady();\n            }\n        };\n        s.preloadImages = function () {\n            s.imagesToLoad = s.container.find('img');\n            function _onReady() {\n                if (typeof s === 'undefined' || s === null) return;\n                if (s.imagesLoaded !== undefined) s.imagesLoaded++;\n                if (s.imagesLoaded === s.imagesToLoad.length) {\n                    if (s.params.updateOnImagesReady) s.update();\n                    s.emit('onImagesReady', s);\n                }\n            }\n            for (var i = 0; i < s.imagesToLoad.length; i++) {\n                s.loadImage(s.imagesToLoad[i], (s.imagesToLoad[i].currentSrc || s.imagesToLoad[i].getAttribute('src')), (s.imagesToLoad[i].srcset || s.imagesToLoad[i].getAttribute('srcset')), true, _onReady);\n            }\n        };\n        \n        /*=========================\n          Autoplay\n          ===========================*/\n        s.autoplayTimeoutId = undefined;\n        s.autoplaying = false;\n        s.autoplayPaused = false;\n        function autoplay() {\n            s.autoplayTimeoutId = setTimeout(function () {\n                if (s.params.loop) {\n                    s.fixLoop();\n                    s._slideNext();\n                    s.emit('onAutoplay', s);\n                }\n                else {\n                    if (!s.isEnd) {\n                        s._slideNext();\n                        s.emit('onAutoplay', s);\n                    }\n                    else {\n                        if (!params.autoplayStopOnLast) {\n                            s._slideTo(0);\n                            s.emit('onAutoplay', s);\n                        }\n                        else {\n                            s.stopAutoplay();\n                        }\n                    }\n                }\n            }, s.params.autoplay);\n        }\n        s.startAutoplay = function () {\n            if (typeof s.autoplayTimeoutId !== 'undefined') return false;\n            if (!s.params.autoplay) return false;\n            if (s.autoplaying) return false;\n            s.autoplaying = true;\n            s.emit('onAutoplayStart', s);\n            autoplay();\n        };\n        s.stopAutoplay = function (internal) {\n            if (!s.autoplayTimeoutId) return;\n            if (s.autoplayTimeoutId) clearTimeout(s.autoplayTimeoutId);\n            s.autoplaying = false;\n            s.autoplayTimeoutId = undefined;\n            s.emit('onAutoplayStop', s);\n        };\n        s.pauseAutoplay = function (speed) {\n            if (s.autoplayPaused) return;\n            if (s.autoplayTimeoutId) clearTimeout(s.autoplayTimeoutId);\n            s.autoplayPaused = true;\n            if (speed === 0) {\n                s.autoplayPaused = false;\n                autoplay();\n            }\n            else {\n                s.wrapper.transitionEnd(function () {\n                    if (!s) return;\n                    s.autoplayPaused = false;\n                    if (!s.autoplaying) {\n                        s.stopAutoplay();\n                    }\n                    else {\n                        autoplay();\n                    }\n                });\n            }\n        };\n        /*=========================\n          Min/Max Translate\n          ===========================*/\n        s.minTranslate = function () {\n            return (-s.snapGrid[0]);\n        };\n        s.maxTranslate = function () {\n            return (-s.snapGrid[s.snapGrid.length - 1]);\n        };\n        /*=========================\n          Slider/slides sizes\n          ===========================*/\n        s.updateAutoHeight = function () {\n            // Update Height\n            var slide = s.slides.eq(s.activeIndex)[0];\n            if (typeof slide !== 'undefined') {\n                var newHeight = slide.offsetHeight;\n                if (newHeight) s.wrapper.css('height', newHeight + 'px');\n            }\n        };\n        s.updateContainerSize = function () {\n            var width, height;\n            if (typeof s.params.width !== 'undefined') {\n                width = s.params.width;\n            }\n            else {\n                width = s.container[0].clientWidth;\n            }\n            if (typeof s.params.height !== 'undefined') {\n                height = s.params.height;\n            }\n            else {\n                height = s.container[0].clientHeight;\n            }\n            if (width === 0 && s.isHorizontal() || height === 0 && !s.isHorizontal()) {\n                return;\n            }\n        \n            //Subtract paddings\n            width = width - parseInt(s.container.css('padding-left'), 10) - parseInt(s.container.css('padding-right'), 10);\n            height = height - parseInt(s.container.css('padding-top'), 10) - parseInt(s.container.css('padding-bottom'), 10);\n        \n            // Store values\n            s.width = width;\n            s.height = height;\n            s.size = s.isHorizontal() ? s.width : s.height;\n        };\n        \n        s.updateSlidesSize = function () {\n            s.slides = s.wrapper.children('.' + s.params.slideClass);\n            s.snapGrid = [];\n            s.slidesGrid = [];\n            s.slidesSizesGrid = [];\n        \n            var spaceBetween = s.params.spaceBetween,\n                slidePosition = -s.params.slidesOffsetBefore,\n                i,\n                prevSlideSize = 0,\n                index = 0;\n            if (typeof s.size === 'undefined') return;\n            if (typeof spaceBetween === 'string' && spaceBetween.indexOf('%') >= 0) {\n                spaceBetween = parseFloat(spaceBetween.replace('%', '')) / 100 * s.size;\n            }\n        \n            s.virtualSize = -spaceBetween;\n            // reset margins\n            if (s.rtl) s.slides.css({marginLeft: '', marginTop: ''});\n            else s.slides.css({marginRight: '', marginBottom: ''});\n        \n            var slidesNumberEvenToRows;\n            if (s.params.slidesPerColumn > 1) {\n                if (Math.floor(s.slides.length / s.params.slidesPerColumn) === s.slides.length / s.params.slidesPerColumn) {\n                    slidesNumberEvenToRows = s.slides.length;\n                }\n                else {\n                    slidesNumberEvenToRows = Math.ceil(s.slides.length / s.params.slidesPerColumn) * s.params.slidesPerColumn;\n                }\n                if (s.params.slidesPerView !== 'auto' && s.params.slidesPerColumnFill === 'row') {\n                    slidesNumberEvenToRows = Math.max(slidesNumberEvenToRows, s.params.slidesPerView * s.params.slidesPerColumn);\n                }\n            }\n        \n            // Calc slides\n            var slideSize;\n            var slidesPerColumn = s.params.slidesPerColumn;\n            var slidesPerRow = slidesNumberEvenToRows / slidesPerColumn;\n            var numFullColumns = slidesPerRow - (s.params.slidesPerColumn * slidesPerRow - s.slides.length);\n            for (i = 0; i < s.slides.length; i++) {\n                slideSize = 0;\n                var slide = s.slides.eq(i);\n                if (s.params.slidesPerColumn > 1) {\n                    // Set slides order\n                    var newSlideOrderIndex;\n                    var column, row;\n                    if (s.params.slidesPerColumnFill === 'column') {\n                        column = Math.floor(i / slidesPerColumn);\n                        row = i - column * slidesPerColumn;\n                        if (column > numFullColumns || (column === numFullColumns && row === slidesPerColumn-1)) {\n                            if (++row >= slidesPerColumn) {\n                                row = 0;\n                                column++;\n                            }\n                        }\n                        newSlideOrderIndex = column + row * slidesNumberEvenToRows / slidesPerColumn;\n                        slide\n                            .css({\n                                '-webkit-box-ordinal-group': newSlideOrderIndex,\n                                '-moz-box-ordinal-group': newSlideOrderIndex,\n                                '-ms-flex-order': newSlideOrderIndex,\n                                '-webkit-order': newSlideOrderIndex,\n                                'order': newSlideOrderIndex\n                            });\n                    }\n                    else {\n                        row = Math.floor(i / slidesPerRow);\n                        column = i - row * slidesPerRow;\n                    }\n                    slide\n                        .css({\n                            'margin-top': (row !== 0 && s.params.spaceBetween) && (s.params.spaceBetween + 'px')\n                        })\n                        .attr('data-swiper-column', column)\n                        .attr('data-swiper-row', row);\n        \n                }\n                if (slide.css('display') === 'none') continue;\n                if (s.params.slidesPerView === 'auto') {\n                    slideSize = s.isHorizontal() ? slide.outerWidth(true) : slide.outerHeight(true);\n                    if (s.params.roundLengths) slideSize = round(slideSize);\n                }\n                else {\n                    slideSize = (s.size - (s.params.slidesPerView - 1) * spaceBetween) / s.params.slidesPerView;\n                    if (s.params.roundLengths) slideSize = round(slideSize);\n        \n                    if (s.isHorizontal()) {\n                        s.slides[i].style.width = slideSize + 'px';\n                    }\n                    else {\n                        s.slides[i].style.height = slideSize + 'px';\n                    }\n                }\n                s.slides[i].swiperSlideSize = slideSize;\n                s.slidesSizesGrid.push(slideSize);\n        \n        \n                if (s.params.centeredSlides) {\n                    slidePosition = slidePosition + slideSize / 2 + prevSlideSize / 2 + spaceBetween;\n                    if (i === 0) slidePosition = slidePosition - s.size / 2 - spaceBetween;\n                    if (Math.abs(slidePosition) < 1 / 1000) slidePosition = 0;\n                    if ((index) % s.params.slidesPerGroup === 0) s.snapGrid.push(slidePosition);\n                    s.slidesGrid.push(slidePosition);\n                }\n                else {\n                    if ((index) % s.params.slidesPerGroup === 0) s.snapGrid.push(slidePosition);\n                    s.slidesGrid.push(slidePosition);\n                    slidePosition = slidePosition + slideSize + spaceBetween;\n                }\n        \n                s.virtualSize += slideSize + spaceBetween;\n        \n                prevSlideSize = slideSize;\n        \n                index ++;\n            }\n            s.virtualSize = Math.max(s.virtualSize, s.size) + s.params.slidesOffsetAfter;\n            var newSlidesGrid;\n        \n            if (\n                s.rtl && s.wrongRTL && (s.params.effect === 'slide' || s.params.effect === 'coverflow')) {\n                s.wrapper.css({width: s.virtualSize + s.params.spaceBetween + 'px'});\n            }\n            if (!s.support.flexbox || s.params.setWrapperSize) {\n                if (s.isHorizontal()) s.wrapper.css({width: s.virtualSize + s.params.spaceBetween + 'px'});\n                else s.wrapper.css({height: s.virtualSize + s.params.spaceBetween + 'px'});\n            }\n        \n            if (s.params.slidesPerColumn > 1) {\n                s.virtualSize = (slideSize + s.params.spaceBetween) * slidesNumberEvenToRows;\n                s.virtualSize = Math.ceil(s.virtualSize / s.params.slidesPerColumn) - s.params.spaceBetween;\n                s.wrapper.css({width: s.virtualSize + s.params.spaceBetween + 'px'});\n                if (s.params.centeredSlides) {\n                    newSlidesGrid = [];\n                    for (i = 0; i < s.snapGrid.length; i++) {\n                        if (s.snapGrid[i] < s.virtualSize + s.snapGrid[0]) newSlidesGrid.push(s.snapGrid[i]);\n                    }\n                    s.snapGrid = newSlidesGrid;\n                }\n            }\n        \n            // Remove last grid elements depending on width\n            if (!s.params.centeredSlides) {\n                newSlidesGrid = [];\n                for (i = 0; i < s.snapGrid.length; i++) {\n                    if (s.snapGrid[i] <= s.virtualSize - s.size) {\n                        newSlidesGrid.push(s.snapGrid[i]);\n                    }\n                }\n                s.snapGrid = newSlidesGrid;\n                if (Math.floor(s.virtualSize - s.size) - Math.floor(s.snapGrid[s.snapGrid.length - 1]) > 1) {\n                    s.snapGrid.push(s.virtualSize - s.size);\n                }\n            }\n            if (s.snapGrid.length === 0) s.snapGrid = [0];\n        \n            if (s.params.spaceBetween !== 0) {\n                if (s.isHorizontal()) {\n                    if (s.rtl) s.slides.css({marginLeft: spaceBetween + 'px'});\n                    else s.slides.css({marginRight: spaceBetween + 'px'});\n                }\n                else s.slides.css({marginBottom: spaceBetween + 'px'});\n            }\n            if (s.params.watchSlidesProgress) {\n                s.updateSlidesOffset();\n            }\n        };\n        s.updateSlidesOffset = function () {\n            for (var i = 0; i < s.slides.length; i++) {\n                s.slides[i].swiperSlideOffset = s.isHorizontal() ? s.slides[i].offsetLeft : s.slides[i].offsetTop;\n            }\n        };\n        \n        /*=========================\n          Slider/slides progress\n          ===========================*/\n        s.updateSlidesProgress = function (translate) {\n            if (typeof translate === 'undefined') {\n                translate = s.translate || 0;\n            }\n            if (s.slides.length === 0) return;\n            if (typeof s.slides[0].swiperSlideOffset === 'undefined') s.updateSlidesOffset();\n        \n            var offsetCenter = -translate;\n            if (s.rtl) offsetCenter = translate;\n        \n            // Visible Slides\n            s.slides.removeClass(s.params.slideVisibleClass);\n            for (var i = 0; i < s.slides.length; i++) {\n                var slide = s.slides[i];\n                var slideProgress = (offsetCenter - slide.swiperSlideOffset) / (slide.swiperSlideSize + s.params.spaceBetween);\n                if (s.params.watchSlidesVisibility) {\n                    var slideBefore = -(offsetCenter - slide.swiperSlideOffset);\n                    var slideAfter = slideBefore + s.slidesSizesGrid[i];\n                    var isVisible =\n                        (slideBefore >= 0 && slideBefore < s.size) ||\n                        (slideAfter > 0 && slideAfter <= s.size) ||\n                        (slideBefore <= 0 && slideAfter >= s.size);\n                    if (isVisible) {\n                        s.slides.eq(i).addClass(s.params.slideVisibleClass);\n                    }\n                }\n                slide.progress = s.rtl ? -slideProgress : slideProgress;\n            }\n        };\n        s.updateProgress = function (translate) {\n            if (typeof translate === 'undefined') {\n                translate = s.translate || 0;\n            }\n            var translatesDiff = s.maxTranslate() - s.minTranslate();\n            var wasBeginning = s.isBeginning;\n            var wasEnd = s.isEnd;\n            if (translatesDiff === 0) {\n                s.progress = 0;\n                s.isBeginning = s.isEnd = true;\n            }\n            else {\n                s.progress = (translate - s.minTranslate()) / (translatesDiff);\n                s.isBeginning = s.progress <= 0;\n                s.isEnd = s.progress >= 1;\n            }\n            if (s.isBeginning && !wasBeginning) s.emit('onReachBeginning', s);\n            if (s.isEnd && !wasEnd) s.emit('onReachEnd', s);\n        \n            if (s.params.watchSlidesProgress) s.updateSlidesProgress(translate);\n            s.emit('onProgress', s, s.progress);\n        };\n        s.updateActiveIndex = function () {\n            var translate = s.rtl ? s.translate : -s.translate;\n            var newActiveIndex, i, snapIndex;\n            for (i = 0; i < s.slidesGrid.length; i ++) {\n                if (typeof s.slidesGrid[i + 1] !== 'undefined') {\n                    if (translate >= s.slidesGrid[i] && translate < s.slidesGrid[i + 1] - (s.slidesGrid[i + 1] - s.slidesGrid[i]) / 2) {\n                        newActiveIndex = i;\n                    }\n                    else if (translate >= s.slidesGrid[i] && translate < s.slidesGrid[i + 1]) {\n                        newActiveIndex = i + 1;\n                    }\n                }\n                else {\n                    if (translate >= s.slidesGrid[i]) {\n                        newActiveIndex = i;\n                    }\n                }\n            }\n            // Normalize slideIndex\n            if (newActiveIndex < 0 || typeof newActiveIndex === 'undefined') newActiveIndex = 0;\n            // for (i = 0; i < s.slidesGrid.length; i++) {\n                // if (- translate >= s.slidesGrid[i]) {\n                    // newActiveIndex = i;\n                // }\n            // }\n            snapIndex = Math.floor(newActiveIndex / s.params.slidesPerGroup);\n            if (snapIndex >= s.snapGrid.length) snapIndex = s.snapGrid.length - 1;\n        \n            if (newActiveIndex === s.activeIndex) {\n                return;\n            }\n            s.snapIndex = snapIndex;\n            s.previousIndex = s.activeIndex;\n            s.activeIndex = newActiveIndex;\n            s.updateClasses();\n        };\n        \n        /*=========================\n          Classes\n          ===========================*/\n        s.updateClasses = function () {\n            s.slides.removeClass(s.params.slideActiveClass + ' ' + s.params.slideNextClass + ' ' + s.params.slidePrevClass);\n            var activeSlide = s.slides.eq(s.activeIndex);\n            // Active classes\n            activeSlide.addClass(s.params.slideActiveClass);\n            // Next Slide\n            var nextSlide = activeSlide.next('.' + s.params.slideClass).addClass(s.params.slideNextClass);\n            if (s.params.loop && nextSlide.length === 0) {\n                s.slides.eq(0).addClass(s.params.slideNextClass);\n            }\n            // Prev Slide\n            var prevSlide = activeSlide.prev('.' + s.params.slideClass).addClass(s.params.slidePrevClass);\n            if (s.params.loop && prevSlide.length === 0) {\n                s.slides.eq(-1).addClass(s.params.slidePrevClass);\n            }\n        \n            // Pagination\n            if (s.paginationContainer && s.paginationContainer.length > 0) {\n                // Current/Total\n                var current,\n                    total = s.params.loop ? Math.ceil((s.slides.length - s.loopedSlides * 2) / s.params.slidesPerGroup) : s.snapGrid.length;\n                if (s.params.loop) {\n                    current = Math.ceil((s.activeIndex - s.loopedSlides)/s.params.slidesPerGroup);\n                    if (current > s.slides.length - 1 - s.loopedSlides * 2) {\n                        current = current - (s.slides.length - s.loopedSlides * 2);\n                    }\n                    if (current > total - 1) current = current - total;\n                    if (current < 0 && s.params.paginationType !== 'bullets') current = total + current;\n                }\n                else {\n                    if (typeof s.snapIndex !== 'undefined') {\n                        current = s.snapIndex;\n                    }\n                    else {\n                        current = s.activeIndex || 0;\n                    }\n                }\n                // Types\n                if (s.params.paginationType === 'bullets' && s.bullets && s.bullets.length > 0) {\n                    s.bullets.removeClass(s.params.bulletActiveClass);\n                    if (s.paginationContainer.length > 1) {\n                        s.bullets.each(function () {\n                            if ($(this).index() === current) $(this).addClass(s.params.bulletActiveClass);\n                        });\n                    }\n                    else {\n                        s.bullets.eq(current).addClass(s.params.bulletActiveClass);\n                    }\n                }\n                if (s.params.paginationType === 'fraction') {\n                    s.paginationContainer.find('.' + s.params.paginationCurrentClass).text(current + 1);\n                    s.paginationContainer.find('.' + s.params.paginationTotalClass).text(total);\n                }\n                if (s.params.paginationType === 'progress') {\n                    var scale = (current + 1) / total,\n                        scaleX = scale,\n                        scaleY = 1;\n                    if (!s.isHorizontal()) {\n                        scaleY = scale;\n                        scaleX = 1;\n                    }\n                    s.paginationContainer.find('.' + s.params.paginationProgressbarClass).transform('translate3d(0,0,0) scaleX(' + scaleX + ') scaleY(' + scaleY + ')').transition(s.params.speed);\n                }\n                if (s.params.paginationType === 'custom' && s.params.paginationCustomRender) {\n                    s.paginationContainer.html(s.params.paginationCustomRender(s, current + 1, total));\n                    s.emit('onPaginationRendered', s, s.paginationContainer[0]);\n                }\n            }\n        \n            // Next/active buttons\n            if (!s.params.loop) {\n                if (s.params.prevButton && s.prevButton && s.prevButton.length > 0) {\n                    if (s.isBeginning) {\n                        s.prevButton.addClass(s.params.buttonDisabledClass);\n                        if (s.params.a11y && s.a11y) s.a11y.disable(s.prevButton);\n                    }\n                    else {\n                        s.prevButton.removeClass(s.params.buttonDisabledClass);\n                        if (s.params.a11y && s.a11y) s.a11y.enable(s.prevButton);\n                    }\n                }\n                if (s.params.nextButton && s.nextButton && s.nextButton.length > 0) {\n                    if (s.isEnd) {\n                        s.nextButton.addClass(s.params.buttonDisabledClass);\n                        if (s.params.a11y && s.a11y) s.a11y.disable(s.nextButton);\n                    }\n                    else {\n                        s.nextButton.removeClass(s.params.buttonDisabledClass);\n                        if (s.params.a11y && s.a11y) s.a11y.enable(s.nextButton);\n                    }\n                }\n            }\n        };\n        \n        /*=========================\n          Pagination\n          ===========================*/\n        s.updatePagination = function () {\n            if (!s.params.pagination) return;\n            if (s.paginationContainer && s.paginationContainer.length > 0) {\n                var paginationHTML = '';\n                if (s.params.paginationType === 'bullets') {\n                    var numberOfBullets = s.params.loop ? Math.ceil((s.slides.length - s.loopedSlides * 2) / s.params.slidesPerGroup) : s.snapGrid.length;\n                    for (var i = 0; i < numberOfBullets; i++) {\n                        if (s.params.paginationBulletRender) {\n                            paginationHTML += s.params.paginationBulletRender(i, s.params.bulletClass);\n                        }\n                        else {\n                            paginationHTML += '<' + s.params.paginationElement+' class=\"' + s.params.bulletClass + '\"></' + s.params.paginationElement + '>';\n                        }\n                    }\n                    s.paginationContainer.html(paginationHTML);\n                    s.bullets = s.paginationContainer.find('.' + s.params.bulletClass);\n                    if (s.params.paginationClickable && s.params.a11y && s.a11y) {\n                        s.a11y.initPagination();\n                    }\n                }\n                if (s.params.paginationType === 'fraction') {\n                    if (s.params.paginationFractionRender) {\n                        paginationHTML = s.params.paginationFractionRender(s, s.params.paginationCurrentClass, s.params.paginationTotalClass);\n                    }\n                    else {\n                        paginationHTML =\n                            '<span class=\"' + s.params.paginationCurrentClass + '\"></span>' +\n                            ' / ' +\n                            '<span class=\"' + s.params.paginationTotalClass+'\"></span>';\n                    }\n                    s.paginationContainer.html(paginationHTML);\n                }\n                if (s.params.paginationType === 'progress') {\n                    if (s.params.paginationProgressRender) {\n                        paginationHTML = s.params.paginationProgressRender(s, s.params.paginationProgressbarClass);\n                    }\n                    else {\n                        paginationHTML = '<span class=\"' + s.params.paginationProgressbarClass + '\"></span>';\n                    }\n                    s.paginationContainer.html(paginationHTML);\n                }\n                if (s.params.paginationType !== 'custom') {\n                    s.emit('onPaginationRendered', s, s.paginationContainer[0]);\n                }\n            }\n        };\n        /*=========================\n          Common update method\n          ===========================*/\n        s.update = function (updateTranslate) {\n            s.updateContainerSize();\n            s.updateSlidesSize();\n            s.updateProgress();\n            s.updatePagination();\n            s.updateClasses();\n            if (s.params.scrollbar && s.scrollbar) {\n                s.scrollbar.set();\n            }\n            function forceSetTranslate() {\n                newTranslate = Math.min(Math.max(s.translate, s.maxTranslate()), s.minTranslate());\n                s.setWrapperTranslate(newTranslate);\n                s.updateActiveIndex();\n                s.updateClasses();\n            }\n            if (updateTranslate) {\n                var translated, newTranslate;\n                if (s.controller && s.controller.spline) {\n                    s.controller.spline = undefined;\n                }\n                if (s.params.freeMode) {\n                    forceSetTranslate();\n                    if (s.params.autoHeight) {\n                        s.updateAutoHeight();\n                    }\n                }\n                else {\n                    if ((s.params.slidesPerView === 'auto' || s.params.slidesPerView > 1) && s.isEnd && !s.params.centeredSlides) {\n                        translated = s.slideTo(s.slides.length - 1, 0, false, true);\n                    }\n                    else {\n                        translated = s.slideTo(s.activeIndex, 0, false, true);\n                    }\n                    if (!translated) {\n                        forceSetTranslate();\n                    }\n                }\n            }\n            else if (s.params.autoHeight) {\n                s.updateAutoHeight();\n            }\n        };\n        \n        /*=========================\n          Resize Handler\n          ===========================*/\n        s.onResize = function (forceUpdatePagination) {\n            //Breakpoints\n            if (s.params.breakpoints) {\n                s.setBreakpoint();\n            }\n        \n            // Disable locks on resize\n            var allowSwipeToPrev = s.params.allowSwipeToPrev;\n            var allowSwipeToNext = s.params.allowSwipeToNext;\n            s.params.allowSwipeToPrev = s.params.allowSwipeToNext = true;\n        \n            s.updateContainerSize();\n            s.updateSlidesSize();\n            if (s.params.slidesPerView === 'auto' || s.params.freeMode || forceUpdatePagination) s.updatePagination();\n            if (s.params.scrollbar && s.scrollbar) {\n                s.scrollbar.set();\n            }\n            if (s.controller && s.controller.spline) {\n                s.controller.spline = undefined;\n            }\n            var slideChangedBySlideTo = false;\n            if (s.params.freeMode) {\n                var newTranslate = Math.min(Math.max(s.translate, s.maxTranslate()), s.minTranslate());\n                s.setWrapperTranslate(newTranslate);\n                s.updateActiveIndex();\n                s.updateClasses();\n        \n                if (s.params.autoHeight) {\n                    s.updateAutoHeight();\n                }\n            }\n            else {\n                s.updateClasses();\n                if ((s.params.slidesPerView === 'auto' || s.params.slidesPerView > 1) && s.isEnd && !s.params.centeredSlides) {\n                    slideChangedBySlideTo = s.slideTo(s.slides.length - 1, 0, false, true);\n                }\n                else {\n                    slideChangedBySlideTo = s.slideTo(s.activeIndex, 0, false, true);\n                }\n            }\n            if (s.params.lazyLoading && !slideChangedBySlideTo && s.lazy) {\n                s.lazy.load();\n            }\n            // Return locks after resize\n            s.params.allowSwipeToPrev = allowSwipeToPrev;\n            s.params.allowSwipeToNext = allowSwipeToNext;\n        };\n        \n        /*=========================\n          Events\n          ===========================*/\n        \n        //Define Touch Events\n        var desktopEvents = ['mousedown', 'mousemove', 'mouseup'];\n        if (window.navigator.pointerEnabled) desktopEvents = ['pointerdown', 'pointermove', 'pointerup'];\n        else if (window.navigator.msPointerEnabled) desktopEvents = ['MSPointerDown', 'MSPointerMove', 'MSPointerUp'];\n        s.touchEvents = {\n            start : s.support.touch || !s.params.simulateTouch  ? 'touchstart' : desktopEvents[0],\n            move : s.support.touch || !s.params.simulateTouch ? 'touchmove' : desktopEvents[1],\n            end : s.support.touch || !s.params.simulateTouch ? 'touchend' : desktopEvents[2]\n        };\n        \n        \n        // WP8 Touch Events Fix\n        if (window.navigator.pointerEnabled || window.navigator.msPointerEnabled) {\n            (s.params.touchEventsTarget === 'container' ? s.container : s.wrapper).addClass('swiper-wp8-' + s.params.direction);\n        }\n        \n        // Attach/detach events\n        s.initEvents = function (detach) {\n            var actionDom = detach ? 'off' : 'on';\n            var action = detach ? 'removeEventListener' : 'addEventListener';\n            var touchEventsTarget = s.params.touchEventsTarget === 'container' ? s.container[0] : s.wrapper[0];\n            var target = s.support.touch ? touchEventsTarget : document;\n        \n            var moveCapture = s.params.nested ? true : false;\n        \n            //Touch Events\n            if (s.browser.ie) {\n                touchEventsTarget[action](s.touchEvents.start, s.onTouchStart, false);\n                target[action](s.touchEvents.move, s.onTouchMove, moveCapture);\n                target[action](s.touchEvents.end, s.onTouchEnd, false);\n            }\n            else {\n                if (s.support.touch) {\n                    touchEventsTarget[action](s.touchEvents.start, s.onTouchStart, false);\n                    touchEventsTarget[action](s.touchEvents.move, s.onTouchMove, moveCapture);\n                    touchEventsTarget[action](s.touchEvents.end, s.onTouchEnd, false);\n                }\n                if (params.simulateTouch && !s.device.ios && !s.device.android) {\n                    touchEventsTarget[action]('mousedown', s.onTouchStart, false);\n                    document[action]('mousemove', s.onTouchMove, moveCapture);\n                    document[action]('mouseup', s.onTouchEnd, false);\n                }\n            }\n            window[action]('resize', s.onResize);\n        \n            // Next, Prev, Index\n            if (s.params.nextButton && s.nextButton && s.nextButton.length > 0) {\n                s.nextButton[actionDom]('click', s.onClickNext);\n                if (s.params.a11y && s.a11y) s.nextButton[actionDom]('keydown', s.a11y.onEnterKey);\n            }\n            if (s.params.prevButton && s.prevButton && s.prevButton.length > 0) {\n                s.prevButton[actionDom]('click', s.onClickPrev);\n                if (s.params.a11y && s.a11y) s.prevButton[actionDom]('keydown', s.a11y.onEnterKey);\n            }\n            if (s.params.pagination && s.params.paginationClickable) {\n                s.paginationContainer[actionDom]('click', '.' + s.params.bulletClass, s.onClickIndex);\n                if (s.params.a11y && s.a11y) s.paginationContainer[actionDom]('keydown', '.' + s.params.bulletClass, s.a11y.onEnterKey);\n            }\n        \n            // Prevent Links Clicks\n            if (s.params.preventClicks || s.params.preventClicksPropagation) touchEventsTarget[action]('click', s.preventClicks, true);\n        };\n        s.attachEvents = function () {\n            s.initEvents();\n        };\n        s.detachEvents = function () {\n            s.initEvents(true);\n        };\n        \n        /*=========================\n          Handle Clicks\n          ===========================*/\n        // Prevent Clicks\n        s.allowClick = true;\n        s.preventClicks = function (e) {\n            if (!s.allowClick) {\n                if (s.params.preventClicks) e.preventDefault();\n                if (s.params.preventClicksPropagation && s.animating) {\n                    e.stopPropagation();\n                    e.stopImmediatePropagation();\n                }\n            }\n        };\n        // Clicks\n        s.onClickNext = function (e) {\n            e.preventDefault();\n            if (s.isEnd && !s.params.loop) return;\n            s.slideNext();\n        };\n        s.onClickPrev = function (e) {\n            e.preventDefault();\n            if (s.isBeginning && !s.params.loop) return;\n            s.slidePrev();\n        };\n        s.onClickIndex = function (e) {\n            e.preventDefault();\n            var index = $(this).index() * s.params.slidesPerGroup;\n            if (s.params.loop) index = index + s.loopedSlides;\n            s.slideTo(index);\n        };\n        \n        /*=========================\n          Handle Touches\n          ===========================*/\n        function findElementInEvent(e, selector) {\n            var el = $(e.target);\n            if (!el.is(selector)) {\n                if (typeof selector === 'string') {\n                    el = el.parents(selector);\n                }\n                else if (selector.nodeType) {\n                    var found;\n                    el.parents().each(function (index, _el) {\n                        if (_el === selector) found = selector;\n                    });\n                    if (!found) return undefined;\n                    else return selector;\n                }\n            }\n            if (el.length === 0) {\n                return undefined;\n            }\n            return el[0];\n        }\n        s.updateClickedSlide = function (e) {\n            var slide = findElementInEvent(e, '.' + s.params.slideClass);\n            var slideFound = false;\n            if (slide) {\n                for (var i = 0; i < s.slides.length; i++) {\n                    if (s.slides[i] === slide) slideFound = true;\n                }\n            }\n        \n            if (slide && slideFound) {\n                s.clickedSlide = slide;\n                s.clickedIndex = $(slide).index();\n            }\n            else {\n                s.clickedSlide = undefined;\n                s.clickedIndex = undefined;\n                return;\n            }\n            if (s.params.slideToClickedSlide && s.clickedIndex !== undefined && s.clickedIndex !== s.activeIndex) {\n                var slideToIndex = s.clickedIndex,\n                    realIndex,\n                    duplicatedSlides;\n                if (s.params.loop) {\n                    if (s.animating) return;\n                    realIndex = $(s.clickedSlide).attr('data-swiper-slide-index');\n                    if (s.params.centeredSlides) {\n                        if ((slideToIndex < s.loopedSlides - s.params.slidesPerView/2) || (slideToIndex > s.slides.length - s.loopedSlides + s.params.slidesPerView/2)) {\n                            s.fixLoop();\n                            slideToIndex = s.wrapper.children('.' + s.params.slideClass + '[data-swiper-slide-index=\"' + realIndex + '\"]:not(.swiper-slide-duplicate)').eq(0).index();\n                            setTimeout(function () {\n                                s.slideTo(slideToIndex);\n                            }, 0);\n                        }\n                        else {\n                            s.slideTo(slideToIndex);\n                        }\n                    }\n                    else {\n                        if (slideToIndex > s.slides.length - s.params.slidesPerView) {\n                            s.fixLoop();\n                            slideToIndex = s.wrapper.children('.' + s.params.slideClass + '[data-swiper-slide-index=\"' + realIndex + '\"]:not(.swiper-slide-duplicate)').eq(0).index();\n                            setTimeout(function () {\n                                s.slideTo(slideToIndex);\n                            }, 0);\n                        }\n                        else {\n                            s.slideTo(slideToIndex);\n                        }\n                    }\n                }\n                else {\n                    s.slideTo(slideToIndex);\n                }\n            }\n        };\n        \n        var isTouched,\n            isMoved,\n            allowTouchCallbacks,\n            touchStartTime,\n            isScrolling,\n            currentTranslate,\n            startTranslate,\n            allowThresholdMove,\n            // Form elements to match\n            formElements = 'input, select, textarea, button',\n            // Last click time\n            lastClickTime = Date.now(), clickTimeout,\n            //Velocities\n            velocities = [],\n            allowMomentumBounce;\n        \n        // Animating Flag\n        s.animating = false;\n        \n        // Touches information\n        s.touches = {\n            startX: 0,\n            startY: 0,\n            currentX: 0,\n            currentY: 0,\n            diff: 0\n        };\n        \n        // Touch handlers\n        var isTouchEvent, startMoving;\n        s.onTouchStart = function (e) {\n            if (e.originalEvent) e = e.originalEvent;\n            isTouchEvent = e.type === 'touchstart';\n            if (!isTouchEvent && 'which' in e && e.which === 3) return;\n            if (s.params.noSwiping && findElementInEvent(e, '.' + s.params.noSwipingClass)) {\n                s.allowClick = true;\n                return;\n            }\n            if (s.params.swipeHandler) {\n                if (!findElementInEvent(e, s.params.swipeHandler)) return;\n            }\n        \n            var startX = s.touches.currentX = e.type === 'touchstart' ? e.targetTouches[0].pageX : e.pageX;\n            var startY = s.touches.currentY = e.type === 'touchstart' ? e.targetTouches[0].pageY : e.pageY;\n        \n            // Do NOT start if iOS edge swipe is detected. Otherwise iOS app (UIWebView) cannot swipe-to-go-back anymore\n            if(s.device.ios && s.params.iOSEdgeSwipeDetection && startX <= s.params.iOSEdgeSwipeThreshold) {\n                return;\n            }\n        \n            isTouched = true;\n            isMoved = false;\n            allowTouchCallbacks = true;\n            isScrolling = undefined;\n            startMoving = undefined;\n            s.touches.startX = startX;\n            s.touches.startY = startY;\n            touchStartTime = Date.now();\n            s.allowClick = true;\n            s.updateContainerSize();\n            s.swipeDirection = undefined;\n            if (s.params.threshold > 0) allowThresholdMove = false;\n            if (e.type !== 'touchstart') {\n                var preventDefault = true;\n                if ($(e.target).is(formElements)) preventDefault = false;\n                if (document.activeElement && $(document.activeElement).is(formElements)) {\n                    document.activeElement.blur();\n                }\n                if (preventDefault) {\n                    e.preventDefault();\n                }\n            }\n            s.emit('onTouchStart', s, e);\n        };\n        \n        s.onTouchMove = function (e) {\n            if (e.originalEvent) e = e.originalEvent;\n            if (isTouchEvent && e.type === 'mousemove') return;\n            if (e.preventedByNestedSwiper) {\n                s.touches.startX = e.type === 'touchmove' ? e.targetTouches[0].pageX : e.pageX;\n                s.touches.startY = e.type === 'touchmove' ? e.targetTouches[0].pageY : e.pageY;\n                return;\n            }\n            if (s.params.onlyExternal) {\n                // isMoved = true;\n                s.allowClick = false;\n                if (isTouched) {\n                    s.touches.startX = s.touches.currentX = e.type === 'touchmove' ? e.targetTouches[0].pageX : e.pageX;\n                    s.touches.startY = s.touches.currentY = e.type === 'touchmove' ? e.targetTouches[0].pageY : e.pageY;\n                    touchStartTime = Date.now();\n                }\n                return;\n            }\n            if (isTouchEvent && document.activeElement) {\n                if (e.target === document.activeElement && $(e.target).is(formElements)) {\n                    isMoved = true;\n                    s.allowClick = false;\n                    return;\n                }\n            }\n            if (allowTouchCallbacks) {\n                s.emit('onTouchMove', s, e);\n            }\n            if (e.targetTouches && e.targetTouches.length > 1) return;\n        \n            s.touches.currentX = e.type === 'touchmove' ? e.targetTouches[0].pageX : e.pageX;\n            s.touches.currentY = e.type === 'touchmove' ? e.targetTouches[0].pageY : e.pageY;\n        \n            if (typeof isScrolling === 'undefined') {\n                var touchAngle = Math.atan2(Math.abs(s.touches.currentY - s.touches.startY), Math.abs(s.touches.currentX - s.touches.startX)) * 180 / Math.PI;\n                isScrolling = s.isHorizontal() ? touchAngle > s.params.touchAngle : (90 - touchAngle > s.params.touchAngle);\n            }\n            if (isScrolling) {\n                s.emit('onTouchMoveOpposite', s, e);\n            }\n            if (typeof startMoving === 'undefined' && s.browser.ieTouch) {\n                if (s.touches.currentX !== s.touches.startX || s.touches.currentY !== s.touches.startY) {\n                    startMoving = true;\n                }\n            }\n            if (!isTouched) return;\n            if (isScrolling)  {\n                isTouched = false;\n                return;\n            }\n            if (!startMoving && s.browser.ieTouch) {\n                return;\n            }\n            s.allowClick = false;\n            s.emit('onSliderMove', s, e);\n            e.preventDefault();\n            if (s.params.touchMoveStopPropagation && !s.params.nested) {\n                e.stopPropagation();\n            }\n        \n            if (!isMoved) {\n                if (params.loop) {\n                    s.fixLoop();\n                }\n                startTranslate = s.getWrapperTranslate();\n                s.setWrapperTransition(0);\n                if (s.animating) {\n                    s.wrapper.trigger('webkitTransitionEnd transitionend oTransitionEnd MSTransitionEnd msTransitionEnd');\n                }\n                if (s.params.autoplay && s.autoplaying) {\n                    if (s.params.autoplayDisableOnInteraction) {\n                        s.stopAutoplay();\n                    }\n                    else {\n                        s.pauseAutoplay();\n                    }\n                }\n                allowMomentumBounce = false;\n                //Grab Cursor\n                if (s.params.grabCursor) {\n                    s.container[0].style.cursor = 'move';\n                    s.container[0].style.cursor = '-webkit-grabbing';\n                    s.container[0].style.cursor = '-moz-grabbin';\n                    s.container[0].style.cursor = 'grabbing';\n                }\n            }\n            isMoved = true;\n        \n            var diff = s.touches.diff = s.isHorizontal() ? s.touches.currentX - s.touches.startX : s.touches.currentY - s.touches.startY;\n        \n            diff = diff * s.params.touchRatio;\n            if (s.rtl) diff = -diff;\n        \n            s.swipeDirection = diff > 0 ? 'prev' : 'next';\n            currentTranslate = diff + startTranslate;\n        \n            var disableParentSwiper = true;\n            if ((diff > 0 && currentTranslate > s.minTranslate())) {\n                disableParentSwiper = false;\n                if (s.params.resistance) currentTranslate = s.minTranslate() - 1 + Math.pow(-s.minTranslate() + startTranslate + diff, s.params.resistanceRatio);\n            }\n            else if (diff < 0 && currentTranslate < s.maxTranslate()) {\n                disableParentSwiper = false;\n                if (s.params.resistance) currentTranslate = s.maxTranslate() + 1 - Math.pow(s.maxTranslate() - startTranslate - diff, s.params.resistanceRatio);\n            }\n        \n            if (disableParentSwiper) {\n                e.preventedByNestedSwiper = true;\n            }\n        \n            // Directions locks\n            if (!s.params.allowSwipeToNext && s.swipeDirection === 'next' && currentTranslate < startTranslate) {\n                currentTranslate = startTranslate;\n            }\n            if (!s.params.allowSwipeToPrev && s.swipeDirection === 'prev' && currentTranslate > startTranslate) {\n                currentTranslate = startTranslate;\n            }\n        \n            if (!s.params.followFinger) return;\n        \n            // Threshold\n            if (s.params.threshold > 0) {\n                if (Math.abs(diff) > s.params.threshold || allowThresholdMove) {\n                    if (!allowThresholdMove) {\n                        allowThresholdMove = true;\n                        s.touches.startX = s.touches.currentX;\n                        s.touches.startY = s.touches.currentY;\n                        currentTranslate = startTranslate;\n                        s.touches.diff = s.isHorizontal() ? s.touches.currentX - s.touches.startX : s.touches.currentY - s.touches.startY;\n                        return;\n                    }\n                }\n                else {\n                    currentTranslate = startTranslate;\n                    return;\n                }\n            }\n            // Update active index in free mode\n            if (s.params.freeMode || s.params.watchSlidesProgress) {\n                s.updateActiveIndex();\n            }\n            if (s.params.freeMode) {\n                //Velocity\n                if (velocities.length === 0) {\n                    velocities.push({\n                        position: s.touches[s.isHorizontal() ? 'startX' : 'startY'],\n                        time: touchStartTime\n                    });\n                }\n                velocities.push({\n                    position: s.touches[s.isHorizontal() ? 'currentX' : 'currentY'],\n                    time: (new window.Date()).getTime()\n                });\n            }\n            // Update progress\n            s.updateProgress(currentTranslate);\n            // Update translate\n            s.setWrapperTranslate(currentTranslate);\n        };\n        s.onTouchEnd = function (e) {\n            if (e.originalEvent) e = e.originalEvent;\n            if (allowTouchCallbacks) {\n                s.emit('onTouchEnd', s, e);\n            }\n            allowTouchCallbacks = false;\n            if (!isTouched) return;\n            //Return Grab Cursor\n            if (s.params.grabCursor && isMoved && isTouched) {\n                s.container[0].style.cursor = 'move';\n                s.container[0].style.cursor = '-webkit-grab';\n                s.container[0].style.cursor = '-moz-grab';\n                s.container[0].style.cursor = 'grab';\n            }\n        \n            // Time diff\n            var touchEndTime = Date.now();\n            var timeDiff = touchEndTime - touchStartTime;\n        \n            // Tap, doubleTap, Click\n            if (s.allowClick) {\n                s.updateClickedSlide(e);\n                s.emit('onTap', s, e);\n                if (timeDiff < 300 && (touchEndTime - lastClickTime) > 300) {\n                    if (clickTimeout) clearTimeout(clickTimeout);\n                    clickTimeout = setTimeout(function () {\n                        if (!s) return;\n                        if (s.params.paginationHide && s.paginationContainer.length > 0 && !$(e.target).hasClass(s.params.bulletClass)) {\n                            s.paginationContainer.toggleClass(s.params.paginationHiddenClass);\n                        }\n                        s.emit('onClick', s, e);\n                    }, 300);\n        \n                }\n                if (timeDiff < 300 && (touchEndTime - lastClickTime) < 300) {\n                    if (clickTimeout) clearTimeout(clickTimeout);\n                    s.emit('onDoubleTap', s, e);\n                }\n            }\n        \n            lastClickTime = Date.now();\n            setTimeout(function () {\n                if (s) s.allowClick = true;\n            }, 0);\n        \n            if (!isTouched || !isMoved || !s.swipeDirection || s.touches.diff === 0 || currentTranslate === startTranslate) {\n                isTouched = isMoved = false;\n                return;\n            }\n            isTouched = isMoved = false;\n        \n            var currentPos;\n            if (s.params.followFinger) {\n                currentPos = s.rtl ? s.translate : -s.translate;\n            }\n            else {\n                currentPos = -currentTranslate;\n            }\n            if (s.params.freeMode) {\n                if (currentPos < -s.minTranslate()) {\n                    s.slideTo(s.activeIndex);\n                    return;\n                }\n                else if (currentPos > -s.maxTranslate()) {\n                    if (s.slides.length < s.snapGrid.length) {\n                        s.slideTo(s.snapGrid.length - 1);\n                    }\n                    else {\n                        s.slideTo(s.slides.length - 1);\n                    }\n                    return;\n                }\n        \n                if (s.params.freeModeMomentum) {\n                    if (velocities.length > 1) {\n                        var lastMoveEvent = velocities.pop(), velocityEvent = velocities.pop();\n        \n                        var distance = lastMoveEvent.position - velocityEvent.position;\n                        var time = lastMoveEvent.time - velocityEvent.time;\n                        s.velocity = distance / time;\n                        s.velocity = s.velocity / 2;\n                        if (Math.abs(s.velocity) < s.params.freeModeMinimumVelocity) {\n                            s.velocity = 0;\n                        }\n                        // this implies that the user stopped moving a finger then released.\n                        // There would be no events with distance zero, so the last event is stale.\n                        if (time > 150 || (new window.Date().getTime() - lastMoveEvent.time) > 300) {\n                            s.velocity = 0;\n                        }\n                    } else {\n                        s.velocity = 0;\n                    }\n        \n                    velocities.length = 0;\n                    var momentumDuration = 1000 * s.params.freeModeMomentumRatio;\n                    var momentumDistance = s.velocity * momentumDuration;\n        \n                    var newPosition = s.translate + momentumDistance;\n                    if (s.rtl) newPosition = - newPosition;\n                    var doBounce = false;\n                    var afterBouncePosition;\n                    var bounceAmount = Math.abs(s.velocity) * 20 * s.params.freeModeMomentumBounceRatio;\n                    if (newPosition < s.maxTranslate()) {\n                        if (s.params.freeModeMomentumBounce) {\n                            if (newPosition + s.maxTranslate() < -bounceAmount) {\n                                newPosition = s.maxTranslate() - bounceAmount;\n                            }\n                            afterBouncePosition = s.maxTranslate();\n                            doBounce = true;\n                            allowMomentumBounce = true;\n                        }\n                        else {\n                            newPosition = s.maxTranslate();\n                        }\n                    }\n                    else if (newPosition > s.minTranslate()) {\n                        if (s.params.freeModeMomentumBounce) {\n                            if (newPosition - s.minTranslate() > bounceAmount) {\n                                newPosition = s.minTranslate() + bounceAmount;\n                            }\n                            afterBouncePosition = s.minTranslate();\n                            doBounce = true;\n                            allowMomentumBounce = true;\n                        }\n                        else {\n                            newPosition = s.minTranslate();\n                        }\n                    }\n                    else if (s.params.freeModeSticky) {\n                        var j = 0,\n                            nextSlide;\n                        for (j = 0; j < s.snapGrid.length; j += 1) {\n                            if (s.snapGrid[j] > -newPosition) {\n                                nextSlide = j;\n                                break;\n                            }\n        \n                        }\n                        if (Math.abs(s.snapGrid[nextSlide] - newPosition) < Math.abs(s.snapGrid[nextSlide - 1] - newPosition) || s.swipeDirection === 'next') {\n                            newPosition = s.snapGrid[nextSlide];\n                        } else {\n                            newPosition = s.snapGrid[nextSlide - 1];\n                        }\n                        if (!s.rtl) newPosition = - newPosition;\n                    }\n                    //Fix duration\n                    if (s.velocity !== 0) {\n                        if (s.rtl) {\n                            momentumDuration = Math.abs((-newPosition - s.translate) / s.velocity);\n                        }\n                        else {\n                            momentumDuration = Math.abs((newPosition - s.translate) / s.velocity);\n                        }\n                    }\n                    else if (s.params.freeModeSticky) {\n                        s.slideReset();\n                        return;\n                    }\n        \n                    if (s.params.freeModeMomentumBounce && doBounce) {\n                        s.updateProgress(afterBouncePosition);\n                        s.setWrapperTransition(momentumDuration);\n                        s.setWrapperTranslate(newPosition);\n                        s.onTransitionStart();\n                        s.animating = true;\n                        s.wrapper.transitionEnd(function () {\n                            if (!s || !allowMomentumBounce) return;\n                            s.emit('onMomentumBounce', s);\n        \n                            s.setWrapperTransition(s.params.speed);\n                            s.setWrapperTranslate(afterBouncePosition);\n                            s.wrapper.transitionEnd(function () {\n                                if (!s) return;\n                                s.onTransitionEnd();\n                            });\n                        });\n                    } else if (s.velocity) {\n                        s.updateProgress(newPosition);\n                        s.setWrapperTransition(momentumDuration);\n                        s.setWrapperTranslate(newPosition);\n                        s.onTransitionStart();\n                        if (!s.animating) {\n                            s.animating = true;\n                            s.wrapper.transitionEnd(function () {\n                                if (!s) return;\n                                s.onTransitionEnd();\n                            });\n                        }\n        \n                    } else {\n                        s.updateProgress(newPosition);\n                    }\n        \n                    s.updateActiveIndex();\n                }\n                if (!s.params.freeModeMomentum || timeDiff >= s.params.longSwipesMs) {\n                    s.updateProgress();\n                    s.updateActiveIndex();\n                }\n                return;\n            }\n        \n            // Find current slide\n            var i, stopIndex = 0, groupSize = s.slidesSizesGrid[0];\n            for (i = 0; i < s.slidesGrid.length; i += s.params.slidesPerGroup) {\n                if (typeof s.slidesGrid[i + s.params.slidesPerGroup] !== 'undefined') {\n                    if (currentPos >= s.slidesGrid[i] && currentPos < s.slidesGrid[i + s.params.slidesPerGroup]) {\n                        stopIndex = i;\n                        groupSize = s.slidesGrid[i + s.params.slidesPerGroup] - s.slidesGrid[i];\n                    }\n                }\n                else {\n                    if (currentPos >= s.slidesGrid[i]) {\n                        stopIndex = i;\n                        groupSize = s.slidesGrid[s.slidesGrid.length - 1] - s.slidesGrid[s.slidesGrid.length - 2];\n                    }\n                }\n            }\n        \n            // Find current slide size\n            var ratio = (currentPos - s.slidesGrid[stopIndex]) / groupSize;\n        \n            if (timeDiff > s.params.longSwipesMs) {\n                // Long touches\n                if (!s.params.longSwipes) {\n                    s.slideTo(s.activeIndex);\n                    return;\n                }\n                if (s.swipeDirection === 'next') {\n                    if (ratio >= s.params.longSwipesRatio) s.slideTo(stopIndex + s.params.slidesPerGroup);\n                    else s.slideTo(stopIndex);\n        \n                }\n                if (s.swipeDirection === 'prev') {\n                    if (ratio > (1 - s.params.longSwipesRatio)) s.slideTo(stopIndex + s.params.slidesPerGroup);\n                    else s.slideTo(stopIndex);\n                }\n            }\n            else {\n                // Short swipes\n                if (!s.params.shortSwipes) {\n                    s.slideTo(s.activeIndex);\n                    return;\n                }\n                if (s.swipeDirection === 'next') {\n                    s.slideTo(stopIndex + s.params.slidesPerGroup);\n        \n                }\n                if (s.swipeDirection === 'prev') {\n                    s.slideTo(stopIndex);\n                }\n            }\n        };\n        /*=========================\n          Transitions\n          ===========================*/\n        s._slideTo = function (slideIndex, speed) {\n            return s.slideTo(slideIndex, speed, true, true);\n        };\n        s.slideTo = function (slideIndex, speed, runCallbacks, internal) {\n            if (typeof runCallbacks === 'undefined') runCallbacks = true;\n            if (typeof slideIndex === 'undefined') slideIndex = 0;\n            if (slideIndex < 0) slideIndex = 0;\n            s.snapIndex = Math.floor(slideIndex / s.params.slidesPerGroup);\n            if (s.snapIndex >= s.snapGrid.length) s.snapIndex = s.snapGrid.length - 1;\n        \n            var translate = - s.snapGrid[s.snapIndex];\n            // Stop autoplay\n            if (s.params.autoplay && s.autoplaying) {\n                if (internal || !s.params.autoplayDisableOnInteraction) {\n                    s.pauseAutoplay(speed);\n                }\n                else {\n                    s.stopAutoplay();\n                }\n            }\n            // Update progress\n            s.updateProgress(translate);\n        \n            // Normalize slideIndex\n            for (var i = 0; i < s.slidesGrid.length; i++) {\n                if (- Math.floor(translate * 100) >= Math.floor(s.slidesGrid[i] * 100)) {\n                    slideIndex = i;\n                }\n            }\n        \n            // Directions locks\n            if (!s.params.allowSwipeToNext && translate < s.translate && translate < s.minTranslate()) {\n                return false;\n            }\n            if (!s.params.allowSwipeToPrev && translate > s.translate && translate > s.maxTranslate()) {\n                if ((s.activeIndex || 0) !== slideIndex ) return false;\n            }\n        \n            // Update Index\n            if (typeof speed === 'undefined') speed = s.params.speed;\n            s.previousIndex = s.activeIndex || 0;\n            s.activeIndex = slideIndex;\n        \n            if ((s.rtl && -translate === s.translate) || (!s.rtl && translate === s.translate)) {\n                // Update Height\n                if (s.params.autoHeight) {\n                    s.updateAutoHeight();\n                }\n                s.updateClasses();\n                if (s.params.effect !== 'slide') {\n                    s.setWrapperTranslate(translate);\n                }\n                return false;\n            }\n            s.updateClasses();\n            s.onTransitionStart(runCallbacks);\n        \n            if (speed === 0) {\n                s.setWrapperTranslate(translate);\n                s.setWrapperTransition(0);\n                s.onTransitionEnd(runCallbacks);\n            }\n            else {\n                s.setWrapperTranslate(translate);\n                s.setWrapperTransition(speed);\n                if (!s.animating) {\n                    s.animating = true;\n                    s.wrapper.transitionEnd(function () {\n                        if (!s) return;\n                        s.onTransitionEnd(runCallbacks);\n                    });\n                }\n        \n            }\n        \n            return true;\n        };\n        \n        s.onTransitionStart = function (runCallbacks) {\n            if (typeof runCallbacks === 'undefined') runCallbacks = true;\n            if (s.params.autoHeight) {\n                s.updateAutoHeight();\n            }\n            if (s.lazy) s.lazy.onTransitionStart();\n            if (runCallbacks) {\n                s.emit('onTransitionStart', s);\n                if (s.activeIndex !== s.previousIndex) {\n                    s.emit('onSlideChangeStart', s);\n                    if (s.activeIndex > s.previousIndex) {\n                        s.emit('onSlideNextStart', s);\n                    }\n                    else {\n                        s.emit('onSlidePrevStart', s);\n                    }\n                }\n        \n            }\n        };\n        s.onTransitionEnd = function (runCallbacks) {\n            s.animating = false;\n            s.setWrapperTransition(0);\n            if (typeof runCallbacks === 'undefined') runCallbacks = true;\n            if (s.lazy) s.lazy.onTransitionEnd();\n            if (runCallbacks) {\n                s.emit('onTransitionEnd', s);\n                if (s.activeIndex !== s.previousIndex) {\n                    s.emit('onSlideChangeEnd', s);\n                    if (s.activeIndex > s.previousIndex) {\n                        s.emit('onSlideNextEnd', s);\n                    }\n                    else {\n                        s.emit('onSlidePrevEnd', s);\n                    }\n                }\n            }\n            if (s.params.hashnav && s.hashnav) {\n                s.hashnav.setHash();\n            }\n        \n        };\n        s.slideNext = function (runCallbacks, speed, internal) {\n            if (s.params.loop) {\n                if (s.animating) return false;\n                s.fixLoop();\n                var clientLeft = s.container[0].clientLeft;\n                return s.slideTo(s.activeIndex + s.params.slidesPerGroup, speed, runCallbacks, internal);\n            }\n            else return s.slideTo(s.activeIndex + s.params.slidesPerGroup, speed, runCallbacks, internal);\n        };\n        s._slideNext = function (speed) {\n            return s.slideNext(true, speed, true);\n        };\n        s.slidePrev = function (runCallbacks, speed, internal) {\n            if (s.params.loop) {\n                if (s.animating) return false;\n                s.fixLoop();\n                var clientLeft = s.container[0].clientLeft;\n                return s.slideTo(s.activeIndex - 1, speed, runCallbacks, internal);\n            }\n            else return s.slideTo(s.activeIndex - 1, speed, runCallbacks, internal);\n        };\n        s._slidePrev = function (speed) {\n            return s.slidePrev(true, speed, true);\n        };\n        s.slideReset = function (runCallbacks, speed, internal) {\n            return s.slideTo(s.activeIndex, speed, runCallbacks);\n        };\n        \n        /*=========================\n          Translate/transition helpers\n          ===========================*/\n        s.setWrapperTransition = function (duration, byController) {\n            s.wrapper.transition(duration);\n            if (s.params.effect !== 'slide' && s.effects[s.params.effect]) {\n                s.effects[s.params.effect].setTransition(duration);\n            }\n            if (s.params.parallax && s.parallax) {\n                s.parallax.setTransition(duration);\n            }\n            if (s.params.scrollbar && s.scrollbar) {\n                s.scrollbar.setTransition(duration);\n            }\n            if (s.params.control && s.controller) {\n                s.controller.setTransition(duration, byController);\n            }\n            s.emit('onSetTransition', s, duration);\n        };\n        s.setWrapperTranslate = function (translate, updateActiveIndex, byController) {\n            var x = 0, y = 0, z = 0;\n            if (s.isHorizontal()) {\n                x = s.rtl ? -translate : translate;\n            }\n            else {\n                y = translate;\n            }\n        \n            if (s.params.roundLengths) {\n                x = round(x);\n                y = round(y);\n            }\n        \n            if (!s.params.virtualTranslate) {\n                if (s.support.transforms3d) s.wrapper.transform('translate3d(' + x + 'px, ' + y + 'px, ' + z + 'px)');\n                else s.wrapper.transform('translate(' + x + 'px, ' + y + 'px)');\n            }\n        \n            s.translate = s.isHorizontal() ? x : y;\n        \n            // Check if we need to update progress\n            var progress;\n            var translatesDiff = s.maxTranslate() - s.minTranslate();\n            if (translatesDiff === 0) {\n                progress = 0;\n            }\n            else {\n                progress = (translate - s.minTranslate()) / (translatesDiff);\n            }\n            if (progress !== s.progress) {\n                s.updateProgress(translate);\n            }\n        \n            if (updateActiveIndex) s.updateActiveIndex();\n            if (s.params.effect !== 'slide' && s.effects[s.params.effect]) {\n                s.effects[s.params.effect].setTranslate(s.translate);\n            }\n            if (s.params.parallax && s.parallax) {\n                s.parallax.setTranslate(s.translate);\n            }\n            if (s.params.scrollbar && s.scrollbar) {\n                s.scrollbar.setTranslate(s.translate);\n            }\n            if (s.params.control && s.controller) {\n                s.controller.setTranslate(s.translate, byController);\n            }\n            s.emit('onSetTranslate', s, s.translate);\n        };\n        \n        s.getTranslate = function (el, axis) {\n            var matrix, curTransform, curStyle, transformMatrix;\n        \n            // automatic axis detection\n            if (typeof axis === 'undefined') {\n                axis = 'x';\n            }\n        \n            if (s.params.virtualTranslate) {\n                return s.rtl ? -s.translate : s.translate;\n            }\n        \n            curStyle = window.getComputedStyle(el, null);\n            if (window.WebKitCSSMatrix) {\n                curTransform = curStyle.transform || curStyle.webkitTransform;\n                if (curTransform.split(',').length > 6) {\n                    curTransform = curTransform.split(', ').map(function(a){\n                        return a.replace(',','.');\n                    }).join(', ');\n                }\n                // Some old versions of Webkit choke when 'none' is passed; pass\n                // empty string instead in this case\n                transformMatrix = new window.WebKitCSSMatrix(curTransform === 'none' ? '' : curTransform);\n            }\n            else {\n                transformMatrix = curStyle.MozTransform || curStyle.OTransform || curStyle.MsTransform || curStyle.msTransform  || curStyle.transform || curStyle.getPropertyValue('transform').replace('translate(', 'matrix(1, 0, 0, 1,');\n                matrix = transformMatrix.toString().split(',');\n            }\n        \n            if (axis === 'x') {\n                //Latest Chrome and webkits Fix\n                if (window.WebKitCSSMatrix)\n                    curTransform = transformMatrix.m41;\n                //Crazy IE10 Matrix\n                else if (matrix.length === 16)\n                    curTransform = parseFloat(matrix[12]);\n                //Normal Browsers\n                else\n                    curTransform = parseFloat(matrix[4]);\n            }\n            if (axis === 'y') {\n                //Latest Chrome and webkits Fix\n                if (window.WebKitCSSMatrix)\n                    curTransform = transformMatrix.m42;\n                //Crazy IE10 Matrix\n                else if (matrix.length === 16)\n                    curTransform = parseFloat(matrix[13]);\n                //Normal Browsers\n                else\n                    curTransform = parseFloat(matrix[5]);\n            }\n            if (s.rtl && curTransform) curTransform = -curTransform;\n            return curTransform || 0;\n        };\n        s.getWrapperTranslate = function (axis) {\n            if (typeof axis === 'undefined') {\n                axis = s.isHorizontal() ? 'x' : 'y';\n            }\n            return s.getTranslate(s.wrapper[0], axis);\n        };\n        \n        /*=========================\n          Observer\n          ===========================*/\n        s.observers = [];\n        function initObserver(target, options) {\n            options = options || {};\n            // create an observer instance\n            var ObserverFunc = window.MutationObserver || window.WebkitMutationObserver;\n            var observer = new ObserverFunc(function (mutations) {\n                mutations.forEach(function (mutation) {\n                    s.onResize(true);\n                    s.emit('onObserverUpdate', s, mutation);\n                });\n            });\n        \n            observer.observe(target, {\n                attributes: typeof options.attributes === 'undefined' ? true : options.attributes,\n                childList: typeof options.childList === 'undefined' ? true : options.childList,\n                characterData: typeof options.characterData === 'undefined' ? true : options.characterData\n            });\n        \n            s.observers.push(observer);\n        }\n        s.initObservers = function () {\n            if (s.params.observeParents) {\n                var containerParents = s.container.parents();\n                for (var i = 0; i < containerParents.length; i++) {\n                    initObserver(containerParents[i]);\n                }\n            }\n        \n            // Observe container\n            initObserver(s.container[0], {childList: false});\n        \n            // Observe wrapper\n            initObserver(s.wrapper[0], {attributes: false});\n        };\n        s.disconnectObservers = function () {\n            for (var i = 0; i < s.observers.length; i++) {\n                s.observers[i].disconnect();\n            }\n            s.observers = [];\n        };\n        /*=========================\n          Loop\n          ===========================*/\n        // Create looped slides\n        s.createLoop = function () {\n            // Remove duplicated slides\n            s.wrapper.children('.' + s.params.slideClass + '.' + s.params.slideDuplicateClass).remove();\n        \n            var slides = s.wrapper.children('.' + s.params.slideClass);\n        \n            if(s.params.slidesPerView === 'auto' && !s.params.loopedSlides) s.params.loopedSlides = slides.length;\n        \n            s.loopedSlides = parseInt(s.params.loopedSlides || s.params.slidesPerView, 10);\n            s.loopedSlides = s.loopedSlides + s.params.loopAdditionalSlides;\n            if (s.loopedSlides > slides.length) {\n                s.loopedSlides = slides.length;\n            }\n        \n            var prependSlides = [], appendSlides = [], i;\n            slides.each(function (index, el) {\n                var slide = $(this);\n                if (index < s.loopedSlides) appendSlides.push(el);\n                if (index < slides.length && index >= slides.length - s.loopedSlides) prependSlides.push(el);\n                slide.attr('data-swiper-slide-index', index);\n            });\n            for (i = 0; i < appendSlides.length; i++) {\n                s.wrapper.append($(appendSlides[i].cloneNode(true)).addClass(s.params.slideDuplicateClass));\n            }\n            for (i = prependSlides.length - 1; i >= 0; i--) {\n                s.wrapper.prepend($(prependSlides[i].cloneNode(true)).addClass(s.params.slideDuplicateClass));\n            }\n        };\n        s.destroyLoop = function () {\n            s.wrapper.children('.' + s.params.slideClass + '.' + s.params.slideDuplicateClass).remove();\n            s.slides.removeAttr('data-swiper-slide-index');\n        };\n        s.reLoop = function (updatePosition) {\n            var oldIndex = s.activeIndex - s.loopedSlides;\n            s.destroyLoop();\n            s.createLoop();\n            s.updateSlidesSize();\n            if (updatePosition) {\n                s.slideTo(oldIndex + s.loopedSlides, 0, false);\n            }\n        \n        };\n        s.fixLoop = function () {\n            var newIndex;\n            //Fix For Negative Oversliding\n            if (s.activeIndex < s.loopedSlides) {\n                newIndex = s.slides.length - s.loopedSlides * 3 + s.activeIndex;\n                newIndex = newIndex + s.loopedSlides;\n                s.slideTo(newIndex, 0, false, true);\n            }\n            //Fix For Positive Oversliding\n            else if ((s.params.slidesPerView === 'auto' && s.activeIndex >= s.loopedSlides * 2) || (s.activeIndex > s.slides.length - s.params.slidesPerView * 2)) {\n                newIndex = -s.slides.length + s.activeIndex + s.loopedSlides;\n                newIndex = newIndex + s.loopedSlides;\n                s.slideTo(newIndex, 0, false, true);\n            }\n        };\n        /*=========================\n          Append/Prepend/Remove Slides\n          ===========================*/\n        s.appendSlide = function (slides) {\n            if (s.params.loop) {\n                s.destroyLoop();\n            }\n            if (typeof slides === 'object' && slides.length) {\n                for (var i = 0; i < slides.length; i++) {\n                    if (slides[i]) s.wrapper.append(slides[i]);\n                }\n            }\n            else {\n                s.wrapper.append(slides);\n            }\n            if (s.params.loop) {\n                s.createLoop();\n            }\n            if (!(s.params.observer && s.support.observer)) {\n                s.update(true);\n            }\n        };\n        s.prependSlide = function (slides) {\n            if (s.params.loop) {\n                s.destroyLoop();\n            }\n            var newActiveIndex = s.activeIndex + 1;\n            if (typeof slides === 'object' && slides.length) {\n                for (var i = 0; i < slides.length; i++) {\n                    if (slides[i]) s.wrapper.prepend(slides[i]);\n                }\n                newActiveIndex = s.activeIndex + slides.length;\n            }\n            else {\n                s.wrapper.prepend(slides);\n            }\n            if (s.params.loop) {\n                s.createLoop();\n            }\n            if (!(s.params.observer && s.support.observer)) {\n                s.update(true);\n            }\n            s.slideTo(newActiveIndex, 0, false);\n        };\n        s.removeSlide = function (slidesIndexes) {\n            if (s.params.loop) {\n                s.destroyLoop();\n                s.slides = s.wrapper.children('.' + s.params.slideClass);\n            }\n            var newActiveIndex = s.activeIndex,\n                indexToRemove;\n            if (typeof slidesIndexes === 'object' && slidesIndexes.length) {\n                for (var i = 0; i < slidesIndexes.length; i++) {\n                    indexToRemove = slidesIndexes[i];\n                    if (s.slides[indexToRemove]) s.slides.eq(indexToRemove).remove();\n                    if (indexToRemove < newActiveIndex) newActiveIndex--;\n                }\n                newActiveIndex = Math.max(newActiveIndex, 0);\n            }\n            else {\n                indexToRemove = slidesIndexes;\n                if (s.slides[indexToRemove]) s.slides.eq(indexToRemove).remove();\n                if (indexToRemove < newActiveIndex) newActiveIndex--;\n                newActiveIndex = Math.max(newActiveIndex, 0);\n            }\n        \n            if (s.params.loop) {\n                s.createLoop();\n            }\n        \n            if (!(s.params.observer && s.support.observer)) {\n                s.update(true);\n            }\n            if (s.params.loop) {\n                s.slideTo(newActiveIndex + s.loopedSlides, 0, false);\n            }\n            else {\n                s.slideTo(newActiveIndex, 0, false);\n            }\n        \n        };\n        s.removeAllSlides = function () {\n            var slidesIndexes = [];\n            for (var i = 0; i < s.slides.length; i++) {\n                slidesIndexes.push(i);\n            }\n            s.removeSlide(slidesIndexes);\n        };\n        \n\n        /*=========================\n          Effects\n          ===========================*/\n        s.effects = {\n            fade: {\n                setTranslate: function () {\n                    for (var i = 0; i < s.slides.length; i++) {\n                        var slide = s.slides.eq(i);\n                        var offset = slide[0].swiperSlideOffset;\n                        var tx = -offset;\n                        if (!s.params.virtualTranslate) tx = tx - s.translate;\n                        var ty = 0;\n                        if (!s.isHorizontal()) {\n                            ty = tx;\n                            tx = 0;\n                        }\n                        var slideOpacity = s.params.fade.crossFade ?\n                                Math.max(1 - Math.abs(slide[0].progress), 0) :\n                                1 + Math.min(Math.max(slide[0].progress, -1), 0);\n                        slide\n                            .css({\n                                opacity: slideOpacity\n                            })\n                            .transform('translate3d(' + tx + 'px, ' + ty + 'px, 0px)');\n        \n                    }\n        \n                },\n                setTransition: function (duration) {\n                    s.slides.transition(duration);\n                    if (s.params.virtualTranslate && duration !== 0) {\n                        var eventTriggered = false;\n                        s.slides.transitionEnd(function () {\n                            if (eventTriggered) return;\n                            if (!s) return;\n                            eventTriggered = true;\n                            s.animating = false;\n                            var triggerEvents = ['webkitTransitionEnd', 'transitionend', 'oTransitionEnd', 'MSTransitionEnd', 'msTransitionEnd'];\n                            for (var i = 0; i < triggerEvents.length; i++) {\n                                s.wrapper.trigger(triggerEvents[i]);\n                            }\n                        });\n                    }\n                }\n            },\n            flip: {\n                setTranslate: function () {\n                    for (var i = 0; i < s.slides.length; i++) {\n                        var slide = s.slides.eq(i);\n                        var progress = slide[0].progress;\n                        if (s.params.flip.limitRotation) {\n                            progress = Math.max(Math.min(slide[0].progress, 1), -1);\n                        }\n                        var offset = slide[0].swiperSlideOffset;\n                        var rotate = -180 * progress,\n                            rotateY = rotate,\n                            rotateX = 0,\n                            tx = -offset,\n                            ty = 0;\n                        if (!s.isHorizontal()) {\n                            ty = tx;\n                            tx = 0;\n                            rotateX = -rotateY;\n                            rotateY = 0;\n                        }\n                        else if (s.rtl) {\n                            rotateY = -rotateY;\n                        }\n        \n                        slide[0].style.zIndex = -Math.abs(Math.round(progress)) + s.slides.length;\n        \n                        if (s.params.flip.slideShadows) {\n                            //Set shadows\n                            var shadowBefore = s.isHorizontal() ? slide.find('.swiper-slide-shadow-left') : slide.find('.swiper-slide-shadow-top');\n                            var shadowAfter = s.isHorizontal() ? slide.find('.swiper-slide-shadow-right') : slide.find('.swiper-slide-shadow-bottom');\n                            if (shadowBefore.length === 0) {\n                                shadowBefore = $('<div class=\"swiper-slide-shadow-' + (s.isHorizontal() ? 'left' : 'top') + '\"></div>');\n                                slide.append(shadowBefore);\n                            }\n                            if (shadowAfter.length === 0) {\n                                shadowAfter = $('<div class=\"swiper-slide-shadow-' + (s.isHorizontal() ? 'right' : 'bottom') + '\"></div>');\n                                slide.append(shadowAfter);\n                            }\n                            if (shadowBefore.length) shadowBefore[0].style.opacity = Math.max(-progress, 0);\n                            if (shadowAfter.length) shadowAfter[0].style.opacity = Math.max(progress, 0);\n                        }\n        \n                        slide\n                            .transform('translate3d(' + tx + 'px, ' + ty + 'px, 0px) rotateX(' + rotateX + 'deg) rotateY(' + rotateY + 'deg)');\n                    }\n                },\n                setTransition: function (duration) {\n                    s.slides.transition(duration).find('.swiper-slide-shadow-top, .swiper-slide-shadow-right, .swiper-slide-shadow-bottom, .swiper-slide-shadow-left').transition(duration);\n                    if (s.params.virtualTranslate && duration !== 0) {\n                        var eventTriggered = false;\n                        s.slides.eq(s.activeIndex).transitionEnd(function () {\n                            if (eventTriggered) return;\n                            if (!s) return;\n                            if (!$(this).hasClass(s.params.slideActiveClass)) return;\n                            eventTriggered = true;\n                            s.animating = false;\n                            var triggerEvents = ['webkitTransitionEnd', 'transitionend', 'oTransitionEnd', 'MSTransitionEnd', 'msTransitionEnd'];\n                            for (var i = 0; i < triggerEvents.length; i++) {\n                                s.wrapper.trigger(triggerEvents[i]);\n                            }\n                        });\n                    }\n                }\n            },\n            cube: {\n                setTranslate: function () {\n                    var wrapperRotate = 0, cubeShadow;\n                    if (s.params.cube.shadow) {\n                        if (s.isHorizontal()) {\n                            cubeShadow = s.wrapper.find('.swiper-cube-shadow');\n                            if (cubeShadow.length === 0) {\n                                cubeShadow = $('<div class=\"swiper-cube-shadow\"></div>');\n                                s.wrapper.append(cubeShadow);\n                            }\n                            cubeShadow.css({height: s.width + 'px'});\n                        }\n                        else {\n                            cubeShadow = s.container.find('.swiper-cube-shadow');\n                            if (cubeShadow.length === 0) {\n                                cubeShadow = $('<div class=\"swiper-cube-shadow\"></div>');\n                                s.container.append(cubeShadow);\n                            }\n                        }\n                    }\n                    for (var i = 0; i < s.slides.length; i++) {\n                        var slide = s.slides.eq(i);\n                        var slideAngle = i * 90;\n                        var round = Math.floor(slideAngle / 360);\n                        if (s.rtl) {\n                            slideAngle = -slideAngle;\n                            round = Math.floor(-slideAngle / 360);\n                        }\n                        var progress = Math.max(Math.min(slide[0].progress, 1), -1);\n                        var tx = 0, ty = 0, tz = 0;\n                        if (i % 4 === 0) {\n                            tx = - round * 4 * s.size;\n                            tz = 0;\n                        }\n                        else if ((i - 1) % 4 === 0) {\n                            tx = 0;\n                            tz = - round * 4 * s.size;\n                        }\n                        else if ((i - 2) % 4 === 0) {\n                            tx = s.size + round * 4 * s.size;\n                            tz = s.size;\n                        }\n                        else if ((i - 3) % 4 === 0) {\n                            tx = - s.size;\n                            tz = 3 * s.size + s.size * 4 * round;\n                        }\n                        if (s.rtl) {\n                            tx = -tx;\n                        }\n        \n                        if (!s.isHorizontal()) {\n                            ty = tx;\n                            tx = 0;\n                        }\n        \n                        var transform = 'rotateX(' + (s.isHorizontal() ? 0 : -slideAngle) + 'deg) rotateY(' + (s.isHorizontal() ? slideAngle : 0) + 'deg) translate3d(' + tx + 'px, ' + ty + 'px, ' + tz + 'px)';\n                        if (progress <= 1 && progress > -1) {\n                            wrapperRotate = i * 90 + progress * 90;\n                            if (s.rtl) wrapperRotate = -i * 90 - progress * 90;\n                        }\n                        slide.transform(transform);\n                        if (s.params.cube.slideShadows) {\n                            //Set shadows\n                            var shadowBefore = s.isHorizontal() ? slide.find('.swiper-slide-shadow-left') : slide.find('.swiper-slide-shadow-top');\n                            var shadowAfter = s.isHorizontal() ? slide.find('.swiper-slide-shadow-right') : slide.find('.swiper-slide-shadow-bottom');\n                            if (shadowBefore.length === 0) {\n                                shadowBefore = $('<div class=\"swiper-slide-shadow-' + (s.isHorizontal() ? 'left' : 'top') + '\"></div>');\n                                slide.append(shadowBefore);\n                            }\n                            if (shadowAfter.length === 0) {\n                                shadowAfter = $('<div class=\"swiper-slide-shadow-' + (s.isHorizontal() ? 'right' : 'bottom') + '\"></div>');\n                                slide.append(shadowAfter);\n                            }\n                            if (shadowBefore.length) shadowBefore[0].style.opacity = Math.max(-progress, 0);\n                            if (shadowAfter.length) shadowAfter[0].style.opacity = Math.max(progress, 0);\n                        }\n                    }\n                    s.wrapper.css({\n                        '-webkit-transform-origin': '50% 50% -' + (s.size / 2) + 'px',\n                        '-moz-transform-origin': '50% 50% -' + (s.size / 2) + 'px',\n                        '-ms-transform-origin': '50% 50% -' + (s.size / 2) + 'px',\n                        'transform-origin': '50% 50% -' + (s.size / 2) + 'px'\n                    });\n        \n                    if (s.params.cube.shadow) {\n                        if (s.isHorizontal()) {\n                            cubeShadow.transform('translate3d(0px, ' + (s.width / 2 + s.params.cube.shadowOffset) + 'px, ' + (-s.width / 2) + 'px) rotateX(90deg) rotateZ(0deg) scale(' + (s.params.cube.shadowScale) + ')');\n                        }\n                        else {\n                            var shadowAngle = Math.abs(wrapperRotate) - Math.floor(Math.abs(wrapperRotate) / 90) * 90;\n                            var multiplier = 1.5 - (Math.sin(shadowAngle * 2 * Math.PI / 360) / 2 + Math.cos(shadowAngle * 2 * Math.PI / 360) / 2);\n                            var scale1 = s.params.cube.shadowScale,\n                                scale2 = s.params.cube.shadowScale / multiplier,\n                                offset = s.params.cube.shadowOffset;\n                            cubeShadow.transform('scale3d(' + scale1 + ', 1, ' + scale2 + ') translate3d(0px, ' + (s.height / 2 + offset) + 'px, ' + (-s.height / 2 / scale2) + 'px) rotateX(-90deg)');\n                        }\n                    }\n                    var zFactor = (s.isSafari || s.isUiWebView) ? (-s.size / 2) : 0;\n                    s.wrapper.transform('translate3d(0px,0,' + zFactor + 'px) rotateX(' + (s.isHorizontal() ? 0 : wrapperRotate) + 'deg) rotateY(' + (s.isHorizontal() ? -wrapperRotate : 0) + 'deg)');\n                },\n                setTransition: function (duration) {\n                    s.slides.transition(duration).find('.swiper-slide-shadow-top, .swiper-slide-shadow-right, .swiper-slide-shadow-bottom, .swiper-slide-shadow-left').transition(duration);\n                    if (s.params.cube.shadow && !s.isHorizontal()) {\n                        s.container.find('.swiper-cube-shadow').transition(duration);\n                    }\n                }\n            },\n            coverflow: {\n                setTranslate: function () {\n                    var transform = s.translate;\n                    var center = s.isHorizontal() ? -transform + s.width / 2 : -transform + s.height / 2;\n                    var rotate = s.isHorizontal() ? s.params.coverflow.rotate: -s.params.coverflow.rotate;\n                    var translate = s.params.coverflow.depth;\n                    //Each slide offset from center\n                    for (var i = 0, length = s.slides.length; i < length; i++) {\n                        var slide = s.slides.eq(i);\n                        var slideSize = s.slidesSizesGrid[i];\n                        var slideOffset = slide[0].swiperSlideOffset;\n                        var offsetMultiplier = (center - slideOffset - slideSize / 2) / slideSize * s.params.coverflow.modifier;\n        \n                        var rotateY = s.isHorizontal() ? rotate * offsetMultiplier : 0;\n                        var rotateX = s.isHorizontal() ? 0 : rotate * offsetMultiplier;\n                        // var rotateZ = 0\n                        var translateZ = -translate * Math.abs(offsetMultiplier);\n        \n                        var translateY = s.isHorizontal() ? 0 : s.params.coverflow.stretch * (offsetMultiplier);\n                        var translateX = s.isHorizontal() ? s.params.coverflow.stretch * (offsetMultiplier) : 0;\n        \n                        //Fix for ultra small values\n                        if (Math.abs(translateX) < 0.001) translateX = 0;\n                        if (Math.abs(translateY) < 0.001) translateY = 0;\n                        if (Math.abs(translateZ) < 0.001) translateZ = 0;\n                        if (Math.abs(rotateY) < 0.001) rotateY = 0;\n                        if (Math.abs(rotateX) < 0.001) rotateX = 0;\n        \n                        var slideTransform = 'translate3d(' + translateX + 'px,' + translateY + 'px,' + translateZ + 'px)  rotateX(' + rotateX + 'deg) rotateY(' + rotateY + 'deg)';\n        \n                        slide.transform(slideTransform);\n                        slide[0].style.zIndex = -Math.abs(Math.round(offsetMultiplier)) + 1;\n                        if (s.params.coverflow.slideShadows) {\n                            //Set shadows\n                            var shadowBefore = s.isHorizontal() ? slide.find('.swiper-slide-shadow-left') : slide.find('.swiper-slide-shadow-top');\n                            var shadowAfter = s.isHorizontal() ? slide.find('.swiper-slide-shadow-right') : slide.find('.swiper-slide-shadow-bottom');\n                            if (shadowBefore.length === 0) {\n                                shadowBefore = $('<div class=\"swiper-slide-shadow-' + (s.isHorizontal() ? 'left' : 'top') + '\"></div>');\n                                slide.append(shadowBefore);\n                            }\n                            if (shadowAfter.length === 0) {\n                                shadowAfter = $('<div class=\"swiper-slide-shadow-' + (s.isHorizontal() ? 'right' : 'bottom') + '\"></div>');\n                                slide.append(shadowAfter);\n                            }\n                            if (shadowBefore.length) shadowBefore[0].style.opacity = offsetMultiplier > 0 ? offsetMultiplier : 0;\n                            if (shadowAfter.length) shadowAfter[0].style.opacity = (-offsetMultiplier) > 0 ? -offsetMultiplier : 0;\n                        }\n                    }\n        \n                    //Set correct perspective for IE10\n                    if (s.browser.ie) {\n                        var ws = s.wrapper[0].style;\n                        ws.perspectiveOrigin = center + 'px 50%';\n                    }\n                },\n                setTransition: function (duration) {\n                    s.slides.transition(duration).find('.swiper-slide-shadow-top, .swiper-slide-shadow-right, .swiper-slide-shadow-bottom, .swiper-slide-shadow-left').transition(duration);\n                }\n            }\n        };\n\n        /*=========================\n          Images Lazy Loading\n          ===========================*/\n        s.lazy = {\n            initialImageLoaded: false,\n            loadImageInSlide: function (index, loadInDuplicate) {\n                if (typeof index === 'undefined') return;\n                if (typeof loadInDuplicate === 'undefined') loadInDuplicate = true;\n                if (s.slides.length === 0) return;\n        \n                var slide = s.slides.eq(index);\n                var img = slide.find('.swiper-lazy:not(.swiper-lazy-loaded):not(.swiper-lazy-loading)');\n                if (slide.hasClass('swiper-lazy') && !slide.hasClass('swiper-lazy-loaded') && !slide.hasClass('swiper-lazy-loading')) {\n                    img = img.add(slide[0]);\n                }\n                if (img.length === 0) return;\n        \n                img.each(function () {\n                    var _img = $(this);\n                    _img.addClass('swiper-lazy-loading');\n                    var background = _img.attr('data-background');\n                    var src = _img.attr('data-src'),\n                        srcset = _img.attr('data-srcset');\n                    s.loadImage(_img[0], (src || background), srcset, false, function () {\n                        if (background) {\n                            _img.css('background-image', 'url(\"' + background + '\")');\n                            _img.removeAttr('data-background');\n                        }\n                        else {\n                            if (srcset) {\n                                _img.attr('srcset', srcset);\n                                _img.removeAttr('data-srcset');\n                            }\n                            if (src) {\n                                _img.attr('src', src);\n                                _img.removeAttr('data-src');\n                            }\n        \n                        }\n        \n                        _img.addClass('swiper-lazy-loaded').removeClass('swiper-lazy-loading');\n                        slide.find('.swiper-lazy-preloader, .preloader').remove();\n                        if (s.params.loop && loadInDuplicate) {\n                            var slideOriginalIndex = slide.attr('data-swiper-slide-index');\n                            if (slide.hasClass(s.params.slideDuplicateClass)) {\n                                var originalSlide = s.wrapper.children('[data-swiper-slide-index=\"' + slideOriginalIndex + '\"]:not(.' + s.params.slideDuplicateClass + ')');\n                                s.lazy.loadImageInSlide(originalSlide.index(), false);\n                            }\n                            else {\n                                var duplicatedSlide = s.wrapper.children('.' + s.params.slideDuplicateClass + '[data-swiper-slide-index=\"' + slideOriginalIndex + '\"]');\n                                s.lazy.loadImageInSlide(duplicatedSlide.index(), false);\n                            }\n                        }\n                        s.emit('onLazyImageReady', s, slide[0], _img[0]);\n                    });\n        \n                    s.emit('onLazyImageLoad', s, slide[0], _img[0]);\n                });\n        \n            },\n            load: function () {\n                var i;\n                if (s.params.watchSlidesVisibility) {\n                    s.wrapper.children('.' + s.params.slideVisibleClass).each(function () {\n                        s.lazy.loadImageInSlide($(this).index());\n                    });\n                }\n                else {\n                    if (s.params.slidesPerView > 1) {\n                        for (i = s.activeIndex; i < s.activeIndex + s.params.slidesPerView ; i++) {\n                            if (s.slides[i]) s.lazy.loadImageInSlide(i);\n                        }\n                    }\n                    else {\n                        s.lazy.loadImageInSlide(s.activeIndex);\n                    }\n                }\n                if (s.params.lazyLoadingInPrevNext) {\n                    if (s.params.slidesPerView > 1 || (s.params.lazyLoadingInPrevNextAmount && s.params.lazyLoadingInPrevNextAmount > 1)) {\n                        var amount = s.params.lazyLoadingInPrevNextAmount;\n                        var spv = s.params.slidesPerView;\n                        var maxIndex = Math.min(s.activeIndex + spv + Math.max(amount, spv), s.slides.length);\n                        var minIndex = Math.max(s.activeIndex - Math.max(spv, amount), 0);\n                        // Next Slides\n                        for (i = s.activeIndex + s.params.slidesPerView; i < maxIndex; i++) {\n                            if (s.slides[i]) s.lazy.loadImageInSlide(i);\n                        }\n                        // Prev Slides\n                        for (i = minIndex; i < s.activeIndex ; i++) {\n                            if (s.slides[i]) s.lazy.loadImageInSlide(i);\n                        }\n                    }\n                    else {\n                        var nextSlide = s.wrapper.children('.' + s.params.slideNextClass);\n                        if (nextSlide.length > 0) s.lazy.loadImageInSlide(nextSlide.index());\n        \n                        var prevSlide = s.wrapper.children('.' + s.params.slidePrevClass);\n                        if (prevSlide.length > 0) s.lazy.loadImageInSlide(prevSlide.index());\n                    }\n                }\n            },\n            onTransitionStart: function () {\n                if (s.params.lazyLoading) {\n                    if (s.params.lazyLoadingOnTransitionStart || (!s.params.lazyLoadingOnTransitionStart && !s.lazy.initialImageLoaded)) {\n                        s.lazy.load();\n                    }\n                }\n            },\n            onTransitionEnd: function () {\n                if (s.params.lazyLoading && !s.params.lazyLoadingOnTransitionStart) {\n                    s.lazy.load();\n                }\n            }\n        };\n        \n\n        /*=========================\n          Scrollbar\n          ===========================*/\n        s.scrollbar = {\n            isTouched: false,\n            setDragPosition: function (e) {\n                var sb = s.scrollbar;\n                var x = 0, y = 0;\n                var translate;\n                var pointerPosition = s.isHorizontal() ?\n                    ((e.type === 'touchstart' || e.type === 'touchmove') ? e.targetTouches[0].pageX : e.pageX || e.clientX) :\n                    ((e.type === 'touchstart' || e.type === 'touchmove') ? e.targetTouches[0].pageY : e.pageY || e.clientY) ;\n                var position = (pointerPosition) - sb.track.offset()[s.isHorizontal() ? 'left' : 'top'] - sb.dragSize / 2;\n                var positionMin = -s.minTranslate() * sb.moveDivider;\n                var positionMax = -s.maxTranslate() * sb.moveDivider;\n                if (position < positionMin) {\n                    position = positionMin;\n                }\n                else if (position > positionMax) {\n                    position = positionMax;\n                }\n                position = -position / sb.moveDivider;\n                s.updateProgress(position);\n                s.setWrapperTranslate(position, true);\n            },\n            dragStart: function (e) {\n                var sb = s.scrollbar;\n                sb.isTouched = true;\n                e.preventDefault();\n                e.stopPropagation();\n        \n                sb.setDragPosition(e);\n                clearTimeout(sb.dragTimeout);\n        \n                sb.track.transition(0);\n                if (s.params.scrollbarHide) {\n                    sb.track.css('opacity', 1);\n                }\n                s.wrapper.transition(100);\n                sb.drag.transition(100);\n                s.emit('onScrollbarDragStart', s);\n            },\n            dragMove: function (e) {\n                var sb = s.scrollbar;\n                if (!sb.isTouched) return;\n                if (e.preventDefault) e.preventDefault();\n                else e.returnValue = false;\n                sb.setDragPosition(e);\n                s.wrapper.transition(0);\n                sb.track.transition(0);\n                sb.drag.transition(0);\n                s.emit('onScrollbarDragMove', s);\n            },\n            dragEnd: function (e) {\n                var sb = s.scrollbar;\n                if (!sb.isTouched) return;\n                sb.isTouched = false;\n                if (s.params.scrollbarHide) {\n                    clearTimeout(sb.dragTimeout);\n                    sb.dragTimeout = setTimeout(function () {\n                        sb.track.css('opacity', 0);\n                        sb.track.transition(400);\n                    }, 1000);\n        \n                }\n                s.emit('onScrollbarDragEnd', s);\n                if (s.params.scrollbarSnapOnRelease) {\n                    s.slideReset();\n                }\n            },\n            enableDraggable: function () {\n                var sb = s.scrollbar;\n                var target = s.support.touch ? sb.track : document;\n                $(sb.track).on(s.touchEvents.start, sb.dragStart);\n                $(target).on(s.touchEvents.move, sb.dragMove);\n                $(target).on(s.touchEvents.end, sb.dragEnd);\n            },\n            disableDraggable: function () {\n                var sb = s.scrollbar;\n                var target = s.support.touch ? sb.track : document;\n                $(sb.track).off(s.touchEvents.start, sb.dragStart);\n                $(target).off(s.touchEvents.move, sb.dragMove);\n                $(target).off(s.touchEvents.end, sb.dragEnd);\n            },\n            set: function () {\n                if (!s.params.scrollbar) return;\n                var sb = s.scrollbar;\n                sb.track = $(s.params.scrollbar);\n                if (s.params.uniqueNavElements && typeof s.params.scrollbar === 'string' && sb.track.length > 1 && s.container.find(s.params.scrollbar).length === 1) {\n                    sb.track = s.container.find(s.params.scrollbar);\n                }\n                sb.drag = sb.track.find('.swiper-scrollbar-drag');\n                if (sb.drag.length === 0) {\n                    sb.drag = $('<div class=\"swiper-scrollbar-drag\"></div>');\n                    sb.track.append(sb.drag);\n                }\n                sb.drag[0].style.width = '';\n                sb.drag[0].style.height = '';\n                sb.trackSize = s.isHorizontal() ? sb.track[0].offsetWidth : sb.track[0].offsetHeight;\n        \n                sb.divider = s.size / s.virtualSize;\n                sb.moveDivider = sb.divider * (sb.trackSize / s.size);\n                sb.dragSize = sb.trackSize * sb.divider;\n        \n                if (s.isHorizontal()) {\n                    sb.drag[0].style.width = sb.dragSize + 'px';\n                }\n                else {\n                    sb.drag[0].style.height = sb.dragSize + 'px';\n                }\n        \n                if (sb.divider >= 1) {\n                    sb.track[0].style.display = 'none';\n                }\n                else {\n                    sb.track[0].style.display = '';\n                }\n                if (s.params.scrollbarHide) {\n                    sb.track[0].style.opacity = 0;\n                }\n            },\n            setTranslate: function () {\n                if (!s.params.scrollbar) return;\n                var diff;\n                var sb = s.scrollbar;\n                var translate = s.translate || 0;\n                var newPos;\n        \n                var newSize = sb.dragSize;\n                newPos = (sb.trackSize - sb.dragSize) * s.progress;\n                if (s.rtl && s.isHorizontal()) {\n                    newPos = -newPos;\n                    if (newPos > 0) {\n                        newSize = sb.dragSize - newPos;\n                        newPos = 0;\n                    }\n                    else if (-newPos + sb.dragSize > sb.trackSize) {\n                        newSize = sb.trackSize + newPos;\n                    }\n                }\n                else {\n                    if (newPos < 0) {\n                        newSize = sb.dragSize + newPos;\n                        newPos = 0;\n                    }\n                    else if (newPos + sb.dragSize > sb.trackSize) {\n                        newSize = sb.trackSize - newPos;\n                    }\n                }\n                if (s.isHorizontal()) {\n                    if (s.support.transforms3d) {\n                        sb.drag.transform('translate3d(' + (newPos) + 'px, 0, 0)');\n                    }\n                    else {\n                        sb.drag.transform('translateX(' + (newPos) + 'px)');\n                    }\n                    sb.drag[0].style.width = newSize + 'px';\n                }\n                else {\n                    if (s.support.transforms3d) {\n                        sb.drag.transform('translate3d(0px, ' + (newPos) + 'px, 0)');\n                    }\n                    else {\n                        sb.drag.transform('translateY(' + (newPos) + 'px)');\n                    }\n                    sb.drag[0].style.height = newSize + 'px';\n                }\n                if (s.params.scrollbarHide) {\n                    clearTimeout(sb.timeout);\n                    sb.track[0].style.opacity = 1;\n                    sb.timeout = setTimeout(function () {\n                        sb.track[0].style.opacity = 0;\n                        sb.track.transition(400);\n                    }, 1000);\n                }\n            },\n            setTransition: function (duration) {\n                if (!s.params.scrollbar) return;\n                s.scrollbar.drag.transition(duration);\n            }\n        };\n\n        /*=========================\n          Controller\n          ===========================*/\n        s.controller = {\n            LinearSpline: function (x, y) {\n                this.x = x;\n                this.y = y;\n                this.lastIndex = x.length - 1;\n                // Given an x value (x2), return the expected y2 value:\n                // (x1,y1) is the known point before given value,\n                // (x3,y3) is the known point after given value.\n                var i1, i3;\n                var l = this.x.length;\n        \n                this.interpolate = function (x2) {\n                    if (!x2) return 0;\n        \n                    // Get the indexes of x1 and x3 (the array indexes before and after given x2):\n                    i3 = binarySearch(this.x, x2);\n                    i1 = i3 - 1;\n        \n                    // We have our indexes i1 & i3, so we can calculate already:\n                    // y2 := ((x2−x1) × (y3−y1)) ÷ (x3−x1) + y1\n                    return ((x2 - this.x[i1]) * (this.y[i3] - this.y[i1])) / (this.x[i3] - this.x[i1]) + this.y[i1];\n                };\n        \n                var binarySearch = (function() {\n                    var maxIndex, minIndex, guess;\n                    return function(array, val) {\n                        minIndex = -1;\n                        maxIndex = array.length;\n                        while (maxIndex - minIndex > 1)\n                            if (array[guess = maxIndex + minIndex >> 1] <= val) {\n                                minIndex = guess;\n                            } else {\n                                maxIndex = guess;\n                            }\n                        return maxIndex;\n                    };\n                })();\n            },\n            //xxx: for now i will just save one spline function to to\n            getInterpolateFunction: function(c){\n                if(!s.controller.spline) s.controller.spline = s.params.loop ?\n                    new s.controller.LinearSpline(s.slidesGrid, c.slidesGrid) :\n                    new s.controller.LinearSpline(s.snapGrid, c.snapGrid);\n            },\n            setTranslate: function (translate, byController) {\n               var controlled = s.params.control;\n               var multiplier, controlledTranslate;\n               function setControlledTranslate(c) {\n                    // this will create an Interpolate function based on the snapGrids\n                    // x is the Grid of the scrolled scroller and y will be the controlled scroller\n                    // it makes sense to create this only once and recall it for the interpolation\n                    // the function does a lot of value caching for performance\n                    translate = c.rtl && c.params.direction === 'horizontal' ? -s.translate : s.translate;\n                    if (s.params.controlBy === 'slide') {\n                        s.controller.getInterpolateFunction(c);\n                        // i am not sure why the values have to be multiplicated this way, tried to invert the snapGrid\n                        // but it did not work out\n                        controlledTranslate = -s.controller.spline.interpolate(-translate);\n                    }\n        \n                    if(!controlledTranslate || s.params.controlBy === 'container'){\n                        multiplier = (c.maxTranslate() - c.minTranslate()) / (s.maxTranslate() - s.minTranslate());\n                        controlledTranslate = (translate - s.minTranslate()) * multiplier + c.minTranslate();\n                    }\n        \n                    if (s.params.controlInverse) {\n                        controlledTranslate = c.maxTranslate() - controlledTranslate;\n                    }\n                    c.updateProgress(controlledTranslate);\n                    c.setWrapperTranslate(controlledTranslate, false, s);\n                    c.updateActiveIndex();\n               }\n               if (s.isArray(controlled)) {\n                   for (var i = 0; i < controlled.length; i++) {\n                       if (controlled[i] !== byController && controlled[i] instanceof Swiper) {\n                           setControlledTranslate(controlled[i]);\n                       }\n                   }\n               }\n               else if (controlled instanceof Swiper && byController !== controlled) {\n        \n                   setControlledTranslate(controlled);\n               }\n            },\n            setTransition: function (duration, byController) {\n                var controlled = s.params.control;\n                var i;\n                function setControlledTransition(c) {\n                    c.setWrapperTransition(duration, s);\n                    if (duration !== 0) {\n                        c.onTransitionStart();\n                        c.wrapper.transitionEnd(function(){\n                            if (!controlled) return;\n                            if (c.params.loop && s.params.controlBy === 'slide') {\n                                c.fixLoop();\n                            }\n                            c.onTransitionEnd();\n        \n                        });\n                    }\n                }\n                if (s.isArray(controlled)) {\n                    for (i = 0; i < controlled.length; i++) {\n                        if (controlled[i] !== byController && controlled[i] instanceof Swiper) {\n                            setControlledTransition(controlled[i]);\n                        }\n                    }\n                }\n                else if (controlled instanceof Swiper && byController !== controlled) {\n                    setControlledTransition(controlled);\n                }\n            }\n        };\n\n        /*=========================\n          Hash Navigation\n          ===========================*/\n        s.hashnav = {\n            init: function () {\n                if (!s.params.hashnav) return;\n                s.hashnav.initialized = true;\n                var hash = document.location.hash.replace('#', '');\n                if (!hash) return;\n                var speed = 0;\n                for (var i = 0, length = s.slides.length; i < length; i++) {\n                    var slide = s.slides.eq(i);\n                    var slideHash = slide.attr('data-hash');\n                    if (slideHash === hash && !slide.hasClass(s.params.slideDuplicateClass)) {\n                        var index = slide.index();\n                        s.slideTo(index, speed, s.params.runCallbacksOnInit, true);\n                    }\n                }\n            },\n            setHash: function () {\n                if (!s.hashnav.initialized || !s.params.hashnav) return;\n                document.location.hash = s.slides.eq(s.activeIndex).attr('data-hash') || '';\n            }\n        };\n\n        /*=========================\n          Keyboard Control\n          ===========================*/\n        function handleKeyboard(e) {\n            if (e.originalEvent) e = e.originalEvent; //jquery fix\n            var kc = e.keyCode || e.charCode;\n            // Directions locks\n            if (!s.params.allowSwipeToNext && (s.isHorizontal() && kc === 39 || !s.isHorizontal() && kc === 40)) {\n                return false;\n            }\n            if (!s.params.allowSwipeToPrev && (s.isHorizontal() && kc === 37 || !s.isHorizontal() && kc === 38)) {\n                return false;\n            }\n            if (e.shiftKey || e.altKey || e.ctrlKey || e.metaKey) {\n                return;\n            }\n            if (document.activeElement && document.activeElement.nodeName && (document.activeElement.nodeName.toLowerCase() === 'input' || document.activeElement.nodeName.toLowerCase() === 'textarea')) {\n                return;\n            }\n            if (kc === 37 || kc === 39 || kc === 38 || kc === 40) {\n                var inView = false;\n                //Check that swiper should be inside of visible area of window\n                if (s.container.parents('.swiper-slide').length > 0 && s.container.parents('.swiper-slide-active').length === 0) {\n                    return;\n                }\n                var windowScroll = {\n                    left: window.pageXOffset,\n                    top: window.pageYOffset\n                };\n                var windowWidth = window.innerWidth;\n                var windowHeight = window.innerHeight;\n                var swiperOffset = s.container.offset();\n                if (s.rtl) swiperOffset.left = swiperOffset.left - s.container[0].scrollLeft;\n                var swiperCoord = [\n                    [swiperOffset.left, swiperOffset.top],\n                    [swiperOffset.left + s.width, swiperOffset.top],\n                    [swiperOffset.left, swiperOffset.top + s.height],\n                    [swiperOffset.left + s.width, swiperOffset.top + s.height]\n                ];\n                for (var i = 0; i < swiperCoord.length; i++) {\n                    var point = swiperCoord[i];\n                    if (\n                        point[0] >= windowScroll.left && point[0] <= windowScroll.left + windowWidth &&\n                        point[1] >= windowScroll.top && point[1] <= windowScroll.top + windowHeight\n                    ) {\n                        inView = true;\n                    }\n        \n                }\n                if (!inView) return;\n            }\n            if (s.isHorizontal()) {\n                if (kc === 37 || kc === 39) {\n                    if (e.preventDefault) e.preventDefault();\n                    else e.returnValue = false;\n                }\n                if ((kc === 39 && !s.rtl) || (kc === 37 && s.rtl)) s.slideNext();\n                if ((kc === 37 && !s.rtl) || (kc === 39 && s.rtl)) s.slidePrev();\n            }\n            else {\n                if (kc === 38 || kc === 40) {\n                    if (e.preventDefault) e.preventDefault();\n                    else e.returnValue = false;\n                }\n                if (kc === 40) s.slideNext();\n                if (kc === 38) s.slidePrev();\n            }\n        }\n        s.disableKeyboardControl = function () {\n            s.params.keyboardControl = false;\n            $(document).off('keydown', handleKeyboard);\n        };\n        s.enableKeyboardControl = function () {\n            s.params.keyboardControl = true;\n            $(document).on('keydown', handleKeyboard);\n        };\n        \n\n        /*=========================\n          Mousewheel Control\n          ===========================*/\n        s.mousewheel = {\n            event: false,\n            lastScrollTime: (new window.Date()).getTime()\n        };\n        if (s.params.mousewheelControl) {\n            try {\n                new window.WheelEvent('wheel');\n                s.mousewheel.event = 'wheel';\n            } catch (e) {\n                if (window.WheelEvent || (s.container[0] && 'wheel' in s.container[0])) {\n                    s.mousewheel.event = 'wheel';\n                }\n            }\n            if (!s.mousewheel.event && window.WheelEvent) {\n        \n            }\n            if (!s.mousewheel.event && document.onmousewheel !== undefined) {\n                s.mousewheel.event = 'mousewheel';\n            }\n            if (!s.mousewheel.event) {\n                s.mousewheel.event = 'DOMMouseScroll';\n            }\n        }\n        function handleMousewheel(e) {\n            if (e.originalEvent) e = e.originalEvent; //jquery fix\n            var we = s.mousewheel.event;\n            var delta = 0;\n            var rtlFactor = s.rtl ? -1 : 1;\n        \n            //WebKits\n            if (we === 'mousewheel') {\n                if (s.params.mousewheelForceToAxis) {\n                    if (s.isHorizontal()) {\n                        if (Math.abs(e.wheelDeltaX) > Math.abs(e.wheelDeltaY)) delta = e.wheelDeltaX * rtlFactor;\n                        else return;\n                    }\n                    else {\n                        if (Math.abs(e.wheelDeltaY) > Math.abs(e.wheelDeltaX)) delta = e.wheelDeltaY;\n                        else return;\n                    }\n                }\n                else {\n                    delta = Math.abs(e.wheelDeltaX) > Math.abs(e.wheelDeltaY) ? - e.wheelDeltaX * rtlFactor : - e.wheelDeltaY;\n                }\n            }\n            //Old FireFox\n            else if (we === 'DOMMouseScroll') delta = -e.detail;\n            //New FireFox\n            else if (we === 'wheel') {\n                if (s.params.mousewheelForceToAxis) {\n                    if (s.isHorizontal()) {\n                        if (Math.abs(e.deltaX) > Math.abs(e.deltaY)) delta = -e.deltaX * rtlFactor;\n                        else return;\n                    }\n                    else {\n                        if (Math.abs(e.deltaY) > Math.abs(e.deltaX)) delta = -e.deltaY;\n                        else return;\n                    }\n                }\n                else {\n                    delta = Math.abs(e.deltaX) > Math.abs(e.deltaY) ? - e.deltaX * rtlFactor : - e.deltaY;\n                }\n            }\n            if (delta === 0) return;\n        \n            if (s.params.mousewheelInvert) delta = -delta;\n        \n            if (!s.params.freeMode) {\n                if ((new window.Date()).getTime() - s.mousewheel.lastScrollTime > 60) {\n                    if (delta < 0) {\n                        if ((!s.isEnd || s.params.loop) && !s.animating) s.slideNext();\n                        else if (s.params.mousewheelReleaseOnEdges) return true;\n                    }\n                    else {\n                        if ((!s.isBeginning || s.params.loop) && !s.animating) s.slidePrev();\n                        else if (s.params.mousewheelReleaseOnEdges) return true;\n                    }\n                }\n                s.mousewheel.lastScrollTime = (new window.Date()).getTime();\n        \n            }\n            else {\n                //Freemode or scrollContainer:\n                var position = s.getWrapperTranslate() + delta * s.params.mousewheelSensitivity;\n                var wasBeginning = s.isBeginning,\n                    wasEnd = s.isEnd;\n        \n                if (position >= s.minTranslate()) position = s.minTranslate();\n                if (position <= s.maxTranslate()) position = s.maxTranslate();\n        \n                s.setWrapperTransition(0);\n                s.setWrapperTranslate(position);\n                s.updateProgress();\n                s.updateActiveIndex();\n        \n                if (!wasBeginning && s.isBeginning || !wasEnd && s.isEnd) {\n                    s.updateClasses();\n                }\n        \n                if (s.params.freeModeSticky) {\n                    clearTimeout(s.mousewheel.timeout);\n                    s.mousewheel.timeout = setTimeout(function () {\n                        s.slideReset();\n                    }, 300);\n                }\n                else {\n                    if (s.params.lazyLoading && s.lazy) {\n                        s.lazy.load();\n                    }\n                }\n        \n                // Return page scroll on edge positions\n                if (position === 0 || position === s.maxTranslate()) return;\n            }\n            if (s.params.autoplay) s.stopAutoplay();\n        \n            if (e.preventDefault) e.preventDefault();\n            else e.returnValue = false;\n            return false;\n        }\n        s.disableMousewheelControl = function () {\n            if (!s.mousewheel.event) return false;\n            s.container.off(s.mousewheel.event, handleMousewheel);\n            return true;\n        };\n        \n        s.enableMousewheelControl = function () {\n            if (!s.mousewheel.event) return false;\n            s.container.on(s.mousewheel.event, handleMousewheel);\n            return true;\n        };\n        \n\n        /*=========================\n          Parallax\n          ===========================*/\n        function setParallaxTransform(el, progress) {\n            el = $(el);\n            var p, pX, pY;\n            var rtlFactor = s.rtl ? -1 : 1;\n        \n            p = el.attr('data-swiper-parallax') || '0';\n            pX = el.attr('data-swiper-parallax-x');\n            pY = el.attr('data-swiper-parallax-y');\n            if (pX || pY) {\n                pX = pX || '0';\n                pY = pY || '0';\n            }\n            else {\n                if (s.isHorizontal()) {\n                    pX = p;\n                    pY = '0';\n                }\n                else {\n                    pY = p;\n                    pX = '0';\n                }\n            }\n        \n            if ((pX).indexOf('%') >= 0) {\n                pX = parseInt(pX, 10) * progress * rtlFactor + '%';\n            }\n            else {\n                pX = pX * progress * rtlFactor + 'px' ;\n            }\n            if ((pY).indexOf('%') >= 0) {\n                pY = parseInt(pY, 10) * progress + '%';\n            }\n            else {\n                pY = pY * progress + 'px' ;\n            }\n        \n            el.transform('translate3d(' + pX + ', ' + pY + ',0px)');\n        }\n        s.parallax = {\n            setTranslate: function () {\n                s.container.children('[data-swiper-parallax], [data-swiper-parallax-x], [data-swiper-parallax-y]').each(function(){\n                    setParallaxTransform(this, s.progress);\n        \n                });\n                s.slides.each(function () {\n                    var slide = $(this);\n                    slide.find('[data-swiper-parallax], [data-swiper-parallax-x], [data-swiper-parallax-y]').each(function () {\n                        var progress = Math.min(Math.max(slide[0].progress, -1), 1);\n                        setParallaxTransform(this, progress);\n                    });\n                });\n            },\n            setTransition: function (duration) {\n                if (typeof duration === 'undefined') duration = s.params.speed;\n                s.container.find('[data-swiper-parallax], [data-swiper-parallax-x], [data-swiper-parallax-y]').each(function(){\n                    var el = $(this);\n                    var parallaxDuration = parseInt(el.attr('data-swiper-parallax-duration'), 10) || duration;\n                    if (duration === 0) parallaxDuration = 0;\n                    el.transition(parallaxDuration);\n                });\n            }\n        };\n        \n\n        /*=========================\n          Plugins API. Collect all and init all plugins\n          ===========================*/\n        s._plugins = [];\n        for (var plugin in s.plugins) {\n            var p = s.plugins[plugin](s, s.params[plugin]);\n            if (p) s._plugins.push(p);\n        }\n        // Method to call all plugins event/method\n        s.callPlugins = function (eventName) {\n            for (var i = 0; i < s._plugins.length; i++) {\n                if (eventName in s._plugins[i]) {\n                    s._plugins[i][eventName](arguments[1], arguments[2], arguments[3], arguments[4], arguments[5]);\n                }\n            }\n        };\n\n        /*=========================\n          Events/Callbacks/Plugins Emitter\n          ===========================*/\n        function normalizeEventName (eventName) {\n            if (eventName.indexOf('on') !== 0) {\n                if (eventName[0] !== eventName[0].toUpperCase()) {\n                    eventName = 'on' + eventName[0].toUpperCase() + eventName.substring(1);\n                }\n                else {\n                    eventName = 'on' + eventName;\n                }\n            }\n            return eventName;\n        }\n        s.emitterEventListeners = {\n        \n        };\n        s.emit = function (eventName) {\n            // Trigger callbacks\n            if (s.params[eventName]) {\n                s.params[eventName](arguments[1], arguments[2], arguments[3], arguments[4], arguments[5]);\n            }\n            var i;\n            // Trigger events\n            if (s.emitterEventListeners[eventName]) {\n                for (i = 0; i < s.emitterEventListeners[eventName].length; i++) {\n                    s.emitterEventListeners[eventName][i](arguments[1], arguments[2], arguments[3], arguments[4], arguments[5]);\n                }\n            }\n            // Trigger plugins\n            if (s.callPlugins) s.callPlugins(eventName, arguments[1], arguments[2], arguments[3], arguments[4], arguments[5]);\n        };\n        s.on = function (eventName, handler) {\n            eventName = normalizeEventName(eventName);\n            if (!s.emitterEventListeners[eventName]) s.emitterEventListeners[eventName] = [];\n            s.emitterEventListeners[eventName].push(handler);\n            return s;\n        };\n        s.off = function (eventName, handler) {\n            var i;\n            eventName = normalizeEventName(eventName);\n            if (typeof handler === 'undefined') {\n                // Remove all handlers for such event\n                s.emitterEventListeners[eventName] = [];\n                return s;\n            }\n            if (!s.emitterEventListeners[eventName] || s.emitterEventListeners[eventName].length === 0) return;\n            for (i = 0; i < s.emitterEventListeners[eventName].length; i++) {\n                if(s.emitterEventListeners[eventName][i] === handler) s.emitterEventListeners[eventName].splice(i, 1);\n            }\n            return s;\n        };\n        s.once = function (eventName, handler) {\n            eventName = normalizeEventName(eventName);\n            var _handler = function () {\n                handler(arguments[0], arguments[1], arguments[2], arguments[3], arguments[4]);\n                s.off(eventName, _handler);\n            };\n            s.on(eventName, _handler);\n            return s;\n        };\n\n        // Accessibility tools\n        s.a11y = {\n            makeFocusable: function ($el) {\n                $el.attr('tabIndex', '0');\n                return $el;\n            },\n            addRole: function ($el, role) {\n                $el.attr('role', role);\n                return $el;\n            },\n        \n            addLabel: function ($el, label) {\n                $el.attr('aria-label', label);\n                return $el;\n            },\n        \n            disable: function ($el) {\n                $el.attr('aria-disabled', true);\n                return $el;\n            },\n        \n            enable: function ($el) {\n                $el.attr('aria-disabled', false);\n                return $el;\n            },\n        \n            onEnterKey: function (event) {\n                if (event.keyCode !== 13) return;\n                if ($(event.target).is(s.params.nextButton)) {\n                    s.onClickNext(event);\n                    if (s.isEnd) {\n                        s.a11y.notify(s.params.lastSlideMessage);\n                    }\n                    else {\n                        s.a11y.notify(s.params.nextSlideMessage);\n                    }\n                }\n                else if ($(event.target).is(s.params.prevButton)) {\n                    s.onClickPrev(event);\n                    if (s.isBeginning) {\n                        s.a11y.notify(s.params.firstSlideMessage);\n                    }\n                    else {\n                        s.a11y.notify(s.params.prevSlideMessage);\n                    }\n                }\n                if ($(event.target).is('.' + s.params.bulletClass)) {\n                    $(event.target)[0].click();\n                }\n            },\n        \n            liveRegion: $('<span class=\"swiper-notification\" aria-live=\"assertive\" aria-atomic=\"true\"></span>'),\n        \n            notify: function (message) {\n                var notification = s.a11y.liveRegion;\n                if (notification.length === 0) return;\n                notification.html('');\n                notification.html(message);\n            },\n            init: function () {\n                // Setup accessibility\n                if (s.params.nextButton && s.nextButton && s.nextButton.length > 0) {\n                    s.a11y.makeFocusable(s.nextButton);\n                    s.a11y.addRole(s.nextButton, 'button');\n                    s.a11y.addLabel(s.nextButton, s.params.nextSlideMessage);\n                }\n                if (s.params.prevButton && s.prevButton && s.prevButton.length > 0) {\n                    s.a11y.makeFocusable(s.prevButton);\n                    s.a11y.addRole(s.prevButton, 'button');\n                    s.a11y.addLabel(s.prevButton, s.params.prevSlideMessage);\n                }\n        \n                $(s.container).append(s.a11y.liveRegion);\n            },\n            initPagination: function () {\n                if (s.params.pagination && s.params.paginationClickable && s.bullets && s.bullets.length) {\n                    s.bullets.each(function () {\n                        var bullet = $(this);\n                        s.a11y.makeFocusable(bullet);\n                        s.a11y.addRole(bullet, 'button');\n                        s.a11y.addLabel(bullet, s.params.paginationBulletMessage.replace(/{{index}}/, bullet.index() + 1));\n                    });\n                }\n            },\n            destroy: function () {\n                if (s.a11y.liveRegion && s.a11y.liveRegion.length > 0) s.a11y.liveRegion.remove();\n            }\n        };\n        \n\n        /*=========================\n          Init/Destroy\n          ===========================*/\n        s.init = function () {\n            if (s.params.loop) s.createLoop();\n            s.updateContainerSize();\n            s.updateSlidesSize();\n            s.updatePagination();\n            if (s.params.scrollbar && s.scrollbar) {\n                s.scrollbar.set();\n                if (s.params.scrollbarDraggable) {\n                    s.scrollbar.enableDraggable();\n                }\n            }\n            if (s.params.effect !== 'slide' && s.effects[s.params.effect]) {\n                if (!s.params.loop) s.updateProgress();\n                s.effects[s.params.effect].setTranslate();\n            }\n            if (s.params.loop) {\n                s.slideTo(s.params.initialSlide + s.loopedSlides, 0, s.params.runCallbacksOnInit);\n            }\n            else {\n                s.slideTo(s.params.initialSlide, 0, s.params.runCallbacksOnInit);\n                if (s.params.initialSlide === 0) {\n                    if (s.parallax && s.params.parallax) s.parallax.setTranslate();\n                    if (s.lazy && s.params.lazyLoading) {\n                        s.lazy.load();\n                        s.lazy.initialImageLoaded = true;\n                    }\n                }\n            }\n            s.attachEvents();\n            if (s.params.observer && s.support.observer) {\n                s.initObservers();\n            }\n            if (s.params.preloadImages && !s.params.lazyLoading) {\n                s.preloadImages();\n            }\n            if (s.params.autoplay) {\n                s.startAutoplay();\n            }\n            if (s.params.keyboardControl) {\n                if (s.enableKeyboardControl) s.enableKeyboardControl();\n            }\n            if (s.params.mousewheelControl) {\n                if (s.enableMousewheelControl) s.enableMousewheelControl();\n            }\n            if (s.params.hashnav) {\n                if (s.hashnav) s.hashnav.init();\n            }\n            if (s.params.a11y && s.a11y) s.a11y.init();\n            s.emit('onInit', s);\n        };\n        \n        // Cleanup dynamic styles\n        s.cleanupStyles = function () {\n            // Container\n            s.container.removeClass(s.classNames.join(' ')).removeAttr('style');\n        \n            // Wrapper\n            s.wrapper.removeAttr('style');\n        \n            // Slides\n            if (s.slides && s.slides.length) {\n                s.slides\n                    .removeClass([\n                      s.params.slideVisibleClass,\n                      s.params.slideActiveClass,\n                      s.params.slideNextClass,\n                      s.params.slidePrevClass\n                    ].join(' '))\n                    .removeAttr('style')\n                    .removeAttr('data-swiper-column')\n                    .removeAttr('data-swiper-row');\n            }\n        \n            // Pagination/Bullets\n            if (s.paginationContainer && s.paginationContainer.length) {\n                s.paginationContainer.removeClass(s.params.paginationHiddenClass);\n            }\n            if (s.bullets && s.bullets.length) {\n                s.bullets.removeClass(s.params.bulletActiveClass);\n            }\n        \n            // Buttons\n            if (s.params.prevButton) $(s.params.prevButton).removeClass(s.params.buttonDisabledClass);\n            if (s.params.nextButton) $(s.params.nextButton).removeClass(s.params.buttonDisabledClass);\n        \n            // Scrollbar\n            if (s.params.scrollbar && s.scrollbar) {\n                if (s.scrollbar.track && s.scrollbar.track.length) s.scrollbar.track.removeAttr('style');\n                if (s.scrollbar.drag && s.scrollbar.drag.length) s.scrollbar.drag.removeAttr('style');\n            }\n        };\n        \n        // Destroy\n        s.destroy = function (deleteInstance, cleanupStyles) {\n            // Detach evebts\n            s.detachEvents();\n            // Stop autoplay\n            s.stopAutoplay();\n            // Disable draggable\n            if (s.params.scrollbar && s.scrollbar) {\n                if (s.params.scrollbarDraggable) {\n                    s.scrollbar.disableDraggable();\n                }\n            }\n            // Destroy loop\n            if (s.params.loop) {\n                s.destroyLoop();\n            }\n            // Cleanup styles\n            if (cleanupStyles) {\n                s.cleanupStyles();\n            }\n            // Disconnect observer\n            s.disconnectObservers();\n            // Disable keyboard/mousewheel\n            if (s.params.keyboardControl) {\n                if (s.disableKeyboardControl) s.disableKeyboardControl();\n            }\n            if (s.params.mousewheelControl) {\n                if (s.disableMousewheelControl) s.disableMousewheelControl();\n            }\n            // Disable a11y\n            if (s.params.a11y && s.a11y) s.a11y.destroy();\n            // Destroy callback\n            s.emit('onDestroy');\n            // Delete instance\n            if (deleteInstance !== false) s = null;\n        };\n        \n        s.init();\n        \n\n    \n        // Return swiper instance\n        return s;\n    };\n    \n\n    /*==================================================\n        Prototype\n    ====================================================*/\n    Swiper.prototype = {\n        isSafari: (function () {\n            var ua = navigator.userAgent.toLowerCase();\n            return (ua.indexOf('safari') >= 0 && ua.indexOf('chrome') < 0 && ua.indexOf('android') < 0);\n        })(),\n        isUiWebView: /(iPhone|iPod|iPad).*AppleWebKit(?!.*Safari)/i.test(navigator.userAgent),\n        isArray: function (arr) {\n            return Object.prototype.toString.apply(arr) === '[object Array]';\n        },\n        /*==================================================\n        Browser\n        ====================================================*/\n        browser: {\n            ie: window.navigator.pointerEnabled || window.navigator.msPointerEnabled,\n            ieTouch: (window.navigator.msPointerEnabled && window.navigator.msMaxTouchPoints > 1) || (window.navigator.pointerEnabled && window.navigator.maxTouchPoints > 1)\n        },\n        /*==================================================\n        Devices\n        ====================================================*/\n        device: (function () {\n            var ua = navigator.userAgent;\n            var android = ua.match(/(Android);?[\\s\\/]+([\\d.]+)?/);\n            var ipad = ua.match(/(iPad).*OS\\s([\\d_]+)/);\n            var ipod = ua.match(/(iPod)(.*OS\\s([\\d_]+))?/);\n            var iphone = !ipad && ua.match(/(iPhone\\sOS)\\s([\\d_]+)/);\n            return {\n                ios: ipad || iphone || ipod,\n                android: android\n            };\n        })(),\n        /*==================================================\n        Feature Detection\n        ====================================================*/\n        support: {\n            touch : (window.Modernizr && Modernizr.touch === true) || (function () {\n                return !!(('ontouchstart' in window) || window.DocumentTouch && document instanceof DocumentTouch);\n            })(),\n    \n            transforms3d : (window.Modernizr && Modernizr.csstransforms3d === true) || (function () {\n                var div = document.createElement('div').style;\n                return ('webkitPerspective' in div || 'MozPerspective' in div || 'OPerspective' in div || 'MsPerspective' in div || 'perspective' in div);\n            })(),\n    \n            flexbox: (function () {\n                var div = document.createElement('div').style;\n                var styles = ('alignItems webkitAlignItems webkitBoxAlign msFlexAlign mozBoxAlign webkitFlexDirection msFlexDirection mozBoxDirection mozBoxOrient webkitBoxDirection webkitBoxOrient').split(' ');\n                for (var i = 0; i < styles.length; i++) {\n                    if (styles[i] in div) return true;\n                }\n            })(),\n    \n            observer: (function () {\n                return ('MutationObserver' in window || 'WebkitMutationObserver' in window);\n            })()\n        },\n        /*==================================================\n        Plugins\n        ====================================================*/\n        plugins: {}\n    };\n    \n\n    /*===========================\n    Dom7 Library\n    ===========================*/\n    var Dom7 = (function () {\n        var Dom7 = function (arr) {\n            var _this = this, i = 0;\n            // Create array-like object\n            for (i = 0; i < arr.length; i++) {\n                _this[i] = arr[i];\n            }\n            _this.length = arr.length;\n            // Return collection with methods\n            return this;\n        };\n        var $ = function (selector, context) {\n            var arr = [], i = 0;\n            if (selector && !context) {\n                if (selector instanceof Dom7) {\n                    return selector;\n                }\n            }\n            if (selector) {\n                // String\n                if (typeof selector === 'string') {\n                    var els, tempParent, html = selector.trim();\n                    if (html.indexOf('<') >= 0 && html.indexOf('>') >= 0) {\n                        var toCreate = 'div';\n                        if (html.indexOf('<li') === 0) toCreate = 'ul';\n                        if (html.indexOf('<tr') === 0) toCreate = 'tbody';\n                        if (html.indexOf('<td') === 0 || html.indexOf('<th') === 0) toCreate = 'tr';\n                        if (html.indexOf('<tbody') === 0) toCreate = 'table';\n                        if (html.indexOf('<option') === 0) toCreate = 'select';\n                        tempParent = document.createElement(toCreate);\n                        tempParent.innerHTML = selector;\n                        for (i = 0; i < tempParent.childNodes.length; i++) {\n                            arr.push(tempParent.childNodes[i]);\n                        }\n                    }\n                    else {\n                        if (!context && selector[0] === '#' && !selector.match(/[ .<>:~]/)) {\n                            // Pure ID selector\n                            els = [document.getElementById(selector.split('#')[1])];\n                        }\n                        else {\n                            // Other selectors\n                            els = (context || document).querySelectorAll(selector);\n                        }\n                        for (i = 0; i < els.length; i++) {\n                            if (els[i]) arr.push(els[i]);\n                        }\n                    }\n                }\n                // Node/element\n                else if (selector.nodeType || selector === window || selector === document) {\n                    arr.push(selector);\n                }\n                //Array of elements or instance of Dom\n                else if (selector.length > 0 && selector[0].nodeType) {\n                    for (i = 0; i < selector.length; i++) {\n                        arr.push(selector[i]);\n                    }\n                }\n            }\n            return new Dom7(arr);\n        };\n        Dom7.prototype = {\n            // Classes and attriutes\n            addClass: function (className) {\n                if (typeof className === 'undefined') {\n                    return this;\n                }\n                var classes = className.split(' ');\n                for (var i = 0; i < classes.length; i++) {\n                    for (var j = 0; j < this.length; j++) {\n                        this[j].classList.add(classes[i]);\n                    }\n                }\n                return this;\n            },\n            removeClass: function (className) {\n                var classes = className.split(' ');\n                for (var i = 0; i < classes.length; i++) {\n                    for (var j = 0; j < this.length; j++) {\n                        this[j].classList.remove(classes[i]);\n                    }\n                }\n                return this;\n            },\n            hasClass: function (className) {\n                if (!this[0]) return false;\n                else return this[0].classList.contains(className);\n            },\n            toggleClass: function (className) {\n                var classes = className.split(' ');\n                for (var i = 0; i < classes.length; i++) {\n                    for (var j = 0; j < this.length; j++) {\n                        this[j].classList.toggle(classes[i]);\n                    }\n                }\n                return this;\n            },\n            attr: function (attrs, value) {\n                if (arguments.length === 1 && typeof attrs === 'string') {\n                    // Get attr\n                    if (this[0]) return this[0].getAttribute(attrs);\n                    else return undefined;\n                }\n                else {\n                    // Set attrs\n                    for (var i = 0; i < this.length; i++) {\n                        if (arguments.length === 2) {\n                            // String\n                            this[i].setAttribute(attrs, value);\n                        }\n                        else {\n                            // Object\n                            for (var attrName in attrs) {\n                                this[i][attrName] = attrs[attrName];\n                                this[i].setAttribute(attrName, attrs[attrName]);\n                            }\n                        }\n                    }\n                    return this;\n                }\n            },\n            removeAttr: function (attr) {\n                for (var i = 0; i < this.length; i++) {\n                    this[i].removeAttribute(attr);\n                }\n                return this;\n            },\n            data: function (key, value) {\n                if (typeof value === 'undefined') {\n                    // Get value\n                    if (this[0]) {\n                        var dataKey = this[0].getAttribute('data-' + key);\n                        if (dataKey) return dataKey;\n                        else if (this[0].dom7ElementDataStorage && (key in this[0].dom7ElementDataStorage)) return this[0].dom7ElementDataStorage[key];\n                        else return undefined;\n                    }\n                    else return undefined;\n                }\n                else {\n                    // Set value\n                    for (var i = 0; i < this.length; i++) {\n                        var el = this[i];\n                        if (!el.dom7ElementDataStorage) el.dom7ElementDataStorage = {};\n                        el.dom7ElementDataStorage[key] = value;\n                    }\n                    return this;\n                }\n            },\n            // Transforms\n            transform : function (transform) {\n                for (var i = 0; i < this.length; i++) {\n                    var elStyle = this[i].style;\n                    elStyle.webkitTransform = elStyle.MsTransform = elStyle.msTransform = elStyle.MozTransform = elStyle.OTransform = elStyle.transform = transform;\n                }\n                return this;\n            },\n            transition: function (duration) {\n                if (typeof duration !== 'string') {\n                    duration = duration + 'ms';\n                }\n                for (var i = 0; i < this.length; i++) {\n                    var elStyle = this[i].style;\n                    elStyle.webkitTransitionDuration = elStyle.MsTransitionDuration = elStyle.msTransitionDuration = elStyle.MozTransitionDuration = elStyle.OTransitionDuration = elStyle.transitionDuration = duration;\n                }\n                return this;\n            },\n            //Events\n            on: function (eventName, targetSelector, listener, capture) {\n                function handleLiveEvent(e) {\n                    var target = e.target;\n                    if ($(target).is(targetSelector)) listener.call(target, e);\n                    else {\n                        var parents = $(target).parents();\n                        for (var k = 0; k < parents.length; k++) {\n                            if ($(parents[k]).is(targetSelector)) listener.call(parents[k], e);\n                        }\n                    }\n                }\n                var events = eventName.split(' ');\n                var i, j;\n                for (i = 0; i < this.length; i++) {\n                    if (typeof targetSelector === 'function' || targetSelector === false) {\n                        // Usual events\n                        if (typeof targetSelector === 'function') {\n                            listener = arguments[1];\n                            capture = arguments[2] || false;\n                        }\n                        for (j = 0; j < events.length; j++) {\n                            this[i].addEventListener(events[j], listener, capture);\n                        }\n                    }\n                    else {\n                        //Live events\n                        for (j = 0; j < events.length; j++) {\n                            if (!this[i].dom7LiveListeners) this[i].dom7LiveListeners = [];\n                            this[i].dom7LiveListeners.push({listener: listener, liveListener: handleLiveEvent});\n                            this[i].addEventListener(events[j], handleLiveEvent, capture);\n                        }\n                    }\n                }\n    \n                return this;\n            },\n            off: function (eventName, targetSelector, listener, capture) {\n                var events = eventName.split(' ');\n                for (var i = 0; i < events.length; i++) {\n                    for (var j = 0; j < this.length; j++) {\n                        if (typeof targetSelector === 'function' || targetSelector === false) {\n                            // Usual events\n                            if (typeof targetSelector === 'function') {\n                                listener = arguments[1];\n                                capture = arguments[2] || false;\n                            }\n                            this[j].removeEventListener(events[i], listener, capture);\n                        }\n                        else {\n                            // Live event\n                            if (this[j].dom7LiveListeners) {\n                                for (var k = 0; k < this[j].dom7LiveListeners.length; k++) {\n                                    if (this[j].dom7LiveListeners[k].listener === listener) {\n                                        this[j].removeEventListener(events[i], this[j].dom7LiveListeners[k].liveListener, capture);\n                                    }\n                                }\n                            }\n                        }\n                    }\n                }\n                return this;\n            },\n            once: function (eventName, targetSelector, listener, capture) {\n                var dom = this;\n                if (typeof targetSelector === 'function') {\n                    targetSelector = false;\n                    listener = arguments[1];\n                    capture = arguments[2];\n                }\n                function proxy(e) {\n                    listener(e);\n                    dom.off(eventName, targetSelector, proxy, capture);\n                }\n                dom.on(eventName, targetSelector, proxy, capture);\n            },\n            trigger: function (eventName, eventData) {\n                for (var i = 0; i < this.length; i++) {\n                    var evt;\n                    try {\n                        evt = new window.CustomEvent(eventName, {detail: eventData, bubbles: true, cancelable: true});\n                    }\n                    catch (e) {\n                        evt = document.createEvent('Event');\n                        evt.initEvent(eventName, true, true);\n                        evt.detail = eventData;\n                    }\n                    this[i].dispatchEvent(evt);\n                }\n                return this;\n            },\n            transitionEnd: function (callback) {\n                var events = ['webkitTransitionEnd', 'transitionend', 'oTransitionEnd', 'MSTransitionEnd', 'msTransitionEnd'],\n                    i, j, dom = this;\n                function fireCallBack(e) {\n                    /*jshint validthis:true */\n                    if (e.target !== this) return;\n                    callback.call(this, e);\n                    for (i = 0; i < events.length; i++) {\n                        dom.off(events[i], fireCallBack);\n                    }\n                }\n                if (callback) {\n                    for (i = 0; i < events.length; i++) {\n                        dom.on(events[i], fireCallBack);\n                    }\n                }\n                return this;\n            },\n            // Sizing/Styles\n            width: function () {\n                if (this[0] === window) {\n                    return window.innerWidth;\n                }\n                else {\n                    if (this.length > 0) {\n                        return parseFloat(this.css('width'));\n                    }\n                    else {\n                        return null;\n                    }\n                }\n            },\n            outerWidth: function (includeMargins) {\n                if (this.length > 0) {\n                    if (includeMargins)\n                        return this[0].offsetWidth + parseFloat(this.css('margin-right')) + parseFloat(this.css('margin-left'));\n                    else\n                        return this[0].offsetWidth;\n                }\n                else return null;\n            },\n            height: function () {\n                if (this[0] === window) {\n                    return window.innerHeight;\n                }\n                else {\n                    if (this.length > 0) {\n                        return parseFloat(this.css('height'));\n                    }\n                    else {\n                        return null;\n                    }\n                }\n            },\n            outerHeight: function (includeMargins) {\n                if (this.length > 0) {\n                    if (includeMargins)\n                        return this[0].offsetHeight + parseFloat(this.css('margin-top')) + parseFloat(this.css('margin-bottom'));\n                    else\n                        return this[0].offsetHeight;\n                }\n                else return null;\n            },\n            offset: function () {\n                if (this.length > 0) {\n                    var el = this[0];\n                    var box = el.getBoundingClientRect();\n                    var body = document.body;\n                    var clientTop  = el.clientTop  || body.clientTop  || 0;\n                    var clientLeft = el.clientLeft || body.clientLeft || 0;\n                    var scrollTop  = window.pageYOffset || el.scrollTop;\n                    var scrollLeft = window.pageXOffset || el.scrollLeft;\n                    return {\n                        top: box.top  + scrollTop  - clientTop,\n                        left: box.left + scrollLeft - clientLeft\n                    };\n                }\n                else {\n                    return null;\n                }\n            },\n            css: function (props, value) {\n                var i;\n                if (arguments.length === 1) {\n                    if (typeof props === 'string') {\n                        if (this[0]) return window.getComputedStyle(this[0], null).getPropertyValue(props);\n                    }\n                    else {\n                        for (i = 0; i < this.length; i++) {\n                            for (var prop in props) {\n                                this[i].style[prop] = props[prop];\n                            }\n                        }\n                        return this;\n                    }\n                }\n                if (arguments.length === 2 && typeof props === 'string') {\n                    for (i = 0; i < this.length; i++) {\n                        this[i].style[props] = value;\n                    }\n                    return this;\n                }\n                return this;\n            },\n    \n            //Dom manipulation\n            each: function (callback) {\n                for (var i = 0; i < this.length; i++) {\n                    callback.call(this[i], i, this[i]);\n                }\n                return this;\n            },\n            html: function (html) {\n                if (typeof html === 'undefined') {\n                    return this[0] ? this[0].innerHTML : undefined;\n                }\n                else {\n                    for (var i = 0; i < this.length; i++) {\n                        this[i].innerHTML = html;\n                    }\n                    return this;\n                }\n            },\n            text: function (text) {\n                if (typeof text === 'undefined') {\n                    if (this[0]) {\n                        return this[0].textContent.trim();\n                    }\n                    else return null;\n                }\n                else {\n                    for (var i = 0; i < this.length; i++) {\n                        this[i].textContent = text;\n                    }\n                    return this;\n                }\n            },\n            is: function (selector) {\n                if (!this[0]) return false;\n                var compareWith, i;\n                if (typeof selector === 'string') {\n                    var el = this[0];\n                    if (el === document) return selector === document;\n                    if (el === window) return selector === window;\n    \n                    if (el.matches) return el.matches(selector);\n                    else if (el.webkitMatchesSelector) return el.webkitMatchesSelector(selector);\n                    else if (el.mozMatchesSelector) return el.mozMatchesSelector(selector);\n                    else if (el.msMatchesSelector) return el.msMatchesSelector(selector);\n                    else {\n                        compareWith = $(selector);\n                        for (i = 0; i < compareWith.length; i++) {\n                            if (compareWith[i] === this[0]) return true;\n                        }\n                        return false;\n                    }\n                }\n                else if (selector === document) return this[0] === document;\n                else if (selector === window) return this[0] === window;\n                else {\n                    if (selector.nodeType || selector instanceof Dom7) {\n                        compareWith = selector.nodeType ? [selector] : selector;\n                        for (i = 0; i < compareWith.length; i++) {\n                            if (compareWith[i] === this[0]) return true;\n                        }\n                        return false;\n                    }\n                    return false;\n                }\n    \n            },\n            index: function () {\n                if (this[0]) {\n                    var child = this[0];\n                    var i = 0;\n                    while ((child = child.previousSibling) !== null) {\n                        if (child.nodeType === 1) i++;\n                    }\n                    return i;\n                }\n                else return undefined;\n            },\n            eq: function (index) {\n                if (typeof index === 'undefined') return this;\n                var length = this.length;\n                var returnIndex;\n                if (index > length - 1) {\n                    return new Dom7([]);\n                }\n                if (index < 0) {\n                    returnIndex = length + index;\n                    if (returnIndex < 0) return new Dom7([]);\n                    else return new Dom7([this[returnIndex]]);\n                }\n                return new Dom7([this[index]]);\n            },\n            append: function (newChild) {\n                var i, j;\n                for (i = 0; i < this.length; i++) {\n                    if (typeof newChild === 'string') {\n                        var tempDiv = document.createElement('div');\n                        tempDiv.innerHTML = newChild;\n                        while (tempDiv.firstChild) {\n                            this[i].appendChild(tempDiv.firstChild);\n                        }\n                    }\n                    else if (newChild instanceof Dom7) {\n                        for (j = 0; j < newChild.length; j++) {\n                            this[i].appendChild(newChild[j]);\n                        }\n                    }\n                    else {\n                        this[i].appendChild(newChild);\n                    }\n                }\n                return this;\n            },\n            prepend: function (newChild) {\n                var i, j;\n                for (i = 0; i < this.length; i++) {\n                    if (typeof newChild === 'string') {\n                        var tempDiv = document.createElement('div');\n                        tempDiv.innerHTML = newChild;\n                        for (j = tempDiv.childNodes.length - 1; j >= 0; j--) {\n                            this[i].insertBefore(tempDiv.childNodes[j], this[i].childNodes[0]);\n                        }\n                        // this[i].insertAdjacentHTML('afterbegin', newChild);\n                    }\n                    else if (newChild instanceof Dom7) {\n                        for (j = 0; j < newChild.length; j++) {\n                            this[i].insertBefore(newChild[j], this[i].childNodes[0]);\n                        }\n                    }\n                    else {\n                        this[i].insertBefore(newChild, this[i].childNodes[0]);\n                    }\n                }\n                return this;\n            },\n            insertBefore: function (selector) {\n                var before = $(selector);\n                for (var i = 0; i < this.length; i++) {\n                    if (before.length === 1) {\n                        before[0].parentNode.insertBefore(this[i], before[0]);\n                    }\n                    else if (before.length > 1) {\n                        for (var j = 0; j < before.length; j++) {\n                            before[j].parentNode.insertBefore(this[i].cloneNode(true), before[j]);\n                        }\n                    }\n                }\n            },\n            insertAfter: function (selector) {\n                var after = $(selector);\n                for (var i = 0; i < this.length; i++) {\n                    if (after.length === 1) {\n                        after[0].parentNode.insertBefore(this[i], after[0].nextSibling);\n                    }\n                    else if (after.length > 1) {\n                        for (var j = 0; j < after.length; j++) {\n                            after[j].parentNode.insertBefore(this[i].cloneNode(true), after[j].nextSibling);\n                        }\n                    }\n                }\n            },\n            next: function (selector) {\n                if (this.length > 0) {\n                    if (selector) {\n                        if (this[0].nextElementSibling && $(this[0].nextElementSibling).is(selector)) return new Dom7([this[0].nextElementSibling]);\n                        else return new Dom7([]);\n                    }\n                    else {\n                        if (this[0].nextElementSibling) return new Dom7([this[0].nextElementSibling]);\n                        else return new Dom7([]);\n                    }\n                }\n                else return new Dom7([]);\n            },\n            nextAll: function (selector) {\n                var nextEls = [];\n                var el = this[0];\n                if (!el) return new Dom7([]);\n                while (el.nextElementSibling) {\n                    var next = el.nextElementSibling;\n                    if (selector) {\n                        if($(next).is(selector)) nextEls.push(next);\n                    }\n                    else nextEls.push(next);\n                    el = next;\n                }\n                return new Dom7(nextEls);\n            },\n            prev: function (selector) {\n                if (this.length > 0) {\n                    if (selector) {\n                        if (this[0].previousElementSibling && $(this[0].previousElementSibling).is(selector)) return new Dom7([this[0].previousElementSibling]);\n                        else return new Dom7([]);\n                    }\n                    else {\n                        if (this[0].previousElementSibling) return new Dom7([this[0].previousElementSibling]);\n                        else return new Dom7([]);\n                    }\n                }\n                else return new Dom7([]);\n            },\n            prevAll: function (selector) {\n                var prevEls = [];\n                var el = this[0];\n                if (!el) return new Dom7([]);\n                while (el.previousElementSibling) {\n                    var prev = el.previousElementSibling;\n                    if (selector) {\n                        if($(prev).is(selector)) prevEls.push(prev);\n                    }\n                    else prevEls.push(prev);\n                    el = prev;\n                }\n                return new Dom7(prevEls);\n            },\n            parent: function (selector) {\n                var parents = [];\n                for (var i = 0; i < this.length; i++) {\n                    if (selector) {\n                        if ($(this[i].parentNode).is(selector)) parents.push(this[i].parentNode);\n                    }\n                    else {\n                        parents.push(this[i].parentNode);\n                    }\n                }\n                return $($.unique(parents));\n            },\n            parents: function (selector) {\n                var parents = [];\n                for (var i = 0; i < this.length; i++) {\n                    var parent = this[i].parentNode;\n                    while (parent) {\n                        if (selector) {\n                            if ($(parent).is(selector)) parents.push(parent);\n                        }\n                        else {\n                            parents.push(parent);\n                        }\n                        parent = parent.parentNode;\n                    }\n                }\n                return $($.unique(parents));\n            },\n            find : function (selector) {\n                var foundElements = [];\n                for (var i = 0; i < this.length; i++) {\n                    var found = this[i].querySelectorAll(selector);\n                    for (var j = 0; j < found.length; j++) {\n                        foundElements.push(found[j]);\n                    }\n                }\n                return new Dom7(foundElements);\n            },\n            children: function (selector) {\n                var children = [];\n                for (var i = 0; i < this.length; i++) {\n                    var childNodes = this[i].childNodes;\n    \n                    for (var j = 0; j < childNodes.length; j++) {\n                        if (!selector) {\n                            if (childNodes[j].nodeType === 1) children.push(childNodes[j]);\n                        }\n                        else {\n                            if (childNodes[j].nodeType === 1 && $(childNodes[j]).is(selector)) children.push(childNodes[j]);\n                        }\n                    }\n                }\n                return new Dom7($.unique(children));\n            },\n            remove: function () {\n                for (var i = 0; i < this.length; i++) {\n                    if (this[i].parentNode) this[i].parentNode.removeChild(this[i]);\n                }\n                return this;\n            },\n            add: function () {\n                var dom = this;\n                var i, j;\n                for (i = 0; i < arguments.length; i++) {\n                    var toAdd = $(arguments[i]);\n                    for (j = 0; j < toAdd.length; j++) {\n                        dom[dom.length] = toAdd[j];\n                        dom.length++;\n                    }\n                }\n                return dom;\n            }\n        };\n        $.fn = Dom7.prototype;\n        $.unique = function (arr) {\n            var unique = [];\n            for (var i = 0; i < arr.length; i++) {\n                if (unique.indexOf(arr[i]) === -1) unique.push(arr[i]);\n            }\n            return unique;\n        };\n    \n        return $;\n    })();\n    \n\n    /*===========================\n     Get Dom libraries\n     ===========================*/\n    var swiperDomPlugins = ['jQuery', 'Zepto', 'Dom7'];\n    for (var i = 0; i < swiperDomPlugins.length; i++) {\n    \tif (window[swiperDomPlugins[i]]) {\n    \t\taddLibraryPlugin(window[swiperDomPlugins[i]]);\n    \t}\n    }\n    // Required DOM Plugins\n    var domLib;\n    if (typeof Dom7 === 'undefined') {\n    \tdomLib = window.Dom7 || window.Zepto || window.jQuery;\n    }\n    else {\n    \tdomLib = Dom7;\n    }\n\n    /*===========================\n    Add .swiper plugin from Dom libraries\n    ===========================*/\n    function addLibraryPlugin(lib) {\n        lib.fn.swiper = function (params) {\n            var firstInstance;\n            lib(this).each(function () {\n                var s = new Swiper(this, params);\n                if (!firstInstance) firstInstance = s;\n            });\n            return firstInstance;\n        };\n    }\n    \n    if (domLib) {\n        if (!('transitionEnd' in domLib.fn)) {\n            domLib.fn.transitionEnd = function (callback) {\n                var events = ['webkitTransitionEnd', 'transitionend', 'oTransitionEnd', 'MSTransitionEnd', 'msTransitionEnd'],\n                    i, j, dom = this;\n                function fireCallBack(e) {\n                    /*jshint validthis:true */\n                    if (e.target !== this) return;\n                    callback.call(this, e);\n                    for (i = 0; i < events.length; i++) {\n                        dom.off(events[i], fireCallBack);\n                    }\n                }\n                if (callback) {\n                    for (i = 0; i < events.length; i++) {\n                        dom.on(events[i], fireCallBack);\n                    }\n                }\n                return this;\n            };\n        }\n        if (!('transform' in domLib.fn)) {\n            domLib.fn.transform = function (transform) {\n                for (var i = 0; i < this.length; i++) {\n                    var elStyle = this[i].style;\n                    elStyle.webkitTransform = elStyle.MsTransform = elStyle.msTransform = elStyle.MozTransform = elStyle.OTransform = elStyle.transform = transform;\n                }\n                return this;\n            };\n        }\n        if (!('transition' in domLib.fn)) {\n            domLib.fn.transition = function (duration) {\n                if (typeof duration !== 'string') {\n                    duration = duration + 'ms';\n                }\n                for (var i = 0; i < this.length; i++) {\n                    var elStyle = this[i].style;\n                    elStyle.webkitTransitionDuration = elStyle.MsTransitionDuration = elStyle.msTransitionDuration = elStyle.MozTransitionDuration = elStyle.OTransitionDuration = elStyle.transitionDuration = duration;\n                }\n                return this;\n            };\n        }\n    }\n\n    window.Swiper = Swiper;\n})();\n/*===========================\nSwiper AMD Export\n===========================*/\nif (typeof(module) !== 'undefined')\n{\n    module.exports = window.Swiper;\n}\nelse if (typeof define === 'function' && define.amd) {\n    define([], function () {\n        'use strict';\n        return window.Swiper;\n    });\n}\n//# sourceMappingURL=maps/swiper.js.map\n"
  },
  {
    "path": "app_backend/static/plugin/Swiper-3.3.1/gulpfile.js",
    "content": "(function(){\n    'use strict';\n    var gulp = require('gulp'),\n        connect = require('gulp-connect'),\n        open = require('gulp-open'),\n        less = require('gulp-less'),\n        rename = require('gulp-rename'),\n        header = require('gulp-header'),\n        path = require('path'),\n        uglify = require('gulp-uglify'),\n        sourcemaps = require('gulp-sourcemaps'),\n        minifyCSS = require('gulp-minify-css'),\n        tap = require('gulp-tap'),\n        concat = require('gulp-concat'),\n        jshint = require('gulp-jshint'),\n        stylish = require('jshint-stylish'),\n        fs = require('fs'),\n        paths = {\n            root: './',\n            build: {\n                root: 'build/',\n                styles: 'build/css/',\n                scripts: 'build/js/'\n            },\n            dist: {\n                root: 'dist/',\n                styles: 'dist/css/',\n                scripts: 'dist/js/'\n            },\n            playground: {\n                root: 'playground/'\n            },\n            source: {\n                root: 'src/',\n                styles: 'src/less/',\n                scripts: 'src/js/*.js'\n            },\n        },\n        swiper = {\n            filename: 'swiper',\n            jsFiles: [\n                'src/js/wrap-start.js',\n                'src/js/swiper-intro.js',\n                'src/js/core.js',\n                'src/js/effects.js',\n                'src/js/lazy-load.js',\n                'src/js/scrollbar.js',\n                'src/js/controller.js',\n                'src/js/hashnav.js',\n                'src/js/keyboard.js',\n                'src/js/mousewheel.js',\n                'src/js/parallax.js',\n                'src/js/plugins.js',\n                'src/js/emitter.js',\n                'src/js/a11y.js',\n                'src/js/init.js',\n                'src/js/swiper-outro.js',\n                'src/js/swiper-proto.js',\n                'src/js/dom.js',\n                'src/js/get-dom-lib.js',\n                'src/js/dom-plugins.js',\n                'src/js/wrap-end.js',\n                'src/js/amd.js'\n            ],\n            jQueryFiles : [\n                'src/js/wrap-start.js',\n                'src/js/swiper-intro.js',\n                'src/js/core.js',\n                'src/js/effects.js',\n                'src/js/lazy-load.js',\n                'src/js/scrollbar.js',\n                'src/js/controller.js',\n                'src/js/hashnav.js',\n                'src/js/keyboard.js',\n                'src/js/mousewheel.js',\n                'src/js/parallax.js',\n                'src/js/plugins.js',\n                'src/js/emitter.js',\n                'src/js/a11y.js',\n                'src/js/init.js',\n                'src/js/swiper-outro.js',\n                'src/js/swiper-proto.js',\n                'src/js/get-dom-lib.js',\n                'src/js/dom-plugins.js',\n                'src/js/wrap-end.js',\n                'src/js/amd.js'\n            ],\n            jQueryUMDFiles : [\n                'src/js/wrap-start-umd.js',\n                'src/js/swiper-intro.js',\n                'src/js/core.js',\n                'src/js/effects.js',\n                'src/js/lazy-load.js',\n                'src/js/scrollbar.js',\n                'src/js/controller.js',\n                'src/js/hashnav.js',\n                'src/js/keyboard.js',\n                'src/js/mousewheel.js',\n                'src/js/parallax.js',\n                'src/js/plugins.js',\n                'src/js/emitter.js',\n                'src/js/a11y.js',\n                'src/js/init.js',\n                'src/js/swiper-outro.js',\n                'src/js/swiper-proto.js',\n                'src/js/get-jquery.js',\n                'src/js/dom-plugins.js',\n                'src/js/wrap-end-umd.js',\n            ],\n            Framework7Files : [\n                'src/js/swiper-intro-f7.js',\n                'src/js/core.js',\n                'src/js/effects.js',\n                'src/js/lazy-load.js',\n                'src/js/scrollbar.js',\n                'src/js/controller.js',\n                'src/js/parallax.js',\n                'src/js/plugins.js',\n                'src/js/emitter.js',\n                'src/js/a11y.js',\n                'src/js/init.js',\n                'src/js/swiper-outro.js',\n                'src/js/swiper-proto.js',\n            ],\n            pkg: require('./bower.json'),\n            banner: [\n                '/**',\n                ' * Swiper <%= pkg.version %>',\n                ' * <%= pkg.description %>',\n                ' * ',\n                ' * <%= pkg.homepage %>',\n                ' * ',\n                ' * Copyright <%= date.year %>, <%= pkg.author %>',\n                ' * The iDangero.us',\n                ' * http://www.idangero.us/',\n                ' * ',\n                ' * Licensed under <%= pkg.license.join(\" & \") %>',\n                ' * ',\n                ' * Released on: <%= date.month %> <%= date.day %>, <%= date.year %>',\n                ' */',\n                ''].join('\\n'),\n            date: {\n                year: new Date().getFullYear(),\n                month: ('January February March April May June July August September October November December').split(' ')[new Date().getMonth()],\n                day: new Date().getDate()\n            }\n        };\n\n    function addJSIndent (file, t, minusIndent) {\n        var addIndent = '        ';\n        var filename = file.path.split('src/js/')[1];\n        if (['wrap-start.js', 'wrap-start-umd.js', 'wrap-end.js', 'wrap-end-umd.js', 'amd.js'].indexOf(filename) !== -1) {\n            addIndent = '';\n        }\n        if (filename === 'swiper-intro.js' || filename === 'swiper-intro-f7.js' || filename === 'swiper-outro.js' || filename === 'dom.js' || filename === 'get-dom-lib.js' || filename === 'get-jquery.js' || filename === 'dom-plugins.js' || filename === 'swiper-proto.js') addIndent = '    ';\n        if (minusIndent) {\n            addIndent = addIndent.substring(4);\n        }\n        if (addIndent !== '') {\n            var fileLines = fs.readFileSync(file.path).toString().split('\\n');\n            var newFileContents = '';\n            for (var i = 0; i < fileLines.length; i++) {\n                newFileContents += addIndent + fileLines[i] + (i === fileLines.length ? '' : '\\n');\n            }\n            file.contents = new Buffer(newFileContents);\n        }\n    }\n    gulp.task('scripts', function (cb) {\n        gulp.src(swiper.jsFiles)\n            .pipe(tap(function (file, t){\n                addJSIndent (file, t);\n            }))\n            .pipe(sourcemaps.init())\n            .pipe(concat(swiper.filename + '.js'))\n            .pipe(header(swiper.banner, { pkg : swiper.pkg, date: swiper.date } ))\n            .pipe(jshint())\n            .pipe(jshint.reporter(stylish))\n            .pipe(sourcemaps.write('./maps/'))\n            .pipe(gulp.dest(paths.build.scripts));\n\n            \n        gulp.src(swiper.jQueryFiles)\n            .pipe(tap(function (file, t){\n                addJSIndent (file, t);\n            }))\n            .pipe(sourcemaps.init())\n            .pipe(concat(swiper.filename + '.jquery.js'))\n            .pipe(header(swiper.banner, { pkg : swiper.pkg, date: swiper.date } ))\n            .pipe(sourcemaps.write('./maps/'))\n            .pipe(gulp.dest(paths.build.scripts));\n        gulp.src(swiper.jQueryUMDFiles)\n            .pipe(tap(function (file, t){\n                addJSIndent (file, t);\n            }))\n            .pipe(sourcemaps.init())\n            .pipe(concat(swiper.filename + '.jquery.umd.js'))\n            .pipe(header(swiper.banner, { pkg : swiper.pkg, date: swiper.date } ))\n            .pipe(sourcemaps.write('./maps/'))\n            .pipe(gulp.dest(paths.build.scripts));\n        gulp.src(swiper.Framework7Files)\n            .pipe(tap(function (file, t){\n                addJSIndent (file, t, true);\n            }))\n            .pipe(sourcemaps.init())\n            .pipe(concat(swiper.filename + '.framework7.js'))\n            .pipe(header(swiper.banner, { pkg : swiper.pkg, date: swiper.date } ))\n            .pipe(sourcemaps.write('./maps/'))\n            .pipe(gulp.dest(paths.build.scripts))\n            .pipe(connect.reload());\n        cb();\n    });\n    gulp.task('styles', function (cb) {\n\n        gulp.src(paths.source.styles + 'swiper.less')\n            .pipe(less({\n                paths: [ path.join(__dirname, 'less', 'includes') ]\n            }))\n            .pipe(header(swiper.banner, { pkg : swiper.pkg, date: swiper.date }))\n            .pipe(rename(function(path) {\n                path.basename = swiper.filename;\n            }))\n            .pipe(gulp.dest(paths.build.styles))\n            .pipe(connect.reload());\n\n        gulp.src([\n                paths.source.styles + 'core.less',\n                paths.source.styles + 'navigation-f7.less',\n                paths.source.styles + 'effects.less',\n                paths.source.styles + 'scrollbar.less',\n                paths.source.styles + 'preloader-f7.less',\n            ])\n            .pipe(concat(swiper.filename + '.framework7.less'))\n            .pipe(header('/* === Swiper === */\\n'))\n            .pipe(gulp.dest(paths.build.styles));\n        cb();\n    });\n    gulp.task('build', ['scripts', 'styles'], function (cb) {\n        cb();\n    });\n\n    gulp.task('dist', function () {\n        gulp.src([paths.build.scripts + swiper.filename + '.js'])\n            .pipe(gulp.dest(paths.dist.scripts))\n            .pipe(sourcemaps.init())\n            .pipe(uglify())\n            .pipe(header(swiper.banner, { pkg : swiper.pkg, date: swiper.date }))\n            .pipe(rename(function(path) {\n                path.basename = swiper.filename + '.min';\n            }))\n            .pipe(sourcemaps.write('./maps'))\n            .pipe(gulp.dest(paths.dist.scripts));\n\n        gulp.src([paths.build.scripts + swiper.filename + '.jquery.js'])\n            .pipe(gulp.dest(paths.dist.scripts))\n            .pipe(sourcemaps.init())\n            .pipe(uglify())\n            .pipe(header(swiper.banner, { pkg : swiper.pkg, date: swiper.date } ))\n            .pipe(rename(function(path) {\n                path.basename = swiper.filename + '.jquery.min';\n            }))\n            .pipe(sourcemaps.write('./maps'))\n            .pipe(gulp.dest(paths.dist.scripts));\n\n        gulp.src([paths.build.scripts + swiper.filename + '.jquery.umd.js'])\n            .pipe(gulp.dest(paths.dist.scripts))\n            .pipe(sourcemaps.init())\n            .pipe(uglify())\n            .pipe(header(swiper.banner, { pkg : swiper.pkg, date: swiper.date } ))\n            .pipe(rename(function(path) {\n                path.basename = swiper.filename + '.jquery.umd.min';\n            }))\n            .pipe(sourcemaps.write('./maps'))\n            .pipe(gulp.dest(paths.dist.scripts));\n\n        gulp.src(paths.build.styles + '*.css')\n            .pipe(gulp.dest(paths.dist.styles))\n            .pipe(minifyCSS({\n                advanced: false,\n                aggressiveMerging: false,\n            }))\n            .pipe(header(swiper.banner, { pkg : swiper.pkg, date: swiper.date }))\n            .pipe(rename(function(path) {\n                path.basename = swiper.filename + '.min';\n            }))\n            .pipe(gulp.dest(paths.dist.styles));\n    });\n\n    gulp.task('watch', function () {\n        gulp.watch(paths.source.scripts, [ 'scripts' ]);\n        gulp.watch(paths.source.styles + '*.less', [ 'styles' ]);\n    });\n\n    gulp.task('connect', function () {\n        return connect.server({\n            root: [ paths.root ],\n            livereload: true,\n            port:'3000'\n        });\n    });\n\n    gulp.task('open', function () {\n        return gulp.src(paths.playground.root + 'index.html').pipe(open({ uri: 'http://localhost:3000/' + paths.playground.root + 'index.html'}));\n    });\n\n    gulp.task('server', [ 'watch', 'connect', 'open' ]);\n\n    gulp.task('default', [ 'server' ]);\n})();\n"
  },
  {
    "path": "app_backend/static/plugin/Swiper-3.3.1/package.js",
    "content": "var version = '3.3.1';\n\nPackage.describe({\n  name: 'nolimits4web:swiper',\n  summary: 'iDangero.us Swiper - mobile touch slider with hardware accelerated transitions and native behavior',\n  version: version,\n  git: 'https://github.com/nolimits4web/Swiper'\n});\n\nPackage.onUse(function (api) {\n  api.versionsFrom('1.1.0.2');\n\n  api.addFiles([\n    'dist/css/swiper.min.css',\n    'dist/js/swiper.js'\n    ], ['client']\n  );\n\n  // Since swiper is attached to window, we do not need to export Swiper\n  // api.export('Swiper');\n});\n\nPackage.onTest(function (api) {\n});\n"
  },
  {
    "path": "app_backend/static/plugin/Swiper-3.3.1/package.json",
    "content": "{\n  \"name\": \"swiper\",\n  \"version\": \"3.3.1\",\n  \"description\": \"Most modern mobile touch slider and framework with hardware accelerated transitions\",\n  \"main\": \"dist/js/swiper.js\",\n  \"files\": [\"dist\", \"src\", \"*.json\", \"*.js\"],\n  \"repository\": {\n    \"type\": \"git\",\n    \"url\": \"https://github.com/nolimits4web/Swiper.git\"\n  },\n  \"keywords\": [\"swiper\", \"swipe\", \"slider\", \"touch\", \"ios\", \"mobile\", \"cordova\", \"phonegap\", \"app\", \"framework\", \"carousel\", \"gallery\"],\n  \"author\": \"Vladimir Kharlampidi\",\n  \"license\": \"MIT\",\n  \"bugs\": {\n    \"url\": \"https://github.com/nolimits4web/Swiper/issues\"\n  },\n  \"homepage\": \"http://www.idangero.us/swiper/\",\n  \"engines\": {\n    \"node\": \">= 0.10.0\"\n  },\n  \"devDependencies\": {\n    \"jshint\": \"~2.9.1\",\n    \"gulp\": \"~3.9.0\",\n    \"gulp-less\": \"~3.0.5\",\n    \"gulp-connect\": \"~2.3.1\",\n    \"gulp-open\": \"~1.0.0\",\n    \"gulp-uglify\": \"~1.5.1\",\n    \"gulp-sourcemaps\": \"~1.6.0\",\n    \"gulp-minify-css\": \"1.2.3\",\n    \"gulp-jshint\": \"~2.0.0\",\n    \"gulp-concat\": \"~2.6.0\",\n    \"gulp-rename\": \"~1.2.2\",\n    \"gulp-header\": \"~1.7.1\",\n    \"gulp-tap\": \"~0.1.3\",\n    \"jshint-stylish\": \"~2.1.0\"\n  },\n  \"scripts\": {\n    \"test\": \"gulp build\"\n  },\n  \"style\": \"dist/css/swiper.css\"\n}\n"
  },
  {
    "path": "app_backend/static/plugin/Swiper-3.3.1/playground/index.html",
    "content": "<!doctype html>\n<html lang=\"en\">\n<head>\n    <meta charset=\"UTF-8\">\n    <title>Swiper Playground</title>\n    <link rel=\"stylesheet\" href=\"../build/css/swiper.css\">\n    <meta name=\"viewport\" content=\"width=device-width\">\n</head>\n<body>\n    <div class=\"swiper-container\">\n        <div class=\"swiper-scrollbar\"></div>\n        <div class=\"swiper-button-prev\"></div>\n        <div class=\"swiper-button-next\"></div>\n        <div class=\"swiper-wrapper\">\n            <div class=\"swiper-slide\">Slide 1</div>\n            <div class=\"swiper-slide\">Slide 2</div>\n            <div class=\"swiper-slide\">Slide 3</div>\n            <div class=\"swiper-slide\">Slide 4</div>\n            <div class=\"swiper-slide\">Slide 5</div>\n            <div class=\"swiper-slide\">Slide 6</div>\n            <div class=\"swiper-slide\">Slide 7</div>\n            <div class=\"swiper-slide\">Slide 8</div>\n            <div class=\"swiper-slide\">Slide 9</div>\n            <div class=\"swiper-slide\">Slide 10</div>\n        </div>\n        <div class=\"swiper-pagination\"></div>\n    </div>\n    <style>\n    body, html {\n        padding: 0;\n        margin: 0;\n        position: relative;\n        height: 100%;\n    }\n    .swiper-container {\n        width: 100%;\n        height: 300px;\n        margin: 50px auto;\n    }\n    .swiper-slide {\n        background: #f1f1f1;\n        color:#000;\n        text-align: center;\n        line-height: 300px;\n    }\n    </style>\n    <script src=\"../build/js/swiper.js\"></script>\n    <script>\n        var swiper = new Swiper('.swiper-container', {\n            spaceBetween: 50,\n            slidesPerView: 2,\n            centeredSlides: true,\n            slideToClickedSlide: true,\n            grabCursor: true,\n            nextButton: '.swiper-button-next',\n            prevButton: '.swiper-button-prev',\n            scrollbar: '.swiper-scrollbar',\n            pagination: '.swiper-pagination',\n        });\n    </script>\n</body>\n</html>"
  },
  {
    "path": "app_backend/static/plugin/Swiper-3.3.1/src/js/a11y.js",
    "content": "// Accessibility tools\ns.a11y = {\n    makeFocusable: function ($el) {\n        $el.attr('tabIndex', '0');\n        return $el;\n    },\n    addRole: function ($el, role) {\n        $el.attr('role', role);\n        return $el;\n    },\n\n    addLabel: function ($el, label) {\n        $el.attr('aria-label', label);\n        return $el;\n    },\n\n    disable: function ($el) {\n        $el.attr('aria-disabled', true);\n        return $el;\n    },\n\n    enable: function ($el) {\n        $el.attr('aria-disabled', false);\n        return $el;\n    },\n\n    onEnterKey: function (event) {\n        if (event.keyCode !== 13) return;\n        if ($(event.target).is(s.params.nextButton)) {\n            s.onClickNext(event);\n            if (s.isEnd) {\n                s.a11y.notify(s.params.lastSlideMessage);\n            }\n            else {\n                s.a11y.notify(s.params.nextSlideMessage);\n            }\n        }\n        else if ($(event.target).is(s.params.prevButton)) {\n            s.onClickPrev(event);\n            if (s.isBeginning) {\n                s.a11y.notify(s.params.firstSlideMessage);\n            }\n            else {\n                s.a11y.notify(s.params.prevSlideMessage);\n            }\n        }\n        if ($(event.target).is('.' + s.params.bulletClass)) {\n            $(event.target)[0].click();\n        }\n    },\n\n    liveRegion: $('<span class=\"swiper-notification\" aria-live=\"assertive\" aria-atomic=\"true\"></span>'),\n\n    notify: function (message) {\n        var notification = s.a11y.liveRegion;\n        if (notification.length === 0) return;\n        notification.html('');\n        notification.html(message);\n    },\n    init: function () {\n        // Setup accessibility\n        if (s.params.nextButton && s.nextButton && s.nextButton.length > 0) {\n            s.a11y.makeFocusable(s.nextButton);\n            s.a11y.addRole(s.nextButton, 'button');\n            s.a11y.addLabel(s.nextButton, s.params.nextSlideMessage);\n        }\n        if (s.params.prevButton && s.prevButton && s.prevButton.length > 0) {\n            s.a11y.makeFocusable(s.prevButton);\n            s.a11y.addRole(s.prevButton, 'button');\n            s.a11y.addLabel(s.prevButton, s.params.prevSlideMessage);\n        }\n\n        $(s.container).append(s.a11y.liveRegion);\n    },\n    initPagination: function () {\n        if (s.params.pagination && s.params.paginationClickable && s.bullets && s.bullets.length) {\n            s.bullets.each(function () {\n                var bullet = $(this);\n                s.a11y.makeFocusable(bullet);\n                s.a11y.addRole(bullet, 'button');\n                s.a11y.addLabel(bullet, s.params.paginationBulletMessage.replace(/{{index}}/, bullet.index() + 1));\n            });\n        }\n    },\n    destroy: function () {\n        if (s.a11y.liveRegion && s.a11y.liveRegion.length > 0) s.a11y.liveRegion.remove();\n    }\n};\n"
  },
  {
    "path": "app_backend/static/plugin/Swiper-3.3.1/src/js/amd.js",
    "content": "/*===========================\nSwiper AMD Export\n===========================*/\nif (typeof(module) !== 'undefined')\n{\n    module.exports = window.Swiper;\n}\nelse if (typeof define === 'function' && define.amd) {\n    define([], function () {\n        'use strict';\n        return window.Swiper;\n    });\n}"
  },
  {
    "path": "app_backend/static/plugin/Swiper-3.3.1/src/js/controller.js",
    "content": "/*=========================\n  Controller\n  ===========================*/\ns.controller = {\n    LinearSpline: function (x, y) {\n        this.x = x;\n        this.y = y;\n        this.lastIndex = x.length - 1;\n        // Given an x value (x2), return the expected y2 value:\n        // (x1,y1) is the known point before given value,\n        // (x3,y3) is the known point after given value.\n        var i1, i3;\n        var l = this.x.length;\n\n        this.interpolate = function (x2) {\n            if (!x2) return 0;\n\n            // Get the indexes of x1 and x3 (the array indexes before and after given x2):\n            i3 = binarySearch(this.x, x2);\n            i1 = i3 - 1;\n\n            // We have our indexes i1 & i3, so we can calculate already:\n            // y2 := ((x2−x1) × (y3−y1)) ÷ (x3−x1) + y1\n            return ((x2 - this.x[i1]) * (this.y[i3] - this.y[i1])) / (this.x[i3] - this.x[i1]) + this.y[i1];\n        };\n\n        var binarySearch = (function() {\n            var maxIndex, minIndex, guess;\n            return function(array, val) {\n                minIndex = -1;\n                maxIndex = array.length;\n                while (maxIndex - minIndex > 1)\n                    if (array[guess = maxIndex + minIndex >> 1] <= val) {\n                        minIndex = guess;\n                    } else {\n                        maxIndex = guess;\n                    }\n                return maxIndex;\n            };\n        })();\n    },\n    //xxx: for now i will just save one spline function to to\n    getInterpolateFunction: function(c){\n        if(!s.controller.spline) s.controller.spline = s.params.loop ?\n            new s.controller.LinearSpline(s.slidesGrid, c.slidesGrid) :\n            new s.controller.LinearSpline(s.snapGrid, c.snapGrid);\n    },\n    setTranslate: function (translate, byController) {\n       var controlled = s.params.control;\n       var multiplier, controlledTranslate;\n       function setControlledTranslate(c) {\n            // this will create an Interpolate function based on the snapGrids\n            // x is the Grid of the scrolled scroller and y will be the controlled scroller\n            // it makes sense to create this only once and recall it for the interpolation\n            // the function does a lot of value caching for performance\n            translate = c.rtl && c.params.direction === 'horizontal' ? -s.translate : s.translate;\n            if (s.params.controlBy === 'slide') {\n                s.controller.getInterpolateFunction(c);\n                // i am not sure why the values have to be multiplicated this way, tried to invert the snapGrid\n                // but it did not work out\n                controlledTranslate = -s.controller.spline.interpolate(-translate);\n            }\n\n            if(!controlledTranslate || s.params.controlBy === 'container'){\n                multiplier = (c.maxTranslate() - c.minTranslate()) / (s.maxTranslate() - s.minTranslate());\n                controlledTranslate = (translate - s.minTranslate()) * multiplier + c.minTranslate();\n            }\n\n            if (s.params.controlInverse) {\n                controlledTranslate = c.maxTranslate() - controlledTranslate;\n            }\n            c.updateProgress(controlledTranslate);\n            c.setWrapperTranslate(controlledTranslate, false, s);\n            c.updateActiveIndex();\n       }\n       if (s.isArray(controlled)) {\n           for (var i = 0; i < controlled.length; i++) {\n               if (controlled[i] !== byController && controlled[i] instanceof Swiper) {\n                   setControlledTranslate(controlled[i]);\n               }\n           }\n       }\n       else if (controlled instanceof Swiper && byController !== controlled) {\n\n           setControlledTranslate(controlled);\n       }\n    },\n    setTransition: function (duration, byController) {\n        var controlled = s.params.control;\n        var i;\n        function setControlledTransition(c) {\n            c.setWrapperTransition(duration, s);\n            if (duration !== 0) {\n                c.onTransitionStart();\n                c.wrapper.transitionEnd(function(){\n                    if (!controlled) return;\n                    if (c.params.loop && s.params.controlBy === 'slide') {\n                        c.fixLoop();\n                    }\n                    c.onTransitionEnd();\n\n                });\n            }\n        }\n        if (s.isArray(controlled)) {\n            for (i = 0; i < controlled.length; i++) {\n                if (controlled[i] !== byController && controlled[i] instanceof Swiper) {\n                    setControlledTransition(controlled[i]);\n                }\n            }\n        }\n        else if (controlled instanceof Swiper && byController !== controlled) {\n            setControlledTransition(controlled);\n        }\n    }\n};"
  },
  {
    "path": "app_backend/static/plugin/Swiper-3.3.1/src/js/core.js",
    "content": "var defaults = {\n    direction: 'horizontal',\n    touchEventsTarget: 'container',\n    initialSlide: 0,\n    speed: 300,\n    // autoplay\n    autoplay: false,\n    autoplayDisableOnInteraction: true,\n    autoplayStopOnLast: false,\n    // To support iOS's swipe-to-go-back gesture (when being used in-app, with UIWebView).\n    iOSEdgeSwipeDetection: false,\n    iOSEdgeSwipeThreshold: 20,\n    // Free mode\n    freeMode: false,\n    freeModeMomentum: true,\n    freeModeMomentumRatio: 1,\n    freeModeMomentumBounce: true,\n    freeModeMomentumBounceRatio: 1,\n    freeModeSticky: false,\n    freeModeMinimumVelocity: 0.02,\n    // Autoheight\n    autoHeight: false,\n    // Set wrapper width\n    setWrapperSize: false,\n    // Virtual Translate\n    virtualTranslate: false,\n    // Effects\n    effect: 'slide', // 'slide' or 'fade' or 'cube' or 'coverflow' or 'flip'\n    coverflow: {\n        rotate: 50,\n        stretch: 0,\n        depth: 100,\n        modifier: 1,\n        slideShadows : true\n    },\n    flip: {\n        slideShadows : true,\n        limitRotation: true\n    },\n    cube: {\n        slideShadows: true,\n        shadow: true,\n        shadowOffset: 20,\n        shadowScale: 0.94\n    },\n    fade: {\n        crossFade: false\n    },\n    // Parallax\n    parallax: false,\n    // Scrollbar\n    scrollbar: null,\n    scrollbarHide: true,\n    scrollbarDraggable: false,\n    scrollbarSnapOnRelease: false,\n    // Keyboard Mousewheel\n    keyboardControl: false,\n    mousewheelControl: false,\n    mousewheelReleaseOnEdges: false,\n    mousewheelInvert: false,\n    mousewheelForceToAxis: false,\n    mousewheelSensitivity: 1,\n    // Hash Navigation\n    hashnav: false,\n    // Breakpoints\n    breakpoints: undefined,\n    // Slides grid\n    spaceBetween: 0,\n    slidesPerView: 1,\n    slidesPerColumn: 1,\n    slidesPerColumnFill: 'column',\n    slidesPerGroup: 1,\n    centeredSlides: false,\n    slidesOffsetBefore: 0, // in px\n    slidesOffsetAfter: 0, // in px\n    // Round length\n    roundLengths: false,\n    // Touches\n    touchRatio: 1,\n    touchAngle: 45,\n    simulateTouch: true,\n    shortSwipes: true,\n    longSwipes: true,\n    longSwipesRatio: 0.5,\n    longSwipesMs: 300,\n    followFinger: true,\n    onlyExternal: false,\n    threshold: 0,\n    touchMoveStopPropagation: true,\n    // Unique Navigation Elements\n    uniqueNavElements: true,\n    // Pagination\n    pagination: null,\n    paginationElement: 'span',\n    paginationClickable: false,\n    paginationHide: false,\n    paginationBulletRender: null,\n    paginationProgressRender: null,\n    paginationFractionRender: null,\n    paginationCustomRender: null,\n    paginationType: 'bullets', // 'bullets' or 'progress' or 'fraction' or 'custom'\n    // Resistance\n    resistance: true,\n    resistanceRatio: 0.85,\n    // Next/prev buttons\n    nextButton: null,\n    prevButton: null,\n    // Progress\n    watchSlidesProgress: false,\n    watchSlidesVisibility: false,\n    // Cursor\n    grabCursor: false,\n    // Clicks\n    preventClicks: true,\n    preventClicksPropagation: true,\n    slideToClickedSlide: false,\n    // Lazy Loading\n    lazyLoading: false,\n    lazyLoadingInPrevNext: false,\n    lazyLoadingInPrevNextAmount: 1,\n    lazyLoadingOnTransitionStart: false,\n    // Images\n    preloadImages: true,\n    updateOnImagesReady: true,\n    // loop\n    loop: false,\n    loopAdditionalSlides: 0,\n    loopedSlides: null,\n    // Control\n    control: undefined,\n    controlInverse: false,\n    controlBy: 'slide', //or 'container'\n    // Swiping/no swiping\n    allowSwipeToPrev: true,\n    allowSwipeToNext: true,\n    swipeHandler: null, //'.swipe-handler',\n    noSwiping: true,\n    noSwipingClass: 'swiper-no-swiping',\n    // NS\n    slideClass: 'swiper-slide',\n    slideActiveClass: 'swiper-slide-active',\n    slideVisibleClass: 'swiper-slide-visible',\n    slideDuplicateClass: 'swiper-slide-duplicate',\n    slideNextClass: 'swiper-slide-next',\n    slidePrevClass: 'swiper-slide-prev',\n    wrapperClass: 'swiper-wrapper',\n    bulletClass: 'swiper-pagination-bullet',\n    bulletActiveClass: 'swiper-pagination-bullet-active',\n    buttonDisabledClass: 'swiper-button-disabled',\n    paginationCurrentClass: 'swiper-pagination-current',\n    paginationTotalClass: 'swiper-pagination-total',\n    paginationHiddenClass: 'swiper-pagination-hidden',\n    paginationProgressbarClass: 'swiper-pagination-progressbar',\n    // Observer\n    observer: false,\n    observeParents: false,\n    // Accessibility\n    a11y: false,\n    prevSlideMessage: 'Previous slide',\n    nextSlideMessage: 'Next slide',\n    firstSlideMessage: 'This is the first slide',\n    lastSlideMessage: 'This is the last slide',\n    paginationBulletMessage: 'Go to slide {{index}}',\n    // Callbacks\n    runCallbacksOnInit: true\n    /*\n    Callbacks:\n    onInit: function (swiper)\n    onDestroy: function (swiper)\n    onClick: function (swiper, e)\n    onTap: function (swiper, e)\n    onDoubleTap: function (swiper, e)\n    onSliderMove: function (swiper, e)\n    onSlideChangeStart: function (swiper)\n    onSlideChangeEnd: function (swiper)\n    onTransitionStart: function (swiper)\n    onTransitionEnd: function (swiper)\n    onImagesReady: function (swiper)\n    onProgress: function (swiper, progress)\n    onTouchStart: function (swiper, e)\n    onTouchMove: function (swiper, e)\n    onTouchMoveOpposite: function (swiper, e)\n    onTouchEnd: function (swiper, e)\n    onReachBeginning: function (swiper)\n    onReachEnd: function (swiper)\n    onSetTransition: function (swiper, duration)\n    onSetTranslate: function (swiper, translate)\n    onAutoplayStart: function (swiper)\n    onAutoplayStop: function (swiper),\n    onLazyImageLoad: function (swiper, slide, image)\n    onLazyImageReady: function (swiper, slide, image)\n    */\n\n};\nvar initialVirtualTranslate = params && params.virtualTranslate;\n\nparams = params || {};\nvar originalParams = {};\nfor (var param in params) {\n    if (typeof params[param] === 'object' && params[param] !== null && !(params[param].nodeType || params[param] === window || params[param] === document || (typeof Dom7 !== 'undefined' && params[param] instanceof Dom7) || (typeof jQuery !== 'undefined' && params[param] instanceof jQuery))) {\n        originalParams[param] = {};\n        for (var deepParam in params[param]) {\n            originalParams[param][deepParam] = params[param][deepParam];\n        }\n    }\n    else {\n        originalParams[param] = params[param];\n    }\n}\nfor (var def in defaults) {\n    if (typeof params[def] === 'undefined') {\n        params[def] = defaults[def];\n    }\n    else if (typeof params[def] === 'object') {\n        for (var deepDef in defaults[def]) {\n            if (typeof params[def][deepDef] === 'undefined') {\n                params[def][deepDef] = defaults[def][deepDef];\n            }\n        }\n    }\n}\n\n// Swiper\nvar s = this;\n\n// Params\ns.params = params;\ns.originalParams = originalParams;\n\n// Classname\ns.classNames = [];\n/*=========================\n  Dom Library and plugins\n  ===========================*/\nif (typeof $ !== 'undefined' && typeof Dom7 !== 'undefined'){\n    $ = Dom7;\n}\nif (typeof $ === 'undefined') {\n    if (typeof Dom7 === 'undefined') {\n        $ = window.Dom7 || window.Zepto || window.jQuery;\n    }\n    else {\n        $ = Dom7;\n    }\n    if (!$) return;\n}\n// Export it to Swiper instance\ns.$ = $;\n\n/*=========================\n  Breakpoints\n  ===========================*/\ns.currentBreakpoint = undefined;\ns.getActiveBreakpoint = function () {\n    //Get breakpoint for window width\n    if (!s.params.breakpoints) return false;\n    var breakpoint = false;\n    var points = [], point;\n    for ( point in s.params.breakpoints ) {\n        if (s.params.breakpoints.hasOwnProperty(point)) {\n            points.push(point);\n        }\n    }\n    points.sort(function (a, b) {\n        return parseInt(a, 10) > parseInt(b, 10);\n    });\n    for (var i = 0; i < points.length; i++) {\n        point = points[i];\n        if (point >= window.innerWidth && !breakpoint) {\n            breakpoint = point;\n        }\n    }\n    return breakpoint || 'max';\n};\ns.setBreakpoint = function () {\n    //Set breakpoint for window width and update parameters\n    var breakpoint = s.getActiveBreakpoint();\n    if (breakpoint && s.currentBreakpoint !== breakpoint) {\n        var breakPointsParams = breakpoint in s.params.breakpoints ? s.params.breakpoints[breakpoint] : s.originalParams;\n        var needsReLoop = s.params.loop && (breakPointsParams.slidesPerView !== s.params.slidesPerView);\n        for ( var param in breakPointsParams ) {\n            s.params[param] = breakPointsParams[param];\n        }\n        s.currentBreakpoint = breakpoint;\n        if(needsReLoop && s.destroyLoop) {\n            s.reLoop(true);\n        }\n    }\n};\n// Set breakpoint on load\nif (s.params.breakpoints) {\n    s.setBreakpoint();\n}\n\n/*=========================\n  Preparation - Define Container, Wrapper and Pagination\n  ===========================*/\ns.container = $(container);\nif (s.container.length === 0) return;\nif (s.container.length > 1) {\n    var swipers = [];\n    s.container.each(function () {\n        var container = this;\n        swipers.push(new Swiper(this, params));\n    });\n    return swipers;\n}\n\n// Save instance in container HTML Element and in data\ns.container[0].swiper = s;\ns.container.data('swiper', s);\n\ns.classNames.push('swiper-container-' + s.params.direction);\n\nif (s.params.freeMode) {\n    s.classNames.push('swiper-container-free-mode');\n}\nif (!s.support.flexbox) {\n    s.classNames.push('swiper-container-no-flexbox');\n    s.params.slidesPerColumn = 1;\n}\nif (s.params.autoHeight) {\n    s.classNames.push('swiper-container-autoheight');\n}\n// Enable slides progress when required\nif (s.params.parallax || s.params.watchSlidesVisibility) {\n    s.params.watchSlidesProgress = true;\n}\n// Coverflow / 3D\nif (['cube', 'coverflow', 'flip'].indexOf(s.params.effect) >= 0) {\n    if (s.support.transforms3d) {\n        s.params.watchSlidesProgress = true;\n        s.classNames.push('swiper-container-3d');\n    }\n    else {\n        s.params.effect = 'slide';\n    }\n}\nif (s.params.effect !== 'slide') {\n    s.classNames.push('swiper-container-' + s.params.effect);\n}\nif (s.params.effect === 'cube') {\n    s.params.resistanceRatio = 0;\n    s.params.slidesPerView = 1;\n    s.params.slidesPerColumn = 1;\n    s.params.slidesPerGroup = 1;\n    s.params.centeredSlides = false;\n    s.params.spaceBetween = 0;\n    s.params.virtualTranslate = true;\n    s.params.setWrapperSize = false;\n}\nif (s.params.effect === 'fade' || s.params.effect === 'flip') {\n    s.params.slidesPerView = 1;\n    s.params.slidesPerColumn = 1;\n    s.params.slidesPerGroup = 1;\n    s.params.watchSlidesProgress = true;\n    s.params.spaceBetween = 0;\n    s.params.setWrapperSize = false;\n    if (typeof initialVirtualTranslate === 'undefined') {\n        s.params.virtualTranslate = true;\n    }\n}\n\n// Grab Cursor\nif (s.params.grabCursor && s.support.touch) {\n    s.params.grabCursor = false;\n}\n\n// Wrapper\ns.wrapper = s.container.children('.' + s.params.wrapperClass);\n\n// Pagination\nif (s.params.pagination) {\n    s.paginationContainer = $(s.params.pagination);\n    if (s.params.uniqueNavElements && typeof s.params.pagination === 'string' && s.paginationContainer.length > 1 && s.container.find(s.params.pagination).length === 1) {\n        s.paginationContainer = s.container.find(s.params.pagination);\n    }\n\n    if (s.params.paginationType === 'bullets' && s.params.paginationClickable) {\n        s.paginationContainer.addClass('swiper-pagination-clickable');\n    }\n    else {\n        s.params.paginationClickable = false;\n    }\n    s.paginationContainer.addClass('swiper-pagination-' + s.params.paginationType);\n}\n// Next/Prev Buttons\nif (s.params.nextButton || s.params.prevButton) {\n    if (s.params.nextButton) {\n        s.nextButton = $(s.params.nextButton);\n        if (s.params.uniqueNavElements && typeof s.params.nextButton === 'string' && s.nextButton.length > 1 && s.container.find(s.params.nextButton).length === 1) {\n            s.nextButton = s.container.find(s.params.nextButton);\n        }\n    }\n    if (s.params.prevButton) {\n        s.prevButton = $(s.params.prevButton);\n        if (s.params.uniqueNavElements && typeof s.params.prevButton === 'string' && s.prevButton.length > 1 && s.container.find(s.params.prevButton).length === 1) {\n            s.prevButton = s.container.find(s.params.prevButton);\n        }\n    }\n}\n\n// Is Horizontal\ns.isHorizontal = function () {\n    return s.params.direction === 'horizontal';\n};\n// s.isH = isH;\n\n// RTL\ns.rtl = s.isHorizontal() && (s.container[0].dir.toLowerCase() === 'rtl' || s.container.css('direction') === 'rtl');\nif (s.rtl) {\n    s.classNames.push('swiper-container-rtl');\n}\n\n// Wrong RTL support\nif (s.rtl) {\n    s.wrongRTL = s.wrapper.css('display') === '-webkit-box';\n}\n\n// Columns\nif (s.params.slidesPerColumn > 1) {\n    s.classNames.push('swiper-container-multirow');\n}\n\n// Check for Android\nif (s.device.android) {\n    s.classNames.push('swiper-container-android');\n}\n\n// Add classes\ns.container.addClass(s.classNames.join(' '));\n\n// Translate\ns.translate = 0;\n\n// Progress\ns.progress = 0;\n\n// Velocity\ns.velocity = 0;\n\n/*=========================\n  Locks, unlocks\n  ===========================*/\ns.lockSwipeToNext = function () {\n    s.params.allowSwipeToNext = false;\n};\ns.lockSwipeToPrev = function () {\n    s.params.allowSwipeToPrev = false;\n};\ns.lockSwipes = function () {\n    s.params.allowSwipeToNext = s.params.allowSwipeToPrev = false;\n};\ns.unlockSwipeToNext = function () {\n    s.params.allowSwipeToNext = true;\n};\ns.unlockSwipeToPrev = function () {\n    s.params.allowSwipeToPrev = true;\n};\ns.unlockSwipes = function () {\n    s.params.allowSwipeToNext = s.params.allowSwipeToPrev = true;\n};\n\n/*=========================\n  Round helper\n  ===========================*/\nfunction round(a) {\n    return Math.floor(a);\n}\n/*=========================\n  Set grab cursor\n  ===========================*/\nif (s.params.grabCursor) {\n    s.container[0].style.cursor = 'move';\n    s.container[0].style.cursor = '-webkit-grab';\n    s.container[0].style.cursor = '-moz-grab';\n    s.container[0].style.cursor = 'grab';\n}\n/*=========================\n  Update on Images Ready\n  ===========================*/\ns.imagesToLoad = [];\ns.imagesLoaded = 0;\n\ns.loadImage = function (imgElement, src, srcset, checkForComplete, callback) {\n    var image;\n    function onReady () {\n        if (callback) callback();\n    }\n    if (!imgElement.complete || !checkForComplete) {\n        if (src) {\n            image = new window.Image();\n            image.onload = onReady;\n            image.onerror = onReady;\n            if (srcset) {\n                image.srcset = srcset;\n            }\n            if (src) {\n                image.src = src;\n            }\n        } else {\n            onReady();\n        }\n\n    } else {//image already loaded...\n        onReady();\n    }\n};\ns.preloadImages = function () {\n    s.imagesToLoad = s.container.find('img');\n    function _onReady() {\n        if (typeof s === 'undefined' || s === null) return;\n        if (s.imagesLoaded !== undefined) s.imagesLoaded++;\n        if (s.imagesLoaded === s.imagesToLoad.length) {\n            if (s.params.updateOnImagesReady) s.update();\n            s.emit('onImagesReady', s);\n        }\n    }\n    for (var i = 0; i < s.imagesToLoad.length; i++) {\n        s.loadImage(s.imagesToLoad[i], (s.imagesToLoad[i].currentSrc || s.imagesToLoad[i].getAttribute('src')), (s.imagesToLoad[i].srcset || s.imagesToLoad[i].getAttribute('srcset')), true, _onReady);\n    }\n};\n\n/*=========================\n  Autoplay\n  ===========================*/\ns.autoplayTimeoutId = undefined;\ns.autoplaying = false;\ns.autoplayPaused = false;\nfunction autoplay() {\n    s.autoplayTimeoutId = setTimeout(function () {\n        if (s.params.loop) {\n            s.fixLoop();\n            s._slideNext();\n            s.emit('onAutoplay', s);\n        }\n        else {\n            if (!s.isEnd) {\n                s._slideNext();\n                s.emit('onAutoplay', s);\n            }\n            else {\n                if (!params.autoplayStopOnLast) {\n                    s._slideTo(0);\n                    s.emit('onAutoplay', s);\n                }\n                else {\n                    s.stopAutoplay();\n                }\n            }\n        }\n    }, s.params.autoplay);\n}\ns.startAutoplay = function () {\n    if (typeof s.autoplayTimeoutId !== 'undefined') return false;\n    if (!s.params.autoplay) return false;\n    if (s.autoplaying) return false;\n    s.autoplaying = true;\n    s.emit('onAutoplayStart', s);\n    autoplay();\n};\ns.stopAutoplay = function (internal) {\n    if (!s.autoplayTimeoutId) return;\n    if (s.autoplayTimeoutId) clearTimeout(s.autoplayTimeoutId);\n    s.autoplaying = false;\n    s.autoplayTimeoutId = undefined;\n    s.emit('onAutoplayStop', s);\n};\ns.pauseAutoplay = function (speed) {\n    if (s.autoplayPaused) return;\n    if (s.autoplayTimeoutId) clearTimeout(s.autoplayTimeoutId);\n    s.autoplayPaused = true;\n    if (speed === 0) {\n        s.autoplayPaused = false;\n        autoplay();\n    }\n    else {\n        s.wrapper.transitionEnd(function () {\n            if (!s) return;\n            s.autoplayPaused = false;\n            if (!s.autoplaying) {\n                s.stopAutoplay();\n            }\n            else {\n                autoplay();\n            }\n        });\n    }\n};\n/*=========================\n  Min/Max Translate\n  ===========================*/\ns.minTranslate = function () {\n    return (-s.snapGrid[0]);\n};\ns.maxTranslate = function () {\n    return (-s.snapGrid[s.snapGrid.length - 1]);\n};\n/*=========================\n  Slider/slides sizes\n  ===========================*/\ns.updateAutoHeight = function () {\n    // Update Height\n    var slide = s.slides.eq(s.activeIndex)[0];\n    if (typeof slide !== 'undefined') {\n        var newHeight = slide.offsetHeight;\n        if (newHeight) s.wrapper.css('height', newHeight + 'px');\n    }\n};\ns.updateContainerSize = function () {\n    var width, height;\n    if (typeof s.params.width !== 'undefined') {\n        width = s.params.width;\n    }\n    else {\n        width = s.container[0].clientWidth;\n    }\n    if (typeof s.params.height !== 'undefined') {\n        height = s.params.height;\n    }\n    else {\n        height = s.container[0].clientHeight;\n    }\n    if (width === 0 && s.isHorizontal() || height === 0 && !s.isHorizontal()) {\n        return;\n    }\n\n    //Subtract paddings\n    width = width - parseInt(s.container.css('padding-left'), 10) - parseInt(s.container.css('padding-right'), 10);\n    height = height - parseInt(s.container.css('padding-top'), 10) - parseInt(s.container.css('padding-bottom'), 10);\n\n    // Store values\n    s.width = width;\n    s.height = height;\n    s.size = s.isHorizontal() ? s.width : s.height;\n};\n\ns.updateSlidesSize = function () {\n    s.slides = s.wrapper.children('.' + s.params.slideClass);\n    s.snapGrid = [];\n    s.slidesGrid = [];\n    s.slidesSizesGrid = [];\n\n    var spaceBetween = s.params.spaceBetween,\n        slidePosition = -s.params.slidesOffsetBefore,\n        i,\n        prevSlideSize = 0,\n        index = 0;\n    if (typeof s.size === 'undefined') return;\n    if (typeof spaceBetween === 'string' && spaceBetween.indexOf('%') >= 0) {\n        spaceBetween = parseFloat(spaceBetween.replace('%', '')) / 100 * s.size;\n    }\n\n    s.virtualSize = -spaceBetween;\n    // reset margins\n    if (s.rtl) s.slides.css({marginLeft: '', marginTop: ''});\n    else s.slides.css({marginRight: '', marginBottom: ''});\n\n    var slidesNumberEvenToRows;\n    if (s.params.slidesPerColumn > 1) {\n        if (Math.floor(s.slides.length / s.params.slidesPerColumn) === s.slides.length / s.params.slidesPerColumn) {\n            slidesNumberEvenToRows = s.slides.length;\n        }\n        else {\n            slidesNumberEvenToRows = Math.ceil(s.slides.length / s.params.slidesPerColumn) * s.params.slidesPerColumn;\n        }\n        if (s.params.slidesPerView !== 'auto' && s.params.slidesPerColumnFill === 'row') {\n            slidesNumberEvenToRows = Math.max(slidesNumberEvenToRows, s.params.slidesPerView * s.params.slidesPerColumn);\n        }\n    }\n\n    // Calc slides\n    var slideSize;\n    var slidesPerColumn = s.params.slidesPerColumn;\n    var slidesPerRow = slidesNumberEvenToRows / slidesPerColumn;\n    var numFullColumns = slidesPerRow - (s.params.slidesPerColumn * slidesPerRow - s.slides.length);\n    for (i = 0; i < s.slides.length; i++) {\n        slideSize = 0;\n        var slide = s.slides.eq(i);\n        if (s.params.slidesPerColumn > 1) {\n            // Set slides order\n            var newSlideOrderIndex;\n            var column, row;\n            if (s.params.slidesPerColumnFill === 'column') {\n                column = Math.floor(i / slidesPerColumn);\n                row = i - column * slidesPerColumn;\n                if (column > numFullColumns || (column === numFullColumns && row === slidesPerColumn-1)) {\n                    if (++row >= slidesPerColumn) {\n                        row = 0;\n                        column++;\n                    }\n                }\n                newSlideOrderIndex = column + row * slidesNumberEvenToRows / slidesPerColumn;\n                slide\n                    .css({\n                        '-webkit-box-ordinal-group': newSlideOrderIndex,\n                        '-moz-box-ordinal-group': newSlideOrderIndex,\n                        '-ms-flex-order': newSlideOrderIndex,\n                        '-webkit-order': newSlideOrderIndex,\n                        'order': newSlideOrderIndex\n                    });\n            }\n            else {\n                row = Math.floor(i / slidesPerRow);\n                column = i - row * slidesPerRow;\n            }\n            slide\n                .css({\n                    'margin-top': (row !== 0 && s.params.spaceBetween) && (s.params.spaceBetween + 'px')\n                })\n                .attr('data-swiper-column', column)\n                .attr('data-swiper-row', row);\n\n        }\n        if (slide.css('display') === 'none') continue;\n        if (s.params.slidesPerView === 'auto') {\n            slideSize = s.isHorizontal() ? slide.outerWidth(true) : slide.outerHeight(true);\n            if (s.params.roundLengths) slideSize = round(slideSize);\n        }\n        else {\n            slideSize = (s.size - (s.params.slidesPerView - 1) * spaceBetween) / s.params.slidesPerView;\n            if (s.params.roundLengths) slideSize = round(slideSize);\n\n            if (s.isHorizontal()) {\n                s.slides[i].style.width = slideSize + 'px';\n            }\n            else {\n                s.slides[i].style.height = slideSize + 'px';\n            }\n        }\n        s.slides[i].swiperSlideSize = slideSize;\n        s.slidesSizesGrid.push(slideSize);\n\n\n        if (s.params.centeredSlides) {\n            slidePosition = slidePosition + slideSize / 2 + prevSlideSize / 2 + spaceBetween;\n            if (i === 0) slidePosition = slidePosition - s.size / 2 - spaceBetween;\n            if (Math.abs(slidePosition) < 1 / 1000) slidePosition = 0;\n            if ((index) % s.params.slidesPerGroup === 0) s.snapGrid.push(slidePosition);\n            s.slidesGrid.push(slidePosition);\n        }\n        else {\n            if ((index) % s.params.slidesPerGroup === 0) s.snapGrid.push(slidePosition);\n            s.slidesGrid.push(slidePosition);\n            slidePosition = slidePosition + slideSize + spaceBetween;\n        }\n\n        s.virtualSize += slideSize + spaceBetween;\n\n        prevSlideSize = slideSize;\n\n        index ++;\n    }\n    s.virtualSize = Math.max(s.virtualSize, s.size) + s.params.slidesOffsetAfter;\n    var newSlidesGrid;\n\n    if (\n        s.rtl && s.wrongRTL && (s.params.effect === 'slide' || s.params.effect === 'coverflow')) {\n        s.wrapper.css({width: s.virtualSize + s.params.spaceBetween + 'px'});\n    }\n    if (!s.support.flexbox || s.params.setWrapperSize) {\n        if (s.isHorizontal()) s.wrapper.css({width: s.virtualSize + s.params.spaceBetween + 'px'});\n        else s.wrapper.css({height: s.virtualSize + s.params.spaceBetween + 'px'});\n    }\n\n    if (s.params.slidesPerColumn > 1) {\n        s.virtualSize = (slideSize + s.params.spaceBetween) * slidesNumberEvenToRows;\n        s.virtualSize = Math.ceil(s.virtualSize / s.params.slidesPerColumn) - s.params.spaceBetween;\n        s.wrapper.css({width: s.virtualSize + s.params.spaceBetween + 'px'});\n        if (s.params.centeredSlides) {\n            newSlidesGrid = [];\n            for (i = 0; i < s.snapGrid.length; i++) {\n                if (s.snapGrid[i] < s.virtualSize + s.snapGrid[0]) newSlidesGrid.push(s.snapGrid[i]);\n            }\n            s.snapGrid = newSlidesGrid;\n        }\n    }\n\n    // Remove last grid elements depending on width\n    if (!s.params.centeredSlides) {\n        newSlidesGrid = [];\n        for (i = 0; i < s.snapGrid.length; i++) {\n            if (s.snapGrid[i] <= s.virtualSize - s.size) {\n                newSlidesGrid.push(s.snapGrid[i]);\n            }\n        }\n        s.snapGrid = newSlidesGrid;\n        if (Math.floor(s.virtualSize - s.size) - Math.floor(s.snapGrid[s.snapGrid.length - 1]) > 1) {\n            s.snapGrid.push(s.virtualSize - s.size);\n        }\n    }\n    if (s.snapGrid.length === 0) s.snapGrid = [0];\n\n    if (s.params.spaceBetween !== 0) {\n        if (s.isHorizontal()) {\n            if (s.rtl) s.slides.css({marginLeft: spaceBetween + 'px'});\n            else s.slides.css({marginRight: spaceBetween + 'px'});\n        }\n        else s.slides.css({marginBottom: spaceBetween + 'px'});\n    }\n    if (s.params.watchSlidesProgress) {\n        s.updateSlidesOffset();\n    }\n};\ns.updateSlidesOffset = function () {\n    for (var i = 0; i < s.slides.length; i++) {\n        s.slides[i].swiperSlideOffset = s.isHorizontal() ? s.slides[i].offsetLeft : s.slides[i].offsetTop;\n    }\n};\n\n/*=========================\n  Slider/slides progress\n  ===========================*/\ns.updateSlidesProgress = function (translate) {\n    if (typeof translate === 'undefined') {\n        translate = s.translate || 0;\n    }\n    if (s.slides.length === 0) return;\n    if (typeof s.slides[0].swiperSlideOffset === 'undefined') s.updateSlidesOffset();\n\n    var offsetCenter = -translate;\n    if (s.rtl) offsetCenter = translate;\n\n    // Visible Slides\n    s.slides.removeClass(s.params.slideVisibleClass);\n    for (var i = 0; i < s.slides.length; i++) {\n        var slide = s.slides[i];\n        var slideProgress = (offsetCenter - slide.swiperSlideOffset) / (slide.swiperSlideSize + s.params.spaceBetween);\n        if (s.params.watchSlidesVisibility) {\n            var slideBefore = -(offsetCenter - slide.swiperSlideOffset);\n            var slideAfter = slideBefore + s.slidesSizesGrid[i];\n            var isVisible =\n                (slideBefore >= 0 && slideBefore < s.size) ||\n                (slideAfter > 0 && slideAfter <= s.size) ||\n                (slideBefore <= 0 && slideAfter >= s.size);\n            if (isVisible) {\n                s.slides.eq(i).addClass(s.params.slideVisibleClass);\n            }\n        }\n        slide.progress = s.rtl ? -slideProgress : slideProgress;\n    }\n};\ns.updateProgress = function (translate) {\n    if (typeof translate === 'undefined') {\n        translate = s.translate || 0;\n    }\n    var translatesDiff = s.maxTranslate() - s.minTranslate();\n    var wasBeginning = s.isBeginning;\n    var wasEnd = s.isEnd;\n    if (translatesDiff === 0) {\n        s.progress = 0;\n        s.isBeginning = s.isEnd = true;\n    }\n    else {\n        s.progress = (translate - s.minTranslate()) / (translatesDiff);\n        s.isBeginning = s.progress <= 0;\n        s.isEnd = s.progress >= 1;\n    }\n    if (s.isBeginning && !wasBeginning) s.emit('onReachBeginning', s);\n    if (s.isEnd && !wasEnd) s.emit('onReachEnd', s);\n\n    if (s.params.watchSlidesProgress) s.updateSlidesProgress(translate);\n    s.emit('onProgress', s, s.progress);\n};\ns.updateActiveIndex = function () {\n    var translate = s.rtl ? s.translate : -s.translate;\n    var newActiveIndex, i, snapIndex;\n    for (i = 0; i < s.slidesGrid.length; i ++) {\n        if (typeof s.slidesGrid[i + 1] !== 'undefined') {\n            if (translate >= s.slidesGrid[i] && translate < s.slidesGrid[i + 1] - (s.slidesGrid[i + 1] - s.slidesGrid[i]) / 2) {\n                newActiveIndex = i;\n            }\n            else if (translate >= s.slidesGrid[i] && translate < s.slidesGrid[i + 1]) {\n                newActiveIndex = i + 1;\n            }\n        }\n        else {\n            if (translate >= s.slidesGrid[i]) {\n                newActiveIndex = i;\n            }\n        }\n    }\n    // Normalize slideIndex\n    if (newActiveIndex < 0 || typeof newActiveIndex === 'undefined') newActiveIndex = 0;\n    // for (i = 0; i < s.slidesGrid.length; i++) {\n        // if (- translate >= s.slidesGrid[i]) {\n            // newActiveIndex = i;\n        // }\n    // }\n    snapIndex = Math.floor(newActiveIndex / s.params.slidesPerGroup);\n    if (snapIndex >= s.snapGrid.length) snapIndex = s.snapGrid.length - 1;\n\n    if (newActiveIndex === s.activeIndex) {\n        return;\n    }\n    s.snapIndex = snapIndex;\n    s.previousIndex = s.activeIndex;\n    s.activeIndex = newActiveIndex;\n    s.updateClasses();\n};\n\n/*=========================\n  Classes\n  ===========================*/\ns.updateClasses = function () {\n    s.slides.removeClass(s.params.slideActiveClass + ' ' + s.params.slideNextClass + ' ' + s.params.slidePrevClass);\n    var activeSlide = s.slides.eq(s.activeIndex);\n    // Active classes\n    activeSlide.addClass(s.params.slideActiveClass);\n    // Next Slide\n    var nextSlide = activeSlide.next('.' + s.params.slideClass).addClass(s.params.slideNextClass);\n    if (s.params.loop && nextSlide.length === 0) {\n        s.slides.eq(0).addClass(s.params.slideNextClass);\n    }\n    // Prev Slide\n    var prevSlide = activeSlide.prev('.' + s.params.slideClass).addClass(s.params.slidePrevClass);\n    if (s.params.loop && prevSlide.length === 0) {\n        s.slides.eq(-1).addClass(s.params.slidePrevClass);\n    }\n\n    // Pagination\n    if (s.paginationContainer && s.paginationContainer.length > 0) {\n        // Current/Total\n        var current,\n            total = s.params.loop ? Math.ceil((s.slides.length - s.loopedSlides * 2) / s.params.slidesPerGroup) : s.snapGrid.length;\n        if (s.params.loop) {\n            current = Math.ceil((s.activeIndex - s.loopedSlides)/s.params.slidesPerGroup);\n            if (current > s.slides.length - 1 - s.loopedSlides * 2) {\n                current = current - (s.slides.length - s.loopedSlides * 2);\n            }\n            if (current > total - 1) current = current - total;\n            if (current < 0 && s.params.paginationType !== 'bullets') current = total + current;\n        }\n        else {\n            if (typeof s.snapIndex !== 'undefined') {\n                current = s.snapIndex;\n            }\n            else {\n                current = s.activeIndex || 0;\n            }\n        }\n        // Types\n        if (s.params.paginationType === 'bullets' && s.bullets && s.bullets.length > 0) {\n            s.bullets.removeClass(s.params.bulletActiveClass);\n            if (s.paginationContainer.length > 1) {\n                s.bullets.each(function () {\n                    if ($(this).index() === current) $(this).addClass(s.params.bulletActiveClass);\n                });\n            }\n            else {\n                s.bullets.eq(current).addClass(s.params.bulletActiveClass);\n            }\n        }\n        if (s.params.paginationType === 'fraction') {\n            s.paginationContainer.find('.' + s.params.paginationCurrentClass).text(current + 1);\n            s.paginationContainer.find('.' + s.params.paginationTotalClass).text(total);\n        }\n        if (s.params.paginationType === 'progress') {\n            var scale = (current + 1) / total,\n                scaleX = scale,\n                scaleY = 1;\n            if (!s.isHorizontal()) {\n                scaleY = scale;\n                scaleX = 1;\n            }\n            s.paginationContainer.find('.' + s.params.paginationProgressbarClass).transform('translate3d(0,0,0) scaleX(' + scaleX + ') scaleY(' + scaleY + ')').transition(s.params.speed);\n        }\n        if (s.params.paginationType === 'custom' && s.params.paginationCustomRender) {\n            s.paginationContainer.html(s.params.paginationCustomRender(s, current + 1, total));\n            s.emit('onPaginationRendered', s, s.paginationContainer[0]);\n        }\n    }\n\n    // Next/active buttons\n    if (!s.params.loop) {\n        if (s.params.prevButton && s.prevButton && s.prevButton.length > 0) {\n            if (s.isBeginning) {\n                s.prevButton.addClass(s.params.buttonDisabledClass);\n                if (s.params.a11y && s.a11y) s.a11y.disable(s.prevButton);\n            }\n            else {\n                s.prevButton.removeClass(s.params.buttonDisabledClass);\n                if (s.params.a11y && s.a11y) s.a11y.enable(s.prevButton);\n            }\n        }\n        if (s.params.nextButton && s.nextButton && s.nextButton.length > 0) {\n            if (s.isEnd) {\n                s.nextButton.addClass(s.params.buttonDisabledClass);\n                if (s.params.a11y && s.a11y) s.a11y.disable(s.nextButton);\n            }\n            else {\n                s.nextButton.removeClass(s.params.buttonDisabledClass);\n                if (s.params.a11y && s.a11y) s.a11y.enable(s.nextButton);\n            }\n        }\n    }\n};\n\n/*=========================\n  Pagination\n  ===========================*/\ns.updatePagination = function () {\n    if (!s.params.pagination) return;\n    if (s.paginationContainer && s.paginationContainer.length > 0) {\n        var paginationHTML = '';\n        if (s.params.paginationType === 'bullets') {\n            var numberOfBullets = s.params.loop ? Math.ceil((s.slides.length - s.loopedSlides * 2) / s.params.slidesPerGroup) : s.snapGrid.length;\n            for (var i = 0; i < numberOfBullets; i++) {\n                if (s.params.paginationBulletRender) {\n                    paginationHTML += s.params.paginationBulletRender(i, s.params.bulletClass);\n                }\n                else {\n                    paginationHTML += '<' + s.params.paginationElement+' class=\"' + s.params.bulletClass + '\"></' + s.params.paginationElement + '>';\n                }\n            }\n            s.paginationContainer.html(paginationHTML);\n            s.bullets = s.paginationContainer.find('.' + s.params.bulletClass);\n            if (s.params.paginationClickable && s.params.a11y && s.a11y) {\n                s.a11y.initPagination();\n            }\n        }\n        if (s.params.paginationType === 'fraction') {\n            if (s.params.paginationFractionRender) {\n                paginationHTML = s.params.paginationFractionRender(s, s.params.paginationCurrentClass, s.params.paginationTotalClass);\n            }\n            else {\n                paginationHTML =\n                    '<span class=\"' + s.params.paginationCurrentClass + '\"></span>' +\n                    ' / ' +\n                    '<span class=\"' + s.params.paginationTotalClass+'\"></span>';\n            }\n            s.paginationContainer.html(paginationHTML);\n        }\n        if (s.params.paginationType === 'progress') {\n            if (s.params.paginationProgressRender) {\n                paginationHTML = s.params.paginationProgressRender(s, s.params.paginationProgressbarClass);\n            }\n            else {\n                paginationHTML = '<span class=\"' + s.params.paginationProgressbarClass + '\"></span>';\n            }\n            s.paginationContainer.html(paginationHTML);\n        }\n        if (s.params.paginationType !== 'custom') {\n            s.emit('onPaginationRendered', s, s.paginationContainer[0]);\n        }\n    }\n};\n/*=========================\n  Common update method\n  ===========================*/\ns.update = function (updateTranslate) {\n    s.updateContainerSize();\n    s.updateSlidesSize();\n    s.updateProgress();\n    s.updatePagination();\n    s.updateClasses();\n    if (s.params.scrollbar && s.scrollbar) {\n        s.scrollbar.set();\n    }\n    function forceSetTranslate() {\n        newTranslate = Math.min(Math.max(s.translate, s.maxTranslate()), s.minTranslate());\n        s.setWrapperTranslate(newTranslate);\n        s.updateActiveIndex();\n        s.updateClasses();\n    }\n    if (updateTranslate) {\n        var translated, newTranslate;\n        if (s.controller && s.controller.spline) {\n            s.controller.spline = undefined;\n        }\n        if (s.params.freeMode) {\n            forceSetTranslate();\n            if (s.params.autoHeight) {\n                s.updateAutoHeight();\n            }\n        }\n        else {\n            if ((s.params.slidesPerView === 'auto' || s.params.slidesPerView > 1) && s.isEnd && !s.params.centeredSlides) {\n                translated = s.slideTo(s.slides.length - 1, 0, false, true);\n            }\n            else {\n                translated = s.slideTo(s.activeIndex, 0, false, true);\n            }\n            if (!translated) {\n                forceSetTranslate();\n            }\n        }\n    }\n    else if (s.params.autoHeight) {\n        s.updateAutoHeight();\n    }\n};\n\n/*=========================\n  Resize Handler\n  ===========================*/\ns.onResize = function (forceUpdatePagination) {\n    //Breakpoints\n    if (s.params.breakpoints) {\n        s.setBreakpoint();\n    }\n\n    // Disable locks on resize\n    var allowSwipeToPrev = s.params.allowSwipeToPrev;\n    var allowSwipeToNext = s.params.allowSwipeToNext;\n    s.params.allowSwipeToPrev = s.params.allowSwipeToNext = true;\n\n    s.updateContainerSize();\n    s.updateSlidesSize();\n    if (s.params.slidesPerView === 'auto' || s.params.freeMode || forceUpdatePagination) s.updatePagination();\n    if (s.params.scrollbar && s.scrollbar) {\n        s.scrollbar.set();\n    }\n    if (s.controller && s.controller.spline) {\n        s.controller.spline = undefined;\n    }\n    var slideChangedBySlideTo = false;\n    if (s.params.freeMode) {\n        var newTranslate = Math.min(Math.max(s.translate, s.maxTranslate()), s.minTranslate());\n        s.setWrapperTranslate(newTranslate);\n        s.updateActiveIndex();\n        s.updateClasses();\n\n        if (s.params.autoHeight) {\n            s.updateAutoHeight();\n        }\n    }\n    else {\n        s.updateClasses();\n        if ((s.params.slidesPerView === 'auto' || s.params.slidesPerView > 1) && s.isEnd && !s.params.centeredSlides) {\n            slideChangedBySlideTo = s.slideTo(s.slides.length - 1, 0, false, true);\n        }\n        else {\n            slideChangedBySlideTo = s.slideTo(s.activeIndex, 0, false, true);\n        }\n    }\n    if (s.params.lazyLoading && !slideChangedBySlideTo && s.lazy) {\n        s.lazy.load();\n    }\n    // Return locks after resize\n    s.params.allowSwipeToPrev = allowSwipeToPrev;\n    s.params.allowSwipeToNext = allowSwipeToNext;\n};\n\n/*=========================\n  Events\n  ===========================*/\n\n//Define Touch Events\nvar desktopEvents = ['mousedown', 'mousemove', 'mouseup'];\nif (window.navigator.pointerEnabled) desktopEvents = ['pointerdown', 'pointermove', 'pointerup'];\nelse if (window.navigator.msPointerEnabled) desktopEvents = ['MSPointerDown', 'MSPointerMove', 'MSPointerUp'];\ns.touchEvents = {\n    start : s.support.touch || !s.params.simulateTouch  ? 'touchstart' : desktopEvents[0],\n    move : s.support.touch || !s.params.simulateTouch ? 'touchmove' : desktopEvents[1],\n    end : s.support.touch || !s.params.simulateTouch ? 'touchend' : desktopEvents[2]\n};\n\n\n// WP8 Touch Events Fix\nif (window.navigator.pointerEnabled || window.navigator.msPointerEnabled) {\n    (s.params.touchEventsTarget === 'container' ? s.container : s.wrapper).addClass('swiper-wp8-' + s.params.direction);\n}\n\n// Attach/detach events\ns.initEvents = function (detach) {\n    var actionDom = detach ? 'off' : 'on';\n    var action = detach ? 'removeEventListener' : 'addEventListener';\n    var touchEventsTarget = s.params.touchEventsTarget === 'container' ? s.container[0] : s.wrapper[0];\n    var target = s.support.touch ? touchEventsTarget : document;\n\n    var moveCapture = s.params.nested ? true : false;\n\n    //Touch Events\n    if (s.browser.ie) {\n        touchEventsTarget[action](s.touchEvents.start, s.onTouchStart, false);\n        target[action](s.touchEvents.move, s.onTouchMove, moveCapture);\n        target[action](s.touchEvents.end, s.onTouchEnd, false);\n    }\n    else {\n        if (s.support.touch) {\n            touchEventsTarget[action](s.touchEvents.start, s.onTouchStart, false);\n            touchEventsTarget[action](s.touchEvents.move, s.onTouchMove, moveCapture);\n            touchEventsTarget[action](s.touchEvents.end, s.onTouchEnd, false);\n        }\n        if (params.simulateTouch && !s.device.ios && !s.device.android) {\n            touchEventsTarget[action]('mousedown', s.onTouchStart, false);\n            document[action]('mousemove', s.onTouchMove, moveCapture);\n            document[action]('mouseup', s.onTouchEnd, false);\n        }\n    }\n    window[action]('resize', s.onResize);\n\n    // Next, Prev, Index\n    if (s.params.nextButton && s.nextButton && s.nextButton.length > 0) {\n        s.nextButton[actionDom]('click', s.onClickNext);\n        if (s.params.a11y && s.a11y) s.nextButton[actionDom]('keydown', s.a11y.onEnterKey);\n    }\n    if (s.params.prevButton && s.prevButton && s.prevButton.length > 0) {\n        s.prevButton[actionDom]('click', s.onClickPrev);\n        if (s.params.a11y && s.a11y) s.prevButton[actionDom]('keydown', s.a11y.onEnterKey);\n    }\n    if (s.params.pagination && s.params.paginationClickable) {\n        s.paginationContainer[actionDom]('click', '.' + s.params.bulletClass, s.onClickIndex);\n        if (s.params.a11y && s.a11y) s.paginationContainer[actionDom]('keydown', '.' + s.params.bulletClass, s.a11y.onEnterKey);\n    }\n\n    // Prevent Links Clicks\n    if (s.params.preventClicks || s.params.preventClicksPropagation) touchEventsTarget[action]('click', s.preventClicks, true);\n};\ns.attachEvents = function () {\n    s.initEvents();\n};\ns.detachEvents = function () {\n    s.initEvents(true);\n};\n\n/*=========================\n  Handle Clicks\n  ===========================*/\n// Prevent Clicks\ns.allowClick = true;\ns.preventClicks = function (e) {\n    if (!s.allowClick) {\n        if (s.params.preventClicks) e.preventDefault();\n        if (s.params.preventClicksPropagation && s.animating) {\n            e.stopPropagation();\n            e.stopImmediatePropagation();\n        }\n    }\n};\n// Clicks\ns.onClickNext = function (e) {\n    e.preventDefault();\n    if (s.isEnd && !s.params.loop) return;\n    s.slideNext();\n};\ns.onClickPrev = function (e) {\n    e.preventDefault();\n    if (s.isBeginning && !s.params.loop) return;\n    s.slidePrev();\n};\ns.onClickIndex = function (e) {\n    e.preventDefault();\n    var index = $(this).index() * s.params.slidesPerGroup;\n    if (s.params.loop) index = index + s.loopedSlides;\n    s.slideTo(index);\n};\n\n/*=========================\n  Handle Touches\n  ===========================*/\nfunction findElementInEvent(e, selector) {\n    var el = $(e.target);\n    if (!el.is(selector)) {\n        if (typeof selector === 'string') {\n            el = el.parents(selector);\n        }\n        else if (selector.nodeType) {\n            var found;\n            el.parents().each(function (index, _el) {\n                if (_el === selector) found = selector;\n            });\n            if (!found) return undefined;\n            else return selector;\n        }\n    }\n    if (el.length === 0) {\n        return undefined;\n    }\n    return el[0];\n}\ns.updateClickedSlide = function (e) {\n    var slide = findElementInEvent(e, '.' + s.params.slideClass);\n    var slideFound = false;\n    if (slide) {\n        for (var i = 0; i < s.slides.length; i++) {\n            if (s.slides[i] === slide) slideFound = true;\n        }\n    }\n\n    if (slide && slideFound) {\n        s.clickedSlide = slide;\n        s.clickedIndex = $(slide).index();\n    }\n    else {\n        s.clickedSlide = undefined;\n        s.clickedIndex = undefined;\n        return;\n    }\n    if (s.params.slideToClickedSlide && s.clickedIndex !== undefined && s.clickedIndex !== s.activeIndex) {\n        var slideToIndex = s.clickedIndex,\n            realIndex,\n            duplicatedSlides;\n        if (s.params.loop) {\n            if (s.animating) return;\n            realIndex = $(s.clickedSlide).attr('data-swiper-slide-index');\n            if (s.params.centeredSlides) {\n                if ((slideToIndex < s.loopedSlides - s.params.slidesPerView/2) || (slideToIndex > s.slides.length - s.loopedSlides + s.params.slidesPerView/2)) {\n                    s.fixLoop();\n                    slideToIndex = s.wrapper.children('.' + s.params.slideClass + '[data-swiper-slide-index=\"' + realIndex + '\"]:not(.swiper-slide-duplicate)').eq(0).index();\n                    setTimeout(function () {\n                        s.slideTo(slideToIndex);\n                    }, 0);\n                }\n                else {\n                    s.slideTo(slideToIndex);\n                }\n            }\n            else {\n                if (slideToIndex > s.slides.length - s.params.slidesPerView) {\n                    s.fixLoop();\n                    slideToIndex = s.wrapper.children('.' + s.params.slideClass + '[data-swiper-slide-index=\"' + realIndex + '\"]:not(.swiper-slide-duplicate)').eq(0).index();\n                    setTimeout(function () {\n                        s.slideTo(slideToIndex);\n                    }, 0);\n                }\n                else {\n                    s.slideTo(slideToIndex);\n                }\n            }\n        }\n        else {\n            s.slideTo(slideToIndex);\n        }\n    }\n};\n\nvar isTouched,\n    isMoved,\n    allowTouchCallbacks,\n    touchStartTime,\n    isScrolling,\n    currentTranslate,\n    startTranslate,\n    allowThresholdMove,\n    // Form elements to match\n    formElements = 'input, select, textarea, button',\n    // Last click time\n    lastClickTime = Date.now(), clickTimeout,\n    //Velocities\n    velocities = [],\n    allowMomentumBounce;\n\n// Animating Flag\ns.animating = false;\n\n// Touches information\ns.touches = {\n    startX: 0,\n    startY: 0,\n    currentX: 0,\n    currentY: 0,\n    diff: 0\n};\n\n// Touch handlers\nvar isTouchEvent, startMoving;\ns.onTouchStart = function (e) {\n    if (e.originalEvent) e = e.originalEvent;\n    isTouchEvent = e.type === 'touchstart';\n    if (!isTouchEvent && 'which' in e && e.which === 3) return;\n    if (s.params.noSwiping && findElementInEvent(e, '.' + s.params.noSwipingClass)) {\n        s.allowClick = true;\n        return;\n    }\n    if (s.params.swipeHandler) {\n        if (!findElementInEvent(e, s.params.swipeHandler)) return;\n    }\n\n    var startX = s.touches.currentX = e.type === 'touchstart' ? e.targetTouches[0].pageX : e.pageX;\n    var startY = s.touches.currentY = e.type === 'touchstart' ? e.targetTouches[0].pageY : e.pageY;\n\n    // Do NOT start if iOS edge swipe is detected. Otherwise iOS app (UIWebView) cannot swipe-to-go-back anymore\n    if(s.device.ios && s.params.iOSEdgeSwipeDetection && startX <= s.params.iOSEdgeSwipeThreshold) {\n        return;\n    }\n\n    isTouched = true;\n    isMoved = false;\n    allowTouchCallbacks = true;\n    isScrolling = undefined;\n    startMoving = undefined;\n    s.touches.startX = startX;\n    s.touches.startY = startY;\n    touchStartTime = Date.now();\n    s.allowClick = true;\n    s.updateContainerSize();\n    s.swipeDirection = undefined;\n    if (s.params.threshold > 0) allowThresholdMove = false;\n    if (e.type !== 'touchstart') {\n        var preventDefault = true;\n        if ($(e.target).is(formElements)) preventDefault = false;\n        if (document.activeElement && $(document.activeElement).is(formElements)) {\n            document.activeElement.blur();\n        }\n        if (preventDefault) {\n            e.preventDefault();\n        }\n    }\n    s.emit('onTouchStart', s, e);\n};\n\ns.onTouchMove = function (e) {\n    if (e.originalEvent) e = e.originalEvent;\n    if (isTouchEvent && e.type === 'mousemove') return;\n    if (e.preventedByNestedSwiper) {\n        s.touches.startX = e.type === 'touchmove' ? e.targetTouches[0].pageX : e.pageX;\n        s.touches.startY = e.type === 'touchmove' ? e.targetTouches[0].pageY : e.pageY;\n        return;\n    }\n    if (s.params.onlyExternal) {\n        // isMoved = true;\n        s.allowClick = false;\n        if (isTouched) {\n            s.touches.startX = s.touches.currentX = e.type === 'touchmove' ? e.targetTouches[0].pageX : e.pageX;\n            s.touches.startY = s.touches.currentY = e.type === 'touchmove' ? e.targetTouches[0].pageY : e.pageY;\n            touchStartTime = Date.now();\n        }\n        return;\n    }\n    if (isTouchEvent && document.activeElement) {\n        if (e.target === document.activeElement && $(e.target).is(formElements)) {\n            isMoved = true;\n            s.allowClick = false;\n            return;\n        }\n    }\n    if (allowTouchCallbacks) {\n        s.emit('onTouchMove', s, e);\n    }\n    if (e.targetTouches && e.targetTouches.length > 1) return;\n\n    s.touches.currentX = e.type === 'touchmove' ? e.targetTouches[0].pageX : e.pageX;\n    s.touches.currentY = e.type === 'touchmove' ? e.targetTouches[0].pageY : e.pageY;\n\n    if (typeof isScrolling === 'undefined') {\n        var touchAngle = Math.atan2(Math.abs(s.touches.currentY - s.touches.startY), Math.abs(s.touches.currentX - s.touches.startX)) * 180 / Math.PI;\n        isScrolling = s.isHorizontal() ? touchAngle > s.params.touchAngle : (90 - touchAngle > s.params.touchAngle);\n    }\n    if (isScrolling) {\n        s.emit('onTouchMoveOpposite', s, e);\n    }\n    if (typeof startMoving === 'undefined' && s.browser.ieTouch) {\n        if (s.touches.currentX !== s.touches.startX || s.touches.currentY !== s.touches.startY) {\n            startMoving = true;\n        }\n    }\n    if (!isTouched) return;\n    if (isScrolling)  {\n        isTouched = false;\n        return;\n    }\n    if (!startMoving && s.browser.ieTouch) {\n        return;\n    }\n    s.allowClick = false;\n    s.emit('onSliderMove', s, e);\n    e.preventDefault();\n    if (s.params.touchMoveStopPropagation && !s.params.nested) {\n        e.stopPropagation();\n    }\n\n    if (!isMoved) {\n        if (params.loop) {\n            s.fixLoop();\n        }\n        startTranslate = s.getWrapperTranslate();\n        s.setWrapperTransition(0);\n        if (s.animating) {\n            s.wrapper.trigger('webkitTransitionEnd transitionend oTransitionEnd MSTransitionEnd msTransitionEnd');\n        }\n        if (s.params.autoplay && s.autoplaying) {\n            if (s.params.autoplayDisableOnInteraction) {\n                s.stopAutoplay();\n            }\n            else {\n                s.pauseAutoplay();\n            }\n        }\n        allowMomentumBounce = false;\n        //Grab Cursor\n        if (s.params.grabCursor) {\n            s.container[0].style.cursor = 'move';\n            s.container[0].style.cursor = '-webkit-grabbing';\n            s.container[0].style.cursor = '-moz-grabbin';\n            s.container[0].style.cursor = 'grabbing';\n        }\n    }\n    isMoved = true;\n\n    var diff = s.touches.diff = s.isHorizontal() ? s.touches.currentX - s.touches.startX : s.touches.currentY - s.touches.startY;\n\n    diff = diff * s.params.touchRatio;\n    if (s.rtl) diff = -diff;\n\n    s.swipeDirection = diff > 0 ? 'prev' : 'next';\n    currentTranslate = diff + startTranslate;\n\n    var disableParentSwiper = true;\n    if ((diff > 0 && currentTranslate > s.minTranslate())) {\n        disableParentSwiper = false;\n        if (s.params.resistance) currentTranslate = s.minTranslate() - 1 + Math.pow(-s.minTranslate() + startTranslate + diff, s.params.resistanceRatio);\n    }\n    else if (diff < 0 && currentTranslate < s.maxTranslate()) {\n        disableParentSwiper = false;\n        if (s.params.resistance) currentTranslate = s.maxTranslate() + 1 - Math.pow(s.maxTranslate() - startTranslate - diff, s.params.resistanceRatio);\n    }\n\n    if (disableParentSwiper) {\n        e.preventedByNestedSwiper = true;\n    }\n\n    // Directions locks\n    if (!s.params.allowSwipeToNext && s.swipeDirection === 'next' && currentTranslate < startTranslate) {\n        currentTranslate = startTranslate;\n    }\n    if (!s.params.allowSwipeToPrev && s.swipeDirection === 'prev' && currentTranslate > startTranslate) {\n        currentTranslate = startTranslate;\n    }\n\n    if (!s.params.followFinger) return;\n\n    // Threshold\n    if (s.params.threshold > 0) {\n        if (Math.abs(diff) > s.params.threshold || allowThresholdMove) {\n            if (!allowThresholdMove) {\n                allowThresholdMove = true;\n                s.touches.startX = s.touches.currentX;\n                s.touches.startY = s.touches.currentY;\n                currentTranslate = startTranslate;\n                s.touches.diff = s.isHorizontal() ? s.touches.currentX - s.touches.startX : s.touches.currentY - s.touches.startY;\n                return;\n            }\n        }\n        else {\n            currentTranslate = startTranslate;\n            return;\n        }\n    }\n    // Update active index in free mode\n    if (s.params.freeMode || s.params.watchSlidesProgress) {\n        s.updateActiveIndex();\n    }\n    if (s.params.freeMode) {\n        //Velocity\n        if (velocities.length === 0) {\n            velocities.push({\n                position: s.touches[s.isHorizontal() ? 'startX' : 'startY'],\n                time: touchStartTime\n            });\n        }\n        velocities.push({\n            position: s.touches[s.isHorizontal() ? 'currentX' : 'currentY'],\n            time: (new window.Date()).getTime()\n        });\n    }\n    // Update progress\n    s.updateProgress(currentTranslate);\n    // Update translate\n    s.setWrapperTranslate(currentTranslate);\n};\ns.onTouchEnd = function (e) {\n    if (e.originalEvent) e = e.originalEvent;\n    if (allowTouchCallbacks) {\n        s.emit('onTouchEnd', s, e);\n    }\n    allowTouchCallbacks = false;\n    if (!isTouched) return;\n    //Return Grab Cursor\n    if (s.params.grabCursor && isMoved && isTouched) {\n        s.container[0].style.cursor = 'move';\n        s.container[0].style.cursor = '-webkit-grab';\n        s.container[0].style.cursor = '-moz-grab';\n        s.container[0].style.cursor = 'grab';\n    }\n\n    // Time diff\n    var touchEndTime = Date.now();\n    var timeDiff = touchEndTime - touchStartTime;\n\n    // Tap, doubleTap, Click\n    if (s.allowClick) {\n        s.updateClickedSlide(e);\n        s.emit('onTap', s, e);\n        if (timeDiff < 300 && (touchEndTime - lastClickTime) > 300) {\n            if (clickTimeout) clearTimeout(clickTimeout);\n            clickTimeout = setTimeout(function () {\n                if (!s) return;\n                if (s.params.paginationHide && s.paginationContainer.length > 0 && !$(e.target).hasClass(s.params.bulletClass)) {\n                    s.paginationContainer.toggleClass(s.params.paginationHiddenClass);\n                }\n                s.emit('onClick', s, e);\n            }, 300);\n\n        }\n        if (timeDiff < 300 && (touchEndTime - lastClickTime) < 300) {\n            if (clickTimeout) clearTimeout(clickTimeout);\n            s.emit('onDoubleTap', s, e);\n        }\n    }\n\n    lastClickTime = Date.now();\n    setTimeout(function () {\n        if (s) s.allowClick = true;\n    }, 0);\n\n    if (!isTouched || !isMoved || !s.swipeDirection || s.touches.diff === 0 || currentTranslate === startTranslate) {\n        isTouched = isMoved = false;\n        return;\n    }\n    isTouched = isMoved = false;\n\n    var currentPos;\n    if (s.params.followFinger) {\n        currentPos = s.rtl ? s.translate : -s.translate;\n    }\n    else {\n        currentPos = -currentTranslate;\n    }\n    if (s.params.freeMode) {\n        if (currentPos < -s.minTranslate()) {\n            s.slideTo(s.activeIndex);\n            return;\n        }\n        else if (currentPos > -s.maxTranslate()) {\n            if (s.slides.length < s.snapGrid.length) {\n                s.slideTo(s.snapGrid.length - 1);\n            }\n            else {\n                s.slideTo(s.slides.length - 1);\n            }\n            return;\n        }\n\n        if (s.params.freeModeMomentum) {\n            if (velocities.length > 1) {\n                var lastMoveEvent = velocities.pop(), velocityEvent = velocities.pop();\n\n                var distance = lastMoveEvent.position - velocityEvent.position;\n                var time = lastMoveEvent.time - velocityEvent.time;\n                s.velocity = distance / time;\n                s.velocity = s.velocity / 2;\n                if (Math.abs(s.velocity) < s.params.freeModeMinimumVelocity) {\n                    s.velocity = 0;\n                }\n                // this implies that the user stopped moving a finger then released.\n                // There would be no events with distance zero, so the last event is stale.\n                if (time > 150 || (new window.Date().getTime() - lastMoveEvent.time) > 300) {\n                    s.velocity = 0;\n                }\n            } else {\n                s.velocity = 0;\n            }\n\n            velocities.length = 0;\n            var momentumDuration = 1000 * s.params.freeModeMomentumRatio;\n            var momentumDistance = s.velocity * momentumDuration;\n\n            var newPosition = s.translate + momentumDistance;\n            if (s.rtl) newPosition = - newPosition;\n            var doBounce = false;\n            var afterBouncePosition;\n            var bounceAmount = Math.abs(s.velocity) * 20 * s.params.freeModeMomentumBounceRatio;\n            if (newPosition < s.maxTranslate()) {\n                if (s.params.freeModeMomentumBounce) {\n                    if (newPosition + s.maxTranslate() < -bounceAmount) {\n                        newPosition = s.maxTranslate() - bounceAmount;\n                    }\n                    afterBouncePosition = s.maxTranslate();\n                    doBounce = true;\n                    allowMomentumBounce = true;\n                }\n                else {\n                    newPosition = s.maxTranslate();\n                }\n            }\n            else if (newPosition > s.minTranslate()) {\n                if (s.params.freeModeMomentumBounce) {\n                    if (newPosition - s.minTranslate() > bounceAmount) {\n                        newPosition = s.minTranslate() + bounceAmount;\n                    }\n                    afterBouncePosition = s.minTranslate();\n                    doBounce = true;\n                    allowMomentumBounce = true;\n                }\n                else {\n                    newPosition = s.minTranslate();\n                }\n            }\n            else if (s.params.freeModeSticky) {\n                var j = 0,\n                    nextSlide;\n                for (j = 0; j < s.snapGrid.length; j += 1) {\n                    if (s.snapGrid[j] > -newPosition) {\n                        nextSlide = j;\n                        break;\n                    }\n\n                }\n                if (Math.abs(s.snapGrid[nextSlide] - newPosition) < Math.abs(s.snapGrid[nextSlide - 1] - newPosition) || s.swipeDirection === 'next') {\n                    newPosition = s.snapGrid[nextSlide];\n                } else {\n                    newPosition = s.snapGrid[nextSlide - 1];\n                }\n                if (!s.rtl) newPosition = - newPosition;\n            }\n            //Fix duration\n            if (s.velocity !== 0) {\n                if (s.rtl) {\n                    momentumDuration = Math.abs((-newPosition - s.translate) / s.velocity);\n                }\n                else {\n                    momentumDuration = Math.abs((newPosition - s.translate) / s.velocity);\n                }\n            }\n            else if (s.params.freeModeSticky) {\n                s.slideReset();\n                return;\n            }\n\n            if (s.params.freeModeMomentumBounce && doBounce) {\n                s.updateProgress(afterBouncePosition);\n                s.setWrapperTransition(momentumDuration);\n                s.setWrapperTranslate(newPosition);\n                s.onTransitionStart();\n                s.animating = true;\n                s.wrapper.transitionEnd(function () {\n                    if (!s || !allowMomentumBounce) return;\n                    s.emit('onMomentumBounce', s);\n\n                    s.setWrapperTransition(s.params.speed);\n                    s.setWrapperTranslate(afterBouncePosition);\n                    s.wrapper.transitionEnd(function () {\n                        if (!s) return;\n                        s.onTransitionEnd();\n                    });\n                });\n            } else if (s.velocity) {\n                s.updateProgress(newPosition);\n                s.setWrapperTransition(momentumDuration);\n                s.setWrapperTranslate(newPosition);\n                s.onTransitionStart();\n                if (!s.animating) {\n                    s.animating = true;\n                    s.wrapper.transitionEnd(function () {\n                        if (!s) return;\n                        s.onTransitionEnd();\n                    });\n                }\n\n            } else {\n                s.updateProgress(newPosition);\n            }\n\n            s.updateActiveIndex();\n        }\n        if (!s.params.freeModeMomentum || timeDiff >= s.params.longSwipesMs) {\n            s.updateProgress();\n            s.updateActiveIndex();\n        }\n        return;\n    }\n\n    // Find current slide\n    var i, stopIndex = 0, groupSize = s.slidesSizesGrid[0];\n    for (i = 0; i < s.slidesGrid.length; i += s.params.slidesPerGroup) {\n        if (typeof s.slidesGrid[i + s.params.slidesPerGroup] !== 'undefined') {\n            if (currentPos >= s.slidesGrid[i] && currentPos < s.slidesGrid[i + s.params.slidesPerGroup]) {\n                stopIndex = i;\n                groupSize = s.slidesGrid[i + s.params.slidesPerGroup] - s.slidesGrid[i];\n            }\n        }\n        else {\n            if (currentPos >= s.slidesGrid[i]) {\n                stopIndex = i;\n                groupSize = s.slidesGrid[s.slidesGrid.length - 1] - s.slidesGrid[s.slidesGrid.length - 2];\n            }\n        }\n    }\n\n    // Find current slide size\n    var ratio = (currentPos - s.slidesGrid[stopIndex]) / groupSize;\n\n    if (timeDiff > s.params.longSwipesMs) {\n        // Long touches\n        if (!s.params.longSwipes) {\n            s.slideTo(s.activeIndex);\n            return;\n        }\n        if (s.swipeDirection === 'next') {\n            if (ratio >= s.params.longSwipesRatio) s.slideTo(stopIndex + s.params.slidesPerGroup);\n            else s.slideTo(stopIndex);\n\n        }\n        if (s.swipeDirection === 'prev') {\n            if (ratio > (1 - s.params.longSwipesRatio)) s.slideTo(stopIndex + s.params.slidesPerGroup);\n            else s.slideTo(stopIndex);\n        }\n    }\n    else {\n        // Short swipes\n        if (!s.params.shortSwipes) {\n            s.slideTo(s.activeIndex);\n            return;\n        }\n        if (s.swipeDirection === 'next') {\n            s.slideTo(stopIndex + s.params.slidesPerGroup);\n\n        }\n        if (s.swipeDirection === 'prev') {\n            s.slideTo(stopIndex);\n        }\n    }\n};\n/*=========================\n  Transitions\n  ===========================*/\ns._slideTo = function (slideIndex, speed) {\n    return s.slideTo(slideIndex, speed, true, true);\n};\ns.slideTo = function (slideIndex, speed, runCallbacks, internal) {\n    if (typeof runCallbacks === 'undefined') runCallbacks = true;\n    if (typeof slideIndex === 'undefined') slideIndex = 0;\n    if (slideIndex < 0) slideIndex = 0;\n    s.snapIndex = Math.floor(slideIndex / s.params.slidesPerGroup);\n    if (s.snapIndex >= s.snapGrid.length) s.snapIndex = s.snapGrid.length - 1;\n\n    var translate = - s.snapGrid[s.snapIndex];\n    // Stop autoplay\n    if (s.params.autoplay && s.autoplaying) {\n        if (internal || !s.params.autoplayDisableOnInteraction) {\n            s.pauseAutoplay(speed);\n        }\n        else {\n            s.stopAutoplay();\n        }\n    }\n    // Update progress\n    s.updateProgress(translate);\n\n    // Normalize slideIndex\n    for (var i = 0; i < s.slidesGrid.length; i++) {\n        if (- Math.floor(translate * 100) >= Math.floor(s.slidesGrid[i] * 100)) {\n            slideIndex = i;\n        }\n    }\n\n    // Directions locks\n    if (!s.params.allowSwipeToNext && translate < s.translate && translate < s.minTranslate()) {\n        return false;\n    }\n    if (!s.params.allowSwipeToPrev && translate > s.translate && translate > s.maxTranslate()) {\n        if ((s.activeIndex || 0) !== slideIndex ) return false;\n    }\n\n    // Update Index\n    if (typeof speed === 'undefined') speed = s.params.speed;\n    s.previousIndex = s.activeIndex || 0;\n    s.activeIndex = slideIndex;\n\n    if ((s.rtl && -translate === s.translate) || (!s.rtl && translate === s.translate)) {\n        // Update Height\n        if (s.params.autoHeight) {\n            s.updateAutoHeight();\n        }\n        s.updateClasses();\n        if (s.params.effect !== 'slide') {\n            s.setWrapperTranslate(translate);\n        }\n        return false;\n    }\n    s.updateClasses();\n    s.onTransitionStart(runCallbacks);\n\n    if (speed === 0) {\n        s.setWrapperTranslate(translate);\n        s.setWrapperTransition(0);\n        s.onTransitionEnd(runCallbacks);\n    }\n    else {\n        s.setWrapperTranslate(translate);\n        s.setWrapperTransition(speed);\n        if (!s.animating) {\n            s.animating = true;\n            s.wrapper.transitionEnd(function () {\n                if (!s) return;\n                s.onTransitionEnd(runCallbacks);\n            });\n        }\n\n    }\n\n    return true;\n};\n\ns.onTransitionStart = function (runCallbacks) {\n    if (typeof runCallbacks === 'undefined') runCallbacks = true;\n    if (s.params.autoHeight) {\n        s.updateAutoHeight();\n    }\n    if (s.lazy) s.lazy.onTransitionStart();\n    if (runCallbacks) {\n        s.emit('onTransitionStart', s);\n        if (s.activeIndex !== s.previousIndex) {\n            s.emit('onSlideChangeStart', s);\n            if (s.activeIndex > s.previousIndex) {\n                s.emit('onSlideNextStart', s);\n            }\n            else {\n                s.emit('onSlidePrevStart', s);\n            }\n        }\n\n    }\n};\ns.onTransitionEnd = function (runCallbacks) {\n    s.animating = false;\n    s.setWrapperTransition(0);\n    if (typeof runCallbacks === 'undefined') runCallbacks = true;\n    if (s.lazy) s.lazy.onTransitionEnd();\n    if (runCallbacks) {\n        s.emit('onTransitionEnd', s);\n        if (s.activeIndex !== s.previousIndex) {\n            s.emit('onSlideChangeEnd', s);\n            if (s.activeIndex > s.previousIndex) {\n                s.emit('onSlideNextEnd', s);\n            }\n            else {\n                s.emit('onSlidePrevEnd', s);\n            }\n        }\n    }\n    if (s.params.hashnav && s.hashnav) {\n        s.hashnav.setHash();\n    }\n\n};\ns.slideNext = function (runCallbacks, speed, internal) {\n    if (s.params.loop) {\n        if (s.animating) return false;\n        s.fixLoop();\n        var clientLeft = s.container[0].clientLeft;\n        return s.slideTo(s.activeIndex + s.params.slidesPerGroup, speed, runCallbacks, internal);\n    }\n    else return s.slideTo(s.activeIndex + s.params.slidesPerGroup, speed, runCallbacks, internal);\n};\ns._slideNext = function (speed) {\n    return s.slideNext(true, speed, true);\n};\ns.slidePrev = function (runCallbacks, speed, internal) {\n    if (s.params.loop) {\n        if (s.animating) return false;\n        s.fixLoop();\n        var clientLeft = s.container[0].clientLeft;\n        return s.slideTo(s.activeIndex - 1, speed, runCallbacks, internal);\n    }\n    else return s.slideTo(s.activeIndex - 1, speed, runCallbacks, internal);\n};\ns._slidePrev = function (speed) {\n    return s.slidePrev(true, speed, true);\n};\ns.slideReset = function (runCallbacks, speed, internal) {\n    return s.slideTo(s.activeIndex, speed, runCallbacks);\n};\n\n/*=========================\n  Translate/transition helpers\n  ===========================*/\ns.setWrapperTransition = function (duration, byController) {\n    s.wrapper.transition(duration);\n    if (s.params.effect !== 'slide' && s.effects[s.params.effect]) {\n        s.effects[s.params.effect].setTransition(duration);\n    }\n    if (s.params.parallax && s.parallax) {\n        s.parallax.setTransition(duration);\n    }\n    if (s.params.scrollbar && s.scrollbar) {\n        s.scrollbar.setTransition(duration);\n    }\n    if (s.params.control && s.controller) {\n        s.controller.setTransition(duration, byController);\n    }\n    s.emit('onSetTransition', s, duration);\n};\ns.setWrapperTranslate = function (translate, updateActiveIndex, byController) {\n    var x = 0, y = 0, z = 0;\n    if (s.isHorizontal()) {\n        x = s.rtl ? -translate : translate;\n    }\n    else {\n        y = translate;\n    }\n\n    if (s.params.roundLengths) {\n        x = round(x);\n        y = round(y);\n    }\n\n    if (!s.params.virtualTranslate) {\n        if (s.support.transforms3d) s.wrapper.transform('translate3d(' + x + 'px, ' + y + 'px, ' + z + 'px)');\n        else s.wrapper.transform('translate(' + x + 'px, ' + y + 'px)');\n    }\n\n    s.translate = s.isHorizontal() ? x : y;\n\n    // Check if we need to update progress\n    var progress;\n    var translatesDiff = s.maxTranslate() - s.minTranslate();\n    if (translatesDiff === 0) {\n        progress = 0;\n    }\n    else {\n        progress = (translate - s.minTranslate()) / (translatesDiff);\n    }\n    if (progress !== s.progress) {\n        s.updateProgress(translate);\n    }\n\n    if (updateActiveIndex) s.updateActiveIndex();\n    if (s.params.effect !== 'slide' && s.effects[s.params.effect]) {\n        s.effects[s.params.effect].setTranslate(s.translate);\n    }\n    if (s.params.parallax && s.parallax) {\n        s.parallax.setTranslate(s.translate);\n    }\n    if (s.params.scrollbar && s.scrollbar) {\n        s.scrollbar.setTranslate(s.translate);\n    }\n    if (s.params.control && s.controller) {\n        s.controller.setTranslate(s.translate, byController);\n    }\n    s.emit('onSetTranslate', s, s.translate);\n};\n\ns.getTranslate = function (el, axis) {\n    var matrix, curTransform, curStyle, transformMatrix;\n\n    // automatic axis detection\n    if (typeof axis === 'undefined') {\n        axis = 'x';\n    }\n\n    if (s.params.virtualTranslate) {\n        return s.rtl ? -s.translate : s.translate;\n    }\n\n    curStyle = window.getComputedStyle(el, null);\n    if (window.WebKitCSSMatrix) {\n        curTransform = curStyle.transform || curStyle.webkitTransform;\n        if (curTransform.split(',').length > 6) {\n            curTransform = curTransform.split(', ').map(function(a){\n                return a.replace(',','.');\n            }).join(', ');\n        }\n        // Some old versions of Webkit choke when 'none' is passed; pass\n        // empty string instead in this case\n        transformMatrix = new window.WebKitCSSMatrix(curTransform === 'none' ? '' : curTransform);\n    }\n    else {\n        transformMatrix = curStyle.MozTransform || curStyle.OTransform || curStyle.MsTransform || curStyle.msTransform  || curStyle.transform || curStyle.getPropertyValue('transform').replace('translate(', 'matrix(1, 0, 0, 1,');\n        matrix = transformMatrix.toString().split(',');\n    }\n\n    if (axis === 'x') {\n        //Latest Chrome and webkits Fix\n        if (window.WebKitCSSMatrix)\n            curTransform = transformMatrix.m41;\n        //Crazy IE10 Matrix\n        else if (matrix.length === 16)\n            curTransform = parseFloat(matrix[12]);\n        //Normal Browsers\n        else\n            curTransform = parseFloat(matrix[4]);\n    }\n    if (axis === 'y') {\n        //Latest Chrome and webkits Fix\n        if (window.WebKitCSSMatrix)\n            curTransform = transformMatrix.m42;\n        //Crazy IE10 Matrix\n        else if (matrix.length === 16)\n            curTransform = parseFloat(matrix[13]);\n        //Normal Browsers\n        else\n            curTransform = parseFloat(matrix[5]);\n    }\n    if (s.rtl && curTransform) curTransform = -curTransform;\n    return curTransform || 0;\n};\ns.getWrapperTranslate = function (axis) {\n    if (typeof axis === 'undefined') {\n        axis = s.isHorizontal() ? 'x' : 'y';\n    }\n    return s.getTranslate(s.wrapper[0], axis);\n};\n\n/*=========================\n  Observer\n  ===========================*/\ns.observers = [];\nfunction initObserver(target, options) {\n    options = options || {};\n    // create an observer instance\n    var ObserverFunc = window.MutationObserver || window.WebkitMutationObserver;\n    var observer = new ObserverFunc(function (mutations) {\n        mutations.forEach(function (mutation) {\n            s.onResize(true);\n            s.emit('onObserverUpdate', s, mutation);\n        });\n    });\n\n    observer.observe(target, {\n        attributes: typeof options.attributes === 'undefined' ? true : options.attributes,\n        childList: typeof options.childList === 'undefined' ? true : options.childList,\n        characterData: typeof options.characterData === 'undefined' ? true : options.characterData\n    });\n\n    s.observers.push(observer);\n}\ns.initObservers = function () {\n    if (s.params.observeParents) {\n        var containerParents = s.container.parents();\n        for (var i = 0; i < containerParents.length; i++) {\n            initObserver(containerParents[i]);\n        }\n    }\n\n    // Observe container\n    initObserver(s.container[0], {childList: false});\n\n    // Observe wrapper\n    initObserver(s.wrapper[0], {attributes: false});\n};\ns.disconnectObservers = function () {\n    for (var i = 0; i < s.observers.length; i++) {\n        s.observers[i].disconnect();\n    }\n    s.observers = [];\n};\n/*=========================\n  Loop\n  ===========================*/\n// Create looped slides\ns.createLoop = function () {\n    // Remove duplicated slides\n    s.wrapper.children('.' + s.params.slideClass + '.' + s.params.slideDuplicateClass).remove();\n\n    var slides = s.wrapper.children('.' + s.params.slideClass);\n\n    if(s.params.slidesPerView === 'auto' && !s.params.loopedSlides) s.params.loopedSlides = slides.length;\n\n    s.loopedSlides = parseInt(s.params.loopedSlides || s.params.slidesPerView, 10);\n    s.loopedSlides = s.loopedSlides + s.params.loopAdditionalSlides;\n    if (s.loopedSlides > slides.length) {\n        s.loopedSlides = slides.length;\n    }\n\n    var prependSlides = [], appendSlides = [], i;\n    slides.each(function (index, el) {\n        var slide = $(this);\n        if (index < s.loopedSlides) appendSlides.push(el);\n        if (index < slides.length && index >= slides.length - s.loopedSlides) prependSlides.push(el);\n        slide.attr('data-swiper-slide-index', index);\n    });\n    for (i = 0; i < appendSlides.length; i++) {\n        s.wrapper.append($(appendSlides[i].cloneNode(true)).addClass(s.params.slideDuplicateClass));\n    }\n    for (i = prependSlides.length - 1; i >= 0; i--) {\n        s.wrapper.prepend($(prependSlides[i].cloneNode(true)).addClass(s.params.slideDuplicateClass));\n    }\n};\ns.destroyLoop = function () {\n    s.wrapper.children('.' + s.params.slideClass + '.' + s.params.slideDuplicateClass).remove();\n    s.slides.removeAttr('data-swiper-slide-index');\n};\ns.reLoop = function (updatePosition) {\n    var oldIndex = s.activeIndex - s.loopedSlides;\n    s.destroyLoop();\n    s.createLoop();\n    s.updateSlidesSize();\n    if (updatePosition) {\n        s.slideTo(oldIndex + s.loopedSlides, 0, false);\n    }\n\n};\ns.fixLoop = function () {\n    var newIndex;\n    //Fix For Negative Oversliding\n    if (s.activeIndex < s.loopedSlides) {\n        newIndex = s.slides.length - s.loopedSlides * 3 + s.activeIndex;\n        newIndex = newIndex + s.loopedSlides;\n        s.slideTo(newIndex, 0, false, true);\n    }\n    //Fix For Positive Oversliding\n    else if ((s.params.slidesPerView === 'auto' && s.activeIndex >= s.loopedSlides * 2) || (s.activeIndex > s.slides.length - s.params.slidesPerView * 2)) {\n        newIndex = -s.slides.length + s.activeIndex + s.loopedSlides;\n        newIndex = newIndex + s.loopedSlides;\n        s.slideTo(newIndex, 0, false, true);\n    }\n};\n/*=========================\n  Append/Prepend/Remove Slides\n  ===========================*/\ns.appendSlide = function (slides) {\n    if (s.params.loop) {\n        s.destroyLoop();\n    }\n    if (typeof slides === 'object' && slides.length) {\n        for (var i = 0; i < slides.length; i++) {\n            if (slides[i]) s.wrapper.append(slides[i]);\n        }\n    }\n    else {\n        s.wrapper.append(slides);\n    }\n    if (s.params.loop) {\n        s.createLoop();\n    }\n    if (!(s.params.observer && s.support.observer)) {\n        s.update(true);\n    }\n};\ns.prependSlide = function (slides) {\n    if (s.params.loop) {\n        s.destroyLoop();\n    }\n    var newActiveIndex = s.activeIndex + 1;\n    if (typeof slides === 'object' && slides.length) {\n        for (var i = 0; i < slides.length; i++) {\n            if (slides[i]) s.wrapper.prepend(slides[i]);\n        }\n        newActiveIndex = s.activeIndex + slides.length;\n    }\n    else {\n        s.wrapper.prepend(slides);\n    }\n    if (s.params.loop) {\n        s.createLoop();\n    }\n    if (!(s.params.observer && s.support.observer)) {\n        s.update(true);\n    }\n    s.slideTo(newActiveIndex, 0, false);\n};\ns.removeSlide = function (slidesIndexes) {\n    if (s.params.loop) {\n        s.destroyLoop();\n        s.slides = s.wrapper.children('.' + s.params.slideClass);\n    }\n    var newActiveIndex = s.activeIndex,\n        indexToRemove;\n    if (typeof slidesIndexes === 'object' && slidesIndexes.length) {\n        for (var i = 0; i < slidesIndexes.length; i++) {\n            indexToRemove = slidesIndexes[i];\n            if (s.slides[indexToRemove]) s.slides.eq(indexToRemove).remove();\n            if (indexToRemove < newActiveIndex) newActiveIndex--;\n        }\n        newActiveIndex = Math.max(newActiveIndex, 0);\n    }\n    else {\n        indexToRemove = slidesIndexes;\n        if (s.slides[indexToRemove]) s.slides.eq(indexToRemove).remove();\n        if (indexToRemove < newActiveIndex) newActiveIndex--;\n        newActiveIndex = Math.max(newActiveIndex, 0);\n    }\n\n    if (s.params.loop) {\n        s.createLoop();\n    }\n\n    if (!(s.params.observer && s.support.observer)) {\n        s.update(true);\n    }\n    if (s.params.loop) {\n        s.slideTo(newActiveIndex + s.loopedSlides, 0, false);\n    }\n    else {\n        s.slideTo(newActiveIndex, 0, false);\n    }\n\n};\ns.removeAllSlides = function () {\n    var slidesIndexes = [];\n    for (var i = 0; i < s.slides.length; i++) {\n        slidesIndexes.push(i);\n    }\n    s.removeSlide(slidesIndexes);\n};\n"
  },
  {
    "path": "app_backend/static/plugin/Swiper-3.3.1/src/js/dom-plugins.js",
    "content": "/*===========================\nAdd .swiper plugin from Dom libraries\n===========================*/\nfunction addLibraryPlugin(lib) {\n    lib.fn.swiper = function (params) {\n        var firstInstance;\n        lib(this).each(function () {\n            var s = new Swiper(this, params);\n            if (!firstInstance) firstInstance = s;\n        });\n        return firstInstance;\n    };\n}\n\nif (domLib) {\n    if (!('transitionEnd' in domLib.fn)) {\n        domLib.fn.transitionEnd = function (callback) {\n            var events = ['webkitTransitionEnd', 'transitionend', 'oTransitionEnd', 'MSTransitionEnd', 'msTransitionEnd'],\n                i, j, dom = this;\n            function fireCallBack(e) {\n                /*jshint validthis:true */\n                if (e.target !== this) return;\n                callback.call(this, e);\n                for (i = 0; i < events.length; i++) {\n                    dom.off(events[i], fireCallBack);\n                }\n            }\n            if (callback) {\n                for (i = 0; i < events.length; i++) {\n                    dom.on(events[i], fireCallBack);\n                }\n            }\n            return this;\n        };\n    }\n    if (!('transform' in domLib.fn)) {\n        domLib.fn.transform = function (transform) {\n            for (var i = 0; i < this.length; i++) {\n                var elStyle = this[i].style;\n                elStyle.webkitTransform = elStyle.MsTransform = elStyle.msTransform = elStyle.MozTransform = elStyle.OTransform = elStyle.transform = transform;\n            }\n            return this;\n        };\n    }\n    if (!('transition' in domLib.fn)) {\n        domLib.fn.transition = function (duration) {\n            if (typeof duration !== 'string') {\n                duration = duration + 'ms';\n            }\n            for (var i = 0; i < this.length; i++) {\n                var elStyle = this[i].style;\n                elStyle.webkitTransitionDuration = elStyle.MsTransitionDuration = elStyle.msTransitionDuration = elStyle.MozTransitionDuration = elStyle.OTransitionDuration = elStyle.transitionDuration = duration;\n            }\n            return this;\n        };\n    }\n}"
  },
  {
    "path": "app_backend/static/plugin/Swiper-3.3.1/src/js/dom.js",
    "content": "/*===========================\nDom7 Library\n===========================*/\nvar Dom7 = (function () {\n    var Dom7 = function (arr) {\n        var _this = this, i = 0;\n        // Create array-like object\n        for (i = 0; i < arr.length; i++) {\n            _this[i] = arr[i];\n        }\n        _this.length = arr.length;\n        // Return collection with methods\n        return this;\n    };\n    var $ = function (selector, context) {\n        var arr = [], i = 0;\n        if (selector && !context) {\n            if (selector instanceof Dom7) {\n                return selector;\n            }\n        }\n        if (selector) {\n            // String\n            if (typeof selector === 'string') {\n                var els, tempParent, html = selector.trim();\n                if (html.indexOf('<') >= 0 && html.indexOf('>') >= 0) {\n                    var toCreate = 'div';\n                    if (html.indexOf('<li') === 0) toCreate = 'ul';\n                    if (html.indexOf('<tr') === 0) toCreate = 'tbody';\n                    if (html.indexOf('<td') === 0 || html.indexOf('<th') === 0) toCreate = 'tr';\n                    if (html.indexOf('<tbody') === 0) toCreate = 'table';\n                    if (html.indexOf('<option') === 0) toCreate = 'select';\n                    tempParent = document.createElement(toCreate);\n                    tempParent.innerHTML = selector;\n                    for (i = 0; i < tempParent.childNodes.length; i++) {\n                        arr.push(tempParent.childNodes[i]);\n                    }\n                }\n                else {\n                    if (!context && selector[0] === '#' && !selector.match(/[ .<>:~]/)) {\n                        // Pure ID selector\n                        els = [document.getElementById(selector.split('#')[1])];\n                    }\n                    else {\n                        // Other selectors\n                        els = (context || document).querySelectorAll(selector);\n                    }\n                    for (i = 0; i < els.length; i++) {\n                        if (els[i]) arr.push(els[i]);\n                    }\n                }\n            }\n            // Node/element\n            else if (selector.nodeType || selector === window || selector === document) {\n                arr.push(selector);\n            }\n            //Array of elements or instance of Dom\n            else if (selector.length > 0 && selector[0].nodeType) {\n                for (i = 0; i < selector.length; i++) {\n                    arr.push(selector[i]);\n                }\n            }\n        }\n        return new Dom7(arr);\n    };\n    Dom7.prototype = {\n        // Classes and attriutes\n        addClass: function (className) {\n            if (typeof className === 'undefined') {\n                return this;\n            }\n            var classes = className.split(' ');\n            for (var i = 0; i < classes.length; i++) {\n                for (var j = 0; j < this.length; j++) {\n                    this[j].classList.add(classes[i]);\n                }\n            }\n            return this;\n        },\n        removeClass: function (className) {\n            var classes = className.split(' ');\n            for (var i = 0; i < classes.length; i++) {\n                for (var j = 0; j < this.length; j++) {\n                    this[j].classList.remove(classes[i]);\n                }\n            }\n            return this;\n        },\n        hasClass: function (className) {\n            if (!this[0]) return false;\n            else return this[0].classList.contains(className);\n        },\n        toggleClass: function (className) {\n            var classes = className.split(' ');\n            for (var i = 0; i < classes.length; i++) {\n                for (var j = 0; j < this.length; j++) {\n                    this[j].classList.toggle(classes[i]);\n                }\n            }\n            return this;\n        },\n        attr: function (attrs, value) {\n            if (arguments.length === 1 && typeof attrs === 'string') {\n                // Get attr\n                if (this[0]) return this[0].getAttribute(attrs);\n                else return undefined;\n            }\n            else {\n                // Set attrs\n                for (var i = 0; i < this.length; i++) {\n                    if (arguments.length === 2) {\n                        // String\n                        this[i].setAttribute(attrs, value);\n                    }\n                    else {\n                        // Object\n                        for (var attrName in attrs) {\n                            this[i][attrName] = attrs[attrName];\n                            this[i].setAttribute(attrName, attrs[attrName]);\n                        }\n                    }\n                }\n                return this;\n            }\n        },\n        removeAttr: function (attr) {\n            for (var i = 0; i < this.length; i++) {\n                this[i].removeAttribute(attr);\n            }\n            return this;\n        },\n        data: function (key, value) {\n            if (typeof value === 'undefined') {\n                // Get value\n                if (this[0]) {\n                    var dataKey = this[0].getAttribute('data-' + key);\n                    if (dataKey) return dataKey;\n                    else if (this[0].dom7ElementDataStorage && (key in this[0].dom7ElementDataStorage)) return this[0].dom7ElementDataStorage[key];\n                    else return undefined;\n                }\n                else return undefined;\n            }\n            else {\n                // Set value\n                for (var i = 0; i < this.length; i++) {\n                    var el = this[i];\n                    if (!el.dom7ElementDataStorage) el.dom7ElementDataStorage = {};\n                    el.dom7ElementDataStorage[key] = value;\n                }\n                return this;\n            }\n        },\n        // Transforms\n        transform : function (transform) {\n            for (var i = 0; i < this.length; i++) {\n                var elStyle = this[i].style;\n                elStyle.webkitTransform = elStyle.MsTransform = elStyle.msTransform = elStyle.MozTransform = elStyle.OTransform = elStyle.transform = transform;\n            }\n            return this;\n        },\n        transition: function (duration) {\n            if (typeof duration !== 'string') {\n                duration = duration + 'ms';\n            }\n            for (var i = 0; i < this.length; i++) {\n                var elStyle = this[i].style;\n                elStyle.webkitTransitionDuration = elStyle.MsTransitionDuration = elStyle.msTransitionDuration = elStyle.MozTransitionDuration = elStyle.OTransitionDuration = elStyle.transitionDuration = duration;\n            }\n            return this;\n        },\n        //Events\n        on: function (eventName, targetSelector, listener, capture) {\n            function handleLiveEvent(e) {\n                var target = e.target;\n                if ($(target).is(targetSelector)) listener.call(target, e);\n                else {\n                    var parents = $(target).parents();\n                    for (var k = 0; k < parents.length; k++) {\n                        if ($(parents[k]).is(targetSelector)) listener.call(parents[k], e);\n                    }\n                }\n            }\n            var events = eventName.split(' ');\n            var i, j;\n            for (i = 0; i < this.length; i++) {\n                if (typeof targetSelector === 'function' || targetSelector === false) {\n                    // Usual events\n                    if (typeof targetSelector === 'function') {\n                        listener = arguments[1];\n                        capture = arguments[2] || false;\n                    }\n                    for (j = 0; j < events.length; j++) {\n                        this[i].addEventListener(events[j], listener, capture);\n                    }\n                }\n                else {\n                    //Live events\n                    for (j = 0; j < events.length; j++) {\n                        if (!this[i].dom7LiveListeners) this[i].dom7LiveListeners = [];\n                        this[i].dom7LiveListeners.push({listener: listener, liveListener: handleLiveEvent});\n                        this[i].addEventListener(events[j], handleLiveEvent, capture);\n                    }\n                }\n            }\n\n            return this;\n        },\n        off: function (eventName, targetSelector, listener, capture) {\n            var events = eventName.split(' ');\n            for (var i = 0; i < events.length; i++) {\n                for (var j = 0; j < this.length; j++) {\n                    if (typeof targetSelector === 'function' || targetSelector === false) {\n                        // Usual events\n                        if (typeof targetSelector === 'function') {\n                            listener = arguments[1];\n                            capture = arguments[2] || false;\n                        }\n                        this[j].removeEventListener(events[i], listener, capture);\n                    }\n                    else {\n                        // Live event\n                        if (this[j].dom7LiveListeners) {\n                            for (var k = 0; k < this[j].dom7LiveListeners.length; k++) {\n                                if (this[j].dom7LiveListeners[k].listener === listener) {\n                                    this[j].removeEventListener(events[i], this[j].dom7LiveListeners[k].liveListener, capture);\n                                }\n                            }\n                        }\n                    }\n                }\n            }\n            return this;\n        },\n        once: function (eventName, targetSelector, listener, capture) {\n            var dom = this;\n            if (typeof targetSelector === 'function') {\n                targetSelector = false;\n                listener = arguments[1];\n                capture = arguments[2];\n            }\n            function proxy(e) {\n                listener(e);\n                dom.off(eventName, targetSelector, proxy, capture);\n            }\n            dom.on(eventName, targetSelector, proxy, capture);\n        },\n        trigger: function (eventName, eventData) {\n            for (var i = 0; i < this.length; i++) {\n                var evt;\n                try {\n                    evt = new window.CustomEvent(eventName, {detail: eventData, bubbles: true, cancelable: true});\n                }\n                catch (e) {\n                    evt = document.createEvent('Event');\n                    evt.initEvent(eventName, true, true);\n                    evt.detail = eventData;\n                }\n                this[i].dispatchEvent(evt);\n            }\n            return this;\n        },\n        transitionEnd: function (callback) {\n            var events = ['webkitTransitionEnd', 'transitionend', 'oTransitionEnd', 'MSTransitionEnd', 'msTransitionEnd'],\n                i, j, dom = this;\n            function fireCallBack(e) {\n                /*jshint validthis:true */\n                if (e.target !== this) return;\n                callback.call(this, e);\n                for (i = 0; i < events.length; i++) {\n                    dom.off(events[i], fireCallBack);\n                }\n            }\n            if (callback) {\n                for (i = 0; i < events.length; i++) {\n                    dom.on(events[i], fireCallBack);\n                }\n            }\n            return this;\n        },\n        // Sizing/Styles\n        width: function () {\n            if (this[0] === window) {\n                return window.innerWidth;\n            }\n            else {\n                if (this.length > 0) {\n                    return parseFloat(this.css('width'));\n                }\n                else {\n                    return null;\n                }\n            }\n        },\n        outerWidth: function (includeMargins) {\n            if (this.length > 0) {\n                if (includeMargins)\n                    return this[0].offsetWidth + parseFloat(this.css('margin-right')) + parseFloat(this.css('margin-left'));\n                else\n                    return this[0].offsetWidth;\n            }\n            else return null;\n        },\n        height: function () {\n            if (this[0] === window) {\n                return window.innerHeight;\n            }\n            else {\n                if (this.length > 0) {\n                    return parseFloat(this.css('height'));\n                }\n                else {\n                    return null;\n                }\n            }\n        },\n        outerHeight: function (includeMargins) {\n            if (this.length > 0) {\n                if (includeMargins)\n                    return this[0].offsetHeight + parseFloat(this.css('margin-top')) + parseFloat(this.css('margin-bottom'));\n                else\n                    return this[0].offsetHeight;\n            }\n            else return null;\n        },\n        offset: function () {\n            if (this.length > 0) {\n                var el = this[0];\n                var box = el.getBoundingClientRect();\n                var body = document.body;\n                var clientTop  = el.clientTop  || body.clientTop  || 0;\n                var clientLeft = el.clientLeft || body.clientLeft || 0;\n                var scrollTop  = window.pageYOffset || el.scrollTop;\n                var scrollLeft = window.pageXOffset || el.scrollLeft;\n                return {\n                    top: box.top  + scrollTop  - clientTop,\n                    left: box.left + scrollLeft - clientLeft\n                };\n            }\n            else {\n                return null;\n            }\n        },\n        css: function (props, value) {\n            var i;\n            if (arguments.length === 1) {\n                if (typeof props === 'string') {\n                    if (this[0]) return window.getComputedStyle(this[0], null).getPropertyValue(props);\n                }\n                else {\n                    for (i = 0; i < this.length; i++) {\n                        for (var prop in props) {\n                            this[i].style[prop] = props[prop];\n                        }\n                    }\n                    return this;\n                }\n            }\n            if (arguments.length === 2 && typeof props === 'string') {\n                for (i = 0; i < this.length; i++) {\n                    this[i].style[props] = value;\n                }\n                return this;\n            }\n            return this;\n        },\n\n        //Dom manipulation\n        each: function (callback) {\n            for (var i = 0; i < this.length; i++) {\n                callback.call(this[i], i, this[i]);\n            }\n            return this;\n        },\n        html: function (html) {\n            if (typeof html === 'undefined') {\n                return this[0] ? this[0].innerHTML : undefined;\n            }\n            else {\n                for (var i = 0; i < this.length; i++) {\n                    this[i].innerHTML = html;\n                }\n                return this;\n            }\n        },\n        text: function (text) {\n            if (typeof text === 'undefined') {\n                if (this[0]) {\n                    return this[0].textContent.trim();\n                }\n                else return null;\n            }\n            else {\n                for (var i = 0; i < this.length; i++) {\n                    this[i].textContent = text;\n                }\n                return this;\n            }\n        },\n        is: function (selector) {\n            if (!this[0]) return false;\n            var compareWith, i;\n            if (typeof selector === 'string') {\n                var el = this[0];\n                if (el === document) return selector === document;\n                if (el === window) return selector === window;\n\n                if (el.matches) return el.matches(selector);\n                else if (el.webkitMatchesSelector) return el.webkitMatchesSelector(selector);\n                else if (el.mozMatchesSelector) return el.mozMatchesSelector(selector);\n                else if (el.msMatchesSelector) return el.msMatchesSelector(selector);\n                else {\n                    compareWith = $(selector);\n                    for (i = 0; i < compareWith.length; i++) {\n                        if (compareWith[i] === this[0]) return true;\n                    }\n                    return false;\n                }\n            }\n            else if (selector === document) return this[0] === document;\n            else if (selector === window) return this[0] === window;\n            else {\n                if (selector.nodeType || selector instanceof Dom7) {\n                    compareWith = selector.nodeType ? [selector] : selector;\n                    for (i = 0; i < compareWith.length; i++) {\n                        if (compareWith[i] === this[0]) return true;\n                    }\n                    return false;\n                }\n                return false;\n            }\n\n        },\n        index: function () {\n            if (this[0]) {\n                var child = this[0];\n                var i = 0;\n                while ((child = child.previousSibling) !== null) {\n                    if (child.nodeType === 1) i++;\n                }\n                return i;\n            }\n            else return undefined;\n        },\n        eq: function (index) {\n            if (typeof index === 'undefined') return this;\n            var length = this.length;\n            var returnIndex;\n            if (index > length - 1) {\n                return new Dom7([]);\n            }\n            if (index < 0) {\n                returnIndex = length + index;\n                if (returnIndex < 0) return new Dom7([]);\n                else return new Dom7([this[returnIndex]]);\n            }\n            return new Dom7([this[index]]);\n        },\n        append: function (newChild) {\n            var i, j;\n            for (i = 0; i < this.length; i++) {\n                if (typeof newChild === 'string') {\n                    var tempDiv = document.createElement('div');\n                    tempDiv.innerHTML = newChild;\n                    while (tempDiv.firstChild) {\n                        this[i].appendChild(tempDiv.firstChild);\n                    }\n                }\n                else if (newChild instanceof Dom7) {\n                    for (j = 0; j < newChild.length; j++) {\n                        this[i].appendChild(newChild[j]);\n                    }\n                }\n                else {\n                    this[i].appendChild(newChild);\n                }\n            }\n            return this;\n        },\n        prepend: function (newChild) {\n            var i, j;\n            for (i = 0; i < this.length; i++) {\n                if (typeof newChild === 'string') {\n                    var tempDiv = document.createElement('div');\n                    tempDiv.innerHTML = newChild;\n                    for (j = tempDiv.childNodes.length - 1; j >= 0; j--) {\n                        this[i].insertBefore(tempDiv.childNodes[j], this[i].childNodes[0]);\n                    }\n                    // this[i].insertAdjacentHTML('afterbegin', newChild);\n                }\n                else if (newChild instanceof Dom7) {\n                    for (j = 0; j < newChild.length; j++) {\n                        this[i].insertBefore(newChild[j], this[i].childNodes[0]);\n                    }\n                }\n                else {\n                    this[i].insertBefore(newChild, this[i].childNodes[0]);\n                }\n            }\n            return this;\n        },\n        insertBefore: function (selector) {\n            var before = $(selector);\n            for (var i = 0; i < this.length; i++) {\n                if (before.length === 1) {\n                    before[0].parentNode.insertBefore(this[i], before[0]);\n                }\n                else if (before.length > 1) {\n                    for (var j = 0; j < before.length; j++) {\n                        before[j].parentNode.insertBefore(this[i].cloneNode(true), before[j]);\n                    }\n                }\n            }\n        },\n        insertAfter: function (selector) {\n            var after = $(selector);\n            for (var i = 0; i < this.length; i++) {\n                if (after.length === 1) {\n                    after[0].parentNode.insertBefore(this[i], after[0].nextSibling);\n                }\n                else if (after.length > 1) {\n                    for (var j = 0; j < after.length; j++) {\n                        after[j].parentNode.insertBefore(this[i].cloneNode(true), after[j].nextSibling);\n                    }\n                }\n            }\n        },\n        next: function (selector) {\n            if (this.length > 0) {\n                if (selector) {\n                    if (this[0].nextElementSibling && $(this[0].nextElementSibling).is(selector)) return new Dom7([this[0].nextElementSibling]);\n                    else return new Dom7([]);\n                }\n                else {\n                    if (this[0].nextElementSibling) return new Dom7([this[0].nextElementSibling]);\n                    else return new Dom7([]);\n                }\n            }\n            else return new Dom7([]);\n        },\n        nextAll: function (selector) {\n            var nextEls = [];\n            var el = this[0];\n            if (!el) return new Dom7([]);\n            while (el.nextElementSibling) {\n                var next = el.nextElementSibling;\n                if (selector) {\n                    if($(next).is(selector)) nextEls.push(next);\n                }\n                else nextEls.push(next);\n                el = next;\n            }\n            return new Dom7(nextEls);\n        },\n        prev: function (selector) {\n            if (this.length > 0) {\n                if (selector) {\n                    if (this[0].previousElementSibling && $(this[0].previousElementSibling).is(selector)) return new Dom7([this[0].previousElementSibling]);\n                    else return new Dom7([]);\n                }\n                else {\n                    if (this[0].previousElementSibling) return new Dom7([this[0].previousElementSibling]);\n                    else return new Dom7([]);\n                }\n            }\n            else return new Dom7([]);\n        },\n        prevAll: function (selector) {\n            var prevEls = [];\n            var el = this[0];\n            if (!el) return new Dom7([]);\n            while (el.previousElementSibling) {\n                var prev = el.previousElementSibling;\n                if (selector) {\n                    if($(prev).is(selector)) prevEls.push(prev);\n                }\n                else prevEls.push(prev);\n                el = prev;\n            }\n            return new Dom7(prevEls);\n        },\n        parent: function (selector) {\n            var parents = [];\n            for (var i = 0; i < this.length; i++) {\n                if (selector) {\n                    if ($(this[i].parentNode).is(selector)) parents.push(this[i].parentNode);\n                }\n                else {\n                    parents.push(this[i].parentNode);\n                }\n            }\n            return $($.unique(parents));\n        },\n        parents: function (selector) {\n            var parents = [];\n            for (var i = 0; i < this.length; i++) {\n                var parent = this[i].parentNode;\n                while (parent) {\n                    if (selector) {\n                        if ($(parent).is(selector)) parents.push(parent);\n                    }\n                    else {\n                        parents.push(parent);\n                    }\n                    parent = parent.parentNode;\n                }\n            }\n            return $($.unique(parents));\n        },\n        find : function (selector) {\n            var foundElements = [];\n            for (var i = 0; i < this.length; i++) {\n                var found = this[i].querySelectorAll(selector);\n                for (var j = 0; j < found.length; j++) {\n                    foundElements.push(found[j]);\n                }\n            }\n            return new Dom7(foundElements);\n        },\n        children: function (selector) {\n            var children = [];\n            for (var i = 0; i < this.length; i++) {\n                var childNodes = this[i].childNodes;\n\n                for (var j = 0; j < childNodes.length; j++) {\n                    if (!selector) {\n                        if (childNodes[j].nodeType === 1) children.push(childNodes[j]);\n                    }\n                    else {\n                        if (childNodes[j].nodeType === 1 && $(childNodes[j]).is(selector)) children.push(childNodes[j]);\n                    }\n                }\n            }\n            return new Dom7($.unique(children));\n        },\n        remove: function () {\n            for (var i = 0; i < this.length; i++) {\n                if (this[i].parentNode) this[i].parentNode.removeChild(this[i]);\n            }\n            return this;\n        },\n        add: function () {\n            var dom = this;\n            var i, j;\n            for (i = 0; i < arguments.length; i++) {\n                var toAdd = $(arguments[i]);\n                for (j = 0; j < toAdd.length; j++) {\n                    dom[dom.length] = toAdd[j];\n                    dom.length++;\n                }\n            }\n            return dom;\n        }\n    };\n    $.fn = Dom7.prototype;\n    $.unique = function (arr) {\n        var unique = [];\n        for (var i = 0; i < arr.length; i++) {\n            if (unique.indexOf(arr[i]) === -1) unique.push(arr[i]);\n        }\n        return unique;\n    };\n\n    return $;\n})();\n"
  },
  {
    "path": "app_backend/static/plugin/Swiper-3.3.1/src/js/effects.js",
    "content": "/*=========================\n  Effects\n  ===========================*/\ns.effects = {\n    fade: {\n        setTranslate: function () {\n            for (var i = 0; i < s.slides.length; i++) {\n                var slide = s.slides.eq(i);\n                var offset = slide[0].swiperSlideOffset;\n                var tx = -offset;\n                if (!s.params.virtualTranslate) tx = tx - s.translate;\n                var ty = 0;\n                if (!s.isHorizontal()) {\n                    ty = tx;\n                    tx = 0;\n                }\n                var slideOpacity = s.params.fade.crossFade ?\n                        Math.max(1 - Math.abs(slide[0].progress), 0) :\n                        1 + Math.min(Math.max(slide[0].progress, -1), 0);\n                slide\n                    .css({\n                        opacity: slideOpacity\n                    })\n                    .transform('translate3d(' + tx + 'px, ' + ty + 'px, 0px)');\n\n            }\n\n        },\n        setTransition: function (duration) {\n            s.slides.transition(duration);\n            if (s.params.virtualTranslate && duration !== 0) {\n                var eventTriggered = false;\n                s.slides.transitionEnd(function () {\n                    if (eventTriggered) return;\n                    if (!s) return;\n                    eventTriggered = true;\n                    s.animating = false;\n                    var triggerEvents = ['webkitTransitionEnd', 'transitionend', 'oTransitionEnd', 'MSTransitionEnd', 'msTransitionEnd'];\n                    for (var i = 0; i < triggerEvents.length; i++) {\n                        s.wrapper.trigger(triggerEvents[i]);\n                    }\n                });\n            }\n        }\n    },\n    flip: {\n        setTranslate: function () {\n            for (var i = 0; i < s.slides.length; i++) {\n                var slide = s.slides.eq(i);\n                var progress = slide[0].progress;\n                if (s.params.flip.limitRotation) {\n                    progress = Math.max(Math.min(slide[0].progress, 1), -1);\n                }\n                var offset = slide[0].swiperSlideOffset;\n                var rotate = -180 * progress,\n                    rotateY = rotate,\n                    rotateX = 0,\n                    tx = -offset,\n                    ty = 0;\n                if (!s.isHorizontal()) {\n                    ty = tx;\n                    tx = 0;\n                    rotateX = -rotateY;\n                    rotateY = 0;\n                }\n                else if (s.rtl) {\n                    rotateY = -rotateY;\n                }\n\n                slide[0].style.zIndex = -Math.abs(Math.round(progress)) + s.slides.length;\n\n                if (s.params.flip.slideShadows) {\n                    //Set shadows\n                    var shadowBefore = s.isHorizontal() ? slide.find('.swiper-slide-shadow-left') : slide.find('.swiper-slide-shadow-top');\n                    var shadowAfter = s.isHorizontal() ? slide.find('.swiper-slide-shadow-right') : slide.find('.swiper-slide-shadow-bottom');\n                    if (shadowBefore.length === 0) {\n                        shadowBefore = $('<div class=\"swiper-slide-shadow-' + (s.isHorizontal() ? 'left' : 'top') + '\"></div>');\n                        slide.append(shadowBefore);\n                    }\n                    if (shadowAfter.length === 0) {\n                        shadowAfter = $('<div class=\"swiper-slide-shadow-' + (s.isHorizontal() ? 'right' : 'bottom') + '\"></div>');\n                        slide.append(shadowAfter);\n                    }\n                    if (shadowBefore.length) shadowBefore[0].style.opacity = Math.max(-progress, 0);\n                    if (shadowAfter.length) shadowAfter[0].style.opacity = Math.max(progress, 0);\n                }\n\n                slide\n                    .transform('translate3d(' + tx + 'px, ' + ty + 'px, 0px) rotateX(' + rotateX + 'deg) rotateY(' + rotateY + 'deg)');\n            }\n        },\n        setTransition: function (duration) {\n            s.slides.transition(duration).find('.swiper-slide-shadow-top, .swiper-slide-shadow-right, .swiper-slide-shadow-bottom, .swiper-slide-shadow-left').transition(duration);\n            if (s.params.virtualTranslate && duration !== 0) {\n                var eventTriggered = false;\n                s.slides.eq(s.activeIndex).transitionEnd(function () {\n                    if (eventTriggered) return;\n                    if (!s) return;\n                    if (!$(this).hasClass(s.params.slideActiveClass)) return;\n                    eventTriggered = true;\n                    s.animating = false;\n                    var triggerEvents = ['webkitTransitionEnd', 'transitionend', 'oTransitionEnd', 'MSTransitionEnd', 'msTransitionEnd'];\n                    for (var i = 0; i < triggerEvents.length; i++) {\n                        s.wrapper.trigger(triggerEvents[i]);\n                    }\n                });\n            }\n        }\n    },\n    cube: {\n        setTranslate: function () {\n            var wrapperRotate = 0, cubeShadow;\n            if (s.params.cube.shadow) {\n                if (s.isHorizontal()) {\n                    cubeShadow = s.wrapper.find('.swiper-cube-shadow');\n                    if (cubeShadow.length === 0) {\n                        cubeShadow = $('<div class=\"swiper-cube-shadow\"></div>');\n                        s.wrapper.append(cubeShadow);\n                    }\n                    cubeShadow.css({height: s.width + 'px'});\n                }\n                else {\n                    cubeShadow = s.container.find('.swiper-cube-shadow');\n                    if (cubeShadow.length === 0) {\n                        cubeShadow = $('<div class=\"swiper-cube-shadow\"></div>');\n                        s.container.append(cubeShadow);\n                    }\n                }\n            }\n            for (var i = 0; i < s.slides.length; i++) {\n                var slide = s.slides.eq(i);\n                var slideAngle = i * 90;\n                var round = Math.floor(slideAngle / 360);\n                if (s.rtl) {\n                    slideAngle = -slideAngle;\n                    round = Math.floor(-slideAngle / 360);\n                }\n                var progress = Math.max(Math.min(slide[0].progress, 1), -1);\n                var tx = 0, ty = 0, tz = 0;\n                if (i % 4 === 0) {\n                    tx = - round * 4 * s.size;\n                    tz = 0;\n                }\n                else if ((i - 1) % 4 === 0) {\n                    tx = 0;\n                    tz = - round * 4 * s.size;\n                }\n                else if ((i - 2) % 4 === 0) {\n                    tx = s.size + round * 4 * s.size;\n                    tz = s.size;\n                }\n                else if ((i - 3) % 4 === 0) {\n                    tx = - s.size;\n                    tz = 3 * s.size + s.size * 4 * round;\n                }\n                if (s.rtl) {\n                    tx = -tx;\n                }\n\n                if (!s.isHorizontal()) {\n                    ty = tx;\n                    tx = 0;\n                }\n\n                var transform = 'rotateX(' + (s.isHorizontal() ? 0 : -slideAngle) + 'deg) rotateY(' + (s.isHorizontal() ? slideAngle : 0) + 'deg) translate3d(' + tx + 'px, ' + ty + 'px, ' + tz + 'px)';\n                if (progress <= 1 && progress > -1) {\n                    wrapperRotate = i * 90 + progress * 90;\n                    if (s.rtl) wrapperRotate = -i * 90 - progress * 90;\n                }\n                slide.transform(transform);\n                if (s.params.cube.slideShadows) {\n                    //Set shadows\n                    var shadowBefore = s.isHorizontal() ? slide.find('.swiper-slide-shadow-left') : slide.find('.swiper-slide-shadow-top');\n                    var shadowAfter = s.isHorizontal() ? slide.find('.swiper-slide-shadow-right') : slide.find('.swiper-slide-shadow-bottom');\n                    if (shadowBefore.length === 0) {\n                        shadowBefore = $('<div class=\"swiper-slide-shadow-' + (s.isHorizontal() ? 'left' : 'top') + '\"></div>');\n                        slide.append(shadowBefore);\n                    }\n                    if (shadowAfter.length === 0) {\n                        shadowAfter = $('<div class=\"swiper-slide-shadow-' + (s.isHorizontal() ? 'right' : 'bottom') + '\"></div>');\n                        slide.append(shadowAfter);\n                    }\n                    if (shadowBefore.length) shadowBefore[0].style.opacity = Math.max(-progress, 0);\n                    if (shadowAfter.length) shadowAfter[0].style.opacity = Math.max(progress, 0);\n                }\n            }\n            s.wrapper.css({\n                '-webkit-transform-origin': '50% 50% -' + (s.size / 2) + 'px',\n                '-moz-transform-origin': '50% 50% -' + (s.size / 2) + 'px',\n                '-ms-transform-origin': '50% 50% -' + (s.size / 2) + 'px',\n                'transform-origin': '50% 50% -' + (s.size / 2) + 'px'\n            });\n\n            if (s.params.cube.shadow) {\n                if (s.isHorizontal()) {\n                    cubeShadow.transform('translate3d(0px, ' + (s.width / 2 + s.params.cube.shadowOffset) + 'px, ' + (-s.width / 2) + 'px) rotateX(90deg) rotateZ(0deg) scale(' + (s.params.cube.shadowScale) + ')');\n                }\n                else {\n                    var shadowAngle = Math.abs(wrapperRotate) - Math.floor(Math.abs(wrapperRotate) / 90) * 90;\n                    var multiplier = 1.5 - (Math.sin(shadowAngle * 2 * Math.PI / 360) / 2 + Math.cos(shadowAngle * 2 * Math.PI / 360) / 2);\n                    var scale1 = s.params.cube.shadowScale,\n                        scale2 = s.params.cube.shadowScale / multiplier,\n                        offset = s.params.cube.shadowOffset;\n                    cubeShadow.transform('scale3d(' + scale1 + ', 1, ' + scale2 + ') translate3d(0px, ' + (s.height / 2 + offset) + 'px, ' + (-s.height / 2 / scale2) + 'px) rotateX(-90deg)');\n                }\n            }\n            var zFactor = (s.isSafari || s.isUiWebView) ? (-s.size / 2) : 0;\n            s.wrapper.transform('translate3d(0px,0,' + zFactor + 'px) rotateX(' + (s.isHorizontal() ? 0 : wrapperRotate) + 'deg) rotateY(' + (s.isHorizontal() ? -wrapperRotate : 0) + 'deg)');\n        },\n        setTransition: function (duration) {\n            s.slides.transition(duration).find('.swiper-slide-shadow-top, .swiper-slide-shadow-right, .swiper-slide-shadow-bottom, .swiper-slide-shadow-left').transition(duration);\n            if (s.params.cube.shadow && !s.isHorizontal()) {\n                s.container.find('.swiper-cube-shadow').transition(duration);\n            }\n        }\n    },\n    coverflow: {\n        setTranslate: function () {\n            var transform = s.translate;\n            var center = s.isHorizontal() ? -transform + s.width / 2 : -transform + s.height / 2;\n            var rotate = s.isHorizontal() ? s.params.coverflow.rotate: -s.params.coverflow.rotate;\n            var translate = s.params.coverflow.depth;\n            //Each slide offset from center\n            for (var i = 0, length = s.slides.length; i < length; i++) {\n                var slide = s.slides.eq(i);\n                var slideSize = s.slidesSizesGrid[i];\n                var slideOffset = slide[0].swiperSlideOffset;\n                var offsetMultiplier = (center - slideOffset - slideSize / 2) / slideSize * s.params.coverflow.modifier;\n\n                var rotateY = s.isHorizontal() ? rotate * offsetMultiplier : 0;\n                var rotateX = s.isHorizontal() ? 0 : rotate * offsetMultiplier;\n                // var rotateZ = 0\n                var translateZ = -translate * Math.abs(offsetMultiplier);\n\n                var translateY = s.isHorizontal() ? 0 : s.params.coverflow.stretch * (offsetMultiplier);\n                var translateX = s.isHorizontal() ? s.params.coverflow.stretch * (offsetMultiplier) : 0;\n\n                //Fix for ultra small values\n                if (Math.abs(translateX) < 0.001) translateX = 0;\n                if (Math.abs(translateY) < 0.001) translateY = 0;\n                if (Math.abs(translateZ) < 0.001) translateZ = 0;\n                if (Math.abs(rotateY) < 0.001) rotateY = 0;\n                if (Math.abs(rotateX) < 0.001) rotateX = 0;\n\n                var slideTransform = 'translate3d(' + translateX + 'px,' + translateY + 'px,' + translateZ + 'px)  rotateX(' + rotateX + 'deg) rotateY(' + rotateY + 'deg)';\n\n                slide.transform(slideTransform);\n                slide[0].style.zIndex = -Math.abs(Math.round(offsetMultiplier)) + 1;\n                if (s.params.coverflow.slideShadows) {\n                    //Set shadows\n                    var shadowBefore = s.isHorizontal() ? slide.find('.swiper-slide-shadow-left') : slide.find('.swiper-slide-shadow-top');\n                    var shadowAfter = s.isHorizontal() ? slide.find('.swiper-slide-shadow-right') : slide.find('.swiper-slide-shadow-bottom');\n                    if (shadowBefore.length === 0) {\n                        shadowBefore = $('<div class=\"swiper-slide-shadow-' + (s.isHorizontal() ? 'left' : 'top') + '\"></div>');\n                        slide.append(shadowBefore);\n                    }\n                    if (shadowAfter.length === 0) {\n                        shadowAfter = $('<div class=\"swiper-slide-shadow-' + (s.isHorizontal() ? 'right' : 'bottom') + '\"></div>');\n                        slide.append(shadowAfter);\n                    }\n                    if (shadowBefore.length) shadowBefore[0].style.opacity = offsetMultiplier > 0 ? offsetMultiplier : 0;\n                    if (shadowAfter.length) shadowAfter[0].style.opacity = (-offsetMultiplier) > 0 ? -offsetMultiplier : 0;\n                }\n            }\n\n            //Set correct perspective for IE10\n            if (s.browser.ie) {\n                var ws = s.wrapper[0].style;\n                ws.perspectiveOrigin = center + 'px 50%';\n            }\n        },\n        setTransition: function (duration) {\n            s.slides.transition(duration).find('.swiper-slide-shadow-top, .swiper-slide-shadow-right, .swiper-slide-shadow-bottom, .swiper-slide-shadow-left').transition(duration);\n        }\n    }\n};"
  },
  {
    "path": "app_backend/static/plugin/Swiper-3.3.1/src/js/emitter.js",
    "content": "/*=========================\n  Events/Callbacks/Plugins Emitter\n  ===========================*/\nfunction normalizeEventName (eventName) {\n    if (eventName.indexOf('on') !== 0) {\n        if (eventName[0] !== eventName[0].toUpperCase()) {\n            eventName = 'on' + eventName[0].toUpperCase() + eventName.substring(1);\n        }\n        else {\n            eventName = 'on' + eventName;\n        }\n    }\n    return eventName;\n}\ns.emitterEventListeners = {\n\n};\ns.emit = function (eventName) {\n    // Trigger callbacks\n    if (s.params[eventName]) {\n        s.params[eventName](arguments[1], arguments[2], arguments[3], arguments[4], arguments[5]);\n    }\n    var i;\n    // Trigger events\n    if (s.emitterEventListeners[eventName]) {\n        for (i = 0; i < s.emitterEventListeners[eventName].length; i++) {\n            s.emitterEventListeners[eventName][i](arguments[1], arguments[2], arguments[3], arguments[4], arguments[5]);\n        }\n    }\n    // Trigger plugins\n    if (s.callPlugins) s.callPlugins(eventName, arguments[1], arguments[2], arguments[3], arguments[4], arguments[5]);\n};\ns.on = function (eventName, handler) {\n    eventName = normalizeEventName(eventName);\n    if (!s.emitterEventListeners[eventName]) s.emitterEventListeners[eventName] = [];\n    s.emitterEventListeners[eventName].push(handler);\n    return s;\n};\ns.off = function (eventName, handler) {\n    var i;\n    eventName = normalizeEventName(eventName);\n    if (typeof handler === 'undefined') {\n        // Remove all handlers for such event\n        s.emitterEventListeners[eventName] = [];\n        return s;\n    }\n    if (!s.emitterEventListeners[eventName] || s.emitterEventListeners[eventName].length === 0) return;\n    for (i = 0; i < s.emitterEventListeners[eventName].length; i++) {\n        if(s.emitterEventListeners[eventName][i] === handler) s.emitterEventListeners[eventName].splice(i, 1);\n    }\n    return s;\n};\ns.once = function (eventName, handler) {\n    eventName = normalizeEventName(eventName);\n    var _handler = function () {\n        handler(arguments[0], arguments[1], arguments[2], arguments[3], arguments[4]);\n        s.off(eventName, _handler);\n    };\n    s.on(eventName, _handler);\n    return s;\n};"
  },
  {
    "path": "app_backend/static/plugin/Swiper-3.3.1/src/js/get-dom-lib.js",
    "content": "/*===========================\n Get Dom libraries\n ===========================*/\nvar swiperDomPlugins = ['jQuery', 'Zepto', 'Dom7'];\nfor (var i = 0; i < swiperDomPlugins.length; i++) {\n\tif (window[swiperDomPlugins[i]]) {\n\t\taddLibraryPlugin(window[swiperDomPlugins[i]]);\n\t}\n}\n// Required DOM Plugins\nvar domLib;\nif (typeof Dom7 === 'undefined') {\n\tdomLib = window.Dom7 || window.Zepto || window.jQuery;\n}\nelse {\n\tdomLib = Dom7;\n}"
  },
  {
    "path": "app_backend/static/plugin/Swiper-3.3.1/src/js/get-jquery.js",
    "content": "/*===========================\n Get jQuery\n ===========================*/\n\naddLibraryPlugin($);\n\nvar domLib = $;"
  },
  {
    "path": "app_backend/static/plugin/Swiper-3.3.1/src/js/hashnav.js",
    "content": "/*=========================\n  Hash Navigation\n  ===========================*/\ns.hashnav = {\n    init: function () {\n        if (!s.params.hashnav) return;\n        s.hashnav.initialized = true;\n        var hash = document.location.hash.replace('#', '');\n        if (!hash) return;\n        var speed = 0;\n        for (var i = 0, length = s.slides.length; i < length; i++) {\n            var slide = s.slides.eq(i);\n            var slideHash = slide.attr('data-hash');\n            if (slideHash === hash && !slide.hasClass(s.params.slideDuplicateClass)) {\n                var index = slide.index();\n                s.slideTo(index, speed, s.params.runCallbacksOnInit, true);\n            }\n        }\n    },\n    setHash: function () {\n        if (!s.hashnav.initialized || !s.params.hashnav) return;\n        document.location.hash = s.slides.eq(s.activeIndex).attr('data-hash') || '';\n    }\n};"
  },
  {
    "path": "app_backend/static/plugin/Swiper-3.3.1/src/js/init.js",
    "content": "/*=========================\n  Init/Destroy\n  ===========================*/\ns.init = function () {\n    if (s.params.loop) s.createLoop();\n    s.updateContainerSize();\n    s.updateSlidesSize();\n    s.updatePagination();\n    if (s.params.scrollbar && s.scrollbar) {\n        s.scrollbar.set();\n        if (s.params.scrollbarDraggable) {\n            s.scrollbar.enableDraggable();\n        }\n    }\n    if (s.params.effect !== 'slide' && s.effects[s.params.effect]) {\n        if (!s.params.loop) s.updateProgress();\n        s.effects[s.params.effect].setTranslate();\n    }\n    if (s.params.loop) {\n        s.slideTo(s.params.initialSlide + s.loopedSlides, 0, s.params.runCallbacksOnInit);\n    }\n    else {\n        s.slideTo(s.params.initialSlide, 0, s.params.runCallbacksOnInit);\n        if (s.params.initialSlide === 0) {\n            if (s.parallax && s.params.parallax) s.parallax.setTranslate();\n            if (s.lazy && s.params.lazyLoading) {\n                s.lazy.load();\n                s.lazy.initialImageLoaded = true;\n            }\n        }\n    }\n    s.attachEvents();\n    if (s.params.observer && s.support.observer) {\n        s.initObservers();\n    }\n    if (s.params.preloadImages && !s.params.lazyLoading) {\n        s.preloadImages();\n    }\n    if (s.params.autoplay) {\n        s.startAutoplay();\n    }\n    if (s.params.keyboardControl) {\n        if (s.enableKeyboardControl) s.enableKeyboardControl();\n    }\n    if (s.params.mousewheelControl) {\n        if (s.enableMousewheelControl) s.enableMousewheelControl();\n    }\n    if (s.params.hashnav) {\n        if (s.hashnav) s.hashnav.init();\n    }\n    if (s.params.a11y && s.a11y) s.a11y.init();\n    s.emit('onInit', s);\n};\n\n// Cleanup dynamic styles\ns.cleanupStyles = function () {\n    // Container\n    s.container.removeClass(s.classNames.join(' ')).removeAttr('style');\n\n    // Wrapper\n    s.wrapper.removeAttr('style');\n\n    // Slides\n    if (s.slides && s.slides.length) {\n        s.slides\n            .removeClass([\n              s.params.slideVisibleClass,\n              s.params.slideActiveClass,\n              s.params.slideNextClass,\n              s.params.slidePrevClass\n            ].join(' '))\n            .removeAttr('style')\n            .removeAttr('data-swiper-column')\n            .removeAttr('data-swiper-row');\n    }\n\n    // Pagination/Bullets\n    if (s.paginationContainer && s.paginationContainer.length) {\n        s.paginationContainer.removeClass(s.params.paginationHiddenClass);\n    }\n    if (s.bullets && s.bullets.length) {\n        s.bullets.removeClass(s.params.bulletActiveClass);\n    }\n\n    // Buttons\n    if (s.params.prevButton) $(s.params.prevButton).removeClass(s.params.buttonDisabledClass);\n    if (s.params.nextButton) $(s.params.nextButton).removeClass(s.params.buttonDisabledClass);\n\n    // Scrollbar\n    if (s.params.scrollbar && s.scrollbar) {\n        if (s.scrollbar.track && s.scrollbar.track.length) s.scrollbar.track.removeAttr('style');\n        if (s.scrollbar.drag && s.scrollbar.drag.length) s.scrollbar.drag.removeAttr('style');\n    }\n};\n\n// Destroy\ns.destroy = function (deleteInstance, cleanupStyles) {\n    // Detach evebts\n    s.detachEvents();\n    // Stop autoplay\n    s.stopAutoplay();\n    // Disable draggable\n    if (s.params.scrollbar && s.scrollbar) {\n        if (s.params.scrollbarDraggable) {\n            s.scrollbar.disableDraggable();\n        }\n    }\n    // Destroy loop\n    if (s.params.loop) {\n        s.destroyLoop();\n    }\n    // Cleanup styles\n    if (cleanupStyles) {\n        s.cleanupStyles();\n    }\n    // Disconnect observer\n    s.disconnectObservers();\n    // Disable keyboard/mousewheel\n    if (s.params.keyboardControl) {\n        if (s.disableKeyboardControl) s.disableKeyboardControl();\n    }\n    if (s.params.mousewheelControl) {\n        if (s.disableMousewheelControl) s.disableMousewheelControl();\n    }\n    // Disable a11y\n    if (s.params.a11y && s.a11y) s.a11y.destroy();\n    // Destroy callback\n    s.emit('onDestroy');\n    // Delete instance\n    if (deleteInstance !== false) s = null;\n};\n\ns.init();\n"
  },
  {
    "path": "app_backend/static/plugin/Swiper-3.3.1/src/js/keyboard.js",
    "content": "/*=========================\n  Keyboard Control\n  ===========================*/\nfunction handleKeyboard(e) {\n    if (e.originalEvent) e = e.originalEvent; //jquery fix\n    var kc = e.keyCode || e.charCode;\n    // Directions locks\n    if (!s.params.allowSwipeToNext && (s.isHorizontal() && kc === 39 || !s.isHorizontal() && kc === 40)) {\n        return false;\n    }\n    if (!s.params.allowSwipeToPrev && (s.isHorizontal() && kc === 37 || !s.isHorizontal() && kc === 38)) {\n        return false;\n    }\n    if (e.shiftKey || e.altKey || e.ctrlKey || e.metaKey) {\n        return;\n    }\n    if (document.activeElement && document.activeElement.nodeName && (document.activeElement.nodeName.toLowerCase() === 'input' || document.activeElement.nodeName.toLowerCase() === 'textarea')) {\n        return;\n    }\n    if (kc === 37 || kc === 39 || kc === 38 || kc === 40) {\n        var inView = false;\n        //Check that swiper should be inside of visible area of window\n        if (s.container.parents('.swiper-slide').length > 0 && s.container.parents('.swiper-slide-active').length === 0) {\n            return;\n        }\n        var windowScroll = {\n            left: window.pageXOffset,\n            top: window.pageYOffset\n        };\n        var windowWidth = window.innerWidth;\n        var windowHeight = window.innerHeight;\n        var swiperOffset = s.container.offset();\n        if (s.rtl) swiperOffset.left = swiperOffset.left - s.container[0].scrollLeft;\n        var swiperCoord = [\n            [swiperOffset.left, swiperOffset.top],\n            [swiperOffset.left + s.width, swiperOffset.top],\n            [swiperOffset.left, swiperOffset.top + s.height],\n            [swiperOffset.left + s.width, swiperOffset.top + s.height]\n        ];\n        for (var i = 0; i < swiperCoord.length; i++) {\n            var point = swiperCoord[i];\n            if (\n                point[0] >= windowScroll.left && point[0] <= windowScroll.left + windowWidth &&\n                point[1] >= windowScroll.top && point[1] <= windowScroll.top + windowHeight\n            ) {\n                inView = true;\n            }\n\n        }\n        if (!inView) return;\n    }\n    if (s.isHorizontal()) {\n        if (kc === 37 || kc === 39) {\n            if (e.preventDefault) e.preventDefault();\n            else e.returnValue = false;\n        }\n        if ((kc === 39 && !s.rtl) || (kc === 37 && s.rtl)) s.slideNext();\n        if ((kc === 37 && !s.rtl) || (kc === 39 && s.rtl)) s.slidePrev();\n    }\n    else {\n        if (kc === 38 || kc === 40) {\n            if (e.preventDefault) e.preventDefault();\n            else e.returnValue = false;\n        }\n        if (kc === 40) s.slideNext();\n        if (kc === 38) s.slidePrev();\n    }\n}\ns.disableKeyboardControl = function () {\n    s.params.keyboardControl = false;\n    $(document).off('keydown', handleKeyboard);\n};\ns.enableKeyboardControl = function () {\n    s.params.keyboardControl = true;\n    $(document).on('keydown', handleKeyboard);\n};\n"
  },
  {
    "path": "app_backend/static/plugin/Swiper-3.3.1/src/js/lazy-load.js",
    "content": "/*=========================\n  Images Lazy Loading\n  ===========================*/\ns.lazy = {\n    initialImageLoaded: false,\n    loadImageInSlide: function (index, loadInDuplicate) {\n        if (typeof index === 'undefined') return;\n        if (typeof loadInDuplicate === 'undefined') loadInDuplicate = true;\n        if (s.slides.length === 0) return;\n\n        var slide = s.slides.eq(index);\n        var img = slide.find('.swiper-lazy:not(.swiper-lazy-loaded):not(.swiper-lazy-loading)');\n        if (slide.hasClass('swiper-lazy') && !slide.hasClass('swiper-lazy-loaded') && !slide.hasClass('swiper-lazy-loading')) {\n            img = img.add(slide[0]);\n        }\n        if (img.length === 0) return;\n\n        img.each(function () {\n            var _img = $(this);\n            _img.addClass('swiper-lazy-loading');\n            var background = _img.attr('data-background');\n            var src = _img.attr('data-src'),\n                srcset = _img.attr('data-srcset');\n            s.loadImage(_img[0], (src || background), srcset, false, function () {\n                if (background) {\n                    _img.css('background-image', 'url(\"' + background + '\")');\n                    _img.removeAttr('data-background');\n                }\n                else {\n                    if (srcset) {\n                        _img.attr('srcset', srcset);\n                        _img.removeAttr('data-srcset');\n                    }\n                    if (src) {\n                        _img.attr('src', src);\n                        _img.removeAttr('data-src');\n                    }\n\n                }\n\n                _img.addClass('swiper-lazy-loaded').removeClass('swiper-lazy-loading');\n                slide.find('.swiper-lazy-preloader, .preloader').remove();\n                if (s.params.loop && loadInDuplicate) {\n                    var slideOriginalIndex = slide.attr('data-swiper-slide-index');\n                    if (slide.hasClass(s.params.slideDuplicateClass)) {\n                        var originalSlide = s.wrapper.children('[data-swiper-slide-index=\"' + slideOriginalIndex + '\"]:not(.' + s.params.slideDuplicateClass + ')');\n                        s.lazy.loadImageInSlide(originalSlide.index(), false);\n                    }\n                    else {\n                        var duplicatedSlide = s.wrapper.children('.' + s.params.slideDuplicateClass + '[data-swiper-slide-index=\"' + slideOriginalIndex + '\"]');\n                        s.lazy.loadImageInSlide(duplicatedSlide.index(), false);\n                    }\n                }\n                s.emit('onLazyImageReady', s, slide[0], _img[0]);\n            });\n\n            s.emit('onLazyImageLoad', s, slide[0], _img[0]);\n        });\n\n    },\n    load: function () {\n        var i;\n        if (s.params.watchSlidesVisibility) {\n            s.wrapper.children('.' + s.params.slideVisibleClass).each(function () {\n                s.lazy.loadImageInSlide($(this).index());\n            });\n        }\n        else {\n            if (s.params.slidesPerView > 1) {\n                for (i = s.activeIndex; i < s.activeIndex + s.params.slidesPerView ; i++) {\n                    if (s.slides[i]) s.lazy.loadImageInSlide(i);\n                }\n            }\n            else {\n                s.lazy.loadImageInSlide(s.activeIndex);\n            }\n        }\n        if (s.params.lazyLoadingInPrevNext) {\n            if (s.params.slidesPerView > 1 || (s.params.lazyLoadingInPrevNextAmount && s.params.lazyLoadingInPrevNextAmount > 1)) {\n                var amount = s.params.lazyLoadingInPrevNextAmount;\n                var spv = s.params.slidesPerView;\n                var maxIndex = Math.min(s.activeIndex + spv + Math.max(amount, spv), s.slides.length);\n                var minIndex = Math.max(s.activeIndex - Math.max(spv, amount), 0);\n                // Next Slides\n                for (i = s.activeIndex + s.params.slidesPerView; i < maxIndex; i++) {\n                    if (s.slides[i]) s.lazy.loadImageInSlide(i);\n                }\n                // Prev Slides\n                for (i = minIndex; i < s.activeIndex ; i++) {\n                    if (s.slides[i]) s.lazy.loadImageInSlide(i);\n                }\n            }\n            else {\n                var nextSlide = s.wrapper.children('.' + s.params.slideNextClass);\n                if (nextSlide.length > 0) s.lazy.loadImageInSlide(nextSlide.index());\n\n                var prevSlide = s.wrapper.children('.' + s.params.slidePrevClass);\n                if (prevSlide.length > 0) s.lazy.loadImageInSlide(prevSlide.index());\n            }\n        }\n    },\n    onTransitionStart: function () {\n        if (s.params.lazyLoading) {\n            if (s.params.lazyLoadingOnTransitionStart || (!s.params.lazyLoadingOnTransitionStart && !s.lazy.initialImageLoaded)) {\n                s.lazy.load();\n            }\n        }\n    },\n    onTransitionEnd: function () {\n        if (s.params.lazyLoading && !s.params.lazyLoadingOnTransitionStart) {\n            s.lazy.load();\n        }\n    }\n};\n"
  },
  {
    "path": "app_backend/static/plugin/Swiper-3.3.1/src/js/mousewheel.js",
    "content": "/*=========================\n  Mousewheel Control\n  ===========================*/\ns.mousewheel = {\n    event: false,\n    lastScrollTime: (new window.Date()).getTime()\n};\nif (s.params.mousewheelControl) {\n    try {\n        new window.WheelEvent('wheel');\n        s.mousewheel.event = 'wheel';\n    } catch (e) {\n        if (window.WheelEvent || (s.container[0] && 'wheel' in s.container[0])) {\n            s.mousewheel.event = 'wheel';\n        }\n    }\n    if (!s.mousewheel.event && window.WheelEvent) {\n\n    }\n    if (!s.mousewheel.event && document.onmousewheel !== undefined) {\n        s.mousewheel.event = 'mousewheel';\n    }\n    if (!s.mousewheel.event) {\n        s.mousewheel.event = 'DOMMouseScroll';\n    }\n}\nfunction handleMousewheel(e) {\n    if (e.originalEvent) e = e.originalEvent; //jquery fix\n    var we = s.mousewheel.event;\n    var delta = 0;\n    var rtlFactor = s.rtl ? -1 : 1;\n\n    //WebKits\n    if (we === 'mousewheel') {\n        if (s.params.mousewheelForceToAxis) {\n            if (s.isHorizontal()) {\n                if (Math.abs(e.wheelDeltaX) > Math.abs(e.wheelDeltaY)) delta = e.wheelDeltaX * rtlFactor;\n                else return;\n            }\n            else {\n                if (Math.abs(e.wheelDeltaY) > Math.abs(e.wheelDeltaX)) delta = e.wheelDeltaY;\n                else return;\n            }\n        }\n        else {\n            delta = Math.abs(e.wheelDeltaX) > Math.abs(e.wheelDeltaY) ? - e.wheelDeltaX * rtlFactor : - e.wheelDeltaY;\n        }\n    }\n    //Old FireFox\n    else if (we === 'DOMMouseScroll') delta = -e.detail;\n    //New FireFox\n    else if (we === 'wheel') {\n        if (s.params.mousewheelForceToAxis) {\n            if (s.isHorizontal()) {\n                if (Math.abs(e.deltaX) > Math.abs(e.deltaY)) delta = -e.deltaX * rtlFactor;\n                else return;\n            }\n            else {\n                if (Math.abs(e.deltaY) > Math.abs(e.deltaX)) delta = -e.deltaY;\n                else return;\n            }\n        }\n        else {\n            delta = Math.abs(e.deltaX) > Math.abs(e.deltaY) ? - e.deltaX * rtlFactor : - e.deltaY;\n        }\n    }\n    if (delta === 0) return;\n\n    if (s.params.mousewheelInvert) delta = -delta;\n\n    if (!s.params.freeMode) {\n        if ((new window.Date()).getTime() - s.mousewheel.lastScrollTime > 60) {\n            if (delta < 0) {\n                if ((!s.isEnd || s.params.loop) && !s.animating) s.slideNext();\n                else if (s.params.mousewheelReleaseOnEdges) return true;\n            }\n            else {\n                if ((!s.isBeginning || s.params.loop) && !s.animating) s.slidePrev();\n                else if (s.params.mousewheelReleaseOnEdges) return true;\n            }\n        }\n        s.mousewheel.lastScrollTime = (new window.Date()).getTime();\n\n    }\n    else {\n        //Freemode or scrollContainer:\n        var position = s.getWrapperTranslate() + delta * s.params.mousewheelSensitivity;\n        var wasBeginning = s.isBeginning,\n            wasEnd = s.isEnd;\n\n        if (position >= s.minTranslate()) position = s.minTranslate();\n        if (position <= s.maxTranslate()) position = s.maxTranslate();\n\n        s.setWrapperTransition(0);\n        s.setWrapperTranslate(position);\n        s.updateProgress();\n        s.updateActiveIndex();\n\n        if (!wasBeginning && s.isBeginning || !wasEnd && s.isEnd) {\n            s.updateClasses();\n        }\n\n        if (s.params.freeModeSticky) {\n            clearTimeout(s.mousewheel.timeout);\n            s.mousewheel.timeout = setTimeout(function () {\n                s.slideReset();\n            }, 300);\n        }\n        else {\n            if (s.params.lazyLoading && s.lazy) {\n                s.lazy.load();\n            }\n        }\n\n        // Return page scroll on edge positions\n        if (position === 0 || position === s.maxTranslate()) return;\n    }\n    if (s.params.autoplay) s.stopAutoplay();\n\n    if (e.preventDefault) e.preventDefault();\n    else e.returnValue = false;\n    return false;\n}\ns.disableMousewheelControl = function () {\n    if (!s.mousewheel.event) return false;\n    s.container.off(s.mousewheel.event, handleMousewheel);\n    return true;\n};\n\ns.enableMousewheelControl = function () {\n    if (!s.mousewheel.event) return false;\n    s.container.on(s.mousewheel.event, handleMousewheel);\n    return true;\n};\n"
  },
  {
    "path": "app_backend/static/plugin/Swiper-3.3.1/src/js/parallax.js",
    "content": "/*=========================\n  Parallax\n  ===========================*/\nfunction setParallaxTransform(el, progress) {\n    el = $(el);\n    var p, pX, pY;\n    var rtlFactor = s.rtl ? -1 : 1;\n\n    p = el.attr('data-swiper-parallax') || '0';\n    pX = el.attr('data-swiper-parallax-x');\n    pY = el.attr('data-swiper-parallax-y');\n    if (pX || pY) {\n        pX = pX || '0';\n        pY = pY || '0';\n    }\n    else {\n        if (s.isHorizontal()) {\n            pX = p;\n            pY = '0';\n        }\n        else {\n            pY = p;\n            pX = '0';\n        }\n    }\n\n    if ((pX).indexOf('%') >= 0) {\n        pX = parseInt(pX, 10) * progress * rtlFactor + '%';\n    }\n    else {\n        pX = pX * progress * rtlFactor + 'px' ;\n    }\n    if ((pY).indexOf('%') >= 0) {\n        pY = parseInt(pY, 10) * progress + '%';\n    }\n    else {\n        pY = pY * progress + 'px' ;\n    }\n\n    el.transform('translate3d(' + pX + ', ' + pY + ',0px)');\n}\ns.parallax = {\n    setTranslate: function () {\n        s.container.children('[data-swiper-parallax], [data-swiper-parallax-x], [data-swiper-parallax-y]').each(function(){\n            setParallaxTransform(this, s.progress);\n\n        });\n        s.slides.each(function () {\n            var slide = $(this);\n            slide.find('[data-swiper-parallax], [data-swiper-parallax-x], [data-swiper-parallax-y]').each(function () {\n                var progress = Math.min(Math.max(slide[0].progress, -1), 1);\n                setParallaxTransform(this, progress);\n            });\n        });\n    },\n    setTransition: function (duration) {\n        if (typeof duration === 'undefined') duration = s.params.speed;\n        s.container.find('[data-swiper-parallax], [data-swiper-parallax-x], [data-swiper-parallax-y]').each(function(){\n            var el = $(this);\n            var parallaxDuration = parseInt(el.attr('data-swiper-parallax-duration'), 10) || duration;\n            if (duration === 0) parallaxDuration = 0;\n            el.transition(parallaxDuration);\n        });\n    }\n};\n"
  },
  {
    "path": "app_backend/static/plugin/Swiper-3.3.1/src/js/plugins.js",
    "content": "/*=========================\n  Plugins API. Collect all and init all plugins\n  ===========================*/\ns._plugins = [];\nfor (var plugin in s.plugins) {\n    var p = s.plugins[plugin](s, s.params[plugin]);\n    if (p) s._plugins.push(p);\n}\n// Method to call all plugins event/method\ns.callPlugins = function (eventName) {\n    for (var i = 0; i < s._plugins.length; i++) {\n        if (eventName in s._plugins[i]) {\n            s._plugins[i][eventName](arguments[1], arguments[2], arguments[3], arguments[4], arguments[5]);\n        }\n    }\n};"
  },
  {
    "path": "app_backend/static/plugin/Swiper-3.3.1/src/js/scrollbar.js",
    "content": "/*=========================\n  Scrollbar\n  ===========================*/\ns.scrollbar = {\n    isTouched: false,\n    setDragPosition: function (e) {\n        var sb = s.scrollbar;\n        var x = 0, y = 0;\n        var translate;\n        var pointerPosition = s.isHorizontal() ?\n            ((e.type === 'touchstart' || e.type === 'touchmove') ? e.targetTouches[0].pageX : e.pageX || e.clientX) :\n            ((e.type === 'touchstart' || e.type === 'touchmove') ? e.targetTouches[0].pageY : e.pageY || e.clientY) ;\n        var position = (pointerPosition) - sb.track.offset()[s.isHorizontal() ? 'left' : 'top'] - sb.dragSize / 2;\n        var positionMin = -s.minTranslate() * sb.moveDivider;\n        var positionMax = -s.maxTranslate() * sb.moveDivider;\n        if (position < positionMin) {\n            position = positionMin;\n        }\n        else if (position > positionMax) {\n            position = positionMax;\n        }\n        position = -position / sb.moveDivider;\n        s.updateProgress(position);\n        s.setWrapperTranslate(position, true);\n    },\n    dragStart: function (e) {\n        var sb = s.scrollbar;\n        sb.isTouched = true;\n        e.preventDefault();\n        e.stopPropagation();\n\n        sb.setDragPosition(e);\n        clearTimeout(sb.dragTimeout);\n\n        sb.track.transition(0);\n        if (s.params.scrollbarHide) {\n            sb.track.css('opacity', 1);\n        }\n        s.wrapper.transition(100);\n        sb.drag.transition(100);\n        s.emit('onScrollbarDragStart', s);\n    },\n    dragMove: function (e) {\n        var sb = s.scrollbar;\n        if (!sb.isTouched) return;\n        if (e.preventDefault) e.preventDefault();\n        else e.returnValue = false;\n        sb.setDragPosition(e);\n        s.wrapper.transition(0);\n        sb.track.transition(0);\n        sb.drag.transition(0);\n        s.emit('onScrollbarDragMove', s);\n    },\n    dragEnd: function (e) {\n        var sb = s.scrollbar;\n        if (!sb.isTouched) return;\n        sb.isTouched = false;\n        if (s.params.scrollbarHide) {\n            clearTimeout(sb.dragTimeout);\n            sb.dragTimeout = setTimeout(function () {\n                sb.track.css('opacity', 0);\n                sb.track.transition(400);\n            }, 1000);\n\n        }\n        s.emit('onScrollbarDragEnd', s);\n        if (s.params.scrollbarSnapOnRelease) {\n            s.slideReset();\n        }\n    },\n    enableDraggable: function () {\n        var sb = s.scrollbar;\n        var target = s.support.touch ? sb.track : document;\n        $(sb.track).on(s.touchEvents.start, sb.dragStart);\n        $(target).on(s.touchEvents.move, sb.dragMove);\n        $(target).on(s.touchEvents.end, sb.dragEnd);\n    },\n    disableDraggable: function () {\n        var sb = s.scrollbar;\n        var target = s.support.touch ? sb.track : document;\n        $(sb.track).off(s.touchEvents.start, sb.dragStart);\n        $(target).off(s.touchEvents.move, sb.dragMove);\n        $(target).off(s.touchEvents.end, sb.dragEnd);\n    },\n    set: function () {\n        if (!s.params.scrollbar) return;\n        var sb = s.scrollbar;\n        sb.track = $(s.params.scrollbar);\n        if (s.params.uniqueNavElements && typeof s.params.scrollbar === 'string' && sb.track.length > 1 && s.container.find(s.params.scrollbar).length === 1) {\n            sb.track = s.container.find(s.params.scrollbar);\n        }\n        sb.drag = sb.track.find('.swiper-scrollbar-drag');\n        if (sb.drag.length === 0) {\n            sb.drag = $('<div class=\"swiper-scrollbar-drag\"></div>');\n            sb.track.append(sb.drag);\n        }\n        sb.drag[0].style.width = '';\n        sb.drag[0].style.height = '';\n        sb.trackSize = s.isHorizontal() ? sb.track[0].offsetWidth : sb.track[0].offsetHeight;\n\n        sb.divider = s.size / s.virtualSize;\n        sb.moveDivider = sb.divider * (sb.trackSize / s.size);\n        sb.dragSize = sb.trackSize * sb.divider;\n\n        if (s.isHorizontal()) {\n            sb.drag[0].style.width = sb.dragSize + 'px';\n        }\n        else {\n            sb.drag[0].style.height = sb.dragSize + 'px';\n        }\n\n        if (sb.divider >= 1) {\n            sb.track[0].style.display = 'none';\n        }\n        else {\n            sb.track[0].style.display = '';\n        }\n        if (s.params.scrollbarHide) {\n            sb.track[0].style.opacity = 0;\n        }\n    },\n    setTranslate: function () {\n        if (!s.params.scrollbar) return;\n        var diff;\n        var sb = s.scrollbar;\n        var translate = s.translate || 0;\n        var newPos;\n\n        var newSize = sb.dragSize;\n        newPos = (sb.trackSize - sb.dragSize) * s.progress;\n        if (s.rtl && s.isHorizontal()) {\n            newPos = -newPos;\n            if (newPos > 0) {\n                newSize = sb.dragSize - newPos;\n                newPos = 0;\n            }\n            else if (-newPos + sb.dragSize > sb.trackSize) {\n                newSize = sb.trackSize + newPos;\n            }\n        }\n        else {\n            if (newPos < 0) {\n                newSize = sb.dragSize + newPos;\n                newPos = 0;\n            }\n            else if (newPos + sb.dragSize > sb.trackSize) {\n                newSize = sb.trackSize - newPos;\n            }\n        }\n        if (s.isHorizontal()) {\n            if (s.support.transforms3d) {\n                sb.drag.transform('translate3d(' + (newPos) + 'px, 0, 0)');\n            }\n            else {\n                sb.drag.transform('translateX(' + (newPos) + 'px)');\n            }\n            sb.drag[0].style.width = newSize + 'px';\n        }\n        else {\n            if (s.support.transforms3d) {\n                sb.drag.transform('translate3d(0px, ' + (newPos) + 'px, 0)');\n            }\n            else {\n                sb.drag.transform('translateY(' + (newPos) + 'px)');\n            }\n            sb.drag[0].style.height = newSize + 'px';\n        }\n        if (s.params.scrollbarHide) {\n            clearTimeout(sb.timeout);\n            sb.track[0].style.opacity = 1;\n            sb.timeout = setTimeout(function () {\n                sb.track[0].style.opacity = 0;\n                sb.track.transition(400);\n            }, 1000);\n        }\n    },\n    setTransition: function (duration) {\n        if (!s.params.scrollbar) return;\n        s.scrollbar.drag.transition(duration);\n    }\n};"
  },
  {
    "path": "app_backend/static/plugin/Swiper-3.3.1/src/js/swiper-intro-f7.js",
    "content": "/*===========================\nSwiper\n===========================*/\nwindow.Swiper = function (container, params) {\n    if (!(this instanceof Swiper)) return new Swiper(container, params);"
  },
  {
    "path": "app_backend/static/plugin/Swiper-3.3.1/src/js/swiper-intro.js",
    "content": "/*===========================\nSwiper\n===========================*/\nvar Swiper = function (container, params) {\n    if (!(this instanceof Swiper)) return new Swiper(container, params);"
  },
  {
    "path": "app_backend/static/plugin/Swiper-3.3.1/src/js/swiper-outro.js",
    "content": "\n    // Return swiper instance\n    return s;\n};\n"
  },
  {
    "path": "app_backend/static/plugin/Swiper-3.3.1/src/js/swiper-proto.js",
    "content": "/*==================================================\n    Prototype\n====================================================*/\nSwiper.prototype = {\n    isSafari: (function () {\n        var ua = navigator.userAgent.toLowerCase();\n        return (ua.indexOf('safari') >= 0 && ua.indexOf('chrome') < 0 && ua.indexOf('android') < 0);\n    })(),\n    isUiWebView: /(iPhone|iPod|iPad).*AppleWebKit(?!.*Safari)/i.test(navigator.userAgent),\n    isArray: function (arr) {\n        return Object.prototype.toString.apply(arr) === '[object Array]';\n    },\n    /*==================================================\n    Browser\n    ====================================================*/\n    browser: {\n        ie: window.navigator.pointerEnabled || window.navigator.msPointerEnabled,\n        ieTouch: (window.navigator.msPointerEnabled && window.navigator.msMaxTouchPoints > 1) || (window.navigator.pointerEnabled && window.navigator.maxTouchPoints > 1)\n    },\n    /*==================================================\n    Devices\n    ====================================================*/\n    device: (function () {\n        var ua = navigator.userAgent;\n        var android = ua.match(/(Android);?[\\s\\/]+([\\d.]+)?/);\n        var ipad = ua.match(/(iPad).*OS\\s([\\d_]+)/);\n        var ipod = ua.match(/(iPod)(.*OS\\s([\\d_]+))?/);\n        var iphone = !ipad && ua.match(/(iPhone\\sOS)\\s([\\d_]+)/);\n        return {\n            ios: ipad || iphone || ipod,\n            android: android\n        };\n    })(),\n    /*==================================================\n    Feature Detection\n    ====================================================*/\n    support: {\n        touch : (window.Modernizr && Modernizr.touch === true) || (function () {\n            return !!(('ontouchstart' in window) || window.DocumentTouch && document instanceof DocumentTouch);\n        })(),\n\n        transforms3d : (window.Modernizr && Modernizr.csstransforms3d === true) || (function () {\n            var div = document.createElement('div').style;\n            return ('webkitPerspective' in div || 'MozPerspective' in div || 'OPerspective' in div || 'MsPerspective' in div || 'perspective' in div);\n        })(),\n\n        flexbox: (function () {\n            var div = document.createElement('div').style;\n            var styles = ('alignItems webkitAlignItems webkitBoxAlign msFlexAlign mozBoxAlign webkitFlexDirection msFlexDirection mozBoxDirection mozBoxOrient webkitBoxDirection webkitBoxOrient').split(' ');\n            for (var i = 0; i < styles.length; i++) {\n                if (styles[i] in div) return true;\n            }\n        })(),\n\n        observer: (function () {\n            return ('MutationObserver' in window || 'WebkitMutationObserver' in window);\n        })()\n    },\n    /*==================================================\n    Plugins\n    ====================================================*/\n    plugins: {}\n};\n"
  },
  {
    "path": "app_backend/static/plugin/Swiper-3.3.1/src/js/wrap-end-umd.js",
    "content": "\treturn Swiper;\n}));"
  },
  {
    "path": "app_backend/static/plugin/Swiper-3.3.1/src/js/wrap-end.js",
    "content": "    window.Swiper = Swiper;\n})();"
  },
  {
    "path": "app_backend/static/plugin/Swiper-3.3.1/src/js/wrap-start-umd.js",
    "content": "(function (root, factory) {\n\t'use strict';\n\n\tif (typeof define === 'function' && define.amd) {\n\t\t// AMD. Register as an anonymous module.\n\t\tdefine(['jquery'], factory);\n\t} else if (typeof exports === 'object') {\n\t\t// Node. Does not work with strict CommonJS, but\n\t\t// only CommonJS-like environments that support module.exports,\n\t\t// like Node.\n\t\tmodule.exports = factory(require('jquery'));\n\t} else {\n\t\t// Browser globals (root is window)\n\t\troot.Swiper = factory(root.jQuery);\n\t}\n}(this, function ($) {\n\t'use strict';\n"
  },
  {
    "path": "app_backend/static/plugin/Swiper-3.3.1/src/js/wrap-start.js",
    "content": "(function () {\n    'use strict';\n    var $;"
  },
  {
    "path": "app_backend/static/plugin/Swiper-3.3.1/src/less/core.less",
    "content": ".swiper-container {\n    margin:0 auto;\n    position:relative;\n    overflow:hidden;\n    /* Fix of Webkit flickering */\n    z-index:1;\n}\n.swiper-container-no-flexbox {\n    .swiper-slide {\n        float: left;\n    }\n}\n.swiper-container-vertical > .swiper-wrapper{\n    -webkit-box-orient: vertical;\n    -moz-box-orient: vertical;\n    -ms-flex-direction: column;\n    -webkit-flex-direction: column;\n    flex-direction: column;\n}\n.swiper-wrapper {\n    position:relative;\n    width: 100%;\n    height: 100%;\n    z-index: 1;\n    display: -webkit-box;\n    display: -moz-box;\n    display: -ms-flexbox;\n    display: -webkit-flex;\n    display: flex;\n\n    -webkit-transition-property:-webkit-transform;\n    -moz-transition-property:-moz-transform;\n    -o-transition-property:-o-transform;\n    -ms-transition-property:-ms-transform;\n    transition-property:transform;\n    \n    -webkit-box-sizing: content-box;\n    -moz-box-sizing: content-box;\n    box-sizing: content-box;\n}\n.swiper-container-android .swiper-slide, .swiper-wrapper {\n    -webkit-transform:translate3d(0px,0,0);\n    -moz-transform:translate3d(0px,0,0);\n    -o-transform:translate(0px,0px);\n    -ms-transform:translate3d(0px,0,0);\n    transform:translate3d(0px,0,0);\n}\n.swiper-container-multirow > .swiper-wrapper {\n    -webkit-box-lines: multiple;\n    -moz-box-lines: multiple;\n    -ms-flex-wrap: wrap;\n    -webkit-flex-wrap: wrap;\n    flex-wrap: wrap;\n}\n.swiper-container-free-mode > .swiper-wrapper {\n    -webkit-transition-timing-function: ease-out;\n    -moz-transition-timing-function: ease-out;\n    -ms-transition-timing-function: ease-out;\n    -o-transition-timing-function: ease-out;\n    transition-timing-function: ease-out;\n    margin: 0 auto;\n}\n.swiper-slide {\n    -webkit-flex-shrink: 0;\n    -ms-flex: 0 0 auto;\n    flex-shrink: 0;\n    width: 100%;\n    height: 100%;\n    position: relative;\n}\n/* Auto Height */\n.swiper-container-autoheight, .swiper-container-autoheight .swiper-slide {\n    height: auto;\n}\n.swiper-container-autoheight .swiper-wrapper {\n    -webkit-box-align: start;\n    -ms-flex-align: start;\n    -webkit-align-items: flex-start;\n    align-items: flex-start;\n    -webkit-transition-property: -webkit-transform, height;\n    -moz-transition-property: -moz-transform;\n    -o-transition-property: -o-transform;\n    -ms-transition-property: -ms-transform;\n    transition-property: transform, height;\n}\n/* a11y */\n.swiper-container .swiper-notification {\n    position: absolute;\n    left: 0;\n    top: 0;\n    pointer-events: none;\n    opacity: 0;\n    z-index: -1000;\n}\n\n/* IE10 Windows Phone 8 Fixes */\n.swiper-wp8-horizontal {\n    -ms-touch-action: pan-y;\n    touch-action: pan-y;\n}\n.swiper-wp8-vertical {\n    -ms-touch-action: pan-x;\n    touch-action: pan-x;\n}"
  },
  {
    "path": "app_backend/static/plugin/Swiper-3.3.1/src/less/effects.less",
    "content": "/* 3D Container */\n.swiper-container-3d {\n    -webkit-perspective: 1200px;\n    -moz-perspective: 1200px;\n    -o-perspective: 1200px;\n    perspective: 1200px;\n    .swiper-wrapper, .swiper-slide, .swiper-slide-shadow-left, .swiper-slide-shadow-right, .swiper-slide-shadow-top, .swiper-slide-shadow-bottom, .swiper-cube-shadow {\n        .preserve3d();\n    }\n    .swiper-slide-shadow-left, .swiper-slide-shadow-right, .swiper-slide-shadow-top, .swiper-slide-shadow-bottom {\n        position: absolute;\n        left: 0;\n        top: 0;\n        width: 100%;\n        height: 100%;\n        pointer-events: none;\n        z-index: 10;\n    }\n    .swiper-slide-shadow-left { \n        background-image: -webkit-gradient(linear, left top, right top, from(rgba(0,0,0,0.5)), to(rgba(0,0,0,0))); /* Safari 4+, Chrome */\n        background-image: -webkit-linear-gradient(right, rgba(0,0,0,0.5), rgba(0,0,0,0)); /* Chrome 10+, Safari 5.1+, iOS 5+ */\n        background-image:    -moz-linear-gradient(right, rgba(0,0,0,0.5), rgba(0,0,0,0)); /* Firefox 3.6-15 */\n        background-image:      -o-linear-gradient(right, rgba(0,0,0,0.5), rgba(0,0,0,0)); /* Opera 11.10-12.00 */\n        background-image:         linear-gradient(to left, rgba(0,0,0,0.5), rgba(0,0,0,0)); /* Firefox 16+, IE10, Opera 12.50+ */\n    }\n    .swiper-slide-shadow-right {    \n        background-image: -webkit-gradient(linear, right top, left top, from(rgba(0,0,0,0.5)), to(rgba(0,0,0,0))); /* Safari 4+, Chrome */\n        background-image: -webkit-linear-gradient(left, rgba(0,0,0,0.5), rgba(0,0,0,0)); /* Chrome 10+, Safari 5.1+, iOS 5+ */\n        background-image:    -moz-linear-gradient(left, rgba(0,0,0,0.5), rgba(0,0,0,0)); /* Firefox 3.6-15 */\n        background-image:      -o-linear-gradient(left, rgba(0,0,0,0.5), rgba(0,0,0,0)); /* Opera 11.10-12.00 */\n        background-image:         linear-gradient(to right, rgba(0,0,0,0.5), rgba(0,0,0,0)); /* Firefox 16+, IE10, Opera 12.50+ */  \n    }\n    .swiper-slide-shadow-top {  \n        background-image: -webkit-gradient(linear, left top, left bottom, from(rgba(0,0,0,0.5)), to(rgba(0,0,0,0))); /* Safari 4+, Chrome */\n        background-image: -webkit-linear-gradient(bottom, rgba(0,0,0,0.5), rgba(0,0,0,0)); /* Chrome 10+, Safari 5.1+, iOS 5+ */\n        background-image:    -moz-linear-gradient(bottom, rgba(0,0,0,0.5), rgba(0,0,0,0)); /* Firefox 3.6-15 */\n        background-image:      -o-linear-gradient(bottom, rgba(0,0,0,0.5), rgba(0,0,0,0)); /* Opera 11.10-12.00 */\n        background-image:         linear-gradient(to top, rgba(0,0,0,0.5), rgba(0,0,0,0)); /* Firefox 16+, IE10, Opera 12.50+ */\n    }\n    .swiper-slide-shadow-bottom {   \n        background-image: -webkit-gradient(linear, left bottom, left top, from(rgba(0,0,0,0.5)), to(rgba(0,0,0,0))); /* Safari 4+, Chrome */\n        background-image: -webkit-linear-gradient(top, rgba(0,0,0,0.5), rgba(0,0,0,0)); /* Chrome 10+, Safari 5.1+, iOS 5+ */\n        background-image:    -moz-linear-gradient(top, rgba(0,0,0,0.5), rgba(0,0,0,0)); /* Firefox 3.6-15 */\n        background-image:      -o-linear-gradient(top, rgba(0,0,0,0.5), rgba(0,0,0,0)); /* Opera 11.10-12.00 */\n        background-image:         linear-gradient(to bottom, rgba(0,0,0,0.5), rgba(0,0,0,0)); /* Firefox 16+, IE10, Opera 12.50+ */\n    }\n}\n/* Coverflow */\n.swiper-container-coverflow, .swiper-container-flip {\n    .swiper-wrapper {\n        /* Windows 8 IE 10 fix */\n        -ms-perspective:1200px;\n    }\n}\n/* Cube + Flip */\n.swiper-container-cube, .swiper-container-flip {\n    overflow: visible;\n    .swiper-slide {\n        pointer-events: none;\n        -webkit-backface-visibility: hidden;\n        -moz-backface-visibility: hidden;\n        -ms-backface-visibility: hidden;\n        backface-visibility: hidden;\n        z-index: 1;\n        .swiper-slide {\n            pointer-events: none;\n        }\n    }\n    .swiper-slide-active {\n        &, & .swiper-slide-active {\n            pointer-events: auto;\n        }\n    }\n    .swiper-slide-shadow-top, .swiper-slide-shadow-bottom, .swiper-slide-shadow-left, .swiper-slide-shadow-right {\n        z-index: 0;\n        -webkit-backface-visibility: hidden;\n        -moz-backface-visibility: hidden;\n        -ms-backface-visibility: hidden;\n        backface-visibility: hidden;\n    }\n}\n/* Cube */\n.swiper-container-cube {\n    .swiper-slide {\n        visibility: hidden;\n        -webkit-transform-origin: 0 0;\n        -moz-transform-origin: 0 0;\n        -ms-transform-origin: 0 0;\n        transform-origin: 0 0;\n        width: 100%;\n        height: 100%;\n    }\n    &.swiper-container-rtl .swiper-slide{\n        -webkit-transform-origin: 100% 0;\n        -moz-transform-origin: 100% 0;\n        -ms-transform-origin: 100% 0;\n        transform-origin: 100% 0;\n    }\n    .swiper-slide-active, .swiper-slide-next, .swiper-slide-prev, .swiper-slide-next + .swiper-slide {\n        pointer-events: auto;\n        visibility: visible;\n    }\n    .swiper-cube-shadow {\n        position: absolute;\n        left: 0;\n        bottom: 0px;\n        width: 100%;\n        height: 100%;\n        background: #000;\n        opacity: 0.6;\n        -webkit-filter: blur(50px);\n        filter: blur(50px);\n        z-index: 0;\n    }\n}\n/* Fade */\n.swiper-container-fade {\n    &.swiper-container-free-mode {\n        .swiper-slide {\n            -webkit-transition-timing-function: ease-out;\n            -moz-transition-timing-function: ease-out;\n            -ms-transition-timing-function: ease-out;\n            -o-transition-timing-function: ease-out;\n            transition-timing-function: ease-out;\n        }\n    }\n    .swiper-slide {\n        pointer-events: none;\n        -webkit-transition-property: opacity;\n        -moz-transition-property: opacity;\n        -o-transition-property: opacity;\n        transition-property: opacity;\n        .swiper-slide {\n            pointer-events: none;\n        }\n    }\n    .swiper-slide-active {\n        &, & .swiper-slide-active {\n            pointer-events: auto;\n        }\n    }\n}"
  },
  {
    "path": "app_backend/static/plugin/Swiper-3.3.1/src/less/mixins.less",
    "content": ".preserve3d() {\n    -webkit-transform-style: preserve-3d;\n    -moz-transform-style: preserve-3d;\n    -ms-transform-style: preserve-3d;\n    transform-style: preserve-3d;\n}\n.encoded-svg-background(@svg) {\n    @url: `encodeURIComponent(@{svg})`;\n    background-image: url(\"data:image/svg+xml;charset=utf-8,@{url}\");\n}"
  },
  {
    "path": "app_backend/static/plugin/Swiper-3.3.1/src/less/navigation-f7.less",
    "content": "/* Arrows */\n.swiper-button-prev, .swiper-button-next {\n    position: absolute;\n    top: 50%;\n    width: 27px;\n    height: 44px;\n    margin-top: -22px;\n    z-index: 10;\n    cursor: pointer;\n    -moz-background-size: 27px 44px;\n    -webkit-background-size: 27px 44px;\n    background-size: 27px 44px;\n    background-position: center;\n    background-repeat: no-repeat;\n    &.swiper-button-disabled {\n        opacity: 0.35;\n        cursor: auto;\n        pointer-events: none;\n    }\n}\n.swiper-button-prev, .swiper-container-rtl .swiper-button-next {\n    .encoded-svg-background(\"<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 27 44'><path d='M0,22L22,0l2.1,2.1L4.2,22l19.9,19.9L22,44L0,22L0,22L0,22z' fill='#007aff'/></svg>\");\n    left: 10px;\n    right: auto;\n}\n.swiper-button-next, .swiper-container-rtl .swiper-button-prev {\n    .encoded-svg-background(\"<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 27 44'><path d='M27,22L27,22L5,44l-2.1-2.1L22.8,22L2.9,2.1L5,0L27,22L27,22z' fill='#007aff'/></svg>\");\n    right: 10px;\n    left: auto;\n}\n\n/* Pagination Styles */\n.swiper-pagination {\n    position: absolute;\n    text-align: center;\n    -webkit-transition: 300ms;\n    -moz-transition: 300ms;\n    -o-transition: 300ms;\n    transition: 300ms;\n    -webkit-transform: translate3d(0,0,0);\n    -ms-transform: translate3d(0,0,0);\n    -o-transform: translate3d(0,0,0);\n    transform: translate3d(0,0,0);\n    z-index: 10;\n    &.swiper-pagination-hidden {\n        opacity: 0;\n    }\n}\n/* Common Styles */\n.swiper-pagination-fraction, .swiper-pagination-custom, .swiper-container-horizontal > .swiper-pagination-bullets{\n    bottom: 10px;\n    left: 0;\n    width: 100%;\n}\n/* Bullets */\n.swiper-pagination-bullet {\n    width: 8px;\n    height: 8px;\n    display: inline-block;\n    border-radius: 100%;\n    background: #000;\n    opacity: 0.2;\n    button& {\n        border: none;\n        margin: 0;\n        padding: 0;\n        box-shadow: none;\n        -moz-appearance: none;\n        -ms-appearance: none;\n        -webkit-appearance: none;\n        appearance: none;\n    }\n    .swiper-pagination-clickable & {\n        cursor: pointer;\n    }\n}\n.swiper-pagination-bullet-active {\n    opacity: 1;\n    background: #007aff;\n}\n.swiper-container-vertical {\n    > .swiper-pagination-bullets {\n        right: 10px;\n        top: 50%;\n        -webkit-transform:translate3d(0px,-50%,0);\n        -moz-transform:translate3d(0px,-50%,0);\n        -o-transform:translate(0px,-50%);\n        -ms-transform:translate3d(0px,-50%,0);\n        transform:translate3d(0px,-50%,0);\n        .swiper-pagination-bullet {\n            margin: 5px 0;\n            display: block;\n        }\n    }\n}\n.swiper-container-horizontal {\n    > .swiper-pagination-bullets {\n        .swiper-pagination-bullet {\n            margin: 0 5px;\n        }\n    }\n}\n/* Progress */\n.swiper-pagination-progress {\n    background: rgba(0,0,0,0.25);\n    position: absolute;\n    .swiper-pagination-progressbar {\n        background: #007aff;\n        position: absolute;\n        left: 0;\n        top: 0;\n        width: 100%;\n        height: 100%;\n        -webkit-transform: scale(0);\n        -ms-transform: scale(0);\n        -o-transform: scale(0);\n        transform: scale(0);\n        -webkit-transform-origin: left top;\n        -moz-transform-origin: left top;\n        -ms-transform-origin: left top;\n        -o-transform-origin: left top;\n        transform-origin: left top;\n    }\n    .swiper-container-rtl & .swiper-pagination-progressbar {\n        -webkit-transform-origin: right top;\n        -moz-transform-origin: right top;\n        -ms-transform-origin: right top;\n        -o-transform-origin: right top;\n        transform-origin: right top;\n    }\n    .swiper-container-horizontal > & {\n        width: 100%;\n        height: 4px;\n        left: 0;\n        top: 0;\n    }\n    .swiper-container-vertical > & {\n        width: 4px;\n        height: 100%;\n        left: 0;\n        top: 0;\n    }\n}"
  },
  {
    "path": "app_backend/static/plugin/Swiper-3.3.1/src/less/navigation.less",
    "content": "/* Arrows */\n.swiper-button-prev, .swiper-button-next {\n    position: absolute;\n    top: 50%;\n    width: 27px;\n    height: 44px;\n    margin-top: -22px;\n    z-index: 10;\n    cursor: pointer;\n    -moz-background-size: 27px 44px;\n    -webkit-background-size: 27px 44px;\n    background-size: 27px 44px;\n    background-position: center;\n    background-repeat: no-repeat;\n    &.swiper-button-disabled {\n        opacity: 0.35;\n        cursor: auto;\n        pointer-events: none;\n    }\n}\n.swiper-button-prev, .swiper-container-rtl .swiper-button-next {\n    .encoded-svg-background(\"<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 27 44'><path d='M0,22L22,0l2.1,2.1L4.2,22l19.9,19.9L22,44L0,22L0,22L0,22z' fill='#007aff'/></svg>\");\n    left: 10px;\n    right: auto;\n    &.swiper-button-black {\n        .encoded-svg-background(\"<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 27 44'><path d='M0,22L22,0l2.1,2.1L4.2,22l19.9,19.9L22,44L0,22L0,22L0,22z' fill='#000000'/></svg>\");\n    }\n    &.swiper-button-white {\n        .encoded-svg-background(\"<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 27 44'><path d='M0,22L22,0l2.1,2.1L4.2,22l19.9,19.9L22,44L0,22L0,22L0,22z' fill='#ffffff'/></svg>\");\n    }\n}\n.swiper-button-next, .swiper-container-rtl .swiper-button-prev {\n    .encoded-svg-background(\"<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 27 44'><path d='M27,22L27,22L5,44l-2.1-2.1L22.8,22L2.9,2.1L5,0L27,22L27,22z' fill='#007aff'/></svg>\");\n    right: 10px;\n    left: auto;\n    &.swiper-button-black {\n        .encoded-svg-background(\"<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 27 44'><path d='M27,22L27,22L5,44l-2.1-2.1L22.8,22L2.9,2.1L5,0L27,22L27,22z' fill='#000000'/></svg>\");\n    }\n    &.swiper-button-white {\n        .encoded-svg-background(\"<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 27 44'><path d='M27,22L27,22L5,44l-2.1-2.1L22.8,22L2.9,2.1L5,0L27,22L27,22z' fill='#ffffff'/></svg>\");\n    }\n}\n/* Pagination Styles */\n.swiper-pagination {\n    position: absolute;\n    text-align: center;\n    -webkit-transition: 300ms;\n    -moz-transition: 300ms;\n    -o-transition: 300ms;\n    transition: 300ms;\n    -webkit-transform: translate3d(0,0,0);\n    -ms-transform: translate3d(0,0,0);\n    -o-transform: translate3d(0,0,0);\n    transform: translate3d(0,0,0);\n    z-index: 10;\n    &.swiper-pagination-hidden {\n        opacity: 0;\n    }\n}\n/* Common Styles */\n.swiper-pagination-fraction, .swiper-pagination-custom, .swiper-container-horizontal > .swiper-pagination-bullets{\n    bottom: 10px;\n    left: 0;\n    width: 100%;\n}\n/* Bullets */\n.swiper-pagination-bullet {\n    width: 8px;\n    height: 8px;\n    display: inline-block;\n    border-radius: 100%;\n    background: #000;\n    opacity: 0.2;\n    button& {\n        border: none;\n        margin: 0;\n        padding: 0;\n        box-shadow: none;\n        -moz-appearance: none;\n        -ms-appearance: none;\n        -webkit-appearance: none;\n        appearance: none;\n    }\n    .swiper-pagination-clickable & {\n        cursor: pointer;\n    }\n    .swiper-pagination-white & {\n        background: #fff;\n    }\n}\n.swiper-pagination-bullet-active {\n    opacity: 1;\n    background: #007aff;\n    .swiper-pagination-white & {\n        background: #fff;\n    }\n    .swiper-pagination-black & {\n        background: #000;\n    }\n}\n.swiper-container-vertical {\n    > .swiper-pagination-bullets {\n        right: 10px;\n        top: 50%;\n        -webkit-transform:translate3d(0px,-50%,0);\n        -moz-transform:translate3d(0px,-50%,0);\n        -o-transform:translate(0px,-50%);\n        -ms-transform:translate3d(0px,-50%,0);\n        transform:translate3d(0px,-50%,0);\n        .swiper-pagination-bullet {\n            margin: 5px 0;\n            display: block;\n        }\n    }\n}\n.swiper-container-horizontal {\n    > .swiper-pagination-bullets {\n        .swiper-pagination-bullet {\n            margin: 0 5px;\n        }\n    }\n}\n/* Progress */\n.swiper-pagination-progress {\n    background: rgba(0,0,0,0.25);\n    position: absolute;\n    .swiper-pagination-progressbar {\n        background: #007aff;\n        position: absolute;\n        left: 0;\n        top: 0;\n        width: 100%;\n        height: 100%;\n        -webkit-transform: scale(0);\n        -ms-transform: scale(0);\n        -o-transform: scale(0);\n        transform: scale(0);\n        -webkit-transform-origin: left top;\n        -moz-transform-origin: left top;\n        -ms-transform-origin: left top;\n        -o-transform-origin: left top;\n        transform-origin: left top;\n    }\n    .swiper-container-rtl & .swiper-pagination-progressbar {\n        -webkit-transform-origin: right top;\n        -moz-transform-origin: right top;\n        -ms-transform-origin: right top;\n        -o-transform-origin: right top;\n        transform-origin: right top;\n    }\n    .swiper-container-horizontal > & {\n        width: 100%;\n        height: 4px;\n        left: 0;\n        top: 0;\n    }\n    .swiper-container-vertical > & {\n        width: 4px;\n        height: 100%;\n        left: 0;\n        top: 0;\n    }\n    &.swiper-pagination-white {\n        background: rgba(255,255,255,0.5);\n        .swiper-pagination-progressbar {\n            background: #fff;\n        }\n    }\n    &.swiper-pagination-black {\n        .swiper-pagination-progressbar {\n            background: #000;\n        }\n    }\n}"
  },
  {
    "path": "app_backend/static/plugin/Swiper-3.3.1/src/less/preloader-f7.less",
    "content": "/* Preloader */\n.swiper-slide .preloader {\n    width: 42px;\n    height: 42px;\n    position: absolute;\n    left: 50%;\n    top: 50%;\n    margin-left: -21px;\n    margin-top: -21px;\n    z-index: 10;\n}"
  },
  {
    "path": "app_backend/static/plugin/Swiper-3.3.1/src/less/preloader.less",
    "content": "/* Preloader */\n.swiper-lazy-preloader {\n    width: 42px;\n    height: 42px;\n    position: absolute;\n    left: 50%;\n    top: 50%;\n    margin-left: -21px;\n    margin-top: -21px;\n    z-index: 10;\n    -webkit-transform-origin: 50%;\n    -moz-transform-origin: 50%;\n    transform-origin: 50%;\n    -webkit-animation: swiper-preloader-spin 1s steps(12, end) infinite;\n    -moz-animation: swiper-preloader-spin 1s steps(12, end) infinite;\n    animation: swiper-preloader-spin 1s steps(12, end) infinite;\n}\n.swiper-lazy-preloader:after {\n    display: block;\n    content: \"\";\n    width: 100%;\n    height: 100%;\n    .encoded-svg-background(\"<svg viewBox='0 0 120 120' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink'><defs><line id='l' x1='60' x2='60' y1='7' y2='27' stroke='#6c6c6c' stroke-width='11' stroke-linecap='round'/></defs><g><use xlink:href='#l' opacity='.27'/><use xlink:href='#l' opacity='.27' transform='rotate(30 60,60)'/><use xlink:href='#l' opacity='.27' transform='rotate(60 60,60)'/><use xlink:href='#l' opacity='.27' transform='rotate(90 60,60)'/><use xlink:href='#l' opacity='.27' transform='rotate(120 60,60)'/><use xlink:href='#l' opacity='.27' transform='rotate(150 60,60)'/><use xlink:href='#l' opacity='.37' transform='rotate(180 60,60)'/><use xlink:href='#l' opacity='.46' transform='rotate(210 60,60)'/><use xlink:href='#l' opacity='.56' transform='rotate(240 60,60)'/><use xlink:href='#l' opacity='.66' transform='rotate(270 60,60)'/><use xlink:href='#l' opacity='.75' transform='rotate(300 60,60)'/><use xlink:href='#l' opacity='.85' transform='rotate(330 60,60)'/></g></svg>\");\n    background-position: 50%;\n    -webkit-background-size: 100%;\n    background-size: 100%;\n    background-repeat: no-repeat;\n    \n}\n.swiper-lazy-preloader-white:after {\n    .encoded-svg-background(\"<svg viewBox='0 0 120 120' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink'><defs><line id='l' x1='60' x2='60' y1='7' y2='27' stroke='#fff' stroke-width='11' stroke-linecap='round'/></defs><g><use xlink:href='#l' opacity='.27'/><use xlink:href='#l' opacity='.27' transform='rotate(30 60,60)'/><use xlink:href='#l' opacity='.27' transform='rotate(60 60,60)'/><use xlink:href='#l' opacity='.27' transform='rotate(90 60,60)'/><use xlink:href='#l' opacity='.27' transform='rotate(120 60,60)'/><use xlink:href='#l' opacity='.27' transform='rotate(150 60,60)'/><use xlink:href='#l' opacity='.37' transform='rotate(180 60,60)'/><use xlink:href='#l' opacity='.46' transform='rotate(210 60,60)'/><use xlink:href='#l' opacity='.56' transform='rotate(240 60,60)'/><use xlink:href='#l' opacity='.66' transform='rotate(270 60,60)'/><use xlink:href='#l' opacity='.75' transform='rotate(300 60,60)'/><use xlink:href='#l' opacity='.85' transform='rotate(330 60,60)'/></g></svg>\");\n}\n@-webkit-keyframes swiper-preloader-spin {\n    100% {\n        -webkit-transform: rotate(360deg);\n    }\n}\n@keyframes swiper-preloader-spin {\n    100% {\n        transform: rotate(360deg);\n    }\n}"
  },
  {
    "path": "app_backend/static/plugin/Swiper-3.3.1/src/less/scrollbar.less",
    "content": "/* Scrollbar */\n.swiper-scrollbar {\n    border-radius: 10px;\n    position: relative;\n    -ms-touch-action: none;\n    background: rgba(0,0,0,0.1);\n    .swiper-container-horizontal > & {\n        position: absolute;\n        left: 1%;\n        bottom: 3px;\n        z-index: 50;\n        height: 5px;\n        width: 98%;\n    }\n    .swiper-container-vertical > & {\n        position: absolute;\n        right: 3px;\n        top: 1%;\n        z-index: 50;\n        width: 5px;\n        height: 98%;\n    }\n}\n.swiper-scrollbar-drag {\n    height: 100%;\n    width: 100%;\n    position: relative;\n    background: rgba(0,0,0,0.5);\n    border-radius: 10px;\n    left: 0;\n    top: 0;\n}\n.swiper-scrollbar-cursor-drag {\n    cursor: move;\n}"
  },
  {
    "path": "app_backend/static/plugin/Swiper-3.3.1/src/less/swiper.less",
    "content": "@import url('mixins.less');\n@import url('core.less');\n@import url('navigation.less');\n@import url('effects.less');\n@import url('scrollbar.less');\n@import url('preloader.less');"
  },
  {
    "path": "app_backend/static/plugin/bootstrap-datepicker-1.6.4/css/bootstrap-datepicker.css",
    "content": "/*!\n * Datepicker for Bootstrap v1.6.4 (https://github.com/eternicode/bootstrap-datepicker)\n *\n * Copyright 2012 Stefan Petre\n * Improvements by Andrew Rowls\n * Licensed under the Apache License v2.0 (http://www.apache.org/licenses/LICENSE-2.0)\n */\n.datepicker {\n  padding: 4px;\n  -webkit-border-radius: 4px;\n  -moz-border-radius: 4px;\n  border-radius: 4px;\n  direction: ltr;\n}\n.datepicker-inline {\n  width: 220px;\n}\n.datepicker.datepicker-rtl {\n  direction: rtl;\n}\n.datepicker.datepicker-rtl table tr td span {\n  float: right;\n}\n.datepicker-dropdown {\n  top: 0;\n  left: 0;\n}\n.datepicker-dropdown:before {\n  content: '';\n  display: inline-block;\n  border-left: 7px solid transparent;\n  border-right: 7px solid transparent;\n  border-bottom: 7px solid #999;\n  border-top: 0;\n  border-bottom-color: rgba(0, 0, 0, 0.2);\n  position: absolute;\n}\n.datepicker-dropdown:after {\n  content: '';\n  display: inline-block;\n  border-left: 6px solid transparent;\n  border-right: 6px solid transparent;\n  border-bottom: 6px solid #fff;\n  border-top: 0;\n  position: absolute;\n}\n.datepicker-dropdown.datepicker-orient-left:before {\n  left: 6px;\n}\n.datepicker-dropdown.datepicker-orient-left:after {\n  left: 7px;\n}\n.datepicker-dropdown.datepicker-orient-right:before {\n  right: 6px;\n}\n.datepicker-dropdown.datepicker-orient-right:after {\n  right: 7px;\n}\n.datepicker-dropdown.datepicker-orient-bottom:before {\n  top: -7px;\n}\n.datepicker-dropdown.datepicker-orient-bottom:after {\n  top: -6px;\n}\n.datepicker-dropdown.datepicker-orient-top:before {\n  bottom: -7px;\n  border-bottom: 0;\n  border-top: 7px solid #999;\n}\n.datepicker-dropdown.datepicker-orient-top:after {\n  bottom: -6px;\n  border-bottom: 0;\n  border-top: 6px solid #fff;\n}\n.datepicker table {\n  margin: 0;\n  -webkit-touch-callout: none;\n  -webkit-user-select: none;\n  -khtml-user-select: none;\n  -moz-user-select: none;\n  -ms-user-select: none;\n  user-select: none;\n}\n.datepicker td,\n.datepicker th {\n  text-align: center;\n  width: 20px;\n  height: 20px;\n  -webkit-border-radius: 4px;\n  -moz-border-radius: 4px;\n  border-radius: 4px;\n  border: none;\n}\n.table-striped .datepicker table tr td,\n.table-striped .datepicker table tr th {\n  background-color: transparent;\n}\n.datepicker table tr td.day:hover,\n.datepicker table tr td.day.focused {\n  background: #eee;\n  cursor: pointer;\n}\n.datepicker table tr td.old,\n.datepicker table tr td.new {\n  color: #999;\n}\n.datepicker table tr td.disabled,\n.datepicker table tr td.disabled:hover {\n  background: none;\n  color: #999;\n  cursor: default;\n}\n.datepicker table tr td.highlighted {\n  background: #d9edf7;\n  border-radius: 0;\n}\n.datepicker table tr td.today,\n.datepicker table tr td.today:hover,\n.datepicker table tr td.today.disabled,\n.datepicker table tr td.today.disabled:hover {\n  background-color: #fde19a;\n  background-image: -moz-linear-gradient(to bottom, #fdd49a, #fdf59a);\n  background-image: -ms-linear-gradient(to bottom, #fdd49a, #fdf59a);\n  background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#fdd49a), to(#fdf59a));\n  background-image: -webkit-linear-gradient(to bottom, #fdd49a, #fdf59a);\n  background-image: -o-linear-gradient(to bottom, #fdd49a, #fdf59a);\n  background-image: linear-gradient(to bottom, #fdd49a, #fdf59a);\n  background-repeat: repeat-x;\n  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fdd49a', endColorstr='#fdf59a', GradientType=0);\n  border-color: #fdf59a #fdf59a #fbed50;\n  border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);\n  filter: progid:DXImageTransform.Microsoft.gradient(enabled=false);\n  color: #000;\n}\n.datepicker table tr td.today:hover,\n.datepicker table tr td.today:hover:hover,\n.datepicker table tr td.today.disabled:hover,\n.datepicker table tr td.today.disabled:hover:hover,\n.datepicker table tr td.today:active,\n.datepicker table tr td.today:hover:active,\n.datepicker table tr td.today.disabled:active,\n.datepicker table tr td.today.disabled:hover:active,\n.datepicker table tr td.today.active,\n.datepicker table tr td.today:hover.active,\n.datepicker table tr td.today.disabled.active,\n.datepicker table tr td.today.disabled:hover.active,\n.datepicker table tr td.today.disabled,\n.datepicker table tr td.today:hover.disabled,\n.datepicker table tr td.today.disabled.disabled,\n.datepicker table tr td.today.disabled:hover.disabled,\n.datepicker table tr td.today[disabled],\n.datepicker table tr td.today:hover[disabled],\n.datepicker table tr td.today.disabled[disabled],\n.datepicker table tr td.today.disabled:hover[disabled] {\n  background-color: #fdf59a;\n}\n.datepicker table tr td.today:active,\n.datepicker table tr td.today:hover:active,\n.datepicker table tr td.today.disabled:active,\n.datepicker table tr td.today.disabled:hover:active,\n.datepicker table tr td.today.active,\n.datepicker table tr td.today:hover.active,\n.datepicker table tr td.today.disabled.active,\n.datepicker table tr td.today.disabled:hover.active {\n  background-color: #fbf069 \\9;\n}\n.datepicker table tr td.today:hover:hover {\n  color: #000;\n}\n.datepicker table tr td.today.active:hover {\n  color: #fff;\n}\n.datepicker table tr td.range,\n.datepicker table tr td.range:hover,\n.datepicker table tr td.range.disabled,\n.datepicker table tr td.range.disabled:hover {\n  background: #eee;\n  -webkit-border-radius: 0;\n  -moz-border-radius: 0;\n  border-radius: 0;\n}\n.datepicker table tr td.range.today,\n.datepicker table tr td.range.today:hover,\n.datepicker table tr td.range.today.disabled,\n.datepicker table tr td.range.today.disabled:hover {\n  background-color: #f3d17a;\n  background-image: -moz-linear-gradient(to bottom, #f3c17a, #f3e97a);\n  background-image: -ms-linear-gradient(to bottom, #f3c17a, #f3e97a);\n  background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#f3c17a), to(#f3e97a));\n  background-image: -webkit-linear-gradient(to bottom, #f3c17a, #f3e97a);\n  background-image: -o-linear-gradient(to bottom, #f3c17a, #f3e97a);\n  background-image: linear-gradient(to bottom, #f3c17a, #f3e97a);\n  background-repeat: repeat-x;\n  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#f3c17a', endColorstr='#f3e97a', GradientType=0);\n  border-color: #f3e97a #f3e97a #edde34;\n  border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);\n  filter: progid:DXImageTransform.Microsoft.gradient(enabled=false);\n  -webkit-border-radius: 0;\n  -moz-border-radius: 0;\n  border-radius: 0;\n}\n.datepicker table tr td.range.today:hover,\n.datepicker table tr td.range.today:hover:hover,\n.datepicker table tr td.range.today.disabled:hover,\n.datepicker table tr td.range.today.disabled:hover:hover,\n.datepicker table tr td.range.today:active,\n.datepicker table tr td.range.today:hover:active,\n.datepicker table tr td.range.today.disabled:active,\n.datepicker table tr td.range.today.disabled:hover:active,\n.datepicker table tr td.range.today.active,\n.datepicker table tr td.range.today:hover.active,\n.datepicker table tr td.range.today.disabled.active,\n.datepicker table tr td.range.today.disabled:hover.active,\n.datepicker table tr td.range.today.disabled,\n.datepicker table tr td.range.today:hover.disabled,\n.datepicker table tr td.range.today.disabled.disabled,\n.datepicker table tr td.range.today.disabled:hover.disabled,\n.datepicker table tr td.range.today[disabled],\n.datepicker table tr td.range.today:hover[disabled],\n.datepicker table tr td.range.today.disabled[disabled],\n.datepicker table tr td.range.today.disabled:hover[disabled] {\n  background-color: #f3e97a;\n}\n.datepicker table tr td.range.today:active,\n.datepicker table tr td.range.today:hover:active,\n.datepicker table tr td.range.today.disabled:active,\n.datepicker table tr td.range.today.disabled:hover:active,\n.datepicker table tr td.range.today.active,\n.datepicker table tr td.range.today:hover.active,\n.datepicker table tr td.range.today.disabled.active,\n.datepicker table tr td.range.today.disabled:hover.active {\n  background-color: #efe24b \\9;\n}\n.datepicker table tr td.selected,\n.datepicker table tr td.selected:hover,\n.datepicker table tr td.selected.disabled,\n.datepicker table tr td.selected.disabled:hover {\n  background-color: #9e9e9e;\n  background-image: -moz-linear-gradient(to bottom, #b3b3b3, #808080);\n  background-image: -ms-linear-gradient(to bottom, #b3b3b3, #808080);\n  background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#b3b3b3), to(#808080));\n  background-image: -webkit-linear-gradient(to bottom, #b3b3b3, #808080);\n  background-image: -o-linear-gradient(to bottom, #b3b3b3, #808080);\n  background-image: linear-gradient(to bottom, #b3b3b3, #808080);\n  background-repeat: repeat-x;\n  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#b3b3b3', endColorstr='#808080', GradientType=0);\n  border-color: #808080 #808080 #595959;\n  border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);\n  filter: progid:DXImageTransform.Microsoft.gradient(enabled=false);\n  color: #fff;\n  text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25);\n}\n.datepicker table tr td.selected:hover,\n.datepicker table tr td.selected:hover:hover,\n.datepicker table tr td.selected.disabled:hover,\n.datepicker table tr td.selected.disabled:hover:hover,\n.datepicker table tr td.selected:active,\n.datepicker table tr td.selected:hover:active,\n.datepicker table tr td.selected.disabled:active,\n.datepicker table tr td.selected.disabled:hover:active,\n.datepicker table tr td.selected.active,\n.datepicker table tr td.selected:hover.active,\n.datepicker table tr td.selected.disabled.active,\n.datepicker table tr td.selected.disabled:hover.active,\n.datepicker table tr td.selected.disabled,\n.datepicker table tr td.selected:hover.disabled,\n.datepicker table tr td.selected.disabled.disabled,\n.datepicker table tr td.selected.disabled:hover.disabled,\n.datepicker table tr td.selected[disabled],\n.datepicker table tr td.selected:hover[disabled],\n.datepicker table tr td.selected.disabled[disabled],\n.datepicker table tr td.selected.disabled:hover[disabled] {\n  background-color: #808080;\n}\n.datepicker table tr td.selected:active,\n.datepicker table tr td.selected:hover:active,\n.datepicker table tr td.selected.disabled:active,\n.datepicker table tr td.selected.disabled:hover:active,\n.datepicker table tr td.selected.active,\n.datepicker table tr td.selected:hover.active,\n.datepicker table tr td.selected.disabled.active,\n.datepicker table tr td.selected.disabled:hover.active {\n  background-color: #666666 \\9;\n}\n.datepicker table tr td.active,\n.datepicker table tr td.active:hover,\n.datepicker table tr td.active.disabled,\n.datepicker table tr td.active.disabled:hover {\n  background-color: #006dcc;\n  background-image: -moz-linear-gradient(to bottom, #08c, #0044cc);\n  background-image: -ms-linear-gradient(to bottom, #08c, #0044cc);\n  background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#08c), to(#0044cc));\n  background-image: -webkit-linear-gradient(to bottom, #08c, #0044cc);\n  background-image: -o-linear-gradient(to bottom, #08c, #0044cc);\n  background-image: linear-gradient(to bottom, #08c, #0044cc);\n  background-repeat: repeat-x;\n  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#08c', endColorstr='#0044cc', GradientType=0);\n  border-color: #0044cc #0044cc #002a80;\n  border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);\n  filter: progid:DXImageTransform.Microsoft.gradient(enabled=false);\n  color: #fff;\n  text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25);\n}\n.datepicker table tr td.active:hover,\n.datepicker table tr td.active:hover:hover,\n.datepicker table tr td.active.disabled:hover,\n.datepicker table tr td.active.disabled:hover:hover,\n.datepicker table tr td.active:active,\n.datepicker table tr td.active:hover:active,\n.datepicker table tr td.active.disabled:active,\n.datepicker table tr td.active.disabled:hover:active,\n.datepicker table tr td.active.active,\n.datepicker table tr td.active:hover.active,\n.datepicker table tr td.active.disabled.active,\n.datepicker table tr td.active.disabled:hover.active,\n.datepicker table tr td.active.disabled,\n.datepicker table tr td.active:hover.disabled,\n.datepicker table tr td.active.disabled.disabled,\n.datepicker table tr td.active.disabled:hover.disabled,\n.datepicker table tr td.active[disabled],\n.datepicker table tr td.active:hover[disabled],\n.datepicker table tr td.active.disabled[disabled],\n.datepicker table tr td.active.disabled:hover[disabled] {\n  background-color: #0044cc;\n}\n.datepicker table tr td.active:active,\n.datepicker table tr td.active:hover:active,\n.datepicker table tr td.active.disabled:active,\n.datepicker table tr td.active.disabled:hover:active,\n.datepicker table tr td.active.active,\n.datepicker table tr td.active:hover.active,\n.datepicker table tr td.active.disabled.active,\n.datepicker table tr td.active.disabled:hover.active {\n  background-color: #003399 \\9;\n}\n.datepicker table tr td span {\n  display: block;\n  width: 23%;\n  height: 54px;\n  line-height: 54px;\n  float: left;\n  margin: 1%;\n  cursor: pointer;\n  -webkit-border-radius: 4px;\n  -moz-border-radius: 4px;\n  border-radius: 4px;\n}\n.datepicker table tr td span:hover,\n.datepicker table tr td span.focused {\n  background: #eee;\n}\n.datepicker table tr td span.disabled,\n.datepicker table tr td span.disabled:hover {\n  background: none;\n  color: #999;\n  cursor: default;\n}\n.datepicker table tr td span.active,\n.datepicker table tr td span.active:hover,\n.datepicker table tr td span.active.disabled,\n.datepicker table tr td span.active.disabled:hover {\n  background-color: #006dcc;\n  background-image: -moz-linear-gradient(to bottom, #08c, #0044cc);\n  background-image: -ms-linear-gradient(to bottom, #08c, #0044cc);\n  background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#08c), to(#0044cc));\n  background-image: -webkit-linear-gradient(to bottom, #08c, #0044cc);\n  background-image: -o-linear-gradient(to bottom, #08c, #0044cc);\n  background-image: linear-gradient(to bottom, #08c, #0044cc);\n  background-repeat: repeat-x;\n  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#08c', endColorstr='#0044cc', GradientType=0);\n  border-color: #0044cc #0044cc #002a80;\n  border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);\n  filter: progid:DXImageTransform.Microsoft.gradient(enabled=false);\n  color: #fff;\n  text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25);\n}\n.datepicker table tr td span.active:hover,\n.datepicker table tr td span.active:hover:hover,\n.datepicker table tr td span.active.disabled:hover,\n.datepicker table tr td span.active.disabled:hover:hover,\n.datepicker table tr td span.active:active,\n.datepicker table tr td span.active:hover:active,\n.datepicker table tr td span.active.disabled:active,\n.datepicker table tr td span.active.disabled:hover:active,\n.datepicker table tr td span.active.active,\n.datepicker table tr td span.active:hover.active,\n.datepicker table tr td span.active.disabled.active,\n.datepicker table tr td span.active.disabled:hover.active,\n.datepicker table tr td span.active.disabled,\n.datepicker table tr td span.active:hover.disabled,\n.datepicker table tr td span.active.disabled.disabled,\n.datepicker table tr td span.active.disabled:hover.disabled,\n.datepicker table tr td span.active[disabled],\n.datepicker table tr td span.active:hover[disabled],\n.datepicker table tr td span.active.disabled[disabled],\n.datepicker table tr td span.active.disabled:hover[disabled] {\n  background-color: #0044cc;\n}\n.datepicker table tr td span.active:active,\n.datepicker table tr td span.active:hover:active,\n.datepicker table tr td span.active.disabled:active,\n.datepicker table tr td span.active.disabled:hover:active,\n.datepicker table tr td span.active.active,\n.datepicker table tr td span.active:hover.active,\n.datepicker table tr td span.active.disabled.active,\n.datepicker table tr td span.active.disabled:hover.active {\n  background-color: #003399 \\9;\n}\n.datepicker table tr td span.old,\n.datepicker table tr td span.new {\n  color: #999;\n}\n.datepicker .datepicker-switch {\n  width: 145px;\n}\n.datepicker .datepicker-switch,\n.datepicker .prev,\n.datepicker .next,\n.datepicker tfoot tr th {\n  cursor: pointer;\n}\n.datepicker .datepicker-switch:hover,\n.datepicker .prev:hover,\n.datepicker .next:hover,\n.datepicker tfoot tr th:hover {\n  background: #eee;\n}\n.datepicker .cw {\n  font-size: 10px;\n  width: 12px;\n  padding: 0 2px 0 5px;\n  vertical-align: middle;\n}\n.input-append.date .add-on,\n.input-prepend.date .add-on {\n  cursor: pointer;\n}\n.input-append.date .add-on i,\n.input-prepend.date .add-on i {\n  margin-top: 3px;\n}\n.input-daterange input {\n  text-align: center;\n}\n.input-daterange input:first-child {\n  -webkit-border-radius: 3px 0 0 3px;\n  -moz-border-radius: 3px 0 0 3px;\n  border-radius: 3px 0 0 3px;\n}\n.input-daterange input:last-child {\n  -webkit-border-radius: 0 3px 3px 0;\n  -moz-border-radius: 0 3px 3px 0;\n  border-radius: 0 3px 3px 0;\n}\n.input-daterange .add-on {\n  display: inline-block;\n  width: auto;\n  min-width: 16px;\n  height: 18px;\n  padding: 4px 5px;\n  font-weight: normal;\n  line-height: 18px;\n  text-align: center;\n  text-shadow: 0 1px 0 #fff;\n  vertical-align: middle;\n  background-color: #eee;\n  border: 1px solid #ccc;\n  margin-left: -5px;\n  margin-right: -5px;\n}\n/*# sourceMappingURL=bootstrap-datepicker.css.map */"
  },
  {
    "path": "app_backend/static/plugin/bootstrap-datepicker-1.6.4/css/bootstrap-datepicker.standalone.css",
    "content": "/*!\n * Datepicker for Bootstrap v1.6.4 (https://github.com/eternicode/bootstrap-datepicker)\n *\n * Copyright 2012 Stefan Petre\n * Improvements by Andrew Rowls\n * Licensed under the Apache License v2.0 (http://www.apache.org/licenses/LICENSE-2.0)\n */\n.datepicker {\n  padding: 4px;\n  -webkit-border-radius: 4px;\n  -moz-border-radius: 4px;\n  border-radius: 4px;\n  direction: ltr;\n}\n.datepicker-inline {\n  width: 220px;\n}\n.datepicker.datepicker-rtl {\n  direction: rtl;\n}\n.datepicker.datepicker-rtl table tr td span {\n  float: right;\n}\n.datepicker-dropdown {\n  top: 0;\n  left: 0;\n}\n.datepicker-dropdown:before {\n  content: '';\n  display: inline-block;\n  border-left: 7px solid transparent;\n  border-right: 7px solid transparent;\n  border-bottom: 7px solid #999;\n  border-top: 0;\n  border-bottom-color: rgba(0, 0, 0, 0.2);\n  position: absolute;\n}\n.datepicker-dropdown:after {\n  content: '';\n  display: inline-block;\n  border-left: 6px solid transparent;\n  border-right: 6px solid transparent;\n  border-bottom: 6px solid #fff;\n  border-top: 0;\n  position: absolute;\n}\n.datepicker-dropdown.datepicker-orient-left:before {\n  left: 6px;\n}\n.datepicker-dropdown.datepicker-orient-left:after {\n  left: 7px;\n}\n.datepicker-dropdown.datepicker-orient-right:before {\n  right: 6px;\n}\n.datepicker-dropdown.datepicker-orient-right:after {\n  right: 7px;\n}\n.datepicker-dropdown.datepicker-orient-bottom:before {\n  top: -7px;\n}\n.datepicker-dropdown.datepicker-orient-bottom:after {\n  top: -6px;\n}\n.datepicker-dropdown.datepicker-orient-top:before {\n  bottom: -7px;\n  border-bottom: 0;\n  border-top: 7px solid #999;\n}\n.datepicker-dropdown.datepicker-orient-top:after {\n  bottom: -6px;\n  border-bottom: 0;\n  border-top: 6px solid #fff;\n}\n.datepicker table {\n  margin: 0;\n  -webkit-touch-callout: none;\n  -webkit-user-select: none;\n  -khtml-user-select: none;\n  -moz-user-select: none;\n  -ms-user-select: none;\n  user-select: none;\n}\n.datepicker td,\n.datepicker th {\n  text-align: center;\n  width: 20px;\n  height: 20px;\n  -webkit-border-radius: 4px;\n  -moz-border-radius: 4px;\n  border-radius: 4px;\n  border: none;\n}\n.table-striped .datepicker table tr td,\n.table-striped .datepicker table tr th {\n  background-color: transparent;\n}\n.datepicker table tr td.day:hover,\n.datepicker table tr td.day.focused {\n  background: #eee;\n  cursor: pointer;\n}\n.datepicker table tr td.old,\n.datepicker table tr td.new {\n  color: #999;\n}\n.datepicker table tr td.disabled,\n.datepicker table tr td.disabled:hover {\n  background: none;\n  color: #999;\n  cursor: default;\n}\n.datepicker table tr td.highlighted {\n  background: #d9edf7;\n  border-radius: 0;\n}\n.datepicker table tr td.today,\n.datepicker table tr td.today:hover,\n.datepicker table tr td.today.disabled,\n.datepicker table tr td.today.disabled:hover {\n  background-color: #fde19a;\n  background-image: -moz-linear-gradient(to bottom, #fdd49a, #fdf59a);\n  background-image: -ms-linear-gradient(to bottom, #fdd49a, #fdf59a);\n  background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#fdd49a), to(#fdf59a));\n  background-image: -webkit-linear-gradient(to bottom, #fdd49a, #fdf59a);\n  background-image: -o-linear-gradient(to bottom, #fdd49a, #fdf59a);\n  background-image: linear-gradient(to bottom, #fdd49a, #fdf59a);\n  background-repeat: repeat-x;\n  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fdd49a', endColorstr='#fdf59a', GradientType=0);\n  border-color: #fdf59a #fdf59a #fbed50;\n  border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);\n  filter: progid:DXImageTransform.Microsoft.gradient(enabled=false);\n  color: #000;\n}\n.datepicker table tr td.today:hover,\n.datepicker table tr td.today:hover:hover,\n.datepicker table tr td.today.disabled:hover,\n.datepicker table tr td.today.disabled:hover:hover,\n.datepicker table tr td.today:active,\n.datepicker table tr td.today:hover:active,\n.datepicker table tr td.today.disabled:active,\n.datepicker table tr td.today.disabled:hover:active,\n.datepicker table tr td.today.active,\n.datepicker table tr td.today:hover.active,\n.datepicker table tr td.today.disabled.active,\n.datepicker table tr td.today.disabled:hover.active,\n.datepicker table tr td.today.disabled,\n.datepicker table tr td.today:hover.disabled,\n.datepicker table tr td.today.disabled.disabled,\n.datepicker table tr td.today.disabled:hover.disabled,\n.datepicker table tr td.today[disabled],\n.datepicker table tr td.today:hover[disabled],\n.datepicker table tr td.today.disabled[disabled],\n.datepicker table tr td.today.disabled:hover[disabled] {\n  background-color: #fdf59a;\n}\n.datepicker table tr td.today:active,\n.datepicker table tr td.today:hover:active,\n.datepicker table tr td.today.disabled:active,\n.datepicker table tr td.today.disabled:hover:active,\n.datepicker table tr td.today.active,\n.datepicker table tr td.today:hover.active,\n.datepicker table tr td.today.disabled.active,\n.datepicker table tr td.today.disabled:hover.active {\n  background-color: #fbf069 \\9;\n}\n.datepicker table tr td.today:hover:hover {\n  color: #000;\n}\n.datepicker table tr td.today.active:hover {\n  color: #fff;\n}\n.datepicker table tr td.range,\n.datepicker table tr td.range:hover,\n.datepicker table tr td.range.disabled,\n.datepicker table tr td.range.disabled:hover {\n  background: #eee;\n  -webkit-border-radius: 0;\n  -moz-border-radius: 0;\n  border-radius: 0;\n}\n.datepicker table tr td.range.today,\n.datepicker table tr td.range.today:hover,\n.datepicker table tr td.range.today.disabled,\n.datepicker table tr td.range.today.disabled:hover {\n  background-color: #f3d17a;\n  background-image: -moz-linear-gradient(to bottom, #f3c17a, #f3e97a);\n  background-image: -ms-linear-gradient(to bottom, #f3c17a, #f3e97a);\n  background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#f3c17a), to(#f3e97a));\n  background-image: -webkit-linear-gradient(to bottom, #f3c17a, #f3e97a);\n  background-image: -o-linear-gradient(to bottom, #f3c17a, #f3e97a);\n  background-image: linear-gradient(to bottom, #f3c17a, #f3e97a);\n  background-repeat: repeat-x;\n  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#f3c17a', endColorstr='#f3e97a', GradientType=0);\n  border-color: #f3e97a #f3e97a #edde34;\n  border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);\n  filter: progid:DXImageTransform.Microsoft.gradient(enabled=false);\n  -webkit-border-radius: 0;\n  -moz-border-radius: 0;\n  border-radius: 0;\n}\n.datepicker table tr td.range.today:hover,\n.datepicker table tr td.range.today:hover:hover,\n.datepicker table tr td.range.today.disabled:hover,\n.datepicker table tr td.range.today.disabled:hover:hover,\n.datepicker table tr td.range.today:active,\n.datepicker table tr td.range.today:hover:active,\n.datepicker table tr td.range.today.disabled:active,\n.datepicker table tr td.range.today.disabled:hover:active,\n.datepicker table tr td.range.today.active,\n.datepicker table tr td.range.today:hover.active,\n.datepicker table tr td.range.today.disabled.active,\n.datepicker table tr td.range.today.disabled:hover.active,\n.datepicker table tr td.range.today.disabled,\n.datepicker table tr td.range.today:hover.disabled,\n.datepicker table tr td.range.today.disabled.disabled,\n.datepicker table tr td.range.today.disabled:hover.disabled,\n.datepicker table tr td.range.today[disabled],\n.datepicker table tr td.range.today:hover[disabled],\n.datepicker table tr td.range.today.disabled[disabled],\n.datepicker table tr td.range.today.disabled:hover[disabled] {\n  background-color: #f3e97a;\n}\n.datepicker table tr td.range.today:active,\n.datepicker table tr td.range.today:hover:active,\n.datepicker table tr td.range.today.disabled:active,\n.datepicker table tr td.range.today.disabled:hover:active,\n.datepicker table tr td.range.today.active,\n.datepicker table tr td.range.today:hover.active,\n.datepicker table tr td.range.today.disabled.active,\n.datepicker table tr td.range.today.disabled:hover.active {\n  background-color: #efe24b \\9;\n}\n.datepicker table tr td.selected,\n.datepicker table tr td.selected:hover,\n.datepicker table tr td.selected.disabled,\n.datepicker table tr td.selected.disabled:hover {\n  background-color: #9e9e9e;\n  background-image: -moz-linear-gradient(to bottom, #b3b3b3, #808080);\n  background-image: -ms-linear-gradient(to bottom, #b3b3b3, #808080);\n  background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#b3b3b3), to(#808080));\n  background-image: -webkit-linear-gradient(to bottom, #b3b3b3, #808080);\n  background-image: -o-linear-gradient(to bottom, #b3b3b3, #808080);\n  background-image: linear-gradient(to bottom, #b3b3b3, #808080);\n  background-repeat: repeat-x;\n  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#b3b3b3', endColorstr='#808080', GradientType=0);\n  border-color: #808080 #808080 #595959;\n  border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);\n  filter: progid:DXImageTransform.Microsoft.gradient(enabled=false);\n  color: #fff;\n  text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25);\n}\n.datepicker table tr td.selected:hover,\n.datepicker table tr td.selected:hover:hover,\n.datepicker table tr td.selected.disabled:hover,\n.datepicker table tr td.selected.disabled:hover:hover,\n.datepicker table tr td.selected:active,\n.datepicker table tr td.selected:hover:active,\n.datepicker table tr td.selected.disabled:active,\n.datepicker table tr td.selected.disabled:hover:active,\n.datepicker table tr td.selected.active,\n.datepicker table tr td.selected:hover.active,\n.datepicker table tr td.selected.disabled.active,\n.datepicker table tr td.selected.disabled:hover.active,\n.datepicker table tr td.selected.disabled,\n.datepicker table tr td.selected:hover.disabled,\n.datepicker table tr td.selected.disabled.disabled,\n.datepicker table tr td.selected.disabled:hover.disabled,\n.datepicker table tr td.selected[disabled],\n.datepicker table tr td.selected:hover[disabled],\n.datepicker table tr td.selected.disabled[disabled],\n.datepicker table tr td.selected.disabled:hover[disabled] {\n  background-color: #808080;\n}\n.datepicker table tr td.selected:active,\n.datepicker table tr td.selected:hover:active,\n.datepicker table tr td.selected.disabled:active,\n.datepicker table tr td.selected.disabled:hover:active,\n.datepicker table tr td.selected.active,\n.datepicker table tr td.selected:hover.active,\n.datepicker table tr td.selected.disabled.active,\n.datepicker table tr td.selected.disabled:hover.active {\n  background-color: #666666 \\9;\n}\n.datepicker table tr td.active,\n.datepicker table tr td.active:hover,\n.datepicker table tr td.active.disabled,\n.datepicker table tr td.active.disabled:hover {\n  background-color: #006dcc;\n  background-image: -moz-linear-gradient(to bottom, #08c, #0044cc);\n  background-image: -ms-linear-gradient(to bottom, #08c, #0044cc);\n  background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#08c), to(#0044cc));\n  background-image: -webkit-linear-gradient(to bottom, #08c, #0044cc);\n  background-image: -o-linear-gradient(to bottom, #08c, #0044cc);\n  background-image: linear-gradient(to bottom, #08c, #0044cc);\n  background-repeat: repeat-x;\n  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#08c', endColorstr='#0044cc', GradientType=0);\n  border-color: #0044cc #0044cc #002a80;\n  border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);\n  filter: progid:DXImageTransform.Microsoft.gradient(enabled=false);\n  color: #fff;\n  text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25);\n}\n.datepicker table tr td.active:hover,\n.datepicker table tr td.active:hover:hover,\n.datepicker table tr td.active.disabled:hover,\n.datepicker table tr td.active.disabled:hover:hover,\n.datepicker table tr td.active:active,\n.datepicker table tr td.active:hover:active,\n.datepicker table tr td.active.disabled:active,\n.datepicker table tr td.active.disabled:hover:active,\n.datepicker table tr td.active.active,\n.datepicker table tr td.active:hover.active,\n.datepicker table tr td.active.disabled.active,\n.datepicker table tr td.active.disabled:hover.active,\n.datepicker table tr td.active.disabled,\n.datepicker table tr td.active:hover.disabled,\n.datepicker table tr td.active.disabled.disabled,\n.datepicker table tr td.active.disabled:hover.disabled,\n.datepicker table tr td.active[disabled],\n.datepicker table tr td.active:hover[disabled],\n.datepicker table tr td.active.disabled[disabled],\n.datepicker table tr td.active.disabled:hover[disabled] {\n  background-color: #0044cc;\n}\n.datepicker table tr td.active:active,\n.datepicker table tr td.active:hover:active,\n.datepicker table tr td.active.disabled:active,\n.datepicker table tr td.active.disabled:hover:active,\n.datepicker table tr td.active.active,\n.datepicker table tr td.active:hover.active,\n.datepicker table tr td.active.disabled.active,\n.datepicker table tr td.active.disabled:hover.active {\n  background-color: #003399 \\9;\n}\n.datepicker table tr td span {\n  display: block;\n  width: 23%;\n  height: 54px;\n  line-height: 54px;\n  float: left;\n  margin: 1%;\n  cursor: pointer;\n  -webkit-border-radius: 4px;\n  -moz-border-radius: 4px;\n  border-radius: 4px;\n}\n.datepicker table tr td span:hover,\n.datepicker table tr td span.focused {\n  background: #eee;\n}\n.datepicker table tr td span.disabled,\n.datepicker table tr td span.disabled:hover {\n  background: none;\n  color: #999;\n  cursor: default;\n}\n.datepicker table tr td span.active,\n.datepicker table tr td span.active:hover,\n.datepicker table tr td span.active.disabled,\n.datepicker table tr td span.active.disabled:hover {\n  background-color: #006dcc;\n  background-image: -moz-linear-gradient(to bottom, #08c, #0044cc);\n  background-image: -ms-linear-gradient(to bottom, #08c, #0044cc);\n  background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#08c), to(#0044cc));\n  background-image: -webkit-linear-gradient(to bottom, #08c, #0044cc);\n  background-image: -o-linear-gradient(to bottom, #08c, #0044cc);\n  background-image: linear-gradient(to bottom, #08c, #0044cc);\n  background-repeat: repeat-x;\n  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#08c', endColorstr='#0044cc', GradientType=0);\n  border-color: #0044cc #0044cc #002a80;\n  border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);\n  filter: progid:DXImageTransform.Microsoft.gradient(enabled=false);\n  color: #fff;\n  text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25);\n}\n.datepicker table tr td span.active:hover,\n.datepicker table tr td span.active:hover:hover,\n.datepicker table tr td span.active.disabled:hover,\n.datepicker table tr td span.active.disabled:hover:hover,\n.datepicker table tr td span.active:active,\n.datepicker table tr td span.active:hover:active,\n.datepicker table tr td span.active.disabled:active,\n.datepicker table tr td span.active.disabled:hover:active,\n.datepicker table tr td span.active.active,\n.datepicker table tr td span.active:hover.active,\n.datepicker table tr td span.active.disabled.active,\n.datepicker table tr td span.active.disabled:hover.active,\n.datepicker table tr td span.active.disabled,\n.datepicker table tr td span.active:hover.disabled,\n.datepicker table tr td span.active.disabled.disabled,\n.datepicker table tr td span.active.disabled:hover.disabled,\n.datepicker table tr td span.active[disabled],\n.datepicker table tr td span.active:hover[disabled],\n.datepicker table tr td span.active.disabled[disabled],\n.datepicker table tr td span.active.disabled:hover[disabled] {\n  background-color: #0044cc;\n}\n.datepicker table tr td span.active:active,\n.datepicker table tr td span.active:hover:active,\n.datepicker table tr td span.active.disabled:active,\n.datepicker table tr td span.active.disabled:hover:active,\n.datepicker table tr td span.active.active,\n.datepicker table tr td span.active:hover.active,\n.datepicker table tr td span.active.disabled.active,\n.datepicker table tr td span.active.disabled:hover.active {\n  background-color: #003399 \\9;\n}\n.datepicker table tr td span.old,\n.datepicker table tr td span.new {\n  color: #999;\n}\n.datepicker .datepicker-switch {\n  width: 145px;\n}\n.datepicker .datepicker-switch,\n.datepicker .prev,\n.datepicker .next,\n.datepicker tfoot tr th {\n  cursor: pointer;\n}\n.datepicker .datepicker-switch:hover,\n.datepicker .prev:hover,\n.datepicker .next:hover,\n.datepicker tfoot tr th:hover {\n  background: #eee;\n}\n.datepicker .cw {\n  font-size: 10px;\n  width: 12px;\n  padding: 0 2px 0 5px;\n  vertical-align: middle;\n}\n.input-append.date .add-on,\n.input-prepend.date .add-on {\n  cursor: pointer;\n}\n.input-append.date .add-on i,\n.input-prepend.date .add-on i {\n  margin-top: 3px;\n}\n.input-daterange input {\n  text-align: center;\n}\n.input-daterange input:first-child {\n  -webkit-border-radius: 3px 0 0 3px;\n  -moz-border-radius: 3px 0 0 3px;\n  border-radius: 3px 0 0 3px;\n}\n.input-daterange input:last-child {\n  -webkit-border-radius: 0 3px 3px 0;\n  -moz-border-radius: 0 3px 3px 0;\n  border-radius: 0 3px 3px 0;\n}\n.input-daterange .add-on {\n  display: inline-block;\n  width: auto;\n  min-width: 16px;\n  height: 20px;\n  padding: 4px 5px;\n  font-weight: normal;\n  line-height: 20px;\n  text-align: center;\n  text-shadow: 0 1px 0 #fff;\n  vertical-align: middle;\n  background-color: #eee;\n  border: 1px solid #ccc;\n  margin-left: -5px;\n  margin-right: -5px;\n}\n.datepicker.dropdown-menu {\n  position: absolute;\n  top: 100%;\n  left: 0;\n  z-index: 1000;\n  float: left;\n  display: none;\n  min-width: 160px;\n  list-style: none;\n  background-color: #fff;\n  border: 1px solid #ccc;\n  border: 1px solid rgba(0, 0, 0, 0.2);\n  -webkit-border-radius: 5px;\n  -moz-border-radius: 5px;\n  border-radius: 5px;\n  -webkit-box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2);\n  -moz-box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2);\n  box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2);\n  -webkit-background-clip: padding-box;\n  -moz-background-clip: padding;\n  background-clip: padding-box;\n  *border-right-width: 2px;\n  *border-bottom-width: 2px;\n  color: #333333;\n  font-size: 13px;\n  line-height: 20px;\n}\n.datepicker.dropdown-menu th,\n.datepicker.datepicker-inline th,\n.datepicker.dropdown-menu td,\n.datepicker.datepicker-inline td {\n  padding: 4px 5px;\n}\n/*# sourceMappingURL=bootstrap-datepicker.standalone.css.map */"
  },
  {
    "path": "app_backend/static/plugin/bootstrap-datepicker-1.6.4/css/bootstrap-datepicker3.css",
    "content": "/*!\n * Datepicker for Bootstrap v1.6.4 (https://github.com/eternicode/bootstrap-datepicker)\n *\n * Copyright 2012 Stefan Petre\n * Improvements by Andrew Rowls\n * Licensed under the Apache License v2.0 (http://www.apache.org/licenses/LICENSE-2.0)\n */\n.datepicker {\n  border-radius: 4px;\n  direction: ltr;\n}\n.datepicker-inline {\n  width: 220px;\n}\n.datepicker.datepicker-rtl {\n  direction: rtl;\n}\n.datepicker.datepicker-rtl table tr td span {\n  float: right;\n}\n.datepicker-dropdown {\n  top: 0;\n  left: 0;\n  padding: 4px;\n}\n.datepicker-dropdown:before {\n  content: '';\n  display: inline-block;\n  border-left: 7px solid transparent;\n  border-right: 7px solid transparent;\n  border-bottom: 7px solid rgba(0, 0, 0, 0.15);\n  border-top: 0;\n  border-bottom-color: rgba(0, 0, 0, 0.2);\n  position: absolute;\n}\n.datepicker-dropdown:after {\n  content: '';\n  display: inline-block;\n  border-left: 6px solid transparent;\n  border-right: 6px solid transparent;\n  border-bottom: 6px solid #fff;\n  border-top: 0;\n  position: absolute;\n}\n.datepicker-dropdown.datepicker-orient-left:before {\n  left: 6px;\n}\n.datepicker-dropdown.datepicker-orient-left:after {\n  left: 7px;\n}\n.datepicker-dropdown.datepicker-orient-right:before {\n  right: 6px;\n}\n.datepicker-dropdown.datepicker-orient-right:after {\n  right: 7px;\n}\n.datepicker-dropdown.datepicker-orient-bottom:before {\n  top: -7px;\n}\n.datepicker-dropdown.datepicker-orient-bottom:after {\n  top: -6px;\n}\n.datepicker-dropdown.datepicker-orient-top:before {\n  bottom: -7px;\n  border-bottom: 0;\n  border-top: 7px solid rgba(0, 0, 0, 0.15);\n}\n.datepicker-dropdown.datepicker-orient-top:after {\n  bottom: -6px;\n  border-bottom: 0;\n  border-top: 6px solid #fff;\n}\n.datepicker table {\n  margin: 0;\n  -webkit-touch-callout: none;\n  -webkit-user-select: none;\n  -khtml-user-select: none;\n  -moz-user-select: none;\n  -ms-user-select: none;\n  user-select: none;\n}\n.datepicker table tr td,\n.datepicker table tr th {\n  text-align: center;\n  width: 30px;\n  height: 30px;\n  border-radius: 4px;\n  border: none;\n}\n.table-striped .datepicker table tr td,\n.table-striped .datepicker table tr th {\n  background-color: transparent;\n}\n.datepicker table tr td.old,\n.datepicker table tr td.new {\n  color: #777777;\n}\n.datepicker table tr td.day:hover,\n.datepicker table tr td.focused {\n  background: #eeeeee;\n  cursor: pointer;\n}\n.datepicker table tr td.disabled,\n.datepicker table tr td.disabled:hover {\n  background: none;\n  color: #777777;\n  cursor: default;\n}\n.datepicker table tr td.highlighted {\n  color: #000;\n  background-color: #d9edf7;\n  border-color: #85c5e5;\n  border-radius: 0;\n}\n.datepicker table tr td.highlighted:focus,\n.datepicker table tr td.highlighted.focus {\n  color: #000;\n  background-color: #afd9ee;\n  border-color: #298fc2;\n}\n.datepicker table tr td.highlighted:hover {\n  color: #000;\n  background-color: #afd9ee;\n  border-color: #52addb;\n}\n.datepicker table tr td.highlighted:active,\n.datepicker table tr td.highlighted.active {\n  color: #000;\n  background-color: #afd9ee;\n  border-color: #52addb;\n}\n.datepicker table tr td.highlighted:active:hover,\n.datepicker table tr td.highlighted.active:hover,\n.datepicker table tr td.highlighted:active:focus,\n.datepicker table tr td.highlighted.active:focus,\n.datepicker table tr td.highlighted:active.focus,\n.datepicker table tr td.highlighted.active.focus {\n  color: #000;\n  background-color: #91cbe8;\n  border-color: #298fc2;\n}\n.datepicker table tr td.highlighted.disabled:hover,\n.datepicker table tr td.highlighted[disabled]:hover,\nfieldset[disabled] .datepicker table tr td.highlighted:hover,\n.datepicker table tr td.highlighted.disabled:focus,\n.datepicker table tr td.highlighted[disabled]:focus,\nfieldset[disabled] .datepicker table tr td.highlighted:focus,\n.datepicker table tr td.highlighted.disabled.focus,\n.datepicker table tr td.highlighted[disabled].focus,\nfieldset[disabled] .datepicker table tr td.highlighted.focus {\n  background-color: #d9edf7;\n  border-color: #85c5e5;\n}\n.datepicker table tr td.highlighted.focused {\n  background: #afd9ee;\n}\n.datepicker table tr td.highlighted.disabled,\n.datepicker table tr td.highlighted.disabled:active {\n  background: #d9edf7;\n  color: #777777;\n}\n.datepicker table tr td.today {\n  color: #000;\n  background-color: #ffdb99;\n  border-color: #ffb733;\n}\n.datepicker table tr td.today:focus,\n.datepicker table tr td.today.focus {\n  color: #000;\n  background-color: #ffc966;\n  border-color: #b37400;\n}\n.datepicker table tr td.today:hover {\n  color: #000;\n  background-color: #ffc966;\n  border-color: #f59e00;\n}\n.datepicker table tr td.today:active,\n.datepicker table tr td.today.active {\n  color: #000;\n  background-color: #ffc966;\n  border-color: #f59e00;\n}\n.datepicker table tr td.today:active:hover,\n.datepicker table tr td.today.active:hover,\n.datepicker table tr td.today:active:focus,\n.datepicker table tr td.today.active:focus,\n.datepicker table tr td.today:active.focus,\n.datepicker table tr td.today.active.focus {\n  color: #000;\n  background-color: #ffbc42;\n  border-color: #b37400;\n}\n.datepicker table tr td.today.disabled:hover,\n.datepicker table tr td.today[disabled]:hover,\nfieldset[disabled] .datepicker table tr td.today:hover,\n.datepicker table tr td.today.disabled:focus,\n.datepicker table tr td.today[disabled]:focus,\nfieldset[disabled] .datepicker table tr td.today:focus,\n.datepicker table tr td.today.disabled.focus,\n.datepicker table tr td.today[disabled].focus,\nfieldset[disabled] .datepicker table tr td.today.focus {\n  background-color: #ffdb99;\n  border-color: #ffb733;\n}\n.datepicker table tr td.today.focused {\n  background: #ffc966;\n}\n.datepicker table tr td.today.disabled,\n.datepicker table tr td.today.disabled:active {\n  background: #ffdb99;\n  color: #777777;\n}\n.datepicker table tr td.range {\n  color: #000;\n  background-color: #eeeeee;\n  border-color: #bbbbbb;\n  border-radius: 0;\n}\n.datepicker table tr td.range:focus,\n.datepicker table tr td.range.focus {\n  color: #000;\n  background-color: #d5d5d5;\n  border-color: #7c7c7c;\n}\n.datepicker table tr td.range:hover {\n  color: #000;\n  background-color: #d5d5d5;\n  border-color: #9d9d9d;\n}\n.datepicker table tr td.range:active,\n.datepicker table tr td.range.active {\n  color: #000;\n  background-color: #d5d5d5;\n  border-color: #9d9d9d;\n}\n.datepicker table tr td.range:active:hover,\n.datepicker table tr td.range.active:hover,\n.datepicker table tr td.range:active:focus,\n.datepicker table tr td.range.active:focus,\n.datepicker table tr td.range:active.focus,\n.datepicker table tr td.range.active.focus {\n  color: #000;\n  background-color: #c3c3c3;\n  border-color: #7c7c7c;\n}\n.datepicker table tr td.range.disabled:hover,\n.datepicker table tr td.range[disabled]:hover,\nfieldset[disabled] .datepicker table tr td.range:hover,\n.datepicker table tr td.range.disabled:focus,\n.datepicker table tr td.range[disabled]:focus,\nfieldset[disabled] .datepicker table tr td.range:focus,\n.datepicker table tr td.range.disabled.focus,\n.datepicker table tr td.range[disabled].focus,\nfieldset[disabled] .datepicker table tr td.range.focus {\n  background-color: #eeeeee;\n  border-color: #bbbbbb;\n}\n.datepicker table tr td.range.focused {\n  background: #d5d5d5;\n}\n.datepicker table tr td.range.disabled,\n.datepicker table tr td.range.disabled:active {\n  background: #eeeeee;\n  color: #777777;\n}\n.datepicker table tr td.range.highlighted {\n  color: #000;\n  background-color: #e4eef3;\n  border-color: #9dc1d3;\n}\n.datepicker table tr td.range.highlighted:focus,\n.datepicker table tr td.range.highlighted.focus {\n  color: #000;\n  background-color: #c1d7e3;\n  border-color: #4b88a6;\n}\n.datepicker table tr td.range.highlighted:hover {\n  color: #000;\n  background-color: #c1d7e3;\n  border-color: #73a6c0;\n}\n.datepicker table tr td.range.highlighted:active,\n.datepicker table tr td.range.highlighted.active {\n  color: #000;\n  background-color: #c1d7e3;\n  border-color: #73a6c0;\n}\n.datepicker table tr td.range.highlighted:active:hover,\n.datepicker table tr td.range.highlighted.active:hover,\n.datepicker table tr td.range.highlighted:active:focus,\n.datepicker table tr td.range.highlighted.active:focus,\n.datepicker table tr td.range.highlighted:active.focus,\n.datepicker table tr td.range.highlighted.active.focus {\n  color: #000;\n  background-color: #a8c8d8;\n  border-color: #4b88a6;\n}\n.datepicker table tr td.range.highlighted.disabled:hover,\n.datepicker table tr td.range.highlighted[disabled]:hover,\nfieldset[disabled] .datepicker table tr td.range.highlighted:hover,\n.datepicker table tr td.range.highlighted.disabled:focus,\n.datepicker table tr td.range.highlighted[disabled]:focus,\nfieldset[disabled] .datepicker table tr td.range.highlighted:focus,\n.datepicker table tr td.range.highlighted.disabled.focus,\n.datepicker table tr td.range.highlighted[disabled].focus,\nfieldset[disabled] .datepicker table tr td.range.highlighted.focus {\n  background-color: #e4eef3;\n  border-color: #9dc1d3;\n}\n.datepicker table tr td.range.highlighted.focused {\n  background: #c1d7e3;\n}\n.datepicker table tr td.range.highlighted.disabled,\n.datepicker table tr td.range.highlighted.disabled:active {\n  background: #e4eef3;\n  color: #777777;\n}\n.datepicker table tr td.range.today {\n  color: #000;\n  background-color: #f7ca77;\n  border-color: #f1a417;\n}\n.datepicker table tr td.range.today:focus,\n.datepicker table tr td.range.today.focus {\n  color: #000;\n  background-color: #f4b747;\n  border-color: #815608;\n}\n.datepicker table tr td.range.today:hover {\n  color: #000;\n  background-color: #f4b747;\n  border-color: #bf800c;\n}\n.datepicker table tr td.range.today:active,\n.datepicker table tr td.range.today.active {\n  color: #000;\n  background-color: #f4b747;\n  border-color: #bf800c;\n}\n.datepicker table tr td.range.today:active:hover,\n.datepicker table tr td.range.today.active:hover,\n.datepicker table tr td.range.today:active:focus,\n.datepicker table tr td.range.today.active:focus,\n.datepicker table tr td.range.today:active.focus,\n.datepicker table tr td.range.today.active.focus {\n  color: #000;\n  background-color: #f2aa25;\n  border-color: #815608;\n}\n.datepicker table tr td.range.today.disabled:hover,\n.datepicker table tr td.range.today[disabled]:hover,\nfieldset[disabled] .datepicker table tr td.range.today:hover,\n.datepicker table tr td.range.today.disabled:focus,\n.datepicker table tr td.range.today[disabled]:focus,\nfieldset[disabled] .datepicker table tr td.range.today:focus,\n.datepicker table tr td.range.today.disabled.focus,\n.datepicker table tr td.range.today[disabled].focus,\nfieldset[disabled] .datepicker table tr td.range.today.focus {\n  background-color: #f7ca77;\n  border-color: #f1a417;\n}\n.datepicker table tr td.range.today.disabled,\n.datepicker table tr td.range.today.disabled:active {\n  background: #f7ca77;\n  color: #777777;\n}\n.datepicker table tr td.selected,\n.datepicker table tr td.selected.highlighted {\n  color: #fff;\n  background-color: #777777;\n  border-color: #555555;\n  text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25);\n}\n.datepicker table tr td.selected:focus,\n.datepicker table tr td.selected.highlighted:focus,\n.datepicker table tr td.selected.focus,\n.datepicker table tr td.selected.highlighted.focus {\n  color: #fff;\n  background-color: #5e5e5e;\n  border-color: #161616;\n}\n.datepicker table tr td.selected:hover,\n.datepicker table tr td.selected.highlighted:hover {\n  color: #fff;\n  background-color: #5e5e5e;\n  border-color: #373737;\n}\n.datepicker table tr td.selected:active,\n.datepicker table tr td.selected.highlighted:active,\n.datepicker table tr td.selected.active,\n.datepicker table tr td.selected.highlighted.active {\n  color: #fff;\n  background-color: #5e5e5e;\n  border-color: #373737;\n}\n.datepicker table tr td.selected:active:hover,\n.datepicker table tr td.selected.highlighted:active:hover,\n.datepicker table tr td.selected.active:hover,\n.datepicker table tr td.selected.highlighted.active:hover,\n.datepicker table tr td.selected:active:focus,\n.datepicker table tr td.selected.highlighted:active:focus,\n.datepicker table tr td.selected.active:focus,\n.datepicker table tr td.selected.highlighted.active:focus,\n.datepicker table tr td.selected:active.focus,\n.datepicker table tr td.selected.highlighted:active.focus,\n.datepicker table tr td.selected.active.focus,\n.datepicker table tr td.selected.highlighted.active.focus {\n  color: #fff;\n  background-color: #4c4c4c;\n  border-color: #161616;\n}\n.datepicker table tr td.selected.disabled:hover,\n.datepicker table tr td.selected.highlighted.disabled:hover,\n.datepicker table tr td.selected[disabled]:hover,\n.datepicker table tr td.selected.highlighted[disabled]:hover,\nfieldset[disabled] .datepicker table tr td.selected:hover,\nfieldset[disabled] .datepicker table tr td.selected.highlighted:hover,\n.datepicker table tr td.selected.disabled:focus,\n.datepicker table tr td.selected.highlighted.disabled:focus,\n.datepicker table tr td.selected[disabled]:focus,\n.datepicker table tr td.selected.highlighted[disabled]:focus,\nfieldset[disabled] .datepicker table tr td.selected:focus,\nfieldset[disabled] .datepicker table tr td.selected.highlighted:focus,\n.datepicker table tr td.selected.disabled.focus,\n.datepicker table tr td.selected.highlighted.disabled.focus,\n.datepicker table tr td.selected[disabled].focus,\n.datepicker table tr td.selected.highlighted[disabled].focus,\nfieldset[disabled] .datepicker table tr td.selected.focus,\nfieldset[disabled] .datepicker table tr td.selected.highlighted.focus {\n  background-color: #777777;\n  border-color: #555555;\n}\n.datepicker table tr td.active,\n.datepicker table tr td.active.highlighted {\n  color: #fff;\n  background-color: #337ab7;\n  border-color: #2e6da4;\n  text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25);\n}\n.datepicker table tr td.active:focus,\n.datepicker table tr td.active.highlighted:focus,\n.datepicker table tr td.active.focus,\n.datepicker table tr td.active.highlighted.focus {\n  color: #fff;\n  background-color: #286090;\n  border-color: #122b40;\n}\n.datepicker table tr td.active:hover,\n.datepicker table tr td.active.highlighted:hover {\n  color: #fff;\n  background-color: #286090;\n  border-color: #204d74;\n}\n.datepicker table tr td.active:active,\n.datepicker table tr td.active.highlighted:active,\n.datepicker table tr td.active.active,\n.datepicker table tr td.active.highlighted.active {\n  color: #fff;\n  background-color: #286090;\n  border-color: #204d74;\n}\n.datepicker table tr td.active:active:hover,\n.datepicker table tr td.active.highlighted:active:hover,\n.datepicker table tr td.active.active:hover,\n.datepicker table tr td.active.highlighted.active:hover,\n.datepicker table tr td.active:active:focus,\n.datepicker table tr td.active.highlighted:active:focus,\n.datepicker table tr td.active.active:focus,\n.datepicker table tr td.active.highlighted.active:focus,\n.datepicker table tr td.active:active.focus,\n.datepicker table tr td.active.highlighted:active.focus,\n.datepicker table tr td.active.active.focus,\n.datepicker table tr td.active.highlighted.active.focus {\n  color: #fff;\n  background-color: #204d74;\n  border-color: #122b40;\n}\n.datepicker table tr td.active.disabled:hover,\n.datepicker table tr td.active.highlighted.disabled:hover,\n.datepicker table tr td.active[disabled]:hover,\n.datepicker table tr td.active.highlighted[disabled]:hover,\nfieldset[disabled] .datepicker table tr td.active:hover,\nfieldset[disabled] .datepicker table tr td.active.highlighted:hover,\n.datepicker table tr td.active.disabled:focus,\n.datepicker table tr td.active.highlighted.disabled:focus,\n.datepicker table tr td.active[disabled]:focus,\n.datepicker table tr td.active.highlighted[disabled]:focus,\nfieldset[disabled] .datepicker table tr td.active:focus,\nfieldset[disabled] .datepicker table tr td.active.highlighted:focus,\n.datepicker table tr td.active.disabled.focus,\n.datepicker table tr td.active.highlighted.disabled.focus,\n.datepicker table tr td.active[disabled].focus,\n.datepicker table tr td.active.highlighted[disabled].focus,\nfieldset[disabled] .datepicker table tr td.active.focus,\nfieldset[disabled] .datepicker table tr td.active.highlighted.focus {\n  background-color: #337ab7;\n  border-color: #2e6da4;\n}\n.datepicker table tr td span {\n  display: block;\n  width: 23%;\n  height: 54px;\n  line-height: 54px;\n  float: left;\n  margin: 1%;\n  cursor: pointer;\n  border-radius: 4px;\n}\n.datepicker table tr td span:hover,\n.datepicker table tr td span.focused {\n  background: #eeeeee;\n}\n.datepicker table tr td span.disabled,\n.datepicker table tr td span.disabled:hover {\n  background: none;\n  color: #777777;\n  cursor: default;\n}\n.datepicker table tr td span.active,\n.datepicker table tr td span.active:hover,\n.datepicker table tr td span.active.disabled,\n.datepicker table tr td span.active.disabled:hover {\n  color: #fff;\n  background-color: #337ab7;\n  border-color: #2e6da4;\n  text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25);\n}\n.datepicker table tr td span.active:focus,\n.datepicker table tr td span.active:hover:focus,\n.datepicker table tr td span.active.disabled:focus,\n.datepicker table tr td span.active.disabled:hover:focus,\n.datepicker table tr td span.active.focus,\n.datepicker table tr td span.active:hover.focus,\n.datepicker table tr td span.active.disabled.focus,\n.datepicker table tr td span.active.disabled:hover.focus {\n  color: #fff;\n  background-color: #286090;\n  border-color: #122b40;\n}\n.datepicker table tr td span.active:hover,\n.datepicker table tr td span.active:hover:hover,\n.datepicker table tr td span.active.disabled:hover,\n.datepicker table tr td span.active.disabled:hover:hover {\n  color: #fff;\n  background-color: #286090;\n  border-color: #204d74;\n}\n.datepicker table tr td span.active:active,\n.datepicker table tr td span.active:hover:active,\n.datepicker table tr td span.active.disabled:active,\n.datepicker table tr td span.active.disabled:hover:active,\n.datepicker table tr td span.active.active,\n.datepicker table tr td span.active:hover.active,\n.datepicker table tr td span.active.disabled.active,\n.datepicker table tr td span.active.disabled:hover.active {\n  color: #fff;\n  background-color: #286090;\n  border-color: #204d74;\n}\n.datepicker table tr td span.active:active:hover,\n.datepicker table tr td span.active:hover:active:hover,\n.datepicker table tr td span.active.disabled:active:hover,\n.datepicker table tr td span.active.disabled:hover:active:hover,\n.datepicker table tr td span.active.active:hover,\n.datepicker table tr td span.active:hover.active:hover,\n.datepicker table tr td span.active.disabled.active:hover,\n.datepicker table tr td span.active.disabled:hover.active:hover,\n.datepicker table tr td span.active:active:focus,\n.datepicker table tr td span.active:hover:active:focus,\n.datepicker table tr td span.active.disabled:active:focus,\n.datepicker table tr td span.active.disabled:hover:active:focus,\n.datepicker table tr td span.active.active:focus,\n.datepicker table tr td span.active:hover.active:focus,\n.datepicker table tr td span.active.disabled.active:focus,\n.datepicker table tr td span.active.disabled:hover.active:focus,\n.datepicker table tr td span.active:active.focus,\n.datepicker table tr td span.active:hover:active.focus,\n.datepicker table tr td span.active.disabled:active.focus,\n.datepicker table tr td span.active.disabled:hover:active.focus,\n.datepicker table tr td span.active.active.focus,\n.datepicker table tr td span.active:hover.active.focus,\n.datepicker table tr td span.active.disabled.active.focus,\n.datepicker table tr td span.active.disabled:hover.active.focus {\n  color: #fff;\n  background-color: #204d74;\n  border-color: #122b40;\n}\n.datepicker table tr td span.active.disabled:hover,\n.datepicker table tr td span.active:hover.disabled:hover,\n.datepicker table tr td span.active.disabled.disabled:hover,\n.datepicker table tr td span.active.disabled:hover.disabled:hover,\n.datepicker table tr td span.active[disabled]:hover,\n.datepicker table tr td span.active:hover[disabled]:hover,\n.datepicker table tr td span.active.disabled[disabled]:hover,\n.datepicker table tr td span.active.disabled:hover[disabled]:hover,\nfieldset[disabled] .datepicker table tr td span.active:hover,\nfieldset[disabled] .datepicker table tr td span.active:hover:hover,\nfieldset[disabled] .datepicker table tr td span.active.disabled:hover,\nfieldset[disabled] .datepicker table tr td span.active.disabled:hover:hover,\n.datepicker table tr td span.active.disabled:focus,\n.datepicker table tr td span.active:hover.disabled:focus,\n.datepicker table tr td span.active.disabled.disabled:focus,\n.datepicker table tr td span.active.disabled:hover.disabled:focus,\n.datepicker table tr td span.active[disabled]:focus,\n.datepicker table tr td span.active:hover[disabled]:focus,\n.datepicker table tr td span.active.disabled[disabled]:focus,\n.datepicker table tr td span.active.disabled:hover[disabled]:focus,\nfieldset[disabled] .datepicker table tr td span.active:focus,\nfieldset[disabled] .datepicker table tr td span.active:hover:focus,\nfieldset[disabled] .datepicker table tr td span.active.disabled:focus,\nfieldset[disabled] .datepicker table tr td span.active.disabled:hover:focus,\n.datepicker table tr td span.active.disabled.focus,\n.datepicker table tr td span.active:hover.disabled.focus,\n.datepicker table tr td span.active.disabled.disabled.focus,\n.datepicker table tr td span.active.disabled:hover.disabled.focus,\n.datepicker table tr td span.active[disabled].focus,\n.datepicker table tr td span.active:hover[disabled].focus,\n.datepicker table tr td span.active.disabled[disabled].focus,\n.datepicker table tr td span.active.disabled:hover[disabled].focus,\nfieldset[disabled] .datepicker table tr td span.active.focus,\nfieldset[disabled] .datepicker table tr td span.active:hover.focus,\nfieldset[disabled] .datepicker table tr td span.active.disabled.focus,\nfieldset[disabled] .datepicker table tr td span.active.disabled:hover.focus {\n  background-color: #337ab7;\n  border-color: #2e6da4;\n}\n.datepicker table tr td span.old,\n.datepicker table tr td span.new {\n  color: #777777;\n}\n.datepicker .datepicker-switch {\n  width: 145px;\n}\n.datepicker .datepicker-switch,\n.datepicker .prev,\n.datepicker .next,\n.datepicker tfoot tr th {\n  cursor: pointer;\n}\n.datepicker .datepicker-switch:hover,\n.datepicker .prev:hover,\n.datepicker .next:hover,\n.datepicker tfoot tr th:hover {\n  background: #eeeeee;\n}\n.datepicker .cw {\n  font-size: 10px;\n  width: 12px;\n  padding: 0 2px 0 5px;\n  vertical-align: middle;\n}\n.input-group.date .input-group-addon {\n  cursor: pointer;\n}\n.input-daterange {\n  width: 100%;\n}\n.input-daterange input {\n  text-align: center;\n}\n.input-daterange input:first-child {\n  border-radius: 3px 0 0 3px;\n}\n.input-daterange input:last-child {\n  border-radius: 0 3px 3px 0;\n}\n.input-daterange .input-group-addon {\n  width: auto;\n  min-width: 16px;\n  padding: 4px 5px;\n  line-height: 1.42857143;\n  text-shadow: 0 1px 0 #fff;\n  border-width: 1px 0;\n  margin-left: -5px;\n  margin-right: -5px;\n}\n/*# sourceMappingURL=bootstrap-datepicker3.css.map */"
  },
  {
    "path": "app_backend/static/plugin/bootstrap-datepicker-1.6.4/css/bootstrap-datepicker3.standalone.css",
    "content": "/*!\n * Datepicker for Bootstrap v1.6.4 (https://github.com/eternicode/bootstrap-datepicker)\n *\n * Copyright 2012 Stefan Petre\n * Improvements by Andrew Rowls\n * Licensed under the Apache License v2.0 (http://www.apache.org/licenses/LICENSE-2.0)\n */\n.datepicker {\n  border-radius: 4px;\n  direction: ltr;\n}\n.datepicker-inline {\n  width: 220px;\n}\n.datepicker.datepicker-rtl {\n  direction: rtl;\n}\n.datepicker.datepicker-rtl table tr td span {\n  float: right;\n}\n.datepicker-dropdown {\n  top: 0;\n  left: 0;\n  padding: 4px;\n}\n.datepicker-dropdown:before {\n  content: '';\n  display: inline-block;\n  border-left: 7px solid transparent;\n  border-right: 7px solid transparent;\n  border-bottom: 7px solid rgba(0, 0, 0, 0.15);\n  border-top: 0;\n  border-bottom-color: rgba(0, 0, 0, 0.2);\n  position: absolute;\n}\n.datepicker-dropdown:after {\n  content: '';\n  display: inline-block;\n  border-left: 6px solid transparent;\n  border-right: 6px solid transparent;\n  border-bottom: 6px solid #fff;\n  border-top: 0;\n  position: absolute;\n}\n.datepicker-dropdown.datepicker-orient-left:before {\n  left: 6px;\n}\n.datepicker-dropdown.datepicker-orient-left:after {\n  left: 7px;\n}\n.datepicker-dropdown.datepicker-orient-right:before {\n  right: 6px;\n}\n.datepicker-dropdown.datepicker-orient-right:after {\n  right: 7px;\n}\n.datepicker-dropdown.datepicker-orient-bottom:before {\n  top: -7px;\n}\n.datepicker-dropdown.datepicker-orient-bottom:after {\n  top: -6px;\n}\n.datepicker-dropdown.datepicker-orient-top:before {\n  bottom: -7px;\n  border-bottom: 0;\n  border-top: 7px solid rgba(0, 0, 0, 0.15);\n}\n.datepicker-dropdown.datepicker-orient-top:after {\n  bottom: -6px;\n  border-bottom: 0;\n  border-top: 6px solid #fff;\n}\n.datepicker table {\n  margin: 0;\n  -webkit-touch-callout: none;\n  -webkit-user-select: none;\n  -khtml-user-select: none;\n  -moz-user-select: none;\n  -ms-user-select: none;\n  user-select: none;\n}\n.datepicker table tr td,\n.datepicker table tr th {\n  text-align: center;\n  width: 30px;\n  height: 30px;\n  border-radius: 4px;\n  border: none;\n}\n.table-striped .datepicker table tr td,\n.table-striped .datepicker table tr th {\n  background-color: transparent;\n}\n.datepicker table tr td.old,\n.datepicker table tr td.new {\n  color: #777777;\n}\n.datepicker table tr td.day:hover,\n.datepicker table tr td.focused {\n  background: #eeeeee;\n  cursor: pointer;\n}\n.datepicker table tr td.disabled,\n.datepicker table tr td.disabled:hover {\n  background: none;\n  color: #777777;\n  cursor: default;\n}\n.datepicker table tr td.highlighted {\n  color: #000;\n  background-color: #d9edf7;\n  border-color: #85c5e5;\n  border-radius: 0;\n}\n.datepicker table tr td.highlighted:focus,\n.datepicker table tr td.highlighted.focus {\n  color: #000;\n  background-color: #afd9ee;\n  border-color: #298fc2;\n}\n.datepicker table tr td.highlighted:hover {\n  color: #000;\n  background-color: #afd9ee;\n  border-color: #52addb;\n}\n.datepicker table tr td.highlighted:active,\n.datepicker table tr td.highlighted.active {\n  color: #000;\n  background-color: #afd9ee;\n  border-color: #52addb;\n}\n.datepicker table tr td.highlighted:active:hover,\n.datepicker table tr td.highlighted.active:hover,\n.datepicker table tr td.highlighted:active:focus,\n.datepicker table tr td.highlighted.active:focus,\n.datepicker table tr td.highlighted:active.focus,\n.datepicker table tr td.highlighted.active.focus {\n  color: #000;\n  background-color: #91cbe8;\n  border-color: #298fc2;\n}\n.datepicker table tr td.highlighted.disabled:hover,\n.datepicker table tr td.highlighted[disabled]:hover,\nfieldset[disabled] .datepicker table tr td.highlighted:hover,\n.datepicker table tr td.highlighted.disabled:focus,\n.datepicker table tr td.highlighted[disabled]:focus,\nfieldset[disabled] .datepicker table tr td.highlighted:focus,\n.datepicker table tr td.highlighted.disabled.focus,\n.datepicker table tr td.highlighted[disabled].focus,\nfieldset[disabled] .datepicker table tr td.highlighted.focus {\n  background-color: #d9edf7;\n  border-color: #85c5e5;\n}\n.datepicker table tr td.highlighted.focused {\n  background: #afd9ee;\n}\n.datepicker table tr td.highlighted.disabled,\n.datepicker table tr td.highlighted.disabled:active {\n  background: #d9edf7;\n  color: #777777;\n}\n.datepicker table tr td.today {\n  color: #000;\n  background-color: #ffdb99;\n  border-color: #ffb733;\n}\n.datepicker table tr td.today:focus,\n.datepicker table tr td.today.focus {\n  color: #000;\n  background-color: #ffc966;\n  border-color: #b37400;\n}\n.datepicker table tr td.today:hover {\n  color: #000;\n  background-color: #ffc966;\n  border-color: #f59e00;\n}\n.datepicker table tr td.today:active,\n.datepicker table tr td.today.active {\n  color: #000;\n  background-color: #ffc966;\n  border-color: #f59e00;\n}\n.datepicker table tr td.today:active:hover,\n.datepicker table tr td.today.active:hover,\n.datepicker table tr td.today:active:focus,\n.datepicker table tr td.today.active:focus,\n.datepicker table tr td.today:active.focus,\n.datepicker table tr td.today.active.focus {\n  color: #000;\n  background-color: #ffbc42;\n  border-color: #b37400;\n}\n.datepicker table tr td.today.disabled:hover,\n.datepicker table tr td.today[disabled]:hover,\nfieldset[disabled] .datepicker table tr td.today:hover,\n.datepicker table tr td.today.disabled:focus,\n.datepicker table tr td.today[disabled]:focus,\nfieldset[disabled] .datepicker table tr td.today:focus,\n.datepicker table tr td.today.disabled.focus,\n.datepicker table tr td.today[disabled].focus,\nfieldset[disabled] .datepicker table tr td.today.focus {\n  background-color: #ffdb99;\n  border-color: #ffb733;\n}\n.datepicker table tr td.today.focused {\n  background: #ffc966;\n}\n.datepicker table tr td.today.disabled,\n.datepicker table tr td.today.disabled:active {\n  background: #ffdb99;\n  color: #777777;\n}\n.datepicker table tr td.range {\n  color: #000;\n  background-color: #eeeeee;\n  border-color: #bbbbbb;\n  border-radius: 0;\n}\n.datepicker table tr td.range:focus,\n.datepicker table tr td.range.focus {\n  color: #000;\n  background-color: #d5d5d5;\n  border-color: #7c7c7c;\n}\n.datepicker table tr td.range:hover {\n  color: #000;\n  background-color: #d5d5d5;\n  border-color: #9d9d9d;\n}\n.datepicker table tr td.range:active,\n.datepicker table tr td.range.active {\n  color: #000;\n  background-color: #d5d5d5;\n  border-color: #9d9d9d;\n}\n.datepicker table tr td.range:active:hover,\n.datepicker table tr td.range.active:hover,\n.datepicker table tr td.range:active:focus,\n.datepicker table tr td.range.active:focus,\n.datepicker table tr td.range:active.focus,\n.datepicker table tr td.range.active.focus {\n  color: #000;\n  background-color: #c3c3c3;\n  border-color: #7c7c7c;\n}\n.datepicker table tr td.range.disabled:hover,\n.datepicker table tr td.range[disabled]:hover,\nfieldset[disabled] .datepicker table tr td.range:hover,\n.datepicker table tr td.range.disabled:focus,\n.datepicker table tr td.range[disabled]:focus,\nfieldset[disabled] .datepicker table tr td.range:focus,\n.datepicker table tr td.range.disabled.focus,\n.datepicker table tr td.range[disabled].focus,\nfieldset[disabled] .datepicker table tr td.range.focus {\n  background-color: #eeeeee;\n  border-color: #bbbbbb;\n}\n.datepicker table tr td.range.focused {\n  background: #d5d5d5;\n}\n.datepicker table tr td.range.disabled,\n.datepicker table tr td.range.disabled:active {\n  background: #eeeeee;\n  color: #777777;\n}\n.datepicker table tr td.range.highlighted {\n  color: #000;\n  background-color: #e4eef3;\n  border-color: #9dc1d3;\n}\n.datepicker table tr td.range.highlighted:focus,\n.datepicker table tr td.range.highlighted.focus {\n  color: #000;\n  background-color: #c1d7e3;\n  border-color: #4b88a6;\n}\n.datepicker table tr td.range.highlighted:hover {\n  color: #000;\n  background-color: #c1d7e3;\n  border-color: #73a6c0;\n}\n.datepicker table tr td.range.highlighted:active,\n.datepicker table tr td.range.highlighted.active {\n  color: #000;\n  background-color: #c1d7e3;\n  border-color: #73a6c0;\n}\n.datepicker table tr td.range.highlighted:active:hover,\n.datepicker table tr td.range.highlighted.active:hover,\n.datepicker table tr td.range.highlighted:active:focus,\n.datepicker table tr td.range.highlighted.active:focus,\n.datepicker table tr td.range.highlighted:active.focus,\n.datepicker table tr td.range.highlighted.active.focus {\n  color: #000;\n  background-color: #a8c8d8;\n  border-color: #4b88a6;\n}\n.datepicker table tr td.range.highlighted.disabled:hover,\n.datepicker table tr td.range.highlighted[disabled]:hover,\nfieldset[disabled] .datepicker table tr td.range.highlighted:hover,\n.datepicker table tr td.range.highlighted.disabled:focus,\n.datepicker table tr td.range.highlighted[disabled]:focus,\nfieldset[disabled] .datepicker table tr td.range.highlighted:focus,\n.datepicker table tr td.range.highlighted.disabled.focus,\n.datepicker table tr td.range.highlighted[disabled].focus,\nfieldset[disabled] .datepicker table tr td.range.highlighted.focus {\n  background-color: #e4eef3;\n  border-color: #9dc1d3;\n}\n.datepicker table tr td.range.highlighted.focused {\n  background: #c1d7e3;\n}\n.datepicker table tr td.range.highlighted.disabled,\n.datepicker table tr td.range.highlighted.disabled:active {\n  background: #e4eef3;\n  color: #777777;\n}\n.datepicker table tr td.range.today {\n  color: #000;\n  background-color: #f7ca77;\n  border-color: #f1a417;\n}\n.datepicker table tr td.range.today:focus,\n.datepicker table tr td.range.today.focus {\n  color: #000;\n  background-color: #f4b747;\n  border-color: #815608;\n}\n.datepicker table tr td.range.today:hover {\n  color: #000;\n  background-color: #f4b747;\n  border-color: #bf800c;\n}\n.datepicker table tr td.range.today:active,\n.datepicker table tr td.range.today.active {\n  color: #000;\n  background-color: #f4b747;\n  border-color: #bf800c;\n}\n.datepicker table tr td.range.today:active:hover,\n.datepicker table tr td.range.today.active:hover,\n.datepicker table tr td.range.today:active:focus,\n.datepicker table tr td.range.today.active:focus,\n.datepicker table tr td.range.today:active.focus,\n.datepicker table tr td.range.today.active.focus {\n  color: #000;\n  background-color: #f2aa25;\n  border-color: #815608;\n}\n.datepicker table tr td.range.today.disabled:hover,\n.datepicker table tr td.range.today[disabled]:hover,\nfieldset[disabled] .datepicker table tr td.range.today:hover,\n.datepicker table tr td.range.today.disabled:focus,\n.datepicker table tr td.range.today[disabled]:focus,\nfieldset[disabled] .datepicker table tr td.range.today:focus,\n.datepicker table tr td.range.today.disabled.focus,\n.datepicker table tr td.range.today[disabled].focus,\nfieldset[disabled] .datepicker table tr td.range.today.focus {\n  background-color: #f7ca77;\n  border-color: #f1a417;\n}\n.datepicker table tr td.range.today.disabled,\n.datepicker table tr td.range.today.disabled:active {\n  background: #f7ca77;\n  color: #777777;\n}\n.datepicker table tr td.selected,\n.datepicker table tr td.selected.highlighted {\n  color: #fff;\n  background-color: #777777;\n  border-color: #555555;\n  text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25);\n}\n.datepicker table tr td.selected:focus,\n.datepicker table tr td.selected.highlighted:focus,\n.datepicker table tr td.selected.focus,\n.datepicker table tr td.selected.highlighted.focus {\n  color: #fff;\n  background-color: #5e5e5e;\n  border-color: #161616;\n}\n.datepicker table tr td.selected:hover,\n.datepicker table tr td.selected.highlighted:hover {\n  color: #fff;\n  background-color: #5e5e5e;\n  border-color: #373737;\n}\n.datepicker table tr td.selected:active,\n.datepicker table tr td.selected.highlighted:active,\n.datepicker table tr td.selected.active,\n.datepicker table tr td.selected.highlighted.active {\n  color: #fff;\n  background-color: #5e5e5e;\n  border-color: #373737;\n}\n.datepicker table tr td.selected:active:hover,\n.datepicker table tr td.selected.highlighted:active:hover,\n.datepicker table tr td.selected.active:hover,\n.datepicker table tr td.selected.highlighted.active:hover,\n.datepicker table tr td.selected:active:focus,\n.datepicker table tr td.selected.highlighted:active:focus,\n.datepicker table tr td.selected.active:focus,\n.datepicker table tr td.selected.highlighted.active:focus,\n.datepicker table tr td.selected:active.focus,\n.datepicker table tr td.selected.highlighted:active.focus,\n.datepicker table tr td.selected.active.focus,\n.datepicker table tr td.selected.highlighted.active.focus {\n  color: #fff;\n  background-color: #4c4c4c;\n  border-color: #161616;\n}\n.datepicker table tr td.selected.disabled:hover,\n.datepicker table tr td.selected.highlighted.disabled:hover,\n.datepicker table tr td.selected[disabled]:hover,\n.datepicker table tr td.selected.highlighted[disabled]:hover,\nfieldset[disabled] .datepicker table tr td.selected:hover,\nfieldset[disabled] .datepicker table tr td.selected.highlighted:hover,\n.datepicker table tr td.selected.disabled:focus,\n.datepicker table tr td.selected.highlighted.disabled:focus,\n.datepicker table tr td.selected[disabled]:focus,\n.datepicker table tr td.selected.highlighted[disabled]:focus,\nfieldset[disabled] .datepicker table tr td.selected:focus,\nfieldset[disabled] .datepicker table tr td.selected.highlighted:focus,\n.datepicker table tr td.selected.disabled.focus,\n.datepicker table tr td.selected.highlighted.disabled.focus,\n.datepicker table tr td.selected[disabled].focus,\n.datepicker table tr td.selected.highlighted[disabled].focus,\nfieldset[disabled] .datepicker table tr td.selected.focus,\nfieldset[disabled] .datepicker table tr td.selected.highlighted.focus {\n  background-color: #777777;\n  border-color: #555555;\n}\n.datepicker table tr td.active,\n.datepicker table tr td.active.highlighted {\n  color: #fff;\n  background-color: #337ab7;\n  border-color: #2e6da4;\n  text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25);\n}\n.datepicker table tr td.active:focus,\n.datepicker table tr td.active.highlighted:focus,\n.datepicker table tr td.active.focus,\n.datepicker table tr td.active.highlighted.focus {\n  color: #fff;\n  background-color: #286090;\n  border-color: #122b40;\n}\n.datepicker table tr td.active:hover,\n.datepicker table tr td.active.highlighted:hover {\n  color: #fff;\n  background-color: #286090;\n  border-color: #204d74;\n}\n.datepicker table tr td.active:active,\n.datepicker table tr td.active.highlighted:active,\n.datepicker table tr td.active.active,\n.datepicker table tr td.active.highlighted.active {\n  color: #fff;\n  background-color: #286090;\n  border-color: #204d74;\n}\n.datepicker table tr td.active:active:hover,\n.datepicker table tr td.active.highlighted:active:hover,\n.datepicker table tr td.active.active:hover,\n.datepicker table tr td.active.highlighted.active:hover,\n.datepicker table tr td.active:active:focus,\n.datepicker table tr td.active.highlighted:active:focus,\n.datepicker table tr td.active.active:focus,\n.datepicker table tr td.active.highlighted.active:focus,\n.datepicker table tr td.active:active.focus,\n.datepicker table tr td.active.highlighted:active.focus,\n.datepicker table tr td.active.active.focus,\n.datepicker table tr td.active.highlighted.active.focus {\n  color: #fff;\n  background-color: #204d74;\n  border-color: #122b40;\n}\n.datepicker table tr td.active.disabled:hover,\n.datepicker table tr td.active.highlighted.disabled:hover,\n.datepicker table tr td.active[disabled]:hover,\n.datepicker table tr td.active.highlighted[disabled]:hover,\nfieldset[disabled] .datepicker table tr td.active:hover,\nfieldset[disabled] .datepicker table tr td.active.highlighted:hover,\n.datepicker table tr td.active.disabled:focus,\n.datepicker table tr td.active.highlighted.disabled:focus,\n.datepicker table tr td.active[disabled]:focus,\n.datepicker table tr td.active.highlighted[disabled]:focus,\nfieldset[disabled] .datepicker table tr td.active:focus,\nfieldset[disabled] .datepicker table tr td.active.highlighted:focus,\n.datepicker table tr td.active.disabled.focus,\n.datepicker table tr td.active.highlighted.disabled.focus,\n.datepicker table tr td.active[disabled].focus,\n.datepicker table tr td.active.highlighted[disabled].focus,\nfieldset[disabled] .datepicker table tr td.active.focus,\nfieldset[disabled] .datepicker table tr td.active.highlighted.focus {\n  background-color: #337ab7;\n  border-color: #2e6da4;\n}\n.datepicker table tr td span {\n  display: block;\n  width: 23%;\n  height: 54px;\n  line-height: 54px;\n  float: left;\n  margin: 1%;\n  cursor: pointer;\n  border-radius: 4px;\n}\n.datepicker table tr td span:hover,\n.datepicker table tr td span.focused {\n  background: #eeeeee;\n}\n.datepicker table tr td span.disabled,\n.datepicker table tr td span.disabled:hover {\n  background: none;\n  color: #777777;\n  cursor: default;\n}\n.datepicker table tr td span.active,\n.datepicker table tr td span.active:hover,\n.datepicker table tr td span.active.disabled,\n.datepicker table tr td span.active.disabled:hover {\n  color: #fff;\n  background-color: #337ab7;\n  border-color: #2e6da4;\n  text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25);\n}\n.datepicker table tr td span.active:focus,\n.datepicker table tr td span.active:hover:focus,\n.datepicker table tr td span.active.disabled:focus,\n.datepicker table tr td span.active.disabled:hover:focus,\n.datepicker table tr td span.active.focus,\n.datepicker table tr td span.active:hover.focus,\n.datepicker table tr td span.active.disabled.focus,\n.datepicker table tr td span.active.disabled:hover.focus {\n  color: #fff;\n  background-color: #286090;\n  border-color: #122b40;\n}\n.datepicker table tr td span.active:hover,\n.datepicker table tr td span.active:hover:hover,\n.datepicker table tr td span.active.disabled:hover,\n.datepicker table tr td span.active.disabled:hover:hover {\n  color: #fff;\n  background-color: #286090;\n  border-color: #204d74;\n}\n.datepicker table tr td span.active:active,\n.datepicker table tr td span.active:hover:active,\n.datepicker table tr td span.active.disabled:active,\n.datepicker table tr td span.active.disabled:hover:active,\n.datepicker table tr td span.active.active,\n.datepicker table tr td span.active:hover.active,\n.datepicker table tr td span.active.disabled.active,\n.datepicker table tr td span.active.disabled:hover.active {\n  color: #fff;\n  background-color: #286090;\n  border-color: #204d74;\n}\n.datepicker table tr td span.active:active:hover,\n.datepicker table tr td span.active:hover:active:hover,\n.datepicker table tr td span.active.disabled:active:hover,\n.datepicker table tr td span.active.disabled:hover:active:hover,\n.datepicker table tr td span.active.active:hover,\n.datepicker table tr td span.active:hover.active:hover,\n.datepicker table tr td span.active.disabled.active:hover,\n.datepicker table tr td span.active.disabled:hover.active:hover,\n.datepicker table tr td span.active:active:focus,\n.datepicker table tr td span.active:hover:active:focus,\n.datepicker table tr td span.active.disabled:active:focus,\n.datepicker table tr td span.active.disabled:hover:active:focus,\n.datepicker table tr td span.active.active:focus,\n.datepicker table tr td span.active:hover.active:focus,\n.datepicker table tr td span.active.disabled.active:focus,\n.datepicker table tr td span.active.disabled:hover.active:focus,\n.datepicker table tr td span.active:active.focus,\n.datepicker table tr td span.active:hover:active.focus,\n.datepicker table tr td span.active.disabled:active.focus,\n.datepicker table tr td span.active.disabled:hover:active.focus,\n.datepicker table tr td span.active.active.focus,\n.datepicker table tr td span.active:hover.active.focus,\n.datepicker table tr td span.active.disabled.active.focus,\n.datepicker table tr td span.active.disabled:hover.active.focus {\n  color: #fff;\n  background-color: #204d74;\n  border-color: #122b40;\n}\n.datepicker table tr td span.active.disabled:hover,\n.datepicker table tr td span.active:hover.disabled:hover,\n.datepicker table tr td span.active.disabled.disabled:hover,\n.datepicker table tr td span.active.disabled:hover.disabled:hover,\n.datepicker table tr td span.active[disabled]:hover,\n.datepicker table tr td span.active:hover[disabled]:hover,\n.datepicker table tr td span.active.disabled[disabled]:hover,\n.datepicker table tr td span.active.disabled:hover[disabled]:hover,\nfieldset[disabled] .datepicker table tr td span.active:hover,\nfieldset[disabled] .datepicker table tr td span.active:hover:hover,\nfieldset[disabled] .datepicker table tr td span.active.disabled:hover,\nfieldset[disabled] .datepicker table tr td span.active.disabled:hover:hover,\n.datepicker table tr td span.active.disabled:focus,\n.datepicker table tr td span.active:hover.disabled:focus,\n.datepicker table tr td span.active.disabled.disabled:focus,\n.datepicker table tr td span.active.disabled:hover.disabled:focus,\n.datepicker table tr td span.active[disabled]:focus,\n.datepicker table tr td span.active:hover[disabled]:focus,\n.datepicker table tr td span.active.disabled[disabled]:focus,\n.datepicker table tr td span.active.disabled:hover[disabled]:focus,\nfieldset[disabled] .datepicker table tr td span.active:focus,\nfieldset[disabled] .datepicker table tr td span.active:hover:focus,\nfieldset[disabled] .datepicker table tr td span.active.disabled:focus,\nfieldset[disabled] .datepicker table tr td span.active.disabled:hover:focus,\n.datepicker table tr td span.active.disabled.focus,\n.datepicker table tr td span.active:hover.disabled.focus,\n.datepicker table tr td span.active.disabled.disabled.focus,\n.datepicker table tr td span.active.disabled:hover.disabled.focus,\n.datepicker table tr td span.active[disabled].focus,\n.datepicker table tr td span.active:hover[disabled].focus,\n.datepicker table tr td span.active.disabled[disabled].focus,\n.datepicker table tr td span.active.disabled:hover[disabled].focus,\nfieldset[disabled] .datepicker table tr td span.active.focus,\nfieldset[disabled] .datepicker table tr td span.active:hover.focus,\nfieldset[disabled] .datepicker table tr td span.active.disabled.focus,\nfieldset[disabled] .datepicker table tr td span.active.disabled:hover.focus {\n  background-color: #337ab7;\n  border-color: #2e6da4;\n}\n.datepicker table tr td span.old,\n.datepicker table tr td span.new {\n  color: #777777;\n}\n.datepicker .datepicker-switch {\n  width: 145px;\n}\n.datepicker .datepicker-switch,\n.datepicker .prev,\n.datepicker .next,\n.datepicker tfoot tr th {\n  cursor: pointer;\n}\n.datepicker .datepicker-switch:hover,\n.datepicker .prev:hover,\n.datepicker .next:hover,\n.datepicker tfoot tr th:hover {\n  background: #eeeeee;\n}\n.datepicker .cw {\n  font-size: 10px;\n  width: 12px;\n  padding: 0 2px 0 5px;\n  vertical-align: middle;\n}\n.input-group.date .input-group-addon {\n  cursor: pointer;\n}\n.input-daterange {\n  width: 100%;\n}\n.input-daterange input {\n  text-align: center;\n}\n.input-daterange input:first-child {\n  border-radius: 3px 0 0 3px;\n}\n.input-daterange input:last-child {\n  border-radius: 0 3px 3px 0;\n}\n.input-daterange .input-group-addon {\n  width: auto;\n  min-width: 16px;\n  padding: 4px 5px;\n  line-height: 1.42857143;\n  text-shadow: 0 1px 0 #fff;\n  border-width: 1px 0;\n  margin-left: -5px;\n  margin-right: -5px;\n}\n.datepicker.dropdown-menu {\n  position: absolute;\n  top: 100%;\n  left: 0;\n  z-index: 1000;\n  display: none;\n  float: left;\n  min-width: 160px;\n  list-style: none;\n  background-color: #fff;\n  border: 1px solid #ccc;\n  border: 1px solid rgba(0, 0, 0, 0.15);\n  border-radius: 4px;\n  -webkit-box-shadow: 0 6px 12px rgba(0, 0, 0, 0.175);\n  -moz-box-shadow: 0 6px 12px rgba(0, 0, 0, 0.175);\n  box-shadow: 0 6px 12px rgba(0, 0, 0, 0.175);\n  -webkit-background-clip: padding-box;\n  -moz-background-clip: padding;\n  background-clip: padding-box;\n  color: #333333;\n  font-size: 13px;\n  line-height: 1.42857143;\n}\n.datepicker.dropdown-menu th,\n.datepicker.datepicker-inline th,\n.datepicker.dropdown-menu td,\n.datepicker.datepicker-inline td {\n  padding: 0px 5px;\n}\n/*# sourceMappingURL=bootstrap-datepicker3.standalone.css.map */"
  },
  {
    "path": "app_backend/static/plugin/bootstrap-datepicker-1.6.4/js/bootstrap-datepicker.js",
    "content": "/*!\n * Datepicker for Bootstrap v1.6.4 (https://github.com/eternicode/bootstrap-datepicker)\n *\n * Copyright 2012 Stefan Petre\n * Improvements by Andrew Rowls\n * Licensed under the Apache License v2.0 (http://www.apache.org/licenses/LICENSE-2.0)\n */(function(factory){\n    if (typeof define === \"function\" && define.amd) {\n        define([\"jquery\"], factory);\n    } else if (typeof exports === 'object') {\n        factory(require('jquery'));\n    } else {\n        factory(jQuery);\n    }\n}(function($, undefined){\n\n\tfunction UTCDate(){\n\t\treturn new Date(Date.UTC.apply(Date, arguments));\n\t}\n\tfunction UTCToday(){\n\t\tvar today = new Date();\n\t\treturn UTCDate(today.getFullYear(), today.getMonth(), today.getDate());\n\t}\n\tfunction isUTCEquals(date1, date2) {\n\t\treturn (\n\t\t\tdate1.getUTCFullYear() === date2.getUTCFullYear() &&\n\t\t\tdate1.getUTCMonth() === date2.getUTCMonth() &&\n\t\t\tdate1.getUTCDate() === date2.getUTCDate()\n\t\t);\n\t}\n\tfunction alias(method){\n\t\treturn function(){\n\t\t\treturn this[method].apply(this, arguments);\n\t\t};\n\t}\n\tfunction isValidDate(d) {\n\t\treturn d && !isNaN(d.getTime());\n\t}\n\n\tvar DateArray = (function(){\n\t\tvar extras = {\n\t\t\tget: function(i){\n\t\t\t\treturn this.slice(i)[0];\n\t\t\t},\n\t\t\tcontains: function(d){\n\t\t\t\t// Array.indexOf is not cross-browser;\n\t\t\t\t// $.inArray doesn't work with Dates\n\t\t\t\tvar val = d && d.valueOf();\n\t\t\t\tfor (var i=0, l=this.length; i < l; i++)\n\t\t\t\t\tif (this[i].valueOf() === val)\n\t\t\t\t\t\treturn i;\n\t\t\t\treturn -1;\n\t\t\t},\n\t\t\tremove: function(i){\n\t\t\t\tthis.splice(i,1);\n\t\t\t},\n\t\t\treplace: function(new_array){\n\t\t\t\tif (!new_array)\n\t\t\t\t\treturn;\n\t\t\t\tif (!$.isArray(new_array))\n\t\t\t\t\tnew_array = [new_array];\n\t\t\t\tthis.clear();\n\t\t\t\tthis.push.apply(this, new_array);\n\t\t\t},\n\t\t\tclear: function(){\n\t\t\t\tthis.length = 0;\n\t\t\t},\n\t\t\tcopy: function(){\n\t\t\t\tvar a = new DateArray();\n\t\t\t\ta.replace(this);\n\t\t\t\treturn a;\n\t\t\t}\n\t\t};\n\n\t\treturn function(){\n\t\t\tvar a = [];\n\t\t\ta.push.apply(a, arguments);\n\t\t\t$.extend(a, extras);\n\t\t\treturn a;\n\t\t};\n\t})();\n\n\n\t// Picker object\n\n\tvar Datepicker = function(element, options){\n\t\t$(element).data('datepicker', this);\n\t\tthis._process_options(options);\n\n\t\tthis.dates = new DateArray();\n\t\tthis.viewDate = this.o.defaultViewDate;\n\t\tthis.focusDate = null;\n\n\t\tthis.element = $(element);\n\t\tthis.isInput = this.element.is('input');\n\t\tthis.inputField = this.isInput ? this.element : this.element.find('input');\n\t\tthis.component = this.element.hasClass('date') ? this.element.find('.add-on, .input-group-addon, .btn') : false;\n\t\tthis.hasInput = this.component && this.inputField.length;\n\t\tif (this.component && this.component.length === 0)\n\t\t\tthis.component = false;\n\t\tthis.isInline = !this.component && this.element.is('div');\n\n\t\tthis.picker = $(DPGlobal.template);\n\n\t\t// Checking templates and inserting\n\t\tif (this._check_template(this.o.templates.leftArrow)) {\n\t\t\tthis.picker.find('.prev').html(this.o.templates.leftArrow);\n\t\t}\n\t\tif (this._check_template(this.o.templates.rightArrow)) {\n\t\t\tthis.picker.find('.next').html(this.o.templates.rightArrow);\n\t\t}\n\n\t\tthis._buildEvents();\n\t\tthis._attachEvents();\n\n\t\tif (this.isInline){\n\t\t\tthis.picker.addClass('datepicker-inline').appendTo(this.element);\n\t\t}\n\t\telse {\n\t\t\tthis.picker.addClass('datepicker-dropdown dropdown-menu');\n\t\t}\n\n\t\tif (this.o.rtl){\n\t\t\tthis.picker.addClass('datepicker-rtl');\n\t\t}\n\n\t\tthis.viewMode = this.o.startView;\n\n\t\tif (this.o.calendarWeeks)\n\t\t\tthis.picker.find('thead .datepicker-title, tfoot .today, tfoot .clear')\n\t\t\t\t\t\t.attr('colspan', function(i, val){\n\t\t\t\t\t\t\treturn parseInt(val) + 1;\n\t\t\t\t\t\t});\n\n\t\tthis._allow_update = false;\n\n\t\tthis.setStartDate(this._o.startDate);\n\t\tthis.setEndDate(this._o.endDate);\n\t\tthis.setDaysOfWeekDisabled(this.o.daysOfWeekDisabled);\n\t\tthis.setDaysOfWeekHighlighted(this.o.daysOfWeekHighlighted);\n\t\tthis.setDatesDisabled(this.o.datesDisabled);\n\n\t\tthis.fillDow();\n\t\tthis.fillMonths();\n\n\t\tthis._allow_update = true;\n\n\t\tthis.update();\n\t\tthis.showMode();\n\n\t\tif (this.isInline){\n\t\t\tthis.show();\n\t\t}\n\t};\n\n\tDatepicker.prototype = {\n\t\tconstructor: Datepicker,\n\n\t\t_resolveViewName: function(view, default_value){\n\t\t\tif (view === 0 || view === 'days' || view === 'month') {\n\t\t\t\treturn 0;\n\t\t\t}\n\t\t\tif (view === 1 || view === 'months' || view === 'year') {\n\t\t\t\treturn 1;\n\t\t\t}\n\t\t\tif (view === 2 || view === 'years' || view === 'decade') {\n\t\t\t\treturn 2;\n\t\t\t}\n\t\t\tif (view === 3 || view === 'decades' || view === 'century') {\n\t\t\t\treturn 3;\n\t\t\t}\n\t\t\tif (view === 4 || view === 'centuries' || view === 'millennium') {\n\t\t\t\treturn 4;\n\t\t\t}\n\t\t\treturn default_value === undefined ? false : default_value;\n\t\t},\n\n\t\t_check_template: function(tmp){\n\t\t\ttry {\n\t\t\t\t// If empty\n\t\t\t\tif (tmp === undefined || tmp === \"\") {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t\t// If no html, everything ok\n\t\t\t\tif ((tmp.match(/[<>]/g) || []).length <= 0) {\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t\t// Checking if html is fine\n\t\t\t\tvar jDom = $(tmp);\n\t\t\t\treturn jDom.length > 0;\n\t\t\t}\n\t\t\tcatch (ex) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t},\n\n\t\t_process_options: function(opts){\n\t\t\t// Store raw options for reference\n\t\t\tthis._o = $.extend({}, this._o, opts);\n\t\t\t// Processed options\n\t\t\tvar o = this.o = $.extend({}, this._o);\n\n\t\t\t// Check if \"de-DE\" style date is available, if not language should\n\t\t\t// fallback to 2 letter code eg \"de\"\n\t\t\tvar lang = o.language;\n\t\t\tif (!dates[lang]){\n\t\t\t\tlang = lang.split('-')[0];\n\t\t\t\tif (!dates[lang])\n\t\t\t\t\tlang = defaults.language;\n\t\t\t}\n\t\t\to.language = lang;\n\n\t\t\t// Retrieve view index from any aliases\n\t\t\to.startView = this._resolveViewName(o.startView, 0);\n\t\t\to.minViewMode = this._resolveViewName(o.minViewMode, 0);\n\t\t\to.maxViewMode = this._resolveViewName(o.maxViewMode, 4);\n\n\t\t\t// Check that the start view is between min and max\n\t\t\to.startView = Math.min(o.startView, o.maxViewMode);\n\t\t\to.startView = Math.max(o.startView, o.minViewMode);\n\n\t\t\t// true, false, or Number > 0\n\t\t\tif (o.multidate !== true){\n\t\t\t\to.multidate = Number(o.multidate) || false;\n\t\t\t\tif (o.multidate !== false)\n\t\t\t\t\to.multidate = Math.max(0, o.multidate);\n\t\t\t}\n\t\t\to.multidateSeparator = String(o.multidateSeparator);\n\n\t\t\to.weekStart %= 7;\n\t\t\to.weekEnd = (o.weekStart + 6) % 7;\n\n\t\t\tvar format = DPGlobal.parseFormat(o.format);\n\t\t\tif (o.startDate !== -Infinity){\n\t\t\t\tif (!!o.startDate){\n\t\t\t\t\tif (o.startDate instanceof Date)\n\t\t\t\t\t\to.startDate = this._local_to_utc(this._zero_time(o.startDate));\n\t\t\t\t\telse\n\t\t\t\t\t\to.startDate = DPGlobal.parseDate(o.startDate, format, o.language, o.assumeNearbyYear);\n\t\t\t\t}\n\t\t\t\telse {\n\t\t\t\t\to.startDate = -Infinity;\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (o.endDate !== Infinity){\n\t\t\t\tif (!!o.endDate){\n\t\t\t\t\tif (o.endDate instanceof Date)\n\t\t\t\t\t\to.endDate = this._local_to_utc(this._zero_time(o.endDate));\n\t\t\t\t\telse\n\t\t\t\t\t\to.endDate = DPGlobal.parseDate(o.endDate, format, o.language, o.assumeNearbyYear);\n\t\t\t\t}\n\t\t\t\telse {\n\t\t\t\t\to.endDate = Infinity;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\to.daysOfWeekDisabled = o.daysOfWeekDisabled||[];\n\t\t\tif (!$.isArray(o.daysOfWeekDisabled))\n\t\t\t\to.daysOfWeekDisabled = o.daysOfWeekDisabled.split(/[,\\s]*/);\n\t\t\to.daysOfWeekDisabled = $.map(o.daysOfWeekDisabled, function(d){\n\t\t\t\treturn parseInt(d, 10);\n\t\t\t});\n\n\t\t\to.daysOfWeekHighlighted = o.daysOfWeekHighlighted||[];\n\t\t\tif (!$.isArray(o.daysOfWeekHighlighted))\n\t\t\t\to.daysOfWeekHighlighted = o.daysOfWeekHighlighted.split(/[,\\s]*/);\n\t\t\to.daysOfWeekHighlighted = $.map(o.daysOfWeekHighlighted, function(d){\n\t\t\t\treturn parseInt(d, 10);\n\t\t\t});\n\n\t\t\to.datesDisabled = o.datesDisabled||[];\n\t\t\tif (!$.isArray(o.datesDisabled)) {\n\t\t\t\to.datesDisabled = [\n\t\t\t\t\to.datesDisabled\n\t\t\t\t];\n\t\t\t}\n\t\t\to.datesDisabled = $.map(o.datesDisabled,function(d){\n\t\t\t\treturn DPGlobal.parseDate(d, format, o.language, o.assumeNearbyYear);\n\t\t\t});\n\n\t\t\tvar plc = String(o.orientation).toLowerCase().split(/\\s+/g),\n\t\t\t\t_plc = o.orientation.toLowerCase();\n\t\t\tplc = $.grep(plc, function(word){\n\t\t\t\treturn /^auto|left|right|top|bottom$/.test(word);\n\t\t\t});\n\t\t\to.orientation = {x: 'auto', y: 'auto'};\n\t\t\tif (!_plc || _plc === 'auto')\n\t\t\t\t; // no action\n\t\t\telse if (plc.length === 1){\n\t\t\t\tswitch (plc[0]){\n\t\t\t\t\tcase 'top':\n\t\t\t\t\tcase 'bottom':\n\t\t\t\t\t\to.orientation.y = plc[0];\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase 'left':\n\t\t\t\t\tcase 'right':\n\t\t\t\t\t\to.orientation.x = plc[0];\n\t\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t\telse {\n\t\t\t\t_plc = $.grep(plc, function(word){\n\t\t\t\t\treturn /^left|right$/.test(word);\n\t\t\t\t});\n\t\t\t\to.orientation.x = _plc[0] || 'auto';\n\n\t\t\t\t_plc = $.grep(plc, function(word){\n\t\t\t\t\treturn /^top|bottom$/.test(word);\n\t\t\t\t});\n\t\t\t\to.orientation.y = _plc[0] || 'auto';\n\t\t\t}\n\t\t\tif (o.defaultViewDate) {\n\t\t\t\tvar year = o.defaultViewDate.year || new Date().getFullYear();\n\t\t\t\tvar month = o.defaultViewDate.month || 0;\n\t\t\t\tvar day = o.defaultViewDate.day || 1;\n\t\t\t\to.defaultViewDate = UTCDate(year, month, day);\n\t\t\t} else {\n\t\t\t\to.defaultViewDate = UTCToday();\n\t\t\t}\n\t\t},\n\t\t_events: [],\n\t\t_secondaryEvents: [],\n\t\t_applyEvents: function(evs){\n\t\t\tfor (var i=0, el, ch, ev; i < evs.length; i++){\n\t\t\t\tel = evs[i][0];\n\t\t\t\tif (evs[i].length === 2){\n\t\t\t\t\tch = undefined;\n\t\t\t\t\tev = evs[i][1];\n\t\t\t\t}\n\t\t\t\telse if (evs[i].length === 3){\n\t\t\t\t\tch = evs[i][1];\n\t\t\t\t\tev = evs[i][2];\n\t\t\t\t}\n\t\t\t\tel.on(ev, ch);\n\t\t\t}\n\t\t},\n\t\t_unapplyEvents: function(evs){\n\t\t\tfor (var i=0, el, ev, ch; i < evs.length; i++){\n\t\t\t\tel = evs[i][0];\n\t\t\t\tif (evs[i].length === 2){\n\t\t\t\t\tch = undefined;\n\t\t\t\t\tev = evs[i][1];\n\t\t\t\t}\n\t\t\t\telse if (evs[i].length === 3){\n\t\t\t\t\tch = evs[i][1];\n\t\t\t\t\tev = evs[i][2];\n\t\t\t\t}\n\t\t\t\tel.off(ev, ch);\n\t\t\t}\n\t\t},\n\t\t_buildEvents: function(){\n            var events = {\n                keyup: $.proxy(function(e){\n                    if ($.inArray(e.keyCode, [27, 37, 39, 38, 40, 32, 13, 9]) === -1)\n                        this.update();\n                }, this),\n                keydown: $.proxy(this.keydown, this),\n                paste: $.proxy(this.paste, this)\n            };\n\n            if (this.o.showOnFocus === true) {\n                events.focus = $.proxy(this.show, this);\n            }\n\n            if (this.isInput) { // single input\n                this._events = [\n                    [this.element, events]\n                ];\n            }\n            else if (this.component && this.hasInput) { // component: input + button\n                this._events = [\n                    // For components that are not readonly, allow keyboard nav\n                    [this.inputField, events],\n                    [this.component, {\n                        click: $.proxy(this.show, this)\n                    }]\n                ];\n            }\n\t\t\telse {\n\t\t\t\tthis._events = [\n\t\t\t\t\t[this.element, {\n\t\t\t\t\t\tclick: $.proxy(this.show, this),\n\t\t\t\t\t\tkeydown: $.proxy(this.keydown, this)\n\t\t\t\t\t}]\n\t\t\t\t];\n\t\t\t}\n\t\t\tthis._events.push(\n\t\t\t\t// Component: listen for blur on element descendants\n\t\t\t\t[this.element, '*', {\n\t\t\t\t\tblur: $.proxy(function(e){\n\t\t\t\t\t\tthis._focused_from = e.target;\n\t\t\t\t\t}, this)\n\t\t\t\t}],\n\t\t\t\t// Input: listen for blur on element\n\t\t\t\t[this.element, {\n\t\t\t\t\tblur: $.proxy(function(e){\n\t\t\t\t\t\tthis._focused_from = e.target;\n\t\t\t\t\t}, this)\n\t\t\t\t}]\n\t\t\t);\n\n\t\t\tif (this.o.immediateUpdates) {\n\t\t\t\t// Trigger input updates immediately on changed year/month\n\t\t\t\tthis._events.push([this.element, {\n\t\t\t\t\t'changeYear changeMonth': $.proxy(function(e){\n\t\t\t\t\t\tthis.update(e.date);\n\t\t\t\t\t}, this)\n\t\t\t\t}]);\n\t\t\t}\n\n\t\t\tthis._secondaryEvents = [\n\t\t\t\t[this.picker, {\n\t\t\t\t\tclick: $.proxy(this.click, this)\n\t\t\t\t}],\n\t\t\t\t[$(window), {\n\t\t\t\t\tresize: $.proxy(this.place, this)\n\t\t\t\t}],\n\t\t\t\t[$(document), {\n\t\t\t\t\tmousedown: $.proxy(function(e){\n\t\t\t\t\t\t// Clicked outside the datepicker, hide it\n\t\t\t\t\t\tif (!(\n\t\t\t\t\t\t\tthis.element.is(e.target) ||\n\t\t\t\t\t\t\tthis.element.find(e.target).length ||\n\t\t\t\t\t\t\tthis.picker.is(e.target) ||\n\t\t\t\t\t\t\tthis.picker.find(e.target).length ||\n\t\t\t\t\t\t\tthis.isInline\n\t\t\t\t\t\t)){\n\t\t\t\t\t\t\tthis.hide();\n\t\t\t\t\t\t}\n\t\t\t\t\t}, this)\n\t\t\t\t}]\n\t\t\t];\n\t\t},\n\t\t_attachEvents: function(){\n\t\t\tthis._detachEvents();\n\t\t\tthis._applyEvents(this._events);\n\t\t},\n\t\t_detachEvents: function(){\n\t\t\tthis._unapplyEvents(this._events);\n\t\t},\n\t\t_attachSecondaryEvents: function(){\n\t\t\tthis._detachSecondaryEvents();\n\t\t\tthis._applyEvents(this._secondaryEvents);\n\t\t},\n\t\t_detachSecondaryEvents: function(){\n\t\t\tthis._unapplyEvents(this._secondaryEvents);\n\t\t},\n\t\t_trigger: function(event, altdate){\n\t\t\tvar date = altdate || this.dates.get(-1),\n\t\t\t\tlocal_date = this._utc_to_local(date);\n\n\t\t\tthis.element.trigger({\n\t\t\t\ttype: event,\n\t\t\t\tdate: local_date,\n\t\t\t\tdates: $.map(this.dates, this._utc_to_local),\n\t\t\t\tformat: $.proxy(function(ix, format){\n\t\t\t\t\tif (arguments.length === 0){\n\t\t\t\t\t\tix = this.dates.length - 1;\n\t\t\t\t\t\tformat = this.o.format;\n\t\t\t\t\t}\n\t\t\t\t\telse if (typeof ix === 'string'){\n\t\t\t\t\t\tformat = ix;\n\t\t\t\t\t\tix = this.dates.length - 1;\n\t\t\t\t\t}\n\t\t\t\t\tformat = format || this.o.format;\n\t\t\t\t\tvar date = this.dates.get(ix);\n\t\t\t\t\treturn DPGlobal.formatDate(date, format, this.o.language);\n\t\t\t\t}, this)\n\t\t\t});\n\t\t},\n\n\t\tshow: function(){\n\t\t\tif (this.inputField.prop('disabled') || (this.inputField.prop('readonly') && this.o.enableOnReadonly === false))\n\t\t\t\treturn;\n\t\t\tif (!this.isInline)\n\t\t\t\tthis.picker.appendTo(this.o.container);\n\t\t\tthis.place();\n\t\t\tthis.picker.show();\n\t\t\tthis._attachSecondaryEvents();\n\t\t\tthis._trigger('show');\n\t\t\tif ((window.navigator.msMaxTouchPoints || 'ontouchstart' in document) && this.o.disableTouchKeyboard) {\n\t\t\t\t$(this.element).blur();\n\t\t\t}\n\t\t\treturn this;\n\t\t},\n\n\t\thide: function(){\n\t\t\tif (this.isInline || !this.picker.is(':visible'))\n\t\t\t\treturn this;\n\t\t\tthis.focusDate = null;\n\t\t\tthis.picker.hide().detach();\n\t\t\tthis._detachSecondaryEvents();\n\t\t\tthis.viewMode = this.o.startView;\n\t\t\tthis.showMode();\n\n\t\t\tif (this.o.forceParse && this.inputField.val())\n\t\t\t\tthis.setValue();\n\t\t\tthis._trigger('hide');\n\t\t\treturn this;\n\t\t},\n\n\t\tdestroy: function(){\n\t\t\tthis.hide();\n\t\t\tthis._detachEvents();\n\t\t\tthis._detachSecondaryEvents();\n\t\t\tthis.picker.remove();\n\t\t\tdelete this.element.data().datepicker;\n\t\t\tif (!this.isInput){\n\t\t\t\tdelete this.element.data().date;\n\t\t\t}\n\t\t\treturn this;\n\t\t},\n\n\t\tpaste: function(evt){\n\t\t\tvar dateString;\n\t\t\tif (evt.originalEvent.clipboardData && evt.originalEvent.clipboardData.types\n\t\t\t\t&& $.inArray('text/plain', evt.originalEvent.clipboardData.types) !== -1) {\n\t\t\t\tdateString = evt.originalEvent.clipboardData.getData('text/plain');\n\t\t\t}\n\t\t\telse if (window.clipboardData) {\n\t\t\t\tdateString = window.clipboardData.getData('Text');\n\t\t\t}\n\t\t\telse {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tthis.setDate(dateString);\n\t\t\tthis.update();\n\t\t\tevt.preventDefault();\n\t\t},\n\n\t\t_utc_to_local: function(utc){\n\t\t\treturn utc && new Date(utc.getTime() + (utc.getTimezoneOffset()*60000));\n\t\t},\n\t\t_local_to_utc: function(local){\n\t\t\treturn local && new Date(local.getTime() - (local.getTimezoneOffset()*60000));\n\t\t},\n\t\t_zero_time: function(local){\n\t\t\treturn local && new Date(local.getFullYear(), local.getMonth(), local.getDate());\n\t\t},\n\t\t_zero_utc_time: function(utc){\n\t\t\treturn utc && new Date(Date.UTC(utc.getUTCFullYear(), utc.getUTCMonth(), utc.getUTCDate()));\n\t\t},\n\n\t\tgetDates: function(){\n\t\t\treturn $.map(this.dates, this._utc_to_local);\n\t\t},\n\n\t\tgetUTCDates: function(){\n\t\t\treturn $.map(this.dates, function(d){\n\t\t\t\treturn new Date(d);\n\t\t\t});\n\t\t},\n\n\t\tgetDate: function(){\n\t\t\treturn this._utc_to_local(this.getUTCDate());\n\t\t},\n\n\t\tgetUTCDate: function(){\n\t\t\tvar selected_date = this.dates.get(-1);\n\t\t\tif (typeof selected_date !== 'undefined') {\n\t\t\t\treturn new Date(selected_date);\n\t\t\t} else {\n\t\t\t\treturn null;\n\t\t\t}\n\t\t},\n\n\t\tclearDates: function(){\n\t\t\tif (this.inputField) {\n\t\t\t\tthis.inputField.val('');\n\t\t\t}\n\n\t\t\tthis.update();\n\t\t\tthis._trigger('changeDate');\n\n\t\t\tif (this.o.autoclose) {\n\t\t\t\tthis.hide();\n\t\t\t}\n\t\t},\n\t\tsetDates: function(){\n\t\t\tvar args = $.isArray(arguments[0]) ? arguments[0] : arguments;\n\t\t\tthis.update.apply(this, args);\n\t\t\tthis._trigger('changeDate');\n\t\t\tthis.setValue();\n\t\t\treturn this;\n\t\t},\n\n\t\tsetUTCDates: function(){\n\t\t\tvar args = $.isArray(arguments[0]) ? arguments[0] : arguments;\n\t\t\tthis.update.apply(this, $.map(args, this._utc_to_local));\n\t\t\tthis._trigger('changeDate');\n\t\t\tthis.setValue();\n\t\t\treturn this;\n\t\t},\n\n\t\tsetDate: alias('setDates'),\n\t\tsetUTCDate: alias('setUTCDates'),\n\t\tremove: alias('destroy'),\n\n\t\tsetValue: function(){\n\t\t\tvar formatted = this.getFormattedDate();\n\t\t\tthis.inputField.val(formatted);\n\t\t\treturn this;\n\t\t},\n\n\t\tgetFormattedDate: function(format){\n\t\t\tif (format === undefined)\n\t\t\t\tformat = this.o.format;\n\n\t\t\tvar lang = this.o.language;\n\t\t\treturn $.map(this.dates, function(d){\n\t\t\t\treturn DPGlobal.formatDate(d, format, lang);\n\t\t\t}).join(this.o.multidateSeparator);\n\t\t},\n\n\t\tgetStartDate: function(){\n\t\t\treturn this.o.startDate;\n\t\t},\n\n\t\tsetStartDate: function(startDate){\n\t\t\tthis._process_options({startDate: startDate});\n\t\t\tthis.update();\n\t\t\tthis.updateNavArrows();\n\t\t\treturn this;\n\t\t},\n\n\t\tgetEndDate: function(){\n\t\t\treturn this.o.endDate;\n\t\t},\n\n\t\tsetEndDate: function(endDate){\n\t\t\tthis._process_options({endDate: endDate});\n\t\t\tthis.update();\n\t\t\tthis.updateNavArrows();\n\t\t\treturn this;\n\t\t},\n\n\t\tsetDaysOfWeekDisabled: function(daysOfWeekDisabled){\n\t\t\tthis._process_options({daysOfWeekDisabled: daysOfWeekDisabled});\n\t\t\tthis.update();\n\t\t\tthis.updateNavArrows();\n\t\t\treturn this;\n\t\t},\n\n\t\tsetDaysOfWeekHighlighted: function(daysOfWeekHighlighted){\n\t\t\tthis._process_options({daysOfWeekHighlighted: daysOfWeekHighlighted});\n\t\t\tthis.update();\n\t\t\treturn this;\n\t\t},\n\n\t\tsetDatesDisabled: function(datesDisabled){\n\t\t\tthis._process_options({datesDisabled: datesDisabled});\n\t\t\tthis.update();\n\t\t\tthis.updateNavArrows();\n\t\t},\n\n\t\tplace: function(){\n\t\t\tif (this.isInline)\n\t\t\t\treturn this;\n\t\t\tvar calendarWidth = this.picker.outerWidth(),\n\t\t\t\tcalendarHeight = this.picker.outerHeight(),\n\t\t\t\tvisualPadding = 10,\n\t\t\t\tcontainer = $(this.o.container),\n\t\t\t\twindowWidth = container.width(),\n\t\t\t\tscrollTop = this.o.container === 'body' ? $(document).scrollTop() : container.scrollTop(),\n\t\t\t\tappendOffset = container.offset();\n\n\t\t\tvar parentsZindex = [];\n\t\t\tthis.element.parents().each(function(){\n\t\t\t\tvar itemZIndex = $(this).css('z-index');\n\t\t\t\tif (itemZIndex !== 'auto' && itemZIndex !== 0) parentsZindex.push(parseInt(itemZIndex));\n\t\t\t});\n\t\t\tvar zIndex = Math.max.apply(Math, parentsZindex) + this.o.zIndexOffset;\n\t\t\tvar offset = this.component ? this.component.parent().offset() : this.element.offset();\n\t\t\tvar height = this.component ? this.component.outerHeight(true) : this.element.outerHeight(false);\n\t\t\tvar width = this.component ? this.component.outerWidth(true) : this.element.outerWidth(false);\n\t\t\tvar left = offset.left - appendOffset.left,\n\t\t\t\ttop = offset.top - appendOffset.top;\n\n\t\t\tif (this.o.container !== 'body') {\n\t\t\t\ttop += scrollTop;\n\t\t\t}\n\n\t\t\tthis.picker.removeClass(\n\t\t\t\t'datepicker-orient-top datepicker-orient-bottom '+\n\t\t\t\t'datepicker-orient-right datepicker-orient-left'\n\t\t\t);\n\n\t\t\tif (this.o.orientation.x !== 'auto'){\n\t\t\t\tthis.picker.addClass('datepicker-orient-' + this.o.orientation.x);\n\t\t\t\tif (this.o.orientation.x === 'right')\n\t\t\t\t\tleft -= calendarWidth - width;\n\t\t\t}\n\t\t\t// auto x orientation is best-placement: if it crosses a window\n\t\t\t// edge, fudge it sideways\n\t\t\telse {\n\t\t\t\tif (offset.left < 0) {\n\t\t\t\t\t// component is outside the window on the left side. Move it into visible range\n\t\t\t\t\tthis.picker.addClass('datepicker-orient-left');\n\t\t\t\t\tleft -= offset.left - visualPadding;\n\t\t\t\t} else if (left + calendarWidth > windowWidth) {\n\t\t\t\t\t// the calendar passes the widow right edge. Align it to component right side\n\t\t\t\t\tthis.picker.addClass('datepicker-orient-right');\n\t\t\t\t\tleft += width - calendarWidth;\n\t\t\t\t} else {\n\t\t\t\t\t// Default to left\n\t\t\t\t\tthis.picker.addClass('datepicker-orient-left');\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// auto y orientation is best-situation: top or bottom, no fudging,\n\t\t\t// decision based on which shows more of the calendar\n\t\t\tvar yorient = this.o.orientation.y,\n\t\t\t\ttop_overflow;\n\t\t\tif (yorient === 'auto'){\n\t\t\t\ttop_overflow = -scrollTop + top - calendarHeight;\n\t\t\t\tyorient = top_overflow < 0 ? 'bottom' : 'top';\n\t\t\t}\n\n\t\t\tthis.picker.addClass('datepicker-orient-' + yorient);\n\t\t\tif (yorient === 'top')\n\t\t\t\ttop -= calendarHeight + parseInt(this.picker.css('padding-top'));\n\t\t\telse\n\t\t\t\ttop += height;\n\n\t\t\tif (this.o.rtl) {\n\t\t\t\tvar right = windowWidth - (left + width);\n\t\t\t\tthis.picker.css({\n\t\t\t\t\ttop: top,\n\t\t\t\t\tright: right,\n\t\t\t\t\tzIndex: zIndex\n\t\t\t\t});\n\t\t\t} else {\n\t\t\t\tthis.picker.css({\n\t\t\t\t\ttop: top,\n\t\t\t\t\tleft: left,\n\t\t\t\t\tzIndex: zIndex\n\t\t\t\t});\n\t\t\t}\n\t\t\treturn this;\n\t\t},\n\n\t\t_allow_update: true,\n\t\tupdate: function(){\n\t\t\tif (!this._allow_update)\n\t\t\t\treturn this;\n\n\t\t\tvar oldDates = this.dates.copy(),\n\t\t\t\tdates = [],\n\t\t\t\tfromArgs = false;\n\t\t\tif (arguments.length){\n\t\t\t\t$.each(arguments, $.proxy(function(i, date){\n\t\t\t\t\tif (date instanceof Date)\n\t\t\t\t\t\tdate = this._local_to_utc(date);\n\t\t\t\t\tdates.push(date);\n\t\t\t\t}, this));\n\t\t\t\tfromArgs = true;\n\t\t\t}\n\t\t\telse {\n\t\t\t\tdates = this.isInput\n\t\t\t\t\t\t? this.element.val()\n\t\t\t\t\t\t: this.element.data('date') || this.inputField.val();\n\t\t\t\tif (dates && this.o.multidate)\n\t\t\t\t\tdates = dates.split(this.o.multidateSeparator);\n\t\t\t\telse\n\t\t\t\t\tdates = [dates];\n\t\t\t\tdelete this.element.data().date;\n\t\t\t}\n\n\t\t\tdates = $.map(dates, $.proxy(function(date){\n\t\t\t\treturn DPGlobal.parseDate(date, this.o.format, this.o.language, this.o.assumeNearbyYear);\n\t\t\t}, this));\n\t\t\tdates = $.grep(dates, $.proxy(function(date){\n\t\t\t\treturn (\n\t\t\t\t\t!this.dateWithinRange(date) ||\n\t\t\t\t\t!date\n\t\t\t\t);\n\t\t\t}, this), true);\n\t\t\tthis.dates.replace(dates);\n\n\t\t\tif (this.dates.length)\n\t\t\t\tthis.viewDate = new Date(this.dates.get(-1));\n\t\t\telse if (this.viewDate < this.o.startDate)\n\t\t\t\tthis.viewDate = new Date(this.o.startDate);\n\t\t\telse if (this.viewDate > this.o.endDate)\n\t\t\t\tthis.viewDate = new Date(this.o.endDate);\n\t\t\telse\n\t\t\t\tthis.viewDate = this.o.defaultViewDate;\n\n\t\t\tif (fromArgs){\n\t\t\t\t// setting date by clicking\n\t\t\t\tthis.setValue();\n\t\t\t}\n\t\t\telse if (dates.length){\n\t\t\t\t// setting date by typing\n\t\t\t\tif (String(oldDates) !== String(this.dates))\n\t\t\t\t\tthis._trigger('changeDate');\n\t\t\t}\n\t\t\tif (!this.dates.length && oldDates.length)\n\t\t\t\tthis._trigger('clearDate');\n\n\t\t\tthis.fill();\n\t\t\tthis.element.change();\n\t\t\treturn this;\n\t\t},\n\n\t\tfillDow: function(){\n\t\t\tvar dowCnt = this.o.weekStart,\n\t\t\t\thtml = '<tr>';\n\t\t\tif (this.o.calendarWeeks){\n\t\t\t\tthis.picker.find('.datepicker-days .datepicker-switch')\n\t\t\t\t\t.attr('colspan', function(i, val){\n\t\t\t\t\t\treturn parseInt(val) + 1;\n\t\t\t\t\t});\n\t\t\t\thtml += '<th class=\"cw\">&#160;</th>';\n\t\t\t}\n\t\t\twhile (dowCnt < this.o.weekStart + 7){\n\t\t\t\thtml += '<th class=\"dow';\n        if ($.inArray(dowCnt, this.o.daysOfWeekDisabled) > -1)\n          html += ' disabled';\n        html += '\">'+dates[this.o.language].daysMin[(dowCnt++)%7]+'</th>';\n\t\t\t}\n\t\t\thtml += '</tr>';\n\t\t\tthis.picker.find('.datepicker-days thead').append(html);\n\t\t},\n\n\t\tfillMonths: function(){\n      var localDate = this._utc_to_local(this.viewDate);\n\t\t\tvar html = '',\n\t\t\ti = 0;\n\t\t\twhile (i < 12){\n        var focused = localDate && localDate.getMonth() === i ? ' focused' : '';\n\t\t\t\thtml += '<span class=\"month' + focused + '\">' + dates[this.o.language].monthsShort[i++]+'</span>';\n\t\t\t}\n\t\t\tthis.picker.find('.datepicker-months td').html(html);\n\t\t},\n\n\t\tsetRange: function(range){\n\t\t\tif (!range || !range.length)\n\t\t\t\tdelete this.range;\n\t\t\telse\n\t\t\t\tthis.range = $.map(range, function(d){\n\t\t\t\t\treturn d.valueOf();\n\t\t\t\t});\n\t\t\tthis.fill();\n\t\t},\n\n\t\tgetClassNames: function(date){\n\t\t\tvar cls = [],\n\t\t\t\tyear = this.viewDate.getUTCFullYear(),\n\t\t\t\tmonth = this.viewDate.getUTCMonth(),\n\t\t\t\ttoday = new Date();\n\t\t\tif (date.getUTCFullYear() < year || (date.getUTCFullYear() === year && date.getUTCMonth() < month)){\n\t\t\t\tcls.push('old');\n\t\t\t}\n\t\t\telse if (date.getUTCFullYear() > year || (date.getUTCFullYear() === year && date.getUTCMonth() > month)){\n\t\t\t\tcls.push('new');\n\t\t\t}\n\t\t\tif (this.focusDate && date.valueOf() === this.focusDate.valueOf())\n\t\t\t\tcls.push('focused');\n\t\t\t// Compare internal UTC date with local today, not UTC today\n\t\t\tif (this.o.todayHighlight &&\n\t\t\t\tdate.getUTCFullYear() === today.getFullYear() &&\n\t\t\t\tdate.getUTCMonth() === today.getMonth() &&\n\t\t\t\tdate.getUTCDate() === today.getDate()){\n\t\t\t\tcls.push('today');\n\t\t\t}\n\t\t\tif (this.dates.contains(date) !== -1)\n\t\t\t\tcls.push('active');\n\t\t\tif (!this.dateWithinRange(date)){\n\t\t\t\tcls.push('disabled');\n\t\t\t}\n\t\t\tif (this.dateIsDisabled(date)){\n\t\t\t\tcls.push('disabled', 'disabled-date');\t\n\t\t\t} \n\t\t\tif ($.inArray(date.getUTCDay(), this.o.daysOfWeekHighlighted) !== -1){\n\t\t\t\tcls.push('highlighted');\n\t\t\t}\n\n\t\t\tif (this.range){\n\t\t\t\tif (date > this.range[0] && date < this.range[this.range.length-1]){\n\t\t\t\t\tcls.push('range');\n\t\t\t\t}\n\t\t\t\tif ($.inArray(date.valueOf(), this.range) !== -1){\n\t\t\t\t\tcls.push('selected');\n\t\t\t\t}\n\t\t\t\tif (date.valueOf() === this.range[0]){\n          cls.push('range-start');\n        }\n        if (date.valueOf() === this.range[this.range.length-1]){\n          cls.push('range-end');\n        }\n\t\t\t}\n\t\t\treturn cls;\n\t\t},\n\n\t\t_fill_yearsView: function(selector, cssClass, factor, step, currentYear, startYear, endYear, callback){\n\t\t\tvar html, view, year, steps, startStep, endStep, thisYear, i, classes, tooltip, before;\n\n\t\t\thtml      = '';\n\t\t\tview      = this.picker.find(selector);\n\t\t\tyear      = parseInt(currentYear / factor, 10) * factor;\n\t\t\tstartStep = parseInt(startYear / step, 10) * step;\n\t\t\tendStep   = parseInt(endYear / step, 10) * step;\n\t\t\tsteps     = $.map(this.dates, function(d){\n\t\t\t\treturn parseInt(d.getUTCFullYear() / step, 10) * step;\n\t\t\t});\n\n\t\t\tview.find('.datepicker-switch').text(year + '-' + (year + step * 9));\n\n\t\t\tthisYear = year - step;\n\t\t\tfor (i = -1; i < 11; i += 1) {\n\t\t\t\tclasses = [cssClass];\n\t\t\t\ttooltip = null;\n\n\t\t\t\tif (i === -1) {\n\t\t\t\t\tclasses.push('old');\n\t\t\t\t} else if (i === 10) {\n\t\t\t\t\tclasses.push('new');\n\t\t\t\t}\n\t\t\t\tif ($.inArray(thisYear, steps) !== -1) {\n\t\t\t\t\tclasses.push('active');\n\t\t\t\t}\n\t\t\t\tif (thisYear < startStep || thisYear > endStep) {\n\t\t\t\t\tclasses.push('disabled');\n\t\t\t\t}\n        if (thisYear === this.viewDate.getFullYear()) {\n\t\t\t\t  classes.push('focused');\n        }\n\n\t\t\t\tif (callback !== $.noop) {\n\t\t\t\t\tbefore = callback(new Date(thisYear, 0, 1));\n\t\t\t\t\tif (before === undefined) {\n\t\t\t\t\t\tbefore = {};\n\t\t\t\t\t} else if (typeof(before) === 'boolean') {\n\t\t\t\t\t\tbefore = {enabled: before};\n\t\t\t\t\t} else if (typeof(before) === 'string') {\n\t\t\t\t\t\tbefore = {classes: before};\n\t\t\t\t\t}\n\t\t\t\t\tif (before.enabled === false) {\n\t\t\t\t\t\tclasses.push('disabled');\n\t\t\t\t\t}\n\t\t\t\t\tif (before.classes) {\n\t\t\t\t\t\tclasses = classes.concat(before.classes.split(/\\s+/));\n\t\t\t\t\t}\n\t\t\t\t\tif (before.tooltip) {\n\t\t\t\t\t\ttooltip = before.tooltip;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\thtml += '<span class=\"' + classes.join(' ') + '\"' + (tooltip ? ' title=\"' + tooltip + '\"' : '') + '>' + thisYear + '</span>';\n\t\t\t\tthisYear += step;\n\t\t\t}\n\t\t\tview.find('td').html(html);\n\t\t},\n\n\t\tfill: function(){\n\t\t\tvar d = new Date(this.viewDate),\n\t\t\t\tyear = d.getUTCFullYear(),\n\t\t\t\tmonth = d.getUTCMonth(),\n\t\t\t\tstartYear = this.o.startDate !== -Infinity ? this.o.startDate.getUTCFullYear() : -Infinity,\n\t\t\t\tstartMonth = this.o.startDate !== -Infinity ? this.o.startDate.getUTCMonth() : -Infinity,\n\t\t\t\tendYear = this.o.endDate !== Infinity ? this.o.endDate.getUTCFullYear() : Infinity,\n\t\t\t\tendMonth = this.o.endDate !== Infinity ? this.o.endDate.getUTCMonth() : Infinity,\n\t\t\t\ttodaytxt = dates[this.o.language].today || dates['en'].today || '',\n\t\t\t\tcleartxt = dates[this.o.language].clear || dates['en'].clear || '',\n\t\t\t\ttitleFormat = dates[this.o.language].titleFormat || dates['en'].titleFormat,\n\t\t\t\ttooltip,\n\t\t\t\tbefore;\n\t\t\tif (isNaN(year) || isNaN(month))\n\t\t\t\treturn;\n\t\t\tthis.picker.find('.datepicker-days .datepicker-switch')\n\t\t\t\t\t\t.text(DPGlobal.formatDate(d, titleFormat, this.o.language));\n\t\t\tthis.picker.find('tfoot .today')\n\t\t\t\t\t\t.text(todaytxt)\n\t\t\t\t\t\t.toggle(this.o.todayBtn !== false);\n\t\t\tthis.picker.find('tfoot .clear')\n\t\t\t\t\t\t.text(cleartxt)\n\t\t\t\t\t\t.toggle(this.o.clearBtn !== false);\n\t\t\tthis.picker.find('thead .datepicker-title')\n\t\t\t\t\t\t.text(this.o.title)\n\t\t\t\t\t\t.toggle(this.o.title !== '');\n\t\t\tthis.updateNavArrows();\n\t\t\tthis.fillMonths();\n\t\t\tvar prevMonth = UTCDate(year, month-1, 28),\n\t\t\t\tday = DPGlobal.getDaysInMonth(prevMonth.getUTCFullYear(), prevMonth.getUTCMonth());\n\t\t\tprevMonth.setUTCDate(day);\n\t\t\tprevMonth.setUTCDate(day - (prevMonth.getUTCDay() - this.o.weekStart + 7)%7);\n\t\t\tvar nextMonth = new Date(prevMonth);\n\t\t\tif (prevMonth.getUTCFullYear() < 100){\n        nextMonth.setUTCFullYear(prevMonth.getUTCFullYear());\n      }\n\t\t\tnextMonth.setUTCDate(nextMonth.getUTCDate() + 42);\n\t\t\tnextMonth = nextMonth.valueOf();\n\t\t\tvar html = [];\n\t\t\tvar clsName;\n\t\t\twhile (prevMonth.valueOf() < nextMonth){\n\t\t\t\tif (prevMonth.getUTCDay() === this.o.weekStart){\n\t\t\t\t\thtml.push('<tr>');\n\t\t\t\t\tif (this.o.calendarWeeks){\n\t\t\t\t\t\t// ISO 8601: First week contains first thursday.\n\t\t\t\t\t\t// ISO also states week starts on Monday, but we can be more abstract here.\n\t\t\t\t\t\tvar\n\t\t\t\t\t\t\t// Start of current week: based on weekstart/current date\n\t\t\t\t\t\t\tws = new Date(+prevMonth + (this.o.weekStart - prevMonth.getUTCDay() - 7) % 7 * 864e5),\n\t\t\t\t\t\t\t// Thursday of this week\n\t\t\t\t\t\t\tth = new Date(Number(ws) + (7 + 4 - ws.getUTCDay()) % 7 * 864e5),\n\t\t\t\t\t\t\t// First Thursday of year, year from thursday\n\t\t\t\t\t\t\tyth = new Date(Number(yth = UTCDate(th.getUTCFullYear(), 0, 1)) + (7 + 4 - yth.getUTCDay())%7*864e5),\n\t\t\t\t\t\t\t// Calendar week: ms between thursdays, div ms per day, div 7 days\n\t\t\t\t\t\t\tcalWeek =  (th - yth) / 864e5 / 7 + 1;\n\t\t\t\t\t\thtml.push('<td class=\"cw\">'+ calWeek +'</td>');\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tclsName = this.getClassNames(prevMonth);\n\t\t\t\tclsName.push('day');\n\n\t\t\t\tif (this.o.beforeShowDay !== $.noop){\n\t\t\t\t\tbefore = this.o.beforeShowDay(this._utc_to_local(prevMonth));\n\t\t\t\t\tif (before === undefined)\n\t\t\t\t\t\tbefore = {};\n\t\t\t\t\telse if (typeof(before) === 'boolean')\n\t\t\t\t\t\tbefore = {enabled: before};\n\t\t\t\t\telse if (typeof(before) === 'string')\n\t\t\t\t\t\tbefore = {classes: before};\n\t\t\t\t\tif (before.enabled === false)\n\t\t\t\t\t\tclsName.push('disabled');\n\t\t\t\t\tif (before.classes)\n\t\t\t\t\t\tclsName = clsName.concat(before.classes.split(/\\s+/));\n\t\t\t\t\tif (before.tooltip)\n\t\t\t\t\t\ttooltip = before.tooltip;\n\t\t\t\t}\n\n\t\t\t\t//Check if uniqueSort exists (supported by jquery >=1.12 and >=2.2)\n\t\t\t\t//Fallback to unique function for older jquery versions\n\t\t\t\tif ($.isFunction($.uniqueSort)) {\n\t\t\t\t\tclsName = $.uniqueSort(clsName);\n\t\t\t\t} else {\n\t\t\t\t\tclsName = $.unique(clsName);\n\t\t\t\t}\n\n\t\t\t\thtml.push('<td class=\"'+clsName.join(' ')+'\"' + (tooltip ? ' title=\"'+tooltip+'\"' : '') + '>'+prevMonth.getUTCDate() + '</td>');\n\t\t\t\ttooltip = null;\n\t\t\t\tif (prevMonth.getUTCDay() === this.o.weekEnd){\n\t\t\t\t\thtml.push('</tr>');\n\t\t\t\t}\n\t\t\t\tprevMonth.setUTCDate(prevMonth.getUTCDate()+1);\n\t\t\t}\n\t\t\tthis.picker.find('.datepicker-days tbody').empty().append(html.join(''));\n\n\t\t\tvar monthsTitle = dates[this.o.language].monthsTitle || dates['en'].monthsTitle || 'Months';\n\t\t\tvar months = this.picker.find('.datepicker-months')\n\t\t\t\t\t\t.find('.datepicker-switch')\n\t\t\t\t\t\t\t.text(this.o.maxViewMode < 2 ? monthsTitle : year)\n\t\t\t\t\t\t\t.end()\n\t\t\t\t\t\t.find('span').removeClass('active');\n\n\t\t\t$.each(this.dates, function(i, d){\n\t\t\t\tif (d.getUTCFullYear() === year)\n\t\t\t\t\tmonths.eq(d.getUTCMonth()).addClass('active');\n\t\t\t});\n\n\t\t\tif (year < startYear || year > endYear){\n\t\t\t\tmonths.addClass('disabled');\n\t\t\t}\n\t\t\tif (year === startYear){\n\t\t\t\tmonths.slice(0, startMonth).addClass('disabled');\n\t\t\t}\n\t\t\tif (year === endYear){\n\t\t\t\tmonths.slice(endMonth+1).addClass('disabled');\n\t\t\t}\n\n\t\t\tif (this.o.beforeShowMonth !== $.noop){\n\t\t\t\tvar that = this;\n\t\t\t\t$.each(months, function(i, month){\n          var moDate = new Date(year, i, 1);\n          var before = that.o.beforeShowMonth(moDate);\n\t\t\t\t\tif (before === undefined)\n\t\t\t\t\t\tbefore = {};\n\t\t\t\t\telse if (typeof(before) === 'boolean')\n\t\t\t\t\t\tbefore = {enabled: before};\n\t\t\t\t\telse if (typeof(before) === 'string')\n\t\t\t\t\t\tbefore = {classes: before};\n\t\t\t\t\tif (before.enabled === false && !$(month).hasClass('disabled'))\n\t\t\t\t\t    $(month).addClass('disabled');\n\t\t\t\t\tif (before.classes)\n\t\t\t\t\t    $(month).addClass(before.classes);\n\t\t\t\t\tif (before.tooltip)\n\t\t\t\t\t    $(month).prop('title', before.tooltip);\n\t\t\t\t});\n\t\t\t}\n\n\t\t\t// Generating decade/years picker\n\t\t\tthis._fill_yearsView(\n\t\t\t\t'.datepicker-years',\n\t\t\t\t'year',\n\t\t\t\t10,\n\t\t\t\t1,\n\t\t\t\tyear,\n\t\t\t\tstartYear,\n\t\t\t\tendYear,\n\t\t\t\tthis.o.beforeShowYear\n\t\t\t);\n\n\t\t\t// Generating century/decades picker\n\t\t\tthis._fill_yearsView(\n\t\t\t\t'.datepicker-decades',\n\t\t\t\t'decade',\n\t\t\t\t100,\n\t\t\t\t10,\n\t\t\t\tyear,\n\t\t\t\tstartYear,\n\t\t\t\tendYear,\n\t\t\t\tthis.o.beforeShowDecade\n\t\t\t);\n\n\t\t\t// Generating millennium/centuries picker\n\t\t\tthis._fill_yearsView(\n\t\t\t\t'.datepicker-centuries',\n\t\t\t\t'century',\n\t\t\t\t1000,\n\t\t\t\t100,\n\t\t\t\tyear,\n\t\t\t\tstartYear,\n\t\t\t\tendYear,\n\t\t\t\tthis.o.beforeShowCentury\n\t\t\t);\n\t\t},\n\n\t\tupdateNavArrows: function(){\n\t\t\tif (!this._allow_update)\n\t\t\t\treturn;\n\n\t\t\tvar d = new Date(this.viewDate),\n\t\t\t\tyear = d.getUTCFullYear(),\n\t\t\t\tmonth = d.getUTCMonth();\n\t\t\tswitch (this.viewMode){\n\t\t\t\tcase 0:\n\t\t\t\t\tif (this.o.startDate !== -Infinity && year <= this.o.startDate.getUTCFullYear() && month <= this.o.startDate.getUTCMonth()){\n\t\t\t\t\t\tthis.picker.find('.prev').css({visibility: 'hidden'});\n\t\t\t\t\t}\n\t\t\t\t\telse {\n\t\t\t\t\t\tthis.picker.find('.prev').css({visibility: 'visible'});\n\t\t\t\t\t}\n\t\t\t\t\tif (this.o.endDate !== Infinity && year >= this.o.endDate.getUTCFullYear() && month >= this.o.endDate.getUTCMonth()){\n\t\t\t\t\t\tthis.picker.find('.next').css({visibility: 'hidden'});\n\t\t\t\t\t}\n\t\t\t\t\telse {\n\t\t\t\t\t\tthis.picker.find('.next').css({visibility: 'visible'});\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\tcase 1:\n\t\t\t\tcase 2:\n\t\t\t\tcase 3:\n\t\t\t\tcase 4:\n\t\t\t\t\tif (this.o.startDate !== -Infinity && year <= this.o.startDate.getUTCFullYear() || this.o.maxViewMode < 2){\n\t\t\t\t\t\tthis.picker.find('.prev').css({visibility: 'hidden'});\n\t\t\t\t\t}\n\t\t\t\t\telse {\n\t\t\t\t\t\tthis.picker.find('.prev').css({visibility: 'visible'});\n\t\t\t\t\t}\n\t\t\t\t\tif (this.o.endDate !== Infinity && year >= this.o.endDate.getUTCFullYear() || this.o.maxViewMode < 2){\n\t\t\t\t\t\tthis.picker.find('.next').css({visibility: 'hidden'});\n\t\t\t\t\t}\n\t\t\t\t\telse {\n\t\t\t\t\t\tthis.picker.find('.next').css({visibility: 'visible'});\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t},\n\n\t\tclick: function(e){\n\t\t\te.preventDefault();\n\t\t\te.stopPropagation();\n\n\t\t\tvar target, dir, day, year, month, monthChanged, yearChanged;\n\t\t\ttarget = $(e.target);\n\n\t\t\t// Clicked on the switch\n\t\t\tif (target.hasClass('datepicker-switch')){\n\t\t\t\tthis.showMode(1);\n\t\t\t}\n\n\t\t\t// Clicked on prev or next\n\t\t\tvar navArrow = target.closest('.prev, .next');\n\t\t\tif (navArrow.length > 0) {\n\t\t\t\tdir = DPGlobal.modes[this.viewMode].navStep * (navArrow.hasClass('prev') ? -1 : 1);\n\t\t\t\tif (this.viewMode === 0){\n\t\t\t\t\tthis.viewDate = this.moveMonth(this.viewDate, dir);\n\t\t\t\t\tthis._trigger('changeMonth', this.viewDate);\n\t\t\t\t} else {\n\t\t\t\t\tthis.viewDate = this.moveYear(this.viewDate, dir);\n\t\t\t\t\tif (this.viewMode === 1){\n\t\t\t\t\t\tthis._trigger('changeYear', this.viewDate);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tthis.fill();\n\t\t\t}\n\n\t\t\t// Clicked on today button\n\t\t\tif (target.hasClass('today') && !target.hasClass('day')){\n\t\t\t\tthis.showMode(-2);\n\t\t\t\tthis._setDate(UTCToday(), this.o.todayBtn === 'linked' ? null : 'view');\n\t\t\t}\n\n\t\t\t// Clicked on clear button\n\t\t\tif (target.hasClass('clear')){\n\t\t\t\tthis.clearDates();\n\t\t\t}\n\n\t\t\tif (!target.hasClass('disabled')){\n\t\t\t\t// Clicked on a day\n\t\t\t\tif (target.hasClass('day')){\n\t\t\t\t\tday = parseInt(target.text(), 10) || 1;\n\t\t\t\t\tyear = this.viewDate.getUTCFullYear();\n\t\t\t\t\tmonth = this.viewDate.getUTCMonth();\n\n\t\t\t\t\t// From last month\n\t\t\t\t\tif (target.hasClass('old')){\n\t\t\t\t\t\tif (month === 0) {\n\t\t\t\t\t\t\tmonth = 11;\n\t\t\t\t\t\t\tyear = year - 1;\n\t\t\t\t\t\t\tmonthChanged = true;\n\t\t\t\t\t\t\tyearChanged = true;\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tmonth = month - 1;\n\t\t\t\t\t\t\tmonthChanged = true;\n \t\t\t\t\t\t}\n \t\t\t\t\t}\n\n\t\t\t\t\t// From next month\n\t\t\t\t\tif (target.hasClass('new')) {\n\t\t\t\t\t\tif (month === 11){\n\t\t\t\t\t\t\tmonth = 0;\n\t\t\t\t\t\t\tyear = year + 1;\n\t\t\t\t\t\t\tmonthChanged = true;\n\t\t\t\t\t\t\tyearChanged = true;\n \t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tmonth = month + 1;\n\t\t\t\t\t\t\tmonthChanged = true;\n \t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tthis._setDate(UTCDate(year, month, day));\n\t\t\t\t\tif (yearChanged) {\n\t\t\t\t\t\tthis._trigger('changeYear', this.viewDate);\n\t\t\t\t\t}\n\t\t\t\t\tif (monthChanged) {\n\t\t\t\t\t\tthis._trigger('changeMonth', this.viewDate);\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// Clicked on a month\n\t\t\t\tif (target.hasClass('month')) {\n\t\t\t\t\tthis.viewDate.setUTCDate(1);\n\t\t\t\t\tday = 1;\n\t\t\t\t\tmonth = target.parent().find('span').index(target);\n\t\t\t\t\tyear = this.viewDate.getUTCFullYear();\n\t\t\t\t\tthis.viewDate.setUTCMonth(month);\n\t\t\t\t\tthis._trigger('changeMonth', this.viewDate);\n\t\t\t\t\tif (this.o.minViewMode === 1){\n\t\t\t\t\t\tthis._setDate(UTCDate(year, month, day));\n\t\t\t\t\t\tthis.showMode();\n\t\t\t\t\t} else {\n\t\t\t\t\t\tthis.showMode(-1);\n\t\t\t\t\t}\n\t\t\t\t\tthis.fill();\n\t\t\t\t}\n\n\t\t\t\t// Clicked on a year\n\t\t\t\tif (target.hasClass('year')\n\t\t\t\t\t\t|| target.hasClass('decade')\n\t\t\t\t\t\t|| target.hasClass('century')) {\n\t\t\t\t\tthis.viewDate.setUTCDate(1);\n\n\t\t\t\t\tday = 1;\n\t\t\t\t\tmonth = 0;\n\t\t\t\t\tyear = parseInt(target.text(), 10)||0;\n\t\t\t\t\tthis.viewDate.setUTCFullYear(year);\n\n\t\t\t\t\tif (target.hasClass('year')){\n\t\t\t\t\t\tthis._trigger('changeYear', this.viewDate);\n\t\t\t\t\t\tif (this.o.minViewMode === 2){\n\t\t\t\t\t\t\tthis._setDate(UTCDate(year, month, day));\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tif (target.hasClass('decade')){\n\t\t\t\t\t\tthis._trigger('changeDecade', this.viewDate);\n\t\t\t\t\t\tif (this.o.minViewMode === 3){\n\t\t\t\t\t\t\tthis._setDate(UTCDate(year, month, day));\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tif (target.hasClass('century')){\n\t\t\t\t\t\tthis._trigger('changeCentury', this.viewDate);\n\t\t\t\t\t\tif (this.o.minViewMode === 4){\n\t\t\t\t\t\t\tthis._setDate(UTCDate(year, month, day));\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tthis.showMode(-1);\n\t\t\t\t\tthis.fill();\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (this.picker.is(':visible') && this._focused_from){\n\t\t\t\t$(this._focused_from).focus();\n\t\t\t}\n\t\t\tdelete this._focused_from;\n\t\t},\n\n\t\t_toggle_multidate: function(date){\n\t\t\tvar ix = this.dates.contains(date);\n\t\t\tif (!date){\n\t\t\t\tthis.dates.clear();\n\t\t\t}\n\n\t\t\tif (ix !== -1){\n\t\t\t\tif (this.o.multidate === true || this.o.multidate > 1 || this.o.toggleActive){\n\t\t\t\t\tthis.dates.remove(ix);\n\t\t\t\t}\n\t\t\t} else if (this.o.multidate === false) {\n\t\t\t\tthis.dates.clear();\n\t\t\t\tthis.dates.push(date);\n\t\t\t}\n\t\t\telse {\n\t\t\t\tthis.dates.push(date);\n\t\t\t}\n\n\t\t\tif (typeof this.o.multidate === 'number')\n\t\t\t\twhile (this.dates.length > this.o.multidate)\n\t\t\t\t\tthis.dates.remove(0);\n\t\t},\n\n\t\t_setDate: function(date, which){\n\t\t\tif (!which || which === 'date')\n\t\t\t\tthis._toggle_multidate(date && new Date(date));\n\t\t\tif (!which || which === 'view')\n\t\t\t\tthis.viewDate = date && new Date(date);\n\n\t\t\tthis.fill();\n\t\t\tthis.setValue();\n\t\t\tif (!which || which !== 'view') {\n\t\t\t\tthis._trigger('changeDate');\n\t\t\t}\n\t\t\tif (this.inputField){\n\t\t\t\tthis.inputField.change();\n\t\t\t}\n\t\t\tif (this.o.autoclose && (!which || which === 'date')){\n\t\t\t\tthis.hide();\n\t\t\t}\n\t\t},\n\n\t\tmoveDay: function(date, dir){\n\t\t\tvar newDate = new Date(date);\n\t\t\tnewDate.setUTCDate(date.getUTCDate() + dir);\n\n\t\t\treturn newDate;\n\t\t},\n\n\t\tmoveWeek: function(date, dir){\n\t\t\treturn this.moveDay(date, dir * 7);\n\t\t},\n\n\t\tmoveMonth: function(date, dir){\n\t\t\tif (!isValidDate(date))\n\t\t\t\treturn this.o.defaultViewDate;\n\t\t\tif (!dir)\n\t\t\t\treturn date;\n\t\t\tvar new_date = new Date(date.valueOf()),\n\t\t\t\tday = new_date.getUTCDate(),\n\t\t\t\tmonth = new_date.getUTCMonth(),\n\t\t\t\tmag = Math.abs(dir),\n\t\t\t\tnew_month, test;\n\t\t\tdir = dir > 0 ? 1 : -1;\n\t\t\tif (mag === 1){\n\t\t\t\ttest = dir === -1\n\t\t\t\t\t// If going back one month, make sure month is not current month\n\t\t\t\t\t// (eg, Mar 31 -> Feb 31 == Feb 28, not Mar 02)\n\t\t\t\t\t? function(){\n\t\t\t\t\t\treturn new_date.getUTCMonth() === month;\n\t\t\t\t\t}\n\t\t\t\t\t// If going forward one month, make sure month is as expected\n\t\t\t\t\t// (eg, Jan 31 -> Feb 31 == Feb 28, not Mar 02)\n\t\t\t\t\t: function(){\n\t\t\t\t\t\treturn new_date.getUTCMonth() !== new_month;\n\t\t\t\t\t};\n\t\t\t\tnew_month = month + dir;\n\t\t\t\tnew_date.setUTCMonth(new_month);\n\t\t\t\t// Dec -> Jan (12) or Jan -> Dec (-1) -- limit expected date to 0-11\n\t\t\t\tif (new_month < 0 || new_month > 11)\n\t\t\t\t\tnew_month = (new_month + 12) % 12;\n\t\t\t}\n\t\t\telse {\n\t\t\t\t// For magnitudes >1, move one month at a time...\n\t\t\t\tfor (var i=0; i < mag; i++)\n\t\t\t\t\t// ...which might decrease the day (eg, Jan 31 to Feb 28, etc)...\n\t\t\t\t\tnew_date = this.moveMonth(new_date, dir);\n\t\t\t\t// ...then reset the day, keeping it in the new month\n\t\t\t\tnew_month = new_date.getUTCMonth();\n\t\t\t\tnew_date.setUTCDate(day);\n\t\t\t\ttest = function(){\n\t\t\t\t\treturn new_month !== new_date.getUTCMonth();\n\t\t\t\t};\n\t\t\t}\n\t\t\t// Common date-resetting loop -- if date is beyond end of month, make it\n\t\t\t// end of month\n\t\t\twhile (test()){\n\t\t\t\tnew_date.setUTCDate(--day);\n\t\t\t\tnew_date.setUTCMonth(new_month);\n\t\t\t}\n\t\t\treturn new_date;\n\t\t},\n\n\t\tmoveYear: function(date, dir){\n\t\t\treturn this.moveMonth(date, dir*12);\n\t\t},\n\n\t\tmoveAvailableDate: function(date, dir, fn){\n\t\t\tdo {\n\t\t\t\tdate = this[fn](date, dir);\n\n\t\t\t\tif (!this.dateWithinRange(date))\n\t\t\t\t\treturn false;\n\n\t\t\t\tfn = 'moveDay';\n\t\t\t}\n\t\t\twhile (this.dateIsDisabled(date));\n\n\t\t\treturn date;\n\t\t},\n\n\t\tweekOfDateIsDisabled: function(date){\n\t\t\treturn $.inArray(date.getUTCDay(), this.o.daysOfWeekDisabled) !== -1;\n\t\t},\n\n\t\tdateIsDisabled: function(date){\n\t\t\treturn (\n\t\t\t\tthis.weekOfDateIsDisabled(date) ||\n\t\t\t\t$.grep(this.o.datesDisabled, function(d){\n\t\t\t\t\treturn isUTCEquals(date, d);\n\t\t\t\t}).length > 0\n\t\t\t);\n\t\t},\n\n\t\tdateWithinRange: function(date){\n\t\t\treturn date >= this.o.startDate && date <= this.o.endDate;\n\t\t},\n\n\t\tkeydown: function(e){\n\t\t\tif (!this.picker.is(':visible')){\n\t\t\t\tif (e.keyCode === 40 || e.keyCode === 27) { // allow down to re-show picker\n\t\t\t\t\tthis.show();\n\t\t\t\t\te.stopPropagation();\n        }\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tvar dateChanged = false,\n\t\t\t\tdir, newViewDate,\n\t\t\t\tfocusDate = this.focusDate || this.viewDate;\n\t\t\tswitch (e.keyCode){\n\t\t\t\tcase 27: // escape\n\t\t\t\t\tif (this.focusDate){\n\t\t\t\t\t\tthis.focusDate = null;\n\t\t\t\t\t\tthis.viewDate = this.dates.get(-1) || this.viewDate;\n\t\t\t\t\t\tthis.fill();\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t\tthis.hide();\n\t\t\t\t\te.preventDefault();\n\t\t\t\t\te.stopPropagation();\n\t\t\t\t\tbreak;\n\t\t\t\tcase 37: // left\n\t\t\t\tcase 38: // up\n\t\t\t\tcase 39: // right\n\t\t\t\tcase 40: // down\n\t\t\t\t\tif (!this.o.keyboardNavigation || this.o.daysOfWeekDisabled.length === 7)\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tdir = e.keyCode === 37 || e.keyCode === 38 ? -1 : 1;\n          if (this.viewMode === 0) {\n  \t\t\t\t\tif (e.ctrlKey){\n  \t\t\t\t\t\tnewViewDate = this.moveAvailableDate(focusDate, dir, 'moveYear');\n\n  \t\t\t\t\t\tif (newViewDate)\n  \t\t\t\t\t\t\tthis._trigger('changeYear', this.viewDate);\n  \t\t\t\t\t}\n  \t\t\t\t\telse if (e.shiftKey){\n  \t\t\t\t\t\tnewViewDate = this.moveAvailableDate(focusDate, dir, 'moveMonth');\n\n  \t\t\t\t\t\tif (newViewDate)\n  \t\t\t\t\t\t\tthis._trigger('changeMonth', this.viewDate);\n  \t\t\t\t\t}\n  \t\t\t\t\telse if (e.keyCode === 37 || e.keyCode === 39){\n  \t\t\t\t\t\tnewViewDate = this.moveAvailableDate(focusDate, dir, 'moveDay');\n  \t\t\t\t\t}\n  \t\t\t\t\telse if (!this.weekOfDateIsDisabled(focusDate)){\n  \t\t\t\t\t\tnewViewDate = this.moveAvailableDate(focusDate, dir, 'moveWeek');\n  \t\t\t\t\t}\n          } else if (this.viewMode === 1) {\n            if (e.keyCode === 38 || e.keyCode === 40) {\n              dir = dir * 4;\n            }\n            newViewDate = this.moveAvailableDate(focusDate, dir, 'moveMonth');\n          } else if (this.viewMode === 2) {\n            if (e.keyCode === 38 || e.keyCode === 40) {\n              dir = dir * 4;\n            }\n            newViewDate = this.moveAvailableDate(focusDate, dir, 'moveYear');\n          }\n\t\t\t\t\tif (newViewDate){\n\t\t\t\t\t\tthis.focusDate = this.viewDate = newViewDate;\n\t\t\t\t\t\tthis.setValue();\n\t\t\t\t\t\tthis.fill();\n\t\t\t\t\t\te.preventDefault();\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\tcase 13: // enter\n\t\t\t\t\tif (!this.o.forceParse)\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tfocusDate = this.focusDate || this.dates.get(-1) || this.viewDate;\n\t\t\t\t\tif (this.o.keyboardNavigation) {\n\t\t\t\t\t\tthis._toggle_multidate(focusDate);\n\t\t\t\t\t\tdateChanged = true;\n\t\t\t\t\t}\n\t\t\t\t\tthis.focusDate = null;\n\t\t\t\t\tthis.viewDate = this.dates.get(-1) || this.viewDate;\n\t\t\t\t\tthis.setValue();\n\t\t\t\t\tthis.fill();\n\t\t\t\t\tif (this.picker.is(':visible')){\n\t\t\t\t\t\te.preventDefault();\n\t\t\t\t\t\te.stopPropagation();\n\t\t\t\t\t\tif (this.o.autoclose)\n\t\t\t\t\t\t\tthis.hide();\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\tcase 9: // tab\n\t\t\t\t\tthis.focusDate = null;\n\t\t\t\t\tthis.viewDate = this.dates.get(-1) || this.viewDate;\n\t\t\t\t\tthis.fill();\n\t\t\t\t\tthis.hide();\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t\tif (dateChanged){\n\t\t\t\tif (this.dates.length)\n\t\t\t\t\tthis._trigger('changeDate');\n\t\t\t\telse\n\t\t\t\t\tthis._trigger('clearDate');\n\t\t\t\tif (this.inputField){\n\t\t\t\t\tthis.inputField.change();\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\n\t\tshowMode: function(dir){\n\t\t\tif (dir){\n\t\t\t\tthis.viewMode = Math.max(this.o.minViewMode, Math.min(this.o.maxViewMode, this.viewMode + dir));\n\t\t\t}\n\t\t\tthis.picker\n\t\t\t\t.children('div')\n\t\t\t\t.hide()\n\t\t\t\t.filter('.datepicker-' + DPGlobal.modes[this.viewMode].clsName)\n\t\t\t\t\t.show();\n\t\t\tthis.updateNavArrows();\n\t\t}\n\t};\n\n\tvar DateRangePicker = function(element, options){\n\t\t$(element).data('datepicker', this);\n\t\tthis.element = $(element);\n\t\tthis.inputs = $.map(options.inputs, function(i){\n\t\t\treturn i.jquery ? i[0] : i;\n\t\t});\n\t\tdelete options.inputs;\n\n\t\tdatepickerPlugin.call($(this.inputs), options)\n\t\t\t.on('changeDate', $.proxy(this.dateUpdated, this));\n\n\t\tthis.pickers = $.map(this.inputs, function(i){\n\t\t\treturn $(i).data('datepicker');\n\t\t});\n\t\tthis.updateDates();\n\t};\n\tDateRangePicker.prototype = {\n\t\tupdateDates: function(){\n\t\t\tthis.dates = $.map(this.pickers, function(i){\n\t\t\t\treturn i.getUTCDate();\n\t\t\t});\n\t\t\tthis.updateRanges();\n\t\t},\n\t\tupdateRanges: function(){\n\t\t\tvar range = $.map(this.dates, function(d){\n\t\t\t\treturn d.valueOf();\n\t\t\t});\n\t\t\t$.each(this.pickers, function(i, p){\n\t\t\t\tp.setRange(range);\n\t\t\t});\n\t\t},\n\t\tdateUpdated: function(e){\n\t\t\t// `this.updating` is a workaround for preventing infinite recursion\n\t\t\t// between `changeDate` triggering and `setUTCDate` calling.  Until\n\t\t\t// there is a better mechanism.\n\t\t\tif (this.updating)\n\t\t\t\treturn;\n\t\t\tthis.updating = true;\n\n\t\t\tvar dp = $(e.target).data('datepicker');\n\n\t\t\tif (typeof(dp) === \"undefined\") {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tvar new_date = dp.getUTCDate(),\n\t\t\t\ti = $.inArray(e.target, this.inputs),\n\t\t\t\tj = i - 1,\n\t\t\t\tk = i + 1,\n\t\t\t\tl = this.inputs.length;\n\t\t\tif (i === -1)\n\t\t\t\treturn;\n\n\t\t\t$.each(this.pickers, function(i, p){\n\t\t\t\tif (!p.getUTCDate())\n\t\t\t\t\tp.setUTCDate(new_date);\n\t\t\t});\n\n\t\t\tif (new_date < this.dates[j]){\n\t\t\t\t// Date being moved earlier/left\n\t\t\t\twhile (j >= 0 && new_date < this.dates[j]){\n\t\t\t\t\tthis.pickers[j--].setUTCDate(new_date);\n\t\t\t\t}\n\t\t\t}\n\t\t\telse if (new_date > this.dates[k]){\n\t\t\t\t// Date being moved later/right\n\t\t\t\twhile (k < l && new_date > this.dates[k]){\n\t\t\t\t\tthis.pickers[k++].setUTCDate(new_date);\n\t\t\t\t}\n\t\t\t}\n\t\t\tthis.updateDates();\n\n\t\t\tdelete this.updating;\n\t\t},\n\t\tremove: function(){\n\t\t\t$.map(this.pickers, function(p){ p.remove(); });\n\t\t\tdelete this.element.data().datepicker;\n\t\t}\n\t};\n\n\tfunction opts_from_el(el, prefix){\n\t\t// Derive options from element data-attrs\n\t\tvar data = $(el).data(),\n\t\t\tout = {}, inkey,\n\t\t\treplace = new RegExp('^' + prefix.toLowerCase() + '([A-Z])');\n\t\tprefix = new RegExp('^' + prefix.toLowerCase());\n\t\tfunction re_lower(_,a){\n\t\t\treturn a.toLowerCase();\n\t\t}\n\t\tfor (var key in data)\n\t\t\tif (prefix.test(key)){\n\t\t\t\tinkey = key.replace(replace, re_lower);\n\t\t\t\tout[inkey] = data[key];\n\t\t\t}\n\t\treturn out;\n\t}\n\n\tfunction opts_from_locale(lang){\n\t\t// Derive options from locale plugins\n\t\tvar out = {};\n\t\t// Check if \"de-DE\" style date is available, if not language should\n\t\t// fallback to 2 letter code eg \"de\"\n\t\tif (!dates[lang]){\n\t\t\tlang = lang.split('-')[0];\n\t\t\tif (!dates[lang])\n\t\t\t\treturn;\n\t\t}\n\t\tvar d = dates[lang];\n\t\t$.each(locale_opts, function(i,k){\n\t\t\tif (k in d)\n\t\t\t\tout[k] = d[k];\n\t\t});\n\t\treturn out;\n\t}\n\n\tvar old = $.fn.datepicker;\n\tvar datepickerPlugin = function(option){\n\t\tvar args = Array.apply(null, arguments);\n\t\targs.shift();\n\t\tvar internal_return;\n\t\tthis.each(function(){\n\t\t\tvar $this = $(this),\n\t\t\t\tdata = $this.data('datepicker'),\n\t\t\t\toptions = typeof option === 'object' && option;\n\t\t\tif (!data){\n\t\t\t\tvar elopts = opts_from_el(this, 'date'),\n\t\t\t\t\t// Preliminary otions\n\t\t\t\t\txopts = $.extend({}, defaults, elopts, options),\n\t\t\t\t\tlocopts = opts_from_locale(xopts.language),\n\t\t\t\t\t// Options priority: js args, data-attrs, locales, defaults\n\t\t\t\t\topts = $.extend({}, defaults, locopts, elopts, options);\n\t\t\t\tif ($this.hasClass('input-daterange') || opts.inputs){\n\t\t\t\t\t$.extend(opts, {\n\t\t\t\t\t\tinputs: opts.inputs || $this.find('input').toArray()\n\t\t\t\t\t});\n\t\t\t\t\tdata = new DateRangePicker(this, opts);\n\t\t\t\t}\n\t\t\t\telse {\n\t\t\t\t\tdata = new Datepicker(this, opts);\n\t\t\t\t}\n\t\t\t\t$this.data('datepicker', data);\n\t\t\t}\n\t\t\tif (typeof option === 'string' && typeof data[option] === 'function'){\n\t\t\t\tinternal_return = data[option].apply(data, args);\n\t\t\t}\n\t\t});\n\n\t\tif (\n\t\t\tinternal_return === undefined ||\n\t\t\tinternal_return instanceof Datepicker ||\n\t\t\tinternal_return instanceof DateRangePicker\n\t\t)\n\t\t\treturn this;\n\n\t\tif (this.length > 1)\n\t\t\tthrow new Error('Using only allowed for the collection of a single element (' + option + ' function)');\n\t\telse\n\t\t\treturn internal_return;\n\t};\n\t$.fn.datepicker = datepickerPlugin;\n\n\tvar defaults = $.fn.datepicker.defaults = {\n\t\tassumeNearbyYear: false,\n\t\tautoclose: false,\n\t\tbeforeShowDay: $.noop,\n\t\tbeforeShowMonth: $.noop,\n\t\tbeforeShowYear: $.noop,\n\t\tbeforeShowDecade: $.noop,\n\t\tbeforeShowCentury: $.noop,\n\t\tcalendarWeeks: false,\n\t\tclearBtn: false,\n\t\ttoggleActive: false,\n\t\tdaysOfWeekDisabled: [],\n\t\tdaysOfWeekHighlighted: [],\n\t\tdatesDisabled: [],\n\t\tendDate: Infinity,\n\t\tforceParse: true,\n\t\tformat: 'mm/dd/yyyy',\n\t\tkeyboardNavigation: true,\n\t\tlanguage: 'en',\n\t\tminViewMode: 0,\n\t\tmaxViewMode: 4,\n\t\tmultidate: false,\n\t\tmultidateSeparator: ',',\n\t\torientation: \"auto\",\n\t\trtl: false,\n\t\tstartDate: -Infinity,\n\t\tstartView: 0,\n\t\ttodayBtn: false,\n\t\ttodayHighlight: false,\n\t\tweekStart: 0,\n\t\tdisableTouchKeyboard: false,\n\t\tenableOnReadonly: true,\n\t\tshowOnFocus: true,\n\t\tzIndexOffset: 10,\n\t\tcontainer: 'body',\n\t\timmediateUpdates: false,\n\t\ttitle: '',\n\t\ttemplates: {\n\t\t\tleftArrow: '&laquo;',\n\t\t\trightArrow: '&raquo;'\n\t\t}\n\t};\n\tvar locale_opts = $.fn.datepicker.locale_opts = [\n\t\t'format',\n\t\t'rtl',\n\t\t'weekStart'\n\t];\n\t$.fn.datepicker.Constructor = Datepicker;\n\tvar dates = $.fn.datepicker.dates = {\n\t\ten: {\n\t\t\tdays: [\"Sunday\", \"Monday\", \"Tuesday\", \"Wednesday\", \"Thursday\", \"Friday\", \"Saturday\"],\n\t\t\tdaysShort: [\"Sun\", \"Mon\", \"Tue\", \"Wed\", \"Thu\", \"Fri\", \"Sat\"],\n\t\t\tdaysMin: [\"Su\", \"Mo\", \"Tu\", \"We\", \"Th\", \"Fr\", \"Sa\"],\n\t\t\tmonths: [\"January\", \"February\", \"March\", \"April\", \"May\", \"June\", \"July\", \"August\", \"September\", \"October\", \"November\", \"December\"],\n\t\t\tmonthsShort: [\"Jan\", \"Feb\", \"Mar\", \"Apr\", \"May\", \"Jun\", \"Jul\", \"Aug\", \"Sep\", \"Oct\", \"Nov\", \"Dec\"],\n\t\t\ttoday: \"Today\",\n\t\t\tclear: \"Clear\",\n\t\t\ttitleFormat: \"MM yyyy\"\n\t\t}\n\t};\n\n\tvar DPGlobal = {\n\t\tmodes: [\n\t\t\t{\n\t\t\t\tclsName: 'days',\n\t\t\t\tnavFnc: 'Month',\n\t\t\t\tnavStep: 1\n\t\t\t},\n\t\t\t{\n\t\t\t\tclsName: 'months',\n\t\t\t\tnavFnc: 'FullYear',\n\t\t\t\tnavStep: 1\n\t\t\t},\n\t\t\t{\n\t\t\t\tclsName: 'years',\n\t\t\t\tnavFnc: 'FullYear',\n\t\t\t\tnavStep: 10\n\t\t\t},\n\t\t\t{\n\t\t\t\tclsName: 'decades',\n\t\t\t\tnavFnc: 'FullDecade',\n\t\t\t\tnavStep: 100\n\t\t\t},\n\t\t\t{\n\t\t\t\tclsName: 'centuries',\n\t\t\t\tnavFnc: 'FullCentury',\n\t\t\t\tnavStep: 1000\n\t\t}],\n\t\tisLeapYear: function(year){\n\t\t\treturn (((year % 4 === 0) && (year % 100 !== 0)) || (year % 400 === 0));\n\t\t},\n\t\tgetDaysInMonth: function(year, month){\n\t\t\treturn [31, (DPGlobal.isLeapYear(year) ? 29 : 28), 31, 30, 31, 30, 31, 31, 30, 31, 30, 31][month];\n\t\t},\n\t\tvalidParts: /dd?|DD?|mm?|MM?|yy(?:yy)?/g,\n\t\tnonpunctuation: /[^ -\\/:-@\\u5e74\\u6708\\u65e5\\[-`{-~\\t\\n\\r]+/g,\n\t\tparseFormat: function(format){\n\t\t\tif (typeof format.toValue === 'function' && typeof format.toDisplay === 'function')\n                return format;\n            // IE treats \\0 as a string end in inputs (truncating the value),\n\t\t\t// so it's a bad format delimiter, anyway\n\t\t\tvar separators = format.replace(this.validParts, '\\0').split('\\0'),\n\t\t\t\tparts = format.match(this.validParts);\n\t\t\tif (!separators || !separators.length || !parts || parts.length === 0){\n\t\t\t\tthrow new Error(\"Invalid date format.\");\n\t\t\t}\n\t\t\treturn {separators: separators, parts: parts};\n\t\t},\n\t\tparseDate: function(date, format, language, assumeNearby){\n\t\t\tif (!date)\n\t\t\t\treturn undefined;\n\t\t\tif (date instanceof Date)\n\t\t\t\treturn date;\n\t\t\tif (typeof format === 'string')\n\t\t\t\tformat = DPGlobal.parseFormat(format);\n\t\t\tif (format.toValue)\n                return format.toValue(date, format, language);\n            var part_re = /([\\-+]\\d+)([dmwy])/,\n\t\t\t\tparts = date.match(/([\\-+]\\d+)([dmwy])/g),\n\t\t\t\tfn_map = {\n\t\t\t\t\td: 'moveDay',\n\t\t\t\t\tm: 'moveMonth',\n\t\t\t\t\tw: 'moveWeek',\n\t\t\t\t\ty: 'moveYear'\n\t\t\t\t},\n\t\t\t\tdateAliases = {\n\t\t\t\t\tyesterday: '-1d',\n\t\t\t\t\ttoday: '+0d',\n\t\t\t\t\ttomorrow: '+1d'\n\t\t\t\t},\n\t\t\t\tpart, dir, i, fn;\n\t\t\tif (/^[\\-+]\\d+[dmwy]([\\s,]+[\\-+]\\d+[dmwy])*$/.test(date)){\n\t\t\t\tdate = new Date();\n\t\t\t\tfor (i=0; i < parts.length; i++){\n\t\t\t\t\tpart = part_re.exec(parts[i]);\n\t\t\t\t\tdir = parseInt(part[1]);\n\t\t\t\t\tfn = fn_map[part[2]];\n\t\t\t\t\tdate = Datepicker.prototype[fn](date, dir);\n\t\t\t\t}\n\t\t\t\treturn UTCDate(date.getUTCFullYear(), date.getUTCMonth(), date.getUTCDate());\n\t\t\t}\n\n\t\t\tif (typeof dateAliases[date] !== 'undefined') {\n\t\t\t\tdate = dateAliases[date];\n\t\t\t\tparts = date.match(/([\\-+]\\d+)([dmwy])/g);\n\n\t\t\t\tif (/^[\\-+]\\d+[dmwy]([\\s,]+[\\-+]\\d+[dmwy])*$/.test(date)){\n\t\t\t\t\tdate = new Date();\n\t\t\t\t  \tfor (i=0; i < parts.length; i++){\n\t\t\t\t\t\tpart = part_re.exec(parts[i]);\n\t\t\t\t\t\tdir = parseInt(part[1]);\n\t\t\t\t\t\tfn = fn_map[part[2]];\n\t\t\t\t\t\tdate = Datepicker.prototype[fn](date, dir);\n\t\t\t\t  \t}\n\n\t\t\t  \t\treturn UTCDate(date.getUTCFullYear(), date.getUTCMonth(), date.getUTCDate());\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tparts = date && date.match(this.nonpunctuation) || [];\n\t\t\tdate = new Date();\n\n\t\t\tfunction applyNearbyYear(year, threshold){\n\t\t\t\tif (threshold === true)\n\t\t\t\t\tthreshold = 10;\n\n\t\t\t\t// if year is 2 digits or less, than the user most likely is trying to get a recent century\n\t\t\t\tif (year < 100){\n\t\t\t\t\tyear += 2000;\n\t\t\t\t\t// if the new year is more than threshold years in advance, use last century\n\t\t\t\t\tif (year > ((new Date()).getFullYear()+threshold)){\n\t\t\t\t\t\tyear -= 100;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\treturn year;\n\t\t\t}\n\n\t\t\tvar parsed = {},\n\t\t\t\tsetters_order = ['yyyy', 'yy', 'M', 'MM', 'm', 'mm', 'd', 'dd'],\n\t\t\t\tsetters_map = {\n\t\t\t\t\tyyyy: function(d,v){\n\t\t\t\t\t\treturn d.setUTCFullYear(assumeNearby ? applyNearbyYear(v, assumeNearby) : v);\n\t\t\t\t\t},\n\t\t\t\t\tyy: function(d,v){\n\t\t\t\t\t\treturn d.setUTCFullYear(assumeNearby ? applyNearbyYear(v, assumeNearby) : v);\n\t\t\t\t\t},\n\t\t\t\t\tm: function(d,v){\n\t\t\t\t\t\tif (isNaN(d))\n\t\t\t\t\t\t\treturn d;\n\t\t\t\t\t\tv -= 1;\n\t\t\t\t\t\twhile (v < 0) v += 12;\n\t\t\t\t\t\tv %= 12;\n\t\t\t\t\t\td.setUTCMonth(v);\n\t\t\t\t\t\twhile (d.getUTCMonth() !== v)\n\t\t\t\t\t\t\td.setUTCDate(d.getUTCDate()-1);\n\t\t\t\t\t\treturn d;\n\t\t\t\t\t},\n\t\t\t\t\td: function(d,v){\n\t\t\t\t\t\treturn d.setUTCDate(v);\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t\tval, filtered;\n\t\t\tsetters_map['M'] = setters_map['MM'] = setters_map['mm'] = setters_map['m'];\n\t\t\tsetters_map['dd'] = setters_map['d'];\n\t\t\tdate = UTCToday();\n\t\t\tvar fparts = format.parts.slice();\n\t\t\t// Remove noop parts\n\t\t\tif (parts.length !== fparts.length){\n\t\t\t\tfparts = $(fparts).filter(function(i,p){\n\t\t\t\t\treturn $.inArray(p, setters_order) !== -1;\n\t\t\t\t}).toArray();\n\t\t\t}\n\t\t\t// Process remainder\n\t\t\tfunction match_part(){\n\t\t\t\tvar m = this.slice(0, parts[i].length),\n\t\t\t\t\tp = parts[i].slice(0, m.length);\n\t\t\t\treturn m.toLowerCase() === p.toLowerCase();\n\t\t\t}\n\t\t\tif (parts.length === fparts.length){\n\t\t\t\tvar cnt;\n\t\t\t\tfor (i=0, cnt = fparts.length; i < cnt; i++){\n\t\t\t\t\tval = parseInt(parts[i], 10);\n\t\t\t\t\tpart = fparts[i];\n\t\t\t\t\tif (isNaN(val)){\n\t\t\t\t\t\tswitch (part){\n\t\t\t\t\t\t\tcase 'MM':\n\t\t\t\t\t\t\t\tfiltered = $(dates[language].months).filter(match_part);\n\t\t\t\t\t\t\t\tval = $.inArray(filtered[0], dates[language].months) + 1;\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\tcase 'M':\n\t\t\t\t\t\t\t\tfiltered = $(dates[language].monthsShort).filter(match_part);\n\t\t\t\t\t\t\t\tval = $.inArray(filtered[0], dates[language].monthsShort) + 1;\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tparsed[part] = val;\n\t\t\t\t}\n\t\t\t\tvar _date, s;\n\t\t\t\tfor (i=0; i < setters_order.length; i++){\n\t\t\t\t\ts = setters_order[i];\n\t\t\t\t\tif (s in parsed && !isNaN(parsed[s])){\n\t\t\t\t\t\t_date = new Date(date);\n\t\t\t\t\t\tsetters_map[s](_date, parsed[s]);\n\t\t\t\t\t\tif (!isNaN(_date))\n\t\t\t\t\t\t\tdate = _date;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn date;\n\t\t},\n\t\tformatDate: function(date, format, language){\n\t\t\tif (!date)\n\t\t\t\treturn '';\n\t\t\tif (typeof format === 'string')\n\t\t\t\tformat = DPGlobal.parseFormat(format);\n\t\t\tif (format.toDisplay)\n                return format.toDisplay(date, format, language);\n            var val = {\n\t\t\t\td: date.getUTCDate(),\n\t\t\t\tD: dates[language].daysShort[date.getUTCDay()],\n\t\t\t\tDD: dates[language].days[date.getUTCDay()],\n\t\t\t\tm: date.getUTCMonth() + 1,\n\t\t\t\tM: dates[language].monthsShort[date.getUTCMonth()],\n\t\t\t\tMM: dates[language].months[date.getUTCMonth()],\n\t\t\t\tyy: date.getUTCFullYear().toString().substring(2),\n\t\t\t\tyyyy: date.getUTCFullYear()\n\t\t\t};\n\t\t\tval.dd = (val.d < 10 ? '0' : '') + val.d;\n\t\t\tval.mm = (val.m < 10 ? '0' : '') + val.m;\n\t\t\tdate = [];\n\t\t\tvar seps = $.extend([], format.separators);\n\t\t\tfor (var i=0, cnt = format.parts.length; i <= cnt; i++){\n\t\t\t\tif (seps.length)\n\t\t\t\t\tdate.push(seps.shift());\n\t\t\t\tdate.push(val[format.parts[i]]);\n\t\t\t}\n\t\t\treturn date.join('');\n\t\t},\n\t\theadTemplate: '<thead>'+\n\t\t\t              '<tr>'+\n\t\t\t                '<th colspan=\"7\" class=\"datepicker-title\"></th>'+\n\t\t\t              '</tr>'+\n\t\t\t\t\t\t\t'<tr>'+\n\t\t\t\t\t\t\t\t'<th class=\"prev\">&laquo;</th>'+\n\t\t\t\t\t\t\t\t'<th colspan=\"5\" class=\"datepicker-switch\"></th>'+\n\t\t\t\t\t\t\t\t'<th class=\"next\">&raquo;</th>'+\n\t\t\t\t\t\t\t'</tr>'+\n\t\t\t\t\t\t'</thead>',\n\t\tcontTemplate: '<tbody><tr><td colspan=\"7\"></td></tr></tbody>',\n\t\tfootTemplate: '<tfoot>'+\n\t\t\t\t\t\t\t'<tr>'+\n\t\t\t\t\t\t\t\t'<th colspan=\"7\" class=\"today\"></th>'+\n\t\t\t\t\t\t\t'</tr>'+\n\t\t\t\t\t\t\t'<tr>'+\n\t\t\t\t\t\t\t\t'<th colspan=\"7\" class=\"clear\"></th>'+\n\t\t\t\t\t\t\t'</tr>'+\n\t\t\t\t\t\t'</tfoot>'\n\t};\n\tDPGlobal.template = '<div class=\"datepicker\">'+\n\t\t\t\t\t\t\t'<div class=\"datepicker-days\">'+\n\t\t\t\t\t\t\t\t'<table class=\"table-condensed\">'+\n\t\t\t\t\t\t\t\t\tDPGlobal.headTemplate+\n\t\t\t\t\t\t\t\t\t'<tbody></tbody>'+\n\t\t\t\t\t\t\t\t\tDPGlobal.footTemplate+\n\t\t\t\t\t\t\t\t'</table>'+\n\t\t\t\t\t\t\t'</div>'+\n\t\t\t\t\t\t\t'<div class=\"datepicker-months\">'+\n\t\t\t\t\t\t\t\t'<table class=\"table-condensed\">'+\n\t\t\t\t\t\t\t\t\tDPGlobal.headTemplate+\n\t\t\t\t\t\t\t\t\tDPGlobal.contTemplate+\n\t\t\t\t\t\t\t\t\tDPGlobal.footTemplate+\n\t\t\t\t\t\t\t\t'</table>'+\n\t\t\t\t\t\t\t'</div>'+\n\t\t\t\t\t\t\t'<div class=\"datepicker-years\">'+\n\t\t\t\t\t\t\t\t'<table class=\"table-condensed\">'+\n\t\t\t\t\t\t\t\t\tDPGlobal.headTemplate+\n\t\t\t\t\t\t\t\t\tDPGlobal.contTemplate+\n\t\t\t\t\t\t\t\t\tDPGlobal.footTemplate+\n\t\t\t\t\t\t\t\t'</table>'+\n\t\t\t\t\t\t\t'</div>'+\n\t\t\t\t\t\t\t'<div class=\"datepicker-decades\">'+\n\t\t\t\t\t\t\t\t'<table class=\"table-condensed\">'+\n\t\t\t\t\t\t\t\t\tDPGlobal.headTemplate+\n\t\t\t\t\t\t\t\t\tDPGlobal.contTemplate+\n\t\t\t\t\t\t\t\t\tDPGlobal.footTemplate+\n\t\t\t\t\t\t\t\t'</table>'+\n\t\t\t\t\t\t\t'</div>'+\n\t\t\t\t\t\t\t'<div class=\"datepicker-centuries\">'+\n\t\t\t\t\t\t\t\t'<table class=\"table-condensed\">'+\n\t\t\t\t\t\t\t\t\tDPGlobal.headTemplate+\n\t\t\t\t\t\t\t\t\tDPGlobal.contTemplate+\n\t\t\t\t\t\t\t\t\tDPGlobal.footTemplate+\n\t\t\t\t\t\t\t\t'</table>'+\n\t\t\t\t\t\t\t'</div>'+\n\t\t\t\t\t\t'</div>';\n\n\t$.fn.datepicker.DPGlobal = DPGlobal;\n\n\n\t/* DATEPICKER NO CONFLICT\n\t* =================== */\n\n\t$.fn.datepicker.noConflict = function(){\n\t\t$.fn.datepicker = old;\n\t\treturn this;\n\t};\n\n\t/* DATEPICKER VERSION\n\t * =================== */\n\t$.fn.datepicker.version = '1.6.4';\n\n\t/* DATEPICKER DATA-API\n\t* ================== */\n\n\t$(document).on(\n\t\t'focus.datepicker.data-api click.datepicker.data-api',\n\t\t'[data-provide=\"datepicker\"]',\n\t\tfunction(e){\n\t\t\tvar $this = $(this);\n\t\t\tif ($this.data('datepicker'))\n\t\t\t\treturn;\n\t\t\te.preventDefault();\n\t\t\t// component click requires us to explicitly show it\n\t\t\tdatepickerPlugin.call($this, 'show');\n\t\t}\n\t);\n\t$(function(){\n\t\tdatepickerPlugin.call($('[data-provide=\"datepicker-inline\"]'));\n\t});\n\n}));\n"
  },
  {
    "path": "app_backend/static/plugin/bootstrap-select-1.12.2/.github/ISSUE_TEMPLATE.md",
    "content": "Before posting, please see [guidelines for contributing](https://github.com/silviomoreto/bootstrap-select/blob/master/CONTRIBUTING.md). If you're submitting a bug report, see below.\n\n## Bug reports\n\nA bug is a _demonstrable problem_ that is caused by the code in the repository.\nGood bug reports are extremely helpful - thank you!\n\nGuidelines for bug reports:\n\n1. **Use the GitHub issue search.** Check if the issue has already been\n   reported.\n\n2. **Check if the issue has been fixed.** Try to reproduce it using the\n   latest `master` or development branch in the repository.\n\n3. **Provide environment details.** Provide your operating system, browser(s),\n   jQuery version, Bootstrap version, and bootstrap-select version.\n\n4. **Create an isolated and reproducible test case.** Create a [reduced test\n   case](http://css-tricks.com/6263-reduced-test-cases/).\n\n5. **Include a live example.** Use [this Plunker debugging template](http://silviomoreto.github.io/bootstrap-select/playground/) to share your isolated test cases. You can also make use of [jsFiddle](http://jsfiddle.net/) or [jsBin](http://jsbin.com/).\n\nA good bug report shouldn't leave others needing to chase you up for more\ninformation. Please try to be as detailed as possible in your report. What is\nyour environment? What steps will reproduce the issue? What browser(s) and OS\nexperience the problem? What would you expect to be the outcome? All these\ndetails will help people to fix any potential bugs.\n\nExample:\n\n> Short and descriptive example bug report title\n>\n> A summary of the issue and the browser/OS environment in which it occurs. If\n> suitable, include the steps required to reproduce the bug.\n>\n> 1. This is the first step\n> 2. This is the second step\n> 3. Further steps, etc.\n>\n> `<url>` - a link to the reduced test case\n>\n> Any other information you want to share that is relevant to the issue being\n> reported. This might include the lines of code that you have identified as\n> causing the bug, and potential solutions (and your opinions on their\n> merits).\n\n## Erase the above text and being typing. Thanks!"
  },
  {
    "path": "app_backend/static/plugin/bootstrap-select-1.12.2/.gitignore",
    "content": "# OS or Editor folders\n.DS_Store\n.idea\n\n# Folders to ignore\nnode_modules\nbower_components\n.sass-cache\n\n# Dist zip\nbootstrap-select-*.zip\n\ndocs/site\n"
  },
  {
    "path": "app_backend/static/plugin/bootstrap-select-1.12.2/CHANGELOG.md",
    "content": "### v1.12.2 (2017-01-30)\n\n## Bug Fixes\n* [#1563]: key word searching broken in [#1516].\n* [#1570]: properly adjust size when inside form-group-sm or form-group-lg\n* [#1590]: menu height calculated improperly when using liveSearch and input has custom height\n\n[#1563]: https://github.com/silviomoreto/bootstrap-select/issues/1563\n[#1570]: https://github.com/silviomoreto/bootstrap-select/issues/1570\n[#1590]: https://github.com/silviomoreto/bootstrap-select/issues/1590\n\n-------------------\n\n### v1.12.1 (2016-11-22)\n\n## Bug Fixes\n* [#1167], [#1366]: using a method before initializing bootstrap-select throws an error\n\n[#1167]: https://github.com/silviomoreto/bootstrap-select/issues/1167\n[#1366]: https://github.com/silviomoreto/bootstrap-select/issues/1366\n\n-------------------\n\n### v1.12.0 (2016-11-18)\n\n## Bug Fixes\n* [#1220]: unescape button title\n* [#1348]: escape HTML for optgroup label\n* [#1506]: Fix bs-placeholder usage for jQuery>=3.0\n* [#1509]: inline style Content Security Policy\n* [#1477]: using liveSearchNormalize and liveSearchStyle=\"startsWith\" simultaneously breaks search\n* [#1489] fix selectOnTab with liveSearch enabled which was broken when [#1489] was fixed\n* [#1533]: remove touchstart event listener (issues with FastClick)\n* remove destroyLi function - improve refresh() performance\n* [#1531]: add Spanish (Spain) translations\n* [#1553]: don't use replace in normalizeToBase if text is undefined (throws error otherwise)\n\n## New Features\n* [#1503]: Add windowPadding option (either a number or an array of numbers - [top, right, bottom, left])\n* [#1516]: Improve liveSearch performance (addresses [#1275])\n* [#1440]: allow HTML in placeholder title for non-multiple selects\n* [#1555]: Use default with SCSS variables\n\n[#1220]: https://github.com/silviomoreto/bootstrap-select/issues/1220\n[#1275]: https://github.com/silviomoreto/bootstrap-select/issues/1275\n[#1348]: https://github.com/silviomoreto/bootstrap-select/issues/1348\n[#1506]: https://github.com/silviomoreto/bootstrap-select/issues/1506\n[#1509]: https://github.com/silviomoreto/bootstrap-select/issues/1509\n[#1477]: https://github.com/silviomoreto/bootstrap-select/issues/1477\n[#1489]: https://github.com/silviomoreto/bootstrap-select/issues/1489\n[#1533]: https://github.com/silviomoreto/bootstrap-select/issues/1533\n[#1531]: https://github.com/silviomoreto/bootstrap-select/issues/1531\n[#1503]: https://github.com/silviomoreto/bootstrap-select/issues/1503\n[#1516]: https://github.com/silviomoreto/bootstrap-select/issues/1516\n[#1440]: https://github.com/silviomoreto/bootstrap-select/issues/1440\n[#1553]: https://github.com/silviomoreto/bootstrap-select/issues/1553\n[#1555]: https://github.com/silviomoreto/bootstrap-select/issues/1555\n\n-------------------\n\n### v1.11.2 (2016-09-09)\n\n#### Bug Fixes\n* fix sourceMappingURL in bootstrap-select.min.js\n\n-------------------\n\n### v1.11.1 (2016-09-09)\n\n#### Bug Fixes\n* [#1475]: fix Cannot read property 'apply' of null error\n* [#1484]: Change events fire twice on IE8\n* [#1489]: hide.bs.select and hidden.bs.select events not fired when \"Esc\" key pressed with live search enabled\n\n[#1475]: https://github.com/silviomoreto/bootstrap-select/issues/1475\n[#1484]: https://github.com/silviomoreto/bootstrap-select/issues/1484\n[#1489]: https://github.com/silviomoreto/bootstrap-select/issues/1489\n\n-------------------\n\n### v1.11.0 (2016-08-16)\n\n#### Bug Fixes\n* [#1291]: don't trigger change event if selecting an option that passes the limit\n* [#1284]: check if all options are already selected/deselected before triggering changed/changed.bs.select\n* [#1245], [#1310]: With livesearch, when keypress, focus to search field isn't working with some characters\n* [#1257]: fix issue with Norwegian translation\n* [#1346]: fix edge case where default values are not respected when initializing the plugin\n* [#1338]: improve support for disabled optgroups and hidden options\n* [#1373]: prevent selectAll and deselectAll from being called on standard select boxes\n* [#1363]: if hideDisabled is enabled, and all options in an optgroup are disabled, the optgroup is still visible\n* [#1422]: fix menu position inside a scrolling container\n* [#1451]: fix select with input-group-addon on both sides\n* [#1465]: changed.bs.select not firing for native mobile menu\n* [#1459]: jQuery 3 support - $.expr[':'] -> $.expr.pseudos\n\n#### New Features\n* [#1139]: add placeholder styling via `bs-placeholder` class\n* [#1290]: auto close the menu if maxOptions is set to 1 (instead of leaving open)\n* [#1127], [#1016], [#1160], [#1269]: add 'auto' option for dropdownAlignRight\n* [58ed408]: support using a string for maxOptionsText\n* [#541]: ARIA - Accessibility\n\n[#1291]: https://github.com/silviomoreto/bootstrap-select/issues/1291\n[#1284]: https://github.com/silviomoreto/bootstrap-select/issues/1284\n[#1245]: https://github.com/silviomoreto/bootstrap-select/issues/1245\n[#1257]: https://github.com/silviomoreto/bootstrap-select/issues/1257\n[#1310]: https://github.com/silviomoreto/bootstrap-select/issues/1310\n[#1346]: https://github.com/silviomoreto/bootstrap-select/issues/1346\n[#1338]: https://github.com/silviomoreto/bootstrap-select/issues/1338\n[#1373]: https://github.com/silviomoreto/bootstrap-select/issues/1373\n[#1363]: https://github.com/silviomoreto/bootstrap-select/issues/1363\n[#1422]: https://github.com/silviomoreto/bootstrap-select/issues/1422\n[#1451]: https://github.com/silviomoreto/bootstrap-select/issues/1451\n[#1465]: https://github.com/silviomoreto/bootstrap-select/issues/1465\n[#1459]: https://github.com/silviomoreto/bootstrap-select/issues/1459\n[#1139]: https://github.com/silviomoreto/bootstrap-select/issues/1139\n[#1290]: https://github.com/silviomoreto/bootstrap-select/issues/1290\n[#1127]: https://github.com/silviomoreto/bootstrap-select/issues/1127\n[#1016]: https://github.com/silviomoreto/bootstrap-select/issues/1016\n[#1160]: https://github.com/silviomoreto/bootstrap-select/issues/1160\n[#1269]: https://github.com/silviomoreto/bootstrap-select/issues/1269\n[58ed408]: https://github.com/silviomoreto/bootstrap-select/commit/58ed4085019526141be07beeada37788dfe2d316\n[#541]: https://github.com/silviomoreto/bootstrap-select/issues/541\n\n-------------------\n\n### v1.10.0 (2016-02-17)\n\n#### Bug Fixes\n* [#1268]: performance bug in clickListener\n* [#1273]: html5 validation message disappears in Chrome 47+\n* [#1295]: hide select by default (so there is no flash of unstyled content)\n\n#### New Features\n* [#950]: add `.selectpicker('toggle')` method to allow menu to be open/closed programmatically\n* [#1272]: add showTick option\n* [#1284]: selectAll and deselectAll now trigger the `changed.bs.select` event\n\nAdd Lithuanian translations.\n\n[#1268]: https://github.com/silviomoreto/bootstrap-select/issues/1268\n[#1273]: https://github.com/silviomoreto/bootstrap-select/issues/1273\n[#1295]: https://github.com/silviomoreto/bootstrap-select/issues/1295\n[#950]: https://github.com/silviomoreto/bootstrap-select/issues/950\n[#1272]: https://github.com/silviomoreto/bootstrap-select/issues/1272\n[#1284]: https://github.com/silviomoreto/bootstrap-select/issues/1284\n\n-------------------\n\n### v1.9.4 (2016-01-18)\n\n#### Bug fixes\n* [#1250]: don't destroy original select when using `destroy` method\n* [#1230]: Optgroup label missing when first option is disabled and `hideDisabled` is true\n\nAdd new translations.\n\n[#1250]: https://github.com/silviomoreto/bootstrap-select/issues/1250\n[#1230]: https://github.com/silviomoreto/bootstrap-select/issues/1230\n\n-------------------\n\n### v1.9.3 (2015-12-16)\n\n#### Bug fixes\n* Fix [#1235] - issue with selects that had `form-control` class\n\n[#1235]: https://github.com/silviomoreto/bootstrap-select/issues/1235\n"
  },
  {
    "path": "app_backend/static/plugin/bootstrap-select-1.12.2/CONTRIBUTING.md",
    "content": "# Contributing to this project\n\nPlease take a moment to review this document in order to make the contribution\nprocess easy and effective for everyone involved.\n\nFollowing these guidelines helps to communicate that you respect the time of\nthe developers managing and developing this open source project. In return,\nthey should reciprocate that respect in addressing your issue or assessing\npatches and features.\n\n\n## Using the issue tracker\n\nThe issue tracker is the preferred channel for [bug reports](#bug-reports),\n[features requests](#feature-requests) and submitting pull requests, but please\nrespect the following restrictions:\n\n* Please **do not** use the issue tracker for personal support requests (use\n  [Stack Overflow](http://stackoverflow.com) or IRC).\n\n* Please **do not** derail or troll issues. Keep the discussion on topic and\n  respect the opinions of others.\n\n\n## Bug reports\n\nA bug is a _demonstrable problem_ that is caused by the code in the repository.\nGood bug reports are extremely helpful - thank you!\n\nGuidelines for bug reports:\n\n1. **Use the GitHub issue search.** Check if the issue has already been\n   reported.\n\n2. **Check if the issue has been fixed.** Try to reproduce it using the\n   latest `master` or development branch in the repository.\n\n3. **Provide environment details.** Provide your operating system, browser(s),\n   jQuery version, Bootstrap version, and bootstrap-select version.\n\n4. **Create an isolated and reproducible test case.** Create a [reduced test\n   case](http://css-tricks.com/6263-reduced-test-cases/).\n\n5. **Include a live example.** Use [this Plunker debugging template](http://silviomoreto.github.io/bootstrap-select/playground/) to share your isolated test cases. You can also make use of [jsFiddle](http://jsfiddle.net/) or [jsBin](http://jsbin.com/).\n\nA good bug report shouldn't leave others needing to chase you up for more\ninformation. Please try to be as detailed as possible in your report. What is\nyour environment? What steps will reproduce the issue? What browser(s) and OS\nexperience the problem? What would you expect to be the outcome? All these\ndetails will help people to fix any potential bugs.\n\nExample:\n\n> Short and descriptive example bug report title\n>\n> A summary of the issue and the browser/OS environment in which it occurs. If\n> suitable, include the steps required to reproduce the bug.\n>\n> 1. This is the first step\n> 2. This is the second step\n> 3. Further steps, etc.\n>\n> `<url>` - a link to the reduced test case\n>\n> Any other information you want to share that is relevant to the issue being\n> reported. This might include the lines of code that you have identified as\n> causing the bug, and potential solutions (and your opinions on their\n> merits).\n\n\n## Feature requests\n\nFeature requests are welcome. But take a moment to find out whether your idea\nfits with the scope and aims of the project. It's up to *you* to make a strong\ncase to convince the project's developers of the merits of this feature. Please\nprovide as much detail and context as possible.\n\n## Pull Request Guidelines\n\nYou must understand that by contributing code to this project, you are granting\nthe authors (and/or leaders) of the project a non-exclusive license to\nre-distribute your code under the current license and possibly re-license the\ncode as deemed necessary.\n\n* To instantiate a context or use it, use the variable **that** instead of\n  **_this**.\n* Please check to make sure that there aren't existing pull requests attempting\n  to address the issue mentioned. We also recommend checking for issues related\n  to the issue on the tracker, as a team member may be working on the issue in\n  a branch or fork.\n* Non-trivial changes should be discussed in an issue first\n* When modifying files, please do not edit the generated or minified files in the dist/ directory. Please edit the original files.\n* If possible, add relevant tests to cover the change\n* Write a convincing description of your PR and why we should land it\n\n## Using Grunt\n\nWe are using node and grunt to build and (in the future) test this project.\nThis means that you must setup a local development environment:\n\n1. Install `node` and `npm` using your preferred method\n2. Install the grunt CLI: `npm install -g grunt-cli`\n3. Install the project's development dependencies: `npm install`\n4. Run the various grunt tasks as needed:\n   - `grunt`: clean the distribution files and re-build them\n   - `grunt dist`: build the distribution files\n   - `grunt clean`: clean the distribution files\n   - `grunt dist-css`: build the css distribution files\n   - `grunt dist-js`: build the javascript distribution files\n   - `grunt watch`: watch for changes in the source files and build the\n     distribution files as needed\n\n"
  },
  {
    "path": "app_backend/static/plugin/bootstrap-select-1.12.2/Gruntfile.js",
    "content": "module.exports = function (grunt) {\n\n  // From TWBS\n  RegExp.quote = function (string) {\n    return string.replace(/[-\\\\^$*+?.()|[\\]{}]/g, '\\\\$&');\n  };\n\n  // Project configuration.\n  grunt.initConfig({\n\n    // Metadata.\n    pkg: grunt.file.readJSON('package.json'),\n    banner: '/*!\\n' +\n    ' * Bootstrap-select v<%= pkg.version %> (<%= pkg.homepage %>)\\n' +\n    ' *\\n' +\n    ' * Copyright 2013-<%= grunt.template.today(\\'yyyy\\') %> bootstrap-select\\n' +\n    ' * Licensed under <%= pkg.license %> (https://github.com/silviomoreto/bootstrap-select/blob/master/LICENSE)\\n' +\n    ' */\\n',\n\n    // Task configuration.\n\n    clean: {\n      css: 'dist/css',\n      js: 'dist/js',\n      docs: 'docs/docs/dist'\n    },\n\n    jshint: {\n      options: {\n        jshintrc: 'js/.jshintrc'\n      },\n      gruntfile: {\n        options: {\n          'node': true\n        },\n        src: 'Gruntfile.js'\n      },\n      main: {\n        src: 'js/*.js'\n      },\n      i18n: {\n        src: 'js/i18n/*.js'\n      }\n    },\n\n    concat: {\n      options: {\n        stripBanners: true\n      },\n      main: {\n        src: '<%= jshint.main.src %>',\n        dest: 'dist/js/<%= pkg.name %>.js'\n      },\n      i18n: {\n        expand: true,\n        src: '<%= jshint.i18n.src %>',\n        dest: 'dist/'\n      }\n    },\n\n    umd: {\n      main: {\n        options: {\n          deps: {\n            'default': ['jQuery'],\n            amd: ['jquery'],\n            cjs: ['jquery'],\n            global: ['jQuery']\n          }\n        },\n        src: '<%= concat.main.dest %>'\n      },\n      i18n: {\n        options: {\n          deps: {\n            'default': ['jQuery'],\n            amd: ['jquery'],\n            cjs: ['jquery'],\n            global: ['jQuery']\n          }\n        },\n        src: 'dist/<%= jshint.i18n.src %>',\n        dest: '.'\n      }\n    },\n\n    uglify: {\n      options: {\n        preserveComments: function(node, comment) {\n          return /^!|@preserve|@license|@cc_on/i.test(comment.value);\n        }\n      },\n      main: {\n        src: '<%= concat.main.dest %>',\n        dest: 'dist/js/<%= pkg.name %>.min.js',\n        options: {\n          sourceMap: true,\n          sourceMapName: 'dist/js/<%= pkg.name %>.js.map'\n        }\n      },\n      i18n: {\n        expand: true,\n        src: 'dist/<%= jshint.i18n.src %>',\n        ext: '.min.js'\n      }\n    },\n\n    less: {\n      options: {\n        strictMath: true,\n        sourceMap: true,\n        outputSourceFiles: true,\n        sourceMapURL: '<%= pkg.name %>.css.map',\n        sourceMapFilename: '<%= less.css.dest %>.map'\n      },\n      css: {\n        src: 'less/bootstrap-select.less',\n        dest: 'dist/css/<%= pkg.name %>.css'\n      }\n    },\n\n    usebanner: {\n      css: {\n        options: {\n          banner: '<%= banner %>'\n        },\n        src: '<%= less.css.dest %>'\n      },\n      js: {\n        options: {\n          banner: '<%= banner %>'\n        },\n        src: [\n          '<%= concat.main.dest %>',\n          '<%= uglify.main.dest %>',\n          'dist/<%= jshint.i18n.src %>',\n        ]\n      }\n    },\n\n    copy: {\n      docs: {\n        expand: true,\n        cwd: 'dist/',\n        src: [\n          '**/*'\n        ],\n        dest: 'docs/docs/dist/'\n      }\n    },\n\n    cssmin: {\n      options: {\n        compatibility: 'ie8',\n        keepSpecialComments: '*',\n        advanced: false\n      },\n      css: {\n        src: '<%= less.css.dest %>',\n        dest: 'dist/css/<%= pkg.name %>.min.css'\n      }\n    },\n\n    csslint: {\n      options: {\n        'adjoining-classes': false,\n        'box-sizing': false,\n        'box-model': false,\n        'compatible-vendor-prefixes': false,\n        'floats': false,\n        'font-sizes': false,\n        'gradients': false,\n        'important': false,\n        'known-properties': false,\n        'outline-none': false,\n        'qualified-headings': false,\n        'regex-selectors': false,\n        'shorthand': false,\n        'text-indent': false,\n        'unique-headings': false,\n        'universal-selector': false,\n        'unqualified-attributes': false,\n        'overqualified-elements': false\n      },\n      css: {\n        src: '<%= less.css.dest %>'\n      }\n    },\n\n    version: {\n      js: {\n        options: {\n          prefix: 'Selectpicker.VERSION = \\''\n        },\n        src: [\n          'js/<%= pkg.name %>.js'\n        ],\n      },\n      cdn: {\n        options: {\n          prefix: 'ajax/libs/<%= pkg.name %>/'\n        },\n        src: [\n          'README.md',\n          'docs/docs/index.md'\n        ],\n      },\n      nuget: {\n        options: {\n          prefix: '<version>'\n        },\n        src: [\n          'nuget/bootstrap-select.nuspec'\n        ],\n      },\n      default: {\n        options: {\n          prefix: '[\\'\"]?version[\\'\"]?:[ \"\\']*'\n        },\n        src: [\n          'composer.json',\n          'docs/mkdocs.yml',\n          'package.json'\n        ],\n      }\n    },\n\n    autoprefixer: {\n      options: {\n        browsers: [\n          'Android 2.3',\n          'Android >= 4',\n          'Chrome >= 20',\n          'Firefox >= 24', // Firefox 24 is the latest ESR\n          'Explorer >= 8',\n          'iOS >= 6',\n          'Opera >= 12',\n          'Safari >= 6'\n        ]\n      },\n      css: {\n        options: {\n          map: true\n        },\n        src: '<%= less.css.dest %>'\n      }\n    },\n\n    compress: {\n      zip: {\n        options: {\n          archive: 'bootstrap-select-<%= pkg.version %>.zip',\n          mode: 'zip'\n        },\n        files: [\n          {\n            expand: true,\n            cwd: 'dist/',\n            src: '**',\n            dest: 'bootstrap-select-<%= pkg.version %>/'\n          }, {\n            src: ['bower.json', 'composer.json', 'package.json'],\n            dest: 'bootstrap-select-<%= pkg.version %>/'\n          }\n        ]\n      }\n    },\n\n    watch: {\n      gruntfile: {\n        files: '<%= jshint.gruntfile.src %>',\n        tasks: 'jshint:gruntfile'\n      },\n      js: {\n        files: ['<%= jshint.main.src %>', '<%= jshint.i18n.src %>'],\n        tasks: 'build-js'\n      },\n      less: {\n        files: 'less/*.less',\n        tasks: 'build-css'\n      }\n    }\n  });\n\n  // These plugins provide necessary tasks.\n  require('load-grunt-tasks')(grunt, {\n    scope: 'devDependencies'\n  });\n\n  // Version numbering task.\n  // to update version number, use grunt version::x.y.z\n\n  // CSS distribution\n  grunt.registerTask('build-css', ['clean:css', 'less', 'autoprefixer', 'usebanner:css', 'cssmin']);\n\n  // JS distribution\n  grunt.registerTask('build-js', ['clean:js', 'concat', 'umd', 'usebanner:js', 'uglify']);\n\n  // Copy dist to docs\n  grunt.registerTask('docs', ['clean:docs', 'copy:docs']);\n\n  // Development watch\n  grunt.registerTask('dev-watch', ['build-css', 'build-js', 'watch']);\n\n  // Full distribution\n  grunt.registerTask('dist', ['build-css', 'build-js', 'compress']);\n\n  // Default task.\n  grunt.registerTask('default', ['build-css', 'build-js']);\n\n};\n"
  },
  {
    "path": "app_backend/static/plugin/bootstrap-select-1.12.2/LICENSE",
    "content": "The MIT License (MIT)\n\nCopyright (c) 2013-2015 bootstrap-select\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
  },
  {
    "path": "app_backend/static/plugin/bootstrap-select-1.12.2/README.md",
    "content": "bootstrap-select\r\n================\r\n\r\n[![Latest release](https://img.shields.io/github/release/silviomoreto/bootstrap-select.svg)](https://github.com/silviomoreto/bootstrap-select/releases/latest)\r\n[![Bower](https://img.shields.io/bower/v/bootstrap-select.svg)]()\r\n[![npm](https://img.shields.io/npm/v/bootstrap-select.svg)](https://www.npmjs.com/package/bootstrap-select)\r\n[![NuGet](https://img.shields.io/nuget/v/bootstrap-select.svg)](https://www.nuget.org/packages/bootstrap-select/)\r\n[![CDNJS](https://img.shields.io/cdnjs/v/bootstrap-select.svg)](https://cdnjs.com/libraries/bootstrap-select)\r\n\r\n[![License](https://img.shields.io/badge/license-MIT-brightgreen.svg)](LICENSE)\r\n[![Dependency Status](https://david-dm.org/silviomoreto/bootstrap-select.svg)](https://david-dm.org/silviomoreto/bootstrap-select)\r\n[![devDependency Status](https://david-dm.org/silviomoreto/bootstrap-select/dev-status.svg)](https://david-dm.org/silviomoreto/bootstrap-select#info=devDependencies)\r\n\r\nBootstrap-select is a jQuery plugin that utilizes Bootstrap's dropdown.js to style and bring additional functionality to standard select elements.\r\n\r\n<a href=\"http://silviomoreto.github.io/bootstrap-select/\"><img src=\"https://cloud.githubusercontent.com/assets/2874325/18023324/42cf556c-6bb5-11e6-84ce-35be08ae57ba.gif\" alt=\"bootstrap-select demo\"></a>\r\n\r\n## Demo and Documentation\r\n\r\nYou can view a live demo and some examples of how to use the various options [here](http://silviomoreto.github.io/bootstrap-select).\r\n\r\nBootstrap-select's documentation, included in this repo in the root directory, is built with MkDocs and publicly hosted on GitHub Pages at http://silviomoreto.github.io/bootstrap-select. The documentation may also be run locally.\r\n\r\n\r\n### Running documentation locally\r\n\r\n1. If necessary, [install MkDocs](http://www.mkdocs.org/#installation).\r\n3. From the `/bootstrap-select/docs` directory, run `mkdocs serve` in the command line.\r\n4. Open `http://127.0.0.1:8000/` in your browser, and voilà.\r\n\r\nLearn more about using MkDocs by reading its [documentation](http://www.mkdocs.org/).\r\n\r\n## Authors\r\n\r\n[Silvio Moreto](https://github.com/silviomoreto),\r\n[Ana Carolina](https://github.com/anacarolinats),\r\n[caseyjhol](https://github.com/caseyjhol),\r\n[Matt Bryson](https://github.com/mattbryson), and\r\n[t0xicCode](https://github.com/t0xicCode).\r\n\r\n## Usage\r\n\r\nCreate your `<select>` with the `.selectpicker` class.\r\n```html\r\n<select class=\"selectpicker\">\r\n  <option>Mustard</option>\r\n  <option>Ketchup</option>\r\n  <option>Barbecue</option>\r\n</select>\r\n```\r\n\r\nIf you use a 1.6.3 or newer, you don't need to do anything else, as the data-api automatically picks up the `<select>`s with the `selectpicker` class.\r\n\r\nIf you use an older version, you need to add the following either at the bottom of the page (after the last selectpicker), or in a [`$(document).ready()`](http://api.jquery.com/ready/) block.\r\n```js\r\n// To style only <select>s with the selectpicker class\r\n$('.selectpicker').selectpicker();\r\n```\r\nOr\r\n```js\r\n// To style all <select>s\r\n$('select').selectpicker();\r\n```\r\n\r\nCheckout the [documentation](http://silviomoreto.github.io/bootstrap-select) for further information.\r\n\r\n## CDN\r\n\r\n**N.B.**: The CDN is updated after the release is made public, which means that there is a delay between the publishing of a release and its availability on the CDN. Check [the GitHub page](https://github.com/silviomoreto/bootstrap-select/releases) for the latest release.\r\n\r\n* [//cdnjs.cloudflare.com/ajax/libs/bootstrap-select/1.12.2/css/bootstrap-select.min.css](//cdnjs.cloudflare.com/ajax/libs/bootstrap-select/1.12.2/css/bootstrap-select.min.css)\r\n* [//cdnjs.cloudflare.com/ajax/libs/bootstrap-select/1.12.2/js/bootstrap-select.min.js](//cdnjs.cloudflare.com/ajax/libs/bootstrap-select/1.12.2/js/bootstrap-select.min.js)\r\n* //cdnjs.cloudflare.com/ajax/libs/bootstrap-select/1.12.2/js/i18n/defaults-*.min.js (The translation files)\r\n\r\n## Bugs and feature requests\r\n\r\nAnyone and everyone is welcome to contribute. **Please take a moment to\r\nreview the [guidelines for contributing](CONTRIBUTING.md)**. Make sure you're using the latest version of bootstrap-select before submitting an issue.\r\n\r\n* [Bug reports](CONTRIBUTING.md#bug-reports)\r\n* [Feature requests](CONTRIBUTING.md#feature-requests)\r\n\r\n## Copyright and license\r\n\r\nCopyright (C) 2013-2015 bootstrap-select\r\n\r\nLicensed under [the MIT license](LICENSE).\r\n\r\n## Used by\r\n\r\n* [SnapAppointments](https://snapappointments.com)\r\n* [Thermo Fisher Scientific Inc.](https://www.thermofisher.com)\r\n* [membermeister](https://www.membermeister.com)\r\n* [Solve for All](https://solveforall.com)\r\n* [EstiMATEit](http://www.123itworks.co.uk)\r\n* [Convertizer](https://convertizer.com)\r\n\r\nDoes your organization use bootstrap-select? Open an issue, and include a link and logo, and you'll be added to the list.\r\n"
  },
  {
    "path": "app_backend/static/plugin/bootstrap-select-1.12.2/bower.json",
    "content": "{\n  \"name\": \"bootstrap-select\",\n  \"main\": [\n    \"less/bootstrap-select.less\",\n    \"dist/css/bootstrap-select.css\",\n    \"dist/js/bootstrap-select.js\"\n  ],\n  \"homepage\": \"http://silviomoreto.github.io/bootstrap-select\",\n  \"authors\": [\n    \"silviomoreto\"\n  ],\n  \"keywords\": [\n    \"form\",\n    \"bootstrap\",\n    \"select\",\n    \"replacement\"\n  ],\n  \"dependencies\": {\n    \"jquery\": \">=1.8\"\n  },\n  \"license\": \"MIT\",\n  \"ignore\": [\n    \".gitignore\",\n    \"CONTRIBUTING.md\",\n    \"Gruntfile.js\",\n    \"README.md\",\n    \"composer.json\",\n    \"package.json\",\n    \"test.html\"\n  ]\n}\n"
  },
  {
    "path": "app_backend/static/plugin/bootstrap-select-1.12.2/composer.json",
    "content": "{\n  \"name\": \"bootstrap-select/bootstrap-select\",\n  \"description\": \"Bootstrap-select is a jQuery plugin that utilizes Bootstrap's dropdown.js to style and bring additional functionality to standard select elements.\",\n  \"keywords\": [\n    \"form\",\n    \"bootstrap\",\n    \"select\",\n    \"replacement\"\n  ],\n  \"homepage\": \"http://silviomoreto.github.io/bootstrap-select\",\n  \"version\": \"1.12.2\",\n  \"authors\": [\n    {\n      \"name\": \"Silvio Moreto\",\n      \"homepage\": \"https://github.com/silviomoreto\"\n    }\n  ],\n  \"license\": \"MIT\",\n  \"suggest\": {\n    \"components/jquery\": \">=1.8\",\n    \"twbs/bootstrap\": \"~3.0.0\"\n  }\n}\n"
  },
  {
    "path": "app_backend/static/plugin/bootstrap-select-1.12.2/dist/css/bootstrap-select.css",
    "content": "/*!\r\n * Bootstrap-select v1.12.2 (http://silviomoreto.github.io/bootstrap-select)\r\n *\r\n * Copyright 2013-2017 bootstrap-select\r\n * Licensed under MIT (https://github.com/silviomoreto/bootstrap-select/blob/master/LICENSE)\r\n */\r\n\r\nselect.bs-select-hidden,\nselect.selectpicker {\n  display: none !important;\n}\n.bootstrap-select {\n  width: 220px \\0;\n  /*IE9 and below*/\n}\n.bootstrap-select > .dropdown-toggle {\n  width: 100%;\n  padding-right: 25px;\n  z-index: 1;\n}\n.bootstrap-select > .dropdown-toggle.bs-placeholder,\n.bootstrap-select > .dropdown-toggle.bs-placeholder:hover,\n.bootstrap-select > .dropdown-toggle.bs-placeholder:focus,\n.bootstrap-select > .dropdown-toggle.bs-placeholder:active {\n  color: #999;\n}\n.bootstrap-select > select {\n  position: absolute !important;\n  bottom: 0;\n  left: 50%;\n  display: block !important;\n  width: 0.5px !important;\n  height: 100% !important;\n  padding: 0 !important;\n  opacity: 0 !important;\n  border: none;\n}\n.bootstrap-select > select.mobile-device {\n  top: 0;\n  left: 0;\n  display: block !important;\n  width: 100% !important;\n  z-index: 2;\n}\n.has-error .bootstrap-select .dropdown-toggle,\n.error .bootstrap-select .dropdown-toggle {\n  border-color: #b94a48;\n}\n.bootstrap-select.fit-width {\n  width: auto !important;\n}\n.bootstrap-select:not([class*=\"col-\"]):not([class*=\"form-control\"]):not(.input-group-btn) {\n  width: 220px;\n}\n.bootstrap-select .dropdown-toggle:focus {\n  outline: thin dotted #333333 !important;\n  outline: 5px auto -webkit-focus-ring-color !important;\n  outline-offset: -2px;\n}\n.bootstrap-select.form-control {\n  margin-bottom: 0;\n  padding: 0;\n  border: none;\n}\n.bootstrap-select.form-control:not([class*=\"col-\"]) {\n  width: 100%;\n}\n.bootstrap-select.form-control.input-group-btn {\n  z-index: auto;\n}\n.bootstrap-select.form-control.input-group-btn:not(:first-child):not(:last-child) > .btn {\n  border-radius: 0;\n}\n.bootstrap-select.btn-group:not(.input-group-btn),\n.bootstrap-select.btn-group[class*=\"col-\"] {\n  float: none;\n  display: inline-block;\n  margin-left: 0;\n}\n.bootstrap-select.btn-group.dropdown-menu-right,\n.bootstrap-select.btn-group[class*=\"col-\"].dropdown-menu-right,\n.row .bootstrap-select.btn-group[class*=\"col-\"].dropdown-menu-right {\n  float: right;\n}\n.form-inline .bootstrap-select.btn-group,\n.form-horizontal .bootstrap-select.btn-group,\n.form-group .bootstrap-select.btn-group {\n  margin-bottom: 0;\n}\n.form-group-lg .bootstrap-select.btn-group.form-control,\n.form-group-sm .bootstrap-select.btn-group.form-control {\n  padding: 0;\n}\n.form-group-lg .bootstrap-select.btn-group.form-control .dropdown-toggle,\n.form-group-sm .bootstrap-select.btn-group.form-control .dropdown-toggle {\n  height: 100%;\n  font-size: inherit;\n  line-height: inherit;\n  border-radius: inherit;\n}\n.form-inline .bootstrap-select.btn-group .form-control {\n  width: 100%;\n}\n.bootstrap-select.btn-group.disabled,\n.bootstrap-select.btn-group > .disabled {\n  cursor: not-allowed;\n}\n.bootstrap-select.btn-group.disabled:focus,\n.bootstrap-select.btn-group > .disabled:focus {\n  outline: none !important;\n}\n.bootstrap-select.btn-group.bs-container {\n  position: absolute;\n  height: 0 !important;\n  padding: 0 !important;\n}\n.bootstrap-select.btn-group.bs-container .dropdown-menu {\n  z-index: 1060;\n}\n.bootstrap-select.btn-group .dropdown-toggle .filter-option {\n  display: inline-block;\n  overflow: hidden;\n  width: 100%;\n  text-align: left;\n}\n.bootstrap-select.btn-group .dropdown-toggle .caret {\n  position: absolute;\n  top: 50%;\n  right: 12px;\n  margin-top: -2px;\n  vertical-align: middle;\n}\n.bootstrap-select.btn-group[class*=\"col-\"] .dropdown-toggle {\n  width: 100%;\n}\n.bootstrap-select.btn-group .dropdown-menu {\n  min-width: 100%;\n  -webkit-box-sizing: border-box;\n     -moz-box-sizing: border-box;\n          box-sizing: border-box;\n}\n.bootstrap-select.btn-group .dropdown-menu.inner {\n  position: static;\n  float: none;\n  border: 0;\n  padding: 0;\n  margin: 0;\n  border-radius: 0;\n  -webkit-box-shadow: none;\n          box-shadow: none;\n}\n.bootstrap-select.btn-group .dropdown-menu li {\n  position: relative;\n}\n.bootstrap-select.btn-group .dropdown-menu li.active small {\n  color: #fff;\n}\n.bootstrap-select.btn-group .dropdown-menu li.disabled a {\n  cursor: not-allowed;\n}\n.bootstrap-select.btn-group .dropdown-menu li a {\n  cursor: pointer;\n  -webkit-user-select: none;\n     -moz-user-select: none;\n      -ms-user-select: none;\n          user-select: none;\n}\n.bootstrap-select.btn-group .dropdown-menu li a.opt {\n  position: relative;\n  padding-left: 2.25em;\n}\n.bootstrap-select.btn-group .dropdown-menu li a span.check-mark {\n  display: none;\n}\n.bootstrap-select.btn-group .dropdown-menu li a span.text {\n  display: inline-block;\n}\n.bootstrap-select.btn-group .dropdown-menu li small {\n  padding-left: 0.5em;\n}\n.bootstrap-select.btn-group .dropdown-menu .notify {\n  position: absolute;\n  bottom: 5px;\n  width: 96%;\n  margin: 0 2%;\n  min-height: 26px;\n  padding: 3px 5px;\n  background: #f5f5f5;\n  border: 1px solid #e3e3e3;\n  -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.05);\n          box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.05);\n  pointer-events: none;\n  opacity: 0.9;\n  -webkit-box-sizing: border-box;\n     -moz-box-sizing: border-box;\n          box-sizing: border-box;\n}\n.bootstrap-select.btn-group .no-results {\n  padding: 3px;\n  background: #f5f5f5;\n  margin: 0 5px;\n  white-space: nowrap;\n}\n.bootstrap-select.btn-group.fit-width .dropdown-toggle .filter-option {\n  position: static;\n}\n.bootstrap-select.btn-group.fit-width .dropdown-toggle .caret {\n  position: static;\n  top: auto;\n  margin-top: -1px;\n}\n.bootstrap-select.btn-group.show-tick .dropdown-menu li.selected a span.check-mark {\n  position: absolute;\n  display: inline-block;\n  right: 15px;\n  margin-top: 5px;\n}\n.bootstrap-select.btn-group.show-tick .dropdown-menu li a span.text {\n  margin-right: 34px;\n}\n.bootstrap-select.show-menu-arrow.open > .dropdown-toggle {\n  z-index: 1061;\n}\n.bootstrap-select.show-menu-arrow .dropdown-toggle:before {\n  content: '';\n  border-left: 7px solid transparent;\n  border-right: 7px solid transparent;\n  border-bottom: 7px solid rgba(204, 204, 204, 0.2);\n  position: absolute;\n  bottom: -4px;\n  left: 9px;\n  display: none;\n}\n.bootstrap-select.show-menu-arrow .dropdown-toggle:after {\n  content: '';\n  border-left: 6px solid transparent;\n  border-right: 6px solid transparent;\n  border-bottom: 6px solid white;\n  position: absolute;\n  bottom: -4px;\n  left: 10px;\n  display: none;\n}\n.bootstrap-select.show-menu-arrow.dropup .dropdown-toggle:before {\n  bottom: auto;\n  top: -3px;\n  border-top: 7px solid rgba(204, 204, 204, 0.2);\n  border-bottom: 0;\n}\n.bootstrap-select.show-menu-arrow.dropup .dropdown-toggle:after {\n  bottom: auto;\n  top: -3px;\n  border-top: 6px solid white;\n  border-bottom: 0;\n}\n.bootstrap-select.show-menu-arrow.pull-right .dropdown-toggle:before {\n  right: 12px;\n  left: auto;\n}\n.bootstrap-select.show-menu-arrow.pull-right .dropdown-toggle:after {\n  right: 13px;\n  left: auto;\n}\n.bootstrap-select.show-menu-arrow.open > .dropdown-toggle:before,\n.bootstrap-select.show-menu-arrow.open > .dropdown-toggle:after {\n  display: block;\n}\n.bs-searchbox,\n.bs-actionsbox,\n.bs-donebutton {\n  padding: 4px 8px;\n}\n.bs-actionsbox {\n  width: 100%;\n  -webkit-box-sizing: border-box;\n     -moz-box-sizing: border-box;\n          box-sizing: border-box;\n}\n.bs-actionsbox .btn-group button {\n  width: 50%;\n}\n.bs-donebutton {\n  float: left;\n  width: 100%;\n  -webkit-box-sizing: border-box;\n     -moz-box-sizing: border-box;\n          box-sizing: border-box;\n}\n.bs-donebutton .btn-group button {\n  width: 100%;\n}\n.bs-searchbox + .bs-actionsbox {\n  padding: 0 8px 4px;\n}\n.bs-searchbox .form-control {\n  margin-bottom: 0;\n  width: 100%;\n  float: none;\n}\n/*# sourceMappingURL=bootstrap-select.css.map */"
  },
  {
    "path": "app_backend/static/plugin/bootstrap-select-1.12.2/dist/js/bootstrap-select.js",
    "content": "/*!\n * Bootstrap-select v1.12.2 (http://silviomoreto.github.io/bootstrap-select)\n *\n * Copyright 2013-2017 bootstrap-select\n * Licensed under MIT (https://github.com/silviomoreto/bootstrap-select/blob/master/LICENSE)\n */\n\n(function (root, factory) {\n  if (typeof define === 'function' && define.amd) {\n    // AMD. Register as an anonymous module unless amdModuleId is set\n    define([\"jquery\"], function (a0) {\n      return (factory(a0));\n    });\n  } else if (typeof module === 'object' && module.exports) {\n    // Node. Does not work with strict CommonJS, but\n    // only CommonJS-like environments that support module.exports,\n    // like Node.\n    module.exports = factory(require(\"jquery\"));\n  } else {\n    factory(root[\"jQuery\"]);\n  }\n}(this, function (jQuery) {\n\n(function ($) {\n  'use strict';\n\n  //<editor-fold desc=\"Shims\">\n  if (!String.prototype.includes) {\n    (function () {\n      'use strict'; // needed to support `apply`/`call` with `undefined`/`null`\n      var toString = {}.toString;\n      var defineProperty = (function () {\n        // IE 8 only supports `Object.defineProperty` on DOM elements\n        try {\n          var object = {};\n          var $defineProperty = Object.defineProperty;\n          var result = $defineProperty(object, object, object) && $defineProperty;\n        } catch (error) {\n        }\n        return result;\n      }());\n      var indexOf = ''.indexOf;\n      var includes = function (search) {\n        if (this == null) {\n          throw new TypeError();\n        }\n        var string = String(this);\n        if (search && toString.call(search) == '[object RegExp]') {\n          throw new TypeError();\n        }\n        var stringLength = string.length;\n        var searchString = String(search);\n        var searchLength = searchString.length;\n        var position = arguments.length > 1 ? arguments[1] : undefined;\n        // `ToInteger`\n        var pos = position ? Number(position) : 0;\n        if (pos != pos) { // better `isNaN`\n          pos = 0;\n        }\n        var start = Math.min(Math.max(pos, 0), stringLength);\n        // Avoid the `indexOf` call if no match is possible\n        if (searchLength + start > stringLength) {\n          return false;\n        }\n        return indexOf.call(string, searchString, pos) != -1;\n      };\n      if (defineProperty) {\n        defineProperty(String.prototype, 'includes', {\n          'value': includes,\n          'configurable': true,\n          'writable': true\n        });\n      } else {\n        String.prototype.includes = includes;\n      }\n    }());\n  }\n\n  if (!String.prototype.startsWith) {\n    (function () {\n      'use strict'; // needed to support `apply`/`call` with `undefined`/`null`\n      var defineProperty = (function () {\n        // IE 8 only supports `Object.defineProperty` on DOM elements\n        try {\n          var object = {};\n          var $defineProperty = Object.defineProperty;\n          var result = $defineProperty(object, object, object) && $defineProperty;\n        } catch (error) {\n        }\n        return result;\n      }());\n      var toString = {}.toString;\n      var startsWith = function (search) {\n        if (this == null) {\n          throw new TypeError();\n        }\n        var string = String(this);\n        if (search && toString.call(search) == '[object RegExp]') {\n          throw new TypeError();\n        }\n        var stringLength = string.length;\n        var searchString = String(search);\n        var searchLength = searchString.length;\n        var position = arguments.length > 1 ? arguments[1] : undefined;\n        // `ToInteger`\n        var pos = position ? Number(position) : 0;\n        if (pos != pos) { // better `isNaN`\n          pos = 0;\n        }\n        var start = Math.min(Math.max(pos, 0), stringLength);\n        // Avoid the `indexOf` call if no match is possible\n        if (searchLength + start > stringLength) {\n          return false;\n        }\n        var index = -1;\n        while (++index < searchLength) {\n          if (string.charCodeAt(start + index) != searchString.charCodeAt(index)) {\n            return false;\n          }\n        }\n        return true;\n      };\n      if (defineProperty) {\n        defineProperty(String.prototype, 'startsWith', {\n          'value': startsWith,\n          'configurable': true,\n          'writable': true\n        });\n      } else {\n        String.prototype.startsWith = startsWith;\n      }\n    }());\n  }\n\n  if (!Object.keys) {\n    Object.keys = function (\n      o, // object\n      k, // key\n      r  // result array\n      ){\n      // initialize object and result\n      r=[];\n      // iterate over object keys\n      for (k in o)\n          // fill result array with non-prototypical keys\n        r.hasOwnProperty.call(o, k) && r.push(k);\n      // return result\n      return r;\n    };\n  }\n\n  // set data-selected on select element if the value has been programmatically selected\n  // prior to initialization of bootstrap-select\n  // * consider removing or replacing an alternative method *\n  var valHooks = {\n    useDefault: false,\n    _set: $.valHooks.select.set\n  };\n\n  $.valHooks.select.set = function(elem, value) {\n    if (value && !valHooks.useDefault) $(elem).data('selected', true);\n\n    return valHooks._set.apply(this, arguments);\n  };\n\n  var changed_arguments = null;\n  $.fn.triggerNative = function (eventName) {\n    var el = this[0],\n        event;\n\n    if (el.dispatchEvent) { // for modern browsers & IE9+\n      if (typeof Event === 'function') {\n        // For modern browsers\n        event = new Event(eventName, {\n          bubbles: true\n        });\n      } else {\n        // For IE since it doesn't support Event constructor\n        event = document.createEvent('Event');\n        event.initEvent(eventName, true, false);\n      }\n\n      el.dispatchEvent(event);\n    } else if (el.fireEvent) { // for IE8\n      event = document.createEventObject();\n      event.eventType = eventName;\n      el.fireEvent('on' + eventName, event);\n    } else {\n      // fall back to jQuery.trigger\n      this.trigger(eventName);\n    }\n  };\n  //</editor-fold>\n\n  // Case insensitive contains search\n  $.expr.pseudos.icontains = function (obj, index, meta) {\n    var $obj = $(obj);\n    var haystack = ($obj.data('tokens') || $obj.text()).toString().toUpperCase();\n    return haystack.includes(meta[3].toUpperCase());\n  };\n\n  // Case insensitive begins search\n  $.expr.pseudos.ibegins = function (obj, index, meta) {\n    var $obj = $(obj);\n    var haystack = ($obj.data('tokens') || $obj.text()).toString().toUpperCase();\n    return haystack.startsWith(meta[3].toUpperCase());\n  };\n\n  // Case and accent insensitive contains search\n  $.expr.pseudos.aicontains = function (obj, index, meta) {\n    var $obj = $(obj);\n    var haystack = ($obj.data('tokens') || $obj.data('normalizedText') || $obj.text()).toString().toUpperCase();\n    return haystack.includes(meta[3].toUpperCase());\n  };\n\n  // Case and accent insensitive begins search\n  $.expr.pseudos.aibegins = function (obj, index, meta) {\n    var $obj = $(obj);\n    var haystack = ($obj.data('tokens') || $obj.data('normalizedText') || $obj.text()).toString().toUpperCase();\n    return haystack.startsWith(meta[3].toUpperCase());\n  };\n\n  /**\n   * Remove all diatrics from the given text.\n   * @access private\n   * @param {String} text\n   * @returns {String}\n   */\n  function normalizeToBase(text) {\n    var rExps = [\n      {re: /[\\xC0-\\xC6]/g, ch: \"A\"},\n      {re: /[\\xE0-\\xE6]/g, ch: \"a\"},\n      {re: /[\\xC8-\\xCB]/g, ch: \"E\"},\n      {re: /[\\xE8-\\xEB]/g, ch: \"e\"},\n      {re: /[\\xCC-\\xCF]/g, ch: \"I\"},\n      {re: /[\\xEC-\\xEF]/g, ch: \"i\"},\n      {re: /[\\xD2-\\xD6]/g, ch: \"O\"},\n      {re: /[\\xF2-\\xF6]/g, ch: \"o\"},\n      {re: /[\\xD9-\\xDC]/g, ch: \"U\"},\n      {re: /[\\xF9-\\xFC]/g, ch: \"u\"},\n      {re: /[\\xC7-\\xE7]/g, ch: \"c\"},\n      {re: /[\\xD1]/g, ch: \"N\"},\n      {re: /[\\xF1]/g, ch: \"n\"}\n    ];\n    $.each(rExps, function () {\n      text = text ? text.replace(this.re, this.ch) : '';\n    });\n    return text;\n  }\n\n\n  // List of HTML entities for escaping.\n  var escapeMap = {\n    '&': '&amp;',\n    '<': '&lt;',\n    '>': '&gt;',\n    '\"': '&quot;',\n    \"'\": '&#x27;',\n    '`': '&#x60;'\n  };\n  \n  var unescapeMap = {\n    '&amp;': '&',\n    '&lt;': '<',\n    '&gt;': '>',\n    '&quot;': '\"',\n    '&#x27;': \"'\",\n    '&#x60;': '`'\n  };\n\n  // Functions for escaping and unescaping strings to/from HTML interpolation.\n  var createEscaper = function(map) {\n    var escaper = function(match) {\n      return map[match];\n    };\n    // Regexes for identifying a key that needs to be escaped.\n    var source = '(?:' + Object.keys(map).join('|') + ')';\n    var testRegexp = RegExp(source);\n    var replaceRegexp = RegExp(source, 'g');\n    return function(string) {\n      string = string == null ? '' : '' + string;\n      return testRegexp.test(string) ? string.replace(replaceRegexp, escaper) : string;\n    };\n  };\n\n  var htmlEscape = createEscaper(escapeMap);\n  var htmlUnescape = createEscaper(unescapeMap);\n\n  var Selectpicker = function (element, options) {\n    // bootstrap-select has been initialized - revert valHooks.select.set back to its original function\n    if (!valHooks.useDefault) {\n      $.valHooks.select.set = valHooks._set;\n      valHooks.useDefault = true;\n    }\n\n    this.$element = $(element);\n    this.$newElement = null;\n    this.$button = null;\n    this.$menu = null;\n    this.$lis = null;\n    this.options = options;\n\n    // If we have no title yet, try to pull it from the html title attribute (jQuery doesnt' pick it up as it's not a\n    // data-attribute)\n    if (this.options.title === null) {\n      this.options.title = this.$element.attr('title');\n    }\n\n    // Format window padding\n    var winPad = this.options.windowPadding;\n    if (typeof winPad === 'number') {\n      this.options.windowPadding = [winPad, winPad, winPad, winPad];\n    }\n\n    //Expose public methods\n    this.val = Selectpicker.prototype.val;\n    this.render = Selectpicker.prototype.render;\n    this.refresh = Selectpicker.prototype.refresh;\n    this.setStyle = Selectpicker.prototype.setStyle;\n    this.selectAll = Selectpicker.prototype.selectAll;\n    this.deselectAll = Selectpicker.prototype.deselectAll;\n    this.destroy = Selectpicker.prototype.destroy;\n    this.remove = Selectpicker.prototype.remove;\n    this.show = Selectpicker.prototype.show;\n    this.hide = Selectpicker.prototype.hide;\n\n    this.init();\n  };\n\n  Selectpicker.VERSION = '1.12.2';\n\n  // part of this is duplicated in i18n/defaults-en_US.js. Make sure to update both.\n  Selectpicker.DEFAULTS = {\n    noneSelectedText: 'Nothing selected',\n    noneResultsText: 'No results matched {0}',\n    countSelectedText: function (numSelected, numTotal) {\n      return (numSelected == 1) ? \"{0} item selected\" : \"{0} items selected\";\n    },\n    maxOptionsText: function (numAll, numGroup) {\n      return [\n        (numAll == 1) ? 'Limit reached ({n} item max)' : 'Limit reached ({n} items max)',\n        (numGroup == 1) ? 'Group limit reached ({n} item max)' : 'Group limit reached ({n} items max)'\n      ];\n    },\n    selectAllText: 'Select All',\n    deselectAllText: 'Deselect All',\n    doneButton: false,\n    doneButtonText: 'Close',\n    multipleSeparator: ', ',\n    styleBase: 'btn',\n    style: 'btn-default',\n    size: 'auto',\n    title: null,\n    selectedTextFormat: 'values',\n    width: false,\n    container: false,\n    hideDisabled: false,\n    showSubtext: false,\n    showIcon: true,\n    showContent: true,\n    dropupAuto: true,\n    header: false,\n    liveSearch: false,\n    liveSearchPlaceholder: null,\n    liveSearchNormalize: false,\n    liveSearchStyle: 'contains',\n    actionsBox: false,\n    iconBase: 'glyphicon',\n    tickIcon: 'glyphicon-ok',\n    showTick: false,\n    template: {\n      caret: '<span class=\"caret\"></span>'\n    },\n    maxOptions: false,\n    mobile: false,\n    selectOnTab: false,\n    dropdownAlignRight: false,\n    windowPadding: 0\n  };\n\n  Selectpicker.prototype = {\n\n    constructor: Selectpicker,\n\n    init: function () {\n      var that = this,\n          id = this.$element.attr('id');\n\n      this.$element.addClass('bs-select-hidden');\n\n      // store originalIndex (key) and newIndex (value) in this.liObj for fast accessibility\n      // allows us to do this.$lis.eq(that.liObj[index]) instead of this.$lis.filter('[data-original-index=\"' + index + '\"]')\n      this.liObj = {};\n      this.multiple = this.$element.prop('multiple');\n      this.autofocus = this.$element.prop('autofocus');\n      this.$newElement = this.createView();\n      this.$element\n        .after(this.$newElement)\n        .appendTo(this.$newElement);\n      this.$button = this.$newElement.children('button');\n      this.$menu = this.$newElement.children('.dropdown-menu');\n      this.$menuInner = this.$menu.children('.inner');\n      this.$searchbox = this.$menu.find('input');\n\n      this.$element.removeClass('bs-select-hidden');\n\n      if (this.options.dropdownAlignRight === true) this.$menu.addClass('dropdown-menu-right');\n\n      if (typeof id !== 'undefined') {\n        this.$button.attr('data-id', id);\n        $('label[for=\"' + id + '\"]').click(function (e) {\n          e.preventDefault();\n          that.$button.focus();\n        });\n      }\n\n      this.checkDisabled();\n      this.clickListener();\n      if (this.options.liveSearch) this.liveSearchListener();\n      this.render();\n      this.setStyle();\n      this.setWidth();\n      if (this.options.container) this.selectPosition();\n      this.$menu.data('this', this);\n      this.$newElement.data('this', this);\n      if (this.options.mobile) this.mobile();\n\n      this.$newElement.on({\n        'hide.bs.dropdown': function (e) {\n          that.$menuInner.attr('aria-expanded', false);\n          that.$element.trigger('hide.bs.select', e);\n        },\n        'hidden.bs.dropdown': function (e) {\n          that.$element.trigger('hidden.bs.select', e);\n        },\n        'show.bs.dropdown': function (e) {\n          that.$menuInner.attr('aria-expanded', true);\n          that.$element.trigger('show.bs.select', e);\n        },\n        'shown.bs.dropdown': function (e) {\n          that.$element.trigger('shown.bs.select', e);\n        }\n      });\n\n      if (that.$element[0].hasAttribute('required')) {\n        this.$element.on('invalid', function () {\n          that.$button\n            .addClass('bs-invalid')\n            .focus();\n\n          that.$element.on({\n            'focus.bs.select': function () {\n              that.$button.focus();\n              that.$element.off('focus.bs.select');\n            },\n            'shown.bs.select': function () {\n              that.$element\n                .val(that.$element.val()) // set the value to hide the validation message in Chrome when menu is opened\n                .off('shown.bs.select');\n            },\n            'rendered.bs.select': function () {\n              // if select is no longer invalid, remove the bs-invalid class\n              if (this.validity.valid) that.$button.removeClass('bs-invalid');\n              that.$element.off('rendered.bs.select');\n            }\n          });\n        });\n      }\n\n      setTimeout(function () {\n        that.$element.trigger('loaded.bs.select');\n      });\n    },\n\n    createDropdown: function () {\n      // Options\n      // If we are multiple or showTick option is set, then add the show-tick class\n      var showTick = (this.multiple || this.options.showTick) ? ' show-tick' : '',\n          inputGroup = this.$element.parent().hasClass('input-group') ? ' input-group-btn' : '',\n          autofocus = this.autofocus ? ' autofocus' : '';\n      // Elements\n      var header = this.options.header ? '<div class=\"popover-title\"><button type=\"button\" class=\"close\" aria-hidden=\"true\">&times;</button>' + this.options.header + '</div>' : '';\n      var searchbox = this.options.liveSearch ?\n      '<div class=\"bs-searchbox\">' +\n      '<input type=\"text\" class=\"form-control\" autocomplete=\"off\"' +\n      (null === this.options.liveSearchPlaceholder ? '' : ' placeholder=\"' + htmlEscape(this.options.liveSearchPlaceholder) + '\"') + ' role=\"textbox\" aria-label=\"Search\">' +\n      '</div>'\n          : '';\n      var actionsbox = this.multiple && this.options.actionsBox ?\n      '<div class=\"bs-actionsbox\">' +\n      '<div class=\"btn-group btn-group-sm btn-block\">' +\n      '<button type=\"button\" class=\"actions-btn bs-select-all btn btn-default\">' +\n      this.options.selectAllText +\n      '</button>' +\n      '<button type=\"button\" class=\"actions-btn bs-deselect-all btn btn-default\">' +\n      this.options.deselectAllText +\n      '</button>' +\n      '</div>' +\n      '</div>'\n          : '';\n      var donebutton = this.multiple && this.options.doneButton ?\n      '<div class=\"bs-donebutton\">' +\n      '<div class=\"btn-group btn-block\">' +\n      '<button type=\"button\" class=\"btn btn-sm btn-default\">' +\n      this.options.doneButtonText +\n      '</button>' +\n      '</div>' +\n      '</div>'\n          : '';\n      var drop =\n          '<div class=\"btn-group bootstrap-select' + showTick + inputGroup + '\">' +\n          '<button type=\"button\" class=\"' + this.options.styleBase + ' dropdown-toggle\" data-toggle=\"dropdown\"' + autofocus + ' role=\"button\">' +\n          '<span class=\"filter-option pull-left\"></span>&nbsp;' +\n          '<span class=\"bs-caret\">' +\n          this.options.template.caret +\n          '</span>' +\n          '</button>' +\n          '<div class=\"dropdown-menu open\" role=\"combobox\">' +\n          header +\n          searchbox +\n          actionsbox +\n          '<ul class=\"dropdown-menu inner\" role=\"listbox\" aria-expanded=\"false\">' +\n          '</ul>' +\n          donebutton +\n          '</div>' +\n          '</div>';\n\n      return $(drop);\n    },\n\n    createView: function () {\n      var $drop = this.createDropdown(),\n          li = this.createLi();\n\n      $drop.find('ul')[0].innerHTML = li;\n      return $drop;\n    },\n\n    reloadLi: function () {\n      // rebuild\n      var li = this.createLi();\n      this.$menuInner[0].innerHTML = li;\n    },\n\n    createLi: function () {\n      var that = this,\n          _li = [],\n          optID = 0,\n          titleOption = document.createElement('option'),\n          liIndex = -1; // increment liIndex whenever a new <li> element is created to ensure liObj is correct\n\n      // Helper functions\n      /**\n       * @param content\n       * @param [index]\n       * @param [classes]\n       * @param [optgroup]\n       * @returns {string}\n       */\n      var generateLI = function (content, index, classes, optgroup) {\n        return '<li' +\n            ((typeof classes !== 'undefined' & '' !== classes) ? ' class=\"' + classes + '\"' : '') +\n            ((typeof index !== 'undefined' & null !== index) ? ' data-original-index=\"' + index + '\"' : '') +\n            ((typeof optgroup !== 'undefined' & null !== optgroup) ? 'data-optgroup=\"' + optgroup + '\"' : '') +\n            '>' + content + '</li>';\n      };\n\n      /**\n       * @param text\n       * @param [classes]\n       * @param [inline]\n       * @param [tokens]\n       * @returns {string}\n       */\n      var generateA = function (text, classes, inline, tokens) {\n        return '<a tabindex=\"0\"' +\n            (typeof classes !== 'undefined' ? ' class=\"' + classes + '\"' : '') +\n            (inline ? ' style=\"' + inline + '\"' : '') +\n            (that.options.liveSearchNormalize ? ' data-normalized-text=\"' + normalizeToBase(htmlEscape($(text).html())) + '\"' : '') +\n            (typeof tokens !== 'undefined' || tokens !== null ? ' data-tokens=\"' + tokens + '\"' : '') +\n            ' role=\"option\">' + text +\n            '<span class=\"' + that.options.iconBase + ' ' + that.options.tickIcon + ' check-mark\"></span>' +\n            '</a>';\n      };\n\n      if (this.options.title && !this.multiple) {\n        // this option doesn't create a new <li> element, but does add a new option, so liIndex is decreased\n        // since liObj is recalculated on every refresh, liIndex needs to be decreased even if the titleOption is already appended\n        liIndex--;\n\n        if (!this.$element.find('.bs-title-option').length) {\n          // Use native JS to prepend option (faster)\n          var element = this.$element[0];\n          titleOption.className = 'bs-title-option';\n          titleOption.innerHTML = this.options.title;\n          titleOption.value = '';\n          element.insertBefore(titleOption, element.firstChild);\n          // Check if selected or data-selected attribute is already set on an option. If not, select the titleOption option.\n          // the selected item may have been changed by user or programmatically before the bootstrap select plugin runs,\n          // if so, the select will have the data-selected attribute\n          var $opt = $(element.options[element.selectedIndex]);\n          if ($opt.attr('selected') === undefined && this.$element.data('selected') === undefined) {\n            titleOption.selected = true;\n          }\n        }\n      }\n\n      this.$element.find('option').each(function (index) {\n        var $this = $(this);\n\n        liIndex++;\n\n        if ($this.hasClass('bs-title-option')) return;\n\n        // Get the class and text for the option\n        var optionClass = this.className || '',\n            inline = this.style.cssText,\n            text = $this.data('content') ? $this.data('content') : $this.html(),\n            tokens = $this.data('tokens') ? $this.data('tokens') : null,\n            subtext = typeof $this.data('subtext') !== 'undefined' ? '<small class=\"text-muted\">' + $this.data('subtext') + '</small>' : '',\n            icon = typeof $this.data('icon') !== 'undefined' ? '<span class=\"' + that.options.iconBase + ' ' + $this.data('icon') + '\"></span> ' : '',\n            $parent = $this.parent(),\n            isOptgroup = $parent[0].tagName === 'OPTGROUP',\n            isOptgroupDisabled = isOptgroup && $parent[0].disabled,\n            isDisabled = this.disabled || isOptgroupDisabled;\n\n        if (icon !== '' && isDisabled) {\n          icon = '<span>' + icon + '</span>';\n        }\n\n        if (that.options.hideDisabled && (isDisabled && !isOptgroup || isOptgroupDisabled)) {\n          liIndex--;\n          return;\n        }\n\n        if (!$this.data('content')) {\n          // Prepend any icon and append any subtext to the main text.\n          text = icon + '<span class=\"text\">' + text + subtext + '</span>';\n        }\n\n        if (isOptgroup && $this.data('divider') !== true) {\n          if (that.options.hideDisabled && isDisabled) {\n            if ($parent.data('allOptionsDisabled') === undefined) {\n              var $options = $parent.children();\n              $parent.data('allOptionsDisabled', $options.filter(':disabled').length === $options.length);\n            }\n\n            if ($parent.data('allOptionsDisabled')) {\n              liIndex--;\n              return;\n            }\n          }\n\n          var optGroupClass = ' ' + $parent[0].className || '';\n\n          if ($this.index() === 0) { // Is it the first option of the optgroup?\n            optID += 1;\n\n            // Get the opt group label\n            var label = $parent[0].label,\n                labelSubtext = typeof $parent.data('subtext') !== 'undefined' ? '<small class=\"text-muted\">' + $parent.data('subtext') + '</small>' : '',\n                labelIcon = $parent.data('icon') ? '<span class=\"' + that.options.iconBase + ' ' + $parent.data('icon') + '\"></span> ' : '';\n\n            label = labelIcon + '<span class=\"text\">' + htmlEscape(label) + labelSubtext + '</span>';\n\n            if (index !== 0 && _li.length > 0) { // Is it NOT the first option of the select && are there elements in the dropdown?\n              liIndex++;\n              _li.push(generateLI('', null, 'divider', optID + 'div'));\n            }\n            liIndex++;\n            _li.push(generateLI(label, null, 'dropdown-header' + optGroupClass, optID));\n          }\n\n          if (that.options.hideDisabled && isDisabled) {\n            liIndex--;\n            return;\n          }\n\n          _li.push(generateLI(generateA(text, 'opt ' + optionClass + optGroupClass, inline, tokens), index, '', optID));\n        } else if ($this.data('divider') === true) {\n          _li.push(generateLI('', index, 'divider'));\n        } else if ($this.data('hidden') === true) {\n          _li.push(generateLI(generateA(text, optionClass, inline, tokens), index, 'hidden is-hidden'));\n        } else {\n          var showDivider = this.previousElementSibling && this.previousElementSibling.tagName === 'OPTGROUP';\n\n          // if previous element is not an optgroup and hideDisabled is true\n          if (!showDivider && that.options.hideDisabled) {\n            // get previous elements\n            var $prev = $(this).prevAll();\n\n            for (var i = 0; i < $prev.length; i++) {\n              // find the first element in the previous elements that is an optgroup\n              if ($prev[i].tagName === 'OPTGROUP') {\n                var optGroupDistance = 0;\n\n                // loop through the options in between the current option and the optgroup\n                // and check if they are hidden or disabled\n                for (var d = 0; d < i; d++) {\n                  var prevOption = $prev[d];\n                  if (prevOption.disabled || $(prevOption).data('hidden') === true) optGroupDistance++;\n                }\n\n                // if all of the options between the current option and the optgroup are hidden or disabled, show the divider\n                if (optGroupDistance === i) showDivider = true;\n\n                break;\n              }\n            }\n          }\n\n          if (showDivider) {\n            liIndex++;\n            _li.push(generateLI('', null, 'divider', optID + 'div'));\n          }\n          _li.push(generateLI(generateA(text, optionClass, inline, tokens), index));\n        }\n\n        that.liObj[index] = liIndex;\n      });\n\n      //If we are not multiple, we don't have a selected item, and we don't have a title, select the first element so something is set in the button\n      if (!this.multiple && this.$element.find('option:selected').length === 0 && !this.options.title) {\n        this.$element.find('option').eq(0).prop('selected', true).attr('selected', 'selected');\n      }\n\n      return _li.join('');\n    },\n\n    findLis: function () {\n      if (this.$lis == null) this.$lis = this.$menu.find('li');\n      return this.$lis;\n    },\n\n    /**\n     * @param [updateLi] defaults to true\n     */\n    render: function (updateLi) {\n      var that = this,\n          notDisabled;\n\n      //Update the LI to match the SELECT\n      if (updateLi !== false) {\n        this.$element.find('option').each(function (index) {\n          var $lis = that.findLis().eq(that.liObj[index]);\n\n          that.setDisabled(index, this.disabled || this.parentNode.tagName === 'OPTGROUP' && this.parentNode.disabled, $lis);\n          that.setSelected(index, this.selected, $lis);\n        });\n      }\n\n      this.togglePlaceholder();\n\n      this.tabIndex();\n\n      var selectedItems = this.$element.find('option').map(function () {\n        if (this.selected) {\n          if (that.options.hideDisabled && (this.disabled || this.parentNode.tagName === 'OPTGROUP' && this.parentNode.disabled)) return;\n\n          var $this = $(this),\n              icon = $this.data('icon') && that.options.showIcon ? '<i class=\"' + that.options.iconBase + ' ' + $this.data('icon') + '\"></i> ' : '',\n              subtext;\n\n          if (that.options.showSubtext && $this.data('subtext') && !that.multiple) {\n            subtext = ' <small class=\"text-muted\">' + $this.data('subtext') + '</small>';\n          } else {\n            subtext = '';\n          }\n          if (typeof $this.attr('title') !== 'undefined') {\n            return $this.attr('title');\n          } else if ($this.data('content') && that.options.showContent) {\n            return $this.data('content').toString();\n          } else {\n            return icon + $this.html() + subtext;\n          }\n        }\n      }).toArray();\n\n      //Fixes issue in IE10 occurring when no default option is selected and at least one option is disabled\n      //Convert all the values into a comma delimited string\n      var title = !this.multiple ? selectedItems[0] : selectedItems.join(this.options.multipleSeparator);\n\n      //If this is multi select, and the selectText type is count, the show 1 of 2 selected etc..\n      if (this.multiple && this.options.selectedTextFormat.indexOf('count') > -1) {\n        var max = this.options.selectedTextFormat.split('>');\n        if ((max.length > 1 && selectedItems.length > max[1]) || (max.length == 1 && selectedItems.length >= 2)) {\n          notDisabled = this.options.hideDisabled ? ', [disabled]' : '';\n          var totalCount = this.$element.find('option').not('[data-divider=\"true\"], [data-hidden=\"true\"]' + notDisabled).length,\n              tr8nText = (typeof this.options.countSelectedText === 'function') ? this.options.countSelectedText(selectedItems.length, totalCount) : this.options.countSelectedText;\n          title = tr8nText.replace('{0}', selectedItems.length.toString()).replace('{1}', totalCount.toString());\n        }\n      }\n\n      if (this.options.title == undefined) {\n        this.options.title = this.$element.attr('title');\n      }\n\n      if (this.options.selectedTextFormat == 'static') {\n        title = this.options.title;\n      }\n\n      //If we dont have a title, then use the default, or if nothing is set at all, use the not selected text\n      if (!title) {\n        title = typeof this.options.title !== 'undefined' ? this.options.title : this.options.noneSelectedText;\n      }\n\n      //strip all HTML tags and trim the result, then unescape any escaped tags\n      this.$button.attr('title', htmlUnescape($.trim(title.replace(/<[^>]*>?/g, ''))));\n      this.$button.children('.filter-option').html(title);\n\n      this.$element.trigger('rendered.bs.select');\n    },\n\n    /**\n     * @param [style]\n     * @param [status]\n     */\n    setStyle: function (style, status) {\n      if (this.$element.attr('class')) {\n        this.$newElement.addClass(this.$element.attr('class').replace(/selectpicker|mobile-device|bs-select-hidden|validate\\[.*\\]/gi, ''));\n      }\n\n      var buttonClass = style ? style : this.options.style;\n\n      if (status == 'add') {\n        this.$button.addClass(buttonClass);\n      } else if (status == 'remove') {\n        this.$button.removeClass(buttonClass);\n      } else {\n        this.$button.removeClass(this.options.style);\n        this.$button.addClass(buttonClass);\n      }\n    },\n\n    liHeight: function (refresh) {\n      if (!refresh && (this.options.size === false || this.sizeInfo)) return;\n\n      var newElement = document.createElement('div'),\n          menu = document.createElement('div'),\n          menuInner = document.createElement('ul'),\n          divider = document.createElement('li'),\n          li = document.createElement('li'),\n          a = document.createElement('a'),\n          text = document.createElement('span'),\n          header = this.options.header && this.$menu.find('.popover-title').length > 0 ? this.$menu.find('.popover-title')[0].cloneNode(true) : null,\n          search = this.options.liveSearch ? document.createElement('div') : null,\n          actions = this.options.actionsBox && this.multiple && this.$menu.find('.bs-actionsbox').length > 0 ? this.$menu.find('.bs-actionsbox')[0].cloneNode(true) : null,\n          doneButton = this.options.doneButton && this.multiple && this.$menu.find('.bs-donebutton').length > 0 ? this.$menu.find('.bs-donebutton')[0].cloneNode(true) : null;\n\n      text.className = 'text';\n      newElement.className = this.$menu[0].parentNode.className + ' open';\n      menu.className = 'dropdown-menu open';\n      menuInner.className = 'dropdown-menu inner';\n      divider.className = 'divider';\n\n      text.appendChild(document.createTextNode('Inner text'));\n      a.appendChild(text);\n      li.appendChild(a);\n      menuInner.appendChild(li);\n      menuInner.appendChild(divider);\n      if (header) menu.appendChild(header);\n      if (search) {\n        var input = document.createElement('input');\n        search.className = 'bs-searchbox';\n        input.className = 'form-control';\n        search.appendChild(input);\n        menu.appendChild(search);\n      }\n      if (actions) menu.appendChild(actions);\n      menu.appendChild(menuInner);\n      if (doneButton) menu.appendChild(doneButton);\n      newElement.appendChild(menu);\n\n      document.body.appendChild(newElement);\n\n      var liHeight = a.offsetHeight,\n          headerHeight = header ? header.offsetHeight : 0,\n          searchHeight = search ? search.offsetHeight : 0,\n          actionsHeight = actions ? actions.offsetHeight : 0,\n          doneButtonHeight = doneButton ? doneButton.offsetHeight : 0,\n          dividerHeight = $(divider).outerHeight(true),\n          // fall back to jQuery if getComputedStyle is not supported\n          menuStyle = typeof getComputedStyle === 'function' ? getComputedStyle(menu) : false,\n          $menu = menuStyle ? null : $(menu),\n          menuPadding = {\n            vert: parseInt(menuStyle ? menuStyle.paddingTop : $menu.css('paddingTop')) +\n                  parseInt(menuStyle ? menuStyle.paddingBottom : $menu.css('paddingBottom')) +\n                  parseInt(menuStyle ? menuStyle.borderTopWidth : $menu.css('borderTopWidth')) +\n                  parseInt(menuStyle ? menuStyle.borderBottomWidth : $menu.css('borderBottomWidth')),\n            horiz: parseInt(menuStyle ? menuStyle.paddingLeft : $menu.css('paddingLeft')) +\n                  parseInt(menuStyle ? menuStyle.paddingRight : $menu.css('paddingRight')) +\n                  parseInt(menuStyle ? menuStyle.borderLeftWidth : $menu.css('borderLeftWidth')) +\n                  parseInt(menuStyle ? menuStyle.borderRightWidth : $menu.css('borderRightWidth'))\n          },\n          menuExtras =  {\n            vert: menuPadding.vert +\n                  parseInt(menuStyle ? menuStyle.marginTop : $menu.css('marginTop')) +\n                  parseInt(menuStyle ? menuStyle.marginBottom : $menu.css('marginBottom')) + 2,\n            horiz: menuPadding.horiz +\n                  parseInt(menuStyle ? menuStyle.marginLeft : $menu.css('marginLeft')) +\n                  parseInt(menuStyle ? menuStyle.marginRight : $menu.css('marginRight')) + 2\n          }\n\n      document.body.removeChild(newElement);\n\n      this.sizeInfo = {\n        liHeight: liHeight,\n        headerHeight: headerHeight,\n        searchHeight: searchHeight,\n        actionsHeight: actionsHeight,\n        doneButtonHeight: doneButtonHeight,\n        dividerHeight: dividerHeight,\n        menuPadding: menuPadding,\n        menuExtras: menuExtras\n      };\n    },\n\n    setSize: function () {\n      this.findLis();\n      this.liHeight();\n\n      if (this.options.header) this.$menu.css('padding-top', 0);\n      if (this.options.size === false) return;\n\n      var that = this,\n          $menu = this.$menu,\n          $menuInner = this.$menuInner,\n          $window = $(window),\n          selectHeight = this.$newElement[0].offsetHeight,\n          selectWidth = this.$newElement[0].offsetWidth,\n          liHeight = this.sizeInfo['liHeight'],\n          headerHeight = this.sizeInfo['headerHeight'],\n          searchHeight = this.sizeInfo['searchHeight'],\n          actionsHeight = this.sizeInfo['actionsHeight'],\n          doneButtonHeight = this.sizeInfo['doneButtonHeight'],\n          divHeight = this.sizeInfo['dividerHeight'],\n          menuPadding = this.sizeInfo['menuPadding'],\n          menuExtras = this.sizeInfo['menuExtras'],\n          notDisabled = this.options.hideDisabled ? '.disabled' : '',\n          menuHeight,\n          menuWidth,\n          getHeight,\n          getWidth,\n          selectOffsetTop,\n          selectOffsetBot,\n          selectOffsetLeft,\n          selectOffsetRight,\n          getPos = function() {\n            var pos = that.$newElement.offset(),\n                $container = $(that.options.container),\n                containerPos;\n\n            if (that.options.container && !$container.is('body')) {\n              containerPos = $container.offset();\n              containerPos.top += parseInt($container.css('borderTopWidth'));\n              containerPos.left += parseInt($container.css('borderLeftWidth'));\n            } else {\n              containerPos = { top: 0, left: 0 };\n            }\n\n            var winPad = that.options.windowPadding;\n            selectOffsetTop = pos.top - containerPos.top - $window.scrollTop();\n            selectOffsetBot = $window.height() - selectOffsetTop - selectHeight - containerPos.top - winPad[2];\n            selectOffsetLeft = pos.left - containerPos.left - $window.scrollLeft();\n            selectOffsetRight = $window.width() - selectOffsetLeft - selectWidth - containerPos.left - winPad[1];\n            selectOffsetTop -= winPad[0];\n            selectOffsetLeft -= winPad[3];\n          };\n\n      getPos();\n\n      if (this.options.size === 'auto') {\n        var getSize = function () {\n          var minHeight,\n              hasClass = function (className, include) {\n                return function (element) {\n                    if (include) {\n                        return (element.classList ? element.classList.contains(className) : $(element).hasClass(className));\n                    } else {\n                        return !(element.classList ? element.classList.contains(className) : $(element).hasClass(className));\n                    }\n                };\n              },\n              lis = that.$menuInner[0].getElementsByTagName('li'),\n              lisVisible = Array.prototype.filter ? Array.prototype.filter.call(lis, hasClass('hidden', false)) : that.$lis.not('.hidden'),\n              optGroup = Array.prototype.filter ? Array.prototype.filter.call(lisVisible, hasClass('dropdown-header', true)) : lisVisible.filter('.dropdown-header');\n\n          getPos();\n          menuHeight = selectOffsetBot - menuExtras.vert;\n          menuWidth = selectOffsetRight - menuExtras.horiz;\n\n          if (that.options.container) {\n            if (!$menu.data('height')) $menu.data('height', $menu.height());\n            getHeight = $menu.data('height');\n\n            if (!$menu.data('width')) $menu.data('width', $menu.width());\n            getWidth = $menu.data('width');\n          } else {\n            getHeight = $menu.height();\n            getWidth = $menu.width();\n          }\n\n          if (that.options.dropupAuto) {\n            that.$newElement.toggleClass('dropup', selectOffsetTop > selectOffsetBot && (menuHeight - menuExtras.vert) < getHeight);\n          }\n\n          if (that.$newElement.hasClass('dropup')) {\n            menuHeight = selectOffsetTop - menuExtras.vert;\n          }\n\n          if (that.options.dropdownAlignRight === 'auto') {\n            $menu.toggleClass('dropdown-menu-right', selectOffsetLeft > selectOffsetRight && (menuWidth - menuExtras.horiz) < (getWidth - selectWidth));\n          }\n\n          if ((lisVisible.length + optGroup.length) > 3) {\n            minHeight = liHeight * 3 + menuExtras.vert - 2;\n          } else {\n            minHeight = 0;\n          }\n\n          $menu.css({\n            'max-height': menuHeight + 'px',\n            'overflow': 'hidden',\n            'min-height': minHeight + headerHeight + searchHeight + actionsHeight + doneButtonHeight + 'px'\n          });\n          $menuInner.css({\n            'max-height': menuHeight - headerHeight - searchHeight - actionsHeight - doneButtonHeight - menuPadding.vert + 'px',\n            'overflow-y': 'auto',\n            'min-height': Math.max(minHeight - menuPadding.vert, 0) + 'px'\n          });\n        };\n        getSize();\n        this.$searchbox.off('input.getSize propertychange.getSize').on('input.getSize propertychange.getSize', getSize);\n        $window.off('resize.getSize scroll.getSize').on('resize.getSize scroll.getSize', getSize);\n      } else if (this.options.size && this.options.size != 'auto' && this.$lis.not(notDisabled).length > this.options.size) {\n        var optIndex = this.$lis.not('.divider').not(notDisabled).children().slice(0, this.options.size).last().parent().index(),\n            divLength = this.$lis.slice(0, optIndex + 1).filter('.divider').length;\n        menuHeight = liHeight * this.options.size + divLength * divHeight + menuPadding.vert;\n\n        if (that.options.container) {\n          if (!$menu.data('height')) $menu.data('height', $menu.height());\n          getHeight = $menu.data('height');\n        } else {\n          getHeight = $menu.height();\n        }\n\n        if (that.options.dropupAuto) {\n          //noinspection JSUnusedAssignment\n          this.$newElement.toggleClass('dropup', selectOffsetTop > selectOffsetBot && (menuHeight - menuExtras.vert) < getHeight);\n        }\n        $menu.css({\n          'max-height': menuHeight + headerHeight + searchHeight + actionsHeight + doneButtonHeight + 'px',\n          'overflow': 'hidden',\n          'min-height': ''\n        });\n        $menuInner.css({\n          'max-height': menuHeight - menuPadding.vert + 'px',\n          'overflow-y': 'auto',\n          'min-height': ''\n        });\n      }\n    },\n\n    setWidth: function () {\n      if (this.options.width === 'auto') {\n        this.$menu.css('min-width', '0');\n\n        // Get correct width if element is hidden\n        var $selectClone = this.$menu.parent().clone().appendTo('body'),\n            $selectClone2 = this.options.container ? this.$newElement.clone().appendTo('body') : $selectClone,\n            ulWidth = $selectClone.children('.dropdown-menu').outerWidth(),\n            btnWidth = $selectClone2.css('width', 'auto').children('button').outerWidth();\n\n        $selectClone.remove();\n        $selectClone2.remove();\n\n        // Set width to whatever's larger, button title or longest option\n        this.$newElement.css('width', Math.max(ulWidth, btnWidth) + 'px');\n      } else if (this.options.width === 'fit') {\n        // Remove inline min-width so width can be changed from 'auto'\n        this.$menu.css('min-width', '');\n        this.$newElement.css('width', '').addClass('fit-width');\n      } else if (this.options.width) {\n        // Remove inline min-width so width can be changed from 'auto'\n        this.$menu.css('min-width', '');\n        this.$newElement.css('width', this.options.width);\n      } else {\n        // Remove inline min-width/width so width can be changed\n        this.$menu.css('min-width', '');\n        this.$newElement.css('width', '');\n      }\n      // Remove fit-width class if width is changed programmatically\n      if (this.$newElement.hasClass('fit-width') && this.options.width !== 'fit') {\n        this.$newElement.removeClass('fit-width');\n      }\n    },\n\n    selectPosition: function () {\n      this.$bsContainer = $('<div class=\"bs-container\" />');\n\n      var that = this,\n          $container = $(this.options.container),\n          pos,\n          containerPos,\n          actualHeight,\n          getPlacement = function ($element) {\n            that.$bsContainer.addClass($element.attr('class').replace(/form-control|fit-width/gi, '')).toggleClass('dropup', $element.hasClass('dropup'));\n            pos = $element.offset();\n\n            if (!$container.is('body')) {\n              containerPos = $container.offset();\n              containerPos.top += parseInt($container.css('borderTopWidth')) - $container.scrollTop();\n              containerPos.left += parseInt($container.css('borderLeftWidth')) - $container.scrollLeft();\n            } else {\n              containerPos = { top: 0, left: 0 };\n            }\n\n            actualHeight = $element.hasClass('dropup') ? 0 : $element[0].offsetHeight;\n\n            that.$bsContainer.css({\n              'top': pos.top - containerPos.top + actualHeight,\n              'left': pos.left - containerPos.left,\n              'width': $element[0].offsetWidth\n            });\n          };\n\n      this.$button.on('click', function () {\n        var $this = $(this);\n\n        if (that.isDisabled()) {\n          return;\n        }\n\n        getPlacement(that.$newElement);\n\n        that.$bsContainer\n          .appendTo(that.options.container)\n          .toggleClass('open', !$this.hasClass('open'))\n          .append(that.$menu);\n      });\n\n      $(window).on('resize scroll', function () {\n        getPlacement(that.$newElement);\n      });\n\n      this.$element.on('hide.bs.select', function () {\n        that.$menu.data('height', that.$menu.height());\n        that.$bsContainer.detach();\n      });\n    },\n\n    /**\n     * @param {number} index - the index of the option that is being changed\n     * @param {boolean} selected - true if the option is being selected, false if being deselected\n     * @param {JQuery} $lis - the 'li' element that is being modified\n     */\n    setSelected: function (index, selected, $lis) {\n      if (!$lis) {\n        this.togglePlaceholder(); // check if setSelected is being called by changing the value of the select\n        $lis = this.findLis().eq(this.liObj[index]);\n      }\n\n      $lis.toggleClass('selected', selected).find('a').attr('aria-selected', selected);\n    },\n\n    /**\n     * @param {number} index - the index of the option that is being disabled\n     * @param {boolean} disabled - true if the option is being disabled, false if being enabled\n     * @param {JQuery} $lis - the 'li' element that is being modified\n     */\n    setDisabled: function (index, disabled, $lis) {\n      if (!$lis) {\n        $lis = this.findLis().eq(this.liObj[index]);\n      }\n\n      if (disabled) {\n        $lis.addClass('disabled').children('a').attr('href', '#').attr('tabindex', -1).attr('aria-disabled', true);\n      } else {\n        $lis.removeClass('disabled').children('a').removeAttr('href').attr('tabindex', 0).attr('aria-disabled', false);\n      }\n    },\n\n    isDisabled: function () {\n      return this.$element[0].disabled;\n    },\n\n    checkDisabled: function () {\n      var that = this;\n\n      if (this.isDisabled()) {\n        this.$newElement.addClass('disabled');\n        this.$button.addClass('disabled').attr('tabindex', -1).attr('aria-disabled', true);\n      } else {\n        if (this.$button.hasClass('disabled')) {\n          this.$newElement.removeClass('disabled');\n          this.$button.removeClass('disabled').attr('aria-disabled', false);\n        }\n\n        if (this.$button.attr('tabindex') == -1 && !this.$element.data('tabindex')) {\n          this.$button.removeAttr('tabindex');\n        }\n      }\n\n      this.$button.click(function () {\n        return !that.isDisabled();\n      });\n    },\n\n    togglePlaceholder: function () {\n      var value = this.$element.val();\n      this.$button.toggleClass('bs-placeholder', value === null || value === '' || (value.constructor === Array && value.length === 0));\n    },\n\n    tabIndex: function () {\n      if (this.$element.data('tabindex') !== this.$element.attr('tabindex') && \n        (this.$element.attr('tabindex') !== -98 && this.$element.attr('tabindex') !== '-98')) {\n        this.$element.data('tabindex', this.$element.attr('tabindex'));\n        this.$button.attr('tabindex', this.$element.data('tabindex'));\n      }\n\n      this.$element.attr('tabindex', -98);\n    },\n\n    clickListener: function () {\n      var that = this,\n          $document = $(document);\n\n      $document.data('spaceSelect', false);\n\n      this.$button.on('keyup', function (e) {\n        if (/(32)/.test(e.keyCode.toString(10)) && $document.data('spaceSelect')) {\n            e.preventDefault();\n            $document.data('spaceSelect', false);\n        }\n      });\n\n      this.$button.on('click', function () {\n        that.setSize();\n      });\n\n      this.$element.on('shown.bs.select', function () {\n        if (!that.options.liveSearch && !that.multiple) {\n          that.$menuInner.find('.selected a').focus();\n        } else if (!that.multiple) {\n          var selectedIndex = that.liObj[that.$element[0].selectedIndex];\n\n          if (typeof selectedIndex !== 'number' || that.options.size === false) return;\n\n          // scroll to selected option\n          var offset = that.$lis.eq(selectedIndex)[0].offsetTop - that.$menuInner[0].offsetTop;\n          offset = offset - that.$menuInner[0].offsetHeight/2 + that.sizeInfo.liHeight/2;\n          that.$menuInner[0].scrollTop = offset;\n        }\n      });\n\n      this.$menuInner.on('click', 'li a', function (e) {\n        var $this = $(this),\n            clickedIndex = $this.parent().data('originalIndex'),\n            prevValue = that.$element.val(),\n            prevIndex = that.$element.prop('selectedIndex'),\n            triggerChange = true;\n\n        // Don't close on multi choice menu\n        if (that.multiple && that.options.maxOptions !== 1) {\n          e.stopPropagation();\n        }\n\n        e.preventDefault();\n\n        //Don't run if we have been disabled\n        if (!that.isDisabled() && !$this.parent().hasClass('disabled')) {\n          var $options = that.$element.find('option'),\n              $option = $options.eq(clickedIndex),\n              state = $option.prop('selected'),\n              $optgroup = $option.parent('optgroup'),\n              maxOptions = that.options.maxOptions,\n              maxOptionsGrp = $optgroup.data('maxOptions') || false;\n\n          if (!that.multiple) { // Deselect all others if not multi select box\n            $options.prop('selected', false);\n            $option.prop('selected', true);\n            that.$menuInner.find('.selected').removeClass('selected').find('a').attr('aria-selected', false);\n            that.setSelected(clickedIndex, true);\n          } else { // Toggle the one we have chosen if we are multi select.\n            $option.prop('selected', !state);\n            that.setSelected(clickedIndex, !state);\n            $this.blur();\n\n            if (maxOptions !== false || maxOptionsGrp !== false) {\n              var maxReached = maxOptions < $options.filter(':selected').length,\n                  maxReachedGrp = maxOptionsGrp < $optgroup.find('option:selected').length;\n\n              if ((maxOptions && maxReached) || (maxOptionsGrp && maxReachedGrp)) {\n                if (maxOptions && maxOptions == 1) {\n                  $options.prop('selected', false);\n                  $option.prop('selected', true);\n                  that.$menuInner.find('.selected').removeClass('selected');\n                  that.setSelected(clickedIndex, true);\n                } else if (maxOptionsGrp && maxOptionsGrp == 1) {\n                  $optgroup.find('option:selected').prop('selected', false);\n                  $option.prop('selected', true);\n                  var optgroupID = $this.parent().data('optgroup');\n                  that.$menuInner.find('[data-optgroup=\"' + optgroupID + '\"]').removeClass('selected');\n                  that.setSelected(clickedIndex, true);\n                } else {\n                  var maxOptionsText = typeof that.options.maxOptionsText === 'string' ? [that.options.maxOptionsText, that.options.maxOptionsText] : that.options.maxOptionsText,\n                      maxOptionsArr = typeof maxOptionsText === 'function' ? maxOptionsText(maxOptions, maxOptionsGrp) : maxOptionsText,\n                      maxTxt = maxOptionsArr[0].replace('{n}', maxOptions),\n                      maxTxtGrp = maxOptionsArr[1].replace('{n}', maxOptionsGrp),\n                      $notify = $('<div class=\"notify\"></div>');\n                  // If {var} is set in array, replace it\n                  /** @deprecated */\n                  if (maxOptionsArr[2]) {\n                    maxTxt = maxTxt.replace('{var}', maxOptionsArr[2][maxOptions > 1 ? 0 : 1]);\n                    maxTxtGrp = maxTxtGrp.replace('{var}', maxOptionsArr[2][maxOptionsGrp > 1 ? 0 : 1]);\n                  }\n\n                  $option.prop('selected', false);\n\n                  that.$menu.append($notify);\n\n                  if (maxOptions && maxReached) {\n                    $notify.append($('<div>' + maxTxt + '</div>'));\n                    triggerChange = false;\n                    that.$element.trigger('maxReached.bs.select');\n                  }\n\n                  if (maxOptionsGrp && maxReachedGrp) {\n                    $notify.append($('<div>' + maxTxtGrp + '</div>'));\n                    triggerChange = false;\n                    that.$element.trigger('maxReachedGrp.bs.select');\n                  }\n\n                  setTimeout(function () {\n                    that.setSelected(clickedIndex, false);\n                  }, 10);\n\n                  $notify.delay(750).fadeOut(300, function () {\n                    $(this).remove();\n                  });\n                }\n              }\n            }\n          }\n\n          if (!that.multiple || (that.multiple && that.options.maxOptions === 1)) {\n            that.$button.focus();\n          } else if (that.options.liveSearch) {\n            that.$searchbox.focus();\n          }\n\n          // Trigger select 'change'\n          if (triggerChange) {\n            if ((prevValue != that.$element.val() && that.multiple) || (prevIndex != that.$element.prop('selectedIndex') && !that.multiple)) {\n              // $option.prop('selected') is current option state (selected/unselected). state is previous option state.\n              changed_arguments = [clickedIndex, $option.prop('selected'), state];\n              that.$element\n                .triggerNative('change');\n            }\n          }\n        }\n      });\n\n      this.$menu.on('click', 'li.disabled a, .popover-title, .popover-title :not(.close)', function (e) {\n        if (e.currentTarget == this) {\n          e.preventDefault();\n          e.stopPropagation();\n          if (that.options.liveSearch && !$(e.target).hasClass('close')) {\n            that.$searchbox.focus();\n          } else {\n            that.$button.focus();\n          }\n        }\n      });\n\n      this.$menuInner.on('click', '.divider, .dropdown-header', function (e) {\n        e.preventDefault();\n        e.stopPropagation();\n        if (that.options.liveSearch) {\n          that.$searchbox.focus();\n        } else {\n          that.$button.focus();\n        }\n      });\n\n      this.$menu.on('click', '.popover-title .close', function () {\n        that.$button.click();\n      });\n\n      this.$searchbox.on('click', function (e) {\n        e.stopPropagation();\n      });\n\n      this.$menu.on('click', '.actions-btn', function (e) {\n        if (that.options.liveSearch) {\n          that.$searchbox.focus();\n        } else {\n          that.$button.focus();\n        }\n\n        e.preventDefault();\n        e.stopPropagation();\n\n        if ($(this).hasClass('bs-select-all')) {\n          that.selectAll();\n        } else {\n          that.deselectAll();\n        }\n      });\n\n      this.$element.change(function () {\n        that.render(false);\n        that.$element.trigger('changed.bs.select', changed_arguments);\n        changed_arguments = null;\n      });\n    },\n\n    liveSearchListener: function () {\n      var that = this,\n          $no_results = $('<li class=\"no-results\"></li>');\n\n      this.$button.on('click.dropdown.data-api', function () {\n        that.$menuInner.find('.active').removeClass('active');\n        if (!!that.$searchbox.val()) {\n          that.$searchbox.val('');\n          that.$lis.not('.is-hidden').removeClass('hidden');\n          if (!!$no_results.parent().length) $no_results.remove();\n        }\n        if (!that.multiple) that.$menuInner.find('.selected').addClass('active');\n        setTimeout(function () {\n          that.$searchbox.focus();\n        }, 10);\n      });\n\n      this.$searchbox.on('click.dropdown.data-api focus.dropdown.data-api touchend.dropdown.data-api', function (e) {\n        e.stopPropagation();\n      });\n\n      this.$searchbox.on('input propertychange', function () {\n        that.$lis.not('.is-hidden').removeClass('hidden');\n        that.$lis.filter('.active').removeClass('active');\n        $no_results.remove();\n\n        if (that.$searchbox.val()) {\n          var $searchBase = that.$lis.not('.is-hidden, .divider, .dropdown-header'),\n              $hideItems;\n          if (that.options.liveSearchNormalize) {\n            $hideItems = $searchBase.find('a').not(':a' + that._searchStyle() + '(\"' + normalizeToBase(that.$searchbox.val()) + '\")');\n          } else {\n            $hideItems = $searchBase.find('a').not(':' + that._searchStyle() + '(\"' + that.$searchbox.val() + '\")');\n          }\n\n          if ($hideItems.length === $searchBase.length) {\n            $no_results.html(that.options.noneResultsText.replace('{0}', '\"' + htmlEscape(that.$searchbox.val()) + '\"'));\n            that.$menuInner.append($no_results);\n            that.$lis.addClass('hidden');\n          } else {\n            $hideItems.parent().addClass('hidden');\n\n            var $lisVisible = that.$lis.not('.hidden'),\n                $foundDiv;\n\n            // hide divider if first or last visible, or if followed by another divider\n            $lisVisible.each(function (index) {\n              var $this = $(this);\n\n              if ($this.hasClass('divider')) {\n                if ($foundDiv === undefined) {\n                  $this.addClass('hidden');\n                } else {\n                  if ($foundDiv) $foundDiv.addClass('hidden');\n                  $foundDiv = $this;\n                }\n              } else if ($this.hasClass('dropdown-header') && $lisVisible.eq(index + 1).data('optgroup') !== $this.data('optgroup')) {\n                $this.addClass('hidden');\n              } else {\n                $foundDiv = null;\n              }\n            });\n            if ($foundDiv) $foundDiv.addClass('hidden');\n\n            $searchBase.not('.hidden').first().addClass('active');\n          }\n        }\n      });\n    },\n\n    _searchStyle: function () {\n      var styles = {\n        begins: 'ibegins',\n        startsWith: 'ibegins'\n      };\n\n      return styles[this.options.liveSearchStyle] || 'icontains';\n    },\n\n    val: function (value) {\n      if (typeof value !== 'undefined') {\n        this.$element.val(value);\n        this.render();\n\n        return this.$element;\n      } else {\n        return this.$element.val();\n      }\n    },\n\n    changeAll: function (status) {\n      if (!this.multiple) return;\n      if (typeof status === 'undefined') status = true;\n\n      this.findLis();\n\n      var $options = this.$element.find('option'),\n          $lisVisible = this.$lis.not('.divider, .dropdown-header, .disabled, .hidden'),\n          lisVisLen = $lisVisible.length,\n          selectedOptions = [];\n          \n      if (status) {\n        if ($lisVisible.filter('.selected').length === $lisVisible.length) return;\n      } else {\n        if ($lisVisible.filter('.selected').length === 0) return;\n      }\n          \n      $lisVisible.toggleClass('selected', status);\n\n      for (var i = 0; i < lisVisLen; i++) {\n        var origIndex = $lisVisible[i].getAttribute('data-original-index');\n        selectedOptions[selectedOptions.length] = $options.eq(origIndex)[0];\n      }\n\n      $(selectedOptions).prop('selected', status);\n\n      this.render(false);\n\n      this.togglePlaceholder();\n\n      this.$element\n        .triggerNative('change');\n    },\n\n    selectAll: function () {\n      return this.changeAll(true);\n    },\n\n    deselectAll: function () {\n      return this.changeAll(false);\n    },\n\n    toggle: function (e) {\n      e = e || window.event;\n\n      if (e) e.stopPropagation();\n\n      this.$button.trigger('click');\n    },\n\n    keydown: function (e) {\n      var $this = $(this),\n          $parent = $this.is('input') ? $this.parent().parent() : $this.parent(),\n          $items,\n          that = $parent.data('this'),\n          index,\n          next,\n          first,\n          last,\n          prev,\n          nextPrev,\n          prevIndex,\n          isActive,\n          selector = ':not(.disabled, .hidden, .dropdown-header, .divider)',\n          keyCodeMap = {\n            32: ' ',\n            48: '0',\n            49: '1',\n            50: '2',\n            51: '3',\n            52: '4',\n            53: '5',\n            54: '6',\n            55: '7',\n            56: '8',\n            57: '9',\n            59: ';',\n            65: 'a',\n            66: 'b',\n            67: 'c',\n            68: 'd',\n            69: 'e',\n            70: 'f',\n            71: 'g',\n            72: 'h',\n            73: 'i',\n            74: 'j',\n            75: 'k',\n            76: 'l',\n            77: 'm',\n            78: 'n',\n            79: 'o',\n            80: 'p',\n            81: 'q',\n            82: 'r',\n            83: 's',\n            84: 't',\n            85: 'u',\n            86: 'v',\n            87: 'w',\n            88: 'x',\n            89: 'y',\n            90: 'z',\n            96: '0',\n            97: '1',\n            98: '2',\n            99: '3',\n            100: '4',\n            101: '5',\n            102: '6',\n            103: '7',\n            104: '8',\n            105: '9'\n          };\n\n      if (that.options.liveSearch) $parent = $this.parent().parent();\n\n      if (that.options.container) $parent = that.$menu;\n\n      $items = $('[role=\"listbox\"] li', $parent);\n\n      isActive = that.$newElement.hasClass('open');\n\n      if (!isActive && (e.keyCode >= 48 && e.keyCode <= 57 || e.keyCode >= 96 && e.keyCode <= 105 || e.keyCode >= 65 && e.keyCode <= 90)) {\n        if (!that.options.container) {\n          that.setSize();\n          that.$menu.parent().addClass('open');\n          isActive = true;\n        } else {\n          that.$button.trigger('click');\n        }\n        that.$searchbox.focus();\n        return;\n      }\n\n      if (that.options.liveSearch) {\n        if (/(^9$|27)/.test(e.keyCode.toString(10)) && isActive) {\n          e.preventDefault();\n          e.stopPropagation();\n          that.$menuInner.click();\n          that.$button.focus();\n        }\n        // $items contains li elements when liveSearch is enabled\n        $items = $('[role=\"listbox\"] li' + selector, $parent);\n        if (!$this.val() && !/(38|40)/.test(e.keyCode.toString(10))) {\n          if ($items.filter('.active').length === 0) {\n            $items = that.$menuInner.find('li');\n            if (that.options.liveSearchNormalize) {\n              $items = $items.filter(':a' + that._searchStyle() + '(' + normalizeToBase(keyCodeMap[e.keyCode]) + ')');\n            } else {\n              $items = $items.filter(':' + that._searchStyle() + '(' + keyCodeMap[e.keyCode] + ')');\n            }\n          }\n        }\n      }\n\n      if (!$items.length) return;\n\n      if (/(38|40)/.test(e.keyCode.toString(10))) {\n        index = $items.index($items.find('a').filter(':focus').parent());\n        first = $items.filter(selector).first().index();\n        last = $items.filter(selector).last().index();\n        next = $items.eq(index).nextAll(selector).eq(0).index();\n        prev = $items.eq(index).prevAll(selector).eq(0).index();\n        nextPrev = $items.eq(next).prevAll(selector).eq(0).index();\n\n        if (that.options.liveSearch) {\n          $items.each(function (i) {\n            if (!$(this).hasClass('disabled')) {\n              $(this).data('index', i);\n            }\n          });\n          index = $items.index($items.filter('.active'));\n          first = $items.first().data('index');\n          last = $items.last().data('index');\n          next = $items.eq(index).nextAll().eq(0).data('index');\n          prev = $items.eq(index).prevAll().eq(0).data('index');\n          nextPrev = $items.eq(next).prevAll().eq(0).data('index');\n        }\n\n        prevIndex = $this.data('prevIndex');\n\n        if (e.keyCode == 38) {\n          if (that.options.liveSearch) index--;\n          if (index != nextPrev && index > prev) index = prev;\n          if (index < first) index = first;\n          if (index == prevIndex) index = last;\n        } else if (e.keyCode == 40) {\n          if (that.options.liveSearch) index++;\n          if (index == -1) index = 0;\n          if (index != nextPrev && index < next) index = next;\n          if (index > last) index = last;\n          if (index == prevIndex) index = first;\n        }\n\n        $this.data('prevIndex', index);\n\n        if (!that.options.liveSearch) {\n          $items.eq(index).children('a').focus();\n        } else {\n          e.preventDefault();\n          if (!$this.hasClass('dropdown-toggle')) {\n            $items.removeClass('active').eq(index).addClass('active').children('a').focus();\n            $this.focus();\n          }\n        }\n\n      } else if (!$this.is('input')) {\n        var keyIndex = [],\n            count,\n            prevKey;\n\n        $items.each(function () {\n          if (!$(this).hasClass('disabled')) {\n            if ($.trim($(this).children('a').text().toLowerCase()).substring(0, 1) == keyCodeMap[e.keyCode]) {\n              keyIndex.push($(this).index());\n            }\n          }\n        });\n\n        count = $(document).data('keycount');\n        count++;\n        $(document).data('keycount', count);\n\n        prevKey = $.trim($(':focus').text().toLowerCase()).substring(0, 1);\n\n        if (prevKey != keyCodeMap[e.keyCode]) {\n          count = 1;\n          $(document).data('keycount', count);\n        } else if (count >= keyIndex.length) {\n          $(document).data('keycount', 0);\n          if (count > keyIndex.length) count = 1;\n        }\n\n        $items.eq(keyIndex[count - 1]).children('a').focus();\n      }\n\n      // Select focused option if \"Enter\", \"Spacebar\" or \"Tab\" (when selectOnTab is true) are pressed inside the menu.\n      if ((/(13|32)/.test(e.keyCode.toString(10)) || (/(^9$)/.test(e.keyCode.toString(10)) && that.options.selectOnTab)) && isActive) {\n        if (!/(32)/.test(e.keyCode.toString(10))) e.preventDefault();\n        if (!that.options.liveSearch) {\n          var elem = $(':focus');\n          elem.click();\n          // Bring back focus for multiselects\n          elem.focus();\n          // Prevent screen from scrolling if the user hit the spacebar\n          e.preventDefault();\n          // Fixes spacebar selection of dropdown items in FF & IE\n          $(document).data('spaceSelect', true);\n        } else if (!/(32)/.test(e.keyCode.toString(10))) {\n          that.$menuInner.find('.active a').click();\n          $this.focus();\n        }\n        $(document).data('keycount', 0);\n      }\n\n      if ((/(^9$|27)/.test(e.keyCode.toString(10)) && isActive && (that.multiple || that.options.liveSearch)) || (/(27)/.test(e.keyCode.toString(10)) && !isActive)) {\n        that.$menu.parent().removeClass('open');\n        if (that.options.container) that.$newElement.removeClass('open');\n        that.$button.focus();\n      }\n    },\n\n    mobile: function () {\n      this.$element.addClass('mobile-device');\n    },\n\n    refresh: function () {\n      this.$lis = null;\n      this.liObj = {};\n      this.reloadLi();\n      this.render();\n      this.checkDisabled();\n      this.liHeight(true);\n      this.setStyle();\n      this.setWidth();\n      if (this.$lis) this.$searchbox.trigger('propertychange');\n\n      this.$element.trigger('refreshed.bs.select');\n    },\n\n    hide: function () {\n      this.$newElement.hide();\n    },\n\n    show: function () {\n      this.$newElement.show();\n    },\n\n    remove: function () {\n      this.$newElement.remove();\n      this.$element.remove();\n    },\n\n    destroy: function () {\n      this.$newElement.before(this.$element).remove();\n\n      if (this.$bsContainer) {\n        this.$bsContainer.remove();\n      } else {\n        this.$menu.remove();\n      }\n\n      this.$element\n        .off('.bs.select')\n        .removeData('selectpicker')\n        .removeClass('bs-select-hidden selectpicker');\n    }\n  };\n\n  // SELECTPICKER PLUGIN DEFINITION\n  // ==============================\n  function Plugin(option) {\n    // get the args of the outer function..\n    var args = arguments;\n    // The arguments of the function are explicitly re-defined from the argument list, because the shift causes them\n    // to get lost/corrupted in android 2.3 and IE9 #715 #775\n    var _option = option;\n\n    [].shift.apply(args);\n\n    var value;\n    var chain = this.each(function () {\n      var $this = $(this);\n      if ($this.is('select')) {\n        var data = $this.data('selectpicker'),\n            options = typeof _option == 'object' && _option;\n\n        if (!data) {\n          var config = $.extend({}, Selectpicker.DEFAULTS, $.fn.selectpicker.defaults || {}, $this.data(), options);\n          config.template = $.extend({}, Selectpicker.DEFAULTS.template, ($.fn.selectpicker.defaults ? $.fn.selectpicker.defaults.template : {}), $this.data().template, options.template);\n          $this.data('selectpicker', (data = new Selectpicker(this, config)));\n        } else if (options) {\n          for (var i in options) {\n            if (options.hasOwnProperty(i)) {\n              data.options[i] = options[i];\n            }\n          }\n        }\n\n        if (typeof _option == 'string') {\n          if (data[_option] instanceof Function) {\n            value = data[_option].apply(data, args);\n          } else {\n            value = data.options[_option];\n          }\n        }\n      }\n    });\n\n    if (typeof value !== 'undefined') {\n      //noinspection JSUnusedAssignment\n      return value;\n    } else {\n      return chain;\n    }\n  }\n\n  var old = $.fn.selectpicker;\n  $.fn.selectpicker = Plugin;\n  $.fn.selectpicker.Constructor = Selectpicker;\n\n  // SELECTPICKER NO CONFLICT\n  // ========================\n  $.fn.selectpicker.noConflict = function () {\n    $.fn.selectpicker = old;\n    return this;\n  };\n\n  $(document)\n      .data('keycount', 0)\n      .on('keydown.bs.select', '.bootstrap-select [data-toggle=dropdown], .bootstrap-select [role=\"listbox\"], .bs-searchbox input', Selectpicker.prototype.keydown)\n      .on('focusin.modal', '.bootstrap-select [data-toggle=dropdown], .bootstrap-select [role=\"listbox\"], .bs-searchbox input', function (e) {\n        e.stopPropagation();\n      });\n\n  // SELECTPICKER DATA-API\n  // =====================\n  $(window).on('load.bs.select.data-api', function () {\n    $('.selectpicker').each(function () {\n      var $selectpicker = $(this);\n      Plugin.call($selectpicker, $selectpicker.data());\n    })\n  });\n})(jQuery);\n\n\n}));\n"
  },
  {
    "path": "app_backend/static/plugin/bootstrap-select-1.12.2/dist/js/i18n/defaults-ar_AR.js",
    "content": "/*!\n * Bootstrap-select v1.12.2 (http://silviomoreto.github.io/bootstrap-select)\n *\n * Copyright 2013-2017 bootstrap-select\n * Licensed under MIT (https://github.com/silviomoreto/bootstrap-select/blob/master/LICENSE)\n */\n\n(function (root, factory) {\n  if (typeof define === 'function' && define.amd) {\n    // AMD. Register as an anonymous module unless amdModuleId is set\n    define([\"jquery\"], function (a0) {\n      return (factory(a0));\n    });\n  } else if (typeof module === 'object' && module.exports) {\n    // Node. Does not work with strict CommonJS, but\n    // only CommonJS-like environments that support module.exports,\n    // like Node.\n    module.exports = factory(require(\"jquery\"));\n  } else {\n    factory(root[\"jQuery\"]);\n  }\n}(this, function (jQuery) {\n\n/*!\n * Translated default messages for bootstrap-select.\n * Locale: AR (Arabic)\n * Author: Yasser Lotfy <y_l@alive.com>\n */\n(function ($) {\n  $.fn.selectpicker.defaults = {\n    noneSelectedText: 'لم يتم إختيار شئ',\n    noneResultsText: 'لا توجد نتائج مطابقة لـ {0}',\n    countSelectedText: function (numSelected, numTotal) {\n      return (numSelected == 1) ? \"{0} خيار تم إختياره\" : \"{0} خيارات تمت إختيارها\";\n    },\n    maxOptionsText: function (numAll, numGroup) {\n      return [\n        (numAll == 1) ? 'تخطى الحد المسموح ({n} خيار بحد أقصى)' : 'تخطى الحد المسموح ({n} خيارات بحد أقصى)',\n        (numGroup == 1) ? 'تخطى الحد المسموح للمجموعة ({n} خيار بحد أقصى)' : 'تخطى الحد المسموح للمجموعة ({n} خيارات بحد أقصى)'\n      ];\n    },\n    selectAllText: 'إختيار الجميع',\n    deselectAllText: 'إلغاء إختيار الجميع',\n    multipleSeparator: '، '\n  };\n})(jQuery);\n\n\n}));\n"
  },
  {
    "path": "app_backend/static/plugin/bootstrap-select-1.12.2/dist/js/i18n/defaults-bg_BG.js",
    "content": "/*!\n * Bootstrap-select v1.12.2 (http://silviomoreto.github.io/bootstrap-select)\n *\n * Copyright 2013-2017 bootstrap-select\n * Licensed under MIT (https://github.com/silviomoreto/bootstrap-select/blob/master/LICENSE)\n */\n\n(function (root, factory) {\n  if (typeof define === 'function' && define.amd) {\n    // AMD. Register as an anonymous module unless amdModuleId is set\n    define([\"jquery\"], function (a0) {\n      return (factory(a0));\n    });\n  } else if (typeof module === 'object' && module.exports) {\n    // Node. Does not work with strict CommonJS, but\n    // only CommonJS-like environments that support module.exports,\n    // like Node.\n    module.exports = factory(require(\"jquery\"));\n  } else {\n    factory(root[\"jQuery\"]);\n  }\n}(this, function (jQuery) {\n\n(function ($) {\n  $.fn.selectpicker.defaults = {\n    noneSelectedText: 'Нищо избрано',\n    noneResultsText: 'Няма резултат за {0}',\n    countSelectedText: function (numSelected, numTotal) {\n      return (numSelected == 1) ? \"{0} избран елемент\" : \"{0} избрани елемента\";\n    },\n    maxOptionsText: function (numAll, numGroup) {\n      return [\n        (numAll == 1) ? 'Лимита е достигнат ({n} елемент максимум)' : 'Лимита е достигнат ({n} елемента максимум)',\n        (numGroup == 1) ? 'Груповия лимит е достигнат ({n} елемент максимум)' : 'Груповия лимит е достигнат ({n} елемента максимум)'\n      ];\n    },\n    selectAllText: 'Избери всички',\n    deselectAllText: 'Размаркирай всички',\n    multipleSeparator: ', '\n  };\n})(jQuery);\n\n\n}));\n"
  },
  {
    "path": "app_backend/static/plugin/bootstrap-select-1.12.2/dist/js/i18n/defaults-cro_CRO.js",
    "content": "/*!\n * Bootstrap-select v1.12.2 (http://silviomoreto.github.io/bootstrap-select)\n *\n * Copyright 2013-2017 bootstrap-select\n * Licensed under MIT (https://github.com/silviomoreto/bootstrap-select/blob/master/LICENSE)\n */\n\n(function (root, factory) {\n  if (typeof define === 'function' && define.amd) {\n    // AMD. Register as an anonymous module unless amdModuleId is set\n    define([\"jquery\"], function (a0) {\n      return (factory(a0));\n    });\n  } else if (typeof module === 'object' && module.exports) {\n    // Node. Does not work with strict CommonJS, but\n    // only CommonJS-like environments that support module.exports,\n    // like Node.\n    module.exports = factory(require(\"jquery\"));\n  } else {\n    factory(root[\"jQuery\"]);\n  }\n}(this, function (jQuery) {\n\n(function ($) {\n  $.fn.selectpicker.defaults = {\n    noneSelectedText: 'Odaberite stavku',\n    noneResultsText: 'Nema rezultata pretrage {0}',\n    countSelectedText: function (numSelected, numTotal) {\n      return (numSelected == 1) ? \"{0} stavka selektirana\" : \"{0} stavke selektirane\";\n    },\n    maxOptionsText: function (numAll, numGroup) {\n      return [\n        (numAll == 1) ? 'Limit je postignut ({n} stvar maximalno)' : 'Limit je postignut ({n} stavke maksimalno)',\n        (numGroup == 1) ? 'Grupni limit je postignut ({n} stvar maksimalno)' : 'Grupni limit je postignut ({n} stavke maksimalno)'\n      ];\n    },\n    selectAllText: 'Selektiraj sve',\n    deselectAllText: 'Deselektiraj sve',\n    multipleSeparator: ', '\n  };\n})(jQuery);\n\n\n}));\n"
  },
  {
    "path": "app_backend/static/plugin/bootstrap-select-1.12.2/dist/js/i18n/defaults-cs_CZ.js",
    "content": "/*!\n * Bootstrap-select v1.12.2 (http://silviomoreto.github.io/bootstrap-select)\n *\n * Copyright 2013-2017 bootstrap-select\n * Licensed under MIT (https://github.com/silviomoreto/bootstrap-select/blob/master/LICENSE)\n */\n\n(function (root, factory) {\n  if (typeof define === 'function' && define.amd) {\n    // AMD. Register as an anonymous module unless amdModuleId is set\n    define([\"jquery\"], function (a0) {\n      return (factory(a0));\n    });\n  } else if (typeof module === 'object' && module.exports) {\n    // Node. Does not work with strict CommonJS, but\n    // only CommonJS-like environments that support module.exports,\n    // like Node.\n    module.exports = factory(require(\"jquery\"));\n  } else {\n    factory(root[\"jQuery\"]);\n  }\n}(this, function (jQuery) {\n\n(function ($) {\n  $.fn.selectpicker.defaults = {\n    noneSelectedText: 'Nic není vybráno',\n    noneResultsText: 'Žádné výsledky {0}',\n    countSelectedText: 'Označeno {0} z {1}',\n    maxOptionsText: ['Limit překročen ({n} {var} max)', 'Limit skupiny překročen ({n} {var} max)', ['položek', 'položka']],\n    multipleSeparator: ', '\n  };\n})(jQuery);\n\n\n}));\n"
  },
  {
    "path": "app_backend/static/plugin/bootstrap-select-1.12.2/dist/js/i18n/defaults-da_DK.js",
    "content": "/*!\n * Bootstrap-select v1.12.2 (http://silviomoreto.github.io/bootstrap-select)\n *\n * Copyright 2013-2017 bootstrap-select\n * Licensed under MIT (https://github.com/silviomoreto/bootstrap-select/blob/master/LICENSE)\n */\n\n(function (root, factory) {\n  if (typeof define === 'function' && define.amd) {\n    // AMD. Register as an anonymous module unless amdModuleId is set\n    define([\"jquery\"], function (a0) {\n      return (factory(a0));\n    });\n  } else if (typeof module === 'object' && module.exports) {\n    // Node. Does not work with strict CommonJS, but\n    // only CommonJS-like environments that support module.exports,\n    // like Node.\n    module.exports = factory(require(\"jquery\"));\n  } else {\n    factory(root[\"jQuery\"]);\n  }\n}(this, function (jQuery) {\n\n(function ($) {\n  $.fn.selectpicker.defaults = {\n    noneSelectedText: 'Intet valgt',\n    noneResultsText: 'Ingen resultater fundet {0}',\n    countSelectedText: function (numSelected, numTotal) {\n      return (numSelected == 1) ? \"{0} valgt\" : \"{0} valgt\";\n    },\n    maxOptionsText: function (numAll, numGroup) {\n      return [\n        (numAll == 1) ? 'Begrænsning nået (max {n} valgt)' : 'Begrænsning nået (max {n} valgte)',\n        (numGroup == 1) ? 'Gruppe-begrænsning nået (max {n} valgt)' : 'Gruppe-begrænsning nået (max {n} valgte)'\n      ];\n    },\n    selectAllText: 'Markér alle',\n    deselectAllText: 'Afmarkér alle',\n    multipleSeparator: ', '\n  };\n})(jQuery);\n\n\n}));\n"
  },
  {
    "path": "app_backend/static/plugin/bootstrap-select-1.12.2/dist/js/i18n/defaults-de_DE.js",
    "content": "/*!\n * Bootstrap-select v1.12.2 (http://silviomoreto.github.io/bootstrap-select)\n *\n * Copyright 2013-2017 bootstrap-select\n * Licensed under MIT (https://github.com/silviomoreto/bootstrap-select/blob/master/LICENSE)\n */\n\n(function (root, factory) {\n  if (typeof define === 'function' && define.amd) {\n    // AMD. Register as an anonymous module unless amdModuleId is set\n    define([\"jquery\"], function (a0) {\n      return (factory(a0));\n    });\n  } else if (typeof module === 'object' && module.exports) {\n    // Node. Does not work with strict CommonJS, but\n    // only CommonJS-like environments that support module.exports,\n    // like Node.\n    module.exports = factory(require(\"jquery\"));\n  } else {\n    factory(root[\"jQuery\"]);\n  }\n}(this, function (jQuery) {\n\n(function ($) {\n  $.fn.selectpicker.defaults = {\n    noneSelectedText: 'Bitte wählen...',\n    noneResultsText: 'Keine Ergebnisse für {0}',\n    countSelectedText: function (numSelected, numTotal) {\n      return (numSelected == 1) ? \"{0} Element ausgewählt\" : \"{0} Elemente ausgewählt\";\n    },\n    maxOptionsText: function (numAll, numGroup) {\n      return [\n        (numAll == 1) ? 'Limit erreicht ({n} Element max.)' : 'Limit erreicht ({n} Elemente max.)',\n        (numGroup == 1) ? 'Gruppen-Limit erreicht ({n} Element max.)' : 'Gruppen-Limit erreicht ({n} Elemente max.)'\n      ];\n    },\n    selectAllText: 'Alles auswählen',\n    deselectAllText: 'Nichts auswählen',\n    multipleSeparator: ', '\n  };\n})(jQuery);\n\n\n}));\n"
  },
  {
    "path": "app_backend/static/plugin/bootstrap-select-1.12.2/dist/js/i18n/defaults-en_US.js",
    "content": "/*!\n * Bootstrap-select v1.12.2 (http://silviomoreto.github.io/bootstrap-select)\n *\n * Copyright 2013-2017 bootstrap-select\n * Licensed under MIT (https://github.com/silviomoreto/bootstrap-select/blob/master/LICENSE)\n */\n\n(function (root, factory) {\n  if (typeof define === 'function' && define.amd) {\n    // AMD. Register as an anonymous module unless amdModuleId is set\n    define([\"jquery\"], function (a0) {\n      return (factory(a0));\n    });\n  } else if (typeof module === 'object' && module.exports) {\n    // Node. Does not work with strict CommonJS, but\n    // only CommonJS-like environments that support module.exports,\n    // like Node.\n    module.exports = factory(require(\"jquery\"));\n  } else {\n    factory(root[\"jQuery\"]);\n  }\n}(this, function (jQuery) {\n\n(function ($) {\n  $.fn.selectpicker.defaults = {\n    noneSelectedText: 'Nothing selected',\n    noneResultsText: 'No results match {0}',\n    countSelectedText: function (numSelected, numTotal) {\n      return (numSelected == 1) ? \"{0} item selected\" : \"{0} items selected\";\n    },\n    maxOptionsText: function (numAll, numGroup) {\n      return [\n        (numAll == 1) ? 'Limit reached ({n} item max)' : 'Limit reached ({n} items max)',\n        (numGroup == 1) ? 'Group limit reached ({n} item max)' : 'Group limit reached ({n} items max)'\n      ];\n    },\n    selectAllText: 'Select All',\n    deselectAllText: 'Deselect All',\n    multipleSeparator: ', '\n  };\n})(jQuery);\n\n\n}));\n"
  },
  {
    "path": "app_backend/static/plugin/bootstrap-select-1.12.2/dist/js/i18n/defaults-es_CL.js",
    "content": "/*!\n * Bootstrap-select v1.12.2 (http://silviomoreto.github.io/bootstrap-select)\n *\n * Copyright 2013-2017 bootstrap-select\n * Licensed under MIT (https://github.com/silviomoreto/bootstrap-select/blob/master/LICENSE)\n */\n\n(function (root, factory) {\n  if (typeof define === 'function' && define.amd) {\n    // AMD. Register as an anonymous module unless amdModuleId is set\n    define([\"jquery\"], function (a0) {\n      return (factory(a0));\n    });\n  } else if (typeof module === 'object' && module.exports) {\n    // Node. Does not work with strict CommonJS, but\n    // only CommonJS-like environments that support module.exports,\n    // like Node.\n    module.exports = factory(require(\"jquery\"));\n  } else {\n    factory(root[\"jQuery\"]);\n  }\n}(this, function (jQuery) {\n\n(function ($) {\n  $.fn.selectpicker.defaults = {\n    noneSelectedText: 'No hay selección',\n    noneResultsText: 'No hay resultados {0}',\n    countSelectedText: 'Seleccionados {0} de {1}',\n    maxOptionsText: ['Límite alcanzado ({n} {var} max)', 'Límite del grupo alcanzado({n} {var} max)', ['elementos', 'element']],\n    multipleSeparator: ', ',\n    selectAllText: 'Seleccionar Todos',\n    deselectAllText: 'Desmarcar Todos'\n  };\n})(jQuery);\n\n\n}));\n"
  },
  {
    "path": "app_backend/static/plugin/bootstrap-select-1.12.2/dist/js/i18n/defaults-es_ES.js",
    "content": "/*!\n * Bootstrap-select v1.12.2 (http://silviomoreto.github.io/bootstrap-select)\n *\n * Copyright 2013-2017 bootstrap-select\n * Licensed under MIT (https://github.com/silviomoreto/bootstrap-select/blob/master/LICENSE)\n */\n\n(function (root, factory) {\n  if (typeof define === 'function' && define.amd) {\n    // AMD. Register as an anonymous module unless amdModuleId is set\n    define([\"jquery\"], function (a0) {\n      return (factory(a0));\n    });\n  } else if (typeof module === 'object' && module.exports) {\n    // Node. Does not work with strict CommonJS, but\n    // only CommonJS-like environments that support module.exports,\n    // like Node.\n    module.exports = factory(require(\"jquery\"));\n  } else {\n    factory(root[\"jQuery\"]);\n  }\n}(this, function (jQuery) {\n\n(function ($) {\n  $.fn.selectpicker.defaults = {\n    noneSelectedText: 'No hay selección',\n    noneResultsText: 'No hay resultados {0}',\n    countSelectedText: 'Seleccionados {0} de {1}',\n    maxOptionsText: ['Límite alcanzado ({n} {var} max)', 'Límite del grupo alcanzado({n} {var} max)', ['elementos', 'element']],\n    multipleSeparator: ', ',\n    selectAllText: 'Seleccionar Todos',\n    deselectAllText: 'Desmarcar Todos'\n  };\n})(jQuery);\n\n\n}));\n"
  },
  {
    "path": "app_backend/static/plugin/bootstrap-select-1.12.2/dist/js/i18n/defaults-eu.js",
    "content": "/*!\n * Bootstrap-select v1.12.2 (http://silviomoreto.github.io/bootstrap-select)\n *\n * Copyright 2013-2017 bootstrap-select\n * Licensed under MIT (https://github.com/silviomoreto/bootstrap-select/blob/master/LICENSE)\n */\n\n(function (root, factory) {\n  if (typeof define === 'function' && define.amd) {\n    // AMD. Register as an anonymous module unless amdModuleId is set\n    define([\"jquery\"], function (a0) {\n      return (factory(a0));\n    });\n  } else if (typeof module === 'object' && module.exports) {\n    // Node. Does not work with strict CommonJS, but\n    // only CommonJS-like environments that support module.exports,\n    // like Node.\n    module.exports = factory(require(\"jquery\"));\n  } else {\n    factory(root[\"jQuery\"]);\n  }\n}(this, function (jQuery) {\n\n(function ($) {\n  $.fn.selectpicker.defaults = {\n    noneSelectedText: 'Hautapenik ez',\n    noneResultsText: 'Emaitzarik ez {0}',\n    countSelectedText: '{1}(e)tik {0} hautatuta',\n    maxOptionsText: ['Mugara iritsita ({n} {var} gehienez)', 'Taldearen mugara iritsita ({n} {var} gehienez)', ['elementu', 'elementu']],\n    multipleSeparator: ', '\n  };\n})(jQuery);\n\n\n}));\n"
  },
  {
    "path": "app_backend/static/plugin/bootstrap-select-1.12.2/dist/js/i18n/defaults-fa_IR.js",
    "content": "/*!\n * Bootstrap-select v1.12.2 (http://silviomoreto.github.io/bootstrap-select)\n *\n * Copyright 2013-2017 bootstrap-select\n * Licensed under MIT (https://github.com/silviomoreto/bootstrap-select/blob/master/LICENSE)\n */\n\n(function (root, factory) {\n  if (typeof define === 'function' && define.amd) {\n    // AMD. Register as an anonymous module unless amdModuleId is set\n    define([\"jquery\"], function (a0) {\n      return (factory(a0));\n    });\n  } else if (typeof module === 'object' && module.exports) {\n    // Node. Does not work with strict CommonJS, but\n    // only CommonJS-like environments that support module.exports,\n    // like Node.\n    module.exports = factory(require(\"jquery\"));\n  } else {\n    factory(root[\"jQuery\"]);\n  }\n}(this, function (jQuery) {\n\n(function ($) {\n    $.fn.selectpicker.defaults = {\n        noneSelectedText: 'چیزی انتخاب نشده است',\n        noneResultsText: 'هیج مشابهی برای {0} پیدا نشد',\n        countSelectedText: \"{0} از {1} مورد انتخاب شده\",\n        maxOptionsText: ['بیشتر ممکن نیست {حداکثر {n} عدد}', 'بیشتر ممکن نیست {حداکثر {n} عدد}'],\n        selectAllText: 'انتخاب همه',\n        deselectAllText: 'انتخاب هیچ کدام',\n        multipleSeparator: ', '\n    };\n})(jQuery);\n\n\n}));\n"
  },
  {
    "path": "app_backend/static/plugin/bootstrap-select-1.12.2/dist/js/i18n/defaults-fi_FI.js",
    "content": "/*!\n * Bootstrap-select v1.12.2 (http://silviomoreto.github.io/bootstrap-select)\n *\n * Copyright 2013-2017 bootstrap-select\n * Licensed under MIT (https://github.com/silviomoreto/bootstrap-select/blob/master/LICENSE)\n */\n\n(function (root, factory) {\n  if (typeof define === 'function' && define.amd) {\n    // AMD. Register as an anonymous module unless amdModuleId is set\n    define([\"jquery\"], function (a0) {\n      return (factory(a0));\n    });\n  } else if (typeof module === 'object' && module.exports) {\n    // Node. Does not work with strict CommonJS, but\n    // only CommonJS-like environments that support module.exports,\n    // like Node.\n    module.exports = factory(require(\"jquery\"));\n  } else {\n    factory(root[\"jQuery\"]);\n  }\n}(this, function (jQuery) {\n\n(function ($) {\n  $.fn.selectpicker.defaults = {\n    noneSelectedText: 'Ei valintoja',\n    noneResultsText: 'Ei hakutuloksia {0}',\n    countSelectedText: function (numSelected, numTotal) {\n      return (numSelected == 1) ? \"{0} valittu\" : \"{0} valitut\";\n    },\n    maxOptionsText: function (numAll, numGroup) {\n      return [\n        (numAll == 1) ? 'Valintojen maksimimäärä ({n} saavutettu)' : 'Valintojen maksimimäärä ({n} saavutettu)',\n        (numGroup == 1) ? 'Ryhmän maksimimäärä ({n} saavutettu)' : 'Ryhmän maksimimäärä ({n} saavutettu)'\n      ];\n    },\n    selectAllText: 'Valitse kaikki',\n    deselectAllText: 'Poista kaikki',\n    multipleSeparator: ', '\n  };\n})(jQuery);\n\n\n}));\n"
  },
  {
    "path": "app_backend/static/plugin/bootstrap-select-1.12.2/dist/js/i18n/defaults-fr_FR.js",
    "content": "/*!\n * Bootstrap-select v1.12.2 (http://silviomoreto.github.io/bootstrap-select)\n *\n * Copyright 2013-2017 bootstrap-select\n * Licensed under MIT (https://github.com/silviomoreto/bootstrap-select/blob/master/LICENSE)\n */\n\n(function (root, factory) {\n  if (typeof define === 'function' && define.amd) {\n    // AMD. Register as an anonymous module unless amdModuleId is set\n    define([\"jquery\"], function (a0) {\n      return (factory(a0));\n    });\n  } else if (typeof module === 'object' && module.exports) {\n    // Node. Does not work with strict CommonJS, but\n    // only CommonJS-like environments that support module.exports,\n    // like Node.\n    module.exports = factory(require(\"jquery\"));\n  } else {\n    factory(root[\"jQuery\"]);\n  }\n}(this, function (jQuery) {\n\n(function ($) {\n  $.fn.selectpicker.defaults = {\n    noneSelectedText: 'Aucune sélection',\n    noneResultsText: 'Aucun résultat pour {0}',\n    countSelectedText: function (numSelected, numTotal) {\n      return (numSelected > 1) ? \"{0} éléments sélectionnés\" : \"{0} élément sélectionné\";\n    },\n    maxOptionsText: function (numAll, numGroup) {\n      return [\n        (numAll > 1) ? 'Limite atteinte ({n} éléments max)' : 'Limite atteinte ({n} élément max)',\n        (numGroup > 1) ? 'Limite du groupe atteinte ({n} éléments max)' : 'Limite du groupe atteinte ({n} élément max)'\n      ];\n    },\n    multipleSeparator: ', ',\n    selectAllText: 'Tout Sélectionner',\n    deselectAllText: 'Tout Dé-selectionner',\n  };\n})(jQuery);\n\n\n}));\n"
  },
  {
    "path": "app_backend/static/plugin/bootstrap-select-1.12.2/dist/js/i18n/defaults-hu_HU.js",
    "content": "/*!\n * Bootstrap-select v1.12.2 (http://silviomoreto.github.io/bootstrap-select)\n *\n * Copyright 2013-2017 bootstrap-select\n * Licensed under MIT (https://github.com/silviomoreto/bootstrap-select/blob/master/LICENSE)\n */\n\n(function (root, factory) {\n  if (typeof define === 'function' && define.amd) {\n    // AMD. Register as an anonymous module unless amdModuleId is set\n    define([\"jquery\"], function (a0) {\n      return (factory(a0));\n    });\n  } else if (typeof module === 'object' && module.exports) {\n    // Node. Does not work with strict CommonJS, but\n    // only CommonJS-like environments that support module.exports,\n    // like Node.\n    module.exports = factory(require(\"jquery\"));\n  } else {\n    factory(root[\"jQuery\"]);\n  }\n}(this, function (jQuery) {\n\n(function ($) {\n  $.fn.selectpicker.defaults = {\n    noneSelectedText: 'Válasszon!',\n    noneResultsText: 'Nincs találat {0}',\n    countSelectedText: function (numSelected, numTotal) {\n      return '{0} elem kiválasztva';\n    },\n    maxOptionsText: function (numAll, numGroup) {\n      return [\n        'Legfeljebb {n} elem választható',\n        'A csoportban legfeljebb {n} elem választható'\n      ];\n    },\n    selectAllText: 'Mind',\n    deselectAllText: 'Egyik sem',\n    multipleSeparator: ', '\n  };\n})(jQuery);\n\n\n}));\n"
  },
  {
    "path": "app_backend/static/plugin/bootstrap-select-1.12.2/dist/js/i18n/defaults-id_ID.js",
    "content": "/*!\n * Bootstrap-select v1.12.2 (http://silviomoreto.github.io/bootstrap-select)\n *\n * Copyright 2013-2017 bootstrap-select\n * Licensed under MIT (https://github.com/silviomoreto/bootstrap-select/blob/master/LICENSE)\n */\n\n(function (root, factory) {\n  if (typeof define === 'function' && define.amd) {\n    // AMD. Register as an anonymous module unless amdModuleId is set\n    define([\"jquery\"], function (a0) {\n      return (factory(a0));\n    });\n  } else if (typeof module === 'object' && module.exports) {\n    // Node. Does not work with strict CommonJS, but\n    // only CommonJS-like environments that support module.exports,\n    // like Node.\n    module.exports = factory(require(\"jquery\"));\n  } else {\n    factory(root[\"jQuery\"]);\n  }\n}(this, function (jQuery) {\n\n(function ($) {\n  $.fn.selectpicker.defaults = {\n    noneSelectedText: 'Tidak ada yang dipilih',\n    noneResultsText: 'Tidak ada yang cocok {0}',\n    countSelectedText: '{0} terpilih',\n    maxOptionsText: ['Mencapai batas (maksimum {n})', 'Mencapai batas grup (maksimum {n})'],\n    selectAllText: 'Pilih Semua',\n    deselectAllText: 'Hapus Semua',\n    multipleSeparator: ', '\n  };\n})(jQuery);\n\n\n}));\n"
  },
  {
    "path": "app_backend/static/plugin/bootstrap-select-1.12.2/dist/js/i18n/defaults-it_IT.js",
    "content": "/*!\n * Bootstrap-select v1.12.2 (http://silviomoreto.github.io/bootstrap-select)\n *\n * Copyright 2013-2017 bootstrap-select\n * Licensed under MIT (https://github.com/silviomoreto/bootstrap-select/blob/master/LICENSE)\n */\n\n(function (root, factory) {\n  if (typeof define === 'function' && define.amd) {\n    // AMD. Register as an anonymous module unless amdModuleId is set\n    define([\"jquery\"], function (a0) {\n      return (factory(a0));\n    });\n  } else if (typeof module === 'object' && module.exports) {\n    // Node. Does not work with strict CommonJS, but\n    // only CommonJS-like environments that support module.exports,\n    // like Node.\n    module.exports = factory(require(\"jquery\"));\n  } else {\n    factory(root[\"jQuery\"]);\n  }\n}(this, function (jQuery) {\n\n(function ($) {\n  $.fn.selectpicker.defaults = {\n    noneSelectedText: 'Nessuna selezione',\n    noneResultsText: 'Nessun risultato per {0}',\n    countSelectedText: function (numSelected, numTotal){\n      return (numSelected == 1) ? 'Selezionato {0} di {1}' : 'Selezionati {0} di {1}';\n    },\n    maxOptionsText: ['Limite raggiunto ({n} {var} max)', 'Limite del gruppo raggiunto ({n} {var} max)', ['elementi', 'elemento']],\n    multipleSeparator: ', ',\n    selectAllText: 'Seleziona Tutto',\n    deselectAllText: 'Deseleziona Tutto'\n  };\n})(jQuery);\n\n\n}));\n"
  },
  {
    "path": "app_backend/static/plugin/bootstrap-select-1.12.2/dist/js/i18n/defaults-ko_KR.js",
    "content": "/*!\n * Bootstrap-select v1.12.2 (http://silviomoreto.github.io/bootstrap-select)\n *\n * Copyright 2013-2017 bootstrap-select\n * Licensed under MIT (https://github.com/silviomoreto/bootstrap-select/blob/master/LICENSE)\n */\n\n(function (root, factory) {\n  if (typeof define === 'function' && define.amd) {\n    // AMD. Register as an anonymous module unless amdModuleId is set\n    define([\"jquery\"], function (a0) {\n      return (factory(a0));\n    });\n  } else if (typeof module === 'object' && module.exports) {\n    // Node. Does not work with strict CommonJS, but\n    // only CommonJS-like environments that support module.exports,\n    // like Node.\n    module.exports = factory(require(\"jquery\"));\n  } else {\n    factory(root[\"jQuery\"]);\n  }\n}(this, function (jQuery) {\n\n(function ($) {\n  $.fn.selectpicker.defaults = {\n    noneSelectedText: '항목을 선택해주세요',\n    noneResultsText: '{0} 검색 결과가 없습니다',\n    countSelectedText: function (numSelected, numTotal) {\n      return \"{0}개를 선택하였습니다\";\n    },\n    maxOptionsText: function (numAll, numGroup) {\n      return [\n        '{n}개까지 선택 가능합니다',\n        '해당 그룹은 {n}개까지 선택 가능합니다'\n      ];\n    },\n    selectAllText: '전체선택',\n    deselectAllText: '전체해제',\n    multipleSeparator: ', '\n  };\n})(jQuery);\n\n\n}));\n"
  },
  {
    "path": "app_backend/static/plugin/bootstrap-select-1.12.2/dist/js/i18n/defaults-lt_LT.js",
    "content": "/*!\n * Bootstrap-select v1.12.2 (http://silviomoreto.github.io/bootstrap-select)\n *\n * Copyright 2013-2017 bootstrap-select\n * Licensed under MIT (https://github.com/silviomoreto/bootstrap-select/blob/master/LICENSE)\n */\n\n(function (root, factory) {\n  if (typeof define === 'function' && define.amd) {\n    // AMD. Register as an anonymous module unless amdModuleId is set\n    define([\"jquery\"], function (a0) {\n      return (factory(a0));\n    });\n  } else if (typeof module === 'object' && module.exports) {\n    // Node. Does not work with strict CommonJS, but\n    // only CommonJS-like environments that support module.exports,\n    // like Node.\n    module.exports = factory(require(\"jquery\"));\n  } else {\n    factory(root[\"jQuery\"]);\n  }\n}(this, function (jQuery) {\n\n(function ($) {\n  $.fn.selectpicker.defaults = {\n    noneSelectedText: 'Niekas nepasirinkta',\n    noneResultsText: 'Niekas nesutapo su {0}',\n    countSelectedText: function (numSelected, numTotal) {\n      return (numSelected == 1) ? \"{0} elementas pasirinktas\" : \"{0} elementai(-ų) pasirinkta\";\n    },\n    maxOptionsText: function (numAll, numGroup) {\n      return [\n        (numAll == 1) ? 'Pasiekta riba ({n} elementas daugiausiai)' : 'Riba pasiekta ({n} elementai(-ų) daugiausiai)',\n        (numGroup == 1) ? 'Grupės riba pasiekta ({n} elementas daugiausiai)' : 'Grupės riba pasiekta ({n} elementai(-ų) daugiausiai)'\n      ];\n    },\n    selectAllText: 'Pasirinkti visus',\n    deselectAllText: 'Atmesti visus',\n    multipleSeparator: ', '\n  };\n})(jQuery);\n\n\n}));\n"
  },
  {
    "path": "app_backend/static/plugin/bootstrap-select-1.12.2/dist/js/i18n/defaults-nb_NO.js",
    "content": "/*!\n * Bootstrap-select v1.12.2 (http://silviomoreto.github.io/bootstrap-select)\n *\n * Copyright 2013-2017 bootstrap-select\n * Licensed under MIT (https://github.com/silviomoreto/bootstrap-select/blob/master/LICENSE)\n */\n\n(function (root, factory) {\n  if (typeof define === 'function' && define.amd) {\n    // AMD. Register as an anonymous module unless amdModuleId is set\n    define([\"jquery\"], function (a0) {\n      return (factory(a0));\n    });\n  } else if (typeof module === 'object' && module.exports) {\n    // Node. Does not work with strict CommonJS, but\n    // only CommonJS-like environments that support module.exports,\n    // like Node.\n    module.exports = factory(require(\"jquery\"));\n  } else {\n    factory(root[\"jQuery\"]);\n  }\n}(this, function (jQuery) {\n\n(function ($) {\n  $.fn.selectpicker.defaults = {\n    noneSelectedText: 'Ingen valgt',\n    noneResultsText: 'Søket gir ingen treff {0}',\n    countSelectedText: function (numSelected, numTotal) {\n      return (numSelected == 1) ? \"{0} alternativ valgt\" : \"{0} alternativer valgt\";\n    },\n    maxOptionsText: function (numAll, numGroup) {\n      return [\n        (numAll == 1) ? 'Grense nådd (maks {n} valg)' : 'Grense nådd (maks {n} valg)',\n        (numGroup == 1) ? 'Grense for grupper nådd (maks {n} grupper)' : 'Grense for grupper nådd (maks {n} grupper)'\n      ];\n    },\n    selectAllText: 'Merk alle',\n    deselectAllText: 'Fjern alle',\n    multipleSeparator: ', '\n  };\n})(jQuery);\n\n\n}));\n"
  },
  {
    "path": "app_backend/static/plugin/bootstrap-select-1.12.2/dist/js/i18n/defaults-nl_NL.js",
    "content": "/*!\n * Bootstrap-select v1.12.2 (http://silviomoreto.github.io/bootstrap-select)\n *\n * Copyright 2013-2017 bootstrap-select\n * Licensed under MIT (https://github.com/silviomoreto/bootstrap-select/blob/master/LICENSE)\n */\n\n(function (root, factory) {\n  if (typeof define === 'function' && define.amd) {\n    // AMD. Register as an anonymous module unless amdModuleId is set\n    define([\"jquery\"], function (a0) {\n      return (factory(a0));\n    });\n  } else if (typeof module === 'object' && module.exports) {\n    // Node. Does not work with strict CommonJS, but\n    // only CommonJS-like environments that support module.exports,\n    // like Node.\n    module.exports = factory(require(\"jquery\"));\n  } else {\n    factory(root[\"jQuery\"]);\n  }\n}(this, function (jQuery) {\n\n(function ($) {\n  $.fn.selectpicker.defaults = {\n    noneSelectedText: 'Niets geselecteerd',\n    noneResultsText: 'Geen resultaten gevonden voor {0}',\n    countSelectedText: '{0} van {1} geselecteerd',\n    maxOptionsText: ['Limiet bereikt ({n} {var} max)', 'Groep limiet bereikt ({n} {var} max)', ['items', 'item']],\n    multipleSeparator: ', '\n  };\n})(jQuery);\n\n\n}));\n"
  },
  {
    "path": "app_backend/static/plugin/bootstrap-select-1.12.2/dist/js/i18n/defaults-pl_PL.js",
    "content": "/*!\n * Bootstrap-select v1.12.2 (http://silviomoreto.github.io/bootstrap-select)\n *\n * Copyright 2013-2017 bootstrap-select\n * Licensed under MIT (https://github.com/silviomoreto/bootstrap-select/blob/master/LICENSE)\n */\n\n(function (root, factory) {\n  if (typeof define === 'function' && define.amd) {\n    // AMD. Register as an anonymous module unless amdModuleId is set\n    define([\"jquery\"], function (a0) {\n      return (factory(a0));\n    });\n  } else if (typeof module === 'object' && module.exports) {\n    // Node. Does not work with strict CommonJS, but\n    // only CommonJS-like environments that support module.exports,\n    // like Node.\n    module.exports = factory(require(\"jquery\"));\n  } else {\n    factory(root[\"jQuery\"]);\n  }\n}(this, function (jQuery) {\n\n(function ($) {\n  $.fn.selectpicker.defaults = {\n    noneSelectedText: 'Nic nie zaznaczono',\n    noneResultsText: 'Brak wyników wyszukiwania {0}',\n    countSelectedText: 'Zaznaczono {0} z {1}',\n    maxOptionsText: ['Osiągnięto limit ({n} {var} max)', 'Limit grupy osiągnięty ({n} {var} max)', ['elementy', 'element']],\n    selectAll: 'Zaznacz wszystkie',\n    deselectAll: 'Odznacz wszystkie',\n    multipleSeparator: ', '\n  };\n})(jQuery);\n\n\n}));\n"
  },
  {
    "path": "app_backend/static/plugin/bootstrap-select-1.12.2/dist/js/i18n/defaults-pt_BR.js",
    "content": "/*!\n * Bootstrap-select v1.12.2 (http://silviomoreto.github.io/bootstrap-select)\n *\n * Copyright 2013-2017 bootstrap-select\n * Licensed under MIT (https://github.com/silviomoreto/bootstrap-select/blob/master/LICENSE)\n */\n\n(function (root, factory) {\n  if (typeof define === 'function' && define.amd) {\n    // AMD. Register as an anonymous module unless amdModuleId is set\n    define([\"jquery\"], function (a0) {\n      return (factory(a0));\n    });\n  } else if (typeof module === 'object' && module.exports) {\n    // Node. Does not work with strict CommonJS, but\n    // only CommonJS-like environments that support module.exports,\n    // like Node.\n    module.exports = factory(require(\"jquery\"));\n  } else {\n    factory(root[\"jQuery\"]);\n  }\n}(this, function (jQuery) {\n\n(function ($) {\n  $.fn.selectpicker.defaults = {\n    noneSelectedText: 'Nada selecionado',\n    noneResultsText: 'Nada encontrado contendo {0}',\n    countSelectedText: 'Selecionado {0} de {1}',\n    maxOptionsText: ['Limite excedido (máx. {n} {var})', 'Limite do grupo excedido (máx. {n} {var})', ['itens', 'item']],\n    multipleSeparator: ', '\n  };\n})(jQuery);\n\n\n}));\n"
  },
  {
    "path": "app_backend/static/plugin/bootstrap-select-1.12.2/dist/js/i18n/defaults-pt_PT.js",
    "content": "/*!\n * Bootstrap-select v1.12.2 (http://silviomoreto.github.io/bootstrap-select)\n *\n * Copyright 2013-2017 bootstrap-select\n * Licensed under MIT (https://github.com/silviomoreto/bootstrap-select/blob/master/LICENSE)\n */\n\n(function (root, factory) {\n  if (typeof define === 'function' && define.amd) {\n    // AMD. Register as an anonymous module unless amdModuleId is set\n    define([\"jquery\"], function (a0) {\n      return (factory(a0));\n    });\n  } else if (typeof module === 'object' && module.exports) {\n    // Node. Does not work with strict CommonJS, but\n    // only CommonJS-like environments that support module.exports,\n    // like Node.\n    module.exports = factory(require(\"jquery\"));\n  } else {\n    factory(root[\"jQuery\"]);\n  }\n}(this, function (jQuery) {\n\n(function ($) {\n$.fn.selectpicker.defaults = {\nnoneSelectedText: 'Nenhum seleccionado',\nnoneResultsText: 'Sem resultados contendo {0}',\ncountSelectedText: 'Selecionado {0} de {1}',\nmaxOptionsText: ['Limite ultrapassado (máx. {n} {var})', 'Limite de seleções ultrapassado (máx. {n} {var})', ['itens', 'item']],\nmultipleSeparator: ', '\n};\n})(jQuery);\n\n\n}));\n"
  },
  {
    "path": "app_backend/static/plugin/bootstrap-select-1.12.2/dist/js/i18n/defaults-ro_RO.js",
    "content": "/*!\n * Bootstrap-select v1.12.2 (http://silviomoreto.github.io/bootstrap-select)\n *\n * Copyright 2013-2017 bootstrap-select\n * Licensed under MIT (https://github.com/silviomoreto/bootstrap-select/blob/master/LICENSE)\n */\n\n(function (root, factory) {\n  if (typeof define === 'function' && define.amd) {\n    // AMD. Register as an anonymous module unless amdModuleId is set\n    define([\"jquery\"], function (a0) {\n      return (factory(a0));\n    });\n  } else if (typeof module === 'object' && module.exports) {\n    // Node. Does not work with strict CommonJS, but\n    // only CommonJS-like environments that support module.exports,\n    // like Node.\n    module.exports = factory(require(\"jquery\"));\n  } else {\n    factory(root[\"jQuery\"]);\n  }\n}(this, function (jQuery) {\n\n(function ($) {\n  $.fn.selectpicker.defaults = {\n    noneSelectedText: 'Nu a fost selectat nimic',\n    noneResultsText: 'Nu exista niciun rezultat {0}',\n    countSelectedText: '{0} din {1} selectat(e)',\n    maxOptionsText: ['Limita a fost atinsa ({n} {var} max)', 'Limita de grup a fost atinsa ({n} {var} max)', ['iteme', 'item']],\n    multipleSeparator: ', '\n  };\n})(jQuery);\n\n\n}));\n"
  },
  {
    "path": "app_backend/static/plugin/bootstrap-select-1.12.2/dist/js/i18n/defaults-ru_RU.js",
    "content": "/*!\n * Bootstrap-select v1.12.2 (http://silviomoreto.github.io/bootstrap-select)\n *\n * Copyright 2013-2017 bootstrap-select\n * Licensed under MIT (https://github.com/silviomoreto/bootstrap-select/blob/master/LICENSE)\n */\n\n(function (root, factory) {\n  if (typeof define === 'function' && define.amd) {\n    // AMD. Register as an anonymous module unless amdModuleId is set\n    define([\"jquery\"], function (a0) {\n      return (factory(a0));\n    });\n  } else if (typeof module === 'object' && module.exports) {\n    // Node. Does not work with strict CommonJS, but\n    // only CommonJS-like environments that support module.exports,\n    // like Node.\n    module.exports = factory(require(\"jquery\"));\n  } else {\n    factory(root[\"jQuery\"]);\n  }\n}(this, function (jQuery) {\n\n(function ($) {\n  $.fn.selectpicker.defaults = {\n    noneSelectedText: 'Ничего не выбрано',\n    noneResultsText: 'Совпадений не найдено {0}',\n    countSelectedText: 'Выбрано {0} из {1}',\n    maxOptionsText: ['Достигнут предел ({n} {var} максимум)', 'Достигнут предел в группе ({n} {var} максимум)', ['шт.', 'шт.']],\n    doneButtonText: 'Закрыть',\n    selectAllText: 'Выбрать все',\n    deselectAllText: 'Отменить все',    \n    multipleSeparator: ', '\n  };\n})(jQuery);\n\n\n}));\n"
  },
  {
    "path": "app_backend/static/plugin/bootstrap-select-1.12.2/dist/js/i18n/defaults-sk_SK.js",
    "content": "/*!\n * Bootstrap-select v1.12.2 (http://silviomoreto.github.io/bootstrap-select)\n *\n * Copyright 2013-2017 bootstrap-select\n * Licensed under MIT (https://github.com/silviomoreto/bootstrap-select/blob/master/LICENSE)\n */\n\n(function (root, factory) {\n  if (typeof define === 'function' && define.amd) {\n    // AMD. Register as an anonymous module unless amdModuleId is set\n    define([\"jquery\"], function (a0) {\n      return (factory(a0));\n    });\n  } else if (typeof module === 'object' && module.exports) {\n    // Node. Does not work with strict CommonJS, but\n    // only CommonJS-like environments that support module.exports,\n    // like Node.\n    module.exports = factory(require(\"jquery\"));\n  } else {\n    factory(root[\"jQuery\"]);\n  }\n}(this, function (jQuery) {\n\n(function ($) {\n  $.fn.selectpicker.defaults = {\n    noneSelectedText: 'Vyberte zo zoznamu',\n    noneResultsText: 'Pre výraz {0} neboli nájdené žiadne výsledky',\n    countSelectedText: 'Vybrané {0} z {1}',\n    maxOptionsText: ['Limit prekročený ({n} {var} max)', 'Limit skupiny prekročený ({n} {var} max)', ['položiek', 'položka']],\n    selectAllText: 'Vybrať všetky',\n    deselectAllText: 'Zrušiť výber',\n    multipleSeparator: ', '\n  };\n})(jQuery);\n\n\n}));\n"
  },
  {
    "path": "app_backend/static/plugin/bootstrap-select-1.12.2/dist/js/i18n/defaults-sl_SI.js",
    "content": "/*!\n * Bootstrap-select v1.12.2 (http://silviomoreto.github.io/bootstrap-select)\n *\n * Copyright 2013-2017 bootstrap-select\n * Licensed under MIT (https://github.com/silviomoreto/bootstrap-select/blob/master/LICENSE)\n */\n\n(function (root, factory) {\n  if (typeof define === 'function' && define.amd) {\n    // AMD. Register as an anonymous module unless amdModuleId is set\n    define([\"jquery\"], function (a0) {\n      return (factory(a0));\n    });\n  } else if (typeof module === 'object' && module.exports) {\n    // Node. Does not work with strict CommonJS, but\n    // only CommonJS-like environments that support module.exports,\n    // like Node.\n    module.exports = factory(require(\"jquery\"));\n  } else {\n    factory(root[\"jQuery\"]);\n  }\n}(this, function (jQuery) {\n\n(function ($) {\n  $.fn.selectpicker.defaults = {\n    noneSelectedText: 'Nič izbranega',\n    noneResultsText: 'Ni zadetkov za {0}',\n    countSelectedText: function (numSelected, numTotal) {\n      \"Število izbranih: {0}\";\n    },\n    maxOptionsText: function (numAll, numGroup) {\n      return [\n        'Omejitev dosežena (max. izbranih: {n})',\n        'Omejitev skupine dosežena (max. izbranih: {n})'\n      ];\n    },\n    selectAllText: 'Izberi vse',\n    deselectAllText: 'Počisti izbor',\n    multipleSeparator: ', '\n  };\n})(jQuery);\n\n\n}));\n"
  },
  {
    "path": "app_backend/static/plugin/bootstrap-select-1.12.2/dist/js/i18n/defaults-sv_SE.js",
    "content": "/*!\n * Bootstrap-select v1.12.2 (http://silviomoreto.github.io/bootstrap-select)\n *\n * Copyright 2013-2017 bootstrap-select\n * Licensed under MIT (https://github.com/silviomoreto/bootstrap-select/blob/master/LICENSE)\n */\n\n(function (root, factory) {\n  if (typeof define === 'function' && define.amd) {\n    // AMD. Register as an anonymous module unless amdModuleId is set\n    define([\"jquery\"], function (a0) {\n      return (factory(a0));\n    });\n  } else if (typeof module === 'object' && module.exports) {\n    // Node. Does not work with strict CommonJS, but\n    // only CommonJS-like environments that support module.exports,\n    // like Node.\n    module.exports = factory(require(\"jquery\"));\n  } else {\n    factory(root[\"jQuery\"]);\n  }\n}(this, function (jQuery) {\n\n(function ($) {\n  $.fn.selectpicker.defaults = {\n    noneSelectedText: 'Inget valt',\n    noneResultsText: 'Inget sökresultat matchar {0}',\n    countSelectedText: function (numSelected, numTotal) {\n      return (numSelected === 1) ? \"{0} alternativ valt\" : \"{0} alternativ valda\";\n    },\n    maxOptionsText: function (numAll, numGroup) {\n      return [\n        'Gräns uppnåd (max {n} alternativ)',\n        'Gräns uppnåd (max {n} gruppalternativ)'\n      ];\n    },\n    selectAllText: 'Markera alla',\n    deselectAllText: 'Avmarkera alla',\n    multipleSeparator: ', '\n  };\n})(jQuery);\n\n\n}));\n"
  },
  {
    "path": "app_backend/static/plugin/bootstrap-select-1.12.2/dist/js/i18n/defaults-tr_TR.js",
    "content": "/*!\n * Bootstrap-select v1.12.2 (http://silviomoreto.github.io/bootstrap-select)\n *\n * Copyright 2013-2017 bootstrap-select\n * Licensed under MIT (https://github.com/silviomoreto/bootstrap-select/blob/master/LICENSE)\n */\n\n(function (root, factory) {\n  if (typeof define === 'function' && define.amd) {\n    // AMD. Register as an anonymous module unless amdModuleId is set\n    define([\"jquery\"], function (a0) {\n      return (factory(a0));\n    });\n  } else if (typeof module === 'object' && module.exports) {\n    // Node. Does not work with strict CommonJS, but\n    // only CommonJS-like environments that support module.exports,\n    // like Node.\n    module.exports = factory(require(\"jquery\"));\n  } else {\n    factory(root[\"jQuery\"]);\n  }\n}(this, function (jQuery) {\n\n(function ($) {\n  $.fn.selectpicker.defaults = {\n    noneSelectedText: 'Hiçbiri seçilmedi',\n    noneResultsText: 'Hiçbir sonuç bulunamadı {0}',\n    countSelectedText: function (numSelected, numTotal) {\n      return (numSelected == 1) ? \"{0} öğe seçildi\" : \"{0} öğe seçildi\";\n    },\n    maxOptionsText: function (numAll, numGroup) {\n      return [\n        (numAll == 1) ? 'Limit aşıldı (maksimum {n} sayıda öğe )' : 'Limit aşıldı (maksimum {n} sayıda öğe)',\n        (numGroup == 1) ? 'Grup limiti aşıldı (maksimum {n} sayıda öğe)' : 'Grup limiti aşıldı (maksimum {n} sayıda öğe)'\n      ];\n    },\n    selectAllText: 'Tümünü Seç',\n    deselectAllText: 'Seçiniz',\n    multipleSeparator: ', '\n  };\n})(jQuery);\n\n\n}));\n"
  },
  {
    "path": "app_backend/static/plugin/bootstrap-select-1.12.2/dist/js/i18n/defaults-ua_UA.js",
    "content": "/*!\n * Bootstrap-select v1.12.2 (http://silviomoreto.github.io/bootstrap-select)\n *\n * Copyright 2013-2017 bootstrap-select\n * Licensed under MIT (https://github.com/silviomoreto/bootstrap-select/blob/master/LICENSE)\n */\n\n(function (root, factory) {\n  if (typeof define === 'function' && define.amd) {\n    // AMD. Register as an anonymous module unless amdModuleId is set\n    define([\"jquery\"], function (a0) {\n      return (factory(a0));\n    });\n  } else if (typeof module === 'object' && module.exports) {\n    // Node. Does not work with strict CommonJS, but\n    // only CommonJS-like environments that support module.exports,\n    // like Node.\n    module.exports = factory(require(\"jquery\"));\n  } else {\n    factory(root[\"jQuery\"]);\n  }\n}(this, function (jQuery) {\n\n(function ($) {\n  $.fn.selectpicker.defaults = {\n    noneSelectedText: 'Нічого не вибрано',\n    noneResultsText: 'Збігів не знайдено {0}',\n    countSelectedText: 'Вибрано {0} із {1}',\n    maxOptionsText: ['Досягнута межа ({n} {var} максимум)', 'Досягнута межа в групі ({n} {var} максимум)', ['items', 'item']],\n    multipleSeparator: ', '\n  };\n})(jQuery);\n\n\n}));\n"
  },
  {
    "path": "app_backend/static/plugin/bootstrap-select-1.12.2/dist/js/i18n/defaults-zh_CN.js",
    "content": "/*!\n * Bootstrap-select v1.12.2 (http://silviomoreto.github.io/bootstrap-select)\n *\n * Copyright 2013-2017 bootstrap-select\n * Licensed under MIT (https://github.com/silviomoreto/bootstrap-select/blob/master/LICENSE)\n */\n\n(function (root, factory) {\n  if (typeof define === 'function' && define.amd) {\n    // AMD. Register as an anonymous module unless amdModuleId is set\n    define([\"jquery\"], function (a0) {\n      return (factory(a0));\n    });\n  } else if (typeof module === 'object' && module.exports) {\n    // Node. Does not work with strict CommonJS, but\n    // only CommonJS-like environments that support module.exports,\n    // like Node.\n    module.exports = factory(require(\"jquery\"));\n  } else {\n    factory(root[\"jQuery\"]);\n  }\n}(this, function (jQuery) {\n\n(function ($) {\n  $.fn.selectpicker.defaults = {\n    noneSelectedText: '没有选中任何项',\n    noneResultsText: '没有找到匹配项',\n    countSelectedText: '选中{1}中的{0}项',\n    maxOptionsText: ['超出限制 (最多选择{n}项)', '组选择超出限制(最多选择{n}组)'],\n    multipleSeparator: ', '\n  };\n})(jQuery);\n\n\n}));\n"
  },
  {
    "path": "app_backend/static/plugin/bootstrap-select-1.12.2/dist/js/i18n/defaults-zh_TW.js",
    "content": "/*!\n * Bootstrap-select v1.12.2 (http://silviomoreto.github.io/bootstrap-select)\n *\n * Copyright 2013-2017 bootstrap-select\n * Licensed under MIT (https://github.com/silviomoreto/bootstrap-select/blob/master/LICENSE)\n */\n\n(function (root, factory) {\n  if (typeof define === 'function' && define.amd) {\n    // AMD. Register as an anonymous module unless amdModuleId is set\n    define([\"jquery\"], function (a0) {\n      return (factory(a0));\n    });\n  } else if (typeof module === 'object' && module.exports) {\n    // Node. Does not work with strict CommonJS, but\n    // only CommonJS-like environments that support module.exports,\n    // like Node.\n    module.exports = factory(require(\"jquery\"));\n  } else {\n    factory(root[\"jQuery\"]);\n  }\n}(this, function (jQuery) {\n\n(function ($) {\n  $.fn.selectpicker.defaults = {\n    noneSelectedText: '沒有選取任何項目',\n    noneResultsText: '沒有找到符合的結果',\n    countSelectedText: '已經選取{0}個項目',\n    maxOptionsText: ['超過限制 (最多選擇{n}項)', '超過限制(最多選擇{n}組)'],\n    selectAllText: '選取全部',\n    deselectAllText: '全部取消',\n    multipleSeparator: ', '\n  };\n})(jQuery);\n\n\n}));\n"
  },
  {
    "path": "app_backend/static/plugin/bootstrap-select-1.12.2/docs/custom_theme/base.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n  <meta charset=\"utf-8\">\n  <meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\">\n  <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n  {% if page_description %}<meta name=\"description\" content=\"{{ page_description }}\">{% endif %}\n  {% if site_author %}<meta name=\"author\" content=\"{{ site_author }}\">{% endif %}\n  {% if canonical_url %}<link rel=\"canonical\" href=\"{{ canonical_url }}\">{% endif %}\n  {% if favicon %}<link rel=\"shortcut icon\" href=\"{{ favicon }}\">\n  {% else %}<link rel=\"shortcut icon\" href=\"{{ base_url }}/img/favicon.ico\">{% endif %}\n\n  <title>{% if page_title %}{{ page_title }} - {% endif %}{{ site_name }}</title>\n\n  <link href=\"https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css\" rel=\"stylesheet\">\n  <link href=\"https://maxcdn.bootstrapcdn.com/font-awesome/4.5.0/css/font-awesome.min.css\" rel=\"stylesheet\">\n  <link href=\"{{ base_url }}/css/highlight.css\" rel=\"stylesheet\">\n  <link href=\"{{ base_url }}/css/base.css\" rel=\"stylesheet\">\n  {%- for path in extra_css %}\n  <link href=\"{{ path }}\" rel=\"stylesheet\">\n  {%- endfor %}\n\n  <!-- HTML5 shim and Respond.js IE8 support of HTML5 elements and media queries -->\n  <!--[if lt IE 9]>\n    <script src=\"https://oss.maxcdn.com/libs/html5shiv/3.7.0/html5shiv.js\"></script>\n    <script src=\"https://oss.maxcdn.com/libs/respond.js/1.3.0/respond.min.js\"></script>\n  <![endif]-->\n</head>\n\n<body>\n\n{% include \"nav.html\" %}\n\n{% if current_page and current_page.is_homepage %} \n<div class=\"jumbotron bs-docs-header text-center\">\n  <div class=\"container\">\n    <h1>bootstrap-select</h1>\n    <p class=\"lead\">Bootstrap-select is a jQuery plugin that utilizes Bootstrap's dropdown.js to style and bring additional functionality to standard select elements.</p>\n    <a class=\"btn btn-outline-inverse btn-lg\" href=\"//github.com/silviomoreto/bootstrap-select/archive/v{{ config.extra.version }}.zip\" role=\"button\">\n      <i class=\"fa fa-download\"></i> Download (v{{ config.extra.version }})\n    </a>\n  </div>\n  <div class=\"gh-btns\">\n    <iframe src=\"https://ghbtns.com/github-btn.html?user=silviomoreto&repo=bootstrap-select&type=star&count=true&size=large\" frameborder=\"0\" scrolling=\"0\" width=\"160px\" height=\"30px\"></iframe>\n    <iframe src=\"https://ghbtns.com/github-btn.html?user=silviomoreto&repo=bootstrap-select&type=fork&count=true&size=large\" frameborder=\"0\" scrolling=\"0\" width=\"160px\" height=\"30px\"></iframe>\n  </div>\n  <div class=\"carbonad\">\n    <div class=\"carbonad-inner\">\n      <script async type=\"text/javascript\" src=\"//cdn.carbonads.com/carbon.js?zoneid=1673&serve=C6AILKT&placement=silviomoretogithubiobootstrapsel\" id=\"_carbonads_js\"></script>\n    </div>\n    <div class=\"charity\">Ad revenue is donated to <a href=\"http://www.projetocana.org/\" target=\"_blank\" rel=\"nofollow\">Projecto Cana</a>.</div>\n  </div>\n</div>\n<div class=\"container\">\n{% include \"content.html\" %}\n</div>\n{% else %}\n<section class=\"jumbotron\">\n  <div class=\"container\">\n    <h1>{{ page_title }}</h1>\n  </div>\n</section>\n<div class=\"container\">\n  <div class=\"col-md-3\">{% include \"toc.html\" %}</div>\n  <div class=\"col-md-9\" role=\"main\">{% include \"content.html\" %}</div>\n</div>\n{% endif %}\n\n  <div class=\"footer\">\n    <div class=\"container text-center\">\n      <p class=\"text-muted\">Bootstrap-select is maintained by <a href=\"https://github.com/caseyjhol\">caseyjhol</a>,\n        <a href=\"https://github.com/t0xicCode\">t0xicCode</a>, and the community.</p>\n    </div>\n  </div>\n\n<script src=\"//ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js\"></script>\n<script src=\"//maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js\"></script>\n<script src=\"{{ base_url }}/js/highlight.pack.js\"></script>\n<script src=\"{{ base_url }}/js/base.js\"></script>\n{%- for path in extra_javascript %}\n<script src=\"{{ path }}\"></script>\n{%- endfor %}\n\n<script type=\"text/javascript\">\n  var _gaq = _gaq || [];\n  _gaq.push(['_setAccount', 'UA-35848102-1']);\n  _gaq.push(['_trackPageview']);\n\n  (function () {\n    var ga = document.createElement('script');\n    ga.type = 'text/javascript';\n    ga.async = true;\n    ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';\n    var s = document.getElementsByTagName('script')[0];\n    s.parentNode.insertBefore(ga, s);\n  })();\n</script>\n</body>\n</html>\n"
  },
  {
    "path": "app_backend/static/plugin/bootstrap-select-1.12.2/docs/custom_theme/css/base.css",
    "content": "body {\n    padding-top: 70px;\n}\n\nh1[id]:before, h2[id]:before, h3[id]:before, h4[id]:before, h5[id]:before, h6[id]:before {\n    content: \"\";\n    display: block;\n    margin-top: -75px;\n    height: 75px;\n}\n\nh2 code, h3 code, h4 code {\n    background-color: inherit;\n}\n\nul.nav li.main {\n    font-weight: bold;\n}\n\n.container > div.col-md-3 {\n    padding-left: 0;\n}\n\n.container > div.col-md-9 {\n    padding-bottom: 100px;\n}\n\ndiv.source-links {\n    float: right;\n}\n\n/*\n * Side navigation\n *\n * Scrollspy and affixed enhanced navigation to highlight sections and secondary\n * sections of docs content.\n */\n\n/* By default it's not affixed in mobile views, so undo that */\n.bs-sidebar.affix {\n    position: static;\n}\n\n.bs-sidebar.well {\n    padding: 0;\n}\n\n/* First level of nav */\n.bs-sidenav {\n    margin-top: 30px;\n    margin-bottom: 30px;\n    padding-top:    10px;\n    padding-bottom: 10px;\n    border-radius: 5px;\n}\n\n/* All levels of nav */\n.bs-sidebar .nav > li > a {\n    display: block;\n    padding: 5px 20px;\n    z-index: 1;\n}\n.bs-sidebar .nav > li > a:hover,\n.bs-sidebar .nav > li > a:focus {\n    text-decoration: none;\n    border-right: 1px solid;\n}\n.bs-sidebar .nav > .active > a,\n.bs-sidebar .nav > .active:hover > a,\n.bs-sidebar .nav > .active:focus > a {\n    font-weight: bold;\n    background-color: transparent;\n    border-right: 1px solid;\n}\n\n/* Nav: second level (shown on .active) */\n.bs-sidebar .nav .nav {\n    display: none; /* Hide by default, but at >768px, show it */\n    margin-bottom: 8px;\n}\n.bs-sidebar .nav .nav > li > a {\n    padding-top:    3px;\n    padding-bottom: 3px;\n    padding-left: 30px;\n    font-size: 90%;\n}\n\n/* Show and affix the side nav when space allows it */\n@media (min-width: 992px) {\n    .bs-sidebar .nav > .active > ul {\n        display: block;\n    }\n    /* Widen the fixed sidebar */\n    .bs-sidebar.affix,\n    .bs-sidebar.affix-bottom {\n        width: 213px;\n    }\n    .bs-sidebar.affix {\n        position: fixed; /* Undo the static from mobile first approach */\n        top: 80px;\n    }\n    .bs-sidebar.affix-bottom {\n        position: absolute; /* Undo the static from mobile first approach */\n    }\n    .bs-sidebar.affix-bottom .bs-sidenav,\n    .bs-sidebar.affix .bs-sidenav {\n        margin-top: 0;\n        margin-bottom: 0;\n    }\n}\n@media (min-width: 1200px) {\n    /* Widen the fixed sidebar again */\n    .bs-sidebar.affix-bottom,\n    .bs-sidebar.affix {\n        width: 263px;\n    }\n}"
  },
  {
    "path": "app_backend/static/plugin/bootstrap-select-1.12.2/docs/custom_theme/js/base.js",
    "content": "/* Highlight */\n$( document ).ready(function() {\n    hljs.initHighlightingOnLoad();\n    $('table').addClass('table table-striped table-hover');\n    $('pre').addClass('highlight');\n});\n\n$('body').scrollspy({\n    target: '.bs-sidebar',\n});\n\n$('.bs-sidebar').affix({\n  offset: {\n    top: 210\n  }\n});\n\n/* Prevent disabled links from causing a page reload */\n$(\"li.disabled a\").click(function() {\n    event.preventDefault();\n});"
  },
  {
    "path": "app_backend/static/plugin/bootstrap-select-1.12.2/docs/custom_theme/nav.html",
    "content": "<div class=\"navbar navbar-default navbar-fixed-top\" role=\"navigation\">\n  <div class=\"container\">\n\n    <!-- Collapsed navigation -->\n    <div class=\"navbar-header\">\n      {% if include_nav or include_next_prev or repo_url %}\n      <!-- Expander button -->\n      <button type=\"button\" class=\"navbar-toggle\" data-toggle=\"collapse\" data-target=\".navbar-collapse\">\n        <span class=\"sr-only\">Toggle navigation</span>\n        <span class=\"icon-bar\"></span>\n        <span class=\"icon-bar\"></span>\n        <span class=\"icon-bar\"></span>\n      </button>\n      {% endif %}\n\n      <!-- Main title -->\n      <a class=\"navbar-brand\" href=\"{{ homepage_url }}\">{{ site_name }}</a>\n    </div>\n\n    <!-- Expanded navigation -->\n    <div class=\"navbar-collapse collapse\">\n      {% if include_nav %}\n      <!-- Main navigation -->\n      <ul class=\"nav navbar-nav\">\n        {% for nav_item in nav %}\n        {% if nav_item.children %}\n        <li class=\"dropdown{% if nav_item.active %} active{% endif %}\">\n          <a href=\"#\" class=\"dropdown-toggle\" data-toggle=\"dropdown\">{{ nav_item.title }} <b class=\"caret\"></b></a>\n          <ul class=\"dropdown-menu\">\n            {% for nav_item in nav_item.children %}\n            {% include \"nav-sub.html\" %}\n            {% endfor %}\n          </ul>\n        </li>\n        {% else %}\n        <li {% if nav_item.active %}class=\"active\"{% endif %}>\n          <a href=\"{{ nav_item.url }}\">{{ nav_item.title }}</a>\n        </li>\n        {% endif %}\n        {% endfor %}\n      </ul>\n      {% endif %}\n\n      <ul class=\"nav navbar-nav navbar-right\">\n        {% if repo_url %}\n        <li>\n          <a href=\"{{ repo_url }}\">\n            {% if repo_name == 'GitHub' %}\n            <i class=\"fa fa-github\"></i>\n            {% elif repo_name == 'Bitbucket' %}\n            <i class=\"fa fa-bitbucket\"></i>\n            {% endif %}\n            {{ repo_name }}\n          </a>\n        </li>\n        {% endif %}\n      </ul>\n    </div>\n  </div>\n</div>\n"
  },
  {
    "path": "app_backend/static/plugin/bootstrap-select-1.12.2/docs/custom_theme/toc.html",
    "content": "<div class=\"bs-sidebar hidden-print affix-top\" role=\"complementary\">\n    <ul class=\"nav bs-sidenav\">\n    {% for toc_item in toc %}\n        <li class=\"main {% if toc_item.active %}active{% endif %}\">\n\t        <a href=\"{{ toc_item.url }}\">{{ toc_item.title }}</a>\n\t        <ul class=\"nav\">\n\t        {% for toc_item in toc_item.children %}\n\t            <li><a href=\"{{ toc_item.url }}\">{{ toc_item.title }}</a></li>\n\t        {% endfor %}\n\t        </ul>\n        </li>\n    {% endfor %}\n    </ul>\n</div>"
  },
  {
    "path": "app_backend/static/plugin/bootstrap-select-1.12.2/docs/docs/css/custom.css",
    "content": "html {\n  position: relative;\n  min-height: 100%;\n}\nbody {\n  padding-top: 51px;\n  /* Margin bottom by footer height */\n  margin-bottom: 60px;\n}\nlabel {\n  display: block;\n}\n/* hide \"Home\" in navbar */\n.nav.navbar-nav:first-child > li:first-child {\n    display: none;\n}\n\nul.nav li.main {\n  font-weight: normal;\n}\n\n.footer {\n  position: absolute;\n  bottom: 0;\n  width: 100%;\n  /* Set the fixed height of the footer here */\n  height: 60px;\n  background-color: #f5f5f5;\n}\n\n.footer .container .text-muted {\n  margin: 20px 0;\n}\n\n.footer .container {\n  padding-right: 15px;\n  padding-left: 15px;\n}\n\n/* Outline button for use within the docs */\n.btn-outline {\n  color: #337ab7;\n  background-color: transparent;\n  border-color: #337ab7;\n}\n.btn-outline:hover,\n.btn-outline:focus,\n.btn-outline:active {\n  color: #fff;\n  background-color: #337ab7;\n  border-color: #337ab7;\n}\n\n/* Inverted outline button (white on dark) */\n.btn-outline-inverse {\n  color: #fff;\n  background-color: transparent;\n  border-color: #fff;\n}\n.btn-outline-inverse:hover,\n.btn-outline-inverse:focus,\n.btn-outline-inverse:active {\n  color: #337ab7;\n  text-shadow: none;\n  background-color: #fff;\n  border-color: #fff;\n}\n\n.bs-docs-header {\n  margin-bottom: 0;\n  background: #337ab7;\n  color: #fff;\n}\n\n.bs-docs-header .btn {\n  padding: 15px 30px;\n  font-size: 20px\n}\n\n.bs-docs-header h1 {\n  margin-bottom: 30px;\n}\n\n.bs-docs-header .lead {\n  margin: 0 auto 30px;\n}\n\n.bs-docs-sub-header {\n  padding-top: 20px;\n  padding-bottom: 20px;\n}\n\n.gh-btns {\n  margin: 48px 0 -30px;\n  background: rgba(0,0,0,.1);\n  padding: 20px 0 15px;\n}\n\n.content h1:first-of-type,\n.content h1:first-of-type + p:first-of-type {\n  text-align: center;\n}\n\n.bs-docs-example > p {\n  margin-top: 20px;\n}\n\n.bs-docs-example > p:last-child {\n  margin-bottom: 0;\n}\n\n.bs-docs-example .table,\n.bs-docs-example .progress,\n.bs-docs-example .well,\n.bs-docs-example .alert,\n.bs-docs-example .hero-unit,\n.bs-docs-example .pagination,\n.bs-docs-example .navbar,\n.bs-docs-example > .nav,\n.bs-docs-example blockquote {\n  margin-bottom: 5px;\n}\n\n.bs-docs-example .pagination {\n  margin-top: 0;\n}\n\n.special {\n  font-weight: bold !important;\n  color: #fff !important;\n  background: #bc0000 !important;\n  text-transform: uppercase;\n}\n\n.bs-docs-example {\n  position: relative;\n  padding: 45px 15px 15px;\n  margin: 0 -15px 15px;\n  border-color: #e5e5e5 #eee #eee;\n  border-style: solid;\n  border-width: 1px 0;\n  -webkit-box-shadow: inset 0 3px 6px rgba(0,0,0,.05);\n  box-shadow: inset 0 3px 6px rgba(0,0,0,.05);\n}\n\n/* Echo out a label for the example */\n.bs-docs-example:after {\n  position: absolute;\n  top: 15px;\n  left: 15px;\n  font-size: 12px;\n  font-weight: 700;\n  color: #959595;\n  text-transform: uppercase;\n  letter-spacing: 1px;\n  content: \"Example\";\n}\n\n.highlight {\n  padding: 9px 14px;\n  margin-bottom: 14px;\n  background-color: #f7f7f9;\n  border: 1px solid #e1e1e8;\n  border-radius: 4px;\n}\n\n.bs-docs-example + .highlight {\n  margin: -15px -15px 15px;\n  border-width: 0 0 1px;\n  border-radius: 0;\n}\n\n.carbonad {\n  margin-top: 80px;\n}\n\n.carbonad-inner {\n  width: auto!important;\n  height: auto!important;\n  padding: 20px!important;\n  margin: 30px -15px 0!important;\n  overflow: hidden;\n  font-size: 13px!important;\n  line-height: 16px!important;\n  text-align: left;\n  background: 0 0!important;\n  border: solid rgba(255, 255, 255, 0.50) !important;\n  border-width: 1px 0!important;\n}\n\n.carbon-poweredby,\n.carbon-text {\n  display: block!important;\n  float: none!important;\n  width: auto!important;\n  height: auto!important;\n  margin-left: 145px!important;\n  font-family: \"Helvetica Neue\",Helvetica,Arial,sans-serif!important;\n  color: #fff!important;\n}\n\n.carbon-poweredby {\n  float: left;\n  margin-top: 9px;\n  text-align: left;\n  width: 142px;\n  opacity: 0.5;\n}\n\n.charity {\n  opacity: 0.5;\n  padding: 4px;\n  margin-bottom: -31px;\n}\n\n.charity a {\n  color: #fff;\n}\n\n.carbon-img img {\n    border: none;\n    display: inline;\n    float: left;\n    height: 100px;\n    margin: 0 !important;\n    width: 130px;\n}\n\n.logo-block a {\n  display: block;\n  padding: 5px;\n  margin: 5px 0;\n}\n\n.logo-block img {\n  height: auto;\n  max-width: 100%;\n  max-height: 40px;\n}\n\n.logo-container {\n  float: left;\n  max-width: 25%;\n  margin: 0 15px;\n}\n\n.logo-block + div {\n  margin: 5px 0;\n}\n\n@media (min-width: 480px){\n  .carbonad-inner {\n    width: 330px!important;\n    margin: 50px auto 0 !important;\n    border-width: 1px!important;\n    border-radius: 4px;\n  }\n\n  .charity {\n    margin-bottom: 0;\n  }\n\n  .logo-container {\n    max-width: 60%;\n  }\n}\n\n@media (min-width: 768px) {\n  .bs-docs-example {\n    margin-right: 0;\n    margin-left: 0;\n    background-color: #fff;\n    border-color: #ddd;\n    border-width: 1px;\n    border-radius: 4px 4px 0 0;\n    -webkit-box-shadow: none;\n    box-shadow: none;\n  }\n\n  .bs-docs-example.no-code {\n    border-radius: 4px;\n  }\n\n  .bs-docs-example + .highlight {\n    margin-top: -16px;\n    margin-right: 0;\n    margin-left: 0;\n    border-width: 1px;\n    border-bottom-right-radius: 4px;\n    border-bottom-left-radius: 4px;\n  }\n\n  .logo-container {\n    max-width: 33.3333%;\n  }\n\n  .gh-btns {\n    margin-bottom: -48px;\n  }\n}\n\n@media (min-width: 992px){\n  .bs-docs-header .lead {\n      width: 80%;\n  }\n\n  .carbonad-inner {\n    top: 0;\n    right: 15px;\n    width: 330px!important;\n    padding: 15px!important;\n  }\n\n  .logo-container {\n    max-width: 25%;\n  }\n}"
  },
  {
    "path": "app_backend/static/plugin/bootstrap-select-1.12.2/docs/docs/dist/css/bootstrap-select.css",
    "content": "/*!\n * Bootstrap-select v1.12.2 (http://silviomoreto.github.io/bootstrap-select)\n *\n * Copyright 2013-2017 bootstrap-select\n * Licensed under MIT (https://github.com/silviomoreto/bootstrap-select/blob/master/LICENSE)\n */\n\nselect.bs-select-hidden,\nselect.selectpicker {\n  display: none !important;\n}\n.bootstrap-select {\n  width: 220px \\0;\n  /*IE9 and below*/\n}\n.bootstrap-select > .dropdown-toggle {\n  width: 100%;\n  padding-right: 25px;\n  z-index: 1;\n}\n.bootstrap-select > .dropdown-toggle.bs-placeholder,\n.bootstrap-select > .dropdown-toggle.bs-placeholder:hover,\n.bootstrap-select > .dropdown-toggle.bs-placeholder:focus,\n.bootstrap-select > .dropdown-toggle.bs-placeholder:active {\n  color: #999;\n}\n.bootstrap-select > select {\n  position: absolute !important;\n  bottom: 0;\n  left: 50%;\n  display: block !important;\n  width: 0.5px !important;\n  height: 100% !important;\n  padding: 0 !important;\n  opacity: 0 !important;\n  border: none;\n}\n.bootstrap-select > select.mobile-device {\n  top: 0;\n  left: 0;\n  display: block !important;\n  width: 100% !important;\n  z-index: 2;\n}\n.has-error .bootstrap-select .dropdown-toggle,\n.error .bootstrap-select .dropdown-toggle {\n  border-color: #b94a48;\n}\n.bootstrap-select.fit-width {\n  width: auto !important;\n}\n.bootstrap-select:not([class*=\"col-\"]):not([class*=\"form-control\"]):not(.input-group-btn) {\n  width: 220px;\n}\n.bootstrap-select .dropdown-toggle:focus {\n  outline: thin dotted #333333 !important;\n  outline: 5px auto -webkit-focus-ring-color !important;\n  outline-offset: -2px;\n}\n.bootstrap-select.form-control {\n  margin-bottom: 0;\n  padding: 0;\n  border: none;\n}\n.bootstrap-select.form-control:not([class*=\"col-\"]) {\n  width: 100%;\n}\n.bootstrap-select.form-control.input-group-btn {\n  z-index: auto;\n}\n.bootstrap-select.form-control.input-group-btn:not(:first-child):not(:last-child) > .btn {\n  border-radius: 0;\n}\n.bootstrap-select.btn-group:not(.input-group-btn),\n.bootstrap-select.btn-group[class*=\"col-\"] {\n  float: none;\n  display: inline-block;\n  margin-left: 0;\n}\n.bootstrap-select.btn-group.dropdown-menu-right,\n.bootstrap-select.btn-group[class*=\"col-\"].dropdown-menu-right,\n.row .bootstrap-select.btn-group[class*=\"col-\"].dropdown-menu-right {\n  float: right;\n}\n.form-inline .bootstrap-select.btn-group,\n.form-horizontal .bootstrap-select.btn-group,\n.form-group .bootstrap-select.btn-group {\n  margin-bottom: 0;\n}\n.form-group-lg .bootstrap-select.btn-group.form-control,\n.form-group-sm .bootstrap-select.btn-group.form-control {\n  padding: 0;\n}\n.form-group-lg .bootstrap-select.btn-group.form-control .dropdown-toggle,\n.form-group-sm .bootstrap-select.btn-group.form-control .dropdown-toggle {\n  height: 100%;\n  font-size: inherit;\n  line-height: inherit;\n  border-radius: inherit;\n}\n.form-inline .bootstrap-select.btn-group .form-control {\n  width: 100%;\n}\n.bootstrap-select.btn-group.disabled,\n.bootstrap-select.btn-group > .disabled {\n  cursor: not-allowed;\n}\n.bootstrap-select.btn-group.disabled:focus,\n.bootstrap-select.btn-group > .disabled:focus {\n  outline: none !important;\n}\n.bootstrap-select.btn-group.bs-container {\n  position: absolute;\n  height: 0 !important;\n  padding: 0 !important;\n}\n.bootstrap-select.btn-group.bs-container .dropdown-menu {\n  z-index: 1060;\n}\n.bootstrap-select.btn-group .dropdown-toggle .filter-option {\n  display: inline-block;\n  overflow: hidden;\n  width: 100%;\n  text-align: left;\n}\n.bootstrap-select.btn-group .dropdown-toggle .caret {\n  position: absolute;\n  top: 50%;\n  right: 12px;\n  margin-top: -2px;\n  vertical-align: middle;\n}\n.bootstrap-select.btn-group[class*=\"col-\"] .dropdown-toggle {\n  width: 100%;\n}\n.bootstrap-select.btn-group .dropdown-menu {\n  min-width: 100%;\n  -webkit-box-sizing: border-box;\n     -moz-box-sizing: border-box;\n          box-sizing: border-box;\n}\n.bootstrap-select.btn-group .dropdown-menu.inner {\n  position: static;\n  float: none;\n  border: 0;\n  padding: 0;\n  margin: 0;\n  border-radius: 0;\n  -webkit-box-shadow: none;\n          box-shadow: none;\n}\n.bootstrap-select.btn-group .dropdown-menu li {\n  position: relative;\n}\n.bootstrap-select.btn-group .dropdown-menu li.active small {\n  color: #fff;\n}\n.bootstrap-select.btn-group .dropdown-menu li.disabled a {\n  cursor: not-allowed;\n}\n.bootstrap-select.btn-group .dropdown-menu li a {\n  cursor: pointer;\n  -webkit-user-select: none;\n     -moz-user-select: none;\n      -ms-user-select: none;\n          user-select: none;\n}\n.bootstrap-select.btn-group .dropdown-menu li a.opt {\n  position: relative;\n  padding-left: 2.25em;\n}\n.bootstrap-select.btn-group .dropdown-menu li a span.check-mark {\n  display: none;\n}\n.bootstrap-select.btn-group .dropdown-menu li a span.text {\n  display: inline-block;\n}\n.bootstrap-select.btn-group .dropdown-menu li small {\n  padding-left: 0.5em;\n}\n.bootstrap-select.btn-group .dropdown-menu .notify {\n  position: absolute;\n  bottom: 5px;\n  width: 96%;\n  margin: 0 2%;\n  min-height: 26px;\n  padding: 3px 5px;\n  background: #f5f5f5;\n  border: 1px solid #e3e3e3;\n  -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.05);\n          box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.05);\n  pointer-events: none;\n  opacity: 0.9;\n  -webkit-box-sizing: border-box;\n     -moz-box-sizing: border-box;\n          box-sizing: border-box;\n}\n.bootstrap-select.btn-group .no-results {\n  padding: 3px;\n  background: #f5f5f5;\n  margin: 0 5px;\n  white-space: nowrap;\n}\n.bootstrap-select.btn-group.fit-width .dropdown-toggle .filter-option {\n  position: static;\n}\n.bootstrap-select.btn-group.fit-width .dropdown-toggle .caret {\n  position: static;\n  top: auto;\n  margin-top: -1px;\n}\n.bootstrap-select.btn-group.show-tick .dropdown-menu li.selected a span.check-mark {\n  position: absolute;\n  display: inline-block;\n  right: 15px;\n  margin-top: 5px;\n}\n.bootstrap-select.btn-group.show-tick .dropdown-menu li a span.text {\n  margin-right: 34px;\n}\n.bootstrap-select.show-menu-arrow.open > .dropdown-toggle {\n  z-index: 1061;\n}\n.bootstrap-select.show-menu-arrow .dropdown-toggle:before {\n  content: '';\n  border-left: 7px solid transparent;\n  border-right: 7px solid transparent;\n  border-bottom: 7px solid rgba(204, 204, 204, 0.2);\n  position: absolute;\n  bottom: -4px;\n  left: 9px;\n  display: none;\n}\n.bootstrap-select.show-menu-arrow .dropdown-toggle:after {\n  content: '';\n  border-left: 6px solid transparent;\n  border-right: 6px solid transparent;\n  border-bottom: 6px solid white;\n  position: absolute;\n  bottom: -4px;\n  left: 10px;\n  display: none;\n}\n.bootstrap-select.show-menu-arrow.dropup .dropdown-toggle:before {\n  bottom: auto;\n  top: -3px;\n  border-top: 7px solid rgba(204, 204, 204, 0.2);\n  border-bottom: 0;\n}\n.bootstrap-select.show-menu-arrow.dropup .dropdown-toggle:after {\n  bottom: auto;\n  top: -3px;\n  border-top: 6px solid white;\n  border-bottom: 0;\n}\n.bootstrap-select.show-menu-arrow.pull-right .dropdown-toggle:before {\n  right: 12px;\n  left: auto;\n}\n.bootstrap-select.show-menu-arrow.pull-right .dropdown-toggle:after {\n  right: 13px;\n  left: auto;\n}\n.bootstrap-select.show-menu-arrow.open > .dropdown-toggle:before,\n.bootstrap-select.show-menu-arrow.open > .dropdown-toggle:after {\n  display: block;\n}\n.bs-searchbox,\n.bs-actionsbox,\n.bs-donebutton {\n  padding: 4px 8px;\n}\n.bs-actionsbox {\n  width: 100%;\n  -webkit-box-sizing: border-box;\n     -moz-box-sizing: border-box;\n          box-sizing: border-box;\n}\n.bs-actionsbox .btn-group button {\n  width: 50%;\n}\n.bs-donebutton {\n  float: left;\n  width: 100%;\n  -webkit-box-sizing: border-box;\n     -moz-box-sizing: border-box;\n          box-sizing: border-box;\n}\n.bs-donebutton .btn-group button {\n  width: 100%;\n}\n.bs-searchbox + .bs-actionsbox {\n  padding: 0 8px 4px;\n}\n.bs-searchbox .form-control {\n  margin-bottom: 0;\n  width: 100%;\n  float: none;\n}\n/*# sourceMappingURL=bootstrap-select.css.map */"
  },
  {
    "path": "app_backend/static/plugin/bootstrap-select-1.12.2/docs/docs/dist/js/bootstrap-select.js",
    "content": "/*!\n * Bootstrap-select v1.12.2 (http://silviomoreto.github.io/bootstrap-select)\n *\n * Copyright 2013-2017 bootstrap-select\n * Licensed under MIT (https://github.com/silviomoreto/bootstrap-select/blob/master/LICENSE)\n */\n\n(function (root, factory) {\n  if (typeof define === 'function' && define.amd) {\n    // AMD. Register as an anonymous module unless amdModuleId is set\n    define([\"jquery\"], function (a0) {\n      return (factory(a0));\n    });\n  } else if (typeof module === 'object' && module.exports) {\n    // Node. Does not work with strict CommonJS, but\n    // only CommonJS-like environments that support module.exports,\n    // like Node.\n    module.exports = factory(require(\"jquery\"));\n  } else {\n    factory(root[\"jQuery\"]);\n  }\n}(this, function (jQuery) {\n\n(function ($) {\n  'use strict';\n\n  //<editor-fold desc=\"Shims\">\n  if (!String.prototype.includes) {\n    (function () {\n      'use strict'; // needed to support `apply`/`call` with `undefined`/`null`\n      var toString = {}.toString;\n      var defineProperty = (function () {\n        // IE 8 only supports `Object.defineProperty` on DOM elements\n        try {\n          var object = {};\n          var $defineProperty = Object.defineProperty;\n          var result = $defineProperty(object, object, object) && $defineProperty;\n        } catch (error) {\n        }\n        return result;\n      }());\n      var indexOf = ''.indexOf;\n      var includes = function (search) {\n        if (this == null) {\n          throw new TypeError();\n        }\n        var string = String(this);\n        if (search && toString.call(search) == '[object RegExp]') {\n          throw new TypeError();\n        }\n        var stringLength = string.length;\n        var searchString = String(search);\n        var searchLength = searchString.length;\n        var position = arguments.length > 1 ? arguments[1] : undefined;\n        // `ToInteger`\n        var pos = position ? Number(position) : 0;\n        if (pos != pos) { // better `isNaN`\n          pos = 0;\n        }\n        var start = Math.min(Math.max(pos, 0), stringLength);\n        // Avoid the `indexOf` call if no match is possible\n        if (searchLength + start > stringLength) {\n          return false;\n        }\n        return indexOf.call(string, searchString, pos) != -1;\n      };\n      if (defineProperty) {\n        defineProperty(String.prototype, 'includes', {\n          'value': includes,\n          'configurable': true,\n          'writable': true\n        });\n      } else {\n        String.prototype.includes = includes;\n      }\n    }());\n  }\n\n  if (!String.prototype.startsWith) {\n    (function () {\n      'use strict'; // needed to support `apply`/`call` with `undefined`/`null`\n      var defineProperty = (function () {\n        // IE 8 only supports `Object.defineProperty` on DOM elements\n        try {\n          var object = {};\n          var $defineProperty = Object.defineProperty;\n          var result = $defineProperty(object, object, object) && $defineProperty;\n        } catch (error) {\n        }\n        return result;\n      }());\n      var toString = {}.toString;\n      var startsWith = function (search) {\n        if (this == null) {\n          throw new TypeError();\n        }\n        var string = String(this);\n        if (search && toString.call(search) == '[object RegExp]') {\n          throw new TypeError();\n        }\n        var stringLength = string.length;\n        var searchString = String(search);\n        var searchLength = searchString.length;\n        var position = arguments.length > 1 ? arguments[1] : undefined;\n        // `ToInteger`\n        var pos = position ? Number(position) : 0;\n        if (pos != pos) { // better `isNaN`\n          pos = 0;\n        }\n        var start = Math.min(Math.max(pos, 0), stringLength);\n        // Avoid the `indexOf` call if no match is possible\n        if (searchLength + start > stringLength) {\n          return false;\n        }\n        var index = -1;\n        while (++index < searchLength) {\n          if (string.charCodeAt(start + index) != searchString.charCodeAt(index)) {\n            return false;\n          }\n        }\n        return true;\n      };\n      if (defineProperty) {\n        defineProperty(String.prototype, 'startsWith', {\n          'value': startsWith,\n          'configurable': true,\n          'writable': true\n        });\n      } else {\n        String.prototype.startsWith = startsWith;\n      }\n    }());\n  }\n\n  if (!Object.keys) {\n    Object.keys = function (\n      o, // object\n      k, // key\n      r  // result array\n      ){\n      // initialize object and result\n      r=[];\n      // iterate over object keys\n      for (k in o)\n          // fill result array with non-prototypical keys\n        r.hasOwnProperty.call(o, k) && r.push(k);\n      // return result\n      return r;\n    };\n  }\n\n  // set data-selected on select element if the value has been programmatically selected\n  // prior to initialization of bootstrap-select\n  // * consider removing or replacing an alternative method *\n  var valHooks = {\n    useDefault: false,\n    _set: $.valHooks.select.set\n  };\n\n  $.valHooks.select.set = function(elem, value) {\n    if (value && !valHooks.useDefault) $(elem).data('selected', true);\n\n    return valHooks._set.apply(this, arguments);\n  };\n\n  var changed_arguments = null;\n  $.fn.triggerNative = function (eventName) {\n    var el = this[0],\n        event;\n\n    if (el.dispatchEvent) { // for modern browsers & IE9+\n      if (typeof Event === 'function') {\n        // For modern browsers\n        event = new Event(eventName, {\n          bubbles: true\n        });\n      } else {\n        // For IE since it doesn't support Event constructor\n        event = document.createEvent('Event');\n        event.initEvent(eventName, true, false);\n      }\n\n      el.dispatchEvent(event);\n    } else if (el.fireEvent) { // for IE8\n      event = document.createEventObject();\n      event.eventType = eventName;\n      el.fireEvent('on' + eventName, event);\n    } else {\n      // fall back to jQuery.trigger\n      this.trigger(eventName);\n    }\n  };\n  //</editor-fold>\n\n  // Case insensitive contains search\n  $.expr.pseudos.icontains = function (obj, index, meta) {\n    var $obj = $(obj);\n    var haystack = ($obj.data('tokens') || $obj.text()).toString().toUpperCase();\n    return haystack.includes(meta[3].toUpperCase());\n  };\n\n  // Case insensitive begins search\n  $.expr.pseudos.ibegins = function (obj, index, meta) {\n    var $obj = $(obj);\n    var haystack = ($obj.data('tokens') || $obj.text()).toString().toUpperCase();\n    return haystack.startsWith(meta[3].toUpperCase());\n  };\n\n  // Case and accent insensitive contains search\n  $.expr.pseudos.aicontains = function (obj, index, meta) {\n    var $obj = $(obj);\n    var haystack = ($obj.data('tokens') || $obj.data('normalizedText') || $obj.text()).toString().toUpperCase();\n    return haystack.includes(meta[3].toUpperCase());\n  };\n\n  // Case and accent insensitive begins search\n  $.expr.pseudos.aibegins = function (obj, index, meta) {\n    var $obj = $(obj);\n    var haystack = ($obj.data('tokens') || $obj.data('normalizedText') || $obj.text()).toString().toUpperCase();\n    return haystack.startsWith(meta[3].toUpperCase());\n  };\n\n  /**\n   * Remove all diatrics from the given text.\n   * @access private\n   * @param {String} text\n   * @returns {String}\n   */\n  function normalizeToBase(text) {\n    var rExps = [\n      {re: /[\\xC0-\\xC6]/g, ch: \"A\"},\n      {re: /[\\xE0-\\xE6]/g, ch: \"a\"},\n      {re: /[\\xC8-\\xCB]/g, ch: \"E\"},\n      {re: /[\\xE8-\\xEB]/g, ch: \"e\"},\n      {re: /[\\xCC-\\xCF]/g, ch: \"I\"},\n      {re: /[\\xEC-\\xEF]/g, ch: \"i\"},\n      {re: /[\\xD2-\\xD6]/g, ch: \"O\"},\n      {re: /[\\xF2-\\xF6]/g, ch: \"o\"},\n      {re: /[\\xD9-\\xDC]/g, ch: \"U\"},\n      {re: /[\\xF9-\\xFC]/g, ch: \"u\"},\n      {re: /[\\xC7-\\xE7]/g, ch: \"c\"},\n      {re: /[\\xD1]/g, ch: \"N\"},\n      {re: /[\\xF1]/g, ch: \"n\"}\n    ];\n    $.each(rExps, function () {\n      text = text ? text.replace(this.re, this.ch) : '';\n    });\n    return text;\n  }\n\n\n  // List of HTML entities for escaping.\n  var escapeMap = {\n    '&': '&amp;',\n    '<': '&lt;',\n    '>': '&gt;',\n    '\"': '&quot;',\n    \"'\": '&#x27;',\n    '`': '&#x60;'\n  };\n  \n  var unescapeMap = {\n    '&amp;': '&',\n    '&lt;': '<',\n    '&gt;': '>',\n    '&quot;': '\"',\n    '&#x27;': \"'\",\n    '&#x60;': '`'\n  };\n\n  // Functions for escaping and unescaping strings to/from HTML interpolation.\n  var createEscaper = function(map) {\n    var escaper = function(match) {\n      return map[match];\n    };\n    // Regexes for identifying a key that needs to be escaped.\n    var source = '(?:' + Object.keys(map).join('|') + ')';\n    var testRegexp = RegExp(source);\n    var replaceRegexp = RegExp(source, 'g');\n    return function(string) {\n      string = string == null ? '' : '' + string;\n      return testRegexp.test(string) ? string.replace(replaceRegexp, escaper) : string;\n    };\n  };\n\n  var htmlEscape = createEscaper(escapeMap);\n  var htmlUnescape = createEscaper(unescapeMap);\n\n  var Selectpicker = function (element, options) {\n    // bootstrap-select has been initialized - revert valHooks.select.set back to its original function\n    if (!valHooks.useDefault) {\n      $.valHooks.select.set = valHooks._set;\n      valHooks.useDefault = true;\n    }\n\n    this.$element = $(element);\n    this.$newElement = null;\n    this.$button = null;\n    this.$menu = null;\n    this.$lis = null;\n    this.options = options;\n\n    // If we have no title yet, try to pull it from the html title attribute (jQuery doesnt' pick it up as it's not a\n    // data-attribute)\n    if (this.options.title === null) {\n      this.options.title = this.$element.attr('title');\n    }\n\n    // Format window padding\n    var winPad = this.options.windowPadding;\n    if (typeof winPad === 'number') {\n      this.options.windowPadding = [winPad, winPad, winPad, winPad];\n    }\n\n    //Expose public methods\n    this.val = Selectpicker.prototype.val;\n    this.render = Selectpicker.prototype.render;\n    this.refresh = Selectpicker.prototype.refresh;\n    this.setStyle = Selectpicker.prototype.setStyle;\n    this.selectAll = Selectpicker.prototype.selectAll;\n    this.deselectAll = Selectpicker.prototype.deselectAll;\n    this.destroy = Selectpicker.prototype.destroy;\n    this.remove = Selectpicker.prototype.remove;\n    this.show = Selectpicker.prototype.show;\n    this.hide = Selectpicker.prototype.hide;\n\n    this.init();\n  };\n\n  Selectpicker.VERSION = '1.12.2';\n\n  // part of this is duplicated in i18n/defaults-en_US.js. Make sure to update both.\n  Selectpicker.DEFAULTS = {\n    noneSelectedText: 'Nothing selected',\n    noneResultsText: 'No results matched {0}',\n    countSelectedText: function (numSelected, numTotal) {\n      return (numSelected == 1) ? \"{0} item selected\" : \"{0} items selected\";\n    },\n    maxOptionsText: function (numAll, numGroup) {\n      return [\n        (numAll == 1) ? 'Limit reached ({n} item max)' : 'Limit reached ({n} items max)',\n        (numGroup == 1) ? 'Group limit reached ({n} item max)' : 'Group limit reached ({n} items max)'\n      ];\n    },\n    selectAllText: 'Select All',\n    deselectAllText: 'Deselect All',\n    doneButton: false,\n    doneButtonText: 'Close',\n    multipleSeparator: ', ',\n    styleBase: 'btn',\n    style: 'btn-default',\n    size: 'auto',\n    title: null,\n    selectedTextFormat: 'values',\n    width: false,\n    container: false,\n    hideDisabled: false,\n    showSubtext: false,\n    showIcon: true,\n    showContent: true,\n    dropupAuto: true,\n    header: false,\n    liveSearch: false,\n    liveSearchPlaceholder: null,\n    liveSearchNormalize: false,\n    liveSearchStyle: 'contains',\n    actionsBox: false,\n    iconBase: 'glyphicon',\n    tickIcon: 'glyphicon-ok',\n    showTick: false,\n    template: {\n      caret: '<span class=\"caret\"></span>'\n    },\n    maxOptions: false,\n    mobile: false,\n    selectOnTab: false,\n    dropdownAlignRight: false,\n    windowPadding: 0\n  };\n\n  Selectpicker.prototype = {\n\n    constructor: Selectpicker,\n\n    init: function () {\n      var that = this,\n          id = this.$element.attr('id');\n\n      this.$element.addClass('bs-select-hidden');\n\n      // store originalIndex (key) and newIndex (value) in this.liObj for fast accessibility\n      // allows us to do this.$lis.eq(that.liObj[index]) instead of this.$lis.filter('[data-original-index=\"' + index + '\"]')\n      this.liObj = {};\n      this.multiple = this.$element.prop('multiple');\n      this.autofocus = this.$element.prop('autofocus');\n      this.$newElement = this.createView();\n      this.$element\n        .after(this.$newElement)\n        .appendTo(this.$newElement);\n      this.$button = this.$newElement.children('button');\n      this.$menu = this.$newElement.children('.dropdown-menu');\n      this.$menuInner = this.$menu.children('.inner');\n      this.$searchbox = this.$menu.find('input');\n\n      this.$element.removeClass('bs-select-hidden');\n\n      if (this.options.dropdownAlignRight === true) this.$menu.addClass('dropdown-menu-right');\n\n      if (typeof id !== 'undefined') {\n        this.$button.attr('data-id', id);\n        $('label[for=\"' + id + '\"]').click(function (e) {\n          e.preventDefault();\n          that.$button.focus();\n        });\n      }\n\n      this.checkDisabled();\n      this.clickListener();\n      if (this.options.liveSearch) this.liveSearchListener();\n      this.render();\n      this.setStyle();\n      this.setWidth();\n      if (this.options.container) this.selectPosition();\n      this.$menu.data('this', this);\n      this.$newElement.data('this', this);\n      if (this.options.mobile) this.mobile();\n\n      this.$newElement.on({\n        'hide.bs.dropdown': function (e) {\n          that.$menuInner.attr('aria-expanded', false);\n          that.$element.trigger('hide.bs.select', e);\n        },\n        'hidden.bs.dropdown': function (e) {\n          that.$element.trigger('hidden.bs.select', e);\n        },\n        'show.bs.dropdown': function (e) {\n          that.$menuInner.attr('aria-expanded', true);\n          that.$element.trigger('show.bs.select', e);\n        },\n        'shown.bs.dropdown': function (e) {\n          that.$element.trigger('shown.bs.select', e);\n        }\n      });\n\n      if (that.$element[0].hasAttribute('required')) {\n        this.$element.on('invalid', function () {\n          that.$button\n            .addClass('bs-invalid')\n            .focus();\n\n          that.$element.on({\n            'focus.bs.select': function () {\n              that.$button.focus();\n              that.$element.off('focus.bs.select');\n            },\n            'shown.bs.select': function () {\n              that.$element\n                .val(that.$element.val()) // set the value to hide the validation message in Chrome when menu is opened\n                .off('shown.bs.select');\n            },\n            'rendered.bs.select': function () {\n              // if select is no longer invalid, remove the bs-invalid class\n              if (this.validity.valid) that.$button.removeClass('bs-invalid');\n              that.$element.off('rendered.bs.select');\n            }\n          });\n        });\n      }\n\n      setTimeout(function () {\n        that.$element.trigger('loaded.bs.select');\n      });\n    },\n\n    createDropdown: function () {\n      // Options\n      // If we are multiple or showTick option is set, then add the show-tick class\n      var showTick = (this.multiple || this.options.showTick) ? ' show-tick' : '',\n          inputGroup = this.$element.parent().hasClass('input-group') ? ' input-group-btn' : '',\n          autofocus = this.autofocus ? ' autofocus' : '';\n      // Elements\n      var header = this.options.header ? '<div class=\"popover-title\"><button type=\"button\" class=\"close\" aria-hidden=\"true\">&times;</button>' + this.options.header + '</div>' : '';\n      var searchbox = this.options.liveSearch ?\n      '<div class=\"bs-searchbox\">' +\n      '<input type=\"text\" class=\"form-control\" autocomplete=\"off\"' +\n      (null === this.options.liveSearchPlaceholder ? '' : ' placeholder=\"' + htmlEscape(this.options.liveSearchPlaceholder) + '\"') + ' role=\"textbox\" aria-label=\"Search\">' +\n      '</div>'\n          : '';\n      var actionsbox = this.multiple && this.options.actionsBox ?\n      '<div class=\"bs-actionsbox\">' +\n      '<div class=\"btn-group btn-group-sm btn-block\">' +\n      '<button type=\"button\" class=\"actions-btn bs-select-all btn btn-default\">' +\n      this.options.selectAllText +\n      '</button>' +\n      '<button type=\"button\" class=\"actions-btn bs-deselect-all btn btn-default\">' +\n      this.options.deselectAllText +\n      '</button>' +\n      '</div>' +\n      '</div>'\n          : '';\n      var donebutton = this.multiple && this.options.doneButton ?\n      '<div class=\"bs-donebutton\">' +\n      '<div class=\"btn-group btn-block\">' +\n      '<button type=\"button\" class=\"btn btn-sm btn-default\">' +\n      this.options.doneButtonText +\n      '</button>' +\n      '</div>' +\n      '</div>'\n          : '';\n      var drop =\n          '<div class=\"btn-group bootstrap-select' + showTick + inputGroup + '\">' +\n          '<button type=\"button\" class=\"' + this.options.styleBase + ' dropdown-toggle\" data-toggle=\"dropdown\"' + autofocus + ' role=\"button\">' +\n          '<span class=\"filter-option pull-left\"></span>&nbsp;' +\n          '<span class=\"bs-caret\">' +\n          this.options.template.caret +\n          '</span>' +\n          '</button>' +\n          '<div class=\"dropdown-menu open\" role=\"combobox\">' +\n          header +\n          searchbox +\n          actionsbox +\n          '<ul class=\"dropdown-menu inner\" role=\"listbox\" aria-expanded=\"false\">' +\n          '</ul>' +\n          donebutton +\n          '</div>' +\n          '</div>';\n\n      return $(drop);\n    },\n\n    createView: function () {\n      var $drop = this.createDropdown(),\n          li = this.createLi();\n\n      $drop.find('ul')[0].innerHTML = li;\n      return $drop;\n    },\n\n    reloadLi: function () {\n      // rebuild\n      var li = this.createLi();\n      this.$menuInner[0].innerHTML = li;\n    },\n\n    createLi: function () {\n      var that = this,\n          _li = [],\n          optID = 0,\n          titleOption = document.createElement('option'),\n          liIndex = -1; // increment liIndex whenever a new <li> element is created to ensure liObj is correct\n\n      // Helper functions\n      /**\n       * @param content\n       * @param [index]\n       * @param [classes]\n       * @param [optgroup]\n       * @returns {string}\n       */\n      var generateLI = function (content, index, classes, optgroup) {\n        return '<li' +\n            ((typeof classes !== 'undefined' & '' !== classes) ? ' class=\"' + classes + '\"' : '') +\n            ((typeof index !== 'undefined' & null !== index) ? ' data-original-index=\"' + index + '\"' : '') +\n            ((typeof optgroup !== 'undefined' & null !== optgroup) ? 'data-optgroup=\"' + optgroup + '\"' : '') +\n            '>' + content + '</li>';\n      };\n\n      /**\n       * @param text\n       * @param [classes]\n       * @param [inline]\n       * @param [tokens]\n       * @returns {string}\n       */\n      var generateA = function (text, classes, inline, tokens) {\n        return '<a tabindex=\"0\"' +\n            (typeof classes !== 'undefined' ? ' class=\"' + classes + '\"' : '') +\n            (inline ? ' style=\"' + inline + '\"' : '') +\n            (that.options.liveSearchNormalize ? ' data-normalized-text=\"' + normalizeToBase(htmlEscape($(text).html())) + '\"' : '') +\n            (typeof tokens !== 'undefined' || tokens !== null ? ' data-tokens=\"' + tokens + '\"' : '') +\n            ' role=\"option\">' + text +\n            '<span class=\"' + that.options.iconBase + ' ' + that.options.tickIcon + ' check-mark\"></span>' +\n            '</a>';\n      };\n\n      if (this.options.title && !this.multiple) {\n        // this option doesn't create a new <li> element, but does add a new option, so liIndex is decreased\n        // since liObj is recalculated on every refresh, liIndex needs to be decreased even if the titleOption is already appended\n        liIndex--;\n\n        if (!this.$element.find('.bs-title-option').length) {\n          // Use native JS to prepend option (faster)\n          var element = this.$element[0];\n          titleOption.className = 'bs-title-option';\n          titleOption.innerHTML = this.options.title;\n          titleOption.value = '';\n          element.insertBefore(titleOption, element.firstChild);\n          // Check if selected or data-selected attribute is already set on an option. If not, select the titleOption option.\n          // the selected item may have been changed by user or programmatically before the bootstrap select plugin runs,\n          // if so, the select will have the data-selected attribute\n          var $opt = $(element.options[element.selectedIndex]);\n          if ($opt.attr('selected') === undefined && this.$element.data('selected') === undefined) {\n            titleOption.selected = true;\n          }\n        }\n      }\n\n      this.$element.find('option').each(function (index) {\n        var $this = $(this);\n\n        liIndex++;\n\n        if ($this.hasClass('bs-title-option')) return;\n\n        // Get the class and text for the option\n        var optionClass = this.className || '',\n            inline = this.style.cssText,\n            text = $this.data('content') ? $this.data('content') : $this.html(),\n            tokens = $this.data('tokens') ? $this.data('tokens') : null,\n            subtext = typeof $this.data('subtext') !== 'undefined' ? '<small class=\"text-muted\">' + $this.data('subtext') + '</small>' : '',\n            icon = typeof $this.data('icon') !== 'undefined' ? '<span class=\"' + that.options.iconBase + ' ' + $this.data('icon') + '\"></span> ' : '',\n            $parent = $this.parent(),\n            isOptgroup = $parent[0].tagName === 'OPTGROUP',\n            isOptgroupDisabled = isOptgroup && $parent[0].disabled,\n            isDisabled = this.disabled || isOptgroupDisabled;\n\n        if (icon !== '' && isDisabled) {\n          icon = '<span>' + icon + '</span>';\n        }\n\n        if (that.options.hideDisabled && (isDisabled && !isOptgroup || isOptgroupDisabled)) {\n          liIndex--;\n          return;\n        }\n\n        if (!$this.data('content')) {\n          // Prepend any icon and append any subtext to the main text.\n          text = icon + '<span class=\"text\">' + text + subtext + '</span>';\n        }\n\n        if (isOptgroup && $this.data('divider') !== true) {\n          if (that.options.hideDisabled && isDisabled) {\n            if ($parent.data('allOptionsDisabled') === undefined) {\n              var $options = $parent.children();\n              $parent.data('allOptionsDisabled', $options.filter(':disabled').length === $options.length);\n            }\n\n            if ($parent.data('allOptionsDisabled')) {\n              liIndex--;\n              return;\n            }\n          }\n\n          var optGroupClass = ' ' + $parent[0].className || '';\n\n          if ($this.index() === 0) { // Is it the first option of the optgroup?\n            optID += 1;\n\n            // Get the opt group label\n            var label = $parent[0].label,\n                labelSubtext = typeof $parent.data('subtext') !== 'undefined' ? '<small class=\"text-muted\">' + $parent.data('subtext') + '</small>' : '',\n                labelIcon = $parent.data('icon') ? '<span class=\"' + that.options.iconBase + ' ' + $parent.data('icon') + '\"></span> ' : '';\n\n            label = labelIcon + '<span class=\"text\">' + htmlEscape(label) + labelSubtext + '</span>';\n\n            if (index !== 0 && _li.length > 0) { // Is it NOT the first option of the select && are there elements in the dropdown?\n              liIndex++;\n              _li.push(generateLI('', null, 'divider', optID + 'div'));\n            }\n            liIndex++;\n            _li.push(generateLI(label, null, 'dropdown-header' + optGroupClass, optID));\n          }\n\n          if (that.options.hideDisabled && isDisabled) {\n            liIndex--;\n            return;\n          }\n\n          _li.push(generateLI(generateA(text, 'opt ' + optionClass + optGroupClass, inline, tokens), index, '', optID));\n        } else if ($this.data('divider') === true) {\n          _li.push(generateLI('', index, 'divider'));\n        } else if ($this.data('hidden') === true) {\n          _li.push(generateLI(generateA(text, optionClass, inline, tokens), index, 'hidden is-hidden'));\n        } else {\n          var showDivider = this.previousElementSibling && this.previousElementSibling.tagName === 'OPTGROUP';\n\n          // if previous element is not an optgroup and hideDisabled is true\n          if (!showDivider && that.options.hideDisabled) {\n            // get previous elements\n            var $prev = $(this).prevAll();\n\n            for (var i = 0; i < $prev.length; i++) {\n              // find the first element in the previous elements that is an optgroup\n              if ($prev[i].tagName === 'OPTGROUP') {\n                var optGroupDistance = 0;\n\n                // loop through the options in between the current option and the optgroup\n                // and check if they are hidden or disabled\n                for (var d = 0; d < i; d++) {\n                  var prevOption = $prev[d];\n                  if (prevOption.disabled || $(prevOption).data('hidden') === true) optGroupDistance++;\n                }\n\n                // if all of the options between the current option and the optgroup are hidden or disabled, show the divider\n                if (optGroupDistance === i) showDivider = true;\n\n                break;\n              }\n            }\n          }\n\n          if (showDivider) {\n            liIndex++;\n            _li.push(generateLI('', null, 'divider', optID + 'div'));\n          }\n          _li.push(generateLI(generateA(text, optionClass, inline, tokens), index));\n        }\n\n        that.liObj[index] = liIndex;\n      });\n\n      //If we are not multiple, we don't have a selected item, and we don't have a title, select the first element so something is set in the button\n      if (!this.multiple && this.$element.find('option:selected').length === 0 && !this.options.title) {\n        this.$element.find('option').eq(0).prop('selected', true).attr('selected', 'selected');\n      }\n\n      return _li.join('');\n    },\n\n    findLis: function () {\n      if (this.$lis == null) this.$lis = this.$menu.find('li');\n      return this.$lis;\n    },\n\n    /**\n     * @param [updateLi] defaults to true\n     */\n    render: function (updateLi) {\n      var that = this,\n          notDisabled;\n\n      //Update the LI to match the SELECT\n      if (updateLi !== false) {\n        this.$element.find('option').each(function (index) {\n          var $lis = that.findLis().eq(that.liObj[index]);\n\n          that.setDisabled(index, this.disabled || this.parentNode.tagName === 'OPTGROUP' && this.parentNode.disabled, $lis);\n          that.setSelected(index, this.selected, $lis);\n        });\n      }\n\n      this.togglePlaceholder();\n\n      this.tabIndex();\n\n      var selectedItems = this.$element.find('option').map(function () {\n        if (this.selected) {\n          if (that.options.hideDisabled && (this.disabled || this.parentNode.tagName === 'OPTGROUP' && this.parentNode.disabled)) return;\n\n          var $this = $(this),\n              icon = $this.data('icon') && that.options.showIcon ? '<i class=\"' + that.options.iconBase + ' ' + $this.data('icon') + '\"></i> ' : '',\n              subtext;\n\n          if (that.options.showSubtext && $this.data('subtext') && !that.multiple) {\n            subtext = ' <small class=\"text-muted\">' + $this.data('subtext') + '</small>';\n          } else {\n            subtext = '';\n          }\n          if (typeof $this.attr('title') !== 'undefined') {\n            return $this.attr('title');\n          } else if ($this.data('content') && that.options.showContent) {\n            return $this.data('content').toString();\n          } else {\n            return icon + $this.html() + subtext;\n          }\n        }\n      }).toArray();\n\n      //Fixes issue in IE10 occurring when no default option is selected and at least one option is disabled\n      //Convert all the values into a comma delimited string\n      var title = !this.multiple ? selectedItems[0] : selectedItems.join(this.options.multipleSeparator);\n\n      //If this is multi select, and the selectText type is count, the show 1 of 2 selected etc..\n      if (this.multiple && this.options.selectedTextFormat.indexOf('count') > -1) {\n        var max = this.options.selectedTextFormat.split('>');\n        if ((max.length > 1 && selectedItems.length > max[1]) || (max.length == 1 && selectedItems.length >= 2)) {\n          notDisabled = this.options.hideDisabled ? ', [disabled]' : '';\n          var totalCount = this.$element.find('option').not('[data-divider=\"true\"], [data-hidden=\"true\"]' + notDisabled).length,\n              tr8nText = (typeof this.options.countSelectedText === 'function') ? this.options.countSelectedText(selectedItems.length, totalCount) : this.options.countSelectedText;\n          title = tr8nText.replace('{0}', selectedItems.length.toString()).replace('{1}', totalCount.toString());\n        }\n      }\n\n      if (this.options.title == undefined) {\n        this.options.title = this.$element.attr('title');\n      }\n\n      if (this.options.selectedTextFormat == 'static') {\n        title = this.options.title;\n      }\n\n      //If we dont have a title, then use the default, or if nothing is set at all, use the not selected text\n      if (!title) {\n        title = typeof this.options.title !== 'undefined' ? this.options.title : this.options.noneSelectedText;\n      }\n\n      //strip all HTML tags and trim the result, then unescape any escaped tags\n      this.$button.attr('title', htmlUnescape($.trim(title.replace(/<[^>]*>?/g, ''))));\n      this.$button.children('.filter-option').html(title);\n\n      this.$element.trigger('rendered.bs.select');\n    },\n\n    /**\n     * @param [style]\n     * @param [status]\n     */\n    setStyle: function (style, status) {\n      if (this.$element.attr('class')) {\n        this.$newElement.addClass(this.$element.attr('class').replace(/selectpicker|mobile-device|bs-select-hidden|validate\\[.*\\]/gi, ''));\n      }\n\n      var buttonClass = style ? style : this.options.style;\n\n      if (status == 'add') {\n        this.$button.addClass(buttonClass);\n      } else if (status == 'remove') {\n        this.$button.removeClass(buttonClass);\n      } else {\n        this.$button.removeClass(this.options.style);\n        this.$button.addClass(buttonClass);\n      }\n    },\n\n    liHeight: function (refresh) {\n      if (!refresh && (this.options.size === false || this.sizeInfo)) return;\n\n      var newElement = document.createElement('div'),\n          menu = document.createElement('div'),\n          menuInner = document.createElement('ul'),\n          divider = document.createElement('li'),\n          li = document.createElement('li'),\n          a = document.createElement('a'),\n          text = document.createElement('span'),\n          header = this.options.header && this.$menu.find('.popover-title').length > 0 ? this.$menu.find('.popover-title')[0].cloneNode(true) : null,\n          search = this.options.liveSearch ? document.createElement('div') : null,\n          actions = this.options.actionsBox && this.multiple && this.$menu.find('.bs-actionsbox').length > 0 ? this.$menu.find('.bs-actionsbox')[0].cloneNode(true) : null,\n          doneButton = this.options.doneButton && this.multiple && this.$menu.find('.bs-donebutton').length > 0 ? this.$menu.find('.bs-donebutton')[0].cloneNode(true) : null;\n\n      text.className = 'text';\n      newElement.className = this.$menu[0].parentNode.className + ' open';\n      menu.className = 'dropdown-menu open';\n      menuInner.className = 'dropdown-menu inner';\n      divider.className = 'divider';\n\n      text.appendChild(document.createTextNode('Inner text'));\n      a.appendChild(text);\n      li.appendChild(a);\n      menuInner.appendChild(li);\n      menuInner.appendChild(divider);\n      if (header) menu.appendChild(header);\n      if (search) {\n        var input = document.createElement('input');\n        search.className = 'bs-searchbox';\n        input.className = 'form-control';\n        search.appendChild(input);\n        menu.appendChild(search);\n      }\n      if (actions) menu.appendChild(actions);\n      menu.appendChild(menuInner);\n      if (doneButton) menu.appendChild(doneButton);\n      newElement.appendChild(menu);\n\n      document.body.appendChild(newElement);\n\n      var liHeight = a.offsetHeight,\n          headerHeight = header ? header.offsetHeight : 0,\n          searchHeight = search ? search.offsetHeight : 0,\n          actionsHeight = actions ? actions.offsetHeight : 0,\n          doneButtonHeight = doneButton ? doneButton.offsetHeight : 0,\n          dividerHeight = $(divider).outerHeight(true),\n          // fall back to jQuery if getComputedStyle is not supported\n          menuStyle = typeof getComputedStyle === 'function' ? getComputedStyle(menu) : false,\n          $menu = menuStyle ? null : $(menu),\n          menuPadding = {\n            vert: parseInt(menuStyle ? menuStyle.paddingTop : $menu.css('paddingTop')) +\n                  parseInt(menuStyle ? menuStyle.paddingBottom : $menu.css('paddingBottom')) +\n                  parseInt(menuStyle ? menuStyle.borderTopWidth : $menu.css('borderTopWidth')) +\n                  parseInt(menuStyle ? menuStyle.borderBottomWidth : $menu.css('borderBottomWidth')),\n            horiz: parseInt(menuStyle ? menuStyle.paddingLeft : $menu.css('paddingLeft')) +\n                  parseInt(menuStyle ? menuStyle.paddingRight : $menu.css('paddingRight')) +\n                  parseInt(menuStyle ? menuStyle.borderLeftWidth : $menu.css('borderLeftWidth')) +\n                  parseInt(menuStyle ? menuStyle.borderRightWidth : $menu.css('borderRightWidth'))\n          },\n          menuExtras =  {\n            vert: menuPadding.vert +\n                  parseInt(menuStyle ? menuStyle.marginTop : $menu.css('marginTop')) +\n                  parseInt(menuStyle ? menuStyle.marginBottom : $menu.css('marginBottom')) + 2,\n            horiz: menuPadding.horiz +\n                  parseInt(menuStyle ? menuStyle.marginLeft : $menu.css('marginLeft')) +\n                  parseInt(menuStyle ? menuStyle.marginRight : $menu.css('marginRight')) + 2\n          }\n\n      document.body.removeChild(newElement);\n\n      this.sizeInfo = {\n        liHeight: liHeight,\n        headerHeight: headerHeight,\n        searchHeight: searchHeight,\n        actionsHeight: actionsHeight,\n        doneButtonHeight: doneButtonHeight,\n        dividerHeight: dividerHeight,\n        menuPadding: menuPadding,\n        menuExtras: menuExtras\n      };\n    },\n\n    setSize: function () {\n      this.findLis();\n      this.liHeight();\n\n      if (this.options.header) this.$menu.css('padding-top', 0);\n      if (this.options.size === false) return;\n\n      var that = this,\n          $menu = this.$menu,\n          $menuInner = this.$menuInner,\n          $window = $(window),\n          selectHeight = this.$newElement[0].offsetHeight,\n          selectWidth = this.$newElement[0].offsetWidth,\n          liHeight = this.sizeInfo['liHeight'],\n          headerHeight = this.sizeInfo['headerHeight'],\n          searchHeight = this.sizeInfo['searchHeight'],\n          actionsHeight = this.sizeInfo['actionsHeight'],\n          doneButtonHeight = this.sizeInfo['doneButtonHeight'],\n          divHeight = this.sizeInfo['dividerHeight'],\n          menuPadding = this.sizeInfo['menuPadding'],\n          menuExtras = this.sizeInfo['menuExtras'],\n          notDisabled = this.options.hideDisabled ? '.disabled' : '',\n          menuHeight,\n          menuWidth,\n          getHeight,\n          getWidth,\n          selectOffsetTop,\n          selectOffsetBot,\n          selectOffsetLeft,\n          selectOffsetRight,\n          getPos = function() {\n            var pos = that.$newElement.offset(),\n                $container = $(that.options.container),\n                containerPos;\n\n            if (that.options.container && !$container.is('body')) {\n              containerPos = $container.offset();\n              containerPos.top += parseInt($container.css('borderTopWidth'));\n              containerPos.left += parseInt($container.css('borderLeftWidth'));\n            } else {\n              containerPos = { top: 0, left: 0 };\n            }\n\n            var winPad = that.options.windowPadding;\n            selectOffsetTop = pos.top - containerPos.top - $window.scrollTop();\n            selectOffsetBot = $window.height() - selectOffsetTop - selectHeight - containerPos.top - winPad[2];\n            selectOffsetLeft = pos.left - containerPos.left - $window.scrollLeft();\n            selectOffsetRight = $window.width() - selectOffsetLeft - selectWidth - containerPos.left - winPad[1];\n            selectOffsetTop -= winPad[0];\n            selectOffsetLeft -= winPad[3];\n          };\n\n      getPos();\n\n      if (this.options.size === 'auto') {\n        var getSize = function () {\n          var minHeight,\n              hasClass = function (className, include) {\n                return function (element) {\n                    if (include) {\n                        return (element.classList ? element.classList.contains(className) : $(element).hasClass(className));\n                    } else {\n                        return !(element.classList ? element.classList.contains(className) : $(element).hasClass(className));\n                    }\n                };\n              },\n              lis = that.$menuInner[0].getElementsByTagName('li'),\n              lisVisible = Array.prototype.filter ? Array.prototype.filter.call(lis, hasClass('hidden', false)) : that.$lis.not('.hidden'),\n              optGroup = Array.prototype.filter ? Array.prototype.filter.call(lisVisible, hasClass('dropdown-header', true)) : lisVisible.filter('.dropdown-header');\n\n          getPos();\n          menuHeight = selectOffsetBot - menuExtras.vert;\n          menuWidth = selectOffsetRight - menuExtras.horiz;\n\n          if (that.options.container) {\n            if (!$menu.data('height')) $menu.data('height', $menu.height());\n            getHeight = $menu.data('height');\n\n            if (!$menu.data('width')) $menu.data('width', $menu.width());\n            getWidth = $menu.data('width');\n          } else {\n            getHeight = $menu.height();\n            getWidth = $menu.width();\n          }\n\n          if (that.options.dropupAuto) {\n            that.$newElement.toggleClass('dropup', selectOffsetTop > selectOffsetBot && (menuHeight - menuExtras.vert) < getHeight);\n          }\n\n          if (that.$newElement.hasClass('dropup')) {\n            menuHeight = selectOffsetTop - menuExtras.vert;\n          }\n\n          if (that.options.dropdownAlignRight === 'auto') {\n            $menu.toggleClass('dropdown-menu-right', selectOffsetLeft > selectOffsetRight && (menuWidth - menuExtras.horiz) < (getWidth - selectWidth));\n          }\n\n          if ((lisVisible.length + optGroup.length) > 3) {\n            minHeight = liHeight * 3 + menuExtras.vert - 2;\n          } else {\n            minHeight = 0;\n          }\n\n          $menu.css({\n            'max-height': menuHeight + 'px',\n            'overflow': 'hidden',\n            'min-height': minHeight + headerHeight + searchHeight + actionsHeight + doneButtonHeight + 'px'\n          });\n          $menuInner.css({\n            'max-height': menuHeight - headerHeight - searchHeight - actionsHeight - doneButtonHeight - menuPadding.vert + 'px',\n            'overflow-y': 'auto',\n            'min-height': Math.max(minHeight - menuPadding.vert, 0) + 'px'\n          });\n        };\n        getSize();\n        this.$searchbox.off('input.getSize propertychange.getSize').on('input.getSize propertychange.getSize', getSize);\n        $window.off('resize.getSize scroll.getSize').on('resize.getSize scroll.getSize', getSize);\n      } else if (this.options.size && this.options.size != 'auto' && this.$lis.not(notDisabled).length > this.options.size) {\n        var optIndex = this.$lis.not('.divider').not(notDisabled).children().slice(0, this.options.size).last().parent().index(),\n            divLength = this.$lis.slice(0, optIndex + 1).filter('.divider').length;\n        menuHeight = liHeight * this.options.size + divLength * divHeight + menuPadding.vert;\n\n        if (that.options.container) {\n          if (!$menu.data('height')) $menu.data('height', $menu.height());\n          getHeight = $menu.data('height');\n        } else {\n          getHeight = $menu.height();\n        }\n\n        if (that.options.dropupAuto) {\n          //noinspection JSUnusedAssignment\n          this.$newElement.toggleClass('dropup', selectOffsetTop > selectOffsetBot && (menuHeight - menuExtras.vert) < getHeight);\n        }\n        $menu.css({\n          'max-height': menuHeight + headerHeight + searchHeight + actionsHeight + doneButtonHeight + 'px',\n          'overflow': 'hidden',\n          'min-height': ''\n        });\n        $menuInner.css({\n          'max-height': menuHeight - menuPadding.vert + 'px',\n          'overflow-y': 'auto',\n          'min-height': ''\n        });\n      }\n    },\n\n    setWidth: function () {\n      if (this.options.width === 'auto') {\n        this.$menu.css('min-width', '0');\n\n        // Get correct width if element is hidden\n        var $selectClone = this.$menu.parent().clone().appendTo('body'),\n            $selectClone2 = this.options.container ? this.$newElement.clone().appendTo('body') : $selectClone,\n            ulWidth = $selectClone.children('.dropdown-menu').outerWidth(),\n            btnWidth = $selectClone2.css('width', 'auto').children('button').outerWidth();\n\n        $selectClone.remove();\n        $selectClone2.remove();\n\n        // Set width to whatever's larger, button title or longest option\n        this.$newElement.css('width', Math.max(ulWidth, btnWidth) + 'px');\n      } else if (this.options.width === 'fit') {\n        // Remove inline min-width so width can be changed from 'auto'\n        this.$menu.css('min-width', '');\n        this.$newElement.css('width', '').addClass('fit-width');\n      } else if (this.options.width) {\n        // Remove inline min-width so width can be changed from 'auto'\n        this.$menu.css('min-width', '');\n        this.$newElement.css('width', this.options.width);\n      } else {\n        // Remove inline min-width/width so width can be changed\n        this.$menu.css('min-width', '');\n        this.$newElement.css('width', '');\n      }\n      // Remove fit-width class if width is changed programmatically\n      if (this.$newElement.hasClass('fit-width') && this.options.width !== 'fit') {\n        this.$newElement.removeClass('fit-width');\n      }\n    },\n\n    selectPosition: function () {\n      this.$bsContainer = $('<div class=\"bs-container\" />');\n\n      var that = this,\n          $container = $(this.options.container),\n          pos,\n          containerPos,\n          actualHeight,\n          getPlacement = function ($element) {\n            that.$bsContainer.addClass($element.attr('class').replace(/form-control|fit-width/gi, '')).toggleClass('dropup', $element.hasClass('dropup'));\n            pos = $element.offset();\n\n            if (!$container.is('body')) {\n              containerPos = $container.offset();\n              containerPos.top += parseInt($container.css('borderTopWidth')) - $container.scrollTop();\n              containerPos.left += parseInt($container.css('borderLeftWidth')) - $container.scrollLeft();\n            } else {\n              containerPos = { top: 0, left: 0 };\n            }\n\n            actualHeight = $element.hasClass('dropup') ? 0 : $element[0].offsetHeight;\n\n            that.$bsContainer.css({\n              'top': pos.top - containerPos.top + actualHeight,\n              'left': pos.left - containerPos.left,\n              'width': $element[0].offsetWidth\n            });\n          };\n\n      this.$button.on('click', function () {\n        var $this = $(this);\n\n        if (that.isDisabled()) {\n          return;\n        }\n\n        getPlacement(that.$newElement);\n\n        that.$bsContainer\n          .appendTo(that.options.container)\n          .toggleClass('open', !$this.hasClass('open'))\n          .append(that.$menu);\n      });\n\n      $(window).on('resize scroll', function () {\n        getPlacement(that.$newElement);\n      });\n\n      this.$element.on('hide.bs.select', function () {\n        that.$menu.data('height', that.$menu.height());\n        that.$bsContainer.detach();\n      });\n    },\n\n    /**\n     * @param {number} index - the index of the option that is being changed\n     * @param {boolean} selected - true if the option is being selected, false if being deselected\n     * @param {JQuery} $lis - the 'li' element that is being modified\n     */\n    setSelected: function (index, selected, $lis) {\n      if (!$lis) {\n        this.togglePlaceholder(); // check if setSelected is being called by changing the value of the select\n        $lis = this.findLis().eq(this.liObj[index]);\n      }\n\n      $lis.toggleClass('selected', selected).find('a').attr('aria-selected', selected);\n    },\n\n    /**\n     * @param {number} index - the index of the option that is being disabled\n     * @param {boolean} disabled - true if the option is being disabled, false if being enabled\n     * @param {JQuery} $lis - the 'li' element that is being modified\n     */\n    setDisabled: function (index, disabled, $lis) {\n      if (!$lis) {\n        $lis = this.findLis().eq(this.liObj[index]);\n      }\n\n      if (disabled) {\n        $lis.addClass('disabled').children('a').attr('href', '#').attr('tabindex', -1).attr('aria-disabled', true);\n      } else {\n        $lis.removeClass('disabled').children('a').removeAttr('href').attr('tabindex', 0).attr('aria-disabled', false);\n      }\n    },\n\n    isDisabled: function () {\n      return this.$element[0].disabled;\n    },\n\n    checkDisabled: function () {\n      var that = this;\n\n      if (this.isDisabled()) {\n        this.$newElement.addClass('disabled');\n        this.$button.addClass('disabled').attr('tabindex', -1).attr('aria-disabled', true);\n      } else {\n        if (this.$button.hasClass('disabled')) {\n          this.$newElement.removeClass('disabled');\n          this.$button.removeClass('disabled').attr('aria-disabled', false);\n        }\n\n        if (this.$button.attr('tabindex') == -1 && !this.$element.data('tabindex')) {\n          this.$button.removeAttr('tabindex');\n        }\n      }\n\n      this.$button.click(function () {\n        return !that.isDisabled();\n      });\n    },\n\n    togglePlaceholder: function () {\n      var value = this.$element.val();\n      this.$button.toggleClass('bs-placeholder', value === null || value === '' || (value.constructor === Array && value.length === 0));\n    },\n\n    tabIndex: function () {\n      if (this.$element.data('tabindex') !== this.$element.attr('tabindex') && \n        (this.$element.attr('tabindex') !== -98 && this.$element.attr('tabindex') !== '-98')) {\n        this.$element.data('tabindex', this.$element.attr('tabindex'));\n        this.$button.attr('tabindex', this.$element.data('tabindex'));\n      }\n\n      this.$element.attr('tabindex', -98);\n    },\n\n    clickListener: function () {\n      var that = this,\n          $document = $(document);\n\n      $document.data('spaceSelect', false);\n\n      this.$button.on('keyup', function (e) {\n        if (/(32)/.test(e.keyCode.toString(10)) && $document.data('spaceSelect')) {\n            e.preventDefault();\n            $document.data('spaceSelect', false);\n        }\n      });\n\n      this.$button.on('click', function () {\n        that.setSize();\n      });\n\n      this.$element.on('shown.bs.select', function () {\n        if (!that.options.liveSearch && !that.multiple) {\n          that.$menuInner.find('.selected a').focus();\n        } else if (!that.multiple) {\n          var selectedIndex = that.liObj[that.$element[0].selectedIndex];\n\n          if (typeof selectedIndex !== 'number' || that.options.size === false) return;\n\n          // scroll to selected option\n          var offset = that.$lis.eq(selectedIndex)[0].offsetTop - that.$menuInner[0].offsetTop;\n          offset = offset - that.$menuInner[0].offsetHeight/2 + that.sizeInfo.liHeight/2;\n          that.$menuInner[0].scrollTop = offset;\n        }\n      });\n\n      this.$menuInner.on('click', 'li a', function (e) {\n        var $this = $(this),\n            clickedIndex = $this.parent().data('originalIndex'),\n            prevValue = that.$element.val(),\n            prevIndex = that.$element.prop('selectedIndex'),\n            triggerChange = true;\n\n        // Don't close on multi choice menu\n        if (that.multiple && that.options.maxOptions !== 1) {\n          e.stopPropagation();\n        }\n\n        e.preventDefault();\n\n        //Don't run if we have been disabled\n        if (!that.isDisabled() && !$this.parent().hasClass('disabled')) {\n          var $options = that.$element.find('option'),\n              $option = $options.eq(clickedIndex),\n              state = $option.prop('selected'),\n              $optgroup = $option.parent('optgroup'),\n              maxOptions = that.options.maxOptions,\n              maxOptionsGrp = $optgroup.data('maxOptions') || false;\n\n          if (!that.multiple) { // Deselect all others if not multi select box\n            $options.prop('selected', false);\n            $option.prop('selected', true);\n            that.$menuInner.find('.selected').removeClass('selected').find('a').attr('aria-selected', false);\n            that.setSelected(clickedIndex, true);\n          } else { // Toggle the one we have chosen if we are multi select.\n            $option.prop('selected', !state);\n            that.setSelected(clickedIndex, !state);\n            $this.blur();\n\n            if (maxOptions !== false || maxOptionsGrp !== false) {\n              var maxReached = maxOptions < $options.filter(':selected').length,\n                  maxReachedGrp = maxOptionsGrp < $optgroup.find('option:selected').length;\n\n              if ((maxOptions && maxReached) || (maxOptionsGrp && maxReachedGrp)) {\n                if (maxOptions && maxOptions == 1) {\n                  $options.prop('selected', false);\n                  $option.prop('selected', true);\n                  that.$menuInner.find('.selected').removeClass('selected');\n                  that.setSelected(clickedIndex, true);\n                } else if (maxOptionsGrp && maxOptionsGrp == 1) {\n                  $optgroup.find('option:selected').prop('selected', false);\n                  $option.prop('selected', true);\n                  var optgroupID = $this.parent().data('optgroup');\n                  that.$menuInner.find('[data-optgroup=\"' + optgroupID + '\"]').removeClass('selected');\n                  that.setSelected(clickedIndex, true);\n                } else {\n                  var maxOptionsText = typeof that.options.maxOptionsText === 'string' ? [that.options.maxOptionsText, that.options.maxOptionsText] : that.options.maxOptionsText,\n                      maxOptionsArr = typeof maxOptionsText === 'function' ? maxOptionsText(maxOptions, maxOptionsGrp) : maxOptionsText,\n                      maxTxt = maxOptionsArr[0].replace('{n}', maxOptions),\n                      maxTxtGrp = maxOptionsArr[1].replace('{n}', maxOptionsGrp),\n                      $notify = $('<div class=\"notify\"></div>');\n                  // If {var} is set in array, replace it\n                  /** @deprecated */\n                  if (maxOptionsArr[2]) {\n                    maxTxt = maxTxt.replace('{var}', maxOptionsArr[2][maxOptions > 1 ? 0 : 1]);\n                    maxTxtGrp = maxTxtGrp.replace('{var}', maxOptionsArr[2][maxOptionsGrp > 1 ? 0 : 1]);\n                  }\n\n                  $option.prop('selected', false);\n\n                  that.$menu.append($notify);\n\n                  if (maxOptions && maxReached) {\n                    $notify.append($('<div>' + maxTxt + '</div>'));\n                    triggerChange = false;\n                    that.$element.trigger('maxReached.bs.select');\n                  }\n\n                  if (maxOptionsGrp && maxReachedGrp) {\n                    $notify.append($('<div>' + maxTxtGrp + '</div>'));\n                    triggerChange = false;\n                    that.$element.trigger('maxReachedGrp.bs.select');\n                  }\n\n                  setTimeout(function () {\n                    that.setSelected(clickedIndex, false);\n                  }, 10);\n\n                  $notify.delay(750).fadeOut(300, function () {\n                    $(this).remove();\n                  });\n                }\n              }\n            }\n          }\n\n          if (!that.multiple || (that.multiple && that.options.maxOptions === 1)) {\n            that.$button.focus();\n          } else if (that.options.liveSearch) {\n            that.$searchbox.focus();\n          }\n\n          // Trigger select 'change'\n          if (triggerChange) {\n            if ((prevValue != that.$element.val() && that.multiple) || (prevIndex != that.$element.prop('selectedIndex') && !that.multiple)) {\n              // $option.prop('selected') is current option state (selected/unselected). state is previous option state.\n              changed_arguments = [clickedIndex, $option.prop('selected'), state];\n              that.$element\n                .triggerNative('change');\n            }\n          }\n        }\n      });\n\n      this.$menu.on('click', 'li.disabled a, .popover-title, .popover-title :not(.close)', function (e) {\n        if (e.currentTarget == this) {\n          e.preventDefault();\n          e.stopPropagation();\n          if (that.options.liveSearch && !$(e.target).hasClass('close')) {\n            that.$searchbox.focus();\n          } else {\n            that.$button.focus();\n          }\n        }\n      });\n\n      this.$menuInner.on('click', '.divider, .dropdown-header', function (e) {\n        e.preventDefault();\n        e.stopPropagation();\n        if (that.options.liveSearch) {\n          that.$searchbox.focus();\n        } else {\n          that.$button.focus();\n        }\n      });\n\n      this.$menu.on('click', '.popover-title .close', function () {\n        that.$button.click();\n      });\n\n      this.$searchbox.on('click', function (e) {\n        e.stopPropagation();\n      });\n\n      this.$menu.on('click', '.actions-btn', function (e) {\n        if (that.options.liveSearch) {\n          that.$searchbox.focus();\n        } else {\n          that.$button.focus();\n        }\n\n        e.preventDefault();\n        e.stopPropagation();\n\n        if ($(this).hasClass('bs-select-all')) {\n          that.selectAll();\n        } else {\n          that.deselectAll();\n        }\n      });\n\n      this.$element.change(function () {\n        that.render(false);\n        that.$element.trigger('changed.bs.select', changed_arguments);\n        changed_arguments = null;\n      });\n    },\n\n    liveSearchListener: function () {\n      var that = this,\n          $no_results = $('<li class=\"no-results\"></li>');\n\n      this.$button.on('click.dropdown.data-api', function () {\n        that.$menuInner.find('.active').removeClass('active');\n        if (!!that.$searchbox.val()) {\n          that.$searchbox.val('');\n          that.$lis.not('.is-hidden').removeClass('hidden');\n          if (!!$no_results.parent().length) $no_results.remove();\n        }\n        if (!that.multiple) that.$menuInner.find('.selected').addClass('active');\n        setTimeout(function () {\n          that.$searchbox.focus();\n        }, 10);\n      });\n\n      this.$searchbox.on('click.dropdown.data-api focus.dropdown.data-api touchend.dropdown.data-api', function (e) {\n        e.stopPropagation();\n      });\n\n      this.$searchbox.on('input propertychange', function () {\n        that.$lis.not('.is-hidden').removeClass('hidden');\n        that.$lis.filter('.active').removeClass('active');\n        $no_results.remove();\n\n        if (that.$searchbox.val()) {\n          var $searchBase = that.$lis.not('.is-hidden, .divider, .dropdown-header'),\n              $hideItems;\n          if (that.options.liveSearchNormalize) {\n            $hideItems = $searchBase.find('a').not(':a' + that._searchStyle() + '(\"' + normalizeToBase(that.$searchbox.val()) + '\")');\n          } else {\n            $hideItems = $searchBase.find('a').not(':' + that._searchStyle() + '(\"' + that.$searchbox.val() + '\")');\n          }\n\n          if ($hideItems.length === $searchBase.length) {\n            $no_results.html(that.options.noneResultsText.replace('{0}', '\"' + htmlEscape(that.$searchbox.val()) + '\"'));\n            that.$menuInner.append($no_results);\n            that.$lis.addClass('hidden');\n          } else {\n            $hideItems.parent().addClass('hidden');\n\n            var $lisVisible = that.$lis.not('.hidden'),\n                $foundDiv;\n\n            // hide divider if first or last visible, or if followed by another divider\n            $lisVisible.each(function (index) {\n              var $this = $(this);\n\n              if ($this.hasClass('divider')) {\n                if ($foundDiv === undefined) {\n                  $this.addClass('hidden');\n                } else {\n                  if ($foundDiv) $foundDiv.addClass('hidden');\n                  $foundDiv = $this;\n                }\n              } else if ($this.hasClass('dropdown-header') && $lisVisible.eq(index + 1).data('optgroup') !== $this.data('optgroup')) {\n                $this.addClass('hidden');\n              } else {\n                $foundDiv = null;\n              }\n            });\n            if ($foundDiv) $foundDiv.addClass('hidden');\n\n            $searchBase.not('.hidden').first().addClass('active');\n          }\n        }\n      });\n    },\n\n    _searchStyle: function () {\n      var styles = {\n        begins: 'ibegins',\n        startsWith: 'ibegins'\n      };\n\n      return styles[this.options.liveSearchStyle] || 'icontains';\n    },\n\n    val: function (value) {\n      if (typeof value !== 'undefined') {\n        this.$element.val(value);\n        this.render();\n\n        return this.$element;\n      } else {\n        return this.$element.val();\n      }\n    },\n\n    changeAll: function (status) {\n      if (!this.multiple) return;\n      if (typeof status === 'undefined') status = true;\n\n      this.findLis();\n\n      var $options = this.$element.find('option'),\n          $lisVisible = this.$lis.not('.divider, .dropdown-header, .disabled, .hidden'),\n          lisVisLen = $lisVisible.length,\n          selectedOptions = [];\n          \n      if (status) {\n        if ($lisVisible.filter('.selected').length === $lisVisible.length) return;\n      } else {\n        if ($lisVisible.filter('.selected').length === 0) return;\n      }\n          \n      $lisVisible.toggleClass('selected', status);\n\n      for (var i = 0; i < lisVisLen; i++) {\n        var origIndex = $lisVisible[i].getAttribute('data-original-index');\n        selectedOptions[selectedOptions.length] = $options.eq(origIndex)[0];\n      }\n\n      $(selectedOptions).prop('selected', status);\n\n      this.render(false);\n\n      this.togglePlaceholder();\n\n      this.$element\n        .triggerNative('change');\n    },\n\n    selectAll: function () {\n      return this.changeAll(true);\n    },\n\n    deselectAll: function () {\n      return this.changeAll(false);\n    },\n\n    toggle: function (e) {\n      e = e || window.event;\n\n      if (e) e.stopPropagation();\n\n      this.$button.trigger('click');\n    },\n\n    keydown: function (e) {\n      var $this = $(this),\n          $parent = $this.is('input') ? $this.parent().parent() : $this.parent(),\n          $items,\n          that = $parent.data('this'),\n          index,\n          next,\n          first,\n          last,\n          prev,\n          nextPrev,\n          prevIndex,\n          isActive,\n          selector = ':not(.disabled, .hidden, .dropdown-header, .divider)',\n          keyCodeMap = {\n            32: ' ',\n            48: '0',\n            49: '1',\n            50: '2',\n            51: '3',\n            52: '4',\n            53: '5',\n            54: '6',\n            55: '7',\n            56: '8',\n            57: '9',\n            59: ';',\n            65: 'a',\n            66: 'b',\n            67: 'c',\n            68: 'd',\n            69: 'e',\n            70: 'f',\n            71: 'g',\n            72: 'h',\n            73: 'i',\n            74: 'j',\n            75: 'k',\n            76: 'l',\n            77: 'm',\n            78: 'n',\n            79: 'o',\n            80: 'p',\n            81: 'q',\n            82: 'r',\n            83: 's',\n            84: 't',\n            85: 'u',\n            86: 'v',\n            87: 'w',\n            88: 'x',\n            89: 'y',\n            90: 'z',\n            96: '0',\n            97: '1',\n            98: '2',\n            99: '3',\n            100: '4',\n            101: '5',\n            102: '6',\n            103: '7',\n            104: '8',\n            105: '9'\n          };\n\n      if (that.options.liveSearch) $parent = $this.parent().parent();\n\n      if (that.options.container) $parent = that.$menu;\n\n      $items = $('[role=\"listbox\"] li', $parent);\n\n      isActive = that.$newElement.hasClass('open');\n\n      if (!isActive && (e.keyCode >= 48 && e.keyCode <= 57 || e.keyCode >= 96 && e.keyCode <= 105 || e.keyCode >= 65 && e.keyCode <= 90)) {\n        if (!that.options.container) {\n          that.setSize();\n          that.$menu.parent().addClass('open');\n          isActive = true;\n        } else {\n          that.$button.trigger('click');\n        }\n        that.$searchbox.focus();\n        return;\n      }\n\n      if (that.options.liveSearch) {\n        if (/(^9$|27)/.test(e.keyCode.toString(10)) && isActive) {\n          e.preventDefault();\n          e.stopPropagation();\n          that.$menuInner.click();\n          that.$button.focus();\n        }\n        // $items contains li elements when liveSearch is enabled\n        $items = $('[role=\"listbox\"] li' + selector, $parent);\n        if (!$this.val() && !/(38|40)/.test(e.keyCode.toString(10))) {\n          if ($items.filter('.active').length === 0) {\n            $items = that.$menuInner.find('li');\n            if (that.options.liveSearchNormalize) {\n              $items = $items.filter(':a' + that._searchStyle() + '(' + normalizeToBase(keyCodeMap[e.keyCode]) + ')');\n            } else {\n              $items = $items.filter(':' + that._searchStyle() + '(' + keyCodeMap[e.keyCode] + ')');\n            }\n          }\n        }\n      }\n\n      if (!$items.length) return;\n\n      if (/(38|40)/.test(e.keyCode.toString(10))) {\n        index = $items.index($items.find('a').filter(':focus').parent());\n        first = $items.filter(selector).first().index();\n        last = $items.filter(selector).last().index();\n        next = $items.eq(index).nextAll(selector).eq(0).index();\n        prev = $items.eq(index).prevAll(selector).eq(0).index();\n        nextPrev = $items.eq(next).prevAll(selector).eq(0).index();\n\n        if (that.options.liveSearch) {\n          $items.each(function (i) {\n            if (!$(this).hasClass('disabled')) {\n              $(this).data('index', i);\n            }\n          });\n          index = $items.index($items.filter('.active'));\n          first = $items.first().data('index');\n          last = $items.last().data('index');\n          next = $items.eq(index).nextAll().eq(0).data('index');\n          prev = $items.eq(index).prevAll().eq(0).data('index');\n          nextPrev = $items.eq(next).prevAll().eq(0).data('index');\n        }\n\n        prevIndex = $this.data('prevIndex');\n\n        if (e.keyCode == 38) {\n          if (that.options.liveSearch) index--;\n          if (index != nextPrev && index > prev) index = prev;\n          if (index < first) index = first;\n          if (index == prevIndex) index = last;\n        } else if (e.keyCode == 40) {\n          if (that.options.liveSearch) index++;\n          if (index == -1) index = 0;\n          if (index != nextPrev && index < next) index = next;\n          if (index > last) index = last;\n          if (index == prevIndex) index = first;\n        }\n\n        $this.data('prevIndex', index);\n\n        if (!that.options.liveSearch) {\n          $items.eq(index).children('a').focus();\n        } else {\n          e.preventDefault();\n          if (!$this.hasClass('dropdown-toggle')) {\n            $items.removeClass('active').eq(index).addClass('active').children('a').focus();\n            $this.focus();\n          }\n        }\n\n      } else if (!$this.is('input')) {\n        var keyIndex = [],\n            count,\n            prevKey;\n\n        $items.each(function () {\n          if (!$(this).hasClass('disabled')) {\n            if ($.trim($(this).children('a').text().toLowerCase()).substring(0, 1) == keyCodeMap[e.keyCode]) {\n              keyIndex.push($(this).index());\n            }\n          }\n        });\n\n        count = $(document).data('keycount');\n        count++;\n        $(document).data('keycount', count);\n\n        prevKey = $.trim($(':focus').text().toLowerCase()).substring(0, 1);\n\n        if (prevKey != keyCodeMap[e.keyCode]) {\n          count = 1;\n          $(document).data('keycount', count);\n        } else if (count >= keyIndex.length) {\n          $(document).data('keycount', 0);\n          if (count > keyIndex.length) count = 1;\n        }\n\n        $items.eq(keyIndex[count - 1]).children('a').focus();\n      }\n\n      // Select focused option if \"Enter\", \"Spacebar\" or \"Tab\" (when selectOnTab is true) are pressed inside the menu.\n      if ((/(13|32)/.test(e.keyCode.toString(10)) || (/(^9$)/.test(e.keyCode.toString(10)) && that.options.selectOnTab)) && isActive) {\n        if (!/(32)/.test(e.keyCode.toString(10))) e.preventDefault();\n        if (!that.options.liveSearch) {\n          var elem = $(':focus');\n          elem.click();\n          // Bring back focus for multiselects\n          elem.focus();\n          // Prevent screen from scrolling if the user hit the spacebar\n          e.preventDefault();\n          // Fixes spacebar selection of dropdown items in FF & IE\n          $(document).data('spaceSelect', true);\n        } else if (!/(32)/.test(e.keyCode.toString(10))) {\n          that.$menuInner.find('.active a').click();\n          $this.focus();\n        }\n        $(document).data('keycount', 0);\n      }\n\n      if ((/(^9$|27)/.test(e.keyCode.toString(10)) && isActive && (that.multiple || that.options.liveSearch)) || (/(27)/.test(e.keyCode.toString(10)) && !isActive)) {\n        that.$menu.parent().removeClass('open');\n        if (that.options.container) that.$newElement.removeClass('open');\n        that.$button.focus();\n      }\n    },\n\n    mobile: function () {\n      this.$element.addClass('mobile-device');\n    },\n\n    refresh: function () {\n      this.$lis = null;\n      this.liObj = {};\n      this.reloadLi();\n      this.render();\n      this.checkDisabled();\n      this.liHeight(true);\n      this.setStyle();\n      this.setWidth();\n      if (this.$lis) this.$searchbox.trigger('propertychange');\n\n      this.$element.trigger('refreshed.bs.select');\n    },\n\n    hide: function () {\n      this.$newElement.hide();\n    },\n\n    show: function () {\n      this.$newElement.show();\n    },\n\n    remove: function () {\n      this.$newElement.remove();\n      this.$element.remove();\n    },\n\n    destroy: function () {\n      this.$newElement.before(this.$element).remove();\n\n      if (this.$bsContainer) {\n        this.$bsContainer.remove();\n      } else {\n        this.$menu.remove();\n      }\n\n      this.$element\n        .off('.bs.select')\n        .removeData('selectpicker')\n        .removeClass('bs-select-hidden selectpicker');\n    }\n  };\n\n  // SELECTPICKER PLUGIN DEFINITION\n  // ==============================\n  function Plugin(option) {\n    // get the args of the outer function..\n    var args = arguments;\n    // The arguments of the function are explicitly re-defined from the argument list, because the shift causes them\n    // to get lost/corrupted in android 2.3 and IE9 #715 #775\n    var _option = option;\n\n    [].shift.apply(args);\n\n    var value;\n    var chain = this.each(function () {\n      var $this = $(this);\n      if ($this.is('select')) {\n        var data = $this.data('selectpicker'),\n            options = typeof _option == 'object' && _option;\n\n        if (!data) {\n          var config = $.extend({}, Selectpicker.DEFAULTS, $.fn.selectpicker.defaults || {}, $this.data(), options);\n          config.template = $.extend({}, Selectpicker.DEFAULTS.template, ($.fn.selectpicker.defaults ? $.fn.selectpicker.defaults.template : {}), $this.data().template, options.template);\n          $this.data('selectpicker', (data = new Selectpicker(this, config)));\n        } else if (options) {\n          for (var i in options) {\n            if (options.hasOwnProperty(i)) {\n              data.options[i] = options[i];\n            }\n          }\n        }\n\n        if (typeof _option == 'string') {\n          if (data[_option] instanceof Function) {\n            value = data[_option].apply(data, args);\n          } else {\n            value = data.options[_option];\n          }\n        }\n      }\n    });\n\n    if (typeof value !== 'undefined') {\n      //noinspection JSUnusedAssignment\n      return value;\n    } else {\n      return chain;\n    }\n  }\n\n  var old = $.fn.selectpicker;\n  $.fn.selectpicker = Plugin;\n  $.fn.selectpicker.Constructor = Selectpicker;\n\n  // SELECTPICKER NO CONFLICT\n  // ========================\n  $.fn.selectpicker.noConflict = function () {\n    $.fn.selectpicker = old;\n    return this;\n  };\n\n  $(document)\n      .data('keycount', 0)\n      .on('keydown.bs.select', '.bootstrap-select [data-toggle=dropdown], .bootstrap-select [role=\"listbox\"], .bs-searchbox input', Selectpicker.prototype.keydown)\n      .on('focusin.modal', '.bootstrap-select [data-toggle=dropdown], .bootstrap-select [role=\"listbox\"], .bs-searchbox input', function (e) {\n        e.stopPropagation();\n      });\n\n  // SELECTPICKER DATA-API\n  // =====================\n  $(window).on('load.bs.select.data-api', function () {\n    $('.selectpicker').each(function () {\n      var $selectpicker = $(this);\n      Plugin.call($selectpicker, $selectpicker.data());\n    })\n  });\n})(jQuery);\n\n\n}));\n"
  },
  {
    "path": "app_backend/static/plugin/bootstrap-select-1.12.2/docs/docs/dist/js/i18n/defaults-ar_AR.js",
    "content": "/*!\n * Bootstrap-select v1.12.2 (http://silviomoreto.github.io/bootstrap-select)\n *\n * Copyright 2013-2017 bootstrap-select\n * Licensed under MIT (https://github.com/silviomoreto/bootstrap-select/blob/master/LICENSE)\n */\n\n(function (root, factory) {\n  if (typeof define === 'function' && define.amd) {\n    // AMD. Register as an anonymous module unless amdModuleId is set\n    define([\"jquery\"], function (a0) {\n      return (factory(a0));\n    });\n  } else if (typeof module === 'object' && module.exports) {\n    // Node. Does not work with strict CommonJS, but\n    // only CommonJS-like environments that support module.exports,\n    // like Node.\n    module.exports = factory(require(\"jquery\"));\n  } else {\n    factory(root[\"jQuery\"]);\n  }\n}(this, function (jQuery) {\n\n/*!\n * Translated default messages for bootstrap-select.\n * Locale: AR (Arabic)\n * Author: Yasser Lotfy <y_l@alive.com>\n */\n(function ($) {\n  $.fn.selectpicker.defaults = {\n    noneSelectedText: 'لم يتم إختيار شئ',\n    noneResultsText: 'لا توجد نتائج مطابقة لـ {0}',\n    countSelectedText: function (numSelected, numTotal) {\n      return (numSelected == 1) ? \"{0} خيار تم إختياره\" : \"{0} خيارات تمت إختيارها\";\n    },\n    maxOptionsText: function (numAll, numGroup) {\n      return [\n        (numAll == 1) ? 'تخطى الحد المسموح ({n} خيار بحد أقصى)' : 'تخطى الحد المسموح ({n} خيارات بحد أقصى)',\n        (numGroup == 1) ? 'تخطى الحد المسموح للمجموعة ({n} خيار بحد أقصى)' : 'تخطى الحد المسموح للمجموعة ({n} خيارات بحد أقصى)'\n      ];\n    },\n    selectAllText: 'إختيار الجميع',\n    deselectAllText: 'إلغاء إختيار الجميع',\n    multipleSeparator: '، '\n  };\n})(jQuery);\n\n\n}));\n"
  },
  {
    "path": "app_backend/static/plugin/bootstrap-select-1.12.2/docs/docs/dist/js/i18n/defaults-bg_BG.js",
    "content": "/*!\n * Bootstrap-select v1.12.2 (http://silviomoreto.github.io/bootstrap-select)\n *\n * Copyright 2013-2017 bootstrap-select\n * Licensed under MIT (https://github.com/silviomoreto/bootstrap-select/blob/master/LICENSE)\n */\n\n(function (root, factory) {\n  if (typeof define === 'function' && define.amd) {\n    // AMD. Register as an anonymous module unless amdModuleId is set\n    define([\"jquery\"], function (a0) {\n      return (factory(a0));\n    });\n  } else if (typeof module === 'object' && module.exports) {\n    // Node. Does not work with strict CommonJS, but\n    // only CommonJS-like environments that support module.exports,\n    // like Node.\n    module.exports = factory(require(\"jquery\"));\n  } else {\n    factory(root[\"jQuery\"]);\n  }\n}(this, function (jQuery) {\n\n(function ($) {\n  $.fn.selectpicker.defaults = {\n    noneSelectedText: 'Нищо избрано',\n    noneResultsText: 'Няма резултат за {0}',\n    countSelectedText: function (numSelected, numTotal) {\n      return (numSelected == 1) ? \"{0} избран елемент\" : \"{0} избрани елемента\";\n    },\n    maxOptionsText: function (numAll, numGroup) {\n      return [\n        (numAll == 1) ? 'Лимита е достигнат ({n} елемент максимум)' : 'Лимита е достигнат ({n} елемента максимум)',\n        (numGroup == 1) ? 'Груповия лимит е достигнат ({n} елемент максимум)' : 'Груповия лимит е достигнат ({n} елемента максимум)'\n      ];\n    },\n    selectAllText: 'Избери всички',\n    deselectAllText: 'Размаркирай всички',\n    multipleSeparator: ', '\n  };\n})(jQuery);\n\n\n}));\n"
  },
  {
    "path": "app_backend/static/plugin/bootstrap-select-1.12.2/docs/docs/dist/js/i18n/defaults-cro_CRO.js",
    "content": "/*!\n * Bootstrap-select v1.12.2 (http://silviomoreto.github.io/bootstrap-select)\n *\n * Copyright 2013-2017 bootstrap-select\n * Licensed under MIT (https://github.com/silviomoreto/bootstrap-select/blob/master/LICENSE)\n */\n\n(function (root, factory) {\n  if (typeof define === 'function' && define.amd) {\n    // AMD. Register as an anonymous module unless amdModuleId is set\n    define([\"jquery\"], function (a0) {\n      return (factory(a0));\n    });\n  } else if (typeof module === 'object' && module.exports) {\n    // Node. Does not work with strict CommonJS, but\n    // only CommonJS-like environments that support module.exports,\n    // like Node.\n    module.exports = factory(require(\"jquery\"));\n  } else {\n    factory(root[\"jQuery\"]);\n  }\n}(this, function (jQuery) {\n\n(function ($) {\n  $.fn.selectpicker.defaults = {\n    noneSelectedText: 'Odaberite stavku',\n    noneResultsText: 'Nema rezultata pretrage {0}',\n    countSelectedText: function (numSelected, numTotal) {\n      return (numSelected == 1) ? \"{0} stavka selektirana\" : \"{0} stavke selektirane\";\n    },\n    maxOptionsText: function (numAll, numGroup) {\n      return [\n        (numAll == 1) ? 'Limit je postignut ({n} stvar maximalno)' : 'Limit je postignut ({n} stavke maksimalno)',\n        (numGroup == 1) ? 'Grupni limit je postignut ({n} stvar maksimalno)' : 'Grupni limit je postignut ({n} stavke maksimalno)'\n      ];\n    },\n    selectAllText: 'Selektiraj sve',\n    deselectAllText: 'Deselektiraj sve',\n    multipleSeparator: ', '\n  };\n})(jQuery);\n\n\n}));\n"
  },
  {
    "path": "app_backend/static/plugin/bootstrap-select-1.12.2/docs/docs/dist/js/i18n/defaults-cs_CZ.js",
    "content": "/*!\n * Bootstrap-select v1.12.2 (http://silviomoreto.github.io/bootstrap-select)\n *\n * Copyright 2013-2017 bootstrap-select\n * Licensed under MIT (https://github.com/silviomoreto/bootstrap-select/blob/master/LICENSE)\n */\n\n(function (root, factory) {\n  if (typeof define === 'function' && define.amd) {\n    // AMD. Register as an anonymous module unless amdModuleId is set\n    define([\"jquery\"], function (a0) {\n      return (factory(a0));\n    });\n  } else if (typeof module === 'object' && module.exports) {\n    // Node. Does not work with strict CommonJS, but\n    // only CommonJS-like environments that support module.exports,\n    // like Node.\n    module.exports = factory(require(\"jquery\"));\n  } else {\n    factory(root[\"jQuery\"]);\n  }\n}(this, function (jQuery) {\n\n(function ($) {\n  $.fn.selectpicker.defaults = {\n    noneSelectedText: 'Nic není vybráno',\n    noneResultsText: 'Žádné výsledky {0}',\n    countSelectedText: 'Označeno {0} z {1}',\n    maxOptionsText: ['Limit překročen ({n} {var} max)', 'Limit skupiny překročen ({n} {var} max)', ['položek', 'položka']],\n    multipleSeparator: ', '\n  };\n})(jQuery);\n\n\n}));\n"
  },
  {
    "path": "app_backend/static/plugin/bootstrap-select-1.12.2/docs/docs/dist/js/i18n/defaults-da_DK.js",
    "content": "/*!\n * Bootstrap-select v1.12.2 (http://silviomoreto.github.io/bootstrap-select)\n *\n * Copyright 2013-2017 bootstrap-select\n * Licensed under MIT (https://github.com/silviomoreto/bootstrap-select/blob/master/LICENSE)\n */\n\n(function (root, factory) {\n  if (typeof define === 'function' && define.amd) {\n    // AMD. Register as an anonymous module unless amdModuleId is set\n    define([\"jquery\"], function (a0) {\n      return (factory(a0));\n    });\n  } else if (typeof module === 'object' && module.exports) {\n    // Node. Does not work with strict CommonJS, but\n    // only CommonJS-like environments that support module.exports,\n    // like Node.\n    module.exports = factory(require(\"jquery\"));\n  } else {\n    factory(root[\"jQuery\"]);\n  }\n}(this, function (jQuery) {\n\n(function ($) {\n  $.fn.selectpicker.defaults = {\n    noneSelectedText: 'Intet valgt',\n    noneResultsText: 'Ingen resultater fundet {0}',\n    countSelectedText: function (numSelected, numTotal) {\n      return (numSelected == 1) ? \"{0} valgt\" : \"{0} valgt\";\n    },\n    maxOptionsText: function (numAll, numGroup) {\n      return [\n        (numAll == 1) ? 'Begrænsning nået (max {n} valgt)' : 'Begrænsning nået (max {n} valgte)',\n        (numGroup == 1) ? 'Gruppe-begrænsning nået (max {n} valgt)' : 'Gruppe-begrænsning nået (max {n} valgte)'\n      ];\n    },\n    selectAllText: 'Markér alle',\n    deselectAllText: 'Afmarkér alle',\n    multipleSeparator: ', '\n  };\n})(jQuery);\n\n\n}));\n"
  },
  {
    "path": "app_backend/static/plugin/bootstrap-select-1.12.2/docs/docs/dist/js/i18n/defaults-de_DE.js",
    "content": "/*!\n * Bootstrap-select v1.12.2 (http://silviomoreto.github.io/bootstrap-select)\n *\n * Copyright 2013-2017 bootstrap-select\n * Licensed under MIT (https://github.com/silviomoreto/bootstrap-select/blob/master/LICENSE)\n */\n\n(function (root, factory) {\n  if (typeof define === 'function' && define.amd) {\n    // AMD. Register as an anonymous module unless amdModuleId is set\n    define([\"jquery\"], function (a0) {\n      return (factory(a0));\n    });\n  } else if (typeof module === 'object' && module.exports) {\n    // Node. Does not work with strict CommonJS, but\n    // only CommonJS-like environments that support module.exports,\n    // like Node.\n    module.exports = factory(require(\"jquery\"));\n  } else {\n    factory(root[\"jQuery\"]);\n  }\n}(this, function (jQuery) {\n\n(function ($) {\n  $.fn.selectpicker.defaults = {\n    noneSelectedText: 'Bitte wählen...',\n    noneResultsText: 'Keine Ergebnisse für {0}',\n    countSelectedText: function (numSelected, numTotal) {\n      return (numSelected == 1) ? \"{0} Element ausgewählt\" : \"{0} Elemente ausgewählt\";\n    },\n    maxOptionsText: function (numAll, numGroup) {\n      return [\n        (numAll == 1) ? 'Limit erreicht ({n} Element max.)' : 'Limit erreicht ({n} Elemente max.)',\n        (numGroup == 1) ? 'Gruppen-Limit erreicht ({n} Element max.)' : 'Gruppen-Limit erreicht ({n} Elemente max.)'\n      ];\n    },\n    selectAllText: 'Alles auswählen',\n    deselectAllText: 'Nichts auswählen',\n    multipleSeparator: ', '\n  };\n})(jQuery);\n\n\n}));\n"
  },
  {
    "path": "app_backend/static/plugin/bootstrap-select-1.12.2/docs/docs/dist/js/i18n/defaults-en_US.js",
    "content": "/*!\n * Bootstrap-select v1.12.2 (http://silviomoreto.github.io/bootstrap-select)\n *\n * Copyright 2013-2017 bootstrap-select\n * Licensed under MIT (https://github.com/silviomoreto/bootstrap-select/blob/master/LICENSE)\n */\n\n(function (root, factory) {\n  if (typeof define === 'function' && define.amd) {\n    // AMD. Register as an anonymous module unless amdModuleId is set\n    define([\"jquery\"], function (a0) {\n      return (factory(a0));\n    });\n  } else if (typeof module === 'object' && module.exports) {\n    // Node. Does not work with strict CommonJS, but\n    // only CommonJS-like environments that support module.exports,\n    // like Node.\n    module.exports = factory(require(\"jquery\"));\n  } else {\n    factory(root[\"jQuery\"]);\n  }\n}(this, function (jQuery) {\n\n(function ($) {\n  $.fn.selectpicker.defaults = {\n    noneSelectedText: 'Nothing selected',\n    noneResultsText: 'No results match {0}',\n    countSelectedText: function (numSelected, numTotal) {\n      return (numSelected == 1) ? \"{0} item selected\" : \"{0} items selected\";\n    },\n    maxOptionsText: function (numAll, numGroup) {\n      return [\n        (numAll == 1) ? 'Limit reached ({n} item max)' : 'Limit reached ({n} items max)',\n        (numGroup == 1) ? 'Group limit reached ({n} item max)' : 'Group limit reached ({n} items max)'\n      ];\n    },\n    selectAllText: 'Select All',\n    deselectAllText: 'Deselect All',\n    multipleSeparator: ', '\n  };\n})(jQuery);\n\n\n}));\n"
  },
  {
    "path": "app_backend/static/plugin/bootstrap-select-1.12.2/docs/docs/dist/js/i18n/defaults-es_CL.js",
    "content": "/*!\n * Bootstrap-select v1.12.2 (http://silviomoreto.github.io/bootstrap-select)\n *\n * Copyright 2013-2017 bootstrap-select\n * Licensed under MIT (https://github.com/silviomoreto/bootstrap-select/blob/master/LICENSE)\n */\n\n(function (root, factory) {\n  if (typeof define === 'function' && define.amd) {\n    // AMD. Register as an anonymous module unless amdModuleId is set\n    define([\"jquery\"], function (a0) {\n      return (factory(a0));\n    });\n  } else if (typeof module === 'object' && module.exports) {\n    // Node. Does not work with strict CommonJS, but\n    // only CommonJS-like environments that support module.exports,\n    // like Node.\n    module.exports = factory(require(\"jquery\"));\n  } else {\n    factory(root[\"jQuery\"]);\n  }\n}(this, function (jQuery) {\n\n(function ($) {\n  $.fn.selectpicker.defaults = {\n    noneSelectedText: 'No hay selección',\n    noneResultsText: 'No hay resultados {0}',\n    countSelectedText: 'Seleccionados {0} de {1}',\n    maxOptionsText: ['Límite alcanzado ({n} {var} max)', 'Límite del grupo alcanzado({n} {var} max)', ['elementos', 'element']],\n    multipleSeparator: ', ',\n    selectAllText: 'Seleccionar Todos',\n    deselectAllText: 'Desmarcar Todos'\n  };\n})(jQuery);\n\n\n}));\n"
  },
  {
    "path": "app_backend/static/plugin/bootstrap-select-1.12.2/docs/docs/dist/js/i18n/defaults-es_ES.js",
    "content": "/*!\n * Bootstrap-select v1.12.2 (http://silviomoreto.github.io/bootstrap-select)\n *\n * Copyright 2013-2017 bootstrap-select\n * Licensed under MIT (https://github.com/silviomoreto/bootstrap-select/blob/master/LICENSE)\n */\n\n(function (root, factory) {\n  if (typeof define === 'function' && define.amd) {\n    // AMD. Register as an anonymous module unless amdModuleId is set\n    define([\"jquery\"], function (a0) {\n      return (factory(a0));\n    });\n  } else if (typeof module === 'object' && module.exports) {\n    // Node. Does not work with strict CommonJS, but\n    // only CommonJS-like environments that support module.exports,\n    // like Node.\n    module.exports = factory(require(\"jquery\"));\n  } else {\n    factory(root[\"jQuery\"]);\n  }\n}(this, function (jQuery) {\n\n(function ($) {\n  $.fn.selectpicker.defaults = {\n    noneSelectedText: 'No hay selección',\n    noneResultsText: 'No hay resultados {0}',\n    countSelectedText: 'Seleccionados {0} de {1}',\n    maxOptionsText: ['Límite alcanzado ({n} {var} max)', 'Límite del grupo alcanzado({n} {var} max)', ['elementos', 'element']],\n    multipleSeparator: ', ',\n    selectAllText: 'Seleccionar Todos',\n    deselectAllText: 'Desmarcar Todos'\n  };\n})(jQuery);\n\n\n}));\n"
  },
  {
    "path": "app_backend/static/plugin/bootstrap-select-1.12.2/docs/docs/dist/js/i18n/defaults-eu.js",
    "content": "/*!\n * Bootstrap-select v1.12.2 (http://silviomoreto.github.io/bootstrap-select)\n *\n * Copyright 2013-2017 bootstrap-select\n * Licensed under MIT (https://github.com/silviomoreto/bootstrap-select/blob/master/LICENSE)\n */\n\n(function (root, factory) {\n  if (typeof define === 'function' && define.amd) {\n    // AMD. Register as an anonymous module unless amdModuleId is set\n    define([\"jquery\"], function (a0) {\n      return (factory(a0));\n    });\n  } else if (typeof module === 'object' && module.exports) {\n    // Node. Does not work with strict CommonJS, but\n    // only CommonJS-like environments that support module.exports,\n    // like Node.\n    module.exports = factory(require(\"jquery\"));\n  } else {\n    factory(root[\"jQuery\"]);\n  }\n}(this, function (jQuery) {\n\n(function ($) {\n  $.fn.selectpicker.defaults = {\n    noneSelectedText: 'Hautapenik ez',\n    noneResultsText: 'Emaitzarik ez {0}',\n    countSelectedText: '{1}(e)tik {0} hautatuta',\n    maxOptionsText: ['Mugara iritsita ({n} {var} gehienez)', 'Taldearen mugara iritsita ({n} {var} gehienez)', ['elementu', 'elementu']],\n    multipleSeparator: ', '\n  };\n})(jQuery);\n\n\n}));\n"
  },
  {
    "path": "app_backend/static/plugin/bootstrap-select-1.12.2/docs/docs/dist/js/i18n/defaults-fa_IR.js",
    "content": "/*!\n * Bootstrap-select v1.12.2 (http://silviomoreto.github.io/bootstrap-select)\n *\n * Copyright 2013-2017 bootstrap-select\n * Licensed under MIT (https://github.com/silviomoreto/bootstrap-select/blob/master/LICENSE)\n */\n\n(function (root, factory) {\n  if (typeof define === 'function' && define.amd) {\n    // AMD. Register as an anonymous module unless amdModuleId is set\n    define([\"jquery\"], function (a0) {\n      return (factory(a0));\n    });\n  } else if (typeof module === 'object' && module.exports) {\n    // Node. Does not work with strict CommonJS, but\n    // only CommonJS-like environments that support module.exports,\n    // like Node.\n    module.exports = factory(require(\"jquery\"));\n  } else {\n    factory(root[\"jQuery\"]);\n  }\n}(this, function (jQuery) {\n\n(function ($) {\n    $.fn.selectpicker.defaults = {\n        noneSelectedText: 'چیزی انتخاب نشده است',\n        noneResultsText: 'هیج مشابهی برای {0} پیدا نشد',\n        countSelectedText: \"{0} از {1} مورد انتخاب شده\",\n        maxOptionsText: ['بیشتر ممکن نیست {حداکثر {n} عدد}', 'بیشتر ممکن نیست {حداکثر {n} عدد}'],\n        selectAllText: 'انتخاب همه',\n        deselectAllText: 'انتخاب هیچ کدام',\n        multipleSeparator: ', '\n    };\n})(jQuery);\n\n\n}));\n"
  },
  {
    "path": "app_backend/static/plugin/bootstrap-select-1.12.2/docs/docs/dist/js/i18n/defaults-fi_FI.js",
    "content": "/*!\n * Bootstrap-select v1.12.2 (http://silviomoreto.github.io/bootstrap-select)\n *\n * Copyright 2013-2017 bootstrap-select\n * Licensed under MIT (https://github.com/silviomoreto/bootstrap-select/blob/master/LICENSE)\n */\n\n(function (root, factory) {\n  if (typeof define === 'function' && define.amd) {\n    // AMD. Register as an anonymous module unless amdModuleId is set\n    define([\"jquery\"], function (a0) {\n      return (factory(a0));\n    });\n  } else if (typeof module === 'object' && module.exports) {\n    // Node. Does not work with strict CommonJS, but\n    // only CommonJS-like environments that support module.exports,\n    // like Node.\n    module.exports = factory(require(\"jquery\"));\n  } else {\n    factory(root[\"jQuery\"]);\n  }\n}(this, function (jQuery) {\n\n(function ($) {\n  $.fn.selectpicker.defaults = {\n    noneSelectedText: 'Ei valintoja',\n    noneResultsText: 'Ei hakutuloksia {0}',\n    countSelectedText: function (numSelected, numTotal) {\n      return (numSelected == 1) ? \"{0} valittu\" : \"{0} valitut\";\n    },\n    maxOptionsText: function (numAll, numGroup) {\n      return [\n        (numAll == 1) ? 'Valintojen maksimimäärä ({n} saavutettu)' : 'Valintojen maksimimäärä ({n} saavutettu)',\n        (numGroup == 1) ? 'Ryhmän maksimimäärä ({n} saavutettu)' : 'Ryhmän maksimimäärä ({n} saavutettu)'\n      ];\n    },\n    selectAllText: 'Valitse kaikki',\n    deselectAllText: 'Poista kaikki',\n    multipleSeparator: ', '\n  };\n})(jQuery);\n\n\n}));\n"
  },
  {
    "path": "app_backend/static/plugin/bootstrap-select-1.12.2/docs/docs/dist/js/i18n/defaults-fr_FR.js",
    "content": "/*!\n * Bootstrap-select v1.12.2 (http://silviomoreto.github.io/bootstrap-select)\n *\n * Copyright 2013-2017 bootstrap-select\n * Licensed under MIT (https://github.com/silviomoreto/bootstrap-select/blob/master/LICENSE)\n */\n\n(function (root, factory) {\n  if (typeof define === 'function' && define.amd) {\n    // AMD. Register as an anonymous module unless amdModuleId is set\n    define([\"jquery\"], function (a0) {\n      return (factory(a0));\n    });\n  } else if (typeof module === 'object' && module.exports) {\n    // Node. Does not work with strict CommonJS, but\n    // only CommonJS-like environments that support module.exports,\n    // like Node.\n    module.exports = factory(require(\"jquery\"));\n  } else {\n    factory(root[\"jQuery\"]);\n  }\n}(this, function (jQuery) {\n\n(function ($) {\n  $.fn.selectpicker.defaults = {\n    noneSelectedText: 'Aucune sélection',\n    noneResultsText: 'Aucun résultat pour {0}',\n    countSelectedText: function (numSelected, numTotal) {\n      return (numSelected > 1) ? \"{0} éléments sélectionnés\" : \"{0} élément sélectionné\";\n    },\n    maxOptionsText: function (numAll, numGroup) {\n      return [\n        (numAll > 1) ? 'Limite atteinte ({n} éléments max)' : 'Limite atteinte ({n} élément max)',\n        (numGroup > 1) ? 'Limite du groupe atteinte ({n} éléments max)' : 'Limite du groupe atteinte ({n} élément max)'\n      ];\n    },\n    multipleSeparator: ', ',\n    selectAllText: 'Tout Sélectionner',\n    deselectAllText: 'Tout Dé-selectionner',\n  };\n})(jQuery);\n\n\n}));\n"
  },
  {
    "path": "app_backend/static/plugin/bootstrap-select-1.12.2/docs/docs/dist/js/i18n/defaults-hu_HU.js",
    "content": "/*!\n * Bootstrap-select v1.12.2 (http://silviomoreto.github.io/bootstrap-select)\n *\n * Copyright 2013-2017 bootstrap-select\n * Licensed under MIT (https://github.com/silviomoreto/bootstrap-select/blob/master/LICENSE)\n */\n\n(function (root, factory) {\n  if (typeof define === 'function' && define.amd) {\n    // AMD. Register as an anonymous module unless amdModuleId is set\n    define([\"jquery\"], function (a0) {\n      return (factory(a0));\n    });\n  } else if (typeof module === 'object' && module.exports) {\n    // Node. Does not work with strict CommonJS, but\n    // only CommonJS-like environments that support module.exports,\n    // like Node.\n    module.exports = factory(require(\"jquery\"));\n  } else {\n    factory(root[\"jQuery\"]);\n  }\n}(this, function (jQuery) {\n\n(function ($) {\n  $.fn.selectpicker.defaults = {\n    noneSelectedText: 'Válasszon!',\n    noneResultsText: 'Nincs találat {0}',\n    countSelectedText: function (numSelected, numTotal) {\n      return '{0} elem kiválasztva';\n    },\n    maxOptionsText: function (numAll, numGroup) {\n      return [\n        'Legfeljebb {n} elem választható',\n        'A csoportban legfeljebb {n} elem választható'\n      ];\n    },\n    selectAllText: 'Mind',\n    deselectAllText: 'Egyik sem',\n    multipleSeparator: ', '\n  };\n})(jQuery);\n\n\n}));\n"
  },
  {
    "path": "app_backend/static/plugin/bootstrap-select-1.12.2/docs/docs/dist/js/i18n/defaults-id_ID.js",
    "content": "/*!\n * Bootstrap-select v1.12.2 (http://silviomoreto.github.io/bootstrap-select)\n *\n * Copyright 2013-2017 bootstrap-select\n * Licensed under MIT (https://github.com/silviomoreto/bootstrap-select/blob/master/LICENSE)\n */\n\n(function (root, factory) {\n  if (typeof define === 'function' && define.amd) {\n    // AMD. Register as an anonymous module unless amdModuleId is set\n    define([\"jquery\"], function (a0) {\n      return (factory(a0));\n    });\n  } else if (typeof module === 'object' && module.exports) {\n    // Node. Does not work with strict CommonJS, but\n    // only CommonJS-like environments that support module.exports,\n    // like Node.\n    module.exports = factory(require(\"jquery\"));\n  } else {\n    factory(root[\"jQuery\"]);\n  }\n}(this, function (jQuery) {\n\n(function ($) {\n  $.fn.selectpicker.defaults = {\n    noneSelectedText: 'Tidak ada yang dipilih',\n    noneResultsText: 'Tidak ada yang cocok {0}',\n    countSelectedText: '{0} terpilih',\n    maxOptionsText: ['Mencapai batas (maksimum {n})', 'Mencapai batas grup (maksimum {n})'],\n    selectAllText: 'Pilih Semua',\n    deselectAllText: 'Hapus Semua',\n    multipleSeparator: ', '\n  };\n})(jQuery);\n\n\n}));\n"
  },
  {
    "path": "app_backend/static/plugin/bootstrap-select-1.12.2/docs/docs/dist/js/i18n/defaults-it_IT.js",
    "content": "/*!\n * Bootstrap-select v1.12.2 (http://silviomoreto.github.io/bootstrap-select)\n *\n * Copyright 2013-2017 bootstrap-select\n * Licensed under MIT (https://github.com/silviomoreto/bootstrap-select/blob/master/LICENSE)\n */\n\n(function (root, factory) {\n  if (typeof define === 'function' && define.amd) {\n    // AMD. Register as an anonymous module unless amdModuleId is set\n    define([\"jquery\"], function (a0) {\n      return (factory(a0));\n    });\n  } else if (typeof module === 'object' && module.exports) {\n    // Node. Does not work with strict CommonJS, but\n    // only CommonJS-like environments that support module.exports,\n    // like Node.\n    module.exports = factory(require(\"jquery\"));\n  } else {\n    factory(root[\"jQuery\"]);\n  }\n}(this, function (jQuery) {\n\n(function ($) {\n  $.fn.selectpicker.defaults = {\n    noneSelectedText: 'Nessuna selezione',\n    noneResultsText: 'Nessun risultato per {0}',\n    countSelectedText: function (numSelected, numTotal){\n      return (numSelected == 1) ? 'Selezionato {0} di {1}' : 'Selezionati {0} di {1}';\n    },\n    maxOptionsText: ['Limite raggiunto ({n} {var} max)', 'Limite del gruppo raggiunto ({n} {var} max)', ['elementi', 'elemento']],\n    multipleSeparator: ', ',\n    selectAllText: 'Seleziona Tutto',\n    deselectAllText: 'Deseleziona Tutto'\n  };\n})(jQuery);\n\n\n}));\n"
  },
  {
    "path": "app_backend/static/plugin/bootstrap-select-1.12.2/docs/docs/dist/js/i18n/defaults-ko_KR.js",
    "content": "/*!\n * Bootstrap-select v1.12.2 (http://silviomoreto.github.io/bootstrap-select)\n *\n * Copyright 2013-2017 bootstrap-select\n * Licensed under MIT (https://github.com/silviomoreto/bootstrap-select/blob/master/LICENSE)\n */\n\n(function (root, factory) {\n  if (typeof define === 'function' && define.amd) {\n    // AMD. Register as an anonymous module unless amdModuleId is set\n    define([\"jquery\"], function (a0) {\n      return (factory(a0));\n    });\n  } else if (typeof module === 'object' && module.exports) {\n    // Node. Does not work with strict CommonJS, but\n    // only CommonJS-like environments that support module.exports,\n    // like Node.\n    module.exports = factory(require(\"jquery\"));\n  } else {\n    factory(root[\"jQuery\"]);\n  }\n}(this, function (jQuery) {\n\n(function ($) {\n  $.fn.selectpicker.defaults = {\n    noneSelectedText: '항목을 선택해주세요',\n    noneResultsText: '{0} 검색 결과가 없습니다',\n    countSelectedText: function (numSelected, numTotal) {\n      return \"{0}개를 선택하였습니다\";\n    },\n    maxOptionsText: function (numAll, numGroup) {\n      return [\n        '{n}개까지 선택 가능합니다',\n        '해당 그룹은 {n}개까지 선택 가능합니다'\n      ];\n    },\n    selectAllText: '전체선택',\n    deselectAllText: '전체해제',\n    multipleSeparator: ', '\n  };\n})(jQuery);\n\n\n}));\n"
  },
  {
    "path": "app_backend/static/plugin/bootstrap-select-1.12.2/docs/docs/dist/js/i18n/defaults-lt_LT.js",
    "content": "/*!\n * Bootstrap-select v1.12.2 (http://silviomoreto.github.io/bootstrap-select)\n *\n * Copyright 2013-2017 bootstrap-select\n * Licensed under MIT (https://github.com/silviomoreto/bootstrap-select/blob/master/LICENSE)\n */\n\n(function (root, factory) {\n  if (typeof define === 'function' && define.amd) {\n    // AMD. Register as an anonymous module unless amdModuleId is set\n    define([\"jquery\"], function (a0) {\n      return (factory(a0));\n    });\n  } else if (typeof module === 'object' && module.exports) {\n    // Node. Does not work with strict CommonJS, but\n    // only CommonJS-like environments that support module.exports,\n    // like Node.\n    module.exports = factory(require(\"jquery\"));\n  } else {\n    factory(root[\"jQuery\"]);\n  }\n}(this, function (jQuery) {\n\n(function ($) {\n  $.fn.selectpicker.defaults = {\n    noneSelectedText: 'Niekas nepasirinkta',\n    noneResultsText: 'Niekas nesutapo su {0}',\n    countSelectedText: function (numSelected, numTotal) {\n      return (numSelected == 1) ? \"{0} elementas pasirinktas\" : \"{0} elementai(-ų) pasirinkta\";\n    },\n    maxOptionsText: function (numAll, numGroup) {\n      return [\n        (numAll == 1) ? 'Pasiekta riba ({n} elementas daugiausiai)' : 'Riba pasiekta ({n} elementai(-ų) daugiausiai)',\n        (numGroup == 1) ? 'Grupės riba pasiekta ({n} elementas daugiausiai)' : 'Grupės riba pasiekta ({n} elementai(-ų) daugiausiai)'\n      ];\n    },\n    selectAllText: 'Pasirinkti visus',\n    deselectAllText: 'Atmesti visus',\n    multipleSeparator: ', '\n  };\n})(jQuery);\n\n\n}));\n"
  },
  {
    "path": "app_backend/static/plugin/bootstrap-select-1.12.2/docs/docs/dist/js/i18n/defaults-nb_NO.js",
    "content": "/*!\n * Bootstrap-select v1.12.2 (http://silviomoreto.github.io/bootstrap-select)\n *\n * Copyright 2013-2017 bootstrap-select\n * Licensed under MIT (https://github.com/silviomoreto/bootstrap-select/blob/master/LICENSE)\n */\n\n(function (root, factory) {\n  if (typeof define === 'function' && define.amd) {\n    // AMD. Register as an anonymous module unless amdModuleId is set\n    define([\"jquery\"], function (a0) {\n      return (factory(a0));\n    });\n  } else if (typeof module === 'object' && module.exports) {\n    // Node. Does not work with strict CommonJS, but\n    // only CommonJS-like environments that support module.exports,\n    // like Node.\n    module.exports = factory(require(\"jquery\"));\n  } else {\n    factory(root[\"jQuery\"]);\n  }\n}(this, function (jQuery) {\n\n(function ($) {\n  $.fn.selectpicker.defaults = {\n    noneSelectedText: 'Ingen valgt',\n    noneResultsText: 'Søket gir ingen treff {0}',\n    countSelectedText: function (numSelected, numTotal) {\n      return (numSelected == 1) ? \"{0} alternativ valgt\" : \"{0} alternativer valgt\";\n    },\n    maxOptionsText: function (numAll, numGroup) {\n      return [\n        (numAll == 1) ? 'Grense nådd (maks {n} valg)' : 'Grense nådd (maks {n} valg)',\n        (numGroup == 1) ? 'Grense for grupper nådd (maks {n} grupper)' : 'Grense for grupper nådd (maks {n} grupper)'\n      ];\n    },\n    selectAllText: 'Merk alle',\n    deselectAllText: 'Fjern alle',\n    multipleSeparator: ', '\n  };\n})(jQuery);\n\n\n}));\n"
  },
  {
    "path": "app_backend/static/plugin/bootstrap-select-1.12.2/docs/docs/dist/js/i18n/defaults-nl_NL.js",
    "content": "/*!\n * Bootstrap-select v1.12.2 (http://silviomoreto.github.io/bootstrap-select)\n *\n * Copyright 2013-2017 bootstrap-select\n * Licensed under MIT (https://github.com/silviomoreto/bootstrap-select/blob/master/LICENSE)\n */\n\n(function (root, factory) {\n  if (typeof define === 'function' && define.amd) {\n    // AMD. Register as an anonymous module unless amdModuleId is set\n    define([\"jquery\"], function (a0) {\n      return (factory(a0));\n    });\n  } else if (typeof module === 'object' && module.exports) {\n    // Node. Does not work with strict CommonJS, but\n    // only CommonJS-like environments that support module.exports,\n    // like Node.\n    module.exports = factory(require(\"jquery\"));\n  } else {\n    factory(root[\"jQuery\"]);\n  }\n}(this, function (jQuery) {\n\n(function ($) {\n  $.fn.selectpicker.defaults = {\n    noneSelectedText: 'Niets geselecteerd',\n    noneResultsText: 'Geen resultaten gevonden voor {0}',\n    countSelectedText: '{0} van {1} geselecteerd',\n    maxOptionsText: ['Limiet bereikt ({n} {var} max)', 'Groep limiet bereikt ({n} {var} max)', ['items', 'item']],\n    multipleSeparator: ', '\n  };\n})(jQuery);\n\n\n}));\n"
  },
  {
    "path": "app_backend/static/plugin/bootstrap-select-1.12.2/docs/docs/dist/js/i18n/defaults-pl_PL.js",
    "content": "/*!\n * Bootstrap-select v1.12.2 (http://silviomoreto.github.io/bootstrap-select)\n *\n * Copyright 2013-2017 bootstrap-select\n * Licensed under MIT (https://github.com/silviomoreto/bootstrap-select/blob/master/LICENSE)\n */\n\n(function (root, factory) {\n  if (typeof define === 'function' && define.amd) {\n    // AMD. Register as an anonymous module unless amdModuleId is set\n    define([\"jquery\"], function (a0) {\n      return (factory(a0));\n    });\n  } else if (typeof module === 'object' && module.exports) {\n    // Node. Does not work with strict CommonJS, but\n    // only CommonJS-like environments that support module.exports,\n    // like Node.\n    module.exports = factory(require(\"jquery\"));\n  } else {\n    factory(root[\"jQuery\"]);\n  }\n}(this, function (jQuery) {\n\n(function ($) {\n  $.fn.selectpicker.defaults = {\n    noneSelectedText: 'Nic nie zaznaczono',\n    noneResultsText: 'Brak wyników wyszukiwania {0}',\n    countSelectedText: 'Zaznaczono {0} z {1}',\n    maxOptionsText: ['Osiągnięto limit ({n} {var} max)', 'Limit grupy osiągnięty ({n} {var} max)', ['elementy', 'element']],\n    selectAll: 'Zaznacz wszystkie',\n    deselectAll: 'Odznacz wszystkie',\n    multipleSeparator: ', '\n  };\n})(jQuery);\n\n\n}));\n"
  },
  {
    "path": "app_backend/static/plugin/bootstrap-select-1.12.2/docs/docs/dist/js/i18n/defaults-pt_BR.js",
    "content": "/*!\n * Bootstrap-select v1.12.2 (http://silviomoreto.github.io/bootstrap-select)\n *\n * Copyright 2013-2017 bootstrap-select\n * Licensed under MIT (https://github.com/silviomoreto/bootstrap-select/blob/master/LICENSE)\n */\n\n(function (root, factory) {\n  if (typeof define === 'function' && define.amd) {\n    // AMD. Register as an anonymous module unless amdModuleId is set\n    define([\"jquery\"], function (a0) {\n      return (factory(a0));\n    });\n  } else if (typeof module === 'object' && module.exports) {\n    // Node. Does not work with strict CommonJS, but\n    // only CommonJS-like environments that support module.exports,\n    // like Node.\n    module.exports = factory(require(\"jquery\"));\n  } else {\n    factory(root[\"jQuery\"]);\n  }\n}(this, function (jQuery) {\n\n(function ($) {\n  $.fn.selectpicker.defaults = {\n    noneSelectedText: 'Nada selecionado',\n    noneResultsText: 'Nada encontrado contendo {0}',\n    countSelectedText: 'Selecionado {0} de {1}',\n    maxOptionsText: ['Limite excedido (máx. {n} {var})', 'Limite do grupo excedido (máx. {n} {var})', ['itens', 'item']],\n    multipleSeparator: ', '\n  };\n})(jQuery);\n\n\n}));\n"
  },
  {
    "path": "app_backend/static/plugin/bootstrap-select-1.12.2/docs/docs/dist/js/i18n/defaults-pt_PT.js",
    "content": "/*!\n * Bootstrap-select v1.12.2 (http://silviomoreto.github.io/bootstrap-select)\n *\n * Copyright 2013-2017 bootstrap-select\n * Licensed under MIT (https://github.com/silviomoreto/bootstrap-select/blob/master/LICENSE)\n */\n\n(function (root, factory) {\n  if (typeof define === 'function' && define.amd) {\n    // AMD. Register as an anonymous module unless amdModuleId is set\n    define([\"jquery\"], function (a0) {\n      return (factory(a0));\n    });\n  } else if (typeof module === 'object' && module.exports) {\n    // Node. Does not work with strict CommonJS, but\n    // only CommonJS-like environments that support module.exports,\n    // like Node.\n    module.exports = factory(require(\"jquery\"));\n  } else {\n    factory(root[\"jQuery\"]);\n  }\n}(this, function (jQuery) {\n\n(function ($) {\n$.fn.selectpicker.defaults = {\nnoneSelectedText: 'Nenhum seleccionado',\nnoneResultsText: 'Sem resultados contendo {0}',\ncountSelectedText: 'Selecionado {0} de {1}',\nmaxOptionsText: ['Limite ultrapassado (máx. {n} {var})', 'Limite de seleções ultrapassado (máx. {n} {var})', ['itens', 'item']],\nmultipleSeparator: ', '\n};\n})(jQuery);\n\n\n}));\n"
  },
  {
    "path": "app_backend/static/plugin/bootstrap-select-1.12.2/docs/docs/dist/js/i18n/defaults-ro_RO.js",
    "content": "/*!\n * Bootstrap-select v1.12.2 (http://silviomoreto.github.io/bootstrap-select)\n *\n * Copyright 2013-2017 bootstrap-select\n * Licensed under MIT (https://github.com/silviomoreto/bootstrap-select/blob/master/LICENSE)\n */\n\n(function (root, factory) {\n  if (typeof define === 'function' && define.amd) {\n    // AMD. Register as an anonymous module unless amdModuleId is set\n    define([\"jquery\"], function (a0) {\n      return (factory(a0));\n    });\n  } else if (typeof module === 'object' && module.exports) {\n    // Node. Does not work with strict CommonJS, but\n    // only CommonJS-like environments that support module.exports,\n    // like Node.\n    module.exports = factory(require(\"jquery\"));\n  } else {\n    factory(root[\"jQuery\"]);\n  }\n}(this, function (jQuery) {\n\n(function ($) {\n  $.fn.selectpicker.defaults = {\n    noneSelectedText: 'Nu a fost selectat nimic',\n    noneResultsText: 'Nu exista niciun rezultat {0}',\n    countSelectedText: '{0} din {1} selectat(e)',\n    maxOptionsText: ['Limita a fost atinsa ({n} {var} max)', 'Limita de grup a fost atinsa ({n} {var} max)', ['iteme', 'item']],\n    multipleSeparator: ', '\n  };\n})(jQuery);\n\n\n}));\n"
  },
  {
    "path": "app_backend/static/plugin/bootstrap-select-1.12.2/docs/docs/dist/js/i18n/defaults-ru_RU.js",
    "content": "/*!\n * Bootstrap-select v1.12.2 (http://silviomoreto.github.io/bootstrap-select)\n *\n * Copyright 2013-2017 bootstrap-select\n * Licensed under MIT (https://github.com/silviomoreto/bootstrap-select/blob/master/LICENSE)\n */\n\n(function (root, factory) {\n  if (typeof define === 'function' && define.amd) {\n    // AMD. Register as an anonymous module unless amdModuleId is set\n    define([\"jquery\"], function (a0) {\n      return (factory(a0));\n    });\n  } else if (typeof module === 'object' && module.exports) {\n    // Node. Does not work with strict CommonJS, but\n    // only CommonJS-like environments that support module.exports,\n    // like Node.\n    module.exports = factory(require(\"jquery\"));\n  } else {\n    factory(root[\"jQuery\"]);\n  }\n}(this, function (jQuery) {\n\n(function ($) {\n  $.fn.selectpicker.defaults = {\n    noneSelectedText: 'Ничего не выбрано',\n    noneResultsText: 'Совпадений не найдено {0}',\n    countSelectedText: 'Выбрано {0} из {1}',\n    maxOptionsText: ['Достигнут предел ({n} {var} максимум)', 'Достигнут предел в группе ({n} {var} максимум)', ['шт.', 'шт.']],\n    doneButtonText: 'Закрыть',\n    selectAllText: 'Выбрать все',\n    deselectAllText: 'Отменить все',    \n    multipleSeparator: ', '\n  };\n})(jQuery);\n\n\n}));\n"
  },
  {
    "path": "app_backend/static/plugin/bootstrap-select-1.12.2/docs/docs/dist/js/i18n/defaults-sk_SK.js",
    "content": "/*!\n * Bootstrap-select v1.12.2 (http://silviomoreto.github.io/bootstrap-select)\n *\n * Copyright 2013-2017 bootstrap-select\n * Licensed under MIT (https://github.com/silviomoreto/bootstrap-select/blob/master/LICENSE)\n */\n\n(function (root, factory) {\n  if (typeof define === 'function' && define.amd) {\n    // AMD. Register as an anonymous module unless amdModuleId is set\n    define([\"jquery\"], function (a0) {\n      return (factory(a0));\n    });\n  } else if (typeof module === 'object' && module.exports) {\n    // Node. Does not work with strict CommonJS, but\n    // only CommonJS-like environments that support module.exports,\n    // like Node.\n    module.exports = factory(require(\"jquery\"));\n  } else {\n    factory(root[\"jQuery\"]);\n  }\n}(this, function (jQuery) {\n\n(function ($) {\n  $.fn.selectpicker.defaults = {\n    noneSelectedText: 'Vyberte zo zoznamu',\n    noneResultsText: 'Pre výraz {0} neboli nájdené žiadne výsledky',\n    countSelectedText: 'Vybrané {0} z {1}',\n    maxOptionsText: ['Limit prekročený ({n} {var} max)', 'Limit skupiny prekročený ({n} {var} max)', ['položiek', 'položka']],\n    selectAllText: 'Vybrať všetky',\n    deselectAllText: 'Zrušiť výber',\n    multipleSeparator: ', '\n  };\n})(jQuery);\n\n\n}));\n"
  },
  {
    "path": "app_backend/static/plugin/bootstrap-select-1.12.2/docs/docs/dist/js/i18n/defaults-sl_SI.js",
    "content": "/*!\n * Bootstrap-select v1.12.2 (http://silviomoreto.github.io/bootstrap-select)\n *\n * Copyright 2013-2017 bootstrap-select\n * Licensed under MIT (https://github.com/silviomoreto/bootstrap-select/blob/master/LICENSE)\n */\n\n(function (root, factory) {\n  if (typeof define === 'function' && define.amd) {\n    // AMD. Register as an anonymous module unless amdModuleId is set\n    define([\"jquery\"], function (a0) {\n      return (factory(a0));\n    });\n  } else if (typeof module === 'object' && module.exports) {\n    // Node. Does not work with strict CommonJS, but\n    // only CommonJS-like environments that support module.exports,\n    // like Node.\n    module.exports = factory(require(\"jquery\"));\n  } else {\n    factory(root[\"jQuery\"]);\n  }\n}(this, function (jQuery) {\n\n(function ($) {\n  $.fn.selectpicker.defaults = {\n    noneSelectedText: 'Nič izbranega',\n    noneResultsText: 'Ni zadetkov za {0}',\n    countSelectedText: function (numSelected, numTotal) {\n      \"Število izbranih: {0}\";\n    },\n    maxOptionsText: function (numAll, numGroup) {\n      return [\n        'Omejitev dosežena (max. izbranih: {n})',\n        'Omejitev skupine dosežena (max. izbranih: {n})'\n      ];\n    },\n    selectAllText: 'Izberi vse',\n    deselectAllText: 'Počisti izbor',\n    multipleSeparator: ', '\n  };\n})(jQuery);\n\n\n}));\n"
  },
  {
    "path": "app_backend/static/plugin/bootstrap-select-1.12.2/docs/docs/dist/js/i18n/defaults-sv_SE.js",
    "content": "/*!\n * Bootstrap-select v1.12.2 (http://silviomoreto.github.io/bootstrap-select)\n *\n * Copyright 2013-2017 bootstrap-select\n * Licensed under MIT (https://github.com/silviomoreto/bootstrap-select/blob/master/LICENSE)\n */\n\n(function (root, factory) {\n  if (typeof define === 'function' && define.amd) {\n    // AMD. Register as an anonymous module unless amdModuleId is set\n    define([\"jquery\"], function (a0) {\n      return (factory(a0));\n    });\n  } else if (typeof module === 'object' && module.exports) {\n    // Node. Does not work with strict CommonJS, but\n    // only CommonJS-like environments that support module.exports,\n    // like Node.\n    module.exports = factory(require(\"jquery\"));\n  } else {\n    factory(root[\"jQuery\"]);\n  }\n}(this, function (jQuery) {\n\n(function ($) {\n  $.fn.selectpicker.defaults = {\n    noneSelectedText: 'Inget valt',\n    noneResultsText: 'Inget sökresultat matchar {0}',\n    countSelectedText: function (numSelected, numTotal) {\n      return (numSelected === 1) ? \"{0} alternativ valt\" : \"{0} alternativ valda\";\n    },\n    maxOptionsText: function (numAll, numGroup) {\n      return [\n        'Gräns uppnåd (max {n} alternativ)',\n        'Gräns uppnåd (max {n} gruppalternativ)'\n      ];\n    },\n    selectAllText: 'Markera alla',\n    deselectAllText: 'Avmarkera alla',\n    multipleSeparator: ', '\n  };\n})(jQuery);\n\n\n}));\n"
  },
  {
    "path": "app_backend/static/plugin/bootstrap-select-1.12.2/docs/docs/dist/js/i18n/defaults-tr_TR.js",
    "content": "/*!\n * Bootstrap-select v1.12.2 (http://silviomoreto.github.io/bootstrap-select)\n *\n * Copyright 2013-2017 bootstrap-select\n * Licensed under MIT (https://github.com/silviomoreto/bootstrap-select/blob/master/LICENSE)\n */\n\n(function (root, factory) {\n  if (typeof define === 'function' && define.amd) {\n    // AMD. Register as an anonymous module unless amdModuleId is set\n    define([\"jquery\"], function (a0) {\n      return (factory(a0));\n    });\n  } else if (typeof module === 'object' && module.exports) {\n    // Node. Does not work with strict CommonJS, but\n    // only CommonJS-like environments that support module.exports,\n    // like Node.\n    module.exports = factory(require(\"jquery\"));\n  } else {\n    factory(root[\"jQuery\"]);\n  }\n}(this, function (jQuery) {\n\n(function ($) {\n  $.fn.selectpicker.defaults = {\n    noneSelectedText: 'Hiçbiri seçilmedi',\n    noneResultsText: 'Hiçbir sonuç bulunamadı {0}',\n    countSelectedText: function (numSelected, numTotal) {\n      return (numSelected == 1) ? \"{0} öğe seçildi\" : \"{0} öğe seçildi\";\n    },\n    maxOptionsText: function (numAll, numGroup) {\n      return [\n        (numAll == 1) ? 'Limit aşıldı (maksimum {n} sayıda öğe )' : 'Limit aşıldı (maksimum {n} sayıda öğe)',\n        (numGroup == 1) ? 'Grup limiti aşıldı (maksimum {n} sayıda öğe)' : 'Grup limiti aşıldı (maksimum {n} sayıda öğe)'\n      ];\n    },\n    selectAllText: 'Tümünü Seç',\n    deselectAllText: 'Seçiniz',\n    multipleSeparator: ', '\n  };\n})(jQuery);\n\n\n}));\n"
  },
  {
    "path": "app_backend/static/plugin/bootstrap-select-1.12.2/docs/docs/dist/js/i18n/defaults-ua_UA.js",
    "content": "/*!\n * Bootstrap-select v1.12.2 (http://silviomoreto.github.io/bootstrap-select)\n *\n * Copyright 2013-2017 bootstrap-select\n * Licensed under MIT (https://github.com/silviomoreto/bootstrap-select/blob/master/LICENSE)\n */\n\n(function (root, factory) {\n  if (typeof define === 'function' && define.amd) {\n    // AMD. Register as an anonymous module unless amdModuleId is set\n    define([\"jquery\"], function (a0) {\n      return (factory(a0));\n    });\n  } else if (typeof module === 'object' && module.exports) {\n    // Node. Does not work with strict CommonJS, but\n    // only CommonJS-like environments that support module.exports,\n    // like Node.\n    module.exports = factory(require(\"jquery\"));\n  } else {\n    factory(root[\"jQuery\"]);\n  }\n}(this, function (jQuery) {\n\n(function ($) {\n  $.fn.selectpicker.defaults = {\n    noneSelectedText: 'Нічого не вибрано',\n    noneResultsText: 'Збігів не знайдено {0}',\n    countSelectedText: 'Вибрано {0} із {1}',\n    maxOptionsText: ['Досягнута межа ({n} {var} максимум)', 'Досягнута межа в групі ({n} {var} максимум)', ['items', 'item']],\n    multipleSeparator: ', '\n  };\n})(jQuery);\n\n\n}));\n"
  },
  {
    "path": "app_backend/static/plugin/bootstrap-select-1.12.2/docs/docs/dist/js/i18n/defaults-zh_CN.js",
    "content": "/*!\n * Bootstrap-select v1.12.2 (http://silviomoreto.github.io/bootstrap-select)\n *\n * Copyright 2013-2017 bootstrap-select\n * Licensed under MIT (https://github.com/silviomoreto/bootstrap-select/blob/master/LICENSE)\n */\n\n(function (root, factory) {\n  if (typeof define === 'function' && define.amd) {\n    // AMD. Register as an anonymous module unless amdModuleId is set\n    define([\"jquery\"], function (a0) {\n      return (factory(a0));\n    });\n  } else if (typeof module === 'object' && module.exports) {\n    // Node. Does not work with strict CommonJS, but\n    // only CommonJS-like environments that support module.exports,\n    // like Node.\n    module.exports = factory(require(\"jquery\"));\n  } else {\n    factory(root[\"jQuery\"]);\n  }\n}(this, function (jQuery) {\n\n(function ($) {\n  $.fn.selectpicker.defaults = {\n    noneSelectedText: '没有选中任何项',\n    noneResultsText: '没有找到匹配项',\n    countSelectedText: '选中{1}中的{0}项',\n    maxOptionsText: ['超出限制 (最多选择{n}项)', '组选择超出限制(最多选择{n}组)'],\n    multipleSeparator: ', '\n  };\n})(jQuery);\n\n\n}));\n"
  },
  {
    "path": "app_backend/static/plugin/bootstrap-select-1.12.2/docs/docs/dist/js/i18n/defaults-zh_TW.js",
    "content": "/*!\n * Bootstrap-select v1.12.2 (http://silviomoreto.github.io/bootstrap-select)\n *\n * Copyright 2013-2017 bootstrap-select\n * Licensed under MIT (https://github.com/silviomoreto/bootstrap-select/blob/master/LICENSE)\n */\n\n(function (root, factory) {\n  if (typeof define === 'function' && define.amd) {\n    // AMD. Register as an anonymous module unless amdModuleId is set\n    define([\"jquery\"], function (a0) {\n      return (factory(a0));\n    });\n  } else if (typeof module === 'object' && module.exports) {\n    // Node. Does not work with strict CommonJS, but\n    // only CommonJS-like environments that support module.exports,\n    // like Node.\n    module.exports = factory(require(\"jquery\"));\n  } else {\n    factory(root[\"jQuery\"]);\n  }\n}(this, function (jQuery) {\n\n(function ($) {\n  $.fn.selectpicker.defaults = {\n    noneSelectedText: '沒有選取任何項目',\n    noneResultsText: '沒有找到符合的結果',\n    countSelectedText: '已經選取{0}個項目',\n    maxOptionsText: ['超過限制 (最多選擇{n}項)', '超過限制(最多選擇{n}組)'],\n    selectAllText: '選取全部',\n    deselectAllText: '全部取消',\n    multipleSeparator: ', '\n  };\n})(jQuery);\n\n\n}));\n"
  },
  {
    "path": "app_backend/static/plugin/bootstrap-select-1.12.2/docs/docs/examples.md",
    "content": "# Basic examples\n\n---\n## Standard select boxes\n\n<div class=\"bs-docs-example\">\n  <p>Make this:</p>\n\n  <select>\n    <option>Mustard</option>\n    <option>Ketchup</option>\n    <option>Relish</option>\n  </select>\n\n  <p>Become this:</p>\n\n  <select class=\"selectpicker\">\n    <option>Mustard</option>\n    <option>Ketchup</option>\n    <option>Relish</option>\n  </select>\n</div>\n\n```html\n<select class=\"selectpicker\">\n  <option>Mustard</option>\n  <option>Ketchup</option>\n  <option>Relish</option>\n</select>\n```\n\n<div id=\"optgroup\"></div>\n## Select boxes with optgroups\n\n<div class=\"bs-docs-example\">\n  <select class=\"selectpicker\">\n    <optgroup label=\"Picnic\">\n      <option>Mustard</option>\n      <option>Ketchup</option>\n      <option>Relish</option>\n    </optgroup>\n    <optgroup label=\"Camping\">\n      <option>Tent</option>\n      <option>Flashlight</option>\n      <option>Toilet Paper</option>\n    </optgroup>\n  </select>\n</div>\n\n```html\n<select class=\"selectpicker\">\n  <optgroup label=\"Picnic\">\n    <option>Mustard</option>\n    <option>Ketchup</option>\n    <option>Relish</option>\n  </optgroup>\n  <optgroup label=\"Camping\">\n    <option>Tent</option>\n    <option>Flashlight</option>\n    <option>Toilet Paper</option>\n  </optgroup>\n</select>\n```\n\n## Multiple select boxes\n\n<div class=\"bs-docs-example\">\n  <select class=\"selectpicker\" multiple>\n    <option>Mustard</option>\n    <option>Ketchup</option>\n    <option>Relish</option>\n  </select>\n</div>\n\n```html\n<select class=\"selectpicker\" multiple>\n  <option>Mustard</option>\n  <option>Ketchup</option>\n  <option>Relish</option>\n</select>\n```\n\n# Live search\n\n---\n\n## Live search\n\nYou can add a search input by passing `data-live-search=\"true\"` attribute:\n\n<div class=\"bs-docs-example no-code\">\n  <select class=\"selectpicker\" data-live-search=\"true\">\n    <option>Hot Dog, Fries and a Soda</option>\n    <option>Burger, Shake and a Smile</option>\n    <option>Sugar, Spice and all things nice</option>\n  </select>\n</div>\n\n## Key words\n\nAdd key words to options to improve their searchability using `data-tokens`.\n\n<div class=\"bs-docs-example\">\n  <select class=\"selectpicker\" data-live-search=\"true\">\n    <option data-tokens=\"ketchup mustard\">Hot Dog, Fries and a Soda</option>\n    <option data-tokens=\"mustard\">Burger, Shake and a Smile</option>\n    <option data-tokens=\"frosting\">Sugar, Spice and all things nice</option>\n  </select>\n</div>\n\n```html\n<select class=\"selectpicker\" data-live-search=\"true\">\n  <option data-tokens=\"ketchup mustard\">Hot Dog, Fries and a Soda</option>\n  <option data-tokens=\"mustard\">Burger, Shake and a Smile</option>\n  <option data-tokens=\"frosting\">Sugar, Spice and all things nice</option>\n</select>\n```\n\n# Limit the number of selections\n\nLimit the number of options that can be selected via the `data-max-options` attribute. It also works for option groups. Customize the message displayed when the limit is reached with `maxOptionsText`.\n\n<div class=\"bs-docs-example\">\n  <select class=\"selectpicker\" multiple data-max-options=\"2\">\n    <option>Mustard</option>\n    <option>Ketchup</option>\n    <option>Relish</option>\n  </select>\n\n  <select class=\"selectpicker\" multiple>\n    <optgroup label=\"Condiments\" data-max-options=\"2\">\n      <option>Mustard</option>\n      <option>Ketchup</option>\n      <option>Relish</option>\n    </optgroup>\n    <optgroup label=\"Breads\" data-max-options=\"2\">\n      <option>Plain</option>\n      <option>Steamed</option>\n      <option>Toasted</option>\n    </optgroup>\n  </select>\n</div>\n\n```html\n<select class=\"selectpicker\" multiple data-max-options=\"2\">\n  <option>Mustard</option>\n  <option>Ketchup</option>\n  <option>Relish</option>\n</select>\n\n<select class=\"selectpicker\" multiple>\n  <optgroup label=\"Condiments\" data-max-options=\"2\">\n    <option>Mustard</option>\n    <option>Ketchup</option>\n    <option>Relish</option>\n  </optgroup>\n  <optgroup label=\"Breads\" data-max-options=\"2\">\n    <option>Plain</option>\n    <option>Steamed</option>\n    <option>Toasted</option>\n  </optgroup>\n</select>\n```\n\n# Custom button text\n\n---\n\n## Placeholder\n<p id=\"titleMultiples\"></p>\nUsing the `title` attribute will set the default placeholder text when nothing is selected. This works for both multiple and standard select boxes:\n\n<div class=\"bs-docs-example\">\n  <div class=\"form-group\">\n    <label>Multiple</label>\n    <select class=\"selectpicker\" multiple title=\"Choose one of the following...\">\n      <option>Mustard</option>\n      <option>Ketchup</option>\n      <option>Relish</option>\n    </select>\n  </div>\n\n  <div class=\"form-group\">\n    <label>Standard</label>\n    <select class=\"selectpicker\" title=\"Choose one of the following...\">\n      <option>Mustard</option>\n      <option>Ketchup</option>\n      <option>Relish</option>\n    </select>\n  </div>\n</div>\n\n```html\n<select class=\"selectpicker\" multiple title=\"Choose one of the following...\">\n  <option>Mustard</option>\n  <option>Ketchup</option>\n  <option>Relish</option>\n</select>\n```\n\n## Selected text\n\n<p id=\"title\"></p>\nSet the `title` attribute on individual options to display alternative text when the option is selected:\n\n<div class=\"bs-docs-example no-code\">\n  <select class=\"selectpicker\">\n    <option title=\"Combo 1\">Hot Dog, Fries and a Soda</option>\n    <option title=\"Combo 2\">Burger, Shake and a Smile</option>\n    <option title=\"Combo 3\">Sugar, Spice and all things nice</option>\n  </select>\n</div>\n\n```html\n<select class=\"selectpicker\">\n  <option title=\"Combo 1\">Hot Dog, Fries and a Soda</option>\n  <option title=\"Combo 2\">Burger, Shake and a Smile</option>\n  <option title=\"Combo 3\">Sugar, Spice and all things nice</option>\n</select>\n```\n## Selected text format\n\n<p id=\"titleMultiplesFormat\"></p>\nSpecify how the selection is displayed with the `data-selected-text-format` attribute on a multiple select.\n\nThe supported values are:\n\n* `values`: A comma delimited list of selected values (default)\n* `count`: If one item is selected, then the option value is shown. If more than one is selected then the number of selected items is displayed, e.g. `2 of 6 selected`\n* `count > x`: Where `x` is the number of items selected when the display format changes from `values` to `count`\n* `static`: Always show the select title (placeholder), regardless of selection\n\n<div class=\"bs-docs-example\">\n  <select class=\"selectpicker\" multiple data-selected-text-format=\"count\">\n    <option>Mustard</option>\n    <option>Ketchup</option>\n    <option>Relish</option>\n  </select>\n</div>\n\n```html\n<select class=\"selectpicker\" multiple data-selected-text-format=\"count\">\n  <option>Mustard</option>\n  <option>Ketchup</option>\n  <option>Relish</option>\n</select>\n```\n\n<div class=\"bs-docs-example\">\n  <select class=\"selectpicker\" multiple data-selected-text-format=\"count > 3\">\n    <option>Mustard</option>\n    <option>Ketchup</option>\n    <option>Relish</option>\n    <option>Onions</option>\n  </select>\n</div>\n\n```html\n<select class=\"selectpicker\" multiple data-selected-text-format=\"count > 3\">\n  <option>Mustard</option>\n  <option>Ketchup</option>\n  <option>Relish</option>\n  <option>Onions</option>\n</select>\n```\n\n# Styling\n\n---\n\n## Button classes\n\nYou can set the button classes via the `data-style` attribute:\n\n<div class=\"bs-docs-example\">\n  <div class=\"form-group\">\n    <select class=\"selectpicker\" data-style=\"btn-primary\">\n      <option>Mustard</option>\n      <option>Ketchup</option>\n      <option>Relish</option>\n    </select>\n  </div>\n  <div class=\"form-group\">\n    <select class=\"selectpicker\" data-style=\"btn-info\">\n      <option>Mustard</option>\n      <option>Ketchup</option>\n      <option>Relish</option>\n    </select>\n  </div>\n  <div class=\"form-group\">\n    <select class=\"selectpicker\" data-style=\"btn-success\">\n      <option>Mustard</option>\n      <option>Ketchup</option>\n      <option>Relish</option>\n    </select>\n  </div>\n  <div class=\"form-group\">\n    <select class=\"selectpicker\" data-style=\"btn-warning\">\n      <option>Mustard</option>\n      <option>Ketchup</option>\n      <option>Relish</option>\n    </select>\n  </div>\n  <div class=\"form-group\">\n    <select class=\"selectpicker\" data-style=\"btn-danger\">\n      <option>Mustard</option>\n      <option>Ketchup</option>\n      <option>Relish</option>\n    </select>\n  </div>\n</div>\n\n```html\n<select class=\"selectpicker\" data-style=\"btn-primary\">\n  ...\n</select>\n\n<select class=\"selectpicker\" data-style=\"btn-info\">\n  ...\n</select>\n\n<select class=\"selectpicker\" data-style=\"btn-success\">\n  ...\n</select>\n\n<select class=\"selectpicker\" data-style=\"btn-warning\">\n  ...\n</select>\n\n<select class=\"selectpicker\" data-style=\"btn-danger\">\n  ...\n</select>\n```\n\n## Checkmark on selected option\n\nYou can also show the checkmark icon on standard select boxes with the `show-tick` class:\n\n<div class=\"bs-docs-example\">\n  <select class=\"selectpicker show-tick\">\n    <option>Mustard</option>\n    <option>Ketchup</option>\n    <option>Relish</option>\n  </select>\n</div>\n\n```html\n<select class=\"selectpicker show-tick\">\n  <option>Mustard</option>\n  <option>Ketchup</option>\n  <option>Relish</option>\n</select>\n```\n\n## Menu arrow\n\nThe Bootstrap menu arrow can be added with the `show-menu-arrow` class:\n\n<div class=\"bs-docs-example\">\n  <select class=\"selectpicker show-menu-arrow\">\n    <option>Mustard</option>\n    <option>Ketchup</option>\n    <option>Relish</option>\n  </select>\n</div>\n\n```html\n<select class=\"selectpicker show-menu-arrow\">\n  <option>Mustard</option>\n  <option>Ketchup</option>\n  <option>Relish</option>\n</select>\n```\n\n## Style individual options\n\n<p id=\"classes\"></p>\nClasses and styles added to options are transferred to the select box:\n\n<div class=\"bs-docs-example\">\n  <select class=\"selectpicker\">\n    <option>Mustard</option>\n    <option class=\"special\">Ketchup</option>\n    <option style=\"background: #5cb85c; color: #fff;\">Relish</option>\n  </select>\n</div>\n\n```html\n<select class=\"selectpicker\">\n  <option>Mustard</option>\n  <option class=\"special\">Ketchup</option>\n  <option style=\"background: #5cb85c; color: #fff;\">Relish</option>\n</select>\n```\n\n```css\n.special {\n  font-weight: bold !important;\n  color: #fff !important;\n  background: #bc0000 !important;\n  text-transform: uppercase;\n}\n```\n\n## Width\n\n<p id=\"grid\"></p>\nWrap selects in grid columns, or any custom parent element, to easily enforce desired widths.\n\n<div class=\"bs-docs-example\">\n  <div class=\"row\">\n    <div class=\"col-xs-3\">\n      <div class=\"form-group\">\n        <select class=\"selectpicker form-control\">\n          <option>Mustard</option>\n          <option>Ketchup</option>\n          <option>Relish</option>\n        </select>\n      </div>\n    </div>\n    <div class=\"col-xs-9\">\n      <div class=\"form-group\">\n        <select class=\"selectpicker form-control\">\n          <option>Mustard</option>\n          <option>Ketchup</option>\n          <option>Relish</option>\n        </select>\n      </div>\n    </div>\n  </div>\n  <div class=\"row\">\n    <div class=\"col-xs-4\">\n       <div class=\"form-group\">\n        <select class=\"selectpicker form-control\">\n          <option>Mustard</option>\n          <option>Ketchup</option>\n          <option>Relish</option>\n        </select>\n      </div>\n    </div>\n    <div class=\"col-xs-8\">\n       <div class=\"form-group\">\n        <select class=\"selectpicker form-control\">\n          <option>Mustard</option>\n          <option>Ketchup</option>\n          <option>Relish</option>\n        </select>\n      </div>\n    </div>\n  </div>\n  <div class=\"row\">\n    <div class=\"col-xs-5\">\n      <div class=\"form-group\">\n        <select class=\"selectpicker form-control\">\n          <option>Mustard</option>\n          <option>Ketchup</option>\n          <option>Relish</option>\n        </select>\n      </div>\n    </div>\n    <div class=\"col-xs-7\">\n      <div class=\"form-group\">\n        <select class=\"selectpicker form-control\">\n          <option>Mustard</option>\n          <option>Ketchup</option>\n          <option>Relish</option>\n        </select>\n      </div>\n    </div>\n  </div>\n</div>\n\n```html\n<div class=\"row\">\n  <div class=\"col-xs-3\">\n    <div class=\"form-group\">\n      <select class=\"selectpicker form-control\">\n        <option>Mustard</option>\n        <option>Ketchup</option>\n        <option>Relish</option>\n      </select>\n    </div>\n  </div>\n</div>\n```\n\n<div id=\"data-width\"></div>\n\nAlternatively, use the `data-width` attribute to set the width of the select. Set `data-width` to `'auto'` to automatically adjust the width of the select to its widest option. `'fit'` automatically adjusts the width of the select to the width of its currently selected option. An exact value can also be specified, e.g., `300px` or `50%`.\n\n<div class=\"bs-docs-example\">\n  <div class=\"row\">\n    <div class=\"col-xs-12\">\n      <div class=\"form-group\">\n        <label>width: 'auto'</label>\n        <select class=\"selectpicker form-control\" data-width=\"auto\">\n          <option>Mustard</option>\n          <option>Ketchup</option>\n          <option>Relish</option>\n          <option>All of the above (and much, much more!)</option>\n        </select>\n      </div>\n    </div>\n  </div>\n  <div class=\"row\">\n    <div class=\"col-xs-12\">\n      <div class=\"form-group\">\n        <label>width: 'fit'</label>\n        <select class=\"selectpicker form-control\" data-width=\"fit\">\n          <option>Mustard</option>\n          <option>Ketchup</option>\n          <option>Relish</option>\n          <option>All of the above (and much, much more!)</option>\n        </select>\n      </div>\n    </div>\n  </div>\n  <div class=\"row\">\n    <div class=\"col-xs-12\">\n      <div class=\"form-group\">\n        <label>width: '100px'</label>\n        <select class=\"selectpicker form-control\" data-width=\"100px\">\n          <option>Mustard</option>\n          <option>Ketchup</option>\n          <option>Relish</option>\n          <option>All of the above (and much, much more!)</option>\n        </select>\n      </div>\n    </div>\n  </div>\n  <div class=\"row\">\n    <div class=\"col-xs-12\">\n      <div class=\"form-group\">\n        <label>width: '75%'</label>\n        <select class=\"selectpicker form-control\" data-width=\"75%\">\n          <option>Mustard</option>\n          <option>Ketchup</option>\n          <option>Relish</option>\n          <option>All of the above (and much, much more!)</option>\n        </select>\n      </div>\n    </div>\n  </div>\n</div>\n\n```html\n<select class=\"selectpicker\" data-width=\"auto\">\n  ...\n</select>\n<select class=\"selectpicker\" data-width=\"fit\">\n  ...\n</select>\n<select class=\"selectpicker\" data-width=\"100px\">\n  ...\n</select>\n<select class=\"selectpicker\" data-width=\"75%\">\n  ...\n</select>\n```\n\n# Customize options\n\n---\n\n## Icons\n\nAdd an icon to an option or optgroup with the `data-icon` attribute:\n\n<div class=\"bs-docs-example\">\n  <select class=\"selectpicker\">\n    <option data-icon=\"glyphicon-glass\">Mustard</option>\n    <option data-icon=\"glyphicon-heart\">Ketchup</option>\n    <option data-icon=\"glyphicon-film\">Relish</option>\n    <option data-icon=\"glyphicon-home\">Mayonnaise</option>\n    <option data-icon=\"glyphicon-print\">Barbecue Sauce</option>\n  </select>\n</div>\n\n```html\n<select class=\"selectpicker\">\n  <option data-icon=\"glyphicon-heart\">Ketchup</option>\n</select>\n```\n\n## Custom content\n\nInsert custom HTML into the option with the `data-content` attribute:\n\n<div class=\"bs-docs-example\">\n  <select class=\"selectpicker\">\n    <option data-content=\"<span class='label label-warning'>Mustard</span>\">Mustard</option>\n    <option data-content=\"<span class='label label-danger label-important'>Ketchup</span>\">Ketchup</option>\n    <option data-content=\"<span class='label label-success'>Relish</span>\">Relish</option>\n    <option data-content=\"<span class='label label-info'>Mayonnaise</span>\">Mayonnaise</option>\n  </select>\n</div>\n\n```html\n<select class=\"selectpicker\">\n  <option data-content=\"<span class='label label-success'>Relish</span>\">Relish</option>\n</select>\n```\n\n## Subtext\nAdd subtext to an option or optgroup with the `data-subtext` attribute:\n\n<div class=\"bs-docs-example\">\n  <div class=\"form-group\">\n    <select class=\"selectpicker\">\n      <option data-subtext=\"French's\">Mustard</option>\n      <option data-subtext=\"Heinz\">Ketchup</option>\n      <option data-subtext=\"Sweet\">Relish</option>\n      <option data-subtext=\"Miracle Whip\">Mayonnaise</option>\n      <option data-divider=\"true\"></option>\n      <option data-subtext=\"Honey\">Barbecue Sauce</option>\n      <option data-subtext=\"Ranch\">Salad Dressing</option>\n      <option data-subtext=\"Sweet & Spicy\">Tabasco</option>\n      <option data-subtext=\"Chunky\">Salsa</option>\n    </select>\n  </div>\n\n  <div class=\"form-group\">\n    <select class=\"selectpicker\" data-show-subtext=\"true\">\n      <option data-subtext=\"French's\">Mustard</option>\n      <option data-subtext=\"Heinz\">Ketchup</option>\n      <option data-subtext=\"Sweet\">Relish</option>\n      <option data-subtext=\"Miracle Whip\">Mayonnaise</option>\n      <option data-divider=\"true\"></option>\n      <option data-subtext=\"Honey\">Barbecue Sauce</option>\n      <option data-subtext=\"Ranch\">Salad Dressing</option>\n      <option data-subtext=\"Sweet & Spicy\">Tabasco</option>\n      <option data-subtext=\"Chunky\">Salsa</option>\n    </select>\n    <span class=\"help-block\">With <code>showSubtext</code> set to true.</span>\n  </div>\n</div>\n\n```html\n<select class=\"selectpicker\" data-size=\"5\">\n  <option data-subtext=\"Heinz\">Ketchup</option>\n</select>\n```\n\n# Customize menu\n\n---\n\n## Menu size\n\nThe `size` option is set to `'auto'` by default. When `size` is set to `'auto'`, the menu always opens up to show as many items as the window will allow without being cut off. Set `size` to `false` to always show all items. The size of the menu can also be specifed using the `data-size` attribute.\n\n<div class=\"bs-docs-example\">\n  <select class=\"selectpicker\">\n    <option>Mustard</option>\n    <option>Ketchup</option>\n    <option>Relish</option>\n    <option>Mayonnaise</option>\n    <option>Barbecue Sauce</option>\n    <option>Salad Dressing</option>\n    <option>Tabasco</option>\n    <option>Salsa</option>\n    <option>Mustard</option>\n    <option>Ketchup</option>\n    <option>Relish</option>\n    <option>Mayonnaise</option>\n    <option>Barbecue Sauce</option>\n    <option>Salad Dressing</option>\n    <option>Tabasco</option>\n    <option>Salsa</option>\n    <option>Mustard</option>\n    <option>Ketchup</option>\n    <option>Relish</option>\n    <option>Mayonnaise</option>\n    <option>Barbecue Sauce</option>\n    <option>Salad Dressing</option>\n    <option>Tabasco</option>\n    <option>Salsa</option>\n  </select>\n</div>\n\n<p id=\"data-size\"></p>\nSpecify a number for `data-size` to choose the maximum number of items to show in the menu.\n\n<div class=\"bs-docs-example\">\n  <select class=\"selectpicker\" data-size=\"5\">\n    <option>Mustard</option>\n    <option>Ketchup</option>\n    <option>Relish</option>\n    <option>Mayonnaise</option>\n    <option>Barbecue Sauce</option>\n    <option>Salad Dressing</option>\n    <option>Tabasco</option>\n    <option>Salsa</option>\n  </select>\n</div>\n\n```html\n<select class=\"selectpicker\" data-size=\"5\">\n  ...\n</select>\n```\n\n## Select/deselect all options\n\nAdds two buttons to the top of the menu - **Select All** & **Deselect All** with `data-actions-box=\"true\"`.\n\n<div class=\"bs-docs-example\">\n  <select class=\"selectpicker\" multiple data-actions-box=\"true\">\n    <option>Mustard</option>\n    <option>Ketchup</option>\n    <option>Relish</option>\n  </select>\n</div>\n\n```html\n<select class=\"selectpicker\" multiple data-actions-box=\"true\">\n  <option>Mustard</option>\n  <option>Ketchup</option>\n  <option>Relish</option>\n</select>\n```\n\n## Divider\n\nAdd `data-divider=\"true\"` to an option to turn it into a divider.\n\n<div class=\"bs-docs-example\">\n  <select class=\"selectpicker\">\n    <option>Mustard</option>\n    <option>Ketchup</option>\n    <option>Relish</option>\n    <option>Mayonnaise</option>\n    <option data-divider=\"true\"></option>\n    <option>Barbecue Sauce</option>\n    <option>Salad Dressing</option>\n    <option>Tabasco</option>\n    <option>Salsa</option>\n  </select>\n</div>\n\n```html\n<select class=\"selectpicker\" data-size=\"5\">\n  <option data-divider=\"true\"></option>\n</select>\n```\n\n## Menu header\n\nAdd a header to the dropdown menu, e.g. `header: 'Select a condiment'` or `data-header=\"Select a condiment\"`\n\n<div class=\"bs-docs-example\">\n  <div class=\"row-fluid\">\n    <select class=\"selectpicker\" data-header=\"Select a condiment\">\n      <option data-subtext=\"French's\">Mustard</option>\n      <option data-subtext=\"Heinz\">Ketchup</option>\n      <option data-subtext=\"Sweet\">Relish</option>\n      <option data-subtext=\"Miracle Whip\">Mayonnaise</option>\n      <option data-divider=\"true\"></option>\n      <option data-subtext=\"Honey\">Barbecue Sauce</option>\n      <option data-subtext=\"Ranch\">Salad Dressing</option>\n      <option data-subtext=\"Sweet & Spicy\">Tabasco</option>\n      <option data-subtext=\"Chunky\">Salsa</option>\n    </select>\n  </div>\n</div>\n\n```html\n<select class=\"selectpicker\" data-header=\"Select a condiment\">\n  ...\n</select>\n```\n\n## Container\n\nAppend the select to a specific element, e.g. `container: 'body'` or `data-container=\".main-content\"`\n\n<div class=\"bs-docs-example\" style=\"overflow:hidden;\">\n  <div class=\"row-fluid\">\n    <select class=\"selectpicker\">\n      <option data-subtext=\"French's\">Mustard</option>\n      <option data-subtext=\"Heinz\">Ketchup</option>\n      <option data-subtext=\"Sweet\">Relish</option>\n      <option data-subtext=\"Miracle Whip\">Mayonnaise</option>\n      <option data-divider=\"true\"></option>\n      <option data-subtext=\"Honey\">Barbecue Sauce</option>\n      <option data-subtext=\"Ranch\">Salad Dressing</option>\n      <option data-subtext=\"Sweet & Spicy\">Tabasco</option>\n      <option data-subtext=\"Chunky\">Salsa</option>\n    </select>\n    <select class=\"selectpicker\" data-container=\"body\">\n      <option data-subtext=\"French's\">Mustard</option>\n      <option data-subtext=\"Heinz\">Ketchup</option>\n      <option data-subtext=\"Sweet\">Relish</option>\n      <option data-subtext=\"Miracle Whip\">Mayonnaise</option>\n      <option data-divider=\"true\"></option>\n      <option data-subtext=\"Honey\">Barbecue Sauce</option>\n      <option data-subtext=\"Ranch\">Salad Dressing</option>\n      <option data-subtext=\"Sweet & Spicy\">Tabasco</option>\n      <option data-subtext=\"Chunky\">Salsa</option>\n    </select>\n  </div>\n</div>\n\n```html\n<div style=\"overflow:hidden;\">\n  <select class=\"selectpicker\">\n    ...\n  </select>\n  <select class=\"selectpicker\" data-container=\"body\">\n    ...\n  </select>\n</div>\n```\n\n## Dropup menu\n\n`dropupAuto` is set to true by default, which automatically determines whether or not the menu should display above or below the select box. If `dropupAuto` is set to false, manually make the select a dropup menu by adding the `.dropup` class to the select.\n\n<div class=\"bs-docs-example\">\n  <select class=\"selectpicker dropup\">\n    <option>Mustard</option>\n    <option>Ketchup</option>\n    <option>Relish</option>\n  </select>\n</div>\n\n```html\n<select class=\"selectpicker dropup\">\n  ...\n</select>\n```\n\n# Disabled\n\n---\n\n## Disabled select box\n\n<div class=\"bs-docs-example\">\n  <select class=\"selectpicker\" disabled>\n    <option>Mustard</option>\n    <option>Ketchup</option>\n    <option>Relish</option>\n  </select>\n</div>\n\n```html\n<select class=\"selectpicker\" disabled>\n  <option>Mustard</option>\n  <option>Ketchup</option>\n  <option>Relish</option>\n</select>\n```\n\n## Disabled options\n\n<div class=\"bs-docs-example\">\n  <select class=\"selectpicker\">\n    <option>Mustard</option>\n    <option disabled>Ketchup</option>\n    <option>Relish</option>\n  </select>\n</div>\n\n```html\n<select class=\"selectpicker\">\n  <option>Mustard</option>\n  <option disabled>Ketchup</option>\n  <option>Relish</option>\n</select>\n```\n\n## Disabled option groups\n\n<div class=\"bs-docs-example\">\n  <select class=\"selectpicker test\">\n    <optgroup label=\"Picnic\" disabled>\n      <option>Mustard</option>\n      <option>Ketchup</option>\n      <option>Relish</option>\n    </optgroup>\n    <optgroup label=\"Camping\">\n      <option>Tent</option>\n      <option>Flashlight</option>\n      <option>Toilet Paper</option>\n    </optgroup>\n  </select>\n</div>\n\n```html\n<select class=\"selectpicker test\">\n  <optgroup label=\"Picnic\" disabled>\n    <option>Mustard</option>\n    <option>Ketchup</option>\n    <option>Relish</option>\n  </optgroup>\n  <optgroup label=\"Camping\">\n    <option>Tent</option>\n    <option>Flashlight</option>\n    <option>Toilet Paper</option>\n  </optgroup>\n</select>\n```"
  },
  {
    "path": "app_backend/static/plugin/bootstrap-select-1.12.2/docs/docs/index.md",
    "content": "# Getting Started\n\n---\n\n## Dependencies\n\nRequires jQuery v1.8.0+, Bootstrap’s dropdown.js component, and Bootstrap's CSS. If you're not already using Bootstrap in your project, a precompiled version of the minimum requirements can be downloaded [here](http://getbootstrap.com/customize/?id=7830063837006f6fc84f).\n\n## CDNJS\n\nThe folks at CDNJS host a copy of the library. The CDN is updated after the release is made public, which means there is a delay between the publishing of a release and its availability on the CDN, so keep that in mind. Just use these links:\n\n```html\n<!-- Latest compiled and minified CSS -->\n<link rel=\"stylesheet\" href=\"https://cdnjs.cloudflare.com/ajax/libs/bootstrap-select/1.12.2/css/bootstrap-select.min.css\">\n\n<!-- Latest compiled and minified JavaScript -->\n<script src=\"https://cdnjs.cloudflare.com/ajax/libs/bootstrap-select/1.12.2/js/bootstrap-select.min.js\"></script>\n\n<!-- (Optional) Latest compiled and minified JavaScript translation files -->\n<script src=\"https://cdnjs.cloudflare.com/ajax/libs/bootstrap-select/1.12.2/js/i18n/defaults-*.min.js\"></script>\n```\n\n## Install with Bower\n\nYou can also install bootstrap-select using [Bower](http://bower.io):\n\n```elixir\n$ bower install bootstrap-select\n```\n\n## Install with npm\n\nYou can also install bootstrap-select using [npm](https://www.npmjs.com/package/bootstrap-select):\n\n```elixir\n$ npm install bootstrap-select\n```\n\n## Install with NuGet\n\nYou can also install bootstrap-select using [NuGet](https://www.nuget.org/packages/bootstrap-select):\n\n```elixir\n$ Install-Package bootstrap-select\n```\n\n# Usage\n\n---\n\nCreate your `<select>` with the `.selectpicker` class. The data-api will automatically theme these elements.\n\n```html\n<select class=\"selectpicker\">\n  <option>Mustard</option>\n  <option>Ketchup</option>\n  <option>Relish</option>\n</select>\n```\n\nOptions can be passed via data attributes or JavaScript.\n\n```js\n$('.selectpicker').selectpicker({\n  style: 'btn-info',\n  size: 4\n});\n```\n\n# Used by\n\n---\n\n<div class=\"row logo-block\">\n\t<div class=\"logo-container\">\n\t\t<a href=\"https://snapappointments.com\" target=\"_blank\"><img src=\"img/logos/snapappointments.png\" alt=\"SnapAppointments\"></a>\n\t</div>\n\t<div class=\"logo-container\">\n\t\t<a href=\"https://www.thermofisher.com\" target=\"_blank\"><img src=\"img/logos/thermofisher.png\" alt=\"Thermo Fisher Scientific Inc.\"></a>\n\t</div>\n\t<div class=\"logo-container\">\n\t\t<a href=\"https://www.membermeister.com\" target=\"_blank\"><img src=\"img/logos/membermeister.png\" alt=\"membermeister\"></a>\n\t</div>\n\t<div class=\"logo-container\">\n\t\t<a href=\"https://solveforall.com\" target=\"_blank\"><img src=\"img/logos/solveforall.png\" alt=\"Solve for All\"></a>\n\t</div>\n\t<div class=\"logo-container\">\n\t\t<a href=\"http://www.123itworks.co.uk\" target=\"_blank\"><img src=\"img/logos/estimateit.png\" alt=\"EstiMATEit\"></a>\n\t</div>\n\t<div class=\"logo-container\">\n\t\t<a href=\"https://convertizer.com\" target=\"_blank\"><img src=\"img/logos/convertizer.png\" alt=\"Convertizer\"></a>\n\t</div>\n</div>\n\n<div class=\"text-muted\">Does your organization use bootstrap-select? Open an issue, and include a link and logo, and you'll be added to the list.</div>\n\n\n"
  },
  {
    "path": "app_backend/static/plugin/bootstrap-select-1.12.2/docs/docs/methods.md",
    "content": "# Methods\n\nInterface with bootstrap-select.\n\n---\n\n#### `.selectpicker('val')`\n\nYou can set the selected value by calling the `val` method on the element.\n\n```js\n$('.selectpicker').selectpicker('val', 'Mustard');\n$('.selectpicker').selectpicker('val', ['Mustard','Relish']);\n```\n\nThis is different to calling `val()` directly on the `select` element. If you call `val()` on the element directly, the bootstrap-select ui will not refresh (as the change event only fires from user interaction). You will have to call the ui refresh method yourself.\n\n```js\n$('.selectpicker').val('Mustard');\n$('.selectpicker').selectpicker('render');\n\n// this is the equivalent of the above\n$('.selectpicker').selectpicker('val', 'Mustard');\n```\n\n---\n\n#### `.selectpicker('selectAll')`\n\nThis will select all items in a multi-select.\n\n```js\n$('.selectpicker').selectpicker('selectAll');\n```\n\n---\n\n#### `.selectpicker('deselectAll')`\n\nThis will deselect all items in a multi-select.\n\n```js\n$('.selectpicker').selectpicker('deselectAll');\n```\n\n---\n\n#### `.selectpicker('render')`\n\nYou can force a re-render of the bootstrap-select ui with the `render` method. This is useful if you programatically change any underlying values that affect the layout of the element.\n\n```js\n$('.selectpicker').selectpicker('render');\n```\n\n---\n\n#### `.selectpicker('mobile')`\n\nEnable mobile scrolling by calling `$('.selectpicker').selectpicker('mobile')`. This enables the device's native menu for select menus.\n\nThe method for detecting the browser is left up to the user.\n\n```js\nif( /Android|webOS|iPhone|iPad|iPod|BlackBerry/i.test(navigator.userAgent) ) {\n  $('.selectpicker').selectpicker('mobile');\n}\n```\n\n---\n\n#### `.selectpicker('setStyle')`\n\nModify the class(es) associated with either the button itself or its container.\n\nIf changing the class on the container:\n\n```js\n$('.selectpicker').addClass('col-lg-12').selectpicker('setStyle');\n```\n\nIf changing the class(es) on the button (altering data-style):\n\n```js\n// Replace Class\n$('.selectpicker').selectpicker('setStyle', 'btn-danger');\n\n// Add Class\n$('.selectpicker').selectpicker('setStyle', 'btn-large', 'add');\n\n// Remove Class\n$('.selectpicker').selectpicker('setStyle', 'btn-large', 'remove');\n```\n\n\n---\n\n#### `.selectpicker('refresh')`\n\nTo programmatically update a select with JavaScript, first manipulate the select, then use the `refresh` method to \nupdate the UI to match the new state. This is necessary when removing or adding options, or when disabling/enabling a \nselect via JavaScript.\n\n```js\n$('.selectpicker').selectpicker('refresh');\n```\n\n<div class=\"bs-docs-example\">\n  <div class=\"form-group\">\n    <select class=\"selectpicker remove-example\">\n      <option value=\"Mustard\">Mustard</option>\n      <option value=\"Ketchup\">Ketchup</option>\n      <option value=\"Relish\">Relish</option>\n    </select>\n  </div>\n\n  <button class=\"btn btn-warning rm-mustard\">Remove Mustard</button>\n  <button class=\"btn btn-danger rm-ketchup\">Remove Ketchup</button>\n  <button class=\"btn btn-success rm-relish\">Remove Relish</button>\n</div>\n\n```html\n<select class=\"selectpicker remove-example\">\n  <option value=\"Mustard\">Mustard</option>\n  <option value=\"Ketchup\">Ketchup</option>\n  <option value=\"Relish\">Relish</option>\n</select>\n\n<button class=\"btn btn-warning rm-mustard\">Remove Mustard</button>\n<button class=\"btn btn-danger rm-ketchup\">Remove Ketchup</button>\n<button class=\"btn btn-success rm-relish\">Remove Relish</button>\n```\n```js\n$('.rm-mustard').click(function () {\n  $('.remove-example').find('[value=Mustard]').remove();\n  $('.remove-example').selectpicker('refresh');\n});\n```\n\n<div class=\"bs-docs-example\">\n  <div class=\"form-group\">\n    <select class=\"selectpicker disable-example\">\n      <option value=\"Mustard\">Mustard</option>\n      <option value=\"Ketchup\">Ketchup</option>\n      <option value=\"Relish\">Relish</option>\n    </select>\n  </div>\n\n  <button class=\"btn btn-default ex-disable\"><i class=\"icon-remove\"></i> Disable</button>\n  <button class=\"btn btn-default ex-enable\"><i class=\"icon-ok\"></i> Enable</button>\n</div>\n\n```js\n$('.ex-disable').click(function () {\n  $('.disable-example').prop('disabled', true);\n  $('.disable-example').selectpicker('refresh');\n});\n\n$('.ex-enable').click(function () {\n  $('.disable-example').prop('disabled', false);\n  $('.disable-example').selectpicker('refresh');\n});\n```\n\n<script type=\"text/javascript\">\n  window.onload = function () {\n    var $re = $('.remove-example'),\n        $de = $('.disable-example');\n\n    $('.rm-mustard').click(function () {\n      $re.find('[value=Mustard]').remove();\n      $re.selectpicker('refresh');\n    });\n    $('.rm-ketchup').click(function () {\n      $re.find('[value=Ketchup]').remove();\n      $re.selectpicker('refresh');\n    });\n    $('.rm-relish').click(function () {\n      $re.find('[value=Relish]').remove();\n      $re.selectpicker('refresh');\n    });\n    $('.ex-disable').click(function () {\n      $de.prop('disabled', true);\n      $de.selectpicker('refresh');\n    });\n    $('.ex-enable').click(function () {\n      $de.prop('disabled', false);\n      $de.selectpicker('refresh');\n    });\n  };\n</script>\n\n---\n\n#### `.selectpicker('toggle')`\n\nProgrammatically toggles the bootstrap-select menu open/closed.\n\n```js\n$('.selectpicker').selectpicker('toggle');\n```\n\n---\n\n#### `.selectpicker('hide')`\n\nTo programmatically hide the bootstrap-select use the `hide` method (this only affects the visibility of the bootstrap-select itself).\n\n```js\n$('.selectpicker').selectpicker('hide');\n```\n\n---\n\n#### `.selectpicker('show')`\n\nTo programmatically show the bootstrap-select use the `show` method (this only affects the visibility of the bootstrap-select itself).\n\n```js\n$('.selectpicker').selectpicker('show');\n```\n\n---\n\n#### `.selectpicker('destroy')`\n\nTo programmatically destroy the bootstrap-select, use the `destroy` method.\n\n```js\n$('.selectpicker').selectpicker('destroy');\n```\n"
  },
  {
    "path": "app_backend/static/plugin/bootstrap-select-1.12.2/docs/docs/options.md",
    "content": "# Core options\n\n---\n\nOptions can be passed via data attributes or JavaScript. For data attributes, append the option name to `data-`, as in \n`data-style=\"\"` or `data-selected-text-format=\"count\"`.\n\n<table class=\"table table-bordered table-striped\">\n  <thead>\n  <tr>\n    <th style=\"width: 15%;\">Name</th>\n    <th style=\"width: 32%;\">Type</th>\n    <th style=\"width: 10%;\">Default</th>\n    <th style=\"width: 43%;\">Description</th>\n  </tr>\n  </thead>\n  <tbody>\n  <tr>\n    <td>actionsBox</td>\n    <td>boolean</td>\n    <td><code>false</code></td>\n    <td>\n      <p>When set to <code>true</code>, adds two buttons to the top of the dropdown menu (<strong>Select All</strong> &amp; <strong>Deselect All</strong>).</p>\n    </td>\n  </tr>\n  <tr>\n    <td>container</td>\n    <td>string | false</td>\n    <td><code>false</code></td>\n    <td>\n        <p>When set to a string, appends the select to a specific element or selector, e.g., \n        <code>container: 'body' | '.main-body'</code></p>\n    </td>\n  </tr>\n  <tr>\n    <td>countSelectedText</td>\n    <td>string | function</td>\n    <td><code>function</code></td>\n    <td>\n      <p>Sets the format for the text displayed when selectedTextFormat is <code>count</code> or <code>count > \n      #</code>. {0} is the selected amount. {1} is total available for selection.</p>\n      <p>When set to a function, the first parameter is the number of selected options, and the second is the total number of \n      options. The function must return a string.</p>\n    </td>\n  </tr>\n  <tr>\n    <td>deselectAllText</td>\n    <td>string</td>\n    <td><code>'Deselect All'</code></td>\n    <td>\n      <p>The text on the button that deselects all options when <code>actionsBox</code> is enabled.</p>\n    </td>\n  </tr>\n  <tr>\n    <td>dropdownAlignRight</td>\n    <td>boolean | <code>'auto'</code></td>\n    <td><code>false</code></td>\n    <td>\n      <p>Align the menu to the right instead of the left. If set to <code>'auto'</code>, the menu will automatically align right if there isn't room for the menu's full width when aligned to the left.</p>\n    </td>\n  </tr>\n  <tr>\n    <td>dropupAuto</td>\n    <td>boolean</td>\n    <td><code>true</code></td>\n    <td>\n      <p>checks to see which has more room, above or below. If the dropup has enough room to fully open normally, but\n      there is more room above, the dropup still opens normally. Otherwise, it becomes a dropup. If dropupAuto is\n      set to false, dropups must be called manually.</p>\n    </td>\n  </tr>\n  <tr>\n    <td>header</td>\n    <td>string</td>\n    <td><code>false</code></td>\n    <td>\n      <p>adds a header to the top of the menu; includes a close button by default</p>\n    </td>\n  </tr>\n  <tr>\n    <td>hideDisabled</td>\n    <td>boolean</td>\n    <td><code>false</code></td>\n    <td>\n      <p>removes disabled options and optgroups from the menu <code>data-hide-disabled: true</code></p>\n    </td>\n  </tr>\n  <tr>\n    <td>iconBase</td>\n    <td>string</td>\n    <td><code>'glyphicon'</code></td>\n    <td>\n      <p>Set the base to use a different icon font instead of Glyphicons. If changing iconBase, you might also want to change <code>tickIcon</code>, in case the new icon font uses a different naming scheme.</p>\n    </td>\n  </tr>\n  <tr>\n    <td>liveSearch</td>\n    <td>boolean</td>\n    <td><code>false</code></td>\n    <td>\n      <p>When set to <code>true</code>, adds a search box to the top of the selectpicker dropdown.</p>\n    </td>\n  </tr>\n  <tr>\n    <td>liveSearchNormalize</td>\n    <td>boolean</td>\n    <td><code>false</code></td>\n    <td>\n      <p>Setting liveSearchNormalize to <code>true</code> allows for accent-insensitive searching.</p>\n    </td>\n  </tr>\n  <tr>\n    <td>liveSearchPlaceholder</td>\n    <td>string</td>\n    <td><code>null</code></td>\n    <td>\n      <p>When set to a string, a placeholder attribute equal to the string will be added to the liveSearch input.</p>\n    </td>\n  </tr>\n  <tr>\n    <td>liveSearchStyle</td>\n    <td>string</td>\n    <td><code>'contains'</code></td>\n    <td>\n      <p>When set to <code>'contains'</code>, searching will reveal options that contain the searched text. For example, searching for pl with return both Ap<b>pl</b>e, <b>Pl</b>um, and <b>Pl</b>antain. When set to <code>'startsWith'</code>, searching for pl will return only <b>Pl</b>um and <b>Pl</b>antain.</p>\n    </td>\n  </tr>\n  <tr>\n    <td>maxOptions</td>\n    <td>integer | false</td>\n    <td><code>false</code></td>\n    <td>\n      <p>When set to an integer and in a multi-select, the number of selected options cannot exceed the given value.</p>\n      <p>This option can also exist as a data-attribute for an <code>&lt;optgroup&gt;</code>, in which case it only \n      applies to that <code>&lt;optgroup&gt;</code>.</p>\n    </td>\n  </tr>\n  <tr>\n    <td>maxOptionsText</td>\n    <td>string | array | function</td>\n    <td><code>function</code></td>\n    <td>\n      <p>The text that is displayed when maxOptions is enabled and the maximum number of options for the given scenario have been selected.</p>\n      <p>If a function is used, it must return an array. array[0] is the text used when maxOptions is applied to the entire select element. array[1] is the text used when maxOptions is used on an optgroup. If a string is used, the same text is used for both the element and the optgroup.</p>\n    </td>\n  </tr>\n  <tr>\n    <td>mobile</td>\n    <td>boolean</td>\n    <td><code>false</code></td>\n    <td>\n      <p>When set to <code>true</code>, enables the device's native menu for select menus.</p>\n    </td>\n  </tr>\n  <tr>\n    <td>multipleSeparator</td>\n    <td>string</td>\n    <td><code>', '</code></td>\n    <td>\n      <p>Set the character displayed in the button that separates selected options.</p>\n    </td>\n  </tr>\n  <tr>\n    <td>noneSelectedText</td>\n    <td>string</td>\n    <td><code>'Nothing selected'</code></td>\n    <td>\n      <p>The text that is displayed when a multiple select has no selected options.</p>\n    </td>\n  </tr>\n  <tr>\n    <td>selectAllText</td>\n    <td>string</td>\n    <td><code>'Select All'</code></td>\n    <td>\n      <p>The text on the button that selects all options when <code>actionsBox</code> is enabled.</p>\n    </td>\n  </tr>\n  <tr>\n    <td>selectedTextFormat</td>\n    <td><code>'values'</code> | <code>'static'</code> | <code>'count'</code> | <code>'count > x'</code> (where x is an integer)</td>\n    <td><code>'values'</code></td>\n    <td>\n      <p>Specifies how the selection is displayed with a multiple select.</p>\n      <p><code>'values'</code> displays a list of the selected options (separated by <code>multipleSeparator</code>. <code>'static'</code> simply displays the select element's title. <code>'count'</code> displays the total number of selected options. <code>'count > x'</code> behaves like <code>'values'</code> until the number of selected options is greater than x; after that, it behaves like <code>'count'</code>.\n    </td>\n  </tr>\n  <tr>\n    <td>selectOnTab</td>\n    <td>boolean</td>\n    <td><code>false</code></td>\n    <td>\n      <p>When set to <code>true</code>, treats the tab character like the enter or space characters within the \n      selectpicker dropdown.</p>\n    </td>\n  </tr>\n  <tr>\n    <td>showContent</td>\n    <td>boolean</td>\n    <td><code>true</code></td>\n    <td>\n      <p>When set to <code>true</code>, display custom HTML associated with selected option(s) in the button. When set \n       to <code>false</code>, the option value will be displayed instead.</p>\n    </td>\n  </tr>\n  <tr>\n    <td>showIcon</td>\n    <td>boolean</td>\n    <td><code>true</code></td>\n    <td>\n      <p>When set to <code>true</code>, display icon(s) associated with selected option(s) in the button.</p>\n    </td>\n  </tr>\n  <tr>\n    <td>showSubtext</td>\n    <td>boolean</td>\n    <td><code>false</code></td>\n    <td>\n      <p>When set to <code>true</code>, display subtext associated with a selected option in the button.</p>\n    </td>\n  </tr>\n  <tr>\n    <td>showTick</td>\n    <td>boolean</td>\n    <td><code>false</code></td>\n    <td>\n      <p>Show checkmark on selected option (for items without <code>multiple</code> attribute).</p>\n    </td>\n  </tr>\n  <tr>\n    <td>size</td>\n    <td><code>'auto'</code> | integer | false</td>\n    <td><code>'auto'</code></td>\n    <td>\n      <p>When set to <code>'auto'</code>, the menu always opens up to show as many items as the window will allow\n      without being cut off.</p>\n      <p>When set to an integer, the menu will show the given number of items, even if the dropdown is cut off.</p>\n      <p>When set to <code>false</code>, the menu will always show all items.</p>\n    </td>\n  </tr>\n  <tr>\n    <td>style</td>\n    <td>string | null</td>\n    <td><code>null</code></td>\n    <td>\n      <p>When set to a string, add the value to the button's style.</p>\n    </td>\n  </tr>\n  <tr>\n    <td>tickIcon</td>\n    <td>string</td>\n    <td><code>'glyphicon-ok'</code></td>\n    <td>\n      <p>Set which icon to use to display as the \"tick\" next to selected options.</p>\n    </td>\n  </tr>\n  <tr>\n    <td>title</td>\n    <td>string | null</td>\n    <td><code>null</code></td>\n    <td>\n      <p>The default title for the selectpicker.</p>\n    </td>\n  </tr>\n  <tr>\n    <td>width</td>\n    <td><code>'auto'</code> | <code>'fit'</code> | css-width | false (where <code>css-width</code> is a CSS width with units, e.g. <code>100px</code>)</td>\n    <td><code>false</code></td>\n    <td>\n      <p>When set to <code>auto</code>, the width of the selectpicker is automatically adjusted to accommodate the \n      widest option.</p>\n      <p>When set to a css-width, the width of the selectpicker is forced inline to the given value.</p>\n      <p>When set to <code>false</code>, all width information is removed.</p>\n    </td>\n  </tr>\n  <tr>\n    <td>windowPadding</td>\n    <td>integer | array</td>\n    <td><code>0</code></td>\n    <td>\n      <p>This is useful in cases where the window has areas that the dropdown menu should not cover - for instance a fixed header. When set to an integer, the same padding will be added to all sides. Alternatively, an array of integers can be used in the format <code>[top, right, bottom, left]</code>.</p>\n    </td>\n  </tr>\n  </tbody>\n</table>\n\n# Events\n\n---\n\nBootstrap-select exposes a few events for hooking into select functionality.\n\nhide.bs.select, hidden.bs.select, show.bs.select, and shown.bs.select all have a `relatedTarget` property, whose value is the toggling anchor element.\n\n<table class=\"table table-bordered table-striped\">\n  <thead>\n    <tr>\n      <th>Event Type</th>\n      <th>Description</th>\n    </tr>\n  </thead>\n  <tbody>\n    <tr>\n      <td>show.bs.select</td>\n      <td>This event fires immediately when the show instance method is called.</td>\n    </tr>\n    <tr>\n      <td>shown.bs.select</td>\n      <td>This event is fired when the dropdown has been made visible to the user (will wait for CSS transitions, to complete).</td>\n    </tr>\n    <tr>\n      <td>hide.bs.select</td>\n      <td>This event is fired immediately when the hide instance method has been called.</td>\n    </tr>\n    <tr>\n      <td>hidden.bs.select</td>\n      <td>This event is fired when the dropdown has finished being hidden from the user (will wait for CSS transitions, to complete).</td>\n    </tr>\n    <tr>\n      <td>loaded.bs.select</td>\n      <td>This event fires after the select has been initialized.</td>\n    </tr>\n    <tr>\n      <td>rendered.bs.select</td>\n      <td>This event fires after the render instance has been called.</td>\n    </tr>\n    <tr>\n      <td>refreshed.bs.select</td>\n      <td>This event fires after the refresh instance has been called.</td>\n    </tr>\n    <tr>\n      <td>changed.bs.select</td>\n      <td>This event fires after the select's value has been changed. It passes through event, clickedIndex, newValue, oldValue.</td>\n    </tr>\n  </tbody>\n</table>\n\n```js\n$('#mySelect').on('hidden.bs.select', function (e) {\n  // do something...\n});\n```\n"
  },
  {
    "path": "app_backend/static/plugin/bootstrap-select-1.12.2/docs/docs/playground/index.html",
    "content": "<!DOCTYPE html>\n<html>\n\n  <head>\n    <script data-require=\"jquery@2.2.0\" data-semver=\"2.2.0\" src=\"https://ajax.googleapis.com/ajax/libs/jquery/2.2.0/jquery.min.js\"></script>\n    <script src=\"plnkrOpener.js\"></script>\n  </head>\n\n  <body>\n  </body>\n\n</html>"
  },
  {
    "path": "app_backend/static/plugin/bootstrap-select-1.12.2/docs/docs/playground/plnkrOpener.js",
    "content": "$(document).ready(function() {\n  function formPostData(url, fields) {\n    var form = $('<form style=\"display: none;\" method=\"post\" action=\"' + url + '\"></form>');\n    $.each(fields, function(name, value) {\n      var input = $('<input type=\"hidden\" name=\"' + name + '\">');\n      input.attr('value', value);\n      form.append(input);\n    });\n\n    $(document).find('body').append(form);\n\n    form[0].submit(function(e) {\n      e.preventDefault();\n    });\n\n    form.remove();\n  }\n  \n  function plnkrOpener() {\n    var ctrl = {};\n  \n    ctrl.example = {\n      path: ctrl.examplePath,\n      manifest: undefined,\n      files: undefined,\n      name: 'bootstrap-select example'\n    };\n  \n    ctrl.open = function() {\n      var postData = {\n        'tags[0]': 'jquery',\n        'tags[1]': 'bootstrap-select',\n        'private': true\n      };\n  \n      ctrl.example.files = [\n        {\n          name: 'index.html',\n          url: 'test.html',\n          content: ''\n        },\n        {\n          name: 'bootstrap-select.js',\n          url: 'https://raw.githubusercontent.com/silviomoreto/bootstrap-select/master/dist/js/bootstrap-select.js',\n          content: ''\n        },\n        {\n          name: 'bootstrap-select.css',\n          url: 'https://raw.githubusercontent.com/silviomoreto/bootstrap-select/master/dist/css/bootstrap-select.css',\n          content: ''\n        }\n      ]\n\n      function getData(file) {\n        return $.ajax({\n          method: 'GET',\n          url: file.url\n        })\n        .then(function(data) {\n          file.content = data;\n          postData['files[' + file.name + ']'] = file.content;\n        });\n      }\n\n      var files = [];\n\n      $.each(ctrl.example.files, function(i, file) {\n        files.push(getData(file));\n      });\n\n      function sendData() {\n        postData.description = ctrl.example.name;\n\n        formPostData('https://plnkr.co/edit/?p=preview', postData);\n      };\n\n      $.when.apply(this, files).done(function() {\n        sendData();\n      });\n    };\n    \n    return ctrl.open()\n  }\n\n  plnkrOpener();\n});"
  },
  {
    "path": "app_backend/static/plugin/bootstrap-select-1.12.2/docs/docs/playground/test.html",
    "content": "<!DOCTYPE html>\n<html>\n<head>\n  <title>Bootstrap-select test page</title>\n\n  <meta charset=\"utf-8\">\n\n  <link rel=\"stylesheet\" href=\"https://maxcdn.bootstrapcdn.com/bootstrap/3.3.4/css/bootstrap.min.css\">\n  <link rel=\"stylesheet\" href=\"bootstrap-select.css\">\n\n  <script src=\"https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js\"></script>\n  <script src=\"https://maxcdn.bootstrapcdn.com/bootstrap/3.3.4/js/bootstrap.min.js\"></script>\n  <script src=\"bootstrap-select.js\"></script>\n</head>\n<body>\n\n<div class=\"container\">\n  <form class=\"form-horizontal\" role=\"form\">\n    <div class=\"form-group\">\n      <label for=\"basic\" class=\"col-lg-2 control-label\">\"Basic\" (liveSearch disabled)</label>\n\n      <div class=\"col-lg-10\">\n        <select id=\"basic\" class=\"selectpicker show-tick form-control\">\n          <option>cow</option>\n          <option data-subtext=\"option subtext\">bull</option>\n          <option class=\"get-class\" disabled>ox</option>\n          <optgroup label=\"test\" data-subtext=\"optgroup subtext\">\n            <option>ASD</option>\n            <option selected>Bla</option>\n            <option>Ble</option>\n          </optgroup>\n        </select>\n      </div>\n    </div>\n  </form>\n\n  <hr>\n\n  <form class=\"form-horizontal\" role=\"form\">\n    <div class=\"form-group\">\n      <label for=\"basic\" class=\"col-lg-2 control-label\">\"Basic\" (liveSearch enabled)</label>\n\n      <div class=\"col-lg-10\">\n        <select id=\"basic\" class=\"selectpicker show-tick form-control\" data-live-search=\"true\">\n          <option>cow</option>\n          <option data-subtext=\"option subtext\">bull</option>\n          <option class=\"get-class\" disabled>ox</option>\n          <optgroup label=\"test\" data-subtext=\"optgroup subtext\">\n            <option>ASD</option>\n            <option selected>Bla</option>\n            <option>Ble</option>\n          </optgroup>\n        </select>\n      </div>\n    </div>\n  </form>\n\n  <hr>\n  <form class=\"form-horizontal\" role=\"form\">\n    <div class=\"form-group\">\n      <label for=\"basic2\" class=\"col-lg-2 control-label\">\"Basic\" (multiple, maxOptions=1)</label>\n\n      <div class=\"col-lg-10\">\n        <select id=\"basic2\" class=\"show-tick form-control\" multiple>\n          <option>cow</option>\n          <option>bull</option>\n          <option class=\"get-class\" disabled>ox</option>\n          <optgroup label=\"test\" data-subtext=\"another test\">\n            <option>ASD</option>\n            <option selected>Bla</option>\n            <option>Ble</option>\n          </optgroup>\n        </select>\n      </div>\n    </div>\n  </form>\n\n  <hr>\n  <form class=\"form-horizontal\" role=\"form\">\n    <div class=\"form-group\">\n      <label for=\"maxOption2\" class=\"col-lg-2 control-label\">multiple, show-menu-arrow, maxOptions=2</label>\n\n      <div class=\"col-lg-10\">\n        <select id=\"maxOption2\" class=\"selectpicker show-menu-arrow form-control\" multiple data-max-options=\"2\">\n          <option>chicken</option>\n          <option>turkey</option>\n          <option disabled>duck</option>\n          <option>goose</option>\n        </select>\n      </div>\n    </div>\n  </form>\n\n  <hr>\n  <form class=\"form-inline\">\n    <div class=\"form-group\">\n      <label class=\"col-md-1 control-label\" for=\"lunch\">Lunch:</label>\n    </div>\n    <div class=\"form-group\">\n      <select id=\"lunch\" class=\"selectpicker\" data-live-search=\"true\" title=\"Please select a lunch ...\">\n        <option>Hot Dog, Fries and a Soda</option>\n        <option>Burger, Shake and a Smile</option>\n        <option>Sugar, Spice and all things nice</option>\n        <option>Baby Back Ribs</option>\n        <option>A really really long option made to illustrate an issue with the live search in an inline form</option>\n      </select>\n    </div>\n  </form>\n\n  <hr>\n  <form class=\"form-horizontal\" role=\"form\">\n    <div class=\"form-group form-group-lg\">\n      <label for=\"error\" class=\"col-lg-2 control-label\">error</label>\n\n      <div class=\"col-lg-10 error\">\n        <select id=\"error\" class=\"selectpicker show-tick form-control\">\n          <option>pen</option>\n          <option>pencil</option>\n          <option selected>brush</option>\n        </select>\n      </div>\n    </div>\n  </form>\n\n  <hr>\n  <form class=\"form-horizontal\" role=\"form\">\n    <div class=\"form-group has-error form-group-lg\">\n      <label class=\"control-label col-lg-2\" for=\"country\">error type 2</label>\n\n      <div class=\"col-lg-10\">\n        <select id=\"country\" name=\"country\" class=\"form-control selectpicker\">\n          <option>Argentina</option>\n          <option>United State</option>\n          <option>Mexico</option>\n        </select>\n\n        <p class=\"help-block\">No service available in the selected country</p>\n      </div>\n    </div>\n  </form>\n\n  <hr>\n  <nav class=\"navbar navbar-default\" role=\"navigation\">\n    <div class=\"container-fluid\">\n      <div class=\"navbar-header\">\n        <a class=\"navbar-brand\" href=\"#\">Navbar</a>\n      </div>\n\n      <form class=\"navbar-form navbar-left\" role=\"search\">\n        <div class=\"form-group\">\n          <select class=\"selectpicker\" multiple data-live-search=\"true\" data-live-search-placeholder=\"Search\" data-actions-box=\"true\">\n            <optgroup label=\"filter1\">\n              <option>option1</option>\n              <option>option2</option>\n              <option>option3</option>\n              <option>option4</option>\n            </optgroup>\n            <optgroup label=\"filter2\">\n              <option>option1</option>\n              <option>option2</option>\n              <option>option3</option>\n              <option>option4</option>\n            </optgroup>\n            <optgroup label=\"filter3\">\n              <option>option1</option>\n              <option>option2</option>\n              <option>option3</option>\n              <option>option4</option>\n            </optgroup>\n          </select>\n        </div>\n\n        <div class=\"input-group\">\n          <input type=\"text\" class=\"form-control\" placeholder=\"Search\" name=\"q\">\n\n          <div class=\"input-group-btn\">\n            <button class=\"btn btn-default\" type=\"submit\"><i class=\"glyphicon glyphicon-search\"></i></button>\n          </div>\n        </div>\n        <button type=\"submit\" class=\"btn btn-default\">Search</button>\n      </form>\n\n    </div>\n    <!-- .container-fluid -->\n  </nav>\n\n  <hr>\n  <select id=\"first-disabled\" class=\"selectpicker\" data-hide-disabled=\"true\" data-live-search=\"true\">\n    <optgroup disabled=\"disabled\" label=\"disabled\">\n      <option>Hidden</option>\n    </optgroup>\n    <optgroup label=\"Fruit\">\n      <option>Apple</option>\n      <option>Orange</option>\n    </optgroup>\n    <optgroup label=\"Vegetable\">\n      <option>Corn</option>\n      <option>Carrot</option>\n    </optgroup>\n  </select>\n\n  <hr>\n  <select id=\"first-disabled2\" class=\"selectpicker\" multiple data-hide-disabled=\"true\" data-size=\"5\">\n    <option>Apple</option>\n    <option>Banana</option>\n    <option>Orange</option>\n    <option>Pineapple</option>\n    <option>Apple2</option>\n    <option>Banana2</option>\n    <option>Orange2</option>\n    <option>Pineapple2</option>\n    <option>Apple2</option>\n    <option>Banana2</option>\n    <option>Orange2</option>\n    <option>Pineapple2</option>\n  </select>\n  <button id=\"special\" class=\"btn btn-default\">Hide selected by disabling</button>\n  <button id=\"special2\" class=\"btn btn-default\">Reset</button>\n  <p>Just select 1st element, click button and check list again</p>\n\n  <hr>\n  <div class=\"input-group\">\n    <span class=\"input-group-addon\">@</span>\n    <select class=\"form-control selectpicker\">\n      <option>One</option>\n      <option>Two</option>\n      <option>Three</option>\n    </select>\n  </div>\n\n  <hr>\n  <div class=\"input-group\">\n    <span class=\"input-group-addon\">@</span>\n    <select class=\"form-control selectpicker\" data-mobile=\"true\">\n      <option>One</option>\n      <option>Two</option>\n      <option>Three</option>\n    </select>\n  </div>\n  <p>With <code>data-mobile=\"true\"</code> option.</p>\n\n  <hr>\n  <select id=\"done\" class=\"selectpicker\" multiple data-done-button=\"true\">\n    <option>Apple</option>\n    <option>Banana</option>\n    <option>Orange</option>\n    <option>Pineapple</option>\n    <option>Apple2</option>\n    <option>Banana2</option>\n    <option>Orange2</option>\n    <option>Pineapple2</option>\n    <option>Apple2</option>\n    <option>Banana2</option>\n    <option>Orange2</option>\n    <option>Pineapple2</option>\n  </select>\n\n  <hr>\n  <select id=\"tokens\" class=\"selectpicker\" multiple data-live-search=\"true\">\n    <option data-tokens=\"first\">I actually am called \"first\"</option>\n    <option data-tokens=\"second\">And me \"second\"</option>\n    <option data-tokens=\"last\">I am \"last\"</option>\n  </select>\n\n  <hr>\n  <form class=\"form-inline\">\n    <div class=\"form-group\">\n      <label class=\"col-md-1 control-label\" for=\"lunchBegins\">Lunch (Begins search):</label>\n    </div>\n    <div class=\"form-group\">\n      <select id=\"lunchBegins\" class=\"selectpicker\" data-live-search=\"true\" data-live-search-style=\"begins\" title=\"Please select a lunch ...\">\n        <option>Hot Dog, Fries and a Soda</option>\n        <option>Burger, Shake and a Smile</option>\n        <option>Sugar, Spice and all things nice</option>\n        <option>Baby Back Ribs</option>\n        <option>A really really long option made to illustrate an issue with the live search in an inline form</option>\n      </select>\n    </div>\n  </form>\n</div>\n\n<script>\n  $(document).ready(function () {\n    var mySelect = $('#first-disabled2');\n\n    $('#special').on('click', function () {\n      mySelect.find('option:selected').prop('disabled', true);\n      mySelect.selectpicker('refresh');\n    });\n\n    $('#special2').on('click', function () {\n      mySelect.find('option:disabled').prop('disabled', false);\n      mySelect.selectpicker('refresh');\n    });\n\n    $('#basic2').selectpicker({\n      liveSearch: true,\n      maxOptions: 1\n    });\n  });\n</script>\n</body>\n</html>"
  },
  {
    "path": "app_backend/static/plugin/bootstrap-select-1.12.2/docs/mkdocs.yml",
    "content": "site_name: bootstrap-select\nsite_description: Bootstrap-select is a jQuery plugin that utilizes Bootstrap's dropdown.js to style and bring additional functionality to standard select elements.\nrepo_url: https://github.com/silviomoreto/bootstrap-select\ntheme: bootstrap\ntheme_dir: custom_theme\nextra_css:\n- css/custom.css\n- dist/css/bootstrap-select.min.css\nextra_javascript:\n- dist/js/bootstrap-select.min.js\npages:\n- Bootstrap-select: index.md\n- Examples: examples.md\n- Options: options.md\n- Methods: methods.md\nextra:\n    version: 1.12.2\n"
  },
  {
    "path": "app_backend/static/plugin/bootstrap-select-1.12.2/js/.jshintrc",
    "content": "{\n  \"curly\": true,\n  \"eqeqeq\": true,\n  \"immed\": true,\n  \"latedef\": true,\n  \"newcap\": true,\n  \"noarg\": true,\n  \"sub\": true,\n  \"undef\": true,\n  \"unused\": true,\n  \"boss\": true,\n  \"eqnull\": true,\n  \"browser\": true,\n  \"jquery\": true\n}\n"
  },
  {
    "path": "app_backend/static/plugin/bootstrap-select-1.12.2/js/bootstrap-select.js",
    "content": "(function ($) {\n  'use strict';\n\n  //<editor-fold desc=\"Shims\">\n  if (!String.prototype.includes) {\n    (function () {\n      'use strict'; // needed to support `apply`/`call` with `undefined`/`null`\n      var toString = {}.toString;\n      var defineProperty = (function () {\n        // IE 8 only supports `Object.defineProperty` on DOM elements\n        try {\n          var object = {};\n          var $defineProperty = Object.defineProperty;\n          var result = $defineProperty(object, object, object) && $defineProperty;\n        } catch (error) {\n        }\n        return result;\n      }());\n      var indexOf = ''.indexOf;\n      var includes = function (search) {\n        if (this == null) {\n          throw new TypeError();\n        }\n        var string = String(this);\n        if (search && toString.call(search) == '[object RegExp]') {\n          throw new TypeError();\n        }\n        var stringLength = string.length;\n        var searchString = String(search);\n        var searchLength = searchString.length;\n        var position = arguments.length > 1 ? arguments[1] : undefined;\n        // `ToInteger`\n        var pos = position ? Number(position) : 0;\n        if (pos != pos) { // better `isNaN`\n          pos = 0;\n        }\n        var start = Math.min(Math.max(pos, 0), stringLength);\n        // Avoid the `indexOf` call if no match is possible\n        if (searchLength + start > stringLength) {\n          return false;\n        }\n        return indexOf.call(string, searchString, pos) != -1;\n      };\n      if (defineProperty) {\n        defineProperty(String.prototype, 'includes', {\n          'value': includes,\n          'configurable': true,\n          'writable': true\n        });\n      } else {\n        String.prototype.includes = includes;\n      }\n    }());\n  }\n\n  if (!String.prototype.startsWith) {\n    (function () {\n      'use strict'; // needed to support `apply`/`call` with `undefined`/`null`\n      var defineProperty = (function () {\n        // IE 8 only supports `Object.defineProperty` on DOM elements\n        try {\n          var object = {};\n          var $defineProperty = Object.defineProperty;\n          var result = $defineProperty(object, object, object) && $defineProperty;\n        } catch (error) {\n        }\n        return result;\n      }());\n      var toString = {}.toString;\n      var startsWith = function (search) {\n        if (this == null) {\n          throw new TypeError();\n        }\n        var string = String(this);\n        if (search && toString.call(search) == '[object RegExp]') {\n          throw new TypeError();\n        }\n        var stringLength = string.length;\n        var searchString = String(search);\n        var searchLength = searchString.length;\n        var position = arguments.length > 1 ? arguments[1] : undefined;\n        // `ToInteger`\n        var pos = position ? Number(position) : 0;\n        if (pos != pos) { // better `isNaN`\n          pos = 0;\n        }\n        var start = Math.min(Math.max(pos, 0), stringLength);\n        // Avoid the `indexOf` call if no match is possible\n        if (searchLength + start > stringLength) {\n          return false;\n        }\n        var index = -1;\n        while (++index < searchLength) {\n          if (string.charCodeAt(start + index) != searchString.charCodeAt(index)) {\n            return false;\n          }\n        }\n        return true;\n      };\n      if (defineProperty) {\n        defineProperty(String.prototype, 'startsWith', {\n          'value': startsWith,\n          'configurable': true,\n          'writable': true\n        });\n      } else {\n        String.prototype.startsWith = startsWith;\n      }\n    }());\n  }\n\n  if (!Object.keys) {\n    Object.keys = function (\n      o, // object\n      k, // key\n      r  // result array\n      ){\n      // initialize object and result\n      r=[];\n      // iterate over object keys\n      for (k in o)\n          // fill result array with non-prototypical keys\n        r.hasOwnProperty.call(o, k) && r.push(k);\n      // return result\n      return r;\n    };\n  }\n\n  // set data-selected on select element if the value has been programmatically selected\n  // prior to initialization of bootstrap-select\n  // * consider removing or replacing an alternative method *\n  var valHooks = {\n    useDefault: false,\n    _set: $.valHooks.select.set\n  };\n\n  $.valHooks.select.set = function(elem, value) {\n    if (value && !valHooks.useDefault) $(elem).data('selected', true);\n\n    return valHooks._set.apply(this, arguments);\n  };\n\n  var changed_arguments = null;\n  $.fn.triggerNative = function (eventName) {\n    var el = this[0],\n        event;\n\n    if (el.dispatchEvent) { // for modern browsers & IE9+\n      if (typeof Event === 'function') {\n        // For modern browsers\n        event = new Event(eventName, {\n          bubbles: true\n        });\n      } else {\n        // For IE since it doesn't support Event constructor\n        event = document.createEvent('Event');\n        event.initEvent(eventName, true, false);\n      }\n\n      el.dispatchEvent(event);\n    } else if (el.fireEvent) { // for IE8\n      event = document.createEventObject();\n      event.eventType = eventName;\n      el.fireEvent('on' + eventName, event);\n    } else {\n      // fall back to jQuery.trigger\n      this.trigger(eventName);\n    }\n  };\n  //</editor-fold>\n\n  // Case insensitive contains search\n  $.expr.pseudos.icontains = function (obj, index, meta) {\n    var $obj = $(obj);\n    var haystack = ($obj.data('tokens') || $obj.text()).toString().toUpperCase();\n    return haystack.includes(meta[3].toUpperCase());\n  };\n\n  // Case insensitive begins search\n  $.expr.pseudos.ibegins = function (obj, index, meta) {\n    var $obj = $(obj);\n    var haystack = ($obj.data('tokens') || $obj.text()).toString().toUpperCase();\n    return haystack.startsWith(meta[3].toUpperCase());\n  };\n\n  // Case and accent insensitive contains search\n  $.expr.pseudos.aicontains = function (obj, index, meta) {\n    var $obj = $(obj);\n    var haystack = ($obj.data('tokens') || $obj.data('normalizedText') || $obj.text()).toString().toUpperCase();\n    return haystack.includes(meta[3].toUpperCase());\n  };\n\n  // Case and accent insensitive begins search\n  $.expr.pseudos.aibegins = function (obj, index, meta) {\n    var $obj = $(obj);\n    var haystack = ($obj.data('tokens') || $obj.data('normalizedText') || $obj.text()).toString().toUpperCase();\n    return haystack.startsWith(meta[3].toUpperCase());\n  };\n\n  /**\n   * Remove all diatrics from the given text.\n   * @access private\n   * @param {String} text\n   * @returns {String}\n   */\n  function normalizeToBase(text) {\n    var rExps = [\n      {re: /[\\xC0-\\xC6]/g, ch: \"A\"},\n      {re: /[\\xE0-\\xE6]/g, ch: \"a\"},\n      {re: /[\\xC8-\\xCB]/g, ch: \"E\"},\n      {re: /[\\xE8-\\xEB]/g, ch: \"e\"},\n      {re: /[\\xCC-\\xCF]/g, ch: \"I\"},\n      {re: /[\\xEC-\\xEF]/g, ch: \"i\"},\n      {re: /[\\xD2-\\xD6]/g, ch: \"O\"},\n      {re: /[\\xF2-\\xF6]/g, ch: \"o\"},\n      {re: /[\\xD9-\\xDC]/g, ch: \"U\"},\n      {re: /[\\xF9-\\xFC]/g, ch: \"u\"},\n      {re: /[\\xC7-\\xE7]/g, ch: \"c\"},\n      {re: /[\\xD1]/g, ch: \"N\"},\n      {re: /[\\xF1]/g, ch: \"n\"}\n    ];\n    $.each(rExps, function () {\n      text = text ? text.replace(this.re, this.ch) : '';\n    });\n    return text;\n  }\n\n\n  // List of HTML entities for escaping.\n  var escapeMap = {\n    '&': '&amp;',\n    '<': '&lt;',\n    '>': '&gt;',\n    '\"': '&quot;',\n    \"'\": '&#x27;',\n    '`': '&#x60;'\n  };\n  \n  var unescapeMap = {\n    '&amp;': '&',\n    '&lt;': '<',\n    '&gt;': '>',\n    '&quot;': '\"',\n    '&#x27;': \"'\",\n    '&#x60;': '`'\n  };\n\n  // Functions for escaping and unescaping strings to/from HTML interpolation.\n  var createEscaper = function(map) {\n    var escaper = function(match) {\n      return map[match];\n    };\n    // Regexes for identifying a key that needs to be escaped.\n    var source = '(?:' + Object.keys(map).join('|') + ')';\n    var testRegexp = RegExp(source);\n    var replaceRegexp = RegExp(source, 'g');\n    return function(string) {\n      string = string == null ? '' : '' + string;\n      return testRegexp.test(string) ? string.replace(replaceRegexp, escaper) : string;\n    };\n  };\n\n  var htmlEscape = createEscaper(escapeMap);\n  var htmlUnescape = createEscaper(unescapeMap);\n\n  var Selectpicker = function (element, options) {\n    // bootstrap-select has been initialized - revert valHooks.select.set back to its original function\n    if (!valHooks.useDefault) {\n      $.valHooks.select.set = valHooks._set;\n      valHooks.useDefault = true;\n    }\n\n    this.$element = $(element);\n    this.$newElement = null;\n    this.$button = null;\n    this.$menu = null;\n    this.$lis = null;\n    this.options = options;\n\n    // If we have no title yet, try to pull it from the html title attribute (jQuery doesnt' pick it up as it's not a\n    // data-attribute)\n    if (this.options.title === null) {\n      this.options.title = this.$element.attr('title');\n    }\n\n    // Format window padding\n    var winPad = this.options.windowPadding;\n    if (typeof winPad === 'number') {\n      this.options.windowPadding = [winPad, winPad, winPad, winPad];\n    }\n\n    //Expose public methods\n    this.val = Selectpicker.prototype.val;\n    this.render = Selectpicker.prototype.render;\n    this.refresh = Selectpicker.prototype.refresh;\n    this.setStyle = Selectpicker.prototype.setStyle;\n    this.selectAll = Selectpicker.prototype.selectAll;\n    this.deselectAll = Selectpicker.prototype.deselectAll;\n    this.destroy = Selectpicker.prototype.destroy;\n    this.remove = Selectpicker.prototype.remove;\n    this.show = Selectpicker.prototype.show;\n    this.hide = Selectpicker.prototype.hide;\n\n    this.init();\n  };\n\n  Selectpicker.VERSION = '1.12.2';\n\n  // part of this is duplicated in i18n/defaults-en_US.js. Make sure to update both.\n  Selectpicker.DEFAULTS = {\n    noneSelectedText: 'Nothing selected',\n    noneResultsText: 'No results matched {0}',\n    countSelectedText: function (numSelected, numTotal) {\n      return (numSelected == 1) ? \"{0} item selected\" : \"{0} items selected\";\n    },\n    maxOptionsText: function (numAll, numGroup) {\n      return [\n        (numAll == 1) ? 'Limit reached ({n} item max)' : 'Limit reached ({n} items max)',\n        (numGroup == 1) ? 'Group limit reached ({n} item max)' : 'Group limit reached ({n} items max)'\n      ];\n    },\n    selectAllText: 'Select All',\n    deselectAllText: 'Deselect All',\n    doneButton: false,\n    doneButtonText: 'Close',\n    multipleSeparator: ', ',\n    styleBase: 'btn',\n    style: 'btn-default',\n    size: 'auto',\n    title: null,\n    selectedTextFormat: 'values',\n    width: false,\n    container: false,\n    hideDisabled: false,\n    showSubtext: false,\n    showIcon: true,\n    showContent: true,\n    dropupAuto: true,\n    header: false,\n    liveSearch: false,\n    liveSearchPlaceholder: null,\n    liveSearchNormalize: false,\n    liveSearchStyle: 'contains',\n    actionsBox: false,\n    iconBase: 'glyphicon',\n    tickIcon: 'glyphicon-ok',\n    showTick: false,\n    template: {\n      caret: '<span class=\"caret\"></span>'\n    },\n    maxOptions: false,\n    mobile: false,\n    selectOnTab: false,\n    dropdownAlignRight: false,\n    windowPadding: 0\n  };\n\n  Selectpicker.prototype = {\n\n    constructor: Selectpicker,\n\n    init: function () {\n      var that = this,\n          id = this.$element.attr('id');\n\n      this.$element.addClass('bs-select-hidden');\n\n      // store originalIndex (key) and newIndex (value) in this.liObj for fast accessibility\n      // allows us to do this.$lis.eq(that.liObj[index]) instead of this.$lis.filter('[data-original-index=\"' + index + '\"]')\n      this.liObj = {};\n      this.multiple = this.$element.prop('multiple');\n      this.autofocus = this.$element.prop('autofocus');\n      this.$newElement = this.createView();\n      this.$element\n        .after(this.$newElement)\n        .appendTo(this.$newElement);\n      this.$button = this.$newElement.children('button');\n      this.$menu = this.$newElement.children('.dropdown-menu');\n      this.$menuInner = this.$menu.children('.inner');\n      this.$searchbox = this.$menu.find('input');\n\n      this.$element.removeClass('bs-select-hidden');\n\n      if (this.options.dropdownAlignRight === true) this.$menu.addClass('dropdown-menu-right');\n\n      if (typeof id !== 'undefined') {\n        this.$button.attr('data-id', id);\n        $('label[for=\"' + id + '\"]').click(function (e) {\n          e.preventDefault();\n          that.$button.focus();\n        });\n      }\n\n      this.checkDisabled();\n      this.clickListener();\n      if (this.options.liveSearch) this.liveSearchListener();\n      this.render();\n      this.setStyle();\n      this.setWidth();\n      if (this.options.container) this.selectPosition();\n      this.$menu.data('this', this);\n      this.$newElement.data('this', this);\n      if (this.options.mobile) this.mobile();\n\n      this.$newElement.on({\n        'hide.bs.dropdown': function (e) {\n          that.$menuInner.attr('aria-expanded', false);\n          that.$element.trigger('hide.bs.select', e);\n        },\n        'hidden.bs.dropdown': function (e) {\n          that.$element.trigger('hidden.bs.select', e);\n        },\n        'show.bs.dropdown': function (e) {\n          that.$menuInner.attr('aria-expanded', true);\n          that.$element.trigger('show.bs.select', e);\n        },\n        'shown.bs.dropdown': function (e) {\n          that.$element.trigger('shown.bs.select', e);\n        }\n      });\n\n      if (that.$element[0].hasAttribute('required')) {\n        this.$element.on('invalid', function () {\n          that.$button\n            .addClass('bs-invalid')\n            .focus();\n\n          that.$element.on({\n            'focus.bs.select': function () {\n              that.$button.focus();\n              that.$element.off('focus.bs.select');\n            },\n            'shown.bs.select': function () {\n              that.$element\n                .val(that.$element.val()) // set the value to hide the validation message in Chrome when menu is opened\n                .off('shown.bs.select');\n            },\n            'rendered.bs.select': function () {\n              // if select is no longer invalid, remove the bs-invalid class\n              if (this.validity.valid) that.$button.removeClass('bs-invalid');\n              that.$element.off('rendered.bs.select');\n            }\n          });\n        });\n      }\n\n      setTimeout(function () {\n        that.$element.trigger('loaded.bs.select');\n      });\n    },\n\n    createDropdown: function () {\n      // Options\n      // If we are multiple or showTick option is set, then add the show-tick class\n      var showTick = (this.multiple || this.options.showTick) ? ' show-tick' : '',\n          inputGroup = this.$element.parent().hasClass('input-group') ? ' input-group-btn' : '',\n          autofocus = this.autofocus ? ' autofocus' : '';\n      // Elements\n      var header = this.options.header ? '<div class=\"popover-title\"><button type=\"button\" class=\"close\" aria-hidden=\"true\">&times;</button>' + this.options.header + '</div>' : '';\n      var searchbox = this.options.liveSearch ?\n      '<div class=\"bs-searchbox\">' +\n      '<input type=\"text\" class=\"form-control\" autocomplete=\"off\"' +\n      (null === this.options.liveSearchPlaceholder ? '' : ' placeholder=\"' + htmlEscape(this.options.liveSearchPlaceholder) + '\"') + ' role=\"textbox\" aria-label=\"Search\">' +\n      '</div>'\n          : '';\n      var actionsbox = this.multiple && this.options.actionsBox ?\n      '<div class=\"bs-actionsbox\">' +\n      '<div class=\"btn-group btn-group-sm btn-block\">' +\n      '<button type=\"button\" class=\"actions-btn bs-select-all btn btn-default\">' +\n      this.options.selectAllText +\n      '</button>' +\n      '<button type=\"button\" class=\"actions-btn bs-deselect-all btn btn-default\">' +\n      this.options.deselectAllText +\n      '</button>' +\n      '</div>' +\n      '</div>'\n          : '';\n      var donebutton = this.multiple && this.options.doneButton ?\n      '<div class=\"bs-donebutton\">' +\n      '<div class=\"btn-group btn-block\">' +\n      '<button type=\"button\" class=\"btn btn-sm btn-default\">' +\n      this.options.doneButtonText +\n      '</button>' +\n      '</div>' +\n      '</div>'\n          : '';\n      var drop =\n          '<div class=\"btn-group bootstrap-select' + showTick + inputGroup + '\">' +\n          '<button type=\"button\" class=\"' + this.options.styleBase + ' dropdown-toggle\" data-toggle=\"dropdown\"' + autofocus + ' role=\"button\">' +\n          '<span class=\"filter-option pull-left\"></span>&nbsp;' +\n          '<span class=\"bs-caret\">' +\n          this.options.template.caret +\n          '</span>' +\n          '</button>' +\n          '<div class=\"dropdown-menu open\" role=\"combobox\">' +\n          header +\n          searchbox +\n          actionsbox +\n          '<ul class=\"dropdown-menu inner\" role=\"listbox\" aria-expanded=\"false\">' +\n          '</ul>' +\n          donebutton +\n          '</div>' +\n          '</div>';\n\n      return $(drop);\n    },\n\n    createView: function () {\n      var $drop = this.createDropdown(),\n          li = this.createLi();\n\n      $drop.find('ul')[0].innerHTML = li;\n      return $drop;\n    },\n\n    reloadLi: function () {\n      // rebuild\n      var li = this.createLi();\n      this.$menuInner[0].innerHTML = li;\n    },\n\n    createLi: function () {\n      var that = this,\n          _li = [],\n          optID = 0,\n          titleOption = document.createElement('option'),\n          liIndex = -1; // increment liIndex whenever a new <li> element is created to ensure liObj is correct\n\n      // Helper functions\n      /**\n       * @param content\n       * @param [index]\n       * @param [classes]\n       * @param [optgroup]\n       * @returns {string}\n       */\n      var generateLI = function (content, index, classes, optgroup) {\n        return '<li' +\n            ((typeof classes !== 'undefined' & '' !== classes) ? ' class=\"' + classes + '\"' : '') +\n            ((typeof index !== 'undefined' & null !== index) ? ' data-original-index=\"' + index + '\"' : '') +\n            ((typeof optgroup !== 'undefined' & null !== optgroup) ? 'data-optgroup=\"' + optgroup + '\"' : '') +\n            '>' + content + '</li>';\n      };\n\n      /**\n       * @param text\n       * @param [classes]\n       * @param [inline]\n       * @param [tokens]\n       * @returns {string}\n       */\n      var generateA = function (text, classes, inline, tokens) {\n        return '<a tabindex=\"0\"' +\n            (typeof classes !== 'undefined' ? ' class=\"' + classes + '\"' : '') +\n            (inline ? ' style=\"' + inline + '\"' : '') +\n            (that.options.liveSearchNormalize ? ' data-normalized-text=\"' + normalizeToBase(htmlEscape($(text).html())) + '\"' : '') +\n            (typeof tokens !== 'undefined' || tokens !== null ? ' data-tokens=\"' + tokens + '\"' : '') +\n            ' role=\"option\">' + text +\n            '<span class=\"' + that.options.iconBase + ' ' + that.options.tickIcon + ' check-mark\"></span>' +\n            '</a>';\n      };\n\n      if (this.options.title && !this.multiple) {\n        // this option doesn't create a new <li> element, but does add a new option, so liIndex is decreased\n        // since liObj is recalculated on every refresh, liIndex needs to be decreased even if the titleOption is already appended\n        liIndex--;\n\n        if (!this.$element.find('.bs-title-option').length) {\n          // Use native JS to prepend option (faster)\n          var element = this.$element[0];\n          titleOption.className = 'bs-title-option';\n          titleOption.innerHTML = this.options.title;\n          titleOption.value = '';\n          element.insertBefore(titleOption, element.firstChild);\n          // Check if selected or data-selected attribute is already set on an option. If not, select the titleOption option.\n          // the selected item may have been changed by user or programmatically before the bootstrap select plugin runs,\n          // if so, the select will have the data-selected attribute\n          var $opt = $(element.options[element.selectedIndex]);\n          if ($opt.attr('selected') === undefined && this.$element.data('selected') === undefined) {\n            titleOption.selected = true;\n          }\n        }\n      }\n\n      this.$element.find('option').each(function (index) {\n        var $this = $(this);\n\n        liIndex++;\n\n        if ($this.hasClass('bs-title-option')) return;\n\n        // Get the class and text for the option\n        var optionClass = this.className || '',\n            inline = this.style.cssText,\n            text = $this.data('content') ? $this.data('content') : $this.html(),\n            tokens = $this.data('tokens') ? $this.data('tokens') : null,\n            subtext = typeof $this.data('subtext') !== 'undefined' ? '<small class=\"text-muted\">' + $this.data('subtext') + '</small>' : '',\n            icon = typeof $this.data('icon') !== 'undefined' ? '<span class=\"' + that.options.iconBase + ' ' + $this.data('icon') + '\"></span> ' : '',\n            $parent = $this.parent(),\n            isOptgroup = $parent[0].tagName === 'OPTGROUP',\n            isOptgroupDisabled = isOptgroup && $parent[0].disabled,\n            isDisabled = this.disabled || isOptgroupDisabled;\n\n        if (icon !== '' && isDisabled) {\n          icon = '<span>' + icon + '</span>';\n        }\n\n        if (that.options.hideDisabled && (isDisabled && !isOptgroup || isOptgroupDisabled)) {\n          liIndex--;\n          return;\n        }\n\n        if (!$this.data('content')) {\n          // Prepend any icon and append any subtext to the main text.\n          text = icon + '<span class=\"text\">' + text + subtext + '</span>';\n        }\n\n        if (isOptgroup && $this.data('divider') !== true) {\n          if (that.options.hideDisabled && isDisabled) {\n            if ($parent.data('allOptionsDisabled') === undefined) {\n              var $options = $parent.children();\n              $parent.data('allOptionsDisabled', $options.filter(':disabled').length === $options.length);\n            }\n\n            if ($parent.data('allOptionsDisabled')) {\n              liIndex--;\n              return;\n            }\n          }\n\n          var optGroupClass = ' ' + $parent[0].className || '';\n\n          if ($this.index() === 0) { // Is it the first option of the optgroup?\n            optID += 1;\n\n            // Get the opt group label\n            var label = $parent[0].label,\n                labelSubtext = typeof $parent.data('subtext') !== 'undefined' ? '<small class=\"text-muted\">' + $parent.data('subtext') + '</small>' : '',\n                labelIcon = $parent.data('icon') ? '<span class=\"' + that.options.iconBase + ' ' + $parent.data('icon') + '\"></span> ' : '';\n\n            label = labelIcon + '<span class=\"text\">' + htmlEscape(label) + labelSubtext + '</span>';\n\n            if (index !== 0 && _li.length > 0) { // Is it NOT the first option of the select && are there elements in the dropdown?\n              liIndex++;\n              _li.push(generateLI('', null, 'divider', optID + 'div'));\n            }\n            liIndex++;\n            _li.push(generateLI(label, null, 'dropdown-header' + optGroupClass, optID));\n          }\n\n          if (that.options.hideDisabled && isDisabled) {\n            liIndex--;\n            return;\n          }\n\n          _li.push(generateLI(generateA(text, 'opt ' + optionClass + optGroupClass, inline, tokens), index, '', optID));\n        } else if ($this.data('divider') === true) {\n          _li.push(generateLI('', index, 'divider'));\n        } else if ($this.data('hidden') === true) {\n          _li.push(generateLI(generateA(text, optionClass, inline, tokens), index, 'hidden is-hidden'));\n        } else {\n          var showDivider = this.previousElementSibling && this.previousElementSibling.tagName === 'OPTGROUP';\n\n          // if previous element is not an optgroup and hideDisabled is true\n          if (!showDivider && that.options.hideDisabled) {\n            // get previous elements\n            var $prev = $(this).prevAll();\n\n            for (var i = 0; i < $prev.length; i++) {\n              // find the first element in the previous elements that is an optgroup\n              if ($prev[i].tagName === 'OPTGROUP') {\n                var optGroupDistance = 0;\n\n                // loop through the options in between the current option and the optgroup\n                // and check if they are hidden or disabled\n                for (var d = 0; d < i; d++) {\n                  var prevOption = $prev[d];\n                  if (prevOption.disabled || $(prevOption).data('hidden') === true) optGroupDistance++;\n                }\n\n                // if all of the options between the current option and the optgroup are hidden or disabled, show the divider\n                if (optGroupDistance === i) showDivider = true;\n\n                break;\n              }\n            }\n          }\n\n          if (showDivider) {\n            liIndex++;\n            _li.push(generateLI('', null, 'divider', optID + 'div'));\n          }\n          _li.push(generateLI(generateA(text, optionClass, inline, tokens), index));\n        }\n\n        that.liObj[index] = liIndex;\n      });\n\n      //If we are not multiple, we don't have a selected item, and we don't have a title, select the first element so something is set in the button\n      if (!this.multiple && this.$element.find('option:selected').length === 0 && !this.options.title) {\n        this.$element.find('option').eq(0).prop('selected', true).attr('selected', 'selected');\n      }\n\n      return _li.join('');\n    },\n\n    findLis: function () {\n      if (this.$lis == null) this.$lis = this.$menu.find('li');\n      return this.$lis;\n    },\n\n    /**\n     * @param [updateLi] defaults to true\n     */\n    render: function (updateLi) {\n      var that = this,\n          notDisabled;\n\n      //Update the LI to match the SELECT\n      if (updateLi !== false) {\n        this.$element.find('option').each(function (index) {\n          var $lis = that.findLis().eq(that.liObj[index]);\n\n          that.setDisabled(index, this.disabled || this.parentNode.tagName === 'OPTGROUP' && this.parentNode.disabled, $lis);\n          that.setSelected(index, this.selected, $lis);\n        });\n      }\n\n      this.togglePlaceholder();\n\n      this.tabIndex();\n\n      var selectedItems = this.$element.find('option').map(function () {\n        if (this.selected) {\n          if (that.options.hideDisabled && (this.disabled || this.parentNode.tagName === 'OPTGROUP' && this.parentNode.disabled)) return;\n\n          var $this = $(this),\n              icon = $this.data('icon') && that.options.showIcon ? '<i class=\"' + that.options.iconBase + ' ' + $this.data('icon') + '\"></i> ' : '',\n              subtext;\n\n          if (that.options.showSubtext && $this.data('subtext') && !that.multiple) {\n            subtext = ' <small class=\"text-muted\">' + $this.data('subtext') + '</small>';\n          } else {\n            subtext = '';\n          }\n          if (typeof $this.attr('title') !== 'undefined') {\n            return $this.attr('title');\n          } else if ($this.data('content') && that.options.showContent) {\n            return $this.data('content').toString();\n          } else {\n            return icon + $this.html() + subtext;\n          }\n        }\n      }).toArray();\n\n      //Fixes issue in IE10 occurring when no default option is selected and at least one option is disabled\n      //Convert all the values into a comma delimited string\n      var title = !this.multiple ? selectedItems[0] : selectedItems.join(this.options.multipleSeparator);\n\n      //If this is multi select, and the selectText type is count, the show 1 of 2 selected etc..\n      if (this.multiple && this.options.selectedTextFormat.indexOf('count') > -1) {\n        var max = this.options.selectedTextFormat.split('>');\n        if ((max.length > 1 && selectedItems.length > max[1]) || (max.length == 1 && selectedItems.length >= 2)) {\n          notDisabled = this.options.hideDisabled ? ', [disabled]' : '';\n          var totalCount = this.$element.find('option').not('[data-divider=\"true\"], [data-hidden=\"true\"]' + notDisabled).length,\n              tr8nText = (typeof this.options.countSelectedText === 'function') ? this.options.countSelectedText(selectedItems.length, totalCount) : this.options.countSelectedText;\n          title = tr8nText.replace('{0}', selectedItems.length.toString()).replace('{1}', totalCount.toString());\n        }\n      }\n\n      if (this.options.title == undefined) {\n        this.options.title = this.$element.attr('title');\n      }\n\n      if (this.options.selectedTextFormat == 'static') {\n        title = this.options.title;\n      }\n\n      //If we dont have a title, then use the default, or if nothing is set at all, use the not selected text\n      if (!title) {\n        title = typeof this.options.title !== 'undefined' ? this.options.title : this.options.noneSelectedText;\n      }\n\n      //strip all HTML tags and trim the result, then unescape any escaped tags\n      this.$button.attr('title', htmlUnescape($.trim(title.replace(/<[^>]*>?/g, ''))));\n      this.$button.children('.filter-option').html(title);\n\n      this.$element.trigger('rendered.bs.select');\n    },\n\n    /**\n     * @param [style]\n     * @param [status]\n     */\n    setStyle: function (style, status) {\n      if (this.$element.attr('class')) {\n        this.$newElement.addClass(this.$element.attr('class').replace(/selectpicker|mobile-device|bs-select-hidden|validate\\[.*\\]/gi, ''));\n      }\n\n      var buttonClass = style ? style : this.options.style;\n\n      if (status == 'add') {\n        this.$button.addClass(buttonClass);\n      } else if (status == 'remove') {\n        this.$button.removeClass(buttonClass);\n      } else {\n        this.$button.removeClass(this.options.style);\n        this.$button.addClass(buttonClass);\n      }\n    },\n\n    liHeight: function (refresh) {\n      if (!refresh && (this.options.size === false || this.sizeInfo)) return;\n\n      var newElement = document.createElement('div'),\n          menu = document.createElement('div'),\n          menuInner = document.createElement('ul'),\n          divider = document.createElement('li'),\n          li = document.createElement('li'),\n          a = document.createElement('a'),\n          text = document.createElement('span'),\n          header = this.options.header && this.$menu.find('.popover-title').length > 0 ? this.$menu.find('.popover-title')[0].cloneNode(true) : null,\n          search = this.options.liveSearch ? document.createElement('div') : null,\n          actions = this.options.actionsBox && this.multiple && this.$menu.find('.bs-actionsbox').length > 0 ? this.$menu.find('.bs-actionsbox')[0].cloneNode(true) : null,\n          doneButton = this.options.doneButton && this.multiple && this.$menu.find('.bs-donebutton').length > 0 ? this.$menu.find('.bs-donebutton')[0].cloneNode(true) : null;\n\n      text.className = 'text';\n      newElement.className = this.$menu[0].parentNode.className + ' open';\n      menu.className = 'dropdown-menu open';\n      menuInner.className = 'dropdown-menu inner';\n      divider.className = 'divider';\n\n      text.appendChild(document.createTextNode('Inner text'));\n      a.appendChild(text);\n      li.appendChild(a);\n      menuInner.appendChild(li);\n      menuInner.appendChild(divider);\n      if (header) menu.appendChild(header);\n      if (search) {\n        var input = document.createElement('input');\n        search.className = 'bs-searchbox';\n        input.className = 'form-control';\n        search.appendChild(input);\n        menu.appendChild(search);\n      }\n      if (actions) menu.appendChild(actions);\n      menu.appendChild(menuInner);\n      if (doneButton) menu.appendChild(doneButton);\n      newElement.appendChild(menu);\n\n      document.body.appendChild(newElement);\n\n      var liHeight = a.offsetHeight,\n          headerHeight = header ? header.offsetHeight : 0,\n          searchHeight = search ? search.offsetHeight : 0,\n          actionsHeight = actions ? actions.offsetHeight : 0,\n          doneButtonHeight = doneButton ? doneButton.offsetHeight : 0,\n          dividerHeight = $(divider).outerHeight(true),\n          // fall back to jQuery if getComputedStyle is not supported\n          menuStyle = typeof getComputedStyle === 'function' ? getComputedStyle(menu) : false,\n          $menu = menuStyle ? null : $(menu),\n          menuPadding = {\n            vert: parseInt(menuStyle ? menuStyle.paddingTop : $menu.css('paddingTop')) +\n                  parseInt(menuStyle ? menuStyle.paddingBottom : $menu.css('paddingBottom')) +\n                  parseInt(menuStyle ? menuStyle.borderTopWidth : $menu.css('borderTopWidth')) +\n                  parseInt(menuStyle ? menuStyle.borderBottomWidth : $menu.css('borderBottomWidth')),\n            horiz: parseInt(menuStyle ? menuStyle.paddingLeft : $menu.css('paddingLeft')) +\n                  parseInt(menuStyle ? menuStyle.paddingRight : $menu.css('paddingRight')) +\n                  parseInt(menuStyle ? menuStyle.borderLeftWidth : $menu.css('borderLeftWidth')) +\n                  parseInt(menuStyle ? menuStyle.borderRightWidth : $menu.css('borderRightWidth'))\n          },\n          menuExtras =  {\n            vert: menuPadding.vert +\n                  parseInt(menuStyle ? menuStyle.marginTop : $menu.css('marginTop')) +\n                  parseInt(menuStyle ? menuStyle.marginBottom : $menu.css('marginBottom')) + 2,\n            horiz: menuPadding.horiz +\n                  parseInt(menuStyle ? menuStyle.marginLeft : $menu.css('marginLeft')) +\n                  parseInt(menuStyle ? menuStyle.marginRight : $menu.css('marginRight')) + 2\n          }\n\n      document.body.removeChild(newElement);\n\n      this.sizeInfo = {\n        liHeight: liHeight,\n        headerHeight: headerHeight,\n        searchHeight: searchHeight,\n        actionsHeight: actionsHeight,\n        doneButtonHeight: doneButtonHeight,\n        dividerHeight: dividerHeight,\n        menuPadding: menuPadding,\n        menuExtras: menuExtras\n      };\n    },\n\n    setSize: function () {\n      this.findLis();\n      this.liHeight();\n\n      if (this.options.header) this.$menu.css('padding-top', 0);\n      if (this.options.size === false) return;\n\n      var that = this,\n          $menu = this.$menu,\n          $menuInner = this.$menuInner,\n          $window = $(window),\n          selectHeight = this.$newElement[0].offsetHeight,\n          selectWidth = this.$newElement[0].offsetWidth,\n          liHeight = this.sizeInfo['liHeight'],\n          headerHeight = this.sizeInfo['headerHeight'],\n          searchHeight = this.sizeInfo['searchHeight'],\n          actionsHeight = this.sizeInfo['actionsHeight'],\n          doneButtonHeight = this.sizeInfo['doneButtonHeight'],\n          divHeight = this.sizeInfo['dividerHeight'],\n          menuPadding = this.sizeInfo['menuPadding'],\n          menuExtras = this.sizeInfo['menuExtras'],\n          notDisabled = this.options.hideDisabled ? '.disabled' : '',\n          menuHeight,\n          menuWidth,\n          getHeight,\n          getWidth,\n          selectOffsetTop,\n          selectOffsetBot,\n          selectOffsetLeft,\n          selectOffsetRight,\n          getPos = function() {\n            var pos = that.$newElement.offset(),\n                $container = $(that.options.container),\n                containerPos;\n\n            if (that.options.container && !$container.is('body')) {\n              containerPos = $container.offset();\n              containerPos.top += parseInt($container.css('borderTopWidth'));\n              containerPos.left += parseInt($container.css('borderLeftWidth'));\n            } else {\n              containerPos = { top: 0, left: 0 };\n            }\n\n            var winPad = that.options.windowPadding;\n            selectOffsetTop = pos.top - containerPos.top - $window.scrollTop();\n            selectOffsetBot = $window.height() - selectOffsetTop - selectHeight - containerPos.top - winPad[2];\n            selectOffsetLeft = pos.left - containerPos.left - $window.scrollLeft();\n            selectOffsetRight = $window.width() - selectOffsetLeft - selectWidth - containerPos.left - winPad[1];\n            selectOffsetTop -= winPad[0];\n            selectOffsetLeft -= winPad[3];\n          };\n\n      getPos();\n\n      if (this.options.size === 'auto') {\n        var getSize = function () {\n          var minHeight,\n              hasClass = function (className, include) {\n                return function (element) {\n                    if (include) {\n                        return (element.classList ? element.classList.contains(className) : $(element).hasClass(className));\n                    } else {\n                        return !(element.classList ? element.classList.contains(className) : $(element).hasClass(className));\n                    }\n                };\n              },\n              lis = that.$menuInner[0].getElementsByTagName('li'),\n              lisVisible = Array.prototype.filter ? Array.prototype.filter.call(lis, hasClass('hidden', false)) : that.$lis.not('.hidden'),\n              optGroup = Array.prototype.filter ? Array.prototype.filter.call(lisVisible, hasClass('dropdown-header', true)) : lisVisible.filter('.dropdown-header');\n\n          getPos();\n          menuHeight = selectOffsetBot - menuExtras.vert;\n          menuWidth = selectOffsetRight - menuExtras.horiz;\n\n          if (that.options.container) {\n            if (!$menu.data('height')) $menu.data('height', $menu.height());\n            getHeight = $menu.data('height');\n\n            if (!$menu.data('width')) $menu.data('width', $menu.width());\n            getWidth = $menu.data('width');\n          } else {\n            getHeight = $menu.height();\n            getWidth = $menu.width();\n          }\n\n          if (that.options.dropupAuto) {\n            that.$newElement.toggleClass('dropup', selectOffsetTop > selectOffsetBot && (menuHeight - menuExtras.vert) < getHeight);\n          }\n\n          if (that.$newElement.hasClass('dropup')) {\n            menuHeight = selectOffsetTop - menuExtras.vert;\n          }\n\n          if (that.options.dropdownAlignRight === 'auto') {\n            $menu.toggleClass('dropdown-menu-right', selectOffsetLeft > selectOffsetRight && (menuWidth - menuExtras.horiz) < (getWidth - selectWidth));\n          }\n\n          if ((lisVisible.length + optGroup.length) > 3) {\n            minHeight = liHeight * 3 + menuExtras.vert - 2;\n          } else {\n            minHeight = 0;\n          }\n\n          $menu.css({\n            'max-height': menuHeight + 'px',\n            'overflow': 'hidden',\n            'min-height': minHeight + headerHeight + searchHeight + actionsHeight + doneButtonHeight + 'px'\n          });\n          $menuInner.css({\n            'max-height': menuHeight - headerHeight - searchHeight - actionsHeight - doneButtonHeight - menuPadding.vert + 'px',\n            'overflow-y': 'auto',\n            'min-height': Math.max(minHeight - menuPadding.vert, 0) + 'px'\n          });\n        };\n        getSize();\n        this.$searchbox.off('input.getSize propertychange.getSize').on('input.getSize propertychange.getSize', getSize);\n        $window.off('resize.getSize scroll.getSize').on('resize.getSize scroll.getSize', getSize);\n      } else if (this.options.size && this.options.size != 'auto' && this.$lis.not(notDisabled).length > this.options.size) {\n        var optIndex = this.$lis.not('.divider').not(notDisabled).children().slice(0, this.options.size).last().parent().index(),\n            divLength = this.$lis.slice(0, optIndex + 1).filter('.divider').length;\n        menuHeight = liHeight * this.options.size + divLength * divHeight + menuPadding.vert;\n\n        if (that.options.container) {\n          if (!$menu.data('height')) $menu.data('height', $menu.height());\n          getHeight = $menu.data('height');\n        } else {\n          getHeight = $menu.height();\n        }\n\n        if (that.options.dropupAuto) {\n          //noinspection JSUnusedAssignment\n          this.$newElement.toggleClass('dropup', selectOffsetTop > selectOffsetBot && (menuHeight - menuExtras.vert) < getHeight);\n        }\n        $menu.css({\n          'max-height': menuHeight + headerHeight + searchHeight + actionsHeight + doneButtonHeight + 'px',\n          'overflow': 'hidden',\n          'min-height': ''\n        });\n        $menuInner.css({\n          'max-height': menuHeight - menuPadding.vert + 'px',\n          'overflow-y': 'auto',\n          'min-height': ''\n        });\n      }\n    },\n\n    setWidth: function () {\n      if (this.options.width === 'auto') {\n        this.$menu.css('min-width', '0');\n\n        // Get correct width if element is hidden\n        var $selectClone = this.$menu.parent().clone().appendTo('body'),\n            $selectClone2 = this.options.container ? this.$newElement.clone().appendTo('body') : $selectClone,\n            ulWidth = $selectClone.children('.dropdown-menu').outerWidth(),\n            btnWidth = $selectClone2.css('width', 'auto').children('button').outerWidth();\n\n        $selectClone.remove();\n        $selectClone2.remove();\n\n        // Set width to whatever's larger, button title or longest option\n        this.$newElement.css('width', Math.max(ulWidth, btnWidth) + 'px');\n      } else if (this.options.width === 'fit') {\n        // Remove inline min-width so width can be changed from 'auto'\n        this.$menu.css('min-width', '');\n        this.$newElement.css('width', '').addClass('fit-width');\n      } else if (this.options.width) {\n        // Remove inline min-width so width can be changed from 'auto'\n        this.$menu.css('min-width', '');\n        this.$newElement.css('width', this.options.width);\n      } else {\n        // Remove inline min-width/width so width can be changed\n        this.$menu.css('min-width', '');\n        this.$newElement.css('width', '');\n      }\n      // Remove fit-width class if width is changed programmatically\n      if (this.$newElement.hasClass('fit-width') && this.options.width !== 'fit') {\n        this.$newElement.removeClass('fit-width');\n      }\n    },\n\n    selectPosition: function () {\n      this.$bsContainer = $('<div class=\"bs-container\" />');\n\n      var that = this,\n          $container = $(this.options.container),\n          pos,\n          containerPos,\n          actualHeight,\n          getPlacement = function ($element) {\n            that.$bsContainer.addClass($element.attr('class').replace(/form-control|fit-width/gi, '')).toggleClass('dropup', $element.hasClass('dropup'));\n            pos = $element.offset();\n\n            if (!$container.is('body')) {\n              containerPos = $container.offset();\n              containerPos.top += parseInt($container.css('borderTopWidth')) - $container.scrollTop();\n              containerPos.left += parseInt($container.css('borderLeftWidth')) - $container.scrollLeft();\n            } else {\n              containerPos = { top: 0, left: 0 };\n            }\n\n            actualHeight = $element.hasClass('dropup') ? 0 : $element[0].offsetHeight;\n\n            that.$bsContainer.css({\n              'top': pos.top - containerPos.top + actualHeight,\n              'left': pos.left - containerPos.left,\n              'width': $element[0].offsetWidth\n            });\n          };\n\n      this.$button.on('click', function () {\n        var $this = $(this);\n\n        if (that.isDisabled()) {\n          return;\n        }\n\n        getPlacement(that.$newElement);\n\n        that.$bsContainer\n          .appendTo(that.options.container)\n          .toggleClass('open', !$this.hasClass('open'))\n          .append(that.$menu);\n      });\n\n      $(window).on('resize scroll', function () {\n        getPlacement(that.$newElement);\n      });\n\n      this.$element.on('hide.bs.select', function () {\n        that.$menu.data('height', that.$menu.height());\n        that.$bsContainer.detach();\n      });\n    },\n\n    /**\n     * @param {number} index - the index of the option that is being changed\n     * @param {boolean} selected - true if the option is being selected, false if being deselected\n     * @param {JQuery} $lis - the 'li' element that is being modified\n     */\n    setSelected: function (index, selected, $lis) {\n      if (!$lis) {\n        this.togglePlaceholder(); // check if setSelected is being called by changing the value of the select\n        $lis = this.findLis().eq(this.liObj[index]);\n      }\n\n      $lis.toggleClass('selected', selected).find('a').attr('aria-selected', selected);\n    },\n\n    /**\n     * @param {number} index - the index of the option that is being disabled\n     * @param {boolean} disabled - true if the option is being disabled, false if being enabled\n     * @param {JQuery} $lis - the 'li' element that is being modified\n     */\n    setDisabled: function (index, disabled, $lis) {\n      if (!$lis) {\n        $lis = this.findLis().eq(this.liObj[index]);\n      }\n\n      if (disabled) {\n        $lis.addClass('disabled').children('a').attr('href', '#').attr('tabindex', -1).attr('aria-disabled', true);\n      } else {\n        $lis.removeClass('disabled').children('a').removeAttr('href').attr('tabindex', 0).attr('aria-disabled', false);\n      }\n    },\n\n    isDisabled: function () {\n      return this.$element[0].disabled;\n    },\n\n    checkDisabled: function () {\n      var that = this;\n\n      if (this.isDisabled()) {\n        this.$newElement.addClass('disabled');\n        this.$button.addClass('disabled').attr('tabindex', -1).attr('aria-disabled', true);\n      } else {\n        if (this.$button.hasClass('disabled')) {\n          this.$newElement.removeClass('disabled');\n          this.$button.removeClass('disabled').attr('aria-disabled', false);\n        }\n\n        if (this.$button.attr('tabindex') == -1 && !this.$element.data('tabindex')) {\n          this.$button.removeAttr('tabindex');\n        }\n      }\n\n      this.$button.click(function () {\n        return !that.isDisabled();\n      });\n    },\n\n    togglePlaceholder: function () {\n      var value = this.$element.val();\n      this.$button.toggleClass('bs-placeholder', value === null || value === '' || (value.constructor === Array && value.length === 0));\n    },\n\n    tabIndex: function () {\n      if (this.$element.data('tabindex') !== this.$element.attr('tabindex') && \n        (this.$element.attr('tabindex') !== -98 && this.$element.attr('tabindex') !== '-98')) {\n        this.$element.data('tabindex', this.$element.attr('tabindex'));\n        this.$button.attr('tabindex', this.$element.data('tabindex'));\n      }\n\n      this.$element.attr('tabindex', -98);\n    },\n\n    clickListener: function () {\n      var that = this,\n          $document = $(document);\n\n      $document.data('spaceSelect', false);\n\n      this.$button.on('keyup', function (e) {\n        if (/(32)/.test(e.keyCode.toString(10)) && $document.data('spaceSelect')) {\n            e.preventDefault();\n            $document.data('spaceSelect', false);\n        }\n      });\n\n      this.$button.on('click', function () {\n        that.setSize();\n      });\n\n      this.$element.on('shown.bs.select', function () {\n        if (!that.options.liveSearch && !that.multiple) {\n          that.$menuInner.find('.selected a').focus();\n        } else if (!that.multiple) {\n          var selectedIndex = that.liObj[that.$element[0].selectedIndex];\n\n          if (typeof selectedIndex !== 'number' || that.options.size === false) return;\n\n          // scroll to selected option\n          var offset = that.$lis.eq(selectedIndex)[0].offsetTop - that.$menuInner[0].offsetTop;\n          offset = offset - that.$menuInner[0].offsetHeight/2 + that.sizeInfo.liHeight/2;\n          that.$menuInner[0].scrollTop = offset;\n        }\n      });\n\n      this.$menuInner.on('click', 'li a', function (e) {\n        var $this = $(this),\n            clickedIndex = $this.parent().data('originalIndex'),\n            prevValue = that.$element.val(),\n            prevIndex = that.$element.prop('selectedIndex'),\n            triggerChange = true;\n\n        // Don't close on multi choice menu\n        if (that.multiple && that.options.maxOptions !== 1) {\n          e.stopPropagation();\n        }\n\n        e.preventDefault();\n\n        //Don't run if we have been disabled\n        if (!that.isDisabled() && !$this.parent().hasClass('disabled')) {\n          var $options = that.$element.find('option'),\n              $option = $options.eq(clickedIndex),\n              state = $option.prop('selected'),\n              $optgroup = $option.parent('optgroup'),\n              maxOptions = that.options.maxOptions,\n              maxOptionsGrp = $optgroup.data('maxOptions') || false;\n\n          if (!that.multiple) { // Deselect all others if not multi select box\n            $options.prop('selected', false);\n            $option.prop('selected', true);\n            that.$menuInner.find('.selected').removeClass('selected').find('a').attr('aria-selected', false);\n            that.setSelected(clickedIndex, true);\n          } else { // Toggle the one we have chosen if we are multi select.\n            $option.prop('selected', !state);\n            that.setSelected(clickedIndex, !state);\n            $this.blur();\n\n            if (maxOptions !== false || maxOptionsGrp !== false) {\n              var maxReached = maxOptions < $options.filter(':selected').length,\n                  maxReachedGrp = maxOptionsGrp < $optgroup.find('option:selected').length;\n\n              if ((maxOptions && maxReached) || (maxOptionsGrp && maxReachedGrp)) {\n                if (maxOptions && maxOptions == 1) {\n                  $options.prop('selected', false);\n                  $option.prop('selected', true);\n                  that.$menuInner.find('.selected').removeClass('selected');\n                  that.setSelected(clickedIndex, true);\n                } else if (maxOptionsGrp && maxOptionsGrp == 1) {\n                  $optgroup.find('option:selected').prop('selected', false);\n                  $option.prop('selected', true);\n                  var optgroupID = $this.parent().data('optgroup');\n                  that.$menuInner.find('[data-optgroup=\"' + optgroupID + '\"]').removeClass('selected');\n                  that.setSelected(clickedIndex, true);\n                } else {\n                  var maxOptionsText = typeof that.options.maxOptionsText === 'string' ? [that.options.maxOptionsText, that.options.maxOptionsText] : that.options.maxOptionsText,\n                      maxOptionsArr = typeof maxOptionsText === 'function' ? maxOptionsText(maxOptions, maxOptionsGrp) : maxOptionsText,\n                      maxTxt = maxOptionsArr[0].replace('{n}', maxOptions),\n                      maxTxtGrp = maxOptionsArr[1].replace('{n}', maxOptionsGrp),\n                      $notify = $('<div class=\"notify\"></div>');\n                  // If {var} is set in array, replace it\n                  /** @deprecated */\n                  if (maxOptionsArr[2]) {\n                    maxTxt = maxTxt.replace('{var}', maxOptionsArr[2][maxOptions > 1 ? 0 : 1]);\n                    maxTxtGrp = maxTxtGrp.replace('{var}', maxOptionsArr[2][maxOptionsGrp > 1 ? 0 : 1]);\n                  }\n\n                  $option.prop('selected', false);\n\n                  that.$menu.append($notify);\n\n                  if (maxOptions && maxReached) {\n                    $notify.append($('<div>' + maxTxt + '</div>'));\n                    triggerChange = false;\n                    that.$element.trigger('maxReached.bs.select');\n                  }\n\n                  if (maxOptionsGrp && maxReachedGrp) {\n                    $notify.append($('<div>' + maxTxtGrp + '</div>'));\n                    triggerChange = false;\n                    that.$element.trigger('maxReachedGrp.bs.select');\n                  }\n\n                  setTimeout(function () {\n                    that.setSelected(clickedIndex, false);\n                  }, 10);\n\n                  $notify.delay(750).fadeOut(300, function () {\n                    $(this).remove();\n                  });\n                }\n              }\n            }\n          }\n\n          if (!that.multiple || (that.multiple && that.options.maxOptions === 1)) {\n            that.$button.focus();\n          } else if (that.options.liveSearch) {\n            that.$searchbox.focus();\n          }\n\n          // Trigger select 'change'\n          if (triggerChange) {\n            if ((prevValue != that.$element.val() && that.multiple) || (prevIndex != that.$element.prop('selectedIndex') && !that.multiple)) {\n              // $option.prop('selected') is current option state (selected/unselected). state is previous option state.\n              changed_arguments = [clickedIndex, $option.prop('selected'), state];\n              that.$element\n                .triggerNative('change');\n            }\n          }\n        }\n      });\n\n      this.$menu.on('click', 'li.disabled a, .popover-title, .popover-title :not(.close)', function (e) {\n        if (e.currentTarget == this) {\n          e.preventDefault();\n          e.stopPropagation();\n          if (that.options.liveSearch && !$(e.target).hasClass('close')) {\n            that.$searchbox.focus();\n          } else {\n            that.$button.focus();\n          }\n        }\n      });\n\n      this.$menuInner.on('click', '.divider, .dropdown-header', function (e) {\n        e.preventDefault();\n        e.stopPropagation();\n        if (that.options.liveSearch) {\n          that.$searchbox.focus();\n        } else {\n          that.$button.focus();\n        }\n      });\n\n      this.$menu.on('click', '.popover-title .close', function () {\n        that.$button.click();\n      });\n\n      this.$searchbox.on('click', function (e) {\n        e.stopPropagation();\n      });\n\n      this.$menu.on('click', '.actions-btn', function (e) {\n        if (that.options.liveSearch) {\n          that.$searchbox.focus();\n        } else {\n          that.$button.focus();\n        }\n\n        e.preventDefault();\n        e.stopPropagation();\n\n        if ($(this).hasClass('bs-select-all')) {\n          that.selectAll();\n        } else {\n          that.deselectAll();\n        }\n      });\n\n      this.$element.change(function () {\n        that.render(false);\n        that.$element.trigger('changed.bs.select', changed_arguments);\n        changed_arguments = null;\n      });\n    },\n\n    liveSearchListener: function () {\n      var that = this,\n          $no_results = $('<li class=\"no-results\"></li>');\n\n      this.$button.on('click.dropdown.data-api', function () {\n        that.$menuInner.find('.active').removeClass('active');\n        if (!!that.$searchbox.val()) {\n          that.$searchbox.val('');\n          that.$lis.not('.is-hidden').removeClass('hidden');\n          if (!!$no_results.parent().length) $no_results.remove();\n        }\n        if (!that.multiple) that.$menuInner.find('.selected').addClass('active');\n        setTimeout(function () {\n          that.$searchbox.focus();\n        }, 10);\n      });\n\n      this.$searchbox.on('click.dropdown.data-api focus.dropdown.data-api touchend.dropdown.data-api', function (e) {\n        e.stopPropagation();\n      });\n\n      this.$searchbox.on('input propertychange', function () {\n        that.$lis.not('.is-hidden').removeClass('hidden');\n        that.$lis.filter('.active').removeClass('active');\n        $no_results.remove();\n\n        if (that.$searchbox.val()) {\n          var $searchBase = that.$lis.not('.is-hidden, .divider, .dropdown-header'),\n              $hideItems;\n          if (that.options.liveSearchNormalize) {\n            $hideItems = $searchBase.find('a').not(':a' + that._searchStyle() + '(\"' + normalizeToBase(that.$searchbox.val()) + '\")');\n          } else {\n            $hideItems = $searchBase.find('a').not(':' + that._searchStyle() + '(\"' + that.$searchbox.val() + '\")');\n          }\n\n          if ($hideItems.length === $searchBase.length) {\n            $no_results.html(that.options.noneResultsText.replace('{0}', '\"' + htmlEscape(that.$searchbox.val()) + '\"'));\n            that.$menuInner.append($no_results);\n            that.$lis.addClass('hidden');\n          } else {\n            $hideItems.parent().addClass('hidden');\n\n            var $lisVisible = that.$lis.not('.hidden'),\n                $foundDiv;\n\n            // hide divider if first or last visible, or if followed by another divider\n            $lisVisible.each(function (index) {\n              var $this = $(this);\n\n              if ($this.hasClass('divider')) {\n                if ($foundDiv === undefined) {\n                  $this.addClass('hidden');\n                } else {\n                  if ($foundDiv) $foundDiv.addClass('hidden');\n                  $foundDiv = $this;\n                }\n              } else if ($this.hasClass('dropdown-header') && $lisVisible.eq(index + 1).data('optgroup') !== $this.data('optgroup')) {\n                $this.addClass('hidden');\n              } else {\n                $foundDiv = null;\n              }\n            });\n            if ($foundDiv) $foundDiv.addClass('hidden');\n\n            $searchBase.not('.hidden').first().addClass('active');\n          }\n        }\n      });\n    },\n\n    _searchStyle: function () {\n      var styles = {\n        begins: 'ibegins',\n        startsWith: 'ibegins'\n      };\n\n      return styles[this.options.liveSearchStyle] || 'icontains';\n    },\n\n    val: function (value) {\n      if (typeof value !== 'undefined') {\n        this.$element.val(value);\n        this.render();\n\n        return this.$element;\n      } else {\n        return this.$element.val();\n      }\n    },\n\n    changeAll: function (status) {\n      if (!this.multiple) return;\n      if (typeof status === 'undefined') status = true;\n\n      this.findLis();\n\n      var $options = this.$element.find('option'),\n          $lisVisible = this.$lis.not('.divider, .dropdown-header, .disabled, .hidden'),\n          lisVisLen = $lisVisible.length,\n          selectedOptions = [];\n          \n      if (status) {\n        if ($lisVisible.filter('.selected').length === $lisVisible.length) return;\n      } else {\n        if ($lisVisible.filter('.selected').length === 0) return;\n      }\n          \n      $lisVisible.toggleClass('selected', status);\n\n      for (var i = 0; i < lisVisLen; i++) {\n        var origIndex = $lisVisible[i].getAttribute('data-original-index');\n        selectedOptions[selectedOptions.length] = $options.eq(origIndex)[0];\n      }\n\n      $(selectedOptions).prop('selected', status);\n\n      this.render(false);\n\n      this.togglePlaceholder();\n\n      this.$element\n        .triggerNative('change');\n    },\n\n    selectAll: function () {\n      return this.changeAll(true);\n    },\n\n    deselectAll: function () {\n      return this.changeAll(false);\n    },\n\n    toggle: function (e) {\n      e = e || window.event;\n\n      if (e) e.stopPropagation();\n\n      this.$button.trigger('click');\n    },\n\n    keydown: function (e) {\n      var $this = $(this),\n          $parent = $this.is('input') ? $this.parent().parent() : $this.parent(),\n          $items,\n          that = $parent.data('this'),\n          index,\n          next,\n          first,\n          last,\n          prev,\n          nextPrev,\n          prevIndex,\n          isActive,\n          selector = ':not(.disabled, .hidden, .dropdown-header, .divider)',\n          keyCodeMap = {\n            32: ' ',\n            48: '0',\n            49: '1',\n            50: '2',\n            51: '3',\n            52: '4',\n            53: '5',\n            54: '6',\n            55: '7',\n            56: '8',\n            57: '9',\n            59: ';',\n            65: 'a',\n            66: 'b',\n            67: 'c',\n            68: 'd',\n            69: 'e',\n            70: 'f',\n            71: 'g',\n            72: 'h',\n            73: 'i',\n            74: 'j',\n            75: 'k',\n            76: 'l',\n            77: 'm',\n            78: 'n',\n            79: 'o',\n            80: 'p',\n            81: 'q',\n            82: 'r',\n            83: 's',\n            84: 't',\n            85: 'u',\n            86: 'v',\n            87: 'w',\n            88: 'x',\n            89: 'y',\n            90: 'z',\n            96: '0',\n            97: '1',\n            98: '2',\n            99: '3',\n            100: '4',\n            101: '5',\n            102: '6',\n            103: '7',\n            104: '8',\n            105: '9'\n          };\n\n      if (that.options.liveSearch) $parent = $this.parent().parent();\n\n      if (that.options.container) $parent = that.$menu;\n\n      $items = $('[role=\"listbox\"] li', $parent);\n\n      isActive = that.$newElement.hasClass('open');\n\n      if (!isActive && (e.keyCode >= 48 && e.keyCode <= 57 || e.keyCode >= 96 && e.keyCode <= 105 || e.keyCode >= 65 && e.keyCode <= 90)) {\n        if (!that.options.container) {\n          that.setSize();\n          that.$menu.parent().addClass('open');\n          isActive = true;\n        } else {\n          that.$button.trigger('click');\n        }\n        that.$searchbox.focus();\n        return;\n      }\n\n      if (that.options.liveSearch) {\n        if (/(^9$|27)/.test(e.keyCode.toString(10)) && isActive) {\n          e.preventDefault();\n          e.stopPropagation();\n          that.$menuInner.click();\n          that.$button.focus();\n        }\n        // $items contains li elements when liveSearch is enabled\n        $items = $('[role=\"listbox\"] li' + selector, $parent);\n        if (!$this.val() && !/(38|40)/.test(e.keyCode.toString(10))) {\n          if ($items.filter('.active').length === 0) {\n            $items = that.$menuInner.find('li');\n            if (that.options.liveSearchNormalize) {\n              $items = $items.filter(':a' + that._searchStyle() + '(' + normalizeToBase(keyCodeMap[e.keyCode]) + ')');\n            } else {\n              $items = $items.filter(':' + that._searchStyle() + '(' + keyCodeMap[e.keyCode] + ')');\n            }\n          }\n        }\n      }\n\n      if (!$items.length) return;\n\n      if (/(38|40)/.test(e.keyCode.toString(10))) {\n        index = $items.index($items.find('a').filter(':focus').parent());\n        first = $items.filter(selector).first().index();\n        last = $items.filter(selector).last().index();\n        next = $items.eq(index).nextAll(selector).eq(0).index();\n        prev = $items.eq(index).prevAll(selector).eq(0).index();\n        nextPrev = $items.eq(next).prevAll(selector).eq(0).index();\n\n        if (that.options.liveSearch) {\n          $items.each(function (i) {\n            if (!$(this).hasClass('disabled')) {\n              $(this).data('index', i);\n            }\n          });\n          index = $items.index($items.filter('.active'));\n          first = $items.first().data('index');\n          last = $items.last().data('index');\n          next = $items.eq(index).nextAll().eq(0).data('index');\n          prev = $items.eq(index).prevAll().eq(0).data('index');\n          nextPrev = $items.eq(next).prevAll().eq(0).data('index');\n        }\n\n        prevIndex = $this.data('prevIndex');\n\n        if (e.keyCode == 38) {\n          if (that.options.liveSearch) index--;\n          if (index != nextPrev && index > prev) index = prev;\n          if (index < first) index = first;\n          if (index == prevIndex) index = last;\n        } else if (e.keyCode == 40) {\n          if (that.options.liveSearch) index++;\n          if (index == -1) index = 0;\n          if (index != nextPrev && index < next) index = next;\n          if (index > last) index = last;\n          if (index == prevIndex) index = first;\n        }\n\n        $this.data('prevIndex', index);\n\n        if (!that.options.liveSearch) {\n          $items.eq(index).children('a').focus();\n        } else {\n          e.preventDefault();\n          if (!$this.hasClass('dropdown-toggle')) {\n            $items.removeClass('active').eq(index).addClass('active').children('a').focus();\n            $this.focus();\n          }\n        }\n\n      } else if (!$this.is('input')) {\n        var keyIndex = [],\n            count,\n            prevKey;\n\n        $items.each(function () {\n          if (!$(this).hasClass('disabled')) {\n            if ($.trim($(this).children('a').text().toLowerCase()).substring(0, 1) == keyCodeMap[e.keyCode]) {\n              keyIndex.push($(this).index());\n            }\n          }\n        });\n\n        count = $(document).data('keycount');\n        count++;\n        $(document).data('keycount', count);\n\n        prevKey = $.trim($(':focus').text().toLowerCase()).substring(0, 1);\n\n        if (prevKey != keyCodeMap[e.keyCode]) {\n          count = 1;\n          $(document).data('keycount', count);\n        } else if (count >= keyIndex.length) {\n          $(document).data('keycount', 0);\n          if (count > keyIndex.length) count = 1;\n        }\n\n        $items.eq(keyIndex[count - 1]).children('a').focus();\n      }\n\n      // Select focused option if \"Enter\", \"Spacebar\" or \"Tab\" (when selectOnTab is true) are pressed inside the menu.\n      if ((/(13|32)/.test(e.keyCode.toString(10)) || (/(^9$)/.test(e.keyCode.toString(10)) && that.options.selectOnTab)) && isActive) {\n        if (!/(32)/.test(e.keyCode.toString(10))) e.preventDefault();\n        if (!that.options.liveSearch) {\n          var elem = $(':focus');\n          elem.click();\n          // Bring back focus for multiselects\n          elem.focus();\n          // Prevent screen from scrolling if the user hit the spacebar\n          e.preventDefault();\n          // Fixes spacebar selection of dropdown items in FF & IE\n          $(document).data('spaceSelect', true);\n        } else if (!/(32)/.test(e.keyCode.toString(10))) {\n          that.$menuInner.find('.active a').click();\n          $this.focus();\n        }\n        $(document).data('keycount', 0);\n      }\n\n      if ((/(^9$|27)/.test(e.keyCode.toString(10)) && isActive && (that.multiple || that.options.liveSearch)) || (/(27)/.test(e.keyCode.toString(10)) && !isActive)) {\n        that.$menu.parent().removeClass('open');\n        if (that.options.container) that.$newElement.removeClass('open');\n        that.$button.focus();\n      }\n    },\n\n    mobile: function () {\n      this.$element.addClass('mobile-device');\n    },\n\n    refresh: function () {\n      this.$lis = null;\n      this.liObj = {};\n      this.reloadLi();\n      this.render();\n      this.checkDisabled();\n      this.liHeight(true);\n      this.setStyle();\n      this.setWidth();\n      if (this.$lis) this.$searchbox.trigger('propertychange');\n\n      this.$element.trigger('refreshed.bs.select');\n    },\n\n    hide: function () {\n      this.$newElement.hide();\n    },\n\n    show: function () {\n      this.$newElement.show();\n    },\n\n    remove: function () {\n      this.$newElement.remove();\n      this.$element.remove();\n    },\n\n    destroy: function () {\n      this.$newElement.before(this.$element).remove();\n\n      if (this.$bsContainer) {\n        this.$bsContainer.remove();\n      } else {\n        this.$menu.remove();\n      }\n\n      this.$element\n        .off('.bs.select')\n        .removeData('selectpicker')\n        .removeClass('bs-select-hidden selectpicker');\n    }\n  };\n\n  // SELECTPICKER PLUGIN DEFINITION\n  // ==============================\n  function Plugin(option) {\n    // get the args of the outer function..\n    var args = arguments;\n    // The arguments of the function are explicitly re-defined from the argument list, because the shift causes them\n    // to get lost/corrupted in android 2.3 and IE9 #715 #775\n    var _option = option;\n\n    [].shift.apply(args);\n\n    var value;\n    var chain = this.each(function () {\n      var $this = $(this);\n      if ($this.is('select')) {\n        var data = $this.data('selectpicker'),\n            options = typeof _option == 'object' && _option;\n\n        if (!data) {\n          var config = $.extend({}, Selectpicker.DEFAULTS, $.fn.selectpicker.defaults || {}, $this.data(), options);\n          config.template = $.extend({}, Selectpicker.DEFAULTS.template, ($.fn.selectpicker.defaults ? $.fn.selectpicker.defaults.template : {}), $this.data().template, options.template);\n          $this.data('selectpicker', (data = new Selectpicker(this, config)));\n        } else if (options) {\n          for (var i in options) {\n            if (options.hasOwnProperty(i)) {\n              data.options[i] = options[i];\n            }\n          }\n        }\n\n        if (typeof _option == 'string') {\n          if (data[_option] instanceof Function) {\n            value = data[_option].apply(data, args);\n          } else {\n            value = data.options[_option];\n          }\n        }\n      }\n    });\n\n    if (typeof value !== 'undefined') {\n      //noinspection JSUnusedAssignment\n      return value;\n    } else {\n      return chain;\n    }\n  }\n\n  var old = $.fn.selectpicker;\n  $.fn.selectpicker = Plugin;\n  $.fn.selectpicker.Constructor = Selectpicker;\n\n  // SELECTPICKER NO CONFLICT\n  // ========================\n  $.fn.selectpicker.noConflict = function () {\n    $.fn.selectpicker = old;\n    return this;\n  };\n\n  $(document)\n      .data('keycount', 0)\n      .on('keydown.bs.select', '.bootstrap-select [data-toggle=dropdown], .bootstrap-select [role=\"listbox\"], .bs-searchbox input', Selectpicker.prototype.keydown)\n      .on('focusin.modal', '.bootstrap-select [data-toggle=dropdown], .bootstrap-select [role=\"listbox\"], .bs-searchbox input', function (e) {\n        e.stopPropagation();\n      });\n\n  // SELECTPICKER DATA-API\n  // =====================\n  $(window).on('load.bs.select.data-api', function () {\n    $('.selectpicker').each(function () {\n      var $selectpicker = $(this);\n      Plugin.call($selectpicker, $selectpicker.data());\n    })\n  });\n})(jQuery);\n"
  },
  {
    "path": "app_backend/static/plugin/bootstrap-select-1.12.2/js/i18n/defaults-ar_AR.js",
    "content": "/*!\n * Translated default messages for bootstrap-select.\n * Locale: AR (Arabic)\n * Author: Yasser Lotfy <y_l@alive.com>\n */\n(function ($) {\n  $.fn.selectpicker.defaults = {\n    noneSelectedText: 'لم يتم إختيار شئ',\n    noneResultsText: 'لا توجد نتائج مطابقة لـ {0}',\n    countSelectedText: function (numSelected, numTotal) {\n      return (numSelected == 1) ? \"{0} خيار تم إختياره\" : \"{0} خيارات تمت إختيارها\";\n    },\n    maxOptionsText: function (numAll, numGroup) {\n      return [\n        (numAll == 1) ? 'تخطى الحد المسموح ({n} خيار بحد أقصى)' : 'تخطى الحد المسموح ({n} خيارات بحد أقصى)',\n        (numGroup == 1) ? 'تخطى الحد المسموح للمجموعة ({n} خيار بحد أقصى)' : 'تخطى الحد المسموح للمجموعة ({n} خيارات بحد أقصى)'\n      ];\n    },\n    selectAllText: 'إختيار الجميع',\n    deselectAllText: 'إلغاء إختيار الجميع',\n    multipleSeparator: '، '\n  };\n})(jQuery);\n"
  },
  {
    "path": "app_backend/static/plugin/bootstrap-select-1.12.2/js/i18n/defaults-bg_BG.js",
    "content": "/*\n * Translated default messages for bootstrap-select.\n * Locale: BG (Bulgaria)\n * Region: BG (Bulgaria)\n */\n(function ($) {\n  $.fn.selectpicker.defaults = {\n    noneSelectedText: 'Нищо избрано',\n    noneResultsText: 'Няма резултат за {0}',\n    countSelectedText: function (numSelected, numTotal) {\n      return (numSelected == 1) ? \"{0} избран елемент\" : \"{0} избрани елемента\";\n    },\n    maxOptionsText: function (numAll, numGroup) {\n      return [\n        (numAll == 1) ? 'Лимита е достигнат ({n} елемент максимум)' : 'Лимита е достигнат ({n} елемента максимум)',\n        (numGroup == 1) ? 'Груповия лимит е достигнат ({n} елемент максимум)' : 'Груповия лимит е достигнат ({n} елемента максимум)'\n      ];\n    },\n    selectAllText: 'Избери всички',\n    deselectAllText: 'Размаркирай всички',\n    multipleSeparator: ', '\n  };\n})(jQuery);\n"
  },
  {
    "path": "app_backend/static/plugin/bootstrap-select-1.12.2/js/i18n/defaults-cro_CRO.js",
    "content": "/*\n * Translated default messages for bootstrap-select.\n * Locale: CRO (Croatia)\n * Region: CRO (Croatia)\n */\n(function ($) {\n  $.fn.selectpicker.defaults = {\n    noneSelectedText: 'Odaberite stavku',\n    noneResultsText: 'Nema rezultata pretrage {0}',\n    countSelectedText: function (numSelected, numTotal) {\n      return (numSelected == 1) ? \"{0} stavka selektirana\" : \"{0} stavke selektirane\";\n    },\n    maxOptionsText: function (numAll, numGroup) {\n      return [\n        (numAll == 1) ? 'Limit je postignut ({n} stvar maximalno)' : 'Limit je postignut ({n} stavke maksimalno)',\n        (numGroup == 1) ? 'Grupni limit je postignut ({n} stvar maksimalno)' : 'Grupni limit je postignut ({n} stavke maksimalno)'\n      ];\n    },\n    selectAllText: 'Selektiraj sve',\n    deselectAllText: 'Deselektiraj sve',\n    multipleSeparator: ', '\n  };\n})(jQuery);\n"
  },
  {
    "path": "app_backend/static/plugin/bootstrap-select-1.12.2/js/i18n/defaults-cs_CZ.js",
    "content": "/*\n * Translated default messages for bootstrap-select.\n * Locale: CS\n * Region: CZ (Czech Republic)\n */\n(function ($) {\n  $.fn.selectpicker.defaults = {\n    noneSelectedText: 'Nic není vybráno',\n    noneResultsText: 'Žádné výsledky {0}',\n    countSelectedText: 'Označeno {0} z {1}',\n    maxOptionsText: ['Limit překročen ({n} {var} max)', 'Limit skupiny překročen ({n} {var} max)', ['položek', 'položka']],\n    multipleSeparator: ', '\n  };\n})(jQuery);\n"
  },
  {
    "path": "app_backend/static/plugin/bootstrap-select-1.12.2/js/i18n/defaults-da_DK.js",
    "content": "/*\n * Translated default messages for bootstrap-select.\n * Locale: DA (Danish)\n * Region: DK (Denmark)\n */\n(function ($) {\n  $.fn.selectpicker.defaults = {\n    noneSelectedText: 'Intet valgt',\n    noneResultsText: 'Ingen resultater fundet {0}',\n    countSelectedText: function (numSelected, numTotal) {\n      return (numSelected == 1) ? \"{0} valgt\" : \"{0} valgt\";\n    },\n    maxOptionsText: function (numAll, numGroup) {\n      return [\n        (numAll == 1) ? 'Begrænsning nået (max {n} valgt)' : 'Begrænsning nået (max {n} valgte)',\n        (numGroup == 1) ? 'Gruppe-begrænsning nået (max {n} valgt)' : 'Gruppe-begrænsning nået (max {n} valgte)'\n      ];\n    },\n    selectAllText: 'Markér alle',\n    deselectAllText: 'Afmarkér alle',\n    multipleSeparator: ', '\n  };\n})(jQuery);\n"
  },
  {
    "path": "app_backend/static/plugin/bootstrap-select-1.12.2/js/i18n/defaults-de_DE.js",
    "content": "/*\n * Translated default messages for bootstrap-select.\n * Locale: DE (German, deutsch)\n * Region: DE (Germany, Deutschland)\n */\n(function ($) {\n  $.fn.selectpicker.defaults = {\n    noneSelectedText: 'Bitte wählen...',\n    noneResultsText: 'Keine Ergebnisse für {0}',\n    countSelectedText: function (numSelected, numTotal) {\n      return (numSelected == 1) ? \"{0} Element ausgewählt\" : \"{0} Elemente ausgewählt\";\n    },\n    maxOptionsText: function (numAll, numGroup) {\n      return [\n        (numAll == 1) ? 'Limit erreicht ({n} Element max.)' : 'Limit erreicht ({n} Elemente max.)',\n        (numGroup == 1) ? 'Gruppen-Limit erreicht ({n} Element max.)' : 'Gruppen-Limit erreicht ({n} Elemente max.)'\n      ];\n    },\n    selectAllText: 'Alles auswählen',\n    deselectAllText: 'Nichts auswählen',\n    multipleSeparator: ', '\n  };\n})(jQuery);\n"
  },
  {
    "path": "app_backend/static/plugin/bootstrap-select-1.12.2/js/i18n/defaults-en_US.js",
    "content": "/*\n * Translated default messages for bootstrap-select.\n * Locale: EN (English)\n * Region: US (United States)\n */\n(function ($) {\n  $.fn.selectpicker.defaults = {\n    noneSelectedText: 'Nothing selected',\n    noneResultsText: 'No results match {0}',\n    countSelectedText: function (numSelected, numTotal) {\n      return (numSelected == 1) ? \"{0} item selected\" : \"{0} items selected\";\n    },\n    maxOptionsText: function (numAll, numGroup) {\n      return [\n        (numAll == 1) ? 'Limit reached ({n} item max)' : 'Limit reached ({n} items max)',\n        (numGroup == 1) ? 'Group limit reached ({n} item max)' : 'Group limit reached ({n} items max)'\n      ];\n    },\n    selectAllText: 'Select All',\n    deselectAllText: 'Deselect All',\n    multipleSeparator: ', '\n  };\n})(jQuery);\n"
  },
  {
    "path": "app_backend/static/plugin/bootstrap-select-1.12.2/js/i18n/defaults-es_CL.js",
    "content": "/*\n * Translated default messages for bootstrap-select.\n * Locale: ES (Spanish)\n * Region: CL (Chile)\n */\n(function ($) {\n  $.fn.selectpicker.defaults = {\n    noneSelectedText: 'No hay selección',\n    noneResultsText: 'No hay resultados {0}',\n    countSelectedText: 'Seleccionados {0} de {1}',\n    maxOptionsText: ['Límite alcanzado ({n} {var} max)', 'Límite del grupo alcanzado({n} {var} max)', ['elementos', 'element']],\n    multipleSeparator: ', ',\n    selectAllText: 'Seleccionar Todos',\n    deselectAllText: 'Desmarcar Todos'\n  };\n})(jQuery);\n"
  },
  {
    "path": "app_backend/static/plugin/bootstrap-select-1.12.2/js/i18n/defaults-es_ES.js",
    "content": "/*\n * Translated default messages for bootstrap-select.\n * Locale: ES (Spanish)\n * Region: ES (Spain)\n */\n(function ($) {\n  $.fn.selectpicker.defaults = {\n    noneSelectedText: 'No hay selección',\n    noneResultsText: 'No hay resultados {0}',\n    countSelectedText: 'Seleccionados {0} de {1}',\n    maxOptionsText: ['Límite alcanzado ({n} {var} max)', 'Límite del grupo alcanzado({n} {var} max)', ['elementos', 'element']],\n    multipleSeparator: ', ',\n    selectAllText: 'Seleccionar Todos',\n    deselectAllText: 'Desmarcar Todos'\n  };\n})(jQuery);\n"
  },
  {
    "path": "app_backend/static/plugin/bootstrap-select-1.12.2/js/i18n/defaults-eu.js",
    "content": "/*\n * Translated default messages for bootstrap-select.\n * Locale: EU (Basque)\n * Region: \n */\n(function ($) {\n  $.fn.selectpicker.defaults = {\n    noneSelectedText: 'Hautapenik ez',\n    noneResultsText: 'Emaitzarik ez {0}',\n    countSelectedText: '{1}(e)tik {0} hautatuta',\n    maxOptionsText: ['Mugara iritsita ({n} {var} gehienez)', 'Taldearen mugara iritsita ({n} {var} gehienez)', ['elementu', 'elementu']],\n    multipleSeparator: ', '\n  };\n})(jQuery);\n"
  },
  {
    "path": "app_backend/static/plugin/bootstrap-select-1.12.2/js/i18n/defaults-fa_IR.js",
    "content": "/*\n * Translated default messages for bootstrap-select.\n * Locale: FA (Farsi)\n * Region: IR (Iran)\n */\n(function ($) {\n    $.fn.selectpicker.defaults = {\n        noneSelectedText: 'چیزی انتخاب نشده است',\n        noneResultsText: 'هیج مشابهی برای {0} پیدا نشد',\n        countSelectedText: \"{0} از {1} مورد انتخاب شده\",\n        maxOptionsText: ['بیشتر ممکن نیست {حداکثر {n} عدد}', 'بیشتر ممکن نیست {حداکثر {n} عدد}'],\n        selectAllText: 'انتخاب همه',\n        deselectAllText: 'انتخاب هیچ کدام',\n        multipleSeparator: ', '\n    };\n})(jQuery);\n"
  },
  {
    "path": "app_backend/static/plugin/bootstrap-select-1.12.2/js/i18n/defaults-fi_FI.js",
    "content": "/*\n * Translated default messages for bootstrap-select.\n * Locale: FI (Finnish)\n * Region: FI (Finland)\n */\n(function ($) {\n  $.fn.selectpicker.defaults = {\n    noneSelectedText: 'Ei valintoja',\n    noneResultsText: 'Ei hakutuloksia {0}',\n    countSelectedText: function (numSelected, numTotal) {\n      return (numSelected == 1) ? \"{0} valittu\" : \"{0} valitut\";\n    },\n    maxOptionsText: function (numAll, numGroup) {\n      return [\n        (numAll == 1) ? 'Valintojen maksimimäärä ({n} saavutettu)' : 'Valintojen maksimimäärä ({n} saavutettu)',\n        (numGroup == 1) ? 'Ryhmän maksimimäärä ({n} saavutettu)' : 'Ryhmän maksimimäärä ({n} saavutettu)'\n      ];\n    },\n    selectAllText: 'Valitse kaikki',\n    deselectAllText: 'Poista kaikki',\n    multipleSeparator: ', '\n  };\n})(jQuery);\n"
  },
  {
    "path": "app_backend/static/plugin/bootstrap-select-1.12.2/js/i18n/defaults-fr_FR.js",
    "content": "/*\n * Translated default messages for bootstrap-select.\n * Locale: FR (French; Français)\n * Region: FR (France)\n */\n(function ($) {\n  $.fn.selectpicker.defaults = {\n    noneSelectedText: 'Aucune sélection',\n    noneResultsText: 'Aucun résultat pour {0}',\n    countSelectedText: function (numSelected, numTotal) {\n      return (numSelected > 1) ? \"{0} éléments sélectionnés\" : \"{0} élément sélectionné\";\n    },\n    maxOptionsText: function (numAll, numGroup) {\n      return [\n        (numAll > 1) ? 'Limite atteinte ({n} éléments max)' : 'Limite atteinte ({n} élément max)',\n        (numGroup > 1) ? 'Limite du groupe atteinte ({n} éléments max)' : 'Limite du groupe atteinte ({n} élément max)'\n      ];\n    },\n    multipleSeparator: ', ',\n    selectAllText: 'Tout Sélectionner',\n    deselectAllText: 'Tout Dé-selectionner',\n  };\n})(jQuery);\n"
  },
  {
    "path": "app_backend/static/plugin/bootstrap-select-1.12.2/js/i18n/defaults-hu_HU.js",
    "content": "/*\n * Translated default messages for bootstrap-select.\n * Locale: HU (Hungarian)\n * Region: HU (Hungary)\n */\n(function ($) {\n  $.fn.selectpicker.defaults = {\n    noneSelectedText: 'Válasszon!',\n    noneResultsText: 'Nincs találat {0}',\n    countSelectedText: function (numSelected, numTotal) {\n      return '{0} elem kiválasztva';\n    },\n    maxOptionsText: function (numAll, numGroup) {\n      return [\n        'Legfeljebb {n} elem választható',\n        'A csoportban legfeljebb {n} elem választható'\n      ];\n    },\n    selectAllText: 'Mind',\n    deselectAllText: 'Egyik sem',\n    multipleSeparator: ', '\n  };\n})(jQuery);\n"
  },
  {
    "path": "app_backend/static/plugin/bootstrap-select-1.12.2/js/i18n/defaults-id_ID.js",
    "content": "/*\n * Translated default messages for bootstrap-select.\n * Locale: ID (Indonesian; Bahasa Indonesia)\n * Region: ID (Indonesia)\n */\n(function ($) {\n  $.fn.selectpicker.defaults = {\n    noneSelectedText: 'Tidak ada yang dipilih',\n    noneResultsText: 'Tidak ada yang cocok {0}',\n    countSelectedText: '{0} terpilih',\n    maxOptionsText: ['Mencapai batas (maksimum {n})', 'Mencapai batas grup (maksimum {n})'],\n    selectAllText: 'Pilih Semua',\n    deselectAllText: 'Hapus Semua',\n    multipleSeparator: ', '\n  };\n})(jQuery);\n"
  },
  {
    "path": "app_backend/static/plugin/bootstrap-select-1.12.2/js/i18n/defaults-it_IT.js",
    "content": "/*\n * Translated default messages for bootstrap-select.\n * Locale: IT (Italian; italiano)\n * Region: IT (Italy; Italia)\n * Author: Michele Beltrame <mb@cattlegrid.info>\n */\n(function ($) {\n  $.fn.selectpicker.defaults = {\n    noneSelectedText: 'Nessuna selezione',\n    noneResultsText: 'Nessun risultato per {0}',\n    countSelectedText: function (numSelected, numTotal){\n      return (numSelected == 1) ? 'Selezionato {0} di {1}' : 'Selezionati {0} di {1}';\n    },\n    maxOptionsText: ['Limite raggiunto ({n} {var} max)', 'Limite del gruppo raggiunto ({n} {var} max)', ['elementi', 'elemento']],\n    multipleSeparator: ', ',\n    selectAllText: 'Seleziona Tutto',\n    deselectAllText: 'Deseleziona Tutto'\n  };\n})(jQuery);\n"
  },
  {
    "path": "app_backend/static/plugin/bootstrap-select-1.12.2/js/i18n/defaults-ko_KR.js",
    "content": "/*\n * Translated default messages for bootstrap-select.\n * Locale: KO (Korean)\n * Region: KR (South Korea)\n */\n(function ($) {\n  $.fn.selectpicker.defaults = {\n    noneSelectedText: '항목을 선택해주세요',\n    noneResultsText: '{0} 검색 결과가 없습니다',\n    countSelectedText: function (numSelected, numTotal) {\n      return \"{0}개를 선택하였습니다\";\n    },\n    maxOptionsText: function (numAll, numGroup) {\n      return [\n        '{n}개까지 선택 가능합니다',\n        '해당 그룹은 {n}개까지 선택 가능합니다'\n      ];\n    },\n    selectAllText: '전체선택',\n    deselectAllText: '전체해제',\n    multipleSeparator: ', '\n  };\n})(jQuery);\n"
  },
  {
    "path": "app_backend/static/plugin/bootstrap-select-1.12.2/js/i18n/defaults-lt_LT.js",
    "content": "/*\n * Translated default messages for bootstrap-select.\n * Locale: LT (Lithuanian)\n * Region: LT (Lithuania)\n */\n(function ($) {\n  $.fn.selectpicker.defaults = {\n    noneSelectedText: 'Niekas nepasirinkta',\n    noneResultsText: 'Niekas nesutapo su {0}',\n    countSelectedText: function (numSelected, numTotal) {\n      return (numSelected == 1) ? \"{0} elementas pasirinktas\" : \"{0} elementai(-ų) pasirinkta\";\n    },\n    maxOptionsText: function (numAll, numGroup) {\n      return [\n        (numAll == 1) ? 'Pasiekta riba ({n} elementas daugiausiai)' : 'Riba pasiekta ({n} elementai(-ų) daugiausiai)',\n        (numGroup == 1) ? 'Grupės riba pasiekta ({n} elementas daugiausiai)' : 'Grupės riba pasiekta ({n} elementai(-ų) daugiausiai)'\n      ];\n    },\n    selectAllText: 'Pasirinkti visus',\n    deselectAllText: 'Atmesti visus',\n    multipleSeparator: ', '\n  };\n})(jQuery);\n"
  },
  {
    "path": "app_backend/static/plugin/bootstrap-select-1.12.2/js/i18n/defaults-nb_NO.js",
    "content": "/*\n * Translated default messages for bootstrap-select.\n * Locale: NB (Norwegian; Bokmål)\n * Region: NO (Norway)\n */\n(function ($) {\n  $.fn.selectpicker.defaults = {\n    noneSelectedText: 'Ingen valgt',\n    noneResultsText: 'Søket gir ingen treff {0}',\n    countSelectedText: function (numSelected, numTotal) {\n      return (numSelected == 1) ? \"{0} alternativ valgt\" : \"{0} alternativer valgt\";\n    },\n    maxOptionsText: function (numAll, numGroup) {\n      return [\n        (numAll == 1) ? 'Grense nådd (maks {n} valg)' : 'Grense nådd (maks {n} valg)',\n        (numGroup == 1) ? 'Grense for grupper nådd (maks {n} grupper)' : 'Grense for grupper nådd (maks {n} grupper)'\n      ];\n    },\n    selectAllText: 'Merk alle',\n    deselectAllText: 'Fjern alle',\n    multipleSeparator: ', '\n  };\n})(jQuery);\n"
  },
  {
    "path": "app_backend/static/plugin/bootstrap-select-1.12.2/js/i18n/defaults-nl_NL.js",
    "content": "/*\n * Translated default messages for bootstrap-select.\n * Locale: NL (Dutch; Nederlands)\n * Region: NL (Europe)\n * Author: Daan Rosbergen (Badmuts)\n */\n(function ($) {\n  $.fn.selectpicker.defaults = {\n    noneSelectedText: 'Niets geselecteerd',\n    noneResultsText: 'Geen resultaten gevonden voor {0}',\n    countSelectedText: '{0} van {1} geselecteerd',\n    maxOptionsText: ['Limiet bereikt ({n} {var} max)', 'Groep limiet bereikt ({n} {var} max)', ['items', 'item']],\n    multipleSeparator: ', '\n  };\n})(jQuery);\n"
  },
  {
    "path": "app_backend/static/plugin/bootstrap-select-1.12.2/js/i18n/defaults-pl_PL.js",
    "content": "/*\n * Translated default messages for bootstrap-select.\n * Locale: PL (Polish)\n * Region: EU (Europe)\n */\n(function ($) {\n  $.fn.selectpicker.defaults = {\n    noneSelectedText: 'Nic nie zaznaczono',\n    noneResultsText: 'Brak wyników wyszukiwania {0}',\n    countSelectedText: 'Zaznaczono {0} z {1}',\n    maxOptionsText: ['Osiągnięto limit ({n} {var} max)', 'Limit grupy osiągnięty ({n} {var} max)', ['elementy', 'element']],\n    selectAll: 'Zaznacz wszystkie',\n    deselectAll: 'Odznacz wszystkie',\n    multipleSeparator: ', '\n  };\n})(jQuery);\n"
  },
  {
    "path": "app_backend/static/plugin/bootstrap-select-1.12.2/js/i18n/defaults-pt_BR.js",
    "content": "/*\n * Translated default messages for bootstrap-select.\n * Locale: PT (Portuguese; português)\n * Region: BR (Brazil; Brasil)\n * Author: Rodrigo de Avila <rodrigo@avila.net.br>\n */\n(function ($) {\n  $.fn.selectpicker.defaults = {\n    noneSelectedText: 'Nada selecionado',\n    noneResultsText: 'Nada encontrado contendo {0}',\n    countSelectedText: 'Selecionado {0} de {1}',\n    maxOptionsText: ['Limite excedido (máx. {n} {var})', 'Limite do grupo excedido (máx. {n} {var})', ['itens', 'item']],\n    multipleSeparator: ', '\n  };\n})(jQuery);\n"
  },
  {
    "path": "app_backend/static/plugin/bootstrap-select-1.12.2/js/i18n/defaults-pt_PT.js",
    "content": "/*\n* Translated default messages for bootstrap-select.\n* Locale: PT (Portuguese; português)\n* Region: PT (Portugal; Portugal)\n* Author: Burnspirit <burnspirit@gmail.com>\n*/\n(function ($) {\n$.fn.selectpicker.defaults = {\nnoneSelectedText: 'Nenhum seleccionado',\nnoneResultsText: 'Sem resultados contendo {0}',\ncountSelectedText: 'Selecionado {0} de {1}',\nmaxOptionsText: ['Limite ultrapassado (máx. {n} {var})', 'Limite de seleções ultrapassado (máx. {n} {var})', ['itens', 'item']],\nmultipleSeparator: ', '\n};\n})(jQuery);\n"
  },
  {
    "path": "app_backend/static/plugin/bootstrap-select-1.12.2/js/i18n/defaults-ro_RO.js",
    "content": "/*\n * Translated default messages for bootstrap-select.\n * Locale: RO (Romanian)\n * Region: RO (Romania)\n * Alex Florea <alecz.fia@gmail.com>\n */\n(function ($) {\n  $.fn.selectpicker.defaults = {\n    noneSelectedText: 'Nu a fost selectat nimic',\n    noneResultsText: 'Nu exista niciun rezultat {0}',\n    countSelectedText: '{0} din {1} selectat(e)',\n    maxOptionsText: ['Limita a fost atinsa ({n} {var} max)', 'Limita de grup a fost atinsa ({n} {var} max)', ['iteme', 'item']],\n    multipleSeparator: ', '\n  };\n})(jQuery);\n"
  },
  {
    "path": "app_backend/static/plugin/bootstrap-select-1.12.2/js/i18n/defaults-ru_RU.js",
    "content": "/*\n * Translated default messages for bootstrap-select.\n * Locale: RU (Russian; Русский)\n * Region: RU (Russian Federation)\n */\n(function ($) {\n  $.fn.selectpicker.defaults = {\n    noneSelectedText: 'Ничего не выбрано',\n    noneResultsText: 'Совпадений не найдено {0}',\n    countSelectedText: 'Выбрано {0} из {1}',\n    maxOptionsText: ['Достигнут предел ({n} {var} максимум)', 'Достигнут предел в группе ({n} {var} максимум)', ['шт.', 'шт.']],\n    doneButtonText: 'Закрыть',\n    selectAllText: 'Выбрать все',\n    deselectAllText: 'Отменить все',    \n    multipleSeparator: ', '\n  };\n})(jQuery);\n"
  },
  {
    "path": "app_backend/static/plugin/bootstrap-select-1.12.2/js/i18n/defaults-sk_SK.js",
    "content": "/*\n * Translated default messages for bootstrap-select.\n * Locale: SK\n * Region: SK (Slovak Republic)\n */\n(function ($) {\n  $.fn.selectpicker.defaults = {\n    noneSelectedText: 'Vyberte zo zoznamu',\n    noneResultsText: 'Pre výraz {0} neboli nájdené žiadne výsledky',\n    countSelectedText: 'Vybrané {0} z {1}',\n    maxOptionsText: ['Limit prekročený ({n} {var} max)', 'Limit skupiny prekročený ({n} {var} max)', ['položiek', 'položka']],\n    selectAllText: 'Vybrať všetky',\n    deselectAllText: 'Zrušiť výber',\n    multipleSeparator: ', '\n  };\n})(jQuery);\n"
  },
  {
    "path": "app_backend/static/plugin/bootstrap-select-1.12.2/js/i18n/defaults-sl_SI.js",
    "content": "/*\n * Translated default messages for bootstrap-select.\n * Locale: SL (Slovenian)\n * Region: SI (Slovenia)\n */\n(function ($) {\n  $.fn.selectpicker.defaults = {\n    noneSelectedText: 'Nič izbranega',\n    noneResultsText: 'Ni zadetkov za {0}',\n    countSelectedText: function (numSelected, numTotal) {\n      \"Število izbranih: {0}\";\n    },\n    maxOptionsText: function (numAll, numGroup) {\n      return [\n        'Omejitev dosežena (max. izbranih: {n})',\n        'Omejitev skupine dosežena (max. izbranih: {n})'\n      ];\n    },\n    selectAllText: 'Izberi vse',\n    deselectAllText: 'Počisti izbor',\n    multipleSeparator: ', '\n  };\n})(jQuery);\n"
  },
  {
    "path": "app_backend/static/plugin/bootstrap-select-1.12.2/js/i18n/defaults-sv_SE.js",
    "content": "/*\n * Translated default messages for bootstrap-select.\n * Locale: SV (Swedish)\n * Region: SE (Sweden)\n */\n(function ($) {\n  $.fn.selectpicker.defaults = {\n    noneSelectedText: 'Inget valt',\n    noneResultsText: 'Inget sökresultat matchar {0}',\n    countSelectedText: function (numSelected, numTotal) {\n      return (numSelected === 1) ? \"{0} alternativ valt\" : \"{0} alternativ valda\";\n    },\n    maxOptionsText: function (numAll, numGroup) {\n      return [\n        'Gräns uppnåd (max {n} alternativ)',\n        'Gräns uppnåd (max {n} gruppalternativ)'\n      ];\n    },\n    selectAllText: 'Markera alla',\n    deselectAllText: 'Avmarkera alla',\n    multipleSeparator: ', '\n  };\n})(jQuery);\n"
  },
  {
    "path": "app_backend/static/plugin/bootstrap-select-1.12.2/js/i18n/defaults-tr_TR.js",
    "content": "/*\n * Translated default messages for bootstrap-select.\n * Locale: TR (Turkey)\n * Region: TR (Europe)\n * Author: Serhan Güney\n */\n(function ($) {\n  $.fn.selectpicker.defaults = {\n    noneSelectedText: 'Hiçbiri seçilmedi',\n    noneResultsText: 'Hiçbir sonuç bulunamadı {0}',\n    countSelectedText: function (numSelected, numTotal) {\n      return (numSelected == 1) ? \"{0} öğe seçildi\" : \"{0} öğe seçildi\";\n    },\n    maxOptionsText: function (numAll, numGroup) {\n      return [\n        (numAll == 1) ? 'Limit aşıldı (maksimum {n} sayıda öğe )' : 'Limit aşıldı (maksimum {n} sayıda öğe)',\n        (numGroup == 1) ? 'Grup limiti aşıldı (maksimum {n} sayıda öğe)' : 'Grup limiti aşıldı (maksimum {n} sayıda öğe)'\n      ];\n    },\n    selectAllText: 'Tümünü Seç',\n    deselectAllText: 'Seçiniz',\n    multipleSeparator: ', '\n  };\n})(jQuery);\n"
  },
  {
    "path": "app_backend/static/plugin/bootstrap-select-1.12.2/js/i18n/defaults-ua_UA.js",
    "content": "/*\n * Translated default messages for bootstrap-select.\n * Locale: UA (Ukrainian; Українська)\n * Region: UA (Ukraine)\n */\n(function ($) {\n  $.fn.selectpicker.defaults = {\n    noneSelectedText: 'Нічого не вибрано',\n    noneResultsText: 'Збігів не знайдено {0}',\n    countSelectedText: 'Вибрано {0} із {1}',\n    maxOptionsText: ['Досягнута межа ({n} {var} максимум)', 'Досягнута межа в групі ({n} {var} максимум)', ['items', 'item']],\n    multipleSeparator: ', '\n  };\n})(jQuery);\n"
  },
  {
    "path": "app_backend/static/plugin/bootstrap-select-1.12.2/js/i18n/defaults-zh_CN.js",
    "content": "/*\n * Translated default messages for bootstrap-select.\n * Locale: ZH (Chinese)\n * Region: CN (China)\n */\n(function ($) {\n  $.fn.selectpicker.defaults = {\n    noneSelectedText: '没有选中任何项',\n    noneResultsText: '没有找到匹配项',\n    countSelectedText: '选中{1}中的{0}项',\n    maxOptionsText: ['超出限制 (最多选择{n}项)', '组选择超出限制(最多选择{n}组)'],\n    multipleSeparator: ', '\n  };\n})(jQuery);\n"
  },
  {
    "path": "app_backend/static/plugin/bootstrap-select-1.12.2/js/i18n/defaults-zh_TW.js",
    "content": "/*\n * Translated default messages for bootstrap-select.\n * Locale: ZH (Chinese)\n * Region: TW (Taiwan)\n */\n(function ($) {\n  $.fn.selectpicker.defaults = {\n    noneSelectedText: '沒有選取任何項目',\n    noneResultsText: '沒有找到符合的結果',\n    countSelectedText: '已經選取{0}個項目',\n    maxOptionsText: ['超過限制 (最多選擇{n}項)', '超過限制(最多選擇{n}組)'],\n    selectAllText: '選取全部',\n    deselectAllText: '全部取消',\n    multipleSeparator: ', '\n  };\n})(jQuery);\n"
  },
  {
    "path": "app_backend/static/plugin/bootstrap-select-1.12.2/less/bootstrap-select.less",
    "content": "@import \"variables\";\n\n// Mixins\n.cursor-disabled() {\n  cursor: not-allowed;\n}\n\n// Rules\nselect.bs-select-hidden,\nselect.selectpicker {\n  display: none !important;\n}\n\n.bootstrap-select {\n  width: 220px \\0; /*IE9 and below*/\n\n  // The selectpicker button\n  > .dropdown-toggle {\n    width: 100%;\n    padding-right: 25px;\n    z-index: 1;\n\n    &.bs-placeholder,\n    &.bs-placeholder:hover,\n    &.bs-placeholder:focus,\n    &.bs-placeholder:active { color: @input-color-placeholder; }\n  }\n\n  > select {\n    position: absolute !important;\n    bottom: 0;\n    left: 50%;\n    display: block !important;\n    width: 0.5px !important;\n    height: 100% !important;\n    padding: 0 !important;\n    opacity: 0 !important;\n    border: none;\n\n    &.mobile-device {\n      top: 0;\n      left: 0;\n      display: block !important;\n      width: 100% !important;\n      z-index: 2;\n    }\n  }\n\n  // Error display\n  .has-error & .dropdown-toggle,\n  .error & .dropdown-toggle {\n    border-color: @color-red-error;\n  }\n\n  &.fit-width {\n    width: auto !important;\n  }\n\n  &:not([class*=\"col-\"]):not([class*=\"form-control\"]):not(.input-group-btn) {\n    width: @width-default;\n  }\n\n  .dropdown-toggle:focus {\n    outline: thin dotted #333333 !important;\n    outline: 5px auto -webkit-focus-ring-color !important;\n    outline-offset: -2px;\n  }\n}\n\n.bootstrap-select.form-control {\n  margin-bottom: 0;\n  padding: 0;\n  border: none;\n\n  &:not([class*=\"col-\"]) {\n    width: 100%;\n  }\n\n  &.input-group-btn {\n    z-index: auto;\n\n    &:not(:first-child):not(:last-child) {\n      > .btn {\n        border-radius: 0;\n      }\n    }\n  }\n}\n\n// The selectpicker components\n.bootstrap-select.btn-group {\n  &:not(.input-group-btn),\n  &[class*=\"col-\"] {\n    float: none;\n    display: inline-block;\n    margin-left: 0;\n  }\n\n  // Forces the pull to the right, if necessary\n  &,\n  &[class*=\"col-\"],\n  .row &[class*=\"col-\"] {\n    &.dropdown-menu-right {\n      float: right;\n    }\n  }\n\n  .form-inline &,\n  .form-horizontal &,\n  .form-group & {\n    margin-bottom: 0;\n  }\n\n  .form-group-lg &.form-control,\n  .form-group-sm &.form-control {\n    padding: 0;\n\n    .dropdown-toggle {\n      height: 100%;\n      font-size: inherit;\n      line-height: inherit;\n      border-radius: inherit;\n    }\n  }\n\n  // Set the width of the live search (and any other form control within an inline form)\n  // see https://github.com/silviomoreto/bootstrap-select/issues/685\n  .form-inline & .form-control {\n    width: 100%;\n  }\n\n  &.disabled,\n  > .disabled {\n    .cursor-disabled();\n\n    &:focus {\n      outline: none !important;\n    }\n  }\n\n  &.bs-container {\n    position: absolute;\n    height: 0 !important;\n    padding: 0 !important;\n    \n    .dropdown-menu {\n      z-index: @zindex-select-dropdown;\n    }\n  }\n\n  // The selectpicker button\n  .dropdown-toggle {\n    .filter-option {\n      display: inline-block;\n      overflow: hidden;\n      width: 100%;\n      text-align: left;\n    }\n\n    .caret {\n      position: absolute;\n      top: 50%;\n      right: 12px;\n      margin-top: -2px;\n      vertical-align: middle;\n    }\n  }\n\n  &[class*=\"col-\"] .dropdown-toggle {\n    width: 100%;\n  }\n\n  // The selectpicker dropdown\n  .dropdown-menu {\n    min-width: 100%;\n    box-sizing: border-box;\n\n    &.inner {\n      position: static;\n      float: none;\n      border: 0;\n      padding: 0;\n      margin: 0;\n      border-radius: 0;\n      box-shadow: none;\n    }\n\n    li {\n      position: relative;\n\n      &.active small {\n        color: #fff;\n      }\n\n      &.disabled a {\n        .cursor-disabled();\n      }\n\n      a {\n        cursor: pointer;\n        user-select: none;\n\n        &.opt {\n          position: relative;\n          padding-left: 2.25em;\n        }\n\n        span.check-mark {\n          display: none;\n        }\n\n        span.text {\n          display: inline-block;\n        }\n      }\n\n      small {\n        padding-left: 0.5em;\n      }\n    }\n\n    .notify {\n      position: absolute;\n      bottom: 5px;\n      width: 96%;\n      margin: 0 2%;\n      min-height: 26px;\n      padding: 3px 5px;\n      background: rgb(245, 245, 245);\n      border: 1px solid rgb(227, 227, 227);\n      box-shadow: inset 0 1px 1px fade(rgb(0, 0, 0), 5%);\n      pointer-events: none;\n      opacity: 0.9;\n      box-sizing: border-box;\n    }\n  }\n\n  .no-results {\n    padding: 3px;\n    background: #f5f5f5;\n    margin: 0 5px;\n    white-space: nowrap;\n  }\n\n  &.fit-width .dropdown-toggle {\n    .filter-option {\n      position: static;\n    }\n\n    .caret {\n      position: static;\n      top: auto;\n      margin-top: -1px;\n    }\n  }\n\n  &.show-tick .dropdown-menu li {\n    &.selected a span.check-mark {\n      position: absolute;\n      display: inline-block;\n      right: 15px;\n      margin-top: 5px;\n    }\n\n    a span.text {\n      margin-right: 34px;\n    }\n  }\n}\n\n.bootstrap-select.show-menu-arrow {\n  &.open > .dropdown-toggle {\n    z-index: (@zindex-select-dropdown + 1);\n  }\n\n  .dropdown-toggle {\n    &:before {\n      content: '';\n      border-left: 7px solid transparent;\n      border-right: 7px solid transparent;\n      border-bottom: 7px solid @color-grey-arrow;\n      position: absolute;\n      bottom: -4px;\n      left: 9px;\n      display: none;\n    }\n\n    &:after {\n      content: '';\n      border-left: 6px solid transparent;\n      border-right: 6px solid transparent;\n      border-bottom: 6px solid white;\n      position: absolute;\n      bottom: -4px;\n      left: 10px;\n      display: none;\n    }\n  }\n\n  &.dropup .dropdown-toggle {\n    &:before {\n      bottom: auto;\n      top: -3px;\n      border-top: 7px solid @color-grey-arrow;\n      border-bottom: 0;\n    }\n\n    &:after {\n      bottom: auto;\n      top: -3px;\n      border-top: 6px solid white;\n      border-bottom: 0;\n    }\n  }\n\n  &.pull-right .dropdown-toggle {\n    &:before {\n      right: 12px;\n      left: auto;\n    }\n\n    &:after {\n      right: 13px;\n      left: auto;\n    }\n  }\n\n  &.open > .dropdown-toggle {\n    &:before,\n    &:after {\n      display: block;\n    }\n  }\n}\n\n.bs-searchbox,\n.bs-actionsbox,\n.bs-donebutton {\n  padding: 4px 8px;\n}\n\n.bs-actionsbox {\n  width: 100%;\n  box-sizing: border-box;\n\n  & .btn-group button {\n    width: 50%;\n  }\n}\n\n.bs-donebutton {\n  float: left;\n  width: 100%;\n  box-sizing: border-box;\n\n  & .btn-group button {\n    width: 100%;\n  }\n}\n\n.bs-searchbox {\n  & + .bs-actionsbox {\n    padding: 0 8px 4px;\n  }\n\n  & .form-control {\n    margin-bottom: 0;\n    width: 100%;\n    float: none;\n  }\n}\n"
  },
  {
    "path": "app_backend/static/plugin/bootstrap-select-1.12.2/less/variables.less",
    "content": "@color-red-error: rgb(185, 74, 72);\n@color-grey-arrow: rgba(204, 204, 204, 0.2);\n\n@width-default: 220px; // 3 960px-grid columns\n\n@zindex-select-dropdown: 1060; // must be higher than a modal background (1050)\n\n//** Placeholder text color\n@input-color-placeholder: #999;"
  },
  {
    "path": "app_backend/static/plugin/bootstrap-select-1.12.2/nuget/MyGet.ps1",
    "content": "# set env vars usually set by MyGet (enable for local testing)\n#$env:SourcesPath = '..'\n#$env:NuGet = \"./nuget.exe\" #https://dist.nuget.org/win-x86-commandline/latest/nuget.exe\n\n$nuget = $env:NuGet\n\n# parse the version number out of package.json\n$bsversionParts = ((Get-Content $env:SourcesPath\\package.json) -join \"`n\" | ConvertFrom-Json).version.split('-', 2) # split the version on the '-'\n$bsversion = $bsversionParts[0]\n\nif ($bsversionParts.Length -gt 1)\n{\n    $bsversion += '-' + $bsversionParts[1].replace('.', '').replace('-', '_')   # strip out invalid chars from the PreRelease part\n}\n\n# update sourceMappingURL in bootstrap-select.min.js\n(Get-Content $env:SourcesPath\\dist\\js\\bootstrap-select.min.js).replace(\"sourceMappingURL=\", \"sourceMappingURL=Scripts/\") | Set-Content $env:SourcesPath\\dist\\js\\bootstrap-select.min.js\n\n# create packages\n& $nuget pack \"$env:SourcesPath\\nuget\\bootstrap-select.nuspec\" -Verbosity detailed -NonInteractive -NoPackageAnalysis -BasePath $env:SourcesPath -Version $bsversion"
  },
  {
    "path": "app_backend/static/plugin/bootstrap-select-1.12.2/nuget/bootstrap-select.nuspec",
    "content": "<?xml version=\"1.0\"?>\n<package xmlns=\"http://schemas.microsoft.com/packaging/2012/06/nuspec.xsd\">\n    <metadata>\n        <id>bootstrap-select</id>\n        <version>1.12.2</version>\n        <title>bootstrap-select</title>\n        <authors>Silvio Moreto,Ana Carolina,caseyjhol,Matt Bryson,and t0xicCode.</authors>\n        <owners>Silvio Moreto</owners>\n        <projectUrl>https://github.com/silviomoreto/bootstrap-select</projectUrl>\n        <description>Bootstrap-select is a jQuery plugin that utilizes Bootstrap's dropdown.js to style and bring additional functionality to standard select elements.</description>\n        <tags>bootstrap dropdown select</tags>\n        <requireLicenseAcceptance>false</requireLicenseAcceptance>\n        <dependencies>\n            <dependency id=\"jQuery\" version=\"1.8.0\" />\n        </dependencies>\n    </metadata>\n    <files>\n        <file src=\"dist\\js\\bootstrap-select*.*\" target=\"content\\Scripts\" />\n        <file src=\"dist\\js\\i18n\\*.*\" target=\"content\\Scripts\\i18n\" />\n        <file src=\"dist\\css\\*.*\" target=\"content\\Content\" />\n    </files>\n</package>"
  },
  {
    "path": "app_backend/static/plugin/bootstrap-select-1.12.2/package.json",
    "content": "{\n  \"name\": \"bootstrap-select\",\n  \"title\": \"bootstrap-select\",\n  \"main\": \"dist/js/bootstrap-select.js\",\n  \"description\": \"Bootstrap-select is a jQuery plugin that utilizes Bootstrap's dropdown.js to style and bring additional functionality to standard select elements.\",\n  \"version\": \"1.12.2\",\n  \"homepage\": \"http://silviomoreto.github.io/bootstrap-select\",\n  \"author\": {\n    \"name\": \"Silvio Moreto\",\n    \"url\": \"https://github.com/silviomoreto\"\n  },\n  \"contributors\": [\n    {\n      \"name\": \"Silvio Moreto\",\n      \"url\": \"https://github.com/silviomoreto\"\n    },\n    {\n      \"name\": \"Ana Carolina\",\n      \"url\": \"https://github.com/anacarolinats\"\n    },\n    {\n      \"name\": \"caseyjhol\",\n      \"url\": \"https://github.com/caseyjhol\"\n    },\n    {\n      \"name\": \"Matt Bryson\",\n      \"url\": \"https://github.com/mattbryson\"\n    },\n    {\n      \"name\": \"t0xicCode\",\n      \"url\": \"https://github.com/t0xicCode\"\n    }\n  ],\n  \"repository\": {\n    \"type\": \"git\",\n    \"url\": \"git://github.com/silviomoreto/bootstrap-select.git\"\n  },\n  \"license\": \"MIT\",\n  \"dependencies\": {\n    \"jquery\": \">=1.8\"\n  },\n  \"devDependencies\": {\n    \"grunt\": \"^1.0.1\",\n    \"grunt-autoprefixer\": \"^3.0.4\",\n    \"grunt-banner\": \"^0.6.0\",\n    \"grunt-contrib-clean\": \"^1.0.0\",\n    \"grunt-contrib-compress\": \"^1.3.0\",\n    \"grunt-contrib-concat\": \"^1.0.1\",\n    \"grunt-contrib-copy\": \"^1.0.0\",\n    \"grunt-contrib-csslint\": \"^2.0.0\",\n    \"grunt-contrib-cssmin\": \"^1.0.2\",\n    \"grunt-contrib-jshint\": \"^1.0.0\",\n    \"grunt-contrib-less\": \"^1.4.0\",\n    \"grunt-contrib-uglify\": \"^2.0.0\",\n    \"grunt-contrib-watch\": \"^1.0.0\",\n    \"grunt-umd\": \"^2.3.6\",\n    \"grunt-version\": \"^1.1.1\",\n    \"load-grunt-tasks\": \"^3.5.2\"\n  },\n  \"keywords\": [\n    \"form\",\n    \"bootstrap\",\n    \"select\",\n    \"replacement\"\n  ]\n}\n"
  },
  {
    "path": "app_backend/static/plugin/bootstrap-select-1.12.2/sass/bootstrap-select.scss",
    "content": "@import \"variables\";\n\n// Mixins\n@mixin cursor-disabled() {\n  cursor: not-allowed;\n}\n\n@mixin box-sizing($fmt) {\n  -webkit-box-sizing: $fmt;\n     -moz-box-sizing: $fmt;\n          box-sizing: $fmt;\n}\n\n@mixin box-shadow($fmt) {\n  -webkit-box-shadow: $fmt;\n          box-shadow: $fmt;\n}\n\n@function fade($color, $amnt) {\n  @if $amnt > 1 {\n    $amnt: $amnt / 100; // convert to percentage if int\n  }\n  @return rgba($color, $amnt);\n}\n\n// Rules\nselect.bs-select-hidden,\nselect.selectpicker {\n  display: none !important;\n}\n\n.bootstrap-select {\n  width: 220px \\0; /*IE9 and below*/\n\n  // The selectpicker button\n  > .dropdown-toggle {\n    width: 100%;\n    padding-right: 25px;\n    z-index: 1;\n\n    &.bs-placeholder,\n    &.bs-placeholder:hover,\n    &.bs-placeholder:focus,\n    &.bs-placeholder:active { color: $input-color-placeholder; }\n  }\n\n  > select {\n    position: absolute !important;\n    bottom: 0;\n    left: 50%;\n    display: block !important;\n    width: 0.5px !important;\n    height: 100% !important;\n    padding: 0 !important;\n    opacity: 0 !important;\n    border: none;\n\n    &.mobile-device {\n      top: 0;\n      left: 0;\n      display: block !important;\n      width: 100% !important;\n      z-index: 2;\n    }\n  }\n\n  // Error display\n  .has-error & .dropdown-toggle,\n  .error & .dropdown-toggle {\n    border-color: $color-red-error;\n  }\n\n  &.fit-width {\n    width: auto !important;\n  }\n\n  &:not([class*=\"col-\"]):not([class*=\"form-control\"]):not(.input-group-btn) {\n    width: $width-default;\n  }\n\n  .dropdown-toggle:focus {\n    outline: thin dotted #333333 !important;\n    outline: 5px auto -webkit-focus-ring-color !important;\n    outline-offset: -2px;\n  }\n}\n\n.bootstrap-select.form-control {\n  margin-bottom: 0;\n  padding: 0;\n  border: none;\n\n  &:not([class*=\"col-\"]) {\n    width: 100%;\n  }\n\n  &.input-group-btn {\n    z-index: auto;\n\n    &:not(:first-child):not(:last-child) {\n      > .btn {\n        border-radius: 0;\n      }\n    }\n  }\n}\n\n// The selectpicker components\n.bootstrap-select.btn-group {\n  &:not(.input-group-btn),\n  &[class*=\"col-\"] {\n    float: none;\n    display: inline-block;\n    margin-left: 0;\n  }\n\n  // Forces the pull to the right, if necessary\n  &,\n  &[class*=\"col-\"],\n  .row &[class*=\"col-\"] {\n    &.dropdown-menu-right {\n      float: right;\n    }\n  }\n\n  .form-inline &,\n  .form-horizontal &,\n  .form-group & {\n    margin-bottom: 0;\n  }\n\n  .form-group-lg &.form-control,\n  .form-group-sm &.form-control {\n    padding: 0;\n\n    .dropdown-toggle {\n      height: 100%;\n      font-size: inherit;\n      line-height: inherit;\n      border-radius: inherit;\n    }\n  }\n\n  // Set the width of the live search (and any other form control within an inline form)\n  // see https://github.com/silviomoreto/bootstrap-select/issues/685\n  .form-inline & .form-control {\n    width: 100%;\n  }\n\n  &.disabled,\n  > .disabled {\n    @include cursor-disabled();\n\n    &:focus {\n      outline: none !important;\n    }\n  }\n\n  &.bs-container {\n    position: absolute;\n    height: 0 !important;\n    padding: 0 !important;\n\n    .dropdown-menu {\n      z-index: $zindex-select-dropdown;\n    }\n  }\n\n  // The selectpicker button\n  .dropdown-toggle {\n    .filter-option {\n      display: inline-block;\n      overflow: hidden;\n      width: 100%;\n      text-align: left;\n    }\n\n    .caret {\n      position: absolute;\n      top: 50%;\n      right: 12px;\n      margin-top: -2px;\n      vertical-align: middle;\n    }\n  }\n\n  &[class*=\"col-\"] .dropdown-toggle {\n    width: 100%;\n  }\n\n  // The selectpicker dropdown\n  .dropdown-menu {\n    min-width: 100%;\n    @include box-sizing(border-box);\n\n    &.inner {\n      position: static;\n      float: none;\n      border: 0;\n      padding: 0;\n      margin: 0;\n      border-radius: 0;\n      box-shadow: none;\n    }\n\n    li {\n      position: relative;\n\n      &.active small {\n        color: #fff;\n      }\n\n      &.disabled a {\n        @include cursor-disabled();\n      }\n\n      a {\n        cursor: pointer;\n        user-select: none;\n\n        &.opt {\n          position: relative;\n          padding-left: 2.25em;\n        }\n\n        span.check-mark {\n          display: none;\n        }\n\n        span.text {\n          display: inline-block;\n        }\n      }\n\n      small {\n        padding-left: 0.5em;\n      }\n    }\n\n    .notify {\n      position: absolute;\n      bottom: 5px;\n      width: 96%;\n      margin: 0 2%;\n      min-height: 26px;\n      padding: 3px 5px;\n      background: rgb(245, 245, 245);\n      border: 1px solid rgb(227, 227, 227);\n      @include box-shadow(inset 0 1px 1px fade(rgb(0, 0, 0), 5));\n      pointer-events: none;\n      opacity: 0.9;\n      @include box-sizing(border-box);\n    }\n  }\n\n  .no-results {\n    padding: 3px;\n    background: #f5f5f5;\n    margin: 0 5px;\n    white-space: nowrap;\n  }\n\n  &.fit-width .dropdown-toggle {\n    .filter-option {\n      position: static;\n    }\n\n    .caret {\n      position: static;\n      top: auto;\n      margin-top: -1px;\n    }\n  }\n\n  &.show-tick .dropdown-menu li {\n    &.selected a span.check-mark {\n      position: absolute;\n      display: inline-block;\n      right: 15px;\n      margin-top: 5px;\n    }\n\n    a span.text {\n      margin-right: 34px;\n    }\n  }\n}\n\n.bootstrap-select.show-menu-arrow {\n  &.open > .dropdown-toggle {\n    z-index: ($zindex-select-dropdown + 1);\n  }\n\n  .dropdown-toggle {\n    &:before {\n      content: '';\n      border-left: 7px solid transparent;\n      border-right: 7px solid transparent;\n      border-bottom: 7px solid $color-grey-arrow;\n      position: absolute;\n      bottom: -4px;\n      left: 9px;\n      display: none;\n    }\n\n    &:after {\n      content: '';\n      border-left: 6px solid transparent;\n      border-right: 6px solid transparent;\n      border-bottom: 6px solid white;\n      position: absolute;\n      bottom: -4px;\n      left: 10px;\n      display: none;\n    }\n  }\n\n  &.dropup .dropdown-toggle {\n    &:before {\n      bottom: auto;\n      top: -3px;\n      border-top: 7px solid $color-grey-arrow;\n      border-bottom: 0;\n    }\n\n    &:after {\n      bottom: auto;\n      top: -3px;\n      border-top: 6px solid white;\n      border-bottom: 0;\n    }\n  }\n\n  &.pull-right .dropdown-toggle {\n    &:before {\n      right: 12px;\n      left: auto;\n    }\n\n    &:after {\n      right: 13px;\n      left: auto;\n    }\n  }\n\n  &.open > .dropdown-toggle {\n    &:before,\n    &:after {\n      display: block;\n    }\n  }\n}\n\n.bs-searchbox,\n.bs-actionsbox,\n.bs-donebutton {\n  padding: 4px 8px;\n}\n\n.bs-actionsbox {\n  width: 100%;\n  @include box-sizing(border-box);\n\n  & .btn-group button {\n    width: 50%;\n  }\n}\n\n.bs-donebutton {\n  float: left;\n  width: 100%;\n  @include box-sizing(border-box);\n\n  & .btn-group button {\n    width: 100%;\n  }\n}\n\n.bs-searchbox {\n  & + .bs-actionsbox {\n    padding: 0 8px 4px;\n  }\n\n  & .form-control {\n    margin-bottom: 0;\n    width: 100%;\n    float: none;\n  }\n}\n"
  },
  {
    "path": "app_backend/static/plugin/bootstrap-select-1.12.2/sass/variables.scss",
    "content": "$color-red-error: rgb(185, 74, 72) !default;\n$color-grey-arrow: rgba(204, 204, 204, 0.2) !default;\n\n$width-default: 220px !default; // 3 960px-grid columns\n\n$zindex-select-dropdown: 1060 !default; // must be higher than a modal background (1050)\n\n//** Placeholder text color\n$input-color-placeholder: #999 !default;"
  },
  {
    "path": "app_backend/static/plugin/bootstrap-select-1.12.2/test.html",
    "content": "<!DOCTYPE html>\n<html>\n<head>\n  <title>Bootstrap-select test page</title>\n\n  <meta charset=\"utf-8\">\n\n  <link rel=\"stylesheet\" href=\"https://maxcdn.bootstrapcdn.com/bootstrap/3.3.4/css/bootstrap.min.css\">\n  <link rel=\"stylesheet\" href=\"dist/css/bootstrap-select.css\">\n\n  <style>\n    body {\n      padding-top: 70px;\n    }\n  </style>\n\n  <script src=\"https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js\"></script>\n  <script src=\"https://maxcdn.bootstrapcdn.com/bootstrap/3.3.4/js/bootstrap.min.js\"></script>\n  <script src=\"dist/js/bootstrap-select.js\"></script>\n</head>\n<body>\n<nav class=\"navbar navbar-default navbar-fixed-top\" role=\"navigation\">\n  <div class=\"container\">\n    <div class=\"navbar-header\">\n      <a class=\"navbar-brand\" href=\"#\">Bootstrap-select usability tests</a>\n    </div>\n  </div>\n</nav>\n\n<div class=\"container\">\n  <form class=\"form-horizontal\" role=\"form\">\n    <div class=\"form-group\">\n      <label for=\"basic\" class=\"col-lg-2 control-label\">\"Basic\" (liveSearch disabled)</label>\n\n      <div class=\"col-lg-10\">\n        <select id=\"basic\" class=\"selectpicker show-tick form-control\">\n          <option>cow</option>\n          <option data-subtext=\"option subtext\">bull</option>\n          <option class=\"get-class\" disabled>ox</option>\n          <optgroup label=\"test\" data-subtext=\"optgroup subtext\">\n            <option>ASD</option>\n            <option selected>Bla</option>\n            <option>Ble</option>\n          </optgroup>\n        </select>\n      </div>\n    </div>\n  </form>\n\n  <hr>\n\n  <form class=\"form-horizontal\" role=\"form\">\n    <div class=\"form-group\">\n      <label for=\"basic\" class=\"col-lg-2 control-label\">\"Basic\" (liveSearch enabled)</label>\n\n      <div class=\"col-lg-10\">\n        <select id=\"basic\" class=\"selectpicker show-tick form-control\" data-live-search=\"true\">\n          <option>cow</option>\n          <option data-subtext=\"option subtext\">bull</option>\n          <option class=\"get-class\" disabled>ox</option>\n          <optgroup label=\"test\" data-subtext=\"optgroup subtext\">\n            <option>ASD</option>\n            <option selected>Bla</option>\n            <option>Ble</option>\n          </optgroup>\n        </select>\n      </div>\n    </div>\n  </form>\n\n  <hr>\n  <form class=\"form-horizontal\" role=\"form\">\n    <div class=\"form-group\">\n      <label for=\"basic2\" class=\"col-lg-2 control-label\">\"Basic\" (multiple, maxOptions=1)</label>\n\n      <div class=\"col-lg-10\">\n        <select id=\"basic2\" class=\"show-tick form-control\" multiple>\n          <option>cow</option>\n          <option>bull</option>\n          <option class=\"get-class\" disabled>ox</option>\n          <optgroup label=\"test\" data-subtext=\"another test\">\n            <option>ASD</option>\n            <option selected>Bla</option>\n            <option>Ble</option>\n          </optgroup>\n        </select>\n      </div>\n    </div>\n  </form>\n\n  <hr>\n  <form class=\"form-horizontal\" role=\"form\">\n    <div class=\"form-group\">\n      <label for=\"maxOption2\" class=\"col-lg-2 control-label\">multiple, show-menu-arrow, maxOptions=2</label>\n\n      <div class=\"col-lg-10\">\n        <select id=\"maxOption2\" class=\"selectpicker show-menu-arrow form-control\" multiple data-max-options=\"2\">\n          <option>chicken</option>\n          <option>turkey</option>\n          <option disabled>duck</option>\n          <option>goose</option>\n        </select>\n      </div>\n    </div>\n  </form>\n\n  <hr>\n  <form class=\"form-inline\">\n    <div class=\"form-group\">\n      <label class=\"col-md-1 control-label\" for=\"lunch\">Lunch:</label>\n    </div>\n    <div class=\"form-group\">\n      <select id=\"lunch\" class=\"selectpicker\" data-live-search=\"true\" title=\"Please select a lunch ...\">\n        <option>Hot Dog, Fries and a Soda</option>\n        <option>Burger, Shake and a Smile</option>\n        <option>Sugar, Spice and all things nice</option>\n        <option>Baby Back Ribs</option>\n        <option>A really really long option made to illustrate an issue with the live search in an inline form</option>\n      </select>\n    </div>\n  </form>\n\n  <hr>\n  <form class=\"form-horizontal\" role=\"form\">\n    <div class=\"form-group form-group-lg\">\n      <label for=\"error\" class=\"col-lg-2 control-label\">error</label>\n\n      <div class=\"col-lg-10 error\">\n        <select id=\"error\" class=\"selectpicker show-tick form-control\">\n          <option>pen</option>\n          <option>pencil</option>\n          <option selected>brush</option>\n        </select>\n      </div>\n    </div>\n  </form>\n\n  <hr>\n  <form class=\"form-horizontal\" role=\"form\">\n    <div class=\"form-group has-error form-group-lg\">\n      <label class=\"control-label col-lg-2\" for=\"country\">error type 2</label>\n\n      <div class=\"col-lg-10\">\n        <select id=\"country\" name=\"country\" class=\"form-control selectpicker\">\n          <option>Argentina</option>\n          <option>United State</option>\n          <option>Mexico</option>\n        </select>\n\n        <p class=\"help-block\">No service available in the selected country</p>\n      </div>\n    </div>\n  </form>\n\n  <hr>\n  <nav class=\"navbar navbar-default\" role=\"navigation\">\n    <div class=\"container-fluid\">\n      <div class=\"navbar-header\">\n        <a class=\"navbar-brand\" href=\"#\">Navbar</a>\n      </div>\n\n      <form class=\"navbar-form navbar-left\" role=\"search\">\n        <div class=\"form-group\">\n          <select class=\"selectpicker\" multiple data-live-search=\"true\" data-live-search-placeholder=\"Search\" data-actions-box=\"true\">\n            <optgroup label=\"filter1\">\n              <option>option1</option>\n              <option>option2</option>\n              <option>option3</option>\n              <option>option4</option>\n            </optgroup>\n            <optgroup label=\"filter2\">\n              <option>option1</option>\n              <option>option2</option>\n              <option>option3</option>\n              <option>option4</option>\n            </optgroup>\n            <optgroup label=\"filter3\">\n              <option>option1</option>\n              <option>option2</option>\n              <option>option3</option>\n              <option>option4</option>\n            </optgroup>\n          </select>\n        </div>\n\n        <div class=\"input-group\">\n          <input type=\"text\" class=\"form-control\" placeholder=\"Search\" name=\"q\">\n\n          <div class=\"input-group-btn\">\n            <button class=\"btn btn-default\" type=\"submit\"><i class=\"glyphicon glyphicon-search\"></i></button>\n          </div>\n        </div>\n        <button type=\"submit\" class=\"btn btn-default\">Search</button>\n      </form>\n\n    </div>\n    <!-- .container-fluid -->\n  </nav>\n\n  <hr>\n  <select id=\"first-disabled\" class=\"selectpicker\" data-hide-disabled=\"true\" data-live-search=\"true\">\n    <optgroup disabled=\"disabled\" label=\"disabled\">\n      <option>Hidden</option>\n    </optgroup>\n    <optgroup label=\"Fruit\">\n      <option>Apple</option>\n      <option>Orange</option>\n    </optgroup>\n    <optgroup label=\"Vegetable\">\n      <option>Corn</option>\n      <option>Carrot</option>\n    </optgroup>\n  </select>\n\n  <hr>\n  <select id=\"first-disabled2\" class=\"selectpicker\" multiple data-hide-disabled=\"true\" data-size=\"5\">\n    <option>Apple</option>\n    <option>Banana</option>\n    <option>Orange</option>\n    <option>Pineapple</option>\n    <option>Apple2</option>\n    <option>Banana2</option>\n    <option>Orange2</option>\n    <option>Pineapple2</option>\n    <option>Apple2</option>\n    <option>Banana2</option>\n    <option>Orange2</option>\n    <option>Pineapple2</option>\n  </select>\n  <button id=\"special\" class=\"btn btn-default\">Hide selected by disabling</button>\n  <button id=\"special2\" class=\"btn btn-default\">Reset</button>\n  <p>Just select 1st element, click button and check list again</p>\n\n  <hr>\n  <div class=\"input-group\">\n    <span class=\"input-group-addon\">@</span>\n    <select class=\"form-control selectpicker\">\n      <option>One</option>\n      <option>Two</option>\n      <option>Three</option>\n    </select>\n  </div>\n\n  <hr>\n  <div class=\"input-group\">\n    <span class=\"input-group-addon\">@</span>\n    <select class=\"form-control selectpicker\" data-mobile=\"true\">\n      <option>One</option>\n      <option>Two</option>\n      <option>Three</option>\n    </select>\n  </div>\n  <p>With <code>data-mobile=\"true\"</code> option.</p>\n\n  <hr>\n  <select id=\"done\" class=\"selectpicker\" multiple data-done-button=\"true\">\n    <option>Apple</option>\n    <option>Banana</option>\n    <option>Orange</option>\n    <option>Pineapple</option>\n    <option>Apple2</option>\n    <option>Banana2</option>\n    <option>Orange2</option>\n    <option>Pineapple2</option>\n    <option>Apple2</option>\n    <option>Banana2</option>\n    <option>Orange2</option>\n    <option>Pineapple2</option>\n  </select>\n\n  <hr>\n\n  <div class=\"form-group\">\n    <label for=\"tokens\">Key words (data-tokens)</label>\n    <select id=\"tokens\" class=\"selectpicker form-control\" multiple data-live-search=\"true\">\n      <option data-tokens=\"first\">I actually am called \"one\"</option>\n      <option data-tokens=\"second\">And me \"two\"</option>\n      <option data-tokens=\"last\">I am \"three\"</option>\n    </select>\n  </div>\n\n  <hr>\n  <form class=\"form-inline\">\n    <div class=\"form-group\">\n      <label class=\"col-md-1 control-label\" for=\"lunchBegins\">Lunch (Begins search):</label>\n    </div>\n    <div class=\"form-group\">\n      <select id=\"lunchBegins\" class=\"selectpicker\" data-live-search=\"true\" data-live-search-style=\"begins\" title=\"Please select a lunch ...\">\n        <option>Hot Dog, Fries and a Soda</option>\n        <option>Burger, Shake and a Smile</option>\n        <option>Sugar, Spice and all things nice</option>\n        <option>Baby Back Ribs</option>\n        <option>A really really long option made to illustrate an issue with the live search in an inline form</option>\n      </select>\n    </div>\n  </form>\n</div>\n\n<script>\n  $(document).ready(function () {\n    var mySelect = $('#first-disabled2');\n\n    $('#special').on('click', function () {\n      mySelect.find('option:selected').prop('disabled', true);\n      mySelect.selectpicker('refresh');\n    });\n\n    $('#special2').on('click', function () {\n      mySelect.find('option:disabled').prop('disabled', false);\n      mySelect.selectpicker('refresh');\n    });\n\n    $('#basic2').selectpicker({\n      liveSearch: true,\n      maxOptions: 1\n    });\n  });\n</script>\n</body>\n</html>\n"
  },
  {
    "path": "app_backend/static/plugin/d3/API.md",
    "content": "# D3 API Reference\n\nD3 4.0 is a [collection of modules](https://github.com/d3) that are designed to work together; you can use the modules independently, or you can use them together as part of the default build. The source and documentation for each module is available in its repository. Follow the links below to learn more. For changes between 3.x and 4.0, see [CHANGES](https://github.com/d3/d3/blob/master/CHANGES.md); see also the [3.x reference](https://github.com/d3/d3-3.x-api-reference/blob/master/API-Reference.md).\n\n* [Arrays](#arrays-d3-array) ([Statistics](#statistics), [Search](#search), [Transformations](#transformations), [Histograms](#histograms))\n* [Axes](#axes-d3-axis)\n* [Brushes](#brushes-d3-brush)\n* [Chords](#chords-d3-chord)\n* [Collections](#collections-d3-collection) ([Objects](#objects), [Maps](#maps), [Sets](#sets), [Nests](#nests))\n* [Colors](#colors-d3-color)\n* [Dispatches](#dispatches-d3-dispatch)\n* [Dragging](#dragging-d3-drag)\n* [Delimiter-Separated Values](#delimiter-separated-values-d3-dsv)\n* [Easings](#easings-d3-ease)\n* [Forces](#forces-d3-force)\n* [Number Formats](#number-formats-d3-format)\n* [Geographies](#geographies-d3-geo) ([Paths](#paths), [Projections](#projections), [Spherical Math](#spherical-math), [Spherical Shapes](#spherical-shapes), [Streams](#streams), [Transforms](#transforms))\n* [Hierarchies](#hierarchies-d3-hierarchy)\n* [Interpolators](#interpolators-d3-interpolate)\n* [Paths](#paths-d3-path)\n* [Polygons](#polygons-d3-polygon)\n* [Quadtrees](#quadtrees-d3-quadtree)\n* [Queues](#queues-d3-queue)\n* [Random Numbers](#random-numbers-d3-random)\n* [Requests](#requests-d3-request)\n* [Scales](#scales-d3-scale) ([Continuous](#continuous-scales), [Sequential](#sequential-scales), [Quantize](#quantize-scales), [Ordinal](#ordinal-scales))\n* [Selections](#selections-d3-selection) ([Selecting](#selecting-elements), [Modifying](#modifying-elements), [Data](#joining-data), [Events](#handling-events), [Control](#control-flow), [Local Variables](#local-variables), [Namespaces](#namespaces))\n* [Shapes](#shapes-d3-shape) ([Arcs](#arcs), [Pies](#pies), [Lines](#lines), [Areas](#areas), [Curves](#curves), [Links](#links), [Symbols](#symbols), [Stacks](#stacks))\n* [Time Formats](#time-formats-d3-time-format)\n* [Time Intervals](#time-intervals-d3-time)\n* [Timers](#timers-d3-timer)\n* [Transitions](#transitions-d3-transition)\n* [Voronoi Diagrams](#voronoi-diagrams-d3-voronoi)\n* [Zooming](#zooming-d3-zoom)\n\nD3 uses [semantic versioning](http://semver.org/). The current version is exposed as d3.version.\n\n## [Arrays (d3-array)](https://github.com/d3/d3-array)\n\nArray manipulation, ordering, searching, summarizing, etc.\n\n### [Statistics](https://github.com/d3/d3-array/blob/master/README.md#statistics)\n\nMethods for computing basic summary statistics.\n\n* [d3.min](https://github.com/d3/d3-array/blob/master/README.md#min) - compute the minimum value in an array.\n* [d3.max](https://github.com/d3/d3-array/blob/master/README.md#max) - compute the maximum value in an array.\n* [d3.extent](https://github.com/d3/d3-array/blob/master/README.md#extent) - compute the minimum and maximum value in an array.\n* [d3.sum](https://github.com/d3/d3-array/blob/master/README.md#sum) - compute the sum of an array of numbers.\n* [d3.mean](https://github.com/d3/d3-array/blob/master/README.md#mean) - compute the arithmetic mean of an array of numbers.\n* [d3.median](https://github.com/d3/d3-array/blob/master/README.md#median) - compute the median of an array of numbers (the 0.5-quantile).\n* [d3.quantile](https://github.com/d3/d3-array/blob/master/README.md#quantile) - compute a quantile for a sorted array of numbers.\n* [d3.variance](https://github.com/d3/d3-array/blob/master/README.md#variance) - compute the variance of an array of numbers.\n* [d3.deviation](https://github.com/d3/d3-array/blob/master/README.md#deviation) - compute the standard deviation of an array of numbers.\n\n### [Search](https://github.com/d3/d3-array/blob/master/README.md#search)\n\nMethods for searching arrays for a specific element.\n\n* [d3.scan](https://github.com/d3/d3-array/blob/master/README.md#scan) - linear search for an element using a comparator.\n* [d3.bisect](https://github.com/d3/d3-array/blob/master/README.md#bisect) - binary search for a value in a sorted array.\n* [d3.bisectRight](https://github.com/d3/d3-array/blob/master/README.md#bisectRight) - binary search for a value in a sorted array.\n* [d3.bisectLeft](https://github.com/d3/d3-array/blob/master/README.md#bisectLeft) - binary search for a value in a sorted array.\n* [d3.bisector](https://github.com/d3/d3-array/blob/master/README.md#bisector) - bisect using an accessor or comparator.\n* [*bisector*.left](https://github.com/d3/d3-array/blob/master/README.md#bisector_left) - bisectLeft, with the given comparator.\n* [*bisector*.right](https://github.com/d3/d3-array/blob/master/README.md#bisector_right) - bisectRight, with the given comparator.\n* [d3.ascending](https://github.com/d3/d3-array/blob/master/README.md#ascending) - compute the natural order of two values.\n* [d3.descending](https://github.com/d3/d3-array/blob/master/README.md#descending) - compute the natural order of two values.\n\n### [Transformations](https://github.com/d3/d3-array/blob/master/README.md#transformations)\n\nMethods for transforming arrays and for generating new arrays.\n\n* [d3.cross](https://github.com/d3/d3-array/blob/master/README.md#cross) - compute the Cartesian product of two arrays.\n* [d3.merge](https://github.com/d3/d3-array/blob/master/README.md#merge) - merge multiple arrays into one array.\n* [d3.pairs](https://github.com/d3/d3-array/blob/master/README.md#pairs) - create an array of adjacent pairs of elements.\n* [d3.permute](https://github.com/d3/d3-array/blob/master/README.md#permute) - reorder an array of elements according to an array of indexes.\n* [d3.shuffle](https://github.com/d3/d3-array/blob/master/README.md#shuffle) - randomize the order of an array.\n* [d3.ticks](https://github.com/d3/d3-array/blob/master/README.md#ticks) - generate representative values from a numeric interval.\n* [d3.tickIncrement](https://github.com/d3/d3-array/blob/master/README.md#tickIncrement) - generate representative values from a numeric interval.\n* [d3.tickStep](https://github.com/d3/d3-array/blob/master/README.md#tickStep) - generate representative values from a numeric interval.\n* [d3.range](https://github.com/d3/d3-array/blob/master/README.md#range) - generate a range of numeric values.\n* [d3.transpose](https://github.com/d3/d3-array/blob/master/README.md#transpose) - transpose an array of arrays.\n* [d3.zip](https://github.com/d3/d3-array/blob/master/README.md#zip) - transpose a variable number of arrays.\n\n### [Histograms](https://github.com/d3/d3-array/blob/master/README.md#histograms)\n\nBin discrete samples into continuous, non-overlapping intervals.\n\n* [d3.histogram](https://github.com/d3/d3-array/blob/master/README.md#histogram) - create a new histogram generator.\n* [*histogram*](https://github.com/d3/d3-array/blob/master/README.md#_histogram) - compute the histogram for the given array of samples.\n* [*histogram*.value](https://github.com/d3/d3-array/blob/master/README.md#histogram_value) - specify a value accessor for each sample.\n* [*histogram*.domain](https://github.com/d3/d3-array/blob/master/README.md#histogram_domain) - specify the interval of observable values.\n* [*histogram*.thresholds](https://github.com/d3/d3-array/blob/master/README.md#histogram_thresholds) - specify how values are divided into bins.\n* [d3.thresholdFreedmanDiaconis](https://github.com/d3/d3-array/blob/master/README.md#thresholdFreedmanDiaconis) - the Freedman–Diaconis binning rule.\n* [d3.thresholdScott](https://github.com/d3/d3-array/blob/master/README.md#thresholdScott) - Scott’s normal reference binning rule.\n* [d3.thresholdSturges](https://github.com/d3/d3-array/blob/master/README.md#thresholdSturges) - Sturges’ binning formula.\n\n## [Axes (d3-axis)](https://github.com/d3/d3-axis)\n\nHuman-readable reference marks for scales.\n\n* [d3.axisTop](https://github.com/d3/d3-axis/blob/master/README.md#axisTop) - create a new top-oriented axis generator.\n* [d3.axisRight](https://github.com/d3/d3-axis/blob/master/README.md#axisRight) - create a new right-oriented axis generator.\n* [d3.axisBottom](https://github.com/d3/d3-axis/blob/master/README.md#axisBottom) - create a new bottom-oriented axis generator.\n* [d3.axisLeft](https://github.com/d3/d3-axis/blob/master/README.md#axisLeft) - create a new left-oriented axis generator.\n* [*axis*](https://github.com/d3/d3-axis/blob/master/README.md#_axis) - generate an axis for the given selection.\n* [*axis*.scale](https://github.com/d3/d3-axis/blob/master/README.md#axis_scale) - set the scale.\n* [*axis*.ticks](https://github.com/d3/d3-axis/blob/master/README.md#axis_ticks) - customize how ticks are generated and formatted.\n* [*axis*.tickArguments](https://github.com/d3/d3-axis/blob/master/README.md#axis_tickArguments) - customize how ticks are generated and formatted.\n* [*axis*.tickValues](https://github.com/d3/d3-axis/blob/master/README.md#axis_tickValues) - set the tick values explicitly.\n* [*axis*.tickFormat](https://github.com/d3/d3-axis/blob/master/README.md#axis_tickFormat) - set the tick format explicitly.\n* [*axis*.tickSize](https://github.com/d3/d3-axis/blob/master/README.md#axis_tickSize) - set the size of the ticks.\n* [*axis*.tickSizeInner](https://github.com/d3/d3-axis/blob/master/README.md#axis_tickSizeInner) - set the size of inner ticks.\n* [*axis*.tickSizeOuter](https://github.com/d3/d3-axis/blob/master/README.md#axis_tickSizeOuter) - set the size of outer (extent) ticks.\n* [*axis*.tickPadding](https://github.com/d3/d3-axis/blob/master/README.md#axis_tickPadding) - set the padding between ticks and labels.\n\n## [Brushes (d3-brush)](https://github.com/d3/d3-brush)\n\nSelect a one- or two-dimensional region using the mouse or touch.\n\n* [d3.brush](https://github.com/d3/d3-brush/blob/master/README.md#brush) - create a new two-dimensional brush.\n* [d3.brushX](https://github.com/d3/d3-brush/blob/master/README.md#brushX) - create a brush along the *x*-dimension.\n* [d3.brushY](https://github.com/d3/d3-brush/blob/master/README.md#brushY) - create a brush along the *y*-dimension.\n* [*brush*](https://github.com/d3/d3-brush/blob/master/README.md#_brush) - apply the brush to a selection.\n* [*brush*.move](https://github.com/d3/d3-brush/blob/master/README.md#brush_move) - move the brush selection.\n* [*brush*.extent](https://github.com/d3/d3-brush/blob/master/README.md#brush_extent) - define the brushable region.\n* [*brush*.filter](https://github.com/d3/d3-brush/blob/master/README.md#brush_filter) - control which input events initiate brushing.\n* [*brush*.handleSize](https://github.com/d3/d3-brush/blob/master/README.md#brush_handleSize) - set the size of the brush handles.\n* [*brush*.on](https://github.com/d3/d3-brush/blob/master/README.md#brush_on) - listen for brush events.\n* [d3.brushSelection](https://github.com/d3/d3-brush/blob/master/README.md#brushSelection) - get the brush selection for a given node.\n\n## [Chords (d3-chord)](https://github.com/d3/d3-chord)\n\n* [d3.chord](https://github.com/d3/d3-chord/blob/master/README.md#chord) - create a new chord layout.\n* [*chord*](https://github.com/d3/d3-chord/blob/master/README.md#_chord) - compute the layout for the given matrix.\n* [*chord*.padAngle](https://github.com/d3/d3-chord/blob/master/README.md#chord_padAngle) - set the padding between adjacent groups.\n* [*chord*.sortGroups](https://github.com/d3/d3-chord/blob/master/README.md#chord_sortGroups) - define the group order.\n* [*chord*.sortSubgroups](https://github.com/d3/d3-chord/blob/master/README.md#chord_sortSubgroups) - define the source and target order within groups.\n* [*chord*.sortChords](https://github.com/d3/d3-chord/blob/master/README.md#chord_sortChords) - define the chord order across groups.\n* [d3.ribbon](https://github.com/d3/d3-chord/blob/master/README.md#ribbon) - create a ribbon shape generator.\n* [*ribbon*](https://github.com/d3/d3-chord/blob/master/README.md#_ribbon) - generate a ribbon shape.\n* [*ribbon*.source](https://github.com/d3/d3-chord/blob/master/README.md#ribbon_source) - set the source accessor.\n* [*ribbon*.target](https://github.com/d3/d3-chord/blob/master/README.md#ribbon_target) - set the target accessor.\n* [*ribbon*.radius](https://github.com/d3/d3-chord/blob/master/README.md#ribbon_radius) - set the ribbon source or target radius.\n* [*ribbon*.startAngle](https://github.com/d3/d3-chord/blob/master/README.md#ribbon_startAngle) - set the ribbon source or target start angle.\n* [*ribbon*.endAngle](https://github.com/d3/d3-chord/blob/master/README.md#ribbon_endAngle) - set the ribbon source or target end angle.\n* [*ribbon*.context](https://github.com/d3/d3-chord/blob/master/README.md#ribbon_context) - set the render context.\n\n## [Collections (d3-collection)](https://github.com/d3/d3-collection)\n\nHandy data structures for elements keyed by string.\n\n### [Objects](https://github.com/d3/d3-collection/blob/master/README.md#objects)\n\nMethods for converting associative arrays (objects) to arrays.\n\n* [d3.keys](https://github.com/d3/d3-collection/blob/master/README.md#keys) - list the keys of an associative array.\n* [d3.values](https://github.com/d3/d3-collection/blob/master/README.md#values) - list the values of an associated array.\n* [d3.entries](https://github.com/d3/d3-collection/blob/master/README.md#entries) - list the key-value entries of an associative array.\n\n### [Maps](https://github.com/d3/d3-collection/blob/master/README.md#maps)\n\nLike ES6 Map, but with string keys and a few other differences.\n\n* [d3.map](https://github.com/d3/d3-collection/blob/master/README.md#map) - create a new, empty map.\n* [*map*.has](https://github.com/d3/d3-collection/blob/master/README.md#map_has) - returns true if the map contains the given key.\n* [*map*.get](https://github.com/d3/d3-collection/blob/master/README.md#map_get) - get the value for the given key.\n* [*map*.set](https://github.com/d3/d3-collection/blob/master/README.md#map_set) - set the value for the given key.\n* [*map*.remove](https://github.com/d3/d3-collection/blob/master/README.md#map_remove) - remove the entry for given key.\n* [*map*.clear](https://github.com/d3/d3-collection/blob/master/README.md#map_clear) - remove all entries.\n* [*map*.keys](https://github.com/d3/d3-collection/blob/master/README.md#map_keys) - get the array of keys.\n* [*map*.values](https://github.com/d3/d3-collection/blob/master/README.md#map_values) - get the array of values.\n* [*map*.entries](https://github.com/d3/d3-collection/blob/master/README.md#map_entries) - get the array of entries (key-values objects).\n* [*map*.each](https://github.com/d3/d3-collection/blob/master/README.md#map_each) - call a function for each entry.\n* [*map*.empty](https://github.com/d3/d3-collection/blob/master/README.md#map_empty) - returns false if the map has at least one entry.\n* [*map*.size](https://github.com/d3/d3-collection/blob/master/README.md#map_size) - compute the number of entries.\n\n### [Sets](https://github.com/d3/d3-collection/blob/master/README.md#sets)\n\nLike ES6 Set, but with string keys and a few other differences.\n\n* [d3.set](https://github.com/d3/d3-collection/blob/master/README.md#set) - create a new, empty set.\n* [*set*.has](https://github.com/d3/d3-collection/blob/master/README.md#set_has) - returns true if the set contains the given value.\n* [*set*.add](https://github.com/d3/d3-collection/blob/master/README.md#set_add) - add the given value.\n* [*set*.remove](https://github.com/d3/d3-collection/blob/master/README.md#set_remove) - remove the given value.\n* [*set*.clear](https://github.com/d3/d3-collection/blob/master/README.md#set_clear) - remove all values.\n* [*set*.values](https://github.com/d3/d3-collection/blob/master/README.md#set_values) - get the array of values.\n* [*set*.each](https://github.com/d3/d3-collection/blob/master/README.md#set_each) - call a function for each value.\n* [*set*.empty](https://github.com/d3/d3-collection/blob/master/README.md#set_empty) - returns true if the set has at least one value.\n* [*set*.size](https://github.com/d3/d3-collection/blob/master/README.md#set_size) - compute the number of values.\n\n### [Nests](https://github.com/d3/d3-collection/blob/master/README.md#nests)\n\nGroup data into arbitrary hierarchies.\n\n* [d3.nest](https://github.com/d3/d3-collection/blob/master/README.md#nest) - create a new nest generator.\n* [*nest*.key](https://github.com/d3/d3-collection/blob/master/README.md#nest_key) - add a level to the nest hierarchy.\n* [*nest*.sortKeys](https://github.com/d3/d3-collection/blob/master/README.md#nest_sortKeys) - sort the current nest level by key.\n* [*nest*.sortValues](https://github.com/d3/d3-collection/blob/master/README.md#nest_sortValues) - sort the leaf nest level by value.\n* [*nest*.rollup](https://github.com/d3/d3-collection/blob/master/README.md#nest_rollup) - specify a rollup function for leaf values.\n* [*nest*.map](https://github.com/d3/d3-collection/blob/master/README.md#nest_map) - generate the nest, returning a map.\n* [*nest*.object](https://github.com/d3/d3-collection/blob/master/README.md#nest_object) - generate the nest, returning an associative array.\n* [*nest*.entries](https://github.com/d3/d3-collection/blob/master/README.md#nest_entries) - generate the nest, returning an array of key-values tuples.\n\n## [Colors (d3-color)](https://github.com/d3/d3-color)\n\nColor manipulation and color space conversion.\n\n* [d3.color](https://github.com/d3/d3-color/blob/master/README.md#color) - parse the given CSS color specifier.\n* [*color*.rgb](https://github.com/d3/d3-color/blob/master/README.md#color_rgb) - compute the RGB equivalent of this color.\n* [*color*.brighter](https://github.com/d3/d3-color/blob/master/README.md#color_brighter) - create a brighter copy of this color.\n* [*color*.darker](https://github.com/d3/d3-color/blob/master/README.md#color_darker) - create a darker copy of this color.\n* [*color*.displayable](https://github.com/d3/d3-color/blob/master/README.md#color_displayable) - returns true if the color is displayable on standard hardware.\n* [*color*.toString](https://github.com/d3/d3-color/blob/master/README.md#color_toString) - format the color as an RGB hexadecimal string.\n* [d3.rgb](https://github.com/d3/d3-color/blob/master/README.md#rgb) - create a new RGB color.\n* [d3.hsl](https://github.com/d3/d3-color/blob/master/README.md#hsl) - create a new HSL color.\n* [d3.lab](https://github.com/d3/d3-color/blob/master/README.md#lab) - create a new Lab color.\n* [d3.hcl](https://github.com/d3/d3-color/blob/master/README.md#hcl) - create a new HCL color.\n* [d3.cubehelix](https://github.com/d3/d3-color/blob/master/README.md#cubehelix) - create a new Cubehelix color.\n\n## [Dispatches (d3-dispatch)](https://github.com/d3/d3-dispatch)\n\nSeparate concerns using named callbacks.\n\n* [d3.dispatch](https://github.com/d3/d3-dispatch/blob/master/README.md#dispatch) - create a custom event dispatcher.\n* [*dispatch*.on](https://github.com/d3/d3-dispatch/blob/master/README.md#dispatch_on) - register or unregister an event listener.\n* [*dispatch*.copy](https://github.com/d3/d3-dispatch/blob/master/README.md#dispatch_copy) - create a copy of a dispatcher.\n* [*dispatch*.*call*](https://github.com/d3/d3-dispatch/blob/master/README.md#dispatch_call) - dispatch an event to registered listeners.\n* [*dispatch*.*apply*](https://github.com/d3/d3-dispatch/blob/master/README.md#dispatch_apply) - dispatch an event to registered listeners.\n\n## [Dragging (d3-drag)](https://github.com/d3/d3-drag)\n\nDrag and drop SVG, HTML or Canvas using mouse or touch input.\n\n* [d3.drag](https://github.com/d3/d3-drag/blob/master/README.md#drag) - create a drag behavior.\n* [*drag*](https://github.com/d3/d3-drag/blob/master/README.md#_drag) - apply the drag behavior to a selection.\n* [*drag*.container](https://github.com/d3/d3-drag/blob/master/README.md#drag_container) - set the coordinate system.\n* [*drag*.filter](https://github.com/d3/d3-drag/blob/master/README.md#drag_filter) - ignore some initiating input events.\n* [*drag*.subject](https://github.com/d3/d3-drag/blob/master/README.md#drag_subject) - set the thing being dragged.\n* [*drag*.clickDistance](https://github.com/d3/d3-drag/blob/master/README.md#drag_clickDistance) - set the click distance threshold.\n* [*drag*.on](https://github.com/d3/d3-drag/blob/master/README.md#drag_on) - listen for drag events.\n* [*event*.on](https://github.com/d3/d3-drag/blob/master/README.md#event_on) - listen for drag events on the current gesture.\n* [d3.dragDisable](https://github.com/d3/d3-drag/blob/master/README.md#dragDisable) -\n* [d3.dragEnable](https://github.com/d3/d3-drag/blob/master/README.md#dragEnable) -\n\n## [Delimiter-Separated Values (d3-dsv)](https://github.com/d3/d3-dsv)\n\nParse and format delimiter-separated values, most commonly CSV and TSV.\n\n* [d3.dsvFormat](https://github.com/d3/d3-dsv/blob/master/README.md#dsvFormat) - create a new parser and formatter for the given delimiter.\n* [*dsv*.parse](https://github.com/d3/d3-dsv/blob/master/README.md#dsv_parse) - parse the given string, returning an array of objects.\n* [*dsv*.parseRows](https://github.com/d3/d3-dsv/blob/master/README.md#dsv_parseRows) - parse the given string, returning an array of rows.\n* [*dsv*.format](https://github.com/d3/d3-dsv/blob/master/README.md#dsv_format) - format the given array of objects.\n* [*dsv*.formatRows](https://github.com/d3/d3-dsv/blob/master/README.md#dsv_formatRows) - format the given array of rows.\n* [d3.csvParse](https://github.com/d3/d3-dsv/blob/master/README.md#csvParse) - parse the given CSV string, returning an array of objects.\n* [d3.csvParseRows](https://github.com/d3/d3-dsv/blob/master/README.md#csvParseRows) - parse the given CSV string, returning an array of rows.\n* [d3.csvFormat](https://github.com/d3/d3-dsv/blob/master/README.md#csvFormat) - format the given array of objects as CSV.\n* [d3.csvFormatRows](https://github.com/d3/d3-dsv/blob/master/README.md#csvFormatRows) - format the given array of rows as CSV.\n* [d3.tsvParse](https://github.com/d3/d3-dsv/blob/master/README.md#tsvParse) - parse the given TSV string, returning an array of objects.\n* [d3.tsvParseRows](https://github.com/d3/d3-dsv/blob/master/README.md#tsvParseRows) - parse the given TSV string, returning an array of rows.\n* [d3.tsvFormat](https://github.com/d3/d3-dsv/blob/master/README.md#tsvFormat) - format the given array of objects as TSV.\n* [d3.tsvFormatRows](https://github.com/d3/d3-dsv/blob/master/README.md#tsvFormatRows) - format the given array of rows as TSV.\n\n## [Easings (d3-ease)](https://github.com/d3/d3-ease)\n\nEasing functions for smooth animation.\n\n* [*ease*](https://github.com/d3/d3-ease/blob/master/README.md#_ease) - ease the given normalized time.\n* [d3.easeLinear](https://github.com/d3/d3-ease/blob/master/README.md#easeLinear) - linear easing; the identity function.\n* [d3.easePolyIn](https://github.com/d3/d3-ease/blob/master/README.md#easePolyIn) - polynomial easing; raises time to the given power.\n* [d3.easePolyOut](https://github.com/d3/d3-ease/blob/master/README.md#easePolyOut) - reverse polynomial easing.\n* [d3.easePolyInOut](https://github.com/d3/d3-ease/blob/master/README.md#easePolyInOut) - symmetric polynomial easing.\n* [*poly*.exponent](https://github.com/d3/d3-ease/blob/master/README.md#poly_exponent) - specify the polynomial exponent.\n* [d3.easeQuad](https://github.com/d3/d3-ease/blob/master/README.md#easeQuad) - an alias for easeQuadInOut.\n* [d3.easeQuadIn](https://github.com/d3/d3-ease/blob/master/README.md#easeQuadIn) - quadratic easing; squares time.\n* [d3.easeQuadOut](https://github.com/d3/d3-ease/blob/master/README.md#easeQuadOut) - reverse quadratic easing.\n* [d3.easeQuadInOut](https://github.com/d3/d3-ease/blob/master/README.md#easeQuadInOut) - symmetric quadratic easing.\n* [d3.easeCubic](https://github.com/d3/d3-ease/blob/master/README.md#easeCubic) - an alias for easeCubicInOut.\n* [d3.easeCubicIn](https://github.com/d3/d3-ease/blob/master/README.md#easeCubicIn) - cubic easing; cubes time.\n* [d3.easeCubicOut](https://github.com/d3/d3-ease/blob/master/README.md#easeCubicOut) - reverse cubic easing.\n* [d3.easeCubicInOut](https://github.com/d3/d3-ease/blob/master/README.md#easeCubicInOut) - symmetric cubic easing.\n* [d3.easeSin](https://github.com/d3/d3-ease/blob/master/README.md#easeSin) - an alias for easeSinInOut.\n* [d3.easeSinIn](https://github.com/d3/d3-ease/blob/master/README.md#easeSinIn) - sinusoidal easing.\n* [d3.easeSinOut](https://github.com/d3/d3-ease/blob/master/README.md#easeSinOut) - reverse sinusoidal easing.\n* [d3.easeSinInOut](https://github.com/d3/d3-ease/blob/master/README.md#easeSinInOut) - symmetric sinusoidal easing.\n* [d3.easeExp](https://github.com/d3/d3-ease/blob/master/README.md#easeExp) - an alias for easeExpInOut.\n* [d3.easeExpIn](https://github.com/d3/d3-ease/blob/master/README.md#easeExpIn) - exponential easing.\n* [d3.easeExpOut](https://github.com/d3/d3-ease/blob/master/README.md#easeExpOut) - reverse exponential easing.\n* [d3.easeExpInOut](https://github.com/d3/d3-ease/blob/master/README.md#easeExpInOut) - symmetric exponential easing.\n* [d3.easeCircle](https://github.com/d3/d3-ease/blob/master/README.md#easeCircle) - an alias for easeCircleInOut.\n* [d3.easeCircleIn](https://github.com/d3/d3-ease/blob/master/README.md#easeCircleIn) - circular easing.\n* [d3.easeCircleOut](https://github.com/d3/d3-ease/blob/master/README.md#easeCircleOut) - reverse circular easing.\n* [d3.easeCircleInOut](https://github.com/d3/d3-ease/blob/master/README.md#easeCircleInOut) - symmetric circular easing.\n* [d3.easeElastic](https://github.com/d3/d3-ease/blob/master/README.md#easeElastic) - an alias for easeElasticOut.\n* [d3.easeElasticIn](https://github.com/d3/d3-ease/blob/master/README.md#easeElasticIn) - elastic easing, like a rubber band.\n* [d3.easeElasticOut](https://github.com/d3/d3-ease/blob/master/README.md#easeElasticOut) - reverse elastic easing.\n* [d3.easeElasticInOut](https://github.com/d3/d3-ease/blob/master/README.md#easeElasticInOut) - symmetric elastic easing.\n* [*elastic*.amplitude](https://github.com/d3/d3-ease/blob/master/README.md#elastic_amplitude) - specify the elastic amplitude.\n* [*elastic*.period](https://github.com/d3/d3-ease/blob/master/README.md#elastic_period) - specify the elastic period.\n* [d3.easeBack](https://github.com/d3/d3-ease/blob/master/README.md#easeBack) - an alias for easeBackInOut.\n* [d3.easeBackIn](https://github.com/d3/d3-ease/blob/master/README.md#easeBackIn) - anticipatory easing, like a dancer bending his knees before jumping.\n* [d3.easeBackOut](https://github.com/d3/d3-ease/blob/master/README.md#easeBackOut) - reverse anticipatory easing.\n* [d3.easeBackInOut](https://github.com/d3/d3-ease/blob/master/README.md#easeBackInOut) - symmetric anticipatory easing.\n* [*back*.overshoot](https://github.com/d3/d3-ease/blob/master/README.md#back_overshoot) - specify the amount of overshoot.\n* [d3.easeBounce](https://github.com/d3/d3-ease/blob/master/README.md#easeBounce) - an alias for easeBounceOut.\n* [d3.easeBounceIn](https://github.com/d3/d3-ease/blob/master/README.md#easeBounceIn) - bounce easing, like a rubber ball.\n* [d3.easeBounceOut](https://github.com/d3/d3-ease/blob/master/README.md#easeBounceOut) - reverse bounce easing.\n* [d3.easeBounceInOut](https://github.com/d3/d3-ease/blob/master/README.md#easeBounceInOut) - symmetric bounce easing.\n\n## [Forces (d3-force)](https://github.com/d3/d3-force)\n\nForce-directed graph layout using velocity Verlet integration.\n\n* [d3.forceSimulation](https://github.com/d3/d3-force/blob/master/README.md#forceSimulation) - create a new force simulation.\n* [*simulation*.restart](https://github.com/d3/d3-force/blob/master/README.md#simulation_restart) - reheat and restart the simulation’s timer.\n* [*simulation*.stop](https://github.com/d3/d3-force/blob/master/README.md#simulation_stop) - stop the simulation’s timer.\n* [*simulation*.tick](https://github.com/d3/d3-force/blob/master/README.md#simulation_tick) - advance the simulation one step.\n* [*simulation*.nodes](https://github.com/d3/d3-force/blob/master/README.md#simulation_nodes) - set the simulation’s nodes.\n* [*simulation*.alpha](https://github.com/d3/d3-force/blob/master/README.md#simulation_alpha) - set the current alpha.\n* [*simulation*.alphaMin](https://github.com/d3/d3-force/blob/master/README.md#simulation_alphaMin) - set the minimum alpha threshold.\n* [*simulation*.alphaDecay](https://github.com/d3/d3-force/blob/master/README.md#simulation_alphaDecay) - set the alpha exponential decay rate.\n* [*simulation*.alphaTarget](https://github.com/d3/d3-force/blob/master/README.md#simulation_alphaTarget) - set the target alpha.\n* [*simulation*.velocityDecay](https://github.com/d3/d3-force/blob/master/README.md#simulation_velocityDecay) - set the velocity decay rate.\n* [*simulation*.force](https://github.com/d3/d3-force/blob/master/README.md#simulation_force) - add or remove a force.\n* [*simulation*.find](https://github.com/d3/d3-force/blob/master/README.md#simulation_find) - find the closest node to the given position.\n* [*simulation*.on](https://github.com/d3/d3-force/blob/master/README.md#simulation_on) - add or remove an event listener.\n* [*force*](https://github.com/d3/d3-force/blob/master/README.md#_force) - apply the force.\n* [*force*.initialize](https://github.com/d3/d3-force/blob/master/README.md#force_initialize) - initialize the force with the given nodes.\n* [d3.forceCenter](https://github.com/d3/d3-force/blob/master/README.md#forceCenter) - create a centering force.\n* [*center*.x](https://github.com/d3/d3-force/blob/master/README.md#center_x) - set the center *x*-coordinate.\n* [*center*.y](https://github.com/d3/d3-force/blob/master/README.md#center_y) - set the center *y*-coordinate.\n* [d3.forceCollide](https://github.com/d3/d3-force/blob/master/README.md#forceCollide) - create a circle collision force.\n* [*collide*.radius](https://github.com/d3/d3-force/blob/master/README.md#collide_radius) - set the circle radius.\n* [*collide*.strength](https://github.com/d3/d3-force/blob/master/README.md#collide_strength) - set the collision resolution strength.\n* [*collide*.iterations](https://github.com/d3/d3-force/blob/master/README.md#collide_iterations) - set the number of iterations.\n* [d3.forceLink](https://github.com/d3/d3-force/blob/master/README.md#forceLink) - create a link force.\n* [*link*.links](https://github.com/d3/d3-force/blob/master/README.md#link_links) - set the array of links.\n* [*link*.id](https://github.com/d3/d3-force/blob/master/README.md#link_id) - link nodes by numeric index or string identifier.\n* [*link*.distance](https://github.com/d3/d3-force/blob/master/README.md#link_distance) - set the link distance.\n* [*link*.strength](https://github.com/d3/d3-force/blob/master/README.md#link_strength) - set the link strength.\n* [*link*.iterations](https://github.com/d3/d3-force/blob/master/README.md#link_iterations) - set the number of iterations.\n* [d3.forceManyBody](https://github.com/d3/d3-force/blob/master/README.md#forceManyBody) - create a many-body force.\n* [*manyBody*.strength](https://github.com/d3/d3-force/blob/master/README.md#manyBody_strength) - set the force strength.\n* [*manyBody*.theta](https://github.com/d3/d3-force/blob/master/README.md#manyBody_theta) - set the Barnes–Hut approximation accuracy.\n* [*manyBody*.distanceMin](https://github.com/d3/d3-force/blob/master/README.md#manyBody_distanceMin) - limit the force when nodes are close.\n* [*manyBody*.distanceMax](https://github.com/d3/d3-force/blob/master/README.md#manyBody_distanceMax) - limit the force when nodes are far.\n* [d3.forceX](https://github.com/d3/d3-force/blob/master/README.md#forceX) - create an *x*-positioning force.\n* [*x*.strength](https://github.com/d3/d3-force/blob/master/README.md#x_strength) - set the force strength.\n* [*x*.x](https://github.com/d3/d3-force/blob/master/README.md#x_x) - set the target *x*-coordinate.\n* [d3.forceY](https://github.com/d3/d3-force/blob/master/README.md#forceY) - create an *y*-positioning force.\n* [*y*.strength](https://github.com/d3/d3-force/blob/master/README.md#y_strength) - set the force strength.\n* [*y*.y](https://github.com/d3/d3-force/blob/master/README.md#y_y) - set the target *y*-coordinate.\n\n## [Number Formats (d3-format)](https://github.com/d3/d3-format)\n\nFormat numbers for human consumption.\n\n* [d3.format](https://github.com/d3/d3-format/blob/master/README.md#format) - alias for *locale*.format on the default locale.\n* [d3.formatPrefix](https://github.com/d3/d3-format/blob/master/README.md#formatPrefix) - alias for *locale*.formatPrefix on the default locale.\n* [d3.formatSpecifier](https://github.com/d3/d3-format/blob/master/README.md#formatSpecifier) - parse a number format specifier.\n* [d3.formatLocale](https://github.com/d3/d3-format/blob/master/README.md#formatLocale) - define a custom locale.\n* [d3.formatDefaultLocale](https://github.com/d3/d3-format/blob/master/README.md#formatDefaultLocale) - define the default locale.\n* [*locale*.format](https://github.com/d3/d3-format/blob/master/README.md#locale_format) - create a number format.\n* [*locale*.formatPrefix](https://github.com/d3/d3-format/blob/master/README.md#locale_formatPrefix) - create a SI-prefix number format.\n* [d3.precisionFixed](https://github.com/d3/d3-format/blob/master/README.md#precisionFixed) - compute decimal precision for fixed-point notation.\n* [d3.precisionPrefix](https://github.com/d3/d3-format/blob/master/README.md#precisionPrefix) - compute decimal precision for SI-prefix notation.\n* [d3.precisionRound](https://github.com/d3/d3-format/blob/master/README.md#precisionRound) - compute significant digits for rounded notation.\n\n## [Geographies (d3-geo)](https://github.com/d3/d3-geo)\n\nGeographic projections, shapes and math.\n\n### [Paths](https://github.com/d3/d3-geo/blob/master/README.md#paths)\n\n* [d3.geoPath](https://github.com/d3/d3-geo/blob/master/README.md#geoPath) - create a new geographic path generator.\n* [*path*](https://github.com/d3/d3-geo/blob/master/README.md#_path) - project and render the specified feature.\n* [*path*.area](https://github.com/d3/d3-geo/blob/master/README.md#path_area) - compute the projected planar area of a given feature.\n* [*path*.bounds](https://github.com/d3/d3-geo/blob/master/README.md#path_bounds) - compute the projected planar bounding box of a given feature.\n* [*path*.centroid](https://github.com/d3/d3-geo/blob/master/README.md#path_centroid) - compute the projected planar centroid of a given feature.\n* [*path*.measure](https://github.com/d3/d3-geo/blob/master/README.md#path_measure) - compute the projected planar length of a given feature.\n* [*path*.projection](https://github.com/d3/d3-geo/blob/master/README.md#path_projection) - set the geographic projection.\n* [*path*.context](https://github.com/d3/d3-geo/blob/master/README.md#path_context) - set the render context.\n* [*path*.pointRadius](https://github.com/d3/d3-geo/blob/master/README.md#path_pointRadius) - set the radius to display point features.\n\n### [Projections](https://github.com/d3/d3-geo/blob/master/README.md#projections)\n\n* [*projection*](https://github.com/d3/d3-geo/blob/master/README.md#_projection) - project the specified point from the sphere to the plane.\n* [*projection*.invert](https://github.com/d3/d3-geo/blob/master/README.md#projection_invert) - unproject the specified point from the plane to the sphere.\n* [*projection*.stream](https://github.com/d3/d3-geo/blob/master/README.md#projection_stream) - wrap the specified stream to project geometry.\n* [*projection*.clipAngle](https://github.com/d3/d3-geo/blob/master/README.md#projection_clipAngle) - set the radius of the clip circle.\n* [*projection*.clipExtent](https://github.com/d3/d3-geo/blob/master/README.md#projection_clipExtent) - set the viewport clip extent, in pixels.\n* [*projection*.scale](https://github.com/d3/d3-geo/blob/master/README.md#projection_scale) - set the scale factor.\n* [*projection*.translate](https://github.com/d3/d3-geo/blob/master/README.md#projection_translate) - set the translation offset.\n* [*projection*.fitExtent](https://github.com/d3/d3-geo/blob/master/README.md#projection_fitExtent) - set the scale and translate to fit a GeoJSON object.\n* [*projection*.fitSize](https://github.com/d3/d3-geo/blob/master/README.md#projection_fitSize) - set the scale and translate to fit a GeoJSON object.\n* [*projection*.center](https://github.com/d3/d3-geo/blob/master/README.md#projection_center) - set the center point.\n* [*projection*.rotate](https://github.com/d3/d3-geo/blob/master/README.md#projection_rotate) - set the three-axis spherical rotation angles.\n* [*projection*.precision](https://github.com/d3/d3-geo/blob/master/README.md#projection_precision) - set the precision threshold for adaptive sampling.\n* [d3.geoAlbers](https://github.com/d3/d3-geo/blob/master/README.md#geoAlbers) - the Albers equal-area conic projection.\n* [d3.geoAlbersUsa](https://github.com/d3/d3-geo/blob/master/README.md#geoAlbersUsa) - a composite Albers projection for the United States.\n* [d3.geoAzimuthalEqualArea](https://github.com/d3/d3-geo/blob/master/README.md#geoAzimuthalEqualArea) - the azimuthal equal-area projection.\n* [d3.geoAzimuthalEquidistant](https://github.com/d3/d3-geo/blob/master/README.md#geoAzimuthalEquidistant) - the azimuthal equidistant projection.\n* [d3.geoConicConformal](https://github.com/d3/d3-geo/blob/master/README.md#geoConicConformal) - the conic conformal projection.\n* [d3.geoConicEqualArea](https://github.com/d3/d3-geo/blob/master/README.md#geoConicEqualArea) - the conic equal-area (Albers) projection.\n* [d3.geoConicEquidistant](https://github.com/d3/d3-geo/blob/master/README.md#geoConicEquidistant) - the conic equidistant projection.\n* [*conic*.parallels](https://github.com/d3/d3-geo/blob/master/README.md#conic_parallels) - set the two standard parallels.\n* [d3.geoEquirectangular](https://github.com/d3/d3-geo/blob/master/README.md#geoEquirectangular) - the equirectangular (plate carreé) projection.\n* [d3.geoGnomonic](https://github.com/d3/d3-geo/blob/master/README.md#geoGnomonic) - the gnomonic projection.\n* [d3.geoMercator](https://github.com/d3/d3-geo/blob/master/README.md#geoMercator) - the spherical Mercator projection.\n* [d3.geoOrthographic](https://github.com/d3/d3-geo/blob/master/README.md#geoOrthographic) - the azimuthal orthographic projection.\n* [d3.geoStereographic](https://github.com/d3/d3-geo/blob/master/README.md#geoStereographic) - the azimuthal stereographic projection.\n* [d3.geoTransverseMercator](https://github.com/d3/d3-geo/blob/master/README.md#geoTransverseMercator) - the transverse spherical Mercator projection.\n* [*project*](https://github.com/d3/d3-geo/blob/master/README.md#_project) - project the specified point from the sphere to the plane.\n* [*project*.invert](https://github.com/d3/d3-geo/blob/master/README.md#project_invert) - unproject the specified point from the plane to the sphere.\n* [d3.geoProjection](https://github.com/d3/d3-geo/blob/master/README.md#geoProjection) - create a custom projection.\n* [d3.geoProjectionMutator](https://github.com/d3/d3-geo/blob/master/README.md#geoProjectionMutator) - create a custom configurable projection.\n* [d3.geoAzimuthalEqualAreaRaw](https://github.com/d3/d3-geo/blob/master/README.md#geoAzimuthalEqualAreaRaw) -\n* [d3.geoAzimuthalEquidistantRaw](https://github.com/d3/d3-geo/blob/master/README.md#geoAzimuthalEquidistantRaw) -\n* [d3.geoConicConformalRaw](https://github.com/d3/d3-geo/blob/master/README.md#geoConicConformalRaw) -\n* [d3.geoConicEqualAreaRaw](https://github.com/d3/d3-geo/blob/master/README.md#geoConicEqualAreaRaw) -\n* [d3.geoConicEquidistantRaw](https://github.com/d3/d3-geo/blob/master/README.md#geoConicEquidistantRaw) -\n* [d3.geoEquirectangularRaw](https://github.com/d3/d3-geo/blob/master/README.md#geoEquirectangularRaw) -\n* [d3.geoGnomonicRaw](https://github.com/d3/d3-geo/blob/master/README.md#geoGnomonicRaw) -\n* [d3.geoMercatorRaw](https://github.com/d3/d3-geo/blob/master/README.md#geoMercatorRaw) -\n* [d3.geoOrthographicRaw](https://github.com/d3/d3-geo/blob/master/README.md#geoOrthographicRaw) -\n* [d3.geoStereographicRaw](https://github.com/d3/d3-geo/blob/master/README.md#geoStereographicRaw) -\n* [d3.geoTransverseMercatorRaw](https://github.com/d3/d3-geo/blob/master/README.md#geoTransverseMercatorRaw) -\n\n### [Spherical Math](https://github.com/d3/d3-geo/blob/master/README.md#spherical-math)\n\n* [d3.geoArea](https://github.com/d3/d3-geo/blob/master/README.md#geoArea) - compute the spherical area of a given feature.\n* [d3.geoBounds](https://github.com/d3/d3-geo/blob/master/README.md#geoBounds) - compute the latitude-longitude bounding box for a given feature.\n* [d3.geoCentroid](https://github.com/d3/d3-geo/blob/master/README.md#geoCentroid) - compute the spherical centroid of a given feature.\n* [d3.geoContains](https://github.com/d3/d3-geo/blob/master/README.md#geoContains) - test whether a point is inside a given feature.\n* [d3.geoDistance](https://github.com/d3/d3-geo/blob/master/README.md#geoDistance) - compute the great-arc distance between two points.\n* [d3.geoLength](https://github.com/d3/d3-geo/blob/master/README.md#geoLength) - compute the length of a line string or the perimeter of a polygon.\n* [d3.geoInterpolate](https://github.com/d3/d3-geo/blob/master/README.md#geoInterpolate) - interpolate between two points along a great arc.\n* [d3.geoRotation](https://github.com/d3/d3-geo/blob/master/README.md#geoRotation) - create a rotation function for the specified angles.\n* [*rotation*](https://github.com/d3/d3-geo/blob/master/README.md#_rotation) - rotate the given point around the sphere.\n* [*rotation*.invert](https://github.com/d3/d3-geo/blob/master/README.md#rotation_invert) - unrotate the given point around the sphere.\n\n### [Spherical Shapes](https://github.com/d3/d3-geo/blob/master/README.md#spherical-shapes)\n\n* [d3.geoCircle](https://github.com/d3/d3-geo/blob/master/README.md#geoCircle) - create a circle generator.\n* [*circle*](https://github.com/d3/d3-geo/blob/master/README.md#_circle) - generate a piecewise circle as a Polygon.\n* [*circle*.center](https://github.com/d3/d3-geo/blob/master/README.md#circle_center) - specify the circle center in latitude and longitude.\n* [*circle*.radius](https://github.com/d3/d3-geo/blob/master/README.md#circle_radius) - specify the angular radius in degrees.\n* [*circle*.precision](https://github.com/d3/d3-geo/blob/master/README.md#circle_precision) - specify the precision of the piecewise circle.\n* [d3.geoGraticule](https://github.com/d3/d3-geo/blob/master/README.md#geoGraticule) - create a graticule generator.\n* [*graticule*](https://github.com/d3/d3-geo/blob/master/README.md#_graticule) - generate a MultiLineString of meridians and parallels.\n* [*graticule*.lines](https://github.com/d3/d3-geo/blob/master/README.md#graticule_lines) - generate an array of LineStrings of meridians and parallels.\n* [*graticule*.outline](https://github.com/d3/d3-geo/blob/master/README.md#graticule_outline) - generate a Polygon of the graticule’s extent.\n* [*graticule*.extent](https://github.com/d3/d3-geo/blob/master/README.md#graticule_extent) - get or set the major & minor extents.\n* [*graticule*.extentMajor](https://github.com/d3/d3-geo/blob/master/README.md#graticule_extentMajor) - get or set the major extent.\n* [*graticule*.extentMinor](https://github.com/d3/d3-geo/blob/master/README.md#graticule_extentMinor) - get or set the minor extent.\n* [*graticule*.step](https://github.com/d3/d3-geo/blob/master/README.md#graticule_step) - get or set the major & minor step intervals.\n* [*graticule*.stepMajor](https://github.com/d3/d3-geo/blob/master/README.md#graticule_stepMajor) - get or set the major step intervals.\n* [*graticule*.stepMinor](https://github.com/d3/d3-geo/blob/master/README.md#graticule_stepMinor) - get or set the minor step intervals.\n* [*graticule*.precision](https://github.com/d3/d3-geo/blob/master/README.md#graticule_precision) - get or set the latitudinal precision.\n* [d3.geoGraticule10](https://github.com/d3/d3-geo/blob/master/README.md#geoGraticule10) - generate the default 10° global graticule.\n\n#### [Streams](https://github.com/d3/d3-geo/blob/master/README.md#streams)\n\n* [d3.geoStream](https://github.com/d3/d3-geo/blob/master/README.md#geoStream) - convert a GeoJSON object to a geometry stream.\n* [*stream*.point](https://github.com/d3/d3-geo/blob/master/README.md#stream_point) -\n* [*stream*.lineStart](https://github.com/d3/d3-geo/blob/master/README.md#stream_lineStart) -\n* [*stream*.lineEnd](https://github.com/d3/d3-geo/blob/master/README.md#stream_lineEnd) -\n* [*stream*.polygonStart](https://github.com/d3/d3-geo/blob/master/README.md#stream_polygonStart) -\n* [*stream*.polygonEnd](https://github.com/d3/d3-geo/blob/master/README.md#stream_polygonEnd) -\n* [*stream*.sphere](https://github.com/d3/d3-geo/blob/master/README.md#stream_sphere) -\n\n### [Transforms](https://github.com/d3/d3-geo/blob/master/README.md#transforms)\n\n* [d3.geoIdentity](https://github.com/d3/d3-geo/blob/master/README.md#geoIdentity) - scale, translate or clip planar geometry.\n* [*identity*.reflectX](https://github.com/d3/d3-geo/blob/master/README.md#identity_reflectX) - reflect the *x*-dimension.\n* [*identity*.reflectY](https://github.com/d3/d3-geo/blob/master/README.md#identity_reflectY) - reflect the *y*-dimension.\n* [d3.geoTransform](https://github.com/d3/d3-geo/blob/master/README.md#geoTransform) - define a custom geometry transform.\n\n## [Hierarchies (d3-hierarchy)](https://github.com/d3/d3-hierarchy)\n\nLayout algorithms for visualizing hierarchical data.\n\n* [d3.hierarchy](https://github.com/d3/d3-hierarchy/blob/master/README.md#hierarchy) - constructs a root node from hierarchical data.\n* [*node*.ancestors](https://github.com/d3/d3-hierarchy/blob/master/README.md#node_ancestors) - generate an array of ancestors.\n* [*node*.descendants](https://github.com/d3/d3-hierarchy/blob/master/README.md#node_descendants) - generate an array of descendants.\n* [*node*.leaves](https://github.com/d3/d3-hierarchy/blob/master/README.md#node_leaves) - generate an array of leaves.\n* [*node*.path](https://github.com/d3/d3-hierarchy/blob/master/README.md#node_path) - generate the shortest path to another node.\n* [*node*.links](https://github.com/d3/d3-hierarchy/blob/master/README.md#node_links) - generate an array of links.\n* [*node*.sum](https://github.com/d3/d3-hierarchy/blob/master/README.md#node_sum) - evaluate and aggregate quantitative values.\n* [*node*.sort](https://github.com/d3/d3-hierarchy/blob/master/README.md#node_sort) - sort all descendant siblings.\n* [*node*.count](https://github.com/d3/d3-hierarchy/blob/master/README.md#node_count) - count the number of leaves.\n* [*node*.each](https://github.com/d3/d3-hierarchy/blob/master/README.md#node_each) - breadth-first traversal.\n* [*node*.eachAfter](https://github.com/d3/d3-hierarchy/blob/master/README.md#node_eachAfter) - post-order traversal.\n* [*node*.eachBefore](https://github.com/d3/d3-hierarchy/blob/master/README.md#node_eachBefore) - pre-order traversal.\n* [*node*.copy](https://github.com/d3/d3-hierarchy/blob/master/README.md#node_copy) - copy a hierarchy.\n* [d3.stratify](https://github.com/d3/d3-hierarchy/blob/master/README.md#stratify) - create a new stratify operator.\n* [*stratify*](https://github.com/d3/d3-hierarchy/blob/master/README.md#_stratify) - construct a root node from tabular data.\n* [*stratify*.id](https://github.com/d3/d3-hierarchy/blob/master/README.md#stratify_id) - set the node id accessor.\n* [*stratify*.parentId](https://github.com/d3/d3-hierarchy/blob/master/README.md#stratify_parentId) - set the parent node id accessor.\n* [d3.cluster](https://github.com/d3/d3-hierarchy/blob/master/README.md#cluster) - create a new cluster (dendrogram) layout.\n* [*cluster*](https://github.com/d3/d3-hierarchy/blob/master/README.md#_cluster) - layout the specified hierarchy in a dendrogram.\n* [*cluster*.size](https://github.com/d3/d3-hierarchy/blob/master/README.md#cluster_size) - set the layout size.\n* [*cluster*.nodeSize](https://github.com/d3/d3-hierarchy/blob/master/README.md#cluster_nodeSize) - set the node size.\n* [*cluster*.separation](https://github.com/d3/d3-hierarchy/blob/master/README.md#cluster_separation) - set the separation between leaves.\n* [d3.tree](https://github.com/d3/d3-hierarchy/blob/master/README.md#tree) - create a new tidy tree layout.\n* [*tree*](https://github.com/d3/d3-hierarchy/blob/master/README.md#_tree) - layout the specified hierarchy in a tidy tree.\n* [*tree*.size](https://github.com/d3/d3-hierarchy/blob/master/README.md#tree_size) - set the layout size.\n* [*tree*.nodeSize](https://github.com/d3/d3-hierarchy/blob/master/README.md#tree_nodeSize) - set the node size.\n* [*tree*.separation](https://github.com/d3/d3-hierarchy/blob/master/README.md#tree_separation) - set the separation between nodes.\n* [d3.treemap](https://github.com/d3/d3-hierarchy/blob/master/README.md#treemap) - create a new treemap layout.\n* [*treemap*](https://github.com/d3/d3-hierarchy/blob/master/README.md#_treemap) - layout the specified hierarchy as a treemap.\n* [*treemap*.tile](https://github.com/d3/d3-hierarchy/blob/master/README.md#treemap_tile) - set the tiling method.\n* [*treemap*.size](https://github.com/d3/d3-hierarchy/blob/master/README.md#treemap_size) - set the layout size.\n* [*treemap*.round](https://github.com/d3/d3-hierarchy/blob/master/README.md#treemap_round) - set whether the output coordinates are rounded.\n* [*treemap*.padding](https://github.com/d3/d3-hierarchy/blob/master/README.md#treemap_padding) - set the padding.\n* [*treemap*.paddingInner](https://github.com/d3/d3-hierarchy/blob/master/README.md#treemap_paddingInner) - set the padding between siblings.\n* [*treemap*.paddingOuter](https://github.com/d3/d3-hierarchy/blob/master/README.md#treemap_paddingOuter) - set the padding between parent and children.\n* [*treemap*.paddingTop](https://github.com/d3/d3-hierarchy/blob/master/README.md#treemap_paddingTop) - set the padding between the parent’s top edge and children.\n* [*treemap*.paddingRight](https://github.com/d3/d3-hierarchy/blob/master/README.md#treemap_paddingRight) - set the padding between the parent’s right edge and children.\n* [*treemap*.paddingBottom](https://github.com/d3/d3-hierarchy/blob/master/README.md#treemap_paddingBottom) - set the padding between the parent’s bottom edge and children.\n* [*treemap*.paddingLeft](https://github.com/d3/d3-hierarchy/blob/master/README.md#treemap_paddingLeft) - set the padding between the parent’s left edge and children.\n* [d3.treemapBinary](https://github.com/d3/d3-hierarchy/blob/master/README.md#treemapBinary) - tile using a balanced binary tree.\n* [d3.treemapDice](https://github.com/d3/d3-hierarchy/blob/master/README.md#treemapDice) - tile into a horizontal row.\n* [d3.treemapSlice](https://github.com/d3/d3-hierarchy/blob/master/README.md#treemapSlice) - tile into a vertical column.\n* [d3.treemapSliceDice](https://github.com/d3/d3-hierarchy/blob/master/README.md#treemapSliceDice) - alternate between slicing and dicing.\n* [d3.treemapSquarify](https://github.com/d3/d3-hierarchy/blob/master/README.md#treemapSquarify) - tile using squarified rows per Bruls *et. al.*\n* [d3.treemapResquarify](https://github.com/d3/d3-hierarchy/blob/master/README.md#treemapResquarify) - like d3.treemapSquarify, but performs stable updates.\n* [*squarify*.ratio](https://github.com/d3/d3-hierarchy/blob/master/README.md#squarify_ratio) - set the desired rectangle aspect ratio.\n* [d3.partition](https://github.com/d3/d3-hierarchy/blob/master/README.md#partition) - create a new partition (icicle or sunburst) layout.\n* [*partition*](https://github.com/d3/d3-hierarchy/blob/master/README.md#_partition) - layout the specified hierarchy as a partition diagram.\n* [*partition*.size](https://github.com/d3/d3-hierarchy/blob/master/README.md#partition_size) - set the layout size.\n* [*partition*.round](https://github.com/d3/d3-hierarchy/blob/master/README.md#partition_round) - set whether the output coordinates are rounded.\n* [*partition*.padding](https://github.com/d3/d3-hierarchy/blob/master/README.md#partition_padding) - set the padding.\n* [d3.pack](https://github.com/d3/d3-hierarchy/blob/master/README.md#pack) - create a new circle-packing layout.\n* [*pack*](https://github.com/d3/d3-hierarchy/blob/master/README.md#_pack) - layout the specified hierarchy using circle-packing.\n* [*pack*.radius](https://github.com/d3/d3-hierarchy/blob/master/README.md#pack_radius) - set the radius accessor.\n* [*pack*.size](https://github.com/d3/d3-hierarchy/blob/master/README.md#pack_size) - set the layout size.\n* [*pack*.padding](https://github.com/d3/d3-hierarchy/blob/master/README.md#pack_padding) - set the padding.\n* [d3.packSiblings](https://github.com/d3/d3-hierarchy/blob/master/README.md#packSiblings) - pack the specified array of circles.\n* [d3.packEnclose](https://github.com/d3/d3-hierarchy/blob/master/README.md#packEnclose) - enclose the specified array of circles.\n\n## [Interpolators (d3-interpolate)](https://github.com/d3/d3-interpolate)\n\nInterpolate numbers, colors, strings, arrays, objects, whatever!\n\n* [d3.interpolate](https://github.com/d3/d3-interpolate/blob/master/README.md#interpolate) - interpolate arbitrary values.\n* [d3.interpolateArray](https://github.com/d3/d3-interpolate/blob/master/README.md#interpolateArray) - interpolate arrays of arbitrary values.\n* [d3.interpolateDate](https://github.com/d3/d3-interpolate/blob/master/README.md#interpolateDate) - interpolate dates.\n* [d3.interpolateNumber](https://github.com/d3/d3-interpolate/blob/master/README.md#interpolateNumber) - interpolate numbers.\n* [d3.interpolateObject](https://github.com/d3/d3-interpolate/blob/master/README.md#interpolateObject) - interpolate arbitrary objects.\n* [d3.interpolateRound](https://github.com/d3/d3-interpolate/blob/master/README.md#interpolateRound) - interpolate integers.\n* [d3.interpolateString](https://github.com/d3/d3-interpolate/blob/master/README.md#interpolateString) - interpolate strings with embedded numbers.\n* [d3.interpolateTransformCss](https://github.com/d3/d3-interpolate/blob/master/README.md#interpolateTransformCss) - interpolate 2D CSS transforms.\n* [d3.interpolateTransformSvg](https://github.com/d3/d3-interpolate/blob/master/README.md#interpolateTransformSvg) - interpolate 2D SVG transforms.\n* [d3.interpolateZoom](https://github.com/d3/d3-interpolate/blob/master/README.md#interpolateZoom) - zoom and pan between two views.\n* [d3.interpolateRgb](https://github.com/d3/d3-interpolate/blob/master/README.md#interpolateRgb) - interpolate RGB colors.\n* [d3.interpolateRgbBasis](https://github.com/d3/d3-interpolate/blob/master/README.md#interpolateRgbBasis) - generate a B-spline through a set of colors.\n* [d3.interpolateRgbBasisClosed](https://github.com/d3/d3-interpolate/blob/master/README.md#interpolateRgbBasisClosed) - generate a closed B-spline through a set of colors.\n* [d3.interpolateHsl](https://github.com/d3/d3-interpolate/blob/master/README.md#interpolateHsl) - interpolate HSL colors.\n* [d3.interpolateHslLong](https://github.com/d3/d3-interpolate/blob/master/README.md#interpolateHslLong) - interpolate HSL colors, the long way.\n* [d3.interpolateLab](https://github.com/d3/d3-interpolate/blob/master/README.md#interpolateLab) - interpolate Lab colors.\n* [d3.interpolateHcl](https://github.com/d3/d3-interpolate/blob/master/README.md#interpolateHcl) - interpolate HCL colors.\n* [d3.interpolateHclLong](https://github.com/d3/d3-interpolate/blob/master/README.md#interpolateHclLong) - interpolate HCL colors, the long way.\n* [d3.interpolateCubehelix](https://github.com/d3/d3-interpolate/blob/master/README.md#interpolateCubehelix) - interpolate Cubehelix colors.\n* [d3.interpolateCubehelixLong](https://github.com/d3/d3-interpolate/blob/master/README.md#interpolateCubehelixLong) - interpolate Cubehelix colors, the long way.\n* [*interpolate*.gamma](https://github.com/d3/d3-interpolate/blob/master/README.md#interpolate_gamma) - apply gamma correction during interpolation.\n* [d3.interpolateBasis](https://github.com/d3/d3-interpolate/blob/master/README.md#interpolateBasis) - generate a B-spline through a set of values.\n* [d3.interpolateBasisClosed](https://github.com/d3/d3-interpolate/blob/master/README.md#interpolateBasisClosed) - generate a closed B-spline through a set of values.\n* [d3.quantize](https://github.com/d3/d3-interpolate/blob/master/README.md#quantize) - generate uniformly-spaced samples from an interpolator.\n\n## [Paths (d3-path)](https://github.com/d3/d3-path)\n\nSerialize Canvas path commands to SVG.\n\n* [d3.path](https://github.com/d3/d3-path/blob/master/README.md#path) - create a new path serializer.\n* [*path*.moveTo](https://github.com/d3/d3-path/blob/master/README.md#path_moveTo) - move to the given point.\n* [*path*.closePath](https://github.com/d3/d3-path/blob/master/README.md#path_closePath) - close the current subpath.\n* [*path*.lineTo](https://github.com/d3/d3-path/blob/master/README.md#path_lineTo) - draw a straight line segment.\n* [*path*.quadraticCurveTo](https://github.com/d3/d3-path/blob/master/README.md#path_quadraticCurveTo) - draw a quadratic Bézier segment.\n* [*path*.bezierCurveTo](https://github.com/d3/d3-path/blob/master/README.md#path_bezierCurveTo) - draw a cubic Bézier segment.\n* [*path*.arcTo](https://github.com/d3/d3-path/blob/master/README.md#path_arcTo) - draw a circular arc segment.\n* [*path*.arc](https://github.com/d3/d3-path/blob/master/README.md#path_arc) - draw a circular arc segment.\n* [*path*.rect](https://github.com/d3/d3-path/blob/master/README.md#path_rect) - draw a rectangle.\n* [*path*.toString](https://github.com/d3/d3-path/blob/master/README.md#path_toString) - serialize to an SVG path data string.\n\n## [Polygons (d3-polygon)](https://github.com/d3/d3-polygon)\n\nGeometric operations for two-dimensional polygons.\n\n* [d3.polygonArea](https://github.com/d3/d3-polygon/blob/master/README.md#polygonArea) - compute the area of the given polygon.\n* [d3.polygonCentroid](https://github.com/d3/d3-polygon/blob/master/README.md#polygonCentroid) - compute the centroid of the given polygon.\n* [d3.polygonHull](https://github.com/d3/d3-polygon/blob/master/README.md#polygonHull) - compute the convex hull of the given points.\n* [d3.polygonContains](https://github.com/d3/d3-polygon/blob/master/README.md#polygonContains) - test whether a point is inside a polygon.\n* [d3.polygonLength](https://github.com/d3/d3-polygon/blob/master/README.md#polygonLength) - compute the length of the given polygon’s perimeter.\n\n## [Quadtrees (d3-quadtree)](https://github.com/d3/d3-quadtree)\n\nTwo-dimensional recursive spatial subdivision.\n\n* [d3.quadtree](https://github.com/d3/d3-quadtree/blob/master/README.md#quadtree) - create a new, empty quadtree.\n* [*quadtree*.x](https://github.com/d3/d3-quadtree/blob/master/README.md#quadtree_x) - set the *x* accessor.\n* [*quadtree*.y](https://github.com/d3/d3-quadtree/blob/master/README.md#quadtree_y) - set the *y* accessor.\n* [*quadtree*.add](https://github.com/d3/d3-quadtree/blob/master/README.md#quadtree_add) - add a datum to a quadtree.\n* [*quadtree*.addAll](https://github.com/d3/d3-quadtree/blob/master/README.md#quadtree_addAll) -\n* [*quadtree*.remove](https://github.com/d3/d3-quadtree/blob/master/README.md#quadtree_remove) - remove a datum from a quadtree.\n* [*quadtree*.removeAll](https://github.com/d3/d3-quadtree/blob/master/README.md#quadtree_removeAll) -\n* [*quadtree*.copy](https://github.com/d3/d3-quadtree/blob/master/README.md#quadtree_copy) - create a copy of a quadtree.\n* [*quadtree*.root](https://github.com/d3/d3-quadtree/blob/master/README.md#quadtree_root) - get the quadtree’s root node.\n* [*quadtree*.data](https://github.com/d3/d3-quadtree/blob/master/README.md#quadtree_data) - retrieve all data from the quadtree.\n* [*quadtree*.size](https://github.com/d3/d3-quadtree/blob/master/README.md#quadtree_size) - count the number of data in the quadtree.\n* [*quadtree*.find](https://github.com/d3/d3-quadtree/blob/master/README.md#quadtree_find) - quickly find the closest datum in a quadtree.\n* [*quadtree*.visit](https://github.com/d3/d3-quadtree/blob/master/README.md#quadtree_visit) - selectively visit nodes in a quadtree.\n* [*quadtree*.visitAfter](https://github.com/d3/d3-quadtree/blob/master/README.md#quadtree_visitAfter) - visit all nodes in a quadtree.\n* [*quadtree*.cover](https://github.com/d3/d3-quadtree/blob/master/README.md#quadtree_cover) - extend the quadtree to cover a point.\n* [*quadtree*.extent](https://github.com/d3/d3-quadtree/blob/master/README.md#quadtree_extent) - extend the quadtree to cover an extent.\n\n## [Queues (d3-queue)](https://github.com/d3/d3-queue)\n\nEvaluate asynchronous tasks with configurable concurrency.\n\n* [d3.queue](https://github.com/d3/d3-queue/blob/master/README.md#queue) - manage the concurrent evaluation of asynchronous tasks.\n* [*queue*.defer](https://github.com/d3/d3-queue/blob/master/README.md#queue_defer) - register a task for evaluation.\n* [*queue*.abort](https://github.com/d3/d3-queue/blob/master/README.md#queue_abort) - abort any active tasks and cancel any pending ones.\n* [*queue*.await](https://github.com/d3/d3-queue/blob/master/README.md#queue_await) - register a callback for when tasks complete.\n* [*queue*.awaitAll](https://github.com/d3/d3-queue/blob/master/README.md#queue_awaitAll) - register a callback for when tasks complete.\n\n## [Random Numbers (d3-random)](https://github.com/d3/d3-random)\n\nGenerate random numbers from various distributions.\n\n* [d3.randomUniform](https://github.com/d3/d3-random/blob/master/README.md#randomUniform) - from a uniform distribution.\n* [d3.randomNormal](https://github.com/d3/d3-random/blob/master/README.md#randomNormal) - from a normal distribution.\n* [d3.randomLogNormal](https://github.com/d3/d3-random/blob/master/README.md#randomLogNormal) - from a log-normal distribution.\n* [d3.randomBates](https://github.com/d3/d3-random/blob/master/README.md#randomBates) - from a Bates distribution.\n* [d3.randomIrwinHall](https://github.com/d3/d3-random/blob/master/README.md#randomIrwinHall) - from an Irwin–Hall distribution.\n* [d3.randomExponential](https://github.com/d3/d3-random/blob/master/README.md#randomExponential) - from an exponential distribution.\n* [*random*.source](https://github.com/d3/d3-random/blob/master/README.md#random_source) - set the source of randomness.\n\n## [Requests (d3-request)](https://github.com/d3/d3-request)\n\nA convenient alternative to asynchronous XMLHttpRequest.\n\n* [d3.request](https://github.com/d3/d3-request/blob/master/README.md#request) - make an asynchronous request.\n* [*request*.header](https://github.com/d3/d3-request/blob/master/README.md#request_header) - set a request header.\n* [*request*.user](https://github.com/d3/d3-request/blob/master/README.md#request_user) - set the user for authentication.\n* [*request*.password](https://github.com/d3/d3-request/blob/master/README.md#request_password) - set the password for authentication.\n* [*request*.mimeType](https://github.com/d3/d3-request/blob/master/README.md#request_mimeType) - set the MIME type.\n* [*request*.timeout](https://github.com/d3/d3-request/blob/master/README.md#request_timeout) - set the timeout in milliseconds.\n* [*request*.responseType](https://github.com/d3/d3-request/blob/master/README.md#request_responseType) - set the response type.\n* [*request*.response](https://github.com/d3/d3-request/blob/master/README.md#request_response) - set the response function.\n* [*request*.get](https://github.com/d3/d3-request/blob/master/README.md#request_get) - send a GET request.\n* [*request*.post](https://github.com/d3/d3-request/blob/master/README.md#request_post) - send a POST request.\n* [*request*.send](https://github.com/d3/d3-request/blob/master/README.md#request_send) - set the request.\n* [*request*.abort](https://github.com/d3/d3-request/blob/master/README.md#request_abort) - abort the request.\n* [*request*.on](https://github.com/d3/d3-request/blob/master/README.md#request_on) - listen for a request event.\n* [d3.csv](https://github.com/d3/d3-request/blob/master/README.md#csv) - get a comma-separated values (CSV) file.\n* [d3.html](https://github.com/d3/d3-request/blob/master/README.md#html) - get an HTML file.\n* [d3.json](https://github.com/d3/d3-request/blob/master/README.md#json) - get a JSON file.\n* [d3.text](https://github.com/d3/d3-request/blob/master/README.md#text) - get a plain text file.\n* [d3.tsv](https://github.com/d3/d3-request/blob/master/README.md#tsv) - get a tab-separated values (TSV) file.\n* [d3.xml](https://github.com/d3/d3-request/blob/master/README.md#xml) - get an XML file.\n\n## [Scales (d3-scale)](https://github.com/d3/d3-scale)\n\nEncodings that map abstract data to visual representation.\n\n### [Continuous Scales](https://github.com/d3/d3-scale/blob/master/README.md#continuous-scales)\n\nMap a continuous, quantitative domain to a continuous range.\n\n* [*continuous*](https://github.com/d3/d3-scale/blob/master/README.md#_continuous) - compute the range value corresponding to a given domain value.\n* [*continuous*.invert](https://github.com/d3/d3-scale/blob/master/README.md#continuous_invert) - compute the domain value corresponding to a given range value.\n* [*continuous*.domain](https://github.com/d3/d3-scale/blob/master/README.md#continuous_domain) - set the input domain.\n* [*continuous*.range](https://github.com/d3/d3-scale/blob/master/README.md#continuous_range) - set the output range.\n* [*continuous*.rangeRound](https://github.com/d3/d3-scale/blob/master/README.md#continuous_rangeRound) - set the output range and enable rounding.\n* [*continuous*.clamp](https://github.com/d3/d3-scale/blob/master/README.md#continuous_clamp) - enable clamping to the domain or range.\n* [*continuous*.interpolate](https://github.com/d3/d3-scale/blob/master/README.md#continuous_interpolate) - set the output interpolator.\n* [*continuous*.ticks](https://github.com/d3/d3-scale/blob/master/README.md#continuous_ticks) - compute representative values from the domain.\n* [*continuous*.tickFormat](https://github.com/d3/d3-scale/blob/master/README.md#continuous_tickFormat) - format ticks for human consumption.\n* [*continuous*.nice](https://github.com/d3/d3-scale/blob/master/README.md#continuous_nice) - extend the domain to nice round numbers.\n* [*continuous*.copy](https://github.com/d3/d3-scale/blob/master/README.md#continuous_copy) - create a copy of this scale.\n* [d3.scaleLinear](https://github.com/d3/d3-scale/blob/master/README.md#scaleLinear) - create a quantitative linear scale.\n* [d3.scalePow](https://github.com/d3/d3-scale/blob/master/README.md#scalePow) - create a quantitative power scale.\n* [*pow*](https://github.com/d3/d3-scale/blob/master/README.md#_pow) - compute the range value corresponding to a given domain value.\n* [*pow*.invert](https://github.com/d3/d3-scale/blob/master/README.md#pow_invert) - compute the domain value corresponding to a given range value.\n* [*pow*.exponent](https://github.com/d3/d3-scale/blob/master/README.md#pow_exponent) - set the power exponent.\n* [*pow*.domain](https://github.com/d3/d3-scale/blob/master/README.md#pow_domain) - set the input domain.\n* [*pow*.range](https://github.com/d3/d3-scale/blob/master/README.md#pow_range) - set the output range.\n* [*pow*.rangeRound](https://github.com/d3/d3-scale/blob/master/README.md#pow_rangeRound) - set the output range and enable rounding.\n* [*pow*.clamp](https://github.com/d3/d3-scale/blob/master/README.md#pow_clamp) - enable clamping to the domain or range.\n* [*pow*.interpolate](https://github.com/d3/d3-scale/blob/master/README.md#pow_interpolate) - set the output interpolator.\n* [*pow*.ticks](https://github.com/d3/d3-scale/blob/master/README.md#pow_ticks) - compute representative values from the domain.\n* [*pow*.tickFormat](https://github.com/d3/d3-scale/blob/master/README.md#pow_tickFormat) - format ticks for human consumption.\n* [*pow*.nice](https://github.com/d3/d3-scale/blob/master/README.md#pow_nice) - extend the domain to nice round numbers.\n* [*pow*.copy](https://github.com/d3/d3-scale/blob/master/README.md#pow_copy) - create a copy of this scale.\n* [d3.scaleSqrt](https://github.com/d3/d3-scale/blob/master/README.md#scaleSqrt) - create a quantitative power scale with exponent 0.5.\n* [d3.scaleLog](https://github.com/d3/d3-scale/blob/master/README.md#scaleLog) - create a quantitative logarithmic scale.\n* [*log*](https://github.com/d3/d3-scale/blob/master/README.md#_log) - compute the range value corresponding to a given domain value.\n* [*log*.invert](https://github.com/d3/d3-scale/blob/master/README.md#log_invert) - compute the domain value corresponding to a given range value.\n* [*log*.base](https://github.com/d3/d3-scale/blob/master/README.md#log_base) - set the logarithm base.\n* [*log*.domain](https://github.com/d3/d3-scale/blob/master/README.md#log_domain) - set the input domain.\n* [*log*.range](https://github.com/d3/d3-scale/blob/master/README.md#log_range) - set the output range.\n* [*log*.rangeRound](https://github.com/d3/d3-scale/blob/master/README.md#log_rangeRound) - set the output range and enable rounding.\n* [*log*.clamp](https://github.com/d3/d3-scale/blob/master/README.md#log_clamp) - enable clamping to the domain or range.\n* [*log*.interpolate](https://github.com/d3/d3-scale/blob/master/README.md#log_interpolate) - set the output interpolator.\n* [*log*.ticks](https://github.com/d3/d3-scale/blob/master/README.md#log_ticks) - compute representative values from the domain.\n* [*log*.tickFormat](https://github.com/d3/d3-scale/blob/master/README.md#log_tickFormat) - format ticks for human consumption.\n* [*log*.nice](https://github.com/d3/d3-scale/blob/master/README.md#log_nice) - extend the domain to nice round numbers.\n* [*log*.copy](https://github.com/d3/d3-scale/blob/master/README.md#log_copy) - create a copy of this scale.\n* [d3.scaleIdentity](https://github.com/d3/d3-scale/blob/master/README.md#identity) - create a quantitative identity scale.\n* [d3.scaleTime](https://github.com/d3/d3-scale/blob/master/README.md#scaleTime) - create a linear scale for time.\n* [*time*](https://github.com/d3/d3-scale/blob/master/README.md#_time) - compute the range value corresponding to a given domain value.\n* [*time*.invert](https://github.com/d3/d3-scale/blob/master/README.md#time_invert) - compute the domain value corresponding to a given range value.\n* [*time*.domain](https://github.com/d3/d3-scale/blob/master/README.md#time_domain) - set the input domain.\n* [*time*.range](https://github.com/d3/d3-scale/blob/master/README.md#time_range) - set the output range.\n* [*time*.rangeRound](https://github.com/d3/d3-scale/blob/master/README.md#time_rangeRound) - set the output range and enable rounding.\n* [*time*.clamp](https://github.com/d3/d3-scale/blob/master/README.md#time_clamp) - enable clamping to the domain or range.\n* [*time*.interpolate](https://github.com/d3/d3-scale/blob/master/README.md#time_interpolate) - set the output interpolator.\n* [*time*.ticks](https://github.com/d3/d3-scale/blob/master/README.md#time_ticks) - compute representative values from the domain.\n* [*time*.tickFormat](https://github.com/d3/d3-scale/blob/master/README.md#time_tickFormat) - format ticks for human consumption.\n* [*time*.nice](https://github.com/d3/d3-scale/blob/master/README.md#time_nice) - extend the domain to nice round times.\n* [*time*.copy](https://github.com/d3/d3-scale/blob/master/README.md#time_copy) - create a copy of this scale.\n* [d3.scaleUtc](https://github.com/d3/d3-scale/blob/master/README.md#scaleUtc) - create a linear scale for UTC.\n\n### [Sequential Scales](https://github.com/d3/d3-scale/blob/master/README.md#sequential-scales)\n\nMap a continuous, quantitative domain to a continuous, fixed interpolator.\n\n* [d3.scaleSequential](https://github.com/d3/d3-scale/blob/master/README.md#scaleSequential) - create a sequential scale.\n* [*sequential*.interpolator](https://github.com/d3/d3-scale/blob/master/README.md#sequential_interpolator) - set the scale’s output interpolator.\n* [d3.interpolateViridis](https://github.com/d3/d3-scale/blob/master/README.md#interpolateViridis) - a dark-to-light color scheme.\n* [d3.interpolateInferno](https://github.com/d3/d3-scale/blob/master/README.md#interpolateInferno) - a dark-to-light color scheme.\n* [d3.interpolateMagma](https://github.com/d3/d3-scale/blob/master/README.md#interpolateMagma) - a dark-to-light color scheme.\n* [d3.interpolatePlasma](https://github.com/d3/d3-scale/blob/master/README.md#interpolatePlasma) - a dark-to-light color scheme.\n* [d3.interpolateWarm](https://github.com/d3/d3-scale/blob/master/README.md#interpolateWarm) - a rotating-hue color scheme.\n* [d3.interpolateCool](https://github.com/d3/d3-scale/blob/master/README.md#interpolateCool) - a rotating-hue color scheme.\n* [d3.interpolateRainbow](https://github.com/d3/d3-scale/blob/master/README.md#interpolateRainbow) - a cyclical rotating-hue color scheme.\n* [d3.interpolateCubehelixDefault](https://github.com/d3/d3-scale/blob/master/README.md#interpolateCubehelixDefault) - a dark-to-light, rotating-hue color scheme.\n\n### [Quantize Scales](https://github.com/d3/d3-scale/blob/master/README.md#quantize-scales)\n\nMap a continuous, quantitative domain to a discrete range.\n\n* [d3.scaleQuantize](https://github.com/d3/d3-scale/blob/master/README.md#scaleQuantize) - create a uniform quantizing linear scale.\n* [*quantize*](https://github.com/d3/d3-scale/blob/master/README.md#_quantize) - compute the range value corresponding to a given domain value.\n* [*quantize*.invertExtent](https://github.com/d3/d3-scale/blob/master/README.md#quantize_invertExtent) - compute the domain values corresponding to a given range value.\n* [*quantize*.domain](https://github.com/d3/d3-scale/blob/master/README.md#quantize_domain) - set the input domain.\n* [*quantize*.range](https://github.com/d3/d3-scale/blob/master/README.md#quantize_range) - set the output range.\n* [*quantize*.nice](https://github.com/d3/d3-scale/blob/master/README.md#quantize_nice) - extend the domain to nice round numbers.\n* [*quantize*.ticks](https://github.com/d3/d3-scale/blob/master/README.md#quantize_ticks) - compute representative values from the domain.\n* [*quantize*.tickFormat](https://github.com/d3/d3-scale/blob/master/README.md#quantize_tickFormat) - format ticks for human consumption.\n* [*quantize*.copy](https://github.com/d3/d3-scale/blob/master/README.md#quantize_copy) - create a copy of this scale.\n* [d3.scaleQuantile](https://github.com/d3/d3-scale/blob/master/README.md#scaleQuantile) - create a quantile quantizing linear scale.\n* [*quantile*](https://github.com/d3/d3-scale/blob/master/README.md#_quantile) - compute the range value corresponding to a given domain value.\n* [*quantile*.invertExtent](https://github.com/d3/d3-scale/blob/master/README.md#quantile_invertExtent) - compute the domain values corresponding to a given range value.\n* [*quantile*.domain](https://github.com/d3/d3-scale/blob/master/README.md#quantile_domain) - set the input domain.\n* [*quantile*.range](https://github.com/d3/d3-scale/blob/master/README.md#quantile_range) - set the output range.\n* [*quantile*.quantiles](https://github.com/d3/d3-scale/blob/master/README.md#quantile_quantiles) - get the quantile thresholds.\n* [*quantile*.copy](https://github.com/d3/d3-scale/blob/master/README.md#quantile_copy) - create a copy of this scale.\n* [d3.scaleThreshold](https://github.com/d3/d3-scale/blob/master/README.md#scaleThreshold) - create an arbitrary quantizing linear scale.\n* [*threshold*](https://github.com/d3/d3-scale/blob/master/README.md#_threshold) - compute the range value corresponding to a given domain value.\n* [*threshold*.invertExtent](https://github.com/d3/d3-scale/blob/master/README.md#threshold_invertExtent) - compute the domain values corresponding to a given range value.\n* [*threshold*.domain](https://github.com/d3/d3-scale/blob/master/README.md#threshold_domain) - set the input domain.\n* [*threshold*.range](https://github.com/d3/d3-scale/blob/master/README.md#threshold_range) - set the output range.\n* [*threshold*.copy](https://github.com/d3/d3-scale/blob/master/README.md#threshold_copy) - create a copy of this scale.\n\n### [Ordinal Scales](https://github.com/d3/d3-scale/blob/master/README.md#ordinal-scales)\n\nMap a discrete domain to a discrete range.\n\n* [d3.scaleOrdinal](https://github.com/d3/d3-scale/blob/master/README.md#scaleOrdinal) - create an ordinal scale.\n* [*ordinal*](https://github.com/d3/d3-scale/blob/master/README.md#_ordinal) - compute the range value corresponding to a given domain value.\n* [*ordinal*.domain](https://github.com/d3/d3-scale/blob/master/README.md#ordinal_domain) - set the input domain.\n* [*ordinal*.range](https://github.com/d3/d3-scale/blob/master/README.md#ordinal_range) - set the output range.\n* [*ordinal*.unknown](https://github.com/d3/d3-scale/blob/master/README.md#ordinal_unknown) - set the output value for unknown inputs.\n* [*ordinal*.copy](https://github.com/d3/d3-scale/blob/master/README.md#ordinal_copy) - create a copy of this scale.\n* [d3.scaleImplicit](https://github.com/d3/d3-scale/blob/master/README.md#scaleImplicit) - a special unknown value for implicit domains.\n* [d3.scaleBand](https://github.com/d3/d3-scale/blob/master/README.md#scaleBand) - create an ordinal band scale.\n* [*band*](https://github.com/d3/d3-scale/blob/master/README.md#_band) - compute the band start corresponding to a given domain value.\n* [*band*.domain](https://github.com/d3/d3-scale/blob/master/README.md#band_domain) - set the input domain.\n* [*band*.range](https://github.com/d3/d3-scale/blob/master/README.md#band_range) - set the output range.\n* [*band*.rangeRound](https://github.com/d3/d3-scale/blob/master/README.md#band_rangeRound) - set the output range and enable rounding.\n* [*band*.round](https://github.com/d3/d3-scale/blob/master/README.md#band_round) - enable rounding.\n* [*band*.paddingInner](https://github.com/d3/d3-scale/blob/master/README.md#band_paddingInner) - set padding between bands.\n* [*band*.paddingOuter](https://github.com/d3/d3-scale/blob/master/README.md#band_paddingOuter) - set padding outside the first and last bands.\n* [*band*.padding](https://github.com/d3/d3-scale/blob/master/README.md#band_padding) - set padding outside and between bands.\n* [*band*.align](https://github.com/d3/d3-scale/blob/master/README.md#band_align) - set band alignment, if there is extra space.\n* [*band*.bandwidth](https://github.com/d3/d3-scale/blob/master/README.md#band_bandwidth) - get the width of each band.\n* [*band*.step](https://github.com/d3/d3-scale/blob/master/README.md#band_step) - get the distance between the starts of adjacent bands.\n* [*band*.copy](https://github.com/d3/d3-scale/blob/master/README.md#band_copy) - create a copy of this scale.\n* [d3.scalePoint](https://github.com/d3/d3-scale/blob/master/README.md#scalePoint) - create an ordinal point scale.\n* [*point*](https://github.com/d3/d3-scale/blob/master/README.md#_point) - compute the point corresponding to a given domain value.\n* [*point*.domain](https://github.com/d3/d3-scale/blob/master/README.md#point_domain) - set the input domain.\n* [*point*.range](https://github.com/d3/d3-scale/blob/master/README.md#point_range) - set the output range.\n* [*point*.rangeRound](https://github.com/d3/d3-scale/blob/master/README.md#point_rangeRound) - set the output range and enable rounding.\n* [*point*.round](https://github.com/d3/d3-scale/blob/master/README.md#point_round) - enable rounding.\n* [*point*.padding](https://github.com/d3/d3-scale/blob/master/README.md#point_padding) - set padding outside the first and last point.\n* [*point*.align](https://github.com/d3/d3-scale/blob/master/README.md#point_align) - set point alignment, if there is extra space.\n* [*point*.bandwidth](https://github.com/d3/d3-scale/blob/master/README.md#point_bandwidth) - returns zero.\n* [*point*.step](https://github.com/d3/d3-scale/blob/master/README.md#point_step) - get the distance between the starts of adjacent points.\n* [*point*.copy](https://github.com/d3/d3-scale/blob/master/README.md#point_copy) - create a copy of this scale.\n* [d3.schemeCategory10](https://github.com/d3/d3-scale/blob/master/README.md#schemeCategory10) - a categorical scheme with 10 colors.\n* [d3.schemeCategory20](https://github.com/d3/d3-scale/blob/master/README.md#schemeCategory20) - a categorical scheme with 20 colors.\n* [d3.schemeCategory20b](https://github.com/d3/d3-scale/blob/master/README.md#schemeCategory20b) - a categorical scheme with 20 colors.\n* [d3.schemeCategory20c](https://github.com/d3/d3-scale/blob/master/README.md#schemeCategory20c) - a categorical scheme with 20 colors.\n\n## [Selections (d3-selection)](https://github.com/d3/d3-selection)\n\nTransform the DOM by selecting elements and joining to data.\n\n### [Selecting Elements](https://github.com/d3/d3-selection/blob/master/README.md#selecting-elements)\n\n* [d3.selection](https://github.com/d3/d3-selection/blob/master/README.md#selection) - select the root document element.\n* [d3.select](https://github.com/d3/d3-selection/blob/master/README.md#select) - select an element from the document.\n* [d3.selectAll](https://github.com/d3/d3-selection/blob/master/README.md#selectAll) - select multiple elements from the document.\n* [*selection*.select](https://github.com/d3/d3-selection/blob/master/README.md#selection_select) - select a descendant element for each selected element.\n* [*selection*.selectAll](https://github.com/d3/d3-selection/blob/master/README.md#selection_selectAll) - select multiple descendants for each selected element.\n* [*selection*.filter](https://github.com/d3/d3-selection/blob/master/README.md#selection_filter) - filter elements based on data.\n* [*selection*.merge](https://github.com/d3/d3-selection/blob/master/README.md#selection_merge) - merge this selection with another.\n* [d3.matcher](https://github.com/d3/d3-selection/blob/master/README.md#matcher) - test whether an element matches a selector.\n* [d3.selector](https://github.com/d3/d3-selection/blob/master/README.md#selector) - select an element.\n* [d3.selectorAll](https://github.com/d3/d3-selection/blob/master/README.md#selectorAll) - select elements.\n* [d3.window](https://github.com/d3/d3-selection/blob/master/README.md#window) - get a node’s owner window.\n* [d3.style](https://github.com/d3/d3-selection/blob/master/README.md#style) - get a node’s current style value.\n\n### [Modifying Elements](https://github.com/d3/d3-selection/blob/master/README.md#modifying-elements)\n\n* [*selection*.attr](https://github.com/d3/d3-selection/blob/master/README.md#selection_attr) - get or set an attribute.\n* [*selection*.classed](https://github.com/d3/d3-selection/blob/master/README.md#selection_classed) - get, add or remove CSS classes.\n* [*selection*.style](https://github.com/d3/d3-selection/blob/master/README.md#selection_style) - get or set a style property.\n* [*selection*.property](https://github.com/d3/d3-selection/blob/master/README.md#selection_property) - get or set a (raw) property.\n* [*selection*.text](https://github.com/d3/d3-selection/blob/master/README.md#selection_text) - get or set the text content.\n* [*selection*.html](https://github.com/d3/d3-selection/blob/master/README.md#selection_html) - get or set the inner HTML.\n* [*selection*.append](https://github.com/d3/d3-selection/blob/master/README.md#selection_append) - create, append and select new elements.\n* [*selection*.insert](https://github.com/d3/d3-selection/blob/master/README.md#selection_insert) - create, insert and select new elements.\n* [*selection*.remove](https://github.com/d3/d3-selection/blob/master/README.md#selection_remove) - remove elements from the document.\n* [*selection*.sort](https://github.com/d3/d3-selection/blob/master/README.md#selection_sort) - sort elements in the document based on data.\n* [*selection*.order](https://github.com/d3/d3-selection/blob/master/README.md#selection_order) - reorders elements in the document to match the selection.\n* [*selection*.raise](https://github.com/d3/d3-selection/blob/master/README.md#selection_raise) - reorders each element as the last child of its parent.\n* [*selection*.lower](https://github.com/d3/d3-selection/blob/master/README.md#selection_lower) - reorders each element as the first child of its parent.\n* [d3.creator](https://github.com/d3/d3-selection/blob/master/README.md#creator) - create an element by name.\n\n### [Joining Data](https://github.com/d3/d3-selection/blob/master/README.md#joining-data)\n\n* [*selection*.data](https://github.com/d3/d3-selection/blob/master/README.md#selection_data) - join elements to data.\n* [*selection*.enter](https://github.com/d3/d3-selection/blob/master/README.md#selection_enter) - get the enter selection (data missing elements).\n* [*selection*.exit](https://github.com/d3/d3-selection/blob/master/README.md#selection_exit) - get the exit selection (elements missing data).\n* [*selection*.datum](https://github.com/d3/d3-selection/blob/master/README.md#selection_datum) - get or set element data (without joining).\n\n### [Handling Events](https://github.com/d3/d3-selection/blob/master/README.md#handling-events)\n\n* [*selection*.on](https://github.com/d3/d3-selection/blob/master/README.md#selection_on) - add or remove event listeners.\n* [*selection*.dispatch](https://github.com/d3/d3-selection/blob/master/README.md#selection_dispatch) - dispatch a custom event.\n* [d3.event](https://github.com/d3/d3-selection/blob/master/README.md#event) - the current user event, during interaction.\n* [d3.customEvent](https://github.com/d3/d3-selection/blob/master/README.md#customEvent) - temporarily define a custom event.\n* [d3.mouse](https://github.com/d3/d3-selection/blob/master/README.md#mouse) - get the mouse position relative to a given container.\n* [d3.touch](https://github.com/d3/d3-selection/blob/master/README.md#touch) - get a touch position relative to a given container.\n* [d3.touches](https://github.com/d3/d3-selection/blob/master/README.md#touches) - get the touch positions relative to a given container.\n\n### [Control Flow](https://github.com/d3/d3-selection/blob/master/README.md#control-flow)\n\n* [*selection*.each](https://github.com/d3/d3-selection/blob/master/README.md#selection_each) - call a function for each element.\n* [*selection*.call](https://github.com/d3/d3-selection/blob/master/README.md#selection_call) - call a function with this selection.\n* [*selection*.empty](https://github.com/d3/d3-selection/blob/master/README.md#selection_empty) - returns true if this selection is empty.\n* [*selection*.nodes](https://github.com/d3/d3-selection/blob/master/README.md#selection_nodes) - returns an array of all selected elements.\n* [*selection*.node](https://github.com/d3/d3-selection/blob/master/README.md#selection_node) - returns the first (non-null) element.\n* [*selection*.size](https://github.com/d3/d3-selection/blob/master/README.md#selection_size) - returns the count of elements.\n\n### [Local Variables](https://github.com/d3/d3-selection/blob/master/README.md#local-variables)\n\n* [d3.local](https://github.com/d3/d3-selection/blob/master/README.md#local) - declares a new local variable.\n* [*local*.set](https://github.com/d3/d3-selection/blob/master/README.md#local_set) - set a local variable’s value.\n* [*local*.get](https://github.com/d3/d3-selection/blob/master/README.md#local_get) - get a local variable’s value.\n* [*local*.remove](https://github.com/d3/d3-selection/blob/master/README.md#local_remove) - delete a local variable.\n* [*local*.toString](https://github.com/d3/d3-selection/blob/master/README.md#local_toString) - get the property identifier of a local variable.\n\n### [Namespaces](https://github.com/d3/d3-selection/blob/master/README.md#namespaces)\n\n* [d3.namespace](https://github.com/d3/d3-selection/blob/master/README.md#namespace) - qualify a prefixed XML name, such as “xlink:href”.\n* [d3.namespaces](https://github.com/d3/d3-selection/blob/master/README.md#namespaces) - the built-in XML namespaces.\n\n## [Shapes (d3-shape)](https://github.com/d3/d3-shape)\n\nGraphical primitives for visualization.\n\n### [Arcs](https://github.com/d3/d3-shape/blob/master/README.md#arcs)\n\nCircular or annular sectors, as in a pie or donut chart.\n\n* [d3.arc](https://github.com/d3/d3-shape/blob/master/README.md#arc) - create a new arc generator.\n* [*arc*](https://github.com/d3/d3-shape/blob/master/README.md#_arc) - generate an arc for the given datum.\n* [*arc*.centroid](https://github.com/d3/d3-shape/blob/master/README.md#arc_centroid) - compute an arc’s midpoint.\n* [*arc*.innerRadius](https://github.com/d3/d3-shape/blob/master/README.md#arc_innerRadius) - set the inner radius.\n* [*arc*.outerRadius](https://github.com/d3/d3-shape/blob/master/README.md#arc_outerRadius) - set the outer radius.\n* [*arc*.cornerRadius](https://github.com/d3/d3-shape/blob/master/README.md#arc_cornerRadius) - set the corner radius, for rounded corners.\n* [*arc*.startAngle](https://github.com/d3/d3-shape/blob/master/README.md#arc_startAngle) - set the start angle.\n* [*arc*.endAngle](https://github.com/d3/d3-shape/blob/master/README.md#arc_endAngle) - set the end angle.\n* [*arc*.padAngle](https://github.com/d3/d3-shape/blob/master/README.md#arc_padAngle) - set the angle between adjacent arcs, for padded arcs.\n* [*arc*.padRadius](https://github.com/d3/d3-shape/blob/master/README.md#arc_padRadius) - set the radius at which to linearize padding.\n* [*arc*.context](https://github.com/d3/d3-shape/blob/master/README.md#arc_context) - set the rendering context.\n\n### [Pies](https://github.com/d3/d3-shape/blob/master/README.md#pies)\n\nCompute the necessary angles to represent a tabular dataset as a pie or donut chart.\n\n* [d3.pie](https://github.com/d3/d3-shape/blob/master/README.md#pie) - create a new pie generator.\n* [*pie*](https://github.com/d3/d3-shape/blob/master/README.md#_pie) - compute the arc angles for the given dataset.\n* [*pie*.value](https://github.com/d3/d3-shape/blob/master/README.md#pie_value) - set the value accessor.\n* [*pie*.sort](https://github.com/d3/d3-shape/blob/master/README.md#pie_sort) - set the sort order comparator.\n* [*pie*.sortValues](https://github.com/d3/d3-shape/blob/master/README.md#pie_sortValues) - set the sort order comparator.\n* [*pie*.startAngle](https://github.com/d3/d3-shape/blob/master/README.md#pie_startAngle) - set the overall start angle.\n* [*pie*.endAngle](https://github.com/d3/d3-shape/blob/master/README.md#pie_endAngle) - set the overall end angle.\n* [*pie*.padAngle](https://github.com/d3/d3-shape/blob/master/README.md#pie_padAngle) - set the pad angle between adjacent arcs.\n\n### [Lines](https://github.com/d3/d3-shape/blob/master/README.md#lines)\n\nA spline or polyline, as in a line chart.\n\n* [d3.line](https://github.com/d3/d3-shape/blob/master/README.md#line) - create a new line generator.\n* [*line*](https://github.com/d3/d3-shape/blob/master/README.md#_line) - generate a line for the given dataset.\n* [*line*.x](https://github.com/d3/d3-shape/blob/master/README.md#line_x) - set the *x* accessor.\n* [*line*.y](https://github.com/d3/d3-shape/blob/master/README.md#line_y) - set the *y* accessor.\n* [*line*.defined](https://github.com/d3/d3-shape/blob/master/README.md#line_defined) - set the defined accessor.\n* [*line*.curve](https://github.com/d3/d3-shape/blob/master/README.md#line_curve) - set the curve interpolator.\n* [*line*.context](https://github.com/d3/d3-shape/blob/master/README.md#line_context) - set the rendering context.\n* [d3.radialLine](https://github.com/d3/d3-shape/blob/master/README.md#radialLine) - create a new radial line generator.\n* [*radialLine*](https://github.com/d3/d3-shape/blob/master/README.md#_radialLine) - generate a line for the given dataset.\n* [*radialLine*.angle](https://github.com/d3/d3-shape/blob/master/README.md#radialLine_angle) - set the angle accessor.\n* [*radialLine*.radius](https://github.com/d3/d3-shape/blob/master/README.md#radialLine_radius) - set the radius accessor.\n* [*radialLine*.defined](https://github.com/d3/d3-shape/blob/master/README.md#radialLine_defined) - set the defined accessor.\n* [*radialLine*.curve](https://github.com/d3/d3-shape/blob/master/README.md#radialLine_curve) - set the curve interpolator.\n* [*radialLine*.context](https://github.com/d3/d3-shape/blob/master/README.md#radialLine_context) - set the rendering context.\n\n### [Areas](https://github.com/d3/d3-shape/blob/master/README.md#areas)\n\nAn area, defined by a bounding topline and baseline, as in an area chart.\n\n* [d3.area](https://github.com/d3/d3-shape/blob/master/README.md#area) - create a new area generator.\n* [*area*](https://github.com/d3/d3-shape/blob/master/README.md#_area) - generate an area for the given dataset.\n* [*area*.x](https://github.com/d3/d3-shape/blob/master/README.md#area_x) - set the *x0* and *x1* accessors.\n* [*area*.x0](https://github.com/d3/d3-shape/blob/master/README.md#area_x0) - set the baseline *x* accessor.\n* [*area*.x1](https://github.com/d3/d3-shape/blob/master/README.md#area_x1) - set the topline *x* accessor.\n* [*area*.y](https://github.com/d3/d3-shape/blob/master/README.md#area_y) - set the *y0* and *y1* accessors.\n* [*area*.y0](https://github.com/d3/d3-shape/blob/master/README.md#area_y0) - set the baseline *y* accessor.\n* [*area*.y1](https://github.com/d3/d3-shape/blob/master/README.md#area_y1) - set the topline *y* accessor.\n* [*area*.defined](https://github.com/d3/d3-shape/blob/master/README.md#area_defined) - set the defined accessor.\n* [*area*.curve](https://github.com/d3/d3-shape/blob/master/README.md#area_curve) - set the curve interpolator.\n* [*area*.context](https://github.com/d3/d3-shape/blob/master/README.md#area_context) - set the rendering context.\n* [*area*.lineX0](https://github.com/d3/d3-shape/blob/master/README.md#area_lineX0) - derive a line for the left edge of an area.\n* [*area*.lineX1](https://github.com/d3/d3-shape/blob/master/README.md#area_lineX1) - derive a line for the right edge of an area.\n* [*area*.lineY0](https://github.com/d3/d3-shape/blob/master/README.md#area_lineY0) - derive a line for the top edge of an area.\n* [*area*.lineY1](https://github.com/d3/d3-shape/blob/master/README.md#area_lineY1) - derive a line for the bottom edge of an area.\n* [d3.radialArea](https://github.com/d3/d3-shape/blob/master/README.md#radialArea) - create a new radial area generator.\n* [*radialArea*](https://github.com/d3/d3-shape/blob/master/README.md#_radialArea) - generate an area for the given dataset.\n* [*radialArea*.angle](https://github.com/d3/d3-shape/blob/master/README.md#radialArea_angle) - set the start and end angle accessors.\n* [*radialArea*.startAngle](https://github.com/d3/d3-shape/blob/master/README.md#radialArea_startAngle) - set the start angle accessor.\n* [*radialArea*.endAngle](https://github.com/d3/d3-shape/blob/master/README.md#radialArea_endAngle) - set the end angle accessor.\n* [*radialArea*.radius](https://github.com/d3/d3-shape/blob/master/README.md#radialArea_radius) - set the inner and outer radius accessors.\n* [*radialArea*.innerRadius](https://github.com/d3/d3-shape/blob/master/README.md#radialArea_innerRadius) - set the inner radius accessor.\n* [*radialArea*.outerRadius](https://github.com/d3/d3-shape/blob/master/README.md#radialArea_outerRadius) - set the outer radius accessor.\n* [*radialArea*.defined](https://github.com/d3/d3-shape/blob/master/README.md#radialArea_defined) - set the defined accessor.\n* [*radialArea*.curve](https://github.com/d3/d3-shape/blob/master/README.md#radialArea_curve) - set the curve interpolator.\n* [*radialArea*.context](https://github.com/d3/d3-shape/blob/master/README.md#radialArea_context) - set the rendering context.\n* [*radialArea*.lineStartAngle](https://github.com/d3/d3-shape/blob/master/README.md#area_lineStartAngle) - derive a line for the start edge of an area.\n* [*radialArea*.lineEndAngle](https://github.com/d3/d3-shape/blob/master/README.md#area_lineEndAngle) - derive a line for the end edge of an area.\n* [*radialArea*.lineInnerRadius](https://github.com/d3/d3-shape/blob/master/README.md#area_lineInnerRadius) - derive a line for the inner edge of an area.\n* [*radialArea*.lineOuterRadius](https://github.com/d3/d3-shape/blob/master/README.md#area_lineOuterRadius) - derive a line for the outer edge of an area.\n\n### [Curves](https://github.com/d3/d3-shape/blob/master/README.md#curves)\n\nInterpolate between points to produce a continuous shape.\n\n* [d3.curveBasis](https://github.com/d3/d3-shape/blob/master/README.md#curveBasis) - a cubic basis spline, repeating the end points.\n* [d3.curveBasisClosed](https://github.com/d3/d3-shape/blob/master/README.md#curveBasisClosed) - a closed cubic basis spline.\n* [d3.curveBasisOpen](https://github.com/d3/d3-shape/blob/master/README.md#curveBasisOpen) - a cubic basis spline.\n* [d3.curveBundle](https://github.com/d3/d3-shape/blob/master/README.md#curveBundle) - a straightened cubic basis spline.\n* [*bundle*.beta](https://github.com/d3/d3-shape/blob/master/README.md#bundle_beta) - set the bundle tension *beta*.\n* [d3.curveCardinal](https://github.com/d3/d3-shape/blob/master/README.md#curveCardinal) - a cubic cardinal spline, with one-sided difference at each end.\n* [d3.curveCardinalClosed](https://github.com/d3/d3-shape/blob/master/README.md#curveCardinalClosed) - a closed cubic cardinal spline.\n* [d3.curveCardinalOpen](https://github.com/d3/d3-shape/blob/master/README.md#curveCardinalOpen) - a cubic cardinal spline.\n* [*cardinal*.tension](https://github.com/d3/d3-shape/blob/master/README.md#cardinal_tension) - set the cardinal spline tension.\n* [d3.curveCatmullRom](https://github.com/d3/d3-shape/blob/master/README.md#curveCatmullRom) - a cubic Catmull–Rom spline, with one-sided difference at each end.\n* [d3.curveCatmullRomClosed](https://github.com/d3/d3-shape/blob/master/README.md#curveCatmullRomClosed) - a closed cubic Catmull–Rom spline.\n* [d3.curveCatmullRomOpen](https://github.com/d3/d3-shape/blob/master/README.md#curveCatmullRomOpen) - a cubic Catmull–Rom spline.\n* [*catmullRom*.alpha](https://github.com/d3/d3-shape/blob/master/README.md#catmullRom_alpha) - set the Catmull–Rom parameter *alpha*.\n* [d3.curveLinear](https://github.com/d3/d3-shape/blob/master/README.md#curveLinear) - a polyline.\n* [d3.curveLinearClosed](https://github.com/d3/d3-shape/blob/master/README.md#curveLinearClosed) - a closed polyline.\n* [d3.curveMonotoneX](https://github.com/d3/d3-shape/blob/master/README.md#curveMonotoneX) - a cubic spline that, given monotonicity in *x*, preserves it in *y*.\n* [d3.curveMonotoneY](https://github.com/d3/d3-shape/blob/master/README.md#curveMonotoneY) - a cubic spline that, given monotonicity in *y*, preserves it in *x*.\n* [d3.curveNatural](https://github.com/d3/d3-shape/blob/master/README.md#curveNatural) - a natural cubic spline.\n* [d3.curveStep](https://github.com/d3/d3-shape/blob/master/README.md#curveStep) - a piecewise constant function.\n* [d3.curveStepAfter](https://github.com/d3/d3-shape/blob/master/README.md#curveStepAfter) - a piecewise constant function.\n* [d3.curveStepBefore](https://github.com/d3/d3-shape/blob/master/README.md#curveStepBefore) - a piecewise constant function.\n* [*curve*.areaStart](https://github.com/d3/d3-shape/blob/master/README.md#curve_areaStart) - start a new area segment.\n* [*curve*.areaEnd](https://github.com/d3/d3-shape/blob/master/README.md#curve_areaEnd) - end the current area segment.\n* [*curve*.lineStart](https://github.com/d3/d3-shape/blob/master/README.md#curve_lineStart) - start a new line segment.\n* [*curve*.lineEnd](https://github.com/d3/d3-shape/blob/master/README.md#curve_lineEnd) - end the current line segment.\n* [*curve*.point](https://github.com/d3/d3-shape/blob/master/README.md#curve_point) - add a point to the current line segment.\n\n### [Links](https://github.com/d3/d3-shape/blob/master/README.md#links)\n\nA smooth cubic Bézier curve from a source to a target.\n\n* [d3.linkVertical](https://github.com/d3/d3-shape/blob/master/README.md#linkVertical) - create a new vertical link generator.\n* [d3.linkHorizontal](https://github.com/d3/d3-shape/blob/master/README.md#linkHorizontal) - create a new horizontal link generator.\n* [*link*](https://github.com/d3/d3-shape/blob/master/README.md#_link) - generate a link.\n* [*link*.source](https://github.com/d3/d3-shape/blob/master/README.md#link_source) - set the source accessor.\n* [*link*.target](https://github.com/d3/d3-shape/blob/master/README.md#link_target) - set the target accessor.\n* [*link*.x](https://github.com/d3/d3-shape/blob/master/README.md#link_x) - set the point *x*-accessor.\n* [*link*.y](https://github.com/d3/d3-shape/blob/master/README.md#link_y) - set the point *y*-accessor.\n* [d3.linkRadial](https://github.com/d3/d3-shape/blob/master/README.md#linkRadial) - create a new radial link generator.\n* [*radialLink*.angle](https://github.com/d3/d3-shape/blob/master/README.md#radialLink_angle) - set the point *angle* accessor.\n* [*radialLink*.radius](https://github.com/d3/d3-shape/blob/master/README.md#radialLink_radius) - set the point *radius* accessor.\n\n### [Symbols](https://github.com/d3/d3-shape/blob/master/README.md#symbols)\n\nA categorical shape encoding, as in a scatterplot.\n\n* [d3.symbol](https://github.com/d3/d3-shape/blob/master/README.md#symbol) - create a new symbol generator.\n* [*symbol*](https://github.com/d3/d3-shape/blob/master/README.md#_symbol) - generate a symbol for the given datum.\n* [*symbol*.type](https://github.com/d3/d3-shape/blob/master/README.md#symbol_type) - set the symbol type.\n* [*symbol*.size](https://github.com/d3/d3-shape/blob/master/README.md#symbol_size) - set the size of the symbol in square pixels.\n* [*symbol*.context](https://github.com/d3/d3-shape/blob/master/README.md#symbol_context) - set the rendering context.\n* [d3.symbols](https://github.com/d3/d3-shape/blob/master/README.md#symbols) - the array of built-in symbol types.\n* [d3.symbolCircle](https://github.com/d3/d3-shape/blob/master/README.md#symbolCircle) - a circle.\n* [d3.symbolCross](https://github.com/d3/d3-shape/blob/master/README.md#symbolCross) - a Greek cross with arms of equal length.\n* [d3.symbolDiamond](https://github.com/d3/d3-shape/blob/master/README.md#symbolDiamond) - a rhombus.\n* [d3.symbolSquare](https://github.com/d3/d3-shape/blob/master/README.md#symbolSquare) - a square.\n* [d3.symbolStar](https://github.com/d3/d3-shape/blob/master/README.md#symbolStar) - a pentagonal star (pentagram).\n* [d3.symbolTriangle](https://github.com/d3/d3-shape/blob/master/README.md#symbolTriangle) - an up-pointing triangle.\n* [d3.symbolWye](https://github.com/d3/d3-shape/blob/master/README.md#symbolWye) - a Y shape.\n* [*symbolType*.draw](https://github.com/d3/d3-shape/blob/master/README.md#symbolType_draw) - draw this symbol to the given context.\n\n### [Stacks](https://github.com/d3/d3-shape/blob/master/README.md#stacks)\n\nStack shapes, placing one adjacent to another, as in a stacked bar chart.\n\n* [d3.stack](https://github.com/d3/d3-shape/blob/master/README.md#stack) - create a new stack generator.\n* [*stack*](https://github.com/d3/d3-shape/blob/master/README.md#_stack) - generate a stack for the given dataset.\n* [*stack*.keys](https://github.com/d3/d3-shape/blob/master/README.md#stack_keys) - set the keys accessor.\n* [*stack*.value](https://github.com/d3/d3-shape/blob/master/README.md#stack_value) - set the value accessor.\n* [*stack*.order](https://github.com/d3/d3-shape/blob/master/README.md#stack_order) - set the order accessor.\n* [*stack*.offset](https://github.com/d3/d3-shape/blob/master/README.md#stack_offset) - set the offset accessor.\n* [d3.stackOrderAscending](https://github.com/d3/d3-shape/blob/master/README.md#stackOrderAscending) - put the smallest series on bottom.\n* [d3.stackOrderDescending](https://github.com/d3/d3-shape/blob/master/README.md#stackOrderDescending) - put the largest series on bottom.\n* [d3.stackOrderInsideOut](https://github.com/d3/d3-shape/blob/master/README.md#stackOrderInsideOut) - put larger series in the middle.\n* [d3.stackOrderNone](https://github.com/d3/d3-shape/blob/master/README.md#stackOrderNone) - use the given series order.\n* [d3.stackOrderReverse](https://github.com/d3/d3-shape/blob/master/README.md#stackOrderReverse) - use the reverse of the given series order.\n* [d3.stackOffsetExpand](https://github.com/d3/d3-shape/blob/master/README.md#stackOffsetExpand) - normalize the baseline to zero and topline to one.\n* [d3.stackOffsetDiverging](https://github.com/d3/d3-shape/blob/master/README.md#stackOffsetDiverging) - positive above zero; negative below zero.\n* [d3.stackOffsetNone](https://github.com/d3/d3-shape/blob/master/README.md#stackOffsetNone) - apply a zero baseline.\n* [d3.stackOffsetSilhouette](https://github.com/d3/d3-shape/blob/master/README.md#stackOffsetSilhouette) - center the streamgraph around zero.\n* [d3.stackOffsetWiggle](https://github.com/d3/d3-shape/blob/master/README.md#stackOffsetWiggle) - minimize streamgraph wiggling.\n\n## [Time Formats (d3-time-format)](https://github.com/d3/d3-time-format)\n\nParse and format times, inspired by strptime and strftime.\n\n* [d3.timeFormat](https://github.com/d3/d3-time-format/blob/master/README.md#timeFormat) - alias for *locale*.format on the default locale.\n* [d3.timeParse](https://github.com/d3/d3-time-format/blob/master/README.md#timeParse) - alias for *locale*.parse on the default locale.\n* [d3.utcFormat](https://github.com/d3/d3-time-format/blob/master/README.md#utcFormat) -  alias for *locale*.utcFormat on the default locale.\n* [d3.utcParse](https://github.com/d3/d3-time-format/blob/master/README.md#utcParse) -  alias for *locale*.utcParse on the default locale.\n* [d3.isoFormat](https://github.com/d3/d3-time-format/blob/master/README.md#isoFormat) - an ISO 8601 UTC formatter.\n* [d3.isoParse](https://github.com/d3/d3-time-format/blob/master/README.md#isoParse) - an ISO 8601 UTC parser.\n* [d3.timeFormatLocale](https://github.com/d3/d3-time-format/blob/master/README.md#timeFormatLocale) - define a custom locale.\n* [d3.timeFormatDefaultLocale](https://github.com/d3/d3-time-format/blob/master/README.md#timeFormatDefaultLocale) - define the default locale.\n* [*locale*.format](https://github.com/d3/d3-time-format/blob/master/README.md#locale_format) - create a time formatter.\n* [*locale*.parse](https://github.com/d3/d3-time-format/blob/master/README.md#locale_parse) - create a time parser.\n* [*locale*.utcFormat](https://github.com/d3/d3-time-format/blob/master/README.md#locale_utcFormat) - create a UTC formatter.\n* [*locale*.utcParse](https://github.com/d3/d3-time-format/blob/master/README.md#locale_utcParse) - create a UTC parser.\n\n## [Time Intervals (d3-time)](https://github.com/d3/d3-time)\n\nA calculator for humanity’s peculiar conventions of time.\n\n* [d3.timeInterval](https://github.com/d3/d3-time/blob/master/README.md#timeInterval) - implement a new custom time interval.\n* [*interval*](https://github.com/d3/d3-time/blob/master/README.md#_interval) - alias for *interval*.floor.\n* [*interval*.floor](https://github.com/d3/d3-time/blob/master/README.md#interval_floor) - round down to the nearest boundary.\n* [*interval*.round](https://github.com/d3/d3-time/blob/master/README.md#interval_round) - round to the nearest boundary.\n* [*interval*.ceil](https://github.com/d3/d3-time/blob/master/README.md#interval_ceil) - round up to the nearest boundary.\n* [*interval*.offset](https://github.com/d3/d3-time/blob/master/README.md#interval_offset) - offset a date by some number of intervals.\n* [*interval*.range](https://github.com/d3/d3-time/blob/master/README.md#interval_range) - generate a range of dates at interval boundaries.\n* [*interval*.filter](https://github.com/d3/d3-time/blob/master/README.md#interval_filter) - create a filtered subset of this interval.\n* [*interval*.every](https://github.com/d3/d3-time/blob/master/README.md#interval_every) - create a filtered subset of this interval.\n* [*interval*.count](https://github.com/d3/d3-time/blob/master/README.md#interval_count) - count interval boundaries between two dates.\n* [d3.timeMillisecond](https://github.com/d3/d3-time/blob/master/README.md#timeMillisecond), [d3.utcMillisecond](https://github.com/d3/d3-time/blob/master/README.md#timeMillisecond) - the millisecond interval.\n* [d3.timeMilliseconds](https://github.com/d3/d3-time/blob/master/README.md#timeMillisecond), [d3.utcMilliseconds](https://github.com/d3/d3-time/blob/master/README.md#timeMillisecond) - aliases for millisecond.range.\n* [d3.timeSecond](https://github.com/d3/d3-time/blob/master/README.md#timeSecond), [d3.utcSecond](https://github.com/d3/d3-time/blob/master/README.md#timeSecond) - the second interval.\n* [d3.timeSeconds](https://github.com/d3/d3-time/blob/master/README.md#timeSecond), [d3.utcSeconds](https://github.com/d3/d3-time/blob/master/README.md#timeSecond) - aliases for second.range.\n* [d3.timeMinute](https://github.com/d3/d3-time/blob/master/README.md#timeMinute), [d3.utcMinute](https://github.com/d3/d3-time/blob/master/README.md#timeMinute) - the minute interval.\n* [d3.timeMinutes](https://github.com/d3/d3-time/blob/master/README.md#timeMinute), [d3.utcMinutes](https://github.com/d3/d3-time/blob/master/README.md#timeMinute) - aliases for minute.range.\n* [d3.timeHour](https://github.com/d3/d3-time/blob/master/README.md#timeHour), [d3.utcHour](https://github.com/d3/d3-time/blob/master/README.md#timeHour) - the hour interval.\n* [d3.timeHours](https://github.com/d3/d3-time/blob/master/README.md#timeHour), [d3.utcHours](https://github.com/d3/d3-time/blob/master/README.md#timeHour) - aliases for hour.range.\n* [d3.timeDay](https://github.com/d3/d3-time/blob/master/README.md#timeDay), [d3.utcDay](https://github.com/d3/d3-time/blob/master/README.md#timeDay) - the day interval.\n* [d3.timeDays](https://github.com/d3/d3-time/blob/master/README.md#timeDay), [d3.utcDays](https://github.com/d3/d3-time/blob/master/README.md#timeDay) - aliases for day.range.\n* [d3.timeWeek](https://github.com/d3/d3-time/blob/master/README.md#timeWeek), [d3.utcWeek](https://github.com/d3/d3-time/blob/master/README.md#timeWeek) - aliases for sunday.\n* [d3.timeWeeks](https://github.com/d3/d3-time/blob/master/README.md#timeWeek), [d3.utcWeeks](https://github.com/d3/d3-time/blob/master/README.md#timeWeek) - aliases for week.range.\n* [d3.timeSunday](https://github.com/d3/d3-time/blob/master/README.md#timeSunday), [d3.utcSunday](https://github.com/d3/d3-time/blob/master/README.md#timeSunday) - the week interval, starting on Sunday.\n* [d3.timeSundays](https://github.com/d3/d3-time/blob/master/README.md#timeSunday), [d3.utcSundays](https://github.com/d3/d3-time/blob/master/README.md#timeSunday) - aliases for sunday.range.\n* [d3.timeMonday](https://github.com/d3/d3-time/blob/master/README.md#timeMonday), [d3.utcMonday](https://github.com/d3/d3-time/blob/master/README.md#timeMonday) - the week interval, starting on Monday.\n* [d3.timeMondays](https://github.com/d3/d3-time/blob/master/README.md#timeMonday), [d3.utcMondays](https://github.com/d3/d3-time/blob/master/README.md#timeMonday) - aliases for monday.range.\n* [d3.timeTuesday](https://github.com/d3/d3-time/blob/master/README.md#timeTuesday), [d3.utcTuesday](https://github.com/d3/d3-time/blob/master/README.md#timeTuesday) - the week interval, starting on Tuesday.\n* [d3.timeTuesdays](https://github.com/d3/d3-time/blob/master/README.md#timeTuesday), [d3.utcTuesdays](https://github.com/d3/d3-time/blob/master/README.md#timeTuesday) - aliases for tuesday.range.\n* [d3.timeWednesday](https://github.com/d3/d3-time/blob/master/README.md#timeWednesday), [d3.utcWednesday](https://github.com/d3/d3-time/blob/master/README.md#timeWednesday) - the week interval, starting on Wednesday.\n* [d3.timeWednesdays](https://github.com/d3/d3-time/blob/master/README.md#timeWednesday), [d3.utcWednesdays](https://github.com/d3/d3-time/blob/master/README.md#timeWednesday) - aliases for wednesday.range.\n* [d3.timeThursday](https://github.com/d3/d3-time/blob/master/README.md#timeThursday), [d3.utcThursday](https://github.com/d3/d3-time/blob/master/README.md#timeThursday) - the week interval, starting on Thursday.\n* [d3.timeThursdays](https://github.com/d3/d3-time/blob/master/README.md#timeThursday), [d3.utcThursdays](https://github.com/d3/d3-time/blob/master/README.md#timeThursday) - aliases for thursday.range.\n* [d3.timeFriday](https://github.com/d3/d3-time/blob/master/README.md#timeFriday), [d3.utcFriday](https://github.com/d3/d3-time/blob/master/README.md#timeFriday) - the week interval, starting on Friday.\n* [d3.timeFridays](https://github.com/d3/d3-time/blob/master/README.md#timeFriday), [d3.utcFridays](https://github.com/d3/d3-time/blob/master/README.md#timeFriday) - aliases for friday.range.\n* [d3.timeSaturday](https://github.com/d3/d3-time/blob/master/README.md#timeSaturday), [d3.utcSaturday](https://github.com/d3/d3-time/blob/master/README.md#timeSaturday) - the week interval, starting on Saturday.\n* [d3.timeSaturdays](https://github.com/d3/d3-time/blob/master/README.md#timeSaturday), [d3.utcSaturdays](https://github.com/d3/d3-time/blob/master/README.md#timeSaturday) - aliases for saturday.range.\n* [d3.timeMonth](https://github.com/d3/d3-time/blob/master/README.md#timeMonth), [d3.utcMonth](https://github.com/d3/d3-time/blob/master/README.md#timeMonth) - the month interval.\n* [d3.timeMonths](https://github.com/d3/d3-time/blob/master/README.md#timeMonth), [d3.utcMonths](https://github.com/d3/d3-time/blob/master/README.md#timeMonth) - aliases for month.range.\n* [d3.timeYear](https://github.com/d3/d3-time/blob/master/README.md#timeYear), [d3.utcYear](https://github.com/d3/d3-time/blob/master/README.md#timeYear) - the year interval.\n* [d3.timeYears](https://github.com/d3/d3-time/blob/master/README.md#timeYear), [d3.utcYears](https://github.com/d3/d3-time/blob/master/README.md#timeYear) - aliases for year.range.\n\n## [Timers (d3-timer)](https://github.com/d3/d3-timer)\n\nAn efficient queue for managing thousands of concurrent animations.\n\n* [d3.now](https://github.com/d3/d3-timer/blob/master/README.md#now) - get the current high-resolution time.\n* [d3.timer](https://github.com/d3/d3-timer/blob/master/README.md#timer) - schedule a new timer.\n* [*timer*.restart](https://github.com/d3/d3-timer/blob/master/README.md#timer_restart) - reset the timer’s start time and callback.\n* [*timer*.stop](https://github.com/d3/d3-timer/blob/master/README.md#timer_stop) - stop the timer.\n* [d3.timerFlush](https://github.com/d3/d3-timer/blob/master/README.md#timerFlush) - immediately execute any eligible timers.\n* [d3.timeout](https://github.com/d3/d3-timer/blob/master/README.md#timeout) - schedule a timer that stops on its first callback.\n* [d3.interval](https://github.com/d3/d3-timer/blob/master/README.md#interval) - schedule a timer that is called with a configurable period.\n\n## [Transitions (d3-transition)](https://github.com/d3/d3-transition)\n\nAnimated transitions for [selections](#selections).\n\n* [*selection*.transition](https://github.com/d3/d3-transition/blob/master/README.md#selection_transition) - schedule a transition for the selected elements.\n* [*selection*.interrupt](https://github.com/d3/d3-transition/blob/master/README.md#selection_interrupt) - interrupt and cancel transitions on the selected elements.\n* [d3.transition](https://github.com/d3/d3-transition/blob/master/README.md#transition) - schedule a transition on the root document element.\n* [*transition*.select](https://github.com/d3/d3-transition/blob/master/README.md#transition_select) - schedule a transition on the selected elements.\n* [*transition*.selectAll](https://github.com/d3/d3-transition/blob/master/README.md#transition_selectAll) - schedule a transition on the selected elements.\n* [*transition*.filter](https://github.com/d3/d3-transition/blob/master/README.md#transition_filter) - filter elements based on data.\n* [*transition*.merge](https://github.com/d3/d3-transition/blob/master/README.md#transition_merge) - merge this transition with another.\n* [*transition*.selection](https://github.com/d3/d3-transition/blob/master/README.md#transition_selection) - returns a selection for this transition.\n* [*transition*.transition](https://github.com/d3/d3-transition/blob/master/README.md#transition_transition) - schedule a new transition following this one.\n* [*transition*.call](https://github.com/d3/d3-transition/blob/master/README.md#transition_call) - call a function with this transition.\n* [*transition*.nodes](https://github.com/d3/d3-transition/blob/master/README.md#transition_nodes) - returns an array of all selected elements.\n* [*transition*.node](https://github.com/d3/d3-transition/blob/master/README.md#transition_node) - returns the first (non-null) element.\n* [*transition*.size](https://github.com/d3/d3-transition/blob/master/README.md#transition_size) - returns the count of elements.\n* [*transition*.empty](https://github.com/d3/d3-transition/blob/master/README.md#transition_empty) - returns true if this transition is empty.\n* [*transition*.each](https://github.com/d3/d3-transition/blob/master/README.md#transition_each) - call a function for each element.\n* [*transition*.on](https://github.com/d3/d3-transition/blob/master/README.md#transition_on) - add or remove transition event listeners.\n* [*transition*.attr](https://github.com/d3/d3-transition/blob/master/README.md#transition_attr) - tween the given attribute using the default interpolator.\n* [*transition*.attrTween](https://github.com/d3/d3-transition/blob/master/README.md#transition_attrTween) - tween the given attribute using a custom interpolator.\n* [*transition*.style](https://github.com/d3/d3-transition/blob/master/README.md#transition_style) - tween the given style property using the default interpolator.\n* [*transition*.styleTween](https://github.com/d3/d3-transition/blob/master/README.md#transition_styleTween) - tween the given style property using a custom interpolator.\n* [*transition*.text](https://github.com/d3/d3-transition/blob/master/README.md#transition_text) - set the text content when the transition starts.\n* [*transition*.remove](https://github.com/d3/d3-transition/blob/master/README.md#transition_remove) - remove the selected elements when the transition ends.\n* [*transition*.tween](https://github.com/d3/d3-transition/blob/master/README.md#transition_tween) - run custom code during the transition.\n* [*transition*.delay](https://github.com/d3/d3-transition/blob/master/README.md#transition_delay) - specify per-element delay in milliseconds.\n* [*transition*.duration](https://github.com/d3/d3-transition/blob/master/README.md#transition_duration) - specify per-element duration in milliseconds.\n* [*transition*.ease](https://github.com/d3/d3-transition/blob/master/README.md#transition_ease) - specify the easing function.\n* [d3.active](https://github.com/d3/d3-transition/blob/master/README.md#active) - select the active transition for a given node.\n* [d3.interrupt](https://github.com/d3/d3-transition/blob/master/README.md#interrupt) -\n\n## [Voronoi Diagrams (d3-voronoi)](https://github.com/d3/d3-voronoi)\n\nCompute the Voronoi diagram of a given set of points.\n\n* [d3.voronoi](https://github.com/d3/d3-voronoi/blob/master/README.md#voronoi) - create a new Voronoi generator.\n* [*voronoi*](https://github.com/d3/d3-voronoi/blob/master/README.md#_voronoi) - generate a new Voronoi diagram for the given points.\n* [*voronoi*.polygons](https://github.com/d3/d3-voronoi/blob/master/README.md#voronoi_polygons) - compute the Voronoi polygons for the given points.\n* [*voronoi*.triangles](https://github.com/d3/d3-voronoi/blob/master/README.md#voronoi_triangles) - compute the Delaunay triangles for the given points.\n* [*voronoi*.links](https://github.com/d3/d3-voronoi/blob/master/README.md#voronoi_links) - compute the Delaunay links for the given points.\n* [*voronoi*.x](https://github.com/d3/d3-voronoi/blob/master/README.md#voronoi_x) - set the *x* accessor.\n* [*voronoi*.y](https://github.com/d3/d3-voronoi/blob/master/README.md#voronoi_y) - set the *y* accessor.\n* [*voronoi*.extent](https://github.com/d3/d3-voronoi/blob/master/README.md#voronoi_extent) - set the observed extent of points.\n* [*voronoi*.size](https://github.com/d3/d3-voronoi/blob/master/README.md#voronoi_size) - set the observed extent of points.\n* [*diagram*.polygons](https://github.com/d3/d3-voronoi/blob/master/README.md#diagram_polygons) - compute the polygons for this Voronoi diagram.\n* [*diagram*.triangles](https://github.com/d3/d3-voronoi/blob/master/README.md#diagram_triangles) - compute the triangles for this Voronoi diagram.\n* [*diagram*.links](https://github.com/d3/d3-voronoi/blob/master/README.md#diagram_links) - compute the links for this Voronoi diagram.\n* [*diagram*.find](https://github.com/d3/d3-voronoi/blob/master/README.md#diagram_find) - find the closest point in this Voronoi diagram.\n\n## [Zooming (d3-zoom)](https://github.com/d3/d3-zoom)\n\nPan and zoom SVG, HTML or Canvas using mouse or touch input.\n\n* [d3.zoom](https://github.com/d3/d3-zoom/blob/master/README.md#zoom) - create a zoom behavior.\n* [*zoom*](https://github.com/d3/d3-zoom/blob/master/README.md#_zoom) - apply the zoom behavior to the selected elements.\n* [*zoom*.transform](https://github.com/d3/d3-zoom/blob/master/README.md#zoom_transform) - change the transform for the selected elements.\n* [*zoom*.translateBy](https://github.com/d3/d3-zoom/blob/master/README.md#zoom_translateBy) - translate the transform for the selected elements.\n* [*zoom*.scaleBy](https://github.com/d3/d3-zoom/blob/master/README.md#zoom_scaleBy) - scale the transform for the selected elements.\n* [*zoom*.scaleTo](https://github.com/d3/d3-zoom/blob/master/README.md#zoom_scaleTo) - scale the transform for the selected elements.\n* [*zoom*.filter](https://github.com/d3/d3-zoom/blob/master/README.md#zoom_filter) - control which input events initiate zooming.\n* [*zoom*.clickDistance](https://github.com/d3/d3-zoom/blob/master/README.md#zoom_clickDistance) - set the click distance threshold.\n* [*zoom*.extent](https://github.com/d3/d3-zoom/blob/master/README.md#zoom_extent) - set the extent of the viewport.\n* [*zoom*.scaleExtent](https://github.com/d3/d3-zoom/blob/master/README.md#zoom_scaleExtent) - set the allowed scale range.\n* [*zoom*.translateExtent](https://github.com/d3/d3-zoom/blob/master/README.md#zoom_translateExtent) - set the extent of the zoomable world.\n* [*zoom*.duration](https://github.com/d3/d3-zoom/blob/master/README.md#zoom_duration) - set the duration of zoom transitions.\n* [*zoom*.interpolate](https://github.com/d3/d3-zoom/blob/master/README.md#zoom_interpolate) - control the interpolation of zoom transitions.\n* [*zoom*.on](https://github.com/d3/d3-zoom/blob/master/README.md#zoom_on) - listen for zoom events.\n* [d3.zoomTransform](https://github.com/d3/d3-zoom/blob/master/README.md#zoomTransform) - get the zoom transform for a given element.\n* [*transform*.scale](https://github.com/d3/d3-zoom/blob/master/README.md#transform_scale) - scale a transform by the specified amount.\n* [*transform*.translate](https://github.com/d3/d3-zoom/blob/master/README.md#transform_translate) - translate a transform by the specified amount.\n* [*transform*.apply](https://github.com/d3/d3-zoom/blob/master/README.md#transform_apply) - apply the transform to the given point.\n* [*transform*.applyX](https://github.com/d3/d3-zoom/blob/master/README.md#transform_applyX) - apply the transform to the given *x*-coordinate.\n* [*transform*.applyY](https://github.com/d3/d3-zoom/blob/master/README.md#transform_applyY) - apply the transform to the given *y*-coordinate.\n* [*transform*.invert](https://github.com/d3/d3-zoom/blob/master/README.md#transform_invert) - unapply the transform to the given point.\n* [*transform*.invertX](https://github.com/d3/d3-zoom/blob/master/README.md#transform_invertX) - unapply the transform to the given *x*-coordinate.\n* [*transform*.invertY](https://github.com/d3/d3-zoom/blob/master/README.md#transform_invertY) - unapply the transform to the given *y*-coordinate.\n* [*transform*.rescaleX](https://github.com/d3/d3-zoom/blob/master/README.md#transform_rescaleX) - apply the transform to an *x*-scale’s domain.\n* [*transform*.rescaleY](https://github.com/d3/d3-zoom/blob/master/README.md#transform_rescaleY) - apply the transform to a *y*-scale’s domain.\n* [*transform*.toString](https://github.com/d3/d3-zoom/blob/master/README.md#transform_toString) - format the transform as an SVG transform string.\n* [d3.zoomIdentity](https://github.com/d3/d3-zoom/blob/master/README.md#zoomIdentity) - the identity transform.\n"
  },
  {
    "path": "app_backend/static/plugin/d3/CHANGES.md",
    "content": "# Changes in D3 4.0\n\nD3 4.0 is modular. Instead of one library, D3 is now [many small libraries](#table-of-contents) that are designed to work together. You can pick and choose which parts to use as you see fit. Each library is maintained in its own repository, allowing decentralized ownership and independent release cycles. The default bundle combines about thirty of these microlibraries.\n\n```html\n<script src=\"https://d3js.org/d3.v4.js\"></script>\n```\n\nAs before, you can load optional plugins on top of the default bundle, such as [ColorBrewer scales](https://github.com/d3/d3-scale-chromatic):\n\n```html\n<script src=\"https://d3js.org/d3.v4.js\"></script>\n<script src=\"https://d3js.org/d3-scale-chromatic.v0.3.js\"></script>\n```\n\nYou are not required to use the default bundle! If you’re just using [d3-selection](https://github.com/d3/d3-selection), use it as a standalone library. Like the default bundle, you can load D3 microlibraries using vanilla script tags or RequireJS (great for HTTP/2!):\n\n```html\n<script src=\"https://d3js.org/d3-selection.v1.js\"></script>\n```\n\nYou can also `cat` D3 microlibraries into a custom bundle, or use tools such as [Webpack](https://webpack.github.io/) and [Rollup](http://rollupjs.org/) to create [optimized bundles](https://bl.ocks.org/mbostock/bb09af4c39c79cffcde4). Custom bundles are great for applications that use a subset of D3’s features; for example, a React chart library might use D3 for scales and shapes, and React to manipulate the DOM. The D3 microlibraries are written as [ES6 modules](http://www.2ality.com/2014/09/es6-modules-final.html), and Rollup lets you pick at the symbol level to produce smaller bundles.\n\nSmall files are nice, but modularity is also about making D3 more *fun*. Microlibraries are easier to understand, develop and test. They make it easier for new people to get involved and contribute. They reduce the distinction between a “core module” and a “plugin”, and increase the pace of development in D3 features.\n\nIf you don’t care about modularity, you can mostly ignore this change and keep using the default bundle. However, there is one unavoidable consequence of adopting ES6 modules: every symbol in D3 4.0 now shares a flat namespace rather than the nested one of D3 3.x. For example, d3.scale.linear is now d3.scaleLinear, and d3.layout.treemap is now d3.treemap. The adoption of ES6 modules also means that D3 is now written exclusively in [strict mode](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Strict_mode) and has better readability. And there have been many other significant improvements to D3’s features! (Nearly all of the code from D3 3.x has been rewritten.) These changes are covered below.\n\n### Other Global Changes\n\nThe default [UMD bundle](https://github.com/umdjs/umd) is now [anonymous](https://github.com/requirejs/requirejs/wiki/Updating-existing-libraries#register-as-an-anonymous-module-). No `d3` global is exported if AMD or CommonJS is detected. In a vanilla environment, the D3 microlibraries share the `d3` global, even if you load them independently; thus, code you write is the same whether or not you use the default bundle. (See [Let’s Make a (D3) Plugin](https://bost.ocks.org/mike/d3-plugin/) for more.) The generated bundle is no longer stored in the Git repository; Bower has been repointed to [d3-bower](https://github.com/mbostock-bower/d3-bower), and you can find the generated files on [npm](https://unpkg.com/d3) or attached to the [latest release](https://github.com/d3/d3/releases/latest). The non-minified default bundle is no longer mangled, making it more readable and preserving inline comments.\n\nTo the consternation of some users, 3.x employed Unicode variable names such as λ, φ, τ and π for a concise representation of mathematical operations. A downside of this approach was that a SyntaxError would occur if you loaded the non-minified D3 using ISO-8859-1 instead of UTF-8. 3.x also used Unicode string literals, such as the SI-prefix µ for 1e-6. 4.0 uses only ASCII variable names and ASCII string literals (see [rollup-plugin-ascii](https://github.com/mbostock/rollup-plugin-ascii)), avoiding encoding problems.\n\n### Table of Contents\n\n* [Arrays](#arrays-d3-array)\n* [Axes](#axes-d3-axis)\n* [Brushes](#brushes-d3-brush)\n* [Chords](#chords-d3-chord)\n* [Collections](#collections-d3-collection)\n* [Colors](#colors-d3-color)\n* [Dispatches](#dispatches-d3-dispatch)\n* [Dragging](#dragging-d3-drag)\n* [Delimiter-Separated Values](#delimiter-separated-values-d3-dsv)\n* [Easings](#easings-d3-ease)\n* [Forces](#forces-d3-force)\n* [Number Formats](#number-formats-d3-format)\n* [Geographies](#geographies-d3-geo)\n* [Hierarchies](#hierarchies-d3-hierarchy)\n* [Internals](#internals)\n* [Interpolators](#interpolators-d3-interpolate)\n* [Paths](#paths-d3-path)\n* [Polygons](#polygons-d3-polygon)\n* [Quadtrees](#quadtrees-d3-quadtree)\n* [Queues](#queues-d3-queue)\n* [Random Numbers](#random-numbers-d3-random)\n* [Requests](#requests-d3-request)\n* [Scales](#scales-d3-scale)\n* [Selections](#selections-d3-selection)\n* [Shapes](#shapes-d3-shape)\n* [Time Formats](#time-formats-d3-time-format)\n* [Time Intervals](#time-intervals-d3-time)\n* [Timers](#timers-d3-timer)\n* [Transitions](#transitions-d3-transition)\n* [Voronoi Diagrams](#voronoi-diagrams-d3-voronoi)\n* [Zooming](#zooming-d3-zoom)\n\n## [Arrays (d3-array)](https://github.com/d3/d3-array/blob/master/README.md)\n\nThe new [d3.scan](https://github.com/d3/d3-array/blob/master/README.md#scan) method performs a linear scan of an array, returning the index of the least element according to the specified comparator. This is similar to [d3.min](https://github.com/d3/d3-array/blob/master/README.md#min) and [d3.max](https://github.com/d3/d3-array/blob/master/README.md#max), except you can use it to find the position of an extreme element, rather than just calculate an extreme value.\n\n```js\nvar data = [\n  {name: \"Alice\", value: 2},\n  {name: \"Bob\", value: 3},\n  {name: \"Carol\", value: 1},\n  {name: \"Dwayne\", value: 5}\n];\n\nvar i = d3.scan(data, function(a, b) { return a.value - b.value; }); // 2\ndata[i]; // {name: \"Carol\", value: 1}\n```\n\nThe new [d3.ticks](https://github.com/d3/d3-array/blob/master/README.md#ticks) and [d3.tickStep](https://github.com/d3/d3-array/blob/master/README.md#tickStep) methods are useful for generating human-readable numeric ticks. These methods are a low-level alternative to [*continuous*.ticks](https://github.com/d3/d3-scale/blob/master/README.md#continuous_ticks) from [d3-scale](https://github.com/d3/d3-scale). The new implementation is also more accurate, returning the optimal number of ticks as measured by relative error.\n\n```js\nvar ticks = d3.ticks(0, 10, 5); // [0, 2, 4, 6, 8, 10]\n```\n\nThe [d3.range](https://github.com/d3/d3-array/blob/master/README.md#range) method no longer makes an elaborate attempt to avoid floating-point error when *step* is not an integer. The returned values are strictly defined as *start* + *i* \\* *step*, where *i* is an integer. (Learn more about [floating point math](http://0.30000000000000004.com/).) d3.range returns the empty array for infinite ranges, rather than throwing an error.\n\nThe method signature for optional accessors has been changed to be more consistent with array methods such as [*array*.forEach](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/forEach): the accessor is passed the current element (*d*), the index (*i*), and the array (*data*), with *this* as undefined. This affects [d3.min](https://github.com/d3/d3-array/blob/master/README.md#min), [d3.max](https://github.com/d3/d3-array/blob/master/README.md#max), [d3.extent](https://github.com/d3/d3-array/blob/master/README.md#extent), [d3.sum](https://github.com/d3/d3-array/blob/master/README.md#sum), [d3.mean](https://github.com/d3/d3-array/blob/master/README.md#mean), [d3.median](https://github.com/d3/d3-array/blob/master/README.md#median), [d3.quantile](https://github.com/d3/d3-array/blob/master/README.md#quantile), [d3.variance](https://github.com/d3/d3-array/blob/master/README.md#variance) and [d3.deviation](https://github.com/d3/d3-array/blob/master/README.md#deviation). The [d3.quantile](https://github.com/d3/d3-array/blob/master/README.md#quantile) method previously did not take an accessor. Some methods with optional arguments now treat those arguments as missing if they are null or undefined, rather than strictly checking arguments.length.\n\nThe new [d3.histogram](https://github.com/d3/d3-array/blob/master/README.md#histograms) API replaces d3.layout.histogram. Rather than exposing *bin*.x and *bin*.dx on each returned bin, the histogram exposes *bin*.x0 and *bin*.x1, guaranteeing that *bin*.x0 is exactly equal to *bin*.x1 on the preceeding bin. The “frequency” and “probability” modes are no longer supported; each bin is simply an array of elements from the input data, so *bin*.length is equal to D3 3.x’s *bin*.y in frequency mode. To compute a probability distribution, divide the number of elements in each bin by the total number of elements.\n\nThe *histogram*.range method has been renamed [*histogram*.domain](https://github.com/d3/d3-array/blob/master/README.md#histogram_domain) for consistency with scales. The *histogram*.bins method has been renamed [*histogram*.thresholds](https://github.com/d3/d3-array/blob/master/README.md#histogram_thresholds), and no longer accepts an upper value: *n* thresholds will produce *n* + 1 bins. If you specify a desired number of bins rather than thresholds, d3.histogram now uses [d3.ticks](https://github.com/d3/d3-array/blob/master/README.md#ticks) to compute nice bin thresholds. In addition to the default Sturges’ formula, D3 now implements the [Freedman-Diaconis rule](https://github.com/d3/d3-array/blob/master/README.md#thresholdFreedmanDiaconis) and [Scott’s normal reference rule](https://github.com/d3/d3-array/blob/master/README.md#thresholdScott).\n\n## [Axes (d3-axis)](https://github.com/d3/d3-axis/blob/master/README.md)\n\nTo render axes properly in D3 3.x, you needed to style them:\n\n```html\n<style>\n\n.axis path,\n.axis line {\n  fill: none;\n  stroke: #000;\n  shape-rendering: crispEdges;\n}\n\n.axis text {\n  font: 10px sans-serif;\n}\n\n</style>\n<script>\n\nd3.select(\".axis\")\n    .call(d3.svg.axis()\n        .scale(x)\n        .orient(\"bottom\"));\n\n</script>\n```\n\nIf you didn’t, you saw this:\n\n<img src=\"https://raw.githubusercontent.com/d3/d3/master/img/axis-v3.png\" width=\"100%\" height=\"105\">\n\nD3 4.0 provides default styles and shorter syntax. In place of d3.svg.axis and *axis*.orient, D3 4.0 now provides four constructors for each orientation: [d3.axisTop](https://github.com/d3/d3-axis/blob/master/README.md#axisTop), [d3.axisRight](https://github.com/d3/d3-axis/blob/master/README.md#axisRight), [d3.axisBottom](https://github.com/d3/d3-axis/blob/master/README.md#axisBottom), [d3.axisLeft](https://github.com/d3/d3-axis/blob/master/README.md#axisLeft). These constructors accept a scale, so you can reduce all of the above to:\n\n```html\n<script>\n\nd3.select(\".axis\")\n    .call(d3.axisBottom(x));\n\n</script>\n```\n\nAnd get this:\n\n<img src=\"https://raw.githubusercontent.com/d3/d3/master/img/axis-v4.png\" width=\"100%\" height=\"105\">\n\nAs before, you can customize the axis appearance either by applying stylesheets or by modifying the axis elements. The default appearance has been changed slightly to offset the axis by a half-pixel;  this fixes a crisp-edges rendering issue on Safari where the axis would be drawn two-pixels thick.\n\nThere’s now an [*axis*.tickArguments](https://github.com/d3/d3-axis/blob/master/README.md#axis_tickArguments) method, as an alternative to [*axis*.ticks](https://github.com/d3/d3-axis/blob/master/README.md#axis_ticks) that also allows the axis tick arguments to be inspected. The [*axis*.tickSize](https://github.com/d3/d3-axis/blob/master/README.md#axis_tickSize) method has been changed to only allow a single argument when setting the tick size. The *axis*.innerTickSize and *axis*.outerTickSize methods have been renamed [*axis*.tickSizeInner](https://github.com/d3/d3-axis/blob/master/README.md#axis_tickSizeInner) and [*axis*.tickSizeOuter](https://github.com/d3/d3-axis/blob/master/README.md#axis_tickSizeOuter), respectively.\n\n## [Brushes (d3-brush)](https://github.com/d3/d3-brush/blob/master/README.md)\n\nReplacing d3.svg.brush, there are now three classes of brush for brushing along the *x*-dimension, the *y*-dimension, or both: [d3.brushX](https://github.com/d3/d3-brush/blob/master/README.md#brushX), [d3.brushY](https://github.com/d3/d3-brush/blob/master/README.md#brushY), [d3.brush](https://github.com/d3/d3-brush/blob/master/README.md#brush). Brushes are no longer dependent on [scales](#scales-d3-scale); instead, each brush defines a selection in screen coordinates. This selection can be [inverted](https://github.com/d3/d3-scale/blob/master/README.md#continuous_invert) if you want to compute the corresponding data domain. And rather than rely on the scales’ ranges to determine the brushable area, there is now a [*brush*.extent](https://github.com/d3/d3-brush/blob/master/README.md#brush_extent) method for setting it. If you do not set the brush extent, it defaults to the full extent of the owner SVG element. The *brush*.clamp method has also been eliminated; brushing is always restricted to the brushable area defined by the brush extent.\n\nBrushes no longer store the active brush selection (*i.e.*, the highlighted region; the brush’s position) internally. The brush’s position is now stored on any elements to which the brush has been applied. The brush’s position is available as *event*.selection within a brush event or by calling [d3.brushSelection](https://github.com/d3/d3-brush/blob/master/README.md#brushSelection) on a given *element*. To move the brush programmatically, use [*brush*.move](https://github.com/d3/d3-brush/blob/master/README.md#brush_move) with a given [selection](#selections-d3-selection) or [transition](#transitions-d3-transition); see the [brush snapping example](https://bl.ocks.org/mbostock/6232537). The *brush*.event method has been removed.\n\nBrush interaction has been improved. By default, brushes now ignore right-clicks intended for the context menu; you can change this behavior using [*brush*.filter](https://github.com/d3/d3-brush/blob/master/README.md#brush_filter). Brushes also ignore emulated mouse events on iOS. Holding down SHIFT (⇧) while brushing locks the *x*- or *y*-position of the brush. Holding down META (⌘) while clicking and dragging starts a new selection, rather than translating the existing selection.\n\nThe default appearance of the brush has also been improved and slightly simplified. Previously it was necessary to apply styles to the brush to give it a reasonable appearance, such as:\n\n```css\n.brush .extent {\n  stroke: #fff;\n  fill-opacity: .125;\n  shape-rendering: crispEdges;\n}\n```\n\nThese styles are now applied by default as attributes; if you want to customize the brush appearance, you can still apply external styles or modify the brush elements. (D3 4.0 features a similar improvement to [axes](#axes-d3-axis).) A new [*brush*.handleSize](https://github.com/d3/d3-brush/blob/master/README.md#brush_handleSize) method lets you override the brush handle size; it defaults to six pixels.\n\nThe brush now consumes handled events, making it easier to combine with other interactive behaviors such as [dragging](#dragging-d3-drag) and [zooming](#zooming-d3-zoom). The *brushstart* and *brushend* events have been renamed to *start* and *end*, respectively. The brush event no longer reports a *event*.mode to distinguish between resizing and dragging the brush.\n\n## [Chords (d3-chord)](https://github.com/d3/d3-chord/blob/master/README.md)\n\nPursuant to the great namespace flattening:\n\n* d3.layout.chord ↦ [d3.chord](https://github.com/d3/d3-chord/blob/master/README.md#chord)\n* d3.svg.chord ↦ [d3.ribbon](https://github.com/d3/d3-chord/blob/master/README.md#ribbon)\n\nFor consistency with [*arc*.padAngle](https://github.com/d3/d3-shape/blob/master/README.md#arc_padAngle), *chord*.padding has also been renamed to [*ribbon*.padAngle](https://github.com/d3/d3-chord/blob/master/README.md#ribbon_padAngle). A new [*ribbon*.context](https://github.com/d3/d3-chord/blob/master/README.md#ribbon_context) method lets you render chord diagrams to Canvas! See also [d3-path](#paths-d3-path).\n\n## [Collections (d3-collection)](https://github.com/d3/d3-collection/blob/master/README.md)\n\nThe [d3.set](https://github.com/d3/d3-collection/blob/master/README.md#set) constructor now accepts an existing set for making a copy. If you pass an array to d3.set, you can also pass a value accessor. This accessor takes the standard arguments: the current element (*d*), the index (*i*), and the array (*data*), with *this* undefined. For example:\n\n```js\nvar yields = [\n  {yield: 22.13333, variety: \"Manchuria\",        year: 1932, site: \"Grand Rapids\"},\n  {yield: 26.76667, variety: \"Peatland\",         year: 1932, site: \"Grand Rapids\"},\n  {yield: 28.10000, variety: \"No. 462\",          year: 1931, site: \"Duluth\"},\n  {yield: 38.50000, variety: \"Svansota\",         year: 1932, site: \"Waseca\"},\n  {yield: 40.46667, variety: \"Svansota\",         year: 1931, site: \"Crookston\"},\n  {yield: 36.03333, variety: \"Peatland\",         year: 1932, site: \"Waseca\"},\n  {yield: 34.46667, variety: \"Wisconsin No. 38\", year: 1931, site: \"Grand Rapids\"}\n];\n\nvar sites = d3.set(yields, function(d) { return d.site; }); // Grand Rapids, Duluth, Waseca, Crookston\n```\n\nThe [d3.map](https://github.com/d3/d3-collection/blob/master/README.md#map) constructor also follows the standard array accessor argument pattern.\n\nThe *map*.forEach and *set*.forEach methods have been renamed to [*map*.each](https://github.com/d3/d3-collection/blob/master/README.md#map_each) and [*set*.each](https://github.com/d3/d3-collection/blob/master/README.md#set_each) respectively. The order of arguments for *map*.each has also been changed to *value*, *key* and *map*, while the order of arguments for *set*.each is now *value*, *value* and *set*. This is closer to ES6 [*map*.forEach](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map/forEach) and [*set*.forEach](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set/forEach). Also like ES6 Map and Set, *map*.set and *set*.add now return the current collection (rather than the added value) to facilitate method chaining. New [*map*.clear](https://github.com/d3/d3-collection/blob/master/README.md#map_clear) and [*set*.clear](https://github.com/d3/d3-collection/blob/master/README.md#set_clear) methods can be used to empty collections.\n\nThe [*nest*.map](https://github.com/d3/d3-collection/blob/master/README.md#nest_map) method now always returns a d3.map instance. For a plain object, use [*nest*.object](https://github.com/d3/d3-collection/blob/master/README.md#nest_object) instead. When used in conjunction with [*nest*.rollup](https://github.com/d3/d3-collection/blob/master/README.md#nest_rollup), [*nest*.entries](https://github.com/d3/d3-collection/blob/master/README.md#nest_entries) now returns {key, value} objects for the leaf entries, instead of {key, values}. This makes *nest*.rollup easier to use in conjunction with [hierarchies](#hierarchies-d3-hierarchy), as in this [Nest Treemap example](https://bl.ocks.org/mbostock/2838bf53e0e65f369f476afd653663a2).\n\n## [Colors (d3-color)](https://github.com/d3/d3-color/blob/master/README.md)\n\nAll colors now have opacity exposed as *color*.opacity, which is a number in [0, 1]. You can pass an optional opacity argument to the color space constructors [d3.rgb](https://github.com/d3/d3-color/blob/master/README.md#rgb), [d3.hsl](https://github.com/d3/d3-color/blob/master/README.md#hsl), [d3.lab](https://github.com/d3/d3-color/blob/master/README.md#lab), [d3.hcl](https://github.com/d3/d3-color/blob/master/README.md#hcl) or [d3.cubehelix](https://github.com/d3/d3-color/blob/master/README.md#cubehelix).\n\nYou can now parse rgba(…) and hsla(…) CSS color specifiers or the string “transparent” using [d3.color](https://github.com/d3/d3-color/blob/master/README.md#color). The “transparent” color is defined as an RGB color with zero opacity and undefined red, green and blue channels; this differs slightly from CSS which defines it as transparent black, but is useful for simplifying color interpolation logic where either the starting or ending color has undefined channels. The [*color*.toString](https://github.com/d3/d3-color/blob/master/README.md#color_toString) method now likewise returns an rgb(…) or rgba(…) string with integer channel values, not the hexadecimal RGB format, consistent with CSS computed values. This improves performance by short-circuiting transitions when the element’s starting style matches its ending style.\n\nThe new [d3.color](https://github.com/d3/d3-color/blob/master/README.md#color) method is the primary method for parsing colors: it returns a d3.color instance in the appropriate color space, or null if the CSS color specifier is invalid. For example:\n\n```js\nvar red = d3.color(\"hsl(0, 80%, 50%)\"); // {h: 0, l: 0.5, s: 0.8, opacity: 1}\n```\n\nThe parsing implementation is now more robust. For example, you can no longer mix integers and percentages in rgb(…), and it correctly handles whitespace, decimal points, number signs, and other edge cases. The color space constructors d3.rgb, d3.hsl, d3.lab, d3.hcl and d3.cubehelix now always return a copy of the input color, converted to the corresponding color space. While [*color*.rgb](https://github.com/d3/d3-color/blob/master/README.md#color_rgb) remains, *rgb*.hsl has been removed; use d3.hsl to convert a color to the RGB color space.\n\nThe RGB color space no longer greedily quantizes and clamps channel values when creating colors, improving accuracy in color space conversion. Quantization and clamping now occurs in *color*.toString when formatting a color for display. You can use the new [*color*.displayable](https://github.com/d3/d3-color/blob/master/README.md#color_displayable) to test whether a color is [out-of-gamut](https://en.wikipedia.org/wiki/Gamut).\n\nThe [*rgb*.brighter](https://github.com/d3/d3-color/blob/master/README.md#rgb_brighter) method no longer special-cases black. This is a multiplicative operator, defining a new color *r*′, *g*′, *b*′ where *r*′ = *r* × *pow*(0.7, *k*), *g*′ = *g* × *pow*(0.7, *k*) and *b*′ = *b* × *pow*(0.7, *k*); a brighter black is still black.\n\nThere’s a new [d3.cubehelix](https://github.com/d3/d3-color/blob/master/README.md#cubehelix) color space, generalizing Dave Green’s color scheme! (See also [d3.interpolateCubehelixDefault](https://github.com/d3/d3-scale/blob/master/README.md#interpolateCubehelixDefault) from [d3-scale](#scales-d3-scale).) You can continue to define your own custom color spaces, too; see [d3-hsv](https://github.com/d3/d3-hsv) for an example.\n\n## [Dispatches (d3-dispatch)](https://github.com/d3/d3-dispatch/blob/master/README.md)\n\nRather than decorating the *dispatch* object with each event type, the dispatch object now exposes generic [*dispatch*.call](https://github.com/d3/d3-dispatch/blob/master/README.md#dispatch_call) and [*dispatch*.apply](https://github.com/d3/d3-dispatch/blob/master/README.md#dispatch_apply) methods which take the *type* string as the first argument. For example, in D3 3.x, you might say:\n\n```js\ndispatcher.foo.call(that, \"Hello, Foo!\");\n```\n\nTo dispatch a *foo* event in D3 4.0, you’d say:\n\n```js\ndispatcher.call(\"foo\", that, \"Hello, Foo!\");\n```\n\nThe [*dispatch*.on](https://github.com/d3/d3-dispatch/blob/master/README.md#dispatch_on) method now accepts multiple typenames, allowing you to add or remove listeners for multiple events simultaneously. For example, to send both *foo* and *bar* events to the same listener:\n\n```js\ndispatcher.on(\"foo bar\", function(message) {\n  console.log(message);\n});\n```\n\nThis matches the new behavior of [*selection*.on](https://github.com/d3/d3-selection/blob/master/README.md#selection_on) in [d3-selection](#selections-d3-selection). The *dispatch*.on method now validates that the specifier *listener* is a function, rather than throwing an error in the future.\n\nThe new implementation d3.dispatch is faster, using fewer closures to improve performance. There’s also a new [*dispatch*.copy](https://github.com/d3/d3-dispatch/blob/master/README.md#dispatch_copy) method for making a copy of a dispatcher; this is used by [d3-transition](#transitions-d3-transition) to improve the performance of transitions in the common case where all elements in a transition have the same transition event listeners.\n\n## [Dragging (d3-drag)](https://github.com/d3/d3-drag/blob/master/README.md)\n\nThe drag behavior d3.behavior.drag has been renamed to d3.drag. The *drag*.origin method has been replaced by [*drag*.subject](https://github.com/d3/d3-drag/blob/master/README.md#drag_subject), which allows you to define the thing being dragged at the start of a drag gesture. This is particularly useful with Canvas, where draggable objects typically share a Canvas element (as opposed to SVG, where draggable objects typically have distinct DOM elements); see the [circle dragging example](https://bl.ocks.org/mbostock/444757cc9f0fde320a5f469cd36860f4).\n\nA new [*drag*.container](https://github.com/d3/d3-drag/blob/master/README.md#drag_container) method lets you override the parent element that defines the drag gesture coordinate system. This defaults to the parent node of the element to which the drag behavior was applied. For dragging on Canvas elements, you probably want to use the Canvas element as the container.\n\n[Drag events](https://github.com/d3/d3-drag/blob/master/README.md#drag-events) now expose an [*event*.on](https://github.com/d3/d3-drag/blob/master/README.md#event_on) method for registering temporary listeners for duration of the current drag gesture; these listeners can capture state for the current gesture, such as the thing being dragged. A new *event*.active property lets you detect whether multiple (multitouch) drag gestures are active concurrently. The *dragstart* and *dragend* events have been renamed to *start* and *end*. By default, drag behaviors now ignore right-clicks intended for the context menu; use [*drag*.filter](https://github.com/d3/d3-drag/blob/master/README.md#drag_filter) to control which events are ignored. The drag behavior also ignores emulated mouse events on iOS. The drag behavior now consumes handled events, making it easier to combine with other interactive behaviors such as [zooming](#zooming-d3-zoom).\n\nThe new [d3.dragEnable](https://github.com/d3/d3-drag/blob/master/README.md#dragEnable) and [d3.dragDisable](https://github.com/d3/d3-drag/blob/master/README.md#dragDisable) methods provide a low-level API for implementing drag gestures across browsers and devices. These methods are also used by other D3 components, such as the [brush](#brushes-d3-brush).\n\n## [Delimiter-Separated Values (d3-dsv)](https://github.com/d3/d3-dsv/blob/master/README.md)\n\nPursuant to the great namespace flattening, various CSV and TSV methods have new names:\n\n* d3.csv.parse ↦ [d3.csvParse](https://github.com/d3/d3-dsv/blob/master/README.md#csvParse)\n* d3.csv.parseRows ↦ [d3.csvParseRows](https://github.com/d3/d3-dsv/blob/master/README.md#csvParseRows)\n* d3.csv.format ↦ [d3.csvFormat](https://github.com/d3/d3-dsv/blob/master/README.md#csvFormat)\n* d3.csv.formatRows ↦ [d3.csvFormatRows](https://github.com/d3/d3-dsv/blob/master/README.md#csvFormatRows)\n* d3.tsv.parse ↦ [d3.tsvParse](https://github.com/d3/d3-dsv/blob/master/README.md#tsvParse)\n* d3.tsv.parseRows ↦ [d3.tsvParseRows](https://github.com/d3/d3-dsv/blob/master/README.md#tsvParseRows)\n* d3.tsv.format ↦ [d3.tsvFormat](https://github.com/d3/d3-dsv/blob/master/README.md#tsvFormat)\n* d3.tsv.formatRows ↦ [d3.tsvFormatRows](https://github.com/d3/d3-dsv/blob/master/README.md#tsvFormatRows)\n\nThe [d3.csv](https://github.com/d3/d3-request/blob/master/README.md#csv) and [d3.tsv](https://github.com/d3/d3-request/blob/master/README.md#tsv) methods for loading files of the corresponding formats have not been renamed, however! Those are defined in [d3-request](#requests-d3-request).There’s no longer a d3.dsv method, which served the triple purpose of defining a DSV formatter, a DSV parser and a DSV requestor; instead, there’s just [d3.dsvFormat](https://github.com/d3/d3-dsv/blob/master/README.md#dsvFormat) which you can use to define a DSV formatter and parser. You can use [*request*.response](https://github.com/d3/d3-request/blob/master/README.md#request_response) to make a request and then parse the response body, or just use [d3.text](https://github.com/d3/d3-request/blob/master/README.md#text).\n\nThe [*dsv*.parse](https://github.com/d3/d3-dsv/blob/master/README.md#dsv_parse) method now exposes the column names and their input order as *data*.columns. For example:\n\n```js\nd3.csv(\"cars.csv\", function(error, data) {\n  if (error) throw error;\n  console.log(data.columns); // [\"Year\", \"Make\", \"Model\", \"Length\"]\n});\n```\n\nYou can likewise pass an optional array of column names to [*dsv*.format](https://github.com/d3/d3-dsv/blob/master/README.md#dsv_format) to format only a subset of columns, or to specify the column order explicitly:\n\n```js\nvar string = d3.csvFormat(data, [\"Year\", \"Model\", \"Length\"]);\n```\n\nThe parser is a bit faster and the formatter is a bit more robust: inputs are coerced to strings before formatting, fixing an obscure crash, and deprecated support for falling back to [*dsv*.formatRows](https://github.com/d3/d3-dsv/blob/master/README.md#dsv_formatRows) when the input *data* is an array of arrays has been removed.\n\n## [Easings (d3-ease)](https://github.com/d3/d3-ease/blob/master/README.md)\n\nD3 3.x used strings, such as “cubic-in-out”, to identify easing methods; these strings could be passed to d3.ease or *transition*.ease. D3 4.0 uses symbols instead, such as [d3.easeCubicInOut](https://github.com/d3/d3-ease/blob/master/README.md#easeCubicInOut). Symbols are simpler and cleaner. They work well with Rollup to produce smaller custom bundles. You can still define your own custom easing function, too, if desired. Here’s the full list of equivalents:\n\n* linear ↦ [d3.easeLinear](https://github.com/d3/d3-ease/blob/master/README.md#easeLinear)¹\n* linear-in ↦ [d3.easeLinear](https://github.com/d3/d3-ease/blob/master/README.md#easeLinear)¹\n* linear-out ↦ [d3.easeLinear](https://github.com/d3/d3-ease/blob/master/README.md#easeLinear)¹\n* linear-in-out ↦ [d3.easeLinear](https://github.com/d3/d3-ease/blob/master/README.md#easeLinear)¹\n* linear-out-in ↦ [d3.easeLinear](https://github.com/d3/d3-ease/blob/master/README.md#easeLinear)¹\n* poly-in ↦ [d3.easePolyIn](https://github.com/d3/d3-ease/blob/master/README.md#easePolyIn)\n* poly-out ↦ [d3.easePolyOut](https://github.com/d3/d3-ease/blob/master/README.md#easePolyOut)\n* poly-in-out ↦ [d3.easePolyInOut](https://github.com/d3/d3-ease/blob/master/README.md#easePolyInOut)\n* poly-out-in ↦ REMOVED²\n* quad-in ↦ [d3.easeQuadIn](https://github.com/d3/d3-ease/blob/master/README.md#easeQuadIn)\n* quad-out ↦ [d3.easeQuadOut](https://github.com/d3/d3-ease/blob/master/README.md#easeQuadOut)\n* quad-in-out ↦ [d3.easeQuadInOut](https://github.com/d3/d3-ease/blob/master/README.md#easeQuadInOut)\n* quad-out-in ↦ REMOVED²\n* cubic-in ↦ [d3.easeCubicIn](https://github.com/d3/d3-ease/blob/master/README.md#easeCubicIn)\n* cubic-out ↦ [d3.easeCubicOut](https://github.com/d3/d3-ease/blob/master/README.md#easeCubicOut)\n* cubic-in-out ↦ [d3.easeCubicInOut](https://github.com/d3/d3-ease/blob/master/README.md#easeCubicInOut)\n* cubic-out-in ↦ REMOVED²\n* sin-in ↦ [d3.easeSinIn](https://github.com/d3/d3-ease/blob/master/README.md#easeSinIn)\n* sin-out ↦ [d3.easeSinOut](https://github.com/d3/d3-ease/blob/master/README.md#easeSinOut)\n* sin-in-out ↦ [d3.easeSinInOut](https://github.com/d3/d3-ease/blob/master/README.md#easeSinInOut)\n* sin-out-in ↦ REMOVED²\n* exp-in ↦ [d3.easeExpIn](https://github.com/d3/d3-ease/blob/master/README.md#easeExpIn)\n* exp-out ↦ [d3.easeExpOut](https://github.com/d3/d3-ease/blob/master/README.md#easeExpOut)\n* exp-in-out ↦ [d3.easeExpInOut](https://github.com/d3/d3-ease/blob/master/README.md#easeExpInOut)\n* exp-out-in ↦ REMOVED²\n* circle-in ↦ [d3.easeCircleIn](https://github.com/d3/d3-ease/blob/master/README.md#easeCircleIn)\n* circle-out ↦ [d3.easeCircleOut](https://github.com/d3/d3-ease/blob/master/README.md#easeCircleOut)\n* circle-in-out ↦ [d3.easeCircleInOut](https://github.com/d3/d3-ease/blob/master/README.md#easeCircleInOut)\n* circle-out-in ↦ REMOVED²\n* elastic-in ↦ [d3.easeElasticOut](https://github.com/d3/d3-ease/blob/master/README.md#easeElasticOut)²\n* elastic-out ↦ [d3.easeElasticIn](https://github.com/d3/d3-ease/blob/master/README.md#easeElasticIn)²\n* elastic-in-out ↦ REMOVED²\n* elastic-out-in ↦ [d3.easeElasticInOut](https://github.com/d3/d3-ease/blob/master/README.md#easeElasticInOut)²\n* back-in ↦ [d3.easeBackIn](https://github.com/d3/d3-ease/blob/master/README.md#easeBackIn)\n* back-out ↦ [d3.easeBackOut](https://github.com/d3/d3-ease/blob/master/README.md#easeBackOut)\n* back-in-out ↦ [d3.easeBackInOut](https://github.com/d3/d3-ease/blob/master/README.md#easeBackInOut)\n* back-out-in ↦ REMOVED²\n* bounce-in ↦ [d3.easeBounceOut](https://github.com/d3/d3-ease/blob/master/README.md#easeBounceOut)²\n* bounce-out ↦ [d3.easeBounceIn](https://github.com/d3/d3-ease/blob/master/README.md#easeBounceIn)²\n* bounce-in-out ↦ REMOVED²\n* bounce-out-in ↦ [d3.easeBounceInOut](https://github.com/d3/d3-ease/blob/master/README.md#easeBounceInOut)²\n\n¹ The -in, -out and -in-out variants of linear easing are identical, so there’s just d3.easeLinear.\n<br>² Elastic and bounce easing were inadvertently reversed in 3.x, so 4.0 eliminates -out-in easing!\n\nFor convenience, there are also default aliases for each easing method. For example, [d3.easeCubic](https://github.com/d3/d3-ease/blob/master/README.md#easeCubic) is an alias for [d3.easeCubicInOut](https://github.com/d3/d3-ease/blob/master/README.md#easeCubicInOut). Most default to -in-out; the exceptions are [d3.easeBounce](https://github.com/d3/d3-ease/blob/master/README.md#easeBounce) and [d3.easeElastic](https://github.com/d3/d3-ease/blob/master/README.md#easeElastic), which default to -out.\n\nRather than pass optional arguments to d3.ease or *transition*.ease, parameterizable easing functions now have named parameters: [*poly*.exponent](https://github.com/d3/d3-ease/blob/master/README.md#poly_exponent), [*elastic*.amplitude](https://github.com/d3/d3-ease/blob/master/README.md#elastic_amplitude), [*elastic*.period](https://github.com/d3/d3-ease/blob/master/README.md#elastic_period) and [*back*.overshoot](https://github.com/d3/d3-ease/blob/master/README.md#back_overshoot). For example, in D3 3.x you might say:\n\n```js\nvar e = d3.ease(\"elastic-out-in\", 1.2);\n```\n\nThe equivalent in D3 4.0 is:\n\n```js\nvar e = d3.easeElastic.amplitude(1.2);\n```\n\nMany of the easing functions have been optimized for performance and accuracy. Several bugs have been fixed, as well, such as the interpretation of the overshoot parameter for back easing, and the period parameter for elastic easing. Also, [d3-transition](#transitions-d3-transition) now explicitly guarantees that the last tick of the transition happens at exactly *t* = 1, avoiding floating point errors in some easing functions.\n\nThere’s now a nice [visual reference](https://github.com/d3/d3-ease/blob/master/README.md) and an [animated reference](https://bl.ocks.org/mbostock/248bac3b8e354a9103c4) to the new easing functions, too!\n\n## [Forces (d3-force)](https://github.com/d3/d3-force/blob/master/README.md)\n\nThe force layout d3.layout.force has been renamed to d3.forceSimulation. The force simulation now uses [velocity Verlet integration](https://en.wikipedia.org/wiki/Verlet_integration#Velocity_Verlet) rather than position Verlet, tracking the nodes’ positions (*node*.x, *node*.y) and velocities (*node*.vx, *node*.vy) rather than their previous positions (*node*.px, *node*.py).\n\nRather than hard-coding a set of built-in forces, the force simulation is now extensible: you specify which forces you want! The approach affords greater flexibility through composition. The new forces are more flexible, too: force parameters can typically be configured per-node or per-link. There are separate positioning forces for [*x*](https://github.com/d3/d3-force/blob/master/README.md#forceX) and [*y*](https://github.com/d3/d3-force/blob/master/README.md#forceY) that replace *force*.gravity; [*x*.x](https://github.com/d3/d3-force/blob/master/README.md#x_x) and [*y*.y](https://github.com/d3/d3-force/blob/master/README.md#y_y) replace *force*.size. The new [link force](https://github.com/d3/d3-force/blob/master/README.md#forceLink) replaces *force*.linkStrength and employs better default heuristics to improve stability. The new [many-body force](https://github.com/d3/d3-force/blob/master/README.md#forceManyBody) replaces *force*.charge and supports a new [minimum-distance parameter](https://github.com/d3/d3-force/blob/master/README.md#manyBody_distanceMin) and performance improvements thanks to 4.0’s [new quadtrees](#quadtrees-d3-quadtree). There are also brand-new forces for [centering nodes](https://github.com/d3/d3-force/blob/master/README.md#forceCenter) and [collision resolution](https://github.com/d3/d3-force/blob/master/README.md#forceCollision).\n\nThe new forces and simulation have been carefully crafted to avoid nondeterminism. Rather than initializing nodes randomly, if the nodes do not have preset positions, they are placed in a phyllotaxis pattern:\n\n<img alt=\"Phyllotaxis\" src=\"https://raw.githubusercontent.com/d3/d3-force/master/img/phyllotaxis.png\" width=\"420\" height=\"219\">\n\nRandom jitter is still needed to resolve link, collision and many-body forces if there are coincident nodes, but at least in the common case, the force simulation (and the resulting force-directed graph layout) is now consistent across browsers and reloads. D3 no longer plays dice!\n\nThe force simulation has several new methods for greater control over heating, such as [*simulation*.alphaMin](https://github.com/d3/d3-force/blob/master/README.md#simulation_alphaMin) and [*simulation*.alphaDecay](https://github.com/d3/d3-force/blob/master/README.md#simulation_alphaDecay), and the internal timer. Calling [*simulation*.alpha](https://github.com/d3/d3-force/blob/master/README.md#simulation_alpha) now has no effect on the internal timer, which is controlled independently via [*simulation*.stop](https://github.com/d3/d3-force/blob/master/README.md#simulation_stop) and [*simulation*.restart](https://github.com/d3/d3-force/blob/master/README.md#simulation_restart). The force layout’s internal timer now starts automatically on creation, removing *force*.start. As in 3.x, you can advance the simulation manually using [*simulation*.tick](https://github.com/d3/d3-force/blob/master/README.md#simulation_tick). The *force*.friction parameter is replaced by *simulation*.velocityDecay. A new [*simulation*.alphaTarget](https://github.com/d3/d3-force/blob/master/README.md#simulation_alphaTarget) method allows you to set the desired alpha (temperature) of the simulation, such that the simulation can be smoothly reheated during interaction, and then smoothly cooled again. This improves the stability of the graph during interaction.\n\nThe force layout no longer depends on the [drag behavior](#dragging-d3-drag), though you can certainly create [draggable force-directed graphs](https://bl.ocks.org/mbostock/ad70335eeef6d167bc36fd3c04378048)! Set *node*.fx and *node*.fy to fix a node’s position. As an alternative to a [Voronoi](#voronoi-d3-voronoi) SVG overlay, you can now use [*simulation*.find](https://github.com/d3/d3-force/blob/master/README.md#simulation_find) to find the closest node to a pointer.\n\n## [Number Formats (d3-format)](https://github.com/d3/d3-format/blob/master/README.md)\n\nIf a precision is not specified, the formatting behavior has changed: there is now a default precision of 6 for all directives except *none*, which defaults to 12. In 3.x, if you did not specify a precision, the number was formatted using its shortest unique representation (per [*number*.toString](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/toString)); this could lead to unexpected digits due to [floating point math](http://0.30000000000000004.com/). The new default precision in 4.0 produces more consistent results:\n\n```js\nvar f = d3.format(\"e\");\nf(42);        // \"4.200000e+1\"\nf(0.1 + 0.2); // \"3.000000e-1\"\n```\n\nTo trim insignificant trailing zeroes, use the *none* directive, which is similar `g`. For example:\n\n```js\nvar f = d3.format(\".3\");\nf(0.12345);   // \"0.123\"\nf(0.10000);   // \"0.1\"\nf(0.1 + 0.2); // \"0.3\"\n```\n\nUnder the hood, number formatting has improved accuracy with very large and very small numbers by using [*number*.toExponential](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/toExponential) rather than [Math.log](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/log) to extract the mantissa and exponent. Negative zero (-0, an IEEE 754 construct) and very small numbers that round to zero are now formatted as unsigned zero. The inherently unsafe d3.round method has been removed, along with d3.requote.\n\nThe [d3.formatPrefix](https://github.com/d3/d3-format/blob/master/README.md#formatPrefix) method has been changed. Rather than returning an SI-prefix string, it returns an SI-prefix format function for a given *specifier* and reference *value*. For example, to format thousands:\n\n```js\nvar f = d3.formatPrefix(\",.0\", 1e3);\nf(1e3); // \"1k\"\nf(1e4); // \"10k\"\nf(1e5); // \"100k\"\nf(1e6); // \"1,000k\"\n```\n\nUnlike the `s` format directive, d3.formatPrefix always employs the same SI-prefix, producing consistent results:\n\n```js\nvar f = d3.format(\".0s\");\nf(1e3); // \"1k\"\nf(1e4); // \"10k\"\nf(1e5); // \"100k\"\nf(1e6); // \"1M\"\n```\n\nThe new `(` sign option uses parentheses for negative values. This is particularly useful in conjunction with `$`. For example:\n\n```js\nd3.format(\"+.0f\")(-42);  // \"-42\"\nd3.format(\"(.0f\")(-42);  // \"(42)\"\nd3.format(\"+$.0f\")(-42); // \"-$42\"\nd3.format(\"($.0f\")(-42); // \"($42)\"\n```\n\nThe new `=` align option places any sign and symbol to the left of any padding:\n\n```js\nd3.format(\">6d\")(-42);  // \"   -42\"\nd3.format(\"=6d\")(-42);  // \"-   42\"\nd3.format(\">(6d\")(-42); // \"  (42)\"\nd3.format(\"=(6d\")(-42); // \"(  42)\"\n```\n\nThe `b`, `o`, `d` and `x` directives now round to the nearest integer, rather than returning the empty string for non-integers:\n\n```js\nd3.format(\"b\")(41.9); // \"101010\"\nd3.format(\"o\")(41.9); // \"52\"\nd3.format(\"d\")(41.9); // \"42\"\nd3.format(\"x\")(41.9); // \"2a\"\n```\n\nThe `c` directive is now for character data (*i.e.*, literal strings), not for character codes. The is useful if you just want to apply padding and alignment and don’t care about formatting numbers. For example, the infamous [left-pad](http://blog.npmjs.org/post/141577284765/kik-left-pad-and-npm) (as well as center- and right-pad!) can be conveniently implemented as:\n\n```js\nd3.format(\">10c\")(\"foo\"); // \"       foo\"\nd3.format(\"^10c\")(\"foo\"); // \"   foo    \"\nd3.format(\"<10c\")(\"foo\"); // \"foo       \"\n```\n\nThere are several new methods for computing suggested decimal precisions; these are used by [d3-scale](#scales-d3-scale) for tick formatting, and are helpful for implementing custom number formats: [d3.precisionFixed](https://github.com/d3/d3-format/blob/master/README.md#precisionFixed), [d3.precisionPrefix](https://github.com/d3/d3-format/blob/master/README.md#precisionPrefix) and [d3.precisionRound](https://github.com/d3/d3-format/blob/master/README.md#precisionRound). There’s also a new [d3.formatSpecifier](https://github.com/d3/d3-format/blob/master/README.md#formatSpecifier) method for parsing, validating and debugging format specifiers; it’s also good for deriving related format specifiers, such as when you want to substitute the precision automatically.\n\nYou can now set the default locale using [d3.formatDefaultLocale](https://github.com/d3/d3-format/blob/master/README.md#formatDefaultLocale)! The locales are published as [JSON](https://github.com/d3/d3-request/blob/master/README.md#json) to [npm](https://unpkg.com/d3-format/locale/).\n\n## [Geographies (d3-geo)](https://github.com/d3/d3-geo/blob/master/README.md)\n\nPursuant to the great namespace flattening, various methods have new names:\n\n* d3.geo.graticule ↦ [d3.geoGraticule](https://github.com/d3/d3-geo/blob/master/README.md#geoGraticule)\n* d3.geo.circle ↦ [d3.geoCircle](https://github.com/d3/d3-geo/blob/master/README.md#geoCircle)\n* d3.geo.area ↦ [d3.geoArea](https://github.com/d3/d3-geo/blob/master/README.md#geoArea)\n* d3.geo.bounds ↦ [d3.geoBounds](https://github.com/d3/d3-geo/blob/master/README.md#geoBounds)\n* d3.geo.centroid ↦ [d3.geoCentroid](https://github.com/d3/d3-geo/blob/master/README.md#geoCentroid)\n* d3.geo.distance ↦ [d3.geoDistance](https://github.com/d3/d3-geo/blob/master/README.md#geoDistance)\n* d3.geo.interpolate ↦ [d3.geoInterpolate](https://github.com/d3/d3-geo/blob/master/README.md#geoInterpolate)\n* d3.geo.length ↦ [d3.geoLength](https://github.com/d3/d3-geo/blob/master/README.md#geoLength)\n* d3.geo.rotation ↦ [d3.geoRotation](https://github.com/d3/d3-geo/blob/master/README.md#geoRotation)\n* d3.geo.stream ↦ [d3.geoStream](https://github.com/d3/d3-geo/blob/master/README.md#geoStream)\n* d3.geo.path ↦ [d3.geoPath](https://github.com/d3/d3-geo/blob/master/README.md#geoPath)\n* d3.geo.projection ↦ [d3.geoProjection](https://github.com/d3/d3-geo/blob/master/README.md#geoProjection)\n* d3.geo.projectionMutator ↦ [d3.geoProjectionMutator](https://github.com/d3/d3-geo/blob/master/README.md#geoProjectionMutator)\n* d3.geo.albers ↦ [d3.geoAlbers](https://github.com/d3/d3-geo/blob/master/README.md#geoAlbers)\n* d3.geo.albersUsa ↦ [d3.geoAlbersUsa](https://github.com/d3/d3-geo/blob/master/README.md#geoAlbersUsa)\n* d3.geo.azimuthalEqualArea ↦ [d3.geoAzimuthalEqualArea](https://github.com/d3/d3-geo/blob/master/README.md#geoAzimuthalEqualArea)\n* d3.geo.azimuthalEquidistant ↦ [d3.geoAzimuthalEquidistant](https://github.com/d3/d3-geo/blob/master/README.md#geoAzimuthalEquidistant)\n* d3.geo.conicConformal ↦ [d3.geoConicConformal](https://github.com/d3/d3-geo/blob/master/README.md#geoConicConformal)\n* d3.geo.conicEqualArea ↦ [d3.geoConicEqualArea](https://github.com/d3/d3-geo/blob/master/README.md#geoConicEqualArea)\n* d3.geo.conicEquidistant ↦ [d3.geoConicEquidistant](https://github.com/d3/d3-geo/blob/master/README.md#geoConicEquidistant)\n* d3.geo.equirectangular ↦ [d3.geoEquirectangular](https://github.com/d3/d3-geo/blob/master/README.md#geoEquirectangular)\n* d3.geo.gnomonic ↦ [d3.geoGnomonic](https://github.com/d3/d3-geo/blob/master/README.md#geoGnomonic)\n* d3.geo.mercator ↦ [d3.geoMercator](https://github.com/d3/d3-geo/blob/master/README.md#geoMercator)\n* d3.geo.orthographic ↦ [d3.geoOrthographic](https://github.com/d3/d3-geo/blob/master/README.md#geoOrthographic)\n* d3.geo.stereographic ↦ [d3.geoStereographic](https://github.com/d3/d3-geo/blob/master/README.md#geoStereographic)\n* d3.geo.transverseMercator ↦ [d3.geoTransverseMercator](https://github.com/d3/d3-geo/blob/master/README.md#geoTransverseMercator)\n\nAlso renamed for consistency:\n\n* *circle*.origin ↦ [*circle*.center](https://github.com/d3/d3-geo/blob/master/README.md#circle_center)\n* *circle*.angle ↦ [*circle*.radius](https://github.com/d3/d3-geo/blob/master/README.md#circle_radius)\n* *graticule*.majorExtent ↦ [*graticule*.extentMajor](https://github.com/d3/d3-geo/blob/master/README.md#graticule_extentMajor)\n* *graticule*.minorExtent ↦ [*graticule*.extentMinor](https://github.com/d3/d3-geo/blob/master/README.md#graticule_extentMinor)\n* *graticule*.majorStep ↦ [*graticule*.stepMajor](https://github.com/d3/d3-geo/blob/master/README.md#graticule_stepMajor)\n* *graticule*.minorStep ↦ [*graticule*.stepMinor](https://github.com/d3/d3-geo/blob/master/README.md#graticule_stepMinor)\n\nProjections now have more appropriate defaults. For example, [d3.geoOrthographic](https://github.com/d3/d3-geo/blob/master/README.md#geoOrthographic) has a 90° clip angle by default, showing only the front hemisphere, and [d3.geoGnomonic](https://github.com/d3/d3-geo/blob/master/README.md#geoGnomonic) has a default 60° clip angle. The default [projection](https://github.com/d3/d3-geo/blob/master/README.md#path_projection) for [d3.geoPath](https://github.com/d3/d3-geo/blob/master/README.md#geoPath) is now null rather than [d3.geoAlbersUsa](https://github.com/d3/d3-geo/blob/master/README.md#geoAlbersUsa); a null projection is used with [pre-projected geometry](https://bl.ocks.org/mbostock/5557726) and is typically faster to render.\n\n“Fallback projections”—when you pass a function rather than a projection to [*path*.projection](https://github.com/d3/d3-geo/blob/master/README.md#path_projection)—are no longer supported. For geographic projections, use [d3.geoProjection](https://github.com/d3/d3-geo/blob/master/README.md#geoProjection) or [d3.geoProjectionMutator](https://github.com/d3/d3-geo/blob/master/README.md#geoProjectionMutator) to define a custom projection. For arbitrary geometry transformations, implement the [stream interface](https://github.com/d3/d3-geo/blob/master/README.md#streams); see also [d3.geoTransform](https://github.com/d3/d3-geo/blob/master/README.md#geoTransform). The “raw” projections (e.g., d3.geo.equirectangular.raw) are no longer exported.\n\n## [Hierarchies (d3-hierarchy)](https://github.com/d3/d3-hierarchy/blob/master/README.md)\n\nPursuant to the great namespace flattening:\n\n* d3.layout.cluster ↦ [d3.cluster](https://github.com/d3/d3-hierarchy/blob/master/README.md#cluster)\n* d3.layout.hierarchy ↦ [d3.hierarchy](https://github.com/d3/d3-hierarchy/blob/master/README.md#hierarchy)\n* d3.layout.pack ↦ [d3.pack](https://github.com/d3/d3-hierarchy/blob/master/README.md#pack)\n* d3.layout.partition ↦ [d3.partition](https://github.com/d3/d3-hierarchy/blob/master/README.md#partition)\n* d3.layout.tree ↦ [d3.tree](https://github.com/d3/d3-hierarchy/blob/master/README.md#tree)\n* d3.layout.treemap ↦ [d3.treemap](https://github.com/d3/d3-hierarchy/blob/master/README.md#treemap)\n\nAs an alternative to using JSON to represent hierarchical data (such as the “flare.json format” used by many D3 examples), the new [d3.stratify](https://github.com/d3/d3-hierarchy/blob/master/README.md#stratify) operator simplifies the conversion of tabular data to hierarchical data! This is convenient if you already have data in a tabular format, such as the result of a SQL query or a CSV file:\n\n```\nname,parent\nEve,\nCain,Eve\nSeth,Eve\nEnos,Seth\nNoam,Seth\nAbel,Eve\nAwan,Eve\nEnoch,Awan\nAzura,Eve\n```\n\nTo convert this to a root [*node*](https://github.com/d3/d3-hierarchy/blob/master/README.md#hierarchy):\n\n```js\nvar root = d3.stratify()\n    .id(function(d) { return d.name; })\n    .parentId(function(d) { return d.parent; })\n    (nodes);\n```\n\nThe resulting *root* can be passed to [d3.tree](https://github.com/d3/d3-hierarchy/blob/master/README.md#tree) to produce a tree diagram like this:\n\n<img src=\"https://raw.githubusercontent.com/d3/d3/master/img/stratify.png\" width=\"298\" height=\"137\">\n\nRoot nodes can also be created from JSON data using [d3.hierarchy](https://github.com/d3/d3-hierarchy/blob/master/README.md#hierarchy). The hierarchy layouts now take these root nodes as input rather than operating directly on JSON data, which helps to provide a cleaner separation between the input data and the computed layout. (For example, use [*node*.copy](https://github.com/d3/d3-hierarchy/blob/master/README.md#node_copy) to isolate layout changes.) It also simplifies the API: rather than each hierarchy layout needing to implement value and sorting accessors, there are now generic [*node*.sum](https://github.com/d3/d3-hierarchy/blob/master/README.md#node_sum) and [*node*.sort](https://github.com/d3/d3-hierarchy/blob/master/README.md#node_sort) methods that work with any hierarchy layout.\n\nThe new d3.hierarchy API also provides a richer set of methods for manipulating hierarchical data. For example, to generate an array of all nodes in topological order, use [*node*.descendants](https://github.com/d3/d3-hierarchy/blob/master/README.md#node_descendants); for just leaf nodes, use [*node*.leaves](https://github.com/d3/d3-hierarchy/blob/master/README.md#node_leaves). To highlight the ancestors of a given *node* on mouseover, use [*node*.ancestors](https://github.com/d3/d3-hierarchy/blob/master/README.md#node_ancestors). To generate an array of {source, target} links for a given hierarchy, use [*node*.links](https://github.com/d3/d3-hierarchy/blob/master/README.md#node_links); this replaces *treemap*.links and similar methods on the other layouts. The new [*node*.path](https://github.com/d3/d3-hierarchy/blob/master/README.md#node_path) method replaces d3.layout.bundle; see also [d3.curveBundle](https://github.com/d3/d3-shape/blob/master/README.md#curveBundle) for hierarchical edge bundling.\n\nThe hierarchy layouts have been rewritten using new, non-recursive traversal methods ([*node*.each](https://github.com/d3/d3-hierarchy/blob/master/README.md#node_each), [*node*.eachAfter](https://github.com/d3/d3-hierarchy/blob/master/README.md#node_eachAfter) and [*node*.eachBefore](https://github.com/d3/d3-hierarchy/blob/master/README.md#node_eachBefore)), improving performance on large datasets. The d3.tree layout no longer uses a *node*.\\_ field to store temporary state during layout.\n\nTreemap tiling is now [extensible](https://github.com/d3/d3-hierarchy/blob/master/README.md#treemap-tiling) via [*treemap*.tile](https://github.com/d3/d3-hierarchy/blob/master/README.md#treemap_tile)! The default squarified tiling algorithm, [d3.treemapSquarify](https://github.com/d3/d3-hierarchy/blob/master/README.md#treemapSquarify), has been completely rewritten, improving performance and fixing bugs in padding and rounding. The *treemap*.sticky method has been replaced with the [d3.treemapResquarify](https://github.com/d3/d3-hierarchy/blob/master/README.md#treemapResquarify), which is identical to d3.treemapSquarify except it performs stable neighbor-preserving updates. The *treemap*.ratio method has been replaced with [*squarify*.ratio](https://github.com/d3/d3-hierarchy/blob/master/README.md#squarify_ratio). And there’s a new [d3.treemapBinary](https://github.com/d3/d3-hierarchy/blob/master/README.md#treemapBinary) for binary treemaps!\n\nTreemap padding has also been improved. The treemap now distinguishes between [outer padding](https://github.com/d3/d3-hierarchy/blob/master/README.md#treemap_paddingOuter) that separates a parent from its children, and [inner padding](https://github.com/d3/d3-hierarchy/blob/master/README.md#treemap_paddingInner) that separates adjacent siblings. You can set the [top-](https://github.com/d3/d3-hierarchy/blob/master/README.md#treemap_paddingTop), [right-](https://github.com/d3/d3-hierarchy/blob/master/README.md#treemap_paddingRight), [bottom-](https://github.com/d3/d3-hierarchy/blob/master/README.md#treemap_paddingBottom) and [left-](https://github.com/d3/d3-hierarchy/blob/master/README.md#treemap_paddingLeft)outer padding separately. There are new examples for the traditional [nested treemap](https://bl.ocks.org/mbostock/911ad09bdead40ec0061) and for Lü and Fogarty’s [cascaded treemap](https://bl.ocks.org/mbostock/f85ffb3a5ac518598043). And there’s a new example demonstrating [d3.nest with d3.treemap](https://bl.ocks.org/mbostock/2838bf53e0e65f369f476afd653663a2).\n\nThe space-filling layouts [d3.treemap](https://github.com/d3/d3-hierarchy/blob/master/README.md#treemap) and [d3.partition](https://github.com/d3/d3-hierarchy/blob/master/README.md#partition) now output *x0*, *x1*, *y0*, *y1* on each node instead of *x0*, *dx*, *y0*, *dy*. This improves accuracy by ensuring that the edges of adjacent cells are exactly equal, rather than sometimes being slightly off due to floating point math. The partition layout now supports [rounding](https://github.com/d3/d3-hierarchy/blob/master/README.md#partition_round) and [padding](https://github.com/d3/d3-hierarchy/blob/master/README.md#partition_padding).\n\nThe circle-packing layout, [d3.pack](https://github.com/d3/d3-hierarchy/blob/master/README.md#pack), has been completely rewritten to better implement Wang et al.’s algorithm, fixing major bugs and improving results! Welzl’s algorithm is now used to compute the exact [smallest enclosing circle](https://bl.ocks.org/mbostock/29c534ff0b270054a01c) for each parent, rather than the approximate answer used by Wang et al. The 3.x output is shown on the left; 4.0 is shown on the right:\n\n<img alt=\"Circle Packing in 3.x\" src=\"https://raw.githubusercontent.com/d3/d3/master/img/pack-v3.png\" width=\"420\" height=\"420\"> <img alt=\"Circle Packing in 4.0\" src=\"https://raw.githubusercontent.com/d3/d3/master/img/pack-v4.png\" width=\"420\" height=\"420\">\n\nA non-hierarchical implementation is also available as [d3.packSiblings](https://github.com/d3/d3-hierarchy/blob/master/README.md#packSiblings), and the smallest enclosing circle implementation is available as [d3.packEnclose](https://github.com/d3/d3-hierarchy/blob/master/README.md#packEnclose). [Pack padding](https://github.com/d3/d3-hierarchy/blob/master/README.md#pack_padding) now applies between a parent and its children, as well as between adjacent siblings. In addition, you can now specify padding as a function that is computed dynamically for each parent.\n\n## Internals\n\nThe d3.rebind method has been removed. (See the [3.x source](https://github.com/d3/d3/blob/v3.5.17/src/core/rebind.js).) If you want to wrap a getter-setter method, the recommend pattern is to implement a wrapper method and check the return value. For example, given a *component* that uses an internal [*dispatch*](#dispatches-d3-dispatch), *component*.on can rebind *dispatch*.on as follows:\n\n```js\ncomponent.on = function() {\n  var value = dispatch.on.apply(dispatch, arguments);\n  return value === dispatch ? component : value;\n};\n```\n\nThe d3.functor method has been removed. (See the [3.x source](https://github.com/d3/d3/blob/v3.5.17/src/core/functor.js).) If you want to promote a constant value to a function, the recommended pattern is to implement a closure that returns the constant value. If desired, you can use a helper method as follows:\n\n```js\nfunction constant(x) {\n  return function() {\n    return x;\n  };\n}\n```\n\nGiven a value *x*, to promote *x* to a function if it is not already:\n\n```js\nvar fx = typeof x === \"function\" ? x : constant(x);\n```\n\n## [Interpolators (d3-interpolate)](https://github.com/d3/d3-interpolate/blob/master/README.md)\n\nThe [d3.interpolate](https://github.com/d3/d3-interpolate/blob/master/README.md#interpolate) method no longer delegates to d3.interpolators, which has been removed; its behavior is now defined by the library. It is now slightly faster in the common case that *b* is a number. It only uses [d3.interpolateRgb](https://github.com/d3/d3-interpolate/blob/master/README.md#interpolateRgb) if *b* is a valid CSS color specifier (and not approximately one). And if the end value *b* is null, undefined, true or false, d3.interpolate now returns a constant function which always returns *b*.\n\nThe behavior of [d3.interpolateObject](https://github.com/d3/d3-interpolate/blob/master/README.md#interpolateObject) and [d3.interpolateArray](https://github.com/d3/d3-interpolate/blob/master/README.md#interpolateArray) has changed slightly with respect to properties or elements in the start value *a* that do not exist in the end value *b*: these properties and elements are now ignored, such that the ending value of the interpolator at *t* = 1 is now precisely equal to *b*. So, in 3.x:\n\n```js\nd3.interpolateObject({foo: 2, bar: 1}, {foo: 3})(0.5); // {bar: 1, foo: 2.5} in 3.x\n```\n\nWhereas in 4.0, *a*.bar is ignored:\n\n```js\nd3.interpolateObject({foo: 2, bar: 1}, {foo: 3})(0.5); // {foo: 2.5} in 4.0\n```\n\nIf *a* or *b* are undefined or not an object, they are now implicitly converted to the empty object or empty array as appropriate, rather than throwing a TypeError.\n\nThe d3.interpolateTransform interpolator has been renamed to [d3.interpolateTransformSvg](https://github.com/d3/d3-interpolate/blob/master/README.md#interpolateTransformSvg), and there is a new [d3.interpolateTransformCss](https://github.com/d3/d3-interpolate/blob/master/README.md#interpolateTransformCss) to interpolate CSS transforms! This allows [d3-transition](#transitions-d3-transition) to automatically interpolate both the SVG [transform attribute](https://www.w3.org/TR/SVG/coords.html#TransformAttribute) and the CSS [transform style property](https://www.w3.org/TR/css-transforms-1/#transform-property). (Note, however, that only 2D CSS transforms are supported.) The d3.transform method has been removed.\n\nColor space interpolators now interpolate opacity (see [d3-color](#colors-d3-color)) and return rgb(…) or rgba(…) CSS color specifier strings rather than using the RGB hexadecimal format. This is necessary to support opacity interpolation, but is also beneficial because it matches CSS computed values. When a channel in the start color *a* is undefined, color interpolators now use the corresponding channel value from the end color *b*, or *vice versa*. This logic previously applied to some channels (such as saturation in HSL), but now applies to all channels in all color spaces, and is especially useful when interpolating to or from transparent.\n\nThere are now “long” versions of cylindrical color space interpolators: [d3.interpolateHslLong](https://github.com/d3/d3-interpolate/blob/master/README.md#interpolateHslLong), [d3.interpolateHclLong](https://github.com/d3/d3-interpolate/blob/master/README.md#interpolateHclLong) and [d3.interpolateCubehelixLong](https://github.com/d3/d3-interpolate/blob/master/README.md#interpolateCubehelixLong). These interpolators use linear interpolation of hue, rather than using the shortest path around the 360° hue circle. See [d3.interpolateRainbow](https://github.com/d3/d3-scale/blob/master/README.md#interpolateRainbow) for an example. The Cubehelix color space is now supported by [d3-color](#colors-d3-color), and so there are now [d3.interpolateCubehelix](https://github.com/d3/d3-interpolate/blob/master/README.md#interpolateCubehelix) and [d3.interpolateCubehelixLong](https://github.com/d3/d3-interpolate/blob/master/README.md#interpolateCubehelixLong) interpolators.\n\n[Gamma-corrected color interpolation](https://web.archive.org/web/20160112115812/http://www.4p8.com/eric.brasseur/gamma.html) is now supported for both RGB and Cubehelix color spaces as [*interpolate*.gamma](https://github.com/d3/d3-interpolate/blob/master/README.md#interpolate_gamma). For example, to interpolate from purple to orange with a gamma of 2.2 in RGB space:\n\n```js\nvar interpolate = d3.interpolateRgb.gamma(2.2)(\"purple\", \"orange\");\n```\n\nThere are new interpolators for uniform non-rational [B-splines](https://en.wikipedia.org/wiki/B-spline)! These are useful for smoothly interpolating between an arbitrary sequence of values from *t* = 0 to *t* = 1, such as to generate a smooth color gradient from a discrete set of colors. The [d3.interpolateBasis](https://github.com/d3/d3-interpolate/blob/master/README.md#interpolateBasis) and [d3.interpolateBasisClosed](https://github.com/d3/d3-interpolate/blob/master/README.md#interpolateBasisClosed) interpolators generate one-dimensional B-splines, while [d3.interpolateRgbBasis](https://github.com/d3/d3-interpolate/blob/master/README.md#interpolateRgbBasis) and [d3.interpolateRgbBasisClosed](https://github.com/d3/d3-interpolate/blob/master/README.md#interpolateRgbBasisClosed) generate three-dimensional B-splines through RGB color space. These are used by [d3-scale-chromatic](https://github.com/d3/d3-scale-chromatic) to generate continuous color scales from ColorBrewer’s discrete color schemes, such as [PiYG](https://bl.ocks.org/mbostock/048d21cf747371b11884f75ad896e5a5).\n\nThere’s also now a [d3.quantize](https://github.com/d3/d3-interpolate/blob/master/README.md#quantize) method for generating uniformly-spaced discrete samples from a continuous interpolator. This is useful for taking one of the built-in color scales (such as [d3.interpolateViridis](https://github.com/d3/d3-scale/blob/master/README.md#interpolateViridis)) and quantizing it for use with [d3.scaleQuantize](https://github.com/d3/d3-scale/blob/master/README.md#scaleQuantize), [d3.scaleQuantile](https://github.com/d3/d3-scale/blob/master/README.md#scaleQuantile) or [d3.scaleThreshold](https://github.com/d3/d3-scale/blob/master/README.md#scaleThreshold).\n\n## [Paths (d3-path)](https://github.com/d3/d3-path/blob/master/README.md)\n\nThe [d3.path](https://github.com/d3/d3-path/blob/master/README.md#path) serializer implements the [CanvasPathMethods API](https://www.w3.org/TR/2dcontext/#canvaspathmethods), allowing you to write code that can render to either Canvas or SVG. For example, given some code that draws to a canvas:\n\n```js\nfunction drawCircle(context, radius) {\n  context.moveTo(radius, 0);\n  context.arc(0, 0, radius, 0, 2 * Math.PI);\n}\n```\n\nYou can render to SVG as follows:\n\n```js\nvar context = d3.path();\ndrawCircle(context, 40);\npathElement.setAttribute(\"d\", context.toString());\n```\n\nThe path serializer enables [d3-shape](#shapes-d3-shape) to support both Canvas and SVG; see [*line*.context](https://github.com/d3/d3-shape/blob/master/README.md#line_context) and [*area*.context](https://github.com/d3/d3-shape/blob/master/README.md#area_context), for example.\n\n## [Polygons (d3-polygon)](https://github.com/d3/d3-polygon/blob/master/README.md)\n\nThere’s no longer a d3.geom.polygon constructor; instead you just pass an array of vertices to the polygon methods. So instead of *polygon*.area and *polygon*.centroid, there’s [d3.polygonArea](https://github.com/d3/d3-polygon/blob/master/README.md#polygonArea) and [d3.polygonCentroid](https://github.com/d3/d3-polygon/blob/master/README.md#polygonCentroid). There are also new [d3.polygonContains](https://github.com/d3/d3-polygon/blob/master/README.md#polygonContains) and [d3.polygonLength](https://github.com/d3/d3-polygon/blob/master/README.md#polygonLength) methods. There’s no longer an equivalent to *polygon*.clip, but if [Sutherland–Hodgman clipping](https://en.wikipedia.org/wiki/Sutherland–Hodgman_algorithm) is needed, please [file a feature request](https://github.com/d3/d3-polygon/issues).\n\nThe d3.geom.hull operator has been simplified: instead of an operator with *hull*.x and *hull*.y accessors, there’s just the [d3.polygonHull](https://github.com/d3/d3-polygon/blob/master/README.md#polygonHull) method which takes an array of points and returns the convex hull.\n\n## [Quadtrees (d3-quadtree)](https://github.com/d3/d3-quadtree/blob/master/README.md)\n\nThe d3.geom.quadtree method has been replaced by [d3.quadtree](https://github.com/d3/d3-quadtree/blob/master/README.md#quadtree). 4.0 removes the concept of quadtree “generators” (configurable functions that build a quadtree from an array of data); there are now just quadtrees, which you can create via d3.quadtree and add data to via [*quadtree*.add](https://github.com/d3/d3-quadtree/blob/master/README.md#quadtree_add) and [*quadtree*.addAll](https://github.com/d3/d3-quadtree/blob/master/README.md#quadtree_addAll). This code in 3.x:\n\n```js\nvar quadtree = d3.geom.quadtree()\n    .extent([[0, 0], [width, height]])\n    (data);\n```\n\nCan be rewritten in 4.0 as:\n\n```js\nvar quadtree = d3.quadtree()\n    .extent([[0, 0], [width, height]])\n    .addAll(data);\n```\n\nThe new quadtree implementation is vastly improved! It is no longer recursive, avoiding stack overflows when there are large numbers of coincident points. The internal storage is now more efficient, and the implementation is also faster; constructing a quadtree of 1M normally-distributed points takes about one second in 4.0, as compared to three seconds in 3.x.\n\nThe change in [internal *node* structure](https://github.com/d3/d3-quadtree/blob/master/README.md#nodes) affects [*quadtree*.visit](https://github.com/d3/d3-quadtree/blob/master/README.md#quadtree_visit): use *node*.length to distinguish leaf nodes from internal nodes. For example, to iterate over all data in a quadtree:\n\n```js\nquadtree.visit(function(node) {\n  if (!node.length) {\n    do {\n      console.log(node.data);\n    } while (node = node.next)\n  }\n});\n```\n\nThere’s a new [*quadtree*.visitAfter](https://github.com/d3/d3-quadtree/blob/master/README.md#quadtree_visitAfter) method for visiting nodes in post-order traversal. This feature is used in [d3-force](#forces-d3-force) to implement the [Barnes–Hut approximation](https://en.wikipedia.org/wiki/Barnes–Hut_simulation).\n\nYou can now remove data from a quadtree using [*quadtree*.remove](https://github.com/d3/d3-quadtree/blob/master/README.md#quadtree_remove) and [*quadtree*.removeAll](https://github.com/d3/d3-quadtree/blob/master/README.md#quadtree_removeAll). When adding data to a quadtree, the quadtree will now expand its extent by repeated doubling if the new point is outside the existing extent of the quadtree. There are also [*quadtree*.extent](https://github.com/d3/d3-quadtree/blob/master/README.md#quadtree_extent) and [*quadtree*.cover](https://github.com/d3/d3-quadtree/blob/master/README.md#quadtree_cover) methods for explicitly expanding the extent of the quadtree after creation.\n\nQuadtrees support several new utility methods: [*quadtree*.copy](https://github.com/d3/d3-quadtree/blob/master/README.md#quadtree_copy) returns a copy of the quadtree sharing the same data; [*quadtree*.data](https://github.com/d3/d3-quadtree/blob/master/README.md#quadtree_data) generates an array of all data in the quadtree; [*quadtree*.size](https://github.com/d3/d3-quadtree/blob/master/README.md#quadtree_size) returns the number of data points in the quadtree; and [*quadtree*.root](https://github.com/d3/d3-quadtree/blob/master/README.md#quadtree_root) returns the root node, which is useful for manual traversal of the quadtree. The [*quadtree*.find](https://github.com/d3/d3-quadtree/blob/master/README.md#quadtree_find) method now takes an optional search radius, which is useful for pointer-based selection in [force-directed graphs](https://bl.ocks.org/mbostock/ad70335eeef6d167bc36fd3c04378048).\n\n## [Queues (d3-queue)](https://github.com/d3/d3-queue/blob/master/README.md)\n\nFormerly known as Queue.js and queue-async, [d3.queue](https://github.com/d3/d3-queue) is now included in the default bundle, making it easy to load data files in parallel. It has been rewritten with fewer closures to improve performance, and there are now stricter checks in place to guarantee well-defined behavior. You can now use instanceof d3.queue and inspect the queue’s internal private state.\n\n## [Random Numbers (d3-random)](https://github.com/d3/d3-random/blob/master/README.md)\n\nPursuant to the great namespace flattening, the random number generators have new names:\n\n* d3.random.normal ↦ [d3.randomNormal](https://github.com/d3/d3-random/blob/master/README.md#randomNormal)\n* d3.random.logNormal ↦ [d3.randomLogNormal](https://github.com/d3/d3-random/blob/master/README.md#randomLogNormal)\n* d3.random.bates ↦ [d3.randomBates](https://github.com/d3/d3-random/blob/master/README.md#randomBates)\n* d3.random.irwinHall ↦ [d3.randomIrwinHall](https://github.com/d3/d3-random/blob/master/README.md#randomIrwinHall)\n\nThere are also new random number generators for [exponential](https://github.com/d3/d3-random/blob/master/README.md#randomExponential) and [uniform](https://github.com/d3/d3-random/blob/master/README.md#randomUniform) distributions. The [normal](https://github.com/d3/d3-random/blob/master/README.md#randomNormal) and [log-normal](https://github.com/d3/d3-random/blob/master/README.md#randomLogNormal) random generators have been optimized.\n\n## [Requests (d3-request)](https://github.com/d3/d3-request/blob/master/README.md)\n\nThe d3.xhr method has been renamed to [d3.request](https://github.com/d3/d3-request/blob/master/README.md#request). Basic authentication is now supported using [*request*.user](https://github.com/d3/d3-request/blob/master/README.md#request_user) and [*request*.password](https://github.com/d3/d3-request/blob/master/README.md#request_password). You can now configure a timeout using [*request*.timeout](https://github.com/d3/d3-request/blob/master/README.md#request_timeout).\n\nIf an error occurs, the corresponding [ProgressEvent](https://xhr.spec.whatwg.org/#interface-progressevent) of type “error” is now passed to the error listener, rather than the [XMLHttpRequest](https://xhr.spec.whatwg.org/#interface-xmlhttprequest). Likewise, the ProgressEvent is passed to progress event listeners, rather than using [d3.event](https://github.com/d3/d3-selection/blob/master/README.md#event). If [d3.xml](https://github.com/d3/d3-request/blob/master/README.md#xml) encounters an error parsing XML, this error is now reported to error listeners rather than returning a null response.\n\nThe [d3.request](https://github.com/d3/d3-request/blob/master/README.md#request), [d3.text](https://github.com/d3/d3-request/blob/master/README.md#text) and [d3.xml](https://github.com/d3/d3-request/blob/master/README.md#xml) methods no longer take an optional mime type as the second argument; use [*request*.mimeType](https://github.com/d3/d3-request/blob/master/README.md#request_mimeType) instead. For example:\n\n```js\nd3.xml(\"file.svg\").mimeType(\"image/svg+xml\").get(function(error, svg) {\n  …\n});\n```\n\nWith the exception of [d3.html](https://github.com/d3/d3-request/blob/master/README.md#html) and [d3.xml](https://github.com/d3/d3-request/blob/master/README.md#xml), Node is now supported via [node-XMLHttpRequest](https://github.com/driverdan/node-XMLHttpRequest).\n\n## [Scales (d3-scale)](https://github.com/d3/d3-scale/blob/master/README.md)\n\nPursuant to the great namespace flattening:\n\n* d3.scale.linear ↦ [d3.scaleLinear](https://github.com/d3/d3-scale/blob/master/README.md#scaleLinear)\n* d3.scale.sqrt ↦ [d3.scaleSqrt](https://github.com/d3/d3-scale/blob/master/README.md#scaleSqrt)\n* d3.scale.pow ↦ [d3.scalePow](https://github.com/d3/d3-scale/blob/master/README.md#scalePow)\n* d3.scale.log ↦ [d3.scaleLog](https://github.com/d3/d3-scale/blob/master/README.md#scaleLog)\n* d3.scale.quantize ↦ [d3.scaleQuantize](https://github.com/d3/d3-scale/blob/master/README.md#scaleQuantize)\n* d3.scale.threshold ↦ [d3.scaleThreshold](https://github.com/d3/d3-scale/blob/master/README.md#scaleThreshold)\n* d3.scale.quantile ↦ [d3.scaleQuantile](https://github.com/d3/d3-scale/blob/master/README.md#scaleQuantile)\n* d3.scale.identity ↦ [d3.scaleIdentity](https://github.com/d3/d3-scale/blob/master/README.md#scaleIdentity)\n* d3.scale.ordinal ↦ [d3.scaleOrdinal](https://github.com/d3/d3-scale/blob/master/README.md#scaleOrdinal)\n* d3.time.scale ↦ [d3.scaleTime](https://github.com/d3/d3-scale/blob/master/README.md#scaleTime)\n* d3.time.scale.utc ↦ [d3.scaleUtc](https://github.com/d3/d3-scale/blob/master/README.md#scaleUtc)\n\nScales now generate ticks in the same order as the domain: if you have a descending domain, you now get descending ticks. This change affects the order of tick elements generated by [axes](#axes-d3-axis). For example:\n\n```js\nd3.scaleLinear().domain([10, 0]).ticks(5); // [10, 8, 6, 4, 2, 0]\n```\n\n[Log tick formatting](https://github.com/d3/d3-scale/blob/master/README.md#log_tickFormat) now assumes a default *count* of ten, not Infinity, if not specified. Log scales with  domains that span many powers (such as from 1e+3 to 1e+29) now return only one [tick](https://github.com/d3/d3-scale/blob/master/README.md#log_ticks) per power rather than returning *base* ticks per power. Non-linear quantitative scales are slightly more accurate.\n\nYou can now control whether an ordinal scale’s domain is implicitly extended when the scale is passed a value that is not already in its domain. By default, [*ordinal*.unknown](https://github.com/d3/d3-scale/blob/master/README.md#ordinal_unknown) is [d3.scaleImplicit](https://github.com/d3/d3-scale/blob/master/README.md#scaleImplicit), causing unknown values to be added to the domain:\n\n```js\nvar x = d3.scaleOrdinal()\n    .domain([0, 1])\n    .range([\"red\", \"green\", \"blue\"]);\n\nx.domain(); // [0, 1]\nx(2); // \"blue\"\nx.domain(); // [0, 1, 2]\n```\n\nBy setting *ordinal*.unknown, you instead define the output value for unknown inputs. This is particularly useful for choropleth maps where you want to assign a color to missing data.\n\n```js\nvar x = d3.scaleOrdinal()\n    .domain([0, 1])\n    .range([\"red\", \"green\", \"blue\"])\n    .unknown(undefined);\n\nx.domain(); // [0, 1]\nx(2); // undefined\nx.domain(); // [0, 1]\n```\n\nThe *ordinal*.rangeBands and *ordinal*.rangeRoundBands methods have been replaced with a new subclass of ordinal scale: [band scales](https://github.com/d3/d3-scale/blob/master/README.md#band-scales). The following code in 3.x:\n\n```js\nvar x = d3.scale.ordinal()\n    .domain([\"a\", \"b\", \"c\"])\n    .rangeBands([0, width]);\n```\n\nIs equivalent to this in 4.0:\n\n```js\nvar x = d3.scaleBand()\n    .domain([\"a\", \"b\", \"c\"])\n    .range([0, width]);\n```\n\nThe new [*band*.padding](https://github.com/d3/d3-scale/blob/master/README.md#band_padding), [*band*.paddingInner](https://github.com/d3/d3-scale/blob/master/README.md#band_paddingInner) and [*band*.paddingOuter](https://github.com/d3/d3-scale/blob/master/README.md#band_paddingOuter) methods replace the optional arguments to *ordinal*.rangeBands. The new [*band*.bandwidth](https://github.com/d3/d3-scale/blob/master/README.md#band_bandwidth) and [*band*.step](https://github.com/d3/d3-scale/blob/master/README.md#band_step) methods replace *ordinal*.rangeBand. There’s also a new [*band*.align](https://github.com/d3/d3-scale/blob/master/README.md#band_align) method which you can use to control how the extra space outside the bands is distributed, say to shift columns closer to the *y*-axis.\n\nSimilarly, the *ordinal*.rangePoints and *ordinal*.rangeRoundPoints methods have been replaced with a new subclass of ordinal scale: [point scales](https://github.com/d3/d3-scale/blob/master/README.md#point-scales). The following code in 3.x:\n\n```js\nvar x = d3.scale.ordinal()\n    .domain([\"a\", \"b\", \"c\"])\n    .rangePoints([0, width]);\n```\n\nIs equivalent to this in 4.0:\n\n```js\nvar x = d3.scalePoint()\n    .domain([\"a\", \"b\", \"c\"])\n    .range([0, width]);\n```\n\nThe new [*point*.padding](https://github.com/d3/d3-scale/blob/master/README.md#point_padding) method replaces the optional *padding* argument to *ordinal*.rangePoints. Like *ordinal*.rangeBand with *ordinal*.rangePoints, the [*point*.bandwidth](https://github.com/d3/d3-scale/blob/master/README.md#point_bandwidth) method always returns zero; a new [*point*.step](https://github.com/d3/d3-scale/blob/master/README.md#point_step) method returns the interval between adjacent points.\n\nThe [ordinal scale constructor](https://github.com/d3/d3-scale/blob/master/README.md#ordinal-scales) now takes an optional *range* for a shorter alternative to [*ordinal*.range](https://github.com/d3/d3-scale/blob/master/README.md#ordinal_range). This is especially useful now that the categorical color scales have been changed to simple arrays of colors rather than specialized ordinal scale constructors:\n\n* d3.scale.category10 ↦ [d3.schemeCategory10](https://github.com/d3/d3-scale/blob/master/README.md#schemeCategory10)\n* d3.scale.category20 ↦ [d3.schemeCategory20](https://github.com/d3/d3-scale/blob/master/README.md#schemeCategory20)\n* d3.scale.category20b ↦ [d3.schemeCategory20b](https://github.com/d3/d3-scale/blob/master/README.md#schemeCategory20b)\n* d3.scale.category20c ↦ [d3.schemeCategory20c](https://github.com/d3/d3-scale/blob/master/README.md#schemeCategory20c)\n\nThe following code in 3.x:\n\n```js\nvar color = d3.scale.category10();\n```\n\nIs equivalent to this in 4.0:\n\n```js\nvar color = d3.scaleOrdinal(d3.schemeCategory10);\n```\n\n[Sequential scales](https://github.com/d3/d3-scale/blob/master/README.md#scaleSequential), are a new class of scales with a fixed output [interpolator](https://github.com/d3/d3-scale/blob/master/README.md#sequential_interpolator) instead of a [range](https://github.com/d3/d3-scale/blob/master/README.md#continuous_range). Typically these scales are used to implement continuous sequential or diverging color schemes. Inspired by Matplotlib’s new [perceptually-motived colormaps](https://bids.github.io/colormap/), 4.0 now features [viridis](https://github.com/d3/d3-scale/blob/master/README.md#interpolateViridis), [inferno](https://github.com/d3/d3-scale/blob/master/README.md#interpolateInferno), [magma](https://github.com/d3/d3-scale/blob/master/README.md#interpolateMagma), [plasma](https://github.com/d3/d3-scale/blob/master/README.md#interpolatePlasma) interpolators for use with sequential scales. Using [d3.quantize](https://github.com/d3/d3-interpolate/blob/master/README.md#quantize), these interpolators can also be applied to [quantile](https://github.com/d3/d3-scale/blob/master/README.md#quantile-scales), [quantize](https://github.com/d3/d3-scale/blob/master/README.md#quantize-scales) and [threshold](https://github.com/d3/d3-scale/blob/master/README.md#threshold-scales) scales.\n\n[<img src=\"https://raw.githubusercontent.com/d3/d3-scale/master/img/viridis.png\" width=\"100%\" height=\"40\" alt=\"viridis\">](https://github.com/d3/d3-scale/blob/master/README.md#interpolateViridis)\n[<img src=\"https://raw.githubusercontent.com/d3/d3-scale/master/img/inferno.png\" width=\"100%\" height=\"40\" alt=\"inferno\">](https://github.com/d3/d3-scale/blob/master/README.md#interpolateInferno)\n[<img src=\"https://raw.githubusercontent.com/d3/d3-scale/master/img/magma.png\" width=\"100%\" height=\"40\" alt=\"magma\">](https://github.com/d3/d3-scale/blob/master/README.md#interpolateMagma)\n[<img src=\"https://raw.githubusercontent.com/d3/d3-scale/master/img/plasma.png\" width=\"100%\" height=\"40\" alt=\"plasma\">](https://github.com/d3/d3-scale/blob/master/README.md#interpolatePlasma)\n\n4.0 also ships new Cubehelix schemes, including [Dave Green’s default](https://github.com/d3/d3-scale/blob/master/README.md#interpolateCubehelixDefault) and a [cyclical rainbow](https://github.com/d3/d3-scale/blob/master/README.md#interpolateRainbow) inspired by [Matteo Niccoli](https://mycarta.wordpress.com/2013/02/21/perceptual-rainbow-palette-the-method/):\n\n[<img src=\"https://raw.githubusercontent.com/d3/d3-scale/master/img/cubehelix.png\" width=\"100%\" height=\"40\" alt=\"cubehelix\">](https://github.com/d3/d3-scale/blob/master/README.md#interpolateCubehelixDefault)\n[<img src=\"https://raw.githubusercontent.com/d3/d3-scale/master/img/rainbow.png\" width=\"100%\" height=\"40\" alt=\"rainbow\">](https://github.com/d3/d3-scale/blob/master/README.md#interpolateRainbow)\n[<img src=\"https://raw.githubusercontent.com/d3/d3-scale/master/img/warm.png\" width=\"100%\" height=\"40\" alt=\"warm\">](https://github.com/d3/d3-scale/blob/master/README.md#interpolateWarm)\n[<img src=\"https://raw.githubusercontent.com/d3/d3-scale/master/img/cool.png\" width=\"100%\" height=\"40\" alt=\"cool\">](https://github.com/d3/d3-scale/blob/master/README.md#interpolateCool)\n\nFor even more sequential and categorical color schemes, see [d3-scale-chromatic](https://github.com/d3/d3-scale-chromatic).\n\nFor an introduction to scales, see [Introducing d3-scale](https://medium.com/@mbostock/introducing-d3-scale-61980c51545f).\n\n## [Selections (d3-selection)](https://github.com/d3/d3-selection/blob/master/README.md)\n\nSelections no longer subclass Array using [prototype chain injection](http://perfectionkills.com/how-ecmascript-5-still-does-not-allow-to-subclass-an-array/#wrappers_prototype_chain_injection); they are now plain objects, improving performance. The internal fields (*selection*.\\_groups, *selection*.\\_parents) are private; please use the documented public API to manipulate selections. The new [*selection*.nodes](https://github.com/d3/d3-selection/blob/master/README.md#selection_nodes) method generates an array of all nodes in a selection.\n\nSelections are now immutable: the elements and parents in a selection never change. (The elements’ attributes and content will of course still be modified!) The [*selection*.sort](https://github.com/d3/d3-selection/blob/master/README.md#selection_sort) and [*selection*.data](https://github.com/d3/d3-selection/blob/master/README.md#selection_data) methods now return new selections rather than modifying the selection in-place. In addition, [*selection*.append](https://github.com/d3/d3-selection/blob/master/README.md#selection_append) no longer merges entering nodes into the update selection; use [*selection*.merge](https://github.com/d3/d3-selection/blob/master/README.md#selection_merge) to combine enter and update after a data join. For example, the following [general update pattern](https://bl.ocks.org/mbostock/a8a5baa4c4a470cda598) in 3.x:\n\n```js\nvar circle = svg.selectAll(\"circle\").data(data) // UPDATE\n    .style(\"fill\", \"blue\");\n\ncircle.exit().remove(); // EXIT\n\ncircle.enter().append(\"circle\") // ENTER; modifies UPDATE! 🌶\n    .style(\"fill\", \"green\");\n\ncircle // ENTER + UPDATE\n    .style(\"stroke\", \"black\");\n```\n\nWould be rewritten in 4.0 as:\n\n```js\nvar circle = svg.selectAll(\"circle\").data(data) // UPDATE\n    .style(\"fill\", \"blue\");\n\ncircle.exit().remove(); // EXIT\n\ncircle.enter().append(\"circle\") // ENTER\n    .style(\"fill\", \"green\")\n  .merge(circle) // ENTER + UPDATE\n    .style(\"stroke\", \"black\");\n```\n\nThis change is discussed further in [What Makes Software Good](https://medium.com/@mbostock/what-makes-software-good-943557f8a488).\n\nIn 3.x, the [*selection*.enter](https://github.com/d3/d3-selection/blob/master/README.md#selection_enter) and [*selection*.exit](https://github.com/d3/d3-selection/blob/master/README.md#selection_exit) methods were undefined until you called *selection*.data, resulting in a TypeError if you attempted to access them. In 4.0, now they simply return the empty selection if the selection has not been joined to data.\n\nIn 3.x, [*selection*.append](https://github.com/d3/d3-selection/blob/master/README.md#selection_append) would always append the new element as the last child of its parent. A little-known trick was to use [*selection*.insert](https://github.com/d3/d3-selection/blob/master/README.md#selection_insert) without specifying a *before* selector when entering nodes, causing the entering nodes to be inserted before the following element in the update selection. In 4.0, this is now the default behavior of *selection*.append; if you do not specify a *before* selector to *selection*.insert, the inserted element is appended as the last child. This change makes the general update pattern preserve the relative order of elements and data. For example, given the following DOM:\n\n```html\n<div>a</div>\n<div>b</div>\n<div>f</div>\n```\n\nAnd the following code:\n\n```js\nvar div = d3.select(\"body\").selectAll(\"div\")\n  .data([\"a\", \"b\", \"c\", \"d\", \"e\", \"f\"], function(d) { return d || this.textContent; });\n\ndiv.enter().append(\"div\")\n    .text(function(d) { return d; });\n```\n\nThe resulting DOM will be:\n\n```html\n<div>a</div>\n<div>b</div>\n<div>c</div>\n<div>d</div>\n<div>e</div>\n<div>f</div>\n```\n\nThus, the entering *c*, *d* and *e* are inserted before *f*, since *f* is the following element in the update selection. Although this behavior is sufficient to preserve order if the new data’s order is stable, if the data changes order, you must still use [*selection*.order](https://github.com/d3/d3-selection/blob/master/README.md#selection_order) to reorder elements.\n\nThere is now only one class of selection. 3.x implemented enter selections using a special class with different behavior for *enter*.append and *enter*.select; a consequence of this design was that enter selections in 3.x lacked [certain methods](https://github.com/d3/d3/issues/2043). In 4.0, enter selections are simply normal selections; they have the same methods and the same behavior. Placeholder [enter nodes](https://github.com/d3/d3-selection/blob/master/src/selection/enter.js) now implement [*node*.appendChild](https://developer.mozilla.org/en-US/docs/Web/API/Node/appendChild), [*node*.insertBefore](https://developer.mozilla.org/en-US/docs/Web/API/Node/insertBefore), [*node*.querySelector](https://developer.mozilla.org/en-US/docs/Web/API/Element/querySelector), and [*node*.querySelectorAll](https://developer.mozilla.org/en-US/docs/Web/API/Element/querySelectorAll).\n\nThe [*selection*.data](https://github.com/d3/d3-selection/blob/master/README.md#selection_data) method has been changed slightly with respect to duplicate keys. In 3.x, if multiple data had the same key, the duplicate data would be ignored and not included in enter, update or exit; in 4.0 the duplicate data is always put in the enter selection. In both 3.x and 4.0, if multiple elements have the same key, the duplicate elements are put in the exit selection. Thus, 4.0’s behavior is now symmetric for enter and exit, and the general update pattern will now produce a DOM that matches the data even if there are duplicate keys.\n\nSelections have several new methods! Use [*selection*.raise](https://github.com/d3/d3-selection/blob/master/README.md#selection_raise) to move the selected elements to the front of their siblings, so that they are drawn on top; use [*selection*.lower](https://github.com/d3/d3-selection/blob/master/README.md#selection_lower) to move them to the back. Use [*selection*.dispatch](https://github.com/d3/d3-selection/blob/master/README.md#selection_dispatch) to dispatch a [custom event](https://developer.mozilla.org/en-US/docs/Web/API/CustomEvent) to event listeners.\n\nWhen called in getter mode, [*selection*.data](https://github.com/d3/d3-selection/blob/master/README.md#selection_data) now returns the data for all elements in the selection, rather than just the data for the first group of elements. The [*selection*.call](https://github.com/d3/d3-selection/blob/master/README.md#selection_call) method no longer sets the `this` context when invoking the specified function; the *selection* is passed as the first argument to the function, so use that. The [*selection*.on](https://github.com/d3/d3-selection/blob/master/README.md#selection_on) method now accepts multiple whitespace-separated typenames, so you can add or remove multiple listeners simultaneously. For example:\n\n```js\nselection.on(\"mousedown touchstart\", function() {\n  console.log(d3.event.type);\n});\n```\n\nThe arguments passed to callback functions has changed slightly in 4.0 to be more consistent. The standard arguments are the element’s datum (*d*), the element’s index (*i*), and the element’s group (*nodes*), with *this* as the element. The slight exception to this convention is *selection*.data, which is evaluated for each group rather than each element; it is passed the group’s parent datum (*d*), the group index (*i*), and the selection’s parents (*parents*), with *this* as the group’s parent.\n\nThe new [d3.local](https://github.com/d3/d3-selection/blob/master/README.md#local-variables) provides a mechanism for defining [local variables](https://bl.ocks.org/mbostock/e1192fe405703d8321a5187350910e08): state that is bound to DOM elements, and available to any descendant element. This can be a convenient alternative to using [*selection*.each](https://github.com/d3/d3-selection/blob/master/README.md#selection_each) or storing local state in data.\n\nThe d3.ns.prefix namespace prefix map has been renamed to [d3.namespaces](https://github.com/d3/d3-selection/blob/master/README.md#namespaces), and the d3.ns.qualify method has been renamed to [d3.namespace](https://github.com/d3/d3-selection/blob/master/README.md#namespace). Several new low-level methods are now available, as well. [d3.matcher](https://github.com/d3/d3-selection/blob/master/README.md#matcher) is used internally by [*selection*.filter](https://github.com/d3/d3-selection/blob/master/README.md#selection_filter); [d3.selector](https://github.com/d3/d3-selection/blob/master/README.md#selector) is used by [*selection*.select](https://github.com/d3/d3-selection/blob/master/README.md#selection_select); [d3.selectorAll](https://github.com/d3/d3-selection/blob/master/README.md#selectorAll) is used by [*selection*.selectAll](https://github.com/d3/d3-selection/blob/master/README.md#selection_selectAll); [d3.creator](https://github.com/d3/d3-selection/blob/master/README.md#creator) is used by [*selection*.append](https://github.com/d3/d3-selection/blob/master/README.md#selection_append) and [*selection*.insert](https://github.com/d3/d3-selection/blob/master/README.md#selection_insert). The new [d3.window](https://github.com/d3/d3-selection/blob/master/README.md#window) returns the owner window for a given element, window or document. The new [d3.customEvent](https://github.com/d3/d3-selection/blob/master/README.md#customEvent) temporarily sets [d3.event](https://github.com/d3/d3-selection/blob/master/README.md#event) while invoking a function, allowing you to implement controls which dispatch custom events; this is used by [d3-drag](https://github.com/d3/d3-drag), [d3-zoom](https://github.com/d3/d3-zoom) and [d3-brush](https://github.com/d3/d3-brush).\n\nFor the sake of parsimony, the multi-value methods—where you pass an object to set multiple attributes, styles or properties simultaneously—have been extracted to [d3-selection-multi](https://github.com/d3/d3-selection-multi) and are no longer part of the default bundle. The multi-value map methods have also been renamed to plural form to reduce overload: [*selection*.attrs](https://github.com/d3/d3-selection-multi/blob/master/README.md#selection_attrs), [*selection*.styles](https://github.com/d3/d3-selection-multi/blob/master/README.md#selection_styles) and [*selection*.properties](https://github.com/d3/d3-selection-multi/blob/master/README.md#selection_properties).\n\n## [Shapes (d3-shape)](https://github.com/d3/d3-shape/blob/master/README.md)\n\nPursuant to the great namespace flattening:\n\n* d3.svg.line ↦ [d3.line](https://github.com/d3/d3-shape/blob/master/README.md#lines)\n* d3.svg.line.radial ↦ [d3.radialLine](https://github.com/d3/d3-shape/blob/master/README.md#radialLine)\n* d3.svg.area ↦ [d3.area](https://github.com/d3/d3-shape/blob/master/README.md#areas)\n* d3.svg.area.radial ↦ [d3.radialArea](https://github.com/d3/d3-shape/blob/master/README.md#radialArea)\n* d3.svg.arc ↦ [d3.arc](https://github.com/d3/d3-shape/blob/master/README.md#arcs)\n* d3.svg.symbol ↦ [d3.symbol](https://github.com/d3/d3-shape/blob/master/README.md#symbols)\n* d3.svg.symbolTypes ↦ [d3.symbolTypes](https://github.com/d3/d3-shape/blob/master/README.md#symbolTypes)\n* d3.layout.pie ↦ [d3.pie](https://github.com/d3/d3-shape/blob/master/README.md#pies)\n* d3.layout.stack ↦ [d3.stack](https://github.com/d3/d3-shape/blob/master/README.md#stacks)\n* d3.svg.diagonal ↦ REMOVED (see [d3/d3-shape#27](https://github.com/d3/d3-shape/issues/27))\n* d3.svg.diagonal.radial ↦ REMOVED\n\nShapes are no longer limited to SVG; they can now render to Canvas! Shape generators now support an optional *context*: given a [CanvasRenderingContext2D](https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D), you can render a shape as a canvas path to be filled or stroked. For example, a [canvas pie chart](https://bl.ocks.org/mbostock/8878e7fd82034f1d63cf) might use an arc generator:\n\n```js\nvar arc = d3.arc()\n    .outerRadius(radius - 10)\n    .innerRadius(0)\n    .context(context);\n```\n\nTo render an arc for a given datum *d*:\n\n```js\ncontext.beginPath();\narc(d);\ncontext.fill();\n```\n\nSee [*line*.context](https://github.com/d3/d3-shape/blob/master/README.md#line_context), [*area*.context](https://github.com/d3/d3-shape/blob/master/README.md#area_context) and [*arc*.context](https://github.com/d3/d3-shape/blob/master/README.md#arc_context) for more. Under the hood, shapes use [d3-path](#paths-d3-path) to serialize canvas path methods to SVG path data when the context is null; thus, shapes are optimized for rendering to canvas. You can also now derive lines from areas. The line shares most of the same accessors, such as [*line*.defined](https://github.com/d3/d3-shape/blob/master/README.md#line_defined) and [*line*.curve](https://github.com/d3/d3-shape/blob/master/README.md#line_curve), with the area from which it is derived. For example, to render the topline of an area, use [*area*.lineY1](https://github.com/d3/d3-shape/blob/master/README.md#area_lineY1); for the baseline, use [*area*.lineY0](https://github.com/d3/d3-shape/blob/master/README.md#area_lineY0).\n\n4.0 introduces a new curve API for specifying how line and area shapes interpolate between data points. The *line*.interpolate and *area*.interpolate methods have been replaced with [*line*.curve](https://github.com/d3/d3-shape/blob/master/README.md#line_curve) and [*area*.curve](https://github.com/d3/d3-shape/blob/master/README.md#area_curve). Curves are implemented using the [curve interface](https://github.com/d3/d3-shape/blob/master/README.md#custom-curves) rather than as a function that returns an SVG path data string; this allows curves to render to either SVG or Canvas. In addition, *line*.curve and *area*.curve now take a function which instantiates a curve for a given *context*, rather than a string. The full list of equivalents:\n\n* linear ↦ [d3.curveLinear](https://github.com/d3/d3-shape/blob/master/README.md#curveLinear)\n* linear-closed ↦ [d3.curveLinearClosed](https://github.com/d3/d3-shape/blob/master/README.md#curveLinearClosed)\n* step ↦ [d3.curveStep](https://github.com/d3/d3-shape/blob/master/README.md#curveStep)\n* step-before ↦ [d3.curveStepBefore](https://github.com/d3/d3-shape/blob/master/README.md#curveStepBefore)\n* step-after ↦ [d3.curveStepAfter](https://github.com/d3/d3-shape/blob/master/README.md#curveStepAfter)\n* basis ↦ [d3.curveBasis](https://github.com/d3/d3-shape/blob/master/README.md#curveBasis)\n* basis-open ↦ [d3.curveBasisOpen](https://github.com/d3/d3-shape/blob/master/README.md#curveBasisOpen)\n* basis-closed ↦ [d3.curveBasisClosed](https://github.com/d3/d3-shape/blob/master/README.md#curveBasisClosed)\n* bundle ↦ [d3.curveBundle](https://github.com/d3/d3-shape/blob/master/README.md#curveBundle)\n* cardinal ↦ [d3.curveCardinal](https://github.com/d3/d3-shape/blob/master/README.md#curveCardinal)\n* cardinal-open ↦ [d3.curveCardinalOpen](https://github.com/d3/d3-shape/blob/master/README.md#curveCardinalOpen)\n* cardinal-closed ↦ [d3.curveCardinalClosed](https://github.com/d3/d3-shape/blob/master/README.md#curveCardinalClosed)\n* monotone ↦ [d3.curveMonotoneX](https://github.com/d3/d3-shape/blob/master/README.md#curveMonotoneX)\n\nBut that’s not all! 4.0 now provides parameterized Catmull–Rom splines as proposed by [Yuksel *et al.*](http://www.cemyuksel.com/research/catmullrom_param/). These are available as [d3.curveCatmullRom](https://github.com/d3/d3-shape/blob/master/README.md#curveCatmullRom), [d3.curveCatmullRomClosed](https://github.com/d3/d3-shape/blob/master/README.md#curveCatmullRomClosed) and [d3.curveCatmullRomOpen](https://github.com/d3/d3-shape/blob/master/README.md#curveCatmullRomOpen).\n\n<img src=\"https://raw.githubusercontent.com/d3/d3-shape/master/img/catmullRom.png\" width=\"888\" height=\"240\" alt=\"catmullRom\">\n<img src=\"https://raw.githubusercontent.com/d3/d3-shape/master/img/catmullRomOpen.png\" width=\"888\" height=\"240\" alt=\"catmullRomOpen\">\n<img src=\"https://raw.githubusercontent.com/d3/d3-shape/master/img/catmullRomClosed.png\" width=\"888\" height=\"330\" alt=\"catmullRomClosed\">\n\nEach curve type can define its own named parameters, replacing *line*.tension and *area*.tension. For example, Catmull–Rom splines are parameterized using [*catmullRom*.alpha](https://github.com/d3/d3-shape/blob/master/README.md#curveCatmullRom_alpha) and defaults to 0.5, which corresponds to a centripetal spline that avoids self-intersections and overshoot. For a uniform Catmull–Rom spline instead:\n\n```js\nvar line = d3.line()\n    .curve(d3.curveCatmullRom.alpha(0));\n```\n\n4.0 fixes the interpretation of the cardinal spline *tension* parameter, which is now specified as [*cardinal*.tension](https://github.com/d3/d3-shape/blob/master/README.md#curveCardinal_tension) and defaults to zero for a uniform Catmull–Rom spline; a tension of one produces a linear curve. The first and last segments of basis and cardinal curves have also been fixed! The undocumented *interpolate*.reverse field has been removed. Curves can define different behavior for toplines and baselines by counting the sequence of [*curve*.lineStart](https://github.com/d3/d3-shape/blob/master/README.md#curve_lineStart) within [*curve*.areaStart](https://github.com/d3/d3-shape/blob/master/README.md#curve_areaStart). See the [d3.curveStep implementation](https://github.com/d3/d3-shape/blob/master/src/curve/step.js) for an example.\n\n4.0 fixes numerous bugs in the monotone curve implementation, and introduces [d3.curveMonotoneY](https://github.com/d3/d3-shape/blob/master/README.md#curveMonotoneY); this is like d3.curveMonotoneX, except it requires that the input points are monotone in *y* rather than *x*, such as for a vertically-oriented line chart. The new [d3.curveNatural](https://github.com/d3/d3-shape/blob/master/README.md#curveNatural) produces a [natural cubic spline](http://mathworld.wolfram.com/CubicSpline.html). The default [β](https://github.com/d3/d3-shape/blob/master/README.md#bundle_beta) for [d3.curveBundle](https://github.com/d3/d3-shape/blob/master/README.md#curveBundle) is now 0.85, rather than 0.7, matching the values used by [Holten](https://www.win.tue.nl/vis1/home/dholten/papers/bundles_infovis.pdf). 4.0 also has a more robust implementation of arc padding; see [*arc*.padAngle](https://github.com/d3/d3-shape/blob/master/README.md#arc_padAngle) and [*arc*.padRadius](https://github.com/d3/d3-shape/blob/master/README.md#arc_padRadius).\n\n4.0 introduces a new symbol type API. Symbol types are passed to [*symbol*.type](https://github.com/d3/d3-shape/blob/master/README.md#symbol_type) in place of strings. The equivalents are:\n\n* circle ↦ [d3.symbolCircle](https://github.com/d3/d3-shape/blob/master/README.md#symbolCircle)\n* cross ↦ [d3.symbolCross](https://github.com/d3/d3-shape/blob/master/README.md#symbolCross)\n* diamond ↦ [d3.symbolDiamond](https://github.com/d3/d3-shape/blob/master/README.md#symbolDiamond)\n* square ↦ [d3.symbolSquare](https://github.com/d3/d3-shape/blob/master/README.md#symbolSquare)\n* triangle-down ↦ REMOVED\n* triangle-up ↦ [d3.symbolTriangle](https://github.com/d3/d3-shape/blob/master/README.md#symbolTriangle)\n* ADDED ↦ [d3.symbolStar](https://github.com/d3/d3-shape/blob/master/README.md#symbolStar)\n* ADDED ↦ [d3.symbolWye](https://github.com/d3/d3-shape/blob/master/README.md#symbolWye)\n\nThe full set of symbol types is now:\n\n<a href=\"#symbolCircle\"><img src=\"https://raw.githubusercontent.com/d3/d3-shape/master/img/circle.png\" width=\"100\" height=\"100\"></a><a href=\"#symbolCross\"><img src=\"https://raw.githubusercontent.com/d3/d3-shape/master/img/cross.png\" width=\"100\" height=\"100\"></a><a href=\"#symbolDiamond\"><img src=\"https://raw.githubusercontent.com/d3/d3-shape/master/img/diamond.png\" width=\"100\" height=\"100\"></a><a href=\"#symbolSquare\"><img src=\"https://raw.githubusercontent.com/d3/d3-shape/master/img/square.png\" width=\"100\" height=\"100\"></a><a href=\"#symbolStar\"><img src=\"https://raw.githubusercontent.com/d3/d3-shape/master/img/star.png\" width=\"100\" height=\"100\"></a><a href=\"#symbolTriangle\"><img src=\"https://raw.githubusercontent.com/d3/d3-shape/master/img/triangle.png\" width=\"100\" height=\"100\"><a href=\"#symbolWye\"><img src=\"https://raw.githubusercontent.com/d3/d3-shape/master/img/wye.png\" width=\"100\" height=\"100\"></a>\n\nLastly, 4.0 overhauls the stack layout API, replacing d3.layout.stack with [d3.stack](https://github.com/d3/d3-shape/blob/master/README.md#stacks). The stack generator no longer needs an *x*-accessor. In addition, the API has been simplified: the *stack* generator now accepts tabular input, such as this array of objects:\n\n```js\nvar data = [\n  {month: new Date(2015, 0, 1), apples: 3840, bananas: 1920, cherries: 960, dates: 400},\n  {month: new Date(2015, 1, 1), apples: 1600, bananas: 1440, cherries: 960, dates: 400},\n  {month: new Date(2015, 2, 1), apples:  640, bananas:  960, cherries: 640, dates: 400},\n  {month: new Date(2015, 3, 1), apples:  320, bananas:  480, cherries: 640, dates: 400}\n];\n```\n\nTo generate the stack layout, first define a stack generator, and then apply it to the data:\n\n```js\nvar stack = d3.stack()\n    .keys([\"apples\", \"bananas\", \"cherries\", \"dates\"])\n    .order(d3.stackOrderNone)\n    .offset(d3.stackOffsetNone);\n\nvar series = stack(data);\n```\n\nThe resulting array has one element per *series*. Each series has one point per month, and each point has a lower and upper value defining the baseline and topline:\n\n```js\n[\n  [[   0, 3840], [   0, 1600], [   0,  640], [   0,  320]], // apples\n  [[3840, 5760], [1600, 3040], [ 640, 1600], [ 320,  800]], // bananas\n  [[5760, 6720], [3040, 4000], [1600, 2240], [ 800, 1440]], // cherries\n  [[6720, 7120], [4000, 4400], [2240, 2640], [1440, 1840]], // dates\n]\n```\n\nEach series in then typically passed to an [area generator](https://github.com/d3/d3-shape/blob/master/README.md#areas) to render an area chart, or used to construct rectangles for a bar chart. Stack generators no longer modify the input data, so *stack*.out has been removed.\n\nFor an introduction to shapes, see [Introducing d3-shape](https://medium.com/@mbostock/introducing-d3-shape-73f8367e6d12).\n\n## [Time Formats (d3-time-format)](https://github.com/d3/d3-time-format/blob/master/README.md)\n\nPursuant to the great namespace flattening, the format constructors have new names:\n\n* d3.time.format ↦ [d3.timeFormat](https://github.com/d3/d3-time-format/blob/master/README.md#timeFormat)\n* d3.time.format.utc ↦ [d3.utcFormat](https://github.com/d3/d3-time-format/blob/master/README.md#utcFormat)\n* d3.time.format.iso ↦ [d3.isoFormat](https://github.com/d3/d3-time-format/blob/master/README.md#isoFormat)\n\nThe *format*.parse method has also been removed in favor of separate [d3.timeParse](https://github.com/d3/d3-time-format/blob/master/README.md#timeParse), [d3.utcParse](https://github.com/d3/d3-time-format/blob/master/README.md#utcParse) and [d3.isoParse](https://github.com/d3/d3-time-format/blob/master/README.md#isoParse) parser constructors. Thus, this code in 3.x:\n\n```js\nvar parseTime = d3.time.format(\"%c\").parse;\n```\n\nCan be rewritten in 4.0 as:\n\n```js\nvar parseTime = d3.timeParse(\"%c\");\n```\n\nThe multi-scale time format d3.time.format.multi has been replaced by [d3.scaleTime](https://github.com/d3/d3-scale/blob/master/README.md#scaleTime)’s [tick format](https://github.com/d3/d3-scale/blob/master/README.md#time_tickFormat). Time formats now coerce inputs to dates, and time parsers coerce inputs to strings. The `%Z` directive now allows more flexible parsing of time zone offsets, such as `-0700`, `-07:00`, `-07`, and `Z`. The `%p` directive is now parsed correctly when the locale’s period name is longer than two characters (*e.g.*, “a.m.”).\n\nThe default U.S. English locale now uses 12-hour time and a more concise representation of the date. This aligns with local convention and is consistent with [*date*.toLocaleString](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/toLocaleString) in Chrome, Firefox and Node:\n\n```js\nvar now = new Date;\nd3.timeFormat(\"%c\")(new Date); // \"6/23/2016, 2:01:33 PM\"\nd3.timeFormat(\"%x\")(new Date); // \"6/23/2016\"\nd3.timeFormat(\"%X\")(new Date); // \"2:01:38 PM\"\n```\n\nYou can now set the default locale using [d3.timeFormatDefaultLocale](https://github.com/d3/d3-time-format/blob/master/README.md#timeFormatDefaultLocale)! The locales are published as [JSON](https://github.com/d3/d3-request/blob/master/README.md#json) to [npm](https://unpkg.com/d3-time-format/locale/).\n\nThe performance of time formatting and parsing has been improved, and the UTC formatter and parser have a cleaner implementation (that avoids temporarily overriding the Date global).\n\n## [Time Intervals (d3-time)](https://github.com/d3/d3-time/blob/master/README.md)\n\nPursuant to the great namespace flattening, the local time intervals have been renamed:\n\n* ADDED ↦ [d3.timeMillisecond](https://github.com/d3/d3-time/blob/master/README.md#timeMillisecond)\n* d3.time.second ↦ [d3.timeSecond](https://github.com/d3/d3-time/blob/master/README.md#timeSecond)\n* d3.time.minute ↦ [d3.timeMinute](https://github.com/d3/d3-time/blob/master/README.md#timeMinute)\n* d3.time.hour ↦ [d3.timeHour](https://github.com/d3/d3-time/blob/master/README.md#timeHour)\n* d3.time.day ↦ [d3.timeDay](https://github.com/d3/d3-time/blob/master/README.md#timeDay)\n* d3.time.sunday ↦ [d3.timeSunday](https://github.com/d3/d3-time/blob/master/README.md#timeSunday)\n* d3.time.monday ↦ [d3.timeMonday](https://github.com/d3/d3-time/blob/master/README.md#timeMonday)\n* d3.time.tuesday ↦ [d3.timeTuesday](https://github.com/d3/d3-time/blob/master/README.md#timeTuesday)\n* d3.time.wednesday ↦ [d3.timeWednesday](https://github.com/d3/d3-time/blob/master/README.md#timeWednesday)\n* d3.time.thursday ↦ [d3.timeThursday](https://github.com/d3/d3-time/blob/master/README.md#timeThursday)\n* d3.time.friday ↦ [d3.timeFriday](https://github.com/d3/d3-time/blob/master/README.md#timeFriday)\n* d3.time.saturday ↦ [d3.timeSaturday](https://github.com/d3/d3-time/blob/master/README.md#timeSaturday)\n* d3.time.week ↦ [d3.timeWeek](https://github.com/d3/d3-time/blob/master/README.md#timeWeek)\n* d3.time.month ↦ [d3.timeMonth](https://github.com/d3/d3-time/blob/master/README.md#timeMonth)\n* d3.time.year ↦ [d3.timeYear](https://github.com/d3/d3-time/blob/master/README.md#timeYear)\n\nThe UTC time intervals have likewise been renamed:\n\n* ADDED ↦ [d3.utcMillisecond](https://github.com/d3/d3-time/blob/master/README.md#utcMillisecond)\n* d3.time.second.utc ↦ [d3.utcSecond](https://github.com/d3/d3-time/blob/master/README.md#utcSecond)\n* d3.time.minute.utc ↦ [d3.utcMinute](https://github.com/d3/d3-time/blob/master/README.md#utcMinute)\n* d3.time.hour.utc ↦ [d3.utcHour](https://github.com/d3/d3-time/blob/master/README.md#utcHour)\n* d3.time.day.utc ↦ [d3.utcDay](https://github.com/d3/d3-time/blob/master/README.md#utcDay)\n* d3.time.sunday.utc ↦ [d3.utcSunday](https://github.com/d3/d3-time/blob/master/README.md#utcSunday)\n* d3.time.monday.utc ↦ [d3.utcMonday](https://github.com/d3/d3-time/blob/master/README.md#utcMonday)\n* d3.time.tuesday.utc ↦ [d3.utcTuesday](https://github.com/d3/d3-time/blob/master/README.md#utcTuesday)\n* d3.time.wednesday.utc ↦ [d3.utcWednesday](https://github.com/d3/d3-time/blob/master/README.md#utcWednesday)\n* d3.time.thursday.utc ↦ [d3.utcThursday](https://github.com/d3/d3-time/blob/master/README.md#utcThursday)\n* d3.time.friday.utc ↦ [d3.utcFriday](https://github.com/d3/d3-time/blob/master/README.md#utcFriday)\n* d3.time.saturday.utc ↦ [d3.utcSaturday](https://github.com/d3/d3-time/blob/master/README.md#utcSaturday)\n* d3.time.week.utc ↦ [d3.utcWeek](https://github.com/d3/d3-time/blob/master/README.md#utcWeek)\n* d3.time.month.utc ↦ [d3.utcMonth](https://github.com/d3/d3-time/blob/master/README.md#utcMonth)\n* d3.time.year.utc ↦ [d3.utcYear](https://github.com/d3/d3-time/blob/master/README.md#utcYear)\n\nThe local time range aliases have been renamed:\n\n* d3.time.seconds ↦ [d3.timeSeconds](https://github.com/d3/d3-time/blob/master/README.md#timeSeconds)\n* d3.time.minutes ↦ [d3.timeMinutes](https://github.com/d3/d3-time/blob/master/README.md#timeMinutes)\n* d3.time.hours ↦ [d3.timeHours](https://github.com/d3/d3-time/blob/master/README.md#timeHours)\n* d3.time.days ↦ [d3.timeDays](https://github.com/d3/d3-time/blob/master/README.md#timeDays)\n* d3.time.sundays ↦ [d3.timeSundays](https://github.com/d3/d3-time/blob/master/README.md#timeSundays)\n* d3.time.mondays ↦ [d3.timeMondays](https://github.com/d3/d3-time/blob/master/README.md#timeMondays)\n* d3.time.tuesdays ↦ [d3.timeTuesdays](https://github.com/d3/d3-time/blob/master/README.md#timeTuesdays)\n* d3.time.wednesdays ↦ [d3.timeWednesdays](https://github.com/d3/d3-time/blob/master/README.md#timeWednesdays)\n* d3.time.thursdays ↦ [d3.timeThursdays](https://github.com/d3/d3-time/blob/master/README.md#timeThursdays)\n* d3.time.fridays ↦ [d3.timeFridays](https://github.com/d3/d3-time/blob/master/README.md#timeFridays)\n* d3.time.saturdays ↦ [d3.timeSaturdays](https://github.com/d3/d3-time/blob/master/README.md#timeSaturdays)\n* d3.time.weeks ↦ [d3.timeWeeks](https://github.com/d3/d3-time/blob/master/README.md#timeWeeks)\n* d3.time.months ↦ [d3.timeMonths](https://github.com/d3/d3-time/blob/master/README.md#timeMonths)\n* d3.time.years ↦ [d3.timeYears](https://github.com/d3/d3-time/blob/master/README.md#timeYears)\n\nThe UTC time range aliases have been renamed:\n\n* d3.time.seconds.utc ↦ [d3.utcSeconds](https://github.com/d3/d3-time/blob/master/README.md#utcSeconds)\n* d3.time.minutes.utc ↦ [d3.utcMinutes](https://github.com/d3/d3-time/blob/master/README.md#utcMinutes)\n* d3.time.hours.utc ↦ [d3.utcHours](https://github.com/d3/d3-time/blob/master/README.md#utcHours)\n* d3.time.days.utc ↦ [d3.utcDays](https://github.com/d3/d3-time/blob/master/README.md#utcDays)\n* d3.time.sundays.utc ↦ [d3.utcSundays](https://github.com/d3/d3-time/blob/master/README.md#utcSundays)\n* d3.time.mondays.utc ↦ [d3.utcMondays](https://github.com/d3/d3-time/blob/master/README.md#utcMondays)\n* d3.time.tuesdays.utc ↦ [d3.utcTuesdays](https://github.com/d3/d3-time/blob/master/README.md#utcTuesdays)\n* d3.time.wednesdays.utc ↦ [d3.utcWednesdays](https://github.com/d3/d3-time/blob/master/README.md#utcWednesdays)\n* d3.time.thursdays.utc ↦ [d3.utcThursdays](https://github.com/d3/d3-time/blob/master/README.md#utcThursdays)\n* d3.time.fridays.utc ↦ [d3.utcFridays](https://github.com/d3/d3-time/blob/master/README.md#utcFridays)\n* d3.time.saturdays.utc ↦ [d3.utcSaturdays](https://github.com/d3/d3-time/blob/master/README.md#utcSaturdays)\n* d3.time.weeks.utc ↦ [d3.utcWeeks](https://github.com/d3/d3-time/blob/master/README.md#utcWeeks)\n* d3.time.months.utc ↦ [d3.utcMonths](https://github.com/d3/d3-time/blob/master/README.md#utcMonths)\n* d3.time.years.utc ↦ [d3.utcYears](https://github.com/d3/d3-time/blob/master/README.md#utcYears)\n\nThe behavior of [*interval*.range](https://github.com/d3/d3-time/blob/master/README.md#interval_range) (and the convenience aliases such as [d3.timeDays](https://github.com/d3/d3-time/blob/master/README.md#timeDays)) has been changed when *step* is greater than one. Rather than filtering the returned dates using the field number, *interval*.range now behaves like [d3.range](https://github.com/d3/d3-array/blob/master/README.md#range): it simply skips, returning every *step*th date. For example, the following code in 3.x returns only odd days of the month:\n\n```js\nd3.time.days(new Date(2016, 4, 28), new Date(2016, 5, 5), 2);\n// [Sun May 29 2016 00:00:00 GMT-0700 (PDT),\n//  Tue May 31 2016 00:00:00 GMT-0700 (PDT),\n//  Wed Jun 01 2016 00:00:00 GMT-0700 (PDT),\n//  Fri Jun 03 2016 00:00:00 GMT-0700 (PDT)]\n```\n\nNote the returned array of dates does not start on the *start* date because May 28 is even. Also note that May 31 and June 1 are one day apart, not two! The behavior of d3.timeDays in 4.0 is probably closer to what you expect:\n\n```js\nd3.timeDays(new Date(2016, 4, 28), new Date(2016, 5, 5), 2);\n// [Sat May 28 2016 00:00:00 GMT-0700 (PDT),\n//  Mon May 30 2016 00:00:00 GMT-0700 (PDT),\n//  Wed Jun 01 2016 00:00:00 GMT-0700 (PDT),\n//  Fri Jun 03 2016 00:00:00 GMT-0700 (PDT)]\n```\n\nIf you want a filtered view of a time interval (say to guarantee that two overlapping ranges are consistent, such as when generating [time scale ticks](https://github.com/d3/d3-scale/blob/master/README.md#time_ticks)), you can use the new [*interval*.every](https://github.com/d3/d3-time/blob/master/README.md#interval_every) method or its more general cousin [*interval*.filter](https://github.com/d3/d3-time/blob/master/README.md#interval_filter):\n\n```js\nd3.timeDay.every(2).range(new Date(2016, 4, 28), new Date(2016, 5, 5));\n// [Sun May 29 2016 00:00:00 GMT-0700 (PDT),\n//  Tue May 31 2016 00:00:00 GMT-0700 (PDT),\n//  Wed Jun 01 2016 00:00:00 GMT-0700 (PDT),\n//  Fri Jun 03 2016 00:00:00 GMT-0700 (PDT)]\n```\n\nTime intervals now expose an [*interval*.count](https://github.com/d3/d3-time/blob/master/README.md#interval_count) method for counting the number of interval boundaries after a *start* date and before or equal to an *end* date. This replaces d3.time.dayOfYear and related methods in 3.x. For example, this code in 3.x:\n\n```js\nvar now = new Date;\nd3.time.dayOfYear(now); // 165\n```\n\nCan be rewritten in 4.0 as:\n\n```js\nvar now = new Date;\nd3.timeDay.count(d3.timeYear(now), now); // 165\n```\n\nLikewise, in place of 3.x’s d3.time.weekOfYear, in 4.0 you would say:\n\n```js\nd3.timeWeek.count(d3.timeYear(now), now); // 24\n```\n\nThe new *interval*.count is of course more general. For example, you can use it to compute hour-of-week for a heatmap:\n\n```js\nd3.timeHour.count(d3.timeWeek(now), now); // 64\n```\n\nHere are all the equivalences from 3.x to 4.0:\n\n* d3.time.dayOfYear ↦ [d3.timeDay](https://github.com/d3/d3-time/blob/master/README.md#timeDay).[count](https://github.com/d3/d3-time/blob/master/README.md#interval_count)\n* d3.time.sundayOfYear ↦ [d3.timeSunday](https://github.com/d3/d3-time/blob/master/README.md#timeSunday).[count](https://github.com/d3/d3-time/blob/master/README.md#interval_count)\n* d3.time.mondayOfYear ↦ [d3.timeMonday](https://github.com/d3/d3-time/blob/master/README.md#timeMonday).[count](https://github.com/d3/d3-time/blob/master/README.md#interval_count)\n* d3.time.tuesdayOfYear ↦ [d3.timeTuesday](https://github.com/d3/d3-time/blob/master/README.md#timeTuesday).[count](https://github.com/d3/d3-time/blob/master/README.md#interval_count)\n* d3.time.wednesdayOfYear ↦ [d3.timeWednesday](https://github.com/d3/d3-time/blob/master/README.md#timeWednesday).[count](https://github.com/d3/d3-time/blob/master/README.md#interval_count)\n* d3.time.thursdayOfYear ↦ [d3.timeThursday](https://github.com/d3/d3-time/blob/master/README.md#timeThursday).[count](https://github.com/d3/d3-time/blob/master/README.md#interval_count)\n* d3.time.fridayOfYear ↦ [d3.timeFriday](https://github.com/d3/d3-time/blob/master/README.md#timeFriday).[count](https://github.com/d3/d3-time/blob/master/README.md#interval_count)\n* d3.time.saturdayOfYear ↦ [d3.timeSaturday](https://github.com/d3/d3-time/blob/master/README.md#timeSaturday).[count](https://github.com/d3/d3-time/blob/master/README.md#interval_count)\n* d3.time.weekOfYear ↦ [d3.timeWeek](https://github.com/d3/d3-time/blob/master/README.md#timeWeek).[count](https://github.com/d3/d3-time/blob/master/README.md#interval_count)\n* d3.time.dayOfYear.utc ↦ [d3.utcDay](https://github.com/d3/d3-time/blob/master/README.md#utcDay).[count](https://github.com/d3/d3-time/blob/master/README.md#interval_count)\n* d3.time.sundayOfYear.utc ↦ [d3.utcSunday](https://github.com/d3/d3-time/blob/master/README.md#utcSunday).[count](https://github.com/d3/d3-time/blob/master/README.md#interval_count)\n* d3.time.mondayOfYear.utc ↦ [d3.utcMonday](https://github.com/d3/d3-time/blob/master/README.md#utcMonday).[count](https://github.com/d3/d3-time/blob/master/README.md#interval_count)\n* d3.time.tuesdayOfYear.utc ↦ [d3.utcTuesday](https://github.com/d3/d3-time/blob/master/README.md#utcTuesday).[count](https://github.com/d3/d3-time/blob/master/README.md#interval_count)\n* d3.time.wednesdayOfYear.utc ↦ [d3.utcWednesday](https://github.com/d3/d3-time/blob/master/README.md#utcWednesday).[count](https://github.com/d3/d3-time/blob/master/README.md#interval_count)\n* d3.time.thursdayOfYear.utc ↦ [d3.utcThursday](https://github.com/d3/d3-time/blob/master/README.md#utcThursday).[count](https://github.com/d3/d3-time/blob/master/README.md#interval_count)\n* d3.time.fridayOfYear.utc ↦ [d3.utcFriday](https://github.com/d3/d3-time/blob/master/README.md#utcFriday).[count](https://github.com/d3/d3-time/blob/master/README.md#interval_count)\n* d3.time.saturdayOfYear.utc ↦ [d3.utcSaturday](https://github.com/d3/d3-time/blob/master/README.md#utcSaturday).[count](https://github.com/d3/d3-time/blob/master/README.md#interval_count)\n* d3.time.weekOfYear.utc ↦ [d3.utcWeek](https://github.com/d3/d3-time/blob/master/README.md#utcWeek).[count](https://github.com/d3/d3-time/blob/master/README.md#interval_count)\n\nD3 4.0 now also lets you define custom time intervals using [d3.timeInterval](https://github.com/d3/d3-time/blob/master/README.md#timeInterval). The [d3.timeYear](https://github.com/d3/d3-time/blob/master/README.md#timeYear), [d3.utcYear](https://github.com/d3/d3-time/blob/master/README.md#utcYear), [d3.timeMillisecond](https://github.com/d3/d3-time/blob/master/README.md#timeMillisecond) and [d3.utcMillisecond](https://github.com/d3/d3-time/blob/master/README.md#utcMillisecond) intervals have optimized implementations of [*interval*.every](https://github.com/d3/d3-time/blob/master/README.md#interval_every), which is necessary to generate time ticks for very large or very small domains efficiently. More generally, the performance of time intervals has been improved, and time intervals now do a better job with respect to daylight savings in various locales.\n\n## [Timers (d3-timer)](https://github.com/d3/d3-timer/blob/master/README.md)\n\nIn D3 3.x, the only way to stop a timer was for its callback to return true. For example, this timer stops after one second:\n\n```js\nd3.timer(function(elapsed) {\n  console.log(elapsed);\n  return elapsed >= 1000;\n});\n```\n\nIn 4.0, use [*timer*.stop](https://github.com/d3/d3-timer/blob/master/README.md#timer_stop) instead:\n\n```js\nvar t = d3.timer(function(elapsed) {\n  console.log(elapsed);\n  if (elapsed >= 1000) {\n    t.stop();\n  }\n});\n```\n\nThe primary benefit of *timer*.stop is that timers are not required to self-terminate: they can be stopped externally, allowing for the immediate and synchronous disposal of associated resources, and the separation of concerns. The above is equivalent to:\n\n```js\nvar t = d3.timer(function(elapsed) {\n  console.log(elapsed);\n});\n\nd3.timeout(function() {\n  t.stop();\n}, 1000);\n```\n\nThis improvement extends to [d3-transition](#transitions-d3-transition): now when a transition is interrupted, its resources are immediately freed rather than having to wait for transition to start.\n\n4.0 also introduces a new [*timer*.restart](https://github.com/d3/d3-timer/blob/master/README.md#timer_restart) method for restarting timers, for replacing the callback of a running timer, or for changing its delay or reference time. Unlike *timer*.stop followed by [d3.timer](https://github.com/d3/d3-timer/blob/master/README.md#timer), *timer*.restart maintains the invocation priority of an existing timer: it guarantees that the order of invocation of active timers remains the same. The d3.timer.flush method has been renamed to [d3.timerFlush](https://github.com/d3/d3-timer/blob/master/README.md#timerFlush).\n\nSome usage patterns in D3 3.x could cause the browser to hang when a background page returned to the foreground. For example, the following code schedules a transition every second:\n\n```js\nsetInterval(function() {\n  d3.selectAll(\"div\").transition().call(someAnimation); // BAD\n}, 1000);\n```\n\nIf such code runs in the background for hours, thousands of queued transitions will try to run simultaneously when the page is foregrounded. D3 4.0 avoids this hang by freezing time in the background: when a page is in the background, time does not advance, and so no queue of timers accumulates to run when the page returns to the foreground. Use d3.timer instead of transitions to schedule a long-running animation, or use [d3.timeout](https://github.com/d3/d3-timer/blob/master/README.md#timeout) and [d3.interval](https://github.com/d3/d3-timer/blob/master/README.md#interval) in place of setTimeout and setInterval to prevent transitions from being queued in the background:\n\n```js\nd3.interval(function() {\n  d3.selectAll(\"div\").transition().call(someAnimation); // GOOD\n}, 1000);\n```\n\nBy freezing time in the background, timers are effectively “unaware” of being backgrounded. It’s like nothing happened! 4.0 also now uses high-precision time ([performance.now](https://developer.mozilla.org/en-US/docs/Web/API/Performance/now)) where available; the current time is available as [d3.now](https://github.com/d3/d3-timer/blob/master/README.md#now).\n\n## [Transitions (d3-transition)](https://github.com/d3/d3-transition/blob/master/README.md)\n\nThe [*selection*.transition](https://github.com/d3/d3-transition/blob/master/README.md#selection_transition) method now takes an optional *transition* instance which can be used to synchronize a new transition with an existing transition. (This change is discussed further in [What Makes Software Good?](https://medium.com/@mbostock/what-makes-software-good-943557f8a488)) For example:\n\n```js\nvar t = d3.transition()\n    .duration(750)\n    .ease(d3.easeLinear);\n\nd3.selectAll(\".apple\").transition(t)\n    .style(\"fill\", \"red\");\n\nd3.selectAll(\".orange\").transition(t)\n    .style(\"fill\", \"orange\");\n```\n\nTransitions created this way inherit timing from the closest ancestor element, and thus are synchronized even when the referenced *transition* has variable timing such as a staggered delay. This method replaces the deeply magical behavior of *transition*.each in 3.x; in 4.0, [*transition*.each](https://github.com/d3/d3-transition/blob/master/README.md#transition_each) is identical to [*selection*.each](https://github.com/d3/d3-selection/blob/master/README.md#selection_each). Use the new [*transition*.on](https://github.com/d3/d3-transition/blob/master/README.md#transition_on) method to listen to transition events.\n\nThe meaning of [*transition*.delay](https://github.com/d3/d3-transition/blob/master/README.md#transition_delay) has changed for chained transitions created by [*transition*.transition](https://github.com/d3/d3-transition/blob/master/README.md#transition_transition). The specified delay is now relative to the *previous* transition in the chain, rather than the *first* transition in the chain; this makes it easier to insert interstitial pauses. For example:\n\n```js\nd3.selectAll(\".apple\")\n  .transition() // First fade to green.\n    .style(\"fill\", \"green\")\n  .transition() // Then red.\n    .style(\"fill\", \"red\")\n  .transition() // Wait one second. Then brown, and remove.\n    .delay(1000)\n    .style(\"fill\", \"brown\")\n    .remove();\n```\n\nTime is now frozen in the background; see [d3-timer](#timers-d3-timer) for more information. While it was previously the case that transitions did not run in the background, now they pick up where they left off when the page returns to the foreground. This avoids page hangs by not scheduling an unbounded number of transitions in the background. If you want to schedule an infinitely-repeating transition, use transition events, or use [d3.timeout](https://github.com/d3/d3-timer/blob/master/README.md#timeout) and [d3.interval](https://github.com/d3/d3-timer/blob/master/README.md#interval) in place of [setTimeout](https://developer.mozilla.org/en-US/docs/Web/API/WindowTimers/setTimeout) and [setInterval](https://developer.mozilla.org/en-US/docs/Web/API/WindowTimers/setInterval).\n\nThe [*selection*.interrupt](https://github.com/d3/d3-transition/blob/master/README.md#selection_interrupt) method now cancels all scheduled transitions on the selected elements, in addition to interrupting any active transition. When transitions are interrupted, any resources associated with the transition are now released immediately, rather than waiting until the transition starts, improving performance. (See also [*timer*.stop](https://github.com/d3/d3-timer/blob/master/README.md#timer_stop).) The new [d3.interrupt](https://github.com/d3/d3-transition/blob/master/README.md#interrupt) method is an alternative to [*selection*.interrupt](https://github.com/d3/d3-transition/blob/master/README.md#selection_interrupt) for quickly interrupting a single node.\n\nThe new [d3.active](https://github.com/d3/d3-transition/blob/master/README.md#active) method allows you to select the currently-active transition on a given *node*, if any. This is useful for modifying in-progress transitions and for scheduling infinitely-repeating transitions. For example, this transition continuously oscillates between red and blue:\n\n```js\nd3.select(\"circle\")\n  .transition()\n    .on(\"start\", function repeat() {\n        d3.active(this)\n            .style(\"fill\", \"red\")\n          .transition()\n            .style(\"fill\", \"blue\")\n          .transition()\n            .on(\"start\", repeat);\n      });\n```\n\nThe [life cycle of a transition](https://github.com/d3/d3-transition/blob/master/README.md#the-life-of-a-transition) is now more formally defined and enforced. For example, attempting to change the duration of a running transition now throws an error rather than silently failing. The [*transition*.remove](https://github.com/d3/d3-transition/blob/master/README.md#transition_remove) method has been fixed if multiple transition names are in use: the element is only removed if it has no scheduled transitions, regardless of name. The [*transition*.ease](https://github.com/d3/d3-transition/blob/master/README.md#transition_ease) method now always takes an [easing function](#easings-d3-ease), not a string. When a transition ends, the tweens are invoked one last time with *t* equal to exactly 1, regardless of the associated easing function.\n\nAs with [selections](#selections-d3-selection) in 4.0, all transition callback functions now receive the standard arguments: the element’s datum (*d*), the element’s index (*i*), and the element’s group (*nodes*), with *this* as the element. This notably affects [*transition*.attrTween](https://github.com/d3/d3-transition/blob/master/README.md#transition_attrTween) and [*transition*.styleTween](https://github.com/d3/d3-transition/blob/master/README.md#transition_styleTween), which no longer pass the *tween* function the current attribute or style value as the third argument. The *transition*.attrTween and *transition*.styleTween methods can now be called in getter modes for debugging or to share tween definitions between transitions.\n\nHomogenous transitions are now optimized! If all elements in a transition share the same tween, interpolator, or event listeners, this state is now shared across the transition rather than separately allocated for each element. 4.0 also uses an optimized default interpolator in place of [d3.interpolate](https://github.com/d3/d3-interpolate/blob/master/README.md#interpolate) for [*transition*.attr](https://github.com/d3/d3-transition/blob/master/README.md#transition_attr) and [*transition*.style](https://github.com/d3/d3-transition/blob/master/README.md#transition_style). And transitions can now interpolate both [CSS](https://github.com/d3/d3-interpolate/blob/master/README.md#interpolateTransformCss) and [SVG](https://github.com/d3/d3-interpolate/blob/master/README.md#interpolateTransformSvg) transforms.\n\nFor reusable components that support transitions, such as [axes](#axes-d3-axis), a new [*transition*.selection](https://github.com/d3/d3-transition/blob/master/README.md#transition_selection) method returns the [selection](#selections-d3-selection) that corresponds to a given transition. There is also a new [*transition*.merge](https://github.com/d3/d3-transition/blob/master/README.md#transition_merge) method that is equivalent to [*selection*.merge](https://github.com/d3/d3-selection/blob/master/README.md#selection_merge).\n\nFor the sake of parsimony, the multi-value map methods have been extracted to [d3-selection-multi](https://github.com/d3/d3-selection-multi) and are no longer part of the default bundle. The multi-value map methods have also been renamed to plural form to reduce overload: [*transition*.attrs](https://github.com/d3/d3-selection-multi/blob/master/README.md#transition_attrs) and [*transition*.styles](https://github.com/d3/d3-selection-multi/blob/master/README.md#transition_styles).\n\n## [Voronoi Diagrams (d3-voronoi)](https://github.com/d3/d3-voronoi/blob/master/README.md)\n\nThe d3.geom.voronoi method has been renamed to [d3.voronoi](https://github.com/d3/d3-voronoi/blob/master/README.md#voronoi), and the *voronoi*.clipExtent method has been renamed to [*voronoi*.extent](https://github.com/d3/d3-voronoi/blob/master/README.md#voronoi_extent). The undocumented *polygon*.point property in 3.x, which is the element in the input *data* corresponding to the polygon, has been renamed to *polygon*.data.\n\nCalling [*voronoi*](https://github.com/d3/d3-voronoi/blob/master/README.md#_voronoi) now returns the full [Voronoi diagram](https://github.com/d3/d3-voronoi/blob/master/README.md#voronoi-diagrams), which includes topological information: each Voronoi edge exposes *edge*.left and *edge*.right specifying the sites on either side of the edge, and each Voronoi cell is defined as an array of these edges and a corresponding site. The Voronoi diagram can be used to efficiently compute both the Voronoi and Delaunay tessellations for a set of points: [*diagram*.polygons](https://github.com/d3/d3-voronoi/blob/master/README.md#diagram_polygons), [*diagram*.links](https://github.com/d3/d3-voronoi/blob/master/README.md#diagram_links), and [*diagram*.triangles](https://github.com/d3/d3-voronoi/blob/master/README.md#diagram_triangles). The new topology is also useful in conjunction with TopoJSON; see the [Voronoi topology example](https://bl.ocks.org/mbostock/cd52a201d7694eb9d890).\n\nThe [*voronoi*.polygons](https://github.com/d3/d3-voronoi/blob/master/README.md#voronoi_polygons) and [*diagram*.polygons](https://github.com/d3/d3-voronoi/blob/master/README.md#diagram_polygons) now require an [extent](https://github.com/d3/d3-voronoi/blob/master/README.md#voronoi_extent); there is no longer an implicit extent of ±1e6. The [*voronoi*.links](https://github.com/d3/d3-voronoi/blob/master/README.md#voronoi_links), [*voronoi*.triangles](https://github.com/d3/d3-voronoi/blob/master/README.md#voronoi_triangles), [*diagram*.links](https://github.com/d3/d3-voronoi/blob/master/README.md#diagram_links) and [*diagram*.triangles](https://github.com/d3/d3-voronoi/blob/master/README.md#diagram_triangles) are now affected by the clip extent: as the Delaunay is computed as the dual of the Voronoi, two sites are only linked if the clipped cells are touching. To compute the Delaunay triangulation without respect to clipping, set the extent to null.\n\nThe Voronoi generator finally has well-defined behavior for coincident vertices: the first of a set of coincident points has a defined cell, while the subsequent duplicate points have null cells. The returned array of polygons is sparse, so by using *array*.forEach or *array*.map, you can easily skip undefined cells. The Voronoi generator also now correctly handles the case where no cell edges intersect the extent.\n\n## [Zooming (d3-zoom)](https://github.com/d3/d3-zoom/blob/master/README.md)\n\nThe zoom behavior d3.behavior.zoom has been renamed to d3.zoom. Zoom behaviors no longer store the active zoom transform (*i.e.*, the visible region; the scale and translate) internally. The zoom transform is now stored on any elements to which the zoom behavior has been applied. The zoom transform is available as *event*.transform within a zoom event or by calling [d3.zoomTransform](https://github.com/d3/d3-zoom/blob/master/README.md#zoomTransform) on a given *element*. To zoom programmatically, use [*zoom*.transform](https://github.com/d3/d3-zoom/blob/master/README.md#zoom_transform) with a given [selection](#selections-d3-selection) or [transition](#transitions-d3-transition); see the [zoom transitions example](https://bl.ocks.org/mbostock/b783fbb2e673561d214e09c7fb5cedee). The *zoom*.event method has been removed.\n\nTo make programmatic zooming easier, there are several new convenience methods on top of *zoom*.transform: [*zoom*.translateBy](https://github.com/d3/d3-zoom/blob/master/README.md#zoom_translateBy), [*zoom*.scaleBy](https://github.com/d3/d3-zoom/blob/master/README.md#zoom_scaleBy) and [*zoom*.scaleTo](https://github.com/d3/d3-zoom/blob/master/README.md#zoom_scaleTo). There is also a new API for describing [zoom transforms](https://github.com/d3/d3-zoom/blob/master/README.md#zoom-transforms). Zoom behaviors are no longer dependent on [scales](#scales-d3-scale), but you can use [*transform*.rescaleX](https://github.com/d3/d3-zoom/blob/master/README.md#transform_rescaleX), [*transform*.rescaleY](https://github.com/d3/d3-zoom/blob/master/README.md#transform_rescaleY), [*transform*.invertX](https://github.com/d3/d3-zoom/blob/master/README.md#transform_invertX) or [*transform*.invertY](https://github.com/d3/d3-zoom/blob/master/README.md#transform_invertY) to transform a scale’s domain. 3.x’s *event*.scale is replaced with *event*.transform.k, and *event*.translate is replaced with *event*.transform.x and *event*.transform.y. The *zoom*.center method has been removed in favor of programmatic zooming.\n\nThe zoom behavior finally supports simple constraints on panning! The new [*zoom*.translateExtent](https://github.com/d3/d3-zoom/blob/master/README.md#zoom_translateExtent) lets you define the viewable extent of the world: the currently-visible extent (the extent of the viewport, as defined by [*zoom*.extent](https://github.com/d3/d3-zoom/blob/master/README.md#zoom_extent)) is always contained within the translate extent. The *zoom*.size method has been replaced by *zoom*.extent, and the default behavior is now smarter: it defaults to the extent of the zoom behavior’s owner element, rather than being hardcoded to 960×500. (This also improves the default path chosen during smooth zoom transitions!)\n\nThe zoom behavior’s interaction has also improved. It now correctly handles concurrent wheeling and dragging, as well as concurrent touching and mousing. The zoom behavior now ignores wheel events at the limits of its scale extent, allowing you to scroll past a zoomable area. The *zoomstart* and *zoomend* events have been renamed *start* and *end*. By default, zoom behaviors now ignore right-clicks intended for the context menu; use [*zoom*.filter](https://github.com/d3/d3-zoom/blob/master/README.md#zoom_filter) to control which events are ignored. The zoom behavior also ignores emulated mouse events on iOS. The zoom behavior now consumes handled events, making it easier to combine with other interactive behaviors such as [dragging](#dragging-d3-drag).\n"
  },
  {
    "path": "app_backend/static/plugin/d3/LICENSE",
    "content": "Copyright 2010-2017 Mike Bostock\nAll rights reserved.\n\nRedistribution and use in source and binary forms, with or without modification,\nare permitted provided that the following conditions are met:\n\n* Redistributions of source code must retain the above copyright notice, this\n  list of conditions and the following disclaimer.\n\n* Redistributions in binary form must reproduce the above copyright notice,\n  this list of conditions and the following disclaimer in the documentation\n  and/or other materials provided with the distribution.\n\n* Neither the name of the author nor the names of contributors may be used to\n  endorse or promote products derived from this software without specific prior\n  written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\" AND\nANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\nWARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\nDISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR\nANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\nLOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON\nANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\nSOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n"
  },
  {
    "path": "app_backend/static/plugin/d3/README.md",
    "content": "# D3: Data-Driven Documents\n\n<a href=\"https://d3js.org\"><img src=\"https://d3js.org/logo.svg\" align=\"left\" hspace=\"10\" vspace=\"6\"></a>\n\n**D3** (or **D3.js**) is a JavaScript library for visualizing data using web standards. D3 helps you bring data to life using SVG, Canvas and HTML. D3 combines powerful visualization and interaction techniques with a data-driven approach to DOM manipulation, giving you the full capabilities of modern browsers and the freedom to design the right visual interface for your data.\n\n## Resources\n\n* [API Reference](https://github.com/d3/d3/blob/master/API.md)\n* [Release Notes](https://github.com/d3/d3/releases)\n* [Gallery](https://github.com/d3/d3/wiki/Gallery)\n* [Examples](https://bl.ocks.org/mbostock)\n* [Wiki](https://github.com/d3/d3/wiki)\n\n## Installing\n\nIf you use npm, `npm install d3`. Otherwise, download the [latest release](https://github.com/d3/d3/releases/latest). The released bundle supports anonymous AMD, CommonJS, and vanilla environments. You can load directly from [d3js.org](https://d3js.org), [CDNJS](https://cdnjs.com/libraries/d3), or [unpkg](https://unpkg.com/d3/). For example:\n\n```html\n<script src=\"https://d3js.org/d3.v4.js\"></script>\n```\n\nFor the minified version:\n\n```html\n<script src=\"https://d3js.org/d3.v4.min.js\"></script>\n```\n\nYou can also use the standalone D3 microlibraries. For example, [d3-selection](https://github.com/d3/d3-selection):\n\n```html\n<script src=\"https://d3js.org/d3-selection.v1.js\"></script>\n```\n\nD3 is written using [ES2015 modules](http://www.2ality.com/2014/09/es6-modules-final.html). Create a [custom bundle using Rollup](https://bl.ocks.org/mbostock/bb09af4c39c79cffcde4), Webpack, or your preferred bundler. To import D3 into an ES2015 application, either import specific symbols from specific D3 modules:\n\n```js\nimport {scaleLinear} from \"d3-scale\";\n```\n\nOr import everything into a namespace (here, `d3`):\n\n```js\nimport * as d3 from \"d3\";\n```\n\nIn Node:\n\n```js\nvar d3 = require(\"d3\");\n```\n\nYou can also require individual modules and combine them into a `d3` object using [Object.assign](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign):\n\n```js\nvar d3 = Object.assign({}, require(\"d3-format\"), require(\"d3-geo\"), require(\"d3-geo-projection\"));\n```\n"
  },
  {
    "path": "app_backend/static/plugin/d3/d3.js",
    "content": "// https://d3js.org Version 4.9.1. Copyright 2017 Mike Bostock.\n(function (global, factory) {\n\ttypeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :\n\ttypeof define === 'function' && define.amd ? define(['exports'], factory) :\n\t(factory((global.d3 = global.d3 || {})));\n}(this, (function (exports) { 'use strict';\n\nvar version = \"4.9.1\";\n\nvar ascending = function(a, b) {\n  return a < b ? -1 : a > b ? 1 : a >= b ? 0 : NaN;\n};\n\nvar bisector = function(compare) {\n  if (compare.length === 1) compare = ascendingComparator(compare);\n  return {\n    left: function(a, x, lo, hi) {\n      if (lo == null) lo = 0;\n      if (hi == null) hi = a.length;\n      while (lo < hi) {\n        var mid = lo + hi >>> 1;\n        if (compare(a[mid], x) < 0) lo = mid + 1;\n        else hi = mid;\n      }\n      return lo;\n    },\n    right: function(a, x, lo, hi) {\n      if (lo == null) lo = 0;\n      if (hi == null) hi = a.length;\n      while (lo < hi) {\n        var mid = lo + hi >>> 1;\n        if (compare(a[mid], x) > 0) hi = mid;\n        else lo = mid + 1;\n      }\n      return lo;\n    }\n  };\n};\n\nfunction ascendingComparator(f) {\n  return function(d, x) {\n    return ascending(f(d), x);\n  };\n}\n\nvar ascendingBisect = bisector(ascending);\nvar bisectRight = ascendingBisect.right;\nvar bisectLeft = ascendingBisect.left;\n\nvar pairs = function(array, f) {\n  if (f == null) f = pair;\n  var i = 0, n = array.length - 1, p = array[0], pairs = new Array(n < 0 ? 0 : n);\n  while (i < n) pairs[i] = f(p, p = array[++i]);\n  return pairs;\n};\n\nfunction pair(a, b) {\n  return [a, b];\n}\n\nvar cross = function(values0, values1, reduce) {\n  var n0 = values0.length,\n      n1 = values1.length,\n      values = new Array(n0 * n1),\n      i0,\n      i1,\n      i,\n      value0;\n\n  if (reduce == null) reduce = pair;\n\n  for (i0 = i = 0; i0 < n0; ++i0) {\n    for (value0 = values0[i0], i1 = 0; i1 < n1; ++i1, ++i) {\n      values[i] = reduce(value0, values1[i1]);\n    }\n  }\n\n  return values;\n};\n\nvar descending = function(a, b) {\n  return b < a ? -1 : b > a ? 1 : b >= a ? 0 : NaN;\n};\n\nvar number = function(x) {\n  return x === null ? NaN : +x;\n};\n\nvar variance = function(values, valueof) {\n  var n = values.length,\n      m = 0,\n      i = -1,\n      mean = 0,\n      value,\n      delta,\n      sum = 0;\n\n  if (valueof == null) {\n    while (++i < n) {\n      if (!isNaN(value = number(values[i]))) {\n        delta = value - mean;\n        mean += delta / ++m;\n        sum += delta * (value - mean);\n      }\n    }\n  }\n\n  else {\n    while (++i < n) {\n      if (!isNaN(value = number(valueof(values[i], i, values)))) {\n        delta = value - mean;\n        mean += delta / ++m;\n        sum += delta * (value - mean);\n      }\n    }\n  }\n\n  if (m > 1) return sum / (m - 1);\n};\n\nvar deviation = function(array, f) {\n  var v = variance(array, f);\n  return v ? Math.sqrt(v) : v;\n};\n\nvar extent = function(values, valueof) {\n  var n = values.length,\n      i = -1,\n      value,\n      min,\n      max;\n\n  if (valueof == null) {\n    while (++i < n) { // Find the first comparable value.\n      if ((value = values[i]) != null && value >= value) {\n        min = max = value;\n        while (++i < n) { // Compare the remaining values.\n          if ((value = values[i]) != null) {\n            if (min > value) min = value;\n            if (max < value) max = value;\n          }\n        }\n      }\n    }\n  }\n\n  else {\n    while (++i < n) { // Find the first comparable value.\n      if ((value = valueof(values[i], i, values)) != null && value >= value) {\n        min = max = value;\n        while (++i < n) { // Compare the remaining values.\n          if ((value = valueof(values[i], i, values)) != null) {\n            if (min > value) min = value;\n            if (max < value) max = value;\n          }\n        }\n      }\n    }\n  }\n\n  return [min, max];\n};\n\nvar array = Array.prototype;\n\nvar slice = array.slice;\nvar map = array.map;\n\nvar constant = function(x) {\n  return function() {\n    return x;\n  };\n};\n\nvar identity = function(x) {\n  return x;\n};\n\nvar sequence = function(start, stop, step) {\n  start = +start, stop = +stop, step = (n = arguments.length) < 2 ? (stop = start, start = 0, 1) : n < 3 ? 1 : +step;\n\n  var i = -1,\n      n = Math.max(0, Math.ceil((stop - start) / step)) | 0,\n      range = new Array(n);\n\n  while (++i < n) {\n    range[i] = start + i * step;\n  }\n\n  return range;\n};\n\nvar e10 = Math.sqrt(50);\nvar e5 = Math.sqrt(10);\nvar e2 = Math.sqrt(2);\n\nvar ticks = function(start, stop, count) {\n  var reverse = stop < start,\n      i = -1,\n      n,\n      ticks,\n      step;\n\n  if (reverse) n = start, start = stop, stop = n;\n\n  if ((step = tickIncrement(start, stop, count)) === 0 || !isFinite(step)) return [];\n\n  if (step > 0) {\n    start = Math.ceil(start / step);\n    stop = Math.floor(stop / step);\n    ticks = new Array(n = Math.ceil(stop - start + 1));\n    while (++i < n) ticks[i] = (start + i) * step;\n  } else {\n    start = Math.floor(start * step);\n    stop = Math.ceil(stop * step);\n    ticks = new Array(n = Math.ceil(start - stop + 1));\n    while (++i < n) ticks[i] = (start - i) / step;\n  }\n\n  if (reverse) ticks.reverse();\n\n  return ticks;\n};\n\nfunction tickIncrement(start, stop, count) {\n  var step = (stop - start) / Math.max(0, count),\n      power = Math.floor(Math.log(step) / Math.LN10),\n      error = step / Math.pow(10, power);\n  return power >= 0\n      ? (error >= e10 ? 10 : error >= e5 ? 5 : error >= e2 ? 2 : 1) * Math.pow(10, power)\n      : -Math.pow(10, -power) / (error >= e10 ? 10 : error >= e5 ? 5 : error >= e2 ? 2 : 1);\n}\n\nfunction tickStep(start, stop, count) {\n  var step0 = Math.abs(stop - start) / Math.max(0, count),\n      step1 = Math.pow(10, Math.floor(Math.log(step0) / Math.LN10)),\n      error = step0 / step1;\n  if (error >= e10) step1 *= 10;\n  else if (error >= e5) step1 *= 5;\n  else if (error >= e2) step1 *= 2;\n  return stop < start ? -step1 : step1;\n}\n\nvar sturges = function(values) {\n  return Math.ceil(Math.log(values.length) / Math.LN2) + 1;\n};\n\nvar histogram = function() {\n  var value = identity,\n      domain = extent,\n      threshold = sturges;\n\n  function histogram(data) {\n    var i,\n        n = data.length,\n        x,\n        values = new Array(n);\n\n    for (i = 0; i < n; ++i) {\n      values[i] = value(data[i], i, data);\n    }\n\n    var xz = domain(values),\n        x0 = xz[0],\n        x1 = xz[1],\n        tz = threshold(values, x0, x1);\n\n    // Convert number of thresholds into uniform thresholds.\n    if (!Array.isArray(tz)) {\n      tz = tickStep(x0, x1, tz);\n      tz = sequence(Math.ceil(x0 / tz) * tz, Math.floor(x1 / tz) * tz, tz); // exclusive\n    }\n\n    // Remove any thresholds outside the domain.\n    var m = tz.length;\n    while (tz[0] <= x0) tz.shift(), --m;\n    while (tz[m - 1] > x1) tz.pop(), --m;\n\n    var bins = new Array(m + 1),\n        bin;\n\n    // Initialize bins.\n    for (i = 0; i <= m; ++i) {\n      bin = bins[i] = [];\n      bin.x0 = i > 0 ? tz[i - 1] : x0;\n      bin.x1 = i < m ? tz[i] : x1;\n    }\n\n    // Assign data to bins by value, ignoring any outside the domain.\n    for (i = 0; i < n; ++i) {\n      x = values[i];\n      if (x0 <= x && x <= x1) {\n        bins[bisectRight(tz, x, 0, m)].push(data[i]);\n      }\n    }\n\n    return bins;\n  }\n\n  histogram.value = function(_) {\n    return arguments.length ? (value = typeof _ === \"function\" ? _ : constant(_), histogram) : value;\n  };\n\n  histogram.domain = function(_) {\n    return arguments.length ? (domain = typeof _ === \"function\" ? _ : constant([_[0], _[1]]), histogram) : domain;\n  };\n\n  histogram.thresholds = function(_) {\n    return arguments.length ? (threshold = typeof _ === \"function\" ? _ : Array.isArray(_) ? constant(slice.call(_)) : constant(_), histogram) : threshold;\n  };\n\n  return histogram;\n};\n\nvar threshold = function(values, p, valueof) {\n  if (valueof == null) valueof = number;\n  if (!(n = values.length)) return;\n  if ((p = +p) <= 0 || n < 2) return +valueof(values[0], 0, values);\n  if (p >= 1) return +valueof(values[n - 1], n - 1, values);\n  var n,\n      i = (n - 1) * p,\n      i0 = Math.floor(i),\n      value0 = +valueof(values[i0], i0, values),\n      value1 = +valueof(values[i0 + 1], i0 + 1, values);\n  return value0 + (value1 - value0) * (i - i0);\n};\n\nvar freedmanDiaconis = function(values, min, max) {\n  values = map.call(values, number).sort(ascending);\n  return Math.ceil((max - min) / (2 * (threshold(values, 0.75) - threshold(values, 0.25)) * Math.pow(values.length, -1 / 3)));\n};\n\nvar scott = function(values, min, max) {\n  return Math.ceil((max - min) / (3.5 * deviation(values) * Math.pow(values.length, -1 / 3)));\n};\n\nvar max = function(values, valueof) {\n  var n = values.length,\n      i = -1,\n      value,\n      max;\n\n  if (valueof == null) {\n    while (++i < n) { // Find the first comparable value.\n      if ((value = values[i]) != null && value >= value) {\n        max = value;\n        while (++i < n) { // Compare the remaining values.\n          if ((value = values[i]) != null && value > max) {\n            max = value;\n          }\n        }\n      }\n    }\n  }\n\n  else {\n    while (++i < n) { // Find the first comparable value.\n      if ((value = valueof(values[i], i, values)) != null && value >= value) {\n        max = value;\n        while (++i < n) { // Compare the remaining values.\n          if ((value = valueof(values[i], i, values)) != null && value > max) {\n            max = value;\n          }\n        }\n      }\n    }\n  }\n\n  return max;\n};\n\nvar mean = function(values, valueof) {\n  var n = values.length,\n      m = n,\n      i = -1,\n      value,\n      sum = 0;\n\n  if (valueof == null) {\n    while (++i < n) {\n      if (!isNaN(value = number(values[i]))) sum += value;\n      else --m;\n    }\n  }\n\n  else {\n    while (++i < n) {\n      if (!isNaN(value = number(valueof(values[i], i, values)))) sum += value;\n      else --m;\n    }\n  }\n\n  if (m) return sum / m;\n};\n\nvar median = function(values, valueof) {\n  var n = values.length,\n      i = -1,\n      value,\n      numbers = [];\n\n  if (valueof == null) {\n    while (++i < n) {\n      if (!isNaN(value = number(values[i]))) {\n        numbers.push(value);\n      }\n    }\n  }\n\n  else {\n    while (++i < n) {\n      if (!isNaN(value = number(valueof(values[i], i, values)))) {\n        numbers.push(value);\n      }\n    }\n  }\n\n  return threshold(numbers.sort(ascending), 0.5);\n};\n\nvar merge = function(arrays) {\n  var n = arrays.length,\n      m,\n      i = -1,\n      j = 0,\n      merged,\n      array;\n\n  while (++i < n) j += arrays[i].length;\n  merged = new Array(j);\n\n  while (--n >= 0) {\n    array = arrays[n];\n    m = array.length;\n    while (--m >= 0) {\n      merged[--j] = array[m];\n    }\n  }\n\n  return merged;\n};\n\nvar min = function(values, valueof) {\n  var n = values.length,\n      i = -1,\n      value,\n      min;\n\n  if (valueof == null) {\n    while (++i < n) { // Find the first comparable value.\n      if ((value = values[i]) != null && value >= value) {\n        min = value;\n        while (++i < n) { // Compare the remaining values.\n          if ((value = values[i]) != null && min > value) {\n            min = value;\n          }\n        }\n      }\n    }\n  }\n\n  else {\n    while (++i < n) { // Find the first comparable value.\n      if ((value = valueof(values[i], i, values)) != null && value >= value) {\n        min = value;\n        while (++i < n) { // Compare the remaining values.\n          if ((value = valueof(values[i], i, values)) != null && min > value) {\n            min = value;\n          }\n        }\n      }\n    }\n  }\n\n  return min;\n};\n\nvar permute = function(array, indexes) {\n  var i = indexes.length, permutes = new Array(i);\n  while (i--) permutes[i] = array[indexes[i]];\n  return permutes;\n};\n\nvar scan = function(values, compare) {\n  if (!(n = values.length)) return;\n  var n,\n      i = 0,\n      j = 0,\n      xi,\n      xj = values[j];\n\n  if (compare == null) compare = ascending;\n\n  while (++i < n) {\n    if (compare(xi = values[i], xj) < 0 || compare(xj, xj) !== 0) {\n      xj = xi, j = i;\n    }\n  }\n\n  if (compare(xj, xj) === 0) return j;\n};\n\nvar shuffle = function(array, i0, i1) {\n  var m = (i1 == null ? array.length : i1) - (i0 = i0 == null ? 0 : +i0),\n      t,\n      i;\n\n  while (m) {\n    i = Math.random() * m-- | 0;\n    t = array[m + i0];\n    array[m + i0] = array[i + i0];\n    array[i + i0] = t;\n  }\n\n  return array;\n};\n\nvar sum = function(values, valueof) {\n  var n = values.length,\n      i = -1,\n      value,\n      sum = 0;\n\n  if (valueof == null) {\n    while (++i < n) {\n      if (value = +values[i]) sum += value; // Note: zero and null are equivalent.\n    }\n  }\n\n  else {\n    while (++i < n) {\n      if (value = +valueof(values[i], i, values)) sum += value;\n    }\n  }\n\n  return sum;\n};\n\nvar transpose = function(matrix) {\n  if (!(n = matrix.length)) return [];\n  for (var i = -1, m = min(matrix, length), transpose = new Array(m); ++i < m;) {\n    for (var j = -1, n, row = transpose[i] = new Array(n); ++j < n;) {\n      row[j] = matrix[j][i];\n    }\n  }\n  return transpose;\n};\n\nfunction length(d) {\n  return d.length;\n}\n\nvar zip = function() {\n  return transpose(arguments);\n};\n\nvar slice$1 = Array.prototype.slice;\n\nvar identity$1 = function(x) {\n  return x;\n};\n\nvar top = 1;\nvar right = 2;\nvar bottom = 3;\nvar left = 4;\nvar epsilon = 1e-6;\n\nfunction translateX(x) {\n  return \"translate(\" + (x + 0.5) + \",0)\";\n}\n\nfunction translateY(y) {\n  return \"translate(0,\" + (y + 0.5) + \")\";\n}\n\nfunction center(scale) {\n  var offset = Math.max(0, scale.bandwidth() - 1) / 2; // Adjust for 0.5px offset.\n  if (scale.round()) offset = Math.round(offset);\n  return function(d) {\n    return scale(d) + offset;\n  };\n}\n\nfunction entering() {\n  return !this.__axis;\n}\n\nfunction axis(orient, scale) {\n  var tickArguments = [],\n      tickValues = null,\n      tickFormat = null,\n      tickSizeInner = 6,\n      tickSizeOuter = 6,\n      tickPadding = 3,\n      k = orient === top || orient === left ? -1 : 1,\n      x = orient === left || orient === right ? \"x\" : \"y\",\n      transform = orient === top || orient === bottom ? translateX : translateY;\n\n  function axis(context) {\n    var values = tickValues == null ? (scale.ticks ? scale.ticks.apply(scale, tickArguments) : scale.domain()) : tickValues,\n        format = tickFormat == null ? (scale.tickFormat ? scale.tickFormat.apply(scale, tickArguments) : identity$1) : tickFormat,\n        spacing = Math.max(tickSizeInner, 0) + tickPadding,\n        range = scale.range(),\n        range0 = range[0] + 0.5,\n        range1 = range[range.length - 1] + 0.5,\n        position = (scale.bandwidth ? center : identity$1)(scale.copy()),\n        selection = context.selection ? context.selection() : context,\n        path = selection.selectAll(\".domain\").data([null]),\n        tick = selection.selectAll(\".tick\").data(values, scale).order(),\n        tickExit = tick.exit(),\n        tickEnter = tick.enter().append(\"g\").attr(\"class\", \"tick\"),\n        line = tick.select(\"line\"),\n        text = tick.select(\"text\");\n\n    path = path.merge(path.enter().insert(\"path\", \".tick\")\n        .attr(\"class\", \"domain\")\n        .attr(\"stroke\", \"#000\"));\n\n    tick = tick.merge(tickEnter);\n\n    line = line.merge(tickEnter.append(\"line\")\n        .attr(\"stroke\", \"#000\")\n        .attr(x + \"2\", k * tickSizeInner));\n\n    text = text.merge(tickEnter.append(\"text\")\n        .attr(\"fill\", \"#000\")\n        .attr(x, k * spacing)\n        .attr(\"dy\", orient === top ? \"0em\" : orient === bottom ? \"0.71em\" : \"0.32em\"));\n\n    if (context !== selection) {\n      path = path.transition(context);\n      tick = tick.transition(context);\n      line = line.transition(context);\n      text = text.transition(context);\n\n      tickExit = tickExit.transition(context)\n          .attr(\"opacity\", epsilon)\n          .attr(\"transform\", function(d) { return isFinite(d = position(d)) ? transform(d) : this.getAttribute(\"transform\"); });\n\n      tickEnter\n          .attr(\"opacity\", epsilon)\n          .attr(\"transform\", function(d) { var p = this.parentNode.__axis; return transform(p && isFinite(p = p(d)) ? p : position(d)); });\n    }\n\n    tickExit.remove();\n\n    path\n        .attr(\"d\", orient === left || orient == right\n            ? \"M\" + k * tickSizeOuter + \",\" + range0 + \"H0.5V\" + range1 + \"H\" + k * tickSizeOuter\n            : \"M\" + range0 + \",\" + k * tickSizeOuter + \"V0.5H\" + range1 + \"V\" + k * tickSizeOuter);\n\n    tick\n        .attr(\"opacity\", 1)\n        .attr(\"transform\", function(d) { return transform(position(d)); });\n\n    line\n        .attr(x + \"2\", k * tickSizeInner);\n\n    text\n        .attr(x, k * spacing)\n        .text(format);\n\n    selection.filter(entering)\n        .attr(\"fill\", \"none\")\n        .attr(\"font-size\", 10)\n        .attr(\"font-family\", \"sans-serif\")\n        .attr(\"text-anchor\", orient === right ? \"start\" : orient === left ? \"end\" : \"middle\");\n\n    selection\n        .each(function() { this.__axis = position; });\n  }\n\n  axis.scale = function(_) {\n    return arguments.length ? (scale = _, axis) : scale;\n  };\n\n  axis.ticks = function() {\n    return tickArguments = slice$1.call(arguments), axis;\n  };\n\n  axis.tickArguments = function(_) {\n    return arguments.length ? (tickArguments = _ == null ? [] : slice$1.call(_), axis) : tickArguments.slice();\n  };\n\n  axis.tickValues = function(_) {\n    return arguments.length ? (tickValues = _ == null ? null : slice$1.call(_), axis) : tickValues && tickValues.slice();\n  };\n\n  axis.tickFormat = function(_) {\n    return arguments.length ? (tickFormat = _, axis) : tickFormat;\n  };\n\n  axis.tickSize = function(_) {\n    return arguments.length ? (tickSizeInner = tickSizeOuter = +_, axis) : tickSizeInner;\n  };\n\n  axis.tickSizeInner = function(_) {\n    return arguments.length ? (tickSizeInner = +_, axis) : tickSizeInner;\n  };\n\n  axis.tickSizeOuter = function(_) {\n    return arguments.length ? (tickSizeOuter = +_, axis) : tickSizeOuter;\n  };\n\n  axis.tickPadding = function(_) {\n    return arguments.length ? (tickPadding = +_, axis) : tickPadding;\n  };\n\n  return axis;\n}\n\nfunction axisTop(scale) {\n  return axis(top, scale);\n}\n\nfunction axisRight(scale) {\n  return axis(right, scale);\n}\n\nfunction axisBottom(scale) {\n  return axis(bottom, scale);\n}\n\nfunction axisLeft(scale) {\n  return axis(left, scale);\n}\n\nvar noop = {value: function() {}};\n\nfunction dispatch() {\n  for (var i = 0, n = arguments.length, _ = {}, t; i < n; ++i) {\n    if (!(t = arguments[i] + \"\") || (t in _)) throw new Error(\"illegal type: \" + t);\n    _[t] = [];\n  }\n  return new Dispatch(_);\n}\n\nfunction Dispatch(_) {\n  this._ = _;\n}\n\nfunction parseTypenames(typenames, types) {\n  return typenames.trim().split(/^|\\s+/).map(function(t) {\n    var name = \"\", i = t.indexOf(\".\");\n    if (i >= 0) name = t.slice(i + 1), t = t.slice(0, i);\n    if (t && !types.hasOwnProperty(t)) throw new Error(\"unknown type: \" + t);\n    return {type: t, name: name};\n  });\n}\n\nDispatch.prototype = dispatch.prototype = {\n  constructor: Dispatch,\n  on: function(typename, callback) {\n    var _ = this._,\n        T = parseTypenames(typename + \"\", _),\n        t,\n        i = -1,\n        n = T.length;\n\n    // If no callback was specified, return the callback of the given type and name.\n    if (arguments.length < 2) {\n      while (++i < n) if ((t = (typename = T[i]).type) && (t = get(_[t], typename.name))) return t;\n      return;\n    }\n\n    // If a type was specified, set the callback for the given type and name.\n    // Otherwise, if a null callback was specified, remove callbacks of the given name.\n    if (callback != null && typeof callback !== \"function\") throw new Error(\"invalid callback: \" + callback);\n    while (++i < n) {\n      if (t = (typename = T[i]).type) _[t] = set(_[t], typename.name, callback);\n      else if (callback == null) for (t in _) _[t] = set(_[t], typename.name, null);\n    }\n\n    return this;\n  },\n  copy: function() {\n    var copy = {}, _ = this._;\n    for (var t in _) copy[t] = _[t].slice();\n    return new Dispatch(copy);\n  },\n  call: function(type, that) {\n    if ((n = arguments.length - 2) > 0) for (var args = new Array(n), i = 0, n, t; i < n; ++i) args[i] = arguments[i + 2];\n    if (!this._.hasOwnProperty(type)) throw new Error(\"unknown type: \" + type);\n    for (t = this._[type], i = 0, n = t.length; i < n; ++i) t[i].value.apply(that, args);\n  },\n  apply: function(type, that, args) {\n    if (!this._.hasOwnProperty(type)) throw new Error(\"unknown type: \" + type);\n    for (var t = this._[type], i = 0, n = t.length; i < n; ++i) t[i].value.apply(that, args);\n  }\n};\n\nfunction get(type, name) {\n  for (var i = 0, n = type.length, c; i < n; ++i) {\n    if ((c = type[i]).name === name) {\n      return c.value;\n    }\n  }\n}\n\nfunction set(type, name, callback) {\n  for (var i = 0, n = type.length; i < n; ++i) {\n    if (type[i].name === name) {\n      type[i] = noop, type = type.slice(0, i).concat(type.slice(i + 1));\n      break;\n    }\n  }\n  if (callback != null) type.push({name: name, value: callback});\n  return type;\n}\n\nvar xhtml = \"http://www.w3.org/1999/xhtml\";\n\nvar namespaces = {\n  svg: \"http://www.w3.org/2000/svg\",\n  xhtml: xhtml,\n  xlink: \"http://www.w3.org/1999/xlink\",\n  xml: \"http://www.w3.org/XML/1998/namespace\",\n  xmlns: \"http://www.w3.org/2000/xmlns/\"\n};\n\nvar namespace = function(name) {\n  var prefix = name += \"\", i = prefix.indexOf(\":\");\n  if (i >= 0 && (prefix = name.slice(0, i)) !== \"xmlns\") name = name.slice(i + 1);\n  return namespaces.hasOwnProperty(prefix) ? {space: namespaces[prefix], local: name} : name;\n};\n\nfunction creatorInherit(name) {\n  return function() {\n    var document = this.ownerDocument,\n        uri = this.namespaceURI;\n    return uri === xhtml && document.documentElement.namespaceURI === xhtml\n        ? document.createElement(name)\n        : document.createElementNS(uri, name);\n  };\n}\n\nfunction creatorFixed(fullname) {\n  return function() {\n    return this.ownerDocument.createElementNS(fullname.space, fullname.local);\n  };\n}\n\nvar creator = function(name) {\n  var fullname = namespace(name);\n  return (fullname.local\n      ? creatorFixed\n      : creatorInherit)(fullname);\n};\n\nvar nextId = 0;\n\nfunction local$1() {\n  return new Local;\n}\n\nfunction Local() {\n  this._ = \"@\" + (++nextId).toString(36);\n}\n\nLocal.prototype = local$1.prototype = {\n  constructor: Local,\n  get: function(node) {\n    var id = this._;\n    while (!(id in node)) if (!(node = node.parentNode)) return;\n    return node[id];\n  },\n  set: function(node, value) {\n    return node[this._] = value;\n  },\n  remove: function(node) {\n    return this._ in node && delete node[this._];\n  },\n  toString: function() {\n    return this._;\n  }\n};\n\nvar matcher = function(selector) {\n  return function() {\n    return this.matches(selector);\n  };\n};\n\nif (typeof document !== \"undefined\") {\n  var element = document.documentElement;\n  if (!element.matches) {\n    var vendorMatches = element.webkitMatchesSelector\n        || element.msMatchesSelector\n        || element.mozMatchesSelector\n        || element.oMatchesSelector;\n    matcher = function(selector) {\n      return function() {\n        return vendorMatches.call(this, selector);\n      };\n    };\n  }\n}\n\nvar matcher$1 = matcher;\n\nvar filterEvents = {};\n\nexports.event = null;\n\nif (typeof document !== \"undefined\") {\n  var element$1 = document.documentElement;\n  if (!(\"onmouseenter\" in element$1)) {\n    filterEvents = {mouseenter: \"mouseover\", mouseleave: \"mouseout\"};\n  }\n}\n\nfunction filterContextListener(listener, index, group) {\n  listener = contextListener(listener, index, group);\n  return function(event) {\n    var related = event.relatedTarget;\n    if (!related || (related !== this && !(related.compareDocumentPosition(this) & 8))) {\n      listener.call(this, event);\n    }\n  };\n}\n\nfunction contextListener(listener, index, group) {\n  return function(event1) {\n    var event0 = exports.event; // Events can be reentrant (e.g., focus).\n    exports.event = event1;\n    try {\n      listener.call(this, this.__data__, index, group);\n    } finally {\n      exports.event = event0;\n    }\n  };\n}\n\nfunction parseTypenames$1(typenames) {\n  return typenames.trim().split(/^|\\s+/).map(function(t) {\n    var name = \"\", i = t.indexOf(\".\");\n    if (i >= 0) name = t.slice(i + 1), t = t.slice(0, i);\n    return {type: t, name: name};\n  });\n}\n\nfunction onRemove(typename) {\n  return function() {\n    var on = this.__on;\n    if (!on) return;\n    for (var j = 0, i = -1, m = on.length, o; j < m; ++j) {\n      if (o = on[j], (!typename.type || o.type === typename.type) && o.name === typename.name) {\n        this.removeEventListener(o.type, o.listener, o.capture);\n      } else {\n        on[++i] = o;\n      }\n    }\n    if (++i) on.length = i;\n    else delete this.__on;\n  };\n}\n\nfunction onAdd(typename, value, capture) {\n  var wrap = filterEvents.hasOwnProperty(typename.type) ? filterContextListener : contextListener;\n  return function(d, i, group) {\n    var on = this.__on, o, listener = wrap(value, i, group);\n    if (on) for (var j = 0, m = on.length; j < m; ++j) {\n      if ((o = on[j]).type === typename.type && o.name === typename.name) {\n        this.removeEventListener(o.type, o.listener, o.capture);\n        this.addEventListener(o.type, o.listener = listener, o.capture = capture);\n        o.value = value;\n        return;\n      }\n    }\n    this.addEventListener(typename.type, listener, capture);\n    o = {type: typename.type, name: typename.name, value: value, listener: listener, capture: capture};\n    if (!on) this.__on = [o];\n    else on.push(o);\n  };\n}\n\nvar selection_on = function(typename, value, capture) {\n  var typenames = parseTypenames$1(typename + \"\"), i, n = typenames.length, t;\n\n  if (arguments.length < 2) {\n    var on = this.node().__on;\n    if (on) for (var j = 0, m = on.length, o; j < m; ++j) {\n      for (i = 0, o = on[j]; i < n; ++i) {\n        if ((t = typenames[i]).type === o.type && t.name === o.name) {\n          return o.value;\n        }\n      }\n    }\n    return;\n  }\n\n  on = value ? onAdd : onRemove;\n  if (capture == null) capture = false;\n  for (i = 0; i < n; ++i) this.each(on(typenames[i], value, capture));\n  return this;\n};\n\nfunction customEvent(event1, listener, that, args) {\n  var event0 = exports.event;\n  event1.sourceEvent = exports.event;\n  exports.event = event1;\n  try {\n    return listener.apply(that, args);\n  } finally {\n    exports.event = event0;\n  }\n}\n\nvar sourceEvent = function() {\n  var current = exports.event, source;\n  while (source = current.sourceEvent) current = source;\n  return current;\n};\n\nvar point = function(node, event) {\n  var svg = node.ownerSVGElement || node;\n\n  if (svg.createSVGPoint) {\n    var point = svg.createSVGPoint();\n    point.x = event.clientX, point.y = event.clientY;\n    point = point.matrixTransform(node.getScreenCTM().inverse());\n    return [point.x, point.y];\n  }\n\n  var rect = node.getBoundingClientRect();\n  return [event.clientX - rect.left - node.clientLeft, event.clientY - rect.top - node.clientTop];\n};\n\nvar mouse = function(node) {\n  var event = sourceEvent();\n  if (event.changedTouches) event = event.changedTouches[0];\n  return point(node, event);\n};\n\nfunction none() {}\n\nvar selector = function(selector) {\n  return selector == null ? none : function() {\n    return this.querySelector(selector);\n  };\n};\n\nvar selection_select = function(select) {\n  if (typeof select !== \"function\") select = selector(select);\n\n  for (var groups = this._groups, m = groups.length, subgroups = new Array(m), j = 0; j < m; ++j) {\n    for (var group = groups[j], n = group.length, subgroup = subgroups[j] = new Array(n), node, subnode, i = 0; i < n; ++i) {\n      if ((node = group[i]) && (subnode = select.call(node, node.__data__, i, group))) {\n        if (\"__data__\" in node) subnode.__data__ = node.__data__;\n        subgroup[i] = subnode;\n      }\n    }\n  }\n\n  return new Selection(subgroups, this._parents);\n};\n\nfunction empty$1() {\n  return [];\n}\n\nvar selectorAll = function(selector) {\n  return selector == null ? empty$1 : function() {\n    return this.querySelectorAll(selector);\n  };\n};\n\nvar selection_selectAll = function(select) {\n  if (typeof select !== \"function\") select = selectorAll(select);\n\n  for (var groups = this._groups, m = groups.length, subgroups = [], parents = [], j = 0; j < m; ++j) {\n    for (var group = groups[j], n = group.length, node, i = 0; i < n; ++i) {\n      if (node = group[i]) {\n        subgroups.push(select.call(node, node.__data__, i, group));\n        parents.push(node);\n      }\n    }\n  }\n\n  return new Selection(subgroups, parents);\n};\n\nvar selection_filter = function(match) {\n  if (typeof match !== \"function\") match = matcher$1(match);\n\n  for (var groups = this._groups, m = groups.length, subgroups = new Array(m), j = 0; j < m; ++j) {\n    for (var group = groups[j], n = group.length, subgroup = subgroups[j] = [], node, i = 0; i < n; ++i) {\n      if ((node = group[i]) && match.call(node, node.__data__, i, group)) {\n        subgroup.push(node);\n      }\n    }\n  }\n\n  return new Selection(subgroups, this._parents);\n};\n\nvar sparse = function(update) {\n  return new Array(update.length);\n};\n\nvar selection_enter = function() {\n  return new Selection(this._enter || this._groups.map(sparse), this._parents);\n};\n\nfunction EnterNode(parent, datum) {\n  this.ownerDocument = parent.ownerDocument;\n  this.namespaceURI = parent.namespaceURI;\n  this._next = null;\n  this._parent = parent;\n  this.__data__ = datum;\n}\n\nEnterNode.prototype = {\n  constructor: EnterNode,\n  appendChild: function(child) { return this._parent.insertBefore(child, this._next); },\n  insertBefore: function(child, next) { return this._parent.insertBefore(child, next); },\n  querySelector: function(selector) { return this._parent.querySelector(selector); },\n  querySelectorAll: function(selector) { return this._parent.querySelectorAll(selector); }\n};\n\nvar constant$1 = function(x) {\n  return function() {\n    return x;\n  };\n};\n\nvar keyPrefix = \"$\"; // Protect against keys like “__proto__”.\n\nfunction bindIndex(parent, group, enter, update, exit, data) {\n  var i = 0,\n      node,\n      groupLength = group.length,\n      dataLength = data.length;\n\n  // Put any non-null nodes that fit into update.\n  // Put any null nodes into enter.\n  // Put any remaining data into enter.\n  for (; i < dataLength; ++i) {\n    if (node = group[i]) {\n      node.__data__ = data[i];\n      update[i] = node;\n    } else {\n      enter[i] = new EnterNode(parent, data[i]);\n    }\n  }\n\n  // Put any non-null nodes that don’t fit into exit.\n  for (; i < groupLength; ++i) {\n    if (node = group[i]) {\n      exit[i] = node;\n    }\n  }\n}\n\nfunction bindKey(parent, group, enter, update, exit, data, key) {\n  var i,\n      node,\n      nodeByKeyValue = {},\n      groupLength = group.length,\n      dataLength = data.length,\n      keyValues = new Array(groupLength),\n      keyValue;\n\n  // Compute the key for each node.\n  // If multiple nodes have the same key, the duplicates are added to exit.\n  for (i = 0; i < groupLength; ++i) {\n    if (node = group[i]) {\n      keyValues[i] = keyValue = keyPrefix + key.call(node, node.__data__, i, group);\n      if (keyValue in nodeByKeyValue) {\n        exit[i] = node;\n      } else {\n        nodeByKeyValue[keyValue] = node;\n      }\n    }\n  }\n\n  // Compute the key for each datum.\n  // If there a node associated with this key, join and add it to update.\n  // If there is not (or the key is a duplicate), add it to enter.\n  for (i = 0; i < dataLength; ++i) {\n    keyValue = keyPrefix + key.call(parent, data[i], i, data);\n    if (node = nodeByKeyValue[keyValue]) {\n      update[i] = node;\n      node.__data__ = data[i];\n      nodeByKeyValue[keyValue] = null;\n    } else {\n      enter[i] = new EnterNode(parent, data[i]);\n    }\n  }\n\n  // Add any remaining nodes that were not bound to data to exit.\n  for (i = 0; i < groupLength; ++i) {\n    if ((node = group[i]) && (nodeByKeyValue[keyValues[i]] === node)) {\n      exit[i] = node;\n    }\n  }\n}\n\nvar selection_data = function(value, key) {\n  if (!value) {\n    data = new Array(this.size()), j = -1;\n    this.each(function(d) { data[++j] = d; });\n    return data;\n  }\n\n  var bind = key ? bindKey : bindIndex,\n      parents = this._parents,\n      groups = this._groups;\n\n  if (typeof value !== \"function\") value = constant$1(value);\n\n  for (var m = groups.length, update = new Array(m), enter = new Array(m), exit = new Array(m), j = 0; j < m; ++j) {\n    var parent = parents[j],\n        group = groups[j],\n        groupLength = group.length,\n        data = value.call(parent, parent && parent.__data__, j, parents),\n        dataLength = data.length,\n        enterGroup = enter[j] = new Array(dataLength),\n        updateGroup = update[j] = new Array(dataLength),\n        exitGroup = exit[j] = new Array(groupLength);\n\n    bind(parent, group, enterGroup, updateGroup, exitGroup, data, key);\n\n    // Now connect the enter nodes to their following update node, such that\n    // appendChild can insert the materialized enter node before this node,\n    // rather than at the end of the parent node.\n    for (var i0 = 0, i1 = 0, previous, next; i0 < dataLength; ++i0) {\n      if (previous = enterGroup[i0]) {\n        if (i0 >= i1) i1 = i0 + 1;\n        while (!(next = updateGroup[i1]) && ++i1 < dataLength);\n        previous._next = next || null;\n      }\n    }\n  }\n\n  update = new Selection(update, parents);\n  update._enter = enter;\n  update._exit = exit;\n  return update;\n};\n\nvar selection_exit = function() {\n  return new Selection(this._exit || this._groups.map(sparse), this._parents);\n};\n\nvar selection_merge = function(selection) {\n\n  for (var groups0 = this._groups, groups1 = selection._groups, m0 = groups0.length, m1 = groups1.length, m = Math.min(m0, m1), merges = new Array(m0), j = 0; j < m; ++j) {\n    for (var group0 = groups0[j], group1 = groups1[j], n = group0.length, merge = merges[j] = new Array(n), node, i = 0; i < n; ++i) {\n      if (node = group0[i] || group1[i]) {\n        merge[i] = node;\n      }\n    }\n  }\n\n  for (; j < m0; ++j) {\n    merges[j] = groups0[j];\n  }\n\n  return new Selection(merges, this._parents);\n};\n\nvar selection_order = function() {\n\n  for (var groups = this._groups, j = -1, m = groups.length; ++j < m;) {\n    for (var group = groups[j], i = group.length - 1, next = group[i], node; --i >= 0;) {\n      if (node = group[i]) {\n        if (next && next !== node.nextSibling) next.parentNode.insertBefore(node, next);\n        next = node;\n      }\n    }\n  }\n\n  return this;\n};\n\nvar selection_sort = function(compare) {\n  if (!compare) compare = ascending$1;\n\n  function compareNode(a, b) {\n    return a && b ? compare(a.__data__, b.__data__) : !a - !b;\n  }\n\n  for (var groups = this._groups, m = groups.length, sortgroups = new Array(m), j = 0; j < m; ++j) {\n    for (var group = groups[j], n = group.length, sortgroup = sortgroups[j] = new Array(n), node, i = 0; i < n; ++i) {\n      if (node = group[i]) {\n        sortgroup[i] = node;\n      }\n    }\n    sortgroup.sort(compareNode);\n  }\n\n  return new Selection(sortgroups, this._parents).order();\n};\n\nfunction ascending$1(a, b) {\n  return a < b ? -1 : a > b ? 1 : a >= b ? 0 : NaN;\n}\n\nvar selection_call = function() {\n  var callback = arguments[0];\n  arguments[0] = this;\n  callback.apply(null, arguments);\n  return this;\n};\n\nvar selection_nodes = function() {\n  var nodes = new Array(this.size()), i = -1;\n  this.each(function() { nodes[++i] = this; });\n  return nodes;\n};\n\nvar selection_node = function() {\n\n  for (var groups = this._groups, j = 0, m = groups.length; j < m; ++j) {\n    for (var group = groups[j], i = 0, n = group.length; i < n; ++i) {\n      var node = group[i];\n      if (node) return node;\n    }\n  }\n\n  return null;\n};\n\nvar selection_size = function() {\n  var size = 0;\n  this.each(function() { ++size; });\n  return size;\n};\n\nvar selection_empty = function() {\n  return !this.node();\n};\n\nvar selection_each = function(callback) {\n\n  for (var groups = this._groups, j = 0, m = groups.length; j < m; ++j) {\n    for (var group = groups[j], i = 0, n = group.length, node; i < n; ++i) {\n      if (node = group[i]) callback.call(node, node.__data__, i, group);\n    }\n  }\n\n  return this;\n};\n\nfunction attrRemove(name) {\n  return function() {\n    this.removeAttribute(name);\n  };\n}\n\nfunction attrRemoveNS(fullname) {\n  return function() {\n    this.removeAttributeNS(fullname.space, fullname.local);\n  };\n}\n\nfunction attrConstant(name, value) {\n  return function() {\n    this.setAttribute(name, value);\n  };\n}\n\nfunction attrConstantNS(fullname, value) {\n  return function() {\n    this.setAttributeNS(fullname.space, fullname.local, value);\n  };\n}\n\nfunction attrFunction(name, value) {\n  return function() {\n    var v = value.apply(this, arguments);\n    if (v == null) this.removeAttribute(name);\n    else this.setAttribute(name, v);\n  };\n}\n\nfunction attrFunctionNS(fullname, value) {\n  return function() {\n    var v = value.apply(this, arguments);\n    if (v == null) this.removeAttributeNS(fullname.space, fullname.local);\n    else this.setAttributeNS(fullname.space, fullname.local, v);\n  };\n}\n\nvar selection_attr = function(name, value) {\n  var fullname = namespace(name);\n\n  if (arguments.length < 2) {\n    var node = this.node();\n    return fullname.local\n        ? node.getAttributeNS(fullname.space, fullname.local)\n        : node.getAttribute(fullname);\n  }\n\n  return this.each((value == null\n      ? (fullname.local ? attrRemoveNS : attrRemove) : (typeof value === \"function\"\n      ? (fullname.local ? attrFunctionNS : attrFunction)\n      : (fullname.local ? attrConstantNS : attrConstant)))(fullname, value));\n};\n\nvar defaultView = function(node) {\n  return (node.ownerDocument && node.ownerDocument.defaultView) // node is a Node\n      || (node.document && node) // node is a Window\n      || node.defaultView; // node is a Document\n};\n\nfunction styleRemove(name) {\n  return function() {\n    this.style.removeProperty(name);\n  };\n}\n\nfunction styleConstant(name, value, priority) {\n  return function() {\n    this.style.setProperty(name, value, priority);\n  };\n}\n\nfunction styleFunction(name, value, priority) {\n  return function() {\n    var v = value.apply(this, arguments);\n    if (v == null) this.style.removeProperty(name);\n    else this.style.setProperty(name, v, priority);\n  };\n}\n\nvar selection_style = function(name, value, priority) {\n  return arguments.length > 1\n      ? this.each((value == null\n            ? styleRemove : typeof value === \"function\"\n            ? styleFunction\n            : styleConstant)(name, value, priority == null ? \"\" : priority))\n      : styleValue(this.node(), name);\n};\n\nfunction styleValue(node, name) {\n  return node.style.getPropertyValue(name)\n      || defaultView(node).getComputedStyle(node, null).getPropertyValue(name);\n}\n\nfunction propertyRemove(name) {\n  return function() {\n    delete this[name];\n  };\n}\n\nfunction propertyConstant(name, value) {\n  return function() {\n    this[name] = value;\n  };\n}\n\nfunction propertyFunction(name, value) {\n  return function() {\n    var v = value.apply(this, arguments);\n    if (v == null) delete this[name];\n    else this[name] = v;\n  };\n}\n\nvar selection_property = function(name, value) {\n  return arguments.length > 1\n      ? this.each((value == null\n          ? propertyRemove : typeof value === \"function\"\n          ? propertyFunction\n          : propertyConstant)(name, value))\n      : this.node()[name];\n};\n\nfunction classArray(string) {\n  return string.trim().split(/^|\\s+/);\n}\n\nfunction classList(node) {\n  return node.classList || new ClassList(node);\n}\n\nfunction ClassList(node) {\n  this._node = node;\n  this._names = classArray(node.getAttribute(\"class\") || \"\");\n}\n\nClassList.prototype = {\n  add: function(name) {\n    var i = this._names.indexOf(name);\n    if (i < 0) {\n      this._names.push(name);\n      this._node.setAttribute(\"class\", this._names.join(\" \"));\n    }\n  },\n  remove: function(name) {\n    var i = this._names.indexOf(name);\n    if (i >= 0) {\n      this._names.splice(i, 1);\n      this._node.setAttribute(\"class\", this._names.join(\" \"));\n    }\n  },\n  contains: function(name) {\n    return this._names.indexOf(name) >= 0;\n  }\n};\n\nfunction classedAdd(node, names) {\n  var list = classList(node), i = -1, n = names.length;\n  while (++i < n) list.add(names[i]);\n}\n\nfunction classedRemove(node, names) {\n  var list = classList(node), i = -1, n = names.length;\n  while (++i < n) list.remove(names[i]);\n}\n\nfunction classedTrue(names) {\n  return function() {\n    classedAdd(this, names);\n  };\n}\n\nfunction classedFalse(names) {\n  return function() {\n    classedRemove(this, names);\n  };\n}\n\nfunction classedFunction(names, value) {\n  return function() {\n    (value.apply(this, arguments) ? classedAdd : classedRemove)(this, names);\n  };\n}\n\nvar selection_classed = function(name, value) {\n  var names = classArray(name + \"\");\n\n  if (arguments.length < 2) {\n    var list = classList(this.node()), i = -1, n = names.length;\n    while (++i < n) if (!list.contains(names[i])) return false;\n    return true;\n  }\n\n  return this.each((typeof value === \"function\"\n      ? classedFunction : value\n      ? classedTrue\n      : classedFalse)(names, value));\n};\n\nfunction textRemove() {\n  this.textContent = \"\";\n}\n\nfunction textConstant(value) {\n  return function() {\n    this.textContent = value;\n  };\n}\n\nfunction textFunction(value) {\n  return function() {\n    var v = value.apply(this, arguments);\n    this.textContent = v == null ? \"\" : v;\n  };\n}\n\nvar selection_text = function(value) {\n  return arguments.length\n      ? this.each(value == null\n          ? textRemove : (typeof value === \"function\"\n          ? textFunction\n          : textConstant)(value))\n      : this.node().textContent;\n};\n\nfunction htmlRemove() {\n  this.innerHTML = \"\";\n}\n\nfunction htmlConstant(value) {\n  return function() {\n    this.innerHTML = value;\n  };\n}\n\nfunction htmlFunction(value) {\n  return function() {\n    var v = value.apply(this, arguments);\n    this.innerHTML = v == null ? \"\" : v;\n  };\n}\n\nvar selection_html = function(value) {\n  return arguments.length\n      ? this.each(value == null\n          ? htmlRemove : (typeof value === \"function\"\n          ? htmlFunction\n          : htmlConstant)(value))\n      : this.node().innerHTML;\n};\n\nfunction raise() {\n  if (this.nextSibling) this.parentNode.appendChild(this);\n}\n\nvar selection_raise = function() {\n  return this.each(raise);\n};\n\nfunction lower() {\n  if (this.previousSibling) this.parentNode.insertBefore(this, this.parentNode.firstChild);\n}\n\nvar selection_lower = function() {\n  return this.each(lower);\n};\n\nvar selection_append = function(name) {\n  var create = typeof name === \"function\" ? name : creator(name);\n  return this.select(function() {\n    return this.appendChild(create.apply(this, arguments));\n  });\n};\n\nfunction constantNull() {\n  return null;\n}\n\nvar selection_insert = function(name, before) {\n  var create = typeof name === \"function\" ? name : creator(name),\n      select = before == null ? constantNull : typeof before === \"function\" ? before : selector(before);\n  return this.select(function() {\n    return this.insertBefore(create.apply(this, arguments), select.apply(this, arguments) || null);\n  });\n};\n\nfunction remove() {\n  var parent = this.parentNode;\n  if (parent) parent.removeChild(this);\n}\n\nvar selection_remove = function() {\n  return this.each(remove);\n};\n\nvar selection_datum = function(value) {\n  return arguments.length\n      ? this.property(\"__data__\", value)\n      : this.node().__data__;\n};\n\nfunction dispatchEvent(node, type, params) {\n  var window = defaultView(node),\n      event = window.CustomEvent;\n\n  if (typeof event === \"function\") {\n    event = new event(type, params);\n  } else {\n    event = window.document.createEvent(\"Event\");\n    if (params) event.initEvent(type, params.bubbles, params.cancelable), event.detail = params.detail;\n    else event.initEvent(type, false, false);\n  }\n\n  node.dispatchEvent(event);\n}\n\nfunction dispatchConstant(type, params) {\n  return function() {\n    return dispatchEvent(this, type, params);\n  };\n}\n\nfunction dispatchFunction(type, params) {\n  return function() {\n    return dispatchEvent(this, type, params.apply(this, arguments));\n  };\n}\n\nvar selection_dispatch = function(type, params) {\n  return this.each((typeof params === \"function\"\n      ? dispatchFunction\n      : dispatchConstant)(type, params));\n};\n\nvar root = [null];\n\nfunction Selection(groups, parents) {\n  this._groups = groups;\n  this._parents = parents;\n}\n\nfunction selection() {\n  return new Selection([[document.documentElement]], root);\n}\n\nSelection.prototype = selection.prototype = {\n  constructor: Selection,\n  select: selection_select,\n  selectAll: selection_selectAll,\n  filter: selection_filter,\n  data: selection_data,\n  enter: selection_enter,\n  exit: selection_exit,\n  merge: selection_merge,\n  order: selection_order,\n  sort: selection_sort,\n  call: selection_call,\n  nodes: selection_nodes,\n  node: selection_node,\n  size: selection_size,\n  empty: selection_empty,\n  each: selection_each,\n  attr: selection_attr,\n  style: selection_style,\n  property: selection_property,\n  classed: selection_classed,\n  text: selection_text,\n  html: selection_html,\n  raise: selection_raise,\n  lower: selection_lower,\n  append: selection_append,\n  insert: selection_insert,\n  remove: selection_remove,\n  datum: selection_datum,\n  on: selection_on,\n  dispatch: selection_dispatch\n};\n\nvar select = function(selector) {\n  return typeof selector === \"string\"\n      ? new Selection([[document.querySelector(selector)]], [document.documentElement])\n      : new Selection([[selector]], root);\n};\n\nvar selectAll = function(selector) {\n  return typeof selector === \"string\"\n      ? new Selection([document.querySelectorAll(selector)], [document.documentElement])\n      : new Selection([selector == null ? [] : selector], root);\n};\n\nvar touch = function(node, touches, identifier) {\n  if (arguments.length < 3) identifier = touches, touches = sourceEvent().changedTouches;\n\n  for (var i = 0, n = touches ? touches.length : 0, touch; i < n; ++i) {\n    if ((touch = touches[i]).identifier === identifier) {\n      return point(node, touch);\n    }\n  }\n\n  return null;\n};\n\nvar touches = function(node, touches) {\n  if (touches == null) touches = sourceEvent().touches;\n\n  for (var i = 0, n = touches ? touches.length : 0, points = new Array(n); i < n; ++i) {\n    points[i] = point(node, touches[i]);\n  }\n\n  return points;\n};\n\nfunction nopropagation() {\n  exports.event.stopImmediatePropagation();\n}\n\nvar noevent = function() {\n  exports.event.preventDefault();\n  exports.event.stopImmediatePropagation();\n};\n\nvar dragDisable = function(view) {\n  var root = view.document.documentElement,\n      selection$$1 = select(view).on(\"dragstart.drag\", noevent, true);\n  if (\"onselectstart\" in root) {\n    selection$$1.on(\"selectstart.drag\", noevent, true);\n  } else {\n    root.__noselect = root.style.MozUserSelect;\n    root.style.MozUserSelect = \"none\";\n  }\n};\n\nfunction yesdrag(view, noclick) {\n  var root = view.document.documentElement,\n      selection$$1 = select(view).on(\"dragstart.drag\", null);\n  if (noclick) {\n    selection$$1.on(\"click.drag\", noevent, true);\n    setTimeout(function() { selection$$1.on(\"click.drag\", null); }, 0);\n  }\n  if (\"onselectstart\" in root) {\n    selection$$1.on(\"selectstart.drag\", null);\n  } else {\n    root.style.MozUserSelect = root.__noselect;\n    delete root.__noselect;\n  }\n}\n\nvar constant$2 = function(x) {\n  return function() {\n    return x;\n  };\n};\n\nfunction DragEvent(target, type, subject, id, active, x, y, dx, dy, dispatch) {\n  this.target = target;\n  this.type = type;\n  this.subject = subject;\n  this.identifier = id;\n  this.active = active;\n  this.x = x;\n  this.y = y;\n  this.dx = dx;\n  this.dy = dy;\n  this._ = dispatch;\n}\n\nDragEvent.prototype.on = function() {\n  var value = this._.on.apply(this._, arguments);\n  return value === this._ ? this : value;\n};\n\n// Ignore right-click, since that should open the context menu.\nfunction defaultFilter$1() {\n  return !exports.event.button;\n}\n\nfunction defaultContainer() {\n  return this.parentNode;\n}\n\nfunction defaultSubject(d) {\n  return d == null ? {x: exports.event.x, y: exports.event.y} : d;\n}\n\nvar drag = function() {\n  var filter = defaultFilter$1,\n      container = defaultContainer,\n      subject = defaultSubject,\n      gestures = {},\n      listeners = dispatch(\"start\", \"drag\", \"end\"),\n      active = 0,\n      mousedownx,\n      mousedowny,\n      mousemoving,\n      touchending,\n      clickDistance2 = 0;\n\n  function drag(selection$$1) {\n    selection$$1\n        .on(\"mousedown.drag\", mousedowned)\n        .on(\"touchstart.drag\", touchstarted)\n        .on(\"touchmove.drag\", touchmoved)\n        .on(\"touchend.drag touchcancel.drag\", touchended)\n        .style(\"-webkit-tap-highlight-color\", \"rgba(0,0,0,0)\");\n  }\n\n  function mousedowned() {\n    if (touchending || !filter.apply(this, arguments)) return;\n    var gesture = beforestart(\"mouse\", container.apply(this, arguments), mouse, this, arguments);\n    if (!gesture) return;\n    select(exports.event.view).on(\"mousemove.drag\", mousemoved, true).on(\"mouseup.drag\", mouseupped, true);\n    dragDisable(exports.event.view);\n    nopropagation();\n    mousemoving = false;\n    mousedownx = exports.event.clientX;\n    mousedowny = exports.event.clientY;\n    gesture(\"start\");\n  }\n\n  function mousemoved() {\n    noevent();\n    if (!mousemoving) {\n      var dx = exports.event.clientX - mousedownx, dy = exports.event.clientY - mousedowny;\n      mousemoving = dx * dx + dy * dy > clickDistance2;\n    }\n    gestures.mouse(\"drag\");\n  }\n\n  function mouseupped() {\n    select(exports.event.view).on(\"mousemove.drag mouseup.drag\", null);\n    yesdrag(exports.event.view, mousemoving);\n    noevent();\n    gestures.mouse(\"end\");\n  }\n\n  function touchstarted() {\n    if (!filter.apply(this, arguments)) return;\n    var touches$$1 = exports.event.changedTouches,\n        c = container.apply(this, arguments),\n        n = touches$$1.length, i, gesture;\n\n    for (i = 0; i < n; ++i) {\n      if (gesture = beforestart(touches$$1[i].identifier, c, touch, this, arguments)) {\n        nopropagation();\n        gesture(\"start\");\n      }\n    }\n  }\n\n  function touchmoved() {\n    var touches$$1 = exports.event.changedTouches,\n        n = touches$$1.length, i, gesture;\n\n    for (i = 0; i < n; ++i) {\n      if (gesture = gestures[touches$$1[i].identifier]) {\n        noevent();\n        gesture(\"drag\");\n      }\n    }\n  }\n\n  function touchended() {\n    var touches$$1 = exports.event.changedTouches,\n        n = touches$$1.length, i, gesture;\n\n    if (touchending) clearTimeout(touchending);\n    touchending = setTimeout(function() { touchending = null; }, 500); // Ghost clicks are delayed!\n    for (i = 0; i < n; ++i) {\n      if (gesture = gestures[touches$$1[i].identifier]) {\n        nopropagation();\n        gesture(\"end\");\n      }\n    }\n  }\n\n  function beforestart(id, container, point, that, args) {\n    var p = point(container, id), s, dx, dy,\n        sublisteners = listeners.copy();\n\n    if (!customEvent(new DragEvent(drag, \"beforestart\", s, id, active, p[0], p[1], 0, 0, sublisteners), function() {\n      if ((exports.event.subject = s = subject.apply(that, args)) == null) return false;\n      dx = s.x - p[0] || 0;\n      dy = s.y - p[1] || 0;\n      return true;\n    })) return;\n\n    return function gesture(type) {\n      var p0 = p, n;\n      switch (type) {\n        case \"start\": gestures[id] = gesture, n = active++; break;\n        case \"end\": delete gestures[id], --active; // nobreak\n        case \"drag\": p = point(container, id), n = active; break;\n      }\n      customEvent(new DragEvent(drag, type, s, id, n, p[0] + dx, p[1] + dy, p[0] - p0[0], p[1] - p0[1], sublisteners), sublisteners.apply, sublisteners, [type, that, args]);\n    };\n  }\n\n  drag.filter = function(_) {\n    return arguments.length ? (filter = typeof _ === \"function\" ? _ : constant$2(!!_), drag) : filter;\n  };\n\n  drag.container = function(_) {\n    return arguments.length ? (container = typeof _ === \"function\" ? _ : constant$2(_), drag) : container;\n  };\n\n  drag.subject = function(_) {\n    return arguments.length ? (subject = typeof _ === \"function\" ? _ : constant$2(_), drag) : subject;\n  };\n\n  drag.on = function() {\n    var value = listeners.on.apply(listeners, arguments);\n    return value === listeners ? drag : value;\n  };\n\n  drag.clickDistance = function(_) {\n    return arguments.length ? (clickDistance2 = (_ = +_) * _, drag) : Math.sqrt(clickDistance2);\n  };\n\n  return drag;\n};\n\nvar define = function(constructor, factory, prototype) {\n  constructor.prototype = factory.prototype = prototype;\n  prototype.constructor = constructor;\n};\n\nfunction extend(parent, definition) {\n  var prototype = Object.create(parent.prototype);\n  for (var key in definition) prototype[key] = definition[key];\n  return prototype;\n}\n\nfunction Color() {}\n\nvar darker = 0.7;\nvar brighter = 1 / darker;\n\nvar reI = \"\\\\s*([+-]?\\\\d+)\\\\s*\";\nvar reN = \"\\\\s*([+-]?\\\\d*\\\\.?\\\\d+(?:[eE][+-]?\\\\d+)?)\\\\s*\";\nvar reP = \"\\\\s*([+-]?\\\\d*\\\\.?\\\\d+(?:[eE][+-]?\\\\d+)?)%\\\\s*\";\nvar reHex3 = /^#([0-9a-f]{3})$/;\nvar reHex6 = /^#([0-9a-f]{6})$/;\nvar reRgbInteger = new RegExp(\"^rgb\\\\(\" + [reI, reI, reI] + \"\\\\)$\");\nvar reRgbPercent = new RegExp(\"^rgb\\\\(\" + [reP, reP, reP] + \"\\\\)$\");\nvar reRgbaInteger = new RegExp(\"^rgba\\\\(\" + [reI, reI, reI, reN] + \"\\\\)$\");\nvar reRgbaPercent = new RegExp(\"^rgba\\\\(\" + [reP, reP, reP, reN] + \"\\\\)$\");\nvar reHslPercent = new RegExp(\"^hsl\\\\(\" + [reN, reP, reP] + \"\\\\)$\");\nvar reHslaPercent = new RegExp(\"^hsla\\\\(\" + [reN, reP, reP, reN] + \"\\\\)$\");\n\nvar named = {\n  aliceblue: 0xf0f8ff,\n  antiquewhite: 0xfaebd7,\n  aqua: 0x00ffff,\n  aquamarine: 0x7fffd4,\n  azure: 0xf0ffff,\n  beige: 0xf5f5dc,\n  bisque: 0xffe4c4,\n  black: 0x000000,\n  blanchedalmond: 0xffebcd,\n  blue: 0x0000ff,\n  blueviolet: 0x8a2be2,\n  brown: 0xa52a2a,\n  burlywood: 0xdeb887,\n  cadetblue: 0x5f9ea0,\n  chartreuse: 0x7fff00,\n  chocolate: 0xd2691e,\n  coral: 0xff7f50,\n  cornflowerblue: 0x6495ed,\n  cornsilk: 0xfff8dc,\n  crimson: 0xdc143c,\n  cyan: 0x00ffff,\n  darkblue: 0x00008b,\n  darkcyan: 0x008b8b,\n  darkgoldenrod: 0xb8860b,\n  darkgray: 0xa9a9a9,\n  darkgreen: 0x006400,\n  darkgrey: 0xa9a9a9,\n  darkkhaki: 0xbdb76b,\n  darkmagenta: 0x8b008b,\n  darkolivegreen: 0x556b2f,\n  darkorange: 0xff8c00,\n  darkorchid: 0x9932cc,\n  darkred: 0x8b0000,\n  darksalmon: 0xe9967a,\n  darkseagreen: 0x8fbc8f,\n  darkslateblue: 0x483d8b,\n  darkslategray: 0x2f4f4f,\n  darkslategrey: 0x2f4f4f,\n  darkturquoise: 0x00ced1,\n  darkviolet: 0x9400d3,\n  deeppink: 0xff1493,\n  deepskyblue: 0x00bfff,\n  dimgray: 0x696969,\n  dimgrey: 0x696969,\n  dodgerblue: 0x1e90ff,\n  firebrick: 0xb22222,\n  floralwhite: 0xfffaf0,\n  forestgreen: 0x228b22,\n  fuchsia: 0xff00ff,\n  gainsboro: 0xdcdcdc,\n  ghostwhite: 0xf8f8ff,\n  gold: 0xffd700,\n  goldenrod: 0xdaa520,\n  gray: 0x808080,\n  green: 0x008000,\n  greenyellow: 0xadff2f,\n  grey: 0x808080,\n  honeydew: 0xf0fff0,\n  hotpink: 0xff69b4,\n  indianred: 0xcd5c5c,\n  indigo: 0x4b0082,\n  ivory: 0xfffff0,\n  khaki: 0xf0e68c,\n  lavender: 0xe6e6fa,\n  lavenderblush: 0xfff0f5,\n  lawngreen: 0x7cfc00,\n  lemonchiffon: 0xfffacd,\n  lightblue: 0xadd8e6,\n  lightcoral: 0xf08080,\n  lightcyan: 0xe0ffff,\n  lightgoldenrodyellow: 0xfafad2,\n  lightgray: 0xd3d3d3,\n  lightgreen: 0x90ee90,\n  lightgrey: 0xd3d3d3,\n  lightpink: 0xffb6c1,\n  lightsalmon: 0xffa07a,\n  lightseagreen: 0x20b2aa,\n  lightskyblue: 0x87cefa,\n  lightslategray: 0x778899,\n  lightslategrey: 0x778899,\n  lightsteelblue: 0xb0c4de,\n  lightyellow: 0xffffe0,\n  lime: 0x00ff00,\n  limegreen: 0x32cd32,\n  linen: 0xfaf0e6,\n  magenta: 0xff00ff,\n  maroon: 0x800000,\n  mediumaquamarine: 0x66cdaa,\n  mediumblue: 0x0000cd,\n  mediumorchid: 0xba55d3,\n  mediumpurple: 0x9370db,\n  mediumseagreen: 0x3cb371,\n  mediumslateblue: 0x7b68ee,\n  mediumspringgreen: 0x00fa9a,\n  mediumturquoise: 0x48d1cc,\n  mediumvioletred: 0xc71585,\n  midnightblue: 0x191970,\n  mintcream: 0xf5fffa,\n  mistyrose: 0xffe4e1,\n  moccasin: 0xffe4b5,\n  navajowhite: 0xffdead,\n  navy: 0x000080,\n  oldlace: 0xfdf5e6,\n  olive: 0x808000,\n  olivedrab: 0x6b8e23,\n  orange: 0xffa500,\n  orangered: 0xff4500,\n  orchid: 0xda70d6,\n  palegoldenrod: 0xeee8aa,\n  palegreen: 0x98fb98,\n  paleturquoise: 0xafeeee,\n  palevioletred: 0xdb7093,\n  papayawhip: 0xffefd5,\n  peachpuff: 0xffdab9,\n  peru: 0xcd853f,\n  pink: 0xffc0cb,\n  plum: 0xdda0dd,\n  powderblue: 0xb0e0e6,\n  purple: 0x800080,\n  rebeccapurple: 0x663399,\n  red: 0xff0000,\n  rosybrown: 0xbc8f8f,\n  royalblue: 0x4169e1,\n  saddlebrown: 0x8b4513,\n  salmon: 0xfa8072,\n  sandybrown: 0xf4a460,\n  seagreen: 0x2e8b57,\n  seashell: 0xfff5ee,\n  sienna: 0xa0522d,\n  silver: 0xc0c0c0,\n  skyblue: 0x87ceeb,\n  slateblue: 0x6a5acd,\n  slategray: 0x708090,\n  slategrey: 0x708090,\n  snow: 0xfffafa,\n  springgreen: 0x00ff7f,\n  steelblue: 0x4682b4,\n  tan: 0xd2b48c,\n  teal: 0x008080,\n  thistle: 0xd8bfd8,\n  tomato: 0xff6347,\n  turquoise: 0x40e0d0,\n  violet: 0xee82ee,\n  wheat: 0xf5deb3,\n  white: 0xffffff,\n  whitesmoke: 0xf5f5f5,\n  yellow: 0xffff00,\n  yellowgreen: 0x9acd32\n};\n\ndefine(Color, color, {\n  displayable: function() {\n    return this.rgb().displayable();\n  },\n  toString: function() {\n    return this.rgb() + \"\";\n  }\n});\n\nfunction color(format) {\n  var m;\n  format = (format + \"\").trim().toLowerCase();\n  return (m = reHex3.exec(format)) ? (m = parseInt(m[1], 16), new Rgb((m >> 8 & 0xf) | (m >> 4 & 0x0f0), (m >> 4 & 0xf) | (m & 0xf0), ((m & 0xf) << 4) | (m & 0xf), 1)) // #f00\n      : (m = reHex6.exec(format)) ? rgbn(parseInt(m[1], 16)) // #ff0000\n      : (m = reRgbInteger.exec(format)) ? new Rgb(m[1], m[2], m[3], 1) // rgb(255, 0, 0)\n      : (m = reRgbPercent.exec(format)) ? new Rgb(m[1] * 255 / 100, m[2] * 255 / 100, m[3] * 255 / 100, 1) // rgb(100%, 0%, 0%)\n      : (m = reRgbaInteger.exec(format)) ? rgba(m[1], m[2], m[3], m[4]) // rgba(255, 0, 0, 1)\n      : (m = reRgbaPercent.exec(format)) ? rgba(m[1] * 255 / 100, m[2] * 255 / 100, m[3] * 255 / 100, m[4]) // rgb(100%, 0%, 0%, 1)\n      : (m = reHslPercent.exec(format)) ? hsla(m[1], m[2] / 100, m[3] / 100, 1) // hsl(120, 50%, 50%)\n      : (m = reHslaPercent.exec(format)) ? hsla(m[1], m[2] / 100, m[3] / 100, m[4]) // hsla(120, 50%, 50%, 1)\n      : named.hasOwnProperty(format) ? rgbn(named[format])\n      : format === \"transparent\" ? new Rgb(NaN, NaN, NaN, 0)\n      : null;\n}\n\nfunction rgbn(n) {\n  return new Rgb(n >> 16 & 0xff, n >> 8 & 0xff, n & 0xff, 1);\n}\n\nfunction rgba(r, g, b, a) {\n  if (a <= 0) r = g = b = NaN;\n  return new Rgb(r, g, b, a);\n}\n\nfunction rgbConvert(o) {\n  if (!(o instanceof Color)) o = color(o);\n  if (!o) return new Rgb;\n  o = o.rgb();\n  return new Rgb(o.r, o.g, o.b, o.opacity);\n}\n\nfunction rgb(r, g, b, opacity) {\n  return arguments.length === 1 ? rgbConvert(r) : new Rgb(r, g, b, opacity == null ? 1 : opacity);\n}\n\nfunction Rgb(r, g, b, opacity) {\n  this.r = +r;\n  this.g = +g;\n  this.b = +b;\n  this.opacity = +opacity;\n}\n\ndefine(Rgb, rgb, extend(Color, {\n  brighter: function(k) {\n    k = k == null ? brighter : Math.pow(brighter, k);\n    return new Rgb(this.r * k, this.g * k, this.b * k, this.opacity);\n  },\n  darker: function(k) {\n    k = k == null ? darker : Math.pow(darker, k);\n    return new Rgb(this.r * k, this.g * k, this.b * k, this.opacity);\n  },\n  rgb: function() {\n    return this;\n  },\n  displayable: function() {\n    return (0 <= this.r && this.r <= 255)\n        && (0 <= this.g && this.g <= 255)\n        && (0 <= this.b && this.b <= 255)\n        && (0 <= this.opacity && this.opacity <= 1);\n  },\n  toString: function() {\n    var a = this.opacity; a = isNaN(a) ? 1 : Math.max(0, Math.min(1, a));\n    return (a === 1 ? \"rgb(\" : \"rgba(\")\n        + Math.max(0, Math.min(255, Math.round(this.r) || 0)) + \", \"\n        + Math.max(0, Math.min(255, Math.round(this.g) || 0)) + \", \"\n        + Math.max(0, Math.min(255, Math.round(this.b) || 0))\n        + (a === 1 ? \")\" : \", \" + a + \")\");\n  }\n}));\n\nfunction hsla(h, s, l, a) {\n  if (a <= 0) h = s = l = NaN;\n  else if (l <= 0 || l >= 1) h = s = NaN;\n  else if (s <= 0) h = NaN;\n  return new Hsl(h, s, l, a);\n}\n\nfunction hslConvert(o) {\n  if (o instanceof Hsl) return new Hsl(o.h, o.s, o.l, o.opacity);\n  if (!(o instanceof Color)) o = color(o);\n  if (!o) return new Hsl;\n  if (o instanceof Hsl) return o;\n  o = o.rgb();\n  var r = o.r / 255,\n      g = o.g / 255,\n      b = o.b / 255,\n      min = Math.min(r, g, b),\n      max = Math.max(r, g, b),\n      h = NaN,\n      s = max - min,\n      l = (max + min) / 2;\n  if (s) {\n    if (r === max) h = (g - b) / s + (g < b) * 6;\n    else if (g === max) h = (b - r) / s + 2;\n    else h = (r - g) / s + 4;\n    s /= l < 0.5 ? max + min : 2 - max - min;\n    h *= 60;\n  } else {\n    s = l > 0 && l < 1 ? 0 : h;\n  }\n  return new Hsl(h, s, l, o.opacity);\n}\n\nfunction hsl(h, s, l, opacity) {\n  return arguments.length === 1 ? hslConvert(h) : new Hsl(h, s, l, opacity == null ? 1 : opacity);\n}\n\nfunction Hsl(h, s, l, opacity) {\n  this.h = +h;\n  this.s = +s;\n  this.l = +l;\n  this.opacity = +opacity;\n}\n\ndefine(Hsl, hsl, extend(Color, {\n  brighter: function(k) {\n    k = k == null ? brighter : Math.pow(brighter, k);\n    return new Hsl(this.h, this.s, this.l * k, this.opacity);\n  },\n  darker: function(k) {\n    k = k == null ? darker : Math.pow(darker, k);\n    return new Hsl(this.h, this.s, this.l * k, this.opacity);\n  },\n  rgb: function() {\n    var h = this.h % 360 + (this.h < 0) * 360,\n        s = isNaN(h) || isNaN(this.s) ? 0 : this.s,\n        l = this.l,\n        m2 = l + (l < 0.5 ? l : 1 - l) * s,\n        m1 = 2 * l - m2;\n    return new Rgb(\n      hsl2rgb(h >= 240 ? h - 240 : h + 120, m1, m2),\n      hsl2rgb(h, m1, m2),\n      hsl2rgb(h < 120 ? h + 240 : h - 120, m1, m2),\n      this.opacity\n    );\n  },\n  displayable: function() {\n    return (0 <= this.s && this.s <= 1 || isNaN(this.s))\n        && (0 <= this.l && this.l <= 1)\n        && (0 <= this.opacity && this.opacity <= 1);\n  }\n}));\n\n/* From FvD 13.37, CSS Color Module Level 3 */\nfunction hsl2rgb(h, m1, m2) {\n  return (h < 60 ? m1 + (m2 - m1) * h / 60\n      : h < 180 ? m2\n      : h < 240 ? m1 + (m2 - m1) * (240 - h) / 60\n      : m1) * 255;\n}\n\nvar deg2rad = Math.PI / 180;\nvar rad2deg = 180 / Math.PI;\n\nvar Kn = 18;\nvar Xn = 0.950470;\nvar Yn = 1;\nvar Zn = 1.088830;\nvar t0 = 4 / 29;\nvar t1 = 6 / 29;\nvar t2 = 3 * t1 * t1;\nvar t3 = t1 * t1 * t1;\n\nfunction labConvert(o) {\n  if (o instanceof Lab) return new Lab(o.l, o.a, o.b, o.opacity);\n  if (o instanceof Hcl) {\n    var h = o.h * deg2rad;\n    return new Lab(o.l, Math.cos(h) * o.c, Math.sin(h) * o.c, o.opacity);\n  }\n  if (!(o instanceof Rgb)) o = rgbConvert(o);\n  var b = rgb2xyz(o.r),\n      a = rgb2xyz(o.g),\n      l = rgb2xyz(o.b),\n      x = xyz2lab((0.4124564 * b + 0.3575761 * a + 0.1804375 * l) / Xn),\n      y = xyz2lab((0.2126729 * b + 0.7151522 * a + 0.0721750 * l) / Yn),\n      z = xyz2lab((0.0193339 * b + 0.1191920 * a + 0.9503041 * l) / Zn);\n  return new Lab(116 * y - 16, 500 * (x - y), 200 * (y - z), o.opacity);\n}\n\nfunction lab(l, a, b, opacity) {\n  return arguments.length === 1 ? labConvert(l) : new Lab(l, a, b, opacity == null ? 1 : opacity);\n}\n\nfunction Lab(l, a, b, opacity) {\n  this.l = +l;\n  this.a = +a;\n  this.b = +b;\n  this.opacity = +opacity;\n}\n\ndefine(Lab, lab, extend(Color, {\n  brighter: function(k) {\n    return new Lab(this.l + Kn * (k == null ? 1 : k), this.a, this.b, this.opacity);\n  },\n  darker: function(k) {\n    return new Lab(this.l - Kn * (k == null ? 1 : k), this.a, this.b, this.opacity);\n  },\n  rgb: function() {\n    var y = (this.l + 16) / 116,\n        x = isNaN(this.a) ? y : y + this.a / 500,\n        z = isNaN(this.b) ? y : y - this.b / 200;\n    y = Yn * lab2xyz(y);\n    x = Xn * lab2xyz(x);\n    z = Zn * lab2xyz(z);\n    return new Rgb(\n      xyz2rgb( 3.2404542 * x - 1.5371385 * y - 0.4985314 * z), // D65 -> sRGB\n      xyz2rgb(-0.9692660 * x + 1.8760108 * y + 0.0415560 * z),\n      xyz2rgb( 0.0556434 * x - 0.2040259 * y + 1.0572252 * z),\n      this.opacity\n    );\n  }\n}));\n\nfunction xyz2lab(t) {\n  return t > t3 ? Math.pow(t, 1 / 3) : t / t2 + t0;\n}\n\nfunction lab2xyz(t) {\n  return t > t1 ? t * t * t : t2 * (t - t0);\n}\n\nfunction xyz2rgb(x) {\n  return 255 * (x <= 0.0031308 ? 12.92 * x : 1.055 * Math.pow(x, 1 / 2.4) - 0.055);\n}\n\nfunction rgb2xyz(x) {\n  return (x /= 255) <= 0.04045 ? x / 12.92 : Math.pow((x + 0.055) / 1.055, 2.4);\n}\n\nfunction hclConvert(o) {\n  if (o instanceof Hcl) return new Hcl(o.h, o.c, o.l, o.opacity);\n  if (!(o instanceof Lab)) o = labConvert(o);\n  var h = Math.atan2(o.b, o.a) * rad2deg;\n  return new Hcl(h < 0 ? h + 360 : h, Math.sqrt(o.a * o.a + o.b * o.b), o.l, o.opacity);\n}\n\nfunction hcl(h, c, l, opacity) {\n  return arguments.length === 1 ? hclConvert(h) : new Hcl(h, c, l, opacity == null ? 1 : opacity);\n}\n\nfunction Hcl(h, c, l, opacity) {\n  this.h = +h;\n  this.c = +c;\n  this.l = +l;\n  this.opacity = +opacity;\n}\n\ndefine(Hcl, hcl, extend(Color, {\n  brighter: function(k) {\n    return new Hcl(this.h, this.c, this.l + Kn * (k == null ? 1 : k), this.opacity);\n  },\n  darker: function(k) {\n    return new Hcl(this.h, this.c, this.l - Kn * (k == null ? 1 : k), this.opacity);\n  },\n  rgb: function() {\n    return labConvert(this).rgb();\n  }\n}));\n\nvar A = -0.14861;\nvar B = +1.78277;\nvar C = -0.29227;\nvar D = -0.90649;\nvar E = +1.97294;\nvar ED = E * D;\nvar EB = E * B;\nvar BC_DA = B * C - D * A;\n\nfunction cubehelixConvert(o) {\n  if (o instanceof Cubehelix) return new Cubehelix(o.h, o.s, o.l, o.opacity);\n  if (!(o instanceof Rgb)) o = rgbConvert(o);\n  var r = o.r / 255,\n      g = o.g / 255,\n      b = o.b / 255,\n      l = (BC_DA * b + ED * r - EB * g) / (BC_DA + ED - EB),\n      bl = b - l,\n      k = (E * (g - l) - C * bl) / D,\n      s = Math.sqrt(k * k + bl * bl) / (E * l * (1 - l)), // NaN if l=0 or l=1\n      h = s ? Math.atan2(k, bl) * rad2deg - 120 : NaN;\n  return new Cubehelix(h < 0 ? h + 360 : h, s, l, o.opacity);\n}\n\nfunction cubehelix(h, s, l, opacity) {\n  return arguments.length === 1 ? cubehelixConvert(h) : new Cubehelix(h, s, l, opacity == null ? 1 : opacity);\n}\n\nfunction Cubehelix(h, s, l, opacity) {\n  this.h = +h;\n  this.s = +s;\n  this.l = +l;\n  this.opacity = +opacity;\n}\n\ndefine(Cubehelix, cubehelix, extend(Color, {\n  brighter: function(k) {\n    k = k == null ? brighter : Math.pow(brighter, k);\n    return new Cubehelix(this.h, this.s, this.l * k, this.opacity);\n  },\n  darker: function(k) {\n    k = k == null ? darker : Math.pow(darker, k);\n    return new Cubehelix(this.h, this.s, this.l * k, this.opacity);\n  },\n  rgb: function() {\n    var h = isNaN(this.h) ? 0 : (this.h + 120) * deg2rad,\n        l = +this.l,\n        a = isNaN(this.s) ? 0 : this.s * l * (1 - l),\n        cosh = Math.cos(h),\n        sinh = Math.sin(h);\n    return new Rgb(\n      255 * (l + a * (A * cosh + B * sinh)),\n      255 * (l + a * (C * cosh + D * sinh)),\n      255 * (l + a * (E * cosh)),\n      this.opacity\n    );\n  }\n}));\n\nfunction basis(t1, v0, v1, v2, v3) {\n  var t2 = t1 * t1, t3 = t2 * t1;\n  return ((1 - 3 * t1 + 3 * t2 - t3) * v0\n      + (4 - 6 * t2 + 3 * t3) * v1\n      + (1 + 3 * t1 + 3 * t2 - 3 * t3) * v2\n      + t3 * v3) / 6;\n}\n\nvar basis$1 = function(values) {\n  var n = values.length - 1;\n  return function(t) {\n    var i = t <= 0 ? (t = 0) : t >= 1 ? (t = 1, n - 1) : Math.floor(t * n),\n        v1 = values[i],\n        v2 = values[i + 1],\n        v0 = i > 0 ? values[i - 1] : 2 * v1 - v2,\n        v3 = i < n - 1 ? values[i + 2] : 2 * v2 - v1;\n    return basis((t - i / n) * n, v0, v1, v2, v3);\n  };\n};\n\nvar basisClosed = function(values) {\n  var n = values.length;\n  return function(t) {\n    var i = Math.floor(((t %= 1) < 0 ? ++t : t) * n),\n        v0 = values[(i + n - 1) % n],\n        v1 = values[i % n],\n        v2 = values[(i + 1) % n],\n        v3 = values[(i + 2) % n];\n    return basis((t - i / n) * n, v0, v1, v2, v3);\n  };\n};\n\nvar constant$3 = function(x) {\n  return function() {\n    return x;\n  };\n};\n\nfunction linear(a, d) {\n  return function(t) {\n    return a + t * d;\n  };\n}\n\nfunction exponential(a, b, y) {\n  return a = Math.pow(a, y), b = Math.pow(b, y) - a, y = 1 / y, function(t) {\n    return Math.pow(a + t * b, y);\n  };\n}\n\nfunction hue(a, b) {\n  var d = b - a;\n  return d ? linear(a, d > 180 || d < -180 ? d - 360 * Math.round(d / 360) : d) : constant$3(isNaN(a) ? b : a);\n}\n\nfunction gamma(y) {\n  return (y = +y) === 1 ? nogamma : function(a, b) {\n    return b - a ? exponential(a, b, y) : constant$3(isNaN(a) ? b : a);\n  };\n}\n\nfunction nogamma(a, b) {\n  var d = b - a;\n  return d ? linear(a, d) : constant$3(isNaN(a) ? b : a);\n}\n\nvar interpolateRgb = ((function rgbGamma(y) {\n  var color$$1 = gamma(y);\n\n  function rgb$$1(start, end) {\n    var r = color$$1((start = rgb(start)).r, (end = rgb(end)).r),\n        g = color$$1(start.g, end.g),\n        b = color$$1(start.b, end.b),\n        opacity = nogamma(start.opacity, end.opacity);\n    return function(t) {\n      start.r = r(t);\n      start.g = g(t);\n      start.b = b(t);\n      start.opacity = opacity(t);\n      return start + \"\";\n    };\n  }\n\n  rgb$$1.gamma = rgbGamma;\n\n  return rgb$$1;\n}))(1);\n\nfunction rgbSpline(spline) {\n  return function(colors) {\n    var n = colors.length,\n        r = new Array(n),\n        g = new Array(n),\n        b = new Array(n),\n        i, color$$1;\n    for (i = 0; i < n; ++i) {\n      color$$1 = rgb(colors[i]);\n      r[i] = color$$1.r || 0;\n      g[i] = color$$1.g || 0;\n      b[i] = color$$1.b || 0;\n    }\n    r = spline(r);\n    g = spline(g);\n    b = spline(b);\n    color$$1.opacity = 1;\n    return function(t) {\n      color$$1.r = r(t);\n      color$$1.g = g(t);\n      color$$1.b = b(t);\n      return color$$1 + \"\";\n    };\n  };\n}\n\nvar rgbBasis = rgbSpline(basis$1);\nvar rgbBasisClosed = rgbSpline(basisClosed);\n\nvar array$1 = function(a, b) {\n  var nb = b ? b.length : 0,\n      na = a ? Math.min(nb, a.length) : 0,\n      x = new Array(nb),\n      c = new Array(nb),\n      i;\n\n  for (i = 0; i < na; ++i) x[i] = interpolateValue(a[i], b[i]);\n  for (; i < nb; ++i) c[i] = b[i];\n\n  return function(t) {\n    for (i = 0; i < na; ++i) c[i] = x[i](t);\n    return c;\n  };\n};\n\nvar date = function(a, b) {\n  var d = new Date;\n  return a = +a, b -= a, function(t) {\n    return d.setTime(a + b * t), d;\n  };\n};\n\nvar reinterpolate = function(a, b) {\n  return a = +a, b -= a, function(t) {\n    return a + b * t;\n  };\n};\n\nvar object = function(a, b) {\n  var i = {},\n      c = {},\n      k;\n\n  if (a === null || typeof a !== \"object\") a = {};\n  if (b === null || typeof b !== \"object\") b = {};\n\n  for (k in b) {\n    if (k in a) {\n      i[k] = interpolateValue(a[k], b[k]);\n    } else {\n      c[k] = b[k];\n    }\n  }\n\n  return function(t) {\n    for (k in i) c[k] = i[k](t);\n    return c;\n  };\n};\n\nvar reA = /[-+]?(?:\\d+\\.?\\d*|\\.?\\d+)(?:[eE][-+]?\\d+)?/g;\nvar reB = new RegExp(reA.source, \"g\");\n\nfunction zero(b) {\n  return function() {\n    return b;\n  };\n}\n\nfunction one(b) {\n  return function(t) {\n    return b(t) + \"\";\n  };\n}\n\nvar interpolateString = function(a, b) {\n  var bi = reA.lastIndex = reB.lastIndex = 0, // scan index for next number in b\n      am, // current match in a\n      bm, // current match in b\n      bs, // string preceding current number in b, if any\n      i = -1, // index in s\n      s = [], // string constants and placeholders\n      q = []; // number interpolators\n\n  // Coerce inputs to strings.\n  a = a + \"\", b = b + \"\";\n\n  // Interpolate pairs of numbers in a & b.\n  while ((am = reA.exec(a))\n      && (bm = reB.exec(b))) {\n    if ((bs = bm.index) > bi) { // a string precedes the next number in b\n      bs = b.slice(bi, bs);\n      if (s[i]) s[i] += bs; // coalesce with previous string\n      else s[++i] = bs;\n    }\n    if ((am = am[0]) === (bm = bm[0])) { // numbers in a & b match\n      if (s[i]) s[i] += bm; // coalesce with previous string\n      else s[++i] = bm;\n    } else { // interpolate non-matching numbers\n      s[++i] = null;\n      q.push({i: i, x: reinterpolate(am, bm)});\n    }\n    bi = reB.lastIndex;\n  }\n\n  // Add remains of b.\n  if (bi < b.length) {\n    bs = b.slice(bi);\n    if (s[i]) s[i] += bs; // coalesce with previous string\n    else s[++i] = bs;\n  }\n\n  // Special optimization for only a single match.\n  // Otherwise, interpolate each of the numbers and rejoin the string.\n  return s.length < 2 ? (q[0]\n      ? one(q[0].x)\n      : zero(b))\n      : (b = q.length, function(t) {\n          for (var i = 0, o; i < b; ++i) s[(o = q[i]).i] = o.x(t);\n          return s.join(\"\");\n        });\n};\n\nvar interpolateValue = function(a, b) {\n  var t = typeof b, c;\n  return b == null || t === \"boolean\" ? constant$3(b)\n      : (t === \"number\" ? reinterpolate\n      : t === \"string\" ? ((c = color(b)) ? (b = c, interpolateRgb) : interpolateString)\n      : b instanceof color ? interpolateRgb\n      : b instanceof Date ? date\n      : Array.isArray(b) ? array$1\n      : typeof b.valueOf !== \"function\" && typeof b.toString !== \"function\" || isNaN(b) ? object\n      : reinterpolate)(a, b);\n};\n\nvar interpolateRound = function(a, b) {\n  return a = +a, b -= a, function(t) {\n    return Math.round(a + b * t);\n  };\n};\n\nvar degrees = 180 / Math.PI;\n\nvar identity$2 = {\n  translateX: 0,\n  translateY: 0,\n  rotate: 0,\n  skewX: 0,\n  scaleX: 1,\n  scaleY: 1\n};\n\nvar decompose = function(a, b, c, d, e, f) {\n  var scaleX, scaleY, skewX;\n  if (scaleX = Math.sqrt(a * a + b * b)) a /= scaleX, b /= scaleX;\n  if (skewX = a * c + b * d) c -= a * skewX, d -= b * skewX;\n  if (scaleY = Math.sqrt(c * c + d * d)) c /= scaleY, d /= scaleY, skewX /= scaleY;\n  if (a * d < b * c) a = -a, b = -b, skewX = -skewX, scaleX = -scaleX;\n  return {\n    translateX: e,\n    translateY: f,\n    rotate: Math.atan2(b, a) * degrees,\n    skewX: Math.atan(skewX) * degrees,\n    scaleX: scaleX,\n    scaleY: scaleY\n  };\n};\n\nvar cssNode;\nvar cssRoot;\nvar cssView;\nvar svgNode;\n\nfunction parseCss(value) {\n  if (value === \"none\") return identity$2;\n  if (!cssNode) cssNode = document.createElement(\"DIV\"), cssRoot = document.documentElement, cssView = document.defaultView;\n  cssNode.style.transform = value;\n  value = cssView.getComputedStyle(cssRoot.appendChild(cssNode), null).getPropertyValue(\"transform\");\n  cssRoot.removeChild(cssNode);\n  value = value.slice(7, -1).split(\",\");\n  return decompose(+value[0], +value[1], +value[2], +value[3], +value[4], +value[5]);\n}\n\nfunction parseSvg(value) {\n  if (value == null) return identity$2;\n  if (!svgNode) svgNode = document.createElementNS(\"http://www.w3.org/2000/svg\", \"g\");\n  svgNode.setAttribute(\"transform\", value);\n  if (!(value = svgNode.transform.baseVal.consolidate())) return identity$2;\n  value = value.matrix;\n  return decompose(value.a, value.b, value.c, value.d, value.e, value.f);\n}\n\nfunction interpolateTransform(parse, pxComma, pxParen, degParen) {\n\n  function pop(s) {\n    return s.length ? s.pop() + \" \" : \"\";\n  }\n\n  function translate(xa, ya, xb, yb, s, q) {\n    if (xa !== xb || ya !== yb) {\n      var i = s.push(\"translate(\", null, pxComma, null, pxParen);\n      q.push({i: i - 4, x: reinterpolate(xa, xb)}, {i: i - 2, x: reinterpolate(ya, yb)});\n    } else if (xb || yb) {\n      s.push(\"translate(\" + xb + pxComma + yb + pxParen);\n    }\n  }\n\n  function rotate(a, b, s, q) {\n    if (a !== b) {\n      if (a - b > 180) b += 360; else if (b - a > 180) a += 360; // shortest path\n      q.push({i: s.push(pop(s) + \"rotate(\", null, degParen) - 2, x: reinterpolate(a, b)});\n    } else if (b) {\n      s.push(pop(s) + \"rotate(\" + b + degParen);\n    }\n  }\n\n  function skewX(a, b, s, q) {\n    if (a !== b) {\n      q.push({i: s.push(pop(s) + \"skewX(\", null, degParen) - 2, x: reinterpolate(a, b)});\n    } else if (b) {\n      s.push(pop(s) + \"skewX(\" + b + degParen);\n    }\n  }\n\n  function scale(xa, ya, xb, yb, s, q) {\n    if (xa !== xb || ya !== yb) {\n      var i = s.push(pop(s) + \"scale(\", null, \",\", null, \")\");\n      q.push({i: i - 4, x: reinterpolate(xa, xb)}, {i: i - 2, x: reinterpolate(ya, yb)});\n    } else if (xb !== 1 || yb !== 1) {\n      s.push(pop(s) + \"scale(\" + xb + \",\" + yb + \")\");\n    }\n  }\n\n  return function(a, b) {\n    var s = [], // string constants and placeholders\n        q = []; // number interpolators\n    a = parse(a), b = parse(b);\n    translate(a.translateX, a.translateY, b.translateX, b.translateY, s, q);\n    rotate(a.rotate, b.rotate, s, q);\n    skewX(a.skewX, b.skewX, s, q);\n    scale(a.scaleX, a.scaleY, b.scaleX, b.scaleY, s, q);\n    a = b = null; // gc\n    return function(t) {\n      var i = -1, n = q.length, o;\n      while (++i < n) s[(o = q[i]).i] = o.x(t);\n      return s.join(\"\");\n    };\n  };\n}\n\nvar interpolateTransformCss = interpolateTransform(parseCss, \"px, \", \"px)\", \"deg)\");\nvar interpolateTransformSvg = interpolateTransform(parseSvg, \", \", \")\", \")\");\n\nvar rho = Math.SQRT2;\nvar rho2 = 2;\nvar rho4 = 4;\nvar epsilon2 = 1e-12;\n\nfunction cosh(x) {\n  return ((x = Math.exp(x)) + 1 / x) / 2;\n}\n\nfunction sinh(x) {\n  return ((x = Math.exp(x)) - 1 / x) / 2;\n}\n\nfunction tanh(x) {\n  return ((x = Math.exp(2 * x)) - 1) / (x + 1);\n}\n\n// p0 = [ux0, uy0, w0]\n// p1 = [ux1, uy1, w1]\nvar interpolateZoom = function(p0, p1) {\n  var ux0 = p0[0], uy0 = p0[1], w0 = p0[2],\n      ux1 = p1[0], uy1 = p1[1], w1 = p1[2],\n      dx = ux1 - ux0,\n      dy = uy1 - uy0,\n      d2 = dx * dx + dy * dy,\n      i,\n      S;\n\n  // Special case for u0 ≅ u1.\n  if (d2 < epsilon2) {\n    S = Math.log(w1 / w0) / rho;\n    i = function(t) {\n      return [\n        ux0 + t * dx,\n        uy0 + t * dy,\n        w0 * Math.exp(rho * t * S)\n      ];\n    };\n  }\n\n  // General case.\n  else {\n    var d1 = Math.sqrt(d2),\n        b0 = (w1 * w1 - w0 * w0 + rho4 * d2) / (2 * w0 * rho2 * d1),\n        b1 = (w1 * w1 - w0 * w0 - rho4 * d2) / (2 * w1 * rho2 * d1),\n        r0 = Math.log(Math.sqrt(b0 * b0 + 1) - b0),\n        r1 = Math.log(Math.sqrt(b1 * b1 + 1) - b1);\n    S = (r1 - r0) / rho;\n    i = function(t) {\n      var s = t * S,\n          coshr0 = cosh(r0),\n          u = w0 / (rho2 * d1) * (coshr0 * tanh(rho * s + r0) - sinh(r0));\n      return [\n        ux0 + u * dx,\n        uy0 + u * dy,\n        w0 * coshr0 / cosh(rho * s + r0)\n      ];\n    };\n  }\n\n  i.duration = S * 1000;\n\n  return i;\n};\n\nfunction hsl$1(hue$$1) {\n  return function(start, end) {\n    var h = hue$$1((start = hsl(start)).h, (end = hsl(end)).h),\n        s = nogamma(start.s, end.s),\n        l = nogamma(start.l, end.l),\n        opacity = nogamma(start.opacity, end.opacity);\n    return function(t) {\n      start.h = h(t);\n      start.s = s(t);\n      start.l = l(t);\n      start.opacity = opacity(t);\n      return start + \"\";\n    };\n  }\n}\n\nvar hsl$2 = hsl$1(hue);\nvar hslLong = hsl$1(nogamma);\n\nfunction lab$1(start, end) {\n  var l = nogamma((start = lab(start)).l, (end = lab(end)).l),\n      a = nogamma(start.a, end.a),\n      b = nogamma(start.b, end.b),\n      opacity = nogamma(start.opacity, end.opacity);\n  return function(t) {\n    start.l = l(t);\n    start.a = a(t);\n    start.b = b(t);\n    start.opacity = opacity(t);\n    return start + \"\";\n  };\n}\n\nfunction hcl$1(hue$$1) {\n  return function(start, end) {\n    var h = hue$$1((start = hcl(start)).h, (end = hcl(end)).h),\n        c = nogamma(start.c, end.c),\n        l = nogamma(start.l, end.l),\n        opacity = nogamma(start.opacity, end.opacity);\n    return function(t) {\n      start.h = h(t);\n      start.c = c(t);\n      start.l = l(t);\n      start.opacity = opacity(t);\n      return start + \"\";\n    };\n  }\n}\n\nvar hcl$2 = hcl$1(hue);\nvar hclLong = hcl$1(nogamma);\n\nfunction cubehelix$1(hue$$1) {\n  return (function cubehelixGamma(y) {\n    y = +y;\n\n    function cubehelix$$1(start, end) {\n      var h = hue$$1((start = cubehelix(start)).h, (end = cubehelix(end)).h),\n          s = nogamma(start.s, end.s),\n          l = nogamma(start.l, end.l),\n          opacity = nogamma(start.opacity, end.opacity);\n      return function(t) {\n        start.h = h(t);\n        start.s = s(t);\n        start.l = l(Math.pow(t, y));\n        start.opacity = opacity(t);\n        return start + \"\";\n      };\n    }\n\n    cubehelix$$1.gamma = cubehelixGamma;\n\n    return cubehelix$$1;\n  })(1);\n}\n\nvar cubehelix$2 = cubehelix$1(hue);\nvar cubehelixLong = cubehelix$1(nogamma);\n\nvar quantize = function(interpolator, n) {\n  var samples = new Array(n);\n  for (var i = 0; i < n; ++i) samples[i] = interpolator(i / (n - 1));\n  return samples;\n};\n\nvar frame = 0;\nvar timeout = 0;\nvar interval = 0;\nvar pokeDelay = 1000;\nvar taskHead;\nvar taskTail;\nvar clockLast = 0;\nvar clockNow = 0;\nvar clockSkew = 0;\nvar clock = typeof performance === \"object\" && performance.now ? performance : Date;\nvar setFrame = typeof requestAnimationFrame === \"function\" ? requestAnimationFrame : function(f) { setTimeout(f, 17); };\n\nfunction now() {\n  return clockNow || (setFrame(clearNow), clockNow = clock.now() + clockSkew);\n}\n\nfunction clearNow() {\n  clockNow = 0;\n}\n\nfunction Timer() {\n  this._call =\n  this._time =\n  this._next = null;\n}\n\nTimer.prototype = timer.prototype = {\n  constructor: Timer,\n  restart: function(callback, delay, time) {\n    if (typeof callback !== \"function\") throw new TypeError(\"callback is not a function\");\n    time = (time == null ? now() : +time) + (delay == null ? 0 : +delay);\n    if (!this._next && taskTail !== this) {\n      if (taskTail) taskTail._next = this;\n      else taskHead = this;\n      taskTail = this;\n    }\n    this._call = callback;\n    this._time = time;\n    sleep();\n  },\n  stop: function() {\n    if (this._call) {\n      this._call = null;\n      this._time = Infinity;\n      sleep();\n    }\n  }\n};\n\nfunction timer(callback, delay, time) {\n  var t = new Timer;\n  t.restart(callback, delay, time);\n  return t;\n}\n\nfunction timerFlush() {\n  now(); // Get the current time, if not already set.\n  ++frame; // Pretend we’ve set an alarm, if we haven’t already.\n  var t = taskHead, e;\n  while (t) {\n    if ((e = clockNow - t._time) >= 0) t._call.call(null, e);\n    t = t._next;\n  }\n  --frame;\n}\n\nfunction wake() {\n  clockNow = (clockLast = clock.now()) + clockSkew;\n  frame = timeout = 0;\n  try {\n    timerFlush();\n  } finally {\n    frame = 0;\n    nap();\n    clockNow = 0;\n  }\n}\n\nfunction poke() {\n  var now = clock.now(), delay = now - clockLast;\n  if (delay > pokeDelay) clockSkew -= delay, clockLast = now;\n}\n\nfunction nap() {\n  var t0, t1 = taskHead, t2, time = Infinity;\n  while (t1) {\n    if (t1._call) {\n      if (time > t1._time) time = t1._time;\n      t0 = t1, t1 = t1._next;\n    } else {\n      t2 = t1._next, t1._next = null;\n      t1 = t0 ? t0._next = t2 : taskHead = t2;\n    }\n  }\n  taskTail = t0;\n  sleep(time);\n}\n\nfunction sleep(time) {\n  if (frame) return; // Soonest alarm already set, or will be.\n  if (timeout) timeout = clearTimeout(timeout);\n  var delay = time - clockNow;\n  if (delay > 24) {\n    if (time < Infinity) timeout = setTimeout(wake, delay);\n    if (interval) interval = clearInterval(interval);\n  } else {\n    if (!interval) clockLast = clockNow, interval = setInterval(poke, pokeDelay);\n    frame = 1, setFrame(wake);\n  }\n}\n\nvar timeout$1 = function(callback, delay, time) {\n  var t = new Timer;\n  delay = delay == null ? 0 : +delay;\n  t.restart(function(elapsed) {\n    t.stop();\n    callback(elapsed + delay);\n  }, delay, time);\n  return t;\n};\n\nvar interval$1 = function(callback, delay, time) {\n  var t = new Timer, total = delay;\n  if (delay == null) return t.restart(callback, delay, time), t;\n  delay = +delay, time = time == null ? now() : +time;\n  t.restart(function tick(elapsed) {\n    elapsed += total;\n    t.restart(tick, total += delay, time);\n    callback(elapsed);\n  }, delay, time);\n  return t;\n};\n\nvar emptyOn = dispatch(\"start\", \"end\", \"interrupt\");\nvar emptyTween = [];\n\nvar CREATED = 0;\nvar SCHEDULED = 1;\nvar STARTING = 2;\nvar STARTED = 3;\nvar RUNNING = 4;\nvar ENDING = 5;\nvar ENDED = 6;\n\nvar schedule = function(node, name, id, index, group, timing) {\n  var schedules = node.__transition;\n  if (!schedules) node.__transition = {};\n  else if (id in schedules) return;\n  create(node, id, {\n    name: name,\n    index: index, // For context during callback.\n    group: group, // For context during callback.\n    on: emptyOn,\n    tween: emptyTween,\n    time: timing.time,\n    delay: timing.delay,\n    duration: timing.duration,\n    ease: timing.ease,\n    timer: null,\n    state: CREATED\n  });\n};\n\nfunction init(node, id) {\n  var schedule = node.__transition;\n  if (!schedule || !(schedule = schedule[id]) || schedule.state > CREATED) throw new Error(\"too late\");\n  return schedule;\n}\n\nfunction set$1(node, id) {\n  var schedule = node.__transition;\n  if (!schedule || !(schedule = schedule[id]) || schedule.state > STARTING) throw new Error(\"too late\");\n  return schedule;\n}\n\nfunction get$1(node, id) {\n  var schedule = node.__transition;\n  if (!schedule || !(schedule = schedule[id])) throw new Error(\"too late\");\n  return schedule;\n}\n\nfunction create(node, id, self) {\n  var schedules = node.__transition,\n      tween;\n\n  // Initialize the self timer when the transition is created.\n  // Note the actual delay is not known until the first callback!\n  schedules[id] = self;\n  self.timer = timer(schedule, 0, self.time);\n\n  function schedule(elapsed) {\n    self.state = SCHEDULED;\n    self.timer.restart(start, self.delay, self.time);\n\n    // If the elapsed delay is less than our first sleep, start immediately.\n    if (self.delay <= elapsed) start(elapsed - self.delay);\n  }\n\n  function start(elapsed) {\n    var i, j, n, o;\n\n    // If the state is not SCHEDULED, then we previously errored on start.\n    if (self.state !== SCHEDULED) return stop();\n\n    for (i in schedules) {\n      o = schedules[i];\n      if (o.name !== self.name) continue;\n\n      // While this element already has a starting transition during this frame,\n      // defer starting an interrupting transition until that transition has a\n      // chance to tick (and possibly end); see d3/d3-transition#54!\n      if (o.state === STARTED) return timeout$1(start);\n\n      // Interrupt the active transition, if any.\n      // Dispatch the interrupt event.\n      if (o.state === RUNNING) {\n        o.state = ENDED;\n        o.timer.stop();\n        o.on.call(\"interrupt\", node, node.__data__, o.index, o.group);\n        delete schedules[i];\n      }\n\n      // Cancel any pre-empted transitions. No interrupt event is dispatched\n      // because the cancelled transitions never started. Note that this also\n      // removes this transition from the pending list!\n      else if (+i < id) {\n        o.state = ENDED;\n        o.timer.stop();\n        delete schedules[i];\n      }\n    }\n\n    // Defer the first tick to end of the current frame; see d3/d3#1576.\n    // Note the transition may be canceled after start and before the first tick!\n    // Note this must be scheduled before the start event; see d3/d3-transition#16!\n    // Assuming this is successful, subsequent callbacks go straight to tick.\n    timeout$1(function() {\n      if (self.state === STARTED) {\n        self.state = RUNNING;\n        self.timer.restart(tick, self.delay, self.time);\n        tick(elapsed);\n      }\n    });\n\n    // Dispatch the start event.\n    // Note this must be done before the tween are initialized.\n    self.state = STARTING;\n    self.on.call(\"start\", node, node.__data__, self.index, self.group);\n    if (self.state !== STARTING) return; // interrupted\n    self.state = STARTED;\n\n    // Initialize the tween, deleting null tween.\n    tween = new Array(n = self.tween.length);\n    for (i = 0, j = -1; i < n; ++i) {\n      if (o = self.tween[i].value.call(node, node.__data__, self.index, self.group)) {\n        tween[++j] = o;\n      }\n    }\n    tween.length = j + 1;\n  }\n\n  function tick(elapsed) {\n    var t = elapsed < self.duration ? self.ease.call(null, elapsed / self.duration) : (self.timer.restart(stop), self.state = ENDING, 1),\n        i = -1,\n        n = tween.length;\n\n    while (++i < n) {\n      tween[i].call(null, t);\n    }\n\n    // Dispatch the end event.\n    if (self.state === ENDING) {\n      self.on.call(\"end\", node, node.__data__, self.index, self.group);\n      stop();\n    }\n  }\n\n  function stop() {\n    self.state = ENDED;\n    self.timer.stop();\n    delete schedules[id];\n    for (var i in schedules) return; // eslint-disable-line no-unused-vars\n    delete node.__transition;\n  }\n}\n\nvar interrupt = function(node, name) {\n  var schedules = node.__transition,\n      schedule,\n      active,\n      empty = true,\n      i;\n\n  if (!schedules) return;\n\n  name = name == null ? null : name + \"\";\n\n  for (i in schedules) {\n    if ((schedule = schedules[i]).name !== name) { empty = false; continue; }\n    active = schedule.state > STARTING && schedule.state < ENDING;\n    schedule.state = ENDED;\n    schedule.timer.stop();\n    if (active) schedule.on.call(\"interrupt\", node, node.__data__, schedule.index, schedule.group);\n    delete schedules[i];\n  }\n\n  if (empty) delete node.__transition;\n};\n\nvar selection_interrupt = function(name) {\n  return this.each(function() {\n    interrupt(this, name);\n  });\n};\n\nfunction tweenRemove(id, name) {\n  var tween0, tween1;\n  return function() {\n    var schedule = set$1(this, id),\n        tween = schedule.tween;\n\n    // If this node shared tween with the previous node,\n    // just assign the updated shared tween and we’re done!\n    // Otherwise, copy-on-write.\n    if (tween !== tween0) {\n      tween1 = tween0 = tween;\n      for (var i = 0, n = tween1.length; i < n; ++i) {\n        if (tween1[i].name === name) {\n          tween1 = tween1.slice();\n          tween1.splice(i, 1);\n          break;\n        }\n      }\n    }\n\n    schedule.tween = tween1;\n  };\n}\n\nfunction tweenFunction(id, name, value) {\n  var tween0, tween1;\n  if (typeof value !== \"function\") throw new Error;\n  return function() {\n    var schedule = set$1(this, id),\n        tween = schedule.tween;\n\n    // If this node shared tween with the previous node,\n    // just assign the updated shared tween and we’re done!\n    // Otherwise, copy-on-write.\n    if (tween !== tween0) {\n      tween1 = (tween0 = tween).slice();\n      for (var t = {name: name, value: value}, i = 0, n = tween1.length; i < n; ++i) {\n        if (tween1[i].name === name) {\n          tween1[i] = t;\n          break;\n        }\n      }\n      if (i === n) tween1.push(t);\n    }\n\n    schedule.tween = tween1;\n  };\n}\n\nvar transition_tween = function(name, value) {\n  var id = this._id;\n\n  name += \"\";\n\n  if (arguments.length < 2) {\n    var tween = get$1(this.node(), id).tween;\n    for (var i = 0, n = tween.length, t; i < n; ++i) {\n      if ((t = tween[i]).name === name) {\n        return t.value;\n      }\n    }\n    return null;\n  }\n\n  return this.each((value == null ? tweenRemove : tweenFunction)(id, name, value));\n};\n\nfunction tweenValue(transition, name, value) {\n  var id = transition._id;\n\n  transition.each(function() {\n    var schedule = set$1(this, id);\n    (schedule.value || (schedule.value = {}))[name] = value.apply(this, arguments);\n  });\n\n  return function(node) {\n    return get$1(node, id).value[name];\n  };\n}\n\nvar interpolate$$1 = function(a, b) {\n  var c;\n  return (typeof b === \"number\" ? reinterpolate\n      : b instanceof color ? interpolateRgb\n      : (c = color(b)) ? (b = c, interpolateRgb)\n      : interpolateString)(a, b);\n};\n\nfunction attrRemove$1(name) {\n  return function() {\n    this.removeAttribute(name);\n  };\n}\n\nfunction attrRemoveNS$1(fullname) {\n  return function() {\n    this.removeAttributeNS(fullname.space, fullname.local);\n  };\n}\n\nfunction attrConstant$1(name, interpolate$$1, value1) {\n  var value00,\n      interpolate0;\n  return function() {\n    var value0 = this.getAttribute(name);\n    return value0 === value1 ? null\n        : value0 === value00 ? interpolate0\n        : interpolate0 = interpolate$$1(value00 = value0, value1);\n  };\n}\n\nfunction attrConstantNS$1(fullname, interpolate$$1, value1) {\n  var value00,\n      interpolate0;\n  return function() {\n    var value0 = this.getAttributeNS(fullname.space, fullname.local);\n    return value0 === value1 ? null\n        : value0 === value00 ? interpolate0\n        : interpolate0 = interpolate$$1(value00 = value0, value1);\n  };\n}\n\nfunction attrFunction$1(name, interpolate$$1, value) {\n  var value00,\n      value10,\n      interpolate0;\n  return function() {\n    var value0, value1 = value(this);\n    if (value1 == null) return void this.removeAttribute(name);\n    value0 = this.getAttribute(name);\n    return value0 === value1 ? null\n        : value0 === value00 && value1 === value10 ? interpolate0\n        : interpolate0 = interpolate$$1(value00 = value0, value10 = value1);\n  };\n}\n\nfunction attrFunctionNS$1(fullname, interpolate$$1, value) {\n  var value00,\n      value10,\n      interpolate0;\n  return function() {\n    var value0, value1 = value(this);\n    if (value1 == null) return void this.removeAttributeNS(fullname.space, fullname.local);\n    value0 = this.getAttributeNS(fullname.space, fullname.local);\n    return value0 === value1 ? null\n        : value0 === value00 && value1 === value10 ? interpolate0\n        : interpolate0 = interpolate$$1(value00 = value0, value10 = value1);\n  };\n}\n\nvar transition_attr = function(name, value) {\n  var fullname = namespace(name), i = fullname === \"transform\" ? interpolateTransformSvg : interpolate$$1;\n  return this.attrTween(name, typeof value === \"function\"\n      ? (fullname.local ? attrFunctionNS$1 : attrFunction$1)(fullname, i, tweenValue(this, \"attr.\" + name, value))\n      : value == null ? (fullname.local ? attrRemoveNS$1 : attrRemove$1)(fullname)\n      : (fullname.local ? attrConstantNS$1 : attrConstant$1)(fullname, i, value + \"\"));\n};\n\nfunction attrTweenNS(fullname, value) {\n  function tween() {\n    var node = this, i = value.apply(node, arguments);\n    return i && function(t) {\n      node.setAttributeNS(fullname.space, fullname.local, i(t));\n    };\n  }\n  tween._value = value;\n  return tween;\n}\n\nfunction attrTween(name, value) {\n  function tween() {\n    var node = this, i = value.apply(node, arguments);\n    return i && function(t) {\n      node.setAttribute(name, i(t));\n    };\n  }\n  tween._value = value;\n  return tween;\n}\n\nvar transition_attrTween = function(name, value) {\n  var key = \"attr.\" + name;\n  if (arguments.length < 2) return (key = this.tween(key)) && key._value;\n  if (value == null) return this.tween(key, null);\n  if (typeof value !== \"function\") throw new Error;\n  var fullname = namespace(name);\n  return this.tween(key, (fullname.local ? attrTweenNS : attrTween)(fullname, value));\n};\n\nfunction delayFunction(id, value) {\n  return function() {\n    init(this, id).delay = +value.apply(this, arguments);\n  };\n}\n\nfunction delayConstant(id, value) {\n  return value = +value, function() {\n    init(this, id).delay = value;\n  };\n}\n\nvar transition_delay = function(value) {\n  var id = this._id;\n\n  return arguments.length\n      ? this.each((typeof value === \"function\"\n          ? delayFunction\n          : delayConstant)(id, value))\n      : get$1(this.node(), id).delay;\n};\n\nfunction durationFunction(id, value) {\n  return function() {\n    set$1(this, id).duration = +value.apply(this, arguments);\n  };\n}\n\nfunction durationConstant(id, value) {\n  return value = +value, function() {\n    set$1(this, id).duration = value;\n  };\n}\n\nvar transition_duration = function(value) {\n  var id = this._id;\n\n  return arguments.length\n      ? this.each((typeof value === \"function\"\n          ? durationFunction\n          : durationConstant)(id, value))\n      : get$1(this.node(), id).duration;\n};\n\nfunction easeConstant(id, value) {\n  if (typeof value !== \"function\") throw new Error;\n  return function() {\n    set$1(this, id).ease = value;\n  };\n}\n\nvar transition_ease = function(value) {\n  var id = this._id;\n\n  return arguments.length\n      ? this.each(easeConstant(id, value))\n      : get$1(this.node(), id).ease;\n};\n\nvar transition_filter = function(match) {\n  if (typeof match !== \"function\") match = matcher$1(match);\n\n  for (var groups = this._groups, m = groups.length, subgroups = new Array(m), j = 0; j < m; ++j) {\n    for (var group = groups[j], n = group.length, subgroup = subgroups[j] = [], node, i = 0; i < n; ++i) {\n      if ((node = group[i]) && match.call(node, node.__data__, i, group)) {\n        subgroup.push(node);\n      }\n    }\n  }\n\n  return new Transition(subgroups, this._parents, this._name, this._id);\n};\n\nvar transition_merge = function(transition) {\n  if (transition._id !== this._id) throw new Error;\n\n  for (var groups0 = this._groups, groups1 = transition._groups, m0 = groups0.length, m1 = groups1.length, m = Math.min(m0, m1), merges = new Array(m0), j = 0; j < m; ++j) {\n    for (var group0 = groups0[j], group1 = groups1[j], n = group0.length, merge = merges[j] = new Array(n), node, i = 0; i < n; ++i) {\n      if (node = group0[i] || group1[i]) {\n        merge[i] = node;\n      }\n    }\n  }\n\n  for (; j < m0; ++j) {\n    merges[j] = groups0[j];\n  }\n\n  return new Transition(merges, this._parents, this._name, this._id);\n};\n\nfunction start(name) {\n  return (name + \"\").trim().split(/^|\\s+/).every(function(t) {\n    var i = t.indexOf(\".\");\n    if (i >= 0) t = t.slice(0, i);\n    return !t || t === \"start\";\n  });\n}\n\nfunction onFunction(id, name, listener) {\n  var on0, on1, sit = start(name) ? init : set$1;\n  return function() {\n    var schedule = sit(this, id),\n        on = schedule.on;\n\n    // If this node shared a dispatch with the previous node,\n    // just assign the updated shared dispatch and we’re done!\n    // Otherwise, copy-on-write.\n    if (on !== on0) (on1 = (on0 = on).copy()).on(name, listener);\n\n    schedule.on = on1;\n  };\n}\n\nvar transition_on = function(name, listener) {\n  var id = this._id;\n\n  return arguments.length < 2\n      ? get$1(this.node(), id).on.on(name)\n      : this.each(onFunction(id, name, listener));\n};\n\nfunction removeFunction(id) {\n  return function() {\n    var parent = this.parentNode;\n    for (var i in this.__transition) if (+i !== id) return;\n    if (parent) parent.removeChild(this);\n  };\n}\n\nvar transition_remove = function() {\n  return this.on(\"end.remove\", removeFunction(this._id));\n};\n\nvar transition_select = function(select$$1) {\n  var name = this._name,\n      id = this._id;\n\n  if (typeof select$$1 !== \"function\") select$$1 = selector(select$$1);\n\n  for (var groups = this._groups, m = groups.length, subgroups = new Array(m), j = 0; j < m; ++j) {\n    for (var group = groups[j], n = group.length, subgroup = subgroups[j] = new Array(n), node, subnode, i = 0; i < n; ++i) {\n      if ((node = group[i]) && (subnode = select$$1.call(node, node.__data__, i, group))) {\n        if (\"__data__\" in node) subnode.__data__ = node.__data__;\n        subgroup[i] = subnode;\n        schedule(subgroup[i], name, id, i, subgroup, get$1(node, id));\n      }\n    }\n  }\n\n  return new Transition(subgroups, this._parents, name, id);\n};\n\nvar transition_selectAll = function(select$$1) {\n  var name = this._name,\n      id = this._id;\n\n  if (typeof select$$1 !== \"function\") select$$1 = selectorAll(select$$1);\n\n  for (var groups = this._groups, m = groups.length, subgroups = [], parents = [], j = 0; j < m; ++j) {\n    for (var group = groups[j], n = group.length, node, i = 0; i < n; ++i) {\n      if (node = group[i]) {\n        for (var children = select$$1.call(node, node.__data__, i, group), child, inherit = get$1(node, id), k = 0, l = children.length; k < l; ++k) {\n          if (child = children[k]) {\n            schedule(child, name, id, k, children, inherit);\n          }\n        }\n        subgroups.push(children);\n        parents.push(node);\n      }\n    }\n  }\n\n  return new Transition(subgroups, parents, name, id);\n};\n\nvar Selection$1 = selection.prototype.constructor;\n\nvar transition_selection = function() {\n  return new Selection$1(this._groups, this._parents);\n};\n\nfunction styleRemove$1(name, interpolate$$2) {\n  var value00,\n      value10,\n      interpolate0;\n  return function() {\n    var value0 = styleValue(this, name),\n        value1 = (this.style.removeProperty(name), styleValue(this, name));\n    return value0 === value1 ? null\n        : value0 === value00 && value1 === value10 ? interpolate0\n        : interpolate0 = interpolate$$2(value00 = value0, value10 = value1);\n  };\n}\n\nfunction styleRemoveEnd(name) {\n  return function() {\n    this.style.removeProperty(name);\n  };\n}\n\nfunction styleConstant$1(name, interpolate$$2, value1) {\n  var value00,\n      interpolate0;\n  return function() {\n    var value0 = styleValue(this, name);\n    return value0 === value1 ? null\n        : value0 === value00 ? interpolate0\n        : interpolate0 = interpolate$$2(value00 = value0, value1);\n  };\n}\n\nfunction styleFunction$1(name, interpolate$$2, value) {\n  var value00,\n      value10,\n      interpolate0;\n  return function() {\n    var value0 = styleValue(this, name),\n        value1 = value(this);\n    if (value1 == null) value1 = (this.style.removeProperty(name), styleValue(this, name));\n    return value0 === value1 ? null\n        : value0 === value00 && value1 === value10 ? interpolate0\n        : interpolate0 = interpolate$$2(value00 = value0, value10 = value1);\n  };\n}\n\nvar transition_style = function(name, value, priority) {\n  var i = (name += \"\") === \"transform\" ? interpolateTransformCss : interpolate$$1;\n  return value == null ? this\n          .styleTween(name, styleRemove$1(name, i))\n          .on(\"end.style.\" + name, styleRemoveEnd(name))\n      : this.styleTween(name, typeof value === \"function\"\n          ? styleFunction$1(name, i, tweenValue(this, \"style.\" + name, value))\n          : styleConstant$1(name, i, value + \"\"), priority);\n};\n\nfunction styleTween(name, value, priority) {\n  function tween() {\n    var node = this, i = value.apply(node, arguments);\n    return i && function(t) {\n      node.style.setProperty(name, i(t), priority);\n    };\n  }\n  tween._value = value;\n  return tween;\n}\n\nvar transition_styleTween = function(name, value, priority) {\n  var key = \"style.\" + (name += \"\");\n  if (arguments.length < 2) return (key = this.tween(key)) && key._value;\n  if (value == null) return this.tween(key, null);\n  if (typeof value !== \"function\") throw new Error;\n  return this.tween(key, styleTween(name, value, priority == null ? \"\" : priority));\n};\n\nfunction textConstant$1(value) {\n  return function() {\n    this.textContent = value;\n  };\n}\n\nfunction textFunction$1(value) {\n  return function() {\n    var value1 = value(this);\n    this.textContent = value1 == null ? \"\" : value1;\n  };\n}\n\nvar transition_text = function(value) {\n  return this.tween(\"text\", typeof value === \"function\"\n      ? textFunction$1(tweenValue(this, \"text\", value))\n      : textConstant$1(value == null ? \"\" : value + \"\"));\n};\n\nvar transition_transition = function() {\n  var name = this._name,\n      id0 = this._id,\n      id1 = newId();\n\n  for (var groups = this._groups, m = groups.length, j = 0; j < m; ++j) {\n    for (var group = groups[j], n = group.length, node, i = 0; i < n; ++i) {\n      if (node = group[i]) {\n        var inherit = get$1(node, id0);\n        schedule(node, name, id1, i, group, {\n          time: inherit.time + inherit.delay + inherit.duration,\n          delay: 0,\n          duration: inherit.duration,\n          ease: inherit.ease\n        });\n      }\n    }\n  }\n\n  return new Transition(groups, this._parents, name, id1);\n};\n\nvar id = 0;\n\nfunction Transition(groups, parents, name, id) {\n  this._groups = groups;\n  this._parents = parents;\n  this._name = name;\n  this._id = id;\n}\n\nfunction transition(name) {\n  return selection().transition(name);\n}\n\nfunction newId() {\n  return ++id;\n}\n\nvar selection_prototype = selection.prototype;\n\nTransition.prototype = transition.prototype = {\n  constructor: Transition,\n  select: transition_select,\n  selectAll: transition_selectAll,\n  filter: transition_filter,\n  merge: transition_merge,\n  selection: transition_selection,\n  transition: transition_transition,\n  call: selection_prototype.call,\n  nodes: selection_prototype.nodes,\n  node: selection_prototype.node,\n  size: selection_prototype.size,\n  empty: selection_prototype.empty,\n  each: selection_prototype.each,\n  on: transition_on,\n  attr: transition_attr,\n  attrTween: transition_attrTween,\n  style: transition_style,\n  styleTween: transition_styleTween,\n  text: transition_text,\n  remove: transition_remove,\n  tween: transition_tween,\n  delay: transition_delay,\n  duration: transition_duration,\n  ease: transition_ease\n};\n\nfunction linear$1(t) {\n  return +t;\n}\n\nfunction quadIn(t) {\n  return t * t;\n}\n\nfunction quadOut(t) {\n  return t * (2 - t);\n}\n\nfunction quadInOut(t) {\n  return ((t *= 2) <= 1 ? t * t : --t * (2 - t) + 1) / 2;\n}\n\nfunction cubicIn(t) {\n  return t * t * t;\n}\n\nfunction cubicOut(t) {\n  return --t * t * t + 1;\n}\n\nfunction cubicInOut(t) {\n  return ((t *= 2) <= 1 ? t * t * t : (t -= 2) * t * t + 2) / 2;\n}\n\nvar exponent = 3;\n\nvar polyIn = (function custom(e) {\n  e = +e;\n\n  function polyIn(t) {\n    return Math.pow(t, e);\n  }\n\n  polyIn.exponent = custom;\n\n  return polyIn;\n})(exponent);\n\nvar polyOut = (function custom(e) {\n  e = +e;\n\n  function polyOut(t) {\n    return 1 - Math.pow(1 - t, e);\n  }\n\n  polyOut.exponent = custom;\n\n  return polyOut;\n})(exponent);\n\nvar polyInOut = (function custom(e) {\n  e = +e;\n\n  function polyInOut(t) {\n    return ((t *= 2) <= 1 ? Math.pow(t, e) : 2 - Math.pow(2 - t, e)) / 2;\n  }\n\n  polyInOut.exponent = custom;\n\n  return polyInOut;\n})(exponent);\n\nvar pi = Math.PI;\nvar halfPi = pi / 2;\n\nfunction sinIn(t) {\n  return 1 - Math.cos(t * halfPi);\n}\n\nfunction sinOut(t) {\n  return Math.sin(t * halfPi);\n}\n\nfunction sinInOut(t) {\n  return (1 - Math.cos(pi * t)) / 2;\n}\n\nfunction expIn(t) {\n  return Math.pow(2, 10 * t - 10);\n}\n\nfunction expOut(t) {\n  return 1 - Math.pow(2, -10 * t);\n}\n\nfunction expInOut(t) {\n  return ((t *= 2) <= 1 ? Math.pow(2, 10 * t - 10) : 2 - Math.pow(2, 10 - 10 * t)) / 2;\n}\n\nfunction circleIn(t) {\n  return 1 - Math.sqrt(1 - t * t);\n}\n\nfunction circleOut(t) {\n  return Math.sqrt(1 - --t * t);\n}\n\nfunction circleInOut(t) {\n  return ((t *= 2) <= 1 ? 1 - Math.sqrt(1 - t * t) : Math.sqrt(1 - (t -= 2) * t) + 1) / 2;\n}\n\nvar b1 = 4 / 11;\nvar b2 = 6 / 11;\nvar b3 = 8 / 11;\nvar b4 = 3 / 4;\nvar b5 = 9 / 11;\nvar b6 = 10 / 11;\nvar b7 = 15 / 16;\nvar b8 = 21 / 22;\nvar b9 = 63 / 64;\nvar b0 = 1 / b1 / b1;\n\nfunction bounceIn(t) {\n  return 1 - bounceOut(1 - t);\n}\n\nfunction bounceOut(t) {\n  return (t = +t) < b1 ? b0 * t * t : t < b3 ? b0 * (t -= b2) * t + b4 : t < b6 ? b0 * (t -= b5) * t + b7 : b0 * (t -= b8) * t + b9;\n}\n\nfunction bounceInOut(t) {\n  return ((t *= 2) <= 1 ? 1 - bounceOut(1 - t) : bounceOut(t - 1) + 1) / 2;\n}\n\nvar overshoot = 1.70158;\n\nvar backIn = (function custom(s) {\n  s = +s;\n\n  function backIn(t) {\n    return t * t * ((s + 1) * t - s);\n  }\n\n  backIn.overshoot = custom;\n\n  return backIn;\n})(overshoot);\n\nvar backOut = (function custom(s) {\n  s = +s;\n\n  function backOut(t) {\n    return --t * t * ((s + 1) * t + s) + 1;\n  }\n\n  backOut.overshoot = custom;\n\n  return backOut;\n})(overshoot);\n\nvar backInOut = (function custom(s) {\n  s = +s;\n\n  function backInOut(t) {\n    return ((t *= 2) < 1 ? t * t * ((s + 1) * t - s) : (t -= 2) * t * ((s + 1) * t + s) + 2) / 2;\n  }\n\n  backInOut.overshoot = custom;\n\n  return backInOut;\n})(overshoot);\n\nvar tau = 2 * Math.PI;\nvar amplitude = 1;\nvar period = 0.3;\n\nvar elasticIn = (function custom(a, p) {\n  var s = Math.asin(1 / (a = Math.max(1, a))) * (p /= tau);\n\n  function elasticIn(t) {\n    return a * Math.pow(2, 10 * --t) * Math.sin((s - t) / p);\n  }\n\n  elasticIn.amplitude = function(a) { return custom(a, p * tau); };\n  elasticIn.period = function(p) { return custom(a, p); };\n\n  return elasticIn;\n})(amplitude, period);\n\nvar elasticOut = (function custom(a, p) {\n  var s = Math.asin(1 / (a = Math.max(1, a))) * (p /= tau);\n\n  function elasticOut(t) {\n    return 1 - a * Math.pow(2, -10 * (t = +t)) * Math.sin((t + s) / p);\n  }\n\n  elasticOut.amplitude = function(a) { return custom(a, p * tau); };\n  elasticOut.period = function(p) { return custom(a, p); };\n\n  return elasticOut;\n})(amplitude, period);\n\nvar elasticInOut = (function custom(a, p) {\n  var s = Math.asin(1 / (a = Math.max(1, a))) * (p /= tau);\n\n  function elasticInOut(t) {\n    return ((t = t * 2 - 1) < 0\n        ? a * Math.pow(2, 10 * t) * Math.sin((s - t) / p)\n        : 2 - a * Math.pow(2, -10 * t) * Math.sin((s + t) / p)) / 2;\n  }\n\n  elasticInOut.amplitude = function(a) { return custom(a, p * tau); };\n  elasticInOut.period = function(p) { return custom(a, p); };\n\n  return elasticInOut;\n})(amplitude, period);\n\nvar defaultTiming = {\n  time: null, // Set on use.\n  delay: 0,\n  duration: 250,\n  ease: cubicInOut\n};\n\nfunction inherit(node, id) {\n  var timing;\n  while (!(timing = node.__transition) || !(timing = timing[id])) {\n    if (!(node = node.parentNode)) {\n      return defaultTiming.time = now(), defaultTiming;\n    }\n  }\n  return timing;\n}\n\nvar selection_transition = function(name) {\n  var id,\n      timing;\n\n  if (name instanceof Transition) {\n    id = name._id, name = name._name;\n  } else {\n    id = newId(), (timing = defaultTiming).time = now(), name = name == null ? null : name + \"\";\n  }\n\n  for (var groups = this._groups, m = groups.length, j = 0; j < m; ++j) {\n    for (var group = groups[j], n = group.length, node, i = 0; i < n; ++i) {\n      if (node = group[i]) {\n        schedule(node, name, id, i, group, timing || inherit(node, id));\n      }\n    }\n  }\n\n  return new Transition(groups, this._parents, name, id);\n};\n\nselection.prototype.interrupt = selection_interrupt;\nselection.prototype.transition = selection_transition;\n\nvar root$1 = [null];\n\nvar active = function(node, name) {\n  var schedules = node.__transition,\n      schedule,\n      i;\n\n  if (schedules) {\n    name = name == null ? null : name + \"\";\n    for (i in schedules) {\n      if ((schedule = schedules[i]).state > SCHEDULED && schedule.name === name) {\n        return new Transition([[node]], root$1, name, +i);\n      }\n    }\n  }\n\n  return null;\n};\n\nvar constant$4 = function(x) {\n  return function() {\n    return x;\n  };\n};\n\nvar BrushEvent = function(target, type, selection) {\n  this.target = target;\n  this.type = type;\n  this.selection = selection;\n};\n\nfunction nopropagation$1() {\n  exports.event.stopImmediatePropagation();\n}\n\nvar noevent$1 = function() {\n  exports.event.preventDefault();\n  exports.event.stopImmediatePropagation();\n};\n\nvar MODE_DRAG = {name: \"drag\"};\nvar MODE_SPACE = {name: \"space\"};\nvar MODE_HANDLE = {name: \"handle\"};\nvar MODE_CENTER = {name: \"center\"};\n\nvar X = {\n  name: \"x\",\n  handles: [\"e\", \"w\"].map(type),\n  input: function(x, e) { return x && [[x[0], e[0][1]], [x[1], e[1][1]]]; },\n  output: function(xy) { return xy && [xy[0][0], xy[1][0]]; }\n};\n\nvar Y = {\n  name: \"y\",\n  handles: [\"n\", \"s\"].map(type),\n  input: function(y, e) { return y && [[e[0][0], y[0]], [e[1][0], y[1]]]; },\n  output: function(xy) { return xy && [xy[0][1], xy[1][1]]; }\n};\n\nvar XY = {\n  name: \"xy\",\n  handles: [\"n\", \"e\", \"s\", \"w\", \"nw\", \"ne\", \"se\", \"sw\"].map(type),\n  input: function(xy) { return xy; },\n  output: function(xy) { return xy; }\n};\n\nvar cursors = {\n  overlay: \"crosshair\",\n  selection: \"move\",\n  n: \"ns-resize\",\n  e: \"ew-resize\",\n  s: \"ns-resize\",\n  w: \"ew-resize\",\n  nw: \"nwse-resize\",\n  ne: \"nesw-resize\",\n  se: \"nwse-resize\",\n  sw: \"nesw-resize\"\n};\n\nvar flipX = {\n  e: \"w\",\n  w: \"e\",\n  nw: \"ne\",\n  ne: \"nw\",\n  se: \"sw\",\n  sw: \"se\"\n};\n\nvar flipY = {\n  n: \"s\",\n  s: \"n\",\n  nw: \"sw\",\n  ne: \"se\",\n  se: \"ne\",\n  sw: \"nw\"\n};\n\nvar signsX = {\n  overlay: +1,\n  selection: +1,\n  n: null,\n  e: +1,\n  s: null,\n  w: -1,\n  nw: -1,\n  ne: +1,\n  se: +1,\n  sw: -1\n};\n\nvar signsY = {\n  overlay: +1,\n  selection: +1,\n  n: -1,\n  e: null,\n  s: +1,\n  w: null,\n  nw: -1,\n  ne: -1,\n  se: +1,\n  sw: +1\n};\n\nfunction type(t) {\n  return {type: t};\n}\n\n// Ignore right-click, since that should open the context menu.\nfunction defaultFilter() {\n  return !exports.event.button;\n}\n\nfunction defaultExtent() {\n  var svg = this.ownerSVGElement || this;\n  return [[0, 0], [svg.width.baseVal.value, svg.height.baseVal.value]];\n}\n\n// Like d3.local, but with the name “__brush” rather than auto-generated.\nfunction local$$1(node) {\n  while (!node.__brush) if (!(node = node.parentNode)) return;\n  return node.__brush;\n}\n\nfunction empty(extent) {\n  return extent[0][0] === extent[1][0]\n      || extent[0][1] === extent[1][1];\n}\n\nfunction brushSelection(node) {\n  var state = node.__brush;\n  return state ? state.dim.output(state.selection) : null;\n}\n\nfunction brushX() {\n  return brush$1(X);\n}\n\nfunction brushY() {\n  return brush$1(Y);\n}\n\nvar brush = function() {\n  return brush$1(XY);\n};\n\nfunction brush$1(dim) {\n  var extent = defaultExtent,\n      filter = defaultFilter,\n      listeners = dispatch(brush, \"start\", \"brush\", \"end\"),\n      handleSize = 6,\n      touchending;\n\n  function brush(group) {\n    var overlay = group\n        .property(\"__brush\", initialize)\n      .selectAll(\".overlay\")\n      .data([type(\"overlay\")]);\n\n    overlay.enter().append(\"rect\")\n        .attr(\"class\", \"overlay\")\n        .attr(\"pointer-events\", \"all\")\n        .attr(\"cursor\", cursors.overlay)\n      .merge(overlay)\n        .each(function() {\n          var extent = local$$1(this).extent;\n          select(this)\n              .attr(\"x\", extent[0][0])\n              .attr(\"y\", extent[0][1])\n              .attr(\"width\", extent[1][0] - extent[0][0])\n              .attr(\"height\", extent[1][1] - extent[0][1]);\n        });\n\n    group.selectAll(\".selection\")\n      .data([type(\"selection\")])\n      .enter().append(\"rect\")\n        .attr(\"class\", \"selection\")\n        .attr(\"cursor\", cursors.selection)\n        .attr(\"fill\", \"#777\")\n        .attr(\"fill-opacity\", 0.3)\n        .attr(\"stroke\", \"#fff\")\n        .attr(\"shape-rendering\", \"crispEdges\");\n\n    var handle = group.selectAll(\".handle\")\n      .data(dim.handles, function(d) { return d.type; });\n\n    handle.exit().remove();\n\n    handle.enter().append(\"rect\")\n        .attr(\"class\", function(d) { return \"handle handle--\" + d.type; })\n        .attr(\"cursor\", function(d) { return cursors[d.type]; });\n\n    group\n        .each(redraw)\n        .attr(\"fill\", \"none\")\n        .attr(\"pointer-events\", \"all\")\n        .style(\"-webkit-tap-highlight-color\", \"rgba(0,0,0,0)\")\n        .on(\"mousedown.brush touchstart.brush\", started);\n  }\n\n  brush.move = function(group, selection$$1) {\n    if (group.selection) {\n      group\n          .on(\"start.brush\", function() { emitter(this, arguments).beforestart().start(); })\n          .on(\"interrupt.brush end.brush\", function() { emitter(this, arguments).end(); })\n          .tween(\"brush\", function() {\n            var that = this,\n                state = that.__brush,\n                emit = emitter(that, arguments),\n                selection0 = state.selection,\n                selection1 = dim.input(typeof selection$$1 === \"function\" ? selection$$1.apply(this, arguments) : selection$$1, state.extent),\n                i = interpolateValue(selection0, selection1);\n\n            function tween(t) {\n              state.selection = t === 1 && empty(selection1) ? null : i(t);\n              redraw.call(that);\n              emit.brush();\n            }\n\n            return selection0 && selection1 ? tween : tween(1);\n          });\n    } else {\n      group\n          .each(function() {\n            var that = this,\n                args = arguments,\n                state = that.__brush,\n                selection1 = dim.input(typeof selection$$1 === \"function\" ? selection$$1.apply(that, args) : selection$$1, state.extent),\n                emit = emitter(that, args).beforestart();\n\n            interrupt(that);\n            state.selection = selection1 == null || empty(selection1) ? null : selection1;\n            redraw.call(that);\n            emit.start().brush().end();\n          });\n    }\n  };\n\n  function redraw() {\n    var group = select(this),\n        selection$$1 = local$$1(this).selection;\n\n    if (selection$$1) {\n      group.selectAll(\".selection\")\n          .style(\"display\", null)\n          .attr(\"x\", selection$$1[0][0])\n          .attr(\"y\", selection$$1[0][1])\n          .attr(\"width\", selection$$1[1][0] - selection$$1[0][0])\n          .attr(\"height\", selection$$1[1][1] - selection$$1[0][1]);\n\n      group.selectAll(\".handle\")\n          .style(\"display\", null)\n          .attr(\"x\", function(d) { return d.type[d.type.length - 1] === \"e\" ? selection$$1[1][0] - handleSize / 2 : selection$$1[0][0] - handleSize / 2; })\n          .attr(\"y\", function(d) { return d.type[0] === \"s\" ? selection$$1[1][1] - handleSize / 2 : selection$$1[0][1] - handleSize / 2; })\n          .attr(\"width\", function(d) { return d.type === \"n\" || d.type === \"s\" ? selection$$1[1][0] - selection$$1[0][0] + handleSize : handleSize; })\n          .attr(\"height\", function(d) { return d.type === \"e\" || d.type === \"w\" ? selection$$1[1][1] - selection$$1[0][1] + handleSize : handleSize; });\n    }\n\n    else {\n      group.selectAll(\".selection,.handle\")\n          .style(\"display\", \"none\")\n          .attr(\"x\", null)\n          .attr(\"y\", null)\n          .attr(\"width\", null)\n          .attr(\"height\", null);\n    }\n  }\n\n  function emitter(that, args) {\n    return that.__brush.emitter || new Emitter(that, args);\n  }\n\n  function Emitter(that, args) {\n    this.that = that;\n    this.args = args;\n    this.state = that.__brush;\n    this.active = 0;\n  }\n\n  Emitter.prototype = {\n    beforestart: function() {\n      if (++this.active === 1) this.state.emitter = this, this.starting = true;\n      return this;\n    },\n    start: function() {\n      if (this.starting) this.starting = false, this.emit(\"start\");\n      return this;\n    },\n    brush: function() {\n      this.emit(\"brush\");\n      return this;\n    },\n    end: function() {\n      if (--this.active === 0) delete this.state.emitter, this.emit(\"end\");\n      return this;\n    },\n    emit: function(type) {\n      customEvent(new BrushEvent(brush, type, dim.output(this.state.selection)), listeners.apply, listeners, [type, this.that, this.args]);\n    }\n  };\n\n  function started() {\n    if (exports.event.touches) { if (exports.event.changedTouches.length < exports.event.touches.length) return noevent$1(); }\n    else if (touchending) return;\n    if (!filter.apply(this, arguments)) return;\n\n    var that = this,\n        type = exports.event.target.__data__.type,\n        mode = (exports.event.metaKey ? type = \"overlay\" : type) === \"selection\" ? MODE_DRAG : (exports.event.altKey ? MODE_CENTER : MODE_HANDLE),\n        signX = dim === Y ? null : signsX[type],\n        signY = dim === X ? null : signsY[type],\n        state = local$$1(that),\n        extent = state.extent,\n        selection$$1 = state.selection,\n        W = extent[0][0], w0, w1,\n        N = extent[0][1], n0, n1,\n        E = extent[1][0], e0, e1,\n        S = extent[1][1], s0, s1,\n        dx,\n        dy,\n        moving,\n        shifting = signX && signY && exports.event.shiftKey,\n        lockX,\n        lockY,\n        point0 = mouse(that),\n        point = point0,\n        emit = emitter(that, arguments).beforestart();\n\n    if (type === \"overlay\") {\n      state.selection = selection$$1 = [\n        [w0 = dim === Y ? W : point0[0], n0 = dim === X ? N : point0[1]],\n        [e0 = dim === Y ? E : w0, s0 = dim === X ? S : n0]\n      ];\n    } else {\n      w0 = selection$$1[0][0];\n      n0 = selection$$1[0][1];\n      e0 = selection$$1[1][0];\n      s0 = selection$$1[1][1];\n    }\n\n    w1 = w0;\n    n1 = n0;\n    e1 = e0;\n    s1 = s0;\n\n    var group = select(that)\n        .attr(\"pointer-events\", \"none\");\n\n    var overlay = group.selectAll(\".overlay\")\n        .attr(\"cursor\", cursors[type]);\n\n    if (exports.event.touches) {\n      group\n          .on(\"touchmove.brush\", moved, true)\n          .on(\"touchend.brush touchcancel.brush\", ended, true);\n    } else {\n      var view = select(exports.event.view)\n          .on(\"keydown.brush\", keydowned, true)\n          .on(\"keyup.brush\", keyupped, true)\n          .on(\"mousemove.brush\", moved, true)\n          .on(\"mouseup.brush\", ended, true);\n\n      dragDisable(exports.event.view);\n    }\n\n    nopropagation$1();\n    interrupt(that);\n    redraw.call(that);\n    emit.start();\n\n    function moved() {\n      var point1 = mouse(that);\n      if (shifting && !lockX && !lockY) {\n        if (Math.abs(point1[0] - point[0]) > Math.abs(point1[1] - point[1])) lockY = true;\n        else lockX = true;\n      }\n      point = point1;\n      moving = true;\n      noevent$1();\n      move();\n    }\n\n    function move() {\n      var t;\n\n      dx = point[0] - point0[0];\n      dy = point[1] - point0[1];\n\n      switch (mode) {\n        case MODE_SPACE:\n        case MODE_DRAG: {\n          if (signX) dx = Math.max(W - w0, Math.min(E - e0, dx)), w1 = w0 + dx, e1 = e0 + dx;\n          if (signY) dy = Math.max(N - n0, Math.min(S - s0, dy)), n1 = n0 + dy, s1 = s0 + dy;\n          break;\n        }\n        case MODE_HANDLE: {\n          if (signX < 0) dx = Math.max(W - w0, Math.min(E - w0, dx)), w1 = w0 + dx, e1 = e0;\n          else if (signX > 0) dx = Math.max(W - e0, Math.min(E - e0, dx)), w1 = w0, e1 = e0 + dx;\n          if (signY < 0) dy = Math.max(N - n0, Math.min(S - n0, dy)), n1 = n0 + dy, s1 = s0;\n          else if (signY > 0) dy = Math.max(N - s0, Math.min(S - s0, dy)), n1 = n0, s1 = s0 + dy;\n          break;\n        }\n        case MODE_CENTER: {\n          if (signX) w1 = Math.max(W, Math.min(E, w0 - dx * signX)), e1 = Math.max(W, Math.min(E, e0 + dx * signX));\n          if (signY) n1 = Math.max(N, Math.min(S, n0 - dy * signY)), s1 = Math.max(N, Math.min(S, s0 + dy * signY));\n          break;\n        }\n      }\n\n      if (e1 < w1) {\n        signX *= -1;\n        t = w0, w0 = e0, e0 = t;\n        t = w1, w1 = e1, e1 = t;\n        if (type in flipX) overlay.attr(\"cursor\", cursors[type = flipX[type]]);\n      }\n\n      if (s1 < n1) {\n        signY *= -1;\n        t = n0, n0 = s0, s0 = t;\n        t = n1, n1 = s1, s1 = t;\n        if (type in flipY) overlay.attr(\"cursor\", cursors[type = flipY[type]]);\n      }\n\n      if (state.selection) selection$$1 = state.selection; // May be set by brush.move!\n      if (lockX) w1 = selection$$1[0][0], e1 = selection$$1[1][0];\n      if (lockY) n1 = selection$$1[0][1], s1 = selection$$1[1][1];\n\n      if (selection$$1[0][0] !== w1\n          || selection$$1[0][1] !== n1\n          || selection$$1[1][0] !== e1\n          || selection$$1[1][1] !== s1) {\n        state.selection = [[w1, n1], [e1, s1]];\n        redraw.call(that);\n        emit.brush();\n      }\n    }\n\n    function ended() {\n      nopropagation$1();\n      if (exports.event.touches) {\n        if (exports.event.touches.length) return;\n        if (touchending) clearTimeout(touchending);\n        touchending = setTimeout(function() { touchending = null; }, 500); // Ghost clicks are delayed!\n        group.on(\"touchmove.brush touchend.brush touchcancel.brush\", null);\n      } else {\n        yesdrag(exports.event.view, moving);\n        view.on(\"keydown.brush keyup.brush mousemove.brush mouseup.brush\", null);\n      }\n      group.attr(\"pointer-events\", \"all\");\n      overlay.attr(\"cursor\", cursors.overlay);\n      if (state.selection) selection$$1 = state.selection; // May be set by brush.move (on start)!\n      if (empty(selection$$1)) state.selection = null, redraw.call(that);\n      emit.end();\n    }\n\n    function keydowned() {\n      switch (exports.event.keyCode) {\n        case 16: { // SHIFT\n          shifting = signX && signY;\n          break;\n        }\n        case 18: { // ALT\n          if (mode === MODE_HANDLE) {\n            if (signX) e0 = e1 - dx * signX, w0 = w1 + dx * signX;\n            if (signY) s0 = s1 - dy * signY, n0 = n1 + dy * signY;\n            mode = MODE_CENTER;\n            move();\n          }\n          break;\n        }\n        case 32: { // SPACE; takes priority over ALT\n          if (mode === MODE_HANDLE || mode === MODE_CENTER) {\n            if (signX < 0) e0 = e1 - dx; else if (signX > 0) w0 = w1 - dx;\n            if (signY < 0) s0 = s1 - dy; else if (signY > 0) n0 = n1 - dy;\n            mode = MODE_SPACE;\n            overlay.attr(\"cursor\", cursors.selection);\n            move();\n          }\n          break;\n        }\n        default: return;\n      }\n      noevent$1();\n    }\n\n    function keyupped() {\n      switch (exports.event.keyCode) {\n        case 16: { // SHIFT\n          if (shifting) {\n            lockX = lockY = shifting = false;\n            move();\n          }\n          break;\n        }\n        case 18: { // ALT\n          if (mode === MODE_CENTER) {\n            if (signX < 0) e0 = e1; else if (signX > 0) w0 = w1;\n            if (signY < 0) s0 = s1; else if (signY > 0) n0 = n1;\n            mode = MODE_HANDLE;\n            move();\n          }\n          break;\n        }\n        case 32: { // SPACE\n          if (mode === MODE_SPACE) {\n            if (exports.event.altKey) {\n              if (signX) e0 = e1 - dx * signX, w0 = w1 + dx * signX;\n              if (signY) s0 = s1 - dy * signY, n0 = n1 + dy * signY;\n              mode = MODE_CENTER;\n            } else {\n              if (signX < 0) e0 = e1; else if (signX > 0) w0 = w1;\n              if (signY < 0) s0 = s1; else if (signY > 0) n0 = n1;\n              mode = MODE_HANDLE;\n            }\n            overlay.attr(\"cursor\", cursors[type]);\n            move();\n          }\n          break;\n        }\n        default: return;\n      }\n      noevent$1();\n    }\n  }\n\n  function initialize() {\n    var state = this.__brush || {selection: null};\n    state.extent = extent.apply(this, arguments);\n    state.dim = dim;\n    return state;\n  }\n\n  brush.extent = function(_) {\n    return arguments.length ? (extent = typeof _ === \"function\" ? _ : constant$4([[+_[0][0], +_[0][1]], [+_[1][0], +_[1][1]]]), brush) : extent;\n  };\n\n  brush.filter = function(_) {\n    return arguments.length ? (filter = typeof _ === \"function\" ? _ : constant$4(!!_), brush) : filter;\n  };\n\n  brush.handleSize = function(_) {\n    return arguments.length ? (handleSize = +_, brush) : handleSize;\n  };\n\n  brush.on = function() {\n    var value = listeners.on.apply(listeners, arguments);\n    return value === listeners ? brush : value;\n  };\n\n  return brush;\n}\n\nvar cos = Math.cos;\nvar sin = Math.sin;\nvar pi$1 = Math.PI;\nvar halfPi$1 = pi$1 / 2;\nvar tau$1 = pi$1 * 2;\nvar max$1 = Math.max;\n\nfunction compareValue(compare) {\n  return function(a, b) {\n    return compare(\n      a.source.value + a.target.value,\n      b.source.value + b.target.value\n    );\n  };\n}\n\nvar chord = function() {\n  var padAngle = 0,\n      sortGroups = null,\n      sortSubgroups = null,\n      sortChords = null;\n\n  function chord(matrix) {\n    var n = matrix.length,\n        groupSums = [],\n        groupIndex = sequence(n),\n        subgroupIndex = [],\n        chords = [],\n        groups = chords.groups = new Array(n),\n        subgroups = new Array(n * n),\n        k,\n        x,\n        x0,\n        dx,\n        i,\n        j;\n\n    // Compute the sum.\n    k = 0, i = -1; while (++i < n) {\n      x = 0, j = -1; while (++j < n) {\n        x += matrix[i][j];\n      }\n      groupSums.push(x);\n      subgroupIndex.push(sequence(n));\n      k += x;\n    }\n\n    // Sort groups…\n    if (sortGroups) groupIndex.sort(function(a, b) {\n      return sortGroups(groupSums[a], groupSums[b]);\n    });\n\n    // Sort subgroups…\n    if (sortSubgroups) subgroupIndex.forEach(function(d, i) {\n      d.sort(function(a, b) {\n        return sortSubgroups(matrix[i][a], matrix[i][b]);\n      });\n    });\n\n    // Convert the sum to scaling factor for [0, 2pi].\n    // TODO Allow start and end angle to be specified?\n    // TODO Allow padding to be specified as percentage?\n    k = max$1(0, tau$1 - padAngle * n) / k;\n    dx = k ? padAngle : tau$1 / n;\n\n    // Compute the start and end angle for each group and subgroup.\n    // Note: Opera has a bug reordering object literal properties!\n    x = 0, i = -1; while (++i < n) {\n      x0 = x, j = -1; while (++j < n) {\n        var di = groupIndex[i],\n            dj = subgroupIndex[di][j],\n            v = matrix[di][dj],\n            a0 = x,\n            a1 = x += v * k;\n        subgroups[dj * n + di] = {\n          index: di,\n          subindex: dj,\n          startAngle: a0,\n          endAngle: a1,\n          value: v\n        };\n      }\n      groups[di] = {\n        index: di,\n        startAngle: x0,\n        endAngle: x,\n        value: groupSums[di]\n      };\n      x += dx;\n    }\n\n    // Generate chords for each (non-empty) subgroup-subgroup link.\n    i = -1; while (++i < n) {\n      j = i - 1; while (++j < n) {\n        var source = subgroups[j * n + i],\n            target = subgroups[i * n + j];\n        if (source.value || target.value) {\n          chords.push(source.value < target.value\n              ? {source: target, target: source}\n              : {source: source, target: target});\n        }\n      }\n    }\n\n    return sortChords ? chords.sort(sortChords) : chords;\n  }\n\n  chord.padAngle = function(_) {\n    return arguments.length ? (padAngle = max$1(0, _), chord) : padAngle;\n  };\n\n  chord.sortGroups = function(_) {\n    return arguments.length ? (sortGroups = _, chord) : sortGroups;\n  };\n\n  chord.sortSubgroups = function(_) {\n    return arguments.length ? (sortSubgroups = _, chord) : sortSubgroups;\n  };\n\n  chord.sortChords = function(_) {\n    return arguments.length ? (_ == null ? sortChords = null : (sortChords = compareValue(_))._ = _, chord) : sortChords && sortChords._;\n  };\n\n  return chord;\n};\n\nvar slice$2 = Array.prototype.slice;\n\nvar constant$5 = function(x) {\n  return function() {\n    return x;\n  };\n};\n\nvar pi$2 = Math.PI;\nvar tau$2 = 2 * pi$2;\nvar epsilon$1 = 1e-6;\nvar tauEpsilon = tau$2 - epsilon$1;\n\nfunction Path() {\n  this._x0 = this._y0 = // start of current subpath\n  this._x1 = this._y1 = null; // end of current subpath\n  this._ = \"\";\n}\n\nfunction path() {\n  return new Path;\n}\n\nPath.prototype = path.prototype = {\n  constructor: Path,\n  moveTo: function(x, y) {\n    this._ += \"M\" + (this._x0 = this._x1 = +x) + \",\" + (this._y0 = this._y1 = +y);\n  },\n  closePath: function() {\n    if (this._x1 !== null) {\n      this._x1 = this._x0, this._y1 = this._y0;\n      this._ += \"Z\";\n    }\n  },\n  lineTo: function(x, y) {\n    this._ += \"L\" + (this._x1 = +x) + \",\" + (this._y1 = +y);\n  },\n  quadraticCurveTo: function(x1, y1, x, y) {\n    this._ += \"Q\" + (+x1) + \",\" + (+y1) + \",\" + (this._x1 = +x) + \",\" + (this._y1 = +y);\n  },\n  bezierCurveTo: function(x1, y1, x2, y2, x, y) {\n    this._ += \"C\" + (+x1) + \",\" + (+y1) + \",\" + (+x2) + \",\" + (+y2) + \",\" + (this._x1 = +x) + \",\" + (this._y1 = +y);\n  },\n  arcTo: function(x1, y1, x2, y2, r) {\n    x1 = +x1, y1 = +y1, x2 = +x2, y2 = +y2, r = +r;\n    var x0 = this._x1,\n        y0 = this._y1,\n        x21 = x2 - x1,\n        y21 = y2 - y1,\n        x01 = x0 - x1,\n        y01 = y0 - y1,\n        l01_2 = x01 * x01 + y01 * y01;\n\n    // Is the radius negative? Error.\n    if (r < 0) throw new Error(\"negative radius: \" + r);\n\n    // Is this path empty? Move to (x1,y1).\n    if (this._x1 === null) {\n      this._ += \"M\" + (this._x1 = x1) + \",\" + (this._y1 = y1);\n    }\n\n    // Or, is (x1,y1) coincident with (x0,y0)? Do nothing.\n    else if (!(l01_2 > epsilon$1)) {}\n\n    // Or, are (x0,y0), (x1,y1) and (x2,y2) collinear?\n    // Equivalently, is (x1,y1) coincident with (x2,y2)?\n    // Or, is the radius zero? Line to (x1,y1).\n    else if (!(Math.abs(y01 * x21 - y21 * x01) > epsilon$1) || !r) {\n      this._ += \"L\" + (this._x1 = x1) + \",\" + (this._y1 = y1);\n    }\n\n    // Otherwise, draw an arc!\n    else {\n      var x20 = x2 - x0,\n          y20 = y2 - y0,\n          l21_2 = x21 * x21 + y21 * y21,\n          l20_2 = x20 * x20 + y20 * y20,\n          l21 = Math.sqrt(l21_2),\n          l01 = Math.sqrt(l01_2),\n          l = r * Math.tan((pi$2 - Math.acos((l21_2 + l01_2 - l20_2) / (2 * l21 * l01))) / 2),\n          t01 = l / l01,\n          t21 = l / l21;\n\n      // If the start tangent is not coincident with (x0,y0), line to.\n      if (Math.abs(t01 - 1) > epsilon$1) {\n        this._ += \"L\" + (x1 + t01 * x01) + \",\" + (y1 + t01 * y01);\n      }\n\n      this._ += \"A\" + r + \",\" + r + \",0,0,\" + (+(y01 * x20 > x01 * y20)) + \",\" + (this._x1 = x1 + t21 * x21) + \",\" + (this._y1 = y1 + t21 * y21);\n    }\n  },\n  arc: function(x, y, r, a0, a1, ccw) {\n    x = +x, y = +y, r = +r;\n    var dx = r * Math.cos(a0),\n        dy = r * Math.sin(a0),\n        x0 = x + dx,\n        y0 = y + dy,\n        cw = 1 ^ ccw,\n        da = ccw ? a0 - a1 : a1 - a0;\n\n    // Is the radius negative? Error.\n    if (r < 0) throw new Error(\"negative radius: \" + r);\n\n    // Is this path empty? Move to (x0,y0).\n    if (this._x1 === null) {\n      this._ += \"M\" + x0 + \",\" + y0;\n    }\n\n    // Or, is (x0,y0) not coincident with the previous point? Line to (x0,y0).\n    else if (Math.abs(this._x1 - x0) > epsilon$1 || Math.abs(this._y1 - y0) > epsilon$1) {\n      this._ += \"L\" + x0 + \",\" + y0;\n    }\n\n    // Is this arc empty? We’re done.\n    if (!r) return;\n\n    // Does the angle go the wrong way? Flip the direction.\n    if (da < 0) da = da % tau$2 + tau$2;\n\n    // Is this a complete circle? Draw two arcs to complete the circle.\n    if (da > tauEpsilon) {\n      this._ += \"A\" + r + \",\" + r + \",0,1,\" + cw + \",\" + (x - dx) + \",\" + (y - dy) + \"A\" + r + \",\" + r + \",0,1,\" + cw + \",\" + (this._x1 = x0) + \",\" + (this._y1 = y0);\n    }\n\n    // Is this arc non-empty? Draw an arc!\n    else if (da > epsilon$1) {\n      this._ += \"A\" + r + \",\" + r + \",0,\" + (+(da >= pi$2)) + \",\" + cw + \",\" + (this._x1 = x + r * Math.cos(a1)) + \",\" + (this._y1 = y + r * Math.sin(a1));\n    }\n  },\n  rect: function(x, y, w, h) {\n    this._ += \"M\" + (this._x0 = this._x1 = +x) + \",\" + (this._y0 = this._y1 = +y) + \"h\" + (+w) + \"v\" + (+h) + \"h\" + (-w) + \"Z\";\n  },\n  toString: function() {\n    return this._;\n  }\n};\n\nfunction defaultSource(d) {\n  return d.source;\n}\n\nfunction defaultTarget(d) {\n  return d.target;\n}\n\nfunction defaultRadius(d) {\n  return d.radius;\n}\n\nfunction defaultStartAngle(d) {\n  return d.startAngle;\n}\n\nfunction defaultEndAngle(d) {\n  return d.endAngle;\n}\n\nvar ribbon = function() {\n  var source = defaultSource,\n      target = defaultTarget,\n      radius = defaultRadius,\n      startAngle = defaultStartAngle,\n      endAngle = defaultEndAngle,\n      context = null;\n\n  function ribbon() {\n    var buffer,\n        argv = slice$2.call(arguments),\n        s = source.apply(this, argv),\n        t = target.apply(this, argv),\n        sr = +radius.apply(this, (argv[0] = s, argv)),\n        sa0 = startAngle.apply(this, argv) - halfPi$1,\n        sa1 = endAngle.apply(this, argv) - halfPi$1,\n        sx0 = sr * cos(sa0),\n        sy0 = sr * sin(sa0),\n        tr = +radius.apply(this, (argv[0] = t, argv)),\n        ta0 = startAngle.apply(this, argv) - halfPi$1,\n        ta1 = endAngle.apply(this, argv) - halfPi$1;\n\n    if (!context) context = buffer = path();\n\n    context.moveTo(sx0, sy0);\n    context.arc(0, 0, sr, sa0, sa1);\n    if (sa0 !== ta0 || sa1 !== ta1) { // TODO sr !== tr?\n      context.quadraticCurveTo(0, 0, tr * cos(ta0), tr * sin(ta0));\n      context.arc(0, 0, tr, ta0, ta1);\n    }\n    context.quadraticCurveTo(0, 0, sx0, sy0);\n    context.closePath();\n\n    if (buffer) return context = null, buffer + \"\" || null;\n  }\n\n  ribbon.radius = function(_) {\n    return arguments.length ? (radius = typeof _ === \"function\" ? _ : constant$5(+_), ribbon) : radius;\n  };\n\n  ribbon.startAngle = function(_) {\n    return arguments.length ? (startAngle = typeof _ === \"function\" ? _ : constant$5(+_), ribbon) : startAngle;\n  };\n\n  ribbon.endAngle = function(_) {\n    return arguments.length ? (endAngle = typeof _ === \"function\" ? _ : constant$5(+_), ribbon) : endAngle;\n  };\n\n  ribbon.source = function(_) {\n    return arguments.length ? (source = _, ribbon) : source;\n  };\n\n  ribbon.target = function(_) {\n    return arguments.length ? (target = _, ribbon) : target;\n  };\n\n  ribbon.context = function(_) {\n    return arguments.length ? ((context = _ == null ? null : _), ribbon) : context;\n  };\n\n  return ribbon;\n};\n\nvar prefix = \"$\";\n\nfunction Map() {}\n\nMap.prototype = map$1.prototype = {\n  constructor: Map,\n  has: function(key) {\n    return (prefix + key) in this;\n  },\n  get: function(key) {\n    return this[prefix + key];\n  },\n  set: function(key, value) {\n    this[prefix + key] = value;\n    return this;\n  },\n  remove: function(key) {\n    var property = prefix + key;\n    return property in this && delete this[property];\n  },\n  clear: function() {\n    for (var property in this) if (property[0] === prefix) delete this[property];\n  },\n  keys: function() {\n    var keys = [];\n    for (var property in this) if (property[0] === prefix) keys.push(property.slice(1));\n    return keys;\n  },\n  values: function() {\n    var values = [];\n    for (var property in this) if (property[0] === prefix) values.push(this[property]);\n    return values;\n  },\n  entries: function() {\n    var entries = [];\n    for (var property in this) if (property[0] === prefix) entries.push({key: property.slice(1), value: this[property]});\n    return entries;\n  },\n  size: function() {\n    var size = 0;\n    for (var property in this) if (property[0] === prefix) ++size;\n    return size;\n  },\n  empty: function() {\n    for (var property in this) if (property[0] === prefix) return false;\n    return true;\n  },\n  each: function(f) {\n    for (var property in this) if (property[0] === prefix) f(this[property], property.slice(1), this);\n  }\n};\n\nfunction map$1(object, f) {\n  var map = new Map;\n\n  // Copy constructor.\n  if (object instanceof Map) object.each(function(value, key) { map.set(key, value); });\n\n  // Index array by numeric index or specified key function.\n  else if (Array.isArray(object)) {\n    var i = -1,\n        n = object.length,\n        o;\n\n    if (f == null) while (++i < n) map.set(i, object[i]);\n    else while (++i < n) map.set(f(o = object[i], i, object), o);\n  }\n\n  // Convert object to map.\n  else if (object) for (var key in object) map.set(key, object[key]);\n\n  return map;\n}\n\nvar nest = function() {\n  var keys = [],\n      sortKeys = [],\n      sortValues,\n      rollup,\n      nest;\n\n  function apply(array, depth, createResult, setResult) {\n    if (depth >= keys.length) return rollup != null\n        ? rollup(array) : (sortValues != null\n        ? array.sort(sortValues)\n        : array);\n\n    var i = -1,\n        n = array.length,\n        key = keys[depth++],\n        keyValue,\n        value,\n        valuesByKey = map$1(),\n        values,\n        result = createResult();\n\n    while (++i < n) {\n      if (values = valuesByKey.get(keyValue = key(value = array[i]) + \"\")) {\n        values.push(value);\n      } else {\n        valuesByKey.set(keyValue, [value]);\n      }\n    }\n\n    valuesByKey.each(function(values, key) {\n      setResult(result, key, apply(values, depth, createResult, setResult));\n    });\n\n    return result;\n  }\n\n  function entries(map, depth) {\n    if (++depth > keys.length) return map;\n    var array, sortKey = sortKeys[depth - 1];\n    if (rollup != null && depth >= keys.length) array = map.entries();\n    else array = [], map.each(function(v, k) { array.push({key: k, values: entries(v, depth)}); });\n    return sortKey != null ? array.sort(function(a, b) { return sortKey(a.key, b.key); }) : array;\n  }\n\n  return nest = {\n    object: function(array) { return apply(array, 0, createObject, setObject); },\n    map: function(array) { return apply(array, 0, createMap, setMap); },\n    entries: function(array) { return entries(apply(array, 0, createMap, setMap), 0); },\n    key: function(d) { keys.push(d); return nest; },\n    sortKeys: function(order) { sortKeys[keys.length - 1] = order; return nest; },\n    sortValues: function(order) { sortValues = order; return nest; },\n    rollup: function(f) { rollup = f; return nest; }\n  };\n};\n\nfunction createObject() {\n  return {};\n}\n\nfunction setObject(object, key, value) {\n  object[key] = value;\n}\n\nfunction createMap() {\n  return map$1();\n}\n\nfunction setMap(map, key, value) {\n  map.set(key, value);\n}\n\nfunction Set() {}\n\nvar proto = map$1.prototype;\n\nSet.prototype = set$2.prototype = {\n  constructor: Set,\n  has: proto.has,\n  add: function(value) {\n    value += \"\";\n    this[prefix + value] = value;\n    return this;\n  },\n  remove: proto.remove,\n  clear: proto.clear,\n  values: proto.keys,\n  size: proto.size,\n  empty: proto.empty,\n  each: proto.each\n};\n\nfunction set$2(object, f) {\n  var set = new Set;\n\n  // Copy constructor.\n  if (object instanceof Set) object.each(function(value) { set.add(value); });\n\n  // Otherwise, assume it’s an array.\n  else if (object) {\n    var i = -1, n = object.length;\n    if (f == null) while (++i < n) set.add(object[i]);\n    else while (++i < n) set.add(f(object[i], i, object));\n  }\n\n  return set;\n}\n\nvar keys = function(map) {\n  var keys = [];\n  for (var key in map) keys.push(key);\n  return keys;\n};\n\nvar values = function(map) {\n  var values = [];\n  for (var key in map) values.push(map[key]);\n  return values;\n};\n\nvar entries = function(map) {\n  var entries = [];\n  for (var key in map) entries.push({key: key, value: map[key]});\n  return entries;\n};\n\nfunction objectConverter(columns) {\n  return new Function(\"d\", \"return {\" + columns.map(function(name, i) {\n    return JSON.stringify(name) + \": d[\" + i + \"]\";\n  }).join(\",\") + \"}\");\n}\n\nfunction customConverter(columns, f) {\n  var object = objectConverter(columns);\n  return function(row, i) {\n    return f(object(row), i, columns);\n  };\n}\n\n// Compute unique columns in order of discovery.\nfunction inferColumns(rows) {\n  var columnSet = Object.create(null),\n      columns = [];\n\n  rows.forEach(function(row) {\n    for (var column in row) {\n      if (!(column in columnSet)) {\n        columns.push(columnSet[column] = column);\n      }\n    }\n  });\n\n  return columns;\n}\n\nvar dsv = function(delimiter) {\n  var reFormat = new RegExp(\"[\\\"\" + delimiter + \"\\n\\r]\"),\n      delimiterCode = delimiter.charCodeAt(0);\n\n  function parse(text, f) {\n    var convert, columns, rows = parseRows(text, function(row, i) {\n      if (convert) return convert(row, i - 1);\n      columns = row, convert = f ? customConverter(row, f) : objectConverter(row);\n    });\n    rows.columns = columns;\n    return rows;\n  }\n\n  function parseRows(text, f) {\n    var EOL = {}, // sentinel value for end-of-line\n        EOF = {}, // sentinel value for end-of-file\n        rows = [], // output rows\n        N = text.length,\n        I = 0, // current character index\n        n = 0, // the current line number\n        t, // the current token\n        eol; // is the current token followed by EOL?\n\n    function token() {\n      if (I >= N) return EOF; // special case: end of file\n      if (eol) return eol = false, EOL; // special case: end of line\n\n      // special case: quotes\n      var j = I, c;\n      if (text.charCodeAt(j) === 34) {\n        var i = j;\n        while (i++ < N) {\n          if (text.charCodeAt(i) === 34) {\n            if (text.charCodeAt(i + 1) !== 34) break;\n            ++i;\n          }\n        }\n        I = i + 2;\n        c = text.charCodeAt(i + 1);\n        if (c === 13) {\n          eol = true;\n          if (text.charCodeAt(i + 2) === 10) ++I;\n        } else if (c === 10) {\n          eol = true;\n        }\n        return text.slice(j + 1, i).replace(/\"\"/g, \"\\\"\");\n      }\n\n      // common case: find next delimiter or newline\n      while (I < N) {\n        var k = 1;\n        c = text.charCodeAt(I++);\n        if (c === 10) eol = true; // \\n\n        else if (c === 13) { eol = true; if (text.charCodeAt(I) === 10) ++I, ++k; } // \\r|\\r\\n\n        else if (c !== delimiterCode) continue;\n        return text.slice(j, I - k);\n      }\n\n      // special case: last token before EOF\n      return text.slice(j);\n    }\n\n    while ((t = token()) !== EOF) {\n      var a = [];\n      while (t !== EOL && t !== EOF) {\n        a.push(t);\n        t = token();\n      }\n      if (f && (a = f(a, n++)) == null) continue;\n      rows.push(a);\n    }\n\n    return rows;\n  }\n\n  function format(rows, columns) {\n    if (columns == null) columns = inferColumns(rows);\n    return [columns.map(formatValue).join(delimiter)].concat(rows.map(function(row) {\n      return columns.map(function(column) {\n        return formatValue(row[column]);\n      }).join(delimiter);\n    })).join(\"\\n\");\n  }\n\n  function formatRows(rows) {\n    return rows.map(formatRow).join(\"\\n\");\n  }\n\n  function formatRow(row) {\n    return row.map(formatValue).join(delimiter);\n  }\n\n  function formatValue(text) {\n    return text == null ? \"\"\n        : reFormat.test(text += \"\") ? \"\\\"\" + text.replace(/\\\"/g, \"\\\"\\\"\") + \"\\\"\"\n        : text;\n  }\n\n  return {\n    parse: parse,\n    parseRows: parseRows,\n    format: format,\n    formatRows: formatRows\n  };\n};\n\nvar csv = dsv(\",\");\n\nvar csvParse = csv.parse;\nvar csvParseRows = csv.parseRows;\nvar csvFormat = csv.format;\nvar csvFormatRows = csv.formatRows;\n\nvar tsv = dsv(\"\\t\");\n\nvar tsvParse = tsv.parse;\nvar tsvParseRows = tsv.parseRows;\nvar tsvFormat = tsv.format;\nvar tsvFormatRows = tsv.formatRows;\n\nvar center$1 = function(x, y) {\n  var nodes;\n\n  if (x == null) x = 0;\n  if (y == null) y = 0;\n\n  function force() {\n    var i,\n        n = nodes.length,\n        node,\n        sx = 0,\n        sy = 0;\n\n    for (i = 0; i < n; ++i) {\n      node = nodes[i], sx += node.x, sy += node.y;\n    }\n\n    for (sx = sx / n - x, sy = sy / n - y, i = 0; i < n; ++i) {\n      node = nodes[i], node.x -= sx, node.y -= sy;\n    }\n  }\n\n  force.initialize = function(_) {\n    nodes = _;\n  };\n\n  force.x = function(_) {\n    return arguments.length ? (x = +_, force) : x;\n  };\n\n  force.y = function(_) {\n    return arguments.length ? (y = +_, force) : y;\n  };\n\n  return force;\n};\n\nvar constant$6 = function(x) {\n  return function() {\n    return x;\n  };\n};\n\nvar jiggle = function() {\n  return (Math.random() - 0.5) * 1e-6;\n};\n\nvar tree_add = function(d) {\n  var x = +this._x.call(null, d),\n      y = +this._y.call(null, d);\n  return add(this.cover(x, y), x, y, d);\n};\n\nfunction add(tree, x, y, d) {\n  if (isNaN(x) || isNaN(y)) return tree; // ignore invalid points\n\n  var parent,\n      node = tree._root,\n      leaf = {data: d},\n      x0 = tree._x0,\n      y0 = tree._y0,\n      x1 = tree._x1,\n      y1 = tree._y1,\n      xm,\n      ym,\n      xp,\n      yp,\n      right,\n      bottom,\n      i,\n      j;\n\n  // If the tree is empty, initialize the root as a leaf.\n  if (!node) return tree._root = leaf, tree;\n\n  // Find the existing leaf for the new point, or add it.\n  while (node.length) {\n    if (right = x >= (xm = (x0 + x1) / 2)) x0 = xm; else x1 = xm;\n    if (bottom = y >= (ym = (y0 + y1) / 2)) y0 = ym; else y1 = ym;\n    if (parent = node, !(node = node[i = bottom << 1 | right])) return parent[i] = leaf, tree;\n  }\n\n  // Is the new point is exactly coincident with the existing point?\n  xp = +tree._x.call(null, node.data);\n  yp = +tree._y.call(null, node.data);\n  if (x === xp && y === yp) return leaf.next = node, parent ? parent[i] = leaf : tree._root = leaf, tree;\n\n  // Otherwise, split the leaf node until the old and new point are separated.\n  do {\n    parent = parent ? parent[i] = new Array(4) : tree._root = new Array(4);\n    if (right = x >= (xm = (x0 + x1) / 2)) x0 = xm; else x1 = xm;\n    if (bottom = y >= (ym = (y0 + y1) / 2)) y0 = ym; else y1 = ym;\n  } while ((i = bottom << 1 | right) === (j = (yp >= ym) << 1 | (xp >= xm)));\n  return parent[j] = node, parent[i] = leaf, tree;\n}\n\nfunction addAll(data) {\n  var d, i, n = data.length,\n      x,\n      y,\n      xz = new Array(n),\n      yz = new Array(n),\n      x0 = Infinity,\n      y0 = Infinity,\n      x1 = -Infinity,\n      y1 = -Infinity;\n\n  // Compute the points and their extent.\n  for (i = 0; i < n; ++i) {\n    if (isNaN(x = +this._x.call(null, d = data[i])) || isNaN(y = +this._y.call(null, d))) continue;\n    xz[i] = x;\n    yz[i] = y;\n    if (x < x0) x0 = x;\n    if (x > x1) x1 = x;\n    if (y < y0) y0 = y;\n    if (y > y1) y1 = y;\n  }\n\n  // If there were no (valid) points, inherit the existing extent.\n  if (x1 < x0) x0 = this._x0, x1 = this._x1;\n  if (y1 < y0) y0 = this._y0, y1 = this._y1;\n\n  // Expand the tree to cover the new points.\n  this.cover(x0, y0).cover(x1, y1);\n\n  // Add the new points.\n  for (i = 0; i < n; ++i) {\n    add(this, xz[i], yz[i], data[i]);\n  }\n\n  return this;\n}\n\nvar tree_cover = function(x, y) {\n  if (isNaN(x = +x) || isNaN(y = +y)) return this; // ignore invalid points\n\n  var x0 = this._x0,\n      y0 = this._y0,\n      x1 = this._x1,\n      y1 = this._y1;\n\n  // If the quadtree has no extent, initialize them.\n  // Integer extent are necessary so that if we later double the extent,\n  // the existing quadrant boundaries don’t change due to floating point error!\n  if (isNaN(x0)) {\n    x1 = (x0 = Math.floor(x)) + 1;\n    y1 = (y0 = Math.floor(y)) + 1;\n  }\n\n  // Otherwise, double repeatedly to cover.\n  else if (x0 > x || x > x1 || y0 > y || y > y1) {\n    var z = x1 - x0,\n        node = this._root,\n        parent,\n        i;\n\n    switch (i = (y < (y0 + y1) / 2) << 1 | (x < (x0 + x1) / 2)) {\n      case 0: {\n        do parent = new Array(4), parent[i] = node, node = parent;\n        while (z *= 2, x1 = x0 + z, y1 = y0 + z, x > x1 || y > y1);\n        break;\n      }\n      case 1: {\n        do parent = new Array(4), parent[i] = node, node = parent;\n        while (z *= 2, x0 = x1 - z, y1 = y0 + z, x0 > x || y > y1);\n        break;\n      }\n      case 2: {\n        do parent = new Array(4), parent[i] = node, node = parent;\n        while (z *= 2, x1 = x0 + z, y0 = y1 - z, x > x1 || y0 > y);\n        break;\n      }\n      case 3: {\n        do parent = new Array(4), parent[i] = node, node = parent;\n        while (z *= 2, x0 = x1 - z, y0 = y1 - z, x0 > x || y0 > y);\n        break;\n      }\n    }\n\n    if (this._root && this._root.length) this._root = node;\n  }\n\n  // If the quadtree covers the point already, just return.\n  else return this;\n\n  this._x0 = x0;\n  this._y0 = y0;\n  this._x1 = x1;\n  this._y1 = y1;\n  return this;\n};\n\nvar tree_data = function() {\n  var data = [];\n  this.visit(function(node) {\n    if (!node.length) do data.push(node.data); while (node = node.next)\n  });\n  return data;\n};\n\nvar tree_extent = function(_) {\n  return arguments.length\n      ? this.cover(+_[0][0], +_[0][1]).cover(+_[1][0], +_[1][1])\n      : isNaN(this._x0) ? undefined : [[this._x0, this._y0], [this._x1, this._y1]];\n};\n\nvar Quad = function(node, x0, y0, x1, y1) {\n  this.node = node;\n  this.x0 = x0;\n  this.y0 = y0;\n  this.x1 = x1;\n  this.y1 = y1;\n};\n\nvar tree_find = function(x, y, radius) {\n  var data,\n      x0 = this._x0,\n      y0 = this._y0,\n      x1,\n      y1,\n      x2,\n      y2,\n      x3 = this._x1,\n      y3 = this._y1,\n      quads = [],\n      node = this._root,\n      q,\n      i;\n\n  if (node) quads.push(new Quad(node, x0, y0, x3, y3));\n  if (radius == null) radius = Infinity;\n  else {\n    x0 = x - radius, y0 = y - radius;\n    x3 = x + radius, y3 = y + radius;\n    radius *= radius;\n  }\n\n  while (q = quads.pop()) {\n\n    // Stop searching if this quadrant can’t contain a closer node.\n    if (!(node = q.node)\n        || (x1 = q.x0) > x3\n        || (y1 = q.y0) > y3\n        || (x2 = q.x1) < x0\n        || (y2 = q.y1) < y0) continue;\n\n    // Bisect the current quadrant.\n    if (node.length) {\n      var xm = (x1 + x2) / 2,\n          ym = (y1 + y2) / 2;\n\n      quads.push(\n        new Quad(node[3], xm, ym, x2, y2),\n        new Quad(node[2], x1, ym, xm, y2),\n        new Quad(node[1], xm, y1, x2, ym),\n        new Quad(node[0], x1, y1, xm, ym)\n      );\n\n      // Visit the closest quadrant first.\n      if (i = (y >= ym) << 1 | (x >= xm)) {\n        q = quads[quads.length - 1];\n        quads[quads.length - 1] = quads[quads.length - 1 - i];\n        quads[quads.length - 1 - i] = q;\n      }\n    }\n\n    // Visit this point. (Visiting coincident points isn’t necessary!)\n    else {\n      var dx = x - +this._x.call(null, node.data),\n          dy = y - +this._y.call(null, node.data),\n          d2 = dx * dx + dy * dy;\n      if (d2 < radius) {\n        var d = Math.sqrt(radius = d2);\n        x0 = x - d, y0 = y - d;\n        x3 = x + d, y3 = y + d;\n        data = node.data;\n      }\n    }\n  }\n\n  return data;\n};\n\nvar tree_remove = function(d) {\n  if (isNaN(x = +this._x.call(null, d)) || isNaN(y = +this._y.call(null, d))) return this; // ignore invalid points\n\n  var parent,\n      node = this._root,\n      retainer,\n      previous,\n      next,\n      x0 = this._x0,\n      y0 = this._y0,\n      x1 = this._x1,\n      y1 = this._y1,\n      x,\n      y,\n      xm,\n      ym,\n      right,\n      bottom,\n      i,\n      j;\n\n  // If the tree is empty, initialize the root as a leaf.\n  if (!node) return this;\n\n  // Find the leaf node for the point.\n  // While descending, also retain the deepest parent with a non-removed sibling.\n  if (node.length) while (true) {\n    if (right = x >= (xm = (x0 + x1) / 2)) x0 = xm; else x1 = xm;\n    if (bottom = y >= (ym = (y0 + y1) / 2)) y0 = ym; else y1 = ym;\n    if (!(parent = node, node = node[i = bottom << 1 | right])) return this;\n    if (!node.length) break;\n    if (parent[(i + 1) & 3] || parent[(i + 2) & 3] || parent[(i + 3) & 3]) retainer = parent, j = i;\n  }\n\n  // Find the point to remove.\n  while (node.data !== d) if (!(previous = node, node = node.next)) return this;\n  if (next = node.next) delete node.next;\n\n  // If there are multiple coincident points, remove just the point.\n  if (previous) return (next ? previous.next = next : delete previous.next), this;\n\n  // If this is the root point, remove it.\n  if (!parent) return this._root = next, this;\n\n  // Remove this leaf.\n  next ? parent[i] = next : delete parent[i];\n\n  // If the parent now contains exactly one leaf, collapse superfluous parents.\n  if ((node = parent[0] || parent[1] || parent[2] || parent[3])\n      && node === (parent[3] || parent[2] || parent[1] || parent[0])\n      && !node.length) {\n    if (retainer) retainer[j] = node;\n    else this._root = node;\n  }\n\n  return this;\n};\n\nfunction removeAll(data) {\n  for (var i = 0, n = data.length; i < n; ++i) this.remove(data[i]);\n  return this;\n}\n\nvar tree_root = function() {\n  return this._root;\n};\n\nvar tree_size = function() {\n  var size = 0;\n  this.visit(function(node) {\n    if (!node.length) do ++size; while (node = node.next)\n  });\n  return size;\n};\n\nvar tree_visit = function(callback) {\n  var quads = [], q, node = this._root, child, x0, y0, x1, y1;\n  if (node) quads.push(new Quad(node, this._x0, this._y0, this._x1, this._y1));\n  while (q = quads.pop()) {\n    if (!callback(node = q.node, x0 = q.x0, y0 = q.y0, x1 = q.x1, y1 = q.y1) && node.length) {\n      var xm = (x0 + x1) / 2, ym = (y0 + y1) / 2;\n      if (child = node[3]) quads.push(new Quad(child, xm, ym, x1, y1));\n      if (child = node[2]) quads.push(new Quad(child, x0, ym, xm, y1));\n      if (child = node[1]) quads.push(new Quad(child, xm, y0, x1, ym));\n      if (child = node[0]) quads.push(new Quad(child, x0, y0, xm, ym));\n    }\n  }\n  return this;\n};\n\nvar tree_visitAfter = function(callback) {\n  var quads = [], next = [], q;\n  if (this._root) quads.push(new Quad(this._root, this._x0, this._y0, this._x1, this._y1));\n  while (q = quads.pop()) {\n    var node = q.node;\n    if (node.length) {\n      var child, x0 = q.x0, y0 = q.y0, x1 = q.x1, y1 = q.y1, xm = (x0 + x1) / 2, ym = (y0 + y1) / 2;\n      if (child = node[0]) quads.push(new Quad(child, x0, y0, xm, ym));\n      if (child = node[1]) quads.push(new Quad(child, xm, y0, x1, ym));\n      if (child = node[2]) quads.push(new Quad(child, x0, ym, xm, y1));\n      if (child = node[3]) quads.push(new Quad(child, xm, ym, x1, y1));\n    }\n    next.push(q);\n  }\n  while (q = next.pop()) {\n    callback(q.node, q.x0, q.y0, q.x1, q.y1);\n  }\n  return this;\n};\n\nfunction defaultX(d) {\n  return d[0];\n}\n\nvar tree_x = function(_) {\n  return arguments.length ? (this._x = _, this) : this._x;\n};\n\nfunction defaultY(d) {\n  return d[1];\n}\n\nvar tree_y = function(_) {\n  return arguments.length ? (this._y = _, this) : this._y;\n};\n\nfunction quadtree(nodes, x, y) {\n  var tree = new Quadtree(x == null ? defaultX : x, y == null ? defaultY : y, NaN, NaN, NaN, NaN);\n  return nodes == null ? tree : tree.addAll(nodes);\n}\n\nfunction Quadtree(x, y, x0, y0, x1, y1) {\n  this._x = x;\n  this._y = y;\n  this._x0 = x0;\n  this._y0 = y0;\n  this._x1 = x1;\n  this._y1 = y1;\n  this._root = undefined;\n}\n\nfunction leaf_copy(leaf) {\n  var copy = {data: leaf.data}, next = copy;\n  while (leaf = leaf.next) next = next.next = {data: leaf.data};\n  return copy;\n}\n\nvar treeProto = quadtree.prototype = Quadtree.prototype;\n\ntreeProto.copy = function() {\n  var copy = new Quadtree(this._x, this._y, this._x0, this._y0, this._x1, this._y1),\n      node = this._root,\n      nodes,\n      child;\n\n  if (!node) return copy;\n\n  if (!node.length) return copy._root = leaf_copy(node), copy;\n\n  nodes = [{source: node, target: copy._root = new Array(4)}];\n  while (node = nodes.pop()) {\n    for (var i = 0; i < 4; ++i) {\n      if (child = node.source[i]) {\n        if (child.length) nodes.push({source: child, target: node.target[i] = new Array(4)});\n        else node.target[i] = leaf_copy(child);\n      }\n    }\n  }\n\n  return copy;\n};\n\ntreeProto.add = tree_add;\ntreeProto.addAll = addAll;\ntreeProto.cover = tree_cover;\ntreeProto.data = tree_data;\ntreeProto.extent = tree_extent;\ntreeProto.find = tree_find;\ntreeProto.remove = tree_remove;\ntreeProto.removeAll = removeAll;\ntreeProto.root = tree_root;\ntreeProto.size = tree_size;\ntreeProto.visit = tree_visit;\ntreeProto.visitAfter = tree_visitAfter;\ntreeProto.x = tree_x;\ntreeProto.y = tree_y;\n\nfunction x(d) {\n  return d.x + d.vx;\n}\n\nfunction y(d) {\n  return d.y + d.vy;\n}\n\nvar collide = function(radius) {\n  var nodes,\n      radii,\n      strength = 1,\n      iterations = 1;\n\n  if (typeof radius !== \"function\") radius = constant$6(radius == null ? 1 : +radius);\n\n  function force() {\n    var i, n = nodes.length,\n        tree,\n        node,\n        xi,\n        yi,\n        ri,\n        ri2;\n\n    for (var k = 0; k < iterations; ++k) {\n      tree = quadtree(nodes, x, y).visitAfter(prepare);\n      for (i = 0; i < n; ++i) {\n        node = nodes[i];\n        ri = radii[node.index], ri2 = ri * ri;\n        xi = node.x + node.vx;\n        yi = node.y + node.vy;\n        tree.visit(apply);\n      }\n    }\n\n    function apply(quad, x0, y0, x1, y1) {\n      var data = quad.data, rj = quad.r, r = ri + rj;\n      if (data) {\n        if (data.index > node.index) {\n          var x = xi - data.x - data.vx,\n              y = yi - data.y - data.vy,\n              l = x * x + y * y;\n          if (l < r * r) {\n            if (x === 0) x = jiggle(), l += x * x;\n            if (y === 0) y = jiggle(), l += y * y;\n            l = (r - (l = Math.sqrt(l))) / l * strength;\n            node.vx += (x *= l) * (r = (rj *= rj) / (ri2 + rj));\n            node.vy += (y *= l) * r;\n            data.vx -= x * (r = 1 - r);\n            data.vy -= y * r;\n          }\n        }\n        return;\n      }\n      return x0 > xi + r || x1 < xi - r || y0 > yi + r || y1 < yi - r;\n    }\n  }\n\n  function prepare(quad) {\n    if (quad.data) return quad.r = radii[quad.data.index];\n    for (var i = quad.r = 0; i < 4; ++i) {\n      if (quad[i] && quad[i].r > quad.r) {\n        quad.r = quad[i].r;\n      }\n    }\n  }\n\n  function initialize() {\n    if (!nodes) return;\n    var i, n = nodes.length, node;\n    radii = new Array(n);\n    for (i = 0; i < n; ++i) node = nodes[i], radii[node.index] = +radius(node, i, nodes);\n  }\n\n  force.initialize = function(_) {\n    nodes = _;\n    initialize();\n  };\n\n  force.iterations = function(_) {\n    return arguments.length ? (iterations = +_, force) : iterations;\n  };\n\n  force.strength = function(_) {\n    return arguments.length ? (strength = +_, force) : strength;\n  };\n\n  force.radius = function(_) {\n    return arguments.length ? (radius = typeof _ === \"function\" ? _ : constant$6(+_), initialize(), force) : radius;\n  };\n\n  return force;\n};\n\nfunction index(d) {\n  return d.index;\n}\n\nfunction find(nodeById, nodeId) {\n  var node = nodeById.get(nodeId);\n  if (!node) throw new Error(\"missing: \" + nodeId);\n  return node;\n}\n\nvar link = function(links) {\n  var id = index,\n      strength = defaultStrength,\n      strengths,\n      distance = constant$6(30),\n      distances,\n      nodes,\n      count,\n      bias,\n      iterations = 1;\n\n  if (links == null) links = [];\n\n  function defaultStrength(link) {\n    return 1 / Math.min(count[link.source.index], count[link.target.index]);\n  }\n\n  function force(alpha) {\n    for (var k = 0, n = links.length; k < iterations; ++k) {\n      for (var i = 0, link, source, target, x, y, l, b; i < n; ++i) {\n        link = links[i], source = link.source, target = link.target;\n        x = target.x + target.vx - source.x - source.vx || jiggle();\n        y = target.y + target.vy - source.y - source.vy || jiggle();\n        l = Math.sqrt(x * x + y * y);\n        l = (l - distances[i]) / l * alpha * strengths[i];\n        x *= l, y *= l;\n        target.vx -= x * (b = bias[i]);\n        target.vy -= y * b;\n        source.vx += x * (b = 1 - b);\n        source.vy += y * b;\n      }\n    }\n  }\n\n  function initialize() {\n    if (!nodes) return;\n\n    var i,\n        n = nodes.length,\n        m = links.length,\n        nodeById = map$1(nodes, id),\n        link;\n\n    for (i = 0, count = new Array(n); i < m; ++i) {\n      link = links[i], link.index = i;\n      if (typeof link.source !== \"object\") link.source = find(nodeById, link.source);\n      if (typeof link.target !== \"object\") link.target = find(nodeById, link.target);\n      count[link.source.index] = (count[link.source.index] || 0) + 1;\n      count[link.target.index] = (count[link.target.index] || 0) + 1;\n    }\n\n    for (i = 0, bias = new Array(m); i < m; ++i) {\n      link = links[i], bias[i] = count[link.source.index] / (count[link.source.index] + count[link.target.index]);\n    }\n\n    strengths = new Array(m), initializeStrength();\n    distances = new Array(m), initializeDistance();\n  }\n\n  function initializeStrength() {\n    if (!nodes) return;\n\n    for (var i = 0, n = links.length; i < n; ++i) {\n      strengths[i] = +strength(links[i], i, links);\n    }\n  }\n\n  function initializeDistance() {\n    if (!nodes) return;\n\n    for (var i = 0, n = links.length; i < n; ++i) {\n      distances[i] = +distance(links[i], i, links);\n    }\n  }\n\n  force.initialize = function(_) {\n    nodes = _;\n    initialize();\n  };\n\n  force.links = function(_) {\n    return arguments.length ? (links = _, initialize(), force) : links;\n  };\n\n  force.id = function(_) {\n    return arguments.length ? (id = _, force) : id;\n  };\n\n  force.iterations = function(_) {\n    return arguments.length ? (iterations = +_, force) : iterations;\n  };\n\n  force.strength = function(_) {\n    return arguments.length ? (strength = typeof _ === \"function\" ? _ : constant$6(+_), initializeStrength(), force) : strength;\n  };\n\n  force.distance = function(_) {\n    return arguments.length ? (distance = typeof _ === \"function\" ? _ : constant$6(+_), initializeDistance(), force) : distance;\n  };\n\n  return force;\n};\n\nfunction x$1(d) {\n  return d.x;\n}\n\nfunction y$1(d) {\n  return d.y;\n}\n\nvar initialRadius = 10;\nvar initialAngle = Math.PI * (3 - Math.sqrt(5));\n\nvar simulation = function(nodes) {\n  var simulation,\n      alpha = 1,\n      alphaMin = 0.001,\n      alphaDecay = 1 - Math.pow(alphaMin, 1 / 300),\n      alphaTarget = 0,\n      velocityDecay = 0.6,\n      forces = map$1(),\n      stepper = timer(step),\n      event = dispatch(\"tick\", \"end\");\n\n  if (nodes == null) nodes = [];\n\n  function step() {\n    tick();\n    event.call(\"tick\", simulation);\n    if (alpha < alphaMin) {\n      stepper.stop();\n      event.call(\"end\", simulation);\n    }\n  }\n\n  function tick() {\n    var i, n = nodes.length, node;\n\n    alpha += (alphaTarget - alpha) * alphaDecay;\n\n    forces.each(function(force) {\n      force(alpha);\n    });\n\n    for (i = 0; i < n; ++i) {\n      node = nodes[i];\n      if (node.fx == null) node.x += node.vx *= velocityDecay;\n      else node.x = node.fx, node.vx = 0;\n      if (node.fy == null) node.y += node.vy *= velocityDecay;\n      else node.y = node.fy, node.vy = 0;\n    }\n  }\n\n  function initializeNodes() {\n    for (var i = 0, n = nodes.length, node; i < n; ++i) {\n      node = nodes[i], node.index = i;\n      if (isNaN(node.x) || isNaN(node.y)) {\n        var radius = initialRadius * Math.sqrt(i), angle = i * initialAngle;\n        node.x = radius * Math.cos(angle);\n        node.y = radius * Math.sin(angle);\n      }\n      if (isNaN(node.vx) || isNaN(node.vy)) {\n        node.vx = node.vy = 0;\n      }\n    }\n  }\n\n  function initializeForce(force) {\n    if (force.initialize) force.initialize(nodes);\n    return force;\n  }\n\n  initializeNodes();\n\n  return simulation = {\n    tick: tick,\n\n    restart: function() {\n      return stepper.restart(step), simulation;\n    },\n\n    stop: function() {\n      return stepper.stop(), simulation;\n    },\n\n    nodes: function(_) {\n      return arguments.length ? (nodes = _, initializeNodes(), forces.each(initializeForce), simulation) : nodes;\n    },\n\n    alpha: function(_) {\n      return arguments.length ? (alpha = +_, simulation) : alpha;\n    },\n\n    alphaMin: function(_) {\n      return arguments.length ? (alphaMin = +_, simulation) : alphaMin;\n    },\n\n    alphaDecay: function(_) {\n      return arguments.length ? (alphaDecay = +_, simulation) : +alphaDecay;\n    },\n\n    alphaTarget: function(_) {\n      return arguments.length ? (alphaTarget = +_, simulation) : alphaTarget;\n    },\n\n    velocityDecay: function(_) {\n      return arguments.length ? (velocityDecay = 1 - _, simulation) : 1 - velocityDecay;\n    },\n\n    force: function(name, _) {\n      return arguments.length > 1 ? ((_ == null ? forces.remove(name) : forces.set(name, initializeForce(_))), simulation) : forces.get(name);\n    },\n\n    find: function(x, y, radius) {\n      var i = 0,\n          n = nodes.length,\n          dx,\n          dy,\n          d2,\n          node,\n          closest;\n\n      if (radius == null) radius = Infinity;\n      else radius *= radius;\n\n      for (i = 0; i < n; ++i) {\n        node = nodes[i];\n        dx = x - node.x;\n        dy = y - node.y;\n        d2 = dx * dx + dy * dy;\n        if (d2 < radius) closest = node, radius = d2;\n      }\n\n      return closest;\n    },\n\n    on: function(name, _) {\n      return arguments.length > 1 ? (event.on(name, _), simulation) : event.on(name);\n    }\n  };\n};\n\nvar manyBody = function() {\n  var nodes,\n      node,\n      alpha,\n      strength = constant$6(-30),\n      strengths,\n      distanceMin2 = 1,\n      distanceMax2 = Infinity,\n      theta2 = 0.81;\n\n  function force(_) {\n    var i, n = nodes.length, tree = quadtree(nodes, x$1, y$1).visitAfter(accumulate);\n    for (alpha = _, i = 0; i < n; ++i) node = nodes[i], tree.visit(apply);\n  }\n\n  function initialize() {\n    if (!nodes) return;\n    var i, n = nodes.length, node;\n    strengths = new Array(n);\n    for (i = 0; i < n; ++i) node = nodes[i], strengths[node.index] = +strength(node, i, nodes);\n  }\n\n  function accumulate(quad) {\n    var strength = 0, q, c, x$$1, y$$1, i;\n\n    // For internal nodes, accumulate forces from child quadrants.\n    if (quad.length) {\n      for (x$$1 = y$$1 = i = 0; i < 4; ++i) {\n        if ((q = quad[i]) && (c = q.value)) {\n          strength += c, x$$1 += c * q.x, y$$1 += c * q.y;\n        }\n      }\n      quad.x = x$$1 / strength;\n      quad.y = y$$1 / strength;\n    }\n\n    // For leaf nodes, accumulate forces from coincident quadrants.\n    else {\n      q = quad;\n      q.x = q.data.x;\n      q.y = q.data.y;\n      do strength += strengths[q.data.index];\n      while (q = q.next);\n    }\n\n    quad.value = strength;\n  }\n\n  function apply(quad, x1, _, x2) {\n    if (!quad.value) return true;\n\n    var x$$1 = quad.x - node.x,\n        y$$1 = quad.y - node.y,\n        w = x2 - x1,\n        l = x$$1 * x$$1 + y$$1 * y$$1;\n\n    // Apply the Barnes-Hut approximation if possible.\n    // Limit forces for very close nodes; randomize direction if coincident.\n    if (w * w / theta2 < l) {\n      if (l < distanceMax2) {\n        if (x$$1 === 0) x$$1 = jiggle(), l += x$$1 * x$$1;\n        if (y$$1 === 0) y$$1 = jiggle(), l += y$$1 * y$$1;\n        if (l < distanceMin2) l = Math.sqrt(distanceMin2 * l);\n        node.vx += x$$1 * quad.value * alpha / l;\n        node.vy += y$$1 * quad.value * alpha / l;\n      }\n      return true;\n    }\n\n    // Otherwise, process points directly.\n    else if (quad.length || l >= distanceMax2) return;\n\n    // Limit forces for very close nodes; randomize direction if coincident.\n    if (quad.data !== node || quad.next) {\n      if (x$$1 === 0) x$$1 = jiggle(), l += x$$1 * x$$1;\n      if (y$$1 === 0) y$$1 = jiggle(), l += y$$1 * y$$1;\n      if (l < distanceMin2) l = Math.sqrt(distanceMin2 * l);\n    }\n\n    do if (quad.data !== node) {\n      w = strengths[quad.data.index] * alpha / l;\n      node.vx += x$$1 * w;\n      node.vy += y$$1 * w;\n    } while (quad = quad.next);\n  }\n\n  force.initialize = function(_) {\n    nodes = _;\n    initialize();\n  };\n\n  force.strength = function(_) {\n    return arguments.length ? (strength = typeof _ === \"function\" ? _ : constant$6(+_), initialize(), force) : strength;\n  };\n\n  force.distanceMin = function(_) {\n    return arguments.length ? (distanceMin2 = _ * _, force) : Math.sqrt(distanceMin2);\n  };\n\n  force.distanceMax = function(_) {\n    return arguments.length ? (distanceMax2 = _ * _, force) : Math.sqrt(distanceMax2);\n  };\n\n  force.theta = function(_) {\n    return arguments.length ? (theta2 = _ * _, force) : Math.sqrt(theta2);\n  };\n\n  return force;\n};\n\nvar x$2 = function(x) {\n  var strength = constant$6(0.1),\n      nodes,\n      strengths,\n      xz;\n\n  if (typeof x !== \"function\") x = constant$6(x == null ? 0 : +x);\n\n  function force(alpha) {\n    for (var i = 0, n = nodes.length, node; i < n; ++i) {\n      node = nodes[i], node.vx += (xz[i] - node.x) * strengths[i] * alpha;\n    }\n  }\n\n  function initialize() {\n    if (!nodes) return;\n    var i, n = nodes.length;\n    strengths = new Array(n);\n    xz = new Array(n);\n    for (i = 0; i < n; ++i) {\n      strengths[i] = isNaN(xz[i] = +x(nodes[i], i, nodes)) ? 0 : +strength(nodes[i], i, nodes);\n    }\n  }\n\n  force.initialize = function(_) {\n    nodes = _;\n    initialize();\n  };\n\n  force.strength = function(_) {\n    return arguments.length ? (strength = typeof _ === \"function\" ? _ : constant$6(+_), initialize(), force) : strength;\n  };\n\n  force.x = function(_) {\n    return arguments.length ? (x = typeof _ === \"function\" ? _ : constant$6(+_), initialize(), force) : x;\n  };\n\n  return force;\n};\n\nvar y$2 = function(y) {\n  var strength = constant$6(0.1),\n      nodes,\n      strengths,\n      yz;\n\n  if (typeof y !== \"function\") y = constant$6(y == null ? 0 : +y);\n\n  function force(alpha) {\n    for (var i = 0, n = nodes.length, node; i < n; ++i) {\n      node = nodes[i], node.vy += (yz[i] - node.y) * strengths[i] * alpha;\n    }\n  }\n\n  function initialize() {\n    if (!nodes) return;\n    var i, n = nodes.length;\n    strengths = new Array(n);\n    yz = new Array(n);\n    for (i = 0; i < n; ++i) {\n      strengths[i] = isNaN(yz[i] = +y(nodes[i], i, nodes)) ? 0 : +strength(nodes[i], i, nodes);\n    }\n  }\n\n  force.initialize = function(_) {\n    nodes = _;\n    initialize();\n  };\n\n  force.strength = function(_) {\n    return arguments.length ? (strength = typeof _ === \"function\" ? _ : constant$6(+_), initialize(), force) : strength;\n  };\n\n  force.y = function(_) {\n    return arguments.length ? (y = typeof _ === \"function\" ? _ : constant$6(+_), initialize(), force) : y;\n  };\n\n  return force;\n};\n\n// Computes the decimal coefficient and exponent of the specified number x with\n// significant digits p, where x is positive and p is in [1, 21] or undefined.\n// For example, formatDecimal(1.23) returns [\"123\", 0].\nvar formatDecimal = function(x, p) {\n  if ((i = (x = p ? x.toExponential(p - 1) : x.toExponential()).indexOf(\"e\")) < 0) return null; // NaN, ±Infinity\n  var i, coefficient = x.slice(0, i);\n\n  // The string returned by toExponential either has the form \\d\\.\\d+e[-+]\\d+\n  // (e.g., 1.2e+3) or the form \\de[-+]\\d+ (e.g., 1e+3).\n  return [\n    coefficient.length > 1 ? coefficient[0] + coefficient.slice(2) : coefficient,\n    +x.slice(i + 1)\n  ];\n};\n\nvar exponent$1 = function(x) {\n  return x = formatDecimal(Math.abs(x)), x ? x[1] : NaN;\n};\n\nvar formatGroup = function(grouping, thousands) {\n  return function(value, width) {\n    var i = value.length,\n        t = [],\n        j = 0,\n        g = grouping[0],\n        length = 0;\n\n    while (i > 0 && g > 0) {\n      if (length + g + 1 > width) g = Math.max(1, width - length);\n      t.push(value.substring(i -= g, i + g));\n      if ((length += g + 1) > width) break;\n      g = grouping[j = (j + 1) % grouping.length];\n    }\n\n    return t.reverse().join(thousands);\n  };\n};\n\nvar formatNumerals = function(numerals) {\n  return function(value) {\n    return value.replace(/[0-9]/g, function(i) {\n      return numerals[+i];\n    });\n  };\n};\n\nvar formatDefault = function(x, p) {\n  x = x.toPrecision(p);\n\n  out: for (var n = x.length, i = 1, i0 = -1, i1; i < n; ++i) {\n    switch (x[i]) {\n      case \".\": i0 = i1 = i; break;\n      case \"0\": if (i0 === 0) i0 = i; i1 = i; break;\n      case \"e\": break out;\n      default: if (i0 > 0) i0 = 0; break;\n    }\n  }\n\n  return i0 > 0 ? x.slice(0, i0) + x.slice(i1 + 1) : x;\n};\n\nvar prefixExponent;\n\nvar formatPrefixAuto = function(x, p) {\n  var d = formatDecimal(x, p);\n  if (!d) return x + \"\";\n  var coefficient = d[0],\n      exponent = d[1],\n      i = exponent - (prefixExponent = Math.max(-8, Math.min(8, Math.floor(exponent / 3))) * 3) + 1,\n      n = coefficient.length;\n  return i === n ? coefficient\n      : i > n ? coefficient + new Array(i - n + 1).join(\"0\")\n      : i > 0 ? coefficient.slice(0, i) + \".\" + coefficient.slice(i)\n      : \"0.\" + new Array(1 - i).join(\"0\") + formatDecimal(x, Math.max(0, p + i - 1))[0]; // less than 1y!\n};\n\nvar formatRounded = function(x, p) {\n  var d = formatDecimal(x, p);\n  if (!d) return x + \"\";\n  var coefficient = d[0],\n      exponent = d[1];\n  return exponent < 0 ? \"0.\" + new Array(-exponent).join(\"0\") + coefficient\n      : coefficient.length > exponent + 1 ? coefficient.slice(0, exponent + 1) + \".\" + coefficient.slice(exponent + 1)\n      : coefficient + new Array(exponent - coefficient.length + 2).join(\"0\");\n};\n\nvar formatTypes = {\n  \"\": formatDefault,\n  \"%\": function(x, p) { return (x * 100).toFixed(p); },\n  \"b\": function(x) { return Math.round(x).toString(2); },\n  \"c\": function(x) { return x + \"\"; },\n  \"d\": function(x) { return Math.round(x).toString(10); },\n  \"e\": function(x, p) { return x.toExponential(p); },\n  \"f\": function(x, p) { return x.toFixed(p); },\n  \"g\": function(x, p) { return x.toPrecision(p); },\n  \"o\": function(x) { return Math.round(x).toString(8); },\n  \"p\": function(x, p) { return formatRounded(x * 100, p); },\n  \"r\": formatRounded,\n  \"s\": formatPrefixAuto,\n  \"X\": function(x) { return Math.round(x).toString(16).toUpperCase(); },\n  \"x\": function(x) { return Math.round(x).toString(16); }\n};\n\n// [[fill]align][sign][symbol][0][width][,][.precision][type]\nvar re = /^(?:(.)?([<>=^]))?([+\\-\\( ])?([$#])?(0)?(\\d+)?(,)?(\\.\\d+)?([a-z%])?$/i;\n\nfunction formatSpecifier(specifier) {\n  return new FormatSpecifier(specifier);\n}\n\nformatSpecifier.prototype = FormatSpecifier.prototype; // instanceof\n\nfunction FormatSpecifier(specifier) {\n  if (!(match = re.exec(specifier))) throw new Error(\"invalid format: \" + specifier);\n\n  var match,\n      fill = match[1] || \" \",\n      align = match[2] || \">\",\n      sign = match[3] || \"-\",\n      symbol = match[4] || \"\",\n      zero = !!match[5],\n      width = match[6] && +match[6],\n      comma = !!match[7],\n      precision = match[8] && +match[8].slice(1),\n      type = match[9] || \"\";\n\n  // The \"n\" type is an alias for \",g\".\n  if (type === \"n\") comma = true, type = \"g\";\n\n  // Map invalid types to the default format.\n  else if (!formatTypes[type]) type = \"\";\n\n  // If zero fill is specified, padding goes after sign and before digits.\n  if (zero || (fill === \"0\" && align === \"=\")) zero = true, fill = \"0\", align = \"=\";\n\n  this.fill = fill;\n  this.align = align;\n  this.sign = sign;\n  this.symbol = symbol;\n  this.zero = zero;\n  this.width = width;\n  this.comma = comma;\n  this.precision = precision;\n  this.type = type;\n}\n\nFormatSpecifier.prototype.toString = function() {\n  return this.fill\n      + this.align\n      + this.sign\n      + this.symbol\n      + (this.zero ? \"0\" : \"\")\n      + (this.width == null ? \"\" : Math.max(1, this.width | 0))\n      + (this.comma ? \",\" : \"\")\n      + (this.precision == null ? \"\" : \".\" + Math.max(0, this.precision | 0))\n      + this.type;\n};\n\nvar identity$3 = function(x) {\n  return x;\n};\n\nvar prefixes = [\"y\",\"z\",\"a\",\"f\",\"p\",\"n\",\"\\xB5\",\"m\",\"\",\"k\",\"M\",\"G\",\"T\",\"P\",\"E\",\"Z\",\"Y\"];\n\nvar formatLocale = function(locale) {\n  var group = locale.grouping && locale.thousands ? formatGroup(locale.grouping, locale.thousands) : identity$3,\n      currency = locale.currency,\n      decimal = locale.decimal,\n      numerals = locale.numerals ? formatNumerals(locale.numerals) : identity$3,\n      percent = locale.percent || \"%\";\n\n  function newFormat(specifier) {\n    specifier = formatSpecifier(specifier);\n\n    var fill = specifier.fill,\n        align = specifier.align,\n        sign = specifier.sign,\n        symbol = specifier.symbol,\n        zero = specifier.zero,\n        width = specifier.width,\n        comma = specifier.comma,\n        precision = specifier.precision,\n        type = specifier.type;\n\n    // Compute the prefix and suffix.\n    // For SI-prefix, the suffix is lazily computed.\n    var prefix = symbol === \"$\" ? currency[0] : symbol === \"#\" && /[boxX]/.test(type) ? \"0\" + type.toLowerCase() : \"\",\n        suffix = symbol === \"$\" ? currency[1] : /[%p]/.test(type) ? percent : \"\";\n\n    // What format function should we use?\n    // Is this an integer type?\n    // Can this type generate exponential notation?\n    var formatType = formatTypes[type],\n        maybeSuffix = !type || /[defgprs%]/.test(type);\n\n    // Set the default precision if not specified,\n    // or clamp the specified precision to the supported range.\n    // For significant precision, it must be in [1, 21].\n    // For fixed precision, it must be in [0, 20].\n    precision = precision == null ? (type ? 6 : 12)\n        : /[gprs]/.test(type) ? Math.max(1, Math.min(21, precision))\n        : Math.max(0, Math.min(20, precision));\n\n    function format(value) {\n      var valuePrefix = prefix,\n          valueSuffix = suffix,\n          i, n, c;\n\n      if (type === \"c\") {\n        valueSuffix = formatType(value) + valueSuffix;\n        value = \"\";\n      } else {\n        value = +value;\n\n        // Perform the initial formatting.\n        var valueNegative = value < 0;\n        value = formatType(Math.abs(value), precision);\n\n        // If a negative value rounds to zero during formatting, treat as positive.\n        if (valueNegative && +value === 0) valueNegative = false;\n\n        // Compute the prefix and suffix.\n        valuePrefix = (valueNegative ? (sign === \"(\" ? sign : \"-\") : sign === \"-\" || sign === \"(\" ? \"\" : sign) + valuePrefix;\n        valueSuffix = valueSuffix + (type === \"s\" ? prefixes[8 + prefixExponent / 3] : \"\") + (valueNegative && sign === \"(\" ? \")\" : \"\");\n\n        // Break the formatted value into the integer “value” part that can be\n        // grouped, and fractional or exponential “suffix” part that is not.\n        if (maybeSuffix) {\n          i = -1, n = value.length;\n          while (++i < n) {\n            if (c = value.charCodeAt(i), 48 > c || c > 57) {\n              valueSuffix = (c === 46 ? decimal + value.slice(i + 1) : value.slice(i)) + valueSuffix;\n              value = value.slice(0, i);\n              break;\n            }\n          }\n        }\n      }\n\n      // If the fill character is not \"0\", grouping is applied before padding.\n      if (comma && !zero) value = group(value, Infinity);\n\n      // Compute the padding.\n      var length = valuePrefix.length + value.length + valueSuffix.length,\n          padding = length < width ? new Array(width - length + 1).join(fill) : \"\";\n\n      // If the fill character is \"0\", grouping is applied after padding.\n      if (comma && zero) value = group(padding + value, padding.length ? width - valueSuffix.length : Infinity), padding = \"\";\n\n      // Reconstruct the final output based on the desired alignment.\n      switch (align) {\n        case \"<\": value = valuePrefix + value + valueSuffix + padding; break;\n        case \"=\": value = valuePrefix + padding + value + valueSuffix; break;\n        case \"^\": value = padding.slice(0, length = padding.length >> 1) + valuePrefix + value + valueSuffix + padding.slice(length); break;\n        default: value = padding + valuePrefix + value + valueSuffix; break;\n      }\n\n      return numerals(value);\n    }\n\n    format.toString = function() {\n      return specifier + \"\";\n    };\n\n    return format;\n  }\n\n  function formatPrefix(specifier, value) {\n    var f = newFormat((specifier = formatSpecifier(specifier), specifier.type = \"f\", specifier)),\n        e = Math.max(-8, Math.min(8, Math.floor(exponent$1(value) / 3))) * 3,\n        k = Math.pow(10, -e),\n        prefix = prefixes[8 + e / 3];\n    return function(value) {\n      return f(k * value) + prefix;\n    };\n  }\n\n  return {\n    format: newFormat,\n    formatPrefix: formatPrefix\n  };\n};\n\nvar locale$1;\n\n\n\ndefaultLocale({\n  decimal: \".\",\n  thousands: \",\",\n  grouping: [3],\n  currency: [\"$\", \"\"]\n});\n\nfunction defaultLocale(definition) {\n  locale$1 = formatLocale(definition);\n  exports.format = locale$1.format;\n  exports.formatPrefix = locale$1.formatPrefix;\n  return locale$1;\n}\n\nvar precisionFixed = function(step) {\n  return Math.max(0, -exponent$1(Math.abs(step)));\n};\n\nvar precisionPrefix = function(step, value) {\n  return Math.max(0, Math.max(-8, Math.min(8, Math.floor(exponent$1(value) / 3))) * 3 - exponent$1(Math.abs(step)));\n};\n\nvar precisionRound = function(step, max) {\n  step = Math.abs(step), max = Math.abs(max) - step;\n  return Math.max(0, exponent$1(max) - exponent$1(step)) + 1;\n};\n\n// Adds floating point numbers with twice the normal precision.\n// Reference: J. R. Shewchuk, Adaptive Precision Floating-Point Arithmetic and\n// Fast Robust Geometric Predicates, Discrete & Computational Geometry 18(3)\n// 305–363 (1997).\n// Code adapted from GeographicLib by Charles F. F. Karney,\n// http://geographiclib.sourceforge.net/\n\nvar adder = function() {\n  return new Adder;\n};\n\nfunction Adder() {\n  this.reset();\n}\n\nAdder.prototype = {\n  constructor: Adder,\n  reset: function() {\n    this.s = // rounded value\n    this.t = 0; // exact error\n  },\n  add: function(y) {\n    add$1(temp, y, this.t);\n    add$1(this, temp.s, this.s);\n    if (this.s) this.t += temp.t;\n    else this.s = temp.t;\n  },\n  valueOf: function() {\n    return this.s;\n  }\n};\n\nvar temp = new Adder;\n\nfunction add$1(adder, a, b) {\n  var x = adder.s = a + b,\n      bv = x - a,\n      av = x - bv;\n  adder.t = (a - av) + (b - bv);\n}\n\nvar epsilon$2 = 1e-6;\nvar epsilon2$1 = 1e-12;\nvar pi$3 = Math.PI;\nvar halfPi$2 = pi$3 / 2;\nvar quarterPi = pi$3 / 4;\nvar tau$3 = pi$3 * 2;\n\nvar degrees$1 = 180 / pi$3;\nvar radians = pi$3 / 180;\n\nvar abs = Math.abs;\nvar atan = Math.atan;\nvar atan2 = Math.atan2;\nvar cos$1 = Math.cos;\nvar ceil = Math.ceil;\nvar exp = Math.exp;\n\nvar log = Math.log;\nvar pow = Math.pow;\nvar sin$1 = Math.sin;\nvar sign = Math.sign || function(x) { return x > 0 ? 1 : x < 0 ? -1 : 0; };\nvar sqrt = Math.sqrt;\nvar tan = Math.tan;\n\nfunction acos(x) {\n  return x > 1 ? 0 : x < -1 ? pi$3 : Math.acos(x);\n}\n\nfunction asin(x) {\n  return x > 1 ? halfPi$2 : x < -1 ? -halfPi$2 : Math.asin(x);\n}\n\nfunction haversin(x) {\n  return (x = sin$1(x / 2)) * x;\n}\n\nfunction noop$1() {}\n\nfunction streamGeometry(geometry, stream) {\n  if (geometry && streamGeometryType.hasOwnProperty(geometry.type)) {\n    streamGeometryType[geometry.type](geometry, stream);\n  }\n}\n\nvar streamObjectType = {\n  Feature: function(object, stream) {\n    streamGeometry(object.geometry, stream);\n  },\n  FeatureCollection: function(object, stream) {\n    var features = object.features, i = -1, n = features.length;\n    while (++i < n) streamGeometry(features[i].geometry, stream);\n  }\n};\n\nvar streamGeometryType = {\n  Sphere: function(object, stream) {\n    stream.sphere();\n  },\n  Point: function(object, stream) {\n    object = object.coordinates;\n    stream.point(object[0], object[1], object[2]);\n  },\n  MultiPoint: function(object, stream) {\n    var coordinates = object.coordinates, i = -1, n = coordinates.length;\n    while (++i < n) object = coordinates[i], stream.point(object[0], object[1], object[2]);\n  },\n  LineString: function(object, stream) {\n    streamLine(object.coordinates, stream, 0);\n  },\n  MultiLineString: function(object, stream) {\n    var coordinates = object.coordinates, i = -1, n = coordinates.length;\n    while (++i < n) streamLine(coordinates[i], stream, 0);\n  },\n  Polygon: function(object, stream) {\n    streamPolygon(object.coordinates, stream);\n  },\n  MultiPolygon: function(object, stream) {\n    var coordinates = object.coordinates, i = -1, n = coordinates.length;\n    while (++i < n) streamPolygon(coordinates[i], stream);\n  },\n  GeometryCollection: function(object, stream) {\n    var geometries = object.geometries, i = -1, n = geometries.length;\n    while (++i < n) streamGeometry(geometries[i], stream);\n  }\n};\n\nfunction streamLine(coordinates, stream, closed) {\n  var i = -1, n = coordinates.length - closed, coordinate;\n  stream.lineStart();\n  while (++i < n) coordinate = coordinates[i], stream.point(coordinate[0], coordinate[1], coordinate[2]);\n  stream.lineEnd();\n}\n\nfunction streamPolygon(coordinates, stream) {\n  var i = -1, n = coordinates.length;\n  stream.polygonStart();\n  while (++i < n) streamLine(coordinates[i], stream, 1);\n  stream.polygonEnd();\n}\n\nvar geoStream = function(object, stream) {\n  if (object && streamObjectType.hasOwnProperty(object.type)) {\n    streamObjectType[object.type](object, stream);\n  } else {\n    streamGeometry(object, stream);\n  }\n};\n\nvar areaRingSum = adder();\n\nvar areaSum = adder();\nvar lambda00;\nvar phi00;\nvar lambda0;\nvar cosPhi0;\nvar sinPhi0;\n\nvar areaStream = {\n  point: noop$1,\n  lineStart: noop$1,\n  lineEnd: noop$1,\n  polygonStart: function() {\n    areaRingSum.reset();\n    areaStream.lineStart = areaRingStart;\n    areaStream.lineEnd = areaRingEnd;\n  },\n  polygonEnd: function() {\n    var areaRing = +areaRingSum;\n    areaSum.add(areaRing < 0 ? tau$3 + areaRing : areaRing);\n    this.lineStart = this.lineEnd = this.point = noop$1;\n  },\n  sphere: function() {\n    areaSum.add(tau$3);\n  }\n};\n\nfunction areaRingStart() {\n  areaStream.point = areaPointFirst;\n}\n\nfunction areaRingEnd() {\n  areaPoint(lambda00, phi00);\n}\n\nfunction areaPointFirst(lambda, phi) {\n  areaStream.point = areaPoint;\n  lambda00 = lambda, phi00 = phi;\n  lambda *= radians, phi *= radians;\n  lambda0 = lambda, cosPhi0 = cos$1(phi = phi / 2 + quarterPi), sinPhi0 = sin$1(phi);\n}\n\nfunction areaPoint(lambda, phi) {\n  lambda *= radians, phi *= radians;\n  phi = phi / 2 + quarterPi; // half the angular distance from south pole\n\n  // Spherical excess E for a spherical triangle with vertices: south pole,\n  // previous point, current point.  Uses a formula derived from Cagnoli’s\n  // theorem.  See Todhunter, Spherical Trig. (1871), Sec. 103, Eq. (2).\n  var dLambda = lambda - lambda0,\n      sdLambda = dLambda >= 0 ? 1 : -1,\n      adLambda = sdLambda * dLambda,\n      cosPhi = cos$1(phi),\n      sinPhi = sin$1(phi),\n      k = sinPhi0 * sinPhi,\n      u = cosPhi0 * cosPhi + k * cos$1(adLambda),\n      v = k * sdLambda * sin$1(adLambda);\n  areaRingSum.add(atan2(v, u));\n\n  // Advance the previous points.\n  lambda0 = lambda, cosPhi0 = cosPhi, sinPhi0 = sinPhi;\n}\n\nvar area = function(object) {\n  areaSum.reset();\n  geoStream(object, areaStream);\n  return areaSum * 2;\n};\n\nfunction spherical(cartesian) {\n  return [atan2(cartesian[1], cartesian[0]), asin(cartesian[2])];\n}\n\nfunction cartesian(spherical) {\n  var lambda = spherical[0], phi = spherical[1], cosPhi = cos$1(phi);\n  return [cosPhi * cos$1(lambda), cosPhi * sin$1(lambda), sin$1(phi)];\n}\n\nfunction cartesianDot(a, b) {\n  return a[0] * b[0] + a[1] * b[1] + a[2] * b[2];\n}\n\nfunction cartesianCross(a, b) {\n  return [a[1] * b[2] - a[2] * b[1], a[2] * b[0] - a[0] * b[2], a[0] * b[1] - a[1] * b[0]];\n}\n\n// TODO return a\nfunction cartesianAddInPlace(a, b) {\n  a[0] += b[0], a[1] += b[1], a[2] += b[2];\n}\n\nfunction cartesianScale(vector, k) {\n  return [vector[0] * k, vector[1] * k, vector[2] * k];\n}\n\n// TODO return d\nfunction cartesianNormalizeInPlace(d) {\n  var l = sqrt(d[0] * d[0] + d[1] * d[1] + d[2] * d[2]);\n  d[0] /= l, d[1] /= l, d[2] /= l;\n}\n\nvar lambda0$1;\nvar phi0;\nvar lambda1;\nvar phi1;\nvar lambda2;\nvar lambda00$1;\nvar phi00$1;\nvar p0;\nvar deltaSum = adder();\nvar ranges;\nvar range;\n\nvar boundsStream = {\n  point: boundsPoint,\n  lineStart: boundsLineStart,\n  lineEnd: boundsLineEnd,\n  polygonStart: function() {\n    boundsStream.point = boundsRingPoint;\n    boundsStream.lineStart = boundsRingStart;\n    boundsStream.lineEnd = boundsRingEnd;\n    deltaSum.reset();\n    areaStream.polygonStart();\n  },\n  polygonEnd: function() {\n    areaStream.polygonEnd();\n    boundsStream.point = boundsPoint;\n    boundsStream.lineStart = boundsLineStart;\n    boundsStream.lineEnd = boundsLineEnd;\n    if (areaRingSum < 0) lambda0$1 = -(lambda1 = 180), phi0 = -(phi1 = 90);\n    else if (deltaSum > epsilon$2) phi1 = 90;\n    else if (deltaSum < -epsilon$2) phi0 = -90;\n    range[0] = lambda0$1, range[1] = lambda1;\n  }\n};\n\nfunction boundsPoint(lambda, phi) {\n  ranges.push(range = [lambda0$1 = lambda, lambda1 = lambda]);\n  if (phi < phi0) phi0 = phi;\n  if (phi > phi1) phi1 = phi;\n}\n\nfunction linePoint(lambda, phi) {\n  var p = cartesian([lambda * radians, phi * radians]);\n  if (p0) {\n    var normal = cartesianCross(p0, p),\n        equatorial = [normal[1], -normal[0], 0],\n        inflection = cartesianCross(equatorial, normal);\n    cartesianNormalizeInPlace(inflection);\n    inflection = spherical(inflection);\n    var delta = lambda - lambda2,\n        sign$$1 = delta > 0 ? 1 : -1,\n        lambdai = inflection[0] * degrees$1 * sign$$1,\n        phii,\n        antimeridian = abs(delta) > 180;\n    if (antimeridian ^ (sign$$1 * lambda2 < lambdai && lambdai < sign$$1 * lambda)) {\n      phii = inflection[1] * degrees$1;\n      if (phii > phi1) phi1 = phii;\n    } else if (lambdai = (lambdai + 360) % 360 - 180, antimeridian ^ (sign$$1 * lambda2 < lambdai && lambdai < sign$$1 * lambda)) {\n      phii = -inflection[1] * degrees$1;\n      if (phii < phi0) phi0 = phii;\n    } else {\n      if (phi < phi0) phi0 = phi;\n      if (phi > phi1) phi1 = phi;\n    }\n    if (antimeridian) {\n      if (lambda < lambda2) {\n        if (angle(lambda0$1, lambda) > angle(lambda0$1, lambda1)) lambda1 = lambda;\n      } else {\n        if (angle(lambda, lambda1) > angle(lambda0$1, lambda1)) lambda0$1 = lambda;\n      }\n    } else {\n      if (lambda1 >= lambda0$1) {\n        if (lambda < lambda0$1) lambda0$1 = lambda;\n        if (lambda > lambda1) lambda1 = lambda;\n      } else {\n        if (lambda > lambda2) {\n          if (angle(lambda0$1, lambda) > angle(lambda0$1, lambda1)) lambda1 = lambda;\n        } else {\n          if (angle(lambda, lambda1) > angle(lambda0$1, lambda1)) lambda0$1 = lambda;\n        }\n      }\n    }\n  } else {\n    ranges.push(range = [lambda0$1 = lambda, lambda1 = lambda]);\n  }\n  if (phi < phi0) phi0 = phi;\n  if (phi > phi1) phi1 = phi;\n  p0 = p, lambda2 = lambda;\n}\n\nfunction boundsLineStart() {\n  boundsStream.point = linePoint;\n}\n\nfunction boundsLineEnd() {\n  range[0] = lambda0$1, range[1] = lambda1;\n  boundsStream.point = boundsPoint;\n  p0 = null;\n}\n\nfunction boundsRingPoint(lambda, phi) {\n  if (p0) {\n    var delta = lambda - lambda2;\n    deltaSum.add(abs(delta) > 180 ? delta + (delta > 0 ? 360 : -360) : delta);\n  } else {\n    lambda00$1 = lambda, phi00$1 = phi;\n  }\n  areaStream.point(lambda, phi);\n  linePoint(lambda, phi);\n}\n\nfunction boundsRingStart() {\n  areaStream.lineStart();\n}\n\nfunction boundsRingEnd() {\n  boundsRingPoint(lambda00$1, phi00$1);\n  areaStream.lineEnd();\n  if (abs(deltaSum) > epsilon$2) lambda0$1 = -(lambda1 = 180);\n  range[0] = lambda0$1, range[1] = lambda1;\n  p0 = null;\n}\n\n// Finds the left-right distance between two longitudes.\n// This is almost the same as (lambda1 - lambda0 + 360°) % 360°, except that we want\n// the distance between ±180° to be 360°.\nfunction angle(lambda0, lambda1) {\n  return (lambda1 -= lambda0) < 0 ? lambda1 + 360 : lambda1;\n}\n\nfunction rangeCompare(a, b) {\n  return a[0] - b[0];\n}\n\nfunction rangeContains(range, x) {\n  return range[0] <= range[1] ? range[0] <= x && x <= range[1] : x < range[0] || range[1] < x;\n}\n\nvar bounds = function(feature) {\n  var i, n, a, b, merged, deltaMax, delta;\n\n  phi1 = lambda1 = -(lambda0$1 = phi0 = Infinity);\n  ranges = [];\n  geoStream(feature, boundsStream);\n\n  // First, sort ranges by their minimum longitudes.\n  if (n = ranges.length) {\n    ranges.sort(rangeCompare);\n\n    // Then, merge any ranges that overlap.\n    for (i = 1, a = ranges[0], merged = [a]; i < n; ++i) {\n      b = ranges[i];\n      if (rangeContains(a, b[0]) || rangeContains(a, b[1])) {\n        if (angle(a[0], b[1]) > angle(a[0], a[1])) a[1] = b[1];\n        if (angle(b[0], a[1]) > angle(a[0], a[1])) a[0] = b[0];\n      } else {\n        merged.push(a = b);\n      }\n    }\n\n    // Finally, find the largest gap between the merged ranges.\n    // The final bounding box will be the inverse of this gap.\n    for (deltaMax = -Infinity, n = merged.length - 1, i = 0, a = merged[n]; i <= n; a = b, ++i) {\n      b = merged[i];\n      if ((delta = angle(a[1], b[0])) > deltaMax) deltaMax = delta, lambda0$1 = b[0], lambda1 = a[1];\n    }\n  }\n\n  ranges = range = null;\n\n  return lambda0$1 === Infinity || phi0 === Infinity\n      ? [[NaN, NaN], [NaN, NaN]]\n      : [[lambda0$1, phi0], [lambda1, phi1]];\n};\n\nvar W0;\nvar W1;\nvar X0;\nvar Y0;\nvar Z0;\nvar X1;\nvar Y1;\nvar Z1;\nvar X2;\nvar Y2;\nvar Z2;\nvar lambda00$2;\nvar phi00$2;\nvar x0;\nvar y0;\nvar z0; // previous point\n\nvar centroidStream = {\n  sphere: noop$1,\n  point: centroidPoint,\n  lineStart: centroidLineStart,\n  lineEnd: centroidLineEnd,\n  polygonStart: function() {\n    centroidStream.lineStart = centroidRingStart;\n    centroidStream.lineEnd = centroidRingEnd;\n  },\n  polygonEnd: function() {\n    centroidStream.lineStart = centroidLineStart;\n    centroidStream.lineEnd = centroidLineEnd;\n  }\n};\n\n// Arithmetic mean of Cartesian vectors.\nfunction centroidPoint(lambda, phi) {\n  lambda *= radians, phi *= radians;\n  var cosPhi = cos$1(phi);\n  centroidPointCartesian(cosPhi * cos$1(lambda), cosPhi * sin$1(lambda), sin$1(phi));\n}\n\nfunction centroidPointCartesian(x, y, z) {\n  ++W0;\n  X0 += (x - X0) / W0;\n  Y0 += (y - Y0) / W0;\n  Z0 += (z - Z0) / W0;\n}\n\nfunction centroidLineStart() {\n  centroidStream.point = centroidLinePointFirst;\n}\n\nfunction centroidLinePointFirst(lambda, phi) {\n  lambda *= radians, phi *= radians;\n  var cosPhi = cos$1(phi);\n  x0 = cosPhi * cos$1(lambda);\n  y0 = cosPhi * sin$1(lambda);\n  z0 = sin$1(phi);\n  centroidStream.point = centroidLinePoint;\n  centroidPointCartesian(x0, y0, z0);\n}\n\nfunction centroidLinePoint(lambda, phi) {\n  lambda *= radians, phi *= radians;\n  var cosPhi = cos$1(phi),\n      x = cosPhi * cos$1(lambda),\n      y = cosPhi * sin$1(lambda),\n      z = sin$1(phi),\n      w = atan2(sqrt((w = y0 * z - z0 * y) * w + (w = z0 * x - x0 * z) * w + (w = x0 * y - y0 * x) * w), x0 * x + y0 * y + z0 * z);\n  W1 += w;\n  X1 += w * (x0 + (x0 = x));\n  Y1 += w * (y0 + (y0 = y));\n  Z1 += w * (z0 + (z0 = z));\n  centroidPointCartesian(x0, y0, z0);\n}\n\nfunction centroidLineEnd() {\n  centroidStream.point = centroidPoint;\n}\n\n// See J. E. Brock, The Inertia Tensor for a Spherical Triangle,\n// J. Applied Mechanics 42, 239 (1975).\nfunction centroidRingStart() {\n  centroidStream.point = centroidRingPointFirst;\n}\n\nfunction centroidRingEnd() {\n  centroidRingPoint(lambda00$2, phi00$2);\n  centroidStream.point = centroidPoint;\n}\n\nfunction centroidRingPointFirst(lambda, phi) {\n  lambda00$2 = lambda, phi00$2 = phi;\n  lambda *= radians, phi *= radians;\n  centroidStream.point = centroidRingPoint;\n  var cosPhi = cos$1(phi);\n  x0 = cosPhi * cos$1(lambda);\n  y0 = cosPhi * sin$1(lambda);\n  z0 = sin$1(phi);\n  centroidPointCartesian(x0, y0, z0);\n}\n\nfunction centroidRingPoint(lambda, phi) {\n  lambda *= radians, phi *= radians;\n  var cosPhi = cos$1(phi),\n      x = cosPhi * cos$1(lambda),\n      y = cosPhi * sin$1(lambda),\n      z = sin$1(phi),\n      cx = y0 * z - z0 * y,\n      cy = z0 * x - x0 * z,\n      cz = x0 * y - y0 * x,\n      m = sqrt(cx * cx + cy * cy + cz * cz),\n      w = asin(m), // line weight = angle\n      v = m && -w / m; // area weight multiplier\n  X2 += v * cx;\n  Y2 += v * cy;\n  Z2 += v * cz;\n  W1 += w;\n  X1 += w * (x0 + (x0 = x));\n  Y1 += w * (y0 + (y0 = y));\n  Z1 += w * (z0 + (z0 = z));\n  centroidPointCartesian(x0, y0, z0);\n}\n\nvar centroid = function(object) {\n  W0 = W1 =\n  X0 = Y0 = Z0 =\n  X1 = Y1 = Z1 =\n  X2 = Y2 = Z2 = 0;\n  geoStream(object, centroidStream);\n\n  var x = X2,\n      y = Y2,\n      z = Z2,\n      m = x * x + y * y + z * z;\n\n  // If the area-weighted ccentroid is undefined, fall back to length-weighted ccentroid.\n  if (m < epsilon2$1) {\n    x = X1, y = Y1, z = Z1;\n    // If the feature has zero length, fall back to arithmetic mean of point vectors.\n    if (W1 < epsilon$2) x = X0, y = Y0, z = Z0;\n    m = x * x + y * y + z * z;\n    // If the feature still has an undefined ccentroid, then return.\n    if (m < epsilon2$1) return [NaN, NaN];\n  }\n\n  return [atan2(y, x) * degrees$1, asin(z / sqrt(m)) * degrees$1];\n};\n\nvar constant$7 = function(x) {\n  return function() {\n    return x;\n  };\n};\n\nvar compose = function(a, b) {\n\n  function compose(x, y) {\n    return x = a(x, y), b(x[0], x[1]);\n  }\n\n  if (a.invert && b.invert) compose.invert = function(x, y) {\n    return x = b.invert(x, y), x && a.invert(x[0], x[1]);\n  };\n\n  return compose;\n};\n\nfunction rotationIdentity(lambda, phi) {\n  return [lambda > pi$3 ? lambda - tau$3 : lambda < -pi$3 ? lambda + tau$3 : lambda, phi];\n}\n\nrotationIdentity.invert = rotationIdentity;\n\nfunction rotateRadians(deltaLambda, deltaPhi, deltaGamma) {\n  return (deltaLambda %= tau$3) ? (deltaPhi || deltaGamma ? compose(rotationLambda(deltaLambda), rotationPhiGamma(deltaPhi, deltaGamma))\n    : rotationLambda(deltaLambda))\n    : (deltaPhi || deltaGamma ? rotationPhiGamma(deltaPhi, deltaGamma)\n    : rotationIdentity);\n}\n\nfunction forwardRotationLambda(deltaLambda) {\n  return function(lambda, phi) {\n    return lambda += deltaLambda, [lambda > pi$3 ? lambda - tau$3 : lambda < -pi$3 ? lambda + tau$3 : lambda, phi];\n  };\n}\n\nfunction rotationLambda(deltaLambda) {\n  var rotation = forwardRotationLambda(deltaLambda);\n  rotation.invert = forwardRotationLambda(-deltaLambda);\n  return rotation;\n}\n\nfunction rotationPhiGamma(deltaPhi, deltaGamma) {\n  var cosDeltaPhi = cos$1(deltaPhi),\n      sinDeltaPhi = sin$1(deltaPhi),\n      cosDeltaGamma = cos$1(deltaGamma),\n      sinDeltaGamma = sin$1(deltaGamma);\n\n  function rotation(lambda, phi) {\n    var cosPhi = cos$1(phi),\n        x = cos$1(lambda) * cosPhi,\n        y = sin$1(lambda) * cosPhi,\n        z = sin$1(phi),\n        k = z * cosDeltaPhi + x * sinDeltaPhi;\n    return [\n      atan2(y * cosDeltaGamma - k * sinDeltaGamma, x * cosDeltaPhi - z * sinDeltaPhi),\n      asin(k * cosDeltaGamma + y * sinDeltaGamma)\n    ];\n  }\n\n  rotation.invert = function(lambda, phi) {\n    var cosPhi = cos$1(phi),\n        x = cos$1(lambda) * cosPhi,\n        y = sin$1(lambda) * cosPhi,\n        z = sin$1(phi),\n        k = z * cosDeltaGamma - y * sinDeltaGamma;\n    return [\n      atan2(y * cosDeltaGamma + z * sinDeltaGamma, x * cosDeltaPhi + k * sinDeltaPhi),\n      asin(k * cosDeltaPhi - x * sinDeltaPhi)\n    ];\n  };\n\n  return rotation;\n}\n\nvar rotation = function(rotate) {\n  rotate = rotateRadians(rotate[0] * radians, rotate[1] * radians, rotate.length > 2 ? rotate[2] * radians : 0);\n\n  function forward(coordinates) {\n    coordinates = rotate(coordinates[0] * radians, coordinates[1] * radians);\n    return coordinates[0] *= degrees$1, coordinates[1] *= degrees$1, coordinates;\n  }\n\n  forward.invert = function(coordinates) {\n    coordinates = rotate.invert(coordinates[0] * radians, coordinates[1] * radians);\n    return coordinates[0] *= degrees$1, coordinates[1] *= degrees$1, coordinates;\n  };\n\n  return forward;\n};\n\n// Generates a circle centered at [0°, 0°], with a given radius and precision.\nfunction circleStream(stream, radius, delta, direction, t0, t1) {\n  if (!delta) return;\n  var cosRadius = cos$1(radius),\n      sinRadius = sin$1(radius),\n      step = direction * delta;\n  if (t0 == null) {\n    t0 = radius + direction * tau$3;\n    t1 = radius - step / 2;\n  } else {\n    t0 = circleRadius(cosRadius, t0);\n    t1 = circleRadius(cosRadius, t1);\n    if (direction > 0 ? t0 < t1 : t0 > t1) t0 += direction * tau$3;\n  }\n  for (var point, t = t0; direction > 0 ? t > t1 : t < t1; t -= step) {\n    point = spherical([cosRadius, -sinRadius * cos$1(t), -sinRadius * sin$1(t)]);\n    stream.point(point[0], point[1]);\n  }\n}\n\n// Returns the signed angle of a cartesian point relative to [cosRadius, 0, 0].\nfunction circleRadius(cosRadius, point) {\n  point = cartesian(point), point[0] -= cosRadius;\n  cartesianNormalizeInPlace(point);\n  var radius = acos(-point[1]);\n  return ((-point[2] < 0 ? -radius : radius) + tau$3 - epsilon$2) % tau$3;\n}\n\nvar circle = function() {\n  var center = constant$7([0, 0]),\n      radius = constant$7(90),\n      precision = constant$7(6),\n      ring,\n      rotate,\n      stream = {point: point};\n\n  function point(x, y) {\n    ring.push(x = rotate(x, y));\n    x[0] *= degrees$1, x[1] *= degrees$1;\n  }\n\n  function circle() {\n    var c = center.apply(this, arguments),\n        r = radius.apply(this, arguments) * radians,\n        p = precision.apply(this, arguments) * radians;\n    ring = [];\n    rotate = rotateRadians(-c[0] * radians, -c[1] * radians, 0).invert;\n    circleStream(stream, r, p, 1);\n    c = {type: \"Polygon\", coordinates: [ring]};\n    ring = rotate = null;\n    return c;\n  }\n\n  circle.center = function(_) {\n    return arguments.length ? (center = typeof _ === \"function\" ? _ : constant$7([+_[0], +_[1]]), circle) : center;\n  };\n\n  circle.radius = function(_) {\n    return arguments.length ? (radius = typeof _ === \"function\" ? _ : constant$7(+_), circle) : radius;\n  };\n\n  circle.precision = function(_) {\n    return arguments.length ? (precision = typeof _ === \"function\" ? _ : constant$7(+_), circle) : precision;\n  };\n\n  return circle;\n};\n\nvar clipBuffer = function() {\n  var lines = [],\n      line;\n  return {\n    point: function(x, y) {\n      line.push([x, y]);\n    },\n    lineStart: function() {\n      lines.push(line = []);\n    },\n    lineEnd: noop$1,\n    rejoin: function() {\n      if (lines.length > 1) lines.push(lines.pop().concat(lines.shift()));\n    },\n    result: function() {\n      var result = lines;\n      lines = [];\n      line = null;\n      return result;\n    }\n  };\n};\n\nvar clipLine = function(a, b, x0, y0, x1, y1) {\n  var ax = a[0],\n      ay = a[1],\n      bx = b[0],\n      by = b[1],\n      t0 = 0,\n      t1 = 1,\n      dx = bx - ax,\n      dy = by - ay,\n      r;\n\n  r = x0 - ax;\n  if (!dx && r > 0) return;\n  r /= dx;\n  if (dx < 0) {\n    if (r < t0) return;\n    if (r < t1) t1 = r;\n  } else if (dx > 0) {\n    if (r > t1) return;\n    if (r > t0) t0 = r;\n  }\n\n  r = x1 - ax;\n  if (!dx && r < 0) return;\n  r /= dx;\n  if (dx < 0) {\n    if (r > t1) return;\n    if (r > t0) t0 = r;\n  } else if (dx > 0) {\n    if (r < t0) return;\n    if (r < t1) t1 = r;\n  }\n\n  r = y0 - ay;\n  if (!dy && r > 0) return;\n  r /= dy;\n  if (dy < 0) {\n    if (r < t0) return;\n    if (r < t1) t1 = r;\n  } else if (dy > 0) {\n    if (r > t1) return;\n    if (r > t0) t0 = r;\n  }\n\n  r = y1 - ay;\n  if (!dy && r < 0) return;\n  r /= dy;\n  if (dy < 0) {\n    if (r > t1) return;\n    if (r > t0) t0 = r;\n  } else if (dy > 0) {\n    if (r < t0) return;\n    if (r < t1) t1 = r;\n  }\n\n  if (t0 > 0) a[0] = ax + t0 * dx, a[1] = ay + t0 * dy;\n  if (t1 < 1) b[0] = ax + t1 * dx, b[1] = ay + t1 * dy;\n  return true;\n};\n\nvar pointEqual = function(a, b) {\n  return abs(a[0] - b[0]) < epsilon$2 && abs(a[1] - b[1]) < epsilon$2;\n};\n\nfunction Intersection(point, points, other, entry) {\n  this.x = point;\n  this.z = points;\n  this.o = other; // another intersection\n  this.e = entry; // is an entry?\n  this.v = false; // visited\n  this.n = this.p = null; // next & previous\n}\n\n// A generalized polygon clipping algorithm: given a polygon that has been cut\n// into its visible line segments, and rejoins the segments by interpolating\n// along the clip edge.\nvar clipPolygon = function(segments, compareIntersection, startInside, interpolate, stream) {\n  var subject = [],\n      clip = [],\n      i,\n      n;\n\n  segments.forEach(function(segment) {\n    if ((n = segment.length - 1) <= 0) return;\n    var n, p0 = segment[0], p1 = segment[n], x;\n\n    // If the first and last points of a segment are coincident, then treat as a\n    // closed ring. TODO if all rings are closed, then the winding order of the\n    // exterior ring should be checked.\n    if (pointEqual(p0, p1)) {\n      stream.lineStart();\n      for (i = 0; i < n; ++i) stream.point((p0 = segment[i])[0], p0[1]);\n      stream.lineEnd();\n      return;\n    }\n\n    subject.push(x = new Intersection(p0, segment, null, true));\n    clip.push(x.o = new Intersection(p0, null, x, false));\n    subject.push(x = new Intersection(p1, segment, null, false));\n    clip.push(x.o = new Intersection(p1, null, x, true));\n  });\n\n  if (!subject.length) return;\n\n  clip.sort(compareIntersection);\n  link$1(subject);\n  link$1(clip);\n\n  for (i = 0, n = clip.length; i < n; ++i) {\n    clip[i].e = startInside = !startInside;\n  }\n\n  var start = subject[0],\n      points,\n      point;\n\n  while (1) {\n    // Find first unvisited intersection.\n    var current = start,\n        isSubject = true;\n    while (current.v) if ((current = current.n) === start) return;\n    points = current.z;\n    stream.lineStart();\n    do {\n      current.v = current.o.v = true;\n      if (current.e) {\n        if (isSubject) {\n          for (i = 0, n = points.length; i < n; ++i) stream.point((point = points[i])[0], point[1]);\n        } else {\n          interpolate(current.x, current.n.x, 1, stream);\n        }\n        current = current.n;\n      } else {\n        if (isSubject) {\n          points = current.p.z;\n          for (i = points.length - 1; i >= 0; --i) stream.point((point = points[i])[0], point[1]);\n        } else {\n          interpolate(current.x, current.p.x, -1, stream);\n        }\n        current = current.p;\n      }\n      current = current.o;\n      points = current.z;\n      isSubject = !isSubject;\n    } while (!current.v);\n    stream.lineEnd();\n  }\n};\n\nfunction link$1(array) {\n  if (!(n = array.length)) return;\n  var n,\n      i = 0,\n      a = array[0],\n      b;\n  while (++i < n) {\n    a.n = b = array[i];\n    b.p = a;\n    a = b;\n  }\n  a.n = b = array[0];\n  b.p = a;\n}\n\nvar clipMax = 1e9;\nvar clipMin = -clipMax;\n\n// TODO Use d3-polygon’s polygonContains here for the ring check?\n// TODO Eliminate duplicate buffering in clipBuffer and polygon.push?\n\nfunction clipExtent(x0, y0, x1, y1) {\n\n  function visible(x, y) {\n    return x0 <= x && x <= x1 && y0 <= y && y <= y1;\n  }\n\n  function interpolate(from, to, direction, stream) {\n    var a = 0, a1 = 0;\n    if (from == null\n        || (a = corner(from, direction)) !== (a1 = corner(to, direction))\n        || comparePoint(from, to) < 0 ^ direction > 0) {\n      do stream.point(a === 0 || a === 3 ? x0 : x1, a > 1 ? y1 : y0);\n      while ((a = (a + direction + 4) % 4) !== a1);\n    } else {\n      stream.point(to[0], to[1]);\n    }\n  }\n\n  function corner(p, direction) {\n    return abs(p[0] - x0) < epsilon$2 ? direction > 0 ? 0 : 3\n        : abs(p[0] - x1) < epsilon$2 ? direction > 0 ? 2 : 1\n        : abs(p[1] - y0) < epsilon$2 ? direction > 0 ? 1 : 0\n        : direction > 0 ? 3 : 2; // abs(p[1] - y1) < epsilon\n  }\n\n  function compareIntersection(a, b) {\n    return comparePoint(a.x, b.x);\n  }\n\n  function comparePoint(a, b) {\n    var ca = corner(a, 1),\n        cb = corner(b, 1);\n    return ca !== cb ? ca - cb\n        : ca === 0 ? b[1] - a[1]\n        : ca === 1 ? a[0] - b[0]\n        : ca === 2 ? a[1] - b[1]\n        : b[0] - a[0];\n  }\n\n  return function(stream) {\n    var activeStream = stream,\n        bufferStream = clipBuffer(),\n        segments,\n        polygon,\n        ring,\n        x__, y__, v__, // first point\n        x_, y_, v_, // previous point\n        first,\n        clean;\n\n    var clipStream = {\n      point: point,\n      lineStart: lineStart,\n      lineEnd: lineEnd,\n      polygonStart: polygonStart,\n      polygonEnd: polygonEnd\n    };\n\n    function point(x, y) {\n      if (visible(x, y)) activeStream.point(x, y);\n    }\n\n    function polygonInside() {\n      var winding = 0;\n\n      for (var i = 0, n = polygon.length; i < n; ++i) {\n        for (var ring = polygon[i], j = 1, m = ring.length, point = ring[0], a0, a1, b0 = point[0], b1 = point[1]; j < m; ++j) {\n          a0 = b0, a1 = b1, point = ring[j], b0 = point[0], b1 = point[1];\n          if (a1 <= y1) { if (b1 > y1 && (b0 - a0) * (y1 - a1) > (b1 - a1) * (x0 - a0)) ++winding; }\n          else { if (b1 <= y1 && (b0 - a0) * (y1 - a1) < (b1 - a1) * (x0 - a0)) --winding; }\n        }\n      }\n\n      return winding;\n    }\n\n    // Buffer geometry within a polygon and then clip it en masse.\n    function polygonStart() {\n      activeStream = bufferStream, segments = [], polygon = [], clean = true;\n    }\n\n    function polygonEnd() {\n      var startInside = polygonInside(),\n          cleanInside = clean && startInside,\n          visible = (segments = merge(segments)).length;\n      if (cleanInside || visible) {\n        stream.polygonStart();\n        if (cleanInside) {\n          stream.lineStart();\n          interpolate(null, null, 1, stream);\n          stream.lineEnd();\n        }\n        if (visible) {\n          clipPolygon(segments, compareIntersection, startInside, interpolate, stream);\n        }\n        stream.polygonEnd();\n      }\n      activeStream = stream, segments = polygon = ring = null;\n    }\n\n    function lineStart() {\n      clipStream.point = linePoint;\n      if (polygon) polygon.push(ring = []);\n      first = true;\n      v_ = false;\n      x_ = y_ = NaN;\n    }\n\n    // TODO rather than special-case polygons, simply handle them separately.\n    // Ideally, coincident intersection points should be jittered to avoid\n    // clipping issues.\n    function lineEnd() {\n      if (segments) {\n        linePoint(x__, y__);\n        if (v__ && v_) bufferStream.rejoin();\n        segments.push(bufferStream.result());\n      }\n      clipStream.point = point;\n      if (v_) activeStream.lineEnd();\n    }\n\n    function linePoint(x, y) {\n      var v = visible(x, y);\n      if (polygon) ring.push([x, y]);\n      if (first) {\n        x__ = x, y__ = y, v__ = v;\n        first = false;\n        if (v) {\n          activeStream.lineStart();\n          activeStream.point(x, y);\n        }\n      } else {\n        if (v && v_) activeStream.point(x, y);\n        else {\n          var a = [x_ = Math.max(clipMin, Math.min(clipMax, x_)), y_ = Math.max(clipMin, Math.min(clipMax, y_))],\n              b = [x = Math.max(clipMin, Math.min(clipMax, x)), y = Math.max(clipMin, Math.min(clipMax, y))];\n          if (clipLine(a, b, x0, y0, x1, y1)) {\n            if (!v_) {\n              activeStream.lineStart();\n              activeStream.point(a[0], a[1]);\n            }\n            activeStream.point(b[0], b[1]);\n            if (!v) activeStream.lineEnd();\n            clean = false;\n          } else if (v) {\n            activeStream.lineStart();\n            activeStream.point(x, y);\n            clean = false;\n          }\n        }\n      }\n      x_ = x, y_ = y, v_ = v;\n    }\n\n    return clipStream;\n  };\n}\n\nvar extent$1 = function() {\n  var x0 = 0,\n      y0 = 0,\n      x1 = 960,\n      y1 = 500,\n      cache,\n      cacheStream,\n      clip;\n\n  return clip = {\n    stream: function(stream) {\n      return cache && cacheStream === stream ? cache : cache = clipExtent(x0, y0, x1, y1)(cacheStream = stream);\n    },\n    extent: function(_) {\n      return arguments.length ? (x0 = +_[0][0], y0 = +_[0][1], x1 = +_[1][0], y1 = +_[1][1], cache = cacheStream = null, clip) : [[x0, y0], [x1, y1]];\n    }\n  };\n};\n\nvar sum$1 = adder();\n\nvar polygonContains = function(polygon, point) {\n  var lambda = point[0],\n      phi = point[1],\n      normal = [sin$1(lambda), -cos$1(lambda), 0],\n      angle = 0,\n      winding = 0;\n\n  sum$1.reset();\n\n  for (var i = 0, n = polygon.length; i < n; ++i) {\n    if (!(m = (ring = polygon[i]).length)) continue;\n    var ring,\n        m,\n        point0 = ring[m - 1],\n        lambda0 = point0[0],\n        phi0 = point0[1] / 2 + quarterPi,\n        sinPhi0 = sin$1(phi0),\n        cosPhi0 = cos$1(phi0);\n\n    for (var j = 0; j < m; ++j, lambda0 = lambda1, sinPhi0 = sinPhi1, cosPhi0 = cosPhi1, point0 = point1) {\n      var point1 = ring[j],\n          lambda1 = point1[0],\n          phi1 = point1[1] / 2 + quarterPi,\n          sinPhi1 = sin$1(phi1),\n          cosPhi1 = cos$1(phi1),\n          delta = lambda1 - lambda0,\n          sign$$1 = delta >= 0 ? 1 : -1,\n          absDelta = sign$$1 * delta,\n          antimeridian = absDelta > pi$3,\n          k = sinPhi0 * sinPhi1;\n\n      sum$1.add(atan2(k * sign$$1 * sin$1(absDelta), cosPhi0 * cosPhi1 + k * cos$1(absDelta)));\n      angle += antimeridian ? delta + sign$$1 * tau$3 : delta;\n\n      // Are the longitudes either side of the point’s meridian (lambda),\n      // and are the latitudes smaller than the parallel (phi)?\n      if (antimeridian ^ lambda0 >= lambda ^ lambda1 >= lambda) {\n        var arc = cartesianCross(cartesian(point0), cartesian(point1));\n        cartesianNormalizeInPlace(arc);\n        var intersection = cartesianCross(normal, arc);\n        cartesianNormalizeInPlace(intersection);\n        var phiArc = (antimeridian ^ delta >= 0 ? -1 : 1) * asin(intersection[2]);\n        if (phi > phiArc || phi === phiArc && (arc[0] || arc[1])) {\n          winding += antimeridian ^ delta >= 0 ? 1 : -1;\n        }\n      }\n    }\n  }\n\n  // First, determine whether the South pole is inside or outside:\n  //\n  // It is inside if:\n  // * the polygon winds around it in a clockwise direction.\n  // * the polygon does not (cumulatively) wind around it, but has a negative\n  //   (counter-clockwise) area.\n  //\n  // Second, count the (signed) number of times a segment crosses a lambda\n  // from the point to the South pole.  If it is zero, then the point is the\n  // same side as the South pole.\n\n  return (angle < -epsilon$2 || angle < epsilon$2 && sum$1 < -epsilon$2) ^ (winding & 1);\n};\n\nvar lengthSum = adder();\nvar lambda0$2;\nvar sinPhi0$1;\nvar cosPhi0$1;\n\nvar lengthStream = {\n  sphere: noop$1,\n  point: noop$1,\n  lineStart: lengthLineStart,\n  lineEnd: noop$1,\n  polygonStart: noop$1,\n  polygonEnd: noop$1\n};\n\nfunction lengthLineStart() {\n  lengthStream.point = lengthPointFirst;\n  lengthStream.lineEnd = lengthLineEnd;\n}\n\nfunction lengthLineEnd() {\n  lengthStream.point = lengthStream.lineEnd = noop$1;\n}\n\nfunction lengthPointFirst(lambda, phi) {\n  lambda *= radians, phi *= radians;\n  lambda0$2 = lambda, sinPhi0$1 = sin$1(phi), cosPhi0$1 = cos$1(phi);\n  lengthStream.point = lengthPoint;\n}\n\nfunction lengthPoint(lambda, phi) {\n  lambda *= radians, phi *= radians;\n  var sinPhi = sin$1(phi),\n      cosPhi = cos$1(phi),\n      delta = abs(lambda - lambda0$2),\n      cosDelta = cos$1(delta),\n      sinDelta = sin$1(delta),\n      x = cosPhi * sinDelta,\n      y = cosPhi0$1 * sinPhi - sinPhi0$1 * cosPhi * cosDelta,\n      z = sinPhi0$1 * sinPhi + cosPhi0$1 * cosPhi * cosDelta;\n  lengthSum.add(atan2(sqrt(x * x + y * y), z));\n  lambda0$2 = lambda, sinPhi0$1 = sinPhi, cosPhi0$1 = cosPhi;\n}\n\nvar length$1 = function(object) {\n  lengthSum.reset();\n  geoStream(object, lengthStream);\n  return +lengthSum;\n};\n\nvar coordinates = [null, null];\nvar object$1 = {type: \"LineString\", coordinates: coordinates};\n\nvar distance = function(a, b) {\n  coordinates[0] = a;\n  coordinates[1] = b;\n  return length$1(object$1);\n};\n\nvar containsObjectType = {\n  Feature: function(object, point) {\n    return containsGeometry(object.geometry, point);\n  },\n  FeatureCollection: function(object, point) {\n    var features = object.features, i = -1, n = features.length;\n    while (++i < n) if (containsGeometry(features[i].geometry, point)) return true;\n    return false;\n  }\n};\n\nvar containsGeometryType = {\n  Sphere: function() {\n    return true;\n  },\n  Point: function(object, point) {\n    return containsPoint(object.coordinates, point);\n  },\n  MultiPoint: function(object, point) {\n    var coordinates = object.coordinates, i = -1, n = coordinates.length;\n    while (++i < n) if (containsPoint(coordinates[i], point)) return true;\n    return false;\n  },\n  LineString: function(object, point) {\n    return containsLine(object.coordinates, point);\n  },\n  MultiLineString: function(object, point) {\n    var coordinates = object.coordinates, i = -1, n = coordinates.length;\n    while (++i < n) if (containsLine(coordinates[i], point)) return true;\n    return false;\n  },\n  Polygon: function(object, point) {\n    return containsPolygon(object.coordinates, point);\n  },\n  MultiPolygon: function(object, point) {\n    var coordinates = object.coordinates, i = -1, n = coordinates.length;\n    while (++i < n) if (containsPolygon(coordinates[i], point)) return true;\n    return false;\n  },\n  GeometryCollection: function(object, point) {\n    var geometries = object.geometries, i = -1, n = geometries.length;\n    while (++i < n) if (containsGeometry(geometries[i], point)) return true;\n    return false;\n  }\n};\n\nfunction containsGeometry(geometry, point) {\n  return geometry && containsGeometryType.hasOwnProperty(geometry.type)\n      ? containsGeometryType[geometry.type](geometry, point)\n      : false;\n}\n\nfunction containsPoint(coordinates, point) {\n  return distance(coordinates, point) === 0;\n}\n\nfunction containsLine(coordinates, point) {\n  var ab = distance(coordinates[0], coordinates[1]),\n      ao = distance(coordinates[0], point),\n      ob = distance(point, coordinates[1]);\n  return ao + ob <= ab + epsilon$2;\n}\n\nfunction containsPolygon(coordinates, point) {\n  return !!polygonContains(coordinates.map(ringRadians), pointRadians(point));\n}\n\nfunction ringRadians(ring) {\n  return ring = ring.map(pointRadians), ring.pop(), ring;\n}\n\nfunction pointRadians(point) {\n  return [point[0] * radians, point[1] * radians];\n}\n\nvar contains = function(object, point) {\n  return (object && containsObjectType.hasOwnProperty(object.type)\n      ? containsObjectType[object.type]\n      : containsGeometry)(object, point);\n};\n\nfunction graticuleX(y0, y1, dy) {\n  var y = sequence(y0, y1 - epsilon$2, dy).concat(y1);\n  return function(x) { return y.map(function(y) { return [x, y]; }); };\n}\n\nfunction graticuleY(x0, x1, dx) {\n  var x = sequence(x0, x1 - epsilon$2, dx).concat(x1);\n  return function(y) { return x.map(function(x) { return [x, y]; }); };\n}\n\nfunction graticule() {\n  var x1, x0, X1, X0,\n      y1, y0, Y1, Y0,\n      dx = 10, dy = dx, DX = 90, DY = 360,\n      x, y, X, Y,\n      precision = 2.5;\n\n  function graticule() {\n    return {type: \"MultiLineString\", coordinates: lines()};\n  }\n\n  function lines() {\n    return sequence(ceil(X0 / DX) * DX, X1, DX).map(X)\n        .concat(sequence(ceil(Y0 / DY) * DY, Y1, DY).map(Y))\n        .concat(sequence(ceil(x0 / dx) * dx, x1, dx).filter(function(x) { return abs(x % DX) > epsilon$2; }).map(x))\n        .concat(sequence(ceil(y0 / dy) * dy, y1, dy).filter(function(y) { return abs(y % DY) > epsilon$2; }).map(y));\n  }\n\n  graticule.lines = function() {\n    return lines().map(function(coordinates) { return {type: \"LineString\", coordinates: coordinates}; });\n  };\n\n  graticule.outline = function() {\n    return {\n      type: \"Polygon\",\n      coordinates: [\n        X(X0).concat(\n        Y(Y1).slice(1),\n        X(X1).reverse().slice(1),\n        Y(Y0).reverse().slice(1))\n      ]\n    };\n  };\n\n  graticule.extent = function(_) {\n    if (!arguments.length) return graticule.extentMinor();\n    return graticule.extentMajor(_).extentMinor(_);\n  };\n\n  graticule.extentMajor = function(_) {\n    if (!arguments.length) return [[X0, Y0], [X1, Y1]];\n    X0 = +_[0][0], X1 = +_[1][0];\n    Y0 = +_[0][1], Y1 = +_[1][1];\n    if (X0 > X1) _ = X0, X0 = X1, X1 = _;\n    if (Y0 > Y1) _ = Y0, Y0 = Y1, Y1 = _;\n    return graticule.precision(precision);\n  };\n\n  graticule.extentMinor = function(_) {\n    if (!arguments.length) return [[x0, y0], [x1, y1]];\n    x0 = +_[0][0], x1 = +_[1][0];\n    y0 = +_[0][1], y1 = +_[1][1];\n    if (x0 > x1) _ = x0, x0 = x1, x1 = _;\n    if (y0 > y1) _ = y0, y0 = y1, y1 = _;\n    return graticule.precision(precision);\n  };\n\n  graticule.step = function(_) {\n    if (!arguments.length) return graticule.stepMinor();\n    return graticule.stepMajor(_).stepMinor(_);\n  };\n\n  graticule.stepMajor = function(_) {\n    if (!arguments.length) return [DX, DY];\n    DX = +_[0], DY = +_[1];\n    return graticule;\n  };\n\n  graticule.stepMinor = function(_) {\n    if (!arguments.length) return [dx, dy];\n    dx = +_[0], dy = +_[1];\n    return graticule;\n  };\n\n  graticule.precision = function(_) {\n    if (!arguments.length) return precision;\n    precision = +_;\n    x = graticuleX(y0, y1, 90);\n    y = graticuleY(x0, x1, precision);\n    X = graticuleX(Y0, Y1, 90);\n    Y = graticuleY(X0, X1, precision);\n    return graticule;\n  };\n\n  return graticule\n      .extentMajor([[-180, -90 + epsilon$2], [180, 90 - epsilon$2]])\n      .extentMinor([[-180, -80 - epsilon$2], [180, 80 + epsilon$2]]);\n}\n\nfunction graticule10() {\n  return graticule()();\n}\n\nvar interpolate$1 = function(a, b) {\n  var x0 = a[0] * radians,\n      y0 = a[1] * radians,\n      x1 = b[0] * radians,\n      y1 = b[1] * radians,\n      cy0 = cos$1(y0),\n      sy0 = sin$1(y0),\n      cy1 = cos$1(y1),\n      sy1 = sin$1(y1),\n      kx0 = cy0 * cos$1(x0),\n      ky0 = cy0 * sin$1(x0),\n      kx1 = cy1 * cos$1(x1),\n      ky1 = cy1 * sin$1(x1),\n      d = 2 * asin(sqrt(haversin(y1 - y0) + cy0 * cy1 * haversin(x1 - x0))),\n      k = sin$1(d);\n\n  var interpolate = d ? function(t) {\n    var B = sin$1(t *= d) / k,\n        A = sin$1(d - t) / k,\n        x = A * kx0 + B * kx1,\n        y = A * ky0 + B * ky1,\n        z = A * sy0 + B * sy1;\n    return [\n      atan2(y, x) * degrees$1,\n      atan2(z, sqrt(x * x + y * y)) * degrees$1\n    ];\n  } : function() {\n    return [x0 * degrees$1, y0 * degrees$1];\n  };\n\n  interpolate.distance = d;\n\n  return interpolate;\n};\n\nvar identity$4 = function(x) {\n  return x;\n};\n\nvar areaSum$1 = adder();\nvar areaRingSum$1 = adder();\nvar x00;\nvar y00;\nvar x0$1;\nvar y0$1;\n\nvar areaStream$1 = {\n  point: noop$1,\n  lineStart: noop$1,\n  lineEnd: noop$1,\n  polygonStart: function() {\n    areaStream$1.lineStart = areaRingStart$1;\n    areaStream$1.lineEnd = areaRingEnd$1;\n  },\n  polygonEnd: function() {\n    areaStream$1.lineStart = areaStream$1.lineEnd = areaStream$1.point = noop$1;\n    areaSum$1.add(abs(areaRingSum$1));\n    areaRingSum$1.reset();\n  },\n  result: function() {\n    var area = areaSum$1 / 2;\n    areaSum$1.reset();\n    return area;\n  }\n};\n\nfunction areaRingStart$1() {\n  areaStream$1.point = areaPointFirst$1;\n}\n\nfunction areaPointFirst$1(x, y) {\n  areaStream$1.point = areaPoint$1;\n  x00 = x0$1 = x, y00 = y0$1 = y;\n}\n\nfunction areaPoint$1(x, y) {\n  areaRingSum$1.add(y0$1 * x - x0$1 * y);\n  x0$1 = x, y0$1 = y;\n}\n\nfunction areaRingEnd$1() {\n  areaPoint$1(x00, y00);\n}\n\nvar x0$2 = Infinity;\nvar y0$2 = x0$2;\nvar x1 = -x0$2;\nvar y1 = x1;\n\nvar boundsStream$1 = {\n  point: boundsPoint$1,\n  lineStart: noop$1,\n  lineEnd: noop$1,\n  polygonStart: noop$1,\n  polygonEnd: noop$1,\n  result: function() {\n    var bounds = [[x0$2, y0$2], [x1, y1]];\n    x1 = y1 = -(y0$2 = x0$2 = Infinity);\n    return bounds;\n  }\n};\n\nfunction boundsPoint$1(x, y) {\n  if (x < x0$2) x0$2 = x;\n  if (x > x1) x1 = x;\n  if (y < y0$2) y0$2 = y;\n  if (y > y1) y1 = y;\n}\n\n// TODO Enforce positive area for exterior, negative area for interior?\n\nvar X0$1 = 0;\nvar Y0$1 = 0;\nvar Z0$1 = 0;\nvar X1$1 = 0;\nvar Y1$1 = 0;\nvar Z1$1 = 0;\nvar X2$1 = 0;\nvar Y2$1 = 0;\nvar Z2$1 = 0;\nvar x00$1;\nvar y00$1;\nvar x0$3;\nvar y0$3;\n\nvar centroidStream$1 = {\n  point: centroidPoint$1,\n  lineStart: centroidLineStart$1,\n  lineEnd: centroidLineEnd$1,\n  polygonStart: function() {\n    centroidStream$1.lineStart = centroidRingStart$1;\n    centroidStream$1.lineEnd = centroidRingEnd$1;\n  },\n  polygonEnd: function() {\n    centroidStream$1.point = centroidPoint$1;\n    centroidStream$1.lineStart = centroidLineStart$1;\n    centroidStream$1.lineEnd = centroidLineEnd$1;\n  },\n  result: function() {\n    var centroid = Z2$1 ? [X2$1 / Z2$1, Y2$1 / Z2$1]\n        : Z1$1 ? [X1$1 / Z1$1, Y1$1 / Z1$1]\n        : Z0$1 ? [X0$1 / Z0$1, Y0$1 / Z0$1]\n        : [NaN, NaN];\n    X0$1 = Y0$1 = Z0$1 =\n    X1$1 = Y1$1 = Z1$1 =\n    X2$1 = Y2$1 = Z2$1 = 0;\n    return centroid;\n  }\n};\n\nfunction centroidPoint$1(x, y) {\n  X0$1 += x;\n  Y0$1 += y;\n  ++Z0$1;\n}\n\nfunction centroidLineStart$1() {\n  centroidStream$1.point = centroidPointFirstLine;\n}\n\nfunction centroidPointFirstLine(x, y) {\n  centroidStream$1.point = centroidPointLine;\n  centroidPoint$1(x0$3 = x, y0$3 = y);\n}\n\nfunction centroidPointLine(x, y) {\n  var dx = x - x0$3, dy = y - y0$3, z = sqrt(dx * dx + dy * dy);\n  X1$1 += z * (x0$3 + x) / 2;\n  Y1$1 += z * (y0$3 + y) / 2;\n  Z1$1 += z;\n  centroidPoint$1(x0$3 = x, y0$3 = y);\n}\n\nfunction centroidLineEnd$1() {\n  centroidStream$1.point = centroidPoint$1;\n}\n\nfunction centroidRingStart$1() {\n  centroidStream$1.point = centroidPointFirstRing;\n}\n\nfunction centroidRingEnd$1() {\n  centroidPointRing(x00$1, y00$1);\n}\n\nfunction centroidPointFirstRing(x, y) {\n  centroidStream$1.point = centroidPointRing;\n  centroidPoint$1(x00$1 = x0$3 = x, y00$1 = y0$3 = y);\n}\n\nfunction centroidPointRing(x, y) {\n  var dx = x - x0$3,\n      dy = y - y0$3,\n      z = sqrt(dx * dx + dy * dy);\n\n  X1$1 += z * (x0$3 + x) / 2;\n  Y1$1 += z * (y0$3 + y) / 2;\n  Z1$1 += z;\n\n  z = y0$3 * x - x0$3 * y;\n  X2$1 += z * (x0$3 + x);\n  Y2$1 += z * (y0$3 + y);\n  Z2$1 += z * 3;\n  centroidPoint$1(x0$3 = x, y0$3 = y);\n}\n\nfunction PathContext(context) {\n  this._context = context;\n}\n\nPathContext.prototype = {\n  _radius: 4.5,\n  pointRadius: function(_) {\n    return this._radius = _, this;\n  },\n  polygonStart: function() {\n    this._line = 0;\n  },\n  polygonEnd: function() {\n    this._line = NaN;\n  },\n  lineStart: function() {\n    this._point = 0;\n  },\n  lineEnd: function() {\n    if (this._line === 0) this._context.closePath();\n    this._point = NaN;\n  },\n  point: function(x, y) {\n    switch (this._point) {\n      case 0: {\n        this._context.moveTo(x, y);\n        this._point = 1;\n        break;\n      }\n      case 1: {\n        this._context.lineTo(x, y);\n        break;\n      }\n      default: {\n        this._context.moveTo(x + this._radius, y);\n        this._context.arc(x, y, this._radius, 0, tau$3);\n        break;\n      }\n    }\n  },\n  result: noop$1\n};\n\nvar lengthSum$1 = adder();\nvar lengthRing;\nvar x00$2;\nvar y00$2;\nvar x0$4;\nvar y0$4;\n\nvar lengthStream$1 = {\n  point: noop$1,\n  lineStart: function() {\n    lengthStream$1.point = lengthPointFirst$1;\n  },\n  lineEnd: function() {\n    if (lengthRing) lengthPoint$1(x00$2, y00$2);\n    lengthStream$1.point = noop$1;\n  },\n  polygonStart: function() {\n    lengthRing = true;\n  },\n  polygonEnd: function() {\n    lengthRing = null;\n  },\n  result: function() {\n    var length = +lengthSum$1;\n    lengthSum$1.reset();\n    return length;\n  }\n};\n\nfunction lengthPointFirst$1(x, y) {\n  lengthStream$1.point = lengthPoint$1;\n  x00$2 = x0$4 = x, y00$2 = y0$4 = y;\n}\n\nfunction lengthPoint$1(x, y) {\n  x0$4 -= x, y0$4 -= y;\n  lengthSum$1.add(sqrt(x0$4 * x0$4 + y0$4 * y0$4));\n  x0$4 = x, y0$4 = y;\n}\n\nfunction PathString() {\n  this._string = [];\n}\n\nPathString.prototype = {\n  _radius: 4.5,\n  _circle: circle$1(4.5),\n  pointRadius: function(_) {\n    if ((_ = +_) !== this._radius) this._radius = _, this._circle = null;\n    return this;\n  },\n  polygonStart: function() {\n    this._line = 0;\n  },\n  polygonEnd: function() {\n    this._line = NaN;\n  },\n  lineStart: function() {\n    this._point = 0;\n  },\n  lineEnd: function() {\n    if (this._line === 0) this._string.push(\"Z\");\n    this._point = NaN;\n  },\n  point: function(x, y) {\n    switch (this._point) {\n      case 0: {\n        this._string.push(\"M\", x, \",\", y);\n        this._point = 1;\n        break;\n      }\n      case 1: {\n        this._string.push(\"L\", x, \",\", y);\n        break;\n      }\n      default: {\n        if (this._circle == null) this._circle = circle$1(this._radius);\n        this._string.push(\"M\", x, \",\", y, this._circle);\n        break;\n      }\n    }\n  },\n  result: function() {\n    if (this._string.length) {\n      var result = this._string.join(\"\");\n      this._string = [];\n      return result;\n    } else {\n      return null;\n    }\n  }\n};\n\nfunction circle$1(radius) {\n  return \"m0,\" + radius\n      + \"a\" + radius + \",\" + radius + \" 0 1,1 0,\" + -2 * radius\n      + \"a\" + radius + \",\" + radius + \" 0 1,1 0,\" + 2 * radius\n      + \"z\";\n}\n\nvar index$1 = function(projection, context) {\n  var pointRadius = 4.5,\n      projectionStream,\n      contextStream;\n\n  function path(object) {\n    if (object) {\n      if (typeof pointRadius === \"function\") contextStream.pointRadius(+pointRadius.apply(this, arguments));\n      geoStream(object, projectionStream(contextStream));\n    }\n    return contextStream.result();\n  }\n\n  path.area = function(object) {\n    geoStream(object, projectionStream(areaStream$1));\n    return areaStream$1.result();\n  };\n\n  path.measure = function(object) {\n    geoStream(object, projectionStream(lengthStream$1));\n    return lengthStream$1.result();\n  };\n\n  path.bounds = function(object) {\n    geoStream(object, projectionStream(boundsStream$1));\n    return boundsStream$1.result();\n  };\n\n  path.centroid = function(object) {\n    geoStream(object, projectionStream(centroidStream$1));\n    return centroidStream$1.result();\n  };\n\n  path.projection = function(_) {\n    return arguments.length ? (projectionStream = _ == null ? (projection = null, identity$4) : (projection = _).stream, path) : projection;\n  };\n\n  path.context = function(_) {\n    if (!arguments.length) return context;\n    contextStream = _ == null ? (context = null, new PathString) : new PathContext(context = _);\n    if (typeof pointRadius !== \"function\") contextStream.pointRadius(pointRadius);\n    return path;\n  };\n\n  path.pointRadius = function(_) {\n    if (!arguments.length) return pointRadius;\n    pointRadius = typeof _ === \"function\" ? _ : (contextStream.pointRadius(+_), +_);\n    return path;\n  };\n\n  return path.projection(projection).context(context);\n};\n\nvar clip = function(pointVisible, clipLine, interpolate, start) {\n  return function(rotate, sink) {\n    var line = clipLine(sink),\n        rotatedStart = rotate.invert(start[0], start[1]),\n        ringBuffer = clipBuffer(),\n        ringSink = clipLine(ringBuffer),\n        polygonStarted = false,\n        polygon,\n        segments,\n        ring;\n\n    var clip = {\n      point: point,\n      lineStart: lineStart,\n      lineEnd: lineEnd,\n      polygonStart: function() {\n        clip.point = pointRing;\n        clip.lineStart = ringStart;\n        clip.lineEnd = ringEnd;\n        segments = [];\n        polygon = [];\n      },\n      polygonEnd: function() {\n        clip.point = point;\n        clip.lineStart = lineStart;\n        clip.lineEnd = lineEnd;\n        segments = merge(segments);\n        var startInside = polygonContains(polygon, rotatedStart);\n        if (segments.length) {\n          if (!polygonStarted) sink.polygonStart(), polygonStarted = true;\n          clipPolygon(segments, compareIntersection, startInside, interpolate, sink);\n        } else if (startInside) {\n          if (!polygonStarted) sink.polygonStart(), polygonStarted = true;\n          sink.lineStart();\n          interpolate(null, null, 1, sink);\n          sink.lineEnd();\n        }\n        if (polygonStarted) sink.polygonEnd(), polygonStarted = false;\n        segments = polygon = null;\n      },\n      sphere: function() {\n        sink.polygonStart();\n        sink.lineStart();\n        interpolate(null, null, 1, sink);\n        sink.lineEnd();\n        sink.polygonEnd();\n      }\n    };\n\n    function point(lambda, phi) {\n      var point = rotate(lambda, phi);\n      if (pointVisible(lambda = point[0], phi = point[1])) sink.point(lambda, phi);\n    }\n\n    function pointLine(lambda, phi) {\n      var point = rotate(lambda, phi);\n      line.point(point[0], point[1]);\n    }\n\n    function lineStart() {\n      clip.point = pointLine;\n      line.lineStart();\n    }\n\n    function lineEnd() {\n      clip.point = point;\n      line.lineEnd();\n    }\n\n    function pointRing(lambda, phi) {\n      ring.push([lambda, phi]);\n      var point = rotate(lambda, phi);\n      ringSink.point(point[0], point[1]);\n    }\n\n    function ringStart() {\n      ringSink.lineStart();\n      ring = [];\n    }\n\n    function ringEnd() {\n      pointRing(ring[0][0], ring[0][1]);\n      ringSink.lineEnd();\n\n      var clean = ringSink.clean(),\n          ringSegments = ringBuffer.result(),\n          i, n = ringSegments.length, m,\n          segment,\n          point;\n\n      ring.pop();\n      polygon.push(ring);\n      ring = null;\n\n      if (!n) return;\n\n      // No intersections.\n      if (clean & 1) {\n        segment = ringSegments[0];\n        if ((m = segment.length - 1) > 0) {\n          if (!polygonStarted) sink.polygonStart(), polygonStarted = true;\n          sink.lineStart();\n          for (i = 0; i < m; ++i) sink.point((point = segment[i])[0], point[1]);\n          sink.lineEnd();\n        }\n        return;\n      }\n\n      // Rejoin connected segments.\n      // TODO reuse ringBuffer.rejoin()?\n      if (n > 1 && clean & 2) ringSegments.push(ringSegments.pop().concat(ringSegments.shift()));\n\n      segments.push(ringSegments.filter(validSegment));\n    }\n\n    return clip;\n  };\n};\n\nfunction validSegment(segment) {\n  return segment.length > 1;\n}\n\n// Intersections are sorted along the clip edge. For both antimeridian cutting\n// and circle clipping, the same comparison is used.\nfunction compareIntersection(a, b) {\n  return ((a = a.x)[0] < 0 ? a[1] - halfPi$2 - epsilon$2 : halfPi$2 - a[1])\n       - ((b = b.x)[0] < 0 ? b[1] - halfPi$2 - epsilon$2 : halfPi$2 - b[1]);\n}\n\nvar clipAntimeridian = clip(\n  function() { return true; },\n  clipAntimeridianLine,\n  clipAntimeridianInterpolate,\n  [-pi$3, -halfPi$2]\n);\n\n// Takes a line and cuts into visible segments. Return values: 0 - there were\n// intersections or the line was empty; 1 - no intersections; 2 - there were\n// intersections, and the first and last segments should be rejoined.\nfunction clipAntimeridianLine(stream) {\n  var lambda0 = NaN,\n      phi0 = NaN,\n      sign0 = NaN,\n      clean; // no intersections\n\n  return {\n    lineStart: function() {\n      stream.lineStart();\n      clean = 1;\n    },\n    point: function(lambda1, phi1) {\n      var sign1 = lambda1 > 0 ? pi$3 : -pi$3,\n          delta = abs(lambda1 - lambda0);\n      if (abs(delta - pi$3) < epsilon$2) { // line crosses a pole\n        stream.point(lambda0, phi0 = (phi0 + phi1) / 2 > 0 ? halfPi$2 : -halfPi$2);\n        stream.point(sign0, phi0);\n        stream.lineEnd();\n        stream.lineStart();\n        stream.point(sign1, phi0);\n        stream.point(lambda1, phi0);\n        clean = 0;\n      } else if (sign0 !== sign1 && delta >= pi$3) { // line crosses antimeridian\n        if (abs(lambda0 - sign0) < epsilon$2) lambda0 -= sign0 * epsilon$2; // handle degeneracies\n        if (abs(lambda1 - sign1) < epsilon$2) lambda1 -= sign1 * epsilon$2;\n        phi0 = clipAntimeridianIntersect(lambda0, phi0, lambda1, phi1);\n        stream.point(sign0, phi0);\n        stream.lineEnd();\n        stream.lineStart();\n        stream.point(sign1, phi0);\n        clean = 0;\n      }\n      stream.point(lambda0 = lambda1, phi0 = phi1);\n      sign0 = sign1;\n    },\n    lineEnd: function() {\n      stream.lineEnd();\n      lambda0 = phi0 = NaN;\n    },\n    clean: function() {\n      return 2 - clean; // if intersections, rejoin first and last segments\n    }\n  };\n}\n\nfunction clipAntimeridianIntersect(lambda0, phi0, lambda1, phi1) {\n  var cosPhi0,\n      cosPhi1,\n      sinLambda0Lambda1 = sin$1(lambda0 - lambda1);\n  return abs(sinLambda0Lambda1) > epsilon$2\n      ? atan((sin$1(phi0) * (cosPhi1 = cos$1(phi1)) * sin$1(lambda1)\n          - sin$1(phi1) * (cosPhi0 = cos$1(phi0)) * sin$1(lambda0))\n          / (cosPhi0 * cosPhi1 * sinLambda0Lambda1))\n      : (phi0 + phi1) / 2;\n}\n\nfunction clipAntimeridianInterpolate(from, to, direction, stream) {\n  var phi;\n  if (from == null) {\n    phi = direction * halfPi$2;\n    stream.point(-pi$3, phi);\n    stream.point(0, phi);\n    stream.point(pi$3, phi);\n    stream.point(pi$3, 0);\n    stream.point(pi$3, -phi);\n    stream.point(0, -phi);\n    stream.point(-pi$3, -phi);\n    stream.point(-pi$3, 0);\n    stream.point(-pi$3, phi);\n  } else if (abs(from[0] - to[0]) > epsilon$2) {\n    var lambda = from[0] < to[0] ? pi$3 : -pi$3;\n    phi = direction * lambda / 2;\n    stream.point(-lambda, phi);\n    stream.point(0, phi);\n    stream.point(lambda, phi);\n  } else {\n    stream.point(to[0], to[1]);\n  }\n}\n\nvar clipCircle = function(radius, delta) {\n  var cr = cos$1(radius),\n      smallRadius = cr > 0,\n      notHemisphere = abs(cr) > epsilon$2; // TODO optimise for this common case\n\n  function interpolate(from, to, direction, stream) {\n    circleStream(stream, radius, delta, direction, from, to);\n  }\n\n  function visible(lambda, phi) {\n    return cos$1(lambda) * cos$1(phi) > cr;\n  }\n\n  // Takes a line and cuts into visible segments. Return values used for polygon\n  // clipping: 0 - there were intersections or the line was empty; 1 - no\n  // intersections 2 - there were intersections, and the first and last segments\n  // should be rejoined.\n  function clipLine(stream) {\n    var point0, // previous point\n        c0, // code for previous point\n        v0, // visibility of previous point\n        v00, // visibility of first point\n        clean; // no intersections\n    return {\n      lineStart: function() {\n        v00 = v0 = false;\n        clean = 1;\n      },\n      point: function(lambda, phi) {\n        var point1 = [lambda, phi],\n            point2,\n            v = visible(lambda, phi),\n            c = smallRadius\n              ? v ? 0 : code(lambda, phi)\n              : v ? code(lambda + (lambda < 0 ? pi$3 : -pi$3), phi) : 0;\n        if (!point0 && (v00 = v0 = v)) stream.lineStart();\n        // Handle degeneracies.\n        // TODO ignore if not clipping polygons.\n        if (v !== v0) {\n          point2 = intersect(point0, point1);\n          if (!point2 || pointEqual(point0, point2) || pointEqual(point1, point2)) {\n            point1[0] += epsilon$2;\n            point1[1] += epsilon$2;\n            v = visible(point1[0], point1[1]);\n          }\n        }\n        if (v !== v0) {\n          clean = 0;\n          if (v) {\n            // outside going in\n            stream.lineStart();\n            point2 = intersect(point1, point0);\n            stream.point(point2[0], point2[1]);\n          } else {\n            // inside going out\n            point2 = intersect(point0, point1);\n            stream.point(point2[0], point2[1]);\n            stream.lineEnd();\n          }\n          point0 = point2;\n        } else if (notHemisphere && point0 && smallRadius ^ v) {\n          var t;\n          // If the codes for two points are different, or are both zero,\n          // and there this segment intersects with the small circle.\n          if (!(c & c0) && (t = intersect(point1, point0, true))) {\n            clean = 0;\n            if (smallRadius) {\n              stream.lineStart();\n              stream.point(t[0][0], t[0][1]);\n              stream.point(t[1][0], t[1][1]);\n              stream.lineEnd();\n            } else {\n              stream.point(t[1][0], t[1][1]);\n              stream.lineEnd();\n              stream.lineStart();\n              stream.point(t[0][0], t[0][1]);\n            }\n          }\n        }\n        if (v && (!point0 || !pointEqual(point0, point1))) {\n          stream.point(point1[0], point1[1]);\n        }\n        point0 = point1, v0 = v, c0 = c;\n      },\n      lineEnd: function() {\n        if (v0) stream.lineEnd();\n        point0 = null;\n      },\n      // Rejoin first and last segments if there were intersections and the first\n      // and last points were visible.\n      clean: function() {\n        return clean | ((v00 && v0) << 1);\n      }\n    };\n  }\n\n  // Intersects the great circle between a and b with the clip circle.\n  function intersect(a, b, two) {\n    var pa = cartesian(a),\n        pb = cartesian(b);\n\n    // We have two planes, n1.p = d1 and n2.p = d2.\n    // Find intersection line p(t) = c1 n1 + c2 n2 + t (n1 ⨯ n2).\n    var n1 = [1, 0, 0], // normal\n        n2 = cartesianCross(pa, pb),\n        n2n2 = cartesianDot(n2, n2),\n        n1n2 = n2[0], // cartesianDot(n1, n2),\n        determinant = n2n2 - n1n2 * n1n2;\n\n    // Two polar points.\n    if (!determinant) return !two && a;\n\n    var c1 =  cr * n2n2 / determinant,\n        c2 = -cr * n1n2 / determinant,\n        n1xn2 = cartesianCross(n1, n2),\n        A = cartesianScale(n1, c1),\n        B = cartesianScale(n2, c2);\n    cartesianAddInPlace(A, B);\n\n    // Solve |p(t)|^2 = 1.\n    var u = n1xn2,\n        w = cartesianDot(A, u),\n        uu = cartesianDot(u, u),\n        t2 = w * w - uu * (cartesianDot(A, A) - 1);\n\n    if (t2 < 0) return;\n\n    var t = sqrt(t2),\n        q = cartesianScale(u, (-w - t) / uu);\n    cartesianAddInPlace(q, A);\n    q = spherical(q);\n\n    if (!two) return q;\n\n    // Two intersection points.\n    var lambda0 = a[0],\n        lambda1 = b[0],\n        phi0 = a[1],\n        phi1 = b[1],\n        z;\n\n    if (lambda1 < lambda0) z = lambda0, lambda0 = lambda1, lambda1 = z;\n\n    var delta = lambda1 - lambda0,\n        polar = abs(delta - pi$3) < epsilon$2,\n        meridian = polar || delta < epsilon$2;\n\n    if (!polar && phi1 < phi0) z = phi0, phi0 = phi1, phi1 = z;\n\n    // Check that the first point is between a and b.\n    if (meridian\n        ? polar\n          ? phi0 + phi1 > 0 ^ q[1] < (abs(q[0] - lambda0) < epsilon$2 ? phi0 : phi1)\n          : phi0 <= q[1] && q[1] <= phi1\n        : delta > pi$3 ^ (lambda0 <= q[0] && q[0] <= lambda1)) {\n      var q1 = cartesianScale(u, (-w + t) / uu);\n      cartesianAddInPlace(q1, A);\n      return [q, spherical(q1)];\n    }\n  }\n\n  // Generates a 4-bit vector representing the location of a point relative to\n  // the small circle's bounding box.\n  function code(lambda, phi) {\n    var r = smallRadius ? radius : pi$3 - radius,\n        code = 0;\n    if (lambda < -r) code |= 1; // left\n    else if (lambda > r) code |= 2; // right\n    if (phi < -r) code |= 4; // below\n    else if (phi > r) code |= 8; // above\n    return code;\n  }\n\n  return clip(visible, clipLine, interpolate, smallRadius ? [0, -radius] : [-pi$3, radius - pi$3]);\n};\n\nvar transform = function(methods) {\n  return {\n    stream: transformer(methods)\n  };\n};\n\nfunction transformer(methods) {\n  return function(stream) {\n    var s = new TransformStream;\n    for (var key in methods) s[key] = methods[key];\n    s.stream = stream;\n    return s;\n  };\n}\n\nfunction TransformStream() {}\n\nTransformStream.prototype = {\n  constructor: TransformStream,\n  point: function(x, y) { this.stream.point(x, y); },\n  sphere: function() { this.stream.sphere(); },\n  lineStart: function() { this.stream.lineStart(); },\n  lineEnd: function() { this.stream.lineEnd(); },\n  polygonStart: function() { this.stream.polygonStart(); },\n  polygonEnd: function() { this.stream.polygonEnd(); }\n};\n\nfunction fitExtent(projection, extent, object) {\n  var w = extent[1][0] - extent[0][0],\n      h = extent[1][1] - extent[0][1],\n      clip = projection.clipExtent && projection.clipExtent();\n\n  projection\n      .scale(150)\n      .translate([0, 0]);\n\n  if (clip != null) projection.clipExtent(null);\n\n  geoStream(object, projection.stream(boundsStream$1));\n\n  var b = boundsStream$1.result(),\n      k = Math.min(w / (b[1][0] - b[0][0]), h / (b[1][1] - b[0][1])),\n      x = +extent[0][0] + (w - k * (b[1][0] + b[0][0])) / 2,\n      y = +extent[0][1] + (h - k * (b[1][1] + b[0][1])) / 2;\n\n  if (clip != null) projection.clipExtent(clip);\n\n  return projection\n      .scale(k * 150)\n      .translate([x, y]);\n}\n\nfunction fitSize(projection, size, object) {\n  return fitExtent(projection, [[0, 0], size], object);\n}\n\nvar maxDepth = 16;\nvar cosMinDistance = cos$1(30 * radians); // cos(minimum angular distance)\n\nvar resample = function(project, delta2) {\n  return +delta2 ? resample$1(project, delta2) : resampleNone(project);\n};\n\nfunction resampleNone(project) {\n  return transformer({\n    point: function(x, y) {\n      x = project(x, y);\n      this.stream.point(x[0], x[1]);\n    }\n  });\n}\n\nfunction resample$1(project, delta2) {\n\n  function resampleLineTo(x0, y0, lambda0, a0, b0, c0, x1, y1, lambda1, a1, b1, c1, depth, stream) {\n    var dx = x1 - x0,\n        dy = y1 - y0,\n        d2 = dx * dx + dy * dy;\n    if (d2 > 4 * delta2 && depth--) {\n      var a = a0 + a1,\n          b = b0 + b1,\n          c = c0 + c1,\n          m = sqrt(a * a + b * b + c * c),\n          phi2 = asin(c /= m),\n          lambda2 = abs(abs(c) - 1) < epsilon$2 || abs(lambda0 - lambda1) < epsilon$2 ? (lambda0 + lambda1) / 2 : atan2(b, a),\n          p = project(lambda2, phi2),\n          x2 = p[0],\n          y2 = p[1],\n          dx2 = x2 - x0,\n          dy2 = y2 - y0,\n          dz = dy * dx2 - dx * dy2;\n      if (dz * dz / d2 > delta2 // perpendicular projected distance\n          || abs((dx * dx2 + dy * dy2) / d2 - 0.5) > 0.3 // midpoint close to an end\n          || a0 * a1 + b0 * b1 + c0 * c1 < cosMinDistance) { // angular distance\n        resampleLineTo(x0, y0, lambda0, a0, b0, c0, x2, y2, lambda2, a /= m, b /= m, c, depth, stream);\n        stream.point(x2, y2);\n        resampleLineTo(x2, y2, lambda2, a, b, c, x1, y1, lambda1, a1, b1, c1, depth, stream);\n      }\n    }\n  }\n  return function(stream) {\n    var lambda00, x00, y00, a00, b00, c00, // first point\n        lambda0, x0, y0, a0, b0, c0; // previous point\n\n    var resampleStream = {\n      point: point,\n      lineStart: lineStart,\n      lineEnd: lineEnd,\n      polygonStart: function() { stream.polygonStart(); resampleStream.lineStart = ringStart; },\n      polygonEnd: function() { stream.polygonEnd(); resampleStream.lineStart = lineStart; }\n    };\n\n    function point(x, y) {\n      x = project(x, y);\n      stream.point(x[0], x[1]);\n    }\n\n    function lineStart() {\n      x0 = NaN;\n      resampleStream.point = linePoint;\n      stream.lineStart();\n    }\n\n    function linePoint(lambda, phi) {\n      var c = cartesian([lambda, phi]), p = project(lambda, phi);\n      resampleLineTo(x0, y0, lambda0, a0, b0, c0, x0 = p[0], y0 = p[1], lambda0 = lambda, a0 = c[0], b0 = c[1], c0 = c[2], maxDepth, stream);\n      stream.point(x0, y0);\n    }\n\n    function lineEnd() {\n      resampleStream.point = point;\n      stream.lineEnd();\n    }\n\n    function ringStart() {\n      lineStart();\n      resampleStream.point = ringPoint;\n      resampleStream.lineEnd = ringEnd;\n    }\n\n    function ringPoint(lambda, phi) {\n      linePoint(lambda00 = lambda, phi), x00 = x0, y00 = y0, a00 = a0, b00 = b0, c00 = c0;\n      resampleStream.point = linePoint;\n    }\n\n    function ringEnd() {\n      resampleLineTo(x0, y0, lambda0, a0, b0, c0, x00, y00, lambda00, a00, b00, c00, maxDepth, stream);\n      resampleStream.lineEnd = lineEnd;\n      lineEnd();\n    }\n\n    return resampleStream;\n  };\n}\n\nvar transformRadians = transformer({\n  point: function(x, y) {\n    this.stream.point(x * radians, y * radians);\n  }\n});\n\nfunction projection(project) {\n  return projectionMutator(function() { return project; })();\n}\n\nfunction projectionMutator(projectAt) {\n  var project,\n      k = 150, // scale\n      x = 480, y = 250, // translate\n      dx, dy, lambda = 0, phi = 0, // center\n      deltaLambda = 0, deltaPhi = 0, deltaGamma = 0, rotate, projectRotate, // rotate\n      theta = null, preclip = clipAntimeridian, // clip angle\n      x0 = null, y0, x1, y1, postclip = identity$4, // clip extent\n      delta2 = 0.5, projectResample = resample(projectTransform, delta2), // precision\n      cache,\n      cacheStream;\n\n  function projection(point) {\n    point = projectRotate(point[0] * radians, point[1] * radians);\n    return [point[0] * k + dx, dy - point[1] * k];\n  }\n\n  function invert(point) {\n    point = projectRotate.invert((point[0] - dx) / k, (dy - point[1]) / k);\n    return point && [point[0] * degrees$1, point[1] * degrees$1];\n  }\n\n  function projectTransform(x, y) {\n    return x = project(x, y), [x[0] * k + dx, dy - x[1] * k];\n  }\n\n  projection.stream = function(stream) {\n    return cache && cacheStream === stream ? cache : cache = transformRadians(preclip(rotate, projectResample(postclip(cacheStream = stream))));\n  };\n\n  projection.clipAngle = function(_) {\n    return arguments.length ? (preclip = +_ ? clipCircle(theta = _ * radians, 6 * radians) : (theta = null, clipAntimeridian), reset()) : theta * degrees$1;\n  };\n\n  projection.clipExtent = function(_) {\n    return arguments.length ? (postclip = _ == null ? (x0 = y0 = x1 = y1 = null, identity$4) : clipExtent(x0 = +_[0][0], y0 = +_[0][1], x1 = +_[1][0], y1 = +_[1][1]), reset()) : x0 == null ? null : [[x0, y0], [x1, y1]];\n  };\n\n  projection.scale = function(_) {\n    return arguments.length ? (k = +_, recenter()) : k;\n  };\n\n  projection.translate = function(_) {\n    return arguments.length ? (x = +_[0], y = +_[1], recenter()) : [x, y];\n  };\n\n  projection.center = function(_) {\n    return arguments.length ? (lambda = _[0] % 360 * radians, phi = _[1] % 360 * radians, recenter()) : [lambda * degrees$1, phi * degrees$1];\n  };\n\n  projection.rotate = function(_) {\n    return arguments.length ? (deltaLambda = _[0] % 360 * radians, deltaPhi = _[1] % 360 * radians, deltaGamma = _.length > 2 ? _[2] % 360 * radians : 0, recenter()) : [deltaLambda * degrees$1, deltaPhi * degrees$1, deltaGamma * degrees$1];\n  };\n\n  projection.precision = function(_) {\n    return arguments.length ? (projectResample = resample(projectTransform, delta2 = _ * _), reset()) : sqrt(delta2);\n  };\n\n  projection.fitExtent = function(extent, object) {\n    return fitExtent(projection, extent, object);\n  };\n\n  projection.fitSize = function(size, object) {\n    return fitSize(projection, size, object);\n  };\n\n  function recenter() {\n    projectRotate = compose(rotate = rotateRadians(deltaLambda, deltaPhi, deltaGamma), project);\n    var center = project(lambda, phi);\n    dx = x - center[0] * k;\n    dy = y + center[1] * k;\n    return reset();\n  }\n\n  function reset() {\n    cache = cacheStream = null;\n    return projection;\n  }\n\n  return function() {\n    project = projectAt.apply(this, arguments);\n    projection.invert = project.invert && invert;\n    return recenter();\n  };\n}\n\nfunction conicProjection(projectAt) {\n  var phi0 = 0,\n      phi1 = pi$3 / 3,\n      m = projectionMutator(projectAt),\n      p = m(phi0, phi1);\n\n  p.parallels = function(_) {\n    return arguments.length ? m(phi0 = _[0] * radians, phi1 = _[1] * radians) : [phi0 * degrees$1, phi1 * degrees$1];\n  };\n\n  return p;\n}\n\nfunction cylindricalEqualAreaRaw(phi0) {\n  var cosPhi0 = cos$1(phi0);\n\n  function forward(lambda, phi) {\n    return [lambda * cosPhi0, sin$1(phi) / cosPhi0];\n  }\n\n  forward.invert = function(x, y) {\n    return [x / cosPhi0, asin(y * cosPhi0)];\n  };\n\n  return forward;\n}\n\nfunction conicEqualAreaRaw(y0, y1) {\n  var sy0 = sin$1(y0), n = (sy0 + sin$1(y1)) / 2;\n\n  // Are the parallels symmetrical around the Equator?\n  if (abs(n) < epsilon$2) return cylindricalEqualAreaRaw(y0);\n\n  var c = 1 + sy0 * (2 * n - sy0), r0 = sqrt(c) / n;\n\n  function project(x, y) {\n    var r = sqrt(c - 2 * n * sin$1(y)) / n;\n    return [r * sin$1(x *= n), r0 - r * cos$1(x)];\n  }\n\n  project.invert = function(x, y) {\n    var r0y = r0 - y;\n    return [atan2(x, abs(r0y)) / n * sign(r0y), asin((c - (x * x + r0y * r0y) * n * n) / (2 * n))];\n  };\n\n  return project;\n}\n\nvar conicEqualArea = function() {\n  return conicProjection(conicEqualAreaRaw)\n      .scale(155.424)\n      .center([0, 33.6442]);\n};\n\nvar albers = function() {\n  return conicEqualArea()\n      .parallels([29.5, 45.5])\n      .scale(1070)\n      .translate([480, 250])\n      .rotate([96, 0])\n      .center([-0.6, 38.7]);\n};\n\n// The projections must have mutually exclusive clip regions on the sphere,\n// as this will avoid emitting interleaving lines and polygons.\nfunction multiplex(streams) {\n  var n = streams.length;\n  return {\n    point: function(x, y) { var i = -1; while (++i < n) streams[i].point(x, y); },\n    sphere: function() { var i = -1; while (++i < n) streams[i].sphere(); },\n    lineStart: function() { var i = -1; while (++i < n) streams[i].lineStart(); },\n    lineEnd: function() { var i = -1; while (++i < n) streams[i].lineEnd(); },\n    polygonStart: function() { var i = -1; while (++i < n) streams[i].polygonStart(); },\n    polygonEnd: function() { var i = -1; while (++i < n) streams[i].polygonEnd(); }\n  };\n}\n\n// A composite projection for the United States, configured by default for\n// 960×500. The projection also works quite well at 960×600 if you change the\n// scale to 1285 and adjust the translate accordingly. The set of standard\n// parallels for each region comes from USGS, which is published here:\n// http://egsc.usgs.gov/isb/pubs/MapProjections/projections.html#albers\nvar albersUsa = function() {\n  var cache,\n      cacheStream,\n      lower48 = albers(), lower48Point,\n      alaska = conicEqualArea().rotate([154, 0]).center([-2, 58.5]).parallels([55, 65]), alaskaPoint, // EPSG:3338\n      hawaii = conicEqualArea().rotate([157, 0]).center([-3, 19.9]).parallels([8, 18]), hawaiiPoint, // ESRI:102007\n      point, pointStream = {point: function(x, y) { point = [x, y]; }};\n\n  function albersUsa(coordinates) {\n    var x = coordinates[0], y = coordinates[1];\n    return point = null,\n        (lower48Point.point(x, y), point)\n        || (alaskaPoint.point(x, y), point)\n        || (hawaiiPoint.point(x, y), point);\n  }\n\n  albersUsa.invert = function(coordinates) {\n    var k = lower48.scale(),\n        t = lower48.translate(),\n        x = (coordinates[0] - t[0]) / k,\n        y = (coordinates[1] - t[1]) / k;\n    return (y >= 0.120 && y < 0.234 && x >= -0.425 && x < -0.214 ? alaska\n        : y >= 0.166 && y < 0.234 && x >= -0.214 && x < -0.115 ? hawaii\n        : lower48).invert(coordinates);\n  };\n\n  albersUsa.stream = function(stream) {\n    return cache && cacheStream === stream ? cache : cache = multiplex([lower48.stream(cacheStream = stream), alaska.stream(stream), hawaii.stream(stream)]);\n  };\n\n  albersUsa.precision = function(_) {\n    if (!arguments.length) return lower48.precision();\n    lower48.precision(_), alaska.precision(_), hawaii.precision(_);\n    return reset();\n  };\n\n  albersUsa.scale = function(_) {\n    if (!arguments.length) return lower48.scale();\n    lower48.scale(_), alaska.scale(_ * 0.35), hawaii.scale(_);\n    return albersUsa.translate(lower48.translate());\n  };\n\n  albersUsa.translate = function(_) {\n    if (!arguments.length) return lower48.translate();\n    var k = lower48.scale(), x = +_[0], y = +_[1];\n\n    lower48Point = lower48\n        .translate(_)\n        .clipExtent([[x - 0.455 * k, y - 0.238 * k], [x + 0.455 * k, y + 0.238 * k]])\n        .stream(pointStream);\n\n    alaskaPoint = alaska\n        .translate([x - 0.307 * k, y + 0.201 * k])\n        .clipExtent([[x - 0.425 * k + epsilon$2, y + 0.120 * k + epsilon$2], [x - 0.214 * k - epsilon$2, y + 0.234 * k - epsilon$2]])\n        .stream(pointStream);\n\n    hawaiiPoint = hawaii\n        .translate([x - 0.205 * k, y + 0.212 * k])\n        .clipExtent([[x - 0.214 * k + epsilon$2, y + 0.166 * k + epsilon$2], [x - 0.115 * k - epsilon$2, y + 0.234 * k - epsilon$2]])\n        .stream(pointStream);\n\n    return reset();\n  };\n\n  albersUsa.fitExtent = function(extent, object) {\n    return fitExtent(albersUsa, extent, object);\n  };\n\n  albersUsa.fitSize = function(size, object) {\n    return fitSize(albersUsa, size, object);\n  };\n\n  function reset() {\n    cache = cacheStream = null;\n    return albersUsa;\n  }\n\n  return albersUsa.scale(1070);\n};\n\nfunction azimuthalRaw(scale) {\n  return function(x, y) {\n    var cx = cos$1(x),\n        cy = cos$1(y),\n        k = scale(cx * cy);\n    return [\n      k * cy * sin$1(x),\n      k * sin$1(y)\n    ];\n  }\n}\n\nfunction azimuthalInvert(angle) {\n  return function(x, y) {\n    var z = sqrt(x * x + y * y),\n        c = angle(z),\n        sc = sin$1(c),\n        cc = cos$1(c);\n    return [\n      atan2(x * sc, z * cc),\n      asin(z && y * sc / z)\n    ];\n  }\n}\n\nvar azimuthalEqualAreaRaw = azimuthalRaw(function(cxcy) {\n  return sqrt(2 / (1 + cxcy));\n});\n\nazimuthalEqualAreaRaw.invert = azimuthalInvert(function(z) {\n  return 2 * asin(z / 2);\n});\n\nvar azimuthalEqualArea = function() {\n  return projection(azimuthalEqualAreaRaw)\n      .scale(124.75)\n      .clipAngle(180 - 1e-3);\n};\n\nvar azimuthalEquidistantRaw = azimuthalRaw(function(c) {\n  return (c = acos(c)) && c / sin$1(c);\n});\n\nazimuthalEquidistantRaw.invert = azimuthalInvert(function(z) {\n  return z;\n});\n\nvar azimuthalEquidistant = function() {\n  return projection(azimuthalEquidistantRaw)\n      .scale(79.4188)\n      .clipAngle(180 - 1e-3);\n};\n\nfunction mercatorRaw(lambda, phi) {\n  return [lambda, log(tan((halfPi$2 + phi) / 2))];\n}\n\nmercatorRaw.invert = function(x, y) {\n  return [x, 2 * atan(exp(y)) - halfPi$2];\n};\n\nvar mercator = function() {\n  return mercatorProjection(mercatorRaw)\n      .scale(961 / tau$3);\n};\n\nfunction mercatorProjection(project) {\n  var m = projection(project),\n      center = m.center,\n      scale = m.scale,\n      translate = m.translate,\n      clipExtent = m.clipExtent,\n      x0 = null, y0, x1, y1; // clip extent\n\n  m.scale = function(_) {\n    return arguments.length ? (scale(_), reclip()) : scale();\n  };\n\n  m.translate = function(_) {\n    return arguments.length ? (translate(_), reclip()) : translate();\n  };\n\n  m.center = function(_) {\n    return arguments.length ? (center(_), reclip()) : center();\n  };\n\n  m.clipExtent = function(_) {\n    return arguments.length ? ((_ == null ? x0 = y0 = x1 = y1 = null : (x0 = +_[0][0], y0 = +_[0][1], x1 = +_[1][0], y1 = +_[1][1])), reclip()) : x0 == null ? null : [[x0, y0], [x1, y1]];\n  };\n\n  function reclip() {\n    var k = pi$3 * scale(),\n        t = m(rotation(m.rotate()).invert([0, 0]));\n    return clipExtent(x0 == null\n        ? [[t[0] - k, t[1] - k], [t[0] + k, t[1] + k]] : project === mercatorRaw\n        ? [[Math.max(t[0] - k, x0), y0], [Math.min(t[0] + k, x1), y1]]\n        : [[x0, Math.max(t[1] - k, y0)], [x1, Math.min(t[1] + k, y1)]]);\n  }\n\n  return reclip();\n}\n\nfunction tany(y) {\n  return tan((halfPi$2 + y) / 2);\n}\n\nfunction conicConformalRaw(y0, y1) {\n  var cy0 = cos$1(y0),\n      n = y0 === y1 ? sin$1(y0) : log(cy0 / cos$1(y1)) / log(tany(y1) / tany(y0)),\n      f = cy0 * pow(tany(y0), n) / n;\n\n  if (!n) return mercatorRaw;\n\n  function project(x, y) {\n    if (f > 0) { if (y < -halfPi$2 + epsilon$2) y = -halfPi$2 + epsilon$2; }\n    else { if (y > halfPi$2 - epsilon$2) y = halfPi$2 - epsilon$2; }\n    var r = f / pow(tany(y), n);\n    return [r * sin$1(n * x), f - r * cos$1(n * x)];\n  }\n\n  project.invert = function(x, y) {\n    var fy = f - y, r = sign(n) * sqrt(x * x + fy * fy);\n    return [atan2(x, abs(fy)) / n * sign(fy), 2 * atan(pow(f / r, 1 / n)) - halfPi$2];\n  };\n\n  return project;\n}\n\nvar conicConformal = function() {\n  return conicProjection(conicConformalRaw)\n      .scale(109.5)\n      .parallels([30, 30]);\n};\n\nfunction equirectangularRaw(lambda, phi) {\n  return [lambda, phi];\n}\n\nequirectangularRaw.invert = equirectangularRaw;\n\nvar equirectangular = function() {\n  return projection(equirectangularRaw)\n      .scale(152.63);\n};\n\nfunction conicEquidistantRaw(y0, y1) {\n  var cy0 = cos$1(y0),\n      n = y0 === y1 ? sin$1(y0) : (cy0 - cos$1(y1)) / (y1 - y0),\n      g = cy0 / n + y0;\n\n  if (abs(n) < epsilon$2) return equirectangularRaw;\n\n  function project(x, y) {\n    var gy = g - y, nx = n * x;\n    return [gy * sin$1(nx), g - gy * cos$1(nx)];\n  }\n\n  project.invert = function(x, y) {\n    var gy = g - y;\n    return [atan2(x, abs(gy)) / n * sign(gy), g - sign(n) * sqrt(x * x + gy * gy)];\n  };\n\n  return project;\n}\n\nvar conicEquidistant = function() {\n  return conicProjection(conicEquidistantRaw)\n      .scale(131.154)\n      .center([0, 13.9389]);\n};\n\nfunction gnomonicRaw(x, y) {\n  var cy = cos$1(y), k = cos$1(x) * cy;\n  return [cy * sin$1(x) / k, sin$1(y) / k];\n}\n\ngnomonicRaw.invert = azimuthalInvert(atan);\n\nvar gnomonic = function() {\n  return projection(gnomonicRaw)\n      .scale(144.049)\n      .clipAngle(60);\n};\n\nfunction scaleTranslate(kx, ky, tx, ty) {\n  return kx === 1 && ky === 1 && tx === 0 && ty === 0 ? identity$4 : transformer({\n    point: function(x, y) {\n      this.stream.point(x * kx + tx, y * ky + ty);\n    }\n  });\n}\n\nvar identity$5 = function() {\n  var k = 1, tx = 0, ty = 0, sx = 1, sy = 1, transform = identity$4, // scale, translate and reflect\n      x0 = null, y0, x1, y1, clip = identity$4, // clip extent\n      cache,\n      cacheStream,\n      projection;\n\n  function reset() {\n    cache = cacheStream = null;\n    return projection;\n  }\n\n  return projection = {\n    stream: function(stream) {\n      return cache && cacheStream === stream ? cache : cache = transform(clip(cacheStream = stream));\n    },\n    clipExtent: function(_) {\n      return arguments.length ? (clip = _ == null ? (x0 = y0 = x1 = y1 = null, identity$4) : clipExtent(x0 = +_[0][0], y0 = +_[0][1], x1 = +_[1][0], y1 = +_[1][1]), reset()) : x0 == null ? null : [[x0, y0], [x1, y1]];\n    },\n    scale: function(_) {\n      return arguments.length ? (transform = scaleTranslate((k = +_) * sx, k * sy, tx, ty), reset()) : k;\n    },\n    translate: function(_) {\n      return arguments.length ? (transform = scaleTranslate(k * sx, k * sy, tx = +_[0], ty = +_[1]), reset()) : [tx, ty];\n    },\n    reflectX: function(_) {\n      return arguments.length ? (transform = scaleTranslate(k * (sx = _ ? -1 : 1), k * sy, tx, ty), reset()) : sx < 0;\n    },\n    reflectY: function(_) {\n      return arguments.length ? (transform = scaleTranslate(k * sx, k * (sy = _ ? -1 : 1), tx, ty), reset()) : sy < 0;\n    },\n    fitExtent: function(extent, object) {\n      return fitExtent(projection, extent, object);\n    },\n    fitSize: function(size, object) {\n      return fitSize(projection, size, object);\n    }\n  };\n};\n\nfunction orthographicRaw(x, y) {\n  return [cos$1(y) * sin$1(x), sin$1(y)];\n}\n\northographicRaw.invert = azimuthalInvert(asin);\n\nvar orthographic = function() {\n  return projection(orthographicRaw)\n      .scale(249.5)\n      .clipAngle(90 + epsilon$2);\n};\n\nfunction stereographicRaw(x, y) {\n  var cy = cos$1(y), k = 1 + cos$1(x) * cy;\n  return [cy * sin$1(x) / k, sin$1(y) / k];\n}\n\nstereographicRaw.invert = azimuthalInvert(function(z) {\n  return 2 * atan(z);\n});\n\nvar stereographic = function() {\n  return projection(stereographicRaw)\n      .scale(250)\n      .clipAngle(142);\n};\n\nfunction transverseMercatorRaw(lambda, phi) {\n  return [log(tan((halfPi$2 + phi) / 2)), -lambda];\n}\n\ntransverseMercatorRaw.invert = function(x, y) {\n  return [-y, 2 * atan(exp(x)) - halfPi$2];\n};\n\nvar transverseMercator = function() {\n  var m = mercatorProjection(transverseMercatorRaw),\n      center = m.center,\n      rotate = m.rotate;\n\n  m.center = function(_) {\n    return arguments.length ? center([-_[1], _[0]]) : (_ = center(), [_[1], -_[0]]);\n  };\n\n  m.rotate = function(_) {\n    return arguments.length ? rotate([_[0], _[1], _.length > 2 ? _[2] + 90 : 90]) : (_ = rotate(), [_[0], _[1], _[2] - 90]);\n  };\n\n  return rotate([0, 0, 90])\n      .scale(159.155);\n};\n\nfunction defaultSeparation(a, b) {\n  return a.parent === b.parent ? 1 : 2;\n}\n\nfunction meanX(children) {\n  return children.reduce(meanXReduce, 0) / children.length;\n}\n\nfunction meanXReduce(x, c) {\n  return x + c.x;\n}\n\nfunction maxY(children) {\n  return 1 + children.reduce(maxYReduce, 0);\n}\n\nfunction maxYReduce(y, c) {\n  return Math.max(y, c.y);\n}\n\nfunction leafLeft(node) {\n  var children;\n  while (children = node.children) node = children[0];\n  return node;\n}\n\nfunction leafRight(node) {\n  var children;\n  while (children = node.children) node = children[children.length - 1];\n  return node;\n}\n\nvar cluster = function() {\n  var separation = defaultSeparation,\n      dx = 1,\n      dy = 1,\n      nodeSize = false;\n\n  function cluster(root) {\n    var previousNode,\n        x = 0;\n\n    // First walk, computing the initial x & y values.\n    root.eachAfter(function(node) {\n      var children = node.children;\n      if (children) {\n        node.x = meanX(children);\n        node.y = maxY(children);\n      } else {\n        node.x = previousNode ? x += separation(node, previousNode) : 0;\n        node.y = 0;\n        previousNode = node;\n      }\n    });\n\n    var left = leafLeft(root),\n        right = leafRight(root),\n        x0 = left.x - separation(left, right) / 2,\n        x1 = right.x + separation(right, left) / 2;\n\n    // Second walk, normalizing x & y to the desired size.\n    return root.eachAfter(nodeSize ? function(node) {\n      node.x = (node.x - root.x) * dx;\n      node.y = (root.y - node.y) * dy;\n    } : function(node) {\n      node.x = (node.x - x0) / (x1 - x0) * dx;\n      node.y = (1 - (root.y ? node.y / root.y : 1)) * dy;\n    });\n  }\n\n  cluster.separation = function(x) {\n    return arguments.length ? (separation = x, cluster) : separation;\n  };\n\n  cluster.size = function(x) {\n    return arguments.length ? (nodeSize = false, dx = +x[0], dy = +x[1], cluster) : (nodeSize ? null : [dx, dy]);\n  };\n\n  cluster.nodeSize = function(x) {\n    return arguments.length ? (nodeSize = true, dx = +x[0], dy = +x[1], cluster) : (nodeSize ? [dx, dy] : null);\n  };\n\n  return cluster;\n};\n\nfunction count(node) {\n  var sum = 0,\n      children = node.children,\n      i = children && children.length;\n  if (!i) sum = 1;\n  else while (--i >= 0) sum += children[i].value;\n  node.value = sum;\n}\n\nvar node_count = function() {\n  return this.eachAfter(count);\n};\n\nvar node_each = function(callback) {\n  var node = this, current, next = [node], children, i, n;\n  do {\n    current = next.reverse(), next = [];\n    while (node = current.pop()) {\n      callback(node), children = node.children;\n      if (children) for (i = 0, n = children.length; i < n; ++i) {\n        next.push(children[i]);\n      }\n    }\n  } while (next.length);\n  return this;\n};\n\nvar node_eachBefore = function(callback) {\n  var node = this, nodes = [node], children, i;\n  while (node = nodes.pop()) {\n    callback(node), children = node.children;\n    if (children) for (i = children.length - 1; i >= 0; --i) {\n      nodes.push(children[i]);\n    }\n  }\n  return this;\n};\n\nvar node_eachAfter = function(callback) {\n  var node = this, nodes = [node], next = [], children, i, n;\n  while (node = nodes.pop()) {\n    next.push(node), children = node.children;\n    if (children) for (i = 0, n = children.length; i < n; ++i) {\n      nodes.push(children[i]);\n    }\n  }\n  while (node = next.pop()) {\n    callback(node);\n  }\n  return this;\n};\n\nvar node_sum = function(value) {\n  return this.eachAfter(function(node) {\n    var sum = +value(node.data) || 0,\n        children = node.children,\n        i = children && children.length;\n    while (--i >= 0) sum += children[i].value;\n    node.value = sum;\n  });\n};\n\nvar node_sort = function(compare) {\n  return this.eachBefore(function(node) {\n    if (node.children) {\n      node.children.sort(compare);\n    }\n  });\n};\n\nvar node_path = function(end) {\n  var start = this,\n      ancestor = leastCommonAncestor(start, end),\n      nodes = [start];\n  while (start !== ancestor) {\n    start = start.parent;\n    nodes.push(start);\n  }\n  var k = nodes.length;\n  while (end !== ancestor) {\n    nodes.splice(k, 0, end);\n    end = end.parent;\n  }\n  return nodes;\n};\n\nfunction leastCommonAncestor(a, b) {\n  if (a === b) return a;\n  var aNodes = a.ancestors(),\n      bNodes = b.ancestors(),\n      c = null;\n  a = aNodes.pop();\n  b = bNodes.pop();\n  while (a === b) {\n    c = a;\n    a = aNodes.pop();\n    b = bNodes.pop();\n  }\n  return c;\n}\n\nvar node_ancestors = function() {\n  var node = this, nodes = [node];\n  while (node = node.parent) {\n    nodes.push(node);\n  }\n  return nodes;\n};\n\nvar node_descendants = function() {\n  var nodes = [];\n  this.each(function(node) {\n    nodes.push(node);\n  });\n  return nodes;\n};\n\nvar node_leaves = function() {\n  var leaves = [];\n  this.eachBefore(function(node) {\n    if (!node.children) {\n      leaves.push(node);\n    }\n  });\n  return leaves;\n};\n\nvar node_links = function() {\n  var root = this, links = [];\n  root.each(function(node) {\n    if (node !== root) { // Don’t include the root’s parent, if any.\n      links.push({source: node.parent, target: node});\n    }\n  });\n  return links;\n};\n\nfunction hierarchy(data, children) {\n  var root = new Node(data),\n      valued = +data.value && (root.value = data.value),\n      node,\n      nodes = [root],\n      child,\n      childs,\n      i,\n      n;\n\n  if (children == null) children = defaultChildren;\n\n  while (node = nodes.pop()) {\n    if (valued) node.value = +node.data.value;\n    if ((childs = children(node.data)) && (n = childs.length)) {\n      node.children = new Array(n);\n      for (i = n - 1; i >= 0; --i) {\n        nodes.push(child = node.children[i] = new Node(childs[i]));\n        child.parent = node;\n        child.depth = node.depth + 1;\n      }\n    }\n  }\n\n  return root.eachBefore(computeHeight);\n}\n\nfunction node_copy() {\n  return hierarchy(this).eachBefore(copyData);\n}\n\nfunction defaultChildren(d) {\n  return d.children;\n}\n\nfunction copyData(node) {\n  node.data = node.data.data;\n}\n\nfunction computeHeight(node) {\n  var height = 0;\n  do node.height = height;\n  while ((node = node.parent) && (node.height < ++height));\n}\n\nfunction Node(data) {\n  this.data = data;\n  this.depth =\n  this.height = 0;\n  this.parent = null;\n}\n\nNode.prototype = hierarchy.prototype = {\n  constructor: Node,\n  count: node_count,\n  each: node_each,\n  eachAfter: node_eachAfter,\n  eachBefore: node_eachBefore,\n  sum: node_sum,\n  sort: node_sort,\n  path: node_path,\n  ancestors: node_ancestors,\n  descendants: node_descendants,\n  leaves: node_leaves,\n  links: node_links,\n  copy: node_copy\n};\n\nfunction Node$2(value) {\n  this._ = value;\n  this.next = null;\n}\n\nvar shuffle$1 = function(array) {\n  var i,\n      n = (array = array.slice()).length,\n      head = null,\n      node = head;\n\n  while (n) {\n    var next = new Node$2(array[n - 1]);\n    if (node) node = node.next = next;\n    else node = head = next;\n    array[i] = array[--n];\n  }\n\n  return {\n    head: head,\n    tail: node\n  };\n};\n\nvar enclose = function(circles) {\n  return encloseN(shuffle$1(circles), []);\n};\n\nfunction encloses(a, b) {\n  var dx = b.x - a.x,\n      dy = b.y - a.y,\n      dr = a.r - b.r;\n  return dr * dr + 1e-6 > dx * dx + dy * dy;\n}\n\n// Returns the smallest circle that contains circles L and intersects circles B.\nfunction encloseN(L, B) {\n  var circle,\n      l0 = null,\n      l1 = L.head,\n      l2,\n      p1;\n\n  switch (B.length) {\n    case 1: circle = enclose1(B[0]); break;\n    case 2: circle = enclose2(B[0], B[1]); break;\n    case 3: circle = enclose3(B[0], B[1], B[2]); break;\n  }\n\n  while (l1) {\n    p1 = l1._, l2 = l1.next;\n    if (!circle || !encloses(circle, p1)) {\n\n      // Temporarily truncate L before l1.\n      if (l0) L.tail = l0, l0.next = null;\n      else L.head = L.tail = null;\n\n      B.push(p1);\n      circle = encloseN(L, B); // Note: reorders L!\n      B.pop();\n\n      // Move l1 to the front of L and reconnect the truncated list L.\n      if (L.head) l1.next = L.head, L.head = l1;\n      else l1.next = null, L.head = L.tail = l1;\n      l0 = L.tail, l0.next = l2;\n\n    } else {\n      l0 = l1;\n    }\n    l1 = l2;\n  }\n\n  L.tail = l0;\n  return circle;\n}\n\nfunction enclose1(a) {\n  return {\n    x: a.x,\n    y: a.y,\n    r: a.r\n  };\n}\n\nfunction enclose2(a, b) {\n  var x1 = a.x, y1 = a.y, r1 = a.r,\n      x2 = b.x, y2 = b.y, r2 = b.r,\n      x21 = x2 - x1, y21 = y2 - y1, r21 = r2 - r1,\n      l = Math.sqrt(x21 * x21 + y21 * y21);\n  return {\n    x: (x1 + x2 + x21 / l * r21) / 2,\n    y: (y1 + y2 + y21 / l * r21) / 2,\n    r: (l + r1 + r2) / 2\n  };\n}\n\nfunction enclose3(a, b, c) {\n  var x1 = a.x, y1 = a.y, r1 = a.r,\n      x2 = b.x, y2 = b.y, r2 = b.r,\n      x3 = c.x, y3 = c.y, r3 = c.r,\n      a2 = 2 * (x1 - x2),\n      b2 = 2 * (y1 - y2),\n      c2 = 2 * (r2 - r1),\n      d2 = x1 * x1 + y1 * y1 - r1 * r1 - x2 * x2 - y2 * y2 + r2 * r2,\n      a3 = 2 * (x1 - x3),\n      b3 = 2 * (y1 - y3),\n      c3 = 2 * (r3 - r1),\n      d3 = x1 * x1 + y1 * y1 - r1 * r1 - x3 * x3 - y3 * y3 + r3 * r3,\n      ab = a3 * b2 - a2 * b3,\n      xa = (b2 * d3 - b3 * d2) / ab - x1,\n      xb = (b3 * c2 - b2 * c3) / ab,\n      ya = (a3 * d2 - a2 * d3) / ab - y1,\n      yb = (a2 * c3 - a3 * c2) / ab,\n      A = xb * xb + yb * yb - 1,\n      B = 2 * (xa * xb + ya * yb + r1),\n      C = xa * xa + ya * ya - r1 * r1,\n      r = (-B - Math.sqrt(B * B - 4 * A * C)) / (2 * A);\n  return {\n    x: xa + xb * r + x1,\n    y: ya + yb * r + y1,\n    r: r\n  };\n}\n\nfunction place(a, b, c) {\n  var ax = a.x,\n      ay = a.y,\n      da = b.r + c.r,\n      db = a.r + c.r,\n      dx = b.x - ax,\n      dy = b.y - ay,\n      dc = dx * dx + dy * dy;\n  if (dc) {\n    var x = 0.5 + ((db *= db) - (da *= da)) / (2 * dc),\n        y = Math.sqrt(Math.max(0, 2 * da * (db + dc) - (db -= dc) * db - da * da)) / (2 * dc);\n    c.x = ax + x * dx + y * dy;\n    c.y = ay + x * dy - y * dx;\n  } else {\n    c.x = ax + db;\n    c.y = ay;\n  }\n}\n\nfunction intersects(a, b) {\n  var dx = b.x - a.x,\n      dy = b.y - a.y,\n      dr = a.r + b.r;\n  return dr * dr - 1e-6 > dx * dx + dy * dy;\n}\n\nfunction distance2(node, x, y) {\n  var a = node._,\n      b = node.next._,\n      ab = a.r + b.r,\n      dx = (a.x * b.r + b.x * a.r) / ab - x,\n      dy = (a.y * b.r + b.y * a.r) / ab - y;\n  return dx * dx + dy * dy;\n}\n\nfunction Node$1(circle) {\n  this._ = circle;\n  this.next = null;\n  this.previous = null;\n}\n\nfunction packEnclose(circles) {\n  if (!(n = circles.length)) return 0;\n\n  var a, b, c, n;\n\n  // Place the first circle.\n  a = circles[0], a.x = 0, a.y = 0;\n  if (!(n > 1)) return a.r;\n\n  // Place the second circle.\n  b = circles[1], a.x = -b.r, b.x = a.r, b.y = 0;\n  if (!(n > 2)) return a.r + b.r;\n\n  // Place the third circle.\n  place(b, a, c = circles[2]);\n\n  // Initialize the weighted centroid.\n  var aa = a.r * a.r,\n      ba = b.r * b.r,\n      ca = c.r * c.r,\n      oa = aa + ba + ca,\n      ox = aa * a.x + ba * b.x + ca * c.x,\n      oy = aa * a.y + ba * b.y + ca * c.y,\n      cx, cy, i, j, k, sj, sk;\n\n  // Initialize the front-chain using the first three circles a, b and c.\n  a = new Node$1(a), b = new Node$1(b), c = new Node$1(c);\n  a.next = c.previous = b;\n  b.next = a.previous = c;\n  c.next = b.previous = a;\n\n  // Attempt to place each remaining circle…\n  pack: for (i = 3; i < n; ++i) {\n    place(a._, b._, c = circles[i]), c = new Node$1(c);\n\n    // Find the closest intersecting circle on the front-chain, if any.\n    // “Closeness” is determined by linear distance along the front-chain.\n    // “Ahead” or “behind” is likewise determined by linear distance.\n    j = b.next, k = a.previous, sj = b._.r, sk = a._.r;\n    do {\n      if (sj <= sk) {\n        if (intersects(j._, c._)) {\n          b = j, a.next = b, b.previous = a, --i;\n          continue pack;\n        }\n        sj += j._.r, j = j.next;\n      } else {\n        if (intersects(k._, c._)) {\n          a = k, a.next = b, b.previous = a, --i;\n          continue pack;\n        }\n        sk += k._.r, k = k.previous;\n      }\n    } while (j !== k.next);\n\n    // Success! Insert the new circle c between a and b.\n    c.previous = a, c.next = b, a.next = b.previous = b = c;\n\n    // Update the weighted centroid.\n    oa += ca = c._.r * c._.r;\n    ox += ca * c._.x;\n    oy += ca * c._.y;\n\n    // Compute the new closest circle pair to the centroid.\n    aa = distance2(a, cx = ox / oa, cy = oy / oa);\n    while ((c = c.next) !== b) {\n      if ((ca = distance2(c, cx, cy)) < aa) {\n        a = c, aa = ca;\n      }\n    }\n    b = a.next;\n  }\n\n  // Compute the enclosing circle of the front chain.\n  a = [b._], c = b; while ((c = c.next) !== b) a.push(c._); c = enclose(a);\n\n  // Translate the circles to put the enclosing circle around the origin.\n  for (i = 0; i < n; ++i) a = circles[i], a.x -= c.x, a.y -= c.y;\n\n  return c.r;\n}\n\nvar siblings = function(circles) {\n  packEnclose(circles);\n  return circles;\n};\n\nfunction optional(f) {\n  return f == null ? null : required(f);\n}\n\nfunction required(f) {\n  if (typeof f !== \"function\") throw new Error;\n  return f;\n}\n\nfunction constantZero() {\n  return 0;\n}\n\nvar constant$8 = function(x) {\n  return function() {\n    return x;\n  };\n};\n\nfunction defaultRadius$1(d) {\n  return Math.sqrt(d.value);\n}\n\nvar index$2 = function() {\n  var radius = null,\n      dx = 1,\n      dy = 1,\n      padding = constantZero;\n\n  function pack(root) {\n    root.x = dx / 2, root.y = dy / 2;\n    if (radius) {\n      root.eachBefore(radiusLeaf(radius))\n          .eachAfter(packChildren(padding, 0.5))\n          .eachBefore(translateChild(1));\n    } else {\n      root.eachBefore(radiusLeaf(defaultRadius$1))\n          .eachAfter(packChildren(constantZero, 1))\n          .eachAfter(packChildren(padding, root.r / Math.min(dx, dy)))\n          .eachBefore(translateChild(Math.min(dx, dy) / (2 * root.r)));\n    }\n    return root;\n  }\n\n  pack.radius = function(x) {\n    return arguments.length ? (radius = optional(x), pack) : radius;\n  };\n\n  pack.size = function(x) {\n    return arguments.length ? (dx = +x[0], dy = +x[1], pack) : [dx, dy];\n  };\n\n  pack.padding = function(x) {\n    return arguments.length ? (padding = typeof x === \"function\" ? x : constant$8(+x), pack) : padding;\n  };\n\n  return pack;\n};\n\nfunction radiusLeaf(radius) {\n  return function(node) {\n    if (!node.children) {\n      node.r = Math.max(0, +radius(node) || 0);\n    }\n  };\n}\n\nfunction packChildren(padding, k) {\n  return function(node) {\n    if (children = node.children) {\n      var children,\n          i,\n          n = children.length,\n          r = padding(node) * k || 0,\n          e;\n\n      if (r) for (i = 0; i < n; ++i) children[i].r += r;\n      e = packEnclose(children);\n      if (r) for (i = 0; i < n; ++i) children[i].r -= r;\n      node.r = e + r;\n    }\n  };\n}\n\nfunction translateChild(k) {\n  return function(node) {\n    var parent = node.parent;\n    node.r *= k;\n    if (parent) {\n      node.x = parent.x + k * node.x;\n      node.y = parent.y + k * node.y;\n    }\n  };\n}\n\nvar roundNode = function(node) {\n  node.x0 = Math.round(node.x0);\n  node.y0 = Math.round(node.y0);\n  node.x1 = Math.round(node.x1);\n  node.y1 = Math.round(node.y1);\n};\n\nvar treemapDice = function(parent, x0, y0, x1, y1) {\n  var nodes = parent.children,\n      node,\n      i = -1,\n      n = nodes.length,\n      k = parent.value && (x1 - x0) / parent.value;\n\n  while (++i < n) {\n    node = nodes[i], node.y0 = y0, node.y1 = y1;\n    node.x0 = x0, node.x1 = x0 += node.value * k;\n  }\n};\n\nvar partition = function() {\n  var dx = 1,\n      dy = 1,\n      padding = 0,\n      round = false;\n\n  function partition(root) {\n    var n = root.height + 1;\n    root.x0 =\n    root.y0 = padding;\n    root.x1 = dx;\n    root.y1 = dy / n;\n    root.eachBefore(positionNode(dy, n));\n    if (round) root.eachBefore(roundNode);\n    return root;\n  }\n\n  function positionNode(dy, n) {\n    return function(node) {\n      if (node.children) {\n        treemapDice(node, node.x0, dy * (node.depth + 1) / n, node.x1, dy * (node.depth + 2) / n);\n      }\n      var x0 = node.x0,\n          y0 = node.y0,\n          x1 = node.x1 - padding,\n          y1 = node.y1 - padding;\n      if (x1 < x0) x0 = x1 = (x0 + x1) / 2;\n      if (y1 < y0) y0 = y1 = (y0 + y1) / 2;\n      node.x0 = x0;\n      node.y0 = y0;\n      node.x1 = x1;\n      node.y1 = y1;\n    };\n  }\n\n  partition.round = function(x) {\n    return arguments.length ? (round = !!x, partition) : round;\n  };\n\n  partition.size = function(x) {\n    return arguments.length ? (dx = +x[0], dy = +x[1], partition) : [dx, dy];\n  };\n\n  partition.padding = function(x) {\n    return arguments.length ? (padding = +x, partition) : padding;\n  };\n\n  return partition;\n};\n\nvar keyPrefix$1 = \"$\";\nvar preroot = {depth: -1};\nvar ambiguous = {};\n\nfunction defaultId(d) {\n  return d.id;\n}\n\nfunction defaultParentId(d) {\n  return d.parentId;\n}\n\nvar stratify = function() {\n  var id = defaultId,\n      parentId = defaultParentId;\n\n  function stratify(data) {\n    var d,\n        i,\n        n = data.length,\n        root,\n        parent,\n        node,\n        nodes = new Array(n),\n        nodeId,\n        nodeKey,\n        nodeByKey = {};\n\n    for (i = 0; i < n; ++i) {\n      d = data[i], node = nodes[i] = new Node(d);\n      if ((nodeId = id(d, i, data)) != null && (nodeId += \"\")) {\n        nodeKey = keyPrefix$1 + (node.id = nodeId);\n        nodeByKey[nodeKey] = nodeKey in nodeByKey ? ambiguous : node;\n      }\n    }\n\n    for (i = 0; i < n; ++i) {\n      node = nodes[i], nodeId = parentId(data[i], i, data);\n      if (nodeId == null || !(nodeId += \"\")) {\n        if (root) throw new Error(\"multiple roots\");\n        root = node;\n      } else {\n        parent = nodeByKey[keyPrefix$1 + nodeId];\n        if (!parent) throw new Error(\"missing: \" + nodeId);\n        if (parent === ambiguous) throw new Error(\"ambiguous: \" + nodeId);\n        if (parent.children) parent.children.push(node);\n        else parent.children = [node];\n        node.parent = parent;\n      }\n    }\n\n    if (!root) throw new Error(\"no root\");\n    root.parent = preroot;\n    root.eachBefore(function(node) { node.depth = node.parent.depth + 1; --n; }).eachBefore(computeHeight);\n    root.parent = null;\n    if (n > 0) throw new Error(\"cycle\");\n\n    return root;\n  }\n\n  stratify.id = function(x) {\n    return arguments.length ? (id = required(x), stratify) : id;\n  };\n\n  stratify.parentId = function(x) {\n    return arguments.length ? (parentId = required(x), stratify) : parentId;\n  };\n\n  return stratify;\n};\n\nfunction defaultSeparation$1(a, b) {\n  return a.parent === b.parent ? 1 : 2;\n}\n\n// function radialSeparation(a, b) {\n//   return (a.parent === b.parent ? 1 : 2) / a.depth;\n// }\n\n// This function is used to traverse the left contour of a subtree (or\n// subforest). It returns the successor of v on this contour. This successor is\n// either given by the leftmost child of v or by the thread of v. The function\n// returns null if and only if v is on the highest level of its subtree.\nfunction nextLeft(v) {\n  var children = v.children;\n  return children ? children[0] : v.t;\n}\n\n// This function works analogously to nextLeft.\nfunction nextRight(v) {\n  var children = v.children;\n  return children ? children[children.length - 1] : v.t;\n}\n\n// Shifts the current subtree rooted at w+. This is done by increasing\n// prelim(w+) and mod(w+) by shift.\nfunction moveSubtree(wm, wp, shift) {\n  var change = shift / (wp.i - wm.i);\n  wp.c -= change;\n  wp.s += shift;\n  wm.c += change;\n  wp.z += shift;\n  wp.m += shift;\n}\n\n// All other shifts, applied to the smaller subtrees between w- and w+, are\n// performed by this function. To prepare the shifts, we have to adjust\n// change(w+), shift(w+), and change(w-).\nfunction executeShifts(v) {\n  var shift = 0,\n      change = 0,\n      children = v.children,\n      i = children.length,\n      w;\n  while (--i >= 0) {\n    w = children[i];\n    w.z += shift;\n    w.m += shift;\n    shift += w.s + (change += w.c);\n  }\n}\n\n// If vi-’s ancestor is a sibling of v, returns vi-’s ancestor. Otherwise,\n// returns the specified (default) ancestor.\nfunction nextAncestor(vim, v, ancestor) {\n  return vim.a.parent === v.parent ? vim.a : ancestor;\n}\n\nfunction TreeNode(node, i) {\n  this._ = node;\n  this.parent = null;\n  this.children = null;\n  this.A = null; // default ancestor\n  this.a = this; // ancestor\n  this.z = 0; // prelim\n  this.m = 0; // mod\n  this.c = 0; // change\n  this.s = 0; // shift\n  this.t = null; // thread\n  this.i = i; // number\n}\n\nTreeNode.prototype = Object.create(Node.prototype);\n\nfunction treeRoot(root) {\n  var tree = new TreeNode(root, 0),\n      node,\n      nodes = [tree],\n      child,\n      children,\n      i,\n      n;\n\n  while (node = nodes.pop()) {\n    if (children = node._.children) {\n      node.children = new Array(n = children.length);\n      for (i = n - 1; i >= 0; --i) {\n        nodes.push(child = node.children[i] = new TreeNode(children[i], i));\n        child.parent = node;\n      }\n    }\n  }\n\n  (tree.parent = new TreeNode(null, 0)).children = [tree];\n  return tree;\n}\n\n// Node-link tree diagram using the Reingold-Tilford \"tidy\" algorithm\nvar tree = function() {\n  var separation = defaultSeparation$1,\n      dx = 1,\n      dy = 1,\n      nodeSize = null;\n\n  function tree(root) {\n    var t = treeRoot(root);\n\n    // Compute the layout using Buchheim et al.’s algorithm.\n    t.eachAfter(firstWalk), t.parent.m = -t.z;\n    t.eachBefore(secondWalk);\n\n    // If a fixed node size is specified, scale x and y.\n    if (nodeSize) root.eachBefore(sizeNode);\n\n    // If a fixed tree size is specified, scale x and y based on the extent.\n    // Compute the left-most, right-most, and depth-most nodes for extents.\n    else {\n      var left = root,\n          right = root,\n          bottom = root;\n      root.eachBefore(function(node) {\n        if (node.x < left.x) left = node;\n        if (node.x > right.x) right = node;\n        if (node.depth > bottom.depth) bottom = node;\n      });\n      var s = left === right ? 1 : separation(left, right) / 2,\n          tx = s - left.x,\n          kx = dx / (right.x + s + tx),\n          ky = dy / (bottom.depth || 1);\n      root.eachBefore(function(node) {\n        node.x = (node.x + tx) * kx;\n        node.y = node.depth * ky;\n      });\n    }\n\n    return root;\n  }\n\n  // Computes a preliminary x-coordinate for v. Before that, FIRST WALK is\n  // applied recursively to the children of v, as well as the function\n  // APPORTION. After spacing out the children by calling EXECUTE SHIFTS, the\n  // node v is placed to the midpoint of its outermost children.\n  function firstWalk(v) {\n    var children = v.children,\n        siblings = v.parent.children,\n        w = v.i ? siblings[v.i - 1] : null;\n    if (children) {\n      executeShifts(v);\n      var midpoint = (children[0].z + children[children.length - 1].z) / 2;\n      if (w) {\n        v.z = w.z + separation(v._, w._);\n        v.m = v.z - midpoint;\n      } else {\n        v.z = midpoint;\n      }\n    } else if (w) {\n      v.z = w.z + separation(v._, w._);\n    }\n    v.parent.A = apportion(v, w, v.parent.A || siblings[0]);\n  }\n\n  // Computes all real x-coordinates by summing up the modifiers recursively.\n  function secondWalk(v) {\n    v._.x = v.z + v.parent.m;\n    v.m += v.parent.m;\n  }\n\n  // The core of the algorithm. Here, a new subtree is combined with the\n  // previous subtrees. Threads are used to traverse the inside and outside\n  // contours of the left and right subtree up to the highest common level. The\n  // vertices used for the traversals are vi+, vi-, vo-, and vo+, where the\n  // superscript o means outside and i means inside, the subscript - means left\n  // subtree and + means right subtree. For summing up the modifiers along the\n  // contour, we use respective variables si+, si-, so-, and so+. Whenever two\n  // nodes of the inside contours conflict, we compute the left one of the\n  // greatest uncommon ancestors using the function ANCESTOR and call MOVE\n  // SUBTREE to shift the subtree and prepare the shifts of smaller subtrees.\n  // Finally, we add a new thread (if necessary).\n  function apportion(v, w, ancestor) {\n    if (w) {\n      var vip = v,\n          vop = v,\n          vim = w,\n          vom = vip.parent.children[0],\n          sip = vip.m,\n          sop = vop.m,\n          sim = vim.m,\n          som = vom.m,\n          shift;\n      while (vim = nextRight(vim), vip = nextLeft(vip), vim && vip) {\n        vom = nextLeft(vom);\n        vop = nextRight(vop);\n        vop.a = v;\n        shift = vim.z + sim - vip.z - sip + separation(vim._, vip._);\n        if (shift > 0) {\n          moveSubtree(nextAncestor(vim, v, ancestor), v, shift);\n          sip += shift;\n          sop += shift;\n        }\n        sim += vim.m;\n        sip += vip.m;\n        som += vom.m;\n        sop += vop.m;\n      }\n      if (vim && !nextRight(vop)) {\n        vop.t = vim;\n        vop.m += sim - sop;\n      }\n      if (vip && !nextLeft(vom)) {\n        vom.t = vip;\n        vom.m += sip - som;\n        ancestor = v;\n      }\n    }\n    return ancestor;\n  }\n\n  function sizeNode(node) {\n    node.x *= dx;\n    node.y = node.depth * dy;\n  }\n\n  tree.separation = function(x) {\n    return arguments.length ? (separation = x, tree) : separation;\n  };\n\n  tree.size = function(x) {\n    return arguments.length ? (nodeSize = false, dx = +x[0], dy = +x[1], tree) : (nodeSize ? null : [dx, dy]);\n  };\n\n  tree.nodeSize = function(x) {\n    return arguments.length ? (nodeSize = true, dx = +x[0], dy = +x[1], tree) : (nodeSize ? [dx, dy] : null);\n  };\n\n  return tree;\n};\n\nvar treemapSlice = function(parent, x0, y0, x1, y1) {\n  var nodes = parent.children,\n      node,\n      i = -1,\n      n = nodes.length,\n      k = parent.value && (y1 - y0) / parent.value;\n\n  while (++i < n) {\n    node = nodes[i], node.x0 = x0, node.x1 = x1;\n    node.y0 = y0, node.y1 = y0 += node.value * k;\n  }\n};\n\nvar phi = (1 + Math.sqrt(5)) / 2;\n\nfunction squarifyRatio(ratio, parent, x0, y0, x1, y1) {\n  var rows = [],\n      nodes = parent.children,\n      row,\n      nodeValue,\n      i0 = 0,\n      i1 = 0,\n      n = nodes.length,\n      dx, dy,\n      value = parent.value,\n      sumValue,\n      minValue,\n      maxValue,\n      newRatio,\n      minRatio,\n      alpha,\n      beta;\n\n  while (i0 < n) {\n    dx = x1 - x0, dy = y1 - y0;\n\n    // Find the next non-empty node.\n    do sumValue = nodes[i1++].value; while (!sumValue && i1 < n);\n    minValue = maxValue = sumValue;\n    alpha = Math.max(dy / dx, dx / dy) / (value * ratio);\n    beta = sumValue * sumValue * alpha;\n    minRatio = Math.max(maxValue / beta, beta / minValue);\n\n    // Keep adding nodes while the aspect ratio maintains or improves.\n    for (; i1 < n; ++i1) {\n      sumValue += nodeValue = nodes[i1].value;\n      if (nodeValue < minValue) minValue = nodeValue;\n      if (nodeValue > maxValue) maxValue = nodeValue;\n      beta = sumValue * sumValue * alpha;\n      newRatio = Math.max(maxValue / beta, beta / minValue);\n      if (newRatio > minRatio) { sumValue -= nodeValue; break; }\n      minRatio = newRatio;\n    }\n\n    // Position and record the row orientation.\n    rows.push(row = {value: sumValue, dice: dx < dy, children: nodes.slice(i0, i1)});\n    if (row.dice) treemapDice(row, x0, y0, x1, value ? y0 += dy * sumValue / value : y1);\n    else treemapSlice(row, x0, y0, value ? x0 += dx * sumValue / value : x1, y1);\n    value -= sumValue, i0 = i1;\n  }\n\n  return rows;\n}\n\nvar squarify = ((function custom(ratio) {\n\n  function squarify(parent, x0, y0, x1, y1) {\n    squarifyRatio(ratio, parent, x0, y0, x1, y1);\n  }\n\n  squarify.ratio = function(x) {\n    return custom((x = +x) > 1 ? x : 1);\n  };\n\n  return squarify;\n}))(phi);\n\nvar index$3 = function() {\n  var tile = squarify,\n      round = false,\n      dx = 1,\n      dy = 1,\n      paddingStack = [0],\n      paddingInner = constantZero,\n      paddingTop = constantZero,\n      paddingRight = constantZero,\n      paddingBottom = constantZero,\n      paddingLeft = constantZero;\n\n  function treemap(root) {\n    root.x0 =\n    root.y0 = 0;\n    root.x1 = dx;\n    root.y1 = dy;\n    root.eachBefore(positionNode);\n    paddingStack = [0];\n    if (round) root.eachBefore(roundNode);\n    return root;\n  }\n\n  function positionNode(node) {\n    var p = paddingStack[node.depth],\n        x0 = node.x0 + p,\n        y0 = node.y0 + p,\n        x1 = node.x1 - p,\n        y1 = node.y1 - p;\n    if (x1 < x0) x0 = x1 = (x0 + x1) / 2;\n    if (y1 < y0) y0 = y1 = (y0 + y1) / 2;\n    node.x0 = x0;\n    node.y0 = y0;\n    node.x1 = x1;\n    node.y1 = y1;\n    if (node.children) {\n      p = paddingStack[node.depth + 1] = paddingInner(node) / 2;\n      x0 += paddingLeft(node) - p;\n      y0 += paddingTop(node) - p;\n      x1 -= paddingRight(node) - p;\n      y1 -= paddingBottom(node) - p;\n      if (x1 < x0) x0 = x1 = (x0 + x1) / 2;\n      if (y1 < y0) y0 = y1 = (y0 + y1) / 2;\n      tile(node, x0, y0, x1, y1);\n    }\n  }\n\n  treemap.round = function(x) {\n    return arguments.length ? (round = !!x, treemap) : round;\n  };\n\n  treemap.size = function(x) {\n    return arguments.length ? (dx = +x[0], dy = +x[1], treemap) : [dx, dy];\n  };\n\n  treemap.tile = function(x) {\n    return arguments.length ? (tile = required(x), treemap) : tile;\n  };\n\n  treemap.padding = function(x) {\n    return arguments.length ? treemap.paddingInner(x).paddingOuter(x) : treemap.paddingInner();\n  };\n\n  treemap.paddingInner = function(x) {\n    return arguments.length ? (paddingInner = typeof x === \"function\" ? x : constant$8(+x), treemap) : paddingInner;\n  };\n\n  treemap.paddingOuter = function(x) {\n    return arguments.length ? treemap.paddingTop(x).paddingRight(x).paddingBottom(x).paddingLeft(x) : treemap.paddingTop();\n  };\n\n  treemap.paddingTop = function(x) {\n    return arguments.length ? (paddingTop = typeof x === \"function\" ? x : constant$8(+x), treemap) : paddingTop;\n  };\n\n  treemap.paddingRight = function(x) {\n    return arguments.length ? (paddingRight = typeof x === \"function\" ? x : constant$8(+x), treemap) : paddingRight;\n  };\n\n  treemap.paddingBottom = function(x) {\n    return arguments.length ? (paddingBottom = typeof x === \"function\" ? x : constant$8(+x), treemap) : paddingBottom;\n  };\n\n  treemap.paddingLeft = function(x) {\n    return arguments.length ? (paddingLeft = typeof x === \"function\" ? x : constant$8(+x), treemap) : paddingLeft;\n  };\n\n  return treemap;\n};\n\nvar binary = function(parent, x0, y0, x1, y1) {\n  var nodes = parent.children,\n      i, n = nodes.length,\n      sum, sums = new Array(n + 1);\n\n  for (sums[0] = sum = i = 0; i < n; ++i) {\n    sums[i + 1] = sum += nodes[i].value;\n  }\n\n  partition(0, n, parent.value, x0, y0, x1, y1);\n\n  function partition(i, j, value, x0, y0, x1, y1) {\n    if (i >= j - 1) {\n      var node = nodes[i];\n      node.x0 = x0, node.y0 = y0;\n      node.x1 = x1, node.y1 = y1;\n      return;\n    }\n\n    var valueOffset = sums[i],\n        valueTarget = (value / 2) + valueOffset,\n        k = i + 1,\n        hi = j - 1;\n\n    while (k < hi) {\n      var mid = k + hi >>> 1;\n      if (sums[mid] < valueTarget) k = mid + 1;\n      else hi = mid;\n    }\n\n    if ((valueTarget - sums[k - 1]) < (sums[k] - valueTarget) && i + 1 < k) --k;\n\n    var valueLeft = sums[k] - valueOffset,\n        valueRight = value - valueLeft;\n\n    if ((x1 - x0) > (y1 - y0)) {\n      var xk = (x0 * valueRight + x1 * valueLeft) / value;\n      partition(i, k, valueLeft, x0, y0, xk, y1);\n      partition(k, j, valueRight, xk, y0, x1, y1);\n    } else {\n      var yk = (y0 * valueRight + y1 * valueLeft) / value;\n      partition(i, k, valueLeft, x0, y0, x1, yk);\n      partition(k, j, valueRight, x0, yk, x1, y1);\n    }\n  }\n};\n\nvar sliceDice = function(parent, x0, y0, x1, y1) {\n  (parent.depth & 1 ? treemapSlice : treemapDice)(parent, x0, y0, x1, y1);\n};\n\nvar resquarify = ((function custom(ratio) {\n\n  function resquarify(parent, x0, y0, x1, y1) {\n    if ((rows = parent._squarify) && (rows.ratio === ratio)) {\n      var rows,\n          row,\n          nodes,\n          i,\n          j = -1,\n          n,\n          m = rows.length,\n          value = parent.value;\n\n      while (++j < m) {\n        row = rows[j], nodes = row.children;\n        for (i = row.value = 0, n = nodes.length; i < n; ++i) row.value += nodes[i].value;\n        if (row.dice) treemapDice(row, x0, y0, x1, y0 += (y1 - y0) * row.value / value);\n        else treemapSlice(row, x0, y0, x0 += (x1 - x0) * row.value / value, y1);\n        value -= row.value;\n      }\n    } else {\n      parent._squarify = rows = squarifyRatio(ratio, parent, x0, y0, x1, y1);\n      rows.ratio = ratio;\n    }\n  }\n\n  resquarify.ratio = function(x) {\n    return custom((x = +x) > 1 ? x : 1);\n  };\n\n  return resquarify;\n}))(phi);\n\nvar area$1 = function(polygon) {\n  var i = -1,\n      n = polygon.length,\n      a,\n      b = polygon[n - 1],\n      area = 0;\n\n  while (++i < n) {\n    a = b;\n    b = polygon[i];\n    area += a[1] * b[0] - a[0] * b[1];\n  }\n\n  return area / 2;\n};\n\nvar centroid$1 = function(polygon) {\n  var i = -1,\n      n = polygon.length,\n      x = 0,\n      y = 0,\n      a,\n      b = polygon[n - 1],\n      c,\n      k = 0;\n\n  while (++i < n) {\n    a = b;\n    b = polygon[i];\n    k += c = a[0] * b[1] - b[0] * a[1];\n    x += (a[0] + b[0]) * c;\n    y += (a[1] + b[1]) * c;\n  }\n\n  return k *= 3, [x / k, y / k];\n};\n\n// Returns the 2D cross product of AB and AC vectors, i.e., the z-component of\n// the 3D cross product in a quadrant I Cartesian coordinate system (+x is\n// right, +y is up). Returns a positive value if ABC is counter-clockwise,\n// negative if clockwise, and zero if the points are collinear.\nvar cross$1 = function(a, b, c) {\n  return (b[0] - a[0]) * (c[1] - a[1]) - (b[1] - a[1]) * (c[0] - a[0]);\n};\n\nfunction lexicographicOrder(a, b) {\n  return a[0] - b[0] || a[1] - b[1];\n}\n\n// Computes the upper convex hull per the monotone chain algorithm.\n// Assumes points.length >= 3, is sorted by x, unique in y.\n// Returns an array of indices into points in left-to-right order.\nfunction computeUpperHullIndexes(points) {\n  var n = points.length,\n      indexes = [0, 1],\n      size = 2;\n\n  for (var i = 2; i < n; ++i) {\n    while (size > 1 && cross$1(points[indexes[size - 2]], points[indexes[size - 1]], points[i]) <= 0) --size;\n    indexes[size++] = i;\n  }\n\n  return indexes.slice(0, size); // remove popped points\n}\n\nvar hull = function(points) {\n  if ((n = points.length) < 3) return null;\n\n  var i,\n      n,\n      sortedPoints = new Array(n),\n      flippedPoints = new Array(n);\n\n  for (i = 0; i < n; ++i) sortedPoints[i] = [+points[i][0], +points[i][1], i];\n  sortedPoints.sort(lexicographicOrder);\n  for (i = 0; i < n; ++i) flippedPoints[i] = [sortedPoints[i][0], -sortedPoints[i][1]];\n\n  var upperIndexes = computeUpperHullIndexes(sortedPoints),\n      lowerIndexes = computeUpperHullIndexes(flippedPoints);\n\n  // Construct the hull polygon, removing possible duplicate endpoints.\n  var skipLeft = lowerIndexes[0] === upperIndexes[0],\n      skipRight = lowerIndexes[lowerIndexes.length - 1] === upperIndexes[upperIndexes.length - 1],\n      hull = [];\n\n  // Add upper hull in right-to-l order.\n  // Then add lower hull in left-to-right order.\n  for (i = upperIndexes.length - 1; i >= 0; --i) hull.push(points[sortedPoints[upperIndexes[i]][2]]);\n  for (i = +skipLeft; i < lowerIndexes.length - skipRight; ++i) hull.push(points[sortedPoints[lowerIndexes[i]][2]]);\n\n  return hull;\n};\n\nvar contains$1 = function(polygon, point) {\n  var n = polygon.length,\n      p = polygon[n - 1],\n      x = point[0], y = point[1],\n      x0 = p[0], y0 = p[1],\n      x1, y1,\n      inside = false;\n\n  for (var i = 0; i < n; ++i) {\n    p = polygon[i], x1 = p[0], y1 = p[1];\n    if (((y1 > y) !== (y0 > y)) && (x < (x0 - x1) * (y - y1) / (y0 - y1) + x1)) inside = !inside;\n    x0 = x1, y0 = y1;\n  }\n\n  return inside;\n};\n\nvar length$2 = function(polygon) {\n  var i = -1,\n      n = polygon.length,\n      b = polygon[n - 1],\n      xa,\n      ya,\n      xb = b[0],\n      yb = b[1],\n      perimeter = 0;\n\n  while (++i < n) {\n    xa = xb;\n    ya = yb;\n    b = polygon[i];\n    xb = b[0];\n    yb = b[1];\n    xa -= xb;\n    ya -= yb;\n    perimeter += Math.sqrt(xa * xa + ya * ya);\n  }\n\n  return perimeter;\n};\n\nvar slice$3 = [].slice;\n\nvar noabort = {};\n\nfunction Queue(size) {\n  this._size = size;\n  this._call =\n  this._error = null;\n  this._tasks = [];\n  this._data = [];\n  this._waiting =\n  this._active =\n  this._ended =\n  this._start = 0; // inside a synchronous task callback?\n}\n\nQueue.prototype = queue.prototype = {\n  constructor: Queue,\n  defer: function(callback) {\n    if (typeof callback !== \"function\") throw new Error(\"invalid callback\");\n    if (this._call) throw new Error(\"defer after await\");\n    if (this._error != null) return this;\n    var t = slice$3.call(arguments, 1);\n    t.push(callback);\n    ++this._waiting, this._tasks.push(t);\n    poke$1(this);\n    return this;\n  },\n  abort: function() {\n    if (this._error == null) abort(this, new Error(\"abort\"));\n    return this;\n  },\n  await: function(callback) {\n    if (typeof callback !== \"function\") throw new Error(\"invalid callback\");\n    if (this._call) throw new Error(\"multiple await\");\n    this._call = function(error, results) { callback.apply(null, [error].concat(results)); };\n    maybeNotify(this);\n    return this;\n  },\n  awaitAll: function(callback) {\n    if (typeof callback !== \"function\") throw new Error(\"invalid callback\");\n    if (this._call) throw new Error(\"multiple await\");\n    this._call = callback;\n    maybeNotify(this);\n    return this;\n  }\n};\n\nfunction poke$1(q) {\n  if (!q._start) {\n    try { start$1(q); } // let the current task complete\n    catch (e) {\n      if (q._tasks[q._ended + q._active - 1]) abort(q, e); // task errored synchronously\n      else if (!q._data) throw e; // await callback errored synchronously\n    }\n  }\n}\n\nfunction start$1(q) {\n  while (q._start = q._waiting && q._active < q._size) {\n    var i = q._ended + q._active,\n        t = q._tasks[i],\n        j = t.length - 1,\n        c = t[j];\n    t[j] = end(q, i);\n    --q._waiting, ++q._active;\n    t = c.apply(null, t);\n    if (!q._tasks[i]) continue; // task finished synchronously\n    q._tasks[i] = t || noabort;\n  }\n}\n\nfunction end(q, i) {\n  return function(e, r) {\n    if (!q._tasks[i]) return; // ignore multiple callbacks\n    --q._active, ++q._ended;\n    q._tasks[i] = null;\n    if (q._error != null) return; // ignore secondary errors\n    if (e != null) {\n      abort(q, e);\n    } else {\n      q._data[i] = r;\n      if (q._waiting) poke$1(q);\n      else maybeNotify(q);\n    }\n  };\n}\n\nfunction abort(q, e) {\n  var i = q._tasks.length, t;\n  q._error = e; // ignore active callbacks\n  q._data = undefined; // allow gc\n  q._waiting = NaN; // prevent starting\n\n  while (--i >= 0) {\n    if (t = q._tasks[i]) {\n      q._tasks[i] = null;\n      if (t.abort) {\n        try { t.abort(); }\n        catch (e) { /* ignore */ }\n      }\n    }\n  }\n\n  q._active = NaN; // allow notification\n  maybeNotify(q);\n}\n\nfunction maybeNotify(q) {\n  if (!q._active && q._call) {\n    var d = q._data;\n    q._data = undefined; // allow gc\n    q._call(q._error, d);\n  }\n}\n\nfunction queue(concurrency) {\n  if (concurrency == null) concurrency = Infinity;\n  else if (!((concurrency = +concurrency) >= 1)) throw new Error(\"invalid concurrency\");\n  return new Queue(concurrency);\n}\n\nvar defaultSource$1 = function() {\n  return Math.random();\n};\n\nvar uniform = ((function sourceRandomUniform(source) {\n  function randomUniform(min, max) {\n    min = min == null ? 0 : +min;\n    max = max == null ? 1 : +max;\n    if (arguments.length === 1) max = min, min = 0;\n    else max -= min;\n    return function() {\n      return source() * max + min;\n    };\n  }\n\n  randomUniform.source = sourceRandomUniform;\n\n  return randomUniform;\n}))(defaultSource$1);\n\nvar normal = ((function sourceRandomNormal(source) {\n  function randomNormal(mu, sigma) {\n    var x, r;\n    mu = mu == null ? 0 : +mu;\n    sigma = sigma == null ? 1 : +sigma;\n    return function() {\n      var y;\n\n      // If available, use the second previously-generated uniform random.\n      if (x != null) y = x, x = null;\n\n      // Otherwise, generate a new x and y.\n      else do {\n        x = source() * 2 - 1;\n        y = source() * 2 - 1;\n        r = x * x + y * y;\n      } while (!r || r > 1);\n\n      return mu + sigma * y * Math.sqrt(-2 * Math.log(r) / r);\n    };\n  }\n\n  randomNormal.source = sourceRandomNormal;\n\n  return randomNormal;\n}))(defaultSource$1);\n\nvar logNormal = ((function sourceRandomLogNormal(source) {\n  function randomLogNormal() {\n    var randomNormal = normal.source(source).apply(this, arguments);\n    return function() {\n      return Math.exp(randomNormal());\n    };\n  }\n\n  randomLogNormal.source = sourceRandomLogNormal;\n\n  return randomLogNormal;\n}))(defaultSource$1);\n\nvar irwinHall = ((function sourceRandomIrwinHall(source) {\n  function randomIrwinHall(n) {\n    return function() {\n      for (var sum = 0, i = 0; i < n; ++i) sum += source();\n      return sum;\n    };\n  }\n\n  randomIrwinHall.source = sourceRandomIrwinHall;\n\n  return randomIrwinHall;\n}))(defaultSource$1);\n\nvar bates = ((function sourceRandomBates(source) {\n  function randomBates(n) {\n    var randomIrwinHall = irwinHall.source(source)(n);\n    return function() {\n      return randomIrwinHall() / n;\n    };\n  }\n\n  randomBates.source = sourceRandomBates;\n\n  return randomBates;\n}))(defaultSource$1);\n\nvar exponential$1 = ((function sourceRandomExponential(source) {\n  function randomExponential(lambda) {\n    return function() {\n      return -Math.log(1 - source()) / lambda;\n    };\n  }\n\n  randomExponential.source = sourceRandomExponential;\n\n  return randomExponential;\n}))(defaultSource$1);\n\nvar request = function(url, callback) {\n  var request,\n      event = dispatch(\"beforesend\", \"progress\", \"load\", \"error\"),\n      mimeType,\n      headers = map$1(),\n      xhr = new XMLHttpRequest,\n      user = null,\n      password = null,\n      response,\n      responseType,\n      timeout = 0;\n\n  // If IE does not support CORS, use XDomainRequest.\n  if (typeof XDomainRequest !== \"undefined\"\n      && !(\"withCredentials\" in xhr)\n      && /^(http(s)?:)?\\/\\//.test(url)) xhr = new XDomainRequest;\n\n  \"onload\" in xhr\n      ? xhr.onload = xhr.onerror = xhr.ontimeout = respond\n      : xhr.onreadystatechange = function(o) { xhr.readyState > 3 && respond(o); };\n\n  function respond(o) {\n    var status = xhr.status, result;\n    if (!status && hasResponse(xhr)\n        || status >= 200 && status < 300\n        || status === 304) {\n      if (response) {\n        try {\n          result = response.call(request, xhr);\n        } catch (e) {\n          event.call(\"error\", request, e);\n          return;\n        }\n      } else {\n        result = xhr;\n      }\n      event.call(\"load\", request, result);\n    } else {\n      event.call(\"error\", request, o);\n    }\n  }\n\n  xhr.onprogress = function(e) {\n    event.call(\"progress\", request, e);\n  };\n\n  request = {\n    header: function(name, value) {\n      name = (name + \"\").toLowerCase();\n      if (arguments.length < 2) return headers.get(name);\n      if (value == null) headers.remove(name);\n      else headers.set(name, value + \"\");\n      return request;\n    },\n\n    // If mimeType is non-null and no Accept header is set, a default is used.\n    mimeType: function(value) {\n      if (!arguments.length) return mimeType;\n      mimeType = value == null ? null : value + \"\";\n      return request;\n    },\n\n    // Specifies what type the response value should take;\n    // for instance, arraybuffer, blob, document, or text.\n    responseType: function(value) {\n      if (!arguments.length) return responseType;\n      responseType = value;\n      return request;\n    },\n\n    timeout: function(value) {\n      if (!arguments.length) return timeout;\n      timeout = +value;\n      return request;\n    },\n\n    user: function(value) {\n      return arguments.length < 1 ? user : (user = value == null ? null : value + \"\", request);\n    },\n\n    password: function(value) {\n      return arguments.length < 1 ? password : (password = value == null ? null : value + \"\", request);\n    },\n\n    // Specify how to convert the response content to a specific type;\n    // changes the callback value on \"load\" events.\n    response: function(value) {\n      response = value;\n      return request;\n    },\n\n    // Alias for send(\"GET\", …).\n    get: function(data, callback) {\n      return request.send(\"GET\", data, callback);\n    },\n\n    // Alias for send(\"POST\", …).\n    post: function(data, callback) {\n      return request.send(\"POST\", data, callback);\n    },\n\n    // If callback is non-null, it will be used for error and load events.\n    send: function(method, data, callback) {\n      xhr.open(method, url, true, user, password);\n      if (mimeType != null && !headers.has(\"accept\")) headers.set(\"accept\", mimeType + \",*/*\");\n      if (xhr.setRequestHeader) headers.each(function(value, name) { xhr.setRequestHeader(name, value); });\n      if (mimeType != null && xhr.overrideMimeType) xhr.overrideMimeType(mimeType);\n      if (responseType != null) xhr.responseType = responseType;\n      if (timeout > 0) xhr.timeout = timeout;\n      if (callback == null && typeof data === \"function\") callback = data, data = null;\n      if (callback != null && callback.length === 1) callback = fixCallback(callback);\n      if (callback != null) request.on(\"error\", callback).on(\"load\", function(xhr) { callback(null, xhr); });\n      event.call(\"beforesend\", request, xhr);\n      xhr.send(data == null ? null : data);\n      return request;\n    },\n\n    abort: function() {\n      xhr.abort();\n      return request;\n    },\n\n    on: function() {\n      var value = event.on.apply(event, arguments);\n      return value === event ? request : value;\n    }\n  };\n\n  if (callback != null) {\n    if (typeof callback !== \"function\") throw new Error(\"invalid callback: \" + callback);\n    return request.get(callback);\n  }\n\n  return request;\n};\n\nfunction fixCallback(callback) {\n  return function(error, xhr) {\n    callback(error == null ? xhr : null);\n  };\n}\n\nfunction hasResponse(xhr) {\n  var type = xhr.responseType;\n  return type && type !== \"text\"\n      ? xhr.response // null on error\n      : xhr.responseText; // \"\" on error\n}\n\nvar type$1 = function(defaultMimeType, response) {\n  return function(url, callback) {\n    var r = request(url).mimeType(defaultMimeType).response(response);\n    if (callback != null) {\n      if (typeof callback !== \"function\") throw new Error(\"invalid callback: \" + callback);\n      return r.get(callback);\n    }\n    return r;\n  };\n};\n\nvar html = type$1(\"text/html\", function(xhr) {\n  return document.createRange().createContextualFragment(xhr.responseText);\n});\n\nvar json = type$1(\"application/json\", function(xhr) {\n  return JSON.parse(xhr.responseText);\n});\n\nvar text = type$1(\"text/plain\", function(xhr) {\n  return xhr.responseText;\n});\n\nvar xml = type$1(\"application/xml\", function(xhr) {\n  var xml = xhr.responseXML;\n  if (!xml) throw new Error(\"parse error\");\n  return xml;\n});\n\nvar dsv$1 = function(defaultMimeType, parse) {\n  return function(url, row, callback) {\n    if (arguments.length < 3) callback = row, row = null;\n    var r = request(url).mimeType(defaultMimeType);\n    r.row = function(_) { return arguments.length ? r.response(responseOf(parse, row = _)) : row; };\n    r.row(row);\n    return callback ? r.get(callback) : r;\n  };\n};\n\nfunction responseOf(parse, row) {\n  return function(request$$1) {\n    return parse(request$$1.responseText, row);\n  };\n}\n\nvar csv$1 = dsv$1(\"text/csv\", csvParse);\n\nvar tsv$1 = dsv$1(\"text/tab-separated-values\", tsvParse);\n\nvar array$2 = Array.prototype;\n\nvar map$3 = array$2.map;\nvar slice$4 = array$2.slice;\n\nvar implicit = {name: \"implicit\"};\n\nfunction ordinal(range) {\n  var index = map$1(),\n      domain = [],\n      unknown = implicit;\n\n  range = range == null ? [] : slice$4.call(range);\n\n  function scale(d) {\n    var key = d + \"\", i = index.get(key);\n    if (!i) {\n      if (unknown !== implicit) return unknown;\n      index.set(key, i = domain.push(d));\n    }\n    return range[(i - 1) % range.length];\n  }\n\n  scale.domain = function(_) {\n    if (!arguments.length) return domain.slice();\n    domain = [], index = map$1();\n    var i = -1, n = _.length, d, key;\n    while (++i < n) if (!index.has(key = (d = _[i]) + \"\")) index.set(key, domain.push(d));\n    return scale;\n  };\n\n  scale.range = function(_) {\n    return arguments.length ? (range = slice$4.call(_), scale) : range.slice();\n  };\n\n  scale.unknown = function(_) {\n    return arguments.length ? (unknown = _, scale) : unknown;\n  };\n\n  scale.copy = function() {\n    return ordinal()\n        .domain(domain)\n        .range(range)\n        .unknown(unknown);\n  };\n\n  return scale;\n}\n\nfunction band() {\n  var scale = ordinal().unknown(undefined),\n      domain = scale.domain,\n      ordinalRange = scale.range,\n      range$$1 = [0, 1],\n      step,\n      bandwidth,\n      round = false,\n      paddingInner = 0,\n      paddingOuter = 0,\n      align = 0.5;\n\n  delete scale.unknown;\n\n  function rescale() {\n    var n = domain().length,\n        reverse = range$$1[1] < range$$1[0],\n        start = range$$1[reverse - 0],\n        stop = range$$1[1 - reverse];\n    step = (stop - start) / Math.max(1, n - paddingInner + paddingOuter * 2);\n    if (round) step = Math.floor(step);\n    start += (stop - start - step * (n - paddingInner)) * align;\n    bandwidth = step * (1 - paddingInner);\n    if (round) start = Math.round(start), bandwidth = Math.round(bandwidth);\n    var values = sequence(n).map(function(i) { return start + step * i; });\n    return ordinalRange(reverse ? values.reverse() : values);\n  }\n\n  scale.domain = function(_) {\n    return arguments.length ? (domain(_), rescale()) : domain();\n  };\n\n  scale.range = function(_) {\n    return arguments.length ? (range$$1 = [+_[0], +_[1]], rescale()) : range$$1.slice();\n  };\n\n  scale.rangeRound = function(_) {\n    return range$$1 = [+_[0], +_[1]], round = true, rescale();\n  };\n\n  scale.bandwidth = function() {\n    return bandwidth;\n  };\n\n  scale.step = function() {\n    return step;\n  };\n\n  scale.round = function(_) {\n    return arguments.length ? (round = !!_, rescale()) : round;\n  };\n\n  scale.padding = function(_) {\n    return arguments.length ? (paddingInner = paddingOuter = Math.max(0, Math.min(1, _)), rescale()) : paddingInner;\n  };\n\n  scale.paddingInner = function(_) {\n    return arguments.length ? (paddingInner = Math.max(0, Math.min(1, _)), rescale()) : paddingInner;\n  };\n\n  scale.paddingOuter = function(_) {\n    return arguments.length ? (paddingOuter = Math.max(0, Math.min(1, _)), rescale()) : paddingOuter;\n  };\n\n  scale.align = function(_) {\n    return arguments.length ? (align = Math.max(0, Math.min(1, _)), rescale()) : align;\n  };\n\n  scale.copy = function() {\n    return band()\n        .domain(domain())\n        .range(range$$1)\n        .round(round)\n        .paddingInner(paddingInner)\n        .paddingOuter(paddingOuter)\n        .align(align);\n  };\n\n  return rescale();\n}\n\nfunction pointish(scale) {\n  var copy = scale.copy;\n\n  scale.padding = scale.paddingOuter;\n  delete scale.paddingInner;\n  delete scale.paddingOuter;\n\n  scale.copy = function() {\n    return pointish(copy());\n  };\n\n  return scale;\n}\n\nfunction point$1() {\n  return pointish(band().paddingInner(1));\n}\n\nvar constant$9 = function(x) {\n  return function() {\n    return x;\n  };\n};\n\nvar number$1 = function(x) {\n  return +x;\n};\n\nvar unit = [0, 1];\n\nfunction deinterpolateLinear(a, b) {\n  return (b -= (a = +a))\n      ? function(x) { return (x - a) / b; }\n      : constant$9(b);\n}\n\nfunction deinterpolateClamp(deinterpolate) {\n  return function(a, b) {\n    var d = deinterpolate(a = +a, b = +b);\n    return function(x) { return x <= a ? 0 : x >= b ? 1 : d(x); };\n  };\n}\n\nfunction reinterpolateClamp(reinterpolate) {\n  return function(a, b) {\n    var r = reinterpolate(a = +a, b = +b);\n    return function(t) { return t <= 0 ? a : t >= 1 ? b : r(t); };\n  };\n}\n\nfunction bimap(domain, range$$1, deinterpolate, reinterpolate) {\n  var d0 = domain[0], d1 = domain[1], r0 = range$$1[0], r1 = range$$1[1];\n  if (d1 < d0) d0 = deinterpolate(d1, d0), r0 = reinterpolate(r1, r0);\n  else d0 = deinterpolate(d0, d1), r0 = reinterpolate(r0, r1);\n  return function(x) { return r0(d0(x)); };\n}\n\nfunction polymap(domain, range$$1, deinterpolate, reinterpolate) {\n  var j = Math.min(domain.length, range$$1.length) - 1,\n      d = new Array(j),\n      r = new Array(j),\n      i = -1;\n\n  // Reverse descending domains.\n  if (domain[j] < domain[0]) {\n    domain = domain.slice().reverse();\n    range$$1 = range$$1.slice().reverse();\n  }\n\n  while (++i < j) {\n    d[i] = deinterpolate(domain[i], domain[i + 1]);\n    r[i] = reinterpolate(range$$1[i], range$$1[i + 1]);\n  }\n\n  return function(x) {\n    var i = bisectRight(domain, x, 1, j) - 1;\n    return r[i](d[i](x));\n  };\n}\n\nfunction copy(source, target) {\n  return target\n      .domain(source.domain())\n      .range(source.range())\n      .interpolate(source.interpolate())\n      .clamp(source.clamp());\n}\n\n// deinterpolate(a, b)(x) takes a domain value x in [a,b] and returns the corresponding parameter t in [0,1].\n// reinterpolate(a, b)(t) takes a parameter t in [0,1] and returns the corresponding domain value x in [a,b].\nfunction continuous(deinterpolate, reinterpolate) {\n  var domain = unit,\n      range$$1 = unit,\n      interpolate$$1 = interpolateValue,\n      clamp = false,\n      piecewise,\n      output,\n      input;\n\n  function rescale() {\n    piecewise = Math.min(domain.length, range$$1.length) > 2 ? polymap : bimap;\n    output = input = null;\n    return scale;\n  }\n\n  function scale(x) {\n    return (output || (output = piecewise(domain, range$$1, clamp ? deinterpolateClamp(deinterpolate) : deinterpolate, interpolate$$1)))(+x);\n  }\n\n  scale.invert = function(y) {\n    return (input || (input = piecewise(range$$1, domain, deinterpolateLinear, clamp ? reinterpolateClamp(reinterpolate) : reinterpolate)))(+y);\n  };\n\n  scale.domain = function(_) {\n    return arguments.length ? (domain = map$3.call(_, number$1), rescale()) : domain.slice();\n  };\n\n  scale.range = function(_) {\n    return arguments.length ? (range$$1 = slice$4.call(_), rescale()) : range$$1.slice();\n  };\n\n  scale.rangeRound = function(_) {\n    return range$$1 = slice$4.call(_), interpolate$$1 = interpolateRound, rescale();\n  };\n\n  scale.clamp = function(_) {\n    return arguments.length ? (clamp = !!_, rescale()) : clamp;\n  };\n\n  scale.interpolate = function(_) {\n    return arguments.length ? (interpolate$$1 = _, rescale()) : interpolate$$1;\n  };\n\n  return rescale();\n}\n\nvar tickFormat = function(domain, count, specifier) {\n  var start = domain[0],\n      stop = domain[domain.length - 1],\n      step = tickStep(start, stop, count == null ? 10 : count),\n      precision;\n  specifier = formatSpecifier(specifier == null ? \",f\" : specifier);\n  switch (specifier.type) {\n    case \"s\": {\n      var value = Math.max(Math.abs(start), Math.abs(stop));\n      if (specifier.precision == null && !isNaN(precision = precisionPrefix(step, value))) specifier.precision = precision;\n      return exports.formatPrefix(specifier, value);\n    }\n    case \"\":\n    case \"e\":\n    case \"g\":\n    case \"p\":\n    case \"r\": {\n      if (specifier.precision == null && !isNaN(precision = precisionRound(step, Math.max(Math.abs(start), Math.abs(stop))))) specifier.precision = precision - (specifier.type === \"e\");\n      break;\n    }\n    case \"f\":\n    case \"%\": {\n      if (specifier.precision == null && !isNaN(precision = precisionFixed(step))) specifier.precision = precision - (specifier.type === \"%\") * 2;\n      break;\n    }\n  }\n  return exports.format(specifier);\n};\n\nfunction linearish(scale) {\n  var domain = scale.domain;\n\n  scale.ticks = function(count) {\n    var d = domain();\n    return ticks(d[0], d[d.length - 1], count == null ? 10 : count);\n  };\n\n  scale.tickFormat = function(count, specifier) {\n    return tickFormat(domain(), count, specifier);\n  };\n\n  scale.nice = function(count) {\n    if (count == null) count = 10;\n\n    var d = domain(),\n        i0 = 0,\n        i1 = d.length - 1,\n        start = d[i0],\n        stop = d[i1],\n        step;\n\n    if (stop < start) {\n      step = start, start = stop, stop = step;\n      step = i0, i0 = i1, i1 = step;\n    }\n\n    step = tickIncrement(start, stop, count);\n\n    if (step > 0) {\n      start = Math.floor(start / step) * step;\n      stop = Math.ceil(stop / step) * step;\n      step = tickIncrement(start, stop, count);\n    } else if (step < 0) {\n      start = Math.ceil(start * step) / step;\n      stop = Math.floor(stop * step) / step;\n      step = tickIncrement(start, stop, count);\n    }\n\n    if (step > 0) {\n      d[i0] = Math.floor(start / step) * step;\n      d[i1] = Math.ceil(stop / step) * step;\n      domain(d);\n    } else if (step < 0) {\n      d[i0] = Math.ceil(start * step) / step;\n      d[i1] = Math.floor(stop * step) / step;\n      domain(d);\n    }\n\n    return scale;\n  };\n\n  return scale;\n}\n\nfunction linear$2() {\n  var scale = continuous(deinterpolateLinear, reinterpolate);\n\n  scale.copy = function() {\n    return copy(scale, linear$2());\n  };\n\n  return linearish(scale);\n}\n\nfunction identity$6() {\n  var domain = [0, 1];\n\n  function scale(x) {\n    return +x;\n  }\n\n  scale.invert = scale;\n\n  scale.domain = scale.range = function(_) {\n    return arguments.length ? (domain = map$3.call(_, number$1), scale) : domain.slice();\n  };\n\n  scale.copy = function() {\n    return identity$6().domain(domain);\n  };\n\n  return linearish(scale);\n}\n\nvar nice = function(domain, interval) {\n  domain = domain.slice();\n\n  var i0 = 0,\n      i1 = domain.length - 1,\n      x0 = domain[i0],\n      x1 = domain[i1],\n      t;\n\n  if (x1 < x0) {\n    t = i0, i0 = i1, i1 = t;\n    t = x0, x0 = x1, x1 = t;\n  }\n\n  domain[i0] = interval.floor(x0);\n  domain[i1] = interval.ceil(x1);\n  return domain;\n};\n\nfunction deinterpolate(a, b) {\n  return (b = Math.log(b / a))\n      ? function(x) { return Math.log(x / a) / b; }\n      : constant$9(b);\n}\n\nfunction reinterpolate$1(a, b) {\n  return a < 0\n      ? function(t) { return -Math.pow(-b, t) * Math.pow(-a, 1 - t); }\n      : function(t) { return Math.pow(b, t) * Math.pow(a, 1 - t); };\n}\n\nfunction pow10(x) {\n  return isFinite(x) ? +(\"1e\" + x) : x < 0 ? 0 : x;\n}\n\nfunction powp(base) {\n  return base === 10 ? pow10\n      : base === Math.E ? Math.exp\n      : function(x) { return Math.pow(base, x); };\n}\n\nfunction logp(base) {\n  return base === Math.E ? Math.log\n      : base === 10 && Math.log10\n      || base === 2 && Math.log2\n      || (base = Math.log(base), function(x) { return Math.log(x) / base; });\n}\n\nfunction reflect(f) {\n  return function(x) {\n    return -f(-x);\n  };\n}\n\nfunction log$1() {\n  var scale = continuous(deinterpolate, reinterpolate$1).domain([1, 10]),\n      domain = scale.domain,\n      base = 10,\n      logs = logp(10),\n      pows = powp(10);\n\n  function rescale() {\n    logs = logp(base), pows = powp(base);\n    if (domain()[0] < 0) logs = reflect(logs), pows = reflect(pows);\n    return scale;\n  }\n\n  scale.base = function(_) {\n    return arguments.length ? (base = +_, rescale()) : base;\n  };\n\n  scale.domain = function(_) {\n    return arguments.length ? (domain(_), rescale()) : domain();\n  };\n\n  scale.ticks = function(count) {\n    var d = domain(),\n        u = d[0],\n        v = d[d.length - 1],\n        r;\n\n    if (r = v < u) i = u, u = v, v = i;\n\n    var i = logs(u),\n        j = logs(v),\n        p,\n        k,\n        t,\n        n = count == null ? 10 : +count,\n        z = [];\n\n    if (!(base % 1) && j - i < n) {\n      i = Math.round(i) - 1, j = Math.round(j) + 1;\n      if (u > 0) for (; i < j; ++i) {\n        for (k = 1, p = pows(i); k < base; ++k) {\n          t = p * k;\n          if (t < u) continue;\n          if (t > v) break;\n          z.push(t);\n        }\n      } else for (; i < j; ++i) {\n        for (k = base - 1, p = pows(i); k >= 1; --k) {\n          t = p * k;\n          if (t < u) continue;\n          if (t > v) break;\n          z.push(t);\n        }\n      }\n    } else {\n      z = ticks(i, j, Math.min(j - i, n)).map(pows);\n    }\n\n    return r ? z.reverse() : z;\n  };\n\n  scale.tickFormat = function(count, specifier) {\n    if (specifier == null) specifier = base === 10 ? \".0e\" : \",\";\n    if (typeof specifier !== \"function\") specifier = exports.format(specifier);\n    if (count === Infinity) return specifier;\n    if (count == null) count = 10;\n    var k = Math.max(1, base * count / scale.ticks().length); // TODO fast estimate?\n    return function(d) {\n      var i = d / pows(Math.round(logs(d)));\n      if (i * base < base - 0.5) i *= base;\n      return i <= k ? specifier(d) : \"\";\n    };\n  };\n\n  scale.nice = function() {\n    return domain(nice(domain(), {\n      floor: function(x) { return pows(Math.floor(logs(x))); },\n      ceil: function(x) { return pows(Math.ceil(logs(x))); }\n    }));\n  };\n\n  scale.copy = function() {\n    return copy(scale, log$1().base(base));\n  };\n\n  return scale;\n}\n\nfunction raise$1(x, exponent) {\n  return x < 0 ? -Math.pow(-x, exponent) : Math.pow(x, exponent);\n}\n\nfunction pow$1() {\n  var exponent = 1,\n      scale = continuous(deinterpolate, reinterpolate),\n      domain = scale.domain;\n\n  function deinterpolate(a, b) {\n    return (b = raise$1(b, exponent) - (a = raise$1(a, exponent)))\n        ? function(x) { return (raise$1(x, exponent) - a) / b; }\n        : constant$9(b);\n  }\n\n  function reinterpolate(a, b) {\n    b = raise$1(b, exponent) - (a = raise$1(a, exponent));\n    return function(t) { return raise$1(a + b * t, 1 / exponent); };\n  }\n\n  scale.exponent = function(_) {\n    return arguments.length ? (exponent = +_, domain(domain())) : exponent;\n  };\n\n  scale.copy = function() {\n    return copy(scale, pow$1().exponent(exponent));\n  };\n\n  return linearish(scale);\n}\n\nfunction sqrt$1() {\n  return pow$1().exponent(0.5);\n}\n\nfunction quantile$$1() {\n  var domain = [],\n      range$$1 = [],\n      thresholds = [];\n\n  function rescale() {\n    var i = 0, n = Math.max(1, range$$1.length);\n    thresholds = new Array(n - 1);\n    while (++i < n) thresholds[i - 1] = threshold(domain, i / n);\n    return scale;\n  }\n\n  function scale(x) {\n    if (!isNaN(x = +x)) return range$$1[bisectRight(thresholds, x)];\n  }\n\n  scale.invertExtent = function(y) {\n    var i = range$$1.indexOf(y);\n    return i < 0 ? [NaN, NaN] : [\n      i > 0 ? thresholds[i - 1] : domain[0],\n      i < thresholds.length ? thresholds[i] : domain[domain.length - 1]\n    ];\n  };\n\n  scale.domain = function(_) {\n    if (!arguments.length) return domain.slice();\n    domain = [];\n    for (var i = 0, n = _.length, d; i < n; ++i) if (d = _[i], d != null && !isNaN(d = +d)) domain.push(d);\n    domain.sort(ascending);\n    return rescale();\n  };\n\n  scale.range = function(_) {\n    return arguments.length ? (range$$1 = slice$4.call(_), rescale()) : range$$1.slice();\n  };\n\n  scale.quantiles = function() {\n    return thresholds.slice();\n  };\n\n  scale.copy = function() {\n    return quantile$$1()\n        .domain(domain)\n        .range(range$$1);\n  };\n\n  return scale;\n}\n\nfunction quantize$1() {\n  var x0 = 0,\n      x1 = 1,\n      n = 1,\n      domain = [0.5],\n      range$$1 = [0, 1];\n\n  function scale(x) {\n    if (x <= x) return range$$1[bisectRight(domain, x, 0, n)];\n  }\n\n  function rescale() {\n    var i = -1;\n    domain = new Array(n);\n    while (++i < n) domain[i] = ((i + 1) * x1 - (i - n) * x0) / (n + 1);\n    return scale;\n  }\n\n  scale.domain = function(_) {\n    return arguments.length ? (x0 = +_[0], x1 = +_[1], rescale()) : [x0, x1];\n  };\n\n  scale.range = function(_) {\n    return arguments.length ? (n = (range$$1 = slice$4.call(_)).length - 1, rescale()) : range$$1.slice();\n  };\n\n  scale.invertExtent = function(y) {\n    var i = range$$1.indexOf(y);\n    return i < 0 ? [NaN, NaN]\n        : i < 1 ? [x0, domain[0]]\n        : i >= n ? [domain[n - 1], x1]\n        : [domain[i - 1], domain[i]];\n  };\n\n  scale.copy = function() {\n    return quantize$1()\n        .domain([x0, x1])\n        .range(range$$1);\n  };\n\n  return linearish(scale);\n}\n\nfunction threshold$1() {\n  var domain = [0.5],\n      range$$1 = [0, 1],\n      n = 1;\n\n  function scale(x) {\n    if (x <= x) return range$$1[bisectRight(domain, x, 0, n)];\n  }\n\n  scale.domain = function(_) {\n    return arguments.length ? (domain = slice$4.call(_), n = Math.min(domain.length, range$$1.length - 1), scale) : domain.slice();\n  };\n\n  scale.range = function(_) {\n    return arguments.length ? (range$$1 = slice$4.call(_), n = Math.min(domain.length, range$$1.length - 1), scale) : range$$1.slice();\n  };\n\n  scale.invertExtent = function(y) {\n    var i = range$$1.indexOf(y);\n    return [domain[i - 1], domain[i]];\n  };\n\n  scale.copy = function() {\n    return threshold$1()\n        .domain(domain)\n        .range(range$$1);\n  };\n\n  return scale;\n}\n\nvar t0$1 = new Date;\nvar t1$1 = new Date;\n\nfunction newInterval(floori, offseti, count, field) {\n\n  function interval(date) {\n    return floori(date = new Date(+date)), date;\n  }\n\n  interval.floor = interval;\n\n  interval.ceil = function(date) {\n    return floori(date = new Date(date - 1)), offseti(date, 1), floori(date), date;\n  };\n\n  interval.round = function(date) {\n    var d0 = interval(date),\n        d1 = interval.ceil(date);\n    return date - d0 < d1 - date ? d0 : d1;\n  };\n\n  interval.offset = function(date, step) {\n    return offseti(date = new Date(+date), step == null ? 1 : Math.floor(step)), date;\n  };\n\n  interval.range = function(start, stop, step) {\n    var range = [];\n    start = interval.ceil(start);\n    step = step == null ? 1 : Math.floor(step);\n    if (!(start < stop) || !(step > 0)) return range; // also handles Invalid Date\n    do range.push(new Date(+start)); while (offseti(start, step), floori(start), start < stop)\n    return range;\n  };\n\n  interval.filter = function(test) {\n    return newInterval(function(date) {\n      if (date >= date) while (floori(date), !test(date)) date.setTime(date - 1);\n    }, function(date, step) {\n      if (date >= date) while (--step >= 0) while (offseti(date, 1), !test(date)) {} // eslint-disable-line no-empty\n    });\n  };\n\n  if (count) {\n    interval.count = function(start, end) {\n      t0$1.setTime(+start), t1$1.setTime(+end);\n      floori(t0$1), floori(t1$1);\n      return Math.floor(count(t0$1, t1$1));\n    };\n\n    interval.every = function(step) {\n      step = Math.floor(step);\n      return !isFinite(step) || !(step > 0) ? null\n          : !(step > 1) ? interval\n          : interval.filter(field\n              ? function(d) { return field(d) % step === 0; }\n              : function(d) { return interval.count(0, d) % step === 0; });\n    };\n  }\n\n  return interval;\n}\n\nvar millisecond = newInterval(function() {\n  // noop\n}, function(date, step) {\n  date.setTime(+date + step);\n}, function(start, end) {\n  return end - start;\n});\n\n// An optimized implementation for this simple case.\nmillisecond.every = function(k) {\n  k = Math.floor(k);\n  if (!isFinite(k) || !(k > 0)) return null;\n  if (!(k > 1)) return millisecond;\n  return newInterval(function(date) {\n    date.setTime(Math.floor(date / k) * k);\n  }, function(date, step) {\n    date.setTime(+date + step * k);\n  }, function(start, end) {\n    return (end - start) / k;\n  });\n};\n\nvar milliseconds = millisecond.range;\n\nvar durationSecond$1 = 1e3;\nvar durationMinute$1 = 6e4;\nvar durationHour$1 = 36e5;\nvar durationDay$1 = 864e5;\nvar durationWeek$1 = 6048e5;\n\nvar second = newInterval(function(date) {\n  date.setTime(Math.floor(date / durationSecond$1) * durationSecond$1);\n}, function(date, step) {\n  date.setTime(+date + step * durationSecond$1);\n}, function(start, end) {\n  return (end - start) / durationSecond$1;\n}, function(date) {\n  return date.getUTCSeconds();\n});\n\nvar seconds = second.range;\n\nvar minute = newInterval(function(date) {\n  date.setTime(Math.floor(date / durationMinute$1) * durationMinute$1);\n}, function(date, step) {\n  date.setTime(+date + step * durationMinute$1);\n}, function(start, end) {\n  return (end - start) / durationMinute$1;\n}, function(date) {\n  return date.getMinutes();\n});\n\nvar minutes = minute.range;\n\nvar hour = newInterval(function(date) {\n  var offset = date.getTimezoneOffset() * durationMinute$1 % durationHour$1;\n  if (offset < 0) offset += durationHour$1;\n  date.setTime(Math.floor((+date - offset) / durationHour$1) * durationHour$1 + offset);\n}, function(date, step) {\n  date.setTime(+date + step * durationHour$1);\n}, function(start, end) {\n  return (end - start) / durationHour$1;\n}, function(date) {\n  return date.getHours();\n});\n\nvar hours = hour.range;\n\nvar day = newInterval(function(date) {\n  date.setHours(0, 0, 0, 0);\n}, function(date, step) {\n  date.setDate(date.getDate() + step);\n}, function(start, end) {\n  return (end - start - (end.getTimezoneOffset() - start.getTimezoneOffset()) * durationMinute$1) / durationDay$1;\n}, function(date) {\n  return date.getDate() - 1;\n});\n\nvar days = day.range;\n\nfunction weekday(i) {\n  return newInterval(function(date) {\n    date.setDate(date.getDate() - (date.getDay() + 7 - i) % 7);\n    date.setHours(0, 0, 0, 0);\n  }, function(date, step) {\n    date.setDate(date.getDate() + step * 7);\n  }, function(start, end) {\n    return (end - start - (end.getTimezoneOffset() - start.getTimezoneOffset()) * durationMinute$1) / durationWeek$1;\n  });\n}\n\nvar sunday = weekday(0);\nvar monday = weekday(1);\nvar tuesday = weekday(2);\nvar wednesday = weekday(3);\nvar thursday = weekday(4);\nvar friday = weekday(5);\nvar saturday = weekday(6);\n\nvar sundays = sunday.range;\nvar mondays = monday.range;\nvar tuesdays = tuesday.range;\nvar wednesdays = wednesday.range;\nvar thursdays = thursday.range;\nvar fridays = friday.range;\nvar saturdays = saturday.range;\n\nvar month = newInterval(function(date) {\n  date.setDate(1);\n  date.setHours(0, 0, 0, 0);\n}, function(date, step) {\n  date.setMonth(date.getMonth() + step);\n}, function(start, end) {\n  return end.getMonth() - start.getMonth() + (end.getFullYear() - start.getFullYear()) * 12;\n}, function(date) {\n  return date.getMonth();\n});\n\nvar months = month.range;\n\nvar year = newInterval(function(date) {\n  date.setMonth(0, 1);\n  date.setHours(0, 0, 0, 0);\n}, function(date, step) {\n  date.setFullYear(date.getFullYear() + step);\n}, function(start, end) {\n  return end.getFullYear() - start.getFullYear();\n}, function(date) {\n  return date.getFullYear();\n});\n\n// An optimized implementation for this simple case.\nyear.every = function(k) {\n  return !isFinite(k = Math.floor(k)) || !(k > 0) ? null : newInterval(function(date) {\n    date.setFullYear(Math.floor(date.getFullYear() / k) * k);\n    date.setMonth(0, 1);\n    date.setHours(0, 0, 0, 0);\n  }, function(date, step) {\n    date.setFullYear(date.getFullYear() + step * k);\n  });\n};\n\nvar years = year.range;\n\nvar utcMinute = newInterval(function(date) {\n  date.setUTCSeconds(0, 0);\n}, function(date, step) {\n  date.setTime(+date + step * durationMinute$1);\n}, function(start, end) {\n  return (end - start) / durationMinute$1;\n}, function(date) {\n  return date.getUTCMinutes();\n});\n\nvar utcMinutes = utcMinute.range;\n\nvar utcHour = newInterval(function(date) {\n  date.setUTCMinutes(0, 0, 0);\n}, function(date, step) {\n  date.setTime(+date + step * durationHour$1);\n}, function(start, end) {\n  return (end - start) / durationHour$1;\n}, function(date) {\n  return date.getUTCHours();\n});\n\nvar utcHours = utcHour.range;\n\nvar utcDay = newInterval(function(date) {\n  date.setUTCHours(0, 0, 0, 0);\n}, function(date, step) {\n  date.setUTCDate(date.getUTCDate() + step);\n}, function(start, end) {\n  return (end - start) / durationDay$1;\n}, function(date) {\n  return date.getUTCDate() - 1;\n});\n\nvar utcDays = utcDay.range;\n\nfunction utcWeekday(i) {\n  return newInterval(function(date) {\n    date.setUTCDate(date.getUTCDate() - (date.getUTCDay() + 7 - i) % 7);\n    date.setUTCHours(0, 0, 0, 0);\n  }, function(date, step) {\n    date.setUTCDate(date.getUTCDate() + step * 7);\n  }, function(start, end) {\n    return (end - start) / durationWeek$1;\n  });\n}\n\nvar utcSunday = utcWeekday(0);\nvar utcMonday = utcWeekday(1);\nvar utcTuesday = utcWeekday(2);\nvar utcWednesday = utcWeekday(3);\nvar utcThursday = utcWeekday(4);\nvar utcFriday = utcWeekday(5);\nvar utcSaturday = utcWeekday(6);\n\nvar utcSundays = utcSunday.range;\nvar utcMondays = utcMonday.range;\nvar utcTuesdays = utcTuesday.range;\nvar utcWednesdays = utcWednesday.range;\nvar utcThursdays = utcThursday.range;\nvar utcFridays = utcFriday.range;\nvar utcSaturdays = utcSaturday.range;\n\nvar utcMonth = newInterval(function(date) {\n  date.setUTCDate(1);\n  date.setUTCHours(0, 0, 0, 0);\n}, function(date, step) {\n  date.setUTCMonth(date.getUTCMonth() + step);\n}, function(start, end) {\n  return end.getUTCMonth() - start.getUTCMonth() + (end.getUTCFullYear() - start.getUTCFullYear()) * 12;\n}, function(date) {\n  return date.getUTCMonth();\n});\n\nvar utcMonths = utcMonth.range;\n\nvar utcYear = newInterval(function(date) {\n  date.setUTCMonth(0, 1);\n  date.setUTCHours(0, 0, 0, 0);\n}, function(date, step) {\n  date.setUTCFullYear(date.getUTCFullYear() + step);\n}, function(start, end) {\n  return end.getUTCFullYear() - start.getUTCFullYear();\n}, function(date) {\n  return date.getUTCFullYear();\n});\n\n// An optimized implementation for this simple case.\nutcYear.every = function(k) {\n  return !isFinite(k = Math.floor(k)) || !(k > 0) ? null : newInterval(function(date) {\n    date.setUTCFullYear(Math.floor(date.getUTCFullYear() / k) * k);\n    date.setUTCMonth(0, 1);\n    date.setUTCHours(0, 0, 0, 0);\n  }, function(date, step) {\n    date.setUTCFullYear(date.getUTCFullYear() + step * k);\n  });\n};\n\nvar utcYears = utcYear.range;\n\nfunction localDate(d) {\n  if (0 <= d.y && d.y < 100) {\n    var date = new Date(-1, d.m, d.d, d.H, d.M, d.S, d.L);\n    date.setFullYear(d.y);\n    return date;\n  }\n  return new Date(d.y, d.m, d.d, d.H, d.M, d.S, d.L);\n}\n\nfunction utcDate(d) {\n  if (0 <= d.y && d.y < 100) {\n    var date = new Date(Date.UTC(-1, d.m, d.d, d.H, d.M, d.S, d.L));\n    date.setUTCFullYear(d.y);\n    return date;\n  }\n  return new Date(Date.UTC(d.y, d.m, d.d, d.H, d.M, d.S, d.L));\n}\n\nfunction newYear(y) {\n  return {y: y, m: 0, d: 1, H: 0, M: 0, S: 0, L: 0};\n}\n\nfunction formatLocale$1(locale) {\n  var locale_dateTime = locale.dateTime,\n      locale_date = locale.date,\n      locale_time = locale.time,\n      locale_periods = locale.periods,\n      locale_weekdays = locale.days,\n      locale_shortWeekdays = locale.shortDays,\n      locale_months = locale.months,\n      locale_shortMonths = locale.shortMonths;\n\n  var periodRe = formatRe(locale_periods),\n      periodLookup = formatLookup(locale_periods),\n      weekdayRe = formatRe(locale_weekdays),\n      weekdayLookup = formatLookup(locale_weekdays),\n      shortWeekdayRe = formatRe(locale_shortWeekdays),\n      shortWeekdayLookup = formatLookup(locale_shortWeekdays),\n      monthRe = formatRe(locale_months),\n      monthLookup = formatLookup(locale_months),\n      shortMonthRe = formatRe(locale_shortMonths),\n      shortMonthLookup = formatLookup(locale_shortMonths);\n\n  var formats = {\n    \"a\": formatShortWeekday,\n    \"A\": formatWeekday,\n    \"b\": formatShortMonth,\n    \"B\": formatMonth,\n    \"c\": null,\n    \"d\": formatDayOfMonth,\n    \"e\": formatDayOfMonth,\n    \"H\": formatHour24,\n    \"I\": formatHour12,\n    \"j\": formatDayOfYear,\n    \"L\": formatMilliseconds,\n    \"m\": formatMonthNumber,\n    \"M\": formatMinutes,\n    \"p\": formatPeriod,\n    \"S\": formatSeconds,\n    \"U\": formatWeekNumberSunday,\n    \"w\": formatWeekdayNumber,\n    \"W\": formatWeekNumberMonday,\n    \"x\": null,\n    \"X\": null,\n    \"y\": formatYear,\n    \"Y\": formatFullYear,\n    \"Z\": formatZone,\n    \"%\": formatLiteralPercent\n  };\n\n  var utcFormats = {\n    \"a\": formatUTCShortWeekday,\n    \"A\": formatUTCWeekday,\n    \"b\": formatUTCShortMonth,\n    \"B\": formatUTCMonth,\n    \"c\": null,\n    \"d\": formatUTCDayOfMonth,\n    \"e\": formatUTCDayOfMonth,\n    \"H\": formatUTCHour24,\n    \"I\": formatUTCHour12,\n    \"j\": formatUTCDayOfYear,\n    \"L\": formatUTCMilliseconds,\n    \"m\": formatUTCMonthNumber,\n    \"M\": formatUTCMinutes,\n    \"p\": formatUTCPeriod,\n    \"S\": formatUTCSeconds,\n    \"U\": formatUTCWeekNumberSunday,\n    \"w\": formatUTCWeekdayNumber,\n    \"W\": formatUTCWeekNumberMonday,\n    \"x\": null,\n    \"X\": null,\n    \"y\": formatUTCYear,\n    \"Y\": formatUTCFullYear,\n    \"Z\": formatUTCZone,\n    \"%\": formatLiteralPercent\n  };\n\n  var parses = {\n    \"a\": parseShortWeekday,\n    \"A\": parseWeekday,\n    \"b\": parseShortMonth,\n    \"B\": parseMonth,\n    \"c\": parseLocaleDateTime,\n    \"d\": parseDayOfMonth,\n    \"e\": parseDayOfMonth,\n    \"H\": parseHour24,\n    \"I\": parseHour24,\n    \"j\": parseDayOfYear,\n    \"L\": parseMilliseconds,\n    \"m\": parseMonthNumber,\n    \"M\": parseMinutes,\n    \"p\": parsePeriod,\n    \"S\": parseSeconds,\n    \"U\": parseWeekNumberSunday,\n    \"w\": parseWeekdayNumber,\n    \"W\": parseWeekNumberMonday,\n    \"x\": parseLocaleDate,\n    \"X\": parseLocaleTime,\n    \"y\": parseYear,\n    \"Y\": parseFullYear,\n    \"Z\": parseZone,\n    \"%\": parseLiteralPercent\n  };\n\n  // These recursive directive definitions must be deferred.\n  formats.x = newFormat(locale_date, formats);\n  formats.X = newFormat(locale_time, formats);\n  formats.c = newFormat(locale_dateTime, formats);\n  utcFormats.x = newFormat(locale_date, utcFormats);\n  utcFormats.X = newFormat(locale_time, utcFormats);\n  utcFormats.c = newFormat(locale_dateTime, utcFormats);\n\n  function newFormat(specifier, formats) {\n    return function(date) {\n      var string = [],\n          i = -1,\n          j = 0,\n          n = specifier.length,\n          c,\n          pad,\n          format;\n\n      if (!(date instanceof Date)) date = new Date(+date);\n\n      while (++i < n) {\n        if (specifier.charCodeAt(i) === 37) {\n          string.push(specifier.slice(j, i));\n          if ((pad = pads[c = specifier.charAt(++i)]) != null) c = specifier.charAt(++i);\n          else pad = c === \"e\" ? \" \" : \"0\";\n          if (format = formats[c]) c = format(date, pad);\n          string.push(c);\n          j = i + 1;\n        }\n      }\n\n      string.push(specifier.slice(j, i));\n      return string.join(\"\");\n    };\n  }\n\n  function newParse(specifier, newDate) {\n    return function(string) {\n      var d = newYear(1900),\n          i = parseSpecifier(d, specifier, string += \"\", 0);\n      if (i != string.length) return null;\n\n      // The am-pm flag is 0 for AM, and 1 for PM.\n      if (\"p\" in d) d.H = d.H % 12 + d.p * 12;\n\n      // Convert day-of-week and week-of-year to day-of-year.\n      if (\"W\" in d || \"U\" in d) {\n        if (!(\"w\" in d)) d.w = \"W\" in d ? 1 : 0;\n        var day$$1 = \"Z\" in d ? utcDate(newYear(d.y)).getUTCDay() : newDate(newYear(d.y)).getDay();\n        d.m = 0;\n        d.d = \"W\" in d ? (d.w + 6) % 7 + d.W * 7 - (day$$1 + 5) % 7 : d.w + d.U * 7 - (day$$1 + 6) % 7;\n      }\n\n      // If a time zone is specified, all fields are interpreted as UTC and then\n      // offset according to the specified time zone.\n      if (\"Z\" in d) {\n        d.H += d.Z / 100 | 0;\n        d.M += d.Z % 100;\n        return utcDate(d);\n      }\n\n      // Otherwise, all fields are in local time.\n      return newDate(d);\n    };\n  }\n\n  function parseSpecifier(d, specifier, string, j) {\n    var i = 0,\n        n = specifier.length,\n        m = string.length,\n        c,\n        parse;\n\n    while (i < n) {\n      if (j >= m) return -1;\n      c = specifier.charCodeAt(i++);\n      if (c === 37) {\n        c = specifier.charAt(i++);\n        parse = parses[c in pads ? specifier.charAt(i++) : c];\n        if (!parse || ((j = parse(d, string, j)) < 0)) return -1;\n      } else if (c != string.charCodeAt(j++)) {\n        return -1;\n      }\n    }\n\n    return j;\n  }\n\n  function parsePeriod(d, string, i) {\n    var n = periodRe.exec(string.slice(i));\n    return n ? (d.p = periodLookup[n[0].toLowerCase()], i + n[0].length) : -1;\n  }\n\n  function parseShortWeekday(d, string, i) {\n    var n = shortWeekdayRe.exec(string.slice(i));\n    return n ? (d.w = shortWeekdayLookup[n[0].toLowerCase()], i + n[0].length) : -1;\n  }\n\n  function parseWeekday(d, string, i) {\n    var n = weekdayRe.exec(string.slice(i));\n    return n ? (d.w = weekdayLookup[n[0].toLowerCase()], i + n[0].length) : -1;\n  }\n\n  function parseShortMonth(d, string, i) {\n    var n = shortMonthRe.exec(string.slice(i));\n    return n ? (d.m = shortMonthLookup[n[0].toLowerCase()], i + n[0].length) : -1;\n  }\n\n  function parseMonth(d, string, i) {\n    var n = monthRe.exec(string.slice(i));\n    return n ? (d.m = monthLookup[n[0].toLowerCase()], i + n[0].length) : -1;\n  }\n\n  function parseLocaleDateTime(d, string, i) {\n    return parseSpecifier(d, locale_dateTime, string, i);\n  }\n\n  function parseLocaleDate(d, string, i) {\n    return parseSpecifier(d, locale_date, string, i);\n  }\n\n  function parseLocaleTime(d, string, i) {\n    return parseSpecifier(d, locale_time, string, i);\n  }\n\n  function formatShortWeekday(d) {\n    return locale_shortWeekdays[d.getDay()];\n  }\n\n  function formatWeekday(d) {\n    return locale_weekdays[d.getDay()];\n  }\n\n  function formatShortMonth(d) {\n    return locale_shortMonths[d.getMonth()];\n  }\n\n  function formatMonth(d) {\n    return locale_months[d.getMonth()];\n  }\n\n  function formatPeriod(d) {\n    return locale_periods[+(d.getHours() >= 12)];\n  }\n\n  function formatUTCShortWeekday(d) {\n    return locale_shortWeekdays[d.getUTCDay()];\n  }\n\n  function formatUTCWeekday(d) {\n    return locale_weekdays[d.getUTCDay()];\n  }\n\n  function formatUTCShortMonth(d) {\n    return locale_shortMonths[d.getUTCMonth()];\n  }\n\n  function formatUTCMonth(d) {\n    return locale_months[d.getUTCMonth()];\n  }\n\n  function formatUTCPeriod(d) {\n    return locale_periods[+(d.getUTCHours() >= 12)];\n  }\n\n  return {\n    format: function(specifier) {\n      var f = newFormat(specifier += \"\", formats);\n      f.toString = function() { return specifier; };\n      return f;\n    },\n    parse: function(specifier) {\n      var p = newParse(specifier += \"\", localDate);\n      p.toString = function() { return specifier; };\n      return p;\n    },\n    utcFormat: function(specifier) {\n      var f = newFormat(specifier += \"\", utcFormats);\n      f.toString = function() { return specifier; };\n      return f;\n    },\n    utcParse: function(specifier) {\n      var p = newParse(specifier, utcDate);\n      p.toString = function() { return specifier; };\n      return p;\n    }\n  };\n}\n\nvar pads = {\"-\": \"\", \"_\": \" \", \"0\": \"0\"};\nvar numberRe = /^\\s*\\d+/;\nvar percentRe = /^%/;\nvar requoteRe = /[\\\\\\^\\$\\*\\+\\?\\|\\[\\]\\(\\)\\.\\{\\}]/g;\n\nfunction pad(value, fill, width) {\n  var sign = value < 0 ? \"-\" : \"\",\n      string = (sign ? -value : value) + \"\",\n      length = string.length;\n  return sign + (length < width ? new Array(width - length + 1).join(fill) + string : string);\n}\n\nfunction requote(s) {\n  return s.replace(requoteRe, \"\\\\$&\");\n}\n\nfunction formatRe(names) {\n  return new RegExp(\"^(?:\" + names.map(requote).join(\"|\") + \")\", \"i\");\n}\n\nfunction formatLookup(names) {\n  var map = {}, i = -1, n = names.length;\n  while (++i < n) map[names[i].toLowerCase()] = i;\n  return map;\n}\n\nfunction parseWeekdayNumber(d, string, i) {\n  var n = numberRe.exec(string.slice(i, i + 1));\n  return n ? (d.w = +n[0], i + n[0].length) : -1;\n}\n\nfunction parseWeekNumberSunday(d, string, i) {\n  var n = numberRe.exec(string.slice(i));\n  return n ? (d.U = +n[0], i + n[0].length) : -1;\n}\n\nfunction parseWeekNumberMonday(d, string, i) {\n  var n = numberRe.exec(string.slice(i));\n  return n ? (d.W = +n[0], i + n[0].length) : -1;\n}\n\nfunction parseFullYear(d, string, i) {\n  var n = numberRe.exec(string.slice(i, i + 4));\n  return n ? (d.y = +n[0], i + n[0].length) : -1;\n}\n\nfunction parseYear(d, string, i) {\n  var n = numberRe.exec(string.slice(i, i + 2));\n  return n ? (d.y = +n[0] + (+n[0] > 68 ? 1900 : 2000), i + n[0].length) : -1;\n}\n\nfunction parseZone(d, string, i) {\n  var n = /^(Z)|([+-]\\d\\d)(?:\\:?(\\d\\d))?/.exec(string.slice(i, i + 6));\n  return n ? (d.Z = n[1] ? 0 : -(n[2] + (n[3] || \"00\")), i + n[0].length) : -1;\n}\n\nfunction parseMonthNumber(d, string, i) {\n  var n = numberRe.exec(string.slice(i, i + 2));\n  return n ? (d.m = n[0] - 1, i + n[0].length) : -1;\n}\n\nfunction parseDayOfMonth(d, string, i) {\n  var n = numberRe.exec(string.slice(i, i + 2));\n  return n ? (d.d = +n[0], i + n[0].length) : -1;\n}\n\nfunction parseDayOfYear(d, string, i) {\n  var n = numberRe.exec(string.slice(i, i + 3));\n  return n ? (d.m = 0, d.d = +n[0], i + n[0].length) : -1;\n}\n\nfunction parseHour24(d, string, i) {\n  var n = numberRe.exec(string.slice(i, i + 2));\n  return n ? (d.H = +n[0], i + n[0].length) : -1;\n}\n\nfunction parseMinutes(d, string, i) {\n  var n = numberRe.exec(string.slice(i, i + 2));\n  return n ? (d.M = +n[0], i + n[0].length) : -1;\n}\n\nfunction parseSeconds(d, string, i) {\n  var n = numberRe.exec(string.slice(i, i + 2));\n  return n ? (d.S = +n[0], i + n[0].length) : -1;\n}\n\nfunction parseMilliseconds(d, string, i) {\n  var n = numberRe.exec(string.slice(i, i + 3));\n  return n ? (d.L = +n[0], i + n[0].length) : -1;\n}\n\nfunction parseLiteralPercent(d, string, i) {\n  var n = percentRe.exec(string.slice(i, i + 1));\n  return n ? i + n[0].length : -1;\n}\n\nfunction formatDayOfMonth(d, p) {\n  return pad(d.getDate(), p, 2);\n}\n\nfunction formatHour24(d, p) {\n  return pad(d.getHours(), p, 2);\n}\n\nfunction formatHour12(d, p) {\n  return pad(d.getHours() % 12 || 12, p, 2);\n}\n\nfunction formatDayOfYear(d, p) {\n  return pad(1 + day.count(year(d), d), p, 3);\n}\n\nfunction formatMilliseconds(d, p) {\n  return pad(d.getMilliseconds(), p, 3);\n}\n\nfunction formatMonthNumber(d, p) {\n  return pad(d.getMonth() + 1, p, 2);\n}\n\nfunction formatMinutes(d, p) {\n  return pad(d.getMinutes(), p, 2);\n}\n\nfunction formatSeconds(d, p) {\n  return pad(d.getSeconds(), p, 2);\n}\n\nfunction formatWeekNumberSunday(d, p) {\n  return pad(sunday.count(year(d), d), p, 2);\n}\n\nfunction formatWeekdayNumber(d) {\n  return d.getDay();\n}\n\nfunction formatWeekNumberMonday(d, p) {\n  return pad(monday.count(year(d), d), p, 2);\n}\n\nfunction formatYear(d, p) {\n  return pad(d.getFullYear() % 100, p, 2);\n}\n\nfunction formatFullYear(d, p) {\n  return pad(d.getFullYear() % 10000, p, 4);\n}\n\nfunction formatZone(d) {\n  var z = d.getTimezoneOffset();\n  return (z > 0 ? \"-\" : (z *= -1, \"+\"))\n      + pad(z / 60 | 0, \"0\", 2)\n      + pad(z % 60, \"0\", 2);\n}\n\nfunction formatUTCDayOfMonth(d, p) {\n  return pad(d.getUTCDate(), p, 2);\n}\n\nfunction formatUTCHour24(d, p) {\n  return pad(d.getUTCHours(), p, 2);\n}\n\nfunction formatUTCHour12(d, p) {\n  return pad(d.getUTCHours() % 12 || 12, p, 2);\n}\n\nfunction formatUTCDayOfYear(d, p) {\n  return pad(1 + utcDay.count(utcYear(d), d), p, 3);\n}\n\nfunction formatUTCMilliseconds(d, p) {\n  return pad(d.getUTCMilliseconds(), p, 3);\n}\n\nfunction formatUTCMonthNumber(d, p) {\n  return pad(d.getUTCMonth() + 1, p, 2);\n}\n\nfunction formatUTCMinutes(d, p) {\n  return pad(d.getUTCMinutes(), p, 2);\n}\n\nfunction formatUTCSeconds(d, p) {\n  return pad(d.getUTCSeconds(), p, 2);\n}\n\nfunction formatUTCWeekNumberSunday(d, p) {\n  return pad(utcSunday.count(utcYear(d), d), p, 2);\n}\n\nfunction formatUTCWeekdayNumber(d) {\n  return d.getUTCDay();\n}\n\nfunction formatUTCWeekNumberMonday(d, p) {\n  return pad(utcMonday.count(utcYear(d), d), p, 2);\n}\n\nfunction formatUTCYear(d, p) {\n  return pad(d.getUTCFullYear() % 100, p, 2);\n}\n\nfunction formatUTCFullYear(d, p) {\n  return pad(d.getUTCFullYear() % 10000, p, 4);\n}\n\nfunction formatUTCZone() {\n  return \"+0000\";\n}\n\nfunction formatLiteralPercent() {\n  return \"%\";\n}\n\nvar locale$2;\n\n\n\n\n\ndefaultLocale$1({\n  dateTime: \"%x, %X\",\n  date: \"%-m/%-d/%Y\",\n  time: \"%-I:%M:%S %p\",\n  periods: [\"AM\", \"PM\"],\n  days: [\"Sunday\", \"Monday\", \"Tuesday\", \"Wednesday\", \"Thursday\", \"Friday\", \"Saturday\"],\n  shortDays: [\"Sun\", \"Mon\", \"Tue\", \"Wed\", \"Thu\", \"Fri\", \"Sat\"],\n  months: [\"January\", \"February\", \"March\", \"April\", \"May\", \"June\", \"July\", \"August\", \"September\", \"October\", \"November\", \"December\"],\n  shortMonths: [\"Jan\", \"Feb\", \"Mar\", \"Apr\", \"May\", \"Jun\", \"Jul\", \"Aug\", \"Sep\", \"Oct\", \"Nov\", \"Dec\"]\n});\n\nfunction defaultLocale$1(definition) {\n  locale$2 = formatLocale$1(definition);\n  exports.timeFormat = locale$2.format;\n  exports.timeParse = locale$2.parse;\n  exports.utcFormat = locale$2.utcFormat;\n  exports.utcParse = locale$2.utcParse;\n  return locale$2;\n}\n\nvar isoSpecifier = \"%Y-%m-%dT%H:%M:%S.%LZ\";\n\nfunction formatIsoNative(date) {\n  return date.toISOString();\n}\n\nvar formatIso = Date.prototype.toISOString\n    ? formatIsoNative\n    : exports.utcFormat(isoSpecifier);\n\nfunction parseIsoNative(string) {\n  var date = new Date(string);\n  return isNaN(date) ? null : date;\n}\n\nvar parseIso = +new Date(\"2000-01-01T00:00:00.000Z\")\n    ? parseIsoNative\n    : exports.utcParse(isoSpecifier);\n\nvar durationSecond = 1000;\nvar durationMinute = durationSecond * 60;\nvar durationHour = durationMinute * 60;\nvar durationDay = durationHour * 24;\nvar durationWeek = durationDay * 7;\nvar durationMonth = durationDay * 30;\nvar durationYear = durationDay * 365;\n\nfunction date$1(t) {\n  return new Date(t);\n}\n\nfunction number$2(t) {\n  return t instanceof Date ? +t : +new Date(+t);\n}\n\nfunction calendar(year$$1, month$$1, week, day$$1, hour$$1, minute$$1, second$$1, millisecond$$1, format) {\n  var scale = continuous(deinterpolateLinear, reinterpolate),\n      invert = scale.invert,\n      domain = scale.domain;\n\n  var formatMillisecond = format(\".%L\"),\n      formatSecond = format(\":%S\"),\n      formatMinute = format(\"%I:%M\"),\n      formatHour = format(\"%I %p\"),\n      formatDay = format(\"%a %d\"),\n      formatWeek = format(\"%b %d\"),\n      formatMonth = format(\"%B\"),\n      formatYear = format(\"%Y\");\n\n  var tickIntervals = [\n    [second$$1,  1,      durationSecond],\n    [second$$1,  5,  5 * durationSecond],\n    [second$$1, 15, 15 * durationSecond],\n    [second$$1, 30, 30 * durationSecond],\n    [minute$$1,  1,      durationMinute],\n    [minute$$1,  5,  5 * durationMinute],\n    [minute$$1, 15, 15 * durationMinute],\n    [minute$$1, 30, 30 * durationMinute],\n    [  hour$$1,  1,      durationHour  ],\n    [  hour$$1,  3,  3 * durationHour  ],\n    [  hour$$1,  6,  6 * durationHour  ],\n    [  hour$$1, 12, 12 * durationHour  ],\n    [   day$$1,  1,      durationDay   ],\n    [   day$$1,  2,  2 * durationDay   ],\n    [  week,  1,      durationWeek  ],\n    [ month$$1,  1,      durationMonth ],\n    [ month$$1,  3,  3 * durationMonth ],\n    [  year$$1,  1,      durationYear  ]\n  ];\n\n  function tickFormat(date) {\n    return (second$$1(date) < date ? formatMillisecond\n        : minute$$1(date) < date ? formatSecond\n        : hour$$1(date) < date ? formatMinute\n        : day$$1(date) < date ? formatHour\n        : month$$1(date) < date ? (week(date) < date ? formatDay : formatWeek)\n        : year$$1(date) < date ? formatMonth\n        : formatYear)(date);\n  }\n\n  function tickInterval(interval, start, stop, step) {\n    if (interval == null) interval = 10;\n\n    // If a desired tick count is specified, pick a reasonable tick interval\n    // based on the extent of the domain and a rough estimate of tick size.\n    // Otherwise, assume interval is already a time interval and use it.\n    if (typeof interval === \"number\") {\n      var target = Math.abs(stop - start) / interval,\n          i = bisector(function(i) { return i[2]; }).right(tickIntervals, target);\n      if (i === tickIntervals.length) {\n        step = tickStep(start / durationYear, stop / durationYear, interval);\n        interval = year$$1;\n      } else if (i) {\n        i = tickIntervals[target / tickIntervals[i - 1][2] < tickIntervals[i][2] / target ? i - 1 : i];\n        step = i[1];\n        interval = i[0];\n      } else {\n        step = tickStep(start, stop, interval);\n        interval = millisecond$$1;\n      }\n    }\n\n    return step == null ? interval : interval.every(step);\n  }\n\n  scale.invert = function(y) {\n    return new Date(invert(y));\n  };\n\n  scale.domain = function(_) {\n    return arguments.length ? domain(map$3.call(_, number$2)) : domain().map(date$1);\n  };\n\n  scale.ticks = function(interval, step) {\n    var d = domain(),\n        t0 = d[0],\n        t1 = d[d.length - 1],\n        r = t1 < t0,\n        t;\n    if (r) t = t0, t0 = t1, t1 = t;\n    t = tickInterval(interval, t0, t1, step);\n    t = t ? t.range(t0, t1 + 1) : []; // inclusive stop\n    return r ? t.reverse() : t;\n  };\n\n  scale.tickFormat = function(count, specifier) {\n    return specifier == null ? tickFormat : format(specifier);\n  };\n\n  scale.nice = function(interval, step) {\n    var d = domain();\n    return (interval = tickInterval(interval, d[0], d[d.length - 1], step))\n        ? domain(nice(d, interval))\n        : scale;\n  };\n\n  scale.copy = function() {\n    return copy(scale, calendar(year$$1, month$$1, week, day$$1, hour$$1, minute$$1, second$$1, millisecond$$1, format));\n  };\n\n  return scale;\n}\n\nvar time = function() {\n  return calendar(year, month, sunday, day, hour, minute, second, millisecond, exports.timeFormat).domain([new Date(2000, 0, 1), new Date(2000, 0, 2)]);\n};\n\nvar utcTime = function() {\n  return calendar(utcYear, utcMonth, utcSunday, utcDay, utcHour, utcMinute, second, millisecond, exports.utcFormat).domain([Date.UTC(2000, 0, 1), Date.UTC(2000, 0, 2)]);\n};\n\nvar colors = function(s) {\n  return s.match(/.{6}/g).map(function(x) {\n    return \"#\" + x;\n  });\n};\n\nvar category10 = colors(\"1f77b4ff7f0e2ca02cd627289467bd8c564be377c27f7f7fbcbd2217becf\");\n\nvar category20b = colors(\"393b795254a36b6ecf9c9ede6379398ca252b5cf6bcedb9c8c6d31bd9e39e7ba52e7cb94843c39ad494ad6616be7969c7b4173a55194ce6dbdde9ed6\");\n\nvar category20c = colors(\"3182bd6baed69ecae1c6dbefe6550dfd8d3cfdae6bfdd0a231a35474c476a1d99bc7e9c0756bb19e9ac8bcbddcdadaeb636363969696bdbdbdd9d9d9\");\n\nvar category20 = colors(\"1f77b4aec7e8ff7f0effbb782ca02c98df8ad62728ff98969467bdc5b0d58c564bc49c94e377c2f7b6d27f7f7fc7c7c7bcbd22dbdb8d17becf9edae5\");\n\nvar cubehelix$3 = cubehelixLong(cubehelix(300, 0.5, 0.0), cubehelix(-240, 0.5, 1.0));\n\nvar warm = cubehelixLong(cubehelix(-100, 0.75, 0.35), cubehelix(80, 1.50, 0.8));\n\nvar cool = cubehelixLong(cubehelix(260, 0.75, 0.35), cubehelix(80, 1.50, 0.8));\n\nvar rainbow = cubehelix();\n\nvar rainbow$1 = function(t) {\n  if (t < 0 || t > 1) t -= Math.floor(t);\n  var ts = Math.abs(t - 0.5);\n  rainbow.h = 360 * t - 100;\n  rainbow.s = 1.5 - 1.5 * ts;\n  rainbow.l = 0.8 - 0.9 * ts;\n  return rainbow + \"\";\n};\n\nfunction ramp(range) {\n  var n = range.length;\n  return function(t) {\n    return range[Math.max(0, Math.min(n - 1, Math.floor(t * n)))];\n  };\n}\n\nvar viridis = ramp(colors(\"44015444025645045745055946075a46085c460a5d460b5e470d60470e6147106347116447136548146748166848176948186a481a6c481b6d481c6e481d6f481f70482071482173482374482475482576482677482878482979472a7a472c7a472d7b472e7c472f7d46307e46327e46337f463480453581453781453882443983443a83443b84433d84433e85423f854240864241864142874144874045884046883f47883f48893e49893e4a893e4c8a3d4d8a3d4e8a3c4f8a3c508b3b518b3b528b3a538b3a548c39558c39568c38588c38598c375a8c375b8d365c8d365d8d355e8d355f8d34608d34618d33628d33638d32648e32658e31668e31678e31688e30698e306a8e2f6b8e2f6c8e2e6d8e2e6e8e2e6f8e2d708e2d718e2c718e2c728e2c738e2b748e2b758e2a768e2a778e2a788e29798e297a8e297b8e287c8e287d8e277e8e277f8e27808e26818e26828e26828e25838e25848e25858e24868e24878e23888e23898e238a8d228b8d228c8d228d8d218e8d218f8d21908d21918c20928c20928c20938c1f948c1f958b1f968b1f978b1f988b1f998a1f9a8a1e9b8a1e9c891e9d891f9e891f9f881fa0881fa1881fa1871fa28720a38620a48621a58521a68522a78522a88423a98324aa8325ab8225ac8226ad8127ad8128ae8029af7f2ab07f2cb17e2db27d2eb37c2fb47c31b57b32b67a34b67935b77937b87838b9773aba763bbb753dbc743fbc7340bd7242be7144bf7046c06f48c16e4ac16d4cc26c4ec36b50c46a52c56954c56856c66758c7655ac8645cc8635ec96260ca6063cb5f65cb5e67cc5c69cd5b6ccd5a6ece5870cf5773d05675d05477d1537ad1517cd2507fd34e81d34d84d44b86d54989d5488bd6468ed64590d74393d74195d84098d83e9bd93c9dd93ba0da39a2da37a5db36a8db34aadc32addc30b0dd2fb2dd2db5de2bb8de29bade28bddf26c0df25c2df23c5e021c8e020cae11fcde11dd0e11cd2e21bd5e21ad8e219dae319dde318dfe318e2e418e5e419e7e419eae51aece51befe51cf1e51df4e61ef6e620f8e621fbe723fde725\"));\n\nvar magma = ramp(colors(\"00000401000501010601010802010902020b02020d03030f03031204041405041606051806051a07061c08071e0907200a08220b09240c09260d0a290e0b2b100b2d110c2f120d31130d34140e36150e38160f3b180f3d19103f1a10421c10441d11471e114920114b21114e22115024125325125527125829115a2a115c2c115f2d11612f116331116533106734106936106b38106c390f6e3b0f703d0f713f0f72400f74420f75440f764510774710784910784a10794c117a4e117b4f127b51127c52137c54137d56147d57157e59157e5a167e5c167f5d177f5f187f601880621980641a80651a80671b80681c816a1c816b1d816d1d816e1e81701f81721f817320817521817621817822817922827b23827c23827e24828025828125818326818426818627818827818928818b29818c29818e2a81902a81912b81932b80942c80962c80982d80992d809b2e7f9c2e7f9e2f7fa02f7fa1307ea3307ea5317ea6317da8327daa337dab337cad347cae347bb0357bb2357bb3367ab5367ab73779b83779ba3878bc3978bd3977bf3a77c03a76c23b75c43c75c53c74c73d73c83e73ca3e72cc3f71cd4071cf4070d0416fd2426fd3436ed5446dd6456cd8456cd9466bdb476adc4869de4968df4a68e04c67e24d66e34e65e44f64e55064e75263e85362e95462ea5661eb5760ec5860ed5a5fee5b5eef5d5ef05f5ef1605df2625df2645cf3655cf4675cf4695cf56b5cf66c5cf66e5cf7705cf7725cf8745cf8765cf9785df9795df97b5dfa7d5efa7f5efa815ffb835ffb8560fb8761fc8961fc8a62fc8c63fc8e64fc9065fd9266fd9467fd9668fd9869fd9a6afd9b6bfe9d6cfe9f6dfea16efea36ffea571fea772fea973feaa74feac76feae77feb078feb27afeb47bfeb67cfeb77efeb97ffebb81febd82febf84fec185fec287fec488fec68afec88cfeca8dfecc8ffecd90fecf92fed194fed395fed597fed799fed89afdda9cfddc9efddea0fde0a1fde2a3fde3a5fde5a7fde7a9fde9aafdebacfcecaefceeb0fcf0b2fcf2b4fcf4b6fcf6b8fcf7b9fcf9bbfcfbbdfcfdbf\"));\n\nvar inferno = ramp(colors(\"00000401000501010601010802010a02020c02020e03021004031204031405041706041907051b08051d09061f0a07220b07240c08260d08290e092b10092d110a30120a32140b34150b37160b39180c3c190c3e1b0c411c0c431e0c451f0c48210c4a230c4c240c4f260c51280b53290b552b0b572d0b592f0a5b310a5c320a5e340a5f3609613809623909633b09643d09653e0966400a67420a68440a68450a69470b6a490b6a4a0c6b4c0c6b4d0d6c4f0d6c510e6c520e6d540f6d550f6d57106e59106e5a116e5c126e5d126e5f136e61136e62146e64156e65156e67166e69166e6a176e6c186e6d186e6f196e71196e721a6e741a6e751b6e771c6d781c6d7a1d6d7c1d6d7d1e6d7f1e6c801f6c82206c84206b85216b87216b88226a8a226a8c23698d23698f24699025689225689326679526679727669827669a28659b29649d29649f2a63a02a63a22b62a32c61a52c60a62d60a82e5fa92e5eab2f5ead305dae305cb0315bb1325ab3325ab43359b63458b73557b93556ba3655bc3754bd3853bf3952c03a51c13a50c33b4fc43c4ec63d4dc73e4cc83f4bca404acb4149cc4248ce4347cf4446d04545d24644d34743d44842d54a41d74b3fd84c3ed94d3dda4e3cdb503bdd513ade5238df5337e05536e15635e25734e35933e45a31e55c30e65d2fe75e2ee8602de9612bea632aeb6429eb6628ec6726ed6925ee6a24ef6c23ef6e21f06f20f1711ff1731df2741cf3761bf37819f47918f57b17f57d15f67e14f68013f78212f78410f8850ff8870ef8890cf98b0bf98c0af98e09fa9008fa9207fa9407fb9606fb9706fb9906fb9b06fb9d07fc9f07fca108fca309fca50afca60cfca80dfcaa0ffcac11fcae12fcb014fcb216fcb418fbb61afbb81dfbba1ffbbc21fbbe23fac026fac228fac42afac62df9c72ff9c932f9cb35f8cd37f8cf3af7d13df7d340f6d543f6d746f5d949f5db4cf4dd4ff4df53f4e156f3e35af3e55df2e661f2e865f2ea69f1ec6df1ed71f1ef75f1f179f2f27df2f482f3f586f3f68af4f88ef5f992f6fa96f8fb9af9fc9dfafda1fcffa4\"));\n\nvar plasma = ramp(colors(\"0d088710078813078916078a19068c1b068d1d068e20068f2206902406912605912805922a05932c05942e05952f059631059733059735049837049938049a3a049a3c049b3e049c3f049c41049d43039e44039e46039f48039f4903a04b03a14c02a14e02a25002a25102a35302a35502a45601a45801a45901a55b01a55c01a65e01a66001a66100a76300a76400a76600a76700a86900a86a00a86c00a86e00a86f00a87100a87201a87401a87501a87701a87801a87a02a87b02a87d03a87e03a88004a88104a78305a78405a78606a68707a68808a68a09a58b0aa58d0ba58e0ca48f0da4910ea3920fa39410a29511a19613a19814a099159f9a169f9c179e9d189d9e199da01a9ca11b9ba21d9aa31e9aa51f99a62098a72197a82296aa2395ab2494ac2694ad2793ae2892b02991b12a90b22b8fb32c8eb42e8db52f8cb6308bb7318ab83289ba3388bb3488bc3587bd3786be3885bf3984c03a83c13b82c23c81c33d80c43e7fc5407ec6417dc7427cc8437bc9447aca457acb4679cc4778cc4977cd4a76ce4b75cf4c74d04d73d14e72d24f71d35171d45270d5536fd5546ed6556dd7566cd8576bd9586ada5a6ada5b69db5c68dc5d67dd5e66de5f65de6164df6263e06363e16462e26561e26660e3685fe4695ee56a5de56b5de66c5ce76e5be76f5ae87059e97158e97257ea7457eb7556eb7655ec7754ed7953ed7a52ee7b51ef7c51ef7e50f07f4ff0804ef1814df1834cf2844bf3854bf3874af48849f48948f58b47f58c46f68d45f68f44f79044f79143f79342f89441f89540f9973ff9983ef99a3efa9b3dfa9c3cfa9e3bfb9f3afba139fba238fca338fca537fca636fca835fca934fdab33fdac33fdae32fdaf31fdb130fdb22ffdb42ffdb52efeb72dfeb82cfeba2cfebb2bfebd2afebe2afec029fdc229fdc328fdc527fdc627fdc827fdca26fdcb26fccd25fcce25fcd025fcd225fbd324fbd524fbd724fad824fada24f9dc24f9dd25f8df25f8e125f7e225f7e425f6e626f6e826f5e926f5eb27f4ed27f3ee27f3f027f2f227f1f426f1f525f0f724f0f921\"));\n\nfunction sequential(interpolator) {\n  var x0 = 0,\n      x1 = 1,\n      clamp = false;\n\n  function scale(x) {\n    var t = (x - x0) / (x1 - x0);\n    return interpolator(clamp ? Math.max(0, Math.min(1, t)) : t);\n  }\n\n  scale.domain = function(_) {\n    return arguments.length ? (x0 = +_[0], x1 = +_[1], scale) : [x0, x1];\n  };\n\n  scale.clamp = function(_) {\n    return arguments.length ? (clamp = !!_, scale) : clamp;\n  };\n\n  scale.interpolator = function(_) {\n    return arguments.length ? (interpolator = _, scale) : interpolator;\n  };\n\n  scale.copy = function() {\n    return sequential(interpolator).domain([x0, x1]).clamp(clamp);\n  };\n\n  return linearish(scale);\n}\n\nvar constant$10 = function(x) {\n  return function constant() {\n    return x;\n  };\n};\n\nvar abs$1 = Math.abs;\nvar atan2$1 = Math.atan2;\nvar cos$2 = Math.cos;\nvar max$2 = Math.max;\nvar min$1 = Math.min;\nvar sin$2 = Math.sin;\nvar sqrt$2 = Math.sqrt;\n\nvar epsilon$3 = 1e-12;\nvar pi$4 = Math.PI;\nvar halfPi$3 = pi$4 / 2;\nvar tau$4 = 2 * pi$4;\n\nfunction acos$1(x) {\n  return x > 1 ? 0 : x < -1 ? pi$4 : Math.acos(x);\n}\n\nfunction asin$1(x) {\n  return x >= 1 ? halfPi$3 : x <= -1 ? -halfPi$3 : Math.asin(x);\n}\n\nfunction arcInnerRadius(d) {\n  return d.innerRadius;\n}\n\nfunction arcOuterRadius(d) {\n  return d.outerRadius;\n}\n\nfunction arcStartAngle(d) {\n  return d.startAngle;\n}\n\nfunction arcEndAngle(d) {\n  return d.endAngle;\n}\n\nfunction arcPadAngle(d) {\n  return d && d.padAngle; // Note: optional!\n}\n\nfunction intersect(x0, y0, x1, y1, x2, y2, x3, y3) {\n  var x10 = x1 - x0, y10 = y1 - y0,\n      x32 = x3 - x2, y32 = y3 - y2,\n      t = (x32 * (y0 - y2) - y32 * (x0 - x2)) / (y32 * x10 - x32 * y10);\n  return [x0 + t * x10, y0 + t * y10];\n}\n\n// Compute perpendicular offset line of length rc.\n// http://mathworld.wolfram.com/Circle-LineIntersection.html\nfunction cornerTangents(x0, y0, x1, y1, r1, rc, cw) {\n  var x01 = x0 - x1,\n      y01 = y0 - y1,\n      lo = (cw ? rc : -rc) / sqrt$2(x01 * x01 + y01 * y01),\n      ox = lo * y01,\n      oy = -lo * x01,\n      x11 = x0 + ox,\n      y11 = y0 + oy,\n      x10 = x1 + ox,\n      y10 = y1 + oy,\n      x00 = (x11 + x10) / 2,\n      y00 = (y11 + y10) / 2,\n      dx = x10 - x11,\n      dy = y10 - y11,\n      d2 = dx * dx + dy * dy,\n      r = r1 - rc,\n      D = x11 * y10 - x10 * y11,\n      d = (dy < 0 ? -1 : 1) * sqrt$2(max$2(0, r * r * d2 - D * D)),\n      cx0 = (D * dy - dx * d) / d2,\n      cy0 = (-D * dx - dy * d) / d2,\n      cx1 = (D * dy + dx * d) / d2,\n      cy1 = (-D * dx + dy * d) / d2,\n      dx0 = cx0 - x00,\n      dy0 = cy0 - y00,\n      dx1 = cx1 - x00,\n      dy1 = cy1 - y00;\n\n  // Pick the closer of the two intersection points.\n  // TODO Is there a faster way to determine which intersection to use?\n  if (dx0 * dx0 + dy0 * dy0 > dx1 * dx1 + dy1 * dy1) cx0 = cx1, cy0 = cy1;\n\n  return {\n    cx: cx0,\n    cy: cy0,\n    x01: -ox,\n    y01: -oy,\n    x11: cx0 * (r1 / r - 1),\n    y11: cy0 * (r1 / r - 1)\n  };\n}\n\nvar arc = function() {\n  var innerRadius = arcInnerRadius,\n      outerRadius = arcOuterRadius,\n      cornerRadius = constant$10(0),\n      padRadius = null,\n      startAngle = arcStartAngle,\n      endAngle = arcEndAngle,\n      padAngle = arcPadAngle,\n      context = null;\n\n  function arc() {\n    var buffer,\n        r,\n        r0 = +innerRadius.apply(this, arguments),\n        r1 = +outerRadius.apply(this, arguments),\n        a0 = startAngle.apply(this, arguments) - halfPi$3,\n        a1 = endAngle.apply(this, arguments) - halfPi$3,\n        da = abs$1(a1 - a0),\n        cw = a1 > a0;\n\n    if (!context) context = buffer = path();\n\n    // Ensure that the outer radius is always larger than the inner radius.\n    if (r1 < r0) r = r1, r1 = r0, r0 = r;\n\n    // Is it a point?\n    if (!(r1 > epsilon$3)) context.moveTo(0, 0);\n\n    // Or is it a circle or annulus?\n    else if (da > tau$4 - epsilon$3) {\n      context.moveTo(r1 * cos$2(a0), r1 * sin$2(a0));\n      context.arc(0, 0, r1, a0, a1, !cw);\n      if (r0 > epsilon$3) {\n        context.moveTo(r0 * cos$2(a1), r0 * sin$2(a1));\n        context.arc(0, 0, r0, a1, a0, cw);\n      }\n    }\n\n    // Or is it a circular or annular sector?\n    else {\n      var a01 = a0,\n          a11 = a1,\n          a00 = a0,\n          a10 = a1,\n          da0 = da,\n          da1 = da,\n          ap = padAngle.apply(this, arguments) / 2,\n          rp = (ap > epsilon$3) && (padRadius ? +padRadius.apply(this, arguments) : sqrt$2(r0 * r0 + r1 * r1)),\n          rc = min$1(abs$1(r1 - r0) / 2, +cornerRadius.apply(this, arguments)),\n          rc0 = rc,\n          rc1 = rc,\n          t0,\n          t1;\n\n      // Apply padding? Note that since r1 ≥ r0, da1 ≥ da0.\n      if (rp > epsilon$3) {\n        var p0 = asin$1(rp / r0 * sin$2(ap)),\n            p1 = asin$1(rp / r1 * sin$2(ap));\n        if ((da0 -= p0 * 2) > epsilon$3) p0 *= (cw ? 1 : -1), a00 += p0, a10 -= p0;\n        else da0 = 0, a00 = a10 = (a0 + a1) / 2;\n        if ((da1 -= p1 * 2) > epsilon$3) p1 *= (cw ? 1 : -1), a01 += p1, a11 -= p1;\n        else da1 = 0, a01 = a11 = (a0 + a1) / 2;\n      }\n\n      var x01 = r1 * cos$2(a01),\n          y01 = r1 * sin$2(a01),\n          x10 = r0 * cos$2(a10),\n          y10 = r0 * sin$2(a10);\n\n      // Apply rounded corners?\n      if (rc > epsilon$3) {\n        var x11 = r1 * cos$2(a11),\n            y11 = r1 * sin$2(a11),\n            x00 = r0 * cos$2(a00),\n            y00 = r0 * sin$2(a00);\n\n        // Restrict the corner radius according to the sector angle.\n        if (da < pi$4) {\n          var oc = da0 > epsilon$3 ? intersect(x01, y01, x00, y00, x11, y11, x10, y10) : [x10, y10],\n              ax = x01 - oc[0],\n              ay = y01 - oc[1],\n              bx = x11 - oc[0],\n              by = y11 - oc[1],\n              kc = 1 / sin$2(acos$1((ax * bx + ay * by) / (sqrt$2(ax * ax + ay * ay) * sqrt$2(bx * bx + by * by))) / 2),\n              lc = sqrt$2(oc[0] * oc[0] + oc[1] * oc[1]);\n          rc0 = min$1(rc, (r0 - lc) / (kc - 1));\n          rc1 = min$1(rc, (r1 - lc) / (kc + 1));\n        }\n      }\n\n      // Is the sector collapsed to a line?\n      if (!(da1 > epsilon$3)) context.moveTo(x01, y01);\n\n      // Does the sector’s outer ring have rounded corners?\n      else if (rc1 > epsilon$3) {\n        t0 = cornerTangents(x00, y00, x01, y01, r1, rc1, cw);\n        t1 = cornerTangents(x11, y11, x10, y10, r1, rc1, cw);\n\n        context.moveTo(t0.cx + t0.x01, t0.cy + t0.y01);\n\n        // Have the corners merged?\n        if (rc1 < rc) context.arc(t0.cx, t0.cy, rc1, atan2$1(t0.y01, t0.x01), atan2$1(t1.y01, t1.x01), !cw);\n\n        // Otherwise, draw the two corners and the ring.\n        else {\n          context.arc(t0.cx, t0.cy, rc1, atan2$1(t0.y01, t0.x01), atan2$1(t0.y11, t0.x11), !cw);\n          context.arc(0, 0, r1, atan2$1(t0.cy + t0.y11, t0.cx + t0.x11), atan2$1(t1.cy + t1.y11, t1.cx + t1.x11), !cw);\n          context.arc(t1.cx, t1.cy, rc1, atan2$1(t1.y11, t1.x11), atan2$1(t1.y01, t1.x01), !cw);\n        }\n      }\n\n      // Or is the outer ring just a circular arc?\n      else context.moveTo(x01, y01), context.arc(0, 0, r1, a01, a11, !cw);\n\n      // Is there no inner ring, and it’s a circular sector?\n      // Or perhaps it’s an annular sector collapsed due to padding?\n      if (!(r0 > epsilon$3) || !(da0 > epsilon$3)) context.lineTo(x10, y10);\n\n      // Does the sector’s inner ring (or point) have rounded corners?\n      else if (rc0 > epsilon$3) {\n        t0 = cornerTangents(x10, y10, x11, y11, r0, -rc0, cw);\n        t1 = cornerTangents(x01, y01, x00, y00, r0, -rc0, cw);\n\n        context.lineTo(t0.cx + t0.x01, t0.cy + t0.y01);\n\n        // Have the corners merged?\n        if (rc0 < rc) context.arc(t0.cx, t0.cy, rc0, atan2$1(t0.y01, t0.x01), atan2$1(t1.y01, t1.x01), !cw);\n\n        // Otherwise, draw the two corners and the ring.\n        else {\n          context.arc(t0.cx, t0.cy, rc0, atan2$1(t0.y01, t0.x01), atan2$1(t0.y11, t0.x11), !cw);\n          context.arc(0, 0, r0, atan2$1(t0.cy + t0.y11, t0.cx + t0.x11), atan2$1(t1.cy + t1.y11, t1.cx + t1.x11), cw);\n          context.arc(t1.cx, t1.cy, rc0, atan2$1(t1.y11, t1.x11), atan2$1(t1.y01, t1.x01), !cw);\n        }\n      }\n\n      // Or is the inner ring just a circular arc?\n      else context.arc(0, 0, r0, a10, a00, cw);\n    }\n\n    context.closePath();\n\n    if (buffer) return context = null, buffer + \"\" || null;\n  }\n\n  arc.centroid = function() {\n    var r = (+innerRadius.apply(this, arguments) + +outerRadius.apply(this, arguments)) / 2,\n        a = (+startAngle.apply(this, arguments) + +endAngle.apply(this, arguments)) / 2 - pi$4 / 2;\n    return [cos$2(a) * r, sin$2(a) * r];\n  };\n\n  arc.innerRadius = function(_) {\n    return arguments.length ? (innerRadius = typeof _ === \"function\" ? _ : constant$10(+_), arc) : innerRadius;\n  };\n\n  arc.outerRadius = function(_) {\n    return arguments.length ? (outerRadius = typeof _ === \"function\" ? _ : constant$10(+_), arc) : outerRadius;\n  };\n\n  arc.cornerRadius = function(_) {\n    return arguments.length ? (cornerRadius = typeof _ === \"function\" ? _ : constant$10(+_), arc) : cornerRadius;\n  };\n\n  arc.padRadius = function(_) {\n    return arguments.length ? (padRadius = _ == null ? null : typeof _ === \"function\" ? _ : constant$10(+_), arc) : padRadius;\n  };\n\n  arc.startAngle = function(_) {\n    return arguments.length ? (startAngle = typeof _ === \"function\" ? _ : constant$10(+_), arc) : startAngle;\n  };\n\n  arc.endAngle = function(_) {\n    return arguments.length ? (endAngle = typeof _ === \"function\" ? _ : constant$10(+_), arc) : endAngle;\n  };\n\n  arc.padAngle = function(_) {\n    return arguments.length ? (padAngle = typeof _ === \"function\" ? _ : constant$10(+_), arc) : padAngle;\n  };\n\n  arc.context = function(_) {\n    return arguments.length ? ((context = _ == null ? null : _), arc) : context;\n  };\n\n  return arc;\n};\n\nfunction Linear(context) {\n  this._context = context;\n}\n\nLinear.prototype = {\n  areaStart: function() {\n    this._line = 0;\n  },\n  areaEnd: function() {\n    this._line = NaN;\n  },\n  lineStart: function() {\n    this._point = 0;\n  },\n  lineEnd: function() {\n    if (this._line || (this._line !== 0 && this._point === 1)) this._context.closePath();\n    this._line = 1 - this._line;\n  },\n  point: function(x, y) {\n    x = +x, y = +y;\n    switch (this._point) {\n      case 0: this._point = 1; this._line ? this._context.lineTo(x, y) : this._context.moveTo(x, y); break;\n      case 1: this._point = 2; // proceed\n      default: this._context.lineTo(x, y); break;\n    }\n  }\n};\n\nvar curveLinear = function(context) {\n  return new Linear(context);\n};\n\nfunction x$3(p) {\n  return p[0];\n}\n\nfunction y$3(p) {\n  return p[1];\n}\n\nvar line = function() {\n  var x$$1 = x$3,\n      y$$1 = y$3,\n      defined = constant$10(true),\n      context = null,\n      curve = curveLinear,\n      output = null;\n\n  function line(data) {\n    var i,\n        n = data.length,\n        d,\n        defined0 = false,\n        buffer;\n\n    if (context == null) output = curve(buffer = path());\n\n    for (i = 0; i <= n; ++i) {\n      if (!(i < n && defined(d = data[i], i, data)) === defined0) {\n        if (defined0 = !defined0) output.lineStart();\n        else output.lineEnd();\n      }\n      if (defined0) output.point(+x$$1(d, i, data), +y$$1(d, i, data));\n    }\n\n    if (buffer) return output = null, buffer + \"\" || null;\n  }\n\n  line.x = function(_) {\n    return arguments.length ? (x$$1 = typeof _ === \"function\" ? _ : constant$10(+_), line) : x$$1;\n  };\n\n  line.y = function(_) {\n    return arguments.length ? (y$$1 = typeof _ === \"function\" ? _ : constant$10(+_), line) : y$$1;\n  };\n\n  line.defined = function(_) {\n    return arguments.length ? (defined = typeof _ === \"function\" ? _ : constant$10(!!_), line) : defined;\n  };\n\n  line.curve = function(_) {\n    return arguments.length ? (curve = _, context != null && (output = curve(context)), line) : curve;\n  };\n\n  line.context = function(_) {\n    return arguments.length ? (_ == null ? context = output = null : output = curve(context = _), line) : context;\n  };\n\n  return line;\n};\n\nvar area$2 = function() {\n  var x0 = x$3,\n      x1 = null,\n      y0 = constant$10(0),\n      y1 = y$3,\n      defined = constant$10(true),\n      context = null,\n      curve = curveLinear,\n      output = null;\n\n  function area(data) {\n    var i,\n        j,\n        k,\n        n = data.length,\n        d,\n        defined0 = false,\n        buffer,\n        x0z = new Array(n),\n        y0z = new Array(n);\n\n    if (context == null) output = curve(buffer = path());\n\n    for (i = 0; i <= n; ++i) {\n      if (!(i < n && defined(d = data[i], i, data)) === defined0) {\n        if (defined0 = !defined0) {\n          j = i;\n          output.areaStart();\n          output.lineStart();\n        } else {\n          output.lineEnd();\n          output.lineStart();\n          for (k = i - 1; k >= j; --k) {\n            output.point(x0z[k], y0z[k]);\n          }\n          output.lineEnd();\n          output.areaEnd();\n        }\n      }\n      if (defined0) {\n        x0z[i] = +x0(d, i, data), y0z[i] = +y0(d, i, data);\n        output.point(x1 ? +x1(d, i, data) : x0z[i], y1 ? +y1(d, i, data) : y0z[i]);\n      }\n    }\n\n    if (buffer) return output = null, buffer + \"\" || null;\n  }\n\n  function arealine() {\n    return line().defined(defined).curve(curve).context(context);\n  }\n\n  area.x = function(_) {\n    return arguments.length ? (x0 = typeof _ === \"function\" ? _ : constant$10(+_), x1 = null, area) : x0;\n  };\n\n  area.x0 = function(_) {\n    return arguments.length ? (x0 = typeof _ === \"function\" ? _ : constant$10(+_), area) : x0;\n  };\n\n  area.x1 = function(_) {\n    return arguments.length ? (x1 = _ == null ? null : typeof _ === \"function\" ? _ : constant$10(+_), area) : x1;\n  };\n\n  area.y = function(_) {\n    return arguments.length ? (y0 = typeof _ === \"function\" ? _ : constant$10(+_), y1 = null, area) : y0;\n  };\n\n  area.y0 = function(_) {\n    return arguments.length ? (y0 = typeof _ === \"function\" ? _ : constant$10(+_), area) : y0;\n  };\n\n  area.y1 = function(_) {\n    return arguments.length ? (y1 = _ == null ? null : typeof _ === \"function\" ? _ : constant$10(+_), area) : y1;\n  };\n\n  area.lineX0 =\n  area.lineY0 = function() {\n    return arealine().x(x0).y(y0);\n  };\n\n  area.lineY1 = function() {\n    return arealine().x(x0).y(y1);\n  };\n\n  area.lineX1 = function() {\n    return arealine().x(x1).y(y0);\n  };\n\n  area.defined = function(_) {\n    return arguments.length ? (defined = typeof _ === \"function\" ? _ : constant$10(!!_), area) : defined;\n  };\n\n  area.curve = function(_) {\n    return arguments.length ? (curve = _, context != null && (output = curve(context)), area) : curve;\n  };\n\n  area.context = function(_) {\n    return arguments.length ? (_ == null ? context = output = null : output = curve(context = _), area) : context;\n  };\n\n  return area;\n};\n\nvar descending$1 = function(a, b) {\n  return b < a ? -1 : b > a ? 1 : b >= a ? 0 : NaN;\n};\n\nvar identity$7 = function(d) {\n  return d;\n};\n\nvar pie = function() {\n  var value = identity$7,\n      sortValues = descending$1,\n      sort = null,\n      startAngle = constant$10(0),\n      endAngle = constant$10(tau$4),\n      padAngle = constant$10(0);\n\n  function pie(data) {\n    var i,\n        n = data.length,\n        j,\n        k,\n        sum = 0,\n        index = new Array(n),\n        arcs = new Array(n),\n        a0 = +startAngle.apply(this, arguments),\n        da = Math.min(tau$4, Math.max(-tau$4, endAngle.apply(this, arguments) - a0)),\n        a1,\n        p = Math.min(Math.abs(da) / n, padAngle.apply(this, arguments)),\n        pa = p * (da < 0 ? -1 : 1),\n        v;\n\n    for (i = 0; i < n; ++i) {\n      if ((v = arcs[index[i] = i] = +value(data[i], i, data)) > 0) {\n        sum += v;\n      }\n    }\n\n    // Optionally sort the arcs by previously-computed values or by data.\n    if (sortValues != null) index.sort(function(i, j) { return sortValues(arcs[i], arcs[j]); });\n    else if (sort != null) index.sort(function(i, j) { return sort(data[i], data[j]); });\n\n    // Compute the arcs! They are stored in the original data's order.\n    for (i = 0, k = sum ? (da - n * pa) / sum : 0; i < n; ++i, a0 = a1) {\n      j = index[i], v = arcs[j], a1 = a0 + (v > 0 ? v * k : 0) + pa, arcs[j] = {\n        data: data[j],\n        index: i,\n        value: v,\n        startAngle: a0,\n        endAngle: a1,\n        padAngle: p\n      };\n    }\n\n    return arcs;\n  }\n\n  pie.value = function(_) {\n    return arguments.length ? (value = typeof _ === \"function\" ? _ : constant$10(+_), pie) : value;\n  };\n\n  pie.sortValues = function(_) {\n    return arguments.length ? (sortValues = _, sort = null, pie) : sortValues;\n  };\n\n  pie.sort = function(_) {\n    return arguments.length ? (sort = _, sortValues = null, pie) : sort;\n  };\n\n  pie.startAngle = function(_) {\n    return arguments.length ? (startAngle = typeof _ === \"function\" ? _ : constant$10(+_), pie) : startAngle;\n  };\n\n  pie.endAngle = function(_) {\n    return arguments.length ? (endAngle = typeof _ === \"function\" ? _ : constant$10(+_), pie) : endAngle;\n  };\n\n  pie.padAngle = function(_) {\n    return arguments.length ? (padAngle = typeof _ === \"function\" ? _ : constant$10(+_), pie) : padAngle;\n  };\n\n  return pie;\n};\n\nvar curveRadialLinear = curveRadial(curveLinear);\n\nfunction Radial(curve) {\n  this._curve = curve;\n}\n\nRadial.prototype = {\n  areaStart: function() {\n    this._curve.areaStart();\n  },\n  areaEnd: function() {\n    this._curve.areaEnd();\n  },\n  lineStart: function() {\n    this._curve.lineStart();\n  },\n  lineEnd: function() {\n    this._curve.lineEnd();\n  },\n  point: function(a, r) {\n    this._curve.point(r * Math.sin(a), r * -Math.cos(a));\n  }\n};\n\nfunction curveRadial(curve) {\n\n  function radial(context) {\n    return new Radial(curve(context));\n  }\n\n  radial._curve = curve;\n\n  return radial;\n}\n\nfunction radialLine(l) {\n  var c = l.curve;\n\n  l.angle = l.x, delete l.x;\n  l.radius = l.y, delete l.y;\n\n  l.curve = function(_) {\n    return arguments.length ? c(curveRadial(_)) : c()._curve;\n  };\n\n  return l;\n}\n\nvar radialLine$1 = function() {\n  return radialLine(line().curve(curveRadialLinear));\n};\n\nvar radialArea = function() {\n  var a = area$2().curve(curveRadialLinear),\n      c = a.curve,\n      x0 = a.lineX0,\n      x1 = a.lineX1,\n      y0 = a.lineY0,\n      y1 = a.lineY1;\n\n  a.angle = a.x, delete a.x;\n  a.startAngle = a.x0, delete a.x0;\n  a.endAngle = a.x1, delete a.x1;\n  a.radius = a.y, delete a.y;\n  a.innerRadius = a.y0, delete a.y0;\n  a.outerRadius = a.y1, delete a.y1;\n  a.lineStartAngle = function() { return radialLine(x0()); }, delete a.lineX0;\n  a.lineEndAngle = function() { return radialLine(x1()); }, delete a.lineX1;\n  a.lineInnerRadius = function() { return radialLine(y0()); }, delete a.lineY0;\n  a.lineOuterRadius = function() { return radialLine(y1()); }, delete a.lineY1;\n\n  a.curve = function(_) {\n    return arguments.length ? c(curveRadial(_)) : c()._curve;\n  };\n\n  return a;\n};\n\nvar slice$5 = Array.prototype.slice;\n\nvar radialPoint = function(x, y) {\n  return [(y = +y) * Math.cos(x -= Math.PI / 2), y * Math.sin(x)];\n};\n\nfunction linkSource(d) {\n  return d.source;\n}\n\nfunction linkTarget(d) {\n  return d.target;\n}\n\nfunction link$2(curve) {\n  var source = linkSource,\n      target = linkTarget,\n      x$$1 = x$3,\n      y$$1 = y$3,\n      context = null;\n\n  function link() {\n    var buffer, argv = slice$5.call(arguments), s = source.apply(this, argv), t = target.apply(this, argv);\n    if (!context) context = buffer = path();\n    curve(context, +x$$1.apply(this, (argv[0] = s, argv)), +y$$1.apply(this, argv), +x$$1.apply(this, (argv[0] = t, argv)), +y$$1.apply(this, argv));\n    if (buffer) return context = null, buffer + \"\" || null;\n  }\n\n  link.source = function(_) {\n    return arguments.length ? (source = _, link) : source;\n  };\n\n  link.target = function(_) {\n    return arguments.length ? (target = _, link) : target;\n  };\n\n  link.x = function(_) {\n    return arguments.length ? (x$$1 = typeof _ === \"function\" ? _ : constant$10(+_), link) : x$$1;\n  };\n\n  link.y = function(_) {\n    return arguments.length ? (y$$1 = typeof _ === \"function\" ? _ : constant$10(+_), link) : y$$1;\n  };\n\n  link.context = function(_) {\n    return arguments.length ? ((context = _ == null ? null : _), link) : context;\n  };\n\n  return link;\n}\n\nfunction curveHorizontal(context, x0, y0, x1, y1) {\n  context.moveTo(x0, y0);\n  context.bezierCurveTo(x0 = (x0 + x1) / 2, y0, x0, y1, x1, y1);\n}\n\nfunction curveVertical(context, x0, y0, x1, y1) {\n  context.moveTo(x0, y0);\n  context.bezierCurveTo(x0, y0 = (y0 + y1) / 2, x1, y0, x1, y1);\n}\n\nfunction curveRadial$1(context, x0, y0, x1, y1) {\n  var p0 = radialPoint(x0, y0),\n      p1 = radialPoint(x0, y0 = (y0 + y1) / 2),\n      p2 = radialPoint(x1, y0),\n      p3 = radialPoint(x1, y1);\n  context.moveTo(p0[0], p0[1]);\n  context.bezierCurveTo(p1[0], p1[1], p2[0], p2[1], p3[0], p3[1]);\n}\n\nfunction linkHorizontal() {\n  return link$2(curveHorizontal);\n}\n\nfunction linkVertical() {\n  return link$2(curveVertical);\n}\n\nfunction linkRadial() {\n  var l = link$2(curveRadial$1);\n  l.angle = l.x, delete l.x;\n  l.radius = l.y, delete l.y;\n  return l;\n}\n\nvar circle$2 = {\n  draw: function(context, size) {\n    var r = Math.sqrt(size / pi$4);\n    context.moveTo(r, 0);\n    context.arc(0, 0, r, 0, tau$4);\n  }\n};\n\nvar cross$2 = {\n  draw: function(context, size) {\n    var r = Math.sqrt(size / 5) / 2;\n    context.moveTo(-3 * r, -r);\n    context.lineTo(-r, -r);\n    context.lineTo(-r, -3 * r);\n    context.lineTo(r, -3 * r);\n    context.lineTo(r, -r);\n    context.lineTo(3 * r, -r);\n    context.lineTo(3 * r, r);\n    context.lineTo(r, r);\n    context.lineTo(r, 3 * r);\n    context.lineTo(-r, 3 * r);\n    context.lineTo(-r, r);\n    context.lineTo(-3 * r, r);\n    context.closePath();\n  }\n};\n\nvar tan30 = Math.sqrt(1 / 3);\nvar tan30_2 = tan30 * 2;\n\nvar diamond = {\n  draw: function(context, size) {\n    var y = Math.sqrt(size / tan30_2),\n        x = y * tan30;\n    context.moveTo(0, -y);\n    context.lineTo(x, 0);\n    context.lineTo(0, y);\n    context.lineTo(-x, 0);\n    context.closePath();\n  }\n};\n\nvar ka = 0.89081309152928522810;\nvar kr = Math.sin(pi$4 / 10) / Math.sin(7 * pi$4 / 10);\nvar kx = Math.sin(tau$4 / 10) * kr;\nvar ky = -Math.cos(tau$4 / 10) * kr;\n\nvar star = {\n  draw: function(context, size) {\n    var r = Math.sqrt(size * ka),\n        x = kx * r,\n        y = ky * r;\n    context.moveTo(0, -r);\n    context.lineTo(x, y);\n    for (var i = 1; i < 5; ++i) {\n      var a = tau$4 * i / 5,\n          c = Math.cos(a),\n          s = Math.sin(a);\n      context.lineTo(s * r, -c * r);\n      context.lineTo(c * x - s * y, s * x + c * y);\n    }\n    context.closePath();\n  }\n};\n\nvar square = {\n  draw: function(context, size) {\n    var w = Math.sqrt(size),\n        x = -w / 2;\n    context.rect(x, x, w, w);\n  }\n};\n\nvar sqrt3 = Math.sqrt(3);\n\nvar triangle = {\n  draw: function(context, size) {\n    var y = -Math.sqrt(size / (sqrt3 * 3));\n    context.moveTo(0, y * 2);\n    context.lineTo(-sqrt3 * y, -y);\n    context.lineTo(sqrt3 * y, -y);\n    context.closePath();\n  }\n};\n\nvar c = -0.5;\nvar s = Math.sqrt(3) / 2;\nvar k = 1 / Math.sqrt(12);\nvar a = (k / 2 + 1) * 3;\n\nvar wye = {\n  draw: function(context, size) {\n    var r = Math.sqrt(size / a),\n        x0 = r / 2,\n        y0 = r * k,\n        x1 = x0,\n        y1 = r * k + r,\n        x2 = -x1,\n        y2 = y1;\n    context.moveTo(x0, y0);\n    context.lineTo(x1, y1);\n    context.lineTo(x2, y2);\n    context.lineTo(c * x0 - s * y0, s * x0 + c * y0);\n    context.lineTo(c * x1 - s * y1, s * x1 + c * y1);\n    context.lineTo(c * x2 - s * y2, s * x2 + c * y2);\n    context.lineTo(c * x0 + s * y0, c * y0 - s * x0);\n    context.lineTo(c * x1 + s * y1, c * y1 - s * x1);\n    context.lineTo(c * x2 + s * y2, c * y2 - s * x2);\n    context.closePath();\n  }\n};\n\nvar symbols = [\n  circle$2,\n  cross$2,\n  diamond,\n  square,\n  star,\n  triangle,\n  wye\n];\n\nvar symbol = function() {\n  var type = constant$10(circle$2),\n      size = constant$10(64),\n      context = null;\n\n  function symbol() {\n    var buffer;\n    if (!context) context = buffer = path();\n    type.apply(this, arguments).draw(context, +size.apply(this, arguments));\n    if (buffer) return context = null, buffer + \"\" || null;\n  }\n\n  symbol.type = function(_) {\n    return arguments.length ? (type = typeof _ === \"function\" ? _ : constant$10(_), symbol) : type;\n  };\n\n  symbol.size = function(_) {\n    return arguments.length ? (size = typeof _ === \"function\" ? _ : constant$10(+_), symbol) : size;\n  };\n\n  symbol.context = function(_) {\n    return arguments.length ? (context = _ == null ? null : _, symbol) : context;\n  };\n\n  return symbol;\n};\n\nvar noop$2 = function() {};\n\nfunction point$2(that, x, y) {\n  that._context.bezierCurveTo(\n    (2 * that._x0 + that._x1) / 3,\n    (2 * that._y0 + that._y1) / 3,\n    (that._x0 + 2 * that._x1) / 3,\n    (that._y0 + 2 * that._y1) / 3,\n    (that._x0 + 4 * that._x1 + x) / 6,\n    (that._y0 + 4 * that._y1 + y) / 6\n  );\n}\n\nfunction Basis(context) {\n  this._context = context;\n}\n\nBasis.prototype = {\n  areaStart: function() {\n    this._line = 0;\n  },\n  areaEnd: function() {\n    this._line = NaN;\n  },\n  lineStart: function() {\n    this._x0 = this._x1 =\n    this._y0 = this._y1 = NaN;\n    this._point = 0;\n  },\n  lineEnd: function() {\n    switch (this._point) {\n      case 3: point$2(this, this._x1, this._y1); // proceed\n      case 2: this._context.lineTo(this._x1, this._y1); break;\n    }\n    if (this._line || (this._line !== 0 && this._point === 1)) this._context.closePath();\n    this._line = 1 - this._line;\n  },\n  point: function(x, y) {\n    x = +x, y = +y;\n    switch (this._point) {\n      case 0: this._point = 1; this._line ? this._context.lineTo(x, y) : this._context.moveTo(x, y); break;\n      case 1: this._point = 2; break;\n      case 2: this._point = 3; this._context.lineTo((5 * this._x0 + this._x1) / 6, (5 * this._y0 + this._y1) / 6); // proceed\n      default: point$2(this, x, y); break;\n    }\n    this._x0 = this._x1, this._x1 = x;\n    this._y0 = this._y1, this._y1 = y;\n  }\n};\n\nvar basis$2 = function(context) {\n  return new Basis(context);\n};\n\nfunction BasisClosed(context) {\n  this._context = context;\n}\n\nBasisClosed.prototype = {\n  areaStart: noop$2,\n  areaEnd: noop$2,\n  lineStart: function() {\n    this._x0 = this._x1 = this._x2 = this._x3 = this._x4 =\n    this._y0 = this._y1 = this._y2 = this._y3 = this._y4 = NaN;\n    this._point = 0;\n  },\n  lineEnd: function() {\n    switch (this._point) {\n      case 1: {\n        this._context.moveTo(this._x2, this._y2);\n        this._context.closePath();\n        break;\n      }\n      case 2: {\n        this._context.moveTo((this._x2 + 2 * this._x3) / 3, (this._y2 + 2 * this._y3) / 3);\n        this._context.lineTo((this._x3 + 2 * this._x2) / 3, (this._y3 + 2 * this._y2) / 3);\n        this._context.closePath();\n        break;\n      }\n      case 3: {\n        this.point(this._x2, this._y2);\n        this.point(this._x3, this._y3);\n        this.point(this._x4, this._y4);\n        break;\n      }\n    }\n  },\n  point: function(x, y) {\n    x = +x, y = +y;\n    switch (this._point) {\n      case 0: this._point = 1; this._x2 = x, this._y2 = y; break;\n      case 1: this._point = 2; this._x3 = x, this._y3 = y; break;\n      case 2: this._point = 3; this._x4 = x, this._y4 = y; this._context.moveTo((this._x0 + 4 * this._x1 + x) / 6, (this._y0 + 4 * this._y1 + y) / 6); break;\n      default: point$2(this, x, y); break;\n    }\n    this._x0 = this._x1, this._x1 = x;\n    this._y0 = this._y1, this._y1 = y;\n  }\n};\n\nvar basisClosed$1 = function(context) {\n  return new BasisClosed(context);\n};\n\nfunction BasisOpen(context) {\n  this._context = context;\n}\n\nBasisOpen.prototype = {\n  areaStart: function() {\n    this._line = 0;\n  },\n  areaEnd: function() {\n    this._line = NaN;\n  },\n  lineStart: function() {\n    this._x0 = this._x1 =\n    this._y0 = this._y1 = NaN;\n    this._point = 0;\n  },\n  lineEnd: function() {\n    if (this._line || (this._line !== 0 && this._point === 3)) this._context.closePath();\n    this._line = 1 - this._line;\n  },\n  point: function(x, y) {\n    x = +x, y = +y;\n    switch (this._point) {\n      case 0: this._point = 1; break;\n      case 1: this._point = 2; break;\n      case 2: this._point = 3; var x0 = (this._x0 + 4 * this._x1 + x) / 6, y0 = (this._y0 + 4 * this._y1 + y) / 6; this._line ? this._context.lineTo(x0, y0) : this._context.moveTo(x0, y0); break;\n      case 3: this._point = 4; // proceed\n      default: point$2(this, x, y); break;\n    }\n    this._x0 = this._x1, this._x1 = x;\n    this._y0 = this._y1, this._y1 = y;\n  }\n};\n\nvar basisOpen = function(context) {\n  return new BasisOpen(context);\n};\n\nfunction Bundle(context, beta) {\n  this._basis = new Basis(context);\n  this._beta = beta;\n}\n\nBundle.prototype = {\n  lineStart: function() {\n    this._x = [];\n    this._y = [];\n    this._basis.lineStart();\n  },\n  lineEnd: function() {\n    var x = this._x,\n        y = this._y,\n        j = x.length - 1;\n\n    if (j > 0) {\n      var x0 = x[0],\n          y0 = y[0],\n          dx = x[j] - x0,\n          dy = y[j] - y0,\n          i = -1,\n          t;\n\n      while (++i <= j) {\n        t = i / j;\n        this._basis.point(\n          this._beta * x[i] + (1 - this._beta) * (x0 + t * dx),\n          this._beta * y[i] + (1 - this._beta) * (y0 + t * dy)\n        );\n      }\n    }\n\n    this._x = this._y = null;\n    this._basis.lineEnd();\n  },\n  point: function(x, y) {\n    this._x.push(+x);\n    this._y.push(+y);\n  }\n};\n\nvar bundle = ((function custom(beta) {\n\n  function bundle(context) {\n    return beta === 1 ? new Basis(context) : new Bundle(context, beta);\n  }\n\n  bundle.beta = function(beta) {\n    return custom(+beta);\n  };\n\n  return bundle;\n}))(0.85);\n\nfunction point$3(that, x, y) {\n  that._context.bezierCurveTo(\n    that._x1 + that._k * (that._x2 - that._x0),\n    that._y1 + that._k * (that._y2 - that._y0),\n    that._x2 + that._k * (that._x1 - x),\n    that._y2 + that._k * (that._y1 - y),\n    that._x2,\n    that._y2\n  );\n}\n\nfunction Cardinal(context, tension) {\n  this._context = context;\n  this._k = (1 - tension) / 6;\n}\n\nCardinal.prototype = {\n  areaStart: function() {\n    this._line = 0;\n  },\n  areaEnd: function() {\n    this._line = NaN;\n  },\n  lineStart: function() {\n    this._x0 = this._x1 = this._x2 =\n    this._y0 = this._y1 = this._y2 = NaN;\n    this._point = 0;\n  },\n  lineEnd: function() {\n    switch (this._point) {\n      case 2: this._context.lineTo(this._x2, this._y2); break;\n      case 3: point$3(this, this._x1, this._y1); break;\n    }\n    if (this._line || (this._line !== 0 && this._point === 1)) this._context.closePath();\n    this._line = 1 - this._line;\n  },\n  point: function(x, y) {\n    x = +x, y = +y;\n    switch (this._point) {\n      case 0: this._point = 1; this._line ? this._context.lineTo(x, y) : this._context.moveTo(x, y); break;\n      case 1: this._point = 2; this._x1 = x, this._y1 = y; break;\n      case 2: this._point = 3; // proceed\n      default: point$3(this, x, y); break;\n    }\n    this._x0 = this._x1, this._x1 = this._x2, this._x2 = x;\n    this._y0 = this._y1, this._y1 = this._y2, this._y2 = y;\n  }\n};\n\nvar cardinal = ((function custom(tension) {\n\n  function cardinal(context) {\n    return new Cardinal(context, tension);\n  }\n\n  cardinal.tension = function(tension) {\n    return custom(+tension);\n  };\n\n  return cardinal;\n}))(0);\n\nfunction CardinalClosed(context, tension) {\n  this._context = context;\n  this._k = (1 - tension) / 6;\n}\n\nCardinalClosed.prototype = {\n  areaStart: noop$2,\n  areaEnd: noop$2,\n  lineStart: function() {\n    this._x0 = this._x1 = this._x2 = this._x3 = this._x4 = this._x5 =\n    this._y0 = this._y1 = this._y2 = this._y3 = this._y4 = this._y5 = NaN;\n    this._point = 0;\n  },\n  lineEnd: function() {\n    switch (this._point) {\n      case 1: {\n        this._context.moveTo(this._x3, this._y3);\n        this._context.closePath();\n        break;\n      }\n      case 2: {\n        this._context.lineTo(this._x3, this._y3);\n        this._context.closePath();\n        break;\n      }\n      case 3: {\n        this.point(this._x3, this._y3);\n        this.point(this._x4, this._y4);\n        this.point(this._x5, this._y5);\n        break;\n      }\n    }\n  },\n  point: function(x, y) {\n    x = +x, y = +y;\n    switch (this._point) {\n      case 0: this._point = 1; this._x3 = x, this._y3 = y; break;\n      case 1: this._point = 2; this._context.moveTo(this._x4 = x, this._y4 = y); break;\n      case 2: this._point = 3; this._x5 = x, this._y5 = y; break;\n      default: point$3(this, x, y); break;\n    }\n    this._x0 = this._x1, this._x1 = this._x2, this._x2 = x;\n    this._y0 = this._y1, this._y1 = this._y2, this._y2 = y;\n  }\n};\n\nvar cardinalClosed = ((function custom(tension) {\n\n  function cardinal(context) {\n    return new CardinalClosed(context, tension);\n  }\n\n  cardinal.tension = function(tension) {\n    return custom(+tension);\n  };\n\n  return cardinal;\n}))(0);\n\nfunction CardinalOpen(context, tension) {\n  this._context = context;\n  this._k = (1 - tension) / 6;\n}\n\nCardinalOpen.prototype = {\n  areaStart: function() {\n    this._line = 0;\n  },\n  areaEnd: function() {\n    this._line = NaN;\n  },\n  lineStart: function() {\n    this._x0 = this._x1 = this._x2 =\n    this._y0 = this._y1 = this._y2 = NaN;\n    this._point = 0;\n  },\n  lineEnd: function() {\n    if (this._line || (this._line !== 0 && this._point === 3)) this._context.closePath();\n    this._line = 1 - this._line;\n  },\n  point: function(x, y) {\n    x = +x, y = +y;\n    switch (this._point) {\n      case 0: this._point = 1; break;\n      case 1: this._point = 2; break;\n      case 2: this._point = 3; this._line ? this._context.lineTo(this._x2, this._y2) : this._context.moveTo(this._x2, this._y2); break;\n      case 3: this._point = 4; // proceed\n      default: point$3(this, x, y); break;\n    }\n    this._x0 = this._x1, this._x1 = this._x2, this._x2 = x;\n    this._y0 = this._y1, this._y1 = this._y2, this._y2 = y;\n  }\n};\n\nvar cardinalOpen = ((function custom(tension) {\n\n  function cardinal(context) {\n    return new CardinalOpen(context, tension);\n  }\n\n  cardinal.tension = function(tension) {\n    return custom(+tension);\n  };\n\n  return cardinal;\n}))(0);\n\nfunction point$4(that, x, y) {\n  var x1 = that._x1,\n      y1 = that._y1,\n      x2 = that._x2,\n      y2 = that._y2;\n\n  if (that._l01_a > epsilon$3) {\n    var a = 2 * that._l01_2a + 3 * that._l01_a * that._l12_a + that._l12_2a,\n        n = 3 * that._l01_a * (that._l01_a + that._l12_a);\n    x1 = (x1 * a - that._x0 * that._l12_2a + that._x2 * that._l01_2a) / n;\n    y1 = (y1 * a - that._y0 * that._l12_2a + that._y2 * that._l01_2a) / n;\n  }\n\n  if (that._l23_a > epsilon$3) {\n    var b = 2 * that._l23_2a + 3 * that._l23_a * that._l12_a + that._l12_2a,\n        m = 3 * that._l23_a * (that._l23_a + that._l12_a);\n    x2 = (x2 * b + that._x1 * that._l23_2a - x * that._l12_2a) / m;\n    y2 = (y2 * b + that._y1 * that._l23_2a - y * that._l12_2a) / m;\n  }\n\n  that._context.bezierCurveTo(x1, y1, x2, y2, that._x2, that._y2);\n}\n\nfunction CatmullRom(context, alpha) {\n  this._context = context;\n  this._alpha = alpha;\n}\n\nCatmullRom.prototype = {\n  areaStart: function() {\n    this._line = 0;\n  },\n  areaEnd: function() {\n    this._line = NaN;\n  },\n  lineStart: function() {\n    this._x0 = this._x1 = this._x2 =\n    this._y0 = this._y1 = this._y2 = NaN;\n    this._l01_a = this._l12_a = this._l23_a =\n    this._l01_2a = this._l12_2a = this._l23_2a =\n    this._point = 0;\n  },\n  lineEnd: function() {\n    switch (this._point) {\n      case 2: this._context.lineTo(this._x2, this._y2); break;\n      case 3: this.point(this._x2, this._y2); break;\n    }\n    if (this._line || (this._line !== 0 && this._point === 1)) this._context.closePath();\n    this._line = 1 - this._line;\n  },\n  point: function(x, y) {\n    x = +x, y = +y;\n\n    if (this._point) {\n      var x23 = this._x2 - x,\n          y23 = this._y2 - y;\n      this._l23_a = Math.sqrt(this._l23_2a = Math.pow(x23 * x23 + y23 * y23, this._alpha));\n    }\n\n    switch (this._point) {\n      case 0: this._point = 1; this._line ? this._context.lineTo(x, y) : this._context.moveTo(x, y); break;\n      case 1: this._point = 2; break;\n      case 2: this._point = 3; // proceed\n      default: point$4(this, x, y); break;\n    }\n\n    this._l01_a = this._l12_a, this._l12_a = this._l23_a;\n    this._l01_2a = this._l12_2a, this._l12_2a = this._l23_2a;\n    this._x0 = this._x1, this._x1 = this._x2, this._x2 = x;\n    this._y0 = this._y1, this._y1 = this._y2, this._y2 = y;\n  }\n};\n\nvar catmullRom = ((function custom(alpha) {\n\n  function catmullRom(context) {\n    return alpha ? new CatmullRom(context, alpha) : new Cardinal(context, 0);\n  }\n\n  catmullRom.alpha = function(alpha) {\n    return custom(+alpha);\n  };\n\n  return catmullRom;\n}))(0.5);\n\nfunction CatmullRomClosed(context, alpha) {\n  this._context = context;\n  this._alpha = alpha;\n}\n\nCatmullRomClosed.prototype = {\n  areaStart: noop$2,\n  areaEnd: noop$2,\n  lineStart: function() {\n    this._x0 = this._x1 = this._x2 = this._x3 = this._x4 = this._x5 =\n    this._y0 = this._y1 = this._y2 = this._y3 = this._y4 = this._y5 = NaN;\n    this._l01_a = this._l12_a = this._l23_a =\n    this._l01_2a = this._l12_2a = this._l23_2a =\n    this._point = 0;\n  },\n  lineEnd: function() {\n    switch (this._point) {\n      case 1: {\n        this._context.moveTo(this._x3, this._y3);\n        this._context.closePath();\n        break;\n      }\n      case 2: {\n        this._context.lineTo(this._x3, this._y3);\n        this._context.closePath();\n        break;\n      }\n      case 3: {\n        this.point(this._x3, this._y3);\n        this.point(this._x4, this._y4);\n        this.point(this._x5, this._y5);\n        break;\n      }\n    }\n  },\n  point: function(x, y) {\n    x = +x, y = +y;\n\n    if (this._point) {\n      var x23 = this._x2 - x,\n          y23 = this._y2 - y;\n      this._l23_a = Math.sqrt(this._l23_2a = Math.pow(x23 * x23 + y23 * y23, this._alpha));\n    }\n\n    switch (this._point) {\n      case 0: this._point = 1; this._x3 = x, this._y3 = y; break;\n      case 1: this._point = 2; this._context.moveTo(this._x4 = x, this._y4 = y); break;\n      case 2: this._point = 3; this._x5 = x, this._y5 = y; break;\n      default: point$4(this, x, y); break;\n    }\n\n    this._l01_a = this._l12_a, this._l12_a = this._l23_a;\n    this._l01_2a = this._l12_2a, this._l12_2a = this._l23_2a;\n    this._x0 = this._x1, this._x1 = this._x2, this._x2 = x;\n    this._y0 = this._y1, this._y1 = this._y2, this._y2 = y;\n  }\n};\n\nvar catmullRomClosed = ((function custom(alpha) {\n\n  function catmullRom(context) {\n    return alpha ? new CatmullRomClosed(context, alpha) : new CardinalClosed(context, 0);\n  }\n\n  catmullRom.alpha = function(alpha) {\n    return custom(+alpha);\n  };\n\n  return catmullRom;\n}))(0.5);\n\nfunction CatmullRomOpen(context, alpha) {\n  this._context = context;\n  this._alpha = alpha;\n}\n\nCatmullRomOpen.prototype = {\n  areaStart: function() {\n    this._line = 0;\n  },\n  areaEnd: function() {\n    this._line = NaN;\n  },\n  lineStart: function() {\n    this._x0 = this._x1 = this._x2 =\n    this._y0 = this._y1 = this._y2 = NaN;\n    this._l01_a = this._l12_a = this._l23_a =\n    this._l01_2a = this._l12_2a = this._l23_2a =\n    this._point = 0;\n  },\n  lineEnd: function() {\n    if (this._line || (this._line !== 0 && this._point === 3)) this._context.closePath();\n    this._line = 1 - this._line;\n  },\n  point: function(x, y) {\n    x = +x, y = +y;\n\n    if (this._point) {\n      var x23 = this._x2 - x,\n          y23 = this._y2 - y;\n      this._l23_a = Math.sqrt(this._l23_2a = Math.pow(x23 * x23 + y23 * y23, this._alpha));\n    }\n\n    switch (this._point) {\n      case 0: this._point = 1; break;\n      case 1: this._point = 2; break;\n      case 2: this._point = 3; this._line ? this._context.lineTo(this._x2, this._y2) : this._context.moveTo(this._x2, this._y2); break;\n      case 3: this._point = 4; // proceed\n      default: point$4(this, x, y); break;\n    }\n\n    this._l01_a = this._l12_a, this._l12_a = this._l23_a;\n    this._l01_2a = this._l12_2a, this._l12_2a = this._l23_2a;\n    this._x0 = this._x1, this._x1 = this._x2, this._x2 = x;\n    this._y0 = this._y1, this._y1 = this._y2, this._y2 = y;\n  }\n};\n\nvar catmullRomOpen = ((function custom(alpha) {\n\n  function catmullRom(context) {\n    return alpha ? new CatmullRomOpen(context, alpha) : new CardinalOpen(context, 0);\n  }\n\n  catmullRom.alpha = function(alpha) {\n    return custom(+alpha);\n  };\n\n  return catmullRom;\n}))(0.5);\n\nfunction LinearClosed(context) {\n  this._context = context;\n}\n\nLinearClosed.prototype = {\n  areaStart: noop$2,\n  areaEnd: noop$2,\n  lineStart: function() {\n    this._point = 0;\n  },\n  lineEnd: function() {\n    if (this._point) this._context.closePath();\n  },\n  point: function(x, y) {\n    x = +x, y = +y;\n    if (this._point) this._context.lineTo(x, y);\n    else this._point = 1, this._context.moveTo(x, y);\n  }\n};\n\nvar linearClosed = function(context) {\n  return new LinearClosed(context);\n};\n\nfunction sign$1(x) {\n  return x < 0 ? -1 : 1;\n}\n\n// Calculate the slopes of the tangents (Hermite-type interpolation) based on\n// the following paper: Steffen, M. 1990. A Simple Method for Monotonic\n// Interpolation in One Dimension. Astronomy and Astrophysics, Vol. 239, NO.\n// NOV(II), P. 443, 1990.\nfunction slope3(that, x2, y2) {\n  var h0 = that._x1 - that._x0,\n      h1 = x2 - that._x1,\n      s0 = (that._y1 - that._y0) / (h0 || h1 < 0 && -0),\n      s1 = (y2 - that._y1) / (h1 || h0 < 0 && -0),\n      p = (s0 * h1 + s1 * h0) / (h0 + h1);\n  return (sign$1(s0) + sign$1(s1)) * Math.min(Math.abs(s0), Math.abs(s1), 0.5 * Math.abs(p)) || 0;\n}\n\n// Calculate a one-sided slope.\nfunction slope2(that, t) {\n  var h = that._x1 - that._x0;\n  return h ? (3 * (that._y1 - that._y0) / h - t) / 2 : t;\n}\n\n// According to https://en.wikipedia.org/wiki/Cubic_Hermite_spline#Representations\n// \"you can express cubic Hermite interpolation in terms of cubic Bézier curves\n// with respect to the four values p0, p0 + m0 / 3, p1 - m1 / 3, p1\".\nfunction point$5(that, t0, t1) {\n  var x0 = that._x0,\n      y0 = that._y0,\n      x1 = that._x1,\n      y1 = that._y1,\n      dx = (x1 - x0) / 3;\n  that._context.bezierCurveTo(x0 + dx, y0 + dx * t0, x1 - dx, y1 - dx * t1, x1, y1);\n}\n\nfunction MonotoneX(context) {\n  this._context = context;\n}\n\nMonotoneX.prototype = {\n  areaStart: function() {\n    this._line = 0;\n  },\n  areaEnd: function() {\n    this._line = NaN;\n  },\n  lineStart: function() {\n    this._x0 = this._x1 =\n    this._y0 = this._y1 =\n    this._t0 = NaN;\n    this._point = 0;\n  },\n  lineEnd: function() {\n    switch (this._point) {\n      case 2: this._context.lineTo(this._x1, this._y1); break;\n      case 3: point$5(this, this._t0, slope2(this, this._t0)); break;\n    }\n    if (this._line || (this._line !== 0 && this._point === 1)) this._context.closePath();\n    this._line = 1 - this._line;\n  },\n  point: function(x, y) {\n    var t1 = NaN;\n\n    x = +x, y = +y;\n    if (x === this._x1 && y === this._y1) return; // Ignore coincident points.\n    switch (this._point) {\n      case 0: this._point = 1; this._line ? this._context.lineTo(x, y) : this._context.moveTo(x, y); break;\n      case 1: this._point = 2; break;\n      case 2: this._point = 3; point$5(this, slope2(this, t1 = slope3(this, x, y)), t1); break;\n      default: point$5(this, this._t0, t1 = slope3(this, x, y)); break;\n    }\n\n    this._x0 = this._x1, this._x1 = x;\n    this._y0 = this._y1, this._y1 = y;\n    this._t0 = t1;\n  }\n};\n\nfunction MonotoneY(context) {\n  this._context = new ReflectContext(context);\n}\n\n(MonotoneY.prototype = Object.create(MonotoneX.prototype)).point = function(x, y) {\n  MonotoneX.prototype.point.call(this, y, x);\n};\n\nfunction ReflectContext(context) {\n  this._context = context;\n}\n\nReflectContext.prototype = {\n  moveTo: function(x, y) { this._context.moveTo(y, x); },\n  closePath: function() { this._context.closePath(); },\n  lineTo: function(x, y) { this._context.lineTo(y, x); },\n  bezierCurveTo: function(x1, y1, x2, y2, x, y) { this._context.bezierCurveTo(y1, x1, y2, x2, y, x); }\n};\n\nfunction monotoneX(context) {\n  return new MonotoneX(context);\n}\n\nfunction monotoneY(context) {\n  return new MonotoneY(context);\n}\n\nfunction Natural(context) {\n  this._context = context;\n}\n\nNatural.prototype = {\n  areaStart: function() {\n    this._line = 0;\n  },\n  areaEnd: function() {\n    this._line = NaN;\n  },\n  lineStart: function() {\n    this._x = [];\n    this._y = [];\n  },\n  lineEnd: function() {\n    var x = this._x,\n        y = this._y,\n        n = x.length;\n\n    if (n) {\n      this._line ? this._context.lineTo(x[0], y[0]) : this._context.moveTo(x[0], y[0]);\n      if (n === 2) {\n        this._context.lineTo(x[1], y[1]);\n      } else {\n        var px = controlPoints(x),\n            py = controlPoints(y);\n        for (var i0 = 0, i1 = 1; i1 < n; ++i0, ++i1) {\n          this._context.bezierCurveTo(px[0][i0], py[0][i0], px[1][i0], py[1][i0], x[i1], y[i1]);\n        }\n      }\n    }\n\n    if (this._line || (this._line !== 0 && n === 1)) this._context.closePath();\n    this._line = 1 - this._line;\n    this._x = this._y = null;\n  },\n  point: function(x, y) {\n    this._x.push(+x);\n    this._y.push(+y);\n  }\n};\n\n// See https://www.particleincell.com/2012/bezier-splines/ for derivation.\nfunction controlPoints(x) {\n  var i,\n      n = x.length - 1,\n      m,\n      a = new Array(n),\n      b = new Array(n),\n      r = new Array(n);\n  a[0] = 0, b[0] = 2, r[0] = x[0] + 2 * x[1];\n  for (i = 1; i < n - 1; ++i) a[i] = 1, b[i] = 4, r[i] = 4 * x[i] + 2 * x[i + 1];\n  a[n - 1] = 2, b[n - 1] = 7, r[n - 1] = 8 * x[n - 1] + x[n];\n  for (i = 1; i < n; ++i) m = a[i] / b[i - 1], b[i] -= m, r[i] -= m * r[i - 1];\n  a[n - 1] = r[n - 1] / b[n - 1];\n  for (i = n - 2; i >= 0; --i) a[i] = (r[i] - a[i + 1]) / b[i];\n  b[n - 1] = (x[n] + a[n - 1]) / 2;\n  for (i = 0; i < n - 1; ++i) b[i] = 2 * x[i + 1] - a[i + 1];\n  return [a, b];\n}\n\nvar natural = function(context) {\n  return new Natural(context);\n};\n\nfunction Step(context, t) {\n  this._context = context;\n  this._t = t;\n}\n\nStep.prototype = {\n  areaStart: function() {\n    this._line = 0;\n  },\n  areaEnd: function() {\n    this._line = NaN;\n  },\n  lineStart: function() {\n    this._x = this._y = NaN;\n    this._point = 0;\n  },\n  lineEnd: function() {\n    if (0 < this._t && this._t < 1 && this._point === 2) this._context.lineTo(this._x, this._y);\n    if (this._line || (this._line !== 0 && this._point === 1)) this._context.closePath();\n    if (this._line >= 0) this._t = 1 - this._t, this._line = 1 - this._line;\n  },\n  point: function(x, y) {\n    x = +x, y = +y;\n    switch (this._point) {\n      case 0: this._point = 1; this._line ? this._context.lineTo(x, y) : this._context.moveTo(x, y); break;\n      case 1: this._point = 2; // proceed\n      default: {\n        if (this._t <= 0) {\n          this._context.lineTo(this._x, y);\n          this._context.lineTo(x, y);\n        } else {\n          var x1 = this._x * (1 - this._t) + x * this._t;\n          this._context.lineTo(x1, this._y);\n          this._context.lineTo(x1, y);\n        }\n        break;\n      }\n    }\n    this._x = x, this._y = y;\n  }\n};\n\nvar step = function(context) {\n  return new Step(context, 0.5);\n};\n\nfunction stepBefore(context) {\n  return new Step(context, 0);\n}\n\nfunction stepAfter(context) {\n  return new Step(context, 1);\n}\n\nvar none$1 = function(series, order) {\n  if (!((n = series.length) > 1)) return;\n  for (var i = 1, j, s0, s1 = series[order[0]], n, m = s1.length; i < n; ++i) {\n    s0 = s1, s1 = series[order[i]];\n    for (j = 0; j < m; ++j) {\n      s1[j][1] += s1[j][0] = isNaN(s0[j][1]) ? s0[j][0] : s0[j][1];\n    }\n  }\n};\n\nvar none$2 = function(series) {\n  var n = series.length, o = new Array(n);\n  while (--n >= 0) o[n] = n;\n  return o;\n};\n\nfunction stackValue(d, key) {\n  return d[key];\n}\n\nvar stack = function() {\n  var keys = constant$10([]),\n      order = none$2,\n      offset = none$1,\n      value = stackValue;\n\n  function stack(data) {\n    var kz = keys.apply(this, arguments),\n        i,\n        m = data.length,\n        n = kz.length,\n        sz = new Array(n),\n        oz;\n\n    for (i = 0; i < n; ++i) {\n      for (var ki = kz[i], si = sz[i] = new Array(m), j = 0, sij; j < m; ++j) {\n        si[j] = sij = [0, +value(data[j], ki, j, data)];\n        sij.data = data[j];\n      }\n      si.key = ki;\n    }\n\n    for (i = 0, oz = order(sz); i < n; ++i) {\n      sz[oz[i]].index = i;\n    }\n\n    offset(sz, oz);\n    return sz;\n  }\n\n  stack.keys = function(_) {\n    return arguments.length ? (keys = typeof _ === \"function\" ? _ : constant$10(slice$5.call(_)), stack) : keys;\n  };\n\n  stack.value = function(_) {\n    return arguments.length ? (value = typeof _ === \"function\" ? _ : constant$10(+_), stack) : value;\n  };\n\n  stack.order = function(_) {\n    return arguments.length ? (order = _ == null ? none$2 : typeof _ === \"function\" ? _ : constant$10(slice$5.call(_)), stack) : order;\n  };\n\n  stack.offset = function(_) {\n    return arguments.length ? (offset = _ == null ? none$1 : _, stack) : offset;\n  };\n\n  return stack;\n};\n\nvar expand = function(series, order) {\n  if (!((n = series.length) > 0)) return;\n  for (var i, n, j = 0, m = series[0].length, y; j < m; ++j) {\n    for (y = i = 0; i < n; ++i) y += series[i][j][1] || 0;\n    if (y) for (i = 0; i < n; ++i) series[i][j][1] /= y;\n  }\n  none$1(series, order);\n};\n\nvar diverging = function(series, order) {\n  if (!((n = series.length) > 1)) return;\n  for (var i, j = 0, d, dy, yp, yn, n, m = series[order[0]].length; j < m; ++j) {\n    for (yp = yn = 0, i = 0; i < n; ++i) {\n      if ((dy = (d = series[order[i]][j])[1] - d[0]) >= 0) {\n        d[0] = yp, d[1] = yp += dy;\n      } else if (dy < 0) {\n        d[1] = yn, d[0] = yn += dy;\n      } else {\n        d[0] = yp;\n      }\n    }\n  }\n};\n\nvar silhouette = function(series, order) {\n  if (!((n = series.length) > 0)) return;\n  for (var j = 0, s0 = series[order[0]], n, m = s0.length; j < m; ++j) {\n    for (var i = 0, y = 0; i < n; ++i) y += series[i][j][1] || 0;\n    s0[j][1] += s0[j][0] = -y / 2;\n  }\n  none$1(series, order);\n};\n\nvar wiggle = function(series, order) {\n  if (!((n = series.length) > 0) || !((m = (s0 = series[order[0]]).length) > 0)) return;\n  for (var y = 0, j = 1, s0, m, n; j < m; ++j) {\n    for (var i = 0, s1 = 0, s2 = 0; i < n; ++i) {\n      var si = series[order[i]],\n          sij0 = si[j][1] || 0,\n          sij1 = si[j - 1][1] || 0,\n          s3 = (sij0 - sij1) / 2;\n      for (var k = 0; k < i; ++k) {\n        var sk = series[order[k]],\n            skj0 = sk[j][1] || 0,\n            skj1 = sk[j - 1][1] || 0;\n        s3 += skj0 - skj1;\n      }\n      s1 += sij0, s2 += s3 * sij0;\n    }\n    s0[j - 1][1] += s0[j - 1][0] = y;\n    if (s1) y -= s2 / s1;\n  }\n  s0[j - 1][1] += s0[j - 1][0] = y;\n  none$1(series, order);\n};\n\nvar ascending$2 = function(series) {\n  var sums = series.map(sum$2);\n  return none$2(series).sort(function(a, b) { return sums[a] - sums[b]; });\n};\n\nfunction sum$2(series) {\n  var s = 0, i = -1, n = series.length, v;\n  while (++i < n) if (v = +series[i][1]) s += v;\n  return s;\n}\n\nvar descending$2 = function(series) {\n  return ascending$2(series).reverse();\n};\n\nvar insideOut = function(series) {\n  var n = series.length,\n      i,\n      j,\n      sums = series.map(sum$2),\n      order = none$2(series).sort(function(a, b) { return sums[b] - sums[a]; }),\n      top = 0,\n      bottom = 0,\n      tops = [],\n      bottoms = [];\n\n  for (i = 0; i < n; ++i) {\n    j = order[i];\n    if (top < bottom) {\n      top += sums[j];\n      tops.push(j);\n    } else {\n      bottom += sums[j];\n      bottoms.push(j);\n    }\n  }\n\n  return bottoms.reverse().concat(tops);\n};\n\nvar reverse = function(series) {\n  return none$2(series).reverse();\n};\n\nvar constant$11 = function(x) {\n  return function() {\n    return x;\n  };\n};\n\nfunction x$4(d) {\n  return d[0];\n}\n\nfunction y$4(d) {\n  return d[1];\n}\n\nfunction RedBlackTree() {\n  this._ = null; // root node\n}\n\nfunction RedBlackNode(node) {\n  node.U = // parent node\n  node.C = // color - true for red, false for black\n  node.L = // left node\n  node.R = // right node\n  node.P = // previous node\n  node.N = null; // next node\n}\n\nRedBlackTree.prototype = {\n  constructor: RedBlackTree,\n\n  insert: function(after, node) {\n    var parent, grandpa, uncle;\n\n    if (after) {\n      node.P = after;\n      node.N = after.N;\n      if (after.N) after.N.P = node;\n      after.N = node;\n      if (after.R) {\n        after = after.R;\n        while (after.L) after = after.L;\n        after.L = node;\n      } else {\n        after.R = node;\n      }\n      parent = after;\n    } else if (this._) {\n      after = RedBlackFirst(this._);\n      node.P = null;\n      node.N = after;\n      after.P = after.L = node;\n      parent = after;\n    } else {\n      node.P = node.N = null;\n      this._ = node;\n      parent = null;\n    }\n    node.L = node.R = null;\n    node.U = parent;\n    node.C = true;\n\n    after = node;\n    while (parent && parent.C) {\n      grandpa = parent.U;\n      if (parent === grandpa.L) {\n        uncle = grandpa.R;\n        if (uncle && uncle.C) {\n          parent.C = uncle.C = false;\n          grandpa.C = true;\n          after = grandpa;\n        } else {\n          if (after === parent.R) {\n            RedBlackRotateLeft(this, parent);\n            after = parent;\n            parent = after.U;\n          }\n          parent.C = false;\n          grandpa.C = true;\n          RedBlackRotateRight(this, grandpa);\n        }\n      } else {\n        uncle = grandpa.L;\n        if (uncle && uncle.C) {\n          parent.C = uncle.C = false;\n          grandpa.C = true;\n          after = grandpa;\n        } else {\n          if (after === parent.L) {\n            RedBlackRotateRight(this, parent);\n            after = parent;\n            parent = after.U;\n          }\n          parent.C = false;\n          grandpa.C = true;\n          RedBlackRotateLeft(this, grandpa);\n        }\n      }\n      parent = after.U;\n    }\n    this._.C = false;\n  },\n\n  remove: function(node) {\n    if (node.N) node.N.P = node.P;\n    if (node.P) node.P.N = node.N;\n    node.N = node.P = null;\n\n    var parent = node.U,\n        sibling,\n        left = node.L,\n        right = node.R,\n        next,\n        red;\n\n    if (!left) next = right;\n    else if (!right) next = left;\n    else next = RedBlackFirst(right);\n\n    if (parent) {\n      if (parent.L === node) parent.L = next;\n      else parent.R = next;\n    } else {\n      this._ = next;\n    }\n\n    if (left && right) {\n      red = next.C;\n      next.C = node.C;\n      next.L = left;\n      left.U = next;\n      if (next !== right) {\n        parent = next.U;\n        next.U = node.U;\n        node = next.R;\n        parent.L = node;\n        next.R = right;\n        right.U = next;\n      } else {\n        next.U = parent;\n        parent = next;\n        node = next.R;\n      }\n    } else {\n      red = node.C;\n      node = next;\n    }\n\n    if (node) node.U = parent;\n    if (red) return;\n    if (node && node.C) { node.C = false; return; }\n\n    do {\n      if (node === this._) break;\n      if (node === parent.L) {\n        sibling = parent.R;\n        if (sibling.C) {\n          sibling.C = false;\n          parent.C = true;\n          RedBlackRotateLeft(this, parent);\n          sibling = parent.R;\n        }\n        if ((sibling.L && sibling.L.C)\n            || (sibling.R && sibling.R.C)) {\n          if (!sibling.R || !sibling.R.C) {\n            sibling.L.C = false;\n            sibling.C = true;\n            RedBlackRotateRight(this, sibling);\n            sibling = parent.R;\n          }\n          sibling.C = parent.C;\n          parent.C = sibling.R.C = false;\n          RedBlackRotateLeft(this, parent);\n          node = this._;\n          break;\n        }\n      } else {\n        sibling = parent.L;\n        if (sibling.C) {\n          sibling.C = false;\n          parent.C = true;\n          RedBlackRotateRight(this, parent);\n          sibling = parent.L;\n        }\n        if ((sibling.L && sibling.L.C)\n          || (sibling.R && sibling.R.C)) {\n          if (!sibling.L || !sibling.L.C) {\n            sibling.R.C = false;\n            sibling.C = true;\n            RedBlackRotateLeft(this, sibling);\n            sibling = parent.L;\n          }\n          sibling.C = parent.C;\n          parent.C = sibling.L.C = false;\n          RedBlackRotateRight(this, parent);\n          node = this._;\n          break;\n        }\n      }\n      sibling.C = true;\n      node = parent;\n      parent = parent.U;\n    } while (!node.C);\n\n    if (node) node.C = false;\n  }\n};\n\nfunction RedBlackRotateLeft(tree, node) {\n  var p = node,\n      q = node.R,\n      parent = p.U;\n\n  if (parent) {\n    if (parent.L === p) parent.L = q;\n    else parent.R = q;\n  } else {\n    tree._ = q;\n  }\n\n  q.U = parent;\n  p.U = q;\n  p.R = q.L;\n  if (p.R) p.R.U = p;\n  q.L = p;\n}\n\nfunction RedBlackRotateRight(tree, node) {\n  var p = node,\n      q = node.L,\n      parent = p.U;\n\n  if (parent) {\n    if (parent.L === p) parent.L = q;\n    else parent.R = q;\n  } else {\n    tree._ = q;\n  }\n\n  q.U = parent;\n  p.U = q;\n  p.L = q.R;\n  if (p.L) p.L.U = p;\n  q.R = p;\n}\n\nfunction RedBlackFirst(node) {\n  while (node.L) node = node.L;\n  return node;\n}\n\nfunction createEdge(left, right, v0, v1) {\n  var edge = [null, null],\n      index = edges.push(edge) - 1;\n  edge.left = left;\n  edge.right = right;\n  if (v0) setEdgeEnd(edge, left, right, v0);\n  if (v1) setEdgeEnd(edge, right, left, v1);\n  cells[left.index].halfedges.push(index);\n  cells[right.index].halfedges.push(index);\n  return edge;\n}\n\nfunction createBorderEdge(left, v0, v1) {\n  var edge = [v0, v1];\n  edge.left = left;\n  return edge;\n}\n\nfunction setEdgeEnd(edge, left, right, vertex) {\n  if (!edge[0] && !edge[1]) {\n    edge[0] = vertex;\n    edge.left = left;\n    edge.right = right;\n  } else if (edge.left === right) {\n    edge[1] = vertex;\n  } else {\n    edge[0] = vertex;\n  }\n}\n\n// Liang–Barsky line clipping.\nfunction clipEdge(edge, x0, y0, x1, y1) {\n  var a = edge[0],\n      b = edge[1],\n      ax = a[0],\n      ay = a[1],\n      bx = b[0],\n      by = b[1],\n      t0 = 0,\n      t1 = 1,\n      dx = bx - ax,\n      dy = by - ay,\n      r;\n\n  r = x0 - ax;\n  if (!dx && r > 0) return;\n  r /= dx;\n  if (dx < 0) {\n    if (r < t0) return;\n    if (r < t1) t1 = r;\n  } else if (dx > 0) {\n    if (r > t1) return;\n    if (r > t0) t0 = r;\n  }\n\n  r = x1 - ax;\n  if (!dx && r < 0) return;\n  r /= dx;\n  if (dx < 0) {\n    if (r > t1) return;\n    if (r > t0) t0 = r;\n  } else if (dx > 0) {\n    if (r < t0) return;\n    if (r < t1) t1 = r;\n  }\n\n  r = y0 - ay;\n  if (!dy && r > 0) return;\n  r /= dy;\n  if (dy < 0) {\n    if (r < t0) return;\n    if (r < t1) t1 = r;\n  } else if (dy > 0) {\n    if (r > t1) return;\n    if (r > t0) t0 = r;\n  }\n\n  r = y1 - ay;\n  if (!dy && r < 0) return;\n  r /= dy;\n  if (dy < 0) {\n    if (r > t1) return;\n    if (r > t0) t0 = r;\n  } else if (dy > 0) {\n    if (r < t0) return;\n    if (r < t1) t1 = r;\n  }\n\n  if (!(t0 > 0) && !(t1 < 1)) return true; // TODO Better check?\n\n  if (t0 > 0) edge[0] = [ax + t0 * dx, ay + t0 * dy];\n  if (t1 < 1) edge[1] = [ax + t1 * dx, ay + t1 * dy];\n  return true;\n}\n\nfunction connectEdge(edge, x0, y0, x1, y1) {\n  var v1 = edge[1];\n  if (v1) return true;\n\n  var v0 = edge[0],\n      left = edge.left,\n      right = edge.right,\n      lx = left[0],\n      ly = left[1],\n      rx = right[0],\n      ry = right[1],\n      fx = (lx + rx) / 2,\n      fy = (ly + ry) / 2,\n      fm,\n      fb;\n\n  if (ry === ly) {\n    if (fx < x0 || fx >= x1) return;\n    if (lx > rx) {\n      if (!v0) v0 = [fx, y0];\n      else if (v0[1] >= y1) return;\n      v1 = [fx, y1];\n    } else {\n      if (!v0) v0 = [fx, y1];\n      else if (v0[1] < y0) return;\n      v1 = [fx, y0];\n    }\n  } else {\n    fm = (lx - rx) / (ry - ly);\n    fb = fy - fm * fx;\n    if (fm < -1 || fm > 1) {\n      if (lx > rx) {\n        if (!v0) v0 = [(y0 - fb) / fm, y0];\n        else if (v0[1] >= y1) return;\n        v1 = [(y1 - fb) / fm, y1];\n      } else {\n        if (!v0) v0 = [(y1 - fb) / fm, y1];\n        else if (v0[1] < y0) return;\n        v1 = [(y0 - fb) / fm, y0];\n      }\n    } else {\n      if (ly < ry) {\n        if (!v0) v0 = [x0, fm * x0 + fb];\n        else if (v0[0] >= x1) return;\n        v1 = [x1, fm * x1 + fb];\n      } else {\n        if (!v0) v0 = [x1, fm * x1 + fb];\n        else if (v0[0] < x0) return;\n        v1 = [x0, fm * x0 + fb];\n      }\n    }\n  }\n\n  edge[0] = v0;\n  edge[1] = v1;\n  return true;\n}\n\nfunction clipEdges(x0, y0, x1, y1) {\n  var i = edges.length,\n      edge;\n\n  while (i--) {\n    if (!connectEdge(edge = edges[i], x0, y0, x1, y1)\n        || !clipEdge(edge, x0, y0, x1, y1)\n        || !(Math.abs(edge[0][0] - edge[1][0]) > epsilon$4\n            || Math.abs(edge[0][1] - edge[1][1]) > epsilon$4)) {\n      delete edges[i];\n    }\n  }\n}\n\nfunction createCell(site) {\n  return cells[site.index] = {\n    site: site,\n    halfedges: []\n  };\n}\n\nfunction cellHalfedgeAngle(cell, edge) {\n  var site = cell.site,\n      va = edge.left,\n      vb = edge.right;\n  if (site === vb) vb = va, va = site;\n  if (vb) return Math.atan2(vb[1] - va[1], vb[0] - va[0]);\n  if (site === va) va = edge[1], vb = edge[0];\n  else va = edge[0], vb = edge[1];\n  return Math.atan2(va[0] - vb[0], vb[1] - va[1]);\n}\n\nfunction cellHalfedgeStart(cell, edge) {\n  return edge[+(edge.left !== cell.site)];\n}\n\nfunction cellHalfedgeEnd(cell, edge) {\n  return edge[+(edge.left === cell.site)];\n}\n\nfunction sortCellHalfedges() {\n  for (var i = 0, n = cells.length, cell, halfedges, j, m; i < n; ++i) {\n    if ((cell = cells[i]) && (m = (halfedges = cell.halfedges).length)) {\n      var index = new Array(m),\n          array = new Array(m);\n      for (j = 0; j < m; ++j) index[j] = j, array[j] = cellHalfedgeAngle(cell, edges[halfedges[j]]);\n      index.sort(function(i, j) { return array[j] - array[i]; });\n      for (j = 0; j < m; ++j) array[j] = halfedges[index[j]];\n      for (j = 0; j < m; ++j) halfedges[j] = array[j];\n    }\n  }\n}\n\nfunction clipCells(x0, y0, x1, y1) {\n  var nCells = cells.length,\n      iCell,\n      cell,\n      site,\n      iHalfedge,\n      halfedges,\n      nHalfedges,\n      start,\n      startX,\n      startY,\n      end,\n      endX,\n      endY,\n      cover = true;\n\n  for (iCell = 0; iCell < nCells; ++iCell) {\n    if (cell = cells[iCell]) {\n      site = cell.site;\n      halfedges = cell.halfedges;\n      iHalfedge = halfedges.length;\n\n      // Remove any dangling clipped edges.\n      while (iHalfedge--) {\n        if (!edges[halfedges[iHalfedge]]) {\n          halfedges.splice(iHalfedge, 1);\n        }\n      }\n\n      // Insert any border edges as necessary.\n      iHalfedge = 0, nHalfedges = halfedges.length;\n      while (iHalfedge < nHalfedges) {\n        end = cellHalfedgeEnd(cell, edges[halfedges[iHalfedge]]), endX = end[0], endY = end[1];\n        start = cellHalfedgeStart(cell, edges[halfedges[++iHalfedge % nHalfedges]]), startX = start[0], startY = start[1];\n        if (Math.abs(endX - startX) > epsilon$4 || Math.abs(endY - startY) > epsilon$4) {\n          halfedges.splice(iHalfedge, 0, edges.push(createBorderEdge(site, end,\n              Math.abs(endX - x0) < epsilon$4 && y1 - endY > epsilon$4 ? [x0, Math.abs(startX - x0) < epsilon$4 ? startY : y1]\n              : Math.abs(endY - y1) < epsilon$4 && x1 - endX > epsilon$4 ? [Math.abs(startY - y1) < epsilon$4 ? startX : x1, y1]\n              : Math.abs(endX - x1) < epsilon$4 && endY - y0 > epsilon$4 ? [x1, Math.abs(startX - x1) < epsilon$4 ? startY : y0]\n              : Math.abs(endY - y0) < epsilon$4 && endX - x0 > epsilon$4 ? [Math.abs(startY - y0) < epsilon$4 ? startX : x0, y0]\n              : null)) - 1);\n          ++nHalfedges;\n        }\n      }\n\n      if (nHalfedges) cover = false;\n    }\n  }\n\n  // If there weren’t any edges, have the closest site cover the extent.\n  // It doesn’t matter which corner of the extent we measure!\n  if (cover) {\n    var dx, dy, d2, dc = Infinity;\n\n    for (iCell = 0, cover = null; iCell < nCells; ++iCell) {\n      if (cell = cells[iCell]) {\n        site = cell.site;\n        dx = site[0] - x0;\n        dy = site[1] - y0;\n        d2 = dx * dx + dy * dy;\n        if (d2 < dc) dc = d2, cover = cell;\n      }\n    }\n\n    if (cover) {\n      var v00 = [x0, y0], v01 = [x0, y1], v11 = [x1, y1], v10 = [x1, y0];\n      cover.halfedges.push(\n        edges.push(createBorderEdge(site = cover.site, v00, v01)) - 1,\n        edges.push(createBorderEdge(site, v01, v11)) - 1,\n        edges.push(createBorderEdge(site, v11, v10)) - 1,\n        edges.push(createBorderEdge(site, v10, v00)) - 1\n      );\n    }\n  }\n\n  // Lastly delete any cells with no edges; these were entirely clipped.\n  for (iCell = 0; iCell < nCells; ++iCell) {\n    if (cell = cells[iCell]) {\n      if (!cell.halfedges.length) {\n        delete cells[iCell];\n      }\n    }\n  }\n}\n\nvar circlePool = [];\n\nvar firstCircle;\n\nfunction Circle() {\n  RedBlackNode(this);\n  this.x =\n  this.y =\n  this.arc =\n  this.site =\n  this.cy = null;\n}\n\nfunction attachCircle(arc) {\n  var lArc = arc.P,\n      rArc = arc.N;\n\n  if (!lArc || !rArc) return;\n\n  var lSite = lArc.site,\n      cSite = arc.site,\n      rSite = rArc.site;\n\n  if (lSite === rSite) return;\n\n  var bx = cSite[0],\n      by = cSite[1],\n      ax = lSite[0] - bx,\n      ay = lSite[1] - by,\n      cx = rSite[0] - bx,\n      cy = rSite[1] - by;\n\n  var d = 2 * (ax * cy - ay * cx);\n  if (d >= -epsilon2$2) return;\n\n  var ha = ax * ax + ay * ay,\n      hc = cx * cx + cy * cy,\n      x = (cy * ha - ay * hc) / d,\n      y = (ax * hc - cx * ha) / d;\n\n  var circle = circlePool.pop() || new Circle;\n  circle.arc = arc;\n  circle.site = cSite;\n  circle.x = x + bx;\n  circle.y = (circle.cy = y + by) + Math.sqrt(x * x + y * y); // y bottom\n\n  arc.circle = circle;\n\n  var before = null,\n      node = circles._;\n\n  while (node) {\n    if (circle.y < node.y || (circle.y === node.y && circle.x <= node.x)) {\n      if (node.L) node = node.L;\n      else { before = node.P; break; }\n    } else {\n      if (node.R) node = node.R;\n      else { before = node; break; }\n    }\n  }\n\n  circles.insert(before, circle);\n  if (!before) firstCircle = circle;\n}\n\nfunction detachCircle(arc) {\n  var circle = arc.circle;\n  if (circle) {\n    if (!circle.P) firstCircle = circle.N;\n    circles.remove(circle);\n    circlePool.push(circle);\n    RedBlackNode(circle);\n    arc.circle = null;\n  }\n}\n\nvar beachPool = [];\n\nfunction Beach() {\n  RedBlackNode(this);\n  this.edge =\n  this.site =\n  this.circle = null;\n}\n\nfunction createBeach(site) {\n  var beach = beachPool.pop() || new Beach;\n  beach.site = site;\n  return beach;\n}\n\nfunction detachBeach(beach) {\n  detachCircle(beach);\n  beaches.remove(beach);\n  beachPool.push(beach);\n  RedBlackNode(beach);\n}\n\nfunction removeBeach(beach) {\n  var circle = beach.circle,\n      x = circle.x,\n      y = circle.cy,\n      vertex = [x, y],\n      previous = beach.P,\n      next = beach.N,\n      disappearing = [beach];\n\n  detachBeach(beach);\n\n  var lArc = previous;\n  while (lArc.circle\n      && Math.abs(x - lArc.circle.x) < epsilon$4\n      && Math.abs(y - lArc.circle.cy) < epsilon$4) {\n    previous = lArc.P;\n    disappearing.unshift(lArc);\n    detachBeach(lArc);\n    lArc = previous;\n  }\n\n  disappearing.unshift(lArc);\n  detachCircle(lArc);\n\n  var rArc = next;\n  while (rArc.circle\n      && Math.abs(x - rArc.circle.x) < epsilon$4\n      && Math.abs(y - rArc.circle.cy) < epsilon$4) {\n    next = rArc.N;\n    disappearing.push(rArc);\n    detachBeach(rArc);\n    rArc = next;\n  }\n\n  disappearing.push(rArc);\n  detachCircle(rArc);\n\n  var nArcs = disappearing.length,\n      iArc;\n  for (iArc = 1; iArc < nArcs; ++iArc) {\n    rArc = disappearing[iArc];\n    lArc = disappearing[iArc - 1];\n    setEdgeEnd(rArc.edge, lArc.site, rArc.site, vertex);\n  }\n\n  lArc = disappearing[0];\n  rArc = disappearing[nArcs - 1];\n  rArc.edge = createEdge(lArc.site, rArc.site, null, vertex);\n\n  attachCircle(lArc);\n  attachCircle(rArc);\n}\n\nfunction addBeach(site) {\n  var x = site[0],\n      directrix = site[1],\n      lArc,\n      rArc,\n      dxl,\n      dxr,\n      node = beaches._;\n\n  while (node) {\n    dxl = leftBreakPoint(node, directrix) - x;\n    if (dxl > epsilon$4) node = node.L; else {\n      dxr = x - rightBreakPoint(node, directrix);\n      if (dxr > epsilon$4) {\n        if (!node.R) {\n          lArc = node;\n          break;\n        }\n        node = node.R;\n      } else {\n        if (dxl > -epsilon$4) {\n          lArc = node.P;\n          rArc = node;\n        } else if (dxr > -epsilon$4) {\n          lArc = node;\n          rArc = node.N;\n        } else {\n          lArc = rArc = node;\n        }\n        break;\n      }\n    }\n  }\n\n  createCell(site);\n  var newArc = createBeach(site);\n  beaches.insert(lArc, newArc);\n\n  if (!lArc && !rArc) return;\n\n  if (lArc === rArc) {\n    detachCircle(lArc);\n    rArc = createBeach(lArc.site);\n    beaches.insert(newArc, rArc);\n    newArc.edge = rArc.edge = createEdge(lArc.site, newArc.site);\n    attachCircle(lArc);\n    attachCircle(rArc);\n    return;\n  }\n\n  if (!rArc) { // && lArc\n    newArc.edge = createEdge(lArc.site, newArc.site);\n    return;\n  }\n\n  // else lArc !== rArc\n  detachCircle(lArc);\n  detachCircle(rArc);\n\n  var lSite = lArc.site,\n      ax = lSite[0],\n      ay = lSite[1],\n      bx = site[0] - ax,\n      by = site[1] - ay,\n      rSite = rArc.site,\n      cx = rSite[0] - ax,\n      cy = rSite[1] - ay,\n      d = 2 * (bx * cy - by * cx),\n      hb = bx * bx + by * by,\n      hc = cx * cx + cy * cy,\n      vertex = [(cy * hb - by * hc) / d + ax, (bx * hc - cx * hb) / d + ay];\n\n  setEdgeEnd(rArc.edge, lSite, rSite, vertex);\n  newArc.edge = createEdge(lSite, site, null, vertex);\n  rArc.edge = createEdge(site, rSite, null, vertex);\n  attachCircle(lArc);\n  attachCircle(rArc);\n}\n\nfunction leftBreakPoint(arc, directrix) {\n  var site = arc.site,\n      rfocx = site[0],\n      rfocy = site[1],\n      pby2 = rfocy - directrix;\n\n  if (!pby2) return rfocx;\n\n  var lArc = arc.P;\n  if (!lArc) return -Infinity;\n\n  site = lArc.site;\n  var lfocx = site[0],\n      lfocy = site[1],\n      plby2 = lfocy - directrix;\n\n  if (!plby2) return lfocx;\n\n  var hl = lfocx - rfocx,\n      aby2 = 1 / pby2 - 1 / plby2,\n      b = hl / plby2;\n\n  if (aby2) return (-b + Math.sqrt(b * b - 2 * aby2 * (hl * hl / (-2 * plby2) - lfocy + plby2 / 2 + rfocy - pby2 / 2))) / aby2 + rfocx;\n\n  return (rfocx + lfocx) / 2;\n}\n\nfunction rightBreakPoint(arc, directrix) {\n  var rArc = arc.N;\n  if (rArc) return leftBreakPoint(rArc, directrix);\n  var site = arc.site;\n  return site[1] === directrix ? site[0] : Infinity;\n}\n\nvar epsilon$4 = 1e-6;\nvar epsilon2$2 = 1e-12;\nvar beaches;\nvar cells;\nvar circles;\nvar edges;\n\nfunction triangleArea(a, b, c) {\n  return (a[0] - c[0]) * (b[1] - a[1]) - (a[0] - b[0]) * (c[1] - a[1]);\n}\n\nfunction lexicographic(a, b) {\n  return b[1] - a[1]\n      || b[0] - a[0];\n}\n\nfunction Diagram(sites, extent) {\n  var site = sites.sort(lexicographic).pop(),\n      x,\n      y,\n      circle;\n\n  edges = [];\n  cells = new Array(sites.length);\n  beaches = new RedBlackTree;\n  circles = new RedBlackTree;\n\n  while (true) {\n    circle = firstCircle;\n    if (site && (!circle || site[1] < circle.y || (site[1] === circle.y && site[0] < circle.x))) {\n      if (site[0] !== x || site[1] !== y) {\n        addBeach(site);\n        x = site[0], y = site[1];\n      }\n      site = sites.pop();\n    } else if (circle) {\n      removeBeach(circle.arc);\n    } else {\n      break;\n    }\n  }\n\n  sortCellHalfedges();\n\n  if (extent) {\n    var x0 = +extent[0][0],\n        y0 = +extent[0][1],\n        x1 = +extent[1][0],\n        y1 = +extent[1][1];\n    clipEdges(x0, y0, x1, y1);\n    clipCells(x0, y0, x1, y1);\n  }\n\n  this.edges = edges;\n  this.cells = cells;\n\n  beaches =\n  circles =\n  edges =\n  cells = null;\n}\n\nDiagram.prototype = {\n  constructor: Diagram,\n\n  polygons: function() {\n    var edges = this.edges;\n\n    return this.cells.map(function(cell) {\n      var polygon = cell.halfedges.map(function(i) { return cellHalfedgeStart(cell, edges[i]); });\n      polygon.data = cell.site.data;\n      return polygon;\n    });\n  },\n\n  triangles: function() {\n    var triangles = [],\n        edges = this.edges;\n\n    this.cells.forEach(function(cell, i) {\n      if (!(m = (halfedges = cell.halfedges).length)) return;\n      var site = cell.site,\n          halfedges,\n          j = -1,\n          m,\n          s0,\n          e1 = edges[halfedges[m - 1]],\n          s1 = e1.left === site ? e1.right : e1.left;\n\n      while (++j < m) {\n        s0 = s1;\n        e1 = edges[halfedges[j]];\n        s1 = e1.left === site ? e1.right : e1.left;\n        if (s0 && s1 && i < s0.index && i < s1.index && triangleArea(site, s0, s1) < 0) {\n          triangles.push([site.data, s0.data, s1.data]);\n        }\n      }\n    });\n\n    return triangles;\n  },\n\n  links: function() {\n    return this.edges.filter(function(edge) {\n      return edge.right;\n    }).map(function(edge) {\n      return {\n        source: edge.left.data,\n        target: edge.right.data\n      };\n    });\n  },\n\n  find: function(x, y, radius) {\n    var that = this, i0, i1 = that._found || 0, n = that.cells.length, cell;\n\n    // Use the previously-found cell, or start with an arbitrary one.\n    while (!(cell = that.cells[i1])) if (++i1 >= n) return null;\n    var dx = x - cell.site[0], dy = y - cell.site[1], d2 = dx * dx + dy * dy;\n\n    // Traverse the half-edges to find a closer cell, if any.\n    do {\n      cell = that.cells[i0 = i1], i1 = null;\n      cell.halfedges.forEach(function(e) {\n        var edge = that.edges[e], v = edge.left;\n        if ((v === cell.site || !v) && !(v = edge.right)) return;\n        var vx = x - v[0], vy = y - v[1], v2 = vx * vx + vy * vy;\n        if (v2 < d2) d2 = v2, i1 = v.index;\n      });\n    } while (i1 !== null);\n\n    that._found = i0;\n\n    return radius == null || d2 <= radius * radius ? cell.site : null;\n  }\n};\n\nvar voronoi = function() {\n  var x$$1 = x$4,\n      y$$1 = y$4,\n      extent = null;\n\n  function voronoi(data) {\n    return new Diagram(data.map(function(d, i) {\n      var s = [Math.round(x$$1(d, i, data) / epsilon$4) * epsilon$4, Math.round(y$$1(d, i, data) / epsilon$4) * epsilon$4];\n      s.index = i;\n      s.data = d;\n      return s;\n    }), extent);\n  }\n\n  voronoi.polygons = function(data) {\n    return voronoi(data).polygons();\n  };\n\n  voronoi.links = function(data) {\n    return voronoi(data).links();\n  };\n\n  voronoi.triangles = function(data) {\n    return voronoi(data).triangles();\n  };\n\n  voronoi.x = function(_) {\n    return arguments.length ? (x$$1 = typeof _ === \"function\" ? _ : constant$11(+_), voronoi) : x$$1;\n  };\n\n  voronoi.y = function(_) {\n    return arguments.length ? (y$$1 = typeof _ === \"function\" ? _ : constant$11(+_), voronoi) : y$$1;\n  };\n\n  voronoi.extent = function(_) {\n    return arguments.length ? (extent = _ == null ? null : [[+_[0][0], +_[0][1]], [+_[1][0], +_[1][1]]], voronoi) : extent && [[extent[0][0], extent[0][1]], [extent[1][0], extent[1][1]]];\n  };\n\n  voronoi.size = function(_) {\n    return arguments.length ? (extent = _ == null ? null : [[0, 0], [+_[0], +_[1]]], voronoi) : extent && [extent[1][0] - extent[0][0], extent[1][1] - extent[0][1]];\n  };\n\n  return voronoi;\n};\n\nvar constant$12 = function(x) {\n  return function() {\n    return x;\n  };\n};\n\nfunction ZoomEvent(target, type, transform) {\n  this.target = target;\n  this.type = type;\n  this.transform = transform;\n}\n\nfunction Transform(k, x, y) {\n  this.k = k;\n  this.x = x;\n  this.y = y;\n}\n\nTransform.prototype = {\n  constructor: Transform,\n  scale: function(k) {\n    return k === 1 ? this : new Transform(this.k * k, this.x, this.y);\n  },\n  translate: function(x, y) {\n    return x === 0 & y === 0 ? this : new Transform(this.k, this.x + this.k * x, this.y + this.k * y);\n  },\n  apply: function(point) {\n    return [point[0] * this.k + this.x, point[1] * this.k + this.y];\n  },\n  applyX: function(x) {\n    return x * this.k + this.x;\n  },\n  applyY: function(y) {\n    return y * this.k + this.y;\n  },\n  invert: function(location) {\n    return [(location[0] - this.x) / this.k, (location[1] - this.y) / this.k];\n  },\n  invertX: function(x) {\n    return (x - this.x) / this.k;\n  },\n  invertY: function(y) {\n    return (y - this.y) / this.k;\n  },\n  rescaleX: function(x) {\n    return x.copy().domain(x.range().map(this.invertX, this).map(x.invert, x));\n  },\n  rescaleY: function(y) {\n    return y.copy().domain(y.range().map(this.invertY, this).map(y.invert, y));\n  },\n  toString: function() {\n    return \"translate(\" + this.x + \",\" + this.y + \") scale(\" + this.k + \")\";\n  }\n};\n\nvar identity$8 = new Transform(1, 0, 0);\n\ntransform$1.prototype = Transform.prototype;\n\nfunction transform$1(node) {\n  return node.__zoom || identity$8;\n}\n\nfunction nopropagation$2() {\n  exports.event.stopImmediatePropagation();\n}\n\nvar noevent$2 = function() {\n  exports.event.preventDefault();\n  exports.event.stopImmediatePropagation();\n};\n\n// Ignore right-click, since that should open the context menu.\nfunction defaultFilter$2() {\n  return !exports.event.button;\n}\n\nfunction defaultExtent$1() {\n  var e = this, w, h;\n  if (e instanceof SVGElement) {\n    e = e.ownerSVGElement || e;\n    w = e.width.baseVal.value;\n    h = e.height.baseVal.value;\n  } else {\n    w = e.clientWidth;\n    h = e.clientHeight;\n  }\n  return [[0, 0], [w, h]];\n}\n\nfunction defaultTransform() {\n  return this.__zoom || identity$8;\n}\n\nvar zoom = function() {\n  var filter = defaultFilter$2,\n      extent = defaultExtent$1,\n      k0 = 0,\n      k1 = Infinity,\n      x0 = -k1,\n      x1 = k1,\n      y0 = x0,\n      y1 = x1,\n      duration = 250,\n      interpolate$$1 = interpolateZoom,\n      gestures = [],\n      listeners = dispatch(\"start\", \"zoom\", \"end\"),\n      touchstarting,\n      touchending,\n      touchDelay = 500,\n      wheelDelay = 150,\n      clickDistance2 = 0;\n\n  function zoom(selection$$1) {\n    selection$$1\n        .on(\"wheel.zoom\", wheeled)\n        .on(\"mousedown.zoom\", mousedowned)\n        .on(\"dblclick.zoom\", dblclicked)\n        .on(\"touchstart.zoom\", touchstarted)\n        .on(\"touchmove.zoom\", touchmoved)\n        .on(\"touchend.zoom touchcancel.zoom\", touchended)\n        .style(\"-webkit-tap-highlight-color\", \"rgba(0,0,0,0)\")\n        .property(\"__zoom\", defaultTransform);\n  }\n\n  zoom.transform = function(collection, transform) {\n    var selection$$1 = collection.selection ? collection.selection() : collection;\n    selection$$1.property(\"__zoom\", defaultTransform);\n    if (collection !== selection$$1) {\n      schedule(collection, transform);\n    } else {\n      selection$$1.interrupt().each(function() {\n        gesture(this, arguments)\n            .start()\n            .zoom(null, typeof transform === \"function\" ? transform.apply(this, arguments) : transform)\n            .end();\n      });\n    }\n  };\n\n  zoom.scaleBy = function(selection$$1, k) {\n    zoom.scaleTo(selection$$1, function() {\n      var k0 = this.__zoom.k,\n          k1 = typeof k === \"function\" ? k.apply(this, arguments) : k;\n      return k0 * k1;\n    });\n  };\n\n  zoom.scaleTo = function(selection$$1, k) {\n    zoom.transform(selection$$1, function() {\n      var e = extent.apply(this, arguments),\n          t0 = this.__zoom,\n          p0 = centroid(e),\n          p1 = t0.invert(p0),\n          k1 = typeof k === \"function\" ? k.apply(this, arguments) : k;\n      return constrain(translate(scale(t0, k1), p0, p1), e);\n    });\n  };\n\n  zoom.translateBy = function(selection$$1, x, y) {\n    zoom.transform(selection$$1, function() {\n      return constrain(this.__zoom.translate(\n        typeof x === \"function\" ? x.apply(this, arguments) : x,\n        typeof y === \"function\" ? y.apply(this, arguments) : y\n      ), extent.apply(this, arguments));\n    });\n  };\n\n  function scale(transform, k) {\n    k = Math.max(k0, Math.min(k1, k));\n    return k === transform.k ? transform : new Transform(k, transform.x, transform.y);\n  }\n\n  function translate(transform, p0, p1) {\n    var x = p0[0] - p1[0] * transform.k, y = p0[1] - p1[1] * transform.k;\n    return x === transform.x && y === transform.y ? transform : new Transform(transform.k, x, y);\n  }\n\n  function constrain(transform, extent) {\n    var dx0 = transform.invertX(extent[0][0]) - x0,\n        dx1 = transform.invertX(extent[1][0]) - x1,\n        dy0 = transform.invertY(extent[0][1]) - y0,\n        dy1 = transform.invertY(extent[1][1]) - y1;\n    return transform.translate(\n      dx1 > dx0 ? (dx0 + dx1) / 2 : Math.min(0, dx0) || Math.max(0, dx1),\n      dy1 > dy0 ? (dy0 + dy1) / 2 : Math.min(0, dy0) || Math.max(0, dy1)\n    );\n  }\n\n  function centroid(extent) {\n    return [(+extent[0][0] + +extent[1][0]) / 2, (+extent[0][1] + +extent[1][1]) / 2];\n  }\n\n  function schedule(transition$$1, transform, center) {\n    transition$$1\n        .on(\"start.zoom\", function() { gesture(this, arguments).start(); })\n        .on(\"interrupt.zoom end.zoom\", function() { gesture(this, arguments).end(); })\n        .tween(\"zoom\", function() {\n          var that = this,\n              args = arguments,\n              g = gesture(that, args),\n              e = extent.apply(that, args),\n              p = center || centroid(e),\n              w = Math.max(e[1][0] - e[0][0], e[1][1] - e[0][1]),\n              a = that.__zoom,\n              b = typeof transform === \"function\" ? transform.apply(that, args) : transform,\n              i = interpolate$$1(a.invert(p).concat(w / a.k), b.invert(p).concat(w / b.k));\n          return function(t) {\n            if (t === 1) t = b; // Avoid rounding error on end.\n            else { var l = i(t), k = w / l[2]; t = new Transform(k, p[0] - l[0] * k, p[1] - l[1] * k); }\n            g.zoom(null, t);\n          };\n        });\n  }\n\n  function gesture(that, args) {\n    for (var i = 0, n = gestures.length, g; i < n; ++i) {\n      if ((g = gestures[i]).that === that) {\n        return g;\n      }\n    }\n    return new Gesture(that, args);\n  }\n\n  function Gesture(that, args) {\n    this.that = that;\n    this.args = args;\n    this.index = -1;\n    this.active = 0;\n    this.extent = extent.apply(that, args);\n  }\n\n  Gesture.prototype = {\n    start: function() {\n      if (++this.active === 1) {\n        this.index = gestures.push(this) - 1;\n        this.emit(\"start\");\n      }\n      return this;\n    },\n    zoom: function(key, transform) {\n      if (this.mouse && key !== \"mouse\") this.mouse[1] = transform.invert(this.mouse[0]);\n      if (this.touch0 && key !== \"touch\") this.touch0[1] = transform.invert(this.touch0[0]);\n      if (this.touch1 && key !== \"touch\") this.touch1[1] = transform.invert(this.touch1[0]);\n      this.that.__zoom = transform;\n      this.emit(\"zoom\");\n      return this;\n    },\n    end: function() {\n      if (--this.active === 0) {\n        gestures.splice(this.index, 1);\n        this.index = -1;\n        this.emit(\"end\");\n      }\n      return this;\n    },\n    emit: function(type) {\n      customEvent(new ZoomEvent(zoom, type, this.that.__zoom), listeners.apply, listeners, [type, this.that, this.args]);\n    }\n  };\n\n  function wheeled() {\n    if (!filter.apply(this, arguments)) return;\n    var g = gesture(this, arguments),\n        t = this.__zoom,\n        k = Math.max(k0, Math.min(k1, t.k * Math.pow(2, -exports.event.deltaY * (exports.event.deltaMode ? 120 : 1) / 500))),\n        p = mouse(this);\n\n    // If the mouse is in the same location as before, reuse it.\n    // If there were recent wheel events, reset the wheel idle timeout.\n    if (g.wheel) {\n      if (g.mouse[0][0] !== p[0] || g.mouse[0][1] !== p[1]) {\n        g.mouse[1] = t.invert(g.mouse[0] = p);\n      }\n      clearTimeout(g.wheel);\n    }\n\n    // If this wheel event won’t trigger a transform change, ignore it.\n    else if (t.k === k) return;\n\n    // Otherwise, capture the mouse point and location at the start.\n    else {\n      g.mouse = [p, t.invert(p)];\n      interrupt(this);\n      g.start();\n    }\n\n    noevent$2();\n    g.wheel = setTimeout(wheelidled, wheelDelay);\n    g.zoom(\"mouse\", constrain(translate(scale(t, k), g.mouse[0], g.mouse[1]), g.extent));\n\n    function wheelidled() {\n      g.wheel = null;\n      g.end();\n    }\n  }\n\n  function mousedowned() {\n    if (touchending || !filter.apply(this, arguments)) return;\n    var g = gesture(this, arguments),\n        v = select(exports.event.view).on(\"mousemove.zoom\", mousemoved, true).on(\"mouseup.zoom\", mouseupped, true),\n        p = mouse(this),\n        x0 = exports.event.clientX,\n        y0 = exports.event.clientY;\n\n    dragDisable(exports.event.view);\n    nopropagation$2();\n    g.mouse = [p, this.__zoom.invert(p)];\n    interrupt(this);\n    g.start();\n\n    function mousemoved() {\n      noevent$2();\n      if (!g.moved) {\n        var dx = exports.event.clientX - x0, dy = exports.event.clientY - y0;\n        g.moved = dx * dx + dy * dy > clickDistance2;\n      }\n      g.zoom(\"mouse\", constrain(translate(g.that.__zoom, g.mouse[0] = mouse(g.that), g.mouse[1]), g.extent));\n    }\n\n    function mouseupped() {\n      v.on(\"mousemove.zoom mouseup.zoom\", null);\n      yesdrag(exports.event.view, g.moved);\n      noevent$2();\n      g.end();\n    }\n  }\n\n  function dblclicked() {\n    if (!filter.apply(this, arguments)) return;\n    var t0 = this.__zoom,\n        p0 = mouse(this),\n        p1 = t0.invert(p0),\n        k1 = t0.k * (exports.event.shiftKey ? 0.5 : 2),\n        t1 = constrain(translate(scale(t0, k1), p0, p1), extent.apply(this, arguments));\n\n    noevent$2();\n    if (duration > 0) select(this).transition().duration(duration).call(schedule, t1, p0);\n    else select(this).call(zoom.transform, t1);\n  }\n\n  function touchstarted() {\n    if (!filter.apply(this, arguments)) return;\n    var g = gesture(this, arguments),\n        touches$$1 = exports.event.changedTouches,\n        started,\n        n = touches$$1.length, i, t, p;\n\n    nopropagation$2();\n    for (i = 0; i < n; ++i) {\n      t = touches$$1[i], p = touch(this, touches$$1, t.identifier);\n      p = [p, this.__zoom.invert(p), t.identifier];\n      if (!g.touch0) g.touch0 = p, started = true;\n      else if (!g.touch1) g.touch1 = p;\n    }\n\n    // If this is a dbltap, reroute to the (optional) dblclick.zoom handler.\n    if (touchstarting) {\n      touchstarting = clearTimeout(touchstarting);\n      if (!g.touch1) {\n        g.end();\n        p = select(this).on(\"dblclick.zoom\");\n        if (p) p.apply(this, arguments);\n        return;\n      }\n    }\n\n    if (started) {\n      touchstarting = setTimeout(function() { touchstarting = null; }, touchDelay);\n      interrupt(this);\n      g.start();\n    }\n  }\n\n  function touchmoved() {\n    var g = gesture(this, arguments),\n        touches$$1 = exports.event.changedTouches,\n        n = touches$$1.length, i, t, p, l;\n\n    noevent$2();\n    if (touchstarting) touchstarting = clearTimeout(touchstarting);\n    for (i = 0; i < n; ++i) {\n      t = touches$$1[i], p = touch(this, touches$$1, t.identifier);\n      if (g.touch0 && g.touch0[2] === t.identifier) g.touch0[0] = p;\n      else if (g.touch1 && g.touch1[2] === t.identifier) g.touch1[0] = p;\n    }\n    t = g.that.__zoom;\n    if (g.touch1) {\n      var p0 = g.touch0[0], l0 = g.touch0[1],\n          p1 = g.touch1[0], l1 = g.touch1[1],\n          dp = (dp = p1[0] - p0[0]) * dp + (dp = p1[1] - p0[1]) * dp,\n          dl = (dl = l1[0] - l0[0]) * dl + (dl = l1[1] - l0[1]) * dl;\n      t = scale(t, Math.sqrt(dp / dl));\n      p = [(p0[0] + p1[0]) / 2, (p0[1] + p1[1]) / 2];\n      l = [(l0[0] + l1[0]) / 2, (l0[1] + l1[1]) / 2];\n    }\n    else if (g.touch0) p = g.touch0[0], l = g.touch0[1];\n    else return;\n    g.zoom(\"touch\", constrain(translate(t, p, l), g.extent));\n  }\n\n  function touchended() {\n    var g = gesture(this, arguments),\n        touches$$1 = exports.event.changedTouches,\n        n = touches$$1.length, i, t;\n\n    nopropagation$2();\n    if (touchending) clearTimeout(touchending);\n    touchending = setTimeout(function() { touchending = null; }, touchDelay);\n    for (i = 0; i < n; ++i) {\n      t = touches$$1[i];\n      if (g.touch0 && g.touch0[2] === t.identifier) delete g.touch0;\n      else if (g.touch1 && g.touch1[2] === t.identifier) delete g.touch1;\n    }\n    if (g.touch1 && !g.touch0) g.touch0 = g.touch1, delete g.touch1;\n    if (g.touch0) g.touch0[1] = this.__zoom.invert(g.touch0[0]);\n    else g.end();\n  }\n\n  zoom.filter = function(_) {\n    return arguments.length ? (filter = typeof _ === \"function\" ? _ : constant$12(!!_), zoom) : filter;\n  };\n\n  zoom.extent = function(_) {\n    return arguments.length ? (extent = typeof _ === \"function\" ? _ : constant$12([[+_[0][0], +_[0][1]], [+_[1][0], +_[1][1]]]), zoom) : extent;\n  };\n\n  zoom.scaleExtent = function(_) {\n    return arguments.length ? (k0 = +_[0], k1 = +_[1], zoom) : [k0, k1];\n  };\n\n  zoom.translateExtent = function(_) {\n    return arguments.length ? (x0 = +_[0][0], x1 = +_[1][0], y0 = +_[0][1], y1 = +_[1][1], zoom) : [[x0, y0], [x1, y1]];\n  };\n\n  zoom.duration = function(_) {\n    return arguments.length ? (duration = +_, zoom) : duration;\n  };\n\n  zoom.interpolate = function(_) {\n    return arguments.length ? (interpolate$$1 = _, zoom) : interpolate$$1;\n  };\n\n  zoom.on = function() {\n    var value = listeners.on.apply(listeners, arguments);\n    return value === listeners ? zoom : value;\n  };\n\n  zoom.clickDistance = function(_) {\n    return arguments.length ? (clickDistance2 = (_ = +_) * _, zoom) : Math.sqrt(clickDistance2);\n  };\n    \n  return zoom;\n};\n\nexports.version = version;\nexports.bisect = bisectRight;\nexports.bisectRight = bisectRight;\nexports.bisectLeft = bisectLeft;\nexports.ascending = ascending;\nexports.bisector = bisector;\nexports.cross = cross;\nexports.descending = descending;\nexports.deviation = deviation;\nexports.extent = extent;\nexports.histogram = histogram;\nexports.thresholdFreedmanDiaconis = freedmanDiaconis;\nexports.thresholdScott = scott;\nexports.thresholdSturges = sturges;\nexports.max = max;\nexports.mean = mean;\nexports.median = median;\nexports.merge = merge;\nexports.min = min;\nexports.pairs = pairs;\nexports.permute = permute;\nexports.quantile = threshold;\nexports.range = sequence;\nexports.scan = scan;\nexports.shuffle = shuffle;\nexports.sum = sum;\nexports.ticks = ticks;\nexports.tickIncrement = tickIncrement;\nexports.tickStep = tickStep;\nexports.transpose = transpose;\nexports.variance = variance;\nexports.zip = zip;\nexports.axisTop = axisTop;\nexports.axisRight = axisRight;\nexports.axisBottom = axisBottom;\nexports.axisLeft = axisLeft;\nexports.brush = brush;\nexports.brushX = brushX;\nexports.brushY = brushY;\nexports.brushSelection = brushSelection;\nexports.chord = chord;\nexports.ribbon = ribbon;\nexports.nest = nest;\nexports.set = set$2;\nexports.map = map$1;\nexports.keys = keys;\nexports.values = values;\nexports.entries = entries;\nexports.color = color;\nexports.rgb = rgb;\nexports.hsl = hsl;\nexports.lab = lab;\nexports.hcl = hcl;\nexports.cubehelix = cubehelix;\nexports.dispatch = dispatch;\nexports.drag = drag;\nexports.dragDisable = dragDisable;\nexports.dragEnable = yesdrag;\nexports.dsvFormat = dsv;\nexports.csvParse = csvParse;\nexports.csvParseRows = csvParseRows;\nexports.csvFormat = csvFormat;\nexports.csvFormatRows = csvFormatRows;\nexports.tsvParse = tsvParse;\nexports.tsvParseRows = tsvParseRows;\nexports.tsvFormat = tsvFormat;\nexports.tsvFormatRows = tsvFormatRows;\nexports.easeLinear = linear$1;\nexports.easeQuad = quadInOut;\nexports.easeQuadIn = quadIn;\nexports.easeQuadOut = quadOut;\nexports.easeQuadInOut = quadInOut;\nexports.easeCubic = cubicInOut;\nexports.easeCubicIn = cubicIn;\nexports.easeCubicOut = cubicOut;\nexports.easeCubicInOut = cubicInOut;\nexports.easePoly = polyInOut;\nexports.easePolyIn = polyIn;\nexports.easePolyOut = polyOut;\nexports.easePolyInOut = polyInOut;\nexports.easeSin = sinInOut;\nexports.easeSinIn = sinIn;\nexports.easeSinOut = sinOut;\nexports.easeSinInOut = sinInOut;\nexports.easeExp = expInOut;\nexports.easeExpIn = expIn;\nexports.easeExpOut = expOut;\nexports.easeExpInOut = expInOut;\nexports.easeCircle = circleInOut;\nexports.easeCircleIn = circleIn;\nexports.easeCircleOut = circleOut;\nexports.easeCircleInOut = circleInOut;\nexports.easeBounce = bounceOut;\nexports.easeBounceIn = bounceIn;\nexports.easeBounceOut = bounceOut;\nexports.easeBounceInOut = bounceInOut;\nexports.easeBack = backInOut;\nexports.easeBackIn = backIn;\nexports.easeBackOut = backOut;\nexports.easeBackInOut = backInOut;\nexports.easeElastic = elasticOut;\nexports.easeElasticIn = elasticIn;\nexports.easeElasticOut = elasticOut;\nexports.easeElasticInOut = elasticInOut;\nexports.forceCenter = center$1;\nexports.forceCollide = collide;\nexports.forceLink = link;\nexports.forceManyBody = manyBody;\nexports.forceSimulation = simulation;\nexports.forceX = x$2;\nexports.forceY = y$2;\nexports.formatDefaultLocale = defaultLocale;\nexports.formatLocale = formatLocale;\nexports.formatSpecifier = formatSpecifier;\nexports.precisionFixed = precisionFixed;\nexports.precisionPrefix = precisionPrefix;\nexports.precisionRound = precisionRound;\nexports.geoArea = area;\nexports.geoBounds = bounds;\nexports.geoCentroid = centroid;\nexports.geoCircle = circle;\nexports.geoClipExtent = extent$1;\nexports.geoContains = contains;\nexports.geoDistance = distance;\nexports.geoGraticule = graticule;\nexports.geoGraticule10 = graticule10;\nexports.geoInterpolate = interpolate$1;\nexports.geoLength = length$1;\nexports.geoPath = index$1;\nexports.geoAlbers = albers;\nexports.geoAlbersUsa = albersUsa;\nexports.geoAzimuthalEqualArea = azimuthalEqualArea;\nexports.geoAzimuthalEqualAreaRaw = azimuthalEqualAreaRaw;\nexports.geoAzimuthalEquidistant = azimuthalEquidistant;\nexports.geoAzimuthalEquidistantRaw = azimuthalEquidistantRaw;\nexports.geoConicConformal = conicConformal;\nexports.geoConicConformalRaw = conicConformalRaw;\nexports.geoConicEqualArea = conicEqualArea;\nexports.geoConicEqualAreaRaw = conicEqualAreaRaw;\nexports.geoConicEquidistant = conicEquidistant;\nexports.geoConicEquidistantRaw = conicEquidistantRaw;\nexports.geoEquirectangular = equirectangular;\nexports.geoEquirectangularRaw = equirectangularRaw;\nexports.geoGnomonic = gnomonic;\nexports.geoGnomonicRaw = gnomonicRaw;\nexports.geoIdentity = identity$5;\nexports.geoProjection = projection;\nexports.geoProjectionMutator = projectionMutator;\nexports.geoMercator = mercator;\nexports.geoMercatorRaw = mercatorRaw;\nexports.geoOrthographic = orthographic;\nexports.geoOrthographicRaw = orthographicRaw;\nexports.geoStereographic = stereographic;\nexports.geoStereographicRaw = stereographicRaw;\nexports.geoTransverseMercator = transverseMercator;\nexports.geoTransverseMercatorRaw = transverseMercatorRaw;\nexports.geoRotation = rotation;\nexports.geoStream = geoStream;\nexports.geoTransform = transform;\nexports.cluster = cluster;\nexports.hierarchy = hierarchy;\nexports.pack = index$2;\nexports.packSiblings = siblings;\nexports.packEnclose = enclose;\nexports.partition = partition;\nexports.stratify = stratify;\nexports.tree = tree;\nexports.treemap = index$3;\nexports.treemapBinary = binary;\nexports.treemapDice = treemapDice;\nexports.treemapSlice = treemapSlice;\nexports.treemapSliceDice = sliceDice;\nexports.treemapSquarify = squarify;\nexports.treemapResquarify = resquarify;\nexports.interpolate = interpolateValue;\nexports.interpolateArray = array$1;\nexports.interpolateBasis = basis$1;\nexports.interpolateBasisClosed = basisClosed;\nexports.interpolateDate = date;\nexports.interpolateNumber = reinterpolate;\nexports.interpolateObject = object;\nexports.interpolateRound = interpolateRound;\nexports.interpolateString = interpolateString;\nexports.interpolateTransformCss = interpolateTransformCss;\nexports.interpolateTransformSvg = interpolateTransformSvg;\nexports.interpolateZoom = interpolateZoom;\nexports.interpolateRgb = interpolateRgb;\nexports.interpolateRgbBasis = rgbBasis;\nexports.interpolateRgbBasisClosed = rgbBasisClosed;\nexports.interpolateHsl = hsl$2;\nexports.interpolateHslLong = hslLong;\nexports.interpolateLab = lab$1;\nexports.interpolateHcl = hcl$2;\nexports.interpolateHclLong = hclLong;\nexports.interpolateCubehelix = cubehelix$2;\nexports.interpolateCubehelixLong = cubehelixLong;\nexports.quantize = quantize;\nexports.path = path;\nexports.polygonArea = area$1;\nexports.polygonCentroid = centroid$1;\nexports.polygonHull = hull;\nexports.polygonContains = contains$1;\nexports.polygonLength = length$2;\nexports.quadtree = quadtree;\nexports.queue = queue;\nexports.randomUniform = uniform;\nexports.randomNormal = normal;\nexports.randomLogNormal = logNormal;\nexports.randomBates = bates;\nexports.randomIrwinHall = irwinHall;\nexports.randomExponential = exponential$1;\nexports.request = request;\nexports.html = html;\nexports.json = json;\nexports.text = text;\nexports.xml = xml;\nexports.csv = csv$1;\nexports.tsv = tsv$1;\nexports.scaleBand = band;\nexports.scalePoint = point$1;\nexports.scaleIdentity = identity$6;\nexports.scaleLinear = linear$2;\nexports.scaleLog = log$1;\nexports.scaleOrdinal = ordinal;\nexports.scaleImplicit = implicit;\nexports.scalePow = pow$1;\nexports.scaleSqrt = sqrt$1;\nexports.scaleQuantile = quantile$$1;\nexports.scaleQuantize = quantize$1;\nexports.scaleThreshold = threshold$1;\nexports.scaleTime = time;\nexports.scaleUtc = utcTime;\nexports.schemeCategory10 = category10;\nexports.schemeCategory20b = category20b;\nexports.schemeCategory20c = category20c;\nexports.schemeCategory20 = category20;\nexports.interpolateCubehelixDefault = cubehelix$3;\nexports.interpolateRainbow = rainbow$1;\nexports.interpolateWarm = warm;\nexports.interpolateCool = cool;\nexports.interpolateViridis = viridis;\nexports.interpolateMagma = magma;\nexports.interpolateInferno = inferno;\nexports.interpolatePlasma = plasma;\nexports.scaleSequential = sequential;\nexports.creator = creator;\nexports.local = local$1;\nexports.matcher = matcher$1;\nexports.mouse = mouse;\nexports.namespace = namespace;\nexports.namespaces = namespaces;\nexports.select = select;\nexports.selectAll = selectAll;\nexports.selection = selection;\nexports.selector = selector;\nexports.selectorAll = selectorAll;\nexports.style = styleValue;\nexports.touch = touch;\nexports.touches = touches;\nexports.window = defaultView;\nexports.customEvent = customEvent;\nexports.arc = arc;\nexports.area = area$2;\nexports.line = line;\nexports.pie = pie;\nexports.radialArea = radialArea;\nexports.radialLine = radialLine$1;\nexports.linkHorizontal = linkHorizontal;\nexports.linkVertical = linkVertical;\nexports.linkRadial = linkRadial;\nexports.symbol = symbol;\nexports.symbols = symbols;\nexports.symbolCircle = circle$2;\nexports.symbolCross = cross$2;\nexports.symbolDiamond = diamond;\nexports.symbolSquare = square;\nexports.symbolStar = star;\nexports.symbolTriangle = triangle;\nexports.symbolWye = wye;\nexports.curveBasisClosed = basisClosed$1;\nexports.curveBasisOpen = basisOpen;\nexports.curveBasis = basis$2;\nexports.curveBundle = bundle;\nexports.curveCardinalClosed = cardinalClosed;\nexports.curveCardinalOpen = cardinalOpen;\nexports.curveCardinal = cardinal;\nexports.curveCatmullRomClosed = catmullRomClosed;\nexports.curveCatmullRomOpen = catmullRomOpen;\nexports.curveCatmullRom = catmullRom;\nexports.curveLinearClosed = linearClosed;\nexports.curveLinear = curveLinear;\nexports.curveMonotoneX = monotoneX;\nexports.curveMonotoneY = monotoneY;\nexports.curveNatural = natural;\nexports.curveStep = step;\nexports.curveStepAfter = stepAfter;\nexports.curveStepBefore = stepBefore;\nexports.stack = stack;\nexports.stackOffsetExpand = expand;\nexports.stackOffsetDiverging = diverging;\nexports.stackOffsetNone = none$1;\nexports.stackOffsetSilhouette = silhouette;\nexports.stackOffsetWiggle = wiggle;\nexports.stackOrderAscending = ascending$2;\nexports.stackOrderDescending = descending$2;\nexports.stackOrderInsideOut = insideOut;\nexports.stackOrderNone = none$2;\nexports.stackOrderReverse = reverse;\nexports.timeInterval = newInterval;\nexports.timeMillisecond = millisecond;\nexports.timeMilliseconds = milliseconds;\nexports.utcMillisecond = millisecond;\nexports.utcMilliseconds = milliseconds;\nexports.timeSecond = second;\nexports.timeSeconds = seconds;\nexports.utcSecond = second;\nexports.utcSeconds = seconds;\nexports.timeMinute = minute;\nexports.timeMinutes = minutes;\nexports.timeHour = hour;\nexports.timeHours = hours;\nexports.timeDay = day;\nexports.timeDays = days;\nexports.timeWeek = sunday;\nexports.timeWeeks = sundays;\nexports.timeSunday = sunday;\nexports.timeSundays = sundays;\nexports.timeMonday = monday;\nexports.timeMondays = mondays;\nexports.timeTuesday = tuesday;\nexports.timeTuesdays = tuesdays;\nexports.timeWednesday = wednesday;\nexports.timeWednesdays = wednesdays;\nexports.timeThursday = thursday;\nexports.timeThursdays = thursdays;\nexports.timeFriday = friday;\nexports.timeFridays = fridays;\nexports.timeSaturday = saturday;\nexports.timeSaturdays = saturdays;\nexports.timeMonth = month;\nexports.timeMonths = months;\nexports.timeYear = year;\nexports.timeYears = years;\nexports.utcMinute = utcMinute;\nexports.utcMinutes = utcMinutes;\nexports.utcHour = utcHour;\nexports.utcHours = utcHours;\nexports.utcDay = utcDay;\nexports.utcDays = utcDays;\nexports.utcWeek = utcSunday;\nexports.utcWeeks = utcSundays;\nexports.utcSunday = utcSunday;\nexports.utcSundays = utcSundays;\nexports.utcMonday = utcMonday;\nexports.utcMondays = utcMondays;\nexports.utcTuesday = utcTuesday;\nexports.utcTuesdays = utcTuesdays;\nexports.utcWednesday = utcWednesday;\nexports.utcWednesdays = utcWednesdays;\nexports.utcThursday = utcThursday;\nexports.utcThursdays = utcThursdays;\nexports.utcFriday = utcFriday;\nexports.utcFridays = utcFridays;\nexports.utcSaturday = utcSaturday;\nexports.utcSaturdays = utcSaturdays;\nexports.utcMonth = utcMonth;\nexports.utcMonths = utcMonths;\nexports.utcYear = utcYear;\nexports.utcYears = utcYears;\nexports.timeFormatDefaultLocale = defaultLocale$1;\nexports.timeFormatLocale = formatLocale$1;\nexports.isoFormat = formatIso;\nexports.isoParse = parseIso;\nexports.now = now;\nexports.timer = timer;\nexports.timerFlush = timerFlush;\nexports.timeout = timeout$1;\nexports.interval = interval$1;\nexports.transition = transition;\nexports.active = active;\nexports.interrupt = interrupt;\nexports.voronoi = voronoi;\nexports.zoom = zoom;\nexports.zoomTransform = transform$1;\nexports.zoomIdentity = identity$8;\n\nObject.defineProperty(exports, '__esModule', { value: true });\n\n})));\n"
  },
  {
    "path": "app_backend/static/plugin/font-awesome/HELP-US-OUT.txt",
    "content": "I hope you love Font Awesome. If you've found it useful, please do me a favor and check out my latest project,\nFort Awesome (https://fortawesome.com). It makes it easy to put the perfect icons on your website. Choose from our awesome,\ncomprehensive icon sets or copy and paste your own.\n\nPlease. Check it out.\n\n-Dave Gandy\n"
  },
  {
    "path": "app_backend/static/plugin/font-awesome/css/font-awesome.css",
    "content": "/*!\n *  Font Awesome 4.6.3 by @davegandy - http://fontawesome.io - @fontawesome\n *  License - http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License)\n */\n/* FONT PATH\n * -------------------------- */\n@font-face {\n  font-family: 'FontAwesome';\n  src: url('../fonts/fontawesome-webfont.eot?v=4.6.3');\n  src: url('../fonts/fontawesome-webfont.eot?#iefix&v=4.6.3') format('embedded-opentype'), url('../fonts/fontawesome-webfont.woff2?v=4.6.3') format('woff2'), url('../fonts/fontawesome-webfont.woff?v=4.6.3') format('woff'), url('../fonts/fontawesome-webfont.ttf?v=4.6.3') format('truetype'), url('../fonts/fontawesome-webfont.svg?v=4.6.3#fontawesomeregular') format('svg');\n  font-weight: normal;\n  font-style: normal;\n}\n.fa {\n  display: inline-block;\n  font: normal normal normal 14px/1 FontAwesome;\n  font-size: inherit;\n  text-rendering: auto;\n  -webkit-font-smoothing: antialiased;\n  -moz-osx-font-smoothing: grayscale;\n}\n/* makes the font 33% larger relative to the icon container */\n.fa-lg {\n  font-size: 1.33333333em;\n  line-height: 0.75em;\n  vertical-align: -15%;\n}\n.fa-2x {\n  font-size: 2em;\n}\n.fa-3x {\n  font-size: 3em;\n}\n.fa-4x {\n  font-size: 4em;\n}\n.fa-5x {\n  font-size: 5em;\n}\n.fa-fw {\n  width: 1.28571429em;\n  text-align: center;\n}\n.fa-ul {\n  padding-left: 0;\n  margin-left: 2.14285714em;\n  list-style-type: none;\n}\n.fa-ul > li {\n  position: relative;\n}\n.fa-li {\n  position: absolute;\n  left: -2.14285714em;\n  width: 2.14285714em;\n  top: 0.14285714em;\n  text-align: center;\n}\n.fa-li.fa-lg {\n  left: -1.85714286em;\n}\n.fa-border {\n  padding: .2em .25em .15em;\n  border: solid 0.08em #eeeeee;\n  border-radius: .1em;\n}\n.fa-pull-left {\n  float: left;\n}\n.fa-pull-right {\n  float: right;\n}\n.fa.fa-pull-left {\n  margin-right: .3em;\n}\n.fa.fa-pull-right {\n  margin-left: .3em;\n}\n/* Deprecated as of 4.4.0 */\n.pull-right {\n  float: right;\n}\n.pull-left {\n  float: left;\n}\n.fa.pull-left {\n  margin-right: .3em;\n}\n.fa.pull-right {\n  margin-left: .3em;\n}\n.fa-spin {\n  -webkit-animation: fa-spin 2s infinite linear;\n  animation: fa-spin 2s infinite linear;\n}\n.fa-pulse {\n  -webkit-animation: fa-spin 1s infinite steps(8);\n  animation: fa-spin 1s infinite steps(8);\n}\n@-webkit-keyframes fa-spin {\n  0% {\n    -webkit-transform: rotate(0deg);\n    transform: rotate(0deg);\n  }\n  100% {\n    -webkit-transform: rotate(359deg);\n    transform: rotate(359deg);\n  }\n}\n@keyframes fa-spin {\n  0% {\n    -webkit-transform: rotate(0deg);\n    transform: rotate(0deg);\n  }\n  100% {\n    -webkit-transform: rotate(359deg);\n    transform: rotate(359deg);\n  }\n}\n.fa-rotate-90 {\n  -ms-filter: \"progid:DXImageTransform.Microsoft.BasicImage(rotation=1)\";\n  -webkit-transform: rotate(90deg);\n  -ms-transform: rotate(90deg);\n  transform: rotate(90deg);\n}\n.fa-rotate-180 {\n  -ms-filter: \"progid:DXImageTransform.Microsoft.BasicImage(rotation=2)\";\n  -webkit-transform: rotate(180deg);\n  -ms-transform: rotate(180deg);\n  transform: rotate(180deg);\n}\n.fa-rotate-270 {\n  -ms-filter: \"progid:DXImageTransform.Microsoft.BasicImage(rotation=3)\";\n  -webkit-transform: rotate(270deg);\n  -ms-transform: rotate(270deg);\n  transform: rotate(270deg);\n}\n.fa-flip-horizontal {\n  -ms-filter: \"progid:DXImageTransform.Microsoft.BasicImage(rotation=0, mirror=1)\";\n  -webkit-transform: scale(-1, 1);\n  -ms-transform: scale(-1, 1);\n  transform: scale(-1, 1);\n}\n.fa-flip-vertical {\n  -ms-filter: \"progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1)\";\n  -webkit-transform: scale(1, -1);\n  -ms-transform: scale(1, -1);\n  transform: scale(1, -1);\n}\n:root .fa-rotate-90,\n:root .fa-rotate-180,\n:root .fa-rotate-270,\n:root .fa-flip-horizontal,\n:root .fa-flip-vertical {\n  filter: none;\n}\n.fa-stack {\n  position: relative;\n  display: inline-block;\n  width: 2em;\n  height: 2em;\n  line-height: 2em;\n  vertical-align: middle;\n}\n.fa-stack-1x,\n.fa-stack-2x {\n  position: absolute;\n  left: 0;\n  width: 100%;\n  text-align: center;\n}\n.fa-stack-1x {\n  line-height: inherit;\n}\n.fa-stack-2x {\n  font-size: 2em;\n}\n.fa-inverse {\n  color: #ffffff;\n}\n/* Font Awesome uses the Unicode Private Use Area (PUA) to ensure screen\n   readers do not read off random characters that represent icons */\n.fa-glass:before {\n  content: \"\\f000\";\n}\n.fa-music:before {\n  content: \"\\f001\";\n}\n.fa-search:before {\n  content: \"\\f002\";\n}\n.fa-envelope-o:before {\n  content: \"\\f003\";\n}\n.fa-heart:before {\n  content: \"\\f004\";\n}\n.fa-star:before {\n  content: \"\\f005\";\n}\n.fa-star-o:before {\n  content: \"\\f006\";\n}\n.fa-user:before {\n  content: \"\\f007\";\n}\n.fa-film:before {\n  content: \"\\f008\";\n}\n.fa-th-large:before {\n  content: \"\\f009\";\n}\n.fa-th:before {\n  content: \"\\f00a\";\n}\n.fa-th-list:before {\n  content: \"\\f00b\";\n}\n.fa-check:before {\n  content: \"\\f00c\";\n}\n.fa-remove:before,\n.fa-close:before,\n.fa-times:before {\n  content: \"\\f00d\";\n}\n.fa-search-plus:before {\n  content: \"\\f00e\";\n}\n.fa-search-minus:before {\n  content: \"\\f010\";\n}\n.fa-power-off:before {\n  content: \"\\f011\";\n}\n.fa-signal:before {\n  content: \"\\f012\";\n}\n.fa-gear:before,\n.fa-cog:before {\n  content: \"\\f013\";\n}\n.fa-trash-o:before {\n  content: \"\\f014\";\n}\n.fa-home:before {\n  content: \"\\f015\";\n}\n.fa-file-o:before {\n  content: \"\\f016\";\n}\n.fa-clock-o:before {\n  content: \"\\f017\";\n}\n.fa-road:before {\n  content: \"\\f018\";\n}\n.fa-download:before {\n  content: \"\\f019\";\n}\n.fa-arrow-circle-o-down:before {\n  content: \"\\f01a\";\n}\n.fa-arrow-circle-o-up:before {\n  content: \"\\f01b\";\n}\n.fa-inbox:before {\n  content: \"\\f01c\";\n}\n.fa-play-circle-o:before {\n  content: \"\\f01d\";\n}\n.fa-rotate-right:before,\n.fa-repeat:before {\n  content: \"\\f01e\";\n}\n.fa-refresh:before {\n  content: \"\\f021\";\n}\n.fa-list-alt:before {\n  content: \"\\f022\";\n}\n.fa-lock:before {\n  content: \"\\f023\";\n}\n.fa-flag:before {\n  content: \"\\f024\";\n}\n.fa-headphones:before {\n  content: \"\\f025\";\n}\n.fa-volume-off:before {\n  content: \"\\f026\";\n}\n.fa-volume-down:before {\n  content: \"\\f027\";\n}\n.fa-volume-up:before {\n  content: \"\\f028\";\n}\n.fa-qrcode:before {\n  content: \"\\f029\";\n}\n.fa-barcode:before {\n  content: \"\\f02a\";\n}\n.fa-tag:before {\n  content: \"\\f02b\";\n}\n.fa-tags:before {\n  content: \"\\f02c\";\n}\n.fa-book:before {\n  content: \"\\f02d\";\n}\n.fa-bookmark:before {\n  content: \"\\f02e\";\n}\n.fa-print:before {\n  content: \"\\f02f\";\n}\n.fa-camera:before {\n  content: \"\\f030\";\n}\n.fa-font:before {\n  content: \"\\f031\";\n}\n.fa-bold:before {\n  content: \"\\f032\";\n}\n.fa-italic:before {\n  content: \"\\f033\";\n}\n.fa-text-height:before {\n  content: \"\\f034\";\n}\n.fa-text-width:before {\n  content: \"\\f035\";\n}\n.fa-align-left:before {\n  content: \"\\f036\";\n}\n.fa-align-center:before {\n  content: \"\\f037\";\n}\n.fa-align-right:before {\n  content: \"\\f038\";\n}\n.fa-align-justify:before {\n  content: \"\\f039\";\n}\n.fa-list:before {\n  content: \"\\f03a\";\n}\n.fa-dedent:before,\n.fa-outdent:before {\n  content: \"\\f03b\";\n}\n.fa-indent:before {\n  content: \"\\f03c\";\n}\n.fa-video-camera:before {\n  content: \"\\f03d\";\n}\n.fa-photo:before,\n.fa-image:before,\n.fa-picture-o:before {\n  content: \"\\f03e\";\n}\n.fa-pencil:before {\n  content: \"\\f040\";\n}\n.fa-map-marker:before {\n  content: \"\\f041\";\n}\n.fa-adjust:before {\n  content: \"\\f042\";\n}\n.fa-tint:before {\n  content: \"\\f043\";\n}\n.fa-edit:before,\n.fa-pencil-square-o:before {\n  content: \"\\f044\";\n}\n.fa-share-square-o:before {\n  content: \"\\f045\";\n}\n.fa-check-square-o:before {\n  content: \"\\f046\";\n}\n.fa-arrows:before {\n  content: \"\\f047\";\n}\n.fa-step-backward:before {\n  content: \"\\f048\";\n}\n.fa-fast-backward:before {\n  content: \"\\f049\";\n}\n.fa-backward:before {\n  content: \"\\f04a\";\n}\n.fa-play:before {\n  content: \"\\f04b\";\n}\n.fa-pause:before {\n  content: \"\\f04c\";\n}\n.fa-stop:before {\n  content: \"\\f04d\";\n}\n.fa-forward:before {\n  content: \"\\f04e\";\n}\n.fa-fast-forward:before {\n  content: \"\\f050\";\n}\n.fa-step-forward:before {\n  content: \"\\f051\";\n}\n.fa-eject:before {\n  content: \"\\f052\";\n}\n.fa-chevron-left:before {\n  content: \"\\f053\";\n}\n.fa-chevron-right:before {\n  content: \"\\f054\";\n}\n.fa-plus-circle:before {\n  content: \"\\f055\";\n}\n.fa-minus-circle:before {\n  content: \"\\f056\";\n}\n.fa-times-circle:before {\n  content: \"\\f057\";\n}\n.fa-check-circle:before {\n  content: \"\\f058\";\n}\n.fa-question-circle:before {\n  content: \"\\f059\";\n}\n.fa-info-circle:before {\n  content: \"\\f05a\";\n}\n.fa-crosshairs:before {\n  content: \"\\f05b\";\n}\n.fa-times-circle-o:before {\n  content: \"\\f05c\";\n}\n.fa-check-circle-o:before {\n  content: \"\\f05d\";\n}\n.fa-ban:before {\n  content: \"\\f05e\";\n}\n.fa-arrow-left:before {\n  content: \"\\f060\";\n}\n.fa-arrow-right:before {\n  content: \"\\f061\";\n}\n.fa-arrow-up:before {\n  content: \"\\f062\";\n}\n.fa-arrow-down:before {\n  content: \"\\f063\";\n}\n.fa-mail-forward:before,\n.fa-share:before {\n  content: \"\\f064\";\n}\n.fa-expand:before {\n  content: \"\\f065\";\n}\n.fa-compress:before {\n  content: \"\\f066\";\n}\n.fa-plus:before {\n  content: \"\\f067\";\n}\n.fa-minus:before {\n  content: \"\\f068\";\n}\n.fa-asterisk:before {\n  content: \"\\f069\";\n}\n.fa-exclamation-circle:before {\n  content: \"\\f06a\";\n}\n.fa-gift:before {\n  content: \"\\f06b\";\n}\n.fa-leaf:before {\n  content: \"\\f06c\";\n}\n.fa-fire:before {\n  content: \"\\f06d\";\n}\n.fa-eye:before {\n  content: \"\\f06e\";\n}\n.fa-eye-slash:before {\n  content: \"\\f070\";\n}\n.fa-warning:before,\n.fa-exclamation-triangle:before {\n  content: \"\\f071\";\n}\n.fa-plane:before {\n  content: \"\\f072\";\n}\n.fa-calendar:before {\n  content: \"\\f073\";\n}\n.fa-random:before {\n  content: \"\\f074\";\n}\n.fa-comment:before {\n  content: \"\\f075\";\n}\n.fa-magnet:before {\n  content: \"\\f076\";\n}\n.fa-chevron-up:before {\n  content: \"\\f077\";\n}\n.fa-chevron-down:before {\n  content: \"\\f078\";\n}\n.fa-retweet:before {\n  content: \"\\f079\";\n}\n.fa-shopping-cart:before {\n  content: \"\\f07a\";\n}\n.fa-folder:before {\n  content: \"\\f07b\";\n}\n.fa-folder-open:before {\n  content: \"\\f07c\";\n}\n.fa-arrows-v:before {\n  content: \"\\f07d\";\n}\n.fa-arrows-h:before {\n  content: \"\\f07e\";\n}\n.fa-bar-chart-o:before,\n.fa-bar-chart:before {\n  content: \"\\f080\";\n}\n.fa-twitter-square:before {\n  content: \"\\f081\";\n}\n.fa-facebook-square:before {\n  content: \"\\f082\";\n}\n.fa-camera-retro:before {\n  content: \"\\f083\";\n}\n.fa-key:before {\n  content: \"\\f084\";\n}\n.fa-gears:before,\n.fa-cogs:before {\n  content: \"\\f085\";\n}\n.fa-comments:before {\n  content: \"\\f086\";\n}\n.fa-thumbs-o-up:before {\n  content: \"\\f087\";\n}\n.fa-thumbs-o-down:before {\n  content: \"\\f088\";\n}\n.fa-star-half:before {\n  content: \"\\f089\";\n}\n.fa-heart-o:before {\n  content: \"\\f08a\";\n}\n.fa-sign-out:before {\n  content: \"\\f08b\";\n}\n.fa-linkedin-square:before {\n  content: \"\\f08c\";\n}\n.fa-thumb-tack:before {\n  content: \"\\f08d\";\n}\n.fa-external-link:before {\n  content: \"\\f08e\";\n}\n.fa-sign-in:before {\n  content: \"\\f090\";\n}\n.fa-trophy:before {\n  content: \"\\f091\";\n}\n.fa-github-square:before {\n  content: \"\\f092\";\n}\n.fa-upload:before {\n  content: \"\\f093\";\n}\n.fa-lemon-o:before {\n  content: \"\\f094\";\n}\n.fa-phone:before {\n  content: \"\\f095\";\n}\n.fa-square-o:before {\n  content: \"\\f096\";\n}\n.fa-bookmark-o:before {\n  content: \"\\f097\";\n}\n.fa-phone-square:before {\n  content: \"\\f098\";\n}\n.fa-twitter:before {\n  content: \"\\f099\";\n}\n.fa-facebook-f:before,\n.fa-facebook:before {\n  content: \"\\f09a\";\n}\n.fa-github:before {\n  content: \"\\f09b\";\n}\n.fa-unlock:before {\n  content: \"\\f09c\";\n}\n.fa-credit-card:before {\n  content: \"\\f09d\";\n}\n.fa-feed:before,\n.fa-rss:before {\n  content: \"\\f09e\";\n}\n.fa-hdd-o:before {\n  content: \"\\f0a0\";\n}\n.fa-bullhorn:before {\n  content: \"\\f0a1\";\n}\n.fa-bell:before {\n  content: \"\\f0f3\";\n}\n.fa-certificate:before {\n  content: \"\\f0a3\";\n}\n.fa-hand-o-right:before {\n  content: \"\\f0a4\";\n}\n.fa-hand-o-left:before {\n  content: \"\\f0a5\";\n}\n.fa-hand-o-up:before {\n  content: \"\\f0a6\";\n}\n.fa-hand-o-down:before {\n  content: \"\\f0a7\";\n}\n.fa-arrow-circle-left:before {\n  content: \"\\f0a8\";\n}\n.fa-arrow-circle-right:before {\n  content: \"\\f0a9\";\n}\n.fa-arrow-circle-up:before {\n  content: \"\\f0aa\";\n}\n.fa-arrow-circle-down:before {\n  content: \"\\f0ab\";\n}\n.fa-globe:before {\n  content: \"\\f0ac\";\n}\n.fa-wrench:before {\n  content: \"\\f0ad\";\n}\n.fa-tasks:before {\n  content: \"\\f0ae\";\n}\n.fa-filter:before {\n  content: \"\\f0b0\";\n}\n.fa-briefcase:before {\n  content: \"\\f0b1\";\n}\n.fa-arrows-alt:before {\n  content: \"\\f0b2\";\n}\n.fa-group:before,\n.fa-users:before {\n  content: \"\\f0c0\";\n}\n.fa-chain:before,\n.fa-link:before {\n  content: \"\\f0c1\";\n}\n.fa-cloud:before {\n  content: \"\\f0c2\";\n}\n.fa-flask:before {\n  content: \"\\f0c3\";\n}\n.fa-cut:before,\n.fa-scissors:before {\n  content: \"\\f0c4\";\n}\n.fa-copy:before,\n.fa-files-o:before {\n  content: \"\\f0c5\";\n}\n.fa-paperclip:before {\n  content: \"\\f0c6\";\n}\n.fa-save:before,\n.fa-floppy-o:before {\n  content: \"\\f0c7\";\n}\n.fa-square:before {\n  content: \"\\f0c8\";\n}\n.fa-navicon:before,\n.fa-reorder:before,\n.fa-bars:before {\n  content: \"\\f0c9\";\n}\n.fa-list-ul:before {\n  content: \"\\f0ca\";\n}\n.fa-list-ol:before {\n  content: \"\\f0cb\";\n}\n.fa-strikethrough:before {\n  content: \"\\f0cc\";\n}\n.fa-underline:before {\n  content: \"\\f0cd\";\n}\n.fa-table:before {\n  content: \"\\f0ce\";\n}\n.fa-magic:before {\n  content: \"\\f0d0\";\n}\n.fa-truck:before {\n  content: \"\\f0d1\";\n}\n.fa-pinterest:before {\n  content: \"\\f0d2\";\n}\n.fa-pinterest-square:before {\n  content: \"\\f0d3\";\n}\n.fa-google-plus-square:before {\n  content: \"\\f0d4\";\n}\n.fa-google-plus:before {\n  content: \"\\f0d5\";\n}\n.fa-money:before {\n  content: \"\\f0d6\";\n}\n.fa-caret-down:before {\n  content: \"\\f0d7\";\n}\n.fa-caret-up:before {\n  content: \"\\f0d8\";\n}\n.fa-caret-left:before {\n  content: \"\\f0d9\";\n}\n.fa-caret-right:before {\n  content: \"\\f0da\";\n}\n.fa-columns:before {\n  content: \"\\f0db\";\n}\n.fa-unsorted:before,\n.fa-sort:before {\n  content: \"\\f0dc\";\n}\n.fa-sort-down:before,\n.fa-sort-desc:before {\n  content: \"\\f0dd\";\n}\n.fa-sort-up:before,\n.fa-sort-asc:before {\n  content: \"\\f0de\";\n}\n.fa-envelope:before {\n  content: \"\\f0e0\";\n}\n.fa-linkedin:before {\n  content: \"\\f0e1\";\n}\n.fa-rotate-left:before,\n.fa-undo:before {\n  content: \"\\f0e2\";\n}\n.fa-legal:before,\n.fa-gavel:before {\n  content: \"\\f0e3\";\n}\n.fa-dashboard:before,\n.fa-tachometer:before {\n  content: \"\\f0e4\";\n}\n.fa-comment-o:before {\n  content: \"\\f0e5\";\n}\n.fa-comments-o:before {\n  content: \"\\f0e6\";\n}\n.fa-flash:before,\n.fa-bolt:before {\n  content: \"\\f0e7\";\n}\n.fa-sitemap:before {\n  content: \"\\f0e8\";\n}\n.fa-umbrella:before {\n  content: \"\\f0e9\";\n}\n.fa-paste:before,\n.fa-clipboard:before {\n  content: \"\\f0ea\";\n}\n.fa-lightbulb-o:before {\n  content: \"\\f0eb\";\n}\n.fa-exchange:before {\n  content: \"\\f0ec\";\n}\n.fa-cloud-download:before {\n  content: \"\\f0ed\";\n}\n.fa-cloud-upload:before {\n  content: \"\\f0ee\";\n}\n.fa-user-md:before {\n  content: \"\\f0f0\";\n}\n.fa-stethoscope:before {\n  content: \"\\f0f1\";\n}\n.fa-suitcase:before {\n  content: \"\\f0f2\";\n}\n.fa-bell-o:before {\n  content: \"\\f0a2\";\n}\n.fa-coffee:before {\n  content: \"\\f0f4\";\n}\n.fa-cutlery:before {\n  content: \"\\f0f5\";\n}\n.fa-file-text-o:before {\n  content: \"\\f0f6\";\n}\n.fa-building-o:before {\n  content: \"\\f0f7\";\n}\n.fa-hospital-o:before {\n  content: \"\\f0f8\";\n}\n.fa-ambulance:before {\n  content: \"\\f0f9\";\n}\n.fa-medkit:before {\n  content: \"\\f0fa\";\n}\n.fa-fighter-jet:before {\n  content: \"\\f0fb\";\n}\n.fa-beer:before {\n  content: \"\\f0fc\";\n}\n.fa-h-square:before {\n  content: \"\\f0fd\";\n}\n.fa-plus-square:before {\n  content: \"\\f0fe\";\n}\n.fa-angle-double-left:before {\n  content: \"\\f100\";\n}\n.fa-angle-double-right:before {\n  content: \"\\f101\";\n}\n.fa-angle-double-up:before {\n  content: \"\\f102\";\n}\n.fa-angle-double-down:before {\n  content: \"\\f103\";\n}\n.fa-angle-left:before {\n  content: \"\\f104\";\n}\n.fa-angle-right:before {\n  content: \"\\f105\";\n}\n.fa-angle-up:before {\n  content: \"\\f106\";\n}\n.fa-angle-down:before {\n  content: \"\\f107\";\n}\n.fa-desktop:before {\n  content: \"\\f108\";\n}\n.fa-laptop:before {\n  content: \"\\f109\";\n}\n.fa-tablet:before {\n  content: \"\\f10a\";\n}\n.fa-mobile-phone:before,\n.fa-mobile:before {\n  content: \"\\f10b\";\n}\n.fa-circle-o:before {\n  content: \"\\f10c\";\n}\n.fa-quote-left:before {\n  content: \"\\f10d\";\n}\n.fa-quote-right:before {\n  content: \"\\f10e\";\n}\n.fa-spinner:before {\n  content: \"\\f110\";\n}\n.fa-circle:before {\n  content: \"\\f111\";\n}\n.fa-mail-reply:before,\n.fa-reply:before {\n  content: \"\\f112\";\n}\n.fa-github-alt:before {\n  content: \"\\f113\";\n}\n.fa-folder-o:before {\n  content: \"\\f114\";\n}\n.fa-folder-open-o:before {\n  content: \"\\f115\";\n}\n.fa-smile-o:before {\n  content: \"\\f118\";\n}\n.fa-frown-o:before {\n  content: \"\\f119\";\n}\n.fa-meh-o:before {\n  content: \"\\f11a\";\n}\n.fa-gamepad:before {\n  content: \"\\f11b\";\n}\n.fa-keyboard-o:before {\n  content: \"\\f11c\";\n}\n.fa-flag-o:before {\n  content: \"\\f11d\";\n}\n.fa-flag-checkered:before {\n  content: \"\\f11e\";\n}\n.fa-terminal:before {\n  content: \"\\f120\";\n}\n.fa-code:before {\n  content: \"\\f121\";\n}\n.fa-mail-reply-all:before,\n.fa-reply-all:before {\n  content: \"\\f122\";\n}\n.fa-star-half-empty:before,\n.fa-star-half-full:before,\n.fa-star-half-o:before {\n  content: \"\\f123\";\n}\n.fa-location-arrow:before {\n  content: \"\\f124\";\n}\n.fa-crop:before {\n  content: \"\\f125\";\n}\n.fa-code-fork:before {\n  content: \"\\f126\";\n}\n.fa-unlink:before,\n.fa-chain-broken:before {\n  content: \"\\f127\";\n}\n.fa-question:before {\n  content: \"\\f128\";\n}\n.fa-info:before {\n  content: \"\\f129\";\n}\n.fa-exclamation:before {\n  content: \"\\f12a\";\n}\n.fa-superscript:before {\n  content: \"\\f12b\";\n}\n.fa-subscript:before {\n  content: \"\\f12c\";\n}\n.fa-eraser:before {\n  content: \"\\f12d\";\n}\n.fa-puzzle-piece:before {\n  content: \"\\f12e\";\n}\n.fa-microphone:before {\n  content: \"\\f130\";\n}\n.fa-microphone-slash:before {\n  content: \"\\f131\";\n}\n.fa-shield:before {\n  content: \"\\f132\";\n}\n.fa-calendar-o:before {\n  content: \"\\f133\";\n}\n.fa-fire-extinguisher:before {\n  content: \"\\f134\";\n}\n.fa-rocket:before {\n  content: \"\\f135\";\n}\n.fa-maxcdn:before {\n  content: \"\\f136\";\n}\n.fa-chevron-circle-left:before {\n  content: \"\\f137\";\n}\n.fa-chevron-circle-right:before {\n  content: \"\\f138\";\n}\n.fa-chevron-circle-up:before {\n  content: \"\\f139\";\n}\n.fa-chevron-circle-down:before {\n  content: \"\\f13a\";\n}\n.fa-html5:before {\n  content: \"\\f13b\";\n}\n.fa-css3:before {\n  content: \"\\f13c\";\n}\n.fa-anchor:before {\n  content: \"\\f13d\";\n}\n.fa-unlock-alt:before {\n  content: \"\\f13e\";\n}\n.fa-bullseye:before {\n  content: \"\\f140\";\n}\n.fa-ellipsis-h:before {\n  content: \"\\f141\";\n}\n.fa-ellipsis-v:before {\n  content: \"\\f142\";\n}\n.fa-rss-square:before {\n  content: \"\\f143\";\n}\n.fa-play-circle:before {\n  content: \"\\f144\";\n}\n.fa-ticket:before {\n  content: \"\\f145\";\n}\n.fa-minus-square:before {\n  content: \"\\f146\";\n}\n.fa-minus-square-o:before {\n  content: \"\\f147\";\n}\n.fa-level-up:before {\n  content: \"\\f148\";\n}\n.fa-level-down:before {\n  content: \"\\f149\";\n}\n.fa-check-square:before {\n  content: \"\\f14a\";\n}\n.fa-pencil-square:before {\n  content: \"\\f14b\";\n}\n.fa-external-link-square:before {\n  content: \"\\f14c\";\n}\n.fa-share-square:before {\n  content: \"\\f14d\";\n}\n.fa-compass:before {\n  content: \"\\f14e\";\n}\n.fa-toggle-down:before,\n.fa-caret-square-o-down:before {\n  content: \"\\f150\";\n}\n.fa-toggle-up:before,\n.fa-caret-square-o-up:before {\n  content: \"\\f151\";\n}\n.fa-toggle-right:before,\n.fa-caret-square-o-right:before {\n  content: \"\\f152\";\n}\n.fa-euro:before,\n.fa-eur:before {\n  content: \"\\f153\";\n}\n.fa-gbp:before {\n  content: \"\\f154\";\n}\n.fa-dollar:before,\n.fa-usd:before {\n  content: \"\\f155\";\n}\n.fa-rupee:before,\n.fa-inr:before {\n  content: \"\\f156\";\n}\n.fa-cny:before,\n.fa-rmb:before,\n.fa-yen:before,\n.fa-jpy:before {\n  content: \"\\f157\";\n}\n.fa-ruble:before,\n.fa-rouble:before,\n.fa-rub:before {\n  content: \"\\f158\";\n}\n.fa-won:before,\n.fa-krw:before {\n  content: \"\\f159\";\n}\n.fa-bitcoin:before,\n.fa-btc:before {\n  content: \"\\f15a\";\n}\n.fa-file:before {\n  content: \"\\f15b\";\n}\n.fa-file-text:before {\n  content: \"\\f15c\";\n}\n.fa-sort-alpha-asc:before {\n  content: \"\\f15d\";\n}\n.fa-sort-alpha-desc:before {\n  content: \"\\f15e\";\n}\n.fa-sort-amount-asc:before {\n  content: \"\\f160\";\n}\n.fa-sort-amount-desc:before {\n  content: \"\\f161\";\n}\n.fa-sort-numeric-asc:before {\n  content: \"\\f162\";\n}\n.fa-sort-numeric-desc:before {\n  content: \"\\f163\";\n}\n.fa-thumbs-up:before {\n  content: \"\\f164\";\n}\n.fa-thumbs-down:before {\n  content: \"\\f165\";\n}\n.fa-youtube-square:before {\n  content: \"\\f166\";\n}\n.fa-youtube:before {\n  content: \"\\f167\";\n}\n.fa-xing:before {\n  content: \"\\f168\";\n}\n.fa-xing-square:before {\n  content: \"\\f169\";\n}\n.fa-youtube-play:before {\n  content: \"\\f16a\";\n}\n.fa-dropbox:before {\n  content: \"\\f16b\";\n}\n.fa-stack-overflow:before {\n  content: \"\\f16c\";\n}\n.fa-instagram:before {\n  content: \"\\f16d\";\n}\n.fa-flickr:before {\n  content: \"\\f16e\";\n}\n.fa-adn:before {\n  content: \"\\f170\";\n}\n.fa-bitbucket:before {\n  content: \"\\f171\";\n}\n.fa-bitbucket-square:before {\n  content: \"\\f172\";\n}\n.fa-tumblr:before {\n  content: \"\\f173\";\n}\n.fa-tumblr-square:before {\n  content: \"\\f174\";\n}\n.fa-long-arrow-down:before {\n  content: \"\\f175\";\n}\n.fa-long-arrow-up:before {\n  content: \"\\f176\";\n}\n.fa-long-arrow-left:before {\n  content: \"\\f177\";\n}\n.fa-long-arrow-right:before {\n  content: \"\\f178\";\n}\n.fa-apple:before {\n  content: \"\\f179\";\n}\n.fa-windows:before {\n  content: \"\\f17a\";\n}\n.fa-android:before {\n  content: \"\\f17b\";\n}\n.fa-linux:before {\n  content: \"\\f17c\";\n}\n.fa-dribbble:before {\n  content: \"\\f17d\";\n}\n.fa-skype:before {\n  content: \"\\f17e\";\n}\n.fa-foursquare:before {\n  content: \"\\f180\";\n}\n.fa-trello:before {\n  content: \"\\f181\";\n}\n.fa-female:before {\n  content: \"\\f182\";\n}\n.fa-male:before {\n  content: \"\\f183\";\n}\n.fa-gittip:before,\n.fa-gratipay:before {\n  content: \"\\f184\";\n}\n.fa-sun-o:before {\n  content: \"\\f185\";\n}\n.fa-moon-o:before {\n  content: \"\\f186\";\n}\n.fa-archive:before {\n  content: \"\\f187\";\n}\n.fa-bug:before {\n  content: \"\\f188\";\n}\n.fa-vk:before {\n  content: \"\\f189\";\n}\n.fa-weibo:before {\n  content: \"\\f18a\";\n}\n.fa-renren:before {\n  content: \"\\f18b\";\n}\n.fa-pagelines:before {\n  content: \"\\f18c\";\n}\n.fa-stack-exchange:before {\n  content: \"\\f18d\";\n}\n.fa-arrow-circle-o-right:before {\n  content: \"\\f18e\";\n}\n.fa-arrow-circle-o-left:before {\n  content: \"\\f190\";\n}\n.fa-toggle-left:before,\n.fa-caret-square-o-left:before {\n  content: \"\\f191\";\n}\n.fa-dot-circle-o:before {\n  content: \"\\f192\";\n}\n.fa-wheelchair:before {\n  content: \"\\f193\";\n}\n.fa-vimeo-square:before {\n  content: \"\\f194\";\n}\n.fa-turkish-lira:before,\n.fa-try:before {\n  content: \"\\f195\";\n}\n.fa-plus-square-o:before {\n  content: \"\\f196\";\n}\n.fa-space-shuttle:before {\n  content: \"\\f197\";\n}\n.fa-slack:before {\n  content: \"\\f198\";\n}\n.fa-envelope-square:before {\n  content: \"\\f199\";\n}\n.fa-wordpress:before {\n  content: \"\\f19a\";\n}\n.fa-openid:before {\n  content: \"\\f19b\";\n}\n.fa-institution:before,\n.fa-bank:before,\n.fa-university:before {\n  content: \"\\f19c\";\n}\n.fa-mortar-board:before,\n.fa-graduation-cap:before {\n  content: \"\\f19d\";\n}\n.fa-yahoo:before {\n  content: \"\\f19e\";\n}\n.fa-google:before {\n  content: \"\\f1a0\";\n}\n.fa-reddit:before {\n  content: \"\\f1a1\";\n}\n.fa-reddit-square:before {\n  content: \"\\f1a2\";\n}\n.fa-stumbleupon-circle:before {\n  content: \"\\f1a3\";\n}\n.fa-stumbleupon:before {\n  content: \"\\f1a4\";\n}\n.fa-delicious:before {\n  content: \"\\f1a5\";\n}\n.fa-digg:before {\n  content: \"\\f1a6\";\n}\n.fa-pied-piper-pp:before {\n  content: \"\\f1a7\";\n}\n.fa-pied-piper-alt:before {\n  content: \"\\f1a8\";\n}\n.fa-drupal:before {\n  content: \"\\f1a9\";\n}\n.fa-joomla:before {\n  content: \"\\f1aa\";\n}\n.fa-language:before {\n  content: \"\\f1ab\";\n}\n.fa-fax:before {\n  content: \"\\f1ac\";\n}\n.fa-building:before {\n  content: \"\\f1ad\";\n}\n.fa-child:before {\n  content: \"\\f1ae\";\n}\n.fa-paw:before {\n  content: \"\\f1b0\";\n}\n.fa-spoon:before {\n  content: \"\\f1b1\";\n}\n.fa-cube:before {\n  content: \"\\f1b2\";\n}\n.fa-cubes:before {\n  content: \"\\f1b3\";\n}\n.fa-behance:before {\n  content: \"\\f1b4\";\n}\n.fa-behance-square:before {\n  content: \"\\f1b5\";\n}\n.fa-steam:before {\n  content: \"\\f1b6\";\n}\n.fa-steam-square:before {\n  content: \"\\f1b7\";\n}\n.fa-recycle:before {\n  content: \"\\f1b8\";\n}\n.fa-automobile:before,\n.fa-car:before {\n  content: \"\\f1b9\";\n}\n.fa-cab:before,\n.fa-taxi:before {\n  content: \"\\f1ba\";\n}\n.fa-tree:before {\n  content: \"\\f1bb\";\n}\n.fa-spotify:before {\n  content: \"\\f1bc\";\n}\n.fa-deviantart:before {\n  content: \"\\f1bd\";\n}\n.fa-soundcloud:before {\n  content: \"\\f1be\";\n}\n.fa-database:before {\n  content: \"\\f1c0\";\n}\n.fa-file-pdf-o:before {\n  content: \"\\f1c1\";\n}\n.fa-file-word-o:before {\n  content: \"\\f1c2\";\n}\n.fa-file-excel-o:before {\n  content: \"\\f1c3\";\n}\n.fa-file-powerpoint-o:before {\n  content: \"\\f1c4\";\n}\n.fa-file-photo-o:before,\n.fa-file-picture-o:before,\n.fa-file-image-o:before {\n  content: \"\\f1c5\";\n}\n.fa-file-zip-o:before,\n.fa-file-archive-o:before {\n  content: \"\\f1c6\";\n}\n.fa-file-sound-o:before,\n.fa-file-audio-o:before {\n  content: \"\\f1c7\";\n}\n.fa-file-movie-o:before,\n.fa-file-video-o:before {\n  content: \"\\f1c8\";\n}\n.fa-file-code-o:before {\n  content: \"\\f1c9\";\n}\n.fa-vine:before {\n  content: \"\\f1ca\";\n}\n.fa-codepen:before {\n  content: \"\\f1cb\";\n}\n.fa-jsfiddle:before {\n  content: \"\\f1cc\";\n}\n.fa-life-bouy:before,\n.fa-life-buoy:before,\n.fa-life-saver:before,\n.fa-support:before,\n.fa-life-ring:before {\n  content: \"\\f1cd\";\n}\n.fa-circle-o-notch:before {\n  content: \"\\f1ce\";\n}\n.fa-ra:before,\n.fa-resistance:before,\n.fa-rebel:before {\n  content: \"\\f1d0\";\n}\n.fa-ge:before,\n.fa-empire:before {\n  content: \"\\f1d1\";\n}\n.fa-git-square:before {\n  content: \"\\f1d2\";\n}\n.fa-git:before {\n  content: \"\\f1d3\";\n}\n.fa-y-combinator-square:before,\n.fa-yc-square:before,\n.fa-hacker-news:before {\n  content: \"\\f1d4\";\n}\n.fa-tencent-weibo:before {\n  content: \"\\f1d5\";\n}\n.fa-qq:before {\n  content: \"\\f1d6\";\n}\n.fa-wechat:before,\n.fa-weixin:before {\n  content: \"\\f1d7\";\n}\n.fa-send:before,\n.fa-paper-plane:before {\n  content: \"\\f1d8\";\n}\n.fa-send-o:before,\n.fa-paper-plane-o:before {\n  content: \"\\f1d9\";\n}\n.fa-history:before {\n  content: \"\\f1da\";\n}\n.fa-circle-thin:before {\n  content: \"\\f1db\";\n}\n.fa-header:before {\n  content: \"\\f1dc\";\n}\n.fa-paragraph:before {\n  content: \"\\f1dd\";\n}\n.fa-sliders:before {\n  content: \"\\f1de\";\n}\n.fa-share-alt:before {\n  content: \"\\f1e0\";\n}\n.fa-share-alt-square:before {\n  content: \"\\f1e1\";\n}\n.fa-bomb:before {\n  content: \"\\f1e2\";\n}\n.fa-soccer-ball-o:before,\n.fa-futbol-o:before {\n  content: \"\\f1e3\";\n}\n.fa-tty:before {\n  content: \"\\f1e4\";\n}\n.fa-binoculars:before {\n  content: \"\\f1e5\";\n}\n.fa-plug:before {\n  content: \"\\f1e6\";\n}\n.fa-slideshare:before {\n  content: \"\\f1e7\";\n}\n.fa-twitch:before {\n  content: \"\\f1e8\";\n}\n.fa-yelp:before {\n  content: \"\\f1e9\";\n}\n.fa-newspaper-o:before {\n  content: \"\\f1ea\";\n}\n.fa-wifi:before {\n  content: \"\\f1eb\";\n}\n.fa-calculator:before {\n  content: \"\\f1ec\";\n}\n.fa-paypal:before {\n  content: \"\\f1ed\";\n}\n.fa-google-wallet:before {\n  content: \"\\f1ee\";\n}\n.fa-cc-visa:before {\n  content: \"\\f1f0\";\n}\n.fa-cc-mastercard:before {\n  content: \"\\f1f1\";\n}\n.fa-cc-discover:before {\n  content: \"\\f1f2\";\n}\n.fa-cc-amex:before {\n  content: \"\\f1f3\";\n}\n.fa-cc-paypal:before {\n  content: \"\\f1f4\";\n}\n.fa-cc-stripe:before {\n  content: \"\\f1f5\";\n}\n.fa-bell-slash:before {\n  content: \"\\f1f6\";\n}\n.fa-bell-slash-o:before {\n  content: \"\\f1f7\";\n}\n.fa-trash:before {\n  content: \"\\f1f8\";\n}\n.fa-copyright:before {\n  content: \"\\f1f9\";\n}\n.fa-at:before {\n  content: \"\\f1fa\";\n}\n.fa-eyedropper:before {\n  content: \"\\f1fb\";\n}\n.fa-paint-brush:before {\n  content: \"\\f1fc\";\n}\n.fa-birthday-cake:before {\n  content: \"\\f1fd\";\n}\n.fa-area-chart:before {\n  content: \"\\f1fe\";\n}\n.fa-pie-chart:before {\n  content: \"\\f200\";\n}\n.fa-line-chart:before {\n  content: \"\\f201\";\n}\n.fa-lastfm:before {\n  content: \"\\f202\";\n}\n.fa-lastfm-square:before {\n  content: \"\\f203\";\n}\n.fa-toggle-off:before {\n  content: \"\\f204\";\n}\n.fa-toggle-on:before {\n  content: \"\\f205\";\n}\n.fa-bicycle:before {\n  content: \"\\f206\";\n}\n.fa-bus:before {\n  content: \"\\f207\";\n}\n.fa-ioxhost:before {\n  content: \"\\f208\";\n}\n.fa-angellist:before {\n  content: \"\\f209\";\n}\n.fa-cc:before {\n  content: \"\\f20a\";\n}\n.fa-shekel:before,\n.fa-sheqel:before,\n.fa-ils:before {\n  content: \"\\f20b\";\n}\n.fa-meanpath:before {\n  content: \"\\f20c\";\n}\n.fa-buysellads:before {\n  content: \"\\f20d\";\n}\n.fa-connectdevelop:before {\n  content: \"\\f20e\";\n}\n.fa-dashcube:before {\n  content: \"\\f210\";\n}\n.fa-forumbee:before {\n  content: \"\\f211\";\n}\n.fa-leanpub:before {\n  content: \"\\f212\";\n}\n.fa-sellsy:before {\n  content: \"\\f213\";\n}\n.fa-shirtsinbulk:before {\n  content: \"\\f214\";\n}\n.fa-simplybuilt:before {\n  content: \"\\f215\";\n}\n.fa-skyatlas:before {\n  content: \"\\f216\";\n}\n.fa-cart-plus:before {\n  content: \"\\f217\";\n}\n.fa-cart-arrow-down:before {\n  content: \"\\f218\";\n}\n.fa-diamond:before {\n  content: \"\\f219\";\n}\n.fa-ship:before {\n  content: \"\\f21a\";\n}\n.fa-user-secret:before {\n  content: \"\\f21b\";\n}\n.fa-motorcycle:before {\n  content: \"\\f21c\";\n}\n.fa-street-view:before {\n  content: \"\\f21d\";\n}\n.fa-heartbeat:before {\n  content: \"\\f21e\";\n}\n.fa-venus:before {\n  content: \"\\f221\";\n}\n.fa-mars:before {\n  content: \"\\f222\";\n}\n.fa-mercury:before {\n  content: \"\\f223\";\n}\n.fa-intersex:before,\n.fa-transgender:before {\n  content: \"\\f224\";\n}\n.fa-transgender-alt:before {\n  content: \"\\f225\";\n}\n.fa-venus-double:before {\n  content: \"\\f226\";\n}\n.fa-mars-double:before {\n  content: \"\\f227\";\n}\n.fa-venus-mars:before {\n  content: \"\\f228\";\n}\n.fa-mars-stroke:before {\n  content: \"\\f229\";\n}\n.fa-mars-stroke-v:before {\n  content: \"\\f22a\";\n}\n.fa-mars-stroke-h:before {\n  content: \"\\f22b\";\n}\n.fa-neuter:before {\n  content: \"\\f22c\";\n}\n.fa-genderless:before {\n  content: \"\\f22d\";\n}\n.fa-facebook-official:before {\n  content: \"\\f230\";\n}\n.fa-pinterest-p:before {\n  content: \"\\f231\";\n}\n.fa-whatsapp:before {\n  content: \"\\f232\";\n}\n.fa-server:before {\n  content: \"\\f233\";\n}\n.fa-user-plus:before {\n  content: \"\\f234\";\n}\n.fa-user-times:before {\n  content: \"\\f235\";\n}\n.fa-hotel:before,\n.fa-bed:before {\n  content: \"\\f236\";\n}\n.fa-viacoin:before {\n  content: \"\\f237\";\n}\n.fa-train:before {\n  content: \"\\f238\";\n}\n.fa-subway:before {\n  content: \"\\f239\";\n}\n.fa-medium:before {\n  content: \"\\f23a\";\n}\n.fa-yc:before,\n.fa-y-combinator:before {\n  content: \"\\f23b\";\n}\n.fa-optin-monster:before {\n  content: \"\\f23c\";\n}\n.fa-opencart:before {\n  content: \"\\f23d\";\n}\n.fa-expeditedssl:before {\n  content: \"\\f23e\";\n}\n.fa-battery-4:before,\n.fa-battery-full:before {\n  content: \"\\f240\";\n}\n.fa-battery-3:before,\n.fa-battery-three-quarters:before {\n  content: \"\\f241\";\n}\n.fa-battery-2:before,\n.fa-battery-half:before {\n  content: \"\\f242\";\n}\n.fa-battery-1:before,\n.fa-battery-quarter:before {\n  content: \"\\f243\";\n}\n.fa-battery-0:before,\n.fa-battery-empty:before {\n  content: \"\\f244\";\n}\n.fa-mouse-pointer:before {\n  content: \"\\f245\";\n}\n.fa-i-cursor:before {\n  content: \"\\f246\";\n}\n.fa-object-group:before {\n  content: \"\\f247\";\n}\n.fa-object-ungroup:before {\n  content: \"\\f248\";\n}\n.fa-sticky-note:before {\n  content: \"\\f249\";\n}\n.fa-sticky-note-o:before {\n  content: \"\\f24a\";\n}\n.fa-cc-jcb:before {\n  content: \"\\f24b\";\n}\n.fa-cc-diners-club:before {\n  content: \"\\f24c\";\n}\n.fa-clone:before {\n  content: \"\\f24d\";\n}\n.fa-balance-scale:before {\n  content: \"\\f24e\";\n}\n.fa-hourglass-o:before {\n  content: \"\\f250\";\n}\n.fa-hourglass-1:before,\n.fa-hourglass-start:before {\n  content: \"\\f251\";\n}\n.fa-hourglass-2:before,\n.fa-hourglass-half:before {\n  content: \"\\f252\";\n}\n.fa-hourglass-3:before,\n.fa-hourglass-end:before {\n  content: \"\\f253\";\n}\n.fa-hourglass:before {\n  content: \"\\f254\";\n}\n.fa-hand-grab-o:before,\n.fa-hand-rock-o:before {\n  content: \"\\f255\";\n}\n.fa-hand-stop-o:before,\n.fa-hand-paper-o:before {\n  content: \"\\f256\";\n}\n.fa-hand-scissors-o:before {\n  content: \"\\f257\";\n}\n.fa-hand-lizard-o:before {\n  content: \"\\f258\";\n}\n.fa-hand-spock-o:before {\n  content: \"\\f259\";\n}\n.fa-hand-pointer-o:before {\n  content: \"\\f25a\";\n}\n.fa-hand-peace-o:before {\n  content: \"\\f25b\";\n}\n.fa-trademark:before {\n  content: \"\\f25c\";\n}\n.fa-registered:before {\n  content: \"\\f25d\";\n}\n.fa-creative-commons:before {\n  content: \"\\f25e\";\n}\n.fa-gg:before {\n  content: \"\\f260\";\n}\n.fa-gg-circle:before {\n  content: \"\\f261\";\n}\n.fa-tripadvisor:before {\n  content: \"\\f262\";\n}\n.fa-odnoklassniki:before {\n  content: \"\\f263\";\n}\n.fa-odnoklassniki-square:before {\n  content: \"\\f264\";\n}\n.fa-get-pocket:before {\n  content: \"\\f265\";\n}\n.fa-wikipedia-w:before {\n  content: \"\\f266\";\n}\n.fa-safari:before {\n  content: \"\\f267\";\n}\n.fa-chrome:before {\n  content: \"\\f268\";\n}\n.fa-firefox:before {\n  content: \"\\f269\";\n}\n.fa-opera:before {\n  content: \"\\f26a\";\n}\n.fa-internet-explorer:before {\n  content: \"\\f26b\";\n}\n.fa-tv:before,\n.fa-television:before {\n  content: \"\\f26c\";\n}\n.fa-contao:before {\n  content: \"\\f26d\";\n}\n.fa-500px:before {\n  content: \"\\f26e\";\n}\n.fa-amazon:before {\n  content: \"\\f270\";\n}\n.fa-calendar-plus-o:before {\n  content: \"\\f271\";\n}\n.fa-calendar-minus-o:before {\n  content: \"\\f272\";\n}\n.fa-calendar-times-o:before {\n  content: \"\\f273\";\n}\n.fa-calendar-check-o:before {\n  content: \"\\f274\";\n}\n.fa-industry:before {\n  content: \"\\f275\";\n}\n.fa-map-pin:before {\n  content: \"\\f276\";\n}\n.fa-map-signs:before {\n  content: \"\\f277\";\n}\n.fa-map-o:before {\n  content: \"\\f278\";\n}\n.fa-map:before {\n  content: \"\\f279\";\n}\n.fa-commenting:before {\n  content: \"\\f27a\";\n}\n.fa-commenting-o:before {\n  content: \"\\f27b\";\n}\n.fa-houzz:before {\n  content: \"\\f27c\";\n}\n.fa-vimeo:before {\n  content: \"\\f27d\";\n}\n.fa-black-tie:before {\n  content: \"\\f27e\";\n}\n.fa-fonticons:before {\n  content: \"\\f280\";\n}\n.fa-reddit-alien:before {\n  content: \"\\f281\";\n}\n.fa-edge:before {\n  content: \"\\f282\";\n}\n.fa-credit-card-alt:before {\n  content: \"\\f283\";\n}\n.fa-codiepie:before {\n  content: \"\\f284\";\n}\n.fa-modx:before {\n  content: \"\\f285\";\n}\n.fa-fort-awesome:before {\n  content: \"\\f286\";\n}\n.fa-usb:before {\n  content: \"\\f287\";\n}\n.fa-product-hunt:before {\n  content: \"\\f288\";\n}\n.fa-mixcloud:before {\n  content: \"\\f289\";\n}\n.fa-scribd:before {\n  content: \"\\f28a\";\n}\n.fa-pause-circle:before {\n  content: \"\\f28b\";\n}\n.fa-pause-circle-o:before {\n  content: \"\\f28c\";\n}\n.fa-stop-circle:before {\n  content: \"\\f28d\";\n}\n.fa-stop-circle-o:before {\n  content: \"\\f28e\";\n}\n.fa-shopping-bag:before {\n  content: \"\\f290\";\n}\n.fa-shopping-basket:before {\n  content: \"\\f291\";\n}\n.fa-hashtag:before {\n  content: \"\\f292\";\n}\n.fa-bluetooth:before {\n  content: \"\\f293\";\n}\n.fa-bluetooth-b:before {\n  content: \"\\f294\";\n}\n.fa-percent:before {\n  content: \"\\f295\";\n}\n.fa-gitlab:before {\n  content: \"\\f296\";\n}\n.fa-wpbeginner:before {\n  content: \"\\f297\";\n}\n.fa-wpforms:before {\n  content: \"\\f298\";\n}\n.fa-envira:before {\n  content: \"\\f299\";\n}\n.fa-universal-access:before {\n  content: \"\\f29a\";\n}\n.fa-wheelchair-alt:before {\n  content: \"\\f29b\";\n}\n.fa-question-circle-o:before {\n  content: \"\\f29c\";\n}\n.fa-blind:before {\n  content: \"\\f29d\";\n}\n.fa-audio-description:before {\n  content: \"\\f29e\";\n}\n.fa-volume-control-phone:before {\n  content: \"\\f2a0\";\n}\n.fa-braille:before {\n  content: \"\\f2a1\";\n}\n.fa-assistive-listening-systems:before {\n  content: \"\\f2a2\";\n}\n.fa-asl-interpreting:before,\n.fa-american-sign-language-interpreting:before {\n  content: \"\\f2a3\";\n}\n.fa-deafness:before,\n.fa-hard-of-hearing:before,\n.fa-deaf:before {\n  content: \"\\f2a4\";\n}\n.fa-glide:before {\n  content: \"\\f2a5\";\n}\n.fa-glide-g:before {\n  content: \"\\f2a6\";\n}\n.fa-signing:before,\n.fa-sign-language:before {\n  content: \"\\f2a7\";\n}\n.fa-low-vision:before {\n  content: \"\\f2a8\";\n}\n.fa-viadeo:before {\n  content: \"\\f2a9\";\n}\n.fa-viadeo-square:before {\n  content: \"\\f2aa\";\n}\n.fa-snapchat:before {\n  content: \"\\f2ab\";\n}\n.fa-snapchat-ghost:before {\n  content: \"\\f2ac\";\n}\n.fa-snapchat-square:before {\n  content: \"\\f2ad\";\n}\n.fa-pied-piper:before {\n  content: \"\\f2ae\";\n}\n.fa-first-order:before {\n  content: \"\\f2b0\";\n}\n.fa-yoast:before {\n  content: \"\\f2b1\";\n}\n.fa-themeisle:before {\n  content: \"\\f2b2\";\n}\n.fa-google-plus-circle:before,\n.fa-google-plus-official:before {\n  content: \"\\f2b3\";\n}\n.fa-fa:before,\n.fa-font-awesome:before {\n  content: \"\\f2b4\";\n}\n.sr-only {\n  position: absolute;\n  width: 1px;\n  height: 1px;\n  padding: 0;\n  margin: -1px;\n  overflow: hidden;\n  clip: rect(0, 0, 0, 0);\n  border: 0;\n}\n.sr-only-focusable:active,\n.sr-only-focusable:focus {\n  position: static;\n  width: auto;\n  height: auto;\n  margin: 0;\n  overflow: visible;\n  clip: auto;\n}\n"
  },
  {
    "path": "app_backend/static/plugin/font-awesome/less/animated.less",
    "content": "// Animated Icons\n// --------------------------\n\n.@{fa-css-prefix}-spin {\n  -webkit-animation: fa-spin 2s infinite linear;\n          animation: fa-spin 2s infinite linear;\n}\n\n.@{fa-css-prefix}-pulse {\n  -webkit-animation: fa-spin 1s infinite steps(8);\n          animation: fa-spin 1s infinite steps(8);\n}\n\n@-webkit-keyframes fa-spin {\n  0% {\n    -webkit-transform: rotate(0deg);\n            transform: rotate(0deg);\n  }\n  100% {\n    -webkit-transform: rotate(359deg);\n            transform: rotate(359deg);\n  }\n}\n\n@keyframes fa-spin {\n  0% {\n    -webkit-transform: rotate(0deg);\n            transform: rotate(0deg);\n  }\n  100% {\n    -webkit-transform: rotate(359deg);\n            transform: rotate(359deg);\n  }\n}\n"
  },
  {
    "path": "app_backend/static/plugin/font-awesome/less/bordered-pulled.less",
    "content": "// Bordered & Pulled\n// -------------------------\n\n.@{fa-css-prefix}-border {\n  padding: .2em .25em .15em;\n  border: solid .08em @fa-border-color;\n  border-radius: .1em;\n}\n\n.@{fa-css-prefix}-pull-left { float: left; }\n.@{fa-css-prefix}-pull-right { float: right; }\n\n.@{fa-css-prefix} {\n  &.@{fa-css-prefix}-pull-left { margin-right: .3em; }\n  &.@{fa-css-prefix}-pull-right { margin-left: .3em; }\n}\n\n/* Deprecated as of 4.4.0 */\n.pull-right { float: right; }\n.pull-left { float: left; }\n\n.@{fa-css-prefix} {\n  &.pull-left { margin-right: .3em; }\n  &.pull-right { margin-left: .3em; }\n}\n"
  },
  {
    "path": "app_backend/static/plugin/font-awesome/less/core.less",
    "content": "// Base Class Definition\n// -------------------------\n\n.@{fa-css-prefix} {\n  display: inline-block;\n  font: normal normal normal @fa-font-size-base/@fa-line-height-base FontAwesome; // shortening font declaration\n  font-size: inherit; // can't have font-size inherit on line above, so need to override\n  text-rendering: auto; // optimizelegibility throws things off #1094\n  -webkit-font-smoothing: antialiased;\n  -moz-osx-font-smoothing: grayscale;\n\n}\n"
  },
  {
    "path": "app_backend/static/plugin/font-awesome/less/extras.less",
    "content": "// Extras\n// --------------------------\n"
  },
  {
    "path": "app_backend/static/plugin/font-awesome/less/fixed-width.less",
    "content": "// Fixed Width Icons\n// -------------------------\n.@{fa-css-prefix}-fw {\n  width: (18em / 14);\n  text-align: center;\n}\n"
  },
  {
    "path": "app_backend/static/plugin/font-awesome/less/font-awesome.less",
    "content": "/*!\n *  Font Awesome 4.6.3 by @davegandy - http://fontawesome.io - @fontawesome\n *  License - http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License)\n */\n\n@import \"variables.less\";\n@import \"mixins.less\";\n@import \"path.less\";\n@import \"core.less\";\n@import \"larger.less\";\n@import \"fixed-width.less\";\n@import \"list.less\";\n@import \"bordered-pulled.less\";\n@import \"animated.less\";\n@import \"rotated-flipped.less\";\n@import \"stacked.less\";\n@import \"icons.less\";\n@import \"screen-reader.less\";\n"
  },
  {
    "path": "app_backend/static/plugin/font-awesome/less/icons.less",
    "content": "/* Font Awesome uses the Unicode Private Use Area (PUA) to ensure screen\n   readers do not read off random characters that represent icons */\n\n.@{fa-css-prefix}-glass:before { content: @fa-var-glass; }\n.@{fa-css-prefix}-music:before { content: @fa-var-music; }\n.@{fa-css-prefix}-search:before { content: @fa-var-search; }\n.@{fa-css-prefix}-envelope-o:before { content: @fa-var-envelope-o; }\n.@{fa-css-prefix}-heart:before { content: @fa-var-heart; }\n.@{fa-css-prefix}-star:before { content: @fa-var-star; }\n.@{fa-css-prefix}-star-o:before { content: @fa-var-star-o; }\n.@{fa-css-prefix}-user:before { content: @fa-var-user; }\n.@{fa-css-prefix}-film:before { content: @fa-var-film; }\n.@{fa-css-prefix}-th-large:before { content: @fa-var-th-large; }\n.@{fa-css-prefix}-th:before { content: @fa-var-th; }\n.@{fa-css-prefix}-th-list:before { content: @fa-var-th-list; }\n.@{fa-css-prefix}-check:before { content: @fa-var-check; }\n.@{fa-css-prefix}-remove:before,\n.@{fa-css-prefix}-close:before,\n.@{fa-css-prefix}-times:before { content: @fa-var-times; }\n.@{fa-css-prefix}-search-plus:before { content: @fa-var-search-plus; }\n.@{fa-css-prefix}-search-minus:before { content: @fa-var-search-minus; }\n.@{fa-css-prefix}-power-off:before { content: @fa-var-power-off; }\n.@{fa-css-prefix}-signal:before { content: @fa-var-signal; }\n.@{fa-css-prefix}-gear:before,\n.@{fa-css-prefix}-cog:before { content: @fa-var-cog; }\n.@{fa-css-prefix}-trash-o:before { content: @fa-var-trash-o; }\n.@{fa-css-prefix}-home:before { content: @fa-var-home; }\n.@{fa-css-prefix}-file-o:before { content: @fa-var-file-o; }\n.@{fa-css-prefix}-clock-o:before { content: @fa-var-clock-o; }\n.@{fa-css-prefix}-road:before { content: @fa-var-road; }\n.@{fa-css-prefix}-download:before { content: @fa-var-download; }\n.@{fa-css-prefix}-arrow-circle-o-down:before { content: @fa-var-arrow-circle-o-down; }\n.@{fa-css-prefix}-arrow-circle-o-up:before { content: @fa-var-arrow-circle-o-up; }\n.@{fa-css-prefix}-inbox:before { content: @fa-var-inbox; }\n.@{fa-css-prefix}-play-circle-o:before { content: @fa-var-play-circle-o; }\n.@{fa-css-prefix}-rotate-right:before,\n.@{fa-css-prefix}-repeat:before { content: @fa-var-repeat; }\n.@{fa-css-prefix}-refresh:before { content: @fa-var-refresh; }\n.@{fa-css-prefix}-list-alt:before { content: @fa-var-list-alt; }\n.@{fa-css-prefix}-lock:before { content: @fa-var-lock; }\n.@{fa-css-prefix}-flag:before { content: @fa-var-flag; }\n.@{fa-css-prefix}-headphones:before { content: @fa-var-headphones; }\n.@{fa-css-prefix}-volume-off:before { content: @fa-var-volume-off; }\n.@{fa-css-prefix}-volume-down:before { content: @fa-var-volume-down; }\n.@{fa-css-prefix}-volume-up:before { content: @fa-var-volume-up; }\n.@{fa-css-prefix}-qrcode:before { content: @fa-var-qrcode; }\n.@{fa-css-prefix}-barcode:before { content: @fa-var-barcode; }\n.@{fa-css-prefix}-tag:before { content: @fa-var-tag; }\n.@{fa-css-prefix}-tags:before { content: @fa-var-tags; }\n.@{fa-css-prefix}-book:before { content: @fa-var-book; }\n.@{fa-css-prefix}-bookmark:before { content: @fa-var-bookmark; }\n.@{fa-css-prefix}-print:before { content: @fa-var-print; }\n.@{fa-css-prefix}-camera:before { content: @fa-var-camera; }\n.@{fa-css-prefix}-font:before { content: @fa-var-font; }\n.@{fa-css-prefix}-bold:before { content: @fa-var-bold; }\n.@{fa-css-prefix}-italic:before { content: @fa-var-italic; }\n.@{fa-css-prefix}-text-height:before { content: @fa-var-text-height; }\n.@{fa-css-prefix}-text-width:before { content: @fa-var-text-width; }\n.@{fa-css-prefix}-align-left:before { content: @fa-var-align-left; }\n.@{fa-css-prefix}-align-center:before { content: @fa-var-align-center; }\n.@{fa-css-prefix}-align-right:before { content: @fa-var-align-right; }\n.@{fa-css-prefix}-align-justify:before { content: @fa-var-align-justify; }\n.@{fa-css-prefix}-list:before { content: @fa-var-list; }\n.@{fa-css-prefix}-dedent:before,\n.@{fa-css-prefix}-outdent:before { content: @fa-var-outdent; }\n.@{fa-css-prefix}-indent:before { content: @fa-var-indent; }\n.@{fa-css-prefix}-video-camera:before { content: @fa-var-video-camera; }\n.@{fa-css-prefix}-photo:before,\n.@{fa-css-prefix}-image:before,\n.@{fa-css-prefix}-picture-o:before { content: @fa-var-picture-o; }\n.@{fa-css-prefix}-pencil:before { content: @fa-var-pencil; }\n.@{fa-css-prefix}-map-marker:before { content: @fa-var-map-marker; }\n.@{fa-css-prefix}-adjust:before { content: @fa-var-adjust; }\n.@{fa-css-prefix}-tint:before { content: @fa-var-tint; }\n.@{fa-css-prefix}-edit:before,\n.@{fa-css-prefix}-pencil-square-o:before { content: @fa-var-pencil-square-o; }\n.@{fa-css-prefix}-share-square-o:before { content: @fa-var-share-square-o; }\n.@{fa-css-prefix}-check-square-o:before { content: @fa-var-check-square-o; }\n.@{fa-css-prefix}-arrows:before { content: @fa-var-arrows; }\n.@{fa-css-prefix}-step-backward:before { content: @fa-var-step-backward; }\n.@{fa-css-prefix}-fast-backward:before { content: @fa-var-fast-backward; }\n.@{fa-css-prefix}-backward:before { content: @fa-var-backward; }\n.@{fa-css-prefix}-play:before { content: @fa-var-play; }\n.@{fa-css-prefix}-pause:before { content: @fa-var-pause; }\n.@{fa-css-prefix}-stop:before { content: @fa-var-stop; }\n.@{fa-css-prefix}-forward:before { content: @fa-var-forward; }\n.@{fa-css-prefix}-fast-forward:before { content: @fa-var-fast-forward; }\n.@{fa-css-prefix}-step-forward:before { content: @fa-var-step-forward; }\n.@{fa-css-prefix}-eject:before { content: @fa-var-eject; }\n.@{fa-css-prefix}-chevron-left:before { content: @fa-var-chevron-left; }\n.@{fa-css-prefix}-chevron-right:before { content: @fa-var-chevron-right; }\n.@{fa-css-prefix}-plus-circle:before { content: @fa-var-plus-circle; }\n.@{fa-css-prefix}-minus-circle:before { content: @fa-var-minus-circle; }\n.@{fa-css-prefix}-times-circle:before { content: @fa-var-times-circle; }\n.@{fa-css-prefix}-check-circle:before { content: @fa-var-check-circle; }\n.@{fa-css-prefix}-question-circle:before { content: @fa-var-question-circle; }\n.@{fa-css-prefix}-info-circle:before { content: @fa-var-info-circle; }\n.@{fa-css-prefix}-crosshairs:before { content: @fa-var-crosshairs; }\n.@{fa-css-prefix}-times-circle-o:before { content: @fa-var-times-circle-o; }\n.@{fa-css-prefix}-check-circle-o:before { content: @fa-var-check-circle-o; }\n.@{fa-css-prefix}-ban:before { content: @fa-var-ban; }\n.@{fa-css-prefix}-arrow-left:before { content: @fa-var-arrow-left; }\n.@{fa-css-prefix}-arrow-right:before { content: @fa-var-arrow-right; }\n.@{fa-css-prefix}-arrow-up:before { content: @fa-var-arrow-up; }\n.@{fa-css-prefix}-arrow-down:before { content: @fa-var-arrow-down; }\n.@{fa-css-prefix}-mail-forward:before,\n.@{fa-css-prefix}-share:before { content: @fa-var-share; }\n.@{fa-css-prefix}-expand:before { content: @fa-var-expand; }\n.@{fa-css-prefix}-compress:before { content: @fa-var-compress; }\n.@{fa-css-prefix}-plus:before { content: @fa-var-plus; }\n.@{fa-css-prefix}-minus:before { content: @fa-var-minus; }\n.@{fa-css-prefix}-asterisk:before { content: @fa-var-asterisk; }\n.@{fa-css-prefix}-exclamation-circle:before { content: @fa-var-exclamation-circle; }\n.@{fa-css-prefix}-gift:before { content: @fa-var-gift; }\n.@{fa-css-prefix}-leaf:before { content: @fa-var-leaf; }\n.@{fa-css-prefix}-fire:before { content: @fa-var-fire; }\n.@{fa-css-prefix}-eye:before { content: @fa-var-eye; }\n.@{fa-css-prefix}-eye-slash:before { content: @fa-var-eye-slash; }\n.@{fa-css-prefix}-warning:before,\n.@{fa-css-prefix}-exclamation-triangle:before { content: @fa-var-exclamation-triangle; }\n.@{fa-css-prefix}-plane:before { content: @fa-var-plane; }\n.@{fa-css-prefix}-calendar:before { content: @fa-var-calendar; }\n.@{fa-css-prefix}-random:before { content: @fa-var-random; }\n.@{fa-css-prefix}-comment:before { content: @fa-var-comment; }\n.@{fa-css-prefix}-magnet:before { content: @fa-var-magnet; }\n.@{fa-css-prefix}-chevron-up:before { content: @fa-var-chevron-up; }\n.@{fa-css-prefix}-chevron-down:before { content: @fa-var-chevron-down; }\n.@{fa-css-prefix}-retweet:before { content: @fa-var-retweet; }\n.@{fa-css-prefix}-shopping-cart:before { content: @fa-var-shopping-cart; }\n.@{fa-css-prefix}-folder:before { content: @fa-var-folder; }\n.@{fa-css-prefix}-folder-open:before { content: @fa-var-folder-open; }\n.@{fa-css-prefix}-arrows-v:before { content: @fa-var-arrows-v; }\n.@{fa-css-prefix}-arrows-h:before { content: @fa-var-arrows-h; }\n.@{fa-css-prefix}-bar-chart-o:before,\n.@{fa-css-prefix}-bar-chart:before { content: @fa-var-bar-chart; }\n.@{fa-css-prefix}-twitter-square:before { content: @fa-var-twitter-square; }\n.@{fa-css-prefix}-facebook-square:before { content: @fa-var-facebook-square; }\n.@{fa-css-prefix}-camera-retro:before { content: @fa-var-camera-retro; }\n.@{fa-css-prefix}-key:before { content: @fa-var-key; }\n.@{fa-css-prefix}-gears:before,\n.@{fa-css-prefix}-cogs:before { content: @fa-var-cogs; }\n.@{fa-css-prefix}-comments:before { content: @fa-var-comments; }\n.@{fa-css-prefix}-thumbs-o-up:before { content: @fa-var-thumbs-o-up; }\n.@{fa-css-prefix}-thumbs-o-down:before { content: @fa-var-thumbs-o-down; }\n.@{fa-css-prefix}-star-half:before { content: @fa-var-star-half; }\n.@{fa-css-prefix}-heart-o:before { content: @fa-var-heart-o; }\n.@{fa-css-prefix}-sign-out:before { content: @fa-var-sign-out; }\n.@{fa-css-prefix}-linkedin-square:before { content: @fa-var-linkedin-square; }\n.@{fa-css-prefix}-thumb-tack:before { content: @fa-var-thumb-tack; }\n.@{fa-css-prefix}-external-link:before { content: @fa-var-external-link; }\n.@{fa-css-prefix}-sign-in:before { content: @fa-var-sign-in; }\n.@{fa-css-prefix}-trophy:before { content: @fa-var-trophy; }\n.@{fa-css-prefix}-github-square:before { content: @fa-var-github-square; }\n.@{fa-css-prefix}-upload:before { content: @fa-var-upload; }\n.@{fa-css-prefix}-lemon-o:before { content: @fa-var-lemon-o; }\n.@{fa-css-prefix}-phone:before { content: @fa-var-phone; }\n.@{fa-css-prefix}-square-o:before { content: @fa-var-square-o; }\n.@{fa-css-prefix}-bookmark-o:before { content: @fa-var-bookmark-o; }\n.@{fa-css-prefix}-phone-square:before { content: @fa-var-phone-square; }\n.@{fa-css-prefix}-twitter:before { content: @fa-var-twitter; }\n.@{fa-css-prefix}-facebook-f:before,\n.@{fa-css-prefix}-facebook:before { content: @fa-var-facebook; }\n.@{fa-css-prefix}-github:before { content: @fa-var-github; }\n.@{fa-css-prefix}-unlock:before { content: @fa-var-unlock; }\n.@{fa-css-prefix}-credit-card:before { content: @fa-var-credit-card; }\n.@{fa-css-prefix}-feed:before,\n.@{fa-css-prefix}-rss:before { content: @fa-var-rss; }\n.@{fa-css-prefix}-hdd-o:before { content: @fa-var-hdd-o; }\n.@{fa-css-prefix}-bullhorn:before { content: @fa-var-bullhorn; }\n.@{fa-css-prefix}-bell:before { content: @fa-var-bell; }\n.@{fa-css-prefix}-certificate:before { content: @fa-var-certificate; }\n.@{fa-css-prefix}-hand-o-right:before { content: @fa-var-hand-o-right; }\n.@{fa-css-prefix}-hand-o-left:before { content: @fa-var-hand-o-left; }\n.@{fa-css-prefix}-hand-o-up:before { content: @fa-var-hand-o-up; }\n.@{fa-css-prefix}-hand-o-down:before { content: @fa-var-hand-o-down; }\n.@{fa-css-prefix}-arrow-circle-left:before { content: @fa-var-arrow-circle-left; }\n.@{fa-css-prefix}-arrow-circle-right:before { content: @fa-var-arrow-circle-right; }\n.@{fa-css-prefix}-arrow-circle-up:before { content: @fa-var-arrow-circle-up; }\n.@{fa-css-prefix}-arrow-circle-down:before { content: @fa-var-arrow-circle-down; }\n.@{fa-css-prefix}-globe:before { content: @fa-var-globe; }\n.@{fa-css-prefix}-wrench:before { content: @fa-var-wrench; }\n.@{fa-css-prefix}-tasks:before { content: @fa-var-tasks; }\n.@{fa-css-prefix}-filter:before { content: @fa-var-filter; }\n.@{fa-css-prefix}-briefcase:before { content: @fa-var-briefcase; }\n.@{fa-css-prefix}-arrows-alt:before { content: @fa-var-arrows-alt; }\n.@{fa-css-prefix}-group:before,\n.@{fa-css-prefix}-users:before { content: @fa-var-users; }\n.@{fa-css-prefix}-chain:before,\n.@{fa-css-prefix}-link:before { content: @fa-var-link; }\n.@{fa-css-prefix}-cloud:before { content: @fa-var-cloud; }\n.@{fa-css-prefix}-flask:before { content: @fa-var-flask; }\n.@{fa-css-prefix}-cut:before,\n.@{fa-css-prefix}-scissors:before { content: @fa-var-scissors; }\n.@{fa-css-prefix}-copy:before,\n.@{fa-css-prefix}-files-o:before { content: @fa-var-files-o; }\n.@{fa-css-prefix}-paperclip:before { content: @fa-var-paperclip; }\n.@{fa-css-prefix}-save:before,\n.@{fa-css-prefix}-floppy-o:before { content: @fa-var-floppy-o; }\n.@{fa-css-prefix}-square:before { content: @fa-var-square; }\n.@{fa-css-prefix}-navicon:before,\n.@{fa-css-prefix}-reorder:before,\n.@{fa-css-prefix}-bars:before { content: @fa-var-bars; }\n.@{fa-css-prefix}-list-ul:before { content: @fa-var-list-ul; }\n.@{fa-css-prefix}-list-ol:before { content: @fa-var-list-ol; }\n.@{fa-css-prefix}-strikethrough:before { content: @fa-var-strikethrough; }\n.@{fa-css-prefix}-underline:before { content: @fa-var-underline; }\n.@{fa-css-prefix}-table:before { content: @fa-var-table; }\n.@{fa-css-prefix}-magic:before { content: @fa-var-magic; }\n.@{fa-css-prefix}-truck:before { content: @fa-var-truck; }\n.@{fa-css-prefix}-pinterest:before { content: @fa-var-pinterest; }\n.@{fa-css-prefix}-pinterest-square:before { content: @fa-var-pinterest-square; }\n.@{fa-css-prefix}-google-plus-square:before { content: @fa-var-google-plus-square; }\n.@{fa-css-prefix}-google-plus:before { content: @fa-var-google-plus; }\n.@{fa-css-prefix}-money:before { content: @fa-var-money; }\n.@{fa-css-prefix}-caret-down:before { content: @fa-var-caret-down; }\n.@{fa-css-prefix}-caret-up:before { content: @fa-var-caret-up; }\n.@{fa-css-prefix}-caret-left:before { content: @fa-var-caret-left; }\n.@{fa-css-prefix}-caret-right:before { content: @fa-var-caret-right; }\n.@{fa-css-prefix}-columns:before { content: @fa-var-columns; }\n.@{fa-css-prefix}-unsorted:before,\n.@{fa-css-prefix}-sort:before { content: @fa-var-sort; }\n.@{fa-css-prefix}-sort-down:before,\n.@{fa-css-prefix}-sort-desc:before { content: @fa-var-sort-desc; }\n.@{fa-css-prefix}-sort-up:before,\n.@{fa-css-prefix}-sort-asc:before { content: @fa-var-sort-asc; }\n.@{fa-css-prefix}-envelope:before { content: @fa-var-envelope; }\n.@{fa-css-prefix}-linkedin:before { content: @fa-var-linkedin; }\n.@{fa-css-prefix}-rotate-left:before,\n.@{fa-css-prefix}-undo:before { content: @fa-var-undo; }\n.@{fa-css-prefix}-legal:before,\n.@{fa-css-prefix}-gavel:before { content: @fa-var-gavel; }\n.@{fa-css-prefix}-dashboard:before,\n.@{fa-css-prefix}-tachometer:before { content: @fa-var-tachometer; }\n.@{fa-css-prefix}-comment-o:before { content: @fa-var-comment-o; }\n.@{fa-css-prefix}-comments-o:before { content: @fa-var-comments-o; }\n.@{fa-css-prefix}-flash:before,\n.@{fa-css-prefix}-bolt:before { content: @fa-var-bolt; }\n.@{fa-css-prefix}-sitemap:before { content: @fa-var-sitemap; }\n.@{fa-css-prefix}-umbrella:before { content: @fa-var-umbrella; }\n.@{fa-css-prefix}-paste:before,\n.@{fa-css-prefix}-clipboard:before { content: @fa-var-clipboard; }\n.@{fa-css-prefix}-lightbulb-o:before { content: @fa-var-lightbulb-o; }\n.@{fa-css-prefix}-exchange:before { content: @fa-var-exchange; }\n.@{fa-css-prefix}-cloud-download:before { content: @fa-var-cloud-download; }\n.@{fa-css-prefix}-cloud-upload:before { content: @fa-var-cloud-upload; }\n.@{fa-css-prefix}-user-md:before { content: @fa-var-user-md; }\n.@{fa-css-prefix}-stethoscope:before { content: @fa-var-stethoscope; }\n.@{fa-css-prefix}-suitcase:before { content: @fa-var-suitcase; }\n.@{fa-css-prefix}-bell-o:before { content: @fa-var-bell-o; }\n.@{fa-css-prefix}-coffee:before { content: @fa-var-coffee; }\n.@{fa-css-prefix}-cutlery:before { content: @fa-var-cutlery; }\n.@{fa-css-prefix}-file-text-o:before { content: @fa-var-file-text-o; }\n.@{fa-css-prefix}-building-o:before { content: @fa-var-building-o; }\n.@{fa-css-prefix}-hospital-o:before { content: @fa-var-hospital-o; }\n.@{fa-css-prefix}-ambulance:before { content: @fa-var-ambulance; }\n.@{fa-css-prefix}-medkit:before { content: @fa-var-medkit; }\n.@{fa-css-prefix}-fighter-jet:before { content: @fa-var-fighter-jet; }\n.@{fa-css-prefix}-beer:before { content: @fa-var-beer; }\n.@{fa-css-prefix}-h-square:before { content: @fa-var-h-square; }\n.@{fa-css-prefix}-plus-square:before { content: @fa-var-plus-square; }\n.@{fa-css-prefix}-angle-double-left:before { content: @fa-var-angle-double-left; }\n.@{fa-css-prefix}-angle-double-right:before { content: @fa-var-angle-double-right; }\n.@{fa-css-prefix}-angle-double-up:before { content: @fa-var-angle-double-up; }\n.@{fa-css-prefix}-angle-double-down:before { content: @fa-var-angle-double-down; }\n.@{fa-css-prefix}-angle-left:before { content: @fa-var-angle-left; }\n.@{fa-css-prefix}-angle-right:before { content: @fa-var-angle-right; }\n.@{fa-css-prefix}-angle-up:before { content: @fa-var-angle-up; }\n.@{fa-css-prefix}-angle-down:before { content: @fa-var-angle-down; }\n.@{fa-css-prefix}-desktop:before { content: @fa-var-desktop; }\n.@{fa-css-prefix}-laptop:before { content: @fa-var-laptop; }\n.@{fa-css-prefix}-tablet:before { content: @fa-var-tablet; }\n.@{fa-css-prefix}-mobile-phone:before,\n.@{fa-css-prefix}-mobile:before { content: @fa-var-mobile; }\n.@{fa-css-prefix}-circle-o:before { content: @fa-var-circle-o; }\n.@{fa-css-prefix}-quote-left:before { content: @fa-var-quote-left; }\n.@{fa-css-prefix}-quote-right:before { content: @fa-var-quote-right; }\n.@{fa-css-prefix}-spinner:before { content: @fa-var-spinner; }\n.@{fa-css-prefix}-circle:before { content: @fa-var-circle; }\n.@{fa-css-prefix}-mail-reply:before,\n.@{fa-css-prefix}-reply:before { content: @fa-var-reply; }\n.@{fa-css-prefix}-github-alt:before { content: @fa-var-github-alt; }\n.@{fa-css-prefix}-folder-o:before { content: @fa-var-folder-o; }\n.@{fa-css-prefix}-folder-open-o:before { content: @fa-var-folder-open-o; }\n.@{fa-css-prefix}-smile-o:before { content: @fa-var-smile-o; }\n.@{fa-css-prefix}-frown-o:before { content: @fa-var-frown-o; }\n.@{fa-css-prefix}-meh-o:before { content: @fa-var-meh-o; }\n.@{fa-css-prefix}-gamepad:before { content: @fa-var-gamepad; }\n.@{fa-css-prefix}-keyboard-o:before { content: @fa-var-keyboard-o; }\n.@{fa-css-prefix}-flag-o:before { content: @fa-var-flag-o; }\n.@{fa-css-prefix}-flag-checkered:before { content: @fa-var-flag-checkered; }\n.@{fa-css-prefix}-terminal:before { content: @fa-var-terminal; }\n.@{fa-css-prefix}-code:before { content: @fa-var-code; }\n.@{fa-css-prefix}-mail-reply-all:before,\n.@{fa-css-prefix}-reply-all:before { content: @fa-var-reply-all; }\n.@{fa-css-prefix}-star-half-empty:before,\n.@{fa-css-prefix}-star-half-full:before,\n.@{fa-css-prefix}-star-half-o:before { content: @fa-var-star-half-o; }\n.@{fa-css-prefix}-location-arrow:before { content: @fa-var-location-arrow; }\n.@{fa-css-prefix}-crop:before { content: @fa-var-crop; }\n.@{fa-css-prefix}-code-fork:before { content: @fa-var-code-fork; }\n.@{fa-css-prefix}-unlink:before,\n.@{fa-css-prefix}-chain-broken:before { content: @fa-var-chain-broken; }\n.@{fa-css-prefix}-question:before { content: @fa-var-question; }\n.@{fa-css-prefix}-info:before { content: @fa-var-info; }\n.@{fa-css-prefix}-exclamation:before { content: @fa-var-exclamation; }\n.@{fa-css-prefix}-superscript:before { content: @fa-var-superscript; }\n.@{fa-css-prefix}-subscript:before { content: @fa-var-subscript; }\n.@{fa-css-prefix}-eraser:before { content: @fa-var-eraser; }\n.@{fa-css-prefix}-puzzle-piece:before { content: @fa-var-puzzle-piece; }\n.@{fa-css-prefix}-microphone:before { content: @fa-var-microphone; }\n.@{fa-css-prefix}-microphone-slash:before { content: @fa-var-microphone-slash; }\n.@{fa-css-prefix}-shield:before { content: @fa-var-shield; }\n.@{fa-css-prefix}-calendar-o:before { content: @fa-var-calendar-o; }\n.@{fa-css-prefix}-fire-extinguisher:before { content: @fa-var-fire-extinguisher; }\n.@{fa-css-prefix}-rocket:before { content: @fa-var-rocket; }\n.@{fa-css-prefix}-maxcdn:before { content: @fa-var-maxcdn; }\n.@{fa-css-prefix}-chevron-circle-left:before { content: @fa-var-chevron-circle-left; }\n.@{fa-css-prefix}-chevron-circle-right:before { content: @fa-var-chevron-circle-right; }\n.@{fa-css-prefix}-chevron-circle-up:before { content: @fa-var-chevron-circle-up; }\n.@{fa-css-prefix}-chevron-circle-down:before { content: @fa-var-chevron-circle-down; }\n.@{fa-css-prefix}-html5:before { content: @fa-var-html5; }\n.@{fa-css-prefix}-css3:before { content: @fa-var-css3; }\n.@{fa-css-prefix}-anchor:before { content: @fa-var-anchor; }\n.@{fa-css-prefix}-unlock-alt:before { content: @fa-var-unlock-alt; }\n.@{fa-css-prefix}-bullseye:before { content: @fa-var-bullseye; }\n.@{fa-css-prefix}-ellipsis-h:before { content: @fa-var-ellipsis-h; }\n.@{fa-css-prefix}-ellipsis-v:before { content: @fa-var-ellipsis-v; }\n.@{fa-css-prefix}-rss-square:before { content: @fa-var-rss-square; }\n.@{fa-css-prefix}-play-circle:before { content: @fa-var-play-circle; }\n.@{fa-css-prefix}-ticket:before { content: @fa-var-ticket; }\n.@{fa-css-prefix}-minus-square:before { content: @fa-var-minus-square; }\n.@{fa-css-prefix}-minus-square-o:before { content: @fa-var-minus-square-o; }\n.@{fa-css-prefix}-level-up:before { content: @fa-var-level-up; }\n.@{fa-css-prefix}-level-down:before { content: @fa-var-level-down; }\n.@{fa-css-prefix}-check-square:before { content: @fa-var-check-square; }\n.@{fa-css-prefix}-pencil-square:before { content: @fa-var-pencil-square; }\n.@{fa-css-prefix}-external-link-square:before { content: @fa-var-external-link-square; }\n.@{fa-css-prefix}-share-square:before { content: @fa-var-share-square; }\n.@{fa-css-prefix}-compass:before { content: @fa-var-compass; }\n.@{fa-css-prefix}-toggle-down:before,\n.@{fa-css-prefix}-caret-square-o-down:before { content: @fa-var-caret-square-o-down; }\n.@{fa-css-prefix}-toggle-up:before,\n.@{fa-css-prefix}-caret-square-o-up:before { content: @fa-var-caret-square-o-up; }\n.@{fa-css-prefix}-toggle-right:before,\n.@{fa-css-prefix}-caret-square-o-right:before { content: @fa-var-caret-square-o-right; }\n.@{fa-css-prefix}-euro:before,\n.@{fa-css-prefix}-eur:before { content: @fa-var-eur; }\n.@{fa-css-prefix}-gbp:before { content: @fa-var-gbp; }\n.@{fa-css-prefix}-dollar:before,\n.@{fa-css-prefix}-usd:before { content: @fa-var-usd; }\n.@{fa-css-prefix}-rupee:before,\n.@{fa-css-prefix}-inr:before { content: @fa-var-inr; }\n.@{fa-css-prefix}-cny:before,\n.@{fa-css-prefix}-rmb:before,\n.@{fa-css-prefix}-yen:before,\n.@{fa-css-prefix}-jpy:before { content: @fa-var-jpy; }\n.@{fa-css-prefix}-ruble:before,\n.@{fa-css-prefix}-rouble:before,\n.@{fa-css-prefix}-rub:before { content: @fa-var-rub; }\n.@{fa-css-prefix}-won:before,\n.@{fa-css-prefix}-krw:before { content: @fa-var-krw; }\n.@{fa-css-prefix}-bitcoin:before,\n.@{fa-css-prefix}-btc:before { content: @fa-var-btc; }\n.@{fa-css-prefix}-file:before { content: @fa-var-file; }\n.@{fa-css-prefix}-file-text:before { content: @fa-var-file-text; }\n.@{fa-css-prefix}-sort-alpha-asc:before { content: @fa-var-sort-alpha-asc; }\n.@{fa-css-prefix}-sort-alpha-desc:before { content: @fa-var-sort-alpha-desc; }\n.@{fa-css-prefix}-sort-amount-asc:before { content: @fa-var-sort-amount-asc; }\n.@{fa-css-prefix}-sort-amount-desc:before { content: @fa-var-sort-amount-desc; }\n.@{fa-css-prefix}-sort-numeric-asc:before { content: @fa-var-sort-numeric-asc; }\n.@{fa-css-prefix}-sort-numeric-desc:before { content: @fa-var-sort-numeric-desc; }\n.@{fa-css-prefix}-thumbs-up:before { content: @fa-var-thumbs-up; }\n.@{fa-css-prefix}-thumbs-down:before { content: @fa-var-thumbs-down; }\n.@{fa-css-prefix}-youtube-square:before { content: @fa-var-youtube-square; }\n.@{fa-css-prefix}-youtube:before { content: @fa-var-youtube; }\n.@{fa-css-prefix}-xing:before { content: @fa-var-xing; }\n.@{fa-css-prefix}-xing-square:before { content: @fa-var-xing-square; }\n.@{fa-css-prefix}-youtube-play:before { content: @fa-var-youtube-play; }\n.@{fa-css-prefix}-dropbox:before { content: @fa-var-dropbox; }\n.@{fa-css-prefix}-stack-overflow:before { content: @fa-var-stack-overflow; }\n.@{fa-css-prefix}-instagram:before { content: @fa-var-instagram; }\n.@{fa-css-prefix}-flickr:before { content: @fa-var-flickr; }\n.@{fa-css-prefix}-adn:before { content: @fa-var-adn; }\n.@{fa-css-prefix}-bitbucket:before { content: @fa-var-bitbucket; }\n.@{fa-css-prefix}-bitbucket-square:before { content: @fa-var-bitbucket-square; }\n.@{fa-css-prefix}-tumblr:before { content: @fa-var-tumblr; }\n.@{fa-css-prefix}-tumblr-square:before { content: @fa-var-tumblr-square; }\n.@{fa-css-prefix}-long-arrow-down:before { content: @fa-var-long-arrow-down; }\n.@{fa-css-prefix}-long-arrow-up:before { content: @fa-var-long-arrow-up; }\n.@{fa-css-prefix}-long-arrow-left:before { content: @fa-var-long-arrow-left; }\n.@{fa-css-prefix}-long-arrow-right:before { content: @fa-var-long-arrow-right; }\n.@{fa-css-prefix}-apple:before { content: @fa-var-apple; }\n.@{fa-css-prefix}-windows:before { content: @fa-var-windows; }\n.@{fa-css-prefix}-android:before { content: @fa-var-android; }\n.@{fa-css-prefix}-linux:before { content: @fa-var-linux; }\n.@{fa-css-prefix}-dribbble:before { content: @fa-var-dribbble; }\n.@{fa-css-prefix}-skype:before { content: @fa-var-skype; }\n.@{fa-css-prefix}-foursquare:before { content: @fa-var-foursquare; }\n.@{fa-css-prefix}-trello:before { content: @fa-var-trello; }\n.@{fa-css-prefix}-female:before { content: @fa-var-female; }\n.@{fa-css-prefix}-male:before { content: @fa-var-male; }\n.@{fa-css-prefix}-gittip:before,\n.@{fa-css-prefix}-gratipay:before { content: @fa-var-gratipay; }\n.@{fa-css-prefix}-sun-o:before { content: @fa-var-sun-o; }\n.@{fa-css-prefix}-moon-o:before { content: @fa-var-moon-o; }\n.@{fa-css-prefix}-archive:before { content: @fa-var-archive; }\n.@{fa-css-prefix}-bug:before { content: @fa-var-bug; }\n.@{fa-css-prefix}-vk:before { content: @fa-var-vk; }\n.@{fa-css-prefix}-weibo:before { content: @fa-var-weibo; }\n.@{fa-css-prefix}-renren:before { content: @fa-var-renren; }\n.@{fa-css-prefix}-pagelines:before { content: @fa-var-pagelines; }\n.@{fa-css-prefix}-stack-exchange:before { content: @fa-var-stack-exchange; }\n.@{fa-css-prefix}-arrow-circle-o-right:before { content: @fa-var-arrow-circle-o-right; }\n.@{fa-css-prefix}-arrow-circle-o-left:before { content: @fa-var-arrow-circle-o-left; }\n.@{fa-css-prefix}-toggle-left:before,\n.@{fa-css-prefix}-caret-square-o-left:before { content: @fa-var-caret-square-o-left; }\n.@{fa-css-prefix}-dot-circle-o:before { content: @fa-var-dot-circle-o; }\n.@{fa-css-prefix}-wheelchair:before { content: @fa-var-wheelchair; }\n.@{fa-css-prefix}-vimeo-square:before { content: @fa-var-vimeo-square; }\n.@{fa-css-prefix}-turkish-lira:before,\n.@{fa-css-prefix}-try:before { content: @fa-var-try; }\n.@{fa-css-prefix}-plus-square-o:before { content: @fa-var-plus-square-o; }\n.@{fa-css-prefix}-space-shuttle:before { content: @fa-var-space-shuttle; }\n.@{fa-css-prefix}-slack:before { content: @fa-var-slack; }\n.@{fa-css-prefix}-envelope-square:before { content: @fa-var-envelope-square; }\n.@{fa-css-prefix}-wordpress:before { content: @fa-var-wordpress; }\n.@{fa-css-prefix}-openid:before { content: @fa-var-openid; }\n.@{fa-css-prefix}-institution:before,\n.@{fa-css-prefix}-bank:before,\n.@{fa-css-prefix}-university:before { content: @fa-var-university; }\n.@{fa-css-prefix}-mortar-board:before,\n.@{fa-css-prefix}-graduation-cap:before { content: @fa-var-graduation-cap; }\n.@{fa-css-prefix}-yahoo:before { content: @fa-var-yahoo; }\n.@{fa-css-prefix}-google:before { content: @fa-var-google; }\n.@{fa-css-prefix}-reddit:before { content: @fa-var-reddit; }\n.@{fa-css-prefix}-reddit-square:before { content: @fa-var-reddit-square; }\n.@{fa-css-prefix}-stumbleupon-circle:before { content: @fa-var-stumbleupon-circle; }\n.@{fa-css-prefix}-stumbleupon:before { content: @fa-var-stumbleupon; }\n.@{fa-css-prefix}-delicious:before { content: @fa-var-delicious; }\n.@{fa-css-prefix}-digg:before { content: @fa-var-digg; }\n.@{fa-css-prefix}-pied-piper-pp:before { content: @fa-var-pied-piper-pp; }\n.@{fa-css-prefix}-pied-piper-alt:before { content: @fa-var-pied-piper-alt; }\n.@{fa-css-prefix}-drupal:before { content: @fa-var-drupal; }\n.@{fa-css-prefix}-joomla:before { content: @fa-var-joomla; }\n.@{fa-css-prefix}-language:before { content: @fa-var-language; }\n.@{fa-css-prefix}-fax:before { content: @fa-var-fax; }\n.@{fa-css-prefix}-building:before { content: @fa-var-building; }\n.@{fa-css-prefix}-child:before { content: @fa-var-child; }\n.@{fa-css-prefix}-paw:before { content: @fa-var-paw; }\n.@{fa-css-prefix}-spoon:before { content: @fa-var-spoon; }\n.@{fa-css-prefix}-cube:before { content: @fa-var-cube; }\n.@{fa-css-prefix}-cubes:before { content: @fa-var-cubes; }\n.@{fa-css-prefix}-behance:before { content: @fa-var-behance; }\n.@{fa-css-prefix}-behance-square:before { content: @fa-var-behance-square; }\n.@{fa-css-prefix}-steam:before { content: @fa-var-steam; }\n.@{fa-css-prefix}-steam-square:before { content: @fa-var-steam-square; }\n.@{fa-css-prefix}-recycle:before { content: @fa-var-recycle; }\n.@{fa-css-prefix}-automobile:before,\n.@{fa-css-prefix}-car:before { content: @fa-var-car; }\n.@{fa-css-prefix}-cab:before,\n.@{fa-css-prefix}-taxi:before { content: @fa-var-taxi; }\n.@{fa-css-prefix}-tree:before { content: @fa-var-tree; }\n.@{fa-css-prefix}-spotify:before { content: @fa-var-spotify; }\n.@{fa-css-prefix}-deviantart:before { content: @fa-var-deviantart; }\n.@{fa-css-prefix}-soundcloud:before { content: @fa-var-soundcloud; }\n.@{fa-css-prefix}-database:before { content: @fa-var-database; }\n.@{fa-css-prefix}-file-pdf-o:before { content: @fa-var-file-pdf-o; }\n.@{fa-css-prefix}-file-word-o:before { content: @fa-var-file-word-o; }\n.@{fa-css-prefix}-file-excel-o:before { content: @fa-var-file-excel-o; }\n.@{fa-css-prefix}-file-powerpoint-o:before { content: @fa-var-file-powerpoint-o; }\n.@{fa-css-prefix}-file-photo-o:before,\n.@{fa-css-prefix}-file-picture-o:before,\n.@{fa-css-prefix}-file-image-o:before { content: @fa-var-file-image-o; }\n.@{fa-css-prefix}-file-zip-o:before,\n.@{fa-css-prefix}-file-archive-o:before { content: @fa-var-file-archive-o; }\n.@{fa-css-prefix}-file-sound-o:before,\n.@{fa-css-prefix}-file-audio-o:before { content: @fa-var-file-audio-o; }\n.@{fa-css-prefix}-file-movie-o:before,\n.@{fa-css-prefix}-file-video-o:before { content: @fa-var-file-video-o; }\n.@{fa-css-prefix}-file-code-o:before { content: @fa-var-file-code-o; }\n.@{fa-css-prefix}-vine:before { content: @fa-var-vine; }\n.@{fa-css-prefix}-codepen:before { content: @fa-var-codepen; }\n.@{fa-css-prefix}-jsfiddle:before { content: @fa-var-jsfiddle; }\n.@{fa-css-prefix}-life-bouy:before,\n.@{fa-css-prefix}-life-buoy:before,\n.@{fa-css-prefix}-life-saver:before,\n.@{fa-css-prefix}-support:before,\n.@{fa-css-prefix}-life-ring:before { content: @fa-var-life-ring; }\n.@{fa-css-prefix}-circle-o-notch:before { content: @fa-var-circle-o-notch; }\n.@{fa-css-prefix}-ra:before,\n.@{fa-css-prefix}-resistance:before,\n.@{fa-css-prefix}-rebel:before { content: @fa-var-rebel; }\n.@{fa-css-prefix}-ge:before,\n.@{fa-css-prefix}-empire:before { content: @fa-var-empire; }\n.@{fa-css-prefix}-git-square:before { content: @fa-var-git-square; }\n.@{fa-css-prefix}-git:before { content: @fa-var-git; }\n.@{fa-css-prefix}-y-combinator-square:before,\n.@{fa-css-prefix}-yc-square:before,\n.@{fa-css-prefix}-hacker-news:before { content: @fa-var-hacker-news; }\n.@{fa-css-prefix}-tencent-weibo:before { content: @fa-var-tencent-weibo; }\n.@{fa-css-prefix}-qq:before { content: @fa-var-qq; }\n.@{fa-css-prefix}-wechat:before,\n.@{fa-css-prefix}-weixin:before { content: @fa-var-weixin; }\n.@{fa-css-prefix}-send:before,\n.@{fa-css-prefix}-paper-plane:before { content: @fa-var-paper-plane; }\n.@{fa-css-prefix}-send-o:before,\n.@{fa-css-prefix}-paper-plane-o:before { content: @fa-var-paper-plane-o; }\n.@{fa-css-prefix}-history:before { content: @fa-var-history; }\n.@{fa-css-prefix}-circle-thin:before { content: @fa-var-circle-thin; }\n.@{fa-css-prefix}-header:before { content: @fa-var-header; }\n.@{fa-css-prefix}-paragraph:before { content: @fa-var-paragraph; }\n.@{fa-css-prefix}-sliders:before { content: @fa-var-sliders; }\n.@{fa-css-prefix}-share-alt:before { content: @fa-var-share-alt; }\n.@{fa-css-prefix}-share-alt-square:before { content: @fa-var-share-alt-square; }\n.@{fa-css-prefix}-bomb:before { content: @fa-var-bomb; }\n.@{fa-css-prefix}-soccer-ball-o:before,\n.@{fa-css-prefix}-futbol-o:before { content: @fa-var-futbol-o; }\n.@{fa-css-prefix}-tty:before { content: @fa-var-tty; }\n.@{fa-css-prefix}-binoculars:before { content: @fa-var-binoculars; }\n.@{fa-css-prefix}-plug:before { content: @fa-var-plug; }\n.@{fa-css-prefix}-slideshare:before { content: @fa-var-slideshare; }\n.@{fa-css-prefix}-twitch:before { content: @fa-var-twitch; }\n.@{fa-css-prefix}-yelp:before { content: @fa-var-yelp; }\n.@{fa-css-prefix}-newspaper-o:before { content: @fa-var-newspaper-o; }\n.@{fa-css-prefix}-wifi:before { content: @fa-var-wifi; }\n.@{fa-css-prefix}-calculator:before { content: @fa-var-calculator; }\n.@{fa-css-prefix}-paypal:before { content: @fa-var-paypal; }\n.@{fa-css-prefix}-google-wallet:before { content: @fa-var-google-wallet; }\n.@{fa-css-prefix}-cc-visa:before { content: @fa-var-cc-visa; }\n.@{fa-css-prefix}-cc-mastercard:before { content: @fa-var-cc-mastercard; }\n.@{fa-css-prefix}-cc-discover:before { content: @fa-var-cc-discover; }\n.@{fa-css-prefix}-cc-amex:before { content: @fa-var-cc-amex; }\n.@{fa-css-prefix}-cc-paypal:before { content: @fa-var-cc-paypal; }\n.@{fa-css-prefix}-cc-stripe:before { content: @fa-var-cc-stripe; }\n.@{fa-css-prefix}-bell-slash:before { content: @fa-var-bell-slash; }\n.@{fa-css-prefix}-bell-slash-o:before { content: @fa-var-bell-slash-o; }\n.@{fa-css-prefix}-trash:before { content: @fa-var-trash; }\n.@{fa-css-prefix}-copyright:before { content: @fa-var-copyright; }\n.@{fa-css-prefix}-at:before { content: @fa-var-at; }\n.@{fa-css-prefix}-eyedropper:before { content: @fa-var-eyedropper; }\n.@{fa-css-prefix}-paint-brush:before { content: @fa-var-paint-brush; }\n.@{fa-css-prefix}-birthday-cake:before { content: @fa-var-birthday-cake; }\n.@{fa-css-prefix}-area-chart:before { content: @fa-var-area-chart; }\n.@{fa-css-prefix}-pie-chart:before { content: @fa-var-pie-chart; }\n.@{fa-css-prefix}-line-chart:before { content: @fa-var-line-chart; }\n.@{fa-css-prefix}-lastfm:before { content: @fa-var-lastfm; }\n.@{fa-css-prefix}-lastfm-square:before { content: @fa-var-lastfm-square; }\n.@{fa-css-prefix}-toggle-off:before { content: @fa-var-toggle-off; }\n.@{fa-css-prefix}-toggle-on:before { content: @fa-var-toggle-on; }\n.@{fa-css-prefix}-bicycle:before { content: @fa-var-bicycle; }\n.@{fa-css-prefix}-bus:before { content: @fa-var-bus; }\n.@{fa-css-prefix}-ioxhost:before { content: @fa-var-ioxhost; }\n.@{fa-css-prefix}-angellist:before { content: @fa-var-angellist; }\n.@{fa-css-prefix}-cc:before { content: @fa-var-cc; }\n.@{fa-css-prefix}-shekel:before,\n.@{fa-css-prefix}-sheqel:before,\n.@{fa-css-prefix}-ils:before { content: @fa-var-ils; }\n.@{fa-css-prefix}-meanpath:before { content: @fa-var-meanpath; }\n.@{fa-css-prefix}-buysellads:before { content: @fa-var-buysellads; }\n.@{fa-css-prefix}-connectdevelop:before { content: @fa-var-connectdevelop; }\n.@{fa-css-prefix}-dashcube:before { content: @fa-var-dashcube; }\n.@{fa-css-prefix}-forumbee:before { content: @fa-var-forumbee; }\n.@{fa-css-prefix}-leanpub:before { content: @fa-var-leanpub; }\n.@{fa-css-prefix}-sellsy:before { content: @fa-var-sellsy; }\n.@{fa-css-prefix}-shirtsinbulk:before { content: @fa-var-shirtsinbulk; }\n.@{fa-css-prefix}-simplybuilt:before { content: @fa-var-simplybuilt; }\n.@{fa-css-prefix}-skyatlas:before { content: @fa-var-skyatlas; }\n.@{fa-css-prefix}-cart-plus:before { content: @fa-var-cart-plus; }\n.@{fa-css-prefix}-cart-arrow-down:before { content: @fa-var-cart-arrow-down; }\n.@{fa-css-prefix}-diamond:before { content: @fa-var-diamond; }\n.@{fa-css-prefix}-ship:before { content: @fa-var-ship; }\n.@{fa-css-prefix}-user-secret:before { content: @fa-var-user-secret; }\n.@{fa-css-prefix}-motorcycle:before { content: @fa-var-motorcycle; }\n.@{fa-css-prefix}-street-view:before { content: @fa-var-street-view; }\n.@{fa-css-prefix}-heartbeat:before { content: @fa-var-heartbeat; }\n.@{fa-css-prefix}-venus:before { content: @fa-var-venus; }\n.@{fa-css-prefix}-mars:before { content: @fa-var-mars; }\n.@{fa-css-prefix}-mercury:before { content: @fa-var-mercury; }\n.@{fa-css-prefix}-intersex:before,\n.@{fa-css-prefix}-transgender:before { content: @fa-var-transgender; }\n.@{fa-css-prefix}-transgender-alt:before { content: @fa-var-transgender-alt; }\n.@{fa-css-prefix}-venus-double:before { content: @fa-var-venus-double; }\n.@{fa-css-prefix}-mars-double:before { content: @fa-var-mars-double; }\n.@{fa-css-prefix}-venus-mars:before { content: @fa-var-venus-mars; }\n.@{fa-css-prefix}-mars-stroke:before { content: @fa-var-mars-stroke; }\n.@{fa-css-prefix}-mars-stroke-v:before { content: @fa-var-mars-stroke-v; }\n.@{fa-css-prefix}-mars-stroke-h:before { content: @fa-var-mars-stroke-h; }\n.@{fa-css-prefix}-neuter:before { content: @fa-var-neuter; }\n.@{fa-css-prefix}-genderless:before { content: @fa-var-genderless; }\n.@{fa-css-prefix}-facebook-official:before { content: @fa-var-facebook-official; }\n.@{fa-css-prefix}-pinterest-p:before { content: @fa-var-pinterest-p; }\n.@{fa-css-prefix}-whatsapp:before { content: @fa-var-whatsapp; }\n.@{fa-css-prefix}-server:before { content: @fa-var-server; }\n.@{fa-css-prefix}-user-plus:before { content: @fa-var-user-plus; }\n.@{fa-css-prefix}-user-times:before { content: @fa-var-user-times; }\n.@{fa-css-prefix}-hotel:before,\n.@{fa-css-prefix}-bed:before { content: @fa-var-bed; }\n.@{fa-css-prefix}-viacoin:before { content: @fa-var-viacoin; }\n.@{fa-css-prefix}-train:before { content: @fa-var-train; }\n.@{fa-css-prefix}-subway:before { content: @fa-var-subway; }\n.@{fa-css-prefix}-medium:before { content: @fa-var-medium; }\n.@{fa-css-prefix}-yc:before,\n.@{fa-css-prefix}-y-combinator:before { content: @fa-var-y-combinator; }\n.@{fa-css-prefix}-optin-monster:before { content: @fa-var-optin-monster; }\n.@{fa-css-prefix}-opencart:before { content: @fa-var-opencart; }\n.@{fa-css-prefix}-expeditedssl:before { content: @fa-var-expeditedssl; }\n.@{fa-css-prefix}-battery-4:before,\n.@{fa-css-prefix}-battery-full:before { content: @fa-var-battery-full; }\n.@{fa-css-prefix}-battery-3:before,\n.@{fa-css-prefix}-battery-three-quarters:before { content: @fa-var-battery-three-quarters; }\n.@{fa-css-prefix}-battery-2:before,\n.@{fa-css-prefix}-battery-half:before { content: @fa-var-battery-half; }\n.@{fa-css-prefix}-battery-1:before,\n.@{fa-css-prefix}-battery-quarter:before { content: @fa-var-battery-quarter; }\n.@{fa-css-prefix}-battery-0:before,\n.@{fa-css-prefix}-battery-empty:before { content: @fa-var-battery-empty; }\n.@{fa-css-prefix}-mouse-pointer:before { content: @fa-var-mouse-pointer; }\n.@{fa-css-prefix}-i-cursor:before { content: @fa-var-i-cursor; }\n.@{fa-css-prefix}-object-group:before { content: @fa-var-object-group; }\n.@{fa-css-prefix}-object-ungroup:before { content: @fa-var-object-ungroup; }\n.@{fa-css-prefix}-sticky-note:before { content: @fa-var-sticky-note; }\n.@{fa-css-prefix}-sticky-note-o:before { content: @fa-var-sticky-note-o; }\n.@{fa-css-prefix}-cc-jcb:before { content: @fa-var-cc-jcb; }\n.@{fa-css-prefix}-cc-diners-club:before { content: @fa-var-cc-diners-club; }\n.@{fa-css-prefix}-clone:before { content: @fa-var-clone; }\n.@{fa-css-prefix}-balance-scale:before { content: @fa-var-balance-scale; }\n.@{fa-css-prefix}-hourglass-o:before { content: @fa-var-hourglass-o; }\n.@{fa-css-prefix}-hourglass-1:before,\n.@{fa-css-prefix}-hourglass-start:before { content: @fa-var-hourglass-start; }\n.@{fa-css-prefix}-hourglass-2:before,\n.@{fa-css-prefix}-hourglass-half:before { content: @fa-var-hourglass-half; }\n.@{fa-css-prefix}-hourglass-3:before,\n.@{fa-css-prefix}-hourglass-end:before { content: @fa-var-hourglass-end; }\n.@{fa-css-prefix}-hourglass:before { content: @fa-var-hourglass; }\n.@{fa-css-prefix}-hand-grab-o:before,\n.@{fa-css-prefix}-hand-rock-o:before { content: @fa-var-hand-rock-o; }\n.@{fa-css-prefix}-hand-stop-o:before,\n.@{fa-css-prefix}-hand-paper-o:before { content: @fa-var-hand-paper-o; }\n.@{fa-css-prefix}-hand-scissors-o:before { content: @fa-var-hand-scissors-o; }\n.@{fa-css-prefix}-hand-lizard-o:before { content: @fa-var-hand-lizard-o; }\n.@{fa-css-prefix}-hand-spock-o:before { content: @fa-var-hand-spock-o; }\n.@{fa-css-prefix}-hand-pointer-o:before { content: @fa-var-hand-pointer-o; }\n.@{fa-css-prefix}-hand-peace-o:before { content: @fa-var-hand-peace-o; }\n.@{fa-css-prefix}-trademark:before { content: @fa-var-trademark; }\n.@{fa-css-prefix}-registered:before { content: @fa-var-registered; }\n.@{fa-css-prefix}-creative-commons:before { content: @fa-var-creative-commons; }\n.@{fa-css-prefix}-gg:before { content: @fa-var-gg; }\n.@{fa-css-prefix}-gg-circle:before { content: @fa-var-gg-circle; }\n.@{fa-css-prefix}-tripadvisor:before { content: @fa-var-tripadvisor; }\n.@{fa-css-prefix}-odnoklassniki:before { content: @fa-var-odnoklassniki; }\n.@{fa-css-prefix}-odnoklassniki-square:before { content: @fa-var-odnoklassniki-square; }\n.@{fa-css-prefix}-get-pocket:before { content: @fa-var-get-pocket; }\n.@{fa-css-prefix}-wikipedia-w:before { content: @fa-var-wikipedia-w; }\n.@{fa-css-prefix}-safari:before { content: @fa-var-safari; }\n.@{fa-css-prefix}-chrome:before { content: @fa-var-chrome; }\n.@{fa-css-prefix}-firefox:before { content: @fa-var-firefox; }\n.@{fa-css-prefix}-opera:before { content: @fa-var-opera; }\n.@{fa-css-prefix}-internet-explorer:before { content: @fa-var-internet-explorer; }\n.@{fa-css-prefix}-tv:before,\n.@{fa-css-prefix}-television:before { content: @fa-var-television; }\n.@{fa-css-prefix}-contao:before { content: @fa-var-contao; }\n.@{fa-css-prefix}-500px:before { content: @fa-var-500px; }\n.@{fa-css-prefix}-amazon:before { content: @fa-var-amazon; }\n.@{fa-css-prefix}-calendar-plus-o:before { content: @fa-var-calendar-plus-o; }\n.@{fa-css-prefix}-calendar-minus-o:before { content: @fa-var-calendar-minus-o; }\n.@{fa-css-prefix}-calendar-times-o:before { content: @fa-var-calendar-times-o; }\n.@{fa-css-prefix}-calendar-check-o:before { content: @fa-var-calendar-check-o; }\n.@{fa-css-prefix}-industry:before { content: @fa-var-industry; }\n.@{fa-css-prefix}-map-pin:before { content: @fa-var-map-pin; }\n.@{fa-css-prefix}-map-signs:before { content: @fa-var-map-signs; }\n.@{fa-css-prefix}-map-o:before { content: @fa-var-map-o; }\n.@{fa-css-prefix}-map:before { content: @fa-var-map; }\n.@{fa-css-prefix}-commenting:before { content: @fa-var-commenting; }\n.@{fa-css-prefix}-commenting-o:before { content: @fa-var-commenting-o; }\n.@{fa-css-prefix}-houzz:before { content: @fa-var-houzz; }\n.@{fa-css-prefix}-vimeo:before { content: @fa-var-vimeo; }\n.@{fa-css-prefix}-black-tie:before { content: @fa-var-black-tie; }\n.@{fa-css-prefix}-fonticons:before { content: @fa-var-fonticons; }\n.@{fa-css-prefix}-reddit-alien:before { content: @fa-var-reddit-alien; }\n.@{fa-css-prefix}-edge:before { content: @fa-var-edge; }\n.@{fa-css-prefix}-credit-card-alt:before { content: @fa-var-credit-card-alt; }\n.@{fa-css-prefix}-codiepie:before { content: @fa-var-codiepie; }\n.@{fa-css-prefix}-modx:before { content: @fa-var-modx; }\n.@{fa-css-prefix}-fort-awesome:before { content: @fa-var-fort-awesome; }\n.@{fa-css-prefix}-usb:before { content: @fa-var-usb; }\n.@{fa-css-prefix}-product-hunt:before { content: @fa-var-product-hunt; }\n.@{fa-css-prefix}-mixcloud:before { content: @fa-var-mixcloud; }\n.@{fa-css-prefix}-scribd:before { content: @fa-var-scribd; }\n.@{fa-css-prefix}-pause-circle:before { content: @fa-var-pause-circle; }\n.@{fa-css-prefix}-pause-circle-o:before { content: @fa-var-pause-circle-o; }\n.@{fa-css-prefix}-stop-circle:before { content: @fa-var-stop-circle; }\n.@{fa-css-prefix}-stop-circle-o:before { content: @fa-var-stop-circle-o; }\n.@{fa-css-prefix}-shopping-bag:before { content: @fa-var-shopping-bag; }\n.@{fa-css-prefix}-shopping-basket:before { content: @fa-var-shopping-basket; }\n.@{fa-css-prefix}-hashtag:before { content: @fa-var-hashtag; }\n.@{fa-css-prefix}-bluetooth:before { content: @fa-var-bluetooth; }\n.@{fa-css-prefix}-bluetooth-b:before { content: @fa-var-bluetooth-b; }\n.@{fa-css-prefix}-percent:before { content: @fa-var-percent; }\n.@{fa-css-prefix}-gitlab:before { content: @fa-var-gitlab; }\n.@{fa-css-prefix}-wpbeginner:before { content: @fa-var-wpbeginner; }\n.@{fa-css-prefix}-wpforms:before { content: @fa-var-wpforms; }\n.@{fa-css-prefix}-envira:before { content: @fa-var-envira; }\n.@{fa-css-prefix}-universal-access:before { content: @fa-var-universal-access; }\n.@{fa-css-prefix}-wheelchair-alt:before { content: @fa-var-wheelchair-alt; }\n.@{fa-css-prefix}-question-circle-o:before { content: @fa-var-question-circle-o; }\n.@{fa-css-prefix}-blind:before { content: @fa-var-blind; }\n.@{fa-css-prefix}-audio-description:before { content: @fa-var-audio-description; }\n.@{fa-css-prefix}-volume-control-phone:before { content: @fa-var-volume-control-phone; }\n.@{fa-css-prefix}-braille:before { content: @fa-var-braille; }\n.@{fa-css-prefix}-assistive-listening-systems:before { content: @fa-var-assistive-listening-systems; }\n.@{fa-css-prefix}-asl-interpreting:before,\n.@{fa-css-prefix}-american-sign-language-interpreting:before { content: @fa-var-american-sign-language-interpreting; }\n.@{fa-css-prefix}-deafness:before,\n.@{fa-css-prefix}-hard-of-hearing:before,\n.@{fa-css-prefix}-deaf:before { content: @fa-var-deaf; }\n.@{fa-css-prefix}-glide:before { content: @fa-var-glide; }\n.@{fa-css-prefix}-glide-g:before { content: @fa-var-glide-g; }\n.@{fa-css-prefix}-signing:before,\n.@{fa-css-prefix}-sign-language:before { content: @fa-var-sign-language; }\n.@{fa-css-prefix}-low-vision:before { content: @fa-var-low-vision; }\n.@{fa-css-prefix}-viadeo:before { content: @fa-var-viadeo; }\n.@{fa-css-prefix}-viadeo-square:before { content: @fa-var-viadeo-square; }\n.@{fa-css-prefix}-snapchat:before { content: @fa-var-snapchat; }\n.@{fa-css-prefix}-snapchat-ghost:before { content: @fa-var-snapchat-ghost; }\n.@{fa-css-prefix}-snapchat-square:before { content: @fa-var-snapchat-square; }\n.@{fa-css-prefix}-pied-piper:before { content: @fa-var-pied-piper; }\n.@{fa-css-prefix}-first-order:before { content: @fa-var-first-order; }\n.@{fa-css-prefix}-yoast:before { content: @fa-var-yoast; }\n.@{fa-css-prefix}-themeisle:before { content: @fa-var-themeisle; }\n.@{fa-css-prefix}-google-plus-circle:before,\n.@{fa-css-prefix}-google-plus-official:before { content: @fa-var-google-plus-official; }\n.@{fa-css-prefix}-fa:before,\n.@{fa-css-prefix}-font-awesome:before { content: @fa-var-font-awesome; }\n"
  },
  {
    "path": "app_backend/static/plugin/font-awesome/less/larger.less",
    "content": "// Icon Sizes\n// -------------------------\n\n/* makes the font 33% larger relative to the icon container */\n.@{fa-css-prefix}-lg {\n  font-size: (4em / 3);\n  line-height: (3em / 4);\n  vertical-align: -15%;\n}\n.@{fa-css-prefix}-2x { font-size: 2em; }\n.@{fa-css-prefix}-3x { font-size: 3em; }\n.@{fa-css-prefix}-4x { font-size: 4em; }\n.@{fa-css-prefix}-5x { font-size: 5em; }\n"
  },
  {
    "path": "app_backend/static/plugin/font-awesome/less/list.less",
    "content": "// List Icons\n// -------------------------\n\n.@{fa-css-prefix}-ul {\n  padding-left: 0;\n  margin-left: @fa-li-width;\n  list-style-type: none;\n  > li { position: relative; }\n}\n.@{fa-css-prefix}-li {\n  position: absolute;\n  left: -@fa-li-width;\n  width: @fa-li-width;\n  top: (2em / 14);\n  text-align: center;\n  &.@{fa-css-prefix}-lg {\n    left: (-@fa-li-width + (4em / 14));\n  }\n}\n"
  },
  {
    "path": "app_backend/static/plugin/font-awesome/less/mixins.less",
    "content": "// Mixins\n// --------------------------\n\n.fa-icon() {\n  display: inline-block;\n  font: normal normal normal @fa-font-size-base/@fa-line-height-base FontAwesome; // shortening font declaration\n  font-size: inherit; // can't have font-size inherit on line above, so need to override\n  text-rendering: auto; // optimizelegibility throws things off #1094\n  -webkit-font-smoothing: antialiased;\n  -moz-osx-font-smoothing: grayscale;\n\n}\n\n.fa-icon-rotate(@degrees, @rotation) {\n  -ms-filter: \"progid:DXImageTransform.Microsoft.BasicImage(rotation=@{rotation})\";\n  -webkit-transform: rotate(@degrees);\n      -ms-transform: rotate(@degrees);\n          transform: rotate(@degrees);\n}\n\n.fa-icon-flip(@horiz, @vert, @rotation) {\n  -ms-filter: \"progid:DXImageTransform.Microsoft.BasicImage(rotation=@{rotation}, mirror=1)\";\n  -webkit-transform: scale(@horiz, @vert);\n      -ms-transform: scale(@horiz, @vert);\n          transform: scale(@horiz, @vert);\n}\n\n\n// Only display content to screen readers. A la Bootstrap 4.\n//\n// See: http://a11yproject.com/posts/how-to-hide-content/\n\n.sr-only() {\n  position: absolute;\n  width: 1px;\n  height: 1px;\n  padding: 0;\n  margin: -1px;\n  overflow: hidden;\n  clip: rect(0,0,0,0);\n  border: 0;\n}\n\n// Use in conjunction with .sr-only to only display content when it's focused.\n//\n// Useful for \"Skip to main content\" links; see http://www.w3.org/TR/2013/NOTE-WCAG20-TECHS-20130905/G1\n//\n// Credit: HTML5 Boilerplate\n\n.sr-only-focusable() {\n  &:active,\n  &:focus {\n    position: static;\n    width: auto;\n    height: auto;\n    margin: 0;\n    overflow: visible;\n    clip: auto;\n  }\n}\n"
  },
  {
    "path": "app_backend/static/plugin/font-awesome/less/path.less",
    "content": "/* FONT PATH\n * -------------------------- */\n\n@font-face {\n  font-family: 'FontAwesome';\n  src: url('@{fa-font-path}/fontawesome-webfont.eot?v=@{fa-version}');\n  src: url('@{fa-font-path}/fontawesome-webfont.eot?#iefix&v=@{fa-version}') format('embedded-opentype'),\n    url('@{fa-font-path}/fontawesome-webfont.woff2?v=@{fa-version}') format('woff2'),\n    url('@{fa-font-path}/fontawesome-webfont.woff?v=@{fa-version}') format('woff'),\n    url('@{fa-font-path}/fontawesome-webfont.ttf?v=@{fa-version}') format('truetype'),\n    url('@{fa-font-path}/fontawesome-webfont.svg?v=@{fa-version}#fontawesomeregular') format('svg');\n  // src: url('@{fa-font-path}/FontAwesome.otf') format('opentype'); // used when developing fonts\n  font-weight: normal;\n  font-style: normal;\n}\n"
  },
  {
    "path": "app_backend/static/plugin/font-awesome/less/rotated-flipped.less",
    "content": "// Rotated & Flipped Icons\n// -------------------------\n\n.@{fa-css-prefix}-rotate-90  { .fa-icon-rotate(90deg, 1);  }\n.@{fa-css-prefix}-rotate-180 { .fa-icon-rotate(180deg, 2); }\n.@{fa-css-prefix}-rotate-270 { .fa-icon-rotate(270deg, 3); }\n\n.@{fa-css-prefix}-flip-horizontal { .fa-icon-flip(-1, 1, 0); }\n.@{fa-css-prefix}-flip-vertical   { .fa-icon-flip(1, -1, 2); }\n\n// Hook for IE8-9\n// -------------------------\n\n:root .@{fa-css-prefix}-rotate-90,\n:root .@{fa-css-prefix}-rotate-180,\n:root .@{fa-css-prefix}-rotate-270,\n:root .@{fa-css-prefix}-flip-horizontal,\n:root .@{fa-css-prefix}-flip-vertical {\n  filter: none;\n}\n"
  },
  {
    "path": "app_backend/static/plugin/font-awesome/less/screen-reader.less",
    "content": "// Screen Readers\n// -------------------------\n\n.sr-only { .sr-only(); }\n.sr-only-focusable { .sr-only-focusable(); }\n"
  },
  {
    "path": "app_backend/static/plugin/font-awesome/less/spinning.less",
    "content": "// Spinning Icons\n// --------------------------\n\n.@{fa-css-prefix}-spin {\n  -webkit-animation: fa-spin 2s infinite linear;\n          animation: fa-spin 2s infinite linear;\n}\n\n@-webkit-keyframes fa-spin {\n  0% {\n    -webkit-transform: rotate(0deg);\n            transform: rotate(0deg);\n  }\n  100% {\n    -webkit-transform: rotate(359deg);\n            transform: rotate(359deg);\n  }\n}\n\n@keyframes fa-spin {\n  0% {\n    -webkit-transform: rotate(0deg);\n            transform: rotate(0deg);\n  }\n  100% {\n    -webkit-transform: rotate(359deg);\n            transform: rotate(359deg);\n  }\n}\n"
  },
  {
    "path": "app_backend/static/plugin/font-awesome/less/stacked.less",
    "content": "// Stacked Icons\n// -------------------------\n\n.@{fa-css-prefix}-stack {\n  position: relative;\n  display: inline-block;\n  width: 2em;\n  height: 2em;\n  line-height: 2em;\n  vertical-align: middle;\n}\n.@{fa-css-prefix}-stack-1x, .@{fa-css-prefix}-stack-2x {\n  position: absolute;\n  left: 0;\n  width: 100%;\n  text-align: center;\n}\n.@{fa-css-prefix}-stack-1x { line-height: inherit; }\n.@{fa-css-prefix}-stack-2x { font-size: 2em; }\n.@{fa-css-prefix}-inverse { color: @fa-inverse; }\n"
  },
  {
    "path": "app_backend/static/plugin/font-awesome/less/variables.less",
    "content": "// Variables\n// --------------------------\n\n@fa-font-path:        \"../fonts\";\n@fa-font-size-base:   14px;\n@fa-line-height-base: 1;\n//@fa-font-path:        \"//netdna.bootstrapcdn.com/font-awesome/4.6.3/fonts\"; // for referencing Bootstrap CDN font files directly\n@fa-css-prefix:       fa;\n@fa-version:          \"4.6.3\";\n@fa-border-color:     #eee;\n@fa-inverse:          #fff;\n@fa-li-width:         (30em / 14);\n\n@fa-var-500px: \"\\f26e\";\n@fa-var-adjust: \"\\f042\";\n@fa-var-adn: \"\\f170\";\n@fa-var-align-center: \"\\f037\";\n@fa-var-align-justify: \"\\f039\";\n@fa-var-align-left: \"\\f036\";\n@fa-var-align-right: \"\\f038\";\n@fa-var-amazon: \"\\f270\";\n@fa-var-ambulance: \"\\f0f9\";\n@fa-var-american-sign-language-interpreting: \"\\f2a3\";\n@fa-var-anchor: \"\\f13d\";\n@fa-var-android: \"\\f17b\";\n@fa-var-angellist: \"\\f209\";\n@fa-var-angle-double-down: \"\\f103\";\n@fa-var-angle-double-left: \"\\f100\";\n@fa-var-angle-double-right: \"\\f101\";\n@fa-var-angle-double-up: \"\\f102\";\n@fa-var-angle-down: \"\\f107\";\n@fa-var-angle-left: \"\\f104\";\n@fa-var-angle-right: \"\\f105\";\n@fa-var-angle-up: \"\\f106\";\n@fa-var-apple: \"\\f179\";\n@fa-var-archive: \"\\f187\";\n@fa-var-area-chart: \"\\f1fe\";\n@fa-var-arrow-circle-down: \"\\f0ab\";\n@fa-var-arrow-circle-left: \"\\f0a8\";\n@fa-var-arrow-circle-o-down: \"\\f01a\";\n@fa-var-arrow-circle-o-left: \"\\f190\";\n@fa-var-arrow-circle-o-right: \"\\f18e\";\n@fa-var-arrow-circle-o-up: \"\\f01b\";\n@fa-var-arrow-circle-right: \"\\f0a9\";\n@fa-var-arrow-circle-up: \"\\f0aa\";\n@fa-var-arrow-down: \"\\f063\";\n@fa-var-arrow-left: \"\\f060\";\n@fa-var-arrow-right: \"\\f061\";\n@fa-var-arrow-up: \"\\f062\";\n@fa-var-arrows: \"\\f047\";\n@fa-var-arrows-alt: \"\\f0b2\";\n@fa-var-arrows-h: \"\\f07e\";\n@fa-var-arrows-v: \"\\f07d\";\n@fa-var-asl-interpreting: \"\\f2a3\";\n@fa-var-assistive-listening-systems: \"\\f2a2\";\n@fa-var-asterisk: \"\\f069\";\n@fa-var-at: \"\\f1fa\";\n@fa-var-audio-description: \"\\f29e\";\n@fa-var-automobile: \"\\f1b9\";\n@fa-var-backward: \"\\f04a\";\n@fa-var-balance-scale: \"\\f24e\";\n@fa-var-ban: \"\\f05e\";\n@fa-var-bank: \"\\f19c\";\n@fa-var-bar-chart: \"\\f080\";\n@fa-var-bar-chart-o: \"\\f080\";\n@fa-var-barcode: \"\\f02a\";\n@fa-var-bars: \"\\f0c9\";\n@fa-var-battery-0: \"\\f244\";\n@fa-var-battery-1: \"\\f243\";\n@fa-var-battery-2: \"\\f242\";\n@fa-var-battery-3: \"\\f241\";\n@fa-var-battery-4: \"\\f240\";\n@fa-var-battery-empty: \"\\f244\";\n@fa-var-battery-full: \"\\f240\";\n@fa-var-battery-half: \"\\f242\";\n@fa-var-battery-quarter: \"\\f243\";\n@fa-var-battery-three-quarters: \"\\f241\";\n@fa-var-bed: \"\\f236\";\n@fa-var-beer: \"\\f0fc\";\n@fa-var-behance: \"\\f1b4\";\n@fa-var-behance-square: \"\\f1b5\";\n@fa-var-bell: \"\\f0f3\";\n@fa-var-bell-o: \"\\f0a2\";\n@fa-var-bell-slash: \"\\f1f6\";\n@fa-var-bell-slash-o: \"\\f1f7\";\n@fa-var-bicycle: \"\\f206\";\n@fa-var-binoculars: \"\\f1e5\";\n@fa-var-birthday-cake: \"\\f1fd\";\n@fa-var-bitbucket: \"\\f171\";\n@fa-var-bitbucket-square: \"\\f172\";\n@fa-var-bitcoin: \"\\f15a\";\n@fa-var-black-tie: \"\\f27e\";\n@fa-var-blind: \"\\f29d\";\n@fa-var-bluetooth: \"\\f293\";\n@fa-var-bluetooth-b: \"\\f294\";\n@fa-var-bold: \"\\f032\";\n@fa-var-bolt: \"\\f0e7\";\n@fa-var-bomb: \"\\f1e2\";\n@fa-var-book: \"\\f02d\";\n@fa-var-bookmark: \"\\f02e\";\n@fa-var-bookmark-o: \"\\f097\";\n@fa-var-braille: \"\\f2a1\";\n@fa-var-briefcase: \"\\f0b1\";\n@fa-var-btc: \"\\f15a\";\n@fa-var-bug: \"\\f188\";\n@fa-var-building: \"\\f1ad\";\n@fa-var-building-o: \"\\f0f7\";\n@fa-var-bullhorn: \"\\f0a1\";\n@fa-var-bullseye: \"\\f140\";\n@fa-var-bus: \"\\f207\";\n@fa-var-buysellads: \"\\f20d\";\n@fa-var-cab: \"\\f1ba\";\n@fa-var-calculator: \"\\f1ec\";\n@fa-var-calendar: \"\\f073\";\n@fa-var-calendar-check-o: \"\\f274\";\n@fa-var-calendar-minus-o: \"\\f272\";\n@fa-var-calendar-o: \"\\f133\";\n@fa-var-calendar-plus-o: \"\\f271\";\n@fa-var-calendar-times-o: \"\\f273\";\n@fa-var-camera: \"\\f030\";\n@fa-var-camera-retro: \"\\f083\";\n@fa-var-car: \"\\f1b9\";\n@fa-var-caret-down: \"\\f0d7\";\n@fa-var-caret-left: \"\\f0d9\";\n@fa-var-caret-right: \"\\f0da\";\n@fa-var-caret-square-o-down: \"\\f150\";\n@fa-var-caret-square-o-left: \"\\f191\";\n@fa-var-caret-square-o-right: \"\\f152\";\n@fa-var-caret-square-o-up: \"\\f151\";\n@fa-var-caret-up: \"\\f0d8\";\n@fa-var-cart-arrow-down: \"\\f218\";\n@fa-var-cart-plus: \"\\f217\";\n@fa-var-cc: \"\\f20a\";\n@fa-var-cc-amex: \"\\f1f3\";\n@fa-var-cc-diners-club: \"\\f24c\";\n@fa-var-cc-discover: \"\\f1f2\";\n@fa-var-cc-jcb: \"\\f24b\";\n@fa-var-cc-mastercard: \"\\f1f1\";\n@fa-var-cc-paypal: \"\\f1f4\";\n@fa-var-cc-stripe: \"\\f1f5\";\n@fa-var-cc-visa: \"\\f1f0\";\n@fa-var-certificate: \"\\f0a3\";\n@fa-var-chain: \"\\f0c1\";\n@fa-var-chain-broken: \"\\f127\";\n@fa-var-check: \"\\f00c\";\n@fa-var-check-circle: \"\\f058\";\n@fa-var-check-circle-o: \"\\f05d\";\n@fa-var-check-square: \"\\f14a\";\n@fa-var-check-square-o: \"\\f046\";\n@fa-var-chevron-circle-down: \"\\f13a\";\n@fa-var-chevron-circle-left: \"\\f137\";\n@fa-var-chevron-circle-right: \"\\f138\";\n@fa-var-chevron-circle-up: \"\\f139\";\n@fa-var-chevron-down: \"\\f078\";\n@fa-var-chevron-left: \"\\f053\";\n@fa-var-chevron-right: \"\\f054\";\n@fa-var-chevron-up: \"\\f077\";\n@fa-var-child: \"\\f1ae\";\n@fa-var-chrome: \"\\f268\";\n@fa-var-circle: \"\\f111\";\n@fa-var-circle-o: \"\\f10c\";\n@fa-var-circle-o-notch: \"\\f1ce\";\n@fa-var-circle-thin: \"\\f1db\";\n@fa-var-clipboard: \"\\f0ea\";\n@fa-var-clock-o: \"\\f017\";\n@fa-var-clone: \"\\f24d\";\n@fa-var-close: \"\\f00d\";\n@fa-var-cloud: \"\\f0c2\";\n@fa-var-cloud-download: \"\\f0ed\";\n@fa-var-cloud-upload: \"\\f0ee\";\n@fa-var-cny: \"\\f157\";\n@fa-var-code: \"\\f121\";\n@fa-var-code-fork: \"\\f126\";\n@fa-var-codepen: \"\\f1cb\";\n@fa-var-codiepie: \"\\f284\";\n@fa-var-coffee: \"\\f0f4\";\n@fa-var-cog: \"\\f013\";\n@fa-var-cogs: \"\\f085\";\n@fa-var-columns: \"\\f0db\";\n@fa-var-comment: \"\\f075\";\n@fa-var-comment-o: \"\\f0e5\";\n@fa-var-commenting: \"\\f27a\";\n@fa-var-commenting-o: \"\\f27b\";\n@fa-var-comments: \"\\f086\";\n@fa-var-comments-o: \"\\f0e6\";\n@fa-var-compass: \"\\f14e\";\n@fa-var-compress: \"\\f066\";\n@fa-var-connectdevelop: \"\\f20e\";\n@fa-var-contao: \"\\f26d\";\n@fa-var-copy: \"\\f0c5\";\n@fa-var-copyright: \"\\f1f9\";\n@fa-var-creative-commons: \"\\f25e\";\n@fa-var-credit-card: \"\\f09d\";\n@fa-var-credit-card-alt: \"\\f283\";\n@fa-var-crop: \"\\f125\";\n@fa-var-crosshairs: \"\\f05b\";\n@fa-var-css3: \"\\f13c\";\n@fa-var-cube: \"\\f1b2\";\n@fa-var-cubes: \"\\f1b3\";\n@fa-var-cut: \"\\f0c4\";\n@fa-var-cutlery: \"\\f0f5\";\n@fa-var-dashboard: \"\\f0e4\";\n@fa-var-dashcube: \"\\f210\";\n@fa-var-database: \"\\f1c0\";\n@fa-var-deaf: \"\\f2a4\";\n@fa-var-deafness: \"\\f2a4\";\n@fa-var-dedent: \"\\f03b\";\n@fa-var-delicious: \"\\f1a5\";\n@fa-var-desktop: \"\\f108\";\n@fa-var-deviantart: \"\\f1bd\";\n@fa-var-diamond: \"\\f219\";\n@fa-var-digg: \"\\f1a6\";\n@fa-var-dollar: \"\\f155\";\n@fa-var-dot-circle-o: \"\\f192\";\n@fa-var-download: \"\\f019\";\n@fa-var-dribbble: \"\\f17d\";\n@fa-var-dropbox: \"\\f16b\";\n@fa-var-drupal: \"\\f1a9\";\n@fa-var-edge: \"\\f282\";\n@fa-var-edit: \"\\f044\";\n@fa-var-eject: \"\\f052\";\n@fa-var-ellipsis-h: \"\\f141\";\n@fa-var-ellipsis-v: \"\\f142\";\n@fa-var-empire: \"\\f1d1\";\n@fa-var-envelope: \"\\f0e0\";\n@fa-var-envelope-o: \"\\f003\";\n@fa-var-envelope-square: \"\\f199\";\n@fa-var-envira: \"\\f299\";\n@fa-var-eraser: \"\\f12d\";\n@fa-var-eur: \"\\f153\";\n@fa-var-euro: \"\\f153\";\n@fa-var-exchange: \"\\f0ec\";\n@fa-var-exclamation: \"\\f12a\";\n@fa-var-exclamation-circle: \"\\f06a\";\n@fa-var-exclamation-triangle: \"\\f071\";\n@fa-var-expand: \"\\f065\";\n@fa-var-expeditedssl: \"\\f23e\";\n@fa-var-external-link: \"\\f08e\";\n@fa-var-external-link-square: \"\\f14c\";\n@fa-var-eye: \"\\f06e\";\n@fa-var-eye-slash: \"\\f070\";\n@fa-var-eyedropper: \"\\f1fb\";\n@fa-var-fa: \"\\f2b4\";\n@fa-var-facebook: \"\\f09a\";\n@fa-var-facebook-f: \"\\f09a\";\n@fa-var-facebook-official: \"\\f230\";\n@fa-var-facebook-square: \"\\f082\";\n@fa-var-fast-backward: \"\\f049\";\n@fa-var-fast-forward: \"\\f050\";\n@fa-var-fax: \"\\f1ac\";\n@fa-var-feed: \"\\f09e\";\n@fa-var-female: \"\\f182\";\n@fa-var-fighter-jet: \"\\f0fb\";\n@fa-var-file: \"\\f15b\";\n@fa-var-file-archive-o: \"\\f1c6\";\n@fa-var-file-audio-o: \"\\f1c7\";\n@fa-var-file-code-o: \"\\f1c9\";\n@fa-var-file-excel-o: \"\\f1c3\";\n@fa-var-file-image-o: \"\\f1c5\";\n@fa-var-file-movie-o: \"\\f1c8\";\n@fa-var-file-o: \"\\f016\";\n@fa-var-file-pdf-o: \"\\f1c1\";\n@fa-var-file-photo-o: \"\\f1c5\";\n@fa-var-file-picture-o: \"\\f1c5\";\n@fa-var-file-powerpoint-o: \"\\f1c4\";\n@fa-var-file-sound-o: \"\\f1c7\";\n@fa-var-file-text: \"\\f15c\";\n@fa-var-file-text-o: \"\\f0f6\";\n@fa-var-file-video-o: \"\\f1c8\";\n@fa-var-file-word-o: \"\\f1c2\";\n@fa-var-file-zip-o: \"\\f1c6\";\n@fa-var-files-o: \"\\f0c5\";\n@fa-var-film: \"\\f008\";\n@fa-var-filter: \"\\f0b0\";\n@fa-var-fire: \"\\f06d\";\n@fa-var-fire-extinguisher: \"\\f134\";\n@fa-var-firefox: \"\\f269\";\n@fa-var-first-order: \"\\f2b0\";\n@fa-var-flag: \"\\f024\";\n@fa-var-flag-checkered: \"\\f11e\";\n@fa-var-flag-o: \"\\f11d\";\n@fa-var-flash: \"\\f0e7\";\n@fa-var-flask: \"\\f0c3\";\n@fa-var-flickr: \"\\f16e\";\n@fa-var-floppy-o: \"\\f0c7\";\n@fa-var-folder: \"\\f07b\";\n@fa-var-folder-o: \"\\f114\";\n@fa-var-folder-open: \"\\f07c\";\n@fa-var-folder-open-o: \"\\f115\";\n@fa-var-font: \"\\f031\";\n@fa-var-font-awesome: \"\\f2b4\";\n@fa-var-fonticons: \"\\f280\";\n@fa-var-fort-awesome: \"\\f286\";\n@fa-var-forumbee: \"\\f211\";\n@fa-var-forward: \"\\f04e\";\n@fa-var-foursquare: \"\\f180\";\n@fa-var-frown-o: \"\\f119\";\n@fa-var-futbol-o: \"\\f1e3\";\n@fa-var-gamepad: \"\\f11b\";\n@fa-var-gavel: \"\\f0e3\";\n@fa-var-gbp: \"\\f154\";\n@fa-var-ge: \"\\f1d1\";\n@fa-var-gear: \"\\f013\";\n@fa-var-gears: \"\\f085\";\n@fa-var-genderless: \"\\f22d\";\n@fa-var-get-pocket: \"\\f265\";\n@fa-var-gg: \"\\f260\";\n@fa-var-gg-circle: \"\\f261\";\n@fa-var-gift: \"\\f06b\";\n@fa-var-git: \"\\f1d3\";\n@fa-var-git-square: \"\\f1d2\";\n@fa-var-github: \"\\f09b\";\n@fa-var-github-alt: \"\\f113\";\n@fa-var-github-square: \"\\f092\";\n@fa-var-gitlab: \"\\f296\";\n@fa-var-gittip: \"\\f184\";\n@fa-var-glass: \"\\f000\";\n@fa-var-glide: \"\\f2a5\";\n@fa-var-glide-g: \"\\f2a6\";\n@fa-var-globe: \"\\f0ac\";\n@fa-var-google: \"\\f1a0\";\n@fa-var-google-plus: \"\\f0d5\";\n@fa-var-google-plus-circle: \"\\f2b3\";\n@fa-var-google-plus-official: \"\\f2b3\";\n@fa-var-google-plus-square: \"\\f0d4\";\n@fa-var-google-wallet: \"\\f1ee\";\n@fa-var-graduation-cap: \"\\f19d\";\n@fa-var-gratipay: \"\\f184\";\n@fa-var-group: \"\\f0c0\";\n@fa-var-h-square: \"\\f0fd\";\n@fa-var-hacker-news: \"\\f1d4\";\n@fa-var-hand-grab-o: \"\\f255\";\n@fa-var-hand-lizard-o: \"\\f258\";\n@fa-var-hand-o-down: \"\\f0a7\";\n@fa-var-hand-o-left: \"\\f0a5\";\n@fa-var-hand-o-right: \"\\f0a4\";\n@fa-var-hand-o-up: \"\\f0a6\";\n@fa-var-hand-paper-o: \"\\f256\";\n@fa-var-hand-peace-o: \"\\f25b\";\n@fa-var-hand-pointer-o: \"\\f25a\";\n@fa-var-hand-rock-o: \"\\f255\";\n@fa-var-hand-scissors-o: \"\\f257\";\n@fa-var-hand-spock-o: \"\\f259\";\n@fa-var-hand-stop-o: \"\\f256\";\n@fa-var-hard-of-hearing: \"\\f2a4\";\n@fa-var-hashtag: \"\\f292\";\n@fa-var-hdd-o: \"\\f0a0\";\n@fa-var-header: \"\\f1dc\";\n@fa-var-headphones: \"\\f025\";\n@fa-var-heart: \"\\f004\";\n@fa-var-heart-o: \"\\f08a\";\n@fa-var-heartbeat: \"\\f21e\";\n@fa-var-history: \"\\f1da\";\n@fa-var-home: \"\\f015\";\n@fa-var-hospital-o: \"\\f0f8\";\n@fa-var-hotel: \"\\f236\";\n@fa-var-hourglass: \"\\f254\";\n@fa-var-hourglass-1: \"\\f251\";\n@fa-var-hourglass-2: \"\\f252\";\n@fa-var-hourglass-3: \"\\f253\";\n@fa-var-hourglass-end: \"\\f253\";\n@fa-var-hourglass-half: \"\\f252\";\n@fa-var-hourglass-o: \"\\f250\";\n@fa-var-hourglass-start: \"\\f251\";\n@fa-var-houzz: \"\\f27c\";\n@fa-var-html5: \"\\f13b\";\n@fa-var-i-cursor: \"\\f246\";\n@fa-var-ils: \"\\f20b\";\n@fa-var-image: \"\\f03e\";\n@fa-var-inbox: \"\\f01c\";\n@fa-var-indent: \"\\f03c\";\n@fa-var-industry: \"\\f275\";\n@fa-var-info: \"\\f129\";\n@fa-var-info-circle: \"\\f05a\";\n@fa-var-inr: \"\\f156\";\n@fa-var-instagram: \"\\f16d\";\n@fa-var-institution: \"\\f19c\";\n@fa-var-internet-explorer: \"\\f26b\";\n@fa-var-intersex: \"\\f224\";\n@fa-var-ioxhost: \"\\f208\";\n@fa-var-italic: \"\\f033\";\n@fa-var-joomla: \"\\f1aa\";\n@fa-var-jpy: \"\\f157\";\n@fa-var-jsfiddle: \"\\f1cc\";\n@fa-var-key: \"\\f084\";\n@fa-var-keyboard-o: \"\\f11c\";\n@fa-var-krw: \"\\f159\";\n@fa-var-language: \"\\f1ab\";\n@fa-var-laptop: \"\\f109\";\n@fa-var-lastfm: \"\\f202\";\n@fa-var-lastfm-square: \"\\f203\";\n@fa-var-leaf: \"\\f06c\";\n@fa-var-leanpub: \"\\f212\";\n@fa-var-legal: \"\\f0e3\";\n@fa-var-lemon-o: \"\\f094\";\n@fa-var-level-down: \"\\f149\";\n@fa-var-level-up: \"\\f148\";\n@fa-var-life-bouy: \"\\f1cd\";\n@fa-var-life-buoy: \"\\f1cd\";\n@fa-var-life-ring: \"\\f1cd\";\n@fa-var-life-saver: \"\\f1cd\";\n@fa-var-lightbulb-o: \"\\f0eb\";\n@fa-var-line-chart: \"\\f201\";\n@fa-var-link: \"\\f0c1\";\n@fa-var-linkedin: \"\\f0e1\";\n@fa-var-linkedin-square: \"\\f08c\";\n@fa-var-linux: \"\\f17c\";\n@fa-var-list: \"\\f03a\";\n@fa-var-list-alt: \"\\f022\";\n@fa-var-list-ol: \"\\f0cb\";\n@fa-var-list-ul: \"\\f0ca\";\n@fa-var-location-arrow: \"\\f124\";\n@fa-var-lock: \"\\f023\";\n@fa-var-long-arrow-down: \"\\f175\";\n@fa-var-long-arrow-left: \"\\f177\";\n@fa-var-long-arrow-right: \"\\f178\";\n@fa-var-long-arrow-up: \"\\f176\";\n@fa-var-low-vision: \"\\f2a8\";\n@fa-var-magic: \"\\f0d0\";\n@fa-var-magnet: \"\\f076\";\n@fa-var-mail-forward: \"\\f064\";\n@fa-var-mail-reply: \"\\f112\";\n@fa-var-mail-reply-all: \"\\f122\";\n@fa-var-male: \"\\f183\";\n@fa-var-map: \"\\f279\";\n@fa-var-map-marker: \"\\f041\";\n@fa-var-map-o: \"\\f278\";\n@fa-var-map-pin: \"\\f276\";\n@fa-var-map-signs: \"\\f277\";\n@fa-var-mars: \"\\f222\";\n@fa-var-mars-double: \"\\f227\";\n@fa-var-mars-stroke: \"\\f229\";\n@fa-var-mars-stroke-h: \"\\f22b\";\n@fa-var-mars-stroke-v: \"\\f22a\";\n@fa-var-maxcdn: \"\\f136\";\n@fa-var-meanpath: \"\\f20c\";\n@fa-var-medium: \"\\f23a\";\n@fa-var-medkit: \"\\f0fa\";\n@fa-var-meh-o: \"\\f11a\";\n@fa-var-mercury: \"\\f223\";\n@fa-var-microphone: \"\\f130\";\n@fa-var-microphone-slash: \"\\f131\";\n@fa-var-minus: \"\\f068\";\n@fa-var-minus-circle: \"\\f056\";\n@fa-var-minus-square: \"\\f146\";\n@fa-var-minus-square-o: \"\\f147\";\n@fa-var-mixcloud: \"\\f289\";\n@fa-var-mobile: \"\\f10b\";\n@fa-var-mobile-phone: \"\\f10b\";\n@fa-var-modx: \"\\f285\";\n@fa-var-money: \"\\f0d6\";\n@fa-var-moon-o: \"\\f186\";\n@fa-var-mortar-board: \"\\f19d\";\n@fa-var-motorcycle: \"\\f21c\";\n@fa-var-mouse-pointer: \"\\f245\";\n@fa-var-music: \"\\f001\";\n@fa-var-navicon: \"\\f0c9\";\n@fa-var-neuter: \"\\f22c\";\n@fa-var-newspaper-o: \"\\f1ea\";\n@fa-var-object-group: \"\\f247\";\n@fa-var-object-ungroup: \"\\f248\";\n@fa-var-odnoklassniki: \"\\f263\";\n@fa-var-odnoklassniki-square: \"\\f264\";\n@fa-var-opencart: \"\\f23d\";\n@fa-var-openid: \"\\f19b\";\n@fa-var-opera: \"\\f26a\";\n@fa-var-optin-monster: \"\\f23c\";\n@fa-var-outdent: \"\\f03b\";\n@fa-var-pagelines: \"\\f18c\";\n@fa-var-paint-brush: \"\\f1fc\";\n@fa-var-paper-plane: \"\\f1d8\";\n@fa-var-paper-plane-o: \"\\f1d9\";\n@fa-var-paperclip: \"\\f0c6\";\n@fa-var-paragraph: \"\\f1dd\";\n@fa-var-paste: \"\\f0ea\";\n@fa-var-pause: \"\\f04c\";\n@fa-var-pause-circle: \"\\f28b\";\n@fa-var-pause-circle-o: \"\\f28c\";\n@fa-var-paw: \"\\f1b0\";\n@fa-var-paypal: \"\\f1ed\";\n@fa-var-pencil: \"\\f040\";\n@fa-var-pencil-square: \"\\f14b\";\n@fa-var-pencil-square-o: \"\\f044\";\n@fa-var-percent: \"\\f295\";\n@fa-var-phone: \"\\f095\";\n@fa-var-phone-square: \"\\f098\";\n@fa-var-photo: \"\\f03e\";\n@fa-var-picture-o: \"\\f03e\";\n@fa-var-pie-chart: \"\\f200\";\n@fa-var-pied-piper: \"\\f2ae\";\n@fa-var-pied-piper-alt: \"\\f1a8\";\n@fa-var-pied-piper-pp: \"\\f1a7\";\n@fa-var-pinterest: \"\\f0d2\";\n@fa-var-pinterest-p: \"\\f231\";\n@fa-var-pinterest-square: \"\\f0d3\";\n@fa-var-plane: \"\\f072\";\n@fa-var-play: \"\\f04b\";\n@fa-var-play-circle: \"\\f144\";\n@fa-var-play-circle-o: \"\\f01d\";\n@fa-var-plug: \"\\f1e6\";\n@fa-var-plus: \"\\f067\";\n@fa-var-plus-circle: \"\\f055\";\n@fa-var-plus-square: \"\\f0fe\";\n@fa-var-plus-square-o: \"\\f196\";\n@fa-var-power-off: \"\\f011\";\n@fa-var-print: \"\\f02f\";\n@fa-var-product-hunt: \"\\f288\";\n@fa-var-puzzle-piece: \"\\f12e\";\n@fa-var-qq: \"\\f1d6\";\n@fa-var-qrcode: \"\\f029\";\n@fa-var-question: \"\\f128\";\n@fa-var-question-circle: \"\\f059\";\n@fa-var-question-circle-o: \"\\f29c\";\n@fa-var-quote-left: \"\\f10d\";\n@fa-var-quote-right: \"\\f10e\";\n@fa-var-ra: \"\\f1d0\";\n@fa-var-random: \"\\f074\";\n@fa-var-rebel: \"\\f1d0\";\n@fa-var-recycle: \"\\f1b8\";\n@fa-var-reddit: \"\\f1a1\";\n@fa-var-reddit-alien: \"\\f281\";\n@fa-var-reddit-square: \"\\f1a2\";\n@fa-var-refresh: \"\\f021\";\n@fa-var-registered: \"\\f25d\";\n@fa-var-remove: \"\\f00d\";\n@fa-var-renren: \"\\f18b\";\n@fa-var-reorder: \"\\f0c9\";\n@fa-var-repeat: \"\\f01e\";\n@fa-var-reply: \"\\f112\";\n@fa-var-reply-all: \"\\f122\";\n@fa-var-resistance: \"\\f1d0\";\n@fa-var-retweet: \"\\f079\";\n@fa-var-rmb: \"\\f157\";\n@fa-var-road: \"\\f018\";\n@fa-var-rocket: \"\\f135\";\n@fa-var-rotate-left: \"\\f0e2\";\n@fa-var-rotate-right: \"\\f01e\";\n@fa-var-rouble: \"\\f158\";\n@fa-var-rss: \"\\f09e\";\n@fa-var-rss-square: \"\\f143\";\n@fa-var-rub: \"\\f158\";\n@fa-var-ruble: \"\\f158\";\n@fa-var-rupee: \"\\f156\";\n@fa-var-safari: \"\\f267\";\n@fa-var-save: \"\\f0c7\";\n@fa-var-scissors: \"\\f0c4\";\n@fa-var-scribd: \"\\f28a\";\n@fa-var-search: \"\\f002\";\n@fa-var-search-minus: \"\\f010\";\n@fa-var-search-plus: \"\\f00e\";\n@fa-var-sellsy: \"\\f213\";\n@fa-var-send: \"\\f1d8\";\n@fa-var-send-o: \"\\f1d9\";\n@fa-var-server: \"\\f233\";\n@fa-var-share: \"\\f064\";\n@fa-var-share-alt: \"\\f1e0\";\n@fa-var-share-alt-square: \"\\f1e1\";\n@fa-var-share-square: \"\\f14d\";\n@fa-var-share-square-o: \"\\f045\";\n@fa-var-shekel: \"\\f20b\";\n@fa-var-sheqel: \"\\f20b\";\n@fa-var-shield: \"\\f132\";\n@fa-var-ship: \"\\f21a\";\n@fa-var-shirtsinbulk: \"\\f214\";\n@fa-var-shopping-bag: \"\\f290\";\n@fa-var-shopping-basket: \"\\f291\";\n@fa-var-shopping-cart: \"\\f07a\";\n@fa-var-sign-in: \"\\f090\";\n@fa-var-sign-language: \"\\f2a7\";\n@fa-var-sign-out: \"\\f08b\";\n@fa-var-signal: \"\\f012\";\n@fa-var-signing: \"\\f2a7\";\n@fa-var-simplybuilt: \"\\f215\";\n@fa-var-sitemap: \"\\f0e8\";\n@fa-var-skyatlas: \"\\f216\";\n@fa-var-skype: \"\\f17e\";\n@fa-var-slack: \"\\f198\";\n@fa-var-sliders: \"\\f1de\";\n@fa-var-slideshare: \"\\f1e7\";\n@fa-var-smile-o: \"\\f118\";\n@fa-var-snapchat: \"\\f2ab\";\n@fa-var-snapchat-ghost: \"\\f2ac\";\n@fa-var-snapchat-square: \"\\f2ad\";\n@fa-var-soccer-ball-o: \"\\f1e3\";\n@fa-var-sort: \"\\f0dc\";\n@fa-var-sort-alpha-asc: \"\\f15d\";\n@fa-var-sort-alpha-desc: \"\\f15e\";\n@fa-var-sort-amount-asc: \"\\f160\";\n@fa-var-sort-amount-desc: \"\\f161\";\n@fa-var-sort-asc: \"\\f0de\";\n@fa-var-sort-desc: \"\\f0dd\";\n@fa-var-sort-down: \"\\f0dd\";\n@fa-var-sort-numeric-asc: \"\\f162\";\n@fa-var-sort-numeric-desc: \"\\f163\";\n@fa-var-sort-up: \"\\f0de\";\n@fa-var-soundcloud: \"\\f1be\";\n@fa-var-space-shuttle: \"\\f197\";\n@fa-var-spinner: \"\\f110\";\n@fa-var-spoon: \"\\f1b1\";\n@fa-var-spotify: \"\\f1bc\";\n@fa-var-square: \"\\f0c8\";\n@fa-var-square-o: \"\\f096\";\n@fa-var-stack-exchange: \"\\f18d\";\n@fa-var-stack-overflow: \"\\f16c\";\n@fa-var-star: \"\\f005\";\n@fa-var-star-half: \"\\f089\";\n@fa-var-star-half-empty: \"\\f123\";\n@fa-var-star-half-full: \"\\f123\";\n@fa-var-star-half-o: \"\\f123\";\n@fa-var-star-o: \"\\f006\";\n@fa-var-steam: \"\\f1b6\";\n@fa-var-steam-square: \"\\f1b7\";\n@fa-var-step-backward: \"\\f048\";\n@fa-var-step-forward: \"\\f051\";\n@fa-var-stethoscope: \"\\f0f1\";\n@fa-var-sticky-note: \"\\f249\";\n@fa-var-sticky-note-o: \"\\f24a\";\n@fa-var-stop: \"\\f04d\";\n@fa-var-stop-circle: \"\\f28d\";\n@fa-var-stop-circle-o: \"\\f28e\";\n@fa-var-street-view: \"\\f21d\";\n@fa-var-strikethrough: \"\\f0cc\";\n@fa-var-stumbleupon: \"\\f1a4\";\n@fa-var-stumbleupon-circle: \"\\f1a3\";\n@fa-var-subscript: \"\\f12c\";\n@fa-var-subway: \"\\f239\";\n@fa-var-suitcase: \"\\f0f2\";\n@fa-var-sun-o: \"\\f185\";\n@fa-var-superscript: \"\\f12b\";\n@fa-var-support: \"\\f1cd\";\n@fa-var-table: \"\\f0ce\";\n@fa-var-tablet: \"\\f10a\";\n@fa-var-tachometer: \"\\f0e4\";\n@fa-var-tag: \"\\f02b\";\n@fa-var-tags: \"\\f02c\";\n@fa-var-tasks: \"\\f0ae\";\n@fa-var-taxi: \"\\f1ba\";\n@fa-var-television: \"\\f26c\";\n@fa-var-tencent-weibo: \"\\f1d5\";\n@fa-var-terminal: \"\\f120\";\n@fa-var-text-height: \"\\f034\";\n@fa-var-text-width: \"\\f035\";\n@fa-var-th: \"\\f00a\";\n@fa-var-th-large: \"\\f009\";\n@fa-var-th-list: \"\\f00b\";\n@fa-var-themeisle: \"\\f2b2\";\n@fa-var-thumb-tack: \"\\f08d\";\n@fa-var-thumbs-down: \"\\f165\";\n@fa-var-thumbs-o-down: \"\\f088\";\n@fa-var-thumbs-o-up: \"\\f087\";\n@fa-var-thumbs-up: \"\\f164\";\n@fa-var-ticket: \"\\f145\";\n@fa-var-times: \"\\f00d\";\n@fa-var-times-circle: \"\\f057\";\n@fa-var-times-circle-o: \"\\f05c\";\n@fa-var-tint: \"\\f043\";\n@fa-var-toggle-down: \"\\f150\";\n@fa-var-toggle-left: \"\\f191\";\n@fa-var-toggle-off: \"\\f204\";\n@fa-var-toggle-on: \"\\f205\";\n@fa-var-toggle-right: \"\\f152\";\n@fa-var-toggle-up: \"\\f151\";\n@fa-var-trademark: \"\\f25c\";\n@fa-var-train: \"\\f238\";\n@fa-var-transgender: \"\\f224\";\n@fa-var-transgender-alt: \"\\f225\";\n@fa-var-trash: \"\\f1f8\";\n@fa-var-trash-o: \"\\f014\";\n@fa-var-tree: \"\\f1bb\";\n@fa-var-trello: \"\\f181\";\n@fa-var-tripadvisor: \"\\f262\";\n@fa-var-trophy: \"\\f091\";\n@fa-var-truck: \"\\f0d1\";\n@fa-var-try: \"\\f195\";\n@fa-var-tty: \"\\f1e4\";\n@fa-var-tumblr: \"\\f173\";\n@fa-var-tumblr-square: \"\\f174\";\n@fa-var-turkish-lira: \"\\f195\";\n@fa-var-tv: \"\\f26c\";\n@fa-var-twitch: \"\\f1e8\";\n@fa-var-twitter: \"\\f099\";\n@fa-var-twitter-square: \"\\f081\";\n@fa-var-umbrella: \"\\f0e9\";\n@fa-var-underline: \"\\f0cd\";\n@fa-var-undo: \"\\f0e2\";\n@fa-var-universal-access: \"\\f29a\";\n@fa-var-university: \"\\f19c\";\n@fa-var-unlink: \"\\f127\";\n@fa-var-unlock: \"\\f09c\";\n@fa-var-unlock-alt: \"\\f13e\";\n@fa-var-unsorted: \"\\f0dc\";\n@fa-var-upload: \"\\f093\";\n@fa-var-usb: \"\\f287\";\n@fa-var-usd: \"\\f155\";\n@fa-var-user: \"\\f007\";\n@fa-var-user-md: \"\\f0f0\";\n@fa-var-user-plus: \"\\f234\";\n@fa-var-user-secret: \"\\f21b\";\n@fa-var-user-times: \"\\f235\";\n@fa-var-users: \"\\f0c0\";\n@fa-var-venus: \"\\f221\";\n@fa-var-venus-double: \"\\f226\";\n@fa-var-venus-mars: \"\\f228\";\n@fa-var-viacoin: \"\\f237\";\n@fa-var-viadeo: \"\\f2a9\";\n@fa-var-viadeo-square: \"\\f2aa\";\n@fa-var-video-camera: \"\\f03d\";\n@fa-var-vimeo: \"\\f27d\";\n@fa-var-vimeo-square: \"\\f194\";\n@fa-var-vine: \"\\f1ca\";\n@fa-var-vk: \"\\f189\";\n@fa-var-volume-control-phone: \"\\f2a0\";\n@fa-var-volume-down: \"\\f027\";\n@fa-var-volume-off: \"\\f026\";\n@fa-var-volume-up: \"\\f028\";\n@fa-var-warning: \"\\f071\";\n@fa-var-wechat: \"\\f1d7\";\n@fa-var-weibo: \"\\f18a\";\n@fa-var-weixin: \"\\f1d7\";\n@fa-var-whatsapp: \"\\f232\";\n@fa-var-wheelchair: \"\\f193\";\n@fa-var-wheelchair-alt: \"\\f29b\";\n@fa-var-wifi: \"\\f1eb\";\n@fa-var-wikipedia-w: \"\\f266\";\n@fa-var-windows: \"\\f17a\";\n@fa-var-won: \"\\f159\";\n@fa-var-wordpress: \"\\f19a\";\n@fa-var-wpbeginner: \"\\f297\";\n@fa-var-wpforms: \"\\f298\";\n@fa-var-wrench: \"\\f0ad\";\n@fa-var-xing: \"\\f168\";\n@fa-var-xing-square: \"\\f169\";\n@fa-var-y-combinator: \"\\f23b\";\n@fa-var-y-combinator-square: \"\\f1d4\";\n@fa-var-yahoo: \"\\f19e\";\n@fa-var-yc: \"\\f23b\";\n@fa-var-yc-square: \"\\f1d4\";\n@fa-var-yelp: \"\\f1e9\";\n@fa-var-yen: \"\\f157\";\n@fa-var-yoast: \"\\f2b1\";\n@fa-var-youtube: \"\\f167\";\n@fa-var-youtube-play: \"\\f16a\";\n@fa-var-youtube-square: \"\\f166\";\n\n"
  },
  {
    "path": "app_backend/static/plugin/font-awesome/scss/_animated.scss",
    "content": "// Spinning Icons\n// --------------------------\n\n.#{$fa-css-prefix}-spin {\n  -webkit-animation: fa-spin 2s infinite linear;\n          animation: fa-spin 2s infinite linear;\n}\n\n.#{$fa-css-prefix}-pulse {\n  -webkit-animation: fa-spin 1s infinite steps(8);\n          animation: fa-spin 1s infinite steps(8);\n}\n\n@-webkit-keyframes fa-spin {\n  0% {\n    -webkit-transform: rotate(0deg);\n            transform: rotate(0deg);\n  }\n  100% {\n    -webkit-transform: rotate(359deg);\n            transform: rotate(359deg);\n  }\n}\n\n@keyframes fa-spin {\n  0% {\n    -webkit-transform: rotate(0deg);\n            transform: rotate(0deg);\n  }\n  100% {\n    -webkit-transform: rotate(359deg);\n            transform: rotate(359deg);\n  }\n}\n"
  },
  {
    "path": "app_backend/static/plugin/font-awesome/scss/_bordered-pulled.scss",
    "content": "// Bordered & Pulled\n// -------------------------\n\n.#{$fa-css-prefix}-border {\n  padding: .2em .25em .15em;\n  border: solid .08em $fa-border-color;\n  border-radius: .1em;\n}\n\n.#{$fa-css-prefix}-pull-left { float: left; }\n.#{$fa-css-prefix}-pull-right { float: right; }\n\n.#{$fa-css-prefix} {\n  &.#{$fa-css-prefix}-pull-left { margin-right: .3em; }\n  &.#{$fa-css-prefix}-pull-right { margin-left: .3em; }\n}\n\n/* Deprecated as of 4.4.0 */\n.pull-right { float: right; }\n.pull-left { float: left; }\n\n.#{$fa-css-prefix} {\n  &.pull-left { margin-right: .3em; }\n  &.pull-right { margin-left: .3em; }\n}\n"
  },
  {
    "path": "app_backend/static/plugin/font-awesome/scss/_core.scss",
    "content": "// Base Class Definition\n// -------------------------\n\n.#{$fa-css-prefix} {\n  display: inline-block;\n  font: normal normal normal #{$fa-font-size-base}/#{$fa-line-height-base} FontAwesome; // shortening font declaration\n  font-size: inherit; // can't have font-size inherit on line above, so need to override\n  text-rendering: auto; // optimizelegibility throws things off #1094\n  -webkit-font-smoothing: antialiased;\n  -moz-osx-font-smoothing: grayscale;\n\n}\n"
  },
  {
    "path": "app_backend/static/plugin/font-awesome/scss/_extras.scss",
    "content": "/* EXTRAS\n * -------------------------- */\n\n/* Stacked and layered icon */\n\n/* Animated rotating icon */\n.#{$fa-css-prefix}-spin {\n  -webkit-animation: spin 2s infinite linear;\n  -moz-animation: spin 2s infinite linear;\n  -o-animation: spin 2s infinite linear;\n  animation: spin 2s infinite linear;\n}\n\n@-moz-keyframes spin {\n  0% { -moz-transform: rotate(0deg); }\n  100% { -moz-transform: rotate(359deg); }\n}\n@-webkit-keyframes spin {\n  0% { -webkit-transform: rotate(0deg); }\n  100% { -webkit-transform: rotate(359deg); }\n}\n@-o-keyframes spin {\n  0% { -o-transform: rotate(0deg); }\n  100% { -o-transform: rotate(359deg); }\n}\n@-ms-keyframes spin {\n  0% { -ms-transform: rotate(0deg); }\n  100% { -ms-transform: rotate(359deg); }\n}\n@keyframes spin {\n  0% { transform: rotate(0deg); }\n  100% { transform: rotate(359deg); }\n}\n\n\n// Icon rotations & flipping\n// -------------------------\n\n.#{$fa-css-prefix}-rotate-90  { @include fa-icon-rotate(90deg, 1);  }\n.#{$fa-css-prefix}-rotate-180 { @include fa-icon-rotate(180deg, 2); }\n.#{$fa-css-prefix}-rotate-270 { @include fa-icon-rotate(270deg, 3); }\n\n.#{$fa-css-prefix}-flip-horizontal { @include fa-icon-flip(-1, 1, 0); }\n.#{$fa-css-prefix}-flip-vertical   { @include fa-icon-flip(1, -1, 2); }\n"
  },
  {
    "path": "app_backend/static/plugin/font-awesome/scss/_fixed-width.scss",
    "content": "// Fixed Width Icons\n// -------------------------\n.#{$fa-css-prefix}-fw {\n  width: (18em / 14);\n  text-align: center;\n}\n"
  },
  {
    "path": "app_backend/static/plugin/font-awesome/scss/_icons.scss",
    "content": "/* Font Awesome uses the Unicode Private Use Area (PUA) to ensure screen\n   readers do not read off random characters that represent icons */\n\n.#{$fa-css-prefix}-glass:before { content: $fa-var-glass; }\n.#{$fa-css-prefix}-music:before { content: $fa-var-music; }\n.#{$fa-css-prefix}-search:before { content: $fa-var-search; }\n.#{$fa-css-prefix}-envelope-o:before { content: $fa-var-envelope-o; }\n.#{$fa-css-prefix}-heart:before { content: $fa-var-heart; }\n.#{$fa-css-prefix}-star:before { content: $fa-var-star; }\n.#{$fa-css-prefix}-star-o:before { content: $fa-var-star-o; }\n.#{$fa-css-prefix}-user:before { content: $fa-var-user; }\n.#{$fa-css-prefix}-film:before { content: $fa-var-film; }\n.#{$fa-css-prefix}-th-large:before { content: $fa-var-th-large; }\n.#{$fa-css-prefix}-th:before { content: $fa-var-th; }\n.#{$fa-css-prefix}-th-list:before { content: $fa-var-th-list; }\n.#{$fa-css-prefix}-check:before { content: $fa-var-check; }\n.#{$fa-css-prefix}-remove:before,\n.#{$fa-css-prefix}-close:before,\n.#{$fa-css-prefix}-times:before { content: $fa-var-times; }\n.#{$fa-css-prefix}-search-plus:before { content: $fa-var-search-plus; }\n.#{$fa-css-prefix}-search-minus:before { content: $fa-var-search-minus; }\n.#{$fa-css-prefix}-power-off:before { content: $fa-var-power-off; }\n.#{$fa-css-prefix}-signal:before { content: $fa-var-signal; }\n.#{$fa-css-prefix}-gear:before,\n.#{$fa-css-prefix}-cog:before { content: $fa-var-cog; }\n.#{$fa-css-prefix}-trash-o:before { content: $fa-var-trash-o; }\n.#{$fa-css-prefix}-home:before { content: $fa-var-home; }\n.#{$fa-css-prefix}-file-o:before { content: $fa-var-file-o; }\n.#{$fa-css-prefix}-clock-o:before { content: $fa-var-clock-o; }\n.#{$fa-css-prefix}-road:before { content: $fa-var-road; }\n.#{$fa-css-prefix}-download:before { content: $fa-var-download; }\n.#{$fa-css-prefix}-arrow-circle-o-down:before { content: $fa-var-arrow-circle-o-down; }\n.#{$fa-css-prefix}-arrow-circle-o-up:before { content: $fa-var-arrow-circle-o-up; }\n.#{$fa-css-prefix}-inbox:before { content: $fa-var-inbox; }\n.#{$fa-css-prefix}-play-circle-o:before { content: $fa-var-play-circle-o; }\n.#{$fa-css-prefix}-rotate-right:before,\n.#{$fa-css-prefix}-repeat:before { content: $fa-var-repeat; }\n.#{$fa-css-prefix}-refresh:before { content: $fa-var-refresh; }\n.#{$fa-css-prefix}-list-alt:before { content: $fa-var-list-alt; }\n.#{$fa-css-prefix}-lock:before { content: $fa-var-lock; }\n.#{$fa-css-prefix}-flag:before { content: $fa-var-flag; }\n.#{$fa-css-prefix}-headphones:before { content: $fa-var-headphones; }\n.#{$fa-css-prefix}-volume-off:before { content: $fa-var-volume-off; }\n.#{$fa-css-prefix}-volume-down:before { content: $fa-var-volume-down; }\n.#{$fa-css-prefix}-volume-up:before { content: $fa-var-volume-up; }\n.#{$fa-css-prefix}-qrcode:before { content: $fa-var-qrcode; }\n.#{$fa-css-prefix}-barcode:before { content: $fa-var-barcode; }\n.#{$fa-css-prefix}-tag:before { content: $fa-var-tag; }\n.#{$fa-css-prefix}-tags:before { content: $fa-var-tags; }\n.#{$fa-css-prefix}-book:before { content: $fa-var-book; }\n.#{$fa-css-prefix}-bookmark:before { content: $fa-var-bookmark; }\n.#{$fa-css-prefix}-print:before { content: $fa-var-print; }\n.#{$fa-css-prefix}-camera:before { content: $fa-var-camera; }\n.#{$fa-css-prefix}-font:before { content: $fa-var-font; }\n.#{$fa-css-prefix}-bold:before { content: $fa-var-bold; }\n.#{$fa-css-prefix}-italic:before { content: $fa-var-italic; }\n.#{$fa-css-prefix}-text-height:before { content: $fa-var-text-height; }\n.#{$fa-css-prefix}-text-width:before { content: $fa-var-text-width; }\n.#{$fa-css-prefix}-align-left:before { content: $fa-var-align-left; }\n.#{$fa-css-prefix}-align-center:before { content: $fa-var-align-center; }\n.#{$fa-css-prefix}-align-right:before { content: $fa-var-align-right; }\n.#{$fa-css-prefix}-align-justify:before { content: $fa-var-align-justify; }\n.#{$fa-css-prefix}-list:before { content: $fa-var-list; }\n.#{$fa-css-prefix}-dedent:before,\n.#{$fa-css-prefix}-outdent:before { content: $fa-var-outdent; }\n.#{$fa-css-prefix}-indent:before { content: $fa-var-indent; }\n.#{$fa-css-prefix}-video-camera:before { content: $fa-var-video-camera; }\n.#{$fa-css-prefix}-photo:before,\n.#{$fa-css-prefix}-image:before,\n.#{$fa-css-prefix}-picture-o:before { content: $fa-var-picture-o; }\n.#{$fa-css-prefix}-pencil:before { content: $fa-var-pencil; }\n.#{$fa-css-prefix}-map-marker:before { content: $fa-var-map-marker; }\n.#{$fa-css-prefix}-adjust:before { content: $fa-var-adjust; }\n.#{$fa-css-prefix}-tint:before { content: $fa-var-tint; }\n.#{$fa-css-prefix}-edit:before,\n.#{$fa-css-prefix}-pencil-square-o:before { content: $fa-var-pencil-square-o; }\n.#{$fa-css-prefix}-share-square-o:before { content: $fa-var-share-square-o; }\n.#{$fa-css-prefix}-check-square-o:before { content: $fa-var-check-square-o; }\n.#{$fa-css-prefix}-arrows:before { content: $fa-var-arrows; }\n.#{$fa-css-prefix}-step-backward:before { content: $fa-var-step-backward; }\n.#{$fa-css-prefix}-fast-backward:before { content: $fa-var-fast-backward; }\n.#{$fa-css-prefix}-backward:before { content: $fa-var-backward; }\n.#{$fa-css-prefix}-play:before { content: $fa-var-play; }\n.#{$fa-css-prefix}-pause:before { content: $fa-var-pause; }\n.#{$fa-css-prefix}-stop:before { content: $fa-var-stop; }\n.#{$fa-css-prefix}-forward:before { content: $fa-var-forward; }\n.#{$fa-css-prefix}-fast-forward:before { content: $fa-var-fast-forward; }\n.#{$fa-css-prefix}-step-forward:before { content: $fa-var-step-forward; }\n.#{$fa-css-prefix}-eject:before { content: $fa-var-eject; }\n.#{$fa-css-prefix}-chevron-left:before { content: $fa-var-chevron-left; }\n.#{$fa-css-prefix}-chevron-right:before { content: $fa-var-chevron-right; }\n.#{$fa-css-prefix}-plus-circle:before { content: $fa-var-plus-circle; }\n.#{$fa-css-prefix}-minus-circle:before { content: $fa-var-minus-circle; }\n.#{$fa-css-prefix}-times-circle:before { content: $fa-var-times-circle; }\n.#{$fa-css-prefix}-check-circle:before { content: $fa-var-check-circle; }\n.#{$fa-css-prefix}-question-circle:before { content: $fa-var-question-circle; }\n.#{$fa-css-prefix}-info-circle:before { content: $fa-var-info-circle; }\n.#{$fa-css-prefix}-crosshairs:before { content: $fa-var-crosshairs; }\n.#{$fa-css-prefix}-times-circle-o:before { content: $fa-var-times-circle-o; }\n.#{$fa-css-prefix}-check-circle-o:before { content: $fa-var-check-circle-o; }\n.#{$fa-css-prefix}-ban:before { content: $fa-var-ban; }\n.#{$fa-css-prefix}-arrow-left:before { content: $fa-var-arrow-left; }\n.#{$fa-css-prefix}-arrow-right:before { content: $fa-var-arrow-right; }\n.#{$fa-css-prefix}-arrow-up:before { content: $fa-var-arrow-up; }\n.#{$fa-css-prefix}-arrow-down:before { content: $fa-var-arrow-down; }\n.#{$fa-css-prefix}-mail-forward:before,\n.#{$fa-css-prefix}-share:before { content: $fa-var-share; }\n.#{$fa-css-prefix}-expand:before { content: $fa-var-expand; }\n.#{$fa-css-prefix}-compress:before { content: $fa-var-compress; }\n.#{$fa-css-prefix}-plus:before { content: $fa-var-plus; }\n.#{$fa-css-prefix}-minus:before { content: $fa-var-minus; }\n.#{$fa-css-prefix}-asterisk:before { content: $fa-var-asterisk; }\n.#{$fa-css-prefix}-exclamation-circle:before { content: $fa-var-exclamation-circle; }\n.#{$fa-css-prefix}-gift:before { content: $fa-var-gift; }\n.#{$fa-css-prefix}-leaf:before { content: $fa-var-leaf; }\n.#{$fa-css-prefix}-fire:before { content: $fa-var-fire; }\n.#{$fa-css-prefix}-eye:before { content: $fa-var-eye; }\n.#{$fa-css-prefix}-eye-slash:before { content: $fa-var-eye-slash; }\n.#{$fa-css-prefix}-warning:before,\n.#{$fa-css-prefix}-exclamation-triangle:before { content: $fa-var-exclamation-triangle; }\n.#{$fa-css-prefix}-plane:before { content: $fa-var-plane; }\n.#{$fa-css-prefix}-calendar:before { content: $fa-var-calendar; }\n.#{$fa-css-prefix}-random:before { content: $fa-var-random; }\n.#{$fa-css-prefix}-comment:before { content: $fa-var-comment; }\n.#{$fa-css-prefix}-magnet:before { content: $fa-var-magnet; }\n.#{$fa-css-prefix}-chevron-up:before { content: $fa-var-chevron-up; }\n.#{$fa-css-prefix}-chevron-down:before { content: $fa-var-chevron-down; }\n.#{$fa-css-prefix}-retweet:before { content: $fa-var-retweet; }\n.#{$fa-css-prefix}-shopping-cart:before { content: $fa-var-shopping-cart; }\n.#{$fa-css-prefix}-folder:before { content: $fa-var-folder; }\n.#{$fa-css-prefix}-folder-open:before { content: $fa-var-folder-open; }\n.#{$fa-css-prefix}-arrows-v:before { content: $fa-var-arrows-v; }\n.#{$fa-css-prefix}-arrows-h:before { content: $fa-var-arrows-h; }\n.#{$fa-css-prefix}-bar-chart-o:before,\n.#{$fa-css-prefix}-bar-chart:before { content: $fa-var-bar-chart; }\n.#{$fa-css-prefix}-twitter-square:before { content: $fa-var-twitter-square; }\n.#{$fa-css-prefix}-facebook-square:before { content: $fa-var-facebook-square; }\n.#{$fa-css-prefix}-camera-retro:before { content: $fa-var-camera-retro; }\n.#{$fa-css-prefix}-key:before { content: $fa-var-key; }\n.#{$fa-css-prefix}-gears:before,\n.#{$fa-css-prefix}-cogs:before { content: $fa-var-cogs; }\n.#{$fa-css-prefix}-comments:before { content: $fa-var-comments; }\n.#{$fa-css-prefix}-thumbs-o-up:before { content: $fa-var-thumbs-o-up; }\n.#{$fa-css-prefix}-thumbs-o-down:before { content: $fa-var-thumbs-o-down; }\n.#{$fa-css-prefix}-star-half:before { content: $fa-var-star-half; }\n.#{$fa-css-prefix}-heart-o:before { content: $fa-var-heart-o; }\n.#{$fa-css-prefix}-sign-out:before { content: $fa-var-sign-out; }\n.#{$fa-css-prefix}-linkedin-square:before { content: $fa-var-linkedin-square; }\n.#{$fa-css-prefix}-thumb-tack:before { content: $fa-var-thumb-tack; }\n.#{$fa-css-prefix}-external-link:before { content: $fa-var-external-link; }\n.#{$fa-css-prefix}-sign-in:before { content: $fa-var-sign-in; }\n.#{$fa-css-prefix}-trophy:before { content: $fa-var-trophy; }\n.#{$fa-css-prefix}-github-square:before { content: $fa-var-github-square; }\n.#{$fa-css-prefix}-upload:before { content: $fa-var-upload; }\n.#{$fa-css-prefix}-lemon-o:before { content: $fa-var-lemon-o; }\n.#{$fa-css-prefix}-phone:before { content: $fa-var-phone; }\n.#{$fa-css-prefix}-square-o:before { content: $fa-var-square-o; }\n.#{$fa-css-prefix}-bookmark-o:before { content: $fa-var-bookmark-o; }\n.#{$fa-css-prefix}-phone-square:before { content: $fa-var-phone-square; }\n.#{$fa-css-prefix}-twitter:before { content: $fa-var-twitter; }\n.#{$fa-css-prefix}-facebook-f:before,\n.#{$fa-css-prefix}-facebook:before { content: $fa-var-facebook; }\n.#{$fa-css-prefix}-github:before { content: $fa-var-github; }\n.#{$fa-css-prefix}-unlock:before { content: $fa-var-unlock; }\n.#{$fa-css-prefix}-credit-card:before { content: $fa-var-credit-card; }\n.#{$fa-css-prefix}-feed:before,\n.#{$fa-css-prefix}-rss:before { content: $fa-var-rss; }\n.#{$fa-css-prefix}-hdd-o:before { content: $fa-var-hdd-o; }\n.#{$fa-css-prefix}-bullhorn:before { content: $fa-var-bullhorn; }\n.#{$fa-css-prefix}-bell:before { content: $fa-var-bell; }\n.#{$fa-css-prefix}-certificate:before { content: $fa-var-certificate; }\n.#{$fa-css-prefix}-hand-o-right:before { content: $fa-var-hand-o-right; }\n.#{$fa-css-prefix}-hand-o-left:before { content: $fa-var-hand-o-left; }\n.#{$fa-css-prefix}-hand-o-up:before { content: $fa-var-hand-o-up; }\n.#{$fa-css-prefix}-hand-o-down:before { content: $fa-var-hand-o-down; }\n.#{$fa-css-prefix}-arrow-circle-left:before { content: $fa-var-arrow-circle-left; }\n.#{$fa-css-prefix}-arrow-circle-right:before { content: $fa-var-arrow-circle-right; }\n.#{$fa-css-prefix}-arrow-circle-up:before { content: $fa-var-arrow-circle-up; }\n.#{$fa-css-prefix}-arrow-circle-down:before { content: $fa-var-arrow-circle-down; }\n.#{$fa-css-prefix}-globe:before { content: $fa-var-globe; }\n.#{$fa-css-prefix}-wrench:before { content: $fa-var-wrench; }\n.#{$fa-css-prefix}-tasks:before { content: $fa-var-tasks; }\n.#{$fa-css-prefix}-filter:before { content: $fa-var-filter; }\n.#{$fa-css-prefix}-briefcase:before { content: $fa-var-briefcase; }\n.#{$fa-css-prefix}-arrows-alt:before { content: $fa-var-arrows-alt; }\n.#{$fa-css-prefix}-group:before,\n.#{$fa-css-prefix}-users:before { content: $fa-var-users; }\n.#{$fa-css-prefix}-chain:before,\n.#{$fa-css-prefix}-link:before { content: $fa-var-link; }\n.#{$fa-css-prefix}-cloud:before { content: $fa-var-cloud; }\n.#{$fa-css-prefix}-flask:before { content: $fa-var-flask; }\n.#{$fa-css-prefix}-cut:before,\n.#{$fa-css-prefix}-scissors:before { content: $fa-var-scissors; }\n.#{$fa-css-prefix}-copy:before,\n.#{$fa-css-prefix}-files-o:before { content: $fa-var-files-o; }\n.#{$fa-css-prefix}-paperclip:before { content: $fa-var-paperclip; }\n.#{$fa-css-prefix}-save:before,\n.#{$fa-css-prefix}-floppy-o:before { content: $fa-var-floppy-o; }\n.#{$fa-css-prefix}-square:before { content: $fa-var-square; }\n.#{$fa-css-prefix}-navicon:before,\n.#{$fa-css-prefix}-reorder:before,\n.#{$fa-css-prefix}-bars:before { content: $fa-var-bars; }\n.#{$fa-css-prefix}-list-ul:before { content: $fa-var-list-ul; }\n.#{$fa-css-prefix}-list-ol:before { content: $fa-var-list-ol; }\n.#{$fa-css-prefix}-strikethrough:before { content: $fa-var-strikethrough; }\n.#{$fa-css-prefix}-underline:before { content: $fa-var-underline; }\n.#{$fa-css-prefix}-table:before { content: $fa-var-table; }\n.#{$fa-css-prefix}-magic:before { content: $fa-var-magic; }\n.#{$fa-css-prefix}-truck:before { content: $fa-var-truck; }\n.#{$fa-css-prefix}-pinterest:before { content: $fa-var-pinterest; }\n.#{$fa-css-prefix}-pinterest-square:before { content: $fa-var-pinterest-square; }\n.#{$fa-css-prefix}-google-plus-square:before { content: $fa-var-google-plus-square; }\n.#{$fa-css-prefix}-google-plus:before { content: $fa-var-google-plus; }\n.#{$fa-css-prefix}-money:before { content: $fa-var-money; }\n.#{$fa-css-prefix}-caret-down:before { content: $fa-var-caret-down; }\n.#{$fa-css-prefix}-caret-up:before { content: $fa-var-caret-up; }\n.#{$fa-css-prefix}-caret-left:before { content: $fa-var-caret-left; }\n.#{$fa-css-prefix}-caret-right:before { content: $fa-var-caret-right; }\n.#{$fa-css-prefix}-columns:before { content: $fa-var-columns; }\n.#{$fa-css-prefix}-unsorted:before,\n.#{$fa-css-prefix}-sort:before { content: $fa-var-sort; }\n.#{$fa-css-prefix}-sort-down:before,\n.#{$fa-css-prefix}-sort-desc:before { content: $fa-var-sort-desc; }\n.#{$fa-css-prefix}-sort-up:before,\n.#{$fa-css-prefix}-sort-asc:before { content: $fa-var-sort-asc; }\n.#{$fa-css-prefix}-envelope:before { content: $fa-var-envelope; }\n.#{$fa-css-prefix}-linkedin:before { content: $fa-var-linkedin; }\n.#{$fa-css-prefix}-rotate-left:before,\n.#{$fa-css-prefix}-undo:before { content: $fa-var-undo; }\n.#{$fa-css-prefix}-legal:before,\n.#{$fa-css-prefix}-gavel:before { content: $fa-var-gavel; }\n.#{$fa-css-prefix}-dashboard:before,\n.#{$fa-css-prefix}-tachometer:before { content: $fa-var-tachometer; }\n.#{$fa-css-prefix}-comment-o:before { content: $fa-var-comment-o; }\n.#{$fa-css-prefix}-comments-o:before { content: $fa-var-comments-o; }\n.#{$fa-css-prefix}-flash:before,\n.#{$fa-css-prefix}-bolt:before { content: $fa-var-bolt; }\n.#{$fa-css-prefix}-sitemap:before { content: $fa-var-sitemap; }\n.#{$fa-css-prefix}-umbrella:before { content: $fa-var-umbrella; }\n.#{$fa-css-prefix}-paste:before,\n.#{$fa-css-prefix}-clipboard:before { content: $fa-var-clipboard; }\n.#{$fa-css-prefix}-lightbulb-o:before { content: $fa-var-lightbulb-o; }\n.#{$fa-css-prefix}-exchange:before { content: $fa-var-exchange; }\n.#{$fa-css-prefix}-cloud-download:before { content: $fa-var-cloud-download; }\n.#{$fa-css-prefix}-cloud-upload:before { content: $fa-var-cloud-upload; }\n.#{$fa-css-prefix}-user-md:before { content: $fa-var-user-md; }\n.#{$fa-css-prefix}-stethoscope:before { content: $fa-var-stethoscope; }\n.#{$fa-css-prefix}-suitcase:before { content: $fa-var-suitcase; }\n.#{$fa-css-prefix}-bell-o:before { content: $fa-var-bell-o; }\n.#{$fa-css-prefix}-coffee:before { content: $fa-var-coffee; }\n.#{$fa-css-prefix}-cutlery:before { content: $fa-var-cutlery; }\n.#{$fa-css-prefix}-file-text-o:before { content: $fa-var-file-text-o; }\n.#{$fa-css-prefix}-building-o:before { content: $fa-var-building-o; }\n.#{$fa-css-prefix}-hospital-o:before { content: $fa-var-hospital-o; }\n.#{$fa-css-prefix}-ambulance:before { content: $fa-var-ambulance; }\n.#{$fa-css-prefix}-medkit:before { content: $fa-var-medkit; }\n.#{$fa-css-prefix}-fighter-jet:before { content: $fa-var-fighter-jet; }\n.#{$fa-css-prefix}-beer:before { content: $fa-var-beer; }\n.#{$fa-css-prefix}-h-square:before { content: $fa-var-h-square; }\n.#{$fa-css-prefix}-plus-square:before { content: $fa-var-plus-square; }\n.#{$fa-css-prefix}-angle-double-left:before { content: $fa-var-angle-double-left; }\n.#{$fa-css-prefix}-angle-double-right:before { content: $fa-var-angle-double-right; }\n.#{$fa-css-prefix}-angle-double-up:before { content: $fa-var-angle-double-up; }\n.#{$fa-css-prefix}-angle-double-down:before { content: $fa-var-angle-double-down; }\n.#{$fa-css-prefix}-angle-left:before { content: $fa-var-angle-left; }\n.#{$fa-css-prefix}-angle-right:before { content: $fa-var-angle-right; }\n.#{$fa-css-prefix}-angle-up:before { content: $fa-var-angle-up; }\n.#{$fa-css-prefix}-angle-down:before { content: $fa-var-angle-down; }\n.#{$fa-css-prefix}-desktop:before { content: $fa-var-desktop; }\n.#{$fa-css-prefix}-laptop:before { content: $fa-var-laptop; }\n.#{$fa-css-prefix}-tablet:before { content: $fa-var-tablet; }\n.#{$fa-css-prefix}-mobile-phone:before,\n.#{$fa-css-prefix}-mobile:before { content: $fa-var-mobile; }\n.#{$fa-css-prefix}-circle-o:before { content: $fa-var-circle-o; }\n.#{$fa-css-prefix}-quote-left:before { content: $fa-var-quote-left; }\n.#{$fa-css-prefix}-quote-right:before { content: $fa-var-quote-right; }\n.#{$fa-css-prefix}-spinner:before { content: $fa-var-spinner; }\n.#{$fa-css-prefix}-circle:before { content: $fa-var-circle; }\n.#{$fa-css-prefix}-mail-reply:before,\n.#{$fa-css-prefix}-reply:before { content: $fa-var-reply; }\n.#{$fa-css-prefix}-github-alt:before { content: $fa-var-github-alt; }\n.#{$fa-css-prefix}-folder-o:before { content: $fa-var-folder-o; }\n.#{$fa-css-prefix}-folder-open-o:before { content: $fa-var-folder-open-o; }\n.#{$fa-css-prefix}-smile-o:before { content: $fa-var-smile-o; }\n.#{$fa-css-prefix}-frown-o:before { content: $fa-var-frown-o; }\n.#{$fa-css-prefix}-meh-o:before { content: $fa-var-meh-o; }\n.#{$fa-css-prefix}-gamepad:before { content: $fa-var-gamepad; }\n.#{$fa-css-prefix}-keyboard-o:before { content: $fa-var-keyboard-o; }\n.#{$fa-css-prefix}-flag-o:before { content: $fa-var-flag-o; }\n.#{$fa-css-prefix}-flag-checkered:before { content: $fa-var-flag-checkered; }\n.#{$fa-css-prefix}-terminal:before { content: $fa-var-terminal; }\n.#{$fa-css-prefix}-code:before { content: $fa-var-code; }\n.#{$fa-css-prefix}-mail-reply-all:before,\n.#{$fa-css-prefix}-reply-all:before { content: $fa-var-reply-all; }\n.#{$fa-css-prefix}-star-half-empty:before,\n.#{$fa-css-prefix}-star-half-full:before,\n.#{$fa-css-prefix}-star-half-o:before { content: $fa-var-star-half-o; }\n.#{$fa-css-prefix}-location-arrow:before { content: $fa-var-location-arrow; }\n.#{$fa-css-prefix}-crop:before { content: $fa-var-crop; }\n.#{$fa-css-prefix}-code-fork:before { content: $fa-var-code-fork; }\n.#{$fa-css-prefix}-unlink:before,\n.#{$fa-css-prefix}-chain-broken:before { content: $fa-var-chain-broken; }\n.#{$fa-css-prefix}-question:before { content: $fa-var-question; }\n.#{$fa-css-prefix}-info:before { content: $fa-var-info; }\n.#{$fa-css-prefix}-exclamation:before { content: $fa-var-exclamation; }\n.#{$fa-css-prefix}-superscript:before { content: $fa-var-superscript; }\n.#{$fa-css-prefix}-subscript:before { content: $fa-var-subscript; }\n.#{$fa-css-prefix}-eraser:before { content: $fa-var-eraser; }\n.#{$fa-css-prefix}-puzzle-piece:before { content: $fa-var-puzzle-piece; }\n.#{$fa-css-prefix}-microphone:before { content: $fa-var-microphone; }\n.#{$fa-css-prefix}-microphone-slash:before { content: $fa-var-microphone-slash; }\n.#{$fa-css-prefix}-shield:before { content: $fa-var-shield; }\n.#{$fa-css-prefix}-calendar-o:before { content: $fa-var-calendar-o; }\n.#{$fa-css-prefix}-fire-extinguisher:before { content: $fa-var-fire-extinguisher; }\n.#{$fa-css-prefix}-rocket:before { content: $fa-var-rocket; }\n.#{$fa-css-prefix}-maxcdn:before { content: $fa-var-maxcdn; }\n.#{$fa-css-prefix}-chevron-circle-left:before { content: $fa-var-chevron-circle-left; }\n.#{$fa-css-prefix}-chevron-circle-right:before { content: $fa-var-chevron-circle-right; }\n.#{$fa-css-prefix}-chevron-circle-up:before { content: $fa-var-chevron-circle-up; }\n.#{$fa-css-prefix}-chevron-circle-down:before { content: $fa-var-chevron-circle-down; }\n.#{$fa-css-prefix}-html5:before { content: $fa-var-html5; }\n.#{$fa-css-prefix}-css3:before { content: $fa-var-css3; }\n.#{$fa-css-prefix}-anchor:before { content: $fa-var-anchor; }\n.#{$fa-css-prefix}-unlock-alt:before { content: $fa-var-unlock-alt; }\n.#{$fa-css-prefix}-bullseye:before { content: $fa-var-bullseye; }\n.#{$fa-css-prefix}-ellipsis-h:before { content: $fa-var-ellipsis-h; }\n.#{$fa-css-prefix}-ellipsis-v:before { content: $fa-var-ellipsis-v; }\n.#{$fa-css-prefix}-rss-square:before { content: $fa-var-rss-square; }\n.#{$fa-css-prefix}-play-circle:before { content: $fa-var-play-circle; }\n.#{$fa-css-prefix}-ticket:before { content: $fa-var-ticket; }\n.#{$fa-css-prefix}-minus-square:before { content: $fa-var-minus-square; }\n.#{$fa-css-prefix}-minus-square-o:before { content: $fa-var-minus-square-o; }\n.#{$fa-css-prefix}-level-up:before { content: $fa-var-level-up; }\n.#{$fa-css-prefix}-level-down:before { content: $fa-var-level-down; }\n.#{$fa-css-prefix}-check-square:before { content: $fa-var-check-square; }\n.#{$fa-css-prefix}-pencil-square:before { content: $fa-var-pencil-square; }\n.#{$fa-css-prefix}-external-link-square:before { content: $fa-var-external-link-square; }\n.#{$fa-css-prefix}-share-square:before { content: $fa-var-share-square; }\n.#{$fa-css-prefix}-compass:before { content: $fa-var-compass; }\n.#{$fa-css-prefix}-toggle-down:before,\n.#{$fa-css-prefix}-caret-square-o-down:before { content: $fa-var-caret-square-o-down; }\n.#{$fa-css-prefix}-toggle-up:before,\n.#{$fa-css-prefix}-caret-square-o-up:before { content: $fa-var-caret-square-o-up; }\n.#{$fa-css-prefix}-toggle-right:before,\n.#{$fa-css-prefix}-caret-square-o-right:before { content: $fa-var-caret-square-o-right; }\n.#{$fa-css-prefix}-euro:before,\n.#{$fa-css-prefix}-eur:before { content: $fa-var-eur; }\n.#{$fa-css-prefix}-gbp:before { content: $fa-var-gbp; }\n.#{$fa-css-prefix}-dollar:before,\n.#{$fa-css-prefix}-usd:before { content: $fa-var-usd; }\n.#{$fa-css-prefix}-rupee:before,\n.#{$fa-css-prefix}-inr:before { content: $fa-var-inr; }\n.#{$fa-css-prefix}-cny:before,\n.#{$fa-css-prefix}-rmb:before,\n.#{$fa-css-prefix}-yen:before,\n.#{$fa-css-prefix}-jpy:before { content: $fa-var-jpy; }\n.#{$fa-css-prefix}-ruble:before,\n.#{$fa-css-prefix}-rouble:before,\n.#{$fa-css-prefix}-rub:before { content: $fa-var-rub; }\n.#{$fa-css-prefix}-won:before,\n.#{$fa-css-prefix}-krw:before { content: $fa-var-krw; }\n.#{$fa-css-prefix}-bitcoin:before,\n.#{$fa-css-prefix}-btc:before { content: $fa-var-btc; }\n.#{$fa-css-prefix}-file:before { content: $fa-var-file; }\n.#{$fa-css-prefix}-file-text:before { content: $fa-var-file-text; }\n.#{$fa-css-prefix}-sort-alpha-asc:before { content: $fa-var-sort-alpha-asc; }\n.#{$fa-css-prefix}-sort-alpha-desc:before { content: $fa-var-sort-alpha-desc; }\n.#{$fa-css-prefix}-sort-amount-asc:before { content: $fa-var-sort-amount-asc; }\n.#{$fa-css-prefix}-sort-amount-desc:before { content: $fa-var-sort-amount-desc; }\n.#{$fa-css-prefix}-sort-numeric-asc:before { content: $fa-var-sort-numeric-asc; }\n.#{$fa-css-prefix}-sort-numeric-desc:before { content: $fa-var-sort-numeric-desc; }\n.#{$fa-css-prefix}-thumbs-up:before { content: $fa-var-thumbs-up; }\n.#{$fa-css-prefix}-thumbs-down:before { content: $fa-var-thumbs-down; }\n.#{$fa-css-prefix}-youtube-square:before { content: $fa-var-youtube-square; }\n.#{$fa-css-prefix}-youtube:before { content: $fa-var-youtube; }\n.#{$fa-css-prefix}-xing:before { content: $fa-var-xing; }\n.#{$fa-css-prefix}-xing-square:before { content: $fa-var-xing-square; }\n.#{$fa-css-prefix}-youtube-play:before { content: $fa-var-youtube-play; }\n.#{$fa-css-prefix}-dropbox:before { content: $fa-var-dropbox; }\n.#{$fa-css-prefix}-stack-overflow:before { content: $fa-var-stack-overflow; }\n.#{$fa-css-prefix}-instagram:before { content: $fa-var-instagram; }\n.#{$fa-css-prefix}-flickr:before { content: $fa-var-flickr; }\n.#{$fa-css-prefix}-adn:before { content: $fa-var-adn; }\n.#{$fa-css-prefix}-bitbucket:before { content: $fa-var-bitbucket; }\n.#{$fa-css-prefix}-bitbucket-square:before { content: $fa-var-bitbucket-square; }\n.#{$fa-css-prefix}-tumblr:before { content: $fa-var-tumblr; }\n.#{$fa-css-prefix}-tumblr-square:before { content: $fa-var-tumblr-square; }\n.#{$fa-css-prefix}-long-arrow-down:before { content: $fa-var-long-arrow-down; }\n.#{$fa-css-prefix}-long-arrow-up:before { content: $fa-var-long-arrow-up; }\n.#{$fa-css-prefix}-long-arrow-left:before { content: $fa-var-long-arrow-left; }\n.#{$fa-css-prefix}-long-arrow-right:before { content: $fa-var-long-arrow-right; }\n.#{$fa-css-prefix}-apple:before { content: $fa-var-apple; }\n.#{$fa-css-prefix}-windows:before { content: $fa-var-windows; }\n.#{$fa-css-prefix}-android:before { content: $fa-var-android; }\n.#{$fa-css-prefix}-linux:before { content: $fa-var-linux; }\n.#{$fa-css-prefix}-dribbble:before { content: $fa-var-dribbble; }\n.#{$fa-css-prefix}-skype:before { content: $fa-var-skype; }\n.#{$fa-css-prefix}-foursquare:before { content: $fa-var-foursquare; }\n.#{$fa-css-prefix}-trello:before { content: $fa-var-trello; }\n.#{$fa-css-prefix}-female:before { content: $fa-var-female; }\n.#{$fa-css-prefix}-male:before { content: $fa-var-male; }\n.#{$fa-css-prefix}-gittip:before,\n.#{$fa-css-prefix}-gratipay:before { content: $fa-var-gratipay; }\n.#{$fa-css-prefix}-sun-o:before { content: $fa-var-sun-o; }\n.#{$fa-css-prefix}-moon-o:before { content: $fa-var-moon-o; }\n.#{$fa-css-prefix}-archive:before { content: $fa-var-archive; }\n.#{$fa-css-prefix}-bug:before { content: $fa-var-bug; }\n.#{$fa-css-prefix}-vk:before { content: $fa-var-vk; }\n.#{$fa-css-prefix}-weibo:before { content: $fa-var-weibo; }\n.#{$fa-css-prefix}-renren:before { content: $fa-var-renren; }\n.#{$fa-css-prefix}-pagelines:before { content: $fa-var-pagelines; }\n.#{$fa-css-prefix}-stack-exchange:before { content: $fa-var-stack-exchange; }\n.#{$fa-css-prefix}-arrow-circle-o-right:before { content: $fa-var-arrow-circle-o-right; }\n.#{$fa-css-prefix}-arrow-circle-o-left:before { content: $fa-var-arrow-circle-o-left; }\n.#{$fa-css-prefix}-toggle-left:before,\n.#{$fa-css-prefix}-caret-square-o-left:before { content: $fa-var-caret-square-o-left; }\n.#{$fa-css-prefix}-dot-circle-o:before { content: $fa-var-dot-circle-o; }\n.#{$fa-css-prefix}-wheelchair:before { content: $fa-var-wheelchair; }\n.#{$fa-css-prefix}-vimeo-square:before { content: $fa-var-vimeo-square; }\n.#{$fa-css-prefix}-turkish-lira:before,\n.#{$fa-css-prefix}-try:before { content: $fa-var-try; }\n.#{$fa-css-prefix}-plus-square-o:before { content: $fa-var-plus-square-o; }\n.#{$fa-css-prefix}-space-shuttle:before { content: $fa-var-space-shuttle; }\n.#{$fa-css-prefix}-slack:before { content: $fa-var-slack; }\n.#{$fa-css-prefix}-envelope-square:before { content: $fa-var-envelope-square; }\n.#{$fa-css-prefix}-wordpress:before { content: $fa-var-wordpress; }\n.#{$fa-css-prefix}-openid:before { content: $fa-var-openid; }\n.#{$fa-css-prefix}-institution:before,\n.#{$fa-css-prefix}-bank:before,\n.#{$fa-css-prefix}-university:before { content: $fa-var-university; }\n.#{$fa-css-prefix}-mortar-board:before,\n.#{$fa-css-prefix}-graduation-cap:before { content: $fa-var-graduation-cap; }\n.#{$fa-css-prefix}-yahoo:before { content: $fa-var-yahoo; }\n.#{$fa-css-prefix}-google:before { content: $fa-var-google; }\n.#{$fa-css-prefix}-reddit:before { content: $fa-var-reddit; }\n.#{$fa-css-prefix}-reddit-square:before { content: $fa-var-reddit-square; }\n.#{$fa-css-prefix}-stumbleupon-circle:before { content: $fa-var-stumbleupon-circle; }\n.#{$fa-css-prefix}-stumbleupon:before { content: $fa-var-stumbleupon; }\n.#{$fa-css-prefix}-delicious:before { content: $fa-var-delicious; }\n.#{$fa-css-prefix}-digg:before { content: $fa-var-digg; }\n.#{$fa-css-prefix}-pied-piper-pp:before { content: $fa-var-pied-piper-pp; }\n.#{$fa-css-prefix}-pied-piper-alt:before { content: $fa-var-pied-piper-alt; }\n.#{$fa-css-prefix}-drupal:before { content: $fa-var-drupal; }\n.#{$fa-css-prefix}-joomla:before { content: $fa-var-joomla; }\n.#{$fa-css-prefix}-language:before { content: $fa-var-language; }\n.#{$fa-css-prefix}-fax:before { content: $fa-var-fax; }\n.#{$fa-css-prefix}-building:before { content: $fa-var-building; }\n.#{$fa-css-prefix}-child:before { content: $fa-var-child; }\n.#{$fa-css-prefix}-paw:before { content: $fa-var-paw; }\n.#{$fa-css-prefix}-spoon:before { content: $fa-var-spoon; }\n.#{$fa-css-prefix}-cube:before { content: $fa-var-cube; }\n.#{$fa-css-prefix}-cubes:before { content: $fa-var-cubes; }\n.#{$fa-css-prefix}-behance:before { content: $fa-var-behance; }\n.#{$fa-css-prefix}-behance-square:before { content: $fa-var-behance-square; }\n.#{$fa-css-prefix}-steam:before { content: $fa-var-steam; }\n.#{$fa-css-prefix}-steam-square:before { content: $fa-var-steam-square; }\n.#{$fa-css-prefix}-recycle:before { content: $fa-var-recycle; }\n.#{$fa-css-prefix}-automobile:before,\n.#{$fa-css-prefix}-car:before { content: $fa-var-car; }\n.#{$fa-css-prefix}-cab:before,\n.#{$fa-css-prefix}-taxi:before { content: $fa-var-taxi; }\n.#{$fa-css-prefix}-tree:before { content: $fa-var-tree; }\n.#{$fa-css-prefix}-spotify:before { content: $fa-var-spotify; }\n.#{$fa-css-prefix}-deviantart:before { content: $fa-var-deviantart; }\n.#{$fa-css-prefix}-soundcloud:before { content: $fa-var-soundcloud; }\n.#{$fa-css-prefix}-database:before { content: $fa-var-database; }\n.#{$fa-css-prefix}-file-pdf-o:before { content: $fa-var-file-pdf-o; }\n.#{$fa-css-prefix}-file-word-o:before { content: $fa-var-file-word-o; }\n.#{$fa-css-prefix}-file-excel-o:before { content: $fa-var-file-excel-o; }\n.#{$fa-css-prefix}-file-powerpoint-o:before { content: $fa-var-file-powerpoint-o; }\n.#{$fa-css-prefix}-file-photo-o:before,\n.#{$fa-css-prefix}-file-picture-o:before,\n.#{$fa-css-prefix}-file-image-o:before { content: $fa-var-file-image-o; }\n.#{$fa-css-prefix}-file-zip-o:before,\n.#{$fa-css-prefix}-file-archive-o:before { content: $fa-var-file-archive-o; }\n.#{$fa-css-prefix}-file-sound-o:before,\n.#{$fa-css-prefix}-file-audio-o:before { content: $fa-var-file-audio-o; }\n.#{$fa-css-prefix}-file-movie-o:before,\n.#{$fa-css-prefix}-file-video-o:before { content: $fa-var-file-video-o; }\n.#{$fa-css-prefix}-file-code-o:before { content: $fa-var-file-code-o; }\n.#{$fa-css-prefix}-vine:before { content: $fa-var-vine; }\n.#{$fa-css-prefix}-codepen:before { content: $fa-var-codepen; }\n.#{$fa-css-prefix}-jsfiddle:before { content: $fa-var-jsfiddle; }\n.#{$fa-css-prefix}-life-bouy:before,\n.#{$fa-css-prefix}-life-buoy:before,\n.#{$fa-css-prefix}-life-saver:before,\n.#{$fa-css-prefix}-support:before,\n.#{$fa-css-prefix}-life-ring:before { content: $fa-var-life-ring; }\n.#{$fa-css-prefix}-circle-o-notch:before { content: $fa-var-circle-o-notch; }\n.#{$fa-css-prefix}-ra:before,\n.#{$fa-css-prefix}-resistance:before,\n.#{$fa-css-prefix}-rebel:before { content: $fa-var-rebel; }\n.#{$fa-css-prefix}-ge:before,\n.#{$fa-css-prefix}-empire:before { content: $fa-var-empire; }\n.#{$fa-css-prefix}-git-square:before { content: $fa-var-git-square; }\n.#{$fa-css-prefix}-git:before { content: $fa-var-git; }\n.#{$fa-css-prefix}-y-combinator-square:before,\n.#{$fa-css-prefix}-yc-square:before,\n.#{$fa-css-prefix}-hacker-news:before { content: $fa-var-hacker-news; }\n.#{$fa-css-prefix}-tencent-weibo:before { content: $fa-var-tencent-weibo; }\n.#{$fa-css-prefix}-qq:before { content: $fa-var-qq; }\n.#{$fa-css-prefix}-wechat:before,\n.#{$fa-css-prefix}-weixin:before { content: $fa-var-weixin; }\n.#{$fa-css-prefix}-send:before,\n.#{$fa-css-prefix}-paper-plane:before { content: $fa-var-paper-plane; }\n.#{$fa-css-prefix}-send-o:before,\n.#{$fa-css-prefix}-paper-plane-o:before { content: $fa-var-paper-plane-o; }\n.#{$fa-css-prefix}-history:before { content: $fa-var-history; }\n.#{$fa-css-prefix}-circle-thin:before { content: $fa-var-circle-thin; }\n.#{$fa-css-prefix}-header:before { content: $fa-var-header; }\n.#{$fa-css-prefix}-paragraph:before { content: $fa-var-paragraph; }\n.#{$fa-css-prefix}-sliders:before { content: $fa-var-sliders; }\n.#{$fa-css-prefix}-share-alt:before { content: $fa-var-share-alt; }\n.#{$fa-css-prefix}-share-alt-square:before { content: $fa-var-share-alt-square; }\n.#{$fa-css-prefix}-bomb:before { content: $fa-var-bomb; }\n.#{$fa-css-prefix}-soccer-ball-o:before,\n.#{$fa-css-prefix}-futbol-o:before { content: $fa-var-futbol-o; }\n.#{$fa-css-prefix}-tty:before { content: $fa-var-tty; }\n.#{$fa-css-prefix}-binoculars:before { content: $fa-var-binoculars; }\n.#{$fa-css-prefix}-plug:before { content: $fa-var-plug; }\n.#{$fa-css-prefix}-slideshare:before { content: $fa-var-slideshare; }\n.#{$fa-css-prefix}-twitch:before { content: $fa-var-twitch; }\n.#{$fa-css-prefix}-yelp:before { content: $fa-var-yelp; }\n.#{$fa-css-prefix}-newspaper-o:before { content: $fa-var-newspaper-o; }\n.#{$fa-css-prefix}-wifi:before { content: $fa-var-wifi; }\n.#{$fa-css-prefix}-calculator:before { content: $fa-var-calculator; }\n.#{$fa-css-prefix}-paypal:before { content: $fa-var-paypal; }\n.#{$fa-css-prefix}-google-wallet:before { content: $fa-var-google-wallet; }\n.#{$fa-css-prefix}-cc-visa:before { content: $fa-var-cc-visa; }\n.#{$fa-css-prefix}-cc-mastercard:before { content: $fa-var-cc-mastercard; }\n.#{$fa-css-prefix}-cc-discover:before { content: $fa-var-cc-discover; }\n.#{$fa-css-prefix}-cc-amex:before { content: $fa-var-cc-amex; }\n.#{$fa-css-prefix}-cc-paypal:before { content: $fa-var-cc-paypal; }\n.#{$fa-css-prefix}-cc-stripe:before { content: $fa-var-cc-stripe; }\n.#{$fa-css-prefix}-bell-slash:before { content: $fa-var-bell-slash; }\n.#{$fa-css-prefix}-bell-slash-o:before { content: $fa-var-bell-slash-o; }\n.#{$fa-css-prefix}-trash:before { content: $fa-var-trash; }\n.#{$fa-css-prefix}-copyright:before { content: $fa-var-copyright; }\n.#{$fa-css-prefix}-at:before { content: $fa-var-at; }\n.#{$fa-css-prefix}-eyedropper:before { content: $fa-var-eyedropper; }\n.#{$fa-css-prefix}-paint-brush:before { content: $fa-var-paint-brush; }\n.#{$fa-css-prefix}-birthday-cake:before { content: $fa-var-birthday-cake; }\n.#{$fa-css-prefix}-area-chart:before { content: $fa-var-area-chart; }\n.#{$fa-css-prefix}-pie-chart:before { content: $fa-var-pie-chart; }\n.#{$fa-css-prefix}-line-chart:before { content: $fa-var-line-chart; }\n.#{$fa-css-prefix}-lastfm:before { content: $fa-var-lastfm; }\n.#{$fa-css-prefix}-lastfm-square:before { content: $fa-var-lastfm-square; }\n.#{$fa-css-prefix}-toggle-off:before { content: $fa-var-toggle-off; }\n.#{$fa-css-prefix}-toggle-on:before { content: $fa-var-toggle-on; }\n.#{$fa-css-prefix}-bicycle:before { content: $fa-var-bicycle; }\n.#{$fa-css-prefix}-bus:before { content: $fa-var-bus; }\n.#{$fa-css-prefix}-ioxhost:before { content: $fa-var-ioxhost; }\n.#{$fa-css-prefix}-angellist:before { content: $fa-var-angellist; }\n.#{$fa-css-prefix}-cc:before { content: $fa-var-cc; }\n.#{$fa-css-prefix}-shekel:before,\n.#{$fa-css-prefix}-sheqel:before,\n.#{$fa-css-prefix}-ils:before { content: $fa-var-ils; }\n.#{$fa-css-prefix}-meanpath:before { content: $fa-var-meanpath; }\n.#{$fa-css-prefix}-buysellads:before { content: $fa-var-buysellads; }\n.#{$fa-css-prefix}-connectdevelop:before { content: $fa-var-connectdevelop; }\n.#{$fa-css-prefix}-dashcube:before { content: $fa-var-dashcube; }\n.#{$fa-css-prefix}-forumbee:before { content: $fa-var-forumbee; }\n.#{$fa-css-prefix}-leanpub:before { content: $fa-var-leanpub; }\n.#{$fa-css-prefix}-sellsy:before { content: $fa-var-sellsy; }\n.#{$fa-css-prefix}-shirtsinbulk:before { content: $fa-var-shirtsinbulk; }\n.#{$fa-css-prefix}-simplybuilt:before { content: $fa-var-simplybuilt; }\n.#{$fa-css-prefix}-skyatlas:before { content: $fa-var-skyatlas; }\n.#{$fa-css-prefix}-cart-plus:before { content: $fa-var-cart-plus; }\n.#{$fa-css-prefix}-cart-arrow-down:before { content: $fa-var-cart-arrow-down; }\n.#{$fa-css-prefix}-diamond:before { content: $fa-var-diamond; }\n.#{$fa-css-prefix}-ship:before { content: $fa-var-ship; }\n.#{$fa-css-prefix}-user-secret:before { content: $fa-var-user-secret; }\n.#{$fa-css-prefix}-motorcycle:before { content: $fa-var-motorcycle; }\n.#{$fa-css-prefix}-street-view:before { content: $fa-var-street-view; }\n.#{$fa-css-prefix}-heartbeat:before { content: $fa-var-heartbeat; }\n.#{$fa-css-prefix}-venus:before { content: $fa-var-venus; }\n.#{$fa-css-prefix}-mars:before { content: $fa-var-mars; }\n.#{$fa-css-prefix}-mercury:before { content: $fa-var-mercury; }\n.#{$fa-css-prefix}-intersex:before,\n.#{$fa-css-prefix}-transgender:before { content: $fa-var-transgender; }\n.#{$fa-css-prefix}-transgender-alt:before { content: $fa-var-transgender-alt; }\n.#{$fa-css-prefix}-venus-double:before { content: $fa-var-venus-double; }\n.#{$fa-css-prefix}-mars-double:before { content: $fa-var-mars-double; }\n.#{$fa-css-prefix}-venus-mars:before { content: $fa-var-venus-mars; }\n.#{$fa-css-prefix}-mars-stroke:before { content: $fa-var-mars-stroke; }\n.#{$fa-css-prefix}-mars-stroke-v:before { content: $fa-var-mars-stroke-v; }\n.#{$fa-css-prefix}-mars-stroke-h:before { content: $fa-var-mars-stroke-h; }\n.#{$fa-css-prefix}-neuter:before { content: $fa-var-neuter; }\n.#{$fa-css-prefix}-genderless:before { content: $fa-var-genderless; }\n.#{$fa-css-prefix}-facebook-official:before { content: $fa-var-facebook-official; }\n.#{$fa-css-prefix}-pinterest-p:before { content: $fa-var-pinterest-p; }\n.#{$fa-css-prefix}-whatsapp:before { content: $fa-var-whatsapp; }\n.#{$fa-css-prefix}-server:before { content: $fa-var-server; }\n.#{$fa-css-prefix}-user-plus:before { content: $fa-var-user-plus; }\n.#{$fa-css-prefix}-user-times:before { content: $fa-var-user-times; }\n.#{$fa-css-prefix}-hotel:before,\n.#{$fa-css-prefix}-bed:before { content: $fa-var-bed; }\n.#{$fa-css-prefix}-viacoin:before { content: $fa-var-viacoin; }\n.#{$fa-css-prefix}-train:before { content: $fa-var-train; }\n.#{$fa-css-prefix}-subway:before { content: $fa-var-subway; }\n.#{$fa-css-prefix}-medium:before { content: $fa-var-medium; }\n.#{$fa-css-prefix}-yc:before,\n.#{$fa-css-prefix}-y-combinator:before { content: $fa-var-y-combinator; }\n.#{$fa-css-prefix}-optin-monster:before { content: $fa-var-optin-monster; }\n.#{$fa-css-prefix}-opencart:before { content: $fa-var-opencart; }\n.#{$fa-css-prefix}-expeditedssl:before { content: $fa-var-expeditedssl; }\n.#{$fa-css-prefix}-battery-4:before,\n.#{$fa-css-prefix}-battery-full:before { content: $fa-var-battery-full; }\n.#{$fa-css-prefix}-battery-3:before,\n.#{$fa-css-prefix}-battery-three-quarters:before { content: $fa-var-battery-three-quarters; }\n.#{$fa-css-prefix}-battery-2:before,\n.#{$fa-css-prefix}-battery-half:before { content: $fa-var-battery-half; }\n.#{$fa-css-prefix}-battery-1:before,\n.#{$fa-css-prefix}-battery-quarter:before { content: $fa-var-battery-quarter; }\n.#{$fa-css-prefix}-battery-0:before,\n.#{$fa-css-prefix}-battery-empty:before { content: $fa-var-battery-empty; }\n.#{$fa-css-prefix}-mouse-pointer:before { content: $fa-var-mouse-pointer; }\n.#{$fa-css-prefix}-i-cursor:before { content: $fa-var-i-cursor; }\n.#{$fa-css-prefix}-object-group:before { content: $fa-var-object-group; }\n.#{$fa-css-prefix}-object-ungroup:before { content: $fa-var-object-ungroup; }\n.#{$fa-css-prefix}-sticky-note:before { content: $fa-var-sticky-note; }\n.#{$fa-css-prefix}-sticky-note-o:before { content: $fa-var-sticky-note-o; }\n.#{$fa-css-prefix}-cc-jcb:before { content: $fa-var-cc-jcb; }\n.#{$fa-css-prefix}-cc-diners-club:before { content: $fa-var-cc-diners-club; }\n.#{$fa-css-prefix}-clone:before { content: $fa-var-clone; }\n.#{$fa-css-prefix}-balance-scale:before { content: $fa-var-balance-scale; }\n.#{$fa-css-prefix}-hourglass-o:before { content: $fa-var-hourglass-o; }\n.#{$fa-css-prefix}-hourglass-1:before,\n.#{$fa-css-prefix}-hourglass-start:before { content: $fa-var-hourglass-start; }\n.#{$fa-css-prefix}-hourglass-2:before,\n.#{$fa-css-prefix}-hourglass-half:before { content: $fa-var-hourglass-half; }\n.#{$fa-css-prefix}-hourglass-3:before,\n.#{$fa-css-prefix}-hourglass-end:before { content: $fa-var-hourglass-end; }\n.#{$fa-css-prefix}-hourglass:before { content: $fa-var-hourglass; }\n.#{$fa-css-prefix}-hand-grab-o:before,\n.#{$fa-css-prefix}-hand-rock-o:before { content: $fa-var-hand-rock-o; }\n.#{$fa-css-prefix}-hand-stop-o:before,\n.#{$fa-css-prefix}-hand-paper-o:before { content: $fa-var-hand-paper-o; }\n.#{$fa-css-prefix}-hand-scissors-o:before { content: $fa-var-hand-scissors-o; }\n.#{$fa-css-prefix}-hand-lizard-o:before { content: $fa-var-hand-lizard-o; }\n.#{$fa-css-prefix}-hand-spock-o:before { content: $fa-var-hand-spock-o; }\n.#{$fa-css-prefix}-hand-pointer-o:before { content: $fa-var-hand-pointer-o; }\n.#{$fa-css-prefix}-hand-peace-o:before { content: $fa-var-hand-peace-o; }\n.#{$fa-css-prefix}-trademark:before { content: $fa-var-trademark; }\n.#{$fa-css-prefix}-registered:before { content: $fa-var-registered; }\n.#{$fa-css-prefix}-creative-commons:before { content: $fa-var-creative-commons; }\n.#{$fa-css-prefix}-gg:before { content: $fa-var-gg; }\n.#{$fa-css-prefix}-gg-circle:before { content: $fa-var-gg-circle; }\n.#{$fa-css-prefix}-tripadvisor:before { content: $fa-var-tripadvisor; }\n.#{$fa-css-prefix}-odnoklassniki:before { content: $fa-var-odnoklassniki; }\n.#{$fa-css-prefix}-odnoklassniki-square:before { content: $fa-var-odnoklassniki-square; }\n.#{$fa-css-prefix}-get-pocket:before { content: $fa-var-get-pocket; }\n.#{$fa-css-prefix}-wikipedia-w:before { content: $fa-var-wikipedia-w; }\n.#{$fa-css-prefix}-safari:before { content: $fa-var-safari; }\n.#{$fa-css-prefix}-chrome:before { content: $fa-var-chrome; }\n.#{$fa-css-prefix}-firefox:before { content: $fa-var-firefox; }\n.#{$fa-css-prefix}-opera:before { content: $fa-var-opera; }\n.#{$fa-css-prefix}-internet-explorer:before { content: $fa-var-internet-explorer; }\n.#{$fa-css-prefix}-tv:before,\n.#{$fa-css-prefix}-television:before { content: $fa-var-television; }\n.#{$fa-css-prefix}-contao:before { content: $fa-var-contao; }\n.#{$fa-css-prefix}-500px:before { content: $fa-var-500px; }\n.#{$fa-css-prefix}-amazon:before { content: $fa-var-amazon; }\n.#{$fa-css-prefix}-calendar-plus-o:before { content: $fa-var-calendar-plus-o; }\n.#{$fa-css-prefix}-calendar-minus-o:before { content: $fa-var-calendar-minus-o; }\n.#{$fa-css-prefix}-calendar-times-o:before { content: $fa-var-calendar-times-o; }\n.#{$fa-css-prefix}-calendar-check-o:before { content: $fa-var-calendar-check-o; }\n.#{$fa-css-prefix}-industry:before { content: $fa-var-industry; }\n.#{$fa-css-prefix}-map-pin:before { content: $fa-var-map-pin; }\n.#{$fa-css-prefix}-map-signs:before { content: $fa-var-map-signs; }\n.#{$fa-css-prefix}-map-o:before { content: $fa-var-map-o; }\n.#{$fa-css-prefix}-map:before { content: $fa-var-map; }\n.#{$fa-css-prefix}-commenting:before { content: $fa-var-commenting; }\n.#{$fa-css-prefix}-commenting-o:before { content: $fa-var-commenting-o; }\n.#{$fa-css-prefix}-houzz:before { content: $fa-var-houzz; }\n.#{$fa-css-prefix}-vimeo:before { content: $fa-var-vimeo; }\n.#{$fa-css-prefix}-black-tie:before { content: $fa-var-black-tie; }\n.#{$fa-css-prefix}-fonticons:before { content: $fa-var-fonticons; }\n.#{$fa-css-prefix}-reddit-alien:before { content: $fa-var-reddit-alien; }\n.#{$fa-css-prefix}-edge:before { content: $fa-var-edge; }\n.#{$fa-css-prefix}-credit-card-alt:before { content: $fa-var-credit-card-alt; }\n.#{$fa-css-prefix}-codiepie:before { content: $fa-var-codiepie; }\n.#{$fa-css-prefix}-modx:before { content: $fa-var-modx; }\n.#{$fa-css-prefix}-fort-awesome:before { content: $fa-var-fort-awesome; }\n.#{$fa-css-prefix}-usb:before { content: $fa-var-usb; }\n.#{$fa-css-prefix}-product-hunt:before { content: $fa-var-product-hunt; }\n.#{$fa-css-prefix}-mixcloud:before { content: $fa-var-mixcloud; }\n.#{$fa-css-prefix}-scribd:before { content: $fa-var-scribd; }\n.#{$fa-css-prefix}-pause-circle:before { content: $fa-var-pause-circle; }\n.#{$fa-css-prefix}-pause-circle-o:before { content: $fa-var-pause-circle-o; }\n.#{$fa-css-prefix}-stop-circle:before { content: $fa-var-stop-circle; }\n.#{$fa-css-prefix}-stop-circle-o:before { content: $fa-var-stop-circle-o; }\n.#{$fa-css-prefix}-shopping-bag:before { content: $fa-var-shopping-bag; }\n.#{$fa-css-prefix}-shopping-basket:before { content: $fa-var-shopping-basket; }\n.#{$fa-css-prefix}-hashtag:before { content: $fa-var-hashtag; }\n.#{$fa-css-prefix}-bluetooth:before { content: $fa-var-bluetooth; }\n.#{$fa-css-prefix}-bluetooth-b:before { content: $fa-var-bluetooth-b; }\n.#{$fa-css-prefix}-percent:before { content: $fa-var-percent; }\n.#{$fa-css-prefix}-gitlab:before { content: $fa-var-gitlab; }\n.#{$fa-css-prefix}-wpbeginner:before { content: $fa-var-wpbeginner; }\n.#{$fa-css-prefix}-wpforms:before { content: $fa-var-wpforms; }\n.#{$fa-css-prefix}-envira:before { content: $fa-var-envira; }\n.#{$fa-css-prefix}-universal-access:before { content: $fa-var-universal-access; }\n.#{$fa-css-prefix}-wheelchair-alt:before { content: $fa-var-wheelchair-alt; }\n.#{$fa-css-prefix}-question-circle-o:before { content: $fa-var-question-circle-o; }\n.#{$fa-css-prefix}-blind:before { content: $fa-var-blind; }\n.#{$fa-css-prefix}-audio-description:before { content: $fa-var-audio-description; }\n.#{$fa-css-prefix}-volume-control-phone:before { content: $fa-var-volume-control-phone; }\n.#{$fa-css-prefix}-braille:before { content: $fa-var-braille; }\n.#{$fa-css-prefix}-assistive-listening-systems:before { content: $fa-var-assistive-listening-systems; }\n.#{$fa-css-prefix}-asl-interpreting:before,\n.#{$fa-css-prefix}-american-sign-language-interpreting:before { content: $fa-var-american-sign-language-interpreting; }\n.#{$fa-css-prefix}-deafness:before,\n.#{$fa-css-prefix}-hard-of-hearing:before,\n.#{$fa-css-prefix}-deaf:before { content: $fa-var-deaf; }\n.#{$fa-css-prefix}-glide:before { content: $fa-var-glide; }\n.#{$fa-css-prefix}-glide-g:before { content: $fa-var-glide-g; }\n.#{$fa-css-prefix}-signing:before,\n.#{$fa-css-prefix}-sign-language:before { content: $fa-var-sign-language; }\n.#{$fa-css-prefix}-low-vision:before { content: $fa-var-low-vision; }\n.#{$fa-css-prefix}-viadeo:before { content: $fa-var-viadeo; }\n.#{$fa-css-prefix}-viadeo-square:before { content: $fa-var-viadeo-square; }\n.#{$fa-css-prefix}-snapchat:before { content: $fa-var-snapchat; }\n.#{$fa-css-prefix}-snapchat-ghost:before { content: $fa-var-snapchat-ghost; }\n.#{$fa-css-prefix}-snapchat-square:before { content: $fa-var-snapchat-square; }\n.#{$fa-css-prefix}-pied-piper:before { content: $fa-var-pied-piper; }\n.#{$fa-css-prefix}-first-order:before { content: $fa-var-first-order; }\n.#{$fa-css-prefix}-yoast:before { content: $fa-var-yoast; }\n.#{$fa-css-prefix}-themeisle:before { content: $fa-var-themeisle; }\n.#{$fa-css-prefix}-google-plus-circle:before,\n.#{$fa-css-prefix}-google-plus-official:before { content: $fa-var-google-plus-official; }\n.#{$fa-css-prefix}-fa:before,\n.#{$fa-css-prefix}-font-awesome:before { content: $fa-var-font-awesome; }\n"
  },
  {
    "path": "app_backend/static/plugin/font-awesome/scss/_larger.scss",
    "content": "// Icon Sizes\n// -------------------------\n\n/* makes the font 33% larger relative to the icon container */\n.#{$fa-css-prefix}-lg {\n  font-size: (4em / 3);\n  line-height: (3em / 4);\n  vertical-align: -15%;\n}\n.#{$fa-css-prefix}-2x { font-size: 2em; }\n.#{$fa-css-prefix}-3x { font-size: 3em; }\n.#{$fa-css-prefix}-4x { font-size: 4em; }\n.#{$fa-css-prefix}-5x { font-size: 5em; }\n"
  },
  {
    "path": "app_backend/static/plugin/font-awesome/scss/_list.scss",
    "content": "// List Icons\n// -------------------------\n\n.#{$fa-css-prefix}-ul {\n  padding-left: 0;\n  margin-left: $fa-li-width;\n  list-style-type: none;\n  > li { position: relative; }\n}\n.#{$fa-css-prefix}-li {\n  position: absolute;\n  left: -$fa-li-width;\n  width: $fa-li-width;\n  top: (2em / 14);\n  text-align: center;\n  &.#{$fa-css-prefix}-lg {\n    left: -$fa-li-width + (4em / 14);\n  }\n}\n"
  },
  {
    "path": "app_backend/static/plugin/font-awesome/scss/_mixins.scss",
    "content": "// Mixins\n// --------------------------\n\n@mixin fa-icon() {\n  display: inline-block;\n  font: normal normal normal #{$fa-font-size-base}/#{$fa-line-height-base} FontAwesome; // shortening font declaration\n  font-size: inherit; // can't have font-size inherit on line above, so need to override\n  text-rendering: auto; // optimizelegibility throws things off #1094\n  -webkit-font-smoothing: antialiased;\n  -moz-osx-font-smoothing: grayscale;\n\n}\n\n@mixin fa-icon-rotate($degrees, $rotation) {\n  -ms-filter: \"progid:DXImageTransform.Microsoft.BasicImage(rotation=#{$rotation})\";\n  -webkit-transform: rotate($degrees);\n      -ms-transform: rotate($degrees);\n          transform: rotate($degrees);\n}\n\n@mixin fa-icon-flip($horiz, $vert, $rotation) {\n  -ms-filter: \"progid:DXImageTransform.Microsoft.BasicImage(rotation=#{$rotation}, mirror=1)\";\n  -webkit-transform: scale($horiz, $vert);\n      -ms-transform: scale($horiz, $vert);\n          transform: scale($horiz, $vert);\n}\n\n\n// Only display content to screen readers. A la Bootstrap 4.\n//\n// See: http://a11yproject.com/posts/how-to-hide-content/\n\n@mixin sr-only {\n  position: absolute;\n  width: 1px;\n  height: 1px;\n  padding: 0;\n  margin: -1px;\n  overflow: hidden;\n  clip: rect(0,0,0,0);\n  border: 0;\n}\n\n// Use in conjunction with .sr-only to only display content when it's focused.\n//\n// Useful for \"Skip to main content\" links; see http://www.w3.org/TR/2013/NOTE-WCAG20-TECHS-20130905/G1\n//\n// Credit: HTML5 Boilerplate\n\n@mixin sr-only-focusable {\n  &:active,\n  &:focus {\n    position: static;\n    width: auto;\n    height: auto;\n    margin: 0;\n    overflow: visible;\n    clip: auto;\n  }\n}\n"
  },
  {
    "path": "app_backend/static/plugin/font-awesome/scss/_path.scss",
    "content": "/* FONT PATH\n * -------------------------- */\n\n@font-face {\n  font-family: 'FontAwesome';\n  src: url('#{$fa-font-path}/fontawesome-webfont.eot?v=#{$fa-version}');\n  src: url('#{$fa-font-path}/fontawesome-webfont.eot?#iefix&v=#{$fa-version}') format('embedded-opentype'),\n    url('#{$fa-font-path}/fontawesome-webfont.woff2?v=#{$fa-version}') format('woff2'),\n    url('#{$fa-font-path}/fontawesome-webfont.woff?v=#{$fa-version}') format('woff'),\n    url('#{$fa-font-path}/fontawesome-webfont.ttf?v=#{$fa-version}') format('truetype'),\n    url('#{$fa-font-path}/fontawesome-webfont.svg?v=#{$fa-version}#fontawesomeregular') format('svg');\n//  src: url('#{$fa-font-path}/FontAwesome.otf') format('opentype'); // used when developing fonts\n  font-weight: normal;\n  font-style: normal;\n}\n"
  },
  {
    "path": "app_backend/static/plugin/font-awesome/scss/_rotated-flipped.scss",
    "content": "// Rotated & Flipped Icons\n// -------------------------\n\n.#{$fa-css-prefix}-rotate-90  { @include fa-icon-rotate(90deg, 1);  }\n.#{$fa-css-prefix}-rotate-180 { @include fa-icon-rotate(180deg, 2); }\n.#{$fa-css-prefix}-rotate-270 { @include fa-icon-rotate(270deg, 3); }\n\n.#{$fa-css-prefix}-flip-horizontal { @include fa-icon-flip(-1, 1, 0); }\n.#{$fa-css-prefix}-flip-vertical   { @include fa-icon-flip(1, -1, 2); }\n\n// Hook for IE8-9\n// -------------------------\n\n:root .#{$fa-css-prefix}-rotate-90,\n:root .#{$fa-css-prefix}-rotate-180,\n:root .#{$fa-css-prefix}-rotate-270,\n:root .#{$fa-css-prefix}-flip-horizontal,\n:root .#{$fa-css-prefix}-flip-vertical {\n  filter: none;\n}\n"
  },
  {
    "path": "app_backend/static/plugin/font-awesome/scss/_screen-reader.scss",
    "content": "// Screen Readers\n// -------------------------\n\n.sr-only { @include sr-only(); }\n.sr-only-focusable { @include sr-only-focusable(); }\n"
  },
  {
    "path": "app_backend/static/plugin/font-awesome/scss/_spinning.scss",
    "content": "// Spinning Icons\n// --------------------------\n\n.#{$fa-css-prefix}-spin {\n  -webkit-animation: fa-spin 2s infinite linear;\n          animation: fa-spin 2s infinite linear;\n}\n\n@-webkit-keyframes fa-spin {\n  0% {\n    -webkit-transform: rotate(0deg);\n            transform: rotate(0deg);\n  }\n  100% {\n    -webkit-transform: rotate(359deg);\n            transform: rotate(359deg);\n  }\n}\n\n@keyframes fa-spin {\n  0% {\n    -webkit-transform: rotate(0deg);\n            transform: rotate(0deg);\n  }\n  100% {\n    -webkit-transform: rotate(359deg);\n            transform: rotate(359deg);\n  }\n}\n"
  },
  {
    "path": "app_backend/static/plugin/font-awesome/scss/_stacked.scss",
    "content": "// Stacked Icons\n// -------------------------\n\n.#{$fa-css-prefix}-stack {\n  position: relative;\n  display: inline-block;\n  width: 2em;\n  height: 2em;\n  line-height: 2em;\n  vertical-align: middle;\n}\n.#{$fa-css-prefix}-stack-1x, .#{$fa-css-prefix}-stack-2x {\n  position: absolute;\n  left: 0;\n  width: 100%;\n  text-align: center;\n}\n.#{$fa-css-prefix}-stack-1x { line-height: inherit; }\n.#{$fa-css-prefix}-stack-2x { font-size: 2em; }\n.#{$fa-css-prefix}-inverse { color: $fa-inverse; }\n"
  },
  {
    "path": "app_backend/static/plugin/font-awesome/scss/_variables.scss",
    "content": "// Variables\n// --------------------------\n\n$fa-font-path:        \"../fonts\" !default;\n$fa-font-size-base:   14px !default;\n$fa-line-height-base: 1 !default;\n//$fa-font-path:        \"//netdna.bootstrapcdn.com/font-awesome/4.6.3/fonts\" !default; // for referencing Bootstrap CDN font files directly\n$fa-css-prefix:       fa !default;\n$fa-version:          \"4.6.3\" !default;\n$fa-border-color:     #eee !default;\n$fa-inverse:          #fff !default;\n$fa-li-width:         (30em / 14) !default;\n\n$fa-var-500px: \"\\f26e\";\n$fa-var-adjust: \"\\f042\";\n$fa-var-adn: \"\\f170\";\n$fa-var-align-center: \"\\f037\";\n$fa-var-align-justify: \"\\f039\";\n$fa-var-align-left: \"\\f036\";\n$fa-var-align-right: \"\\f038\";\n$fa-var-amazon: \"\\f270\";\n$fa-var-ambulance: \"\\f0f9\";\n$fa-var-american-sign-language-interpreting: \"\\f2a3\";\n$fa-var-anchor: \"\\f13d\";\n$fa-var-android: \"\\f17b\";\n$fa-var-angellist: \"\\f209\";\n$fa-var-angle-double-down: \"\\f103\";\n$fa-var-angle-double-left: \"\\f100\";\n$fa-var-angle-double-right: \"\\f101\";\n$fa-var-angle-double-up: \"\\f102\";\n$fa-var-angle-down: \"\\f107\";\n$fa-var-angle-left: \"\\f104\";\n$fa-var-angle-right: \"\\f105\";\n$fa-var-angle-up: \"\\f106\";\n$fa-var-apple: \"\\f179\";\n$fa-var-archive: \"\\f187\";\n$fa-var-area-chart: \"\\f1fe\";\n$fa-var-arrow-circle-down: \"\\f0ab\";\n$fa-var-arrow-circle-left: \"\\f0a8\";\n$fa-var-arrow-circle-o-down: \"\\f01a\";\n$fa-var-arrow-circle-o-left: \"\\f190\";\n$fa-var-arrow-circle-o-right: \"\\f18e\";\n$fa-var-arrow-circle-o-up: \"\\f01b\";\n$fa-var-arrow-circle-right: \"\\f0a9\";\n$fa-var-arrow-circle-up: \"\\f0aa\";\n$fa-var-arrow-down: \"\\f063\";\n$fa-var-arrow-left: \"\\f060\";\n$fa-var-arrow-right: \"\\f061\";\n$fa-var-arrow-up: \"\\f062\";\n$fa-var-arrows: \"\\f047\";\n$fa-var-arrows-alt: \"\\f0b2\";\n$fa-var-arrows-h: \"\\f07e\";\n$fa-var-arrows-v: \"\\f07d\";\n$fa-var-asl-interpreting: \"\\f2a3\";\n$fa-var-assistive-listening-systems: \"\\f2a2\";\n$fa-var-asterisk: \"\\f069\";\n$fa-var-at: \"\\f1fa\";\n$fa-var-audio-description: \"\\f29e\";\n$fa-var-automobile: \"\\f1b9\";\n$fa-var-backward: \"\\f04a\";\n$fa-var-balance-scale: \"\\f24e\";\n$fa-var-ban: \"\\f05e\";\n$fa-var-bank: \"\\f19c\";\n$fa-var-bar-chart: \"\\f080\";\n$fa-var-bar-chart-o: \"\\f080\";\n$fa-var-barcode: \"\\f02a\";\n$fa-var-bars: \"\\f0c9\";\n$fa-var-battery-0: \"\\f244\";\n$fa-var-battery-1: \"\\f243\";\n$fa-var-battery-2: \"\\f242\";\n$fa-var-battery-3: \"\\f241\";\n$fa-var-battery-4: \"\\f240\";\n$fa-var-battery-empty: \"\\f244\";\n$fa-var-battery-full: \"\\f240\";\n$fa-var-battery-half: \"\\f242\";\n$fa-var-battery-quarter: \"\\f243\";\n$fa-var-battery-three-quarters: \"\\f241\";\n$fa-var-bed: \"\\f236\";\n$fa-var-beer: \"\\f0fc\";\n$fa-var-behance: \"\\f1b4\";\n$fa-var-behance-square: \"\\f1b5\";\n$fa-var-bell: \"\\f0f3\";\n$fa-var-bell-o: \"\\f0a2\";\n$fa-var-bell-slash: \"\\f1f6\";\n$fa-var-bell-slash-o: \"\\f1f7\";\n$fa-var-bicycle: \"\\f206\";\n$fa-var-binoculars: \"\\f1e5\";\n$fa-var-birthday-cake: \"\\f1fd\";\n$fa-var-bitbucket: \"\\f171\";\n$fa-var-bitbucket-square: \"\\f172\";\n$fa-var-bitcoin: \"\\f15a\";\n$fa-var-black-tie: \"\\f27e\";\n$fa-var-blind: \"\\f29d\";\n$fa-var-bluetooth: \"\\f293\";\n$fa-var-bluetooth-b: \"\\f294\";\n$fa-var-bold: \"\\f032\";\n$fa-var-bolt: \"\\f0e7\";\n$fa-var-bomb: \"\\f1e2\";\n$fa-var-book: \"\\f02d\";\n$fa-var-bookmark: \"\\f02e\";\n$fa-var-bookmark-o: \"\\f097\";\n$fa-var-braille: \"\\f2a1\";\n$fa-var-briefcase: \"\\f0b1\";\n$fa-var-btc: \"\\f15a\";\n$fa-var-bug: \"\\f188\";\n$fa-var-building: \"\\f1ad\";\n$fa-var-building-o: \"\\f0f7\";\n$fa-var-bullhorn: \"\\f0a1\";\n$fa-var-bullseye: \"\\f140\";\n$fa-var-bus: \"\\f207\";\n$fa-var-buysellads: \"\\f20d\";\n$fa-var-cab: \"\\f1ba\";\n$fa-var-calculator: \"\\f1ec\";\n$fa-var-calendar: \"\\f073\";\n$fa-var-calendar-check-o: \"\\f274\";\n$fa-var-calendar-minus-o: \"\\f272\";\n$fa-var-calendar-o: \"\\f133\";\n$fa-var-calendar-plus-o: \"\\f271\";\n$fa-var-calendar-times-o: \"\\f273\";\n$fa-var-camera: \"\\f030\";\n$fa-var-camera-retro: \"\\f083\";\n$fa-var-car: \"\\f1b9\";\n$fa-var-caret-down: \"\\f0d7\";\n$fa-var-caret-left: \"\\f0d9\";\n$fa-var-caret-right: \"\\f0da\";\n$fa-var-caret-square-o-down: \"\\f150\";\n$fa-var-caret-square-o-left: \"\\f191\";\n$fa-var-caret-square-o-right: \"\\f152\";\n$fa-var-caret-square-o-up: \"\\f151\";\n$fa-var-caret-up: \"\\f0d8\";\n$fa-var-cart-arrow-down: \"\\f218\";\n$fa-var-cart-plus: \"\\f217\";\n$fa-var-cc: \"\\f20a\";\n$fa-var-cc-amex: \"\\f1f3\";\n$fa-var-cc-diners-club: \"\\f24c\";\n$fa-var-cc-discover: \"\\f1f2\";\n$fa-var-cc-jcb: \"\\f24b\";\n$fa-var-cc-mastercard: \"\\f1f1\";\n$fa-var-cc-paypal: \"\\f1f4\";\n$fa-var-cc-stripe: \"\\f1f5\";\n$fa-var-cc-visa: \"\\f1f0\";\n$fa-var-certificate: \"\\f0a3\";\n$fa-var-chain: \"\\f0c1\";\n$fa-var-chain-broken: \"\\f127\";\n$fa-var-check: \"\\f00c\";\n$fa-var-check-circle: \"\\f058\";\n$fa-var-check-circle-o: \"\\f05d\";\n$fa-var-check-square: \"\\f14a\";\n$fa-var-check-square-o: \"\\f046\";\n$fa-var-chevron-circle-down: \"\\f13a\";\n$fa-var-chevron-circle-left: \"\\f137\";\n$fa-var-chevron-circle-right: \"\\f138\";\n$fa-var-chevron-circle-up: \"\\f139\";\n$fa-var-chevron-down: \"\\f078\";\n$fa-var-chevron-left: \"\\f053\";\n$fa-var-chevron-right: \"\\f054\";\n$fa-var-chevron-up: \"\\f077\";\n$fa-var-child: \"\\f1ae\";\n$fa-var-chrome: \"\\f268\";\n$fa-var-circle: \"\\f111\";\n$fa-var-circle-o: \"\\f10c\";\n$fa-var-circle-o-notch: \"\\f1ce\";\n$fa-var-circle-thin: \"\\f1db\";\n$fa-var-clipboard: \"\\f0ea\";\n$fa-var-clock-o: \"\\f017\";\n$fa-var-clone: \"\\f24d\";\n$fa-var-close: \"\\f00d\";\n$fa-var-cloud: \"\\f0c2\";\n$fa-var-cloud-download: \"\\f0ed\";\n$fa-var-cloud-upload: \"\\f0ee\";\n$fa-var-cny: \"\\f157\";\n$fa-var-code: \"\\f121\";\n$fa-var-code-fork: \"\\f126\";\n$fa-var-codepen: \"\\f1cb\";\n$fa-var-codiepie: \"\\f284\";\n$fa-var-coffee: \"\\f0f4\";\n$fa-var-cog: \"\\f013\";\n$fa-var-cogs: \"\\f085\";\n$fa-var-columns: \"\\f0db\";\n$fa-var-comment: \"\\f075\";\n$fa-var-comment-o: \"\\f0e5\";\n$fa-var-commenting: \"\\f27a\";\n$fa-var-commenting-o: \"\\f27b\";\n$fa-var-comments: \"\\f086\";\n$fa-var-comments-o: \"\\f0e6\";\n$fa-var-compass: \"\\f14e\";\n$fa-var-compress: \"\\f066\";\n$fa-var-connectdevelop: \"\\f20e\";\n$fa-var-contao: \"\\f26d\";\n$fa-var-copy: \"\\f0c5\";\n$fa-var-copyright: \"\\f1f9\";\n$fa-var-creative-commons: \"\\f25e\";\n$fa-var-credit-card: \"\\f09d\";\n$fa-var-credit-card-alt: \"\\f283\";\n$fa-var-crop: \"\\f125\";\n$fa-var-crosshairs: \"\\f05b\";\n$fa-var-css3: \"\\f13c\";\n$fa-var-cube: \"\\f1b2\";\n$fa-var-cubes: \"\\f1b3\";\n$fa-var-cut: \"\\f0c4\";\n$fa-var-cutlery: \"\\f0f5\";\n$fa-var-dashboard: \"\\f0e4\";\n$fa-var-dashcube: \"\\f210\";\n$fa-var-database: \"\\f1c0\";\n$fa-var-deaf: \"\\f2a4\";\n$fa-var-deafness: \"\\f2a4\";\n$fa-var-dedent: \"\\f03b\";\n$fa-var-delicious: \"\\f1a5\";\n$fa-var-desktop: \"\\f108\";\n$fa-var-deviantart: \"\\f1bd\";\n$fa-var-diamond: \"\\f219\";\n$fa-var-digg: \"\\f1a6\";\n$fa-var-dollar: \"\\f155\";\n$fa-var-dot-circle-o: \"\\f192\";\n$fa-var-download: \"\\f019\";\n$fa-var-dribbble: \"\\f17d\";\n$fa-var-dropbox: \"\\f16b\";\n$fa-var-drupal: \"\\f1a9\";\n$fa-var-edge: \"\\f282\";\n$fa-var-edit: \"\\f044\";\n$fa-var-eject: \"\\f052\";\n$fa-var-ellipsis-h: \"\\f141\";\n$fa-var-ellipsis-v: \"\\f142\";\n$fa-var-empire: \"\\f1d1\";\n$fa-var-envelope: \"\\f0e0\";\n$fa-var-envelope-o: \"\\f003\";\n$fa-var-envelope-square: \"\\f199\";\n$fa-var-envira: \"\\f299\";\n$fa-var-eraser: \"\\f12d\";\n$fa-var-eur: \"\\f153\";\n$fa-var-euro: \"\\f153\";\n$fa-var-exchange: \"\\f0ec\";\n$fa-var-exclamation: \"\\f12a\";\n$fa-var-exclamation-circle: \"\\f06a\";\n$fa-var-exclamation-triangle: \"\\f071\";\n$fa-var-expand: \"\\f065\";\n$fa-var-expeditedssl: \"\\f23e\";\n$fa-var-external-link: \"\\f08e\";\n$fa-var-external-link-square: \"\\f14c\";\n$fa-var-eye: \"\\f06e\";\n$fa-var-eye-slash: \"\\f070\";\n$fa-var-eyedropper: \"\\f1fb\";\n$fa-var-fa: \"\\f2b4\";\n$fa-var-facebook: \"\\f09a\";\n$fa-var-facebook-f: \"\\f09a\";\n$fa-var-facebook-official: \"\\f230\";\n$fa-var-facebook-square: \"\\f082\";\n$fa-var-fast-backward: \"\\f049\";\n$fa-var-fast-forward: \"\\f050\";\n$fa-var-fax: \"\\f1ac\";\n$fa-var-feed: \"\\f09e\";\n$fa-var-female: \"\\f182\";\n$fa-var-fighter-jet: \"\\f0fb\";\n$fa-var-file: \"\\f15b\";\n$fa-var-file-archive-o: \"\\f1c6\";\n$fa-var-file-audio-o: \"\\f1c7\";\n$fa-var-file-code-o: \"\\f1c9\";\n$fa-var-file-excel-o: \"\\f1c3\";\n$fa-var-file-image-o: \"\\f1c5\";\n$fa-var-file-movie-o: \"\\f1c8\";\n$fa-var-file-o: \"\\f016\";\n$fa-var-file-pdf-o: \"\\f1c1\";\n$fa-var-file-photo-o: \"\\f1c5\";\n$fa-var-file-picture-o: \"\\f1c5\";\n$fa-var-file-powerpoint-o: \"\\f1c4\";\n$fa-var-file-sound-o: \"\\f1c7\";\n$fa-var-file-text: \"\\f15c\";\n$fa-var-file-text-o: \"\\f0f6\";\n$fa-var-file-video-o: \"\\f1c8\";\n$fa-var-file-word-o: \"\\f1c2\";\n$fa-var-file-zip-o: \"\\f1c6\";\n$fa-var-files-o: \"\\f0c5\";\n$fa-var-film: \"\\f008\";\n$fa-var-filter: \"\\f0b0\";\n$fa-var-fire: \"\\f06d\";\n$fa-var-fire-extinguisher: \"\\f134\";\n$fa-var-firefox: \"\\f269\";\n$fa-var-first-order: \"\\f2b0\";\n$fa-var-flag: \"\\f024\";\n$fa-var-flag-checkered: \"\\f11e\";\n$fa-var-flag-o: \"\\f11d\";\n$fa-var-flash: \"\\f0e7\";\n$fa-var-flask: \"\\f0c3\";\n$fa-var-flickr: \"\\f16e\";\n$fa-var-floppy-o: \"\\f0c7\";\n$fa-var-folder: \"\\f07b\";\n$fa-var-folder-o: \"\\f114\";\n$fa-var-folder-open: \"\\f07c\";\n$fa-var-folder-open-o: \"\\f115\";\n$fa-var-font: \"\\f031\";\n$fa-var-font-awesome: \"\\f2b4\";\n$fa-var-fonticons: \"\\f280\";\n$fa-var-fort-awesome: \"\\f286\";\n$fa-var-forumbee: \"\\f211\";\n$fa-var-forward: \"\\f04e\";\n$fa-var-foursquare: \"\\f180\";\n$fa-var-frown-o: \"\\f119\";\n$fa-var-futbol-o: \"\\f1e3\";\n$fa-var-gamepad: \"\\f11b\";\n$fa-var-gavel: \"\\f0e3\";\n$fa-var-gbp: \"\\f154\";\n$fa-var-ge: \"\\f1d1\";\n$fa-var-gear: \"\\f013\";\n$fa-var-gears: \"\\f085\";\n$fa-var-genderless: \"\\f22d\";\n$fa-var-get-pocket: \"\\f265\";\n$fa-var-gg: \"\\f260\";\n$fa-var-gg-circle: \"\\f261\";\n$fa-var-gift: \"\\f06b\";\n$fa-var-git: \"\\f1d3\";\n$fa-var-git-square: \"\\f1d2\";\n$fa-var-github: \"\\f09b\";\n$fa-var-github-alt: \"\\f113\";\n$fa-var-github-square: \"\\f092\";\n$fa-var-gitlab: \"\\f296\";\n$fa-var-gittip: \"\\f184\";\n$fa-var-glass: \"\\f000\";\n$fa-var-glide: \"\\f2a5\";\n$fa-var-glide-g: \"\\f2a6\";\n$fa-var-globe: \"\\f0ac\";\n$fa-var-google: \"\\f1a0\";\n$fa-var-google-plus: \"\\f0d5\";\n$fa-var-google-plus-circle: \"\\f2b3\";\n$fa-var-google-plus-official: \"\\f2b3\";\n$fa-var-google-plus-square: \"\\f0d4\";\n$fa-var-google-wallet: \"\\f1ee\";\n$fa-var-graduation-cap: \"\\f19d\";\n$fa-var-gratipay: \"\\f184\";\n$fa-var-group: \"\\f0c0\";\n$fa-var-h-square: \"\\f0fd\";\n$fa-var-hacker-news: \"\\f1d4\";\n$fa-var-hand-grab-o: \"\\f255\";\n$fa-var-hand-lizard-o: \"\\f258\";\n$fa-var-hand-o-down: \"\\f0a7\";\n$fa-var-hand-o-left: \"\\f0a5\";\n$fa-var-hand-o-right: \"\\f0a4\";\n$fa-var-hand-o-up: \"\\f0a6\";\n$fa-var-hand-paper-o: \"\\f256\";\n$fa-var-hand-peace-o: \"\\f25b\";\n$fa-var-hand-pointer-o: \"\\f25a\";\n$fa-var-hand-rock-o: \"\\f255\";\n$fa-var-hand-scissors-o: \"\\f257\";\n$fa-var-hand-spock-o: \"\\f259\";\n$fa-var-hand-stop-o: \"\\f256\";\n$fa-var-hard-of-hearing: \"\\f2a4\";\n$fa-var-hashtag: \"\\f292\";\n$fa-var-hdd-o: \"\\f0a0\";\n$fa-var-header: \"\\f1dc\";\n$fa-var-headphones: \"\\f025\";\n$fa-var-heart: \"\\f004\";\n$fa-var-heart-o: \"\\f08a\";\n$fa-var-heartbeat: \"\\f21e\";\n$fa-var-history: \"\\f1da\";\n$fa-var-home: \"\\f015\";\n$fa-var-hospital-o: \"\\f0f8\";\n$fa-var-hotel: \"\\f236\";\n$fa-var-hourglass: \"\\f254\";\n$fa-var-hourglass-1: \"\\f251\";\n$fa-var-hourglass-2: \"\\f252\";\n$fa-var-hourglass-3: \"\\f253\";\n$fa-var-hourglass-end: \"\\f253\";\n$fa-var-hourglass-half: \"\\f252\";\n$fa-var-hourglass-o: \"\\f250\";\n$fa-var-hourglass-start: \"\\f251\";\n$fa-var-houzz: \"\\f27c\";\n$fa-var-html5: \"\\f13b\";\n$fa-var-i-cursor: \"\\f246\";\n$fa-var-ils: \"\\f20b\";\n$fa-var-image: \"\\f03e\";\n$fa-var-inbox: \"\\f01c\";\n$fa-var-indent: \"\\f03c\";\n$fa-var-industry: \"\\f275\";\n$fa-var-info: \"\\f129\";\n$fa-var-info-circle: \"\\f05a\";\n$fa-var-inr: \"\\f156\";\n$fa-var-instagram: \"\\f16d\";\n$fa-var-institution: \"\\f19c\";\n$fa-var-internet-explorer: \"\\f26b\";\n$fa-var-intersex: \"\\f224\";\n$fa-var-ioxhost: \"\\f208\";\n$fa-var-italic: \"\\f033\";\n$fa-var-joomla: \"\\f1aa\";\n$fa-var-jpy: \"\\f157\";\n$fa-var-jsfiddle: \"\\f1cc\";\n$fa-var-key: \"\\f084\";\n$fa-var-keyboard-o: \"\\f11c\";\n$fa-var-krw: \"\\f159\";\n$fa-var-language: \"\\f1ab\";\n$fa-var-laptop: \"\\f109\";\n$fa-var-lastfm: \"\\f202\";\n$fa-var-lastfm-square: \"\\f203\";\n$fa-var-leaf: \"\\f06c\";\n$fa-var-leanpub: \"\\f212\";\n$fa-var-legal: \"\\f0e3\";\n$fa-var-lemon-o: \"\\f094\";\n$fa-var-level-down: \"\\f149\";\n$fa-var-level-up: \"\\f148\";\n$fa-var-life-bouy: \"\\f1cd\";\n$fa-var-life-buoy: \"\\f1cd\";\n$fa-var-life-ring: \"\\f1cd\";\n$fa-var-life-saver: \"\\f1cd\";\n$fa-var-lightbulb-o: \"\\f0eb\";\n$fa-var-line-chart: \"\\f201\";\n$fa-var-link: \"\\f0c1\";\n$fa-var-linkedin: \"\\f0e1\";\n$fa-var-linkedin-square: \"\\f08c\";\n$fa-var-linux: \"\\f17c\";\n$fa-var-list: \"\\f03a\";\n$fa-var-list-alt: \"\\f022\";\n$fa-var-list-ol: \"\\f0cb\";\n$fa-var-list-ul: \"\\f0ca\";\n$fa-var-location-arrow: \"\\f124\";\n$fa-var-lock: \"\\f023\";\n$fa-var-long-arrow-down: \"\\f175\";\n$fa-var-long-arrow-left: \"\\f177\";\n$fa-var-long-arrow-right: \"\\f178\";\n$fa-var-long-arrow-up: \"\\f176\";\n$fa-var-low-vision: \"\\f2a8\";\n$fa-var-magic: \"\\f0d0\";\n$fa-var-magnet: \"\\f076\";\n$fa-var-mail-forward: \"\\f064\";\n$fa-var-mail-reply: \"\\f112\";\n$fa-var-mail-reply-all: \"\\f122\";\n$fa-var-male: \"\\f183\";\n$fa-var-map: \"\\f279\";\n$fa-var-map-marker: \"\\f041\";\n$fa-var-map-o: \"\\f278\";\n$fa-var-map-pin: \"\\f276\";\n$fa-var-map-signs: \"\\f277\";\n$fa-var-mars: \"\\f222\";\n$fa-var-mars-double: \"\\f227\";\n$fa-var-mars-stroke: \"\\f229\";\n$fa-var-mars-stroke-h: \"\\f22b\";\n$fa-var-mars-stroke-v: \"\\f22a\";\n$fa-var-maxcdn: \"\\f136\";\n$fa-var-meanpath: \"\\f20c\";\n$fa-var-medium: \"\\f23a\";\n$fa-var-medkit: \"\\f0fa\";\n$fa-var-meh-o: \"\\f11a\";\n$fa-var-mercury: \"\\f223\";\n$fa-var-microphone: \"\\f130\";\n$fa-var-microphone-slash: \"\\f131\";\n$fa-var-minus: \"\\f068\";\n$fa-var-minus-circle: \"\\f056\";\n$fa-var-minus-square: \"\\f146\";\n$fa-var-minus-square-o: \"\\f147\";\n$fa-var-mixcloud: \"\\f289\";\n$fa-var-mobile: \"\\f10b\";\n$fa-var-mobile-phone: \"\\f10b\";\n$fa-var-modx: \"\\f285\";\n$fa-var-money: \"\\f0d6\";\n$fa-var-moon-o: \"\\f186\";\n$fa-var-mortar-board: \"\\f19d\";\n$fa-var-motorcycle: \"\\f21c\";\n$fa-var-mouse-pointer: \"\\f245\";\n$fa-var-music: \"\\f001\";\n$fa-var-navicon: \"\\f0c9\";\n$fa-var-neuter: \"\\f22c\";\n$fa-var-newspaper-o: \"\\f1ea\";\n$fa-var-object-group: \"\\f247\";\n$fa-var-object-ungroup: \"\\f248\";\n$fa-var-odnoklassniki: \"\\f263\";\n$fa-var-odnoklassniki-square: \"\\f264\";\n$fa-var-opencart: \"\\f23d\";\n$fa-var-openid: \"\\f19b\";\n$fa-var-opera: \"\\f26a\";\n$fa-var-optin-monster: \"\\f23c\";\n$fa-var-outdent: \"\\f03b\";\n$fa-var-pagelines: \"\\f18c\";\n$fa-var-paint-brush: \"\\f1fc\";\n$fa-var-paper-plane: \"\\f1d8\";\n$fa-var-paper-plane-o: \"\\f1d9\";\n$fa-var-paperclip: \"\\f0c6\";\n$fa-var-paragraph: \"\\f1dd\";\n$fa-var-paste: \"\\f0ea\";\n$fa-var-pause: \"\\f04c\";\n$fa-var-pause-circle: \"\\f28b\";\n$fa-var-pause-circle-o: \"\\f28c\";\n$fa-var-paw: \"\\f1b0\";\n$fa-var-paypal: \"\\f1ed\";\n$fa-var-pencil: \"\\f040\";\n$fa-var-pencil-square: \"\\f14b\";\n$fa-var-pencil-square-o: \"\\f044\";\n$fa-var-percent: \"\\f295\";\n$fa-var-phone: \"\\f095\";\n$fa-var-phone-square: \"\\f098\";\n$fa-var-photo: \"\\f03e\";\n$fa-var-picture-o: \"\\f03e\";\n$fa-var-pie-chart: \"\\f200\";\n$fa-var-pied-piper: \"\\f2ae\";\n$fa-var-pied-piper-alt: \"\\f1a8\";\n$fa-var-pied-piper-pp: \"\\f1a7\";\n$fa-var-pinterest: \"\\f0d2\";\n$fa-var-pinterest-p: \"\\f231\";\n$fa-var-pinterest-square: \"\\f0d3\";\n$fa-var-plane: \"\\f072\";\n$fa-var-play: \"\\f04b\";\n$fa-var-play-circle: \"\\f144\";\n$fa-var-play-circle-o: \"\\f01d\";\n$fa-var-plug: \"\\f1e6\";\n$fa-var-plus: \"\\f067\";\n$fa-var-plus-circle: \"\\f055\";\n$fa-var-plus-square: \"\\f0fe\";\n$fa-var-plus-square-o: \"\\f196\";\n$fa-var-power-off: \"\\f011\";\n$fa-var-print: \"\\f02f\";\n$fa-var-product-hunt: \"\\f288\";\n$fa-var-puzzle-piece: \"\\f12e\";\n$fa-var-qq: \"\\f1d6\";\n$fa-var-qrcode: \"\\f029\";\n$fa-var-question: \"\\f128\";\n$fa-var-question-circle: \"\\f059\";\n$fa-var-question-circle-o: \"\\f29c\";\n$fa-var-quote-left: \"\\f10d\";\n$fa-var-quote-right: \"\\f10e\";\n$fa-var-ra: \"\\f1d0\";\n$fa-var-random: \"\\f074\";\n$fa-var-rebel: \"\\f1d0\";\n$fa-var-recycle: \"\\f1b8\";\n$fa-var-reddit: \"\\f1a1\";\n$fa-var-reddit-alien: \"\\f281\";\n$fa-var-reddit-square: \"\\f1a2\";\n$fa-var-refresh: \"\\f021\";\n$fa-var-registered: \"\\f25d\";\n$fa-var-remove: \"\\f00d\";\n$fa-var-renren: \"\\f18b\";\n$fa-var-reorder: \"\\f0c9\";\n$fa-var-repeat: \"\\f01e\";\n$fa-var-reply: \"\\f112\";\n$fa-var-reply-all: \"\\f122\";\n$fa-var-resistance: \"\\f1d0\";\n$fa-var-retweet: \"\\f079\";\n$fa-var-rmb: \"\\f157\";\n$fa-var-road: \"\\f018\";\n$fa-var-rocket: \"\\f135\";\n$fa-var-rotate-left: \"\\f0e2\";\n$fa-var-rotate-right: \"\\f01e\";\n$fa-var-rouble: \"\\f158\";\n$fa-var-rss: \"\\f09e\";\n$fa-var-rss-square: \"\\f143\";\n$fa-var-rub: \"\\f158\";\n$fa-var-ruble: \"\\f158\";\n$fa-var-rupee: \"\\f156\";\n$fa-var-safari: \"\\f267\";\n$fa-var-save: \"\\f0c7\";\n$fa-var-scissors: \"\\f0c4\";\n$fa-var-scribd: \"\\f28a\";\n$fa-var-search: \"\\f002\";\n$fa-var-search-minus: \"\\f010\";\n$fa-var-search-plus: \"\\f00e\";\n$fa-var-sellsy: \"\\f213\";\n$fa-var-send: \"\\f1d8\";\n$fa-var-send-o: \"\\f1d9\";\n$fa-var-server: \"\\f233\";\n$fa-var-share: \"\\f064\";\n$fa-var-share-alt: \"\\f1e0\";\n$fa-var-share-alt-square: \"\\f1e1\";\n$fa-var-share-square: \"\\f14d\";\n$fa-var-share-square-o: \"\\f045\";\n$fa-var-shekel: \"\\f20b\";\n$fa-var-sheqel: \"\\f20b\";\n$fa-var-shield: \"\\f132\";\n$fa-var-ship: \"\\f21a\";\n$fa-var-shirtsinbulk: \"\\f214\";\n$fa-var-shopping-bag: \"\\f290\";\n$fa-var-shopping-basket: \"\\f291\";\n$fa-var-shopping-cart: \"\\f07a\";\n$fa-var-sign-in: \"\\f090\";\n$fa-var-sign-language: \"\\f2a7\";\n$fa-var-sign-out: \"\\f08b\";\n$fa-var-signal: \"\\f012\";\n$fa-var-signing: \"\\f2a7\";\n$fa-var-simplybuilt: \"\\f215\";\n$fa-var-sitemap: \"\\f0e8\";\n$fa-var-skyatlas: \"\\f216\";\n$fa-var-skype: \"\\f17e\";\n$fa-var-slack: \"\\f198\";\n$fa-var-sliders: \"\\f1de\";\n$fa-var-slideshare: \"\\f1e7\";\n$fa-var-smile-o: \"\\f118\";\n$fa-var-snapchat: \"\\f2ab\";\n$fa-var-snapchat-ghost: \"\\f2ac\";\n$fa-var-snapchat-square: \"\\f2ad\";\n$fa-var-soccer-ball-o: \"\\f1e3\";\n$fa-var-sort: \"\\f0dc\";\n$fa-var-sort-alpha-asc: \"\\f15d\";\n$fa-var-sort-alpha-desc: \"\\f15e\";\n$fa-var-sort-amount-asc: \"\\f160\";\n$fa-var-sort-amount-desc: \"\\f161\";\n$fa-var-sort-asc: \"\\f0de\";\n$fa-var-sort-desc: \"\\f0dd\";\n$fa-var-sort-down: \"\\f0dd\";\n$fa-var-sort-numeric-asc: \"\\f162\";\n$fa-var-sort-numeric-desc: \"\\f163\";\n$fa-var-sort-up: \"\\f0de\";\n$fa-var-soundcloud: \"\\f1be\";\n$fa-var-space-shuttle: \"\\f197\";\n$fa-var-spinner: \"\\f110\";\n$fa-var-spoon: \"\\f1b1\";\n$fa-var-spotify: \"\\f1bc\";\n$fa-var-square: \"\\f0c8\";\n$fa-var-square-o: \"\\f096\";\n$fa-var-stack-exchange: \"\\f18d\";\n$fa-var-stack-overflow: \"\\f16c\";\n$fa-var-star: \"\\f005\";\n$fa-var-star-half: \"\\f089\";\n$fa-var-star-half-empty: \"\\f123\";\n$fa-var-star-half-full: \"\\f123\";\n$fa-var-star-half-o: \"\\f123\";\n$fa-var-star-o: \"\\f006\";\n$fa-var-steam: \"\\f1b6\";\n$fa-var-steam-square: \"\\f1b7\";\n$fa-var-step-backward: \"\\f048\";\n$fa-var-step-forward: \"\\f051\";\n$fa-var-stethoscope: \"\\f0f1\";\n$fa-var-sticky-note: \"\\f249\";\n$fa-var-sticky-note-o: \"\\f24a\";\n$fa-var-stop: \"\\f04d\";\n$fa-var-stop-circle: \"\\f28d\";\n$fa-var-stop-circle-o: \"\\f28e\";\n$fa-var-street-view: \"\\f21d\";\n$fa-var-strikethrough: \"\\f0cc\";\n$fa-var-stumbleupon: \"\\f1a4\";\n$fa-var-stumbleupon-circle: \"\\f1a3\";\n$fa-var-subscript: \"\\f12c\";\n$fa-var-subway: \"\\f239\";\n$fa-var-suitcase: \"\\f0f2\";\n$fa-var-sun-o: \"\\f185\";\n$fa-var-superscript: \"\\f12b\";\n$fa-var-support: \"\\f1cd\";\n$fa-var-table: \"\\f0ce\";\n$fa-var-tablet: \"\\f10a\";\n$fa-var-tachometer: \"\\f0e4\";\n$fa-var-tag: \"\\f02b\";\n$fa-var-tags: \"\\f02c\";\n$fa-var-tasks: \"\\f0ae\";\n$fa-var-taxi: \"\\f1ba\";\n$fa-var-television: \"\\f26c\";\n$fa-var-tencent-weibo: \"\\f1d5\";\n$fa-var-terminal: \"\\f120\";\n$fa-var-text-height: \"\\f034\";\n$fa-var-text-width: \"\\f035\";\n$fa-var-th: \"\\f00a\";\n$fa-var-th-large: \"\\f009\";\n$fa-var-th-list: \"\\f00b\";\n$fa-var-themeisle: \"\\f2b2\";\n$fa-var-thumb-tack: \"\\f08d\";\n$fa-var-thumbs-down: \"\\f165\";\n$fa-var-thumbs-o-down: \"\\f088\";\n$fa-var-thumbs-o-up: \"\\f087\";\n$fa-var-thumbs-up: \"\\f164\";\n$fa-var-ticket: \"\\f145\";\n$fa-var-times: \"\\f00d\";\n$fa-var-times-circle: \"\\f057\";\n$fa-var-times-circle-o: \"\\f05c\";\n$fa-var-tint: \"\\f043\";\n$fa-var-toggle-down: \"\\f150\";\n$fa-var-toggle-left: \"\\f191\";\n$fa-var-toggle-off: \"\\f204\";\n$fa-var-toggle-on: \"\\f205\";\n$fa-var-toggle-right: \"\\f152\";\n$fa-var-toggle-up: \"\\f151\";\n$fa-var-trademark: \"\\f25c\";\n$fa-var-train: \"\\f238\";\n$fa-var-transgender: \"\\f224\";\n$fa-var-transgender-alt: \"\\f225\";\n$fa-var-trash: \"\\f1f8\";\n$fa-var-trash-o: \"\\f014\";\n$fa-var-tree: \"\\f1bb\";\n$fa-var-trello: \"\\f181\";\n$fa-var-tripadvisor: \"\\f262\";\n$fa-var-trophy: \"\\f091\";\n$fa-var-truck: \"\\f0d1\";\n$fa-var-try: \"\\f195\";\n$fa-var-tty: \"\\f1e4\";\n$fa-var-tumblr: \"\\f173\";\n$fa-var-tumblr-square: \"\\f174\";\n$fa-var-turkish-lira: \"\\f195\";\n$fa-var-tv: \"\\f26c\";\n$fa-var-twitch: \"\\f1e8\";\n$fa-var-twitter: \"\\f099\";\n$fa-var-twitter-square: \"\\f081\";\n$fa-var-umbrella: \"\\f0e9\";\n$fa-var-underline: \"\\f0cd\";\n$fa-var-undo: \"\\f0e2\";\n$fa-var-universal-access: \"\\f29a\";\n$fa-var-university: \"\\f19c\";\n$fa-var-unlink: \"\\f127\";\n$fa-var-unlock: \"\\f09c\";\n$fa-var-unlock-alt: \"\\f13e\";\n$fa-var-unsorted: \"\\f0dc\";\n$fa-var-upload: \"\\f093\";\n$fa-var-usb: \"\\f287\";\n$fa-var-usd: \"\\f155\";\n$fa-var-user: \"\\f007\";\n$fa-var-user-md: \"\\f0f0\";\n$fa-var-user-plus: \"\\f234\";\n$fa-var-user-secret: \"\\f21b\";\n$fa-var-user-times: \"\\f235\";\n$fa-var-users: \"\\f0c0\";\n$fa-var-venus: \"\\f221\";\n$fa-var-venus-double: \"\\f226\";\n$fa-var-venus-mars: \"\\f228\";\n$fa-var-viacoin: \"\\f237\";\n$fa-var-viadeo: \"\\f2a9\";\n$fa-var-viadeo-square: \"\\f2aa\";\n$fa-var-video-camera: \"\\f03d\";\n$fa-var-vimeo: \"\\f27d\";\n$fa-var-vimeo-square: \"\\f194\";\n$fa-var-vine: \"\\f1ca\";\n$fa-var-vk: \"\\f189\";\n$fa-var-volume-control-phone: \"\\f2a0\";\n$fa-var-volume-down: \"\\f027\";\n$fa-var-volume-off: \"\\f026\";\n$fa-var-volume-up: \"\\f028\";\n$fa-var-warning: \"\\f071\";\n$fa-var-wechat: \"\\f1d7\";\n$fa-var-weibo: \"\\f18a\";\n$fa-var-weixin: \"\\f1d7\";\n$fa-var-whatsapp: \"\\f232\";\n$fa-var-wheelchair: \"\\f193\";\n$fa-var-wheelchair-alt: \"\\f29b\";\n$fa-var-wifi: \"\\f1eb\";\n$fa-var-wikipedia-w: \"\\f266\";\n$fa-var-windows: \"\\f17a\";\n$fa-var-won: \"\\f159\";\n$fa-var-wordpress: \"\\f19a\";\n$fa-var-wpbeginner: \"\\f297\";\n$fa-var-wpforms: \"\\f298\";\n$fa-var-wrench: \"\\f0ad\";\n$fa-var-xing: \"\\f168\";\n$fa-var-xing-square: \"\\f169\";\n$fa-var-y-combinator: \"\\f23b\";\n$fa-var-y-combinator-square: \"\\f1d4\";\n$fa-var-yahoo: \"\\f19e\";\n$fa-var-yc: \"\\f23b\";\n$fa-var-yc-square: \"\\f1d4\";\n$fa-var-yelp: \"\\f1e9\";\n$fa-var-yen: \"\\f157\";\n$fa-var-yoast: \"\\f2b1\";\n$fa-var-youtube: \"\\f167\";\n$fa-var-youtube-play: \"\\f16a\";\n$fa-var-youtube-square: \"\\f166\";\n\n"
  },
  {
    "path": "app_backend/static/plugin/font-awesome/scss/font-awesome.scss",
    "content": "/*!\n *  Font Awesome 4.6.3 by @davegandy - http://fontawesome.io - @fontawesome\n *  License - http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License)\n */\n\n@import \"variables\";\n@import \"mixins\";\n@import \"path\";\n@import \"core\";\n@import \"larger\";\n@import \"fixed-width\";\n@import \"list\";\n@import \"bordered-pulled\";\n@import \"animated\";\n@import \"rotated-flipped\";\n@import \"stacked\";\n@import \"icons\";\n@import \"screen-reader\";\n"
  },
  {
    "path": "app_backend/static/plugin/jQuery-File-Upload-9.18.0/.gitignore",
    "content": ".DS_Store\n*.pyc\nnode_modules\n"
  },
  {
    "path": "app_backend/static/plugin/jQuery-File-Upload-9.18.0/.jshintrc",
    "content": "{\n  \"bitwise\"       : true,     // true: Prohibit bitwise operators (&, |, ^, etc.)\n  \"camelcase\"     : true,     // true: Identifiers must be in camelCase\n  \"curly\"         : true,     // true: Require {} for every new block or scope\n  \"eqeqeq\"        : true,     // true: Require triple equals (===) for comparison\n  \"forin\"         : true,     // true: Require filtering for..in loops with obj.hasOwnProperty()\n  \"immed\"         : true,     // true: Require immediate invocations to be wrapped in parens\n                              // e.g. `(function () { } ());`\n  \"indent\"        : 4,        // {int} Number of spaces to use for indentation\n  \"latedef\"       : true,     // true: Require variables/functions to be defined before being used\n  \"newcap\"        : true,     // true: Require capitalization of all constructor functions e.g. `new F()`\n  \"noarg\"         : true,     // true: Prohibit use of `arguments.caller` and `arguments.callee`\n  \"noempty\"       : true,     // true: Prohibit use of empty blocks\n  \"nonew\"         : true,     // true: Prohibit use of constructors for side-effects (without assignment)\n  \"plusplus\"      : false,    // true: Prohibit use of `++` & `--`\n  \"quotmark\"      : \"single\", // Quotation mark consistency:\n                              //   false    : do nothing (default)\n                              //   true     : ensure whatever is used is consistent\n                              //   \"single\" : require single quotes\n                              //   \"double\" : require double quotes\n  \"undef\"         : true,     // true: Require all non-global variables to be declared (prevents global leaks)\n  \"unused\"        : true,     // true: Require all defined variables be used\n  \"strict\"        : true,     // true: Requires all functions run in ES5 Strict Mode\n  \"trailing\"      : true,     // true: Prohibit trailing whitespaces\n  \"maxparams\"     : false,    // {int} Max number of formal params allowed per function\n  \"maxdepth\"      : false,    // {int} Max depth of nested blocks (within functions)\n  \"maxstatements\" : false,    // {int} Max number statements per function\n  \"maxcomplexity\" : false,    // {int} Max cyclomatic complexity per function\n  \"maxlen\"        : false,    // {int} Max number of characters per line\n\n  // Relaxing\n  \"asi\"           : false,     // true: Tolerate Automatic Semicolon Insertion (no semicolons)\n  \"boss\"          : false,     // true: Tolerate assignments where comparisons would be expected\n  \"debug\"         : false,     // true: Allow debugger statements e.g. browser breakpoints.\n  \"eqnull\"        : false,     // true: Tolerate use of `== null`\n  \"es5\"           : false,     // true: Allow ES5 syntax (ex: getters and setters)\n  \"esnext\"        : false,     // true: Allow ES.next (ES6) syntax (ex: `const`)\n  \"moz\"           : false,     // true: Allow Mozilla specific syntax (extends and overrides esnext features)\n                               // (ex: `for each`, multiple try/catch, function expression…)\n  \"evil\"          : false,     // true: Tolerate use of `eval` and `new Function()`\n  \"expr\"          : false,     // true: Tolerate `ExpressionStatement` as Programs\n  \"funcscope\"     : false,     // true: Tolerate defining variables inside control statements\"\n  \"globalstrict\"  : false,     // true: Allow global \"use strict\" (also enables 'strict')\n  \"iterator\"      : false,     // true: Tolerate using the `__iterator__` property\n  \"lastsemic\"     : false,     // true: Tolerate omitting a semicolon for the last statement of a 1-line block\n  \"laxbreak\"      : false,     // true: Tolerate possibly unsafe line breakings\n  \"laxcomma\"      : false,     // true: Tolerate comma-first style coding\n  \"loopfunc\"      : false,     // true: Tolerate functions being defined in loops\n  \"multistr\"      : false,     // true: Tolerate multi-line strings\n  \"proto\"         : false,     // true: Tolerate using the `__proto__` property\n  \"scripturl\"     : false,     // true: Tolerate script-targeted URLs\n  \"smarttabs\"     : false,     // true: Tolerate mixed tabs/spaces when used for alignment\n  \"shadow\"        : false,     // true: Allows re-define variables later in code e.g. `var x=1; x=2;`\n  \"sub\"           : false,     // true: Tolerate using `[]` notation when it can still be expressed in dot notation\n  \"supernew\"      : false,     // true: Tolerate `new function () { ... };` and `new Object;`\n  \"validthis\"     : false,     // true: Tolerate using this in a non-constructor function\n\n  // Environments\n  \"browser\"       : false,    // Web Browser (window, document, etc)\n  \"couch\"         : false,    // CouchDB\n  \"devel\"         : false,    // Development/debugging (alert, confirm, etc)\n  \"dojo\"          : false,    // Dojo Toolkit\n  \"jquery\"        : false,    // jQuery\n  \"mootools\"      : false,    // MooTools\n  \"node\"          : false,    // Node.js\n  \"nonstandard\"   : false,    // Widely adopted globals (escape, unescape, etc)\n  \"prototypejs\"   : false,    // Prototype and Scriptaculous\n  \"rhino\"         : false,    // Rhino\n  \"worker\"        : false,    // Web Workers\n  \"wsh\"           : false,    // Windows Scripting Host\n  \"yui\"           : false,    // Yahoo User Interface\n\n  // Legacy\n  \"nomen\"         : true,     // true: Prohibit dangling `_` in variables\n  \"onevar\"        : true,     // true: Allow only one `var` statement per function\n  \"passfail\"      : false,    // true: Stop on first error\n  \"white\"         : true,     // true: Check against strict whitespace and indentation rules\n\n  // Custom Globals\n  \"globals\"       : {}        // additional predefined global variables\n}\n"
  },
  {
    "path": "app_backend/static/plugin/jQuery-File-Upload-9.18.0/.npmignore",
    "content": "*\n!css/jquery.fileupload-noscript.css\n!css/jquery.fileupload-ui-noscript.css\n!css/jquery.fileupload-ui.css\n!css/jquery.fileupload.css\n!img/loading.gif\n!img/progressbar.gif\n!js/cors/jquery.postmessage-transport.js\n!js/cors/jquery.xdr-transport.js\n!js/vendor/jquery.ui.widget.js\n!js/jquery.fileupload-angular.js\n!js/jquery.fileupload-audio.js\n!js/jquery.fileupload-image.js\n!js/jquery.fileupload-jquery-ui.js\n!js/jquery.fileupload-process.js\n!js/jquery.fileupload-ui.js\n!js/jquery.fileupload-validate.js\n!js/jquery.fileupload-video.js\n!js/jquery.fileupload.js\n!js/jquery.iframe-transport.js\n"
  },
  {
    "path": "app_backend/static/plugin/jQuery-File-Upload-9.18.0/CONTRIBUTING.md",
    "content": "Please follow these pull request guidelines:\n\n1. Update your fork to the latest upstream version.\n\n2. Follow the coding conventions of the original source files (indentation, spaces, brackets layout).\n\n3. Code changes must pass JSHint validation with the `.jshintrc` settings of this project.\n\n4. Code changes must pass the QUnit tests defined in the `test` folder.\n\n5. New features should be covered by accompanying QUnit tests.\n\n6. Keep your commits as atomic as possible, i.e. create a new commit for every single bug fix or feature added.\n\n7. Always add meaningful commit messages.\n"
  },
  {
    "path": "app_backend/static/plugin/jQuery-File-Upload-9.18.0/LICENSE",
    "content": "The MIT License (MIT)\n\nCopyright (c) 2017 jQuery-File-Upload Authors\n\nPermission is hereby granted, free of charge, to any person obtaining a copy of\nthis software and associated documentation files (the \"Software\"), to deal in\nthe Software without restriction, including without limitation the rights to\nuse, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of\nthe Software, and to permit persons to whom the Software is furnished to do so,\nsubject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS\nFOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR\nCOPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER\nIN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN\nCONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n"
  },
  {
    "path": "app_backend/static/plugin/jQuery-File-Upload-9.18.0/README.md",
    "content": "# jQuery File Upload Plugin\n\n## Demo\n[Demo File Upload](https://blueimp.github.io/jQuery-File-Upload/)\n\n## Description\nFile Upload widget with multiple file selection, drag&amp;drop support, progress bars, validation and preview images, audio and video for jQuery.  \nSupports cross-domain, chunked and resumable file uploads and client-side image resizing. Works with any server-side platform (PHP, Python, Ruby on Rails, Java, Node.js, Go etc.) that supports standard HTML form file uploads.\n\n## Setup\n* [How to setup the plugin on your website](https://github.com/blueimp/jQuery-File-Upload/wiki/Setup)\n* [How to use only the basic plugin (minimal setup guide).](https://github.com/blueimp/jQuery-File-Upload/wiki/Basic-plugin)\n\n## Features\n* **Multiple file upload:**  \n  Allows to select multiple files at once and upload them simultaneously.\n* **Drag & Drop support:**  \n  Allows to upload files by dragging them from your desktop or filemanager and dropping them on your browser window.\n* **Upload progress bar:**  \n  Shows a progress bar indicating the upload progress for individual files and for all uploads combined.\n* **Cancelable uploads:**  \n  Individual file uploads can be canceled to stop the upload progress.\n* **Resumable uploads:**  \n  Aborted uploads can be resumed with browsers supporting the Blob API.\n* **Chunked uploads:**  \n  Large files can be uploaded in smaller chunks with browsers supporting the Blob API.\n* **Client-side image resizing:**  \n  Images can be automatically resized on client-side with browsers supporting the required JS APIs.\n* **Preview images, audio and video:**  \n  A preview of image, audio and video files can be displayed before uploading with browsers supporting the required APIs.\n* **No browser plugins (e.g. Adobe Flash) required:**  \n  The implementation is based on open standards like HTML5 and JavaScript and requires no additional browser plugins.\n* **Graceful fallback for legacy browsers:**  \n  Uploads files via XMLHttpRequests if supported and uses iframes as fallback for legacy browsers.\n* **HTML file upload form fallback:**  \n  Allows progressive enhancement by using a standard HTML file upload form as widget element.\n* **Cross-site file uploads:**  \n  Supports uploading files to a different domain with cross-site XMLHttpRequests or iframe redirects.\n* **Multiple plugin instances:**  \n  Allows to use multiple plugin instances on the same webpage.\n* **Customizable and extensible:**  \n  Provides an API to set individual options and define callBack methods for various upload events.\n* **Multipart and file contents stream uploads:**  \n  Files can be uploaded as standard \"multipart/form-data\" or file contents stream (HTTP PUT file upload).\n* **Compatible with any server-side application platform:**  \n  Works with any server-side platform (PHP, Python, Ruby on Rails, Java, Node.js, Go etc.) that supports standard HTML form file uploads.\n\n## Requirements\n\n### Mandatory requirements\n* [jQuery](https://jquery.com/) v. 1.6+\n* [jQuery UI widget factory](https://api.jqueryui.com/jQuery.widget/) v. 1.9+ (included): Required for the basic File Upload plugin, but very lightweight without any other dependencies from the jQuery UI suite.\n* [jQuery Iframe Transport plugin](https://github.com/blueimp/jQuery-File-Upload/blob/master/js/jquery.iframe-transport.js) (included): Required for [browsers without XHR file upload support](https://github.com/blueimp/jQuery-File-Upload/wiki/Browser-support).\n\n### Optional requirements\n* [JavaScript Templates engine](https://github.com/blueimp/JavaScript-Templates) v. 2.5.4+: Used to render the selected and uploaded files for the Basic Plus UI and jQuery UI versions.\n* [JavaScript Load Image library](https://github.com/blueimp/JavaScript-Load-Image) v. 1.13.0+: Required for the image previews and resizing functionality.\n* [JavaScript Canvas to Blob polyfill](https://github.com/blueimp/JavaScript-Canvas-to-Blob) v. 2.1.1+:Required for the image previews and resizing functionality.\n* [blueimp Gallery](https://github.com/blueimp/Gallery) v. 2.15.1+: Used to display the uploaded images in a lightbox.\n* [Bootstrap](http://getbootstrap.com/) v. 3.2.0+\n* [Glyphicons](http://glyphicons.com/)\n\nThe user interface of all versions except the jQuery UI version is built with [Bootstrap](http://getbootstrap.com/) and icons from [Glyphicons](http://glyphicons.com/).\n\n### Cross-domain requirements\n[Cross-domain File Uploads](https://github.com/blueimp/jQuery-File-Upload/wiki/Cross-domain-uploads) using the [Iframe Transport plugin](https://github.com/blueimp/jQuery-File-Upload/blob/master/js/jquery.iframe-transport.js) require a redirect back to the origin server to retrieve the upload results. The [example implementation](https://github.com/blueimp/jQuery-File-Upload/blob/master/js/main.js) makes use of [result.html](https://github.com/blueimp/jQuery-File-Upload/blob/master/cors/result.html) as a static redirect page for the origin server.\n\nThe repository also includes the [jQuery XDomainRequest Transport plugin](https://github.com/blueimp/jQuery-File-Upload/blob/master/js/cors/jquery.xdr-transport.js), which enables limited cross-domain AJAX requests in Microsoft Internet Explorer 8 and 9 (IE 10 supports cross-domain XHR requests).  \nThe XDomainRequest object allows GET and POST requests only and doesn't support file uploads. It is used on the [Demo](https://blueimp.github.io/jQuery-File-Upload/) to delete uploaded files from the cross-domain demo file upload service.\n\n### Custom Backends\n\nYou can add support for various backends by adhering to the specification [outlined here](https://github.com/blueimp/jQuery-File-Upload/wiki/JSON-Response).\n\n## Browsers\n\n### Desktop browsers\nThe File Upload plugin is regularly tested with the latest browser versions and supports the following minimal versions:\n\n* Google Chrome\n* Apple Safari 4.0+\n* Mozilla Firefox 3.0+\n* Opera 11.0+\n* Microsoft Internet Explorer 6.0+\n\n### Mobile browsers\nThe File Upload plugin has been tested with and supports the following mobile browsers:\n\n* Apple Safari on iOS 6.0+\n* Google Chrome on iOS 6.0+\n* Google Chrome on Android 4.0+\n* Default Browser on Android 2.3+\n* Opera Mobile 12.0+\n\n### Supported features\nFor a detailed overview of the features supported by each browser version, please have a look at the [Extended browser support information](https://github.com/blueimp/jQuery-File-Upload/wiki/Browser-support).\n\n## Contributing\n**Bug fixes** and **new features** can be proposed using [pull requests](https://github.com/blueimp/jQuery-File-Upload/pulls).\nPlease read the [contribution guidelines](https://github.com/blueimp/jQuery-File-Upload/blob/master/CONTRIBUTING.md) before submitting a pull request.\n\n## Support\nThis project is actively maintained, but there is no official support channel.  \nIf you have a question that another developer might help you with, please post to [Stack Overflow](http://stackoverflow.com/questions/tagged/blueimp+jquery+file-upload) and tag your question with `blueimp jquery file upload`.\n\n## License\nReleased under the [MIT license](https://opensource.org/licenses/MIT).\n"
  },
  {
    "path": "app_backend/static/plugin/jQuery-File-Upload-9.18.0/angularjs.html",
    "content": "<!DOCTYPE HTML>\n<!--\n/*\n * jQuery File Upload Plugin AngularJS Demo\n * https://github.com/blueimp/jQuery-File-Upload\n *\n * Copyright 2013, Sebastian Tschan\n * https://blueimp.net\n *\n * Licensed under the MIT license:\n * https://opensource.org/licenses/MIT\n */\n-->\n<html lang=\"en\">\n<head>\n<!-- Force latest IE rendering engine or ChromeFrame if installed -->\n<!--[if IE]>\n<meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge,chrome=1\">\n<![endif]-->\n<meta charset=\"utf-8\">\n<title>jQuery File Upload Demo - AngularJS version</title>\n<meta name=\"description\" content=\"File Upload widget with multiple file selection, drag&amp;drop support, progress bars, validation and preview images, audio and video for AngularJS. Supports cross-domain, chunked and resumable file uploads and client-side image resizing. Works with any server-side platform (PHP, Python, Ruby on Rails, Java, Node.js, Go etc.) that supports standard HTML form file uploads.\">\n<meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n<!-- Bootstrap styles -->\n<link rel=\"stylesheet\" href=\"//netdna.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.min.css\">\n<!-- Generic page styles -->\n<link rel=\"stylesheet\" href=\"css/style.css\">\n<!-- blueimp Gallery styles -->\n<link rel=\"stylesheet\" href=\"//blueimp.github.io/Gallery/css/blueimp-gallery.min.css\">\n<!-- CSS to style the file input field as button and adjust the Bootstrap progress bars -->\n<link rel=\"stylesheet\" href=\"css/jquery.fileupload.css\">\n<link rel=\"stylesheet\" href=\"css/jquery.fileupload-ui.css\">\n<!-- CSS adjustments for browsers with JavaScript disabled -->\n<noscript><link rel=\"stylesheet\" href=\"css/jquery.fileupload-noscript.css\"></noscript>\n<noscript><link rel=\"stylesheet\" href=\"css/jquery.fileupload-ui-noscript.css\"></noscript>\n<style>\n/* Hide Angular JS elements before initializing */\n.ng-cloak {\n    display: none;\n}\n</style>\n</head>\n<body>\n<div class=\"navbar navbar-default navbar-fixed-top\">\n    <div class=\"container\">\n        <div class=\"navbar-header\">\n            <button type=\"button\" class=\"navbar-toggle\" data-toggle=\"collapse\" data-target=\".navbar-fixed-top .navbar-collapse\">\n                <span class=\"icon-bar\"></span>\n                <span class=\"icon-bar\"></span>\n                <span class=\"icon-bar\"></span>\n            </button>\n            <a class=\"navbar-brand\" href=\"https://github.com/blueimp/jQuery-File-Upload\">jQuery File Upload</a>\n        </div>\n        <div class=\"navbar-collapse collapse\">\n            <ul class=\"nav navbar-nav\">\n                <li><a href=\"https://github.com/blueimp/jQuery-File-Upload/tags\">Download</a></li>\n                <li><a href=\"https://github.com/blueimp/jQuery-File-Upload\">Source Code</a></li>\n                <li><a href=\"https://github.com/blueimp/jQuery-File-Upload/wiki\">Documentation</a></li>\n                <li><a href=\"https://blueimp.net\">&copy; Sebastian Tschan</a></li>\n            </ul>\n        </div>\n    </div>\n</div>\n<div class=\"container\">\n    <h1>jQuery File Upload Demo</h1>\n    <h2 class=\"lead\">AngularJS version</h2>\n    <ul class=\"nav nav-tabs\">\n        <li><a href=\"basic.html\">Basic</a></li>\n        <li><a href=\"basic-plus.html\">Basic Plus</a></li>\n        <li><a href=\"index.html\">Basic Plus UI</a></li>\n        <li class=\"active\"><a href=\"angularjs.html\">AngularJS</a></li>\n        <li><a href=\"jquery-ui.html\">jQuery UI</a></li>\n    </ul>\n    <br>\n    <blockquote>\n        <p>File Upload widget with multiple file selection, drag&amp;drop support, progress bars, validation and preview images, audio and video for AngularJS.<br>\n        Supports cross-domain, chunked and resumable file uploads and client-side image resizing.<br>\n        Works with any server-side platform (PHP, Python, Ruby on Rails, Java, Node.js, Go etc.) that supports standard HTML form file uploads.</p>\n    </blockquote>\n    <br>\n    <!-- The file upload form used as target for the file upload widget -->\n    <form id=\"fileupload\" action=\"//jquery-file-upload.appspot.com/\" method=\"POST\" enctype=\"multipart/form-data\" data-ng-app=\"demo\" data-ng-controller=\"DemoFileUploadController\" data-file-upload=\"options\" data-ng-class=\"{'fileupload-processing': processing() || loadingFiles}\">\n        <!-- Redirect browsers with JavaScript disabled to the origin page -->\n        <noscript><input type=\"hidden\" name=\"redirect\" value=\"https://blueimp.github.io/jQuery-File-Upload/\"></noscript>\n        <!-- The fileupload-buttonbar contains buttons to add/delete files and start/cancel the upload -->\n        <div class=\"row fileupload-buttonbar\">\n            <div class=\"col-lg-7\">\n                <!-- The fileinput-button span is used to style the file input field as button -->\n                <span class=\"btn btn-success fileinput-button\" ng-class=\"{disabled: disabled}\">\n                    <i class=\"glyphicon glyphicon-plus\"></i>\n                    <span>Add files...</span>\n                    <input type=\"file\" name=\"files[]\" multiple ng-disabled=\"disabled\">\n                </span>\n                <button type=\"button\" class=\"btn btn-primary start\" data-ng-click=\"submit()\">\n                    <i class=\"glyphicon glyphicon-upload\"></i>\n                    <span>Start upload</span>\n                </button>\n                <button type=\"button\" class=\"btn btn-warning cancel\" data-ng-click=\"cancel()\">\n                    <i class=\"glyphicon glyphicon-ban-circle\"></i>\n                    <span>Cancel upload</span>\n                </button>\n                <!-- The global file processing state -->\n                <span class=\"fileupload-process\"></span>\n            </div>\n            <!-- The global progress state -->\n            <div class=\"col-lg-5 fade\" data-ng-class=\"{in: active()}\">\n                <!-- The global progress bar -->\n                <div class=\"progress progress-striped active\" data-file-upload-progress=\"progress()\"><div class=\"progress-bar progress-bar-success\" data-ng-style=\"{width: num + '%'}\"></div></div>\n                <!-- The extended global progress state -->\n                <div class=\"progress-extended\">&nbsp;</div>\n            </div>\n        </div>\n        <!-- The table listing the files available for upload/download -->\n        <table class=\"table table-striped files ng-cloak\">\n            <tr data-ng-repeat=\"file in queue\" data-ng-class=\"{'processing': file.$processing()}\">\n                <td data-ng-switch data-on=\"!!file.thumbnailUrl\">\n                    <div class=\"preview\" data-ng-switch-when=\"true\">\n                        <a data-ng-href=\"{{file.url}}\" title=\"{{file.name}}\" download=\"{{file.name}}\" data-gallery><img data-ng-src=\"{{file.thumbnailUrl}}\" alt=\"\"></a>\n                    </div>\n                    <div class=\"preview\" data-ng-switch-default data-file-upload-preview=\"file\"></div>\n                </td>\n                <td>\n                    <p class=\"name\" data-ng-switch data-on=\"!!file.url\">\n                        <span data-ng-switch-when=\"true\" data-ng-switch data-on=\"!!file.thumbnailUrl\">\n                            <a data-ng-switch-when=\"true\" data-ng-href=\"{{file.url}}\" title=\"{{file.name}}\" download=\"{{file.name}}\" data-gallery>{{file.name}}</a>\n                            <a data-ng-switch-default data-ng-href=\"{{file.url}}\" title=\"{{file.name}}\" download=\"{{file.name}}\">{{file.name}}</a>\n                        </span>\n                        <span data-ng-switch-default>{{file.name}}</span>\n                    </p>\n                    <strong data-ng-show=\"file.error\" class=\"error text-danger\">{{file.error}}</strong>\n                </td>\n                <td>\n                    <p class=\"size\">{{file.size | formatFileSize}}</p>\n                    <div class=\"progress progress-striped active fade\" data-ng-class=\"{pending: 'in'}[file.$state()]\" data-file-upload-progress=\"file.$progress()\"><div class=\"progress-bar progress-bar-success\" data-ng-style=\"{width: num + '%'}\"></div></div>\n                </td>\n                <td>\n                    <button type=\"button\" class=\"btn btn-primary start\" data-ng-click=\"file.$submit()\" data-ng-hide=\"!file.$submit || options.autoUpload\" data-ng-disabled=\"file.$state() == 'pending' || file.$state() == 'rejected'\">\n                        <i class=\"glyphicon glyphicon-upload\"></i>\n                        <span>Start</span>\n                    </button>\n                    <button type=\"button\" class=\"btn btn-warning cancel\" data-ng-click=\"file.$cancel()\" data-ng-hide=\"!file.$cancel\">\n                        <i class=\"glyphicon glyphicon-ban-circle\"></i>\n                        <span>Cancel</span>\n                    </button>\n                    <button data-ng-controller=\"FileDestroyController\" type=\"button\" class=\"btn btn-danger destroy\" data-ng-click=\"file.$destroy()\" data-ng-hide=\"!file.$destroy\">\n                        <i class=\"glyphicon glyphicon-trash\"></i>\n                        <span>Delete</span>\n                    </button>\n                </td>\n            </tr>\n        </table>\n    </form>\n    <br>\n    <div class=\"panel panel-default\">\n        <div class=\"panel-heading\">\n            <h3 class=\"panel-title\">Demo Notes</h3>\n        </div>\n        <div class=\"panel-body\">\n            <ul>\n                <li>The maximum file size for uploads in this demo is <strong>999 KB</strong> (default file size is unlimited).</li>\n                <li>Only image files (<strong>JPG, GIF, PNG</strong>) are allowed in this demo (by default there is no file type restriction).</li>\n                <li>Uploaded files will be deleted automatically after <strong>5 minutes or less</strong> (demo files are stored in memory).</li>\n                <li>You can <strong>drag &amp; drop</strong> files from your desktop on this webpage (see <a href=\"https://github.com/blueimp/jQuery-File-Upload/wiki/Browser-support\">Browser support</a>).</li>\n                <li>Please refer to the <a href=\"https://github.com/blueimp/jQuery-File-Upload\">project website</a> and <a href=\"https://github.com/blueimp/jQuery-File-Upload/wiki\">documentation</a> for more information.</li>\n                <li>Built with the <a href=\"http://getbootstrap.com/\">Bootstrap</a> CSS framework and Icons from <a href=\"http://glyphicons.com/\">Glyphicons</a>.</li>\n            </ul>\n        </div>\n    </div>\n</div>\n<!-- The blueimp Gallery widget -->\n<div id=\"blueimp-gallery\" class=\"blueimp-gallery blueimp-gallery-controls\" data-filter=\":even\">\n    <div class=\"slides\"></div>\n    <h3 class=\"title\"></h3>\n    <a class=\"prev\">‹</a>\n    <a class=\"next\">›</a>\n    <a class=\"close\">×</a>\n    <a class=\"play-pause\"></a>\n    <ol class=\"indicator\"></ol>\n</div>\n<script src=\"//ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js\"></script>\n<script src=\"//ajax.googleapis.com/ajax/libs/angularjs/1.3.15/angular.min.js\"></script>\n<!-- The jQuery UI widget factory, can be omitted if jQuery UI is already included -->\n<script src=\"js/vendor/jquery.ui.widget.js\"></script>\n<!-- The Load Image plugin is included for the preview images and image resizing functionality -->\n<script src=\"//blueimp.github.io/JavaScript-Load-Image/js/load-image.all.min.js\"></script>\n<!-- The Canvas to Blob plugin is included for image resizing functionality -->\n<script src=\"//blueimp.github.io/JavaScript-Canvas-to-Blob/js/canvas-to-blob.min.js\"></script>\n<!-- Bootstrap JS is not required, but included for the responsive demo navigation -->\n<script src=\"//netdna.bootstrapcdn.com/bootstrap/3.2.0/js/bootstrap.min.js\"></script>\n<!-- blueimp Gallery script -->\n<script src=\"//blueimp.github.io/Gallery/js/jquery.blueimp-gallery.min.js\"></script>\n<!-- The Iframe Transport is required for browsers without support for XHR file uploads -->\n<script src=\"js/jquery.iframe-transport.js\"></script>\n<!-- The basic File Upload plugin -->\n<script src=\"js/jquery.fileupload.js\"></script>\n<!-- The File Upload processing plugin -->\n<script src=\"js/jquery.fileupload-process.js\"></script>\n<!-- The File Upload image preview & resize plugin -->\n<script src=\"js/jquery.fileupload-image.js\"></script>\n<!-- The File Upload audio preview plugin -->\n<script src=\"js/jquery.fileupload-audio.js\"></script>\n<!-- The File Upload video preview plugin -->\n<script src=\"js/jquery.fileupload-video.js\"></script>\n<!-- The File Upload validation plugin -->\n<script src=\"js/jquery.fileupload-validate.js\"></script>\n<!-- The File Upload Angular JS module -->\n<script src=\"js/jquery.fileupload-angular.js\"></script>\n<!-- The main application script -->\n<script src=\"js/app.js\"></script>\n</body>\n</html>\n"
  },
  {
    "path": "app_backend/static/plugin/jQuery-File-Upload-9.18.0/basic-plus.html",
    "content": "<!DOCTYPE HTML>\n<!--\n/*\n * jQuery File Upload Plugin Basic Plus Demo\n * https://github.com/blueimp/jQuery-File-Upload\n *\n * Copyright 2013, Sebastian Tschan\n * https://blueimp.net\n *\n * Licensed under the MIT license:\n * https://opensource.org/licenses/MIT\n */\n-->\n<html lang=\"en\">\n<head>\n<!-- Force latest IE rendering engine or ChromeFrame if installed -->\n<!--[if IE]><meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge,chrome=1\"><![endif]-->\n<meta charset=\"utf-8\">\n<title>jQuery File Upload Demo - Basic Plus version</title>\n<meta name=\"description\" content=\"File Upload widget with multiple file selection, drag&amp;drop support, progress bar, validation and preview images, audio and video for jQuery. Supports cross-domain, chunked and resumable file uploads. Works with any server-side platform (Google App Engine, PHP, Python, Ruby on Rails, Java, etc.) that supports standard HTML form file uploads.\">\n<meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n<!-- Bootstrap styles -->\n<link rel=\"stylesheet\" href=\"//netdna.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.min.css\">\n<!-- Generic page styles -->\n<link rel=\"stylesheet\" href=\"css/style.css\">\n<!-- CSS to style the file input field as button and adjust the Bootstrap progress bars -->\n<link rel=\"stylesheet\" href=\"css/jquery.fileupload.css\">\n</head>\n<body>\n<div class=\"navbar navbar-default navbar-fixed-top\">\n    <div class=\"container\">\n        <div class=\"navbar-header\">\n            <button type=\"button\" class=\"navbar-toggle\" data-toggle=\"collapse\" data-target=\".navbar-fixed-top .navbar-collapse\">\n                <span class=\"icon-bar\"></span>\n                <span class=\"icon-bar\"></span>\n                <span class=\"icon-bar\"></span>\n            </button>\n            <a class=\"navbar-brand\" href=\"https://github.com/blueimp/jQuery-File-Upload\">jQuery File Upload</a>\n        </div>\n        <div class=\"navbar-collapse collapse\">\n            <ul class=\"nav navbar-nav\">\n                <li><a href=\"https://github.com/blueimp/jQuery-File-Upload/tags\">Download</a></li>\n                <li><a href=\"https://github.com/blueimp/jQuery-File-Upload\">Source Code</a></li>\n                <li><a href=\"https://github.com/blueimp/jQuery-File-Upload/wiki\">Documentation</a></li>\n                <li><a href=\"https://blueimp.net\">&copy; Sebastian Tschan</a></li>\n            </ul>\n        </div>\n    </div>\n</div>\n<div class=\"container\">\n    <h1>jQuery File Upload Demo</h1>\n    <h2 class=\"lead\">Basic Plus version</h2>\n    <ul class=\"nav nav-tabs\">\n        <li><a href=\"basic.html\">Basic</a></li>\n        <li class=\"active\"><a href=\"basic-plus.html\">Basic Plus</a></li>\n        <li><a href=\"index.html\">Basic Plus UI</a></li>\n        <li><a href=\"angularjs.html\">AngularJS</a></li>\n        <li><a href=\"jquery-ui.html\">jQuery UI</a></li>\n    </ul>\n    <br>\n    <blockquote>\n        <p>File Upload widget with multiple file selection, drag&amp;drop support, progress bar, validation and preview images, audio and video for jQuery.<br>\n        Supports cross-domain, chunked and resumable file uploads and client-side image resizing.<br>\n        Works with any server-side platform (PHP, Python, Ruby on Rails, Java, Node.js, Go etc.) that supports standard HTML form file uploads.</p>\n    </blockquote>\n    <br>\n    <!-- The fileinput-button span is used to style the file input field as button -->\n    <span class=\"btn btn-success fileinput-button\">\n        <i class=\"glyphicon glyphicon-plus\"></i>\n        <span>Add files...</span>\n        <!-- The file input field used as target for the file upload widget -->\n        <input id=\"fileupload\" type=\"file\" name=\"files[]\" multiple>\n    </span>\n    <br>\n    <br>\n    <!-- The global progress bar -->\n    <div id=\"progress\" class=\"progress\">\n        <div class=\"progress-bar progress-bar-success\"></div>\n    </div>\n    <!-- The container for the uploaded files -->\n    <div id=\"files\" class=\"files\"></div>\n    <br>\n    <div class=\"panel panel-default\">\n        <div class=\"panel-heading\">\n            <h3 class=\"panel-title\">Demo Notes</h3>\n        </div>\n        <div class=\"panel-body\">\n            <ul>\n                <li>The maximum file size for uploads in this demo is <strong>999 KB</strong> (default file size is unlimited).</li>\n                <li>Only image files (<strong>JPG, GIF, PNG</strong>) are allowed in this demo (by default there is no file type restriction).</li>\n                <li>Uploaded files will be deleted automatically after <strong>5 minutes or less</strong> (demo files are stored in memory).</li>\n                <li>You can <strong>drag &amp; drop</strong> files from your desktop on this webpage (see <a href=\"https://github.com/blueimp/jQuery-File-Upload/wiki/Browser-support\">Browser support</a>).</li>\n                <li>Please refer to the <a href=\"https://github.com/blueimp/jQuery-File-Upload\">project website</a> and <a href=\"https://github.com/blueimp/jQuery-File-Upload/wiki\">documentation</a> for more information.</li>\n                <li>Built with the <a href=\"http://getbootstrap.com/\">Bootstrap</a> CSS framework and Icons from <a href=\"http://glyphicons.com/\">Glyphicons</a>.</li>\n            </ul>\n        </div>\n    </div>\n</div>\n<script src=\"//ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js\"></script>\n<!-- The jQuery UI widget factory, can be omitted if jQuery UI is already included -->\n<script src=\"js/vendor/jquery.ui.widget.js\"></script>\n<!-- The Load Image plugin is included for the preview images and image resizing functionality -->\n<script src=\"//blueimp.github.io/JavaScript-Load-Image/js/load-image.all.min.js\"></script>\n<!-- The Canvas to Blob plugin is included for image resizing functionality -->\n<script src=\"//blueimp.github.io/JavaScript-Canvas-to-Blob/js/canvas-to-blob.min.js\"></script>\n<!-- Bootstrap JS is not required, but included for the responsive demo navigation -->\n<script src=\"//netdna.bootstrapcdn.com/bootstrap/3.2.0/js/bootstrap.min.js\"></script>\n<!-- The Iframe Transport is required for browsers without support for XHR file uploads -->\n<script src=\"js/jquery.iframe-transport.js\"></script>\n<!-- The basic File Upload plugin -->\n<script src=\"js/jquery.fileupload.js\"></script>\n<!-- The File Upload processing plugin -->\n<script src=\"js/jquery.fileupload-process.js\"></script>\n<!-- The File Upload image preview & resize plugin -->\n<script src=\"js/jquery.fileupload-image.js\"></script>\n<!-- The File Upload audio preview plugin -->\n<script src=\"js/jquery.fileupload-audio.js\"></script>\n<!-- The File Upload video preview plugin -->\n<script src=\"js/jquery.fileupload-video.js\"></script>\n<!-- The File Upload validation plugin -->\n<script src=\"js/jquery.fileupload-validate.js\"></script>\n<script>\n/*jslint unparam: true, regexp: true */\n/*global window, $ */\n$(function () {\n    'use strict';\n    // Change this to the location of your server-side upload handler:\n    var url = window.location.hostname === 'blueimp.github.io' ?\n                '//jquery-file-upload.appspot.com/' : 'server/php/',\n        uploadButton = $('<button/>')\n            .addClass('btn btn-primary')\n            .prop('disabled', true)\n            .text('Processing...')\n            .on('click', function () {\n                var $this = $(this),\n                    data = $this.data();\n                $this\n                    .off('click')\n                    .text('Abort')\n                    .on('click', function () {\n                        $this.remove();\n                        data.abort();\n                    });\n                data.submit().always(function () {\n                    $this.remove();\n                });\n            });\n    $('#fileupload').fileupload({\n        url: url,\n        dataType: 'json',\n        autoUpload: false,\n        acceptFileTypes: /(\\.|\\/)(gif|jpe?g|png)$/i,\n        maxFileSize: 999000,\n        // Enable image resizing, except for Android and Opera,\n        // which actually support image resizing, but fail to\n        // send Blob objects via XHR requests:\n        disableImageResize: /Android(?!.*Chrome)|Opera/\n            .test(window.navigator.userAgent),\n        previewMaxWidth: 100,\n        previewMaxHeight: 100,\n        previewCrop: true\n    }).on('fileuploadadd', function (e, data) {\n        data.context = $('<div/>').appendTo('#files');\n        $.each(data.files, function (index, file) {\n            var node = $('<p/>')\n                    .append($('<span/>').text(file.name));\n            if (!index) {\n                node\n                    .append('<br>')\n                    .append(uploadButton.clone(true).data(data));\n            }\n            node.appendTo(data.context);\n        });\n    }).on('fileuploadprocessalways', function (e, data) {\n        var index = data.index,\n            file = data.files[index],\n            node = $(data.context.children()[index]);\n        if (file.preview) {\n            node\n                .prepend('<br>')\n                .prepend(file.preview);\n        }\n        if (file.error) {\n            node\n                .append('<br>')\n                .append($('<span class=\"text-danger\"/>').text(file.error));\n        }\n        if (index + 1 === data.files.length) {\n            data.context.find('button')\n                .text('Upload')\n                .prop('disabled', !!data.files.error);\n        }\n    }).on('fileuploadprogressall', function (e, data) {\n        var progress = parseInt(data.loaded / data.total * 100, 10);\n        $('#progress .progress-bar').css(\n            'width',\n            progress + '%'\n        );\n    }).on('fileuploaddone', function (e, data) {\n        $.each(data.result.files, function (index, file) {\n            if (file.url) {\n                var link = $('<a>')\n                    .attr('target', '_blank')\n                    .prop('href', file.url);\n                $(data.context.children()[index])\n                    .wrap(link);\n            } else if (file.error) {\n                var error = $('<span class=\"text-danger\"/>').text(file.error);\n                $(data.context.children()[index])\n                    .append('<br>')\n                    .append(error);\n            }\n        });\n    }).on('fileuploadfail', function (e, data) {\n        $.each(data.files, function (index) {\n            var error = $('<span class=\"text-danger\"/>').text('File upload failed.');\n            $(data.context.children()[index])\n                .append('<br>')\n                .append(error);\n        });\n    }).prop('disabled', !$.support.fileInput)\n        .parent().addClass($.support.fileInput ? undefined : 'disabled');\n});\n</script>\n</body>\n</html>\n"
  },
  {
    "path": "app_backend/static/plugin/jQuery-File-Upload-9.18.0/basic.html",
    "content": "<!DOCTYPE HTML>\n<!--\n/*\n * jQuery File Upload Plugin Basic Demo\n * https://github.com/blueimp/jQuery-File-Upload\n *\n * Copyright 2013, Sebastian Tschan\n * https://blueimp.net\n *\n * Licensed under the MIT license:\n * https://opensource.org/licenses/MIT\n */\n-->\n<html lang=\"en\">\n<head>\n<!-- Force latest IE rendering engine or ChromeFrame if installed -->\n<!--[if IE]><meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge,chrome=1\"><![endif]-->\n<meta charset=\"utf-8\">\n<title>jQuery File Upload Demo - Basic version</title>\n<meta name=\"description\" content=\"File Upload widget with multiple file selection, drag&amp;drop support and progress bar for jQuery. Supports cross-domain, chunked and resumable file uploads. Works with any server-side platform (PHP, Python, Ruby on Rails, Java, Node.js, Go etc.) that supports standard HTML form file uploads.\">\n<meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n<!-- Bootstrap styles -->\n<link rel=\"stylesheet\" href=\"//netdna.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.min.css\">\n<!-- Generic page styles -->\n<link rel=\"stylesheet\" href=\"css/style.css\">\n<!-- CSS to style the file input field as button and adjust the Bootstrap progress bars -->\n<link rel=\"stylesheet\" href=\"css/jquery.fileupload.css\">\n</head>\n<body>\n<div class=\"navbar navbar-default navbar-fixed-top\">\n    <div class=\"container\">\n        <div class=\"navbar-header\">\n            <button type=\"button\" class=\"navbar-toggle\" data-toggle=\"collapse\" data-target=\".navbar-fixed-top .navbar-collapse\">\n                <span class=\"icon-bar\"></span>\n                <span class=\"icon-bar\"></span>\n                <span class=\"icon-bar\"></span>\n            </button>\n            <a class=\"navbar-brand\" href=\"https://github.com/blueimp/jQuery-File-Upload\">jQuery File Upload</a>\n        </div>\n        <div class=\"navbar-collapse collapse\">\n            <ul class=\"nav navbar-nav\">\n                <li><a href=\"https://github.com/blueimp/jQuery-File-Upload/tags\">Download</a></li>\n                <li><a href=\"https://github.com/blueimp/jQuery-File-Upload\">Source Code</a></li>\n                <li><a href=\"https://github.com/blueimp/jQuery-File-Upload/wiki\">Documentation</a></li>\n                <li><a href=\"https://blueimp.net\">&copy; Sebastian Tschan</a></li>\n            </ul>\n        </div>\n    </div>\n</div>\n<div class=\"container\">\n    <h1>jQuery File Upload Demo</h1>\n    <h2 class=\"lead\">Basic version</h2>\n    <ul class=\"nav nav-tabs\">\n        <li class=\"active\"><a href=\"basic.html\">Basic</a></li>\n        <li><a href=\"basic-plus.html\">Basic Plus</a></li>\n        <li><a href=\"index.html\">Basic Plus UI</a></li>\n        <li><a href=\"angularjs.html\">AngularJS</a></li>\n        <li><a href=\"jquery-ui.html\">jQuery UI</a></li>\n    </ul>\n    <br>\n    <blockquote>\n        <p>File Upload widget with multiple file selection, drag&amp;drop support and progress bar for jQuery.<br>\n        Supports cross-domain, chunked and resumable file uploads.<br>\n        Works with any server-side platform (PHP, Python, Ruby on Rails, Java, Node.js, Go etc.) that supports standard HTML form file uploads.</p>\n    </blockquote>\n    <br>\n    <!-- The fileinput-button span is used to style the file input field as button -->\n    <span class=\"btn btn-success fileinput-button\">\n        <i class=\"glyphicon glyphicon-plus\"></i>\n        <span>Select files...</span>\n        <!-- The file input field used as target for the file upload widget -->\n        <input id=\"fileupload\" type=\"file\" name=\"files[]\" multiple>\n    </span>\n    <br>\n    <br>\n    <!-- The global progress bar -->\n    <div id=\"progress\" class=\"progress\">\n        <div class=\"progress-bar progress-bar-success\"></div>\n    </div>\n    <!-- The container for the uploaded files -->\n    <div id=\"files\" class=\"files\"></div>\n    <br>\n    <div class=\"panel panel-default\">\n        <div class=\"panel-heading\">\n            <h3 class=\"panel-title\">Demo Notes</h3>\n        </div>\n        <div class=\"panel-body\">\n            <ul>\n                <li>The maximum file size for uploads in this demo is <strong>999 KB</strong> (default file size is unlimited).</li>\n                <li>Only image files (<strong>JPG, GIF, PNG</strong>) are allowed in this demo (by default there is no file type restriction).</li>\n                <li>Uploaded files will be deleted automatically after <strong>5 minutes or less</strong> (demo files are stored in memory).</li>\n                <li>You can <strong>drag &amp; drop</strong> files from your desktop on this webpage (see <a href=\"https://github.com/blueimp/jQuery-File-Upload/wiki/Browser-support\">Browser support</a>).</li>\n                <li>Please refer to the <a href=\"https://github.com/blueimp/jQuery-File-Upload\">project website</a> and <a href=\"https://github.com/blueimp/jQuery-File-Upload/wiki\">documentation</a> for more information.</li>\n                <li>Built with the <a href=\"http://getbootstrap.com/\">Bootstrap</a> CSS framework and Icons from <a href=\"http://glyphicons.com/\">Glyphicons</a>.</li>\n            </ul>\n        </div>\n    </div>\n</div>\n<script src=\"//ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js\"></script>\n<!-- The jQuery UI widget factory, can be omitted if jQuery UI is already included -->\n<script src=\"js/vendor/jquery.ui.widget.js\"></script>\n<!-- The Iframe Transport is required for browsers without support for XHR file uploads -->\n<script src=\"js/jquery.iframe-transport.js\"></script>\n<!-- The basic File Upload plugin -->\n<script src=\"js/jquery.fileupload.js\"></script>\n<!-- Bootstrap JS is not required, but included for the responsive demo navigation -->\n<script src=\"//netdna.bootstrapcdn.com/bootstrap/3.2.0/js/bootstrap.min.js\"></script>\n<script>\n/*jslint unparam: true */\n/*global window, $ */\n$(function () {\n    'use strict';\n    // Change this to the location of your server-side upload handler:\n    var url = window.location.hostname === 'blueimp.github.io' ?\n                '//jquery-file-upload.appspot.com/' : 'server/php/';\n    $('#fileupload').fileupload({\n        url: url,\n        dataType: 'json',\n        done: function (e, data) {\n            $.each(data.result.files, function (index, file) {\n                $('<p/>').text(file.name).appendTo('#files');\n            });\n        },\n        progressall: function (e, data) {\n            var progress = parseInt(data.loaded / data.total * 100, 10);\n            $('#progress .progress-bar').css(\n                'width',\n                progress + '%'\n            );\n        }\n    }).prop('disabled', !$.support.fileInput)\n        .parent().addClass($.support.fileInput ? undefined : 'disabled');\n});\n</script>\n</body>\n</html>\n"
  },
  {
    "path": "app_backend/static/plugin/jQuery-File-Upload-9.18.0/bower-version-update.js",
    "content": "#!/usr/bin/env node\n\n'use strict';\n\nvar path = require('path');\nvar packageJSON = require(path.join(__dirname, 'package.json'));\nvar bowerFile = path.join(__dirname, 'bower.json');\nvar bowerJSON = require('bower-json').parse(\n  require(bowerFile),\n  {normalize: true}\n);\nbowerJSON.version = packageJSON.version;\nrequire('fs').writeFileSync(\n  bowerFile,\n  JSON.stringify(bowerJSON, null, 2) + '\\n'\n);\n"
  },
  {
    "path": "app_backend/static/plugin/jQuery-File-Upload-9.18.0/bower.json",
    "content": "{\n  \"name\": \"blueimp-file-upload\",\n  \"version\": \"9.18.0\",\n  \"title\": \"jQuery File Upload\",\n  \"description\": \"File Upload widget with multiple file selection, drag&amp;drop support, progress bar, validation and preview images.\",\n  \"keywords\": [\n    \"jquery\",\n    \"file\",\n    \"upload\",\n    \"widget\",\n    \"multiple\",\n    \"selection\",\n    \"drag\",\n    \"drop\",\n    \"progress\",\n    \"preview\",\n    \"cross-domain\",\n    \"cross-site\",\n    \"chunk\",\n    \"resume\",\n    \"gae\",\n    \"go\",\n    \"python\",\n    \"php\",\n    \"bootstrap\"\n  ],\n  \"homepage\": \"https://github.com/blueimp/jQuery-File-Upload\",\n  \"author\": {\n    \"name\": \"Sebastian Tschan\",\n    \"url\": \"https://blueimp.net\"\n  },\n  \"maintainers\": [\n    {\n      \"name\": \"Sebastian Tschan\",\n      \"url\": \"https://blueimp.net\"\n    }\n  ],\n  \"repository\": {\n    \"type\": \"git\",\n    \"url\": \"git://github.com/blueimp/jQuery-File-Upload.git\"\n  },\n  \"bugs\": \"https://github.com/blueimp/jQuery-File-Upload/issues\",\n  \"license\": \"MIT\",\n  \"dependencies\": {\n    \"jquery\": \">=1.6\",\n    \"blueimp-tmpl\": \">=2.5.4\",\n    \"blueimp-load-image\": \">=1.13.0\",\n    \"blueimp-canvas-to-blob\": \">=2.1.1\"\n  },\n  \"main\": [\n    \"js/jquery.fileupload.js\"\n  ],\n  \"ignore\": [\n    \"/*.*\",\n    \"/cors\",\n    \"css/demo-ie8.css\",\n    \"css/demo.css\",\n    \"css/style.css\",\n    \"js/app.js\",\n    \"js/main.js\",\n    \"server\",\n    \"test\"\n  ]\n}\n"
  },
  {
    "path": "app_backend/static/plugin/jQuery-File-Upload-9.18.0/cors/postmessage.html",
    "content": "<!DOCTYPE HTML>\n<!--\n/*\n * jQuery File Upload Plugin postMessage API\n * https://github.com/blueimp/jQuery-File-Upload\n *\n * Copyright 2011, Sebastian Tschan\n * https://blueimp.net\n *\n * Licensed under the MIT license:\n * https://opensource.org/licenses/MIT\n */\n-->\n<html lang=\"en\">\n<head>\n<meta charset=\"utf-8\">\n<title>jQuery File Upload Plugin postMessage API</title>\n<script src=\"//ajax.googleapis.com/ajax/libs/jquery/1.10.1/jquery.min.js\"></script>\n</head>\n<body>\n<script>\n/*jslint unparam: true, regexp: true */\n/*global $, Blob, FormData, location */\n'use strict';\nvar origin = /^http:\\/\\/example.org/,\n    target = new RegExp('^(http(s)?:)?\\\\/\\\\/' + location.host + '\\\\/');\n$(window).on('message', function (e) {\n    e = e.originalEvent;\n    var s = e.data,\n        xhr = $.ajaxSettings.xhr(),\n        f;\n    if (!origin.test(e.origin)) {\n        throw new Error('Origin \"' + e.origin + '\" does not match ' + origin);\n    }\n    if (!target.test(e.data.url)) {\n        throw new Error('Target \"' + e.data.url + '\" does not match ' + target);\n    }\n    $(xhr.upload).on('progress', function (ev) {\n        ev = ev.originalEvent;\n        e.source.postMessage({\n            id: s.id,\n            type: ev.type,\n            timeStamp: ev.timeStamp,\n            lengthComputable: ev.lengthComputable,\n            loaded: ev.loaded,\n            total: ev.total\n        }, e.origin);\n    });\n    s.xhr = function () {\n        return xhr;\n    };\n    if (!(s.data instanceof Blob)) {\n        f = new FormData();\n        $.each(s.data, function (i, v) {\n            f.append(v.name, v.value);\n        });\n        s.data = f;\n    }\n    $.ajax(s).always(function (result, statusText, jqXHR) {\n        if (!jqXHR.done) {\n            jqXHR = result;\n            result = null;\n        }\n        e.source.postMessage({\n            id: s.id,\n            status: jqXHR.status,\n            statusText: statusText,\n            result: result,\n            headers: jqXHR.getAllResponseHeaders()\n        }, e.origin);\n    });\n});\n</script>\n</body>\n</html>\n"
  },
  {
    "path": "app_backend/static/plugin/jQuery-File-Upload-9.18.0/cors/result.html",
    "content": "<!DOCTYPE HTML>\n<!--\n/*\n * jQuery Iframe Transport Plugin Redirect Page\n * https://github.com/blueimp/jQuery-File-Upload\n *\n * Copyright 2010, Sebastian Tschan\n * https://blueimp.net\n *\n * Licensed under the MIT license:\n * https://opensource.org/licenses/MIT\n */\n-->\n<html lang=\"en\">\n<head>\n<meta charset=\"utf-8\">\n<title>jQuery Iframe Transport Plugin Redirect Page</title>\n</head>\n<body>\n<script>\ndocument.body.innerText=document.body.textContent=decodeURIComponent(window.location.search.slice(1));\n</script>\n</body>\n</html>\n"
  },
  {
    "path": "app_backend/static/plugin/jQuery-File-Upload-9.18.0/css/demo-ie8.css",
    "content": "@charset \"UTF-8\";\n/*\n * jQuery File Upload Demo CSS Fixes for IE<9\n * https://github.com/blueimp/jQuery-File-Upload\n *\n * Copyright 2013, Sebastian Tschan\n * https://blueimp.net\n *\n * Licensed under the MIT license:\n * https://opensource.org/licenses/MIT\n */\n\n.navigation {\n  list-style: none;\n  padding: 0;\n  margin: 1em 0;\n}\n.navigation li {\n  display: inline;\n  margin-right: 10px;\n}\n"
  },
  {
    "path": "app_backend/static/plugin/jQuery-File-Upload-9.18.0/css/demo.css",
    "content": "@charset \"UTF-8\";\n/*\n * jQuery File Upload Demo CSS\n * https://github.com/blueimp/jQuery-File-Upload\n *\n * Copyright 2013, Sebastian Tschan\n * https://blueimp.net\n *\n * Licensed under the MIT license:\n * https://opensource.org/licenses/MIT\n */\n\nbody {\n  max-width: 750px;\n  margin: 0 auto;\n  padding: 1em;\n  font-family: \"Lucida Grande\", \"Lucida Sans Unicode\", Arial, sans-serif;\n  font-size: 1em;\n  line-height: 1.4em;\n  background: #222;\n  color: #fff;\n  -webkit-text-size-adjust: 100%;\n      -ms-text-size-adjust: 100%;\n}\na {\n  color: orange;\n  text-decoration: none;\n}\nimg {\n  border: 0;\n  vertical-align: middle;\n}\nh1 {\n  line-height: 1em;\n}\nblockquote {\n  padding: 0 0 0 15px;\n  margin: 0 0 20px;\n  border-left: 5px solid #eee;\n}\ntable {\n  width: 100%;\n  margin: 10px 0;\n}\n\n.fileupload-progress {\n\tmargin: 10px 0;\n}\n.fileupload-progress .progress-extended {\n\tmargin-top: 5px;\n}\n.error {\n  color: red;\n}\n\n@media (min-width: 481px) {\n  .navigation {\n    list-style: none;\n    padding: 0;\n  }\n  .navigation li {\n    display: inline-block;\n  }\n  .navigation li:not(:first-child):before {\n    content: \"| \";\n  }\n}\n"
  },
  {
    "path": "app_backend/static/plugin/jQuery-File-Upload-9.18.0/css/jquery.fileupload-noscript.css",
    "content": "@charset \"UTF-8\";\n/*\n * jQuery File Upload Plugin NoScript CSS\n * https://github.com/blueimp/jQuery-File-Upload\n *\n * Copyright 2013, Sebastian Tschan\n * https://blueimp.net\n *\n * Licensed under the MIT license:\n * https://opensource.org/licenses/MIT\n */\n\n.fileinput-button input {\n  position: static;\n  opacity: 1;\n  filter: none;\n  font-size: inherit !important;\n  direction: inherit;\n}\n.fileinput-button span {\n  display: none;\n}\n"
  },
  {
    "path": "app_backend/static/plugin/jQuery-File-Upload-9.18.0/css/jquery.fileupload-ui-noscript.css",
    "content": "@charset \"UTF-8\";\n/*\n * jQuery File Upload UI Plugin NoScript CSS\n * https://github.com/blueimp/jQuery-File-Upload\n *\n * Copyright 2012, Sebastian Tschan\n * https://blueimp.net\n *\n * Licensed under the MIT license:\n * https://opensource.org/licenses/MIT\n */\n\n.fileinput-button i,\n.fileupload-buttonbar .delete,\n.fileupload-buttonbar .toggle {\n  display: none;\n}\n"
  },
  {
    "path": "app_backend/static/plugin/jQuery-File-Upload-9.18.0/css/jquery.fileupload-ui.css",
    "content": "@charset \"UTF-8\";\n/*\n * jQuery File Upload UI Plugin CSS\n * https://github.com/blueimp/jQuery-File-Upload\n *\n * Copyright 2010, Sebastian Tschan\n * https://blueimp.net\n *\n * Licensed under the MIT license:\n * https://opensource.org/licenses/MIT\n */\n\n.fileupload-buttonbar .btn,\n.fileupload-buttonbar .toggle {\n  margin-bottom: 5px;\n}\n.progress-animated .progress-bar,\n.progress-animated .bar {\n  background: url(\"../img/progressbar.gif\") !important;\n  filter: none;\n}\n.fileupload-process {\n  float: right;\n  display: none;\n}\n.fileupload-processing .fileupload-process,\n.files .processing .preview {\n  display: block;\n  width: 32px;\n  height: 32px;\n  background: url(\"../img/loading.gif\") center no-repeat;\n  background-size: contain;\n}\n.files audio,\n.files video {\n  max-width: 300px;\n}\n\n@media (max-width: 767px) {\n  .fileupload-buttonbar .toggle,\n  .files .toggle,\n  .files .btn span {\n    display: none;\n  }\n  .files .name {\n    width: 80px;\n    word-wrap: break-word;\n  }\n  .files audio,\n  .files video {\n    max-width: 80px;\n  }\n  .files img,\n  .files canvas {\n    max-width: 100%;\n  }\n}\n"
  },
  {
    "path": "app_backend/static/plugin/jQuery-File-Upload-9.18.0/css/jquery.fileupload.css",
    "content": "@charset \"UTF-8\";\n/*\n * jQuery File Upload Plugin CSS\n * https://github.com/blueimp/jQuery-File-Upload\n *\n * Copyright 2013, Sebastian Tschan\n * https://blueimp.net\n *\n * Licensed under the MIT license:\n * https://opensource.org/licenses/MIT\n */\n\n.fileinput-button {\n  position: relative;\n  overflow: hidden;\n  display: inline-block;\n}\n.fileinput-button input {\n  position: absolute;\n  top: 0;\n  right: 0;\n  margin: 0;\n  opacity: 0;\n  -ms-filter: 'alpha(opacity=0)';\n  font-size: 200px !important;\n  direction: ltr;\n  cursor: pointer;\n}\n\n/* Fixes for IE < 8 */\n@media screen\\9 {\n  .fileinput-button input {\n    filter: alpha(opacity=0);\n    font-size: 100%;\n    height: 100%;\n  }\n}\n"
  },
  {
    "path": "app_backend/static/plugin/jQuery-File-Upload-9.18.0/css/style.css",
    "content": "@charset \"UTF-8\";\n/*\n * jQuery File Upload Plugin CSS Example\n * https://github.com/blueimp/jQuery-File-Upload\n *\n * Copyright 2013, Sebastian Tschan\n * https://blueimp.net\n *\n * Licensed under the MIT license:\n * https://opensource.org/licenses/MIT\n */\n\nbody {\n  padding-top: 60px;\n}\n"
  },
  {
    "path": "app_backend/static/plugin/jQuery-File-Upload-9.18.0/index.html",
    "content": "<!DOCTYPE HTML>\n<!--\n/*\n * jQuery File Upload Plugin Demo\n * https://github.com/blueimp/jQuery-File-Upload\n *\n * Copyright 2010, Sebastian Tschan\n * https://blueimp.net\n *\n * Licensed under the MIT license:\n * https://opensource.org/licenses/MIT\n */\n-->\n<html lang=\"en\">\n<head>\n<!-- Force latest IE rendering engine or ChromeFrame if installed -->\n<!--[if IE]>\n<meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge,chrome=1\">\n<![endif]-->\n<meta charset=\"utf-8\">\n<title>jQuery File Upload Demo</title>\n<meta name=\"description\" content=\"File Upload widget with multiple file selection, drag&amp;drop support, progress bars, validation and preview images, audio and video for jQuery. Supports cross-domain, chunked and resumable file uploads and client-side image resizing. Works with any server-side platform (PHP, Python, Ruby on Rails, Java, Node.js, Go etc.) that supports standard HTML form file uploads.\">\n<meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n<!-- Bootstrap styles -->\n<link rel=\"stylesheet\" href=\"//netdna.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.min.css\">\n<!-- Generic page styles -->\n<link rel=\"stylesheet\" href=\"css/style.css\">\n<!-- blueimp Gallery styles -->\n<link rel=\"stylesheet\" href=\"//blueimp.github.io/Gallery/css/blueimp-gallery.min.css\">\n<!-- CSS to style the file input field as button and adjust the Bootstrap progress bars -->\n<link rel=\"stylesheet\" href=\"css/jquery.fileupload.css\">\n<link rel=\"stylesheet\" href=\"css/jquery.fileupload-ui.css\">\n<!-- CSS adjustments for browsers with JavaScript disabled -->\n<noscript><link rel=\"stylesheet\" href=\"css/jquery.fileupload-noscript.css\"></noscript>\n<noscript><link rel=\"stylesheet\" href=\"css/jquery.fileupload-ui-noscript.css\"></noscript>\n</head>\n<body>\n<div class=\"navbar navbar-default navbar-fixed-top\">\n    <div class=\"container\">\n        <div class=\"navbar-header\">\n            <button type=\"button\" class=\"navbar-toggle\" data-toggle=\"collapse\" data-target=\".navbar-fixed-top .navbar-collapse\">\n                <span class=\"icon-bar\"></span>\n                <span class=\"icon-bar\"></span>\n                <span class=\"icon-bar\"></span>\n            </button>\n            <a class=\"navbar-brand\" href=\"https://github.com/blueimp/jQuery-File-Upload\">jQuery File Upload</a>\n        </div>\n        <div class=\"navbar-collapse collapse\">\n            <ul class=\"nav navbar-nav\">\n                <li><a href=\"https://github.com/blueimp/jQuery-File-Upload/tags\">Download</a></li>\n                <li><a href=\"https://github.com/blueimp/jQuery-File-Upload\">Source Code</a></li>\n                <li><a href=\"https://github.com/blueimp/jQuery-File-Upload/wiki\">Documentation</a></li>\n                <li><a href=\"https://blueimp.net\">&copy; Sebastian Tschan</a></li>\n            </ul>\n        </div>\n    </div>\n</div>\n<div class=\"container\">\n    <h1>jQuery File Upload Demo</h1>\n    <h2 class=\"lead\">Basic Plus UI version</h2>\n    <ul class=\"nav nav-tabs\">\n        <li><a href=\"basic.html\">Basic</a></li>\n        <li><a href=\"basic-plus.html\">Basic Plus</a></li>\n        <li class=\"active\"><a href=\"index.html\">Basic Plus UI</a></li>\n        <li><a href=\"angularjs.html\">AngularJS</a></li>\n        <li><a href=\"jquery-ui.html\">jQuery UI</a></li>\n    </ul>\n    <br>\n    <blockquote>\n        <p>File Upload widget with multiple file selection, drag&amp;drop support, progress bars, validation and preview images, audio and video for jQuery.<br>\n        Supports cross-domain, chunked and resumable file uploads and client-side image resizing.<br>\n        Works with any server-side platform (PHP, Python, Ruby on Rails, Java, Node.js, Go etc.) that supports standard HTML form file uploads.</p>\n    </blockquote>\n    <br>\n    <!-- The file upload form used as target for the file upload widget -->\n    <form id=\"fileupload\" action=\"//jquery-file-upload.appspot.com/\" method=\"POST\" enctype=\"multipart/form-data\">\n        <!-- Redirect browsers with JavaScript disabled to the origin page -->\n        <noscript><input type=\"hidden\" name=\"redirect\" value=\"https://blueimp.github.io/jQuery-File-Upload/\"></noscript>\n        <!-- The fileupload-buttonbar contains buttons to add/delete files and start/cancel the upload -->\n        <div class=\"row fileupload-buttonbar\">\n            <div class=\"col-lg-7\">\n                <!-- The fileinput-button span is used to style the file input field as button -->\n                <span class=\"btn btn-success fileinput-button\">\n                    <i class=\"glyphicon glyphicon-plus\"></i>\n                    <span>Add files...</span>\n                    <input type=\"file\" name=\"files[]\" multiple>\n                </span>\n                <button type=\"submit\" class=\"btn btn-primary start\">\n                    <i class=\"glyphicon glyphicon-upload\"></i>\n                    <span>Start upload</span>\n                </button>\n                <button type=\"reset\" class=\"btn btn-warning cancel\">\n                    <i class=\"glyphicon glyphicon-ban-circle\"></i>\n                    <span>Cancel upload</span>\n                </button>\n                <button type=\"button\" class=\"btn btn-danger delete\">\n                    <i class=\"glyphicon glyphicon-trash\"></i>\n                    <span>Delete</span>\n                </button>\n                <input type=\"checkbox\" class=\"toggle\">\n                <!-- The global file processing state -->\n                <span class=\"fileupload-process\"></span>\n            </div>\n            <!-- The global progress state -->\n            <div class=\"col-lg-5 fileupload-progress fade\">\n                <!-- The global progress bar -->\n                <div class=\"progress progress-striped active\" role=\"progressbar\" aria-valuemin=\"0\" aria-valuemax=\"100\">\n                    <div class=\"progress-bar progress-bar-success\" style=\"width:0%;\"></div>\n                </div>\n                <!-- The extended global progress state -->\n                <div class=\"progress-extended\">&nbsp;</div>\n            </div>\n        </div>\n        <!-- The table listing the files available for upload/download -->\n        <table role=\"presentation\" class=\"table table-striped\"><tbody class=\"files\"></tbody></table>\n    </form>\n    <br>\n    <div class=\"panel panel-default\">\n        <div class=\"panel-heading\">\n            <h3 class=\"panel-title\">Demo Notes</h3>\n        </div>\n        <div class=\"panel-body\">\n            <ul>\n                <li>The maximum file size for uploads in this demo is <strong>999 KB</strong> (default file size is unlimited).</li>\n                <li>Only image files (<strong>JPG, GIF, PNG</strong>) are allowed in this demo (by default there is no file type restriction).</li>\n                <li>Uploaded files will be deleted automatically after <strong>5 minutes or less</strong> (demo files are stored in memory).</li>\n                <li>You can <strong>drag &amp; drop</strong> files from your desktop on this webpage (see <a href=\"https://github.com/blueimp/jQuery-File-Upload/wiki/Browser-support\">Browser support</a>).</li>\n                <li>Please refer to the <a href=\"https://github.com/blueimp/jQuery-File-Upload\">project website</a> and <a href=\"https://github.com/blueimp/jQuery-File-Upload/wiki\">documentation</a> for more information.</li>\n                <li>Built with the <a href=\"http://getbootstrap.com/\">Bootstrap</a> CSS framework and Icons from <a href=\"http://glyphicons.com/\">Glyphicons</a>.</li>\n            </ul>\n        </div>\n    </div>\n</div>\n<!-- The blueimp Gallery widget -->\n<div id=\"blueimp-gallery\" class=\"blueimp-gallery blueimp-gallery-controls\" data-filter=\":even\">\n    <div class=\"slides\"></div>\n    <h3 class=\"title\"></h3>\n    <a class=\"prev\">‹</a>\n    <a class=\"next\">›</a>\n    <a class=\"close\">×</a>\n    <a class=\"play-pause\"></a>\n    <ol class=\"indicator\"></ol>\n</div>\n<!-- The template to display files available for upload -->\n<script id=\"template-upload\" type=\"text/x-tmpl\">\n{% for (var i=0, file; file=o.files[i]; i++) { %}\n    <tr class=\"template-upload fade\">\n        <td>\n            <span class=\"preview\"></span>\n        </td>\n        <td>\n            <p class=\"name\">{%=file.name%}</p>\n            <strong class=\"error text-danger\"></strong>\n        </td>\n        <td>\n            <p class=\"size\">Processing...</p>\n            <div class=\"progress progress-striped active\" role=\"progressbar\" aria-valuemin=\"0\" aria-valuemax=\"100\" aria-valuenow=\"0\"><div class=\"progress-bar progress-bar-success\" style=\"width:0%;\"></div></div>\n        </td>\n        <td>\n            {% if (!i && !o.options.autoUpload) { %}\n                <button class=\"btn btn-primary start\" disabled>\n                    <i class=\"glyphicon glyphicon-upload\"></i>\n                    <span>Start</span>\n                </button>\n            {% } %}\n            {% if (!i) { %}\n                <button class=\"btn btn-warning cancel\">\n                    <i class=\"glyphicon glyphicon-ban-circle\"></i>\n                    <span>Cancel</span>\n                </button>\n            {% } %}\n        </td>\n    </tr>\n{% } %}\n</script>\n<!-- The template to display files available for download -->\n<script id=\"template-download\" type=\"text/x-tmpl\">\n{% for (var i=0, file; file=o.files[i]; i++) { %}\n    <tr class=\"template-download fade\">\n        <td>\n            <span class=\"preview\">\n                {% if (file.thumbnailUrl) { %}\n                    <a href=\"{%=file.url%}\" title=\"{%=file.name%}\" download=\"{%=file.name%}\" data-gallery><img src=\"{%=file.thumbnailUrl%}\"></a>\n                {% } %}\n            </span>\n        </td>\n        <td>\n            <p class=\"name\">\n                {% if (file.url) { %}\n                    <a href=\"{%=file.url%}\" title=\"{%=file.name%}\" download=\"{%=file.name%}\" {%=file.thumbnailUrl?'data-gallery':''%}>{%=file.name%}</a>\n                {% } else { %}\n                    <span>{%=file.name%}</span>\n                {% } %}\n            </p>\n            {% if (file.error) { %}\n                <div><span class=\"label label-danger\">Error</span> {%=file.error%}</div>\n            {% } %}\n        </td>\n        <td>\n            <span class=\"size\">{%=o.formatFileSize(file.size)%}</span>\n        </td>\n        <td>\n            {% if (file.deleteUrl) { %}\n                <button class=\"btn btn-danger delete\" data-type=\"{%=file.deleteType%}\" data-url=\"{%=file.deleteUrl%}\"{% if (file.deleteWithCredentials) { %} data-xhr-fields='{\"withCredentials\":true}'{% } %}>\n                    <i class=\"glyphicon glyphicon-trash\"></i>\n                    <span>Delete</span>\n                </button>\n                <input type=\"checkbox\" name=\"delete\" value=\"1\" class=\"toggle\">\n            {% } else { %}\n                <button class=\"btn btn-warning cancel\">\n                    <i class=\"glyphicon glyphicon-ban-circle\"></i>\n                    <span>Cancel</span>\n                </button>\n            {% } %}\n        </td>\n    </tr>\n{% } %}\n</script>\n<script src=\"//ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js\"></script>\n<!-- The jQuery UI widget factory, can be omitted if jQuery UI is already included -->\n<script src=\"js/vendor/jquery.ui.widget.js\"></script>\n<!-- The Templates plugin is included to render the upload/download listings -->\n<script src=\"//blueimp.github.io/JavaScript-Templates/js/tmpl.min.js\"></script>\n<!-- The Load Image plugin is included for the preview images and image resizing functionality -->\n<script src=\"//blueimp.github.io/JavaScript-Load-Image/js/load-image.all.min.js\"></script>\n<!-- The Canvas to Blob plugin is included for image resizing functionality -->\n<script src=\"//blueimp.github.io/JavaScript-Canvas-to-Blob/js/canvas-to-blob.min.js\"></script>\n<!-- Bootstrap JS is not required, but included for the responsive demo navigation -->\n<script src=\"//netdna.bootstrapcdn.com/bootstrap/3.2.0/js/bootstrap.min.js\"></script>\n<!-- blueimp Gallery script -->\n<script src=\"//blueimp.github.io/Gallery/js/jquery.blueimp-gallery.min.js\"></script>\n<!-- The Iframe Transport is required for browsers without support for XHR file uploads -->\n<script src=\"js/jquery.iframe-transport.js\"></script>\n<!-- The basic File Upload plugin -->\n<script src=\"js/jquery.fileupload.js\"></script>\n<!-- The File Upload processing plugin -->\n<script src=\"js/jquery.fileupload-process.js\"></script>\n<!-- The File Upload image preview & resize plugin -->\n<script src=\"js/jquery.fileupload-image.js\"></script>\n<!-- The File Upload audio preview plugin -->\n<script src=\"js/jquery.fileupload-audio.js\"></script>\n<!-- The File Upload video preview plugin -->\n<script src=\"js/jquery.fileupload-video.js\"></script>\n<!-- The File Upload validation plugin -->\n<script src=\"js/jquery.fileupload-validate.js\"></script>\n<!-- The File Upload user interface plugin -->\n<script src=\"js/jquery.fileupload-ui.js\"></script>\n<!-- The main application script -->\n<script src=\"js/main.js\"></script>\n<!-- The XDomainRequest Transport is included for cross-domain file deletion for IE 8 and IE 9 -->\n<!--[if (gte IE 8)&(lt IE 10)]>\n<script src=\"js/cors/jquery.xdr-transport.js\"></script>\n<![endif]-->\n</body>\n</html>\n"
  },
  {
    "path": "app_backend/static/plugin/jQuery-File-Upload-9.18.0/jquery-ui.html",
    "content": "<!DOCTYPE HTML>\n<!--\n/*\n * jQuery File Upload Plugin jQuery UI Demo\n * https://github.com/blueimp/jQuery-File-Upload\n *\n * Copyright 2013, Sebastian Tschan\n * https://blueimp.net\n *\n * Licensed under the MIT license:\n * https://opensource.org/licenses/MIT\n */\n-->\n<html lang=\"en\">\n<head>\n<!-- Force latest IE rendering engine or ChromeFrame if installed -->\n<!--[if IE]>\n<meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge,chrome=1\">\n<![endif]-->\n<meta charset=\"utf-8\">\n<title>jQuery File Upload Demo - jQuery UI version</title>\n<meta name=\"description\" content=\"File Upload widget with multiple file selection, drag&amp;drop support, progress bars, validation and preview images, audio and video for jQuery. Supports cross-domain, chunked and resumable file uploads and client-side image resizing. Works with any server-side platform (PHP, Python, Ruby on Rails, Java, Node.js, Go etc.) that supports standard HTML form file uploads.\">\n<meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n<!-- jQuery UI styles -->\n<link rel=\"stylesheet\" href=\"//ajax.googleapis.com/ajax/libs/jqueryui/1.11.1/themes/dark-hive/jquery-ui.css\" id=\"theme\">\n<!-- Demo styles -->\n<link rel=\"stylesheet\" href=\"css/demo.css\">\n<!--[if lte IE 8]>\n<link rel=\"stylesheet\" href=\"css/demo-ie8.css\">\n<![endif]-->\n<style>\n/* Adjust the jQuery UI widget font-size: */\n.ui-widget {\n    font-size: 0.95em;\n}\n</style>\n<!-- blueimp Gallery styles -->\n<link rel=\"stylesheet\" href=\"//blueimp.github.io/Gallery/css/blueimp-gallery.min.css\">\n<!-- CSS to style the file input field as button and adjust the Bootstrap progress bars -->\n<link rel=\"stylesheet\" href=\"css/jquery.fileupload.css\">\n<link rel=\"stylesheet\" href=\"css/jquery.fileupload-ui.css\">\n<!-- CSS adjustments for browsers with JavaScript disabled -->\n<noscript><link rel=\"stylesheet\" href=\"css/jquery.fileupload-noscript.css\"></noscript>\n<noscript><link rel=\"stylesheet\" href=\"css/jquery.fileupload-ui-noscript.css\"></noscript>\n</head>\n<body>\n<ul class=\"navigation\">\n    <li><h3><a href=\"https://github.com/blueimp/jQuery-File-Upload\">jQuery File Upload</a></h3></li>\n    <li><a href=\"https://github.com/blueimp/jQuery-File-Upload/tags\">Download</a></li>\n    <li><a href=\"https://github.com/blueimp/jQuery-File-Upload\">Source Code</a></li>\n    <li><a href=\"https://github.com/blueimp/jQuery-File-Upload/wiki\">Documentation</a></li>\n    <li><a href=\"https://blueimp.net\">&copy; blueimp.net</a></li>\n</ul>\n<h1>jQuery File Upload Demo</h1>\n<h2>jQuery UI version</h2>\n<form>\n    <label for=\"theme-switcher\">Theme:</label>\n    <select id=\"theme-switcher\" class=\"pull-right\">\n        <option value=\"black-tie\">Black Tie</option>\n        <option value=\"blitzer\">Blitzer</option>\n        <option value=\"cupertino\">Cupertino</option>\n        <option value=\"dark-hive\" selected>Dark Hive</option>\n        <option value=\"dot-luv\">Dot Luv</option>\n        <option value=\"eggplant\">Eggplant</option>\n        <option value=\"excite-bike\">Excite Bike</option>\n        <option value=\"flick\">Flick</option>\n        <option value=\"hot-sneaks\">Hot sneaks</option>\n        <option value=\"humanity\">Humanity</option>\n        <option value=\"le-frog\">Le Frog</option>\n        <option value=\"mint-choc\">Mint Choc</option>\n        <option value=\"overcast\">Overcast</option>\n        <option value=\"pepper-grinder\">Pepper Grinder</option>\n        <option value=\"redmond\">Redmond</option>\n        <option value=\"smoothness\">Smoothness</option>\n        <option value=\"south-street\">South Street</option>\n        <option value=\"start\">Start</option>\n        <option value=\"sunny\">Sunny</option>\n        <option value=\"swanky-purse\">Swanky Purse</option>\n        <option value=\"trontastic\">Trontastic</option>\n        <option value=\"ui-darkness\">UI Darkness</option>\n        <option value=\"ui-lightness\">UI Lightness</option>\n        <option value=\"vader\">Vader</option>\n    </select>\n</form>\n<ul class=\"navigation\">\n    <li><a href=\"basic.html\">Basic</a></li>\n    <li><a href=\"basic-plus.html\">Basic Plus</a></li>\n    <li><a href=\"index.html\">Basic Plus UI</a></li>\n    <li><a href=\"angularjs.html\">AngularJS</a></li>\n    <li class=\"active\"><a href=\"jquery-ui.html\">jQuery UI</a></li>\n</ul>\n<blockquote>\n    <p>File Upload widget with multiple file selection, drag&amp;drop support, progress bars, validation and preview images, audio and video for jQuery UI.<br>\n    Supports cross-domain, chunked and resumable file uploads and client-side image resizing.<br>\n    Works with any server-side platform (PHP, Python, Ruby on Rails, Java, Node.js, Go etc.) that supports standard HTML form file uploads.</p>\n</blockquote>\n<!-- The file upload form used as target for the file upload widget -->\n<form id=\"fileupload\" action=\"//jquery-file-upload.appspot.com/\" method=\"POST\" enctype=\"multipart/form-data\">\n    <!-- Redirect browsers with JavaScript disabled to the origin page -->\n    <noscript><input type=\"hidden\" name=\"redirect\" value=\"https://blueimp.github.io/jQuery-File-Upload/\"></noscript>\n    <!-- The fileupload-buttonbar contains buttons to add/delete files and start/cancel the upload -->\n    <div class=\"fileupload-buttonbar\">\n        <div class=\"fileupload-buttons\">\n            <!-- The fileinput-button span is used to style the file input field as button -->\n            <span class=\"fileinput-button\">\n                <span>Add files...</span>\n                <input type=\"file\" name=\"files[]\" multiple>\n            </span>\n            <button type=\"submit\" class=\"start\">Start upload</button>\n            <button type=\"reset\" class=\"cancel\">Cancel upload</button>\n            <button type=\"button\" class=\"delete\">Delete</button>\n            <input type=\"checkbox\" class=\"toggle\">\n            <!-- The global file processing state -->\n            <span class=\"fileupload-process\"></span>\n        </div>\n        <!-- The global progress state -->\n        <div class=\"fileupload-progress fade\" style=\"display:none\">\n            <!-- The global progress bar -->\n            <div class=\"progress\" role=\"progressbar\" aria-valuemin=\"0\" aria-valuemax=\"100\"></div>\n            <!-- The extended global progress state -->\n            <div class=\"progress-extended\">&nbsp;</div>\n        </div>\n    </div>\n    <!-- The table listing the files available for upload/download -->\n    <table role=\"presentation\"><tbody class=\"files\"></tbody></table>\n</form>\n<br>\n<h3>Demo Notes</h3>\n<ul>\n    <li>The maximum file size for uploads in this demo is <strong>999 KB</strong> (default file size is unlimited).</li>\n    <li>Only image files (<strong>JPG, GIF, PNG</strong>) are allowed in this demo (by default there is no file type restriction).</li>\n    <li>Uploaded files will be deleted automatically after <strong>5 minutes or less</strong> (demo files are stored in memory).</li>\n    <li>You can <strong>drag &amp; drop</strong> files from your desktop on this webpage (see <a href=\"https://github.com/blueimp/jQuery-File-Upload/wiki/Browser-support\">Browser support</a>).</li>\n    <li>Please refer to the <a href=\"https://github.com/blueimp/jQuery-File-Upload\">project website</a> and <a href=\"https://github.com/blueimp/jQuery-File-Upload/wiki\">documentation</a> for more information.</li>\n    <li>Built with <a href=\"https://jqueryui.com\">jQuery UI</a>.</li>\n</ul>\n<!-- The blueimp Gallery widget -->\n<div id=\"blueimp-gallery\" class=\"blueimp-gallery blueimp-gallery-controls\" data-filter=\":even\">\n    <div class=\"slides\"></div>\n    <h3 class=\"title\"></h3>\n    <a class=\"prev\">‹</a>\n    <a class=\"next\">›</a>\n    <a class=\"close\">×</a>\n    <a class=\"play-pause\"></a>\n    <ol class=\"indicator\"></ol>\n</div>\n<!-- The template to display files available for upload -->\n<script id=\"template-upload\" type=\"text/x-tmpl\">\n{% for (var i=0, file; file=o.files[i]; i++) { %}\n    <tr class=\"template-upload fade\">\n        <td>\n            <span class=\"preview\"></span>\n        </td>\n        <td>\n            <p class=\"name\">{%=file.name%}</p>\n            <strong class=\"error\"></strong>\n        </td>\n        <td>\n            <p class=\"size\">Processing...</p>\n            <div class=\"progress\"></div>\n        </td>\n        <td>\n            {% if (!i && !o.options.autoUpload) { %}\n                <button class=\"start\" disabled>Start</button>\n            {% } %}\n            {% if (!i) { %}\n                <button class=\"cancel\">Cancel</button>\n            {% } %}\n        </td>\n    </tr>\n{% } %}\n</script>\n<!-- The template to display files available for download -->\n<script id=\"template-download\" type=\"text/x-tmpl\">\n{% for (var i=0, file; file=o.files[i]; i++) { %}\n    <tr class=\"template-download fade\">\n        <td>\n            <span class=\"preview\">\n                {% if (file.thumbnailUrl) { %}\n                    <a href=\"{%=file.url%}\" title=\"{%=file.name%}\" download=\"{%=file.name%}\" data-gallery><img src=\"{%=file.thumbnailUrl%}\"></a>\n                {% } %}\n            </span>\n        </td>\n        <td>\n            <p class=\"name\">\n                <a href=\"{%=file.url%}\" title=\"{%=file.name%}\" download=\"{%=file.name%}\" {%=file.thumbnailUrl?'data-gallery':''%}>{%=file.name%}</a>\n            </p>\n            {% if (file.error) { %}\n                <div><span class=\"error\">Error</span> {%=file.error%}</div>\n            {% } %}\n        </td>\n        <td>\n            <span class=\"size\">{%=o.formatFileSize(file.size)%}</span>\n        </td>\n        <td>\n            <button class=\"delete\" data-type=\"{%=file.deleteType%}\" data-url=\"{%=file.deleteUrl%}\"{% if (file.deleteWithCredentials) { %} data-xhr-fields='{\"withCredentials\":true}'{% } %}>Delete</button>\n            <input type=\"checkbox\" name=\"delete\" value=\"1\" class=\"toggle\">\n        </td>\n    </tr>\n{% } %}\n</script>\n<script src=\"//ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js\"></script>\n<script src=\"//ajax.googleapis.com/ajax/libs/jqueryui/1.11.4/jquery-ui.min.js\"></script>\n<!-- The Templates plugin is included to render the upload/download listings -->\n<script src=\"//blueimp.github.io/JavaScript-Templates/js/tmpl.min.js\"></script>\n<!-- The Load Image plugin is included for the preview images and image resizing functionality -->\n<script src=\"//blueimp.github.io/JavaScript-Load-Image/js/load-image.all.min.js\"></script>\n<!-- The Canvas to Blob plugin is included for image resizing functionality -->\n<script src=\"//blueimp.github.io/JavaScript-Canvas-to-Blob/js/canvas-to-blob.min.js\"></script>\n<!-- blueimp Gallery script -->\n<script src=\"//blueimp.github.io/Gallery/js/jquery.blueimp-gallery.min.js\"></script>\n<!-- The Iframe Transport is required for browsers without support for XHR file uploads -->\n<script src=\"js/jquery.iframe-transport.js\"></script>\n<!-- The basic File Upload plugin -->\n<script src=\"js/jquery.fileupload.js\"></script>\n<!-- The File Upload processing plugin -->\n<script src=\"js/jquery.fileupload-process.js\"></script>\n<!-- The File Upload image preview & resize plugin -->\n<script src=\"js/jquery.fileupload-image.js\"></script>\n<!-- The File Upload audio preview plugin -->\n<script src=\"js/jquery.fileupload-audio.js\"></script>\n<!-- The File Upload video preview plugin -->\n<script src=\"js/jquery.fileupload-video.js\"></script>\n<!-- The File Upload validation plugin -->\n<script src=\"js/jquery.fileupload-validate.js\"></script>\n<!-- The File Upload user interface plugin -->\n<script src=\"js/jquery.fileupload-ui.js\"></script>\n<!-- The File Upload jQuery UI plugin -->\n<script src=\"js/jquery.fileupload-jquery-ui.js\"></script>\n<!-- The main application script -->\n<script src=\"js/main.js\"></script>\n<script>\n// Initialize the jQuery UI theme switcher:\n$('#theme-switcher').change(function () {\n    var theme = $('#theme');\n    theme.prop(\n        'href',\n        theme.prop('href').replace(\n            /[\\w\\-]+\\/jquery-ui.css/,\n            $(this).val() + '/jquery-ui.css'\n        )\n    );\n});\n</script>\n<!-- The XDomainRequest Transport is included for cross-domain file deletion for IE 8 and IE 9 -->\n<!--[if (gte IE 8)&(lt IE 10)]>\n<script src=\"js/cors/jquery.xdr-transport.js\"></script>\n<![endif]-->\n</body>\n</html>\n"
  },
  {
    "path": "app_backend/static/plugin/jQuery-File-Upload-9.18.0/js/app.js",
    "content": "/*\n * jQuery File Upload Plugin Angular JS Example\n * https://github.com/blueimp/jQuery-File-Upload\n *\n * Copyright 2013, Sebastian Tschan\n * https://blueimp.net\n *\n * Licensed under the MIT license:\n * https://opensource.org/licenses/MIT\n */\n\n/* jshint nomen:false */\n/* global window, angular */\n\n;(function () {\n    'use strict';\n\n    var isOnGitHub = window.location.hostname === 'blueimp.github.io',\n        url = isOnGitHub ? '//jquery-file-upload.appspot.com/' : 'server/php/';\n\n    angular.module('demo', [\n        'blueimp.fileupload'\n    ])\n        .config([\n            '$httpProvider', 'fileUploadProvider',\n            function ($httpProvider, fileUploadProvider) {\n                delete $httpProvider.defaults.headers.common['X-Requested-With'];\n                fileUploadProvider.defaults.redirect = window.location.href.replace(\n                    /\\/[^\\/]*$/,\n                    '/cors/result.html?%s'\n                );\n                if (isOnGitHub) {\n                    // Demo settings:\n                    angular.extend(fileUploadProvider.defaults, {\n                        // Enable image resizing, except for Android and Opera,\n                        // which actually support image resizing, but fail to\n                        // send Blob objects via XHR requests:\n                        disableImageResize: /Android(?!.*Chrome)|Opera/\n                            .test(window.navigator.userAgent),\n                        maxFileSize: 999000,\n                        acceptFileTypes: /(\\.|\\/)(gif|jpe?g|png)$/i\n                    });\n                }\n            }\n        ])\n\n        .controller('DemoFileUploadController', [\n            '$scope', '$http', '$filter', '$window',\n            function ($scope, $http) {\n                $scope.options = {\n                    url: url\n                };\n                if (!isOnGitHub) {\n                    $scope.loadingFiles = true;\n                    $http.get(url)\n                        .then(\n                            function (response) {\n                                $scope.loadingFiles = false;\n                                $scope.queue = response.data.files || [];\n                            },\n                            function () {\n                                $scope.loadingFiles = false;\n                            }\n                        );\n                }\n            }\n        ])\n\n        .controller('FileDestroyController', [\n            '$scope', '$http',\n            function ($scope, $http) {\n                var file = $scope.file,\n                    state;\n                if (file.url) {\n                    file.$state = function () {\n                        return state;\n                    };\n                    file.$destroy = function () {\n                        state = 'pending';\n                        return $http({\n                            url: file.deleteUrl,\n                            method: file.deleteType\n                        }).then(\n                            function () {\n                                state = 'resolved';\n                                $scope.clear(file);\n                            },\n                            function () {\n                                state = 'rejected';\n                            }\n                        );\n                    };\n                } else if (!file.$cancel && !file._index) {\n                    file.$cancel = function () {\n                        $scope.clear(file);\n                    };\n                }\n            }\n        ]);\n\n}());\n"
  },
  {
    "path": "app_backend/static/plugin/jQuery-File-Upload-9.18.0/js/cors/jquery.postmessage-transport.js",
    "content": "/*\n * jQuery postMessage Transport Plugin\n * https://github.com/blueimp/jQuery-File-Upload\n *\n * Copyright 2011, Sebastian Tschan\n * https://blueimp.net\n *\n * Licensed under the MIT license:\n * https://opensource.org/licenses/MIT\n */\n\n/* global define, require, window, document */\n\n;(function (factory) {\n    'use strict';\n    if (typeof define === 'function' && define.amd) {\n        // Register as an anonymous AMD module:\n        define(['jquery'], factory);\n    } else if (typeof exports === 'object') {\n        // Node/CommonJS:\n        factory(require('jquery'));\n    } else {\n        // Browser globals:\n        factory(window.jQuery);\n    }\n}(function ($) {\n    'use strict';\n\n    var counter = 0,\n        names = [\n            'accepts',\n            'cache',\n            'contents',\n            'contentType',\n            'crossDomain',\n            'data',\n            'dataType',\n            'headers',\n            'ifModified',\n            'mimeType',\n            'password',\n            'processData',\n            'timeout',\n            'traditional',\n            'type',\n            'url',\n            'username'\n        ],\n        convert = function (p) {\n            return p;\n        };\n\n    $.ajaxSetup({\n        converters: {\n            'postmessage text': convert,\n            'postmessage json': convert,\n            'postmessage html': convert\n        }\n    });\n\n    $.ajaxTransport('postmessage', function (options) {\n        if (options.postMessage && window.postMessage) {\n            var iframe,\n                loc = $('<a>').prop('href', options.postMessage)[0],\n                target = loc.protocol + '//' + loc.host,\n                xhrUpload = options.xhr().upload;\n            // IE always includes the port for the host property of a link\n            // element, but not in the location.host or origin property for the\n            // default http port 80 and https port 443, so we strip it:\n            if (/^(http:\\/\\/.+:80)|(https:\\/\\/.+:443)$/.test(target)) {\n              target = target.replace(/:(80|443)$/, '');\n            }\n            return {\n                send: function (_, completeCallback) {\n                    counter += 1;\n                    var message = {\n                            id: 'postmessage-transport-' + counter\n                        },\n                        eventName = 'message.' + message.id;\n                    iframe = $(\n                        '<iframe style=\"display:none;\" src=\"' +\n                            options.postMessage + '\" name=\"' +\n                            message.id + '\"></iframe>'\n                    ).bind('load', function () {\n                        $.each(names, function (i, name) {\n                            message[name] = options[name];\n                        });\n                        message.dataType = message.dataType.replace('postmessage ', '');\n                        $(window).bind(eventName, function (e) {\n                            e = e.originalEvent;\n                            var data = e.data,\n                                ev;\n                            if (e.origin === target && data.id === message.id) {\n                                if (data.type === 'progress') {\n                                    ev = document.createEvent('Event');\n                                    ev.initEvent(data.type, false, true);\n                                    $.extend(ev, data);\n                                    xhrUpload.dispatchEvent(ev);\n                                } else {\n                                    completeCallback(\n                                        data.status,\n                                        data.statusText,\n                                        {postmessage: data.result},\n                                        data.headers\n                                    );\n                                    iframe.remove();\n                                    $(window).unbind(eventName);\n                                }\n                            }\n                        });\n                        iframe[0].contentWindow.postMessage(\n                            message,\n                            target\n                        );\n                    }).appendTo(document.body);\n                },\n                abort: function () {\n                    if (iframe) {\n                        iframe.remove();\n                    }\n                }\n            };\n        }\n    });\n\n}));\n"
  },
  {
    "path": "app_backend/static/plugin/jQuery-File-Upload-9.18.0/js/cors/jquery.xdr-transport.js",
    "content": "/*\n * jQuery XDomainRequest Transport Plugin\n * https://github.com/blueimp/jQuery-File-Upload\n *\n * Copyright 2011, Sebastian Tschan\n * https://blueimp.net\n *\n * Licensed under the MIT license:\n * https://opensource.org/licenses/MIT\n *\n * Based on Julian Aubourg's ajaxHooks xdr.js:\n * https://github.com/jaubourg/ajaxHooks/\n */\n\n/* global define, require, window, XDomainRequest */\n\n;(function (factory) {\n    'use strict';\n    if (typeof define === 'function' && define.amd) {\n        // Register as an anonymous AMD module:\n        define(['jquery'], factory);\n    } else if (typeof exports === 'object') {\n        // Node/CommonJS:\n        factory(require('jquery'));\n    } else {\n        // Browser globals:\n        factory(window.jQuery);\n    }\n}(function ($) {\n    'use strict';\n    if (window.XDomainRequest && !$.support.cors) {\n        $.ajaxTransport(function (s) {\n            if (s.crossDomain && s.async) {\n                if (s.timeout) {\n                    s.xdrTimeout = s.timeout;\n                    delete s.timeout;\n                }\n                var xdr;\n                return {\n                    send: function (headers, completeCallback) {\n                        var addParamChar = /\\?/.test(s.url) ? '&' : '?';\n                        function callback(status, statusText, responses, responseHeaders) {\n                            xdr.onload = xdr.onerror = xdr.ontimeout = $.noop;\n                            xdr = null;\n                            completeCallback(status, statusText, responses, responseHeaders);\n                        }\n                        xdr = new XDomainRequest();\n                        // XDomainRequest only supports GET and POST:\n                        if (s.type === 'DELETE') {\n                            s.url = s.url + addParamChar + '_method=DELETE';\n                            s.type = 'POST';\n                        } else if (s.type === 'PUT') {\n                            s.url = s.url + addParamChar + '_method=PUT';\n                            s.type = 'POST';\n                        } else if (s.type === 'PATCH') {\n                            s.url = s.url + addParamChar + '_method=PATCH';\n                            s.type = 'POST';\n                        }\n                        xdr.open(s.type, s.url);\n                        xdr.onload = function () {\n                            callback(\n                                200,\n                                'OK',\n                                {text: xdr.responseText},\n                                'Content-Type: ' + xdr.contentType\n                            );\n                        };\n                        xdr.onerror = function () {\n                            callback(404, 'Not Found');\n                        };\n                        if (s.xdrTimeout) {\n                            xdr.ontimeout = function () {\n                                callback(0, 'timeout');\n                            };\n                            xdr.timeout = s.xdrTimeout;\n                        }\n                        xdr.send((s.hasContent && s.data) || null);\n                    },\n                    abort: function () {\n                        if (xdr) {\n                            xdr.onerror = $.noop();\n                            xdr.abort();\n                        }\n                    }\n                };\n            }\n        });\n    }\n}));\n"
  },
  {
    "path": "app_backend/static/plugin/jQuery-File-Upload-9.18.0/js/jquery.fileupload-angular.js",
    "content": "/*\n * jQuery File Upload AngularJS Plugin\n * https://github.com/blueimp/jQuery-File-Upload\n *\n * Copyright 2013, Sebastian Tschan\n * https://blueimp.net\n *\n * Licensed under the MIT license:\n * https://opensource.org/licenses/MIT\n */\n\n/* jshint nomen:false */\n/* global define, angular, require */\n\n;(function (factory) {\n    'use strict';\n    if (typeof define === 'function' && define.amd) {\n        // Register as an anonymous AMD module:\n        define([\n            'jquery',\n            'angular',\n            './jquery.fileupload-image',\n            './jquery.fileupload-audio',\n            './jquery.fileupload-video',\n            './jquery.fileupload-validate'\n        ], factory);\n    } else if (typeof exports === 'object') {\n        // Node/CommonJS:\n        factory(\n            require('jquery'),\n            require('angular'),\n            require('./jquery.fileupload-image'),\n            require('./jquery.fileupload-audio'),\n            require('./jquery.fileupload-video'),\n            require('./jquery.fileupload-validate')\n        );\n    } else {\n        factory();\n    }\n}(function () {\n    'use strict';\n\n    angular.module('blueimp.fileupload', [])\n\n        // The fileUpload service provides configuration options\n        // for the fileUpload directive and default handlers for\n        // File Upload events:\n        .provider('fileUpload', function () {\n            var scopeEvalAsync = function (expression) {\n                    var scope = angular.element(this)\n                            .fileupload('option', 'scope');\n                    // Schedule a new $digest cycle if not already inside of one\n                    // and evaluate the given expression:\n                    scope.$evalAsync(expression);\n                },\n                addFileMethods = function (scope, data) {\n                    var files = data.files,\n                        file = files[0];\n                    angular.forEach(files, function (file, index) {\n                        file._index = index;\n                        file.$state = function () {\n                            return data.state();\n                        };\n                        file.$processing = function () {\n                            return data.processing();\n                        };\n                        file.$progress = function () {\n                            return data.progress();\n                        };\n                        file.$response = function () {\n                            return data.response();\n                        };\n                    });\n                    file.$submit = function () {\n                        if (!file.error) {\n                            return data.submit();\n                        }\n                    };\n                    file.$cancel = function () {\n                        return data.abort();\n                    };\n                },\n                $config;\n            $config = this.defaults = {\n                handleResponse: function (e, data) {\n                    var files = data.result && data.result.files;\n                    if (files) {\n                        data.scope.replace(data.files, files);\n                    } else if (data.errorThrown ||\n                            data.textStatus === 'error') {\n                        data.files[0].error = data.errorThrown ||\n                            data.textStatus;\n                    }\n                },\n                add: function (e, data) {\n                    if (e.isDefaultPrevented()) {\n                        return false;\n                    }\n                    var scope = data.scope,\n                        filesCopy = [];\n                    angular.forEach(data.files, function (file) {\n                        filesCopy.push(file);\n                    });\n                    scope.$parent.$applyAsync(function () {\n                        addFileMethods(scope, data);\n                        var method = scope.option('prependFiles') ?\n                                'unshift' : 'push';\n                        Array.prototype[method].apply(scope.queue, data.files);\n                    });\n                    data.process(function () {\n                        return scope.process(data);\n                    }).always(function () {\n                        scope.$parent.$applyAsync(function () {\n                            addFileMethods(scope, data);\n                            scope.replace(filesCopy, data.files);\n                        });\n                    }).then(function () {\n                        if ((scope.option('autoUpload') ||\n                                data.autoUpload) &&\n                                data.autoUpload !== false) {\n                            data.submit();\n                        }\n                    });\n                },\n                done: function (e, data) {\n                    if (e.isDefaultPrevented()) {\n                        return false;\n                    }\n                    var that = this;\n                    data.scope.$apply(function () {\n                        data.handleResponse.call(that, e, data);\n                    });\n                },\n                fail: function (e, data) {\n                    if (e.isDefaultPrevented()) {\n                        return false;\n                    }\n                    var that = this,\n                        scope = data.scope;\n                    if (data.errorThrown === 'abort') {\n                        scope.clear(data.files);\n                        return;\n                    }\n                    scope.$apply(function () {\n                        data.handleResponse.call(that, e, data);\n                    });\n                },\n                stop: scopeEvalAsync,\n                processstart: scopeEvalAsync,\n                processstop: scopeEvalAsync,\n                getNumberOfFiles: function () {\n                    var scope = this.scope;\n                    return scope.queue.length - scope.processing();\n                },\n                dataType: 'json',\n                autoUpload: false\n            };\n            this.$get = [\n                function () {\n                    return {\n                        defaults: $config\n                    };\n                }\n            ];\n        })\n\n        // Format byte numbers to readable presentations:\n        .provider('formatFileSizeFilter', function () {\n            var $config = {\n                // Byte units following the IEC format\n                // http://en.wikipedia.org/wiki/Kilobyte\n                units: [\n                    {size: 1000000000, suffix: ' GB'},\n                    {size: 1000000, suffix: ' MB'},\n                    {size: 1000, suffix: ' KB'}\n                ]\n            };\n            this.defaults = $config;\n            this.$get = function () {\n                return function (bytes) {\n                    if (!angular.isNumber(bytes)) {\n                        return '';\n                    }\n                    var unit = true,\n                        i = 0,\n                        prefix,\n                        suffix;\n                    while (unit) {\n                        unit = $config.units[i];\n                        prefix = unit.prefix || '';\n                        suffix = unit.suffix || '';\n                        if (i === $config.units.length - 1 || bytes >= unit.size) {\n                            return prefix + (bytes / unit.size).toFixed(2) + suffix;\n                        }\n                        i += 1;\n                    }\n                };\n            };\n        })\n\n        // The FileUploadController initializes the fileupload widget and\n        // provides scope methods to control the File Upload functionality:\n        .controller('FileUploadController', [\n            '$scope', '$element', '$attrs', '$window', 'fileUpload','$q',\n            function ($scope, $element, $attrs, $window, fileUpload, $q) {\n                var uploadMethods = {\n                    progress: function () {\n                        return $element.fileupload('progress');\n                    },\n                    active: function () {\n                        return $element.fileupload('active');\n                    },\n                    option: function (option, data) {\n                        if (arguments.length === 1) {\n                            return $element.fileupload('option', option);\n                        }\n                        $element.fileupload('option', option, data);\n                    },\n                    add: function (data) {\n                        return $element.fileupload('add', data);\n                    },\n                    send: function (data) {\n                        return $element.fileupload('send', data);\n                    },\n                    process: function (data) {\n                        return $element.fileupload('process', data);\n                    },\n                    processing: function (data) {\n                        return $element.fileupload('processing', data);\n                    }\n                };\n                $scope.disabled = !$window.jQuery.support.fileInput;\n                $scope.queue = $scope.queue || [];\n                $scope.clear = function (files) {\n                    var queue = this.queue,\n                        i = queue.length,\n                        file = files,\n                        length = 1;\n                    if (angular.isArray(files)) {\n                        file = files[0];\n                        length = files.length;\n                    }\n                    while (i) {\n                        i -= 1;\n                        if (queue[i] === file) {\n                            return queue.splice(i, length);\n                        }\n                    }\n                };\n                $scope.replace = function (oldFiles, newFiles) {\n                    var queue = this.queue,\n                        file = oldFiles[0],\n                        i,\n                        j;\n                    for (i = 0; i < queue.length; i += 1) {\n                        if (queue[i] === file) {\n                            for (j = 0; j < newFiles.length; j += 1) {\n                                queue[i + j] = newFiles[j];\n                            }\n                            return;\n                        }\n                    }\n                };\n                $scope.applyOnQueue = function (method) {\n                    var list = this.queue.slice(0),\n                        i,\n                        file,\n                        promises = [];\n                    for (i = 0; i < list.length; i += 1) {\n                        file = list[i];\n                        if (file[method]) {\n                            promises.push(file[method]());\n                        }\n                    }\n                    return $q.all(promises);\n                };\n                $scope.submit = function () {\n                    return this.applyOnQueue('$submit');\n                };\n                $scope.cancel = function () {\n                    return this.applyOnQueue('$cancel');\n                };\n                // Add upload methods to the scope:\n                angular.extend($scope, uploadMethods);\n                // The fileupload widget will initialize with\n                // the options provided via \"data-\"-parameters,\n                // as well as those given via options object:\n                $element.fileupload(angular.extend(\n                    {scope: $scope},\n                    fileUpload.defaults\n                )).on('fileuploadadd', function (e, data) {\n                    data.scope = $scope;\n                }).on('fileuploadfail', function (e, data) {\n                    if (data.errorThrown === 'abort') {\n                        return;\n                    }\n                    if (data.dataType &&\n                            data.dataType.indexOf('json') === data.dataType.length - 4) {\n                        try {\n                            data.result = angular.fromJson(data.jqXHR.responseText);\n                        } catch (ignore) {}\n                    }\n                }).on([\n                    'fileuploadadd',\n                    'fileuploadsubmit',\n                    'fileuploadsend',\n                    'fileuploaddone',\n                    'fileuploadfail',\n                    'fileuploadalways',\n                    'fileuploadprogress',\n                    'fileuploadprogressall',\n                    'fileuploadstart',\n                    'fileuploadstop',\n                    'fileuploadchange',\n                    'fileuploadpaste',\n                    'fileuploaddrop',\n                    'fileuploaddragover',\n                    'fileuploadchunksend',\n                    'fileuploadchunkdone',\n                    'fileuploadchunkfail',\n                    'fileuploadchunkalways',\n                    'fileuploadprocessstart',\n                    'fileuploadprocess',\n                    'fileuploadprocessdone',\n                    'fileuploadprocessfail',\n                    'fileuploadprocessalways',\n                    'fileuploadprocessstop'\n                ].join(' '), function (e, data) {\n                    $scope.$parent.$applyAsync(function () {\n                        if ($scope.$emit(e.type, data).defaultPrevented) {\n                            e.preventDefault();\n                        }\n                    });\n                }).on('remove', function () {\n                    // Remove upload methods from the scope,\n                    // when the widget is removed:\n                    var method;\n                    for (method in uploadMethods) {\n                        if (uploadMethods.hasOwnProperty(method)) {\n                            delete $scope[method];\n                        }\n                    }\n                });\n                // Observe option changes:\n                $scope.$watch(\n                    $attrs.fileUpload,\n                    function (newOptions) {\n                        if (newOptions) {\n                            $element.fileupload('option', newOptions);\n                        }\n                    }\n                );\n            }\n        ])\n\n        // Provide File Upload progress feedback:\n        .controller('FileUploadProgressController', [\n            '$scope', '$attrs', '$parse',\n            function ($scope, $attrs, $parse) {\n                var fn = $parse($attrs.fileUploadProgress),\n                    update = function () {\n                        var progress = fn($scope);\n                        if (!progress || !progress.total) {\n                            return;\n                        }\n                        $scope.num = Math.floor(\n                            progress.loaded / progress.total * 100\n                        );\n                    };\n                update();\n                $scope.$watch(\n                    $attrs.fileUploadProgress + '.loaded',\n                    function (newValue, oldValue) {\n                        if (newValue !== oldValue) {\n                            update();\n                        }\n                    }\n                );\n            }\n        ])\n\n        // Display File Upload previews:\n        .controller('FileUploadPreviewController', [\n            '$scope', '$element', '$attrs',\n            function ($scope, $element, $attrs) {\n                $scope.$watch(\n                    $attrs.fileUploadPreview + '.preview',\n                    function (preview) {\n                        $element.empty();\n                        if (preview) {\n                            $element.append(preview);\n                        }\n                    }\n                );\n            }\n        ])\n\n        .directive('fileUpload', function () {\n            return {\n                controller: 'FileUploadController',\n                scope: true\n            };\n        })\n\n        .directive('fileUploadProgress', function () {\n            return {\n                controller: 'FileUploadProgressController',\n                scope: true\n            };\n        })\n\n        .directive('fileUploadPreview', function () {\n            return {\n                controller: 'FileUploadPreviewController'\n            };\n        })\n\n        // Enhance the HTML5 download attribute to\n        // allow drag&drop of files to the desktop:\n        .directive('download', function () {\n            return function (scope, elm) {\n                elm.on('dragstart', function (e) {\n                    try {\n                        e.originalEvent.dataTransfer.setData(\n                            'DownloadURL',\n                            [\n                                'application/octet-stream',\n                                elm.prop('download'),\n                                elm.prop('href')\n                            ].join(':')\n                        );\n                    } catch (ignore) {}\n                });\n            };\n        });\n\n}));\n"
  },
  {
    "path": "app_backend/static/plugin/jQuery-File-Upload-9.18.0/js/jquery.fileupload-audio.js",
    "content": "/*\n * jQuery File Upload Audio Preview Plugin\n * https://github.com/blueimp/jQuery-File-Upload\n *\n * Copyright 2013, Sebastian Tschan\n * https://blueimp.net\n *\n * Licensed under the MIT license:\n * https://opensource.org/licenses/MIT\n */\n\n/* jshint nomen:false */\n/* global define, require, window, document */\n\n;(function (factory) {\n    'use strict';\n    if (typeof define === 'function' && define.amd) {\n        // Register as an anonymous AMD module:\n        define([\n            'jquery',\n            'load-image',\n            './jquery.fileupload-process'\n        ], factory);\n    } else if (typeof exports === 'object') {\n        // Node/CommonJS:\n        factory(\n            require('jquery'),\n            require('blueimp-load-image/js/load-image'),\n            require('./jquery.fileupload-process')\n        );\n    } else {\n        // Browser globals:\n        factory(\n            window.jQuery,\n            window.loadImage\n        );\n    }\n}(function ($, loadImage) {\n    'use strict';\n\n    // Prepend to the default processQueue:\n    $.blueimp.fileupload.prototype.options.processQueue.unshift(\n        {\n            action: 'loadAudio',\n            // Use the action as prefix for the \"@\" options:\n            prefix: true,\n            fileTypes: '@',\n            maxFileSize: '@',\n            disabled: '@disableAudioPreview'\n        },\n        {\n            action: 'setAudio',\n            name: '@audioPreviewName',\n            disabled: '@disableAudioPreview'\n        }\n    );\n\n    // The File Upload Audio Preview plugin extends the fileupload widget\n    // with audio preview functionality:\n    $.widget('blueimp.fileupload', $.blueimp.fileupload, {\n\n        options: {\n            // The regular expression for the types of audio files to load,\n            // matched against the file type:\n            loadAudioFileTypes: /^audio\\/.*$/\n        },\n\n        _audioElement: document.createElement('audio'),\n\n        processActions: {\n\n            // Loads the audio file given via data.files and data.index\n            // as audio element if the browser supports playing it.\n            // Accepts the options fileTypes (regular expression)\n            // and maxFileSize (integer) to limit the files to load:\n            loadAudio: function (data, options) {\n                if (options.disabled) {\n                    return data;\n                }\n                var file = data.files[data.index],\n                    url,\n                    audio;\n                if (this._audioElement.canPlayType &&\n                        this._audioElement.canPlayType(file.type) &&\n                        ($.type(options.maxFileSize) !== 'number' ||\n                            file.size <= options.maxFileSize) &&\n                        (!options.fileTypes ||\n                            options.fileTypes.test(file.type))) {\n                    url = loadImage.createObjectURL(file);\n                    if (url) {\n                        audio = this._audioElement.cloneNode(false);\n                        audio.src = url;\n                        audio.controls = true;\n                        data.audio = audio;\n                        return data;\n                    }\n                }\n                return data;\n            },\n\n            // Sets the audio element as a property of the file object:\n            setAudio: function (data, options) {\n                if (data.audio && !options.disabled) {\n                    data.files[data.index][options.name || 'preview'] = data.audio;\n                }\n                return data;\n            }\n\n        }\n\n    });\n\n}));\n"
  },
  {
    "path": "app_backend/static/plugin/jQuery-File-Upload-9.18.0/js/jquery.fileupload-image.js",
    "content": "/*\n * jQuery File Upload Image Preview & Resize Plugin\n * https://github.com/blueimp/jQuery-File-Upload\n *\n * Copyright 2013, Sebastian Tschan\n * https://blueimp.net\n *\n * Licensed under the MIT license:\n * https://opensource.org/licenses/MIT\n */\n\n/* jshint nomen:false */\n/* global define, require, window, Blob */\n\n;(function (factory) {\n    'use strict';\n    if (typeof define === 'function' && define.amd) {\n        // Register as an anonymous AMD module:\n        define([\n            'jquery',\n            'load-image',\n            'load-image-meta',\n            'load-image-scale',\n            'load-image-exif',\n            'canvas-to-blob',\n            './jquery.fileupload-process'\n        ], factory);\n    } else if (typeof exports === 'object') {\n        // Node/CommonJS:\n        factory(\n            require('jquery'),\n            require('blueimp-load-image/js/load-image'),\n            require('blueimp-load-image/js/load-image-meta'),\n            require('blueimp-load-image/js/load-image-scale'),\n            require('blueimp-load-image/js/load-image-exif'),\n            require('blueimp-canvas-to-blob'),\n            require('./jquery.fileupload-process')\n        );\n    } else {\n        // Browser globals:\n        factory(\n            window.jQuery,\n            window.loadImage\n        );\n    }\n}(function ($, loadImage) {\n    'use strict';\n\n    // Prepend to the default processQueue:\n    $.blueimp.fileupload.prototype.options.processQueue.unshift(\n        {\n            action: 'loadImageMetaData',\n            disableImageHead: '@',\n            disableExif: '@',\n            disableExifThumbnail: '@',\n            disableExifSub: '@',\n            disableExifGps: '@',\n            disabled: '@disableImageMetaDataLoad'\n        },\n        {\n            action: 'loadImage',\n            // Use the action as prefix for the \"@\" options:\n            prefix: true,\n            fileTypes: '@',\n            maxFileSize: '@',\n            noRevoke: '@',\n            disabled: '@disableImageLoad'\n        },\n        {\n            action: 'resizeImage',\n            // Use \"image\" as prefix for the \"@\" options:\n            prefix: 'image',\n            maxWidth: '@',\n            maxHeight: '@',\n            minWidth: '@',\n            minHeight: '@',\n            crop: '@',\n            orientation: '@',\n            forceResize: '@',\n            disabled: '@disableImageResize'\n        },\n        {\n            action: 'saveImage',\n            quality: '@imageQuality',\n            type: '@imageType',\n            disabled: '@disableImageResize'\n        },\n        {\n            action: 'saveImageMetaData',\n            disabled: '@disableImageMetaDataSave'\n        },\n        {\n            action: 'resizeImage',\n            // Use \"preview\" as prefix for the \"@\" options:\n            prefix: 'preview',\n            maxWidth: '@',\n            maxHeight: '@',\n            minWidth: '@',\n            minHeight: '@',\n            crop: '@',\n            orientation: '@',\n            thumbnail: '@',\n            canvas: '@',\n            disabled: '@disableImagePreview'\n        },\n        {\n            action: 'setImage',\n            name: '@imagePreviewName',\n            disabled: '@disableImagePreview'\n        },\n        {\n            action: 'deleteImageReferences',\n            disabled: '@disableImageReferencesDeletion'\n        }\n    );\n\n    // The File Upload Resize plugin extends the fileupload widget\n    // with image resize functionality:\n    $.widget('blueimp.fileupload', $.blueimp.fileupload, {\n\n        options: {\n            // The regular expression for the types of images to load:\n            // matched against the file type:\n            loadImageFileTypes: /^image\\/(gif|jpeg|png|svg\\+xml)$/,\n            // The maximum file size of images to load:\n            loadImageMaxFileSize: 10000000, // 10MB\n            // The maximum width of resized images:\n            imageMaxWidth: 1920,\n            // The maximum height of resized images:\n            imageMaxHeight: 1080,\n            // Defines the image orientation (1-8) or takes the orientation\n            // value from Exif data if set to true:\n            imageOrientation: false,\n            // Define if resized images should be cropped or only scaled:\n            imageCrop: false,\n            // Disable the resize image functionality by default:\n            disableImageResize: true,\n            // The maximum width of the preview images:\n            previewMaxWidth: 80,\n            // The maximum height of the preview images:\n            previewMaxHeight: 80,\n            // Defines the preview orientation (1-8) or takes the orientation\n            // value from Exif data if set to true:\n            previewOrientation: true,\n            // Create the preview using the Exif data thumbnail:\n            previewThumbnail: true,\n            // Define if preview images should be cropped or only scaled:\n            previewCrop: false,\n            // Define if preview images should be resized as canvas elements:\n            previewCanvas: true\n        },\n\n        processActions: {\n\n            // Loads the image given via data.files and data.index\n            // as img element, if the browser supports the File API.\n            // Accepts the options fileTypes (regular expression)\n            // and maxFileSize (integer) to limit the files to load:\n            loadImage: function (data, options) {\n                if (options.disabled) {\n                    return data;\n                }\n                var that = this,\n                    file = data.files[data.index],\n                    dfd = $.Deferred();\n                if (($.type(options.maxFileSize) === 'number' &&\n                            file.size > options.maxFileSize) ||\n                        (options.fileTypes &&\n                            !options.fileTypes.test(file.type)) ||\n                        !loadImage(\n                            file,\n                            function (img) {\n                                if (img.src) {\n                                    data.img = img;\n                                }\n                                dfd.resolveWith(that, [data]);\n                            },\n                            options\n                        )) {\n                    return data;\n                }\n                return dfd.promise();\n            },\n\n            // Resizes the image given as data.canvas or data.img\n            // and updates data.canvas or data.img with the resized image.\n            // Also stores the resized image as preview property.\n            // Accepts the options maxWidth, maxHeight, minWidth,\n            // minHeight, canvas and crop:\n            resizeImage: function (data, options) {\n                if (options.disabled || !(data.canvas || data.img)) {\n                    return data;\n                }\n                options = $.extend({canvas: true}, options);\n                var that = this,\n                    dfd = $.Deferred(),\n                    img = (options.canvas && data.canvas) || data.img,\n                    resolve = function (newImg) {\n                        if (newImg && (newImg.width !== img.width ||\n                                newImg.height !== img.height ||\n                                options.forceResize)) {\n                            data[newImg.getContext ? 'canvas' : 'img'] = newImg;\n                        }\n                        data.preview = newImg;\n                        dfd.resolveWith(that, [data]);\n                    },\n                    thumbnail;\n                if (data.exif) {\n                    if (options.orientation === true) {\n                        options.orientation = data.exif.get('Orientation');\n                    }\n                    if (options.thumbnail) {\n                        thumbnail = data.exif.get('Thumbnail');\n                        if (thumbnail) {\n                            loadImage(thumbnail, resolve, options);\n                            return dfd.promise();\n                        }\n                    }\n                    // Prevent orienting the same image twice:\n                    if (data.orientation) {\n                        delete options.orientation;\n                    } else {\n                        data.orientation = options.orientation;\n                    }\n                }\n                if (img) {\n                    resolve(loadImage.scale(img, options));\n                    return dfd.promise();\n                }\n                return data;\n            },\n\n            // Saves the processed image given as data.canvas\n            // inplace at data.index of data.files:\n            saveImage: function (data, options) {\n                if (!data.canvas || options.disabled) {\n                    return data;\n                }\n                var that = this,\n                    file = data.files[data.index],\n                    dfd = $.Deferred();\n                if (data.canvas.toBlob) {\n                    data.canvas.toBlob(\n                        function (blob) {\n                            if (!blob.name) {\n                                if (file.type === blob.type) {\n                                    blob.name = file.name;\n                                } else if (file.name) {\n                                    blob.name = file.name.replace(\n                                        /\\.\\w+$/,\n                                        '.' + blob.type.substr(6)\n                                    );\n                                }\n                            }\n                            // Don't restore invalid meta data:\n                            if (file.type !== blob.type) {\n                                delete data.imageHead;\n                            }\n                            // Store the created blob at the position\n                            // of the original file in the files list:\n                            data.files[data.index] = blob;\n                            dfd.resolveWith(that, [data]);\n                        },\n                        options.type || file.type,\n                        options.quality\n                    );\n                } else {\n                    return data;\n                }\n                return dfd.promise();\n            },\n\n            loadImageMetaData: function (data, options) {\n                if (options.disabled) {\n                    return data;\n                }\n                var that = this,\n                    dfd = $.Deferred();\n                loadImage.parseMetaData(data.files[data.index], function (result) {\n                    $.extend(data, result);\n                    dfd.resolveWith(that, [data]);\n                }, options);\n                return dfd.promise();\n            },\n\n            saveImageMetaData: function (data, options) {\n                if (!(data.imageHead && data.canvas &&\n                        data.canvas.toBlob && !options.disabled)) {\n                    return data;\n                }\n                var file = data.files[data.index],\n                    blob = new Blob([\n                        data.imageHead,\n                        // Resized images always have a head size of 20 bytes,\n                        // including the JPEG marker and a minimal JFIF header:\n                        this._blobSlice.call(file, 20)\n                    ], {type: file.type});\n                blob.name = file.name;\n                data.files[data.index] = blob;\n                return data;\n            },\n\n            // Sets the resized version of the image as a property of the\n            // file object, must be called after \"saveImage\":\n            setImage: function (data, options) {\n                if (data.preview && !options.disabled) {\n                    data.files[data.index][options.name || 'preview'] = data.preview;\n                }\n                return data;\n            },\n\n            deleteImageReferences: function (data, options) {\n                if (!options.disabled) {\n                    delete data.img;\n                    delete data.canvas;\n                    delete data.preview;\n                    delete data.imageHead;\n                }\n                return data;\n            }\n\n        }\n\n    });\n\n}));\n"
  },
  {
    "path": "app_backend/static/plugin/jQuery-File-Upload-9.18.0/js/jquery.fileupload-jquery-ui.js",
    "content": "/*\n * jQuery File Upload jQuery UI Plugin\n * https://github.com/blueimp/jQuery-File-Upload\n *\n * Copyright 2013, Sebastian Tschan\n * https://blueimp.net\n *\n * Licensed under the MIT license:\n * https://opensource.org/licenses/MIT\n */\n\n/* jshint nomen:false */\n/* global define, require, window */\n\n;(function (factory) {\n    'use strict';\n    if (typeof define === 'function' && define.amd) {\n        // Register as an anonymous AMD module:\n        define([\n            'jquery',\n            './jquery.fileupload-ui'\n        ], factory);\n    } else if (typeof exports === 'object') {\n        // Node/CommonJS:\n        factory(\n            require('jquery'),\n            require('./jquery.fileupload-ui')\n        );\n    } else {\n        // Browser globals:\n        factory(window.jQuery);\n    }\n}(function ($) {\n    'use strict';\n\n    $.widget('blueimp.fileupload', $.blueimp.fileupload, {\n\n        options: {\n            processdone: function (e, data) {\n                data.context.find('.start').button('enable');\n            },\n            progress: function (e, data) {\n                if (data.context) {\n                    data.context.find('.progress').progressbar(\n                        'option',\n                        'value',\n                        parseInt(data.loaded / data.total * 100, 10)\n                    );\n                }\n            },\n            progressall: function (e, data) {\n                var $this = $(this);\n                $this.find('.fileupload-progress')\n                    .find('.progress').progressbar(\n                        'option',\n                        'value',\n                        parseInt(data.loaded / data.total * 100, 10)\n                    ).end()\n                    .find('.progress-extended').each(function () {\n                        $(this).html(\n                            ($this.data('blueimp-fileupload') ||\n                                    $this.data('fileupload'))\n                                ._renderExtendedProgress(data)\n                        );\n                    });\n            }\n        },\n\n        _renderUpload: function (func, files) {\n            var node = this._super(func, files),\n                showIconText = $(window).width() > 480;\n            node.find('.progress').empty().progressbar();\n            node.find('.start').button({\n                icons: {primary: 'ui-icon-circle-arrow-e'},\n                text: showIconText\n            });\n            node.find('.cancel').button({\n                icons: {primary: 'ui-icon-cancel'},\n                text: showIconText\n            });\n            if (node.hasClass('fade')) {\n                node.hide();\n            }\n            return node;\n        },\n\n        _renderDownload: function (func, files) {\n            var node = this._super(func, files),\n                showIconText = $(window).width() > 480;\n            node.find('.delete').button({\n                icons: {primary: 'ui-icon-trash'},\n                text: showIconText\n            });\n            if (node.hasClass('fade')) {\n                node.hide();\n            }\n            return node;\n        },\n\n        _startHandler: function (e) {\n            $(e.currentTarget).button('disable');\n            this._super(e);\n        },\n\n        _transition: function (node) {\n            var deferred = $.Deferred();\n            if (node.hasClass('fade')) {\n                node.fadeToggle(\n                    this.options.transitionDuration,\n                    this.options.transitionEasing,\n                    function () {\n                        deferred.resolveWith(node);\n                    }\n                );\n            } else {\n                deferred.resolveWith(node);\n            }\n            return deferred;\n        },\n\n        _create: function () {\n            this._super();\n            this.element\n                .find('.fileupload-buttonbar')\n                .find('.fileinput-button').each(function () {\n                    var input = $(this).find('input:file').detach();\n                    $(this)\n                        .button({icons: {primary: 'ui-icon-plusthick'}})\n                        .append(input);\n                })\n                .end().find('.start')\n                .button({icons: {primary: 'ui-icon-circle-arrow-e'}})\n                .end().find('.cancel')\n                .button({icons: {primary: 'ui-icon-cancel'}})\n                .end().find('.delete')\n                .button({icons: {primary: 'ui-icon-trash'}})\n                .end().find('.progress').progressbar();\n        },\n\n        _destroy: function () {\n            this.element\n                .find('.fileupload-buttonbar')\n                .find('.fileinput-button').each(function () {\n                    var input = $(this).find('input:file').detach();\n                    $(this)\n                        .button('destroy')\n                        .append(input);\n                })\n                .end().find('.start')\n                .button('destroy')\n                .end().find('.cancel')\n                .button('destroy')\n                .end().find('.delete')\n                .button('destroy')\n                .end().find('.progress').progressbar('destroy');\n            this._super();\n        }\n\n    });\n\n}));\n"
  },
  {
    "path": "app_backend/static/plugin/jQuery-File-Upload-9.18.0/js/jquery.fileupload-process.js",
    "content": "/*\n * jQuery File Upload Processing Plugin\n * https://github.com/blueimp/jQuery-File-Upload\n *\n * Copyright 2012, Sebastian Tschan\n * https://blueimp.net\n *\n * Licensed under the MIT license:\n * https://opensource.org/licenses/MIT\n */\n\n/* jshint nomen:false */\n/* global define, require, window */\n\n;(function (factory) {\n    'use strict';\n    if (typeof define === 'function' && define.amd) {\n        // Register as an anonymous AMD module:\n        define([\n            'jquery',\n            './jquery.fileupload'\n        ], factory);\n    } else if (typeof exports === 'object') {\n        // Node/CommonJS:\n        factory(\n            require('jquery'),\n            require('./jquery.fileupload')\n        );\n    } else {\n        // Browser globals:\n        factory(\n            window.jQuery\n        );\n    }\n}(function ($) {\n    'use strict';\n\n    var originalAdd = $.blueimp.fileupload.prototype.options.add;\n\n    // The File Upload Processing plugin extends the fileupload widget\n    // with file processing functionality:\n    $.widget('blueimp.fileupload', $.blueimp.fileupload, {\n\n        options: {\n            // The list of processing actions:\n            processQueue: [\n                /*\n                {\n                    action: 'log',\n                    type: 'debug'\n                }\n                */\n            ],\n            add: function (e, data) {\n                var $this = $(this);\n                data.process(function () {\n                    return $this.fileupload('process', data);\n                });\n                originalAdd.call(this, e, data);\n            }\n        },\n\n        processActions: {\n            /*\n            log: function (data, options) {\n                console[options.type](\n                    'Processing \"' + data.files[data.index].name + '\"'\n                );\n            }\n            */\n        },\n\n        _processFile: function (data, originalData) {\n            var that = this,\n                dfd = $.Deferred().resolveWith(that, [data]),\n                chain = dfd.promise();\n            this._trigger('process', null, data);\n            $.each(data.processQueue, function (i, settings) {\n                var func = function (data) {\n                    if (originalData.errorThrown) {\n                        return $.Deferred()\n                                .rejectWith(that, [originalData]).promise();\n                    }\n                    return that.processActions[settings.action].call(\n                        that,\n                        data,\n                        settings\n                    );\n                };\n                chain = chain.then(func, settings.always && func);\n            });\n            chain\n                .done(function () {\n                    that._trigger('processdone', null, data);\n                    that._trigger('processalways', null, data);\n                })\n                .fail(function () {\n                    that._trigger('processfail', null, data);\n                    that._trigger('processalways', null, data);\n                });\n            return chain;\n        },\n\n        // Replaces the settings of each processQueue item that\n        // are strings starting with an \"@\", using the remaining\n        // substring as key for the option map,\n        // e.g. \"@autoUpload\" is replaced with options.autoUpload:\n        _transformProcessQueue: function (options) {\n            var processQueue = [];\n            $.each(options.processQueue, function () {\n                var settings = {},\n                    action = this.action,\n                    prefix = this.prefix === true ? action : this.prefix;\n                $.each(this, function (key, value) {\n                    if ($.type(value) === 'string' &&\n                            value.charAt(0) === '@') {\n                        settings[key] = options[\n                            value.slice(1) || (prefix ? prefix +\n                                key.charAt(0).toUpperCase() + key.slice(1) : key)\n                        ];\n                    } else {\n                        settings[key] = value;\n                    }\n\n                });\n                processQueue.push(settings);\n            });\n            options.processQueue = processQueue;\n        },\n\n        // Returns the number of files currently in the processsing queue:\n        processing: function () {\n            return this._processing;\n        },\n\n        // Processes the files given as files property of the data parameter,\n        // returns a Promise object that allows to bind callbacks:\n        process: function (data) {\n            var that = this,\n                options = $.extend({}, this.options, data);\n            if (options.processQueue && options.processQueue.length) {\n                this._transformProcessQueue(options);\n                if (this._processing === 0) {\n                    this._trigger('processstart');\n                }\n                $.each(data.files, function (index) {\n                    var opts = index ? $.extend({}, options) : options,\n                        func = function () {\n                            if (data.errorThrown) {\n                                return $.Deferred()\n                                        .rejectWith(that, [data]).promise();\n                            }\n                            return that._processFile(opts, data);\n                        };\n                    opts.index = index;\n                    that._processing += 1;\n                    that._processingQueue = that._processingQueue.then(func, func)\n                        .always(function () {\n                            that._processing -= 1;\n                            if (that._processing === 0) {\n                                that._trigger('processstop');\n                            }\n                        });\n                });\n            }\n            return this._processingQueue;\n        },\n\n        _create: function () {\n            this._super();\n            this._processing = 0;\n            this._processingQueue = $.Deferred().resolveWith(this)\n                .promise();\n        }\n\n    });\n\n}));\n"
  },
  {
    "path": "app_backend/static/plugin/jQuery-File-Upload-9.18.0/js/jquery.fileupload-ui.js",
    "content": "/*\n * jQuery File Upload User Interface Plugin\n * https://github.com/blueimp/jQuery-File-Upload\n *\n * Copyright 2010, Sebastian Tschan\n * https://blueimp.net\n *\n * Licensed under the MIT license:\n * https://opensource.org/licenses/MIT\n */\n\n/* jshint nomen:false */\n/* global define, require, window */\n\n;(function (factory) {\n    'use strict';\n    if (typeof define === 'function' && define.amd) {\n        // Register as an anonymous AMD module:\n        define([\n            'jquery',\n            'blueimp-tmpl',\n            './jquery.fileupload-image',\n            './jquery.fileupload-audio',\n            './jquery.fileupload-video',\n            './jquery.fileupload-validate'\n        ], factory);\n    } else if (typeof exports === 'object') {\n        // Node/CommonJS:\n        factory(\n            require('jquery'),\n            require('blueimp-tmpl'),\n            require('./jquery.fileupload-image'),\n            require('./jquery.fileupload-video'),\n            require('./jquery.fileupload-validate')\n        );\n    } else {\n        // Browser globals:\n        factory(\n            window.jQuery,\n            window.tmpl\n        );\n    }\n}(function ($, tmpl) {\n    'use strict';\n\n    $.blueimp.fileupload.prototype._specialOptions.push(\n        'filesContainer',\n        'uploadTemplateId',\n        'downloadTemplateId'\n    );\n\n    // The UI version extends the file upload widget\n    // and adds complete user interface interaction:\n    $.widget('blueimp.fileupload', $.blueimp.fileupload, {\n\n        options: {\n            // By default, files added to the widget are uploaded as soon\n            // as the user clicks on the start buttons. To enable automatic\n            // uploads, set the following option to true:\n            autoUpload: false,\n            // The ID of the upload template:\n            uploadTemplateId: 'template-upload',\n            // The ID of the download template:\n            downloadTemplateId: 'template-download',\n            // The container for the list of files. If undefined, it is set to\n            // an element with class \"files\" inside of the widget element:\n            filesContainer: undefined,\n            // By default, files are appended to the files container.\n            // Set the following option to true, to prepend files instead:\n            prependFiles: false,\n            // The expected data type of the upload response, sets the dataType\n            // option of the $.ajax upload requests:\n            dataType: 'json',\n\n            // Error and info messages:\n            messages: {\n                unknownError: 'Unknown error'\n            },\n\n            // Function returning the current number of files,\n            // used by the maxNumberOfFiles validation:\n            getNumberOfFiles: function () {\n                return this.filesContainer.children()\n                    .not('.processing').length;\n            },\n\n            // Callback to retrieve the list of files from the server response:\n            getFilesFromResponse: function (data) {\n                if (data.result && $.isArray(data.result.files)) {\n                    return data.result.files;\n                }\n                return [];\n            },\n\n            // The add callback is invoked as soon as files are added to the fileupload\n            // widget (via file input selection, drag & drop or add API call).\n            // See the basic file upload widget for more information:\n            add: function (e, data) {\n                if (e.isDefaultPrevented()) {\n                    return false;\n                }\n                var $this = $(this),\n                    that = $this.data('blueimp-fileupload') ||\n                        $this.data('fileupload'),\n                    options = that.options;\n                data.context = that._renderUpload(data.files)\n                    .data('data', data)\n                    .addClass('processing');\n                options.filesContainer[\n                    options.prependFiles ? 'prepend' : 'append'\n                ](data.context);\n                that._forceReflow(data.context);\n                that._transition(data.context);\n                data.process(function () {\n                    return $this.fileupload('process', data);\n                }).always(function () {\n                    data.context.each(function (index) {\n                        $(this).find('.size').text(\n                            that._formatFileSize(data.files[index].size)\n                        );\n                    }).removeClass('processing');\n                    that._renderPreviews(data);\n                }).done(function () {\n                    data.context.find('.start').prop('disabled', false);\n                    if ((that._trigger('added', e, data) !== false) &&\n                            (options.autoUpload || data.autoUpload) &&\n                            data.autoUpload !== false) {\n                        data.submit();\n                    }\n                }).fail(function () {\n                    if (data.files.error) {\n                        data.context.each(function (index) {\n                            var error = data.files[index].error;\n                            if (error) {\n                                $(this).find('.error').text(error);\n                            }\n                        });\n                    }\n                });\n            },\n            // Callback for the start of each file upload request:\n            send: function (e, data) {\n                if (e.isDefaultPrevented()) {\n                    return false;\n                }\n                var that = $(this).data('blueimp-fileupload') ||\n                        $(this).data('fileupload');\n                if (data.context && data.dataType &&\n                        data.dataType.substr(0, 6) === 'iframe') {\n                    // Iframe Transport does not support progress events.\n                    // In lack of an indeterminate progress bar, we set\n                    // the progress to 100%, showing the full animated bar:\n                    data.context\n                        .find('.progress').addClass(\n                            !$.support.transition && 'progress-animated'\n                        )\n                        .attr('aria-valuenow', 100)\n                        .children().first().css(\n                            'width',\n                            '100%'\n                        );\n                }\n                return that._trigger('sent', e, data);\n            },\n            // Callback for successful uploads:\n            done: function (e, data) {\n                if (e.isDefaultPrevented()) {\n                    return false;\n                }\n                var that = $(this).data('blueimp-fileupload') ||\n                        $(this).data('fileupload'),\n                    getFilesFromResponse = data.getFilesFromResponse ||\n                        that.options.getFilesFromResponse,\n                    files = getFilesFromResponse(data),\n                    template,\n                    deferred;\n                if (data.context) {\n                    data.context.each(function (index) {\n                        var file = files[index] ||\n                                {error: 'Empty file upload result'};\n                        deferred = that._addFinishedDeferreds();\n                        that._transition($(this)).done(\n                            function () {\n                                var node = $(this);\n                                template = that._renderDownload([file])\n                                    .replaceAll(node);\n                                that._forceReflow(template);\n                                that._transition(template).done(\n                                    function () {\n                                        data.context = $(this);\n                                        that._trigger('completed', e, data);\n                                        that._trigger('finished', e, data);\n                                        deferred.resolve();\n                                    }\n                                );\n                            }\n                        );\n                    });\n                } else {\n                    template = that._renderDownload(files)[\n                        that.options.prependFiles ? 'prependTo' : 'appendTo'\n                    ](that.options.filesContainer);\n                    that._forceReflow(template);\n                    deferred = that._addFinishedDeferreds();\n                    that._transition(template).done(\n                        function () {\n                            data.context = $(this);\n                            that._trigger('completed', e, data);\n                            that._trigger('finished', e, data);\n                            deferred.resolve();\n                        }\n                    );\n                }\n            },\n            // Callback for failed (abort or error) uploads:\n            fail: function (e, data) {\n                if (e.isDefaultPrevented()) {\n                    return false;\n                }\n                var that = $(this).data('blueimp-fileupload') ||\n                        $(this).data('fileupload'),\n                    template,\n                    deferred;\n                if (data.context) {\n                    data.context.each(function (index) {\n                        if (data.errorThrown !== 'abort') {\n                            var file = data.files[index];\n                            file.error = file.error || data.errorThrown ||\n                                data.i18n('unknownError');\n                            deferred = that._addFinishedDeferreds();\n                            that._transition($(this)).done(\n                                function () {\n                                    var node = $(this);\n                                    template = that._renderDownload([file])\n                                        .replaceAll(node);\n                                    that._forceReflow(template);\n                                    that._transition(template).done(\n                                        function () {\n                                            data.context = $(this);\n                                            that._trigger('failed', e, data);\n                                            that._trigger('finished', e, data);\n                                            deferred.resolve();\n                                        }\n                                    );\n                                }\n                            );\n                        } else {\n                            deferred = that._addFinishedDeferreds();\n                            that._transition($(this)).done(\n                                function () {\n                                    $(this).remove();\n                                    that._trigger('failed', e, data);\n                                    that._trigger('finished', e, data);\n                                    deferred.resolve();\n                                }\n                            );\n                        }\n                    });\n                } else if (data.errorThrown !== 'abort') {\n                    data.context = that._renderUpload(data.files)[\n                        that.options.prependFiles ? 'prependTo' : 'appendTo'\n                    ](that.options.filesContainer)\n                        .data('data', data);\n                    that._forceReflow(data.context);\n                    deferred = that._addFinishedDeferreds();\n                    that._transition(data.context).done(\n                        function () {\n                            data.context = $(this);\n                            that._trigger('failed', e, data);\n                            that._trigger('finished', e, data);\n                            deferred.resolve();\n                        }\n                    );\n                } else {\n                    that._trigger('failed', e, data);\n                    that._trigger('finished', e, data);\n                    that._addFinishedDeferreds().resolve();\n                }\n            },\n            // Callback for upload progress events:\n            progress: function (e, data) {\n                if (e.isDefaultPrevented()) {\n                    return false;\n                }\n                var progress = Math.floor(data.loaded / data.total * 100);\n                if (data.context) {\n                    data.context.each(function () {\n                        $(this).find('.progress')\n                            .attr('aria-valuenow', progress)\n                            .children().first().css(\n                                'width',\n                                progress + '%'\n                            );\n                    });\n                }\n            },\n            // Callback for global upload progress events:\n            progressall: function (e, data) {\n                if (e.isDefaultPrevented()) {\n                    return false;\n                }\n                var $this = $(this),\n                    progress = Math.floor(data.loaded / data.total * 100),\n                    globalProgressNode = $this.find('.fileupload-progress'),\n                    extendedProgressNode = globalProgressNode\n                        .find('.progress-extended');\n                if (extendedProgressNode.length) {\n                    extendedProgressNode.html(\n                        ($this.data('blueimp-fileupload') || $this.data('fileupload'))\n                            ._renderExtendedProgress(data)\n                    );\n                }\n                globalProgressNode\n                    .find('.progress')\n                    .attr('aria-valuenow', progress)\n                    .children().first().css(\n                        'width',\n                        progress + '%'\n                    );\n            },\n            // Callback for uploads start, equivalent to the global ajaxStart event:\n            start: function (e) {\n                if (e.isDefaultPrevented()) {\n                    return false;\n                }\n                var that = $(this).data('blueimp-fileupload') ||\n                        $(this).data('fileupload');\n                that._resetFinishedDeferreds();\n                that._transition($(this).find('.fileupload-progress')).done(\n                    function () {\n                        that._trigger('started', e);\n                    }\n                );\n            },\n            // Callback for uploads stop, equivalent to the global ajaxStop event:\n            stop: function (e) {\n                if (e.isDefaultPrevented()) {\n                    return false;\n                }\n                var that = $(this).data('blueimp-fileupload') ||\n                        $(this).data('fileupload'),\n                    deferred = that._addFinishedDeferreds();\n                $.when.apply($, that._getFinishedDeferreds())\n                    .done(function () {\n                        that._trigger('stopped', e);\n                    });\n                that._transition($(this).find('.fileupload-progress')).done(\n                    function () {\n                        $(this).find('.progress')\n                            .attr('aria-valuenow', '0')\n                            .children().first().css('width', '0%');\n                        $(this).find('.progress-extended').html('&nbsp;');\n                        deferred.resolve();\n                    }\n                );\n            },\n            processstart: function (e) {\n                if (e.isDefaultPrevented()) {\n                    return false;\n                }\n                $(this).addClass('fileupload-processing');\n            },\n            processstop: function (e) {\n                if (e.isDefaultPrevented()) {\n                    return false;\n                }\n                $(this).removeClass('fileupload-processing');\n            },\n            // Callback for file deletion:\n            destroy: function (e, data) {\n                if (e.isDefaultPrevented()) {\n                    return false;\n                }\n                var that = $(this).data('blueimp-fileupload') ||\n                        $(this).data('fileupload'),\n                    removeNode = function () {\n                        that._transition(data.context).done(\n                            function () {\n                                $(this).remove();\n                                that._trigger('destroyed', e, data);\n                            }\n                        );\n                    };\n                if (data.url) {\n                    data.dataType = data.dataType || that.options.dataType;\n                    $.ajax(data).done(removeNode).fail(function () {\n                        that._trigger('destroyfailed', e, data);\n                    });\n                } else {\n                    removeNode();\n                }\n            }\n        },\n\n        _resetFinishedDeferreds: function () {\n            this._finishedUploads = [];\n        },\n\n        _addFinishedDeferreds: function (deferred) {\n            if (!deferred) {\n                deferred = $.Deferred();\n            }\n            this._finishedUploads.push(deferred);\n            return deferred;\n        },\n\n        _getFinishedDeferreds: function () {\n            return this._finishedUploads;\n        },\n\n        // Link handler, that allows to download files\n        // by drag & drop of the links to the desktop:\n        _enableDragToDesktop: function () {\n            var link = $(this),\n                url = link.prop('href'),\n                name = link.prop('download'),\n                type = 'application/octet-stream';\n            link.bind('dragstart', function (e) {\n                try {\n                    e.originalEvent.dataTransfer.setData(\n                        'DownloadURL',\n                        [type, name, url].join(':')\n                    );\n                } catch (ignore) {}\n            });\n        },\n\n        _formatFileSize: function (bytes) {\n            if (typeof bytes !== 'number') {\n                return '';\n            }\n            if (bytes >= 1000000000) {\n                return (bytes / 1000000000).toFixed(2) + ' GB';\n            }\n            if (bytes >= 1000000) {\n                return (bytes / 1000000).toFixed(2) + ' MB';\n            }\n            return (bytes / 1000).toFixed(2) + ' KB';\n        },\n\n        _formatBitrate: function (bits) {\n            if (typeof bits !== 'number') {\n                return '';\n            }\n            if (bits >= 1000000000) {\n                return (bits / 1000000000).toFixed(2) + ' Gbit/s';\n            }\n            if (bits >= 1000000) {\n                return (bits / 1000000).toFixed(2) + ' Mbit/s';\n            }\n            if (bits >= 1000) {\n                return (bits / 1000).toFixed(2) + ' kbit/s';\n            }\n            return bits.toFixed(2) + ' bit/s';\n        },\n\n        _formatTime: function (seconds) {\n            var date = new Date(seconds * 1000),\n                days = Math.floor(seconds / 86400);\n            days = days ? days + 'd ' : '';\n            return days +\n                ('0' + date.getUTCHours()).slice(-2) + ':' +\n                ('0' + date.getUTCMinutes()).slice(-2) + ':' +\n                ('0' + date.getUTCSeconds()).slice(-2);\n        },\n\n        _formatPercentage: function (floatValue) {\n            return (floatValue * 100).toFixed(2) + ' %';\n        },\n\n        _renderExtendedProgress: function (data) {\n            return this._formatBitrate(data.bitrate) + ' | ' +\n                this._formatTime(\n                    (data.total - data.loaded) * 8 / data.bitrate\n                ) + ' | ' +\n                this._formatPercentage(\n                    data.loaded / data.total\n                ) + ' | ' +\n                this._formatFileSize(data.loaded) + ' / ' +\n                this._formatFileSize(data.total);\n        },\n\n        _renderTemplate: function (func, files) {\n            if (!func) {\n                return $();\n            }\n            var result = func({\n                files: files,\n                formatFileSize: this._formatFileSize,\n                options: this.options\n            });\n            if (result instanceof $) {\n                return result;\n            }\n            return $(this.options.templatesContainer).html(result).children();\n        },\n\n        _renderPreviews: function (data) {\n            data.context.find('.preview').each(function (index, elm) {\n                $(elm).append(data.files[index].preview);\n            });\n        },\n\n        _renderUpload: function (files) {\n            return this._renderTemplate(\n                this.options.uploadTemplate,\n                files\n            );\n        },\n\n        _renderDownload: function (files) {\n            return this._renderTemplate(\n                this.options.downloadTemplate,\n                files\n            ).find('a[download]').each(this._enableDragToDesktop).end();\n        },\n\n        _startHandler: function (e) {\n            e.preventDefault();\n            var button = $(e.currentTarget),\n                template = button.closest('.template-upload'),\n                data = template.data('data');\n            button.prop('disabled', true);\n            if (data && data.submit) {\n                data.submit();\n            }\n        },\n\n        _cancelHandler: function (e) {\n            e.preventDefault();\n            var template = $(e.currentTarget)\n                    .closest('.template-upload,.template-download'),\n                data = template.data('data') || {};\n            data.context = data.context || template;\n            if (data.abort) {\n                data.abort();\n            } else {\n                data.errorThrown = 'abort';\n                this._trigger('fail', e, data);\n            }\n        },\n\n        _deleteHandler: function (e) {\n            e.preventDefault();\n            var button = $(e.currentTarget);\n            this._trigger('destroy', e, $.extend({\n                context: button.closest('.template-download'),\n                type: 'DELETE'\n            }, button.data()));\n        },\n\n        _forceReflow: function (node) {\n            return $.support.transition && node.length &&\n                node[0].offsetWidth;\n        },\n\n        _transition: function (node) {\n            var dfd = $.Deferred();\n            if ($.support.transition && node.hasClass('fade') && node.is(':visible')) {\n                node.bind(\n                    $.support.transition.end,\n                    function (e) {\n                        // Make sure we don't respond to other transitions events\n                        // in the container element, e.g. from button elements:\n                        if (e.target === node[0]) {\n                            node.unbind($.support.transition.end);\n                            dfd.resolveWith(node);\n                        }\n                    }\n                ).toggleClass('in');\n            } else {\n                node.toggleClass('in');\n                dfd.resolveWith(node);\n            }\n            return dfd;\n        },\n\n        _initButtonBarEventHandlers: function () {\n            var fileUploadButtonBar = this.element.find('.fileupload-buttonbar'),\n                filesList = this.options.filesContainer;\n            this._on(fileUploadButtonBar.find('.start'), {\n                click: function (e) {\n                    e.preventDefault();\n                    filesList.find('.start').click();\n                }\n            });\n            this._on(fileUploadButtonBar.find('.cancel'), {\n                click: function (e) {\n                    e.preventDefault();\n                    filesList.find('.cancel').click();\n                }\n            });\n            this._on(fileUploadButtonBar.find('.delete'), {\n                click: function (e) {\n                    e.preventDefault();\n                    filesList.find('.toggle:checked')\n                        .closest('.template-download')\n                        .find('.delete').click();\n                    fileUploadButtonBar.find('.toggle')\n                        .prop('checked', false);\n                }\n            });\n            this._on(fileUploadButtonBar.find('.toggle'), {\n                change: function (e) {\n                    filesList.find('.toggle').prop(\n                        'checked',\n                        $(e.currentTarget).is(':checked')\n                    );\n                }\n            });\n        },\n\n        _destroyButtonBarEventHandlers: function () {\n            this._off(\n                this.element.find('.fileupload-buttonbar')\n                    .find('.start, .cancel, .delete'),\n                'click'\n            );\n            this._off(\n                this.element.find('.fileupload-buttonbar .toggle'),\n                'change.'\n            );\n        },\n\n        _initEventHandlers: function () {\n            this._super();\n            this._on(this.options.filesContainer, {\n                'click .start': this._startHandler,\n                'click .cancel': this._cancelHandler,\n                'click .delete': this._deleteHandler\n            });\n            this._initButtonBarEventHandlers();\n        },\n\n        _destroyEventHandlers: function () {\n            this._destroyButtonBarEventHandlers();\n            this._off(this.options.filesContainer, 'click');\n            this._super();\n        },\n\n        _enableFileInputButton: function () {\n            this.element.find('.fileinput-button input')\n                .prop('disabled', false)\n                .parent().removeClass('disabled');\n        },\n\n        _disableFileInputButton: function () {\n            this.element.find('.fileinput-button input')\n                .prop('disabled', true)\n                .parent().addClass('disabled');\n        },\n\n        _initTemplates: function () {\n            var options = this.options;\n            options.templatesContainer = this.document[0].createElement(\n                options.filesContainer.prop('nodeName')\n            );\n            if (tmpl) {\n                if (options.uploadTemplateId) {\n                    options.uploadTemplate = tmpl(options.uploadTemplateId);\n                }\n                if (options.downloadTemplateId) {\n                    options.downloadTemplate = tmpl(options.downloadTemplateId);\n                }\n            }\n        },\n\n        _initFilesContainer: function () {\n            var options = this.options;\n            if (options.filesContainer === undefined) {\n                options.filesContainer = this.element.find('.files');\n            } else if (!(options.filesContainer instanceof $)) {\n                options.filesContainer = $(options.filesContainer);\n            }\n        },\n\n        _initSpecialOptions: function () {\n            this._super();\n            this._initFilesContainer();\n            this._initTemplates();\n        },\n\n        _create: function () {\n            this._super();\n            this._resetFinishedDeferreds();\n            if (!$.support.fileInput) {\n                this._disableFileInputButton();\n            }\n        },\n\n        enable: function () {\n            var wasDisabled = false;\n            if (this.options.disabled) {\n                wasDisabled = true;\n            }\n            this._super();\n            if (wasDisabled) {\n                this.element.find('input, button').prop('disabled', false);\n                this._enableFileInputButton();\n            }\n        },\n\n        disable: function () {\n            if (!this.options.disabled) {\n                this.element.find('input, button').prop('disabled', true);\n                this._disableFileInputButton();\n            }\n            this._super();\n        }\n\n    });\n\n}));\n"
  },
  {
    "path": "app_backend/static/plugin/jQuery-File-Upload-9.18.0/js/jquery.fileupload-validate.js",
    "content": "/*\n * jQuery File Upload Validation Plugin\n * https://github.com/blueimp/jQuery-File-Upload\n *\n * Copyright 2013, Sebastian Tschan\n * https://blueimp.net\n *\n * Licensed under the MIT license:\n * https://opensource.org/licenses/MIT\n */\n\n/* global define, require, window */\n\n;(function (factory) {\n    'use strict';\n    if (typeof define === 'function' && define.amd) {\n        // Register as an anonymous AMD module:\n        define([\n            'jquery',\n            './jquery.fileupload-process'\n        ], factory);\n    } else if (typeof exports === 'object') {\n        // Node/CommonJS:\n        factory(\n            require('jquery'),\n            require('./jquery.fileupload-process')\n        );\n    } else {\n        // Browser globals:\n        factory(\n            window.jQuery\n        );\n    }\n}(function ($) {\n    'use strict';\n\n    // Append to the default processQueue:\n    $.blueimp.fileupload.prototype.options.processQueue.push(\n        {\n            action: 'validate',\n            // Always trigger this action,\n            // even if the previous action was rejected:\n            always: true,\n            // Options taken from the global options map:\n            acceptFileTypes: '@',\n            maxFileSize: '@',\n            minFileSize: '@',\n            maxNumberOfFiles: '@',\n            disabled: '@disableValidation'\n        }\n    );\n\n    // The File Upload Validation plugin extends the fileupload widget\n    // with file validation functionality:\n    $.widget('blueimp.fileupload', $.blueimp.fileupload, {\n\n        options: {\n            /*\n            // The regular expression for allowed file types, matches\n            // against either file type or file name:\n            acceptFileTypes: /(\\.|\\/)(gif|jpe?g|png)$/i,\n            // The maximum allowed file size in bytes:\n            maxFileSize: 10000000, // 10 MB\n            // The minimum allowed file size in bytes:\n            minFileSize: undefined, // No minimal file size\n            // The limit of files to be uploaded:\n            maxNumberOfFiles: 10,\n            */\n\n            // Function returning the current number of files,\n            // has to be overriden for maxNumberOfFiles validation:\n            getNumberOfFiles: $.noop,\n\n            // Error and info messages:\n            messages: {\n                maxNumberOfFiles: 'Maximum number of files exceeded',\n                acceptFileTypes: 'File type not allowed',\n                maxFileSize: 'File is too large',\n                minFileSize: 'File is too small'\n            }\n        },\n\n        processActions: {\n\n            validate: function (data, options) {\n                if (options.disabled) {\n                    return data;\n                }\n                var dfd = $.Deferred(),\n                    settings = this.options,\n                    file = data.files[data.index],\n                    fileSize;\n                if (options.minFileSize || options.maxFileSize) {\n                    fileSize = file.size;\n                }\n                if ($.type(options.maxNumberOfFiles) === 'number' &&\n                        (settings.getNumberOfFiles() || 0) + data.files.length >\n                            options.maxNumberOfFiles) {\n                    file.error = settings.i18n('maxNumberOfFiles');\n                } else if (options.acceptFileTypes &&\n                        !(options.acceptFileTypes.test(file.type) ||\n                        options.acceptFileTypes.test(file.name))) {\n                    file.error = settings.i18n('acceptFileTypes');\n                } else if (fileSize > options.maxFileSize) {\n                    file.error = settings.i18n('maxFileSize');\n                } else if ($.type(fileSize) === 'number' &&\n                        fileSize < options.minFileSize) {\n                    file.error = settings.i18n('minFileSize');\n                } else {\n                    delete file.error;\n                }\n                if (file.error || data.files.error) {\n                    data.files.error = true;\n                    dfd.rejectWith(this, [data]);\n                } else {\n                    dfd.resolveWith(this, [data]);\n                }\n                return dfd.promise();\n            }\n\n        }\n\n    });\n\n}));\n"
  },
  {
    "path": "app_backend/static/plugin/jQuery-File-Upload-9.18.0/js/jquery.fileupload-video.js",
    "content": "/*\n * jQuery File Upload Video Preview Plugin\n * https://github.com/blueimp/jQuery-File-Upload\n *\n * Copyright 2013, Sebastian Tschan\n * https://blueimp.net\n *\n * Licensed under the MIT license:\n * https://opensource.org/licenses/MIT\n */\n\n/* jshint nomen:false */\n/* global define, require, window, document */\n\n;(function (factory) {\n    'use strict';\n    if (typeof define === 'function' && define.amd) {\n        // Register as an anonymous AMD module:\n        define([\n            'jquery',\n            'load-image',\n            './jquery.fileupload-process'\n        ], factory);\n    } else if (typeof exports === 'object') {\n        // Node/CommonJS:\n        factory(\n            require('jquery'),\n            require('blueimp-load-image/js/load-image'),\n            require('./jquery.fileupload-process')\n        );\n    } else {\n        // Browser globals:\n        factory(\n            window.jQuery,\n            window.loadImage\n        );\n    }\n}(function ($, loadImage) {\n    'use strict';\n\n    // Prepend to the default processQueue:\n    $.blueimp.fileupload.prototype.options.processQueue.unshift(\n        {\n            action: 'loadVideo',\n            // Use the action as prefix for the \"@\" options:\n            prefix: true,\n            fileTypes: '@',\n            maxFileSize: '@',\n            disabled: '@disableVideoPreview'\n        },\n        {\n            action: 'setVideo',\n            name: '@videoPreviewName',\n            disabled: '@disableVideoPreview'\n        }\n    );\n\n    // The File Upload Video Preview plugin extends the fileupload widget\n    // with video preview functionality:\n    $.widget('blueimp.fileupload', $.blueimp.fileupload, {\n\n        options: {\n            // The regular expression for the types of video files to load,\n            // matched against the file type:\n            loadVideoFileTypes: /^video\\/.*$/\n        },\n\n        _videoElement: document.createElement('video'),\n\n        processActions: {\n\n            // Loads the video file given via data.files and data.index\n            // as video element if the browser supports playing it.\n            // Accepts the options fileTypes (regular expression)\n            // and maxFileSize (integer) to limit the files to load:\n            loadVideo: function (data, options) {\n                if (options.disabled) {\n                    return data;\n                }\n                var file = data.files[data.index],\n                    url,\n                    video;\n                if (this._videoElement.canPlayType &&\n                        this._videoElement.canPlayType(file.type) &&\n                        ($.type(options.maxFileSize) !== 'number' ||\n                            file.size <= options.maxFileSize) &&\n                        (!options.fileTypes ||\n                            options.fileTypes.test(file.type))) {\n                    url = loadImage.createObjectURL(file);\n                    if (url) {\n                        video = this._videoElement.cloneNode(false);\n                        video.src = url;\n                        video.controls = true;\n                        data.video = video;\n                        return data;\n                    }\n                }\n                return data;\n            },\n\n            // Sets the video element as a property of the file object:\n            setVideo: function (data, options) {\n                if (data.video && !options.disabled) {\n                    data.files[data.index][options.name || 'preview'] = data.video;\n                }\n                return data;\n            }\n\n        }\n\n    });\n\n}));\n"
  },
  {
    "path": "app_backend/static/plugin/jQuery-File-Upload-9.18.0/js/jquery.fileupload.js",
    "content": "/*\n * jQuery File Upload Plugin\n * https://github.com/blueimp/jQuery-File-Upload\n *\n * Copyright 2010, Sebastian Tschan\n * https://blueimp.net\n *\n * Licensed under the MIT license:\n * https://opensource.org/licenses/MIT\n */\n\n/* jshint nomen:false */\n/* global define, require, window, document, location, Blob, FormData */\n\n;(function (factory) {\n    'use strict';\n    if (typeof define === 'function' && define.amd) {\n        // Register as an anonymous AMD module:\n        define([\n            'jquery',\n            'jquery-ui/ui/widget'\n        ], factory);\n    } else if (typeof exports === 'object') {\n        // Node/CommonJS:\n        factory(\n            require('jquery'),\n            require('./vendor/jquery.ui.widget')\n        );\n    } else {\n        // Browser globals:\n        factory(window.jQuery);\n    }\n}(function ($) {\n    'use strict';\n\n    // Detect file input support, based on\n    // http://viljamis.com/blog/2012/file-upload-support-on-mobile/\n    $.support.fileInput = !(new RegExp(\n        // Handle devices which give false positives for the feature detection:\n        '(Android (1\\\\.[0156]|2\\\\.[01]))' +\n            '|(Windows Phone (OS 7|8\\\\.0))|(XBLWP)|(ZuneWP)|(WPDesktop)' +\n            '|(w(eb)?OSBrowser)|(webOS)' +\n            '|(Kindle/(1\\\\.0|2\\\\.[05]|3\\\\.0))'\n    ).test(window.navigator.userAgent) ||\n        // Feature detection for all other devices:\n        $('<input type=\"file\">').prop('disabled'));\n\n    // The FileReader API is not actually used, but works as feature detection,\n    // as some Safari versions (5?) support XHR file uploads via the FormData API,\n    // but not non-multipart XHR file uploads.\n    // window.XMLHttpRequestUpload is not available on IE10, so we check for\n    // window.ProgressEvent instead to detect XHR2 file upload capability:\n    $.support.xhrFileUpload = !!(window.ProgressEvent && window.FileReader);\n    $.support.xhrFormDataFileUpload = !!window.FormData;\n\n    // Detect support for Blob slicing (required for chunked uploads):\n    $.support.blobSlice = window.Blob && (Blob.prototype.slice ||\n        Blob.prototype.webkitSlice || Blob.prototype.mozSlice);\n\n    // Helper function to create drag handlers for dragover/dragenter/dragleave:\n    function getDragHandler(type) {\n        var isDragOver = type === 'dragover';\n        return function (e) {\n            e.dataTransfer = e.originalEvent && e.originalEvent.dataTransfer;\n            var dataTransfer = e.dataTransfer;\n            if (dataTransfer && $.inArray('Files', dataTransfer.types) !== -1 &&\n                    this._trigger(\n                        type,\n                        $.Event(type, {delegatedEvent: e})\n                    ) !== false) {\n                e.preventDefault();\n                if (isDragOver) {\n                    dataTransfer.dropEffect = 'copy';\n                }\n            }\n        };\n    }\n\n    // The fileupload widget listens for change events on file input fields defined\n    // via fileInput setting and paste or drop events of the given dropZone.\n    // In addition to the default jQuery Widget methods, the fileupload widget\n    // exposes the \"add\" and \"send\" methods, to add or directly send files using\n    // the fileupload API.\n    // By default, files added via file input selection, paste, drag & drop or\n    // \"add\" method are uploaded immediately, but it is possible to override\n    // the \"add\" callback option to queue file uploads.\n    $.widget('blueimp.fileupload', {\n\n        options: {\n            // The drop target element(s), by the default the complete document.\n            // Set to null to disable drag & drop support:\n            dropZone: $(document),\n            // The paste target element(s), by the default undefined.\n            // Set to a DOM node or jQuery object to enable file pasting:\n            pasteZone: undefined,\n            // The file input field(s), that are listened to for change events.\n            // If undefined, it is set to the file input fields inside\n            // of the widget element on plugin initialization.\n            // Set to null to disable the change listener.\n            fileInput: undefined,\n            // By default, the file input field is replaced with a clone after\n            // each input field change event. This is required for iframe transport\n            // queues and allows change events to be fired for the same file\n            // selection, but can be disabled by setting the following option to false:\n            replaceFileInput: true,\n            // The parameter name for the file form data (the request argument name).\n            // If undefined or empty, the name property of the file input field is\n            // used, or \"files[]\" if the file input name property is also empty,\n            // can be a string or an array of strings:\n            paramName: undefined,\n            // By default, each file of a selection is uploaded using an individual\n            // request for XHR type uploads. Set to false to upload file\n            // selections in one request each:\n            singleFileUploads: true,\n            // To limit the number of files uploaded with one XHR request,\n            // set the following option to an integer greater than 0:\n            limitMultiFileUploads: undefined,\n            // The following option limits the number of files uploaded with one\n            // XHR request to keep the request size under or equal to the defined\n            // limit in bytes:\n            limitMultiFileUploadSize: undefined,\n            // Multipart file uploads add a number of bytes to each uploaded file,\n            // therefore the following option adds an overhead for each file used\n            // in the limitMultiFileUploadSize configuration:\n            limitMultiFileUploadSizeOverhead: 512,\n            // Set the following option to true to issue all file upload requests\n            // in a sequential order:\n            sequentialUploads: false,\n            // To limit the number of concurrent uploads,\n            // set the following option to an integer greater than 0:\n            limitConcurrentUploads: undefined,\n            // Set the following option to true to force iframe transport uploads:\n            forceIframeTransport: false,\n            // Set the following option to the location of a redirect url on the\n            // origin server, for cross-domain iframe transport uploads:\n            redirect: undefined,\n            // The parameter name for the redirect url, sent as part of the form\n            // data and set to 'redirect' if this option is empty:\n            redirectParamName: undefined,\n            // Set the following option to the location of a postMessage window,\n            // to enable postMessage transport uploads:\n            postMessage: undefined,\n            // By default, XHR file uploads are sent as multipart/form-data.\n            // The iframe transport is always using multipart/form-data.\n            // Set to false to enable non-multipart XHR uploads:\n            multipart: true,\n            // To upload large files in smaller chunks, set the following option\n            // to a preferred maximum chunk size. If set to 0, null or undefined,\n            // or the browser does not support the required Blob API, files will\n            // be uploaded as a whole.\n            maxChunkSize: undefined,\n            // When a non-multipart upload or a chunked multipart upload has been\n            // aborted, this option can be used to resume the upload by setting\n            // it to the size of the already uploaded bytes. This option is most\n            // useful when modifying the options object inside of the \"add\" or\n            // \"send\" callbacks, as the options are cloned for each file upload.\n            uploadedBytes: undefined,\n            // By default, failed (abort or error) file uploads are removed from the\n            // global progress calculation. Set the following option to false to\n            // prevent recalculating the global progress data:\n            recalculateProgress: true,\n            // Interval in milliseconds to calculate and trigger progress events:\n            progressInterval: 100,\n            // Interval in milliseconds to calculate progress bitrate:\n            bitrateInterval: 500,\n            // By default, uploads are started automatically when adding files:\n            autoUpload: true,\n\n            // Error and info messages:\n            messages: {\n                uploadedBytes: 'Uploaded bytes exceed file size'\n            },\n\n            // Translation function, gets the message key to be translated\n            // and an object with context specific data as arguments:\n            i18n: function (message, context) {\n                message = this.messages[message] || message.toString();\n                if (context) {\n                    $.each(context, function (key, value) {\n                        message = message.replace('{' + key + '}', value);\n                    });\n                }\n                return message;\n            },\n\n            // Additional form data to be sent along with the file uploads can be set\n            // using this option, which accepts an array of objects with name and\n            // value properties, a function returning such an array, a FormData\n            // object (for XHR file uploads), or a simple object.\n            // The form of the first fileInput is given as parameter to the function:\n            formData: function (form) {\n                return form.serializeArray();\n            },\n\n            // The add callback is invoked as soon as files are added to the fileupload\n            // widget (via file input selection, drag & drop, paste or add API call).\n            // If the singleFileUploads option is enabled, this callback will be\n            // called once for each file in the selection for XHR file uploads, else\n            // once for each file selection.\n            //\n            // The upload starts when the submit method is invoked on the data parameter.\n            // The data object contains a files property holding the added files\n            // and allows you to override plugin options as well as define ajax settings.\n            //\n            // Listeners for this callback can also be bound the following way:\n            // .bind('fileuploadadd', func);\n            //\n            // data.submit() returns a Promise object and allows to attach additional\n            // handlers using jQuery's Deferred callbacks:\n            // data.submit().done(func).fail(func).always(func);\n            add: function (e, data) {\n                if (e.isDefaultPrevented()) {\n                    return false;\n                }\n                if (data.autoUpload || (data.autoUpload !== false &&\n                        $(this).fileupload('option', 'autoUpload'))) {\n                    data.process().done(function () {\n                        data.submit();\n                    });\n                }\n            },\n\n            // Other callbacks:\n\n            // Callback for the submit event of each file upload:\n            // submit: function (e, data) {}, // .bind('fileuploadsubmit', func);\n\n            // Callback for the start of each file upload request:\n            // send: function (e, data) {}, // .bind('fileuploadsend', func);\n\n            // Callback for successful uploads:\n            // done: function (e, data) {}, // .bind('fileuploaddone', func);\n\n            // Callback for failed (abort or error) uploads:\n            // fail: function (e, data) {}, // .bind('fileuploadfail', func);\n\n            // Callback for completed (success, abort or error) requests:\n            // always: function (e, data) {}, // .bind('fileuploadalways', func);\n\n            // Callback for upload progress events:\n            // progress: function (e, data) {}, // .bind('fileuploadprogress', func);\n\n            // Callback for global upload progress events:\n            // progressall: function (e, data) {}, // .bind('fileuploadprogressall', func);\n\n            // Callback for uploads start, equivalent to the global ajaxStart event:\n            // start: function (e) {}, // .bind('fileuploadstart', func);\n\n            // Callback for uploads stop, equivalent to the global ajaxStop event:\n            // stop: function (e) {}, // .bind('fileuploadstop', func);\n\n            // Callback for change events of the fileInput(s):\n            // change: function (e, data) {}, // .bind('fileuploadchange', func);\n\n            // Callback for paste events to the pasteZone(s):\n            // paste: function (e, data) {}, // .bind('fileuploadpaste', func);\n\n            // Callback for drop events of the dropZone(s):\n            // drop: function (e, data) {}, // .bind('fileuploaddrop', func);\n\n            // Callback for dragover events of the dropZone(s):\n            // dragover: function (e) {}, // .bind('fileuploaddragover', func);\n\n            // Callback for the start of each chunk upload request:\n            // chunksend: function (e, data) {}, // .bind('fileuploadchunksend', func);\n\n            // Callback for successful chunk uploads:\n            // chunkdone: function (e, data) {}, // .bind('fileuploadchunkdone', func);\n\n            // Callback for failed (abort or error) chunk uploads:\n            // chunkfail: function (e, data) {}, // .bind('fileuploadchunkfail', func);\n\n            // Callback for completed (success, abort or error) chunk upload requests:\n            // chunkalways: function (e, data) {}, // .bind('fileuploadchunkalways', func);\n\n            // The plugin options are used as settings object for the ajax calls.\n            // The following are jQuery ajax settings required for the file uploads:\n            processData: false,\n            contentType: false,\n            cache: false,\n            timeout: 0\n        },\n\n        // A list of options that require reinitializing event listeners and/or\n        // special initialization code:\n        _specialOptions: [\n            'fileInput',\n            'dropZone',\n            'pasteZone',\n            'multipart',\n            'forceIframeTransport'\n        ],\n\n        _blobSlice: $.support.blobSlice && function () {\n            var slice = this.slice || this.webkitSlice || this.mozSlice;\n            return slice.apply(this, arguments);\n        },\n\n        _BitrateTimer: function () {\n            this.timestamp = ((Date.now) ? Date.now() : (new Date()).getTime());\n            this.loaded = 0;\n            this.bitrate = 0;\n            this.getBitrate = function (now, loaded, interval) {\n                var timeDiff = now - this.timestamp;\n                if (!this.bitrate || !interval || timeDiff > interval) {\n                    this.bitrate = (loaded - this.loaded) * (1000 / timeDiff) * 8;\n                    this.loaded = loaded;\n                    this.timestamp = now;\n                }\n                return this.bitrate;\n            };\n        },\n\n        _isXHRUpload: function (options) {\n            return !options.forceIframeTransport &&\n                ((!options.multipart && $.support.xhrFileUpload) ||\n                $.support.xhrFormDataFileUpload);\n        },\n\n        _getFormData: function (options) {\n            var formData;\n            if ($.type(options.formData) === 'function') {\n                return options.formData(options.form);\n            }\n            if ($.isArray(options.formData)) {\n                return options.formData;\n            }\n            if ($.type(options.formData) === 'object') {\n                formData = [];\n                $.each(options.formData, function (name, value) {\n                    formData.push({name: name, value: value});\n                });\n                return formData;\n            }\n            return [];\n        },\n\n        _getTotal: function (files) {\n            var total = 0;\n            $.each(files, function (index, file) {\n                total += file.size || 1;\n            });\n            return total;\n        },\n\n        _initProgressObject: function (obj) {\n            var progress = {\n                loaded: 0,\n                total: 0,\n                bitrate: 0\n            };\n            if (obj._progress) {\n                $.extend(obj._progress, progress);\n            } else {\n                obj._progress = progress;\n            }\n        },\n\n        _initResponseObject: function (obj) {\n            var prop;\n            if (obj._response) {\n                for (prop in obj._response) {\n                    if (obj._response.hasOwnProperty(prop)) {\n                        delete obj._response[prop];\n                    }\n                }\n            } else {\n                obj._response = {};\n            }\n        },\n\n        _onProgress: function (e, data) {\n            if (e.lengthComputable) {\n                var now = ((Date.now) ? Date.now() : (new Date()).getTime()),\n                    loaded;\n                if (data._time && data.progressInterval &&\n                        (now - data._time < data.progressInterval) &&\n                        e.loaded !== e.total) {\n                    return;\n                }\n                data._time = now;\n                loaded = Math.floor(\n                    e.loaded / e.total * (data.chunkSize || data._progress.total)\n                ) + (data.uploadedBytes || 0);\n                // Add the difference from the previously loaded state\n                // to the global loaded counter:\n                this._progress.loaded += (loaded - data._progress.loaded);\n                this._progress.bitrate = this._bitrateTimer.getBitrate(\n                    now,\n                    this._progress.loaded,\n                    data.bitrateInterval\n                );\n                data._progress.loaded = data.loaded = loaded;\n                data._progress.bitrate = data.bitrate = data._bitrateTimer.getBitrate(\n                    now,\n                    loaded,\n                    data.bitrateInterval\n                );\n                // Trigger a custom progress event with a total data property set\n                // to the file size(s) of the current upload and a loaded data\n                // property calculated accordingly:\n                this._trigger(\n                    'progress',\n                    $.Event('progress', {delegatedEvent: e}),\n                    data\n                );\n                // Trigger a global progress event for all current file uploads,\n                // including ajax calls queued for sequential file uploads:\n                this._trigger(\n                    'progressall',\n                    $.Event('progressall', {delegatedEvent: e}),\n                    this._progress\n                );\n            }\n        },\n\n        _initProgressListener: function (options) {\n            var that = this,\n                xhr = options.xhr ? options.xhr() : $.ajaxSettings.xhr();\n            // Accesss to the native XHR object is required to add event listeners\n            // for the upload progress event:\n            if (xhr.upload) {\n                $(xhr.upload).bind('progress', function (e) {\n                    var oe = e.originalEvent;\n                    // Make sure the progress event properties get copied over:\n                    e.lengthComputable = oe.lengthComputable;\n                    e.loaded = oe.loaded;\n                    e.total = oe.total;\n                    that._onProgress(e, options);\n                });\n                options.xhr = function () {\n                    return xhr;\n                };\n            }\n        },\n\n        _isInstanceOf: function (type, obj) {\n            // Cross-frame instanceof check\n            return Object.prototype.toString.call(obj) === '[object ' + type + ']';\n        },\n\n        _initXHRData: function (options) {\n            var that = this,\n                formData,\n                file = options.files[0],\n                // Ignore non-multipart setting if not supported:\n                multipart = options.multipart || !$.support.xhrFileUpload,\n                paramName = $.type(options.paramName) === 'array' ?\n                    options.paramName[0] : options.paramName;\n            options.headers = $.extend({}, options.headers);\n            if (options.contentRange) {\n                options.headers['Content-Range'] = options.contentRange;\n            }\n            if (!multipart || options.blob || !this._isInstanceOf('File', file)) {\n                options.headers['Content-Disposition'] = 'attachment; filename=\"' +\n                    encodeURI(file.name) + '\"';\n            }\n            if (!multipart) {\n                options.contentType = file.type || 'application/octet-stream';\n                options.data = options.blob || file;\n            } else if ($.support.xhrFormDataFileUpload) {\n                if (options.postMessage) {\n                    // window.postMessage does not allow sending FormData\n                    // objects, so we just add the File/Blob objects to\n                    // the formData array and let the postMessage window\n                    // create the FormData object out of this array:\n                    formData = this._getFormData(options);\n                    if (options.blob) {\n                        formData.push({\n                            name: paramName,\n                            value: options.blob\n                        });\n                    } else {\n                        $.each(options.files, function (index, file) {\n                            formData.push({\n                                name: ($.type(options.paramName) === 'array' &&\n                                    options.paramName[index]) || paramName,\n                                value: file\n                            });\n                        });\n                    }\n                } else {\n                    if (that._isInstanceOf('FormData', options.formData)) {\n                        formData = options.formData;\n                    } else {\n                        formData = new FormData();\n                        $.each(this._getFormData(options), function (index, field) {\n                            formData.append(field.name, field.value);\n                        });\n                    }\n                    if (options.blob) {\n                        formData.append(paramName, options.blob, file.name);\n                    } else {\n                        $.each(options.files, function (index, file) {\n                            // This check allows the tests to run with\n                            // dummy objects:\n                            if (that._isInstanceOf('File', file) ||\n                                    that._isInstanceOf('Blob', file)) {\n                                formData.append(\n                                    ($.type(options.paramName) === 'array' &&\n                                        options.paramName[index]) || paramName,\n                                    file,\n                                    file.uploadName || file.name\n                                );\n                            }\n                        });\n                    }\n                }\n                options.data = formData;\n            }\n            // Blob reference is not needed anymore, free memory:\n            options.blob = null;\n        },\n\n        _initIframeSettings: function (options) {\n            var targetHost = $('<a></a>').prop('href', options.url).prop('host');\n            // Setting the dataType to iframe enables the iframe transport:\n            options.dataType = 'iframe ' + (options.dataType || '');\n            // The iframe transport accepts a serialized array as form data:\n            options.formData = this._getFormData(options);\n            // Add redirect url to form data on cross-domain uploads:\n            if (options.redirect && targetHost && targetHost !== location.host) {\n                options.formData.push({\n                    name: options.redirectParamName || 'redirect',\n                    value: options.redirect\n                });\n            }\n        },\n\n        _initDataSettings: function (options) {\n            if (this._isXHRUpload(options)) {\n                if (!this._chunkedUpload(options, true)) {\n                    if (!options.data) {\n                        this._initXHRData(options);\n                    }\n                    this._initProgressListener(options);\n                }\n                if (options.postMessage) {\n                    // Setting the dataType to postmessage enables the\n                    // postMessage transport:\n                    options.dataType = 'postmessage ' + (options.dataType || '');\n                }\n            } else {\n                this._initIframeSettings(options);\n            }\n        },\n\n        _getParamName: function (options) {\n            var fileInput = $(options.fileInput),\n                paramName = options.paramName;\n            if (!paramName) {\n                paramName = [];\n                fileInput.each(function () {\n                    var input = $(this),\n                        name = input.prop('name') || 'files[]',\n                        i = (input.prop('files') || [1]).length;\n                    while (i) {\n                        paramName.push(name);\n                        i -= 1;\n                    }\n                });\n                if (!paramName.length) {\n                    paramName = [fileInput.prop('name') || 'files[]'];\n                }\n            } else if (!$.isArray(paramName)) {\n                paramName = [paramName];\n            }\n            return paramName;\n        },\n\n        _initFormSettings: function (options) {\n            // Retrieve missing options from the input field and the\n            // associated form, if available:\n            if (!options.form || !options.form.length) {\n                options.form = $(options.fileInput.prop('form'));\n                // If the given file input doesn't have an associated form,\n                // use the default widget file input's form:\n                if (!options.form.length) {\n                    options.form = $(this.options.fileInput.prop('form'));\n                }\n            }\n            options.paramName = this._getParamName(options);\n            if (!options.url) {\n                options.url = options.form.prop('action') || location.href;\n            }\n            // The HTTP request method must be \"POST\" or \"PUT\":\n            options.type = (options.type ||\n                ($.type(options.form.prop('method')) === 'string' &&\n                    options.form.prop('method')) || ''\n                ).toUpperCase();\n            if (options.type !== 'POST' && options.type !== 'PUT' &&\n                    options.type !== 'PATCH') {\n                options.type = 'POST';\n            }\n            if (!options.formAcceptCharset) {\n                options.formAcceptCharset = options.form.attr('accept-charset');\n            }\n        },\n\n        _getAJAXSettings: function (data) {\n            var options = $.extend({}, this.options, data);\n            this._initFormSettings(options);\n            this._initDataSettings(options);\n            return options;\n        },\n\n        // jQuery 1.6 doesn't provide .state(),\n        // while jQuery 1.8+ removed .isRejected() and .isResolved():\n        _getDeferredState: function (deferred) {\n            if (deferred.state) {\n                return deferred.state();\n            }\n            if (deferred.isResolved()) {\n                return 'resolved';\n            }\n            if (deferred.isRejected()) {\n                return 'rejected';\n            }\n            return 'pending';\n        },\n\n        // Maps jqXHR callbacks to the equivalent\n        // methods of the given Promise object:\n        _enhancePromise: function (promise) {\n            promise.success = promise.done;\n            promise.error = promise.fail;\n            promise.complete = promise.always;\n            return promise;\n        },\n\n        // Creates and returns a Promise object enhanced with\n        // the jqXHR methods abort, success, error and complete:\n        _getXHRPromise: function (resolveOrReject, context, args) {\n            var dfd = $.Deferred(),\n                promise = dfd.promise();\n            context = context || this.options.context || promise;\n            if (resolveOrReject === true) {\n                dfd.resolveWith(context, args);\n            } else if (resolveOrReject === false) {\n                dfd.rejectWith(context, args);\n            }\n            promise.abort = dfd.promise;\n            return this._enhancePromise(promise);\n        },\n\n        // Adds convenience methods to the data callback argument:\n        _addConvenienceMethods: function (e, data) {\n            var that = this,\n                getPromise = function (args) {\n                    return $.Deferred().resolveWith(that, args).promise();\n                };\n            data.process = function (resolveFunc, rejectFunc) {\n                if (resolveFunc || rejectFunc) {\n                    data._processQueue = this._processQueue =\n                        (this._processQueue || getPromise([this])).then(\n                            function () {\n                                if (data.errorThrown) {\n                                    return $.Deferred()\n                                        .rejectWith(that, [data]).promise();\n                                }\n                                return getPromise(arguments);\n                            }\n                        ).then(resolveFunc, rejectFunc);\n                }\n                return this._processQueue || getPromise([this]);\n            };\n            data.submit = function () {\n                if (this.state() !== 'pending') {\n                    data.jqXHR = this.jqXHR =\n                        (that._trigger(\n                            'submit',\n                            $.Event('submit', {delegatedEvent: e}),\n                            this\n                        ) !== false) && that._onSend(e, this);\n                }\n                return this.jqXHR || that._getXHRPromise();\n            };\n            data.abort = function () {\n                if (this.jqXHR) {\n                    return this.jqXHR.abort();\n                }\n                this.errorThrown = 'abort';\n                that._trigger('fail', null, this);\n                return that._getXHRPromise(false);\n            };\n            data.state = function () {\n                if (this.jqXHR) {\n                    return that._getDeferredState(this.jqXHR);\n                }\n                if (this._processQueue) {\n                    return that._getDeferredState(this._processQueue);\n                }\n            };\n            data.processing = function () {\n                return !this.jqXHR && this._processQueue && that\n                    ._getDeferredState(this._processQueue) === 'pending';\n            };\n            data.progress = function () {\n                return this._progress;\n            };\n            data.response = function () {\n                return this._response;\n            };\n        },\n\n        // Parses the Range header from the server response\n        // and returns the uploaded bytes:\n        _getUploadedBytes: function (jqXHR) {\n            var range = jqXHR.getResponseHeader('Range'),\n                parts = range && range.split('-'),\n                upperBytesPos = parts && parts.length > 1 &&\n                    parseInt(parts[1], 10);\n            return upperBytesPos && upperBytesPos + 1;\n        },\n\n        // Uploads a file in multiple, sequential requests\n        // by splitting the file up in multiple blob chunks.\n        // If the second parameter is true, only tests if the file\n        // should be uploaded in chunks, but does not invoke any\n        // upload requests:\n        _chunkedUpload: function (options, testOnly) {\n            options.uploadedBytes = options.uploadedBytes || 0;\n            var that = this,\n                file = options.files[0],\n                fs = file.size,\n                ub = options.uploadedBytes,\n                mcs = options.maxChunkSize || fs,\n                slice = this._blobSlice,\n                dfd = $.Deferred(),\n                promise = dfd.promise(),\n                jqXHR,\n                upload;\n            if (!(this._isXHRUpload(options) && slice && (ub || mcs < fs)) ||\n                    options.data) {\n                return false;\n            }\n            if (testOnly) {\n                return true;\n            }\n            if (ub >= fs) {\n                file.error = options.i18n('uploadedBytes');\n                return this._getXHRPromise(\n                    false,\n                    options.context,\n                    [null, 'error', file.error]\n                );\n            }\n            // The chunk upload method:\n            upload = function () {\n                // Clone the options object for each chunk upload:\n                var o = $.extend({}, options),\n                    currentLoaded = o._progress.loaded;\n                o.blob = slice.call(\n                    file,\n                    ub,\n                    ub + mcs,\n                    file.type\n                );\n                // Store the current chunk size, as the blob itself\n                // will be dereferenced after data processing:\n                o.chunkSize = o.blob.size;\n                // Expose the chunk bytes position range:\n                o.contentRange = 'bytes ' + ub + '-' +\n                    (ub + o.chunkSize - 1) + '/' + fs;\n                // Process the upload data (the blob and potential form data):\n                that._initXHRData(o);\n                // Add progress listeners for this chunk upload:\n                that._initProgressListener(o);\n                jqXHR = ((that._trigger('chunksend', null, o) !== false && $.ajax(o)) ||\n                        that._getXHRPromise(false, o.context))\n                    .done(function (result, textStatus, jqXHR) {\n                        ub = that._getUploadedBytes(jqXHR) ||\n                            (ub + o.chunkSize);\n                        // Create a progress event if no final progress event\n                        // with loaded equaling total has been triggered\n                        // for this chunk:\n                        if (currentLoaded + o.chunkSize - o._progress.loaded) {\n                            that._onProgress($.Event('progress', {\n                                lengthComputable: true,\n                                loaded: ub - o.uploadedBytes,\n                                total: ub - o.uploadedBytes\n                            }), o);\n                        }\n                        options.uploadedBytes = o.uploadedBytes = ub;\n                        o.result = result;\n                        o.textStatus = textStatus;\n                        o.jqXHR = jqXHR;\n                        that._trigger('chunkdone', null, o);\n                        that._trigger('chunkalways', null, o);\n                        if (ub < fs) {\n                            // File upload not yet complete,\n                            // continue with the next chunk:\n                            upload();\n                        } else {\n                            dfd.resolveWith(\n                                o.context,\n                                [result, textStatus, jqXHR]\n                            );\n                        }\n                    })\n                    .fail(function (jqXHR, textStatus, errorThrown) {\n                        o.jqXHR = jqXHR;\n                        o.textStatus = textStatus;\n                        o.errorThrown = errorThrown;\n                        that._trigger('chunkfail', null, o);\n                        that._trigger('chunkalways', null, o);\n                        dfd.rejectWith(\n                            o.context,\n                            [jqXHR, textStatus, errorThrown]\n                        );\n                    });\n            };\n            this._enhancePromise(promise);\n            promise.abort = function () {\n                return jqXHR.abort();\n            };\n            upload();\n            return promise;\n        },\n\n        _beforeSend: function (e, data) {\n            if (this._active === 0) {\n                // the start callback is triggered when an upload starts\n                // and no other uploads are currently running,\n                // equivalent to the global ajaxStart event:\n                this._trigger('start');\n                // Set timer for global bitrate progress calculation:\n                this._bitrateTimer = new this._BitrateTimer();\n                // Reset the global progress values:\n                this._progress.loaded = this._progress.total = 0;\n                this._progress.bitrate = 0;\n            }\n            // Make sure the container objects for the .response() and\n            // .progress() methods on the data object are available\n            // and reset to their initial state:\n            this._initResponseObject(data);\n            this._initProgressObject(data);\n            data._progress.loaded = data.loaded = data.uploadedBytes || 0;\n            data._progress.total = data.total = this._getTotal(data.files) || 1;\n            data._progress.bitrate = data.bitrate = 0;\n            this._active += 1;\n            // Initialize the global progress values:\n            this._progress.loaded += data.loaded;\n            this._progress.total += data.total;\n        },\n\n        _onDone: function (result, textStatus, jqXHR, options) {\n            var total = options._progress.total,\n                response = options._response;\n            if (options._progress.loaded < total) {\n                // Create a progress event if no final progress event\n                // with loaded equaling total has been triggered:\n                this._onProgress($.Event('progress', {\n                    lengthComputable: true,\n                    loaded: total,\n                    total: total\n                }), options);\n            }\n            response.result = options.result = result;\n            response.textStatus = options.textStatus = textStatus;\n            response.jqXHR = options.jqXHR = jqXHR;\n            this._trigger('done', null, options);\n        },\n\n        _onFail: function (jqXHR, textStatus, errorThrown, options) {\n            var response = options._response;\n            if (options.recalculateProgress) {\n                // Remove the failed (error or abort) file upload from\n                // the global progress calculation:\n                this._progress.loaded -= options._progress.loaded;\n                this._progress.total -= options._progress.total;\n            }\n            response.jqXHR = options.jqXHR = jqXHR;\n            response.textStatus = options.textStatus = textStatus;\n            response.errorThrown = options.errorThrown = errorThrown;\n            this._trigger('fail', null, options);\n        },\n\n        _onAlways: function (jqXHRorResult, textStatus, jqXHRorError, options) {\n            // jqXHRorResult, textStatus and jqXHRorError are added to the\n            // options object via done and fail callbacks\n            this._trigger('always', null, options);\n        },\n\n        _onSend: function (e, data) {\n            if (!data.submit) {\n                this._addConvenienceMethods(e, data);\n            }\n            var that = this,\n                jqXHR,\n                aborted,\n                slot,\n                pipe,\n                options = that._getAJAXSettings(data),\n                send = function () {\n                    that._sending += 1;\n                    // Set timer for bitrate progress calculation:\n                    options._bitrateTimer = new that._BitrateTimer();\n                    jqXHR = jqXHR || (\n                        ((aborted || that._trigger(\n                            'send',\n                            $.Event('send', {delegatedEvent: e}),\n                            options\n                        ) === false) &&\n                        that._getXHRPromise(false, options.context, aborted)) ||\n                        that._chunkedUpload(options) || $.ajax(options)\n                    ).done(function (result, textStatus, jqXHR) {\n                        that._onDone(result, textStatus, jqXHR, options);\n                    }).fail(function (jqXHR, textStatus, errorThrown) {\n                        that._onFail(jqXHR, textStatus, errorThrown, options);\n                    }).always(function (jqXHRorResult, textStatus, jqXHRorError) {\n                        that._onAlways(\n                            jqXHRorResult,\n                            textStatus,\n                            jqXHRorError,\n                            options\n                        );\n                        that._sending -= 1;\n                        that._active -= 1;\n                        if (options.limitConcurrentUploads &&\n                                options.limitConcurrentUploads > that._sending) {\n                            // Start the next queued upload,\n                            // that has not been aborted:\n                            var nextSlot = that._slots.shift();\n                            while (nextSlot) {\n                                if (that._getDeferredState(nextSlot) === 'pending') {\n                                    nextSlot.resolve();\n                                    break;\n                                }\n                                nextSlot = that._slots.shift();\n                            }\n                        }\n                        if (that._active === 0) {\n                            // The stop callback is triggered when all uploads have\n                            // been completed, equivalent to the global ajaxStop event:\n                            that._trigger('stop');\n                        }\n                    });\n                    return jqXHR;\n                };\n            this._beforeSend(e, options);\n            if (this.options.sequentialUploads ||\n                    (this.options.limitConcurrentUploads &&\n                    this.options.limitConcurrentUploads <= this._sending)) {\n                if (this.options.limitConcurrentUploads > 1) {\n                    slot = $.Deferred();\n                    this._slots.push(slot);\n                    pipe = slot.then(send);\n                } else {\n                    this._sequence = this._sequence.then(send, send);\n                    pipe = this._sequence;\n                }\n                // Return the piped Promise object, enhanced with an abort method,\n                // which is delegated to the jqXHR object of the current upload,\n                // and jqXHR callbacks mapped to the equivalent Promise methods:\n                pipe.abort = function () {\n                    aborted = [undefined, 'abort', 'abort'];\n                    if (!jqXHR) {\n                        if (slot) {\n                            slot.rejectWith(options.context, aborted);\n                        }\n                        return send();\n                    }\n                    return jqXHR.abort();\n                };\n                return this._enhancePromise(pipe);\n            }\n            return send();\n        },\n\n        _onAdd: function (e, data) {\n            var that = this,\n                result = true,\n                options = $.extend({}, this.options, data),\n                files = data.files,\n                filesLength = files.length,\n                limit = options.limitMultiFileUploads,\n                limitSize = options.limitMultiFileUploadSize,\n                overhead = options.limitMultiFileUploadSizeOverhead,\n                batchSize = 0,\n                paramName = this._getParamName(options),\n                paramNameSet,\n                paramNameSlice,\n                fileSet,\n                i,\n                j = 0;\n            if (!filesLength) {\n                return false;\n            }\n            if (limitSize && files[0].size === undefined) {\n                limitSize = undefined;\n            }\n            if (!(options.singleFileUploads || limit || limitSize) ||\n                    !this._isXHRUpload(options)) {\n                fileSet = [files];\n                paramNameSet = [paramName];\n            } else if (!(options.singleFileUploads || limitSize) && limit) {\n                fileSet = [];\n                paramNameSet = [];\n                for (i = 0; i < filesLength; i += limit) {\n                    fileSet.push(files.slice(i, i + limit));\n                    paramNameSlice = paramName.slice(i, i + limit);\n                    if (!paramNameSlice.length) {\n                        paramNameSlice = paramName;\n                    }\n                    paramNameSet.push(paramNameSlice);\n                }\n            } else if (!options.singleFileUploads && limitSize) {\n                fileSet = [];\n                paramNameSet = [];\n                for (i = 0; i < filesLength; i = i + 1) {\n                    batchSize += files[i].size + overhead;\n                    if (i + 1 === filesLength ||\n                            ((batchSize + files[i + 1].size + overhead) > limitSize) ||\n                            (limit && i + 1 - j >= limit)) {\n                        fileSet.push(files.slice(j, i + 1));\n                        paramNameSlice = paramName.slice(j, i + 1);\n                        if (!paramNameSlice.length) {\n                            paramNameSlice = paramName;\n                        }\n                        paramNameSet.push(paramNameSlice);\n                        j = i + 1;\n                        batchSize = 0;\n                    }\n                }\n            } else {\n                paramNameSet = paramName;\n            }\n            data.originalFiles = files;\n            $.each(fileSet || files, function (index, element) {\n                var newData = $.extend({}, data);\n                newData.files = fileSet ? element : [element];\n                newData.paramName = paramNameSet[index];\n                that._initResponseObject(newData);\n                that._initProgressObject(newData);\n                that._addConvenienceMethods(e, newData);\n                result = that._trigger(\n                    'add',\n                    $.Event('add', {delegatedEvent: e}),\n                    newData\n                );\n                return result;\n            });\n            return result;\n        },\n\n        _replaceFileInput: function (data) {\n            var input = data.fileInput,\n                inputClone = input.clone(true),\n                restoreFocus = input.is(document.activeElement);\n            // Add a reference for the new cloned file input to the data argument:\n            data.fileInputClone = inputClone;\n            $('<form></form>').append(inputClone)[0].reset();\n            // Detaching allows to insert the fileInput on another form\n            // without loosing the file input value:\n            input.after(inputClone).detach();\n            // If the fileInput had focus before it was detached,\n            // restore focus to the inputClone.\n            if (restoreFocus) {\n                inputClone.focus();\n            }\n            // Avoid memory leaks with the detached file input:\n            $.cleanData(input.unbind('remove'));\n            // Replace the original file input element in the fileInput\n            // elements set with the clone, which has been copied including\n            // event handlers:\n            this.options.fileInput = this.options.fileInput.map(function (i, el) {\n                if (el === input[0]) {\n                    return inputClone[0];\n                }\n                return el;\n            });\n            // If the widget has been initialized on the file input itself,\n            // override this.element with the file input clone:\n            if (input[0] === this.element[0]) {\n                this.element = inputClone;\n            }\n        },\n\n        _handleFileTreeEntry: function (entry, path) {\n            var that = this,\n                dfd = $.Deferred(),\n                entries = [],\n                dirReader,\n                errorHandler = function (e) {\n                    if (e && !e.entry) {\n                        e.entry = entry;\n                    }\n                    // Since $.when returns immediately if one\n                    // Deferred is rejected, we use resolve instead.\n                    // This allows valid files and invalid items\n                    // to be returned together in one set:\n                    dfd.resolve([e]);\n                },\n                successHandler = function (entries) {\n                    that._handleFileTreeEntries(\n                        entries,\n                        path + entry.name + '/'\n                    ).done(function (files) {\n                        dfd.resolve(files);\n                    }).fail(errorHandler);\n                },\n                readEntries = function () {\n                    dirReader.readEntries(function (results) {\n                        if (!results.length) {\n                            successHandler(entries);\n                        } else {\n                            entries = entries.concat(results);\n                            readEntries();\n                        }\n                    }, errorHandler);\n                };\n            path = path || '';\n            if (entry.isFile) {\n                if (entry._file) {\n                    // Workaround for Chrome bug #149735\n                    entry._file.relativePath = path;\n                    dfd.resolve(entry._file);\n                } else {\n                    entry.file(function (file) {\n                        file.relativePath = path;\n                        dfd.resolve(file);\n                    }, errorHandler);\n                }\n            } else if (entry.isDirectory) {\n                dirReader = entry.createReader();\n                readEntries();\n            } else {\n                // Return an empy list for file system items\n                // other than files or directories:\n                dfd.resolve([]);\n            }\n            return dfd.promise();\n        },\n\n        _handleFileTreeEntries: function (entries, path) {\n            var that = this;\n            return $.when.apply(\n                $,\n                $.map(entries, function (entry) {\n                    return that._handleFileTreeEntry(entry, path);\n                })\n            ).then(function () {\n                return Array.prototype.concat.apply(\n                    [],\n                    arguments\n                );\n            });\n        },\n\n        _getDroppedFiles: function (dataTransfer) {\n            dataTransfer = dataTransfer || {};\n            var items = dataTransfer.items;\n            if (items && items.length && (items[0].webkitGetAsEntry ||\n                    items[0].getAsEntry)) {\n                return this._handleFileTreeEntries(\n                    $.map(items, function (item) {\n                        var entry;\n                        if (item.webkitGetAsEntry) {\n                            entry = item.webkitGetAsEntry();\n                            if (entry) {\n                                // Workaround for Chrome bug #149735:\n                                entry._file = item.getAsFile();\n                            }\n                            return entry;\n                        }\n                        return item.getAsEntry();\n                    })\n                );\n            }\n            return $.Deferred().resolve(\n                $.makeArray(dataTransfer.files)\n            ).promise();\n        },\n\n        _getSingleFileInputFiles: function (fileInput) {\n            fileInput = $(fileInput);\n            var entries = fileInput.prop('webkitEntries') ||\n                    fileInput.prop('entries'),\n                files,\n                value;\n            if (entries && entries.length) {\n                return this._handleFileTreeEntries(entries);\n            }\n            files = $.makeArray(fileInput.prop('files'));\n            if (!files.length) {\n                value = fileInput.prop('value');\n                if (!value) {\n                    return $.Deferred().resolve([]).promise();\n                }\n                // If the files property is not available, the browser does not\n                // support the File API and we add a pseudo File object with\n                // the input value as name with path information removed:\n                files = [{name: value.replace(/^.*\\\\/, '')}];\n            } else if (files[0].name === undefined && files[0].fileName) {\n                // File normalization for Safari 4 and Firefox 3:\n                $.each(files, function (index, file) {\n                    file.name = file.fileName;\n                    file.size = file.fileSize;\n                });\n            }\n            return $.Deferred().resolve(files).promise();\n        },\n\n        _getFileInputFiles: function (fileInput) {\n            if (!(fileInput instanceof $) || fileInput.length === 1) {\n                return this._getSingleFileInputFiles(fileInput);\n            }\n            return $.when.apply(\n                $,\n                $.map(fileInput, this._getSingleFileInputFiles)\n            ).then(function () {\n                return Array.prototype.concat.apply(\n                    [],\n                    arguments\n                );\n            });\n        },\n\n        _onChange: function (e) {\n            var that = this,\n                data = {\n                    fileInput: $(e.target),\n                    form: $(e.target.form)\n                };\n            this._getFileInputFiles(data.fileInput).always(function (files) {\n                data.files = files;\n                if (that.options.replaceFileInput) {\n                    that._replaceFileInput(data);\n                }\n                if (that._trigger(\n                        'change',\n                        $.Event('change', {delegatedEvent: e}),\n                        data\n                    ) !== false) {\n                    that._onAdd(e, data);\n                }\n            });\n        },\n\n        _onPaste: function (e) {\n            var items = e.originalEvent && e.originalEvent.clipboardData &&\n                    e.originalEvent.clipboardData.items,\n                data = {files: []};\n            if (items && items.length) {\n                $.each(items, function (index, item) {\n                    var file = item.getAsFile && item.getAsFile();\n                    if (file) {\n                        data.files.push(file);\n                    }\n                });\n                if (this._trigger(\n                        'paste',\n                        $.Event('paste', {delegatedEvent: e}),\n                        data\n                    ) !== false) {\n                    this._onAdd(e, data);\n                }\n            }\n        },\n\n        _onDrop: function (e) {\n            e.dataTransfer = e.originalEvent && e.originalEvent.dataTransfer;\n            var that = this,\n                dataTransfer = e.dataTransfer,\n                data = {};\n            if (dataTransfer && dataTransfer.files && dataTransfer.files.length) {\n                e.preventDefault();\n                this._getDroppedFiles(dataTransfer).always(function (files) {\n                    data.files = files;\n                    if (that._trigger(\n                            'drop',\n                            $.Event('drop', {delegatedEvent: e}),\n                            data\n                        ) !== false) {\n                        that._onAdd(e, data);\n                    }\n                });\n            }\n        },\n\n        _onDragOver: getDragHandler('dragover'),\n\n        _onDragEnter: getDragHandler('dragenter'),\n\n        _onDragLeave: getDragHandler('dragleave'),\n\n        _initEventHandlers: function () {\n            if (this._isXHRUpload(this.options)) {\n                this._on(this.options.dropZone, {\n                    dragover: this._onDragOver,\n                    drop: this._onDrop,\n                    // event.preventDefault() on dragenter is required for IE10+:\n                    dragenter: this._onDragEnter,\n                    // dragleave is not required, but added for completeness:\n                    dragleave: this._onDragLeave\n                });\n                this._on(this.options.pasteZone, {\n                    paste: this._onPaste\n                });\n            }\n            if ($.support.fileInput) {\n                this._on(this.options.fileInput, {\n                    change: this._onChange\n                });\n            }\n        },\n\n        _destroyEventHandlers: function () {\n            this._off(this.options.dropZone, 'dragenter dragleave dragover drop');\n            this._off(this.options.pasteZone, 'paste');\n            this._off(this.options.fileInput, 'change');\n        },\n\n        _destroy: function () {\n            this._destroyEventHandlers();\n        },\n\n        _setOption: function (key, value) {\n            var reinit = $.inArray(key, this._specialOptions) !== -1;\n            if (reinit) {\n                this._destroyEventHandlers();\n            }\n            this._super(key, value);\n            if (reinit) {\n                this._initSpecialOptions();\n                this._initEventHandlers();\n            }\n        },\n\n        _initSpecialOptions: function () {\n            var options = this.options;\n            if (options.fileInput === undefined) {\n                options.fileInput = this.element.is('input[type=\"file\"]') ?\n                        this.element : this.element.find('input[type=\"file\"]');\n            } else if (!(options.fileInput instanceof $)) {\n                options.fileInput = $(options.fileInput);\n            }\n            if (!(options.dropZone instanceof $)) {\n                options.dropZone = $(options.dropZone);\n            }\n            if (!(options.pasteZone instanceof $)) {\n                options.pasteZone = $(options.pasteZone);\n            }\n        },\n\n        _getRegExp: function (str) {\n            var parts = str.split('/'),\n                modifiers = parts.pop();\n            parts.shift();\n            return new RegExp(parts.join('/'), modifiers);\n        },\n\n        _isRegExpOption: function (key, value) {\n            return key !== 'url' && $.type(value) === 'string' &&\n                /^\\/.*\\/[igm]{0,3}$/.test(value);\n        },\n\n        _initDataAttributes: function () {\n            var that = this,\n                options = this.options,\n                data = this.element.data();\n            // Initialize options set via HTML5 data-attributes:\n            $.each(\n                this.element[0].attributes,\n                function (index, attr) {\n                    var key = attr.name.toLowerCase(),\n                        value;\n                    if (/^data-/.test(key)) {\n                        // Convert hyphen-ated key to camelCase:\n                        key = key.slice(5).replace(/-[a-z]/g, function (str) {\n                            return str.charAt(1).toUpperCase();\n                        });\n                        value = data[key];\n                        if (that._isRegExpOption(key, value)) {\n                            value = that._getRegExp(value);\n                        }\n                        options[key] = value;\n                    }\n                }\n            );\n        },\n\n        _create: function () {\n            this._initDataAttributes();\n            this._initSpecialOptions();\n            this._slots = [];\n            this._sequence = this._getXHRPromise(true);\n            this._sending = this._active = 0;\n            this._initProgressObject(this);\n            this._initEventHandlers();\n        },\n\n        // This method is exposed to the widget API and allows to query\n        // the number of active uploads:\n        active: function () {\n            return this._active;\n        },\n\n        // This method is exposed to the widget API and allows to query\n        // the widget upload progress.\n        // It returns an object with loaded, total and bitrate properties\n        // for the running uploads:\n        progress: function () {\n            return this._progress;\n        },\n\n        // This method is exposed to the widget API and allows adding files\n        // using the fileupload API. The data parameter accepts an object which\n        // must have a files property and can contain additional options:\n        // .fileupload('add', {files: filesList});\n        add: function (data) {\n            var that = this;\n            if (!data || this.options.disabled) {\n                return;\n            }\n            if (data.fileInput && !data.files) {\n                this._getFileInputFiles(data.fileInput).always(function (files) {\n                    data.files = files;\n                    that._onAdd(null, data);\n                });\n            } else {\n                data.files = $.makeArray(data.files);\n                this._onAdd(null, data);\n            }\n        },\n\n        // This method is exposed to the widget API and allows sending files\n        // using the fileupload API. The data parameter accepts an object which\n        // must have a files or fileInput property and can contain additional options:\n        // .fileupload('send', {files: filesList});\n        // The method returns a Promise object for the file upload call.\n        send: function (data) {\n            if (data && !this.options.disabled) {\n                if (data.fileInput && !data.files) {\n                    var that = this,\n                        dfd = $.Deferred(),\n                        promise = dfd.promise(),\n                        jqXHR,\n                        aborted;\n                    promise.abort = function () {\n                        aborted = true;\n                        if (jqXHR) {\n                            return jqXHR.abort();\n                        }\n                        dfd.reject(null, 'abort', 'abort');\n                        return promise;\n                    };\n                    this._getFileInputFiles(data.fileInput).always(\n                        function (files) {\n                            if (aborted) {\n                                return;\n                            }\n                            if (!files.length) {\n                                dfd.reject();\n                                return;\n                            }\n                            data.files = files;\n                            jqXHR = that._onSend(null, data);\n                            jqXHR.then(\n                                function (result, textStatus, jqXHR) {\n                                    dfd.resolve(result, textStatus, jqXHR);\n                                },\n                                function (jqXHR, textStatus, errorThrown) {\n                                    dfd.reject(jqXHR, textStatus, errorThrown);\n                                }\n                            );\n                        }\n                    );\n                    return this._enhancePromise(promise);\n                }\n                data.files = $.makeArray(data.files);\n                if (data.files.length) {\n                    return this._onSend(null, data);\n                }\n            }\n            return this._getXHRPromise(false, data && data.context);\n        }\n\n    });\n\n}));\n"
  },
  {
    "path": "app_backend/static/plugin/jQuery-File-Upload-9.18.0/js/jquery.iframe-transport.js",
    "content": "/*\n * jQuery Iframe Transport Plugin\n * https://github.com/blueimp/jQuery-File-Upload\n *\n * Copyright 2011, Sebastian Tschan\n * https://blueimp.net\n *\n * Licensed under the MIT license:\n * https://opensource.org/licenses/MIT\n */\n\n/* global define, require, window, document, JSON */\n\n;(function (factory) {\n    'use strict';\n    if (typeof define === 'function' && define.amd) {\n        // Register as an anonymous AMD module:\n        define(['jquery'], factory);\n    } else if (typeof exports === 'object') {\n        // Node/CommonJS:\n        factory(require('jquery'));\n    } else {\n        // Browser globals:\n        factory(window.jQuery);\n    }\n}(function ($) {\n    'use strict';\n\n    // Helper variable to create unique names for the transport iframes:\n    var counter = 0,\n        jsonAPI = $,\n        jsonParse = 'parseJSON';\n\n    if ('JSON' in window && 'parse' in JSON) {\n      jsonAPI = JSON;\n      jsonParse = 'parse';\n    }\n\n    // The iframe transport accepts four additional options:\n    // options.fileInput: a jQuery collection of file input fields\n    // options.paramName: the parameter name for the file form data,\n    //  overrides the name property of the file input field(s),\n    //  can be a string or an array of strings.\n    // options.formData: an array of objects with name and value properties,\n    //  equivalent to the return data of .serializeArray(), e.g.:\n    //  [{name: 'a', value: 1}, {name: 'b', value: 2}]\n    // options.initialIframeSrc: the URL of the initial iframe src,\n    //  by default set to \"javascript:false;\"\n    $.ajaxTransport('iframe', function (options) {\n        if (options.async) {\n            // javascript:false as initial iframe src\n            // prevents warning popups on HTTPS in IE6:\n            /*jshint scripturl: true */\n            var initialIframeSrc = options.initialIframeSrc || 'javascript:false;',\n            /*jshint scripturl: false */\n                form,\n                iframe,\n                addParamChar;\n            return {\n                send: function (_, completeCallback) {\n                    form = $('<form style=\"display:none;\"></form>');\n                    form.attr('accept-charset', options.formAcceptCharset);\n                    addParamChar = /\\?/.test(options.url) ? '&' : '?';\n                    // XDomainRequest only supports GET and POST:\n                    if (options.type === 'DELETE') {\n                        options.url = options.url + addParamChar + '_method=DELETE';\n                        options.type = 'POST';\n                    } else if (options.type === 'PUT') {\n                        options.url = options.url + addParamChar + '_method=PUT';\n                        options.type = 'POST';\n                    } else if (options.type === 'PATCH') {\n                        options.url = options.url + addParamChar + '_method=PATCH';\n                        options.type = 'POST';\n                    }\n                    // IE versions below IE8 cannot set the name property of\n                    // elements that have already been added to the DOM,\n                    // so we set the name along with the iframe HTML markup:\n                    counter += 1;\n                    iframe = $(\n                        '<iframe src=\"' + initialIframeSrc +\n                            '\" name=\"iframe-transport-' + counter + '\"></iframe>'\n                    ).bind('load', function () {\n                        var fileInputClones,\n                            paramNames = $.isArray(options.paramName) ?\n                                    options.paramName : [options.paramName];\n                        iframe\n                            .unbind('load')\n                            .bind('load', function () {\n                                var response;\n                                // Wrap in a try/catch block to catch exceptions thrown\n                                // when trying to access cross-domain iframe contents:\n                                try {\n                                    response = iframe.contents();\n                                    // Google Chrome and Firefox do not throw an\n                                    // exception when calling iframe.contents() on\n                                    // cross-domain requests, so we unify the response:\n                                    if (!response.length || !response[0].firstChild) {\n                                        throw new Error();\n                                    }\n                                } catch (e) {\n                                    response = undefined;\n                                }\n                                // The complete callback returns the\n                                // iframe content document as response object:\n                                completeCallback(\n                                    200,\n                                    'success',\n                                    {'iframe': response}\n                                );\n                                // Fix for IE endless progress bar activity bug\n                                // (happens on form submits to iframe targets):\n                                $('<iframe src=\"' + initialIframeSrc + '\"></iframe>')\n                                    .appendTo(form);\n                                window.setTimeout(function () {\n                                    // Removing the form in a setTimeout call\n                                    // allows Chrome's developer tools to display\n                                    // the response result\n                                    form.remove();\n                                }, 0);\n                            });\n                        form\n                            .prop('target', iframe.prop('name'))\n                            .prop('action', options.url)\n                            .prop('method', options.type);\n                        if (options.formData) {\n                            $.each(options.formData, function (index, field) {\n                                $('<input type=\"hidden\"/>')\n                                    .prop('name', field.name)\n                                    .val(field.value)\n                                    .appendTo(form);\n                            });\n                        }\n                        if (options.fileInput && options.fileInput.length &&\n                                options.type === 'POST') {\n                            fileInputClones = options.fileInput.clone();\n                            // Insert a clone for each file input field:\n                            options.fileInput.after(function (index) {\n                                return fileInputClones[index];\n                            });\n                            if (options.paramName) {\n                                options.fileInput.each(function (index) {\n                                    $(this).prop(\n                                        'name',\n                                        paramNames[index] || options.paramName\n                                    );\n                                });\n                            }\n                            // Appending the file input fields to the hidden form\n                            // removes them from their original location:\n                            form\n                                .append(options.fileInput)\n                                .prop('enctype', 'multipart/form-data')\n                                // enctype must be set as encoding for IE:\n                                .prop('encoding', 'multipart/form-data');\n                            // Remove the HTML5 form attribute from the input(s):\n                            options.fileInput.removeAttr('form');\n                        }\n                        form.submit();\n                        // Insert the file input fields at their original location\n                        // by replacing the clones with the originals:\n                        if (fileInputClones && fileInputClones.length) {\n                            options.fileInput.each(function (index, input) {\n                                var clone = $(fileInputClones[index]);\n                                // Restore the original name and form properties:\n                                $(input)\n                                    .prop('name', clone.prop('name'))\n                                    .attr('form', clone.attr('form'));\n                                clone.replaceWith(input);\n                            });\n                        }\n                    });\n                    form.append(iframe).appendTo(document.body);\n                },\n                abort: function () {\n                    if (iframe) {\n                        // javascript:false as iframe src aborts the request\n                        // and prevents warning popups on HTTPS in IE6.\n                        // concat is used to avoid the \"Script URL\" JSLint error:\n                        iframe\n                            .unbind('load')\n                            .prop('src', initialIframeSrc);\n                    }\n                    if (form) {\n                        form.remove();\n                    }\n                }\n            };\n        }\n    });\n\n    // The iframe transport returns the iframe content document as response.\n    // The following adds converters from iframe to text, json, html, xml\n    // and script.\n    // Please note that the Content-Type for JSON responses has to be text/plain\n    // or text/html, if the browser doesn't include application/json in the\n    // Accept header, else IE will show a download dialog.\n    // The Content-Type for XML responses on the other hand has to be always\n    // application/xml or text/xml, so IE properly parses the XML response.\n    // See also\n    // https://github.com/blueimp/jQuery-File-Upload/wiki/Setup#content-type-negotiation\n    $.ajaxSetup({\n        converters: {\n            'iframe text': function (iframe) {\n                return iframe && $(iframe[0].body).text();\n            },\n            'iframe json': function (iframe) {\n                return iframe && jsonAPI[jsonParse]($(iframe[0].body).text());\n            },\n            'iframe html': function (iframe) {\n                return iframe && $(iframe[0].body).html();\n            },\n            'iframe xml': function (iframe) {\n                var xmlDoc = iframe && iframe[0];\n                return xmlDoc && $.isXMLDoc(xmlDoc) ? xmlDoc :\n                        $.parseXML((xmlDoc.XMLDocument && xmlDoc.XMLDocument.xml) ||\n                            $(xmlDoc.body).html());\n            },\n            'iframe script': function (iframe) {\n                return iframe && $.globalEval($(iframe[0].body).text());\n            }\n        }\n    });\n\n}));\n"
  },
  {
    "path": "app_backend/static/plugin/jQuery-File-Upload-9.18.0/js/main.js",
    "content": "/*\n * jQuery File Upload Plugin JS Example\n * https://github.com/blueimp/jQuery-File-Upload\n *\n * Copyright 2010, Sebastian Tschan\n * https://blueimp.net\n *\n * Licensed under the MIT license:\n * https://opensource.org/licenses/MIT\n */\n\n/* global $, window */\n\n$(function () {\n    'use strict';\n\n    // Initialize the jQuery File Upload widget:\n    $('#fileupload').fileupload({\n        // Uncomment the following to send cross-domain cookies:\n        //xhrFields: {withCredentials: true},\n        url: 'server/php/'\n    });\n\n    // Enable iframe cross-domain access via redirect option:\n    $('#fileupload').fileupload(\n        'option',\n        'redirect',\n        window.location.href.replace(\n            /\\/[^\\/]*$/,\n            '/cors/result.html?%s'\n        )\n    );\n\n    if (window.location.hostname === 'blueimp.github.io') {\n        // Demo settings:\n        $('#fileupload').fileupload('option', {\n            url: '//jquery-file-upload.appspot.com/',\n            // Enable image resizing, except for Android and Opera,\n            // which actually support image resizing, but fail to\n            // send Blob objects via XHR requests:\n            disableImageResize: /Android(?!.*Chrome)|Opera/\n                .test(window.navigator.userAgent),\n            maxFileSize: 999000,\n            acceptFileTypes: /(\\.|\\/)(gif|jpe?g|png)$/i\n        });\n        // Upload server status check for browsers with CORS support:\n        if ($.support.cors) {\n            $.ajax({\n                url: '//jquery-file-upload.appspot.com/',\n                type: 'HEAD'\n            }).fail(function () {\n                $('<div class=\"alert alert-danger\"/>')\n                    .text('Upload server currently unavailable - ' +\n                            new Date())\n                    .appendTo('#fileupload');\n            });\n        }\n    } else {\n        // Load existing files:\n        $('#fileupload').addClass('fileupload-processing');\n        $.ajax({\n            // Uncomment the following to send cross-domain cookies:\n            //xhrFields: {withCredentials: true},\n            url: $('#fileupload').fileupload('option', 'url'),\n            dataType: 'json',\n            context: $('#fileupload')[0]\n        }).always(function () {\n            $(this).removeClass('fileupload-processing');\n        }).done(function (result) {\n            $(this).fileupload('option', 'done')\n                .call(this, $.Event('done'), {result: result});\n        });\n    }\n\n});\n"
  },
  {
    "path": "app_backend/static/plugin/jQuery-File-Upload-9.18.0/js/vendor/jquery.ui.widget.js",
    "content": "/*! jQuery UI - v1.11.4+CommonJS - 2015-08-28\n* http://jqueryui.com\n* Includes: widget.js\n* Copyright 2015 jQuery Foundation and other contributors; Licensed MIT */\n\n(function( factory ) {\n\tif ( typeof define === \"function\" && define.amd ) {\n\n\t\t// AMD. Register as an anonymous module.\n\t\tdefine([ \"jquery\" ], factory );\n\n\t} else if ( typeof exports === \"object\" ) {\n\n\t\t// Node/CommonJS\n\t\tfactory( require( \"jquery\" ) );\n\n\t} else {\n\n\t\t// Browser globals\n\t\tfactory( jQuery );\n\t}\n}(function( $ ) {\n/*!\n * jQuery UI Widget 1.11.4\n * http://jqueryui.com\n *\n * Copyright jQuery Foundation and other contributors\n * Released under the MIT license.\n * http://jquery.org/license\n *\n * http://api.jqueryui.com/jQuery.widget/\n */\n\n\nvar widget_uuid = 0,\n\twidget_slice = Array.prototype.slice;\n\n$.cleanData = (function( orig ) {\n\treturn function( elems ) {\n\t\tvar events, elem, i;\n\t\tfor ( i = 0; (elem = elems[i]) != null; i++ ) {\n\t\t\ttry {\n\n\t\t\t\t// Only trigger remove when necessary to save time\n\t\t\t\tevents = $._data( elem, \"events\" );\n\t\t\t\tif ( events && events.remove ) {\n\t\t\t\t\t$( elem ).triggerHandler( \"remove\" );\n\t\t\t\t}\n\n\t\t\t// http://bugs.jquery.com/ticket/8235\n\t\t\t} catch ( e ) {}\n\t\t}\n\t\torig( elems );\n\t};\n})( $.cleanData );\n\n$.widget = function( name, base, prototype ) {\n\tvar fullName, existingConstructor, constructor, basePrototype,\n\t\t// proxiedPrototype allows the provided prototype to remain unmodified\n\t\t// so that it can be used as a mixin for multiple widgets (#8876)\n\t\tproxiedPrototype = {},\n\t\tnamespace = name.split( \".\" )[ 0 ];\n\n\tname = name.split( \".\" )[ 1 ];\n\tfullName = namespace + \"-\" + name;\n\n\tif ( !prototype ) {\n\t\tprototype = base;\n\t\tbase = $.Widget;\n\t}\n\n\t// create selector for plugin\n\t$.expr[ \":\" ][ fullName.toLowerCase() ] = function( elem ) {\n\t\treturn !!$.data( elem, fullName );\n\t};\n\n\t$[ namespace ] = $[ namespace ] || {};\n\texistingConstructor = $[ namespace ][ name ];\n\tconstructor = $[ namespace ][ name ] = function( options, element ) {\n\t\t// allow instantiation without \"new\" keyword\n\t\tif ( !this._createWidget ) {\n\t\t\treturn new constructor( options, element );\n\t\t}\n\n\t\t// allow instantiation without initializing for simple inheritance\n\t\t// must use \"new\" keyword (the code above always passes args)\n\t\tif ( arguments.length ) {\n\t\t\tthis._createWidget( options, element );\n\t\t}\n\t};\n\t// extend with the existing constructor to carry over any static properties\n\t$.extend( constructor, existingConstructor, {\n\t\tversion: prototype.version,\n\t\t// copy the object used to create the prototype in case we need to\n\t\t// redefine the widget later\n\t\t_proto: $.extend( {}, prototype ),\n\t\t// track widgets that inherit from this widget in case this widget is\n\t\t// redefined after a widget inherits from it\n\t\t_childConstructors: []\n\t});\n\n\tbasePrototype = new base();\n\t// we need to make the options hash a property directly on the new instance\n\t// otherwise we'll modify the options hash on the prototype that we're\n\t// inheriting from\n\tbasePrototype.options = $.widget.extend( {}, basePrototype.options );\n\t$.each( prototype, function( prop, value ) {\n\t\tif ( !$.isFunction( value ) ) {\n\t\t\tproxiedPrototype[ prop ] = value;\n\t\t\treturn;\n\t\t}\n\t\tproxiedPrototype[ prop ] = (function() {\n\t\t\tvar _super = function() {\n\t\t\t\t\treturn base.prototype[ prop ].apply( this, arguments );\n\t\t\t\t},\n\t\t\t\t_superApply = function( args ) {\n\t\t\t\t\treturn base.prototype[ prop ].apply( this, args );\n\t\t\t\t};\n\t\t\treturn function() {\n\t\t\t\tvar __super = this._super,\n\t\t\t\t\t__superApply = this._superApply,\n\t\t\t\t\treturnValue;\n\n\t\t\t\tthis._super = _super;\n\t\t\t\tthis._superApply = _superApply;\n\n\t\t\t\treturnValue = value.apply( this, arguments );\n\n\t\t\t\tthis._super = __super;\n\t\t\t\tthis._superApply = __superApply;\n\n\t\t\t\treturn returnValue;\n\t\t\t};\n\t\t})();\n\t});\n\tconstructor.prototype = $.widget.extend( basePrototype, {\n\t\t// TODO: remove support for widgetEventPrefix\n\t\t// always use the name + a colon as the prefix, e.g., draggable:start\n\t\t// don't prefix for widgets that aren't DOM-based\n\t\twidgetEventPrefix: existingConstructor ? (basePrototype.widgetEventPrefix || name) : name\n\t}, proxiedPrototype, {\n\t\tconstructor: constructor,\n\t\tnamespace: namespace,\n\t\twidgetName: name,\n\t\twidgetFullName: fullName\n\t});\n\n\t// If this widget is being redefined then we need to find all widgets that\n\t// are inheriting from it and redefine all of them so that they inherit from\n\t// the new version of this widget. We're essentially trying to replace one\n\t// level in the prototype chain.\n\tif ( existingConstructor ) {\n\t\t$.each( existingConstructor._childConstructors, function( i, child ) {\n\t\t\tvar childPrototype = child.prototype;\n\n\t\t\t// redefine the child widget using the same prototype that was\n\t\t\t// originally used, but inherit from the new version of the base\n\t\t\t$.widget( childPrototype.namespace + \".\" + childPrototype.widgetName, constructor, child._proto );\n\t\t});\n\t\t// remove the list of existing child constructors from the old constructor\n\t\t// so the old child constructors can be garbage collected\n\t\tdelete existingConstructor._childConstructors;\n\t} else {\n\t\tbase._childConstructors.push( constructor );\n\t}\n\n\t$.widget.bridge( name, constructor );\n\n\treturn constructor;\n};\n\n$.widget.extend = function( target ) {\n\tvar input = widget_slice.call( arguments, 1 ),\n\t\tinputIndex = 0,\n\t\tinputLength = input.length,\n\t\tkey,\n\t\tvalue;\n\tfor ( ; inputIndex < inputLength; inputIndex++ ) {\n\t\tfor ( key in input[ inputIndex ] ) {\n\t\t\tvalue = input[ inputIndex ][ key ];\n\t\t\tif ( input[ inputIndex ].hasOwnProperty( key ) && value !== undefined ) {\n\t\t\t\t// Clone objects\n\t\t\t\tif ( $.isPlainObject( value ) ) {\n\t\t\t\t\ttarget[ key ] = $.isPlainObject( target[ key ] ) ?\n\t\t\t\t\t\t$.widget.extend( {}, target[ key ], value ) :\n\t\t\t\t\t\t// Don't extend strings, arrays, etc. with objects\n\t\t\t\t\t\t$.widget.extend( {}, value );\n\t\t\t\t// Copy everything else by reference\n\t\t\t\t} else {\n\t\t\t\t\ttarget[ key ] = value;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\treturn target;\n};\n\n$.widget.bridge = function( name, object ) {\n\tvar fullName = object.prototype.widgetFullName || name;\n\t$.fn[ name ] = function( options ) {\n\t\tvar isMethodCall = typeof options === \"string\",\n\t\t\targs = widget_slice.call( arguments, 1 ),\n\t\t\treturnValue = this;\n\n\t\tif ( isMethodCall ) {\n\t\t\tthis.each(function() {\n\t\t\t\tvar methodValue,\n\t\t\t\t\tinstance = $.data( this, fullName );\n\t\t\t\tif ( options === \"instance\" ) {\n\t\t\t\t\treturnValue = instance;\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t\tif ( !instance ) {\n\t\t\t\t\treturn $.error( \"cannot call methods on \" + name + \" prior to initialization; \" +\n\t\t\t\t\t\t\"attempted to call method '\" + options + \"'\" );\n\t\t\t\t}\n\t\t\t\tif ( !$.isFunction( instance[options] ) || options.charAt( 0 ) === \"_\" ) {\n\t\t\t\t\treturn $.error( \"no such method '\" + options + \"' for \" + name + \" widget instance\" );\n\t\t\t\t}\n\t\t\t\tmethodValue = instance[ options ].apply( instance, args );\n\t\t\t\tif ( methodValue !== instance && methodValue !== undefined ) {\n\t\t\t\t\treturnValue = methodValue && methodValue.jquery ?\n\t\t\t\t\t\treturnValue.pushStack( methodValue.get() ) :\n\t\t\t\t\t\tmethodValue;\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t});\n\t\t} else {\n\n\t\t\t// Allow multiple hashes to be passed on init\n\t\t\tif ( args.length ) {\n\t\t\t\toptions = $.widget.extend.apply( null, [ options ].concat(args) );\n\t\t\t}\n\n\t\t\tthis.each(function() {\n\t\t\t\tvar instance = $.data( this, fullName );\n\t\t\t\tif ( instance ) {\n\t\t\t\t\tinstance.option( options || {} );\n\t\t\t\t\tif ( instance._init ) {\n\t\t\t\t\t\tinstance._init();\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\t$.data( this, fullName, new object( options, this ) );\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\n\t\treturn returnValue;\n\t};\n};\n\n$.Widget = function( /* options, element */ ) {};\n$.Widget._childConstructors = [];\n\n$.Widget.prototype = {\n\twidgetName: \"widget\",\n\twidgetEventPrefix: \"\",\n\tdefaultElement: \"<div>\",\n\toptions: {\n\t\tdisabled: false,\n\n\t\t// callbacks\n\t\tcreate: null\n\t},\n\t_createWidget: function( options, element ) {\n\t\telement = $( element || this.defaultElement || this )[ 0 ];\n\t\tthis.element = $( element );\n\t\tthis.uuid = widget_uuid++;\n\t\tthis.eventNamespace = \".\" + this.widgetName + this.uuid;\n\n\t\tthis.bindings = $();\n\t\tthis.hoverable = $();\n\t\tthis.focusable = $();\n\n\t\tif ( element !== this ) {\n\t\t\t$.data( element, this.widgetFullName, this );\n\t\t\tthis._on( true, this.element, {\n\t\t\t\tremove: function( event ) {\n\t\t\t\t\tif ( event.target === element ) {\n\t\t\t\t\t\tthis.destroy();\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t});\n\t\t\tthis.document = $( element.style ?\n\t\t\t\t// element within the document\n\t\t\t\telement.ownerDocument :\n\t\t\t\t// element is window or document\n\t\t\t\telement.document || element );\n\t\t\tthis.window = $( this.document[0].defaultView || this.document[0].parentWindow );\n\t\t}\n\n\t\tthis.options = $.widget.extend( {},\n\t\t\tthis.options,\n\t\t\tthis._getCreateOptions(),\n\t\t\toptions );\n\n\t\tthis._create();\n\t\tthis._trigger( \"create\", null, this._getCreateEventData() );\n\t\tthis._init();\n\t},\n\t_getCreateOptions: $.noop,\n\t_getCreateEventData: $.noop,\n\t_create: $.noop,\n\t_init: $.noop,\n\n\tdestroy: function() {\n\t\tthis._destroy();\n\t\t// we can probably remove the unbind calls in 2.0\n\t\t// all event bindings should go through this._on()\n\t\tthis.element\n\t\t\t.unbind( this.eventNamespace )\n\t\t\t.removeData( this.widgetFullName )\n\t\t\t// support: jquery <1.6.3\n\t\t\t// http://bugs.jquery.com/ticket/9413\n\t\t\t.removeData( $.camelCase( this.widgetFullName ) );\n\t\tthis.widget()\n\t\t\t.unbind( this.eventNamespace )\n\t\t\t.removeAttr( \"aria-disabled\" )\n\t\t\t.removeClass(\n\t\t\t\tthis.widgetFullName + \"-disabled \" +\n\t\t\t\t\"ui-state-disabled\" );\n\n\t\t// clean up events and states\n\t\tthis.bindings.unbind( this.eventNamespace );\n\t\tthis.hoverable.removeClass( \"ui-state-hover\" );\n\t\tthis.focusable.removeClass( \"ui-state-focus\" );\n\t},\n\t_destroy: $.noop,\n\n\twidget: function() {\n\t\treturn this.element;\n\t},\n\n\toption: function( key, value ) {\n\t\tvar options = key,\n\t\t\tparts,\n\t\t\tcurOption,\n\t\t\ti;\n\n\t\tif ( arguments.length === 0 ) {\n\t\t\t// don't return a reference to the internal hash\n\t\t\treturn $.widget.extend( {}, this.options );\n\t\t}\n\n\t\tif ( typeof key === \"string\" ) {\n\t\t\t// handle nested keys, e.g., \"foo.bar\" => { foo: { bar: ___ } }\n\t\t\toptions = {};\n\t\t\tparts = key.split( \".\" );\n\t\t\tkey = parts.shift();\n\t\t\tif ( parts.length ) {\n\t\t\t\tcurOption = options[ key ] = $.widget.extend( {}, this.options[ key ] );\n\t\t\t\tfor ( i = 0; i < parts.length - 1; i++ ) {\n\t\t\t\t\tcurOption[ parts[ i ] ] = curOption[ parts[ i ] ] || {};\n\t\t\t\t\tcurOption = curOption[ parts[ i ] ];\n\t\t\t\t}\n\t\t\t\tkey = parts.pop();\n\t\t\t\tif ( arguments.length === 1 ) {\n\t\t\t\t\treturn curOption[ key ] === undefined ? null : curOption[ key ];\n\t\t\t\t}\n\t\t\t\tcurOption[ key ] = value;\n\t\t\t} else {\n\t\t\t\tif ( arguments.length === 1 ) {\n\t\t\t\t\treturn this.options[ key ] === undefined ? null : this.options[ key ];\n\t\t\t\t}\n\t\t\t\toptions[ key ] = value;\n\t\t\t}\n\t\t}\n\n\t\tthis._setOptions( options );\n\n\t\treturn this;\n\t},\n\t_setOptions: function( options ) {\n\t\tvar key;\n\n\t\tfor ( key in options ) {\n\t\t\tthis._setOption( key, options[ key ] );\n\t\t}\n\n\t\treturn this;\n\t},\n\t_setOption: function( key, value ) {\n\t\tthis.options[ key ] = value;\n\n\t\tif ( key === \"disabled\" ) {\n\t\t\tthis.widget()\n\t\t\t\t.toggleClass( this.widgetFullName + \"-disabled\", !!value );\n\n\t\t\t// If the widget is becoming disabled, then nothing is interactive\n\t\t\tif ( value ) {\n\t\t\t\tthis.hoverable.removeClass( \"ui-state-hover\" );\n\t\t\t\tthis.focusable.removeClass( \"ui-state-focus\" );\n\t\t\t}\n\t\t}\n\n\t\treturn this;\n\t},\n\n\tenable: function() {\n\t\treturn this._setOptions({ disabled: false });\n\t},\n\tdisable: function() {\n\t\treturn this._setOptions({ disabled: true });\n\t},\n\n\t_on: function( suppressDisabledCheck, element, handlers ) {\n\t\tvar delegateElement,\n\t\t\tinstance = this;\n\n\t\t// no suppressDisabledCheck flag, shuffle arguments\n\t\tif ( typeof suppressDisabledCheck !== \"boolean\" ) {\n\t\t\thandlers = element;\n\t\t\telement = suppressDisabledCheck;\n\t\t\tsuppressDisabledCheck = false;\n\t\t}\n\n\t\t// no element argument, shuffle and use this.element\n\t\tif ( !handlers ) {\n\t\t\thandlers = element;\n\t\t\telement = this.element;\n\t\t\tdelegateElement = this.widget();\n\t\t} else {\n\t\t\telement = delegateElement = $( element );\n\t\t\tthis.bindings = this.bindings.add( element );\n\t\t}\n\n\t\t$.each( handlers, function( event, handler ) {\n\t\t\tfunction handlerProxy() {\n\t\t\t\t// allow widgets to customize the disabled handling\n\t\t\t\t// - disabled as an array instead of boolean\n\t\t\t\t// - disabled class as method for disabling individual parts\n\t\t\t\tif ( !suppressDisabledCheck &&\n\t\t\t\t\t\t( instance.options.disabled === true ||\n\t\t\t\t\t\t\t$( this ).hasClass( \"ui-state-disabled\" ) ) ) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\treturn ( typeof handler === \"string\" ? instance[ handler ] : handler )\n\t\t\t\t\t.apply( instance, arguments );\n\t\t\t}\n\n\t\t\t// copy the guid so direct unbinding works\n\t\t\tif ( typeof handler !== \"string\" ) {\n\t\t\t\thandlerProxy.guid = handler.guid =\n\t\t\t\t\thandler.guid || handlerProxy.guid || $.guid++;\n\t\t\t}\n\n\t\t\tvar match = event.match( /^([\\w:-]*)\\s*(.*)$/ ),\n\t\t\t\teventName = match[1] + instance.eventNamespace,\n\t\t\t\tselector = match[2];\n\t\t\tif ( selector ) {\n\t\t\t\tdelegateElement.delegate( selector, eventName, handlerProxy );\n\t\t\t} else {\n\t\t\t\telement.bind( eventName, handlerProxy );\n\t\t\t}\n\t\t});\n\t},\n\n\t_off: function( element, eventName ) {\n\t\teventName = (eventName || \"\").split( \" \" ).join( this.eventNamespace + \" \" ) +\n\t\t\tthis.eventNamespace;\n\t\telement.unbind( eventName ).undelegate( eventName );\n\n\t\t// Clear the stack to avoid memory leaks (#10056)\n\t\tthis.bindings = $( this.bindings.not( element ).get() );\n\t\tthis.focusable = $( this.focusable.not( element ).get() );\n\t\tthis.hoverable = $( this.hoverable.not( element ).get() );\n\t},\n\n\t_delay: function( handler, delay ) {\n\t\tfunction handlerProxy() {\n\t\t\treturn ( typeof handler === \"string\" ? instance[ handler ] : handler )\n\t\t\t\t.apply( instance, arguments );\n\t\t}\n\t\tvar instance = this;\n\t\treturn setTimeout( handlerProxy, delay || 0 );\n\t},\n\n\t_hoverable: function( element ) {\n\t\tthis.hoverable = this.hoverable.add( element );\n\t\tthis._on( element, {\n\t\t\tmouseenter: function( event ) {\n\t\t\t\t$( event.currentTarget ).addClass( \"ui-state-hover\" );\n\t\t\t},\n\t\t\tmouseleave: function( event ) {\n\t\t\t\t$( event.currentTarget ).removeClass( \"ui-state-hover\" );\n\t\t\t}\n\t\t});\n\t},\n\n\t_focusable: function( element ) {\n\t\tthis.focusable = this.focusable.add( element );\n\t\tthis._on( element, {\n\t\t\tfocusin: function( event ) {\n\t\t\t\t$( event.currentTarget ).addClass( \"ui-state-focus\" );\n\t\t\t},\n\t\t\tfocusout: function( event ) {\n\t\t\t\t$( event.currentTarget ).removeClass( \"ui-state-focus\" );\n\t\t\t}\n\t\t});\n\t},\n\n\t_trigger: function( type, event, data ) {\n\t\tvar prop, orig,\n\t\t\tcallback = this.options[ type ];\n\n\t\tdata = data || {};\n\t\tevent = $.Event( event );\n\t\tevent.type = ( type === this.widgetEventPrefix ?\n\t\t\ttype :\n\t\t\tthis.widgetEventPrefix + type ).toLowerCase();\n\t\t// the original event may come from any element\n\t\t// so we need to reset the target on the new event\n\t\tevent.target = this.element[ 0 ];\n\n\t\t// copy original event properties over to the new event\n\t\torig = event.originalEvent;\n\t\tif ( orig ) {\n\t\t\tfor ( prop in orig ) {\n\t\t\t\tif ( !( prop in event ) ) {\n\t\t\t\t\tevent[ prop ] = orig[ prop ];\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tthis.element.trigger( event, data );\n\t\treturn !( $.isFunction( callback ) &&\n\t\t\tcallback.apply( this.element[0], [ event ].concat( data ) ) === false ||\n\t\t\tevent.isDefaultPrevented() );\n\t}\n};\n\n$.each( { show: \"fadeIn\", hide: \"fadeOut\" }, function( method, defaultEffect ) {\n\t$.Widget.prototype[ \"_\" + method ] = function( element, options, callback ) {\n\t\tif ( typeof options === \"string\" ) {\n\t\t\toptions = { effect: options };\n\t\t}\n\t\tvar hasOptions,\n\t\t\teffectName = !options ?\n\t\t\t\tmethod :\n\t\t\t\toptions === true || typeof options === \"number\" ?\n\t\t\t\t\tdefaultEffect :\n\t\t\t\t\toptions.effect || defaultEffect;\n\t\toptions = options || {};\n\t\tif ( typeof options === \"number\" ) {\n\t\t\toptions = { duration: options };\n\t\t}\n\t\thasOptions = !$.isEmptyObject( options );\n\t\toptions.complete = callback;\n\t\tif ( options.delay ) {\n\t\t\telement.delay( options.delay );\n\t\t}\n\t\tif ( hasOptions && $.effects && $.effects.effect[ effectName ] ) {\n\t\t\telement[ method ]( options );\n\t\t} else if ( effectName !== method && element[ effectName ] ) {\n\t\t\telement[ effectName ]( options.duration, options.easing, callback );\n\t\t} else {\n\t\t\telement.queue(function( next ) {\n\t\t\t\t$( this )[ method ]();\n\t\t\t\tif ( callback ) {\n\t\t\t\t\tcallback.call( element[ 0 ] );\n\t\t\t\t}\n\t\t\t\tnext();\n\t\t\t});\n\t\t}\n\t};\n});\n\nvar widget = $.widget;\n\n\n\n}));\n"
  },
  {
    "path": "app_backend/static/plugin/jQuery-File-Upload-9.18.0/package.json",
    "content": "{\n  \"name\": \"blueimp-file-upload\",\n  \"version\": \"9.18.0\",\n  \"title\": \"jQuery File Upload\",\n  \"description\": \"File Upload widget with multiple file selection, drag&drop support, progress bar, validation and preview images, audio and video for jQuery. Supports cross-domain, chunked and resumable file uploads. Works with any server-side platform (Google App Engine, PHP, Python, Ruby on Rails, Java, etc.) that supports standard HTML form file uploads.\",\n  \"keywords\": [\n    \"jquery\",\n    \"file\",\n    \"upload\",\n    \"widget\",\n    \"multiple\",\n    \"selection\",\n    \"drag\",\n    \"drop\",\n    \"progress\",\n    \"preview\",\n    \"cross-domain\",\n    \"cross-site\",\n    \"chunk\",\n    \"resume\",\n    \"gae\",\n    \"go\",\n    \"python\",\n    \"php\",\n    \"bootstrap\"\n  ],\n  \"homepage\": \"https://github.com/blueimp/jQuery-File-Upload\",\n  \"author\": {\n    \"name\": \"Sebastian Tschan\",\n    \"url\": \"https://blueimp.net\"\n  },\n  \"repository\": {\n    \"type\": \"git\",\n    \"url\": \"git://github.com/blueimp/jQuery-File-Upload.git\"\n  },\n  \"license\": \"MIT\",\n  \"optionalDependencies\": {\n    \"blueimp-canvas-to-blob\": \"3.5.0\",\n    \"blueimp-load-image\": \"2.12.2\",\n    \"blueimp-tmpl\": \"3.6.0\"\n  },\n  \"devDependencies\": {\n    \"bower-json\": \"0.8.1\",\n    \"jshint\": \"2.9.3\"\n  },\n  \"scripts\": {\n    \"bower-version-update\": \"./bower-version-update.js\",\n    \"lint\": \"jshint *.js js/*.js js/cors/*.js\",\n    \"test\": \"npm run lint\",\n    \"preversion\": \"npm test\",\n    \"version\": \"npm run bower-version-update && git add bower.json\",\n    \"postversion\": \"git push --tags origin master && npm publish\"\n  },\n  \"main\": \"js/jquery.fileupload.js\"\n}\n"
  },
  {
    "path": "app_backend/static/plugin/jQuery-File-Upload-9.18.0/server/gae-go/app/main.go",
    "content": "/*\n * jQuery File Upload Plugin GAE Go Example\n * https://github.com/blueimp/jQuery-File-Upload\n *\n * Copyright 2011, Sebastian Tschan\n * https://blueimp.net\n *\n * Licensed under the MIT license:\n * https://opensource.org/licenses/MIT\n */\n\npackage app\n\nimport (\n\t\"bufio\"\n\t\"bytes\"\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"github.com/disintegration/gift\"\n\t\"golang.org/x/net/context\"\n\t\"google.golang.org/appengine\"\n\t\"google.golang.org/appengine/memcache\"\n\t\"hash/crc32\"\n\t\"image\"\n\t\"image/gif\"\n\t\"image/jpeg\"\n\t\"image/png\"\n\t\"io\"\n\t\"log\"\n\t\"mime/multipart\"\n\t\"net/http\"\n\t\"net/url\"\n\t\"path/filepath\"\n\t\"regexp\"\n\t\"strings\"\n)\n\nconst (\n\tWEBSITE       = \"https://blueimp.github.io/jQuery-File-Upload/\"\n\tMIN_FILE_SIZE = 1 // bytes\n\t// Max file size is memcache limit (1MB) minus key size minus overhead:\n\tMAX_FILE_SIZE     = 999000 // bytes\n\tIMAGE_TYPES       = \"image/(gif|p?jpeg|(x-)?png)\"\n\tACCEPT_FILE_TYPES = IMAGE_TYPES\n\tTHUMB_MAX_WIDTH   = 80\n\tTHUMB_MAX_HEIGHT  = 80\n\tEXPIRATION_TIME   = 300 // seconds\n\t// If empty, only allow redirects to the referer protocol+host.\n\t// Set to a regexp string for custom pattern matching:\n\tREDIRECT_ALLOW_TARGET = \"\"\n)\n\nvar (\n\timageTypes      = regexp.MustCompile(IMAGE_TYPES)\n\tacceptFileTypes = regexp.MustCompile(ACCEPT_FILE_TYPES)\n\tthumbSuffix     = \".\" + fmt.Sprint(THUMB_MAX_WIDTH) + \"x\" +\n\t\tfmt.Sprint(THUMB_MAX_HEIGHT)\n)\n\nfunc escape(s string) string {\n\treturn strings.Replace(url.QueryEscape(s), \"+\", \"%20\", -1)\n}\n\nfunc extractKey(r *http.Request) string {\n\t// Use RequestURI instead of r.URL.Path, as we need the encoded form:\n\tpath := strings.Split(r.RequestURI, \"?\")[0]\n\t// Also adjust double encoded slashes:\n\treturn strings.Replace(path[1:], \"%252F\", \"%2F\", -1)\n}\n\nfunc check(err error) {\n\tif err != nil {\n\t\tpanic(err)\n\t}\n}\n\ntype FileInfo struct {\n\tKey          string `json:\"-\"`\n\tThumbnailKey string `json:\"-\"`\n\tUrl          string `json:\"url,omitempty\"`\n\tThumbnailUrl string `json:\"thumbnailUrl,omitempty\"`\n\tName         string `json:\"name\"`\n\tType         string `json:\"type\"`\n\tSize         int64  `json:\"size\"`\n\tError        string `json:\"error,omitempty\"`\n\tDeleteUrl    string `json:\"deleteUrl,omitempty\"`\n\tDeleteType   string `json:\"deleteType,omitempty\"`\n}\n\nfunc (fi *FileInfo) ValidateType() (valid bool) {\n\tif acceptFileTypes.MatchString(fi.Type) {\n\t\treturn true\n\t}\n\tfi.Error = \"Filetype not allowed\"\n\treturn false\n}\n\nfunc (fi *FileInfo) ValidateSize() (valid bool) {\n\tif fi.Size < MIN_FILE_SIZE {\n\t\tfi.Error = \"File is too small\"\n\t} else if fi.Size > MAX_FILE_SIZE {\n\t\tfi.Error = \"File is too big\"\n\t} else {\n\t\treturn true\n\t}\n\treturn false\n}\n\nfunc (fi *FileInfo) CreateUrls(r *http.Request, c context.Context) {\n\tu := &url.URL{\n\t\tScheme: r.URL.Scheme,\n\t\tHost:   appengine.DefaultVersionHostname(c),\n\t\tPath:   \"/\",\n\t}\n\tuString := u.String()\n\tfi.Url = uString + fi.Key\n\tfi.DeleteUrl = fi.Url\n\tfi.DeleteType = \"DELETE\"\n\tif fi.ThumbnailKey != \"\" {\n\t\tfi.ThumbnailUrl = uString + fi.ThumbnailKey\n\t}\n}\n\nfunc (fi *FileInfo) SetKey(checksum uint32) {\n\tfi.Key = escape(string(fi.Type)) + \"/\" +\n\t\tescape(fmt.Sprint(checksum)) + \"/\" +\n\t\tescape(string(fi.Name))\n}\n\nfunc (fi *FileInfo) createThumb(buffer *bytes.Buffer, c context.Context) {\n\tif imageTypes.MatchString(fi.Type) {\n\t\tsrc, _, err := image.Decode(bytes.NewReader(buffer.Bytes()))\n\t\tcheck(err)\n\t\tfilter := gift.New(gift.ResizeToFit(\n\t\t\tTHUMB_MAX_WIDTH,\n\t\t\tTHUMB_MAX_HEIGHT,\n\t\t\tgift.LanczosResampling,\n\t\t))\n\t\tdst := image.NewNRGBA(filter.Bounds(src.Bounds()))\n\t\tfilter.Draw(dst, src)\n\t\tbuffer.Reset()\n\t\tbWriter := bufio.NewWriter(buffer)\n\t\tswitch fi.Type {\n\t\tcase \"image/jpeg\", \"image/pjpeg\":\n\t\t\terr = jpeg.Encode(bWriter, dst, nil)\n\t\tcase \"image/gif\":\n\t\t\terr = gif.Encode(bWriter, dst, nil)\n\t\tdefault:\n\t\t\terr = png.Encode(bWriter, dst)\n\t\t}\n\t\tcheck(err)\n\t\tbWriter.Flush()\n\t\tthumbnailKey := fi.Key + thumbSuffix + filepath.Ext(fi.Name)\n\t\titem := &memcache.Item{\n\t\t\tKey:   thumbnailKey,\n\t\t\tValue: buffer.Bytes(),\n\t\t}\n\t\terr = memcache.Set(c, item)\n\t\tcheck(err)\n\t\tfi.ThumbnailKey = thumbnailKey\n\t}\n}\n\nfunc handleUpload(r *http.Request, p *multipart.Part) (fi *FileInfo) {\n\tfi = &FileInfo{\n\t\tName: p.FileName(),\n\t\tType: p.Header.Get(\"Content-Type\"),\n\t}\n\tif !fi.ValidateType() {\n\t\treturn\n\t}\n\tdefer func() {\n\t\tif rec := recover(); rec != nil {\n\t\t\tlog.Println(rec)\n\t\t\tfi.Error = rec.(error).Error()\n\t\t}\n\t}()\n\tvar buffer bytes.Buffer\n\thash := crc32.NewIEEE()\n\tmw := io.MultiWriter(&buffer, hash)\n\tlr := &io.LimitedReader{R: p, N: MAX_FILE_SIZE + 1}\n\t_, err := io.Copy(mw, lr)\n\tcheck(err)\n\tfi.Size = MAX_FILE_SIZE + 1 - lr.N\n\tif !fi.ValidateSize() {\n\t\treturn\n\t}\n\tfi.SetKey(hash.Sum32())\n\titem := &memcache.Item{\n\t\tKey:   fi.Key,\n\t\tValue: buffer.Bytes(),\n\t}\n\tcontext := appengine.NewContext(r)\n\terr = memcache.Set(context, item)\n\tcheck(err)\n\tfi.createThumb(&buffer, context)\n\tfi.CreateUrls(r, context)\n\treturn\n}\n\nfunc getFormValue(p *multipart.Part) string {\n\tvar b bytes.Buffer\n\tio.CopyN(&b, p, int64(1<<20)) // Copy max: 1 MiB\n\treturn b.String()\n}\n\nfunc handleUploads(r *http.Request) (fileInfos []*FileInfo) {\n\tfileInfos = make([]*FileInfo, 0)\n\tmr, err := r.MultipartReader()\n\tcheck(err)\n\tr.Form, err = url.ParseQuery(r.URL.RawQuery)\n\tcheck(err)\n\tpart, err := mr.NextPart()\n\tfor err == nil {\n\t\tif name := part.FormName(); name != \"\" {\n\t\t\tif part.FileName() != \"\" {\n\t\t\t\tfileInfos = append(fileInfos, handleUpload(r, part))\n\t\t\t} else {\n\t\t\t\tr.Form[name] = append(r.Form[name], getFormValue(part))\n\t\t\t}\n\t\t}\n\t\tpart, err = mr.NextPart()\n\t}\n\treturn\n}\n\nfunc validateRedirect(r *http.Request, redirect string) bool {\n\tif redirect != \"\" {\n\t\tvar redirectAllowTarget *regexp.Regexp\n\t\tif REDIRECT_ALLOW_TARGET != \"\" {\n\t\t\tredirectAllowTarget = regexp.MustCompile(REDIRECT_ALLOW_TARGET)\n\t\t} else {\n\t\t\treferer := r.Referer()\n\t\t\tif referer == \"\" {\n\t\t\t\treturn false\n\t\t\t}\n\t\t\trefererUrl, err := url.Parse(referer)\n\t\t\tif err != nil {\n\t\t\t\treturn false\n\t\t\t}\n\t\t\tredirectAllowTarget = regexp.MustCompile(\"^\" + regexp.QuoteMeta(\n\t\t\t\trefererUrl.Scheme+\"://\"+refererUrl.Host+\"/\",\n\t\t\t))\n\t\t}\n\t\treturn redirectAllowTarget.MatchString(redirect)\n\t}\n\treturn false\n}\n\nfunc get(w http.ResponseWriter, r *http.Request) {\n\tif r.URL.Path == \"/\" {\n\t\thttp.Redirect(w, r, WEBSITE, http.StatusFound)\n\t\treturn\n\t}\n\t// Use RequestURI instead of r.URL.Path, as we need the encoded form:\n\tkey := extractKey(r)\n\tparts := strings.Split(key, \"/\")\n\tif len(parts) == 3 {\n\t\tcontext := appengine.NewContext(r)\n\t\titem, err := memcache.Get(context, key)\n\t\tif err == nil {\n\t\t\tw.Header().Add(\"X-Content-Type-Options\", \"nosniff\")\n\t\t\tcontentType, _ := url.QueryUnescape(parts[0])\n\t\t\tif !imageTypes.MatchString(contentType) {\n\t\t\t\tcontentType = \"application/octet-stream\"\n\t\t\t}\n\t\t\tw.Header().Add(\"Content-Type\", contentType)\n\t\t\tw.Header().Add(\n\t\t\t\t\"Cache-Control\",\n\t\t\t\tfmt.Sprintf(\"public,max-age=%d\", EXPIRATION_TIME),\n\t\t\t)\n\t\t\tw.Write(item.Value)\n\t\t\treturn\n\t\t}\n\t}\n\thttp.Error(w, \"404 Not Found\", http.StatusNotFound)\n}\n\nfunc post(w http.ResponseWriter, r *http.Request) {\n\tresult := make(map[string][]*FileInfo, 1)\n\tresult[\"files\"] = handleUploads(r)\n\tb, err := json.Marshal(result)\n\tcheck(err)\n\tif redirect := r.FormValue(\"redirect\"); validateRedirect(r, redirect) {\n\t\tif strings.Contains(redirect, \"%s\") {\n\t\t\tredirect = fmt.Sprintf(\n\t\t\t\tredirect,\n\t\t\t\tescape(string(b)),\n\t\t\t)\n\t\t}\n\t\thttp.Redirect(w, r, redirect, http.StatusFound)\n\t\treturn\n\t}\n\tw.Header().Set(\"Cache-Control\", \"no-cache\")\n\tjsonType := \"application/json\"\n\tif strings.Index(r.Header.Get(\"Accept\"), jsonType) != -1 {\n\t\tw.Header().Set(\"Content-Type\", jsonType)\n\t}\n\tfmt.Fprintln(w, string(b))\n}\n\nfunc delete(w http.ResponseWriter, r *http.Request) {\n\tkey := extractKey(r)\n\tparts := strings.Split(key, \"/\")\n\tif len(parts) == 3 {\n\t\tresult := make(map[string]bool, 1)\n\t\tcontext := appengine.NewContext(r)\n\t\terr := memcache.Delete(context, key)\n\t\tif err == nil {\n\t\t\tresult[key] = true\n\t\t\tcontentType, _ := url.QueryUnescape(parts[0])\n\t\t\tif imageTypes.MatchString(contentType) {\n\t\t\t\tthumbnailKey := key + thumbSuffix + filepath.Ext(parts[2])\n\t\t\t\terr := memcache.Delete(context, thumbnailKey)\n\t\t\t\tif err == nil {\n\t\t\t\t\tresult[thumbnailKey] = true\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tw.Header().Set(\"Content-Type\", \"application/json\")\n\t\tb, err := json.Marshal(result)\n\t\tcheck(err)\n\t\tfmt.Fprintln(w, string(b))\n\t} else {\n\t\thttp.Error(w, \"405 Method not allowed\", http.StatusMethodNotAllowed)\n\t}\n}\n\nfunc handle(w http.ResponseWriter, r *http.Request) {\n\tparams, err := url.ParseQuery(r.URL.RawQuery)\n\tcheck(err)\n\tw.Header().Add(\"Access-Control-Allow-Origin\", \"*\")\n\tw.Header().Add(\n\t\t\"Access-Control-Allow-Methods\",\n\t\t\"OPTIONS, HEAD, GET, POST, DELETE\",\n\t)\n\tw.Header().Add(\n\t\t\"Access-Control-Allow-Headers\",\n\t\t\"Content-Type, Content-Range, Content-Disposition\",\n\t)\n\tswitch r.Method {\n\tcase \"OPTIONS\", \"HEAD\":\n\t\treturn\n\tcase \"GET\":\n\t\tget(w, r)\n\tcase \"POST\":\n\t\tif len(params[\"_method\"]) > 0 && params[\"_method\"][0] == \"DELETE\" {\n\t\t\tdelete(w, r)\n\t\t} else {\n\t\t\tpost(w, r)\n\t\t}\n\tcase \"DELETE\":\n\t\tdelete(w, r)\n\tdefault:\n\t\thttp.Error(w, \"501 Not Implemented\", http.StatusNotImplemented)\n\t}\n}\n\nfunc init() {\n\thttp.HandleFunc(\"/\", handle)\n}\n"
  },
  {
    "path": "app_backend/static/plugin/jQuery-File-Upload-9.18.0/server/gae-go/app.yaml",
    "content": "application: jquery-file-upload\nversion: 2\nruntime: go\napi_version: go1\n\nhandlers:\n- url: /(favicon\\.ico|robots\\.txt)\n  static_files: static/\\1\n  upload: static/(.*)\n  expiration: '1d'\n- url: /.*\n  script: _go_app\n"
  },
  {
    "path": "app_backend/static/plugin/jQuery-File-Upload-9.18.0/server/gae-go/static/robots.txt",
    "content": "User-agent: *\nDisallow:\n"
  },
  {
    "path": "app_backend/static/plugin/jQuery-File-Upload-9.18.0/server/gae-python/app.yaml",
    "content": "application: jquery-file-upload\nversion: 1\nruntime: python27\napi_version: 1\nthreadsafe: true\n\nlibraries:\n- name: PIL\n  version: latest\n\nhandlers:\n- url: /(favicon\\.ico|robots\\.txt)\n  static_files: static/\\1\n  upload: static/(.*)\n  expiration: '1d'\n- url: /.*\n  script: main.app\n"
  },
  {
    "path": "app_backend/static/plugin/jQuery-File-Upload-9.18.0/server/gae-python/main.py",
    "content": "# -*- coding: utf-8 -*-\n#\n# jQuery File Upload Plugin GAE Python Example\n# https://github.com/blueimp/jQuery-File-Upload\n#\n# Copyright 2011, Sebastian Tschan\n# https://blueimp.net\n#\n# Licensed under the MIT license:\n# https://opensource.org/licenses/MIT\n#\n\nfrom google.appengine.api import memcache, images\nimport json\nimport os\nimport re\nimport urllib\nimport webapp2\n\nDEBUG=os.environ.get('SERVER_SOFTWARE', '').startswith('Dev')\nWEBSITE = 'https://blueimp.github.io/jQuery-File-Upload/'\nMIN_FILE_SIZE = 1  # bytes\n# Max file size is memcache limit (1MB) minus key size minus overhead:\nMAX_FILE_SIZE = 999000  # bytes\nIMAGE_TYPES = re.compile('image/(gif|p?jpeg|(x-)?png)')\nACCEPT_FILE_TYPES = IMAGE_TYPES\nTHUMB_MAX_WIDTH = 80\nTHUMB_MAX_HEIGHT = 80\nTHUMB_SUFFIX = '.'+str(THUMB_MAX_WIDTH)+'x'+str(THUMB_MAX_HEIGHT)+'.png'\nEXPIRATION_TIME = 300  # seconds\n# If set to None, only allow redirects to the referer protocol+host.\n# Set to a regexp for custom pattern matching against the redirect value:\nREDIRECT_ALLOW_TARGET = None\n\nclass CORSHandler(webapp2.RequestHandler):\n    def cors(self):\n        headers = self.response.headers\n        headers['Access-Control-Allow-Origin'] = '*'\n        headers['Access-Control-Allow-Methods'] =\\\n            'OPTIONS, HEAD, GET, POST, DELETE'\n        headers['Access-Control-Allow-Headers'] =\\\n            'Content-Type, Content-Range, Content-Disposition'\n\n    def initialize(self, request, response):\n        super(CORSHandler, self).initialize(request, response)\n        self.cors()\n\n    def json_stringify(self, obj):\n        return json.dumps(obj, separators=(',', ':'))\n\n    def options(self, *args, **kwargs):\n        pass\n\nclass UploadHandler(CORSHandler):\n    def validate(self, file):\n        if file['size'] < MIN_FILE_SIZE:\n            file['error'] = 'File is too small'\n        elif file['size'] > MAX_FILE_SIZE:\n            file['error'] = 'File is too big'\n        elif not ACCEPT_FILE_TYPES.match(file['type']):\n            file['error'] = 'Filetype not allowed'\n        else:\n            return True\n        return False\n\n    def validate_redirect(self, redirect):\n        if redirect:\n            if REDIRECT_ALLOW_TARGET:\n                return REDIRECT_ALLOW_TARGET.match(redirect)\n            referer = self.request.headers['referer']\n            if referer:\n                from urlparse import urlparse\n                parts = urlparse(referer)\n                redirect_allow_target = '^' + re.escape(\n                    parts.scheme + '://' + parts.netloc + '/'\n                )\n            return re.match(redirect_allow_target, redirect)\n        return False\n\n    def get_file_size(self, file):\n        file.seek(0, 2)  # Seek to the end of the file\n        size = file.tell()  # Get the position of EOF\n        file.seek(0)  # Reset the file position to the beginning\n        return size\n\n    def write_blob(self, data, info):\n        key = urllib.quote(info['type'].encode('utf-8'), '') +\\\n            '/' + str(hash(data)) +\\\n            '/' + urllib.quote(info['name'].encode('utf-8'), '')\n        try:\n            memcache.set(key, data, time=EXPIRATION_TIME)\n        except: #Failed to add to memcache\n            return (None, None)\n        thumbnail_key = None\n        if IMAGE_TYPES.match(info['type']):\n            try:\n                img = images.Image(image_data=data)\n                img.resize(\n                    width=THUMB_MAX_WIDTH,\n                    height=THUMB_MAX_HEIGHT\n                )\n                thumbnail_data = img.execute_transforms()\n                thumbnail_key = key + THUMB_SUFFIX\n                memcache.set(\n                    thumbnail_key,\n                    thumbnail_data,\n                    time=EXPIRATION_TIME\n                )\n            except: #Failed to resize Image or add to memcache\n                thumbnail_key = None\n        return (key, thumbnail_key)\n\n    def handle_upload(self):\n        results = []\n        for name, fieldStorage in self.request.POST.items():\n            if type(fieldStorage) is unicode:\n                continue\n            result = {}\n            result['name'] = urllib.unquote(fieldStorage.filename)\n            result['type'] = fieldStorage.type\n            result['size'] = self.get_file_size(fieldStorage.file)\n            if self.validate(result):\n                key, thumbnail_key = self.write_blob(\n                    fieldStorage.value,\n                    result\n                )\n                if key is not None:\n                    result['url'] = self.request.host_url + '/' + key\n                    result['deleteUrl'] = result['url']\n                    result['deleteType'] = 'DELETE'\n                    if thumbnail_key is not None:\n                        result['thumbnailUrl'] = self.request.host_url +\\\n                             '/' + thumbnail_key\n                else:\n                    result['error'] = 'Failed to store uploaded file.'\n            results.append(result)\n        return results\n\n    def head(self):\n        pass\n\n    def get(self):\n        self.redirect(WEBSITE)\n\n    def post(self):\n        if (self.request.get('_method') == 'DELETE'):\n            return self.delete()\n        result = {'files': self.handle_upload()}\n        s = self.json_stringify(result)\n        redirect = self.request.get('redirect')\n        if self.validate_redirect(redirect):\n            return self.redirect(str(\n                redirect.replace('%s', urllib.quote(s, ''), 1)\n            ))\n        if 'application/json' in self.request.headers.get('Accept'):\n            self.response.headers['Content-Type'] = 'application/json'\n        self.response.write(s)\n\nclass FileHandler(CORSHandler):\n    def normalize(self, str):\n        return urllib.quote(urllib.unquote(str), '')\n\n    def get(self, content_type, data_hash, file_name):\n        content_type = self.normalize(content_type)\n        file_name = self.normalize(file_name)\n        key = content_type + '/' + data_hash + '/' + file_name\n        data = memcache.get(key)\n        if data is None:\n            return self.error(404)\n        # Prevent browsers from MIME-sniffing the content-type:\n        self.response.headers['X-Content-Type-Options'] = 'nosniff'\n        content_type = urllib.unquote(content_type)\n        if not IMAGE_TYPES.match(content_type):\n            # Force a download dialog for non-image types:\n            content_type = 'application/octet-stream'\n        elif file_name.endswith(THUMB_SUFFIX):\n            content_type = 'image/png'\n        self.response.headers['Content-Type'] = content_type\n        # Cache for the expiration time:\n        self.response.headers['Cache-Control'] = 'public,max-age=%d' \\\n            % EXPIRATION_TIME\n        self.response.write(data)\n\n    def delete(self, content_type, data_hash, file_name):\n        content_type = self.normalize(content_type)\n        file_name = self.normalize(file_name)\n        key = content_type + '/' + data_hash + '/' + file_name\n        result = {key: memcache.delete(key)}\n        content_type = urllib.unquote(content_type)\n        if IMAGE_TYPES.match(content_type):\n            thumbnail_key = key + THUMB_SUFFIX\n            result[thumbnail_key] = memcache.delete(thumbnail_key)\n        if 'application/json' in self.request.headers.get('Accept'):\n            self.response.headers['Content-Type'] = 'application/json'\n        s = self.json_stringify(result)\n        self.response.write(s)\n\napp = webapp2.WSGIApplication(\n    [\n        ('/', UploadHandler),\n        ('/(.+)/([^/]+)/([^/]+)', FileHandler)\n    ],\n    debug=DEBUG\n)\n"
  },
  {
    "path": "app_backend/static/plugin/jQuery-File-Upload-9.18.0/server/gae-python/static/robots.txt",
    "content": "User-agent: *\nDisallow:\n"
  },
  {
    "path": "app_backend/static/plugin/jQuery-File-Upload-9.18.0/server/php/Dockerfile",
    "content": "FROM php:7.0-apache\n\n# Enable the Apache Headers module:\nRUN ln -s /etc/apache2/mods-available/headers.load \\\n  /etc/apache2/mods-enabled/headers.load\n\n# Enable the Apache Rewrite module:\nRUN ln -s /etc/apache2/mods-available/rewrite.load \\\n  /etc/apache2/mods-enabled/rewrite.load\n\n# Install GD, Imagick and ImageMagick as image conversion options:\nRUN DEBIAN_FRONTEND=noninteractive \\\n  apt-get update && apt-get install -y --no-install-recommends \\\n    libpng-dev \\\n    libjpeg-dev \\\n    libmagickwand-dev \\\n    imagemagick \\\n  && pecl install \\\n    imagick \\\n  && docker-php-ext-enable \\\n    imagick \\\n  && docker-php-ext-configure \\\n    gd --with-jpeg-dir=/usr/include/ \\\n  && docker-php-ext-install \\\n    gd \\\n  # Uninstall obsolete packages:\n  && apt-get autoremove -y \\\n    libpng-dev \\\n    libjpeg-dev \\\n    libmagickwand-dev \\\n  # Remove obsolete files:\n  && apt-get clean \\\n  && rm -rf \\\n    /tmp/* \\\n    /usr/share/doc/* \\\n    /var/cache/* \\\n    /var/lib/apt/lists/* \\\n    /var/tmp/*\n"
  },
  {
    "path": "app_backend/static/plugin/jQuery-File-Upload-9.18.0/server/php/UploadHandler.php",
    "content": "<?php\n/*\n * jQuery File Upload Plugin PHP Class\n * https://github.com/blueimp/jQuery-File-Upload\n *\n * Copyright 2010, Sebastian Tschan\n * https://blueimp.net\n *\n * Licensed under the MIT license:\n * https://opensource.org/licenses/MIT\n */\n\nclass UploadHandler\n{\n\n    protected $options;\n\n    // PHP File Upload error message codes:\n    // http://php.net/manual/en/features.file-upload.errors.php\n    protected $error_messages = array(\n        1 => 'The uploaded file exceeds the upload_max_filesize directive in php.ini',\n        2 => 'The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form',\n        3 => 'The uploaded file was only partially uploaded',\n        4 => 'No file was uploaded',\n        6 => 'Missing a temporary folder',\n        7 => 'Failed to write file to disk',\n        8 => 'A PHP extension stopped the file upload',\n        'post_max_size' => 'The uploaded file exceeds the post_max_size directive in php.ini',\n        'max_file_size' => 'File is too big',\n        'min_file_size' => 'File is too small',\n        'accept_file_types' => 'Filetype not allowed',\n        'max_number_of_files' => 'Maximum number of files exceeded',\n        'max_width' => 'Image exceeds maximum width',\n        'min_width' => 'Image requires a minimum width',\n        'max_height' => 'Image exceeds maximum height',\n        'min_height' => 'Image requires a minimum height',\n        'abort' => 'File upload aborted',\n        'image_resize' => 'Failed to resize image'\n    );\n\n    protected $image_objects = array();\n\n    public function __construct($options = null, $initialize = true, $error_messages = null) {\n        $this->response = array();\n        $this->options = array(\n            'script_url' => $this->get_full_url().'/'.$this->basename($this->get_server_var('SCRIPT_NAME')),\n            'upload_dir' => dirname($this->get_server_var('SCRIPT_FILENAME')).'/files/',\n            'upload_url' => $this->get_full_url().'/files/',\n            'input_stream' => 'php://input',\n            'user_dirs' => false,\n            'mkdir_mode' => 0755,\n            'param_name' => 'files',\n            // Set the following option to 'POST', if your server does not support\n            // DELETE requests. This is a parameter sent to the client:\n            'delete_type' => 'DELETE',\n            'access_control_allow_origin' => '*',\n            'access_control_allow_credentials' => false,\n            'access_control_allow_methods' => array(\n                'OPTIONS',\n                'HEAD',\n                'GET',\n                'POST',\n                'PUT',\n                'PATCH',\n                'DELETE'\n            ),\n            'access_control_allow_headers' => array(\n                'Content-Type',\n                'Content-Range',\n                'Content-Disposition'\n            ),\n            // By default, allow redirects to the referer protocol+host:\n            'redirect_allow_target' => '/^'.preg_quote(\n              parse_url($this->get_server_var('HTTP_REFERER'), PHP_URL_SCHEME)\n                .'://'\n                .parse_url($this->get_server_var('HTTP_REFERER'), PHP_URL_HOST)\n                .'/', // Trailing slash to not match subdomains by mistake\n              '/' // preg_quote delimiter param\n            ).'/',\n            // Enable to provide file downloads via GET requests to the PHP script:\n            //     1. Set to 1 to download files via readfile method through PHP\n            //     2. Set to 2 to send a X-Sendfile header for lighttpd/Apache\n            //     3. Set to 3 to send a X-Accel-Redirect header for nginx\n            // If set to 2 or 3, adjust the upload_url option to the base path of\n            // the redirect parameter, e.g. '/files/'.\n            'download_via_php' => false,\n            // Read files in chunks to avoid memory limits when download_via_php\n            // is enabled, set to 0 to disable chunked reading of files:\n            'readfile_chunk_size' => 10 * 1024 * 1024, // 10 MiB\n            // Defines which files can be displayed inline when downloaded:\n            'inline_file_types' => '/\\.(gif|jpe?g|png)$/i',\n            // Defines which files (based on their names) are accepted for upload:\n            'accept_file_types' => '/.+$/i',\n            // The php.ini settings upload_max_filesize and post_max_size\n            // take precedence over the following max_file_size setting:\n            'max_file_size' => null,\n            'min_file_size' => 1,\n            // The maximum number of files for the upload directory:\n            'max_number_of_files' => null,\n            // Defines which files are handled as image files:\n            'image_file_types' => '/\\.(gif|jpe?g|png)$/i',\n            // Use exif_imagetype on all files to correct file extensions:\n            'correct_image_extensions' => false,\n            // Image resolution restrictions:\n            'max_width' => null,\n            'max_height' => null,\n            'min_width' => 1,\n            'min_height' => 1,\n            // Set the following option to false to enable resumable uploads:\n            'discard_aborted_uploads' => true,\n            // Set to 0 to use the GD library to scale and orient images,\n            // set to 1 to use imagick (if installed, falls back to GD),\n            // set to 2 to use the ImageMagick convert binary directly:\n            'image_library' => 1,\n            // Uncomment the following to define an array of resource limits\n            // for imagick:\n            /*\n            'imagick_resource_limits' => array(\n                imagick::RESOURCETYPE_MAP => 32,\n                imagick::RESOURCETYPE_MEMORY => 32\n            ),\n            */\n            // Command or path for to the ImageMagick convert binary:\n            'convert_bin' => 'convert',\n            // Uncomment the following to add parameters in front of each\n            // ImageMagick convert call (the limit constraints seem only\n            // to have an effect if put in front):\n            /*\n            'convert_params' => '-limit memory 32MiB -limit map 32MiB',\n            */\n            // Command or path for to the ImageMagick identify binary:\n            'identify_bin' => 'identify',\n            'image_versions' => array(\n                // The empty image version key defines options for the original image:\n                '' => array(\n                    // Automatically rotate images based on EXIF meta data:\n                    'auto_orient' => true\n                ),\n                // Uncomment the following to create medium sized images:\n                /*\n                'medium' => array(\n                    'max_width' => 800,\n                    'max_height' => 600\n                ),\n                */\n                'thumbnail' => array(\n                    // Uncomment the following to use a defined directory for the thumbnails\n                    // instead of a subdirectory based on the version identifier.\n                    // Make sure that this directory doesn't allow execution of files if you\n                    // don't pose any restrictions on the type of uploaded files, e.g. by\n                    // copying the .htaccess file from the files directory for Apache:\n                    //'upload_dir' => dirname($this->get_server_var('SCRIPT_FILENAME')).'/thumb/',\n                    //'upload_url' => $this->get_full_url().'/thumb/',\n                    // Uncomment the following to force the max\n                    // dimensions and e.g. create square thumbnails:\n                    //'crop' => true,\n                    'max_width' => 80,\n                    'max_height' => 80\n                )\n            ),\n            'print_response' => true\n        );\n        if ($options) {\n            $this->options = $options + $this->options;\n        }\n        if ($error_messages) {\n            $this->error_messages = $error_messages + $this->error_messages;\n        }\n        if ($initialize) {\n            $this->initialize();\n        }\n    }\n\n    protected function initialize() {\n        switch ($this->get_server_var('REQUEST_METHOD')) {\n            case 'OPTIONS':\n            case 'HEAD':\n                $this->head();\n                break;\n            case 'GET':\n                $this->get($this->options['print_response']);\n                break;\n            case 'PATCH':\n            case 'PUT':\n            case 'POST':\n                $this->post($this->options['print_response']);\n                break;\n            case 'DELETE':\n                $this->delete($this->options['print_response']);\n                break;\n            default:\n                $this->header('HTTP/1.1 405 Method Not Allowed');\n        }\n    }\n\n    protected function get_full_url() {\n        $https = !empty($_SERVER['HTTPS']) && strcasecmp($_SERVER['HTTPS'], 'on') === 0 ||\n            !empty($_SERVER['HTTP_X_FORWARDED_PROTO']) &&\n                strcasecmp($_SERVER['HTTP_X_FORWARDED_PROTO'], 'https') === 0;\n        return\n            ($https ? 'https://' : 'http://').\n            (!empty($_SERVER['REMOTE_USER']) ? $_SERVER['REMOTE_USER'].'@' : '').\n            (isset($_SERVER['HTTP_HOST']) ? $_SERVER['HTTP_HOST'] : ($_SERVER['SERVER_NAME'].\n            ($https && $_SERVER['SERVER_PORT'] === 443 ||\n            $_SERVER['SERVER_PORT'] === 80 ? '' : ':'.$_SERVER['SERVER_PORT']))).\n            substr($_SERVER['SCRIPT_NAME'],0, strrpos($_SERVER['SCRIPT_NAME'], '/'));\n    }\n\n    protected function get_user_id() {\n        @session_start();\n        return session_id();\n    }\n\n    protected function get_user_path() {\n        if ($this->options['user_dirs']) {\n            return $this->get_user_id().'/';\n        }\n        return '';\n    }\n\n    protected function get_upload_path($file_name = null, $version = null) {\n        $file_name = $file_name ? $file_name : '';\n        if (empty($version)) {\n            $version_path = '';\n        } else {\n            $version_dir = @$this->options['image_versions'][$version]['upload_dir'];\n            if ($version_dir) {\n                return $version_dir.$this->get_user_path().$file_name;\n            }\n            $version_path = $version.'/';\n        }\n        return $this->options['upload_dir'].$this->get_user_path()\n            .$version_path.$file_name;\n    }\n\n    protected function get_query_separator($url) {\n        return strpos($url, '?') === false ? '?' : '&';\n    }\n\n    protected function get_download_url($file_name, $version = null, $direct = false) {\n        if (!$direct && $this->options['download_via_php']) {\n            $url = $this->options['script_url']\n                .$this->get_query_separator($this->options['script_url'])\n                .$this->get_singular_param_name()\n                .'='.rawurlencode($file_name);\n            if ($version) {\n                $url .= '&version='.rawurlencode($version);\n            }\n            return $url.'&download=1';\n        }\n        if (empty($version)) {\n            $version_path = '';\n        } else {\n            $version_url = @$this->options['image_versions'][$version]['upload_url'];\n            if ($version_url) {\n                return $version_url.$this->get_user_path().rawurlencode($file_name);\n            }\n            $version_path = rawurlencode($version).'/';\n        }\n        return $this->options['upload_url'].$this->get_user_path()\n            .$version_path.rawurlencode($file_name);\n    }\n\n    protected function set_additional_file_properties($file) {\n        $file->deleteUrl = $this->options['script_url']\n            .$this->get_query_separator($this->options['script_url'])\n            .$this->get_singular_param_name()\n            .'='.rawurlencode($file->name);\n        $file->deleteType = $this->options['delete_type'];\n        if ($file->deleteType !== 'DELETE') {\n            $file->deleteUrl .= '&_method=DELETE';\n        }\n        if ($this->options['access_control_allow_credentials']) {\n            $file->deleteWithCredentials = true;\n        }\n    }\n\n    // Fix for overflowing signed 32 bit integers,\n    // works for sizes up to 2^32-1 bytes (4 GiB - 1):\n    protected function fix_integer_overflow($size) {\n        if ($size < 0) {\n            $size += 2.0 * (PHP_INT_MAX + 1);\n        }\n        return $size;\n    }\n\n    protected function get_file_size($file_path, $clear_stat_cache = false) {\n        if ($clear_stat_cache) {\n            if (version_compare(PHP_VERSION, '5.3.0') >= 0) {\n                clearstatcache(true, $file_path);\n            } else {\n                clearstatcache();\n            }\n        }\n        return $this->fix_integer_overflow(filesize($file_path));\n    }\n\n    protected function is_valid_file_object($file_name) {\n        $file_path = $this->get_upload_path($file_name);\n        if (is_file($file_path) && $file_name[0] !== '.') {\n            return true;\n        }\n        return false;\n    }\n\n    protected function get_file_object($file_name) {\n        if ($this->is_valid_file_object($file_name)) {\n            $file = new \\stdClass();\n            $file->name = $file_name;\n            $file->size = $this->get_file_size(\n                $this->get_upload_path($file_name)\n            );\n            $file->url = $this->get_download_url($file->name);\n            foreach ($this->options['image_versions'] as $version => $options) {\n                if (!empty($version)) {\n                    if (is_file($this->get_upload_path($file_name, $version))) {\n                        $file->{$version.'Url'} = $this->get_download_url(\n                            $file->name,\n                            $version\n                        );\n                    }\n                }\n            }\n            $this->set_additional_file_properties($file);\n            return $file;\n        }\n        return null;\n    }\n\n    protected function get_file_objects($iteration_method = 'get_file_object') {\n        $upload_dir = $this->get_upload_path();\n        if (!is_dir($upload_dir)) {\n            return array();\n        }\n        return array_values(array_filter(array_map(\n            array($this, $iteration_method),\n            scandir($upload_dir)\n        )));\n    }\n\n    protected function count_file_objects() {\n        return count($this->get_file_objects('is_valid_file_object'));\n    }\n\n    protected function get_error_message($error) {\n        return isset($this->error_messages[$error]) ?\n            $this->error_messages[$error] : $error;\n    }\n\n    public function get_config_bytes($val) {\n        $val = trim($val);\n        $last = strtolower($val[strlen($val)-1]);\n        $val = (int)$val;\n        switch ($last) {\n            case 'g':\n                $val *= 1024;\n            case 'm':\n                $val *= 1024;\n            case 'k':\n                $val *= 1024;\n        }\n        return $this->fix_integer_overflow($val);\n    }\n\n    protected function validate($uploaded_file, $file, $error, $index) {\n        if ($error) {\n            $file->error = $this->get_error_message($error);\n            return false;\n        }\n        $content_length = $this->fix_integer_overflow(\n            (int)$this->get_server_var('CONTENT_LENGTH')\n        );\n        $post_max_size = $this->get_config_bytes(ini_get('post_max_size'));\n        if ($post_max_size && ($content_length > $post_max_size)) {\n            $file->error = $this->get_error_message('post_max_size');\n            return false;\n        }\n        if (!preg_match($this->options['accept_file_types'], $file->name)) {\n            $file->error = $this->get_error_message('accept_file_types');\n            return false;\n        }\n        if ($uploaded_file && is_uploaded_file($uploaded_file)) {\n            $file_size = $this->get_file_size($uploaded_file);\n        } else {\n            $file_size = $content_length;\n        }\n        if ($this->options['max_file_size'] && (\n                $file_size > $this->options['max_file_size'] ||\n                $file->size > $this->options['max_file_size'])\n            ) {\n            $file->error = $this->get_error_message('max_file_size');\n            return false;\n        }\n        if ($this->options['min_file_size'] &&\n            $file_size < $this->options['min_file_size']) {\n            $file->error = $this->get_error_message('min_file_size');\n            return false;\n        }\n        if (is_int($this->options['max_number_of_files']) &&\n                ($this->count_file_objects() >= $this->options['max_number_of_files']) &&\n                // Ignore additional chunks of existing files:\n                !is_file($this->get_upload_path($file->name))) {\n            $file->error = $this->get_error_message('max_number_of_files');\n            return false;\n        }\n        $max_width = @$this->options['max_width'];\n        $max_height = @$this->options['max_height'];\n        $min_width = @$this->options['min_width'];\n        $min_height = @$this->options['min_height'];\n        if (($max_width || $max_height || $min_width || $min_height)\n           && preg_match($this->options['image_file_types'], $file->name)) {\n            list($img_width, $img_height) = $this->get_image_size($uploaded_file);\n\n            // If we are auto rotating the image by default, do the checks on\n            // the correct orientation\n            if (\n                @$this->options['image_versions']['']['auto_orient'] &&\n                function_exists('exif_read_data') &&\n                ($exif = @exif_read_data($uploaded_file)) &&\n                (((int) @$exif['Orientation']) >= 5)\n            ) {\n                $tmp = $img_width;\n                $img_width = $img_height;\n                $img_height = $tmp;\n                unset($tmp);\n            }\n\n        }\n        if (!empty($img_width)) {\n            if ($max_width && $img_width > $max_width) {\n                $file->error = $this->get_error_message('max_width');\n                return false;\n            }\n            if ($max_height && $img_height > $max_height) {\n                $file->error = $this->get_error_message('max_height');\n                return false;\n            }\n            if ($min_width && $img_width < $min_width) {\n                $file->error = $this->get_error_message('min_width');\n                return false;\n            }\n            if ($min_height && $img_height < $min_height) {\n                $file->error = $this->get_error_message('min_height');\n                return false;\n            }\n        }\n        return true;\n    }\n\n    protected function upcount_name_callback($matches) {\n        $index = isset($matches[1]) ? ((int)$matches[1]) + 1 : 1;\n        $ext = isset($matches[2]) ? $matches[2] : '';\n        return ' ('.$index.')'.$ext;\n    }\n\n    protected function upcount_name($name) {\n        return preg_replace_callback(\n            '/(?:(?: \\(([\\d]+)\\))?(\\.[^.]+))?$/',\n            array($this, 'upcount_name_callback'),\n            $name,\n            1\n        );\n    }\n\n    protected function get_unique_filename($file_path, $name, $size, $type, $error,\n            $index, $content_range) {\n        while(is_dir($this->get_upload_path($name))) {\n            $name = $this->upcount_name($name);\n        }\n        // Keep an existing filename if this is part of a chunked upload:\n        $uploaded_bytes = $this->fix_integer_overflow((int)$content_range[1]);\n        while (is_file($this->get_upload_path($name))) {\n            if ($uploaded_bytes === $this->get_file_size(\n                    $this->get_upload_path($name))) {\n                break;\n            }\n            $name = $this->upcount_name($name);\n        }\n        return $name;\n    }\n\n    protected function fix_file_extension($file_path, $name, $size, $type, $error,\n            $index, $content_range) {\n        // Add missing file extension for known image types:\n        if (strpos($name, '.') === false &&\n                preg_match('/^image\\/(gif|jpe?g|png)/', $type, $matches)) {\n            $name .= '.'.$matches[1];\n        }\n        if ($this->options['correct_image_extensions'] &&\n                function_exists('exif_imagetype')) {\n            switch (@exif_imagetype($file_path)){\n                case IMAGETYPE_JPEG:\n                    $extensions = array('jpg', 'jpeg');\n                    break;\n                case IMAGETYPE_PNG:\n                    $extensions = array('png');\n                    break;\n                case IMAGETYPE_GIF:\n                    $extensions = array('gif');\n                    break;\n            }\n            // Adjust incorrect image file extensions:\n            if (!empty($extensions)) {\n                $parts = explode('.', $name);\n                $extIndex = count($parts) - 1;\n                $ext = strtolower(@$parts[$extIndex]);\n                if (!in_array($ext, $extensions)) {\n                    $parts[$extIndex] = $extensions[0];\n                    $name = implode('.', $parts);\n                }\n            }\n        }\n        return $name;\n    }\n\n    protected function trim_file_name($file_path, $name, $size, $type, $error,\n            $index, $content_range) {\n        // Remove path information and dots around the filename, to prevent uploading\n        // into different directories or replacing hidden system files.\n        // Also remove control characters and spaces (\\x00..\\x20) around the filename:\n        $name = trim($this->basename(stripslashes($name)), \".\\x00..\\x20\");\n        // Use a timestamp for empty filenames:\n        if (!$name) {\n            $name = str_replace('.', '-', microtime(true));\n        }\n        return $name;\n    }\n\n    protected function get_file_name($file_path, $name, $size, $type, $error,\n            $index, $content_range) {\n        $name = $this->trim_file_name($file_path, $name, $size, $type, $error,\n            $index, $content_range);\n        return $this->get_unique_filename(\n            $file_path,\n            $this->fix_file_extension($file_path, $name, $size, $type, $error,\n                $index, $content_range),\n            $size,\n            $type,\n            $error,\n            $index,\n            $content_range\n        );\n    }\n\n    protected function get_scaled_image_file_paths($file_name, $version) {\n        $file_path = $this->get_upload_path($file_name);\n        if (!empty($version)) {\n            $version_dir = $this->get_upload_path(null, $version);\n            if (!is_dir($version_dir)) {\n                mkdir($version_dir, $this->options['mkdir_mode'], true);\n            }\n            $new_file_path = $version_dir.'/'.$file_name;\n        } else {\n            $new_file_path = $file_path;\n        }\n        return array($file_path, $new_file_path);\n    }\n\n    protected function gd_get_image_object($file_path, $func, $no_cache = false) {\n        if (empty($this->image_objects[$file_path]) || $no_cache) {\n            $this->gd_destroy_image_object($file_path);\n            $this->image_objects[$file_path] = $func($file_path);\n        }\n        return $this->image_objects[$file_path];\n    }\n\n    protected function gd_set_image_object($file_path, $image) {\n        $this->gd_destroy_image_object($file_path);\n        $this->image_objects[$file_path] = $image;\n    }\n\n    protected function gd_destroy_image_object($file_path) {\n        $image = (isset($this->image_objects[$file_path])) ? $this->image_objects[$file_path] : null ;\n        return $image && imagedestroy($image);\n    }\n\n    protected function gd_imageflip($image, $mode) {\n        if (function_exists('imageflip')) {\n            return imageflip($image, $mode);\n        }\n        $new_width = $src_width = imagesx($image);\n        $new_height = $src_height = imagesy($image);\n        $new_img = imagecreatetruecolor($new_width, $new_height);\n        $src_x = 0;\n        $src_y = 0;\n        switch ($mode) {\n            case '1': // flip on the horizontal axis\n                $src_y = $new_height - 1;\n                $src_height = -$new_height;\n                break;\n            case '2': // flip on the vertical axis\n                $src_x  = $new_width - 1;\n                $src_width = -$new_width;\n                break;\n            case '3': // flip on both axes\n                $src_y = $new_height - 1;\n                $src_height = -$new_height;\n                $src_x  = $new_width - 1;\n                $src_width = -$new_width;\n                break;\n            default:\n                return $image;\n        }\n        imagecopyresampled(\n            $new_img,\n            $image,\n            0,\n            0,\n            $src_x,\n            $src_y,\n            $new_width,\n            $new_height,\n            $src_width,\n            $src_height\n        );\n        return $new_img;\n    }\n\n    protected function gd_orient_image($file_path, $src_img) {\n        if (!function_exists('exif_read_data')) {\n            return false;\n        }\n        $exif = @exif_read_data($file_path);\n        if ($exif === false) {\n            return false;\n        }\n        $orientation = (int)@$exif['Orientation'];\n        if ($orientation < 2 || $orientation > 8) {\n            return false;\n        }\n        switch ($orientation) {\n            case 2:\n                $new_img = $this->gd_imageflip(\n                    $src_img,\n                    defined('IMG_FLIP_VERTICAL') ? IMG_FLIP_VERTICAL : 2\n                );\n                break;\n            case 3:\n                $new_img = imagerotate($src_img, 180, 0);\n                break;\n            case 4:\n                $new_img = $this->gd_imageflip(\n                    $src_img,\n                    defined('IMG_FLIP_HORIZONTAL') ? IMG_FLIP_HORIZONTAL : 1\n                );\n                break;\n            case 5:\n                $tmp_img = $this->gd_imageflip(\n                    $src_img,\n                    defined('IMG_FLIP_HORIZONTAL') ? IMG_FLIP_HORIZONTAL : 1\n                );\n                $new_img = imagerotate($tmp_img, 270, 0);\n                imagedestroy($tmp_img);\n                break;\n            case 6:\n                $new_img = imagerotate($src_img, 270, 0);\n                break;\n            case 7:\n                $tmp_img = $this->gd_imageflip(\n                    $src_img,\n                    defined('IMG_FLIP_VERTICAL') ? IMG_FLIP_VERTICAL : 2\n                );\n                $new_img = imagerotate($tmp_img, 270, 0);\n                imagedestroy($tmp_img);\n                break;\n            case 8:\n                $new_img = imagerotate($src_img, 90, 0);\n                break;\n            default:\n                return false;\n        }\n        $this->gd_set_image_object($file_path, $new_img);\n        return true;\n    }\n\n    protected function gd_create_scaled_image($file_name, $version, $options) {\n        if (!function_exists('imagecreatetruecolor')) {\n            error_log('Function not found: imagecreatetruecolor');\n            return false;\n        }\n        list($file_path, $new_file_path) =\n            $this->get_scaled_image_file_paths($file_name, $version);\n        $type = strtolower(substr(strrchr($file_name, '.'), 1));\n        switch ($type) {\n            case 'jpg':\n            case 'jpeg':\n                $src_func = 'imagecreatefromjpeg';\n                $write_func = 'imagejpeg';\n                $image_quality = isset($options['jpeg_quality']) ?\n                    $options['jpeg_quality'] : 75;\n                break;\n            case 'gif':\n                $src_func = 'imagecreatefromgif';\n                $write_func = 'imagegif';\n                $image_quality = null;\n                break;\n            case 'png':\n                $src_func = 'imagecreatefrompng';\n                $write_func = 'imagepng';\n                $image_quality = isset($options['png_quality']) ?\n                    $options['png_quality'] : 9;\n                break;\n            default:\n                return false;\n        }\n        $src_img = $this->gd_get_image_object(\n            $file_path,\n            $src_func,\n            !empty($options['no_cache'])\n        );\n        $image_oriented = false;\n        if (!empty($options['auto_orient']) && $this->gd_orient_image(\n                $file_path,\n                $src_img\n            )) {\n            $image_oriented = true;\n            $src_img = $this->gd_get_image_object(\n                $file_path,\n                $src_func\n            );\n        }\n        $max_width = $img_width = imagesx($src_img);\n        $max_height = $img_height = imagesy($src_img);\n        if (!empty($options['max_width'])) {\n            $max_width = $options['max_width'];\n        }\n        if (!empty($options['max_height'])) {\n            $max_height = $options['max_height'];\n        }\n        $scale = min(\n            $max_width / $img_width,\n            $max_height / $img_height\n        );\n        if ($scale >= 1) {\n            if ($image_oriented) {\n                return $write_func($src_img, $new_file_path, $image_quality);\n            }\n            if ($file_path !== $new_file_path) {\n                return copy($file_path, $new_file_path);\n            }\n            return true;\n        }\n        if (empty($options['crop'])) {\n            $new_width = $img_width * $scale;\n            $new_height = $img_height * $scale;\n            $dst_x = 0;\n            $dst_y = 0;\n            $new_img = imagecreatetruecolor($new_width, $new_height);\n        } else {\n            if (($img_width / $img_height) >= ($max_width / $max_height)) {\n                $new_width = $img_width / ($img_height / $max_height);\n                $new_height = $max_height;\n            } else {\n                $new_width = $max_width;\n                $new_height = $img_height / ($img_width / $max_width);\n            }\n            $dst_x = 0 - ($new_width - $max_width) / 2;\n            $dst_y = 0 - ($new_height - $max_height) / 2;\n            $new_img = imagecreatetruecolor($max_width, $max_height);\n        }\n        // Handle transparency in GIF and PNG images:\n        switch ($type) {\n            case 'gif':\n            case 'png':\n                imagecolortransparent($new_img, imagecolorallocate($new_img, 0, 0, 0));\n            case 'png':\n                imagealphablending($new_img, false);\n                imagesavealpha($new_img, true);\n                break;\n        }\n        $success = imagecopyresampled(\n            $new_img,\n            $src_img,\n            $dst_x,\n            $dst_y,\n            0,\n            0,\n            $new_width,\n            $new_height,\n            $img_width,\n            $img_height\n        ) && $write_func($new_img, $new_file_path, $image_quality);\n        $this->gd_set_image_object($file_path, $new_img);\n        return $success;\n    }\n\n    protected function imagick_get_image_object($file_path, $no_cache = false) {\n        if (empty($this->image_objects[$file_path]) || $no_cache) {\n            $this->imagick_destroy_image_object($file_path);\n            $image = new \\Imagick();\n            if (!empty($this->options['imagick_resource_limits'])) {\n                foreach ($this->options['imagick_resource_limits'] as $type => $limit) {\n                    $image->setResourceLimit($type, $limit);\n                }\n            }\n            $image->readImage($file_path);\n            $this->image_objects[$file_path] = $image;\n        }\n        return $this->image_objects[$file_path];\n    }\n\n    protected function imagick_set_image_object($file_path, $image) {\n        $this->imagick_destroy_image_object($file_path);\n        $this->image_objects[$file_path] = $image;\n    }\n\n    protected function imagick_destroy_image_object($file_path) {\n        $image = (isset($this->image_objects[$file_path])) ? $this->image_objects[$file_path] : null ;\n        return $image && $image->destroy();\n    }\n\n    protected function imagick_orient_image($image) {\n        $orientation = $image->getImageOrientation();\n        $background = new \\ImagickPixel('none');\n        switch ($orientation) {\n            case \\imagick::ORIENTATION_TOPRIGHT: // 2\n                $image->flopImage(); // horizontal flop around y-axis\n                break;\n            case \\imagick::ORIENTATION_BOTTOMRIGHT: // 3\n                $image->rotateImage($background, 180);\n                break;\n            case \\imagick::ORIENTATION_BOTTOMLEFT: // 4\n                $image->flipImage(); // vertical flip around x-axis\n                break;\n            case \\imagick::ORIENTATION_LEFTTOP: // 5\n                $image->flopImage(); // horizontal flop around y-axis\n                $image->rotateImage($background, 270);\n                break;\n            case \\imagick::ORIENTATION_RIGHTTOP: // 6\n                $image->rotateImage($background, 90);\n                break;\n            case \\imagick::ORIENTATION_RIGHTBOTTOM: // 7\n                $image->flipImage(); // vertical flip around x-axis\n                $image->rotateImage($background, 270);\n                break;\n            case \\imagick::ORIENTATION_LEFTBOTTOM: // 8\n                $image->rotateImage($background, 270);\n                break;\n            default:\n                return false;\n        }\n        $image->setImageOrientation(\\imagick::ORIENTATION_TOPLEFT); // 1\n        return true;\n    }\n\n    protected function imagick_create_scaled_image($file_name, $version, $options) {\n        list($file_path, $new_file_path) =\n            $this->get_scaled_image_file_paths($file_name, $version);\n        $image = $this->imagick_get_image_object(\n            $file_path,\n            !empty($options['crop']) || !empty($options['no_cache'])\n        );\n        if ($image->getImageFormat() === 'GIF') {\n            // Handle animated GIFs:\n            $images = $image->coalesceImages();\n            foreach ($images as $frame) {\n                $image = $frame;\n                $this->imagick_set_image_object($file_name, $image);\n                break;\n            }\n        }\n        $image_oriented = false;\n        if (!empty($options['auto_orient'])) {\n            $image_oriented = $this->imagick_orient_image($image);\n        }\n        $new_width = $max_width = $img_width = $image->getImageWidth();\n        $new_height = $max_height = $img_height = $image->getImageHeight();\n        if (!empty($options['max_width'])) {\n            $new_width = $max_width = $options['max_width'];\n        }\n        if (!empty($options['max_height'])) {\n            $new_height = $max_height = $options['max_height'];\n        }\n        if (!($image_oriented || $max_width < $img_width || $max_height < $img_height)) {\n            if ($file_path !== $new_file_path) {\n                return copy($file_path, $new_file_path);\n            }\n            return true;\n        }\n        $crop = !empty($options['crop']);\n        if ($crop) {\n            $x = 0;\n            $y = 0;\n            if (($img_width / $img_height) >= ($max_width / $max_height)) {\n                $new_width = 0; // Enables proportional scaling based on max_height\n                $x = ($img_width / ($img_height / $max_height) - $max_width) / 2;\n            } else {\n                $new_height = 0; // Enables proportional scaling based on max_width\n                $y = ($img_height / ($img_width / $max_width) - $max_height) / 2;\n            }\n        }\n        $success = $image->resizeImage(\n            $new_width,\n            $new_height,\n            isset($options['filter']) ? $options['filter'] : \\imagick::FILTER_LANCZOS,\n            isset($options['blur']) ? $options['blur'] : 1,\n            $new_width && $new_height // fit image into constraints if not to be cropped\n        );\n        if ($success && $crop) {\n            $success = $image->cropImage(\n                $max_width,\n                $max_height,\n                $x,\n                $y\n            );\n            if ($success) {\n                $success = $image->setImagePage($max_width, $max_height, 0, 0);\n            }\n        }\n        $type = strtolower(substr(strrchr($file_name, '.'), 1));\n        switch ($type) {\n            case 'jpg':\n            case 'jpeg':\n                if (!empty($options['jpeg_quality'])) {\n                    $image->setImageCompression(\\imagick::COMPRESSION_JPEG);\n                    $image->setImageCompressionQuality($options['jpeg_quality']);\n                }\n                break;\n        }\n        if (!empty($options['strip'])) {\n            $image->stripImage();\n        }\n        return $success && $image->writeImage($new_file_path);\n    }\n\n    protected function imagemagick_create_scaled_image($file_name, $version, $options) {\n        list($file_path, $new_file_path) =\n            $this->get_scaled_image_file_paths($file_name, $version);\n        $resize = @$options['max_width']\n            .(empty($options['max_height']) ? '' : 'X'.$options['max_height']);\n        if (!$resize && empty($options['auto_orient'])) {\n            if ($file_path !== $new_file_path) {\n                return copy($file_path, $new_file_path);\n            }\n            return true;\n        }\n        $cmd = $this->options['convert_bin'];\n        if (!empty($this->options['convert_params'])) {\n            $cmd .= ' '.$this->options['convert_params'];\n        }\n        $cmd .= ' '.escapeshellarg($file_path);\n        if (!empty($options['auto_orient'])) {\n            $cmd .= ' -auto-orient';\n        }\n        if ($resize) {\n            // Handle animated GIFs:\n            $cmd .= ' -coalesce';\n            if (empty($options['crop'])) {\n                $cmd .= ' -resize '.escapeshellarg($resize.'>');\n            } else {\n                $cmd .= ' -resize '.escapeshellarg($resize.'^');\n                $cmd .= ' -gravity center';\n                $cmd .= ' -crop '.escapeshellarg($resize.'+0+0');\n            }\n            // Make sure the page dimensions are correct (fixes offsets of animated GIFs):\n            $cmd .= ' +repage';\n        }\n        if (!empty($options['convert_params'])) {\n            $cmd .= ' '.$options['convert_params'];\n        }\n        $cmd .= ' '.escapeshellarg($new_file_path);\n        exec($cmd, $output, $error);\n        if ($error) {\n            error_log(implode('\\n', $output));\n            return false;\n        }\n        return true;\n    }\n\n    protected function get_image_size($file_path) {\n        if ($this->options['image_library']) {\n            if (extension_loaded('imagick')) {\n                $image = new \\Imagick();\n                try {\n                    if (@$image->pingImage($file_path)) {\n                        $dimensions = array($image->getImageWidth(), $image->getImageHeight());\n                        $image->destroy();\n                        return $dimensions;\n                    }\n                    return false;\n                } catch (\\Exception $e) {\n                    error_log($e->getMessage());\n                }\n            }\n            if ($this->options['image_library'] === 2) {\n                $cmd = $this->options['identify_bin'];\n                $cmd .= ' -ping '.escapeshellarg($file_path);\n                exec($cmd, $output, $error);\n                if (!$error && !empty($output)) {\n                    // image.jpg JPEG 1920x1080 1920x1080+0+0 8-bit sRGB 465KB 0.000u 0:00.000\n                    $infos = preg_split('/\\s+/', substr($output[0], strlen($file_path)));\n                    $dimensions = preg_split('/x/', $infos[2]);\n                    return $dimensions;\n                }\n                return false;\n            }\n        }\n        if (!function_exists('getimagesize')) {\n            error_log('Function not found: getimagesize');\n            return false;\n        }\n        return @getimagesize($file_path);\n    }\n\n    protected function create_scaled_image($file_name, $version, $options) {\n        if ($this->options['image_library'] === 2) {\n            return $this->imagemagick_create_scaled_image($file_name, $version, $options);\n        }\n        if ($this->options['image_library'] && extension_loaded('imagick')) {\n            return $this->imagick_create_scaled_image($file_name, $version, $options);\n        }\n        return $this->gd_create_scaled_image($file_name, $version, $options);\n    }\n\n    protected function destroy_image_object($file_path) {\n        if ($this->options['image_library'] && extension_loaded('imagick')) {\n            return $this->imagick_destroy_image_object($file_path);\n        }\n    }\n\n    protected function is_valid_image_file($file_path) {\n        if (!preg_match($this->options['image_file_types'], $file_path)) {\n            return false;\n        }\n        if (function_exists('exif_imagetype')) {\n            return @exif_imagetype($file_path);\n        }\n        $image_info = $this->get_image_size($file_path);\n        return $image_info && $image_info[0] && $image_info[1];\n    }\n\n    protected function handle_image_file($file_path, $file) {\n        $failed_versions = array();\n        foreach ($this->options['image_versions'] as $version => $options) {\n            if ($this->create_scaled_image($file->name, $version, $options)) {\n                if (!empty($version)) {\n                    $file->{$version.'Url'} = $this->get_download_url(\n                        $file->name,\n                        $version\n                    );\n                } else {\n                    $file->size = $this->get_file_size($file_path, true);\n                }\n            } else {\n                $failed_versions[] = $version ? $version : 'original';\n            }\n        }\n        if (count($failed_versions)) {\n            $file->error = $this->get_error_message('image_resize')\n                    .' ('.implode($failed_versions, ', ').')';\n        }\n        // Free memory:\n        $this->destroy_image_object($file_path);\n    }\n\n    protected function handle_file_upload($uploaded_file, $name, $size, $type, $error,\n            $index = null, $content_range = null) {\n        $file = new \\stdClass();\n        $file->name = $this->get_file_name($uploaded_file, $name, $size, $type, $error,\n            $index, $content_range);\n        $file->size = $this->fix_integer_overflow((int)$size);\n        $file->type = $type;\n        if ($this->validate($uploaded_file, $file, $error, $index)) {\n            $this->handle_form_data($file, $index);\n            $upload_dir = $this->get_upload_path();\n            if (!is_dir($upload_dir)) {\n                mkdir($upload_dir, $this->options['mkdir_mode'], true);\n            }\n            $file_path = $this->get_upload_path($file->name);\n            $append_file = $content_range && is_file($file_path) &&\n                $file->size > $this->get_file_size($file_path);\n            if ($uploaded_file && is_uploaded_file($uploaded_file)) {\n                // multipart/formdata uploads (POST method uploads)\n                if ($append_file) {\n                    file_put_contents(\n                        $file_path,\n                        fopen($uploaded_file, 'r'),\n                        FILE_APPEND\n                    );\n                } else {\n                    move_uploaded_file($uploaded_file, $file_path);\n                }\n            } else {\n                // Non-multipart uploads (PUT method support)\n                file_put_contents(\n                    $file_path,\n                    fopen($this->options['input_stream'], 'r'),\n                    $append_file ? FILE_APPEND : 0\n                );\n            }\n            $file_size = $this->get_file_size($file_path, $append_file);\n            if ($file_size === $file->size) {\n                $file->url = $this->get_download_url($file->name);\n                if ($this->is_valid_image_file($file_path)) {\n                    $this->handle_image_file($file_path, $file);\n                }\n            } else {\n                $file->size = $file_size;\n                if (!$content_range && $this->options['discard_aborted_uploads']) {\n                    unlink($file_path);\n                    $file->error = $this->get_error_message('abort');\n                }\n            }\n            $this->set_additional_file_properties($file);\n        }\n        return $file;\n    }\n\n    protected function readfile($file_path) {\n        $file_size = $this->get_file_size($file_path);\n        $chunk_size = $this->options['readfile_chunk_size'];\n        if ($chunk_size && $file_size > $chunk_size) {\n            $handle = fopen($file_path, 'rb');\n            while (!feof($handle)) {\n                echo fread($handle, $chunk_size);\n                @ob_flush();\n                @flush();\n            }\n            fclose($handle);\n            return $file_size;\n        }\n        return readfile($file_path);\n    }\n\n    protected function body($str) {\n        echo $str;\n    }\n\n    protected function header($str) {\n        header($str);\n    }\n\n    protected function get_upload_data($id) {\n        return @$_FILES[$id];\n    }\n\n    protected function get_post_param($id) {\n        return @$_POST[$id];\n    }\n\n    protected function get_query_param($id) {\n        return @$_GET[$id];\n    }\n\n    protected function get_server_var($id) {\n        return @$_SERVER[$id];\n    }\n\n    protected function handle_form_data($file, $index) {\n        // Handle form data, e.g. $_POST['description'][$index]\n    }\n\n    protected function get_version_param() {\n        return $this->basename(stripslashes($this->get_query_param('version')));\n    }\n\n    protected function get_singular_param_name() {\n        return substr($this->options['param_name'], 0, -1);\n    }\n\n    protected function get_file_name_param() {\n        $name = $this->get_singular_param_name();\n        return $this->basename(stripslashes($this->get_query_param($name)));\n    }\n\n    protected function get_file_names_params() {\n        $params = $this->get_query_param($this->options['param_name']);\n        if (!$params) {\n            return null;\n        }\n        foreach ($params as $key => $value) {\n            $params[$key] = $this->basename(stripslashes($value));\n        }\n        return $params;\n    }\n\n    protected function get_file_type($file_path) {\n        switch (strtolower(pathinfo($file_path, PATHINFO_EXTENSION))) {\n            case 'jpeg':\n            case 'jpg':\n                return 'image/jpeg';\n            case 'png':\n                return 'image/png';\n            case 'gif':\n                return 'image/gif';\n            default:\n                return '';\n        }\n    }\n\n    protected function download() {\n        switch ($this->options['download_via_php']) {\n            case 1:\n                $redirect_header = null;\n                break;\n            case 2:\n                $redirect_header = 'X-Sendfile';\n                break;\n            case 3:\n                $redirect_header = 'X-Accel-Redirect';\n                break;\n            default:\n                return $this->header('HTTP/1.1 403 Forbidden');\n        }\n        $file_name = $this->get_file_name_param();\n        if (!$this->is_valid_file_object($file_name)) {\n            return $this->header('HTTP/1.1 404 Not Found');\n        }\n        if ($redirect_header) {\n            return $this->header(\n                $redirect_header.': '.$this->get_download_url(\n                    $file_name,\n                    $this->get_version_param(),\n                    true\n                )\n            );\n        }\n        $file_path = $this->get_upload_path($file_name, $this->get_version_param());\n        // Prevent browsers from MIME-sniffing the content-type:\n        $this->header('X-Content-Type-Options: nosniff');\n        if (!preg_match($this->options['inline_file_types'], $file_name)) {\n            $this->header('Content-Type: application/octet-stream');\n            $this->header('Content-Disposition: attachment; filename=\"'.$file_name.'\"');\n        } else {\n            $this->header('Content-Type: '.$this->get_file_type($file_path));\n            $this->header('Content-Disposition: inline; filename=\"'.$file_name.'\"');\n        }\n        $this->header('Content-Length: '.$this->get_file_size($file_path));\n        $this->header('Last-Modified: '.gmdate('D, d M Y H:i:s T', filemtime($file_path)));\n        $this->readfile($file_path);\n    }\n\n    protected function send_content_type_header() {\n        $this->header('Vary: Accept');\n        if (strpos($this->get_server_var('HTTP_ACCEPT'), 'application/json') !== false) {\n            $this->header('Content-type: application/json');\n        } else {\n            $this->header('Content-type: text/plain');\n        }\n    }\n\n    protected function send_access_control_headers() {\n        $this->header('Access-Control-Allow-Origin: '.$this->options['access_control_allow_origin']);\n        $this->header('Access-Control-Allow-Credentials: '\n            .($this->options['access_control_allow_credentials'] ? 'true' : 'false'));\n        $this->header('Access-Control-Allow-Methods: '\n            .implode(', ', $this->options['access_control_allow_methods']));\n        $this->header('Access-Control-Allow-Headers: '\n            .implode(', ', $this->options['access_control_allow_headers']));\n    }\n\n    public function generate_response($content, $print_response = true) {\n        $this->response = $content;\n        if ($print_response) {\n            $json = json_encode($content);\n            $redirect = stripslashes($this->get_post_param('redirect'));\n            if ($redirect && preg_match($this->options['redirect_allow_target'], $redirect)) {\n                $this->header('Location: '.sprintf($redirect, rawurlencode($json)));\n                return;\n            }\n            $this->head();\n            if ($this->get_server_var('HTTP_CONTENT_RANGE')) {\n                $files = isset($content[$this->options['param_name']]) ?\n                    $content[$this->options['param_name']] : null;\n                if ($files && is_array($files) && is_object($files[0]) && $files[0]->size) {\n                    $this->header('Range: 0-'.(\n                        $this->fix_integer_overflow((int)$files[0]->size) - 1\n                    ));\n                }\n            }\n            $this->body($json);\n        }\n        return $content;\n    }\n\n    public function get_response () {\n        return $this->response;\n    }\n\n    public function head() {\n        $this->header('Pragma: no-cache');\n        $this->header('Cache-Control: no-store, no-cache, must-revalidate');\n        $this->header('Content-Disposition: inline; filename=\"files.json\"');\n        // Prevent Internet Explorer from MIME-sniffing the content-type:\n        $this->header('X-Content-Type-Options: nosniff');\n        if ($this->options['access_control_allow_origin']) {\n            $this->send_access_control_headers();\n        }\n        $this->send_content_type_header();\n    }\n\n    public function get($print_response = true) {\n        if ($print_response && $this->get_query_param('download')) {\n            return $this->download();\n        }\n        $file_name = $this->get_file_name_param();\n        if ($file_name) {\n            $response = array(\n                $this->get_singular_param_name() => $this->get_file_object($file_name)\n            );\n        } else {\n            $response = array(\n                $this->options['param_name'] => $this->get_file_objects()\n            );\n        }\n        return $this->generate_response($response, $print_response);\n    }\n\n    public function post($print_response = true) {\n        if ($this->get_query_param('_method') === 'DELETE') {\n            return $this->delete($print_response);\n        }\n        $upload = $this->get_upload_data($this->options['param_name']);\n        // Parse the Content-Disposition header, if available:\n        $content_disposition_header = $this->get_server_var('HTTP_CONTENT_DISPOSITION');\n        $file_name = $content_disposition_header ?\n            rawurldecode(preg_replace(\n                '/(^[^\"]+\")|(\"$)/',\n                '',\n                $content_disposition_header\n            )) : null;\n        // Parse the Content-Range header, which has the following form:\n        // Content-Range: bytes 0-524287/2000000\n        $content_range_header = $this->get_server_var('HTTP_CONTENT_RANGE');\n        $content_range = $content_range_header ?\n            preg_split('/[^0-9]+/', $content_range_header) : null;\n        $size =  $content_range ? $content_range[3] : null;\n        $files = array();\n        if ($upload) {\n            if (is_array($upload['tmp_name'])) {\n                // param_name is an array identifier like \"files[]\",\n                // $upload is a multi-dimensional array:\n                foreach ($upload['tmp_name'] as $index => $value) {\n                    $files[] = $this->handle_file_upload(\n                        $upload['tmp_name'][$index],\n                        $file_name ? $file_name : $upload['name'][$index],\n                        $size ? $size : $upload['size'][$index],\n                        $upload['type'][$index],\n                        $upload['error'][$index],\n                        $index,\n                        $content_range\n                    );\n                }\n            } else {\n                // param_name is a single object identifier like \"file\",\n                // $upload is a one-dimensional array:\n                $files[] = $this->handle_file_upload(\n                    isset($upload['tmp_name']) ? $upload['tmp_name'] : null,\n                    $file_name ? $file_name : (isset($upload['name']) ?\n                            $upload['name'] : null),\n                    $size ? $size : (isset($upload['size']) ?\n                            $upload['size'] : $this->get_server_var('CONTENT_LENGTH')),\n                    isset($upload['type']) ?\n                            $upload['type'] : $this->get_server_var('CONTENT_TYPE'),\n                    isset($upload['error']) ? $upload['error'] : null,\n                    null,\n                    $content_range\n                );\n            }\n        }\n        $response = array($this->options['param_name'] => $files);\n        return $this->generate_response($response, $print_response);\n    }\n\n    public function delete($print_response = true) {\n        $file_names = $this->get_file_names_params();\n        if (empty($file_names)) {\n            $file_names = array($this->get_file_name_param());\n        }\n        $response = array();\n        foreach ($file_names as $file_name) {\n            $file_path = $this->get_upload_path($file_name);\n            $success = is_file($file_path) && $file_name[0] !== '.' && unlink($file_path);\n            if ($success) {\n                foreach ($this->options['image_versions'] as $version => $options) {\n                    if (!empty($version)) {\n                        $file = $this->get_upload_path($file_name, $version);\n                        if (is_file($file)) {\n                            unlink($file);\n                        }\n                    }\n                }\n            }\n            $response[$file_name] = $success;\n        }\n        return $this->generate_response($response, $print_response);\n    }\n\n    protected function basename($filepath, $suffix = null) {\n        $splited = preg_split('/\\//', rtrim ($filepath, '/ '));\n        return substr(basename('X'.$splited[count($splited)-1], $suffix), 1);\n    }\n}\n"
  },
  {
    "path": "app_backend/static/plugin/jQuery-File-Upload-9.18.0/server/php/docker-compose.yml",
    "content": "apache:\n  build: ./\n  ports:\n    - \"80:80\"\n  volumes:\n    - \"../../:/var/www/html\"\n"
  },
  {
    "path": "app_backend/static/plugin/jQuery-File-Upload-9.18.0/server/php/files/.gitignore",
    "content": "*\n!.gitignore\n!.htaccess\n"
  },
  {
    "path": "app_backend/static/plugin/jQuery-File-Upload-9.18.0/server/php/files/.htaccess",
    "content": "# To enable the Headers module, execute the following command and reload Apache:\n# sudo a2enmod headers\n\n# The following directives prevent the execution of script files\n# in the context of the website.\n# They also force the content-type application/octet-stream and\n# force browsers to display a download dialog for non-image files.\nSetHandler default-handler\nForceType application/octet-stream\nHeader set Content-Disposition attachment\n\n# The following unsets the forced type and Content-Disposition headers\n# for known image files:\n<FilesMatch \"(?i)\\.(gif|jpe?g|png)$\">\n\tForceType none\n\tHeader unset Content-Disposition\n</FilesMatch>\n\n# The following directive prevents browsers from MIME-sniffing the content-type.\n# This is an important complement to the ForceType directive above:\nHeader set X-Content-Type-Options nosniff\n\n# Uncomment the following lines to prevent unauthorized download of files:\n#AuthName \"Authorization required\"\n#AuthType Basic\n#require valid-user\n"
  },
  {
    "path": "app_backend/static/plugin/jQuery-File-Upload-9.18.0/server/php/index.php",
    "content": "<?php\n/*\n * jQuery File Upload Plugin PHP Example\n * https://github.com/blueimp/jQuery-File-Upload\n *\n * Copyright 2010, Sebastian Tschan\n * https://blueimp.net\n *\n * Licensed under the MIT license:\n * https://opensource.org/licenses/MIT\n */\n\nerror_reporting(E_ALL | E_STRICT);\nrequire('UploadHandler.php');\n$upload_handler = new UploadHandler();\n"
  },
  {
    "path": "app_backend/static/plugin/jQuery-File-Upload-9.18.0/test/index.html",
    "content": "<!DOCTYPE HTML>\n<!--\n/*\n * jQuery File Upload Plugin Test\n * https://github.com/blueimp/jQuery-File-Upload\n *\n * Copyright 2010, Sebastian Tschan\n * https://blueimp.net\n *\n * Licensed under the MIT license:\n * https://opensource.org/licenses/MIT\n */\n-->\n<html lang=\"en\">\n<head>\n<!-- Force latest IE rendering engine or ChromeFrame if installed -->\n<!--[if IE]>\n<meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge,chrome=1\">\n<![endif]-->\n<meta charset=\"utf-8\">\n<title>jQuery File Upload Plugin Test</title>\n<meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n<link rel=\"stylesheet\" href=\"//codeorigin.jquery.com/qunit/qunit-1.14.0.css\">\n</head>\n<body>\n<h1 id=\"qunit-header\">jQuery File Upload Plugin Test</h1>\n<h2 id=\"qunit-banner\"></h2>\n<div id=\"qunit-testrunner-toolbar\"></div>\n<h2 id=\"qunit-userAgent\"></h2>\n<ol id=\"qunit-tests\"></ol>\n<div id=\"qunit-fixture\">\n    <!-- The file upload form used as target for the file upload widget -->\n    <form id=\"fileupload\" action=\"../server/php/\" method=\"POST\" enctype=\"multipart/form-data\">\n        <!-- The fileupload-buttonbar contains buttons to add/delete files and start/cancel the upload -->\n       <div class=\"row fileupload-buttonbar\">\n            <div class=\"col-lg-7\">\n                <!-- The fileinput-button span is used to style the file input field as button -->\n                <span class=\"btn btn-success fileinput-button\">\n                    <i class=\"icon-plus icon-white\"></i>\n                    <span>Add files...</span>\n                    <input type=\"file\" name=\"files[]\" multiple>\n                </span>\n                <button type=\"submit\" class=\"btn btn-primary start\">\n                    <i class=\"icon-upload icon-white\"></i>\n                    <span>Start upload</span>\n                </button>\n                <button type=\"reset\" class=\"btn btn-warning cancel\">\n                    <i class=\"icon-ban-circle icon-white\"></i>\n                    <span>Cancel upload</span>\n                </button>\n                <button type=\"button\" class=\"btn btn-danger delete\">\n                    <i class=\"icon-trash icon-white\"></i>\n                    <span>Delete</span>\n                </button>\n                <input type=\"checkbox\" class=\"toggle\">\n                <!-- The global file processing state -->\n                <span class=\"fileupload-process\"></span>\n            </div>\n            <!-- The global progress state -->\n            <div class=\"col-lg-5 fileupload-progress\">\n                <!-- The global progress bar -->\n                <div class=\"progress progress-striped active\" role=\"progressbar\" aria-valuemin=\"0\" aria-valuemax=\"100\">\n                    <div class=\"progress-bar progress-bar-success\" style=\"width:0%;\"></div>\n                </div>\n                <!-- The extended global progress state -->\n                <div class=\"progress-extended\">&nbsp;</div>\n            </div>\n        </div>\n        <!-- The table listing the files available for upload/download -->\n        <table role=\"presentation\" class=\"table table-striped\"><tbody class=\"files\"></tbody></table>\n    </form>\n</div>\n<!-- The template to display files available for upload -->\n<script id=\"template-upload\" type=\"text/x-tmpl\">\n{% for (var i=0, file; file=o.files[i]; i++) { %}\n    <tr class=\"template-upload\">\n        <td>\n            <span class=\"preview\"></span>\n        </td>\n        <td>\n            <p class=\"name\">{%=file.name%}</p>\n            <strong class=\"error text-danger\"></strong>\n        </td>\n        <td>\n            <p class=\"size\">Processing...</p>\n            <div class=\"progress progress-striped active\" role=\"progressbar\" aria-valuemin=\"0\" aria-valuemax=\"100\" aria-valuenow=\"0\"><div class=\"progress-bar progress-bar-success\" style=\"width:0%;\"></div></div>\n        </td>\n        <td>\n            {% if (!i && !o.options.autoUpload) { %}\n                <button class=\"btn btn-primary start\" disabled>\n                    <i class=\"glyphicon glyphicon-upload\"></i>\n                    <span>Start</span>\n                </button>\n            {% } %}\n            {% if (!i) { %}\n                <button class=\"btn btn-warning cancel\">\n                    <i class=\"glyphicon glyphicon-ban-circle\"></i>\n                    <span>Cancel</span>\n                </button>\n            {% } %}\n        </td>\n    </tr>\n{% } %}\n</script>\n<!-- The template to display files available for download -->\n<script id=\"template-download\" type=\"text/x-tmpl\">\n{% for (var i=0, file; file=o.files[i]; i++) { %}\n    <tr class=\"template-download\">\n        <td>\n            <span class=\"preview\">\n                {% if (file.thumbnailUrl) { %}\n                    <a href=\"{%=file.url%}\" title=\"{%=file.name%}\" download=\"{%=file.name%}\" data-gallery><img src=\"{%=file.thumbnailUrl%}\"></a>\n                {% } %}\n            </span>\n        </td>\n        <td>\n            <p class=\"name\">\n                {% if (file.url) { %}\n                    <a href=\"{%=file.url%}\" title=\"{%=file.name%}\" download=\"{%=file.name%}\" {%=file.thumbnailUrl?'data-gallery':''%}>{%=file.name%}</a>\n                {% } else { %}\n                    <span>{%=file.name%}</span>\n                {% } %}\n            </p>\n            {% if (file.error) { %}\n                <div><span class=\"label label-danger\">Error</span> {%=file.error%}</div>\n            {% } %}\n        </td>\n        <td>\n            <span class=\"size\">{%=o.formatFileSize(file.size)%}</span>\n        </td>\n        <td>\n            {% if (file.deleteUrl) { %}\n                <button class=\"btn btn-danger delete\" data-type=\"{%=file.deleteType%}\" data-url=\"{%=file.deleteUrl%}\"{% if (file.deleteWithCredentials) { %} data-xhr-fields='{\"withCredentials\":true}'{% } %}>\n                    <i class=\"glyphicon glyphicon-trash\"></i>\n                    <span>Delete</span>\n                </button>\n                <input type=\"checkbox\" name=\"delete\" value=\"1\" class=\"toggle\">\n            {% } else { %}\n                <button class=\"btn btn-warning cancel\">\n                    <i class=\"glyphicon glyphicon-ban-circle\"></i>\n                    <span>Cancel</span>\n                </button>\n            {% } %}\n        </td>\n    </tr>\n{% } %}\n</script>\n<script src=\"//ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js\"></script>\n<script src=\"../js/vendor/jquery.ui.widget.js\"></script>\n<script src=\"//blueimp.github.io/JavaScript-Templates/js/tmpl.min.js\"></script>\n<script src=\"//blueimp.github.io/JavaScript-Load-Image/js/load-image.all.min.js\"></script>\n<script src=\"//blueimp.github.io/JavaScript-Canvas-to-Blob/js/canvas-to-blob.min.js\"></script>\n<script src=\"../js/jquery.iframe-transport.js\"></script>\n<script src=\"../js/jquery.fileupload.js\"></script>\n<script>\n/* global window, $ */\nwindow.testBasicWidget = $.blueimp.fileupload;\n</script>\n<script src=\"../js/jquery.fileupload-process.js\"></script>\n<script src=\"../js/jquery.fileupload-image.js\"></script>\n<script src=\"../js/jquery.fileupload-audio.js\"></script>\n<script src=\"../js/jquery.fileupload-video.js\"></script>\n<script src=\"../js/jquery.fileupload-validate.js\"></script>\n<script src=\"../js/jquery.fileupload-ui.js\"></script>\n<script>\n/* global window, $ */\nwindow.testUIWidget = $.blueimp.fileupload;\n</script>\n<script src=\"//code.jquery.com/qunit/qunit-1.15.0.js\"></script>\n<script src=\"test.js\"></script>\n</body>\n</html>\n"
  },
  {
    "path": "app_backend/static/plugin/jQuery-File-Upload-9.18.0/test/test.js",
    "content": "/*\n * jQuery File Upload Plugin Test\n * https://github.com/blueimp/jQuery-File-Upload\n *\n * Copyright 2010, Sebastian Tschan\n * https://blueimp.net\n *\n * Licensed under the MIT license:\n * https://opensource.org/licenses/MIT\n */\n\n/* global $, QUnit, window, document, expect, module, test, asyncTest, start, ok, strictEqual, notStrictEqual */\n\n$(function () {\n    // jshint nomen:false\n    'use strict';\n\n    QUnit.done = function () {\n        // Delete all uploaded files:\n        var url = $('#fileupload').prop('action');\n        $.getJSON(url, function (result) {\n            $.each(result.files, function (index, file) {\n                $.ajax({\n                    url: url + '?file=' + encodeURIComponent(file.name),\n                    type: 'DELETE'\n                });\n            });\n        });\n    };\n\n    var lifecycle = {\n            setup: function () {\n                // Set the .fileupload method to the basic widget method:\n                $.widget('blueimp.fileupload', window.testBasicWidget, {});\n            },\n            teardown: function () {\n                // Remove all remaining event listeners:\n                $(document).unbind();\n            }\n        },\n        lifecycleUI = {\n            setup: function () {\n                // Set the .fileupload method to the UI widget method:\n                $.widget('blueimp.fileupload', window.testUIWidget, {});\n            },\n            teardown: function () {\n                // Remove all remaining event listeners:\n                $(document).unbind();\n            }\n        };\n\n    module('Initialization', lifecycle);\n\n    test('Widget initialization', function () {\n        var fu = $('#fileupload').fileupload();\n        ok(fu.data('blueimp-fileupload') || fu.data('fileupload'));\n    });\n\n    test('Data attribute options', function () {\n        $('#fileupload').attr('data-url', 'http://example.org');\n        $('#fileupload').fileupload();\n        strictEqual(\n            $('#fileupload').fileupload('option', 'url'),\n            'http://example.org'\n        );\n    });\n\n    test('File input initialization', function () {\n        var fu = $('#fileupload').fileupload();\n        ok(\n            fu.fileupload('option', 'fileInput').length,\n            'File input field inside of the widget'\n        );\n        ok(\n            fu.fileupload('option', 'fileInput').length,\n            'Widget element as file input field'\n        );\n    });\n\n    test('Drop zone initialization', function () {\n        ok($('#fileupload').fileupload()\n            .fileupload('option', 'dropZone').length);\n    });\n\n    test('Paste zone initialization', function () {\n        ok($('#fileupload').fileupload({pasteZone: document})\n            .fileupload('option', 'pasteZone').length);\n    });\n\n    test('Event listeners initialization', function () {\n        expect(\n            $.support.xhrFormDataFileUpload ? 4 : 1\n        );\n        var eo = {\n                originalEvent: {\n                    dataTransfer: {files: [{}], types: ['Files']},\n                    clipboardData: {items: [{}]}\n                }\n            },\n            fu = $('#fileupload').fileupload({\n                pasteZone: document,\n                dragover: function () {\n                    ok(true, 'Triggers dragover callback');\n                    return false;\n                },\n                drop: function () {\n                    ok(true, 'Triggers drop callback');\n                    return false;\n                },\n                paste: function () {\n                    ok(true, 'Triggers paste callback');\n                    return false;\n                },\n                change: function () {\n                    ok(true, 'Triggers change callback');\n                    return false;\n                }\n            }),\n            fileInput = fu.fileupload('option', 'fileInput'),\n            dropZone = fu.fileupload('option', 'dropZone'),\n            pasteZone = fu.fileupload('option', 'pasteZone');\n        fileInput.trigger($.Event('change', eo));\n        dropZone.trigger($.Event('dragover', eo));\n        dropZone.trigger($.Event('drop', eo));\n        pasteZone.trigger($.Event('paste', eo));\n    });\n\n    module('API', lifecycle);\n\n    test('destroy', function () {\n        expect(4);\n        var eo = {\n                originalEvent: {\n                    dataTransfer: {files: [{}], types: ['Files']},\n                    clipboardData: {items: [{}]}\n                }\n            },\n            options = {\n                pasteZone: document,\n                dragover: function () {\n                    ok(true, 'Triggers dragover callback');\n                    return false;\n                },\n                drop: function () {\n                    ok(true, 'Triggers drop callback');\n                    return false;\n                },\n                paste: function () {\n                    ok(true, 'Triggers paste callback');\n                    return false;\n                },\n                change: function () {\n                    ok(true, 'Triggers change callback');\n                    return false;\n                }\n            },\n            fu = $('#fileupload').fileupload(options),\n            fileInput = fu.fileupload('option', 'fileInput'),\n            dropZone = fu.fileupload('option', 'dropZone'),\n            pasteZone = fu.fileupload('option', 'pasteZone');\n        dropZone.bind('dragover', options.dragover);\n        dropZone.bind('drop', options.drop);\n        pasteZone.bind('paste', options.paste);\n        fileInput.bind('change', options.change);\n        fu.fileupload('destroy');\n        fileInput.trigger($.Event('change', eo));\n        dropZone.trigger($.Event('dragover', eo));\n        dropZone.trigger($.Event('drop', eo));\n        pasteZone.trigger($.Event('paste', eo));\n    });\n\n    test('disable/enable', function () {\n        expect(\n            $.support.xhrFormDataFileUpload ? 4 : 1\n        );\n        var eo = {\n                originalEvent: {\n                    dataTransfer: {files: [{}], types: ['Files']},\n                    clipboardData: {items: [{}]}\n                }\n            },\n            fu = $('#fileupload').fileupload({\n                pasteZone: document,\n                dragover: function () {\n                    ok(true, 'Triggers dragover callback');\n                    return false;\n                },\n                drop: function () {\n                    ok(true, 'Triggers drop callback');\n                    return false;\n                },\n                paste: function () {\n                    ok(true, 'Triggers paste callback');\n                    return false;\n                },\n                change: function () {\n                    ok(true, 'Triggers change callback');\n                    return false;\n                }\n            }),\n            fileInput = fu.fileupload('option', 'fileInput'),\n            dropZone = fu.fileupload('option', 'dropZone'),\n            pasteZone = fu.fileupload('option', 'pasteZone');\n        fu.fileupload('disable');\n        fileInput.trigger($.Event('change', eo));\n        dropZone.trigger($.Event('dragover', eo));\n        dropZone.trigger($.Event('drop', eo));\n        pasteZone.trigger($.Event('paste', eo));\n        fu.fileupload('enable');\n        fileInput.trigger($.Event('change', eo));\n        dropZone.trigger($.Event('dragover', eo));\n        dropZone.trigger($.Event('drop', eo));\n        pasteZone.trigger($.Event('paste', eo));\n    });\n\n    test('option', function () {\n        expect(\n            $.support.xhrFormDataFileUpload ? 10 : 7\n        );\n        var eo = {\n                originalEvent: {\n                    dataTransfer: {files: [{}], types: ['Files']},\n                    clipboardData: {items: [{}]}\n                }\n            },\n            fu = $('#fileupload').fileupload({\n                pasteZone: document,\n                dragover: function () {\n                    ok(true, 'Triggers dragover callback');\n                    return false;\n                },\n                drop: function () {\n                    ok(true, 'Triggers drop callback');\n                    return false;\n                },\n                paste: function () {\n                    ok(true, 'Triggers paste callback');\n                    return false;\n                },\n                change: function () {\n                    ok(true, 'Triggers change callback');\n                    return false;\n                }\n            }),\n            fileInput = fu.fileupload('option', 'fileInput'),\n            dropZone = fu.fileupload('option', 'dropZone'),\n            pasteZone = fu.fileupload('option', 'pasteZone');\n        fu.fileupload('option', 'fileInput', null);\n        fu.fileupload('option', 'dropZone', null);\n        fu.fileupload('option', 'pasteZone', null);\n        fileInput.trigger($.Event('change', eo));\n        dropZone.trigger($.Event('dragover', eo));\n        dropZone.trigger($.Event('drop', eo));\n        pasteZone.trigger($.Event('paste', eo));\n        fu.fileupload('option', 'dropZone', 'body');\n        strictEqual(\n            fu.fileupload('option', 'dropZone')[0],\n            document.body,\n            'Allow a query string as parameter for the dropZone option'\n        );\n        fu.fileupload('option', 'dropZone', document);\n        strictEqual(\n            fu.fileupload('option', 'dropZone')[0],\n            document,\n            'Allow a document element as parameter for the dropZone option'\n        );\n        fu.fileupload('option', 'pasteZone', 'body');\n        strictEqual(\n            fu.fileupload('option', 'pasteZone')[0],\n            document.body,\n            'Allow a query string as parameter for the pasteZone option'\n        );\n        fu.fileupload('option', 'pasteZone', document);\n        strictEqual(\n            fu.fileupload('option', 'pasteZone')[0],\n            document,\n            'Allow a document element as parameter for the pasteZone option'\n        );\n        fu.fileupload('option', 'fileInput', ':file');\n        strictEqual(\n            fu.fileupload('option', 'fileInput')[0],\n            $(':file')[0],\n            'Allow a query string as parameter for the fileInput option'\n        );\n        fu.fileupload('option', 'fileInput', $(':file')[0]);\n        strictEqual(\n            fu.fileupload('option', 'fileInput')[0],\n            $(':file')[0],\n            'Allow a document element as parameter for the fileInput option'\n        );\n        fu.fileupload('option', 'fileInput', fileInput);\n        fu.fileupload('option', 'dropZone', dropZone);\n        fu.fileupload('option', 'pasteZone', pasteZone);\n        fileInput.trigger($.Event('change', eo));\n        dropZone.trigger($.Event('dragover', eo));\n        dropZone.trigger($.Event('drop', eo));\n        pasteZone.trigger($.Event('paste', eo));\n    });\n\n    asyncTest('add', function () {\n        expect(2);\n        var param = {files: [{name: 'test'}]};\n        $('#fileupload').fileupload({\n            add: function (e, data) {\n                strictEqual(\n                    data.files[0].name,\n                    param.files[0].name,\n                    'Triggers add callback'\n                );\n            }\n        }).fileupload('add', param).fileupload(\n            'option',\n            'add',\n            function (e, data) {\n                data.submit().complete(function () {\n                    ok(true, 'data.submit() Returns a jqXHR object');\n                    start();\n                });\n            }\n        ).fileupload('add', param);\n    });\n\n    asyncTest('send', function () {\n        expect(3);\n        var param = {files: [{name: 'test'}]};\n        $('#fileupload').fileupload({\n            send: function (e, data) {\n                strictEqual(\n                    data.files[0].name,\n                    'test',\n                    'Triggers send callback'\n                );\n            }\n        }).fileupload('send', param).fail(function () {\n            ok(true, 'Allows to abort the request');\n        }).complete(function () {\n            ok(true, 'Returns a jqXHR object');\n            start();\n        }).abort();\n    });\n\n    module('Callbacks', lifecycle);\n\n    asyncTest('add', function () {\n        expect(1);\n        var param = {files: [{name: 'test'}]};\n        $('#fileupload').fileupload({\n            add: function () {\n                ok(true, 'Triggers add callback');\n                start();\n            }\n        }).fileupload('add', param);\n    });\n\n    asyncTest('submit', function () {\n        expect(1);\n        var param = {files: [{name: 'test'}]};\n        $('#fileupload').fileupload({\n            submit: function () {\n                ok(true, 'Triggers submit callback');\n                start();\n                return false;\n            }\n        }).fileupload('add', param);\n    });\n\n    asyncTest('send', function () {\n        expect(1);\n        var param = {files: [{name: 'test'}]};\n        $('#fileupload').fileupload({\n            send: function () {\n                ok(true, 'Triggers send callback');\n                start();\n                return false;\n            }\n        }).fileupload('send', param);\n    });\n\n    asyncTest('done', function () {\n        expect(1);\n        var param = {files: [{name: 'test'}]};\n        $('#fileupload').fileupload({\n            done: function () {\n                ok(true, 'Triggers done callback');\n                start();\n            }\n        }).fileupload('send', param);\n    });\n\n    asyncTest('fail', function () {\n        expect(1);\n        var param = {files: [{name: 'test'}]},\n            fu = $('#fileupload').fileupload({\n                url: '404',\n                fail: function () {\n                    ok(true, 'Triggers fail callback');\n                    start();\n                }\n            });\n        (fu.data('blueimp-fileupload') || fu.data('fileupload'))\n            ._isXHRUpload = function () {\n                return true;\n            };\n        fu.fileupload('send', param);\n    });\n\n    asyncTest('always', function () {\n        expect(2);\n        var param = {files: [{name: 'test'}]},\n            counter = 0,\n            fu = $('#fileupload').fileupload({\n                always: function () {\n                    ok(true, 'Triggers always callback');\n                    if (counter === 1) {\n                        start();\n                    } else {\n                        counter += 1;\n                    }\n                }\n            });\n        (fu.data('blueimp-fileupload') || fu.data('fileupload'))\n            ._isXHRUpload = function () {\n                return true;\n            };\n        fu.fileupload('add', param).fileupload(\n            'option',\n            'url',\n            '404'\n        ).fileupload('add', param);\n    });\n\n    asyncTest('progress', function () {\n        expect(1);\n        var param = {files: [{name: 'test'}]},\n            counter = 0;\n        $('#fileupload').fileupload({\n            forceIframeTransport: true,\n            progress: function () {\n                ok(true, 'Triggers progress callback');\n                if (counter === 0) {\n                    start();\n                } else {\n                    counter += 1;\n                }\n            }\n        }).fileupload('send', param);\n    });\n\n    asyncTest('progressall', function () {\n        expect(1);\n        var param = {files: [{name: 'test'}]},\n            counter = 0;\n        $('#fileupload').fileupload({\n            forceIframeTransport: true,\n            progressall: function () {\n                ok(true, 'Triggers progressall callback');\n                if (counter === 0) {\n                    start();\n                } else {\n                    counter += 1;\n                }\n            }\n        }).fileupload('send', param);\n    });\n\n    asyncTest('start', function () {\n        expect(1);\n        var param = {files: [{name: '1'}, {name: '2'}]},\n            active = 0;\n        $('#fileupload').fileupload({\n            send: function () {\n                active += 1;\n            },\n            start: function () {\n                ok(!active, 'Triggers start callback before uploads');\n                start();\n            }\n        }).fileupload('send', param);\n    });\n\n    asyncTest('stop', function () {\n        expect(1);\n        var param = {files: [{name: '1'}, {name: '2'}]},\n            active = 0;\n        $('#fileupload').fileupload({\n            send: function () {\n                active += 1;\n            },\n            always: function () {\n                active -= 1;\n            },\n            stop: function () {\n                ok(!active, 'Triggers stop callback after uploads');\n                start();\n            }\n        }).fileupload('send', param);\n    });\n\n    test('change', function () {\n        var fu = $('#fileupload').fileupload(),\n            fuo = fu.data('blueimp-fileupload') || fu.data('fileupload'),\n            fileInput = fu.fileupload('option', 'fileInput');\n        expect(2);\n        fu.fileupload({\n            change: function (e, data) {\n                ok(true, 'Triggers change callback');\n                strictEqual(\n                    data.files.length,\n                    0,\n                    'Returns empty files list'\n                );\n            },\n            add: $.noop\n        });\n        fuo._onChange({\n            data: {fileupload: fuo},\n            target: fileInput[0]\n        });\n    });\n\n    test('paste', function () {\n        var fu = $('#fileupload').fileupload(),\n            fuo = fu.data('blueimp-fileupload') || fu.data('fileupload');\n        expect(1);\n        fu.fileupload({\n            paste: function () {\n                ok(true, 'Triggers paste callback');\n            },\n            add: $.noop\n        });\n        fuo._onPaste({\n            data: {fileupload: fuo},\n            originalEvent: {\n                dataTransfer: {files: [{}]},\n                clipboardData: {items: [{}]}\n            },\n            preventDefault: $.noop\n        });\n    });\n\n    test('drop', function () {\n        var fu = $('#fileupload').fileupload(),\n            fuo = fu.data('blueimp-fileupload') || fu.data('fileupload');\n        expect(1);\n        fu.fileupload({\n            drop: function () {\n                ok(true, 'Triggers drop callback');\n            },\n            add: $.noop\n        });\n        fuo._onDrop({\n            data: {fileupload: fuo},\n            originalEvent: {\n                dataTransfer: {files: [{}]},\n                clipboardData: {items: [{}]}\n            },\n            preventDefault: $.noop\n        });\n    });\n\n    test('dragover', function () {\n        var fu = $('#fileupload').fileupload(),\n            fuo = fu.data('blueimp-fileupload') || fu.data('fileupload');\n        expect(1);\n        fu.fileupload({\n            dragover: function () {\n                ok(true, 'Triggers dragover callback');\n            },\n            add: $.noop\n        });\n        fuo._onDragOver({\n            data: {fileupload: fuo},\n            originalEvent: {dataTransfer: {types: ['Files']}},\n            preventDefault: $.noop\n        });\n    });\n\n    module('Options', lifecycle);\n\n    test('paramName', function () {\n        expect(1);\n        var param = {files: [{name: 'test'}]};\n        $('#fileupload').fileupload({\n            paramName: null,\n            send: function (e, data) {\n                strictEqual(\n                    data.paramName[0],\n                    data.fileInput.prop('name'),\n                    'Takes paramName from file input field if not set'\n                );\n                return false;\n            }\n        }).fileupload('send', param);\n    });\n\n    test('url', function () {\n        expect(1);\n        var param = {files: [{name: 'test'}]};\n        $('#fileupload').fileupload({\n            url: null,\n            send: function (e, data) {\n                strictEqual(\n                    data.url,\n                    $(data.fileInput.prop('form')).prop('action'),\n                    'Takes url from form action if not set'\n                );\n                return false;\n            }\n        }).fileupload('send', param);\n    });\n\n    test('type', function () {\n        expect(2);\n        var param = {files: [{name: 'test'}]};\n        $('#fileupload').fileupload({\n            type: null,\n            send: function (e, data) {\n                strictEqual(\n                    data.type,\n                    'POST',\n                    'Request type is \"POST\" if not set to \"PUT\"'\n                );\n                return false;\n            }\n        }).fileupload('send', param);\n        $('#fileupload').fileupload({\n            type: 'PUT',\n            send: function (e, data) {\n                strictEqual(\n                    data.type,\n                    'PUT',\n                    'Request type is \"PUT\" if set to \"PUT\"'\n                );\n                return false;\n            }\n        }).fileupload('send', param);\n    });\n\n    test('replaceFileInput', function () {\n        var fu = $('#fileupload').fileupload(),\n            fuo = fu.data('blueimp-fileupload') || fu.data('fileupload'),\n            fileInput = fu.fileupload('option', 'fileInput'),\n            fileInputElement = fileInput[0];\n        expect(2);\n        fu.fileupload({\n            replaceFileInput: false,\n            change: function () {\n                strictEqual(\n                    fu.fileupload('option', 'fileInput')[0],\n                    fileInputElement,\n                    'Keeps file input with replaceFileInput: false'\n                );\n            },\n            add: $.noop\n        });\n        fuo._onChange({\n            data: {fileupload: fuo},\n            target: fileInput[0]\n        });\n        fu.fileupload({\n            replaceFileInput: true,\n            change: function () {\n                notStrictEqual(\n                    fu.fileupload('option', 'fileInput')[0],\n                    fileInputElement,\n                    'Replaces file input with replaceFileInput: true'\n                );\n            },\n            add: $.noop\n        });\n        fuo._onChange({\n            data: {fileupload: fuo},\n            target: fileInput[0]\n        });\n    });\n\n    asyncTest('forceIframeTransport', function () {\n        expect(1);\n        var param = {files: [{name: 'test'}]};\n        $('#fileupload').fileupload({\n            forceIframeTransport: true,\n            done: function (e, data) {\n                strictEqual(\n                    data.dataType.substr(0, 6),\n                    'iframe',\n                    'Iframe Transport is used'\n                );\n                start();\n            }\n        }).fileupload('send', param);\n    });\n\n    test('singleFileUploads', function () {\n        expect(3);\n        var fu = $('#fileupload').fileupload(),\n            param = {files: [{name: '1'}, {name: '2'}]},\n            index = 1;\n        (fu.data('blueimp-fileupload') || fu.data('fileupload'))\n            ._isXHRUpload = function () {\n                return true;\n            };\n        $('#fileupload').fileupload({\n            singleFileUploads: true,\n            add: function () {\n                ok(true, 'Triggers callback number ' + index.toString());\n                index += 1;\n            }\n        }).fileupload('add', param).fileupload(\n            'option',\n            'singleFileUploads',\n            false\n        ).fileupload('add', param);\n    });\n\n    test('limitMultiFileUploads', function () {\n        expect(3);\n        var fu = $('#fileupload').fileupload(),\n            param = {files: [\n                {name: '1'},\n                {name: '2'},\n                {name: '3'},\n                {name: '4'},\n                {name: '5'}\n            ]},\n            index = 1;\n        (fu.data('blueimp-fileupload') || fu.data('fileupload'))\n            ._isXHRUpload = function () {\n                return true;\n            };\n        $('#fileupload').fileupload({\n            singleFileUploads: false,\n            limitMultiFileUploads: 2,\n            add: function () {\n                ok(true, 'Triggers callback number ' + index.toString());\n                index += 1;\n            }\n        }).fileupload('add', param);\n    });\n\n    test('limitMultiFileUploadSize', function () {\n        expect(7);\n        var fu = $('#fileupload').fileupload(),\n            param = {files: [\n                {name: '1-1', size: 100000},\n                {name: '1-2', size: 40000},\n                {name: '2-1', size: 100000},\n                {name: '3-1', size: 50000},\n                {name: '3-2', size: 40000},\n                {name: '4-1', size: 45000} // New request due to limitMultiFileUploads\n            ]},\n            param2 = {files: [\n                {name: '5-1'},\n                {name: '5-2'},\n                {name: '6-1'},\n                {name: '6-2'},\n                {name: '7-1'}\n            ]},\n            index = 1;\n        (fu.data('blueimp-fileupload') || fu.data('fileupload'))\n            ._isXHRUpload = function () {\n                return true;\n            };\n        $('#fileupload').fileupload({\n            singleFileUploads: false,\n            limitMultiFileUploads: 2,\n            limitMultiFileUploadSize: 150000,\n            limitMultiFileUploadSizeOverhead: 5000,\n            add: function () {\n                ok(true, 'Triggers callback number ' + index.toString());\n                index += 1;\n            }\n        }).fileupload('add', param).fileupload('add', param2);\n    });\n\n    asyncTest('sequentialUploads', function () {\n        expect(6);\n        var param = {files: [\n                {name: '1'},\n                {name: '2'},\n                {name: '3'},\n                {name: '4'},\n                {name: '5'},\n                {name: '6'}\n            ]},\n            addIndex = 0,\n            sendIndex = 0,\n            loadIndex = 0,\n            fu = $('#fileupload').fileupload({\n                sequentialUploads: true,\n                add: function (e, data) {\n                    addIndex += 1;\n                    if (addIndex === 4) {\n                        data.submit().abort();\n                    } else {\n                        data.submit();\n                    }\n                },\n                send: function () {\n                    sendIndex += 1;\n                },\n                done: function () {\n                    loadIndex += 1;\n                    strictEqual(sendIndex, loadIndex, 'upload in order');\n                },\n                fail: function (e, data) {\n                    strictEqual(data.errorThrown, 'abort', 'upload aborted');\n                },\n                stop: function () {\n                    start();\n                }\n            });\n        (fu.data('blueimp-fileupload') || fu.data('fileupload'))\n            ._isXHRUpload = function () {\n                return true;\n            };\n        fu.fileupload('add', param);\n    });\n\n    asyncTest('limitConcurrentUploads', function () {\n        expect(12);\n        var param = {files: [\n                {name: '1'},\n                {name: '2'},\n                {name: '3'},\n                {name: '4'},\n                {name: '5'},\n                {name: '6'},\n                {name: '7'},\n                {name: '8'},\n                {name: '9'},\n                {name: '10'},\n                {name: '11'},\n                {name: '12'}\n            ]},\n            addIndex = 0,\n            sendIndex = 0,\n            loadIndex = 0,\n            fu = $('#fileupload').fileupload({\n                limitConcurrentUploads: 3,\n                add: function (e, data) {\n                    addIndex += 1;\n                    if (addIndex === 4) {\n                        data.submit().abort();\n                    } else {\n                        data.submit();\n                    }\n                },\n                send: function () {\n                    sendIndex += 1;\n                },\n                done: function () {\n                    loadIndex += 1;\n                    ok(sendIndex - loadIndex < 3);\n                },\n                fail: function (e, data) {\n                    strictEqual(data.errorThrown, 'abort', 'upload aborted');\n                },\n                stop: function () {\n                    start();\n                }\n            });\n        (fu.data('blueimp-fileupload') || fu.data('fileupload'))\n            ._isXHRUpload = function () {\n                return true;\n            };\n        fu.fileupload('add', param);\n    });\n\n    if ($.support.xhrFileUpload) {\n        asyncTest('multipart', function () {\n            expect(2);\n            var param = {files: [{\n                    name: 'test.png',\n                    size: 123,\n                    type: 'image/png'\n                }]},\n                fu = $('#fileupload').fileupload({\n                    multipart: false,\n                    always: function (e, data) {\n                        strictEqual(\n                            data.contentType,\n                            param.files[0].type,\n                            'non-multipart upload sets file type as contentType'\n                        );\n                        strictEqual(\n                            data.headers['Content-Disposition'],\n                            'attachment; filename=\"' + param.files[0].name + '\"',\n                            'non-multipart upload sets Content-Disposition header'\n                        );\n                        start();\n                    }\n                });\n            fu.fileupload('send', param);\n        });\n    }\n\n    module('UI Initialization', lifecycleUI);\n\n    test('Widget initialization', function () {\n        var fu = $('#fileupload').fileupload();\n        ok(fu.data('blueimp-fileupload') || fu.data('fileupload'));\n        ok(\n            $('#fileupload').fileupload('option', 'uploadTemplate').length,\n            'Initialized upload template'\n        );\n        ok(\n            $('#fileupload').fileupload('option', 'downloadTemplate').length,\n            'Initialized download template'\n        );\n    });\n\n    test('Buttonbar event listeners', function () {\n        var buttonbar = $('#fileupload .fileupload-buttonbar'),\n            files = [{name: 'test'}];\n        expect(4);\n        $('#fileupload').fileupload({\n            send: function () {\n                ok(true, 'Started file upload via global start button');\n            },\n            fail: function (e, data) {\n                ok(true, 'Canceled file upload via global cancel button');\n                data.context.remove();\n            },\n            destroy: function () {\n                ok(true, 'Delete action called via global delete button');\n            }\n        });\n        $('#fileupload').fileupload('add', {files: files});\n        buttonbar.find('.cancel').click();\n        $('#fileupload').fileupload('add', {files: files});\n        buttonbar.find('.start').click();\n        buttonbar.find('.cancel').click();\n        files[0].deleteUrl = 'http://example.org/banana.jpg';\n        ($('#fileupload').data('blueimp-fileupload') ||\n                $('#fileupload').data('fileupload'))\n            ._renderDownload(files)\n            .appendTo($('#fileupload .files')).show()\n            .find('.toggle').click();\n        buttonbar.find('.delete').click();\n    });\n\n    module('UI API', lifecycleUI);\n\n    test('destroy', function () {\n        var buttonbar = $('#fileupload .fileupload-buttonbar'),\n            files = [{name: 'test'}];\n        expect(1);\n        $('#fileupload').fileupload({\n            send: function () {\n                ok(true, 'This test should not run');\n                return false;\n            }\n        })\n            .fileupload('add', {files: files})\n            .fileupload('destroy');\n        buttonbar.find('.start').click(function () {\n            ok(true, 'Clicked global start button');\n            return false;\n        }).click();\n    });\n\n    test('disable/enable', function () {\n        var buttonbar = $('#fileupload .fileupload-buttonbar');\n        $('#fileupload').fileupload();\n        $('#fileupload').fileupload('disable');\n        strictEqual(\n            buttonbar.find('input[type=file], button').not(':disabled').length,\n            0,\n            'Disables the buttonbar buttons'\n        );\n        $('#fileupload').fileupload('enable');\n        strictEqual(\n            buttonbar.find('input[type=file], button').not(':disabled').length,\n            4,\n            'Enables the buttonbar buttons'\n        );\n    });\n\n    module('UI Callbacks', lifecycleUI);\n\n    test('destroy', function () {\n        expect(3);\n        $('#fileupload').fileupload({\n            destroy: function (e, data) {\n                ok(true, 'Triggers destroy callback');\n                strictEqual(\n                    data.url,\n                    'test',\n                    'Passes over deletion url parameter'\n                );\n                strictEqual(\n                    data.type,\n                    'DELETE',\n                    'Passes over deletion request type parameter'\n                );\n            }\n        });\n        ($('#fileupload').data('blueimp-fileupload') ||\n                $('#fileupload').data('fileupload'))\n            ._renderDownload([{\n                name: 'test',\n                deleteUrl: 'test',\n                deleteType: 'DELETE'\n            }])\n            .appendTo($('#fileupload .files'))\n            .show()\n            .find('.toggle').click();\n        $('#fileupload .fileupload-buttonbar .delete').click();\n    });\n\n    asyncTest('added', function () {\n        expect(1);\n        var param = {files: [{name: 'test'}]};\n        $('#fileupload').fileupload({\n            added: function (e, data) {\n                start();\n                strictEqual(\n                    data.files[0].name,\n                    param.files[0].name,\n                    'Triggers added callback'\n                );\n            },\n            send: function () {\n                return false;\n            }\n        }).fileupload('add', param);\n    });\n\n    asyncTest('started', function () {\n        expect(1);\n        var param = {files: [{name: 'test'}]};\n        $('#fileupload').fileupload({\n            started: function () {\n                start();\n                ok('Triggers started callback');\n                return false;\n            },\n            sent: function () {\n                return false;\n            }\n        }).fileupload('send', param);\n    });\n\n    asyncTest('sent', function () {\n        expect(1);\n        var param = {files: [{name: 'test'}]};\n        $('#fileupload').fileupload({\n            sent: function (e, data) {\n                start();\n                strictEqual(\n                    data.files[0].name,\n                    param.files[0].name,\n                    'Triggers sent callback'\n                );\n                return false;\n            }\n        }).fileupload('send', param);\n    });\n\n    asyncTest('completed', function () {\n        expect(1);\n        var param = {files: [{name: 'test'}]};\n        $('#fileupload').fileupload({\n            completed: function () {\n                start();\n                ok('Triggers completed callback');\n                return false;\n            }\n        }).fileupload('send', param);\n    });\n\n    asyncTest('failed', function () {\n        expect(1);\n        var param = {files: [{name: 'test'}]};\n        $('#fileupload').fileupload({\n            failed: function () {\n                start();\n                ok('Triggers failed callback');\n                return false;\n            }\n        }).fileupload('send', param).abort();\n    });\n\n    asyncTest('stopped', function () {\n        expect(1);\n        var param = {files: [{name: 'test'}]};\n        $('#fileupload').fileupload({\n            stopped: function () {\n                start();\n                ok('Triggers stopped callback');\n                return false;\n            }\n        }).fileupload('send', param);\n    });\n\n    asyncTest('destroyed', function () {\n        expect(1);\n        $('#fileupload').fileupload({\n            dataType: 'html',\n            destroyed: function () {\n                start();\n                ok(true, 'Triggers destroyed callback');\n            }\n        });\n        ($('#fileupload').data('blueimp-fileupload') ||\n                $('#fileupload').data('fileupload'))\n            ._renderDownload([{\n                name: 'test',\n                deleteUrl: '.',\n                deleteType: 'GET'\n            }])\n            .appendTo($('#fileupload .files'))\n            .show()\n            .find('.toggle').click();\n        $('#fileupload .fileupload-buttonbar .delete').click();\n    });\n\n    module('UI Options', lifecycleUI);\n\n    test('autoUpload', function () {\n        expect(1);\n        $('#fileupload')\n            .fileupload({\n                autoUpload: true,\n                send: function () {\n                    ok(true, 'Started file upload automatically');\n                    return false;\n                }\n            })\n            .fileupload('add', {files: [{name: 'test'}]})\n            .fileupload('option', 'autoUpload', false)\n            .fileupload('add', {files: [{name: 'test'}]});\n    });\n\n    test('maxNumberOfFiles', function () {\n        expect(3);\n        var addIndex = 0,\n            sendIndex = 0;\n        $('#fileupload')\n            .fileupload({\n                autoUpload: true,\n                maxNumberOfFiles: 3,\n                singleFileUploads: false,\n                send: function () {\n                    strictEqual(\n                        sendIndex += 1,\n                        addIndex\n                    );\n                },\n                progress: $.noop,\n                progressall: $.noop,\n                done: $.noop,\n                stop: $.noop\n            })\n            .fileupload('add', {files: [{name: (addIndex += 1)}]})\n            .fileupload('add', {files: [{name: (addIndex += 1)}]})\n            .fileupload('add', {files: [{name: (addIndex += 1)}]})\n            .fileupload('add', {files: [{name: 'test'}]});\n    });\n\n    test('maxFileSize', function () {\n        expect(2);\n        var addIndex = 0,\n            sendIndex = 0;\n        $('#fileupload')\n            .fileupload({\n                autoUpload: true,\n                maxFileSize: 1000,\n                send: function () {\n                    strictEqual(\n                        sendIndex += 1,\n                        addIndex\n                    );\n                    return false;\n                }\n            })\n            .fileupload('add', {files: [{\n                name: (addIndex += 1)\n            }]})\n            .fileupload('add', {files: [{\n                name: (addIndex += 1),\n                size: 999\n            }]})\n            .fileupload('add', {files: [{\n                name: 'test',\n                size: 1001\n            }]})\n            .fileupload({\n                send: function (e, data) {\n                    ok(\n                        !$.blueimp.fileupload.prototype.options\n                            .send.call(this, e, data)\n                    );\n                    return false;\n                }\n            });\n    });\n\n    test('minFileSize', function () {\n        expect(2);\n        var addIndex = 0,\n            sendIndex = 0;\n        $('#fileupload')\n            .fileupload({\n                autoUpload: true,\n                minFileSize: 1000,\n                send: function () {\n                    strictEqual(\n                        sendIndex += 1,\n                        addIndex\n                    );\n                    return false;\n                }\n            })\n            .fileupload('add', {files: [{\n                name: (addIndex += 1)\n            }]})\n            .fileupload('add', {files: [{\n                name: (addIndex += 1),\n                size: 1001\n            }]})\n            .fileupload('add', {files: [{\n                name: 'test',\n                size: 999\n            }]})\n            .fileupload({\n                send: function (e, data) {\n                    ok(\n                        !$.blueimp.fileupload.prototype.options\n                            .send.call(this, e, data)\n                    );\n                    return false;\n                }\n            });\n    });\n\n    test('acceptFileTypes', function () {\n        expect(2);\n        var addIndex = 0,\n            sendIndex = 0;\n        $('#fileupload')\n            .fileupload({\n                autoUpload: true,\n                acceptFileTypes: /(\\.|\\/)(gif|jpe?g|png)$/i,\n                disableImageMetaDataLoad: true,\n                send: function () {\n                    strictEqual(\n                        sendIndex += 1,\n                        addIndex\n                    );\n                    return false;\n                }\n            })\n            .fileupload('add', {files: [{\n                name: (addIndex += 1) + '.jpg'\n            }]})\n            .fileupload('add', {files: [{\n                name: (addIndex += 1),\n                type: 'image/jpeg'\n            }]})\n            .fileupload('add', {files: [{\n                name: 'test.txt',\n                type: 'text/plain'\n            }]})\n            .fileupload({\n                send: function (e, data) {\n                    ok(\n                        !$.blueimp.fileupload.prototype.options\n                            .send.call(this, e, data)\n                    );\n                    return false;\n                }\n            });\n    });\n\n    test('acceptFileTypes as HTML5 data attribute', function () {\n        expect(2);\n        var regExp = /(\\.|\\/)(gif|jpe?g|png)$/i;\n        $('#fileupload')\n            .attr('data-accept-file-types', regExp.toString())\n            .fileupload();\n        strictEqual(\n            $.type($('#fileupload').fileupload('option', 'acceptFileTypes')),\n            $.type(regExp)\n        );\n        strictEqual(\n            $('#fileupload').fileupload('option', 'acceptFileTypes').toString(),\n            regExp.toString()\n        );\n    });\n\n});\n"
  },
  {
    "path": "app_backend/static/plugin/metisMenu/metisMenu.css",
    "content": "/*\n * metismenu - v1.1.3\n * Easy menu jQuery plugin for Twitter Bootstrap 3\n * https://github.com/onokumus/metisMenu\n *\n * Made by Osman Nuri Okumus\n * Under MIT License\n */\n.arrow {\n    float: right;\n    line-height: 1.42857;\n}\n\n.glyphicon.arrow:before {\n    content: \"\\e079\";\n}\n\n.active > a > .glyphicon.arrow:before {\n    content: \"\\e114\";\n}\n\n\n/*\n * Require Font-Awesome\n * http://fortawesome.github.io/Font-Awesome/\n*/\n\n\n.fa.arrow:before {\n    content: \"\\f104\";\n}\n\n.active > a > .fa.arrow:before {\n    content: \"\\f107\";\n}\n\n.plus-times {\n    float: right;\n}\n\n.fa.plus-times:before {\n    content: \"\\f067\";\n}\n\n.active > a > .fa.plus-times {\n    filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=1);\n    -webkit-transform: rotate(45deg);\n    -moz-transform: rotate(45deg);\n    -ms-transform: rotate(45deg);\n    -o-transform: rotate(45deg);\n    transform: rotate(45deg);\n}\n\n.plus-minus {\n    float: right;\n}\n\n.fa.plus-minus:before {\n    content: \"\\f067\";\n}\n\n.active > a > .fa.plus-minus:before {\n    content: \"\\f068\";\n}"
  },
  {
    "path": "app_backend/static/plugin/metisMenu/metisMenu.js",
    "content": "/*\n * metismenu - v1.1.3\n * Easy menu jQuery plugin for Twitter Bootstrap 3\n * https://github.com/onokumus/metisMenu\n *\n * Made by Osman Nuri Okumus\n * Under MIT License\n */\n;(function($, window, document, undefined) {\n\n    var pluginName = \"metisMenu\",\n        defaults = {\n            toggle: true,\n            doubleTapToGo: false\n        };\n\n    function Plugin(element, options) {\n        this.element = $(element);\n        this.settings = $.extend({}, defaults, options);\n        this._defaults = defaults;\n        this._name = pluginName;\n        this.init();\n    }\n\n    Plugin.prototype = {\n        init: function() {\n\n            var $this = this.element,\n                $toggle = this.settings.toggle,\n                obj = this;\n\n            if (this.isIE() <= 9) {\n                $this.find(\"li.active\").has(\"ul\").children(\"ul\").collapse(\"show\");\n                $this.find(\"li\").not(\".active\").has(\"ul\").children(\"ul\").collapse(\"hide\");\n            } else {\n                $this.find(\"li.active\").has(\"ul\").children(\"ul\").addClass(\"collapse in\");\n                $this.find(\"li\").not(\".active\").has(\"ul\").children(\"ul\").addClass(\"collapse\");\n            }\n\n            //add the \"doubleTapToGo\" class to active items if needed\n            if (obj.settings.doubleTapToGo) {\n                $this.find(\"li.active\").has(\"ul\").children(\"a\").addClass(\"doubleTapToGo\");\n            }\n\n            $this.find(\"li\").has(\"ul\").children(\"a\").on(\"click\" + \".\" + pluginName, function(e) {\n                e.preventDefault();\n\n                //Do we need to enable the double tap\n                if (obj.settings.doubleTapToGo) {\n\n                    //if we hit a second time on the link and the href is valid, navigate to that url\n                    if (obj.doubleTapToGo($(this)) && $(this).attr(\"href\") !== \"#\" && $(this).attr(\"href\") !== \"\") {\n                        e.stopPropagation();\n                        document.location = $(this).attr(\"href\");\n                        return;\n                    }\n                }\n\n                $(this).parent(\"li\").toggleClass(\"active\").children(\"ul\").collapse(\"toggle\");\n\n                if ($toggle) {\n                    $(this).parent(\"li\").siblings().removeClass(\"active\").children(\"ul.in\").collapse(\"hide\");\n                }\n\n            });\n        },\n\n        isIE: function() { //https://gist.github.com/padolsey/527683\n            var undef,\n                v = 3,\n                div = document.createElement(\"div\"),\n                all = div.getElementsByTagName(\"i\");\n\n            while (\n                div.innerHTML = \"<!--[if gt IE \" + (++v) + \"]><i></i><![endif]-->\",\n                all[0]\n            ) {\n                return v > 4 ? v : undef;\n            }\n        },\n\n        //Enable the link on the second click.\n        doubleTapToGo: function(elem) {\n            var $this = this.element;\n\n            //if the class \"doubleTapToGo\" exists, remove it and return\n            if (elem.hasClass(\"doubleTapToGo\")) {\n                elem.removeClass(\"doubleTapToGo\");\n                return true;\n            }\n\n            //does not exists, add a new class and return false\n            if (elem.parent().children(\"ul\").length) {\n                 //first remove all other class\n                $this.find(\".doubleTapToGo\").removeClass(\"doubleTapToGo\");\n                //add the class on the current element\n                elem.addClass(\"doubleTapToGo\");\n                return false;\n            }\n        },\n\n        remove: function() {\n            this.element.off(\".\" + pluginName);\n            this.element.removeData(pluginName);\n        }\n\n    };\n\n    $.fn[pluginName] = function(options) {\n        this.each(function () {\n            var el = $(this);\n            if (el.data(pluginName)) {\n                el.data(pluginName).remove();\n            }\n            el.data(pluginName, new Plugin(this, options));\n        });\n        return this;\n    };\n\n})(jQuery, window, document);"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/.editorconfig",
    "content": "root = true\n\n[*]\ncharset = utf-8\nend_of_line = lf\ninsert_final_newline = true\ntrim_trailing_whitespace = true\nindent_style = space\n\n[*.{js,json}]\nindent_size = 4\n\n[*.{yml}]\nindent_size = 2\n\n[*.md]\ntrim_trailing_whitespace = false\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/.gitattributes",
    "content": "# we don't have non-text files, don't take chances with git's text=auto\n* text\n# this file is read by nuget (Windows) tooling, lets keep it happy\nMoment.js.nuspec eol=crlf\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/.gitignore",
    "content": "node_modules/\n.DS_Store\nmin/moment+customlangs.js\nmin/moment+customlangs.min.js\nsauce_connect.log\n.sauce-labs.creds\nnpm-debug.log\n.build*\nbuild\ncoverage\nnyc_output\n.nyc_output\n.coveralls.yml\n.vscode/\n.idea\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/.jscs.json",
    "content": "{\n    \"requireCurlyBraces\": [\n        \"if\",\n        \"else\",\n        \"for\",\n        \"while\",\n        \"do\",\n        \"try\",\n        \"catch\"\n    ],\n    \"requireSpaceAfterKeywords\": [\n        \"if\",\n        \"else\",\n        \"for\",\n        \"while\",\n        \"do\",\n        \"switch\",\n        \"return\",\n        \"try\",\n        \"catch\"\n    ],\n    \"requireSpaceBeforeBlockStatements\": true,\n    \"requireParenthesesAroundIIFE\": true,\n    \"requireSpacesInConditionalExpression\": true,\n    \"requireSpacesInAnonymousFunctionExpression\": {\n        \"beforeOpeningRoundBrace\": true,\n        \"beforeOpeningCurlyBrace\": true\n    },\n    \"requireSpacesInNamedFunctionExpression\": {\n        \"beforeOpeningCurlyBrace\": true\n    },\n    \"disallowSpacesInNamedFunctionExpression\": {\n        \"beforeOpeningRoundBrace\": true\n    },\n    \"requireBlocksOnNewline\": true,\n    \"disallowPaddingNewlinesInBlocks\": true,\n    \"disallowEmptyBlocks\": true,\n    \"disallowSpacesInsideObjectBrackets\": true,\n    \"disallowSpacesInsideArrayBrackets\": true,\n    \"disallowSpacesInsideParentheses\": true,\n    \"requireCommaBeforeLineBreak\": true,\n    \"disallowSpaceAfterPrefixUnaryOperators\": [\"++\", \"--\", \"+\", \"-\", \"~\", \"!\"],\n    \"disallowSpaceBeforePostfixUnaryOperators\": [\"++\", \"--\"],\n    \"requireSpaceBeforeBinaryOperators\": [\n        \"=\", \"+=\", \"-=\", \"*=\", \"/=\", \"%=\", \"<<=\", \">>=\", \">>>=\",\n        \"&=\", \"|=\", \"^=\",\n\n        \"+\", \"-\", \"*\", \"/\", \"%\", \"<<\", \">>\", \">>>\", \"&\",\n        \"|\", \"^\", \"&&\", \"||\", \"===\", \"==\", \">=\",\n        \"<=\", \"<\", \">\", \"!=\", \"!==\"\n    ],\n    \"requireSpaceAfterBinaryOperators\": true,\n    \"requireCamelCaseOrUpperCaseIdentifiers\": \"ignoreProperties\",\n    \"disallowKeywords\": [\"with\"],\n    \"disallowMultipleLineStrings\": true,\n    \"validateIndentation\": 4,\n    \"disallowTrailingWhitespace\": true,\n    \"disallowTrailingComma\": true,\n    \"requireLineFeedAtFileEnd\": true,\n    \"requireCapitalizedConstructors\": true,\n    \"validateQuoteMarks\": {\n        \"mark\": \"'\",\n        \"escape\": true\n    }\n}\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/.jshintrc",
    "content": "{\n    \"node\"     : true,\n    \"browser\"  : true,\n    \"boss\"     : false,\n    \"curly\"    : true,\n    \"debug\"    : false,\n    \"devel\"    : false,\n    \"eqeqeq\"   : true,\n    \"eqnull\"   : true,\n    \"esnext\"   : true,\n    \"evil\"     : false,\n    \"forin\"    : false,\n    \"immed\"    : false,\n    \"laxbreak\" : false,\n    \"newcap\"   : true,\n    \"noarg\"    : true,\n    \"noempty\"  : false,\n    \"nonew\"    : false,\n    \"onevar\"   : true,\n    \"plusplus\" : false,\n    \"regexp\"   : false,\n    \"undef\"    : true,\n    \"sub\"      : true,\n    \"strict\"   : false,\n    \"white\"    : true,\n    \"es3\"      : false,\n    \"camelcase\" : true,\n    \"globals\": {\n        \"define\": false\n    }\n}\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/.npmignore",
    "content": "test\nmin/tests.js\n.npmignore\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/.spmignore",
    "content": "benchmarks\nbower_components\nmeteor\nmin\nnode_modules\nscripts\ntasks\ntest\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/.travis.yml",
    "content": "language: node_js\nnode_js:\n  - \"node\"\n  - \"0.12\"\nsudo: false\n\nenv:\n  global:\n    - secure: \"M4STT2TOZxjzv3cZOgSVi0J4j6enrGjgE+p5YTNUw+S6Dg6FS5pTIPeafu1kGhfm7F0uk7xPVwGKYb+3uWNO9IhkKXz8jySMMQ2iKISHwECGNNuFNjSMD1vIjbIkLwV8TyPO/PurQg2s+WtYz+DoAZsDFKpdaRUtif64OjdQ3vQ=\"\n    - secure: \"V+i7kHoGe7VXWGplPNqJz+aDtgDF9Dh9/guoaf2BPyXLvkFW6VgMjJyoNUW7JVsakrWzAz2ubb734vAPDt7BCcFQ2BqfatOmabdFogviCaXC6IqVaEkYS2eSP7MIUPIeWJgnTrDGzkFMDk4K7y5SiVJ8UmYwZxe+tJV7kbb0Yig=\"\n\ninstall:\n  - npm install\n  - npm install -g grunt-cli\n\nscript: grunt build:travis\n\ngit:\n  depth: 10\n\n# TODO: Fix problem with coveralls.io not displaying autogenerated files\n# after_success: npm run coveralls\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/CHANGELOG.md",
    "content": "Changelog\n=========\n\n### 2.18.1\n\n* Release Mar 22, 2017\n\n* [#3853](https://github.com/moment/moment/pull/3853) [misc] Fix invalid whitespace character causing inability to parse\n  moment.js\n\n### 2.18.0 [See full changelog](https://gist.github.com/ichernev/78920c5a1e419fb28c6e4546d1b7235c)\n\n* Release Mar 18, 2017\n\n## Features\n\n* [#3708](https://github.com/moment/moment/pull/3708) [feature] RFC2822 parsing\n* [#3611](https://github.com/moment/moment/pull/3611) [feature] Durations gain validity\n* [#3738](https://github.com/moment/moment/pull/3738) [feature] Enable relative time for multiple seconds, request [#2558](https://github.com/moment/moment/issues/2558)\n* [#3766](https://github.com/moment/moment/pull/3766) [feature] Add support for k and kk format parsing\n\n## Bugfixes\n\n* [#3643](https://github.com/moment/moment/pull/3643) [bugfix] Fixes [#3520](https://github.com/moment/moment/issues/3520), parseZone incorrectly handled minutes under 16\n* [#3710](https://github.com/moment/moment/pull/3710) [bugfix] Fixes [#3632](https://github.com/moment/moment/issues/3632), toISOString returns null for invalid date\n* [#3787](https://github.com/moment/moment/pull/3787) [bugfix] Fixes [#3717](https://github.com/moment/moment/issues/3717), ensure day-of-year is non-zero\n* [#3780](https://github.com/moment/moment/pull/3780) [bugfix] Fixes [#3765](https://github.com/moment/moment/issues/3765): Ensure year 0 is formatted with YYYY\n* [#3806](https://github.com/moment/moment/pull/3806) [bugfix] Fixes [#3805](https://github.com/moment/moment/issues/3805), fix locale month getters for standalone/format cases\n\n7 new locales, many locale improvements and some misc changes\n\n### 2.17.1 [Also available here](https://gist.github.com/ichernev/f38280b2b29c4932914a6d3a4e50bfb2)\n* Release Dec 03, 2016\n\n* [#3638](https://github.com/moment/moment/pull/3638) [misc] TS: Make typescript definitions work with 1.x\n* [#3628](https://github.com/moment/moment/pull/3628) [misc] Adds \"sign CLA\" link to `CONTRIBUTING.md`\n* [#3640](https://github.com/moment/moment/pull/3640) [misc] Fix locale issues\n\n### 2.17.0 [Also available here](https://gist.github.com/ichernev/ed58f76fb95205eeac653d719972b90c)\n* Release Nov 22, 2016\n\n* [#3435](https://github.com/moment/moment/pull/3435) [new locale] yo: Yoruba (Nigeria) locale\n* [#3595](https://github.com/moment/moment/pull/3595) [bugfix] Fix accidental reference to global \"value\" variable\n* [#3506](https://github.com/moment/moment/pull/3506) [bugfix] Fix invalid moments returning valid dates to method calls\n* [#3563](https://github.com/moment/moment/pull/3563) [locale] ca: Change future relative time\n* [#3504](https://github.com/moment/moment/pull/3504) [tests] Fixes [#3463](https://github.com/moment/moment/issues/3463), parseZone not handling Z correctly (tests only)\n* [#3591](https://github.com/moment/moment/pull/3591) [misc] typescript: update typescript to 2.0.8, add strictNullChecks=true\n* [#3597](https://github.com/moment/moment/pull/3597) [misc] Fixed capitalization in nuget spec\n\n### 2.16.0 [See full changelog](https://gist.github.com/ichernev/17bffc1005a032cb1a8ac4c1558b4994)\n* Release Nov 9, 2016\n\n## Features\n* [#3530](https://github.com/moment/moment/pull/3530) [feature] Check whether input is date before checking if format is array\n* [#3515](https://github.com/moment/moment/pull/3515) [feature] Fix [#2300](https://github.com/moment/moment/issues/2300): Default to current week.\n\n## Bugfixes\n* [#3546](https://github.com/moment/moment/pull/3546) [bugfix] Implement lazy-loading of child locales with missing prents\n* [#3523](https://github.com/moment/moment/pull/3523) [bugfix] parseZone should handle UTC\n* [#3502](https://github.com/moment/moment/pull/3502) [bugfix] Fix [#3500](https://github.com/moment/moment/issues/3500): ISO 8601 parsing should match the full string, not the beginning of the string.\n* [#3581](https://github.com/moment/moment/pull/3581) [bugfix] Fix parseZone, redo [#3504](https://github.com/moment/moment/issues/3504), fix [#3463](https://github.com/moment/moment/issues/3463)\n\n## New Locales\n* [#3416](https://github.com/moment/moment/pull/3416) [new locale] nl-be: Dutch (Belgium) locale\n* [#3393](https://github.com/moment/moment/pull/3393) [new locale] ar-dz: Arabic (Algeria) locale\n* [#3342](https://github.com/moment/moment/pull/3342) [new locale] tet: Tetun Dili (East Timor) locale\n\nAnd more locale, build and typescript improvements\n\n### 2.15.2\n* Release Oct 23, 2016\n* [#3525](https://github.com/moment/moment/pull/3525) Speedup month standalone/format regexes **(IMPORTANT)**\n* [#3466](https://github.com/moment/moment/pull/3466) Fix typo of Javanese\n\n### 2.15.1\n* Release Sept 20, 2016\n* [#3438](https://github.com/moment/moment/pull/3438) Fix locale autoload, revert [#3344](https://github.com/moment/moment/pull/3344)\n\n### 2.15.0 [See full changelog](https://gist.github.com/ichernev/10e1c5bf647545c72ca30e9628a09ed3)\n- Release Sept 12, 2016\n\n## New Locales\n* [#3255](https://github.com/moment/moment/pull/3255) [new locale] mi: Maori language\n* [#3267](https://github.com/moment/moment/pull/3267) [new locale] ar-ly: Arabic (Libya) locale\n* [#3333](https://github.com/moment/moment/pull/3333) [new locale] zh-hk: Chinese (Hong Kong) locale\n\n## Bugfixes\n* [#3276](https://github.com/moment/moment/pull/3276) [bugfix] duration: parser: Support ms durations in .NET syntax\n* [#3312](https://github.com/moment/moment/pull/3312) [bugfix] locales: Enable locale-data getters without moment (fixes [#3284](https://github.com/moment/moment/issues/3284))\n* [#3381](https://github.com/moment/moment/pull/3381) [bugfix] parsing: Fix parseZone without timezone in string, fixes [#3083](https://github.com/moment/moment/issues/3083)\n* [#3383](https://github.com/moment/moment/pull/3383) [bugfix] toJSON: Fix isValid so that toJSON works after a moment is frozen\n* [#3427](https://github.com/moment/moment/pull/3427) [bugfix] ie8: Fix IE8 (regression in 2.14.x)\n\n## Packaging\n* [#3299](https://github.com/moment/moment/pull/3299) [pkg] npm: Do not include .npmignore in npm package\n* [#3273](https://github.com/moment/moment/pull/3273) [pkg] jspm: Include moment.d.ts file in package\n* [#3344](https://github.com/moment/moment/pull/3344) [pkg] exports: use module.require for nodejs\n\nAlso some locale and typescript improvements\n\n### 2.14.1\n- Release July 20, 2016\n* [#3280](https://github.com/moment/moment/pull/3280) Fix typescript definitions\n\n\n### 2.14.0 [See full changelog](https://gist.github.com/ichernev/812e79ac36a7829a22598fe964bfc18a)\n\n- Release July 20, 2016\n\n## New Features\n* [#3233](https://github.com/moment/moment/pull/3233) Introduce month.isFormat for format/standalone discovery\n* [#2848](https://github.com/moment/moment/pull/2848) Allow user to get/set the rounding method used when calculating relative time\n* [#3112](https://github.com/moment/moment/pull/3112) optimize configFromStringAndFormat\n* [#3147](https://github.com/moment/moment/pull/3147) Call calendar format function with moment context\n* [#3160](https://github.com/moment/moment/pull/3160) deprecate isDSTShifted\n* [#3175](https://github.com/moment/moment/pull/3175) make moment calendar extensible with ad-hoc options\n* [#3191](https://github.com/moment/moment/pull/3191) toDate returns a copy of the internal date object\n* [#3192](https://github.com/moment/moment/pull/3192) Adding support for rollup import.\n* [#3238](https://github.com/moment/moment/pull/3238) Handle empty object and empty array for creation as now\n* [#3082](https://github.com/moment/moment/pull/3082) Use relative AMD moment dependency\n\n## Bugfixes\n* [#3241](https://github.com/moment/moment/pull/3241) Escape all 24 mixed pieces, not only first 12 in computeMonthsParse\n* [#3008](https://github.com/moment/moment/pull/3008) Object setter orders sets based on size of unit\n* [#3177](https://github.com/moment/moment/pull/3177) Bug Fix [#2704](https://github.com/moment/moment/pull/2704) - isoWeekday(String) inconsistent with isoWeekday(Number)\n* [#3230](https://github.com/moment/moment/pull/3230) fix passing date with format string to ignore format string\n* [#3232](https://github.com/moment/moment/pull/3232) Fix negative 0 in certain diff cases\n* [#3235](https://github.com/moment/moment/pull/3235) Use proper locale inheritance for the base locale, fixes [#3137](https://github.com/moment/moment/pull/3137)\n\nPlus es-do locale and locale bugfixes\n\n### 2.13.0 [See full changelog](https://gist.github.com/ichernev/0132fcf5b61f7fc140b0bb0090480d49)\n- Release April 18, 2016\n\n## Enhancements:\n* [#2982](https://github.com/moment/moment/pull/2982) Add 'date' as alias to 'day' for startOf() and endOf().\n* [#2955](https://github.com/moment/moment/pull/2955) Add parsing negative components in durations when ISO 8601\n* [#2991](https://github.com/moment/moment/pull/2991) isBetween support for both open and closed intervals\n* [#3105](https://github.com/moment/moment/pull/3105) Add localeSorted argument to weekday listers\n* [#3102](https://github.com/moment/moment/pull/3102) Add k and kk formatting tokens\n\n## Bugfixes\n* [#3109](https://github.com/moment/moment/pull/3109) Fix [#1756](https://github.com/moment/moment/issues/1756) Resolved thread-safe issue on server side.\n* [#3078](https://github.com/moment/moment/pull/3078) Fix parsing for months/weekdays with weird characters\n* [#3098](https://github.com/moment/moment/pull/3098) Use Z suffix when in UTC mode ([#3020](https://github.com/moment/moment/issues/3020))\n* [#2995](https://github.com/moment/moment/pull/2995) Fix floating point rounding errors in durations\n* [#3059](https://github.com/moment/moment/pull/3059) fix bug where diff returns -0 in month-related diffs\n* [#3045](https://github.com/moment/moment/pull/3045) Fix mistaking any input for 'a' token\n* [#2877](https://github.com/moment/moment/pull/2877) Use explicit .valueOf() calls instead of coercion\n* [#3036](https://github.com/moment/moment/pull/3036) Year setter should keep time when DST changes\n\nPlus 3 new locales and locale fixes.\n\n### 2.12.0 [See full changelog](https://gist.github.com/ichernev/6e5bfdf8d6522fc4ac73)\n\n- Release March 7, 2016\n\n## Enhancements:\n* [#2932](https://github.com/moment/moment/pull/2932) List loaded locales\n* [#2818](https://github.com/moment/moment/pull/2818) Parse ISO-8061 duration containing both day and week values\n* [#2774](https://github.com/moment/moment/pull/2774) Implement locale inheritance and locale updating\n\n## Bugfixes:\n* [#2970](https://github.com/moment/moment/pull/2970) change add subtract to handle decimal values by rounding\n* [#2887](https://github.com/moment/moment/pull/2887) Fix toJSON casting of invalid moment\n* [#2897](https://github.com/moment/moment/pull/2897) parse string arguments for month() correctly, closes #2884\n* [#2946](https://github.com/moment/moment/pull/2946) Fix usage suggestions for min and max\n\n## New locales:\n* [#2917](https://github.com/moment/moment/pull/2917) Locale Punjabi(Gurmukhi) India format conversion\n\nAnd more\n\n### 2.11.2 (Fix ReDoS attack vector)\n\n- Release February 7, 2016\n\n* [#2939](https://github.com/moment/moment/pull/2939) use full-string match to speed up aspnet regex match\n\n### 2.11.1 [See full changelog](https://gist.github.com/ichernev/8ec3ee25b749b4cff3c2)\n\n- Release January 9, 2016\n\n## Bugfixes:\n* [#2881](https://github.com/moment/moment/pull/2881) Revert \"Merge pull request #2746 from mbad0la:develop\" Sep->Sept\n* [#2868](https://github.com/moment/moment/pull/2868) Add format and parse token Y, so it actually works\n* [#2865](https://github.com/moment/moment/pull/2865) Use typeof checks for undefined for global variables\n* [#2858](https://github.com/moment/moment/pull/2858) Fix Date mocking regression introduced in 2.11.0\n* [#2864](https://github.com/moment/moment/pull/2864) Include changelog in npm release\n* [#2830](https://github.com/moment/moment/pull/2830) dep: add grunt-cli\n* [#2869](https://github.com/moment/moment/pull/2869) Fix months parsing for some locales\n\n### 2.11.0 [See full changelog](https://gist.github.com/ichernev/6594bc29719dde6b2f66)\n\n- Release January 4, 2016\n\n* [#2624](https://github.com/moment/moment/pull/2624) Proper handling of invalid moments\n* [#2634](https://github.com/moment/moment/pull/2634) Fix strict month parsing issue in cs,ru,sk\n* [#2735](https://github.com/moment/moment/pull/2735) Reset the locale back to 'en' after defining all locales in min/locales.js\n* [#2702](https://github.com/moment/moment/pull/2702) Week rework\n* [#2746](https://github.com/moment/moment/pull/2746) Changed September Abbreviation to \"Sept\" in locale-specific english\n  files and default locale file\n* [#2646](https://github.com/moment/moment/pull/2646) Fix [#2645](https://github.com/moment/moment/pull/2645) - invalid dates pre-1970\n\n* [#2641](https://github.com/moment/moment/pull/2641) Implement basic format and comma as ms separator in ISO 8601\n* [#2665](https://github.com/moment/moment/pull/2665) Implement stricter weekday parsing\n* [#2700](https://github.com/moment/moment/pull/2700) Add [Hh]mm and [Hh]mmss formatting tokens, so you can parse 123 with\n  hmm for example\n* [#2565](https://github.com/moment/moment/pull/2565) [#2835](https://github.com/moment/moment/pull/2835) Expose arguments used for moment creation with creationData\n  (fix [#2443](https://github.com/moment/moment/pull/2443))\n* [#2648](https://github.com/moment/moment/pull/2648) fix issue [#2640](https://github.com/moment/moment/pull/2640): support instanceof operator\n* [#2709](https://github.com/moment/moment/pull/2709) Add isSameOrAfter and isSameOrBefore comparison methods\n* [#2721](https://github.com/moment/moment/pull/2721) Fix moment creation from object with strings values\n* [#2740](https://github.com/moment/moment/pull/2740) Enable 'd hh:mm:ss.sss' format for durations\n* [#2766](https://github.com/moment/moment/pull/2766) [#2833](https://github.com/moment/moment/pull/2833) Alternate Clock Source Support\n\n### 2.10.6\n\n- Release July 28, 2015\n\n[#2515](https://github.com/moment/moment/pull/2515) Fix regression introduced\nin `2.10.5` related to `moment.ISO_8601` parsing.\n\n### 2.10.5 [See full changelog](https://gist.github.com/ichernev/6ec13ac7efc396da44b2)\n\n- Release July 26, 2015\n\nImportant changes:\n* [#2357](https://github.com/moment/moment/pull/2357) Improve unit bubbling for ISO dates\n  this fixes day to year conversions to work around end-of-year (~365 days). As\n  a side effect 365 days is 11 months and 30 days, and 366 days is one year.\n* [#2438](https://github.com/moment/moment/pull/2438) Fix inconsistent moment.min and moment.max results\n  Return invalid result if any of the inputs is invalid\n* [#2494](https://github.com/moment/moment/pull/2494) Fix two digit year parsing with YYYY format\n  This brings the benefits of YY to YYYY\n* [#2368](https://github.com/moment/moment/pull/2368) perf: use faster form of copying dates, across the board improvement\n\n\n### 2.10.3 [See full changelog](https://gist.github.com/ichernev/f264b9bed5b00f8b1b7f)\n\n- Release May 13, 2015\n\n* add `moment.fn.to` and `moment.fn.toNow` (similar to `from` and `fromNow`)\n* new locales (Sinhalese (si), Montenegrin (me), Javanese (ja))\n* performance improvements\n\n### 2.10.2\n\n- Release April 9, 2015\n\n* fixed moment-with-locales in browser env caused by esperanto change\n\n### 2.10.1\n\n* regression: Add moment.duration.fn back\n\n### 2.10.0\n\nPorted code to es6 modules.\n\n### 2.9.0 [See full changelog](https://gist.github.com/ichernev/0c9a9b49951111a27ce7)\n\n- Release January 8, 2015\n\nlanguages:\n* [2104](https://github.com/moment/moment/issues/2104) Frisian (fy) language file with unit test\n* [2097](https://github.com/moment/moment/issues/2097) add ar-tn locale\n\ndeprecations:\n* [2074](https://github.com/moment/moment/issues/2074) Implement `moment.fn.utcOffset`, deprecate `moment.fn.zone`\n\nfeatures:\n* [2088](https://github.com/moment/moment/issues/2088) add moment.fn.isBetween\n* [2054](https://github.com/moment/moment/issues/2054) Call updateOffset when creating moment (needed for default timezone in\n  moment-timezone)\n* [1893](https://github.com/moment/moment/issues/1893) Add moment.isDate method\n* [1825](https://github.com/moment/moment/issues/1825) Implement toJSON function on Duration\n* [1809](https://github.com/moment/moment/issues/1809) Allowing moment.set() to accept a hash of units\n* [2128](https://github.com/moment/moment/issues/2128) Add firstDayOfWeek, firstDayOfYear locale getters\n* [2131](https://github.com/moment/moment/issues/2131) Add quarter diff support\n\nSome bugfixes and language improvements -- [full changelog](https://gist.github.com/ichernev/0c9a9b49951111a27ce7)\n\n### 2.8.4 [See full changelog](https://gist.github.com/ichernev/a4fcb0a46d74e4b9b996)\n\n- Release November 19, 2014\n\nFeatures:\n\n* [#2000](https://github.com/moment/moment/issues/2000) Add LTS localised format that includes seconds\n* [#1960](https://github.com/moment/moment/issues/1960) added formatToken 'x' for unix offset in milliseconds #1938\n* [#1965](https://github.com/moment/moment/issues/1965) Support 24:00:00.000 to mean next day, at midnight.\n* [#2002](https://github.com/moment/moment/issues/2002) Accept 'date' key when creating moment with object\n* [#2009](https://github.com/moment/moment/issues/2009) Use native toISOString when we can\n\nSome bugfixes and language improvements -- [full changelog](https://gist.github.com/ichernev/a4fcb0a46d74e4b9b996)\n\n### 2.8.3\n\n- Release September 5, 2014\n\nBugfixes:\n\n* [#1801](https://github.com/moment/moment/issues/1801) proper pluralization for Arabic\n* [#1833](https://github.com/moment/moment/issues/1833) improve spm integration\n* [#1871](https://github.com/moment/moment/issues/1871) fix zone bug caused by Firefox 24\n* [#1882](https://github.com/moment/moment/issues/1882) Use hh:mm in Czech\n* [#1883](https://github.com/moment/moment/issues/1883) Fix 2.8.0 regression in duration as conversions\n* [#1890](https://github.com/moment/moment/issues/1890) Faster travis builds\n* [#1892](https://github.com/moment/moment/issues/1892) Faster isBefore/After/Same\n* [#1848](https://github.com/moment/moment/issues/1848) Fix flaky month diffs\n* [#1895](https://github.com/moment/moment/issues/1895) Fix 2.8.0 regression in moment.utc with format array\n* [#1896](https://github.com/moment/moment/issues/1896) Support setting invalid instance locale (noop)\n* [#1897](https://github.com/moment/moment/issues/1897) Support moment([str]) in addition to moment([int])\n\n### 2.8.2\n\n- Release August 22, 2014\n\nMinor bugfixes:\n\n* [#1874](https://github.com/moment/moment/issues/1874) use `Object.prototype.hasOwnProperty`\n  instead of `obj.hasOwnProperty` (ie8 bug)\n* [#1873](https://github.com/moment/moment/issues/1873) add `duration#toString()`\n* [#1859](https://github.com/moment/moment/issues/1859) better month/weekday names in norwegian\n* [#1812](https://github.com/moment/moment/issues/1812) meridiem parsing for greek\n* [#1804](https://github.com/moment/moment/issues/1804) spanish del -> de\n* [#1800](https://github.com/moment/moment/issues/1800) korean LT improvement\n\n### 2.8.1\n\n- Release August 1, 2014\n\n* bugfix [#1813](https://github.com/moment/moment/issues/1813): fix moment().lang([key]) incompatibility\n\n### 2.8.0 [See changelog](https://gist.github.com/ichernev/ac3899324a5fa6c8c9b4)\n\n- Release July 31, 2014\n\n* incompatible changes\n    * [#1761](https://github.com/moment/moment/issues/1761): moments created without a language are no longer following the global language, in case it changes. Only newly created moments take the global language by default. In case you're affected by this, wait, comment on [#1797](https://github.com/moment/moment/issues/1797) and wait for a proper reimplementation\n    * [#1642](https://github.com/moment/moment/issues/1642): 45 days is no longer \"a month\" according to humanize, cutoffs for month, and year have changed. Hopefully your code does not depend on a particular answer from humanize (which it shouldn't anyway)\n    * [#1784](https://github.com/moment/moment/issues/1784): if you use the human readable English datetime format in a weird way (like storing them in a database) that would break when the format changes you're at risk.\n\n* deprecations (old behavior will be dropped in 3.0)\n    * [#1761](https://github.com/moment/moment/issues/1761) `lang` is renamed to `locale`, `langData` -> `localeData`. Also there is now `defineLocale` that should be used when creating new locales\n    * [#1763](https://github.com/moment/moment/issues/1763) `add(unit, value)` and `subtract(unit, value)` are now deprecated. Use `add(value, unit)` and `subtract(value, unit)` instead.\n    * [#1759](https://github.com/moment/moment/issues/1759) rename `duration.toIsoString` to `duration.toISOString`. The js standard library and moment's `toISOString` follow that convention.\n\n* new locales\n    * [#1789](https://github.com/moment/moment/issues/1789) Tibetan (bo)\n    * [#1786](https://github.com/moment/moment/issues/1786) Africaans (af)\n    * [#1778](https://github.com/moment/moment/issues/1778) Burmese (my)\n    * [#1727](https://github.com/moment/moment/issues/1727) Belarusian (be)\n\n* bugfixes, locale bugfixes, performance improvements, features\n\n### 2.7.0 [See changelog](https://gist.github.com/ichernev/b0a3d456d5a84c9901d7)\n\n- Release June 12, 2014\n\n* new languages\n\n  * [#1678](https://github.com/moment/moment/issues/1678) Bengali (bn)\n  * [#1628](https://github.com/moment/moment/issues/1628) Azerbaijani (az)\n  * [#1633](https://github.com/moment/moment/issues/1633) Arabic, Saudi Arabia (ar-sa)\n  * [#1648](https://github.com/moment/moment/issues/1648) Austrian German (de-at)\n\n* features\n\n  * [#1663](https://github.com/moment/moment/issues/1663) configurable relative time thresholds\n  * [#1554](https://github.com/moment/moment/issues/1554) support anchor time in moment.calendar\n  * [#1693](https://github.com/moment/moment/issues/1693) support moment.ISO_8601 as parsing format\n  * [#1637](https://github.com/moment/moment/issues/1637) add moment.min and moment.max and deprecate min/max instance methods\n  * [#1704](https://github.com/moment/moment/issues/1704) support string value in add/subtract\n  * [#1647](https://github.com/moment/moment/issues/1647) add spm support (package manager)\n\n* bugfixes\n\n### 2.6.0 [See changelog](https://gist.github.com/ichernev/10544682)\n\n- Release April 12 , 2014\n\n* languages\n  * [#1529](https://github.com/moment/moment/issues/1529) Serbian-Cyrillic (sr-cyr)\n  * [#1544](https://github.com/moment/moment/issues/1544), [#1546](https://github.com/moment/moment/issues/1546) Khmer Cambodia (km)\n\n* features\n    * [#1419](https://github.com/moment/moment/issues/1419), [#1468](https://github.com/moment/moment/issues/1468), [#1467](https://github.com/moment/moment/issues/1467), [#1546](https://github.com/moment/moment/issues/1546) better handling of timezone-d moments around DST\n    * [#1462](https://github.com/moment/moment/issues/1462) add weeksInYear and isoWeeksInYear\n    * [#1475](https://github.com/moment/moment/issues/1475) support ordinal parsing\n    * [#1499](https://github.com/moment/moment/issues/1499) composer support\n    * [#1577](https://github.com/moment/moment/issues/1577), [#1604](https://github.com/moment/moment/issues/1604) put Date parsing in moment.createFromInputFallback so it can be properly deprecated and controlled in the future\n    * [#1545](https://github.com/moment/moment/issues/1545) extract two-digit year parsing in moment.parseTwoDigitYear, so it can be overwritten\n    * [#1590](https://github.com/moment/moment/issues/1590) (see [#1574](https://github.com/moment/moment/issues/1574)) set AMD global before module definition to better support non AMD module dependencies used in AMD environment\n    * [#1589](https://github.com/moment/moment/issues/1589) remove global in Node.JS environment (was not working before, nobody complained, was scheduled for removal anyway)\n    * [#1586](https://github.com/moment/moment/issues/1586) support quarter setting and parsing\n\n* 18 bugs fixed\n\n### 2.5.1\n\n- Release January 22, 2014\n\n* languages\n  * [#1392](https://github.com/moment/moment/issues/1392) Armenian (hy-am)\n\n* bugfixes\n  * [#1429](https://github.com/moment/moment/issues/1429) fixes [#1423](https://github.com/moment/moment/issues/1423) weird chrome-32 bug with js object creation\n  * [#1421](https://github.com/moment/moment/issues/1421) remove html entities from Welsh\n  * [#1418](https://github.com/moment/moment/issues/1418) fixes [#1401](https://github.com/moment/moment/issues/1401) improved non-padded tokens in strict matching\n  * [#1417](https://github.com/moment/moment/issues/1417) fixes [#1404](https://github.com/moment/moment/issues/1404) handle buggy moment object created by property cloning\n  * [#1398](https://github.com/moment/moment/issues/1398) fixes [#1397](https://github.com/moment/moment/issues/1397) fix Arabic-like week number parsing\n  * [#1396](https://github.com/moment/moment/issues/1396) add leftZeroFill(4) to GGGG and gggg formats\n  * [#1373](https://github.com/moment/moment/issues/1373) use lowercase for months and days in Catalan\n\n* testing\n  * [#1374](https://github.com/moment/moment/issues/1374) run tests on multiple browser/os combos via SauceLabs and Travis\n\n### 2.5.0 [See changelog](https://gist.github.com/ichernev/8104451)\n\n- Release Dec 24, 2013\n\n* New languages\n  * Luxemburish (lb) [1247](https://github.com/moment/moment/issues/1247)\n  * Serbian (rs) [1319](https://github.com/moment/moment/issues/1319)\n  * Tamil (ta) [1324](https://github.com/moment/moment/issues/1324)\n  * Macedonian (mk) [1337](https://github.com/moment/moment/issues/1337)\n\n* Features\n  * [1311](https://github.com/moment/moment/issues/1311) Add quarter getter and format token `Q`\n  * [1303](https://github.com/moment/moment/issues/1303) strict parsing now respects number of digits per token (fix [1196](https://github.com/moment/moment/issues/1196))\n  * 0d30bb7 add jspm support\n  * [1347](https://github.com/moment/moment/issues/1347) improve zone parsing\n  * [1362](https://github.com/moment/moment/issues/1362) support merideam parsing in Korean\n\n* 22 bugfixes\n\n### 2.4.0\n\n- Release Oct 27, 2013\n\n* **Deprecate** globally exported moment, will be removed in next major\n* New languages\n  * Farose (fo) [#1206](https://github.com/moment/moment/issues/1206)\n  * Tagalog/Filipino (tl-ph) [#1197](https://github.com/moment/moment/issues/1197)\n  * Welsh (cy) [#1215](https://github.com/moment/moment/issues/1215)\n* Bugfixes\n  * properly handle Z at the end of iso RegExp [#1187](https://github.com/moment/moment/issues/1187)\n  * chinese meridian time improvements [#1076](https://github.com/moment/moment/issues/1076)\n  * fix language tests [#1177](https://github.com/moment/moment/issues/1177)\n  * remove some failing tests (that should have never existed :))\n    [#1185](https://github.com/moment/moment/issues/1185)\n    [#1183](https://github.com/moment/moment/issues/1183)\n  * handle russian noun cases in weird cases [#1195](https://github.com/moment/moment/issues/1195)\n\n### 2.3.1\n\n- Release Oct 9, 2013\n\nRemoved a trailing comma [1169] and fixed a bug with `months`, `weekdays` getters [#1171](https://github.com/moment/moment/issues/1171).\n\n### 2.3.0 [See changelog](https://gist.github.com/ichernev/6864354)\n\n- Release Oct 7, 2013\n\nChanged isValid, added strict parsing.\nWeek tokens parsing.\n\n### 2.2.1\n\n- Release Sep 12, 2013\n\nFixed bug in string prototype test.\nUpdated authors and contributors.\n\n### 2.2.0 [See changelog](https://gist.github.com/ichernev/00f837a9baf46a3565e4)\n\n- Release  Sep 11, 2013\n\nAdded bower support.\n\nLanguage files now use UMD.\n\nCreating moment defaults to current date/month/year.\n\nAdded a bundle of moment and all language files.\n\n### 2.1.0 [See changelog](https://gist.github.com/timrwood/b8c2d90d528eddb53ab5)\n\n- Release Jul 8, 2013\n\nAdded better week support.\n\nAdded ability to set offset with `moment#zone`.\n\nAdded ability to set month or weekday from a string.\n\nAdded `moment#min` and `moment#max`\n\n### 2.0.0 [See changelog](https://gist.github.com/timrwood/e72f2eef320ed9e37c51)\n\n- Release Feb 9, 2013\n\nAdded short form localized tokens.\n\nAdded ability to define language a string should be parsed in.\n\nAdded support for reversed add/subtract arguments.\n\nAdded support for `endOf('week')` and `startOf('week')`.\n\nFixed the logic for `moment#diff(Moment, 'months')` and `moment#diff(Moment, 'years')`\n\n`moment#diff` now floors instead of rounds.\n\nNormalized `moment#toString`.\n\nAdded `isSame`, `isAfter`, and `isBefore` methods.\n\nAdded better week support.\n\nAdded `moment#toJSON`\n\nBugfix: Fixed parsing of first century dates\n\nBugfix: Parsing 10Sep2001 should work as expected\n\nBugfix: Fixed weirdness with `moment.utc()` parsing.\n\nChanged language ordinal method to return the number + ordinal instead of just the ordinal.\n\nChanged two digit year parsing cutoff to match strptime.\n\nRemoved `moment#sod` and `moment#eod` in favor of `moment#startOf` and `moment#endOf`.\n\nRemoved `moment.humanizeDuration()` in favor of `moment.duration().humanize()`.\n\nRemoved the lang data objects from the top level namespace.\n\nDuplicate `Date` passed to `moment()` instead of referencing it.\n\n### 1.7.2 [See discussion](https://github.com/timrwood/moment/issues/456)\n\n- Release Oct 2, 2012\n\nBugfixes\n\n### 1.7.1 [See discussion](https://github.com/timrwood/moment/issues/384)\n\n- Release Oct 1, 2012\n\nBugfixes\n\n### 1.7.0 [See discussion](https://github.com/timrwood/moment/issues/288)\n\n- Release Jul 26, 2012\n\nAdded `moment.fn.endOf()` and `moment.fn.startOf()`.\n\nAdded validation via `moment.fn.isValid()`.\n\nMade formatting method 3x faster. http://jsperf.com/momentjs-cached-format-functions\n\nAdd support for month/weekday callbacks in `moment.fn.format()`\n\nAdded instance specific languages.\n\nAdded two letter weekday abbreviations with the formatting token `dd`.\n\nVarious language updates.\n\nVarious bugfixes.\n\n### 1.6.0 [See discussion](https://github.com/timrwood/moment/pull/268)\n\n- Release Apr 26, 2012\n\nAdded Durations.\n\nRevamped parser to support parsing non-separated strings (YYYYMMDD vs YYYY-MM-DD).\n\nAdded support for millisecond parsing and formatting tokens (S SS SSS)\n\nAdded a getter for `moment.lang()`\n\nVarious bugfixes.\n\nThere are a few things deprecated in the 1.6.0 release.\n\n1. The format tokens `z` and `zz` (timezone abbreviations like EST CST MST etc) will no longer be supported. Due to inconsistent browser support, we are unable to consistently produce this value. See [this issue](https://github.com/timrwood/moment/issues/162) for more background.\n\n2. The method `moment.fn.native` is deprecated in favor of `moment.fn.toDate`. There continue to be issues with Google Closure Compiler throwing errors when using `native`, even in valid instances.\n\n3. The way to customize am/pm strings is being changed. This would only affect you if you created a custom language file. For more information, see [this issue](https://github.com/timrwood/moment/pull/222).\n\n### 1.5.0 [See milestone](https://github.com/timrwood/moment/issues?milestone=10&page=1&state=closed)\n\n- Release Mar 20, 2012\n\nAdded UTC mode.\n\nAdded automatic ISO8601 parsing.\n\nVarious bugfixes.\n\n### 1.4.0 [See milestone](https://github.com/timrwood/moment/issues?milestone=8&state=closed)\n\n- Release Feb 4, 2012\n\nAdded `moment.fn.toDate` as a replacement for `moment.fn.native`.\n\nAdded `moment.fn.sod` and `moment.fn.eod` to get the start and end of day.\n\nVarious bugfixes.\n\n### 1.3.0 [See milestone](https://github.com/timrwood/moment/issues?milestone=7&state=closed)\n\n- Release Jan 5, 2012\n\nAdded support for parsing month names in the current language.\n\nAdded escape blocks for parsing tokens.\n\nAdded `moment.fn.calendar` to format strings like 'Today 2:30 PM', 'Tomorrow 1:25 AM', and 'Last Sunday 4:30 AM'.\n\nAdded `moment.fn.day` as a setter.\n\nVarious bugfixes\n\n### 1.2.0 [See milestone](https://github.com/timrwood/moment/issues?milestone=4&state=closed)\n\n- Release Dec 7, 2011\n\nAdded timezones to parser and formatter.\n\nAdded `moment.fn.isDST`.\n\nAdded `moment.fn.zone` to get the timezone offset in minutes.\n\n### 1.1.2 [See milestone](https://github.com/timrwood/moment/issues?milestone=6&state=closed)\n\n- Release Nov 18, 2011\n\nVarious bugfixes\n\n### 1.1.1 [See milestone](https://github.com/timrwood/moment/issues?milestone=5&state=closed)\n\n- Release Nov 12, 2011\n\nAdded time specific diffs (months, days, hours, etc)\n\n### 1.1.0\n\n- Release Oct 28, 2011\n\nAdded `moment.fn.format` localized masks. 'L LL LLL LLLL' [issue 29](https://github.com/timrwood/moment/pull/29)\n\nFixed [issue 31](https://github.com/timrwood/moment/pull/31).\n\n### 1.0.1\n\n- Release Oct 18, 2011\n\nAdded `moment.version` to get the current version.\n\nRemoved `window !== undefined` when checking if module exists to support browserify. [issue 25](https://github.com/timrwood/moment/pull/25)\n\n### 1.0.0\n\n- Release\n\nAdded convenience methods for getting and setting date parts.\n\nAdded better support for `moment.add()`.\n\nAdded better lang support in NodeJS.\n\nRenamed library from underscore.date to Moment.js\n\n### 0.6.1\n\n- Release Oct 12, 2011\n\nAdded Portuguese, Italian, and French language support\n\n### 0.6.0\n\n- Release Sep 21, 2011\n\nAdded _date.lang() support.\nAdded support for passing multiple formats to try to parse a date. _date(\"07-10-1986\", [\"MM-DD-YYYY\", \"YYYY-MM-DD\"]);\nMade parse from string and single format 25% faster.\n\n### 0.5.2\n\n- Release Jul 11, 2011\n\nBugfix for [issue 8](https://github.com/timrwood/underscore.date/pull/8) and [issue 9](https://github.com/timrwood/underscore.date/pull/9).\n\n### 0.5.1\n\n- Release Jun 17, 2011\n\nBugfix for [issue 5](https://github.com/timrwood/underscore.date/pull/5).\n\n### 0.5.0\n\n- Release Jun 13, 2011\n\nDropped the redundant `_date.date()` in favor of `_date()`.\nRemoved `_date.now()`, as it is a duplicate of `_date()` with no parameters.\nRemoved `_date.isLeapYear(yearNumber)`. Use `_date([yearNumber]).isLeapYear()` instead.\nExposed customization options through the `_date.relativeTime`, `_date.weekdays`, `_date.weekdaysShort`, `_date.months`, `_date.monthsShort`, and `_date.ordinal` variables instead of the `_date.customize()` function.\n\n### 0.4.1\n\n- Release May 9, 2011\n\nAdded date input formats for input strings.\n\n### 0.4.0\n\n- Release May 9, 2011\n\nAdded underscore.date to npm. Removed dependencies on underscore.\n\n### 0.3.2\n\n- Release Apr 9, 2011\n\nAdded `'z'` and `'zz'` to `_.date().format()`. Cleaned up some redundant code to trim off some bytes.\n\n### 0.3.1\n\n- Release Mar 25, 2011\n\nCleaned up the namespace. Moved all date manipulation and display functions to the _.date() object.\n\n### 0.3.0\n\n- Release Mar 25, 2011\n\nSwitched to the Underscore methodology of not mucking with the native objects' prototypes.\nMade chaining possible.\n\n### 0.2.1\n\n- Release\n\nChanged date names to be a more pseudo standardized 'dddd, MMMM Do YYYY, h:mm:ss a'.\nAdded `Date.prototype` functions `add`, `subtract`, `isdst`, and `isleapyear`.\n\n### 0.2.0\n\n- Release\n\nChanged function names to be more concise.\nChanged date format from php date format to custom format.\n\n### 0.1.0\n\n- Release\n\nInitial release\n\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/CONTRIBUTING.md",
    "content": "Submitting Issues\n=================\n\nIf you are submitting a bug, please create a [jsfiddle](http://jsfiddle.net/) demonstrating the issue.\n\nRead before submitting Pull Requests\n====================================\n\n * **Pull requests to the `master` branch will be closed.** Please submit all pull requests to the `develop` branch.\n * **You will be required to sign a JS Foundation CLA before your pull request can be merged.** [Sign it right now](https://cla.js.foundation/moment/moment).\n * **Locale translations will not be merged without unit tests.** See [the British English unit tests](https://github.com/moment/moment/blob/develop/src/test/locale/en-gb.js) for an example.\n * **Do not include the minified files in your pull request.** These are\n   `moment.js`, `locale/*.js`, `min/*.js`. Don't worry, we'll build them when\n   we cut a release.\n\nCode organization\n=================\n\nStarting from version 2.10.0 the code is placed under `src/`.\n`moment.js`, `locale/*.js`, `min/*.js` are generated only on release.\n\n**DO NOT** submit changes to the generated files. Instead only change\n`src/**/*.js` and run the tests.\n\n* `src/lib/**/*.js` moment core files\n* `src/locale/*.js` locale files\n* `src/test/moment/*.js` moment core tests\n* `src/test/locale/*.js` locale tests\n\nWe're using ES6 module system, but nothing else ES6, because of performance\nconsiderations (added code by the transpiler, less than optimal translation to\nES5). So please do not use that fancy new ES6 feature in your patch, it won't\nbe accepted.\n\nSetting up development environment\n==================================\n\nTo contribute, fork the library and install grunt and dependencies. You need\n[git](http://git-scm.com/) and\n[node](http://nodejs.org/); you might use\n[nvm](https://github.com/creationix/nvm) or\n[nenv](https://github.com/ryuone/nenv) to install node.\n\n```bash\ngit clone https://github.com/moment/moment.git\ncd moment\nnpm install -g grunt-cli\nnpm install\ngit checkout develop  # all patches against develop branch, please!\ngrunt                 # this runs tests and jshint\n```\n\nChanging locale files\n=====================\n\nIf you have any changes to existing locale files, `@mention` the original\nauthor in the pull request (check the top of the language file), and ask if\nhe/she approves of your changes. Because I don't know any languages I can't\njudge your locale changes, only the original author can :)\n\nIn order for your pull request to get merged it must have approval of original\nauthor, or at least one other native speaker has to approve of the change\n(happens rarely).\n\nGrunt tasks\n===========\n\nWe use Grunt for managing the build. Here are some useful Grunt tasks:\n\n  * `grunt` The default task lints the code and runs the tests. You should make sure you do this before submitting a PR.\n  * `grunt test` run the tests.\n  * `grunt release` Build everything, including minified files (do not include\n    those in Pull Requests)\n  * `grunt transpile:fr,ru` Build custom locale bundles `moment-with-locales.custom.js` and `locales.custom.js` inside `build/umd/min` containing just French and Russian.\n  * `grunt size` Print size statistics.\n\nBecoming a moment team member\n=============================\n\nMoment's team members have extra powers and responsibilities. If you want to\nbecome one -- be active in our repositories by answering issues, reviewing PRs,\ndiscussing changes, submitting PRs for open bugs. Any help on\n[moment/moment](https://github.com/moment/moment),\n[moment/momentjs.com](https://github.com/moment/momentjs.com),\n[moment/moment-timezone](https://github.com/moment/moment-timezone) will be\nnoticed.\n\nOnce you've proven to be trustworthy, submit your request to the\n[gitter chat](https://gitter.im/moment/moment), and it will be reviewed by the\nexisting team.\n\nOnce you become a member:\n* you can tell your friends\n* you can close issues submitted by others\n\nBut also:\n* be active in the repositories\n* pick up work nobody else wants to\n* attend a monthly meeting\n* participate in the internal slack group\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/Gruntfile.js",
    "content": "module.exports = function (grunt) {\n    grunt.initConfig({\n        pkg: grunt.file.readJSON('package.json'),\n        env : {\n            sauceLabs : (grunt.file.exists('.sauce-labs.creds') ?\n                    grunt.file.readJSON('.sauce-labs.creds') : {})\n        },\n        karma : {\n            options: {\n                browserNoActivityTimeout: 60000,\n                browserDisconnectTimeout: 10000,\n                browserDisconnectTolerance: 2,\n                frameworks: ['qunit'],\n                files: [\n                    'min/moment-with-locales.js',\n                    'min/tests.js'\n                ],\n                sauceLabs: {\n                    startConnect: true,\n                    testName: 'MomentJS'\n                },\n                customLaunchers: {\n                    slChromeWinXp: {\n                        base: 'SauceLabs',\n                        browserName: 'chrome',\n                        platform: 'Windows XP'\n                    },\n                    slIe10Win7: {\n                        base: 'SauceLabs',\n                        browserName: 'internet explorer',\n                        platform: 'Windows 7',\n                        version: '10'\n                    },\n                    slIe9Win7: {\n                        base: 'SauceLabs',\n                        browserName: 'internet explorer',\n                        platform: 'Windows 7',\n                        version: '9'\n                    },\n                    slIe8Win7: {\n                        base: 'SauceLabs',\n                        browserName: 'internet explorer',\n                        platform: 'Windows 7',\n                        version: '8'\n                    },\n                    slIe11Win10: {\n                        base: 'SauceLabs',\n                        browserName: 'internet explorer',\n                        platform: 'Windows 10',\n                        version: '11'\n                    },\n                    slME25Win10: {\n                        base: 'SauceLabs',\n                        browserName: 'MicrosoftEdge',\n                        platform: 'Windows 10',\n                        version: '20.10240'\n                    },\n                    slFfLinux: {\n                        base: 'SauceLabs',\n                        browserName: 'firefox',\n                        platform: 'Linux'\n                    },\n                    slSafariOsx: {\n                        base: 'SauceLabs',\n                        browserName: 'safari',\n                        platform: 'OS X 10.8'\n                    },\n                    slSafariOsx11: {\n                        base: 'SauceLabs',\n                        browserName: 'safari',\n                        platform: 'OS X 10.11'\n                    }\n                }\n            },\n            server: {\n                browsers: []\n            },\n            chrome: {\n                singleRun: true,\n                browsers: ['Chrome']\n            },\n            firefox: {\n                singleRun: true,\n                browsers: ['Firefox']\n            },\n            sauce: {\n                options: {\n                    reporters: ['dots']\n                },\n                singleRun: true,\n                browsers: [\n                    'slChromeWinXp',\n                    'slIe10Win7',\n                    'slIe9Win7',\n                    'slIe8Win7',\n                    'slIe11Win10',\n                    'slME25Win10',\n                    'slFfLinux',\n                    'slSafariOsx'\n                ]\n            }\n        },\n        uglify : {\n            main: {\n                files: {\n                    'min/moment-with-locales.min.js'     : 'min/moment-with-locales.js',\n                    'min/locales.min.js'                 : 'min/locales.js',\n                    'min/moment.min.js'                  : 'moment.js'\n                }\n            },\n            options: {\n                mangle: true,\n                compress: {\n                    dead_code: false // jshint ignore:line\n                },\n                output: {\n                    ascii_only: true // jshint ignore:line\n                },\n                report: 'min',\n                preserveComments: /^!|@preserve|@license|@cc_on/i\n            }\n        },\n        jshint: {\n            all: [\n                'Gruntfile.js',\n                'tasks/**.js',\n                'src/**/*.js'\n            ],\n            options: {\n                jshintrc: true\n            }\n        },\n        jscs: {\n            all: [\n                'Gruntfile.js',\n                'tasks/**.js',\n                'src/**/*.js'\n            ],\n            options: {\n                config: '.jscs.json'\n            }\n        },\n        watch : {\n            test : {\n                files : [\n                    'src/**/*.js'\n                ],\n                tasks: ['test']\n            },\n            jshint : {\n                files : '<%= jshint.all %>',\n                tasks: ['jshint']\n            }\n        },\n        benchmark: {\n            all: {\n                src: ['benchmarks/*.js']\n            }\n        },\n        exec: {\n            'meteor-init': {\n                // Make sure Meteor is installed, per https://meteor.com/install.\n                // The curl'ed script is safe; takes 2 minutes to read source & check.\n                command: 'type meteor >/dev/null 2>&1 || { curl https://install.meteor.com/ | sh; }'\n            },\n            'meteor-test': {\n                command: 'spacejam --mongo-url mongodb:// test-packages ./meteor'\n            },\n            'meteor-publish': {\n                command: 'cd meteor && meteor publish'\n            },\n            'typescript-test': {\n                command: 'npm run typescript-test'\n            }\n        }\n\n    });\n\n    grunt.loadTasks('tasks');\n\n    // These plugins provide necessary tasks.\n    require('load-grunt-tasks')(grunt);\n\n    // Default task.\n    grunt.registerTask('default', ['lint', 'test']);\n\n    // linting\n    grunt.registerTask('lint', ['jshint', 'jscs']);\n\n    // test tasks\n    grunt.registerTask('test', ['test:node', 'test:typescript']);\n    grunt.registerTask('test:node', ['transpile', 'qtest']);\n    grunt.registerTask('test:typescript', ['exec:typescript-test']);\n    // TODO: For some weird reason karma doesn't like the files in\n    // build/umd/min/* but works with min/*, so update-index, then git checkout\n    grunt.registerTask('test:server', ['transpile', 'update-index', 'karma:server']);\n    grunt.registerTask('test:browser', ['transpile', 'update-index', 'karma:chrome', 'karma:firefox']);\n    grunt.registerTask('test:sauce-browser', ['transpile', 'update-index', 'env:sauceLabs', 'karma:sauce']);\n    grunt.registerTask('test:meteor', ['exec:meteor-init', 'exec:meteor-test', 'exec:meteor-cleanup']);\n\n    // travis build task\n    grunt.registerTask('build:travis', ['default']);\n    grunt.registerTask('meteor-publish', ['exec:meteor-init', 'exec:meteor-publish', 'exec:meteor-cleanup']);\n\n    // Task to be run when releasing a new version\n    grunt.registerTask('release', [\n        'default',\n        'update-index',\n        'component',\n        'uglify:main'\n    ]);\n};\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/ISSUE_TEMPLATE.md",
    "content": "**Description of the Issue and Steps to Reproduce:**\n\n*Please include the values of all variables used.*\n\n**Environment:**\n\n*Examples: Chrome 49 on OSX, Internet Explorer 10 on Windows 7, Node.JS 4.4.4 on Ubuntu 16.0.4*\n\n*Both the browser and the OS are important to us, particularly if you have an unsual environment like an IOT application.*\n\n**Other information that may be helpful:**\n* The time zone setting of the machine the code is running on\n* The time and date at which the code was run\n* Other libraries in use (TypeScript, Immutable.js, etc)\n\nIf you are reporting an issue, please run the following code in the environment you are using and include the output:\n```js\nconsole.log( (new Date()).toString())\nconsole.log((new Date()).toLocaleString())\nconsole.log( (new Date()).getTimezoneOffset())\nconsole.log( navigator.userAgent)\nconsole.log(moment.version)\n```\n\n*Ensure your issue is isolated to moment. Issues involving third party tools will be closed unless submitted by the tool's author/maintainer.*"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/LICENSE",
    "content": "Copyright (c) JS Foundation and other contributors\n\nPermission is hereby granted, free of charge, to any person\nobtaining a copy of this software and associated documentation\nfiles (the \"Software\"), to deal in the Software without\nrestriction, including without limitation the rights to use,\ncopy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the\nSoftware is furnished to do so, subject to the following\nconditions:\n\nThe above copyright notice and this permission notice shall be\nincluded in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\nEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES\nOF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\nNONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT\nHOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,\nWHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\nFROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR\nOTHER DEALINGS IN THE SOFTWARE.\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/Moment.js.nuspec",
    "content": "<?xml version=\"1.0\"?>\r\n<package xmlns=\"http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd\">\r\n    <metadata>\r\n        <id>Moment.js</id>\r\n        <version>2.18.1</version>\r\n        <authors>Tim Wood, Iskren Chernev, Moment.js contributors</authors>\r\n        <owners>Cory Deppen, Iskren Chernev</owners>\r\n        <description>A lightweight JavaScript date library for parsing, manipulating, and formatting dates.</description>\r\n        <releaseNotes>\r\n            * Release Mar 22, 2017\r\n            * [#3853](https://github.com/moment/moment/pull/3853) [misc] Fix invalid whitespace character causing inability to parse\r\n              moment.js\r\n        </releaseNotes>\r\n        <projectUrl>http://momentjs.com/</projectUrl>\r\n        <iconUrl>http://pbs.twimg.com/profile_images/482670411402858496/Xrtdc94q_normal.png</iconUrl>\r\n        <licenseUrl>https://raw.github.com/timrwood/moment/master/LICENSE</licenseUrl>\r\n        <tags>JavaScript date time browser node.js</tags>\r\n  </metadata>\r\n  <files>\r\n      <file src=\"moment.js\" target=\"Content\\Scripts\" />\r\n      <file src=\"min/moment.min.js\" target=\"Content\\Scripts\" />\r\n      <file src=\"min/moment-with-locales.js\" target=\"Content\\Scripts\" />\r\n      <file src=\"min/moment-with-locales.min.js\" target=\"Content\\Scripts\" />\r\n  </files>\r\n</package>\r\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/README.md",
    "content": "[![Join the chat at https://gitter.im/moment/moment](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/moment/moment?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)\n\n[![NPM version][npm-version-image]][npm-url] [![NPM downloads][npm-downloads-image]][npm-url] [![MIT License][license-image]][license-url] [![Build Status][travis-image]][travis-url]\n[![Coverage Status](https://coveralls.io/repos/moment/moment/badge.svg?branch=develop)](https://coveralls.io/r/moment/moment?branch=develop)\n\nA lightweight JavaScript date library for parsing, validating, manipulating, and formatting dates.\n\n**[Documentation](http://momentjs.com/docs/)**\n\n## Port to ECMAScript 6 (version 2.10.0)\n\nMoment 2.10.0 does not bring any new features, but the code is now written in\nECMAScript 6 modules and placed inside `src/`. Previously `moment.js`, `locale/*.js` and\n`test/moment/*.js`, `test/locale/*.js` contained the source of the project. Now\nthe source is in `src/`, temporary build (ECMAScript 5) files are placed under\n`build/umd/` (for running tests during development), and the `moment.js` and\n`locale/*.js` files are updated only on release.\n\nIf you want to use a particular revision of the code, make sure to run\n`grunt transpile update-index`, so `moment.js` and `locales/*.js` are synced\nwith `src/*`. We might place that in a commit hook in the future.\n\n## Upgrading to 2.0.0\n\nThere are a number of small backwards incompatible changes with version 2.0.0. [See the full descriptions here](https://gist.github.com/timrwood/e72f2eef320ed9e37c51#backwards-incompatible-changes)\n\n * Changed language ordinal method to return the number + ordinal instead of just the ordinal.\n\n * Changed two digit year parsing cutoff to match strptime.\n\n * Removed `moment#sod` and `moment#eod` in favor of `moment#startOf` and `moment#endOf`.\n\n * Removed `moment.humanizeDuration()` in favor of `moment.duration().humanize()`.\n\n * Removed the lang data objects from the top level namespace.\n\n * Duplicate `Date` passed to `moment()` instead of referencing it.\n\n## [Changelog](https://github.com/moment/moment/blob/develop/CHANGELOG.md)\n\n## [Contributing](https://github.com/moment/moment/blob/develop/CONTRIBUTING.md)\n\nWe're looking for co-maintainers! If you want to become a master of time please\nwrite to [ichernev](https://github.com/ichernev).\n\n## License\n\nMoment.js is freely distributable under the terms of the [MIT license](https://github.com/moment/moment/blob/develop/LICENSE).\n\n[license-image]: http://img.shields.io/badge/license-MIT-blue.svg?style=flat\n[license-url]: LICENSE\n\n[npm-url]: https://npmjs.org/package/moment\n[npm-version-image]: http://img.shields.io/npm/v/moment.svg?style=flat\n[npm-downloads-image]: http://img.shields.io/npm/dm/moment.svg?style=flat\n\n[travis-url]: http://travis-ci.org/moment/moment\n[travis-image]: http://img.shields.io/travis/moment/moment/develop.svg?style=flat\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/benchmarks/add.js",
    "content": "var Benchmark = require('benchmark'),\n    moment = require(\"./../moment.js\"),\n    base = moment('2013-05-25');\n\nvar unitsUnderTest = [\"milliseconds\", \"seconds\", \"minutes\", \"hours\", \"days\", \"weeks\", \"months\", \"quarters\", \"years\"];\nvar tests = unitsUnderTest.reduce(function (testsSoFar, unit) {\n    testsSoFar[\"add \" + unit] = generateTestForUnit(unit);\n    return testsSoFar;\n}, {});\n\nfunction generateTestForUnit(unit) {\n    return {\n        setup: function(){var base = base; var unit = unit;},\n        fn: function(){base.add(8, unit);},\n        async: true\n    };\n}\n\nmodule.exports = {\n    name: 'add',\n    tests: tests\n};\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/benchmarks/clone.js",
    "content": "var Benchmark = require('benchmark'),\n    moment = require(\"./../moment.js\"),\n    base = moment('2013-05-25');\n\nmodule.exports = {\n  name: 'clone',\n  onComplete: function(){},\n  fn: function(){base.clone();},\n  async: true\n};\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/benchmarks/endOf.js",
    "content": "var Benchmark = require('benchmark'),\n    moment = require(\"./../moment.js\"),\n    base = moment('2013-05-25');\n\nvar unitsUnderTest = [\"second\", \"minute\", \"hour\", \"date\", \"day\", \"isoWeek\", \"week\", \"month\", \"quarter\", \"year\"];\nvar tests = unitsUnderTest.reduce(function (testsSoFar, unit) {\n    testsSoFar[\"endOf \" + unit] = generateTestForUnit(unit);\n    return testsSoFar;\n}, {});\n\nfunction generateTestForUnit(unit) {\n    return {\n        setup: function(){var base = base; var unit = unit;},\n        fn: function(){base.endOf(unit);},\n        async: true\n    };\n}\n\nmodule.exports = {\n    name: 'endOf',\n    tests: tests\n};\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/benchmarks/fromDate.js",
    "content": "var Benchmark = require('benchmark'),\n    moment = require('./../moment.js'),\n    base = new Date();\n\nmodule.exports = {\n  name: 'fromDate',\n  onComplete: function(){},\n  fn: function(){\n      moment(base);\n  },\n  async: true\n};\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/benchmarks/fromDateUtc.js",
    "content": "var Benchmark = require('benchmark'),\n    moment = require('./../moment.js'),\n    base = new Date();\n\nmodule.exports = {\n  name: 'fromDateUtc',\n  onComplete: function(){},\n  fn: function(){\n      moment.utc(base);\n  },\n  async: true\n};\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/benchmarks/makeDuration.js",
    "content": "var Benchmark = require('benchmark'),\n    moment = require('./../moment.js');\n\nmodule.exports = {\n  name: 'makeDuration',\n  onComplete: function(){},\n  fn: function(){\n      moment.duration(5, 'years');\n  },\n  async: true\n};\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/benchmarks/query.js",
    "content": "var Benchmark = require('benchmark'),\n    moment = require(\"./../moment.js\"),\n    base = moment('2013-05-25');\n\n\nmodule.exports = {\n    name: 'clone',\n    tests: {\n        isBefore_true: {\n            onComplete: function(){},\n            fn: function(){base.isBefore('2013-06-25');},\n            async: true\n        },\n        isBefore_self: {\n            onComplete: function(){},\n            fn: function(){base.isBefore('2013-05-25');},\n            async: true\n        },\n        isBefore_false: {\n            onComplete: function(){},\n            fn: function(){base.isBefore('2013-04-25');},\n            async: true\n        },\n        isAfter_true: {\n            onComplete: function(){},\n            fn: function(){base.isAfter('2013-04-25');},\n            async: true\n        },\n        isAfter_self: {\n            onComplete: function(){},\n            fn: function(){base.isAfter('2013-05-25');},\n            async: true\n        },\n        isAfter_false: {\n            onComplete: function(){},\n            fn: function(){base.isAfter('2013-06-25');},\n            async: true\n        }\n    }\n};\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/benchmarks/startOf.js",
    "content": "var Benchmark = require('benchmark'),\n    moment = require(\"./../moment.js\"),\n    base = moment('2013-05-25');\n\nvar unitsUnderTest = [\"second\", \"minute\", \"hour\", \"date\", \"day\", \"isoWeek\", \"week\", \"month\", \"quarter\", \"year\"];\nvar tests = unitsUnderTest.reduce(function (testsSoFar, unit) {\n    testsSoFar[\"startOf \" + unit] = generateTestForUnit(unit);\n    return testsSoFar;\n}, {});\n\nfunction generateTestForUnit(unit) {\n    return {\n        setup: function(){var base = base; var unit = unit;},\n        fn: function(){base.startOf(unit);},\n        async: true\n    };\n}\n\nmodule.exports = {\n    name: 'startOf',\n    tests: tests\n};\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/benchmarks/subtract.js",
    "content": "var Benchmark = require('benchmark'),\n    moment = require(\"./../moment.js\"),\n    base = moment('2013-05-25');\n\nvar unitsUnderTest = [\"milliseconds\", \"seconds\", \"minutes\", \"hours\", \"days\", \"weeks\", \"months\", \"quarters\", \"years\"];\nvar tests = unitsUnderTest.reduce(function (testsSoFar, unit) {\n    testsSoFar[\"subtract \" + unit] = generateTestForUnit(unit);\n    return testsSoFar;\n}, {});\n\nfunction generateTestForUnit(unit) {\n    return {\n        setup: function(){var base = base; var unit = unit;},\n        fn: function(){base.subtract(8, unit);},\n        async: true\n    };\n}\n\nmodule.exports = {\n    name: 'subtract',\n    tests: tests\n};\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/benchmarks/zeroFill.js",
    "content": "var Benchmark = require('benchmark');\n\nmodule.exports = {\n  name: 'zeroFill',\n  tests: {\n    zeroFillMath: {\n      setup: function() {\n        var zeroFillMath = function(number, targetLength, forceSign) {\n            var absNumber = '' + Math.abs(number),\n                zerosToFill = targetLength - absNumber.length,\n                sign = number >= 0;\n            return (sign ? (forceSign ? '+' : '') : '-') +\n                Math.pow(10, Math.max(0, zerosToFill)).toString().substr(1) + absNumber;\n        }\n      },\n      fn: function() {\n        zeroFillMath(Math.random() * 1e5 | 0, 5);\n        zeroFillMath(Math.random() * 1e5 | 0, 10);\n        zeroFillMath(Math.random() * 1e10 | 0, 20);\n      },\n      async: true\n    },\n    zeroFillWhile: {\n      setup: function() {\n        var zeroFillWhile = function(number, targetLength, forceSign) {\n          var output = '' + Math.abs(number),\n              sign = number >= 0;\n\n          while (output.length < targetLength) {\n              output = '0' + output;\n          }\n          return (sign ? (forceSign ? '+' : '') : '-') + output;\n        }\n      },\n      fn: function() {\n        zeroFillWhile(Math.random() * 1e5 | 0, 5);\n        zeroFillWhile(Math.random() * 1e5 | 0, 10);\n        zeroFillWhile(Math.random() * 1e10 | 0, 20);\n      },\n      async: true\n    }\n  }\n};\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/bower.json",
    "content": "{\n  \"name\": \"moment\",\n  \"license\": \"MIT\",\n  \"main\": \"moment.js\",\n  \"ignore\": [\n    \"**/.*\",\n    \"benchmarks\",\n    \"bower_components\",\n    \"meteor\",\n    \"node_modules\",\n    \"scripts\",\n    \"tasks\",\n    \"test\",\n    \"component.json\",\n    \"composer.json\",\n    \"CONTRIBUTING.md\",\n    \"ender.js\",\n    \"Gruntfile.js\",\n    \"Moment.js.nuspec\",\n    \"package.js\",\n    \"package.json\",\n    \"ISSUE_TEMPLATE.md\",\n    \"typing-tests\"\n  ]\n}\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/component.json",
    "content": "{\n  \"name\": \"moment\",\n  \"version\": \"2.18.1\",\n  \"main\": \"moment.js\",\n  \"description\": \"Parse, validate, manipulate, and display dates in JavaScript.\",\n  \"files\": [\n    \"moment.js\",\n    \"locale/af.js\",\n    \"locale/ar-dz.js\",\n    \"locale/ar-kw.js\",\n    \"locale/ar-ly.js\",\n    \"locale/ar-ma.js\",\n    \"locale/ar-sa.js\",\n    \"locale/ar-tn.js\",\n    \"locale/ar.js\",\n    \"locale/az.js\",\n    \"locale/be.js\",\n    \"locale/bg.js\",\n    \"locale/bn.js\",\n    \"locale/bo.js\",\n    \"locale/br.js\",\n    \"locale/bs.js\",\n    \"locale/ca.js\",\n    \"locale/cs.js\",\n    \"locale/cv.js\",\n    \"locale/cy.js\",\n    \"locale/da.js\",\n    \"locale/de-at.js\",\n    \"locale/de-ch.js\",\n    \"locale/de.js\",\n    \"locale/dv.js\",\n    \"locale/el.js\",\n    \"locale/en-au.js\",\n    \"locale/en-ca.js\",\n    \"locale/en-gb.js\",\n    \"locale/en-ie.js\",\n    \"locale/en-nz.js\",\n    \"locale/eo.js\",\n    \"locale/es-do.js\",\n    \"locale/es.js\",\n    \"locale/et.js\",\n    \"locale/eu.js\",\n    \"locale/fa.js\",\n    \"locale/fi.js\",\n    \"locale/fo.js\",\n    \"locale/fr-ca.js\",\n    \"locale/fr-ch.js\",\n    \"locale/fr.js\",\n    \"locale/fy.js\",\n    \"locale/gd.js\",\n    \"locale/gl.js\",\n    \"locale/gom-latn.js\",\n    \"locale/he.js\",\n    \"locale/hi.js\",\n    \"locale/hr.js\",\n    \"locale/hu.js\",\n    \"locale/hy-am.js\",\n    \"locale/id.js\",\n    \"locale/is.js\",\n    \"locale/it.js\",\n    \"locale/ja.js\",\n    \"locale/jv.js\",\n    \"locale/ka.js\",\n    \"locale/kk.js\",\n    \"locale/km.js\",\n    \"locale/kn.js\",\n    \"locale/ko.js\",\n    \"locale/ky.js\",\n    \"locale/lb.js\",\n    \"locale/lo.js\",\n    \"locale/lt.js\",\n    \"locale/lv.js\",\n    \"locale/me.js\",\n    \"locale/mi.js\",\n    \"locale/mk.js\",\n    \"locale/ml.js\",\n    \"locale/mr.js\",\n    \"locale/ms-my.js\",\n    \"locale/ms.js\",\n    \"locale/my.js\",\n    \"locale/nb.js\",\n    \"locale/ne.js\",\n    \"locale/nl-be.js\",\n    \"locale/nl.js\",\n    \"locale/nn.js\",\n    \"locale/pa-in.js\",\n    \"locale/pl.js\",\n    \"locale/pt-br.js\",\n    \"locale/pt.js\",\n    \"locale/ro.js\",\n    \"locale/ru.js\",\n    \"locale/sd.js\",\n    \"locale/se.js\",\n    \"locale/si.js\",\n    \"locale/sk.js\",\n    \"locale/sl.js\",\n    \"locale/sq.js\",\n    \"locale/sr-cyrl.js\",\n    \"locale/sr.js\",\n    \"locale/ss.js\",\n    \"locale/sv.js\",\n    \"locale/sw.js\",\n    \"locale/ta.js\",\n    \"locale/te.js\",\n    \"locale/tet.js\",\n    \"locale/th.js\",\n    \"locale/tl-ph.js\",\n    \"locale/tlh.js\",\n    \"locale/tr.js\",\n    \"locale/tzl.js\",\n    \"locale/tzm-latn.js\",\n    \"locale/tzm.js\",\n    \"locale/uk.js\",\n    \"locale/ur.js\",\n    \"locale/uz-latn.js\",\n    \"locale/uz.js\",\n    \"locale/vi.js\",\n    \"locale/x-pseudo.js\",\n    \"locale/yo.js\",\n    \"locale/zh-cn.js\",\n    \"locale/zh-hk.js\",\n    \"locale/zh-tw.js\"\n  ],\n  \"scripts\": [\n    \"moment.js\"\n  ]\n}\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/composer.json",
    "content": "{\n    \"name\": \"moment/moment\",\n    \"description\": \"Parse, validate, manipulate, and display dates in JavaScript.\",\n    \"keywords\": [\n        \"moment\",\n        \"date\",\n        \"time\",\n        \"parse\",\n        \"format\",\n        \"validate\",\n        \"i18n\",\n        \"l10n\",\n        \"ender\"\n    ],\n    \"homepage\": \"https://github.com/moment/moment\",\n    \"authors\": [{\"name\": \"Tim Wood\", \"email\": \"washwithcare@gmail.com\"}],\n    \"license\": \"MIT\",\n    \"type\": \"component\",\n    \"require\": {\n        \"robloach/component-installer\": \"*\"\n    },\n    \"extra\": {\n        \"component\": {\n            \"scripts\": [\n                \"moment.js\"\n            ],\n            \"files\": [\n               \"min/*.js\",\n               \"locale/*.js\"\n            ]\n        }\n    }\n}\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/ender.js",
    "content": "$.ender({ moment: require('moment') })\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/locale/af.js",
    "content": "//! moment.js locale configuration\n//! locale : Afrikaans [af]\n//! author : Werner Mollentze : https://github.com/wernerm\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\n\nvar af = moment.defineLocale('af', {\n    months : 'Januarie_Februarie_Maart_April_Mei_Junie_Julie_Augustus_September_Oktober_November_Desember'.split('_'),\n    monthsShort : 'Jan_Feb_Mrt_Apr_Mei_Jun_Jul_Aug_Sep_Okt_Nov_Des'.split('_'),\n    weekdays : 'Sondag_Maandag_Dinsdag_Woensdag_Donderdag_Vrydag_Saterdag'.split('_'),\n    weekdaysShort : 'Son_Maa_Din_Woe_Don_Vry_Sat'.split('_'),\n    weekdaysMin : 'So_Ma_Di_Wo_Do_Vr_Sa'.split('_'),\n    meridiemParse: /vm|nm/i,\n    isPM : function (input) {\n        return /^nm$/i.test(input);\n    },\n    meridiem : function (hours, minutes, isLower) {\n        if (hours < 12) {\n            return isLower ? 'vm' : 'VM';\n        } else {\n            return isLower ? 'nm' : 'NM';\n        }\n    },\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY HH:mm',\n        LLLL : 'dddd, D MMMM YYYY HH:mm'\n    },\n    calendar : {\n        sameDay : '[Vandag om] LT',\n        nextDay : '[Môre om] LT',\n        nextWeek : 'dddd [om] LT',\n        lastDay : '[Gister om] LT',\n        lastWeek : '[Laas] dddd [om] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'oor %s',\n        past : '%s gelede',\n        s : '\\'n paar sekondes',\n        m : '\\'n minuut',\n        mm : '%d minute',\n        h : '\\'n uur',\n        hh : '%d ure',\n        d : '\\'n dag',\n        dd : '%d dae',\n        M : '\\'n maand',\n        MM : '%d maande',\n        y : '\\'n jaar',\n        yy : '%d jaar'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}(ste|de)/,\n    ordinal : function (number) {\n        return number + ((number === 1 || number === 8 || number >= 20) ? 'ste' : 'de'); // Thanks to Joris Röling : https://github.com/jjupiter\n    },\n    week : {\n        dow : 1, // Maandag is die eerste dag van die week.\n        doy : 4  // Die week wat die 4de Januarie bevat is die eerste week van die jaar.\n    }\n});\n\nreturn af;\n\n})));\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/locale/ar-dz.js",
    "content": "//! moment.js locale configuration\n//! locale : Arabic (Algeria) [ar-dz]\n//! author : Noureddine LOUAHEDJ : https://github.com/noureddineme\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\n\nvar arDz = moment.defineLocale('ar-dz', {\n    months : 'جانفي_فيفري_مارس_أفريل_ماي_جوان_جويلية_أوت_سبتمبر_أكتوبر_نوفمبر_ديسمبر'.split('_'),\n    monthsShort : 'جانفي_فيفري_مارس_أفريل_ماي_جوان_جويلية_أوت_سبتمبر_أكتوبر_نوفمبر_ديسمبر'.split('_'),\n    weekdays : 'الأحد_الإثنين_الثلاثاء_الأربعاء_الخميس_الجمعة_السبت'.split('_'),\n    weekdaysShort : 'احد_اثنين_ثلاثاء_اربعاء_خميس_جمعة_سبت'.split('_'),\n    weekdaysMin : 'أح_إث_ثلا_أر_خم_جم_سب'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY HH:mm',\n        LLLL : 'dddd D MMMM YYYY HH:mm'\n    },\n    calendar : {\n        sameDay: '[اليوم على الساعة] LT',\n        nextDay: '[غدا على الساعة] LT',\n        nextWeek: 'dddd [على الساعة] LT',\n        lastDay: '[أمس على الساعة] LT',\n        lastWeek: 'dddd [على الساعة] LT',\n        sameElse: 'L'\n    },\n    relativeTime : {\n        future : 'في %s',\n        past : 'منذ %s',\n        s : 'ثوان',\n        m : 'دقيقة',\n        mm : '%d دقائق',\n        h : 'ساعة',\n        hh : '%d ساعات',\n        d : 'يوم',\n        dd : '%d أيام',\n        M : 'شهر',\n        MM : '%d أشهر',\n        y : 'سنة',\n        yy : '%d سنوات'\n    },\n    week : {\n        dow : 0, // Sunday is the first day of the week.\n        doy : 4  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\nreturn arDz;\n\n})));\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/locale/ar-kw.js",
    "content": "//! moment.js locale configuration\n//! locale : Arabic (Kuwait) [ar-kw]\n//! author : Nusret Parlak: https://github.com/nusretparlak\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\n\nvar arKw = moment.defineLocale('ar-kw', {\n    months : 'يناير_فبراير_مارس_أبريل_ماي_يونيو_يوليوز_غشت_شتنبر_أكتوبر_نونبر_دجنبر'.split('_'),\n    monthsShort : 'يناير_فبراير_مارس_أبريل_ماي_يونيو_يوليوز_غشت_شتنبر_أكتوبر_نونبر_دجنبر'.split('_'),\n    weekdays : 'الأحد_الإتنين_الثلاثاء_الأربعاء_الخميس_الجمعة_السبت'.split('_'),\n    weekdaysShort : 'احد_اتنين_ثلاثاء_اربعاء_خميس_جمعة_سبت'.split('_'),\n    weekdaysMin : 'ح_ن_ث_ر_خ_ج_س'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY HH:mm',\n        LLLL : 'dddd D MMMM YYYY HH:mm'\n    },\n    calendar : {\n        sameDay: '[اليوم على الساعة] LT',\n        nextDay: '[غدا على الساعة] LT',\n        nextWeek: 'dddd [على الساعة] LT',\n        lastDay: '[أمس على الساعة] LT',\n        lastWeek: 'dddd [على الساعة] LT',\n        sameElse: 'L'\n    },\n    relativeTime : {\n        future : 'في %s',\n        past : 'منذ %s',\n        s : 'ثوان',\n        m : 'دقيقة',\n        mm : '%d دقائق',\n        h : 'ساعة',\n        hh : '%d ساعات',\n        d : 'يوم',\n        dd : '%d أيام',\n        M : 'شهر',\n        MM : '%d أشهر',\n        y : 'سنة',\n        yy : '%d سنوات'\n    },\n    week : {\n        dow : 0, // Sunday is the first day of the week.\n        doy : 12  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\nreturn arKw;\n\n})));\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/locale/ar-ly.js",
    "content": "//! moment.js locale configuration\n//! locale : Arabic (Lybia) [ar-ly]\n//! author : Ali Hmer: https://github.com/kikoanis\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\n\nvar symbolMap = {\n    '1': '1',\n    '2': '2',\n    '3': '3',\n    '4': '4',\n    '5': '5',\n    '6': '6',\n    '7': '7',\n    '8': '8',\n    '9': '9',\n    '0': '0'\n};\nvar pluralForm = function (n) {\n    return n === 0 ? 0 : n === 1 ? 1 : n === 2 ? 2 : n % 100 >= 3 && n % 100 <= 10 ? 3 : n % 100 >= 11 ? 4 : 5;\n};\nvar plurals = {\n    s : ['أقل من ثانية', 'ثانية واحدة', ['ثانيتان', 'ثانيتين'], '%d ثوان', '%d ثانية', '%d ثانية'],\n    m : ['أقل من دقيقة', 'دقيقة واحدة', ['دقيقتان', 'دقيقتين'], '%d دقائق', '%d دقيقة', '%d دقيقة'],\n    h : ['أقل من ساعة', 'ساعة واحدة', ['ساعتان', 'ساعتين'], '%d ساعات', '%d ساعة', '%d ساعة'],\n    d : ['أقل من يوم', 'يوم واحد', ['يومان', 'يومين'], '%d أيام', '%d يومًا', '%d يوم'],\n    M : ['أقل من شهر', 'شهر واحد', ['شهران', 'شهرين'], '%d أشهر', '%d شهرا', '%d شهر'],\n    y : ['أقل من عام', 'عام واحد', ['عامان', 'عامين'], '%d أعوام', '%d عامًا', '%d عام']\n};\nvar pluralize = function (u) {\n    return function (number, withoutSuffix, string, isFuture) {\n        var f = pluralForm(number),\n            str = plurals[u][pluralForm(number)];\n        if (f === 2) {\n            str = str[withoutSuffix ? 0 : 1];\n        }\n        return str.replace(/%d/i, number);\n    };\n};\nvar months = [\n    'يناير',\n    'فبراير',\n    'مارس',\n    'أبريل',\n    'مايو',\n    'يونيو',\n    'يوليو',\n    'أغسطس',\n    'سبتمبر',\n    'أكتوبر',\n    'نوفمبر',\n    'ديسمبر'\n];\n\nvar arLy = moment.defineLocale('ar-ly', {\n    months : months,\n    monthsShort : months,\n    weekdays : 'الأحد_الإثنين_الثلاثاء_الأربعاء_الخميس_الجمعة_السبت'.split('_'),\n    weekdaysShort : 'أحد_إثنين_ثلاثاء_أربعاء_خميس_جمعة_سبت'.split('_'),\n    weekdaysMin : 'ح_ن_ث_ر_خ_ج_س'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'D/\\u200FM/\\u200FYYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY HH:mm',\n        LLLL : 'dddd D MMMM YYYY HH:mm'\n    },\n    meridiemParse: /ص|م/,\n    isPM : function (input) {\n        return 'م' === input;\n    },\n    meridiem : function (hour, minute, isLower) {\n        if (hour < 12) {\n            return 'ص';\n        } else {\n            return 'م';\n        }\n    },\n    calendar : {\n        sameDay: '[اليوم عند الساعة] LT',\n        nextDay: '[غدًا عند الساعة] LT',\n        nextWeek: 'dddd [عند الساعة] LT',\n        lastDay: '[أمس عند الساعة] LT',\n        lastWeek: 'dddd [عند الساعة] LT',\n        sameElse: 'L'\n    },\n    relativeTime : {\n        future : 'بعد %s',\n        past : 'منذ %s',\n        s : pluralize('s'),\n        m : pluralize('m'),\n        mm : pluralize('m'),\n        h : pluralize('h'),\n        hh : pluralize('h'),\n        d : pluralize('d'),\n        dd : pluralize('d'),\n        M : pluralize('M'),\n        MM : pluralize('M'),\n        y : pluralize('y'),\n        yy : pluralize('y')\n    },\n    preparse: function (string) {\n        return string.replace(/\\u200f/g, '').replace(/،/g, ',');\n    },\n    postformat: function (string) {\n        return string.replace(/\\d/g, function (match) {\n            return symbolMap[match];\n        }).replace(/,/g, '،');\n    },\n    week : {\n        dow : 6, // Saturday is the first day of the week.\n        doy : 12  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\nreturn arLy;\n\n})));\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/locale/ar-ma.js",
    "content": "//! moment.js locale configuration\n//! locale : Arabic (Morocco) [ar-ma]\n//! author : ElFadili Yassine : https://github.com/ElFadiliY\n//! author : Abdel Said : https://github.com/abdelsaid\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\n\nvar arMa = moment.defineLocale('ar-ma', {\n    months : 'يناير_فبراير_مارس_أبريل_ماي_يونيو_يوليوز_غشت_شتنبر_أكتوبر_نونبر_دجنبر'.split('_'),\n    monthsShort : 'يناير_فبراير_مارس_أبريل_ماي_يونيو_يوليوز_غشت_شتنبر_أكتوبر_نونبر_دجنبر'.split('_'),\n    weekdays : 'الأحد_الإتنين_الثلاثاء_الأربعاء_الخميس_الجمعة_السبت'.split('_'),\n    weekdaysShort : 'احد_اتنين_ثلاثاء_اربعاء_خميس_جمعة_سبت'.split('_'),\n    weekdaysMin : 'ح_ن_ث_ر_خ_ج_س'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY HH:mm',\n        LLLL : 'dddd D MMMM YYYY HH:mm'\n    },\n    calendar : {\n        sameDay: '[اليوم على الساعة] LT',\n        nextDay: '[غدا على الساعة] LT',\n        nextWeek: 'dddd [على الساعة] LT',\n        lastDay: '[أمس على الساعة] LT',\n        lastWeek: 'dddd [على الساعة] LT',\n        sameElse: 'L'\n    },\n    relativeTime : {\n        future : 'في %s',\n        past : 'منذ %s',\n        s : 'ثوان',\n        m : 'دقيقة',\n        mm : '%d دقائق',\n        h : 'ساعة',\n        hh : '%d ساعات',\n        d : 'يوم',\n        dd : '%d أيام',\n        M : 'شهر',\n        MM : '%d أشهر',\n        y : 'سنة',\n        yy : '%d سنوات'\n    },\n    week : {\n        dow : 6, // Saturday is the first day of the week.\n        doy : 12  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\nreturn arMa;\n\n})));\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/locale/ar-sa.js",
    "content": "//! moment.js locale configuration\n//! locale : Arabic (Saudi Arabia) [ar-sa]\n//! author : Suhail Alkowaileet : https://github.com/xsoh\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\n\nvar symbolMap = {\n    '1': '١',\n    '2': '٢',\n    '3': '٣',\n    '4': '٤',\n    '5': '٥',\n    '6': '٦',\n    '7': '٧',\n    '8': '٨',\n    '9': '٩',\n    '0': '٠'\n};\nvar numberMap = {\n    '١': '1',\n    '٢': '2',\n    '٣': '3',\n    '٤': '4',\n    '٥': '5',\n    '٦': '6',\n    '٧': '7',\n    '٨': '8',\n    '٩': '9',\n    '٠': '0'\n};\n\nvar arSa = moment.defineLocale('ar-sa', {\n    months : 'يناير_فبراير_مارس_أبريل_مايو_يونيو_يوليو_أغسطس_سبتمبر_أكتوبر_نوفمبر_ديسمبر'.split('_'),\n    monthsShort : 'يناير_فبراير_مارس_أبريل_مايو_يونيو_يوليو_أغسطس_سبتمبر_أكتوبر_نوفمبر_ديسمبر'.split('_'),\n    weekdays : 'الأحد_الإثنين_الثلاثاء_الأربعاء_الخميس_الجمعة_السبت'.split('_'),\n    weekdaysShort : 'أحد_إثنين_ثلاثاء_أربعاء_خميس_جمعة_سبت'.split('_'),\n    weekdaysMin : 'ح_ن_ث_ر_خ_ج_س'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY HH:mm',\n        LLLL : 'dddd D MMMM YYYY HH:mm'\n    },\n    meridiemParse: /ص|م/,\n    isPM : function (input) {\n        return 'م' === input;\n    },\n    meridiem : function (hour, minute, isLower) {\n        if (hour < 12) {\n            return 'ص';\n        } else {\n            return 'م';\n        }\n    },\n    calendar : {\n        sameDay: '[اليوم على الساعة] LT',\n        nextDay: '[غدا على الساعة] LT',\n        nextWeek: 'dddd [على الساعة] LT',\n        lastDay: '[أمس على الساعة] LT',\n        lastWeek: 'dddd [على الساعة] LT',\n        sameElse: 'L'\n    },\n    relativeTime : {\n        future : 'في %s',\n        past : 'منذ %s',\n        s : 'ثوان',\n        m : 'دقيقة',\n        mm : '%d دقائق',\n        h : 'ساعة',\n        hh : '%d ساعات',\n        d : 'يوم',\n        dd : '%d أيام',\n        M : 'شهر',\n        MM : '%d أشهر',\n        y : 'سنة',\n        yy : '%d سنوات'\n    },\n    preparse: function (string) {\n        return string.replace(/[١٢٣٤٥٦٧٨٩٠]/g, function (match) {\n            return numberMap[match];\n        }).replace(/،/g, ',');\n    },\n    postformat: function (string) {\n        return string.replace(/\\d/g, function (match) {\n            return symbolMap[match];\n        }).replace(/,/g, '،');\n    },\n    week : {\n        dow : 0, // Sunday is the first day of the week.\n        doy : 6  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\nreturn arSa;\n\n})));\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/locale/ar-tn.js",
    "content": "//! moment.js locale configuration\n//! locale  :  Arabic (Tunisia) [ar-tn]\n//! author : Nader Toukabri : https://github.com/naderio\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\n\nvar arTn = moment.defineLocale('ar-tn', {\n    months: 'جانفي_فيفري_مارس_أفريل_ماي_جوان_جويلية_أوت_سبتمبر_أكتوبر_نوفمبر_ديسمبر'.split('_'),\n    monthsShort: 'جانفي_فيفري_مارس_أفريل_ماي_جوان_جويلية_أوت_سبتمبر_أكتوبر_نوفمبر_ديسمبر'.split('_'),\n    weekdays: 'الأحد_الإثنين_الثلاثاء_الأربعاء_الخميس_الجمعة_السبت'.split('_'),\n    weekdaysShort: 'أحد_إثنين_ثلاثاء_أربعاء_خميس_جمعة_سبت'.split('_'),\n    weekdaysMin: 'ح_ن_ث_ر_خ_ج_س'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat: {\n        LT: 'HH:mm',\n        LTS: 'HH:mm:ss',\n        L: 'DD/MM/YYYY',\n        LL: 'D MMMM YYYY',\n        LLL: 'D MMMM YYYY HH:mm',\n        LLLL: 'dddd D MMMM YYYY HH:mm'\n    },\n    calendar: {\n        sameDay: '[اليوم على الساعة] LT',\n        nextDay: '[غدا على الساعة] LT',\n        nextWeek: 'dddd [على الساعة] LT',\n        lastDay: '[أمس على الساعة] LT',\n        lastWeek: 'dddd [على الساعة] LT',\n        sameElse: 'L'\n    },\n    relativeTime: {\n        future: 'في %s',\n        past: 'منذ %s',\n        s: 'ثوان',\n        m: 'دقيقة',\n        mm: '%d دقائق',\n        h: 'ساعة',\n        hh: '%d ساعات',\n        d: 'يوم',\n        dd: '%d أيام',\n        M: 'شهر',\n        MM: '%d أشهر',\n        y: 'سنة',\n        yy: '%d سنوات'\n    },\n    week: {\n        dow: 1, // Monday is the first day of the week.\n        doy: 4 // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\nreturn arTn;\n\n})));\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/locale/ar.js",
    "content": "//! moment.js locale configuration\n//! locale : Arabic [ar]\n//! author : Abdel Said: https://github.com/abdelsaid\n//! author : Ahmed Elkhatib\n//! author : forabi https://github.com/forabi\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\n\nvar symbolMap = {\n    '1': '١',\n    '2': '٢',\n    '3': '٣',\n    '4': '٤',\n    '5': '٥',\n    '6': '٦',\n    '7': '٧',\n    '8': '٨',\n    '9': '٩',\n    '0': '٠'\n};\nvar numberMap = {\n    '١': '1',\n    '٢': '2',\n    '٣': '3',\n    '٤': '4',\n    '٥': '5',\n    '٦': '6',\n    '٧': '7',\n    '٨': '8',\n    '٩': '9',\n    '٠': '0'\n};\nvar pluralForm = function (n) {\n    return n === 0 ? 0 : n === 1 ? 1 : n === 2 ? 2 : n % 100 >= 3 && n % 100 <= 10 ? 3 : n % 100 >= 11 ? 4 : 5;\n};\nvar plurals = {\n    s : ['أقل من ثانية', 'ثانية واحدة', ['ثانيتان', 'ثانيتين'], '%d ثوان', '%d ثانية', '%d ثانية'],\n    m : ['أقل من دقيقة', 'دقيقة واحدة', ['دقيقتان', 'دقيقتين'], '%d دقائق', '%d دقيقة', '%d دقيقة'],\n    h : ['أقل من ساعة', 'ساعة واحدة', ['ساعتان', 'ساعتين'], '%d ساعات', '%d ساعة', '%d ساعة'],\n    d : ['أقل من يوم', 'يوم واحد', ['يومان', 'يومين'], '%d أيام', '%d يومًا', '%d يوم'],\n    M : ['أقل من شهر', 'شهر واحد', ['شهران', 'شهرين'], '%d أشهر', '%d شهرا', '%d شهر'],\n    y : ['أقل من عام', 'عام واحد', ['عامان', 'عامين'], '%d أعوام', '%d عامًا', '%d عام']\n};\nvar pluralize = function (u) {\n    return function (number, withoutSuffix, string, isFuture) {\n        var f = pluralForm(number),\n            str = plurals[u][pluralForm(number)];\n        if (f === 2) {\n            str = str[withoutSuffix ? 0 : 1];\n        }\n        return str.replace(/%d/i, number);\n    };\n};\nvar months = [\n    'كانون الثاني يناير',\n    'شباط فبراير',\n    'آذار مارس',\n    'نيسان أبريل',\n    'أيار مايو',\n    'حزيران يونيو',\n    'تموز يوليو',\n    'آب أغسطس',\n    'أيلول سبتمبر',\n    'تشرين الأول أكتوبر',\n    'تشرين الثاني نوفمبر',\n    'كانون الأول ديسمبر'\n];\n\nvar ar = moment.defineLocale('ar', {\n    months : months,\n    monthsShort : months,\n    weekdays : 'الأحد_الإثنين_الثلاثاء_الأربعاء_الخميس_الجمعة_السبت'.split('_'),\n    weekdaysShort : 'أحد_إثنين_ثلاثاء_أربعاء_خميس_جمعة_سبت'.split('_'),\n    weekdaysMin : 'ح_ن_ث_ر_خ_ج_س'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'D/\\u200FM/\\u200FYYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY HH:mm',\n        LLLL : 'dddd D MMMM YYYY HH:mm'\n    },\n    meridiemParse: /ص|م/,\n    isPM : function (input) {\n        return 'م' === input;\n    },\n    meridiem : function (hour, minute, isLower) {\n        if (hour < 12) {\n            return 'ص';\n        } else {\n            return 'م';\n        }\n    },\n    calendar : {\n        sameDay: '[اليوم عند الساعة] LT',\n        nextDay: '[غدًا عند الساعة] LT',\n        nextWeek: 'dddd [عند الساعة] LT',\n        lastDay: '[أمس عند الساعة] LT',\n        lastWeek: 'dddd [عند الساعة] LT',\n        sameElse: 'L'\n    },\n    relativeTime : {\n        future : 'بعد %s',\n        past : 'منذ %s',\n        s : pluralize('s'),\n        m : pluralize('m'),\n        mm : pluralize('m'),\n        h : pluralize('h'),\n        hh : pluralize('h'),\n        d : pluralize('d'),\n        dd : pluralize('d'),\n        M : pluralize('M'),\n        MM : pluralize('M'),\n        y : pluralize('y'),\n        yy : pluralize('y')\n    },\n    preparse: function (string) {\n        return string.replace(/\\u200f/g, '').replace(/[١٢٣٤٥٦٧٨٩٠]/g, function (match) {\n            return numberMap[match];\n        }).replace(/،/g, ',');\n    },\n    postformat: function (string) {\n        return string.replace(/\\d/g, function (match) {\n            return symbolMap[match];\n        }).replace(/,/g, '،');\n    },\n    week : {\n        dow : 6, // Saturday is the first day of the week.\n        doy : 12  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\nreturn ar;\n\n})));\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/locale/az.js",
    "content": "//! moment.js locale configuration\n//! locale : Azerbaijani [az]\n//! author : topchiyev : https://github.com/topchiyev\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\n\nvar suffixes = {\n    1: '-inci',\n    5: '-inci',\n    8: '-inci',\n    70: '-inci',\n    80: '-inci',\n    2: '-nci',\n    7: '-nci',\n    20: '-nci',\n    50: '-nci',\n    3: '-üncü',\n    4: '-üncü',\n    100: '-üncü',\n    6: '-ncı',\n    9: '-uncu',\n    10: '-uncu',\n    30: '-uncu',\n    60: '-ıncı',\n    90: '-ıncı'\n};\n\nvar az = moment.defineLocale('az', {\n    months : 'yanvar_fevral_mart_aprel_may_iyun_iyul_avqust_sentyabr_oktyabr_noyabr_dekabr'.split('_'),\n    monthsShort : 'yan_fev_mar_apr_may_iyn_iyl_avq_sen_okt_noy_dek'.split('_'),\n    weekdays : 'Bazar_Bazar ertəsi_Çərşənbə axşamı_Çərşənbə_Cümə axşamı_Cümə_Şənbə'.split('_'),\n    weekdaysShort : 'Baz_BzE_ÇAx_Çər_CAx_Cüm_Şən'.split('_'),\n    weekdaysMin : 'Bz_BE_ÇA_Çə_CA_Cü_Şə'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD.MM.YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY HH:mm',\n        LLLL : 'dddd, D MMMM YYYY HH:mm'\n    },\n    calendar : {\n        sameDay : '[bugün saat] LT',\n        nextDay : '[sabah saat] LT',\n        nextWeek : '[gələn həftə] dddd [saat] LT',\n        lastDay : '[dünən] LT',\n        lastWeek : '[keçən həftə] dddd [saat] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : '%s sonra',\n        past : '%s əvvəl',\n        s : 'birneçə saniyyə',\n        m : 'bir dəqiqə',\n        mm : '%d dəqiqə',\n        h : 'bir saat',\n        hh : '%d saat',\n        d : 'bir gün',\n        dd : '%d gün',\n        M : 'bir ay',\n        MM : '%d ay',\n        y : 'bir il',\n        yy : '%d il'\n    },\n    meridiemParse: /gecə|səhər|gündüz|axşam/,\n    isPM : function (input) {\n        return /^(gündüz|axşam)$/.test(input);\n    },\n    meridiem : function (hour, minute, isLower) {\n        if (hour < 4) {\n            return 'gecə';\n        } else if (hour < 12) {\n            return 'səhər';\n        } else if (hour < 17) {\n            return 'gündüz';\n        } else {\n            return 'axşam';\n        }\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}-(ıncı|inci|nci|üncü|ncı|uncu)/,\n    ordinal : function (number) {\n        if (number === 0) {  // special case for zero\n            return number + '-ıncı';\n        }\n        var a = number % 10,\n            b = number % 100 - a,\n            c = number >= 100 ? 100 : null;\n        return number + (suffixes[a] || suffixes[b] || suffixes[c]);\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 7  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\nreturn az;\n\n})));\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/locale/be.js",
    "content": "//! moment.js locale configuration\n//! locale : Belarusian [be]\n//! author : Dmitry Demidov : https://github.com/demidov91\n//! author: Praleska: http://praleska.pro/\n//! Author : Menelion Elensúle : https://github.com/Oire\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\n\nfunction plural(word, num) {\n    var forms = word.split('_');\n    return num % 10 === 1 && num % 100 !== 11 ? forms[0] : (num % 10 >= 2 && num % 10 <= 4 && (num % 100 < 10 || num % 100 >= 20) ? forms[1] : forms[2]);\n}\nfunction relativeTimeWithPlural(number, withoutSuffix, key) {\n    var format = {\n        'mm': withoutSuffix ? 'хвіліна_хвіліны_хвілін' : 'хвіліну_хвіліны_хвілін',\n        'hh': withoutSuffix ? 'гадзіна_гадзіны_гадзін' : 'гадзіну_гадзіны_гадзін',\n        'dd': 'дзень_дні_дзён',\n        'MM': 'месяц_месяцы_месяцаў',\n        'yy': 'год_гады_гадоў'\n    };\n    if (key === 'm') {\n        return withoutSuffix ? 'хвіліна' : 'хвіліну';\n    }\n    else if (key === 'h') {\n        return withoutSuffix ? 'гадзіна' : 'гадзіну';\n    }\n    else {\n        return number + ' ' + plural(format[key], +number);\n    }\n}\n\nvar be = moment.defineLocale('be', {\n    months : {\n        format: 'студзеня_лютага_сакавіка_красавіка_траўня_чэрвеня_ліпеня_жніўня_верасня_кастрычніка_лістапада_снежня'.split('_'),\n        standalone: 'студзень_люты_сакавік_красавік_травень_чэрвень_ліпень_жнівень_верасень_кастрычнік_лістапад_снежань'.split('_')\n    },\n    monthsShort : 'студ_лют_сак_крас_трав_чэрв_ліп_жнів_вер_каст_ліст_снеж'.split('_'),\n    weekdays : {\n        format: 'нядзелю_панядзелак_аўторак_сераду_чацвер_пятніцу_суботу'.split('_'),\n        standalone: 'нядзеля_панядзелак_аўторак_серада_чацвер_пятніца_субота'.split('_'),\n        isFormat: /\\[ ?[Вв] ?(?:мінулую|наступную)? ?\\] ?dddd/\n    },\n    weekdaysShort : 'нд_пн_ат_ср_чц_пт_сб'.split('_'),\n    weekdaysMin : 'нд_пн_ат_ср_чц_пт_сб'.split('_'),\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD.MM.YYYY',\n        LL : 'D MMMM YYYY г.',\n        LLL : 'D MMMM YYYY г., HH:mm',\n        LLLL : 'dddd, D MMMM YYYY г., HH:mm'\n    },\n    calendar : {\n        sameDay: '[Сёння ў] LT',\n        nextDay: '[Заўтра ў] LT',\n        lastDay: '[Учора ў] LT',\n        nextWeek: function () {\n            return '[У] dddd [ў] LT';\n        },\n        lastWeek: function () {\n            switch (this.day()) {\n                case 0:\n                case 3:\n                case 5:\n                case 6:\n                    return '[У мінулую] dddd [ў] LT';\n                case 1:\n                case 2:\n                case 4:\n                    return '[У мінулы] dddd [ў] LT';\n            }\n        },\n        sameElse: 'L'\n    },\n    relativeTime : {\n        future : 'праз %s',\n        past : '%s таму',\n        s : 'некалькі секунд',\n        m : relativeTimeWithPlural,\n        mm : relativeTimeWithPlural,\n        h : relativeTimeWithPlural,\n        hh : relativeTimeWithPlural,\n        d : 'дзень',\n        dd : relativeTimeWithPlural,\n        M : 'месяц',\n        MM : relativeTimeWithPlural,\n        y : 'год',\n        yy : relativeTimeWithPlural\n    },\n    meridiemParse: /ночы|раніцы|дня|вечара/,\n    isPM : function (input) {\n        return /^(дня|вечара)$/.test(input);\n    },\n    meridiem : function (hour, minute, isLower) {\n        if (hour < 4) {\n            return 'ночы';\n        } else if (hour < 12) {\n            return 'раніцы';\n        } else if (hour < 17) {\n            return 'дня';\n        } else {\n            return 'вечара';\n        }\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}-(і|ы|га)/,\n    ordinal: function (number, period) {\n        switch (period) {\n            case 'M':\n            case 'd':\n            case 'DDD':\n            case 'w':\n            case 'W':\n                return (number % 10 === 2 || number % 10 === 3) && (number % 100 !== 12 && number % 100 !== 13) ? number + '-і' : number + '-ы';\n            case 'D':\n                return number + '-га';\n            default:\n                return number;\n        }\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 7  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\nreturn be;\n\n})));\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/locale/bg.js",
    "content": "//! moment.js locale configuration\n//! locale : Bulgarian [bg]\n//! author : Krasen Borisov : https://github.com/kraz\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\n\nvar bg = moment.defineLocale('bg', {\n    months : 'януари_февруари_март_април_май_юни_юли_август_септември_октомври_ноември_декември'.split('_'),\n    monthsShort : 'янр_фев_мар_апр_май_юни_юли_авг_сеп_окт_ное_дек'.split('_'),\n    weekdays : 'неделя_понеделник_вторник_сряда_четвъртък_петък_събота'.split('_'),\n    weekdaysShort : 'нед_пон_вто_сря_чет_пет_съб'.split('_'),\n    weekdaysMin : 'нд_пн_вт_ср_чт_пт_сб'.split('_'),\n    longDateFormat : {\n        LT : 'H:mm',\n        LTS : 'H:mm:ss',\n        L : 'D.MM.YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY H:mm',\n        LLLL : 'dddd, D MMMM YYYY H:mm'\n    },\n    calendar : {\n        sameDay : '[Днес в] LT',\n        nextDay : '[Утре в] LT',\n        nextWeek : 'dddd [в] LT',\n        lastDay : '[Вчера в] LT',\n        lastWeek : function () {\n            switch (this.day()) {\n                case 0:\n                case 3:\n                case 6:\n                    return '[В изминалата] dddd [в] LT';\n                case 1:\n                case 2:\n                case 4:\n                case 5:\n                    return '[В изминалия] dddd [в] LT';\n            }\n        },\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'след %s',\n        past : 'преди %s',\n        s : 'няколко секунди',\n        m : 'минута',\n        mm : '%d минути',\n        h : 'час',\n        hh : '%d часа',\n        d : 'ден',\n        dd : '%d дни',\n        M : 'месец',\n        MM : '%d месеца',\n        y : 'година',\n        yy : '%d години'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}-(ев|ен|ти|ви|ри|ми)/,\n    ordinal : function (number) {\n        var lastDigit = number % 10,\n            last2Digits = number % 100;\n        if (number === 0) {\n            return number + '-ев';\n        } else if (last2Digits === 0) {\n            return number + '-ен';\n        } else if (last2Digits > 10 && last2Digits < 20) {\n            return number + '-ти';\n        } else if (lastDigit === 1) {\n            return number + '-ви';\n        } else if (lastDigit === 2) {\n            return number + '-ри';\n        } else if (lastDigit === 7 || lastDigit === 8) {\n            return number + '-ми';\n        } else {\n            return number + '-ти';\n        }\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 7  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\nreturn bg;\n\n})));\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/locale/bn.js",
    "content": "//! moment.js locale configuration\n//! locale : Bengali [bn]\n//! author : Kaushik Gandhi : https://github.com/kaushikgandhi\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\n\nvar symbolMap = {\n    '1': '১',\n    '2': '২',\n    '3': '৩',\n    '4': '৪',\n    '5': '৫',\n    '6': '৬',\n    '7': '৭',\n    '8': '৮',\n    '9': '৯',\n    '0': '০'\n};\nvar numberMap = {\n    '১': '1',\n    '২': '2',\n    '৩': '3',\n    '৪': '4',\n    '৫': '5',\n    '৬': '6',\n    '৭': '7',\n    '৮': '8',\n    '৯': '9',\n    '০': '0'\n};\n\nvar bn = moment.defineLocale('bn', {\n    months : 'জানুয়ারী_ফেব্রুয়ারি_মার্চ_এপ্রিল_মে_জুন_জুলাই_আগস্ট_সেপ্টেম্বর_অক্টোবর_নভেম্বর_ডিসেম্বর'.split('_'),\n    monthsShort : 'জানু_ফেব_মার্চ_এপ্র_মে_জুন_জুল_আগ_সেপ্ট_অক্টো_নভে_ডিসে'.split('_'),\n    weekdays : 'রবিবার_সোমবার_মঙ্গলবার_বুধবার_বৃহস্পতিবার_শুক্রবার_শনিবার'.split('_'),\n    weekdaysShort : 'রবি_সোম_মঙ্গল_বুধ_বৃহস্পতি_শুক্র_শনি'.split('_'),\n    weekdaysMin : 'রবি_সোম_মঙ্গ_বুধ_বৃহঃ_শুক্র_শনি'.split('_'),\n    longDateFormat : {\n        LT : 'A h:mm সময়',\n        LTS : 'A h:mm:ss সময়',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY, A h:mm সময়',\n        LLLL : 'dddd, D MMMM YYYY, A h:mm সময়'\n    },\n    calendar : {\n        sameDay : '[আজ] LT',\n        nextDay : '[আগামীকাল] LT',\n        nextWeek : 'dddd, LT',\n        lastDay : '[গতকাল] LT',\n        lastWeek : '[গত] dddd, LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : '%s পরে',\n        past : '%s আগে',\n        s : 'কয়েক সেকেন্ড',\n        m : 'এক মিনিট',\n        mm : '%d মিনিট',\n        h : 'এক ঘন্টা',\n        hh : '%d ঘন্টা',\n        d : 'এক দিন',\n        dd : '%d দিন',\n        M : 'এক মাস',\n        MM : '%d মাস',\n        y : 'এক বছর',\n        yy : '%d বছর'\n    },\n    preparse: function (string) {\n        return string.replace(/[১২৩৪৫৬৭৮৯০]/g, function (match) {\n            return numberMap[match];\n        });\n    },\n    postformat: function (string) {\n        return string.replace(/\\d/g, function (match) {\n            return symbolMap[match];\n        });\n    },\n    meridiemParse: /রাত|সকাল|দুপুর|বিকাল|রাত/,\n    meridiemHour : function (hour, meridiem) {\n        if (hour === 12) {\n            hour = 0;\n        }\n        if ((meridiem === 'রাত' && hour >= 4) ||\n                (meridiem === 'দুপুর' && hour < 5) ||\n                meridiem === 'বিকাল') {\n            return hour + 12;\n        } else {\n            return hour;\n        }\n    },\n    meridiem : function (hour, minute, isLower) {\n        if (hour < 4) {\n            return 'রাত';\n        } else if (hour < 10) {\n            return 'সকাল';\n        } else if (hour < 17) {\n            return 'দুপুর';\n        } else if (hour < 20) {\n            return 'বিকাল';\n        } else {\n            return 'রাত';\n        }\n    },\n    week : {\n        dow : 0, // Sunday is the first day of the week.\n        doy : 6  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\nreturn bn;\n\n})));\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/locale/bo.js",
    "content": "//! moment.js locale configuration\n//! locale : Tibetan [bo]\n//! author : Thupten N. Chakrishar : https://github.com/vajradog\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\n\nvar symbolMap = {\n    '1': '༡',\n    '2': '༢',\n    '3': '༣',\n    '4': '༤',\n    '5': '༥',\n    '6': '༦',\n    '7': '༧',\n    '8': '༨',\n    '9': '༩',\n    '0': '༠'\n};\nvar numberMap = {\n    '༡': '1',\n    '༢': '2',\n    '༣': '3',\n    '༤': '4',\n    '༥': '5',\n    '༦': '6',\n    '༧': '7',\n    '༨': '8',\n    '༩': '9',\n    '༠': '0'\n};\n\nvar bo = moment.defineLocale('bo', {\n    months : 'ཟླ་བ་དང་པོ_ཟླ་བ་གཉིས་པ_ཟླ་བ་གསུམ་པ_ཟླ་བ་བཞི་པ_ཟླ་བ་ལྔ་པ_ཟླ་བ་དྲུག་པ_ཟླ་བ་བདུན་པ_ཟླ་བ་བརྒྱད་པ_ཟླ་བ་དགུ་པ_ཟླ་བ་བཅུ་པ_ཟླ་བ་བཅུ་གཅིག་པ_ཟླ་བ་བཅུ་གཉིས་པ'.split('_'),\n    monthsShort : 'ཟླ་བ་དང་པོ_ཟླ་བ་གཉིས་པ_ཟླ་བ་གསུམ་པ_ཟླ་བ་བཞི་པ_ཟླ་བ་ལྔ་པ_ཟླ་བ་དྲུག་པ_ཟླ་བ་བདུན་པ_ཟླ་བ་བརྒྱད་པ_ཟླ་བ་དགུ་པ_ཟླ་བ་བཅུ་པ_ཟླ་བ་བཅུ་གཅིག་པ_ཟླ་བ་བཅུ་གཉིས་པ'.split('_'),\n    weekdays : 'གཟའ་ཉི་མ་_གཟའ་ཟླ་བ་_གཟའ་མིག་དམར་_གཟའ་ལྷག་པ་_གཟའ་ཕུར་བུ_གཟའ་པ་སངས་_གཟའ་སྤེན་པ་'.split('_'),\n    weekdaysShort : 'ཉི་མ་_ཟླ་བ་_མིག་དམར་_ལྷག་པ་_ཕུར་བུ_པ་སངས་_སྤེན་པ་'.split('_'),\n    weekdaysMin : 'ཉི་མ་_ཟླ་བ་_མིག་དམར་_ལྷག་པ་_ཕུར་བུ_པ་སངས་_སྤེན་པ་'.split('_'),\n    longDateFormat : {\n        LT : 'A h:mm',\n        LTS : 'A h:mm:ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY, A h:mm',\n        LLLL : 'dddd, D MMMM YYYY, A h:mm'\n    },\n    calendar : {\n        sameDay : '[དི་རིང] LT',\n        nextDay : '[སང་ཉིན] LT',\n        nextWeek : '[བདུན་ཕྲག་རྗེས་མ], LT',\n        lastDay : '[ཁ་སང] LT',\n        lastWeek : '[བདུན་ཕྲག་མཐའ་མ] dddd, LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : '%s ལ་',\n        past : '%s སྔན་ལ',\n        s : 'ལམ་སང',\n        m : 'སྐར་མ་གཅིག',\n        mm : '%d སྐར་མ',\n        h : 'ཆུ་ཚོད་གཅིག',\n        hh : '%d ཆུ་ཚོད',\n        d : 'ཉིན་གཅིག',\n        dd : '%d ཉིན་',\n        M : 'ཟླ་བ་གཅིག',\n        MM : '%d ཟླ་བ',\n        y : 'ལོ་གཅིག',\n        yy : '%d ལོ'\n    },\n    preparse: function (string) {\n        return string.replace(/[༡༢༣༤༥༦༧༨༩༠]/g, function (match) {\n            return numberMap[match];\n        });\n    },\n    postformat: function (string) {\n        return string.replace(/\\d/g, function (match) {\n            return symbolMap[match];\n        });\n    },\n    meridiemParse: /མཚན་མོ|ཞོགས་ཀས|ཉིན་གུང|དགོང་དག|མཚན་མོ/,\n    meridiemHour : function (hour, meridiem) {\n        if (hour === 12) {\n            hour = 0;\n        }\n        if ((meridiem === 'མཚན་མོ' && hour >= 4) ||\n                (meridiem === 'ཉིན་གུང' && hour < 5) ||\n                meridiem === 'དགོང་དག') {\n            return hour + 12;\n        } else {\n            return hour;\n        }\n    },\n    meridiem : function (hour, minute, isLower) {\n        if (hour < 4) {\n            return 'མཚན་མོ';\n        } else if (hour < 10) {\n            return 'ཞོགས་ཀས';\n        } else if (hour < 17) {\n            return 'ཉིན་གུང';\n        } else if (hour < 20) {\n            return 'དགོང་དག';\n        } else {\n            return 'མཚན་མོ';\n        }\n    },\n    week : {\n        dow : 0, // Sunday is the first day of the week.\n        doy : 6  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\nreturn bo;\n\n})));\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/locale/br.js",
    "content": "//! moment.js locale configuration\n//! locale : Breton [br]\n//! author : Jean-Baptiste Le Duigou : https://github.com/jbleduigou\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\n\nfunction relativeTimeWithMutation(number, withoutSuffix, key) {\n    var format = {\n        'mm': 'munutenn',\n        'MM': 'miz',\n        'dd': 'devezh'\n    };\n    return number + ' ' + mutation(format[key], number);\n}\nfunction specialMutationForYears(number) {\n    switch (lastNumber(number)) {\n        case 1:\n        case 3:\n        case 4:\n        case 5:\n        case 9:\n            return number + ' bloaz';\n        default:\n            return number + ' vloaz';\n    }\n}\nfunction lastNumber(number) {\n    if (number > 9) {\n        return lastNumber(number % 10);\n    }\n    return number;\n}\nfunction mutation(text, number) {\n    if (number === 2) {\n        return softMutation(text);\n    }\n    return text;\n}\nfunction softMutation(text) {\n    var mutationTable = {\n        'm': 'v',\n        'b': 'v',\n        'd': 'z'\n    };\n    if (mutationTable[text.charAt(0)] === undefined) {\n        return text;\n    }\n    return mutationTable[text.charAt(0)] + text.substring(1);\n}\n\nvar br = moment.defineLocale('br', {\n    months : 'Genver_C\\'hwevrer_Meurzh_Ebrel_Mae_Mezheven_Gouere_Eost_Gwengolo_Here_Du_Kerzu'.split('_'),\n    monthsShort : 'Gen_C\\'hwe_Meu_Ebr_Mae_Eve_Gou_Eos_Gwe_Her_Du_Ker'.split('_'),\n    weekdays : 'Sul_Lun_Meurzh_Merc\\'her_Yaou_Gwener_Sadorn'.split('_'),\n    weekdaysShort : 'Sul_Lun_Meu_Mer_Yao_Gwe_Sad'.split('_'),\n    weekdaysMin : 'Su_Lu_Me_Mer_Ya_Gw_Sa'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat : {\n        LT : 'h[e]mm A',\n        LTS : 'h[e]mm:ss A',\n        L : 'DD/MM/YYYY',\n        LL : 'D [a viz] MMMM YYYY',\n        LLL : 'D [a viz] MMMM YYYY h[e]mm A',\n        LLLL : 'dddd, D [a viz] MMMM YYYY h[e]mm A'\n    },\n    calendar : {\n        sameDay : '[Hiziv da] LT',\n        nextDay : '[Warc\\'hoazh da] LT',\n        nextWeek : 'dddd [da] LT',\n        lastDay : '[Dec\\'h da] LT',\n        lastWeek : 'dddd [paset da] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'a-benn %s',\n        past : '%s \\'zo',\n        s : 'un nebeud segondennoù',\n        m : 'ur vunutenn',\n        mm : relativeTimeWithMutation,\n        h : 'un eur',\n        hh : '%d eur',\n        d : 'un devezh',\n        dd : relativeTimeWithMutation,\n        M : 'ur miz',\n        MM : relativeTimeWithMutation,\n        y : 'ur bloaz',\n        yy : specialMutationForYears\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}(añ|vet)/,\n    ordinal : function (number) {\n        var output = (number === 1) ? 'añ' : 'vet';\n        return number + output;\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\nreturn br;\n\n})));\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/locale/bs.js",
    "content": "//! moment.js locale configuration\n//! locale : Bosnian [bs]\n//! author : Nedim Cholich : https://github.com/frontyard\n//! based on (hr) translation by Bojan Marković\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\n\nfunction translate(number, withoutSuffix, key) {\n    var result = number + ' ';\n    switch (key) {\n        case 'm':\n            return withoutSuffix ? 'jedna minuta' : 'jedne minute';\n        case 'mm':\n            if (number === 1) {\n                result += 'minuta';\n            } else if (number === 2 || number === 3 || number === 4) {\n                result += 'minute';\n            } else {\n                result += 'minuta';\n            }\n            return result;\n        case 'h':\n            return withoutSuffix ? 'jedan sat' : 'jednog sata';\n        case 'hh':\n            if (number === 1) {\n                result += 'sat';\n            } else if (number === 2 || number === 3 || number === 4) {\n                result += 'sata';\n            } else {\n                result += 'sati';\n            }\n            return result;\n        case 'dd':\n            if (number === 1) {\n                result += 'dan';\n            } else {\n                result += 'dana';\n            }\n            return result;\n        case 'MM':\n            if (number === 1) {\n                result += 'mjesec';\n            } else if (number === 2 || number === 3 || number === 4) {\n                result += 'mjeseca';\n            } else {\n                result += 'mjeseci';\n            }\n            return result;\n        case 'yy':\n            if (number === 1) {\n                result += 'godina';\n            } else if (number === 2 || number === 3 || number === 4) {\n                result += 'godine';\n            } else {\n                result += 'godina';\n            }\n            return result;\n    }\n}\n\nvar bs = moment.defineLocale('bs', {\n    months : 'januar_februar_mart_april_maj_juni_juli_august_septembar_oktobar_novembar_decembar'.split('_'),\n    monthsShort : 'jan._feb._mar._apr._maj._jun._jul._aug._sep._okt._nov._dec.'.split('_'),\n    monthsParseExact: true,\n    weekdays : 'nedjelja_ponedjeljak_utorak_srijeda_četvrtak_petak_subota'.split('_'),\n    weekdaysShort : 'ned._pon._uto._sri._čet._pet._sub.'.split('_'),\n    weekdaysMin : 'ne_po_ut_sr_če_pe_su'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat : {\n        LT : 'H:mm',\n        LTS : 'H:mm:ss',\n        L : 'DD.MM.YYYY',\n        LL : 'D. MMMM YYYY',\n        LLL : 'D. MMMM YYYY H:mm',\n        LLLL : 'dddd, D. MMMM YYYY H:mm'\n    },\n    calendar : {\n        sameDay  : '[danas u] LT',\n        nextDay  : '[sutra u] LT',\n        nextWeek : function () {\n            switch (this.day()) {\n                case 0:\n                    return '[u] [nedjelju] [u] LT';\n                case 3:\n                    return '[u] [srijedu] [u] LT';\n                case 6:\n                    return '[u] [subotu] [u] LT';\n                case 1:\n                case 2:\n                case 4:\n                case 5:\n                    return '[u] dddd [u] LT';\n            }\n        },\n        lastDay  : '[jučer u] LT',\n        lastWeek : function () {\n            switch (this.day()) {\n                case 0:\n                case 3:\n                    return '[prošlu] dddd [u] LT';\n                case 6:\n                    return '[prošle] [subote] [u] LT';\n                case 1:\n                case 2:\n                case 4:\n                case 5:\n                    return '[prošli] dddd [u] LT';\n            }\n        },\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'za %s',\n        past   : 'prije %s',\n        s      : 'par sekundi',\n        m      : translate,\n        mm     : translate,\n        h      : translate,\n        hh     : translate,\n        d      : 'dan',\n        dd     : translate,\n        M      : 'mjesec',\n        MM     : translate,\n        y      : 'godinu',\n        yy     : translate\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}\\./,\n    ordinal : '%d.',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 7  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\nreturn bs;\n\n})));\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/locale/ca.js",
    "content": "//! moment.js locale configuration\n//! locale : Catalan [ca]\n//! author : Juan G. Hurtado : https://github.com/juanghurtado\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\n\nvar ca = moment.defineLocale('ca', {\n    months : {\n        standalone: 'gener_febrer_març_abril_maig_juny_juliol_agost_setembre_octubre_novembre_desembre'.split('_'),\n        format: 'de gener_de febrer_de març_d\\'abril_de maig_de juny_de juliol_d\\'agost_de setembre_d\\'octubre_de novembre_de desembre'.split('_'),\n        isFormat: /D[oD]?(\\s)+MMMM/\n    },\n    monthsShort : 'gen._febr._març_abr._maig_juny_jul._ag._set._oct._nov._des.'.split('_'),\n    monthsParseExact : true,\n    weekdays : 'diumenge_dilluns_dimarts_dimecres_dijous_divendres_dissabte'.split('_'),\n    weekdaysShort : 'dg._dl._dt._dc._dj._dv._ds.'.split('_'),\n    weekdaysMin : 'Dg_Dl_Dt_Dc_Dj_Dv_Ds'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat : {\n        LT : 'H:mm',\n        LTS : 'H:mm:ss',\n        L : 'DD/MM/YYYY',\n        LL : '[el] D MMMM [de] YYYY',\n        ll : 'D MMM YYYY',\n        LLL : '[el] D MMMM [de] YYYY [a les] H:mm',\n        lll : 'D MMM YYYY, H:mm',\n        LLLL : '[el] dddd D MMMM [de] YYYY [a les] H:mm',\n        llll : 'ddd D MMM YYYY, H:mm'\n    },\n    calendar : {\n        sameDay : function () {\n            return '[avui a ' + ((this.hours() !== 1) ? 'les' : 'la') + '] LT';\n        },\n        nextDay : function () {\n            return '[demà a ' + ((this.hours() !== 1) ? 'les' : 'la') + '] LT';\n        },\n        nextWeek : function () {\n            return 'dddd [a ' + ((this.hours() !== 1) ? 'les' : 'la') + '] LT';\n        },\n        lastDay : function () {\n            return '[ahir a ' + ((this.hours() !== 1) ? 'les' : 'la') + '] LT';\n        },\n        lastWeek : function () {\n            return '[el] dddd [passat a ' + ((this.hours() !== 1) ? 'les' : 'la') + '] LT';\n        },\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'd\\'aquí %s',\n        past : 'fa %s',\n        s : 'uns segons',\n        m : 'un minut',\n        mm : '%d minuts',\n        h : 'una hora',\n        hh : '%d hores',\n        d : 'un dia',\n        dd : '%d dies',\n        M : 'un mes',\n        MM : '%d mesos',\n        y : 'un any',\n        yy : '%d anys'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}(r|n|t|è|a)/,\n    ordinal : function (number, period) {\n        var output = (number === 1) ? 'r' :\n            (number === 2) ? 'n' :\n            (number === 3) ? 'r' :\n            (number === 4) ? 't' : 'è';\n        if (period === 'w' || period === 'W') {\n            output = 'a';\n        }\n        return number + output;\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\nreturn ca;\n\n})));\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/locale/cs.js",
    "content": "//! moment.js locale configuration\n//! locale : Czech [cs]\n//! author : petrbela : https://github.com/petrbela\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\n\nvar months = 'leden_únor_březen_duben_květen_červen_červenec_srpen_září_říjen_listopad_prosinec'.split('_');\nvar monthsShort = 'led_úno_bře_dub_kvě_čvn_čvc_srp_zář_říj_lis_pro'.split('_');\nfunction plural(n) {\n    return (n > 1) && (n < 5) && (~~(n / 10) !== 1);\n}\nfunction translate(number, withoutSuffix, key, isFuture) {\n    var result = number + ' ';\n    switch (key) {\n        case 's':  // a few seconds / in a few seconds / a few seconds ago\n            return (withoutSuffix || isFuture) ? 'pár sekund' : 'pár sekundami';\n        case 'm':  // a minute / in a minute / a minute ago\n            return withoutSuffix ? 'minuta' : (isFuture ? 'minutu' : 'minutou');\n        case 'mm': // 9 minutes / in 9 minutes / 9 minutes ago\n            if (withoutSuffix || isFuture) {\n                return result + (plural(number) ? 'minuty' : 'minut');\n            } else {\n                return result + 'minutami';\n            }\n            break;\n        case 'h':  // an hour / in an hour / an hour ago\n            return withoutSuffix ? 'hodina' : (isFuture ? 'hodinu' : 'hodinou');\n        case 'hh': // 9 hours / in 9 hours / 9 hours ago\n            if (withoutSuffix || isFuture) {\n                return result + (plural(number) ? 'hodiny' : 'hodin');\n            } else {\n                return result + 'hodinami';\n            }\n            break;\n        case 'd':  // a day / in a day / a day ago\n            return (withoutSuffix || isFuture) ? 'den' : 'dnem';\n        case 'dd': // 9 days / in 9 days / 9 days ago\n            if (withoutSuffix || isFuture) {\n                return result + (plural(number) ? 'dny' : 'dní');\n            } else {\n                return result + 'dny';\n            }\n            break;\n        case 'M':  // a month / in a month / a month ago\n            return (withoutSuffix || isFuture) ? 'měsíc' : 'měsícem';\n        case 'MM': // 9 months / in 9 months / 9 months ago\n            if (withoutSuffix || isFuture) {\n                return result + (plural(number) ? 'měsíce' : 'měsíců');\n            } else {\n                return result + 'měsíci';\n            }\n            break;\n        case 'y':  // a year / in a year / a year ago\n            return (withoutSuffix || isFuture) ? 'rok' : 'rokem';\n        case 'yy': // 9 years / in 9 years / 9 years ago\n            if (withoutSuffix || isFuture) {\n                return result + (plural(number) ? 'roky' : 'let');\n            } else {\n                return result + 'lety';\n            }\n            break;\n    }\n}\n\nvar cs = moment.defineLocale('cs', {\n    months : months,\n    monthsShort : monthsShort,\n    monthsParse : (function (months, monthsShort) {\n        var i, _monthsParse = [];\n        for (i = 0; i < 12; i++) {\n            // use custom parser to solve problem with July (červenec)\n            _monthsParse[i] = new RegExp('^' + months[i] + '$|^' + monthsShort[i] + '$', 'i');\n        }\n        return _monthsParse;\n    }(months, monthsShort)),\n    shortMonthsParse : (function (monthsShort) {\n        var i, _shortMonthsParse = [];\n        for (i = 0; i < 12; i++) {\n            _shortMonthsParse[i] = new RegExp('^' + monthsShort[i] + '$', 'i');\n        }\n        return _shortMonthsParse;\n    }(monthsShort)),\n    longMonthsParse : (function (months) {\n        var i, _longMonthsParse = [];\n        for (i = 0; i < 12; i++) {\n            _longMonthsParse[i] = new RegExp('^' + months[i] + '$', 'i');\n        }\n        return _longMonthsParse;\n    }(months)),\n    weekdays : 'neděle_pondělí_úterý_středa_čtvrtek_pátek_sobota'.split('_'),\n    weekdaysShort : 'ne_po_út_st_čt_pá_so'.split('_'),\n    weekdaysMin : 'ne_po_út_st_čt_pá_so'.split('_'),\n    longDateFormat : {\n        LT: 'H:mm',\n        LTS : 'H:mm:ss',\n        L : 'DD.MM.YYYY',\n        LL : 'D. MMMM YYYY',\n        LLL : 'D. MMMM YYYY H:mm',\n        LLLL : 'dddd D. MMMM YYYY H:mm',\n        l : 'D. M. YYYY'\n    },\n    calendar : {\n        sameDay: '[dnes v] LT',\n        nextDay: '[zítra v] LT',\n        nextWeek: function () {\n            switch (this.day()) {\n                case 0:\n                    return '[v neděli v] LT';\n                case 1:\n                case 2:\n                    return '[v] dddd [v] LT';\n                case 3:\n                    return '[ve středu v] LT';\n                case 4:\n                    return '[ve čtvrtek v] LT';\n                case 5:\n                    return '[v pátek v] LT';\n                case 6:\n                    return '[v sobotu v] LT';\n            }\n        },\n        lastDay: '[včera v] LT',\n        lastWeek: function () {\n            switch (this.day()) {\n                case 0:\n                    return '[minulou neděli v] LT';\n                case 1:\n                case 2:\n                    return '[minulé] dddd [v] LT';\n                case 3:\n                    return '[minulou středu v] LT';\n                case 4:\n                case 5:\n                    return '[minulý] dddd [v] LT';\n                case 6:\n                    return '[minulou sobotu v] LT';\n            }\n        },\n        sameElse: 'L'\n    },\n    relativeTime : {\n        future : 'za %s',\n        past : 'před %s',\n        s : translate,\n        m : translate,\n        mm : translate,\n        h : translate,\n        hh : translate,\n        d : translate,\n        dd : translate,\n        M : translate,\n        MM : translate,\n        y : translate,\n        yy : translate\n    },\n    dayOfMonthOrdinalParse : /\\d{1,2}\\./,\n    ordinal : '%d.',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\nreturn cs;\n\n})));\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/locale/cv.js",
    "content": "//! moment.js locale configuration\n//! locale : Chuvash [cv]\n//! author : Anatoly Mironov : https://github.com/mirontoli\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\n\nvar cv = moment.defineLocale('cv', {\n    months : 'кӑрлач_нарӑс_пуш_ака_май_ҫӗртме_утӑ_ҫурла_авӑн_юпа_чӳк_раштав'.split('_'),\n    monthsShort : 'кӑр_нар_пуш_ака_май_ҫӗр_утӑ_ҫур_авн_юпа_чӳк_раш'.split('_'),\n    weekdays : 'вырсарникун_тунтикун_ытларикун_юнкун_кӗҫнерникун_эрнекун_шӑматкун'.split('_'),\n    weekdaysShort : 'выр_тун_ытл_юн_кӗҫ_эрн_шӑм'.split('_'),\n    weekdaysMin : 'вр_тн_ыт_юн_кҫ_эр_шм'.split('_'),\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD-MM-YYYY',\n        LL : 'YYYY [ҫулхи] MMMM [уйӑхӗн] D[-мӗшӗ]',\n        LLL : 'YYYY [ҫулхи] MMMM [уйӑхӗн] D[-мӗшӗ], HH:mm',\n        LLLL : 'dddd, YYYY [ҫулхи] MMMM [уйӑхӗн] D[-мӗшӗ], HH:mm'\n    },\n    calendar : {\n        sameDay: '[Паян] LT [сехетре]',\n        nextDay: '[Ыран] LT [сехетре]',\n        lastDay: '[Ӗнер] LT [сехетре]',\n        nextWeek: '[Ҫитес] dddd LT [сехетре]',\n        lastWeek: '[Иртнӗ] dddd LT [сехетре]',\n        sameElse: 'L'\n    },\n    relativeTime : {\n        future : function (output) {\n            var affix = /сехет$/i.exec(output) ? 'рен' : /ҫул$/i.exec(output) ? 'тан' : 'ран';\n            return output + affix;\n        },\n        past : '%s каялла',\n        s : 'пӗр-ик ҫеккунт',\n        m : 'пӗр минут',\n        mm : '%d минут',\n        h : 'пӗр сехет',\n        hh : '%d сехет',\n        d : 'пӗр кун',\n        dd : '%d кун',\n        M : 'пӗр уйӑх',\n        MM : '%d уйӑх',\n        y : 'пӗр ҫул',\n        yy : '%d ҫул'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}-мӗш/,\n    ordinal : '%d-мӗш',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 7  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\nreturn cv;\n\n})));\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/locale/cy.js",
    "content": "//! moment.js locale configuration\n//! locale : Welsh [cy]\n//! author : Robert Allen : https://github.com/robgallen\n//! author : https://github.com/ryangreaves\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\n\nvar cy = moment.defineLocale('cy', {\n    months: 'Ionawr_Chwefror_Mawrth_Ebrill_Mai_Mehefin_Gorffennaf_Awst_Medi_Hydref_Tachwedd_Rhagfyr'.split('_'),\n    monthsShort: 'Ion_Chwe_Maw_Ebr_Mai_Meh_Gor_Aws_Med_Hyd_Tach_Rhag'.split('_'),\n    weekdays: 'Dydd Sul_Dydd Llun_Dydd Mawrth_Dydd Mercher_Dydd Iau_Dydd Gwener_Dydd Sadwrn'.split('_'),\n    weekdaysShort: 'Sul_Llun_Maw_Mer_Iau_Gwe_Sad'.split('_'),\n    weekdaysMin: 'Su_Ll_Ma_Me_Ia_Gw_Sa'.split('_'),\n    weekdaysParseExact : true,\n    // time formats are the same as en-gb\n    longDateFormat: {\n        LT: 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L: 'DD/MM/YYYY',\n        LL: 'D MMMM YYYY',\n        LLL: 'D MMMM YYYY HH:mm',\n        LLLL: 'dddd, D MMMM YYYY HH:mm'\n    },\n    calendar: {\n        sameDay: '[Heddiw am] LT',\n        nextDay: '[Yfory am] LT',\n        nextWeek: 'dddd [am] LT',\n        lastDay: '[Ddoe am] LT',\n        lastWeek: 'dddd [diwethaf am] LT',\n        sameElse: 'L'\n    },\n    relativeTime: {\n        future: 'mewn %s',\n        past: '%s yn ôl',\n        s: 'ychydig eiliadau',\n        m: 'munud',\n        mm: '%d munud',\n        h: 'awr',\n        hh: '%d awr',\n        d: 'diwrnod',\n        dd: '%d diwrnod',\n        M: 'mis',\n        MM: '%d mis',\n        y: 'blwyddyn',\n        yy: '%d flynedd'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}(fed|ain|af|il|ydd|ed|eg)/,\n    // traditional ordinal numbers above 31 are not commonly used in colloquial Welsh\n    ordinal: function (number) {\n        var b = number,\n            output = '',\n            lookup = [\n                '', 'af', 'il', 'ydd', 'ydd', 'ed', 'ed', 'ed', 'fed', 'fed', 'fed', // 1af to 10fed\n                'eg', 'fed', 'eg', 'eg', 'fed', 'eg', 'eg', 'fed', 'eg', 'fed' // 11eg to 20fed\n            ];\n        if (b > 20) {\n            if (b === 40 || b === 50 || b === 60 || b === 80 || b === 100) {\n                output = 'fed'; // not 30ain, 70ain or 90ain\n            } else {\n                output = 'ain';\n            }\n        } else if (b > 0) {\n            output = lookup[b];\n        }\n        return number + output;\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\nreturn cy;\n\n})));\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/locale/da.js",
    "content": "//! moment.js locale configuration\n//! locale : Danish [da]\n//! author : Ulrik Nielsen : https://github.com/mrbase\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\n\nvar da = moment.defineLocale('da', {\n    months : 'januar_februar_marts_april_maj_juni_juli_august_september_oktober_november_december'.split('_'),\n    monthsShort : 'jan_feb_mar_apr_maj_jun_jul_aug_sep_okt_nov_dec'.split('_'),\n    weekdays : 'søndag_mandag_tirsdag_onsdag_torsdag_fredag_lørdag'.split('_'),\n    weekdaysShort : 'søn_man_tir_ons_tor_fre_lør'.split('_'),\n    weekdaysMin : 'sø_ma_ti_on_to_fr_lø'.split('_'),\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D. MMMM YYYY',\n        LLL : 'D. MMMM YYYY HH:mm',\n        LLLL : 'dddd [d.] D. MMMM YYYY [kl.] HH:mm'\n    },\n    calendar : {\n        sameDay : '[i dag kl.] LT',\n        nextDay : '[i morgen kl.] LT',\n        nextWeek : 'på dddd [kl.] LT',\n        lastDay : '[i går kl.] LT',\n        lastWeek : '[i] dddd[s kl.] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'om %s',\n        past : '%s siden',\n        s : 'få sekunder',\n        m : 'et minut',\n        mm : '%d minutter',\n        h : 'en time',\n        hh : '%d timer',\n        d : 'en dag',\n        dd : '%d dage',\n        M : 'en måned',\n        MM : '%d måneder',\n        y : 'et år',\n        yy : '%d år'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}\\./,\n    ordinal : '%d.',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\nreturn da;\n\n})));\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/locale/de-at.js",
    "content": "//! moment.js locale configuration\n//! locale : German (Austria) [de-at]\n//! author : lluchs : https://github.com/lluchs\n//! author: Menelion Elensúle: https://github.com/Oire\n//! author : Martin Groller : https://github.com/MadMG\n//! author : Mikolaj Dadela : https://github.com/mik01aj\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\n\nfunction processRelativeTime(number, withoutSuffix, key, isFuture) {\n    var format = {\n        'm': ['eine Minute', 'einer Minute'],\n        'h': ['eine Stunde', 'einer Stunde'],\n        'd': ['ein Tag', 'einem Tag'],\n        'dd': [number + ' Tage', number + ' Tagen'],\n        'M': ['ein Monat', 'einem Monat'],\n        'MM': [number + ' Monate', number + ' Monaten'],\n        'y': ['ein Jahr', 'einem Jahr'],\n        'yy': [number + ' Jahre', number + ' Jahren']\n    };\n    return withoutSuffix ? format[key][0] : format[key][1];\n}\n\nvar deAt = moment.defineLocale('de-at', {\n    months : 'Jänner_Februar_März_April_Mai_Juni_Juli_August_September_Oktober_November_Dezember'.split('_'),\n    monthsShort : 'Jän._Febr._Mrz._Apr._Mai_Jun._Jul._Aug._Sept._Okt._Nov._Dez.'.split('_'),\n    monthsParseExact : true,\n    weekdays : 'Sonntag_Montag_Dienstag_Mittwoch_Donnerstag_Freitag_Samstag'.split('_'),\n    weekdaysShort : 'So._Mo._Di._Mi._Do._Fr._Sa.'.split('_'),\n    weekdaysMin : 'So_Mo_Di_Mi_Do_Fr_Sa'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat : {\n        LT: 'HH:mm',\n        LTS: 'HH:mm:ss',\n        L : 'DD.MM.YYYY',\n        LL : 'D. MMMM YYYY',\n        LLL : 'D. MMMM YYYY HH:mm',\n        LLLL : 'dddd, D. MMMM YYYY HH:mm'\n    },\n    calendar : {\n        sameDay: '[heute um] LT [Uhr]',\n        sameElse: 'L',\n        nextDay: '[morgen um] LT [Uhr]',\n        nextWeek: 'dddd [um] LT [Uhr]',\n        lastDay: '[gestern um] LT [Uhr]',\n        lastWeek: '[letzten] dddd [um] LT [Uhr]'\n    },\n    relativeTime : {\n        future : 'in %s',\n        past : 'vor %s',\n        s : 'ein paar Sekunden',\n        m : processRelativeTime,\n        mm : '%d Minuten',\n        h : processRelativeTime,\n        hh : '%d Stunden',\n        d : processRelativeTime,\n        dd : processRelativeTime,\n        M : processRelativeTime,\n        MM : processRelativeTime,\n        y : processRelativeTime,\n        yy : processRelativeTime\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}\\./,\n    ordinal : '%d.',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\nreturn deAt;\n\n})));\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/locale/de-ch.js",
    "content": "//! moment.js locale configuration\n//! locale : German (Switzerland) [de-ch]\n//! author : sschueller : https://github.com/sschueller\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\n\n// based on: https://www.bk.admin.ch/dokumentation/sprachen/04915/05016/index.html?lang=de#\n\nfunction processRelativeTime(number, withoutSuffix, key, isFuture) {\n    var format = {\n        'm': ['eine Minute', 'einer Minute'],\n        'h': ['eine Stunde', 'einer Stunde'],\n        'd': ['ein Tag', 'einem Tag'],\n        'dd': [number + ' Tage', number + ' Tagen'],\n        'M': ['ein Monat', 'einem Monat'],\n        'MM': [number + ' Monate', number + ' Monaten'],\n        'y': ['ein Jahr', 'einem Jahr'],\n        'yy': [number + ' Jahre', number + ' Jahren']\n    };\n    return withoutSuffix ? format[key][0] : format[key][1];\n}\n\nvar deCh = moment.defineLocale('de-ch', {\n    months : 'Januar_Februar_März_April_Mai_Juni_Juli_August_September_Oktober_November_Dezember'.split('_'),\n    monthsShort : 'Jan._Febr._März_April_Mai_Juni_Juli_Aug._Sept._Okt._Nov._Dez.'.split('_'),\n    monthsParseExact : true,\n    weekdays : 'Sonntag_Montag_Dienstag_Mittwoch_Donnerstag_Freitag_Samstag'.split('_'),\n    weekdaysShort : 'So_Mo_Di_Mi_Do_Fr_Sa'.split('_'),\n    weekdaysMin : 'So_Mo_Di_Mi_Do_Fr_Sa'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat : {\n        LT: 'HH.mm',\n        LTS: 'HH.mm.ss',\n        L : 'DD.MM.YYYY',\n        LL : 'D. MMMM YYYY',\n        LLL : 'D. MMMM YYYY HH.mm',\n        LLLL : 'dddd, D. MMMM YYYY HH.mm'\n    },\n    calendar : {\n        sameDay: '[heute um] LT [Uhr]',\n        sameElse: 'L',\n        nextDay: '[morgen um] LT [Uhr]',\n        nextWeek: 'dddd [um] LT [Uhr]',\n        lastDay: '[gestern um] LT [Uhr]',\n        lastWeek: '[letzten] dddd [um] LT [Uhr]'\n    },\n    relativeTime : {\n        future : 'in %s',\n        past : 'vor %s',\n        s : 'ein paar Sekunden',\n        m : processRelativeTime,\n        mm : '%d Minuten',\n        h : processRelativeTime,\n        hh : '%d Stunden',\n        d : processRelativeTime,\n        dd : processRelativeTime,\n        M : processRelativeTime,\n        MM : processRelativeTime,\n        y : processRelativeTime,\n        yy : processRelativeTime\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}\\./,\n    ordinal : '%d.',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\nreturn deCh;\n\n})));\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/locale/de.js",
    "content": "//! moment.js locale configuration\n//! locale : German [de]\n//! author : lluchs : https://github.com/lluchs\n//! author: Menelion Elensúle: https://github.com/Oire\n//! author : Mikolaj Dadela : https://github.com/mik01aj\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\n\nfunction processRelativeTime(number, withoutSuffix, key, isFuture) {\n    var format = {\n        'm': ['eine Minute', 'einer Minute'],\n        'h': ['eine Stunde', 'einer Stunde'],\n        'd': ['ein Tag', 'einem Tag'],\n        'dd': [number + ' Tage', number + ' Tagen'],\n        'M': ['ein Monat', 'einem Monat'],\n        'MM': [number + ' Monate', number + ' Monaten'],\n        'y': ['ein Jahr', 'einem Jahr'],\n        'yy': [number + ' Jahre', number + ' Jahren']\n    };\n    return withoutSuffix ? format[key][0] : format[key][1];\n}\n\nvar de = moment.defineLocale('de', {\n    months : 'Januar_Februar_März_April_Mai_Juni_Juli_August_September_Oktober_November_Dezember'.split('_'),\n    monthsShort : 'Jan._Febr._Mrz._Apr._Mai_Jun._Jul._Aug._Sept._Okt._Nov._Dez.'.split('_'),\n    monthsParseExact : true,\n    weekdays : 'Sonntag_Montag_Dienstag_Mittwoch_Donnerstag_Freitag_Samstag'.split('_'),\n    weekdaysShort : 'So._Mo._Di._Mi._Do._Fr._Sa.'.split('_'),\n    weekdaysMin : 'So_Mo_Di_Mi_Do_Fr_Sa'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat : {\n        LT: 'HH:mm',\n        LTS: 'HH:mm:ss',\n        L : 'DD.MM.YYYY',\n        LL : 'D. MMMM YYYY',\n        LLL : 'D. MMMM YYYY HH:mm',\n        LLLL : 'dddd, D. MMMM YYYY HH:mm'\n    },\n    calendar : {\n        sameDay: '[heute um] LT [Uhr]',\n        sameElse: 'L',\n        nextDay: '[morgen um] LT [Uhr]',\n        nextWeek: 'dddd [um] LT [Uhr]',\n        lastDay: '[gestern um] LT [Uhr]',\n        lastWeek: '[letzten] dddd [um] LT [Uhr]'\n    },\n    relativeTime : {\n        future : 'in %s',\n        past : 'vor %s',\n        s : 'ein paar Sekunden',\n        m : processRelativeTime,\n        mm : '%d Minuten',\n        h : processRelativeTime,\n        hh : '%d Stunden',\n        d : processRelativeTime,\n        dd : processRelativeTime,\n        M : processRelativeTime,\n        MM : processRelativeTime,\n        y : processRelativeTime,\n        yy : processRelativeTime\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}\\./,\n    ordinal : '%d.',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\nreturn de;\n\n})));\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/locale/dv.js",
    "content": "//! moment.js locale configuration\n//! locale : Maldivian [dv]\n//! author : Jawish Hameed : https://github.com/jawish\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\n\nvar months = [\n    'ޖެނުއަރީ',\n    'ފެބްރުއަރީ',\n    'މާރިޗު',\n    'އޭޕްރީލު',\n    'މޭ',\n    'ޖޫން',\n    'ޖުލައި',\n    'އޯގަސްޓު',\n    'ސެޕްޓެމްބަރު',\n    'އޮކްޓޯބަރު',\n    'ނޮވެމްބަރު',\n    'ޑިސެމްބަރު'\n];\nvar weekdays = [\n    'އާދިއްތަ',\n    'ހޯމަ',\n    'އަންގާރަ',\n    'ބުދަ',\n    'ބުރާސްފަތި',\n    'ހުކުރު',\n    'ހޮނިހިރު'\n];\n\nvar dv = moment.defineLocale('dv', {\n    months : months,\n    monthsShort : months,\n    weekdays : weekdays,\n    weekdaysShort : weekdays,\n    weekdaysMin : 'އާދި_ހޯމަ_އަން_ބުދަ_ބުރާ_ހުކު_ހޮނި'.split('_'),\n    longDateFormat : {\n\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'D/M/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY HH:mm',\n        LLLL : 'dddd D MMMM YYYY HH:mm'\n    },\n    meridiemParse: /މކ|މފ/,\n    isPM : function (input) {\n        return 'މފ' === input;\n    },\n    meridiem : function (hour, minute, isLower) {\n        if (hour < 12) {\n            return 'މކ';\n        } else {\n            return 'މފ';\n        }\n    },\n    calendar : {\n        sameDay : '[މިއަދު] LT',\n        nextDay : '[މާދަމާ] LT',\n        nextWeek : 'dddd LT',\n        lastDay : '[އިއްޔެ] LT',\n        lastWeek : '[ފާއިތުވި] dddd LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'ތެރޭގައި %s',\n        past : 'ކުރިން %s',\n        s : 'ސިކުންތުކޮޅެއް',\n        m : 'މިނިޓެއް',\n        mm : 'މިނިޓު %d',\n        h : 'ގަޑިއިރެއް',\n        hh : 'ގަޑިއިރު %d',\n        d : 'ދުވަހެއް',\n        dd : 'ދުވަސް %d',\n        M : 'މަހެއް',\n        MM : 'މަސް %d',\n        y : 'އަހަރެއް',\n        yy : 'އަހަރު %d'\n    },\n    preparse: function (string) {\n        return string.replace(/،/g, ',');\n    },\n    postformat: function (string) {\n        return string.replace(/,/g, '،');\n    },\n    week : {\n        dow : 7,  // Sunday is the first day of the week.\n        doy : 12  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\nreturn dv;\n\n})));\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/locale/el.js",
    "content": "//! moment.js locale configuration\n//! locale : Greek [el]\n//! author : Aggelos Karalias : https://github.com/mehiel\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction isFunction(input) {\n    return input instanceof Function || Object.prototype.toString.call(input) === '[object Function]';\n}\n\n\nvar el = moment.defineLocale('el', {\n    monthsNominativeEl : 'Ιανουάριος_Φεβρουάριος_Μάρτιος_Απρίλιος_Μάιος_Ιούνιος_Ιούλιος_Αύγουστος_Σεπτέμβριος_Οκτώβριος_Νοέμβριος_Δεκέμβριος'.split('_'),\n    monthsGenitiveEl : 'Ιανουαρίου_Φεβρουαρίου_Μαρτίου_Απριλίου_Μαΐου_Ιουνίου_Ιουλίου_Αυγούστου_Σεπτεμβρίου_Οκτωβρίου_Νοεμβρίου_Δεκεμβρίου'.split('_'),\n    months : function (momentToFormat, format) {\n        if (!momentToFormat) {\n            return this._monthsNominativeEl;\n        } else if (/D/.test(format.substring(0, format.indexOf('MMMM')))) { // if there is a day number before 'MMMM'\n            return this._monthsGenitiveEl[momentToFormat.month()];\n        } else {\n            return this._monthsNominativeEl[momentToFormat.month()];\n        }\n    },\n    monthsShort : 'Ιαν_Φεβ_Μαρ_Απρ_Μαϊ_Ιουν_Ιουλ_Αυγ_Σεπ_Οκτ_Νοε_Δεκ'.split('_'),\n    weekdays : 'Κυριακή_Δευτέρα_Τρίτη_Τετάρτη_Πέμπτη_Παρασκευή_Σάββατο'.split('_'),\n    weekdaysShort : 'Κυρ_Δευ_Τρι_Τετ_Πεμ_Παρ_Σαβ'.split('_'),\n    weekdaysMin : 'Κυ_Δε_Τρ_Τε_Πε_Πα_Σα'.split('_'),\n    meridiem : function (hours, minutes, isLower) {\n        if (hours > 11) {\n            return isLower ? 'μμ' : 'ΜΜ';\n        } else {\n            return isLower ? 'πμ' : 'ΠΜ';\n        }\n    },\n    isPM : function (input) {\n        return ((input + '').toLowerCase()[0] === 'μ');\n    },\n    meridiemParse : /[ΠΜ]\\.?Μ?\\.?/i,\n    longDateFormat : {\n        LT : 'h:mm A',\n        LTS : 'h:mm:ss A',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY h:mm A',\n        LLLL : 'dddd, D MMMM YYYY h:mm A'\n    },\n    calendarEl : {\n        sameDay : '[Σήμερα {}] LT',\n        nextDay : '[Αύριο {}] LT',\n        nextWeek : 'dddd [{}] LT',\n        lastDay : '[Χθες {}] LT',\n        lastWeek : function () {\n            switch (this.day()) {\n                case 6:\n                    return '[το προηγούμενο] dddd [{}] LT';\n                default:\n                    return '[την προηγούμενη] dddd [{}] LT';\n            }\n        },\n        sameElse : 'L'\n    },\n    calendar : function (key, mom) {\n        var output = this._calendarEl[key],\n            hours = mom && mom.hours();\n        if (isFunction(output)) {\n            output = output.apply(mom);\n        }\n        return output.replace('{}', (hours % 12 === 1 ? 'στη' : 'στις'));\n    },\n    relativeTime : {\n        future : 'σε %s',\n        past : '%s πριν',\n        s : 'λίγα δευτερόλεπτα',\n        m : 'ένα λεπτό',\n        mm : '%d λεπτά',\n        h : 'μία ώρα',\n        hh : '%d ώρες',\n        d : 'μία μέρα',\n        dd : '%d μέρες',\n        M : 'ένας μήνας',\n        MM : '%d μήνες',\n        y : 'ένας χρόνος',\n        yy : '%d χρόνια'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}η/,\n    ordinal: '%dη',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4st is the first week of the year.\n    }\n});\n\nreturn el;\n\n})));\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/locale/en-au.js",
    "content": "//! moment.js locale configuration\n//! locale : English (Australia) [en-au]\n//! author : Jared Morse : https://github.com/jarcoal\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\n\nvar enAu = moment.defineLocale('en-au', {\n    months : 'January_February_March_April_May_June_July_August_September_October_November_December'.split('_'),\n    monthsShort : 'Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec'.split('_'),\n    weekdays : 'Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday'.split('_'),\n    weekdaysShort : 'Sun_Mon_Tue_Wed_Thu_Fri_Sat'.split('_'),\n    weekdaysMin : 'Su_Mo_Tu_We_Th_Fr_Sa'.split('_'),\n    longDateFormat : {\n        LT : 'h:mm A',\n        LTS : 'h:mm:ss A',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY h:mm A',\n        LLLL : 'dddd, D MMMM YYYY h:mm A'\n    },\n    calendar : {\n        sameDay : '[Today at] LT',\n        nextDay : '[Tomorrow at] LT',\n        nextWeek : 'dddd [at] LT',\n        lastDay : '[Yesterday at] LT',\n        lastWeek : '[Last] dddd [at] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'in %s',\n        past : '%s ago',\n        s : 'a few seconds',\n        m : 'a minute',\n        mm : '%d minutes',\n        h : 'an hour',\n        hh : '%d hours',\n        d : 'a day',\n        dd : '%d days',\n        M : 'a month',\n        MM : '%d months',\n        y : 'a year',\n        yy : '%d years'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}(st|nd|rd|th)/,\n    ordinal : function (number) {\n        var b = number % 10,\n            output = (~~(number % 100 / 10) === 1) ? 'th' :\n            (b === 1) ? 'st' :\n            (b === 2) ? 'nd' :\n            (b === 3) ? 'rd' : 'th';\n        return number + output;\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\nreturn enAu;\n\n})));\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/locale/en-ca.js",
    "content": "//! moment.js locale configuration\n//! locale : English (Canada) [en-ca]\n//! author : Jonathan Abourbih : https://github.com/jonbca\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\n\nvar enCa = moment.defineLocale('en-ca', {\n    months : 'January_February_March_April_May_June_July_August_September_October_November_December'.split('_'),\n    monthsShort : 'Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec'.split('_'),\n    weekdays : 'Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday'.split('_'),\n    weekdaysShort : 'Sun_Mon_Tue_Wed_Thu_Fri_Sat'.split('_'),\n    weekdaysMin : 'Su_Mo_Tu_We_Th_Fr_Sa'.split('_'),\n    longDateFormat : {\n        LT : 'h:mm A',\n        LTS : 'h:mm:ss A',\n        L : 'YYYY-MM-DD',\n        LL : 'MMMM D, YYYY',\n        LLL : 'MMMM D, YYYY h:mm A',\n        LLLL : 'dddd, MMMM D, YYYY h:mm A'\n    },\n    calendar : {\n        sameDay : '[Today at] LT',\n        nextDay : '[Tomorrow at] LT',\n        nextWeek : 'dddd [at] LT',\n        lastDay : '[Yesterday at] LT',\n        lastWeek : '[Last] dddd [at] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'in %s',\n        past : '%s ago',\n        s : 'a few seconds',\n        m : 'a minute',\n        mm : '%d minutes',\n        h : 'an hour',\n        hh : '%d hours',\n        d : 'a day',\n        dd : '%d days',\n        M : 'a month',\n        MM : '%d months',\n        y : 'a year',\n        yy : '%d years'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}(st|nd|rd|th)/,\n    ordinal : function (number) {\n        var b = number % 10,\n            output = (~~(number % 100 / 10) === 1) ? 'th' :\n            (b === 1) ? 'st' :\n            (b === 2) ? 'nd' :\n            (b === 3) ? 'rd' : 'th';\n        return number + output;\n    }\n});\n\nreturn enCa;\n\n})));\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/locale/en-gb.js",
    "content": "//! moment.js locale configuration\n//! locale : English (United Kingdom) [en-gb]\n//! author : Chris Gedrim : https://github.com/chrisgedrim\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\n\nvar enGb = moment.defineLocale('en-gb', {\n    months : 'January_February_March_April_May_June_July_August_September_October_November_December'.split('_'),\n    monthsShort : 'Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec'.split('_'),\n    weekdays : 'Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday'.split('_'),\n    weekdaysShort : 'Sun_Mon_Tue_Wed_Thu_Fri_Sat'.split('_'),\n    weekdaysMin : 'Su_Mo_Tu_We_Th_Fr_Sa'.split('_'),\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY HH:mm',\n        LLLL : 'dddd, D MMMM YYYY HH:mm'\n    },\n    calendar : {\n        sameDay : '[Today at] LT',\n        nextDay : '[Tomorrow at] LT',\n        nextWeek : 'dddd [at] LT',\n        lastDay : '[Yesterday at] LT',\n        lastWeek : '[Last] dddd [at] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'in %s',\n        past : '%s ago',\n        s : 'a few seconds',\n        m : 'a minute',\n        mm : '%d minutes',\n        h : 'an hour',\n        hh : '%d hours',\n        d : 'a day',\n        dd : '%d days',\n        M : 'a month',\n        MM : '%d months',\n        y : 'a year',\n        yy : '%d years'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}(st|nd|rd|th)/,\n    ordinal : function (number) {\n        var b = number % 10,\n            output = (~~(number % 100 / 10) === 1) ? 'th' :\n            (b === 1) ? 'st' :\n            (b === 2) ? 'nd' :\n            (b === 3) ? 'rd' : 'th';\n        return number + output;\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\nreturn enGb;\n\n})));\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/locale/en-ie.js",
    "content": "//! moment.js locale configuration\n//! locale : English (Ireland) [en-ie]\n//! author : Chris Cartlidge : https://github.com/chriscartlidge\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\n\nvar enIe = moment.defineLocale('en-ie', {\n    months : 'January_February_March_April_May_June_July_August_September_October_November_December'.split('_'),\n    monthsShort : 'Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec'.split('_'),\n    weekdays : 'Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday'.split('_'),\n    weekdaysShort : 'Sun_Mon_Tue_Wed_Thu_Fri_Sat'.split('_'),\n    weekdaysMin : 'Su_Mo_Tu_We_Th_Fr_Sa'.split('_'),\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD-MM-YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY HH:mm',\n        LLLL : 'dddd D MMMM YYYY HH:mm'\n    },\n    calendar : {\n        sameDay : '[Today at] LT',\n        nextDay : '[Tomorrow at] LT',\n        nextWeek : 'dddd [at] LT',\n        lastDay : '[Yesterday at] LT',\n        lastWeek : '[Last] dddd [at] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'in %s',\n        past : '%s ago',\n        s : 'a few seconds',\n        m : 'a minute',\n        mm : '%d minutes',\n        h : 'an hour',\n        hh : '%d hours',\n        d : 'a day',\n        dd : '%d days',\n        M : 'a month',\n        MM : '%d months',\n        y : 'a year',\n        yy : '%d years'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}(st|nd|rd|th)/,\n    ordinal : function (number) {\n        var b = number % 10,\n            output = (~~(number % 100 / 10) === 1) ? 'th' :\n            (b === 1) ? 'st' :\n            (b === 2) ? 'nd' :\n            (b === 3) ? 'rd' : 'th';\n        return number + output;\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\nreturn enIe;\n\n})));\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/locale/en-nz.js",
    "content": "//! moment.js locale configuration\n//! locale : English (New Zealand) [en-nz]\n//! author : Luke McGregor : https://github.com/lukemcgregor\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\n\nvar enNz = moment.defineLocale('en-nz', {\n    months : 'January_February_March_April_May_June_July_August_September_October_November_December'.split('_'),\n    monthsShort : 'Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec'.split('_'),\n    weekdays : 'Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday'.split('_'),\n    weekdaysShort : 'Sun_Mon_Tue_Wed_Thu_Fri_Sat'.split('_'),\n    weekdaysMin : 'Su_Mo_Tu_We_Th_Fr_Sa'.split('_'),\n    longDateFormat : {\n        LT : 'h:mm A',\n        LTS : 'h:mm:ss A',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY h:mm A',\n        LLLL : 'dddd, D MMMM YYYY h:mm A'\n    },\n    calendar : {\n        sameDay : '[Today at] LT',\n        nextDay : '[Tomorrow at] LT',\n        nextWeek : 'dddd [at] LT',\n        lastDay : '[Yesterday at] LT',\n        lastWeek : '[Last] dddd [at] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'in %s',\n        past : '%s ago',\n        s : 'a few seconds',\n        m : 'a minute',\n        mm : '%d minutes',\n        h : 'an hour',\n        hh : '%d hours',\n        d : 'a day',\n        dd : '%d days',\n        M : 'a month',\n        MM : '%d months',\n        y : 'a year',\n        yy : '%d years'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}(st|nd|rd|th)/,\n    ordinal : function (number) {\n        var b = number % 10,\n            output = (~~(number % 100 / 10) === 1) ? 'th' :\n            (b === 1) ? 'st' :\n            (b === 2) ? 'nd' :\n            (b === 3) ? 'rd' : 'th';\n        return number + output;\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\nreturn enNz;\n\n})));\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/locale/eo.js",
    "content": "//! moment.js locale configuration\n//! locale : Esperanto [eo]\n//! author : Colin Dean : https://github.com/colindean\n//! author : Mia Nordentoft Imperatori : https://github.com/miestasmia\n//! comment : miestasmia corrected the translation by colindean\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\n\nvar eo = moment.defineLocale('eo', {\n    months : 'januaro_februaro_marto_aprilo_majo_junio_julio_aŭgusto_septembro_oktobro_novembro_decembro'.split('_'),\n    monthsShort : 'jan_feb_mar_apr_maj_jun_jul_aŭg_sep_okt_nov_dec'.split('_'),\n    weekdays : 'dimanĉo_lundo_mardo_merkredo_ĵaŭdo_vendredo_sabato'.split('_'),\n    weekdaysShort : 'dim_lun_mard_merk_ĵaŭ_ven_sab'.split('_'),\n    weekdaysMin : 'di_lu_ma_me_ĵa_ve_sa'.split('_'),\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'YYYY-MM-DD',\n        LL : 'D[-a de] MMMM, YYYY',\n        LLL : 'D[-a de] MMMM, YYYY HH:mm',\n        LLLL : 'dddd, [la] D[-a de] MMMM, YYYY HH:mm'\n    },\n    meridiemParse: /[ap]\\.t\\.m/i,\n    isPM: function (input) {\n        return input.charAt(0).toLowerCase() === 'p';\n    },\n    meridiem : function (hours, minutes, isLower) {\n        if (hours > 11) {\n            return isLower ? 'p.t.m.' : 'P.T.M.';\n        } else {\n            return isLower ? 'a.t.m.' : 'A.T.M.';\n        }\n    },\n    calendar : {\n        sameDay : '[Hodiaŭ je] LT',\n        nextDay : '[Morgaŭ je] LT',\n        nextWeek : 'dddd [je] LT',\n        lastDay : '[Hieraŭ je] LT',\n        lastWeek : '[pasinta] dddd [je] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'post %s',\n        past : 'antaŭ %s',\n        s : 'sekundoj',\n        m : 'minuto',\n        mm : '%d minutoj',\n        h : 'horo',\n        hh : '%d horoj',\n        d : 'tago',//ne 'diurno', ĉar estas uzita por proksimumo\n        dd : '%d tagoj',\n        M : 'monato',\n        MM : '%d monatoj',\n        y : 'jaro',\n        yy : '%d jaroj'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}a/,\n    ordinal : '%da',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 7  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\nreturn eo;\n\n})));\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/locale/es-do.js",
    "content": "//! moment.js locale configuration\n//! locale : Spanish (Dominican Republic) [es-do]\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\n\nvar monthsShortDot = 'ene._feb._mar._abr._may._jun._jul._ago._sep._oct._nov._dic.'.split('_');\nvar monthsShort = 'ene_feb_mar_abr_may_jun_jul_ago_sep_oct_nov_dic'.split('_');\n\nvar esDo = moment.defineLocale('es-do', {\n    months : 'enero_febrero_marzo_abril_mayo_junio_julio_agosto_septiembre_octubre_noviembre_diciembre'.split('_'),\n    monthsShort : function (m, format) {\n        if (!m) {\n            return monthsShortDot;\n        } else if (/-MMM-/.test(format)) {\n            return monthsShort[m.month()];\n        } else {\n            return monthsShortDot[m.month()];\n        }\n    },\n    monthsParseExact : true,\n    weekdays : 'domingo_lunes_martes_miércoles_jueves_viernes_sábado'.split('_'),\n    weekdaysShort : 'dom._lun._mar._mié._jue._vie._sáb.'.split('_'),\n    weekdaysMin : 'do_lu_ma_mi_ju_vi_sá'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat : {\n        LT : 'h:mm A',\n        LTS : 'h:mm:ss A',\n        L : 'DD/MM/YYYY',\n        LL : 'D [de] MMMM [de] YYYY',\n        LLL : 'D [de] MMMM [de] YYYY h:mm A',\n        LLLL : 'dddd, D [de] MMMM [de] YYYY h:mm A'\n    },\n    calendar : {\n        sameDay : function () {\n            return '[hoy a la' + ((this.hours() !== 1) ? 's' : '') + '] LT';\n        },\n        nextDay : function () {\n            return '[mañana a la' + ((this.hours() !== 1) ? 's' : '') + '] LT';\n        },\n        nextWeek : function () {\n            return 'dddd [a la' + ((this.hours() !== 1) ? 's' : '') + '] LT';\n        },\n        lastDay : function () {\n            return '[ayer a la' + ((this.hours() !== 1) ? 's' : '') + '] LT';\n        },\n        lastWeek : function () {\n            return '[el] dddd [pasado a la' + ((this.hours() !== 1) ? 's' : '') + '] LT';\n        },\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'en %s',\n        past : 'hace %s',\n        s : 'unos segundos',\n        m : 'un minuto',\n        mm : '%d minutos',\n        h : 'una hora',\n        hh : '%d horas',\n        d : 'un día',\n        dd : '%d días',\n        M : 'un mes',\n        MM : '%d meses',\n        y : 'un año',\n        yy : '%d años'\n    },\n    dayOfMonthOrdinalParse : /\\d{1,2}º/,\n    ordinal : '%dº',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\nreturn esDo;\n\n})));\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/locale/es.js",
    "content": "//! moment.js locale configuration\n//! locale : Spanish [es]\n//! author : Julio Napurí : https://github.com/julionc\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\n\nvar monthsShortDot = 'ene._feb._mar._abr._may._jun._jul._ago._sep._oct._nov._dic.'.split('_');\nvar monthsShort = 'ene_feb_mar_abr_may_jun_jul_ago_sep_oct_nov_dic'.split('_');\n\nvar es = moment.defineLocale('es', {\n    months : 'enero_febrero_marzo_abril_mayo_junio_julio_agosto_septiembre_octubre_noviembre_diciembre'.split('_'),\n    monthsShort : function (m, format) {\n        if (!m) {\n            return monthsShortDot;\n        } else if (/-MMM-/.test(format)) {\n            return monthsShort[m.month()];\n        } else {\n            return monthsShortDot[m.month()];\n        }\n    },\n    monthsParseExact : true,\n    weekdays : 'domingo_lunes_martes_miércoles_jueves_viernes_sábado'.split('_'),\n    weekdaysShort : 'dom._lun._mar._mié._jue._vie._sáb.'.split('_'),\n    weekdaysMin : 'do_lu_ma_mi_ju_vi_sá'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat : {\n        LT : 'H:mm',\n        LTS : 'H:mm:ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D [de] MMMM [de] YYYY',\n        LLL : 'D [de] MMMM [de] YYYY H:mm',\n        LLLL : 'dddd, D [de] MMMM [de] YYYY H:mm'\n    },\n    calendar : {\n        sameDay : function () {\n            return '[hoy a la' + ((this.hours() !== 1) ? 's' : '') + '] LT';\n        },\n        nextDay : function () {\n            return '[mañana a la' + ((this.hours() !== 1) ? 's' : '') + '] LT';\n        },\n        nextWeek : function () {\n            return 'dddd [a la' + ((this.hours() !== 1) ? 's' : '') + '] LT';\n        },\n        lastDay : function () {\n            return '[ayer a la' + ((this.hours() !== 1) ? 's' : '') + '] LT';\n        },\n        lastWeek : function () {\n            return '[el] dddd [pasado a la' + ((this.hours() !== 1) ? 's' : '') + '] LT';\n        },\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'en %s',\n        past : 'hace %s',\n        s : 'unos segundos',\n        m : 'un minuto',\n        mm : '%d minutos',\n        h : 'una hora',\n        hh : '%d horas',\n        d : 'un día',\n        dd : '%d días',\n        M : 'un mes',\n        MM : '%d meses',\n        y : 'un año',\n        yy : '%d años'\n    },\n    dayOfMonthOrdinalParse : /\\d{1,2}º/,\n    ordinal : '%dº',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\nreturn es;\n\n})));\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/locale/et.js",
    "content": "//! moment.js locale configuration\n//! locale : Estonian [et]\n//! author : Henry Kehlmann : https://github.com/madhenry\n//! improvements : Illimar Tambek : https://github.com/ragulka\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\n\nfunction processRelativeTime(number, withoutSuffix, key, isFuture) {\n    var format = {\n        's' : ['mõne sekundi', 'mõni sekund', 'paar sekundit'],\n        'm' : ['ühe minuti', 'üks minut'],\n        'mm': [number + ' minuti', number + ' minutit'],\n        'h' : ['ühe tunni', 'tund aega', 'üks tund'],\n        'hh': [number + ' tunni', number + ' tundi'],\n        'd' : ['ühe päeva', 'üks päev'],\n        'M' : ['kuu aja', 'kuu aega', 'üks kuu'],\n        'MM': [number + ' kuu', number + ' kuud'],\n        'y' : ['ühe aasta', 'aasta', 'üks aasta'],\n        'yy': [number + ' aasta', number + ' aastat']\n    };\n    if (withoutSuffix) {\n        return format[key][2] ? format[key][2] : format[key][1];\n    }\n    return isFuture ? format[key][0] : format[key][1];\n}\n\nvar et = moment.defineLocale('et', {\n    months        : 'jaanuar_veebruar_märts_aprill_mai_juuni_juuli_august_september_oktoober_november_detsember'.split('_'),\n    monthsShort   : 'jaan_veebr_märts_apr_mai_juuni_juuli_aug_sept_okt_nov_dets'.split('_'),\n    weekdays      : 'pühapäev_esmaspäev_teisipäev_kolmapäev_neljapäev_reede_laupäev'.split('_'),\n    weekdaysShort : 'P_E_T_K_N_R_L'.split('_'),\n    weekdaysMin   : 'P_E_T_K_N_R_L'.split('_'),\n    longDateFormat : {\n        LT   : 'H:mm',\n        LTS : 'H:mm:ss',\n        L    : 'DD.MM.YYYY',\n        LL   : 'D. MMMM YYYY',\n        LLL  : 'D. MMMM YYYY H:mm',\n        LLLL : 'dddd, D. MMMM YYYY H:mm'\n    },\n    calendar : {\n        sameDay  : '[Täna,] LT',\n        nextDay  : '[Homme,] LT',\n        nextWeek : '[Järgmine] dddd LT',\n        lastDay  : '[Eile,] LT',\n        lastWeek : '[Eelmine] dddd LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : '%s pärast',\n        past   : '%s tagasi',\n        s      : processRelativeTime,\n        m      : processRelativeTime,\n        mm     : processRelativeTime,\n        h      : processRelativeTime,\n        hh     : processRelativeTime,\n        d      : processRelativeTime,\n        dd     : '%d päeva',\n        M      : processRelativeTime,\n        MM     : processRelativeTime,\n        y      : processRelativeTime,\n        yy     : processRelativeTime\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}\\./,\n    ordinal : '%d.',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\nreturn et;\n\n})));\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/locale/eu.js",
    "content": "//! moment.js locale configuration\n//! locale : Basque [eu]\n//! author : Eneko Illarramendi : https://github.com/eillarra\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\n\nvar eu = moment.defineLocale('eu', {\n    months : 'urtarrila_otsaila_martxoa_apirila_maiatza_ekaina_uztaila_abuztua_iraila_urria_azaroa_abendua'.split('_'),\n    monthsShort : 'urt._ots._mar._api._mai._eka._uzt._abu._ira._urr._aza._abe.'.split('_'),\n    monthsParseExact : true,\n    weekdays : 'igandea_astelehena_asteartea_asteazkena_osteguna_ostirala_larunbata'.split('_'),\n    weekdaysShort : 'ig._al._ar._az._og._ol._lr.'.split('_'),\n    weekdaysMin : 'ig_al_ar_az_og_ol_lr'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'YYYY-MM-DD',\n        LL : 'YYYY[ko] MMMM[ren] D[a]',\n        LLL : 'YYYY[ko] MMMM[ren] D[a] HH:mm',\n        LLLL : 'dddd, YYYY[ko] MMMM[ren] D[a] HH:mm',\n        l : 'YYYY-M-D',\n        ll : 'YYYY[ko] MMM D[a]',\n        lll : 'YYYY[ko] MMM D[a] HH:mm',\n        llll : 'ddd, YYYY[ko] MMM D[a] HH:mm'\n    },\n    calendar : {\n        sameDay : '[gaur] LT[etan]',\n        nextDay : '[bihar] LT[etan]',\n        nextWeek : 'dddd LT[etan]',\n        lastDay : '[atzo] LT[etan]',\n        lastWeek : '[aurreko] dddd LT[etan]',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : '%s barru',\n        past : 'duela %s',\n        s : 'segundo batzuk',\n        m : 'minutu bat',\n        mm : '%d minutu',\n        h : 'ordu bat',\n        hh : '%d ordu',\n        d : 'egun bat',\n        dd : '%d egun',\n        M : 'hilabete bat',\n        MM : '%d hilabete',\n        y : 'urte bat',\n        yy : '%d urte'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}\\./,\n    ordinal : '%d.',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 7  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\nreturn eu;\n\n})));\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/locale/fa.js",
    "content": "//! moment.js locale configuration\n//! locale : Persian [fa]\n//! author : Ebrahim Byagowi : https://github.com/ebraminio\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\n\nvar symbolMap = {\n    '1': '۱',\n    '2': '۲',\n    '3': '۳',\n    '4': '۴',\n    '5': '۵',\n    '6': '۶',\n    '7': '۷',\n    '8': '۸',\n    '9': '۹',\n    '0': '۰'\n};\nvar numberMap = {\n    '۱': '1',\n    '۲': '2',\n    '۳': '3',\n    '۴': '4',\n    '۵': '5',\n    '۶': '6',\n    '۷': '7',\n    '۸': '8',\n    '۹': '9',\n    '۰': '0'\n};\n\nvar fa = moment.defineLocale('fa', {\n    months : 'ژانویه_فوریه_مارس_آوریل_مه_ژوئن_ژوئیه_اوت_سپتامبر_اکتبر_نوامبر_دسامبر'.split('_'),\n    monthsShort : 'ژانویه_فوریه_مارس_آوریل_مه_ژوئن_ژوئیه_اوت_سپتامبر_اکتبر_نوامبر_دسامبر'.split('_'),\n    weekdays : 'یک\\u200cشنبه_دوشنبه_سه\\u200cشنبه_چهارشنبه_پنج\\u200cشنبه_جمعه_شنبه'.split('_'),\n    weekdaysShort : 'یک\\u200cشنبه_دوشنبه_سه\\u200cشنبه_چهارشنبه_پنج\\u200cشنبه_جمعه_شنبه'.split('_'),\n    weekdaysMin : 'ی_د_س_چ_پ_ج_ش'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY HH:mm',\n        LLLL : 'dddd, D MMMM YYYY HH:mm'\n    },\n    meridiemParse: /قبل از ظهر|بعد از ظهر/,\n    isPM: function (input) {\n        return /بعد از ظهر/.test(input);\n    },\n    meridiem : function (hour, minute, isLower) {\n        if (hour < 12) {\n            return 'قبل از ظهر';\n        } else {\n            return 'بعد از ظهر';\n        }\n    },\n    calendar : {\n        sameDay : '[امروز ساعت] LT',\n        nextDay : '[فردا ساعت] LT',\n        nextWeek : 'dddd [ساعت] LT',\n        lastDay : '[دیروز ساعت] LT',\n        lastWeek : 'dddd [پیش] [ساعت] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'در %s',\n        past : '%s پیش',\n        s : 'چند ثانیه',\n        m : 'یک دقیقه',\n        mm : '%d دقیقه',\n        h : 'یک ساعت',\n        hh : '%d ساعت',\n        d : 'یک روز',\n        dd : '%d روز',\n        M : 'یک ماه',\n        MM : '%d ماه',\n        y : 'یک سال',\n        yy : '%d سال'\n    },\n    preparse: function (string) {\n        return string.replace(/[۰-۹]/g, function (match) {\n            return numberMap[match];\n        }).replace(/،/g, ',');\n    },\n    postformat: function (string) {\n        return string.replace(/\\d/g, function (match) {\n            return symbolMap[match];\n        }).replace(/,/g, '،');\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}م/,\n    ordinal : '%dم',\n    week : {\n        dow : 6, // Saturday is the first day of the week.\n        doy : 12 // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\nreturn fa;\n\n})));\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/locale/fi.js",
    "content": "//! moment.js locale configuration\n//! locale : Finnish [fi]\n//! author : Tarmo Aidantausta : https://github.com/bleadof\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\n\nvar numbersPast = 'nolla yksi kaksi kolme neljä viisi kuusi seitsemän kahdeksan yhdeksän'.split(' ');\nvar numbersFuture = [\n        'nolla', 'yhden', 'kahden', 'kolmen', 'neljän', 'viiden', 'kuuden',\n        numbersPast[7], numbersPast[8], numbersPast[9]\n    ];\nfunction translate(number, withoutSuffix, key, isFuture) {\n    var result = '';\n    switch (key) {\n        case 's':\n            return isFuture ? 'muutaman sekunnin' : 'muutama sekunti';\n        case 'm':\n            return isFuture ? 'minuutin' : 'minuutti';\n        case 'mm':\n            result = isFuture ? 'minuutin' : 'minuuttia';\n            break;\n        case 'h':\n            return isFuture ? 'tunnin' : 'tunti';\n        case 'hh':\n            result = isFuture ? 'tunnin' : 'tuntia';\n            break;\n        case 'd':\n            return isFuture ? 'päivän' : 'päivä';\n        case 'dd':\n            result = isFuture ? 'päivän' : 'päivää';\n            break;\n        case 'M':\n            return isFuture ? 'kuukauden' : 'kuukausi';\n        case 'MM':\n            result = isFuture ? 'kuukauden' : 'kuukautta';\n            break;\n        case 'y':\n            return isFuture ? 'vuoden' : 'vuosi';\n        case 'yy':\n            result = isFuture ? 'vuoden' : 'vuotta';\n            break;\n    }\n    result = verbalNumber(number, isFuture) + ' ' + result;\n    return result;\n}\nfunction verbalNumber(number, isFuture) {\n    return number < 10 ? (isFuture ? numbersFuture[number] : numbersPast[number]) : number;\n}\n\nvar fi = moment.defineLocale('fi', {\n    months : 'tammikuu_helmikuu_maaliskuu_huhtikuu_toukokuu_kesäkuu_heinäkuu_elokuu_syyskuu_lokakuu_marraskuu_joulukuu'.split('_'),\n    monthsShort : 'tammi_helmi_maalis_huhti_touko_kesä_heinä_elo_syys_loka_marras_joulu'.split('_'),\n    weekdays : 'sunnuntai_maanantai_tiistai_keskiviikko_torstai_perjantai_lauantai'.split('_'),\n    weekdaysShort : 'su_ma_ti_ke_to_pe_la'.split('_'),\n    weekdaysMin : 'su_ma_ti_ke_to_pe_la'.split('_'),\n    longDateFormat : {\n        LT : 'HH.mm',\n        LTS : 'HH.mm.ss',\n        L : 'DD.MM.YYYY',\n        LL : 'Do MMMM[ta] YYYY',\n        LLL : 'Do MMMM[ta] YYYY, [klo] HH.mm',\n        LLLL : 'dddd, Do MMMM[ta] YYYY, [klo] HH.mm',\n        l : 'D.M.YYYY',\n        ll : 'Do MMM YYYY',\n        lll : 'Do MMM YYYY, [klo] HH.mm',\n        llll : 'ddd, Do MMM YYYY, [klo] HH.mm'\n    },\n    calendar : {\n        sameDay : '[tänään] [klo] LT',\n        nextDay : '[huomenna] [klo] LT',\n        nextWeek : 'dddd [klo] LT',\n        lastDay : '[eilen] [klo] LT',\n        lastWeek : '[viime] dddd[na] [klo] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : '%s päästä',\n        past : '%s sitten',\n        s : translate,\n        m : translate,\n        mm : translate,\n        h : translate,\n        hh : translate,\n        d : translate,\n        dd : translate,\n        M : translate,\n        MM : translate,\n        y : translate,\n        yy : translate\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}\\./,\n    ordinal : '%d.',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\nreturn fi;\n\n})));\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/locale/fo.js",
    "content": "//! moment.js locale configuration\n//! locale : Faroese [fo]\n//! author : Ragnar Johannesen : https://github.com/ragnar123\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\n\nvar fo = moment.defineLocale('fo', {\n    months : 'januar_februar_mars_apríl_mai_juni_juli_august_september_oktober_november_desember'.split('_'),\n    monthsShort : 'jan_feb_mar_apr_mai_jun_jul_aug_sep_okt_nov_des'.split('_'),\n    weekdays : 'sunnudagur_mánadagur_týsdagur_mikudagur_hósdagur_fríggjadagur_leygardagur'.split('_'),\n    weekdaysShort : 'sun_mán_týs_mik_hós_frí_ley'.split('_'),\n    weekdaysMin : 'su_má_tý_mi_hó_fr_le'.split('_'),\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY HH:mm',\n        LLLL : 'dddd D. MMMM, YYYY HH:mm'\n    },\n    calendar : {\n        sameDay : '[Í dag kl.] LT',\n        nextDay : '[Í morgin kl.] LT',\n        nextWeek : 'dddd [kl.] LT',\n        lastDay : '[Í gjár kl.] LT',\n        lastWeek : '[síðstu] dddd [kl] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'um %s',\n        past : '%s síðani',\n        s : 'fá sekund',\n        m : 'ein minutt',\n        mm : '%d minuttir',\n        h : 'ein tími',\n        hh : '%d tímar',\n        d : 'ein dagur',\n        dd : '%d dagar',\n        M : 'ein mánaði',\n        MM : '%d mánaðir',\n        y : 'eitt ár',\n        yy : '%d ár'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}\\./,\n    ordinal : '%d.',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\nreturn fo;\n\n})));\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/locale/fr-ca.js",
    "content": "//! moment.js locale configuration\n//! locale : French (Canada) [fr-ca]\n//! author : Jonathan Abourbih : https://github.com/jonbca\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\n\nvar frCa = moment.defineLocale('fr-ca', {\n    months : 'janvier_février_mars_avril_mai_juin_juillet_août_septembre_octobre_novembre_décembre'.split('_'),\n    monthsShort : 'janv._févr._mars_avr._mai_juin_juil._août_sept._oct._nov._déc.'.split('_'),\n    monthsParseExact : true,\n    weekdays : 'dimanche_lundi_mardi_mercredi_jeudi_vendredi_samedi'.split('_'),\n    weekdaysShort : 'dim._lun._mar._mer._jeu._ven._sam.'.split('_'),\n    weekdaysMin : 'Di_Lu_Ma_Me_Je_Ve_Sa'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'YYYY-MM-DD',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY HH:mm',\n        LLLL : 'dddd D MMMM YYYY HH:mm'\n    },\n    calendar : {\n        sameDay : '[Aujourd’hui à] LT',\n        nextDay : '[Demain à] LT',\n        nextWeek : 'dddd [à] LT',\n        lastDay : '[Hier à] LT',\n        lastWeek : 'dddd [dernier à] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'dans %s',\n        past : 'il y a %s',\n        s : 'quelques secondes',\n        m : 'une minute',\n        mm : '%d minutes',\n        h : 'une heure',\n        hh : '%d heures',\n        d : 'un jour',\n        dd : '%d jours',\n        M : 'un mois',\n        MM : '%d mois',\n        y : 'un an',\n        yy : '%d ans'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}(er|e)/,\n    ordinal : function (number, period) {\n        switch (period) {\n            // Words with masculine grammatical gender: mois, trimestre, jour\n            default:\n            case 'M':\n            case 'Q':\n            case 'D':\n            case 'DDD':\n            case 'd':\n                return number + (number === 1 ? 'er' : 'e');\n\n            // Words with feminine grammatical gender: semaine\n            case 'w':\n            case 'W':\n                return number + (number === 1 ? 're' : 'e');\n        }\n    }\n});\n\nreturn frCa;\n\n})));\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/locale/fr-ch.js",
    "content": "//! moment.js locale configuration\n//! locale : French (Switzerland) [fr-ch]\n//! author : Gaspard Bucher : https://github.com/gaspard\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\n\nvar frCh = moment.defineLocale('fr-ch', {\n    months : 'janvier_février_mars_avril_mai_juin_juillet_août_septembre_octobre_novembre_décembre'.split('_'),\n    monthsShort : 'janv._févr._mars_avr._mai_juin_juil._août_sept._oct._nov._déc.'.split('_'),\n    monthsParseExact : true,\n    weekdays : 'dimanche_lundi_mardi_mercredi_jeudi_vendredi_samedi'.split('_'),\n    weekdaysShort : 'dim._lun._mar._mer._jeu._ven._sam.'.split('_'),\n    weekdaysMin : 'Di_Lu_Ma_Me_Je_Ve_Sa'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD.MM.YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY HH:mm',\n        LLLL : 'dddd D MMMM YYYY HH:mm'\n    },\n    calendar : {\n        sameDay : '[Aujourd’hui à] LT',\n        nextDay : '[Demain à] LT',\n        nextWeek : 'dddd [à] LT',\n        lastDay : '[Hier à] LT',\n        lastWeek : 'dddd [dernier à] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'dans %s',\n        past : 'il y a %s',\n        s : 'quelques secondes',\n        m : 'une minute',\n        mm : '%d minutes',\n        h : 'une heure',\n        hh : '%d heures',\n        d : 'un jour',\n        dd : '%d jours',\n        M : 'un mois',\n        MM : '%d mois',\n        y : 'un an',\n        yy : '%d ans'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}(er|e)/,\n    ordinal : function (number, period) {\n        switch (period) {\n            // Words with masculine grammatical gender: mois, trimestre, jour\n            default:\n            case 'M':\n            case 'Q':\n            case 'D':\n            case 'DDD':\n            case 'd':\n                return number + (number === 1 ? 'er' : 'e');\n\n            // Words with feminine grammatical gender: semaine\n            case 'w':\n            case 'W':\n                return number + (number === 1 ? 're' : 'e');\n        }\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\nreturn frCh;\n\n})));\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/locale/fr.js",
    "content": "//! moment.js locale configuration\n//! locale : French [fr]\n//! author : John Fischer : https://github.com/jfroffice\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\n\nvar fr = moment.defineLocale('fr', {\n    months : 'janvier_février_mars_avril_mai_juin_juillet_août_septembre_octobre_novembre_décembre'.split('_'),\n    monthsShort : 'janv._févr._mars_avr._mai_juin_juil._août_sept._oct._nov._déc.'.split('_'),\n    monthsParseExact : true,\n    weekdays : 'dimanche_lundi_mardi_mercredi_jeudi_vendredi_samedi'.split('_'),\n    weekdaysShort : 'dim._lun._mar._mer._jeu._ven._sam.'.split('_'),\n    weekdaysMin : 'Di_Lu_Ma_Me_Je_Ve_Sa'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY HH:mm',\n        LLLL : 'dddd D MMMM YYYY HH:mm'\n    },\n    calendar : {\n        sameDay : '[Aujourd’hui à] LT',\n        nextDay : '[Demain à] LT',\n        nextWeek : 'dddd [à] LT',\n        lastDay : '[Hier à] LT',\n        lastWeek : 'dddd [dernier à] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'dans %s',\n        past : 'il y a %s',\n        s : 'quelques secondes',\n        m : 'une minute',\n        mm : '%d minutes',\n        h : 'une heure',\n        hh : '%d heures',\n        d : 'un jour',\n        dd : '%d jours',\n        M : 'un mois',\n        MM : '%d mois',\n        y : 'un an',\n        yy : '%d ans'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}(er|)/,\n    ordinal : function (number, period) {\n        switch (period) {\n            // TODO: Return 'e' when day of month > 1. Move this case inside\n            // block for masculine words below.\n            // See https://github.com/moment/moment/issues/3375\n            case 'D':\n                return number + (number === 1 ? 'er' : '');\n\n            // Words with masculine grammatical gender: mois, trimestre, jour\n            default:\n            case 'M':\n            case 'Q':\n            case 'DDD':\n            case 'd':\n                return number + (number === 1 ? 'er' : 'e');\n\n            // Words with feminine grammatical gender: semaine\n            case 'w':\n            case 'W':\n                return number + (number === 1 ? 're' : 'e');\n        }\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\nreturn fr;\n\n})));\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/locale/fy.js",
    "content": "//! moment.js locale configuration\n//! locale : Frisian [fy]\n//! author : Robin van der Vliet : https://github.com/robin0van0der0v\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\n\nvar monthsShortWithDots = 'jan._feb._mrt._apr._mai_jun._jul._aug._sep._okt._nov._des.'.split('_');\nvar monthsShortWithoutDots = 'jan_feb_mrt_apr_mai_jun_jul_aug_sep_okt_nov_des'.split('_');\n\nvar fy = moment.defineLocale('fy', {\n    months : 'jannewaris_febrewaris_maart_april_maaie_juny_july_augustus_septimber_oktober_novimber_desimber'.split('_'),\n    monthsShort : function (m, format) {\n        if (!m) {\n            return monthsShortWithDots;\n        } else if (/-MMM-/.test(format)) {\n            return monthsShortWithoutDots[m.month()];\n        } else {\n            return monthsShortWithDots[m.month()];\n        }\n    },\n    monthsParseExact : true,\n    weekdays : 'snein_moandei_tiisdei_woansdei_tongersdei_freed_sneon'.split('_'),\n    weekdaysShort : 'si._mo._ti._wo._to._fr._so.'.split('_'),\n    weekdaysMin : 'Si_Mo_Ti_Wo_To_Fr_So'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD-MM-YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY HH:mm',\n        LLLL : 'dddd D MMMM YYYY HH:mm'\n    },\n    calendar : {\n        sameDay: '[hjoed om] LT',\n        nextDay: '[moarn om] LT',\n        nextWeek: 'dddd [om] LT',\n        lastDay: '[juster om] LT',\n        lastWeek: '[ôfrûne] dddd [om] LT',\n        sameElse: 'L'\n    },\n    relativeTime : {\n        future : 'oer %s',\n        past : '%s lyn',\n        s : 'in pear sekonden',\n        m : 'ien minút',\n        mm : '%d minuten',\n        h : 'ien oere',\n        hh : '%d oeren',\n        d : 'ien dei',\n        dd : '%d dagen',\n        M : 'ien moanne',\n        MM : '%d moannen',\n        y : 'ien jier',\n        yy : '%d jierren'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}(ste|de)/,\n    ordinal : function (number) {\n        return number + ((number === 1 || number === 8 || number >= 20) ? 'ste' : 'de');\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\nreturn fy;\n\n})));\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/locale/gd.js",
    "content": "//! moment.js locale configuration\n//! locale : Scottish Gaelic [gd]\n//! author : Jon Ashdown : https://github.com/jonashdown\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\n\nvar months = [\n    'Am Faoilleach', 'An Gearran', 'Am Màrt', 'An Giblean', 'An Cèitean', 'An t-Ògmhios', 'An t-Iuchar', 'An Lùnastal', 'An t-Sultain', 'An Dàmhair', 'An t-Samhain', 'An Dùbhlachd'\n];\n\nvar monthsShort = ['Faoi', 'Gear', 'Màrt', 'Gibl', 'Cèit', 'Ògmh', 'Iuch', 'Lùn', 'Sult', 'Dàmh', 'Samh', 'Dùbh'];\n\nvar weekdays = ['Didòmhnaich', 'Diluain', 'Dimàirt', 'Diciadain', 'Diardaoin', 'Dihaoine', 'Disathairne'];\n\nvar weekdaysShort = ['Did', 'Dil', 'Dim', 'Dic', 'Dia', 'Dih', 'Dis'];\n\nvar weekdaysMin = ['Dò', 'Lu', 'Mà', 'Ci', 'Ar', 'Ha', 'Sa'];\n\nvar gd = moment.defineLocale('gd', {\n    months : months,\n    monthsShort : monthsShort,\n    monthsParseExact : true,\n    weekdays : weekdays,\n    weekdaysShort : weekdaysShort,\n    weekdaysMin : weekdaysMin,\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY HH:mm',\n        LLLL : 'dddd, D MMMM YYYY HH:mm'\n    },\n    calendar : {\n        sameDay : '[An-diugh aig] LT',\n        nextDay : '[A-màireach aig] LT',\n        nextWeek : 'dddd [aig] LT',\n        lastDay : '[An-dè aig] LT',\n        lastWeek : 'dddd [seo chaidh] [aig] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'ann an %s',\n        past : 'bho chionn %s',\n        s : 'beagan diogan',\n        m : 'mionaid',\n        mm : '%d mionaidean',\n        h : 'uair',\n        hh : '%d uairean',\n        d : 'latha',\n        dd : '%d latha',\n        M : 'mìos',\n        MM : '%d mìosan',\n        y : 'bliadhna',\n        yy : '%d bliadhna'\n    },\n    dayOfMonthOrdinalParse : /\\d{1,2}(d|na|mh)/,\n    ordinal : function (number) {\n        var output = number === 1 ? 'd' : number % 10 === 2 ? 'na' : 'mh';\n        return number + output;\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\nreturn gd;\n\n})));\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/locale/gl.js",
    "content": "//! moment.js locale configuration\n//! locale : Galician [gl]\n//! author : Juan G. Hurtado : https://github.com/juanghurtado\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\n\nvar gl = moment.defineLocale('gl', {\n    months : 'xaneiro_febreiro_marzo_abril_maio_xuño_xullo_agosto_setembro_outubro_novembro_decembro'.split('_'),\n    monthsShort : 'xan._feb._mar._abr._mai._xuñ._xul._ago._set._out._nov._dec.'.split('_'),\n    monthsParseExact: true,\n    weekdays : 'domingo_luns_martes_mércores_xoves_venres_sábado'.split('_'),\n    weekdaysShort : 'dom._lun._mar._mér._xov._ven._sáb.'.split('_'),\n    weekdaysMin : 'do_lu_ma_mé_xo_ve_sá'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat : {\n        LT : 'H:mm',\n        LTS : 'H:mm:ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D [de] MMMM [de] YYYY',\n        LLL : 'D [de] MMMM [de] YYYY H:mm',\n        LLLL : 'dddd, D [de] MMMM [de] YYYY H:mm'\n    },\n    calendar : {\n        sameDay : function () {\n            return '[hoxe ' + ((this.hours() !== 1) ? 'ás' : 'á') + '] LT';\n        },\n        nextDay : function () {\n            return '[mañá ' + ((this.hours() !== 1) ? 'ás' : 'á') + '] LT';\n        },\n        nextWeek : function () {\n            return 'dddd [' + ((this.hours() !== 1) ? 'ás' : 'a') + '] LT';\n        },\n        lastDay : function () {\n            return '[onte ' + ((this.hours() !== 1) ? 'á' : 'a') + '] LT';\n        },\n        lastWeek : function () {\n            return '[o] dddd [pasado ' + ((this.hours() !== 1) ? 'ás' : 'a') + '] LT';\n        },\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : function (str) {\n            if (str.indexOf('un') === 0) {\n                return 'n' + str;\n            }\n            return 'en ' + str;\n        },\n        past : 'hai %s',\n        s : 'uns segundos',\n        m : 'un minuto',\n        mm : '%d minutos',\n        h : 'unha hora',\n        hh : '%d horas',\n        d : 'un día',\n        dd : '%d días',\n        M : 'un mes',\n        MM : '%d meses',\n        y : 'un ano',\n        yy : '%d anos'\n    },\n    dayOfMonthOrdinalParse : /\\d{1,2}º/,\n    ordinal : '%dº',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\nreturn gl;\n\n})));\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/locale/gom-latn.js",
    "content": "//! moment.js locale configuration\n//! locale : Konkani Latin script [gom-latn]\n//! author : The Discoverer : https://github.com/WikiDiscoverer\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\n\nfunction processRelativeTime(number, withoutSuffix, key, isFuture) {\n    var format = {\n        's': ['thodde secondanim', 'thodde second'],\n        'm': ['eka mintan', 'ek minute'],\n        'mm': [number + ' mintanim', number + ' mintam'],\n        'h': ['eka horan', 'ek hor'],\n        'hh': [number + ' horanim', number + ' hor'],\n        'd': ['eka disan', 'ek dis'],\n        'dd': [number + ' disanim', number + ' dis'],\n        'M': ['eka mhoinean', 'ek mhoino'],\n        'MM': [number + ' mhoineanim', number + ' mhoine'],\n        'y': ['eka vorsan', 'ek voros'],\n        'yy': [number + ' vorsanim', number + ' vorsam']\n    };\n    return withoutSuffix ? format[key][0] : format[key][1];\n}\n\nvar gomLatn = moment.defineLocale('gom-latn', {\n    months : 'Janer_Febrer_Mars_Abril_Mai_Jun_Julai_Agost_Setembr_Otubr_Novembr_Dezembr'.split('_'),\n    monthsShort : 'Jan._Feb._Mars_Abr._Mai_Jun_Jul._Ago._Set._Otu._Nov._Dez.'.split('_'),\n    monthsParseExact : true,\n    weekdays : 'Aitar_Somar_Mongllar_Budvar_Brestar_Sukrar_Son\\'var'.split('_'),\n    weekdaysShort : 'Ait._Som._Mon._Bud._Bre._Suk._Son.'.split('_'),\n    weekdaysMin : 'Ai_Sm_Mo_Bu_Br_Su_Sn'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat : {\n        LT : 'A h:mm [vazta]',\n        LTS : 'A h:mm:ss [vazta]',\n        L : 'DD-MM-YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY A h:mm [vazta]',\n        LLLL : 'dddd, MMMM[achea] Do, YYYY, A h:mm [vazta]',\n        llll: 'ddd, D MMM YYYY, A h:mm [vazta]'\n    },\n    calendar : {\n        sameDay: '[Aiz] LT',\n        nextDay: '[Faleam] LT',\n        nextWeek: '[Ieta to] dddd[,] LT',\n        lastDay: '[Kal] LT',\n        lastWeek: '[Fatlo] dddd[,] LT',\n        sameElse: 'L'\n    },\n    relativeTime : {\n        future : '%s',\n        past : '%s adim',\n        s : processRelativeTime,\n        m : processRelativeTime,\n        mm : processRelativeTime,\n        h : processRelativeTime,\n        hh : processRelativeTime,\n        d : processRelativeTime,\n        dd : processRelativeTime,\n        M : processRelativeTime,\n        MM : processRelativeTime,\n        y : processRelativeTime,\n        yy : processRelativeTime\n    },\n    dayOfMonthOrdinalParse : /\\d{1,2}(er)/,\n    ordinal : function (number, period) {\n        switch (period) {\n            // the ordinal 'er' only applies to day of the month\n            case 'D':\n                return number + 'er';\n            default:\n            case 'M':\n            case 'Q':\n            case 'DDD':\n            case 'd':\n            case 'w':\n            case 'W':\n                return number;\n        }\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    },\n    meridiemParse: /rati|sokalli|donparam|sanje/,\n    meridiemHour : function (hour, meridiem) {\n        if (hour === 12) {\n            hour = 0;\n        }\n        if (meridiem === 'rati') {\n            return hour < 4 ? hour : hour + 12;\n        } else if (meridiem === 'sokalli') {\n            return hour;\n        } else if (meridiem === 'donparam') {\n            return hour > 12 ? hour : hour + 12;\n        } else if (meridiem === 'sanje') {\n            return hour + 12;\n        }\n    },\n    meridiem : function (hour, minute, isLower) {\n        if (hour < 4) {\n            return 'rati';\n        } else if (hour < 12) {\n            return 'sokalli';\n        } else if (hour < 16) {\n            return 'donparam';\n        } else if (hour < 20) {\n            return 'sanje';\n        } else {\n            return 'rati';\n        }\n    }\n});\n\nreturn gomLatn;\n\n})));\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/locale/he.js",
    "content": "//! moment.js locale configuration\n//! locale : Hebrew [he]\n//! author : Tomer Cohen : https://github.com/tomer\n//! author : Moshe Simantov : https://github.com/DevelopmentIL\n//! author : Tal Ater : https://github.com/TalAter\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\n\nvar he = moment.defineLocale('he', {\n    months : 'ינואר_פברואר_מרץ_אפריל_מאי_יוני_יולי_אוגוסט_ספטמבר_אוקטובר_נובמבר_דצמבר'.split('_'),\n    monthsShort : 'ינו׳_פבר׳_מרץ_אפר׳_מאי_יוני_יולי_אוג׳_ספט׳_אוק׳_נוב׳_דצמ׳'.split('_'),\n    weekdays : 'ראשון_שני_שלישי_רביעי_חמישי_שישי_שבת'.split('_'),\n    weekdaysShort : 'א׳_ב׳_ג׳_ד׳_ה׳_ו׳_ש׳'.split('_'),\n    weekdaysMin : 'א_ב_ג_ד_ה_ו_ש'.split('_'),\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D [ב]MMMM YYYY',\n        LLL : 'D [ב]MMMM YYYY HH:mm',\n        LLLL : 'dddd, D [ב]MMMM YYYY HH:mm',\n        l : 'D/M/YYYY',\n        ll : 'D MMM YYYY',\n        lll : 'D MMM YYYY HH:mm',\n        llll : 'ddd, D MMM YYYY HH:mm'\n    },\n    calendar : {\n        sameDay : '[היום ב־]LT',\n        nextDay : '[מחר ב־]LT',\n        nextWeek : 'dddd [בשעה] LT',\n        lastDay : '[אתמול ב־]LT',\n        lastWeek : '[ביום] dddd [האחרון בשעה] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'בעוד %s',\n        past : 'לפני %s',\n        s : 'מספר שניות',\n        m : 'דקה',\n        mm : '%d דקות',\n        h : 'שעה',\n        hh : function (number) {\n            if (number === 2) {\n                return 'שעתיים';\n            }\n            return number + ' שעות';\n        },\n        d : 'יום',\n        dd : function (number) {\n            if (number === 2) {\n                return 'יומיים';\n            }\n            return number + ' ימים';\n        },\n        M : 'חודש',\n        MM : function (number) {\n            if (number === 2) {\n                return 'חודשיים';\n            }\n            return number + ' חודשים';\n        },\n        y : 'שנה',\n        yy : function (number) {\n            if (number === 2) {\n                return 'שנתיים';\n            } else if (number % 10 === 0 && number !== 10) {\n                return number + ' שנה';\n            }\n            return number + ' שנים';\n        }\n    },\n    meridiemParse: /אחה\"צ|לפנה\"צ|אחרי הצהריים|לפני הצהריים|לפנות בוקר|בבוקר|בערב/i,\n    isPM : function (input) {\n        return /^(אחה\"צ|אחרי הצהריים|בערב)$/.test(input);\n    },\n    meridiem : function (hour, minute, isLower) {\n        if (hour < 5) {\n            return 'לפנות בוקר';\n        } else if (hour < 10) {\n            return 'בבוקר';\n        } else if (hour < 12) {\n            return isLower ? 'לפנה\"צ' : 'לפני הצהריים';\n        } else if (hour < 18) {\n            return isLower ? 'אחה\"צ' : 'אחרי הצהריים';\n        } else {\n            return 'בערב';\n        }\n    }\n});\n\nreturn he;\n\n})));\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/locale/hi.js",
    "content": "//! moment.js locale configuration\n//! locale : Hindi [hi]\n//! author : Mayank Singhal : https://github.com/mayanksinghal\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\n\nvar symbolMap = {\n    '1': '१',\n    '2': '२',\n    '3': '३',\n    '4': '४',\n    '5': '५',\n    '6': '६',\n    '7': '७',\n    '8': '८',\n    '9': '९',\n    '0': '०'\n};\nvar numberMap = {\n    '१': '1',\n    '२': '2',\n    '३': '3',\n    '४': '4',\n    '५': '5',\n    '६': '6',\n    '७': '7',\n    '८': '8',\n    '९': '9',\n    '०': '0'\n};\n\nvar hi = moment.defineLocale('hi', {\n    months : 'जनवरी_फ़रवरी_मार्च_अप्रैल_मई_जून_जुलाई_अगस्त_सितम्बर_अक्टूबर_नवम्बर_दिसम्बर'.split('_'),\n    monthsShort : 'जन._फ़र._मार्च_अप्रै._मई_जून_जुल._अग._सित._अक्टू._नव._दिस.'.split('_'),\n    monthsParseExact: true,\n    weekdays : 'रविवार_सोमवार_मंगलवार_बुधवार_गुरूवार_शुक्रवार_शनिवार'.split('_'),\n    weekdaysShort : 'रवि_सोम_मंगल_बुध_गुरू_शुक्र_शनि'.split('_'),\n    weekdaysMin : 'र_सो_मं_बु_गु_शु_श'.split('_'),\n    longDateFormat : {\n        LT : 'A h:mm बजे',\n        LTS : 'A h:mm:ss बजे',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY, A h:mm बजे',\n        LLLL : 'dddd, D MMMM YYYY, A h:mm बजे'\n    },\n    calendar : {\n        sameDay : '[आज] LT',\n        nextDay : '[कल] LT',\n        nextWeek : 'dddd, LT',\n        lastDay : '[कल] LT',\n        lastWeek : '[पिछले] dddd, LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : '%s में',\n        past : '%s पहले',\n        s : 'कुछ ही क्षण',\n        m : 'एक मिनट',\n        mm : '%d मिनट',\n        h : 'एक घंटा',\n        hh : '%d घंटे',\n        d : 'एक दिन',\n        dd : '%d दिन',\n        M : 'एक महीने',\n        MM : '%d महीने',\n        y : 'एक वर्ष',\n        yy : '%d वर्ष'\n    },\n    preparse: function (string) {\n        return string.replace(/[१२३४५६७८९०]/g, function (match) {\n            return numberMap[match];\n        });\n    },\n    postformat: function (string) {\n        return string.replace(/\\d/g, function (match) {\n            return symbolMap[match];\n        });\n    },\n    // Hindi notation for meridiems are quite fuzzy in practice. While there exists\n    // a rigid notion of a 'Pahar' it is not used as rigidly in modern Hindi.\n    meridiemParse: /रात|सुबह|दोपहर|शाम/,\n    meridiemHour : function (hour, meridiem) {\n        if (hour === 12) {\n            hour = 0;\n        }\n        if (meridiem === 'रात') {\n            return hour < 4 ? hour : hour + 12;\n        } else if (meridiem === 'सुबह') {\n            return hour;\n        } else if (meridiem === 'दोपहर') {\n            return hour >= 10 ? hour : hour + 12;\n        } else if (meridiem === 'शाम') {\n            return hour + 12;\n        }\n    },\n    meridiem : function (hour, minute, isLower) {\n        if (hour < 4) {\n            return 'रात';\n        } else if (hour < 10) {\n            return 'सुबह';\n        } else if (hour < 17) {\n            return 'दोपहर';\n        } else if (hour < 20) {\n            return 'शाम';\n        } else {\n            return 'रात';\n        }\n    },\n    week : {\n        dow : 0, // Sunday is the first day of the week.\n        doy : 6  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\nreturn hi;\n\n})));\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/locale/hr.js",
    "content": "//! moment.js locale configuration\n//! locale : Croatian [hr]\n//! author : Bojan Marković : https://github.com/bmarkovic\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\n\nfunction translate(number, withoutSuffix, key) {\n    var result = number + ' ';\n    switch (key) {\n        case 'm':\n            return withoutSuffix ? 'jedna minuta' : 'jedne minute';\n        case 'mm':\n            if (number === 1) {\n                result += 'minuta';\n            } else if (number === 2 || number === 3 || number === 4) {\n                result += 'minute';\n            } else {\n                result += 'minuta';\n            }\n            return result;\n        case 'h':\n            return withoutSuffix ? 'jedan sat' : 'jednog sata';\n        case 'hh':\n            if (number === 1) {\n                result += 'sat';\n            } else if (number === 2 || number === 3 || number === 4) {\n                result += 'sata';\n            } else {\n                result += 'sati';\n            }\n            return result;\n        case 'dd':\n            if (number === 1) {\n                result += 'dan';\n            } else {\n                result += 'dana';\n            }\n            return result;\n        case 'MM':\n            if (number === 1) {\n                result += 'mjesec';\n            } else if (number === 2 || number === 3 || number === 4) {\n                result += 'mjeseca';\n            } else {\n                result += 'mjeseci';\n            }\n            return result;\n        case 'yy':\n            if (number === 1) {\n                result += 'godina';\n            } else if (number === 2 || number === 3 || number === 4) {\n                result += 'godine';\n            } else {\n                result += 'godina';\n            }\n            return result;\n    }\n}\n\nvar hr = moment.defineLocale('hr', {\n    months : {\n        format: 'siječnja_veljače_ožujka_travnja_svibnja_lipnja_srpnja_kolovoza_rujna_listopada_studenoga_prosinca'.split('_'),\n        standalone: 'siječanj_veljača_ožujak_travanj_svibanj_lipanj_srpanj_kolovoz_rujan_listopad_studeni_prosinac'.split('_')\n    },\n    monthsShort : 'sij._velj._ožu._tra._svi._lip._srp._kol._ruj._lis._stu._pro.'.split('_'),\n    monthsParseExact: true,\n    weekdays : 'nedjelja_ponedjeljak_utorak_srijeda_četvrtak_petak_subota'.split('_'),\n    weekdaysShort : 'ned._pon._uto._sri._čet._pet._sub.'.split('_'),\n    weekdaysMin : 'ne_po_ut_sr_če_pe_su'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat : {\n        LT : 'H:mm',\n        LTS : 'H:mm:ss',\n        L : 'DD.MM.YYYY',\n        LL : 'D. MMMM YYYY',\n        LLL : 'D. MMMM YYYY H:mm',\n        LLLL : 'dddd, D. MMMM YYYY H:mm'\n    },\n    calendar : {\n        sameDay  : '[danas u] LT',\n        nextDay  : '[sutra u] LT',\n        nextWeek : function () {\n            switch (this.day()) {\n                case 0:\n                    return '[u] [nedjelju] [u] LT';\n                case 3:\n                    return '[u] [srijedu] [u] LT';\n                case 6:\n                    return '[u] [subotu] [u] LT';\n                case 1:\n                case 2:\n                case 4:\n                case 5:\n                    return '[u] dddd [u] LT';\n            }\n        },\n        lastDay  : '[jučer u] LT',\n        lastWeek : function () {\n            switch (this.day()) {\n                case 0:\n                case 3:\n                    return '[prošlu] dddd [u] LT';\n                case 6:\n                    return '[prošle] [subote] [u] LT';\n                case 1:\n                case 2:\n                case 4:\n                case 5:\n                    return '[prošli] dddd [u] LT';\n            }\n        },\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'za %s',\n        past   : 'prije %s',\n        s      : 'par sekundi',\n        m      : translate,\n        mm     : translate,\n        h      : translate,\n        hh     : translate,\n        d      : 'dan',\n        dd     : translate,\n        M      : 'mjesec',\n        MM     : translate,\n        y      : 'godinu',\n        yy     : translate\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}\\./,\n    ordinal : '%d.',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 7  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\nreturn hr;\n\n})));\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/locale/hu.js",
    "content": "//! moment.js locale configuration\n//! locale : Hungarian [hu]\n//! author : Adam Brunner : https://github.com/adambrunner\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\n\nvar weekEndings = 'vasárnap hétfőn kedden szerdán csütörtökön pénteken szombaton'.split(' ');\nfunction translate(number, withoutSuffix, key, isFuture) {\n    var num = number,\n        suffix;\n    switch (key) {\n        case 's':\n            return (isFuture || withoutSuffix) ? 'néhány másodperc' : 'néhány másodperce';\n        case 'm':\n            return 'egy' + (isFuture || withoutSuffix ? ' perc' : ' perce');\n        case 'mm':\n            return num + (isFuture || withoutSuffix ? ' perc' : ' perce');\n        case 'h':\n            return 'egy' + (isFuture || withoutSuffix ? ' óra' : ' órája');\n        case 'hh':\n            return num + (isFuture || withoutSuffix ? ' óra' : ' órája');\n        case 'd':\n            return 'egy' + (isFuture || withoutSuffix ? ' nap' : ' napja');\n        case 'dd':\n            return num + (isFuture || withoutSuffix ? ' nap' : ' napja');\n        case 'M':\n            return 'egy' + (isFuture || withoutSuffix ? ' hónap' : ' hónapja');\n        case 'MM':\n            return num + (isFuture || withoutSuffix ? ' hónap' : ' hónapja');\n        case 'y':\n            return 'egy' + (isFuture || withoutSuffix ? ' év' : ' éve');\n        case 'yy':\n            return num + (isFuture || withoutSuffix ? ' év' : ' éve');\n    }\n    return '';\n}\nfunction week(isFuture) {\n    return (isFuture ? '' : '[múlt] ') + '[' + weekEndings[this.day()] + '] LT[-kor]';\n}\n\nvar hu = moment.defineLocale('hu', {\n    months : 'január_február_március_április_május_június_július_augusztus_szeptember_október_november_december'.split('_'),\n    monthsShort : 'jan_feb_márc_ápr_máj_jún_júl_aug_szept_okt_nov_dec'.split('_'),\n    weekdays : 'vasárnap_hétfő_kedd_szerda_csütörtök_péntek_szombat'.split('_'),\n    weekdaysShort : 'vas_hét_kedd_sze_csüt_pén_szo'.split('_'),\n    weekdaysMin : 'v_h_k_sze_cs_p_szo'.split('_'),\n    longDateFormat : {\n        LT : 'H:mm',\n        LTS : 'H:mm:ss',\n        L : 'YYYY.MM.DD.',\n        LL : 'YYYY. MMMM D.',\n        LLL : 'YYYY. MMMM D. H:mm',\n        LLLL : 'YYYY. MMMM D., dddd H:mm'\n    },\n    meridiemParse: /de|du/i,\n    isPM: function (input) {\n        return input.charAt(1).toLowerCase() === 'u';\n    },\n    meridiem : function (hours, minutes, isLower) {\n        if (hours < 12) {\n            return isLower === true ? 'de' : 'DE';\n        } else {\n            return isLower === true ? 'du' : 'DU';\n        }\n    },\n    calendar : {\n        sameDay : '[ma] LT[-kor]',\n        nextDay : '[holnap] LT[-kor]',\n        nextWeek : function () {\n            return week.call(this, true);\n        },\n        lastDay : '[tegnap] LT[-kor]',\n        lastWeek : function () {\n            return week.call(this, false);\n        },\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : '%s múlva',\n        past : '%s',\n        s : translate,\n        m : translate,\n        mm : translate,\n        h : translate,\n        hh : translate,\n        d : translate,\n        dd : translate,\n        M : translate,\n        MM : translate,\n        y : translate,\n        yy : translate\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}\\./,\n    ordinal : '%d.',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\nreturn hu;\n\n})));\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/locale/hy-am.js",
    "content": "//! moment.js locale configuration\n//! locale : Armenian [hy-am]\n//! author : Armendarabyan : https://github.com/armendarabyan\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\n\nvar hyAm = moment.defineLocale('hy-am', {\n    months : {\n        format: 'հունվարի_փետրվարի_մարտի_ապրիլի_մայիսի_հունիսի_հուլիսի_օգոստոսի_սեպտեմբերի_հոկտեմբերի_նոյեմբերի_դեկտեմբերի'.split('_'),\n        standalone: 'հունվար_փետրվար_մարտ_ապրիլ_մայիս_հունիս_հուլիս_օգոստոս_սեպտեմբեր_հոկտեմբեր_նոյեմբեր_դեկտեմբեր'.split('_')\n    },\n    monthsShort : 'հնվ_փտր_մրտ_ապր_մյս_հնս_հլս_օգս_սպտ_հկտ_նմբ_դկտ'.split('_'),\n    weekdays : 'կիրակի_երկուշաբթի_երեքշաբթի_չորեքշաբթի_հինգշաբթի_ուրբաթ_շաբաթ'.split('_'),\n    weekdaysShort : 'կրկ_երկ_երք_չրք_հնգ_ուրբ_շբթ'.split('_'),\n    weekdaysMin : 'կրկ_երկ_երք_չրք_հնգ_ուրբ_շբթ'.split('_'),\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD.MM.YYYY',\n        LL : 'D MMMM YYYY թ.',\n        LLL : 'D MMMM YYYY թ., HH:mm',\n        LLLL : 'dddd, D MMMM YYYY թ., HH:mm'\n    },\n    calendar : {\n        sameDay: '[այսօր] LT',\n        nextDay: '[վաղը] LT',\n        lastDay: '[երեկ] LT',\n        nextWeek: function () {\n            return 'dddd [օրը ժամը] LT';\n        },\n        lastWeek: function () {\n            return '[անցած] dddd [օրը ժամը] LT';\n        },\n        sameElse: 'L'\n    },\n    relativeTime : {\n        future : '%s հետո',\n        past : '%s առաջ',\n        s : 'մի քանի վայրկյան',\n        m : 'րոպե',\n        mm : '%d րոպե',\n        h : 'ժամ',\n        hh : '%d ժամ',\n        d : 'օր',\n        dd : '%d օր',\n        M : 'ամիս',\n        MM : '%d ամիս',\n        y : 'տարի',\n        yy : '%d տարի'\n    },\n    meridiemParse: /գիշերվա|առավոտվա|ցերեկվա|երեկոյան/,\n    isPM: function (input) {\n        return /^(ցերեկվա|երեկոյան)$/.test(input);\n    },\n    meridiem : function (hour) {\n        if (hour < 4) {\n            return 'գիշերվա';\n        } else if (hour < 12) {\n            return 'առավոտվա';\n        } else if (hour < 17) {\n            return 'ցերեկվա';\n        } else {\n            return 'երեկոյան';\n        }\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}|\\d{1,2}-(ին|րդ)/,\n    ordinal: function (number, period) {\n        switch (period) {\n            case 'DDD':\n            case 'w':\n            case 'W':\n            case 'DDDo':\n                if (number === 1) {\n                    return number + '-ին';\n                }\n                return number + '-րդ';\n            default:\n                return number;\n        }\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 7  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\nreturn hyAm;\n\n})));\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/locale/id.js",
    "content": "//! moment.js locale configuration\n//! locale : Indonesian [id]\n//! author : Mohammad Satrio Utomo : https://github.com/tyok\n//! reference: http://id.wikisource.org/wiki/Pedoman_Umum_Ejaan_Bahasa_Indonesia_yang_Disempurnakan\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\n\nvar id = moment.defineLocale('id', {\n    months : 'Januari_Februari_Maret_April_Mei_Juni_Juli_Agustus_September_Oktober_November_Desember'.split('_'),\n    monthsShort : 'Jan_Feb_Mar_Apr_Mei_Jun_Jul_Ags_Sep_Okt_Nov_Des'.split('_'),\n    weekdays : 'Minggu_Senin_Selasa_Rabu_Kamis_Jumat_Sabtu'.split('_'),\n    weekdaysShort : 'Min_Sen_Sel_Rab_Kam_Jum_Sab'.split('_'),\n    weekdaysMin : 'Mg_Sn_Sl_Rb_Km_Jm_Sb'.split('_'),\n    longDateFormat : {\n        LT : 'HH.mm',\n        LTS : 'HH.mm.ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY [pukul] HH.mm',\n        LLLL : 'dddd, D MMMM YYYY [pukul] HH.mm'\n    },\n    meridiemParse: /pagi|siang|sore|malam/,\n    meridiemHour : function (hour, meridiem) {\n        if (hour === 12) {\n            hour = 0;\n        }\n        if (meridiem === 'pagi') {\n            return hour;\n        } else if (meridiem === 'siang') {\n            return hour >= 11 ? hour : hour + 12;\n        } else if (meridiem === 'sore' || meridiem === 'malam') {\n            return hour + 12;\n        }\n    },\n    meridiem : function (hours, minutes, isLower) {\n        if (hours < 11) {\n            return 'pagi';\n        } else if (hours < 15) {\n            return 'siang';\n        } else if (hours < 19) {\n            return 'sore';\n        } else {\n            return 'malam';\n        }\n    },\n    calendar : {\n        sameDay : '[Hari ini pukul] LT',\n        nextDay : '[Besok pukul] LT',\n        nextWeek : 'dddd [pukul] LT',\n        lastDay : '[Kemarin pukul] LT',\n        lastWeek : 'dddd [lalu pukul] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'dalam %s',\n        past : '%s yang lalu',\n        s : 'beberapa detik',\n        m : 'semenit',\n        mm : '%d menit',\n        h : 'sejam',\n        hh : '%d jam',\n        d : 'sehari',\n        dd : '%d hari',\n        M : 'sebulan',\n        MM : '%d bulan',\n        y : 'setahun',\n        yy : '%d tahun'\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 7  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\nreturn id;\n\n})));\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/locale/is.js",
    "content": "//! moment.js locale configuration\n//! locale : Icelandic [is]\n//! author : Hinrik Örn Sigurðsson : https://github.com/hinrik\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\n\nfunction plural(n) {\n    if (n % 100 === 11) {\n        return true;\n    } else if (n % 10 === 1) {\n        return false;\n    }\n    return true;\n}\nfunction translate(number, withoutSuffix, key, isFuture) {\n    var result = number + ' ';\n    switch (key) {\n        case 's':\n            return withoutSuffix || isFuture ? 'nokkrar sekúndur' : 'nokkrum sekúndum';\n        case 'm':\n            return withoutSuffix ? 'mínúta' : 'mínútu';\n        case 'mm':\n            if (plural(number)) {\n                return result + (withoutSuffix || isFuture ? 'mínútur' : 'mínútum');\n            } else if (withoutSuffix) {\n                return result + 'mínúta';\n            }\n            return result + 'mínútu';\n        case 'hh':\n            if (plural(number)) {\n                return result + (withoutSuffix || isFuture ? 'klukkustundir' : 'klukkustundum');\n            }\n            return result + 'klukkustund';\n        case 'd':\n            if (withoutSuffix) {\n                return 'dagur';\n            }\n            return isFuture ? 'dag' : 'degi';\n        case 'dd':\n            if (plural(number)) {\n                if (withoutSuffix) {\n                    return result + 'dagar';\n                }\n                return result + (isFuture ? 'daga' : 'dögum');\n            } else if (withoutSuffix) {\n                return result + 'dagur';\n            }\n            return result + (isFuture ? 'dag' : 'degi');\n        case 'M':\n            if (withoutSuffix) {\n                return 'mánuður';\n            }\n            return isFuture ? 'mánuð' : 'mánuði';\n        case 'MM':\n            if (plural(number)) {\n                if (withoutSuffix) {\n                    return result + 'mánuðir';\n                }\n                return result + (isFuture ? 'mánuði' : 'mánuðum');\n            } else if (withoutSuffix) {\n                return result + 'mánuður';\n            }\n            return result + (isFuture ? 'mánuð' : 'mánuði');\n        case 'y':\n            return withoutSuffix || isFuture ? 'ár' : 'ári';\n        case 'yy':\n            if (plural(number)) {\n                return result + (withoutSuffix || isFuture ? 'ár' : 'árum');\n            }\n            return result + (withoutSuffix || isFuture ? 'ár' : 'ári');\n    }\n}\n\nvar is = moment.defineLocale('is', {\n    months : 'janúar_febrúar_mars_apríl_maí_júní_júlí_ágúst_september_október_nóvember_desember'.split('_'),\n    monthsShort : 'jan_feb_mar_apr_maí_jún_júl_ágú_sep_okt_nóv_des'.split('_'),\n    weekdays : 'sunnudagur_mánudagur_þriðjudagur_miðvikudagur_fimmtudagur_föstudagur_laugardagur'.split('_'),\n    weekdaysShort : 'sun_mán_þri_mið_fim_fös_lau'.split('_'),\n    weekdaysMin : 'Su_Má_Þr_Mi_Fi_Fö_La'.split('_'),\n    longDateFormat : {\n        LT : 'H:mm',\n        LTS : 'H:mm:ss',\n        L : 'DD.MM.YYYY',\n        LL : 'D. MMMM YYYY',\n        LLL : 'D. MMMM YYYY [kl.] H:mm',\n        LLLL : 'dddd, D. MMMM YYYY [kl.] H:mm'\n    },\n    calendar : {\n        sameDay : '[í dag kl.] LT',\n        nextDay : '[á morgun kl.] LT',\n        nextWeek : 'dddd [kl.] LT',\n        lastDay : '[í gær kl.] LT',\n        lastWeek : '[síðasta] dddd [kl.] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'eftir %s',\n        past : 'fyrir %s síðan',\n        s : translate,\n        m : translate,\n        mm : translate,\n        h : 'klukkustund',\n        hh : translate,\n        d : translate,\n        dd : translate,\n        M : translate,\n        MM : translate,\n        y : translate,\n        yy : translate\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}\\./,\n    ordinal : '%d.',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\nreturn is;\n\n})));\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/locale/it.js",
    "content": "//! moment.js locale configuration\n//! locale : Italian [it]\n//! author : Lorenzo : https://github.com/aliem\n//! author: Mattia Larentis: https://github.com/nostalgiaz\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\n\nvar it = moment.defineLocale('it', {\n    months : 'gennaio_febbraio_marzo_aprile_maggio_giugno_luglio_agosto_settembre_ottobre_novembre_dicembre'.split('_'),\n    monthsShort : 'gen_feb_mar_apr_mag_giu_lug_ago_set_ott_nov_dic'.split('_'),\n    weekdays : 'domenica_lunedì_martedì_mercoledì_giovedì_venerdì_sabato'.split('_'),\n    weekdaysShort : 'dom_lun_mar_mer_gio_ven_sab'.split('_'),\n    weekdaysMin : 'do_lu_ma_me_gi_ve_sa'.split('_'),\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY HH:mm',\n        LLLL : 'dddd, D MMMM YYYY HH:mm'\n    },\n    calendar : {\n        sameDay: '[Oggi alle] LT',\n        nextDay: '[Domani alle] LT',\n        nextWeek: 'dddd [alle] LT',\n        lastDay: '[Ieri alle] LT',\n        lastWeek: function () {\n            switch (this.day()) {\n                case 0:\n                    return '[la scorsa] dddd [alle] LT';\n                default:\n                    return '[lo scorso] dddd [alle] LT';\n            }\n        },\n        sameElse: 'L'\n    },\n    relativeTime : {\n        future : function (s) {\n            return ((/^[0-9].+$/).test(s) ? 'tra' : 'in') + ' ' + s;\n        },\n        past : '%s fa',\n        s : 'alcuni secondi',\n        m : 'un minuto',\n        mm : '%d minuti',\n        h : 'un\\'ora',\n        hh : '%d ore',\n        d : 'un giorno',\n        dd : '%d giorni',\n        M : 'un mese',\n        MM : '%d mesi',\n        y : 'un anno',\n        yy : '%d anni'\n    },\n    dayOfMonthOrdinalParse : /\\d{1,2}º/,\n    ordinal: '%dº',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\nreturn it;\n\n})));\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/locale/ja.js",
    "content": "//! moment.js locale configuration\n//! locale : Japanese [ja]\n//! author : LI Long : https://github.com/baryon\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\n\nvar ja = moment.defineLocale('ja', {\n    months : '1月_2月_3月_4月_5月_6月_7月_8月_9月_10月_11月_12月'.split('_'),\n    monthsShort : '1月_2月_3月_4月_5月_6月_7月_8月_9月_10月_11月_12月'.split('_'),\n    weekdays : '日曜日_月曜日_火曜日_水曜日_木曜日_金曜日_土曜日'.split('_'),\n    weekdaysShort : '日_月_火_水_木_金_土'.split('_'),\n    weekdaysMin : '日_月_火_水_木_金_土'.split('_'),\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'YYYY/MM/DD',\n        LL : 'YYYY年M月D日',\n        LLL : 'YYYY年M月D日 HH:mm',\n        LLLL : 'YYYY年M月D日 HH:mm dddd',\n        l : 'YYYY/MM/DD',\n        ll : 'YYYY年M月D日',\n        lll : 'YYYY年M月D日 HH:mm',\n        llll : 'YYYY年M月D日 HH:mm dddd'\n    },\n    meridiemParse: /午前|午後/i,\n    isPM : function (input) {\n        return input === '午後';\n    },\n    meridiem : function (hour, minute, isLower) {\n        if (hour < 12) {\n            return '午前';\n        } else {\n            return '午後';\n        }\n    },\n    calendar : {\n        sameDay : '[今日] LT',\n        nextDay : '[明日] LT',\n        nextWeek : '[来週]dddd LT',\n        lastDay : '[昨日] LT',\n        lastWeek : '[前週]dddd LT',\n        sameElse : 'L'\n    },\n    dayOfMonthOrdinalParse : /\\d{1,2}日/,\n    ordinal : function (number, period) {\n        switch (period) {\n            case 'd':\n            case 'D':\n            case 'DDD':\n                return number + '日';\n            default:\n                return number;\n        }\n    },\n    relativeTime : {\n        future : '%s後',\n        past : '%s前',\n        s : '数秒',\n        m : '1分',\n        mm : '%d分',\n        h : '1時間',\n        hh : '%d時間',\n        d : '1日',\n        dd : '%d日',\n        M : '1ヶ月',\n        MM : '%dヶ月',\n        y : '1年',\n        yy : '%d年'\n    }\n});\n\nreturn ja;\n\n})));\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/locale/jv.js",
    "content": "//! moment.js locale configuration\n//! locale : Javanese [jv]\n//! author : Rony Lantip : https://github.com/lantip\n//! reference: http://jv.wikipedia.org/wiki/Basa_Jawa\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\n\nvar jv = moment.defineLocale('jv', {\n    months : 'Januari_Februari_Maret_April_Mei_Juni_Juli_Agustus_September_Oktober_Nopember_Desember'.split('_'),\n    monthsShort : 'Jan_Feb_Mar_Apr_Mei_Jun_Jul_Ags_Sep_Okt_Nop_Des'.split('_'),\n    weekdays : 'Minggu_Senen_Seloso_Rebu_Kemis_Jemuwah_Septu'.split('_'),\n    weekdaysShort : 'Min_Sen_Sel_Reb_Kem_Jem_Sep'.split('_'),\n    weekdaysMin : 'Mg_Sn_Sl_Rb_Km_Jm_Sp'.split('_'),\n    longDateFormat : {\n        LT : 'HH.mm',\n        LTS : 'HH.mm.ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY [pukul] HH.mm',\n        LLLL : 'dddd, D MMMM YYYY [pukul] HH.mm'\n    },\n    meridiemParse: /enjing|siyang|sonten|ndalu/,\n    meridiemHour : function (hour, meridiem) {\n        if (hour === 12) {\n            hour = 0;\n        }\n        if (meridiem === 'enjing') {\n            return hour;\n        } else if (meridiem === 'siyang') {\n            return hour >= 11 ? hour : hour + 12;\n        } else if (meridiem === 'sonten' || meridiem === 'ndalu') {\n            return hour + 12;\n        }\n    },\n    meridiem : function (hours, minutes, isLower) {\n        if (hours < 11) {\n            return 'enjing';\n        } else if (hours < 15) {\n            return 'siyang';\n        } else if (hours < 19) {\n            return 'sonten';\n        } else {\n            return 'ndalu';\n        }\n    },\n    calendar : {\n        sameDay : '[Dinten puniko pukul] LT',\n        nextDay : '[Mbenjang pukul] LT',\n        nextWeek : 'dddd [pukul] LT',\n        lastDay : '[Kala wingi pukul] LT',\n        lastWeek : 'dddd [kepengker pukul] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'wonten ing %s',\n        past : '%s ingkang kepengker',\n        s : 'sawetawis detik',\n        m : 'setunggal menit',\n        mm : '%d menit',\n        h : 'setunggal jam',\n        hh : '%d jam',\n        d : 'sedinten',\n        dd : '%d dinten',\n        M : 'sewulan',\n        MM : '%d wulan',\n        y : 'setaun',\n        yy : '%d taun'\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 7  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\nreturn jv;\n\n})));\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/locale/ka.js",
    "content": "//! moment.js locale configuration\n//! locale : Georgian [ka]\n//! author : Irakli Janiashvili : https://github.com/irakli-janiashvili\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\n\nvar ka = moment.defineLocale('ka', {\n    months : {\n        standalone: 'იანვარი_თებერვალი_მარტი_აპრილი_მაისი_ივნისი_ივლისი_აგვისტო_სექტემბერი_ოქტომბერი_ნოემბერი_დეკემბერი'.split('_'),\n        format: 'იანვარს_თებერვალს_მარტს_აპრილის_მაისს_ივნისს_ივლისს_აგვისტს_სექტემბერს_ოქტომბერს_ნოემბერს_დეკემბერს'.split('_')\n    },\n    monthsShort : 'იან_თებ_მარ_აპრ_მაი_ივნ_ივლ_აგვ_სექ_ოქტ_ნოე_დეკ'.split('_'),\n    weekdays : {\n        standalone: 'კვირა_ორშაბათი_სამშაბათი_ოთხშაბათი_ხუთშაბათი_პარასკევი_შაბათი'.split('_'),\n        format: 'კვირას_ორშაბათს_სამშაბათს_ოთხშაბათს_ხუთშაბათს_პარასკევს_შაბათს'.split('_'),\n        isFormat: /(წინა|შემდეგ)/\n    },\n    weekdaysShort : 'კვი_ორშ_სამ_ოთხ_ხუთ_პარ_შაბ'.split('_'),\n    weekdaysMin : 'კვ_ორ_სა_ოთ_ხუ_პა_შა'.split('_'),\n    longDateFormat : {\n        LT : 'h:mm A',\n        LTS : 'h:mm:ss A',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY h:mm A',\n        LLLL : 'dddd, D MMMM YYYY h:mm A'\n    },\n    calendar : {\n        sameDay : '[დღეს] LT[-ზე]',\n        nextDay : '[ხვალ] LT[-ზე]',\n        lastDay : '[გუშინ] LT[-ზე]',\n        nextWeek : '[შემდეგ] dddd LT[-ზე]',\n        lastWeek : '[წინა] dddd LT-ზე',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : function (s) {\n            return (/(წამი|წუთი|საათი|წელი)/).test(s) ?\n                s.replace(/ი$/, 'ში') :\n                s + 'ში';\n        },\n        past : function (s) {\n            if ((/(წამი|წუთი|საათი|დღე|თვე)/).test(s)) {\n                return s.replace(/(ი|ე)$/, 'ის უკან');\n            }\n            if ((/წელი/).test(s)) {\n                return s.replace(/წელი$/, 'წლის უკან');\n            }\n        },\n        s : 'რამდენიმე წამი',\n        m : 'წუთი',\n        mm : '%d წუთი',\n        h : 'საათი',\n        hh : '%d საათი',\n        d : 'დღე',\n        dd : '%d დღე',\n        M : 'თვე',\n        MM : '%d თვე',\n        y : 'წელი',\n        yy : '%d წელი'\n    },\n    dayOfMonthOrdinalParse: /0|1-ლი|მე-\\d{1,2}|\\d{1,2}-ე/,\n    ordinal : function (number) {\n        if (number === 0) {\n            return number;\n        }\n        if (number === 1) {\n            return number + '-ლი';\n        }\n        if ((number < 20) || (number <= 100 && (number % 20 === 0)) || (number % 100 === 0)) {\n            return 'მე-' + number;\n        }\n        return number + '-ე';\n    },\n    week : {\n        dow : 1,\n        doy : 7\n    }\n});\n\nreturn ka;\n\n})));\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/locale/kk.js",
    "content": "//! moment.js locale configuration\n//! locale : Kazakh [kk]\n//! authors : Nurlan Rakhimzhanov : https://github.com/nurlan\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\n\nvar suffixes = {\n    0: '-ші',\n    1: '-ші',\n    2: '-ші',\n    3: '-ші',\n    4: '-ші',\n    5: '-ші',\n    6: '-шы',\n    7: '-ші',\n    8: '-ші',\n    9: '-шы',\n    10: '-шы',\n    20: '-шы',\n    30: '-шы',\n    40: '-шы',\n    50: '-ші',\n    60: '-шы',\n    70: '-ші',\n    80: '-ші',\n    90: '-шы',\n    100: '-ші'\n};\n\nvar kk = moment.defineLocale('kk', {\n    months : 'қаңтар_ақпан_наурыз_сәуір_мамыр_маусым_шілде_тамыз_қыркүйек_қазан_қараша_желтоқсан'.split('_'),\n    monthsShort : 'қаң_ақп_нау_сәу_мам_мау_шіл_там_қыр_қаз_қар_жел'.split('_'),\n    weekdays : 'жексенбі_дүйсенбі_сейсенбі_сәрсенбі_бейсенбі_жұма_сенбі'.split('_'),\n    weekdaysShort : 'жек_дүй_сей_сәр_бей_жұм_сен'.split('_'),\n    weekdaysMin : 'жк_дй_сй_ср_бй_жм_сн'.split('_'),\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD.MM.YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY HH:mm',\n        LLLL : 'dddd, D MMMM YYYY HH:mm'\n    },\n    calendar : {\n        sameDay : '[Бүгін сағат] LT',\n        nextDay : '[Ертең сағат] LT',\n        nextWeek : 'dddd [сағат] LT',\n        lastDay : '[Кеше сағат] LT',\n        lastWeek : '[Өткен аптаның] dddd [сағат] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : '%s ішінде',\n        past : '%s бұрын',\n        s : 'бірнеше секунд',\n        m : 'бір минут',\n        mm : '%d минут',\n        h : 'бір сағат',\n        hh : '%d сағат',\n        d : 'бір күн',\n        dd : '%d күн',\n        M : 'бір ай',\n        MM : '%d ай',\n        y : 'бір жыл',\n        yy : '%d жыл'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}-(ші|шы)/,\n    ordinal : function (number) {\n        var a = number % 10,\n            b = number >= 100 ? 100 : null;\n        return number + (suffixes[number] || suffixes[a] || suffixes[b]);\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 7  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\nreturn kk;\n\n})));\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/locale/km.js",
    "content": "//! moment.js locale configuration\n//! locale : Cambodian [km]\n//! author : Kruy Vanna : https://github.com/kruyvanna\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\n\nvar km = moment.defineLocale('km', {\n    months: 'មករា_កុម្ភៈ_មីនា_មេសា_ឧសភា_មិថុនា_កក្កដា_សីហា_កញ្ញា_តុលា_វិច្ឆិកា_ធ្នូ'.split('_'),\n    monthsShort: 'មករា_កុម្ភៈ_មីនា_មេសា_ឧសភា_មិថុនា_កក្កដា_សីហា_កញ្ញា_តុលា_វិច្ឆិកា_ធ្នូ'.split('_'),\n    weekdays: 'អាទិត្យ_ច័ន្ទ_អង្គារ_ពុធ_ព្រហស្បតិ៍_សុក្រ_សៅរ៍'.split('_'),\n    weekdaysShort: 'អាទិត្យ_ច័ន្ទ_អង្គារ_ពុធ_ព្រហស្បតិ៍_សុក្រ_សៅរ៍'.split('_'),\n    weekdaysMin: 'អាទិត្យ_ច័ន្ទ_អង្គារ_ពុធ_ព្រហស្បតិ៍_សុក្រ_សៅរ៍'.split('_'),\n    longDateFormat: {\n        LT: 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L: 'DD/MM/YYYY',\n        LL: 'D MMMM YYYY',\n        LLL: 'D MMMM YYYY HH:mm',\n        LLLL: 'dddd, D MMMM YYYY HH:mm'\n    },\n    calendar: {\n        sameDay: '[ថ្ងៃនេះ ម៉ោង] LT',\n        nextDay: '[ស្អែក ម៉ោង] LT',\n        nextWeek: 'dddd [ម៉ោង] LT',\n        lastDay: '[ម្សិលមិញ ម៉ោង] LT',\n        lastWeek: 'dddd [សប្តាហ៍មុន] [ម៉ោង] LT',\n        sameElse: 'L'\n    },\n    relativeTime: {\n        future: '%sទៀត',\n        past: '%sមុន',\n        s: 'ប៉ុន្មានវិនាទី',\n        m: 'មួយនាទី',\n        mm: '%d នាទី',\n        h: 'មួយម៉ោង',\n        hh: '%d ម៉ោង',\n        d: 'មួយថ្ងៃ',\n        dd: '%d ថ្ងៃ',\n        M: 'មួយខែ',\n        MM: '%d ខែ',\n        y: 'មួយឆ្នាំ',\n        yy: '%d ឆ្នាំ'\n    },\n    week: {\n        dow: 1, // Monday is the first day of the week.\n        doy: 4 // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\nreturn km;\n\n})));\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/locale/kn.js",
    "content": "//! moment.js locale configuration\n//! locale : Kannada [kn]\n//! author : Rajeev Naik : https://github.com/rajeevnaikte\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\n\nvar symbolMap = {\n    '1': '೧',\n    '2': '೨',\n    '3': '೩',\n    '4': '೪',\n    '5': '೫',\n    '6': '೬',\n    '7': '೭',\n    '8': '೮',\n    '9': '೯',\n    '0': '೦'\n};\nvar numberMap = {\n    '೧': '1',\n    '೨': '2',\n    '೩': '3',\n    '೪': '4',\n    '೫': '5',\n    '೬': '6',\n    '೭': '7',\n    '೮': '8',\n    '೯': '9',\n    '೦': '0'\n};\n\nvar kn = moment.defineLocale('kn', {\n    months : 'ಜನವರಿ_ಫೆಬ್ರವರಿ_ಮಾರ್ಚ್_ಏಪ್ರಿಲ್_ಮೇ_ಜೂನ್_ಜುಲೈ_ಆಗಸ್ಟ್_ಸೆಪ್ಟೆಂಬರ್_ಅಕ್ಟೋಬರ್_ನವೆಂಬರ್_ಡಿಸೆಂಬರ್'.split('_'),\n    monthsShort : 'ಜನ_ಫೆಬ್ರ_ಮಾರ್ಚ್_ಏಪ್ರಿಲ್_ಮೇ_ಜೂನ್_ಜುಲೈ_ಆಗಸ್ಟ್_ಸೆಪ್ಟೆಂಬ_ಅಕ್ಟೋಬ_ನವೆಂಬ_ಡಿಸೆಂಬ'.split('_'),\n    monthsParseExact: true,\n    weekdays : 'ಭಾನುವಾರ_ಸೋಮವಾರ_ಮಂಗಳವಾರ_ಬುಧವಾರ_ಗುರುವಾರ_ಶುಕ್ರವಾರ_ಶನಿವಾರ'.split('_'),\n    weekdaysShort : 'ಭಾನು_ಸೋಮ_ಮಂಗಳ_ಬುಧ_ಗುರು_ಶುಕ್ರ_ಶನಿ'.split('_'),\n    weekdaysMin : 'ಭಾ_ಸೋ_ಮಂ_ಬು_ಗು_ಶು_ಶ'.split('_'),\n    longDateFormat : {\n        LT : 'A h:mm',\n        LTS : 'A h:mm:ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY, A h:mm',\n        LLLL : 'dddd, D MMMM YYYY, A h:mm'\n    },\n    calendar : {\n        sameDay : '[ಇಂದು] LT',\n        nextDay : '[ನಾಳೆ] LT',\n        nextWeek : 'dddd, LT',\n        lastDay : '[ನಿನ್ನೆ] LT',\n        lastWeek : '[ಕೊನೆಯ] dddd, LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : '%s ನಂತರ',\n        past : '%s ಹಿಂದೆ',\n        s : 'ಕೆಲವು ಕ್ಷಣಗಳು',\n        m : 'ಒಂದು ನಿಮಿಷ',\n        mm : '%d ನಿಮಿಷ',\n        h : 'ಒಂದು ಗಂಟೆ',\n        hh : '%d ಗಂಟೆ',\n        d : 'ಒಂದು ದಿನ',\n        dd : '%d ದಿನ',\n        M : 'ಒಂದು ತಿಂಗಳು',\n        MM : '%d ತಿಂಗಳು',\n        y : 'ಒಂದು ವರ್ಷ',\n        yy : '%d ವರ್ಷ'\n    },\n    preparse: function (string) {\n        return string.replace(/[೧೨೩೪೫೬೭೮೯೦]/g, function (match) {\n            return numberMap[match];\n        });\n    },\n    postformat: function (string) {\n        return string.replace(/\\d/g, function (match) {\n            return symbolMap[match];\n        });\n    },\n    meridiemParse: /ರಾತ್ರಿ|ಬೆಳಿಗ್ಗೆ|ಮಧ್ಯಾಹ್ನ|ಸಂಜೆ/,\n    meridiemHour : function (hour, meridiem) {\n        if (hour === 12) {\n            hour = 0;\n        }\n        if (meridiem === 'ರಾತ್ರಿ') {\n            return hour < 4 ? hour : hour + 12;\n        } else if (meridiem === 'ಬೆಳಿಗ್ಗೆ') {\n            return hour;\n        } else if (meridiem === 'ಮಧ್ಯಾಹ್ನ') {\n            return hour >= 10 ? hour : hour + 12;\n        } else if (meridiem === 'ಸಂಜೆ') {\n            return hour + 12;\n        }\n    },\n    meridiem : function (hour, minute, isLower) {\n        if (hour < 4) {\n            return 'ರಾತ್ರಿ';\n        } else if (hour < 10) {\n            return 'ಬೆಳಿಗ್ಗೆ';\n        } else if (hour < 17) {\n            return 'ಮಧ್ಯಾಹ್ನ';\n        } else if (hour < 20) {\n            return 'ಸಂಜೆ';\n        } else {\n            return 'ರಾತ್ರಿ';\n        }\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}(ನೇ)/,\n    ordinal : function (number) {\n        return number + 'ನೇ';\n    },\n    week : {\n        dow : 0, // Sunday is the first day of the week.\n        doy : 6  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\nreturn kn;\n\n})));\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/locale/ko.js",
    "content": "//! moment.js locale configuration\n//! locale : Korean [ko]\n//! author : Kyungwook, Park : https://github.com/kyungw00k\n//! author : Jeeeyul Lee <jeeeyul@gmail.com>\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\n\nvar ko = moment.defineLocale('ko', {\n    months : '1월_2월_3월_4월_5월_6월_7월_8월_9월_10월_11월_12월'.split('_'),\n    monthsShort : '1월_2월_3월_4월_5월_6월_7월_8월_9월_10월_11월_12월'.split('_'),\n    weekdays : '일요일_월요일_화요일_수요일_목요일_금요일_토요일'.split('_'),\n    weekdaysShort : '일_월_화_수_목_금_토'.split('_'),\n    weekdaysMin : '일_월_화_수_목_금_토'.split('_'),\n    longDateFormat : {\n        LT : 'A h:mm',\n        LTS : 'A h:mm:ss',\n        L : 'YYYY.MM.DD',\n        LL : 'YYYY년 MMMM D일',\n        LLL : 'YYYY년 MMMM D일 A h:mm',\n        LLLL : 'YYYY년 MMMM D일 dddd A h:mm',\n        l : 'YYYY.MM.DD',\n        ll : 'YYYY년 MMMM D일',\n        lll : 'YYYY년 MMMM D일 A h:mm',\n        llll : 'YYYY년 MMMM D일 dddd A h:mm'\n    },\n    calendar : {\n        sameDay : '오늘 LT',\n        nextDay : '내일 LT',\n        nextWeek : 'dddd LT',\n        lastDay : '어제 LT',\n        lastWeek : '지난주 dddd LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : '%s 후',\n        past : '%s 전',\n        s : '몇 초',\n        ss : '%d초',\n        m : '1분',\n        mm : '%d분',\n        h : '한 시간',\n        hh : '%d시간',\n        d : '하루',\n        dd : '%d일',\n        M : '한 달',\n        MM : '%d달',\n        y : '일 년',\n        yy : '%d년'\n    },\n    dayOfMonthOrdinalParse : /\\d{1,2}일/,\n    ordinal : '%d일',\n    meridiemParse : /오전|오후/,\n    isPM : function (token) {\n        return token === '오후';\n    },\n    meridiem : function (hour, minute, isUpper) {\n        return hour < 12 ? '오전' : '오후';\n    }\n});\n\nreturn ko;\n\n})));\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/locale/ky.js",
    "content": "//! moment.js locale configuration\n//! locale : Kyrgyz [ky]\n//! author : Chyngyz Arystan uulu : https://github.com/chyngyz\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\n\n\nvar suffixes = {\n    0: '-чү',\n    1: '-чи',\n    2: '-чи',\n    3: '-чү',\n    4: '-чү',\n    5: '-чи',\n    6: '-чы',\n    7: '-чи',\n    8: '-чи',\n    9: '-чу',\n    10: '-чу',\n    20: '-чы',\n    30: '-чу',\n    40: '-чы',\n    50: '-чү',\n    60: '-чы',\n    70: '-чи',\n    80: '-чи',\n    90: '-чу',\n    100: '-чү'\n};\n\nvar ky = moment.defineLocale('ky', {\n    months : 'январь_февраль_март_апрель_май_июнь_июль_август_сентябрь_октябрь_ноябрь_декабрь'.split('_'),\n    monthsShort : 'янв_фев_март_апр_май_июнь_июль_авг_сен_окт_ноя_дек'.split('_'),\n    weekdays : 'Жекшемби_Дүйшөмбү_Шейшемби_Шаршемби_Бейшемби_Жума_Ишемби'.split('_'),\n    weekdaysShort : 'Жек_Дүй_Шей_Шар_Бей_Жум_Ише'.split('_'),\n    weekdaysMin : 'Жк_Дй_Шй_Шр_Бй_Жм_Иш'.split('_'),\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD.MM.YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY HH:mm',\n        LLLL : 'dddd, D MMMM YYYY HH:mm'\n    },\n    calendar : {\n        sameDay : '[Бүгүн саат] LT',\n        nextDay : '[Эртең саат] LT',\n        nextWeek : 'dddd [саат] LT',\n        lastDay : '[Кече саат] LT',\n        lastWeek : '[Өткен аптанын] dddd [күнү] [саат] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : '%s ичинде',\n        past : '%s мурун',\n        s : 'бирнече секунд',\n        m : 'бир мүнөт',\n        mm : '%d мүнөт',\n        h : 'бир саат',\n        hh : '%d саат',\n        d : 'бир күн',\n        dd : '%d күн',\n        M : 'бир ай',\n        MM : '%d ай',\n        y : 'бир жыл',\n        yy : '%d жыл'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}-(чи|чы|чү|чу)/,\n    ordinal : function (number) {\n        var a = number % 10,\n            b = number >= 100 ? 100 : null;\n        return number + (suffixes[number] || suffixes[a] || suffixes[b]);\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 7  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\nreturn ky;\n\n})));\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/locale/lb.js",
    "content": "//! moment.js locale configuration\n//! locale : Luxembourgish [lb]\n//! author : mweimerskirch : https://github.com/mweimerskirch\n//! author : David Raison : https://github.com/kwisatz\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\n\nfunction processRelativeTime(number, withoutSuffix, key, isFuture) {\n    var format = {\n        'm': ['eng Minutt', 'enger Minutt'],\n        'h': ['eng Stonn', 'enger Stonn'],\n        'd': ['een Dag', 'engem Dag'],\n        'M': ['ee Mount', 'engem Mount'],\n        'y': ['ee Joer', 'engem Joer']\n    };\n    return withoutSuffix ? format[key][0] : format[key][1];\n}\nfunction processFutureTime(string) {\n    var number = string.substr(0, string.indexOf(' '));\n    if (eifelerRegelAppliesToNumber(number)) {\n        return 'a ' + string;\n    }\n    return 'an ' + string;\n}\nfunction processPastTime(string) {\n    var number = string.substr(0, string.indexOf(' '));\n    if (eifelerRegelAppliesToNumber(number)) {\n        return 'viru ' + string;\n    }\n    return 'virun ' + string;\n}\n/**\n * Returns true if the word before the given number loses the '-n' ending.\n * e.g. 'an 10 Deeg' but 'a 5 Deeg'\n *\n * @param number {integer}\n * @returns {boolean}\n */\nfunction eifelerRegelAppliesToNumber(number) {\n    number = parseInt(number, 10);\n    if (isNaN(number)) {\n        return false;\n    }\n    if (number < 0) {\n        // Negative Number --> always true\n        return true;\n    } else if (number < 10) {\n        // Only 1 digit\n        if (4 <= number && number <= 7) {\n            return true;\n        }\n        return false;\n    } else if (number < 100) {\n        // 2 digits\n        var lastDigit = number % 10, firstDigit = number / 10;\n        if (lastDigit === 0) {\n            return eifelerRegelAppliesToNumber(firstDigit);\n        }\n        return eifelerRegelAppliesToNumber(lastDigit);\n    } else if (number < 10000) {\n        // 3 or 4 digits --> recursively check first digit\n        while (number >= 10) {\n            number = number / 10;\n        }\n        return eifelerRegelAppliesToNumber(number);\n    } else {\n        // Anything larger than 4 digits: recursively check first n-3 digits\n        number = number / 1000;\n        return eifelerRegelAppliesToNumber(number);\n    }\n}\n\nvar lb = moment.defineLocale('lb', {\n    months: 'Januar_Februar_Mäerz_Abrëll_Mee_Juni_Juli_August_September_Oktober_November_Dezember'.split('_'),\n    monthsShort: 'Jan._Febr._Mrz._Abr._Mee_Jun._Jul._Aug._Sept._Okt._Nov._Dez.'.split('_'),\n    monthsParseExact : true,\n    weekdays: 'Sonndeg_Méindeg_Dënschdeg_Mëttwoch_Donneschdeg_Freideg_Samschdeg'.split('_'),\n    weekdaysShort: 'So._Mé._Dë._Më._Do._Fr._Sa.'.split('_'),\n    weekdaysMin: 'So_Mé_Dë_Më_Do_Fr_Sa'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat: {\n        LT: 'H:mm [Auer]',\n        LTS: 'H:mm:ss [Auer]',\n        L: 'DD.MM.YYYY',\n        LL: 'D. MMMM YYYY',\n        LLL: 'D. MMMM YYYY H:mm [Auer]',\n        LLLL: 'dddd, D. MMMM YYYY H:mm [Auer]'\n    },\n    calendar: {\n        sameDay: '[Haut um] LT',\n        sameElse: 'L',\n        nextDay: '[Muer um] LT',\n        nextWeek: 'dddd [um] LT',\n        lastDay: '[Gëschter um] LT',\n        lastWeek: function () {\n            // Different date string for 'Dënschdeg' (Tuesday) and 'Donneschdeg' (Thursday) due to phonological rule\n            switch (this.day()) {\n                case 2:\n                case 4:\n                    return '[Leschten] dddd [um] LT';\n                default:\n                    return '[Leschte] dddd [um] LT';\n            }\n        }\n    },\n    relativeTime : {\n        future : processFutureTime,\n        past : processPastTime,\n        s : 'e puer Sekonnen',\n        m : processRelativeTime,\n        mm : '%d Minutten',\n        h : processRelativeTime,\n        hh : '%d Stonnen',\n        d : processRelativeTime,\n        dd : '%d Deeg',\n        M : processRelativeTime,\n        MM : '%d Méint',\n        y : processRelativeTime,\n        yy : '%d Joer'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}\\./,\n    ordinal: '%d.',\n    week: {\n        dow: 1, // Monday is the first day of the week.\n        doy: 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\nreturn lb;\n\n})));\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/locale/lo.js",
    "content": "//! moment.js locale configuration\n//! locale : Lao [lo]\n//! author : Ryan Hart : https://github.com/ryanhart2\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\n\nvar lo = moment.defineLocale('lo', {\n    months : 'ມັງກອນ_ກຸມພາ_ມີນາ_ເມສາ_ພຶດສະພາ_ມິຖຸນາ_ກໍລະກົດ_ສິງຫາ_ກັນຍາ_ຕຸລາ_ພະຈິກ_ທັນວາ'.split('_'),\n    monthsShort : 'ມັງກອນ_ກຸມພາ_ມີນາ_ເມສາ_ພຶດສະພາ_ມິຖຸນາ_ກໍລະກົດ_ສິງຫາ_ກັນຍາ_ຕຸລາ_ພະຈິກ_ທັນວາ'.split('_'),\n    weekdays : 'ອາທິດ_ຈັນ_ອັງຄານ_ພຸດ_ພະຫັດ_ສຸກ_ເສົາ'.split('_'),\n    weekdaysShort : 'ທິດ_ຈັນ_ອັງຄານ_ພຸດ_ພະຫັດ_ສຸກ_ເສົາ'.split('_'),\n    weekdaysMin : 'ທ_ຈ_ອຄ_ພ_ພຫ_ສກ_ສ'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY HH:mm',\n        LLLL : 'ວັນdddd D MMMM YYYY HH:mm'\n    },\n    meridiemParse: /ຕອນເຊົ້າ|ຕອນແລງ/,\n    isPM: function (input) {\n        return input === 'ຕອນແລງ';\n    },\n    meridiem : function (hour, minute, isLower) {\n        if (hour < 12) {\n            return 'ຕອນເຊົ້າ';\n        } else {\n            return 'ຕອນແລງ';\n        }\n    },\n    calendar : {\n        sameDay : '[ມື້ນີ້ເວລາ] LT',\n        nextDay : '[ມື້ອື່ນເວລາ] LT',\n        nextWeek : '[ວັນ]dddd[ໜ້າເວລາ] LT',\n        lastDay : '[ມື້ວານນີ້ເວລາ] LT',\n        lastWeek : '[ວັນ]dddd[ແລ້ວນີ້ເວລາ] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'ອີກ %s',\n        past : '%sຜ່ານມາ',\n        s : 'ບໍ່ເທົ່າໃດວິນາທີ',\n        m : '1 ນາທີ',\n        mm : '%d ນາທີ',\n        h : '1 ຊົ່ວໂມງ',\n        hh : '%d ຊົ່ວໂມງ',\n        d : '1 ມື້',\n        dd : '%d ມື້',\n        M : '1 ເດືອນ',\n        MM : '%d ເດືອນ',\n        y : '1 ປີ',\n        yy : '%d ປີ'\n    },\n    dayOfMonthOrdinalParse: /(ທີ່)\\d{1,2}/,\n    ordinal : function (number) {\n        return 'ທີ່' + number;\n    }\n});\n\nreturn lo;\n\n})));\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/locale/lt.js",
    "content": "//! moment.js locale configuration\n//! locale : Lithuanian [lt]\n//! author : Mindaugas Mozūras : https://github.com/mmozuras\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\n\nvar units = {\n    'm' : 'minutė_minutės_minutę',\n    'mm': 'minutės_minučių_minutes',\n    'h' : 'valanda_valandos_valandą',\n    'hh': 'valandos_valandų_valandas',\n    'd' : 'diena_dienos_dieną',\n    'dd': 'dienos_dienų_dienas',\n    'M' : 'mėnuo_mėnesio_mėnesį',\n    'MM': 'mėnesiai_mėnesių_mėnesius',\n    'y' : 'metai_metų_metus',\n    'yy': 'metai_metų_metus'\n};\nfunction translateSeconds(number, withoutSuffix, key, isFuture) {\n    if (withoutSuffix) {\n        return 'kelios sekundės';\n    } else {\n        return isFuture ? 'kelių sekundžių' : 'kelias sekundes';\n    }\n}\nfunction translateSingular(number, withoutSuffix, key, isFuture) {\n    return withoutSuffix ? forms(key)[0] : (isFuture ? forms(key)[1] : forms(key)[2]);\n}\nfunction special(number) {\n    return number % 10 === 0 || (number > 10 && number < 20);\n}\nfunction forms(key) {\n    return units[key].split('_');\n}\nfunction translate(number, withoutSuffix, key, isFuture) {\n    var result = number + ' ';\n    if (number === 1) {\n        return result + translateSingular(number, withoutSuffix, key[0], isFuture);\n    } else if (withoutSuffix) {\n        return result + (special(number) ? forms(key)[1] : forms(key)[0]);\n    } else {\n        if (isFuture) {\n            return result + forms(key)[1];\n        } else {\n            return result + (special(number) ? forms(key)[1] : forms(key)[2]);\n        }\n    }\n}\nvar lt = moment.defineLocale('lt', {\n    months : {\n        format: 'sausio_vasario_kovo_balandžio_gegužės_birželio_liepos_rugpjūčio_rugsėjo_spalio_lapkričio_gruodžio'.split('_'),\n        standalone: 'sausis_vasaris_kovas_balandis_gegužė_birželis_liepa_rugpjūtis_rugsėjis_spalis_lapkritis_gruodis'.split('_'),\n        isFormat: /D[oD]?(\\[[^\\[\\]]*\\]|\\s)+MMMM?|MMMM?(\\[[^\\[\\]]*\\]|\\s)+D[oD]?/\n    },\n    monthsShort : 'sau_vas_kov_bal_geg_bir_lie_rgp_rgs_spa_lap_grd'.split('_'),\n    weekdays : {\n        format: 'sekmadienį_pirmadienį_antradienį_trečiadienį_ketvirtadienį_penktadienį_šeštadienį'.split('_'),\n        standalone: 'sekmadienis_pirmadienis_antradienis_trečiadienis_ketvirtadienis_penktadienis_šeštadienis'.split('_'),\n        isFormat: /dddd HH:mm/\n    },\n    weekdaysShort : 'Sek_Pir_Ant_Tre_Ket_Pen_Šeš'.split('_'),\n    weekdaysMin : 'S_P_A_T_K_Pn_Š'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'YYYY-MM-DD',\n        LL : 'YYYY [m.] MMMM D [d.]',\n        LLL : 'YYYY [m.] MMMM D [d.], HH:mm [val.]',\n        LLLL : 'YYYY [m.] MMMM D [d.], dddd, HH:mm [val.]',\n        l : 'YYYY-MM-DD',\n        ll : 'YYYY [m.] MMMM D [d.]',\n        lll : 'YYYY [m.] MMMM D [d.], HH:mm [val.]',\n        llll : 'YYYY [m.] MMMM D [d.], ddd, HH:mm [val.]'\n    },\n    calendar : {\n        sameDay : '[Šiandien] LT',\n        nextDay : '[Rytoj] LT',\n        nextWeek : 'dddd LT',\n        lastDay : '[Vakar] LT',\n        lastWeek : '[Praėjusį] dddd LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'po %s',\n        past : 'prieš %s',\n        s : translateSeconds,\n        m : translateSingular,\n        mm : translate,\n        h : translateSingular,\n        hh : translate,\n        d : translateSingular,\n        dd : translate,\n        M : translateSingular,\n        MM : translate,\n        y : translateSingular,\n        yy : translate\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}-oji/,\n    ordinal : function (number) {\n        return number + '-oji';\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\nreturn lt;\n\n})));\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/locale/lv.js",
    "content": "//! moment.js locale configuration\n//! locale : Latvian [lv]\n//! author : Kristaps Karlsons : https://github.com/skakri\n//! author : Jānis Elmeris : https://github.com/JanisE\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\n\nvar units = {\n    'm': 'minūtes_minūtēm_minūte_minūtes'.split('_'),\n    'mm': 'minūtes_minūtēm_minūte_minūtes'.split('_'),\n    'h': 'stundas_stundām_stunda_stundas'.split('_'),\n    'hh': 'stundas_stundām_stunda_stundas'.split('_'),\n    'd': 'dienas_dienām_diena_dienas'.split('_'),\n    'dd': 'dienas_dienām_diena_dienas'.split('_'),\n    'M': 'mēneša_mēnešiem_mēnesis_mēneši'.split('_'),\n    'MM': 'mēneša_mēnešiem_mēnesis_mēneši'.split('_'),\n    'y': 'gada_gadiem_gads_gadi'.split('_'),\n    'yy': 'gada_gadiem_gads_gadi'.split('_')\n};\n/**\n * @param withoutSuffix boolean true = a length of time; false = before/after a period of time.\n */\nfunction format(forms, number, withoutSuffix) {\n    if (withoutSuffix) {\n        // E.g. \"21 minūte\", \"3 minūtes\".\n        return number % 10 === 1 && number % 100 !== 11 ? forms[2] : forms[3];\n    } else {\n        // E.g. \"21 minūtes\" as in \"pēc 21 minūtes\".\n        // E.g. \"3 minūtēm\" as in \"pēc 3 minūtēm\".\n        return number % 10 === 1 && number % 100 !== 11 ? forms[0] : forms[1];\n    }\n}\nfunction relativeTimeWithPlural(number, withoutSuffix, key) {\n    return number + ' ' + format(units[key], number, withoutSuffix);\n}\nfunction relativeTimeWithSingular(number, withoutSuffix, key) {\n    return format(units[key], number, withoutSuffix);\n}\nfunction relativeSeconds(number, withoutSuffix) {\n    return withoutSuffix ? 'dažas sekundes' : 'dažām sekundēm';\n}\n\nvar lv = moment.defineLocale('lv', {\n    months : 'janvāris_februāris_marts_aprīlis_maijs_jūnijs_jūlijs_augusts_septembris_oktobris_novembris_decembris'.split('_'),\n    monthsShort : 'jan_feb_mar_apr_mai_jūn_jūl_aug_sep_okt_nov_dec'.split('_'),\n    weekdays : 'svētdiena_pirmdiena_otrdiena_trešdiena_ceturtdiena_piektdiena_sestdiena'.split('_'),\n    weekdaysShort : 'Sv_P_O_T_C_Pk_S'.split('_'),\n    weekdaysMin : 'Sv_P_O_T_C_Pk_S'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD.MM.YYYY.',\n        LL : 'YYYY. [gada] D. MMMM',\n        LLL : 'YYYY. [gada] D. MMMM, HH:mm',\n        LLLL : 'YYYY. [gada] D. MMMM, dddd, HH:mm'\n    },\n    calendar : {\n        sameDay : '[Šodien pulksten] LT',\n        nextDay : '[Rīt pulksten] LT',\n        nextWeek : 'dddd [pulksten] LT',\n        lastDay : '[Vakar pulksten] LT',\n        lastWeek : '[Pagājušā] dddd [pulksten] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'pēc %s',\n        past : 'pirms %s',\n        s : relativeSeconds,\n        m : relativeTimeWithSingular,\n        mm : relativeTimeWithPlural,\n        h : relativeTimeWithSingular,\n        hh : relativeTimeWithPlural,\n        d : relativeTimeWithSingular,\n        dd : relativeTimeWithPlural,\n        M : relativeTimeWithSingular,\n        MM : relativeTimeWithPlural,\n        y : relativeTimeWithSingular,\n        yy : relativeTimeWithPlural\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}\\./,\n    ordinal : '%d.',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\nreturn lv;\n\n})));\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/locale/me.js",
    "content": "//! moment.js locale configuration\n//! locale : Montenegrin [me]\n//! author : Miodrag Nikač <miodrag@restartit.me> : https://github.com/miodragnikac\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\n\nvar translator = {\n    words: { //Different grammatical cases\n        m: ['jedan minut', 'jednog minuta'],\n        mm: ['minut', 'minuta', 'minuta'],\n        h: ['jedan sat', 'jednog sata'],\n        hh: ['sat', 'sata', 'sati'],\n        dd: ['dan', 'dana', 'dana'],\n        MM: ['mjesec', 'mjeseca', 'mjeseci'],\n        yy: ['godina', 'godine', 'godina']\n    },\n    correctGrammaticalCase: function (number, wordKey) {\n        return number === 1 ? wordKey[0] : (number >= 2 && number <= 4 ? wordKey[1] : wordKey[2]);\n    },\n    translate: function (number, withoutSuffix, key) {\n        var wordKey = translator.words[key];\n        if (key.length === 1) {\n            return withoutSuffix ? wordKey[0] : wordKey[1];\n        } else {\n            return number + ' ' + translator.correctGrammaticalCase(number, wordKey);\n        }\n    }\n};\n\nvar me = moment.defineLocale('me', {\n    months: 'januar_februar_mart_april_maj_jun_jul_avgust_septembar_oktobar_novembar_decembar'.split('_'),\n    monthsShort: 'jan._feb._mar._apr._maj_jun_jul_avg._sep._okt._nov._dec.'.split('_'),\n    monthsParseExact : true,\n    weekdays: 'nedjelja_ponedjeljak_utorak_srijeda_četvrtak_petak_subota'.split('_'),\n    weekdaysShort: 'ned._pon._uto._sri._čet._pet._sub.'.split('_'),\n    weekdaysMin: 'ne_po_ut_sr_če_pe_su'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat: {\n        LT: 'H:mm',\n        LTS : 'H:mm:ss',\n        L: 'DD.MM.YYYY',\n        LL: 'D. MMMM YYYY',\n        LLL: 'D. MMMM YYYY H:mm',\n        LLLL: 'dddd, D. MMMM YYYY H:mm'\n    },\n    calendar: {\n        sameDay: '[danas u] LT',\n        nextDay: '[sjutra u] LT',\n\n        nextWeek: function () {\n            switch (this.day()) {\n                case 0:\n                    return '[u] [nedjelju] [u] LT';\n                case 3:\n                    return '[u] [srijedu] [u] LT';\n                case 6:\n                    return '[u] [subotu] [u] LT';\n                case 1:\n                case 2:\n                case 4:\n                case 5:\n                    return '[u] dddd [u] LT';\n            }\n        },\n        lastDay  : '[juče u] LT',\n        lastWeek : function () {\n            var lastWeekDays = [\n                '[prošle] [nedjelje] [u] LT',\n                '[prošlog] [ponedjeljka] [u] LT',\n                '[prošlog] [utorka] [u] LT',\n                '[prošle] [srijede] [u] LT',\n                '[prošlog] [četvrtka] [u] LT',\n                '[prošlog] [petka] [u] LT',\n                '[prošle] [subote] [u] LT'\n            ];\n            return lastWeekDays[this.day()];\n        },\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'za %s',\n        past   : 'prije %s',\n        s      : 'nekoliko sekundi',\n        m      : translator.translate,\n        mm     : translator.translate,\n        h      : translator.translate,\n        hh     : translator.translate,\n        d      : 'dan',\n        dd     : translator.translate,\n        M      : 'mjesec',\n        MM     : translator.translate,\n        y      : 'godinu',\n        yy     : translator.translate\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}\\./,\n    ordinal : '%d.',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 7  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\nreturn me;\n\n})));\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/locale/mi.js",
    "content": "//! moment.js locale configuration\n//! locale : Maori [mi]\n//! author : John Corrigan <robbiecloset@gmail.com> : https://github.com/johnideal\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\n\nvar mi = moment.defineLocale('mi', {\n    months: 'Kohi-tāte_Hui-tanguru_Poutū-te-rangi_Paenga-whāwhā_Haratua_Pipiri_Hōngoingoi_Here-turi-kōkā_Mahuru_Whiringa-ā-nuku_Whiringa-ā-rangi_Hakihea'.split('_'),\n    monthsShort: 'Kohi_Hui_Pou_Pae_Hara_Pipi_Hōngoi_Here_Mahu_Whi-nu_Whi-ra_Haki'.split('_'),\n    monthsRegex: /(?:['a-z\\u0101\\u014D\\u016B]+\\-?){1,3}/i,\n    monthsStrictRegex: /(?:['a-z\\u0101\\u014D\\u016B]+\\-?){1,3}/i,\n    monthsShortRegex: /(?:['a-z\\u0101\\u014D\\u016B]+\\-?){1,3}/i,\n    monthsShortStrictRegex: /(?:['a-z\\u0101\\u014D\\u016B]+\\-?){1,2}/i,\n    weekdays: 'Rātapu_Mane_Tūrei_Wenerei_Tāite_Paraire_Hātarei'.split('_'),\n    weekdaysShort: 'Ta_Ma_Tū_We_Tāi_Pa_Hā'.split('_'),\n    weekdaysMin: 'Ta_Ma_Tū_We_Tāi_Pa_Hā'.split('_'),\n    longDateFormat: {\n        LT: 'HH:mm',\n        LTS: 'HH:mm:ss',\n        L: 'DD/MM/YYYY',\n        LL: 'D MMMM YYYY',\n        LLL: 'D MMMM YYYY [i] HH:mm',\n        LLLL: 'dddd, D MMMM YYYY [i] HH:mm'\n    },\n    calendar: {\n        sameDay: '[i teie mahana, i] LT',\n        nextDay: '[apopo i] LT',\n        nextWeek: 'dddd [i] LT',\n        lastDay: '[inanahi i] LT',\n        lastWeek: 'dddd [whakamutunga i] LT',\n        sameElse: 'L'\n    },\n    relativeTime: {\n        future: 'i roto i %s',\n        past: '%s i mua',\n        s: 'te hēkona ruarua',\n        m: 'he meneti',\n        mm: '%d meneti',\n        h: 'te haora',\n        hh: '%d haora',\n        d: 'he ra',\n        dd: '%d ra',\n        M: 'he marama',\n        MM: '%d marama',\n        y: 'he tau',\n        yy: '%d tau'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}º/,\n    ordinal: '%dº',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\nreturn mi;\n\n})));\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/locale/mk.js",
    "content": "//! moment.js locale configuration\n//! locale : Macedonian [mk]\n//! author : Borislav Mickov : https://github.com/B0k0\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\n\nvar mk = moment.defineLocale('mk', {\n    months : 'јануари_февруари_март_април_мај_јуни_јули_август_септември_октомври_ноември_декември'.split('_'),\n    monthsShort : 'јан_фев_мар_апр_мај_јун_јул_авг_сеп_окт_ное_дек'.split('_'),\n    weekdays : 'недела_понеделник_вторник_среда_четврток_петок_сабота'.split('_'),\n    weekdaysShort : 'нед_пон_вто_сре_чет_пет_саб'.split('_'),\n    weekdaysMin : 'нe_пo_вт_ср_че_пе_сa'.split('_'),\n    longDateFormat : {\n        LT : 'H:mm',\n        LTS : 'H:mm:ss',\n        L : 'D.MM.YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY H:mm',\n        LLLL : 'dddd, D MMMM YYYY H:mm'\n    },\n    calendar : {\n        sameDay : '[Денес во] LT',\n        nextDay : '[Утре во] LT',\n        nextWeek : '[Во] dddd [во] LT',\n        lastDay : '[Вчера во] LT',\n        lastWeek : function () {\n            switch (this.day()) {\n                case 0:\n                case 3:\n                case 6:\n                    return '[Изминатата] dddd [во] LT';\n                case 1:\n                case 2:\n                case 4:\n                case 5:\n                    return '[Изминатиот] dddd [во] LT';\n            }\n        },\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'после %s',\n        past : 'пред %s',\n        s : 'неколку секунди',\n        m : 'минута',\n        mm : '%d минути',\n        h : 'час',\n        hh : '%d часа',\n        d : 'ден',\n        dd : '%d дена',\n        M : 'месец',\n        MM : '%d месеци',\n        y : 'година',\n        yy : '%d години'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}-(ев|ен|ти|ви|ри|ми)/,\n    ordinal : function (number) {\n        var lastDigit = number % 10,\n            last2Digits = number % 100;\n        if (number === 0) {\n            return number + '-ев';\n        } else if (last2Digits === 0) {\n            return number + '-ен';\n        } else if (last2Digits > 10 && last2Digits < 20) {\n            return number + '-ти';\n        } else if (lastDigit === 1) {\n            return number + '-ви';\n        } else if (lastDigit === 2) {\n            return number + '-ри';\n        } else if (lastDigit === 7 || lastDigit === 8) {\n            return number + '-ми';\n        } else {\n            return number + '-ти';\n        }\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 7  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\nreturn mk;\n\n})));\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/locale/ml.js",
    "content": "//! moment.js locale configuration\n//! locale : Malayalam [ml]\n//! author : Floyd Pink : https://github.com/floydpink\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\n\nvar ml = moment.defineLocale('ml', {\n    months : 'ജനുവരി_ഫെബ്രുവരി_മാർച്ച്_ഏപ്രിൽ_മേയ്_ജൂൺ_ജൂലൈ_ഓഗസ്റ്റ്_സെപ്റ്റംബർ_ഒക്ടോബർ_നവംബർ_ഡിസംബർ'.split('_'),\n    monthsShort : 'ജനു._ഫെബ്രു._മാർ._ഏപ്രി._മേയ്_ജൂൺ_ജൂലൈ._ഓഗ._സെപ്റ്റ._ഒക്ടോ._നവം._ഡിസം.'.split('_'),\n    monthsParseExact : true,\n    weekdays : 'ഞായറാഴ്ച_തിങ്കളാഴ്ച_ചൊവ്വാഴ്ച_ബുധനാഴ്ച_വ്യാഴാഴ്ച_വെള്ളിയാഴ്ച_ശനിയാഴ്ച'.split('_'),\n    weekdaysShort : 'ഞായർ_തിങ്കൾ_ചൊവ്വ_ബുധൻ_വ്യാഴം_വെള്ളി_ശനി'.split('_'),\n    weekdaysMin : 'ഞാ_തി_ചൊ_ബു_വ്യാ_വെ_ശ'.split('_'),\n    longDateFormat : {\n        LT : 'A h:mm -നു',\n        LTS : 'A h:mm:ss -നു',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY, A h:mm -നു',\n        LLLL : 'dddd, D MMMM YYYY, A h:mm -നു'\n    },\n    calendar : {\n        sameDay : '[ഇന്ന്] LT',\n        nextDay : '[നാളെ] LT',\n        nextWeek : 'dddd, LT',\n        lastDay : '[ഇന്നലെ] LT',\n        lastWeek : '[കഴിഞ്ഞ] dddd, LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : '%s കഴിഞ്ഞ്',\n        past : '%s മുൻപ്',\n        s : 'അൽപ നിമിഷങ്ങൾ',\n        m : 'ഒരു മിനിറ്റ്',\n        mm : '%d മിനിറ്റ്',\n        h : 'ഒരു മണിക്കൂർ',\n        hh : '%d മണിക്കൂർ',\n        d : 'ഒരു ദിവസം',\n        dd : '%d ദിവസം',\n        M : 'ഒരു മാസം',\n        MM : '%d മാസം',\n        y : 'ഒരു വർഷം',\n        yy : '%d വർഷം'\n    },\n    meridiemParse: /രാത്രി|രാവിലെ|ഉച്ച കഴിഞ്ഞ്|വൈകുന്നേരം|രാത്രി/i,\n    meridiemHour : function (hour, meridiem) {\n        if (hour === 12) {\n            hour = 0;\n        }\n        if ((meridiem === 'രാത്രി' && hour >= 4) ||\n                meridiem === 'ഉച്ച കഴിഞ്ഞ്' ||\n                meridiem === 'വൈകുന്നേരം') {\n            return hour + 12;\n        } else {\n            return hour;\n        }\n    },\n    meridiem : function (hour, minute, isLower) {\n        if (hour < 4) {\n            return 'രാത്രി';\n        } else if (hour < 12) {\n            return 'രാവിലെ';\n        } else if (hour < 17) {\n            return 'ഉച്ച കഴിഞ്ഞ്';\n        } else if (hour < 20) {\n            return 'വൈകുന്നേരം';\n        } else {\n            return 'രാത്രി';\n        }\n    }\n});\n\nreturn ml;\n\n})));\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/locale/mr.js",
    "content": "//! moment.js locale configuration\n//! locale : Marathi [mr]\n//! author : Harshad Kale : https://github.com/kalehv\n//! author : Vivek Athalye : https://github.com/vnathalye\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\n\nvar symbolMap = {\n    '1': '१',\n    '2': '२',\n    '3': '३',\n    '4': '४',\n    '5': '५',\n    '6': '६',\n    '7': '७',\n    '8': '८',\n    '9': '९',\n    '0': '०'\n};\nvar numberMap = {\n    '१': '1',\n    '२': '2',\n    '३': '3',\n    '४': '4',\n    '५': '5',\n    '६': '6',\n    '७': '7',\n    '८': '8',\n    '९': '9',\n    '०': '0'\n};\n\nfunction relativeTimeMr(number, withoutSuffix, string, isFuture)\n{\n    var output = '';\n    if (withoutSuffix) {\n        switch (string) {\n            case 's': output = 'काही सेकंद'; break;\n            case 'm': output = 'एक मिनिट'; break;\n            case 'mm': output = '%d मिनिटे'; break;\n            case 'h': output = 'एक तास'; break;\n            case 'hh': output = '%d तास'; break;\n            case 'd': output = 'एक दिवस'; break;\n            case 'dd': output = '%d दिवस'; break;\n            case 'M': output = 'एक महिना'; break;\n            case 'MM': output = '%d महिने'; break;\n            case 'y': output = 'एक वर्ष'; break;\n            case 'yy': output = '%d वर्षे'; break;\n        }\n    }\n    else {\n        switch (string) {\n            case 's': output = 'काही सेकंदां'; break;\n            case 'm': output = 'एका मिनिटा'; break;\n            case 'mm': output = '%d मिनिटां'; break;\n            case 'h': output = 'एका तासा'; break;\n            case 'hh': output = '%d तासां'; break;\n            case 'd': output = 'एका दिवसा'; break;\n            case 'dd': output = '%d दिवसां'; break;\n            case 'M': output = 'एका महिन्या'; break;\n            case 'MM': output = '%d महिन्यां'; break;\n            case 'y': output = 'एका वर्षा'; break;\n            case 'yy': output = '%d वर्षां'; break;\n        }\n    }\n    return output.replace(/%d/i, number);\n}\n\nvar mr = moment.defineLocale('mr', {\n    months : 'जानेवारी_फेब्रुवारी_मार्च_एप्रिल_मे_जून_जुलै_ऑगस्ट_सप्टेंबर_ऑक्टोबर_नोव्हेंबर_डिसेंबर'.split('_'),\n    monthsShort: 'जाने._फेब्रु._मार्च._एप्रि._मे._जून._जुलै._ऑग._सप्टें._ऑक्टो._नोव्हें._डिसें.'.split('_'),\n    monthsParseExact : true,\n    weekdays : 'रविवार_सोमवार_मंगळवार_बुधवार_गुरूवार_शुक्रवार_शनिवार'.split('_'),\n    weekdaysShort : 'रवि_सोम_मंगळ_बुध_गुरू_शुक्र_शनि'.split('_'),\n    weekdaysMin : 'र_सो_मं_बु_गु_शु_श'.split('_'),\n    longDateFormat : {\n        LT : 'A h:mm वाजता',\n        LTS : 'A h:mm:ss वाजता',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY, A h:mm वाजता',\n        LLLL : 'dddd, D MMMM YYYY, A h:mm वाजता'\n    },\n    calendar : {\n        sameDay : '[आज] LT',\n        nextDay : '[उद्या] LT',\n        nextWeek : 'dddd, LT',\n        lastDay : '[काल] LT',\n        lastWeek: '[मागील] dddd, LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future: '%sमध्ये',\n        past: '%sपूर्वी',\n        s: relativeTimeMr,\n        m: relativeTimeMr,\n        mm: relativeTimeMr,\n        h: relativeTimeMr,\n        hh: relativeTimeMr,\n        d: relativeTimeMr,\n        dd: relativeTimeMr,\n        M: relativeTimeMr,\n        MM: relativeTimeMr,\n        y: relativeTimeMr,\n        yy: relativeTimeMr\n    },\n    preparse: function (string) {\n        return string.replace(/[१२३४५६७८९०]/g, function (match) {\n            return numberMap[match];\n        });\n    },\n    postformat: function (string) {\n        return string.replace(/\\d/g, function (match) {\n            return symbolMap[match];\n        });\n    },\n    meridiemParse: /रात्री|सकाळी|दुपारी|सायंकाळी/,\n    meridiemHour : function (hour, meridiem) {\n        if (hour === 12) {\n            hour = 0;\n        }\n        if (meridiem === 'रात्री') {\n            return hour < 4 ? hour : hour + 12;\n        } else if (meridiem === 'सकाळी') {\n            return hour;\n        } else if (meridiem === 'दुपारी') {\n            return hour >= 10 ? hour : hour + 12;\n        } else if (meridiem === 'सायंकाळी') {\n            return hour + 12;\n        }\n    },\n    meridiem: function (hour, minute, isLower) {\n        if (hour < 4) {\n            return 'रात्री';\n        } else if (hour < 10) {\n            return 'सकाळी';\n        } else if (hour < 17) {\n            return 'दुपारी';\n        } else if (hour < 20) {\n            return 'सायंकाळी';\n        } else {\n            return 'रात्री';\n        }\n    },\n    week : {\n        dow : 0, // Sunday is the first day of the week.\n        doy : 6  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\nreturn mr;\n\n})));\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/locale/ms-my.js",
    "content": "//! moment.js locale configuration\n//! locale : Malay [ms-my]\n//! note : DEPRECATED, the correct one is [ms]\n//! author : Weldan Jamili : https://github.com/weldan\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\n\nvar msMy = moment.defineLocale('ms-my', {\n    months : 'Januari_Februari_Mac_April_Mei_Jun_Julai_Ogos_September_Oktober_November_Disember'.split('_'),\n    monthsShort : 'Jan_Feb_Mac_Apr_Mei_Jun_Jul_Ogs_Sep_Okt_Nov_Dis'.split('_'),\n    weekdays : 'Ahad_Isnin_Selasa_Rabu_Khamis_Jumaat_Sabtu'.split('_'),\n    weekdaysShort : 'Ahd_Isn_Sel_Rab_Kha_Jum_Sab'.split('_'),\n    weekdaysMin : 'Ah_Is_Sl_Rb_Km_Jm_Sb'.split('_'),\n    longDateFormat : {\n        LT : 'HH.mm',\n        LTS : 'HH.mm.ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY [pukul] HH.mm',\n        LLLL : 'dddd, D MMMM YYYY [pukul] HH.mm'\n    },\n    meridiemParse: /pagi|tengahari|petang|malam/,\n    meridiemHour: function (hour, meridiem) {\n        if (hour === 12) {\n            hour = 0;\n        }\n        if (meridiem === 'pagi') {\n            return hour;\n        } else if (meridiem === 'tengahari') {\n            return hour >= 11 ? hour : hour + 12;\n        } else if (meridiem === 'petang' || meridiem === 'malam') {\n            return hour + 12;\n        }\n    },\n    meridiem : function (hours, minutes, isLower) {\n        if (hours < 11) {\n            return 'pagi';\n        } else if (hours < 15) {\n            return 'tengahari';\n        } else if (hours < 19) {\n            return 'petang';\n        } else {\n            return 'malam';\n        }\n    },\n    calendar : {\n        sameDay : '[Hari ini pukul] LT',\n        nextDay : '[Esok pukul] LT',\n        nextWeek : 'dddd [pukul] LT',\n        lastDay : '[Kelmarin pukul] LT',\n        lastWeek : 'dddd [lepas pukul] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'dalam %s',\n        past : '%s yang lepas',\n        s : 'beberapa saat',\n        m : 'seminit',\n        mm : '%d minit',\n        h : 'sejam',\n        hh : '%d jam',\n        d : 'sehari',\n        dd : '%d hari',\n        M : 'sebulan',\n        MM : '%d bulan',\n        y : 'setahun',\n        yy : '%d tahun'\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 7  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\nreturn msMy;\n\n})));\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/locale/ms.js",
    "content": "//! moment.js locale configuration\n//! locale : Malay [ms]\n//! author : Weldan Jamili : https://github.com/weldan\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\n\nvar ms = moment.defineLocale('ms', {\n    months : 'Januari_Februari_Mac_April_Mei_Jun_Julai_Ogos_September_Oktober_November_Disember'.split('_'),\n    monthsShort : 'Jan_Feb_Mac_Apr_Mei_Jun_Jul_Ogs_Sep_Okt_Nov_Dis'.split('_'),\n    weekdays : 'Ahad_Isnin_Selasa_Rabu_Khamis_Jumaat_Sabtu'.split('_'),\n    weekdaysShort : 'Ahd_Isn_Sel_Rab_Kha_Jum_Sab'.split('_'),\n    weekdaysMin : 'Ah_Is_Sl_Rb_Km_Jm_Sb'.split('_'),\n    longDateFormat : {\n        LT : 'HH.mm',\n        LTS : 'HH.mm.ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY [pukul] HH.mm',\n        LLLL : 'dddd, D MMMM YYYY [pukul] HH.mm'\n    },\n    meridiemParse: /pagi|tengahari|petang|malam/,\n    meridiemHour: function (hour, meridiem) {\n        if (hour === 12) {\n            hour = 0;\n        }\n        if (meridiem === 'pagi') {\n            return hour;\n        } else if (meridiem === 'tengahari') {\n            return hour >= 11 ? hour : hour + 12;\n        } else if (meridiem === 'petang' || meridiem === 'malam') {\n            return hour + 12;\n        }\n    },\n    meridiem : function (hours, minutes, isLower) {\n        if (hours < 11) {\n            return 'pagi';\n        } else if (hours < 15) {\n            return 'tengahari';\n        } else if (hours < 19) {\n            return 'petang';\n        } else {\n            return 'malam';\n        }\n    },\n    calendar : {\n        sameDay : '[Hari ini pukul] LT',\n        nextDay : '[Esok pukul] LT',\n        nextWeek : 'dddd [pukul] LT',\n        lastDay : '[Kelmarin pukul] LT',\n        lastWeek : 'dddd [lepas pukul] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'dalam %s',\n        past : '%s yang lepas',\n        s : 'beberapa saat',\n        m : 'seminit',\n        mm : '%d minit',\n        h : 'sejam',\n        hh : '%d jam',\n        d : 'sehari',\n        dd : '%d hari',\n        M : 'sebulan',\n        MM : '%d bulan',\n        y : 'setahun',\n        yy : '%d tahun'\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 7  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\nreturn ms;\n\n})));\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/locale/my.js",
    "content": "//! moment.js locale configuration\n//! locale : Burmese [my]\n//! author : Squar team, mysquar.com\n//! author : David Rossellat : https://github.com/gholadr\n//! author : Tin Aung Lin : https://github.com/thanyawzinmin\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\n\nvar symbolMap = {\n    '1': '၁',\n    '2': '၂',\n    '3': '၃',\n    '4': '၄',\n    '5': '၅',\n    '6': '၆',\n    '7': '၇',\n    '8': '၈',\n    '9': '၉',\n    '0': '၀'\n};\nvar numberMap = {\n    '၁': '1',\n    '၂': '2',\n    '၃': '3',\n    '၄': '4',\n    '၅': '5',\n    '၆': '6',\n    '၇': '7',\n    '၈': '8',\n    '၉': '9',\n    '၀': '0'\n};\n\nvar my = moment.defineLocale('my', {\n    months: 'ဇန်နဝါရီ_ဖေဖော်ဝါရီ_မတ်_ဧပြီ_မေ_ဇွန်_ဇူလိုင်_သြဂုတ်_စက်တင်ဘာ_အောက်တိုဘာ_နိုဝင်ဘာ_ဒီဇင်ဘာ'.split('_'),\n    monthsShort: 'ဇန်_ဖေ_မတ်_ပြီ_မေ_ဇွန်_လိုင်_သြ_စက်_အောက်_နို_ဒီ'.split('_'),\n    weekdays: 'တနင်္ဂနွေ_တနင်္လာ_အင်္ဂါ_ဗုဒ္ဓဟူး_ကြာသပတေး_သောကြာ_စနေ'.split('_'),\n    weekdaysShort: 'နွေ_လာ_ဂါ_ဟူး_ကြာ_သော_နေ'.split('_'),\n    weekdaysMin: 'နွေ_လာ_ဂါ_ဟူး_ကြာ_သော_နေ'.split('_'),\n\n    longDateFormat: {\n        LT: 'HH:mm',\n        LTS: 'HH:mm:ss',\n        L: 'DD/MM/YYYY',\n        LL: 'D MMMM YYYY',\n        LLL: 'D MMMM YYYY HH:mm',\n        LLLL: 'dddd D MMMM YYYY HH:mm'\n    },\n    calendar: {\n        sameDay: '[ယနေ.] LT [မှာ]',\n        nextDay: '[မနက်ဖြန်] LT [မှာ]',\n        nextWeek: 'dddd LT [မှာ]',\n        lastDay: '[မနေ.က] LT [မှာ]',\n        lastWeek: '[ပြီးခဲ့သော] dddd LT [မှာ]',\n        sameElse: 'L'\n    },\n    relativeTime: {\n        future: 'လာမည့် %s မှာ',\n        past: 'လွန်ခဲ့သော %s က',\n        s: 'စက္ကန်.အနည်းငယ်',\n        m: 'တစ်မိနစ်',\n        mm: '%d မိနစ်',\n        h: 'တစ်နာရီ',\n        hh: '%d နာရီ',\n        d: 'တစ်ရက်',\n        dd: '%d ရက်',\n        M: 'တစ်လ',\n        MM: '%d လ',\n        y: 'တစ်နှစ်',\n        yy: '%d နှစ်'\n    },\n    preparse: function (string) {\n        return string.replace(/[၁၂၃၄၅၆၇၈၉၀]/g, function (match) {\n            return numberMap[match];\n        });\n    },\n    postformat: function (string) {\n        return string.replace(/\\d/g, function (match) {\n            return symbolMap[match];\n        });\n    },\n    week: {\n        dow: 1, // Monday is the first day of the week.\n        doy: 4 // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\nreturn my;\n\n})));\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/locale/nb.js",
    "content": "//! moment.js locale configuration\n//! locale : Norwegian Bokmål [nb]\n//! authors : Espen Hovlandsdal : https://github.com/rexxars\n//!           Sigurd Gartmann : https://github.com/sigurdga\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\n\nvar nb = moment.defineLocale('nb', {\n    months : 'januar_februar_mars_april_mai_juni_juli_august_september_oktober_november_desember'.split('_'),\n    monthsShort : 'jan._feb._mars_april_mai_juni_juli_aug._sep._okt._nov._des.'.split('_'),\n    monthsParseExact : true,\n    weekdays : 'søndag_mandag_tirsdag_onsdag_torsdag_fredag_lørdag'.split('_'),\n    weekdaysShort : 'sø._ma._ti._on._to._fr._lø.'.split('_'),\n    weekdaysMin : 'sø_ma_ti_on_to_fr_lø'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD.MM.YYYY',\n        LL : 'D. MMMM YYYY',\n        LLL : 'D. MMMM YYYY [kl.] HH:mm',\n        LLLL : 'dddd D. MMMM YYYY [kl.] HH:mm'\n    },\n    calendar : {\n        sameDay: '[i dag kl.] LT',\n        nextDay: '[i morgen kl.] LT',\n        nextWeek: 'dddd [kl.] LT',\n        lastDay: '[i går kl.] LT',\n        lastWeek: '[forrige] dddd [kl.] LT',\n        sameElse: 'L'\n    },\n    relativeTime : {\n        future : 'om %s',\n        past : '%s siden',\n        s : 'noen sekunder',\n        m : 'ett minutt',\n        mm : '%d minutter',\n        h : 'en time',\n        hh : '%d timer',\n        d : 'en dag',\n        dd : '%d dager',\n        M : 'en måned',\n        MM : '%d måneder',\n        y : 'ett år',\n        yy : '%d år'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}\\./,\n    ordinal : '%d.',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\nreturn nb;\n\n})));\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/locale/ne.js",
    "content": "//! moment.js locale configuration\n//! locale : Nepalese [ne]\n//! author : suvash : https://github.com/suvash\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\n\nvar symbolMap = {\n    '1': '१',\n    '2': '२',\n    '3': '३',\n    '4': '४',\n    '5': '५',\n    '6': '६',\n    '7': '७',\n    '8': '८',\n    '9': '९',\n    '0': '०'\n};\nvar numberMap = {\n    '१': '1',\n    '२': '2',\n    '३': '3',\n    '४': '4',\n    '५': '5',\n    '६': '6',\n    '७': '7',\n    '८': '8',\n    '९': '9',\n    '०': '0'\n};\n\nvar ne = moment.defineLocale('ne', {\n    months : 'जनवरी_फेब्रुवरी_मार्च_अप्रिल_मई_जुन_जुलाई_अगष्ट_सेप्टेम्बर_अक्टोबर_नोभेम्बर_डिसेम्बर'.split('_'),\n    monthsShort : 'जन._फेब्रु._मार्च_अप्रि._मई_जुन_जुलाई._अग._सेप्ट._अक्टो._नोभे._डिसे.'.split('_'),\n    monthsParseExact : true,\n    weekdays : 'आइतबार_सोमबार_मङ्गलबार_बुधबार_बिहिबार_शुक्रबार_शनिबार'.split('_'),\n    weekdaysShort : 'आइत._सोम._मङ्गल._बुध._बिहि._शुक्र._शनि.'.split('_'),\n    weekdaysMin : 'आ._सो._मं._बु._बि._शु._श.'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat : {\n        LT : 'Aको h:mm बजे',\n        LTS : 'Aको h:mm:ss बजे',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY, Aको h:mm बजे',\n        LLLL : 'dddd, D MMMM YYYY, Aको h:mm बजे'\n    },\n    preparse: function (string) {\n        return string.replace(/[१२३४५६७८९०]/g, function (match) {\n            return numberMap[match];\n        });\n    },\n    postformat: function (string) {\n        return string.replace(/\\d/g, function (match) {\n            return symbolMap[match];\n        });\n    },\n    meridiemParse: /राति|बिहान|दिउँसो|साँझ/,\n    meridiemHour : function (hour, meridiem) {\n        if (hour === 12) {\n            hour = 0;\n        }\n        if (meridiem === 'राति') {\n            return hour < 4 ? hour : hour + 12;\n        } else if (meridiem === 'बिहान') {\n            return hour;\n        } else if (meridiem === 'दिउँसो') {\n            return hour >= 10 ? hour : hour + 12;\n        } else if (meridiem === 'साँझ') {\n            return hour + 12;\n        }\n    },\n    meridiem : function (hour, minute, isLower) {\n        if (hour < 3) {\n            return 'राति';\n        } else if (hour < 12) {\n            return 'बिहान';\n        } else if (hour < 16) {\n            return 'दिउँसो';\n        } else if (hour < 20) {\n            return 'साँझ';\n        } else {\n            return 'राति';\n        }\n    },\n    calendar : {\n        sameDay : '[आज] LT',\n        nextDay : '[भोलि] LT',\n        nextWeek : '[आउँदो] dddd[,] LT',\n        lastDay : '[हिजो] LT',\n        lastWeek : '[गएको] dddd[,] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : '%sमा',\n        past : '%s अगाडि',\n        s : 'केही क्षण',\n        m : 'एक मिनेट',\n        mm : '%d मिनेट',\n        h : 'एक घण्टा',\n        hh : '%d घण्टा',\n        d : 'एक दिन',\n        dd : '%d दिन',\n        M : 'एक महिना',\n        MM : '%d महिना',\n        y : 'एक बर्ष',\n        yy : '%d बर्ष'\n    },\n    week : {\n        dow : 0, // Sunday is the first day of the week.\n        doy : 6  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\nreturn ne;\n\n})));\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/locale/nl-be.js",
    "content": "//! moment.js locale configuration\n//! locale : Dutch (Belgium) [nl-be]\n//! author : Joris Röling : https://github.com/jorisroling\n//! author : Jacob Middag : https://github.com/middagj\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\n\nvar monthsShortWithDots = 'jan._feb._mrt._apr._mei_jun._jul._aug._sep._okt._nov._dec.'.split('_');\nvar monthsShortWithoutDots = 'jan_feb_mrt_apr_mei_jun_jul_aug_sep_okt_nov_dec'.split('_');\n\nvar monthsParse = [/^jan/i, /^feb/i, /^maart|mrt.?$/i, /^apr/i, /^mei$/i, /^jun[i.]?$/i, /^jul[i.]?$/i, /^aug/i, /^sep/i, /^okt/i, /^nov/i, /^dec/i];\nvar monthsRegex = /^(januari|februari|maart|april|mei|april|ju[nl]i|augustus|september|oktober|november|december|jan\\.?|feb\\.?|mrt\\.?|apr\\.?|ju[nl]\\.?|aug\\.?|sep\\.?|okt\\.?|nov\\.?|dec\\.?)/i;\n\nvar nlBe = moment.defineLocale('nl-be', {\n    months : 'januari_februari_maart_april_mei_juni_juli_augustus_september_oktober_november_december'.split('_'),\n    monthsShort : function (m, format) {\n        if (!m) {\n            return monthsShortWithDots;\n        } else if (/-MMM-/.test(format)) {\n            return monthsShortWithoutDots[m.month()];\n        } else {\n            return monthsShortWithDots[m.month()];\n        }\n    },\n\n    monthsRegex: monthsRegex,\n    monthsShortRegex: monthsRegex,\n    monthsStrictRegex: /^(januari|februari|maart|mei|ju[nl]i|april|augustus|september|oktober|november|december)/i,\n    monthsShortStrictRegex: /^(jan\\.?|feb\\.?|mrt\\.?|apr\\.?|mei|ju[nl]\\.?|aug\\.?|sep\\.?|okt\\.?|nov\\.?|dec\\.?)/i,\n\n    monthsParse : monthsParse,\n    longMonthsParse : monthsParse,\n    shortMonthsParse : monthsParse,\n\n    weekdays : 'zondag_maandag_dinsdag_woensdag_donderdag_vrijdag_zaterdag'.split('_'),\n    weekdaysShort : 'zo._ma._di._wo._do._vr._za.'.split('_'),\n    weekdaysMin : 'Zo_Ma_Di_Wo_Do_Vr_Za'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY HH:mm',\n        LLLL : 'dddd D MMMM YYYY HH:mm'\n    },\n    calendar : {\n        sameDay: '[vandaag om] LT',\n        nextDay: '[morgen om] LT',\n        nextWeek: 'dddd [om] LT',\n        lastDay: '[gisteren om] LT',\n        lastWeek: '[afgelopen] dddd [om] LT',\n        sameElse: 'L'\n    },\n    relativeTime : {\n        future : 'over %s',\n        past : '%s geleden',\n        s : 'een paar seconden',\n        m : 'één minuut',\n        mm : '%d minuten',\n        h : 'één uur',\n        hh : '%d uur',\n        d : 'één dag',\n        dd : '%d dagen',\n        M : 'één maand',\n        MM : '%d maanden',\n        y : 'één jaar',\n        yy : '%d jaar'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}(ste|de)/,\n    ordinal : function (number) {\n        return number + ((number === 1 || number === 8 || number >= 20) ? 'ste' : 'de');\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\nreturn nlBe;\n\n})));\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/locale/nl.js",
    "content": "//! moment.js locale configuration\n//! locale : Dutch [nl]\n//! author : Joris Röling : https://github.com/jorisroling\n//! author : Jacob Middag : https://github.com/middagj\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\n\nvar monthsShortWithDots = 'jan._feb._mrt._apr._mei_jun._jul._aug._sep._okt._nov._dec.'.split('_');\nvar monthsShortWithoutDots = 'jan_feb_mrt_apr_mei_jun_jul_aug_sep_okt_nov_dec'.split('_');\n\nvar monthsParse = [/^jan/i, /^feb/i, /^maart|mrt.?$/i, /^apr/i, /^mei$/i, /^jun[i.]?$/i, /^jul[i.]?$/i, /^aug/i, /^sep/i, /^okt/i, /^nov/i, /^dec/i];\nvar monthsRegex = /^(januari|februari|maart|april|mei|april|ju[nl]i|augustus|september|oktober|november|december|jan\\.?|feb\\.?|mrt\\.?|apr\\.?|ju[nl]\\.?|aug\\.?|sep\\.?|okt\\.?|nov\\.?|dec\\.?)/i;\n\nvar nl = moment.defineLocale('nl', {\n    months : 'januari_februari_maart_april_mei_juni_juli_augustus_september_oktober_november_december'.split('_'),\n    monthsShort : function (m, format) {\n        if (!m) {\n            return monthsShortWithDots;\n        } else if (/-MMM-/.test(format)) {\n            return monthsShortWithoutDots[m.month()];\n        } else {\n            return monthsShortWithDots[m.month()];\n        }\n    },\n\n    monthsRegex: monthsRegex,\n    monthsShortRegex: monthsRegex,\n    monthsStrictRegex: /^(januari|februari|maart|mei|ju[nl]i|april|augustus|september|oktober|november|december)/i,\n    monthsShortStrictRegex: /^(jan\\.?|feb\\.?|mrt\\.?|apr\\.?|mei|ju[nl]\\.?|aug\\.?|sep\\.?|okt\\.?|nov\\.?|dec\\.?)/i,\n\n    monthsParse : monthsParse,\n    longMonthsParse : monthsParse,\n    shortMonthsParse : monthsParse,\n\n    weekdays : 'zondag_maandag_dinsdag_woensdag_donderdag_vrijdag_zaterdag'.split('_'),\n    weekdaysShort : 'zo._ma._di._wo._do._vr._za.'.split('_'),\n    weekdaysMin : 'Zo_Ma_Di_Wo_Do_Vr_Za'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD-MM-YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY HH:mm',\n        LLLL : 'dddd D MMMM YYYY HH:mm'\n    },\n    calendar : {\n        sameDay: '[vandaag om] LT',\n        nextDay: '[morgen om] LT',\n        nextWeek: 'dddd [om] LT',\n        lastDay: '[gisteren om] LT',\n        lastWeek: '[afgelopen] dddd [om] LT',\n        sameElse: 'L'\n    },\n    relativeTime : {\n        future : 'over %s',\n        past : '%s geleden',\n        s : 'een paar seconden',\n        m : 'één minuut',\n        mm : '%d minuten',\n        h : 'één uur',\n        hh : '%d uur',\n        d : 'één dag',\n        dd : '%d dagen',\n        M : 'één maand',\n        MM : '%d maanden',\n        y : 'één jaar',\n        yy : '%d jaar'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}(ste|de)/,\n    ordinal : function (number) {\n        return number + ((number === 1 || number === 8 || number >= 20) ? 'ste' : 'de');\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\nreturn nl;\n\n})));\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/locale/nn.js",
    "content": "//! moment.js locale configuration\n//! locale : Nynorsk [nn]\n//! author : https://github.com/mechuwind\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\n\nvar nn = moment.defineLocale('nn', {\n    months : 'januar_februar_mars_april_mai_juni_juli_august_september_oktober_november_desember'.split('_'),\n    monthsShort : 'jan_feb_mar_apr_mai_jun_jul_aug_sep_okt_nov_des'.split('_'),\n    weekdays : 'sundag_måndag_tysdag_onsdag_torsdag_fredag_laurdag'.split('_'),\n    weekdaysShort : 'sun_mån_tys_ons_tor_fre_lau'.split('_'),\n    weekdaysMin : 'su_må_ty_on_to_fr_lø'.split('_'),\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD.MM.YYYY',\n        LL : 'D. MMMM YYYY',\n        LLL : 'D. MMMM YYYY [kl.] H:mm',\n        LLLL : 'dddd D. MMMM YYYY [kl.] HH:mm'\n    },\n    calendar : {\n        sameDay: '[I dag klokka] LT',\n        nextDay: '[I morgon klokka] LT',\n        nextWeek: 'dddd [klokka] LT',\n        lastDay: '[I går klokka] LT',\n        lastWeek: '[Føregåande] dddd [klokka] LT',\n        sameElse: 'L'\n    },\n    relativeTime : {\n        future : 'om %s',\n        past : '%s sidan',\n        s : 'nokre sekund',\n        m : 'eit minutt',\n        mm : '%d minutt',\n        h : 'ein time',\n        hh : '%d timar',\n        d : 'ein dag',\n        dd : '%d dagar',\n        M : 'ein månad',\n        MM : '%d månader',\n        y : 'eit år',\n        yy : '%d år'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}\\./,\n    ordinal : '%d.',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\nreturn nn;\n\n})));\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/locale/pa-in.js",
    "content": "//! moment.js locale configuration\n//! locale : Punjabi (India) [pa-in]\n//! author : Harpreet Singh : https://github.com/harpreetkhalsagtbit\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\n\nvar symbolMap = {\n    '1': '੧',\n    '2': '੨',\n    '3': '੩',\n    '4': '੪',\n    '5': '੫',\n    '6': '੬',\n    '7': '੭',\n    '8': '੮',\n    '9': '੯',\n    '0': '੦'\n};\nvar numberMap = {\n    '੧': '1',\n    '੨': '2',\n    '੩': '3',\n    '੪': '4',\n    '੫': '5',\n    '੬': '6',\n    '੭': '7',\n    '੮': '8',\n    '੯': '9',\n    '੦': '0'\n};\n\nvar paIn = moment.defineLocale('pa-in', {\n    // There are months name as per Nanakshahi Calender but they are not used as rigidly in modern Punjabi.\n    months : 'ਜਨਵਰੀ_ਫ਼ਰਵਰੀ_ਮਾਰਚ_ਅਪ੍ਰੈਲ_ਮਈ_ਜੂਨ_ਜੁਲਾਈ_ਅਗਸਤ_ਸਤੰਬਰ_ਅਕਤੂਬਰ_ਨਵੰਬਰ_ਦਸੰਬਰ'.split('_'),\n    monthsShort : 'ਜਨਵਰੀ_ਫ਼ਰਵਰੀ_ਮਾਰਚ_ਅਪ੍ਰੈਲ_ਮਈ_ਜੂਨ_ਜੁਲਾਈ_ਅਗਸਤ_ਸਤੰਬਰ_ਅਕਤੂਬਰ_ਨਵੰਬਰ_ਦਸੰਬਰ'.split('_'),\n    weekdays : 'ਐਤਵਾਰ_ਸੋਮਵਾਰ_ਮੰਗਲਵਾਰ_ਬੁਧਵਾਰ_ਵੀਰਵਾਰ_ਸ਼ੁੱਕਰਵਾਰ_ਸ਼ਨੀਚਰਵਾਰ'.split('_'),\n    weekdaysShort : 'ਐਤ_ਸੋਮ_ਮੰਗਲ_ਬੁਧ_ਵੀਰ_ਸ਼ੁਕਰ_ਸ਼ਨੀ'.split('_'),\n    weekdaysMin : 'ਐਤ_ਸੋਮ_ਮੰਗਲ_ਬੁਧ_ਵੀਰ_ਸ਼ੁਕਰ_ਸ਼ਨੀ'.split('_'),\n    longDateFormat : {\n        LT : 'A h:mm ਵਜੇ',\n        LTS : 'A h:mm:ss ਵਜੇ',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY, A h:mm ਵਜੇ',\n        LLLL : 'dddd, D MMMM YYYY, A h:mm ਵਜੇ'\n    },\n    calendar : {\n        sameDay : '[ਅਜ] LT',\n        nextDay : '[ਕਲ] LT',\n        nextWeek : 'dddd, LT',\n        lastDay : '[ਕਲ] LT',\n        lastWeek : '[ਪਿਛਲੇ] dddd, LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : '%s ਵਿੱਚ',\n        past : '%s ਪਿਛਲੇ',\n        s : 'ਕੁਝ ਸਕਿੰਟ',\n        m : 'ਇਕ ਮਿੰਟ',\n        mm : '%d ਮਿੰਟ',\n        h : 'ਇੱਕ ਘੰਟਾ',\n        hh : '%d ਘੰਟੇ',\n        d : 'ਇੱਕ ਦਿਨ',\n        dd : '%d ਦਿਨ',\n        M : 'ਇੱਕ ਮਹੀਨਾ',\n        MM : '%d ਮਹੀਨੇ',\n        y : 'ਇੱਕ ਸਾਲ',\n        yy : '%d ਸਾਲ'\n    },\n    preparse: function (string) {\n        return string.replace(/[੧੨੩੪੫੬੭੮੯੦]/g, function (match) {\n            return numberMap[match];\n        });\n    },\n    postformat: function (string) {\n        return string.replace(/\\d/g, function (match) {\n            return symbolMap[match];\n        });\n    },\n    // Punjabi notation for meridiems are quite fuzzy in practice. While there exists\n    // a rigid notion of a 'Pahar' it is not used as rigidly in modern Punjabi.\n    meridiemParse: /ਰਾਤ|ਸਵੇਰ|ਦੁਪਹਿਰ|ਸ਼ਾਮ/,\n    meridiemHour : function (hour, meridiem) {\n        if (hour === 12) {\n            hour = 0;\n        }\n        if (meridiem === 'ਰਾਤ') {\n            return hour < 4 ? hour : hour + 12;\n        } else if (meridiem === 'ਸਵੇਰ') {\n            return hour;\n        } else if (meridiem === 'ਦੁਪਹਿਰ') {\n            return hour >= 10 ? hour : hour + 12;\n        } else if (meridiem === 'ਸ਼ਾਮ') {\n            return hour + 12;\n        }\n    },\n    meridiem : function (hour, minute, isLower) {\n        if (hour < 4) {\n            return 'ਰਾਤ';\n        } else if (hour < 10) {\n            return 'ਸਵੇਰ';\n        } else if (hour < 17) {\n            return 'ਦੁਪਹਿਰ';\n        } else if (hour < 20) {\n            return 'ਸ਼ਾਮ';\n        } else {\n            return 'ਰਾਤ';\n        }\n    },\n    week : {\n        dow : 0, // Sunday is the first day of the week.\n        doy : 6  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\nreturn paIn;\n\n})));\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/locale/pl.js",
    "content": "//! moment.js locale configuration\n//! locale : Polish [pl]\n//! author : Rafal Hirsz : https://github.com/evoL\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\n\nvar monthsNominative = 'styczeń_luty_marzec_kwiecień_maj_czerwiec_lipiec_sierpień_wrzesień_październik_listopad_grudzień'.split('_');\nvar monthsSubjective = 'stycznia_lutego_marca_kwietnia_maja_czerwca_lipca_sierpnia_września_października_listopada_grudnia'.split('_');\nfunction plural(n) {\n    return (n % 10 < 5) && (n % 10 > 1) && ((~~(n / 10) % 10) !== 1);\n}\nfunction translate(number, withoutSuffix, key) {\n    var result = number + ' ';\n    switch (key) {\n        case 'm':\n            return withoutSuffix ? 'minuta' : 'minutę';\n        case 'mm':\n            return result + (plural(number) ? 'minuty' : 'minut');\n        case 'h':\n            return withoutSuffix  ? 'godzina'  : 'godzinę';\n        case 'hh':\n            return result + (plural(number) ? 'godziny' : 'godzin');\n        case 'MM':\n            return result + (plural(number) ? 'miesiące' : 'miesięcy');\n        case 'yy':\n            return result + (plural(number) ? 'lata' : 'lat');\n    }\n}\n\nvar pl = moment.defineLocale('pl', {\n    months : function (momentToFormat, format) {\n        if (!momentToFormat) {\n            return monthsNominative;\n        } else if (format === '') {\n            // Hack: if format empty we know this is used to generate\n            // RegExp by moment. Give then back both valid forms of months\n            // in RegExp ready format.\n            return '(' + monthsSubjective[momentToFormat.month()] + '|' + monthsNominative[momentToFormat.month()] + ')';\n        } else if (/D MMMM/.test(format)) {\n            return monthsSubjective[momentToFormat.month()];\n        } else {\n            return monthsNominative[momentToFormat.month()];\n        }\n    },\n    monthsShort : 'sty_lut_mar_kwi_maj_cze_lip_sie_wrz_paź_lis_gru'.split('_'),\n    weekdays : 'niedziela_poniedziałek_wtorek_środa_czwartek_piątek_sobota'.split('_'),\n    weekdaysShort : 'ndz_pon_wt_śr_czw_pt_sob'.split('_'),\n    weekdaysMin : 'Nd_Pn_Wt_Śr_Cz_Pt_So'.split('_'),\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD.MM.YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY HH:mm',\n        LLLL : 'dddd, D MMMM YYYY HH:mm'\n    },\n    calendar : {\n        sameDay: '[Dziś o] LT',\n        nextDay: '[Jutro o] LT',\n        nextWeek: '[W] dddd [o] LT',\n        lastDay: '[Wczoraj o] LT',\n        lastWeek: function () {\n            switch (this.day()) {\n                case 0:\n                    return '[W zeszłą niedzielę o] LT';\n                case 3:\n                    return '[W zeszłą środę o] LT';\n                case 6:\n                    return '[W zeszłą sobotę o] LT';\n                default:\n                    return '[W zeszły] dddd [o] LT';\n            }\n        },\n        sameElse: 'L'\n    },\n    relativeTime : {\n        future : 'za %s',\n        past : '%s temu',\n        s : 'kilka sekund',\n        m : translate,\n        mm : translate,\n        h : translate,\n        hh : translate,\n        d : '1 dzień',\n        dd : '%d dni',\n        M : 'miesiąc',\n        MM : translate,\n        y : 'rok',\n        yy : translate\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}\\./,\n    ordinal : '%d.',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\nreturn pl;\n\n})));\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/locale/pt-br.js",
    "content": "//! moment.js locale configuration\n//! locale : Portuguese (Brazil) [pt-br]\n//! author : Caio Ribeiro Pereira : https://github.com/caio-ribeiro-pereira\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\n\nvar ptBr = moment.defineLocale('pt-br', {\n    months : 'Janeiro_Fevereiro_Março_Abril_Maio_Junho_Julho_Agosto_Setembro_Outubro_Novembro_Dezembro'.split('_'),\n    monthsShort : 'Jan_Fev_Mar_Abr_Mai_Jun_Jul_Ago_Set_Out_Nov_Dez'.split('_'),\n    weekdays : 'Domingo_Segunda-feira_Terça-feira_Quarta-feira_Quinta-feira_Sexta-feira_Sábado'.split('_'),\n    weekdaysShort : 'Dom_Seg_Ter_Qua_Qui_Sex_Sáb'.split('_'),\n    weekdaysMin : 'Do_2ª_3ª_4ª_5ª_6ª_Sá'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D [de] MMMM [de] YYYY',\n        LLL : 'D [de] MMMM [de] YYYY [às] HH:mm',\n        LLLL : 'dddd, D [de] MMMM [de] YYYY [às] HH:mm'\n    },\n    calendar : {\n        sameDay: '[Hoje às] LT',\n        nextDay: '[Amanhã às] LT',\n        nextWeek: 'dddd [às] LT',\n        lastDay: '[Ontem às] LT',\n        lastWeek: function () {\n            return (this.day() === 0 || this.day() === 6) ?\n                '[Último] dddd [às] LT' : // Saturday + Sunday\n                '[Última] dddd [às] LT'; // Monday - Friday\n        },\n        sameElse: 'L'\n    },\n    relativeTime : {\n        future : 'em %s',\n        past : '%s atrás',\n        s : 'poucos segundos',\n        m : 'um minuto',\n        mm : '%d minutos',\n        h : 'uma hora',\n        hh : '%d horas',\n        d : 'um dia',\n        dd : '%d dias',\n        M : 'um mês',\n        MM : '%d meses',\n        y : 'um ano',\n        yy : '%d anos'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}º/,\n    ordinal : '%dº'\n});\n\nreturn ptBr;\n\n})));\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/locale/pt.js",
    "content": "//! moment.js locale configuration\n//! locale : Portuguese [pt]\n//! author : Jefferson : https://github.com/jalex79\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\n\nvar pt = moment.defineLocale('pt', {\n    months : 'Janeiro_Fevereiro_Março_Abril_Maio_Junho_Julho_Agosto_Setembro_Outubro_Novembro_Dezembro'.split('_'),\n    monthsShort : 'Jan_Fev_Mar_Abr_Mai_Jun_Jul_Ago_Set_Out_Nov_Dez'.split('_'),\n    weekdays : 'Domingo_Segunda-Feira_Terça-Feira_Quarta-Feira_Quinta-Feira_Sexta-Feira_Sábado'.split('_'),\n    weekdaysShort : 'Dom_Seg_Ter_Qua_Qui_Sex_Sáb'.split('_'),\n    weekdaysMin : 'Do_2ª_3ª_4ª_5ª_6ª_Sá'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D [de] MMMM [de] YYYY',\n        LLL : 'D [de] MMMM [de] YYYY HH:mm',\n        LLLL : 'dddd, D [de] MMMM [de] YYYY HH:mm'\n    },\n    calendar : {\n        sameDay: '[Hoje às] LT',\n        nextDay: '[Amanhã às] LT',\n        nextWeek: 'dddd [às] LT',\n        lastDay: '[Ontem às] LT',\n        lastWeek: function () {\n            return (this.day() === 0 || this.day() === 6) ?\n                '[Último] dddd [às] LT' : // Saturday + Sunday\n                '[Última] dddd [às] LT'; // Monday - Friday\n        },\n        sameElse: 'L'\n    },\n    relativeTime : {\n        future : 'em %s',\n        past : 'há %s',\n        s : 'segundos',\n        m : 'um minuto',\n        mm : '%d minutos',\n        h : 'uma hora',\n        hh : '%d horas',\n        d : 'um dia',\n        dd : '%d dias',\n        M : 'um mês',\n        MM : '%d meses',\n        y : 'um ano',\n        yy : '%d anos'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}º/,\n    ordinal : '%dº',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\nreturn pt;\n\n})));\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/locale/ro.js",
    "content": "//! moment.js locale configuration\n//! locale : Romanian [ro]\n//! author : Vlad Gurdiga : https://github.com/gurdiga\n//! author : Valentin Agachi : https://github.com/avaly\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\n\nfunction relativeTimeWithPlural(number, withoutSuffix, key) {\n    var format = {\n            'mm': 'minute',\n            'hh': 'ore',\n            'dd': 'zile',\n            'MM': 'luni',\n            'yy': 'ani'\n        },\n        separator = ' ';\n    if (number % 100 >= 20 || (number >= 100 && number % 100 === 0)) {\n        separator = ' de ';\n    }\n    return number + separator + format[key];\n}\n\nvar ro = moment.defineLocale('ro', {\n    months : 'ianuarie_februarie_martie_aprilie_mai_iunie_iulie_august_septembrie_octombrie_noiembrie_decembrie'.split('_'),\n    monthsShort : 'ian._febr._mart._apr._mai_iun._iul._aug._sept._oct._nov._dec.'.split('_'),\n    monthsParseExact: true,\n    weekdays : 'duminică_luni_marți_miercuri_joi_vineri_sâmbătă'.split('_'),\n    weekdaysShort : 'Dum_Lun_Mar_Mie_Joi_Vin_Sâm'.split('_'),\n    weekdaysMin : 'Du_Lu_Ma_Mi_Jo_Vi_Sâ'.split('_'),\n    longDateFormat : {\n        LT : 'H:mm',\n        LTS : 'H:mm:ss',\n        L : 'DD.MM.YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY H:mm',\n        LLLL : 'dddd, D MMMM YYYY H:mm'\n    },\n    calendar : {\n        sameDay: '[azi la] LT',\n        nextDay: '[mâine la] LT',\n        nextWeek: 'dddd [la] LT',\n        lastDay: '[ieri la] LT',\n        lastWeek: '[fosta] dddd [la] LT',\n        sameElse: 'L'\n    },\n    relativeTime : {\n        future : 'peste %s',\n        past : '%s în urmă',\n        s : 'câteva secunde',\n        m : 'un minut',\n        mm : relativeTimeWithPlural,\n        h : 'o oră',\n        hh : relativeTimeWithPlural,\n        d : 'o zi',\n        dd : relativeTimeWithPlural,\n        M : 'o lună',\n        MM : relativeTimeWithPlural,\n        y : 'un an',\n        yy : relativeTimeWithPlural\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 7  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\nreturn ro;\n\n})));\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/locale/ru.js",
    "content": "//! moment.js locale configuration\n//! locale : Russian [ru]\n//! author : Viktorminator : https://github.com/Viktorminator\n//! Author : Menelion Elensúle : https://github.com/Oire\n//! author : Коренберг Марк : https://github.com/socketpair\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\n\nfunction plural(word, num) {\n    var forms = word.split('_');\n    return num % 10 === 1 && num % 100 !== 11 ? forms[0] : (num % 10 >= 2 && num % 10 <= 4 && (num % 100 < 10 || num % 100 >= 20) ? forms[1] : forms[2]);\n}\nfunction relativeTimeWithPlural(number, withoutSuffix, key) {\n    var format = {\n        'mm': withoutSuffix ? 'минута_минуты_минут' : 'минуту_минуты_минут',\n        'hh': 'час_часа_часов',\n        'dd': 'день_дня_дней',\n        'MM': 'месяц_месяца_месяцев',\n        'yy': 'год_года_лет'\n    };\n    if (key === 'm') {\n        return withoutSuffix ? 'минута' : 'минуту';\n    }\n    else {\n        return number + ' ' + plural(format[key], +number);\n    }\n}\nvar monthsParse = [/^янв/i, /^фев/i, /^мар/i, /^апр/i, /^ма[йя]/i, /^июн/i, /^июл/i, /^авг/i, /^сен/i, /^окт/i, /^ноя/i, /^дек/i];\n\n// http://new.gramota.ru/spravka/rules/139-prop : § 103\n// Сокращения месяцев: http://new.gramota.ru/spravka/buro/search-answer?s=242637\n// CLDR data:          http://www.unicode.org/cldr/charts/28/summary/ru.html#1753\nvar ru = moment.defineLocale('ru', {\n    months : {\n        format: 'января_февраля_марта_апреля_мая_июня_июля_августа_сентября_октября_ноября_декабря'.split('_'),\n        standalone: 'январь_февраль_март_апрель_май_июнь_июль_август_сентябрь_октябрь_ноябрь_декабрь'.split('_')\n    },\n    monthsShort : {\n        // по CLDR именно \"июл.\" и \"июн.\", но какой смысл менять букву на точку ?\n        format: 'янв._февр._мар._апр._мая_июня_июля_авг._сент._окт._нояб._дек.'.split('_'),\n        standalone: 'янв._февр._март_апр._май_июнь_июль_авг._сент._окт._нояб._дек.'.split('_')\n    },\n    weekdays : {\n        standalone: 'воскресенье_понедельник_вторник_среда_четверг_пятница_суббота'.split('_'),\n        format: 'воскресенье_понедельник_вторник_среду_четверг_пятницу_субботу'.split('_'),\n        isFormat: /\\[ ?[Вв] ?(?:прошлую|следующую|эту)? ?\\] ?dddd/\n    },\n    weekdaysShort : 'вс_пн_вт_ср_чт_пт_сб'.split('_'),\n    weekdaysMin : 'вс_пн_вт_ср_чт_пт_сб'.split('_'),\n    monthsParse : monthsParse,\n    longMonthsParse : monthsParse,\n    shortMonthsParse : monthsParse,\n\n    // полные названия с падежами, по три буквы, для некоторых, по 4 буквы, сокращения с точкой и без точки\n    monthsRegex: /^(январ[ья]|янв\\.?|феврал[ья]|февр?\\.?|марта?|мар\\.?|апрел[ья]|апр\\.?|ма[йя]|июн[ья]|июн\\.?|июл[ья]|июл\\.?|августа?|авг\\.?|сентябр[ья]|сент?\\.?|октябр[ья]|окт\\.?|ноябр[ья]|нояб?\\.?|декабр[ья]|дек\\.?)/i,\n\n    // копия предыдущего\n    monthsShortRegex: /^(январ[ья]|янв\\.?|феврал[ья]|февр?\\.?|марта?|мар\\.?|апрел[ья]|апр\\.?|ма[йя]|июн[ья]|июн\\.?|июл[ья]|июл\\.?|августа?|авг\\.?|сентябр[ья]|сент?\\.?|октябр[ья]|окт\\.?|ноябр[ья]|нояб?\\.?|декабр[ья]|дек\\.?)/i,\n\n    // полные названия с падежами\n    monthsStrictRegex: /^(январ[яь]|феврал[яь]|марта?|апрел[яь]|ма[яй]|июн[яь]|июл[яь]|августа?|сентябр[яь]|октябр[яь]|ноябр[яь]|декабр[яь])/i,\n\n    // Выражение, которое соотвествует только сокращённым формам\n    monthsShortStrictRegex: /^(янв\\.|февр?\\.|мар[т.]|апр\\.|ма[яй]|июн[ья.]|июл[ья.]|авг\\.|сент?\\.|окт\\.|нояб?\\.|дек\\.)/i,\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD.MM.YYYY',\n        LL : 'D MMMM YYYY г.',\n        LLL : 'D MMMM YYYY г., HH:mm',\n        LLLL : 'dddd, D MMMM YYYY г., HH:mm'\n    },\n    calendar : {\n        sameDay: '[Сегодня в] LT',\n        nextDay: '[Завтра в] LT',\n        lastDay: '[Вчера в] LT',\n        nextWeek: function (now) {\n            if (now.week() !== this.week()) {\n                switch (this.day()) {\n                    case 0:\n                        return '[В следующее] dddd [в] LT';\n                    case 1:\n                    case 2:\n                    case 4:\n                        return '[В следующий] dddd [в] LT';\n                    case 3:\n                    case 5:\n                    case 6:\n                        return '[В следующую] dddd [в] LT';\n                }\n            } else {\n                if (this.day() === 2) {\n                    return '[Во] dddd [в] LT';\n                } else {\n                    return '[В] dddd [в] LT';\n                }\n            }\n        },\n        lastWeek: function (now) {\n            if (now.week() !== this.week()) {\n                switch (this.day()) {\n                    case 0:\n                        return '[В прошлое] dddd [в] LT';\n                    case 1:\n                    case 2:\n                    case 4:\n                        return '[В прошлый] dddd [в] LT';\n                    case 3:\n                    case 5:\n                    case 6:\n                        return '[В прошлую] dddd [в] LT';\n                }\n            } else {\n                if (this.day() === 2) {\n                    return '[Во] dddd [в] LT';\n                } else {\n                    return '[В] dddd [в] LT';\n                }\n            }\n        },\n        sameElse: 'L'\n    },\n    relativeTime : {\n        future : 'через %s',\n        past : '%s назад',\n        s : 'несколько секунд',\n        m : relativeTimeWithPlural,\n        mm : relativeTimeWithPlural,\n        h : 'час',\n        hh : relativeTimeWithPlural,\n        d : 'день',\n        dd : relativeTimeWithPlural,\n        M : 'месяц',\n        MM : relativeTimeWithPlural,\n        y : 'год',\n        yy : relativeTimeWithPlural\n    },\n    meridiemParse: /ночи|утра|дня|вечера/i,\n    isPM : function (input) {\n        return /^(дня|вечера)$/.test(input);\n    },\n    meridiem : function (hour, minute, isLower) {\n        if (hour < 4) {\n            return 'ночи';\n        } else if (hour < 12) {\n            return 'утра';\n        } else if (hour < 17) {\n            return 'дня';\n        } else {\n            return 'вечера';\n        }\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}-(й|го|я)/,\n    ordinal: function (number, period) {\n        switch (period) {\n            case 'M':\n            case 'd':\n            case 'DDD':\n                return number + '-й';\n            case 'D':\n                return number + '-го';\n            case 'w':\n            case 'W':\n                return number + '-я';\n            default:\n                return number;\n        }\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 7  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\nreturn ru;\n\n})));\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/locale/sd.js",
    "content": "//! moment.js locale configuration\n//! locale : Sindhi [sd]\n//! author : Narain Sagar : https://github.com/narainsagar\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\n\nvar months = [\n    'جنوري',\n    'فيبروري',\n    'مارچ',\n    'اپريل',\n    'مئي',\n    'جون',\n    'جولاءِ',\n    'آگسٽ',\n    'سيپٽمبر',\n    'آڪٽوبر',\n    'نومبر',\n    'ڊسمبر'\n];\nvar days = [\n    'آچر',\n    'سومر',\n    'اڱارو',\n    'اربع',\n    'خميس',\n    'جمع',\n    'ڇنڇر'\n];\n\nvar sd = moment.defineLocale('sd', {\n    months : months,\n    monthsShort : months,\n    weekdays : days,\n    weekdaysShort : days,\n    weekdaysMin : days,\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY HH:mm',\n        LLLL : 'dddd، D MMMM YYYY HH:mm'\n    },\n    meridiemParse: /صبح|شام/,\n    isPM : function (input) {\n        return 'شام' === input;\n    },\n    meridiem : function (hour, minute, isLower) {\n        if (hour < 12) {\n            return 'صبح';\n        }\n        return 'شام';\n    },\n    calendar : {\n        sameDay : '[اڄ] LT',\n        nextDay : '[سڀاڻي] LT',\n        nextWeek : 'dddd [اڳين هفتي تي] LT',\n        lastDay : '[ڪالهه] LT',\n        lastWeek : '[گزريل هفتي] dddd [تي] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : '%s پوء',\n        past : '%s اڳ',\n        s : 'چند سيڪنڊ',\n        m : 'هڪ منٽ',\n        mm : '%d منٽ',\n        h : 'هڪ ڪلاڪ',\n        hh : '%d ڪلاڪ',\n        d : 'هڪ ڏينهن',\n        dd : '%d ڏينهن',\n        M : 'هڪ مهينو',\n        MM : '%d مهينا',\n        y : 'هڪ سال',\n        yy : '%d سال'\n    },\n    preparse: function (string) {\n        return string.replace(/،/g, ',');\n    },\n    postformat: function (string) {\n        return string.replace(/,/g, '،');\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\nreturn sd;\n\n})));\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/locale/se.js",
    "content": "//! moment.js locale configuration\n//! locale : Northern Sami [se]\n//! authors : Bård Rolstad Henriksen : https://github.com/karamell\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\n\n\nvar se = moment.defineLocale('se', {\n    months : 'ođđajagemánnu_guovvamánnu_njukčamánnu_cuoŋománnu_miessemánnu_geassemánnu_suoidnemánnu_borgemánnu_čakčamánnu_golggotmánnu_skábmamánnu_juovlamánnu'.split('_'),\n    monthsShort : 'ođđj_guov_njuk_cuo_mies_geas_suoi_borg_čakč_golg_skáb_juov'.split('_'),\n    weekdays : 'sotnabeaivi_vuossárga_maŋŋebárga_gaskavahkku_duorastat_bearjadat_lávvardat'.split('_'),\n    weekdaysShort : 'sotn_vuos_maŋ_gask_duor_bear_láv'.split('_'),\n    weekdaysMin : 's_v_m_g_d_b_L'.split('_'),\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD.MM.YYYY',\n        LL : 'MMMM D. [b.] YYYY',\n        LLL : 'MMMM D. [b.] YYYY [ti.] HH:mm',\n        LLLL : 'dddd, MMMM D. [b.] YYYY [ti.] HH:mm'\n    },\n    calendar : {\n        sameDay: '[otne ti] LT',\n        nextDay: '[ihttin ti] LT',\n        nextWeek: 'dddd [ti] LT',\n        lastDay: '[ikte ti] LT',\n        lastWeek: '[ovddit] dddd [ti] LT',\n        sameElse: 'L'\n    },\n    relativeTime : {\n        future : '%s geažes',\n        past : 'maŋit %s',\n        s : 'moadde sekunddat',\n        m : 'okta minuhta',\n        mm : '%d minuhtat',\n        h : 'okta diimmu',\n        hh : '%d diimmut',\n        d : 'okta beaivi',\n        dd : '%d beaivvit',\n        M : 'okta mánnu',\n        MM : '%d mánut',\n        y : 'okta jahki',\n        yy : '%d jagit'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}\\./,\n    ordinal : '%d.',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\nreturn se;\n\n})));\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/locale/si.js",
    "content": "//! moment.js locale configuration\n//! locale : Sinhalese [si]\n//! author : Sampath Sitinamaluwa : https://github.com/sampathsris\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\n\n/*jshint -W100*/\nvar si = moment.defineLocale('si', {\n    months : 'ජනවාරි_පෙබරවාරි_මාර්තු_අප්‍රේල්_මැයි_ජූනි_ජූලි_අගෝස්තු_සැප්තැම්බර්_ඔක්තෝබර්_නොවැම්බර්_දෙසැම්බර්'.split('_'),\n    monthsShort : 'ජන_පෙබ_මාර්_අප්_මැයි_ජූනි_ජූලි_අගෝ_සැප්_ඔක්_නොවැ_දෙසැ'.split('_'),\n    weekdays : 'ඉරිදා_සඳුදා_අඟහරුවාදා_බදාදා_බ්‍රහස්පතින්දා_සිකුරාදා_සෙනසුරාදා'.split('_'),\n    weekdaysShort : 'ඉරි_සඳු_අඟ_බදා_බ්‍රහ_සිකු_සෙන'.split('_'),\n    weekdaysMin : 'ඉ_ස_අ_බ_බ්‍ර_සි_සෙ'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat : {\n        LT : 'a h:mm',\n        LTS : 'a h:mm:ss',\n        L : 'YYYY/MM/DD',\n        LL : 'YYYY MMMM D',\n        LLL : 'YYYY MMMM D, a h:mm',\n        LLLL : 'YYYY MMMM D [වැනි] dddd, a h:mm:ss'\n    },\n    calendar : {\n        sameDay : '[අද] LT[ට]',\n        nextDay : '[හෙට] LT[ට]',\n        nextWeek : 'dddd LT[ට]',\n        lastDay : '[ඊයේ] LT[ට]',\n        lastWeek : '[පසුගිය] dddd LT[ට]',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : '%sකින්',\n        past : '%sකට පෙර',\n        s : 'තත්පර කිහිපය',\n        m : 'මිනිත්තුව',\n        mm : 'මිනිත්තු %d',\n        h : 'පැය',\n        hh : 'පැය %d',\n        d : 'දිනය',\n        dd : 'දින %d',\n        M : 'මාසය',\n        MM : 'මාස %d',\n        y : 'වසර',\n        yy : 'වසර %d'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2} වැනි/,\n    ordinal : function (number) {\n        return number + ' වැනි';\n    },\n    meridiemParse : /පෙර වරු|පස් වරු|පෙ.ව|ප.ව./,\n    isPM : function (input) {\n        return input === 'ප.ව.' || input === 'පස් වරු';\n    },\n    meridiem : function (hours, minutes, isLower) {\n        if (hours > 11) {\n            return isLower ? 'ප.ව.' : 'පස් වරු';\n        } else {\n            return isLower ? 'පෙ.ව.' : 'පෙර වරු';\n        }\n    }\n});\n\nreturn si;\n\n})));\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/locale/sk.js",
    "content": "//! moment.js locale configuration\n//! locale : Slovak [sk]\n//! author : Martin Minka : https://github.com/k2s\n//! based on work of petrbela : https://github.com/petrbela\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\n\nvar months = 'január_február_marec_apríl_máj_jún_júl_august_september_október_november_december'.split('_');\nvar monthsShort = 'jan_feb_mar_apr_máj_jún_júl_aug_sep_okt_nov_dec'.split('_');\nfunction plural(n) {\n    return (n > 1) && (n < 5);\n}\nfunction translate(number, withoutSuffix, key, isFuture) {\n    var result = number + ' ';\n    switch (key) {\n        case 's':  // a few seconds / in a few seconds / a few seconds ago\n            return (withoutSuffix || isFuture) ? 'pár sekúnd' : 'pár sekundami';\n        case 'm':  // a minute / in a minute / a minute ago\n            return withoutSuffix ? 'minúta' : (isFuture ? 'minútu' : 'minútou');\n        case 'mm': // 9 minutes / in 9 minutes / 9 minutes ago\n            if (withoutSuffix || isFuture) {\n                return result + (plural(number) ? 'minúty' : 'minút');\n            } else {\n                return result + 'minútami';\n            }\n            break;\n        case 'h':  // an hour / in an hour / an hour ago\n            return withoutSuffix ? 'hodina' : (isFuture ? 'hodinu' : 'hodinou');\n        case 'hh': // 9 hours / in 9 hours / 9 hours ago\n            if (withoutSuffix || isFuture) {\n                return result + (plural(number) ? 'hodiny' : 'hodín');\n            } else {\n                return result + 'hodinami';\n            }\n            break;\n        case 'd':  // a day / in a day / a day ago\n            return (withoutSuffix || isFuture) ? 'deň' : 'dňom';\n        case 'dd': // 9 days / in 9 days / 9 days ago\n            if (withoutSuffix || isFuture) {\n                return result + (plural(number) ? 'dni' : 'dní');\n            } else {\n                return result + 'dňami';\n            }\n            break;\n        case 'M':  // a month / in a month / a month ago\n            return (withoutSuffix || isFuture) ? 'mesiac' : 'mesiacom';\n        case 'MM': // 9 months / in 9 months / 9 months ago\n            if (withoutSuffix || isFuture) {\n                return result + (plural(number) ? 'mesiace' : 'mesiacov');\n            } else {\n                return result + 'mesiacmi';\n            }\n            break;\n        case 'y':  // a year / in a year / a year ago\n            return (withoutSuffix || isFuture) ? 'rok' : 'rokom';\n        case 'yy': // 9 years / in 9 years / 9 years ago\n            if (withoutSuffix || isFuture) {\n                return result + (plural(number) ? 'roky' : 'rokov');\n            } else {\n                return result + 'rokmi';\n            }\n            break;\n    }\n}\n\nvar sk = moment.defineLocale('sk', {\n    months : months,\n    monthsShort : monthsShort,\n    weekdays : 'nedeľa_pondelok_utorok_streda_štvrtok_piatok_sobota'.split('_'),\n    weekdaysShort : 'ne_po_ut_st_št_pi_so'.split('_'),\n    weekdaysMin : 'ne_po_ut_st_št_pi_so'.split('_'),\n    longDateFormat : {\n        LT: 'H:mm',\n        LTS : 'H:mm:ss',\n        L : 'DD.MM.YYYY',\n        LL : 'D. MMMM YYYY',\n        LLL : 'D. MMMM YYYY H:mm',\n        LLLL : 'dddd D. MMMM YYYY H:mm'\n    },\n    calendar : {\n        sameDay: '[dnes o] LT',\n        nextDay: '[zajtra o] LT',\n        nextWeek: function () {\n            switch (this.day()) {\n                case 0:\n                    return '[v nedeľu o] LT';\n                case 1:\n                case 2:\n                    return '[v] dddd [o] LT';\n                case 3:\n                    return '[v stredu o] LT';\n                case 4:\n                    return '[vo štvrtok o] LT';\n                case 5:\n                    return '[v piatok o] LT';\n                case 6:\n                    return '[v sobotu o] LT';\n            }\n        },\n        lastDay: '[včera o] LT',\n        lastWeek: function () {\n            switch (this.day()) {\n                case 0:\n                    return '[minulú nedeľu o] LT';\n                case 1:\n                case 2:\n                    return '[minulý] dddd [o] LT';\n                case 3:\n                    return '[minulú stredu o] LT';\n                case 4:\n                case 5:\n                    return '[minulý] dddd [o] LT';\n                case 6:\n                    return '[minulú sobotu o] LT';\n            }\n        },\n        sameElse: 'L'\n    },\n    relativeTime : {\n        future : 'za %s',\n        past : 'pred %s',\n        s : translate,\n        m : translate,\n        mm : translate,\n        h : translate,\n        hh : translate,\n        d : translate,\n        dd : translate,\n        M : translate,\n        MM : translate,\n        y : translate,\n        yy : translate\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}\\./,\n    ordinal : '%d.',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\nreturn sk;\n\n})));\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/locale/sl.js",
    "content": "//! moment.js locale configuration\n//! locale : Slovenian [sl]\n//! author : Robert Sedovšek : https://github.com/sedovsek\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\n\nfunction processRelativeTime(number, withoutSuffix, key, isFuture) {\n    var result = number + ' ';\n    switch (key) {\n        case 's':\n            return withoutSuffix || isFuture ? 'nekaj sekund' : 'nekaj sekundami';\n        case 'm':\n            return withoutSuffix ? 'ena minuta' : 'eno minuto';\n        case 'mm':\n            if (number === 1) {\n                result += withoutSuffix ? 'minuta' : 'minuto';\n            } else if (number === 2) {\n                result += withoutSuffix || isFuture ? 'minuti' : 'minutama';\n            } else if (number < 5) {\n                result += withoutSuffix || isFuture ? 'minute' : 'minutami';\n            } else {\n                result += withoutSuffix || isFuture ? 'minut' : 'minutami';\n            }\n            return result;\n        case 'h':\n            return withoutSuffix ? 'ena ura' : 'eno uro';\n        case 'hh':\n            if (number === 1) {\n                result += withoutSuffix ? 'ura' : 'uro';\n            } else if (number === 2) {\n                result += withoutSuffix || isFuture ? 'uri' : 'urama';\n            } else if (number < 5) {\n                result += withoutSuffix || isFuture ? 'ure' : 'urami';\n            } else {\n                result += withoutSuffix || isFuture ? 'ur' : 'urami';\n            }\n            return result;\n        case 'd':\n            return withoutSuffix || isFuture ? 'en dan' : 'enim dnem';\n        case 'dd':\n            if (number === 1) {\n                result += withoutSuffix || isFuture ? 'dan' : 'dnem';\n            } else if (number === 2) {\n                result += withoutSuffix || isFuture ? 'dni' : 'dnevoma';\n            } else {\n                result += withoutSuffix || isFuture ? 'dni' : 'dnevi';\n            }\n            return result;\n        case 'M':\n            return withoutSuffix || isFuture ? 'en mesec' : 'enim mesecem';\n        case 'MM':\n            if (number === 1) {\n                result += withoutSuffix || isFuture ? 'mesec' : 'mesecem';\n            } else if (number === 2) {\n                result += withoutSuffix || isFuture ? 'meseca' : 'mesecema';\n            } else if (number < 5) {\n                result += withoutSuffix || isFuture ? 'mesece' : 'meseci';\n            } else {\n                result += withoutSuffix || isFuture ? 'mesecev' : 'meseci';\n            }\n            return result;\n        case 'y':\n            return withoutSuffix || isFuture ? 'eno leto' : 'enim letom';\n        case 'yy':\n            if (number === 1) {\n                result += withoutSuffix || isFuture ? 'leto' : 'letom';\n            } else if (number === 2) {\n                result += withoutSuffix || isFuture ? 'leti' : 'letoma';\n            } else if (number < 5) {\n                result += withoutSuffix || isFuture ? 'leta' : 'leti';\n            } else {\n                result += withoutSuffix || isFuture ? 'let' : 'leti';\n            }\n            return result;\n    }\n}\n\nvar sl = moment.defineLocale('sl', {\n    months : 'januar_februar_marec_april_maj_junij_julij_avgust_september_oktober_november_december'.split('_'),\n    monthsShort : 'jan._feb._mar._apr._maj._jun._jul._avg._sep._okt._nov._dec.'.split('_'),\n    monthsParseExact: true,\n    weekdays : 'nedelja_ponedeljek_torek_sreda_četrtek_petek_sobota'.split('_'),\n    weekdaysShort : 'ned._pon._tor._sre._čet._pet._sob.'.split('_'),\n    weekdaysMin : 'ne_po_to_sr_če_pe_so'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat : {\n        LT : 'H:mm',\n        LTS : 'H:mm:ss',\n        L : 'DD.MM.YYYY',\n        LL : 'D. MMMM YYYY',\n        LLL : 'D. MMMM YYYY H:mm',\n        LLLL : 'dddd, D. MMMM YYYY H:mm'\n    },\n    calendar : {\n        sameDay  : '[danes ob] LT',\n        nextDay  : '[jutri ob] LT',\n\n        nextWeek : function () {\n            switch (this.day()) {\n                case 0:\n                    return '[v] [nedeljo] [ob] LT';\n                case 3:\n                    return '[v] [sredo] [ob] LT';\n                case 6:\n                    return '[v] [soboto] [ob] LT';\n                case 1:\n                case 2:\n                case 4:\n                case 5:\n                    return '[v] dddd [ob] LT';\n            }\n        },\n        lastDay  : '[včeraj ob] LT',\n        lastWeek : function () {\n            switch (this.day()) {\n                case 0:\n                    return '[prejšnjo] [nedeljo] [ob] LT';\n                case 3:\n                    return '[prejšnjo] [sredo] [ob] LT';\n                case 6:\n                    return '[prejšnjo] [soboto] [ob] LT';\n                case 1:\n                case 2:\n                case 4:\n                case 5:\n                    return '[prejšnji] dddd [ob] LT';\n            }\n        },\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'čez %s',\n        past   : 'pred %s',\n        s      : processRelativeTime,\n        m      : processRelativeTime,\n        mm     : processRelativeTime,\n        h      : processRelativeTime,\n        hh     : processRelativeTime,\n        d      : processRelativeTime,\n        dd     : processRelativeTime,\n        M      : processRelativeTime,\n        MM     : processRelativeTime,\n        y      : processRelativeTime,\n        yy     : processRelativeTime\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}\\./,\n    ordinal : '%d.',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 7  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\nreturn sl;\n\n})));\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/locale/sq.js",
    "content": "//! moment.js locale configuration\n//! locale : Albanian [sq]\n//! author : Flakërim Ismani : https://github.com/flakerimi\n//! author : Menelion Elensúle : https://github.com/Oire\n//! author : Oerd Cukalla : https://github.com/oerd\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\n\nvar sq = moment.defineLocale('sq', {\n    months : 'Janar_Shkurt_Mars_Prill_Maj_Qershor_Korrik_Gusht_Shtator_Tetor_Nëntor_Dhjetor'.split('_'),\n    monthsShort : 'Jan_Shk_Mar_Pri_Maj_Qer_Kor_Gus_Sht_Tet_Nën_Dhj'.split('_'),\n    weekdays : 'E Diel_E Hënë_E Martë_E Mërkurë_E Enjte_E Premte_E Shtunë'.split('_'),\n    weekdaysShort : 'Die_Hën_Mar_Mër_Enj_Pre_Sht'.split('_'),\n    weekdaysMin : 'D_H_Ma_Më_E_P_Sh'.split('_'),\n    weekdaysParseExact : true,\n    meridiemParse: /PD|MD/,\n    isPM: function (input) {\n        return input.charAt(0) === 'M';\n    },\n    meridiem : function (hours, minutes, isLower) {\n        return hours < 12 ? 'PD' : 'MD';\n    },\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY HH:mm',\n        LLLL : 'dddd, D MMMM YYYY HH:mm'\n    },\n    calendar : {\n        sameDay : '[Sot në] LT',\n        nextDay : '[Nesër në] LT',\n        nextWeek : 'dddd [në] LT',\n        lastDay : '[Dje në] LT',\n        lastWeek : 'dddd [e kaluar në] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'në %s',\n        past : '%s më parë',\n        s : 'disa sekonda',\n        m : 'një minutë',\n        mm : '%d minuta',\n        h : 'një orë',\n        hh : '%d orë',\n        d : 'një ditë',\n        dd : '%d ditë',\n        M : 'një muaj',\n        MM : '%d muaj',\n        y : 'një vit',\n        yy : '%d vite'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}\\./,\n    ordinal : '%d.',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\nreturn sq;\n\n})));\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/locale/sr-cyrl.js",
    "content": "//! moment.js locale configuration\n//! locale : Serbian Cyrillic [sr-cyrl]\n//! author : Milan Janačković<milanjanackovic@gmail.com> : https://github.com/milan-j\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\n\nvar translator = {\n    words: { //Different grammatical cases\n        m: ['један минут', 'једне минуте'],\n        mm: ['минут', 'минуте', 'минута'],\n        h: ['један сат', 'једног сата'],\n        hh: ['сат', 'сата', 'сати'],\n        dd: ['дан', 'дана', 'дана'],\n        MM: ['месец', 'месеца', 'месеци'],\n        yy: ['година', 'године', 'година']\n    },\n    correctGrammaticalCase: function (number, wordKey) {\n        return number === 1 ? wordKey[0] : (number >= 2 && number <= 4 ? wordKey[1] : wordKey[2]);\n    },\n    translate: function (number, withoutSuffix, key) {\n        var wordKey = translator.words[key];\n        if (key.length === 1) {\n            return withoutSuffix ? wordKey[0] : wordKey[1];\n        } else {\n            return number + ' ' + translator.correctGrammaticalCase(number, wordKey);\n        }\n    }\n};\n\nvar srCyrl = moment.defineLocale('sr-cyrl', {\n    months: 'јануар_фебруар_март_април_мај_јун_јул_август_септембар_октобар_новембар_децембар'.split('_'),\n    monthsShort: 'јан._феб._мар._апр._мај_јун_јул_авг._сеп._окт._нов._дец.'.split('_'),\n    monthsParseExact: true,\n    weekdays: 'недеља_понедељак_уторак_среда_четвртак_петак_субота'.split('_'),\n    weekdaysShort: 'нед._пон._уто._сре._чет._пет._суб.'.split('_'),\n    weekdaysMin: 'не_по_ут_ср_че_пе_су'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat: {\n        LT: 'H:mm',\n        LTS : 'H:mm:ss',\n        L: 'DD.MM.YYYY',\n        LL: 'D. MMMM YYYY',\n        LLL: 'D. MMMM YYYY H:mm',\n        LLLL: 'dddd, D. MMMM YYYY H:mm'\n    },\n    calendar: {\n        sameDay: '[данас у] LT',\n        nextDay: '[сутра у] LT',\n        nextWeek: function () {\n            switch (this.day()) {\n                case 0:\n                    return '[у] [недељу] [у] LT';\n                case 3:\n                    return '[у] [среду] [у] LT';\n                case 6:\n                    return '[у] [суботу] [у] LT';\n                case 1:\n                case 2:\n                case 4:\n                case 5:\n                    return '[у] dddd [у] LT';\n            }\n        },\n        lastDay  : '[јуче у] LT',\n        lastWeek : function () {\n            var lastWeekDays = [\n                '[прошле] [недеље] [у] LT',\n                '[прошлог] [понедељка] [у] LT',\n                '[прошлог] [уторка] [у] LT',\n                '[прошле] [среде] [у] LT',\n                '[прошлог] [четвртка] [у] LT',\n                '[прошлог] [петка] [у] LT',\n                '[прошле] [суботе] [у] LT'\n            ];\n            return lastWeekDays[this.day()];\n        },\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'за %s',\n        past   : 'пре %s',\n        s      : 'неколико секунди',\n        m      : translator.translate,\n        mm     : translator.translate,\n        h      : translator.translate,\n        hh     : translator.translate,\n        d      : 'дан',\n        dd     : translator.translate,\n        M      : 'месец',\n        MM     : translator.translate,\n        y      : 'годину',\n        yy     : translator.translate\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}\\./,\n    ordinal : '%d.',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 7  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\nreturn srCyrl;\n\n})));\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/locale/sr.js",
    "content": "//! moment.js locale configuration\n//! locale : Serbian [sr]\n//! author : Milan Janačković<milanjanackovic@gmail.com> : https://github.com/milan-j\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\n\nvar translator = {\n    words: { //Different grammatical cases\n        m: ['jedan minut', 'jedne minute'],\n        mm: ['minut', 'minute', 'minuta'],\n        h: ['jedan sat', 'jednog sata'],\n        hh: ['sat', 'sata', 'sati'],\n        dd: ['dan', 'dana', 'dana'],\n        MM: ['mesec', 'meseca', 'meseci'],\n        yy: ['godina', 'godine', 'godina']\n    },\n    correctGrammaticalCase: function (number, wordKey) {\n        return number === 1 ? wordKey[0] : (number >= 2 && number <= 4 ? wordKey[1] : wordKey[2]);\n    },\n    translate: function (number, withoutSuffix, key) {\n        var wordKey = translator.words[key];\n        if (key.length === 1) {\n            return withoutSuffix ? wordKey[0] : wordKey[1];\n        } else {\n            return number + ' ' + translator.correctGrammaticalCase(number, wordKey);\n        }\n    }\n};\n\nvar sr = moment.defineLocale('sr', {\n    months: 'januar_februar_mart_april_maj_jun_jul_avgust_septembar_oktobar_novembar_decembar'.split('_'),\n    monthsShort: 'jan._feb._mar._apr._maj_jun_jul_avg._sep._okt._nov._dec.'.split('_'),\n    monthsParseExact: true,\n    weekdays: 'nedelja_ponedeljak_utorak_sreda_četvrtak_petak_subota'.split('_'),\n    weekdaysShort: 'ned._pon._uto._sre._čet._pet._sub.'.split('_'),\n    weekdaysMin: 'ne_po_ut_sr_če_pe_su'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat: {\n        LT: 'H:mm',\n        LTS : 'H:mm:ss',\n        L: 'DD.MM.YYYY',\n        LL: 'D. MMMM YYYY',\n        LLL: 'D. MMMM YYYY H:mm',\n        LLLL: 'dddd, D. MMMM YYYY H:mm'\n    },\n    calendar: {\n        sameDay: '[danas u] LT',\n        nextDay: '[sutra u] LT',\n        nextWeek: function () {\n            switch (this.day()) {\n                case 0:\n                    return '[u] [nedelju] [u] LT';\n                case 3:\n                    return '[u] [sredu] [u] LT';\n                case 6:\n                    return '[u] [subotu] [u] LT';\n                case 1:\n                case 2:\n                case 4:\n                case 5:\n                    return '[u] dddd [u] LT';\n            }\n        },\n        lastDay  : '[juče u] LT',\n        lastWeek : function () {\n            var lastWeekDays = [\n                '[prošle] [nedelje] [u] LT',\n                '[prošlog] [ponedeljka] [u] LT',\n                '[prošlog] [utorka] [u] LT',\n                '[prošle] [srede] [u] LT',\n                '[prošlog] [četvrtka] [u] LT',\n                '[prošlog] [petka] [u] LT',\n                '[prošle] [subote] [u] LT'\n            ];\n            return lastWeekDays[this.day()];\n        },\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'za %s',\n        past   : 'pre %s',\n        s      : 'nekoliko sekundi',\n        m      : translator.translate,\n        mm     : translator.translate,\n        h      : translator.translate,\n        hh     : translator.translate,\n        d      : 'dan',\n        dd     : translator.translate,\n        M      : 'mesec',\n        MM     : translator.translate,\n        y      : 'godinu',\n        yy     : translator.translate\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}\\./,\n    ordinal : '%d.',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 7  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\nreturn sr;\n\n})));\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/locale/ss.js",
    "content": "//! moment.js locale configuration\n//! locale : siSwati [ss]\n//! author : Nicolai Davies<mail@nicolai.io> : https://github.com/nicolaidavies\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\n\n\nvar ss = moment.defineLocale('ss', {\n    months : \"Bhimbidvwane_Indlovana_Indlov'lenkhulu_Mabasa_Inkhwekhweti_Inhlaba_Kholwane_Ingci_Inyoni_Imphala_Lweti_Ingongoni\".split('_'),\n    monthsShort : 'Bhi_Ina_Inu_Mab_Ink_Inh_Kho_Igc_Iny_Imp_Lwe_Igo'.split('_'),\n    weekdays : 'Lisontfo_Umsombuluko_Lesibili_Lesitsatfu_Lesine_Lesihlanu_Umgcibelo'.split('_'),\n    weekdaysShort : 'Lis_Umb_Lsb_Les_Lsi_Lsh_Umg'.split('_'),\n    weekdaysMin : 'Li_Us_Lb_Lt_Ls_Lh_Ug'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat : {\n        LT : 'h:mm A',\n        LTS : 'h:mm:ss A',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY h:mm A',\n        LLLL : 'dddd, D MMMM YYYY h:mm A'\n    },\n    calendar : {\n        sameDay : '[Namuhla nga] LT',\n        nextDay : '[Kusasa nga] LT',\n        nextWeek : 'dddd [nga] LT',\n        lastDay : '[Itolo nga] LT',\n        lastWeek : 'dddd [leliphelile] [nga] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'nga %s',\n        past : 'wenteka nga %s',\n        s : 'emizuzwana lomcane',\n        m : 'umzuzu',\n        mm : '%d emizuzu',\n        h : 'lihora',\n        hh : '%d emahora',\n        d : 'lilanga',\n        dd : '%d emalanga',\n        M : 'inyanga',\n        MM : '%d tinyanga',\n        y : 'umnyaka',\n        yy : '%d iminyaka'\n    },\n    meridiemParse: /ekuseni|emini|entsambama|ebusuku/,\n    meridiem : function (hours, minutes, isLower) {\n        if (hours < 11) {\n            return 'ekuseni';\n        } else if (hours < 15) {\n            return 'emini';\n        } else if (hours < 19) {\n            return 'entsambama';\n        } else {\n            return 'ebusuku';\n        }\n    },\n    meridiemHour : function (hour, meridiem) {\n        if (hour === 12) {\n            hour = 0;\n        }\n        if (meridiem === 'ekuseni') {\n            return hour;\n        } else if (meridiem === 'emini') {\n            return hour >= 11 ? hour : hour + 12;\n        } else if (meridiem === 'entsambama' || meridiem === 'ebusuku') {\n            if (hour === 0) {\n                return 0;\n            }\n            return hour + 12;\n        }\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}/,\n    ordinal : '%d',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\nreturn ss;\n\n})));\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/locale/sv.js",
    "content": "//! moment.js locale configuration\n//! locale : Swedish [sv]\n//! author : Jens Alm : https://github.com/ulmus\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\n\nvar sv = moment.defineLocale('sv', {\n    months : 'januari_februari_mars_april_maj_juni_juli_augusti_september_oktober_november_december'.split('_'),\n    monthsShort : 'jan_feb_mar_apr_maj_jun_jul_aug_sep_okt_nov_dec'.split('_'),\n    weekdays : 'söndag_måndag_tisdag_onsdag_torsdag_fredag_lördag'.split('_'),\n    weekdaysShort : 'sön_mån_tis_ons_tor_fre_lör'.split('_'),\n    weekdaysMin : 'sö_må_ti_on_to_fr_lö'.split('_'),\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'YYYY-MM-DD',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY [kl.] HH:mm',\n        LLLL : 'dddd D MMMM YYYY [kl.] HH:mm',\n        lll : 'D MMM YYYY HH:mm',\n        llll : 'ddd D MMM YYYY HH:mm'\n    },\n    calendar : {\n        sameDay: '[Idag] LT',\n        nextDay: '[Imorgon] LT',\n        lastDay: '[Igår] LT',\n        nextWeek: '[På] dddd LT',\n        lastWeek: '[I] dddd[s] LT',\n        sameElse: 'L'\n    },\n    relativeTime : {\n        future : 'om %s',\n        past : 'för %s sedan',\n        s : 'några sekunder',\n        m : 'en minut',\n        mm : '%d minuter',\n        h : 'en timme',\n        hh : '%d timmar',\n        d : 'en dag',\n        dd : '%d dagar',\n        M : 'en månad',\n        MM : '%d månader',\n        y : 'ett år',\n        yy : '%d år'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}(e|a)/,\n    ordinal : function (number) {\n        var b = number % 10,\n            output = (~~(number % 100 / 10) === 1) ? 'e' :\n            (b === 1) ? 'a' :\n            (b === 2) ? 'a' :\n            (b === 3) ? 'e' : 'e';\n        return number + output;\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\nreturn sv;\n\n})));\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/locale/sw.js",
    "content": "//! moment.js locale configuration\n//! locale : Swahili [sw]\n//! author : Fahad Kassim : https://github.com/fadsel\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\n\nvar sw = moment.defineLocale('sw', {\n    months : 'Januari_Februari_Machi_Aprili_Mei_Juni_Julai_Agosti_Septemba_Oktoba_Novemba_Desemba'.split('_'),\n    monthsShort : 'Jan_Feb_Mac_Apr_Mei_Jun_Jul_Ago_Sep_Okt_Nov_Des'.split('_'),\n    weekdays : 'Jumapili_Jumatatu_Jumanne_Jumatano_Alhamisi_Ijumaa_Jumamosi'.split('_'),\n    weekdaysShort : 'Jpl_Jtat_Jnne_Jtan_Alh_Ijm_Jmos'.split('_'),\n    weekdaysMin : 'J2_J3_J4_J5_Al_Ij_J1'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD.MM.YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY HH:mm',\n        LLLL : 'dddd, D MMMM YYYY HH:mm'\n    },\n    calendar : {\n        sameDay : '[leo saa] LT',\n        nextDay : '[kesho saa] LT',\n        nextWeek : '[wiki ijayo] dddd [saat] LT',\n        lastDay : '[jana] LT',\n        lastWeek : '[wiki iliyopita] dddd [saat] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : '%s baadaye',\n        past : 'tokea %s',\n        s : 'hivi punde',\n        m : 'dakika moja',\n        mm : 'dakika %d',\n        h : 'saa limoja',\n        hh : 'masaa %d',\n        d : 'siku moja',\n        dd : 'masiku %d',\n        M : 'mwezi mmoja',\n        MM : 'miezi %d',\n        y : 'mwaka mmoja',\n        yy : 'miaka %d'\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 7  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\nreturn sw;\n\n})));\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/locale/ta.js",
    "content": "//! moment.js locale configuration\n//! locale : Tamil [ta]\n//! author : Arjunkumar Krishnamoorthy : https://github.com/tk120404\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\n\nvar symbolMap = {\n    '1': '௧',\n    '2': '௨',\n    '3': '௩',\n    '4': '௪',\n    '5': '௫',\n    '6': '௬',\n    '7': '௭',\n    '8': '௮',\n    '9': '௯',\n    '0': '௦'\n};\nvar numberMap = {\n    '௧': '1',\n    '௨': '2',\n    '௩': '3',\n    '௪': '4',\n    '௫': '5',\n    '௬': '6',\n    '௭': '7',\n    '௮': '8',\n    '௯': '9',\n    '௦': '0'\n};\n\nvar ta = moment.defineLocale('ta', {\n    months : 'ஜனவரி_பிப்ரவரி_மார்ச்_ஏப்ரல்_மே_ஜூன்_ஜூலை_ஆகஸ்ட்_செப்டெம்பர்_அக்டோபர்_நவம்பர்_டிசம்பர்'.split('_'),\n    monthsShort : 'ஜனவரி_பிப்ரவரி_மார்ச்_ஏப்ரல்_மே_ஜூன்_ஜூலை_ஆகஸ்ட்_செப்டெம்பர்_அக்டோபர்_நவம்பர்_டிசம்பர்'.split('_'),\n    weekdays : 'ஞாயிற்றுக்கிழமை_திங்கட்கிழமை_செவ்வாய்கிழமை_புதன்கிழமை_வியாழக்கிழமை_வெள்ளிக்கிழமை_சனிக்கிழமை'.split('_'),\n    weekdaysShort : 'ஞாயிறு_திங்கள்_செவ்வாய்_புதன்_வியாழன்_வெள்ளி_சனி'.split('_'),\n    weekdaysMin : 'ஞா_தி_செ_பு_வி_வெ_ச'.split('_'),\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY, HH:mm',\n        LLLL : 'dddd, D MMMM YYYY, HH:mm'\n    },\n    calendar : {\n        sameDay : '[இன்று] LT',\n        nextDay : '[நாளை] LT',\n        nextWeek : 'dddd, LT',\n        lastDay : '[நேற்று] LT',\n        lastWeek : '[கடந்த வாரம்] dddd, LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : '%s இல்',\n        past : '%s முன்',\n        s : 'ஒரு சில விநாடிகள்',\n        m : 'ஒரு நிமிடம்',\n        mm : '%d நிமிடங்கள்',\n        h : 'ஒரு மணி நேரம்',\n        hh : '%d மணி நேரம்',\n        d : 'ஒரு நாள்',\n        dd : '%d நாட்கள்',\n        M : 'ஒரு மாதம்',\n        MM : '%d மாதங்கள்',\n        y : 'ஒரு வருடம்',\n        yy : '%d ஆண்டுகள்'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}வது/,\n    ordinal : function (number) {\n        return number + 'வது';\n    },\n    preparse: function (string) {\n        return string.replace(/[௧௨௩௪௫௬௭௮௯௦]/g, function (match) {\n            return numberMap[match];\n        });\n    },\n    postformat: function (string) {\n        return string.replace(/\\d/g, function (match) {\n            return symbolMap[match];\n        });\n    },\n    // refer http://ta.wikipedia.org/s/1er1\n    meridiemParse: /யாமம்|வைகறை|காலை|நண்பகல்|எற்பாடு|மாலை/,\n    meridiem : function (hour, minute, isLower) {\n        if (hour < 2) {\n            return ' யாமம்';\n        } else if (hour < 6) {\n            return ' வைகறை';  // வைகறை\n        } else if (hour < 10) {\n            return ' காலை'; // காலை\n        } else if (hour < 14) {\n            return ' நண்பகல்'; // நண்பகல்\n        } else if (hour < 18) {\n            return ' எற்பாடு'; // எற்பாடு\n        } else if (hour < 22) {\n            return ' மாலை'; // மாலை\n        } else {\n            return ' யாமம்';\n        }\n    },\n    meridiemHour : function (hour, meridiem) {\n        if (hour === 12) {\n            hour = 0;\n        }\n        if (meridiem === 'யாமம்') {\n            return hour < 2 ? hour : hour + 12;\n        } else if (meridiem === 'வைகறை' || meridiem === 'காலை') {\n            return hour;\n        } else if (meridiem === 'நண்பகல்') {\n            return hour >= 10 ? hour : hour + 12;\n        } else {\n            return hour + 12;\n        }\n    },\n    week : {\n        dow : 0, // Sunday is the first day of the week.\n        doy : 6  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\nreturn ta;\n\n})));\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/locale/te.js",
    "content": "//! moment.js locale configuration\n//! locale : Telugu [te]\n//! author : Krishna Chaitanya Thota : https://github.com/kcthota\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\n\nvar te = moment.defineLocale('te', {\n    months : 'జనవరి_ఫిబ్రవరి_మార్చి_ఏప్రిల్_మే_జూన్_జూలై_ఆగస్టు_సెప్టెంబర్_అక్టోబర్_నవంబర్_డిసెంబర్'.split('_'),\n    monthsShort : 'జన._ఫిబ్ర._మార్చి_ఏప్రి._మే_జూన్_జూలై_ఆగ._సెప్._అక్టో._నవ._డిసె.'.split('_'),\n    monthsParseExact : true,\n    weekdays : 'ఆదివారం_సోమవారం_మంగళవారం_బుధవారం_గురువారం_శుక్రవారం_శనివారం'.split('_'),\n    weekdaysShort : 'ఆది_సోమ_మంగళ_బుధ_గురు_శుక్ర_శని'.split('_'),\n    weekdaysMin : 'ఆ_సో_మం_బు_గు_శు_శ'.split('_'),\n    longDateFormat : {\n        LT : 'A h:mm',\n        LTS : 'A h:mm:ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY, A h:mm',\n        LLLL : 'dddd, D MMMM YYYY, A h:mm'\n    },\n    calendar : {\n        sameDay : '[నేడు] LT',\n        nextDay : '[రేపు] LT',\n        nextWeek : 'dddd, LT',\n        lastDay : '[నిన్న] LT',\n        lastWeek : '[గత] dddd, LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : '%s లో',\n        past : '%s క్రితం',\n        s : 'కొన్ని క్షణాలు',\n        m : 'ఒక నిమిషం',\n        mm : '%d నిమిషాలు',\n        h : 'ఒక గంట',\n        hh : '%d గంటలు',\n        d : 'ఒక రోజు',\n        dd : '%d రోజులు',\n        M : 'ఒక నెల',\n        MM : '%d నెలలు',\n        y : 'ఒక సంవత్సరం',\n        yy : '%d సంవత్సరాలు'\n    },\n    dayOfMonthOrdinalParse : /\\d{1,2}వ/,\n    ordinal : '%dవ',\n    meridiemParse: /రాత్రి|ఉదయం|మధ్యాహ్నం|సాయంత్రం/,\n    meridiemHour : function (hour, meridiem) {\n        if (hour === 12) {\n            hour = 0;\n        }\n        if (meridiem === 'రాత్రి') {\n            return hour < 4 ? hour : hour + 12;\n        } else if (meridiem === 'ఉదయం') {\n            return hour;\n        } else if (meridiem === 'మధ్యాహ్నం') {\n            return hour >= 10 ? hour : hour + 12;\n        } else if (meridiem === 'సాయంత్రం') {\n            return hour + 12;\n        }\n    },\n    meridiem : function (hour, minute, isLower) {\n        if (hour < 4) {\n            return 'రాత్రి';\n        } else if (hour < 10) {\n            return 'ఉదయం';\n        } else if (hour < 17) {\n            return 'మధ్యాహ్నం';\n        } else if (hour < 20) {\n            return 'సాయంత్రం';\n        } else {\n            return 'రాత్రి';\n        }\n    },\n    week : {\n        dow : 0, // Sunday is the first day of the week.\n        doy : 6  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\nreturn te;\n\n})));\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/locale/tet.js",
    "content": "//! moment.js locale configuration\n//! locale : Tetun Dili (East Timor) [tet]\n//! author : Joshua Brooks : https://github.com/joshbrooks\n//! author : Onorio De J. Afonso : https://github.com/marobo\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\n\nvar tet = moment.defineLocale('tet', {\n    months : 'Janeiru_Fevereiru_Marsu_Abril_Maiu_Juniu_Juliu_Augustu_Setembru_Outubru_Novembru_Dezembru'.split('_'),\n    monthsShort : 'Jan_Fev_Mar_Abr_Mai_Jun_Jul_Aug_Set_Out_Nov_Dez'.split('_'),\n    weekdays : 'Domingu_Segunda_Tersa_Kuarta_Kinta_Sexta_Sabadu'.split('_'),\n    weekdaysShort : 'Dom_Seg_Ters_Kua_Kint_Sext_Sab'.split('_'),\n    weekdaysMin : 'Do_Seg_Te_Ku_Ki_Sex_Sa'.split('_'),\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY HH:mm',\n        LLLL : 'dddd, D MMMM YYYY HH:mm'\n    },\n    calendar : {\n        sameDay: '[Ohin iha] LT',\n        nextDay: '[Aban iha] LT',\n        nextWeek: 'dddd [iha] LT',\n        lastDay: '[Horiseik iha] LT',\n        lastWeek: 'dddd [semana kotuk] [iha] LT',\n        sameElse: 'L'\n    },\n    relativeTime : {\n        future : 'iha %s',\n        past : '%s liuba',\n        s : 'minutu balun',\n        m : 'minutu ida',\n        mm : 'minutus %d',\n        h : 'horas ida',\n        hh : 'horas %d',\n        d : 'loron ida',\n        dd : 'loron %d',\n        M : 'fulan ida',\n        MM : 'fulan %d',\n        y : 'tinan ida',\n        yy : 'tinan %d'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}(st|nd|rd|th)/,\n    ordinal : function (number) {\n        var b = number % 10,\n            output = (~~(number % 100 / 10) === 1) ? 'th' :\n            (b === 1) ? 'st' :\n            (b === 2) ? 'nd' :\n            (b === 3) ? 'rd' : 'th';\n        return number + output;\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\nreturn tet;\n\n})));\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/locale/th.js",
    "content": "//! moment.js locale configuration\n//! locale : Thai [th]\n//! author : Kridsada Thanabulpong : https://github.com/sirn\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\n\nvar th = moment.defineLocale('th', {\n    months : 'มกราคม_กุมภาพันธ์_มีนาคม_เมษายน_พฤษภาคม_มิถุนายน_กรกฎาคม_สิงหาคม_กันยายน_ตุลาคม_พฤศจิกายน_ธันวาคม'.split('_'),\n    monthsShort : 'ม.ค._ก.พ._มี.ค._เม.ย._พ.ค._มิ.ย._ก.ค._ส.ค._ก.ย._ต.ค._พ.ย._ธ.ค.'.split('_'),\n    monthsParseExact: true,\n    weekdays : 'อาทิตย์_จันทร์_อังคาร_พุธ_พฤหัสบดี_ศุกร์_เสาร์'.split('_'),\n    weekdaysShort : 'อาทิตย์_จันทร์_อังคาร_พุธ_พฤหัส_ศุกร์_เสาร์'.split('_'), // yes, three characters difference\n    weekdaysMin : 'อา._จ._อ._พ._พฤ._ศ._ส.'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat : {\n        LT : 'H:mm',\n        LTS : 'H:mm:ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY เวลา H:mm',\n        LLLL : 'วันddddที่ D MMMM YYYY เวลา H:mm'\n    },\n    meridiemParse: /ก่อนเที่ยง|หลังเที่ยง/,\n    isPM: function (input) {\n        return input === 'หลังเที่ยง';\n    },\n    meridiem : function (hour, minute, isLower) {\n        if (hour < 12) {\n            return 'ก่อนเที่ยง';\n        } else {\n            return 'หลังเที่ยง';\n        }\n    },\n    calendar : {\n        sameDay : '[วันนี้ เวลา] LT',\n        nextDay : '[พรุ่งนี้ เวลา] LT',\n        nextWeek : 'dddd[หน้า เวลา] LT',\n        lastDay : '[เมื่อวานนี้ เวลา] LT',\n        lastWeek : '[วัน]dddd[ที่แล้ว เวลา] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'อีก %s',\n        past : '%sที่แล้ว',\n        s : 'ไม่กี่วินาที',\n        m : '1 นาที',\n        mm : '%d นาที',\n        h : '1 ชั่วโมง',\n        hh : '%d ชั่วโมง',\n        d : '1 วัน',\n        dd : '%d วัน',\n        M : '1 เดือน',\n        MM : '%d เดือน',\n        y : '1 ปี',\n        yy : '%d ปี'\n    }\n});\n\nreturn th;\n\n})));\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/locale/tl-ph.js",
    "content": "//! moment.js locale configuration\n//! locale : Tagalog (Philippines) [tl-ph]\n//! author : Dan Hagman : https://github.com/hagmandan\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\n\nvar tlPh = moment.defineLocale('tl-ph', {\n    months : 'Enero_Pebrero_Marso_Abril_Mayo_Hunyo_Hulyo_Agosto_Setyembre_Oktubre_Nobyembre_Disyembre'.split('_'),\n    monthsShort : 'Ene_Peb_Mar_Abr_May_Hun_Hul_Ago_Set_Okt_Nob_Dis'.split('_'),\n    weekdays : 'Linggo_Lunes_Martes_Miyerkules_Huwebes_Biyernes_Sabado'.split('_'),\n    weekdaysShort : 'Lin_Lun_Mar_Miy_Huw_Biy_Sab'.split('_'),\n    weekdaysMin : 'Li_Lu_Ma_Mi_Hu_Bi_Sab'.split('_'),\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'MM/D/YYYY',\n        LL : 'MMMM D, YYYY',\n        LLL : 'MMMM D, YYYY HH:mm',\n        LLLL : 'dddd, MMMM DD, YYYY HH:mm'\n    },\n    calendar : {\n        sameDay: 'LT [ngayong araw]',\n        nextDay: '[Bukas ng] LT',\n        nextWeek: 'LT [sa susunod na] dddd',\n        lastDay: 'LT [kahapon]',\n        lastWeek: 'LT [noong nakaraang] dddd',\n        sameElse: 'L'\n    },\n    relativeTime : {\n        future : 'sa loob ng %s',\n        past : '%s ang nakalipas',\n        s : 'ilang segundo',\n        m : 'isang minuto',\n        mm : '%d minuto',\n        h : 'isang oras',\n        hh : '%d oras',\n        d : 'isang araw',\n        dd : '%d araw',\n        M : 'isang buwan',\n        MM : '%d buwan',\n        y : 'isang taon',\n        yy : '%d taon'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}/,\n    ordinal : function (number) {\n        return number;\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\nreturn tlPh;\n\n})));\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/locale/tlh.js",
    "content": "//! moment.js locale configuration\n//! locale : Klingon [tlh]\n//! author : Dominika Kruk : https://github.com/amaranthrose\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\n\nvar numbersNouns = 'pagh_wa’_cha’_wej_loS_vagh_jav_Soch_chorgh_Hut'.split('_');\n\nfunction translateFuture(output) {\n    var time = output;\n    time = (output.indexOf('jaj') !== -1) ?\n    time.slice(0, -3) + 'leS' :\n    (output.indexOf('jar') !== -1) ?\n    time.slice(0, -3) + 'waQ' :\n    (output.indexOf('DIS') !== -1) ?\n    time.slice(0, -3) + 'nem' :\n    time + ' pIq';\n    return time;\n}\n\nfunction translatePast(output) {\n    var time = output;\n    time = (output.indexOf('jaj') !== -1) ?\n    time.slice(0, -3) + 'Hu’' :\n    (output.indexOf('jar') !== -1) ?\n    time.slice(0, -3) + 'wen' :\n    (output.indexOf('DIS') !== -1) ?\n    time.slice(0, -3) + 'ben' :\n    time + ' ret';\n    return time;\n}\n\nfunction translate(number, withoutSuffix, string, isFuture) {\n    var numberNoun = numberAsNoun(number);\n    switch (string) {\n        case 'mm':\n            return numberNoun + ' tup';\n        case 'hh':\n            return numberNoun + ' rep';\n        case 'dd':\n            return numberNoun + ' jaj';\n        case 'MM':\n            return numberNoun + ' jar';\n        case 'yy':\n            return numberNoun + ' DIS';\n    }\n}\n\nfunction numberAsNoun(number) {\n    var hundred = Math.floor((number % 1000) / 100),\n    ten = Math.floor((number % 100) / 10),\n    one = number % 10,\n    word = '';\n    if (hundred > 0) {\n        word += numbersNouns[hundred] + 'vatlh';\n    }\n    if (ten > 0) {\n        word += ((word !== '') ? ' ' : '') + numbersNouns[ten] + 'maH';\n    }\n    if (one > 0) {\n        word += ((word !== '') ? ' ' : '') + numbersNouns[one];\n    }\n    return (word === '') ? 'pagh' : word;\n}\n\nvar tlh = moment.defineLocale('tlh', {\n    months : 'tera’ jar wa’_tera’ jar cha’_tera’ jar wej_tera’ jar loS_tera’ jar vagh_tera’ jar jav_tera’ jar Soch_tera’ jar chorgh_tera’ jar Hut_tera’ jar wa’maH_tera’ jar wa’maH wa’_tera’ jar wa’maH cha’'.split('_'),\n    monthsShort : 'jar wa’_jar cha’_jar wej_jar loS_jar vagh_jar jav_jar Soch_jar chorgh_jar Hut_jar wa’maH_jar wa’maH wa’_jar wa’maH cha’'.split('_'),\n    monthsParseExact : true,\n    weekdays : 'lojmItjaj_DaSjaj_povjaj_ghItlhjaj_loghjaj_buqjaj_ghInjaj'.split('_'),\n    weekdaysShort : 'lojmItjaj_DaSjaj_povjaj_ghItlhjaj_loghjaj_buqjaj_ghInjaj'.split('_'),\n    weekdaysMin : 'lojmItjaj_DaSjaj_povjaj_ghItlhjaj_loghjaj_buqjaj_ghInjaj'.split('_'),\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD.MM.YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY HH:mm',\n        LLLL : 'dddd, D MMMM YYYY HH:mm'\n    },\n    calendar : {\n        sameDay: '[DaHjaj] LT',\n        nextDay: '[wa’leS] LT',\n        nextWeek: 'LLL',\n        lastDay: '[wa’Hu’] LT',\n        lastWeek: 'LLL',\n        sameElse: 'L'\n    },\n    relativeTime : {\n        future : translateFuture,\n        past : translatePast,\n        s : 'puS lup',\n        m : 'wa’ tup',\n        mm : translate,\n        h : 'wa’ rep',\n        hh : translate,\n        d : 'wa’ jaj',\n        dd : translate,\n        M : 'wa’ jar',\n        MM : translate,\n        y : 'wa’ DIS',\n        yy : translate\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}\\./,\n    ordinal : '%d.',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\nreturn tlh;\n\n})));\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/locale/tr.js",
    "content": "//! moment.js locale configuration\n//! locale : Turkish [tr]\n//! authors : Erhan Gundogan : https://github.com/erhangundogan,\n//!           Burak Yiğit Kaya: https://github.com/BYK\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\n\nvar suffixes = {\n    1: '\\'inci',\n    5: '\\'inci',\n    8: '\\'inci',\n    70: '\\'inci',\n    80: '\\'inci',\n    2: '\\'nci',\n    7: '\\'nci',\n    20: '\\'nci',\n    50: '\\'nci',\n    3: '\\'üncü',\n    4: '\\'üncü',\n    100: '\\'üncü',\n    6: '\\'ncı',\n    9: '\\'uncu',\n    10: '\\'uncu',\n    30: '\\'uncu',\n    60: '\\'ıncı',\n    90: '\\'ıncı'\n};\n\nvar tr = moment.defineLocale('tr', {\n    months : 'Ocak_Şubat_Mart_Nisan_Mayıs_Haziran_Temmuz_Ağustos_Eylül_Ekim_Kasım_Aralık'.split('_'),\n    monthsShort : 'Oca_Şub_Mar_Nis_May_Haz_Tem_Ağu_Eyl_Eki_Kas_Ara'.split('_'),\n    weekdays : 'Pazar_Pazartesi_Salı_Çarşamba_Perşembe_Cuma_Cumartesi'.split('_'),\n    weekdaysShort : 'Paz_Pts_Sal_Çar_Per_Cum_Cts'.split('_'),\n    weekdaysMin : 'Pz_Pt_Sa_Ça_Pe_Cu_Ct'.split('_'),\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD.MM.YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY HH:mm',\n        LLLL : 'dddd, D MMMM YYYY HH:mm'\n    },\n    calendar : {\n        sameDay : '[bugün saat] LT',\n        nextDay : '[yarın saat] LT',\n        nextWeek : '[haftaya] dddd [saat] LT',\n        lastDay : '[dün] LT',\n        lastWeek : '[geçen hafta] dddd [saat] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : '%s sonra',\n        past : '%s önce',\n        s : 'birkaç saniye',\n        m : 'bir dakika',\n        mm : '%d dakika',\n        h : 'bir saat',\n        hh : '%d saat',\n        d : 'bir gün',\n        dd : '%d gün',\n        M : 'bir ay',\n        MM : '%d ay',\n        y : 'bir yıl',\n        yy : '%d yıl'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}'(inci|nci|üncü|ncı|uncu|ıncı)/,\n    ordinal : function (number) {\n        if (number === 0) {  // special case for zero\n            return number + '\\'ıncı';\n        }\n        var a = number % 10,\n            b = number % 100 - a,\n            c = number >= 100 ? 100 : null;\n        return number + (suffixes[a] || suffixes[b] || suffixes[c]);\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 7  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\nreturn tr;\n\n})));\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/locale/tzl.js",
    "content": "//! moment.js locale configuration\n//! locale : Talossan [tzl]\n//! author : Robin van der Vliet : https://github.com/robin0van0der0v\n//! author : Iustì Canun\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\n\n// After the year there should be a slash and the amount of years since December 26, 1979 in Roman numerals.\n// This is currently too difficult (maybe even impossible) to add.\nvar tzl = moment.defineLocale('tzl', {\n    months : 'Januar_Fevraglh_Març_Avrïu_Mai_Gün_Julia_Guscht_Setemvar_Listopäts_Noemvar_Zecemvar'.split('_'),\n    monthsShort : 'Jan_Fev_Mar_Avr_Mai_Gün_Jul_Gus_Set_Lis_Noe_Zec'.split('_'),\n    weekdays : 'Súladi_Lúneçi_Maitzi_Márcuri_Xhúadi_Viénerçi_Sáturi'.split('_'),\n    weekdaysShort : 'Súl_Lún_Mai_Már_Xhú_Vié_Sát'.split('_'),\n    weekdaysMin : 'Sú_Lú_Ma_Má_Xh_Vi_Sá'.split('_'),\n    longDateFormat : {\n        LT : 'HH.mm',\n        LTS : 'HH.mm.ss',\n        L : 'DD.MM.YYYY',\n        LL : 'D. MMMM [dallas] YYYY',\n        LLL : 'D. MMMM [dallas] YYYY HH.mm',\n        LLLL : 'dddd, [li] D. MMMM [dallas] YYYY HH.mm'\n    },\n    meridiemParse: /d\\'o|d\\'a/i,\n    isPM : function (input) {\n        return 'd\\'o' === input.toLowerCase();\n    },\n    meridiem : function (hours, minutes, isLower) {\n        if (hours > 11) {\n            return isLower ? 'd\\'o' : 'D\\'O';\n        } else {\n            return isLower ? 'd\\'a' : 'D\\'A';\n        }\n    },\n    calendar : {\n        sameDay : '[oxhi à] LT',\n        nextDay : '[demà à] LT',\n        nextWeek : 'dddd [à] LT',\n        lastDay : '[ieiri à] LT',\n        lastWeek : '[sür el] dddd [lasteu à] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'osprei %s',\n        past : 'ja%s',\n        s : processRelativeTime,\n        m : processRelativeTime,\n        mm : processRelativeTime,\n        h : processRelativeTime,\n        hh : processRelativeTime,\n        d : processRelativeTime,\n        dd : processRelativeTime,\n        M : processRelativeTime,\n        MM : processRelativeTime,\n        y : processRelativeTime,\n        yy : processRelativeTime\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}\\./,\n    ordinal : '%d.',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\nfunction processRelativeTime(number, withoutSuffix, key, isFuture) {\n    var format = {\n        's': ['viensas secunds', '\\'iensas secunds'],\n        'm': ['\\'n míut', '\\'iens míut'],\n        'mm': [number + ' míuts', '' + number + ' míuts'],\n        'h': ['\\'n þora', '\\'iensa þora'],\n        'hh': [number + ' þoras', '' + number + ' þoras'],\n        'd': ['\\'n ziua', '\\'iensa ziua'],\n        'dd': [number + ' ziuas', '' + number + ' ziuas'],\n        'M': ['\\'n mes', '\\'iens mes'],\n        'MM': [number + ' mesen', '' + number + ' mesen'],\n        'y': ['\\'n ar', '\\'iens ar'],\n        'yy': [number + ' ars', '' + number + ' ars']\n    };\n    return isFuture ? format[key][0] : (withoutSuffix ? format[key][0] : format[key][1]);\n}\n\nreturn tzl;\n\n})));\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/locale/tzm-latn.js",
    "content": "//! moment.js locale configuration\n//! locale : Central Atlas Tamazight Latin [tzm-latn]\n//! author : Abdel Said : https://github.com/abdelsaid\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\n\nvar tzmLatn = moment.defineLocale('tzm-latn', {\n    months : 'innayr_brˤayrˤ_marˤsˤ_ibrir_mayyw_ywnyw_ywlywz_ɣwšt_šwtanbir_ktˤwbrˤ_nwwanbir_dwjnbir'.split('_'),\n    monthsShort : 'innayr_brˤayrˤ_marˤsˤ_ibrir_mayyw_ywnyw_ywlywz_ɣwšt_šwtanbir_ktˤwbrˤ_nwwanbir_dwjnbir'.split('_'),\n    weekdays : 'asamas_aynas_asinas_akras_akwas_asimwas_asiḍyas'.split('_'),\n    weekdaysShort : 'asamas_aynas_asinas_akras_akwas_asimwas_asiḍyas'.split('_'),\n    weekdaysMin : 'asamas_aynas_asinas_akras_akwas_asimwas_asiḍyas'.split('_'),\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY HH:mm',\n        LLLL : 'dddd D MMMM YYYY HH:mm'\n    },\n    calendar : {\n        sameDay: '[asdkh g] LT',\n        nextDay: '[aska g] LT',\n        nextWeek: 'dddd [g] LT',\n        lastDay: '[assant g] LT',\n        lastWeek: 'dddd [g] LT',\n        sameElse: 'L'\n    },\n    relativeTime : {\n        future : 'dadkh s yan %s',\n        past : 'yan %s',\n        s : 'imik',\n        m : 'minuḍ',\n        mm : '%d minuḍ',\n        h : 'saɛa',\n        hh : '%d tassaɛin',\n        d : 'ass',\n        dd : '%d ossan',\n        M : 'ayowr',\n        MM : '%d iyyirn',\n        y : 'asgas',\n        yy : '%d isgasn'\n    },\n    week : {\n        dow : 6, // Saturday is the first day of the week.\n        doy : 12  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\nreturn tzmLatn;\n\n})));\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/locale/tzm.js",
    "content": "//! moment.js locale configuration\n//! locale : Central Atlas Tamazight [tzm]\n//! author : Abdel Said : https://github.com/abdelsaid\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\n\nvar tzm = moment.defineLocale('tzm', {\n    months : 'ⵉⵏⵏⴰⵢⵔ_ⴱⵕⴰⵢⵕ_ⵎⴰⵕⵚ_ⵉⴱⵔⵉⵔ_ⵎⴰⵢⵢⵓ_ⵢⵓⵏⵢⵓ_ⵢⵓⵍⵢⵓⵣ_ⵖⵓⵛⵜ_ⵛⵓⵜⴰⵏⴱⵉⵔ_ⴽⵟⵓⴱⵕ_ⵏⵓⵡⴰⵏⴱⵉⵔ_ⴷⵓⵊⵏⴱⵉⵔ'.split('_'),\n    monthsShort : 'ⵉⵏⵏⴰⵢⵔ_ⴱⵕⴰⵢⵕ_ⵎⴰⵕⵚ_ⵉⴱⵔⵉⵔ_ⵎⴰⵢⵢⵓ_ⵢⵓⵏⵢⵓ_ⵢⵓⵍⵢⵓⵣ_ⵖⵓⵛⵜ_ⵛⵓⵜⴰⵏⴱⵉⵔ_ⴽⵟⵓⴱⵕ_ⵏⵓⵡⴰⵏⴱⵉⵔ_ⴷⵓⵊⵏⴱⵉⵔ'.split('_'),\n    weekdays : 'ⴰⵙⴰⵎⴰⵙ_ⴰⵢⵏⴰⵙ_ⴰⵙⵉⵏⴰⵙ_ⴰⴽⵔⴰⵙ_ⴰⴽⵡⴰⵙ_ⴰⵙⵉⵎⵡⴰⵙ_ⴰⵙⵉⴹⵢⴰⵙ'.split('_'),\n    weekdaysShort : 'ⴰⵙⴰⵎⴰⵙ_ⴰⵢⵏⴰⵙ_ⴰⵙⵉⵏⴰⵙ_ⴰⴽⵔⴰⵙ_ⴰⴽⵡⴰⵙ_ⴰⵙⵉⵎⵡⴰⵙ_ⴰⵙⵉⴹⵢⴰⵙ'.split('_'),\n    weekdaysMin : 'ⴰⵙⴰⵎⴰⵙ_ⴰⵢⵏⴰⵙ_ⴰⵙⵉⵏⴰⵙ_ⴰⴽⵔⴰⵙ_ⴰⴽⵡⴰⵙ_ⴰⵙⵉⵎⵡⴰⵙ_ⴰⵙⵉⴹⵢⴰⵙ'.split('_'),\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS: 'HH:mm:ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY HH:mm',\n        LLLL : 'dddd D MMMM YYYY HH:mm'\n    },\n    calendar : {\n        sameDay: '[ⴰⵙⴷⵅ ⴴ] LT',\n        nextDay: '[ⴰⵙⴽⴰ ⴴ] LT',\n        nextWeek: 'dddd [ⴴ] LT',\n        lastDay: '[ⴰⵚⴰⵏⵜ ⴴ] LT',\n        lastWeek: 'dddd [ⴴ] LT',\n        sameElse: 'L'\n    },\n    relativeTime : {\n        future : 'ⴷⴰⴷⵅ ⵙ ⵢⴰⵏ %s',\n        past : 'ⵢⴰⵏ %s',\n        s : 'ⵉⵎⵉⴽ',\n        m : 'ⵎⵉⵏⵓⴺ',\n        mm : '%d ⵎⵉⵏⵓⴺ',\n        h : 'ⵙⴰⵄⴰ',\n        hh : '%d ⵜⴰⵙⵙⴰⵄⵉⵏ',\n        d : 'ⴰⵙⵙ',\n        dd : '%d oⵙⵙⴰⵏ',\n        M : 'ⴰⵢoⵓⵔ',\n        MM : '%d ⵉⵢⵢⵉⵔⵏ',\n        y : 'ⴰⵙⴳⴰⵙ',\n        yy : '%d ⵉⵙⴳⴰⵙⵏ'\n    },\n    week : {\n        dow : 6, // Saturday is the first day of the week.\n        doy : 12  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\nreturn tzm;\n\n})));\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/locale/uk.js",
    "content": "//! moment.js locale configuration\n//! locale : Ukrainian [uk]\n//! author : zemlanin : https://github.com/zemlanin\n//! Author : Menelion Elensúle : https://github.com/Oire\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\n\nfunction plural(word, num) {\n    var forms = word.split('_');\n    return num % 10 === 1 && num % 100 !== 11 ? forms[0] : (num % 10 >= 2 && num % 10 <= 4 && (num % 100 < 10 || num % 100 >= 20) ? forms[1] : forms[2]);\n}\nfunction relativeTimeWithPlural(number, withoutSuffix, key) {\n    var format = {\n        'mm': withoutSuffix ? 'хвилина_хвилини_хвилин' : 'хвилину_хвилини_хвилин',\n        'hh': withoutSuffix ? 'година_години_годин' : 'годину_години_годин',\n        'dd': 'день_дні_днів',\n        'MM': 'місяць_місяці_місяців',\n        'yy': 'рік_роки_років'\n    };\n    if (key === 'm') {\n        return withoutSuffix ? 'хвилина' : 'хвилину';\n    }\n    else if (key === 'h') {\n        return withoutSuffix ? 'година' : 'годину';\n    }\n    else {\n        return number + ' ' + plural(format[key], +number);\n    }\n}\nfunction weekdaysCaseReplace(m, format) {\n    var weekdays = {\n        'nominative': 'неділя_понеділок_вівторок_середа_четвер_п’ятниця_субота'.split('_'),\n        'accusative': 'неділю_понеділок_вівторок_середу_четвер_п’ятницю_суботу'.split('_'),\n        'genitive': 'неділі_понеділка_вівторка_середи_четверга_п’ятниці_суботи'.split('_')\n    };\n\n    if (!m) {\n        return weekdays['nominative'];\n    }\n\n    var nounCase = (/(\\[[ВвУу]\\]) ?dddd/).test(format) ?\n        'accusative' :\n        ((/\\[?(?:минулої|наступної)? ?\\] ?dddd/).test(format) ?\n            'genitive' :\n            'nominative');\n    return weekdays[nounCase][m.day()];\n}\nfunction processHoursFunction(str) {\n    return function () {\n        return str + 'о' + (this.hours() === 11 ? 'б' : '') + '] LT';\n    };\n}\n\nvar uk = moment.defineLocale('uk', {\n    months : {\n        'format': 'січня_лютого_березня_квітня_травня_червня_липня_серпня_вересня_жовтня_листопада_грудня'.split('_'),\n        'standalone': 'січень_лютий_березень_квітень_травень_червень_липень_серпень_вересень_жовтень_листопад_грудень'.split('_')\n    },\n    monthsShort : 'січ_лют_бер_квіт_трав_черв_лип_серп_вер_жовт_лист_груд'.split('_'),\n    weekdays : weekdaysCaseReplace,\n    weekdaysShort : 'нд_пн_вт_ср_чт_пт_сб'.split('_'),\n    weekdaysMin : 'нд_пн_вт_ср_чт_пт_сб'.split('_'),\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD.MM.YYYY',\n        LL : 'D MMMM YYYY р.',\n        LLL : 'D MMMM YYYY р., HH:mm',\n        LLLL : 'dddd, D MMMM YYYY р., HH:mm'\n    },\n    calendar : {\n        sameDay: processHoursFunction('[Сьогодні '),\n        nextDay: processHoursFunction('[Завтра '),\n        lastDay: processHoursFunction('[Вчора '),\n        nextWeek: processHoursFunction('[У] dddd ['),\n        lastWeek: function () {\n            switch (this.day()) {\n                case 0:\n                case 3:\n                case 5:\n                case 6:\n                    return processHoursFunction('[Минулої] dddd [').call(this);\n                case 1:\n                case 2:\n                case 4:\n                    return processHoursFunction('[Минулого] dddd [').call(this);\n            }\n        },\n        sameElse: 'L'\n    },\n    relativeTime : {\n        future : 'за %s',\n        past : '%s тому',\n        s : 'декілька секунд',\n        m : relativeTimeWithPlural,\n        mm : relativeTimeWithPlural,\n        h : 'годину',\n        hh : relativeTimeWithPlural,\n        d : 'день',\n        dd : relativeTimeWithPlural,\n        M : 'місяць',\n        MM : relativeTimeWithPlural,\n        y : 'рік',\n        yy : relativeTimeWithPlural\n    },\n    // M. E.: those two are virtually unused but a user might want to implement them for his/her website for some reason\n    meridiemParse: /ночі|ранку|дня|вечора/,\n    isPM: function (input) {\n        return /^(дня|вечора)$/.test(input);\n    },\n    meridiem : function (hour, minute, isLower) {\n        if (hour < 4) {\n            return 'ночі';\n        } else if (hour < 12) {\n            return 'ранку';\n        } else if (hour < 17) {\n            return 'дня';\n        } else {\n            return 'вечора';\n        }\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}-(й|го)/,\n    ordinal: function (number, period) {\n        switch (period) {\n            case 'M':\n            case 'd':\n            case 'DDD':\n            case 'w':\n            case 'W':\n                return number + '-й';\n            case 'D':\n                return number + '-го';\n            default:\n                return number;\n        }\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 7  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\nreturn uk;\n\n})));\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/locale/ur.js",
    "content": "//! moment.js locale configuration\n//! locale : Urdu [ur]\n//! author : Sawood Alam : https://github.com/ibnesayeed\n//! author : Zack : https://github.com/ZackVision\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\n\nvar months = [\n    'جنوری',\n    'فروری',\n    'مارچ',\n    'اپریل',\n    'مئی',\n    'جون',\n    'جولائی',\n    'اگست',\n    'ستمبر',\n    'اکتوبر',\n    'نومبر',\n    'دسمبر'\n];\nvar days = [\n    'اتوار',\n    'پیر',\n    'منگل',\n    'بدھ',\n    'جمعرات',\n    'جمعہ',\n    'ہفتہ'\n];\n\nvar ur = moment.defineLocale('ur', {\n    months : months,\n    monthsShort : months,\n    weekdays : days,\n    weekdaysShort : days,\n    weekdaysMin : days,\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY HH:mm',\n        LLLL : 'dddd، D MMMM YYYY HH:mm'\n    },\n    meridiemParse: /صبح|شام/,\n    isPM : function (input) {\n        return 'شام' === input;\n    },\n    meridiem : function (hour, minute, isLower) {\n        if (hour < 12) {\n            return 'صبح';\n        }\n        return 'شام';\n    },\n    calendar : {\n        sameDay : '[آج بوقت] LT',\n        nextDay : '[کل بوقت] LT',\n        nextWeek : 'dddd [بوقت] LT',\n        lastDay : '[گذشتہ روز بوقت] LT',\n        lastWeek : '[گذشتہ] dddd [بوقت] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : '%s بعد',\n        past : '%s قبل',\n        s : 'چند سیکنڈ',\n        m : 'ایک منٹ',\n        mm : '%d منٹ',\n        h : 'ایک گھنٹہ',\n        hh : '%d گھنٹے',\n        d : 'ایک دن',\n        dd : '%d دن',\n        M : 'ایک ماہ',\n        MM : '%d ماہ',\n        y : 'ایک سال',\n        yy : '%d سال'\n    },\n    preparse: function (string) {\n        return string.replace(/،/g, ',');\n    },\n    postformat: function (string) {\n        return string.replace(/,/g, '،');\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\nreturn ur;\n\n})));\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/locale/uz-latn.js",
    "content": "//! moment.js locale configuration\n//! locale : Uzbek Latin [uz-latn]\n//! author : Rasulbek Mirzayev : github.com/Rasulbeeek\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\n\nvar uzLatn = moment.defineLocale('uz-latn', {\n    months : 'Yanvar_Fevral_Mart_Aprel_May_Iyun_Iyul_Avgust_Sentabr_Oktabr_Noyabr_Dekabr'.split('_'),\n    monthsShort : 'Yan_Fev_Mar_Apr_May_Iyun_Iyul_Avg_Sen_Okt_Noy_Dek'.split('_'),\n    weekdays : 'Yakshanba_Dushanba_Seshanba_Chorshanba_Payshanba_Juma_Shanba'.split('_'),\n    weekdaysShort : 'Yak_Dush_Sesh_Chor_Pay_Jum_Shan'.split('_'),\n    weekdaysMin : 'Ya_Du_Se_Cho_Pa_Ju_Sha'.split('_'),\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY HH:mm',\n        LLLL : 'D MMMM YYYY, dddd HH:mm'\n    },\n    calendar : {\n        sameDay : '[Bugun soat] LT [da]',\n        nextDay : '[Ertaga] LT [da]',\n        nextWeek : 'dddd [kuni soat] LT [da]',\n        lastDay : '[Kecha soat] LT [da]',\n        lastWeek : '[O\\'tgan] dddd [kuni soat] LT [da]',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'Yaqin %s ichida',\n        past : 'Bir necha %s oldin',\n        s : 'soniya',\n        m : 'bir daqiqa',\n        mm : '%d daqiqa',\n        h : 'bir soat',\n        hh : '%d soat',\n        d : 'bir kun',\n        dd : '%d kun',\n        M : 'bir oy',\n        MM : '%d oy',\n        y : 'bir yil',\n        yy : '%d yil'\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 7  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\nreturn uzLatn;\n\n})));\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/locale/uz.js",
    "content": "//! moment.js locale configuration\n//! locale : Uzbek [uz]\n//! author : Sardor Muminov : https://github.com/muminoff\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\n\nvar uz = moment.defineLocale('uz', {\n    months : 'январ_феврал_март_апрел_май_июн_июл_август_сентябр_октябр_ноябр_декабр'.split('_'),\n    monthsShort : 'янв_фев_мар_апр_май_июн_июл_авг_сен_окт_ноя_дек'.split('_'),\n    weekdays : 'Якшанба_Душанба_Сешанба_Чоршанба_Пайшанба_Жума_Шанба'.split('_'),\n    weekdaysShort : 'Якш_Душ_Сеш_Чор_Пай_Жум_Шан'.split('_'),\n    weekdaysMin : 'Як_Ду_Се_Чо_Па_Жу_Ша'.split('_'),\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY HH:mm',\n        LLLL : 'D MMMM YYYY, dddd HH:mm'\n    },\n    calendar : {\n        sameDay : '[Бугун соат] LT [да]',\n        nextDay : '[Эртага] LT [да]',\n        nextWeek : 'dddd [куни соат] LT [да]',\n        lastDay : '[Кеча соат] LT [да]',\n        lastWeek : '[Утган] dddd [куни соат] LT [да]',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'Якин %s ичида',\n        past : 'Бир неча %s олдин',\n        s : 'фурсат',\n        m : 'бир дакика',\n        mm : '%d дакика',\n        h : 'бир соат',\n        hh : '%d соат',\n        d : 'бир кун',\n        dd : '%d кун',\n        M : 'бир ой',\n        MM : '%d ой',\n        y : 'бир йил',\n        yy : '%d йил'\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 7  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\nreturn uz;\n\n})));\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/locale/vi.js",
    "content": "//! moment.js locale configuration\n//! locale : Vietnamese [vi]\n//! author : Bang Nguyen : https://github.com/bangnk\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\n\nvar vi = moment.defineLocale('vi', {\n    months : 'tháng 1_tháng 2_tháng 3_tháng 4_tháng 5_tháng 6_tháng 7_tháng 8_tháng 9_tháng 10_tháng 11_tháng 12'.split('_'),\n    monthsShort : 'Th01_Th02_Th03_Th04_Th05_Th06_Th07_Th08_Th09_Th10_Th11_Th12'.split('_'),\n    monthsParseExact : true,\n    weekdays : 'chủ nhật_thứ hai_thứ ba_thứ tư_thứ năm_thứ sáu_thứ bảy'.split('_'),\n    weekdaysShort : 'CN_T2_T3_T4_T5_T6_T7'.split('_'),\n    weekdaysMin : 'CN_T2_T3_T4_T5_T6_T7'.split('_'),\n    weekdaysParseExact : true,\n    meridiemParse: /sa|ch/i,\n    isPM : function (input) {\n        return /^ch$/i.test(input);\n    },\n    meridiem : function (hours, minutes, isLower) {\n        if (hours < 12) {\n            return isLower ? 'sa' : 'SA';\n        } else {\n            return isLower ? 'ch' : 'CH';\n        }\n    },\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM [năm] YYYY',\n        LLL : 'D MMMM [năm] YYYY HH:mm',\n        LLLL : 'dddd, D MMMM [năm] YYYY HH:mm',\n        l : 'DD/M/YYYY',\n        ll : 'D MMM YYYY',\n        lll : 'D MMM YYYY HH:mm',\n        llll : 'ddd, D MMM YYYY HH:mm'\n    },\n    calendar : {\n        sameDay: '[Hôm nay lúc] LT',\n        nextDay: '[Ngày mai lúc] LT',\n        nextWeek: 'dddd [tuần tới lúc] LT',\n        lastDay: '[Hôm qua lúc] LT',\n        lastWeek: 'dddd [tuần rồi lúc] LT',\n        sameElse: 'L'\n    },\n    relativeTime : {\n        future : '%s tới',\n        past : '%s trước',\n        s : 'vài giây',\n        m : 'một phút',\n        mm : '%d phút',\n        h : 'một giờ',\n        hh : '%d giờ',\n        d : 'một ngày',\n        dd : '%d ngày',\n        M : 'một tháng',\n        MM : '%d tháng',\n        y : 'một năm',\n        yy : '%d năm'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}/,\n    ordinal : function (number) {\n        return number;\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\nreturn vi;\n\n})));\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/locale/x-pseudo.js",
    "content": "//! moment.js locale configuration\n//! locale : Pseudo [x-pseudo]\n//! author : Andrew Hood : https://github.com/andrewhood125\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\n\nvar xPseudo = moment.defineLocale('x-pseudo', {\n    months : 'J~áñúá~rý_F~ébrú~árý_~Márc~h_Áp~ríl_~Máý_~Júñé~_Júl~ý_Áú~gúst~_Sép~témb~ér_Ó~ctób~ér_Ñ~óvém~bér_~Décé~mbér'.split('_'),\n    monthsShort : 'J~áñ_~Féb_~Már_~Ápr_~Máý_~Júñ_~Júl_~Áúg_~Sép_~Óct_~Ñóv_~Déc'.split('_'),\n    monthsParseExact : true,\n    weekdays : 'S~úñdá~ý_Mó~ñdáý~_Túé~sdáý~_Wéd~ñésd~áý_T~húrs~dáý_~Fríd~áý_S~átúr~dáý'.split('_'),\n    weekdaysShort : 'S~úñ_~Móñ_~Túé_~Wéd_~Thú_~Frí_~Sát'.split('_'),\n    weekdaysMin : 'S~ú_Mó~_Tú_~Wé_T~h_Fr~_Sá'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat : {\n        LT : 'HH:mm',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY HH:mm',\n        LLLL : 'dddd, D MMMM YYYY HH:mm'\n    },\n    calendar : {\n        sameDay : '[T~ódá~ý át] LT',\n        nextDay : '[T~ómó~rró~w át] LT',\n        nextWeek : 'dddd [át] LT',\n        lastDay : '[Ý~ést~érdá~ý át] LT',\n        lastWeek : '[L~ást] dddd [át] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'í~ñ %s',\n        past : '%s á~gó',\n        s : 'á ~féw ~sécó~ñds',\n        m : 'á ~míñ~úté',\n        mm : '%d m~íñú~tés',\n        h : 'á~ñ hó~úr',\n        hh : '%d h~óúrs',\n        d : 'á ~dáý',\n        dd : '%d d~áýs',\n        M : 'á ~móñ~th',\n        MM : '%d m~óñt~hs',\n        y : 'á ~ýéár',\n        yy : '%d ý~éárs'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}(th|st|nd|rd)/,\n    ordinal : function (number) {\n        var b = number % 10,\n            output = (~~(number % 100 / 10) === 1) ? 'th' :\n            (b === 1) ? 'st' :\n            (b === 2) ? 'nd' :\n            (b === 3) ? 'rd' : 'th';\n        return number + output;\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\nreturn xPseudo;\n\n})));\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/locale/yo.js",
    "content": "//! moment.js locale configuration\n//! locale : Yoruba Nigeria [yo]\n//! author : Atolagbe Abisoye : https://github.com/andela-batolagbe\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\n\nvar yo = moment.defineLocale('yo', {\n    months : 'Sẹ́rẹ́_Èrèlè_Ẹrẹ̀nà_Ìgbé_Èbibi_Òkùdu_Agẹmo_Ògún_Owewe_Ọ̀wàrà_Bélú_Ọ̀pẹ̀̀'.split('_'),\n    monthsShort : 'Sẹ́r_Èrl_Ẹrn_Ìgb_Èbi_Òkù_Agẹ_Ògú_Owe_Ọ̀wà_Bél_Ọ̀pẹ̀̀'.split('_'),\n    weekdays : 'Àìkú_Ajé_Ìsẹ́gun_Ọjọ́rú_Ọjọ́bọ_Ẹtì_Àbámẹ́ta'.split('_'),\n    weekdaysShort : 'Àìk_Ajé_Ìsẹ́_Ọjr_Ọjb_Ẹtì_Àbá'.split('_'),\n    weekdaysMin : 'Àì_Aj_Ìs_Ọr_Ọb_Ẹt_Àb'.split('_'),\n    longDateFormat : {\n        LT : 'h:mm A',\n        LTS : 'h:mm:ss A',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY h:mm A',\n        LLLL : 'dddd, D MMMM YYYY h:mm A'\n    },\n    calendar : {\n        sameDay : '[Ònì ni] LT',\n        nextDay : '[Ọ̀la ni] LT',\n        nextWeek : 'dddd [Ọsẹ̀ tón\\'bọ] [ni] LT',\n        lastDay : '[Àna ni] LT',\n        lastWeek : 'dddd [Ọsẹ̀ tólọ́] [ni] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'ní %s',\n        past : '%s kọjá',\n        s : 'ìsẹjú aayá die',\n        m : 'ìsẹjú kan',\n        mm : 'ìsẹjú %d',\n        h : 'wákati kan',\n        hh : 'wákati %d',\n        d : 'ọjọ́ kan',\n        dd : 'ọjọ́ %d',\n        M : 'osù kan',\n        MM : 'osù %d',\n        y : 'ọdún kan',\n        yy : 'ọdún %d'\n    },\n    dayOfMonthOrdinalParse : /ọjọ́\\s\\d{1,2}/,\n    ordinal : 'ọjọ́ %d',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4 // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\nreturn yo;\n\n})));\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/locale/zh-cn.js",
    "content": "//! moment.js locale configuration\n//! locale : Chinese (China) [zh-cn]\n//! author : suupic : https://github.com/suupic\n//! author : Zeno Zeng : https://github.com/zenozeng\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\n\nvar zhCn = moment.defineLocale('zh-cn', {\n    months : '一月_二月_三月_四月_五月_六月_七月_八月_九月_十月_十一月_十二月'.split('_'),\n    monthsShort : '1月_2月_3月_4月_5月_6月_7月_8月_9月_10月_11月_12月'.split('_'),\n    weekdays : '星期日_星期一_星期二_星期三_星期四_星期五_星期六'.split('_'),\n    weekdaysShort : '周日_周一_周二_周三_周四_周五_周六'.split('_'),\n    weekdaysMin : '日_一_二_三_四_五_六'.split('_'),\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'YYYY年MMMD日',\n        LL : 'YYYY年MMMD日',\n        LLL : 'YYYY年MMMD日Ah点mm分',\n        LLLL : 'YYYY年MMMD日ddddAh点mm分',\n        l : 'YYYY年MMMD日',\n        ll : 'YYYY年MMMD日',\n        lll : 'YYYY年MMMD日 HH:mm',\n        llll : 'YYYY年MMMD日dddd HH:mm'\n    },\n    meridiemParse: /凌晨|早上|上午|中午|下午|晚上/,\n    meridiemHour: function (hour, meridiem) {\n        if (hour === 12) {\n            hour = 0;\n        }\n        if (meridiem === '凌晨' || meridiem === '早上' ||\n                meridiem === '上午') {\n            return hour;\n        } else if (meridiem === '下午' || meridiem === '晚上') {\n            return hour + 12;\n        } else {\n            // '中午'\n            return hour >= 11 ? hour : hour + 12;\n        }\n    },\n    meridiem : function (hour, minute, isLower) {\n        var hm = hour * 100 + minute;\n        if (hm < 600) {\n            return '凌晨';\n        } else if (hm < 900) {\n            return '早上';\n        } else if (hm < 1130) {\n            return '上午';\n        } else if (hm < 1230) {\n            return '中午';\n        } else if (hm < 1800) {\n            return '下午';\n        } else {\n            return '晚上';\n        }\n    },\n    calendar : {\n        sameDay : '[今天]LT',\n        nextDay : '[明天]LT',\n        nextWeek : '[下]ddddLT',\n        lastDay : '[昨天]LT',\n        lastWeek : '[上]ddddLT',\n        sameElse : 'L'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}(日|月|周)/,\n    ordinal : function (number, period) {\n        switch (period) {\n            case 'd':\n            case 'D':\n            case 'DDD':\n                return number + '日';\n            case 'M':\n                return number + '月';\n            case 'w':\n            case 'W':\n                return number + '周';\n            default:\n                return number;\n        }\n    },\n    relativeTime : {\n        future : '%s内',\n        past : '%s前',\n        s : '几秒',\n        m : '1 分钟',\n        mm : '%d 分钟',\n        h : '1 小时',\n        hh : '%d 小时',\n        d : '1 天',\n        dd : '%d 天',\n        M : '1 个月',\n        MM : '%d 个月',\n        y : '1 年',\n        yy : '%d 年'\n    },\n    week : {\n        // GB/T 7408-1994《数据元和交换格式·信息交换·日期和时间表示法》与ISO 8601:1988等效\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\nreturn zhCn;\n\n})));\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/locale/zh-hk.js",
    "content": "//! moment.js locale configuration\n//! locale : Chinese (Hong Kong) [zh-hk]\n//! author : Ben : https://github.com/ben-lin\n//! author : Chris Lam : https://github.com/hehachris\n//! author : Konstantin : https://github.com/skfd\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\n\nvar zhHk = moment.defineLocale('zh-hk', {\n    months : '一月_二月_三月_四月_五月_六月_七月_八月_九月_十月_十一月_十二月'.split('_'),\n    monthsShort : '1月_2月_3月_4月_5月_6月_7月_8月_9月_10月_11月_12月'.split('_'),\n    weekdays : '星期日_星期一_星期二_星期三_星期四_星期五_星期六'.split('_'),\n    weekdaysShort : '週日_週一_週二_週三_週四_週五_週六'.split('_'),\n    weekdaysMin : '日_一_二_三_四_五_六'.split('_'),\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'YYYY年MMMD日',\n        LL : 'YYYY年MMMD日',\n        LLL : 'YYYY年MMMD日 HH:mm',\n        LLLL : 'YYYY年MMMD日dddd HH:mm',\n        l : 'YYYY年MMMD日',\n        ll : 'YYYY年MMMD日',\n        lll : 'YYYY年MMMD日 HH:mm',\n        llll : 'YYYY年MMMD日dddd HH:mm'\n    },\n    meridiemParse: /凌晨|早上|上午|中午|下午|晚上/,\n    meridiemHour : function (hour, meridiem) {\n        if (hour === 12) {\n            hour = 0;\n        }\n        if (meridiem === '凌晨' || meridiem === '早上' || meridiem === '上午') {\n            return hour;\n        } else if (meridiem === '中午') {\n            return hour >= 11 ? hour : hour + 12;\n        } else if (meridiem === '下午' || meridiem === '晚上') {\n            return hour + 12;\n        }\n    },\n    meridiem : function (hour, minute, isLower) {\n        var hm = hour * 100 + minute;\n        if (hm < 600) {\n            return '凌晨';\n        } else if (hm < 900) {\n            return '早上';\n        } else if (hm < 1130) {\n            return '上午';\n        } else if (hm < 1230) {\n            return '中午';\n        } else if (hm < 1800) {\n            return '下午';\n        } else {\n            return '晚上';\n        }\n    },\n    calendar : {\n        sameDay : '[今天]LT',\n        nextDay : '[明天]LT',\n        nextWeek : '[下]ddddLT',\n        lastDay : '[昨天]LT',\n        lastWeek : '[上]ddddLT',\n        sameElse : 'L'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}(日|月|週)/,\n    ordinal : function (number, period) {\n        switch (period) {\n            case 'd' :\n            case 'D' :\n            case 'DDD' :\n                return number + '日';\n            case 'M' :\n                return number + '月';\n            case 'w' :\n            case 'W' :\n                return number + '週';\n            default :\n                return number;\n        }\n    },\n    relativeTime : {\n        future : '%s內',\n        past : '%s前',\n        s : '幾秒',\n        m : '1 分鐘',\n        mm : '%d 分鐘',\n        h : '1 小時',\n        hh : '%d 小時',\n        d : '1 天',\n        dd : '%d 天',\n        M : '1 個月',\n        MM : '%d 個月',\n        y : '1 年',\n        yy : '%d 年'\n    }\n});\n\nreturn zhHk;\n\n})));\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/locale/zh-tw.js",
    "content": "//! moment.js locale configuration\n//! locale : Chinese (Taiwan) [zh-tw]\n//! author : Ben : https://github.com/ben-lin\n//! author : Chris Lam : https://github.com/hehachris\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\n\nvar zhTw = moment.defineLocale('zh-tw', {\n    months : '一月_二月_三月_四月_五月_六月_七月_八月_九月_十月_十一月_十二月'.split('_'),\n    monthsShort : '1月_2月_3月_4月_5月_6月_7月_8月_9月_10月_11月_12月'.split('_'),\n    weekdays : '星期日_星期一_星期二_星期三_星期四_星期五_星期六'.split('_'),\n    weekdaysShort : '週日_週一_週二_週三_週四_週五_週六'.split('_'),\n    weekdaysMin : '日_一_二_三_四_五_六'.split('_'),\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'YYYY年MMMD日',\n        LL : 'YYYY年MMMD日',\n        LLL : 'YYYY年MMMD日 HH:mm',\n        LLLL : 'YYYY年MMMD日dddd HH:mm',\n        l : 'YYYY年MMMD日',\n        ll : 'YYYY年MMMD日',\n        lll : 'YYYY年MMMD日 HH:mm',\n        llll : 'YYYY年MMMD日dddd HH:mm'\n    },\n    meridiemParse: /凌晨|早上|上午|中午|下午|晚上/,\n    meridiemHour : function (hour, meridiem) {\n        if (hour === 12) {\n            hour = 0;\n        }\n        if (meridiem === '凌晨' || meridiem === '早上' || meridiem === '上午') {\n            return hour;\n        } else if (meridiem === '中午') {\n            return hour >= 11 ? hour : hour + 12;\n        } else if (meridiem === '下午' || meridiem === '晚上') {\n            return hour + 12;\n        }\n    },\n    meridiem : function (hour, minute, isLower) {\n        var hm = hour * 100 + minute;\n        if (hm < 600) {\n            return '凌晨';\n        } else if (hm < 900) {\n            return '早上';\n        } else if (hm < 1130) {\n            return '上午';\n        } else if (hm < 1230) {\n            return '中午';\n        } else if (hm < 1800) {\n            return '下午';\n        } else {\n            return '晚上';\n        }\n    },\n    calendar : {\n        sameDay : '[今天]LT',\n        nextDay : '[明天]LT',\n        nextWeek : '[下]ddddLT',\n        lastDay : '[昨天]LT',\n        lastWeek : '[上]ddddLT',\n        sameElse : 'L'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}(日|月|週)/,\n    ordinal : function (number, period) {\n        switch (period) {\n            case 'd' :\n            case 'D' :\n            case 'DDD' :\n                return number + '日';\n            case 'M' :\n                return number + '月';\n            case 'w' :\n            case 'W' :\n                return number + '週';\n            default :\n                return number;\n        }\n    },\n    relativeTime : {\n        future : '%s內',\n        past : '%s前',\n        s : '幾秒',\n        m : '1 分鐘',\n        mm : '%d 分鐘',\n        h : '1 小時',\n        hh : '%d 小時',\n        d : '1 天',\n        dd : '%d 天',\n        M : '1 個月',\n        MM : '%d 個月',\n        y : '1 年',\n        yy : '%d 年'\n    }\n});\n\nreturn zhTw;\n\n})));\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/meteor/README.md",
    "content": "Packaging [Moment](momentjs.org) for [Meteor.js](http://meteor.com).\n\n# Issues\n\nIf you encounter an issue while using this package, please CC @dandv when you file it in this repo.\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/meteor/export.js",
    "content": "// moment.js makes `moment` global on the window (or global) object, while Meteor expects a file-scoped global variable\nmoment = this.moment;\ntry {\n    delete this.moment;\n} catch (e) {\n}\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/meteor/moment.js",
    "content": "//! moment.js\n//! version : 2.18.1\n//! authors : Tim Wood, Iskren Chernev, Moment.js contributors\n//! license : MIT\n//! momentjs.com\n\n;(function (global, factory) {\n    typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :\n    typeof define === 'function' && define.amd ? define(factory) :\n    global.moment = factory()\n}(this, (function () { 'use strict';\n\nvar hookCallback;\n\nfunction hooks () {\n    return hookCallback.apply(null, arguments);\n}\n\n// This is done to register the method called with moment()\n// without creating circular dependencies.\nfunction setHookCallback (callback) {\n    hookCallback = callback;\n}\n\nfunction isArray(input) {\n    return input instanceof Array || Object.prototype.toString.call(input) === '[object Array]';\n}\n\nfunction isObject(input) {\n    // IE8 will treat undefined and null as object if it wasn't for\n    // input != null\n    return input != null && Object.prototype.toString.call(input) === '[object Object]';\n}\n\nfunction isObjectEmpty(obj) {\n    var k;\n    for (k in obj) {\n        // even if its not own property I'd still call it non-empty\n        return false;\n    }\n    return true;\n}\n\nfunction isUndefined(input) {\n    return input === void 0;\n}\n\nfunction isNumber(input) {\n    return typeof input === 'number' || Object.prototype.toString.call(input) === '[object Number]';\n}\n\nfunction isDate(input) {\n    return input instanceof Date || Object.prototype.toString.call(input) === '[object Date]';\n}\n\nfunction map(arr, fn) {\n    var res = [], i;\n    for (i = 0; i < arr.length; ++i) {\n        res.push(fn(arr[i], i));\n    }\n    return res;\n}\n\nfunction hasOwnProp(a, b) {\n    return Object.prototype.hasOwnProperty.call(a, b);\n}\n\nfunction extend(a, b) {\n    for (var i in b) {\n        if (hasOwnProp(b, i)) {\n            a[i] = b[i];\n        }\n    }\n\n    if (hasOwnProp(b, 'toString')) {\n        a.toString = b.toString;\n    }\n\n    if (hasOwnProp(b, 'valueOf')) {\n        a.valueOf = b.valueOf;\n    }\n\n    return a;\n}\n\nfunction createUTC (input, format, locale, strict) {\n    return createLocalOrUTC(input, format, locale, strict, true).utc();\n}\n\nfunction defaultParsingFlags() {\n    // We need to deep clone this object.\n    return {\n        empty           : false,\n        unusedTokens    : [],\n        unusedInput     : [],\n        overflow        : -2,\n        charsLeftOver   : 0,\n        nullInput       : false,\n        invalidMonth    : null,\n        invalidFormat   : false,\n        userInvalidated : false,\n        iso             : false,\n        parsedDateParts : [],\n        meridiem        : null,\n        rfc2822         : false,\n        weekdayMismatch : false\n    };\n}\n\nfunction getParsingFlags(m) {\n    if (m._pf == null) {\n        m._pf = defaultParsingFlags();\n    }\n    return m._pf;\n}\n\nvar some;\nif (Array.prototype.some) {\n    some = Array.prototype.some;\n} else {\n    some = function (fun) {\n        var t = Object(this);\n        var len = t.length >>> 0;\n\n        for (var i = 0; i < len; i++) {\n            if (i in t && fun.call(this, t[i], i, t)) {\n                return true;\n            }\n        }\n\n        return false;\n    };\n}\n\nvar some$1 = some;\n\nfunction isValid(m) {\n    if (m._isValid == null) {\n        var flags = getParsingFlags(m);\n        var parsedParts = some$1.call(flags.parsedDateParts, function (i) {\n            return i != null;\n        });\n        var isNowValid = !isNaN(m._d.getTime()) &&\n            flags.overflow < 0 &&\n            !flags.empty &&\n            !flags.invalidMonth &&\n            !flags.invalidWeekday &&\n            !flags.nullInput &&\n            !flags.invalidFormat &&\n            !flags.userInvalidated &&\n            (!flags.meridiem || (flags.meridiem && parsedParts));\n\n        if (m._strict) {\n            isNowValid = isNowValid &&\n                flags.charsLeftOver === 0 &&\n                flags.unusedTokens.length === 0 &&\n                flags.bigHour === undefined;\n        }\n\n        if (Object.isFrozen == null || !Object.isFrozen(m)) {\n            m._isValid = isNowValid;\n        }\n        else {\n            return isNowValid;\n        }\n    }\n    return m._isValid;\n}\n\nfunction createInvalid (flags) {\n    var m = createUTC(NaN);\n    if (flags != null) {\n        extend(getParsingFlags(m), flags);\n    }\n    else {\n        getParsingFlags(m).userInvalidated = true;\n    }\n\n    return m;\n}\n\n// Plugins that add properties should also add the key here (null value),\n// so we can properly clone ourselves.\nvar momentProperties = hooks.momentProperties = [];\n\nfunction copyConfig(to, from) {\n    var i, prop, val;\n\n    if (!isUndefined(from._isAMomentObject)) {\n        to._isAMomentObject = from._isAMomentObject;\n    }\n    if (!isUndefined(from._i)) {\n        to._i = from._i;\n    }\n    if (!isUndefined(from._f)) {\n        to._f = from._f;\n    }\n    if (!isUndefined(from._l)) {\n        to._l = from._l;\n    }\n    if (!isUndefined(from._strict)) {\n        to._strict = from._strict;\n    }\n    if (!isUndefined(from._tzm)) {\n        to._tzm = from._tzm;\n    }\n    if (!isUndefined(from._isUTC)) {\n        to._isUTC = from._isUTC;\n    }\n    if (!isUndefined(from._offset)) {\n        to._offset = from._offset;\n    }\n    if (!isUndefined(from._pf)) {\n        to._pf = getParsingFlags(from);\n    }\n    if (!isUndefined(from._locale)) {\n        to._locale = from._locale;\n    }\n\n    if (momentProperties.length > 0) {\n        for (i = 0; i < momentProperties.length; i++) {\n            prop = momentProperties[i];\n            val = from[prop];\n            if (!isUndefined(val)) {\n                to[prop] = val;\n            }\n        }\n    }\n\n    return to;\n}\n\nvar updateInProgress = false;\n\n// Moment prototype object\nfunction Moment(config) {\n    copyConfig(this, config);\n    this._d = new Date(config._d != null ? config._d.getTime() : NaN);\n    if (!this.isValid()) {\n        this._d = new Date(NaN);\n    }\n    // Prevent infinite loop in case updateOffset creates new moment\n    // objects.\n    if (updateInProgress === false) {\n        updateInProgress = true;\n        hooks.updateOffset(this);\n        updateInProgress = false;\n    }\n}\n\nfunction isMoment (obj) {\n    return obj instanceof Moment || (obj != null && obj._isAMomentObject != null);\n}\n\nfunction absFloor (number) {\n    if (number < 0) {\n        // -0 -> 0\n        return Math.ceil(number) || 0;\n    } else {\n        return Math.floor(number);\n    }\n}\n\nfunction toInt(argumentForCoercion) {\n    var coercedNumber = +argumentForCoercion,\n        value = 0;\n\n    if (coercedNumber !== 0 && isFinite(coercedNumber)) {\n        value = absFloor(coercedNumber);\n    }\n\n    return value;\n}\n\n// compare two arrays, return the number of differences\nfunction compareArrays(array1, array2, dontConvert) {\n    var len = Math.min(array1.length, array2.length),\n        lengthDiff = Math.abs(array1.length - array2.length),\n        diffs = 0,\n        i;\n    for (i = 0; i < len; i++) {\n        if ((dontConvert && array1[i] !== array2[i]) ||\n            (!dontConvert && toInt(array1[i]) !== toInt(array2[i]))) {\n            diffs++;\n        }\n    }\n    return diffs + lengthDiff;\n}\n\nfunction warn(msg) {\n    if (hooks.suppressDeprecationWarnings === false &&\n            (typeof console !==  'undefined') && console.warn) {\n        console.warn('Deprecation warning: ' + msg);\n    }\n}\n\nfunction deprecate(msg, fn) {\n    var firstTime = true;\n\n    return extend(function () {\n        if (hooks.deprecationHandler != null) {\n            hooks.deprecationHandler(null, msg);\n        }\n        if (firstTime) {\n            var args = [];\n            var arg;\n            for (var i = 0; i < arguments.length; i++) {\n                arg = '';\n                if (typeof arguments[i] === 'object') {\n                    arg += '\\n[' + i + '] ';\n                    for (var key in arguments[0]) {\n                        arg += key + ': ' + arguments[0][key] + ', ';\n                    }\n                    arg = arg.slice(0, -2); // Remove trailing comma and space\n                } else {\n                    arg = arguments[i];\n                }\n                args.push(arg);\n            }\n            warn(msg + '\\nArguments: ' + Array.prototype.slice.call(args).join('') + '\\n' + (new Error()).stack);\n            firstTime = false;\n        }\n        return fn.apply(this, arguments);\n    }, fn);\n}\n\nvar deprecations = {};\n\nfunction deprecateSimple(name, msg) {\n    if (hooks.deprecationHandler != null) {\n        hooks.deprecationHandler(name, msg);\n    }\n    if (!deprecations[name]) {\n        warn(msg);\n        deprecations[name] = true;\n    }\n}\n\nhooks.suppressDeprecationWarnings = false;\nhooks.deprecationHandler = null;\n\nfunction isFunction(input) {\n    return input instanceof Function || Object.prototype.toString.call(input) === '[object Function]';\n}\n\nfunction set (config) {\n    var prop, i;\n    for (i in config) {\n        prop = config[i];\n        if (isFunction(prop)) {\n            this[i] = prop;\n        } else {\n            this['_' + i] = prop;\n        }\n    }\n    this._config = config;\n    // Lenient ordinal parsing accepts just a number in addition to\n    // number + (possibly) stuff coming from _dayOfMonthOrdinalParse.\n    // TODO: Remove \"ordinalParse\" fallback in next major release.\n    this._dayOfMonthOrdinalParseLenient = new RegExp(\n        (this._dayOfMonthOrdinalParse.source || this._ordinalParse.source) +\n            '|' + (/\\d{1,2}/).source);\n}\n\nfunction mergeConfigs(parentConfig, childConfig) {\n    var res = extend({}, parentConfig), prop;\n    for (prop in childConfig) {\n        if (hasOwnProp(childConfig, prop)) {\n            if (isObject(parentConfig[prop]) && isObject(childConfig[prop])) {\n                res[prop] = {};\n                extend(res[prop], parentConfig[prop]);\n                extend(res[prop], childConfig[prop]);\n            } else if (childConfig[prop] != null) {\n                res[prop] = childConfig[prop];\n            } else {\n                delete res[prop];\n            }\n        }\n    }\n    for (prop in parentConfig) {\n        if (hasOwnProp(parentConfig, prop) &&\n                !hasOwnProp(childConfig, prop) &&\n                isObject(parentConfig[prop])) {\n            // make sure changes to properties don't modify parent config\n            res[prop] = extend({}, res[prop]);\n        }\n    }\n    return res;\n}\n\nfunction Locale(config) {\n    if (config != null) {\n        this.set(config);\n    }\n}\n\nvar keys;\n\nif (Object.keys) {\n    keys = Object.keys;\n} else {\n    keys = function (obj) {\n        var i, res = [];\n        for (i in obj) {\n            if (hasOwnProp(obj, i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    };\n}\n\nvar keys$1 = keys;\n\nvar defaultCalendar = {\n    sameDay : '[Today at] LT',\n    nextDay : '[Tomorrow at] LT',\n    nextWeek : 'dddd [at] LT',\n    lastDay : '[Yesterday at] LT',\n    lastWeek : '[Last] dddd [at] LT',\n    sameElse : 'L'\n};\n\nfunction calendar (key, mom, now) {\n    var output = this._calendar[key] || this._calendar['sameElse'];\n    return isFunction(output) ? output.call(mom, now) : output;\n}\n\nvar defaultLongDateFormat = {\n    LTS  : 'h:mm:ss A',\n    LT   : 'h:mm A',\n    L    : 'MM/DD/YYYY',\n    LL   : 'MMMM D, YYYY',\n    LLL  : 'MMMM D, YYYY h:mm A',\n    LLLL : 'dddd, MMMM D, YYYY h:mm A'\n};\n\nfunction longDateFormat (key) {\n    var format = this._longDateFormat[key],\n        formatUpper = this._longDateFormat[key.toUpperCase()];\n\n    if (format || !formatUpper) {\n        return format;\n    }\n\n    this._longDateFormat[key] = formatUpper.replace(/MMMM|MM|DD|dddd/g, function (val) {\n        return val.slice(1);\n    });\n\n    return this._longDateFormat[key];\n}\n\nvar defaultInvalidDate = 'Invalid date';\n\nfunction invalidDate () {\n    return this._invalidDate;\n}\n\nvar defaultOrdinal = '%d';\nvar defaultDayOfMonthOrdinalParse = /\\d{1,2}/;\n\nfunction ordinal (number) {\n    return this._ordinal.replace('%d', number);\n}\n\nvar defaultRelativeTime = {\n    future : 'in %s',\n    past   : '%s ago',\n    s  : 'a few seconds',\n    ss : '%d seconds',\n    m  : 'a minute',\n    mm : '%d minutes',\n    h  : 'an hour',\n    hh : '%d hours',\n    d  : 'a day',\n    dd : '%d days',\n    M  : 'a month',\n    MM : '%d months',\n    y  : 'a year',\n    yy : '%d years'\n};\n\nfunction relativeTime (number, withoutSuffix, string, isFuture) {\n    var output = this._relativeTime[string];\n    return (isFunction(output)) ?\n        output(number, withoutSuffix, string, isFuture) :\n        output.replace(/%d/i, number);\n}\n\nfunction pastFuture (diff, output) {\n    var format = this._relativeTime[diff > 0 ? 'future' : 'past'];\n    return isFunction(format) ? format(output) : format.replace(/%s/i, output);\n}\n\nvar aliases = {};\n\nfunction addUnitAlias (unit, shorthand) {\n    var lowerCase = unit.toLowerCase();\n    aliases[lowerCase] = aliases[lowerCase + 's'] = aliases[shorthand] = unit;\n}\n\nfunction normalizeUnits(units) {\n    return typeof units === 'string' ? aliases[units] || aliases[units.toLowerCase()] : undefined;\n}\n\nfunction normalizeObjectUnits(inputObject) {\n    var normalizedInput = {},\n        normalizedProp,\n        prop;\n\n    for (prop in inputObject) {\n        if (hasOwnProp(inputObject, prop)) {\n            normalizedProp = normalizeUnits(prop);\n            if (normalizedProp) {\n                normalizedInput[normalizedProp] = inputObject[prop];\n            }\n        }\n    }\n\n    return normalizedInput;\n}\n\nvar priorities = {};\n\nfunction addUnitPriority(unit, priority) {\n    priorities[unit] = priority;\n}\n\nfunction getPrioritizedUnits(unitsObj) {\n    var units = [];\n    for (var u in unitsObj) {\n        units.push({unit: u, priority: priorities[u]});\n    }\n    units.sort(function (a, b) {\n        return a.priority - b.priority;\n    });\n    return units;\n}\n\nfunction makeGetSet (unit, keepTime) {\n    return function (value) {\n        if (value != null) {\n            set$1(this, unit, value);\n            hooks.updateOffset(this, keepTime);\n            return this;\n        } else {\n            return get(this, unit);\n        }\n    };\n}\n\nfunction get (mom, unit) {\n    return mom.isValid() ?\n        mom._d['get' + (mom._isUTC ? 'UTC' : '') + unit]() : NaN;\n}\n\nfunction set$1 (mom, unit, value) {\n    if (mom.isValid()) {\n        mom._d['set' + (mom._isUTC ? 'UTC' : '') + unit](value);\n    }\n}\n\n// MOMENTS\n\nfunction stringGet (units) {\n    units = normalizeUnits(units);\n    if (isFunction(this[units])) {\n        return this[units]();\n    }\n    return this;\n}\n\n\nfunction stringSet (units, value) {\n    if (typeof units === 'object') {\n        units = normalizeObjectUnits(units);\n        var prioritized = getPrioritizedUnits(units);\n        for (var i = 0; i < prioritized.length; i++) {\n            this[prioritized[i].unit](units[prioritized[i].unit]);\n        }\n    } else {\n        units = normalizeUnits(units);\n        if (isFunction(this[units])) {\n            return this[units](value);\n        }\n    }\n    return this;\n}\n\nfunction zeroFill(number, targetLength, forceSign) {\n    var absNumber = '' + Math.abs(number),\n        zerosToFill = targetLength - absNumber.length,\n        sign = number >= 0;\n    return (sign ? (forceSign ? '+' : '') : '-') +\n        Math.pow(10, Math.max(0, zerosToFill)).toString().substr(1) + absNumber;\n}\n\nvar formattingTokens = /(\\[[^\\[]*\\])|(\\\\)?([Hh]mm(ss)?|Mo|MM?M?M?|Do|DDDo|DD?D?D?|ddd?d?|do?|w[o|w]?|W[o|W]?|Qo?|YYYYYY|YYYYY|YYYY|YY|gg(ggg?)?|GG(GGG?)?|e|E|a|A|hh?|HH?|kk?|mm?|ss?|S{1,9}|x|X|zz?|ZZ?|.)/g;\n\nvar localFormattingTokens = /(\\[[^\\[]*\\])|(\\\\)?(LTS|LT|LL?L?L?|l{1,4})/g;\n\nvar formatFunctions = {};\n\nvar formatTokenFunctions = {};\n\n// token:    'M'\n// padded:   ['MM', 2]\n// ordinal:  'Mo'\n// callback: function () { this.month() + 1 }\nfunction addFormatToken (token, padded, ordinal, callback) {\n    var func = callback;\n    if (typeof callback === 'string') {\n        func = function () {\n            return this[callback]();\n        };\n    }\n    if (token) {\n        formatTokenFunctions[token] = func;\n    }\n    if (padded) {\n        formatTokenFunctions[padded[0]] = function () {\n            return zeroFill(func.apply(this, arguments), padded[1], padded[2]);\n        };\n    }\n    if (ordinal) {\n        formatTokenFunctions[ordinal] = function () {\n            return this.localeData().ordinal(func.apply(this, arguments), token);\n        };\n    }\n}\n\nfunction removeFormattingTokens(input) {\n    if (input.match(/\\[[\\s\\S]/)) {\n        return input.replace(/^\\[|\\]$/g, '');\n    }\n    return input.replace(/\\\\/g, '');\n}\n\nfunction makeFormatFunction(format) {\n    var array = format.match(formattingTokens), i, length;\n\n    for (i = 0, length = array.length; i < length; i++) {\n        if (formatTokenFunctions[array[i]]) {\n            array[i] = formatTokenFunctions[array[i]];\n        } else {\n            array[i] = removeFormattingTokens(array[i]);\n        }\n    }\n\n    return function (mom) {\n        var output = '', i;\n        for (i = 0; i < length; i++) {\n            output += isFunction(array[i]) ? array[i].call(mom, format) : array[i];\n        }\n        return output;\n    };\n}\n\n// format date using native date object\nfunction formatMoment(m, format) {\n    if (!m.isValid()) {\n        return m.localeData().invalidDate();\n    }\n\n    format = expandFormat(format, m.localeData());\n    formatFunctions[format] = formatFunctions[format] || makeFormatFunction(format);\n\n    return formatFunctions[format](m);\n}\n\nfunction expandFormat(format, locale) {\n    var i = 5;\n\n    function replaceLongDateFormatTokens(input) {\n        return locale.longDateFormat(input) || input;\n    }\n\n    localFormattingTokens.lastIndex = 0;\n    while (i >= 0 && localFormattingTokens.test(format)) {\n        format = format.replace(localFormattingTokens, replaceLongDateFormatTokens);\n        localFormattingTokens.lastIndex = 0;\n        i -= 1;\n    }\n\n    return format;\n}\n\nvar match1         = /\\d/;            //       0 - 9\nvar match2         = /\\d\\d/;          //      00 - 99\nvar match3         = /\\d{3}/;         //     000 - 999\nvar match4         = /\\d{4}/;         //    0000 - 9999\nvar match6         = /[+-]?\\d{6}/;    // -999999 - 999999\nvar match1to2      = /\\d\\d?/;         //       0 - 99\nvar match3to4      = /\\d\\d\\d\\d?/;     //     999 - 9999\nvar match5to6      = /\\d\\d\\d\\d\\d\\d?/; //   99999 - 999999\nvar match1to3      = /\\d{1,3}/;       //       0 - 999\nvar match1to4      = /\\d{1,4}/;       //       0 - 9999\nvar match1to6      = /[+-]?\\d{1,6}/;  // -999999 - 999999\n\nvar matchUnsigned  = /\\d+/;           //       0 - inf\nvar matchSigned    = /[+-]?\\d+/;      //    -inf - inf\n\nvar matchOffset    = /Z|[+-]\\d\\d:?\\d\\d/gi; // +00:00 -00:00 +0000 -0000 or Z\nvar matchShortOffset = /Z|[+-]\\d\\d(?::?\\d\\d)?/gi; // +00 -00 +00:00 -00:00 +0000 -0000 or Z\n\nvar matchTimestamp = /[+-]?\\d+(\\.\\d{1,3})?/; // 123456789 123456789.123\n\n// any word (or two) characters or numbers including two/three word month in arabic.\n// includes scottish gaelic two word and hyphenated months\nvar matchWord = /[0-9]*['a-z\\u00A0-\\u05FF\\u0700-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF]+|[\\u0600-\\u06FF\\/]+(\\s*?[\\u0600-\\u06FF]+){1,2}/i;\n\n\nvar regexes = {};\n\nfunction addRegexToken (token, regex, strictRegex) {\n    regexes[token] = isFunction(regex) ? regex : function (isStrict, localeData) {\n        return (isStrict && strictRegex) ? strictRegex : regex;\n    };\n}\n\nfunction getParseRegexForToken (token, config) {\n    if (!hasOwnProp(regexes, token)) {\n        return new RegExp(unescapeFormat(token));\n    }\n\n    return regexes[token](config._strict, config._locale);\n}\n\n// Code from http://stackoverflow.com/questions/3561493/is-there-a-regexp-escape-function-in-javascript\nfunction unescapeFormat(s) {\n    return regexEscape(s.replace('\\\\', '').replace(/\\\\(\\[)|\\\\(\\])|\\[([^\\]\\[]*)\\]|\\\\(.)/g, function (matched, p1, p2, p3, p4) {\n        return p1 || p2 || p3 || p4;\n    }));\n}\n\nfunction regexEscape(s) {\n    return s.replace(/[-\\/\\\\^$*+?.()|[\\]{}]/g, '\\\\$&');\n}\n\nvar tokens = {};\n\nfunction addParseToken (token, callback) {\n    var i, func = callback;\n    if (typeof token === 'string') {\n        token = [token];\n    }\n    if (isNumber(callback)) {\n        func = function (input, array) {\n            array[callback] = toInt(input);\n        };\n    }\n    for (i = 0; i < token.length; i++) {\n        tokens[token[i]] = func;\n    }\n}\n\nfunction addWeekParseToken (token, callback) {\n    addParseToken(token, function (input, array, config, token) {\n        config._w = config._w || {};\n        callback(input, config._w, config, token);\n    });\n}\n\nfunction addTimeToArrayFromToken(token, input, config) {\n    if (input != null && hasOwnProp(tokens, token)) {\n        tokens[token](input, config._a, config, token);\n    }\n}\n\nvar YEAR = 0;\nvar MONTH = 1;\nvar DATE = 2;\nvar HOUR = 3;\nvar MINUTE = 4;\nvar SECOND = 5;\nvar MILLISECOND = 6;\nvar WEEK = 7;\nvar WEEKDAY = 8;\n\nvar indexOf;\n\nif (Array.prototype.indexOf) {\n    indexOf = Array.prototype.indexOf;\n} else {\n    indexOf = function (o) {\n        // I know\n        var i;\n        for (i = 0; i < this.length; ++i) {\n            if (this[i] === o) {\n                return i;\n            }\n        }\n        return -1;\n    };\n}\n\nvar indexOf$1 = indexOf;\n\nfunction daysInMonth(year, month) {\n    return new Date(Date.UTC(year, month + 1, 0)).getUTCDate();\n}\n\n// FORMATTING\n\naddFormatToken('M', ['MM', 2], 'Mo', function () {\n    return this.month() + 1;\n});\n\naddFormatToken('MMM', 0, 0, function (format) {\n    return this.localeData().monthsShort(this, format);\n});\n\naddFormatToken('MMMM', 0, 0, function (format) {\n    return this.localeData().months(this, format);\n});\n\n// ALIASES\n\naddUnitAlias('month', 'M');\n\n// PRIORITY\n\naddUnitPriority('month', 8);\n\n// PARSING\n\naddRegexToken('M',    match1to2);\naddRegexToken('MM',   match1to2, match2);\naddRegexToken('MMM',  function (isStrict, locale) {\n    return locale.monthsShortRegex(isStrict);\n});\naddRegexToken('MMMM', function (isStrict, locale) {\n    return locale.monthsRegex(isStrict);\n});\n\naddParseToken(['M', 'MM'], function (input, array) {\n    array[MONTH] = toInt(input) - 1;\n});\n\naddParseToken(['MMM', 'MMMM'], function (input, array, config, token) {\n    var month = config._locale.monthsParse(input, token, config._strict);\n    // if we didn't find a month name, mark the date as invalid.\n    if (month != null) {\n        array[MONTH] = month;\n    } else {\n        getParsingFlags(config).invalidMonth = input;\n    }\n});\n\n// LOCALES\n\nvar MONTHS_IN_FORMAT = /D[oD]?(\\[[^\\[\\]]*\\]|\\s)+MMMM?/;\nvar defaultLocaleMonths = 'January_February_March_April_May_June_July_August_September_October_November_December'.split('_');\nfunction localeMonths (m, format) {\n    if (!m) {\n        return isArray(this._months) ? this._months :\n            this._months['standalone'];\n    }\n    return isArray(this._months) ? this._months[m.month()] :\n        this._months[(this._months.isFormat || MONTHS_IN_FORMAT).test(format) ? 'format' : 'standalone'][m.month()];\n}\n\nvar defaultLocaleMonthsShort = 'Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec'.split('_');\nfunction localeMonthsShort (m, format) {\n    if (!m) {\n        return isArray(this._monthsShort) ? this._monthsShort :\n            this._monthsShort['standalone'];\n    }\n    return isArray(this._monthsShort) ? this._monthsShort[m.month()] :\n        this._monthsShort[MONTHS_IN_FORMAT.test(format) ? 'format' : 'standalone'][m.month()];\n}\n\nfunction handleStrictParse(monthName, format, strict) {\n    var i, ii, mom, llc = monthName.toLocaleLowerCase();\n    if (!this._monthsParse) {\n        // this is not used\n        this._monthsParse = [];\n        this._longMonthsParse = [];\n        this._shortMonthsParse = [];\n        for (i = 0; i < 12; ++i) {\n            mom = createUTC([2000, i]);\n            this._shortMonthsParse[i] = this.monthsShort(mom, '').toLocaleLowerCase();\n            this._longMonthsParse[i] = this.months(mom, '').toLocaleLowerCase();\n        }\n    }\n\n    if (strict) {\n        if (format === 'MMM') {\n            ii = indexOf$1.call(this._shortMonthsParse, llc);\n            return ii !== -1 ? ii : null;\n        } else {\n            ii = indexOf$1.call(this._longMonthsParse, llc);\n            return ii !== -1 ? ii : null;\n        }\n    } else {\n        if (format === 'MMM') {\n            ii = indexOf$1.call(this._shortMonthsParse, llc);\n            if (ii !== -1) {\n                return ii;\n            }\n            ii = indexOf$1.call(this._longMonthsParse, llc);\n            return ii !== -1 ? ii : null;\n        } else {\n            ii = indexOf$1.call(this._longMonthsParse, llc);\n            if (ii !== -1) {\n                return ii;\n            }\n            ii = indexOf$1.call(this._shortMonthsParse, llc);\n            return ii !== -1 ? ii : null;\n        }\n    }\n}\n\nfunction localeMonthsParse (monthName, format, strict) {\n    var i, mom, regex;\n\n    if (this._monthsParseExact) {\n        return handleStrictParse.call(this, monthName, format, strict);\n    }\n\n    if (!this._monthsParse) {\n        this._monthsParse = [];\n        this._longMonthsParse = [];\n        this._shortMonthsParse = [];\n    }\n\n    // TODO: add sorting\n    // Sorting makes sure if one month (or abbr) is a prefix of another\n    // see sorting in computeMonthsParse\n    for (i = 0; i < 12; i++) {\n        // make the regex if we don't have it already\n        mom = createUTC([2000, i]);\n        if (strict && !this._longMonthsParse[i]) {\n            this._longMonthsParse[i] = new RegExp('^' + this.months(mom, '').replace('.', '') + '$', 'i');\n            this._shortMonthsParse[i] = new RegExp('^' + this.monthsShort(mom, '').replace('.', '') + '$', 'i');\n        }\n        if (!strict && !this._monthsParse[i]) {\n            regex = '^' + this.months(mom, '') + '|^' + this.monthsShort(mom, '');\n            this._monthsParse[i] = new RegExp(regex.replace('.', ''), 'i');\n        }\n        // test the regex\n        if (strict && format === 'MMMM' && this._longMonthsParse[i].test(monthName)) {\n            return i;\n        } else if (strict && format === 'MMM' && this._shortMonthsParse[i].test(monthName)) {\n            return i;\n        } else if (!strict && this._monthsParse[i].test(monthName)) {\n            return i;\n        }\n    }\n}\n\n// MOMENTS\n\nfunction setMonth (mom, value) {\n    var dayOfMonth;\n\n    if (!mom.isValid()) {\n        // No op\n        return mom;\n    }\n\n    if (typeof value === 'string') {\n        if (/^\\d+$/.test(value)) {\n            value = toInt(value);\n        } else {\n            value = mom.localeData().monthsParse(value);\n            // TODO: Another silent failure?\n            if (!isNumber(value)) {\n                return mom;\n            }\n        }\n    }\n\n    dayOfMonth = Math.min(mom.date(), daysInMonth(mom.year(), value));\n    mom._d['set' + (mom._isUTC ? 'UTC' : '') + 'Month'](value, dayOfMonth);\n    return mom;\n}\n\nfunction getSetMonth (value) {\n    if (value != null) {\n        setMonth(this, value);\n        hooks.updateOffset(this, true);\n        return this;\n    } else {\n        return get(this, 'Month');\n    }\n}\n\nfunction getDaysInMonth () {\n    return daysInMonth(this.year(), this.month());\n}\n\nvar defaultMonthsShortRegex = matchWord;\nfunction monthsShortRegex (isStrict) {\n    if (this._monthsParseExact) {\n        if (!hasOwnProp(this, '_monthsRegex')) {\n            computeMonthsParse.call(this);\n        }\n        if (isStrict) {\n            return this._monthsShortStrictRegex;\n        } else {\n            return this._monthsShortRegex;\n        }\n    } else {\n        if (!hasOwnProp(this, '_monthsShortRegex')) {\n            this._monthsShortRegex = defaultMonthsShortRegex;\n        }\n        return this._monthsShortStrictRegex && isStrict ?\n            this._monthsShortStrictRegex : this._monthsShortRegex;\n    }\n}\n\nvar defaultMonthsRegex = matchWord;\nfunction monthsRegex (isStrict) {\n    if (this._monthsParseExact) {\n        if (!hasOwnProp(this, '_monthsRegex')) {\n            computeMonthsParse.call(this);\n        }\n        if (isStrict) {\n            return this._monthsStrictRegex;\n        } else {\n            return this._monthsRegex;\n        }\n    } else {\n        if (!hasOwnProp(this, '_monthsRegex')) {\n            this._monthsRegex = defaultMonthsRegex;\n        }\n        return this._monthsStrictRegex && isStrict ?\n            this._monthsStrictRegex : this._monthsRegex;\n    }\n}\n\nfunction computeMonthsParse () {\n    function cmpLenRev(a, b) {\n        return b.length - a.length;\n    }\n\n    var shortPieces = [], longPieces = [], mixedPieces = [],\n        i, mom;\n    for (i = 0; i < 12; i++) {\n        // make the regex if we don't have it already\n        mom = createUTC([2000, i]);\n        shortPieces.push(this.monthsShort(mom, ''));\n        longPieces.push(this.months(mom, ''));\n        mixedPieces.push(this.months(mom, ''));\n        mixedPieces.push(this.monthsShort(mom, ''));\n    }\n    // Sorting makes sure if one month (or abbr) is a prefix of another it\n    // will match the longer piece.\n    shortPieces.sort(cmpLenRev);\n    longPieces.sort(cmpLenRev);\n    mixedPieces.sort(cmpLenRev);\n    for (i = 0; i < 12; i++) {\n        shortPieces[i] = regexEscape(shortPieces[i]);\n        longPieces[i] = regexEscape(longPieces[i]);\n    }\n    for (i = 0; i < 24; i++) {\n        mixedPieces[i] = regexEscape(mixedPieces[i]);\n    }\n\n    this._monthsRegex = new RegExp('^(' + mixedPieces.join('|') + ')', 'i');\n    this._monthsShortRegex = this._monthsRegex;\n    this._monthsStrictRegex = new RegExp('^(' + longPieces.join('|') + ')', 'i');\n    this._monthsShortStrictRegex = new RegExp('^(' + shortPieces.join('|') + ')', 'i');\n}\n\n// FORMATTING\n\naddFormatToken('Y', 0, 0, function () {\n    var y = this.year();\n    return y <= 9999 ? '' + y : '+' + y;\n});\n\naddFormatToken(0, ['YY', 2], 0, function () {\n    return this.year() % 100;\n});\n\naddFormatToken(0, ['YYYY',   4],       0, 'year');\naddFormatToken(0, ['YYYYY',  5],       0, 'year');\naddFormatToken(0, ['YYYYYY', 6, true], 0, 'year');\n\n// ALIASES\n\naddUnitAlias('year', 'y');\n\n// PRIORITIES\n\naddUnitPriority('year', 1);\n\n// PARSING\n\naddRegexToken('Y',      matchSigned);\naddRegexToken('YY',     match1to2, match2);\naddRegexToken('YYYY',   match1to4, match4);\naddRegexToken('YYYYY',  match1to6, match6);\naddRegexToken('YYYYYY', match1to6, match6);\n\naddParseToken(['YYYYY', 'YYYYYY'], YEAR);\naddParseToken('YYYY', function (input, array) {\n    array[YEAR] = input.length === 2 ? hooks.parseTwoDigitYear(input) : toInt(input);\n});\naddParseToken('YY', function (input, array) {\n    array[YEAR] = hooks.parseTwoDigitYear(input);\n});\naddParseToken('Y', function (input, array) {\n    array[YEAR] = parseInt(input, 10);\n});\n\n// HELPERS\n\nfunction daysInYear(year) {\n    return isLeapYear(year) ? 366 : 365;\n}\n\nfunction isLeapYear(year) {\n    return (year % 4 === 0 && year % 100 !== 0) || year % 400 === 0;\n}\n\n// HOOKS\n\nhooks.parseTwoDigitYear = function (input) {\n    return toInt(input) + (toInt(input) > 68 ? 1900 : 2000);\n};\n\n// MOMENTS\n\nvar getSetYear = makeGetSet('FullYear', true);\n\nfunction getIsLeapYear () {\n    return isLeapYear(this.year());\n}\n\nfunction createDate (y, m, d, h, M, s, ms) {\n    // can't just apply() to create a date:\n    // https://stackoverflow.com/q/181348\n    var date = new Date(y, m, d, h, M, s, ms);\n\n    // the date constructor remaps years 0-99 to 1900-1999\n    if (y < 100 && y >= 0 && isFinite(date.getFullYear())) {\n        date.setFullYear(y);\n    }\n    return date;\n}\n\nfunction createUTCDate (y) {\n    var date = new Date(Date.UTC.apply(null, arguments));\n\n    // the Date.UTC function remaps years 0-99 to 1900-1999\n    if (y < 100 && y >= 0 && isFinite(date.getUTCFullYear())) {\n        date.setUTCFullYear(y);\n    }\n    return date;\n}\n\n// start-of-first-week - start-of-year\nfunction firstWeekOffset(year, dow, doy) {\n    var // first-week day -- which january is always in the first week (4 for iso, 1 for other)\n        fwd = 7 + dow - doy,\n        // first-week day local weekday -- which local weekday is fwd\n        fwdlw = (7 + createUTCDate(year, 0, fwd).getUTCDay() - dow) % 7;\n\n    return -fwdlw + fwd - 1;\n}\n\n// https://en.wikipedia.org/wiki/ISO_week_date#Calculating_a_date_given_the_year.2C_week_number_and_weekday\nfunction dayOfYearFromWeeks(year, week, weekday, dow, doy) {\n    var localWeekday = (7 + weekday - dow) % 7,\n        weekOffset = firstWeekOffset(year, dow, doy),\n        dayOfYear = 1 + 7 * (week - 1) + localWeekday + weekOffset,\n        resYear, resDayOfYear;\n\n    if (dayOfYear <= 0) {\n        resYear = year - 1;\n        resDayOfYear = daysInYear(resYear) + dayOfYear;\n    } else if (dayOfYear > daysInYear(year)) {\n        resYear = year + 1;\n        resDayOfYear = dayOfYear - daysInYear(year);\n    } else {\n        resYear = year;\n        resDayOfYear = dayOfYear;\n    }\n\n    return {\n        year: resYear,\n        dayOfYear: resDayOfYear\n    };\n}\n\nfunction weekOfYear(mom, dow, doy) {\n    var weekOffset = firstWeekOffset(mom.year(), dow, doy),\n        week = Math.floor((mom.dayOfYear() - weekOffset - 1) / 7) + 1,\n        resWeek, resYear;\n\n    if (week < 1) {\n        resYear = mom.year() - 1;\n        resWeek = week + weeksInYear(resYear, dow, doy);\n    } else if (week > weeksInYear(mom.year(), dow, doy)) {\n        resWeek = week - weeksInYear(mom.year(), dow, doy);\n        resYear = mom.year() + 1;\n    } else {\n        resYear = mom.year();\n        resWeek = week;\n    }\n\n    return {\n        week: resWeek,\n        year: resYear\n    };\n}\n\nfunction weeksInYear(year, dow, doy) {\n    var weekOffset = firstWeekOffset(year, dow, doy),\n        weekOffsetNext = firstWeekOffset(year + 1, dow, doy);\n    return (daysInYear(year) - weekOffset + weekOffsetNext) / 7;\n}\n\n// FORMATTING\n\naddFormatToken('w', ['ww', 2], 'wo', 'week');\naddFormatToken('W', ['WW', 2], 'Wo', 'isoWeek');\n\n// ALIASES\n\naddUnitAlias('week', 'w');\naddUnitAlias('isoWeek', 'W');\n\n// PRIORITIES\n\naddUnitPriority('week', 5);\naddUnitPriority('isoWeek', 5);\n\n// PARSING\n\naddRegexToken('w',  match1to2);\naddRegexToken('ww', match1to2, match2);\naddRegexToken('W',  match1to2);\naddRegexToken('WW', match1to2, match2);\n\naddWeekParseToken(['w', 'ww', 'W', 'WW'], function (input, week, config, token) {\n    week[token.substr(0, 1)] = toInt(input);\n});\n\n// HELPERS\n\n// LOCALES\n\nfunction localeWeek (mom) {\n    return weekOfYear(mom, this._week.dow, this._week.doy).week;\n}\n\nvar defaultLocaleWeek = {\n    dow : 0, // Sunday is the first day of the week.\n    doy : 6  // The week that contains Jan 1st is the first week of the year.\n};\n\nfunction localeFirstDayOfWeek () {\n    return this._week.dow;\n}\n\nfunction localeFirstDayOfYear () {\n    return this._week.doy;\n}\n\n// MOMENTS\n\nfunction getSetWeek (input) {\n    var week = this.localeData().week(this);\n    return input == null ? week : this.add((input - week) * 7, 'd');\n}\n\nfunction getSetISOWeek (input) {\n    var week = weekOfYear(this, 1, 4).week;\n    return input == null ? week : this.add((input - week) * 7, 'd');\n}\n\n// FORMATTING\n\naddFormatToken('d', 0, 'do', 'day');\n\naddFormatToken('dd', 0, 0, function (format) {\n    return this.localeData().weekdaysMin(this, format);\n});\n\naddFormatToken('ddd', 0, 0, function (format) {\n    return this.localeData().weekdaysShort(this, format);\n});\n\naddFormatToken('dddd', 0, 0, function (format) {\n    return this.localeData().weekdays(this, format);\n});\n\naddFormatToken('e', 0, 0, 'weekday');\naddFormatToken('E', 0, 0, 'isoWeekday');\n\n// ALIASES\n\naddUnitAlias('day', 'd');\naddUnitAlias('weekday', 'e');\naddUnitAlias('isoWeekday', 'E');\n\n// PRIORITY\naddUnitPriority('day', 11);\naddUnitPriority('weekday', 11);\naddUnitPriority('isoWeekday', 11);\n\n// PARSING\n\naddRegexToken('d',    match1to2);\naddRegexToken('e',    match1to2);\naddRegexToken('E',    match1to2);\naddRegexToken('dd',   function (isStrict, locale) {\n    return locale.weekdaysMinRegex(isStrict);\n});\naddRegexToken('ddd',   function (isStrict, locale) {\n    return locale.weekdaysShortRegex(isStrict);\n});\naddRegexToken('dddd',   function (isStrict, locale) {\n    return locale.weekdaysRegex(isStrict);\n});\n\naddWeekParseToken(['dd', 'ddd', 'dddd'], function (input, week, config, token) {\n    var weekday = config._locale.weekdaysParse(input, token, config._strict);\n    // if we didn't get a weekday name, mark the date as invalid\n    if (weekday != null) {\n        week.d = weekday;\n    } else {\n        getParsingFlags(config).invalidWeekday = input;\n    }\n});\n\naddWeekParseToken(['d', 'e', 'E'], function (input, week, config, token) {\n    week[token] = toInt(input);\n});\n\n// HELPERS\n\nfunction parseWeekday(input, locale) {\n    if (typeof input !== 'string') {\n        return input;\n    }\n\n    if (!isNaN(input)) {\n        return parseInt(input, 10);\n    }\n\n    input = locale.weekdaysParse(input);\n    if (typeof input === 'number') {\n        return input;\n    }\n\n    return null;\n}\n\nfunction parseIsoWeekday(input, locale) {\n    if (typeof input === 'string') {\n        return locale.weekdaysParse(input) % 7 || 7;\n    }\n    return isNaN(input) ? null : input;\n}\n\n// LOCALES\n\nvar defaultLocaleWeekdays = 'Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday'.split('_');\nfunction localeWeekdays (m, format) {\n    if (!m) {\n        return isArray(this._weekdays) ? this._weekdays :\n            this._weekdays['standalone'];\n    }\n    return isArray(this._weekdays) ? this._weekdays[m.day()] :\n        this._weekdays[this._weekdays.isFormat.test(format) ? 'format' : 'standalone'][m.day()];\n}\n\nvar defaultLocaleWeekdaysShort = 'Sun_Mon_Tue_Wed_Thu_Fri_Sat'.split('_');\nfunction localeWeekdaysShort (m) {\n    return (m) ? this._weekdaysShort[m.day()] : this._weekdaysShort;\n}\n\nvar defaultLocaleWeekdaysMin = 'Su_Mo_Tu_We_Th_Fr_Sa'.split('_');\nfunction localeWeekdaysMin (m) {\n    return (m) ? this._weekdaysMin[m.day()] : this._weekdaysMin;\n}\n\nfunction handleStrictParse$1(weekdayName, format, strict) {\n    var i, ii, mom, llc = weekdayName.toLocaleLowerCase();\n    if (!this._weekdaysParse) {\n        this._weekdaysParse = [];\n        this._shortWeekdaysParse = [];\n        this._minWeekdaysParse = [];\n\n        for (i = 0; i < 7; ++i) {\n            mom = createUTC([2000, 1]).day(i);\n            this._minWeekdaysParse[i] = this.weekdaysMin(mom, '').toLocaleLowerCase();\n            this._shortWeekdaysParse[i] = this.weekdaysShort(mom, '').toLocaleLowerCase();\n            this._weekdaysParse[i] = this.weekdays(mom, '').toLocaleLowerCase();\n        }\n    }\n\n    if (strict) {\n        if (format === 'dddd') {\n            ii = indexOf$1.call(this._weekdaysParse, llc);\n            return ii !== -1 ? ii : null;\n        } else if (format === 'ddd') {\n            ii = indexOf$1.call(this._shortWeekdaysParse, llc);\n            return ii !== -1 ? ii : null;\n        } else {\n            ii = indexOf$1.call(this._minWeekdaysParse, llc);\n            return ii !== -1 ? ii : null;\n        }\n    } else {\n        if (format === 'dddd') {\n            ii = indexOf$1.call(this._weekdaysParse, llc);\n            if (ii !== -1) {\n                return ii;\n            }\n            ii = indexOf$1.call(this._shortWeekdaysParse, llc);\n            if (ii !== -1) {\n                return ii;\n            }\n            ii = indexOf$1.call(this._minWeekdaysParse, llc);\n            return ii !== -1 ? ii : null;\n        } else if (format === 'ddd') {\n            ii = indexOf$1.call(this._shortWeekdaysParse, llc);\n            if (ii !== -1) {\n                return ii;\n            }\n            ii = indexOf$1.call(this._weekdaysParse, llc);\n            if (ii !== -1) {\n                return ii;\n            }\n            ii = indexOf$1.call(this._minWeekdaysParse, llc);\n            return ii !== -1 ? ii : null;\n        } else {\n            ii = indexOf$1.call(this._minWeekdaysParse, llc);\n            if (ii !== -1) {\n                return ii;\n            }\n            ii = indexOf$1.call(this._weekdaysParse, llc);\n            if (ii !== -1) {\n                return ii;\n            }\n            ii = indexOf$1.call(this._shortWeekdaysParse, llc);\n            return ii !== -1 ? ii : null;\n        }\n    }\n}\n\nfunction localeWeekdaysParse (weekdayName, format, strict) {\n    var i, mom, regex;\n\n    if (this._weekdaysParseExact) {\n        return handleStrictParse$1.call(this, weekdayName, format, strict);\n    }\n\n    if (!this._weekdaysParse) {\n        this._weekdaysParse = [];\n        this._minWeekdaysParse = [];\n        this._shortWeekdaysParse = [];\n        this._fullWeekdaysParse = [];\n    }\n\n    for (i = 0; i < 7; i++) {\n        // make the regex if we don't have it already\n\n        mom = createUTC([2000, 1]).day(i);\n        if (strict && !this._fullWeekdaysParse[i]) {\n            this._fullWeekdaysParse[i] = new RegExp('^' + this.weekdays(mom, '').replace('.', '\\.?') + '$', 'i');\n            this._shortWeekdaysParse[i] = new RegExp('^' + this.weekdaysShort(mom, '').replace('.', '\\.?') + '$', 'i');\n            this._minWeekdaysParse[i] = new RegExp('^' + this.weekdaysMin(mom, '').replace('.', '\\.?') + '$', 'i');\n        }\n        if (!this._weekdaysParse[i]) {\n            regex = '^' + this.weekdays(mom, '') + '|^' + this.weekdaysShort(mom, '') + '|^' + this.weekdaysMin(mom, '');\n            this._weekdaysParse[i] = new RegExp(regex.replace('.', ''), 'i');\n        }\n        // test the regex\n        if (strict && format === 'dddd' && this._fullWeekdaysParse[i].test(weekdayName)) {\n            return i;\n        } else if (strict && format === 'ddd' && this._shortWeekdaysParse[i].test(weekdayName)) {\n            return i;\n        } else if (strict && format === 'dd' && this._minWeekdaysParse[i].test(weekdayName)) {\n            return i;\n        } else if (!strict && this._weekdaysParse[i].test(weekdayName)) {\n            return i;\n        }\n    }\n}\n\n// MOMENTS\n\nfunction getSetDayOfWeek (input) {\n    if (!this.isValid()) {\n        return input != null ? this : NaN;\n    }\n    var day = this._isUTC ? this._d.getUTCDay() : this._d.getDay();\n    if (input != null) {\n        input = parseWeekday(input, this.localeData());\n        return this.add(input - day, 'd');\n    } else {\n        return day;\n    }\n}\n\nfunction getSetLocaleDayOfWeek (input) {\n    if (!this.isValid()) {\n        return input != null ? this : NaN;\n    }\n    var weekday = (this.day() + 7 - this.localeData()._week.dow) % 7;\n    return input == null ? weekday : this.add(input - weekday, 'd');\n}\n\nfunction getSetISODayOfWeek (input) {\n    if (!this.isValid()) {\n        return input != null ? this : NaN;\n    }\n\n    // behaves the same as moment#day except\n    // as a getter, returns 7 instead of 0 (1-7 range instead of 0-6)\n    // as a setter, sunday should belong to the previous week.\n\n    if (input != null) {\n        var weekday = parseIsoWeekday(input, this.localeData());\n        return this.day(this.day() % 7 ? weekday : weekday - 7);\n    } else {\n        return this.day() || 7;\n    }\n}\n\nvar defaultWeekdaysRegex = matchWord;\nfunction weekdaysRegex (isStrict) {\n    if (this._weekdaysParseExact) {\n        if (!hasOwnProp(this, '_weekdaysRegex')) {\n            computeWeekdaysParse.call(this);\n        }\n        if (isStrict) {\n            return this._weekdaysStrictRegex;\n        } else {\n            return this._weekdaysRegex;\n        }\n    } else {\n        if (!hasOwnProp(this, '_weekdaysRegex')) {\n            this._weekdaysRegex = defaultWeekdaysRegex;\n        }\n        return this._weekdaysStrictRegex && isStrict ?\n            this._weekdaysStrictRegex : this._weekdaysRegex;\n    }\n}\n\nvar defaultWeekdaysShortRegex = matchWord;\nfunction weekdaysShortRegex (isStrict) {\n    if (this._weekdaysParseExact) {\n        if (!hasOwnProp(this, '_weekdaysRegex')) {\n            computeWeekdaysParse.call(this);\n        }\n        if (isStrict) {\n            return this._weekdaysShortStrictRegex;\n        } else {\n            return this._weekdaysShortRegex;\n        }\n    } else {\n        if (!hasOwnProp(this, '_weekdaysShortRegex')) {\n            this._weekdaysShortRegex = defaultWeekdaysShortRegex;\n        }\n        return this._weekdaysShortStrictRegex && isStrict ?\n            this._weekdaysShortStrictRegex : this._weekdaysShortRegex;\n    }\n}\n\nvar defaultWeekdaysMinRegex = matchWord;\nfunction weekdaysMinRegex (isStrict) {\n    if (this._weekdaysParseExact) {\n        if (!hasOwnProp(this, '_weekdaysRegex')) {\n            computeWeekdaysParse.call(this);\n        }\n        if (isStrict) {\n            return this._weekdaysMinStrictRegex;\n        } else {\n            return this._weekdaysMinRegex;\n        }\n    } else {\n        if (!hasOwnProp(this, '_weekdaysMinRegex')) {\n            this._weekdaysMinRegex = defaultWeekdaysMinRegex;\n        }\n        return this._weekdaysMinStrictRegex && isStrict ?\n            this._weekdaysMinStrictRegex : this._weekdaysMinRegex;\n    }\n}\n\n\nfunction computeWeekdaysParse () {\n    function cmpLenRev(a, b) {\n        return b.length - a.length;\n    }\n\n    var minPieces = [], shortPieces = [], longPieces = [], mixedPieces = [],\n        i, mom, minp, shortp, longp;\n    for (i = 0; i < 7; i++) {\n        // make the regex if we don't have it already\n        mom = createUTC([2000, 1]).day(i);\n        minp = this.weekdaysMin(mom, '');\n        shortp = this.weekdaysShort(mom, '');\n        longp = this.weekdays(mom, '');\n        minPieces.push(minp);\n        shortPieces.push(shortp);\n        longPieces.push(longp);\n        mixedPieces.push(minp);\n        mixedPieces.push(shortp);\n        mixedPieces.push(longp);\n    }\n    // Sorting makes sure if one weekday (or abbr) is a prefix of another it\n    // will match the longer piece.\n    minPieces.sort(cmpLenRev);\n    shortPieces.sort(cmpLenRev);\n    longPieces.sort(cmpLenRev);\n    mixedPieces.sort(cmpLenRev);\n    for (i = 0; i < 7; i++) {\n        shortPieces[i] = regexEscape(shortPieces[i]);\n        longPieces[i] = regexEscape(longPieces[i]);\n        mixedPieces[i] = regexEscape(mixedPieces[i]);\n    }\n\n    this._weekdaysRegex = new RegExp('^(' + mixedPieces.join('|') + ')', 'i');\n    this._weekdaysShortRegex = this._weekdaysRegex;\n    this._weekdaysMinRegex = this._weekdaysRegex;\n\n    this._weekdaysStrictRegex = new RegExp('^(' + longPieces.join('|') + ')', 'i');\n    this._weekdaysShortStrictRegex = new RegExp('^(' + shortPieces.join('|') + ')', 'i');\n    this._weekdaysMinStrictRegex = new RegExp('^(' + minPieces.join('|') + ')', 'i');\n}\n\n// FORMATTING\n\nfunction hFormat() {\n    return this.hours() % 12 || 12;\n}\n\nfunction kFormat() {\n    return this.hours() || 24;\n}\n\naddFormatToken('H', ['HH', 2], 0, 'hour');\naddFormatToken('h', ['hh', 2], 0, hFormat);\naddFormatToken('k', ['kk', 2], 0, kFormat);\n\naddFormatToken('hmm', 0, 0, function () {\n    return '' + hFormat.apply(this) + zeroFill(this.minutes(), 2);\n});\n\naddFormatToken('hmmss', 0, 0, function () {\n    return '' + hFormat.apply(this) + zeroFill(this.minutes(), 2) +\n        zeroFill(this.seconds(), 2);\n});\n\naddFormatToken('Hmm', 0, 0, function () {\n    return '' + this.hours() + zeroFill(this.minutes(), 2);\n});\n\naddFormatToken('Hmmss', 0, 0, function () {\n    return '' + this.hours() + zeroFill(this.minutes(), 2) +\n        zeroFill(this.seconds(), 2);\n});\n\nfunction meridiem (token, lowercase) {\n    addFormatToken(token, 0, 0, function () {\n        return this.localeData().meridiem(this.hours(), this.minutes(), lowercase);\n    });\n}\n\nmeridiem('a', true);\nmeridiem('A', false);\n\n// ALIASES\n\naddUnitAlias('hour', 'h');\n\n// PRIORITY\naddUnitPriority('hour', 13);\n\n// PARSING\n\nfunction matchMeridiem (isStrict, locale) {\n    return locale._meridiemParse;\n}\n\naddRegexToken('a',  matchMeridiem);\naddRegexToken('A',  matchMeridiem);\naddRegexToken('H',  match1to2);\naddRegexToken('h',  match1to2);\naddRegexToken('k',  match1to2);\naddRegexToken('HH', match1to2, match2);\naddRegexToken('hh', match1to2, match2);\naddRegexToken('kk', match1to2, match2);\n\naddRegexToken('hmm', match3to4);\naddRegexToken('hmmss', match5to6);\naddRegexToken('Hmm', match3to4);\naddRegexToken('Hmmss', match5to6);\n\naddParseToken(['H', 'HH'], HOUR);\naddParseToken(['k', 'kk'], function (input, array, config) {\n    var kInput = toInt(input);\n    array[HOUR] = kInput === 24 ? 0 : kInput;\n});\naddParseToken(['a', 'A'], function (input, array, config) {\n    config._isPm = config._locale.isPM(input);\n    config._meridiem = input;\n});\naddParseToken(['h', 'hh'], function (input, array, config) {\n    array[HOUR] = toInt(input);\n    getParsingFlags(config).bigHour = true;\n});\naddParseToken('hmm', function (input, array, config) {\n    var pos = input.length - 2;\n    array[HOUR] = toInt(input.substr(0, pos));\n    array[MINUTE] = toInt(input.substr(pos));\n    getParsingFlags(config).bigHour = true;\n});\naddParseToken('hmmss', function (input, array, config) {\n    var pos1 = input.length - 4;\n    var pos2 = input.length - 2;\n    array[HOUR] = toInt(input.substr(0, pos1));\n    array[MINUTE] = toInt(input.substr(pos1, 2));\n    array[SECOND] = toInt(input.substr(pos2));\n    getParsingFlags(config).bigHour = true;\n});\naddParseToken('Hmm', function (input, array, config) {\n    var pos = input.length - 2;\n    array[HOUR] = toInt(input.substr(0, pos));\n    array[MINUTE] = toInt(input.substr(pos));\n});\naddParseToken('Hmmss', function (input, array, config) {\n    var pos1 = input.length - 4;\n    var pos2 = input.length - 2;\n    array[HOUR] = toInt(input.substr(0, pos1));\n    array[MINUTE] = toInt(input.substr(pos1, 2));\n    array[SECOND] = toInt(input.substr(pos2));\n});\n\n// LOCALES\n\nfunction localeIsPM (input) {\n    // IE8 Quirks Mode & IE7 Standards Mode do not allow accessing strings like arrays\n    // Using charAt should be more compatible.\n    return ((input + '').toLowerCase().charAt(0) === 'p');\n}\n\nvar defaultLocaleMeridiemParse = /[ap]\\.?m?\\.?/i;\nfunction localeMeridiem (hours, minutes, isLower) {\n    if (hours > 11) {\n        return isLower ? 'pm' : 'PM';\n    } else {\n        return isLower ? 'am' : 'AM';\n    }\n}\n\n\n// MOMENTS\n\n// Setting the hour should keep the time, because the user explicitly\n// specified which hour he wants. So trying to maintain the same hour (in\n// a new timezone) makes sense. Adding/subtracting hours does not follow\n// this rule.\nvar getSetHour = makeGetSet('Hours', true);\n\n// months\n// week\n// weekdays\n// meridiem\nvar baseConfig = {\n    calendar: defaultCalendar,\n    longDateFormat: defaultLongDateFormat,\n    invalidDate: defaultInvalidDate,\n    ordinal: defaultOrdinal,\n    dayOfMonthOrdinalParse: defaultDayOfMonthOrdinalParse,\n    relativeTime: defaultRelativeTime,\n\n    months: defaultLocaleMonths,\n    monthsShort: defaultLocaleMonthsShort,\n\n    week: defaultLocaleWeek,\n\n    weekdays: defaultLocaleWeekdays,\n    weekdaysMin: defaultLocaleWeekdaysMin,\n    weekdaysShort: defaultLocaleWeekdaysShort,\n\n    meridiemParse: defaultLocaleMeridiemParse\n};\n\n// internal storage for locale config files\nvar locales = {};\nvar localeFamilies = {};\nvar globalLocale;\n\nfunction normalizeLocale(key) {\n    return key ? key.toLowerCase().replace('_', '-') : key;\n}\n\n// pick the locale from the array\n// try ['en-au', 'en-gb'] as 'en-au', 'en-gb', 'en', as in move through the list trying each\n// substring from most specific to least, but move to the next array item if it's a more specific variant than the current root\nfunction chooseLocale(names) {\n    var i = 0, j, next, locale, split;\n\n    while (i < names.length) {\n        split = normalizeLocale(names[i]).split('-');\n        j = split.length;\n        next = normalizeLocale(names[i + 1]);\n        next = next ? next.split('-') : null;\n        while (j > 0) {\n            locale = loadLocale(split.slice(0, j).join('-'));\n            if (locale) {\n                return locale;\n            }\n            if (next && next.length >= j && compareArrays(split, next, true) >= j - 1) {\n                //the next array item is better than a shallower substring of this one\n                break;\n            }\n            j--;\n        }\n        i++;\n    }\n    return null;\n}\n\nfunction loadLocale(name) {\n    var oldLocale = null;\n    // TODO: Find a better way to register and load all the locales in Node\n    if (!locales[name] && (typeof module !== 'undefined') &&\n            module && module.exports) {\n        try {\n            oldLocale = globalLocale._abbr;\n            require('./locale/' + name);\n            // because defineLocale currently also sets the global locale, we\n            // want to undo that for lazy loaded locales\n            getSetGlobalLocale(oldLocale);\n        } catch (e) { }\n    }\n    return locales[name];\n}\n\n// This function will load locale and then set the global locale.  If\n// no arguments are passed in, it will simply return the current global\n// locale key.\nfunction getSetGlobalLocale (key, values) {\n    var data;\n    if (key) {\n        if (isUndefined(values)) {\n            data = getLocale(key);\n        }\n        else {\n            data = defineLocale(key, values);\n        }\n\n        if (data) {\n            // moment.duration._locale = moment._locale = data;\n            globalLocale = data;\n        }\n    }\n\n    return globalLocale._abbr;\n}\n\nfunction defineLocale (name, config) {\n    if (config !== null) {\n        var parentConfig = baseConfig;\n        config.abbr = name;\n        if (locales[name] != null) {\n            deprecateSimple('defineLocaleOverride',\n                    'use moment.updateLocale(localeName, config) to change ' +\n                    'an existing locale. moment.defineLocale(localeName, ' +\n                    'config) should only be used for creating a new locale ' +\n                    'See http://momentjs.com/guides/#/warnings/define-locale/ for more info.');\n            parentConfig = locales[name]._config;\n        } else if (config.parentLocale != null) {\n            if (locales[config.parentLocale] != null) {\n                parentConfig = locales[config.parentLocale]._config;\n            } else {\n                if (!localeFamilies[config.parentLocale]) {\n                    localeFamilies[config.parentLocale] = [];\n                }\n                localeFamilies[config.parentLocale].push({\n                    name: name,\n                    config: config\n                });\n                return null;\n            }\n        }\n        locales[name] = new Locale(mergeConfigs(parentConfig, config));\n\n        if (localeFamilies[name]) {\n            localeFamilies[name].forEach(function (x) {\n                defineLocale(x.name, x.config);\n            });\n        }\n\n        // backwards compat for now: also set the locale\n        // make sure we set the locale AFTER all child locales have been\n        // created, so we won't end up with the child locale set.\n        getSetGlobalLocale(name);\n\n\n        return locales[name];\n    } else {\n        // useful for testing\n        delete locales[name];\n        return null;\n    }\n}\n\nfunction updateLocale(name, config) {\n    if (config != null) {\n        var locale, parentConfig = baseConfig;\n        // MERGE\n        if (locales[name] != null) {\n            parentConfig = locales[name]._config;\n        }\n        config = mergeConfigs(parentConfig, config);\n        locale = new Locale(config);\n        locale.parentLocale = locales[name];\n        locales[name] = locale;\n\n        // backwards compat for now: also set the locale\n        getSetGlobalLocale(name);\n    } else {\n        // pass null for config to unupdate, useful for tests\n        if (locales[name] != null) {\n            if (locales[name].parentLocale != null) {\n                locales[name] = locales[name].parentLocale;\n            } else if (locales[name] != null) {\n                delete locales[name];\n            }\n        }\n    }\n    return locales[name];\n}\n\n// returns locale data\nfunction getLocale (key) {\n    var locale;\n\n    if (key && key._locale && key._locale._abbr) {\n        key = key._locale._abbr;\n    }\n\n    if (!key) {\n        return globalLocale;\n    }\n\n    if (!isArray(key)) {\n        //short-circuit everything else\n        locale = loadLocale(key);\n        if (locale) {\n            return locale;\n        }\n        key = [key];\n    }\n\n    return chooseLocale(key);\n}\n\nfunction listLocales() {\n    return keys$1(locales);\n}\n\nfunction checkOverflow (m) {\n    var overflow;\n    var a = m._a;\n\n    if (a && getParsingFlags(m).overflow === -2) {\n        overflow =\n            a[MONTH]       < 0 || a[MONTH]       > 11  ? MONTH :\n            a[DATE]        < 1 || a[DATE]        > daysInMonth(a[YEAR], a[MONTH]) ? DATE :\n            a[HOUR]        < 0 || a[HOUR]        > 24 || (a[HOUR] === 24 && (a[MINUTE] !== 0 || a[SECOND] !== 0 || a[MILLISECOND] !== 0)) ? HOUR :\n            a[MINUTE]      < 0 || a[MINUTE]      > 59  ? MINUTE :\n            a[SECOND]      < 0 || a[SECOND]      > 59  ? SECOND :\n            a[MILLISECOND] < 0 || a[MILLISECOND] > 999 ? MILLISECOND :\n            -1;\n\n        if (getParsingFlags(m)._overflowDayOfYear && (overflow < YEAR || overflow > DATE)) {\n            overflow = DATE;\n        }\n        if (getParsingFlags(m)._overflowWeeks && overflow === -1) {\n            overflow = WEEK;\n        }\n        if (getParsingFlags(m)._overflowWeekday && overflow === -1) {\n            overflow = WEEKDAY;\n        }\n\n        getParsingFlags(m).overflow = overflow;\n    }\n\n    return m;\n}\n\n// iso 8601 regex\n// 0000-00-00 0000-W00 or 0000-W00-0 + T + 00 or 00:00 or 00:00:00 or 00:00:00.000 + +00:00 or +0000 or +00)\nvar extendedIsoRegex = /^\\s*((?:[+-]\\d{6}|\\d{4})-(?:\\d\\d-\\d\\d|W\\d\\d-\\d|W\\d\\d|\\d\\d\\d|\\d\\d))(?:(T| )(\\d\\d(?::\\d\\d(?::\\d\\d(?:[.,]\\d+)?)?)?)([\\+\\-]\\d\\d(?::?\\d\\d)?|\\s*Z)?)?$/;\nvar basicIsoRegex = /^\\s*((?:[+-]\\d{6}|\\d{4})(?:\\d\\d\\d\\d|W\\d\\d\\d|W\\d\\d|\\d\\d\\d|\\d\\d))(?:(T| )(\\d\\d(?:\\d\\d(?:\\d\\d(?:[.,]\\d+)?)?)?)([\\+\\-]\\d\\d(?::?\\d\\d)?|\\s*Z)?)?$/;\n\nvar tzRegex = /Z|[+-]\\d\\d(?::?\\d\\d)?/;\n\nvar isoDates = [\n    ['YYYYYY-MM-DD', /[+-]\\d{6}-\\d\\d-\\d\\d/],\n    ['YYYY-MM-DD', /\\d{4}-\\d\\d-\\d\\d/],\n    ['GGGG-[W]WW-E', /\\d{4}-W\\d\\d-\\d/],\n    ['GGGG-[W]WW', /\\d{4}-W\\d\\d/, false],\n    ['YYYY-DDD', /\\d{4}-\\d{3}/],\n    ['YYYY-MM', /\\d{4}-\\d\\d/, false],\n    ['YYYYYYMMDD', /[+-]\\d{10}/],\n    ['YYYYMMDD', /\\d{8}/],\n    // YYYYMM is NOT allowed by the standard\n    ['GGGG[W]WWE', /\\d{4}W\\d{3}/],\n    ['GGGG[W]WW', /\\d{4}W\\d{2}/, false],\n    ['YYYYDDD', /\\d{7}/]\n];\n\n// iso time formats and regexes\nvar isoTimes = [\n    ['HH:mm:ss.SSSS', /\\d\\d:\\d\\d:\\d\\d\\.\\d+/],\n    ['HH:mm:ss,SSSS', /\\d\\d:\\d\\d:\\d\\d,\\d+/],\n    ['HH:mm:ss', /\\d\\d:\\d\\d:\\d\\d/],\n    ['HH:mm', /\\d\\d:\\d\\d/],\n    ['HHmmss.SSSS', /\\d\\d\\d\\d\\d\\d\\.\\d+/],\n    ['HHmmss,SSSS', /\\d\\d\\d\\d\\d\\d,\\d+/],\n    ['HHmmss', /\\d\\d\\d\\d\\d\\d/],\n    ['HHmm', /\\d\\d\\d\\d/],\n    ['HH', /\\d\\d/]\n];\n\nvar aspNetJsonRegex = /^\\/?Date\\((\\-?\\d+)/i;\n\n// date from iso format\nfunction configFromISO(config) {\n    var i, l,\n        string = config._i,\n        match = extendedIsoRegex.exec(string) || basicIsoRegex.exec(string),\n        allowTime, dateFormat, timeFormat, tzFormat;\n\n    if (match) {\n        getParsingFlags(config).iso = true;\n\n        for (i = 0, l = isoDates.length; i < l; i++) {\n            if (isoDates[i][1].exec(match[1])) {\n                dateFormat = isoDates[i][0];\n                allowTime = isoDates[i][2] !== false;\n                break;\n            }\n        }\n        if (dateFormat == null) {\n            config._isValid = false;\n            return;\n        }\n        if (match[3]) {\n            for (i = 0, l = isoTimes.length; i < l; i++) {\n                if (isoTimes[i][1].exec(match[3])) {\n                    // match[2] should be 'T' or space\n                    timeFormat = (match[2] || ' ') + isoTimes[i][0];\n                    break;\n                }\n            }\n            if (timeFormat == null) {\n                config._isValid = false;\n                return;\n            }\n        }\n        if (!allowTime && timeFormat != null) {\n            config._isValid = false;\n            return;\n        }\n        if (match[4]) {\n            if (tzRegex.exec(match[4])) {\n                tzFormat = 'Z';\n            } else {\n                config._isValid = false;\n                return;\n            }\n        }\n        config._f = dateFormat + (timeFormat || '') + (tzFormat || '');\n        configFromStringAndFormat(config);\n    } else {\n        config._isValid = false;\n    }\n}\n\n// RFC 2822 regex: For details see https://tools.ietf.org/html/rfc2822#section-3.3\nvar basicRfcRegex = /^((?:Mon|Tue|Wed|Thu|Fri|Sat|Sun),?\\s)?(\\d?\\d\\s(?:Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)\\s(?:\\d\\d)?\\d\\d\\s)(\\d\\d:\\d\\d)(\\:\\d\\d)?(\\s(?:UT|GMT|[ECMP][SD]T|[A-IK-Za-ik-z]|[+-]\\d{4}))$/;\n\n// date and time from ref 2822 format\nfunction configFromRFC2822(config) {\n    var string, match, dayFormat,\n        dateFormat, timeFormat, tzFormat;\n    var timezones = {\n        ' GMT': ' +0000',\n        ' EDT': ' -0400',\n        ' EST': ' -0500',\n        ' CDT': ' -0500',\n        ' CST': ' -0600',\n        ' MDT': ' -0600',\n        ' MST': ' -0700',\n        ' PDT': ' -0700',\n        ' PST': ' -0800'\n    };\n    var military = 'YXWVUTSRQPONZABCDEFGHIKLM';\n    var timezone, timezoneIndex;\n\n    string = config._i\n        .replace(/\\([^\\)]*\\)|[\\n\\t]/g, ' ') // Remove comments and folding whitespace\n        .replace(/(\\s\\s+)/g, ' ') // Replace multiple-spaces with a single space\n        .replace(/^\\s|\\s$/g, ''); // Remove leading and trailing spaces\n    match = basicRfcRegex.exec(string);\n\n    if (match) {\n        dayFormat = match[1] ? 'ddd' + ((match[1].length === 5) ? ', ' : ' ') : '';\n        dateFormat = 'D MMM ' + ((match[2].length > 10) ? 'YYYY ' : 'YY ');\n        timeFormat = 'HH:mm' + (match[4] ? ':ss' : '');\n\n        // TODO: Replace the vanilla JS Date object with an indepentent day-of-week check.\n        if (match[1]) { // day of week given\n            var momentDate = new Date(match[2]);\n            var momentDay = ['Sun','Mon','Tue','Wed','Thu','Fri','Sat'][momentDate.getDay()];\n\n            if (match[1].substr(0,3) !== momentDay) {\n                getParsingFlags(config).weekdayMismatch = true;\n                config._isValid = false;\n                return;\n            }\n        }\n\n        switch (match[5].length) {\n            case 2: // military\n                if (timezoneIndex === 0) {\n                    timezone = ' +0000';\n                } else {\n                    timezoneIndex = military.indexOf(match[5][1].toUpperCase()) - 12;\n                    timezone = ((timezoneIndex < 0) ? ' -' : ' +') +\n                        (('' + timezoneIndex).replace(/^-?/, '0')).match(/..$/)[0] + '00';\n                }\n                break;\n            case 4: // Zone\n                timezone = timezones[match[5]];\n                break;\n            default: // UT or +/-9999\n                timezone = timezones[' GMT'];\n        }\n        match[5] = timezone;\n        config._i = match.splice(1).join('');\n        tzFormat = ' ZZ';\n        config._f = dayFormat + dateFormat + timeFormat + tzFormat;\n        configFromStringAndFormat(config);\n        getParsingFlags(config).rfc2822 = true;\n    } else {\n        config._isValid = false;\n    }\n}\n\n// date from iso format or fallback\nfunction configFromString(config) {\n    var matched = aspNetJsonRegex.exec(config._i);\n\n    if (matched !== null) {\n        config._d = new Date(+matched[1]);\n        return;\n    }\n\n    configFromISO(config);\n    if (config._isValid === false) {\n        delete config._isValid;\n    } else {\n        return;\n    }\n\n    configFromRFC2822(config);\n    if (config._isValid === false) {\n        delete config._isValid;\n    } else {\n        return;\n    }\n\n    // Final attempt, use Input Fallback\n    hooks.createFromInputFallback(config);\n}\n\nhooks.createFromInputFallback = deprecate(\n    'value provided is not in a recognized RFC2822 or ISO format. moment construction falls back to js Date(), ' +\n    'which is not reliable across all browsers and versions. Non RFC2822/ISO date formats are ' +\n    'discouraged and will be removed in an upcoming major release. Please refer to ' +\n    'http://momentjs.com/guides/#/warnings/js-date/ for more info.',\n    function (config) {\n        config._d = new Date(config._i + (config._useUTC ? ' UTC' : ''));\n    }\n);\n\n// Pick the first defined of two or three arguments.\nfunction defaults(a, b, c) {\n    if (a != null) {\n        return a;\n    }\n    if (b != null) {\n        return b;\n    }\n    return c;\n}\n\nfunction currentDateArray(config) {\n    // hooks is actually the exported moment object\n    var nowValue = new Date(hooks.now());\n    if (config._useUTC) {\n        return [nowValue.getUTCFullYear(), nowValue.getUTCMonth(), nowValue.getUTCDate()];\n    }\n    return [nowValue.getFullYear(), nowValue.getMonth(), nowValue.getDate()];\n}\n\n// convert an array to a date.\n// the array should mirror the parameters below\n// note: all values past the year are optional and will default to the lowest possible value.\n// [year, month, day , hour, minute, second, millisecond]\nfunction configFromArray (config) {\n    var i, date, input = [], currentDate, yearToUse;\n\n    if (config._d) {\n        return;\n    }\n\n    currentDate = currentDateArray(config);\n\n    //compute day of the year from weeks and weekdays\n    if (config._w && config._a[DATE] == null && config._a[MONTH] == null) {\n        dayOfYearFromWeekInfo(config);\n    }\n\n    //if the day of the year is set, figure out what it is\n    if (config._dayOfYear != null) {\n        yearToUse = defaults(config._a[YEAR], currentDate[YEAR]);\n\n        if (config._dayOfYear > daysInYear(yearToUse) || config._dayOfYear === 0) {\n            getParsingFlags(config)._overflowDayOfYear = true;\n        }\n\n        date = createUTCDate(yearToUse, 0, config._dayOfYear);\n        config._a[MONTH] = date.getUTCMonth();\n        config._a[DATE] = date.getUTCDate();\n    }\n\n    // Default to current date.\n    // * if no year, month, day of month are given, default to today\n    // * if day of month is given, default month and year\n    // * if month is given, default only year\n    // * if year is given, don't default anything\n    for (i = 0; i < 3 && config._a[i] == null; ++i) {\n        config._a[i] = input[i] = currentDate[i];\n    }\n\n    // Zero out whatever was not defaulted, including time\n    for (; i < 7; i++) {\n        config._a[i] = input[i] = (config._a[i] == null) ? (i === 2 ? 1 : 0) : config._a[i];\n    }\n\n    // Check for 24:00:00.000\n    if (config._a[HOUR] === 24 &&\n            config._a[MINUTE] === 0 &&\n            config._a[SECOND] === 0 &&\n            config._a[MILLISECOND] === 0) {\n        config._nextDay = true;\n        config._a[HOUR] = 0;\n    }\n\n    config._d = (config._useUTC ? createUTCDate : createDate).apply(null, input);\n    // Apply timezone offset from input. The actual utcOffset can be changed\n    // with parseZone.\n    if (config._tzm != null) {\n        config._d.setUTCMinutes(config._d.getUTCMinutes() - config._tzm);\n    }\n\n    if (config._nextDay) {\n        config._a[HOUR] = 24;\n    }\n}\n\nfunction dayOfYearFromWeekInfo(config) {\n    var w, weekYear, week, weekday, dow, doy, temp, weekdayOverflow;\n\n    w = config._w;\n    if (w.GG != null || w.W != null || w.E != null) {\n        dow = 1;\n        doy = 4;\n\n        // TODO: We need to take the current isoWeekYear, but that depends on\n        // how we interpret now (local, utc, fixed offset). So create\n        // a now version of current config (take local/utc/offset flags, and\n        // create now).\n        weekYear = defaults(w.GG, config._a[YEAR], weekOfYear(createLocal(), 1, 4).year);\n        week = defaults(w.W, 1);\n        weekday = defaults(w.E, 1);\n        if (weekday < 1 || weekday > 7) {\n            weekdayOverflow = true;\n        }\n    } else {\n        dow = config._locale._week.dow;\n        doy = config._locale._week.doy;\n\n        var curWeek = weekOfYear(createLocal(), dow, doy);\n\n        weekYear = defaults(w.gg, config._a[YEAR], curWeek.year);\n\n        // Default to current week.\n        week = defaults(w.w, curWeek.week);\n\n        if (w.d != null) {\n            // weekday -- low day numbers are considered next week\n            weekday = w.d;\n            if (weekday < 0 || weekday > 6) {\n                weekdayOverflow = true;\n            }\n        } else if (w.e != null) {\n            // local weekday -- counting starts from begining of week\n            weekday = w.e + dow;\n            if (w.e < 0 || w.e > 6) {\n                weekdayOverflow = true;\n            }\n        } else {\n            // default to begining of week\n            weekday = dow;\n        }\n    }\n    if (week < 1 || week > weeksInYear(weekYear, dow, doy)) {\n        getParsingFlags(config)._overflowWeeks = true;\n    } else if (weekdayOverflow != null) {\n        getParsingFlags(config)._overflowWeekday = true;\n    } else {\n        temp = dayOfYearFromWeeks(weekYear, week, weekday, dow, doy);\n        config._a[YEAR] = temp.year;\n        config._dayOfYear = temp.dayOfYear;\n    }\n}\n\n// constant that refers to the ISO standard\nhooks.ISO_8601 = function () {};\n\n// constant that refers to the RFC 2822 form\nhooks.RFC_2822 = function () {};\n\n// date from string and format string\nfunction configFromStringAndFormat(config) {\n    // TODO: Move this to another part of the creation flow to prevent circular deps\n    if (config._f === hooks.ISO_8601) {\n        configFromISO(config);\n        return;\n    }\n    if (config._f === hooks.RFC_2822) {\n        configFromRFC2822(config);\n        return;\n    }\n    config._a = [];\n    getParsingFlags(config).empty = true;\n\n    // This array is used to make a Date, either with `new Date` or `Date.UTC`\n    var string = '' + config._i,\n        i, parsedInput, tokens, token, skipped,\n        stringLength = string.length,\n        totalParsedInputLength = 0;\n\n    tokens = expandFormat(config._f, config._locale).match(formattingTokens) || [];\n\n    for (i = 0; i < tokens.length; i++) {\n        token = tokens[i];\n        parsedInput = (string.match(getParseRegexForToken(token, config)) || [])[0];\n        // console.log('token', token, 'parsedInput', parsedInput,\n        //         'regex', getParseRegexForToken(token, config));\n        if (parsedInput) {\n            skipped = string.substr(0, string.indexOf(parsedInput));\n            if (skipped.length > 0) {\n                getParsingFlags(config).unusedInput.push(skipped);\n            }\n            string = string.slice(string.indexOf(parsedInput) + parsedInput.length);\n            totalParsedInputLength += parsedInput.length;\n        }\n        // don't parse if it's not a known token\n        if (formatTokenFunctions[token]) {\n            if (parsedInput) {\n                getParsingFlags(config).empty = false;\n            }\n            else {\n                getParsingFlags(config).unusedTokens.push(token);\n            }\n            addTimeToArrayFromToken(token, parsedInput, config);\n        }\n        else if (config._strict && !parsedInput) {\n            getParsingFlags(config).unusedTokens.push(token);\n        }\n    }\n\n    // add remaining unparsed input length to the string\n    getParsingFlags(config).charsLeftOver = stringLength - totalParsedInputLength;\n    if (string.length > 0) {\n        getParsingFlags(config).unusedInput.push(string);\n    }\n\n    // clear _12h flag if hour is <= 12\n    if (config._a[HOUR] <= 12 &&\n        getParsingFlags(config).bigHour === true &&\n        config._a[HOUR] > 0) {\n        getParsingFlags(config).bigHour = undefined;\n    }\n\n    getParsingFlags(config).parsedDateParts = config._a.slice(0);\n    getParsingFlags(config).meridiem = config._meridiem;\n    // handle meridiem\n    config._a[HOUR] = meridiemFixWrap(config._locale, config._a[HOUR], config._meridiem);\n\n    configFromArray(config);\n    checkOverflow(config);\n}\n\n\nfunction meridiemFixWrap (locale, hour, meridiem) {\n    var isPm;\n\n    if (meridiem == null) {\n        // nothing to do\n        return hour;\n    }\n    if (locale.meridiemHour != null) {\n        return locale.meridiemHour(hour, meridiem);\n    } else if (locale.isPM != null) {\n        // Fallback\n        isPm = locale.isPM(meridiem);\n        if (isPm && hour < 12) {\n            hour += 12;\n        }\n        if (!isPm && hour === 12) {\n            hour = 0;\n        }\n        return hour;\n    } else {\n        // this is not supposed to happen\n        return hour;\n    }\n}\n\n// date from string and array of format strings\nfunction configFromStringAndArray(config) {\n    var tempConfig,\n        bestMoment,\n\n        scoreToBeat,\n        i,\n        currentScore;\n\n    if (config._f.length === 0) {\n        getParsingFlags(config).invalidFormat = true;\n        config._d = new Date(NaN);\n        return;\n    }\n\n    for (i = 0; i < config._f.length; i++) {\n        currentScore = 0;\n        tempConfig = copyConfig({}, config);\n        if (config._useUTC != null) {\n            tempConfig._useUTC = config._useUTC;\n        }\n        tempConfig._f = config._f[i];\n        configFromStringAndFormat(tempConfig);\n\n        if (!isValid(tempConfig)) {\n            continue;\n        }\n\n        // if there is any input that was not parsed add a penalty for that format\n        currentScore += getParsingFlags(tempConfig).charsLeftOver;\n\n        //or tokens\n        currentScore += getParsingFlags(tempConfig).unusedTokens.length * 10;\n\n        getParsingFlags(tempConfig).score = currentScore;\n\n        if (scoreToBeat == null || currentScore < scoreToBeat) {\n            scoreToBeat = currentScore;\n            bestMoment = tempConfig;\n        }\n    }\n\n    extend(config, bestMoment || tempConfig);\n}\n\nfunction configFromObject(config) {\n    if (config._d) {\n        return;\n    }\n\n    var i = normalizeObjectUnits(config._i);\n    config._a = map([i.year, i.month, i.day || i.date, i.hour, i.minute, i.second, i.millisecond], function (obj) {\n        return obj && parseInt(obj, 10);\n    });\n\n    configFromArray(config);\n}\n\nfunction createFromConfig (config) {\n    var res = new Moment(checkOverflow(prepareConfig(config)));\n    if (res._nextDay) {\n        // Adding is smart enough around DST\n        res.add(1, 'd');\n        res._nextDay = undefined;\n    }\n\n    return res;\n}\n\nfunction prepareConfig (config) {\n    var input = config._i,\n        format = config._f;\n\n    config._locale = config._locale || getLocale(config._l);\n\n    if (input === null || (format === undefined && input === '')) {\n        return createInvalid({nullInput: true});\n    }\n\n    if (typeof input === 'string') {\n        config._i = input = config._locale.preparse(input);\n    }\n\n    if (isMoment(input)) {\n        return new Moment(checkOverflow(input));\n    } else if (isDate(input)) {\n        config._d = input;\n    } else if (isArray(format)) {\n        configFromStringAndArray(config);\n    } else if (format) {\n        configFromStringAndFormat(config);\n    }  else {\n        configFromInput(config);\n    }\n\n    if (!isValid(config)) {\n        config._d = null;\n    }\n\n    return config;\n}\n\nfunction configFromInput(config) {\n    var input = config._i;\n    if (isUndefined(input)) {\n        config._d = new Date(hooks.now());\n    } else if (isDate(input)) {\n        config._d = new Date(input.valueOf());\n    } else if (typeof input === 'string') {\n        configFromString(config);\n    } else if (isArray(input)) {\n        config._a = map(input.slice(0), function (obj) {\n            return parseInt(obj, 10);\n        });\n        configFromArray(config);\n    } else if (isObject(input)) {\n        configFromObject(config);\n    } else if (isNumber(input)) {\n        // from milliseconds\n        config._d = new Date(input);\n    } else {\n        hooks.createFromInputFallback(config);\n    }\n}\n\nfunction createLocalOrUTC (input, format, locale, strict, isUTC) {\n    var c = {};\n\n    if (locale === true || locale === false) {\n        strict = locale;\n        locale = undefined;\n    }\n\n    if ((isObject(input) && isObjectEmpty(input)) ||\n            (isArray(input) && input.length === 0)) {\n        input = undefined;\n    }\n    // object construction must be done this way.\n    // https://github.com/moment/moment/issues/1423\n    c._isAMomentObject = true;\n    c._useUTC = c._isUTC = isUTC;\n    c._l = locale;\n    c._i = input;\n    c._f = format;\n    c._strict = strict;\n\n    return createFromConfig(c);\n}\n\nfunction createLocal (input, format, locale, strict) {\n    return createLocalOrUTC(input, format, locale, strict, false);\n}\n\nvar prototypeMin = deprecate(\n    'moment().min is deprecated, use moment.max instead. http://momentjs.com/guides/#/warnings/min-max/',\n    function () {\n        var other = createLocal.apply(null, arguments);\n        if (this.isValid() && other.isValid()) {\n            return other < this ? this : other;\n        } else {\n            return createInvalid();\n        }\n    }\n);\n\nvar prototypeMax = deprecate(\n    'moment().max is deprecated, use moment.min instead. http://momentjs.com/guides/#/warnings/min-max/',\n    function () {\n        var other = createLocal.apply(null, arguments);\n        if (this.isValid() && other.isValid()) {\n            return other > this ? this : other;\n        } else {\n            return createInvalid();\n        }\n    }\n);\n\n// Pick a moment m from moments so that m[fn](other) is true for all\n// other. This relies on the function fn to be transitive.\n//\n// moments should either be an array of moment objects or an array, whose\n// first element is an array of moment objects.\nfunction pickBy(fn, moments) {\n    var res, i;\n    if (moments.length === 1 && isArray(moments[0])) {\n        moments = moments[0];\n    }\n    if (!moments.length) {\n        return createLocal();\n    }\n    res = moments[0];\n    for (i = 1; i < moments.length; ++i) {\n        if (!moments[i].isValid() || moments[i][fn](res)) {\n            res = moments[i];\n        }\n    }\n    return res;\n}\n\n// TODO: Use [].sort instead?\nfunction min () {\n    var args = [].slice.call(arguments, 0);\n\n    return pickBy('isBefore', args);\n}\n\nfunction max () {\n    var args = [].slice.call(arguments, 0);\n\n    return pickBy('isAfter', args);\n}\n\nvar now = function () {\n    return Date.now ? Date.now() : +(new Date());\n};\n\nvar ordering = ['year', 'quarter', 'month', 'week', 'day', 'hour', 'minute', 'second', 'millisecond'];\n\nfunction isDurationValid(m) {\n    for (var key in m) {\n        if (!(ordering.indexOf(key) !== -1 && (m[key] == null || !isNaN(m[key])))) {\n            return false;\n        }\n    }\n\n    var unitHasDecimal = false;\n    for (var i = 0; i < ordering.length; ++i) {\n        if (m[ordering[i]]) {\n            if (unitHasDecimal) {\n                return false; // only allow non-integers for smallest unit\n            }\n            if (parseFloat(m[ordering[i]]) !== toInt(m[ordering[i]])) {\n                unitHasDecimal = true;\n            }\n        }\n    }\n\n    return true;\n}\n\nfunction isValid$1() {\n    return this._isValid;\n}\n\nfunction createInvalid$1() {\n    return createDuration(NaN);\n}\n\nfunction Duration (duration) {\n    var normalizedInput = normalizeObjectUnits(duration),\n        years = normalizedInput.year || 0,\n        quarters = normalizedInput.quarter || 0,\n        months = normalizedInput.month || 0,\n        weeks = normalizedInput.week || 0,\n        days = normalizedInput.day || 0,\n        hours = normalizedInput.hour || 0,\n        minutes = normalizedInput.minute || 0,\n        seconds = normalizedInput.second || 0,\n        milliseconds = normalizedInput.millisecond || 0;\n\n    this._isValid = isDurationValid(normalizedInput);\n\n    // representation for dateAddRemove\n    this._milliseconds = +milliseconds +\n        seconds * 1e3 + // 1000\n        minutes * 6e4 + // 1000 * 60\n        hours * 1000 * 60 * 60; //using 1000 * 60 * 60 instead of 36e5 to avoid floating point rounding errors https://github.com/moment/moment/issues/2978\n    // Because of dateAddRemove treats 24 hours as different from a\n    // day when working around DST, we need to store them separately\n    this._days = +days +\n        weeks * 7;\n    // It is impossible translate months into days without knowing\n    // which months you are are talking about, so we have to store\n    // it separately.\n    this._months = +months +\n        quarters * 3 +\n        years * 12;\n\n    this._data = {};\n\n    this._locale = getLocale();\n\n    this._bubble();\n}\n\nfunction isDuration (obj) {\n    return obj instanceof Duration;\n}\n\nfunction absRound (number) {\n    if (number < 0) {\n        return Math.round(-1 * number) * -1;\n    } else {\n        return Math.round(number);\n    }\n}\n\n// FORMATTING\n\nfunction offset (token, separator) {\n    addFormatToken(token, 0, 0, function () {\n        var offset = this.utcOffset();\n        var sign = '+';\n        if (offset < 0) {\n            offset = -offset;\n            sign = '-';\n        }\n        return sign + zeroFill(~~(offset / 60), 2) + separator + zeroFill(~~(offset) % 60, 2);\n    });\n}\n\noffset('Z', ':');\noffset('ZZ', '');\n\n// PARSING\n\naddRegexToken('Z',  matchShortOffset);\naddRegexToken('ZZ', matchShortOffset);\naddParseToken(['Z', 'ZZ'], function (input, array, config) {\n    config._useUTC = true;\n    config._tzm = offsetFromString(matchShortOffset, input);\n});\n\n// HELPERS\n\n// timezone chunker\n// '+10:00' > ['10',  '00']\n// '-1530'  > ['-15', '30']\nvar chunkOffset = /([\\+\\-]|\\d\\d)/gi;\n\nfunction offsetFromString(matcher, string) {\n    var matches = (string || '').match(matcher);\n\n    if (matches === null) {\n        return null;\n    }\n\n    var chunk   = matches[matches.length - 1] || [];\n    var parts   = (chunk + '').match(chunkOffset) || ['-', 0, 0];\n    var minutes = +(parts[1] * 60) + toInt(parts[2]);\n\n    return minutes === 0 ?\n      0 :\n      parts[0] === '+' ? minutes : -minutes;\n}\n\n// Return a moment from input, that is local/utc/zone equivalent to model.\nfunction cloneWithOffset(input, model) {\n    var res, diff;\n    if (model._isUTC) {\n        res = model.clone();\n        diff = (isMoment(input) || isDate(input) ? input.valueOf() : createLocal(input).valueOf()) - res.valueOf();\n        // Use low-level api, because this fn is low-level api.\n        res._d.setTime(res._d.valueOf() + diff);\n        hooks.updateOffset(res, false);\n        return res;\n    } else {\n        return createLocal(input).local();\n    }\n}\n\nfunction getDateOffset (m) {\n    // On Firefox.24 Date#getTimezoneOffset returns a floating point.\n    // https://github.com/moment/moment/pull/1871\n    return -Math.round(m._d.getTimezoneOffset() / 15) * 15;\n}\n\n// HOOKS\n\n// This function will be called whenever a moment is mutated.\n// It is intended to keep the offset in sync with the timezone.\nhooks.updateOffset = function () {};\n\n// MOMENTS\n\n// keepLocalTime = true means only change the timezone, without\n// affecting the local hour. So 5:31:26 +0300 --[utcOffset(2, true)]-->\n// 5:31:26 +0200 It is possible that 5:31:26 doesn't exist with offset\n// +0200, so we adjust the time as needed, to be valid.\n//\n// Keeping the time actually adds/subtracts (one hour)\n// from the actual represented time. That is why we call updateOffset\n// a second time. In case it wants us to change the offset again\n// _changeInProgress == true case, then we have to adjust, because\n// there is no such time in the given timezone.\nfunction getSetOffset (input, keepLocalTime, keepMinutes) {\n    var offset = this._offset || 0,\n        localAdjust;\n    if (!this.isValid()) {\n        return input != null ? this : NaN;\n    }\n    if (input != null) {\n        if (typeof input === 'string') {\n            input = offsetFromString(matchShortOffset, input);\n            if (input === null) {\n                return this;\n            }\n        } else if (Math.abs(input) < 16 && !keepMinutes) {\n            input = input * 60;\n        }\n        if (!this._isUTC && keepLocalTime) {\n            localAdjust = getDateOffset(this);\n        }\n        this._offset = input;\n        this._isUTC = true;\n        if (localAdjust != null) {\n            this.add(localAdjust, 'm');\n        }\n        if (offset !== input) {\n            if (!keepLocalTime || this._changeInProgress) {\n                addSubtract(this, createDuration(input - offset, 'm'), 1, false);\n            } else if (!this._changeInProgress) {\n                this._changeInProgress = true;\n                hooks.updateOffset(this, true);\n                this._changeInProgress = null;\n            }\n        }\n        return this;\n    } else {\n        return this._isUTC ? offset : getDateOffset(this);\n    }\n}\n\nfunction getSetZone (input, keepLocalTime) {\n    if (input != null) {\n        if (typeof input !== 'string') {\n            input = -input;\n        }\n\n        this.utcOffset(input, keepLocalTime);\n\n        return this;\n    } else {\n        return -this.utcOffset();\n    }\n}\n\nfunction setOffsetToUTC (keepLocalTime) {\n    return this.utcOffset(0, keepLocalTime);\n}\n\nfunction setOffsetToLocal (keepLocalTime) {\n    if (this._isUTC) {\n        this.utcOffset(0, keepLocalTime);\n        this._isUTC = false;\n\n        if (keepLocalTime) {\n            this.subtract(getDateOffset(this), 'm');\n        }\n    }\n    return this;\n}\n\nfunction setOffsetToParsedOffset () {\n    if (this._tzm != null) {\n        this.utcOffset(this._tzm, false, true);\n    } else if (typeof this._i === 'string') {\n        var tZone = offsetFromString(matchOffset, this._i);\n        if (tZone != null) {\n            this.utcOffset(tZone);\n        }\n        else {\n            this.utcOffset(0, true);\n        }\n    }\n    return this;\n}\n\nfunction hasAlignedHourOffset (input) {\n    if (!this.isValid()) {\n        return false;\n    }\n    input = input ? createLocal(input).utcOffset() : 0;\n\n    return (this.utcOffset() - input) % 60 === 0;\n}\n\nfunction isDaylightSavingTime () {\n    return (\n        this.utcOffset() > this.clone().month(0).utcOffset() ||\n        this.utcOffset() > this.clone().month(5).utcOffset()\n    );\n}\n\nfunction isDaylightSavingTimeShifted () {\n    if (!isUndefined(this._isDSTShifted)) {\n        return this._isDSTShifted;\n    }\n\n    var c = {};\n\n    copyConfig(c, this);\n    c = prepareConfig(c);\n\n    if (c._a) {\n        var other = c._isUTC ? createUTC(c._a) : createLocal(c._a);\n        this._isDSTShifted = this.isValid() &&\n            compareArrays(c._a, other.toArray()) > 0;\n    } else {\n        this._isDSTShifted = false;\n    }\n\n    return this._isDSTShifted;\n}\n\nfunction isLocal () {\n    return this.isValid() ? !this._isUTC : false;\n}\n\nfunction isUtcOffset () {\n    return this.isValid() ? this._isUTC : false;\n}\n\nfunction isUtc () {\n    return this.isValid() ? this._isUTC && this._offset === 0 : false;\n}\n\n// ASP.NET json date format regex\nvar aspNetRegex = /^(\\-)?(?:(\\d*)[. ])?(\\d+)\\:(\\d+)(?:\\:(\\d+)(\\.\\d*)?)?$/;\n\n// from http://docs.closure-library.googlecode.com/git/closure_goog_date_date.js.source.html\n// somewhat more in line with 4.4.3.2 2004 spec, but allows decimal anywhere\n// and further modified to allow for strings containing both week and day\nvar isoRegex = /^(-)?P(?:(-?[0-9,.]*)Y)?(?:(-?[0-9,.]*)M)?(?:(-?[0-9,.]*)W)?(?:(-?[0-9,.]*)D)?(?:T(?:(-?[0-9,.]*)H)?(?:(-?[0-9,.]*)M)?(?:(-?[0-9,.]*)S)?)?$/;\n\nfunction createDuration (input, key) {\n    var duration = input,\n        // matching against regexp is expensive, do it on demand\n        match = null,\n        sign,\n        ret,\n        diffRes;\n\n    if (isDuration(input)) {\n        duration = {\n            ms : input._milliseconds,\n            d  : input._days,\n            M  : input._months\n        };\n    } else if (isNumber(input)) {\n        duration = {};\n        if (key) {\n            duration[key] = input;\n        } else {\n            duration.milliseconds = input;\n        }\n    } else if (!!(match = aspNetRegex.exec(input))) {\n        sign = (match[1] === '-') ? -1 : 1;\n        duration = {\n            y  : 0,\n            d  : toInt(match[DATE])                         * sign,\n            h  : toInt(match[HOUR])                         * sign,\n            m  : toInt(match[MINUTE])                       * sign,\n            s  : toInt(match[SECOND])                       * sign,\n            ms : toInt(absRound(match[MILLISECOND] * 1000)) * sign // the millisecond decimal point is included in the match\n        };\n    } else if (!!(match = isoRegex.exec(input))) {\n        sign = (match[1] === '-') ? -1 : 1;\n        duration = {\n            y : parseIso(match[2], sign),\n            M : parseIso(match[3], sign),\n            w : parseIso(match[4], sign),\n            d : parseIso(match[5], sign),\n            h : parseIso(match[6], sign),\n            m : parseIso(match[7], sign),\n            s : parseIso(match[8], sign)\n        };\n    } else if (duration == null) {// checks for null or undefined\n        duration = {};\n    } else if (typeof duration === 'object' && ('from' in duration || 'to' in duration)) {\n        diffRes = momentsDifference(createLocal(duration.from), createLocal(duration.to));\n\n        duration = {};\n        duration.ms = diffRes.milliseconds;\n        duration.M = diffRes.months;\n    }\n\n    ret = new Duration(duration);\n\n    if (isDuration(input) && hasOwnProp(input, '_locale')) {\n        ret._locale = input._locale;\n    }\n\n    return ret;\n}\n\ncreateDuration.fn = Duration.prototype;\ncreateDuration.invalid = createInvalid$1;\n\nfunction parseIso (inp, sign) {\n    // We'd normally use ~~inp for this, but unfortunately it also\n    // converts floats to ints.\n    // inp may be undefined, so careful calling replace on it.\n    var res = inp && parseFloat(inp.replace(',', '.'));\n    // apply sign while we're at it\n    return (isNaN(res) ? 0 : res) * sign;\n}\n\nfunction positiveMomentsDifference(base, other) {\n    var res = {milliseconds: 0, months: 0};\n\n    res.months = other.month() - base.month() +\n        (other.year() - base.year()) * 12;\n    if (base.clone().add(res.months, 'M').isAfter(other)) {\n        --res.months;\n    }\n\n    res.milliseconds = +other - +(base.clone().add(res.months, 'M'));\n\n    return res;\n}\n\nfunction momentsDifference(base, other) {\n    var res;\n    if (!(base.isValid() && other.isValid())) {\n        return {milliseconds: 0, months: 0};\n    }\n\n    other = cloneWithOffset(other, base);\n    if (base.isBefore(other)) {\n        res = positiveMomentsDifference(base, other);\n    } else {\n        res = positiveMomentsDifference(other, base);\n        res.milliseconds = -res.milliseconds;\n        res.months = -res.months;\n    }\n\n    return res;\n}\n\n// TODO: remove 'name' arg after deprecation is removed\nfunction createAdder(direction, name) {\n    return function (val, period) {\n        var dur, tmp;\n        //invert the arguments, but complain about it\n        if (period !== null && !isNaN(+period)) {\n            deprecateSimple(name, 'moment().' + name  + '(period, number) is deprecated. Please use moment().' + name + '(number, period). ' +\n            'See http://momentjs.com/guides/#/warnings/add-inverted-param/ for more info.');\n            tmp = val; val = period; period = tmp;\n        }\n\n        val = typeof val === 'string' ? +val : val;\n        dur = createDuration(val, period);\n        addSubtract(this, dur, direction);\n        return this;\n    };\n}\n\nfunction addSubtract (mom, duration, isAdding, updateOffset) {\n    var milliseconds = duration._milliseconds,\n        days = absRound(duration._days),\n        months = absRound(duration._months);\n\n    if (!mom.isValid()) {\n        // No op\n        return;\n    }\n\n    updateOffset = updateOffset == null ? true : updateOffset;\n\n    if (milliseconds) {\n        mom._d.setTime(mom._d.valueOf() + milliseconds * isAdding);\n    }\n    if (days) {\n        set$1(mom, 'Date', get(mom, 'Date') + days * isAdding);\n    }\n    if (months) {\n        setMonth(mom, get(mom, 'Month') + months * isAdding);\n    }\n    if (updateOffset) {\n        hooks.updateOffset(mom, days || months);\n    }\n}\n\nvar add      = createAdder(1, 'add');\nvar subtract = createAdder(-1, 'subtract');\n\nfunction getCalendarFormat(myMoment, now) {\n    var diff = myMoment.diff(now, 'days', true);\n    return diff < -6 ? 'sameElse' :\n            diff < -1 ? 'lastWeek' :\n            diff < 0 ? 'lastDay' :\n            diff < 1 ? 'sameDay' :\n            diff < 2 ? 'nextDay' :\n            diff < 7 ? 'nextWeek' : 'sameElse';\n}\n\nfunction calendar$1 (time, formats) {\n    // We want to compare the start of today, vs this.\n    // Getting start-of-today depends on whether we're local/utc/offset or not.\n    var now = time || createLocal(),\n        sod = cloneWithOffset(now, this).startOf('day'),\n        format = hooks.calendarFormat(this, sod) || 'sameElse';\n\n    var output = formats && (isFunction(formats[format]) ? formats[format].call(this, now) : formats[format]);\n\n    return this.format(output || this.localeData().calendar(format, this, createLocal(now)));\n}\n\nfunction clone () {\n    return new Moment(this);\n}\n\nfunction isAfter (input, units) {\n    var localInput = isMoment(input) ? input : createLocal(input);\n    if (!(this.isValid() && localInput.isValid())) {\n        return false;\n    }\n    units = normalizeUnits(!isUndefined(units) ? units : 'millisecond');\n    if (units === 'millisecond') {\n        return this.valueOf() > localInput.valueOf();\n    } else {\n        return localInput.valueOf() < this.clone().startOf(units).valueOf();\n    }\n}\n\nfunction isBefore (input, units) {\n    var localInput = isMoment(input) ? input : createLocal(input);\n    if (!(this.isValid() && localInput.isValid())) {\n        return false;\n    }\n    units = normalizeUnits(!isUndefined(units) ? units : 'millisecond');\n    if (units === 'millisecond') {\n        return this.valueOf() < localInput.valueOf();\n    } else {\n        return this.clone().endOf(units).valueOf() < localInput.valueOf();\n    }\n}\n\nfunction isBetween (from, to, units, inclusivity) {\n    inclusivity = inclusivity || '()';\n    return (inclusivity[0] === '(' ? this.isAfter(from, units) : !this.isBefore(from, units)) &&\n        (inclusivity[1] === ')' ? this.isBefore(to, units) : !this.isAfter(to, units));\n}\n\nfunction isSame (input, units) {\n    var localInput = isMoment(input) ? input : createLocal(input),\n        inputMs;\n    if (!(this.isValid() && localInput.isValid())) {\n        return false;\n    }\n    units = normalizeUnits(units || 'millisecond');\n    if (units === 'millisecond') {\n        return this.valueOf() === localInput.valueOf();\n    } else {\n        inputMs = localInput.valueOf();\n        return this.clone().startOf(units).valueOf() <= inputMs && inputMs <= this.clone().endOf(units).valueOf();\n    }\n}\n\nfunction isSameOrAfter (input, units) {\n    return this.isSame(input, units) || this.isAfter(input,units);\n}\n\nfunction isSameOrBefore (input, units) {\n    return this.isSame(input, units) || this.isBefore(input,units);\n}\n\nfunction diff (input, units, asFloat) {\n    var that,\n        zoneDelta,\n        delta, output;\n\n    if (!this.isValid()) {\n        return NaN;\n    }\n\n    that = cloneWithOffset(input, this);\n\n    if (!that.isValid()) {\n        return NaN;\n    }\n\n    zoneDelta = (that.utcOffset() - this.utcOffset()) * 6e4;\n\n    units = normalizeUnits(units);\n\n    if (units === 'year' || units === 'month' || units === 'quarter') {\n        output = monthDiff(this, that);\n        if (units === 'quarter') {\n            output = output / 3;\n        } else if (units === 'year') {\n            output = output / 12;\n        }\n    } else {\n        delta = this - that;\n        output = units === 'second' ? delta / 1e3 : // 1000\n            units === 'minute' ? delta / 6e4 : // 1000 * 60\n            units === 'hour' ? delta / 36e5 : // 1000 * 60 * 60\n            units === 'day' ? (delta - zoneDelta) / 864e5 : // 1000 * 60 * 60 * 24, negate dst\n            units === 'week' ? (delta - zoneDelta) / 6048e5 : // 1000 * 60 * 60 * 24 * 7, negate dst\n            delta;\n    }\n    return asFloat ? output : absFloor(output);\n}\n\nfunction monthDiff (a, b) {\n    // difference in months\n    var wholeMonthDiff = ((b.year() - a.year()) * 12) + (b.month() - a.month()),\n        // b is in (anchor - 1 month, anchor + 1 month)\n        anchor = a.clone().add(wholeMonthDiff, 'months'),\n        anchor2, adjust;\n\n    if (b - anchor < 0) {\n        anchor2 = a.clone().add(wholeMonthDiff - 1, 'months');\n        // linear across the month\n        adjust = (b - anchor) / (anchor - anchor2);\n    } else {\n        anchor2 = a.clone().add(wholeMonthDiff + 1, 'months');\n        // linear across the month\n        adjust = (b - anchor) / (anchor2 - anchor);\n    }\n\n    //check for negative zero, return zero if negative zero\n    return -(wholeMonthDiff + adjust) || 0;\n}\n\nhooks.defaultFormat = 'YYYY-MM-DDTHH:mm:ssZ';\nhooks.defaultFormatUtc = 'YYYY-MM-DDTHH:mm:ss[Z]';\n\nfunction toString () {\n    return this.clone().locale('en').format('ddd MMM DD YYYY HH:mm:ss [GMT]ZZ');\n}\n\nfunction toISOString() {\n    if (!this.isValid()) {\n        return null;\n    }\n    var m = this.clone().utc();\n    if (m.year() < 0 || m.year() > 9999) {\n        return formatMoment(m, 'YYYYYY-MM-DD[T]HH:mm:ss.SSS[Z]');\n    }\n    if (isFunction(Date.prototype.toISOString)) {\n        // native implementation is ~50x faster, use it when we can\n        return this.toDate().toISOString();\n    }\n    return formatMoment(m, 'YYYY-MM-DD[T]HH:mm:ss.SSS[Z]');\n}\n\n/**\n * Return a human readable representation of a moment that can\n * also be evaluated to get a new moment which is the same\n *\n * @link https://nodejs.org/dist/latest/docs/api/util.html#util_custom_inspect_function_on_objects\n */\nfunction inspect () {\n    if (!this.isValid()) {\n        return 'moment.invalid(/* ' + this._i + ' */)';\n    }\n    var func = 'moment';\n    var zone = '';\n    if (!this.isLocal()) {\n        func = this.utcOffset() === 0 ? 'moment.utc' : 'moment.parseZone';\n        zone = 'Z';\n    }\n    var prefix = '[' + func + '(\"]';\n    var year = (0 <= this.year() && this.year() <= 9999) ? 'YYYY' : 'YYYYYY';\n    var datetime = '-MM-DD[T]HH:mm:ss.SSS';\n    var suffix = zone + '[\")]';\n\n    return this.format(prefix + year + datetime + suffix);\n}\n\nfunction format (inputString) {\n    if (!inputString) {\n        inputString = this.isUtc() ? hooks.defaultFormatUtc : hooks.defaultFormat;\n    }\n    var output = formatMoment(this, inputString);\n    return this.localeData().postformat(output);\n}\n\nfunction from (time, withoutSuffix) {\n    if (this.isValid() &&\n            ((isMoment(time) && time.isValid()) ||\n             createLocal(time).isValid())) {\n        return createDuration({to: this, from: time}).locale(this.locale()).humanize(!withoutSuffix);\n    } else {\n        return this.localeData().invalidDate();\n    }\n}\n\nfunction fromNow (withoutSuffix) {\n    return this.from(createLocal(), withoutSuffix);\n}\n\nfunction to (time, withoutSuffix) {\n    if (this.isValid() &&\n            ((isMoment(time) && time.isValid()) ||\n             createLocal(time).isValid())) {\n        return createDuration({from: this, to: time}).locale(this.locale()).humanize(!withoutSuffix);\n    } else {\n        return this.localeData().invalidDate();\n    }\n}\n\nfunction toNow (withoutSuffix) {\n    return this.to(createLocal(), withoutSuffix);\n}\n\n// If passed a locale key, it will set the locale for this\n// instance.  Otherwise, it will return the locale configuration\n// variables for this instance.\nfunction locale (key) {\n    var newLocaleData;\n\n    if (key === undefined) {\n        return this._locale._abbr;\n    } else {\n        newLocaleData = getLocale(key);\n        if (newLocaleData != null) {\n            this._locale = newLocaleData;\n        }\n        return this;\n    }\n}\n\nvar lang = deprecate(\n    'moment().lang() is deprecated. Instead, use moment().localeData() to get the language configuration. Use moment().locale() to change languages.',\n    function (key) {\n        if (key === undefined) {\n            return this.localeData();\n        } else {\n            return this.locale(key);\n        }\n    }\n);\n\nfunction localeData () {\n    return this._locale;\n}\n\nfunction startOf (units) {\n    units = normalizeUnits(units);\n    // the following switch intentionally omits break keywords\n    // to utilize falling through the cases.\n    switch (units) {\n        case 'year':\n            this.month(0);\n            /* falls through */\n        case 'quarter':\n        case 'month':\n            this.date(1);\n            /* falls through */\n        case 'week':\n        case 'isoWeek':\n        case 'day':\n        case 'date':\n            this.hours(0);\n            /* falls through */\n        case 'hour':\n            this.minutes(0);\n            /* falls through */\n        case 'minute':\n            this.seconds(0);\n            /* falls through */\n        case 'second':\n            this.milliseconds(0);\n    }\n\n    // weeks are a special case\n    if (units === 'week') {\n        this.weekday(0);\n    }\n    if (units === 'isoWeek') {\n        this.isoWeekday(1);\n    }\n\n    // quarters are also special\n    if (units === 'quarter') {\n        this.month(Math.floor(this.month() / 3) * 3);\n    }\n\n    return this;\n}\n\nfunction endOf (units) {\n    units = normalizeUnits(units);\n    if (units === undefined || units === 'millisecond') {\n        return this;\n    }\n\n    // 'date' is an alias for 'day', so it should be considered as such.\n    if (units === 'date') {\n        units = 'day';\n    }\n\n    return this.startOf(units).add(1, (units === 'isoWeek' ? 'week' : units)).subtract(1, 'ms');\n}\n\nfunction valueOf () {\n    return this._d.valueOf() - ((this._offset || 0) * 60000);\n}\n\nfunction unix () {\n    return Math.floor(this.valueOf() / 1000);\n}\n\nfunction toDate () {\n    return new Date(this.valueOf());\n}\n\nfunction toArray () {\n    var m = this;\n    return [m.year(), m.month(), m.date(), m.hour(), m.minute(), m.second(), m.millisecond()];\n}\n\nfunction toObject () {\n    var m = this;\n    return {\n        years: m.year(),\n        months: m.month(),\n        date: m.date(),\n        hours: m.hours(),\n        minutes: m.minutes(),\n        seconds: m.seconds(),\n        milliseconds: m.milliseconds()\n    };\n}\n\nfunction toJSON () {\n    // new Date(NaN).toJSON() === null\n    return this.isValid() ? this.toISOString() : null;\n}\n\nfunction isValid$2 () {\n    return isValid(this);\n}\n\nfunction parsingFlags () {\n    return extend({}, getParsingFlags(this));\n}\n\nfunction invalidAt () {\n    return getParsingFlags(this).overflow;\n}\n\nfunction creationData() {\n    return {\n        input: this._i,\n        format: this._f,\n        locale: this._locale,\n        isUTC: this._isUTC,\n        strict: this._strict\n    };\n}\n\n// FORMATTING\n\naddFormatToken(0, ['gg', 2], 0, function () {\n    return this.weekYear() % 100;\n});\n\naddFormatToken(0, ['GG', 2], 0, function () {\n    return this.isoWeekYear() % 100;\n});\n\nfunction addWeekYearFormatToken (token, getter) {\n    addFormatToken(0, [token, token.length], 0, getter);\n}\n\naddWeekYearFormatToken('gggg',     'weekYear');\naddWeekYearFormatToken('ggggg',    'weekYear');\naddWeekYearFormatToken('GGGG',  'isoWeekYear');\naddWeekYearFormatToken('GGGGG', 'isoWeekYear');\n\n// ALIASES\n\naddUnitAlias('weekYear', 'gg');\naddUnitAlias('isoWeekYear', 'GG');\n\n// PRIORITY\n\naddUnitPriority('weekYear', 1);\naddUnitPriority('isoWeekYear', 1);\n\n\n// PARSING\n\naddRegexToken('G',      matchSigned);\naddRegexToken('g',      matchSigned);\naddRegexToken('GG',     match1to2, match2);\naddRegexToken('gg',     match1to2, match2);\naddRegexToken('GGGG',   match1to4, match4);\naddRegexToken('gggg',   match1to4, match4);\naddRegexToken('GGGGG',  match1to6, match6);\naddRegexToken('ggggg',  match1to6, match6);\n\naddWeekParseToken(['gggg', 'ggggg', 'GGGG', 'GGGGG'], function (input, week, config, token) {\n    week[token.substr(0, 2)] = toInt(input);\n});\n\naddWeekParseToken(['gg', 'GG'], function (input, week, config, token) {\n    week[token] = hooks.parseTwoDigitYear(input);\n});\n\n// MOMENTS\n\nfunction getSetWeekYear (input) {\n    return getSetWeekYearHelper.call(this,\n            input,\n            this.week(),\n            this.weekday(),\n            this.localeData()._week.dow,\n            this.localeData()._week.doy);\n}\n\nfunction getSetISOWeekYear (input) {\n    return getSetWeekYearHelper.call(this,\n            input, this.isoWeek(), this.isoWeekday(), 1, 4);\n}\n\nfunction getISOWeeksInYear () {\n    return weeksInYear(this.year(), 1, 4);\n}\n\nfunction getWeeksInYear () {\n    var weekInfo = this.localeData()._week;\n    return weeksInYear(this.year(), weekInfo.dow, weekInfo.doy);\n}\n\nfunction getSetWeekYearHelper(input, week, weekday, dow, doy) {\n    var weeksTarget;\n    if (input == null) {\n        return weekOfYear(this, dow, doy).year;\n    } else {\n        weeksTarget = weeksInYear(input, dow, doy);\n        if (week > weeksTarget) {\n            week = weeksTarget;\n        }\n        return setWeekAll.call(this, input, week, weekday, dow, doy);\n    }\n}\n\nfunction setWeekAll(weekYear, week, weekday, dow, doy) {\n    var dayOfYearData = dayOfYearFromWeeks(weekYear, week, weekday, dow, doy),\n        date = createUTCDate(dayOfYearData.year, 0, dayOfYearData.dayOfYear);\n\n    this.year(date.getUTCFullYear());\n    this.month(date.getUTCMonth());\n    this.date(date.getUTCDate());\n    return this;\n}\n\n// FORMATTING\n\naddFormatToken('Q', 0, 'Qo', 'quarter');\n\n// ALIASES\n\naddUnitAlias('quarter', 'Q');\n\n// PRIORITY\n\naddUnitPriority('quarter', 7);\n\n// PARSING\n\naddRegexToken('Q', match1);\naddParseToken('Q', function (input, array) {\n    array[MONTH] = (toInt(input) - 1) * 3;\n});\n\n// MOMENTS\n\nfunction getSetQuarter (input) {\n    return input == null ? Math.ceil((this.month() + 1) / 3) : this.month((input - 1) * 3 + this.month() % 3);\n}\n\n// FORMATTING\n\naddFormatToken('D', ['DD', 2], 'Do', 'date');\n\n// ALIASES\n\naddUnitAlias('date', 'D');\n\n// PRIOROITY\naddUnitPriority('date', 9);\n\n// PARSING\n\naddRegexToken('D',  match1to2);\naddRegexToken('DD', match1to2, match2);\naddRegexToken('Do', function (isStrict, locale) {\n    // TODO: Remove \"ordinalParse\" fallback in next major release.\n    return isStrict ?\n      (locale._dayOfMonthOrdinalParse || locale._ordinalParse) :\n      locale._dayOfMonthOrdinalParseLenient;\n});\n\naddParseToken(['D', 'DD'], DATE);\naddParseToken('Do', function (input, array) {\n    array[DATE] = toInt(input.match(match1to2)[0], 10);\n});\n\n// MOMENTS\n\nvar getSetDayOfMonth = makeGetSet('Date', true);\n\n// FORMATTING\n\naddFormatToken('DDD', ['DDDD', 3], 'DDDo', 'dayOfYear');\n\n// ALIASES\n\naddUnitAlias('dayOfYear', 'DDD');\n\n// PRIORITY\naddUnitPriority('dayOfYear', 4);\n\n// PARSING\n\naddRegexToken('DDD',  match1to3);\naddRegexToken('DDDD', match3);\naddParseToken(['DDD', 'DDDD'], function (input, array, config) {\n    config._dayOfYear = toInt(input);\n});\n\n// HELPERS\n\n// MOMENTS\n\nfunction getSetDayOfYear (input) {\n    var dayOfYear = Math.round((this.clone().startOf('day') - this.clone().startOf('year')) / 864e5) + 1;\n    return input == null ? dayOfYear : this.add((input - dayOfYear), 'd');\n}\n\n// FORMATTING\n\naddFormatToken('m', ['mm', 2], 0, 'minute');\n\n// ALIASES\n\naddUnitAlias('minute', 'm');\n\n// PRIORITY\n\naddUnitPriority('minute', 14);\n\n// PARSING\n\naddRegexToken('m',  match1to2);\naddRegexToken('mm', match1to2, match2);\naddParseToken(['m', 'mm'], MINUTE);\n\n// MOMENTS\n\nvar getSetMinute = makeGetSet('Minutes', false);\n\n// FORMATTING\n\naddFormatToken('s', ['ss', 2], 0, 'second');\n\n// ALIASES\n\naddUnitAlias('second', 's');\n\n// PRIORITY\n\naddUnitPriority('second', 15);\n\n// PARSING\n\naddRegexToken('s',  match1to2);\naddRegexToken('ss', match1to2, match2);\naddParseToken(['s', 'ss'], SECOND);\n\n// MOMENTS\n\nvar getSetSecond = makeGetSet('Seconds', false);\n\n// FORMATTING\n\naddFormatToken('S', 0, 0, function () {\n    return ~~(this.millisecond() / 100);\n});\n\naddFormatToken(0, ['SS', 2], 0, function () {\n    return ~~(this.millisecond() / 10);\n});\n\naddFormatToken(0, ['SSS', 3], 0, 'millisecond');\naddFormatToken(0, ['SSSS', 4], 0, function () {\n    return this.millisecond() * 10;\n});\naddFormatToken(0, ['SSSSS', 5], 0, function () {\n    return this.millisecond() * 100;\n});\naddFormatToken(0, ['SSSSSS', 6], 0, function () {\n    return this.millisecond() * 1000;\n});\naddFormatToken(0, ['SSSSSSS', 7], 0, function () {\n    return this.millisecond() * 10000;\n});\naddFormatToken(0, ['SSSSSSSS', 8], 0, function () {\n    return this.millisecond() * 100000;\n});\naddFormatToken(0, ['SSSSSSSSS', 9], 0, function () {\n    return this.millisecond() * 1000000;\n});\n\n\n// ALIASES\n\naddUnitAlias('millisecond', 'ms');\n\n// PRIORITY\n\naddUnitPriority('millisecond', 16);\n\n// PARSING\n\naddRegexToken('S',    match1to3, match1);\naddRegexToken('SS',   match1to3, match2);\naddRegexToken('SSS',  match1to3, match3);\n\nvar token;\nfor (token = 'SSSS'; token.length <= 9; token += 'S') {\n    addRegexToken(token, matchUnsigned);\n}\n\nfunction parseMs(input, array) {\n    array[MILLISECOND] = toInt(('0.' + input) * 1000);\n}\n\nfor (token = 'S'; token.length <= 9; token += 'S') {\n    addParseToken(token, parseMs);\n}\n// MOMENTS\n\nvar getSetMillisecond = makeGetSet('Milliseconds', false);\n\n// FORMATTING\n\naddFormatToken('z',  0, 0, 'zoneAbbr');\naddFormatToken('zz', 0, 0, 'zoneName');\n\n// MOMENTS\n\nfunction getZoneAbbr () {\n    return this._isUTC ? 'UTC' : '';\n}\n\nfunction getZoneName () {\n    return this._isUTC ? 'Coordinated Universal Time' : '';\n}\n\nvar proto = Moment.prototype;\n\nproto.add               = add;\nproto.calendar          = calendar$1;\nproto.clone             = clone;\nproto.diff              = diff;\nproto.endOf             = endOf;\nproto.format            = format;\nproto.from              = from;\nproto.fromNow           = fromNow;\nproto.to                = to;\nproto.toNow             = toNow;\nproto.get               = stringGet;\nproto.invalidAt         = invalidAt;\nproto.isAfter           = isAfter;\nproto.isBefore          = isBefore;\nproto.isBetween         = isBetween;\nproto.isSame            = isSame;\nproto.isSameOrAfter     = isSameOrAfter;\nproto.isSameOrBefore    = isSameOrBefore;\nproto.isValid           = isValid$2;\nproto.lang              = lang;\nproto.locale            = locale;\nproto.localeData        = localeData;\nproto.max               = prototypeMax;\nproto.min               = prototypeMin;\nproto.parsingFlags      = parsingFlags;\nproto.set               = stringSet;\nproto.startOf           = startOf;\nproto.subtract          = subtract;\nproto.toArray           = toArray;\nproto.toObject          = toObject;\nproto.toDate            = toDate;\nproto.toISOString       = toISOString;\nproto.inspect           = inspect;\nproto.toJSON            = toJSON;\nproto.toString          = toString;\nproto.unix              = unix;\nproto.valueOf           = valueOf;\nproto.creationData      = creationData;\n\n// Year\nproto.year       = getSetYear;\nproto.isLeapYear = getIsLeapYear;\n\n// Week Year\nproto.weekYear    = getSetWeekYear;\nproto.isoWeekYear = getSetISOWeekYear;\n\n// Quarter\nproto.quarter = proto.quarters = getSetQuarter;\n\n// Month\nproto.month       = getSetMonth;\nproto.daysInMonth = getDaysInMonth;\n\n// Week\nproto.week           = proto.weeks        = getSetWeek;\nproto.isoWeek        = proto.isoWeeks     = getSetISOWeek;\nproto.weeksInYear    = getWeeksInYear;\nproto.isoWeeksInYear = getISOWeeksInYear;\n\n// Day\nproto.date       = getSetDayOfMonth;\nproto.day        = proto.days             = getSetDayOfWeek;\nproto.weekday    = getSetLocaleDayOfWeek;\nproto.isoWeekday = getSetISODayOfWeek;\nproto.dayOfYear  = getSetDayOfYear;\n\n// Hour\nproto.hour = proto.hours = getSetHour;\n\n// Minute\nproto.minute = proto.minutes = getSetMinute;\n\n// Second\nproto.second = proto.seconds = getSetSecond;\n\n// Millisecond\nproto.millisecond = proto.milliseconds = getSetMillisecond;\n\n// Offset\nproto.utcOffset            = getSetOffset;\nproto.utc                  = setOffsetToUTC;\nproto.local                = setOffsetToLocal;\nproto.parseZone            = setOffsetToParsedOffset;\nproto.hasAlignedHourOffset = hasAlignedHourOffset;\nproto.isDST                = isDaylightSavingTime;\nproto.isLocal              = isLocal;\nproto.isUtcOffset          = isUtcOffset;\nproto.isUtc                = isUtc;\nproto.isUTC                = isUtc;\n\n// Timezone\nproto.zoneAbbr = getZoneAbbr;\nproto.zoneName = getZoneName;\n\n// Deprecations\nproto.dates  = deprecate('dates accessor is deprecated. Use date instead.', getSetDayOfMonth);\nproto.months = deprecate('months accessor is deprecated. Use month instead', getSetMonth);\nproto.years  = deprecate('years accessor is deprecated. Use year instead', getSetYear);\nproto.zone   = deprecate('moment().zone is deprecated, use moment().utcOffset instead. http://momentjs.com/guides/#/warnings/zone/', getSetZone);\nproto.isDSTShifted = deprecate('isDSTShifted is deprecated. See http://momentjs.com/guides/#/warnings/dst-shifted/ for more information', isDaylightSavingTimeShifted);\n\nfunction createUnix (input) {\n    return createLocal(input * 1000);\n}\n\nfunction createInZone () {\n    return createLocal.apply(null, arguments).parseZone();\n}\n\nfunction preParsePostFormat (string) {\n    return string;\n}\n\nvar proto$1 = Locale.prototype;\n\nproto$1.calendar        = calendar;\nproto$1.longDateFormat  = longDateFormat;\nproto$1.invalidDate     = invalidDate;\nproto$1.ordinal         = ordinal;\nproto$1.preparse        = preParsePostFormat;\nproto$1.postformat      = preParsePostFormat;\nproto$1.relativeTime    = relativeTime;\nproto$1.pastFuture      = pastFuture;\nproto$1.set             = set;\n\n// Month\nproto$1.months            =        localeMonths;\nproto$1.monthsShort       =        localeMonthsShort;\nproto$1.monthsParse       =        localeMonthsParse;\nproto$1.monthsRegex       = monthsRegex;\nproto$1.monthsShortRegex  = monthsShortRegex;\n\n// Week\nproto$1.week = localeWeek;\nproto$1.firstDayOfYear = localeFirstDayOfYear;\nproto$1.firstDayOfWeek = localeFirstDayOfWeek;\n\n// Day of Week\nproto$1.weekdays       =        localeWeekdays;\nproto$1.weekdaysMin    =        localeWeekdaysMin;\nproto$1.weekdaysShort  =        localeWeekdaysShort;\nproto$1.weekdaysParse  =        localeWeekdaysParse;\n\nproto$1.weekdaysRegex       =        weekdaysRegex;\nproto$1.weekdaysShortRegex  =        weekdaysShortRegex;\nproto$1.weekdaysMinRegex    =        weekdaysMinRegex;\n\n// Hours\nproto$1.isPM = localeIsPM;\nproto$1.meridiem = localeMeridiem;\n\nfunction get$1 (format, index, field, setter) {\n    var locale = getLocale();\n    var utc = createUTC().set(setter, index);\n    return locale[field](utc, format);\n}\n\nfunction listMonthsImpl (format, index, field) {\n    if (isNumber(format)) {\n        index = format;\n        format = undefined;\n    }\n\n    format = format || '';\n\n    if (index != null) {\n        return get$1(format, index, field, 'month');\n    }\n\n    var i;\n    var out = [];\n    for (i = 0; i < 12; i++) {\n        out[i] = get$1(format, i, field, 'month');\n    }\n    return out;\n}\n\n// ()\n// (5)\n// (fmt, 5)\n// (fmt)\n// (true)\n// (true, 5)\n// (true, fmt, 5)\n// (true, fmt)\nfunction listWeekdaysImpl (localeSorted, format, index, field) {\n    if (typeof localeSorted === 'boolean') {\n        if (isNumber(format)) {\n            index = format;\n            format = undefined;\n        }\n\n        format = format || '';\n    } else {\n        format = localeSorted;\n        index = format;\n        localeSorted = false;\n\n        if (isNumber(format)) {\n            index = format;\n            format = undefined;\n        }\n\n        format = format || '';\n    }\n\n    var locale = getLocale(),\n        shift = localeSorted ? locale._week.dow : 0;\n\n    if (index != null) {\n        return get$1(format, (index + shift) % 7, field, 'day');\n    }\n\n    var i;\n    var out = [];\n    for (i = 0; i < 7; i++) {\n        out[i] = get$1(format, (i + shift) % 7, field, 'day');\n    }\n    return out;\n}\n\nfunction listMonths (format, index) {\n    return listMonthsImpl(format, index, 'months');\n}\n\nfunction listMonthsShort (format, index) {\n    return listMonthsImpl(format, index, 'monthsShort');\n}\n\nfunction listWeekdays (localeSorted, format, index) {\n    return listWeekdaysImpl(localeSorted, format, index, 'weekdays');\n}\n\nfunction listWeekdaysShort (localeSorted, format, index) {\n    return listWeekdaysImpl(localeSorted, format, index, 'weekdaysShort');\n}\n\nfunction listWeekdaysMin (localeSorted, format, index) {\n    return listWeekdaysImpl(localeSorted, format, index, 'weekdaysMin');\n}\n\ngetSetGlobalLocale('en', {\n    dayOfMonthOrdinalParse: /\\d{1,2}(th|st|nd|rd)/,\n    ordinal : function (number) {\n        var b = number % 10,\n            output = (toInt(number % 100 / 10) === 1) ? 'th' :\n            (b === 1) ? 'st' :\n            (b === 2) ? 'nd' :\n            (b === 3) ? 'rd' : 'th';\n        return number + output;\n    }\n});\n\n// Side effect imports\nhooks.lang = deprecate('moment.lang is deprecated. Use moment.locale instead.', getSetGlobalLocale);\nhooks.langData = deprecate('moment.langData is deprecated. Use moment.localeData instead.', getLocale);\n\nvar mathAbs = Math.abs;\n\nfunction abs () {\n    var data           = this._data;\n\n    this._milliseconds = mathAbs(this._milliseconds);\n    this._days         = mathAbs(this._days);\n    this._months       = mathAbs(this._months);\n\n    data.milliseconds  = mathAbs(data.milliseconds);\n    data.seconds       = mathAbs(data.seconds);\n    data.minutes       = mathAbs(data.minutes);\n    data.hours         = mathAbs(data.hours);\n    data.months        = mathAbs(data.months);\n    data.years         = mathAbs(data.years);\n\n    return this;\n}\n\nfunction addSubtract$1 (duration, input, value, direction) {\n    var other = createDuration(input, value);\n\n    duration._milliseconds += direction * other._milliseconds;\n    duration._days         += direction * other._days;\n    duration._months       += direction * other._months;\n\n    return duration._bubble();\n}\n\n// supports only 2.0-style add(1, 's') or add(duration)\nfunction add$1 (input, value) {\n    return addSubtract$1(this, input, value, 1);\n}\n\n// supports only 2.0-style subtract(1, 's') or subtract(duration)\nfunction subtract$1 (input, value) {\n    return addSubtract$1(this, input, value, -1);\n}\n\nfunction absCeil (number) {\n    if (number < 0) {\n        return Math.floor(number);\n    } else {\n        return Math.ceil(number);\n    }\n}\n\nfunction bubble () {\n    var milliseconds = this._milliseconds;\n    var days         = this._days;\n    var months       = this._months;\n    var data         = this._data;\n    var seconds, minutes, hours, years, monthsFromDays;\n\n    // if we have a mix of positive and negative values, bubble down first\n    // check: https://github.com/moment/moment/issues/2166\n    if (!((milliseconds >= 0 && days >= 0 && months >= 0) ||\n            (milliseconds <= 0 && days <= 0 && months <= 0))) {\n        milliseconds += absCeil(monthsToDays(months) + days) * 864e5;\n        days = 0;\n        months = 0;\n    }\n\n    // The following code bubbles up values, see the tests for\n    // examples of what that means.\n    data.milliseconds = milliseconds % 1000;\n\n    seconds           = absFloor(milliseconds / 1000);\n    data.seconds      = seconds % 60;\n\n    minutes           = absFloor(seconds / 60);\n    data.minutes      = minutes % 60;\n\n    hours             = absFloor(minutes / 60);\n    data.hours        = hours % 24;\n\n    days += absFloor(hours / 24);\n\n    // convert days to months\n    monthsFromDays = absFloor(daysToMonths(days));\n    months += monthsFromDays;\n    days -= absCeil(monthsToDays(monthsFromDays));\n\n    // 12 months -> 1 year\n    years = absFloor(months / 12);\n    months %= 12;\n\n    data.days   = days;\n    data.months = months;\n    data.years  = years;\n\n    return this;\n}\n\nfunction daysToMonths (days) {\n    // 400 years have 146097 days (taking into account leap year rules)\n    // 400 years have 12 months === 4800\n    return days * 4800 / 146097;\n}\n\nfunction monthsToDays (months) {\n    // the reverse of daysToMonths\n    return months * 146097 / 4800;\n}\n\nfunction as (units) {\n    if (!this.isValid()) {\n        return NaN;\n    }\n    var days;\n    var months;\n    var milliseconds = this._milliseconds;\n\n    units = normalizeUnits(units);\n\n    if (units === 'month' || units === 'year') {\n        days   = this._days   + milliseconds / 864e5;\n        months = this._months + daysToMonths(days);\n        return units === 'month' ? months : months / 12;\n    } else {\n        // handle milliseconds separately because of floating point math errors (issue #1867)\n        days = this._days + Math.round(monthsToDays(this._months));\n        switch (units) {\n            case 'week'   : return days / 7     + milliseconds / 6048e5;\n            case 'day'    : return days         + milliseconds / 864e5;\n            case 'hour'   : return days * 24    + milliseconds / 36e5;\n            case 'minute' : return days * 1440  + milliseconds / 6e4;\n            case 'second' : return days * 86400 + milliseconds / 1000;\n            // Math.floor prevents floating point math errors here\n            case 'millisecond': return Math.floor(days * 864e5) + milliseconds;\n            default: throw new Error('Unknown unit ' + units);\n        }\n    }\n}\n\n// TODO: Use this.as('ms')?\nfunction valueOf$1 () {\n    if (!this.isValid()) {\n        return NaN;\n    }\n    return (\n        this._milliseconds +\n        this._days * 864e5 +\n        (this._months % 12) * 2592e6 +\n        toInt(this._months / 12) * 31536e6\n    );\n}\n\nfunction makeAs (alias) {\n    return function () {\n        return this.as(alias);\n    };\n}\n\nvar asMilliseconds = makeAs('ms');\nvar asSeconds      = makeAs('s');\nvar asMinutes      = makeAs('m');\nvar asHours        = makeAs('h');\nvar asDays         = makeAs('d');\nvar asWeeks        = makeAs('w');\nvar asMonths       = makeAs('M');\nvar asYears        = makeAs('y');\n\nfunction get$2 (units) {\n    units = normalizeUnits(units);\n    return this.isValid() ? this[units + 's']() : NaN;\n}\n\nfunction makeGetter(name) {\n    return function () {\n        return this.isValid() ? this._data[name] : NaN;\n    };\n}\n\nvar milliseconds = makeGetter('milliseconds');\nvar seconds      = makeGetter('seconds');\nvar minutes      = makeGetter('minutes');\nvar hours        = makeGetter('hours');\nvar days         = makeGetter('days');\nvar months       = makeGetter('months');\nvar years        = makeGetter('years');\n\nfunction weeks () {\n    return absFloor(this.days() / 7);\n}\n\nvar round = Math.round;\nvar thresholds = {\n    ss: 44,         // a few seconds to seconds\n    s : 45,         // seconds to minute\n    m : 45,         // minutes to hour\n    h : 22,         // hours to day\n    d : 26,         // days to month\n    M : 11          // months to year\n};\n\n// helper function for moment.fn.from, moment.fn.fromNow, and moment.duration.fn.humanize\nfunction substituteTimeAgo(string, number, withoutSuffix, isFuture, locale) {\n    return locale.relativeTime(number || 1, !!withoutSuffix, string, isFuture);\n}\n\nfunction relativeTime$1 (posNegDuration, withoutSuffix, locale) {\n    var duration = createDuration(posNegDuration).abs();\n    var seconds  = round(duration.as('s'));\n    var minutes  = round(duration.as('m'));\n    var hours    = round(duration.as('h'));\n    var days     = round(duration.as('d'));\n    var months   = round(duration.as('M'));\n    var years    = round(duration.as('y'));\n\n    var a = seconds <= thresholds.ss && ['s', seconds]  ||\n            seconds < thresholds.s   && ['ss', seconds] ||\n            minutes <= 1             && ['m']           ||\n            minutes < thresholds.m   && ['mm', minutes] ||\n            hours   <= 1             && ['h']           ||\n            hours   < thresholds.h   && ['hh', hours]   ||\n            days    <= 1             && ['d']           ||\n            days    < thresholds.d   && ['dd', days]    ||\n            months  <= 1             && ['M']           ||\n            months  < thresholds.M   && ['MM', months]  ||\n            years   <= 1             && ['y']           || ['yy', years];\n\n    a[2] = withoutSuffix;\n    a[3] = +posNegDuration > 0;\n    a[4] = locale;\n    return substituteTimeAgo.apply(null, a);\n}\n\n// This function allows you to set the rounding function for relative time strings\nfunction getSetRelativeTimeRounding (roundingFunction) {\n    if (roundingFunction === undefined) {\n        return round;\n    }\n    if (typeof(roundingFunction) === 'function') {\n        round = roundingFunction;\n        return true;\n    }\n    return false;\n}\n\n// This function allows you to set a threshold for relative time strings\nfunction getSetRelativeTimeThreshold (threshold, limit) {\n    if (thresholds[threshold] === undefined) {\n        return false;\n    }\n    if (limit === undefined) {\n        return thresholds[threshold];\n    }\n    thresholds[threshold] = limit;\n    if (threshold === 's') {\n        thresholds.ss = limit - 1;\n    }\n    return true;\n}\n\nfunction humanize (withSuffix) {\n    if (!this.isValid()) {\n        return this.localeData().invalidDate();\n    }\n\n    var locale = this.localeData();\n    var output = relativeTime$1(this, !withSuffix, locale);\n\n    if (withSuffix) {\n        output = locale.pastFuture(+this, output);\n    }\n\n    return locale.postformat(output);\n}\n\nvar abs$1 = Math.abs;\n\nfunction toISOString$1() {\n    // for ISO strings we do not use the normal bubbling rules:\n    //  * milliseconds bubble up until they become hours\n    //  * days do not bubble at all\n    //  * months bubble up until they become years\n    // This is because there is no context-free conversion between hours and days\n    // (think of clock changes)\n    // and also not between days and months (28-31 days per month)\n    if (!this.isValid()) {\n        return this.localeData().invalidDate();\n    }\n\n    var seconds = abs$1(this._milliseconds) / 1000;\n    var days         = abs$1(this._days);\n    var months       = abs$1(this._months);\n    var minutes, hours, years;\n\n    // 3600 seconds -> 60 minutes -> 1 hour\n    minutes           = absFloor(seconds / 60);\n    hours             = absFloor(minutes / 60);\n    seconds %= 60;\n    minutes %= 60;\n\n    // 12 months -> 1 year\n    years  = absFloor(months / 12);\n    months %= 12;\n\n\n    // inspired by https://github.com/dordille/moment-isoduration/blob/master/moment.isoduration.js\n    var Y = years;\n    var M = months;\n    var D = days;\n    var h = hours;\n    var m = minutes;\n    var s = seconds;\n    var total = this.asSeconds();\n\n    if (!total) {\n        // this is the same as C#'s (Noda) and python (isodate)...\n        // but not other JS (goog.date)\n        return 'P0D';\n    }\n\n    return (total < 0 ? '-' : '') +\n        'P' +\n        (Y ? Y + 'Y' : '') +\n        (M ? M + 'M' : '') +\n        (D ? D + 'D' : '') +\n        ((h || m || s) ? 'T' : '') +\n        (h ? h + 'H' : '') +\n        (m ? m + 'M' : '') +\n        (s ? s + 'S' : '');\n}\n\nvar proto$2 = Duration.prototype;\n\nproto$2.isValid        = isValid$1;\nproto$2.abs            = abs;\nproto$2.add            = add$1;\nproto$2.subtract       = subtract$1;\nproto$2.as             = as;\nproto$2.asMilliseconds = asMilliseconds;\nproto$2.asSeconds      = asSeconds;\nproto$2.asMinutes      = asMinutes;\nproto$2.asHours        = asHours;\nproto$2.asDays         = asDays;\nproto$2.asWeeks        = asWeeks;\nproto$2.asMonths       = asMonths;\nproto$2.asYears        = asYears;\nproto$2.valueOf        = valueOf$1;\nproto$2._bubble        = bubble;\nproto$2.get            = get$2;\nproto$2.milliseconds   = milliseconds;\nproto$2.seconds        = seconds;\nproto$2.minutes        = minutes;\nproto$2.hours          = hours;\nproto$2.days           = days;\nproto$2.weeks          = weeks;\nproto$2.months         = months;\nproto$2.years          = years;\nproto$2.humanize       = humanize;\nproto$2.toISOString    = toISOString$1;\nproto$2.toString       = toISOString$1;\nproto$2.toJSON         = toISOString$1;\nproto$2.locale         = locale;\nproto$2.localeData     = localeData;\n\n// Deprecations\nproto$2.toIsoString = deprecate('toIsoString() is deprecated. Please use toISOString() instead (notice the capitals)', toISOString$1);\nproto$2.lang = lang;\n\n// Side effect imports\n\n// FORMATTING\n\naddFormatToken('X', 0, 0, 'unix');\naddFormatToken('x', 0, 0, 'valueOf');\n\n// PARSING\n\naddRegexToken('x', matchSigned);\naddRegexToken('X', matchTimestamp);\naddParseToken('X', function (input, array, config) {\n    config._d = new Date(parseFloat(input, 10) * 1000);\n});\naddParseToken('x', function (input, array, config) {\n    config._d = new Date(toInt(input));\n});\n\n// Side effect imports\n\n\nhooks.version = '2.18.1';\n\nsetHookCallback(createLocal);\n\nhooks.fn                    = proto;\nhooks.min                   = min;\nhooks.max                   = max;\nhooks.now                   = now;\nhooks.utc                   = createUTC;\nhooks.unix                  = createUnix;\nhooks.months                = listMonths;\nhooks.isDate                = isDate;\nhooks.locale                = getSetGlobalLocale;\nhooks.invalid               = createInvalid;\nhooks.duration              = createDuration;\nhooks.isMoment              = isMoment;\nhooks.weekdays              = listWeekdays;\nhooks.parseZone             = createInZone;\nhooks.localeData            = getLocale;\nhooks.isDuration            = isDuration;\nhooks.monthsShort           = listMonthsShort;\nhooks.weekdaysMin           = listWeekdaysMin;\nhooks.defineLocale          = defineLocale;\nhooks.updateLocale          = updateLocale;\nhooks.locales               = listLocales;\nhooks.weekdaysShort         = listWeekdaysShort;\nhooks.normalizeUnits        = normalizeUnits;\nhooks.relativeTimeRounding = getSetRelativeTimeRounding;\nhooks.relativeTimeThreshold = getSetRelativeTimeThreshold;\nhooks.calendarFormat        = getCalendarFormat;\nhooks.prototype             = proto;\n\nreturn hooks;\n\n})));\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/meteor/package.js",
    "content": "// package metadata file for Meteor.js\n'use strict';\n\nvar packageName = 'momentjs:moment';  // https://atmospherejs.com/momentjs/moment\n\nPackage.describe({\n  name: packageName,\n  summary: 'Moment.js (official): parse, validate, manipulate, and display dates - official Meteor packaging',\n  version: '2.18.1',\n  git: 'https://github.com/moment/moment.git'\n});\n\nPackage.onUse(function (api) {\n  api.versionsFrom(['METEOR@0.9.0', 'METEOR@1.0', 'METEOR@1.2']);\n  api.export('moment');\n  api.addFiles([\n    'moment.js',\n    'export.js'\n  ]);\n});\n\nPackage.onTest(function (api) {\n  api.use(packageName);\n  api.use('tinytest');\n\n  api.addFiles('test.js');\n});\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/meteor/test.js",
    "content": "'use strict';\n\nTinytest.add('Moment.is', function (test) {\n  test.ok(moment.isMoment(moment()), {message: 'simple moment object'});\n});\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/min/locales.js",
    "content": ";(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\n//! moment.js locale configuration\n//! locale : Afrikaans [af]\n//! author : Werner Mollentze : https://github.com/wernerm\n\nmoment.defineLocale('af', {\n    months : 'Januarie_Februarie_Maart_April_Mei_Junie_Julie_Augustus_September_Oktober_November_Desember'.split('_'),\n    monthsShort : 'Jan_Feb_Mrt_Apr_Mei_Jun_Jul_Aug_Sep_Okt_Nov_Des'.split('_'),\n    weekdays : 'Sondag_Maandag_Dinsdag_Woensdag_Donderdag_Vrydag_Saterdag'.split('_'),\n    weekdaysShort : 'Son_Maa_Din_Woe_Don_Vry_Sat'.split('_'),\n    weekdaysMin : 'So_Ma_Di_Wo_Do_Vr_Sa'.split('_'),\n    meridiemParse: /vm|nm/i,\n    isPM : function (input) {\n        return /^nm$/i.test(input);\n    },\n    meridiem : function (hours, minutes, isLower) {\n        if (hours < 12) {\n            return isLower ? 'vm' : 'VM';\n        } else {\n            return isLower ? 'nm' : 'NM';\n        }\n    },\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY HH:mm',\n        LLLL : 'dddd, D MMMM YYYY HH:mm'\n    },\n    calendar : {\n        sameDay : '[Vandag om] LT',\n        nextDay : '[Môre om] LT',\n        nextWeek : 'dddd [om] LT',\n        lastDay : '[Gister om] LT',\n        lastWeek : '[Laas] dddd [om] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'oor %s',\n        past : '%s gelede',\n        s : '\\'n paar sekondes',\n        m : '\\'n minuut',\n        mm : '%d minute',\n        h : '\\'n uur',\n        hh : '%d ure',\n        d : '\\'n dag',\n        dd : '%d dae',\n        M : '\\'n maand',\n        MM : '%d maande',\n        y : '\\'n jaar',\n        yy : '%d jaar'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}(ste|de)/,\n    ordinal : function (number) {\n        return number + ((number === 1 || number === 8 || number >= 20) ? 'ste' : 'de'); // Thanks to Joris Röling : https://github.com/jjupiter\n    },\n    week : {\n        dow : 1, // Maandag is die eerste dag van die week.\n        doy : 4  // Die week wat die 4de Januarie bevat is die eerste week van die jaar.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Arabic (Algeria) [ar-dz]\n//! author : Noureddine LOUAHEDJ : https://github.com/noureddineme\n\nmoment.defineLocale('ar-dz', {\n    months : 'جانفي_فيفري_مارس_أفريل_ماي_جوان_جويلية_أوت_سبتمبر_أكتوبر_نوفمبر_ديسمبر'.split('_'),\n    monthsShort : 'جانفي_فيفري_مارس_أفريل_ماي_جوان_جويلية_أوت_سبتمبر_أكتوبر_نوفمبر_ديسمبر'.split('_'),\n    weekdays : 'الأحد_الإثنين_الثلاثاء_الأربعاء_الخميس_الجمعة_السبت'.split('_'),\n    weekdaysShort : 'احد_اثنين_ثلاثاء_اربعاء_خميس_جمعة_سبت'.split('_'),\n    weekdaysMin : 'أح_إث_ثلا_أر_خم_جم_سب'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY HH:mm',\n        LLLL : 'dddd D MMMM YYYY HH:mm'\n    },\n    calendar : {\n        sameDay: '[اليوم على الساعة] LT',\n        nextDay: '[غدا على الساعة] LT',\n        nextWeek: 'dddd [على الساعة] LT',\n        lastDay: '[أمس على الساعة] LT',\n        lastWeek: 'dddd [على الساعة] LT',\n        sameElse: 'L'\n    },\n    relativeTime : {\n        future : 'في %s',\n        past : 'منذ %s',\n        s : 'ثوان',\n        m : 'دقيقة',\n        mm : '%d دقائق',\n        h : 'ساعة',\n        hh : '%d ساعات',\n        d : 'يوم',\n        dd : '%d أيام',\n        M : 'شهر',\n        MM : '%d أشهر',\n        y : 'سنة',\n        yy : '%d سنوات'\n    },\n    week : {\n        dow : 0, // Sunday is the first day of the week.\n        doy : 4  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Arabic (Kuwait) [ar-kw]\n//! author : Nusret Parlak: https://github.com/nusretparlak\n\nmoment.defineLocale('ar-kw', {\n    months : 'يناير_فبراير_مارس_أبريل_ماي_يونيو_يوليوز_غشت_شتنبر_أكتوبر_نونبر_دجنبر'.split('_'),\n    monthsShort : 'يناير_فبراير_مارس_أبريل_ماي_يونيو_يوليوز_غشت_شتنبر_أكتوبر_نونبر_دجنبر'.split('_'),\n    weekdays : 'الأحد_الإتنين_الثلاثاء_الأربعاء_الخميس_الجمعة_السبت'.split('_'),\n    weekdaysShort : 'احد_اتنين_ثلاثاء_اربعاء_خميس_جمعة_سبت'.split('_'),\n    weekdaysMin : 'ح_ن_ث_ر_خ_ج_س'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY HH:mm',\n        LLLL : 'dddd D MMMM YYYY HH:mm'\n    },\n    calendar : {\n        sameDay: '[اليوم على الساعة] LT',\n        nextDay: '[غدا على الساعة] LT',\n        nextWeek: 'dddd [على الساعة] LT',\n        lastDay: '[أمس على الساعة] LT',\n        lastWeek: 'dddd [على الساعة] LT',\n        sameElse: 'L'\n    },\n    relativeTime : {\n        future : 'في %s',\n        past : 'منذ %s',\n        s : 'ثوان',\n        m : 'دقيقة',\n        mm : '%d دقائق',\n        h : 'ساعة',\n        hh : '%d ساعات',\n        d : 'يوم',\n        dd : '%d أيام',\n        M : 'شهر',\n        MM : '%d أشهر',\n        y : 'سنة',\n        yy : '%d سنوات'\n    },\n    week : {\n        dow : 0, // Sunday is the first day of the week.\n        doy : 12  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Arabic (Lybia) [ar-ly]\n//! author : Ali Hmer: https://github.com/kikoanis\n\nvar symbolMap = {\n    '1': '1',\n    '2': '2',\n    '3': '3',\n    '4': '4',\n    '5': '5',\n    '6': '6',\n    '7': '7',\n    '8': '8',\n    '9': '9',\n    '0': '0'\n};\nvar pluralForm = function (n) {\n    return n === 0 ? 0 : n === 1 ? 1 : n === 2 ? 2 : n % 100 >= 3 && n % 100 <= 10 ? 3 : n % 100 >= 11 ? 4 : 5;\n};\nvar plurals = {\n    s : ['أقل من ثانية', 'ثانية واحدة', ['ثانيتان', 'ثانيتين'], '%d ثوان', '%d ثانية', '%d ثانية'],\n    m : ['أقل من دقيقة', 'دقيقة واحدة', ['دقيقتان', 'دقيقتين'], '%d دقائق', '%d دقيقة', '%d دقيقة'],\n    h : ['أقل من ساعة', 'ساعة واحدة', ['ساعتان', 'ساعتين'], '%d ساعات', '%d ساعة', '%d ساعة'],\n    d : ['أقل من يوم', 'يوم واحد', ['يومان', 'يومين'], '%d أيام', '%d يومًا', '%d يوم'],\n    M : ['أقل من شهر', 'شهر واحد', ['شهران', 'شهرين'], '%d أشهر', '%d شهرا', '%d شهر'],\n    y : ['أقل من عام', 'عام واحد', ['عامان', 'عامين'], '%d أعوام', '%d عامًا', '%d عام']\n};\nvar pluralize = function (u) {\n    return function (number, withoutSuffix, string, isFuture) {\n        var f = pluralForm(number),\n            str = plurals[u][pluralForm(number)];\n        if (f === 2) {\n            str = str[withoutSuffix ? 0 : 1];\n        }\n        return str.replace(/%d/i, number);\n    };\n};\nvar months = [\n    'يناير',\n    'فبراير',\n    'مارس',\n    'أبريل',\n    'مايو',\n    'يونيو',\n    'يوليو',\n    'أغسطس',\n    'سبتمبر',\n    'أكتوبر',\n    'نوفمبر',\n    'ديسمبر'\n];\n\nmoment.defineLocale('ar-ly', {\n    months : months,\n    monthsShort : months,\n    weekdays : 'الأحد_الإثنين_الثلاثاء_الأربعاء_الخميس_الجمعة_السبت'.split('_'),\n    weekdaysShort : 'أحد_إثنين_ثلاثاء_أربعاء_خميس_جمعة_سبت'.split('_'),\n    weekdaysMin : 'ح_ن_ث_ر_خ_ج_س'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'D/\\u200FM/\\u200FYYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY HH:mm',\n        LLLL : 'dddd D MMMM YYYY HH:mm'\n    },\n    meridiemParse: /ص|م/,\n    isPM : function (input) {\n        return 'م' === input;\n    },\n    meridiem : function (hour, minute, isLower) {\n        if (hour < 12) {\n            return 'ص';\n        } else {\n            return 'م';\n        }\n    },\n    calendar : {\n        sameDay: '[اليوم عند الساعة] LT',\n        nextDay: '[غدًا عند الساعة] LT',\n        nextWeek: 'dddd [عند الساعة] LT',\n        lastDay: '[أمس عند الساعة] LT',\n        lastWeek: 'dddd [عند الساعة] LT',\n        sameElse: 'L'\n    },\n    relativeTime : {\n        future : 'بعد %s',\n        past : 'منذ %s',\n        s : pluralize('s'),\n        m : pluralize('m'),\n        mm : pluralize('m'),\n        h : pluralize('h'),\n        hh : pluralize('h'),\n        d : pluralize('d'),\n        dd : pluralize('d'),\n        M : pluralize('M'),\n        MM : pluralize('M'),\n        y : pluralize('y'),\n        yy : pluralize('y')\n    },\n    preparse: function (string) {\n        return string.replace(/\\u200f/g, '').replace(/،/g, ',');\n    },\n    postformat: function (string) {\n        return string.replace(/\\d/g, function (match) {\n            return symbolMap[match];\n        }).replace(/,/g, '،');\n    },\n    week : {\n        dow : 6, // Saturday is the first day of the week.\n        doy : 12  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Arabic (Morocco) [ar-ma]\n//! author : ElFadili Yassine : https://github.com/ElFadiliY\n//! author : Abdel Said : https://github.com/abdelsaid\n\nmoment.defineLocale('ar-ma', {\n    months : 'يناير_فبراير_مارس_أبريل_ماي_يونيو_يوليوز_غشت_شتنبر_أكتوبر_نونبر_دجنبر'.split('_'),\n    monthsShort : 'يناير_فبراير_مارس_أبريل_ماي_يونيو_يوليوز_غشت_شتنبر_أكتوبر_نونبر_دجنبر'.split('_'),\n    weekdays : 'الأحد_الإتنين_الثلاثاء_الأربعاء_الخميس_الجمعة_السبت'.split('_'),\n    weekdaysShort : 'احد_اتنين_ثلاثاء_اربعاء_خميس_جمعة_سبت'.split('_'),\n    weekdaysMin : 'ح_ن_ث_ر_خ_ج_س'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY HH:mm',\n        LLLL : 'dddd D MMMM YYYY HH:mm'\n    },\n    calendar : {\n        sameDay: '[اليوم على الساعة] LT',\n        nextDay: '[غدا على الساعة] LT',\n        nextWeek: 'dddd [على الساعة] LT',\n        lastDay: '[أمس على الساعة] LT',\n        lastWeek: 'dddd [على الساعة] LT',\n        sameElse: 'L'\n    },\n    relativeTime : {\n        future : 'في %s',\n        past : 'منذ %s',\n        s : 'ثوان',\n        m : 'دقيقة',\n        mm : '%d دقائق',\n        h : 'ساعة',\n        hh : '%d ساعات',\n        d : 'يوم',\n        dd : '%d أيام',\n        M : 'شهر',\n        MM : '%d أشهر',\n        y : 'سنة',\n        yy : '%d سنوات'\n    },\n    week : {\n        dow : 6, // Saturday is the first day of the week.\n        doy : 12  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Arabic (Saudi Arabia) [ar-sa]\n//! author : Suhail Alkowaileet : https://github.com/xsoh\n\nvar symbolMap$1 = {\n    '1': '١',\n    '2': '٢',\n    '3': '٣',\n    '4': '٤',\n    '5': '٥',\n    '6': '٦',\n    '7': '٧',\n    '8': '٨',\n    '9': '٩',\n    '0': '٠'\n};\nvar numberMap = {\n    '١': '1',\n    '٢': '2',\n    '٣': '3',\n    '٤': '4',\n    '٥': '5',\n    '٦': '6',\n    '٧': '7',\n    '٨': '8',\n    '٩': '9',\n    '٠': '0'\n};\n\nmoment.defineLocale('ar-sa', {\n    months : 'يناير_فبراير_مارس_أبريل_مايو_يونيو_يوليو_أغسطس_سبتمبر_أكتوبر_نوفمبر_ديسمبر'.split('_'),\n    monthsShort : 'يناير_فبراير_مارس_أبريل_مايو_يونيو_يوليو_أغسطس_سبتمبر_أكتوبر_نوفمبر_ديسمبر'.split('_'),\n    weekdays : 'الأحد_الإثنين_الثلاثاء_الأربعاء_الخميس_الجمعة_السبت'.split('_'),\n    weekdaysShort : 'أحد_إثنين_ثلاثاء_أربعاء_خميس_جمعة_سبت'.split('_'),\n    weekdaysMin : 'ح_ن_ث_ر_خ_ج_س'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY HH:mm',\n        LLLL : 'dddd D MMMM YYYY HH:mm'\n    },\n    meridiemParse: /ص|م/,\n    isPM : function (input) {\n        return 'م' === input;\n    },\n    meridiem : function (hour, minute, isLower) {\n        if (hour < 12) {\n            return 'ص';\n        } else {\n            return 'م';\n        }\n    },\n    calendar : {\n        sameDay: '[اليوم على الساعة] LT',\n        nextDay: '[غدا على الساعة] LT',\n        nextWeek: 'dddd [على الساعة] LT',\n        lastDay: '[أمس على الساعة] LT',\n        lastWeek: 'dddd [على الساعة] LT',\n        sameElse: 'L'\n    },\n    relativeTime : {\n        future : 'في %s',\n        past : 'منذ %s',\n        s : 'ثوان',\n        m : 'دقيقة',\n        mm : '%d دقائق',\n        h : 'ساعة',\n        hh : '%d ساعات',\n        d : 'يوم',\n        dd : '%d أيام',\n        M : 'شهر',\n        MM : '%d أشهر',\n        y : 'سنة',\n        yy : '%d سنوات'\n    },\n    preparse: function (string) {\n        return string.replace(/[١٢٣٤٥٦٧٨٩٠]/g, function (match) {\n            return numberMap[match];\n        }).replace(/،/g, ',');\n    },\n    postformat: function (string) {\n        return string.replace(/\\d/g, function (match) {\n            return symbolMap$1[match];\n        }).replace(/,/g, '،');\n    },\n    week : {\n        dow : 0, // Sunday is the first day of the week.\n        doy : 6  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale  :  Arabic (Tunisia) [ar-tn]\n//! author : Nader Toukabri : https://github.com/naderio\n\nmoment.defineLocale('ar-tn', {\n    months: 'جانفي_فيفري_مارس_أفريل_ماي_جوان_جويلية_أوت_سبتمبر_أكتوبر_نوفمبر_ديسمبر'.split('_'),\n    monthsShort: 'جانفي_فيفري_مارس_أفريل_ماي_جوان_جويلية_أوت_سبتمبر_أكتوبر_نوفمبر_ديسمبر'.split('_'),\n    weekdays: 'الأحد_الإثنين_الثلاثاء_الأربعاء_الخميس_الجمعة_السبت'.split('_'),\n    weekdaysShort: 'أحد_إثنين_ثلاثاء_أربعاء_خميس_جمعة_سبت'.split('_'),\n    weekdaysMin: 'ح_ن_ث_ر_خ_ج_س'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat: {\n        LT: 'HH:mm',\n        LTS: 'HH:mm:ss',\n        L: 'DD/MM/YYYY',\n        LL: 'D MMMM YYYY',\n        LLL: 'D MMMM YYYY HH:mm',\n        LLLL: 'dddd D MMMM YYYY HH:mm'\n    },\n    calendar: {\n        sameDay: '[اليوم على الساعة] LT',\n        nextDay: '[غدا على الساعة] LT',\n        nextWeek: 'dddd [على الساعة] LT',\n        lastDay: '[أمس على الساعة] LT',\n        lastWeek: 'dddd [على الساعة] LT',\n        sameElse: 'L'\n    },\n    relativeTime: {\n        future: 'في %s',\n        past: 'منذ %s',\n        s: 'ثوان',\n        m: 'دقيقة',\n        mm: '%d دقائق',\n        h: 'ساعة',\n        hh: '%d ساعات',\n        d: 'يوم',\n        dd: '%d أيام',\n        M: 'شهر',\n        MM: '%d أشهر',\n        y: 'سنة',\n        yy: '%d سنوات'\n    },\n    week: {\n        dow: 1, // Monday is the first day of the week.\n        doy: 4 // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Arabic [ar]\n//! author : Abdel Said: https://github.com/abdelsaid\n//! author : Ahmed Elkhatib\n//! author : forabi https://github.com/forabi\n\nvar symbolMap$2 = {\n    '1': '١',\n    '2': '٢',\n    '3': '٣',\n    '4': '٤',\n    '5': '٥',\n    '6': '٦',\n    '7': '٧',\n    '8': '٨',\n    '9': '٩',\n    '0': '٠'\n};\nvar numberMap$1 = {\n    '١': '1',\n    '٢': '2',\n    '٣': '3',\n    '٤': '4',\n    '٥': '5',\n    '٦': '6',\n    '٧': '7',\n    '٨': '8',\n    '٩': '9',\n    '٠': '0'\n};\nvar pluralForm$1 = function (n) {\n    return n === 0 ? 0 : n === 1 ? 1 : n === 2 ? 2 : n % 100 >= 3 && n % 100 <= 10 ? 3 : n % 100 >= 11 ? 4 : 5;\n};\nvar plurals$1 = {\n    s : ['أقل من ثانية', 'ثانية واحدة', ['ثانيتان', 'ثانيتين'], '%d ثوان', '%d ثانية', '%d ثانية'],\n    m : ['أقل من دقيقة', 'دقيقة واحدة', ['دقيقتان', 'دقيقتين'], '%d دقائق', '%d دقيقة', '%d دقيقة'],\n    h : ['أقل من ساعة', 'ساعة واحدة', ['ساعتان', 'ساعتين'], '%d ساعات', '%d ساعة', '%d ساعة'],\n    d : ['أقل من يوم', 'يوم واحد', ['يومان', 'يومين'], '%d أيام', '%d يومًا', '%d يوم'],\n    M : ['أقل من شهر', 'شهر واحد', ['شهران', 'شهرين'], '%d أشهر', '%d شهرا', '%d شهر'],\n    y : ['أقل من عام', 'عام واحد', ['عامان', 'عامين'], '%d أعوام', '%d عامًا', '%d عام']\n};\nvar pluralize$1 = function (u) {\n    return function (number, withoutSuffix, string, isFuture) {\n        var f = pluralForm$1(number),\n            str = plurals$1[u][pluralForm$1(number)];\n        if (f === 2) {\n            str = str[withoutSuffix ? 0 : 1];\n        }\n        return str.replace(/%d/i, number);\n    };\n};\nvar months$1 = [\n    'كانون الثاني يناير',\n    'شباط فبراير',\n    'آذار مارس',\n    'نيسان أبريل',\n    'أيار مايو',\n    'حزيران يونيو',\n    'تموز يوليو',\n    'آب أغسطس',\n    'أيلول سبتمبر',\n    'تشرين الأول أكتوبر',\n    'تشرين الثاني نوفمبر',\n    'كانون الأول ديسمبر'\n];\n\nmoment.defineLocale('ar', {\n    months : months$1,\n    monthsShort : months$1,\n    weekdays : 'الأحد_الإثنين_الثلاثاء_الأربعاء_الخميس_الجمعة_السبت'.split('_'),\n    weekdaysShort : 'أحد_إثنين_ثلاثاء_أربعاء_خميس_جمعة_سبت'.split('_'),\n    weekdaysMin : 'ح_ن_ث_ر_خ_ج_س'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'D/\\u200FM/\\u200FYYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY HH:mm',\n        LLLL : 'dddd D MMMM YYYY HH:mm'\n    },\n    meridiemParse: /ص|م/,\n    isPM : function (input) {\n        return 'م' === input;\n    },\n    meridiem : function (hour, minute, isLower) {\n        if (hour < 12) {\n            return 'ص';\n        } else {\n            return 'م';\n        }\n    },\n    calendar : {\n        sameDay: '[اليوم عند الساعة] LT',\n        nextDay: '[غدًا عند الساعة] LT',\n        nextWeek: 'dddd [عند الساعة] LT',\n        lastDay: '[أمس عند الساعة] LT',\n        lastWeek: 'dddd [عند الساعة] LT',\n        sameElse: 'L'\n    },\n    relativeTime : {\n        future : 'بعد %s',\n        past : 'منذ %s',\n        s : pluralize$1('s'),\n        m : pluralize$1('m'),\n        mm : pluralize$1('m'),\n        h : pluralize$1('h'),\n        hh : pluralize$1('h'),\n        d : pluralize$1('d'),\n        dd : pluralize$1('d'),\n        M : pluralize$1('M'),\n        MM : pluralize$1('M'),\n        y : pluralize$1('y'),\n        yy : pluralize$1('y')\n    },\n    preparse: function (string) {\n        return string.replace(/\\u200f/g, '').replace(/[١٢٣٤٥٦٧٨٩٠]/g, function (match) {\n            return numberMap$1[match];\n        }).replace(/،/g, ',');\n    },\n    postformat: function (string) {\n        return string.replace(/\\d/g, function (match) {\n            return symbolMap$2[match];\n        }).replace(/,/g, '،');\n    },\n    week : {\n        dow : 6, // Saturday is the first day of the week.\n        doy : 12  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Azerbaijani [az]\n//! author : topchiyev : https://github.com/topchiyev\n\nvar suffixes = {\n    1: '-inci',\n    5: '-inci',\n    8: '-inci',\n    70: '-inci',\n    80: '-inci',\n    2: '-nci',\n    7: '-nci',\n    20: '-nci',\n    50: '-nci',\n    3: '-üncü',\n    4: '-üncü',\n    100: '-üncü',\n    6: '-ncı',\n    9: '-uncu',\n    10: '-uncu',\n    30: '-uncu',\n    60: '-ıncı',\n    90: '-ıncı'\n};\n\nmoment.defineLocale('az', {\n    months : 'yanvar_fevral_mart_aprel_may_iyun_iyul_avqust_sentyabr_oktyabr_noyabr_dekabr'.split('_'),\n    monthsShort : 'yan_fev_mar_apr_may_iyn_iyl_avq_sen_okt_noy_dek'.split('_'),\n    weekdays : 'Bazar_Bazar ertəsi_Çərşənbə axşamı_Çərşənbə_Cümə axşamı_Cümə_Şənbə'.split('_'),\n    weekdaysShort : 'Baz_BzE_ÇAx_Çər_CAx_Cüm_Şən'.split('_'),\n    weekdaysMin : 'Bz_BE_ÇA_Çə_CA_Cü_Şə'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD.MM.YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY HH:mm',\n        LLLL : 'dddd, D MMMM YYYY HH:mm'\n    },\n    calendar : {\n        sameDay : '[bugün saat] LT',\n        nextDay : '[sabah saat] LT',\n        nextWeek : '[gələn həftə] dddd [saat] LT',\n        lastDay : '[dünən] LT',\n        lastWeek : '[keçən həftə] dddd [saat] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : '%s sonra',\n        past : '%s əvvəl',\n        s : 'birneçə saniyyə',\n        m : 'bir dəqiqə',\n        mm : '%d dəqiqə',\n        h : 'bir saat',\n        hh : '%d saat',\n        d : 'bir gün',\n        dd : '%d gün',\n        M : 'bir ay',\n        MM : '%d ay',\n        y : 'bir il',\n        yy : '%d il'\n    },\n    meridiemParse: /gecə|səhər|gündüz|axşam/,\n    isPM : function (input) {\n        return /^(gündüz|axşam)$/.test(input);\n    },\n    meridiem : function (hour, minute, isLower) {\n        if (hour < 4) {\n            return 'gecə';\n        } else if (hour < 12) {\n            return 'səhər';\n        } else if (hour < 17) {\n            return 'gündüz';\n        } else {\n            return 'axşam';\n        }\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}-(ıncı|inci|nci|üncü|ncı|uncu)/,\n    ordinal : function (number) {\n        if (number === 0) {  // special case for zero\n            return number + '-ıncı';\n        }\n        var a = number % 10,\n            b = number % 100 - a,\n            c = number >= 100 ? 100 : null;\n        return number + (suffixes[a] || suffixes[b] || suffixes[c]);\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 7  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Belarusian [be]\n//! author : Dmitry Demidov : https://github.com/demidov91\n//! author: Praleska: http://praleska.pro/\n//! Author : Menelion Elensúle : https://github.com/Oire\n\nfunction plural(word, num) {\n    var forms = word.split('_');\n    return num % 10 === 1 && num % 100 !== 11 ? forms[0] : (num % 10 >= 2 && num % 10 <= 4 && (num % 100 < 10 || num % 100 >= 20) ? forms[1] : forms[2]);\n}\nfunction relativeTimeWithPlural(number, withoutSuffix, key) {\n    var format = {\n        'mm': withoutSuffix ? 'хвіліна_хвіліны_хвілін' : 'хвіліну_хвіліны_хвілін',\n        'hh': withoutSuffix ? 'гадзіна_гадзіны_гадзін' : 'гадзіну_гадзіны_гадзін',\n        'dd': 'дзень_дні_дзён',\n        'MM': 'месяц_месяцы_месяцаў',\n        'yy': 'год_гады_гадоў'\n    };\n    if (key === 'm') {\n        return withoutSuffix ? 'хвіліна' : 'хвіліну';\n    }\n    else if (key === 'h') {\n        return withoutSuffix ? 'гадзіна' : 'гадзіну';\n    }\n    else {\n        return number + ' ' + plural(format[key], +number);\n    }\n}\n\nmoment.defineLocale('be', {\n    months : {\n        format: 'студзеня_лютага_сакавіка_красавіка_траўня_чэрвеня_ліпеня_жніўня_верасня_кастрычніка_лістапада_снежня'.split('_'),\n        standalone: 'студзень_люты_сакавік_красавік_травень_чэрвень_ліпень_жнівень_верасень_кастрычнік_лістапад_снежань'.split('_')\n    },\n    monthsShort : 'студ_лют_сак_крас_трав_чэрв_ліп_жнів_вер_каст_ліст_снеж'.split('_'),\n    weekdays : {\n        format: 'нядзелю_панядзелак_аўторак_сераду_чацвер_пятніцу_суботу'.split('_'),\n        standalone: 'нядзеля_панядзелак_аўторак_серада_чацвер_пятніца_субота'.split('_'),\n        isFormat: /\\[ ?[Вв] ?(?:мінулую|наступную)? ?\\] ?dddd/\n    },\n    weekdaysShort : 'нд_пн_ат_ср_чц_пт_сб'.split('_'),\n    weekdaysMin : 'нд_пн_ат_ср_чц_пт_сб'.split('_'),\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD.MM.YYYY',\n        LL : 'D MMMM YYYY г.',\n        LLL : 'D MMMM YYYY г., HH:mm',\n        LLLL : 'dddd, D MMMM YYYY г., HH:mm'\n    },\n    calendar : {\n        sameDay: '[Сёння ў] LT',\n        nextDay: '[Заўтра ў] LT',\n        lastDay: '[Учора ў] LT',\n        nextWeek: function () {\n            return '[У] dddd [ў] LT';\n        },\n        lastWeek: function () {\n            switch (this.day()) {\n                case 0:\n                case 3:\n                case 5:\n                case 6:\n                    return '[У мінулую] dddd [ў] LT';\n                case 1:\n                case 2:\n                case 4:\n                    return '[У мінулы] dddd [ў] LT';\n            }\n        },\n        sameElse: 'L'\n    },\n    relativeTime : {\n        future : 'праз %s',\n        past : '%s таму',\n        s : 'некалькі секунд',\n        m : relativeTimeWithPlural,\n        mm : relativeTimeWithPlural,\n        h : relativeTimeWithPlural,\n        hh : relativeTimeWithPlural,\n        d : 'дзень',\n        dd : relativeTimeWithPlural,\n        M : 'месяц',\n        MM : relativeTimeWithPlural,\n        y : 'год',\n        yy : relativeTimeWithPlural\n    },\n    meridiemParse: /ночы|раніцы|дня|вечара/,\n    isPM : function (input) {\n        return /^(дня|вечара)$/.test(input);\n    },\n    meridiem : function (hour, minute, isLower) {\n        if (hour < 4) {\n            return 'ночы';\n        } else if (hour < 12) {\n            return 'раніцы';\n        } else if (hour < 17) {\n            return 'дня';\n        } else {\n            return 'вечара';\n        }\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}-(і|ы|га)/,\n    ordinal: function (number, period) {\n        switch (period) {\n            case 'M':\n            case 'd':\n            case 'DDD':\n            case 'w':\n            case 'W':\n                return (number % 10 === 2 || number % 10 === 3) && (number % 100 !== 12 && number % 100 !== 13) ? number + '-і' : number + '-ы';\n            case 'D':\n                return number + '-га';\n            default:\n                return number;\n        }\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 7  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Bulgarian [bg]\n//! author : Krasen Borisov : https://github.com/kraz\n\nmoment.defineLocale('bg', {\n    months : 'януари_февруари_март_април_май_юни_юли_август_септември_октомври_ноември_декември'.split('_'),\n    monthsShort : 'янр_фев_мар_апр_май_юни_юли_авг_сеп_окт_ное_дек'.split('_'),\n    weekdays : 'неделя_понеделник_вторник_сряда_четвъртък_петък_събота'.split('_'),\n    weekdaysShort : 'нед_пон_вто_сря_чет_пет_съб'.split('_'),\n    weekdaysMin : 'нд_пн_вт_ср_чт_пт_сб'.split('_'),\n    longDateFormat : {\n        LT : 'H:mm',\n        LTS : 'H:mm:ss',\n        L : 'D.MM.YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY H:mm',\n        LLLL : 'dddd, D MMMM YYYY H:mm'\n    },\n    calendar : {\n        sameDay : '[Днес в] LT',\n        nextDay : '[Утре в] LT',\n        nextWeek : 'dddd [в] LT',\n        lastDay : '[Вчера в] LT',\n        lastWeek : function () {\n            switch (this.day()) {\n                case 0:\n                case 3:\n                case 6:\n                    return '[В изминалата] dddd [в] LT';\n                case 1:\n                case 2:\n                case 4:\n                case 5:\n                    return '[В изминалия] dddd [в] LT';\n            }\n        },\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'след %s',\n        past : 'преди %s',\n        s : 'няколко секунди',\n        m : 'минута',\n        mm : '%d минути',\n        h : 'час',\n        hh : '%d часа',\n        d : 'ден',\n        dd : '%d дни',\n        M : 'месец',\n        MM : '%d месеца',\n        y : 'година',\n        yy : '%d години'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}-(ев|ен|ти|ви|ри|ми)/,\n    ordinal : function (number) {\n        var lastDigit = number % 10,\n            last2Digits = number % 100;\n        if (number === 0) {\n            return number + '-ев';\n        } else if (last2Digits === 0) {\n            return number + '-ен';\n        } else if (last2Digits > 10 && last2Digits < 20) {\n            return number + '-ти';\n        } else if (lastDigit === 1) {\n            return number + '-ви';\n        } else if (lastDigit === 2) {\n            return number + '-ри';\n        } else if (lastDigit === 7 || lastDigit === 8) {\n            return number + '-ми';\n        } else {\n            return number + '-ти';\n        }\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 7  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Bengali [bn]\n//! author : Kaushik Gandhi : https://github.com/kaushikgandhi\n\nvar symbolMap$3 = {\n    '1': '১',\n    '2': '২',\n    '3': '৩',\n    '4': '৪',\n    '5': '৫',\n    '6': '৬',\n    '7': '৭',\n    '8': '৮',\n    '9': '৯',\n    '0': '০'\n};\nvar numberMap$2 = {\n    '১': '1',\n    '২': '2',\n    '৩': '3',\n    '৪': '4',\n    '৫': '5',\n    '৬': '6',\n    '৭': '7',\n    '৮': '8',\n    '৯': '9',\n    '০': '0'\n};\n\nmoment.defineLocale('bn', {\n    months : 'জানুয়ারী_ফেব্রুয়ারি_মার্চ_এপ্রিল_মে_জুন_জুলাই_আগস্ট_সেপ্টেম্বর_অক্টোবর_নভেম্বর_ডিসেম্বর'.split('_'),\n    monthsShort : 'জানু_ফেব_মার্চ_এপ্র_মে_জুন_জুল_আগ_সেপ্ট_অক্টো_নভে_ডিসে'.split('_'),\n    weekdays : 'রবিবার_সোমবার_মঙ্গলবার_বুধবার_বৃহস্পতিবার_শুক্রবার_শনিবার'.split('_'),\n    weekdaysShort : 'রবি_সোম_মঙ্গল_বুধ_বৃহস্পতি_শুক্র_শনি'.split('_'),\n    weekdaysMin : 'রবি_সোম_মঙ্গ_বুধ_বৃহঃ_শুক্র_শনি'.split('_'),\n    longDateFormat : {\n        LT : 'A h:mm সময়',\n        LTS : 'A h:mm:ss সময়',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY, A h:mm সময়',\n        LLLL : 'dddd, D MMMM YYYY, A h:mm সময়'\n    },\n    calendar : {\n        sameDay : '[আজ] LT',\n        nextDay : '[আগামীকাল] LT',\n        nextWeek : 'dddd, LT',\n        lastDay : '[গতকাল] LT',\n        lastWeek : '[গত] dddd, LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : '%s পরে',\n        past : '%s আগে',\n        s : 'কয়েক সেকেন্ড',\n        m : 'এক মিনিট',\n        mm : '%d মিনিট',\n        h : 'এক ঘন্টা',\n        hh : '%d ঘন্টা',\n        d : 'এক দিন',\n        dd : '%d দিন',\n        M : 'এক মাস',\n        MM : '%d মাস',\n        y : 'এক বছর',\n        yy : '%d বছর'\n    },\n    preparse: function (string) {\n        return string.replace(/[১২৩৪৫৬৭৮৯০]/g, function (match) {\n            return numberMap$2[match];\n        });\n    },\n    postformat: function (string) {\n        return string.replace(/\\d/g, function (match) {\n            return symbolMap$3[match];\n        });\n    },\n    meridiemParse: /রাত|সকাল|দুপুর|বিকাল|রাত/,\n    meridiemHour : function (hour, meridiem) {\n        if (hour === 12) {\n            hour = 0;\n        }\n        if ((meridiem === 'রাত' && hour >= 4) ||\n                (meridiem === 'দুপুর' && hour < 5) ||\n                meridiem === 'বিকাল') {\n            return hour + 12;\n        } else {\n            return hour;\n        }\n    },\n    meridiem : function (hour, minute, isLower) {\n        if (hour < 4) {\n            return 'রাত';\n        } else if (hour < 10) {\n            return 'সকাল';\n        } else if (hour < 17) {\n            return 'দুপুর';\n        } else if (hour < 20) {\n            return 'বিকাল';\n        } else {\n            return 'রাত';\n        }\n    },\n    week : {\n        dow : 0, // Sunday is the first day of the week.\n        doy : 6  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Tibetan [bo]\n//! author : Thupten N. Chakrishar : https://github.com/vajradog\n\nvar symbolMap$4 = {\n    '1': '༡',\n    '2': '༢',\n    '3': '༣',\n    '4': '༤',\n    '5': '༥',\n    '6': '༦',\n    '7': '༧',\n    '8': '༨',\n    '9': '༩',\n    '0': '༠'\n};\nvar numberMap$3 = {\n    '༡': '1',\n    '༢': '2',\n    '༣': '3',\n    '༤': '4',\n    '༥': '5',\n    '༦': '6',\n    '༧': '7',\n    '༨': '8',\n    '༩': '9',\n    '༠': '0'\n};\n\nmoment.defineLocale('bo', {\n    months : 'ཟླ་བ་དང་པོ_ཟླ་བ་གཉིས་པ_ཟླ་བ་གསུམ་པ_ཟླ་བ་བཞི་པ_ཟླ་བ་ལྔ་པ_ཟླ་བ་དྲུག་པ_ཟླ་བ་བདུན་པ_ཟླ་བ་བརྒྱད་པ_ཟླ་བ་དགུ་པ_ཟླ་བ་བཅུ་པ_ཟླ་བ་བཅུ་གཅིག་པ_ཟླ་བ་བཅུ་གཉིས་པ'.split('_'),\n    monthsShort : 'ཟླ་བ་དང་པོ_ཟླ་བ་གཉིས་པ_ཟླ་བ་གསུམ་པ_ཟླ་བ་བཞི་པ_ཟླ་བ་ལྔ་པ_ཟླ་བ་དྲུག་པ_ཟླ་བ་བདུན་པ_ཟླ་བ་བརྒྱད་པ_ཟླ་བ་དགུ་པ_ཟླ་བ་བཅུ་པ_ཟླ་བ་བཅུ་གཅིག་པ_ཟླ་བ་བཅུ་གཉིས་པ'.split('_'),\n    weekdays : 'གཟའ་ཉི་མ་_གཟའ་ཟླ་བ་_གཟའ་མིག་དམར་_གཟའ་ལྷག་པ་_གཟའ་ཕུར་བུ_གཟའ་པ་སངས་_གཟའ་སྤེན་པ་'.split('_'),\n    weekdaysShort : 'ཉི་མ་_ཟླ་བ་_མིག་དམར་_ལྷག་པ་_ཕུར་བུ_པ་སངས་_སྤེན་པ་'.split('_'),\n    weekdaysMin : 'ཉི་མ་_ཟླ་བ་_མིག་དམར་_ལྷག་པ་_ཕུར་བུ_པ་སངས་_སྤེན་པ་'.split('_'),\n    longDateFormat : {\n        LT : 'A h:mm',\n        LTS : 'A h:mm:ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY, A h:mm',\n        LLLL : 'dddd, D MMMM YYYY, A h:mm'\n    },\n    calendar : {\n        sameDay : '[དི་རིང] LT',\n        nextDay : '[སང་ཉིན] LT',\n        nextWeek : '[བདུན་ཕྲག་རྗེས་མ], LT',\n        lastDay : '[ཁ་སང] LT',\n        lastWeek : '[བདུན་ཕྲག་མཐའ་མ] dddd, LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : '%s ལ་',\n        past : '%s སྔན་ལ',\n        s : 'ལམ་སང',\n        m : 'སྐར་མ་གཅིག',\n        mm : '%d སྐར་མ',\n        h : 'ཆུ་ཚོད་གཅིག',\n        hh : '%d ཆུ་ཚོད',\n        d : 'ཉིན་གཅིག',\n        dd : '%d ཉིན་',\n        M : 'ཟླ་བ་གཅིག',\n        MM : '%d ཟླ་བ',\n        y : 'ལོ་གཅིག',\n        yy : '%d ལོ'\n    },\n    preparse: function (string) {\n        return string.replace(/[༡༢༣༤༥༦༧༨༩༠]/g, function (match) {\n            return numberMap$3[match];\n        });\n    },\n    postformat: function (string) {\n        return string.replace(/\\d/g, function (match) {\n            return symbolMap$4[match];\n        });\n    },\n    meridiemParse: /མཚན་མོ|ཞོགས་ཀས|ཉིན་གུང|དགོང་དག|མཚན་མོ/,\n    meridiemHour : function (hour, meridiem) {\n        if (hour === 12) {\n            hour = 0;\n        }\n        if ((meridiem === 'མཚན་མོ' && hour >= 4) ||\n                (meridiem === 'ཉིན་གུང' && hour < 5) ||\n                meridiem === 'དགོང་དག') {\n            return hour + 12;\n        } else {\n            return hour;\n        }\n    },\n    meridiem : function (hour, minute, isLower) {\n        if (hour < 4) {\n            return 'མཚན་མོ';\n        } else if (hour < 10) {\n            return 'ཞོགས་ཀས';\n        } else if (hour < 17) {\n            return 'ཉིན་གུང';\n        } else if (hour < 20) {\n            return 'དགོང་དག';\n        } else {\n            return 'མཚན་མོ';\n        }\n    },\n    week : {\n        dow : 0, // Sunday is the first day of the week.\n        doy : 6  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Breton [br]\n//! author : Jean-Baptiste Le Duigou : https://github.com/jbleduigou\n\nfunction relativeTimeWithMutation(number, withoutSuffix, key) {\n    var format = {\n        'mm': 'munutenn',\n        'MM': 'miz',\n        'dd': 'devezh'\n    };\n    return number + ' ' + mutation(format[key], number);\n}\nfunction specialMutationForYears(number) {\n    switch (lastNumber(number)) {\n        case 1:\n        case 3:\n        case 4:\n        case 5:\n        case 9:\n            return number + ' bloaz';\n        default:\n            return number + ' vloaz';\n    }\n}\nfunction lastNumber(number) {\n    if (number > 9) {\n        return lastNumber(number % 10);\n    }\n    return number;\n}\nfunction mutation(text, number) {\n    if (number === 2) {\n        return softMutation(text);\n    }\n    return text;\n}\nfunction softMutation(text) {\n    var mutationTable = {\n        'm': 'v',\n        'b': 'v',\n        'd': 'z'\n    };\n    if (mutationTable[text.charAt(0)] === undefined) {\n        return text;\n    }\n    return mutationTable[text.charAt(0)] + text.substring(1);\n}\n\nmoment.defineLocale('br', {\n    months : 'Genver_C\\'hwevrer_Meurzh_Ebrel_Mae_Mezheven_Gouere_Eost_Gwengolo_Here_Du_Kerzu'.split('_'),\n    monthsShort : 'Gen_C\\'hwe_Meu_Ebr_Mae_Eve_Gou_Eos_Gwe_Her_Du_Ker'.split('_'),\n    weekdays : 'Sul_Lun_Meurzh_Merc\\'her_Yaou_Gwener_Sadorn'.split('_'),\n    weekdaysShort : 'Sul_Lun_Meu_Mer_Yao_Gwe_Sad'.split('_'),\n    weekdaysMin : 'Su_Lu_Me_Mer_Ya_Gw_Sa'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat : {\n        LT : 'h[e]mm A',\n        LTS : 'h[e]mm:ss A',\n        L : 'DD/MM/YYYY',\n        LL : 'D [a viz] MMMM YYYY',\n        LLL : 'D [a viz] MMMM YYYY h[e]mm A',\n        LLLL : 'dddd, D [a viz] MMMM YYYY h[e]mm A'\n    },\n    calendar : {\n        sameDay : '[Hiziv da] LT',\n        nextDay : '[Warc\\'hoazh da] LT',\n        nextWeek : 'dddd [da] LT',\n        lastDay : '[Dec\\'h da] LT',\n        lastWeek : 'dddd [paset da] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'a-benn %s',\n        past : '%s \\'zo',\n        s : 'un nebeud segondennoù',\n        m : 'ur vunutenn',\n        mm : relativeTimeWithMutation,\n        h : 'un eur',\n        hh : '%d eur',\n        d : 'un devezh',\n        dd : relativeTimeWithMutation,\n        M : 'ur miz',\n        MM : relativeTimeWithMutation,\n        y : 'ur bloaz',\n        yy : specialMutationForYears\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}(añ|vet)/,\n    ordinal : function (number) {\n        var output = (number === 1) ? 'añ' : 'vet';\n        return number + output;\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Bosnian [bs]\n//! author : Nedim Cholich : https://github.com/frontyard\n//! based on (hr) translation by Bojan Marković\n\nfunction translate(number, withoutSuffix, key) {\n    var result = number + ' ';\n    switch (key) {\n        case 'm':\n            return withoutSuffix ? 'jedna minuta' : 'jedne minute';\n        case 'mm':\n            if (number === 1) {\n                result += 'minuta';\n            } else if (number === 2 || number === 3 || number === 4) {\n                result += 'minute';\n            } else {\n                result += 'minuta';\n            }\n            return result;\n        case 'h':\n            return withoutSuffix ? 'jedan sat' : 'jednog sata';\n        case 'hh':\n            if (number === 1) {\n                result += 'sat';\n            } else if (number === 2 || number === 3 || number === 4) {\n                result += 'sata';\n            } else {\n                result += 'sati';\n            }\n            return result;\n        case 'dd':\n            if (number === 1) {\n                result += 'dan';\n            } else {\n                result += 'dana';\n            }\n            return result;\n        case 'MM':\n            if (number === 1) {\n                result += 'mjesec';\n            } else if (number === 2 || number === 3 || number === 4) {\n                result += 'mjeseca';\n            } else {\n                result += 'mjeseci';\n            }\n            return result;\n        case 'yy':\n            if (number === 1) {\n                result += 'godina';\n            } else if (number === 2 || number === 3 || number === 4) {\n                result += 'godine';\n            } else {\n                result += 'godina';\n            }\n            return result;\n    }\n}\n\nmoment.defineLocale('bs', {\n    months : 'januar_februar_mart_april_maj_juni_juli_august_septembar_oktobar_novembar_decembar'.split('_'),\n    monthsShort : 'jan._feb._mar._apr._maj._jun._jul._aug._sep._okt._nov._dec.'.split('_'),\n    monthsParseExact: true,\n    weekdays : 'nedjelja_ponedjeljak_utorak_srijeda_četvrtak_petak_subota'.split('_'),\n    weekdaysShort : 'ned._pon._uto._sri._čet._pet._sub.'.split('_'),\n    weekdaysMin : 'ne_po_ut_sr_če_pe_su'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat : {\n        LT : 'H:mm',\n        LTS : 'H:mm:ss',\n        L : 'DD.MM.YYYY',\n        LL : 'D. MMMM YYYY',\n        LLL : 'D. MMMM YYYY H:mm',\n        LLLL : 'dddd, D. MMMM YYYY H:mm'\n    },\n    calendar : {\n        sameDay  : '[danas u] LT',\n        nextDay  : '[sutra u] LT',\n        nextWeek : function () {\n            switch (this.day()) {\n                case 0:\n                    return '[u] [nedjelju] [u] LT';\n                case 3:\n                    return '[u] [srijedu] [u] LT';\n                case 6:\n                    return '[u] [subotu] [u] LT';\n                case 1:\n                case 2:\n                case 4:\n                case 5:\n                    return '[u] dddd [u] LT';\n            }\n        },\n        lastDay  : '[jučer u] LT',\n        lastWeek : function () {\n            switch (this.day()) {\n                case 0:\n                case 3:\n                    return '[prošlu] dddd [u] LT';\n                case 6:\n                    return '[prošle] [subote] [u] LT';\n                case 1:\n                case 2:\n                case 4:\n                case 5:\n                    return '[prošli] dddd [u] LT';\n            }\n        },\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'za %s',\n        past   : 'prije %s',\n        s      : 'par sekundi',\n        m      : translate,\n        mm     : translate,\n        h      : translate,\n        hh     : translate,\n        d      : 'dan',\n        dd     : translate,\n        M      : 'mjesec',\n        MM     : translate,\n        y      : 'godinu',\n        yy     : translate\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}\\./,\n    ordinal : '%d.',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 7  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Catalan [ca]\n//! author : Juan G. Hurtado : https://github.com/juanghurtado\n\nmoment.defineLocale('ca', {\n    months : {\n        standalone: 'gener_febrer_març_abril_maig_juny_juliol_agost_setembre_octubre_novembre_desembre'.split('_'),\n        format: 'de gener_de febrer_de març_d\\'abril_de maig_de juny_de juliol_d\\'agost_de setembre_d\\'octubre_de novembre_de desembre'.split('_'),\n        isFormat: /D[oD]?(\\s)+MMMM/\n    },\n    monthsShort : 'gen._febr._març_abr._maig_juny_jul._ag._set._oct._nov._des.'.split('_'),\n    monthsParseExact : true,\n    weekdays : 'diumenge_dilluns_dimarts_dimecres_dijous_divendres_dissabte'.split('_'),\n    weekdaysShort : 'dg._dl._dt._dc._dj._dv._ds.'.split('_'),\n    weekdaysMin : 'Dg_Dl_Dt_Dc_Dj_Dv_Ds'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat : {\n        LT : 'H:mm',\n        LTS : 'H:mm:ss',\n        L : 'DD/MM/YYYY',\n        LL : '[el] D MMMM [de] YYYY',\n        ll : 'D MMM YYYY',\n        LLL : '[el] D MMMM [de] YYYY [a les] H:mm',\n        lll : 'D MMM YYYY, H:mm',\n        LLLL : '[el] dddd D MMMM [de] YYYY [a les] H:mm',\n        llll : 'ddd D MMM YYYY, H:mm'\n    },\n    calendar : {\n        sameDay : function () {\n            return '[avui a ' + ((this.hours() !== 1) ? 'les' : 'la') + '] LT';\n        },\n        nextDay : function () {\n            return '[demà a ' + ((this.hours() !== 1) ? 'les' : 'la') + '] LT';\n        },\n        nextWeek : function () {\n            return 'dddd [a ' + ((this.hours() !== 1) ? 'les' : 'la') + '] LT';\n        },\n        lastDay : function () {\n            return '[ahir a ' + ((this.hours() !== 1) ? 'les' : 'la') + '] LT';\n        },\n        lastWeek : function () {\n            return '[el] dddd [passat a ' + ((this.hours() !== 1) ? 'les' : 'la') + '] LT';\n        },\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'd\\'aquí %s',\n        past : 'fa %s',\n        s : 'uns segons',\n        m : 'un minut',\n        mm : '%d minuts',\n        h : 'una hora',\n        hh : '%d hores',\n        d : 'un dia',\n        dd : '%d dies',\n        M : 'un mes',\n        MM : '%d mesos',\n        y : 'un any',\n        yy : '%d anys'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}(r|n|t|è|a)/,\n    ordinal : function (number, period) {\n        var output = (number === 1) ? 'r' :\n            (number === 2) ? 'n' :\n            (number === 3) ? 'r' :\n            (number === 4) ? 't' : 'è';\n        if (period === 'w' || period === 'W') {\n            output = 'a';\n        }\n        return number + output;\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Czech [cs]\n//! author : petrbela : https://github.com/petrbela\n\nvar months$2 = 'leden_únor_březen_duben_květen_červen_červenec_srpen_září_říjen_listopad_prosinec'.split('_');\nvar monthsShort = 'led_úno_bře_dub_kvě_čvn_čvc_srp_zář_říj_lis_pro'.split('_');\nfunction plural$1(n) {\n    return (n > 1) && (n < 5) && (~~(n / 10) !== 1);\n}\nfunction translate$1(number, withoutSuffix, key, isFuture) {\n    var result = number + ' ';\n    switch (key) {\n        case 's':  // a few seconds / in a few seconds / a few seconds ago\n            return (withoutSuffix || isFuture) ? 'pár sekund' : 'pár sekundami';\n        case 'm':  // a minute / in a minute / a minute ago\n            return withoutSuffix ? 'minuta' : (isFuture ? 'minutu' : 'minutou');\n        case 'mm': // 9 minutes / in 9 minutes / 9 minutes ago\n            if (withoutSuffix || isFuture) {\n                return result + (plural$1(number) ? 'minuty' : 'minut');\n            } else {\n                return result + 'minutami';\n            }\n            break;\n        case 'h':  // an hour / in an hour / an hour ago\n            return withoutSuffix ? 'hodina' : (isFuture ? 'hodinu' : 'hodinou');\n        case 'hh': // 9 hours / in 9 hours / 9 hours ago\n            if (withoutSuffix || isFuture) {\n                return result + (plural$1(number) ? 'hodiny' : 'hodin');\n            } else {\n                return result + 'hodinami';\n            }\n            break;\n        case 'd':  // a day / in a day / a day ago\n            return (withoutSuffix || isFuture) ? 'den' : 'dnem';\n        case 'dd': // 9 days / in 9 days / 9 days ago\n            if (withoutSuffix || isFuture) {\n                return result + (plural$1(number) ? 'dny' : 'dní');\n            } else {\n                return result + 'dny';\n            }\n            break;\n        case 'M':  // a month / in a month / a month ago\n            return (withoutSuffix || isFuture) ? 'měsíc' : 'měsícem';\n        case 'MM': // 9 months / in 9 months / 9 months ago\n            if (withoutSuffix || isFuture) {\n                return result + (plural$1(number) ? 'měsíce' : 'měsíců');\n            } else {\n                return result + 'měsíci';\n            }\n            break;\n        case 'y':  // a year / in a year / a year ago\n            return (withoutSuffix || isFuture) ? 'rok' : 'rokem';\n        case 'yy': // 9 years / in 9 years / 9 years ago\n            if (withoutSuffix || isFuture) {\n                return result + (plural$1(number) ? 'roky' : 'let');\n            } else {\n                return result + 'lety';\n            }\n            break;\n    }\n}\n\nmoment.defineLocale('cs', {\n    months : months$2,\n    monthsShort : monthsShort,\n    monthsParse : (function (months, monthsShort) {\n        var i, _monthsParse = [];\n        for (i = 0; i < 12; i++) {\n            // use custom parser to solve problem with July (červenec)\n            _monthsParse[i] = new RegExp('^' + months[i] + '$|^' + monthsShort[i] + '$', 'i');\n        }\n        return _monthsParse;\n    }(months$2, monthsShort)),\n    shortMonthsParse : (function (monthsShort) {\n        var i, _shortMonthsParse = [];\n        for (i = 0; i < 12; i++) {\n            _shortMonthsParse[i] = new RegExp('^' + monthsShort[i] + '$', 'i');\n        }\n        return _shortMonthsParse;\n    }(monthsShort)),\n    longMonthsParse : (function (months) {\n        var i, _longMonthsParse = [];\n        for (i = 0; i < 12; i++) {\n            _longMonthsParse[i] = new RegExp('^' + months[i] + '$', 'i');\n        }\n        return _longMonthsParse;\n    }(months$2)),\n    weekdays : 'neděle_pondělí_úterý_středa_čtvrtek_pátek_sobota'.split('_'),\n    weekdaysShort : 'ne_po_út_st_čt_pá_so'.split('_'),\n    weekdaysMin : 'ne_po_út_st_čt_pá_so'.split('_'),\n    longDateFormat : {\n        LT: 'H:mm',\n        LTS : 'H:mm:ss',\n        L : 'DD.MM.YYYY',\n        LL : 'D. MMMM YYYY',\n        LLL : 'D. MMMM YYYY H:mm',\n        LLLL : 'dddd D. MMMM YYYY H:mm',\n        l : 'D. M. YYYY'\n    },\n    calendar : {\n        sameDay: '[dnes v] LT',\n        nextDay: '[zítra v] LT',\n        nextWeek: function () {\n            switch (this.day()) {\n                case 0:\n                    return '[v neděli v] LT';\n                case 1:\n                case 2:\n                    return '[v] dddd [v] LT';\n                case 3:\n                    return '[ve středu v] LT';\n                case 4:\n                    return '[ve čtvrtek v] LT';\n                case 5:\n                    return '[v pátek v] LT';\n                case 6:\n                    return '[v sobotu v] LT';\n            }\n        },\n        lastDay: '[včera v] LT',\n        lastWeek: function () {\n            switch (this.day()) {\n                case 0:\n                    return '[minulou neděli v] LT';\n                case 1:\n                case 2:\n                    return '[minulé] dddd [v] LT';\n                case 3:\n                    return '[minulou středu v] LT';\n                case 4:\n                case 5:\n                    return '[minulý] dddd [v] LT';\n                case 6:\n                    return '[minulou sobotu v] LT';\n            }\n        },\n        sameElse: 'L'\n    },\n    relativeTime : {\n        future : 'za %s',\n        past : 'před %s',\n        s : translate$1,\n        m : translate$1,\n        mm : translate$1,\n        h : translate$1,\n        hh : translate$1,\n        d : translate$1,\n        dd : translate$1,\n        M : translate$1,\n        MM : translate$1,\n        y : translate$1,\n        yy : translate$1\n    },\n    dayOfMonthOrdinalParse : /\\d{1,2}\\./,\n    ordinal : '%d.',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Chuvash [cv]\n//! author : Anatoly Mironov : https://github.com/mirontoli\n\nmoment.defineLocale('cv', {\n    months : 'кӑрлач_нарӑс_пуш_ака_май_ҫӗртме_утӑ_ҫурла_авӑн_юпа_чӳк_раштав'.split('_'),\n    monthsShort : 'кӑр_нар_пуш_ака_май_ҫӗр_утӑ_ҫур_авн_юпа_чӳк_раш'.split('_'),\n    weekdays : 'вырсарникун_тунтикун_ытларикун_юнкун_кӗҫнерникун_эрнекун_шӑматкун'.split('_'),\n    weekdaysShort : 'выр_тун_ытл_юн_кӗҫ_эрн_шӑм'.split('_'),\n    weekdaysMin : 'вр_тн_ыт_юн_кҫ_эр_шм'.split('_'),\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD-MM-YYYY',\n        LL : 'YYYY [ҫулхи] MMMM [уйӑхӗн] D[-мӗшӗ]',\n        LLL : 'YYYY [ҫулхи] MMMM [уйӑхӗн] D[-мӗшӗ], HH:mm',\n        LLLL : 'dddd, YYYY [ҫулхи] MMMM [уйӑхӗн] D[-мӗшӗ], HH:mm'\n    },\n    calendar : {\n        sameDay: '[Паян] LT [сехетре]',\n        nextDay: '[Ыран] LT [сехетре]',\n        lastDay: '[Ӗнер] LT [сехетре]',\n        nextWeek: '[Ҫитес] dddd LT [сехетре]',\n        lastWeek: '[Иртнӗ] dddd LT [сехетре]',\n        sameElse: 'L'\n    },\n    relativeTime : {\n        future : function (output) {\n            var affix = /сехет$/i.exec(output) ? 'рен' : /ҫул$/i.exec(output) ? 'тан' : 'ран';\n            return output + affix;\n        },\n        past : '%s каялла',\n        s : 'пӗр-ик ҫеккунт',\n        m : 'пӗр минут',\n        mm : '%d минут',\n        h : 'пӗр сехет',\n        hh : '%d сехет',\n        d : 'пӗр кун',\n        dd : '%d кун',\n        M : 'пӗр уйӑх',\n        MM : '%d уйӑх',\n        y : 'пӗр ҫул',\n        yy : '%d ҫул'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}-мӗш/,\n    ordinal : '%d-мӗш',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 7  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Welsh [cy]\n//! author : Robert Allen : https://github.com/robgallen\n//! author : https://github.com/ryangreaves\n\nmoment.defineLocale('cy', {\n    months: 'Ionawr_Chwefror_Mawrth_Ebrill_Mai_Mehefin_Gorffennaf_Awst_Medi_Hydref_Tachwedd_Rhagfyr'.split('_'),\n    monthsShort: 'Ion_Chwe_Maw_Ebr_Mai_Meh_Gor_Aws_Med_Hyd_Tach_Rhag'.split('_'),\n    weekdays: 'Dydd Sul_Dydd Llun_Dydd Mawrth_Dydd Mercher_Dydd Iau_Dydd Gwener_Dydd Sadwrn'.split('_'),\n    weekdaysShort: 'Sul_Llun_Maw_Mer_Iau_Gwe_Sad'.split('_'),\n    weekdaysMin: 'Su_Ll_Ma_Me_Ia_Gw_Sa'.split('_'),\n    weekdaysParseExact : true,\n    // time formats are the same as en-gb\n    longDateFormat: {\n        LT: 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L: 'DD/MM/YYYY',\n        LL: 'D MMMM YYYY',\n        LLL: 'D MMMM YYYY HH:mm',\n        LLLL: 'dddd, D MMMM YYYY HH:mm'\n    },\n    calendar: {\n        sameDay: '[Heddiw am] LT',\n        nextDay: '[Yfory am] LT',\n        nextWeek: 'dddd [am] LT',\n        lastDay: '[Ddoe am] LT',\n        lastWeek: 'dddd [diwethaf am] LT',\n        sameElse: 'L'\n    },\n    relativeTime: {\n        future: 'mewn %s',\n        past: '%s yn ôl',\n        s: 'ychydig eiliadau',\n        m: 'munud',\n        mm: '%d munud',\n        h: 'awr',\n        hh: '%d awr',\n        d: 'diwrnod',\n        dd: '%d diwrnod',\n        M: 'mis',\n        MM: '%d mis',\n        y: 'blwyddyn',\n        yy: '%d flynedd'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}(fed|ain|af|il|ydd|ed|eg)/,\n    // traditional ordinal numbers above 31 are not commonly used in colloquial Welsh\n    ordinal: function (number) {\n        var b = number,\n            output = '',\n            lookup = [\n                '', 'af', 'il', 'ydd', 'ydd', 'ed', 'ed', 'ed', 'fed', 'fed', 'fed', // 1af to 10fed\n                'eg', 'fed', 'eg', 'eg', 'fed', 'eg', 'eg', 'fed', 'eg', 'fed' // 11eg to 20fed\n            ];\n        if (b > 20) {\n            if (b === 40 || b === 50 || b === 60 || b === 80 || b === 100) {\n                output = 'fed'; // not 30ain, 70ain or 90ain\n            } else {\n                output = 'ain';\n            }\n        } else if (b > 0) {\n            output = lookup[b];\n        }\n        return number + output;\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Danish [da]\n//! author : Ulrik Nielsen : https://github.com/mrbase\n\nmoment.defineLocale('da', {\n    months : 'januar_februar_marts_april_maj_juni_juli_august_september_oktober_november_december'.split('_'),\n    monthsShort : 'jan_feb_mar_apr_maj_jun_jul_aug_sep_okt_nov_dec'.split('_'),\n    weekdays : 'søndag_mandag_tirsdag_onsdag_torsdag_fredag_lørdag'.split('_'),\n    weekdaysShort : 'søn_man_tir_ons_tor_fre_lør'.split('_'),\n    weekdaysMin : 'sø_ma_ti_on_to_fr_lø'.split('_'),\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D. MMMM YYYY',\n        LLL : 'D. MMMM YYYY HH:mm',\n        LLLL : 'dddd [d.] D. MMMM YYYY [kl.] HH:mm'\n    },\n    calendar : {\n        sameDay : '[i dag kl.] LT',\n        nextDay : '[i morgen kl.] LT',\n        nextWeek : 'på dddd [kl.] LT',\n        lastDay : '[i går kl.] LT',\n        lastWeek : '[i] dddd[s kl.] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'om %s',\n        past : '%s siden',\n        s : 'få sekunder',\n        m : 'et minut',\n        mm : '%d minutter',\n        h : 'en time',\n        hh : '%d timer',\n        d : 'en dag',\n        dd : '%d dage',\n        M : 'en måned',\n        MM : '%d måneder',\n        y : 'et år',\n        yy : '%d år'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}\\./,\n    ordinal : '%d.',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : German (Austria) [de-at]\n//! author : lluchs : https://github.com/lluchs\n//! author: Menelion Elensúle: https://github.com/Oire\n//! author : Martin Groller : https://github.com/MadMG\n//! author : Mikolaj Dadela : https://github.com/mik01aj\n\nfunction processRelativeTime(number, withoutSuffix, key, isFuture) {\n    var format = {\n        'm': ['eine Minute', 'einer Minute'],\n        'h': ['eine Stunde', 'einer Stunde'],\n        'd': ['ein Tag', 'einem Tag'],\n        'dd': [number + ' Tage', number + ' Tagen'],\n        'M': ['ein Monat', 'einem Monat'],\n        'MM': [number + ' Monate', number + ' Monaten'],\n        'y': ['ein Jahr', 'einem Jahr'],\n        'yy': [number + ' Jahre', number + ' Jahren']\n    };\n    return withoutSuffix ? format[key][0] : format[key][1];\n}\n\nmoment.defineLocale('de-at', {\n    months : 'Jänner_Februar_März_April_Mai_Juni_Juli_August_September_Oktober_November_Dezember'.split('_'),\n    monthsShort : 'Jän._Febr._Mrz._Apr._Mai_Jun._Jul._Aug._Sept._Okt._Nov._Dez.'.split('_'),\n    monthsParseExact : true,\n    weekdays : 'Sonntag_Montag_Dienstag_Mittwoch_Donnerstag_Freitag_Samstag'.split('_'),\n    weekdaysShort : 'So._Mo._Di._Mi._Do._Fr._Sa.'.split('_'),\n    weekdaysMin : 'So_Mo_Di_Mi_Do_Fr_Sa'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat : {\n        LT: 'HH:mm',\n        LTS: 'HH:mm:ss',\n        L : 'DD.MM.YYYY',\n        LL : 'D. MMMM YYYY',\n        LLL : 'D. MMMM YYYY HH:mm',\n        LLLL : 'dddd, D. MMMM YYYY HH:mm'\n    },\n    calendar : {\n        sameDay: '[heute um] LT [Uhr]',\n        sameElse: 'L',\n        nextDay: '[morgen um] LT [Uhr]',\n        nextWeek: 'dddd [um] LT [Uhr]',\n        lastDay: '[gestern um] LT [Uhr]',\n        lastWeek: '[letzten] dddd [um] LT [Uhr]'\n    },\n    relativeTime : {\n        future : 'in %s',\n        past : 'vor %s',\n        s : 'ein paar Sekunden',\n        m : processRelativeTime,\n        mm : '%d Minuten',\n        h : processRelativeTime,\n        hh : '%d Stunden',\n        d : processRelativeTime,\n        dd : processRelativeTime,\n        M : processRelativeTime,\n        MM : processRelativeTime,\n        y : processRelativeTime,\n        yy : processRelativeTime\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}\\./,\n    ordinal : '%d.',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : German (Switzerland) [de-ch]\n//! author : sschueller : https://github.com/sschueller\n\n// based on: https://www.bk.admin.ch/dokumentation/sprachen/04915/05016/index.html?lang=de#\n\nfunction processRelativeTime$1(number, withoutSuffix, key, isFuture) {\n    var format = {\n        'm': ['eine Minute', 'einer Minute'],\n        'h': ['eine Stunde', 'einer Stunde'],\n        'd': ['ein Tag', 'einem Tag'],\n        'dd': [number + ' Tage', number + ' Tagen'],\n        'M': ['ein Monat', 'einem Monat'],\n        'MM': [number + ' Monate', number + ' Monaten'],\n        'y': ['ein Jahr', 'einem Jahr'],\n        'yy': [number + ' Jahre', number + ' Jahren']\n    };\n    return withoutSuffix ? format[key][0] : format[key][1];\n}\n\nmoment.defineLocale('de-ch', {\n    months : 'Januar_Februar_März_April_Mai_Juni_Juli_August_September_Oktober_November_Dezember'.split('_'),\n    monthsShort : 'Jan._Febr._März_April_Mai_Juni_Juli_Aug._Sept._Okt._Nov._Dez.'.split('_'),\n    monthsParseExact : true,\n    weekdays : 'Sonntag_Montag_Dienstag_Mittwoch_Donnerstag_Freitag_Samstag'.split('_'),\n    weekdaysShort : 'So_Mo_Di_Mi_Do_Fr_Sa'.split('_'),\n    weekdaysMin : 'So_Mo_Di_Mi_Do_Fr_Sa'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat : {\n        LT: 'HH.mm',\n        LTS: 'HH.mm.ss',\n        L : 'DD.MM.YYYY',\n        LL : 'D. MMMM YYYY',\n        LLL : 'D. MMMM YYYY HH.mm',\n        LLLL : 'dddd, D. MMMM YYYY HH.mm'\n    },\n    calendar : {\n        sameDay: '[heute um] LT [Uhr]',\n        sameElse: 'L',\n        nextDay: '[morgen um] LT [Uhr]',\n        nextWeek: 'dddd [um] LT [Uhr]',\n        lastDay: '[gestern um] LT [Uhr]',\n        lastWeek: '[letzten] dddd [um] LT [Uhr]'\n    },\n    relativeTime : {\n        future : 'in %s',\n        past : 'vor %s',\n        s : 'ein paar Sekunden',\n        m : processRelativeTime$1,\n        mm : '%d Minuten',\n        h : processRelativeTime$1,\n        hh : '%d Stunden',\n        d : processRelativeTime$1,\n        dd : processRelativeTime$1,\n        M : processRelativeTime$1,\n        MM : processRelativeTime$1,\n        y : processRelativeTime$1,\n        yy : processRelativeTime$1\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}\\./,\n    ordinal : '%d.',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : German [de]\n//! author : lluchs : https://github.com/lluchs\n//! author: Menelion Elensúle: https://github.com/Oire\n//! author : Mikolaj Dadela : https://github.com/mik01aj\n\nfunction processRelativeTime$2(number, withoutSuffix, key, isFuture) {\n    var format = {\n        'm': ['eine Minute', 'einer Minute'],\n        'h': ['eine Stunde', 'einer Stunde'],\n        'd': ['ein Tag', 'einem Tag'],\n        'dd': [number + ' Tage', number + ' Tagen'],\n        'M': ['ein Monat', 'einem Monat'],\n        'MM': [number + ' Monate', number + ' Monaten'],\n        'y': ['ein Jahr', 'einem Jahr'],\n        'yy': [number + ' Jahre', number + ' Jahren']\n    };\n    return withoutSuffix ? format[key][0] : format[key][1];\n}\n\nmoment.defineLocale('de', {\n    months : 'Januar_Februar_März_April_Mai_Juni_Juli_August_September_Oktober_November_Dezember'.split('_'),\n    monthsShort : 'Jan._Febr._Mrz._Apr._Mai_Jun._Jul._Aug._Sept._Okt._Nov._Dez.'.split('_'),\n    monthsParseExact : true,\n    weekdays : 'Sonntag_Montag_Dienstag_Mittwoch_Donnerstag_Freitag_Samstag'.split('_'),\n    weekdaysShort : 'So._Mo._Di._Mi._Do._Fr._Sa.'.split('_'),\n    weekdaysMin : 'So_Mo_Di_Mi_Do_Fr_Sa'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat : {\n        LT: 'HH:mm',\n        LTS: 'HH:mm:ss',\n        L : 'DD.MM.YYYY',\n        LL : 'D. MMMM YYYY',\n        LLL : 'D. MMMM YYYY HH:mm',\n        LLLL : 'dddd, D. MMMM YYYY HH:mm'\n    },\n    calendar : {\n        sameDay: '[heute um] LT [Uhr]',\n        sameElse: 'L',\n        nextDay: '[morgen um] LT [Uhr]',\n        nextWeek: 'dddd [um] LT [Uhr]',\n        lastDay: '[gestern um] LT [Uhr]',\n        lastWeek: '[letzten] dddd [um] LT [Uhr]'\n    },\n    relativeTime : {\n        future : 'in %s',\n        past : 'vor %s',\n        s : 'ein paar Sekunden',\n        m : processRelativeTime$2,\n        mm : '%d Minuten',\n        h : processRelativeTime$2,\n        hh : '%d Stunden',\n        d : processRelativeTime$2,\n        dd : processRelativeTime$2,\n        M : processRelativeTime$2,\n        MM : processRelativeTime$2,\n        y : processRelativeTime$2,\n        yy : processRelativeTime$2\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}\\./,\n    ordinal : '%d.',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Maldivian [dv]\n//! author : Jawish Hameed : https://github.com/jawish\n\nvar months$3 = [\n    'ޖެނުއަރީ',\n    'ފެބްރުއަރީ',\n    'މާރިޗު',\n    'އޭޕްރީލު',\n    'މޭ',\n    'ޖޫން',\n    'ޖުލައި',\n    'އޯގަސްޓު',\n    'ސެޕްޓެމްބަރު',\n    'އޮކްޓޯބަރު',\n    'ނޮވެމްބަރު',\n    'ޑިސެމްބަރު'\n];\nvar weekdays = [\n    'އާދިއްތަ',\n    'ހޯމަ',\n    'އަންގާރަ',\n    'ބުދަ',\n    'ބުރާސްފަތި',\n    'ހުކުރު',\n    'ހޮނިހިރު'\n];\n\nmoment.defineLocale('dv', {\n    months : months$3,\n    monthsShort : months$3,\n    weekdays : weekdays,\n    weekdaysShort : weekdays,\n    weekdaysMin : 'އާދި_ހޯމަ_އަން_ބުދަ_ބުރާ_ހުކު_ހޮނި'.split('_'),\n    longDateFormat : {\n\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'D/M/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY HH:mm',\n        LLLL : 'dddd D MMMM YYYY HH:mm'\n    },\n    meridiemParse: /މކ|މފ/,\n    isPM : function (input) {\n        return 'މފ' === input;\n    },\n    meridiem : function (hour, minute, isLower) {\n        if (hour < 12) {\n            return 'މކ';\n        } else {\n            return 'މފ';\n        }\n    },\n    calendar : {\n        sameDay : '[މިއަދު] LT',\n        nextDay : '[މާދަމާ] LT',\n        nextWeek : 'dddd LT',\n        lastDay : '[އިއްޔެ] LT',\n        lastWeek : '[ފާއިތުވި] dddd LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'ތެރޭގައި %s',\n        past : 'ކުރިން %s',\n        s : 'ސިކުންތުކޮޅެއް',\n        m : 'މިނިޓެއް',\n        mm : 'މިނިޓު %d',\n        h : 'ގަޑިއިރެއް',\n        hh : 'ގަޑިއިރު %d',\n        d : 'ދުވަހެއް',\n        dd : 'ދުވަސް %d',\n        M : 'މަހެއް',\n        MM : 'މަސް %d',\n        y : 'އަހަރެއް',\n        yy : 'އަހަރު %d'\n    },\n    preparse: function (string) {\n        return string.replace(/،/g, ',');\n    },\n    postformat: function (string) {\n        return string.replace(/,/g, '،');\n    },\n    week : {\n        dow : 7,  // Sunday is the first day of the week.\n        doy : 12  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\nfunction isFunction(input) {\n    return input instanceof Function || Object.prototype.toString.call(input) === '[object Function]';\n}\n\n//! moment.js locale configuration\n//! locale : Greek [el]\n//! author : Aggelos Karalias : https://github.com/mehiel\n\nmoment.defineLocale('el', {\n    monthsNominativeEl : 'Ιανουάριος_Φεβρουάριος_Μάρτιος_Απρίλιος_Μάιος_Ιούνιος_Ιούλιος_Αύγουστος_Σεπτέμβριος_Οκτώβριος_Νοέμβριος_Δεκέμβριος'.split('_'),\n    monthsGenitiveEl : 'Ιανουαρίου_Φεβρουαρίου_Μαρτίου_Απριλίου_Μαΐου_Ιουνίου_Ιουλίου_Αυγούστου_Σεπτεμβρίου_Οκτωβρίου_Νοεμβρίου_Δεκεμβρίου'.split('_'),\n    months : function (momentToFormat, format) {\n        if (!momentToFormat) {\n            return this._monthsNominativeEl;\n        } else if (/D/.test(format.substring(0, format.indexOf('MMMM')))) { // if there is a day number before 'MMMM'\n            return this._monthsGenitiveEl[momentToFormat.month()];\n        } else {\n            return this._monthsNominativeEl[momentToFormat.month()];\n        }\n    },\n    monthsShort : 'Ιαν_Φεβ_Μαρ_Απρ_Μαϊ_Ιουν_Ιουλ_Αυγ_Σεπ_Οκτ_Νοε_Δεκ'.split('_'),\n    weekdays : 'Κυριακή_Δευτέρα_Τρίτη_Τετάρτη_Πέμπτη_Παρασκευή_Σάββατο'.split('_'),\n    weekdaysShort : 'Κυρ_Δευ_Τρι_Τετ_Πεμ_Παρ_Σαβ'.split('_'),\n    weekdaysMin : 'Κυ_Δε_Τρ_Τε_Πε_Πα_Σα'.split('_'),\n    meridiem : function (hours, minutes, isLower) {\n        if (hours > 11) {\n            return isLower ? 'μμ' : 'ΜΜ';\n        } else {\n            return isLower ? 'πμ' : 'ΠΜ';\n        }\n    },\n    isPM : function (input) {\n        return ((input + '').toLowerCase()[0] === 'μ');\n    },\n    meridiemParse : /[ΠΜ]\\.?Μ?\\.?/i,\n    longDateFormat : {\n        LT : 'h:mm A',\n        LTS : 'h:mm:ss A',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY h:mm A',\n        LLLL : 'dddd, D MMMM YYYY h:mm A'\n    },\n    calendarEl : {\n        sameDay : '[Σήμερα {}] LT',\n        nextDay : '[Αύριο {}] LT',\n        nextWeek : 'dddd [{}] LT',\n        lastDay : '[Χθες {}] LT',\n        lastWeek : function () {\n            switch (this.day()) {\n                case 6:\n                    return '[το προηγούμενο] dddd [{}] LT';\n                default:\n                    return '[την προηγούμενη] dddd [{}] LT';\n            }\n        },\n        sameElse : 'L'\n    },\n    calendar : function (key, mom) {\n        var output = this._calendarEl[key],\n            hours = mom && mom.hours();\n        if (isFunction(output)) {\n            output = output.apply(mom);\n        }\n        return output.replace('{}', (hours % 12 === 1 ? 'στη' : 'στις'));\n    },\n    relativeTime : {\n        future : 'σε %s',\n        past : '%s πριν',\n        s : 'λίγα δευτερόλεπτα',\n        m : 'ένα λεπτό',\n        mm : '%d λεπτά',\n        h : 'μία ώρα',\n        hh : '%d ώρες',\n        d : 'μία μέρα',\n        dd : '%d μέρες',\n        M : 'ένας μήνας',\n        MM : '%d μήνες',\n        y : 'ένας χρόνος',\n        yy : '%d χρόνια'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}η/,\n    ordinal: '%dη',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4st is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : English (Australia) [en-au]\n//! author : Jared Morse : https://github.com/jarcoal\n\nmoment.defineLocale('en-au', {\n    months : 'January_February_March_April_May_June_July_August_September_October_November_December'.split('_'),\n    monthsShort : 'Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec'.split('_'),\n    weekdays : 'Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday'.split('_'),\n    weekdaysShort : 'Sun_Mon_Tue_Wed_Thu_Fri_Sat'.split('_'),\n    weekdaysMin : 'Su_Mo_Tu_We_Th_Fr_Sa'.split('_'),\n    longDateFormat : {\n        LT : 'h:mm A',\n        LTS : 'h:mm:ss A',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY h:mm A',\n        LLLL : 'dddd, D MMMM YYYY h:mm A'\n    },\n    calendar : {\n        sameDay : '[Today at] LT',\n        nextDay : '[Tomorrow at] LT',\n        nextWeek : 'dddd [at] LT',\n        lastDay : '[Yesterday at] LT',\n        lastWeek : '[Last] dddd [at] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'in %s',\n        past : '%s ago',\n        s : 'a few seconds',\n        m : 'a minute',\n        mm : '%d minutes',\n        h : 'an hour',\n        hh : '%d hours',\n        d : 'a day',\n        dd : '%d days',\n        M : 'a month',\n        MM : '%d months',\n        y : 'a year',\n        yy : '%d years'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}(st|nd|rd|th)/,\n    ordinal : function (number) {\n        var b = number % 10,\n            output = (~~(number % 100 / 10) === 1) ? 'th' :\n            (b === 1) ? 'st' :\n            (b === 2) ? 'nd' :\n            (b === 3) ? 'rd' : 'th';\n        return number + output;\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : English (Canada) [en-ca]\n//! author : Jonathan Abourbih : https://github.com/jonbca\n\nmoment.defineLocale('en-ca', {\n    months : 'January_February_March_April_May_June_July_August_September_October_November_December'.split('_'),\n    monthsShort : 'Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec'.split('_'),\n    weekdays : 'Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday'.split('_'),\n    weekdaysShort : 'Sun_Mon_Tue_Wed_Thu_Fri_Sat'.split('_'),\n    weekdaysMin : 'Su_Mo_Tu_We_Th_Fr_Sa'.split('_'),\n    longDateFormat : {\n        LT : 'h:mm A',\n        LTS : 'h:mm:ss A',\n        L : 'YYYY-MM-DD',\n        LL : 'MMMM D, YYYY',\n        LLL : 'MMMM D, YYYY h:mm A',\n        LLLL : 'dddd, MMMM D, YYYY h:mm A'\n    },\n    calendar : {\n        sameDay : '[Today at] LT',\n        nextDay : '[Tomorrow at] LT',\n        nextWeek : 'dddd [at] LT',\n        lastDay : '[Yesterday at] LT',\n        lastWeek : '[Last] dddd [at] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'in %s',\n        past : '%s ago',\n        s : 'a few seconds',\n        m : 'a minute',\n        mm : '%d minutes',\n        h : 'an hour',\n        hh : '%d hours',\n        d : 'a day',\n        dd : '%d days',\n        M : 'a month',\n        MM : '%d months',\n        y : 'a year',\n        yy : '%d years'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}(st|nd|rd|th)/,\n    ordinal : function (number) {\n        var b = number % 10,\n            output = (~~(number % 100 / 10) === 1) ? 'th' :\n            (b === 1) ? 'st' :\n            (b === 2) ? 'nd' :\n            (b === 3) ? 'rd' : 'th';\n        return number + output;\n    }\n});\n\n//! moment.js locale configuration\n//! locale : English (United Kingdom) [en-gb]\n//! author : Chris Gedrim : https://github.com/chrisgedrim\n\nmoment.defineLocale('en-gb', {\n    months : 'January_February_March_April_May_June_July_August_September_October_November_December'.split('_'),\n    monthsShort : 'Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec'.split('_'),\n    weekdays : 'Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday'.split('_'),\n    weekdaysShort : 'Sun_Mon_Tue_Wed_Thu_Fri_Sat'.split('_'),\n    weekdaysMin : 'Su_Mo_Tu_We_Th_Fr_Sa'.split('_'),\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY HH:mm',\n        LLLL : 'dddd, D MMMM YYYY HH:mm'\n    },\n    calendar : {\n        sameDay : '[Today at] LT',\n        nextDay : '[Tomorrow at] LT',\n        nextWeek : 'dddd [at] LT',\n        lastDay : '[Yesterday at] LT',\n        lastWeek : '[Last] dddd [at] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'in %s',\n        past : '%s ago',\n        s : 'a few seconds',\n        m : 'a minute',\n        mm : '%d minutes',\n        h : 'an hour',\n        hh : '%d hours',\n        d : 'a day',\n        dd : '%d days',\n        M : 'a month',\n        MM : '%d months',\n        y : 'a year',\n        yy : '%d years'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}(st|nd|rd|th)/,\n    ordinal : function (number) {\n        var b = number % 10,\n            output = (~~(number % 100 / 10) === 1) ? 'th' :\n            (b === 1) ? 'st' :\n            (b === 2) ? 'nd' :\n            (b === 3) ? 'rd' : 'th';\n        return number + output;\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : English (Ireland) [en-ie]\n//! author : Chris Cartlidge : https://github.com/chriscartlidge\n\nmoment.defineLocale('en-ie', {\n    months : 'January_February_March_April_May_June_July_August_September_October_November_December'.split('_'),\n    monthsShort : 'Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec'.split('_'),\n    weekdays : 'Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday'.split('_'),\n    weekdaysShort : 'Sun_Mon_Tue_Wed_Thu_Fri_Sat'.split('_'),\n    weekdaysMin : 'Su_Mo_Tu_We_Th_Fr_Sa'.split('_'),\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD-MM-YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY HH:mm',\n        LLLL : 'dddd D MMMM YYYY HH:mm'\n    },\n    calendar : {\n        sameDay : '[Today at] LT',\n        nextDay : '[Tomorrow at] LT',\n        nextWeek : 'dddd [at] LT',\n        lastDay : '[Yesterday at] LT',\n        lastWeek : '[Last] dddd [at] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'in %s',\n        past : '%s ago',\n        s : 'a few seconds',\n        m : 'a minute',\n        mm : '%d minutes',\n        h : 'an hour',\n        hh : '%d hours',\n        d : 'a day',\n        dd : '%d days',\n        M : 'a month',\n        MM : '%d months',\n        y : 'a year',\n        yy : '%d years'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}(st|nd|rd|th)/,\n    ordinal : function (number) {\n        var b = number % 10,\n            output = (~~(number % 100 / 10) === 1) ? 'th' :\n            (b === 1) ? 'st' :\n            (b === 2) ? 'nd' :\n            (b === 3) ? 'rd' : 'th';\n        return number + output;\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : English (New Zealand) [en-nz]\n//! author : Luke McGregor : https://github.com/lukemcgregor\n\nmoment.defineLocale('en-nz', {\n    months : 'January_February_March_April_May_June_July_August_September_October_November_December'.split('_'),\n    monthsShort : 'Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec'.split('_'),\n    weekdays : 'Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday'.split('_'),\n    weekdaysShort : 'Sun_Mon_Tue_Wed_Thu_Fri_Sat'.split('_'),\n    weekdaysMin : 'Su_Mo_Tu_We_Th_Fr_Sa'.split('_'),\n    longDateFormat : {\n        LT : 'h:mm A',\n        LTS : 'h:mm:ss A',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY h:mm A',\n        LLLL : 'dddd, D MMMM YYYY h:mm A'\n    },\n    calendar : {\n        sameDay : '[Today at] LT',\n        nextDay : '[Tomorrow at] LT',\n        nextWeek : 'dddd [at] LT',\n        lastDay : '[Yesterday at] LT',\n        lastWeek : '[Last] dddd [at] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'in %s',\n        past : '%s ago',\n        s : 'a few seconds',\n        m : 'a minute',\n        mm : '%d minutes',\n        h : 'an hour',\n        hh : '%d hours',\n        d : 'a day',\n        dd : '%d days',\n        M : 'a month',\n        MM : '%d months',\n        y : 'a year',\n        yy : '%d years'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}(st|nd|rd|th)/,\n    ordinal : function (number) {\n        var b = number % 10,\n            output = (~~(number % 100 / 10) === 1) ? 'th' :\n            (b === 1) ? 'st' :\n            (b === 2) ? 'nd' :\n            (b === 3) ? 'rd' : 'th';\n        return number + output;\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Esperanto [eo]\n//! author : Colin Dean : https://github.com/colindean\n//! author : Mia Nordentoft Imperatori : https://github.com/miestasmia\n//! comment : miestasmia corrected the translation by colindean\n\nmoment.defineLocale('eo', {\n    months : 'januaro_februaro_marto_aprilo_majo_junio_julio_aŭgusto_septembro_oktobro_novembro_decembro'.split('_'),\n    monthsShort : 'jan_feb_mar_apr_maj_jun_jul_aŭg_sep_okt_nov_dec'.split('_'),\n    weekdays : 'dimanĉo_lundo_mardo_merkredo_ĵaŭdo_vendredo_sabato'.split('_'),\n    weekdaysShort : 'dim_lun_mard_merk_ĵaŭ_ven_sab'.split('_'),\n    weekdaysMin : 'di_lu_ma_me_ĵa_ve_sa'.split('_'),\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'YYYY-MM-DD',\n        LL : 'D[-a de] MMMM, YYYY',\n        LLL : 'D[-a de] MMMM, YYYY HH:mm',\n        LLLL : 'dddd, [la] D[-a de] MMMM, YYYY HH:mm'\n    },\n    meridiemParse: /[ap]\\.t\\.m/i,\n    isPM: function (input) {\n        return input.charAt(0).toLowerCase() === 'p';\n    },\n    meridiem : function (hours, minutes, isLower) {\n        if (hours > 11) {\n            return isLower ? 'p.t.m.' : 'P.T.M.';\n        } else {\n            return isLower ? 'a.t.m.' : 'A.T.M.';\n        }\n    },\n    calendar : {\n        sameDay : '[Hodiaŭ je] LT',\n        nextDay : '[Morgaŭ je] LT',\n        nextWeek : 'dddd [je] LT',\n        lastDay : '[Hieraŭ je] LT',\n        lastWeek : '[pasinta] dddd [je] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'post %s',\n        past : 'antaŭ %s',\n        s : 'sekundoj',\n        m : 'minuto',\n        mm : '%d minutoj',\n        h : 'horo',\n        hh : '%d horoj',\n        d : 'tago',//ne 'diurno', ĉar estas uzita por proksimumo\n        dd : '%d tagoj',\n        M : 'monato',\n        MM : '%d monatoj',\n        y : 'jaro',\n        yy : '%d jaroj'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}a/,\n    ordinal : '%da',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 7  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Spanish (Dominican Republic) [es-do]\n\nvar monthsShortDot = 'ene._feb._mar._abr._may._jun._jul._ago._sep._oct._nov._dic.'.split('_');\nvar monthsShort$1 = 'ene_feb_mar_abr_may_jun_jul_ago_sep_oct_nov_dic'.split('_');\n\nmoment.defineLocale('es-do', {\n    months : 'enero_febrero_marzo_abril_mayo_junio_julio_agosto_septiembre_octubre_noviembre_diciembre'.split('_'),\n    monthsShort : function (m, format) {\n        if (!m) {\n            return monthsShortDot;\n        } else if (/-MMM-/.test(format)) {\n            return monthsShort$1[m.month()];\n        } else {\n            return monthsShortDot[m.month()];\n        }\n    },\n    monthsParseExact : true,\n    weekdays : 'domingo_lunes_martes_miércoles_jueves_viernes_sábado'.split('_'),\n    weekdaysShort : 'dom._lun._mar._mié._jue._vie._sáb.'.split('_'),\n    weekdaysMin : 'do_lu_ma_mi_ju_vi_sá'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat : {\n        LT : 'h:mm A',\n        LTS : 'h:mm:ss A',\n        L : 'DD/MM/YYYY',\n        LL : 'D [de] MMMM [de] YYYY',\n        LLL : 'D [de] MMMM [de] YYYY h:mm A',\n        LLLL : 'dddd, D [de] MMMM [de] YYYY h:mm A'\n    },\n    calendar : {\n        sameDay : function () {\n            return '[hoy a la' + ((this.hours() !== 1) ? 's' : '') + '] LT';\n        },\n        nextDay : function () {\n            return '[mañana a la' + ((this.hours() !== 1) ? 's' : '') + '] LT';\n        },\n        nextWeek : function () {\n            return 'dddd [a la' + ((this.hours() !== 1) ? 's' : '') + '] LT';\n        },\n        lastDay : function () {\n            return '[ayer a la' + ((this.hours() !== 1) ? 's' : '') + '] LT';\n        },\n        lastWeek : function () {\n            return '[el] dddd [pasado a la' + ((this.hours() !== 1) ? 's' : '') + '] LT';\n        },\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'en %s',\n        past : 'hace %s',\n        s : 'unos segundos',\n        m : 'un minuto',\n        mm : '%d minutos',\n        h : 'una hora',\n        hh : '%d horas',\n        d : 'un día',\n        dd : '%d días',\n        M : 'un mes',\n        MM : '%d meses',\n        y : 'un año',\n        yy : '%d años'\n    },\n    dayOfMonthOrdinalParse : /\\d{1,2}º/,\n    ordinal : '%dº',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Spanish [es]\n//! author : Julio Napurí : https://github.com/julionc\n\nvar monthsShortDot$1 = 'ene._feb._mar._abr._may._jun._jul._ago._sep._oct._nov._dic.'.split('_');\nvar monthsShort$2 = 'ene_feb_mar_abr_may_jun_jul_ago_sep_oct_nov_dic'.split('_');\n\nmoment.defineLocale('es', {\n    months : 'enero_febrero_marzo_abril_mayo_junio_julio_agosto_septiembre_octubre_noviembre_diciembre'.split('_'),\n    monthsShort : function (m, format) {\n        if (!m) {\n            return monthsShortDot$1;\n        } else if (/-MMM-/.test(format)) {\n            return monthsShort$2[m.month()];\n        } else {\n            return monthsShortDot$1[m.month()];\n        }\n    },\n    monthsParseExact : true,\n    weekdays : 'domingo_lunes_martes_miércoles_jueves_viernes_sábado'.split('_'),\n    weekdaysShort : 'dom._lun._mar._mié._jue._vie._sáb.'.split('_'),\n    weekdaysMin : 'do_lu_ma_mi_ju_vi_sá'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat : {\n        LT : 'H:mm',\n        LTS : 'H:mm:ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D [de] MMMM [de] YYYY',\n        LLL : 'D [de] MMMM [de] YYYY H:mm',\n        LLLL : 'dddd, D [de] MMMM [de] YYYY H:mm'\n    },\n    calendar : {\n        sameDay : function () {\n            return '[hoy a la' + ((this.hours() !== 1) ? 's' : '') + '] LT';\n        },\n        nextDay : function () {\n            return '[mañana a la' + ((this.hours() !== 1) ? 's' : '') + '] LT';\n        },\n        nextWeek : function () {\n            return 'dddd [a la' + ((this.hours() !== 1) ? 's' : '') + '] LT';\n        },\n        lastDay : function () {\n            return '[ayer a la' + ((this.hours() !== 1) ? 's' : '') + '] LT';\n        },\n        lastWeek : function () {\n            return '[el] dddd [pasado a la' + ((this.hours() !== 1) ? 's' : '') + '] LT';\n        },\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'en %s',\n        past : 'hace %s',\n        s : 'unos segundos',\n        m : 'un minuto',\n        mm : '%d minutos',\n        h : 'una hora',\n        hh : '%d horas',\n        d : 'un día',\n        dd : '%d días',\n        M : 'un mes',\n        MM : '%d meses',\n        y : 'un año',\n        yy : '%d años'\n    },\n    dayOfMonthOrdinalParse : /\\d{1,2}º/,\n    ordinal : '%dº',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Estonian [et]\n//! author : Henry Kehlmann : https://github.com/madhenry\n//! improvements : Illimar Tambek : https://github.com/ragulka\n\nfunction processRelativeTime$3(number, withoutSuffix, key, isFuture) {\n    var format = {\n        's' : ['mõne sekundi', 'mõni sekund', 'paar sekundit'],\n        'm' : ['ühe minuti', 'üks minut'],\n        'mm': [number + ' minuti', number + ' minutit'],\n        'h' : ['ühe tunni', 'tund aega', 'üks tund'],\n        'hh': [number + ' tunni', number + ' tundi'],\n        'd' : ['ühe päeva', 'üks päev'],\n        'M' : ['kuu aja', 'kuu aega', 'üks kuu'],\n        'MM': [number + ' kuu', number + ' kuud'],\n        'y' : ['ühe aasta', 'aasta', 'üks aasta'],\n        'yy': [number + ' aasta', number + ' aastat']\n    };\n    if (withoutSuffix) {\n        return format[key][2] ? format[key][2] : format[key][1];\n    }\n    return isFuture ? format[key][0] : format[key][1];\n}\n\nmoment.defineLocale('et', {\n    months        : 'jaanuar_veebruar_märts_aprill_mai_juuni_juuli_august_september_oktoober_november_detsember'.split('_'),\n    monthsShort   : 'jaan_veebr_märts_apr_mai_juuni_juuli_aug_sept_okt_nov_dets'.split('_'),\n    weekdays      : 'pühapäev_esmaspäev_teisipäev_kolmapäev_neljapäev_reede_laupäev'.split('_'),\n    weekdaysShort : 'P_E_T_K_N_R_L'.split('_'),\n    weekdaysMin   : 'P_E_T_K_N_R_L'.split('_'),\n    longDateFormat : {\n        LT   : 'H:mm',\n        LTS : 'H:mm:ss',\n        L    : 'DD.MM.YYYY',\n        LL   : 'D. MMMM YYYY',\n        LLL  : 'D. MMMM YYYY H:mm',\n        LLLL : 'dddd, D. MMMM YYYY H:mm'\n    },\n    calendar : {\n        sameDay  : '[Täna,] LT',\n        nextDay  : '[Homme,] LT',\n        nextWeek : '[Järgmine] dddd LT',\n        lastDay  : '[Eile,] LT',\n        lastWeek : '[Eelmine] dddd LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : '%s pärast',\n        past   : '%s tagasi',\n        s      : processRelativeTime$3,\n        m      : processRelativeTime$3,\n        mm     : processRelativeTime$3,\n        h      : processRelativeTime$3,\n        hh     : processRelativeTime$3,\n        d      : processRelativeTime$3,\n        dd     : '%d päeva',\n        M      : processRelativeTime$3,\n        MM     : processRelativeTime$3,\n        y      : processRelativeTime$3,\n        yy     : processRelativeTime$3\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}\\./,\n    ordinal : '%d.',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Basque [eu]\n//! author : Eneko Illarramendi : https://github.com/eillarra\n\nmoment.defineLocale('eu', {\n    months : 'urtarrila_otsaila_martxoa_apirila_maiatza_ekaina_uztaila_abuztua_iraila_urria_azaroa_abendua'.split('_'),\n    monthsShort : 'urt._ots._mar._api._mai._eka._uzt._abu._ira._urr._aza._abe.'.split('_'),\n    monthsParseExact : true,\n    weekdays : 'igandea_astelehena_asteartea_asteazkena_osteguna_ostirala_larunbata'.split('_'),\n    weekdaysShort : 'ig._al._ar._az._og._ol._lr.'.split('_'),\n    weekdaysMin : 'ig_al_ar_az_og_ol_lr'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'YYYY-MM-DD',\n        LL : 'YYYY[ko] MMMM[ren] D[a]',\n        LLL : 'YYYY[ko] MMMM[ren] D[a] HH:mm',\n        LLLL : 'dddd, YYYY[ko] MMMM[ren] D[a] HH:mm',\n        l : 'YYYY-M-D',\n        ll : 'YYYY[ko] MMM D[a]',\n        lll : 'YYYY[ko] MMM D[a] HH:mm',\n        llll : 'ddd, YYYY[ko] MMM D[a] HH:mm'\n    },\n    calendar : {\n        sameDay : '[gaur] LT[etan]',\n        nextDay : '[bihar] LT[etan]',\n        nextWeek : 'dddd LT[etan]',\n        lastDay : '[atzo] LT[etan]',\n        lastWeek : '[aurreko] dddd LT[etan]',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : '%s barru',\n        past : 'duela %s',\n        s : 'segundo batzuk',\n        m : 'minutu bat',\n        mm : '%d minutu',\n        h : 'ordu bat',\n        hh : '%d ordu',\n        d : 'egun bat',\n        dd : '%d egun',\n        M : 'hilabete bat',\n        MM : '%d hilabete',\n        y : 'urte bat',\n        yy : '%d urte'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}\\./,\n    ordinal : '%d.',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 7  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Persian [fa]\n//! author : Ebrahim Byagowi : https://github.com/ebraminio\n\nvar symbolMap$5 = {\n    '1': '۱',\n    '2': '۲',\n    '3': '۳',\n    '4': '۴',\n    '5': '۵',\n    '6': '۶',\n    '7': '۷',\n    '8': '۸',\n    '9': '۹',\n    '0': '۰'\n};\nvar numberMap$4 = {\n    '۱': '1',\n    '۲': '2',\n    '۳': '3',\n    '۴': '4',\n    '۵': '5',\n    '۶': '6',\n    '۷': '7',\n    '۸': '8',\n    '۹': '9',\n    '۰': '0'\n};\n\nmoment.defineLocale('fa', {\n    months : 'ژانویه_فوریه_مارس_آوریل_مه_ژوئن_ژوئیه_اوت_سپتامبر_اکتبر_نوامبر_دسامبر'.split('_'),\n    monthsShort : 'ژانویه_فوریه_مارس_آوریل_مه_ژوئن_ژوئیه_اوت_سپتامبر_اکتبر_نوامبر_دسامبر'.split('_'),\n    weekdays : 'یک\\u200cشنبه_دوشنبه_سه\\u200cشنبه_چهارشنبه_پنج\\u200cشنبه_جمعه_شنبه'.split('_'),\n    weekdaysShort : 'یک\\u200cشنبه_دوشنبه_سه\\u200cشنبه_چهارشنبه_پنج\\u200cشنبه_جمعه_شنبه'.split('_'),\n    weekdaysMin : 'ی_د_س_چ_پ_ج_ش'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY HH:mm',\n        LLLL : 'dddd, D MMMM YYYY HH:mm'\n    },\n    meridiemParse: /قبل از ظهر|بعد از ظهر/,\n    isPM: function (input) {\n        return /بعد از ظهر/.test(input);\n    },\n    meridiem : function (hour, minute, isLower) {\n        if (hour < 12) {\n            return 'قبل از ظهر';\n        } else {\n            return 'بعد از ظهر';\n        }\n    },\n    calendar : {\n        sameDay : '[امروز ساعت] LT',\n        nextDay : '[فردا ساعت] LT',\n        nextWeek : 'dddd [ساعت] LT',\n        lastDay : '[دیروز ساعت] LT',\n        lastWeek : 'dddd [پیش] [ساعت] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'در %s',\n        past : '%s پیش',\n        s : 'چند ثانیه',\n        m : 'یک دقیقه',\n        mm : '%d دقیقه',\n        h : 'یک ساعت',\n        hh : '%d ساعت',\n        d : 'یک روز',\n        dd : '%d روز',\n        M : 'یک ماه',\n        MM : '%d ماه',\n        y : 'یک سال',\n        yy : '%d سال'\n    },\n    preparse: function (string) {\n        return string.replace(/[۰-۹]/g, function (match) {\n            return numberMap$4[match];\n        }).replace(/،/g, ',');\n    },\n    postformat: function (string) {\n        return string.replace(/\\d/g, function (match) {\n            return symbolMap$5[match];\n        }).replace(/,/g, '،');\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}م/,\n    ordinal : '%dم',\n    week : {\n        dow : 6, // Saturday is the first day of the week.\n        doy : 12 // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Finnish [fi]\n//! author : Tarmo Aidantausta : https://github.com/bleadof\n\nvar numbersPast = 'nolla yksi kaksi kolme neljä viisi kuusi seitsemän kahdeksan yhdeksän'.split(' ');\nvar numbersFuture = [\n        'nolla', 'yhden', 'kahden', 'kolmen', 'neljän', 'viiden', 'kuuden',\n        numbersPast[7], numbersPast[8], numbersPast[9]\n    ];\nfunction translate$2(number, withoutSuffix, key, isFuture) {\n    var result = '';\n    switch (key) {\n        case 's':\n            return isFuture ? 'muutaman sekunnin' : 'muutama sekunti';\n        case 'm':\n            return isFuture ? 'minuutin' : 'minuutti';\n        case 'mm':\n            result = isFuture ? 'minuutin' : 'minuuttia';\n            break;\n        case 'h':\n            return isFuture ? 'tunnin' : 'tunti';\n        case 'hh':\n            result = isFuture ? 'tunnin' : 'tuntia';\n            break;\n        case 'd':\n            return isFuture ? 'päivän' : 'päivä';\n        case 'dd':\n            result = isFuture ? 'päivän' : 'päivää';\n            break;\n        case 'M':\n            return isFuture ? 'kuukauden' : 'kuukausi';\n        case 'MM':\n            result = isFuture ? 'kuukauden' : 'kuukautta';\n            break;\n        case 'y':\n            return isFuture ? 'vuoden' : 'vuosi';\n        case 'yy':\n            result = isFuture ? 'vuoden' : 'vuotta';\n            break;\n    }\n    result = verbalNumber(number, isFuture) + ' ' + result;\n    return result;\n}\nfunction verbalNumber(number, isFuture) {\n    return number < 10 ? (isFuture ? numbersFuture[number] : numbersPast[number]) : number;\n}\n\nmoment.defineLocale('fi', {\n    months : 'tammikuu_helmikuu_maaliskuu_huhtikuu_toukokuu_kesäkuu_heinäkuu_elokuu_syyskuu_lokakuu_marraskuu_joulukuu'.split('_'),\n    monthsShort : 'tammi_helmi_maalis_huhti_touko_kesä_heinä_elo_syys_loka_marras_joulu'.split('_'),\n    weekdays : 'sunnuntai_maanantai_tiistai_keskiviikko_torstai_perjantai_lauantai'.split('_'),\n    weekdaysShort : 'su_ma_ti_ke_to_pe_la'.split('_'),\n    weekdaysMin : 'su_ma_ti_ke_to_pe_la'.split('_'),\n    longDateFormat : {\n        LT : 'HH.mm',\n        LTS : 'HH.mm.ss',\n        L : 'DD.MM.YYYY',\n        LL : 'Do MMMM[ta] YYYY',\n        LLL : 'Do MMMM[ta] YYYY, [klo] HH.mm',\n        LLLL : 'dddd, Do MMMM[ta] YYYY, [klo] HH.mm',\n        l : 'D.M.YYYY',\n        ll : 'Do MMM YYYY',\n        lll : 'Do MMM YYYY, [klo] HH.mm',\n        llll : 'ddd, Do MMM YYYY, [klo] HH.mm'\n    },\n    calendar : {\n        sameDay : '[tänään] [klo] LT',\n        nextDay : '[huomenna] [klo] LT',\n        nextWeek : 'dddd [klo] LT',\n        lastDay : '[eilen] [klo] LT',\n        lastWeek : '[viime] dddd[na] [klo] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : '%s päästä',\n        past : '%s sitten',\n        s : translate$2,\n        m : translate$2,\n        mm : translate$2,\n        h : translate$2,\n        hh : translate$2,\n        d : translate$2,\n        dd : translate$2,\n        M : translate$2,\n        MM : translate$2,\n        y : translate$2,\n        yy : translate$2\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}\\./,\n    ordinal : '%d.',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Faroese [fo]\n//! author : Ragnar Johannesen : https://github.com/ragnar123\n\nmoment.defineLocale('fo', {\n    months : 'januar_februar_mars_apríl_mai_juni_juli_august_september_oktober_november_desember'.split('_'),\n    monthsShort : 'jan_feb_mar_apr_mai_jun_jul_aug_sep_okt_nov_des'.split('_'),\n    weekdays : 'sunnudagur_mánadagur_týsdagur_mikudagur_hósdagur_fríggjadagur_leygardagur'.split('_'),\n    weekdaysShort : 'sun_mán_týs_mik_hós_frí_ley'.split('_'),\n    weekdaysMin : 'su_má_tý_mi_hó_fr_le'.split('_'),\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY HH:mm',\n        LLLL : 'dddd D. MMMM, YYYY HH:mm'\n    },\n    calendar : {\n        sameDay : '[Í dag kl.] LT',\n        nextDay : '[Í morgin kl.] LT',\n        nextWeek : 'dddd [kl.] LT',\n        lastDay : '[Í gjár kl.] LT',\n        lastWeek : '[síðstu] dddd [kl] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'um %s',\n        past : '%s síðani',\n        s : 'fá sekund',\n        m : 'ein minutt',\n        mm : '%d minuttir',\n        h : 'ein tími',\n        hh : '%d tímar',\n        d : 'ein dagur',\n        dd : '%d dagar',\n        M : 'ein mánaði',\n        MM : '%d mánaðir',\n        y : 'eitt ár',\n        yy : '%d ár'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}\\./,\n    ordinal : '%d.',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : French (Canada) [fr-ca]\n//! author : Jonathan Abourbih : https://github.com/jonbca\n\nmoment.defineLocale('fr-ca', {\n    months : 'janvier_février_mars_avril_mai_juin_juillet_août_septembre_octobre_novembre_décembre'.split('_'),\n    monthsShort : 'janv._févr._mars_avr._mai_juin_juil._août_sept._oct._nov._déc.'.split('_'),\n    monthsParseExact : true,\n    weekdays : 'dimanche_lundi_mardi_mercredi_jeudi_vendredi_samedi'.split('_'),\n    weekdaysShort : 'dim._lun._mar._mer._jeu._ven._sam.'.split('_'),\n    weekdaysMin : 'Di_Lu_Ma_Me_Je_Ve_Sa'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'YYYY-MM-DD',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY HH:mm',\n        LLLL : 'dddd D MMMM YYYY HH:mm'\n    },\n    calendar : {\n        sameDay : '[Aujourd’hui à] LT',\n        nextDay : '[Demain à] LT',\n        nextWeek : 'dddd [à] LT',\n        lastDay : '[Hier à] LT',\n        lastWeek : 'dddd [dernier à] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'dans %s',\n        past : 'il y a %s',\n        s : 'quelques secondes',\n        m : 'une minute',\n        mm : '%d minutes',\n        h : 'une heure',\n        hh : '%d heures',\n        d : 'un jour',\n        dd : '%d jours',\n        M : 'un mois',\n        MM : '%d mois',\n        y : 'un an',\n        yy : '%d ans'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}(er|e)/,\n    ordinal : function (number, period) {\n        switch (period) {\n            // Words with masculine grammatical gender: mois, trimestre, jour\n            default:\n            case 'M':\n            case 'Q':\n            case 'D':\n            case 'DDD':\n            case 'd':\n                return number + (number === 1 ? 'er' : 'e');\n\n            // Words with feminine grammatical gender: semaine\n            case 'w':\n            case 'W':\n                return number + (number === 1 ? 're' : 'e');\n        }\n    }\n});\n\n//! moment.js locale configuration\n//! locale : French (Switzerland) [fr-ch]\n//! author : Gaspard Bucher : https://github.com/gaspard\n\nmoment.defineLocale('fr-ch', {\n    months : 'janvier_février_mars_avril_mai_juin_juillet_août_septembre_octobre_novembre_décembre'.split('_'),\n    monthsShort : 'janv._févr._mars_avr._mai_juin_juil._août_sept._oct._nov._déc.'.split('_'),\n    monthsParseExact : true,\n    weekdays : 'dimanche_lundi_mardi_mercredi_jeudi_vendredi_samedi'.split('_'),\n    weekdaysShort : 'dim._lun._mar._mer._jeu._ven._sam.'.split('_'),\n    weekdaysMin : 'Di_Lu_Ma_Me_Je_Ve_Sa'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD.MM.YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY HH:mm',\n        LLLL : 'dddd D MMMM YYYY HH:mm'\n    },\n    calendar : {\n        sameDay : '[Aujourd’hui à] LT',\n        nextDay : '[Demain à] LT',\n        nextWeek : 'dddd [à] LT',\n        lastDay : '[Hier à] LT',\n        lastWeek : 'dddd [dernier à] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'dans %s',\n        past : 'il y a %s',\n        s : 'quelques secondes',\n        m : 'une minute',\n        mm : '%d minutes',\n        h : 'une heure',\n        hh : '%d heures',\n        d : 'un jour',\n        dd : '%d jours',\n        M : 'un mois',\n        MM : '%d mois',\n        y : 'un an',\n        yy : '%d ans'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}(er|e)/,\n    ordinal : function (number, period) {\n        switch (period) {\n            // Words with masculine grammatical gender: mois, trimestre, jour\n            default:\n            case 'M':\n            case 'Q':\n            case 'D':\n            case 'DDD':\n            case 'd':\n                return number + (number === 1 ? 'er' : 'e');\n\n            // Words with feminine grammatical gender: semaine\n            case 'w':\n            case 'W':\n                return number + (number === 1 ? 're' : 'e');\n        }\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : French [fr]\n//! author : John Fischer : https://github.com/jfroffice\n\nmoment.defineLocale('fr', {\n    months : 'janvier_février_mars_avril_mai_juin_juillet_août_septembre_octobre_novembre_décembre'.split('_'),\n    monthsShort : 'janv._févr._mars_avr._mai_juin_juil._août_sept._oct._nov._déc.'.split('_'),\n    monthsParseExact : true,\n    weekdays : 'dimanche_lundi_mardi_mercredi_jeudi_vendredi_samedi'.split('_'),\n    weekdaysShort : 'dim._lun._mar._mer._jeu._ven._sam.'.split('_'),\n    weekdaysMin : 'Di_Lu_Ma_Me_Je_Ve_Sa'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY HH:mm',\n        LLLL : 'dddd D MMMM YYYY HH:mm'\n    },\n    calendar : {\n        sameDay : '[Aujourd’hui à] LT',\n        nextDay : '[Demain à] LT',\n        nextWeek : 'dddd [à] LT',\n        lastDay : '[Hier à] LT',\n        lastWeek : 'dddd [dernier à] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'dans %s',\n        past : 'il y a %s',\n        s : 'quelques secondes',\n        m : 'une minute',\n        mm : '%d minutes',\n        h : 'une heure',\n        hh : '%d heures',\n        d : 'un jour',\n        dd : '%d jours',\n        M : 'un mois',\n        MM : '%d mois',\n        y : 'un an',\n        yy : '%d ans'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}(er|)/,\n    ordinal : function (number, period) {\n        switch (period) {\n            // TODO: Return 'e' when day of month > 1. Move this case inside\n            // block for masculine words below.\n            // See https://github.com/moment/moment/issues/3375\n            case 'D':\n                return number + (number === 1 ? 'er' : '');\n\n            // Words with masculine grammatical gender: mois, trimestre, jour\n            default:\n            case 'M':\n            case 'Q':\n            case 'DDD':\n            case 'd':\n                return number + (number === 1 ? 'er' : 'e');\n\n            // Words with feminine grammatical gender: semaine\n            case 'w':\n            case 'W':\n                return number + (number === 1 ? 're' : 'e');\n        }\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Frisian [fy]\n//! author : Robin van der Vliet : https://github.com/robin0van0der0v\n\nvar monthsShortWithDots = 'jan._feb._mrt._apr._mai_jun._jul._aug._sep._okt._nov._des.'.split('_');\nvar monthsShortWithoutDots = 'jan_feb_mrt_apr_mai_jun_jul_aug_sep_okt_nov_des'.split('_');\n\nmoment.defineLocale('fy', {\n    months : 'jannewaris_febrewaris_maart_april_maaie_juny_july_augustus_septimber_oktober_novimber_desimber'.split('_'),\n    monthsShort : function (m, format) {\n        if (!m) {\n            return monthsShortWithDots;\n        } else if (/-MMM-/.test(format)) {\n            return monthsShortWithoutDots[m.month()];\n        } else {\n            return monthsShortWithDots[m.month()];\n        }\n    },\n    monthsParseExact : true,\n    weekdays : 'snein_moandei_tiisdei_woansdei_tongersdei_freed_sneon'.split('_'),\n    weekdaysShort : 'si._mo._ti._wo._to._fr._so.'.split('_'),\n    weekdaysMin : 'Si_Mo_Ti_Wo_To_Fr_So'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD-MM-YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY HH:mm',\n        LLLL : 'dddd D MMMM YYYY HH:mm'\n    },\n    calendar : {\n        sameDay: '[hjoed om] LT',\n        nextDay: '[moarn om] LT',\n        nextWeek: 'dddd [om] LT',\n        lastDay: '[juster om] LT',\n        lastWeek: '[ôfrûne] dddd [om] LT',\n        sameElse: 'L'\n    },\n    relativeTime : {\n        future : 'oer %s',\n        past : '%s lyn',\n        s : 'in pear sekonden',\n        m : 'ien minút',\n        mm : '%d minuten',\n        h : 'ien oere',\n        hh : '%d oeren',\n        d : 'ien dei',\n        dd : '%d dagen',\n        M : 'ien moanne',\n        MM : '%d moannen',\n        y : 'ien jier',\n        yy : '%d jierren'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}(ste|de)/,\n    ordinal : function (number) {\n        return number + ((number === 1 || number === 8 || number >= 20) ? 'ste' : 'de');\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Scottish Gaelic [gd]\n//! author : Jon Ashdown : https://github.com/jonashdown\n\nvar months$4 = [\n    'Am Faoilleach', 'An Gearran', 'Am Màrt', 'An Giblean', 'An Cèitean', 'An t-Ògmhios', 'An t-Iuchar', 'An Lùnastal', 'An t-Sultain', 'An Dàmhair', 'An t-Samhain', 'An Dùbhlachd'\n];\n\nvar monthsShort$3 = ['Faoi', 'Gear', 'Màrt', 'Gibl', 'Cèit', 'Ògmh', 'Iuch', 'Lùn', 'Sult', 'Dàmh', 'Samh', 'Dùbh'];\n\nvar weekdays$1 = ['Didòmhnaich', 'Diluain', 'Dimàirt', 'Diciadain', 'Diardaoin', 'Dihaoine', 'Disathairne'];\n\nvar weekdaysShort = ['Did', 'Dil', 'Dim', 'Dic', 'Dia', 'Dih', 'Dis'];\n\nvar weekdaysMin = ['Dò', 'Lu', 'Mà', 'Ci', 'Ar', 'Ha', 'Sa'];\n\nmoment.defineLocale('gd', {\n    months : months$4,\n    monthsShort : monthsShort$3,\n    monthsParseExact : true,\n    weekdays : weekdays$1,\n    weekdaysShort : weekdaysShort,\n    weekdaysMin : weekdaysMin,\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY HH:mm',\n        LLLL : 'dddd, D MMMM YYYY HH:mm'\n    },\n    calendar : {\n        sameDay : '[An-diugh aig] LT',\n        nextDay : '[A-màireach aig] LT',\n        nextWeek : 'dddd [aig] LT',\n        lastDay : '[An-dè aig] LT',\n        lastWeek : 'dddd [seo chaidh] [aig] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'ann an %s',\n        past : 'bho chionn %s',\n        s : 'beagan diogan',\n        m : 'mionaid',\n        mm : '%d mionaidean',\n        h : 'uair',\n        hh : '%d uairean',\n        d : 'latha',\n        dd : '%d latha',\n        M : 'mìos',\n        MM : '%d mìosan',\n        y : 'bliadhna',\n        yy : '%d bliadhna'\n    },\n    dayOfMonthOrdinalParse : /\\d{1,2}(d|na|mh)/,\n    ordinal : function (number) {\n        var output = number === 1 ? 'd' : number % 10 === 2 ? 'na' : 'mh';\n        return number + output;\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Galician [gl]\n//! author : Juan G. Hurtado : https://github.com/juanghurtado\n\nmoment.defineLocale('gl', {\n    months : 'xaneiro_febreiro_marzo_abril_maio_xuño_xullo_agosto_setembro_outubro_novembro_decembro'.split('_'),\n    monthsShort : 'xan._feb._mar._abr._mai._xuñ._xul._ago._set._out._nov._dec.'.split('_'),\n    monthsParseExact: true,\n    weekdays : 'domingo_luns_martes_mércores_xoves_venres_sábado'.split('_'),\n    weekdaysShort : 'dom._lun._mar._mér._xov._ven._sáb.'.split('_'),\n    weekdaysMin : 'do_lu_ma_mé_xo_ve_sá'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat : {\n        LT : 'H:mm',\n        LTS : 'H:mm:ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D [de] MMMM [de] YYYY',\n        LLL : 'D [de] MMMM [de] YYYY H:mm',\n        LLLL : 'dddd, D [de] MMMM [de] YYYY H:mm'\n    },\n    calendar : {\n        sameDay : function () {\n            return '[hoxe ' + ((this.hours() !== 1) ? 'ás' : 'á') + '] LT';\n        },\n        nextDay : function () {\n            return '[mañá ' + ((this.hours() !== 1) ? 'ás' : 'á') + '] LT';\n        },\n        nextWeek : function () {\n            return 'dddd [' + ((this.hours() !== 1) ? 'ás' : 'a') + '] LT';\n        },\n        lastDay : function () {\n            return '[onte ' + ((this.hours() !== 1) ? 'á' : 'a') + '] LT';\n        },\n        lastWeek : function () {\n            return '[o] dddd [pasado ' + ((this.hours() !== 1) ? 'ás' : 'a') + '] LT';\n        },\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : function (str) {\n            if (str.indexOf('un') === 0) {\n                return 'n' + str;\n            }\n            return 'en ' + str;\n        },\n        past : 'hai %s',\n        s : 'uns segundos',\n        m : 'un minuto',\n        mm : '%d minutos',\n        h : 'unha hora',\n        hh : '%d horas',\n        d : 'un día',\n        dd : '%d días',\n        M : 'un mes',\n        MM : '%d meses',\n        y : 'un ano',\n        yy : '%d anos'\n    },\n    dayOfMonthOrdinalParse : /\\d{1,2}º/,\n    ordinal : '%dº',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Konkani Latin script [gom-latn]\n//! author : The Discoverer : https://github.com/WikiDiscoverer\n\nfunction processRelativeTime$4(number, withoutSuffix, key, isFuture) {\n    var format = {\n        's': ['thodde secondanim', 'thodde second'],\n        'm': ['eka mintan', 'ek minute'],\n        'mm': [number + ' mintanim', number + ' mintam'],\n        'h': ['eka horan', 'ek hor'],\n        'hh': [number + ' horanim', number + ' hor'],\n        'd': ['eka disan', 'ek dis'],\n        'dd': [number + ' disanim', number + ' dis'],\n        'M': ['eka mhoinean', 'ek mhoino'],\n        'MM': [number + ' mhoineanim', number + ' mhoine'],\n        'y': ['eka vorsan', 'ek voros'],\n        'yy': [number + ' vorsanim', number + ' vorsam']\n    };\n    return withoutSuffix ? format[key][0] : format[key][1];\n}\n\nmoment.defineLocale('gom-latn', {\n    months : 'Janer_Febrer_Mars_Abril_Mai_Jun_Julai_Agost_Setembr_Otubr_Novembr_Dezembr'.split('_'),\n    monthsShort : 'Jan._Feb._Mars_Abr._Mai_Jun_Jul._Ago._Set._Otu._Nov._Dez.'.split('_'),\n    monthsParseExact : true,\n    weekdays : 'Aitar_Somar_Mongllar_Budvar_Brestar_Sukrar_Son\\'var'.split('_'),\n    weekdaysShort : 'Ait._Som._Mon._Bud._Bre._Suk._Son.'.split('_'),\n    weekdaysMin : 'Ai_Sm_Mo_Bu_Br_Su_Sn'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat : {\n        LT : 'A h:mm [vazta]',\n        LTS : 'A h:mm:ss [vazta]',\n        L : 'DD-MM-YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY A h:mm [vazta]',\n        LLLL : 'dddd, MMMM[achea] Do, YYYY, A h:mm [vazta]',\n        llll: 'ddd, D MMM YYYY, A h:mm [vazta]'\n    },\n    calendar : {\n        sameDay: '[Aiz] LT',\n        nextDay: '[Faleam] LT',\n        nextWeek: '[Ieta to] dddd[,] LT',\n        lastDay: '[Kal] LT',\n        lastWeek: '[Fatlo] dddd[,] LT',\n        sameElse: 'L'\n    },\n    relativeTime : {\n        future : '%s',\n        past : '%s adim',\n        s : processRelativeTime$4,\n        m : processRelativeTime$4,\n        mm : processRelativeTime$4,\n        h : processRelativeTime$4,\n        hh : processRelativeTime$4,\n        d : processRelativeTime$4,\n        dd : processRelativeTime$4,\n        M : processRelativeTime$4,\n        MM : processRelativeTime$4,\n        y : processRelativeTime$4,\n        yy : processRelativeTime$4\n    },\n    dayOfMonthOrdinalParse : /\\d{1,2}(er)/,\n    ordinal : function (number, period) {\n        switch (period) {\n            // the ordinal 'er' only applies to day of the month\n            case 'D':\n                return number + 'er';\n            default:\n            case 'M':\n            case 'Q':\n            case 'DDD':\n            case 'd':\n            case 'w':\n            case 'W':\n                return number;\n        }\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    },\n    meridiemParse: /rati|sokalli|donparam|sanje/,\n    meridiemHour : function (hour, meridiem) {\n        if (hour === 12) {\n            hour = 0;\n        }\n        if (meridiem === 'rati') {\n            return hour < 4 ? hour : hour + 12;\n        } else if (meridiem === 'sokalli') {\n            return hour;\n        } else if (meridiem === 'donparam') {\n            return hour > 12 ? hour : hour + 12;\n        } else if (meridiem === 'sanje') {\n            return hour + 12;\n        }\n    },\n    meridiem : function (hour, minute, isLower) {\n        if (hour < 4) {\n            return 'rati';\n        } else if (hour < 12) {\n            return 'sokalli';\n        } else if (hour < 16) {\n            return 'donparam';\n        } else if (hour < 20) {\n            return 'sanje';\n        } else {\n            return 'rati';\n        }\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Hebrew [he]\n//! author : Tomer Cohen : https://github.com/tomer\n//! author : Moshe Simantov : https://github.com/DevelopmentIL\n//! author : Tal Ater : https://github.com/TalAter\n\nmoment.defineLocale('he', {\n    months : 'ינואר_פברואר_מרץ_אפריל_מאי_יוני_יולי_אוגוסט_ספטמבר_אוקטובר_נובמבר_דצמבר'.split('_'),\n    monthsShort : 'ינו׳_פבר׳_מרץ_אפר׳_מאי_יוני_יולי_אוג׳_ספט׳_אוק׳_נוב׳_דצמ׳'.split('_'),\n    weekdays : 'ראשון_שני_שלישי_רביעי_חמישי_שישי_שבת'.split('_'),\n    weekdaysShort : 'א׳_ב׳_ג׳_ד׳_ה׳_ו׳_ש׳'.split('_'),\n    weekdaysMin : 'א_ב_ג_ד_ה_ו_ש'.split('_'),\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D [ב]MMMM YYYY',\n        LLL : 'D [ב]MMMM YYYY HH:mm',\n        LLLL : 'dddd, D [ב]MMMM YYYY HH:mm',\n        l : 'D/M/YYYY',\n        ll : 'D MMM YYYY',\n        lll : 'D MMM YYYY HH:mm',\n        llll : 'ddd, D MMM YYYY HH:mm'\n    },\n    calendar : {\n        sameDay : '[היום ב־]LT',\n        nextDay : '[מחר ב־]LT',\n        nextWeek : 'dddd [בשעה] LT',\n        lastDay : '[אתמול ב־]LT',\n        lastWeek : '[ביום] dddd [האחרון בשעה] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'בעוד %s',\n        past : 'לפני %s',\n        s : 'מספר שניות',\n        m : 'דקה',\n        mm : '%d דקות',\n        h : 'שעה',\n        hh : function (number) {\n            if (number === 2) {\n                return 'שעתיים';\n            }\n            return number + ' שעות';\n        },\n        d : 'יום',\n        dd : function (number) {\n            if (number === 2) {\n                return 'יומיים';\n            }\n            return number + ' ימים';\n        },\n        M : 'חודש',\n        MM : function (number) {\n            if (number === 2) {\n                return 'חודשיים';\n            }\n            return number + ' חודשים';\n        },\n        y : 'שנה',\n        yy : function (number) {\n            if (number === 2) {\n                return 'שנתיים';\n            } else if (number % 10 === 0 && number !== 10) {\n                return number + ' שנה';\n            }\n            return number + ' שנים';\n        }\n    },\n    meridiemParse: /אחה\"צ|לפנה\"צ|אחרי הצהריים|לפני הצהריים|לפנות בוקר|בבוקר|בערב/i,\n    isPM : function (input) {\n        return /^(אחה\"צ|אחרי הצהריים|בערב)$/.test(input);\n    },\n    meridiem : function (hour, minute, isLower) {\n        if (hour < 5) {\n            return 'לפנות בוקר';\n        } else if (hour < 10) {\n            return 'בבוקר';\n        } else if (hour < 12) {\n            return isLower ? 'לפנה\"צ' : 'לפני הצהריים';\n        } else if (hour < 18) {\n            return isLower ? 'אחה\"צ' : 'אחרי הצהריים';\n        } else {\n            return 'בערב';\n        }\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Hindi [hi]\n//! author : Mayank Singhal : https://github.com/mayanksinghal\n\nvar symbolMap$6 = {\n    '1': '१',\n    '2': '२',\n    '3': '३',\n    '4': '४',\n    '5': '५',\n    '6': '६',\n    '7': '७',\n    '8': '८',\n    '9': '९',\n    '0': '०'\n};\nvar numberMap$5 = {\n    '१': '1',\n    '२': '2',\n    '३': '3',\n    '४': '4',\n    '५': '5',\n    '६': '6',\n    '७': '7',\n    '८': '8',\n    '९': '9',\n    '०': '0'\n};\n\nmoment.defineLocale('hi', {\n    months : 'जनवरी_फ़रवरी_मार्च_अप्रैल_मई_जून_जुलाई_अगस्त_सितम्बर_अक्टूबर_नवम्बर_दिसम्बर'.split('_'),\n    monthsShort : 'जन._फ़र._मार्च_अप्रै._मई_जून_जुल._अग._सित._अक्टू._नव._दिस.'.split('_'),\n    monthsParseExact: true,\n    weekdays : 'रविवार_सोमवार_मंगलवार_बुधवार_गुरूवार_शुक्रवार_शनिवार'.split('_'),\n    weekdaysShort : 'रवि_सोम_मंगल_बुध_गुरू_शुक्र_शनि'.split('_'),\n    weekdaysMin : 'र_सो_मं_बु_गु_शु_श'.split('_'),\n    longDateFormat : {\n        LT : 'A h:mm बजे',\n        LTS : 'A h:mm:ss बजे',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY, A h:mm बजे',\n        LLLL : 'dddd, D MMMM YYYY, A h:mm बजे'\n    },\n    calendar : {\n        sameDay : '[आज] LT',\n        nextDay : '[कल] LT',\n        nextWeek : 'dddd, LT',\n        lastDay : '[कल] LT',\n        lastWeek : '[पिछले] dddd, LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : '%s में',\n        past : '%s पहले',\n        s : 'कुछ ही क्षण',\n        m : 'एक मिनट',\n        mm : '%d मिनट',\n        h : 'एक घंटा',\n        hh : '%d घंटे',\n        d : 'एक दिन',\n        dd : '%d दिन',\n        M : 'एक महीने',\n        MM : '%d महीने',\n        y : 'एक वर्ष',\n        yy : '%d वर्ष'\n    },\n    preparse: function (string) {\n        return string.replace(/[१२३४५६७८९०]/g, function (match) {\n            return numberMap$5[match];\n        });\n    },\n    postformat: function (string) {\n        return string.replace(/\\d/g, function (match) {\n            return symbolMap$6[match];\n        });\n    },\n    // Hindi notation for meridiems are quite fuzzy in practice. While there exists\n    // a rigid notion of a 'Pahar' it is not used as rigidly in modern Hindi.\n    meridiemParse: /रात|सुबह|दोपहर|शाम/,\n    meridiemHour : function (hour, meridiem) {\n        if (hour === 12) {\n            hour = 0;\n        }\n        if (meridiem === 'रात') {\n            return hour < 4 ? hour : hour + 12;\n        } else if (meridiem === 'सुबह') {\n            return hour;\n        } else if (meridiem === 'दोपहर') {\n            return hour >= 10 ? hour : hour + 12;\n        } else if (meridiem === 'शाम') {\n            return hour + 12;\n        }\n    },\n    meridiem : function (hour, minute, isLower) {\n        if (hour < 4) {\n            return 'रात';\n        } else if (hour < 10) {\n            return 'सुबह';\n        } else if (hour < 17) {\n            return 'दोपहर';\n        } else if (hour < 20) {\n            return 'शाम';\n        } else {\n            return 'रात';\n        }\n    },\n    week : {\n        dow : 0, // Sunday is the first day of the week.\n        doy : 6  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Croatian [hr]\n//! author : Bojan Marković : https://github.com/bmarkovic\n\nfunction translate$3(number, withoutSuffix, key) {\n    var result = number + ' ';\n    switch (key) {\n        case 'm':\n            return withoutSuffix ? 'jedna minuta' : 'jedne minute';\n        case 'mm':\n            if (number === 1) {\n                result += 'minuta';\n            } else if (number === 2 || number === 3 || number === 4) {\n                result += 'minute';\n            } else {\n                result += 'minuta';\n            }\n            return result;\n        case 'h':\n            return withoutSuffix ? 'jedan sat' : 'jednog sata';\n        case 'hh':\n            if (number === 1) {\n                result += 'sat';\n            } else if (number === 2 || number === 3 || number === 4) {\n                result += 'sata';\n            } else {\n                result += 'sati';\n            }\n            return result;\n        case 'dd':\n            if (number === 1) {\n                result += 'dan';\n            } else {\n                result += 'dana';\n            }\n            return result;\n        case 'MM':\n            if (number === 1) {\n                result += 'mjesec';\n            } else if (number === 2 || number === 3 || number === 4) {\n                result += 'mjeseca';\n            } else {\n                result += 'mjeseci';\n            }\n            return result;\n        case 'yy':\n            if (number === 1) {\n                result += 'godina';\n            } else if (number === 2 || number === 3 || number === 4) {\n                result += 'godine';\n            } else {\n                result += 'godina';\n            }\n            return result;\n    }\n}\n\nmoment.defineLocale('hr', {\n    months : {\n        format: 'siječnja_veljače_ožujka_travnja_svibnja_lipnja_srpnja_kolovoza_rujna_listopada_studenoga_prosinca'.split('_'),\n        standalone: 'siječanj_veljača_ožujak_travanj_svibanj_lipanj_srpanj_kolovoz_rujan_listopad_studeni_prosinac'.split('_')\n    },\n    monthsShort : 'sij._velj._ožu._tra._svi._lip._srp._kol._ruj._lis._stu._pro.'.split('_'),\n    monthsParseExact: true,\n    weekdays : 'nedjelja_ponedjeljak_utorak_srijeda_četvrtak_petak_subota'.split('_'),\n    weekdaysShort : 'ned._pon._uto._sri._čet._pet._sub.'.split('_'),\n    weekdaysMin : 'ne_po_ut_sr_če_pe_su'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat : {\n        LT : 'H:mm',\n        LTS : 'H:mm:ss',\n        L : 'DD.MM.YYYY',\n        LL : 'D. MMMM YYYY',\n        LLL : 'D. MMMM YYYY H:mm',\n        LLLL : 'dddd, D. MMMM YYYY H:mm'\n    },\n    calendar : {\n        sameDay  : '[danas u] LT',\n        nextDay  : '[sutra u] LT',\n        nextWeek : function () {\n            switch (this.day()) {\n                case 0:\n                    return '[u] [nedjelju] [u] LT';\n                case 3:\n                    return '[u] [srijedu] [u] LT';\n                case 6:\n                    return '[u] [subotu] [u] LT';\n                case 1:\n                case 2:\n                case 4:\n                case 5:\n                    return '[u] dddd [u] LT';\n            }\n        },\n        lastDay  : '[jučer u] LT',\n        lastWeek : function () {\n            switch (this.day()) {\n                case 0:\n                case 3:\n                    return '[prošlu] dddd [u] LT';\n                case 6:\n                    return '[prošle] [subote] [u] LT';\n                case 1:\n                case 2:\n                case 4:\n                case 5:\n                    return '[prošli] dddd [u] LT';\n            }\n        },\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'za %s',\n        past   : 'prije %s',\n        s      : 'par sekundi',\n        m      : translate$3,\n        mm     : translate$3,\n        h      : translate$3,\n        hh     : translate$3,\n        d      : 'dan',\n        dd     : translate$3,\n        M      : 'mjesec',\n        MM     : translate$3,\n        y      : 'godinu',\n        yy     : translate$3\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}\\./,\n    ordinal : '%d.',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 7  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Hungarian [hu]\n//! author : Adam Brunner : https://github.com/adambrunner\n\nvar weekEndings = 'vasárnap hétfőn kedden szerdán csütörtökön pénteken szombaton'.split(' ');\nfunction translate$4(number, withoutSuffix, key, isFuture) {\n    var num = number,\n        suffix;\n    switch (key) {\n        case 's':\n            return (isFuture || withoutSuffix) ? 'néhány másodperc' : 'néhány másodperce';\n        case 'm':\n            return 'egy' + (isFuture || withoutSuffix ? ' perc' : ' perce');\n        case 'mm':\n            return num + (isFuture || withoutSuffix ? ' perc' : ' perce');\n        case 'h':\n            return 'egy' + (isFuture || withoutSuffix ? ' óra' : ' órája');\n        case 'hh':\n            return num + (isFuture || withoutSuffix ? ' óra' : ' órája');\n        case 'd':\n            return 'egy' + (isFuture || withoutSuffix ? ' nap' : ' napja');\n        case 'dd':\n            return num + (isFuture || withoutSuffix ? ' nap' : ' napja');\n        case 'M':\n            return 'egy' + (isFuture || withoutSuffix ? ' hónap' : ' hónapja');\n        case 'MM':\n            return num + (isFuture || withoutSuffix ? ' hónap' : ' hónapja');\n        case 'y':\n            return 'egy' + (isFuture || withoutSuffix ? ' év' : ' éve');\n        case 'yy':\n            return num + (isFuture || withoutSuffix ? ' év' : ' éve');\n    }\n    return '';\n}\nfunction week(isFuture) {\n    return (isFuture ? '' : '[múlt] ') + '[' + weekEndings[this.day()] + '] LT[-kor]';\n}\n\nmoment.defineLocale('hu', {\n    months : 'január_február_március_április_május_június_július_augusztus_szeptember_október_november_december'.split('_'),\n    monthsShort : 'jan_feb_márc_ápr_máj_jún_júl_aug_szept_okt_nov_dec'.split('_'),\n    weekdays : 'vasárnap_hétfő_kedd_szerda_csütörtök_péntek_szombat'.split('_'),\n    weekdaysShort : 'vas_hét_kedd_sze_csüt_pén_szo'.split('_'),\n    weekdaysMin : 'v_h_k_sze_cs_p_szo'.split('_'),\n    longDateFormat : {\n        LT : 'H:mm',\n        LTS : 'H:mm:ss',\n        L : 'YYYY.MM.DD.',\n        LL : 'YYYY. MMMM D.',\n        LLL : 'YYYY. MMMM D. H:mm',\n        LLLL : 'YYYY. MMMM D., dddd H:mm'\n    },\n    meridiemParse: /de|du/i,\n    isPM: function (input) {\n        return input.charAt(1).toLowerCase() === 'u';\n    },\n    meridiem : function (hours, minutes, isLower) {\n        if (hours < 12) {\n            return isLower === true ? 'de' : 'DE';\n        } else {\n            return isLower === true ? 'du' : 'DU';\n        }\n    },\n    calendar : {\n        sameDay : '[ma] LT[-kor]',\n        nextDay : '[holnap] LT[-kor]',\n        nextWeek : function () {\n            return week.call(this, true);\n        },\n        lastDay : '[tegnap] LT[-kor]',\n        lastWeek : function () {\n            return week.call(this, false);\n        },\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : '%s múlva',\n        past : '%s',\n        s : translate$4,\n        m : translate$4,\n        mm : translate$4,\n        h : translate$4,\n        hh : translate$4,\n        d : translate$4,\n        dd : translate$4,\n        M : translate$4,\n        MM : translate$4,\n        y : translate$4,\n        yy : translate$4\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}\\./,\n    ordinal : '%d.',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Armenian [hy-am]\n//! author : Armendarabyan : https://github.com/armendarabyan\n\nmoment.defineLocale('hy-am', {\n    months : {\n        format: 'հունվարի_փետրվարի_մարտի_ապրիլի_մայիսի_հունիսի_հուլիսի_օգոստոսի_սեպտեմբերի_հոկտեմբերի_նոյեմբերի_դեկտեմբերի'.split('_'),\n        standalone: 'հունվար_փետրվար_մարտ_ապրիլ_մայիս_հունիս_հուլիս_օգոստոս_սեպտեմբեր_հոկտեմբեր_նոյեմբեր_դեկտեմբեր'.split('_')\n    },\n    monthsShort : 'հնվ_փտր_մրտ_ապր_մյս_հնս_հլս_օգս_սպտ_հկտ_նմբ_դկտ'.split('_'),\n    weekdays : 'կիրակի_երկուշաբթի_երեքշաբթի_չորեքշաբթի_հինգշաբթի_ուրբաթ_շաբաթ'.split('_'),\n    weekdaysShort : 'կրկ_երկ_երք_չրք_հնգ_ուրբ_շբթ'.split('_'),\n    weekdaysMin : 'կրկ_երկ_երք_չրք_հնգ_ուրբ_շբթ'.split('_'),\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD.MM.YYYY',\n        LL : 'D MMMM YYYY թ.',\n        LLL : 'D MMMM YYYY թ., HH:mm',\n        LLLL : 'dddd, D MMMM YYYY թ., HH:mm'\n    },\n    calendar : {\n        sameDay: '[այսօր] LT',\n        nextDay: '[վաղը] LT',\n        lastDay: '[երեկ] LT',\n        nextWeek: function () {\n            return 'dddd [օրը ժամը] LT';\n        },\n        lastWeek: function () {\n            return '[անցած] dddd [օրը ժամը] LT';\n        },\n        sameElse: 'L'\n    },\n    relativeTime : {\n        future : '%s հետո',\n        past : '%s առաջ',\n        s : 'մի քանի վայրկյան',\n        m : 'րոպե',\n        mm : '%d րոպե',\n        h : 'ժամ',\n        hh : '%d ժամ',\n        d : 'օր',\n        dd : '%d օր',\n        M : 'ամիս',\n        MM : '%d ամիս',\n        y : 'տարի',\n        yy : '%d տարի'\n    },\n    meridiemParse: /գիշերվա|առավոտվա|ցերեկվա|երեկոյան/,\n    isPM: function (input) {\n        return /^(ցերեկվա|երեկոյան)$/.test(input);\n    },\n    meridiem : function (hour) {\n        if (hour < 4) {\n            return 'գիշերվա';\n        } else if (hour < 12) {\n            return 'առավոտվա';\n        } else if (hour < 17) {\n            return 'ցերեկվա';\n        } else {\n            return 'երեկոյան';\n        }\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}|\\d{1,2}-(ին|րդ)/,\n    ordinal: function (number, period) {\n        switch (period) {\n            case 'DDD':\n            case 'w':\n            case 'W':\n            case 'DDDo':\n                if (number === 1) {\n                    return number + '-ին';\n                }\n                return number + '-րդ';\n            default:\n                return number;\n        }\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 7  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Indonesian [id]\n//! author : Mohammad Satrio Utomo : https://github.com/tyok\n//! reference: http://id.wikisource.org/wiki/Pedoman_Umum_Ejaan_Bahasa_Indonesia_yang_Disempurnakan\n\nmoment.defineLocale('id', {\n    months : 'Januari_Februari_Maret_April_Mei_Juni_Juli_Agustus_September_Oktober_November_Desember'.split('_'),\n    monthsShort : 'Jan_Feb_Mar_Apr_Mei_Jun_Jul_Ags_Sep_Okt_Nov_Des'.split('_'),\n    weekdays : 'Minggu_Senin_Selasa_Rabu_Kamis_Jumat_Sabtu'.split('_'),\n    weekdaysShort : 'Min_Sen_Sel_Rab_Kam_Jum_Sab'.split('_'),\n    weekdaysMin : 'Mg_Sn_Sl_Rb_Km_Jm_Sb'.split('_'),\n    longDateFormat : {\n        LT : 'HH.mm',\n        LTS : 'HH.mm.ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY [pukul] HH.mm',\n        LLLL : 'dddd, D MMMM YYYY [pukul] HH.mm'\n    },\n    meridiemParse: /pagi|siang|sore|malam/,\n    meridiemHour : function (hour, meridiem) {\n        if (hour === 12) {\n            hour = 0;\n        }\n        if (meridiem === 'pagi') {\n            return hour;\n        } else if (meridiem === 'siang') {\n            return hour >= 11 ? hour : hour + 12;\n        } else if (meridiem === 'sore' || meridiem === 'malam') {\n            return hour + 12;\n        }\n    },\n    meridiem : function (hours, minutes, isLower) {\n        if (hours < 11) {\n            return 'pagi';\n        } else if (hours < 15) {\n            return 'siang';\n        } else if (hours < 19) {\n            return 'sore';\n        } else {\n            return 'malam';\n        }\n    },\n    calendar : {\n        sameDay : '[Hari ini pukul] LT',\n        nextDay : '[Besok pukul] LT',\n        nextWeek : 'dddd [pukul] LT',\n        lastDay : '[Kemarin pukul] LT',\n        lastWeek : 'dddd [lalu pukul] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'dalam %s',\n        past : '%s yang lalu',\n        s : 'beberapa detik',\n        m : 'semenit',\n        mm : '%d menit',\n        h : 'sejam',\n        hh : '%d jam',\n        d : 'sehari',\n        dd : '%d hari',\n        M : 'sebulan',\n        MM : '%d bulan',\n        y : 'setahun',\n        yy : '%d tahun'\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 7  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Icelandic [is]\n//! author : Hinrik Örn Sigurðsson : https://github.com/hinrik\n\nfunction plural$2(n) {\n    if (n % 100 === 11) {\n        return true;\n    } else if (n % 10 === 1) {\n        return false;\n    }\n    return true;\n}\nfunction translate$5(number, withoutSuffix, key, isFuture) {\n    var result = number + ' ';\n    switch (key) {\n        case 's':\n            return withoutSuffix || isFuture ? 'nokkrar sekúndur' : 'nokkrum sekúndum';\n        case 'm':\n            return withoutSuffix ? 'mínúta' : 'mínútu';\n        case 'mm':\n            if (plural$2(number)) {\n                return result + (withoutSuffix || isFuture ? 'mínútur' : 'mínútum');\n            } else if (withoutSuffix) {\n                return result + 'mínúta';\n            }\n            return result + 'mínútu';\n        case 'hh':\n            if (plural$2(number)) {\n                return result + (withoutSuffix || isFuture ? 'klukkustundir' : 'klukkustundum');\n            }\n            return result + 'klukkustund';\n        case 'd':\n            if (withoutSuffix) {\n                return 'dagur';\n            }\n            return isFuture ? 'dag' : 'degi';\n        case 'dd':\n            if (plural$2(number)) {\n                if (withoutSuffix) {\n                    return result + 'dagar';\n                }\n                return result + (isFuture ? 'daga' : 'dögum');\n            } else if (withoutSuffix) {\n                return result + 'dagur';\n            }\n            return result + (isFuture ? 'dag' : 'degi');\n        case 'M':\n            if (withoutSuffix) {\n                return 'mánuður';\n            }\n            return isFuture ? 'mánuð' : 'mánuði';\n        case 'MM':\n            if (plural$2(number)) {\n                if (withoutSuffix) {\n                    return result + 'mánuðir';\n                }\n                return result + (isFuture ? 'mánuði' : 'mánuðum');\n            } else if (withoutSuffix) {\n                return result + 'mánuður';\n            }\n            return result + (isFuture ? 'mánuð' : 'mánuði');\n        case 'y':\n            return withoutSuffix || isFuture ? 'ár' : 'ári';\n        case 'yy':\n            if (plural$2(number)) {\n                return result + (withoutSuffix || isFuture ? 'ár' : 'árum');\n            }\n            return result + (withoutSuffix || isFuture ? 'ár' : 'ári');\n    }\n}\n\nmoment.defineLocale('is', {\n    months : 'janúar_febrúar_mars_apríl_maí_júní_júlí_ágúst_september_október_nóvember_desember'.split('_'),\n    monthsShort : 'jan_feb_mar_apr_maí_jún_júl_ágú_sep_okt_nóv_des'.split('_'),\n    weekdays : 'sunnudagur_mánudagur_þriðjudagur_miðvikudagur_fimmtudagur_föstudagur_laugardagur'.split('_'),\n    weekdaysShort : 'sun_mán_þri_mið_fim_fös_lau'.split('_'),\n    weekdaysMin : 'Su_Má_Þr_Mi_Fi_Fö_La'.split('_'),\n    longDateFormat : {\n        LT : 'H:mm',\n        LTS : 'H:mm:ss',\n        L : 'DD.MM.YYYY',\n        LL : 'D. MMMM YYYY',\n        LLL : 'D. MMMM YYYY [kl.] H:mm',\n        LLLL : 'dddd, D. MMMM YYYY [kl.] H:mm'\n    },\n    calendar : {\n        sameDay : '[í dag kl.] LT',\n        nextDay : '[á morgun kl.] LT',\n        nextWeek : 'dddd [kl.] LT',\n        lastDay : '[í gær kl.] LT',\n        lastWeek : '[síðasta] dddd [kl.] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'eftir %s',\n        past : 'fyrir %s síðan',\n        s : translate$5,\n        m : translate$5,\n        mm : translate$5,\n        h : 'klukkustund',\n        hh : translate$5,\n        d : translate$5,\n        dd : translate$5,\n        M : translate$5,\n        MM : translate$5,\n        y : translate$5,\n        yy : translate$5\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}\\./,\n    ordinal : '%d.',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Italian [it]\n//! author : Lorenzo : https://github.com/aliem\n//! author: Mattia Larentis: https://github.com/nostalgiaz\n\nmoment.defineLocale('it', {\n    months : 'gennaio_febbraio_marzo_aprile_maggio_giugno_luglio_agosto_settembre_ottobre_novembre_dicembre'.split('_'),\n    monthsShort : 'gen_feb_mar_apr_mag_giu_lug_ago_set_ott_nov_dic'.split('_'),\n    weekdays : 'domenica_lunedì_martedì_mercoledì_giovedì_venerdì_sabato'.split('_'),\n    weekdaysShort : 'dom_lun_mar_mer_gio_ven_sab'.split('_'),\n    weekdaysMin : 'do_lu_ma_me_gi_ve_sa'.split('_'),\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY HH:mm',\n        LLLL : 'dddd, D MMMM YYYY HH:mm'\n    },\n    calendar : {\n        sameDay: '[Oggi alle] LT',\n        nextDay: '[Domani alle] LT',\n        nextWeek: 'dddd [alle] LT',\n        lastDay: '[Ieri alle] LT',\n        lastWeek: function () {\n            switch (this.day()) {\n                case 0:\n                    return '[la scorsa] dddd [alle] LT';\n                default:\n                    return '[lo scorso] dddd [alle] LT';\n            }\n        },\n        sameElse: 'L'\n    },\n    relativeTime : {\n        future : function (s) {\n            return ((/^[0-9].+$/).test(s) ? 'tra' : 'in') + ' ' + s;\n        },\n        past : '%s fa',\n        s : 'alcuni secondi',\n        m : 'un minuto',\n        mm : '%d minuti',\n        h : 'un\\'ora',\n        hh : '%d ore',\n        d : 'un giorno',\n        dd : '%d giorni',\n        M : 'un mese',\n        MM : '%d mesi',\n        y : 'un anno',\n        yy : '%d anni'\n    },\n    dayOfMonthOrdinalParse : /\\d{1,2}º/,\n    ordinal: '%dº',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Japanese [ja]\n//! author : LI Long : https://github.com/baryon\n\nmoment.defineLocale('ja', {\n    months : '1月_2月_3月_4月_5月_6月_7月_8月_9月_10月_11月_12月'.split('_'),\n    monthsShort : '1月_2月_3月_4月_5月_6月_7月_8月_9月_10月_11月_12月'.split('_'),\n    weekdays : '日曜日_月曜日_火曜日_水曜日_木曜日_金曜日_土曜日'.split('_'),\n    weekdaysShort : '日_月_火_水_木_金_土'.split('_'),\n    weekdaysMin : '日_月_火_水_木_金_土'.split('_'),\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'YYYY/MM/DD',\n        LL : 'YYYY年M月D日',\n        LLL : 'YYYY年M月D日 HH:mm',\n        LLLL : 'YYYY年M月D日 HH:mm dddd',\n        l : 'YYYY/MM/DD',\n        ll : 'YYYY年M月D日',\n        lll : 'YYYY年M月D日 HH:mm',\n        llll : 'YYYY年M月D日 HH:mm dddd'\n    },\n    meridiemParse: /午前|午後/i,\n    isPM : function (input) {\n        return input === '午後';\n    },\n    meridiem : function (hour, minute, isLower) {\n        if (hour < 12) {\n            return '午前';\n        } else {\n            return '午後';\n        }\n    },\n    calendar : {\n        sameDay : '[今日] LT',\n        nextDay : '[明日] LT',\n        nextWeek : '[来週]dddd LT',\n        lastDay : '[昨日] LT',\n        lastWeek : '[前週]dddd LT',\n        sameElse : 'L'\n    },\n    dayOfMonthOrdinalParse : /\\d{1,2}日/,\n    ordinal : function (number, period) {\n        switch (period) {\n            case 'd':\n            case 'D':\n            case 'DDD':\n                return number + '日';\n            default:\n                return number;\n        }\n    },\n    relativeTime : {\n        future : '%s後',\n        past : '%s前',\n        s : '数秒',\n        m : '1分',\n        mm : '%d分',\n        h : '1時間',\n        hh : '%d時間',\n        d : '1日',\n        dd : '%d日',\n        M : '1ヶ月',\n        MM : '%dヶ月',\n        y : '1年',\n        yy : '%d年'\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Javanese [jv]\n//! author : Rony Lantip : https://github.com/lantip\n//! reference: http://jv.wikipedia.org/wiki/Basa_Jawa\n\nmoment.defineLocale('jv', {\n    months : 'Januari_Februari_Maret_April_Mei_Juni_Juli_Agustus_September_Oktober_Nopember_Desember'.split('_'),\n    monthsShort : 'Jan_Feb_Mar_Apr_Mei_Jun_Jul_Ags_Sep_Okt_Nop_Des'.split('_'),\n    weekdays : 'Minggu_Senen_Seloso_Rebu_Kemis_Jemuwah_Septu'.split('_'),\n    weekdaysShort : 'Min_Sen_Sel_Reb_Kem_Jem_Sep'.split('_'),\n    weekdaysMin : 'Mg_Sn_Sl_Rb_Km_Jm_Sp'.split('_'),\n    longDateFormat : {\n        LT : 'HH.mm',\n        LTS : 'HH.mm.ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY [pukul] HH.mm',\n        LLLL : 'dddd, D MMMM YYYY [pukul] HH.mm'\n    },\n    meridiemParse: /enjing|siyang|sonten|ndalu/,\n    meridiemHour : function (hour, meridiem) {\n        if (hour === 12) {\n            hour = 0;\n        }\n        if (meridiem === 'enjing') {\n            return hour;\n        } else if (meridiem === 'siyang') {\n            return hour >= 11 ? hour : hour + 12;\n        } else if (meridiem === 'sonten' || meridiem === 'ndalu') {\n            return hour + 12;\n        }\n    },\n    meridiem : function (hours, minutes, isLower) {\n        if (hours < 11) {\n            return 'enjing';\n        } else if (hours < 15) {\n            return 'siyang';\n        } else if (hours < 19) {\n            return 'sonten';\n        } else {\n            return 'ndalu';\n        }\n    },\n    calendar : {\n        sameDay : '[Dinten puniko pukul] LT',\n        nextDay : '[Mbenjang pukul] LT',\n        nextWeek : 'dddd [pukul] LT',\n        lastDay : '[Kala wingi pukul] LT',\n        lastWeek : 'dddd [kepengker pukul] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'wonten ing %s',\n        past : '%s ingkang kepengker',\n        s : 'sawetawis detik',\n        m : 'setunggal menit',\n        mm : '%d menit',\n        h : 'setunggal jam',\n        hh : '%d jam',\n        d : 'sedinten',\n        dd : '%d dinten',\n        M : 'sewulan',\n        MM : '%d wulan',\n        y : 'setaun',\n        yy : '%d taun'\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 7  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Georgian [ka]\n//! author : Irakli Janiashvili : https://github.com/irakli-janiashvili\n\nmoment.defineLocale('ka', {\n    months : {\n        standalone: 'იანვარი_თებერვალი_მარტი_აპრილი_მაისი_ივნისი_ივლისი_აგვისტო_სექტემბერი_ოქტომბერი_ნოემბერი_დეკემბერი'.split('_'),\n        format: 'იანვარს_თებერვალს_მარტს_აპრილის_მაისს_ივნისს_ივლისს_აგვისტს_სექტემბერს_ოქტომბერს_ნოემბერს_დეკემბერს'.split('_')\n    },\n    monthsShort : 'იან_თებ_მარ_აპრ_მაი_ივნ_ივლ_აგვ_სექ_ოქტ_ნოე_დეკ'.split('_'),\n    weekdays : {\n        standalone: 'კვირა_ორშაბათი_სამშაბათი_ოთხშაბათი_ხუთშაბათი_პარასკევი_შაბათი'.split('_'),\n        format: 'კვირას_ორშაბათს_სამშაბათს_ოთხშაბათს_ხუთშაბათს_პარასკევს_შაბათს'.split('_'),\n        isFormat: /(წინა|შემდეგ)/\n    },\n    weekdaysShort : 'კვი_ორშ_სამ_ოთხ_ხუთ_პარ_შაბ'.split('_'),\n    weekdaysMin : 'კვ_ორ_სა_ოთ_ხუ_პა_შა'.split('_'),\n    longDateFormat : {\n        LT : 'h:mm A',\n        LTS : 'h:mm:ss A',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY h:mm A',\n        LLLL : 'dddd, D MMMM YYYY h:mm A'\n    },\n    calendar : {\n        sameDay : '[დღეს] LT[-ზე]',\n        nextDay : '[ხვალ] LT[-ზე]',\n        lastDay : '[გუშინ] LT[-ზე]',\n        nextWeek : '[შემდეგ] dddd LT[-ზე]',\n        lastWeek : '[წინა] dddd LT-ზე',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : function (s) {\n            return (/(წამი|წუთი|საათი|წელი)/).test(s) ?\n                s.replace(/ი$/, 'ში') :\n                s + 'ში';\n        },\n        past : function (s) {\n            if ((/(წამი|წუთი|საათი|დღე|თვე)/).test(s)) {\n                return s.replace(/(ი|ე)$/, 'ის უკან');\n            }\n            if ((/წელი/).test(s)) {\n                return s.replace(/წელი$/, 'წლის უკან');\n            }\n        },\n        s : 'რამდენიმე წამი',\n        m : 'წუთი',\n        mm : '%d წუთი',\n        h : 'საათი',\n        hh : '%d საათი',\n        d : 'დღე',\n        dd : '%d დღე',\n        M : 'თვე',\n        MM : '%d თვე',\n        y : 'წელი',\n        yy : '%d წელი'\n    },\n    dayOfMonthOrdinalParse: /0|1-ლი|მე-\\d{1,2}|\\d{1,2}-ე/,\n    ordinal : function (number) {\n        if (number === 0) {\n            return number;\n        }\n        if (number === 1) {\n            return number + '-ლი';\n        }\n        if ((number < 20) || (number <= 100 && (number % 20 === 0)) || (number % 100 === 0)) {\n            return 'მე-' + number;\n        }\n        return number + '-ე';\n    },\n    week : {\n        dow : 1,\n        doy : 7\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Kazakh [kk]\n//! authors : Nurlan Rakhimzhanov : https://github.com/nurlan\n\nvar suffixes$1 = {\n    0: '-ші',\n    1: '-ші',\n    2: '-ші',\n    3: '-ші',\n    4: '-ші',\n    5: '-ші',\n    6: '-шы',\n    7: '-ші',\n    8: '-ші',\n    9: '-шы',\n    10: '-шы',\n    20: '-шы',\n    30: '-шы',\n    40: '-шы',\n    50: '-ші',\n    60: '-шы',\n    70: '-ші',\n    80: '-ші',\n    90: '-шы',\n    100: '-ші'\n};\n\nmoment.defineLocale('kk', {\n    months : 'қаңтар_ақпан_наурыз_сәуір_мамыр_маусым_шілде_тамыз_қыркүйек_қазан_қараша_желтоқсан'.split('_'),\n    monthsShort : 'қаң_ақп_нау_сәу_мам_мау_шіл_там_қыр_қаз_қар_жел'.split('_'),\n    weekdays : 'жексенбі_дүйсенбі_сейсенбі_сәрсенбі_бейсенбі_жұма_сенбі'.split('_'),\n    weekdaysShort : 'жек_дүй_сей_сәр_бей_жұм_сен'.split('_'),\n    weekdaysMin : 'жк_дй_сй_ср_бй_жм_сн'.split('_'),\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD.MM.YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY HH:mm',\n        LLLL : 'dddd, D MMMM YYYY HH:mm'\n    },\n    calendar : {\n        sameDay : '[Бүгін сағат] LT',\n        nextDay : '[Ертең сағат] LT',\n        nextWeek : 'dddd [сағат] LT',\n        lastDay : '[Кеше сағат] LT',\n        lastWeek : '[Өткен аптаның] dddd [сағат] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : '%s ішінде',\n        past : '%s бұрын',\n        s : 'бірнеше секунд',\n        m : 'бір минут',\n        mm : '%d минут',\n        h : 'бір сағат',\n        hh : '%d сағат',\n        d : 'бір күн',\n        dd : '%d күн',\n        M : 'бір ай',\n        MM : '%d ай',\n        y : 'бір жыл',\n        yy : '%d жыл'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}-(ші|шы)/,\n    ordinal : function (number) {\n        var a = number % 10,\n            b = number >= 100 ? 100 : null;\n        return number + (suffixes$1[number] || suffixes$1[a] || suffixes$1[b]);\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 7  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Cambodian [km]\n//! author : Kruy Vanna : https://github.com/kruyvanna\n\nmoment.defineLocale('km', {\n    months: 'មករា_កុម្ភៈ_មីនា_មេសា_ឧសភា_មិថុនា_កក្កដា_សីហា_កញ្ញា_តុលា_វិច្ឆិកា_ធ្នូ'.split('_'),\n    monthsShort: 'មករា_កុម្ភៈ_មីនា_មេសា_ឧសភា_មិថុនា_កក្កដា_សីហា_កញ្ញា_តុលា_វិច្ឆិកា_ធ្នូ'.split('_'),\n    weekdays: 'អាទិត្យ_ច័ន្ទ_អង្គារ_ពុធ_ព្រហស្បតិ៍_សុក្រ_សៅរ៍'.split('_'),\n    weekdaysShort: 'អាទិត្យ_ច័ន្ទ_អង្គារ_ពុធ_ព្រហស្បតិ៍_សុក្រ_សៅរ៍'.split('_'),\n    weekdaysMin: 'អាទិត្យ_ច័ន្ទ_អង្គារ_ពុធ_ព្រហស្បតិ៍_សុក្រ_សៅរ៍'.split('_'),\n    longDateFormat: {\n        LT: 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L: 'DD/MM/YYYY',\n        LL: 'D MMMM YYYY',\n        LLL: 'D MMMM YYYY HH:mm',\n        LLLL: 'dddd, D MMMM YYYY HH:mm'\n    },\n    calendar: {\n        sameDay: '[ថ្ងៃនេះ ម៉ោង] LT',\n        nextDay: '[ស្អែក ម៉ោង] LT',\n        nextWeek: 'dddd [ម៉ោង] LT',\n        lastDay: '[ម្សិលមិញ ម៉ោង] LT',\n        lastWeek: 'dddd [សប្តាហ៍មុន] [ម៉ោង] LT',\n        sameElse: 'L'\n    },\n    relativeTime: {\n        future: '%sទៀត',\n        past: '%sមុន',\n        s: 'ប៉ុន្មានវិនាទី',\n        m: 'មួយនាទី',\n        mm: '%d នាទី',\n        h: 'មួយម៉ោង',\n        hh: '%d ម៉ោង',\n        d: 'មួយថ្ងៃ',\n        dd: '%d ថ្ងៃ',\n        M: 'មួយខែ',\n        MM: '%d ខែ',\n        y: 'មួយឆ្នាំ',\n        yy: '%d ឆ្នាំ'\n    },\n    week: {\n        dow: 1, // Monday is the first day of the week.\n        doy: 4 // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Kannada [kn]\n//! author : Rajeev Naik : https://github.com/rajeevnaikte\n\nvar symbolMap$7 = {\n    '1': '೧',\n    '2': '೨',\n    '3': '೩',\n    '4': '೪',\n    '5': '೫',\n    '6': '೬',\n    '7': '೭',\n    '8': '೮',\n    '9': '೯',\n    '0': '೦'\n};\nvar numberMap$6 = {\n    '೧': '1',\n    '೨': '2',\n    '೩': '3',\n    '೪': '4',\n    '೫': '5',\n    '೬': '6',\n    '೭': '7',\n    '೮': '8',\n    '೯': '9',\n    '೦': '0'\n};\n\nmoment.defineLocale('kn', {\n    months : 'ಜನವರಿ_ಫೆಬ್ರವರಿ_ಮಾರ್ಚ್_ಏಪ್ರಿಲ್_ಮೇ_ಜೂನ್_ಜುಲೈ_ಆಗಸ್ಟ್_ಸೆಪ್ಟೆಂಬರ್_ಅಕ್ಟೋಬರ್_ನವೆಂಬರ್_ಡಿಸೆಂಬರ್'.split('_'),\n    monthsShort : 'ಜನ_ಫೆಬ್ರ_ಮಾರ್ಚ್_ಏಪ್ರಿಲ್_ಮೇ_ಜೂನ್_ಜುಲೈ_ಆಗಸ್ಟ್_ಸೆಪ್ಟೆಂಬ_ಅಕ್ಟೋಬ_ನವೆಂಬ_ಡಿಸೆಂಬ'.split('_'),\n    monthsParseExact: true,\n    weekdays : 'ಭಾನುವಾರ_ಸೋಮವಾರ_ಮಂಗಳವಾರ_ಬುಧವಾರ_ಗುರುವಾರ_ಶುಕ್ರವಾರ_ಶನಿವಾರ'.split('_'),\n    weekdaysShort : 'ಭಾನು_ಸೋಮ_ಮಂಗಳ_ಬುಧ_ಗುರು_ಶುಕ್ರ_ಶನಿ'.split('_'),\n    weekdaysMin : 'ಭಾ_ಸೋ_ಮಂ_ಬು_ಗು_ಶು_ಶ'.split('_'),\n    longDateFormat : {\n        LT : 'A h:mm',\n        LTS : 'A h:mm:ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY, A h:mm',\n        LLLL : 'dddd, D MMMM YYYY, A h:mm'\n    },\n    calendar : {\n        sameDay : '[ಇಂದು] LT',\n        nextDay : '[ನಾಳೆ] LT',\n        nextWeek : 'dddd, LT',\n        lastDay : '[ನಿನ್ನೆ] LT',\n        lastWeek : '[ಕೊನೆಯ] dddd, LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : '%s ನಂತರ',\n        past : '%s ಹಿಂದೆ',\n        s : 'ಕೆಲವು ಕ್ಷಣಗಳು',\n        m : 'ಒಂದು ನಿಮಿಷ',\n        mm : '%d ನಿಮಿಷ',\n        h : 'ಒಂದು ಗಂಟೆ',\n        hh : '%d ಗಂಟೆ',\n        d : 'ಒಂದು ದಿನ',\n        dd : '%d ದಿನ',\n        M : 'ಒಂದು ತಿಂಗಳು',\n        MM : '%d ತಿಂಗಳು',\n        y : 'ಒಂದು ವರ್ಷ',\n        yy : '%d ವರ್ಷ'\n    },\n    preparse: function (string) {\n        return string.replace(/[೧೨೩೪೫೬೭೮೯೦]/g, function (match) {\n            return numberMap$6[match];\n        });\n    },\n    postformat: function (string) {\n        return string.replace(/\\d/g, function (match) {\n            return symbolMap$7[match];\n        });\n    },\n    meridiemParse: /ರಾತ್ರಿ|ಬೆಳಿಗ್ಗೆ|ಮಧ್ಯಾಹ್ನ|ಸಂಜೆ/,\n    meridiemHour : function (hour, meridiem) {\n        if (hour === 12) {\n            hour = 0;\n        }\n        if (meridiem === 'ರಾತ್ರಿ') {\n            return hour < 4 ? hour : hour + 12;\n        } else if (meridiem === 'ಬೆಳಿಗ್ಗೆ') {\n            return hour;\n        } else if (meridiem === 'ಮಧ್ಯಾಹ್ನ') {\n            return hour >= 10 ? hour : hour + 12;\n        } else if (meridiem === 'ಸಂಜೆ') {\n            return hour + 12;\n        }\n    },\n    meridiem : function (hour, minute, isLower) {\n        if (hour < 4) {\n            return 'ರಾತ್ರಿ';\n        } else if (hour < 10) {\n            return 'ಬೆಳಿಗ್ಗೆ';\n        } else if (hour < 17) {\n            return 'ಮಧ್ಯಾಹ್ನ';\n        } else if (hour < 20) {\n            return 'ಸಂಜೆ';\n        } else {\n            return 'ರಾತ್ರಿ';\n        }\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}(ನೇ)/,\n    ordinal : function (number) {\n        return number + 'ನೇ';\n    },\n    week : {\n        dow : 0, // Sunday is the first day of the week.\n        doy : 6  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Korean [ko]\n//! author : Kyungwook, Park : https://github.com/kyungw00k\n//! author : Jeeeyul Lee <jeeeyul@gmail.com>\n\nmoment.defineLocale('ko', {\n    months : '1월_2월_3월_4월_5월_6월_7월_8월_9월_10월_11월_12월'.split('_'),\n    monthsShort : '1월_2월_3월_4월_5월_6월_7월_8월_9월_10월_11월_12월'.split('_'),\n    weekdays : '일요일_월요일_화요일_수요일_목요일_금요일_토요일'.split('_'),\n    weekdaysShort : '일_월_화_수_목_금_토'.split('_'),\n    weekdaysMin : '일_월_화_수_목_금_토'.split('_'),\n    longDateFormat : {\n        LT : 'A h:mm',\n        LTS : 'A h:mm:ss',\n        L : 'YYYY.MM.DD',\n        LL : 'YYYY년 MMMM D일',\n        LLL : 'YYYY년 MMMM D일 A h:mm',\n        LLLL : 'YYYY년 MMMM D일 dddd A h:mm',\n        l : 'YYYY.MM.DD',\n        ll : 'YYYY년 MMMM D일',\n        lll : 'YYYY년 MMMM D일 A h:mm',\n        llll : 'YYYY년 MMMM D일 dddd A h:mm'\n    },\n    calendar : {\n        sameDay : '오늘 LT',\n        nextDay : '내일 LT',\n        nextWeek : 'dddd LT',\n        lastDay : '어제 LT',\n        lastWeek : '지난주 dddd LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : '%s 후',\n        past : '%s 전',\n        s : '몇 초',\n        ss : '%d초',\n        m : '1분',\n        mm : '%d분',\n        h : '한 시간',\n        hh : '%d시간',\n        d : '하루',\n        dd : '%d일',\n        M : '한 달',\n        MM : '%d달',\n        y : '일 년',\n        yy : '%d년'\n    },\n    dayOfMonthOrdinalParse : /\\d{1,2}일/,\n    ordinal : '%d일',\n    meridiemParse : /오전|오후/,\n    isPM : function (token) {\n        return token === '오후';\n    },\n    meridiem : function (hour, minute, isUpper) {\n        return hour < 12 ? '오전' : '오후';\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Kyrgyz [ky]\n//! author : Chyngyz Arystan uulu : https://github.com/chyngyz\n\n\nvar suffixes$2 = {\n    0: '-чү',\n    1: '-чи',\n    2: '-чи',\n    3: '-чү',\n    4: '-чү',\n    5: '-чи',\n    6: '-чы',\n    7: '-чи',\n    8: '-чи',\n    9: '-чу',\n    10: '-чу',\n    20: '-чы',\n    30: '-чу',\n    40: '-чы',\n    50: '-чү',\n    60: '-чы',\n    70: '-чи',\n    80: '-чи',\n    90: '-чу',\n    100: '-чү'\n};\n\nmoment.defineLocale('ky', {\n    months : 'январь_февраль_март_апрель_май_июнь_июль_август_сентябрь_октябрь_ноябрь_декабрь'.split('_'),\n    monthsShort : 'янв_фев_март_апр_май_июнь_июль_авг_сен_окт_ноя_дек'.split('_'),\n    weekdays : 'Жекшемби_Дүйшөмбү_Шейшемби_Шаршемби_Бейшемби_Жума_Ишемби'.split('_'),\n    weekdaysShort : 'Жек_Дүй_Шей_Шар_Бей_Жум_Ише'.split('_'),\n    weekdaysMin : 'Жк_Дй_Шй_Шр_Бй_Жм_Иш'.split('_'),\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD.MM.YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY HH:mm',\n        LLLL : 'dddd, D MMMM YYYY HH:mm'\n    },\n    calendar : {\n        sameDay : '[Бүгүн саат] LT',\n        nextDay : '[Эртең саат] LT',\n        nextWeek : 'dddd [саат] LT',\n        lastDay : '[Кече саат] LT',\n        lastWeek : '[Өткен аптанын] dddd [күнү] [саат] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : '%s ичинде',\n        past : '%s мурун',\n        s : 'бирнече секунд',\n        m : 'бир мүнөт',\n        mm : '%d мүнөт',\n        h : 'бир саат',\n        hh : '%d саат',\n        d : 'бир күн',\n        dd : '%d күн',\n        M : 'бир ай',\n        MM : '%d ай',\n        y : 'бир жыл',\n        yy : '%d жыл'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}-(чи|чы|чү|чу)/,\n    ordinal : function (number) {\n        var a = number % 10,\n            b = number >= 100 ? 100 : null;\n        return number + (suffixes$2[number] || suffixes$2[a] || suffixes$2[b]);\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 7  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Luxembourgish [lb]\n//! author : mweimerskirch : https://github.com/mweimerskirch\n//! author : David Raison : https://github.com/kwisatz\n\nfunction processRelativeTime$5(number, withoutSuffix, key, isFuture) {\n    var format = {\n        'm': ['eng Minutt', 'enger Minutt'],\n        'h': ['eng Stonn', 'enger Stonn'],\n        'd': ['een Dag', 'engem Dag'],\n        'M': ['ee Mount', 'engem Mount'],\n        'y': ['ee Joer', 'engem Joer']\n    };\n    return withoutSuffix ? format[key][0] : format[key][1];\n}\nfunction processFutureTime(string) {\n    var number = string.substr(0, string.indexOf(' '));\n    if (eifelerRegelAppliesToNumber(number)) {\n        return 'a ' + string;\n    }\n    return 'an ' + string;\n}\nfunction processPastTime(string) {\n    var number = string.substr(0, string.indexOf(' '));\n    if (eifelerRegelAppliesToNumber(number)) {\n        return 'viru ' + string;\n    }\n    return 'virun ' + string;\n}\n/**\n * Returns true if the word before the given number loses the '-n' ending.\n * e.g. 'an 10 Deeg' but 'a 5 Deeg'\n *\n * @param number {integer}\n * @returns {boolean}\n */\nfunction eifelerRegelAppliesToNumber(number) {\n    number = parseInt(number, 10);\n    if (isNaN(number)) {\n        return false;\n    }\n    if (number < 0) {\n        // Negative Number --> always true\n        return true;\n    } else if (number < 10) {\n        // Only 1 digit\n        if (4 <= number && number <= 7) {\n            return true;\n        }\n        return false;\n    } else if (number < 100) {\n        // 2 digits\n        var lastDigit = number % 10, firstDigit = number / 10;\n        if (lastDigit === 0) {\n            return eifelerRegelAppliesToNumber(firstDigit);\n        }\n        return eifelerRegelAppliesToNumber(lastDigit);\n    } else if (number < 10000) {\n        // 3 or 4 digits --> recursively check first digit\n        while (number >= 10) {\n            number = number / 10;\n        }\n        return eifelerRegelAppliesToNumber(number);\n    } else {\n        // Anything larger than 4 digits: recursively check first n-3 digits\n        number = number / 1000;\n        return eifelerRegelAppliesToNumber(number);\n    }\n}\n\nmoment.defineLocale('lb', {\n    months: 'Januar_Februar_Mäerz_Abrëll_Mee_Juni_Juli_August_September_Oktober_November_Dezember'.split('_'),\n    monthsShort: 'Jan._Febr._Mrz._Abr._Mee_Jun._Jul._Aug._Sept._Okt._Nov._Dez.'.split('_'),\n    monthsParseExact : true,\n    weekdays: 'Sonndeg_Méindeg_Dënschdeg_Mëttwoch_Donneschdeg_Freideg_Samschdeg'.split('_'),\n    weekdaysShort: 'So._Mé._Dë._Më._Do._Fr._Sa.'.split('_'),\n    weekdaysMin: 'So_Mé_Dë_Më_Do_Fr_Sa'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat: {\n        LT: 'H:mm [Auer]',\n        LTS: 'H:mm:ss [Auer]',\n        L: 'DD.MM.YYYY',\n        LL: 'D. MMMM YYYY',\n        LLL: 'D. MMMM YYYY H:mm [Auer]',\n        LLLL: 'dddd, D. MMMM YYYY H:mm [Auer]'\n    },\n    calendar: {\n        sameDay: '[Haut um] LT',\n        sameElse: 'L',\n        nextDay: '[Muer um] LT',\n        nextWeek: 'dddd [um] LT',\n        lastDay: '[Gëschter um] LT',\n        lastWeek: function () {\n            // Different date string for 'Dënschdeg' (Tuesday) and 'Donneschdeg' (Thursday) due to phonological rule\n            switch (this.day()) {\n                case 2:\n                case 4:\n                    return '[Leschten] dddd [um] LT';\n                default:\n                    return '[Leschte] dddd [um] LT';\n            }\n        }\n    },\n    relativeTime : {\n        future : processFutureTime,\n        past : processPastTime,\n        s : 'e puer Sekonnen',\n        m : processRelativeTime$5,\n        mm : '%d Minutten',\n        h : processRelativeTime$5,\n        hh : '%d Stonnen',\n        d : processRelativeTime$5,\n        dd : '%d Deeg',\n        M : processRelativeTime$5,\n        MM : '%d Méint',\n        y : processRelativeTime$5,\n        yy : '%d Joer'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}\\./,\n    ordinal: '%d.',\n    week: {\n        dow: 1, // Monday is the first day of the week.\n        doy: 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Lao [lo]\n//! author : Ryan Hart : https://github.com/ryanhart2\n\nmoment.defineLocale('lo', {\n    months : 'ມັງກອນ_ກຸມພາ_ມີນາ_ເມສາ_ພຶດສະພາ_ມິຖຸນາ_ກໍລະກົດ_ສິງຫາ_ກັນຍາ_ຕຸລາ_ພະຈິກ_ທັນວາ'.split('_'),\n    monthsShort : 'ມັງກອນ_ກຸມພາ_ມີນາ_ເມສາ_ພຶດສະພາ_ມິຖຸນາ_ກໍລະກົດ_ສິງຫາ_ກັນຍາ_ຕຸລາ_ພະຈິກ_ທັນວາ'.split('_'),\n    weekdays : 'ອາທິດ_ຈັນ_ອັງຄານ_ພຸດ_ພະຫັດ_ສຸກ_ເສົາ'.split('_'),\n    weekdaysShort : 'ທິດ_ຈັນ_ອັງຄານ_ພຸດ_ພະຫັດ_ສຸກ_ເສົາ'.split('_'),\n    weekdaysMin : 'ທ_ຈ_ອຄ_ພ_ພຫ_ສກ_ສ'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY HH:mm',\n        LLLL : 'ວັນdddd D MMMM YYYY HH:mm'\n    },\n    meridiemParse: /ຕອນເຊົ້າ|ຕອນແລງ/,\n    isPM: function (input) {\n        return input === 'ຕອນແລງ';\n    },\n    meridiem : function (hour, minute, isLower) {\n        if (hour < 12) {\n            return 'ຕອນເຊົ້າ';\n        } else {\n            return 'ຕອນແລງ';\n        }\n    },\n    calendar : {\n        sameDay : '[ມື້ນີ້ເວລາ] LT',\n        nextDay : '[ມື້ອື່ນເວລາ] LT',\n        nextWeek : '[ວັນ]dddd[ໜ້າເວລາ] LT',\n        lastDay : '[ມື້ວານນີ້ເວລາ] LT',\n        lastWeek : '[ວັນ]dddd[ແລ້ວນີ້ເວລາ] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'ອີກ %s',\n        past : '%sຜ່ານມາ',\n        s : 'ບໍ່ເທົ່າໃດວິນາທີ',\n        m : '1 ນາທີ',\n        mm : '%d ນາທີ',\n        h : '1 ຊົ່ວໂມງ',\n        hh : '%d ຊົ່ວໂມງ',\n        d : '1 ມື້',\n        dd : '%d ມື້',\n        M : '1 ເດືອນ',\n        MM : '%d ເດືອນ',\n        y : '1 ປີ',\n        yy : '%d ປີ'\n    },\n    dayOfMonthOrdinalParse: /(ທີ່)\\d{1,2}/,\n    ordinal : function (number) {\n        return 'ທີ່' + number;\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Lithuanian [lt]\n//! author : Mindaugas Mozūras : https://github.com/mmozuras\n\nvar units = {\n    'm' : 'minutė_minutės_minutę',\n    'mm': 'minutės_minučių_minutes',\n    'h' : 'valanda_valandos_valandą',\n    'hh': 'valandos_valandų_valandas',\n    'd' : 'diena_dienos_dieną',\n    'dd': 'dienos_dienų_dienas',\n    'M' : 'mėnuo_mėnesio_mėnesį',\n    'MM': 'mėnesiai_mėnesių_mėnesius',\n    'y' : 'metai_metų_metus',\n    'yy': 'metai_metų_metus'\n};\nfunction translateSeconds(number, withoutSuffix, key, isFuture) {\n    if (withoutSuffix) {\n        return 'kelios sekundės';\n    } else {\n        return isFuture ? 'kelių sekundžių' : 'kelias sekundes';\n    }\n}\nfunction translateSingular(number, withoutSuffix, key, isFuture) {\n    return withoutSuffix ? forms(key)[0] : (isFuture ? forms(key)[1] : forms(key)[2]);\n}\nfunction special(number) {\n    return number % 10 === 0 || (number > 10 && number < 20);\n}\nfunction forms(key) {\n    return units[key].split('_');\n}\nfunction translate$6(number, withoutSuffix, key, isFuture) {\n    var result = number + ' ';\n    if (number === 1) {\n        return result + translateSingular(number, withoutSuffix, key[0], isFuture);\n    } else if (withoutSuffix) {\n        return result + (special(number) ? forms(key)[1] : forms(key)[0]);\n    } else {\n        if (isFuture) {\n            return result + forms(key)[1];\n        } else {\n            return result + (special(number) ? forms(key)[1] : forms(key)[2]);\n        }\n    }\n}\nmoment.defineLocale('lt', {\n    months : {\n        format: 'sausio_vasario_kovo_balandžio_gegužės_birželio_liepos_rugpjūčio_rugsėjo_spalio_lapkričio_gruodžio'.split('_'),\n        standalone: 'sausis_vasaris_kovas_balandis_gegužė_birželis_liepa_rugpjūtis_rugsėjis_spalis_lapkritis_gruodis'.split('_'),\n        isFormat: /D[oD]?(\\[[^\\[\\]]*\\]|\\s)+MMMM?|MMMM?(\\[[^\\[\\]]*\\]|\\s)+D[oD]?/\n    },\n    monthsShort : 'sau_vas_kov_bal_geg_bir_lie_rgp_rgs_spa_lap_grd'.split('_'),\n    weekdays : {\n        format: 'sekmadienį_pirmadienį_antradienį_trečiadienį_ketvirtadienį_penktadienį_šeštadienį'.split('_'),\n        standalone: 'sekmadienis_pirmadienis_antradienis_trečiadienis_ketvirtadienis_penktadienis_šeštadienis'.split('_'),\n        isFormat: /dddd HH:mm/\n    },\n    weekdaysShort : 'Sek_Pir_Ant_Tre_Ket_Pen_Šeš'.split('_'),\n    weekdaysMin : 'S_P_A_T_K_Pn_Š'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'YYYY-MM-DD',\n        LL : 'YYYY [m.] MMMM D [d.]',\n        LLL : 'YYYY [m.] MMMM D [d.], HH:mm [val.]',\n        LLLL : 'YYYY [m.] MMMM D [d.], dddd, HH:mm [val.]',\n        l : 'YYYY-MM-DD',\n        ll : 'YYYY [m.] MMMM D [d.]',\n        lll : 'YYYY [m.] MMMM D [d.], HH:mm [val.]',\n        llll : 'YYYY [m.] MMMM D [d.], ddd, HH:mm [val.]'\n    },\n    calendar : {\n        sameDay : '[Šiandien] LT',\n        nextDay : '[Rytoj] LT',\n        nextWeek : 'dddd LT',\n        lastDay : '[Vakar] LT',\n        lastWeek : '[Praėjusį] dddd LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'po %s',\n        past : 'prieš %s',\n        s : translateSeconds,\n        m : translateSingular,\n        mm : translate$6,\n        h : translateSingular,\n        hh : translate$6,\n        d : translateSingular,\n        dd : translate$6,\n        M : translateSingular,\n        MM : translate$6,\n        y : translateSingular,\n        yy : translate$6\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}-oji/,\n    ordinal : function (number) {\n        return number + '-oji';\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Latvian [lv]\n//! author : Kristaps Karlsons : https://github.com/skakri\n//! author : Jānis Elmeris : https://github.com/JanisE\n\nvar units$1 = {\n    'm': 'minūtes_minūtēm_minūte_minūtes'.split('_'),\n    'mm': 'minūtes_minūtēm_minūte_minūtes'.split('_'),\n    'h': 'stundas_stundām_stunda_stundas'.split('_'),\n    'hh': 'stundas_stundām_stunda_stundas'.split('_'),\n    'd': 'dienas_dienām_diena_dienas'.split('_'),\n    'dd': 'dienas_dienām_diena_dienas'.split('_'),\n    'M': 'mēneša_mēnešiem_mēnesis_mēneši'.split('_'),\n    'MM': 'mēneša_mēnešiem_mēnesis_mēneši'.split('_'),\n    'y': 'gada_gadiem_gads_gadi'.split('_'),\n    'yy': 'gada_gadiem_gads_gadi'.split('_')\n};\n/**\n * @param withoutSuffix boolean true = a length of time; false = before/after a period of time.\n */\nfunction format(forms, number, withoutSuffix) {\n    if (withoutSuffix) {\n        // E.g. \"21 minūte\", \"3 minūtes\".\n        return number % 10 === 1 && number % 100 !== 11 ? forms[2] : forms[3];\n    } else {\n        // E.g. \"21 minūtes\" as in \"pēc 21 minūtes\".\n        // E.g. \"3 minūtēm\" as in \"pēc 3 minūtēm\".\n        return number % 10 === 1 && number % 100 !== 11 ? forms[0] : forms[1];\n    }\n}\nfunction relativeTimeWithPlural$1(number, withoutSuffix, key) {\n    return number + ' ' + format(units$1[key], number, withoutSuffix);\n}\nfunction relativeTimeWithSingular(number, withoutSuffix, key) {\n    return format(units$1[key], number, withoutSuffix);\n}\nfunction relativeSeconds(number, withoutSuffix) {\n    return withoutSuffix ? 'dažas sekundes' : 'dažām sekundēm';\n}\n\nmoment.defineLocale('lv', {\n    months : 'janvāris_februāris_marts_aprīlis_maijs_jūnijs_jūlijs_augusts_septembris_oktobris_novembris_decembris'.split('_'),\n    monthsShort : 'jan_feb_mar_apr_mai_jūn_jūl_aug_sep_okt_nov_dec'.split('_'),\n    weekdays : 'svētdiena_pirmdiena_otrdiena_trešdiena_ceturtdiena_piektdiena_sestdiena'.split('_'),\n    weekdaysShort : 'Sv_P_O_T_C_Pk_S'.split('_'),\n    weekdaysMin : 'Sv_P_O_T_C_Pk_S'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD.MM.YYYY.',\n        LL : 'YYYY. [gada] D. MMMM',\n        LLL : 'YYYY. [gada] D. MMMM, HH:mm',\n        LLLL : 'YYYY. [gada] D. MMMM, dddd, HH:mm'\n    },\n    calendar : {\n        sameDay : '[Šodien pulksten] LT',\n        nextDay : '[Rīt pulksten] LT',\n        nextWeek : 'dddd [pulksten] LT',\n        lastDay : '[Vakar pulksten] LT',\n        lastWeek : '[Pagājušā] dddd [pulksten] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'pēc %s',\n        past : 'pirms %s',\n        s : relativeSeconds,\n        m : relativeTimeWithSingular,\n        mm : relativeTimeWithPlural$1,\n        h : relativeTimeWithSingular,\n        hh : relativeTimeWithPlural$1,\n        d : relativeTimeWithSingular,\n        dd : relativeTimeWithPlural$1,\n        M : relativeTimeWithSingular,\n        MM : relativeTimeWithPlural$1,\n        y : relativeTimeWithSingular,\n        yy : relativeTimeWithPlural$1\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}\\./,\n    ordinal : '%d.',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Montenegrin [me]\n//! author : Miodrag Nikač <miodrag@restartit.me> : https://github.com/miodragnikac\n\nvar translator = {\n    words: { //Different grammatical cases\n        m: ['jedan minut', 'jednog minuta'],\n        mm: ['minut', 'minuta', 'minuta'],\n        h: ['jedan sat', 'jednog sata'],\n        hh: ['sat', 'sata', 'sati'],\n        dd: ['dan', 'dana', 'dana'],\n        MM: ['mjesec', 'mjeseca', 'mjeseci'],\n        yy: ['godina', 'godine', 'godina']\n    },\n    correctGrammaticalCase: function (number, wordKey) {\n        return number === 1 ? wordKey[0] : (number >= 2 && number <= 4 ? wordKey[1] : wordKey[2]);\n    },\n    translate: function (number, withoutSuffix, key) {\n        var wordKey = translator.words[key];\n        if (key.length === 1) {\n            return withoutSuffix ? wordKey[0] : wordKey[1];\n        } else {\n            return number + ' ' + translator.correctGrammaticalCase(number, wordKey);\n        }\n    }\n};\n\nmoment.defineLocale('me', {\n    months: 'januar_februar_mart_april_maj_jun_jul_avgust_septembar_oktobar_novembar_decembar'.split('_'),\n    monthsShort: 'jan._feb._mar._apr._maj_jun_jul_avg._sep._okt._nov._dec.'.split('_'),\n    monthsParseExact : true,\n    weekdays: 'nedjelja_ponedjeljak_utorak_srijeda_četvrtak_petak_subota'.split('_'),\n    weekdaysShort: 'ned._pon._uto._sri._čet._pet._sub.'.split('_'),\n    weekdaysMin: 'ne_po_ut_sr_če_pe_su'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat: {\n        LT: 'H:mm',\n        LTS : 'H:mm:ss',\n        L: 'DD.MM.YYYY',\n        LL: 'D. MMMM YYYY',\n        LLL: 'D. MMMM YYYY H:mm',\n        LLLL: 'dddd, D. MMMM YYYY H:mm'\n    },\n    calendar: {\n        sameDay: '[danas u] LT',\n        nextDay: '[sjutra u] LT',\n\n        nextWeek: function () {\n            switch (this.day()) {\n                case 0:\n                    return '[u] [nedjelju] [u] LT';\n                case 3:\n                    return '[u] [srijedu] [u] LT';\n                case 6:\n                    return '[u] [subotu] [u] LT';\n                case 1:\n                case 2:\n                case 4:\n                case 5:\n                    return '[u] dddd [u] LT';\n            }\n        },\n        lastDay  : '[juče u] LT',\n        lastWeek : function () {\n            var lastWeekDays = [\n                '[prošle] [nedjelje] [u] LT',\n                '[prošlog] [ponedjeljka] [u] LT',\n                '[prošlog] [utorka] [u] LT',\n                '[prošle] [srijede] [u] LT',\n                '[prošlog] [četvrtka] [u] LT',\n                '[prošlog] [petka] [u] LT',\n                '[prošle] [subote] [u] LT'\n            ];\n            return lastWeekDays[this.day()];\n        },\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'za %s',\n        past   : 'prije %s',\n        s      : 'nekoliko sekundi',\n        m      : translator.translate,\n        mm     : translator.translate,\n        h      : translator.translate,\n        hh     : translator.translate,\n        d      : 'dan',\n        dd     : translator.translate,\n        M      : 'mjesec',\n        MM     : translator.translate,\n        y      : 'godinu',\n        yy     : translator.translate\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}\\./,\n    ordinal : '%d.',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 7  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Maori [mi]\n//! author : John Corrigan <robbiecloset@gmail.com> : https://github.com/johnideal\n\nmoment.defineLocale('mi', {\n    months: 'Kohi-tāte_Hui-tanguru_Poutū-te-rangi_Paenga-whāwhā_Haratua_Pipiri_Hōngoingoi_Here-turi-kōkā_Mahuru_Whiringa-ā-nuku_Whiringa-ā-rangi_Hakihea'.split('_'),\n    monthsShort: 'Kohi_Hui_Pou_Pae_Hara_Pipi_Hōngoi_Here_Mahu_Whi-nu_Whi-ra_Haki'.split('_'),\n    monthsRegex: /(?:['a-z\\u0101\\u014D\\u016B]+\\-?){1,3}/i,\n    monthsStrictRegex: /(?:['a-z\\u0101\\u014D\\u016B]+\\-?){1,3}/i,\n    monthsShortRegex: /(?:['a-z\\u0101\\u014D\\u016B]+\\-?){1,3}/i,\n    monthsShortStrictRegex: /(?:['a-z\\u0101\\u014D\\u016B]+\\-?){1,2}/i,\n    weekdays: 'Rātapu_Mane_Tūrei_Wenerei_Tāite_Paraire_Hātarei'.split('_'),\n    weekdaysShort: 'Ta_Ma_Tū_We_Tāi_Pa_Hā'.split('_'),\n    weekdaysMin: 'Ta_Ma_Tū_We_Tāi_Pa_Hā'.split('_'),\n    longDateFormat: {\n        LT: 'HH:mm',\n        LTS: 'HH:mm:ss',\n        L: 'DD/MM/YYYY',\n        LL: 'D MMMM YYYY',\n        LLL: 'D MMMM YYYY [i] HH:mm',\n        LLLL: 'dddd, D MMMM YYYY [i] HH:mm'\n    },\n    calendar: {\n        sameDay: '[i teie mahana, i] LT',\n        nextDay: '[apopo i] LT',\n        nextWeek: 'dddd [i] LT',\n        lastDay: '[inanahi i] LT',\n        lastWeek: 'dddd [whakamutunga i] LT',\n        sameElse: 'L'\n    },\n    relativeTime: {\n        future: 'i roto i %s',\n        past: '%s i mua',\n        s: 'te hēkona ruarua',\n        m: 'he meneti',\n        mm: '%d meneti',\n        h: 'te haora',\n        hh: '%d haora',\n        d: 'he ra',\n        dd: '%d ra',\n        M: 'he marama',\n        MM: '%d marama',\n        y: 'he tau',\n        yy: '%d tau'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}º/,\n    ordinal: '%dº',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Macedonian [mk]\n//! author : Borislav Mickov : https://github.com/B0k0\n\nmoment.defineLocale('mk', {\n    months : 'јануари_февруари_март_април_мај_јуни_јули_август_септември_октомври_ноември_декември'.split('_'),\n    monthsShort : 'јан_фев_мар_апр_мај_јун_јул_авг_сеп_окт_ное_дек'.split('_'),\n    weekdays : 'недела_понеделник_вторник_среда_четврток_петок_сабота'.split('_'),\n    weekdaysShort : 'нед_пон_вто_сре_чет_пет_саб'.split('_'),\n    weekdaysMin : 'нe_пo_вт_ср_че_пе_сa'.split('_'),\n    longDateFormat : {\n        LT : 'H:mm',\n        LTS : 'H:mm:ss',\n        L : 'D.MM.YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY H:mm',\n        LLLL : 'dddd, D MMMM YYYY H:mm'\n    },\n    calendar : {\n        sameDay : '[Денес во] LT',\n        nextDay : '[Утре во] LT',\n        nextWeek : '[Во] dddd [во] LT',\n        lastDay : '[Вчера во] LT',\n        lastWeek : function () {\n            switch (this.day()) {\n                case 0:\n                case 3:\n                case 6:\n                    return '[Изминатата] dddd [во] LT';\n                case 1:\n                case 2:\n                case 4:\n                case 5:\n                    return '[Изминатиот] dddd [во] LT';\n            }\n        },\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'после %s',\n        past : 'пред %s',\n        s : 'неколку секунди',\n        m : 'минута',\n        mm : '%d минути',\n        h : 'час',\n        hh : '%d часа',\n        d : 'ден',\n        dd : '%d дена',\n        M : 'месец',\n        MM : '%d месеци',\n        y : 'година',\n        yy : '%d години'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}-(ев|ен|ти|ви|ри|ми)/,\n    ordinal : function (number) {\n        var lastDigit = number % 10,\n            last2Digits = number % 100;\n        if (number === 0) {\n            return number + '-ев';\n        } else if (last2Digits === 0) {\n            return number + '-ен';\n        } else if (last2Digits > 10 && last2Digits < 20) {\n            return number + '-ти';\n        } else if (lastDigit === 1) {\n            return number + '-ви';\n        } else if (lastDigit === 2) {\n            return number + '-ри';\n        } else if (lastDigit === 7 || lastDigit === 8) {\n            return number + '-ми';\n        } else {\n            return number + '-ти';\n        }\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 7  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Malayalam [ml]\n//! author : Floyd Pink : https://github.com/floydpink\n\nmoment.defineLocale('ml', {\n    months : 'ജനുവരി_ഫെബ്രുവരി_മാർച്ച്_ഏപ്രിൽ_മേയ്_ജൂൺ_ജൂലൈ_ഓഗസ്റ്റ്_സെപ്റ്റംബർ_ഒക്ടോബർ_നവംബർ_ഡിസംബർ'.split('_'),\n    monthsShort : 'ജനു._ഫെബ്രു._മാർ._ഏപ്രി._മേയ്_ജൂൺ_ജൂലൈ._ഓഗ._സെപ്റ്റ._ഒക്ടോ._നവം._ഡിസം.'.split('_'),\n    monthsParseExact : true,\n    weekdays : 'ഞായറാഴ്ച_തിങ്കളാഴ്ച_ചൊവ്വാഴ്ച_ബുധനാഴ്ച_വ്യാഴാഴ്ച_വെള്ളിയാഴ്ച_ശനിയാഴ്ച'.split('_'),\n    weekdaysShort : 'ഞായർ_തിങ്കൾ_ചൊവ്വ_ബുധൻ_വ്യാഴം_വെള്ളി_ശനി'.split('_'),\n    weekdaysMin : 'ഞാ_തി_ചൊ_ബു_വ്യാ_വെ_ശ'.split('_'),\n    longDateFormat : {\n        LT : 'A h:mm -നു',\n        LTS : 'A h:mm:ss -നു',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY, A h:mm -നു',\n        LLLL : 'dddd, D MMMM YYYY, A h:mm -നു'\n    },\n    calendar : {\n        sameDay : '[ഇന്ന്] LT',\n        nextDay : '[നാളെ] LT',\n        nextWeek : 'dddd, LT',\n        lastDay : '[ഇന്നലെ] LT',\n        lastWeek : '[കഴിഞ്ഞ] dddd, LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : '%s കഴിഞ്ഞ്',\n        past : '%s മുൻപ്',\n        s : 'അൽപ നിമിഷങ്ങൾ',\n        m : 'ഒരു മിനിറ്റ്',\n        mm : '%d മിനിറ്റ്',\n        h : 'ഒരു മണിക്കൂർ',\n        hh : '%d മണിക്കൂർ',\n        d : 'ഒരു ദിവസം',\n        dd : '%d ദിവസം',\n        M : 'ഒരു മാസം',\n        MM : '%d മാസം',\n        y : 'ഒരു വർഷം',\n        yy : '%d വർഷം'\n    },\n    meridiemParse: /രാത്രി|രാവിലെ|ഉച്ച കഴിഞ്ഞ്|വൈകുന്നേരം|രാത്രി/i,\n    meridiemHour : function (hour, meridiem) {\n        if (hour === 12) {\n            hour = 0;\n        }\n        if ((meridiem === 'രാത്രി' && hour >= 4) ||\n                meridiem === 'ഉച്ച കഴിഞ്ഞ്' ||\n                meridiem === 'വൈകുന്നേരം') {\n            return hour + 12;\n        } else {\n            return hour;\n        }\n    },\n    meridiem : function (hour, minute, isLower) {\n        if (hour < 4) {\n            return 'രാത്രി';\n        } else if (hour < 12) {\n            return 'രാവിലെ';\n        } else if (hour < 17) {\n            return 'ഉച്ച കഴിഞ്ഞ്';\n        } else if (hour < 20) {\n            return 'വൈകുന്നേരം';\n        } else {\n            return 'രാത്രി';\n        }\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Marathi [mr]\n//! author : Harshad Kale : https://github.com/kalehv\n//! author : Vivek Athalye : https://github.com/vnathalye\n\nvar symbolMap$8 = {\n    '1': '१',\n    '2': '२',\n    '3': '३',\n    '4': '४',\n    '5': '५',\n    '6': '६',\n    '7': '७',\n    '8': '८',\n    '9': '९',\n    '0': '०'\n};\nvar numberMap$7 = {\n    '१': '1',\n    '२': '2',\n    '३': '3',\n    '४': '4',\n    '५': '5',\n    '६': '6',\n    '७': '7',\n    '८': '8',\n    '९': '9',\n    '०': '0'\n};\n\nfunction relativeTimeMr(number, withoutSuffix, string, isFuture)\n{\n    var output = '';\n    if (withoutSuffix) {\n        switch (string) {\n            case 's': output = 'काही सेकंद'; break;\n            case 'm': output = 'एक मिनिट'; break;\n            case 'mm': output = '%d मिनिटे'; break;\n            case 'h': output = 'एक तास'; break;\n            case 'hh': output = '%d तास'; break;\n            case 'd': output = 'एक दिवस'; break;\n            case 'dd': output = '%d दिवस'; break;\n            case 'M': output = 'एक महिना'; break;\n            case 'MM': output = '%d महिने'; break;\n            case 'y': output = 'एक वर्ष'; break;\n            case 'yy': output = '%d वर्षे'; break;\n        }\n    }\n    else {\n        switch (string) {\n            case 's': output = 'काही सेकंदां'; break;\n            case 'm': output = 'एका मिनिटा'; break;\n            case 'mm': output = '%d मिनिटां'; break;\n            case 'h': output = 'एका तासा'; break;\n            case 'hh': output = '%d तासां'; break;\n            case 'd': output = 'एका दिवसा'; break;\n            case 'dd': output = '%d दिवसां'; break;\n            case 'M': output = 'एका महिन्या'; break;\n            case 'MM': output = '%d महिन्यां'; break;\n            case 'y': output = 'एका वर्षा'; break;\n            case 'yy': output = '%d वर्षां'; break;\n        }\n    }\n    return output.replace(/%d/i, number);\n}\n\nmoment.defineLocale('mr', {\n    months : 'जानेवारी_फेब्रुवारी_मार्च_एप्रिल_मे_जून_जुलै_ऑगस्ट_सप्टेंबर_ऑक्टोबर_नोव्हेंबर_डिसेंबर'.split('_'),\n    monthsShort: 'जाने._फेब्रु._मार्च._एप्रि._मे._जून._जुलै._ऑग._सप्टें._ऑक्टो._नोव्हें._डिसें.'.split('_'),\n    monthsParseExact : true,\n    weekdays : 'रविवार_सोमवार_मंगळवार_बुधवार_गुरूवार_शुक्रवार_शनिवार'.split('_'),\n    weekdaysShort : 'रवि_सोम_मंगळ_बुध_गुरू_शुक्र_शनि'.split('_'),\n    weekdaysMin : 'र_सो_मं_बु_गु_शु_श'.split('_'),\n    longDateFormat : {\n        LT : 'A h:mm वाजता',\n        LTS : 'A h:mm:ss वाजता',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY, A h:mm वाजता',\n        LLLL : 'dddd, D MMMM YYYY, A h:mm वाजता'\n    },\n    calendar : {\n        sameDay : '[आज] LT',\n        nextDay : '[उद्या] LT',\n        nextWeek : 'dddd, LT',\n        lastDay : '[काल] LT',\n        lastWeek: '[मागील] dddd, LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future: '%sमध्ये',\n        past: '%sपूर्वी',\n        s: relativeTimeMr,\n        m: relativeTimeMr,\n        mm: relativeTimeMr,\n        h: relativeTimeMr,\n        hh: relativeTimeMr,\n        d: relativeTimeMr,\n        dd: relativeTimeMr,\n        M: relativeTimeMr,\n        MM: relativeTimeMr,\n        y: relativeTimeMr,\n        yy: relativeTimeMr\n    },\n    preparse: function (string) {\n        return string.replace(/[१२३४५६७८९०]/g, function (match) {\n            return numberMap$7[match];\n        });\n    },\n    postformat: function (string) {\n        return string.replace(/\\d/g, function (match) {\n            return symbolMap$8[match];\n        });\n    },\n    meridiemParse: /रात्री|सकाळी|दुपारी|सायंकाळी/,\n    meridiemHour : function (hour, meridiem) {\n        if (hour === 12) {\n            hour = 0;\n        }\n        if (meridiem === 'रात्री') {\n            return hour < 4 ? hour : hour + 12;\n        } else if (meridiem === 'सकाळी') {\n            return hour;\n        } else if (meridiem === 'दुपारी') {\n            return hour >= 10 ? hour : hour + 12;\n        } else if (meridiem === 'सायंकाळी') {\n            return hour + 12;\n        }\n    },\n    meridiem: function (hour, minute, isLower) {\n        if (hour < 4) {\n            return 'रात्री';\n        } else if (hour < 10) {\n            return 'सकाळी';\n        } else if (hour < 17) {\n            return 'दुपारी';\n        } else if (hour < 20) {\n            return 'सायंकाळी';\n        } else {\n            return 'रात्री';\n        }\n    },\n    week : {\n        dow : 0, // Sunday is the first day of the week.\n        doy : 6  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Malay [ms-my]\n//! note : DEPRECATED, the correct one is [ms]\n//! author : Weldan Jamili : https://github.com/weldan\n\nmoment.defineLocale('ms-my', {\n    months : 'Januari_Februari_Mac_April_Mei_Jun_Julai_Ogos_September_Oktober_November_Disember'.split('_'),\n    monthsShort : 'Jan_Feb_Mac_Apr_Mei_Jun_Jul_Ogs_Sep_Okt_Nov_Dis'.split('_'),\n    weekdays : 'Ahad_Isnin_Selasa_Rabu_Khamis_Jumaat_Sabtu'.split('_'),\n    weekdaysShort : 'Ahd_Isn_Sel_Rab_Kha_Jum_Sab'.split('_'),\n    weekdaysMin : 'Ah_Is_Sl_Rb_Km_Jm_Sb'.split('_'),\n    longDateFormat : {\n        LT : 'HH.mm',\n        LTS : 'HH.mm.ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY [pukul] HH.mm',\n        LLLL : 'dddd, D MMMM YYYY [pukul] HH.mm'\n    },\n    meridiemParse: /pagi|tengahari|petang|malam/,\n    meridiemHour: function (hour, meridiem) {\n        if (hour === 12) {\n            hour = 0;\n        }\n        if (meridiem === 'pagi') {\n            return hour;\n        } else if (meridiem === 'tengahari') {\n            return hour >= 11 ? hour : hour + 12;\n        } else if (meridiem === 'petang' || meridiem === 'malam') {\n            return hour + 12;\n        }\n    },\n    meridiem : function (hours, minutes, isLower) {\n        if (hours < 11) {\n            return 'pagi';\n        } else if (hours < 15) {\n            return 'tengahari';\n        } else if (hours < 19) {\n            return 'petang';\n        } else {\n            return 'malam';\n        }\n    },\n    calendar : {\n        sameDay : '[Hari ini pukul] LT',\n        nextDay : '[Esok pukul] LT',\n        nextWeek : 'dddd [pukul] LT',\n        lastDay : '[Kelmarin pukul] LT',\n        lastWeek : 'dddd [lepas pukul] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'dalam %s',\n        past : '%s yang lepas',\n        s : 'beberapa saat',\n        m : 'seminit',\n        mm : '%d minit',\n        h : 'sejam',\n        hh : '%d jam',\n        d : 'sehari',\n        dd : '%d hari',\n        M : 'sebulan',\n        MM : '%d bulan',\n        y : 'setahun',\n        yy : '%d tahun'\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 7  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Malay [ms]\n//! author : Weldan Jamili : https://github.com/weldan\n\nmoment.defineLocale('ms', {\n    months : 'Januari_Februari_Mac_April_Mei_Jun_Julai_Ogos_September_Oktober_November_Disember'.split('_'),\n    monthsShort : 'Jan_Feb_Mac_Apr_Mei_Jun_Jul_Ogs_Sep_Okt_Nov_Dis'.split('_'),\n    weekdays : 'Ahad_Isnin_Selasa_Rabu_Khamis_Jumaat_Sabtu'.split('_'),\n    weekdaysShort : 'Ahd_Isn_Sel_Rab_Kha_Jum_Sab'.split('_'),\n    weekdaysMin : 'Ah_Is_Sl_Rb_Km_Jm_Sb'.split('_'),\n    longDateFormat : {\n        LT : 'HH.mm',\n        LTS : 'HH.mm.ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY [pukul] HH.mm',\n        LLLL : 'dddd, D MMMM YYYY [pukul] HH.mm'\n    },\n    meridiemParse: /pagi|tengahari|petang|malam/,\n    meridiemHour: function (hour, meridiem) {\n        if (hour === 12) {\n            hour = 0;\n        }\n        if (meridiem === 'pagi') {\n            return hour;\n        } else if (meridiem === 'tengahari') {\n            return hour >= 11 ? hour : hour + 12;\n        } else if (meridiem === 'petang' || meridiem === 'malam') {\n            return hour + 12;\n        }\n    },\n    meridiem : function (hours, minutes, isLower) {\n        if (hours < 11) {\n            return 'pagi';\n        } else if (hours < 15) {\n            return 'tengahari';\n        } else if (hours < 19) {\n            return 'petang';\n        } else {\n            return 'malam';\n        }\n    },\n    calendar : {\n        sameDay : '[Hari ini pukul] LT',\n        nextDay : '[Esok pukul] LT',\n        nextWeek : 'dddd [pukul] LT',\n        lastDay : '[Kelmarin pukul] LT',\n        lastWeek : 'dddd [lepas pukul] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'dalam %s',\n        past : '%s yang lepas',\n        s : 'beberapa saat',\n        m : 'seminit',\n        mm : '%d minit',\n        h : 'sejam',\n        hh : '%d jam',\n        d : 'sehari',\n        dd : '%d hari',\n        M : 'sebulan',\n        MM : '%d bulan',\n        y : 'setahun',\n        yy : '%d tahun'\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 7  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Burmese [my]\n//! author : Squar team, mysquar.com\n//! author : David Rossellat : https://github.com/gholadr\n//! author : Tin Aung Lin : https://github.com/thanyawzinmin\n\nvar symbolMap$9 = {\n    '1': '၁',\n    '2': '၂',\n    '3': '၃',\n    '4': '၄',\n    '5': '၅',\n    '6': '၆',\n    '7': '၇',\n    '8': '၈',\n    '9': '၉',\n    '0': '၀'\n};\nvar numberMap$8 = {\n    '၁': '1',\n    '၂': '2',\n    '၃': '3',\n    '၄': '4',\n    '၅': '5',\n    '၆': '6',\n    '၇': '7',\n    '၈': '8',\n    '၉': '9',\n    '၀': '0'\n};\n\nmoment.defineLocale('my', {\n    months: 'ဇန်နဝါရီ_ဖေဖော်ဝါရီ_မတ်_ဧပြီ_မေ_ဇွန်_ဇူလိုင်_သြဂုတ်_စက်တင်ဘာ_အောက်တိုဘာ_နိုဝင်ဘာ_ဒီဇင်ဘာ'.split('_'),\n    monthsShort: 'ဇန်_ဖေ_မတ်_ပြီ_မေ_ဇွန်_လိုင်_သြ_စက်_အောက်_နို_ဒီ'.split('_'),\n    weekdays: 'တနင်္ဂနွေ_တနင်္လာ_အင်္ဂါ_ဗုဒ္ဓဟူး_ကြာသပတေး_သောကြာ_စနေ'.split('_'),\n    weekdaysShort: 'နွေ_လာ_ဂါ_ဟူး_ကြာ_သော_နေ'.split('_'),\n    weekdaysMin: 'နွေ_လာ_ဂါ_ဟူး_ကြာ_သော_နေ'.split('_'),\n\n    longDateFormat: {\n        LT: 'HH:mm',\n        LTS: 'HH:mm:ss',\n        L: 'DD/MM/YYYY',\n        LL: 'D MMMM YYYY',\n        LLL: 'D MMMM YYYY HH:mm',\n        LLLL: 'dddd D MMMM YYYY HH:mm'\n    },\n    calendar: {\n        sameDay: '[ယနေ.] LT [မှာ]',\n        nextDay: '[မနက်ဖြန်] LT [မှာ]',\n        nextWeek: 'dddd LT [မှာ]',\n        lastDay: '[မနေ.က] LT [မှာ]',\n        lastWeek: '[ပြီးခဲ့သော] dddd LT [မှာ]',\n        sameElse: 'L'\n    },\n    relativeTime: {\n        future: 'လာမည့် %s မှာ',\n        past: 'လွန်ခဲ့သော %s က',\n        s: 'စက္ကန်.အနည်းငယ်',\n        m: 'တစ်မိနစ်',\n        mm: '%d မိနစ်',\n        h: 'တစ်နာရီ',\n        hh: '%d နာရီ',\n        d: 'တစ်ရက်',\n        dd: '%d ရက်',\n        M: 'တစ်လ',\n        MM: '%d လ',\n        y: 'တစ်နှစ်',\n        yy: '%d နှစ်'\n    },\n    preparse: function (string) {\n        return string.replace(/[၁၂၃၄၅၆၇၈၉၀]/g, function (match) {\n            return numberMap$8[match];\n        });\n    },\n    postformat: function (string) {\n        return string.replace(/\\d/g, function (match) {\n            return symbolMap$9[match];\n        });\n    },\n    week: {\n        dow: 1, // Monday is the first day of the week.\n        doy: 4 // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Norwegian Bokmål [nb]\n//! authors : Espen Hovlandsdal : https://github.com/rexxars\n//!           Sigurd Gartmann : https://github.com/sigurdga\n\nmoment.defineLocale('nb', {\n    months : 'januar_februar_mars_april_mai_juni_juli_august_september_oktober_november_desember'.split('_'),\n    monthsShort : 'jan._feb._mars_april_mai_juni_juli_aug._sep._okt._nov._des.'.split('_'),\n    monthsParseExact : true,\n    weekdays : 'søndag_mandag_tirsdag_onsdag_torsdag_fredag_lørdag'.split('_'),\n    weekdaysShort : 'sø._ma._ti._on._to._fr._lø.'.split('_'),\n    weekdaysMin : 'sø_ma_ti_on_to_fr_lø'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD.MM.YYYY',\n        LL : 'D. MMMM YYYY',\n        LLL : 'D. MMMM YYYY [kl.] HH:mm',\n        LLLL : 'dddd D. MMMM YYYY [kl.] HH:mm'\n    },\n    calendar : {\n        sameDay: '[i dag kl.] LT',\n        nextDay: '[i morgen kl.] LT',\n        nextWeek: 'dddd [kl.] LT',\n        lastDay: '[i går kl.] LT',\n        lastWeek: '[forrige] dddd [kl.] LT',\n        sameElse: 'L'\n    },\n    relativeTime : {\n        future : 'om %s',\n        past : '%s siden',\n        s : 'noen sekunder',\n        m : 'ett minutt',\n        mm : '%d minutter',\n        h : 'en time',\n        hh : '%d timer',\n        d : 'en dag',\n        dd : '%d dager',\n        M : 'en måned',\n        MM : '%d måneder',\n        y : 'ett år',\n        yy : '%d år'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}\\./,\n    ordinal : '%d.',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Nepalese [ne]\n//! author : suvash : https://github.com/suvash\n\nvar symbolMap$10 = {\n    '1': '१',\n    '2': '२',\n    '3': '३',\n    '4': '४',\n    '5': '५',\n    '6': '६',\n    '7': '७',\n    '8': '८',\n    '9': '९',\n    '0': '०'\n};\nvar numberMap$9 = {\n    '१': '1',\n    '२': '2',\n    '३': '3',\n    '४': '4',\n    '५': '5',\n    '६': '6',\n    '७': '7',\n    '८': '8',\n    '९': '9',\n    '०': '0'\n};\n\nmoment.defineLocale('ne', {\n    months : 'जनवरी_फेब्रुवरी_मार्च_अप्रिल_मई_जुन_जुलाई_अगष्ट_सेप्टेम्बर_अक्टोबर_नोभेम्बर_डिसेम्बर'.split('_'),\n    monthsShort : 'जन._फेब्रु._मार्च_अप्रि._मई_जुन_जुलाई._अग._सेप्ट._अक्टो._नोभे._डिसे.'.split('_'),\n    monthsParseExact : true,\n    weekdays : 'आइतबार_सोमबार_मङ्गलबार_बुधबार_बिहिबार_शुक्रबार_शनिबार'.split('_'),\n    weekdaysShort : 'आइत._सोम._मङ्गल._बुध._बिहि._शुक्र._शनि.'.split('_'),\n    weekdaysMin : 'आ._सो._मं._बु._बि._शु._श.'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat : {\n        LT : 'Aको h:mm बजे',\n        LTS : 'Aको h:mm:ss बजे',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY, Aको h:mm बजे',\n        LLLL : 'dddd, D MMMM YYYY, Aको h:mm बजे'\n    },\n    preparse: function (string) {\n        return string.replace(/[१२३४५६७८९०]/g, function (match) {\n            return numberMap$9[match];\n        });\n    },\n    postformat: function (string) {\n        return string.replace(/\\d/g, function (match) {\n            return symbolMap$10[match];\n        });\n    },\n    meridiemParse: /राति|बिहान|दिउँसो|साँझ/,\n    meridiemHour : function (hour, meridiem) {\n        if (hour === 12) {\n            hour = 0;\n        }\n        if (meridiem === 'राति') {\n            return hour < 4 ? hour : hour + 12;\n        } else if (meridiem === 'बिहान') {\n            return hour;\n        } else if (meridiem === 'दिउँसो') {\n            return hour >= 10 ? hour : hour + 12;\n        } else if (meridiem === 'साँझ') {\n            return hour + 12;\n        }\n    },\n    meridiem : function (hour, minute, isLower) {\n        if (hour < 3) {\n            return 'राति';\n        } else if (hour < 12) {\n            return 'बिहान';\n        } else if (hour < 16) {\n            return 'दिउँसो';\n        } else if (hour < 20) {\n            return 'साँझ';\n        } else {\n            return 'राति';\n        }\n    },\n    calendar : {\n        sameDay : '[आज] LT',\n        nextDay : '[भोलि] LT',\n        nextWeek : '[आउँदो] dddd[,] LT',\n        lastDay : '[हिजो] LT',\n        lastWeek : '[गएको] dddd[,] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : '%sमा',\n        past : '%s अगाडि',\n        s : 'केही क्षण',\n        m : 'एक मिनेट',\n        mm : '%d मिनेट',\n        h : 'एक घण्टा',\n        hh : '%d घण्टा',\n        d : 'एक दिन',\n        dd : '%d दिन',\n        M : 'एक महिना',\n        MM : '%d महिना',\n        y : 'एक बर्ष',\n        yy : '%d बर्ष'\n    },\n    week : {\n        dow : 0, // Sunday is the first day of the week.\n        doy : 6  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Dutch (Belgium) [nl-be]\n//! author : Joris Röling : https://github.com/jorisroling\n//! author : Jacob Middag : https://github.com/middagj\n\nvar monthsShortWithDots$1 = 'jan._feb._mrt._apr._mei_jun._jul._aug._sep._okt._nov._dec.'.split('_');\nvar monthsShortWithoutDots$1 = 'jan_feb_mrt_apr_mei_jun_jul_aug_sep_okt_nov_dec'.split('_');\n\nvar monthsParse = [/^jan/i, /^feb/i, /^maart|mrt.?$/i, /^apr/i, /^mei$/i, /^jun[i.]?$/i, /^jul[i.]?$/i, /^aug/i, /^sep/i, /^okt/i, /^nov/i, /^dec/i];\nvar monthsRegex = /^(januari|februari|maart|april|mei|april|ju[nl]i|augustus|september|oktober|november|december|jan\\.?|feb\\.?|mrt\\.?|apr\\.?|ju[nl]\\.?|aug\\.?|sep\\.?|okt\\.?|nov\\.?|dec\\.?)/i;\n\nmoment.defineLocale('nl-be', {\n    months : 'januari_februari_maart_april_mei_juni_juli_augustus_september_oktober_november_december'.split('_'),\n    monthsShort : function (m, format) {\n        if (!m) {\n            return monthsShortWithDots$1;\n        } else if (/-MMM-/.test(format)) {\n            return monthsShortWithoutDots$1[m.month()];\n        } else {\n            return monthsShortWithDots$1[m.month()];\n        }\n    },\n\n    monthsRegex: monthsRegex,\n    monthsShortRegex: monthsRegex,\n    monthsStrictRegex: /^(januari|februari|maart|mei|ju[nl]i|april|augustus|september|oktober|november|december)/i,\n    monthsShortStrictRegex: /^(jan\\.?|feb\\.?|mrt\\.?|apr\\.?|mei|ju[nl]\\.?|aug\\.?|sep\\.?|okt\\.?|nov\\.?|dec\\.?)/i,\n\n    monthsParse : monthsParse,\n    longMonthsParse : monthsParse,\n    shortMonthsParse : monthsParse,\n\n    weekdays : 'zondag_maandag_dinsdag_woensdag_donderdag_vrijdag_zaterdag'.split('_'),\n    weekdaysShort : 'zo._ma._di._wo._do._vr._za.'.split('_'),\n    weekdaysMin : 'Zo_Ma_Di_Wo_Do_Vr_Za'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY HH:mm',\n        LLLL : 'dddd D MMMM YYYY HH:mm'\n    },\n    calendar : {\n        sameDay: '[vandaag om] LT',\n        nextDay: '[morgen om] LT',\n        nextWeek: 'dddd [om] LT',\n        lastDay: '[gisteren om] LT',\n        lastWeek: '[afgelopen] dddd [om] LT',\n        sameElse: 'L'\n    },\n    relativeTime : {\n        future : 'over %s',\n        past : '%s geleden',\n        s : 'een paar seconden',\n        m : 'één minuut',\n        mm : '%d minuten',\n        h : 'één uur',\n        hh : '%d uur',\n        d : 'één dag',\n        dd : '%d dagen',\n        M : 'één maand',\n        MM : '%d maanden',\n        y : 'één jaar',\n        yy : '%d jaar'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}(ste|de)/,\n    ordinal : function (number) {\n        return number + ((number === 1 || number === 8 || number >= 20) ? 'ste' : 'de');\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Dutch [nl]\n//! author : Joris Röling : https://github.com/jorisroling\n//! author : Jacob Middag : https://github.com/middagj\n\nvar monthsShortWithDots$2 = 'jan._feb._mrt._apr._mei_jun._jul._aug._sep._okt._nov._dec.'.split('_');\nvar monthsShortWithoutDots$2 = 'jan_feb_mrt_apr_mei_jun_jul_aug_sep_okt_nov_dec'.split('_');\n\nvar monthsParse$1 = [/^jan/i, /^feb/i, /^maart|mrt.?$/i, /^apr/i, /^mei$/i, /^jun[i.]?$/i, /^jul[i.]?$/i, /^aug/i, /^sep/i, /^okt/i, /^nov/i, /^dec/i];\nvar monthsRegex$1 = /^(januari|februari|maart|april|mei|april|ju[nl]i|augustus|september|oktober|november|december|jan\\.?|feb\\.?|mrt\\.?|apr\\.?|ju[nl]\\.?|aug\\.?|sep\\.?|okt\\.?|nov\\.?|dec\\.?)/i;\n\nmoment.defineLocale('nl', {\n    months : 'januari_februari_maart_april_mei_juni_juli_augustus_september_oktober_november_december'.split('_'),\n    monthsShort : function (m, format) {\n        if (!m) {\n            return monthsShortWithDots$2;\n        } else if (/-MMM-/.test(format)) {\n            return monthsShortWithoutDots$2[m.month()];\n        } else {\n            return monthsShortWithDots$2[m.month()];\n        }\n    },\n\n    monthsRegex: monthsRegex$1,\n    monthsShortRegex: monthsRegex$1,\n    monthsStrictRegex: /^(januari|februari|maart|mei|ju[nl]i|april|augustus|september|oktober|november|december)/i,\n    monthsShortStrictRegex: /^(jan\\.?|feb\\.?|mrt\\.?|apr\\.?|mei|ju[nl]\\.?|aug\\.?|sep\\.?|okt\\.?|nov\\.?|dec\\.?)/i,\n\n    monthsParse : monthsParse$1,\n    longMonthsParse : monthsParse$1,\n    shortMonthsParse : monthsParse$1,\n\n    weekdays : 'zondag_maandag_dinsdag_woensdag_donderdag_vrijdag_zaterdag'.split('_'),\n    weekdaysShort : 'zo._ma._di._wo._do._vr._za.'.split('_'),\n    weekdaysMin : 'Zo_Ma_Di_Wo_Do_Vr_Za'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD-MM-YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY HH:mm',\n        LLLL : 'dddd D MMMM YYYY HH:mm'\n    },\n    calendar : {\n        sameDay: '[vandaag om] LT',\n        nextDay: '[morgen om] LT',\n        nextWeek: 'dddd [om] LT',\n        lastDay: '[gisteren om] LT',\n        lastWeek: '[afgelopen] dddd [om] LT',\n        sameElse: 'L'\n    },\n    relativeTime : {\n        future : 'over %s',\n        past : '%s geleden',\n        s : 'een paar seconden',\n        m : 'één minuut',\n        mm : '%d minuten',\n        h : 'één uur',\n        hh : '%d uur',\n        d : 'één dag',\n        dd : '%d dagen',\n        M : 'één maand',\n        MM : '%d maanden',\n        y : 'één jaar',\n        yy : '%d jaar'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}(ste|de)/,\n    ordinal : function (number) {\n        return number + ((number === 1 || number === 8 || number >= 20) ? 'ste' : 'de');\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Nynorsk [nn]\n//! author : https://github.com/mechuwind\n\nmoment.defineLocale('nn', {\n    months : 'januar_februar_mars_april_mai_juni_juli_august_september_oktober_november_desember'.split('_'),\n    monthsShort : 'jan_feb_mar_apr_mai_jun_jul_aug_sep_okt_nov_des'.split('_'),\n    weekdays : 'sundag_måndag_tysdag_onsdag_torsdag_fredag_laurdag'.split('_'),\n    weekdaysShort : 'sun_mån_tys_ons_tor_fre_lau'.split('_'),\n    weekdaysMin : 'su_må_ty_on_to_fr_lø'.split('_'),\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD.MM.YYYY',\n        LL : 'D. MMMM YYYY',\n        LLL : 'D. MMMM YYYY [kl.] H:mm',\n        LLLL : 'dddd D. MMMM YYYY [kl.] HH:mm'\n    },\n    calendar : {\n        sameDay: '[I dag klokka] LT',\n        nextDay: '[I morgon klokka] LT',\n        nextWeek: 'dddd [klokka] LT',\n        lastDay: '[I går klokka] LT',\n        lastWeek: '[Føregåande] dddd [klokka] LT',\n        sameElse: 'L'\n    },\n    relativeTime : {\n        future : 'om %s',\n        past : '%s sidan',\n        s : 'nokre sekund',\n        m : 'eit minutt',\n        mm : '%d minutt',\n        h : 'ein time',\n        hh : '%d timar',\n        d : 'ein dag',\n        dd : '%d dagar',\n        M : 'ein månad',\n        MM : '%d månader',\n        y : 'eit år',\n        yy : '%d år'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}\\./,\n    ordinal : '%d.',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Punjabi (India) [pa-in]\n//! author : Harpreet Singh : https://github.com/harpreetkhalsagtbit\n\nvar symbolMap$11 = {\n    '1': '੧',\n    '2': '੨',\n    '3': '੩',\n    '4': '੪',\n    '5': '੫',\n    '6': '੬',\n    '7': '੭',\n    '8': '੮',\n    '9': '੯',\n    '0': '੦'\n};\nvar numberMap$10 = {\n    '੧': '1',\n    '੨': '2',\n    '੩': '3',\n    '੪': '4',\n    '੫': '5',\n    '੬': '6',\n    '੭': '7',\n    '੮': '8',\n    '੯': '9',\n    '੦': '0'\n};\n\nmoment.defineLocale('pa-in', {\n    // There are months name as per Nanakshahi Calender but they are not used as rigidly in modern Punjabi.\n    months : 'ਜਨਵਰੀ_ਫ਼ਰਵਰੀ_ਮਾਰਚ_ਅਪ੍ਰੈਲ_ਮਈ_ਜੂਨ_ਜੁਲਾਈ_ਅਗਸਤ_ਸਤੰਬਰ_ਅਕਤੂਬਰ_ਨਵੰਬਰ_ਦਸੰਬਰ'.split('_'),\n    monthsShort : 'ਜਨਵਰੀ_ਫ਼ਰਵਰੀ_ਮਾਰਚ_ਅਪ੍ਰੈਲ_ਮਈ_ਜੂਨ_ਜੁਲਾਈ_ਅਗਸਤ_ਸਤੰਬਰ_ਅਕਤੂਬਰ_ਨਵੰਬਰ_ਦਸੰਬਰ'.split('_'),\n    weekdays : 'ਐਤਵਾਰ_ਸੋਮਵਾਰ_ਮੰਗਲਵਾਰ_ਬੁਧਵਾਰ_ਵੀਰਵਾਰ_ਸ਼ੁੱਕਰਵਾਰ_ਸ਼ਨੀਚਰਵਾਰ'.split('_'),\n    weekdaysShort : 'ਐਤ_ਸੋਮ_ਮੰਗਲ_ਬੁਧ_ਵੀਰ_ਸ਼ੁਕਰ_ਸ਼ਨੀ'.split('_'),\n    weekdaysMin : 'ਐਤ_ਸੋਮ_ਮੰਗਲ_ਬੁਧ_ਵੀਰ_ਸ਼ੁਕਰ_ਸ਼ਨੀ'.split('_'),\n    longDateFormat : {\n        LT : 'A h:mm ਵਜੇ',\n        LTS : 'A h:mm:ss ਵਜੇ',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY, A h:mm ਵਜੇ',\n        LLLL : 'dddd, D MMMM YYYY, A h:mm ਵਜੇ'\n    },\n    calendar : {\n        sameDay : '[ਅਜ] LT',\n        nextDay : '[ਕਲ] LT',\n        nextWeek : 'dddd, LT',\n        lastDay : '[ਕਲ] LT',\n        lastWeek : '[ਪਿਛਲੇ] dddd, LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : '%s ਵਿੱਚ',\n        past : '%s ਪਿਛਲੇ',\n        s : 'ਕੁਝ ਸਕਿੰਟ',\n        m : 'ਇਕ ਮਿੰਟ',\n        mm : '%d ਮਿੰਟ',\n        h : 'ਇੱਕ ਘੰਟਾ',\n        hh : '%d ਘੰਟੇ',\n        d : 'ਇੱਕ ਦਿਨ',\n        dd : '%d ਦਿਨ',\n        M : 'ਇੱਕ ਮਹੀਨਾ',\n        MM : '%d ਮਹੀਨੇ',\n        y : 'ਇੱਕ ਸਾਲ',\n        yy : '%d ਸਾਲ'\n    },\n    preparse: function (string) {\n        return string.replace(/[੧੨੩੪੫੬੭੮੯੦]/g, function (match) {\n            return numberMap$10[match];\n        });\n    },\n    postformat: function (string) {\n        return string.replace(/\\d/g, function (match) {\n            return symbolMap$11[match];\n        });\n    },\n    // Punjabi notation for meridiems are quite fuzzy in practice. While there exists\n    // a rigid notion of a 'Pahar' it is not used as rigidly in modern Punjabi.\n    meridiemParse: /ਰਾਤ|ਸਵੇਰ|ਦੁਪਹਿਰ|ਸ਼ਾਮ/,\n    meridiemHour : function (hour, meridiem) {\n        if (hour === 12) {\n            hour = 0;\n        }\n        if (meridiem === 'ਰਾਤ') {\n            return hour < 4 ? hour : hour + 12;\n        } else if (meridiem === 'ਸਵੇਰ') {\n            return hour;\n        } else if (meridiem === 'ਦੁਪਹਿਰ') {\n            return hour >= 10 ? hour : hour + 12;\n        } else if (meridiem === 'ਸ਼ਾਮ') {\n            return hour + 12;\n        }\n    },\n    meridiem : function (hour, minute, isLower) {\n        if (hour < 4) {\n            return 'ਰਾਤ';\n        } else if (hour < 10) {\n            return 'ਸਵੇਰ';\n        } else if (hour < 17) {\n            return 'ਦੁਪਹਿਰ';\n        } else if (hour < 20) {\n            return 'ਸ਼ਾਮ';\n        } else {\n            return 'ਰਾਤ';\n        }\n    },\n    week : {\n        dow : 0, // Sunday is the first day of the week.\n        doy : 6  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Polish [pl]\n//! author : Rafal Hirsz : https://github.com/evoL\n\nvar monthsNominative = 'styczeń_luty_marzec_kwiecień_maj_czerwiec_lipiec_sierpień_wrzesień_październik_listopad_grudzień'.split('_');\nvar monthsSubjective = 'stycznia_lutego_marca_kwietnia_maja_czerwca_lipca_sierpnia_września_października_listopada_grudnia'.split('_');\nfunction plural$3(n) {\n    return (n % 10 < 5) && (n % 10 > 1) && ((~~(n / 10) % 10) !== 1);\n}\nfunction translate$7(number, withoutSuffix, key) {\n    var result = number + ' ';\n    switch (key) {\n        case 'm':\n            return withoutSuffix ? 'minuta' : 'minutę';\n        case 'mm':\n            return result + (plural$3(number) ? 'minuty' : 'minut');\n        case 'h':\n            return withoutSuffix  ? 'godzina'  : 'godzinę';\n        case 'hh':\n            return result + (plural$3(number) ? 'godziny' : 'godzin');\n        case 'MM':\n            return result + (plural$3(number) ? 'miesiące' : 'miesięcy');\n        case 'yy':\n            return result + (plural$3(number) ? 'lata' : 'lat');\n    }\n}\n\nmoment.defineLocale('pl', {\n    months : function (momentToFormat, format) {\n        if (!momentToFormat) {\n            return monthsNominative;\n        } else if (format === '') {\n            // Hack: if format empty we know this is used to generate\n            // RegExp by moment. Give then back both valid forms of months\n            // in RegExp ready format.\n            return '(' + monthsSubjective[momentToFormat.month()] + '|' + monthsNominative[momentToFormat.month()] + ')';\n        } else if (/D MMMM/.test(format)) {\n            return monthsSubjective[momentToFormat.month()];\n        } else {\n            return monthsNominative[momentToFormat.month()];\n        }\n    },\n    monthsShort : 'sty_lut_mar_kwi_maj_cze_lip_sie_wrz_paź_lis_gru'.split('_'),\n    weekdays : 'niedziela_poniedziałek_wtorek_środa_czwartek_piątek_sobota'.split('_'),\n    weekdaysShort : 'ndz_pon_wt_śr_czw_pt_sob'.split('_'),\n    weekdaysMin : 'Nd_Pn_Wt_Śr_Cz_Pt_So'.split('_'),\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD.MM.YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY HH:mm',\n        LLLL : 'dddd, D MMMM YYYY HH:mm'\n    },\n    calendar : {\n        sameDay: '[Dziś o] LT',\n        nextDay: '[Jutro o] LT',\n        nextWeek: '[W] dddd [o] LT',\n        lastDay: '[Wczoraj o] LT',\n        lastWeek: function () {\n            switch (this.day()) {\n                case 0:\n                    return '[W zeszłą niedzielę o] LT';\n                case 3:\n                    return '[W zeszłą środę o] LT';\n                case 6:\n                    return '[W zeszłą sobotę o] LT';\n                default:\n                    return '[W zeszły] dddd [o] LT';\n            }\n        },\n        sameElse: 'L'\n    },\n    relativeTime : {\n        future : 'za %s',\n        past : '%s temu',\n        s : 'kilka sekund',\n        m : translate$7,\n        mm : translate$7,\n        h : translate$7,\n        hh : translate$7,\n        d : '1 dzień',\n        dd : '%d dni',\n        M : 'miesiąc',\n        MM : translate$7,\n        y : 'rok',\n        yy : translate$7\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}\\./,\n    ordinal : '%d.',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Portuguese (Brazil) [pt-br]\n//! author : Caio Ribeiro Pereira : https://github.com/caio-ribeiro-pereira\n\nmoment.defineLocale('pt-br', {\n    months : 'Janeiro_Fevereiro_Março_Abril_Maio_Junho_Julho_Agosto_Setembro_Outubro_Novembro_Dezembro'.split('_'),\n    monthsShort : 'Jan_Fev_Mar_Abr_Mai_Jun_Jul_Ago_Set_Out_Nov_Dez'.split('_'),\n    weekdays : 'Domingo_Segunda-feira_Terça-feira_Quarta-feira_Quinta-feira_Sexta-feira_Sábado'.split('_'),\n    weekdaysShort : 'Dom_Seg_Ter_Qua_Qui_Sex_Sáb'.split('_'),\n    weekdaysMin : 'Do_2ª_3ª_4ª_5ª_6ª_Sá'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D [de] MMMM [de] YYYY',\n        LLL : 'D [de] MMMM [de] YYYY [às] HH:mm',\n        LLLL : 'dddd, D [de] MMMM [de] YYYY [às] HH:mm'\n    },\n    calendar : {\n        sameDay: '[Hoje às] LT',\n        nextDay: '[Amanhã às] LT',\n        nextWeek: 'dddd [às] LT',\n        lastDay: '[Ontem às] LT',\n        lastWeek: function () {\n            return (this.day() === 0 || this.day() === 6) ?\n                '[Último] dddd [às] LT' : // Saturday + Sunday\n                '[Última] dddd [às] LT'; // Monday - Friday\n        },\n        sameElse: 'L'\n    },\n    relativeTime : {\n        future : 'em %s',\n        past : '%s atrás',\n        s : 'poucos segundos',\n        m : 'um minuto',\n        mm : '%d minutos',\n        h : 'uma hora',\n        hh : '%d horas',\n        d : 'um dia',\n        dd : '%d dias',\n        M : 'um mês',\n        MM : '%d meses',\n        y : 'um ano',\n        yy : '%d anos'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}º/,\n    ordinal : '%dº'\n});\n\n//! moment.js locale configuration\n//! locale : Portuguese [pt]\n//! author : Jefferson : https://github.com/jalex79\n\nmoment.defineLocale('pt', {\n    months : 'Janeiro_Fevereiro_Março_Abril_Maio_Junho_Julho_Agosto_Setembro_Outubro_Novembro_Dezembro'.split('_'),\n    monthsShort : 'Jan_Fev_Mar_Abr_Mai_Jun_Jul_Ago_Set_Out_Nov_Dez'.split('_'),\n    weekdays : 'Domingo_Segunda-Feira_Terça-Feira_Quarta-Feira_Quinta-Feira_Sexta-Feira_Sábado'.split('_'),\n    weekdaysShort : 'Dom_Seg_Ter_Qua_Qui_Sex_Sáb'.split('_'),\n    weekdaysMin : 'Do_2ª_3ª_4ª_5ª_6ª_Sá'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D [de] MMMM [de] YYYY',\n        LLL : 'D [de] MMMM [de] YYYY HH:mm',\n        LLLL : 'dddd, D [de] MMMM [de] YYYY HH:mm'\n    },\n    calendar : {\n        sameDay: '[Hoje às] LT',\n        nextDay: '[Amanhã às] LT',\n        nextWeek: 'dddd [às] LT',\n        lastDay: '[Ontem às] LT',\n        lastWeek: function () {\n            return (this.day() === 0 || this.day() === 6) ?\n                '[Último] dddd [às] LT' : // Saturday + Sunday\n                '[Última] dddd [às] LT'; // Monday - Friday\n        },\n        sameElse: 'L'\n    },\n    relativeTime : {\n        future : 'em %s',\n        past : 'há %s',\n        s : 'segundos',\n        m : 'um minuto',\n        mm : '%d minutos',\n        h : 'uma hora',\n        hh : '%d horas',\n        d : 'um dia',\n        dd : '%d dias',\n        M : 'um mês',\n        MM : '%d meses',\n        y : 'um ano',\n        yy : '%d anos'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}º/,\n    ordinal : '%dº',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Romanian [ro]\n//! author : Vlad Gurdiga : https://github.com/gurdiga\n//! author : Valentin Agachi : https://github.com/avaly\n\nfunction relativeTimeWithPlural$2(number, withoutSuffix, key) {\n    var format = {\n            'mm': 'minute',\n            'hh': 'ore',\n            'dd': 'zile',\n            'MM': 'luni',\n            'yy': 'ani'\n        },\n        separator = ' ';\n    if (number % 100 >= 20 || (number >= 100 && number % 100 === 0)) {\n        separator = ' de ';\n    }\n    return number + separator + format[key];\n}\n\nmoment.defineLocale('ro', {\n    months : 'ianuarie_februarie_martie_aprilie_mai_iunie_iulie_august_septembrie_octombrie_noiembrie_decembrie'.split('_'),\n    monthsShort : 'ian._febr._mart._apr._mai_iun._iul._aug._sept._oct._nov._dec.'.split('_'),\n    monthsParseExact: true,\n    weekdays : 'duminică_luni_marți_miercuri_joi_vineri_sâmbătă'.split('_'),\n    weekdaysShort : 'Dum_Lun_Mar_Mie_Joi_Vin_Sâm'.split('_'),\n    weekdaysMin : 'Du_Lu_Ma_Mi_Jo_Vi_Sâ'.split('_'),\n    longDateFormat : {\n        LT : 'H:mm',\n        LTS : 'H:mm:ss',\n        L : 'DD.MM.YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY H:mm',\n        LLLL : 'dddd, D MMMM YYYY H:mm'\n    },\n    calendar : {\n        sameDay: '[azi la] LT',\n        nextDay: '[mâine la] LT',\n        nextWeek: 'dddd [la] LT',\n        lastDay: '[ieri la] LT',\n        lastWeek: '[fosta] dddd [la] LT',\n        sameElse: 'L'\n    },\n    relativeTime : {\n        future : 'peste %s',\n        past : '%s în urmă',\n        s : 'câteva secunde',\n        m : 'un minut',\n        mm : relativeTimeWithPlural$2,\n        h : 'o oră',\n        hh : relativeTimeWithPlural$2,\n        d : 'o zi',\n        dd : relativeTimeWithPlural$2,\n        M : 'o lună',\n        MM : relativeTimeWithPlural$2,\n        y : 'un an',\n        yy : relativeTimeWithPlural$2\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 7  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Russian [ru]\n//! author : Viktorminator : https://github.com/Viktorminator\n//! Author : Menelion Elensúle : https://github.com/Oire\n//! author : Коренберг Марк : https://github.com/socketpair\n\nfunction plural$4(word, num) {\n    var forms = word.split('_');\n    return num % 10 === 1 && num % 100 !== 11 ? forms[0] : (num % 10 >= 2 && num % 10 <= 4 && (num % 100 < 10 || num % 100 >= 20) ? forms[1] : forms[2]);\n}\nfunction relativeTimeWithPlural$3(number, withoutSuffix, key) {\n    var format = {\n        'mm': withoutSuffix ? 'минута_минуты_минут' : 'минуту_минуты_минут',\n        'hh': 'час_часа_часов',\n        'dd': 'день_дня_дней',\n        'MM': 'месяц_месяца_месяцев',\n        'yy': 'год_года_лет'\n    };\n    if (key === 'm') {\n        return withoutSuffix ? 'минута' : 'минуту';\n    }\n    else {\n        return number + ' ' + plural$4(format[key], +number);\n    }\n}\nvar monthsParse$2 = [/^янв/i, /^фев/i, /^мар/i, /^апр/i, /^ма[йя]/i, /^июн/i, /^июл/i, /^авг/i, /^сен/i, /^окт/i, /^ноя/i, /^дек/i];\n\n// http://new.gramota.ru/spravka/rules/139-prop : § 103\n// Сокращения месяцев: http://new.gramota.ru/spravka/buro/search-answer?s=242637\n// CLDR data:          http://www.unicode.org/cldr/charts/28/summary/ru.html#1753\nmoment.defineLocale('ru', {\n    months : {\n        format: 'января_февраля_марта_апреля_мая_июня_июля_августа_сентября_октября_ноября_декабря'.split('_'),\n        standalone: 'январь_февраль_март_апрель_май_июнь_июль_август_сентябрь_октябрь_ноябрь_декабрь'.split('_')\n    },\n    monthsShort : {\n        // по CLDR именно \"июл.\" и \"июн.\", но какой смысл менять букву на точку ?\n        format: 'янв._февр._мар._апр._мая_июня_июля_авг._сент._окт._нояб._дек.'.split('_'),\n        standalone: 'янв._февр._март_апр._май_июнь_июль_авг._сент._окт._нояб._дек.'.split('_')\n    },\n    weekdays : {\n        standalone: 'воскресенье_понедельник_вторник_среда_четверг_пятница_суббота'.split('_'),\n        format: 'воскресенье_понедельник_вторник_среду_четверг_пятницу_субботу'.split('_'),\n        isFormat: /\\[ ?[Вв] ?(?:прошлую|следующую|эту)? ?\\] ?dddd/\n    },\n    weekdaysShort : 'вс_пн_вт_ср_чт_пт_сб'.split('_'),\n    weekdaysMin : 'вс_пн_вт_ср_чт_пт_сб'.split('_'),\n    monthsParse : monthsParse$2,\n    longMonthsParse : monthsParse$2,\n    shortMonthsParse : monthsParse$2,\n\n    // полные названия с падежами, по три буквы, для некоторых, по 4 буквы, сокращения с точкой и без точки\n    monthsRegex: /^(январ[ья]|янв\\.?|феврал[ья]|февр?\\.?|марта?|мар\\.?|апрел[ья]|апр\\.?|ма[йя]|июн[ья]|июн\\.?|июл[ья]|июл\\.?|августа?|авг\\.?|сентябр[ья]|сент?\\.?|октябр[ья]|окт\\.?|ноябр[ья]|нояб?\\.?|декабр[ья]|дек\\.?)/i,\n\n    // копия предыдущего\n    monthsShortRegex: /^(январ[ья]|янв\\.?|феврал[ья]|февр?\\.?|марта?|мар\\.?|апрел[ья]|апр\\.?|ма[йя]|июн[ья]|июн\\.?|июл[ья]|июл\\.?|августа?|авг\\.?|сентябр[ья]|сент?\\.?|октябр[ья]|окт\\.?|ноябр[ья]|нояб?\\.?|декабр[ья]|дек\\.?)/i,\n\n    // полные названия с падежами\n    monthsStrictRegex: /^(январ[яь]|феврал[яь]|марта?|апрел[яь]|ма[яй]|июн[яь]|июл[яь]|августа?|сентябр[яь]|октябр[яь]|ноябр[яь]|декабр[яь])/i,\n\n    // Выражение, которое соотвествует только сокращённым формам\n    monthsShortStrictRegex: /^(янв\\.|февр?\\.|мар[т.]|апр\\.|ма[яй]|июн[ья.]|июл[ья.]|авг\\.|сент?\\.|окт\\.|нояб?\\.|дек\\.)/i,\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD.MM.YYYY',\n        LL : 'D MMMM YYYY г.',\n        LLL : 'D MMMM YYYY г., HH:mm',\n        LLLL : 'dddd, D MMMM YYYY г., HH:mm'\n    },\n    calendar : {\n        sameDay: '[Сегодня в] LT',\n        nextDay: '[Завтра в] LT',\n        lastDay: '[Вчера в] LT',\n        nextWeek: function (now) {\n            if (now.week() !== this.week()) {\n                switch (this.day()) {\n                    case 0:\n                        return '[В следующее] dddd [в] LT';\n                    case 1:\n                    case 2:\n                    case 4:\n                        return '[В следующий] dddd [в] LT';\n                    case 3:\n                    case 5:\n                    case 6:\n                        return '[В следующую] dddd [в] LT';\n                }\n            } else {\n                if (this.day() === 2) {\n                    return '[Во] dddd [в] LT';\n                } else {\n                    return '[В] dddd [в] LT';\n                }\n            }\n        },\n        lastWeek: function (now) {\n            if (now.week() !== this.week()) {\n                switch (this.day()) {\n                    case 0:\n                        return '[В прошлое] dddd [в] LT';\n                    case 1:\n                    case 2:\n                    case 4:\n                        return '[В прошлый] dddd [в] LT';\n                    case 3:\n                    case 5:\n                    case 6:\n                        return '[В прошлую] dddd [в] LT';\n                }\n            } else {\n                if (this.day() === 2) {\n                    return '[Во] dddd [в] LT';\n                } else {\n                    return '[В] dddd [в] LT';\n                }\n            }\n        },\n        sameElse: 'L'\n    },\n    relativeTime : {\n        future : 'через %s',\n        past : '%s назад',\n        s : 'несколько секунд',\n        m : relativeTimeWithPlural$3,\n        mm : relativeTimeWithPlural$3,\n        h : 'час',\n        hh : relativeTimeWithPlural$3,\n        d : 'день',\n        dd : relativeTimeWithPlural$3,\n        M : 'месяц',\n        MM : relativeTimeWithPlural$3,\n        y : 'год',\n        yy : relativeTimeWithPlural$3\n    },\n    meridiemParse: /ночи|утра|дня|вечера/i,\n    isPM : function (input) {\n        return /^(дня|вечера)$/.test(input);\n    },\n    meridiem : function (hour, minute, isLower) {\n        if (hour < 4) {\n            return 'ночи';\n        } else if (hour < 12) {\n            return 'утра';\n        } else if (hour < 17) {\n            return 'дня';\n        } else {\n            return 'вечера';\n        }\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}-(й|го|я)/,\n    ordinal: function (number, period) {\n        switch (period) {\n            case 'M':\n            case 'd':\n            case 'DDD':\n                return number + '-й';\n            case 'D':\n                return number + '-го';\n            case 'w':\n            case 'W':\n                return number + '-я';\n            default:\n                return number;\n        }\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 7  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Sindhi [sd]\n//! author : Narain Sagar : https://github.com/narainsagar\n\nvar months$5 = [\n    'جنوري',\n    'فيبروري',\n    'مارچ',\n    'اپريل',\n    'مئي',\n    'جون',\n    'جولاءِ',\n    'آگسٽ',\n    'سيپٽمبر',\n    'آڪٽوبر',\n    'نومبر',\n    'ڊسمبر'\n];\nvar days = [\n    'آچر',\n    'سومر',\n    'اڱارو',\n    'اربع',\n    'خميس',\n    'جمع',\n    'ڇنڇر'\n];\n\nmoment.defineLocale('sd', {\n    months : months$5,\n    monthsShort : months$5,\n    weekdays : days,\n    weekdaysShort : days,\n    weekdaysMin : days,\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY HH:mm',\n        LLLL : 'dddd، D MMMM YYYY HH:mm'\n    },\n    meridiemParse: /صبح|شام/,\n    isPM : function (input) {\n        return 'شام' === input;\n    },\n    meridiem : function (hour, minute, isLower) {\n        if (hour < 12) {\n            return 'صبح';\n        }\n        return 'شام';\n    },\n    calendar : {\n        sameDay : '[اڄ] LT',\n        nextDay : '[سڀاڻي] LT',\n        nextWeek : 'dddd [اڳين هفتي تي] LT',\n        lastDay : '[ڪالهه] LT',\n        lastWeek : '[گزريل هفتي] dddd [تي] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : '%s پوء',\n        past : '%s اڳ',\n        s : 'چند سيڪنڊ',\n        m : 'هڪ منٽ',\n        mm : '%d منٽ',\n        h : 'هڪ ڪلاڪ',\n        hh : '%d ڪلاڪ',\n        d : 'هڪ ڏينهن',\n        dd : '%d ڏينهن',\n        M : 'هڪ مهينو',\n        MM : '%d مهينا',\n        y : 'هڪ سال',\n        yy : '%d سال'\n    },\n    preparse: function (string) {\n        return string.replace(/،/g, ',');\n    },\n    postformat: function (string) {\n        return string.replace(/,/g, '،');\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Northern Sami [se]\n//! authors : Bård Rolstad Henriksen : https://github.com/karamell\n\n\nmoment.defineLocale('se', {\n    months : 'ođđajagemánnu_guovvamánnu_njukčamánnu_cuoŋománnu_miessemánnu_geassemánnu_suoidnemánnu_borgemánnu_čakčamánnu_golggotmánnu_skábmamánnu_juovlamánnu'.split('_'),\n    monthsShort : 'ođđj_guov_njuk_cuo_mies_geas_suoi_borg_čakč_golg_skáb_juov'.split('_'),\n    weekdays : 'sotnabeaivi_vuossárga_maŋŋebárga_gaskavahkku_duorastat_bearjadat_lávvardat'.split('_'),\n    weekdaysShort : 'sotn_vuos_maŋ_gask_duor_bear_láv'.split('_'),\n    weekdaysMin : 's_v_m_g_d_b_L'.split('_'),\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD.MM.YYYY',\n        LL : 'MMMM D. [b.] YYYY',\n        LLL : 'MMMM D. [b.] YYYY [ti.] HH:mm',\n        LLLL : 'dddd, MMMM D. [b.] YYYY [ti.] HH:mm'\n    },\n    calendar : {\n        sameDay: '[otne ti] LT',\n        nextDay: '[ihttin ti] LT',\n        nextWeek: 'dddd [ti] LT',\n        lastDay: '[ikte ti] LT',\n        lastWeek: '[ovddit] dddd [ti] LT',\n        sameElse: 'L'\n    },\n    relativeTime : {\n        future : '%s geažes',\n        past : 'maŋit %s',\n        s : 'moadde sekunddat',\n        m : 'okta minuhta',\n        mm : '%d minuhtat',\n        h : 'okta diimmu',\n        hh : '%d diimmut',\n        d : 'okta beaivi',\n        dd : '%d beaivvit',\n        M : 'okta mánnu',\n        MM : '%d mánut',\n        y : 'okta jahki',\n        yy : '%d jagit'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}\\./,\n    ordinal : '%d.',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Sinhalese [si]\n//! author : Sampath Sitinamaluwa : https://github.com/sampathsris\n\n/*jshint -W100*/\nmoment.defineLocale('si', {\n    months : 'ජනවාරි_පෙබරවාරි_මාර්තු_අප්‍රේල්_මැයි_ජූනි_ජූලි_අගෝස්තු_සැප්තැම්බර්_ඔක්තෝබර්_නොවැම්බර්_දෙසැම්බර්'.split('_'),\n    monthsShort : 'ජන_පෙබ_මාර්_අප්_මැයි_ජූනි_ජූලි_අගෝ_සැප්_ඔක්_නොවැ_දෙසැ'.split('_'),\n    weekdays : 'ඉරිදා_සඳුදා_අඟහරුවාදා_බදාදා_බ්‍රහස්පතින්දා_සිකුරාදා_සෙනසුරාදා'.split('_'),\n    weekdaysShort : 'ඉරි_සඳු_අඟ_බදා_බ්‍රහ_සිකු_සෙන'.split('_'),\n    weekdaysMin : 'ඉ_ස_අ_බ_බ්‍ර_සි_සෙ'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat : {\n        LT : 'a h:mm',\n        LTS : 'a h:mm:ss',\n        L : 'YYYY/MM/DD',\n        LL : 'YYYY MMMM D',\n        LLL : 'YYYY MMMM D, a h:mm',\n        LLLL : 'YYYY MMMM D [වැනි] dddd, a h:mm:ss'\n    },\n    calendar : {\n        sameDay : '[අද] LT[ට]',\n        nextDay : '[හෙට] LT[ට]',\n        nextWeek : 'dddd LT[ට]',\n        lastDay : '[ඊයේ] LT[ට]',\n        lastWeek : '[පසුගිය] dddd LT[ට]',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : '%sකින්',\n        past : '%sකට පෙර',\n        s : 'තත්පර කිහිපය',\n        m : 'මිනිත්තුව',\n        mm : 'මිනිත්තු %d',\n        h : 'පැය',\n        hh : 'පැය %d',\n        d : 'දිනය',\n        dd : 'දින %d',\n        M : 'මාසය',\n        MM : 'මාස %d',\n        y : 'වසර',\n        yy : 'වසර %d'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2} වැනි/,\n    ordinal : function (number) {\n        return number + ' වැනි';\n    },\n    meridiemParse : /පෙර වරු|පස් වරු|පෙ.ව|ප.ව./,\n    isPM : function (input) {\n        return input === 'ප.ව.' || input === 'පස් වරු';\n    },\n    meridiem : function (hours, minutes, isLower) {\n        if (hours > 11) {\n            return isLower ? 'ප.ව.' : 'පස් වරු';\n        } else {\n            return isLower ? 'පෙ.ව.' : 'පෙර වරු';\n        }\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Slovak [sk]\n//! author : Martin Minka : https://github.com/k2s\n//! based on work of petrbela : https://github.com/petrbela\n\nvar months$6 = 'január_február_marec_apríl_máj_jún_júl_august_september_október_november_december'.split('_');\nvar monthsShort$4 = 'jan_feb_mar_apr_máj_jún_júl_aug_sep_okt_nov_dec'.split('_');\nfunction plural$5(n) {\n    return (n > 1) && (n < 5);\n}\nfunction translate$8(number, withoutSuffix, key, isFuture) {\n    var result = number + ' ';\n    switch (key) {\n        case 's':  // a few seconds / in a few seconds / a few seconds ago\n            return (withoutSuffix || isFuture) ? 'pár sekúnd' : 'pár sekundami';\n        case 'm':  // a minute / in a minute / a minute ago\n            return withoutSuffix ? 'minúta' : (isFuture ? 'minútu' : 'minútou');\n        case 'mm': // 9 minutes / in 9 minutes / 9 minutes ago\n            if (withoutSuffix || isFuture) {\n                return result + (plural$5(number) ? 'minúty' : 'minút');\n            } else {\n                return result + 'minútami';\n            }\n            break;\n        case 'h':  // an hour / in an hour / an hour ago\n            return withoutSuffix ? 'hodina' : (isFuture ? 'hodinu' : 'hodinou');\n        case 'hh': // 9 hours / in 9 hours / 9 hours ago\n            if (withoutSuffix || isFuture) {\n                return result + (plural$5(number) ? 'hodiny' : 'hodín');\n            } else {\n                return result + 'hodinami';\n            }\n            break;\n        case 'd':  // a day / in a day / a day ago\n            return (withoutSuffix || isFuture) ? 'deň' : 'dňom';\n        case 'dd': // 9 days / in 9 days / 9 days ago\n            if (withoutSuffix || isFuture) {\n                return result + (plural$5(number) ? 'dni' : 'dní');\n            } else {\n                return result + 'dňami';\n            }\n            break;\n        case 'M':  // a month / in a month / a month ago\n            return (withoutSuffix || isFuture) ? 'mesiac' : 'mesiacom';\n        case 'MM': // 9 months / in 9 months / 9 months ago\n            if (withoutSuffix || isFuture) {\n                return result + (plural$5(number) ? 'mesiace' : 'mesiacov');\n            } else {\n                return result + 'mesiacmi';\n            }\n            break;\n        case 'y':  // a year / in a year / a year ago\n            return (withoutSuffix || isFuture) ? 'rok' : 'rokom';\n        case 'yy': // 9 years / in 9 years / 9 years ago\n            if (withoutSuffix || isFuture) {\n                return result + (plural$5(number) ? 'roky' : 'rokov');\n            } else {\n                return result + 'rokmi';\n            }\n            break;\n    }\n}\n\nmoment.defineLocale('sk', {\n    months : months$6,\n    monthsShort : monthsShort$4,\n    weekdays : 'nedeľa_pondelok_utorok_streda_štvrtok_piatok_sobota'.split('_'),\n    weekdaysShort : 'ne_po_ut_st_št_pi_so'.split('_'),\n    weekdaysMin : 'ne_po_ut_st_št_pi_so'.split('_'),\n    longDateFormat : {\n        LT: 'H:mm',\n        LTS : 'H:mm:ss',\n        L : 'DD.MM.YYYY',\n        LL : 'D. MMMM YYYY',\n        LLL : 'D. MMMM YYYY H:mm',\n        LLLL : 'dddd D. MMMM YYYY H:mm'\n    },\n    calendar : {\n        sameDay: '[dnes o] LT',\n        nextDay: '[zajtra o] LT',\n        nextWeek: function () {\n            switch (this.day()) {\n                case 0:\n                    return '[v nedeľu o] LT';\n                case 1:\n                case 2:\n                    return '[v] dddd [o] LT';\n                case 3:\n                    return '[v stredu o] LT';\n                case 4:\n                    return '[vo štvrtok o] LT';\n                case 5:\n                    return '[v piatok o] LT';\n                case 6:\n                    return '[v sobotu o] LT';\n            }\n        },\n        lastDay: '[včera o] LT',\n        lastWeek: function () {\n            switch (this.day()) {\n                case 0:\n                    return '[minulú nedeľu o] LT';\n                case 1:\n                case 2:\n                    return '[minulý] dddd [o] LT';\n                case 3:\n                    return '[minulú stredu o] LT';\n                case 4:\n                case 5:\n                    return '[minulý] dddd [o] LT';\n                case 6:\n                    return '[minulú sobotu o] LT';\n            }\n        },\n        sameElse: 'L'\n    },\n    relativeTime : {\n        future : 'za %s',\n        past : 'pred %s',\n        s : translate$8,\n        m : translate$8,\n        mm : translate$8,\n        h : translate$8,\n        hh : translate$8,\n        d : translate$8,\n        dd : translate$8,\n        M : translate$8,\n        MM : translate$8,\n        y : translate$8,\n        yy : translate$8\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}\\./,\n    ordinal : '%d.',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Slovenian [sl]\n//! author : Robert Sedovšek : https://github.com/sedovsek\n\nfunction processRelativeTime$6(number, withoutSuffix, key, isFuture) {\n    var result = number + ' ';\n    switch (key) {\n        case 's':\n            return withoutSuffix || isFuture ? 'nekaj sekund' : 'nekaj sekundami';\n        case 'm':\n            return withoutSuffix ? 'ena minuta' : 'eno minuto';\n        case 'mm':\n            if (number === 1) {\n                result += withoutSuffix ? 'minuta' : 'minuto';\n            } else if (number === 2) {\n                result += withoutSuffix || isFuture ? 'minuti' : 'minutama';\n            } else if (number < 5) {\n                result += withoutSuffix || isFuture ? 'minute' : 'minutami';\n            } else {\n                result += withoutSuffix || isFuture ? 'minut' : 'minutami';\n            }\n            return result;\n        case 'h':\n            return withoutSuffix ? 'ena ura' : 'eno uro';\n        case 'hh':\n            if (number === 1) {\n                result += withoutSuffix ? 'ura' : 'uro';\n            } else if (number === 2) {\n                result += withoutSuffix || isFuture ? 'uri' : 'urama';\n            } else if (number < 5) {\n                result += withoutSuffix || isFuture ? 'ure' : 'urami';\n            } else {\n                result += withoutSuffix || isFuture ? 'ur' : 'urami';\n            }\n            return result;\n        case 'd':\n            return withoutSuffix || isFuture ? 'en dan' : 'enim dnem';\n        case 'dd':\n            if (number === 1) {\n                result += withoutSuffix || isFuture ? 'dan' : 'dnem';\n            } else if (number === 2) {\n                result += withoutSuffix || isFuture ? 'dni' : 'dnevoma';\n            } else {\n                result += withoutSuffix || isFuture ? 'dni' : 'dnevi';\n            }\n            return result;\n        case 'M':\n            return withoutSuffix || isFuture ? 'en mesec' : 'enim mesecem';\n        case 'MM':\n            if (number === 1) {\n                result += withoutSuffix || isFuture ? 'mesec' : 'mesecem';\n            } else if (number === 2) {\n                result += withoutSuffix || isFuture ? 'meseca' : 'mesecema';\n            } else if (number < 5) {\n                result += withoutSuffix || isFuture ? 'mesece' : 'meseci';\n            } else {\n                result += withoutSuffix || isFuture ? 'mesecev' : 'meseci';\n            }\n            return result;\n        case 'y':\n            return withoutSuffix || isFuture ? 'eno leto' : 'enim letom';\n        case 'yy':\n            if (number === 1) {\n                result += withoutSuffix || isFuture ? 'leto' : 'letom';\n            } else if (number === 2) {\n                result += withoutSuffix || isFuture ? 'leti' : 'letoma';\n            } else if (number < 5) {\n                result += withoutSuffix || isFuture ? 'leta' : 'leti';\n            } else {\n                result += withoutSuffix || isFuture ? 'let' : 'leti';\n            }\n            return result;\n    }\n}\n\nmoment.defineLocale('sl', {\n    months : 'januar_februar_marec_april_maj_junij_julij_avgust_september_oktober_november_december'.split('_'),\n    monthsShort : 'jan._feb._mar._apr._maj._jun._jul._avg._sep._okt._nov._dec.'.split('_'),\n    monthsParseExact: true,\n    weekdays : 'nedelja_ponedeljek_torek_sreda_četrtek_petek_sobota'.split('_'),\n    weekdaysShort : 'ned._pon._tor._sre._čet._pet._sob.'.split('_'),\n    weekdaysMin : 'ne_po_to_sr_če_pe_so'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat : {\n        LT : 'H:mm',\n        LTS : 'H:mm:ss',\n        L : 'DD.MM.YYYY',\n        LL : 'D. MMMM YYYY',\n        LLL : 'D. MMMM YYYY H:mm',\n        LLLL : 'dddd, D. MMMM YYYY H:mm'\n    },\n    calendar : {\n        sameDay  : '[danes ob] LT',\n        nextDay  : '[jutri ob] LT',\n\n        nextWeek : function () {\n            switch (this.day()) {\n                case 0:\n                    return '[v] [nedeljo] [ob] LT';\n                case 3:\n                    return '[v] [sredo] [ob] LT';\n                case 6:\n                    return '[v] [soboto] [ob] LT';\n                case 1:\n                case 2:\n                case 4:\n                case 5:\n                    return '[v] dddd [ob] LT';\n            }\n        },\n        lastDay  : '[včeraj ob] LT',\n        lastWeek : function () {\n            switch (this.day()) {\n                case 0:\n                    return '[prejšnjo] [nedeljo] [ob] LT';\n                case 3:\n                    return '[prejšnjo] [sredo] [ob] LT';\n                case 6:\n                    return '[prejšnjo] [soboto] [ob] LT';\n                case 1:\n                case 2:\n                case 4:\n                case 5:\n                    return '[prejšnji] dddd [ob] LT';\n            }\n        },\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'čez %s',\n        past   : 'pred %s',\n        s      : processRelativeTime$6,\n        m      : processRelativeTime$6,\n        mm     : processRelativeTime$6,\n        h      : processRelativeTime$6,\n        hh     : processRelativeTime$6,\n        d      : processRelativeTime$6,\n        dd     : processRelativeTime$6,\n        M      : processRelativeTime$6,\n        MM     : processRelativeTime$6,\n        y      : processRelativeTime$6,\n        yy     : processRelativeTime$6\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}\\./,\n    ordinal : '%d.',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 7  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Albanian [sq]\n//! author : Flakërim Ismani : https://github.com/flakerimi\n//! author : Menelion Elensúle : https://github.com/Oire\n//! author : Oerd Cukalla : https://github.com/oerd\n\nmoment.defineLocale('sq', {\n    months : 'Janar_Shkurt_Mars_Prill_Maj_Qershor_Korrik_Gusht_Shtator_Tetor_Nëntor_Dhjetor'.split('_'),\n    monthsShort : 'Jan_Shk_Mar_Pri_Maj_Qer_Kor_Gus_Sht_Tet_Nën_Dhj'.split('_'),\n    weekdays : 'E Diel_E Hënë_E Martë_E Mërkurë_E Enjte_E Premte_E Shtunë'.split('_'),\n    weekdaysShort : 'Die_Hën_Mar_Mër_Enj_Pre_Sht'.split('_'),\n    weekdaysMin : 'D_H_Ma_Më_E_P_Sh'.split('_'),\n    weekdaysParseExact : true,\n    meridiemParse: /PD|MD/,\n    isPM: function (input) {\n        return input.charAt(0) === 'M';\n    },\n    meridiem : function (hours, minutes, isLower) {\n        return hours < 12 ? 'PD' : 'MD';\n    },\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY HH:mm',\n        LLLL : 'dddd, D MMMM YYYY HH:mm'\n    },\n    calendar : {\n        sameDay : '[Sot në] LT',\n        nextDay : '[Nesër në] LT',\n        nextWeek : 'dddd [në] LT',\n        lastDay : '[Dje në] LT',\n        lastWeek : 'dddd [e kaluar në] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'në %s',\n        past : '%s më parë',\n        s : 'disa sekonda',\n        m : 'një minutë',\n        mm : '%d minuta',\n        h : 'një orë',\n        hh : '%d orë',\n        d : 'një ditë',\n        dd : '%d ditë',\n        M : 'një muaj',\n        MM : '%d muaj',\n        y : 'një vit',\n        yy : '%d vite'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}\\./,\n    ordinal : '%d.',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Serbian Cyrillic [sr-cyrl]\n//! author : Milan Janačković<milanjanackovic@gmail.com> : https://github.com/milan-j\n\nvar translator$1 = {\n    words: { //Different grammatical cases\n        m: ['један минут', 'једне минуте'],\n        mm: ['минут', 'минуте', 'минута'],\n        h: ['један сат', 'једног сата'],\n        hh: ['сат', 'сата', 'сати'],\n        dd: ['дан', 'дана', 'дана'],\n        MM: ['месец', 'месеца', 'месеци'],\n        yy: ['година', 'године', 'година']\n    },\n    correctGrammaticalCase: function (number, wordKey) {\n        return number === 1 ? wordKey[0] : (number >= 2 && number <= 4 ? wordKey[1] : wordKey[2]);\n    },\n    translate: function (number, withoutSuffix, key) {\n        var wordKey = translator$1.words[key];\n        if (key.length === 1) {\n            return withoutSuffix ? wordKey[0] : wordKey[1];\n        } else {\n            return number + ' ' + translator$1.correctGrammaticalCase(number, wordKey);\n        }\n    }\n};\n\nmoment.defineLocale('sr-cyrl', {\n    months: 'јануар_фебруар_март_април_мај_јун_јул_август_септембар_октобар_новембар_децембар'.split('_'),\n    monthsShort: 'јан._феб._мар._апр._мај_јун_јул_авг._сеп._окт._нов._дец.'.split('_'),\n    monthsParseExact: true,\n    weekdays: 'недеља_понедељак_уторак_среда_четвртак_петак_субота'.split('_'),\n    weekdaysShort: 'нед._пон._уто._сре._чет._пет._суб.'.split('_'),\n    weekdaysMin: 'не_по_ут_ср_че_пе_су'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat: {\n        LT: 'H:mm',\n        LTS : 'H:mm:ss',\n        L: 'DD.MM.YYYY',\n        LL: 'D. MMMM YYYY',\n        LLL: 'D. MMMM YYYY H:mm',\n        LLLL: 'dddd, D. MMMM YYYY H:mm'\n    },\n    calendar: {\n        sameDay: '[данас у] LT',\n        nextDay: '[сутра у] LT',\n        nextWeek: function () {\n            switch (this.day()) {\n                case 0:\n                    return '[у] [недељу] [у] LT';\n                case 3:\n                    return '[у] [среду] [у] LT';\n                case 6:\n                    return '[у] [суботу] [у] LT';\n                case 1:\n                case 2:\n                case 4:\n                case 5:\n                    return '[у] dddd [у] LT';\n            }\n        },\n        lastDay  : '[јуче у] LT',\n        lastWeek : function () {\n            var lastWeekDays = [\n                '[прошле] [недеље] [у] LT',\n                '[прошлог] [понедељка] [у] LT',\n                '[прошлог] [уторка] [у] LT',\n                '[прошле] [среде] [у] LT',\n                '[прошлог] [четвртка] [у] LT',\n                '[прошлог] [петка] [у] LT',\n                '[прошле] [суботе] [у] LT'\n            ];\n            return lastWeekDays[this.day()];\n        },\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'за %s',\n        past   : 'пре %s',\n        s      : 'неколико секунди',\n        m      : translator$1.translate,\n        mm     : translator$1.translate,\n        h      : translator$1.translate,\n        hh     : translator$1.translate,\n        d      : 'дан',\n        dd     : translator$1.translate,\n        M      : 'месец',\n        MM     : translator$1.translate,\n        y      : 'годину',\n        yy     : translator$1.translate\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}\\./,\n    ordinal : '%d.',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 7  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Serbian [sr]\n//! author : Milan Janačković<milanjanackovic@gmail.com> : https://github.com/milan-j\n\nvar translator$2 = {\n    words: { //Different grammatical cases\n        m: ['jedan minut', 'jedne minute'],\n        mm: ['minut', 'minute', 'minuta'],\n        h: ['jedan sat', 'jednog sata'],\n        hh: ['sat', 'sata', 'sati'],\n        dd: ['dan', 'dana', 'dana'],\n        MM: ['mesec', 'meseca', 'meseci'],\n        yy: ['godina', 'godine', 'godina']\n    },\n    correctGrammaticalCase: function (number, wordKey) {\n        return number === 1 ? wordKey[0] : (number >= 2 && number <= 4 ? wordKey[1] : wordKey[2]);\n    },\n    translate: function (number, withoutSuffix, key) {\n        var wordKey = translator$2.words[key];\n        if (key.length === 1) {\n            return withoutSuffix ? wordKey[0] : wordKey[1];\n        } else {\n            return number + ' ' + translator$2.correctGrammaticalCase(number, wordKey);\n        }\n    }\n};\n\nmoment.defineLocale('sr', {\n    months: 'januar_februar_mart_april_maj_jun_jul_avgust_septembar_oktobar_novembar_decembar'.split('_'),\n    monthsShort: 'jan._feb._mar._apr._maj_jun_jul_avg._sep._okt._nov._dec.'.split('_'),\n    monthsParseExact: true,\n    weekdays: 'nedelja_ponedeljak_utorak_sreda_četvrtak_petak_subota'.split('_'),\n    weekdaysShort: 'ned._pon._uto._sre._čet._pet._sub.'.split('_'),\n    weekdaysMin: 'ne_po_ut_sr_če_pe_su'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat: {\n        LT: 'H:mm',\n        LTS : 'H:mm:ss',\n        L: 'DD.MM.YYYY',\n        LL: 'D. MMMM YYYY',\n        LLL: 'D. MMMM YYYY H:mm',\n        LLLL: 'dddd, D. MMMM YYYY H:mm'\n    },\n    calendar: {\n        sameDay: '[danas u] LT',\n        nextDay: '[sutra u] LT',\n        nextWeek: function () {\n            switch (this.day()) {\n                case 0:\n                    return '[u] [nedelju] [u] LT';\n                case 3:\n                    return '[u] [sredu] [u] LT';\n                case 6:\n                    return '[u] [subotu] [u] LT';\n                case 1:\n                case 2:\n                case 4:\n                case 5:\n                    return '[u] dddd [u] LT';\n            }\n        },\n        lastDay  : '[juče u] LT',\n        lastWeek : function () {\n            var lastWeekDays = [\n                '[prošle] [nedelje] [u] LT',\n                '[prošlog] [ponedeljka] [u] LT',\n                '[prošlog] [utorka] [u] LT',\n                '[prošle] [srede] [u] LT',\n                '[prošlog] [četvrtka] [u] LT',\n                '[prošlog] [petka] [u] LT',\n                '[prošle] [subote] [u] LT'\n            ];\n            return lastWeekDays[this.day()];\n        },\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'za %s',\n        past   : 'pre %s',\n        s      : 'nekoliko sekundi',\n        m      : translator$2.translate,\n        mm     : translator$2.translate,\n        h      : translator$2.translate,\n        hh     : translator$2.translate,\n        d      : 'dan',\n        dd     : translator$2.translate,\n        M      : 'mesec',\n        MM     : translator$2.translate,\n        y      : 'godinu',\n        yy     : translator$2.translate\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}\\./,\n    ordinal : '%d.',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 7  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : siSwati [ss]\n//! author : Nicolai Davies<mail@nicolai.io> : https://github.com/nicolaidavies\n\n\nmoment.defineLocale('ss', {\n    months : \"Bhimbidvwane_Indlovana_Indlov'lenkhulu_Mabasa_Inkhwekhweti_Inhlaba_Kholwane_Ingci_Inyoni_Imphala_Lweti_Ingongoni\".split('_'),\n    monthsShort : 'Bhi_Ina_Inu_Mab_Ink_Inh_Kho_Igc_Iny_Imp_Lwe_Igo'.split('_'),\n    weekdays : 'Lisontfo_Umsombuluko_Lesibili_Lesitsatfu_Lesine_Lesihlanu_Umgcibelo'.split('_'),\n    weekdaysShort : 'Lis_Umb_Lsb_Les_Lsi_Lsh_Umg'.split('_'),\n    weekdaysMin : 'Li_Us_Lb_Lt_Ls_Lh_Ug'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat : {\n        LT : 'h:mm A',\n        LTS : 'h:mm:ss A',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY h:mm A',\n        LLLL : 'dddd, D MMMM YYYY h:mm A'\n    },\n    calendar : {\n        sameDay : '[Namuhla nga] LT',\n        nextDay : '[Kusasa nga] LT',\n        nextWeek : 'dddd [nga] LT',\n        lastDay : '[Itolo nga] LT',\n        lastWeek : 'dddd [leliphelile] [nga] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'nga %s',\n        past : 'wenteka nga %s',\n        s : 'emizuzwana lomcane',\n        m : 'umzuzu',\n        mm : '%d emizuzu',\n        h : 'lihora',\n        hh : '%d emahora',\n        d : 'lilanga',\n        dd : '%d emalanga',\n        M : 'inyanga',\n        MM : '%d tinyanga',\n        y : 'umnyaka',\n        yy : '%d iminyaka'\n    },\n    meridiemParse: /ekuseni|emini|entsambama|ebusuku/,\n    meridiem : function (hours, minutes, isLower) {\n        if (hours < 11) {\n            return 'ekuseni';\n        } else if (hours < 15) {\n            return 'emini';\n        } else if (hours < 19) {\n            return 'entsambama';\n        } else {\n            return 'ebusuku';\n        }\n    },\n    meridiemHour : function (hour, meridiem) {\n        if (hour === 12) {\n            hour = 0;\n        }\n        if (meridiem === 'ekuseni') {\n            return hour;\n        } else if (meridiem === 'emini') {\n            return hour >= 11 ? hour : hour + 12;\n        } else if (meridiem === 'entsambama' || meridiem === 'ebusuku') {\n            if (hour === 0) {\n                return 0;\n            }\n            return hour + 12;\n        }\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}/,\n    ordinal : '%d',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Swedish [sv]\n//! author : Jens Alm : https://github.com/ulmus\n\nmoment.defineLocale('sv', {\n    months : 'januari_februari_mars_april_maj_juni_juli_augusti_september_oktober_november_december'.split('_'),\n    monthsShort : 'jan_feb_mar_apr_maj_jun_jul_aug_sep_okt_nov_dec'.split('_'),\n    weekdays : 'söndag_måndag_tisdag_onsdag_torsdag_fredag_lördag'.split('_'),\n    weekdaysShort : 'sön_mån_tis_ons_tor_fre_lör'.split('_'),\n    weekdaysMin : 'sö_må_ti_on_to_fr_lö'.split('_'),\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'YYYY-MM-DD',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY [kl.] HH:mm',\n        LLLL : 'dddd D MMMM YYYY [kl.] HH:mm',\n        lll : 'D MMM YYYY HH:mm',\n        llll : 'ddd D MMM YYYY HH:mm'\n    },\n    calendar : {\n        sameDay: '[Idag] LT',\n        nextDay: '[Imorgon] LT',\n        lastDay: '[Igår] LT',\n        nextWeek: '[På] dddd LT',\n        lastWeek: '[I] dddd[s] LT',\n        sameElse: 'L'\n    },\n    relativeTime : {\n        future : 'om %s',\n        past : 'för %s sedan',\n        s : 'några sekunder',\n        m : 'en minut',\n        mm : '%d minuter',\n        h : 'en timme',\n        hh : '%d timmar',\n        d : 'en dag',\n        dd : '%d dagar',\n        M : 'en månad',\n        MM : '%d månader',\n        y : 'ett år',\n        yy : '%d år'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}(e|a)/,\n    ordinal : function (number) {\n        var b = number % 10,\n            output = (~~(number % 100 / 10) === 1) ? 'e' :\n            (b === 1) ? 'a' :\n            (b === 2) ? 'a' :\n            (b === 3) ? 'e' : 'e';\n        return number + output;\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Swahili [sw]\n//! author : Fahad Kassim : https://github.com/fadsel\n\nmoment.defineLocale('sw', {\n    months : 'Januari_Februari_Machi_Aprili_Mei_Juni_Julai_Agosti_Septemba_Oktoba_Novemba_Desemba'.split('_'),\n    monthsShort : 'Jan_Feb_Mac_Apr_Mei_Jun_Jul_Ago_Sep_Okt_Nov_Des'.split('_'),\n    weekdays : 'Jumapili_Jumatatu_Jumanne_Jumatano_Alhamisi_Ijumaa_Jumamosi'.split('_'),\n    weekdaysShort : 'Jpl_Jtat_Jnne_Jtan_Alh_Ijm_Jmos'.split('_'),\n    weekdaysMin : 'J2_J3_J4_J5_Al_Ij_J1'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD.MM.YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY HH:mm',\n        LLLL : 'dddd, D MMMM YYYY HH:mm'\n    },\n    calendar : {\n        sameDay : '[leo saa] LT',\n        nextDay : '[kesho saa] LT',\n        nextWeek : '[wiki ijayo] dddd [saat] LT',\n        lastDay : '[jana] LT',\n        lastWeek : '[wiki iliyopita] dddd [saat] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : '%s baadaye',\n        past : 'tokea %s',\n        s : 'hivi punde',\n        m : 'dakika moja',\n        mm : 'dakika %d',\n        h : 'saa limoja',\n        hh : 'masaa %d',\n        d : 'siku moja',\n        dd : 'masiku %d',\n        M : 'mwezi mmoja',\n        MM : 'miezi %d',\n        y : 'mwaka mmoja',\n        yy : 'miaka %d'\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 7  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Tamil [ta]\n//! author : Arjunkumar Krishnamoorthy : https://github.com/tk120404\n\nvar symbolMap$12 = {\n    '1': '௧',\n    '2': '௨',\n    '3': '௩',\n    '4': '௪',\n    '5': '௫',\n    '6': '௬',\n    '7': '௭',\n    '8': '௮',\n    '9': '௯',\n    '0': '௦'\n};\nvar numberMap$11 = {\n    '௧': '1',\n    '௨': '2',\n    '௩': '3',\n    '௪': '4',\n    '௫': '5',\n    '௬': '6',\n    '௭': '7',\n    '௮': '8',\n    '௯': '9',\n    '௦': '0'\n};\n\nmoment.defineLocale('ta', {\n    months : 'ஜனவரி_பிப்ரவரி_மார்ச்_ஏப்ரல்_மே_ஜூன்_ஜூலை_ஆகஸ்ட்_செப்டெம்பர்_அக்டோபர்_நவம்பர்_டிசம்பர்'.split('_'),\n    monthsShort : 'ஜனவரி_பிப்ரவரி_மார்ச்_ஏப்ரல்_மே_ஜூன்_ஜூலை_ஆகஸ்ட்_செப்டெம்பர்_அக்டோபர்_நவம்பர்_டிசம்பர்'.split('_'),\n    weekdays : 'ஞாயிற்றுக்கிழமை_திங்கட்கிழமை_செவ்வாய்கிழமை_புதன்கிழமை_வியாழக்கிழமை_வெள்ளிக்கிழமை_சனிக்கிழமை'.split('_'),\n    weekdaysShort : 'ஞாயிறு_திங்கள்_செவ்வாய்_புதன்_வியாழன்_வெள்ளி_சனி'.split('_'),\n    weekdaysMin : 'ஞா_தி_செ_பு_வி_வெ_ச'.split('_'),\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY, HH:mm',\n        LLLL : 'dddd, D MMMM YYYY, HH:mm'\n    },\n    calendar : {\n        sameDay : '[இன்று] LT',\n        nextDay : '[நாளை] LT',\n        nextWeek : 'dddd, LT',\n        lastDay : '[நேற்று] LT',\n        lastWeek : '[கடந்த வாரம்] dddd, LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : '%s இல்',\n        past : '%s முன்',\n        s : 'ஒரு சில விநாடிகள்',\n        m : 'ஒரு நிமிடம்',\n        mm : '%d நிமிடங்கள்',\n        h : 'ஒரு மணி நேரம்',\n        hh : '%d மணி நேரம்',\n        d : 'ஒரு நாள்',\n        dd : '%d நாட்கள்',\n        M : 'ஒரு மாதம்',\n        MM : '%d மாதங்கள்',\n        y : 'ஒரு வருடம்',\n        yy : '%d ஆண்டுகள்'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}வது/,\n    ordinal : function (number) {\n        return number + 'வது';\n    },\n    preparse: function (string) {\n        return string.replace(/[௧௨௩௪௫௬௭௮௯௦]/g, function (match) {\n            return numberMap$11[match];\n        });\n    },\n    postformat: function (string) {\n        return string.replace(/\\d/g, function (match) {\n            return symbolMap$12[match];\n        });\n    },\n    // refer http://ta.wikipedia.org/s/1er1\n    meridiemParse: /யாமம்|வைகறை|காலை|நண்பகல்|எற்பாடு|மாலை/,\n    meridiem : function (hour, minute, isLower) {\n        if (hour < 2) {\n            return ' யாமம்';\n        } else if (hour < 6) {\n            return ' வைகறை';  // வைகறை\n        } else if (hour < 10) {\n            return ' காலை'; // காலை\n        } else if (hour < 14) {\n            return ' நண்பகல்'; // நண்பகல்\n        } else if (hour < 18) {\n            return ' எற்பாடு'; // எற்பாடு\n        } else if (hour < 22) {\n            return ' மாலை'; // மாலை\n        } else {\n            return ' யாமம்';\n        }\n    },\n    meridiemHour : function (hour, meridiem) {\n        if (hour === 12) {\n            hour = 0;\n        }\n        if (meridiem === 'யாமம்') {\n            return hour < 2 ? hour : hour + 12;\n        } else if (meridiem === 'வைகறை' || meridiem === 'காலை') {\n            return hour;\n        } else if (meridiem === 'நண்பகல்') {\n            return hour >= 10 ? hour : hour + 12;\n        } else {\n            return hour + 12;\n        }\n    },\n    week : {\n        dow : 0, // Sunday is the first day of the week.\n        doy : 6  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Telugu [te]\n//! author : Krishna Chaitanya Thota : https://github.com/kcthota\n\nmoment.defineLocale('te', {\n    months : 'జనవరి_ఫిబ్రవరి_మార్చి_ఏప్రిల్_మే_జూన్_జూలై_ఆగస్టు_సెప్టెంబర్_అక్టోబర్_నవంబర్_డిసెంబర్'.split('_'),\n    monthsShort : 'జన._ఫిబ్ర._మార్చి_ఏప్రి._మే_జూన్_జూలై_ఆగ._సెప్._అక్టో._నవ._డిసె.'.split('_'),\n    monthsParseExact : true,\n    weekdays : 'ఆదివారం_సోమవారం_మంగళవారం_బుధవారం_గురువారం_శుక్రవారం_శనివారం'.split('_'),\n    weekdaysShort : 'ఆది_సోమ_మంగళ_బుధ_గురు_శుక్ర_శని'.split('_'),\n    weekdaysMin : 'ఆ_సో_మం_బు_గు_శు_శ'.split('_'),\n    longDateFormat : {\n        LT : 'A h:mm',\n        LTS : 'A h:mm:ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY, A h:mm',\n        LLLL : 'dddd, D MMMM YYYY, A h:mm'\n    },\n    calendar : {\n        sameDay : '[నేడు] LT',\n        nextDay : '[రేపు] LT',\n        nextWeek : 'dddd, LT',\n        lastDay : '[నిన్న] LT',\n        lastWeek : '[గత] dddd, LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : '%s లో',\n        past : '%s క్రితం',\n        s : 'కొన్ని క్షణాలు',\n        m : 'ఒక నిమిషం',\n        mm : '%d నిమిషాలు',\n        h : 'ఒక గంట',\n        hh : '%d గంటలు',\n        d : 'ఒక రోజు',\n        dd : '%d రోజులు',\n        M : 'ఒక నెల',\n        MM : '%d నెలలు',\n        y : 'ఒక సంవత్సరం',\n        yy : '%d సంవత్సరాలు'\n    },\n    dayOfMonthOrdinalParse : /\\d{1,2}వ/,\n    ordinal : '%dవ',\n    meridiemParse: /రాత్రి|ఉదయం|మధ్యాహ్నం|సాయంత్రం/,\n    meridiemHour : function (hour, meridiem) {\n        if (hour === 12) {\n            hour = 0;\n        }\n        if (meridiem === 'రాత్రి') {\n            return hour < 4 ? hour : hour + 12;\n        } else if (meridiem === 'ఉదయం') {\n            return hour;\n        } else if (meridiem === 'మధ్యాహ్నం') {\n            return hour >= 10 ? hour : hour + 12;\n        } else if (meridiem === 'సాయంత్రం') {\n            return hour + 12;\n        }\n    },\n    meridiem : function (hour, minute, isLower) {\n        if (hour < 4) {\n            return 'రాత్రి';\n        } else if (hour < 10) {\n            return 'ఉదయం';\n        } else if (hour < 17) {\n            return 'మధ్యాహ్నం';\n        } else if (hour < 20) {\n            return 'సాయంత్రం';\n        } else {\n            return 'రాత్రి';\n        }\n    },\n    week : {\n        dow : 0, // Sunday is the first day of the week.\n        doy : 6  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Tetun Dili (East Timor) [tet]\n//! author : Joshua Brooks : https://github.com/joshbrooks\n//! author : Onorio De J. Afonso : https://github.com/marobo\n\nmoment.defineLocale('tet', {\n    months : 'Janeiru_Fevereiru_Marsu_Abril_Maiu_Juniu_Juliu_Augustu_Setembru_Outubru_Novembru_Dezembru'.split('_'),\n    monthsShort : 'Jan_Fev_Mar_Abr_Mai_Jun_Jul_Aug_Set_Out_Nov_Dez'.split('_'),\n    weekdays : 'Domingu_Segunda_Tersa_Kuarta_Kinta_Sexta_Sabadu'.split('_'),\n    weekdaysShort : 'Dom_Seg_Ters_Kua_Kint_Sext_Sab'.split('_'),\n    weekdaysMin : 'Do_Seg_Te_Ku_Ki_Sex_Sa'.split('_'),\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY HH:mm',\n        LLLL : 'dddd, D MMMM YYYY HH:mm'\n    },\n    calendar : {\n        sameDay: '[Ohin iha] LT',\n        nextDay: '[Aban iha] LT',\n        nextWeek: 'dddd [iha] LT',\n        lastDay: '[Horiseik iha] LT',\n        lastWeek: 'dddd [semana kotuk] [iha] LT',\n        sameElse: 'L'\n    },\n    relativeTime : {\n        future : 'iha %s',\n        past : '%s liuba',\n        s : 'minutu balun',\n        m : 'minutu ida',\n        mm : 'minutus %d',\n        h : 'horas ida',\n        hh : 'horas %d',\n        d : 'loron ida',\n        dd : 'loron %d',\n        M : 'fulan ida',\n        MM : 'fulan %d',\n        y : 'tinan ida',\n        yy : 'tinan %d'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}(st|nd|rd|th)/,\n    ordinal : function (number) {\n        var b = number % 10,\n            output = (~~(number % 100 / 10) === 1) ? 'th' :\n            (b === 1) ? 'st' :\n            (b === 2) ? 'nd' :\n            (b === 3) ? 'rd' : 'th';\n        return number + output;\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Thai [th]\n//! author : Kridsada Thanabulpong : https://github.com/sirn\n\nmoment.defineLocale('th', {\n    months : 'มกราคม_กุมภาพันธ์_มีนาคม_เมษายน_พฤษภาคม_มิถุนายน_กรกฎาคม_สิงหาคม_กันยายน_ตุลาคม_พฤศจิกายน_ธันวาคม'.split('_'),\n    monthsShort : 'ม.ค._ก.พ._มี.ค._เม.ย._พ.ค._มิ.ย._ก.ค._ส.ค._ก.ย._ต.ค._พ.ย._ธ.ค.'.split('_'),\n    monthsParseExact: true,\n    weekdays : 'อาทิตย์_จันทร์_อังคาร_พุธ_พฤหัสบดี_ศุกร์_เสาร์'.split('_'),\n    weekdaysShort : 'อาทิตย์_จันทร์_อังคาร_พุธ_พฤหัส_ศุกร์_เสาร์'.split('_'), // yes, three characters difference\n    weekdaysMin : 'อา._จ._อ._พ._พฤ._ศ._ส.'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat : {\n        LT : 'H:mm',\n        LTS : 'H:mm:ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY เวลา H:mm',\n        LLLL : 'วันddddที่ D MMMM YYYY เวลา H:mm'\n    },\n    meridiemParse: /ก่อนเที่ยง|หลังเที่ยง/,\n    isPM: function (input) {\n        return input === 'หลังเที่ยง';\n    },\n    meridiem : function (hour, minute, isLower) {\n        if (hour < 12) {\n            return 'ก่อนเที่ยง';\n        } else {\n            return 'หลังเที่ยง';\n        }\n    },\n    calendar : {\n        sameDay : '[วันนี้ เวลา] LT',\n        nextDay : '[พรุ่งนี้ เวลา] LT',\n        nextWeek : 'dddd[หน้า เวลา] LT',\n        lastDay : '[เมื่อวานนี้ เวลา] LT',\n        lastWeek : '[วัน]dddd[ที่แล้ว เวลา] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'อีก %s',\n        past : '%sที่แล้ว',\n        s : 'ไม่กี่วินาที',\n        m : '1 นาที',\n        mm : '%d นาที',\n        h : '1 ชั่วโมง',\n        hh : '%d ชั่วโมง',\n        d : '1 วัน',\n        dd : '%d วัน',\n        M : '1 เดือน',\n        MM : '%d เดือน',\n        y : '1 ปี',\n        yy : '%d ปี'\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Tagalog (Philippines) [tl-ph]\n//! author : Dan Hagman : https://github.com/hagmandan\n\nmoment.defineLocale('tl-ph', {\n    months : 'Enero_Pebrero_Marso_Abril_Mayo_Hunyo_Hulyo_Agosto_Setyembre_Oktubre_Nobyembre_Disyembre'.split('_'),\n    monthsShort : 'Ene_Peb_Mar_Abr_May_Hun_Hul_Ago_Set_Okt_Nob_Dis'.split('_'),\n    weekdays : 'Linggo_Lunes_Martes_Miyerkules_Huwebes_Biyernes_Sabado'.split('_'),\n    weekdaysShort : 'Lin_Lun_Mar_Miy_Huw_Biy_Sab'.split('_'),\n    weekdaysMin : 'Li_Lu_Ma_Mi_Hu_Bi_Sab'.split('_'),\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'MM/D/YYYY',\n        LL : 'MMMM D, YYYY',\n        LLL : 'MMMM D, YYYY HH:mm',\n        LLLL : 'dddd, MMMM DD, YYYY HH:mm'\n    },\n    calendar : {\n        sameDay: 'LT [ngayong araw]',\n        nextDay: '[Bukas ng] LT',\n        nextWeek: 'LT [sa susunod na] dddd',\n        lastDay: 'LT [kahapon]',\n        lastWeek: 'LT [noong nakaraang] dddd',\n        sameElse: 'L'\n    },\n    relativeTime : {\n        future : 'sa loob ng %s',\n        past : '%s ang nakalipas',\n        s : 'ilang segundo',\n        m : 'isang minuto',\n        mm : '%d minuto',\n        h : 'isang oras',\n        hh : '%d oras',\n        d : 'isang araw',\n        dd : '%d araw',\n        M : 'isang buwan',\n        MM : '%d buwan',\n        y : 'isang taon',\n        yy : '%d taon'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}/,\n    ordinal : function (number) {\n        return number;\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Klingon [tlh]\n//! author : Dominika Kruk : https://github.com/amaranthrose\n\nvar numbersNouns = 'pagh_wa’_cha’_wej_loS_vagh_jav_Soch_chorgh_Hut'.split('_');\n\nfunction translateFuture(output) {\n    var time = output;\n    time = (output.indexOf('jaj') !== -1) ?\n    time.slice(0, -3) + 'leS' :\n    (output.indexOf('jar') !== -1) ?\n    time.slice(0, -3) + 'waQ' :\n    (output.indexOf('DIS') !== -1) ?\n    time.slice(0, -3) + 'nem' :\n    time + ' pIq';\n    return time;\n}\n\nfunction translatePast(output) {\n    var time = output;\n    time = (output.indexOf('jaj') !== -1) ?\n    time.slice(0, -3) + 'Hu’' :\n    (output.indexOf('jar') !== -1) ?\n    time.slice(0, -3) + 'wen' :\n    (output.indexOf('DIS') !== -1) ?\n    time.slice(0, -3) + 'ben' :\n    time + ' ret';\n    return time;\n}\n\nfunction translate$9(number, withoutSuffix, string, isFuture) {\n    var numberNoun = numberAsNoun(number);\n    switch (string) {\n        case 'mm':\n            return numberNoun + ' tup';\n        case 'hh':\n            return numberNoun + ' rep';\n        case 'dd':\n            return numberNoun + ' jaj';\n        case 'MM':\n            return numberNoun + ' jar';\n        case 'yy':\n            return numberNoun + ' DIS';\n    }\n}\n\nfunction numberAsNoun(number) {\n    var hundred = Math.floor((number % 1000) / 100),\n    ten = Math.floor((number % 100) / 10),\n    one = number % 10,\n    word = '';\n    if (hundred > 0) {\n        word += numbersNouns[hundred] + 'vatlh';\n    }\n    if (ten > 0) {\n        word += ((word !== '') ? ' ' : '') + numbersNouns[ten] + 'maH';\n    }\n    if (one > 0) {\n        word += ((word !== '') ? ' ' : '') + numbersNouns[one];\n    }\n    return (word === '') ? 'pagh' : word;\n}\n\nmoment.defineLocale('tlh', {\n    months : 'tera’ jar wa’_tera’ jar cha’_tera’ jar wej_tera’ jar loS_tera’ jar vagh_tera’ jar jav_tera’ jar Soch_tera’ jar chorgh_tera’ jar Hut_tera’ jar wa’maH_tera’ jar wa’maH wa’_tera’ jar wa’maH cha’'.split('_'),\n    monthsShort : 'jar wa’_jar cha’_jar wej_jar loS_jar vagh_jar jav_jar Soch_jar chorgh_jar Hut_jar wa’maH_jar wa’maH wa’_jar wa’maH cha’'.split('_'),\n    monthsParseExact : true,\n    weekdays : 'lojmItjaj_DaSjaj_povjaj_ghItlhjaj_loghjaj_buqjaj_ghInjaj'.split('_'),\n    weekdaysShort : 'lojmItjaj_DaSjaj_povjaj_ghItlhjaj_loghjaj_buqjaj_ghInjaj'.split('_'),\n    weekdaysMin : 'lojmItjaj_DaSjaj_povjaj_ghItlhjaj_loghjaj_buqjaj_ghInjaj'.split('_'),\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD.MM.YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY HH:mm',\n        LLLL : 'dddd, D MMMM YYYY HH:mm'\n    },\n    calendar : {\n        sameDay: '[DaHjaj] LT',\n        nextDay: '[wa’leS] LT',\n        nextWeek: 'LLL',\n        lastDay: '[wa’Hu’] LT',\n        lastWeek: 'LLL',\n        sameElse: 'L'\n    },\n    relativeTime : {\n        future : translateFuture,\n        past : translatePast,\n        s : 'puS lup',\n        m : 'wa’ tup',\n        mm : translate$9,\n        h : 'wa’ rep',\n        hh : translate$9,\n        d : 'wa’ jaj',\n        dd : translate$9,\n        M : 'wa’ jar',\n        MM : translate$9,\n        y : 'wa’ DIS',\n        yy : translate$9\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}\\./,\n    ordinal : '%d.',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Turkish [tr]\n//! authors : Erhan Gundogan : https://github.com/erhangundogan,\n//!           Burak Yiğit Kaya: https://github.com/BYK\n\nvar suffixes$3 = {\n    1: '\\'inci',\n    5: '\\'inci',\n    8: '\\'inci',\n    70: '\\'inci',\n    80: '\\'inci',\n    2: '\\'nci',\n    7: '\\'nci',\n    20: '\\'nci',\n    50: '\\'nci',\n    3: '\\'üncü',\n    4: '\\'üncü',\n    100: '\\'üncü',\n    6: '\\'ncı',\n    9: '\\'uncu',\n    10: '\\'uncu',\n    30: '\\'uncu',\n    60: '\\'ıncı',\n    90: '\\'ıncı'\n};\n\nmoment.defineLocale('tr', {\n    months : 'Ocak_Şubat_Mart_Nisan_Mayıs_Haziran_Temmuz_Ağustos_Eylül_Ekim_Kasım_Aralık'.split('_'),\n    monthsShort : 'Oca_Şub_Mar_Nis_May_Haz_Tem_Ağu_Eyl_Eki_Kas_Ara'.split('_'),\n    weekdays : 'Pazar_Pazartesi_Salı_Çarşamba_Perşembe_Cuma_Cumartesi'.split('_'),\n    weekdaysShort : 'Paz_Pts_Sal_Çar_Per_Cum_Cts'.split('_'),\n    weekdaysMin : 'Pz_Pt_Sa_Ça_Pe_Cu_Ct'.split('_'),\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD.MM.YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY HH:mm',\n        LLLL : 'dddd, D MMMM YYYY HH:mm'\n    },\n    calendar : {\n        sameDay : '[bugün saat] LT',\n        nextDay : '[yarın saat] LT',\n        nextWeek : '[haftaya] dddd [saat] LT',\n        lastDay : '[dün] LT',\n        lastWeek : '[geçen hafta] dddd [saat] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : '%s sonra',\n        past : '%s önce',\n        s : 'birkaç saniye',\n        m : 'bir dakika',\n        mm : '%d dakika',\n        h : 'bir saat',\n        hh : '%d saat',\n        d : 'bir gün',\n        dd : '%d gün',\n        M : 'bir ay',\n        MM : '%d ay',\n        y : 'bir yıl',\n        yy : '%d yıl'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}'(inci|nci|üncü|ncı|uncu|ıncı)/,\n    ordinal : function (number) {\n        if (number === 0) {  // special case for zero\n            return number + '\\'ıncı';\n        }\n        var a = number % 10,\n            b = number % 100 - a,\n            c = number >= 100 ? 100 : null;\n        return number + (suffixes$3[a] || suffixes$3[b] || suffixes$3[c]);\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 7  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Talossan [tzl]\n//! author : Robin van der Vliet : https://github.com/robin0van0der0v\n//! author : Iustì Canun\n\n// After the year there should be a slash and the amount of years since December 26, 1979 in Roman numerals.\n// This is currently too difficult (maybe even impossible) to add.\nmoment.defineLocale('tzl', {\n    months : 'Januar_Fevraglh_Març_Avrïu_Mai_Gün_Julia_Guscht_Setemvar_Listopäts_Noemvar_Zecemvar'.split('_'),\n    monthsShort : 'Jan_Fev_Mar_Avr_Mai_Gün_Jul_Gus_Set_Lis_Noe_Zec'.split('_'),\n    weekdays : 'Súladi_Lúneçi_Maitzi_Márcuri_Xhúadi_Viénerçi_Sáturi'.split('_'),\n    weekdaysShort : 'Súl_Lún_Mai_Már_Xhú_Vié_Sát'.split('_'),\n    weekdaysMin : 'Sú_Lú_Ma_Má_Xh_Vi_Sá'.split('_'),\n    longDateFormat : {\n        LT : 'HH.mm',\n        LTS : 'HH.mm.ss',\n        L : 'DD.MM.YYYY',\n        LL : 'D. MMMM [dallas] YYYY',\n        LLL : 'D. MMMM [dallas] YYYY HH.mm',\n        LLLL : 'dddd, [li] D. MMMM [dallas] YYYY HH.mm'\n    },\n    meridiemParse: /d\\'o|d\\'a/i,\n    isPM : function (input) {\n        return 'd\\'o' === input.toLowerCase();\n    },\n    meridiem : function (hours, minutes, isLower) {\n        if (hours > 11) {\n            return isLower ? 'd\\'o' : 'D\\'O';\n        } else {\n            return isLower ? 'd\\'a' : 'D\\'A';\n        }\n    },\n    calendar : {\n        sameDay : '[oxhi à] LT',\n        nextDay : '[demà à] LT',\n        nextWeek : 'dddd [à] LT',\n        lastDay : '[ieiri à] LT',\n        lastWeek : '[sür el] dddd [lasteu à] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'osprei %s',\n        past : 'ja%s',\n        s : processRelativeTime$7,\n        m : processRelativeTime$7,\n        mm : processRelativeTime$7,\n        h : processRelativeTime$7,\n        hh : processRelativeTime$7,\n        d : processRelativeTime$7,\n        dd : processRelativeTime$7,\n        M : processRelativeTime$7,\n        MM : processRelativeTime$7,\n        y : processRelativeTime$7,\n        yy : processRelativeTime$7\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}\\./,\n    ordinal : '%d.',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\nfunction processRelativeTime$7(number, withoutSuffix, key, isFuture) {\n    var format = {\n        's': ['viensas secunds', '\\'iensas secunds'],\n        'm': ['\\'n míut', '\\'iens míut'],\n        'mm': [number + ' míuts', '' + number + ' míuts'],\n        'h': ['\\'n þora', '\\'iensa þora'],\n        'hh': [number + ' þoras', '' + number + ' þoras'],\n        'd': ['\\'n ziua', '\\'iensa ziua'],\n        'dd': [number + ' ziuas', '' + number + ' ziuas'],\n        'M': ['\\'n mes', '\\'iens mes'],\n        'MM': [number + ' mesen', '' + number + ' mesen'],\n        'y': ['\\'n ar', '\\'iens ar'],\n        'yy': [number + ' ars', '' + number + ' ars']\n    };\n    return isFuture ? format[key][0] : (withoutSuffix ? format[key][0] : format[key][1]);\n}\n\n//! moment.js locale configuration\n//! locale : Central Atlas Tamazight Latin [tzm-latn]\n//! author : Abdel Said : https://github.com/abdelsaid\n\nmoment.defineLocale('tzm-latn', {\n    months : 'innayr_brˤayrˤ_marˤsˤ_ibrir_mayyw_ywnyw_ywlywz_ɣwšt_šwtanbir_ktˤwbrˤ_nwwanbir_dwjnbir'.split('_'),\n    monthsShort : 'innayr_brˤayrˤ_marˤsˤ_ibrir_mayyw_ywnyw_ywlywz_ɣwšt_šwtanbir_ktˤwbrˤ_nwwanbir_dwjnbir'.split('_'),\n    weekdays : 'asamas_aynas_asinas_akras_akwas_asimwas_asiḍyas'.split('_'),\n    weekdaysShort : 'asamas_aynas_asinas_akras_akwas_asimwas_asiḍyas'.split('_'),\n    weekdaysMin : 'asamas_aynas_asinas_akras_akwas_asimwas_asiḍyas'.split('_'),\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY HH:mm',\n        LLLL : 'dddd D MMMM YYYY HH:mm'\n    },\n    calendar : {\n        sameDay: '[asdkh g] LT',\n        nextDay: '[aska g] LT',\n        nextWeek: 'dddd [g] LT',\n        lastDay: '[assant g] LT',\n        lastWeek: 'dddd [g] LT',\n        sameElse: 'L'\n    },\n    relativeTime : {\n        future : 'dadkh s yan %s',\n        past : 'yan %s',\n        s : 'imik',\n        m : 'minuḍ',\n        mm : '%d minuḍ',\n        h : 'saɛa',\n        hh : '%d tassaɛin',\n        d : 'ass',\n        dd : '%d ossan',\n        M : 'ayowr',\n        MM : '%d iyyirn',\n        y : 'asgas',\n        yy : '%d isgasn'\n    },\n    week : {\n        dow : 6, // Saturday is the first day of the week.\n        doy : 12  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Central Atlas Tamazight [tzm]\n//! author : Abdel Said : https://github.com/abdelsaid\n\nmoment.defineLocale('tzm', {\n    months : 'ⵉⵏⵏⴰⵢⵔ_ⴱⵕⴰⵢⵕ_ⵎⴰⵕⵚ_ⵉⴱⵔⵉⵔ_ⵎⴰⵢⵢⵓ_ⵢⵓⵏⵢⵓ_ⵢⵓⵍⵢⵓⵣ_ⵖⵓⵛⵜ_ⵛⵓⵜⴰⵏⴱⵉⵔ_ⴽⵟⵓⴱⵕ_ⵏⵓⵡⴰⵏⴱⵉⵔ_ⴷⵓⵊⵏⴱⵉⵔ'.split('_'),\n    monthsShort : 'ⵉⵏⵏⴰⵢⵔ_ⴱⵕⴰⵢⵕ_ⵎⴰⵕⵚ_ⵉⴱⵔⵉⵔ_ⵎⴰⵢⵢⵓ_ⵢⵓⵏⵢⵓ_ⵢⵓⵍⵢⵓⵣ_ⵖⵓⵛⵜ_ⵛⵓⵜⴰⵏⴱⵉⵔ_ⴽⵟⵓⴱⵕ_ⵏⵓⵡⴰⵏⴱⵉⵔ_ⴷⵓⵊⵏⴱⵉⵔ'.split('_'),\n    weekdays : 'ⴰⵙⴰⵎⴰⵙ_ⴰⵢⵏⴰⵙ_ⴰⵙⵉⵏⴰⵙ_ⴰⴽⵔⴰⵙ_ⴰⴽⵡⴰⵙ_ⴰⵙⵉⵎⵡⴰⵙ_ⴰⵙⵉⴹⵢⴰⵙ'.split('_'),\n    weekdaysShort : 'ⴰⵙⴰⵎⴰⵙ_ⴰⵢⵏⴰⵙ_ⴰⵙⵉⵏⴰⵙ_ⴰⴽⵔⴰⵙ_ⴰⴽⵡⴰⵙ_ⴰⵙⵉⵎⵡⴰⵙ_ⴰⵙⵉⴹⵢⴰⵙ'.split('_'),\n    weekdaysMin : 'ⴰⵙⴰⵎⴰⵙ_ⴰⵢⵏⴰⵙ_ⴰⵙⵉⵏⴰⵙ_ⴰⴽⵔⴰⵙ_ⴰⴽⵡⴰⵙ_ⴰⵙⵉⵎⵡⴰⵙ_ⴰⵙⵉⴹⵢⴰⵙ'.split('_'),\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS: 'HH:mm:ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY HH:mm',\n        LLLL : 'dddd D MMMM YYYY HH:mm'\n    },\n    calendar : {\n        sameDay: '[ⴰⵙⴷⵅ ⴴ] LT',\n        nextDay: '[ⴰⵙⴽⴰ ⴴ] LT',\n        nextWeek: 'dddd [ⴴ] LT',\n        lastDay: '[ⴰⵚⴰⵏⵜ ⴴ] LT',\n        lastWeek: 'dddd [ⴴ] LT',\n        sameElse: 'L'\n    },\n    relativeTime : {\n        future : 'ⴷⴰⴷⵅ ⵙ ⵢⴰⵏ %s',\n        past : 'ⵢⴰⵏ %s',\n        s : 'ⵉⵎⵉⴽ',\n        m : 'ⵎⵉⵏⵓⴺ',\n        mm : '%d ⵎⵉⵏⵓⴺ',\n        h : 'ⵙⴰⵄⴰ',\n        hh : '%d ⵜⴰⵙⵙⴰⵄⵉⵏ',\n        d : 'ⴰⵙⵙ',\n        dd : '%d oⵙⵙⴰⵏ',\n        M : 'ⴰⵢoⵓⵔ',\n        MM : '%d ⵉⵢⵢⵉⵔⵏ',\n        y : 'ⴰⵙⴳⴰⵙ',\n        yy : '%d ⵉⵙⴳⴰⵙⵏ'\n    },\n    week : {\n        dow : 6, // Saturday is the first day of the week.\n        doy : 12  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Ukrainian [uk]\n//! author : zemlanin : https://github.com/zemlanin\n//! Author : Menelion Elensúle : https://github.com/Oire\n\nfunction plural$6(word, num) {\n    var forms = word.split('_');\n    return num % 10 === 1 && num % 100 !== 11 ? forms[0] : (num % 10 >= 2 && num % 10 <= 4 && (num % 100 < 10 || num % 100 >= 20) ? forms[1] : forms[2]);\n}\nfunction relativeTimeWithPlural$4(number, withoutSuffix, key) {\n    var format = {\n        'mm': withoutSuffix ? 'хвилина_хвилини_хвилин' : 'хвилину_хвилини_хвилин',\n        'hh': withoutSuffix ? 'година_години_годин' : 'годину_години_годин',\n        'dd': 'день_дні_днів',\n        'MM': 'місяць_місяці_місяців',\n        'yy': 'рік_роки_років'\n    };\n    if (key === 'm') {\n        return withoutSuffix ? 'хвилина' : 'хвилину';\n    }\n    else if (key === 'h') {\n        return withoutSuffix ? 'година' : 'годину';\n    }\n    else {\n        return number + ' ' + plural$6(format[key], +number);\n    }\n}\nfunction weekdaysCaseReplace(m, format) {\n    var weekdays = {\n        'nominative': 'неділя_понеділок_вівторок_середа_четвер_п’ятниця_субота'.split('_'),\n        'accusative': 'неділю_понеділок_вівторок_середу_четвер_п’ятницю_суботу'.split('_'),\n        'genitive': 'неділі_понеділка_вівторка_середи_четверга_п’ятниці_суботи'.split('_')\n    };\n\n    if (!m) {\n        return weekdays['nominative'];\n    }\n\n    var nounCase = (/(\\[[ВвУу]\\]) ?dddd/).test(format) ?\n        'accusative' :\n        ((/\\[?(?:минулої|наступної)? ?\\] ?dddd/).test(format) ?\n            'genitive' :\n            'nominative');\n    return weekdays[nounCase][m.day()];\n}\nfunction processHoursFunction(str) {\n    return function () {\n        return str + 'о' + (this.hours() === 11 ? 'б' : '') + '] LT';\n    };\n}\n\nmoment.defineLocale('uk', {\n    months : {\n        'format': 'січня_лютого_березня_квітня_травня_червня_липня_серпня_вересня_жовтня_листопада_грудня'.split('_'),\n        'standalone': 'січень_лютий_березень_квітень_травень_червень_липень_серпень_вересень_жовтень_листопад_грудень'.split('_')\n    },\n    monthsShort : 'січ_лют_бер_квіт_трав_черв_лип_серп_вер_жовт_лист_груд'.split('_'),\n    weekdays : weekdaysCaseReplace,\n    weekdaysShort : 'нд_пн_вт_ср_чт_пт_сб'.split('_'),\n    weekdaysMin : 'нд_пн_вт_ср_чт_пт_сб'.split('_'),\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD.MM.YYYY',\n        LL : 'D MMMM YYYY р.',\n        LLL : 'D MMMM YYYY р., HH:mm',\n        LLLL : 'dddd, D MMMM YYYY р., HH:mm'\n    },\n    calendar : {\n        sameDay: processHoursFunction('[Сьогодні '),\n        nextDay: processHoursFunction('[Завтра '),\n        lastDay: processHoursFunction('[Вчора '),\n        nextWeek: processHoursFunction('[У] dddd ['),\n        lastWeek: function () {\n            switch (this.day()) {\n                case 0:\n                case 3:\n                case 5:\n                case 6:\n                    return processHoursFunction('[Минулої] dddd [').call(this);\n                case 1:\n                case 2:\n                case 4:\n                    return processHoursFunction('[Минулого] dddd [').call(this);\n            }\n        },\n        sameElse: 'L'\n    },\n    relativeTime : {\n        future : 'за %s',\n        past : '%s тому',\n        s : 'декілька секунд',\n        m : relativeTimeWithPlural$4,\n        mm : relativeTimeWithPlural$4,\n        h : 'годину',\n        hh : relativeTimeWithPlural$4,\n        d : 'день',\n        dd : relativeTimeWithPlural$4,\n        M : 'місяць',\n        MM : relativeTimeWithPlural$4,\n        y : 'рік',\n        yy : relativeTimeWithPlural$4\n    },\n    // M. E.: those two are virtually unused but a user might want to implement them for his/her website for some reason\n    meridiemParse: /ночі|ранку|дня|вечора/,\n    isPM: function (input) {\n        return /^(дня|вечора)$/.test(input);\n    },\n    meridiem : function (hour, minute, isLower) {\n        if (hour < 4) {\n            return 'ночі';\n        } else if (hour < 12) {\n            return 'ранку';\n        } else if (hour < 17) {\n            return 'дня';\n        } else {\n            return 'вечора';\n        }\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}-(й|го)/,\n    ordinal: function (number, period) {\n        switch (period) {\n            case 'M':\n            case 'd':\n            case 'DDD':\n            case 'w':\n            case 'W':\n                return number + '-й';\n            case 'D':\n                return number + '-го';\n            default:\n                return number;\n        }\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 7  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Urdu [ur]\n//! author : Sawood Alam : https://github.com/ibnesayeed\n//! author : Zack : https://github.com/ZackVision\n\nvar months$7 = [\n    'جنوری',\n    'فروری',\n    'مارچ',\n    'اپریل',\n    'مئی',\n    'جون',\n    'جولائی',\n    'اگست',\n    'ستمبر',\n    'اکتوبر',\n    'نومبر',\n    'دسمبر'\n];\nvar days$1 = [\n    'اتوار',\n    'پیر',\n    'منگل',\n    'بدھ',\n    'جمعرات',\n    'جمعہ',\n    'ہفتہ'\n];\n\nmoment.defineLocale('ur', {\n    months : months$7,\n    monthsShort : months$7,\n    weekdays : days$1,\n    weekdaysShort : days$1,\n    weekdaysMin : days$1,\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY HH:mm',\n        LLLL : 'dddd، D MMMM YYYY HH:mm'\n    },\n    meridiemParse: /صبح|شام/,\n    isPM : function (input) {\n        return 'شام' === input;\n    },\n    meridiem : function (hour, minute, isLower) {\n        if (hour < 12) {\n            return 'صبح';\n        }\n        return 'شام';\n    },\n    calendar : {\n        sameDay : '[آج بوقت] LT',\n        nextDay : '[کل بوقت] LT',\n        nextWeek : 'dddd [بوقت] LT',\n        lastDay : '[گذشتہ روز بوقت] LT',\n        lastWeek : '[گذشتہ] dddd [بوقت] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : '%s بعد',\n        past : '%s قبل',\n        s : 'چند سیکنڈ',\n        m : 'ایک منٹ',\n        mm : '%d منٹ',\n        h : 'ایک گھنٹہ',\n        hh : '%d گھنٹے',\n        d : 'ایک دن',\n        dd : '%d دن',\n        M : 'ایک ماہ',\n        MM : '%d ماہ',\n        y : 'ایک سال',\n        yy : '%d سال'\n    },\n    preparse: function (string) {\n        return string.replace(/،/g, ',');\n    },\n    postformat: function (string) {\n        return string.replace(/,/g, '،');\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Uzbek Latin [uz-latn]\n//! author : Rasulbek Mirzayev : github.com/Rasulbeeek\n\nmoment.defineLocale('uz-latn', {\n    months : 'Yanvar_Fevral_Mart_Aprel_May_Iyun_Iyul_Avgust_Sentabr_Oktabr_Noyabr_Dekabr'.split('_'),\n    monthsShort : 'Yan_Fev_Mar_Apr_May_Iyun_Iyul_Avg_Sen_Okt_Noy_Dek'.split('_'),\n    weekdays : 'Yakshanba_Dushanba_Seshanba_Chorshanba_Payshanba_Juma_Shanba'.split('_'),\n    weekdaysShort : 'Yak_Dush_Sesh_Chor_Pay_Jum_Shan'.split('_'),\n    weekdaysMin : 'Ya_Du_Se_Cho_Pa_Ju_Sha'.split('_'),\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY HH:mm',\n        LLLL : 'D MMMM YYYY, dddd HH:mm'\n    },\n    calendar : {\n        sameDay : '[Bugun soat] LT [da]',\n        nextDay : '[Ertaga] LT [da]',\n        nextWeek : 'dddd [kuni soat] LT [da]',\n        lastDay : '[Kecha soat] LT [da]',\n        lastWeek : '[O\\'tgan] dddd [kuni soat] LT [da]',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'Yaqin %s ichida',\n        past : 'Bir necha %s oldin',\n        s : 'soniya',\n        m : 'bir daqiqa',\n        mm : '%d daqiqa',\n        h : 'bir soat',\n        hh : '%d soat',\n        d : 'bir kun',\n        dd : '%d kun',\n        M : 'bir oy',\n        MM : '%d oy',\n        y : 'bir yil',\n        yy : '%d yil'\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 7  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Uzbek [uz]\n//! author : Sardor Muminov : https://github.com/muminoff\n\nmoment.defineLocale('uz', {\n    months : 'январ_феврал_март_апрел_май_июн_июл_август_сентябр_октябр_ноябр_декабр'.split('_'),\n    monthsShort : 'янв_фев_мар_апр_май_июн_июл_авг_сен_окт_ноя_дек'.split('_'),\n    weekdays : 'Якшанба_Душанба_Сешанба_Чоршанба_Пайшанба_Жума_Шанба'.split('_'),\n    weekdaysShort : 'Якш_Душ_Сеш_Чор_Пай_Жум_Шан'.split('_'),\n    weekdaysMin : 'Як_Ду_Се_Чо_Па_Жу_Ша'.split('_'),\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY HH:mm',\n        LLLL : 'D MMMM YYYY, dddd HH:mm'\n    },\n    calendar : {\n        sameDay : '[Бугун соат] LT [да]',\n        nextDay : '[Эртага] LT [да]',\n        nextWeek : 'dddd [куни соат] LT [да]',\n        lastDay : '[Кеча соат] LT [да]',\n        lastWeek : '[Утган] dddd [куни соат] LT [да]',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'Якин %s ичида',\n        past : 'Бир неча %s олдин',\n        s : 'фурсат',\n        m : 'бир дакика',\n        mm : '%d дакика',\n        h : 'бир соат',\n        hh : '%d соат',\n        d : 'бир кун',\n        dd : '%d кун',\n        M : 'бир ой',\n        MM : '%d ой',\n        y : 'бир йил',\n        yy : '%d йил'\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 7  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Vietnamese [vi]\n//! author : Bang Nguyen : https://github.com/bangnk\n\nmoment.defineLocale('vi', {\n    months : 'tháng 1_tháng 2_tháng 3_tháng 4_tháng 5_tháng 6_tháng 7_tháng 8_tháng 9_tháng 10_tháng 11_tháng 12'.split('_'),\n    monthsShort : 'Th01_Th02_Th03_Th04_Th05_Th06_Th07_Th08_Th09_Th10_Th11_Th12'.split('_'),\n    monthsParseExact : true,\n    weekdays : 'chủ nhật_thứ hai_thứ ba_thứ tư_thứ năm_thứ sáu_thứ bảy'.split('_'),\n    weekdaysShort : 'CN_T2_T3_T4_T5_T6_T7'.split('_'),\n    weekdaysMin : 'CN_T2_T3_T4_T5_T6_T7'.split('_'),\n    weekdaysParseExact : true,\n    meridiemParse: /sa|ch/i,\n    isPM : function (input) {\n        return /^ch$/i.test(input);\n    },\n    meridiem : function (hours, minutes, isLower) {\n        if (hours < 12) {\n            return isLower ? 'sa' : 'SA';\n        } else {\n            return isLower ? 'ch' : 'CH';\n        }\n    },\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM [năm] YYYY',\n        LLL : 'D MMMM [năm] YYYY HH:mm',\n        LLLL : 'dddd, D MMMM [năm] YYYY HH:mm',\n        l : 'DD/M/YYYY',\n        ll : 'D MMM YYYY',\n        lll : 'D MMM YYYY HH:mm',\n        llll : 'ddd, D MMM YYYY HH:mm'\n    },\n    calendar : {\n        sameDay: '[Hôm nay lúc] LT',\n        nextDay: '[Ngày mai lúc] LT',\n        nextWeek: 'dddd [tuần tới lúc] LT',\n        lastDay: '[Hôm qua lúc] LT',\n        lastWeek: 'dddd [tuần rồi lúc] LT',\n        sameElse: 'L'\n    },\n    relativeTime : {\n        future : '%s tới',\n        past : '%s trước',\n        s : 'vài giây',\n        m : 'một phút',\n        mm : '%d phút',\n        h : 'một giờ',\n        hh : '%d giờ',\n        d : 'một ngày',\n        dd : '%d ngày',\n        M : 'một tháng',\n        MM : '%d tháng',\n        y : 'một năm',\n        yy : '%d năm'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}/,\n    ordinal : function (number) {\n        return number;\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Pseudo [x-pseudo]\n//! author : Andrew Hood : https://github.com/andrewhood125\n\nmoment.defineLocale('x-pseudo', {\n    months : 'J~áñúá~rý_F~ébrú~árý_~Márc~h_Áp~ríl_~Máý_~Júñé~_Júl~ý_Áú~gúst~_Sép~témb~ér_Ó~ctób~ér_Ñ~óvém~bér_~Décé~mbér'.split('_'),\n    monthsShort : 'J~áñ_~Féb_~Már_~Ápr_~Máý_~Júñ_~Júl_~Áúg_~Sép_~Óct_~Ñóv_~Déc'.split('_'),\n    monthsParseExact : true,\n    weekdays : 'S~úñdá~ý_Mó~ñdáý~_Túé~sdáý~_Wéd~ñésd~áý_T~húrs~dáý_~Fríd~áý_S~átúr~dáý'.split('_'),\n    weekdaysShort : 'S~úñ_~Móñ_~Túé_~Wéd_~Thú_~Frí_~Sát'.split('_'),\n    weekdaysMin : 'S~ú_Mó~_Tú_~Wé_T~h_Fr~_Sá'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat : {\n        LT : 'HH:mm',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY HH:mm',\n        LLLL : 'dddd, D MMMM YYYY HH:mm'\n    },\n    calendar : {\n        sameDay : '[T~ódá~ý át] LT',\n        nextDay : '[T~ómó~rró~w át] LT',\n        nextWeek : 'dddd [át] LT',\n        lastDay : '[Ý~ést~érdá~ý át] LT',\n        lastWeek : '[L~ást] dddd [át] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'í~ñ %s',\n        past : '%s á~gó',\n        s : 'á ~féw ~sécó~ñds',\n        m : 'á ~míñ~úté',\n        mm : '%d m~íñú~tés',\n        h : 'á~ñ hó~úr',\n        hh : '%d h~óúrs',\n        d : 'á ~dáý',\n        dd : '%d d~áýs',\n        M : 'á ~móñ~th',\n        MM : '%d m~óñt~hs',\n        y : 'á ~ýéár',\n        yy : '%d ý~éárs'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}(th|st|nd|rd)/,\n    ordinal : function (number) {\n        var b = number % 10,\n            output = (~~(number % 100 / 10) === 1) ? 'th' :\n            (b === 1) ? 'st' :\n            (b === 2) ? 'nd' :\n            (b === 3) ? 'rd' : 'th';\n        return number + output;\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Yoruba Nigeria [yo]\n//! author : Atolagbe Abisoye : https://github.com/andela-batolagbe\n\nmoment.defineLocale('yo', {\n    months : 'Sẹ́rẹ́_Èrèlè_Ẹrẹ̀nà_Ìgbé_Èbibi_Òkùdu_Agẹmo_Ògún_Owewe_Ọ̀wàrà_Bélú_Ọ̀pẹ̀̀'.split('_'),\n    monthsShort : 'Sẹ́r_Èrl_Ẹrn_Ìgb_Èbi_Òkù_Agẹ_Ògú_Owe_Ọ̀wà_Bél_Ọ̀pẹ̀̀'.split('_'),\n    weekdays : 'Àìkú_Ajé_Ìsẹ́gun_Ọjọ́rú_Ọjọ́bọ_Ẹtì_Àbámẹ́ta'.split('_'),\n    weekdaysShort : 'Àìk_Ajé_Ìsẹ́_Ọjr_Ọjb_Ẹtì_Àbá'.split('_'),\n    weekdaysMin : 'Àì_Aj_Ìs_Ọr_Ọb_Ẹt_Àb'.split('_'),\n    longDateFormat : {\n        LT : 'h:mm A',\n        LTS : 'h:mm:ss A',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY h:mm A',\n        LLLL : 'dddd, D MMMM YYYY h:mm A'\n    },\n    calendar : {\n        sameDay : '[Ònì ni] LT',\n        nextDay : '[Ọ̀la ni] LT',\n        nextWeek : 'dddd [Ọsẹ̀ tón\\'bọ] [ni] LT',\n        lastDay : '[Àna ni] LT',\n        lastWeek : 'dddd [Ọsẹ̀ tólọ́] [ni] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'ní %s',\n        past : '%s kọjá',\n        s : 'ìsẹjú aayá die',\n        m : 'ìsẹjú kan',\n        mm : 'ìsẹjú %d',\n        h : 'wákati kan',\n        hh : 'wákati %d',\n        d : 'ọjọ́ kan',\n        dd : 'ọjọ́ %d',\n        M : 'osù kan',\n        MM : 'osù %d',\n        y : 'ọdún kan',\n        yy : 'ọdún %d'\n    },\n    dayOfMonthOrdinalParse : /ọjọ́\\s\\d{1,2}/,\n    ordinal : 'ọjọ́ %d',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4 // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Chinese (China) [zh-cn]\n//! author : suupic : https://github.com/suupic\n//! author : Zeno Zeng : https://github.com/zenozeng\n\nmoment.defineLocale('zh-cn', {\n    months : '一月_二月_三月_四月_五月_六月_七月_八月_九月_十月_十一月_十二月'.split('_'),\n    monthsShort : '1月_2月_3月_4月_5月_6月_7月_8月_9月_10月_11月_12月'.split('_'),\n    weekdays : '星期日_星期一_星期二_星期三_星期四_星期五_星期六'.split('_'),\n    weekdaysShort : '周日_周一_周二_周三_周四_周五_周六'.split('_'),\n    weekdaysMin : '日_一_二_三_四_五_六'.split('_'),\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'YYYY年MMMD日',\n        LL : 'YYYY年MMMD日',\n        LLL : 'YYYY年MMMD日Ah点mm分',\n        LLLL : 'YYYY年MMMD日ddddAh点mm分',\n        l : 'YYYY年MMMD日',\n        ll : 'YYYY年MMMD日',\n        lll : 'YYYY年MMMD日 HH:mm',\n        llll : 'YYYY年MMMD日dddd HH:mm'\n    },\n    meridiemParse: /凌晨|早上|上午|中午|下午|晚上/,\n    meridiemHour: function (hour, meridiem) {\n        if (hour === 12) {\n            hour = 0;\n        }\n        if (meridiem === '凌晨' || meridiem === '早上' ||\n                meridiem === '上午') {\n            return hour;\n        } else if (meridiem === '下午' || meridiem === '晚上') {\n            return hour + 12;\n        } else {\n            // '中午'\n            return hour >= 11 ? hour : hour + 12;\n        }\n    },\n    meridiem : function (hour, minute, isLower) {\n        var hm = hour * 100 + minute;\n        if (hm < 600) {\n            return '凌晨';\n        } else if (hm < 900) {\n            return '早上';\n        } else if (hm < 1130) {\n            return '上午';\n        } else if (hm < 1230) {\n            return '中午';\n        } else if (hm < 1800) {\n            return '下午';\n        } else {\n            return '晚上';\n        }\n    },\n    calendar : {\n        sameDay : '[今天]LT',\n        nextDay : '[明天]LT',\n        nextWeek : '[下]ddddLT',\n        lastDay : '[昨天]LT',\n        lastWeek : '[上]ddddLT',\n        sameElse : 'L'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}(日|月|周)/,\n    ordinal : function (number, period) {\n        switch (period) {\n            case 'd':\n            case 'D':\n            case 'DDD':\n                return number + '日';\n            case 'M':\n                return number + '月';\n            case 'w':\n            case 'W':\n                return number + '周';\n            default:\n                return number;\n        }\n    },\n    relativeTime : {\n        future : '%s内',\n        past : '%s前',\n        s : '几秒',\n        m : '1 分钟',\n        mm : '%d 分钟',\n        h : '1 小时',\n        hh : '%d 小时',\n        d : '1 天',\n        dd : '%d 天',\n        M : '1 个月',\n        MM : '%d 个月',\n        y : '1 年',\n        yy : '%d 年'\n    },\n    week : {\n        // GB/T 7408-1994《数据元和交换格式·信息交换·日期和时间表示法》与ISO 8601:1988等效\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Chinese (Hong Kong) [zh-hk]\n//! author : Ben : https://github.com/ben-lin\n//! author : Chris Lam : https://github.com/hehachris\n//! author : Konstantin : https://github.com/skfd\n\nmoment.defineLocale('zh-hk', {\n    months : '一月_二月_三月_四月_五月_六月_七月_八月_九月_十月_十一月_十二月'.split('_'),\n    monthsShort : '1月_2月_3月_4月_5月_6月_7月_8月_9月_10月_11月_12月'.split('_'),\n    weekdays : '星期日_星期一_星期二_星期三_星期四_星期五_星期六'.split('_'),\n    weekdaysShort : '週日_週一_週二_週三_週四_週五_週六'.split('_'),\n    weekdaysMin : '日_一_二_三_四_五_六'.split('_'),\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'YYYY年MMMD日',\n        LL : 'YYYY年MMMD日',\n        LLL : 'YYYY年MMMD日 HH:mm',\n        LLLL : 'YYYY年MMMD日dddd HH:mm',\n        l : 'YYYY年MMMD日',\n        ll : 'YYYY年MMMD日',\n        lll : 'YYYY年MMMD日 HH:mm',\n        llll : 'YYYY年MMMD日dddd HH:mm'\n    },\n    meridiemParse: /凌晨|早上|上午|中午|下午|晚上/,\n    meridiemHour : function (hour, meridiem) {\n        if (hour === 12) {\n            hour = 0;\n        }\n        if (meridiem === '凌晨' || meridiem === '早上' || meridiem === '上午') {\n            return hour;\n        } else if (meridiem === '中午') {\n            return hour >= 11 ? hour : hour + 12;\n        } else if (meridiem === '下午' || meridiem === '晚上') {\n            return hour + 12;\n        }\n    },\n    meridiem : function (hour, minute, isLower) {\n        var hm = hour * 100 + minute;\n        if (hm < 600) {\n            return '凌晨';\n        } else if (hm < 900) {\n            return '早上';\n        } else if (hm < 1130) {\n            return '上午';\n        } else if (hm < 1230) {\n            return '中午';\n        } else if (hm < 1800) {\n            return '下午';\n        } else {\n            return '晚上';\n        }\n    },\n    calendar : {\n        sameDay : '[今天]LT',\n        nextDay : '[明天]LT',\n        nextWeek : '[下]ddddLT',\n        lastDay : '[昨天]LT',\n        lastWeek : '[上]ddddLT',\n        sameElse : 'L'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}(日|月|週)/,\n    ordinal : function (number, period) {\n        switch (period) {\n            case 'd' :\n            case 'D' :\n            case 'DDD' :\n                return number + '日';\n            case 'M' :\n                return number + '月';\n            case 'w' :\n            case 'W' :\n                return number + '週';\n            default :\n                return number;\n        }\n    },\n    relativeTime : {\n        future : '%s內',\n        past : '%s前',\n        s : '幾秒',\n        m : '1 分鐘',\n        mm : '%d 分鐘',\n        h : '1 小時',\n        hh : '%d 小時',\n        d : '1 天',\n        dd : '%d 天',\n        M : '1 個月',\n        MM : '%d 個月',\n        y : '1 年',\n        yy : '%d 年'\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Chinese (Taiwan) [zh-tw]\n//! author : Ben : https://github.com/ben-lin\n//! author : Chris Lam : https://github.com/hehachris\n\nmoment.defineLocale('zh-tw', {\n    months : '一月_二月_三月_四月_五月_六月_七月_八月_九月_十月_十一月_十二月'.split('_'),\n    monthsShort : '1月_2月_3月_4月_5月_6月_7月_8月_9月_10月_11月_12月'.split('_'),\n    weekdays : '星期日_星期一_星期二_星期三_星期四_星期五_星期六'.split('_'),\n    weekdaysShort : '週日_週一_週二_週三_週四_週五_週六'.split('_'),\n    weekdaysMin : '日_一_二_三_四_五_六'.split('_'),\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'YYYY年MMMD日',\n        LL : 'YYYY年MMMD日',\n        LLL : 'YYYY年MMMD日 HH:mm',\n        LLLL : 'YYYY年MMMD日dddd HH:mm',\n        l : 'YYYY年MMMD日',\n        ll : 'YYYY年MMMD日',\n        lll : 'YYYY年MMMD日 HH:mm',\n        llll : 'YYYY年MMMD日dddd HH:mm'\n    },\n    meridiemParse: /凌晨|早上|上午|中午|下午|晚上/,\n    meridiemHour : function (hour, meridiem) {\n        if (hour === 12) {\n            hour = 0;\n        }\n        if (meridiem === '凌晨' || meridiem === '早上' || meridiem === '上午') {\n            return hour;\n        } else if (meridiem === '中午') {\n            return hour >= 11 ? hour : hour + 12;\n        } else if (meridiem === '下午' || meridiem === '晚上') {\n            return hour + 12;\n        }\n    },\n    meridiem : function (hour, minute, isLower) {\n        var hm = hour * 100 + minute;\n        if (hm < 600) {\n            return '凌晨';\n        } else if (hm < 900) {\n            return '早上';\n        } else if (hm < 1130) {\n            return '上午';\n        } else if (hm < 1230) {\n            return '中午';\n        } else if (hm < 1800) {\n            return '下午';\n        } else {\n            return '晚上';\n        }\n    },\n    calendar : {\n        sameDay : '[今天]LT',\n        nextDay : '[明天]LT',\n        nextWeek : '[下]ddddLT',\n        lastDay : '[昨天]LT',\n        lastWeek : '[上]ddddLT',\n        sameElse : 'L'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}(日|月|週)/,\n    ordinal : function (number, period) {\n        switch (period) {\n            case 'd' :\n            case 'D' :\n            case 'DDD' :\n                return number + '日';\n            case 'M' :\n                return number + '月';\n            case 'w' :\n            case 'W' :\n                return number + '週';\n            default :\n                return number;\n        }\n    },\n    relativeTime : {\n        future : '%s內',\n        past : '%s前',\n        s : '幾秒',\n        m : '1 分鐘',\n        mm : '%d 分鐘',\n        h : '1 小時',\n        hh : '%d 小時',\n        d : '1 天',\n        dd : '%d 天',\n        M : '1 個月',\n        MM : '%d 個月',\n        y : '1 年',\n        yy : '%d 年'\n    }\n});\n\nmoment.locale('en');\n\nreturn moment;\n\n})));\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/min/moment-with-locales.js",
    "content": ";(function (global, factory) {\n    typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :\n    typeof define === 'function' && define.amd ? define(factory) :\n    global.moment = factory()\n}(this, (function () { 'use strict';\n\nvar hookCallback;\n\nfunction hooks () {\n    return hookCallback.apply(null, arguments);\n}\n\n// This is done to register the method called with moment()\n// without creating circular dependencies.\nfunction setHookCallback (callback) {\n    hookCallback = callback;\n}\n\nfunction isArray(input) {\n    return input instanceof Array || Object.prototype.toString.call(input) === '[object Array]';\n}\n\nfunction isObject(input) {\n    // IE8 will treat undefined and null as object if it wasn't for\n    // input != null\n    return input != null && Object.prototype.toString.call(input) === '[object Object]';\n}\n\nfunction isObjectEmpty(obj) {\n    var k;\n    for (k in obj) {\n        // even if its not own property I'd still call it non-empty\n        return false;\n    }\n    return true;\n}\n\nfunction isUndefined(input) {\n    return input === void 0;\n}\n\nfunction isNumber(input) {\n    return typeof input === 'number' || Object.prototype.toString.call(input) === '[object Number]';\n}\n\nfunction isDate(input) {\n    return input instanceof Date || Object.prototype.toString.call(input) === '[object Date]';\n}\n\nfunction map(arr, fn) {\n    var res = [], i;\n    for (i = 0; i < arr.length; ++i) {\n        res.push(fn(arr[i], i));\n    }\n    return res;\n}\n\nfunction hasOwnProp(a, b) {\n    return Object.prototype.hasOwnProperty.call(a, b);\n}\n\nfunction extend(a, b) {\n    for (var i in b) {\n        if (hasOwnProp(b, i)) {\n            a[i] = b[i];\n        }\n    }\n\n    if (hasOwnProp(b, 'toString')) {\n        a.toString = b.toString;\n    }\n\n    if (hasOwnProp(b, 'valueOf')) {\n        a.valueOf = b.valueOf;\n    }\n\n    return a;\n}\n\nfunction createUTC (input, format, locale, strict) {\n    return createLocalOrUTC(input, format, locale, strict, true).utc();\n}\n\nfunction defaultParsingFlags() {\n    // We need to deep clone this object.\n    return {\n        empty           : false,\n        unusedTokens    : [],\n        unusedInput     : [],\n        overflow        : -2,\n        charsLeftOver   : 0,\n        nullInput       : false,\n        invalidMonth    : null,\n        invalidFormat   : false,\n        userInvalidated : false,\n        iso             : false,\n        parsedDateParts : [],\n        meridiem        : null,\n        rfc2822         : false,\n        weekdayMismatch : false\n    };\n}\n\nfunction getParsingFlags(m) {\n    if (m._pf == null) {\n        m._pf = defaultParsingFlags();\n    }\n    return m._pf;\n}\n\nvar some;\nif (Array.prototype.some) {\n    some = Array.prototype.some;\n} else {\n    some = function (fun) {\n        var t = Object(this);\n        var len = t.length >>> 0;\n\n        for (var i = 0; i < len; i++) {\n            if (i in t && fun.call(this, t[i], i, t)) {\n                return true;\n            }\n        }\n\n        return false;\n    };\n}\n\nvar some$1 = some;\n\nfunction isValid(m) {\n    if (m._isValid == null) {\n        var flags = getParsingFlags(m);\n        var parsedParts = some$1.call(flags.parsedDateParts, function (i) {\n            return i != null;\n        });\n        var isNowValid = !isNaN(m._d.getTime()) &&\n            flags.overflow < 0 &&\n            !flags.empty &&\n            !flags.invalidMonth &&\n            !flags.invalidWeekday &&\n            !flags.nullInput &&\n            !flags.invalidFormat &&\n            !flags.userInvalidated &&\n            (!flags.meridiem || (flags.meridiem && parsedParts));\n\n        if (m._strict) {\n            isNowValid = isNowValid &&\n                flags.charsLeftOver === 0 &&\n                flags.unusedTokens.length === 0 &&\n                flags.bigHour === undefined;\n        }\n\n        if (Object.isFrozen == null || !Object.isFrozen(m)) {\n            m._isValid = isNowValid;\n        }\n        else {\n            return isNowValid;\n        }\n    }\n    return m._isValid;\n}\n\nfunction createInvalid (flags) {\n    var m = createUTC(NaN);\n    if (flags != null) {\n        extend(getParsingFlags(m), flags);\n    }\n    else {\n        getParsingFlags(m).userInvalidated = true;\n    }\n\n    return m;\n}\n\n// Plugins that add properties should also add the key here (null value),\n// so we can properly clone ourselves.\nvar momentProperties = hooks.momentProperties = [];\n\nfunction copyConfig(to, from) {\n    var i, prop, val;\n\n    if (!isUndefined(from._isAMomentObject)) {\n        to._isAMomentObject = from._isAMomentObject;\n    }\n    if (!isUndefined(from._i)) {\n        to._i = from._i;\n    }\n    if (!isUndefined(from._f)) {\n        to._f = from._f;\n    }\n    if (!isUndefined(from._l)) {\n        to._l = from._l;\n    }\n    if (!isUndefined(from._strict)) {\n        to._strict = from._strict;\n    }\n    if (!isUndefined(from._tzm)) {\n        to._tzm = from._tzm;\n    }\n    if (!isUndefined(from._isUTC)) {\n        to._isUTC = from._isUTC;\n    }\n    if (!isUndefined(from._offset)) {\n        to._offset = from._offset;\n    }\n    if (!isUndefined(from._pf)) {\n        to._pf = getParsingFlags(from);\n    }\n    if (!isUndefined(from._locale)) {\n        to._locale = from._locale;\n    }\n\n    if (momentProperties.length > 0) {\n        for (i = 0; i < momentProperties.length; i++) {\n            prop = momentProperties[i];\n            val = from[prop];\n            if (!isUndefined(val)) {\n                to[prop] = val;\n            }\n        }\n    }\n\n    return to;\n}\n\nvar updateInProgress = false;\n\n// Moment prototype object\nfunction Moment(config) {\n    copyConfig(this, config);\n    this._d = new Date(config._d != null ? config._d.getTime() : NaN);\n    if (!this.isValid()) {\n        this._d = new Date(NaN);\n    }\n    // Prevent infinite loop in case updateOffset creates new moment\n    // objects.\n    if (updateInProgress === false) {\n        updateInProgress = true;\n        hooks.updateOffset(this);\n        updateInProgress = false;\n    }\n}\n\nfunction isMoment (obj) {\n    return obj instanceof Moment || (obj != null && obj._isAMomentObject != null);\n}\n\nfunction absFloor (number) {\n    if (number < 0) {\n        // -0 -> 0\n        return Math.ceil(number) || 0;\n    } else {\n        return Math.floor(number);\n    }\n}\n\nfunction toInt(argumentForCoercion) {\n    var coercedNumber = +argumentForCoercion,\n        value = 0;\n\n    if (coercedNumber !== 0 && isFinite(coercedNumber)) {\n        value = absFloor(coercedNumber);\n    }\n\n    return value;\n}\n\n// compare two arrays, return the number of differences\nfunction compareArrays(array1, array2, dontConvert) {\n    var len = Math.min(array1.length, array2.length),\n        lengthDiff = Math.abs(array1.length - array2.length),\n        diffs = 0,\n        i;\n    for (i = 0; i < len; i++) {\n        if ((dontConvert && array1[i] !== array2[i]) ||\n            (!dontConvert && toInt(array1[i]) !== toInt(array2[i]))) {\n            diffs++;\n        }\n    }\n    return diffs + lengthDiff;\n}\n\nfunction warn(msg) {\n    if (hooks.suppressDeprecationWarnings === false &&\n            (typeof console !==  'undefined') && console.warn) {\n        console.warn('Deprecation warning: ' + msg);\n    }\n}\n\nfunction deprecate(msg, fn) {\n    var firstTime = true;\n\n    return extend(function () {\n        if (hooks.deprecationHandler != null) {\n            hooks.deprecationHandler(null, msg);\n        }\n        if (firstTime) {\n            var args = [];\n            var arg;\n            for (var i = 0; i < arguments.length; i++) {\n                arg = '';\n                if (typeof arguments[i] === 'object') {\n                    arg += '\\n[' + i + '] ';\n                    for (var key in arguments[0]) {\n                        arg += key + ': ' + arguments[0][key] + ', ';\n                    }\n                    arg = arg.slice(0, -2); // Remove trailing comma and space\n                } else {\n                    arg = arguments[i];\n                }\n                args.push(arg);\n            }\n            warn(msg + '\\nArguments: ' + Array.prototype.slice.call(args).join('') + '\\n' + (new Error()).stack);\n            firstTime = false;\n        }\n        return fn.apply(this, arguments);\n    }, fn);\n}\n\nvar deprecations = {};\n\nfunction deprecateSimple(name, msg) {\n    if (hooks.deprecationHandler != null) {\n        hooks.deprecationHandler(name, msg);\n    }\n    if (!deprecations[name]) {\n        warn(msg);\n        deprecations[name] = true;\n    }\n}\n\nhooks.suppressDeprecationWarnings = false;\nhooks.deprecationHandler = null;\n\nfunction isFunction(input) {\n    return input instanceof Function || Object.prototype.toString.call(input) === '[object Function]';\n}\n\nfunction set (config) {\n    var prop, i;\n    for (i in config) {\n        prop = config[i];\n        if (isFunction(prop)) {\n            this[i] = prop;\n        } else {\n            this['_' + i] = prop;\n        }\n    }\n    this._config = config;\n    // Lenient ordinal parsing accepts just a number in addition to\n    // number + (possibly) stuff coming from _dayOfMonthOrdinalParse.\n    // TODO: Remove \"ordinalParse\" fallback in next major release.\n    this._dayOfMonthOrdinalParseLenient = new RegExp(\n        (this._dayOfMonthOrdinalParse.source || this._ordinalParse.source) +\n            '|' + (/\\d{1,2}/).source);\n}\n\nfunction mergeConfigs(parentConfig, childConfig) {\n    var res = extend({}, parentConfig), prop;\n    for (prop in childConfig) {\n        if (hasOwnProp(childConfig, prop)) {\n            if (isObject(parentConfig[prop]) && isObject(childConfig[prop])) {\n                res[prop] = {};\n                extend(res[prop], parentConfig[prop]);\n                extend(res[prop], childConfig[prop]);\n            } else if (childConfig[prop] != null) {\n                res[prop] = childConfig[prop];\n            } else {\n                delete res[prop];\n            }\n        }\n    }\n    for (prop in parentConfig) {\n        if (hasOwnProp(parentConfig, prop) &&\n                !hasOwnProp(childConfig, prop) &&\n                isObject(parentConfig[prop])) {\n            // make sure changes to properties don't modify parent config\n            res[prop] = extend({}, res[prop]);\n        }\n    }\n    return res;\n}\n\nfunction Locale(config) {\n    if (config != null) {\n        this.set(config);\n    }\n}\n\nvar keys;\n\nif (Object.keys) {\n    keys = Object.keys;\n} else {\n    keys = function (obj) {\n        var i, res = [];\n        for (i in obj) {\n            if (hasOwnProp(obj, i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    };\n}\n\nvar keys$1 = keys;\n\nvar defaultCalendar = {\n    sameDay : '[Today at] LT',\n    nextDay : '[Tomorrow at] LT',\n    nextWeek : 'dddd [at] LT',\n    lastDay : '[Yesterday at] LT',\n    lastWeek : '[Last] dddd [at] LT',\n    sameElse : 'L'\n};\n\nfunction calendar (key, mom, now) {\n    var output = this._calendar[key] || this._calendar['sameElse'];\n    return isFunction(output) ? output.call(mom, now) : output;\n}\n\nvar defaultLongDateFormat = {\n    LTS  : 'h:mm:ss A',\n    LT   : 'h:mm A',\n    L    : 'MM/DD/YYYY',\n    LL   : 'MMMM D, YYYY',\n    LLL  : 'MMMM D, YYYY h:mm A',\n    LLLL : 'dddd, MMMM D, YYYY h:mm A'\n};\n\nfunction longDateFormat (key) {\n    var format = this._longDateFormat[key],\n        formatUpper = this._longDateFormat[key.toUpperCase()];\n\n    if (format || !formatUpper) {\n        return format;\n    }\n\n    this._longDateFormat[key] = formatUpper.replace(/MMMM|MM|DD|dddd/g, function (val) {\n        return val.slice(1);\n    });\n\n    return this._longDateFormat[key];\n}\n\nvar defaultInvalidDate = 'Invalid date';\n\nfunction invalidDate () {\n    return this._invalidDate;\n}\n\nvar defaultOrdinal = '%d';\nvar defaultDayOfMonthOrdinalParse = /\\d{1,2}/;\n\nfunction ordinal (number) {\n    return this._ordinal.replace('%d', number);\n}\n\nvar defaultRelativeTime = {\n    future : 'in %s',\n    past   : '%s ago',\n    s  : 'a few seconds',\n    ss : '%d seconds',\n    m  : 'a minute',\n    mm : '%d minutes',\n    h  : 'an hour',\n    hh : '%d hours',\n    d  : 'a day',\n    dd : '%d days',\n    M  : 'a month',\n    MM : '%d months',\n    y  : 'a year',\n    yy : '%d years'\n};\n\nfunction relativeTime (number, withoutSuffix, string, isFuture) {\n    var output = this._relativeTime[string];\n    return (isFunction(output)) ?\n        output(number, withoutSuffix, string, isFuture) :\n        output.replace(/%d/i, number);\n}\n\nfunction pastFuture (diff, output) {\n    var format = this._relativeTime[diff > 0 ? 'future' : 'past'];\n    return isFunction(format) ? format(output) : format.replace(/%s/i, output);\n}\n\nvar aliases = {};\n\nfunction addUnitAlias (unit, shorthand) {\n    var lowerCase = unit.toLowerCase();\n    aliases[lowerCase] = aliases[lowerCase + 's'] = aliases[shorthand] = unit;\n}\n\nfunction normalizeUnits(units) {\n    return typeof units === 'string' ? aliases[units] || aliases[units.toLowerCase()] : undefined;\n}\n\nfunction normalizeObjectUnits(inputObject) {\n    var normalizedInput = {},\n        normalizedProp,\n        prop;\n\n    for (prop in inputObject) {\n        if (hasOwnProp(inputObject, prop)) {\n            normalizedProp = normalizeUnits(prop);\n            if (normalizedProp) {\n                normalizedInput[normalizedProp] = inputObject[prop];\n            }\n        }\n    }\n\n    return normalizedInput;\n}\n\nvar priorities = {};\n\nfunction addUnitPriority(unit, priority) {\n    priorities[unit] = priority;\n}\n\nfunction getPrioritizedUnits(unitsObj) {\n    var units = [];\n    for (var u in unitsObj) {\n        units.push({unit: u, priority: priorities[u]});\n    }\n    units.sort(function (a, b) {\n        return a.priority - b.priority;\n    });\n    return units;\n}\n\nfunction makeGetSet (unit, keepTime) {\n    return function (value) {\n        if (value != null) {\n            set$1(this, unit, value);\n            hooks.updateOffset(this, keepTime);\n            return this;\n        } else {\n            return get(this, unit);\n        }\n    };\n}\n\nfunction get (mom, unit) {\n    return mom.isValid() ?\n        mom._d['get' + (mom._isUTC ? 'UTC' : '') + unit]() : NaN;\n}\n\nfunction set$1 (mom, unit, value) {\n    if (mom.isValid()) {\n        mom._d['set' + (mom._isUTC ? 'UTC' : '') + unit](value);\n    }\n}\n\n// MOMENTS\n\nfunction stringGet (units) {\n    units = normalizeUnits(units);\n    if (isFunction(this[units])) {\n        return this[units]();\n    }\n    return this;\n}\n\n\nfunction stringSet (units, value) {\n    if (typeof units === 'object') {\n        units = normalizeObjectUnits(units);\n        var prioritized = getPrioritizedUnits(units);\n        for (var i = 0; i < prioritized.length; i++) {\n            this[prioritized[i].unit](units[prioritized[i].unit]);\n        }\n    } else {\n        units = normalizeUnits(units);\n        if (isFunction(this[units])) {\n            return this[units](value);\n        }\n    }\n    return this;\n}\n\nfunction zeroFill(number, targetLength, forceSign) {\n    var absNumber = '' + Math.abs(number),\n        zerosToFill = targetLength - absNumber.length,\n        sign = number >= 0;\n    return (sign ? (forceSign ? '+' : '') : '-') +\n        Math.pow(10, Math.max(0, zerosToFill)).toString().substr(1) + absNumber;\n}\n\nvar formattingTokens = /(\\[[^\\[]*\\])|(\\\\)?([Hh]mm(ss)?|Mo|MM?M?M?|Do|DDDo|DD?D?D?|ddd?d?|do?|w[o|w]?|W[o|W]?|Qo?|YYYYYY|YYYYY|YYYY|YY|gg(ggg?)?|GG(GGG?)?|e|E|a|A|hh?|HH?|kk?|mm?|ss?|S{1,9}|x|X|zz?|ZZ?|.)/g;\n\nvar localFormattingTokens = /(\\[[^\\[]*\\])|(\\\\)?(LTS|LT|LL?L?L?|l{1,4})/g;\n\nvar formatFunctions = {};\n\nvar formatTokenFunctions = {};\n\n// token:    'M'\n// padded:   ['MM', 2]\n// ordinal:  'Mo'\n// callback: function () { this.month() + 1 }\nfunction addFormatToken (token, padded, ordinal, callback) {\n    var func = callback;\n    if (typeof callback === 'string') {\n        func = function () {\n            return this[callback]();\n        };\n    }\n    if (token) {\n        formatTokenFunctions[token] = func;\n    }\n    if (padded) {\n        formatTokenFunctions[padded[0]] = function () {\n            return zeroFill(func.apply(this, arguments), padded[1], padded[2]);\n        };\n    }\n    if (ordinal) {\n        formatTokenFunctions[ordinal] = function () {\n            return this.localeData().ordinal(func.apply(this, arguments), token);\n        };\n    }\n}\n\nfunction removeFormattingTokens(input) {\n    if (input.match(/\\[[\\s\\S]/)) {\n        return input.replace(/^\\[|\\]$/g, '');\n    }\n    return input.replace(/\\\\/g, '');\n}\n\nfunction makeFormatFunction(format) {\n    var array = format.match(formattingTokens), i, length;\n\n    for (i = 0, length = array.length; i < length; i++) {\n        if (formatTokenFunctions[array[i]]) {\n            array[i] = formatTokenFunctions[array[i]];\n        } else {\n            array[i] = removeFormattingTokens(array[i]);\n        }\n    }\n\n    return function (mom) {\n        var output = '', i;\n        for (i = 0; i < length; i++) {\n            output += isFunction(array[i]) ? array[i].call(mom, format) : array[i];\n        }\n        return output;\n    };\n}\n\n// format date using native date object\nfunction formatMoment(m, format) {\n    if (!m.isValid()) {\n        return m.localeData().invalidDate();\n    }\n\n    format = expandFormat(format, m.localeData());\n    formatFunctions[format] = formatFunctions[format] || makeFormatFunction(format);\n\n    return formatFunctions[format](m);\n}\n\nfunction expandFormat(format, locale) {\n    var i = 5;\n\n    function replaceLongDateFormatTokens(input) {\n        return locale.longDateFormat(input) || input;\n    }\n\n    localFormattingTokens.lastIndex = 0;\n    while (i >= 0 && localFormattingTokens.test(format)) {\n        format = format.replace(localFormattingTokens, replaceLongDateFormatTokens);\n        localFormattingTokens.lastIndex = 0;\n        i -= 1;\n    }\n\n    return format;\n}\n\nvar match1         = /\\d/;            //       0 - 9\nvar match2         = /\\d\\d/;          //      00 - 99\nvar match3         = /\\d{3}/;         //     000 - 999\nvar match4         = /\\d{4}/;         //    0000 - 9999\nvar match6         = /[+-]?\\d{6}/;    // -999999 - 999999\nvar match1to2      = /\\d\\d?/;         //       0 - 99\nvar match3to4      = /\\d\\d\\d\\d?/;     //     999 - 9999\nvar match5to6      = /\\d\\d\\d\\d\\d\\d?/; //   99999 - 999999\nvar match1to3      = /\\d{1,3}/;       //       0 - 999\nvar match1to4      = /\\d{1,4}/;       //       0 - 9999\nvar match1to6      = /[+-]?\\d{1,6}/;  // -999999 - 999999\n\nvar matchUnsigned  = /\\d+/;           //       0 - inf\nvar matchSigned    = /[+-]?\\d+/;      //    -inf - inf\n\nvar matchOffset    = /Z|[+-]\\d\\d:?\\d\\d/gi; // +00:00 -00:00 +0000 -0000 or Z\nvar matchShortOffset = /Z|[+-]\\d\\d(?::?\\d\\d)?/gi; // +00 -00 +00:00 -00:00 +0000 -0000 or Z\n\nvar matchTimestamp = /[+-]?\\d+(\\.\\d{1,3})?/; // 123456789 123456789.123\n\n// any word (or two) characters or numbers including two/three word month in arabic.\n// includes scottish gaelic two word and hyphenated months\nvar matchWord = /[0-9]*['a-z\\u00A0-\\u05FF\\u0700-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF]+|[\\u0600-\\u06FF\\/]+(\\s*?[\\u0600-\\u06FF]+){1,2}/i;\n\n\nvar regexes = {};\n\nfunction addRegexToken (token, regex, strictRegex) {\n    regexes[token] = isFunction(regex) ? regex : function (isStrict, localeData) {\n        return (isStrict && strictRegex) ? strictRegex : regex;\n    };\n}\n\nfunction getParseRegexForToken (token, config) {\n    if (!hasOwnProp(regexes, token)) {\n        return new RegExp(unescapeFormat(token));\n    }\n\n    return regexes[token](config._strict, config._locale);\n}\n\n// Code from http://stackoverflow.com/questions/3561493/is-there-a-regexp-escape-function-in-javascript\nfunction unescapeFormat(s) {\n    return regexEscape(s.replace('\\\\', '').replace(/\\\\(\\[)|\\\\(\\])|\\[([^\\]\\[]*)\\]|\\\\(.)/g, function (matched, p1, p2, p3, p4) {\n        return p1 || p2 || p3 || p4;\n    }));\n}\n\nfunction regexEscape(s) {\n    return s.replace(/[-\\/\\\\^$*+?.()|[\\]{}]/g, '\\\\$&');\n}\n\nvar tokens = {};\n\nfunction addParseToken (token, callback) {\n    var i, func = callback;\n    if (typeof token === 'string') {\n        token = [token];\n    }\n    if (isNumber(callback)) {\n        func = function (input, array) {\n            array[callback] = toInt(input);\n        };\n    }\n    for (i = 0; i < token.length; i++) {\n        tokens[token[i]] = func;\n    }\n}\n\nfunction addWeekParseToken (token, callback) {\n    addParseToken(token, function (input, array, config, token) {\n        config._w = config._w || {};\n        callback(input, config._w, config, token);\n    });\n}\n\nfunction addTimeToArrayFromToken(token, input, config) {\n    if (input != null && hasOwnProp(tokens, token)) {\n        tokens[token](input, config._a, config, token);\n    }\n}\n\nvar YEAR = 0;\nvar MONTH = 1;\nvar DATE = 2;\nvar HOUR = 3;\nvar MINUTE = 4;\nvar SECOND = 5;\nvar MILLISECOND = 6;\nvar WEEK = 7;\nvar WEEKDAY = 8;\n\nvar indexOf;\n\nif (Array.prototype.indexOf) {\n    indexOf = Array.prototype.indexOf;\n} else {\n    indexOf = function (o) {\n        // I know\n        var i;\n        for (i = 0; i < this.length; ++i) {\n            if (this[i] === o) {\n                return i;\n            }\n        }\n        return -1;\n    };\n}\n\nvar indexOf$1 = indexOf;\n\nfunction daysInMonth(year, month) {\n    return new Date(Date.UTC(year, month + 1, 0)).getUTCDate();\n}\n\n// FORMATTING\n\naddFormatToken('M', ['MM', 2], 'Mo', function () {\n    return this.month() + 1;\n});\n\naddFormatToken('MMM', 0, 0, function (format) {\n    return this.localeData().monthsShort(this, format);\n});\n\naddFormatToken('MMMM', 0, 0, function (format) {\n    return this.localeData().months(this, format);\n});\n\n// ALIASES\n\naddUnitAlias('month', 'M');\n\n// PRIORITY\n\naddUnitPriority('month', 8);\n\n// PARSING\n\naddRegexToken('M',    match1to2);\naddRegexToken('MM',   match1to2, match2);\naddRegexToken('MMM',  function (isStrict, locale) {\n    return locale.monthsShortRegex(isStrict);\n});\naddRegexToken('MMMM', function (isStrict, locale) {\n    return locale.monthsRegex(isStrict);\n});\n\naddParseToken(['M', 'MM'], function (input, array) {\n    array[MONTH] = toInt(input) - 1;\n});\n\naddParseToken(['MMM', 'MMMM'], function (input, array, config, token) {\n    var month = config._locale.monthsParse(input, token, config._strict);\n    // if we didn't find a month name, mark the date as invalid.\n    if (month != null) {\n        array[MONTH] = month;\n    } else {\n        getParsingFlags(config).invalidMonth = input;\n    }\n});\n\n// LOCALES\n\nvar MONTHS_IN_FORMAT = /D[oD]?(\\[[^\\[\\]]*\\]|\\s)+MMMM?/;\nvar defaultLocaleMonths = 'January_February_March_April_May_June_July_August_September_October_November_December'.split('_');\nfunction localeMonths (m, format) {\n    if (!m) {\n        return isArray(this._months) ? this._months :\n            this._months['standalone'];\n    }\n    return isArray(this._months) ? this._months[m.month()] :\n        this._months[(this._months.isFormat || MONTHS_IN_FORMAT).test(format) ? 'format' : 'standalone'][m.month()];\n}\n\nvar defaultLocaleMonthsShort = 'Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec'.split('_');\nfunction localeMonthsShort (m, format) {\n    if (!m) {\n        return isArray(this._monthsShort) ? this._monthsShort :\n            this._monthsShort['standalone'];\n    }\n    return isArray(this._monthsShort) ? this._monthsShort[m.month()] :\n        this._monthsShort[MONTHS_IN_FORMAT.test(format) ? 'format' : 'standalone'][m.month()];\n}\n\nfunction handleStrictParse(monthName, format, strict) {\n    var i, ii, mom, llc = monthName.toLocaleLowerCase();\n    if (!this._monthsParse) {\n        // this is not used\n        this._monthsParse = [];\n        this._longMonthsParse = [];\n        this._shortMonthsParse = [];\n        for (i = 0; i < 12; ++i) {\n            mom = createUTC([2000, i]);\n            this._shortMonthsParse[i] = this.monthsShort(mom, '').toLocaleLowerCase();\n            this._longMonthsParse[i] = this.months(mom, '').toLocaleLowerCase();\n        }\n    }\n\n    if (strict) {\n        if (format === 'MMM') {\n            ii = indexOf$1.call(this._shortMonthsParse, llc);\n            return ii !== -1 ? ii : null;\n        } else {\n            ii = indexOf$1.call(this._longMonthsParse, llc);\n            return ii !== -1 ? ii : null;\n        }\n    } else {\n        if (format === 'MMM') {\n            ii = indexOf$1.call(this._shortMonthsParse, llc);\n            if (ii !== -1) {\n                return ii;\n            }\n            ii = indexOf$1.call(this._longMonthsParse, llc);\n            return ii !== -1 ? ii : null;\n        } else {\n            ii = indexOf$1.call(this._longMonthsParse, llc);\n            if (ii !== -1) {\n                return ii;\n            }\n            ii = indexOf$1.call(this._shortMonthsParse, llc);\n            return ii !== -1 ? ii : null;\n        }\n    }\n}\n\nfunction localeMonthsParse (monthName, format, strict) {\n    var i, mom, regex;\n\n    if (this._monthsParseExact) {\n        return handleStrictParse.call(this, monthName, format, strict);\n    }\n\n    if (!this._monthsParse) {\n        this._monthsParse = [];\n        this._longMonthsParse = [];\n        this._shortMonthsParse = [];\n    }\n\n    // TODO: add sorting\n    // Sorting makes sure if one month (or abbr) is a prefix of another\n    // see sorting in computeMonthsParse\n    for (i = 0; i < 12; i++) {\n        // make the regex if we don't have it already\n        mom = createUTC([2000, i]);\n        if (strict && !this._longMonthsParse[i]) {\n            this._longMonthsParse[i] = new RegExp('^' + this.months(mom, '').replace('.', '') + '$', 'i');\n            this._shortMonthsParse[i] = new RegExp('^' + this.monthsShort(mom, '').replace('.', '') + '$', 'i');\n        }\n        if (!strict && !this._monthsParse[i]) {\n            regex = '^' + this.months(mom, '') + '|^' + this.monthsShort(mom, '');\n            this._monthsParse[i] = new RegExp(regex.replace('.', ''), 'i');\n        }\n        // test the regex\n        if (strict && format === 'MMMM' && this._longMonthsParse[i].test(monthName)) {\n            return i;\n        } else if (strict && format === 'MMM' && this._shortMonthsParse[i].test(monthName)) {\n            return i;\n        } else if (!strict && this._monthsParse[i].test(monthName)) {\n            return i;\n        }\n    }\n}\n\n// MOMENTS\n\nfunction setMonth (mom, value) {\n    var dayOfMonth;\n\n    if (!mom.isValid()) {\n        // No op\n        return mom;\n    }\n\n    if (typeof value === 'string') {\n        if (/^\\d+$/.test(value)) {\n            value = toInt(value);\n        } else {\n            value = mom.localeData().monthsParse(value);\n            // TODO: Another silent failure?\n            if (!isNumber(value)) {\n                return mom;\n            }\n        }\n    }\n\n    dayOfMonth = Math.min(mom.date(), daysInMonth(mom.year(), value));\n    mom._d['set' + (mom._isUTC ? 'UTC' : '') + 'Month'](value, dayOfMonth);\n    return mom;\n}\n\nfunction getSetMonth (value) {\n    if (value != null) {\n        setMonth(this, value);\n        hooks.updateOffset(this, true);\n        return this;\n    } else {\n        return get(this, 'Month');\n    }\n}\n\nfunction getDaysInMonth () {\n    return daysInMonth(this.year(), this.month());\n}\n\nvar defaultMonthsShortRegex = matchWord;\nfunction monthsShortRegex (isStrict) {\n    if (this._monthsParseExact) {\n        if (!hasOwnProp(this, '_monthsRegex')) {\n            computeMonthsParse.call(this);\n        }\n        if (isStrict) {\n            return this._monthsShortStrictRegex;\n        } else {\n            return this._monthsShortRegex;\n        }\n    } else {\n        if (!hasOwnProp(this, '_monthsShortRegex')) {\n            this._monthsShortRegex = defaultMonthsShortRegex;\n        }\n        return this._monthsShortStrictRegex && isStrict ?\n            this._monthsShortStrictRegex : this._monthsShortRegex;\n    }\n}\n\nvar defaultMonthsRegex = matchWord;\nfunction monthsRegex (isStrict) {\n    if (this._monthsParseExact) {\n        if (!hasOwnProp(this, '_monthsRegex')) {\n            computeMonthsParse.call(this);\n        }\n        if (isStrict) {\n            return this._monthsStrictRegex;\n        } else {\n            return this._monthsRegex;\n        }\n    } else {\n        if (!hasOwnProp(this, '_monthsRegex')) {\n            this._monthsRegex = defaultMonthsRegex;\n        }\n        return this._monthsStrictRegex && isStrict ?\n            this._monthsStrictRegex : this._monthsRegex;\n    }\n}\n\nfunction computeMonthsParse () {\n    function cmpLenRev(a, b) {\n        return b.length - a.length;\n    }\n\n    var shortPieces = [], longPieces = [], mixedPieces = [],\n        i, mom;\n    for (i = 0; i < 12; i++) {\n        // make the regex if we don't have it already\n        mom = createUTC([2000, i]);\n        shortPieces.push(this.monthsShort(mom, ''));\n        longPieces.push(this.months(mom, ''));\n        mixedPieces.push(this.months(mom, ''));\n        mixedPieces.push(this.monthsShort(mom, ''));\n    }\n    // Sorting makes sure if one month (or abbr) is a prefix of another it\n    // will match the longer piece.\n    shortPieces.sort(cmpLenRev);\n    longPieces.sort(cmpLenRev);\n    mixedPieces.sort(cmpLenRev);\n    for (i = 0; i < 12; i++) {\n        shortPieces[i] = regexEscape(shortPieces[i]);\n        longPieces[i] = regexEscape(longPieces[i]);\n    }\n    for (i = 0; i < 24; i++) {\n        mixedPieces[i] = regexEscape(mixedPieces[i]);\n    }\n\n    this._monthsRegex = new RegExp('^(' + mixedPieces.join('|') + ')', 'i');\n    this._monthsShortRegex = this._monthsRegex;\n    this._monthsStrictRegex = new RegExp('^(' + longPieces.join('|') + ')', 'i');\n    this._monthsShortStrictRegex = new RegExp('^(' + shortPieces.join('|') + ')', 'i');\n}\n\n// FORMATTING\n\naddFormatToken('Y', 0, 0, function () {\n    var y = this.year();\n    return y <= 9999 ? '' + y : '+' + y;\n});\n\naddFormatToken(0, ['YY', 2], 0, function () {\n    return this.year() % 100;\n});\n\naddFormatToken(0, ['YYYY',   4],       0, 'year');\naddFormatToken(0, ['YYYYY',  5],       0, 'year');\naddFormatToken(0, ['YYYYYY', 6, true], 0, 'year');\n\n// ALIASES\n\naddUnitAlias('year', 'y');\n\n// PRIORITIES\n\naddUnitPriority('year', 1);\n\n// PARSING\n\naddRegexToken('Y',      matchSigned);\naddRegexToken('YY',     match1to2, match2);\naddRegexToken('YYYY',   match1to4, match4);\naddRegexToken('YYYYY',  match1to6, match6);\naddRegexToken('YYYYYY', match1to6, match6);\n\naddParseToken(['YYYYY', 'YYYYYY'], YEAR);\naddParseToken('YYYY', function (input, array) {\n    array[YEAR] = input.length === 2 ? hooks.parseTwoDigitYear(input) : toInt(input);\n});\naddParseToken('YY', function (input, array) {\n    array[YEAR] = hooks.parseTwoDigitYear(input);\n});\naddParseToken('Y', function (input, array) {\n    array[YEAR] = parseInt(input, 10);\n});\n\n// HELPERS\n\nfunction daysInYear(year) {\n    return isLeapYear(year) ? 366 : 365;\n}\n\nfunction isLeapYear(year) {\n    return (year % 4 === 0 && year % 100 !== 0) || year % 400 === 0;\n}\n\n// HOOKS\n\nhooks.parseTwoDigitYear = function (input) {\n    return toInt(input) + (toInt(input) > 68 ? 1900 : 2000);\n};\n\n// MOMENTS\n\nvar getSetYear = makeGetSet('FullYear', true);\n\nfunction getIsLeapYear () {\n    return isLeapYear(this.year());\n}\n\nfunction createDate (y, m, d, h, M, s, ms) {\n    // can't just apply() to create a date:\n    // https://stackoverflow.com/q/181348\n    var date = new Date(y, m, d, h, M, s, ms);\n\n    // the date constructor remaps years 0-99 to 1900-1999\n    if (y < 100 && y >= 0 && isFinite(date.getFullYear())) {\n        date.setFullYear(y);\n    }\n    return date;\n}\n\nfunction createUTCDate (y) {\n    var date = new Date(Date.UTC.apply(null, arguments));\n\n    // the Date.UTC function remaps years 0-99 to 1900-1999\n    if (y < 100 && y >= 0 && isFinite(date.getUTCFullYear())) {\n        date.setUTCFullYear(y);\n    }\n    return date;\n}\n\n// start-of-first-week - start-of-year\nfunction firstWeekOffset(year, dow, doy) {\n    var // first-week day -- which january is always in the first week (4 for iso, 1 for other)\n        fwd = 7 + dow - doy,\n        // first-week day local weekday -- which local weekday is fwd\n        fwdlw = (7 + createUTCDate(year, 0, fwd).getUTCDay() - dow) % 7;\n\n    return -fwdlw + fwd - 1;\n}\n\n// https://en.wikipedia.org/wiki/ISO_week_date#Calculating_a_date_given_the_year.2C_week_number_and_weekday\nfunction dayOfYearFromWeeks(year, week, weekday, dow, doy) {\n    var localWeekday = (7 + weekday - dow) % 7,\n        weekOffset = firstWeekOffset(year, dow, doy),\n        dayOfYear = 1 + 7 * (week - 1) + localWeekday + weekOffset,\n        resYear, resDayOfYear;\n\n    if (dayOfYear <= 0) {\n        resYear = year - 1;\n        resDayOfYear = daysInYear(resYear) + dayOfYear;\n    } else if (dayOfYear > daysInYear(year)) {\n        resYear = year + 1;\n        resDayOfYear = dayOfYear - daysInYear(year);\n    } else {\n        resYear = year;\n        resDayOfYear = dayOfYear;\n    }\n\n    return {\n        year: resYear,\n        dayOfYear: resDayOfYear\n    };\n}\n\nfunction weekOfYear(mom, dow, doy) {\n    var weekOffset = firstWeekOffset(mom.year(), dow, doy),\n        week = Math.floor((mom.dayOfYear() - weekOffset - 1) / 7) + 1,\n        resWeek, resYear;\n\n    if (week < 1) {\n        resYear = mom.year() - 1;\n        resWeek = week + weeksInYear(resYear, dow, doy);\n    } else if (week > weeksInYear(mom.year(), dow, doy)) {\n        resWeek = week - weeksInYear(mom.year(), dow, doy);\n        resYear = mom.year() + 1;\n    } else {\n        resYear = mom.year();\n        resWeek = week;\n    }\n\n    return {\n        week: resWeek,\n        year: resYear\n    };\n}\n\nfunction weeksInYear(year, dow, doy) {\n    var weekOffset = firstWeekOffset(year, dow, doy),\n        weekOffsetNext = firstWeekOffset(year + 1, dow, doy);\n    return (daysInYear(year) - weekOffset + weekOffsetNext) / 7;\n}\n\n// FORMATTING\n\naddFormatToken('w', ['ww', 2], 'wo', 'week');\naddFormatToken('W', ['WW', 2], 'Wo', 'isoWeek');\n\n// ALIASES\n\naddUnitAlias('week', 'w');\naddUnitAlias('isoWeek', 'W');\n\n// PRIORITIES\n\naddUnitPriority('week', 5);\naddUnitPriority('isoWeek', 5);\n\n// PARSING\n\naddRegexToken('w',  match1to2);\naddRegexToken('ww', match1to2, match2);\naddRegexToken('W',  match1to2);\naddRegexToken('WW', match1to2, match2);\n\naddWeekParseToken(['w', 'ww', 'W', 'WW'], function (input, week, config, token) {\n    week[token.substr(0, 1)] = toInt(input);\n});\n\n// HELPERS\n\n// LOCALES\n\nfunction localeWeek (mom) {\n    return weekOfYear(mom, this._week.dow, this._week.doy).week;\n}\n\nvar defaultLocaleWeek = {\n    dow : 0, // Sunday is the first day of the week.\n    doy : 6  // The week that contains Jan 1st is the first week of the year.\n};\n\nfunction localeFirstDayOfWeek () {\n    return this._week.dow;\n}\n\nfunction localeFirstDayOfYear () {\n    return this._week.doy;\n}\n\n// MOMENTS\n\nfunction getSetWeek (input) {\n    var week = this.localeData().week(this);\n    return input == null ? week : this.add((input - week) * 7, 'd');\n}\n\nfunction getSetISOWeek (input) {\n    var week = weekOfYear(this, 1, 4).week;\n    return input == null ? week : this.add((input - week) * 7, 'd');\n}\n\n// FORMATTING\n\naddFormatToken('d', 0, 'do', 'day');\n\naddFormatToken('dd', 0, 0, function (format) {\n    return this.localeData().weekdaysMin(this, format);\n});\n\naddFormatToken('ddd', 0, 0, function (format) {\n    return this.localeData().weekdaysShort(this, format);\n});\n\naddFormatToken('dddd', 0, 0, function (format) {\n    return this.localeData().weekdays(this, format);\n});\n\naddFormatToken('e', 0, 0, 'weekday');\naddFormatToken('E', 0, 0, 'isoWeekday');\n\n// ALIASES\n\naddUnitAlias('day', 'd');\naddUnitAlias('weekday', 'e');\naddUnitAlias('isoWeekday', 'E');\n\n// PRIORITY\naddUnitPriority('day', 11);\naddUnitPriority('weekday', 11);\naddUnitPriority('isoWeekday', 11);\n\n// PARSING\n\naddRegexToken('d',    match1to2);\naddRegexToken('e',    match1to2);\naddRegexToken('E',    match1to2);\naddRegexToken('dd',   function (isStrict, locale) {\n    return locale.weekdaysMinRegex(isStrict);\n});\naddRegexToken('ddd',   function (isStrict, locale) {\n    return locale.weekdaysShortRegex(isStrict);\n});\naddRegexToken('dddd',   function (isStrict, locale) {\n    return locale.weekdaysRegex(isStrict);\n});\n\naddWeekParseToken(['dd', 'ddd', 'dddd'], function (input, week, config, token) {\n    var weekday = config._locale.weekdaysParse(input, token, config._strict);\n    // if we didn't get a weekday name, mark the date as invalid\n    if (weekday != null) {\n        week.d = weekday;\n    } else {\n        getParsingFlags(config).invalidWeekday = input;\n    }\n});\n\naddWeekParseToken(['d', 'e', 'E'], function (input, week, config, token) {\n    week[token] = toInt(input);\n});\n\n// HELPERS\n\nfunction parseWeekday(input, locale) {\n    if (typeof input !== 'string') {\n        return input;\n    }\n\n    if (!isNaN(input)) {\n        return parseInt(input, 10);\n    }\n\n    input = locale.weekdaysParse(input);\n    if (typeof input === 'number') {\n        return input;\n    }\n\n    return null;\n}\n\nfunction parseIsoWeekday(input, locale) {\n    if (typeof input === 'string') {\n        return locale.weekdaysParse(input) % 7 || 7;\n    }\n    return isNaN(input) ? null : input;\n}\n\n// LOCALES\n\nvar defaultLocaleWeekdays = 'Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday'.split('_');\nfunction localeWeekdays (m, format) {\n    if (!m) {\n        return isArray(this._weekdays) ? this._weekdays :\n            this._weekdays['standalone'];\n    }\n    return isArray(this._weekdays) ? this._weekdays[m.day()] :\n        this._weekdays[this._weekdays.isFormat.test(format) ? 'format' : 'standalone'][m.day()];\n}\n\nvar defaultLocaleWeekdaysShort = 'Sun_Mon_Tue_Wed_Thu_Fri_Sat'.split('_');\nfunction localeWeekdaysShort (m) {\n    return (m) ? this._weekdaysShort[m.day()] : this._weekdaysShort;\n}\n\nvar defaultLocaleWeekdaysMin = 'Su_Mo_Tu_We_Th_Fr_Sa'.split('_');\nfunction localeWeekdaysMin (m) {\n    return (m) ? this._weekdaysMin[m.day()] : this._weekdaysMin;\n}\n\nfunction handleStrictParse$1(weekdayName, format, strict) {\n    var i, ii, mom, llc = weekdayName.toLocaleLowerCase();\n    if (!this._weekdaysParse) {\n        this._weekdaysParse = [];\n        this._shortWeekdaysParse = [];\n        this._minWeekdaysParse = [];\n\n        for (i = 0; i < 7; ++i) {\n            mom = createUTC([2000, 1]).day(i);\n            this._minWeekdaysParse[i] = this.weekdaysMin(mom, '').toLocaleLowerCase();\n            this._shortWeekdaysParse[i] = this.weekdaysShort(mom, '').toLocaleLowerCase();\n            this._weekdaysParse[i] = this.weekdays(mom, '').toLocaleLowerCase();\n        }\n    }\n\n    if (strict) {\n        if (format === 'dddd') {\n            ii = indexOf$1.call(this._weekdaysParse, llc);\n            return ii !== -1 ? ii : null;\n        } else if (format === 'ddd') {\n            ii = indexOf$1.call(this._shortWeekdaysParse, llc);\n            return ii !== -1 ? ii : null;\n        } else {\n            ii = indexOf$1.call(this._minWeekdaysParse, llc);\n            return ii !== -1 ? ii : null;\n        }\n    } else {\n        if (format === 'dddd') {\n            ii = indexOf$1.call(this._weekdaysParse, llc);\n            if (ii !== -1) {\n                return ii;\n            }\n            ii = indexOf$1.call(this._shortWeekdaysParse, llc);\n            if (ii !== -1) {\n                return ii;\n            }\n            ii = indexOf$1.call(this._minWeekdaysParse, llc);\n            return ii !== -1 ? ii : null;\n        } else if (format === 'ddd') {\n            ii = indexOf$1.call(this._shortWeekdaysParse, llc);\n            if (ii !== -1) {\n                return ii;\n            }\n            ii = indexOf$1.call(this._weekdaysParse, llc);\n            if (ii !== -1) {\n                return ii;\n            }\n            ii = indexOf$1.call(this._minWeekdaysParse, llc);\n            return ii !== -1 ? ii : null;\n        } else {\n            ii = indexOf$1.call(this._minWeekdaysParse, llc);\n            if (ii !== -1) {\n                return ii;\n            }\n            ii = indexOf$1.call(this._weekdaysParse, llc);\n            if (ii !== -1) {\n                return ii;\n            }\n            ii = indexOf$1.call(this._shortWeekdaysParse, llc);\n            return ii !== -1 ? ii : null;\n        }\n    }\n}\n\nfunction localeWeekdaysParse (weekdayName, format, strict) {\n    var i, mom, regex;\n\n    if (this._weekdaysParseExact) {\n        return handleStrictParse$1.call(this, weekdayName, format, strict);\n    }\n\n    if (!this._weekdaysParse) {\n        this._weekdaysParse = [];\n        this._minWeekdaysParse = [];\n        this._shortWeekdaysParse = [];\n        this._fullWeekdaysParse = [];\n    }\n\n    for (i = 0; i < 7; i++) {\n        // make the regex if we don't have it already\n\n        mom = createUTC([2000, 1]).day(i);\n        if (strict && !this._fullWeekdaysParse[i]) {\n            this._fullWeekdaysParse[i] = new RegExp('^' + this.weekdays(mom, '').replace('.', '\\.?') + '$', 'i');\n            this._shortWeekdaysParse[i] = new RegExp('^' + this.weekdaysShort(mom, '').replace('.', '\\.?') + '$', 'i');\n            this._minWeekdaysParse[i] = new RegExp('^' + this.weekdaysMin(mom, '').replace('.', '\\.?') + '$', 'i');\n        }\n        if (!this._weekdaysParse[i]) {\n            regex = '^' + this.weekdays(mom, '') + '|^' + this.weekdaysShort(mom, '') + '|^' + this.weekdaysMin(mom, '');\n            this._weekdaysParse[i] = new RegExp(regex.replace('.', ''), 'i');\n        }\n        // test the regex\n        if (strict && format === 'dddd' && this._fullWeekdaysParse[i].test(weekdayName)) {\n            return i;\n        } else if (strict && format === 'ddd' && this._shortWeekdaysParse[i].test(weekdayName)) {\n            return i;\n        } else if (strict && format === 'dd' && this._minWeekdaysParse[i].test(weekdayName)) {\n            return i;\n        } else if (!strict && this._weekdaysParse[i].test(weekdayName)) {\n            return i;\n        }\n    }\n}\n\n// MOMENTS\n\nfunction getSetDayOfWeek (input) {\n    if (!this.isValid()) {\n        return input != null ? this : NaN;\n    }\n    var day = this._isUTC ? this._d.getUTCDay() : this._d.getDay();\n    if (input != null) {\n        input = parseWeekday(input, this.localeData());\n        return this.add(input - day, 'd');\n    } else {\n        return day;\n    }\n}\n\nfunction getSetLocaleDayOfWeek (input) {\n    if (!this.isValid()) {\n        return input != null ? this : NaN;\n    }\n    var weekday = (this.day() + 7 - this.localeData()._week.dow) % 7;\n    return input == null ? weekday : this.add(input - weekday, 'd');\n}\n\nfunction getSetISODayOfWeek (input) {\n    if (!this.isValid()) {\n        return input != null ? this : NaN;\n    }\n\n    // behaves the same as moment#day except\n    // as a getter, returns 7 instead of 0 (1-7 range instead of 0-6)\n    // as a setter, sunday should belong to the previous week.\n\n    if (input != null) {\n        var weekday = parseIsoWeekday(input, this.localeData());\n        return this.day(this.day() % 7 ? weekday : weekday - 7);\n    } else {\n        return this.day() || 7;\n    }\n}\n\nvar defaultWeekdaysRegex = matchWord;\nfunction weekdaysRegex (isStrict) {\n    if (this._weekdaysParseExact) {\n        if (!hasOwnProp(this, '_weekdaysRegex')) {\n            computeWeekdaysParse.call(this);\n        }\n        if (isStrict) {\n            return this._weekdaysStrictRegex;\n        } else {\n            return this._weekdaysRegex;\n        }\n    } else {\n        if (!hasOwnProp(this, '_weekdaysRegex')) {\n            this._weekdaysRegex = defaultWeekdaysRegex;\n        }\n        return this._weekdaysStrictRegex && isStrict ?\n            this._weekdaysStrictRegex : this._weekdaysRegex;\n    }\n}\n\nvar defaultWeekdaysShortRegex = matchWord;\nfunction weekdaysShortRegex (isStrict) {\n    if (this._weekdaysParseExact) {\n        if (!hasOwnProp(this, '_weekdaysRegex')) {\n            computeWeekdaysParse.call(this);\n        }\n        if (isStrict) {\n            return this._weekdaysShortStrictRegex;\n        } else {\n            return this._weekdaysShortRegex;\n        }\n    } else {\n        if (!hasOwnProp(this, '_weekdaysShortRegex')) {\n            this._weekdaysShortRegex = defaultWeekdaysShortRegex;\n        }\n        return this._weekdaysShortStrictRegex && isStrict ?\n            this._weekdaysShortStrictRegex : this._weekdaysShortRegex;\n    }\n}\n\nvar defaultWeekdaysMinRegex = matchWord;\nfunction weekdaysMinRegex (isStrict) {\n    if (this._weekdaysParseExact) {\n        if (!hasOwnProp(this, '_weekdaysRegex')) {\n            computeWeekdaysParse.call(this);\n        }\n        if (isStrict) {\n            return this._weekdaysMinStrictRegex;\n        } else {\n            return this._weekdaysMinRegex;\n        }\n    } else {\n        if (!hasOwnProp(this, '_weekdaysMinRegex')) {\n            this._weekdaysMinRegex = defaultWeekdaysMinRegex;\n        }\n        return this._weekdaysMinStrictRegex && isStrict ?\n            this._weekdaysMinStrictRegex : this._weekdaysMinRegex;\n    }\n}\n\n\nfunction computeWeekdaysParse () {\n    function cmpLenRev(a, b) {\n        return b.length - a.length;\n    }\n\n    var minPieces = [], shortPieces = [], longPieces = [], mixedPieces = [],\n        i, mom, minp, shortp, longp;\n    for (i = 0; i < 7; i++) {\n        // make the regex if we don't have it already\n        mom = createUTC([2000, 1]).day(i);\n        minp = this.weekdaysMin(mom, '');\n        shortp = this.weekdaysShort(mom, '');\n        longp = this.weekdays(mom, '');\n        minPieces.push(minp);\n        shortPieces.push(shortp);\n        longPieces.push(longp);\n        mixedPieces.push(minp);\n        mixedPieces.push(shortp);\n        mixedPieces.push(longp);\n    }\n    // Sorting makes sure if one weekday (or abbr) is a prefix of another it\n    // will match the longer piece.\n    minPieces.sort(cmpLenRev);\n    shortPieces.sort(cmpLenRev);\n    longPieces.sort(cmpLenRev);\n    mixedPieces.sort(cmpLenRev);\n    for (i = 0; i < 7; i++) {\n        shortPieces[i] = regexEscape(shortPieces[i]);\n        longPieces[i] = regexEscape(longPieces[i]);\n        mixedPieces[i] = regexEscape(mixedPieces[i]);\n    }\n\n    this._weekdaysRegex = new RegExp('^(' + mixedPieces.join('|') + ')', 'i');\n    this._weekdaysShortRegex = this._weekdaysRegex;\n    this._weekdaysMinRegex = this._weekdaysRegex;\n\n    this._weekdaysStrictRegex = new RegExp('^(' + longPieces.join('|') + ')', 'i');\n    this._weekdaysShortStrictRegex = new RegExp('^(' + shortPieces.join('|') + ')', 'i');\n    this._weekdaysMinStrictRegex = new RegExp('^(' + minPieces.join('|') + ')', 'i');\n}\n\n// FORMATTING\n\nfunction hFormat() {\n    return this.hours() % 12 || 12;\n}\n\nfunction kFormat() {\n    return this.hours() || 24;\n}\n\naddFormatToken('H', ['HH', 2], 0, 'hour');\naddFormatToken('h', ['hh', 2], 0, hFormat);\naddFormatToken('k', ['kk', 2], 0, kFormat);\n\naddFormatToken('hmm', 0, 0, function () {\n    return '' + hFormat.apply(this) + zeroFill(this.minutes(), 2);\n});\n\naddFormatToken('hmmss', 0, 0, function () {\n    return '' + hFormat.apply(this) + zeroFill(this.minutes(), 2) +\n        zeroFill(this.seconds(), 2);\n});\n\naddFormatToken('Hmm', 0, 0, function () {\n    return '' + this.hours() + zeroFill(this.minutes(), 2);\n});\n\naddFormatToken('Hmmss', 0, 0, function () {\n    return '' + this.hours() + zeroFill(this.minutes(), 2) +\n        zeroFill(this.seconds(), 2);\n});\n\nfunction meridiem (token, lowercase) {\n    addFormatToken(token, 0, 0, function () {\n        return this.localeData().meridiem(this.hours(), this.minutes(), lowercase);\n    });\n}\n\nmeridiem('a', true);\nmeridiem('A', false);\n\n// ALIASES\n\naddUnitAlias('hour', 'h');\n\n// PRIORITY\naddUnitPriority('hour', 13);\n\n// PARSING\n\nfunction matchMeridiem (isStrict, locale) {\n    return locale._meridiemParse;\n}\n\naddRegexToken('a',  matchMeridiem);\naddRegexToken('A',  matchMeridiem);\naddRegexToken('H',  match1to2);\naddRegexToken('h',  match1to2);\naddRegexToken('k',  match1to2);\naddRegexToken('HH', match1to2, match2);\naddRegexToken('hh', match1to2, match2);\naddRegexToken('kk', match1to2, match2);\n\naddRegexToken('hmm', match3to4);\naddRegexToken('hmmss', match5to6);\naddRegexToken('Hmm', match3to4);\naddRegexToken('Hmmss', match5to6);\n\naddParseToken(['H', 'HH'], HOUR);\naddParseToken(['k', 'kk'], function (input, array, config) {\n    var kInput = toInt(input);\n    array[HOUR] = kInput === 24 ? 0 : kInput;\n});\naddParseToken(['a', 'A'], function (input, array, config) {\n    config._isPm = config._locale.isPM(input);\n    config._meridiem = input;\n});\naddParseToken(['h', 'hh'], function (input, array, config) {\n    array[HOUR] = toInt(input);\n    getParsingFlags(config).bigHour = true;\n});\naddParseToken('hmm', function (input, array, config) {\n    var pos = input.length - 2;\n    array[HOUR] = toInt(input.substr(0, pos));\n    array[MINUTE] = toInt(input.substr(pos));\n    getParsingFlags(config).bigHour = true;\n});\naddParseToken('hmmss', function (input, array, config) {\n    var pos1 = input.length - 4;\n    var pos2 = input.length - 2;\n    array[HOUR] = toInt(input.substr(0, pos1));\n    array[MINUTE] = toInt(input.substr(pos1, 2));\n    array[SECOND] = toInt(input.substr(pos2));\n    getParsingFlags(config).bigHour = true;\n});\naddParseToken('Hmm', function (input, array, config) {\n    var pos = input.length - 2;\n    array[HOUR] = toInt(input.substr(0, pos));\n    array[MINUTE] = toInt(input.substr(pos));\n});\naddParseToken('Hmmss', function (input, array, config) {\n    var pos1 = input.length - 4;\n    var pos2 = input.length - 2;\n    array[HOUR] = toInt(input.substr(0, pos1));\n    array[MINUTE] = toInt(input.substr(pos1, 2));\n    array[SECOND] = toInt(input.substr(pos2));\n});\n\n// LOCALES\n\nfunction localeIsPM (input) {\n    // IE8 Quirks Mode & IE7 Standards Mode do not allow accessing strings like arrays\n    // Using charAt should be more compatible.\n    return ((input + '').toLowerCase().charAt(0) === 'p');\n}\n\nvar defaultLocaleMeridiemParse = /[ap]\\.?m?\\.?/i;\nfunction localeMeridiem (hours, minutes, isLower) {\n    if (hours > 11) {\n        return isLower ? 'pm' : 'PM';\n    } else {\n        return isLower ? 'am' : 'AM';\n    }\n}\n\n\n// MOMENTS\n\n// Setting the hour should keep the time, because the user explicitly\n// specified which hour he wants. So trying to maintain the same hour (in\n// a new timezone) makes sense. Adding/subtracting hours does not follow\n// this rule.\nvar getSetHour = makeGetSet('Hours', true);\n\n// months\n// week\n// weekdays\n// meridiem\nvar baseConfig = {\n    calendar: defaultCalendar,\n    longDateFormat: defaultLongDateFormat,\n    invalidDate: defaultInvalidDate,\n    ordinal: defaultOrdinal,\n    dayOfMonthOrdinalParse: defaultDayOfMonthOrdinalParse,\n    relativeTime: defaultRelativeTime,\n\n    months: defaultLocaleMonths,\n    monthsShort: defaultLocaleMonthsShort,\n\n    week: defaultLocaleWeek,\n\n    weekdays: defaultLocaleWeekdays,\n    weekdaysMin: defaultLocaleWeekdaysMin,\n    weekdaysShort: defaultLocaleWeekdaysShort,\n\n    meridiemParse: defaultLocaleMeridiemParse\n};\n\n// internal storage for locale config files\nvar locales = {};\nvar localeFamilies = {};\nvar globalLocale;\n\nfunction normalizeLocale(key) {\n    return key ? key.toLowerCase().replace('_', '-') : key;\n}\n\n// pick the locale from the array\n// try ['en-au', 'en-gb'] as 'en-au', 'en-gb', 'en', as in move through the list trying each\n// substring from most specific to least, but move to the next array item if it's a more specific variant than the current root\nfunction chooseLocale(names) {\n    var i = 0, j, next, locale, split;\n\n    while (i < names.length) {\n        split = normalizeLocale(names[i]).split('-');\n        j = split.length;\n        next = normalizeLocale(names[i + 1]);\n        next = next ? next.split('-') : null;\n        while (j > 0) {\n            locale = loadLocale(split.slice(0, j).join('-'));\n            if (locale) {\n                return locale;\n            }\n            if (next && next.length >= j && compareArrays(split, next, true) >= j - 1) {\n                //the next array item is better than a shallower substring of this one\n                break;\n            }\n            j--;\n        }\n        i++;\n    }\n    return null;\n}\n\nfunction loadLocale(name) {\n    var oldLocale = null;\n    // TODO: Find a better way to register and load all the locales in Node\n    if (!locales[name] && (typeof module !== 'undefined') &&\n            module && module.exports) {\n        try {\n            oldLocale = globalLocale._abbr;\n            require('./locale/' + name);\n            // because defineLocale currently also sets the global locale, we\n            // want to undo that for lazy loaded locales\n            getSetGlobalLocale(oldLocale);\n        } catch (e) { }\n    }\n    return locales[name];\n}\n\n// This function will load locale and then set the global locale.  If\n// no arguments are passed in, it will simply return the current global\n// locale key.\nfunction getSetGlobalLocale (key, values) {\n    var data;\n    if (key) {\n        if (isUndefined(values)) {\n            data = getLocale(key);\n        }\n        else {\n            data = defineLocale(key, values);\n        }\n\n        if (data) {\n            // moment.duration._locale = moment._locale = data;\n            globalLocale = data;\n        }\n    }\n\n    return globalLocale._abbr;\n}\n\nfunction defineLocale (name, config) {\n    if (config !== null) {\n        var parentConfig = baseConfig;\n        config.abbr = name;\n        if (locales[name] != null) {\n            deprecateSimple('defineLocaleOverride',\n                    'use moment.updateLocale(localeName, config) to change ' +\n                    'an existing locale. moment.defineLocale(localeName, ' +\n                    'config) should only be used for creating a new locale ' +\n                    'See http://momentjs.com/guides/#/warnings/define-locale/ for more info.');\n            parentConfig = locales[name]._config;\n        } else if (config.parentLocale != null) {\n            if (locales[config.parentLocale] != null) {\n                parentConfig = locales[config.parentLocale]._config;\n            } else {\n                if (!localeFamilies[config.parentLocale]) {\n                    localeFamilies[config.parentLocale] = [];\n                }\n                localeFamilies[config.parentLocale].push({\n                    name: name,\n                    config: config\n                });\n                return null;\n            }\n        }\n        locales[name] = new Locale(mergeConfigs(parentConfig, config));\n\n        if (localeFamilies[name]) {\n            localeFamilies[name].forEach(function (x) {\n                defineLocale(x.name, x.config);\n            });\n        }\n\n        // backwards compat for now: also set the locale\n        // make sure we set the locale AFTER all child locales have been\n        // created, so we won't end up with the child locale set.\n        getSetGlobalLocale(name);\n\n\n        return locales[name];\n    } else {\n        // useful for testing\n        delete locales[name];\n        return null;\n    }\n}\n\nfunction updateLocale(name, config) {\n    if (config != null) {\n        var locale, parentConfig = baseConfig;\n        // MERGE\n        if (locales[name] != null) {\n            parentConfig = locales[name]._config;\n        }\n        config = mergeConfigs(parentConfig, config);\n        locale = new Locale(config);\n        locale.parentLocale = locales[name];\n        locales[name] = locale;\n\n        // backwards compat for now: also set the locale\n        getSetGlobalLocale(name);\n    } else {\n        // pass null for config to unupdate, useful for tests\n        if (locales[name] != null) {\n            if (locales[name].parentLocale != null) {\n                locales[name] = locales[name].parentLocale;\n            } else if (locales[name] != null) {\n                delete locales[name];\n            }\n        }\n    }\n    return locales[name];\n}\n\n// returns locale data\nfunction getLocale (key) {\n    var locale;\n\n    if (key && key._locale && key._locale._abbr) {\n        key = key._locale._abbr;\n    }\n\n    if (!key) {\n        return globalLocale;\n    }\n\n    if (!isArray(key)) {\n        //short-circuit everything else\n        locale = loadLocale(key);\n        if (locale) {\n            return locale;\n        }\n        key = [key];\n    }\n\n    return chooseLocale(key);\n}\n\nfunction listLocales() {\n    return keys$1(locales);\n}\n\nfunction checkOverflow (m) {\n    var overflow;\n    var a = m._a;\n\n    if (a && getParsingFlags(m).overflow === -2) {\n        overflow =\n            a[MONTH]       < 0 || a[MONTH]       > 11  ? MONTH :\n            a[DATE]        < 1 || a[DATE]        > daysInMonth(a[YEAR], a[MONTH]) ? DATE :\n            a[HOUR]        < 0 || a[HOUR]        > 24 || (a[HOUR] === 24 && (a[MINUTE] !== 0 || a[SECOND] !== 0 || a[MILLISECOND] !== 0)) ? HOUR :\n            a[MINUTE]      < 0 || a[MINUTE]      > 59  ? MINUTE :\n            a[SECOND]      < 0 || a[SECOND]      > 59  ? SECOND :\n            a[MILLISECOND] < 0 || a[MILLISECOND] > 999 ? MILLISECOND :\n            -1;\n\n        if (getParsingFlags(m)._overflowDayOfYear && (overflow < YEAR || overflow > DATE)) {\n            overflow = DATE;\n        }\n        if (getParsingFlags(m)._overflowWeeks && overflow === -1) {\n            overflow = WEEK;\n        }\n        if (getParsingFlags(m)._overflowWeekday && overflow === -1) {\n            overflow = WEEKDAY;\n        }\n\n        getParsingFlags(m).overflow = overflow;\n    }\n\n    return m;\n}\n\n// iso 8601 regex\n// 0000-00-00 0000-W00 or 0000-W00-0 + T + 00 or 00:00 or 00:00:00 or 00:00:00.000 + +00:00 or +0000 or +00)\nvar extendedIsoRegex = /^\\s*((?:[+-]\\d{6}|\\d{4})-(?:\\d\\d-\\d\\d|W\\d\\d-\\d|W\\d\\d|\\d\\d\\d|\\d\\d))(?:(T| )(\\d\\d(?::\\d\\d(?::\\d\\d(?:[.,]\\d+)?)?)?)([\\+\\-]\\d\\d(?::?\\d\\d)?|\\s*Z)?)?$/;\nvar basicIsoRegex = /^\\s*((?:[+-]\\d{6}|\\d{4})(?:\\d\\d\\d\\d|W\\d\\d\\d|W\\d\\d|\\d\\d\\d|\\d\\d))(?:(T| )(\\d\\d(?:\\d\\d(?:\\d\\d(?:[.,]\\d+)?)?)?)([\\+\\-]\\d\\d(?::?\\d\\d)?|\\s*Z)?)?$/;\n\nvar tzRegex = /Z|[+-]\\d\\d(?::?\\d\\d)?/;\n\nvar isoDates = [\n    ['YYYYYY-MM-DD', /[+-]\\d{6}-\\d\\d-\\d\\d/],\n    ['YYYY-MM-DD', /\\d{4}-\\d\\d-\\d\\d/],\n    ['GGGG-[W]WW-E', /\\d{4}-W\\d\\d-\\d/],\n    ['GGGG-[W]WW', /\\d{4}-W\\d\\d/, false],\n    ['YYYY-DDD', /\\d{4}-\\d{3}/],\n    ['YYYY-MM', /\\d{4}-\\d\\d/, false],\n    ['YYYYYYMMDD', /[+-]\\d{10}/],\n    ['YYYYMMDD', /\\d{8}/],\n    // YYYYMM is NOT allowed by the standard\n    ['GGGG[W]WWE', /\\d{4}W\\d{3}/],\n    ['GGGG[W]WW', /\\d{4}W\\d{2}/, false],\n    ['YYYYDDD', /\\d{7}/]\n];\n\n// iso time formats and regexes\nvar isoTimes = [\n    ['HH:mm:ss.SSSS', /\\d\\d:\\d\\d:\\d\\d\\.\\d+/],\n    ['HH:mm:ss,SSSS', /\\d\\d:\\d\\d:\\d\\d,\\d+/],\n    ['HH:mm:ss', /\\d\\d:\\d\\d:\\d\\d/],\n    ['HH:mm', /\\d\\d:\\d\\d/],\n    ['HHmmss.SSSS', /\\d\\d\\d\\d\\d\\d\\.\\d+/],\n    ['HHmmss,SSSS', /\\d\\d\\d\\d\\d\\d,\\d+/],\n    ['HHmmss', /\\d\\d\\d\\d\\d\\d/],\n    ['HHmm', /\\d\\d\\d\\d/],\n    ['HH', /\\d\\d/]\n];\n\nvar aspNetJsonRegex = /^\\/?Date\\((\\-?\\d+)/i;\n\n// date from iso format\nfunction configFromISO(config) {\n    var i, l,\n        string = config._i,\n        match = extendedIsoRegex.exec(string) || basicIsoRegex.exec(string),\n        allowTime, dateFormat, timeFormat, tzFormat;\n\n    if (match) {\n        getParsingFlags(config).iso = true;\n\n        for (i = 0, l = isoDates.length; i < l; i++) {\n            if (isoDates[i][1].exec(match[1])) {\n                dateFormat = isoDates[i][0];\n                allowTime = isoDates[i][2] !== false;\n                break;\n            }\n        }\n        if (dateFormat == null) {\n            config._isValid = false;\n            return;\n        }\n        if (match[3]) {\n            for (i = 0, l = isoTimes.length; i < l; i++) {\n                if (isoTimes[i][1].exec(match[3])) {\n                    // match[2] should be 'T' or space\n                    timeFormat = (match[2] || ' ') + isoTimes[i][0];\n                    break;\n                }\n            }\n            if (timeFormat == null) {\n                config._isValid = false;\n                return;\n            }\n        }\n        if (!allowTime && timeFormat != null) {\n            config._isValid = false;\n            return;\n        }\n        if (match[4]) {\n            if (tzRegex.exec(match[4])) {\n                tzFormat = 'Z';\n            } else {\n                config._isValid = false;\n                return;\n            }\n        }\n        config._f = dateFormat + (timeFormat || '') + (tzFormat || '');\n        configFromStringAndFormat(config);\n    } else {\n        config._isValid = false;\n    }\n}\n\n// RFC 2822 regex: For details see https://tools.ietf.org/html/rfc2822#section-3.3\nvar basicRfcRegex = /^((?:Mon|Tue|Wed|Thu|Fri|Sat|Sun),?\\s)?(\\d?\\d\\s(?:Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)\\s(?:\\d\\d)?\\d\\d\\s)(\\d\\d:\\d\\d)(\\:\\d\\d)?(\\s(?:UT|GMT|[ECMP][SD]T|[A-IK-Za-ik-z]|[+-]\\d{4}))$/;\n\n// date and time from ref 2822 format\nfunction configFromRFC2822(config) {\n    var string, match, dayFormat,\n        dateFormat, timeFormat, tzFormat;\n    var timezones = {\n        ' GMT': ' +0000',\n        ' EDT': ' -0400',\n        ' EST': ' -0500',\n        ' CDT': ' -0500',\n        ' CST': ' -0600',\n        ' MDT': ' -0600',\n        ' MST': ' -0700',\n        ' PDT': ' -0700',\n        ' PST': ' -0800'\n    };\n    var military = 'YXWVUTSRQPONZABCDEFGHIKLM';\n    var timezone, timezoneIndex;\n\n    string = config._i\n        .replace(/\\([^\\)]*\\)|[\\n\\t]/g, ' ') // Remove comments and folding whitespace\n        .replace(/(\\s\\s+)/g, ' ') // Replace multiple-spaces with a single space\n        .replace(/^\\s|\\s$/g, ''); // Remove leading and trailing spaces\n    match = basicRfcRegex.exec(string);\n\n    if (match) {\n        dayFormat = match[1] ? 'ddd' + ((match[1].length === 5) ? ', ' : ' ') : '';\n        dateFormat = 'D MMM ' + ((match[2].length > 10) ? 'YYYY ' : 'YY ');\n        timeFormat = 'HH:mm' + (match[4] ? ':ss' : '');\n\n        // TODO: Replace the vanilla JS Date object with an indepentent day-of-week check.\n        if (match[1]) { // day of week given\n            var momentDate = new Date(match[2]);\n            var momentDay = ['Sun','Mon','Tue','Wed','Thu','Fri','Sat'][momentDate.getDay()];\n\n            if (match[1].substr(0,3) !== momentDay) {\n                getParsingFlags(config).weekdayMismatch = true;\n                config._isValid = false;\n                return;\n            }\n        }\n\n        switch (match[5].length) {\n            case 2: // military\n                if (timezoneIndex === 0) {\n                    timezone = ' +0000';\n                } else {\n                    timezoneIndex = military.indexOf(match[5][1].toUpperCase()) - 12;\n                    timezone = ((timezoneIndex < 0) ? ' -' : ' +') +\n                        (('' + timezoneIndex).replace(/^-?/, '0')).match(/..$/)[0] + '00';\n                }\n                break;\n            case 4: // Zone\n                timezone = timezones[match[5]];\n                break;\n            default: // UT or +/-9999\n                timezone = timezones[' GMT'];\n        }\n        match[5] = timezone;\n        config._i = match.splice(1).join('');\n        tzFormat = ' ZZ';\n        config._f = dayFormat + dateFormat + timeFormat + tzFormat;\n        configFromStringAndFormat(config);\n        getParsingFlags(config).rfc2822 = true;\n    } else {\n        config._isValid = false;\n    }\n}\n\n// date from iso format or fallback\nfunction configFromString(config) {\n    var matched = aspNetJsonRegex.exec(config._i);\n\n    if (matched !== null) {\n        config._d = new Date(+matched[1]);\n        return;\n    }\n\n    configFromISO(config);\n    if (config._isValid === false) {\n        delete config._isValid;\n    } else {\n        return;\n    }\n\n    configFromRFC2822(config);\n    if (config._isValid === false) {\n        delete config._isValid;\n    } else {\n        return;\n    }\n\n    // Final attempt, use Input Fallback\n    hooks.createFromInputFallback(config);\n}\n\nhooks.createFromInputFallback = deprecate(\n    'value provided is not in a recognized RFC2822 or ISO format. moment construction falls back to js Date(), ' +\n    'which is not reliable across all browsers and versions. Non RFC2822/ISO date formats are ' +\n    'discouraged and will be removed in an upcoming major release. Please refer to ' +\n    'http://momentjs.com/guides/#/warnings/js-date/ for more info.',\n    function (config) {\n        config._d = new Date(config._i + (config._useUTC ? ' UTC' : ''));\n    }\n);\n\n// Pick the first defined of two or three arguments.\nfunction defaults(a, b, c) {\n    if (a != null) {\n        return a;\n    }\n    if (b != null) {\n        return b;\n    }\n    return c;\n}\n\nfunction currentDateArray(config) {\n    // hooks is actually the exported moment object\n    var nowValue = new Date(hooks.now());\n    if (config._useUTC) {\n        return [nowValue.getUTCFullYear(), nowValue.getUTCMonth(), nowValue.getUTCDate()];\n    }\n    return [nowValue.getFullYear(), nowValue.getMonth(), nowValue.getDate()];\n}\n\n// convert an array to a date.\n// the array should mirror the parameters below\n// note: all values past the year are optional and will default to the lowest possible value.\n// [year, month, day , hour, minute, second, millisecond]\nfunction configFromArray (config) {\n    var i, date, input = [], currentDate, yearToUse;\n\n    if (config._d) {\n        return;\n    }\n\n    currentDate = currentDateArray(config);\n\n    //compute day of the year from weeks and weekdays\n    if (config._w && config._a[DATE] == null && config._a[MONTH] == null) {\n        dayOfYearFromWeekInfo(config);\n    }\n\n    //if the day of the year is set, figure out what it is\n    if (config._dayOfYear != null) {\n        yearToUse = defaults(config._a[YEAR], currentDate[YEAR]);\n\n        if (config._dayOfYear > daysInYear(yearToUse) || config._dayOfYear === 0) {\n            getParsingFlags(config)._overflowDayOfYear = true;\n        }\n\n        date = createUTCDate(yearToUse, 0, config._dayOfYear);\n        config._a[MONTH] = date.getUTCMonth();\n        config._a[DATE] = date.getUTCDate();\n    }\n\n    // Default to current date.\n    // * if no year, month, day of month are given, default to today\n    // * if day of month is given, default month and year\n    // * if month is given, default only year\n    // * if year is given, don't default anything\n    for (i = 0; i < 3 && config._a[i] == null; ++i) {\n        config._a[i] = input[i] = currentDate[i];\n    }\n\n    // Zero out whatever was not defaulted, including time\n    for (; i < 7; i++) {\n        config._a[i] = input[i] = (config._a[i] == null) ? (i === 2 ? 1 : 0) : config._a[i];\n    }\n\n    // Check for 24:00:00.000\n    if (config._a[HOUR] === 24 &&\n            config._a[MINUTE] === 0 &&\n            config._a[SECOND] === 0 &&\n            config._a[MILLISECOND] === 0) {\n        config._nextDay = true;\n        config._a[HOUR] = 0;\n    }\n\n    config._d = (config._useUTC ? createUTCDate : createDate).apply(null, input);\n    // Apply timezone offset from input. The actual utcOffset can be changed\n    // with parseZone.\n    if (config._tzm != null) {\n        config._d.setUTCMinutes(config._d.getUTCMinutes() - config._tzm);\n    }\n\n    if (config._nextDay) {\n        config._a[HOUR] = 24;\n    }\n}\n\nfunction dayOfYearFromWeekInfo(config) {\n    var w, weekYear, week, weekday, dow, doy, temp, weekdayOverflow;\n\n    w = config._w;\n    if (w.GG != null || w.W != null || w.E != null) {\n        dow = 1;\n        doy = 4;\n\n        // TODO: We need to take the current isoWeekYear, but that depends on\n        // how we interpret now (local, utc, fixed offset). So create\n        // a now version of current config (take local/utc/offset flags, and\n        // create now).\n        weekYear = defaults(w.GG, config._a[YEAR], weekOfYear(createLocal(), 1, 4).year);\n        week = defaults(w.W, 1);\n        weekday = defaults(w.E, 1);\n        if (weekday < 1 || weekday > 7) {\n            weekdayOverflow = true;\n        }\n    } else {\n        dow = config._locale._week.dow;\n        doy = config._locale._week.doy;\n\n        var curWeek = weekOfYear(createLocal(), dow, doy);\n\n        weekYear = defaults(w.gg, config._a[YEAR], curWeek.year);\n\n        // Default to current week.\n        week = defaults(w.w, curWeek.week);\n\n        if (w.d != null) {\n            // weekday -- low day numbers are considered next week\n            weekday = w.d;\n            if (weekday < 0 || weekday > 6) {\n                weekdayOverflow = true;\n            }\n        } else if (w.e != null) {\n            // local weekday -- counting starts from begining of week\n            weekday = w.e + dow;\n            if (w.e < 0 || w.e > 6) {\n                weekdayOverflow = true;\n            }\n        } else {\n            // default to begining of week\n            weekday = dow;\n        }\n    }\n    if (week < 1 || week > weeksInYear(weekYear, dow, doy)) {\n        getParsingFlags(config)._overflowWeeks = true;\n    } else if (weekdayOverflow != null) {\n        getParsingFlags(config)._overflowWeekday = true;\n    } else {\n        temp = dayOfYearFromWeeks(weekYear, week, weekday, dow, doy);\n        config._a[YEAR] = temp.year;\n        config._dayOfYear = temp.dayOfYear;\n    }\n}\n\n// constant that refers to the ISO standard\nhooks.ISO_8601 = function () {};\n\n// constant that refers to the RFC 2822 form\nhooks.RFC_2822 = function () {};\n\n// date from string and format string\nfunction configFromStringAndFormat(config) {\n    // TODO: Move this to another part of the creation flow to prevent circular deps\n    if (config._f === hooks.ISO_8601) {\n        configFromISO(config);\n        return;\n    }\n    if (config._f === hooks.RFC_2822) {\n        configFromRFC2822(config);\n        return;\n    }\n    config._a = [];\n    getParsingFlags(config).empty = true;\n\n    // This array is used to make a Date, either with `new Date` or `Date.UTC`\n    var string = '' + config._i,\n        i, parsedInput, tokens, token, skipped,\n        stringLength = string.length,\n        totalParsedInputLength = 0;\n\n    tokens = expandFormat(config._f, config._locale).match(formattingTokens) || [];\n\n    for (i = 0; i < tokens.length; i++) {\n        token = tokens[i];\n        parsedInput = (string.match(getParseRegexForToken(token, config)) || [])[0];\n        // console.log('token', token, 'parsedInput', parsedInput,\n        //         'regex', getParseRegexForToken(token, config));\n        if (parsedInput) {\n            skipped = string.substr(0, string.indexOf(parsedInput));\n            if (skipped.length > 0) {\n                getParsingFlags(config).unusedInput.push(skipped);\n            }\n            string = string.slice(string.indexOf(parsedInput) + parsedInput.length);\n            totalParsedInputLength += parsedInput.length;\n        }\n        // don't parse if it's not a known token\n        if (formatTokenFunctions[token]) {\n            if (parsedInput) {\n                getParsingFlags(config).empty = false;\n            }\n            else {\n                getParsingFlags(config).unusedTokens.push(token);\n            }\n            addTimeToArrayFromToken(token, parsedInput, config);\n        }\n        else if (config._strict && !parsedInput) {\n            getParsingFlags(config).unusedTokens.push(token);\n        }\n    }\n\n    // add remaining unparsed input length to the string\n    getParsingFlags(config).charsLeftOver = stringLength - totalParsedInputLength;\n    if (string.length > 0) {\n        getParsingFlags(config).unusedInput.push(string);\n    }\n\n    // clear _12h flag if hour is <= 12\n    if (config._a[HOUR] <= 12 &&\n        getParsingFlags(config).bigHour === true &&\n        config._a[HOUR] > 0) {\n        getParsingFlags(config).bigHour = undefined;\n    }\n\n    getParsingFlags(config).parsedDateParts = config._a.slice(0);\n    getParsingFlags(config).meridiem = config._meridiem;\n    // handle meridiem\n    config._a[HOUR] = meridiemFixWrap(config._locale, config._a[HOUR], config._meridiem);\n\n    configFromArray(config);\n    checkOverflow(config);\n}\n\n\nfunction meridiemFixWrap (locale, hour, meridiem) {\n    var isPm;\n\n    if (meridiem == null) {\n        // nothing to do\n        return hour;\n    }\n    if (locale.meridiemHour != null) {\n        return locale.meridiemHour(hour, meridiem);\n    } else if (locale.isPM != null) {\n        // Fallback\n        isPm = locale.isPM(meridiem);\n        if (isPm && hour < 12) {\n            hour += 12;\n        }\n        if (!isPm && hour === 12) {\n            hour = 0;\n        }\n        return hour;\n    } else {\n        // this is not supposed to happen\n        return hour;\n    }\n}\n\n// date from string and array of format strings\nfunction configFromStringAndArray(config) {\n    var tempConfig,\n        bestMoment,\n\n        scoreToBeat,\n        i,\n        currentScore;\n\n    if (config._f.length === 0) {\n        getParsingFlags(config).invalidFormat = true;\n        config._d = new Date(NaN);\n        return;\n    }\n\n    for (i = 0; i < config._f.length; i++) {\n        currentScore = 0;\n        tempConfig = copyConfig({}, config);\n        if (config._useUTC != null) {\n            tempConfig._useUTC = config._useUTC;\n        }\n        tempConfig._f = config._f[i];\n        configFromStringAndFormat(tempConfig);\n\n        if (!isValid(tempConfig)) {\n            continue;\n        }\n\n        // if there is any input that was not parsed add a penalty for that format\n        currentScore += getParsingFlags(tempConfig).charsLeftOver;\n\n        //or tokens\n        currentScore += getParsingFlags(tempConfig).unusedTokens.length * 10;\n\n        getParsingFlags(tempConfig).score = currentScore;\n\n        if (scoreToBeat == null || currentScore < scoreToBeat) {\n            scoreToBeat = currentScore;\n            bestMoment = tempConfig;\n        }\n    }\n\n    extend(config, bestMoment || tempConfig);\n}\n\nfunction configFromObject(config) {\n    if (config._d) {\n        return;\n    }\n\n    var i = normalizeObjectUnits(config._i);\n    config._a = map([i.year, i.month, i.day || i.date, i.hour, i.minute, i.second, i.millisecond], function (obj) {\n        return obj && parseInt(obj, 10);\n    });\n\n    configFromArray(config);\n}\n\nfunction createFromConfig (config) {\n    var res = new Moment(checkOverflow(prepareConfig(config)));\n    if (res._nextDay) {\n        // Adding is smart enough around DST\n        res.add(1, 'd');\n        res._nextDay = undefined;\n    }\n\n    return res;\n}\n\nfunction prepareConfig (config) {\n    var input = config._i,\n        format = config._f;\n\n    config._locale = config._locale || getLocale(config._l);\n\n    if (input === null || (format === undefined && input === '')) {\n        return createInvalid({nullInput: true});\n    }\n\n    if (typeof input === 'string') {\n        config._i = input = config._locale.preparse(input);\n    }\n\n    if (isMoment(input)) {\n        return new Moment(checkOverflow(input));\n    } else if (isDate(input)) {\n        config._d = input;\n    } else if (isArray(format)) {\n        configFromStringAndArray(config);\n    } else if (format) {\n        configFromStringAndFormat(config);\n    }  else {\n        configFromInput(config);\n    }\n\n    if (!isValid(config)) {\n        config._d = null;\n    }\n\n    return config;\n}\n\nfunction configFromInput(config) {\n    var input = config._i;\n    if (isUndefined(input)) {\n        config._d = new Date(hooks.now());\n    } else if (isDate(input)) {\n        config._d = new Date(input.valueOf());\n    } else if (typeof input === 'string') {\n        configFromString(config);\n    } else if (isArray(input)) {\n        config._a = map(input.slice(0), function (obj) {\n            return parseInt(obj, 10);\n        });\n        configFromArray(config);\n    } else if (isObject(input)) {\n        configFromObject(config);\n    } else if (isNumber(input)) {\n        // from milliseconds\n        config._d = new Date(input);\n    } else {\n        hooks.createFromInputFallback(config);\n    }\n}\n\nfunction createLocalOrUTC (input, format, locale, strict, isUTC) {\n    var c = {};\n\n    if (locale === true || locale === false) {\n        strict = locale;\n        locale = undefined;\n    }\n\n    if ((isObject(input) && isObjectEmpty(input)) ||\n            (isArray(input) && input.length === 0)) {\n        input = undefined;\n    }\n    // object construction must be done this way.\n    // https://github.com/moment/moment/issues/1423\n    c._isAMomentObject = true;\n    c._useUTC = c._isUTC = isUTC;\n    c._l = locale;\n    c._i = input;\n    c._f = format;\n    c._strict = strict;\n\n    return createFromConfig(c);\n}\n\nfunction createLocal (input, format, locale, strict) {\n    return createLocalOrUTC(input, format, locale, strict, false);\n}\n\nvar prototypeMin = deprecate(\n    'moment().min is deprecated, use moment.max instead. http://momentjs.com/guides/#/warnings/min-max/',\n    function () {\n        var other = createLocal.apply(null, arguments);\n        if (this.isValid() && other.isValid()) {\n            return other < this ? this : other;\n        } else {\n            return createInvalid();\n        }\n    }\n);\n\nvar prototypeMax = deprecate(\n    'moment().max is deprecated, use moment.min instead. http://momentjs.com/guides/#/warnings/min-max/',\n    function () {\n        var other = createLocal.apply(null, arguments);\n        if (this.isValid() && other.isValid()) {\n            return other > this ? this : other;\n        } else {\n            return createInvalid();\n        }\n    }\n);\n\n// Pick a moment m from moments so that m[fn](other) is true for all\n// other. This relies on the function fn to be transitive.\n//\n// moments should either be an array of moment objects or an array, whose\n// first element is an array of moment objects.\nfunction pickBy(fn, moments) {\n    var res, i;\n    if (moments.length === 1 && isArray(moments[0])) {\n        moments = moments[0];\n    }\n    if (!moments.length) {\n        return createLocal();\n    }\n    res = moments[0];\n    for (i = 1; i < moments.length; ++i) {\n        if (!moments[i].isValid() || moments[i][fn](res)) {\n            res = moments[i];\n        }\n    }\n    return res;\n}\n\n// TODO: Use [].sort instead?\nfunction min () {\n    var args = [].slice.call(arguments, 0);\n\n    return pickBy('isBefore', args);\n}\n\nfunction max () {\n    var args = [].slice.call(arguments, 0);\n\n    return pickBy('isAfter', args);\n}\n\nvar now = function () {\n    return Date.now ? Date.now() : +(new Date());\n};\n\nvar ordering = ['year', 'quarter', 'month', 'week', 'day', 'hour', 'minute', 'second', 'millisecond'];\n\nfunction isDurationValid(m) {\n    for (var key in m) {\n        if (!(ordering.indexOf(key) !== -1 && (m[key] == null || !isNaN(m[key])))) {\n            return false;\n        }\n    }\n\n    var unitHasDecimal = false;\n    for (var i = 0; i < ordering.length; ++i) {\n        if (m[ordering[i]]) {\n            if (unitHasDecimal) {\n                return false; // only allow non-integers for smallest unit\n            }\n            if (parseFloat(m[ordering[i]]) !== toInt(m[ordering[i]])) {\n                unitHasDecimal = true;\n            }\n        }\n    }\n\n    return true;\n}\n\nfunction isValid$1() {\n    return this._isValid;\n}\n\nfunction createInvalid$1() {\n    return createDuration(NaN);\n}\n\nfunction Duration (duration) {\n    var normalizedInput = normalizeObjectUnits(duration),\n        years = normalizedInput.year || 0,\n        quarters = normalizedInput.quarter || 0,\n        months = normalizedInput.month || 0,\n        weeks = normalizedInput.week || 0,\n        days = normalizedInput.day || 0,\n        hours = normalizedInput.hour || 0,\n        minutes = normalizedInput.minute || 0,\n        seconds = normalizedInput.second || 0,\n        milliseconds = normalizedInput.millisecond || 0;\n\n    this._isValid = isDurationValid(normalizedInput);\n\n    // representation for dateAddRemove\n    this._milliseconds = +milliseconds +\n        seconds * 1e3 + // 1000\n        minutes * 6e4 + // 1000 * 60\n        hours * 1000 * 60 * 60; //using 1000 * 60 * 60 instead of 36e5 to avoid floating point rounding errors https://github.com/moment/moment/issues/2978\n    // Because of dateAddRemove treats 24 hours as different from a\n    // day when working around DST, we need to store them separately\n    this._days = +days +\n        weeks * 7;\n    // It is impossible translate months into days without knowing\n    // which months you are are talking about, so we have to store\n    // it separately.\n    this._months = +months +\n        quarters * 3 +\n        years * 12;\n\n    this._data = {};\n\n    this._locale = getLocale();\n\n    this._bubble();\n}\n\nfunction isDuration (obj) {\n    return obj instanceof Duration;\n}\n\nfunction absRound (number) {\n    if (number < 0) {\n        return Math.round(-1 * number) * -1;\n    } else {\n        return Math.round(number);\n    }\n}\n\n// FORMATTING\n\nfunction offset (token, separator) {\n    addFormatToken(token, 0, 0, function () {\n        var offset = this.utcOffset();\n        var sign = '+';\n        if (offset < 0) {\n            offset = -offset;\n            sign = '-';\n        }\n        return sign + zeroFill(~~(offset / 60), 2) + separator + zeroFill(~~(offset) % 60, 2);\n    });\n}\n\noffset('Z', ':');\noffset('ZZ', '');\n\n// PARSING\n\naddRegexToken('Z',  matchShortOffset);\naddRegexToken('ZZ', matchShortOffset);\naddParseToken(['Z', 'ZZ'], function (input, array, config) {\n    config._useUTC = true;\n    config._tzm = offsetFromString(matchShortOffset, input);\n});\n\n// HELPERS\n\n// timezone chunker\n// '+10:00' > ['10',  '00']\n// '-1530'  > ['-15', '30']\nvar chunkOffset = /([\\+\\-]|\\d\\d)/gi;\n\nfunction offsetFromString(matcher, string) {\n    var matches = (string || '').match(matcher);\n\n    if (matches === null) {\n        return null;\n    }\n\n    var chunk   = matches[matches.length - 1] || [];\n    var parts   = (chunk + '').match(chunkOffset) || ['-', 0, 0];\n    var minutes = +(parts[1] * 60) + toInt(parts[2]);\n\n    return minutes === 0 ?\n      0 :\n      parts[0] === '+' ? minutes : -minutes;\n}\n\n// Return a moment from input, that is local/utc/zone equivalent to model.\nfunction cloneWithOffset(input, model) {\n    var res, diff;\n    if (model._isUTC) {\n        res = model.clone();\n        diff = (isMoment(input) || isDate(input) ? input.valueOf() : createLocal(input).valueOf()) - res.valueOf();\n        // Use low-level api, because this fn is low-level api.\n        res._d.setTime(res._d.valueOf() + diff);\n        hooks.updateOffset(res, false);\n        return res;\n    } else {\n        return createLocal(input).local();\n    }\n}\n\nfunction getDateOffset (m) {\n    // On Firefox.24 Date#getTimezoneOffset returns a floating point.\n    // https://github.com/moment/moment/pull/1871\n    return -Math.round(m._d.getTimezoneOffset() / 15) * 15;\n}\n\n// HOOKS\n\n// This function will be called whenever a moment is mutated.\n// It is intended to keep the offset in sync with the timezone.\nhooks.updateOffset = function () {};\n\n// MOMENTS\n\n// keepLocalTime = true means only change the timezone, without\n// affecting the local hour. So 5:31:26 +0300 --[utcOffset(2, true)]-->\n// 5:31:26 +0200 It is possible that 5:31:26 doesn't exist with offset\n// +0200, so we adjust the time as needed, to be valid.\n//\n// Keeping the time actually adds/subtracts (one hour)\n// from the actual represented time. That is why we call updateOffset\n// a second time. In case it wants us to change the offset again\n// _changeInProgress == true case, then we have to adjust, because\n// there is no such time in the given timezone.\nfunction getSetOffset (input, keepLocalTime, keepMinutes) {\n    var offset = this._offset || 0,\n        localAdjust;\n    if (!this.isValid()) {\n        return input != null ? this : NaN;\n    }\n    if (input != null) {\n        if (typeof input === 'string') {\n            input = offsetFromString(matchShortOffset, input);\n            if (input === null) {\n                return this;\n            }\n        } else if (Math.abs(input) < 16 && !keepMinutes) {\n            input = input * 60;\n        }\n        if (!this._isUTC && keepLocalTime) {\n            localAdjust = getDateOffset(this);\n        }\n        this._offset = input;\n        this._isUTC = true;\n        if (localAdjust != null) {\n            this.add(localAdjust, 'm');\n        }\n        if (offset !== input) {\n            if (!keepLocalTime || this._changeInProgress) {\n                addSubtract(this, createDuration(input - offset, 'm'), 1, false);\n            } else if (!this._changeInProgress) {\n                this._changeInProgress = true;\n                hooks.updateOffset(this, true);\n                this._changeInProgress = null;\n            }\n        }\n        return this;\n    } else {\n        return this._isUTC ? offset : getDateOffset(this);\n    }\n}\n\nfunction getSetZone (input, keepLocalTime) {\n    if (input != null) {\n        if (typeof input !== 'string') {\n            input = -input;\n        }\n\n        this.utcOffset(input, keepLocalTime);\n\n        return this;\n    } else {\n        return -this.utcOffset();\n    }\n}\n\nfunction setOffsetToUTC (keepLocalTime) {\n    return this.utcOffset(0, keepLocalTime);\n}\n\nfunction setOffsetToLocal (keepLocalTime) {\n    if (this._isUTC) {\n        this.utcOffset(0, keepLocalTime);\n        this._isUTC = false;\n\n        if (keepLocalTime) {\n            this.subtract(getDateOffset(this), 'm');\n        }\n    }\n    return this;\n}\n\nfunction setOffsetToParsedOffset () {\n    if (this._tzm != null) {\n        this.utcOffset(this._tzm, false, true);\n    } else if (typeof this._i === 'string') {\n        var tZone = offsetFromString(matchOffset, this._i);\n        if (tZone != null) {\n            this.utcOffset(tZone);\n        }\n        else {\n            this.utcOffset(0, true);\n        }\n    }\n    return this;\n}\n\nfunction hasAlignedHourOffset (input) {\n    if (!this.isValid()) {\n        return false;\n    }\n    input = input ? createLocal(input).utcOffset() : 0;\n\n    return (this.utcOffset() - input) % 60 === 0;\n}\n\nfunction isDaylightSavingTime () {\n    return (\n        this.utcOffset() > this.clone().month(0).utcOffset() ||\n        this.utcOffset() > this.clone().month(5).utcOffset()\n    );\n}\n\nfunction isDaylightSavingTimeShifted () {\n    if (!isUndefined(this._isDSTShifted)) {\n        return this._isDSTShifted;\n    }\n\n    var c = {};\n\n    copyConfig(c, this);\n    c = prepareConfig(c);\n\n    if (c._a) {\n        var other = c._isUTC ? createUTC(c._a) : createLocal(c._a);\n        this._isDSTShifted = this.isValid() &&\n            compareArrays(c._a, other.toArray()) > 0;\n    } else {\n        this._isDSTShifted = false;\n    }\n\n    return this._isDSTShifted;\n}\n\nfunction isLocal () {\n    return this.isValid() ? !this._isUTC : false;\n}\n\nfunction isUtcOffset () {\n    return this.isValid() ? this._isUTC : false;\n}\n\nfunction isUtc () {\n    return this.isValid() ? this._isUTC && this._offset === 0 : false;\n}\n\n// ASP.NET json date format regex\nvar aspNetRegex = /^(\\-)?(?:(\\d*)[. ])?(\\d+)\\:(\\d+)(?:\\:(\\d+)(\\.\\d*)?)?$/;\n\n// from http://docs.closure-library.googlecode.com/git/closure_goog_date_date.js.source.html\n// somewhat more in line with 4.4.3.2 2004 spec, but allows decimal anywhere\n// and further modified to allow for strings containing both week and day\nvar isoRegex = /^(-)?P(?:(-?[0-9,.]*)Y)?(?:(-?[0-9,.]*)M)?(?:(-?[0-9,.]*)W)?(?:(-?[0-9,.]*)D)?(?:T(?:(-?[0-9,.]*)H)?(?:(-?[0-9,.]*)M)?(?:(-?[0-9,.]*)S)?)?$/;\n\nfunction createDuration (input, key) {\n    var duration = input,\n        // matching against regexp is expensive, do it on demand\n        match = null,\n        sign,\n        ret,\n        diffRes;\n\n    if (isDuration(input)) {\n        duration = {\n            ms : input._milliseconds,\n            d  : input._days,\n            M  : input._months\n        };\n    } else if (isNumber(input)) {\n        duration = {};\n        if (key) {\n            duration[key] = input;\n        } else {\n            duration.milliseconds = input;\n        }\n    } else if (!!(match = aspNetRegex.exec(input))) {\n        sign = (match[1] === '-') ? -1 : 1;\n        duration = {\n            y  : 0,\n            d  : toInt(match[DATE])                         * sign,\n            h  : toInt(match[HOUR])                         * sign,\n            m  : toInt(match[MINUTE])                       * sign,\n            s  : toInt(match[SECOND])                       * sign,\n            ms : toInt(absRound(match[MILLISECOND] * 1000)) * sign // the millisecond decimal point is included in the match\n        };\n    } else if (!!(match = isoRegex.exec(input))) {\n        sign = (match[1] === '-') ? -1 : 1;\n        duration = {\n            y : parseIso(match[2], sign),\n            M : parseIso(match[3], sign),\n            w : parseIso(match[4], sign),\n            d : parseIso(match[5], sign),\n            h : parseIso(match[6], sign),\n            m : parseIso(match[7], sign),\n            s : parseIso(match[8], sign)\n        };\n    } else if (duration == null) {// checks for null or undefined\n        duration = {};\n    } else if (typeof duration === 'object' && ('from' in duration || 'to' in duration)) {\n        diffRes = momentsDifference(createLocal(duration.from), createLocal(duration.to));\n\n        duration = {};\n        duration.ms = diffRes.milliseconds;\n        duration.M = diffRes.months;\n    }\n\n    ret = new Duration(duration);\n\n    if (isDuration(input) && hasOwnProp(input, '_locale')) {\n        ret._locale = input._locale;\n    }\n\n    return ret;\n}\n\ncreateDuration.fn = Duration.prototype;\ncreateDuration.invalid = createInvalid$1;\n\nfunction parseIso (inp, sign) {\n    // We'd normally use ~~inp for this, but unfortunately it also\n    // converts floats to ints.\n    // inp may be undefined, so careful calling replace on it.\n    var res = inp && parseFloat(inp.replace(',', '.'));\n    // apply sign while we're at it\n    return (isNaN(res) ? 0 : res) * sign;\n}\n\nfunction positiveMomentsDifference(base, other) {\n    var res = {milliseconds: 0, months: 0};\n\n    res.months = other.month() - base.month() +\n        (other.year() - base.year()) * 12;\n    if (base.clone().add(res.months, 'M').isAfter(other)) {\n        --res.months;\n    }\n\n    res.milliseconds = +other - +(base.clone().add(res.months, 'M'));\n\n    return res;\n}\n\nfunction momentsDifference(base, other) {\n    var res;\n    if (!(base.isValid() && other.isValid())) {\n        return {milliseconds: 0, months: 0};\n    }\n\n    other = cloneWithOffset(other, base);\n    if (base.isBefore(other)) {\n        res = positiveMomentsDifference(base, other);\n    } else {\n        res = positiveMomentsDifference(other, base);\n        res.milliseconds = -res.milliseconds;\n        res.months = -res.months;\n    }\n\n    return res;\n}\n\n// TODO: remove 'name' arg after deprecation is removed\nfunction createAdder(direction, name) {\n    return function (val, period) {\n        var dur, tmp;\n        //invert the arguments, but complain about it\n        if (period !== null && !isNaN(+period)) {\n            deprecateSimple(name, 'moment().' + name  + '(period, number) is deprecated. Please use moment().' + name + '(number, period). ' +\n            'See http://momentjs.com/guides/#/warnings/add-inverted-param/ for more info.');\n            tmp = val; val = period; period = tmp;\n        }\n\n        val = typeof val === 'string' ? +val : val;\n        dur = createDuration(val, period);\n        addSubtract(this, dur, direction);\n        return this;\n    };\n}\n\nfunction addSubtract (mom, duration, isAdding, updateOffset) {\n    var milliseconds = duration._milliseconds,\n        days = absRound(duration._days),\n        months = absRound(duration._months);\n\n    if (!mom.isValid()) {\n        // No op\n        return;\n    }\n\n    updateOffset = updateOffset == null ? true : updateOffset;\n\n    if (milliseconds) {\n        mom._d.setTime(mom._d.valueOf() + milliseconds * isAdding);\n    }\n    if (days) {\n        set$1(mom, 'Date', get(mom, 'Date') + days * isAdding);\n    }\n    if (months) {\n        setMonth(mom, get(mom, 'Month') + months * isAdding);\n    }\n    if (updateOffset) {\n        hooks.updateOffset(mom, days || months);\n    }\n}\n\nvar add      = createAdder(1, 'add');\nvar subtract = createAdder(-1, 'subtract');\n\nfunction getCalendarFormat(myMoment, now) {\n    var diff = myMoment.diff(now, 'days', true);\n    return diff < -6 ? 'sameElse' :\n            diff < -1 ? 'lastWeek' :\n            diff < 0 ? 'lastDay' :\n            diff < 1 ? 'sameDay' :\n            diff < 2 ? 'nextDay' :\n            diff < 7 ? 'nextWeek' : 'sameElse';\n}\n\nfunction calendar$1 (time, formats) {\n    // We want to compare the start of today, vs this.\n    // Getting start-of-today depends on whether we're local/utc/offset or not.\n    var now = time || createLocal(),\n        sod = cloneWithOffset(now, this).startOf('day'),\n        format = hooks.calendarFormat(this, sod) || 'sameElse';\n\n    var output = formats && (isFunction(formats[format]) ? formats[format].call(this, now) : formats[format]);\n\n    return this.format(output || this.localeData().calendar(format, this, createLocal(now)));\n}\n\nfunction clone () {\n    return new Moment(this);\n}\n\nfunction isAfter (input, units) {\n    var localInput = isMoment(input) ? input : createLocal(input);\n    if (!(this.isValid() && localInput.isValid())) {\n        return false;\n    }\n    units = normalizeUnits(!isUndefined(units) ? units : 'millisecond');\n    if (units === 'millisecond') {\n        return this.valueOf() > localInput.valueOf();\n    } else {\n        return localInput.valueOf() < this.clone().startOf(units).valueOf();\n    }\n}\n\nfunction isBefore (input, units) {\n    var localInput = isMoment(input) ? input : createLocal(input);\n    if (!(this.isValid() && localInput.isValid())) {\n        return false;\n    }\n    units = normalizeUnits(!isUndefined(units) ? units : 'millisecond');\n    if (units === 'millisecond') {\n        return this.valueOf() < localInput.valueOf();\n    } else {\n        return this.clone().endOf(units).valueOf() < localInput.valueOf();\n    }\n}\n\nfunction isBetween (from, to, units, inclusivity) {\n    inclusivity = inclusivity || '()';\n    return (inclusivity[0] === '(' ? this.isAfter(from, units) : !this.isBefore(from, units)) &&\n        (inclusivity[1] === ')' ? this.isBefore(to, units) : !this.isAfter(to, units));\n}\n\nfunction isSame (input, units) {\n    var localInput = isMoment(input) ? input : createLocal(input),\n        inputMs;\n    if (!(this.isValid() && localInput.isValid())) {\n        return false;\n    }\n    units = normalizeUnits(units || 'millisecond');\n    if (units === 'millisecond') {\n        return this.valueOf() === localInput.valueOf();\n    } else {\n        inputMs = localInput.valueOf();\n        return this.clone().startOf(units).valueOf() <= inputMs && inputMs <= this.clone().endOf(units).valueOf();\n    }\n}\n\nfunction isSameOrAfter (input, units) {\n    return this.isSame(input, units) || this.isAfter(input,units);\n}\n\nfunction isSameOrBefore (input, units) {\n    return this.isSame(input, units) || this.isBefore(input,units);\n}\n\nfunction diff (input, units, asFloat) {\n    var that,\n        zoneDelta,\n        delta, output;\n\n    if (!this.isValid()) {\n        return NaN;\n    }\n\n    that = cloneWithOffset(input, this);\n\n    if (!that.isValid()) {\n        return NaN;\n    }\n\n    zoneDelta = (that.utcOffset() - this.utcOffset()) * 6e4;\n\n    units = normalizeUnits(units);\n\n    if (units === 'year' || units === 'month' || units === 'quarter') {\n        output = monthDiff(this, that);\n        if (units === 'quarter') {\n            output = output / 3;\n        } else if (units === 'year') {\n            output = output / 12;\n        }\n    } else {\n        delta = this - that;\n        output = units === 'second' ? delta / 1e3 : // 1000\n            units === 'minute' ? delta / 6e4 : // 1000 * 60\n            units === 'hour' ? delta / 36e5 : // 1000 * 60 * 60\n            units === 'day' ? (delta - zoneDelta) / 864e5 : // 1000 * 60 * 60 * 24, negate dst\n            units === 'week' ? (delta - zoneDelta) / 6048e5 : // 1000 * 60 * 60 * 24 * 7, negate dst\n            delta;\n    }\n    return asFloat ? output : absFloor(output);\n}\n\nfunction monthDiff (a, b) {\n    // difference in months\n    var wholeMonthDiff = ((b.year() - a.year()) * 12) + (b.month() - a.month()),\n        // b is in (anchor - 1 month, anchor + 1 month)\n        anchor = a.clone().add(wholeMonthDiff, 'months'),\n        anchor2, adjust;\n\n    if (b - anchor < 0) {\n        anchor2 = a.clone().add(wholeMonthDiff - 1, 'months');\n        // linear across the month\n        adjust = (b - anchor) / (anchor - anchor2);\n    } else {\n        anchor2 = a.clone().add(wholeMonthDiff + 1, 'months');\n        // linear across the month\n        adjust = (b - anchor) / (anchor2 - anchor);\n    }\n\n    //check for negative zero, return zero if negative zero\n    return -(wholeMonthDiff + adjust) || 0;\n}\n\nhooks.defaultFormat = 'YYYY-MM-DDTHH:mm:ssZ';\nhooks.defaultFormatUtc = 'YYYY-MM-DDTHH:mm:ss[Z]';\n\nfunction toString () {\n    return this.clone().locale('en').format('ddd MMM DD YYYY HH:mm:ss [GMT]ZZ');\n}\n\nfunction toISOString() {\n    if (!this.isValid()) {\n        return null;\n    }\n    var m = this.clone().utc();\n    if (m.year() < 0 || m.year() > 9999) {\n        return formatMoment(m, 'YYYYYY-MM-DD[T]HH:mm:ss.SSS[Z]');\n    }\n    if (isFunction(Date.prototype.toISOString)) {\n        // native implementation is ~50x faster, use it when we can\n        return this.toDate().toISOString();\n    }\n    return formatMoment(m, 'YYYY-MM-DD[T]HH:mm:ss.SSS[Z]');\n}\n\n/**\n * Return a human readable representation of a moment that can\n * also be evaluated to get a new moment which is the same\n *\n * @link https://nodejs.org/dist/latest/docs/api/util.html#util_custom_inspect_function_on_objects\n */\nfunction inspect () {\n    if (!this.isValid()) {\n        return 'moment.invalid(/* ' + this._i + ' */)';\n    }\n    var func = 'moment';\n    var zone = '';\n    if (!this.isLocal()) {\n        func = this.utcOffset() === 0 ? 'moment.utc' : 'moment.parseZone';\n        zone = 'Z';\n    }\n    var prefix = '[' + func + '(\"]';\n    var year = (0 <= this.year() && this.year() <= 9999) ? 'YYYY' : 'YYYYYY';\n    var datetime = '-MM-DD[T]HH:mm:ss.SSS';\n    var suffix = zone + '[\")]';\n\n    return this.format(prefix + year + datetime + suffix);\n}\n\nfunction format (inputString) {\n    if (!inputString) {\n        inputString = this.isUtc() ? hooks.defaultFormatUtc : hooks.defaultFormat;\n    }\n    var output = formatMoment(this, inputString);\n    return this.localeData().postformat(output);\n}\n\nfunction from (time, withoutSuffix) {\n    if (this.isValid() &&\n            ((isMoment(time) && time.isValid()) ||\n             createLocal(time).isValid())) {\n        return createDuration({to: this, from: time}).locale(this.locale()).humanize(!withoutSuffix);\n    } else {\n        return this.localeData().invalidDate();\n    }\n}\n\nfunction fromNow (withoutSuffix) {\n    return this.from(createLocal(), withoutSuffix);\n}\n\nfunction to (time, withoutSuffix) {\n    if (this.isValid() &&\n            ((isMoment(time) && time.isValid()) ||\n             createLocal(time).isValid())) {\n        return createDuration({from: this, to: time}).locale(this.locale()).humanize(!withoutSuffix);\n    } else {\n        return this.localeData().invalidDate();\n    }\n}\n\nfunction toNow (withoutSuffix) {\n    return this.to(createLocal(), withoutSuffix);\n}\n\n// If passed a locale key, it will set the locale for this\n// instance.  Otherwise, it will return the locale configuration\n// variables for this instance.\nfunction locale (key) {\n    var newLocaleData;\n\n    if (key === undefined) {\n        return this._locale._abbr;\n    } else {\n        newLocaleData = getLocale(key);\n        if (newLocaleData != null) {\n            this._locale = newLocaleData;\n        }\n        return this;\n    }\n}\n\nvar lang = deprecate(\n    'moment().lang() is deprecated. Instead, use moment().localeData() to get the language configuration. Use moment().locale() to change languages.',\n    function (key) {\n        if (key === undefined) {\n            return this.localeData();\n        } else {\n            return this.locale(key);\n        }\n    }\n);\n\nfunction localeData () {\n    return this._locale;\n}\n\nfunction startOf (units) {\n    units = normalizeUnits(units);\n    // the following switch intentionally omits break keywords\n    // to utilize falling through the cases.\n    switch (units) {\n        case 'year':\n            this.month(0);\n            /* falls through */\n        case 'quarter':\n        case 'month':\n            this.date(1);\n            /* falls through */\n        case 'week':\n        case 'isoWeek':\n        case 'day':\n        case 'date':\n            this.hours(0);\n            /* falls through */\n        case 'hour':\n            this.minutes(0);\n            /* falls through */\n        case 'minute':\n            this.seconds(0);\n            /* falls through */\n        case 'second':\n            this.milliseconds(0);\n    }\n\n    // weeks are a special case\n    if (units === 'week') {\n        this.weekday(0);\n    }\n    if (units === 'isoWeek') {\n        this.isoWeekday(1);\n    }\n\n    // quarters are also special\n    if (units === 'quarter') {\n        this.month(Math.floor(this.month() / 3) * 3);\n    }\n\n    return this;\n}\n\nfunction endOf (units) {\n    units = normalizeUnits(units);\n    if (units === undefined || units === 'millisecond') {\n        return this;\n    }\n\n    // 'date' is an alias for 'day', so it should be considered as such.\n    if (units === 'date') {\n        units = 'day';\n    }\n\n    return this.startOf(units).add(1, (units === 'isoWeek' ? 'week' : units)).subtract(1, 'ms');\n}\n\nfunction valueOf () {\n    return this._d.valueOf() - ((this._offset || 0) * 60000);\n}\n\nfunction unix () {\n    return Math.floor(this.valueOf() / 1000);\n}\n\nfunction toDate () {\n    return new Date(this.valueOf());\n}\n\nfunction toArray () {\n    var m = this;\n    return [m.year(), m.month(), m.date(), m.hour(), m.minute(), m.second(), m.millisecond()];\n}\n\nfunction toObject () {\n    var m = this;\n    return {\n        years: m.year(),\n        months: m.month(),\n        date: m.date(),\n        hours: m.hours(),\n        minutes: m.minutes(),\n        seconds: m.seconds(),\n        milliseconds: m.milliseconds()\n    };\n}\n\nfunction toJSON () {\n    // new Date(NaN).toJSON() === null\n    return this.isValid() ? this.toISOString() : null;\n}\n\nfunction isValid$2 () {\n    return isValid(this);\n}\n\nfunction parsingFlags () {\n    return extend({}, getParsingFlags(this));\n}\n\nfunction invalidAt () {\n    return getParsingFlags(this).overflow;\n}\n\nfunction creationData() {\n    return {\n        input: this._i,\n        format: this._f,\n        locale: this._locale,\n        isUTC: this._isUTC,\n        strict: this._strict\n    };\n}\n\n// FORMATTING\n\naddFormatToken(0, ['gg', 2], 0, function () {\n    return this.weekYear() % 100;\n});\n\naddFormatToken(0, ['GG', 2], 0, function () {\n    return this.isoWeekYear() % 100;\n});\n\nfunction addWeekYearFormatToken (token, getter) {\n    addFormatToken(0, [token, token.length], 0, getter);\n}\n\naddWeekYearFormatToken('gggg',     'weekYear');\naddWeekYearFormatToken('ggggg',    'weekYear');\naddWeekYearFormatToken('GGGG',  'isoWeekYear');\naddWeekYearFormatToken('GGGGG', 'isoWeekYear');\n\n// ALIASES\n\naddUnitAlias('weekYear', 'gg');\naddUnitAlias('isoWeekYear', 'GG');\n\n// PRIORITY\n\naddUnitPriority('weekYear', 1);\naddUnitPriority('isoWeekYear', 1);\n\n\n// PARSING\n\naddRegexToken('G',      matchSigned);\naddRegexToken('g',      matchSigned);\naddRegexToken('GG',     match1to2, match2);\naddRegexToken('gg',     match1to2, match2);\naddRegexToken('GGGG',   match1to4, match4);\naddRegexToken('gggg',   match1to4, match4);\naddRegexToken('GGGGG',  match1to6, match6);\naddRegexToken('ggggg',  match1to6, match6);\n\naddWeekParseToken(['gggg', 'ggggg', 'GGGG', 'GGGGG'], function (input, week, config, token) {\n    week[token.substr(0, 2)] = toInt(input);\n});\n\naddWeekParseToken(['gg', 'GG'], function (input, week, config, token) {\n    week[token] = hooks.parseTwoDigitYear(input);\n});\n\n// MOMENTS\n\nfunction getSetWeekYear (input) {\n    return getSetWeekYearHelper.call(this,\n            input,\n            this.week(),\n            this.weekday(),\n            this.localeData()._week.dow,\n            this.localeData()._week.doy);\n}\n\nfunction getSetISOWeekYear (input) {\n    return getSetWeekYearHelper.call(this,\n            input, this.isoWeek(), this.isoWeekday(), 1, 4);\n}\n\nfunction getISOWeeksInYear () {\n    return weeksInYear(this.year(), 1, 4);\n}\n\nfunction getWeeksInYear () {\n    var weekInfo = this.localeData()._week;\n    return weeksInYear(this.year(), weekInfo.dow, weekInfo.doy);\n}\n\nfunction getSetWeekYearHelper(input, week, weekday, dow, doy) {\n    var weeksTarget;\n    if (input == null) {\n        return weekOfYear(this, dow, doy).year;\n    } else {\n        weeksTarget = weeksInYear(input, dow, doy);\n        if (week > weeksTarget) {\n            week = weeksTarget;\n        }\n        return setWeekAll.call(this, input, week, weekday, dow, doy);\n    }\n}\n\nfunction setWeekAll(weekYear, week, weekday, dow, doy) {\n    var dayOfYearData = dayOfYearFromWeeks(weekYear, week, weekday, dow, doy),\n        date = createUTCDate(dayOfYearData.year, 0, dayOfYearData.dayOfYear);\n\n    this.year(date.getUTCFullYear());\n    this.month(date.getUTCMonth());\n    this.date(date.getUTCDate());\n    return this;\n}\n\n// FORMATTING\n\naddFormatToken('Q', 0, 'Qo', 'quarter');\n\n// ALIASES\n\naddUnitAlias('quarter', 'Q');\n\n// PRIORITY\n\naddUnitPriority('quarter', 7);\n\n// PARSING\n\naddRegexToken('Q', match1);\naddParseToken('Q', function (input, array) {\n    array[MONTH] = (toInt(input) - 1) * 3;\n});\n\n// MOMENTS\n\nfunction getSetQuarter (input) {\n    return input == null ? Math.ceil((this.month() + 1) / 3) : this.month((input - 1) * 3 + this.month() % 3);\n}\n\n// FORMATTING\n\naddFormatToken('D', ['DD', 2], 'Do', 'date');\n\n// ALIASES\n\naddUnitAlias('date', 'D');\n\n// PRIOROITY\naddUnitPriority('date', 9);\n\n// PARSING\n\naddRegexToken('D',  match1to2);\naddRegexToken('DD', match1to2, match2);\naddRegexToken('Do', function (isStrict, locale) {\n    // TODO: Remove \"ordinalParse\" fallback in next major release.\n    return isStrict ?\n      (locale._dayOfMonthOrdinalParse || locale._ordinalParse) :\n      locale._dayOfMonthOrdinalParseLenient;\n});\n\naddParseToken(['D', 'DD'], DATE);\naddParseToken('Do', function (input, array) {\n    array[DATE] = toInt(input.match(match1to2)[0], 10);\n});\n\n// MOMENTS\n\nvar getSetDayOfMonth = makeGetSet('Date', true);\n\n// FORMATTING\n\naddFormatToken('DDD', ['DDDD', 3], 'DDDo', 'dayOfYear');\n\n// ALIASES\n\naddUnitAlias('dayOfYear', 'DDD');\n\n// PRIORITY\naddUnitPriority('dayOfYear', 4);\n\n// PARSING\n\naddRegexToken('DDD',  match1to3);\naddRegexToken('DDDD', match3);\naddParseToken(['DDD', 'DDDD'], function (input, array, config) {\n    config._dayOfYear = toInt(input);\n});\n\n// HELPERS\n\n// MOMENTS\n\nfunction getSetDayOfYear (input) {\n    var dayOfYear = Math.round((this.clone().startOf('day') - this.clone().startOf('year')) / 864e5) + 1;\n    return input == null ? dayOfYear : this.add((input - dayOfYear), 'd');\n}\n\n// FORMATTING\n\naddFormatToken('m', ['mm', 2], 0, 'minute');\n\n// ALIASES\n\naddUnitAlias('minute', 'm');\n\n// PRIORITY\n\naddUnitPriority('minute', 14);\n\n// PARSING\n\naddRegexToken('m',  match1to2);\naddRegexToken('mm', match1to2, match2);\naddParseToken(['m', 'mm'], MINUTE);\n\n// MOMENTS\n\nvar getSetMinute = makeGetSet('Minutes', false);\n\n// FORMATTING\n\naddFormatToken('s', ['ss', 2], 0, 'second');\n\n// ALIASES\n\naddUnitAlias('second', 's');\n\n// PRIORITY\n\naddUnitPriority('second', 15);\n\n// PARSING\n\naddRegexToken('s',  match1to2);\naddRegexToken('ss', match1to2, match2);\naddParseToken(['s', 'ss'], SECOND);\n\n// MOMENTS\n\nvar getSetSecond = makeGetSet('Seconds', false);\n\n// FORMATTING\n\naddFormatToken('S', 0, 0, function () {\n    return ~~(this.millisecond() / 100);\n});\n\naddFormatToken(0, ['SS', 2], 0, function () {\n    return ~~(this.millisecond() / 10);\n});\n\naddFormatToken(0, ['SSS', 3], 0, 'millisecond');\naddFormatToken(0, ['SSSS', 4], 0, function () {\n    return this.millisecond() * 10;\n});\naddFormatToken(0, ['SSSSS', 5], 0, function () {\n    return this.millisecond() * 100;\n});\naddFormatToken(0, ['SSSSSS', 6], 0, function () {\n    return this.millisecond() * 1000;\n});\naddFormatToken(0, ['SSSSSSS', 7], 0, function () {\n    return this.millisecond() * 10000;\n});\naddFormatToken(0, ['SSSSSSSS', 8], 0, function () {\n    return this.millisecond() * 100000;\n});\naddFormatToken(0, ['SSSSSSSSS', 9], 0, function () {\n    return this.millisecond() * 1000000;\n});\n\n\n// ALIASES\n\naddUnitAlias('millisecond', 'ms');\n\n// PRIORITY\n\naddUnitPriority('millisecond', 16);\n\n// PARSING\n\naddRegexToken('S',    match1to3, match1);\naddRegexToken('SS',   match1to3, match2);\naddRegexToken('SSS',  match1to3, match3);\n\nvar token;\nfor (token = 'SSSS'; token.length <= 9; token += 'S') {\n    addRegexToken(token, matchUnsigned);\n}\n\nfunction parseMs(input, array) {\n    array[MILLISECOND] = toInt(('0.' + input) * 1000);\n}\n\nfor (token = 'S'; token.length <= 9; token += 'S') {\n    addParseToken(token, parseMs);\n}\n// MOMENTS\n\nvar getSetMillisecond = makeGetSet('Milliseconds', false);\n\n// FORMATTING\n\naddFormatToken('z',  0, 0, 'zoneAbbr');\naddFormatToken('zz', 0, 0, 'zoneName');\n\n// MOMENTS\n\nfunction getZoneAbbr () {\n    return this._isUTC ? 'UTC' : '';\n}\n\nfunction getZoneName () {\n    return this._isUTC ? 'Coordinated Universal Time' : '';\n}\n\nvar proto = Moment.prototype;\n\nproto.add               = add;\nproto.calendar          = calendar$1;\nproto.clone             = clone;\nproto.diff              = diff;\nproto.endOf             = endOf;\nproto.format            = format;\nproto.from              = from;\nproto.fromNow           = fromNow;\nproto.to                = to;\nproto.toNow             = toNow;\nproto.get               = stringGet;\nproto.invalidAt         = invalidAt;\nproto.isAfter           = isAfter;\nproto.isBefore          = isBefore;\nproto.isBetween         = isBetween;\nproto.isSame            = isSame;\nproto.isSameOrAfter     = isSameOrAfter;\nproto.isSameOrBefore    = isSameOrBefore;\nproto.isValid           = isValid$2;\nproto.lang              = lang;\nproto.locale            = locale;\nproto.localeData        = localeData;\nproto.max               = prototypeMax;\nproto.min               = prototypeMin;\nproto.parsingFlags      = parsingFlags;\nproto.set               = stringSet;\nproto.startOf           = startOf;\nproto.subtract          = subtract;\nproto.toArray           = toArray;\nproto.toObject          = toObject;\nproto.toDate            = toDate;\nproto.toISOString       = toISOString;\nproto.inspect           = inspect;\nproto.toJSON            = toJSON;\nproto.toString          = toString;\nproto.unix              = unix;\nproto.valueOf           = valueOf;\nproto.creationData      = creationData;\n\n// Year\nproto.year       = getSetYear;\nproto.isLeapYear = getIsLeapYear;\n\n// Week Year\nproto.weekYear    = getSetWeekYear;\nproto.isoWeekYear = getSetISOWeekYear;\n\n// Quarter\nproto.quarter = proto.quarters = getSetQuarter;\n\n// Month\nproto.month       = getSetMonth;\nproto.daysInMonth = getDaysInMonth;\n\n// Week\nproto.week           = proto.weeks        = getSetWeek;\nproto.isoWeek        = proto.isoWeeks     = getSetISOWeek;\nproto.weeksInYear    = getWeeksInYear;\nproto.isoWeeksInYear = getISOWeeksInYear;\n\n// Day\nproto.date       = getSetDayOfMonth;\nproto.day        = proto.days             = getSetDayOfWeek;\nproto.weekday    = getSetLocaleDayOfWeek;\nproto.isoWeekday = getSetISODayOfWeek;\nproto.dayOfYear  = getSetDayOfYear;\n\n// Hour\nproto.hour = proto.hours = getSetHour;\n\n// Minute\nproto.minute = proto.minutes = getSetMinute;\n\n// Second\nproto.second = proto.seconds = getSetSecond;\n\n// Millisecond\nproto.millisecond = proto.milliseconds = getSetMillisecond;\n\n// Offset\nproto.utcOffset            = getSetOffset;\nproto.utc                  = setOffsetToUTC;\nproto.local                = setOffsetToLocal;\nproto.parseZone            = setOffsetToParsedOffset;\nproto.hasAlignedHourOffset = hasAlignedHourOffset;\nproto.isDST                = isDaylightSavingTime;\nproto.isLocal              = isLocal;\nproto.isUtcOffset          = isUtcOffset;\nproto.isUtc                = isUtc;\nproto.isUTC                = isUtc;\n\n// Timezone\nproto.zoneAbbr = getZoneAbbr;\nproto.zoneName = getZoneName;\n\n// Deprecations\nproto.dates  = deprecate('dates accessor is deprecated. Use date instead.', getSetDayOfMonth);\nproto.months = deprecate('months accessor is deprecated. Use month instead', getSetMonth);\nproto.years  = deprecate('years accessor is deprecated. Use year instead', getSetYear);\nproto.zone   = deprecate('moment().zone is deprecated, use moment().utcOffset instead. http://momentjs.com/guides/#/warnings/zone/', getSetZone);\nproto.isDSTShifted = deprecate('isDSTShifted is deprecated. See http://momentjs.com/guides/#/warnings/dst-shifted/ for more information', isDaylightSavingTimeShifted);\n\nfunction createUnix (input) {\n    return createLocal(input * 1000);\n}\n\nfunction createInZone () {\n    return createLocal.apply(null, arguments).parseZone();\n}\n\nfunction preParsePostFormat (string) {\n    return string;\n}\n\nvar proto$1 = Locale.prototype;\n\nproto$1.calendar        = calendar;\nproto$1.longDateFormat  = longDateFormat;\nproto$1.invalidDate     = invalidDate;\nproto$1.ordinal         = ordinal;\nproto$1.preparse        = preParsePostFormat;\nproto$1.postformat      = preParsePostFormat;\nproto$1.relativeTime    = relativeTime;\nproto$1.pastFuture      = pastFuture;\nproto$1.set             = set;\n\n// Month\nproto$1.months            =        localeMonths;\nproto$1.monthsShort       =        localeMonthsShort;\nproto$1.monthsParse       =        localeMonthsParse;\nproto$1.monthsRegex       = monthsRegex;\nproto$1.monthsShortRegex  = monthsShortRegex;\n\n// Week\nproto$1.week = localeWeek;\nproto$1.firstDayOfYear = localeFirstDayOfYear;\nproto$1.firstDayOfWeek = localeFirstDayOfWeek;\n\n// Day of Week\nproto$1.weekdays       =        localeWeekdays;\nproto$1.weekdaysMin    =        localeWeekdaysMin;\nproto$1.weekdaysShort  =        localeWeekdaysShort;\nproto$1.weekdaysParse  =        localeWeekdaysParse;\n\nproto$1.weekdaysRegex       =        weekdaysRegex;\nproto$1.weekdaysShortRegex  =        weekdaysShortRegex;\nproto$1.weekdaysMinRegex    =        weekdaysMinRegex;\n\n// Hours\nproto$1.isPM = localeIsPM;\nproto$1.meridiem = localeMeridiem;\n\nfunction get$1 (format, index, field, setter) {\n    var locale = getLocale();\n    var utc = createUTC().set(setter, index);\n    return locale[field](utc, format);\n}\n\nfunction listMonthsImpl (format, index, field) {\n    if (isNumber(format)) {\n        index = format;\n        format = undefined;\n    }\n\n    format = format || '';\n\n    if (index != null) {\n        return get$1(format, index, field, 'month');\n    }\n\n    var i;\n    var out = [];\n    for (i = 0; i < 12; i++) {\n        out[i] = get$1(format, i, field, 'month');\n    }\n    return out;\n}\n\n// ()\n// (5)\n// (fmt, 5)\n// (fmt)\n// (true)\n// (true, 5)\n// (true, fmt, 5)\n// (true, fmt)\nfunction listWeekdaysImpl (localeSorted, format, index, field) {\n    if (typeof localeSorted === 'boolean') {\n        if (isNumber(format)) {\n            index = format;\n            format = undefined;\n        }\n\n        format = format || '';\n    } else {\n        format = localeSorted;\n        index = format;\n        localeSorted = false;\n\n        if (isNumber(format)) {\n            index = format;\n            format = undefined;\n        }\n\n        format = format || '';\n    }\n\n    var locale = getLocale(),\n        shift = localeSorted ? locale._week.dow : 0;\n\n    if (index != null) {\n        return get$1(format, (index + shift) % 7, field, 'day');\n    }\n\n    var i;\n    var out = [];\n    for (i = 0; i < 7; i++) {\n        out[i] = get$1(format, (i + shift) % 7, field, 'day');\n    }\n    return out;\n}\n\nfunction listMonths (format, index) {\n    return listMonthsImpl(format, index, 'months');\n}\n\nfunction listMonthsShort (format, index) {\n    return listMonthsImpl(format, index, 'monthsShort');\n}\n\nfunction listWeekdays (localeSorted, format, index) {\n    return listWeekdaysImpl(localeSorted, format, index, 'weekdays');\n}\n\nfunction listWeekdaysShort (localeSorted, format, index) {\n    return listWeekdaysImpl(localeSorted, format, index, 'weekdaysShort');\n}\n\nfunction listWeekdaysMin (localeSorted, format, index) {\n    return listWeekdaysImpl(localeSorted, format, index, 'weekdaysMin');\n}\n\ngetSetGlobalLocale('en', {\n    dayOfMonthOrdinalParse: /\\d{1,2}(th|st|nd|rd)/,\n    ordinal : function (number) {\n        var b = number % 10,\n            output = (toInt(number % 100 / 10) === 1) ? 'th' :\n            (b === 1) ? 'st' :\n            (b === 2) ? 'nd' :\n            (b === 3) ? 'rd' : 'th';\n        return number + output;\n    }\n});\n\n// Side effect imports\nhooks.lang = deprecate('moment.lang is deprecated. Use moment.locale instead.', getSetGlobalLocale);\nhooks.langData = deprecate('moment.langData is deprecated. Use moment.localeData instead.', getLocale);\n\nvar mathAbs = Math.abs;\n\nfunction abs () {\n    var data           = this._data;\n\n    this._milliseconds = mathAbs(this._milliseconds);\n    this._days         = mathAbs(this._days);\n    this._months       = mathAbs(this._months);\n\n    data.milliseconds  = mathAbs(data.milliseconds);\n    data.seconds       = mathAbs(data.seconds);\n    data.minutes       = mathAbs(data.minutes);\n    data.hours         = mathAbs(data.hours);\n    data.months        = mathAbs(data.months);\n    data.years         = mathAbs(data.years);\n\n    return this;\n}\n\nfunction addSubtract$1 (duration, input, value, direction) {\n    var other = createDuration(input, value);\n\n    duration._milliseconds += direction * other._milliseconds;\n    duration._days         += direction * other._days;\n    duration._months       += direction * other._months;\n\n    return duration._bubble();\n}\n\n// supports only 2.0-style add(1, 's') or add(duration)\nfunction add$1 (input, value) {\n    return addSubtract$1(this, input, value, 1);\n}\n\n// supports only 2.0-style subtract(1, 's') or subtract(duration)\nfunction subtract$1 (input, value) {\n    return addSubtract$1(this, input, value, -1);\n}\n\nfunction absCeil (number) {\n    if (number < 0) {\n        return Math.floor(number);\n    } else {\n        return Math.ceil(number);\n    }\n}\n\nfunction bubble () {\n    var milliseconds = this._milliseconds;\n    var days         = this._days;\n    var months       = this._months;\n    var data         = this._data;\n    var seconds, minutes, hours, years, monthsFromDays;\n\n    // if we have a mix of positive and negative values, bubble down first\n    // check: https://github.com/moment/moment/issues/2166\n    if (!((milliseconds >= 0 && days >= 0 && months >= 0) ||\n            (milliseconds <= 0 && days <= 0 && months <= 0))) {\n        milliseconds += absCeil(monthsToDays(months) + days) * 864e5;\n        days = 0;\n        months = 0;\n    }\n\n    // The following code bubbles up values, see the tests for\n    // examples of what that means.\n    data.milliseconds = milliseconds % 1000;\n\n    seconds           = absFloor(milliseconds / 1000);\n    data.seconds      = seconds % 60;\n\n    minutes           = absFloor(seconds / 60);\n    data.minutes      = minutes % 60;\n\n    hours             = absFloor(minutes / 60);\n    data.hours        = hours % 24;\n\n    days += absFloor(hours / 24);\n\n    // convert days to months\n    monthsFromDays = absFloor(daysToMonths(days));\n    months += monthsFromDays;\n    days -= absCeil(monthsToDays(monthsFromDays));\n\n    // 12 months -> 1 year\n    years = absFloor(months / 12);\n    months %= 12;\n\n    data.days   = days;\n    data.months = months;\n    data.years  = years;\n\n    return this;\n}\n\nfunction daysToMonths (days) {\n    // 400 years have 146097 days (taking into account leap year rules)\n    // 400 years have 12 months === 4800\n    return days * 4800 / 146097;\n}\n\nfunction monthsToDays (months) {\n    // the reverse of daysToMonths\n    return months * 146097 / 4800;\n}\n\nfunction as (units) {\n    if (!this.isValid()) {\n        return NaN;\n    }\n    var days;\n    var months;\n    var milliseconds = this._milliseconds;\n\n    units = normalizeUnits(units);\n\n    if (units === 'month' || units === 'year') {\n        days   = this._days   + milliseconds / 864e5;\n        months = this._months + daysToMonths(days);\n        return units === 'month' ? months : months / 12;\n    } else {\n        // handle milliseconds separately because of floating point math errors (issue #1867)\n        days = this._days + Math.round(monthsToDays(this._months));\n        switch (units) {\n            case 'week'   : return days / 7     + milliseconds / 6048e5;\n            case 'day'    : return days         + milliseconds / 864e5;\n            case 'hour'   : return days * 24    + milliseconds / 36e5;\n            case 'minute' : return days * 1440  + milliseconds / 6e4;\n            case 'second' : return days * 86400 + milliseconds / 1000;\n            // Math.floor prevents floating point math errors here\n            case 'millisecond': return Math.floor(days * 864e5) + milliseconds;\n            default: throw new Error('Unknown unit ' + units);\n        }\n    }\n}\n\n// TODO: Use this.as('ms')?\nfunction valueOf$1 () {\n    if (!this.isValid()) {\n        return NaN;\n    }\n    return (\n        this._milliseconds +\n        this._days * 864e5 +\n        (this._months % 12) * 2592e6 +\n        toInt(this._months / 12) * 31536e6\n    );\n}\n\nfunction makeAs (alias) {\n    return function () {\n        return this.as(alias);\n    };\n}\n\nvar asMilliseconds = makeAs('ms');\nvar asSeconds      = makeAs('s');\nvar asMinutes      = makeAs('m');\nvar asHours        = makeAs('h');\nvar asDays         = makeAs('d');\nvar asWeeks        = makeAs('w');\nvar asMonths       = makeAs('M');\nvar asYears        = makeAs('y');\n\nfunction get$2 (units) {\n    units = normalizeUnits(units);\n    return this.isValid() ? this[units + 's']() : NaN;\n}\n\nfunction makeGetter(name) {\n    return function () {\n        return this.isValid() ? this._data[name] : NaN;\n    };\n}\n\nvar milliseconds = makeGetter('milliseconds');\nvar seconds      = makeGetter('seconds');\nvar minutes      = makeGetter('minutes');\nvar hours        = makeGetter('hours');\nvar days         = makeGetter('days');\nvar months       = makeGetter('months');\nvar years        = makeGetter('years');\n\nfunction weeks () {\n    return absFloor(this.days() / 7);\n}\n\nvar round = Math.round;\nvar thresholds = {\n    ss: 44,         // a few seconds to seconds\n    s : 45,         // seconds to minute\n    m : 45,         // minutes to hour\n    h : 22,         // hours to day\n    d : 26,         // days to month\n    M : 11          // months to year\n};\n\n// helper function for moment.fn.from, moment.fn.fromNow, and moment.duration.fn.humanize\nfunction substituteTimeAgo(string, number, withoutSuffix, isFuture, locale) {\n    return locale.relativeTime(number || 1, !!withoutSuffix, string, isFuture);\n}\n\nfunction relativeTime$1 (posNegDuration, withoutSuffix, locale) {\n    var duration = createDuration(posNegDuration).abs();\n    var seconds  = round(duration.as('s'));\n    var minutes  = round(duration.as('m'));\n    var hours    = round(duration.as('h'));\n    var days     = round(duration.as('d'));\n    var months   = round(duration.as('M'));\n    var years    = round(duration.as('y'));\n\n    var a = seconds <= thresholds.ss && ['s', seconds]  ||\n            seconds < thresholds.s   && ['ss', seconds] ||\n            minutes <= 1             && ['m']           ||\n            minutes < thresholds.m   && ['mm', minutes] ||\n            hours   <= 1             && ['h']           ||\n            hours   < thresholds.h   && ['hh', hours]   ||\n            days    <= 1             && ['d']           ||\n            days    < thresholds.d   && ['dd', days]    ||\n            months  <= 1             && ['M']           ||\n            months  < thresholds.M   && ['MM', months]  ||\n            years   <= 1             && ['y']           || ['yy', years];\n\n    a[2] = withoutSuffix;\n    a[3] = +posNegDuration > 0;\n    a[4] = locale;\n    return substituteTimeAgo.apply(null, a);\n}\n\n// This function allows you to set the rounding function for relative time strings\nfunction getSetRelativeTimeRounding (roundingFunction) {\n    if (roundingFunction === undefined) {\n        return round;\n    }\n    if (typeof(roundingFunction) === 'function') {\n        round = roundingFunction;\n        return true;\n    }\n    return false;\n}\n\n// This function allows you to set a threshold for relative time strings\nfunction getSetRelativeTimeThreshold (threshold, limit) {\n    if (thresholds[threshold] === undefined) {\n        return false;\n    }\n    if (limit === undefined) {\n        return thresholds[threshold];\n    }\n    thresholds[threshold] = limit;\n    if (threshold === 's') {\n        thresholds.ss = limit - 1;\n    }\n    return true;\n}\n\nfunction humanize (withSuffix) {\n    if (!this.isValid()) {\n        return this.localeData().invalidDate();\n    }\n\n    var locale = this.localeData();\n    var output = relativeTime$1(this, !withSuffix, locale);\n\n    if (withSuffix) {\n        output = locale.pastFuture(+this, output);\n    }\n\n    return locale.postformat(output);\n}\n\nvar abs$1 = Math.abs;\n\nfunction toISOString$1() {\n    // for ISO strings we do not use the normal bubbling rules:\n    //  * milliseconds bubble up until they become hours\n    //  * days do not bubble at all\n    //  * months bubble up until they become years\n    // This is because there is no context-free conversion between hours and days\n    // (think of clock changes)\n    // and also not between days and months (28-31 days per month)\n    if (!this.isValid()) {\n        return this.localeData().invalidDate();\n    }\n\n    var seconds = abs$1(this._milliseconds) / 1000;\n    var days         = abs$1(this._days);\n    var months       = abs$1(this._months);\n    var minutes, hours, years;\n\n    // 3600 seconds -> 60 minutes -> 1 hour\n    minutes           = absFloor(seconds / 60);\n    hours             = absFloor(minutes / 60);\n    seconds %= 60;\n    minutes %= 60;\n\n    // 12 months -> 1 year\n    years  = absFloor(months / 12);\n    months %= 12;\n\n\n    // inspired by https://github.com/dordille/moment-isoduration/blob/master/moment.isoduration.js\n    var Y = years;\n    var M = months;\n    var D = days;\n    var h = hours;\n    var m = minutes;\n    var s = seconds;\n    var total = this.asSeconds();\n\n    if (!total) {\n        // this is the same as C#'s (Noda) and python (isodate)...\n        // but not other JS (goog.date)\n        return 'P0D';\n    }\n\n    return (total < 0 ? '-' : '') +\n        'P' +\n        (Y ? Y + 'Y' : '') +\n        (M ? M + 'M' : '') +\n        (D ? D + 'D' : '') +\n        ((h || m || s) ? 'T' : '') +\n        (h ? h + 'H' : '') +\n        (m ? m + 'M' : '') +\n        (s ? s + 'S' : '');\n}\n\nvar proto$2 = Duration.prototype;\n\nproto$2.isValid        = isValid$1;\nproto$2.abs            = abs;\nproto$2.add            = add$1;\nproto$2.subtract       = subtract$1;\nproto$2.as             = as;\nproto$2.asMilliseconds = asMilliseconds;\nproto$2.asSeconds      = asSeconds;\nproto$2.asMinutes      = asMinutes;\nproto$2.asHours        = asHours;\nproto$2.asDays         = asDays;\nproto$2.asWeeks        = asWeeks;\nproto$2.asMonths       = asMonths;\nproto$2.asYears        = asYears;\nproto$2.valueOf        = valueOf$1;\nproto$2._bubble        = bubble;\nproto$2.get            = get$2;\nproto$2.milliseconds   = milliseconds;\nproto$2.seconds        = seconds;\nproto$2.minutes        = minutes;\nproto$2.hours          = hours;\nproto$2.days           = days;\nproto$2.weeks          = weeks;\nproto$2.months         = months;\nproto$2.years          = years;\nproto$2.humanize       = humanize;\nproto$2.toISOString    = toISOString$1;\nproto$2.toString       = toISOString$1;\nproto$2.toJSON         = toISOString$1;\nproto$2.locale         = locale;\nproto$2.localeData     = localeData;\n\n// Deprecations\nproto$2.toIsoString = deprecate('toIsoString() is deprecated. Please use toISOString() instead (notice the capitals)', toISOString$1);\nproto$2.lang = lang;\n\n// Side effect imports\n\n// FORMATTING\n\naddFormatToken('X', 0, 0, 'unix');\naddFormatToken('x', 0, 0, 'valueOf');\n\n// PARSING\n\naddRegexToken('x', matchSigned);\naddRegexToken('X', matchTimestamp);\naddParseToken('X', function (input, array, config) {\n    config._d = new Date(parseFloat(input, 10) * 1000);\n});\naddParseToken('x', function (input, array, config) {\n    config._d = new Date(toInt(input));\n});\n\n// Side effect imports\n\n//! moment.js\n//! version : 2.18.1\n//! authors : Tim Wood, Iskren Chernev, Moment.js contributors\n//! license : MIT\n//! momentjs.com\n\nhooks.version = '2.18.1';\n\nsetHookCallback(createLocal);\n\nhooks.fn                    = proto;\nhooks.min                   = min;\nhooks.max                   = max;\nhooks.now                   = now;\nhooks.utc                   = createUTC;\nhooks.unix                  = createUnix;\nhooks.months                = listMonths;\nhooks.isDate                = isDate;\nhooks.locale                = getSetGlobalLocale;\nhooks.invalid               = createInvalid;\nhooks.duration              = createDuration;\nhooks.isMoment              = isMoment;\nhooks.weekdays              = listWeekdays;\nhooks.parseZone             = createInZone;\nhooks.localeData            = getLocale;\nhooks.isDuration            = isDuration;\nhooks.monthsShort           = listMonthsShort;\nhooks.weekdaysMin           = listWeekdaysMin;\nhooks.defineLocale          = defineLocale;\nhooks.updateLocale          = updateLocale;\nhooks.locales               = listLocales;\nhooks.weekdaysShort         = listWeekdaysShort;\nhooks.normalizeUnits        = normalizeUnits;\nhooks.relativeTimeRounding = getSetRelativeTimeRounding;\nhooks.relativeTimeThreshold = getSetRelativeTimeThreshold;\nhooks.calendarFormat        = getCalendarFormat;\nhooks.prototype             = proto;\n\n//! moment.js locale configuration\n//! locale : Afrikaans [af]\n//! author : Werner Mollentze : https://github.com/wernerm\n\nhooks.defineLocale('af', {\n    months : 'Januarie_Februarie_Maart_April_Mei_Junie_Julie_Augustus_September_Oktober_November_Desember'.split('_'),\n    monthsShort : 'Jan_Feb_Mrt_Apr_Mei_Jun_Jul_Aug_Sep_Okt_Nov_Des'.split('_'),\n    weekdays : 'Sondag_Maandag_Dinsdag_Woensdag_Donderdag_Vrydag_Saterdag'.split('_'),\n    weekdaysShort : 'Son_Maa_Din_Woe_Don_Vry_Sat'.split('_'),\n    weekdaysMin : 'So_Ma_Di_Wo_Do_Vr_Sa'.split('_'),\n    meridiemParse: /vm|nm/i,\n    isPM : function (input) {\n        return /^nm$/i.test(input);\n    },\n    meridiem : function (hours, minutes, isLower) {\n        if (hours < 12) {\n            return isLower ? 'vm' : 'VM';\n        } else {\n            return isLower ? 'nm' : 'NM';\n        }\n    },\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY HH:mm',\n        LLLL : 'dddd, D MMMM YYYY HH:mm'\n    },\n    calendar : {\n        sameDay : '[Vandag om] LT',\n        nextDay : '[Môre om] LT',\n        nextWeek : 'dddd [om] LT',\n        lastDay : '[Gister om] LT',\n        lastWeek : '[Laas] dddd [om] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'oor %s',\n        past : '%s gelede',\n        s : '\\'n paar sekondes',\n        m : '\\'n minuut',\n        mm : '%d minute',\n        h : '\\'n uur',\n        hh : '%d ure',\n        d : '\\'n dag',\n        dd : '%d dae',\n        M : '\\'n maand',\n        MM : '%d maande',\n        y : '\\'n jaar',\n        yy : '%d jaar'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}(ste|de)/,\n    ordinal : function (number) {\n        return number + ((number === 1 || number === 8 || number >= 20) ? 'ste' : 'de'); // Thanks to Joris Röling : https://github.com/jjupiter\n    },\n    week : {\n        dow : 1, // Maandag is die eerste dag van die week.\n        doy : 4  // Die week wat die 4de Januarie bevat is die eerste week van die jaar.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Arabic (Algeria) [ar-dz]\n//! author : Noureddine LOUAHEDJ : https://github.com/noureddineme\n\nhooks.defineLocale('ar-dz', {\n    months : 'جانفي_فيفري_مارس_أفريل_ماي_جوان_جويلية_أوت_سبتمبر_أكتوبر_نوفمبر_ديسمبر'.split('_'),\n    monthsShort : 'جانفي_فيفري_مارس_أفريل_ماي_جوان_جويلية_أوت_سبتمبر_أكتوبر_نوفمبر_ديسمبر'.split('_'),\n    weekdays : 'الأحد_الإثنين_الثلاثاء_الأربعاء_الخميس_الجمعة_السبت'.split('_'),\n    weekdaysShort : 'احد_اثنين_ثلاثاء_اربعاء_خميس_جمعة_سبت'.split('_'),\n    weekdaysMin : 'أح_إث_ثلا_أر_خم_جم_سب'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY HH:mm',\n        LLLL : 'dddd D MMMM YYYY HH:mm'\n    },\n    calendar : {\n        sameDay: '[اليوم على الساعة] LT',\n        nextDay: '[غدا على الساعة] LT',\n        nextWeek: 'dddd [على الساعة] LT',\n        lastDay: '[أمس على الساعة] LT',\n        lastWeek: 'dddd [على الساعة] LT',\n        sameElse: 'L'\n    },\n    relativeTime : {\n        future : 'في %s',\n        past : 'منذ %s',\n        s : 'ثوان',\n        m : 'دقيقة',\n        mm : '%d دقائق',\n        h : 'ساعة',\n        hh : '%d ساعات',\n        d : 'يوم',\n        dd : '%d أيام',\n        M : 'شهر',\n        MM : '%d أشهر',\n        y : 'سنة',\n        yy : '%d سنوات'\n    },\n    week : {\n        dow : 0, // Sunday is the first day of the week.\n        doy : 4  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Arabic (Kuwait) [ar-kw]\n//! author : Nusret Parlak: https://github.com/nusretparlak\n\nhooks.defineLocale('ar-kw', {\n    months : 'يناير_فبراير_مارس_أبريل_ماي_يونيو_يوليوز_غشت_شتنبر_أكتوبر_نونبر_دجنبر'.split('_'),\n    monthsShort : 'يناير_فبراير_مارس_أبريل_ماي_يونيو_يوليوز_غشت_شتنبر_أكتوبر_نونبر_دجنبر'.split('_'),\n    weekdays : 'الأحد_الإتنين_الثلاثاء_الأربعاء_الخميس_الجمعة_السبت'.split('_'),\n    weekdaysShort : 'احد_اتنين_ثلاثاء_اربعاء_خميس_جمعة_سبت'.split('_'),\n    weekdaysMin : 'ح_ن_ث_ر_خ_ج_س'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY HH:mm',\n        LLLL : 'dddd D MMMM YYYY HH:mm'\n    },\n    calendar : {\n        sameDay: '[اليوم على الساعة] LT',\n        nextDay: '[غدا على الساعة] LT',\n        nextWeek: 'dddd [على الساعة] LT',\n        lastDay: '[أمس على الساعة] LT',\n        lastWeek: 'dddd [على الساعة] LT',\n        sameElse: 'L'\n    },\n    relativeTime : {\n        future : 'في %s',\n        past : 'منذ %s',\n        s : 'ثوان',\n        m : 'دقيقة',\n        mm : '%d دقائق',\n        h : 'ساعة',\n        hh : '%d ساعات',\n        d : 'يوم',\n        dd : '%d أيام',\n        M : 'شهر',\n        MM : '%d أشهر',\n        y : 'سنة',\n        yy : '%d سنوات'\n    },\n    week : {\n        dow : 0, // Sunday is the first day of the week.\n        doy : 12  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Arabic (Lybia) [ar-ly]\n//! author : Ali Hmer: https://github.com/kikoanis\n\nvar symbolMap = {\n    '1': '1',\n    '2': '2',\n    '3': '3',\n    '4': '4',\n    '5': '5',\n    '6': '6',\n    '7': '7',\n    '8': '8',\n    '9': '9',\n    '0': '0'\n};\nvar pluralForm = function (n) {\n    return n === 0 ? 0 : n === 1 ? 1 : n === 2 ? 2 : n % 100 >= 3 && n % 100 <= 10 ? 3 : n % 100 >= 11 ? 4 : 5;\n};\nvar plurals = {\n    s : ['أقل من ثانية', 'ثانية واحدة', ['ثانيتان', 'ثانيتين'], '%d ثوان', '%d ثانية', '%d ثانية'],\n    m : ['أقل من دقيقة', 'دقيقة واحدة', ['دقيقتان', 'دقيقتين'], '%d دقائق', '%d دقيقة', '%d دقيقة'],\n    h : ['أقل من ساعة', 'ساعة واحدة', ['ساعتان', 'ساعتين'], '%d ساعات', '%d ساعة', '%d ساعة'],\n    d : ['أقل من يوم', 'يوم واحد', ['يومان', 'يومين'], '%d أيام', '%d يومًا', '%d يوم'],\n    M : ['أقل من شهر', 'شهر واحد', ['شهران', 'شهرين'], '%d أشهر', '%d شهرا', '%d شهر'],\n    y : ['أقل من عام', 'عام واحد', ['عامان', 'عامين'], '%d أعوام', '%d عامًا', '%d عام']\n};\nvar pluralize = function (u) {\n    return function (number, withoutSuffix, string, isFuture) {\n        var f = pluralForm(number),\n            str = plurals[u][pluralForm(number)];\n        if (f === 2) {\n            str = str[withoutSuffix ? 0 : 1];\n        }\n        return str.replace(/%d/i, number);\n    };\n};\nvar months$1 = [\n    'يناير',\n    'فبراير',\n    'مارس',\n    'أبريل',\n    'مايو',\n    'يونيو',\n    'يوليو',\n    'أغسطس',\n    'سبتمبر',\n    'أكتوبر',\n    'نوفمبر',\n    'ديسمبر'\n];\n\nhooks.defineLocale('ar-ly', {\n    months : months$1,\n    monthsShort : months$1,\n    weekdays : 'الأحد_الإثنين_الثلاثاء_الأربعاء_الخميس_الجمعة_السبت'.split('_'),\n    weekdaysShort : 'أحد_إثنين_ثلاثاء_أربعاء_خميس_جمعة_سبت'.split('_'),\n    weekdaysMin : 'ح_ن_ث_ر_خ_ج_س'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'D/\\u200FM/\\u200FYYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY HH:mm',\n        LLLL : 'dddd D MMMM YYYY HH:mm'\n    },\n    meridiemParse: /ص|م/,\n    isPM : function (input) {\n        return 'م' === input;\n    },\n    meridiem : function (hour, minute, isLower) {\n        if (hour < 12) {\n            return 'ص';\n        } else {\n            return 'م';\n        }\n    },\n    calendar : {\n        sameDay: '[اليوم عند الساعة] LT',\n        nextDay: '[غدًا عند الساعة] LT',\n        nextWeek: 'dddd [عند الساعة] LT',\n        lastDay: '[أمس عند الساعة] LT',\n        lastWeek: 'dddd [عند الساعة] LT',\n        sameElse: 'L'\n    },\n    relativeTime : {\n        future : 'بعد %s',\n        past : 'منذ %s',\n        s : pluralize('s'),\n        m : pluralize('m'),\n        mm : pluralize('m'),\n        h : pluralize('h'),\n        hh : pluralize('h'),\n        d : pluralize('d'),\n        dd : pluralize('d'),\n        M : pluralize('M'),\n        MM : pluralize('M'),\n        y : pluralize('y'),\n        yy : pluralize('y')\n    },\n    preparse: function (string) {\n        return string.replace(/\\u200f/g, '').replace(/،/g, ',');\n    },\n    postformat: function (string) {\n        return string.replace(/\\d/g, function (match) {\n            return symbolMap[match];\n        }).replace(/,/g, '،');\n    },\n    week : {\n        dow : 6, // Saturday is the first day of the week.\n        doy : 12  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Arabic (Morocco) [ar-ma]\n//! author : ElFadili Yassine : https://github.com/ElFadiliY\n//! author : Abdel Said : https://github.com/abdelsaid\n\nhooks.defineLocale('ar-ma', {\n    months : 'يناير_فبراير_مارس_أبريل_ماي_يونيو_يوليوز_غشت_شتنبر_أكتوبر_نونبر_دجنبر'.split('_'),\n    monthsShort : 'يناير_فبراير_مارس_أبريل_ماي_يونيو_يوليوز_غشت_شتنبر_أكتوبر_نونبر_دجنبر'.split('_'),\n    weekdays : 'الأحد_الإتنين_الثلاثاء_الأربعاء_الخميس_الجمعة_السبت'.split('_'),\n    weekdaysShort : 'احد_اتنين_ثلاثاء_اربعاء_خميس_جمعة_سبت'.split('_'),\n    weekdaysMin : 'ح_ن_ث_ر_خ_ج_س'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY HH:mm',\n        LLLL : 'dddd D MMMM YYYY HH:mm'\n    },\n    calendar : {\n        sameDay: '[اليوم على الساعة] LT',\n        nextDay: '[غدا على الساعة] LT',\n        nextWeek: 'dddd [على الساعة] LT',\n        lastDay: '[أمس على الساعة] LT',\n        lastWeek: 'dddd [على الساعة] LT',\n        sameElse: 'L'\n    },\n    relativeTime : {\n        future : 'في %s',\n        past : 'منذ %s',\n        s : 'ثوان',\n        m : 'دقيقة',\n        mm : '%d دقائق',\n        h : 'ساعة',\n        hh : '%d ساعات',\n        d : 'يوم',\n        dd : '%d أيام',\n        M : 'شهر',\n        MM : '%d أشهر',\n        y : 'سنة',\n        yy : '%d سنوات'\n    },\n    week : {\n        dow : 6, // Saturday is the first day of the week.\n        doy : 12  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Arabic (Saudi Arabia) [ar-sa]\n//! author : Suhail Alkowaileet : https://github.com/xsoh\n\nvar symbolMap$1 = {\n    '1': '١',\n    '2': '٢',\n    '3': '٣',\n    '4': '٤',\n    '5': '٥',\n    '6': '٦',\n    '7': '٧',\n    '8': '٨',\n    '9': '٩',\n    '0': '٠'\n};\nvar numberMap = {\n    '١': '1',\n    '٢': '2',\n    '٣': '3',\n    '٤': '4',\n    '٥': '5',\n    '٦': '6',\n    '٧': '7',\n    '٨': '8',\n    '٩': '9',\n    '٠': '0'\n};\n\nhooks.defineLocale('ar-sa', {\n    months : 'يناير_فبراير_مارس_أبريل_مايو_يونيو_يوليو_أغسطس_سبتمبر_أكتوبر_نوفمبر_ديسمبر'.split('_'),\n    monthsShort : 'يناير_فبراير_مارس_أبريل_مايو_يونيو_يوليو_أغسطس_سبتمبر_أكتوبر_نوفمبر_ديسمبر'.split('_'),\n    weekdays : 'الأحد_الإثنين_الثلاثاء_الأربعاء_الخميس_الجمعة_السبت'.split('_'),\n    weekdaysShort : 'أحد_إثنين_ثلاثاء_أربعاء_خميس_جمعة_سبت'.split('_'),\n    weekdaysMin : 'ح_ن_ث_ر_خ_ج_س'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY HH:mm',\n        LLLL : 'dddd D MMMM YYYY HH:mm'\n    },\n    meridiemParse: /ص|م/,\n    isPM : function (input) {\n        return 'م' === input;\n    },\n    meridiem : function (hour, minute, isLower) {\n        if (hour < 12) {\n            return 'ص';\n        } else {\n            return 'م';\n        }\n    },\n    calendar : {\n        sameDay: '[اليوم على الساعة] LT',\n        nextDay: '[غدا على الساعة] LT',\n        nextWeek: 'dddd [على الساعة] LT',\n        lastDay: '[أمس على الساعة] LT',\n        lastWeek: 'dddd [على الساعة] LT',\n        sameElse: 'L'\n    },\n    relativeTime : {\n        future : 'في %s',\n        past : 'منذ %s',\n        s : 'ثوان',\n        m : 'دقيقة',\n        mm : '%d دقائق',\n        h : 'ساعة',\n        hh : '%d ساعات',\n        d : 'يوم',\n        dd : '%d أيام',\n        M : 'شهر',\n        MM : '%d أشهر',\n        y : 'سنة',\n        yy : '%d سنوات'\n    },\n    preparse: function (string) {\n        return string.replace(/[١٢٣٤٥٦٧٨٩٠]/g, function (match) {\n            return numberMap[match];\n        }).replace(/،/g, ',');\n    },\n    postformat: function (string) {\n        return string.replace(/\\d/g, function (match) {\n            return symbolMap$1[match];\n        }).replace(/,/g, '،');\n    },\n    week : {\n        dow : 0, // Sunday is the first day of the week.\n        doy : 6  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale  :  Arabic (Tunisia) [ar-tn]\n//! author : Nader Toukabri : https://github.com/naderio\n\nhooks.defineLocale('ar-tn', {\n    months: 'جانفي_فيفري_مارس_أفريل_ماي_جوان_جويلية_أوت_سبتمبر_أكتوبر_نوفمبر_ديسمبر'.split('_'),\n    monthsShort: 'جانفي_فيفري_مارس_أفريل_ماي_جوان_جويلية_أوت_سبتمبر_أكتوبر_نوفمبر_ديسمبر'.split('_'),\n    weekdays: 'الأحد_الإثنين_الثلاثاء_الأربعاء_الخميس_الجمعة_السبت'.split('_'),\n    weekdaysShort: 'أحد_إثنين_ثلاثاء_أربعاء_خميس_جمعة_سبت'.split('_'),\n    weekdaysMin: 'ح_ن_ث_ر_خ_ج_س'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat: {\n        LT: 'HH:mm',\n        LTS: 'HH:mm:ss',\n        L: 'DD/MM/YYYY',\n        LL: 'D MMMM YYYY',\n        LLL: 'D MMMM YYYY HH:mm',\n        LLLL: 'dddd D MMMM YYYY HH:mm'\n    },\n    calendar: {\n        sameDay: '[اليوم على الساعة] LT',\n        nextDay: '[غدا على الساعة] LT',\n        nextWeek: 'dddd [على الساعة] LT',\n        lastDay: '[أمس على الساعة] LT',\n        lastWeek: 'dddd [على الساعة] LT',\n        sameElse: 'L'\n    },\n    relativeTime: {\n        future: 'في %s',\n        past: 'منذ %s',\n        s: 'ثوان',\n        m: 'دقيقة',\n        mm: '%d دقائق',\n        h: 'ساعة',\n        hh: '%d ساعات',\n        d: 'يوم',\n        dd: '%d أيام',\n        M: 'شهر',\n        MM: '%d أشهر',\n        y: 'سنة',\n        yy: '%d سنوات'\n    },\n    week: {\n        dow: 1, // Monday is the first day of the week.\n        doy: 4 // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Arabic [ar]\n//! author : Abdel Said: https://github.com/abdelsaid\n//! author : Ahmed Elkhatib\n//! author : forabi https://github.com/forabi\n\nvar symbolMap$2 = {\n    '1': '١',\n    '2': '٢',\n    '3': '٣',\n    '4': '٤',\n    '5': '٥',\n    '6': '٦',\n    '7': '٧',\n    '8': '٨',\n    '9': '٩',\n    '0': '٠'\n};\nvar numberMap$1 = {\n    '١': '1',\n    '٢': '2',\n    '٣': '3',\n    '٤': '4',\n    '٥': '5',\n    '٦': '6',\n    '٧': '7',\n    '٨': '8',\n    '٩': '9',\n    '٠': '0'\n};\nvar pluralForm$1 = function (n) {\n    return n === 0 ? 0 : n === 1 ? 1 : n === 2 ? 2 : n % 100 >= 3 && n % 100 <= 10 ? 3 : n % 100 >= 11 ? 4 : 5;\n};\nvar plurals$1 = {\n    s : ['أقل من ثانية', 'ثانية واحدة', ['ثانيتان', 'ثانيتين'], '%d ثوان', '%d ثانية', '%d ثانية'],\n    m : ['أقل من دقيقة', 'دقيقة واحدة', ['دقيقتان', 'دقيقتين'], '%d دقائق', '%d دقيقة', '%d دقيقة'],\n    h : ['أقل من ساعة', 'ساعة واحدة', ['ساعتان', 'ساعتين'], '%d ساعات', '%d ساعة', '%d ساعة'],\n    d : ['أقل من يوم', 'يوم واحد', ['يومان', 'يومين'], '%d أيام', '%d يومًا', '%d يوم'],\n    M : ['أقل من شهر', 'شهر واحد', ['شهران', 'شهرين'], '%d أشهر', '%d شهرا', '%d شهر'],\n    y : ['أقل من عام', 'عام واحد', ['عامان', 'عامين'], '%d أعوام', '%d عامًا', '%d عام']\n};\nvar pluralize$1 = function (u) {\n    return function (number, withoutSuffix, string, isFuture) {\n        var f = pluralForm$1(number),\n            str = plurals$1[u][pluralForm$1(number)];\n        if (f === 2) {\n            str = str[withoutSuffix ? 0 : 1];\n        }\n        return str.replace(/%d/i, number);\n    };\n};\nvar months$2 = [\n    'كانون الثاني يناير',\n    'شباط فبراير',\n    'آذار مارس',\n    'نيسان أبريل',\n    'أيار مايو',\n    'حزيران يونيو',\n    'تموز يوليو',\n    'آب أغسطس',\n    'أيلول سبتمبر',\n    'تشرين الأول أكتوبر',\n    'تشرين الثاني نوفمبر',\n    'كانون الأول ديسمبر'\n];\n\nhooks.defineLocale('ar', {\n    months : months$2,\n    monthsShort : months$2,\n    weekdays : 'الأحد_الإثنين_الثلاثاء_الأربعاء_الخميس_الجمعة_السبت'.split('_'),\n    weekdaysShort : 'أحد_إثنين_ثلاثاء_أربعاء_خميس_جمعة_سبت'.split('_'),\n    weekdaysMin : 'ح_ن_ث_ر_خ_ج_س'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'D/\\u200FM/\\u200FYYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY HH:mm',\n        LLLL : 'dddd D MMMM YYYY HH:mm'\n    },\n    meridiemParse: /ص|م/,\n    isPM : function (input) {\n        return 'م' === input;\n    },\n    meridiem : function (hour, minute, isLower) {\n        if (hour < 12) {\n            return 'ص';\n        } else {\n            return 'م';\n        }\n    },\n    calendar : {\n        sameDay: '[اليوم عند الساعة] LT',\n        nextDay: '[غدًا عند الساعة] LT',\n        nextWeek: 'dddd [عند الساعة] LT',\n        lastDay: '[أمس عند الساعة] LT',\n        lastWeek: 'dddd [عند الساعة] LT',\n        sameElse: 'L'\n    },\n    relativeTime : {\n        future : 'بعد %s',\n        past : 'منذ %s',\n        s : pluralize$1('s'),\n        m : pluralize$1('m'),\n        mm : pluralize$1('m'),\n        h : pluralize$1('h'),\n        hh : pluralize$1('h'),\n        d : pluralize$1('d'),\n        dd : pluralize$1('d'),\n        M : pluralize$1('M'),\n        MM : pluralize$1('M'),\n        y : pluralize$1('y'),\n        yy : pluralize$1('y')\n    },\n    preparse: function (string) {\n        return string.replace(/\\u200f/g, '').replace(/[١٢٣٤٥٦٧٨٩٠]/g, function (match) {\n            return numberMap$1[match];\n        }).replace(/،/g, ',');\n    },\n    postformat: function (string) {\n        return string.replace(/\\d/g, function (match) {\n            return symbolMap$2[match];\n        }).replace(/,/g, '،');\n    },\n    week : {\n        dow : 6, // Saturday is the first day of the week.\n        doy : 12  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Azerbaijani [az]\n//! author : topchiyev : https://github.com/topchiyev\n\nvar suffixes = {\n    1: '-inci',\n    5: '-inci',\n    8: '-inci',\n    70: '-inci',\n    80: '-inci',\n    2: '-nci',\n    7: '-nci',\n    20: '-nci',\n    50: '-nci',\n    3: '-üncü',\n    4: '-üncü',\n    100: '-üncü',\n    6: '-ncı',\n    9: '-uncu',\n    10: '-uncu',\n    30: '-uncu',\n    60: '-ıncı',\n    90: '-ıncı'\n};\n\nhooks.defineLocale('az', {\n    months : 'yanvar_fevral_mart_aprel_may_iyun_iyul_avqust_sentyabr_oktyabr_noyabr_dekabr'.split('_'),\n    monthsShort : 'yan_fev_mar_apr_may_iyn_iyl_avq_sen_okt_noy_dek'.split('_'),\n    weekdays : 'Bazar_Bazar ertəsi_Çərşənbə axşamı_Çərşənbə_Cümə axşamı_Cümə_Şənbə'.split('_'),\n    weekdaysShort : 'Baz_BzE_ÇAx_Çər_CAx_Cüm_Şən'.split('_'),\n    weekdaysMin : 'Bz_BE_ÇA_Çə_CA_Cü_Şə'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD.MM.YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY HH:mm',\n        LLLL : 'dddd, D MMMM YYYY HH:mm'\n    },\n    calendar : {\n        sameDay : '[bugün saat] LT',\n        nextDay : '[sabah saat] LT',\n        nextWeek : '[gələn həftə] dddd [saat] LT',\n        lastDay : '[dünən] LT',\n        lastWeek : '[keçən həftə] dddd [saat] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : '%s sonra',\n        past : '%s əvvəl',\n        s : 'birneçə saniyyə',\n        m : 'bir dəqiqə',\n        mm : '%d dəqiqə',\n        h : 'bir saat',\n        hh : '%d saat',\n        d : 'bir gün',\n        dd : '%d gün',\n        M : 'bir ay',\n        MM : '%d ay',\n        y : 'bir il',\n        yy : '%d il'\n    },\n    meridiemParse: /gecə|səhər|gündüz|axşam/,\n    isPM : function (input) {\n        return /^(gündüz|axşam)$/.test(input);\n    },\n    meridiem : function (hour, minute, isLower) {\n        if (hour < 4) {\n            return 'gecə';\n        } else if (hour < 12) {\n            return 'səhər';\n        } else if (hour < 17) {\n            return 'gündüz';\n        } else {\n            return 'axşam';\n        }\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}-(ıncı|inci|nci|üncü|ncı|uncu)/,\n    ordinal : function (number) {\n        if (number === 0) {  // special case for zero\n            return number + '-ıncı';\n        }\n        var a = number % 10,\n            b = number % 100 - a,\n            c = number >= 100 ? 100 : null;\n        return number + (suffixes[a] || suffixes[b] || suffixes[c]);\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 7  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Belarusian [be]\n//! author : Dmitry Demidov : https://github.com/demidov91\n//! author: Praleska: http://praleska.pro/\n//! Author : Menelion Elensúle : https://github.com/Oire\n\nfunction plural(word, num) {\n    var forms = word.split('_');\n    return num % 10 === 1 && num % 100 !== 11 ? forms[0] : (num % 10 >= 2 && num % 10 <= 4 && (num % 100 < 10 || num % 100 >= 20) ? forms[1] : forms[2]);\n}\nfunction relativeTimeWithPlural(number, withoutSuffix, key) {\n    var format = {\n        'mm': withoutSuffix ? 'хвіліна_хвіліны_хвілін' : 'хвіліну_хвіліны_хвілін',\n        'hh': withoutSuffix ? 'гадзіна_гадзіны_гадзін' : 'гадзіну_гадзіны_гадзін',\n        'dd': 'дзень_дні_дзён',\n        'MM': 'месяц_месяцы_месяцаў',\n        'yy': 'год_гады_гадоў'\n    };\n    if (key === 'm') {\n        return withoutSuffix ? 'хвіліна' : 'хвіліну';\n    }\n    else if (key === 'h') {\n        return withoutSuffix ? 'гадзіна' : 'гадзіну';\n    }\n    else {\n        return number + ' ' + plural(format[key], +number);\n    }\n}\n\nhooks.defineLocale('be', {\n    months : {\n        format: 'студзеня_лютага_сакавіка_красавіка_траўня_чэрвеня_ліпеня_жніўня_верасня_кастрычніка_лістапада_снежня'.split('_'),\n        standalone: 'студзень_люты_сакавік_красавік_травень_чэрвень_ліпень_жнівень_верасень_кастрычнік_лістапад_снежань'.split('_')\n    },\n    monthsShort : 'студ_лют_сак_крас_трав_чэрв_ліп_жнів_вер_каст_ліст_снеж'.split('_'),\n    weekdays : {\n        format: 'нядзелю_панядзелак_аўторак_сераду_чацвер_пятніцу_суботу'.split('_'),\n        standalone: 'нядзеля_панядзелак_аўторак_серада_чацвер_пятніца_субота'.split('_'),\n        isFormat: /\\[ ?[Вв] ?(?:мінулую|наступную)? ?\\] ?dddd/\n    },\n    weekdaysShort : 'нд_пн_ат_ср_чц_пт_сб'.split('_'),\n    weekdaysMin : 'нд_пн_ат_ср_чц_пт_сб'.split('_'),\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD.MM.YYYY',\n        LL : 'D MMMM YYYY г.',\n        LLL : 'D MMMM YYYY г., HH:mm',\n        LLLL : 'dddd, D MMMM YYYY г., HH:mm'\n    },\n    calendar : {\n        sameDay: '[Сёння ў] LT',\n        nextDay: '[Заўтра ў] LT',\n        lastDay: '[Учора ў] LT',\n        nextWeek: function () {\n            return '[У] dddd [ў] LT';\n        },\n        lastWeek: function () {\n            switch (this.day()) {\n                case 0:\n                case 3:\n                case 5:\n                case 6:\n                    return '[У мінулую] dddd [ў] LT';\n                case 1:\n                case 2:\n                case 4:\n                    return '[У мінулы] dddd [ў] LT';\n            }\n        },\n        sameElse: 'L'\n    },\n    relativeTime : {\n        future : 'праз %s',\n        past : '%s таму',\n        s : 'некалькі секунд',\n        m : relativeTimeWithPlural,\n        mm : relativeTimeWithPlural,\n        h : relativeTimeWithPlural,\n        hh : relativeTimeWithPlural,\n        d : 'дзень',\n        dd : relativeTimeWithPlural,\n        M : 'месяц',\n        MM : relativeTimeWithPlural,\n        y : 'год',\n        yy : relativeTimeWithPlural\n    },\n    meridiemParse: /ночы|раніцы|дня|вечара/,\n    isPM : function (input) {\n        return /^(дня|вечара)$/.test(input);\n    },\n    meridiem : function (hour, minute, isLower) {\n        if (hour < 4) {\n            return 'ночы';\n        } else if (hour < 12) {\n            return 'раніцы';\n        } else if (hour < 17) {\n            return 'дня';\n        } else {\n            return 'вечара';\n        }\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}-(і|ы|га)/,\n    ordinal: function (number, period) {\n        switch (period) {\n            case 'M':\n            case 'd':\n            case 'DDD':\n            case 'w':\n            case 'W':\n                return (number % 10 === 2 || number % 10 === 3) && (number % 100 !== 12 && number % 100 !== 13) ? number + '-і' : number + '-ы';\n            case 'D':\n                return number + '-га';\n            default:\n                return number;\n        }\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 7  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Bulgarian [bg]\n//! author : Krasen Borisov : https://github.com/kraz\n\nhooks.defineLocale('bg', {\n    months : 'януари_февруари_март_април_май_юни_юли_август_септември_октомври_ноември_декември'.split('_'),\n    monthsShort : 'янр_фев_мар_апр_май_юни_юли_авг_сеп_окт_ное_дек'.split('_'),\n    weekdays : 'неделя_понеделник_вторник_сряда_четвъртък_петък_събота'.split('_'),\n    weekdaysShort : 'нед_пон_вто_сря_чет_пет_съб'.split('_'),\n    weekdaysMin : 'нд_пн_вт_ср_чт_пт_сб'.split('_'),\n    longDateFormat : {\n        LT : 'H:mm',\n        LTS : 'H:mm:ss',\n        L : 'D.MM.YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY H:mm',\n        LLLL : 'dddd, D MMMM YYYY H:mm'\n    },\n    calendar : {\n        sameDay : '[Днес в] LT',\n        nextDay : '[Утре в] LT',\n        nextWeek : 'dddd [в] LT',\n        lastDay : '[Вчера в] LT',\n        lastWeek : function () {\n            switch (this.day()) {\n                case 0:\n                case 3:\n                case 6:\n                    return '[В изминалата] dddd [в] LT';\n                case 1:\n                case 2:\n                case 4:\n                case 5:\n                    return '[В изминалия] dddd [в] LT';\n            }\n        },\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'след %s',\n        past : 'преди %s',\n        s : 'няколко секунди',\n        m : 'минута',\n        mm : '%d минути',\n        h : 'час',\n        hh : '%d часа',\n        d : 'ден',\n        dd : '%d дни',\n        M : 'месец',\n        MM : '%d месеца',\n        y : 'година',\n        yy : '%d години'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}-(ев|ен|ти|ви|ри|ми)/,\n    ordinal : function (number) {\n        var lastDigit = number % 10,\n            last2Digits = number % 100;\n        if (number === 0) {\n            return number + '-ев';\n        } else if (last2Digits === 0) {\n            return number + '-ен';\n        } else if (last2Digits > 10 && last2Digits < 20) {\n            return number + '-ти';\n        } else if (lastDigit === 1) {\n            return number + '-ви';\n        } else if (lastDigit === 2) {\n            return number + '-ри';\n        } else if (lastDigit === 7 || lastDigit === 8) {\n            return number + '-ми';\n        } else {\n            return number + '-ти';\n        }\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 7  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Bengali [bn]\n//! author : Kaushik Gandhi : https://github.com/kaushikgandhi\n\nvar symbolMap$3 = {\n    '1': '১',\n    '2': '২',\n    '3': '৩',\n    '4': '৪',\n    '5': '৫',\n    '6': '৬',\n    '7': '৭',\n    '8': '৮',\n    '9': '৯',\n    '0': '০'\n};\nvar numberMap$2 = {\n    '১': '1',\n    '২': '2',\n    '৩': '3',\n    '৪': '4',\n    '৫': '5',\n    '৬': '6',\n    '৭': '7',\n    '৮': '8',\n    '৯': '9',\n    '০': '0'\n};\n\nhooks.defineLocale('bn', {\n    months : 'জানুয়ারী_ফেব্রুয়ারি_মার্চ_এপ্রিল_মে_জুন_জুলাই_আগস্ট_সেপ্টেম্বর_অক্টোবর_নভেম্বর_ডিসেম্বর'.split('_'),\n    monthsShort : 'জানু_ফেব_মার্চ_এপ্র_মে_জুন_জুল_আগ_সেপ্ট_অক্টো_নভে_ডিসে'.split('_'),\n    weekdays : 'রবিবার_সোমবার_মঙ্গলবার_বুধবার_বৃহস্পতিবার_শুক্রবার_শনিবার'.split('_'),\n    weekdaysShort : 'রবি_সোম_মঙ্গল_বুধ_বৃহস্পতি_শুক্র_শনি'.split('_'),\n    weekdaysMin : 'রবি_সোম_মঙ্গ_বুধ_বৃহঃ_শুক্র_শনি'.split('_'),\n    longDateFormat : {\n        LT : 'A h:mm সময়',\n        LTS : 'A h:mm:ss সময়',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY, A h:mm সময়',\n        LLLL : 'dddd, D MMMM YYYY, A h:mm সময়'\n    },\n    calendar : {\n        sameDay : '[আজ] LT',\n        nextDay : '[আগামীকাল] LT',\n        nextWeek : 'dddd, LT',\n        lastDay : '[গতকাল] LT',\n        lastWeek : '[গত] dddd, LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : '%s পরে',\n        past : '%s আগে',\n        s : 'কয়েক সেকেন্ড',\n        m : 'এক মিনিট',\n        mm : '%d মিনিট',\n        h : 'এক ঘন্টা',\n        hh : '%d ঘন্টা',\n        d : 'এক দিন',\n        dd : '%d দিন',\n        M : 'এক মাস',\n        MM : '%d মাস',\n        y : 'এক বছর',\n        yy : '%d বছর'\n    },\n    preparse: function (string) {\n        return string.replace(/[১২৩৪৫৬৭৮৯০]/g, function (match) {\n            return numberMap$2[match];\n        });\n    },\n    postformat: function (string) {\n        return string.replace(/\\d/g, function (match) {\n            return symbolMap$3[match];\n        });\n    },\n    meridiemParse: /রাত|সকাল|দুপুর|বিকাল|রাত/,\n    meridiemHour : function (hour, meridiem) {\n        if (hour === 12) {\n            hour = 0;\n        }\n        if ((meridiem === 'রাত' && hour >= 4) ||\n                (meridiem === 'দুপুর' && hour < 5) ||\n                meridiem === 'বিকাল') {\n            return hour + 12;\n        } else {\n            return hour;\n        }\n    },\n    meridiem : function (hour, minute, isLower) {\n        if (hour < 4) {\n            return 'রাত';\n        } else if (hour < 10) {\n            return 'সকাল';\n        } else if (hour < 17) {\n            return 'দুপুর';\n        } else if (hour < 20) {\n            return 'বিকাল';\n        } else {\n            return 'রাত';\n        }\n    },\n    week : {\n        dow : 0, // Sunday is the first day of the week.\n        doy : 6  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Tibetan [bo]\n//! author : Thupten N. Chakrishar : https://github.com/vajradog\n\nvar symbolMap$4 = {\n    '1': '༡',\n    '2': '༢',\n    '3': '༣',\n    '4': '༤',\n    '5': '༥',\n    '6': '༦',\n    '7': '༧',\n    '8': '༨',\n    '9': '༩',\n    '0': '༠'\n};\nvar numberMap$3 = {\n    '༡': '1',\n    '༢': '2',\n    '༣': '3',\n    '༤': '4',\n    '༥': '5',\n    '༦': '6',\n    '༧': '7',\n    '༨': '8',\n    '༩': '9',\n    '༠': '0'\n};\n\nhooks.defineLocale('bo', {\n    months : 'ཟླ་བ་དང་པོ_ཟླ་བ་གཉིས་པ_ཟླ་བ་གསུམ་པ_ཟླ་བ་བཞི་པ_ཟླ་བ་ལྔ་པ_ཟླ་བ་དྲུག་པ_ཟླ་བ་བདུན་པ_ཟླ་བ་བརྒྱད་པ_ཟླ་བ་དགུ་པ_ཟླ་བ་བཅུ་པ_ཟླ་བ་བཅུ་གཅིག་པ_ཟླ་བ་བཅུ་གཉིས་པ'.split('_'),\n    monthsShort : 'ཟླ་བ་དང་པོ_ཟླ་བ་གཉིས་པ_ཟླ་བ་གསུམ་པ_ཟླ་བ་བཞི་པ_ཟླ་བ་ལྔ་པ_ཟླ་བ་དྲུག་པ_ཟླ་བ་བདུན་པ_ཟླ་བ་བརྒྱད་པ_ཟླ་བ་དགུ་པ_ཟླ་བ་བཅུ་པ_ཟླ་བ་བཅུ་གཅིག་པ_ཟླ་བ་བཅུ་གཉིས་པ'.split('_'),\n    weekdays : 'གཟའ་ཉི་མ་_གཟའ་ཟླ་བ་_གཟའ་མིག་དམར་_གཟའ་ལྷག་པ་_གཟའ་ཕུར་བུ_གཟའ་པ་སངས་_གཟའ་སྤེན་པ་'.split('_'),\n    weekdaysShort : 'ཉི་མ་_ཟླ་བ་_མིག་དམར་_ལྷག་པ་_ཕུར་བུ_པ་སངས་_སྤེན་པ་'.split('_'),\n    weekdaysMin : 'ཉི་མ་_ཟླ་བ་_མིག་དམར་_ལྷག་པ་_ཕུར་བུ_པ་སངས་_སྤེན་པ་'.split('_'),\n    longDateFormat : {\n        LT : 'A h:mm',\n        LTS : 'A h:mm:ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY, A h:mm',\n        LLLL : 'dddd, D MMMM YYYY, A h:mm'\n    },\n    calendar : {\n        sameDay : '[དི་རིང] LT',\n        nextDay : '[སང་ཉིན] LT',\n        nextWeek : '[བདུན་ཕྲག་རྗེས་མ], LT',\n        lastDay : '[ཁ་སང] LT',\n        lastWeek : '[བདུན་ཕྲག་མཐའ་མ] dddd, LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : '%s ལ་',\n        past : '%s སྔན་ལ',\n        s : 'ལམ་སང',\n        m : 'སྐར་མ་གཅིག',\n        mm : '%d སྐར་མ',\n        h : 'ཆུ་ཚོད་གཅིག',\n        hh : '%d ཆུ་ཚོད',\n        d : 'ཉིན་གཅིག',\n        dd : '%d ཉིན་',\n        M : 'ཟླ་བ་གཅིག',\n        MM : '%d ཟླ་བ',\n        y : 'ལོ་གཅིག',\n        yy : '%d ལོ'\n    },\n    preparse: function (string) {\n        return string.replace(/[༡༢༣༤༥༦༧༨༩༠]/g, function (match) {\n            return numberMap$3[match];\n        });\n    },\n    postformat: function (string) {\n        return string.replace(/\\d/g, function (match) {\n            return symbolMap$4[match];\n        });\n    },\n    meridiemParse: /མཚན་མོ|ཞོགས་ཀས|ཉིན་གུང|དགོང་དག|མཚན་མོ/,\n    meridiemHour : function (hour, meridiem) {\n        if (hour === 12) {\n            hour = 0;\n        }\n        if ((meridiem === 'མཚན་མོ' && hour >= 4) ||\n                (meridiem === 'ཉིན་གུང' && hour < 5) ||\n                meridiem === 'དགོང་དག') {\n            return hour + 12;\n        } else {\n            return hour;\n        }\n    },\n    meridiem : function (hour, minute, isLower) {\n        if (hour < 4) {\n            return 'མཚན་མོ';\n        } else if (hour < 10) {\n            return 'ཞོགས་ཀས';\n        } else if (hour < 17) {\n            return 'ཉིན་གུང';\n        } else if (hour < 20) {\n            return 'དགོང་དག';\n        } else {\n            return 'མཚན་མོ';\n        }\n    },\n    week : {\n        dow : 0, // Sunday is the first day of the week.\n        doy : 6  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Breton [br]\n//! author : Jean-Baptiste Le Duigou : https://github.com/jbleduigou\n\nfunction relativeTimeWithMutation(number, withoutSuffix, key) {\n    var format = {\n        'mm': 'munutenn',\n        'MM': 'miz',\n        'dd': 'devezh'\n    };\n    return number + ' ' + mutation(format[key], number);\n}\nfunction specialMutationForYears(number) {\n    switch (lastNumber(number)) {\n        case 1:\n        case 3:\n        case 4:\n        case 5:\n        case 9:\n            return number + ' bloaz';\n        default:\n            return number + ' vloaz';\n    }\n}\nfunction lastNumber(number) {\n    if (number > 9) {\n        return lastNumber(number % 10);\n    }\n    return number;\n}\nfunction mutation(text, number) {\n    if (number === 2) {\n        return softMutation(text);\n    }\n    return text;\n}\nfunction softMutation(text) {\n    var mutationTable = {\n        'm': 'v',\n        'b': 'v',\n        'd': 'z'\n    };\n    if (mutationTable[text.charAt(0)] === undefined) {\n        return text;\n    }\n    return mutationTable[text.charAt(0)] + text.substring(1);\n}\n\nhooks.defineLocale('br', {\n    months : 'Genver_C\\'hwevrer_Meurzh_Ebrel_Mae_Mezheven_Gouere_Eost_Gwengolo_Here_Du_Kerzu'.split('_'),\n    monthsShort : 'Gen_C\\'hwe_Meu_Ebr_Mae_Eve_Gou_Eos_Gwe_Her_Du_Ker'.split('_'),\n    weekdays : 'Sul_Lun_Meurzh_Merc\\'her_Yaou_Gwener_Sadorn'.split('_'),\n    weekdaysShort : 'Sul_Lun_Meu_Mer_Yao_Gwe_Sad'.split('_'),\n    weekdaysMin : 'Su_Lu_Me_Mer_Ya_Gw_Sa'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat : {\n        LT : 'h[e]mm A',\n        LTS : 'h[e]mm:ss A',\n        L : 'DD/MM/YYYY',\n        LL : 'D [a viz] MMMM YYYY',\n        LLL : 'D [a viz] MMMM YYYY h[e]mm A',\n        LLLL : 'dddd, D [a viz] MMMM YYYY h[e]mm A'\n    },\n    calendar : {\n        sameDay : '[Hiziv da] LT',\n        nextDay : '[Warc\\'hoazh da] LT',\n        nextWeek : 'dddd [da] LT',\n        lastDay : '[Dec\\'h da] LT',\n        lastWeek : 'dddd [paset da] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'a-benn %s',\n        past : '%s \\'zo',\n        s : 'un nebeud segondennoù',\n        m : 'ur vunutenn',\n        mm : relativeTimeWithMutation,\n        h : 'un eur',\n        hh : '%d eur',\n        d : 'un devezh',\n        dd : relativeTimeWithMutation,\n        M : 'ur miz',\n        MM : relativeTimeWithMutation,\n        y : 'ur bloaz',\n        yy : specialMutationForYears\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}(añ|vet)/,\n    ordinal : function (number) {\n        var output = (number === 1) ? 'añ' : 'vet';\n        return number + output;\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Bosnian [bs]\n//! author : Nedim Cholich : https://github.com/frontyard\n//! based on (hr) translation by Bojan Marković\n\nfunction translate(number, withoutSuffix, key) {\n    var result = number + ' ';\n    switch (key) {\n        case 'm':\n            return withoutSuffix ? 'jedna minuta' : 'jedne minute';\n        case 'mm':\n            if (number === 1) {\n                result += 'minuta';\n            } else if (number === 2 || number === 3 || number === 4) {\n                result += 'minute';\n            } else {\n                result += 'minuta';\n            }\n            return result;\n        case 'h':\n            return withoutSuffix ? 'jedan sat' : 'jednog sata';\n        case 'hh':\n            if (number === 1) {\n                result += 'sat';\n            } else if (number === 2 || number === 3 || number === 4) {\n                result += 'sata';\n            } else {\n                result += 'sati';\n            }\n            return result;\n        case 'dd':\n            if (number === 1) {\n                result += 'dan';\n            } else {\n                result += 'dana';\n            }\n            return result;\n        case 'MM':\n            if (number === 1) {\n                result += 'mjesec';\n            } else if (number === 2 || number === 3 || number === 4) {\n                result += 'mjeseca';\n            } else {\n                result += 'mjeseci';\n            }\n            return result;\n        case 'yy':\n            if (number === 1) {\n                result += 'godina';\n            } else if (number === 2 || number === 3 || number === 4) {\n                result += 'godine';\n            } else {\n                result += 'godina';\n            }\n            return result;\n    }\n}\n\nhooks.defineLocale('bs', {\n    months : 'januar_februar_mart_april_maj_juni_juli_august_septembar_oktobar_novembar_decembar'.split('_'),\n    monthsShort : 'jan._feb._mar._apr._maj._jun._jul._aug._sep._okt._nov._dec.'.split('_'),\n    monthsParseExact: true,\n    weekdays : 'nedjelja_ponedjeljak_utorak_srijeda_četvrtak_petak_subota'.split('_'),\n    weekdaysShort : 'ned._pon._uto._sri._čet._pet._sub.'.split('_'),\n    weekdaysMin : 'ne_po_ut_sr_če_pe_su'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat : {\n        LT : 'H:mm',\n        LTS : 'H:mm:ss',\n        L : 'DD.MM.YYYY',\n        LL : 'D. MMMM YYYY',\n        LLL : 'D. MMMM YYYY H:mm',\n        LLLL : 'dddd, D. MMMM YYYY H:mm'\n    },\n    calendar : {\n        sameDay  : '[danas u] LT',\n        nextDay  : '[sutra u] LT',\n        nextWeek : function () {\n            switch (this.day()) {\n                case 0:\n                    return '[u] [nedjelju] [u] LT';\n                case 3:\n                    return '[u] [srijedu] [u] LT';\n                case 6:\n                    return '[u] [subotu] [u] LT';\n                case 1:\n                case 2:\n                case 4:\n                case 5:\n                    return '[u] dddd [u] LT';\n            }\n        },\n        lastDay  : '[jučer u] LT',\n        lastWeek : function () {\n            switch (this.day()) {\n                case 0:\n                case 3:\n                    return '[prošlu] dddd [u] LT';\n                case 6:\n                    return '[prošle] [subote] [u] LT';\n                case 1:\n                case 2:\n                case 4:\n                case 5:\n                    return '[prošli] dddd [u] LT';\n            }\n        },\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'za %s',\n        past   : 'prije %s',\n        s      : 'par sekundi',\n        m      : translate,\n        mm     : translate,\n        h      : translate,\n        hh     : translate,\n        d      : 'dan',\n        dd     : translate,\n        M      : 'mjesec',\n        MM     : translate,\n        y      : 'godinu',\n        yy     : translate\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}\\./,\n    ordinal : '%d.',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 7  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Catalan [ca]\n//! author : Juan G. Hurtado : https://github.com/juanghurtado\n\nhooks.defineLocale('ca', {\n    months : {\n        standalone: 'gener_febrer_març_abril_maig_juny_juliol_agost_setembre_octubre_novembre_desembre'.split('_'),\n        format: 'de gener_de febrer_de març_d\\'abril_de maig_de juny_de juliol_d\\'agost_de setembre_d\\'octubre_de novembre_de desembre'.split('_'),\n        isFormat: /D[oD]?(\\s)+MMMM/\n    },\n    monthsShort : 'gen._febr._març_abr._maig_juny_jul._ag._set._oct._nov._des.'.split('_'),\n    monthsParseExact : true,\n    weekdays : 'diumenge_dilluns_dimarts_dimecres_dijous_divendres_dissabte'.split('_'),\n    weekdaysShort : 'dg._dl._dt._dc._dj._dv._ds.'.split('_'),\n    weekdaysMin : 'Dg_Dl_Dt_Dc_Dj_Dv_Ds'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat : {\n        LT : 'H:mm',\n        LTS : 'H:mm:ss',\n        L : 'DD/MM/YYYY',\n        LL : '[el] D MMMM [de] YYYY',\n        ll : 'D MMM YYYY',\n        LLL : '[el] D MMMM [de] YYYY [a les] H:mm',\n        lll : 'D MMM YYYY, H:mm',\n        LLLL : '[el] dddd D MMMM [de] YYYY [a les] H:mm',\n        llll : 'ddd D MMM YYYY, H:mm'\n    },\n    calendar : {\n        sameDay : function () {\n            return '[avui a ' + ((this.hours() !== 1) ? 'les' : 'la') + '] LT';\n        },\n        nextDay : function () {\n            return '[demà a ' + ((this.hours() !== 1) ? 'les' : 'la') + '] LT';\n        },\n        nextWeek : function () {\n            return 'dddd [a ' + ((this.hours() !== 1) ? 'les' : 'la') + '] LT';\n        },\n        lastDay : function () {\n            return '[ahir a ' + ((this.hours() !== 1) ? 'les' : 'la') + '] LT';\n        },\n        lastWeek : function () {\n            return '[el] dddd [passat a ' + ((this.hours() !== 1) ? 'les' : 'la') + '] LT';\n        },\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'd\\'aquí %s',\n        past : 'fa %s',\n        s : 'uns segons',\n        m : 'un minut',\n        mm : '%d minuts',\n        h : 'una hora',\n        hh : '%d hores',\n        d : 'un dia',\n        dd : '%d dies',\n        M : 'un mes',\n        MM : '%d mesos',\n        y : 'un any',\n        yy : '%d anys'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}(r|n|t|è|a)/,\n    ordinal : function (number, period) {\n        var output = (number === 1) ? 'r' :\n            (number === 2) ? 'n' :\n            (number === 3) ? 'r' :\n            (number === 4) ? 't' : 'è';\n        if (period === 'w' || period === 'W') {\n            output = 'a';\n        }\n        return number + output;\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Czech [cs]\n//! author : petrbela : https://github.com/petrbela\n\nvar months$3 = 'leden_únor_březen_duben_květen_červen_červenec_srpen_září_říjen_listopad_prosinec'.split('_');\nvar monthsShort = 'led_úno_bře_dub_kvě_čvn_čvc_srp_zář_říj_lis_pro'.split('_');\nfunction plural$1(n) {\n    return (n > 1) && (n < 5) && (~~(n / 10) !== 1);\n}\nfunction translate$1(number, withoutSuffix, key, isFuture) {\n    var result = number + ' ';\n    switch (key) {\n        case 's':  // a few seconds / in a few seconds / a few seconds ago\n            return (withoutSuffix || isFuture) ? 'pár sekund' : 'pár sekundami';\n        case 'm':  // a minute / in a minute / a minute ago\n            return withoutSuffix ? 'minuta' : (isFuture ? 'minutu' : 'minutou');\n        case 'mm': // 9 minutes / in 9 minutes / 9 minutes ago\n            if (withoutSuffix || isFuture) {\n                return result + (plural$1(number) ? 'minuty' : 'minut');\n            } else {\n                return result + 'minutami';\n            }\n            break;\n        case 'h':  // an hour / in an hour / an hour ago\n            return withoutSuffix ? 'hodina' : (isFuture ? 'hodinu' : 'hodinou');\n        case 'hh': // 9 hours / in 9 hours / 9 hours ago\n            if (withoutSuffix || isFuture) {\n                return result + (plural$1(number) ? 'hodiny' : 'hodin');\n            } else {\n                return result + 'hodinami';\n            }\n            break;\n        case 'd':  // a day / in a day / a day ago\n            return (withoutSuffix || isFuture) ? 'den' : 'dnem';\n        case 'dd': // 9 days / in 9 days / 9 days ago\n            if (withoutSuffix || isFuture) {\n                return result + (plural$1(number) ? 'dny' : 'dní');\n            } else {\n                return result + 'dny';\n            }\n            break;\n        case 'M':  // a month / in a month / a month ago\n            return (withoutSuffix || isFuture) ? 'měsíc' : 'měsícem';\n        case 'MM': // 9 months / in 9 months / 9 months ago\n            if (withoutSuffix || isFuture) {\n                return result + (plural$1(number) ? 'měsíce' : 'měsíců');\n            } else {\n                return result + 'měsíci';\n            }\n            break;\n        case 'y':  // a year / in a year / a year ago\n            return (withoutSuffix || isFuture) ? 'rok' : 'rokem';\n        case 'yy': // 9 years / in 9 years / 9 years ago\n            if (withoutSuffix || isFuture) {\n                return result + (plural$1(number) ? 'roky' : 'let');\n            } else {\n                return result + 'lety';\n            }\n            break;\n    }\n}\n\nhooks.defineLocale('cs', {\n    months : months$3,\n    monthsShort : monthsShort,\n    monthsParse : (function (months, monthsShort) {\n        var i, _monthsParse = [];\n        for (i = 0; i < 12; i++) {\n            // use custom parser to solve problem with July (červenec)\n            _monthsParse[i] = new RegExp('^' + months[i] + '$|^' + monthsShort[i] + '$', 'i');\n        }\n        return _monthsParse;\n    }(months$3, monthsShort)),\n    shortMonthsParse : (function (monthsShort) {\n        var i, _shortMonthsParse = [];\n        for (i = 0; i < 12; i++) {\n            _shortMonthsParse[i] = new RegExp('^' + monthsShort[i] + '$', 'i');\n        }\n        return _shortMonthsParse;\n    }(monthsShort)),\n    longMonthsParse : (function (months) {\n        var i, _longMonthsParse = [];\n        for (i = 0; i < 12; i++) {\n            _longMonthsParse[i] = new RegExp('^' + months[i] + '$', 'i');\n        }\n        return _longMonthsParse;\n    }(months$3)),\n    weekdays : 'neděle_pondělí_úterý_středa_čtvrtek_pátek_sobota'.split('_'),\n    weekdaysShort : 'ne_po_út_st_čt_pá_so'.split('_'),\n    weekdaysMin : 'ne_po_út_st_čt_pá_so'.split('_'),\n    longDateFormat : {\n        LT: 'H:mm',\n        LTS : 'H:mm:ss',\n        L : 'DD.MM.YYYY',\n        LL : 'D. MMMM YYYY',\n        LLL : 'D. MMMM YYYY H:mm',\n        LLLL : 'dddd D. MMMM YYYY H:mm',\n        l : 'D. M. YYYY'\n    },\n    calendar : {\n        sameDay: '[dnes v] LT',\n        nextDay: '[zítra v] LT',\n        nextWeek: function () {\n            switch (this.day()) {\n                case 0:\n                    return '[v neděli v] LT';\n                case 1:\n                case 2:\n                    return '[v] dddd [v] LT';\n                case 3:\n                    return '[ve středu v] LT';\n                case 4:\n                    return '[ve čtvrtek v] LT';\n                case 5:\n                    return '[v pátek v] LT';\n                case 6:\n                    return '[v sobotu v] LT';\n            }\n        },\n        lastDay: '[včera v] LT',\n        lastWeek: function () {\n            switch (this.day()) {\n                case 0:\n                    return '[minulou neděli v] LT';\n                case 1:\n                case 2:\n                    return '[minulé] dddd [v] LT';\n                case 3:\n                    return '[minulou středu v] LT';\n                case 4:\n                case 5:\n                    return '[minulý] dddd [v] LT';\n                case 6:\n                    return '[minulou sobotu v] LT';\n            }\n        },\n        sameElse: 'L'\n    },\n    relativeTime : {\n        future : 'za %s',\n        past : 'před %s',\n        s : translate$1,\n        m : translate$1,\n        mm : translate$1,\n        h : translate$1,\n        hh : translate$1,\n        d : translate$1,\n        dd : translate$1,\n        M : translate$1,\n        MM : translate$1,\n        y : translate$1,\n        yy : translate$1\n    },\n    dayOfMonthOrdinalParse : /\\d{1,2}\\./,\n    ordinal : '%d.',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Chuvash [cv]\n//! author : Anatoly Mironov : https://github.com/mirontoli\n\nhooks.defineLocale('cv', {\n    months : 'кӑрлач_нарӑс_пуш_ака_май_ҫӗртме_утӑ_ҫурла_авӑн_юпа_чӳк_раштав'.split('_'),\n    monthsShort : 'кӑр_нар_пуш_ака_май_ҫӗр_утӑ_ҫур_авн_юпа_чӳк_раш'.split('_'),\n    weekdays : 'вырсарникун_тунтикун_ытларикун_юнкун_кӗҫнерникун_эрнекун_шӑматкун'.split('_'),\n    weekdaysShort : 'выр_тун_ытл_юн_кӗҫ_эрн_шӑм'.split('_'),\n    weekdaysMin : 'вр_тн_ыт_юн_кҫ_эр_шм'.split('_'),\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD-MM-YYYY',\n        LL : 'YYYY [ҫулхи] MMMM [уйӑхӗн] D[-мӗшӗ]',\n        LLL : 'YYYY [ҫулхи] MMMM [уйӑхӗн] D[-мӗшӗ], HH:mm',\n        LLLL : 'dddd, YYYY [ҫулхи] MMMM [уйӑхӗн] D[-мӗшӗ], HH:mm'\n    },\n    calendar : {\n        sameDay: '[Паян] LT [сехетре]',\n        nextDay: '[Ыран] LT [сехетре]',\n        lastDay: '[Ӗнер] LT [сехетре]',\n        nextWeek: '[Ҫитес] dddd LT [сехетре]',\n        lastWeek: '[Иртнӗ] dddd LT [сехетре]',\n        sameElse: 'L'\n    },\n    relativeTime : {\n        future : function (output) {\n            var affix = /сехет$/i.exec(output) ? 'рен' : /ҫул$/i.exec(output) ? 'тан' : 'ран';\n            return output + affix;\n        },\n        past : '%s каялла',\n        s : 'пӗр-ик ҫеккунт',\n        m : 'пӗр минут',\n        mm : '%d минут',\n        h : 'пӗр сехет',\n        hh : '%d сехет',\n        d : 'пӗр кун',\n        dd : '%d кун',\n        M : 'пӗр уйӑх',\n        MM : '%d уйӑх',\n        y : 'пӗр ҫул',\n        yy : '%d ҫул'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}-мӗш/,\n    ordinal : '%d-мӗш',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 7  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Welsh [cy]\n//! author : Robert Allen : https://github.com/robgallen\n//! author : https://github.com/ryangreaves\n\nhooks.defineLocale('cy', {\n    months: 'Ionawr_Chwefror_Mawrth_Ebrill_Mai_Mehefin_Gorffennaf_Awst_Medi_Hydref_Tachwedd_Rhagfyr'.split('_'),\n    monthsShort: 'Ion_Chwe_Maw_Ebr_Mai_Meh_Gor_Aws_Med_Hyd_Tach_Rhag'.split('_'),\n    weekdays: 'Dydd Sul_Dydd Llun_Dydd Mawrth_Dydd Mercher_Dydd Iau_Dydd Gwener_Dydd Sadwrn'.split('_'),\n    weekdaysShort: 'Sul_Llun_Maw_Mer_Iau_Gwe_Sad'.split('_'),\n    weekdaysMin: 'Su_Ll_Ma_Me_Ia_Gw_Sa'.split('_'),\n    weekdaysParseExact : true,\n    // time formats are the same as en-gb\n    longDateFormat: {\n        LT: 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L: 'DD/MM/YYYY',\n        LL: 'D MMMM YYYY',\n        LLL: 'D MMMM YYYY HH:mm',\n        LLLL: 'dddd, D MMMM YYYY HH:mm'\n    },\n    calendar: {\n        sameDay: '[Heddiw am] LT',\n        nextDay: '[Yfory am] LT',\n        nextWeek: 'dddd [am] LT',\n        lastDay: '[Ddoe am] LT',\n        lastWeek: 'dddd [diwethaf am] LT',\n        sameElse: 'L'\n    },\n    relativeTime: {\n        future: 'mewn %s',\n        past: '%s yn ôl',\n        s: 'ychydig eiliadau',\n        m: 'munud',\n        mm: '%d munud',\n        h: 'awr',\n        hh: '%d awr',\n        d: 'diwrnod',\n        dd: '%d diwrnod',\n        M: 'mis',\n        MM: '%d mis',\n        y: 'blwyddyn',\n        yy: '%d flynedd'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}(fed|ain|af|il|ydd|ed|eg)/,\n    // traditional ordinal numbers above 31 are not commonly used in colloquial Welsh\n    ordinal: function (number) {\n        var b = number,\n            output = '',\n            lookup = [\n                '', 'af', 'il', 'ydd', 'ydd', 'ed', 'ed', 'ed', 'fed', 'fed', 'fed', // 1af to 10fed\n                'eg', 'fed', 'eg', 'eg', 'fed', 'eg', 'eg', 'fed', 'eg', 'fed' // 11eg to 20fed\n            ];\n        if (b > 20) {\n            if (b === 40 || b === 50 || b === 60 || b === 80 || b === 100) {\n                output = 'fed'; // not 30ain, 70ain or 90ain\n            } else {\n                output = 'ain';\n            }\n        } else if (b > 0) {\n            output = lookup[b];\n        }\n        return number + output;\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Danish [da]\n//! author : Ulrik Nielsen : https://github.com/mrbase\n\nhooks.defineLocale('da', {\n    months : 'januar_februar_marts_april_maj_juni_juli_august_september_oktober_november_december'.split('_'),\n    monthsShort : 'jan_feb_mar_apr_maj_jun_jul_aug_sep_okt_nov_dec'.split('_'),\n    weekdays : 'søndag_mandag_tirsdag_onsdag_torsdag_fredag_lørdag'.split('_'),\n    weekdaysShort : 'søn_man_tir_ons_tor_fre_lør'.split('_'),\n    weekdaysMin : 'sø_ma_ti_on_to_fr_lø'.split('_'),\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D. MMMM YYYY',\n        LLL : 'D. MMMM YYYY HH:mm',\n        LLLL : 'dddd [d.] D. MMMM YYYY [kl.] HH:mm'\n    },\n    calendar : {\n        sameDay : '[i dag kl.] LT',\n        nextDay : '[i morgen kl.] LT',\n        nextWeek : 'på dddd [kl.] LT',\n        lastDay : '[i går kl.] LT',\n        lastWeek : '[i] dddd[s kl.] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'om %s',\n        past : '%s siden',\n        s : 'få sekunder',\n        m : 'et minut',\n        mm : '%d minutter',\n        h : 'en time',\n        hh : '%d timer',\n        d : 'en dag',\n        dd : '%d dage',\n        M : 'en måned',\n        MM : '%d måneder',\n        y : 'et år',\n        yy : '%d år'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}\\./,\n    ordinal : '%d.',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : German (Austria) [de-at]\n//! author : lluchs : https://github.com/lluchs\n//! author: Menelion Elensúle: https://github.com/Oire\n//! author : Martin Groller : https://github.com/MadMG\n//! author : Mikolaj Dadela : https://github.com/mik01aj\n\nfunction processRelativeTime(number, withoutSuffix, key, isFuture) {\n    var format = {\n        'm': ['eine Minute', 'einer Minute'],\n        'h': ['eine Stunde', 'einer Stunde'],\n        'd': ['ein Tag', 'einem Tag'],\n        'dd': [number + ' Tage', number + ' Tagen'],\n        'M': ['ein Monat', 'einem Monat'],\n        'MM': [number + ' Monate', number + ' Monaten'],\n        'y': ['ein Jahr', 'einem Jahr'],\n        'yy': [number + ' Jahre', number + ' Jahren']\n    };\n    return withoutSuffix ? format[key][0] : format[key][1];\n}\n\nhooks.defineLocale('de-at', {\n    months : 'Jänner_Februar_März_April_Mai_Juni_Juli_August_September_Oktober_November_Dezember'.split('_'),\n    monthsShort : 'Jän._Febr._Mrz._Apr._Mai_Jun._Jul._Aug._Sept._Okt._Nov._Dez.'.split('_'),\n    monthsParseExact : true,\n    weekdays : 'Sonntag_Montag_Dienstag_Mittwoch_Donnerstag_Freitag_Samstag'.split('_'),\n    weekdaysShort : 'So._Mo._Di._Mi._Do._Fr._Sa.'.split('_'),\n    weekdaysMin : 'So_Mo_Di_Mi_Do_Fr_Sa'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat : {\n        LT: 'HH:mm',\n        LTS: 'HH:mm:ss',\n        L : 'DD.MM.YYYY',\n        LL : 'D. MMMM YYYY',\n        LLL : 'D. MMMM YYYY HH:mm',\n        LLLL : 'dddd, D. MMMM YYYY HH:mm'\n    },\n    calendar : {\n        sameDay: '[heute um] LT [Uhr]',\n        sameElse: 'L',\n        nextDay: '[morgen um] LT [Uhr]',\n        nextWeek: 'dddd [um] LT [Uhr]',\n        lastDay: '[gestern um] LT [Uhr]',\n        lastWeek: '[letzten] dddd [um] LT [Uhr]'\n    },\n    relativeTime : {\n        future : 'in %s',\n        past : 'vor %s',\n        s : 'ein paar Sekunden',\n        m : processRelativeTime,\n        mm : '%d Minuten',\n        h : processRelativeTime,\n        hh : '%d Stunden',\n        d : processRelativeTime,\n        dd : processRelativeTime,\n        M : processRelativeTime,\n        MM : processRelativeTime,\n        y : processRelativeTime,\n        yy : processRelativeTime\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}\\./,\n    ordinal : '%d.',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : German (Switzerland) [de-ch]\n//! author : sschueller : https://github.com/sschueller\n\n// based on: https://www.bk.admin.ch/dokumentation/sprachen/04915/05016/index.html?lang=de#\n\nfunction processRelativeTime$1(number, withoutSuffix, key, isFuture) {\n    var format = {\n        'm': ['eine Minute', 'einer Minute'],\n        'h': ['eine Stunde', 'einer Stunde'],\n        'd': ['ein Tag', 'einem Tag'],\n        'dd': [number + ' Tage', number + ' Tagen'],\n        'M': ['ein Monat', 'einem Monat'],\n        'MM': [number + ' Monate', number + ' Monaten'],\n        'y': ['ein Jahr', 'einem Jahr'],\n        'yy': [number + ' Jahre', number + ' Jahren']\n    };\n    return withoutSuffix ? format[key][0] : format[key][1];\n}\n\nhooks.defineLocale('de-ch', {\n    months : 'Januar_Februar_März_April_Mai_Juni_Juli_August_September_Oktober_November_Dezember'.split('_'),\n    monthsShort : 'Jan._Febr._März_April_Mai_Juni_Juli_Aug._Sept._Okt._Nov._Dez.'.split('_'),\n    monthsParseExact : true,\n    weekdays : 'Sonntag_Montag_Dienstag_Mittwoch_Donnerstag_Freitag_Samstag'.split('_'),\n    weekdaysShort : 'So_Mo_Di_Mi_Do_Fr_Sa'.split('_'),\n    weekdaysMin : 'So_Mo_Di_Mi_Do_Fr_Sa'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat : {\n        LT: 'HH.mm',\n        LTS: 'HH.mm.ss',\n        L : 'DD.MM.YYYY',\n        LL : 'D. MMMM YYYY',\n        LLL : 'D. MMMM YYYY HH.mm',\n        LLLL : 'dddd, D. MMMM YYYY HH.mm'\n    },\n    calendar : {\n        sameDay: '[heute um] LT [Uhr]',\n        sameElse: 'L',\n        nextDay: '[morgen um] LT [Uhr]',\n        nextWeek: 'dddd [um] LT [Uhr]',\n        lastDay: '[gestern um] LT [Uhr]',\n        lastWeek: '[letzten] dddd [um] LT [Uhr]'\n    },\n    relativeTime : {\n        future : 'in %s',\n        past : 'vor %s',\n        s : 'ein paar Sekunden',\n        m : processRelativeTime$1,\n        mm : '%d Minuten',\n        h : processRelativeTime$1,\n        hh : '%d Stunden',\n        d : processRelativeTime$1,\n        dd : processRelativeTime$1,\n        M : processRelativeTime$1,\n        MM : processRelativeTime$1,\n        y : processRelativeTime$1,\n        yy : processRelativeTime$1\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}\\./,\n    ordinal : '%d.',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : German [de]\n//! author : lluchs : https://github.com/lluchs\n//! author: Menelion Elensúle: https://github.com/Oire\n//! author : Mikolaj Dadela : https://github.com/mik01aj\n\nfunction processRelativeTime$2(number, withoutSuffix, key, isFuture) {\n    var format = {\n        'm': ['eine Minute', 'einer Minute'],\n        'h': ['eine Stunde', 'einer Stunde'],\n        'd': ['ein Tag', 'einem Tag'],\n        'dd': [number + ' Tage', number + ' Tagen'],\n        'M': ['ein Monat', 'einem Monat'],\n        'MM': [number + ' Monate', number + ' Monaten'],\n        'y': ['ein Jahr', 'einem Jahr'],\n        'yy': [number + ' Jahre', number + ' Jahren']\n    };\n    return withoutSuffix ? format[key][0] : format[key][1];\n}\n\nhooks.defineLocale('de', {\n    months : 'Januar_Februar_März_April_Mai_Juni_Juli_August_September_Oktober_November_Dezember'.split('_'),\n    monthsShort : 'Jan._Febr._Mrz._Apr._Mai_Jun._Jul._Aug._Sept._Okt._Nov._Dez.'.split('_'),\n    monthsParseExact : true,\n    weekdays : 'Sonntag_Montag_Dienstag_Mittwoch_Donnerstag_Freitag_Samstag'.split('_'),\n    weekdaysShort : 'So._Mo._Di._Mi._Do._Fr._Sa.'.split('_'),\n    weekdaysMin : 'So_Mo_Di_Mi_Do_Fr_Sa'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat : {\n        LT: 'HH:mm',\n        LTS: 'HH:mm:ss',\n        L : 'DD.MM.YYYY',\n        LL : 'D. MMMM YYYY',\n        LLL : 'D. MMMM YYYY HH:mm',\n        LLLL : 'dddd, D. MMMM YYYY HH:mm'\n    },\n    calendar : {\n        sameDay: '[heute um] LT [Uhr]',\n        sameElse: 'L',\n        nextDay: '[morgen um] LT [Uhr]',\n        nextWeek: 'dddd [um] LT [Uhr]',\n        lastDay: '[gestern um] LT [Uhr]',\n        lastWeek: '[letzten] dddd [um] LT [Uhr]'\n    },\n    relativeTime : {\n        future : 'in %s',\n        past : 'vor %s',\n        s : 'ein paar Sekunden',\n        m : processRelativeTime$2,\n        mm : '%d Minuten',\n        h : processRelativeTime$2,\n        hh : '%d Stunden',\n        d : processRelativeTime$2,\n        dd : processRelativeTime$2,\n        M : processRelativeTime$2,\n        MM : processRelativeTime$2,\n        y : processRelativeTime$2,\n        yy : processRelativeTime$2\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}\\./,\n    ordinal : '%d.',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Maldivian [dv]\n//! author : Jawish Hameed : https://github.com/jawish\n\nvar months$4 = [\n    'ޖެނުއަރީ',\n    'ފެބްރުއަރީ',\n    'މާރިޗު',\n    'އޭޕްރީލު',\n    'މޭ',\n    'ޖޫން',\n    'ޖުލައި',\n    'އޯގަސްޓު',\n    'ސެޕްޓެމްބަރު',\n    'އޮކްޓޯބަރު',\n    'ނޮވެމްބަރު',\n    'ޑިސެމްބަރު'\n];\nvar weekdays = [\n    'އާދިއްތަ',\n    'ހޯމަ',\n    'އަންގާރަ',\n    'ބުދަ',\n    'ބުރާސްފަތި',\n    'ހުކުރު',\n    'ހޮނިހިރު'\n];\n\nhooks.defineLocale('dv', {\n    months : months$4,\n    monthsShort : months$4,\n    weekdays : weekdays,\n    weekdaysShort : weekdays,\n    weekdaysMin : 'އާދި_ހޯމަ_އަން_ބުދަ_ބުރާ_ހުކު_ހޮނި'.split('_'),\n    longDateFormat : {\n\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'D/M/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY HH:mm',\n        LLLL : 'dddd D MMMM YYYY HH:mm'\n    },\n    meridiemParse: /މކ|މފ/,\n    isPM : function (input) {\n        return 'މފ' === input;\n    },\n    meridiem : function (hour, minute, isLower) {\n        if (hour < 12) {\n            return 'މކ';\n        } else {\n            return 'މފ';\n        }\n    },\n    calendar : {\n        sameDay : '[މިއަދު] LT',\n        nextDay : '[މާދަމާ] LT',\n        nextWeek : 'dddd LT',\n        lastDay : '[އިއްޔެ] LT',\n        lastWeek : '[ފާއިތުވި] dddd LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'ތެރޭގައި %s',\n        past : 'ކުރިން %s',\n        s : 'ސިކުންތުކޮޅެއް',\n        m : 'މިނިޓެއް',\n        mm : 'މިނިޓު %d',\n        h : 'ގަޑިއިރެއް',\n        hh : 'ގަޑިއިރު %d',\n        d : 'ދުވަހެއް',\n        dd : 'ދުވަސް %d',\n        M : 'މަހެއް',\n        MM : 'މަސް %d',\n        y : 'އަހަރެއް',\n        yy : 'އަހަރު %d'\n    },\n    preparse: function (string) {\n        return string.replace(/،/g, ',');\n    },\n    postformat: function (string) {\n        return string.replace(/,/g, '،');\n    },\n    week : {\n        dow : 7,  // Sunday is the first day of the week.\n        doy : 12  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Greek [el]\n//! author : Aggelos Karalias : https://github.com/mehiel\n\nhooks.defineLocale('el', {\n    monthsNominativeEl : 'Ιανουάριος_Φεβρουάριος_Μάρτιος_Απρίλιος_Μάιος_Ιούνιος_Ιούλιος_Αύγουστος_Σεπτέμβριος_Οκτώβριος_Νοέμβριος_Δεκέμβριος'.split('_'),\n    monthsGenitiveEl : 'Ιανουαρίου_Φεβρουαρίου_Μαρτίου_Απριλίου_Μαΐου_Ιουνίου_Ιουλίου_Αυγούστου_Σεπτεμβρίου_Οκτωβρίου_Νοεμβρίου_Δεκεμβρίου'.split('_'),\n    months : function (momentToFormat, format) {\n        if (!momentToFormat) {\n            return this._monthsNominativeEl;\n        } else if (/D/.test(format.substring(0, format.indexOf('MMMM')))) { // if there is a day number before 'MMMM'\n            return this._monthsGenitiveEl[momentToFormat.month()];\n        } else {\n            return this._monthsNominativeEl[momentToFormat.month()];\n        }\n    },\n    monthsShort : 'Ιαν_Φεβ_Μαρ_Απρ_Μαϊ_Ιουν_Ιουλ_Αυγ_Σεπ_Οκτ_Νοε_Δεκ'.split('_'),\n    weekdays : 'Κυριακή_Δευτέρα_Τρίτη_Τετάρτη_Πέμπτη_Παρασκευή_Σάββατο'.split('_'),\n    weekdaysShort : 'Κυρ_Δευ_Τρι_Τετ_Πεμ_Παρ_Σαβ'.split('_'),\n    weekdaysMin : 'Κυ_Δε_Τρ_Τε_Πε_Πα_Σα'.split('_'),\n    meridiem : function (hours, minutes, isLower) {\n        if (hours > 11) {\n            return isLower ? 'μμ' : 'ΜΜ';\n        } else {\n            return isLower ? 'πμ' : 'ΠΜ';\n        }\n    },\n    isPM : function (input) {\n        return ((input + '').toLowerCase()[0] === 'μ');\n    },\n    meridiemParse : /[ΠΜ]\\.?Μ?\\.?/i,\n    longDateFormat : {\n        LT : 'h:mm A',\n        LTS : 'h:mm:ss A',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY h:mm A',\n        LLLL : 'dddd, D MMMM YYYY h:mm A'\n    },\n    calendarEl : {\n        sameDay : '[Σήμερα {}] LT',\n        nextDay : '[Αύριο {}] LT',\n        nextWeek : 'dddd [{}] LT',\n        lastDay : '[Χθες {}] LT',\n        lastWeek : function () {\n            switch (this.day()) {\n                case 6:\n                    return '[το προηγούμενο] dddd [{}] LT';\n                default:\n                    return '[την προηγούμενη] dddd [{}] LT';\n            }\n        },\n        sameElse : 'L'\n    },\n    calendar : function (key, mom) {\n        var output = this._calendarEl[key],\n            hours = mom && mom.hours();\n        if (isFunction(output)) {\n            output = output.apply(mom);\n        }\n        return output.replace('{}', (hours % 12 === 1 ? 'στη' : 'στις'));\n    },\n    relativeTime : {\n        future : 'σε %s',\n        past : '%s πριν',\n        s : 'λίγα δευτερόλεπτα',\n        m : 'ένα λεπτό',\n        mm : '%d λεπτά',\n        h : 'μία ώρα',\n        hh : '%d ώρες',\n        d : 'μία μέρα',\n        dd : '%d μέρες',\n        M : 'ένας μήνας',\n        MM : '%d μήνες',\n        y : 'ένας χρόνος',\n        yy : '%d χρόνια'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}η/,\n    ordinal: '%dη',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4st is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : English (Australia) [en-au]\n//! author : Jared Morse : https://github.com/jarcoal\n\nhooks.defineLocale('en-au', {\n    months : 'January_February_March_April_May_June_July_August_September_October_November_December'.split('_'),\n    monthsShort : 'Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec'.split('_'),\n    weekdays : 'Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday'.split('_'),\n    weekdaysShort : 'Sun_Mon_Tue_Wed_Thu_Fri_Sat'.split('_'),\n    weekdaysMin : 'Su_Mo_Tu_We_Th_Fr_Sa'.split('_'),\n    longDateFormat : {\n        LT : 'h:mm A',\n        LTS : 'h:mm:ss A',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY h:mm A',\n        LLLL : 'dddd, D MMMM YYYY h:mm A'\n    },\n    calendar : {\n        sameDay : '[Today at] LT',\n        nextDay : '[Tomorrow at] LT',\n        nextWeek : 'dddd [at] LT',\n        lastDay : '[Yesterday at] LT',\n        lastWeek : '[Last] dddd [at] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'in %s',\n        past : '%s ago',\n        s : 'a few seconds',\n        m : 'a minute',\n        mm : '%d minutes',\n        h : 'an hour',\n        hh : '%d hours',\n        d : 'a day',\n        dd : '%d days',\n        M : 'a month',\n        MM : '%d months',\n        y : 'a year',\n        yy : '%d years'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}(st|nd|rd|th)/,\n    ordinal : function (number) {\n        var b = number % 10,\n            output = (~~(number % 100 / 10) === 1) ? 'th' :\n            (b === 1) ? 'st' :\n            (b === 2) ? 'nd' :\n            (b === 3) ? 'rd' : 'th';\n        return number + output;\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : English (Canada) [en-ca]\n//! author : Jonathan Abourbih : https://github.com/jonbca\n\nhooks.defineLocale('en-ca', {\n    months : 'January_February_March_April_May_June_July_August_September_October_November_December'.split('_'),\n    monthsShort : 'Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec'.split('_'),\n    weekdays : 'Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday'.split('_'),\n    weekdaysShort : 'Sun_Mon_Tue_Wed_Thu_Fri_Sat'.split('_'),\n    weekdaysMin : 'Su_Mo_Tu_We_Th_Fr_Sa'.split('_'),\n    longDateFormat : {\n        LT : 'h:mm A',\n        LTS : 'h:mm:ss A',\n        L : 'YYYY-MM-DD',\n        LL : 'MMMM D, YYYY',\n        LLL : 'MMMM D, YYYY h:mm A',\n        LLLL : 'dddd, MMMM D, YYYY h:mm A'\n    },\n    calendar : {\n        sameDay : '[Today at] LT',\n        nextDay : '[Tomorrow at] LT',\n        nextWeek : 'dddd [at] LT',\n        lastDay : '[Yesterday at] LT',\n        lastWeek : '[Last] dddd [at] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'in %s',\n        past : '%s ago',\n        s : 'a few seconds',\n        m : 'a minute',\n        mm : '%d minutes',\n        h : 'an hour',\n        hh : '%d hours',\n        d : 'a day',\n        dd : '%d days',\n        M : 'a month',\n        MM : '%d months',\n        y : 'a year',\n        yy : '%d years'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}(st|nd|rd|th)/,\n    ordinal : function (number) {\n        var b = number % 10,\n            output = (~~(number % 100 / 10) === 1) ? 'th' :\n            (b === 1) ? 'st' :\n            (b === 2) ? 'nd' :\n            (b === 3) ? 'rd' : 'th';\n        return number + output;\n    }\n});\n\n//! moment.js locale configuration\n//! locale : English (United Kingdom) [en-gb]\n//! author : Chris Gedrim : https://github.com/chrisgedrim\n\nhooks.defineLocale('en-gb', {\n    months : 'January_February_March_April_May_June_July_August_September_October_November_December'.split('_'),\n    monthsShort : 'Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec'.split('_'),\n    weekdays : 'Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday'.split('_'),\n    weekdaysShort : 'Sun_Mon_Tue_Wed_Thu_Fri_Sat'.split('_'),\n    weekdaysMin : 'Su_Mo_Tu_We_Th_Fr_Sa'.split('_'),\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY HH:mm',\n        LLLL : 'dddd, D MMMM YYYY HH:mm'\n    },\n    calendar : {\n        sameDay : '[Today at] LT',\n        nextDay : '[Tomorrow at] LT',\n        nextWeek : 'dddd [at] LT',\n        lastDay : '[Yesterday at] LT',\n        lastWeek : '[Last] dddd [at] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'in %s',\n        past : '%s ago',\n        s : 'a few seconds',\n        m : 'a minute',\n        mm : '%d minutes',\n        h : 'an hour',\n        hh : '%d hours',\n        d : 'a day',\n        dd : '%d days',\n        M : 'a month',\n        MM : '%d months',\n        y : 'a year',\n        yy : '%d years'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}(st|nd|rd|th)/,\n    ordinal : function (number) {\n        var b = number % 10,\n            output = (~~(number % 100 / 10) === 1) ? 'th' :\n            (b === 1) ? 'st' :\n            (b === 2) ? 'nd' :\n            (b === 3) ? 'rd' : 'th';\n        return number + output;\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : English (Ireland) [en-ie]\n//! author : Chris Cartlidge : https://github.com/chriscartlidge\n\nhooks.defineLocale('en-ie', {\n    months : 'January_February_March_April_May_June_July_August_September_October_November_December'.split('_'),\n    monthsShort : 'Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec'.split('_'),\n    weekdays : 'Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday'.split('_'),\n    weekdaysShort : 'Sun_Mon_Tue_Wed_Thu_Fri_Sat'.split('_'),\n    weekdaysMin : 'Su_Mo_Tu_We_Th_Fr_Sa'.split('_'),\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD-MM-YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY HH:mm',\n        LLLL : 'dddd D MMMM YYYY HH:mm'\n    },\n    calendar : {\n        sameDay : '[Today at] LT',\n        nextDay : '[Tomorrow at] LT',\n        nextWeek : 'dddd [at] LT',\n        lastDay : '[Yesterday at] LT',\n        lastWeek : '[Last] dddd [at] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'in %s',\n        past : '%s ago',\n        s : 'a few seconds',\n        m : 'a minute',\n        mm : '%d minutes',\n        h : 'an hour',\n        hh : '%d hours',\n        d : 'a day',\n        dd : '%d days',\n        M : 'a month',\n        MM : '%d months',\n        y : 'a year',\n        yy : '%d years'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}(st|nd|rd|th)/,\n    ordinal : function (number) {\n        var b = number % 10,\n            output = (~~(number % 100 / 10) === 1) ? 'th' :\n            (b === 1) ? 'st' :\n            (b === 2) ? 'nd' :\n            (b === 3) ? 'rd' : 'th';\n        return number + output;\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : English (New Zealand) [en-nz]\n//! author : Luke McGregor : https://github.com/lukemcgregor\n\nhooks.defineLocale('en-nz', {\n    months : 'January_February_March_April_May_June_July_August_September_October_November_December'.split('_'),\n    monthsShort : 'Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec'.split('_'),\n    weekdays : 'Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday'.split('_'),\n    weekdaysShort : 'Sun_Mon_Tue_Wed_Thu_Fri_Sat'.split('_'),\n    weekdaysMin : 'Su_Mo_Tu_We_Th_Fr_Sa'.split('_'),\n    longDateFormat : {\n        LT : 'h:mm A',\n        LTS : 'h:mm:ss A',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY h:mm A',\n        LLLL : 'dddd, D MMMM YYYY h:mm A'\n    },\n    calendar : {\n        sameDay : '[Today at] LT',\n        nextDay : '[Tomorrow at] LT',\n        nextWeek : 'dddd [at] LT',\n        lastDay : '[Yesterday at] LT',\n        lastWeek : '[Last] dddd [at] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'in %s',\n        past : '%s ago',\n        s : 'a few seconds',\n        m : 'a minute',\n        mm : '%d minutes',\n        h : 'an hour',\n        hh : '%d hours',\n        d : 'a day',\n        dd : '%d days',\n        M : 'a month',\n        MM : '%d months',\n        y : 'a year',\n        yy : '%d years'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}(st|nd|rd|th)/,\n    ordinal : function (number) {\n        var b = number % 10,\n            output = (~~(number % 100 / 10) === 1) ? 'th' :\n            (b === 1) ? 'st' :\n            (b === 2) ? 'nd' :\n            (b === 3) ? 'rd' : 'th';\n        return number + output;\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Esperanto [eo]\n//! author : Colin Dean : https://github.com/colindean\n//! author : Mia Nordentoft Imperatori : https://github.com/miestasmia\n//! comment : miestasmia corrected the translation by colindean\n\nhooks.defineLocale('eo', {\n    months : 'januaro_februaro_marto_aprilo_majo_junio_julio_aŭgusto_septembro_oktobro_novembro_decembro'.split('_'),\n    monthsShort : 'jan_feb_mar_apr_maj_jun_jul_aŭg_sep_okt_nov_dec'.split('_'),\n    weekdays : 'dimanĉo_lundo_mardo_merkredo_ĵaŭdo_vendredo_sabato'.split('_'),\n    weekdaysShort : 'dim_lun_mard_merk_ĵaŭ_ven_sab'.split('_'),\n    weekdaysMin : 'di_lu_ma_me_ĵa_ve_sa'.split('_'),\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'YYYY-MM-DD',\n        LL : 'D[-a de] MMMM, YYYY',\n        LLL : 'D[-a de] MMMM, YYYY HH:mm',\n        LLLL : 'dddd, [la] D[-a de] MMMM, YYYY HH:mm'\n    },\n    meridiemParse: /[ap]\\.t\\.m/i,\n    isPM: function (input) {\n        return input.charAt(0).toLowerCase() === 'p';\n    },\n    meridiem : function (hours, minutes, isLower) {\n        if (hours > 11) {\n            return isLower ? 'p.t.m.' : 'P.T.M.';\n        } else {\n            return isLower ? 'a.t.m.' : 'A.T.M.';\n        }\n    },\n    calendar : {\n        sameDay : '[Hodiaŭ je] LT',\n        nextDay : '[Morgaŭ je] LT',\n        nextWeek : 'dddd [je] LT',\n        lastDay : '[Hieraŭ je] LT',\n        lastWeek : '[pasinta] dddd [je] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'post %s',\n        past : 'antaŭ %s',\n        s : 'sekundoj',\n        m : 'minuto',\n        mm : '%d minutoj',\n        h : 'horo',\n        hh : '%d horoj',\n        d : 'tago',//ne 'diurno', ĉar estas uzita por proksimumo\n        dd : '%d tagoj',\n        M : 'monato',\n        MM : '%d monatoj',\n        y : 'jaro',\n        yy : '%d jaroj'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}a/,\n    ordinal : '%da',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 7  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Spanish (Dominican Republic) [es-do]\n\nvar monthsShortDot = 'ene._feb._mar._abr._may._jun._jul._ago._sep._oct._nov._dic.'.split('_');\nvar monthsShort$1 = 'ene_feb_mar_abr_may_jun_jul_ago_sep_oct_nov_dic'.split('_');\n\nhooks.defineLocale('es-do', {\n    months : 'enero_febrero_marzo_abril_mayo_junio_julio_agosto_septiembre_octubre_noviembre_diciembre'.split('_'),\n    monthsShort : function (m, format) {\n        if (!m) {\n            return monthsShortDot;\n        } else if (/-MMM-/.test(format)) {\n            return monthsShort$1[m.month()];\n        } else {\n            return monthsShortDot[m.month()];\n        }\n    },\n    monthsParseExact : true,\n    weekdays : 'domingo_lunes_martes_miércoles_jueves_viernes_sábado'.split('_'),\n    weekdaysShort : 'dom._lun._mar._mié._jue._vie._sáb.'.split('_'),\n    weekdaysMin : 'do_lu_ma_mi_ju_vi_sá'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat : {\n        LT : 'h:mm A',\n        LTS : 'h:mm:ss A',\n        L : 'DD/MM/YYYY',\n        LL : 'D [de] MMMM [de] YYYY',\n        LLL : 'D [de] MMMM [de] YYYY h:mm A',\n        LLLL : 'dddd, D [de] MMMM [de] YYYY h:mm A'\n    },\n    calendar : {\n        sameDay : function () {\n            return '[hoy a la' + ((this.hours() !== 1) ? 's' : '') + '] LT';\n        },\n        nextDay : function () {\n            return '[mañana a la' + ((this.hours() !== 1) ? 's' : '') + '] LT';\n        },\n        nextWeek : function () {\n            return 'dddd [a la' + ((this.hours() !== 1) ? 's' : '') + '] LT';\n        },\n        lastDay : function () {\n            return '[ayer a la' + ((this.hours() !== 1) ? 's' : '') + '] LT';\n        },\n        lastWeek : function () {\n            return '[el] dddd [pasado a la' + ((this.hours() !== 1) ? 's' : '') + '] LT';\n        },\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'en %s',\n        past : 'hace %s',\n        s : 'unos segundos',\n        m : 'un minuto',\n        mm : '%d minutos',\n        h : 'una hora',\n        hh : '%d horas',\n        d : 'un día',\n        dd : '%d días',\n        M : 'un mes',\n        MM : '%d meses',\n        y : 'un año',\n        yy : '%d años'\n    },\n    dayOfMonthOrdinalParse : /\\d{1,2}º/,\n    ordinal : '%dº',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Spanish [es]\n//! author : Julio Napurí : https://github.com/julionc\n\nvar monthsShortDot$1 = 'ene._feb._mar._abr._may._jun._jul._ago._sep._oct._nov._dic.'.split('_');\nvar monthsShort$2 = 'ene_feb_mar_abr_may_jun_jul_ago_sep_oct_nov_dic'.split('_');\n\nhooks.defineLocale('es', {\n    months : 'enero_febrero_marzo_abril_mayo_junio_julio_agosto_septiembre_octubre_noviembre_diciembre'.split('_'),\n    monthsShort : function (m, format) {\n        if (!m) {\n            return monthsShortDot$1;\n        } else if (/-MMM-/.test(format)) {\n            return monthsShort$2[m.month()];\n        } else {\n            return monthsShortDot$1[m.month()];\n        }\n    },\n    monthsParseExact : true,\n    weekdays : 'domingo_lunes_martes_miércoles_jueves_viernes_sábado'.split('_'),\n    weekdaysShort : 'dom._lun._mar._mié._jue._vie._sáb.'.split('_'),\n    weekdaysMin : 'do_lu_ma_mi_ju_vi_sá'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat : {\n        LT : 'H:mm',\n        LTS : 'H:mm:ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D [de] MMMM [de] YYYY',\n        LLL : 'D [de] MMMM [de] YYYY H:mm',\n        LLLL : 'dddd, D [de] MMMM [de] YYYY H:mm'\n    },\n    calendar : {\n        sameDay : function () {\n            return '[hoy a la' + ((this.hours() !== 1) ? 's' : '') + '] LT';\n        },\n        nextDay : function () {\n            return '[mañana a la' + ((this.hours() !== 1) ? 's' : '') + '] LT';\n        },\n        nextWeek : function () {\n            return 'dddd [a la' + ((this.hours() !== 1) ? 's' : '') + '] LT';\n        },\n        lastDay : function () {\n            return '[ayer a la' + ((this.hours() !== 1) ? 's' : '') + '] LT';\n        },\n        lastWeek : function () {\n            return '[el] dddd [pasado a la' + ((this.hours() !== 1) ? 's' : '') + '] LT';\n        },\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'en %s',\n        past : 'hace %s',\n        s : 'unos segundos',\n        m : 'un minuto',\n        mm : '%d minutos',\n        h : 'una hora',\n        hh : '%d horas',\n        d : 'un día',\n        dd : '%d días',\n        M : 'un mes',\n        MM : '%d meses',\n        y : 'un año',\n        yy : '%d años'\n    },\n    dayOfMonthOrdinalParse : /\\d{1,2}º/,\n    ordinal : '%dº',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Estonian [et]\n//! author : Henry Kehlmann : https://github.com/madhenry\n//! improvements : Illimar Tambek : https://github.com/ragulka\n\nfunction processRelativeTime$3(number, withoutSuffix, key, isFuture) {\n    var format = {\n        's' : ['mõne sekundi', 'mõni sekund', 'paar sekundit'],\n        'm' : ['ühe minuti', 'üks minut'],\n        'mm': [number + ' minuti', number + ' minutit'],\n        'h' : ['ühe tunni', 'tund aega', 'üks tund'],\n        'hh': [number + ' tunni', number + ' tundi'],\n        'd' : ['ühe päeva', 'üks päev'],\n        'M' : ['kuu aja', 'kuu aega', 'üks kuu'],\n        'MM': [number + ' kuu', number + ' kuud'],\n        'y' : ['ühe aasta', 'aasta', 'üks aasta'],\n        'yy': [number + ' aasta', number + ' aastat']\n    };\n    if (withoutSuffix) {\n        return format[key][2] ? format[key][2] : format[key][1];\n    }\n    return isFuture ? format[key][0] : format[key][1];\n}\n\nhooks.defineLocale('et', {\n    months        : 'jaanuar_veebruar_märts_aprill_mai_juuni_juuli_august_september_oktoober_november_detsember'.split('_'),\n    monthsShort   : 'jaan_veebr_märts_apr_mai_juuni_juuli_aug_sept_okt_nov_dets'.split('_'),\n    weekdays      : 'pühapäev_esmaspäev_teisipäev_kolmapäev_neljapäev_reede_laupäev'.split('_'),\n    weekdaysShort : 'P_E_T_K_N_R_L'.split('_'),\n    weekdaysMin   : 'P_E_T_K_N_R_L'.split('_'),\n    longDateFormat : {\n        LT   : 'H:mm',\n        LTS : 'H:mm:ss',\n        L    : 'DD.MM.YYYY',\n        LL   : 'D. MMMM YYYY',\n        LLL  : 'D. MMMM YYYY H:mm',\n        LLLL : 'dddd, D. MMMM YYYY H:mm'\n    },\n    calendar : {\n        sameDay  : '[Täna,] LT',\n        nextDay  : '[Homme,] LT',\n        nextWeek : '[Järgmine] dddd LT',\n        lastDay  : '[Eile,] LT',\n        lastWeek : '[Eelmine] dddd LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : '%s pärast',\n        past   : '%s tagasi',\n        s      : processRelativeTime$3,\n        m      : processRelativeTime$3,\n        mm     : processRelativeTime$3,\n        h      : processRelativeTime$3,\n        hh     : processRelativeTime$3,\n        d      : processRelativeTime$3,\n        dd     : '%d päeva',\n        M      : processRelativeTime$3,\n        MM     : processRelativeTime$3,\n        y      : processRelativeTime$3,\n        yy     : processRelativeTime$3\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}\\./,\n    ordinal : '%d.',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Basque [eu]\n//! author : Eneko Illarramendi : https://github.com/eillarra\n\nhooks.defineLocale('eu', {\n    months : 'urtarrila_otsaila_martxoa_apirila_maiatza_ekaina_uztaila_abuztua_iraila_urria_azaroa_abendua'.split('_'),\n    monthsShort : 'urt._ots._mar._api._mai._eka._uzt._abu._ira._urr._aza._abe.'.split('_'),\n    monthsParseExact : true,\n    weekdays : 'igandea_astelehena_asteartea_asteazkena_osteguna_ostirala_larunbata'.split('_'),\n    weekdaysShort : 'ig._al._ar._az._og._ol._lr.'.split('_'),\n    weekdaysMin : 'ig_al_ar_az_og_ol_lr'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'YYYY-MM-DD',\n        LL : 'YYYY[ko] MMMM[ren] D[a]',\n        LLL : 'YYYY[ko] MMMM[ren] D[a] HH:mm',\n        LLLL : 'dddd, YYYY[ko] MMMM[ren] D[a] HH:mm',\n        l : 'YYYY-M-D',\n        ll : 'YYYY[ko] MMM D[a]',\n        lll : 'YYYY[ko] MMM D[a] HH:mm',\n        llll : 'ddd, YYYY[ko] MMM D[a] HH:mm'\n    },\n    calendar : {\n        sameDay : '[gaur] LT[etan]',\n        nextDay : '[bihar] LT[etan]',\n        nextWeek : 'dddd LT[etan]',\n        lastDay : '[atzo] LT[etan]',\n        lastWeek : '[aurreko] dddd LT[etan]',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : '%s barru',\n        past : 'duela %s',\n        s : 'segundo batzuk',\n        m : 'minutu bat',\n        mm : '%d minutu',\n        h : 'ordu bat',\n        hh : '%d ordu',\n        d : 'egun bat',\n        dd : '%d egun',\n        M : 'hilabete bat',\n        MM : '%d hilabete',\n        y : 'urte bat',\n        yy : '%d urte'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}\\./,\n    ordinal : '%d.',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 7  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Persian [fa]\n//! author : Ebrahim Byagowi : https://github.com/ebraminio\n\nvar symbolMap$5 = {\n    '1': '۱',\n    '2': '۲',\n    '3': '۳',\n    '4': '۴',\n    '5': '۵',\n    '6': '۶',\n    '7': '۷',\n    '8': '۸',\n    '9': '۹',\n    '0': '۰'\n};\nvar numberMap$4 = {\n    '۱': '1',\n    '۲': '2',\n    '۳': '3',\n    '۴': '4',\n    '۵': '5',\n    '۶': '6',\n    '۷': '7',\n    '۸': '8',\n    '۹': '9',\n    '۰': '0'\n};\n\nhooks.defineLocale('fa', {\n    months : 'ژانویه_فوریه_مارس_آوریل_مه_ژوئن_ژوئیه_اوت_سپتامبر_اکتبر_نوامبر_دسامبر'.split('_'),\n    monthsShort : 'ژانویه_فوریه_مارس_آوریل_مه_ژوئن_ژوئیه_اوت_سپتامبر_اکتبر_نوامبر_دسامبر'.split('_'),\n    weekdays : 'یک\\u200cشنبه_دوشنبه_سه\\u200cشنبه_چهارشنبه_پنج\\u200cشنبه_جمعه_شنبه'.split('_'),\n    weekdaysShort : 'یک\\u200cشنبه_دوشنبه_سه\\u200cشنبه_چهارشنبه_پنج\\u200cشنبه_جمعه_شنبه'.split('_'),\n    weekdaysMin : 'ی_د_س_چ_پ_ج_ش'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY HH:mm',\n        LLLL : 'dddd, D MMMM YYYY HH:mm'\n    },\n    meridiemParse: /قبل از ظهر|بعد از ظهر/,\n    isPM: function (input) {\n        return /بعد از ظهر/.test(input);\n    },\n    meridiem : function (hour, minute, isLower) {\n        if (hour < 12) {\n            return 'قبل از ظهر';\n        } else {\n            return 'بعد از ظهر';\n        }\n    },\n    calendar : {\n        sameDay : '[امروز ساعت] LT',\n        nextDay : '[فردا ساعت] LT',\n        nextWeek : 'dddd [ساعت] LT',\n        lastDay : '[دیروز ساعت] LT',\n        lastWeek : 'dddd [پیش] [ساعت] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'در %s',\n        past : '%s پیش',\n        s : 'چند ثانیه',\n        m : 'یک دقیقه',\n        mm : '%d دقیقه',\n        h : 'یک ساعت',\n        hh : '%d ساعت',\n        d : 'یک روز',\n        dd : '%d روز',\n        M : 'یک ماه',\n        MM : '%d ماه',\n        y : 'یک سال',\n        yy : '%d سال'\n    },\n    preparse: function (string) {\n        return string.replace(/[۰-۹]/g, function (match) {\n            return numberMap$4[match];\n        }).replace(/،/g, ',');\n    },\n    postformat: function (string) {\n        return string.replace(/\\d/g, function (match) {\n            return symbolMap$5[match];\n        }).replace(/,/g, '،');\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}م/,\n    ordinal : '%dم',\n    week : {\n        dow : 6, // Saturday is the first day of the week.\n        doy : 12 // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Finnish [fi]\n//! author : Tarmo Aidantausta : https://github.com/bleadof\n\nvar numbersPast = 'nolla yksi kaksi kolme neljä viisi kuusi seitsemän kahdeksan yhdeksän'.split(' ');\nvar numbersFuture = [\n        'nolla', 'yhden', 'kahden', 'kolmen', 'neljän', 'viiden', 'kuuden',\n        numbersPast[7], numbersPast[8], numbersPast[9]\n    ];\nfunction translate$2(number, withoutSuffix, key, isFuture) {\n    var result = '';\n    switch (key) {\n        case 's':\n            return isFuture ? 'muutaman sekunnin' : 'muutama sekunti';\n        case 'm':\n            return isFuture ? 'minuutin' : 'minuutti';\n        case 'mm':\n            result = isFuture ? 'minuutin' : 'minuuttia';\n            break;\n        case 'h':\n            return isFuture ? 'tunnin' : 'tunti';\n        case 'hh':\n            result = isFuture ? 'tunnin' : 'tuntia';\n            break;\n        case 'd':\n            return isFuture ? 'päivän' : 'päivä';\n        case 'dd':\n            result = isFuture ? 'päivän' : 'päivää';\n            break;\n        case 'M':\n            return isFuture ? 'kuukauden' : 'kuukausi';\n        case 'MM':\n            result = isFuture ? 'kuukauden' : 'kuukautta';\n            break;\n        case 'y':\n            return isFuture ? 'vuoden' : 'vuosi';\n        case 'yy':\n            result = isFuture ? 'vuoden' : 'vuotta';\n            break;\n    }\n    result = verbalNumber(number, isFuture) + ' ' + result;\n    return result;\n}\nfunction verbalNumber(number, isFuture) {\n    return number < 10 ? (isFuture ? numbersFuture[number] : numbersPast[number]) : number;\n}\n\nhooks.defineLocale('fi', {\n    months : 'tammikuu_helmikuu_maaliskuu_huhtikuu_toukokuu_kesäkuu_heinäkuu_elokuu_syyskuu_lokakuu_marraskuu_joulukuu'.split('_'),\n    monthsShort : 'tammi_helmi_maalis_huhti_touko_kesä_heinä_elo_syys_loka_marras_joulu'.split('_'),\n    weekdays : 'sunnuntai_maanantai_tiistai_keskiviikko_torstai_perjantai_lauantai'.split('_'),\n    weekdaysShort : 'su_ma_ti_ke_to_pe_la'.split('_'),\n    weekdaysMin : 'su_ma_ti_ke_to_pe_la'.split('_'),\n    longDateFormat : {\n        LT : 'HH.mm',\n        LTS : 'HH.mm.ss',\n        L : 'DD.MM.YYYY',\n        LL : 'Do MMMM[ta] YYYY',\n        LLL : 'Do MMMM[ta] YYYY, [klo] HH.mm',\n        LLLL : 'dddd, Do MMMM[ta] YYYY, [klo] HH.mm',\n        l : 'D.M.YYYY',\n        ll : 'Do MMM YYYY',\n        lll : 'Do MMM YYYY, [klo] HH.mm',\n        llll : 'ddd, Do MMM YYYY, [klo] HH.mm'\n    },\n    calendar : {\n        sameDay : '[tänään] [klo] LT',\n        nextDay : '[huomenna] [klo] LT',\n        nextWeek : 'dddd [klo] LT',\n        lastDay : '[eilen] [klo] LT',\n        lastWeek : '[viime] dddd[na] [klo] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : '%s päästä',\n        past : '%s sitten',\n        s : translate$2,\n        m : translate$2,\n        mm : translate$2,\n        h : translate$2,\n        hh : translate$2,\n        d : translate$2,\n        dd : translate$2,\n        M : translate$2,\n        MM : translate$2,\n        y : translate$2,\n        yy : translate$2\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}\\./,\n    ordinal : '%d.',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Faroese [fo]\n//! author : Ragnar Johannesen : https://github.com/ragnar123\n\nhooks.defineLocale('fo', {\n    months : 'januar_februar_mars_apríl_mai_juni_juli_august_september_oktober_november_desember'.split('_'),\n    monthsShort : 'jan_feb_mar_apr_mai_jun_jul_aug_sep_okt_nov_des'.split('_'),\n    weekdays : 'sunnudagur_mánadagur_týsdagur_mikudagur_hósdagur_fríggjadagur_leygardagur'.split('_'),\n    weekdaysShort : 'sun_mán_týs_mik_hós_frí_ley'.split('_'),\n    weekdaysMin : 'su_má_tý_mi_hó_fr_le'.split('_'),\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY HH:mm',\n        LLLL : 'dddd D. MMMM, YYYY HH:mm'\n    },\n    calendar : {\n        sameDay : '[Í dag kl.] LT',\n        nextDay : '[Í morgin kl.] LT',\n        nextWeek : 'dddd [kl.] LT',\n        lastDay : '[Í gjár kl.] LT',\n        lastWeek : '[síðstu] dddd [kl] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'um %s',\n        past : '%s síðani',\n        s : 'fá sekund',\n        m : 'ein minutt',\n        mm : '%d minuttir',\n        h : 'ein tími',\n        hh : '%d tímar',\n        d : 'ein dagur',\n        dd : '%d dagar',\n        M : 'ein mánaði',\n        MM : '%d mánaðir',\n        y : 'eitt ár',\n        yy : '%d ár'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}\\./,\n    ordinal : '%d.',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : French (Canada) [fr-ca]\n//! author : Jonathan Abourbih : https://github.com/jonbca\n\nhooks.defineLocale('fr-ca', {\n    months : 'janvier_février_mars_avril_mai_juin_juillet_août_septembre_octobre_novembre_décembre'.split('_'),\n    monthsShort : 'janv._févr._mars_avr._mai_juin_juil._août_sept._oct._nov._déc.'.split('_'),\n    monthsParseExact : true,\n    weekdays : 'dimanche_lundi_mardi_mercredi_jeudi_vendredi_samedi'.split('_'),\n    weekdaysShort : 'dim._lun._mar._mer._jeu._ven._sam.'.split('_'),\n    weekdaysMin : 'Di_Lu_Ma_Me_Je_Ve_Sa'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'YYYY-MM-DD',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY HH:mm',\n        LLLL : 'dddd D MMMM YYYY HH:mm'\n    },\n    calendar : {\n        sameDay : '[Aujourd’hui à] LT',\n        nextDay : '[Demain à] LT',\n        nextWeek : 'dddd [à] LT',\n        lastDay : '[Hier à] LT',\n        lastWeek : 'dddd [dernier à] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'dans %s',\n        past : 'il y a %s',\n        s : 'quelques secondes',\n        m : 'une minute',\n        mm : '%d minutes',\n        h : 'une heure',\n        hh : '%d heures',\n        d : 'un jour',\n        dd : '%d jours',\n        M : 'un mois',\n        MM : '%d mois',\n        y : 'un an',\n        yy : '%d ans'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}(er|e)/,\n    ordinal : function (number, period) {\n        switch (period) {\n            // Words with masculine grammatical gender: mois, trimestre, jour\n            default:\n            case 'M':\n            case 'Q':\n            case 'D':\n            case 'DDD':\n            case 'd':\n                return number + (number === 1 ? 'er' : 'e');\n\n            // Words with feminine grammatical gender: semaine\n            case 'w':\n            case 'W':\n                return number + (number === 1 ? 're' : 'e');\n        }\n    }\n});\n\n//! moment.js locale configuration\n//! locale : French (Switzerland) [fr-ch]\n//! author : Gaspard Bucher : https://github.com/gaspard\n\nhooks.defineLocale('fr-ch', {\n    months : 'janvier_février_mars_avril_mai_juin_juillet_août_septembre_octobre_novembre_décembre'.split('_'),\n    monthsShort : 'janv._févr._mars_avr._mai_juin_juil._août_sept._oct._nov._déc.'.split('_'),\n    monthsParseExact : true,\n    weekdays : 'dimanche_lundi_mardi_mercredi_jeudi_vendredi_samedi'.split('_'),\n    weekdaysShort : 'dim._lun._mar._mer._jeu._ven._sam.'.split('_'),\n    weekdaysMin : 'Di_Lu_Ma_Me_Je_Ve_Sa'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD.MM.YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY HH:mm',\n        LLLL : 'dddd D MMMM YYYY HH:mm'\n    },\n    calendar : {\n        sameDay : '[Aujourd’hui à] LT',\n        nextDay : '[Demain à] LT',\n        nextWeek : 'dddd [à] LT',\n        lastDay : '[Hier à] LT',\n        lastWeek : 'dddd [dernier à] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'dans %s',\n        past : 'il y a %s',\n        s : 'quelques secondes',\n        m : 'une minute',\n        mm : '%d minutes',\n        h : 'une heure',\n        hh : '%d heures',\n        d : 'un jour',\n        dd : '%d jours',\n        M : 'un mois',\n        MM : '%d mois',\n        y : 'un an',\n        yy : '%d ans'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}(er|e)/,\n    ordinal : function (number, period) {\n        switch (period) {\n            // Words with masculine grammatical gender: mois, trimestre, jour\n            default:\n            case 'M':\n            case 'Q':\n            case 'D':\n            case 'DDD':\n            case 'd':\n                return number + (number === 1 ? 'er' : 'e');\n\n            // Words with feminine grammatical gender: semaine\n            case 'w':\n            case 'W':\n                return number + (number === 1 ? 're' : 'e');\n        }\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : French [fr]\n//! author : John Fischer : https://github.com/jfroffice\n\nhooks.defineLocale('fr', {\n    months : 'janvier_février_mars_avril_mai_juin_juillet_août_septembre_octobre_novembre_décembre'.split('_'),\n    monthsShort : 'janv._févr._mars_avr._mai_juin_juil._août_sept._oct._nov._déc.'.split('_'),\n    monthsParseExact : true,\n    weekdays : 'dimanche_lundi_mardi_mercredi_jeudi_vendredi_samedi'.split('_'),\n    weekdaysShort : 'dim._lun._mar._mer._jeu._ven._sam.'.split('_'),\n    weekdaysMin : 'Di_Lu_Ma_Me_Je_Ve_Sa'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY HH:mm',\n        LLLL : 'dddd D MMMM YYYY HH:mm'\n    },\n    calendar : {\n        sameDay : '[Aujourd’hui à] LT',\n        nextDay : '[Demain à] LT',\n        nextWeek : 'dddd [à] LT',\n        lastDay : '[Hier à] LT',\n        lastWeek : 'dddd [dernier à] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'dans %s',\n        past : 'il y a %s',\n        s : 'quelques secondes',\n        m : 'une minute',\n        mm : '%d minutes',\n        h : 'une heure',\n        hh : '%d heures',\n        d : 'un jour',\n        dd : '%d jours',\n        M : 'un mois',\n        MM : '%d mois',\n        y : 'un an',\n        yy : '%d ans'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}(er|)/,\n    ordinal : function (number, period) {\n        switch (period) {\n            // TODO: Return 'e' when day of month > 1. Move this case inside\n            // block for masculine words below.\n            // See https://github.com/moment/moment/issues/3375\n            case 'D':\n                return number + (number === 1 ? 'er' : '');\n\n            // Words with masculine grammatical gender: mois, trimestre, jour\n            default:\n            case 'M':\n            case 'Q':\n            case 'DDD':\n            case 'd':\n                return number + (number === 1 ? 'er' : 'e');\n\n            // Words with feminine grammatical gender: semaine\n            case 'w':\n            case 'W':\n                return number + (number === 1 ? 're' : 'e');\n        }\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Frisian [fy]\n//! author : Robin van der Vliet : https://github.com/robin0van0der0v\n\nvar monthsShortWithDots = 'jan._feb._mrt._apr._mai_jun._jul._aug._sep._okt._nov._des.'.split('_');\nvar monthsShortWithoutDots = 'jan_feb_mrt_apr_mai_jun_jul_aug_sep_okt_nov_des'.split('_');\n\nhooks.defineLocale('fy', {\n    months : 'jannewaris_febrewaris_maart_april_maaie_juny_july_augustus_septimber_oktober_novimber_desimber'.split('_'),\n    monthsShort : function (m, format) {\n        if (!m) {\n            return monthsShortWithDots;\n        } else if (/-MMM-/.test(format)) {\n            return monthsShortWithoutDots[m.month()];\n        } else {\n            return monthsShortWithDots[m.month()];\n        }\n    },\n    monthsParseExact : true,\n    weekdays : 'snein_moandei_tiisdei_woansdei_tongersdei_freed_sneon'.split('_'),\n    weekdaysShort : 'si._mo._ti._wo._to._fr._so.'.split('_'),\n    weekdaysMin : 'Si_Mo_Ti_Wo_To_Fr_So'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD-MM-YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY HH:mm',\n        LLLL : 'dddd D MMMM YYYY HH:mm'\n    },\n    calendar : {\n        sameDay: '[hjoed om] LT',\n        nextDay: '[moarn om] LT',\n        nextWeek: 'dddd [om] LT',\n        lastDay: '[juster om] LT',\n        lastWeek: '[ôfrûne] dddd [om] LT',\n        sameElse: 'L'\n    },\n    relativeTime : {\n        future : 'oer %s',\n        past : '%s lyn',\n        s : 'in pear sekonden',\n        m : 'ien minút',\n        mm : '%d minuten',\n        h : 'ien oere',\n        hh : '%d oeren',\n        d : 'ien dei',\n        dd : '%d dagen',\n        M : 'ien moanne',\n        MM : '%d moannen',\n        y : 'ien jier',\n        yy : '%d jierren'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}(ste|de)/,\n    ordinal : function (number) {\n        return number + ((number === 1 || number === 8 || number >= 20) ? 'ste' : 'de');\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Scottish Gaelic [gd]\n//! author : Jon Ashdown : https://github.com/jonashdown\n\nvar months$5 = [\n    'Am Faoilleach', 'An Gearran', 'Am Màrt', 'An Giblean', 'An Cèitean', 'An t-Ògmhios', 'An t-Iuchar', 'An Lùnastal', 'An t-Sultain', 'An Dàmhair', 'An t-Samhain', 'An Dùbhlachd'\n];\n\nvar monthsShort$3 = ['Faoi', 'Gear', 'Màrt', 'Gibl', 'Cèit', 'Ògmh', 'Iuch', 'Lùn', 'Sult', 'Dàmh', 'Samh', 'Dùbh'];\n\nvar weekdays$1 = ['Didòmhnaich', 'Diluain', 'Dimàirt', 'Diciadain', 'Diardaoin', 'Dihaoine', 'Disathairne'];\n\nvar weekdaysShort = ['Did', 'Dil', 'Dim', 'Dic', 'Dia', 'Dih', 'Dis'];\n\nvar weekdaysMin = ['Dò', 'Lu', 'Mà', 'Ci', 'Ar', 'Ha', 'Sa'];\n\nhooks.defineLocale('gd', {\n    months : months$5,\n    monthsShort : monthsShort$3,\n    monthsParseExact : true,\n    weekdays : weekdays$1,\n    weekdaysShort : weekdaysShort,\n    weekdaysMin : weekdaysMin,\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY HH:mm',\n        LLLL : 'dddd, D MMMM YYYY HH:mm'\n    },\n    calendar : {\n        sameDay : '[An-diugh aig] LT',\n        nextDay : '[A-màireach aig] LT',\n        nextWeek : 'dddd [aig] LT',\n        lastDay : '[An-dè aig] LT',\n        lastWeek : 'dddd [seo chaidh] [aig] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'ann an %s',\n        past : 'bho chionn %s',\n        s : 'beagan diogan',\n        m : 'mionaid',\n        mm : '%d mionaidean',\n        h : 'uair',\n        hh : '%d uairean',\n        d : 'latha',\n        dd : '%d latha',\n        M : 'mìos',\n        MM : '%d mìosan',\n        y : 'bliadhna',\n        yy : '%d bliadhna'\n    },\n    dayOfMonthOrdinalParse : /\\d{1,2}(d|na|mh)/,\n    ordinal : function (number) {\n        var output = number === 1 ? 'd' : number % 10 === 2 ? 'na' : 'mh';\n        return number + output;\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Galician [gl]\n//! author : Juan G. Hurtado : https://github.com/juanghurtado\n\nhooks.defineLocale('gl', {\n    months : 'xaneiro_febreiro_marzo_abril_maio_xuño_xullo_agosto_setembro_outubro_novembro_decembro'.split('_'),\n    monthsShort : 'xan._feb._mar._abr._mai._xuñ._xul._ago._set._out._nov._dec.'.split('_'),\n    monthsParseExact: true,\n    weekdays : 'domingo_luns_martes_mércores_xoves_venres_sábado'.split('_'),\n    weekdaysShort : 'dom._lun._mar._mér._xov._ven._sáb.'.split('_'),\n    weekdaysMin : 'do_lu_ma_mé_xo_ve_sá'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat : {\n        LT : 'H:mm',\n        LTS : 'H:mm:ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D [de] MMMM [de] YYYY',\n        LLL : 'D [de] MMMM [de] YYYY H:mm',\n        LLLL : 'dddd, D [de] MMMM [de] YYYY H:mm'\n    },\n    calendar : {\n        sameDay : function () {\n            return '[hoxe ' + ((this.hours() !== 1) ? 'ás' : 'á') + '] LT';\n        },\n        nextDay : function () {\n            return '[mañá ' + ((this.hours() !== 1) ? 'ás' : 'á') + '] LT';\n        },\n        nextWeek : function () {\n            return 'dddd [' + ((this.hours() !== 1) ? 'ás' : 'a') + '] LT';\n        },\n        lastDay : function () {\n            return '[onte ' + ((this.hours() !== 1) ? 'á' : 'a') + '] LT';\n        },\n        lastWeek : function () {\n            return '[o] dddd [pasado ' + ((this.hours() !== 1) ? 'ás' : 'a') + '] LT';\n        },\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : function (str) {\n            if (str.indexOf('un') === 0) {\n                return 'n' + str;\n            }\n            return 'en ' + str;\n        },\n        past : 'hai %s',\n        s : 'uns segundos',\n        m : 'un minuto',\n        mm : '%d minutos',\n        h : 'unha hora',\n        hh : '%d horas',\n        d : 'un día',\n        dd : '%d días',\n        M : 'un mes',\n        MM : '%d meses',\n        y : 'un ano',\n        yy : '%d anos'\n    },\n    dayOfMonthOrdinalParse : /\\d{1,2}º/,\n    ordinal : '%dº',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Konkani Latin script [gom-latn]\n//! author : The Discoverer : https://github.com/WikiDiscoverer\n\nfunction processRelativeTime$4(number, withoutSuffix, key, isFuture) {\n    var format = {\n        's': ['thodde secondanim', 'thodde second'],\n        'm': ['eka mintan', 'ek minute'],\n        'mm': [number + ' mintanim', number + ' mintam'],\n        'h': ['eka horan', 'ek hor'],\n        'hh': [number + ' horanim', number + ' hor'],\n        'd': ['eka disan', 'ek dis'],\n        'dd': [number + ' disanim', number + ' dis'],\n        'M': ['eka mhoinean', 'ek mhoino'],\n        'MM': [number + ' mhoineanim', number + ' mhoine'],\n        'y': ['eka vorsan', 'ek voros'],\n        'yy': [number + ' vorsanim', number + ' vorsam']\n    };\n    return withoutSuffix ? format[key][0] : format[key][1];\n}\n\nhooks.defineLocale('gom-latn', {\n    months : 'Janer_Febrer_Mars_Abril_Mai_Jun_Julai_Agost_Setembr_Otubr_Novembr_Dezembr'.split('_'),\n    monthsShort : 'Jan._Feb._Mars_Abr._Mai_Jun_Jul._Ago._Set._Otu._Nov._Dez.'.split('_'),\n    monthsParseExact : true,\n    weekdays : 'Aitar_Somar_Mongllar_Budvar_Brestar_Sukrar_Son\\'var'.split('_'),\n    weekdaysShort : 'Ait._Som._Mon._Bud._Bre._Suk._Son.'.split('_'),\n    weekdaysMin : 'Ai_Sm_Mo_Bu_Br_Su_Sn'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat : {\n        LT : 'A h:mm [vazta]',\n        LTS : 'A h:mm:ss [vazta]',\n        L : 'DD-MM-YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY A h:mm [vazta]',\n        LLLL : 'dddd, MMMM[achea] Do, YYYY, A h:mm [vazta]',\n        llll: 'ddd, D MMM YYYY, A h:mm [vazta]'\n    },\n    calendar : {\n        sameDay: '[Aiz] LT',\n        nextDay: '[Faleam] LT',\n        nextWeek: '[Ieta to] dddd[,] LT',\n        lastDay: '[Kal] LT',\n        lastWeek: '[Fatlo] dddd[,] LT',\n        sameElse: 'L'\n    },\n    relativeTime : {\n        future : '%s',\n        past : '%s adim',\n        s : processRelativeTime$4,\n        m : processRelativeTime$4,\n        mm : processRelativeTime$4,\n        h : processRelativeTime$4,\n        hh : processRelativeTime$4,\n        d : processRelativeTime$4,\n        dd : processRelativeTime$4,\n        M : processRelativeTime$4,\n        MM : processRelativeTime$4,\n        y : processRelativeTime$4,\n        yy : processRelativeTime$4\n    },\n    dayOfMonthOrdinalParse : /\\d{1,2}(er)/,\n    ordinal : function (number, period) {\n        switch (period) {\n            // the ordinal 'er' only applies to day of the month\n            case 'D':\n                return number + 'er';\n            default:\n            case 'M':\n            case 'Q':\n            case 'DDD':\n            case 'd':\n            case 'w':\n            case 'W':\n                return number;\n        }\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    },\n    meridiemParse: /rati|sokalli|donparam|sanje/,\n    meridiemHour : function (hour, meridiem) {\n        if (hour === 12) {\n            hour = 0;\n        }\n        if (meridiem === 'rati') {\n            return hour < 4 ? hour : hour + 12;\n        } else if (meridiem === 'sokalli') {\n            return hour;\n        } else if (meridiem === 'donparam') {\n            return hour > 12 ? hour : hour + 12;\n        } else if (meridiem === 'sanje') {\n            return hour + 12;\n        }\n    },\n    meridiem : function (hour, minute, isLower) {\n        if (hour < 4) {\n            return 'rati';\n        } else if (hour < 12) {\n            return 'sokalli';\n        } else if (hour < 16) {\n            return 'donparam';\n        } else if (hour < 20) {\n            return 'sanje';\n        } else {\n            return 'rati';\n        }\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Hebrew [he]\n//! author : Tomer Cohen : https://github.com/tomer\n//! author : Moshe Simantov : https://github.com/DevelopmentIL\n//! author : Tal Ater : https://github.com/TalAter\n\nhooks.defineLocale('he', {\n    months : 'ינואר_פברואר_מרץ_אפריל_מאי_יוני_יולי_אוגוסט_ספטמבר_אוקטובר_נובמבר_דצמבר'.split('_'),\n    monthsShort : 'ינו׳_פבר׳_מרץ_אפר׳_מאי_יוני_יולי_אוג׳_ספט׳_אוק׳_נוב׳_דצמ׳'.split('_'),\n    weekdays : 'ראשון_שני_שלישי_רביעי_חמישי_שישי_שבת'.split('_'),\n    weekdaysShort : 'א׳_ב׳_ג׳_ד׳_ה׳_ו׳_ש׳'.split('_'),\n    weekdaysMin : 'א_ב_ג_ד_ה_ו_ש'.split('_'),\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D [ב]MMMM YYYY',\n        LLL : 'D [ב]MMMM YYYY HH:mm',\n        LLLL : 'dddd, D [ב]MMMM YYYY HH:mm',\n        l : 'D/M/YYYY',\n        ll : 'D MMM YYYY',\n        lll : 'D MMM YYYY HH:mm',\n        llll : 'ddd, D MMM YYYY HH:mm'\n    },\n    calendar : {\n        sameDay : '[היום ב־]LT',\n        nextDay : '[מחר ב־]LT',\n        nextWeek : 'dddd [בשעה] LT',\n        lastDay : '[אתמול ב־]LT',\n        lastWeek : '[ביום] dddd [האחרון בשעה] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'בעוד %s',\n        past : 'לפני %s',\n        s : 'מספר שניות',\n        m : 'דקה',\n        mm : '%d דקות',\n        h : 'שעה',\n        hh : function (number) {\n            if (number === 2) {\n                return 'שעתיים';\n            }\n            return number + ' שעות';\n        },\n        d : 'יום',\n        dd : function (number) {\n            if (number === 2) {\n                return 'יומיים';\n            }\n            return number + ' ימים';\n        },\n        M : 'חודש',\n        MM : function (number) {\n            if (number === 2) {\n                return 'חודשיים';\n            }\n            return number + ' חודשים';\n        },\n        y : 'שנה',\n        yy : function (number) {\n            if (number === 2) {\n                return 'שנתיים';\n            } else if (number % 10 === 0 && number !== 10) {\n                return number + ' שנה';\n            }\n            return number + ' שנים';\n        }\n    },\n    meridiemParse: /אחה\"צ|לפנה\"צ|אחרי הצהריים|לפני הצהריים|לפנות בוקר|בבוקר|בערב/i,\n    isPM : function (input) {\n        return /^(אחה\"צ|אחרי הצהריים|בערב)$/.test(input);\n    },\n    meridiem : function (hour, minute, isLower) {\n        if (hour < 5) {\n            return 'לפנות בוקר';\n        } else if (hour < 10) {\n            return 'בבוקר';\n        } else if (hour < 12) {\n            return isLower ? 'לפנה\"צ' : 'לפני הצהריים';\n        } else if (hour < 18) {\n            return isLower ? 'אחה\"צ' : 'אחרי הצהריים';\n        } else {\n            return 'בערב';\n        }\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Hindi [hi]\n//! author : Mayank Singhal : https://github.com/mayanksinghal\n\nvar symbolMap$6 = {\n    '1': '१',\n    '2': '२',\n    '3': '३',\n    '4': '४',\n    '5': '५',\n    '6': '६',\n    '7': '७',\n    '8': '८',\n    '9': '९',\n    '0': '०'\n};\nvar numberMap$5 = {\n    '१': '1',\n    '२': '2',\n    '३': '3',\n    '४': '4',\n    '५': '5',\n    '६': '6',\n    '७': '7',\n    '८': '8',\n    '९': '9',\n    '०': '0'\n};\n\nhooks.defineLocale('hi', {\n    months : 'जनवरी_फ़रवरी_मार्च_अप्रैल_मई_जून_जुलाई_अगस्त_सितम्बर_अक्टूबर_नवम्बर_दिसम्बर'.split('_'),\n    monthsShort : 'जन._फ़र._मार्च_अप्रै._मई_जून_जुल._अग._सित._अक्टू._नव._दिस.'.split('_'),\n    monthsParseExact: true,\n    weekdays : 'रविवार_सोमवार_मंगलवार_बुधवार_गुरूवार_शुक्रवार_शनिवार'.split('_'),\n    weekdaysShort : 'रवि_सोम_मंगल_बुध_गुरू_शुक्र_शनि'.split('_'),\n    weekdaysMin : 'र_सो_मं_बु_गु_शु_श'.split('_'),\n    longDateFormat : {\n        LT : 'A h:mm बजे',\n        LTS : 'A h:mm:ss बजे',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY, A h:mm बजे',\n        LLLL : 'dddd, D MMMM YYYY, A h:mm बजे'\n    },\n    calendar : {\n        sameDay : '[आज] LT',\n        nextDay : '[कल] LT',\n        nextWeek : 'dddd, LT',\n        lastDay : '[कल] LT',\n        lastWeek : '[पिछले] dddd, LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : '%s में',\n        past : '%s पहले',\n        s : 'कुछ ही क्षण',\n        m : 'एक मिनट',\n        mm : '%d मिनट',\n        h : 'एक घंटा',\n        hh : '%d घंटे',\n        d : 'एक दिन',\n        dd : '%d दिन',\n        M : 'एक महीने',\n        MM : '%d महीने',\n        y : 'एक वर्ष',\n        yy : '%d वर्ष'\n    },\n    preparse: function (string) {\n        return string.replace(/[१२३४५६७८९०]/g, function (match) {\n            return numberMap$5[match];\n        });\n    },\n    postformat: function (string) {\n        return string.replace(/\\d/g, function (match) {\n            return symbolMap$6[match];\n        });\n    },\n    // Hindi notation for meridiems are quite fuzzy in practice. While there exists\n    // a rigid notion of a 'Pahar' it is not used as rigidly in modern Hindi.\n    meridiemParse: /रात|सुबह|दोपहर|शाम/,\n    meridiemHour : function (hour, meridiem) {\n        if (hour === 12) {\n            hour = 0;\n        }\n        if (meridiem === 'रात') {\n            return hour < 4 ? hour : hour + 12;\n        } else if (meridiem === 'सुबह') {\n            return hour;\n        } else if (meridiem === 'दोपहर') {\n            return hour >= 10 ? hour : hour + 12;\n        } else if (meridiem === 'शाम') {\n            return hour + 12;\n        }\n    },\n    meridiem : function (hour, minute, isLower) {\n        if (hour < 4) {\n            return 'रात';\n        } else if (hour < 10) {\n            return 'सुबह';\n        } else if (hour < 17) {\n            return 'दोपहर';\n        } else if (hour < 20) {\n            return 'शाम';\n        } else {\n            return 'रात';\n        }\n    },\n    week : {\n        dow : 0, // Sunday is the first day of the week.\n        doy : 6  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Croatian [hr]\n//! author : Bojan Marković : https://github.com/bmarkovic\n\nfunction translate$3(number, withoutSuffix, key) {\n    var result = number + ' ';\n    switch (key) {\n        case 'm':\n            return withoutSuffix ? 'jedna minuta' : 'jedne minute';\n        case 'mm':\n            if (number === 1) {\n                result += 'minuta';\n            } else if (number === 2 || number === 3 || number === 4) {\n                result += 'minute';\n            } else {\n                result += 'minuta';\n            }\n            return result;\n        case 'h':\n            return withoutSuffix ? 'jedan sat' : 'jednog sata';\n        case 'hh':\n            if (number === 1) {\n                result += 'sat';\n            } else if (number === 2 || number === 3 || number === 4) {\n                result += 'sata';\n            } else {\n                result += 'sati';\n            }\n            return result;\n        case 'dd':\n            if (number === 1) {\n                result += 'dan';\n            } else {\n                result += 'dana';\n            }\n            return result;\n        case 'MM':\n            if (number === 1) {\n                result += 'mjesec';\n            } else if (number === 2 || number === 3 || number === 4) {\n                result += 'mjeseca';\n            } else {\n                result += 'mjeseci';\n            }\n            return result;\n        case 'yy':\n            if (number === 1) {\n                result += 'godina';\n            } else if (number === 2 || number === 3 || number === 4) {\n                result += 'godine';\n            } else {\n                result += 'godina';\n            }\n            return result;\n    }\n}\n\nhooks.defineLocale('hr', {\n    months : {\n        format: 'siječnja_veljače_ožujka_travnja_svibnja_lipnja_srpnja_kolovoza_rujna_listopada_studenoga_prosinca'.split('_'),\n        standalone: 'siječanj_veljača_ožujak_travanj_svibanj_lipanj_srpanj_kolovoz_rujan_listopad_studeni_prosinac'.split('_')\n    },\n    monthsShort : 'sij._velj._ožu._tra._svi._lip._srp._kol._ruj._lis._stu._pro.'.split('_'),\n    monthsParseExact: true,\n    weekdays : 'nedjelja_ponedjeljak_utorak_srijeda_četvrtak_petak_subota'.split('_'),\n    weekdaysShort : 'ned._pon._uto._sri._čet._pet._sub.'.split('_'),\n    weekdaysMin : 'ne_po_ut_sr_če_pe_su'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat : {\n        LT : 'H:mm',\n        LTS : 'H:mm:ss',\n        L : 'DD.MM.YYYY',\n        LL : 'D. MMMM YYYY',\n        LLL : 'D. MMMM YYYY H:mm',\n        LLLL : 'dddd, D. MMMM YYYY H:mm'\n    },\n    calendar : {\n        sameDay  : '[danas u] LT',\n        nextDay  : '[sutra u] LT',\n        nextWeek : function () {\n            switch (this.day()) {\n                case 0:\n                    return '[u] [nedjelju] [u] LT';\n                case 3:\n                    return '[u] [srijedu] [u] LT';\n                case 6:\n                    return '[u] [subotu] [u] LT';\n                case 1:\n                case 2:\n                case 4:\n                case 5:\n                    return '[u] dddd [u] LT';\n            }\n        },\n        lastDay  : '[jučer u] LT',\n        lastWeek : function () {\n            switch (this.day()) {\n                case 0:\n                case 3:\n                    return '[prošlu] dddd [u] LT';\n                case 6:\n                    return '[prošle] [subote] [u] LT';\n                case 1:\n                case 2:\n                case 4:\n                case 5:\n                    return '[prošli] dddd [u] LT';\n            }\n        },\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'za %s',\n        past   : 'prije %s',\n        s      : 'par sekundi',\n        m      : translate$3,\n        mm     : translate$3,\n        h      : translate$3,\n        hh     : translate$3,\n        d      : 'dan',\n        dd     : translate$3,\n        M      : 'mjesec',\n        MM     : translate$3,\n        y      : 'godinu',\n        yy     : translate$3\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}\\./,\n    ordinal : '%d.',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 7  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Hungarian [hu]\n//! author : Adam Brunner : https://github.com/adambrunner\n\nvar weekEndings = 'vasárnap hétfőn kedden szerdán csütörtökön pénteken szombaton'.split(' ');\nfunction translate$4(number, withoutSuffix, key, isFuture) {\n    var num = number,\n        suffix;\n    switch (key) {\n        case 's':\n            return (isFuture || withoutSuffix) ? 'néhány másodperc' : 'néhány másodperce';\n        case 'm':\n            return 'egy' + (isFuture || withoutSuffix ? ' perc' : ' perce');\n        case 'mm':\n            return num + (isFuture || withoutSuffix ? ' perc' : ' perce');\n        case 'h':\n            return 'egy' + (isFuture || withoutSuffix ? ' óra' : ' órája');\n        case 'hh':\n            return num + (isFuture || withoutSuffix ? ' óra' : ' órája');\n        case 'd':\n            return 'egy' + (isFuture || withoutSuffix ? ' nap' : ' napja');\n        case 'dd':\n            return num + (isFuture || withoutSuffix ? ' nap' : ' napja');\n        case 'M':\n            return 'egy' + (isFuture || withoutSuffix ? ' hónap' : ' hónapja');\n        case 'MM':\n            return num + (isFuture || withoutSuffix ? ' hónap' : ' hónapja');\n        case 'y':\n            return 'egy' + (isFuture || withoutSuffix ? ' év' : ' éve');\n        case 'yy':\n            return num + (isFuture || withoutSuffix ? ' év' : ' éve');\n    }\n    return '';\n}\nfunction week(isFuture) {\n    return (isFuture ? '' : '[múlt] ') + '[' + weekEndings[this.day()] + '] LT[-kor]';\n}\n\nhooks.defineLocale('hu', {\n    months : 'január_február_március_április_május_június_július_augusztus_szeptember_október_november_december'.split('_'),\n    monthsShort : 'jan_feb_márc_ápr_máj_jún_júl_aug_szept_okt_nov_dec'.split('_'),\n    weekdays : 'vasárnap_hétfő_kedd_szerda_csütörtök_péntek_szombat'.split('_'),\n    weekdaysShort : 'vas_hét_kedd_sze_csüt_pén_szo'.split('_'),\n    weekdaysMin : 'v_h_k_sze_cs_p_szo'.split('_'),\n    longDateFormat : {\n        LT : 'H:mm',\n        LTS : 'H:mm:ss',\n        L : 'YYYY.MM.DD.',\n        LL : 'YYYY. MMMM D.',\n        LLL : 'YYYY. MMMM D. H:mm',\n        LLLL : 'YYYY. MMMM D., dddd H:mm'\n    },\n    meridiemParse: /de|du/i,\n    isPM: function (input) {\n        return input.charAt(1).toLowerCase() === 'u';\n    },\n    meridiem : function (hours, minutes, isLower) {\n        if (hours < 12) {\n            return isLower === true ? 'de' : 'DE';\n        } else {\n            return isLower === true ? 'du' : 'DU';\n        }\n    },\n    calendar : {\n        sameDay : '[ma] LT[-kor]',\n        nextDay : '[holnap] LT[-kor]',\n        nextWeek : function () {\n            return week.call(this, true);\n        },\n        lastDay : '[tegnap] LT[-kor]',\n        lastWeek : function () {\n            return week.call(this, false);\n        },\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : '%s múlva',\n        past : '%s',\n        s : translate$4,\n        m : translate$4,\n        mm : translate$4,\n        h : translate$4,\n        hh : translate$4,\n        d : translate$4,\n        dd : translate$4,\n        M : translate$4,\n        MM : translate$4,\n        y : translate$4,\n        yy : translate$4\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}\\./,\n    ordinal : '%d.',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Armenian [hy-am]\n//! author : Armendarabyan : https://github.com/armendarabyan\n\nhooks.defineLocale('hy-am', {\n    months : {\n        format: 'հունվարի_փետրվարի_մարտի_ապրիլի_մայիսի_հունիսի_հուլիսի_օգոստոսի_սեպտեմբերի_հոկտեմբերի_նոյեմբերի_դեկտեմբերի'.split('_'),\n        standalone: 'հունվար_փետրվար_մարտ_ապրիլ_մայիս_հունիս_հուլիս_օգոստոս_սեպտեմբեր_հոկտեմբեր_նոյեմբեր_դեկտեմբեր'.split('_')\n    },\n    monthsShort : 'հնվ_փտր_մրտ_ապր_մյս_հնս_հլս_օգս_սպտ_հկտ_նմբ_դկտ'.split('_'),\n    weekdays : 'կիրակի_երկուշաբթի_երեքշաբթի_չորեքշաբթի_հինգշաբթի_ուրբաթ_շաբաթ'.split('_'),\n    weekdaysShort : 'կրկ_երկ_երք_չրք_հնգ_ուրբ_շբթ'.split('_'),\n    weekdaysMin : 'կրկ_երկ_երք_չրք_հնգ_ուրբ_շբթ'.split('_'),\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD.MM.YYYY',\n        LL : 'D MMMM YYYY թ.',\n        LLL : 'D MMMM YYYY թ., HH:mm',\n        LLLL : 'dddd, D MMMM YYYY թ., HH:mm'\n    },\n    calendar : {\n        sameDay: '[այսօր] LT',\n        nextDay: '[վաղը] LT',\n        lastDay: '[երեկ] LT',\n        nextWeek: function () {\n            return 'dddd [օրը ժամը] LT';\n        },\n        lastWeek: function () {\n            return '[անցած] dddd [օրը ժամը] LT';\n        },\n        sameElse: 'L'\n    },\n    relativeTime : {\n        future : '%s հետո',\n        past : '%s առաջ',\n        s : 'մի քանի վայրկյան',\n        m : 'րոպե',\n        mm : '%d րոպե',\n        h : 'ժամ',\n        hh : '%d ժամ',\n        d : 'օր',\n        dd : '%d օր',\n        M : 'ամիս',\n        MM : '%d ամիս',\n        y : 'տարի',\n        yy : '%d տարի'\n    },\n    meridiemParse: /գիշերվա|առավոտվա|ցերեկվա|երեկոյան/,\n    isPM: function (input) {\n        return /^(ցերեկվա|երեկոյան)$/.test(input);\n    },\n    meridiem : function (hour) {\n        if (hour < 4) {\n            return 'գիշերվա';\n        } else if (hour < 12) {\n            return 'առավոտվա';\n        } else if (hour < 17) {\n            return 'ցերեկվա';\n        } else {\n            return 'երեկոյան';\n        }\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}|\\d{1,2}-(ին|րդ)/,\n    ordinal: function (number, period) {\n        switch (period) {\n            case 'DDD':\n            case 'w':\n            case 'W':\n            case 'DDDo':\n                if (number === 1) {\n                    return number + '-ին';\n                }\n                return number + '-րդ';\n            default:\n                return number;\n        }\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 7  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Indonesian [id]\n//! author : Mohammad Satrio Utomo : https://github.com/tyok\n//! reference: http://id.wikisource.org/wiki/Pedoman_Umum_Ejaan_Bahasa_Indonesia_yang_Disempurnakan\n\nhooks.defineLocale('id', {\n    months : 'Januari_Februari_Maret_April_Mei_Juni_Juli_Agustus_September_Oktober_November_Desember'.split('_'),\n    monthsShort : 'Jan_Feb_Mar_Apr_Mei_Jun_Jul_Ags_Sep_Okt_Nov_Des'.split('_'),\n    weekdays : 'Minggu_Senin_Selasa_Rabu_Kamis_Jumat_Sabtu'.split('_'),\n    weekdaysShort : 'Min_Sen_Sel_Rab_Kam_Jum_Sab'.split('_'),\n    weekdaysMin : 'Mg_Sn_Sl_Rb_Km_Jm_Sb'.split('_'),\n    longDateFormat : {\n        LT : 'HH.mm',\n        LTS : 'HH.mm.ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY [pukul] HH.mm',\n        LLLL : 'dddd, D MMMM YYYY [pukul] HH.mm'\n    },\n    meridiemParse: /pagi|siang|sore|malam/,\n    meridiemHour : function (hour, meridiem) {\n        if (hour === 12) {\n            hour = 0;\n        }\n        if (meridiem === 'pagi') {\n            return hour;\n        } else if (meridiem === 'siang') {\n            return hour >= 11 ? hour : hour + 12;\n        } else if (meridiem === 'sore' || meridiem === 'malam') {\n            return hour + 12;\n        }\n    },\n    meridiem : function (hours, minutes, isLower) {\n        if (hours < 11) {\n            return 'pagi';\n        } else if (hours < 15) {\n            return 'siang';\n        } else if (hours < 19) {\n            return 'sore';\n        } else {\n            return 'malam';\n        }\n    },\n    calendar : {\n        sameDay : '[Hari ini pukul] LT',\n        nextDay : '[Besok pukul] LT',\n        nextWeek : 'dddd [pukul] LT',\n        lastDay : '[Kemarin pukul] LT',\n        lastWeek : 'dddd [lalu pukul] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'dalam %s',\n        past : '%s yang lalu',\n        s : 'beberapa detik',\n        m : 'semenit',\n        mm : '%d menit',\n        h : 'sejam',\n        hh : '%d jam',\n        d : 'sehari',\n        dd : '%d hari',\n        M : 'sebulan',\n        MM : '%d bulan',\n        y : 'setahun',\n        yy : '%d tahun'\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 7  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Icelandic [is]\n//! author : Hinrik Örn Sigurðsson : https://github.com/hinrik\n\nfunction plural$2(n) {\n    if (n % 100 === 11) {\n        return true;\n    } else if (n % 10 === 1) {\n        return false;\n    }\n    return true;\n}\nfunction translate$5(number, withoutSuffix, key, isFuture) {\n    var result = number + ' ';\n    switch (key) {\n        case 's':\n            return withoutSuffix || isFuture ? 'nokkrar sekúndur' : 'nokkrum sekúndum';\n        case 'm':\n            return withoutSuffix ? 'mínúta' : 'mínútu';\n        case 'mm':\n            if (plural$2(number)) {\n                return result + (withoutSuffix || isFuture ? 'mínútur' : 'mínútum');\n            } else if (withoutSuffix) {\n                return result + 'mínúta';\n            }\n            return result + 'mínútu';\n        case 'hh':\n            if (plural$2(number)) {\n                return result + (withoutSuffix || isFuture ? 'klukkustundir' : 'klukkustundum');\n            }\n            return result + 'klukkustund';\n        case 'd':\n            if (withoutSuffix) {\n                return 'dagur';\n            }\n            return isFuture ? 'dag' : 'degi';\n        case 'dd':\n            if (plural$2(number)) {\n                if (withoutSuffix) {\n                    return result + 'dagar';\n                }\n                return result + (isFuture ? 'daga' : 'dögum');\n            } else if (withoutSuffix) {\n                return result + 'dagur';\n            }\n            return result + (isFuture ? 'dag' : 'degi');\n        case 'M':\n            if (withoutSuffix) {\n                return 'mánuður';\n            }\n            return isFuture ? 'mánuð' : 'mánuði';\n        case 'MM':\n            if (plural$2(number)) {\n                if (withoutSuffix) {\n                    return result + 'mánuðir';\n                }\n                return result + (isFuture ? 'mánuði' : 'mánuðum');\n            } else if (withoutSuffix) {\n                return result + 'mánuður';\n            }\n            return result + (isFuture ? 'mánuð' : 'mánuði');\n        case 'y':\n            return withoutSuffix || isFuture ? 'ár' : 'ári';\n        case 'yy':\n            if (plural$2(number)) {\n                return result + (withoutSuffix || isFuture ? 'ár' : 'árum');\n            }\n            return result + (withoutSuffix || isFuture ? 'ár' : 'ári');\n    }\n}\n\nhooks.defineLocale('is', {\n    months : 'janúar_febrúar_mars_apríl_maí_júní_júlí_ágúst_september_október_nóvember_desember'.split('_'),\n    monthsShort : 'jan_feb_mar_apr_maí_jún_júl_ágú_sep_okt_nóv_des'.split('_'),\n    weekdays : 'sunnudagur_mánudagur_þriðjudagur_miðvikudagur_fimmtudagur_föstudagur_laugardagur'.split('_'),\n    weekdaysShort : 'sun_mán_þri_mið_fim_fös_lau'.split('_'),\n    weekdaysMin : 'Su_Má_Þr_Mi_Fi_Fö_La'.split('_'),\n    longDateFormat : {\n        LT : 'H:mm',\n        LTS : 'H:mm:ss',\n        L : 'DD.MM.YYYY',\n        LL : 'D. MMMM YYYY',\n        LLL : 'D. MMMM YYYY [kl.] H:mm',\n        LLLL : 'dddd, D. MMMM YYYY [kl.] H:mm'\n    },\n    calendar : {\n        sameDay : '[í dag kl.] LT',\n        nextDay : '[á morgun kl.] LT',\n        nextWeek : 'dddd [kl.] LT',\n        lastDay : '[í gær kl.] LT',\n        lastWeek : '[síðasta] dddd [kl.] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'eftir %s',\n        past : 'fyrir %s síðan',\n        s : translate$5,\n        m : translate$5,\n        mm : translate$5,\n        h : 'klukkustund',\n        hh : translate$5,\n        d : translate$5,\n        dd : translate$5,\n        M : translate$5,\n        MM : translate$5,\n        y : translate$5,\n        yy : translate$5\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}\\./,\n    ordinal : '%d.',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Italian [it]\n//! author : Lorenzo : https://github.com/aliem\n//! author: Mattia Larentis: https://github.com/nostalgiaz\n\nhooks.defineLocale('it', {\n    months : 'gennaio_febbraio_marzo_aprile_maggio_giugno_luglio_agosto_settembre_ottobre_novembre_dicembre'.split('_'),\n    monthsShort : 'gen_feb_mar_apr_mag_giu_lug_ago_set_ott_nov_dic'.split('_'),\n    weekdays : 'domenica_lunedì_martedì_mercoledì_giovedì_venerdì_sabato'.split('_'),\n    weekdaysShort : 'dom_lun_mar_mer_gio_ven_sab'.split('_'),\n    weekdaysMin : 'do_lu_ma_me_gi_ve_sa'.split('_'),\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY HH:mm',\n        LLLL : 'dddd, D MMMM YYYY HH:mm'\n    },\n    calendar : {\n        sameDay: '[Oggi alle] LT',\n        nextDay: '[Domani alle] LT',\n        nextWeek: 'dddd [alle] LT',\n        lastDay: '[Ieri alle] LT',\n        lastWeek: function () {\n            switch (this.day()) {\n                case 0:\n                    return '[la scorsa] dddd [alle] LT';\n                default:\n                    return '[lo scorso] dddd [alle] LT';\n            }\n        },\n        sameElse: 'L'\n    },\n    relativeTime : {\n        future : function (s) {\n            return ((/^[0-9].+$/).test(s) ? 'tra' : 'in') + ' ' + s;\n        },\n        past : '%s fa',\n        s : 'alcuni secondi',\n        m : 'un minuto',\n        mm : '%d minuti',\n        h : 'un\\'ora',\n        hh : '%d ore',\n        d : 'un giorno',\n        dd : '%d giorni',\n        M : 'un mese',\n        MM : '%d mesi',\n        y : 'un anno',\n        yy : '%d anni'\n    },\n    dayOfMonthOrdinalParse : /\\d{1,2}º/,\n    ordinal: '%dº',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Japanese [ja]\n//! author : LI Long : https://github.com/baryon\n\nhooks.defineLocale('ja', {\n    months : '1月_2月_3月_4月_5月_6月_7月_8月_9月_10月_11月_12月'.split('_'),\n    monthsShort : '1月_2月_3月_4月_5月_6月_7月_8月_9月_10月_11月_12月'.split('_'),\n    weekdays : '日曜日_月曜日_火曜日_水曜日_木曜日_金曜日_土曜日'.split('_'),\n    weekdaysShort : '日_月_火_水_木_金_土'.split('_'),\n    weekdaysMin : '日_月_火_水_木_金_土'.split('_'),\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'YYYY/MM/DD',\n        LL : 'YYYY年M月D日',\n        LLL : 'YYYY年M月D日 HH:mm',\n        LLLL : 'YYYY年M月D日 HH:mm dddd',\n        l : 'YYYY/MM/DD',\n        ll : 'YYYY年M月D日',\n        lll : 'YYYY年M月D日 HH:mm',\n        llll : 'YYYY年M月D日 HH:mm dddd'\n    },\n    meridiemParse: /午前|午後/i,\n    isPM : function (input) {\n        return input === '午後';\n    },\n    meridiem : function (hour, minute, isLower) {\n        if (hour < 12) {\n            return '午前';\n        } else {\n            return '午後';\n        }\n    },\n    calendar : {\n        sameDay : '[今日] LT',\n        nextDay : '[明日] LT',\n        nextWeek : '[来週]dddd LT',\n        lastDay : '[昨日] LT',\n        lastWeek : '[前週]dddd LT',\n        sameElse : 'L'\n    },\n    dayOfMonthOrdinalParse : /\\d{1,2}日/,\n    ordinal : function (number, period) {\n        switch (period) {\n            case 'd':\n            case 'D':\n            case 'DDD':\n                return number + '日';\n            default:\n                return number;\n        }\n    },\n    relativeTime : {\n        future : '%s後',\n        past : '%s前',\n        s : '数秒',\n        m : '1分',\n        mm : '%d分',\n        h : '1時間',\n        hh : '%d時間',\n        d : '1日',\n        dd : '%d日',\n        M : '1ヶ月',\n        MM : '%dヶ月',\n        y : '1年',\n        yy : '%d年'\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Javanese [jv]\n//! author : Rony Lantip : https://github.com/lantip\n//! reference: http://jv.wikipedia.org/wiki/Basa_Jawa\n\nhooks.defineLocale('jv', {\n    months : 'Januari_Februari_Maret_April_Mei_Juni_Juli_Agustus_September_Oktober_Nopember_Desember'.split('_'),\n    monthsShort : 'Jan_Feb_Mar_Apr_Mei_Jun_Jul_Ags_Sep_Okt_Nop_Des'.split('_'),\n    weekdays : 'Minggu_Senen_Seloso_Rebu_Kemis_Jemuwah_Septu'.split('_'),\n    weekdaysShort : 'Min_Sen_Sel_Reb_Kem_Jem_Sep'.split('_'),\n    weekdaysMin : 'Mg_Sn_Sl_Rb_Km_Jm_Sp'.split('_'),\n    longDateFormat : {\n        LT : 'HH.mm',\n        LTS : 'HH.mm.ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY [pukul] HH.mm',\n        LLLL : 'dddd, D MMMM YYYY [pukul] HH.mm'\n    },\n    meridiemParse: /enjing|siyang|sonten|ndalu/,\n    meridiemHour : function (hour, meridiem) {\n        if (hour === 12) {\n            hour = 0;\n        }\n        if (meridiem === 'enjing') {\n            return hour;\n        } else if (meridiem === 'siyang') {\n            return hour >= 11 ? hour : hour + 12;\n        } else if (meridiem === 'sonten' || meridiem === 'ndalu') {\n            return hour + 12;\n        }\n    },\n    meridiem : function (hours, minutes, isLower) {\n        if (hours < 11) {\n            return 'enjing';\n        } else if (hours < 15) {\n            return 'siyang';\n        } else if (hours < 19) {\n            return 'sonten';\n        } else {\n            return 'ndalu';\n        }\n    },\n    calendar : {\n        sameDay : '[Dinten puniko pukul] LT',\n        nextDay : '[Mbenjang pukul] LT',\n        nextWeek : 'dddd [pukul] LT',\n        lastDay : '[Kala wingi pukul] LT',\n        lastWeek : 'dddd [kepengker pukul] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'wonten ing %s',\n        past : '%s ingkang kepengker',\n        s : 'sawetawis detik',\n        m : 'setunggal menit',\n        mm : '%d menit',\n        h : 'setunggal jam',\n        hh : '%d jam',\n        d : 'sedinten',\n        dd : '%d dinten',\n        M : 'sewulan',\n        MM : '%d wulan',\n        y : 'setaun',\n        yy : '%d taun'\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 7  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Georgian [ka]\n//! author : Irakli Janiashvili : https://github.com/irakli-janiashvili\n\nhooks.defineLocale('ka', {\n    months : {\n        standalone: 'იანვარი_თებერვალი_მარტი_აპრილი_მაისი_ივნისი_ივლისი_აგვისტო_სექტემბერი_ოქტომბერი_ნოემბერი_დეკემბერი'.split('_'),\n        format: 'იანვარს_თებერვალს_მარტს_აპრილის_მაისს_ივნისს_ივლისს_აგვისტს_სექტემბერს_ოქტომბერს_ნოემბერს_დეკემბერს'.split('_')\n    },\n    monthsShort : 'იან_თებ_მარ_აპრ_მაი_ივნ_ივლ_აგვ_სექ_ოქტ_ნოე_დეკ'.split('_'),\n    weekdays : {\n        standalone: 'კვირა_ორშაბათი_სამშაბათი_ოთხშაბათი_ხუთშაბათი_პარასკევი_შაბათი'.split('_'),\n        format: 'კვირას_ორშაბათს_სამშაბათს_ოთხშაბათს_ხუთშაბათს_პარასკევს_შაბათს'.split('_'),\n        isFormat: /(წინა|შემდეგ)/\n    },\n    weekdaysShort : 'კვი_ორშ_სამ_ოთხ_ხუთ_პარ_შაბ'.split('_'),\n    weekdaysMin : 'კვ_ორ_სა_ოთ_ხუ_პა_შა'.split('_'),\n    longDateFormat : {\n        LT : 'h:mm A',\n        LTS : 'h:mm:ss A',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY h:mm A',\n        LLLL : 'dddd, D MMMM YYYY h:mm A'\n    },\n    calendar : {\n        sameDay : '[დღეს] LT[-ზე]',\n        nextDay : '[ხვალ] LT[-ზე]',\n        lastDay : '[გუშინ] LT[-ზე]',\n        nextWeek : '[შემდეგ] dddd LT[-ზე]',\n        lastWeek : '[წინა] dddd LT-ზე',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : function (s) {\n            return (/(წამი|წუთი|საათი|წელი)/).test(s) ?\n                s.replace(/ი$/, 'ში') :\n                s + 'ში';\n        },\n        past : function (s) {\n            if ((/(წამი|წუთი|საათი|დღე|თვე)/).test(s)) {\n                return s.replace(/(ი|ე)$/, 'ის უკან');\n            }\n            if ((/წელი/).test(s)) {\n                return s.replace(/წელი$/, 'წლის უკან');\n            }\n        },\n        s : 'რამდენიმე წამი',\n        m : 'წუთი',\n        mm : '%d წუთი',\n        h : 'საათი',\n        hh : '%d საათი',\n        d : 'დღე',\n        dd : '%d დღე',\n        M : 'თვე',\n        MM : '%d თვე',\n        y : 'წელი',\n        yy : '%d წელი'\n    },\n    dayOfMonthOrdinalParse: /0|1-ლი|მე-\\d{1,2}|\\d{1,2}-ე/,\n    ordinal : function (number) {\n        if (number === 0) {\n            return number;\n        }\n        if (number === 1) {\n            return number + '-ლი';\n        }\n        if ((number < 20) || (number <= 100 && (number % 20 === 0)) || (number % 100 === 0)) {\n            return 'მე-' + number;\n        }\n        return number + '-ე';\n    },\n    week : {\n        dow : 1,\n        doy : 7\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Kazakh [kk]\n//! authors : Nurlan Rakhimzhanov : https://github.com/nurlan\n\nvar suffixes$1 = {\n    0: '-ші',\n    1: '-ші',\n    2: '-ші',\n    3: '-ші',\n    4: '-ші',\n    5: '-ші',\n    6: '-шы',\n    7: '-ші',\n    8: '-ші',\n    9: '-шы',\n    10: '-шы',\n    20: '-шы',\n    30: '-шы',\n    40: '-шы',\n    50: '-ші',\n    60: '-шы',\n    70: '-ші',\n    80: '-ші',\n    90: '-шы',\n    100: '-ші'\n};\n\nhooks.defineLocale('kk', {\n    months : 'қаңтар_ақпан_наурыз_сәуір_мамыр_маусым_шілде_тамыз_қыркүйек_қазан_қараша_желтоқсан'.split('_'),\n    monthsShort : 'қаң_ақп_нау_сәу_мам_мау_шіл_там_қыр_қаз_қар_жел'.split('_'),\n    weekdays : 'жексенбі_дүйсенбі_сейсенбі_сәрсенбі_бейсенбі_жұма_сенбі'.split('_'),\n    weekdaysShort : 'жек_дүй_сей_сәр_бей_жұм_сен'.split('_'),\n    weekdaysMin : 'жк_дй_сй_ср_бй_жм_сн'.split('_'),\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD.MM.YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY HH:mm',\n        LLLL : 'dddd, D MMMM YYYY HH:mm'\n    },\n    calendar : {\n        sameDay : '[Бүгін сағат] LT',\n        nextDay : '[Ертең сағат] LT',\n        nextWeek : 'dddd [сағат] LT',\n        lastDay : '[Кеше сағат] LT',\n        lastWeek : '[Өткен аптаның] dddd [сағат] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : '%s ішінде',\n        past : '%s бұрын',\n        s : 'бірнеше секунд',\n        m : 'бір минут',\n        mm : '%d минут',\n        h : 'бір сағат',\n        hh : '%d сағат',\n        d : 'бір күн',\n        dd : '%d күн',\n        M : 'бір ай',\n        MM : '%d ай',\n        y : 'бір жыл',\n        yy : '%d жыл'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}-(ші|шы)/,\n    ordinal : function (number) {\n        var a = number % 10,\n            b = number >= 100 ? 100 : null;\n        return number + (suffixes$1[number] || suffixes$1[a] || suffixes$1[b]);\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 7  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Cambodian [km]\n//! author : Kruy Vanna : https://github.com/kruyvanna\n\nhooks.defineLocale('km', {\n    months: 'មករា_កុម្ភៈ_មីនា_មេសា_ឧសភា_មិថុនា_កក្កដា_សីហា_កញ្ញា_តុលា_វិច្ឆិកា_ធ្នូ'.split('_'),\n    monthsShort: 'មករា_កុម្ភៈ_មីនា_មេសា_ឧសភា_មិថុនា_កក្កដា_សីហា_កញ្ញា_តុលា_វិច្ឆិកា_ធ្នូ'.split('_'),\n    weekdays: 'អាទិត្យ_ច័ន្ទ_អង្គារ_ពុធ_ព្រហស្បតិ៍_សុក្រ_សៅរ៍'.split('_'),\n    weekdaysShort: 'អាទិត្យ_ច័ន្ទ_អង្គារ_ពុធ_ព្រហស្បតិ៍_សុក្រ_សៅរ៍'.split('_'),\n    weekdaysMin: 'អាទិត្យ_ច័ន្ទ_អង្គារ_ពុធ_ព្រហស្បតិ៍_សុក្រ_សៅរ៍'.split('_'),\n    longDateFormat: {\n        LT: 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L: 'DD/MM/YYYY',\n        LL: 'D MMMM YYYY',\n        LLL: 'D MMMM YYYY HH:mm',\n        LLLL: 'dddd, D MMMM YYYY HH:mm'\n    },\n    calendar: {\n        sameDay: '[ថ្ងៃនេះ ម៉ោង] LT',\n        nextDay: '[ស្អែក ម៉ោង] LT',\n        nextWeek: 'dddd [ម៉ោង] LT',\n        lastDay: '[ម្សិលមិញ ម៉ោង] LT',\n        lastWeek: 'dddd [សប្តាហ៍មុន] [ម៉ោង] LT',\n        sameElse: 'L'\n    },\n    relativeTime: {\n        future: '%sទៀត',\n        past: '%sមុន',\n        s: 'ប៉ុន្មានវិនាទី',\n        m: 'មួយនាទី',\n        mm: '%d នាទី',\n        h: 'មួយម៉ោង',\n        hh: '%d ម៉ោង',\n        d: 'មួយថ្ងៃ',\n        dd: '%d ថ្ងៃ',\n        M: 'មួយខែ',\n        MM: '%d ខែ',\n        y: 'មួយឆ្នាំ',\n        yy: '%d ឆ្នាំ'\n    },\n    week: {\n        dow: 1, // Monday is the first day of the week.\n        doy: 4 // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Kannada [kn]\n//! author : Rajeev Naik : https://github.com/rajeevnaikte\n\nvar symbolMap$7 = {\n    '1': '೧',\n    '2': '೨',\n    '3': '೩',\n    '4': '೪',\n    '5': '೫',\n    '6': '೬',\n    '7': '೭',\n    '8': '೮',\n    '9': '೯',\n    '0': '೦'\n};\nvar numberMap$6 = {\n    '೧': '1',\n    '೨': '2',\n    '೩': '3',\n    '೪': '4',\n    '೫': '5',\n    '೬': '6',\n    '೭': '7',\n    '೮': '8',\n    '೯': '9',\n    '೦': '0'\n};\n\nhooks.defineLocale('kn', {\n    months : 'ಜನವರಿ_ಫೆಬ್ರವರಿ_ಮಾರ್ಚ್_ಏಪ್ರಿಲ್_ಮೇ_ಜೂನ್_ಜುಲೈ_ಆಗಸ್ಟ್_ಸೆಪ್ಟೆಂಬರ್_ಅಕ್ಟೋಬರ್_ನವೆಂಬರ್_ಡಿಸೆಂಬರ್'.split('_'),\n    monthsShort : 'ಜನ_ಫೆಬ್ರ_ಮಾರ್ಚ್_ಏಪ್ರಿಲ್_ಮೇ_ಜೂನ್_ಜುಲೈ_ಆಗಸ್ಟ್_ಸೆಪ್ಟೆಂಬ_ಅಕ್ಟೋಬ_ನವೆಂಬ_ಡಿಸೆಂಬ'.split('_'),\n    monthsParseExact: true,\n    weekdays : 'ಭಾನುವಾರ_ಸೋಮವಾರ_ಮಂಗಳವಾರ_ಬುಧವಾರ_ಗುರುವಾರ_ಶುಕ್ರವಾರ_ಶನಿವಾರ'.split('_'),\n    weekdaysShort : 'ಭಾನು_ಸೋಮ_ಮಂಗಳ_ಬುಧ_ಗುರು_ಶುಕ್ರ_ಶನಿ'.split('_'),\n    weekdaysMin : 'ಭಾ_ಸೋ_ಮಂ_ಬು_ಗು_ಶು_ಶ'.split('_'),\n    longDateFormat : {\n        LT : 'A h:mm',\n        LTS : 'A h:mm:ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY, A h:mm',\n        LLLL : 'dddd, D MMMM YYYY, A h:mm'\n    },\n    calendar : {\n        sameDay : '[ಇಂದು] LT',\n        nextDay : '[ನಾಳೆ] LT',\n        nextWeek : 'dddd, LT',\n        lastDay : '[ನಿನ್ನೆ] LT',\n        lastWeek : '[ಕೊನೆಯ] dddd, LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : '%s ನಂತರ',\n        past : '%s ಹಿಂದೆ',\n        s : 'ಕೆಲವು ಕ್ಷಣಗಳು',\n        m : 'ಒಂದು ನಿಮಿಷ',\n        mm : '%d ನಿಮಿಷ',\n        h : 'ಒಂದು ಗಂಟೆ',\n        hh : '%d ಗಂಟೆ',\n        d : 'ಒಂದು ದಿನ',\n        dd : '%d ದಿನ',\n        M : 'ಒಂದು ತಿಂಗಳು',\n        MM : '%d ತಿಂಗಳು',\n        y : 'ಒಂದು ವರ್ಷ',\n        yy : '%d ವರ್ಷ'\n    },\n    preparse: function (string) {\n        return string.replace(/[೧೨೩೪೫೬೭೮೯೦]/g, function (match) {\n            return numberMap$6[match];\n        });\n    },\n    postformat: function (string) {\n        return string.replace(/\\d/g, function (match) {\n            return symbolMap$7[match];\n        });\n    },\n    meridiemParse: /ರಾತ್ರಿ|ಬೆಳಿಗ್ಗೆ|ಮಧ್ಯಾಹ್ನ|ಸಂಜೆ/,\n    meridiemHour : function (hour, meridiem) {\n        if (hour === 12) {\n            hour = 0;\n        }\n        if (meridiem === 'ರಾತ್ರಿ') {\n            return hour < 4 ? hour : hour + 12;\n        } else if (meridiem === 'ಬೆಳಿಗ್ಗೆ') {\n            return hour;\n        } else if (meridiem === 'ಮಧ್ಯಾಹ್ನ') {\n            return hour >= 10 ? hour : hour + 12;\n        } else if (meridiem === 'ಸಂಜೆ') {\n            return hour + 12;\n        }\n    },\n    meridiem : function (hour, minute, isLower) {\n        if (hour < 4) {\n            return 'ರಾತ್ರಿ';\n        } else if (hour < 10) {\n            return 'ಬೆಳಿಗ್ಗೆ';\n        } else if (hour < 17) {\n            return 'ಮಧ್ಯಾಹ್ನ';\n        } else if (hour < 20) {\n            return 'ಸಂಜೆ';\n        } else {\n            return 'ರಾತ್ರಿ';\n        }\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}(ನೇ)/,\n    ordinal : function (number) {\n        return number + 'ನೇ';\n    },\n    week : {\n        dow : 0, // Sunday is the first day of the week.\n        doy : 6  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Korean [ko]\n//! author : Kyungwook, Park : https://github.com/kyungw00k\n//! author : Jeeeyul Lee <jeeeyul@gmail.com>\n\nhooks.defineLocale('ko', {\n    months : '1월_2월_3월_4월_5월_6월_7월_8월_9월_10월_11월_12월'.split('_'),\n    monthsShort : '1월_2월_3월_4월_5월_6월_7월_8월_9월_10월_11월_12월'.split('_'),\n    weekdays : '일요일_월요일_화요일_수요일_목요일_금요일_토요일'.split('_'),\n    weekdaysShort : '일_월_화_수_목_금_토'.split('_'),\n    weekdaysMin : '일_월_화_수_목_금_토'.split('_'),\n    longDateFormat : {\n        LT : 'A h:mm',\n        LTS : 'A h:mm:ss',\n        L : 'YYYY.MM.DD',\n        LL : 'YYYY년 MMMM D일',\n        LLL : 'YYYY년 MMMM D일 A h:mm',\n        LLLL : 'YYYY년 MMMM D일 dddd A h:mm',\n        l : 'YYYY.MM.DD',\n        ll : 'YYYY년 MMMM D일',\n        lll : 'YYYY년 MMMM D일 A h:mm',\n        llll : 'YYYY년 MMMM D일 dddd A h:mm'\n    },\n    calendar : {\n        sameDay : '오늘 LT',\n        nextDay : '내일 LT',\n        nextWeek : 'dddd LT',\n        lastDay : '어제 LT',\n        lastWeek : '지난주 dddd LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : '%s 후',\n        past : '%s 전',\n        s : '몇 초',\n        ss : '%d초',\n        m : '1분',\n        mm : '%d분',\n        h : '한 시간',\n        hh : '%d시간',\n        d : '하루',\n        dd : '%d일',\n        M : '한 달',\n        MM : '%d달',\n        y : '일 년',\n        yy : '%d년'\n    },\n    dayOfMonthOrdinalParse : /\\d{1,2}일/,\n    ordinal : '%d일',\n    meridiemParse : /오전|오후/,\n    isPM : function (token) {\n        return token === '오후';\n    },\n    meridiem : function (hour, minute, isUpper) {\n        return hour < 12 ? '오전' : '오후';\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Kyrgyz [ky]\n//! author : Chyngyz Arystan uulu : https://github.com/chyngyz\n\n\nvar suffixes$2 = {\n    0: '-чү',\n    1: '-чи',\n    2: '-чи',\n    3: '-чү',\n    4: '-чү',\n    5: '-чи',\n    6: '-чы',\n    7: '-чи',\n    8: '-чи',\n    9: '-чу',\n    10: '-чу',\n    20: '-чы',\n    30: '-чу',\n    40: '-чы',\n    50: '-чү',\n    60: '-чы',\n    70: '-чи',\n    80: '-чи',\n    90: '-чу',\n    100: '-чү'\n};\n\nhooks.defineLocale('ky', {\n    months : 'январь_февраль_март_апрель_май_июнь_июль_август_сентябрь_октябрь_ноябрь_декабрь'.split('_'),\n    monthsShort : 'янв_фев_март_апр_май_июнь_июль_авг_сен_окт_ноя_дек'.split('_'),\n    weekdays : 'Жекшемби_Дүйшөмбү_Шейшемби_Шаршемби_Бейшемби_Жума_Ишемби'.split('_'),\n    weekdaysShort : 'Жек_Дүй_Шей_Шар_Бей_Жум_Ише'.split('_'),\n    weekdaysMin : 'Жк_Дй_Шй_Шр_Бй_Жм_Иш'.split('_'),\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD.MM.YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY HH:mm',\n        LLLL : 'dddd, D MMMM YYYY HH:mm'\n    },\n    calendar : {\n        sameDay : '[Бүгүн саат] LT',\n        nextDay : '[Эртең саат] LT',\n        nextWeek : 'dddd [саат] LT',\n        lastDay : '[Кече саат] LT',\n        lastWeek : '[Өткен аптанын] dddd [күнү] [саат] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : '%s ичинде',\n        past : '%s мурун',\n        s : 'бирнече секунд',\n        m : 'бир мүнөт',\n        mm : '%d мүнөт',\n        h : 'бир саат',\n        hh : '%d саат',\n        d : 'бир күн',\n        dd : '%d күн',\n        M : 'бир ай',\n        MM : '%d ай',\n        y : 'бир жыл',\n        yy : '%d жыл'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}-(чи|чы|чү|чу)/,\n    ordinal : function (number) {\n        var a = number % 10,\n            b = number >= 100 ? 100 : null;\n        return number + (suffixes$2[number] || suffixes$2[a] || suffixes$2[b]);\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 7  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Luxembourgish [lb]\n//! author : mweimerskirch : https://github.com/mweimerskirch\n//! author : David Raison : https://github.com/kwisatz\n\nfunction processRelativeTime$5(number, withoutSuffix, key, isFuture) {\n    var format = {\n        'm': ['eng Minutt', 'enger Minutt'],\n        'h': ['eng Stonn', 'enger Stonn'],\n        'd': ['een Dag', 'engem Dag'],\n        'M': ['ee Mount', 'engem Mount'],\n        'y': ['ee Joer', 'engem Joer']\n    };\n    return withoutSuffix ? format[key][0] : format[key][1];\n}\nfunction processFutureTime(string) {\n    var number = string.substr(0, string.indexOf(' '));\n    if (eifelerRegelAppliesToNumber(number)) {\n        return 'a ' + string;\n    }\n    return 'an ' + string;\n}\nfunction processPastTime(string) {\n    var number = string.substr(0, string.indexOf(' '));\n    if (eifelerRegelAppliesToNumber(number)) {\n        return 'viru ' + string;\n    }\n    return 'virun ' + string;\n}\n/**\n * Returns true if the word before the given number loses the '-n' ending.\n * e.g. 'an 10 Deeg' but 'a 5 Deeg'\n *\n * @param number {integer}\n * @returns {boolean}\n */\nfunction eifelerRegelAppliesToNumber(number) {\n    number = parseInt(number, 10);\n    if (isNaN(number)) {\n        return false;\n    }\n    if (number < 0) {\n        // Negative Number --> always true\n        return true;\n    } else if (number < 10) {\n        // Only 1 digit\n        if (4 <= number && number <= 7) {\n            return true;\n        }\n        return false;\n    } else if (number < 100) {\n        // 2 digits\n        var lastDigit = number % 10, firstDigit = number / 10;\n        if (lastDigit === 0) {\n            return eifelerRegelAppliesToNumber(firstDigit);\n        }\n        return eifelerRegelAppliesToNumber(lastDigit);\n    } else if (number < 10000) {\n        // 3 or 4 digits --> recursively check first digit\n        while (number >= 10) {\n            number = number / 10;\n        }\n        return eifelerRegelAppliesToNumber(number);\n    } else {\n        // Anything larger than 4 digits: recursively check first n-3 digits\n        number = number / 1000;\n        return eifelerRegelAppliesToNumber(number);\n    }\n}\n\nhooks.defineLocale('lb', {\n    months: 'Januar_Februar_Mäerz_Abrëll_Mee_Juni_Juli_August_September_Oktober_November_Dezember'.split('_'),\n    monthsShort: 'Jan._Febr._Mrz._Abr._Mee_Jun._Jul._Aug._Sept._Okt._Nov._Dez.'.split('_'),\n    monthsParseExact : true,\n    weekdays: 'Sonndeg_Méindeg_Dënschdeg_Mëttwoch_Donneschdeg_Freideg_Samschdeg'.split('_'),\n    weekdaysShort: 'So._Mé._Dë._Më._Do._Fr._Sa.'.split('_'),\n    weekdaysMin: 'So_Mé_Dë_Më_Do_Fr_Sa'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat: {\n        LT: 'H:mm [Auer]',\n        LTS: 'H:mm:ss [Auer]',\n        L: 'DD.MM.YYYY',\n        LL: 'D. MMMM YYYY',\n        LLL: 'D. MMMM YYYY H:mm [Auer]',\n        LLLL: 'dddd, D. MMMM YYYY H:mm [Auer]'\n    },\n    calendar: {\n        sameDay: '[Haut um] LT',\n        sameElse: 'L',\n        nextDay: '[Muer um] LT',\n        nextWeek: 'dddd [um] LT',\n        lastDay: '[Gëschter um] LT',\n        lastWeek: function () {\n            // Different date string for 'Dënschdeg' (Tuesday) and 'Donneschdeg' (Thursday) due to phonological rule\n            switch (this.day()) {\n                case 2:\n                case 4:\n                    return '[Leschten] dddd [um] LT';\n                default:\n                    return '[Leschte] dddd [um] LT';\n            }\n        }\n    },\n    relativeTime : {\n        future : processFutureTime,\n        past : processPastTime,\n        s : 'e puer Sekonnen',\n        m : processRelativeTime$5,\n        mm : '%d Minutten',\n        h : processRelativeTime$5,\n        hh : '%d Stonnen',\n        d : processRelativeTime$5,\n        dd : '%d Deeg',\n        M : processRelativeTime$5,\n        MM : '%d Méint',\n        y : processRelativeTime$5,\n        yy : '%d Joer'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}\\./,\n    ordinal: '%d.',\n    week: {\n        dow: 1, // Monday is the first day of the week.\n        doy: 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Lao [lo]\n//! author : Ryan Hart : https://github.com/ryanhart2\n\nhooks.defineLocale('lo', {\n    months : 'ມັງກອນ_ກຸມພາ_ມີນາ_ເມສາ_ພຶດສະພາ_ມິຖຸນາ_ກໍລະກົດ_ສິງຫາ_ກັນຍາ_ຕຸລາ_ພະຈິກ_ທັນວາ'.split('_'),\n    monthsShort : 'ມັງກອນ_ກຸມພາ_ມີນາ_ເມສາ_ພຶດສະພາ_ມິຖຸນາ_ກໍລະກົດ_ສິງຫາ_ກັນຍາ_ຕຸລາ_ພະຈິກ_ທັນວາ'.split('_'),\n    weekdays : 'ອາທິດ_ຈັນ_ອັງຄານ_ພຸດ_ພະຫັດ_ສຸກ_ເສົາ'.split('_'),\n    weekdaysShort : 'ທິດ_ຈັນ_ອັງຄານ_ພຸດ_ພະຫັດ_ສຸກ_ເສົາ'.split('_'),\n    weekdaysMin : 'ທ_ຈ_ອຄ_ພ_ພຫ_ສກ_ສ'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY HH:mm',\n        LLLL : 'ວັນdddd D MMMM YYYY HH:mm'\n    },\n    meridiemParse: /ຕອນເຊົ້າ|ຕອນແລງ/,\n    isPM: function (input) {\n        return input === 'ຕອນແລງ';\n    },\n    meridiem : function (hour, minute, isLower) {\n        if (hour < 12) {\n            return 'ຕອນເຊົ້າ';\n        } else {\n            return 'ຕອນແລງ';\n        }\n    },\n    calendar : {\n        sameDay : '[ມື້ນີ້ເວລາ] LT',\n        nextDay : '[ມື້ອື່ນເວລາ] LT',\n        nextWeek : '[ວັນ]dddd[ໜ້າເວລາ] LT',\n        lastDay : '[ມື້ວານນີ້ເວລາ] LT',\n        lastWeek : '[ວັນ]dddd[ແລ້ວນີ້ເວລາ] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'ອີກ %s',\n        past : '%sຜ່ານມາ',\n        s : 'ບໍ່ເທົ່າໃດວິນາທີ',\n        m : '1 ນາທີ',\n        mm : '%d ນາທີ',\n        h : '1 ຊົ່ວໂມງ',\n        hh : '%d ຊົ່ວໂມງ',\n        d : '1 ມື້',\n        dd : '%d ມື້',\n        M : '1 ເດືອນ',\n        MM : '%d ເດືອນ',\n        y : '1 ປີ',\n        yy : '%d ປີ'\n    },\n    dayOfMonthOrdinalParse: /(ທີ່)\\d{1,2}/,\n    ordinal : function (number) {\n        return 'ທີ່' + number;\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Lithuanian [lt]\n//! author : Mindaugas Mozūras : https://github.com/mmozuras\n\nvar units = {\n    'm' : 'minutė_minutės_minutę',\n    'mm': 'minutės_minučių_minutes',\n    'h' : 'valanda_valandos_valandą',\n    'hh': 'valandos_valandų_valandas',\n    'd' : 'diena_dienos_dieną',\n    'dd': 'dienos_dienų_dienas',\n    'M' : 'mėnuo_mėnesio_mėnesį',\n    'MM': 'mėnesiai_mėnesių_mėnesius',\n    'y' : 'metai_metų_metus',\n    'yy': 'metai_metų_metus'\n};\nfunction translateSeconds(number, withoutSuffix, key, isFuture) {\n    if (withoutSuffix) {\n        return 'kelios sekundės';\n    } else {\n        return isFuture ? 'kelių sekundžių' : 'kelias sekundes';\n    }\n}\nfunction translateSingular(number, withoutSuffix, key, isFuture) {\n    return withoutSuffix ? forms(key)[0] : (isFuture ? forms(key)[1] : forms(key)[2]);\n}\nfunction special(number) {\n    return number % 10 === 0 || (number > 10 && number < 20);\n}\nfunction forms(key) {\n    return units[key].split('_');\n}\nfunction translate$6(number, withoutSuffix, key, isFuture) {\n    var result = number + ' ';\n    if (number === 1) {\n        return result + translateSingular(number, withoutSuffix, key[0], isFuture);\n    } else if (withoutSuffix) {\n        return result + (special(number) ? forms(key)[1] : forms(key)[0]);\n    } else {\n        if (isFuture) {\n            return result + forms(key)[1];\n        } else {\n            return result + (special(number) ? forms(key)[1] : forms(key)[2]);\n        }\n    }\n}\nhooks.defineLocale('lt', {\n    months : {\n        format: 'sausio_vasario_kovo_balandžio_gegužės_birželio_liepos_rugpjūčio_rugsėjo_spalio_lapkričio_gruodžio'.split('_'),\n        standalone: 'sausis_vasaris_kovas_balandis_gegužė_birželis_liepa_rugpjūtis_rugsėjis_spalis_lapkritis_gruodis'.split('_'),\n        isFormat: /D[oD]?(\\[[^\\[\\]]*\\]|\\s)+MMMM?|MMMM?(\\[[^\\[\\]]*\\]|\\s)+D[oD]?/\n    },\n    monthsShort : 'sau_vas_kov_bal_geg_bir_lie_rgp_rgs_spa_lap_grd'.split('_'),\n    weekdays : {\n        format: 'sekmadienį_pirmadienį_antradienį_trečiadienį_ketvirtadienį_penktadienį_šeštadienį'.split('_'),\n        standalone: 'sekmadienis_pirmadienis_antradienis_trečiadienis_ketvirtadienis_penktadienis_šeštadienis'.split('_'),\n        isFormat: /dddd HH:mm/\n    },\n    weekdaysShort : 'Sek_Pir_Ant_Tre_Ket_Pen_Šeš'.split('_'),\n    weekdaysMin : 'S_P_A_T_K_Pn_Š'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'YYYY-MM-DD',\n        LL : 'YYYY [m.] MMMM D [d.]',\n        LLL : 'YYYY [m.] MMMM D [d.], HH:mm [val.]',\n        LLLL : 'YYYY [m.] MMMM D [d.], dddd, HH:mm [val.]',\n        l : 'YYYY-MM-DD',\n        ll : 'YYYY [m.] MMMM D [d.]',\n        lll : 'YYYY [m.] MMMM D [d.], HH:mm [val.]',\n        llll : 'YYYY [m.] MMMM D [d.], ddd, HH:mm [val.]'\n    },\n    calendar : {\n        sameDay : '[Šiandien] LT',\n        nextDay : '[Rytoj] LT',\n        nextWeek : 'dddd LT',\n        lastDay : '[Vakar] LT',\n        lastWeek : '[Praėjusį] dddd LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'po %s',\n        past : 'prieš %s',\n        s : translateSeconds,\n        m : translateSingular,\n        mm : translate$6,\n        h : translateSingular,\n        hh : translate$6,\n        d : translateSingular,\n        dd : translate$6,\n        M : translateSingular,\n        MM : translate$6,\n        y : translateSingular,\n        yy : translate$6\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}-oji/,\n    ordinal : function (number) {\n        return number + '-oji';\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Latvian [lv]\n//! author : Kristaps Karlsons : https://github.com/skakri\n//! author : Jānis Elmeris : https://github.com/JanisE\n\nvar units$1 = {\n    'm': 'minūtes_minūtēm_minūte_minūtes'.split('_'),\n    'mm': 'minūtes_minūtēm_minūte_minūtes'.split('_'),\n    'h': 'stundas_stundām_stunda_stundas'.split('_'),\n    'hh': 'stundas_stundām_stunda_stundas'.split('_'),\n    'd': 'dienas_dienām_diena_dienas'.split('_'),\n    'dd': 'dienas_dienām_diena_dienas'.split('_'),\n    'M': 'mēneša_mēnešiem_mēnesis_mēneši'.split('_'),\n    'MM': 'mēneša_mēnešiem_mēnesis_mēneši'.split('_'),\n    'y': 'gada_gadiem_gads_gadi'.split('_'),\n    'yy': 'gada_gadiem_gads_gadi'.split('_')\n};\n/**\n * @param withoutSuffix boolean true = a length of time; false = before/after a period of time.\n */\nfunction format$1(forms, number, withoutSuffix) {\n    if (withoutSuffix) {\n        // E.g. \"21 minūte\", \"3 minūtes\".\n        return number % 10 === 1 && number % 100 !== 11 ? forms[2] : forms[3];\n    } else {\n        // E.g. \"21 minūtes\" as in \"pēc 21 minūtes\".\n        // E.g. \"3 minūtēm\" as in \"pēc 3 minūtēm\".\n        return number % 10 === 1 && number % 100 !== 11 ? forms[0] : forms[1];\n    }\n}\nfunction relativeTimeWithPlural$1(number, withoutSuffix, key) {\n    return number + ' ' + format$1(units$1[key], number, withoutSuffix);\n}\nfunction relativeTimeWithSingular(number, withoutSuffix, key) {\n    return format$1(units$1[key], number, withoutSuffix);\n}\nfunction relativeSeconds(number, withoutSuffix) {\n    return withoutSuffix ? 'dažas sekundes' : 'dažām sekundēm';\n}\n\nhooks.defineLocale('lv', {\n    months : 'janvāris_februāris_marts_aprīlis_maijs_jūnijs_jūlijs_augusts_septembris_oktobris_novembris_decembris'.split('_'),\n    monthsShort : 'jan_feb_mar_apr_mai_jūn_jūl_aug_sep_okt_nov_dec'.split('_'),\n    weekdays : 'svētdiena_pirmdiena_otrdiena_trešdiena_ceturtdiena_piektdiena_sestdiena'.split('_'),\n    weekdaysShort : 'Sv_P_O_T_C_Pk_S'.split('_'),\n    weekdaysMin : 'Sv_P_O_T_C_Pk_S'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD.MM.YYYY.',\n        LL : 'YYYY. [gada] D. MMMM',\n        LLL : 'YYYY. [gada] D. MMMM, HH:mm',\n        LLLL : 'YYYY. [gada] D. MMMM, dddd, HH:mm'\n    },\n    calendar : {\n        sameDay : '[Šodien pulksten] LT',\n        nextDay : '[Rīt pulksten] LT',\n        nextWeek : 'dddd [pulksten] LT',\n        lastDay : '[Vakar pulksten] LT',\n        lastWeek : '[Pagājušā] dddd [pulksten] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'pēc %s',\n        past : 'pirms %s',\n        s : relativeSeconds,\n        m : relativeTimeWithSingular,\n        mm : relativeTimeWithPlural$1,\n        h : relativeTimeWithSingular,\n        hh : relativeTimeWithPlural$1,\n        d : relativeTimeWithSingular,\n        dd : relativeTimeWithPlural$1,\n        M : relativeTimeWithSingular,\n        MM : relativeTimeWithPlural$1,\n        y : relativeTimeWithSingular,\n        yy : relativeTimeWithPlural$1\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}\\./,\n    ordinal : '%d.',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Montenegrin [me]\n//! author : Miodrag Nikač <miodrag@restartit.me> : https://github.com/miodragnikac\n\nvar translator = {\n    words: { //Different grammatical cases\n        m: ['jedan minut', 'jednog minuta'],\n        mm: ['minut', 'minuta', 'minuta'],\n        h: ['jedan sat', 'jednog sata'],\n        hh: ['sat', 'sata', 'sati'],\n        dd: ['dan', 'dana', 'dana'],\n        MM: ['mjesec', 'mjeseca', 'mjeseci'],\n        yy: ['godina', 'godine', 'godina']\n    },\n    correctGrammaticalCase: function (number, wordKey) {\n        return number === 1 ? wordKey[0] : (number >= 2 && number <= 4 ? wordKey[1] : wordKey[2]);\n    },\n    translate: function (number, withoutSuffix, key) {\n        var wordKey = translator.words[key];\n        if (key.length === 1) {\n            return withoutSuffix ? wordKey[0] : wordKey[1];\n        } else {\n            return number + ' ' + translator.correctGrammaticalCase(number, wordKey);\n        }\n    }\n};\n\nhooks.defineLocale('me', {\n    months: 'januar_februar_mart_april_maj_jun_jul_avgust_septembar_oktobar_novembar_decembar'.split('_'),\n    monthsShort: 'jan._feb._mar._apr._maj_jun_jul_avg._sep._okt._nov._dec.'.split('_'),\n    monthsParseExact : true,\n    weekdays: 'nedjelja_ponedjeljak_utorak_srijeda_četvrtak_petak_subota'.split('_'),\n    weekdaysShort: 'ned._pon._uto._sri._čet._pet._sub.'.split('_'),\n    weekdaysMin: 'ne_po_ut_sr_če_pe_su'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat: {\n        LT: 'H:mm',\n        LTS : 'H:mm:ss',\n        L: 'DD.MM.YYYY',\n        LL: 'D. MMMM YYYY',\n        LLL: 'D. MMMM YYYY H:mm',\n        LLLL: 'dddd, D. MMMM YYYY H:mm'\n    },\n    calendar: {\n        sameDay: '[danas u] LT',\n        nextDay: '[sjutra u] LT',\n\n        nextWeek: function () {\n            switch (this.day()) {\n                case 0:\n                    return '[u] [nedjelju] [u] LT';\n                case 3:\n                    return '[u] [srijedu] [u] LT';\n                case 6:\n                    return '[u] [subotu] [u] LT';\n                case 1:\n                case 2:\n                case 4:\n                case 5:\n                    return '[u] dddd [u] LT';\n            }\n        },\n        lastDay  : '[juče u] LT',\n        lastWeek : function () {\n            var lastWeekDays = [\n                '[prošle] [nedjelje] [u] LT',\n                '[prošlog] [ponedjeljka] [u] LT',\n                '[prošlog] [utorka] [u] LT',\n                '[prošle] [srijede] [u] LT',\n                '[prošlog] [četvrtka] [u] LT',\n                '[prošlog] [petka] [u] LT',\n                '[prošle] [subote] [u] LT'\n            ];\n            return lastWeekDays[this.day()];\n        },\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'za %s',\n        past   : 'prije %s',\n        s      : 'nekoliko sekundi',\n        m      : translator.translate,\n        mm     : translator.translate,\n        h      : translator.translate,\n        hh     : translator.translate,\n        d      : 'dan',\n        dd     : translator.translate,\n        M      : 'mjesec',\n        MM     : translator.translate,\n        y      : 'godinu',\n        yy     : translator.translate\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}\\./,\n    ordinal : '%d.',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 7  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Maori [mi]\n//! author : John Corrigan <robbiecloset@gmail.com> : https://github.com/johnideal\n\nhooks.defineLocale('mi', {\n    months: 'Kohi-tāte_Hui-tanguru_Poutū-te-rangi_Paenga-whāwhā_Haratua_Pipiri_Hōngoingoi_Here-turi-kōkā_Mahuru_Whiringa-ā-nuku_Whiringa-ā-rangi_Hakihea'.split('_'),\n    monthsShort: 'Kohi_Hui_Pou_Pae_Hara_Pipi_Hōngoi_Here_Mahu_Whi-nu_Whi-ra_Haki'.split('_'),\n    monthsRegex: /(?:['a-z\\u0101\\u014D\\u016B]+\\-?){1,3}/i,\n    monthsStrictRegex: /(?:['a-z\\u0101\\u014D\\u016B]+\\-?){1,3}/i,\n    monthsShortRegex: /(?:['a-z\\u0101\\u014D\\u016B]+\\-?){1,3}/i,\n    monthsShortStrictRegex: /(?:['a-z\\u0101\\u014D\\u016B]+\\-?){1,2}/i,\n    weekdays: 'Rātapu_Mane_Tūrei_Wenerei_Tāite_Paraire_Hātarei'.split('_'),\n    weekdaysShort: 'Ta_Ma_Tū_We_Tāi_Pa_Hā'.split('_'),\n    weekdaysMin: 'Ta_Ma_Tū_We_Tāi_Pa_Hā'.split('_'),\n    longDateFormat: {\n        LT: 'HH:mm',\n        LTS: 'HH:mm:ss',\n        L: 'DD/MM/YYYY',\n        LL: 'D MMMM YYYY',\n        LLL: 'D MMMM YYYY [i] HH:mm',\n        LLLL: 'dddd, D MMMM YYYY [i] HH:mm'\n    },\n    calendar: {\n        sameDay: '[i teie mahana, i] LT',\n        nextDay: '[apopo i] LT',\n        nextWeek: 'dddd [i] LT',\n        lastDay: '[inanahi i] LT',\n        lastWeek: 'dddd [whakamutunga i] LT',\n        sameElse: 'L'\n    },\n    relativeTime: {\n        future: 'i roto i %s',\n        past: '%s i mua',\n        s: 'te hēkona ruarua',\n        m: 'he meneti',\n        mm: '%d meneti',\n        h: 'te haora',\n        hh: '%d haora',\n        d: 'he ra',\n        dd: '%d ra',\n        M: 'he marama',\n        MM: '%d marama',\n        y: 'he tau',\n        yy: '%d tau'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}º/,\n    ordinal: '%dº',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Macedonian [mk]\n//! author : Borislav Mickov : https://github.com/B0k0\n\nhooks.defineLocale('mk', {\n    months : 'јануари_февруари_март_април_мај_јуни_јули_август_септември_октомври_ноември_декември'.split('_'),\n    monthsShort : 'јан_фев_мар_апр_мај_јун_јул_авг_сеп_окт_ное_дек'.split('_'),\n    weekdays : 'недела_понеделник_вторник_среда_четврток_петок_сабота'.split('_'),\n    weekdaysShort : 'нед_пон_вто_сре_чет_пет_саб'.split('_'),\n    weekdaysMin : 'нe_пo_вт_ср_че_пе_сa'.split('_'),\n    longDateFormat : {\n        LT : 'H:mm',\n        LTS : 'H:mm:ss',\n        L : 'D.MM.YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY H:mm',\n        LLLL : 'dddd, D MMMM YYYY H:mm'\n    },\n    calendar : {\n        sameDay : '[Денес во] LT',\n        nextDay : '[Утре во] LT',\n        nextWeek : '[Во] dddd [во] LT',\n        lastDay : '[Вчера во] LT',\n        lastWeek : function () {\n            switch (this.day()) {\n                case 0:\n                case 3:\n                case 6:\n                    return '[Изминатата] dddd [во] LT';\n                case 1:\n                case 2:\n                case 4:\n                case 5:\n                    return '[Изминатиот] dddd [во] LT';\n            }\n        },\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'после %s',\n        past : 'пред %s',\n        s : 'неколку секунди',\n        m : 'минута',\n        mm : '%d минути',\n        h : 'час',\n        hh : '%d часа',\n        d : 'ден',\n        dd : '%d дена',\n        M : 'месец',\n        MM : '%d месеци',\n        y : 'година',\n        yy : '%d години'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}-(ев|ен|ти|ви|ри|ми)/,\n    ordinal : function (number) {\n        var lastDigit = number % 10,\n            last2Digits = number % 100;\n        if (number === 0) {\n            return number + '-ев';\n        } else if (last2Digits === 0) {\n            return number + '-ен';\n        } else if (last2Digits > 10 && last2Digits < 20) {\n            return number + '-ти';\n        } else if (lastDigit === 1) {\n            return number + '-ви';\n        } else if (lastDigit === 2) {\n            return number + '-ри';\n        } else if (lastDigit === 7 || lastDigit === 8) {\n            return number + '-ми';\n        } else {\n            return number + '-ти';\n        }\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 7  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Malayalam [ml]\n//! author : Floyd Pink : https://github.com/floydpink\n\nhooks.defineLocale('ml', {\n    months : 'ജനുവരി_ഫെബ്രുവരി_മാർച്ച്_ഏപ്രിൽ_മേയ്_ജൂൺ_ജൂലൈ_ഓഗസ്റ്റ്_സെപ്റ്റംബർ_ഒക്ടോബർ_നവംബർ_ഡിസംബർ'.split('_'),\n    monthsShort : 'ജനു._ഫെബ്രു._മാർ._ഏപ്രി._മേയ്_ജൂൺ_ജൂലൈ._ഓഗ._സെപ്റ്റ._ഒക്ടോ._നവം._ഡിസം.'.split('_'),\n    monthsParseExact : true,\n    weekdays : 'ഞായറാഴ്ച_തിങ്കളാഴ്ച_ചൊവ്വാഴ്ച_ബുധനാഴ്ച_വ്യാഴാഴ്ച_വെള്ളിയാഴ്ച_ശനിയാഴ്ച'.split('_'),\n    weekdaysShort : 'ഞായർ_തിങ്കൾ_ചൊവ്വ_ബുധൻ_വ്യാഴം_വെള്ളി_ശനി'.split('_'),\n    weekdaysMin : 'ഞാ_തി_ചൊ_ബു_വ്യാ_വെ_ശ'.split('_'),\n    longDateFormat : {\n        LT : 'A h:mm -നു',\n        LTS : 'A h:mm:ss -നു',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY, A h:mm -നു',\n        LLLL : 'dddd, D MMMM YYYY, A h:mm -നു'\n    },\n    calendar : {\n        sameDay : '[ഇന്ന്] LT',\n        nextDay : '[നാളെ] LT',\n        nextWeek : 'dddd, LT',\n        lastDay : '[ഇന്നലെ] LT',\n        lastWeek : '[കഴിഞ്ഞ] dddd, LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : '%s കഴിഞ്ഞ്',\n        past : '%s മുൻപ്',\n        s : 'അൽപ നിമിഷങ്ങൾ',\n        m : 'ഒരു മിനിറ്റ്',\n        mm : '%d മിനിറ്റ്',\n        h : 'ഒരു മണിക്കൂർ',\n        hh : '%d മണിക്കൂർ',\n        d : 'ഒരു ദിവസം',\n        dd : '%d ദിവസം',\n        M : 'ഒരു മാസം',\n        MM : '%d മാസം',\n        y : 'ഒരു വർഷം',\n        yy : '%d വർഷം'\n    },\n    meridiemParse: /രാത്രി|രാവിലെ|ഉച്ച കഴിഞ്ഞ്|വൈകുന്നേരം|രാത്രി/i,\n    meridiemHour : function (hour, meridiem) {\n        if (hour === 12) {\n            hour = 0;\n        }\n        if ((meridiem === 'രാത്രി' && hour >= 4) ||\n                meridiem === 'ഉച്ച കഴിഞ്ഞ്' ||\n                meridiem === 'വൈകുന്നേരം') {\n            return hour + 12;\n        } else {\n            return hour;\n        }\n    },\n    meridiem : function (hour, minute, isLower) {\n        if (hour < 4) {\n            return 'രാത്രി';\n        } else if (hour < 12) {\n            return 'രാവിലെ';\n        } else if (hour < 17) {\n            return 'ഉച്ച കഴിഞ്ഞ്';\n        } else if (hour < 20) {\n            return 'വൈകുന്നേരം';\n        } else {\n            return 'രാത്രി';\n        }\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Marathi [mr]\n//! author : Harshad Kale : https://github.com/kalehv\n//! author : Vivek Athalye : https://github.com/vnathalye\n\nvar symbolMap$8 = {\n    '1': '१',\n    '2': '२',\n    '3': '३',\n    '4': '४',\n    '5': '५',\n    '6': '६',\n    '7': '७',\n    '8': '८',\n    '9': '९',\n    '0': '०'\n};\nvar numberMap$7 = {\n    '१': '1',\n    '२': '2',\n    '३': '3',\n    '४': '4',\n    '५': '5',\n    '६': '6',\n    '७': '7',\n    '८': '8',\n    '९': '9',\n    '०': '0'\n};\n\nfunction relativeTimeMr(number, withoutSuffix, string, isFuture)\n{\n    var output = '';\n    if (withoutSuffix) {\n        switch (string) {\n            case 's': output = 'काही सेकंद'; break;\n            case 'm': output = 'एक मिनिट'; break;\n            case 'mm': output = '%d मिनिटे'; break;\n            case 'h': output = 'एक तास'; break;\n            case 'hh': output = '%d तास'; break;\n            case 'd': output = 'एक दिवस'; break;\n            case 'dd': output = '%d दिवस'; break;\n            case 'M': output = 'एक महिना'; break;\n            case 'MM': output = '%d महिने'; break;\n            case 'y': output = 'एक वर्ष'; break;\n            case 'yy': output = '%d वर्षे'; break;\n        }\n    }\n    else {\n        switch (string) {\n            case 's': output = 'काही सेकंदां'; break;\n            case 'm': output = 'एका मिनिटा'; break;\n            case 'mm': output = '%d मिनिटां'; break;\n            case 'h': output = 'एका तासा'; break;\n            case 'hh': output = '%d तासां'; break;\n            case 'd': output = 'एका दिवसा'; break;\n            case 'dd': output = '%d दिवसां'; break;\n            case 'M': output = 'एका महिन्या'; break;\n            case 'MM': output = '%d महिन्यां'; break;\n            case 'y': output = 'एका वर्षा'; break;\n            case 'yy': output = '%d वर्षां'; break;\n        }\n    }\n    return output.replace(/%d/i, number);\n}\n\nhooks.defineLocale('mr', {\n    months : 'जानेवारी_फेब्रुवारी_मार्च_एप्रिल_मे_जून_जुलै_ऑगस्ट_सप्टेंबर_ऑक्टोबर_नोव्हेंबर_डिसेंबर'.split('_'),\n    monthsShort: 'जाने._फेब्रु._मार्च._एप्रि._मे._जून._जुलै._ऑग._सप्टें._ऑक्टो._नोव्हें._डिसें.'.split('_'),\n    monthsParseExact : true,\n    weekdays : 'रविवार_सोमवार_मंगळवार_बुधवार_गुरूवार_शुक्रवार_शनिवार'.split('_'),\n    weekdaysShort : 'रवि_सोम_मंगळ_बुध_गुरू_शुक्र_शनि'.split('_'),\n    weekdaysMin : 'र_सो_मं_बु_गु_शु_श'.split('_'),\n    longDateFormat : {\n        LT : 'A h:mm वाजता',\n        LTS : 'A h:mm:ss वाजता',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY, A h:mm वाजता',\n        LLLL : 'dddd, D MMMM YYYY, A h:mm वाजता'\n    },\n    calendar : {\n        sameDay : '[आज] LT',\n        nextDay : '[उद्या] LT',\n        nextWeek : 'dddd, LT',\n        lastDay : '[काल] LT',\n        lastWeek: '[मागील] dddd, LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future: '%sमध्ये',\n        past: '%sपूर्वी',\n        s: relativeTimeMr,\n        m: relativeTimeMr,\n        mm: relativeTimeMr,\n        h: relativeTimeMr,\n        hh: relativeTimeMr,\n        d: relativeTimeMr,\n        dd: relativeTimeMr,\n        M: relativeTimeMr,\n        MM: relativeTimeMr,\n        y: relativeTimeMr,\n        yy: relativeTimeMr\n    },\n    preparse: function (string) {\n        return string.replace(/[१२३४५६७८९०]/g, function (match) {\n            return numberMap$7[match];\n        });\n    },\n    postformat: function (string) {\n        return string.replace(/\\d/g, function (match) {\n            return symbolMap$8[match];\n        });\n    },\n    meridiemParse: /रात्री|सकाळी|दुपारी|सायंकाळी/,\n    meridiemHour : function (hour, meridiem) {\n        if (hour === 12) {\n            hour = 0;\n        }\n        if (meridiem === 'रात्री') {\n            return hour < 4 ? hour : hour + 12;\n        } else if (meridiem === 'सकाळी') {\n            return hour;\n        } else if (meridiem === 'दुपारी') {\n            return hour >= 10 ? hour : hour + 12;\n        } else if (meridiem === 'सायंकाळी') {\n            return hour + 12;\n        }\n    },\n    meridiem: function (hour, minute, isLower) {\n        if (hour < 4) {\n            return 'रात्री';\n        } else if (hour < 10) {\n            return 'सकाळी';\n        } else if (hour < 17) {\n            return 'दुपारी';\n        } else if (hour < 20) {\n            return 'सायंकाळी';\n        } else {\n            return 'रात्री';\n        }\n    },\n    week : {\n        dow : 0, // Sunday is the first day of the week.\n        doy : 6  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Malay [ms-my]\n//! note : DEPRECATED, the correct one is [ms]\n//! author : Weldan Jamili : https://github.com/weldan\n\nhooks.defineLocale('ms-my', {\n    months : 'Januari_Februari_Mac_April_Mei_Jun_Julai_Ogos_September_Oktober_November_Disember'.split('_'),\n    monthsShort : 'Jan_Feb_Mac_Apr_Mei_Jun_Jul_Ogs_Sep_Okt_Nov_Dis'.split('_'),\n    weekdays : 'Ahad_Isnin_Selasa_Rabu_Khamis_Jumaat_Sabtu'.split('_'),\n    weekdaysShort : 'Ahd_Isn_Sel_Rab_Kha_Jum_Sab'.split('_'),\n    weekdaysMin : 'Ah_Is_Sl_Rb_Km_Jm_Sb'.split('_'),\n    longDateFormat : {\n        LT : 'HH.mm',\n        LTS : 'HH.mm.ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY [pukul] HH.mm',\n        LLLL : 'dddd, D MMMM YYYY [pukul] HH.mm'\n    },\n    meridiemParse: /pagi|tengahari|petang|malam/,\n    meridiemHour: function (hour, meridiem) {\n        if (hour === 12) {\n            hour = 0;\n        }\n        if (meridiem === 'pagi') {\n            return hour;\n        } else if (meridiem === 'tengahari') {\n            return hour >= 11 ? hour : hour + 12;\n        } else if (meridiem === 'petang' || meridiem === 'malam') {\n            return hour + 12;\n        }\n    },\n    meridiem : function (hours, minutes, isLower) {\n        if (hours < 11) {\n            return 'pagi';\n        } else if (hours < 15) {\n            return 'tengahari';\n        } else if (hours < 19) {\n            return 'petang';\n        } else {\n            return 'malam';\n        }\n    },\n    calendar : {\n        sameDay : '[Hari ini pukul] LT',\n        nextDay : '[Esok pukul] LT',\n        nextWeek : 'dddd [pukul] LT',\n        lastDay : '[Kelmarin pukul] LT',\n        lastWeek : 'dddd [lepas pukul] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'dalam %s',\n        past : '%s yang lepas',\n        s : 'beberapa saat',\n        m : 'seminit',\n        mm : '%d minit',\n        h : 'sejam',\n        hh : '%d jam',\n        d : 'sehari',\n        dd : '%d hari',\n        M : 'sebulan',\n        MM : '%d bulan',\n        y : 'setahun',\n        yy : '%d tahun'\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 7  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Malay [ms]\n//! author : Weldan Jamili : https://github.com/weldan\n\nhooks.defineLocale('ms', {\n    months : 'Januari_Februari_Mac_April_Mei_Jun_Julai_Ogos_September_Oktober_November_Disember'.split('_'),\n    monthsShort : 'Jan_Feb_Mac_Apr_Mei_Jun_Jul_Ogs_Sep_Okt_Nov_Dis'.split('_'),\n    weekdays : 'Ahad_Isnin_Selasa_Rabu_Khamis_Jumaat_Sabtu'.split('_'),\n    weekdaysShort : 'Ahd_Isn_Sel_Rab_Kha_Jum_Sab'.split('_'),\n    weekdaysMin : 'Ah_Is_Sl_Rb_Km_Jm_Sb'.split('_'),\n    longDateFormat : {\n        LT : 'HH.mm',\n        LTS : 'HH.mm.ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY [pukul] HH.mm',\n        LLLL : 'dddd, D MMMM YYYY [pukul] HH.mm'\n    },\n    meridiemParse: /pagi|tengahari|petang|malam/,\n    meridiemHour: function (hour, meridiem) {\n        if (hour === 12) {\n            hour = 0;\n        }\n        if (meridiem === 'pagi') {\n            return hour;\n        } else if (meridiem === 'tengahari') {\n            return hour >= 11 ? hour : hour + 12;\n        } else if (meridiem === 'petang' || meridiem === 'malam') {\n            return hour + 12;\n        }\n    },\n    meridiem : function (hours, minutes, isLower) {\n        if (hours < 11) {\n            return 'pagi';\n        } else if (hours < 15) {\n            return 'tengahari';\n        } else if (hours < 19) {\n            return 'petang';\n        } else {\n            return 'malam';\n        }\n    },\n    calendar : {\n        sameDay : '[Hari ini pukul] LT',\n        nextDay : '[Esok pukul] LT',\n        nextWeek : 'dddd [pukul] LT',\n        lastDay : '[Kelmarin pukul] LT',\n        lastWeek : 'dddd [lepas pukul] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'dalam %s',\n        past : '%s yang lepas',\n        s : 'beberapa saat',\n        m : 'seminit',\n        mm : '%d minit',\n        h : 'sejam',\n        hh : '%d jam',\n        d : 'sehari',\n        dd : '%d hari',\n        M : 'sebulan',\n        MM : '%d bulan',\n        y : 'setahun',\n        yy : '%d tahun'\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 7  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Burmese [my]\n//! author : Squar team, mysquar.com\n//! author : David Rossellat : https://github.com/gholadr\n//! author : Tin Aung Lin : https://github.com/thanyawzinmin\n\nvar symbolMap$9 = {\n    '1': '၁',\n    '2': '၂',\n    '3': '၃',\n    '4': '၄',\n    '5': '၅',\n    '6': '၆',\n    '7': '၇',\n    '8': '၈',\n    '9': '၉',\n    '0': '၀'\n};\nvar numberMap$8 = {\n    '၁': '1',\n    '၂': '2',\n    '၃': '3',\n    '၄': '4',\n    '၅': '5',\n    '၆': '6',\n    '၇': '7',\n    '၈': '8',\n    '၉': '9',\n    '၀': '0'\n};\n\nhooks.defineLocale('my', {\n    months: 'ဇန်နဝါရီ_ဖေဖော်ဝါရီ_မတ်_ဧပြီ_မေ_ဇွန်_ဇူလိုင်_သြဂုတ်_စက်တင်ဘာ_အောက်တိုဘာ_နိုဝင်ဘာ_ဒီဇင်ဘာ'.split('_'),\n    monthsShort: 'ဇန်_ဖေ_မတ်_ပြီ_မေ_ဇွန်_လိုင်_သြ_စက်_အောက်_နို_ဒီ'.split('_'),\n    weekdays: 'တနင်္ဂနွေ_တနင်္လာ_အင်္ဂါ_ဗုဒ္ဓဟူး_ကြာသပတေး_သောကြာ_စနေ'.split('_'),\n    weekdaysShort: 'နွေ_လာ_ဂါ_ဟူး_ကြာ_သော_နေ'.split('_'),\n    weekdaysMin: 'နွေ_လာ_ဂါ_ဟူး_ကြာ_သော_နေ'.split('_'),\n\n    longDateFormat: {\n        LT: 'HH:mm',\n        LTS: 'HH:mm:ss',\n        L: 'DD/MM/YYYY',\n        LL: 'D MMMM YYYY',\n        LLL: 'D MMMM YYYY HH:mm',\n        LLLL: 'dddd D MMMM YYYY HH:mm'\n    },\n    calendar: {\n        sameDay: '[ယနေ.] LT [မှာ]',\n        nextDay: '[မနက်ဖြန်] LT [မှာ]',\n        nextWeek: 'dddd LT [မှာ]',\n        lastDay: '[မနေ.က] LT [မှာ]',\n        lastWeek: '[ပြီးခဲ့သော] dddd LT [မှာ]',\n        sameElse: 'L'\n    },\n    relativeTime: {\n        future: 'လာမည့် %s မှာ',\n        past: 'လွန်ခဲ့သော %s က',\n        s: 'စက္ကန်.အနည်းငယ်',\n        m: 'တစ်မိနစ်',\n        mm: '%d မိနစ်',\n        h: 'တစ်နာရီ',\n        hh: '%d နာရီ',\n        d: 'တစ်ရက်',\n        dd: '%d ရက်',\n        M: 'တစ်လ',\n        MM: '%d လ',\n        y: 'တစ်နှစ်',\n        yy: '%d နှစ်'\n    },\n    preparse: function (string) {\n        return string.replace(/[၁၂၃၄၅၆၇၈၉၀]/g, function (match) {\n            return numberMap$8[match];\n        });\n    },\n    postformat: function (string) {\n        return string.replace(/\\d/g, function (match) {\n            return symbolMap$9[match];\n        });\n    },\n    week: {\n        dow: 1, // Monday is the first day of the week.\n        doy: 4 // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Norwegian Bokmål [nb]\n//! authors : Espen Hovlandsdal : https://github.com/rexxars\n//!           Sigurd Gartmann : https://github.com/sigurdga\n\nhooks.defineLocale('nb', {\n    months : 'januar_februar_mars_april_mai_juni_juli_august_september_oktober_november_desember'.split('_'),\n    monthsShort : 'jan._feb._mars_april_mai_juni_juli_aug._sep._okt._nov._des.'.split('_'),\n    monthsParseExact : true,\n    weekdays : 'søndag_mandag_tirsdag_onsdag_torsdag_fredag_lørdag'.split('_'),\n    weekdaysShort : 'sø._ma._ti._on._to._fr._lø.'.split('_'),\n    weekdaysMin : 'sø_ma_ti_on_to_fr_lø'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD.MM.YYYY',\n        LL : 'D. MMMM YYYY',\n        LLL : 'D. MMMM YYYY [kl.] HH:mm',\n        LLLL : 'dddd D. MMMM YYYY [kl.] HH:mm'\n    },\n    calendar : {\n        sameDay: '[i dag kl.] LT',\n        nextDay: '[i morgen kl.] LT',\n        nextWeek: 'dddd [kl.] LT',\n        lastDay: '[i går kl.] LT',\n        lastWeek: '[forrige] dddd [kl.] LT',\n        sameElse: 'L'\n    },\n    relativeTime : {\n        future : 'om %s',\n        past : '%s siden',\n        s : 'noen sekunder',\n        m : 'ett minutt',\n        mm : '%d minutter',\n        h : 'en time',\n        hh : '%d timer',\n        d : 'en dag',\n        dd : '%d dager',\n        M : 'en måned',\n        MM : '%d måneder',\n        y : 'ett år',\n        yy : '%d år'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}\\./,\n    ordinal : '%d.',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Nepalese [ne]\n//! author : suvash : https://github.com/suvash\n\nvar symbolMap$10 = {\n    '1': '१',\n    '2': '२',\n    '3': '३',\n    '4': '४',\n    '5': '५',\n    '6': '६',\n    '7': '७',\n    '8': '८',\n    '9': '९',\n    '0': '०'\n};\nvar numberMap$9 = {\n    '१': '1',\n    '२': '2',\n    '३': '3',\n    '४': '4',\n    '५': '5',\n    '६': '6',\n    '७': '7',\n    '८': '8',\n    '९': '9',\n    '०': '0'\n};\n\nhooks.defineLocale('ne', {\n    months : 'जनवरी_फेब्रुवरी_मार्च_अप्रिल_मई_जुन_जुलाई_अगष्ट_सेप्टेम्बर_अक्टोबर_नोभेम्बर_डिसेम्बर'.split('_'),\n    monthsShort : 'जन._फेब्रु._मार्च_अप्रि._मई_जुन_जुलाई._अग._सेप्ट._अक्टो._नोभे._डिसे.'.split('_'),\n    monthsParseExact : true,\n    weekdays : 'आइतबार_सोमबार_मङ्गलबार_बुधबार_बिहिबार_शुक्रबार_शनिबार'.split('_'),\n    weekdaysShort : 'आइत._सोम._मङ्गल._बुध._बिहि._शुक्र._शनि.'.split('_'),\n    weekdaysMin : 'आ._सो._मं._बु._बि._शु._श.'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat : {\n        LT : 'Aको h:mm बजे',\n        LTS : 'Aको h:mm:ss बजे',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY, Aको h:mm बजे',\n        LLLL : 'dddd, D MMMM YYYY, Aको h:mm बजे'\n    },\n    preparse: function (string) {\n        return string.replace(/[१२३४५६७८९०]/g, function (match) {\n            return numberMap$9[match];\n        });\n    },\n    postformat: function (string) {\n        return string.replace(/\\d/g, function (match) {\n            return symbolMap$10[match];\n        });\n    },\n    meridiemParse: /राति|बिहान|दिउँसो|साँझ/,\n    meridiemHour : function (hour, meridiem) {\n        if (hour === 12) {\n            hour = 0;\n        }\n        if (meridiem === 'राति') {\n            return hour < 4 ? hour : hour + 12;\n        } else if (meridiem === 'बिहान') {\n            return hour;\n        } else if (meridiem === 'दिउँसो') {\n            return hour >= 10 ? hour : hour + 12;\n        } else if (meridiem === 'साँझ') {\n            return hour + 12;\n        }\n    },\n    meridiem : function (hour, minute, isLower) {\n        if (hour < 3) {\n            return 'राति';\n        } else if (hour < 12) {\n            return 'बिहान';\n        } else if (hour < 16) {\n            return 'दिउँसो';\n        } else if (hour < 20) {\n            return 'साँझ';\n        } else {\n            return 'राति';\n        }\n    },\n    calendar : {\n        sameDay : '[आज] LT',\n        nextDay : '[भोलि] LT',\n        nextWeek : '[आउँदो] dddd[,] LT',\n        lastDay : '[हिजो] LT',\n        lastWeek : '[गएको] dddd[,] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : '%sमा',\n        past : '%s अगाडि',\n        s : 'केही क्षण',\n        m : 'एक मिनेट',\n        mm : '%d मिनेट',\n        h : 'एक घण्टा',\n        hh : '%d घण्टा',\n        d : 'एक दिन',\n        dd : '%d दिन',\n        M : 'एक महिना',\n        MM : '%d महिना',\n        y : 'एक बर्ष',\n        yy : '%d बर्ष'\n    },\n    week : {\n        dow : 0, // Sunday is the first day of the week.\n        doy : 6  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Dutch (Belgium) [nl-be]\n//! author : Joris Röling : https://github.com/jorisroling\n//! author : Jacob Middag : https://github.com/middagj\n\nvar monthsShortWithDots$1 = 'jan._feb._mrt._apr._mei_jun._jul._aug._sep._okt._nov._dec.'.split('_');\nvar monthsShortWithoutDots$1 = 'jan_feb_mrt_apr_mei_jun_jul_aug_sep_okt_nov_dec'.split('_');\n\nvar monthsParse = [/^jan/i, /^feb/i, /^maart|mrt.?$/i, /^apr/i, /^mei$/i, /^jun[i.]?$/i, /^jul[i.]?$/i, /^aug/i, /^sep/i, /^okt/i, /^nov/i, /^dec/i];\nvar monthsRegex$1 = /^(januari|februari|maart|april|mei|april|ju[nl]i|augustus|september|oktober|november|december|jan\\.?|feb\\.?|mrt\\.?|apr\\.?|ju[nl]\\.?|aug\\.?|sep\\.?|okt\\.?|nov\\.?|dec\\.?)/i;\n\nhooks.defineLocale('nl-be', {\n    months : 'januari_februari_maart_april_mei_juni_juli_augustus_september_oktober_november_december'.split('_'),\n    monthsShort : function (m, format) {\n        if (!m) {\n            return monthsShortWithDots$1;\n        } else if (/-MMM-/.test(format)) {\n            return monthsShortWithoutDots$1[m.month()];\n        } else {\n            return monthsShortWithDots$1[m.month()];\n        }\n    },\n\n    monthsRegex: monthsRegex$1,\n    monthsShortRegex: monthsRegex$1,\n    monthsStrictRegex: /^(januari|februari|maart|mei|ju[nl]i|april|augustus|september|oktober|november|december)/i,\n    monthsShortStrictRegex: /^(jan\\.?|feb\\.?|mrt\\.?|apr\\.?|mei|ju[nl]\\.?|aug\\.?|sep\\.?|okt\\.?|nov\\.?|dec\\.?)/i,\n\n    monthsParse : monthsParse,\n    longMonthsParse : monthsParse,\n    shortMonthsParse : monthsParse,\n\n    weekdays : 'zondag_maandag_dinsdag_woensdag_donderdag_vrijdag_zaterdag'.split('_'),\n    weekdaysShort : 'zo._ma._di._wo._do._vr._za.'.split('_'),\n    weekdaysMin : 'Zo_Ma_Di_Wo_Do_Vr_Za'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY HH:mm',\n        LLLL : 'dddd D MMMM YYYY HH:mm'\n    },\n    calendar : {\n        sameDay: '[vandaag om] LT',\n        nextDay: '[morgen om] LT',\n        nextWeek: 'dddd [om] LT',\n        lastDay: '[gisteren om] LT',\n        lastWeek: '[afgelopen] dddd [om] LT',\n        sameElse: 'L'\n    },\n    relativeTime : {\n        future : 'over %s',\n        past : '%s geleden',\n        s : 'een paar seconden',\n        m : 'één minuut',\n        mm : '%d minuten',\n        h : 'één uur',\n        hh : '%d uur',\n        d : 'één dag',\n        dd : '%d dagen',\n        M : 'één maand',\n        MM : '%d maanden',\n        y : 'één jaar',\n        yy : '%d jaar'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}(ste|de)/,\n    ordinal : function (number) {\n        return number + ((number === 1 || number === 8 || number >= 20) ? 'ste' : 'de');\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Dutch [nl]\n//! author : Joris Röling : https://github.com/jorisroling\n//! author : Jacob Middag : https://github.com/middagj\n\nvar monthsShortWithDots$2 = 'jan._feb._mrt._apr._mei_jun._jul._aug._sep._okt._nov._dec.'.split('_');\nvar monthsShortWithoutDots$2 = 'jan_feb_mrt_apr_mei_jun_jul_aug_sep_okt_nov_dec'.split('_');\n\nvar monthsParse$1 = [/^jan/i, /^feb/i, /^maart|mrt.?$/i, /^apr/i, /^mei$/i, /^jun[i.]?$/i, /^jul[i.]?$/i, /^aug/i, /^sep/i, /^okt/i, /^nov/i, /^dec/i];\nvar monthsRegex$2 = /^(januari|februari|maart|april|mei|april|ju[nl]i|augustus|september|oktober|november|december|jan\\.?|feb\\.?|mrt\\.?|apr\\.?|ju[nl]\\.?|aug\\.?|sep\\.?|okt\\.?|nov\\.?|dec\\.?)/i;\n\nhooks.defineLocale('nl', {\n    months : 'januari_februari_maart_april_mei_juni_juli_augustus_september_oktober_november_december'.split('_'),\n    monthsShort : function (m, format) {\n        if (!m) {\n            return monthsShortWithDots$2;\n        } else if (/-MMM-/.test(format)) {\n            return monthsShortWithoutDots$2[m.month()];\n        } else {\n            return monthsShortWithDots$2[m.month()];\n        }\n    },\n\n    monthsRegex: monthsRegex$2,\n    monthsShortRegex: monthsRegex$2,\n    monthsStrictRegex: /^(januari|februari|maart|mei|ju[nl]i|april|augustus|september|oktober|november|december)/i,\n    monthsShortStrictRegex: /^(jan\\.?|feb\\.?|mrt\\.?|apr\\.?|mei|ju[nl]\\.?|aug\\.?|sep\\.?|okt\\.?|nov\\.?|dec\\.?)/i,\n\n    monthsParse : monthsParse$1,\n    longMonthsParse : monthsParse$1,\n    shortMonthsParse : monthsParse$1,\n\n    weekdays : 'zondag_maandag_dinsdag_woensdag_donderdag_vrijdag_zaterdag'.split('_'),\n    weekdaysShort : 'zo._ma._di._wo._do._vr._za.'.split('_'),\n    weekdaysMin : 'Zo_Ma_Di_Wo_Do_Vr_Za'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD-MM-YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY HH:mm',\n        LLLL : 'dddd D MMMM YYYY HH:mm'\n    },\n    calendar : {\n        sameDay: '[vandaag om] LT',\n        nextDay: '[morgen om] LT',\n        nextWeek: 'dddd [om] LT',\n        lastDay: '[gisteren om] LT',\n        lastWeek: '[afgelopen] dddd [om] LT',\n        sameElse: 'L'\n    },\n    relativeTime : {\n        future : 'over %s',\n        past : '%s geleden',\n        s : 'een paar seconden',\n        m : 'één minuut',\n        mm : '%d minuten',\n        h : 'één uur',\n        hh : '%d uur',\n        d : 'één dag',\n        dd : '%d dagen',\n        M : 'één maand',\n        MM : '%d maanden',\n        y : 'één jaar',\n        yy : '%d jaar'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}(ste|de)/,\n    ordinal : function (number) {\n        return number + ((number === 1 || number === 8 || number >= 20) ? 'ste' : 'de');\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Nynorsk [nn]\n//! author : https://github.com/mechuwind\n\nhooks.defineLocale('nn', {\n    months : 'januar_februar_mars_april_mai_juni_juli_august_september_oktober_november_desember'.split('_'),\n    monthsShort : 'jan_feb_mar_apr_mai_jun_jul_aug_sep_okt_nov_des'.split('_'),\n    weekdays : 'sundag_måndag_tysdag_onsdag_torsdag_fredag_laurdag'.split('_'),\n    weekdaysShort : 'sun_mån_tys_ons_tor_fre_lau'.split('_'),\n    weekdaysMin : 'su_må_ty_on_to_fr_lø'.split('_'),\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD.MM.YYYY',\n        LL : 'D. MMMM YYYY',\n        LLL : 'D. MMMM YYYY [kl.] H:mm',\n        LLLL : 'dddd D. MMMM YYYY [kl.] HH:mm'\n    },\n    calendar : {\n        sameDay: '[I dag klokka] LT',\n        nextDay: '[I morgon klokka] LT',\n        nextWeek: 'dddd [klokka] LT',\n        lastDay: '[I går klokka] LT',\n        lastWeek: '[Føregåande] dddd [klokka] LT',\n        sameElse: 'L'\n    },\n    relativeTime : {\n        future : 'om %s',\n        past : '%s sidan',\n        s : 'nokre sekund',\n        m : 'eit minutt',\n        mm : '%d minutt',\n        h : 'ein time',\n        hh : '%d timar',\n        d : 'ein dag',\n        dd : '%d dagar',\n        M : 'ein månad',\n        MM : '%d månader',\n        y : 'eit år',\n        yy : '%d år'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}\\./,\n    ordinal : '%d.',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Punjabi (India) [pa-in]\n//! author : Harpreet Singh : https://github.com/harpreetkhalsagtbit\n\nvar symbolMap$11 = {\n    '1': '੧',\n    '2': '੨',\n    '3': '੩',\n    '4': '੪',\n    '5': '੫',\n    '6': '੬',\n    '7': '੭',\n    '8': '੮',\n    '9': '੯',\n    '0': '੦'\n};\nvar numberMap$10 = {\n    '੧': '1',\n    '੨': '2',\n    '੩': '3',\n    '੪': '4',\n    '੫': '5',\n    '੬': '6',\n    '੭': '7',\n    '੮': '8',\n    '੯': '9',\n    '੦': '0'\n};\n\nhooks.defineLocale('pa-in', {\n    // There are months name as per Nanakshahi Calender but they are not used as rigidly in modern Punjabi.\n    months : 'ਜਨਵਰੀ_ਫ਼ਰਵਰੀ_ਮਾਰਚ_ਅਪ੍ਰੈਲ_ਮਈ_ਜੂਨ_ਜੁਲਾਈ_ਅਗਸਤ_ਸਤੰਬਰ_ਅਕਤੂਬਰ_ਨਵੰਬਰ_ਦਸੰਬਰ'.split('_'),\n    monthsShort : 'ਜਨਵਰੀ_ਫ਼ਰਵਰੀ_ਮਾਰਚ_ਅਪ੍ਰੈਲ_ਮਈ_ਜੂਨ_ਜੁਲਾਈ_ਅਗਸਤ_ਸਤੰਬਰ_ਅਕਤੂਬਰ_ਨਵੰਬਰ_ਦਸੰਬਰ'.split('_'),\n    weekdays : 'ਐਤਵਾਰ_ਸੋਮਵਾਰ_ਮੰਗਲਵਾਰ_ਬੁਧਵਾਰ_ਵੀਰਵਾਰ_ਸ਼ੁੱਕਰਵਾਰ_ਸ਼ਨੀਚਰਵਾਰ'.split('_'),\n    weekdaysShort : 'ਐਤ_ਸੋਮ_ਮੰਗਲ_ਬੁਧ_ਵੀਰ_ਸ਼ੁਕਰ_ਸ਼ਨੀ'.split('_'),\n    weekdaysMin : 'ਐਤ_ਸੋਮ_ਮੰਗਲ_ਬੁਧ_ਵੀਰ_ਸ਼ੁਕਰ_ਸ਼ਨੀ'.split('_'),\n    longDateFormat : {\n        LT : 'A h:mm ਵਜੇ',\n        LTS : 'A h:mm:ss ਵਜੇ',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY, A h:mm ਵਜੇ',\n        LLLL : 'dddd, D MMMM YYYY, A h:mm ਵਜੇ'\n    },\n    calendar : {\n        sameDay : '[ਅਜ] LT',\n        nextDay : '[ਕਲ] LT',\n        nextWeek : 'dddd, LT',\n        lastDay : '[ਕਲ] LT',\n        lastWeek : '[ਪਿਛਲੇ] dddd, LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : '%s ਵਿੱਚ',\n        past : '%s ਪਿਛਲੇ',\n        s : 'ਕੁਝ ਸਕਿੰਟ',\n        m : 'ਇਕ ਮਿੰਟ',\n        mm : '%d ਮਿੰਟ',\n        h : 'ਇੱਕ ਘੰਟਾ',\n        hh : '%d ਘੰਟੇ',\n        d : 'ਇੱਕ ਦਿਨ',\n        dd : '%d ਦਿਨ',\n        M : 'ਇੱਕ ਮਹੀਨਾ',\n        MM : '%d ਮਹੀਨੇ',\n        y : 'ਇੱਕ ਸਾਲ',\n        yy : '%d ਸਾਲ'\n    },\n    preparse: function (string) {\n        return string.replace(/[੧੨੩੪੫੬੭੮੯੦]/g, function (match) {\n            return numberMap$10[match];\n        });\n    },\n    postformat: function (string) {\n        return string.replace(/\\d/g, function (match) {\n            return symbolMap$11[match];\n        });\n    },\n    // Punjabi notation for meridiems are quite fuzzy in practice. While there exists\n    // a rigid notion of a 'Pahar' it is not used as rigidly in modern Punjabi.\n    meridiemParse: /ਰਾਤ|ਸਵੇਰ|ਦੁਪਹਿਰ|ਸ਼ਾਮ/,\n    meridiemHour : function (hour, meridiem) {\n        if (hour === 12) {\n            hour = 0;\n        }\n        if (meridiem === 'ਰਾਤ') {\n            return hour < 4 ? hour : hour + 12;\n        } else if (meridiem === 'ਸਵੇਰ') {\n            return hour;\n        } else if (meridiem === 'ਦੁਪਹਿਰ') {\n            return hour >= 10 ? hour : hour + 12;\n        } else if (meridiem === 'ਸ਼ਾਮ') {\n            return hour + 12;\n        }\n    },\n    meridiem : function (hour, minute, isLower) {\n        if (hour < 4) {\n            return 'ਰਾਤ';\n        } else if (hour < 10) {\n            return 'ਸਵੇਰ';\n        } else if (hour < 17) {\n            return 'ਦੁਪਹਿਰ';\n        } else if (hour < 20) {\n            return 'ਸ਼ਾਮ';\n        } else {\n            return 'ਰਾਤ';\n        }\n    },\n    week : {\n        dow : 0, // Sunday is the first day of the week.\n        doy : 6  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Polish [pl]\n//! author : Rafal Hirsz : https://github.com/evoL\n\nvar monthsNominative = 'styczeń_luty_marzec_kwiecień_maj_czerwiec_lipiec_sierpień_wrzesień_październik_listopad_grudzień'.split('_');\nvar monthsSubjective = 'stycznia_lutego_marca_kwietnia_maja_czerwca_lipca_sierpnia_września_października_listopada_grudnia'.split('_');\nfunction plural$3(n) {\n    return (n % 10 < 5) && (n % 10 > 1) && ((~~(n / 10) % 10) !== 1);\n}\nfunction translate$7(number, withoutSuffix, key) {\n    var result = number + ' ';\n    switch (key) {\n        case 'm':\n            return withoutSuffix ? 'minuta' : 'minutę';\n        case 'mm':\n            return result + (plural$3(number) ? 'minuty' : 'minut');\n        case 'h':\n            return withoutSuffix  ? 'godzina'  : 'godzinę';\n        case 'hh':\n            return result + (plural$3(number) ? 'godziny' : 'godzin');\n        case 'MM':\n            return result + (plural$3(number) ? 'miesiące' : 'miesięcy');\n        case 'yy':\n            return result + (plural$3(number) ? 'lata' : 'lat');\n    }\n}\n\nhooks.defineLocale('pl', {\n    months : function (momentToFormat, format) {\n        if (!momentToFormat) {\n            return monthsNominative;\n        } else if (format === '') {\n            // Hack: if format empty we know this is used to generate\n            // RegExp by moment. Give then back both valid forms of months\n            // in RegExp ready format.\n            return '(' + monthsSubjective[momentToFormat.month()] + '|' + monthsNominative[momentToFormat.month()] + ')';\n        } else if (/D MMMM/.test(format)) {\n            return monthsSubjective[momentToFormat.month()];\n        } else {\n            return monthsNominative[momentToFormat.month()];\n        }\n    },\n    monthsShort : 'sty_lut_mar_kwi_maj_cze_lip_sie_wrz_paź_lis_gru'.split('_'),\n    weekdays : 'niedziela_poniedziałek_wtorek_środa_czwartek_piątek_sobota'.split('_'),\n    weekdaysShort : 'ndz_pon_wt_śr_czw_pt_sob'.split('_'),\n    weekdaysMin : 'Nd_Pn_Wt_Śr_Cz_Pt_So'.split('_'),\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD.MM.YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY HH:mm',\n        LLLL : 'dddd, D MMMM YYYY HH:mm'\n    },\n    calendar : {\n        sameDay: '[Dziś o] LT',\n        nextDay: '[Jutro o] LT',\n        nextWeek: '[W] dddd [o] LT',\n        lastDay: '[Wczoraj o] LT',\n        lastWeek: function () {\n            switch (this.day()) {\n                case 0:\n                    return '[W zeszłą niedzielę o] LT';\n                case 3:\n                    return '[W zeszłą środę o] LT';\n                case 6:\n                    return '[W zeszłą sobotę o] LT';\n                default:\n                    return '[W zeszły] dddd [o] LT';\n            }\n        },\n        sameElse: 'L'\n    },\n    relativeTime : {\n        future : 'za %s',\n        past : '%s temu',\n        s : 'kilka sekund',\n        m : translate$7,\n        mm : translate$7,\n        h : translate$7,\n        hh : translate$7,\n        d : '1 dzień',\n        dd : '%d dni',\n        M : 'miesiąc',\n        MM : translate$7,\n        y : 'rok',\n        yy : translate$7\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}\\./,\n    ordinal : '%d.',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Portuguese (Brazil) [pt-br]\n//! author : Caio Ribeiro Pereira : https://github.com/caio-ribeiro-pereira\n\nhooks.defineLocale('pt-br', {\n    months : 'Janeiro_Fevereiro_Março_Abril_Maio_Junho_Julho_Agosto_Setembro_Outubro_Novembro_Dezembro'.split('_'),\n    monthsShort : 'Jan_Fev_Mar_Abr_Mai_Jun_Jul_Ago_Set_Out_Nov_Dez'.split('_'),\n    weekdays : 'Domingo_Segunda-feira_Terça-feira_Quarta-feira_Quinta-feira_Sexta-feira_Sábado'.split('_'),\n    weekdaysShort : 'Dom_Seg_Ter_Qua_Qui_Sex_Sáb'.split('_'),\n    weekdaysMin : 'Do_2ª_3ª_4ª_5ª_6ª_Sá'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D [de] MMMM [de] YYYY',\n        LLL : 'D [de] MMMM [de] YYYY [às] HH:mm',\n        LLLL : 'dddd, D [de] MMMM [de] YYYY [às] HH:mm'\n    },\n    calendar : {\n        sameDay: '[Hoje às] LT',\n        nextDay: '[Amanhã às] LT',\n        nextWeek: 'dddd [às] LT',\n        lastDay: '[Ontem às] LT',\n        lastWeek: function () {\n            return (this.day() === 0 || this.day() === 6) ?\n                '[Último] dddd [às] LT' : // Saturday + Sunday\n                '[Última] dddd [às] LT'; // Monday - Friday\n        },\n        sameElse: 'L'\n    },\n    relativeTime : {\n        future : 'em %s',\n        past : '%s atrás',\n        s : 'poucos segundos',\n        m : 'um minuto',\n        mm : '%d minutos',\n        h : 'uma hora',\n        hh : '%d horas',\n        d : 'um dia',\n        dd : '%d dias',\n        M : 'um mês',\n        MM : '%d meses',\n        y : 'um ano',\n        yy : '%d anos'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}º/,\n    ordinal : '%dº'\n});\n\n//! moment.js locale configuration\n//! locale : Portuguese [pt]\n//! author : Jefferson : https://github.com/jalex79\n\nhooks.defineLocale('pt', {\n    months : 'Janeiro_Fevereiro_Março_Abril_Maio_Junho_Julho_Agosto_Setembro_Outubro_Novembro_Dezembro'.split('_'),\n    monthsShort : 'Jan_Fev_Mar_Abr_Mai_Jun_Jul_Ago_Set_Out_Nov_Dez'.split('_'),\n    weekdays : 'Domingo_Segunda-Feira_Terça-Feira_Quarta-Feira_Quinta-Feira_Sexta-Feira_Sábado'.split('_'),\n    weekdaysShort : 'Dom_Seg_Ter_Qua_Qui_Sex_Sáb'.split('_'),\n    weekdaysMin : 'Do_2ª_3ª_4ª_5ª_6ª_Sá'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D [de] MMMM [de] YYYY',\n        LLL : 'D [de] MMMM [de] YYYY HH:mm',\n        LLLL : 'dddd, D [de] MMMM [de] YYYY HH:mm'\n    },\n    calendar : {\n        sameDay: '[Hoje às] LT',\n        nextDay: '[Amanhã às] LT',\n        nextWeek: 'dddd [às] LT',\n        lastDay: '[Ontem às] LT',\n        lastWeek: function () {\n            return (this.day() === 0 || this.day() === 6) ?\n                '[Último] dddd [às] LT' : // Saturday + Sunday\n                '[Última] dddd [às] LT'; // Monday - Friday\n        },\n        sameElse: 'L'\n    },\n    relativeTime : {\n        future : 'em %s',\n        past : 'há %s',\n        s : 'segundos',\n        m : 'um minuto',\n        mm : '%d minutos',\n        h : 'uma hora',\n        hh : '%d horas',\n        d : 'um dia',\n        dd : '%d dias',\n        M : 'um mês',\n        MM : '%d meses',\n        y : 'um ano',\n        yy : '%d anos'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}º/,\n    ordinal : '%dº',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Romanian [ro]\n//! author : Vlad Gurdiga : https://github.com/gurdiga\n//! author : Valentin Agachi : https://github.com/avaly\n\nfunction relativeTimeWithPlural$2(number, withoutSuffix, key) {\n    var format = {\n            'mm': 'minute',\n            'hh': 'ore',\n            'dd': 'zile',\n            'MM': 'luni',\n            'yy': 'ani'\n        },\n        separator = ' ';\n    if (number % 100 >= 20 || (number >= 100 && number % 100 === 0)) {\n        separator = ' de ';\n    }\n    return number + separator + format[key];\n}\n\nhooks.defineLocale('ro', {\n    months : 'ianuarie_februarie_martie_aprilie_mai_iunie_iulie_august_septembrie_octombrie_noiembrie_decembrie'.split('_'),\n    monthsShort : 'ian._febr._mart._apr._mai_iun._iul._aug._sept._oct._nov._dec.'.split('_'),\n    monthsParseExact: true,\n    weekdays : 'duminică_luni_marți_miercuri_joi_vineri_sâmbătă'.split('_'),\n    weekdaysShort : 'Dum_Lun_Mar_Mie_Joi_Vin_Sâm'.split('_'),\n    weekdaysMin : 'Du_Lu_Ma_Mi_Jo_Vi_Sâ'.split('_'),\n    longDateFormat : {\n        LT : 'H:mm',\n        LTS : 'H:mm:ss',\n        L : 'DD.MM.YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY H:mm',\n        LLLL : 'dddd, D MMMM YYYY H:mm'\n    },\n    calendar : {\n        sameDay: '[azi la] LT',\n        nextDay: '[mâine la] LT',\n        nextWeek: 'dddd [la] LT',\n        lastDay: '[ieri la] LT',\n        lastWeek: '[fosta] dddd [la] LT',\n        sameElse: 'L'\n    },\n    relativeTime : {\n        future : 'peste %s',\n        past : '%s în urmă',\n        s : 'câteva secunde',\n        m : 'un minut',\n        mm : relativeTimeWithPlural$2,\n        h : 'o oră',\n        hh : relativeTimeWithPlural$2,\n        d : 'o zi',\n        dd : relativeTimeWithPlural$2,\n        M : 'o lună',\n        MM : relativeTimeWithPlural$2,\n        y : 'un an',\n        yy : relativeTimeWithPlural$2\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 7  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Russian [ru]\n//! author : Viktorminator : https://github.com/Viktorminator\n//! Author : Menelion Elensúle : https://github.com/Oire\n//! author : Коренберг Марк : https://github.com/socketpair\n\nfunction plural$4(word, num) {\n    var forms = word.split('_');\n    return num % 10 === 1 && num % 100 !== 11 ? forms[0] : (num % 10 >= 2 && num % 10 <= 4 && (num % 100 < 10 || num % 100 >= 20) ? forms[1] : forms[2]);\n}\nfunction relativeTimeWithPlural$3(number, withoutSuffix, key) {\n    var format = {\n        'mm': withoutSuffix ? 'минута_минуты_минут' : 'минуту_минуты_минут',\n        'hh': 'час_часа_часов',\n        'dd': 'день_дня_дней',\n        'MM': 'месяц_месяца_месяцев',\n        'yy': 'год_года_лет'\n    };\n    if (key === 'm') {\n        return withoutSuffix ? 'минута' : 'минуту';\n    }\n    else {\n        return number + ' ' + plural$4(format[key], +number);\n    }\n}\nvar monthsParse$2 = [/^янв/i, /^фев/i, /^мар/i, /^апр/i, /^ма[йя]/i, /^июн/i, /^июл/i, /^авг/i, /^сен/i, /^окт/i, /^ноя/i, /^дек/i];\n\n// http://new.gramota.ru/spravka/rules/139-prop : § 103\n// Сокращения месяцев: http://new.gramota.ru/spravka/buro/search-answer?s=242637\n// CLDR data:          http://www.unicode.org/cldr/charts/28/summary/ru.html#1753\nhooks.defineLocale('ru', {\n    months : {\n        format: 'января_февраля_марта_апреля_мая_июня_июля_августа_сентября_октября_ноября_декабря'.split('_'),\n        standalone: 'январь_февраль_март_апрель_май_июнь_июль_август_сентябрь_октябрь_ноябрь_декабрь'.split('_')\n    },\n    monthsShort : {\n        // по CLDR именно \"июл.\" и \"июн.\", но какой смысл менять букву на точку ?\n        format: 'янв._февр._мар._апр._мая_июня_июля_авг._сент._окт._нояб._дек.'.split('_'),\n        standalone: 'янв._февр._март_апр._май_июнь_июль_авг._сент._окт._нояб._дек.'.split('_')\n    },\n    weekdays : {\n        standalone: 'воскресенье_понедельник_вторник_среда_четверг_пятница_суббота'.split('_'),\n        format: 'воскресенье_понедельник_вторник_среду_четверг_пятницу_субботу'.split('_'),\n        isFormat: /\\[ ?[Вв] ?(?:прошлую|следующую|эту)? ?\\] ?dddd/\n    },\n    weekdaysShort : 'вс_пн_вт_ср_чт_пт_сб'.split('_'),\n    weekdaysMin : 'вс_пн_вт_ср_чт_пт_сб'.split('_'),\n    monthsParse : monthsParse$2,\n    longMonthsParse : monthsParse$2,\n    shortMonthsParse : monthsParse$2,\n\n    // полные названия с падежами, по три буквы, для некоторых, по 4 буквы, сокращения с точкой и без точки\n    monthsRegex: /^(январ[ья]|янв\\.?|феврал[ья]|февр?\\.?|марта?|мар\\.?|апрел[ья]|апр\\.?|ма[йя]|июн[ья]|июн\\.?|июл[ья]|июл\\.?|августа?|авг\\.?|сентябр[ья]|сент?\\.?|октябр[ья]|окт\\.?|ноябр[ья]|нояб?\\.?|декабр[ья]|дек\\.?)/i,\n\n    // копия предыдущего\n    monthsShortRegex: /^(январ[ья]|янв\\.?|феврал[ья]|февр?\\.?|марта?|мар\\.?|апрел[ья]|апр\\.?|ма[йя]|июн[ья]|июн\\.?|июл[ья]|июл\\.?|августа?|авг\\.?|сентябр[ья]|сент?\\.?|октябр[ья]|окт\\.?|ноябр[ья]|нояб?\\.?|декабр[ья]|дек\\.?)/i,\n\n    // полные названия с падежами\n    monthsStrictRegex: /^(январ[яь]|феврал[яь]|марта?|апрел[яь]|ма[яй]|июн[яь]|июл[яь]|августа?|сентябр[яь]|октябр[яь]|ноябр[яь]|декабр[яь])/i,\n\n    // Выражение, которое соотвествует только сокращённым формам\n    monthsShortStrictRegex: /^(янв\\.|февр?\\.|мар[т.]|апр\\.|ма[яй]|июн[ья.]|июл[ья.]|авг\\.|сент?\\.|окт\\.|нояб?\\.|дек\\.)/i,\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD.MM.YYYY',\n        LL : 'D MMMM YYYY г.',\n        LLL : 'D MMMM YYYY г., HH:mm',\n        LLLL : 'dddd, D MMMM YYYY г., HH:mm'\n    },\n    calendar : {\n        sameDay: '[Сегодня в] LT',\n        nextDay: '[Завтра в] LT',\n        lastDay: '[Вчера в] LT',\n        nextWeek: function (now) {\n            if (now.week() !== this.week()) {\n                switch (this.day()) {\n                    case 0:\n                        return '[В следующее] dddd [в] LT';\n                    case 1:\n                    case 2:\n                    case 4:\n                        return '[В следующий] dddd [в] LT';\n                    case 3:\n                    case 5:\n                    case 6:\n                        return '[В следующую] dddd [в] LT';\n                }\n            } else {\n                if (this.day() === 2) {\n                    return '[Во] dddd [в] LT';\n                } else {\n                    return '[В] dddd [в] LT';\n                }\n            }\n        },\n        lastWeek: function (now) {\n            if (now.week() !== this.week()) {\n                switch (this.day()) {\n                    case 0:\n                        return '[В прошлое] dddd [в] LT';\n                    case 1:\n                    case 2:\n                    case 4:\n                        return '[В прошлый] dddd [в] LT';\n                    case 3:\n                    case 5:\n                    case 6:\n                        return '[В прошлую] dddd [в] LT';\n                }\n            } else {\n                if (this.day() === 2) {\n                    return '[Во] dddd [в] LT';\n                } else {\n                    return '[В] dddd [в] LT';\n                }\n            }\n        },\n        sameElse: 'L'\n    },\n    relativeTime : {\n        future : 'через %s',\n        past : '%s назад',\n        s : 'несколько секунд',\n        m : relativeTimeWithPlural$3,\n        mm : relativeTimeWithPlural$3,\n        h : 'час',\n        hh : relativeTimeWithPlural$3,\n        d : 'день',\n        dd : relativeTimeWithPlural$3,\n        M : 'месяц',\n        MM : relativeTimeWithPlural$3,\n        y : 'год',\n        yy : relativeTimeWithPlural$3\n    },\n    meridiemParse: /ночи|утра|дня|вечера/i,\n    isPM : function (input) {\n        return /^(дня|вечера)$/.test(input);\n    },\n    meridiem : function (hour, minute, isLower) {\n        if (hour < 4) {\n            return 'ночи';\n        } else if (hour < 12) {\n            return 'утра';\n        } else if (hour < 17) {\n            return 'дня';\n        } else {\n            return 'вечера';\n        }\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}-(й|го|я)/,\n    ordinal: function (number, period) {\n        switch (period) {\n            case 'M':\n            case 'd':\n            case 'DDD':\n                return number + '-й';\n            case 'D':\n                return number + '-го';\n            case 'w':\n            case 'W':\n                return number + '-я';\n            default:\n                return number;\n        }\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 7  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Sindhi [sd]\n//! author : Narain Sagar : https://github.com/narainsagar\n\nvar months$6 = [\n    'جنوري',\n    'فيبروري',\n    'مارچ',\n    'اپريل',\n    'مئي',\n    'جون',\n    'جولاءِ',\n    'آگسٽ',\n    'سيپٽمبر',\n    'آڪٽوبر',\n    'نومبر',\n    'ڊسمبر'\n];\nvar days$1 = [\n    'آچر',\n    'سومر',\n    'اڱارو',\n    'اربع',\n    'خميس',\n    'جمع',\n    'ڇنڇر'\n];\n\nhooks.defineLocale('sd', {\n    months : months$6,\n    monthsShort : months$6,\n    weekdays : days$1,\n    weekdaysShort : days$1,\n    weekdaysMin : days$1,\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY HH:mm',\n        LLLL : 'dddd، D MMMM YYYY HH:mm'\n    },\n    meridiemParse: /صبح|شام/,\n    isPM : function (input) {\n        return 'شام' === input;\n    },\n    meridiem : function (hour, minute, isLower) {\n        if (hour < 12) {\n            return 'صبح';\n        }\n        return 'شام';\n    },\n    calendar : {\n        sameDay : '[اڄ] LT',\n        nextDay : '[سڀاڻي] LT',\n        nextWeek : 'dddd [اڳين هفتي تي] LT',\n        lastDay : '[ڪالهه] LT',\n        lastWeek : '[گزريل هفتي] dddd [تي] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : '%s پوء',\n        past : '%s اڳ',\n        s : 'چند سيڪنڊ',\n        m : 'هڪ منٽ',\n        mm : '%d منٽ',\n        h : 'هڪ ڪلاڪ',\n        hh : '%d ڪلاڪ',\n        d : 'هڪ ڏينهن',\n        dd : '%d ڏينهن',\n        M : 'هڪ مهينو',\n        MM : '%d مهينا',\n        y : 'هڪ سال',\n        yy : '%d سال'\n    },\n    preparse: function (string) {\n        return string.replace(/،/g, ',');\n    },\n    postformat: function (string) {\n        return string.replace(/,/g, '،');\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Northern Sami [se]\n//! authors : Bård Rolstad Henriksen : https://github.com/karamell\n\n\nhooks.defineLocale('se', {\n    months : 'ođđajagemánnu_guovvamánnu_njukčamánnu_cuoŋománnu_miessemánnu_geassemánnu_suoidnemánnu_borgemánnu_čakčamánnu_golggotmánnu_skábmamánnu_juovlamánnu'.split('_'),\n    monthsShort : 'ođđj_guov_njuk_cuo_mies_geas_suoi_borg_čakč_golg_skáb_juov'.split('_'),\n    weekdays : 'sotnabeaivi_vuossárga_maŋŋebárga_gaskavahkku_duorastat_bearjadat_lávvardat'.split('_'),\n    weekdaysShort : 'sotn_vuos_maŋ_gask_duor_bear_láv'.split('_'),\n    weekdaysMin : 's_v_m_g_d_b_L'.split('_'),\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD.MM.YYYY',\n        LL : 'MMMM D. [b.] YYYY',\n        LLL : 'MMMM D. [b.] YYYY [ti.] HH:mm',\n        LLLL : 'dddd, MMMM D. [b.] YYYY [ti.] HH:mm'\n    },\n    calendar : {\n        sameDay: '[otne ti] LT',\n        nextDay: '[ihttin ti] LT',\n        nextWeek: 'dddd [ti] LT',\n        lastDay: '[ikte ti] LT',\n        lastWeek: '[ovddit] dddd [ti] LT',\n        sameElse: 'L'\n    },\n    relativeTime : {\n        future : '%s geažes',\n        past : 'maŋit %s',\n        s : 'moadde sekunddat',\n        m : 'okta minuhta',\n        mm : '%d minuhtat',\n        h : 'okta diimmu',\n        hh : '%d diimmut',\n        d : 'okta beaivi',\n        dd : '%d beaivvit',\n        M : 'okta mánnu',\n        MM : '%d mánut',\n        y : 'okta jahki',\n        yy : '%d jagit'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}\\./,\n    ordinal : '%d.',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Sinhalese [si]\n//! author : Sampath Sitinamaluwa : https://github.com/sampathsris\n\n/*jshint -W100*/\nhooks.defineLocale('si', {\n    months : 'ජනවාරි_පෙබරවාරි_මාර්තු_අප්‍රේල්_මැයි_ජූනි_ජූලි_අගෝස්තු_සැප්තැම්බර්_ඔක්තෝබර්_නොවැම්බර්_දෙසැම්බර්'.split('_'),\n    monthsShort : 'ජන_පෙබ_මාර්_අප්_මැයි_ජූනි_ජූලි_අගෝ_සැප්_ඔක්_නොවැ_දෙසැ'.split('_'),\n    weekdays : 'ඉරිදා_සඳුදා_අඟහරුවාදා_බදාදා_බ්‍රහස්පතින්දා_සිකුරාදා_සෙනසුරාදා'.split('_'),\n    weekdaysShort : 'ඉරි_සඳු_අඟ_බදා_බ්‍රහ_සිකු_සෙන'.split('_'),\n    weekdaysMin : 'ඉ_ස_අ_බ_බ්‍ර_සි_සෙ'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat : {\n        LT : 'a h:mm',\n        LTS : 'a h:mm:ss',\n        L : 'YYYY/MM/DD',\n        LL : 'YYYY MMMM D',\n        LLL : 'YYYY MMMM D, a h:mm',\n        LLLL : 'YYYY MMMM D [වැනි] dddd, a h:mm:ss'\n    },\n    calendar : {\n        sameDay : '[අද] LT[ට]',\n        nextDay : '[හෙට] LT[ට]',\n        nextWeek : 'dddd LT[ට]',\n        lastDay : '[ඊයේ] LT[ට]',\n        lastWeek : '[පසුගිය] dddd LT[ට]',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : '%sකින්',\n        past : '%sකට පෙර',\n        s : 'තත්පර කිහිපය',\n        m : 'මිනිත්තුව',\n        mm : 'මිනිත්තු %d',\n        h : 'පැය',\n        hh : 'පැය %d',\n        d : 'දිනය',\n        dd : 'දින %d',\n        M : 'මාසය',\n        MM : 'මාස %d',\n        y : 'වසර',\n        yy : 'වසර %d'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2} වැනි/,\n    ordinal : function (number) {\n        return number + ' වැනි';\n    },\n    meridiemParse : /පෙර වරු|පස් වරු|පෙ.ව|ප.ව./,\n    isPM : function (input) {\n        return input === 'ප.ව.' || input === 'පස් වරු';\n    },\n    meridiem : function (hours, minutes, isLower) {\n        if (hours > 11) {\n            return isLower ? 'ප.ව.' : 'පස් වරු';\n        } else {\n            return isLower ? 'පෙ.ව.' : 'පෙර වරු';\n        }\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Slovak [sk]\n//! author : Martin Minka : https://github.com/k2s\n//! based on work of petrbela : https://github.com/petrbela\n\nvar months$7 = 'január_február_marec_apríl_máj_jún_júl_august_september_október_november_december'.split('_');\nvar monthsShort$4 = 'jan_feb_mar_apr_máj_jún_júl_aug_sep_okt_nov_dec'.split('_');\nfunction plural$5(n) {\n    return (n > 1) && (n < 5);\n}\nfunction translate$8(number, withoutSuffix, key, isFuture) {\n    var result = number + ' ';\n    switch (key) {\n        case 's':  // a few seconds / in a few seconds / a few seconds ago\n            return (withoutSuffix || isFuture) ? 'pár sekúnd' : 'pár sekundami';\n        case 'm':  // a minute / in a minute / a minute ago\n            return withoutSuffix ? 'minúta' : (isFuture ? 'minútu' : 'minútou');\n        case 'mm': // 9 minutes / in 9 minutes / 9 minutes ago\n            if (withoutSuffix || isFuture) {\n                return result + (plural$5(number) ? 'minúty' : 'minút');\n            } else {\n                return result + 'minútami';\n            }\n            break;\n        case 'h':  // an hour / in an hour / an hour ago\n            return withoutSuffix ? 'hodina' : (isFuture ? 'hodinu' : 'hodinou');\n        case 'hh': // 9 hours / in 9 hours / 9 hours ago\n            if (withoutSuffix || isFuture) {\n                return result + (plural$5(number) ? 'hodiny' : 'hodín');\n            } else {\n                return result + 'hodinami';\n            }\n            break;\n        case 'd':  // a day / in a day / a day ago\n            return (withoutSuffix || isFuture) ? 'deň' : 'dňom';\n        case 'dd': // 9 days / in 9 days / 9 days ago\n            if (withoutSuffix || isFuture) {\n                return result + (plural$5(number) ? 'dni' : 'dní');\n            } else {\n                return result + 'dňami';\n            }\n            break;\n        case 'M':  // a month / in a month / a month ago\n            return (withoutSuffix || isFuture) ? 'mesiac' : 'mesiacom';\n        case 'MM': // 9 months / in 9 months / 9 months ago\n            if (withoutSuffix || isFuture) {\n                return result + (plural$5(number) ? 'mesiace' : 'mesiacov');\n            } else {\n                return result + 'mesiacmi';\n            }\n            break;\n        case 'y':  // a year / in a year / a year ago\n            return (withoutSuffix || isFuture) ? 'rok' : 'rokom';\n        case 'yy': // 9 years / in 9 years / 9 years ago\n            if (withoutSuffix || isFuture) {\n                return result + (plural$5(number) ? 'roky' : 'rokov');\n            } else {\n                return result + 'rokmi';\n            }\n            break;\n    }\n}\n\nhooks.defineLocale('sk', {\n    months : months$7,\n    monthsShort : monthsShort$4,\n    weekdays : 'nedeľa_pondelok_utorok_streda_štvrtok_piatok_sobota'.split('_'),\n    weekdaysShort : 'ne_po_ut_st_št_pi_so'.split('_'),\n    weekdaysMin : 'ne_po_ut_st_št_pi_so'.split('_'),\n    longDateFormat : {\n        LT: 'H:mm',\n        LTS : 'H:mm:ss',\n        L : 'DD.MM.YYYY',\n        LL : 'D. MMMM YYYY',\n        LLL : 'D. MMMM YYYY H:mm',\n        LLLL : 'dddd D. MMMM YYYY H:mm'\n    },\n    calendar : {\n        sameDay: '[dnes o] LT',\n        nextDay: '[zajtra o] LT',\n        nextWeek: function () {\n            switch (this.day()) {\n                case 0:\n                    return '[v nedeľu o] LT';\n                case 1:\n                case 2:\n                    return '[v] dddd [o] LT';\n                case 3:\n                    return '[v stredu o] LT';\n                case 4:\n                    return '[vo štvrtok o] LT';\n                case 5:\n                    return '[v piatok o] LT';\n                case 6:\n                    return '[v sobotu o] LT';\n            }\n        },\n        lastDay: '[včera o] LT',\n        lastWeek: function () {\n            switch (this.day()) {\n                case 0:\n                    return '[minulú nedeľu o] LT';\n                case 1:\n                case 2:\n                    return '[minulý] dddd [o] LT';\n                case 3:\n                    return '[minulú stredu o] LT';\n                case 4:\n                case 5:\n                    return '[minulý] dddd [o] LT';\n                case 6:\n                    return '[minulú sobotu o] LT';\n            }\n        },\n        sameElse: 'L'\n    },\n    relativeTime : {\n        future : 'za %s',\n        past : 'pred %s',\n        s : translate$8,\n        m : translate$8,\n        mm : translate$8,\n        h : translate$8,\n        hh : translate$8,\n        d : translate$8,\n        dd : translate$8,\n        M : translate$8,\n        MM : translate$8,\n        y : translate$8,\n        yy : translate$8\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}\\./,\n    ordinal : '%d.',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Slovenian [sl]\n//! author : Robert Sedovšek : https://github.com/sedovsek\n\nfunction processRelativeTime$6(number, withoutSuffix, key, isFuture) {\n    var result = number + ' ';\n    switch (key) {\n        case 's':\n            return withoutSuffix || isFuture ? 'nekaj sekund' : 'nekaj sekundami';\n        case 'm':\n            return withoutSuffix ? 'ena minuta' : 'eno minuto';\n        case 'mm':\n            if (number === 1) {\n                result += withoutSuffix ? 'minuta' : 'minuto';\n            } else if (number === 2) {\n                result += withoutSuffix || isFuture ? 'minuti' : 'minutama';\n            } else if (number < 5) {\n                result += withoutSuffix || isFuture ? 'minute' : 'minutami';\n            } else {\n                result += withoutSuffix || isFuture ? 'minut' : 'minutami';\n            }\n            return result;\n        case 'h':\n            return withoutSuffix ? 'ena ura' : 'eno uro';\n        case 'hh':\n            if (number === 1) {\n                result += withoutSuffix ? 'ura' : 'uro';\n            } else if (number === 2) {\n                result += withoutSuffix || isFuture ? 'uri' : 'urama';\n            } else if (number < 5) {\n                result += withoutSuffix || isFuture ? 'ure' : 'urami';\n            } else {\n                result += withoutSuffix || isFuture ? 'ur' : 'urami';\n            }\n            return result;\n        case 'd':\n            return withoutSuffix || isFuture ? 'en dan' : 'enim dnem';\n        case 'dd':\n            if (number === 1) {\n                result += withoutSuffix || isFuture ? 'dan' : 'dnem';\n            } else if (number === 2) {\n                result += withoutSuffix || isFuture ? 'dni' : 'dnevoma';\n            } else {\n                result += withoutSuffix || isFuture ? 'dni' : 'dnevi';\n            }\n            return result;\n        case 'M':\n            return withoutSuffix || isFuture ? 'en mesec' : 'enim mesecem';\n        case 'MM':\n            if (number === 1) {\n                result += withoutSuffix || isFuture ? 'mesec' : 'mesecem';\n            } else if (number === 2) {\n                result += withoutSuffix || isFuture ? 'meseca' : 'mesecema';\n            } else if (number < 5) {\n                result += withoutSuffix || isFuture ? 'mesece' : 'meseci';\n            } else {\n                result += withoutSuffix || isFuture ? 'mesecev' : 'meseci';\n            }\n            return result;\n        case 'y':\n            return withoutSuffix || isFuture ? 'eno leto' : 'enim letom';\n        case 'yy':\n            if (number === 1) {\n                result += withoutSuffix || isFuture ? 'leto' : 'letom';\n            } else if (number === 2) {\n                result += withoutSuffix || isFuture ? 'leti' : 'letoma';\n            } else if (number < 5) {\n                result += withoutSuffix || isFuture ? 'leta' : 'leti';\n            } else {\n                result += withoutSuffix || isFuture ? 'let' : 'leti';\n            }\n            return result;\n    }\n}\n\nhooks.defineLocale('sl', {\n    months : 'januar_februar_marec_april_maj_junij_julij_avgust_september_oktober_november_december'.split('_'),\n    monthsShort : 'jan._feb._mar._apr._maj._jun._jul._avg._sep._okt._nov._dec.'.split('_'),\n    monthsParseExact: true,\n    weekdays : 'nedelja_ponedeljek_torek_sreda_četrtek_petek_sobota'.split('_'),\n    weekdaysShort : 'ned._pon._tor._sre._čet._pet._sob.'.split('_'),\n    weekdaysMin : 'ne_po_to_sr_če_pe_so'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat : {\n        LT : 'H:mm',\n        LTS : 'H:mm:ss',\n        L : 'DD.MM.YYYY',\n        LL : 'D. MMMM YYYY',\n        LLL : 'D. MMMM YYYY H:mm',\n        LLLL : 'dddd, D. MMMM YYYY H:mm'\n    },\n    calendar : {\n        sameDay  : '[danes ob] LT',\n        nextDay  : '[jutri ob] LT',\n\n        nextWeek : function () {\n            switch (this.day()) {\n                case 0:\n                    return '[v] [nedeljo] [ob] LT';\n                case 3:\n                    return '[v] [sredo] [ob] LT';\n                case 6:\n                    return '[v] [soboto] [ob] LT';\n                case 1:\n                case 2:\n                case 4:\n                case 5:\n                    return '[v] dddd [ob] LT';\n            }\n        },\n        lastDay  : '[včeraj ob] LT',\n        lastWeek : function () {\n            switch (this.day()) {\n                case 0:\n                    return '[prejšnjo] [nedeljo] [ob] LT';\n                case 3:\n                    return '[prejšnjo] [sredo] [ob] LT';\n                case 6:\n                    return '[prejšnjo] [soboto] [ob] LT';\n                case 1:\n                case 2:\n                case 4:\n                case 5:\n                    return '[prejšnji] dddd [ob] LT';\n            }\n        },\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'čez %s',\n        past   : 'pred %s',\n        s      : processRelativeTime$6,\n        m      : processRelativeTime$6,\n        mm     : processRelativeTime$6,\n        h      : processRelativeTime$6,\n        hh     : processRelativeTime$6,\n        d      : processRelativeTime$6,\n        dd     : processRelativeTime$6,\n        M      : processRelativeTime$6,\n        MM     : processRelativeTime$6,\n        y      : processRelativeTime$6,\n        yy     : processRelativeTime$6\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}\\./,\n    ordinal : '%d.',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 7  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Albanian [sq]\n//! author : Flakërim Ismani : https://github.com/flakerimi\n//! author : Menelion Elensúle : https://github.com/Oire\n//! author : Oerd Cukalla : https://github.com/oerd\n\nhooks.defineLocale('sq', {\n    months : 'Janar_Shkurt_Mars_Prill_Maj_Qershor_Korrik_Gusht_Shtator_Tetor_Nëntor_Dhjetor'.split('_'),\n    monthsShort : 'Jan_Shk_Mar_Pri_Maj_Qer_Kor_Gus_Sht_Tet_Nën_Dhj'.split('_'),\n    weekdays : 'E Diel_E Hënë_E Martë_E Mërkurë_E Enjte_E Premte_E Shtunë'.split('_'),\n    weekdaysShort : 'Die_Hën_Mar_Mër_Enj_Pre_Sht'.split('_'),\n    weekdaysMin : 'D_H_Ma_Më_E_P_Sh'.split('_'),\n    weekdaysParseExact : true,\n    meridiemParse: /PD|MD/,\n    isPM: function (input) {\n        return input.charAt(0) === 'M';\n    },\n    meridiem : function (hours, minutes, isLower) {\n        return hours < 12 ? 'PD' : 'MD';\n    },\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY HH:mm',\n        LLLL : 'dddd, D MMMM YYYY HH:mm'\n    },\n    calendar : {\n        sameDay : '[Sot në] LT',\n        nextDay : '[Nesër në] LT',\n        nextWeek : 'dddd [në] LT',\n        lastDay : '[Dje në] LT',\n        lastWeek : 'dddd [e kaluar në] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'në %s',\n        past : '%s më parë',\n        s : 'disa sekonda',\n        m : 'një minutë',\n        mm : '%d minuta',\n        h : 'një orë',\n        hh : '%d orë',\n        d : 'një ditë',\n        dd : '%d ditë',\n        M : 'një muaj',\n        MM : '%d muaj',\n        y : 'një vit',\n        yy : '%d vite'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}\\./,\n    ordinal : '%d.',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Serbian Cyrillic [sr-cyrl]\n//! author : Milan Janačković<milanjanackovic@gmail.com> : https://github.com/milan-j\n\nvar translator$1 = {\n    words: { //Different grammatical cases\n        m: ['један минут', 'једне минуте'],\n        mm: ['минут', 'минуте', 'минута'],\n        h: ['један сат', 'једног сата'],\n        hh: ['сат', 'сата', 'сати'],\n        dd: ['дан', 'дана', 'дана'],\n        MM: ['месец', 'месеца', 'месеци'],\n        yy: ['година', 'године', 'година']\n    },\n    correctGrammaticalCase: function (number, wordKey) {\n        return number === 1 ? wordKey[0] : (number >= 2 && number <= 4 ? wordKey[1] : wordKey[2]);\n    },\n    translate: function (number, withoutSuffix, key) {\n        var wordKey = translator$1.words[key];\n        if (key.length === 1) {\n            return withoutSuffix ? wordKey[0] : wordKey[1];\n        } else {\n            return number + ' ' + translator$1.correctGrammaticalCase(number, wordKey);\n        }\n    }\n};\n\nhooks.defineLocale('sr-cyrl', {\n    months: 'јануар_фебруар_март_април_мај_јун_јул_август_септембар_октобар_новембар_децембар'.split('_'),\n    monthsShort: 'јан._феб._мар._апр._мај_јун_јул_авг._сеп._окт._нов._дец.'.split('_'),\n    monthsParseExact: true,\n    weekdays: 'недеља_понедељак_уторак_среда_четвртак_петак_субота'.split('_'),\n    weekdaysShort: 'нед._пон._уто._сре._чет._пет._суб.'.split('_'),\n    weekdaysMin: 'не_по_ут_ср_че_пе_су'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat: {\n        LT: 'H:mm',\n        LTS : 'H:mm:ss',\n        L: 'DD.MM.YYYY',\n        LL: 'D. MMMM YYYY',\n        LLL: 'D. MMMM YYYY H:mm',\n        LLLL: 'dddd, D. MMMM YYYY H:mm'\n    },\n    calendar: {\n        sameDay: '[данас у] LT',\n        nextDay: '[сутра у] LT',\n        nextWeek: function () {\n            switch (this.day()) {\n                case 0:\n                    return '[у] [недељу] [у] LT';\n                case 3:\n                    return '[у] [среду] [у] LT';\n                case 6:\n                    return '[у] [суботу] [у] LT';\n                case 1:\n                case 2:\n                case 4:\n                case 5:\n                    return '[у] dddd [у] LT';\n            }\n        },\n        lastDay  : '[јуче у] LT',\n        lastWeek : function () {\n            var lastWeekDays = [\n                '[прошле] [недеље] [у] LT',\n                '[прошлог] [понедељка] [у] LT',\n                '[прошлог] [уторка] [у] LT',\n                '[прошле] [среде] [у] LT',\n                '[прошлог] [четвртка] [у] LT',\n                '[прошлог] [петка] [у] LT',\n                '[прошле] [суботе] [у] LT'\n            ];\n            return lastWeekDays[this.day()];\n        },\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'за %s',\n        past   : 'пре %s',\n        s      : 'неколико секунди',\n        m      : translator$1.translate,\n        mm     : translator$1.translate,\n        h      : translator$1.translate,\n        hh     : translator$1.translate,\n        d      : 'дан',\n        dd     : translator$1.translate,\n        M      : 'месец',\n        MM     : translator$1.translate,\n        y      : 'годину',\n        yy     : translator$1.translate\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}\\./,\n    ordinal : '%d.',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 7  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Serbian [sr]\n//! author : Milan Janačković<milanjanackovic@gmail.com> : https://github.com/milan-j\n\nvar translator$2 = {\n    words: { //Different grammatical cases\n        m: ['jedan minut', 'jedne minute'],\n        mm: ['minut', 'minute', 'minuta'],\n        h: ['jedan sat', 'jednog sata'],\n        hh: ['sat', 'sata', 'sati'],\n        dd: ['dan', 'dana', 'dana'],\n        MM: ['mesec', 'meseca', 'meseci'],\n        yy: ['godina', 'godine', 'godina']\n    },\n    correctGrammaticalCase: function (number, wordKey) {\n        return number === 1 ? wordKey[0] : (number >= 2 && number <= 4 ? wordKey[1] : wordKey[2]);\n    },\n    translate: function (number, withoutSuffix, key) {\n        var wordKey = translator$2.words[key];\n        if (key.length === 1) {\n            return withoutSuffix ? wordKey[0] : wordKey[1];\n        } else {\n            return number + ' ' + translator$2.correctGrammaticalCase(number, wordKey);\n        }\n    }\n};\n\nhooks.defineLocale('sr', {\n    months: 'januar_februar_mart_april_maj_jun_jul_avgust_septembar_oktobar_novembar_decembar'.split('_'),\n    monthsShort: 'jan._feb._mar._apr._maj_jun_jul_avg._sep._okt._nov._dec.'.split('_'),\n    monthsParseExact: true,\n    weekdays: 'nedelja_ponedeljak_utorak_sreda_četvrtak_petak_subota'.split('_'),\n    weekdaysShort: 'ned._pon._uto._sre._čet._pet._sub.'.split('_'),\n    weekdaysMin: 'ne_po_ut_sr_če_pe_su'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat: {\n        LT: 'H:mm',\n        LTS : 'H:mm:ss',\n        L: 'DD.MM.YYYY',\n        LL: 'D. MMMM YYYY',\n        LLL: 'D. MMMM YYYY H:mm',\n        LLLL: 'dddd, D. MMMM YYYY H:mm'\n    },\n    calendar: {\n        sameDay: '[danas u] LT',\n        nextDay: '[sutra u] LT',\n        nextWeek: function () {\n            switch (this.day()) {\n                case 0:\n                    return '[u] [nedelju] [u] LT';\n                case 3:\n                    return '[u] [sredu] [u] LT';\n                case 6:\n                    return '[u] [subotu] [u] LT';\n                case 1:\n                case 2:\n                case 4:\n                case 5:\n                    return '[u] dddd [u] LT';\n            }\n        },\n        lastDay  : '[juče u] LT',\n        lastWeek : function () {\n            var lastWeekDays = [\n                '[prošle] [nedelje] [u] LT',\n                '[prošlog] [ponedeljka] [u] LT',\n                '[prošlog] [utorka] [u] LT',\n                '[prošle] [srede] [u] LT',\n                '[prošlog] [četvrtka] [u] LT',\n                '[prošlog] [petka] [u] LT',\n                '[prošle] [subote] [u] LT'\n            ];\n            return lastWeekDays[this.day()];\n        },\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'za %s',\n        past   : 'pre %s',\n        s      : 'nekoliko sekundi',\n        m      : translator$2.translate,\n        mm     : translator$2.translate,\n        h      : translator$2.translate,\n        hh     : translator$2.translate,\n        d      : 'dan',\n        dd     : translator$2.translate,\n        M      : 'mesec',\n        MM     : translator$2.translate,\n        y      : 'godinu',\n        yy     : translator$2.translate\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}\\./,\n    ordinal : '%d.',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 7  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : siSwati [ss]\n//! author : Nicolai Davies<mail@nicolai.io> : https://github.com/nicolaidavies\n\n\nhooks.defineLocale('ss', {\n    months : \"Bhimbidvwane_Indlovana_Indlov'lenkhulu_Mabasa_Inkhwekhweti_Inhlaba_Kholwane_Ingci_Inyoni_Imphala_Lweti_Ingongoni\".split('_'),\n    monthsShort : 'Bhi_Ina_Inu_Mab_Ink_Inh_Kho_Igc_Iny_Imp_Lwe_Igo'.split('_'),\n    weekdays : 'Lisontfo_Umsombuluko_Lesibili_Lesitsatfu_Lesine_Lesihlanu_Umgcibelo'.split('_'),\n    weekdaysShort : 'Lis_Umb_Lsb_Les_Lsi_Lsh_Umg'.split('_'),\n    weekdaysMin : 'Li_Us_Lb_Lt_Ls_Lh_Ug'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat : {\n        LT : 'h:mm A',\n        LTS : 'h:mm:ss A',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY h:mm A',\n        LLLL : 'dddd, D MMMM YYYY h:mm A'\n    },\n    calendar : {\n        sameDay : '[Namuhla nga] LT',\n        nextDay : '[Kusasa nga] LT',\n        nextWeek : 'dddd [nga] LT',\n        lastDay : '[Itolo nga] LT',\n        lastWeek : 'dddd [leliphelile] [nga] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'nga %s',\n        past : 'wenteka nga %s',\n        s : 'emizuzwana lomcane',\n        m : 'umzuzu',\n        mm : '%d emizuzu',\n        h : 'lihora',\n        hh : '%d emahora',\n        d : 'lilanga',\n        dd : '%d emalanga',\n        M : 'inyanga',\n        MM : '%d tinyanga',\n        y : 'umnyaka',\n        yy : '%d iminyaka'\n    },\n    meridiemParse: /ekuseni|emini|entsambama|ebusuku/,\n    meridiem : function (hours, minutes, isLower) {\n        if (hours < 11) {\n            return 'ekuseni';\n        } else if (hours < 15) {\n            return 'emini';\n        } else if (hours < 19) {\n            return 'entsambama';\n        } else {\n            return 'ebusuku';\n        }\n    },\n    meridiemHour : function (hour, meridiem) {\n        if (hour === 12) {\n            hour = 0;\n        }\n        if (meridiem === 'ekuseni') {\n            return hour;\n        } else if (meridiem === 'emini') {\n            return hour >= 11 ? hour : hour + 12;\n        } else if (meridiem === 'entsambama' || meridiem === 'ebusuku') {\n            if (hour === 0) {\n                return 0;\n            }\n            return hour + 12;\n        }\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}/,\n    ordinal : '%d',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Swedish [sv]\n//! author : Jens Alm : https://github.com/ulmus\n\nhooks.defineLocale('sv', {\n    months : 'januari_februari_mars_april_maj_juni_juli_augusti_september_oktober_november_december'.split('_'),\n    monthsShort : 'jan_feb_mar_apr_maj_jun_jul_aug_sep_okt_nov_dec'.split('_'),\n    weekdays : 'söndag_måndag_tisdag_onsdag_torsdag_fredag_lördag'.split('_'),\n    weekdaysShort : 'sön_mån_tis_ons_tor_fre_lör'.split('_'),\n    weekdaysMin : 'sö_må_ti_on_to_fr_lö'.split('_'),\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'YYYY-MM-DD',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY [kl.] HH:mm',\n        LLLL : 'dddd D MMMM YYYY [kl.] HH:mm',\n        lll : 'D MMM YYYY HH:mm',\n        llll : 'ddd D MMM YYYY HH:mm'\n    },\n    calendar : {\n        sameDay: '[Idag] LT',\n        nextDay: '[Imorgon] LT',\n        lastDay: '[Igår] LT',\n        nextWeek: '[På] dddd LT',\n        lastWeek: '[I] dddd[s] LT',\n        sameElse: 'L'\n    },\n    relativeTime : {\n        future : 'om %s',\n        past : 'för %s sedan',\n        s : 'några sekunder',\n        m : 'en minut',\n        mm : '%d minuter',\n        h : 'en timme',\n        hh : '%d timmar',\n        d : 'en dag',\n        dd : '%d dagar',\n        M : 'en månad',\n        MM : '%d månader',\n        y : 'ett år',\n        yy : '%d år'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}(e|a)/,\n    ordinal : function (number) {\n        var b = number % 10,\n            output = (~~(number % 100 / 10) === 1) ? 'e' :\n            (b === 1) ? 'a' :\n            (b === 2) ? 'a' :\n            (b === 3) ? 'e' : 'e';\n        return number + output;\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Swahili [sw]\n//! author : Fahad Kassim : https://github.com/fadsel\n\nhooks.defineLocale('sw', {\n    months : 'Januari_Februari_Machi_Aprili_Mei_Juni_Julai_Agosti_Septemba_Oktoba_Novemba_Desemba'.split('_'),\n    monthsShort : 'Jan_Feb_Mac_Apr_Mei_Jun_Jul_Ago_Sep_Okt_Nov_Des'.split('_'),\n    weekdays : 'Jumapili_Jumatatu_Jumanne_Jumatano_Alhamisi_Ijumaa_Jumamosi'.split('_'),\n    weekdaysShort : 'Jpl_Jtat_Jnne_Jtan_Alh_Ijm_Jmos'.split('_'),\n    weekdaysMin : 'J2_J3_J4_J5_Al_Ij_J1'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD.MM.YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY HH:mm',\n        LLLL : 'dddd, D MMMM YYYY HH:mm'\n    },\n    calendar : {\n        sameDay : '[leo saa] LT',\n        nextDay : '[kesho saa] LT',\n        nextWeek : '[wiki ijayo] dddd [saat] LT',\n        lastDay : '[jana] LT',\n        lastWeek : '[wiki iliyopita] dddd [saat] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : '%s baadaye',\n        past : 'tokea %s',\n        s : 'hivi punde',\n        m : 'dakika moja',\n        mm : 'dakika %d',\n        h : 'saa limoja',\n        hh : 'masaa %d',\n        d : 'siku moja',\n        dd : 'masiku %d',\n        M : 'mwezi mmoja',\n        MM : 'miezi %d',\n        y : 'mwaka mmoja',\n        yy : 'miaka %d'\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 7  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Tamil [ta]\n//! author : Arjunkumar Krishnamoorthy : https://github.com/tk120404\n\nvar symbolMap$12 = {\n    '1': '௧',\n    '2': '௨',\n    '3': '௩',\n    '4': '௪',\n    '5': '௫',\n    '6': '௬',\n    '7': '௭',\n    '8': '௮',\n    '9': '௯',\n    '0': '௦'\n};\nvar numberMap$11 = {\n    '௧': '1',\n    '௨': '2',\n    '௩': '3',\n    '௪': '4',\n    '௫': '5',\n    '௬': '6',\n    '௭': '7',\n    '௮': '8',\n    '௯': '9',\n    '௦': '0'\n};\n\nhooks.defineLocale('ta', {\n    months : 'ஜனவரி_பிப்ரவரி_மார்ச்_ஏப்ரல்_மே_ஜூன்_ஜூலை_ஆகஸ்ட்_செப்டெம்பர்_அக்டோபர்_நவம்பர்_டிசம்பர்'.split('_'),\n    monthsShort : 'ஜனவரி_பிப்ரவரி_மார்ச்_ஏப்ரல்_மே_ஜூன்_ஜூலை_ஆகஸ்ட்_செப்டெம்பர்_அக்டோபர்_நவம்பர்_டிசம்பர்'.split('_'),\n    weekdays : 'ஞாயிற்றுக்கிழமை_திங்கட்கிழமை_செவ்வாய்கிழமை_புதன்கிழமை_வியாழக்கிழமை_வெள்ளிக்கிழமை_சனிக்கிழமை'.split('_'),\n    weekdaysShort : 'ஞாயிறு_திங்கள்_செவ்வாய்_புதன்_வியாழன்_வெள்ளி_சனி'.split('_'),\n    weekdaysMin : 'ஞா_தி_செ_பு_வி_வெ_ச'.split('_'),\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY, HH:mm',\n        LLLL : 'dddd, D MMMM YYYY, HH:mm'\n    },\n    calendar : {\n        sameDay : '[இன்று] LT',\n        nextDay : '[நாளை] LT',\n        nextWeek : 'dddd, LT',\n        lastDay : '[நேற்று] LT',\n        lastWeek : '[கடந்த வாரம்] dddd, LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : '%s இல்',\n        past : '%s முன்',\n        s : 'ஒரு சில விநாடிகள்',\n        m : 'ஒரு நிமிடம்',\n        mm : '%d நிமிடங்கள்',\n        h : 'ஒரு மணி நேரம்',\n        hh : '%d மணி நேரம்',\n        d : 'ஒரு நாள்',\n        dd : '%d நாட்கள்',\n        M : 'ஒரு மாதம்',\n        MM : '%d மாதங்கள்',\n        y : 'ஒரு வருடம்',\n        yy : '%d ஆண்டுகள்'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}வது/,\n    ordinal : function (number) {\n        return number + 'வது';\n    },\n    preparse: function (string) {\n        return string.replace(/[௧௨௩௪௫௬௭௮௯௦]/g, function (match) {\n            return numberMap$11[match];\n        });\n    },\n    postformat: function (string) {\n        return string.replace(/\\d/g, function (match) {\n            return symbolMap$12[match];\n        });\n    },\n    // refer http://ta.wikipedia.org/s/1er1\n    meridiemParse: /யாமம்|வைகறை|காலை|நண்பகல்|எற்பாடு|மாலை/,\n    meridiem : function (hour, minute, isLower) {\n        if (hour < 2) {\n            return ' யாமம்';\n        } else if (hour < 6) {\n            return ' வைகறை';  // வைகறை\n        } else if (hour < 10) {\n            return ' காலை'; // காலை\n        } else if (hour < 14) {\n            return ' நண்பகல்'; // நண்பகல்\n        } else if (hour < 18) {\n            return ' எற்பாடு'; // எற்பாடு\n        } else if (hour < 22) {\n            return ' மாலை'; // மாலை\n        } else {\n            return ' யாமம்';\n        }\n    },\n    meridiemHour : function (hour, meridiem) {\n        if (hour === 12) {\n            hour = 0;\n        }\n        if (meridiem === 'யாமம்') {\n            return hour < 2 ? hour : hour + 12;\n        } else if (meridiem === 'வைகறை' || meridiem === 'காலை') {\n            return hour;\n        } else if (meridiem === 'நண்பகல்') {\n            return hour >= 10 ? hour : hour + 12;\n        } else {\n            return hour + 12;\n        }\n    },\n    week : {\n        dow : 0, // Sunday is the first day of the week.\n        doy : 6  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Telugu [te]\n//! author : Krishna Chaitanya Thota : https://github.com/kcthota\n\nhooks.defineLocale('te', {\n    months : 'జనవరి_ఫిబ్రవరి_మార్చి_ఏప్రిల్_మే_జూన్_జూలై_ఆగస్టు_సెప్టెంబర్_అక్టోబర్_నవంబర్_డిసెంబర్'.split('_'),\n    monthsShort : 'జన._ఫిబ్ర._మార్చి_ఏప్రి._మే_జూన్_జూలై_ఆగ._సెప్._అక్టో._నవ._డిసె.'.split('_'),\n    monthsParseExact : true,\n    weekdays : 'ఆదివారం_సోమవారం_మంగళవారం_బుధవారం_గురువారం_శుక్రవారం_శనివారం'.split('_'),\n    weekdaysShort : 'ఆది_సోమ_మంగళ_బుధ_గురు_శుక్ర_శని'.split('_'),\n    weekdaysMin : 'ఆ_సో_మం_బు_గు_శు_శ'.split('_'),\n    longDateFormat : {\n        LT : 'A h:mm',\n        LTS : 'A h:mm:ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY, A h:mm',\n        LLLL : 'dddd, D MMMM YYYY, A h:mm'\n    },\n    calendar : {\n        sameDay : '[నేడు] LT',\n        nextDay : '[రేపు] LT',\n        nextWeek : 'dddd, LT',\n        lastDay : '[నిన్న] LT',\n        lastWeek : '[గత] dddd, LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : '%s లో',\n        past : '%s క్రితం',\n        s : 'కొన్ని క్షణాలు',\n        m : 'ఒక నిమిషం',\n        mm : '%d నిమిషాలు',\n        h : 'ఒక గంట',\n        hh : '%d గంటలు',\n        d : 'ఒక రోజు',\n        dd : '%d రోజులు',\n        M : 'ఒక నెల',\n        MM : '%d నెలలు',\n        y : 'ఒక సంవత్సరం',\n        yy : '%d సంవత్సరాలు'\n    },\n    dayOfMonthOrdinalParse : /\\d{1,2}వ/,\n    ordinal : '%dవ',\n    meridiemParse: /రాత్రి|ఉదయం|మధ్యాహ్నం|సాయంత్రం/,\n    meridiemHour : function (hour, meridiem) {\n        if (hour === 12) {\n            hour = 0;\n        }\n        if (meridiem === 'రాత్రి') {\n            return hour < 4 ? hour : hour + 12;\n        } else if (meridiem === 'ఉదయం') {\n            return hour;\n        } else if (meridiem === 'మధ్యాహ్నం') {\n            return hour >= 10 ? hour : hour + 12;\n        } else if (meridiem === 'సాయంత్రం') {\n            return hour + 12;\n        }\n    },\n    meridiem : function (hour, minute, isLower) {\n        if (hour < 4) {\n            return 'రాత్రి';\n        } else if (hour < 10) {\n            return 'ఉదయం';\n        } else if (hour < 17) {\n            return 'మధ్యాహ్నం';\n        } else if (hour < 20) {\n            return 'సాయంత్రం';\n        } else {\n            return 'రాత్రి';\n        }\n    },\n    week : {\n        dow : 0, // Sunday is the first day of the week.\n        doy : 6  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Tetun Dili (East Timor) [tet]\n//! author : Joshua Brooks : https://github.com/joshbrooks\n//! author : Onorio De J. Afonso : https://github.com/marobo\n\nhooks.defineLocale('tet', {\n    months : 'Janeiru_Fevereiru_Marsu_Abril_Maiu_Juniu_Juliu_Augustu_Setembru_Outubru_Novembru_Dezembru'.split('_'),\n    monthsShort : 'Jan_Fev_Mar_Abr_Mai_Jun_Jul_Aug_Set_Out_Nov_Dez'.split('_'),\n    weekdays : 'Domingu_Segunda_Tersa_Kuarta_Kinta_Sexta_Sabadu'.split('_'),\n    weekdaysShort : 'Dom_Seg_Ters_Kua_Kint_Sext_Sab'.split('_'),\n    weekdaysMin : 'Do_Seg_Te_Ku_Ki_Sex_Sa'.split('_'),\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY HH:mm',\n        LLLL : 'dddd, D MMMM YYYY HH:mm'\n    },\n    calendar : {\n        sameDay: '[Ohin iha] LT',\n        nextDay: '[Aban iha] LT',\n        nextWeek: 'dddd [iha] LT',\n        lastDay: '[Horiseik iha] LT',\n        lastWeek: 'dddd [semana kotuk] [iha] LT',\n        sameElse: 'L'\n    },\n    relativeTime : {\n        future : 'iha %s',\n        past : '%s liuba',\n        s : 'minutu balun',\n        m : 'minutu ida',\n        mm : 'minutus %d',\n        h : 'horas ida',\n        hh : 'horas %d',\n        d : 'loron ida',\n        dd : 'loron %d',\n        M : 'fulan ida',\n        MM : 'fulan %d',\n        y : 'tinan ida',\n        yy : 'tinan %d'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}(st|nd|rd|th)/,\n    ordinal : function (number) {\n        var b = number % 10,\n            output = (~~(number % 100 / 10) === 1) ? 'th' :\n            (b === 1) ? 'st' :\n            (b === 2) ? 'nd' :\n            (b === 3) ? 'rd' : 'th';\n        return number + output;\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Thai [th]\n//! author : Kridsada Thanabulpong : https://github.com/sirn\n\nhooks.defineLocale('th', {\n    months : 'มกราคม_กุมภาพันธ์_มีนาคม_เมษายน_พฤษภาคม_มิถุนายน_กรกฎาคม_สิงหาคม_กันยายน_ตุลาคม_พฤศจิกายน_ธันวาคม'.split('_'),\n    monthsShort : 'ม.ค._ก.พ._มี.ค._เม.ย._พ.ค._มิ.ย._ก.ค._ส.ค._ก.ย._ต.ค._พ.ย._ธ.ค.'.split('_'),\n    monthsParseExact: true,\n    weekdays : 'อาทิตย์_จันทร์_อังคาร_พุธ_พฤหัสบดี_ศุกร์_เสาร์'.split('_'),\n    weekdaysShort : 'อาทิตย์_จันทร์_อังคาร_พุธ_พฤหัส_ศุกร์_เสาร์'.split('_'), // yes, three characters difference\n    weekdaysMin : 'อา._จ._อ._พ._พฤ._ศ._ส.'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat : {\n        LT : 'H:mm',\n        LTS : 'H:mm:ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY เวลา H:mm',\n        LLLL : 'วันddddที่ D MMMM YYYY เวลา H:mm'\n    },\n    meridiemParse: /ก่อนเที่ยง|หลังเที่ยง/,\n    isPM: function (input) {\n        return input === 'หลังเที่ยง';\n    },\n    meridiem : function (hour, minute, isLower) {\n        if (hour < 12) {\n            return 'ก่อนเที่ยง';\n        } else {\n            return 'หลังเที่ยง';\n        }\n    },\n    calendar : {\n        sameDay : '[วันนี้ เวลา] LT',\n        nextDay : '[พรุ่งนี้ เวลา] LT',\n        nextWeek : 'dddd[หน้า เวลา] LT',\n        lastDay : '[เมื่อวานนี้ เวลา] LT',\n        lastWeek : '[วัน]dddd[ที่แล้ว เวลา] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'อีก %s',\n        past : '%sที่แล้ว',\n        s : 'ไม่กี่วินาที',\n        m : '1 นาที',\n        mm : '%d นาที',\n        h : '1 ชั่วโมง',\n        hh : '%d ชั่วโมง',\n        d : '1 วัน',\n        dd : '%d วัน',\n        M : '1 เดือน',\n        MM : '%d เดือน',\n        y : '1 ปี',\n        yy : '%d ปี'\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Tagalog (Philippines) [tl-ph]\n//! author : Dan Hagman : https://github.com/hagmandan\n\nhooks.defineLocale('tl-ph', {\n    months : 'Enero_Pebrero_Marso_Abril_Mayo_Hunyo_Hulyo_Agosto_Setyembre_Oktubre_Nobyembre_Disyembre'.split('_'),\n    monthsShort : 'Ene_Peb_Mar_Abr_May_Hun_Hul_Ago_Set_Okt_Nob_Dis'.split('_'),\n    weekdays : 'Linggo_Lunes_Martes_Miyerkules_Huwebes_Biyernes_Sabado'.split('_'),\n    weekdaysShort : 'Lin_Lun_Mar_Miy_Huw_Biy_Sab'.split('_'),\n    weekdaysMin : 'Li_Lu_Ma_Mi_Hu_Bi_Sab'.split('_'),\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'MM/D/YYYY',\n        LL : 'MMMM D, YYYY',\n        LLL : 'MMMM D, YYYY HH:mm',\n        LLLL : 'dddd, MMMM DD, YYYY HH:mm'\n    },\n    calendar : {\n        sameDay: 'LT [ngayong araw]',\n        nextDay: '[Bukas ng] LT',\n        nextWeek: 'LT [sa susunod na] dddd',\n        lastDay: 'LT [kahapon]',\n        lastWeek: 'LT [noong nakaraang] dddd',\n        sameElse: 'L'\n    },\n    relativeTime : {\n        future : 'sa loob ng %s',\n        past : '%s ang nakalipas',\n        s : 'ilang segundo',\n        m : 'isang minuto',\n        mm : '%d minuto',\n        h : 'isang oras',\n        hh : '%d oras',\n        d : 'isang araw',\n        dd : '%d araw',\n        M : 'isang buwan',\n        MM : '%d buwan',\n        y : 'isang taon',\n        yy : '%d taon'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}/,\n    ordinal : function (number) {\n        return number;\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Klingon [tlh]\n//! author : Dominika Kruk : https://github.com/amaranthrose\n\nvar numbersNouns = 'pagh_wa’_cha’_wej_loS_vagh_jav_Soch_chorgh_Hut'.split('_');\n\nfunction translateFuture(output) {\n    var time = output;\n    time = (output.indexOf('jaj') !== -1) ?\n    time.slice(0, -3) + 'leS' :\n    (output.indexOf('jar') !== -1) ?\n    time.slice(0, -3) + 'waQ' :\n    (output.indexOf('DIS') !== -1) ?\n    time.slice(0, -3) + 'nem' :\n    time + ' pIq';\n    return time;\n}\n\nfunction translatePast(output) {\n    var time = output;\n    time = (output.indexOf('jaj') !== -1) ?\n    time.slice(0, -3) + 'Hu’' :\n    (output.indexOf('jar') !== -1) ?\n    time.slice(0, -3) + 'wen' :\n    (output.indexOf('DIS') !== -1) ?\n    time.slice(0, -3) + 'ben' :\n    time + ' ret';\n    return time;\n}\n\nfunction translate$9(number, withoutSuffix, string, isFuture) {\n    var numberNoun = numberAsNoun(number);\n    switch (string) {\n        case 'mm':\n            return numberNoun + ' tup';\n        case 'hh':\n            return numberNoun + ' rep';\n        case 'dd':\n            return numberNoun + ' jaj';\n        case 'MM':\n            return numberNoun + ' jar';\n        case 'yy':\n            return numberNoun + ' DIS';\n    }\n}\n\nfunction numberAsNoun(number) {\n    var hundred = Math.floor((number % 1000) / 100),\n    ten = Math.floor((number % 100) / 10),\n    one = number % 10,\n    word = '';\n    if (hundred > 0) {\n        word += numbersNouns[hundred] + 'vatlh';\n    }\n    if (ten > 0) {\n        word += ((word !== '') ? ' ' : '') + numbersNouns[ten] + 'maH';\n    }\n    if (one > 0) {\n        word += ((word !== '') ? ' ' : '') + numbersNouns[one];\n    }\n    return (word === '') ? 'pagh' : word;\n}\n\nhooks.defineLocale('tlh', {\n    months : 'tera’ jar wa’_tera’ jar cha’_tera’ jar wej_tera’ jar loS_tera’ jar vagh_tera’ jar jav_tera’ jar Soch_tera’ jar chorgh_tera’ jar Hut_tera’ jar wa’maH_tera’ jar wa’maH wa’_tera’ jar wa’maH cha’'.split('_'),\n    monthsShort : 'jar wa’_jar cha’_jar wej_jar loS_jar vagh_jar jav_jar Soch_jar chorgh_jar Hut_jar wa’maH_jar wa’maH wa’_jar wa’maH cha’'.split('_'),\n    monthsParseExact : true,\n    weekdays : 'lojmItjaj_DaSjaj_povjaj_ghItlhjaj_loghjaj_buqjaj_ghInjaj'.split('_'),\n    weekdaysShort : 'lojmItjaj_DaSjaj_povjaj_ghItlhjaj_loghjaj_buqjaj_ghInjaj'.split('_'),\n    weekdaysMin : 'lojmItjaj_DaSjaj_povjaj_ghItlhjaj_loghjaj_buqjaj_ghInjaj'.split('_'),\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD.MM.YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY HH:mm',\n        LLLL : 'dddd, D MMMM YYYY HH:mm'\n    },\n    calendar : {\n        sameDay: '[DaHjaj] LT',\n        nextDay: '[wa’leS] LT',\n        nextWeek: 'LLL',\n        lastDay: '[wa’Hu’] LT',\n        lastWeek: 'LLL',\n        sameElse: 'L'\n    },\n    relativeTime : {\n        future : translateFuture,\n        past : translatePast,\n        s : 'puS lup',\n        m : 'wa’ tup',\n        mm : translate$9,\n        h : 'wa’ rep',\n        hh : translate$9,\n        d : 'wa’ jaj',\n        dd : translate$9,\n        M : 'wa’ jar',\n        MM : translate$9,\n        y : 'wa’ DIS',\n        yy : translate$9\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}\\./,\n    ordinal : '%d.',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Turkish [tr]\n//! authors : Erhan Gundogan : https://github.com/erhangundogan,\n//!           Burak Yiğit Kaya: https://github.com/BYK\n\nvar suffixes$3 = {\n    1: '\\'inci',\n    5: '\\'inci',\n    8: '\\'inci',\n    70: '\\'inci',\n    80: '\\'inci',\n    2: '\\'nci',\n    7: '\\'nci',\n    20: '\\'nci',\n    50: '\\'nci',\n    3: '\\'üncü',\n    4: '\\'üncü',\n    100: '\\'üncü',\n    6: '\\'ncı',\n    9: '\\'uncu',\n    10: '\\'uncu',\n    30: '\\'uncu',\n    60: '\\'ıncı',\n    90: '\\'ıncı'\n};\n\nhooks.defineLocale('tr', {\n    months : 'Ocak_Şubat_Mart_Nisan_Mayıs_Haziran_Temmuz_Ağustos_Eylül_Ekim_Kasım_Aralık'.split('_'),\n    monthsShort : 'Oca_Şub_Mar_Nis_May_Haz_Tem_Ağu_Eyl_Eki_Kas_Ara'.split('_'),\n    weekdays : 'Pazar_Pazartesi_Salı_Çarşamba_Perşembe_Cuma_Cumartesi'.split('_'),\n    weekdaysShort : 'Paz_Pts_Sal_Çar_Per_Cum_Cts'.split('_'),\n    weekdaysMin : 'Pz_Pt_Sa_Ça_Pe_Cu_Ct'.split('_'),\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD.MM.YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY HH:mm',\n        LLLL : 'dddd, D MMMM YYYY HH:mm'\n    },\n    calendar : {\n        sameDay : '[bugün saat] LT',\n        nextDay : '[yarın saat] LT',\n        nextWeek : '[haftaya] dddd [saat] LT',\n        lastDay : '[dün] LT',\n        lastWeek : '[geçen hafta] dddd [saat] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : '%s sonra',\n        past : '%s önce',\n        s : 'birkaç saniye',\n        m : 'bir dakika',\n        mm : '%d dakika',\n        h : 'bir saat',\n        hh : '%d saat',\n        d : 'bir gün',\n        dd : '%d gün',\n        M : 'bir ay',\n        MM : '%d ay',\n        y : 'bir yıl',\n        yy : '%d yıl'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}'(inci|nci|üncü|ncı|uncu|ıncı)/,\n    ordinal : function (number) {\n        if (number === 0) {  // special case for zero\n            return number + '\\'ıncı';\n        }\n        var a = number % 10,\n            b = number % 100 - a,\n            c = number >= 100 ? 100 : null;\n        return number + (suffixes$3[a] || suffixes$3[b] || suffixes$3[c]);\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 7  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Talossan [tzl]\n//! author : Robin van der Vliet : https://github.com/robin0van0der0v\n//! author : Iustì Canun\n\n// After the year there should be a slash and the amount of years since December 26, 1979 in Roman numerals.\n// This is currently too difficult (maybe even impossible) to add.\nhooks.defineLocale('tzl', {\n    months : 'Januar_Fevraglh_Març_Avrïu_Mai_Gün_Julia_Guscht_Setemvar_Listopäts_Noemvar_Zecemvar'.split('_'),\n    monthsShort : 'Jan_Fev_Mar_Avr_Mai_Gün_Jul_Gus_Set_Lis_Noe_Zec'.split('_'),\n    weekdays : 'Súladi_Lúneçi_Maitzi_Márcuri_Xhúadi_Viénerçi_Sáturi'.split('_'),\n    weekdaysShort : 'Súl_Lún_Mai_Már_Xhú_Vié_Sát'.split('_'),\n    weekdaysMin : 'Sú_Lú_Ma_Má_Xh_Vi_Sá'.split('_'),\n    longDateFormat : {\n        LT : 'HH.mm',\n        LTS : 'HH.mm.ss',\n        L : 'DD.MM.YYYY',\n        LL : 'D. MMMM [dallas] YYYY',\n        LLL : 'D. MMMM [dallas] YYYY HH.mm',\n        LLLL : 'dddd, [li] D. MMMM [dallas] YYYY HH.mm'\n    },\n    meridiemParse: /d\\'o|d\\'a/i,\n    isPM : function (input) {\n        return 'd\\'o' === input.toLowerCase();\n    },\n    meridiem : function (hours, minutes, isLower) {\n        if (hours > 11) {\n            return isLower ? 'd\\'o' : 'D\\'O';\n        } else {\n            return isLower ? 'd\\'a' : 'D\\'A';\n        }\n    },\n    calendar : {\n        sameDay : '[oxhi à] LT',\n        nextDay : '[demà à] LT',\n        nextWeek : 'dddd [à] LT',\n        lastDay : '[ieiri à] LT',\n        lastWeek : '[sür el] dddd [lasteu à] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'osprei %s',\n        past : 'ja%s',\n        s : processRelativeTime$7,\n        m : processRelativeTime$7,\n        mm : processRelativeTime$7,\n        h : processRelativeTime$7,\n        hh : processRelativeTime$7,\n        d : processRelativeTime$7,\n        dd : processRelativeTime$7,\n        M : processRelativeTime$7,\n        MM : processRelativeTime$7,\n        y : processRelativeTime$7,\n        yy : processRelativeTime$7\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}\\./,\n    ordinal : '%d.',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\nfunction processRelativeTime$7(number, withoutSuffix, key, isFuture) {\n    var format = {\n        's': ['viensas secunds', '\\'iensas secunds'],\n        'm': ['\\'n míut', '\\'iens míut'],\n        'mm': [number + ' míuts', '' + number + ' míuts'],\n        'h': ['\\'n þora', '\\'iensa þora'],\n        'hh': [number + ' þoras', '' + number + ' þoras'],\n        'd': ['\\'n ziua', '\\'iensa ziua'],\n        'dd': [number + ' ziuas', '' + number + ' ziuas'],\n        'M': ['\\'n mes', '\\'iens mes'],\n        'MM': [number + ' mesen', '' + number + ' mesen'],\n        'y': ['\\'n ar', '\\'iens ar'],\n        'yy': [number + ' ars', '' + number + ' ars']\n    };\n    return isFuture ? format[key][0] : (withoutSuffix ? format[key][0] : format[key][1]);\n}\n\n//! moment.js locale configuration\n//! locale : Central Atlas Tamazight Latin [tzm-latn]\n//! author : Abdel Said : https://github.com/abdelsaid\n\nhooks.defineLocale('tzm-latn', {\n    months : 'innayr_brˤayrˤ_marˤsˤ_ibrir_mayyw_ywnyw_ywlywz_ɣwšt_šwtanbir_ktˤwbrˤ_nwwanbir_dwjnbir'.split('_'),\n    monthsShort : 'innayr_brˤayrˤ_marˤsˤ_ibrir_mayyw_ywnyw_ywlywz_ɣwšt_šwtanbir_ktˤwbrˤ_nwwanbir_dwjnbir'.split('_'),\n    weekdays : 'asamas_aynas_asinas_akras_akwas_asimwas_asiḍyas'.split('_'),\n    weekdaysShort : 'asamas_aynas_asinas_akras_akwas_asimwas_asiḍyas'.split('_'),\n    weekdaysMin : 'asamas_aynas_asinas_akras_akwas_asimwas_asiḍyas'.split('_'),\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY HH:mm',\n        LLLL : 'dddd D MMMM YYYY HH:mm'\n    },\n    calendar : {\n        sameDay: '[asdkh g] LT',\n        nextDay: '[aska g] LT',\n        nextWeek: 'dddd [g] LT',\n        lastDay: '[assant g] LT',\n        lastWeek: 'dddd [g] LT',\n        sameElse: 'L'\n    },\n    relativeTime : {\n        future : 'dadkh s yan %s',\n        past : 'yan %s',\n        s : 'imik',\n        m : 'minuḍ',\n        mm : '%d minuḍ',\n        h : 'saɛa',\n        hh : '%d tassaɛin',\n        d : 'ass',\n        dd : '%d ossan',\n        M : 'ayowr',\n        MM : '%d iyyirn',\n        y : 'asgas',\n        yy : '%d isgasn'\n    },\n    week : {\n        dow : 6, // Saturday is the first day of the week.\n        doy : 12  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Central Atlas Tamazight [tzm]\n//! author : Abdel Said : https://github.com/abdelsaid\n\nhooks.defineLocale('tzm', {\n    months : 'ⵉⵏⵏⴰⵢⵔ_ⴱⵕⴰⵢⵕ_ⵎⴰⵕⵚ_ⵉⴱⵔⵉⵔ_ⵎⴰⵢⵢⵓ_ⵢⵓⵏⵢⵓ_ⵢⵓⵍⵢⵓⵣ_ⵖⵓⵛⵜ_ⵛⵓⵜⴰⵏⴱⵉⵔ_ⴽⵟⵓⴱⵕ_ⵏⵓⵡⴰⵏⴱⵉⵔ_ⴷⵓⵊⵏⴱⵉⵔ'.split('_'),\n    monthsShort : 'ⵉⵏⵏⴰⵢⵔ_ⴱⵕⴰⵢⵕ_ⵎⴰⵕⵚ_ⵉⴱⵔⵉⵔ_ⵎⴰⵢⵢⵓ_ⵢⵓⵏⵢⵓ_ⵢⵓⵍⵢⵓⵣ_ⵖⵓⵛⵜ_ⵛⵓⵜⴰⵏⴱⵉⵔ_ⴽⵟⵓⴱⵕ_ⵏⵓⵡⴰⵏⴱⵉⵔ_ⴷⵓⵊⵏⴱⵉⵔ'.split('_'),\n    weekdays : 'ⴰⵙⴰⵎⴰⵙ_ⴰⵢⵏⴰⵙ_ⴰⵙⵉⵏⴰⵙ_ⴰⴽⵔⴰⵙ_ⴰⴽⵡⴰⵙ_ⴰⵙⵉⵎⵡⴰⵙ_ⴰⵙⵉⴹⵢⴰⵙ'.split('_'),\n    weekdaysShort : 'ⴰⵙⴰⵎⴰⵙ_ⴰⵢⵏⴰⵙ_ⴰⵙⵉⵏⴰⵙ_ⴰⴽⵔⴰⵙ_ⴰⴽⵡⴰⵙ_ⴰⵙⵉⵎⵡⴰⵙ_ⴰⵙⵉⴹⵢⴰⵙ'.split('_'),\n    weekdaysMin : 'ⴰⵙⴰⵎⴰⵙ_ⴰⵢⵏⴰⵙ_ⴰⵙⵉⵏⴰⵙ_ⴰⴽⵔⴰⵙ_ⴰⴽⵡⴰⵙ_ⴰⵙⵉⵎⵡⴰⵙ_ⴰⵙⵉⴹⵢⴰⵙ'.split('_'),\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS: 'HH:mm:ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY HH:mm',\n        LLLL : 'dddd D MMMM YYYY HH:mm'\n    },\n    calendar : {\n        sameDay: '[ⴰⵙⴷⵅ ⴴ] LT',\n        nextDay: '[ⴰⵙⴽⴰ ⴴ] LT',\n        nextWeek: 'dddd [ⴴ] LT',\n        lastDay: '[ⴰⵚⴰⵏⵜ ⴴ] LT',\n        lastWeek: 'dddd [ⴴ] LT',\n        sameElse: 'L'\n    },\n    relativeTime : {\n        future : 'ⴷⴰⴷⵅ ⵙ ⵢⴰⵏ %s',\n        past : 'ⵢⴰⵏ %s',\n        s : 'ⵉⵎⵉⴽ',\n        m : 'ⵎⵉⵏⵓⴺ',\n        mm : '%d ⵎⵉⵏⵓⴺ',\n        h : 'ⵙⴰⵄⴰ',\n        hh : '%d ⵜⴰⵙⵙⴰⵄⵉⵏ',\n        d : 'ⴰⵙⵙ',\n        dd : '%d oⵙⵙⴰⵏ',\n        M : 'ⴰⵢoⵓⵔ',\n        MM : '%d ⵉⵢⵢⵉⵔⵏ',\n        y : 'ⴰⵙⴳⴰⵙ',\n        yy : '%d ⵉⵙⴳⴰⵙⵏ'\n    },\n    week : {\n        dow : 6, // Saturday is the first day of the week.\n        doy : 12  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Ukrainian [uk]\n//! author : zemlanin : https://github.com/zemlanin\n//! Author : Menelion Elensúle : https://github.com/Oire\n\nfunction plural$6(word, num) {\n    var forms = word.split('_');\n    return num % 10 === 1 && num % 100 !== 11 ? forms[0] : (num % 10 >= 2 && num % 10 <= 4 && (num % 100 < 10 || num % 100 >= 20) ? forms[1] : forms[2]);\n}\nfunction relativeTimeWithPlural$4(number, withoutSuffix, key) {\n    var format = {\n        'mm': withoutSuffix ? 'хвилина_хвилини_хвилин' : 'хвилину_хвилини_хвилин',\n        'hh': withoutSuffix ? 'година_години_годин' : 'годину_години_годин',\n        'dd': 'день_дні_днів',\n        'MM': 'місяць_місяці_місяців',\n        'yy': 'рік_роки_років'\n    };\n    if (key === 'm') {\n        return withoutSuffix ? 'хвилина' : 'хвилину';\n    }\n    else if (key === 'h') {\n        return withoutSuffix ? 'година' : 'годину';\n    }\n    else {\n        return number + ' ' + plural$6(format[key], +number);\n    }\n}\nfunction weekdaysCaseReplace(m, format) {\n    var weekdays = {\n        'nominative': 'неділя_понеділок_вівторок_середа_четвер_п’ятниця_субота'.split('_'),\n        'accusative': 'неділю_понеділок_вівторок_середу_четвер_п’ятницю_суботу'.split('_'),\n        'genitive': 'неділі_понеділка_вівторка_середи_четверга_п’ятниці_суботи'.split('_')\n    };\n\n    if (!m) {\n        return weekdays['nominative'];\n    }\n\n    var nounCase = (/(\\[[ВвУу]\\]) ?dddd/).test(format) ?\n        'accusative' :\n        ((/\\[?(?:минулої|наступної)? ?\\] ?dddd/).test(format) ?\n            'genitive' :\n            'nominative');\n    return weekdays[nounCase][m.day()];\n}\nfunction processHoursFunction(str) {\n    return function () {\n        return str + 'о' + (this.hours() === 11 ? 'б' : '') + '] LT';\n    };\n}\n\nhooks.defineLocale('uk', {\n    months : {\n        'format': 'січня_лютого_березня_квітня_травня_червня_липня_серпня_вересня_жовтня_листопада_грудня'.split('_'),\n        'standalone': 'січень_лютий_березень_квітень_травень_червень_липень_серпень_вересень_жовтень_листопад_грудень'.split('_')\n    },\n    monthsShort : 'січ_лют_бер_квіт_трав_черв_лип_серп_вер_жовт_лист_груд'.split('_'),\n    weekdays : weekdaysCaseReplace,\n    weekdaysShort : 'нд_пн_вт_ср_чт_пт_сб'.split('_'),\n    weekdaysMin : 'нд_пн_вт_ср_чт_пт_сб'.split('_'),\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD.MM.YYYY',\n        LL : 'D MMMM YYYY р.',\n        LLL : 'D MMMM YYYY р., HH:mm',\n        LLLL : 'dddd, D MMMM YYYY р., HH:mm'\n    },\n    calendar : {\n        sameDay: processHoursFunction('[Сьогодні '),\n        nextDay: processHoursFunction('[Завтра '),\n        lastDay: processHoursFunction('[Вчора '),\n        nextWeek: processHoursFunction('[У] dddd ['),\n        lastWeek: function () {\n            switch (this.day()) {\n                case 0:\n                case 3:\n                case 5:\n                case 6:\n                    return processHoursFunction('[Минулої] dddd [').call(this);\n                case 1:\n                case 2:\n                case 4:\n                    return processHoursFunction('[Минулого] dddd [').call(this);\n            }\n        },\n        sameElse: 'L'\n    },\n    relativeTime : {\n        future : 'за %s',\n        past : '%s тому',\n        s : 'декілька секунд',\n        m : relativeTimeWithPlural$4,\n        mm : relativeTimeWithPlural$4,\n        h : 'годину',\n        hh : relativeTimeWithPlural$4,\n        d : 'день',\n        dd : relativeTimeWithPlural$4,\n        M : 'місяць',\n        MM : relativeTimeWithPlural$4,\n        y : 'рік',\n        yy : relativeTimeWithPlural$4\n    },\n    // M. E.: those two are virtually unused but a user might want to implement them for his/her website for some reason\n    meridiemParse: /ночі|ранку|дня|вечора/,\n    isPM: function (input) {\n        return /^(дня|вечора)$/.test(input);\n    },\n    meridiem : function (hour, minute, isLower) {\n        if (hour < 4) {\n            return 'ночі';\n        } else if (hour < 12) {\n            return 'ранку';\n        } else if (hour < 17) {\n            return 'дня';\n        } else {\n            return 'вечора';\n        }\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}-(й|го)/,\n    ordinal: function (number, period) {\n        switch (period) {\n            case 'M':\n            case 'd':\n            case 'DDD':\n            case 'w':\n            case 'W':\n                return number + '-й';\n            case 'D':\n                return number + '-го';\n            default:\n                return number;\n        }\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 7  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Urdu [ur]\n//! author : Sawood Alam : https://github.com/ibnesayeed\n//! author : Zack : https://github.com/ZackVision\n\nvar months$8 = [\n    'جنوری',\n    'فروری',\n    'مارچ',\n    'اپریل',\n    'مئی',\n    'جون',\n    'جولائی',\n    'اگست',\n    'ستمبر',\n    'اکتوبر',\n    'نومبر',\n    'دسمبر'\n];\nvar days$2 = [\n    'اتوار',\n    'پیر',\n    'منگل',\n    'بدھ',\n    'جمعرات',\n    'جمعہ',\n    'ہفتہ'\n];\n\nhooks.defineLocale('ur', {\n    months : months$8,\n    monthsShort : months$8,\n    weekdays : days$2,\n    weekdaysShort : days$2,\n    weekdaysMin : days$2,\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY HH:mm',\n        LLLL : 'dddd، D MMMM YYYY HH:mm'\n    },\n    meridiemParse: /صبح|شام/,\n    isPM : function (input) {\n        return 'شام' === input;\n    },\n    meridiem : function (hour, minute, isLower) {\n        if (hour < 12) {\n            return 'صبح';\n        }\n        return 'شام';\n    },\n    calendar : {\n        sameDay : '[آج بوقت] LT',\n        nextDay : '[کل بوقت] LT',\n        nextWeek : 'dddd [بوقت] LT',\n        lastDay : '[گذشتہ روز بوقت] LT',\n        lastWeek : '[گذشتہ] dddd [بوقت] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : '%s بعد',\n        past : '%s قبل',\n        s : 'چند سیکنڈ',\n        m : 'ایک منٹ',\n        mm : '%d منٹ',\n        h : 'ایک گھنٹہ',\n        hh : '%d گھنٹے',\n        d : 'ایک دن',\n        dd : '%d دن',\n        M : 'ایک ماہ',\n        MM : '%d ماہ',\n        y : 'ایک سال',\n        yy : '%d سال'\n    },\n    preparse: function (string) {\n        return string.replace(/،/g, ',');\n    },\n    postformat: function (string) {\n        return string.replace(/,/g, '،');\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Uzbek Latin [uz-latn]\n//! author : Rasulbek Mirzayev : github.com/Rasulbeeek\n\nhooks.defineLocale('uz-latn', {\n    months : 'Yanvar_Fevral_Mart_Aprel_May_Iyun_Iyul_Avgust_Sentabr_Oktabr_Noyabr_Dekabr'.split('_'),\n    monthsShort : 'Yan_Fev_Mar_Apr_May_Iyun_Iyul_Avg_Sen_Okt_Noy_Dek'.split('_'),\n    weekdays : 'Yakshanba_Dushanba_Seshanba_Chorshanba_Payshanba_Juma_Shanba'.split('_'),\n    weekdaysShort : 'Yak_Dush_Sesh_Chor_Pay_Jum_Shan'.split('_'),\n    weekdaysMin : 'Ya_Du_Se_Cho_Pa_Ju_Sha'.split('_'),\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY HH:mm',\n        LLLL : 'D MMMM YYYY, dddd HH:mm'\n    },\n    calendar : {\n        sameDay : '[Bugun soat] LT [da]',\n        nextDay : '[Ertaga] LT [da]',\n        nextWeek : 'dddd [kuni soat] LT [da]',\n        lastDay : '[Kecha soat] LT [da]',\n        lastWeek : '[O\\'tgan] dddd [kuni soat] LT [da]',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'Yaqin %s ichida',\n        past : 'Bir necha %s oldin',\n        s : 'soniya',\n        m : 'bir daqiqa',\n        mm : '%d daqiqa',\n        h : 'bir soat',\n        hh : '%d soat',\n        d : 'bir kun',\n        dd : '%d kun',\n        M : 'bir oy',\n        MM : '%d oy',\n        y : 'bir yil',\n        yy : '%d yil'\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 7  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Uzbek [uz]\n//! author : Sardor Muminov : https://github.com/muminoff\n\nhooks.defineLocale('uz', {\n    months : 'январ_феврал_март_апрел_май_июн_июл_август_сентябр_октябр_ноябр_декабр'.split('_'),\n    monthsShort : 'янв_фев_мар_апр_май_июн_июл_авг_сен_окт_ноя_дек'.split('_'),\n    weekdays : 'Якшанба_Душанба_Сешанба_Чоршанба_Пайшанба_Жума_Шанба'.split('_'),\n    weekdaysShort : 'Якш_Душ_Сеш_Чор_Пай_Жум_Шан'.split('_'),\n    weekdaysMin : 'Як_Ду_Се_Чо_Па_Жу_Ша'.split('_'),\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY HH:mm',\n        LLLL : 'D MMMM YYYY, dddd HH:mm'\n    },\n    calendar : {\n        sameDay : '[Бугун соат] LT [да]',\n        nextDay : '[Эртага] LT [да]',\n        nextWeek : 'dddd [куни соат] LT [да]',\n        lastDay : '[Кеча соат] LT [да]',\n        lastWeek : '[Утган] dddd [куни соат] LT [да]',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'Якин %s ичида',\n        past : 'Бир неча %s олдин',\n        s : 'фурсат',\n        m : 'бир дакика',\n        mm : '%d дакика',\n        h : 'бир соат',\n        hh : '%d соат',\n        d : 'бир кун',\n        dd : '%d кун',\n        M : 'бир ой',\n        MM : '%d ой',\n        y : 'бир йил',\n        yy : '%d йил'\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 7  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Vietnamese [vi]\n//! author : Bang Nguyen : https://github.com/bangnk\n\nhooks.defineLocale('vi', {\n    months : 'tháng 1_tháng 2_tháng 3_tháng 4_tháng 5_tháng 6_tháng 7_tháng 8_tháng 9_tháng 10_tháng 11_tháng 12'.split('_'),\n    monthsShort : 'Th01_Th02_Th03_Th04_Th05_Th06_Th07_Th08_Th09_Th10_Th11_Th12'.split('_'),\n    monthsParseExact : true,\n    weekdays : 'chủ nhật_thứ hai_thứ ba_thứ tư_thứ năm_thứ sáu_thứ bảy'.split('_'),\n    weekdaysShort : 'CN_T2_T3_T4_T5_T6_T7'.split('_'),\n    weekdaysMin : 'CN_T2_T3_T4_T5_T6_T7'.split('_'),\n    weekdaysParseExact : true,\n    meridiemParse: /sa|ch/i,\n    isPM : function (input) {\n        return /^ch$/i.test(input);\n    },\n    meridiem : function (hours, minutes, isLower) {\n        if (hours < 12) {\n            return isLower ? 'sa' : 'SA';\n        } else {\n            return isLower ? 'ch' : 'CH';\n        }\n    },\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM [năm] YYYY',\n        LLL : 'D MMMM [năm] YYYY HH:mm',\n        LLLL : 'dddd, D MMMM [năm] YYYY HH:mm',\n        l : 'DD/M/YYYY',\n        ll : 'D MMM YYYY',\n        lll : 'D MMM YYYY HH:mm',\n        llll : 'ddd, D MMM YYYY HH:mm'\n    },\n    calendar : {\n        sameDay: '[Hôm nay lúc] LT',\n        nextDay: '[Ngày mai lúc] LT',\n        nextWeek: 'dddd [tuần tới lúc] LT',\n        lastDay: '[Hôm qua lúc] LT',\n        lastWeek: 'dddd [tuần rồi lúc] LT',\n        sameElse: 'L'\n    },\n    relativeTime : {\n        future : '%s tới',\n        past : '%s trước',\n        s : 'vài giây',\n        m : 'một phút',\n        mm : '%d phút',\n        h : 'một giờ',\n        hh : '%d giờ',\n        d : 'một ngày',\n        dd : '%d ngày',\n        M : 'một tháng',\n        MM : '%d tháng',\n        y : 'một năm',\n        yy : '%d năm'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}/,\n    ordinal : function (number) {\n        return number;\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Pseudo [x-pseudo]\n//! author : Andrew Hood : https://github.com/andrewhood125\n\nhooks.defineLocale('x-pseudo', {\n    months : 'J~áñúá~rý_F~ébrú~árý_~Márc~h_Áp~ríl_~Máý_~Júñé~_Júl~ý_Áú~gúst~_Sép~témb~ér_Ó~ctób~ér_Ñ~óvém~bér_~Décé~mbér'.split('_'),\n    monthsShort : 'J~áñ_~Féb_~Már_~Ápr_~Máý_~Júñ_~Júl_~Áúg_~Sép_~Óct_~Ñóv_~Déc'.split('_'),\n    monthsParseExact : true,\n    weekdays : 'S~úñdá~ý_Mó~ñdáý~_Túé~sdáý~_Wéd~ñésd~áý_T~húrs~dáý_~Fríd~áý_S~átúr~dáý'.split('_'),\n    weekdaysShort : 'S~úñ_~Móñ_~Túé_~Wéd_~Thú_~Frí_~Sát'.split('_'),\n    weekdaysMin : 'S~ú_Mó~_Tú_~Wé_T~h_Fr~_Sá'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat : {\n        LT : 'HH:mm',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY HH:mm',\n        LLLL : 'dddd, D MMMM YYYY HH:mm'\n    },\n    calendar : {\n        sameDay : '[T~ódá~ý át] LT',\n        nextDay : '[T~ómó~rró~w át] LT',\n        nextWeek : 'dddd [át] LT',\n        lastDay : '[Ý~ést~érdá~ý át] LT',\n        lastWeek : '[L~ást] dddd [át] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'í~ñ %s',\n        past : '%s á~gó',\n        s : 'á ~féw ~sécó~ñds',\n        m : 'á ~míñ~úté',\n        mm : '%d m~íñú~tés',\n        h : 'á~ñ hó~úr',\n        hh : '%d h~óúrs',\n        d : 'á ~dáý',\n        dd : '%d d~áýs',\n        M : 'á ~móñ~th',\n        MM : '%d m~óñt~hs',\n        y : 'á ~ýéár',\n        yy : '%d ý~éárs'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}(th|st|nd|rd)/,\n    ordinal : function (number) {\n        var b = number % 10,\n            output = (~~(number % 100 / 10) === 1) ? 'th' :\n            (b === 1) ? 'st' :\n            (b === 2) ? 'nd' :\n            (b === 3) ? 'rd' : 'th';\n        return number + output;\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Yoruba Nigeria [yo]\n//! author : Atolagbe Abisoye : https://github.com/andela-batolagbe\n\nhooks.defineLocale('yo', {\n    months : 'Sẹ́rẹ́_Èrèlè_Ẹrẹ̀nà_Ìgbé_Èbibi_Òkùdu_Agẹmo_Ògún_Owewe_Ọ̀wàrà_Bélú_Ọ̀pẹ̀̀'.split('_'),\n    monthsShort : 'Sẹ́r_Èrl_Ẹrn_Ìgb_Èbi_Òkù_Agẹ_Ògú_Owe_Ọ̀wà_Bél_Ọ̀pẹ̀̀'.split('_'),\n    weekdays : 'Àìkú_Ajé_Ìsẹ́gun_Ọjọ́rú_Ọjọ́bọ_Ẹtì_Àbámẹ́ta'.split('_'),\n    weekdaysShort : 'Àìk_Ajé_Ìsẹ́_Ọjr_Ọjb_Ẹtì_Àbá'.split('_'),\n    weekdaysMin : 'Àì_Aj_Ìs_Ọr_Ọb_Ẹt_Àb'.split('_'),\n    longDateFormat : {\n        LT : 'h:mm A',\n        LTS : 'h:mm:ss A',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY h:mm A',\n        LLLL : 'dddd, D MMMM YYYY h:mm A'\n    },\n    calendar : {\n        sameDay : '[Ònì ni] LT',\n        nextDay : '[Ọ̀la ni] LT',\n        nextWeek : 'dddd [Ọsẹ̀ tón\\'bọ] [ni] LT',\n        lastDay : '[Àna ni] LT',\n        lastWeek : 'dddd [Ọsẹ̀ tólọ́] [ni] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'ní %s',\n        past : '%s kọjá',\n        s : 'ìsẹjú aayá die',\n        m : 'ìsẹjú kan',\n        mm : 'ìsẹjú %d',\n        h : 'wákati kan',\n        hh : 'wákati %d',\n        d : 'ọjọ́ kan',\n        dd : 'ọjọ́ %d',\n        M : 'osù kan',\n        MM : 'osù %d',\n        y : 'ọdún kan',\n        yy : 'ọdún %d'\n    },\n    dayOfMonthOrdinalParse : /ọjọ́\\s\\d{1,2}/,\n    ordinal : 'ọjọ́ %d',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4 // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Chinese (China) [zh-cn]\n//! author : suupic : https://github.com/suupic\n//! author : Zeno Zeng : https://github.com/zenozeng\n\nhooks.defineLocale('zh-cn', {\n    months : '一月_二月_三月_四月_五月_六月_七月_八月_九月_十月_十一月_十二月'.split('_'),\n    monthsShort : '1月_2月_3月_4月_5月_6月_7月_8月_9月_10月_11月_12月'.split('_'),\n    weekdays : '星期日_星期一_星期二_星期三_星期四_星期五_星期六'.split('_'),\n    weekdaysShort : '周日_周一_周二_周三_周四_周五_周六'.split('_'),\n    weekdaysMin : '日_一_二_三_四_五_六'.split('_'),\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'YYYY年MMMD日',\n        LL : 'YYYY年MMMD日',\n        LLL : 'YYYY年MMMD日Ah点mm分',\n        LLLL : 'YYYY年MMMD日ddddAh点mm分',\n        l : 'YYYY年MMMD日',\n        ll : 'YYYY年MMMD日',\n        lll : 'YYYY年MMMD日 HH:mm',\n        llll : 'YYYY年MMMD日dddd HH:mm'\n    },\n    meridiemParse: /凌晨|早上|上午|中午|下午|晚上/,\n    meridiemHour: function (hour, meridiem) {\n        if (hour === 12) {\n            hour = 0;\n        }\n        if (meridiem === '凌晨' || meridiem === '早上' ||\n                meridiem === '上午') {\n            return hour;\n        } else if (meridiem === '下午' || meridiem === '晚上') {\n            return hour + 12;\n        } else {\n            // '中午'\n            return hour >= 11 ? hour : hour + 12;\n        }\n    },\n    meridiem : function (hour, minute, isLower) {\n        var hm = hour * 100 + minute;\n        if (hm < 600) {\n            return '凌晨';\n        } else if (hm < 900) {\n            return '早上';\n        } else if (hm < 1130) {\n            return '上午';\n        } else if (hm < 1230) {\n            return '中午';\n        } else if (hm < 1800) {\n            return '下午';\n        } else {\n            return '晚上';\n        }\n    },\n    calendar : {\n        sameDay : '[今天]LT',\n        nextDay : '[明天]LT',\n        nextWeek : '[下]ddddLT',\n        lastDay : '[昨天]LT',\n        lastWeek : '[上]ddddLT',\n        sameElse : 'L'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}(日|月|周)/,\n    ordinal : function (number, period) {\n        switch (period) {\n            case 'd':\n            case 'D':\n            case 'DDD':\n                return number + '日';\n            case 'M':\n                return number + '月';\n            case 'w':\n            case 'W':\n                return number + '周';\n            default:\n                return number;\n        }\n    },\n    relativeTime : {\n        future : '%s内',\n        past : '%s前',\n        s : '几秒',\n        m : '1 分钟',\n        mm : '%d 分钟',\n        h : '1 小时',\n        hh : '%d 小时',\n        d : '1 天',\n        dd : '%d 天',\n        M : '1 个月',\n        MM : '%d 个月',\n        y : '1 年',\n        yy : '%d 年'\n    },\n    week : {\n        // GB/T 7408-1994《数据元和交换格式·信息交换·日期和时间表示法》与ISO 8601:1988等效\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Chinese (Hong Kong) [zh-hk]\n//! author : Ben : https://github.com/ben-lin\n//! author : Chris Lam : https://github.com/hehachris\n//! author : Konstantin : https://github.com/skfd\n\nhooks.defineLocale('zh-hk', {\n    months : '一月_二月_三月_四月_五月_六月_七月_八月_九月_十月_十一月_十二月'.split('_'),\n    monthsShort : '1月_2月_3月_4月_5月_6月_7月_8月_9月_10月_11月_12月'.split('_'),\n    weekdays : '星期日_星期一_星期二_星期三_星期四_星期五_星期六'.split('_'),\n    weekdaysShort : '週日_週一_週二_週三_週四_週五_週六'.split('_'),\n    weekdaysMin : '日_一_二_三_四_五_六'.split('_'),\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'YYYY年MMMD日',\n        LL : 'YYYY年MMMD日',\n        LLL : 'YYYY年MMMD日 HH:mm',\n        LLLL : 'YYYY年MMMD日dddd HH:mm',\n        l : 'YYYY年MMMD日',\n        ll : 'YYYY年MMMD日',\n        lll : 'YYYY年MMMD日 HH:mm',\n        llll : 'YYYY年MMMD日dddd HH:mm'\n    },\n    meridiemParse: /凌晨|早上|上午|中午|下午|晚上/,\n    meridiemHour : function (hour, meridiem) {\n        if (hour === 12) {\n            hour = 0;\n        }\n        if (meridiem === '凌晨' || meridiem === '早上' || meridiem === '上午') {\n            return hour;\n        } else if (meridiem === '中午') {\n            return hour >= 11 ? hour : hour + 12;\n        } else if (meridiem === '下午' || meridiem === '晚上') {\n            return hour + 12;\n        }\n    },\n    meridiem : function (hour, minute, isLower) {\n        var hm = hour * 100 + minute;\n        if (hm < 600) {\n            return '凌晨';\n        } else if (hm < 900) {\n            return '早上';\n        } else if (hm < 1130) {\n            return '上午';\n        } else if (hm < 1230) {\n            return '中午';\n        } else if (hm < 1800) {\n            return '下午';\n        } else {\n            return '晚上';\n        }\n    },\n    calendar : {\n        sameDay : '[今天]LT',\n        nextDay : '[明天]LT',\n        nextWeek : '[下]ddddLT',\n        lastDay : '[昨天]LT',\n        lastWeek : '[上]ddddLT',\n        sameElse : 'L'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}(日|月|週)/,\n    ordinal : function (number, period) {\n        switch (period) {\n            case 'd' :\n            case 'D' :\n            case 'DDD' :\n                return number + '日';\n            case 'M' :\n                return number + '月';\n            case 'w' :\n            case 'W' :\n                return number + '週';\n            default :\n                return number;\n        }\n    },\n    relativeTime : {\n        future : '%s內',\n        past : '%s前',\n        s : '幾秒',\n        m : '1 分鐘',\n        mm : '%d 分鐘',\n        h : '1 小時',\n        hh : '%d 小時',\n        d : '1 天',\n        dd : '%d 天',\n        M : '1 個月',\n        MM : '%d 個月',\n        y : '1 年',\n        yy : '%d 年'\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Chinese (Taiwan) [zh-tw]\n//! author : Ben : https://github.com/ben-lin\n//! author : Chris Lam : https://github.com/hehachris\n\nhooks.defineLocale('zh-tw', {\n    months : '一月_二月_三月_四月_五月_六月_七月_八月_九月_十月_十一月_十二月'.split('_'),\n    monthsShort : '1月_2月_3月_4月_5月_6月_7月_8月_9月_10月_11月_12月'.split('_'),\n    weekdays : '星期日_星期一_星期二_星期三_星期四_星期五_星期六'.split('_'),\n    weekdaysShort : '週日_週一_週二_週三_週四_週五_週六'.split('_'),\n    weekdaysMin : '日_一_二_三_四_五_六'.split('_'),\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'YYYY年MMMD日',\n        LL : 'YYYY年MMMD日',\n        LLL : 'YYYY年MMMD日 HH:mm',\n        LLLL : 'YYYY年MMMD日dddd HH:mm',\n        l : 'YYYY年MMMD日',\n        ll : 'YYYY年MMMD日',\n        lll : 'YYYY年MMMD日 HH:mm',\n        llll : 'YYYY年MMMD日dddd HH:mm'\n    },\n    meridiemParse: /凌晨|早上|上午|中午|下午|晚上/,\n    meridiemHour : function (hour, meridiem) {\n        if (hour === 12) {\n            hour = 0;\n        }\n        if (meridiem === '凌晨' || meridiem === '早上' || meridiem === '上午') {\n            return hour;\n        } else if (meridiem === '中午') {\n            return hour >= 11 ? hour : hour + 12;\n        } else if (meridiem === '下午' || meridiem === '晚上') {\n            return hour + 12;\n        }\n    },\n    meridiem : function (hour, minute, isLower) {\n        var hm = hour * 100 + minute;\n        if (hm < 600) {\n            return '凌晨';\n        } else if (hm < 900) {\n            return '早上';\n        } else if (hm < 1130) {\n            return '上午';\n        } else if (hm < 1230) {\n            return '中午';\n        } else if (hm < 1800) {\n            return '下午';\n        } else {\n            return '晚上';\n        }\n    },\n    calendar : {\n        sameDay : '[今天]LT',\n        nextDay : '[明天]LT',\n        nextWeek : '[下]ddddLT',\n        lastDay : '[昨天]LT',\n        lastWeek : '[上]ddddLT',\n        sameElse : 'L'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}(日|月|週)/,\n    ordinal : function (number, period) {\n        switch (period) {\n            case 'd' :\n            case 'D' :\n            case 'DDD' :\n                return number + '日';\n            case 'M' :\n                return number + '月';\n            case 'w' :\n            case 'W' :\n                return number + '週';\n            default :\n                return number;\n        }\n    },\n    relativeTime : {\n        future : '%s內',\n        past : '%s前',\n        s : '幾秒',\n        m : '1 分鐘',\n        mm : '%d 分鐘',\n        h : '1 小時',\n        hh : '%d 小時',\n        d : '1 天',\n        dd : '%d 天',\n        M : '1 個月',\n        MM : '%d 個月',\n        y : '1 年',\n        yy : '%d 年'\n    }\n});\n\nhooks.locale('en');\n\nreturn hooks;\n\n})));\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/min/tests.js",
    "content": "\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\n\n\nfunction localeModule (name, lifecycle) {\n    QUnit.module('locale:' + name, {\n        setup : function () {\n            moment.locale(name);\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            moment.locale('en');\n            teardownDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n    defineCommonLocaleTests(name, -1, -1);\n}\n\nlocaleModule('af');\n\ntest('parse', function (assert) {\n    var tests = 'Januarie Jan_Februarie Feb_Maart Mrt_April Apr_Mei Mei_Junie Jun_Julie Jul_Augustus Aug_September Sep_Oktober Okt_November Nov_Desember Des'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, MMMM Do YYYY, h:mm:ss a',      'Sondag, Februarie 14de 2010, 3:25:50 nm'],\n            ['ddd, hA',                            'Son, 3NM'],\n            ['M Mo MM MMMM MMM',                   '2 2de 02 Februarie Feb'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14de 14'],\n            ['d do dddd ddd dd',                   '0 0de Sondag Son So'],\n            ['DDD DDDo DDDD',                      '45 45ste 045'],\n            ['w wo ww',                            '6 6de 06'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'nm NM'],\n            ['[the] DDDo [day of the year]',       'the 45ste day of the year'],\n            ['LT',                                 '15:25'],\n            ['LTS',                                '15:25:50'],\n            ['L',                                  '14/02/2010'],\n            ['LL',                                 '14 Februarie 2010'],\n            ['LLL',                                '14 Februarie 2010 15:25'],\n            ['LLLL',                               'Sondag, 14 Februarie 2010 15:25'],\n            ['l',                                  '14/2/2010'],\n            ['ll',                                 '14 Feb 2010'],\n            ['lll',                                '14 Feb 2010 15:25'],\n            ['llll',                               'Son, 14 Feb 2010 15:25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1ste', '1ste');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2de', '2de');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3de', '3de');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4de', '4de');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5de', '5de');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6de', '6de');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7de', '7de');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8ste', '8ste');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9de', '9de');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10de', '10de');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11de', '11de');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12de', '12de');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13de', '13de');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14de', '14de');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15de', '15de');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16de', '16de');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17de', '17de');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18de', '18de');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19de', '19de');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20ste', '20ste');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21ste', '21ste');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22ste', '22ste');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23ste', '23ste');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24ste', '24ste');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25ste', '25ste');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26ste', '26ste');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27ste', '27ste');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28ste', '28ste');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29ste', '29ste');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30ste', '30ste');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31ste', '31ste');\n});\n\ntest('format month', function (assert) {\n    var expected = 'Januarie Jan_Februarie Feb_Maart Mrt_April Apr_Mei Mei_Junie Jun_Julie Jul_Augustus Aug_September Sep_Oktober Okt_November Nov_Desember Des'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'Sondag Son So_Maandag Maa Ma_Dinsdag Din Di_Woensdag Woe Wo_Donderdag Don Do_Vrydag Vry Vr_Saterdag Sat Sa'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  '\\'n paar sekondes', '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  '\\'n minuut',      '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  '\\'n minuut',      '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 minute',     '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 minute',    '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  '\\'n uur',       '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  '\\'n uur',       '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 ure',       '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 ure',       '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 ure',      '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  '\\'n dag',         '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  '\\'n dag',         '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 dae',        '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   '\\'n dag',         '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 dae',        '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 dae',       '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  '\\'n maand',       '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  '\\'n maand',       '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  '\\'n maand',       '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 maande',      '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 maande',      '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 maande',      '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   '\\'n maand',       '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 maande',      '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), '\\'n jaar',        '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 jaar',       '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   '\\'n jaar',        '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 jaar',       '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'oor \\'n paar sekondes',  'prefix');\n    assert.equal(moment(0).from(30000), '\\'n paar sekondes gelede', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), '\\'n paar sekondes gelede',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'oor \\'n paar sekondes', 'in a few seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), 'oor 5 dae', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'Vandag om 12:00',     'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'Vandag om 12:25',     'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'Vandag om 13:00',     'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'Môre om 12:00',       'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'Vandag om 11:00',     'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'Gister om 12:00',     'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('dddd [om] LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd [om] LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd [om] LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('[Laas] dddd [om] LT'),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[Laas] dddd [om] LT'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[Laas] dddd [om] LT'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2012, 0,  1]).format('w ww wo'), '52 52 52ste', 'Jan  1 2012 should be week 52');\n    assert.equal(moment([2012, 0,  2]).format('w ww wo'),   '1 01 1ste', 'Jan  2 2012 should be week 1');\n    assert.equal(moment([2012, 0,  8]).format('w ww wo'),   '1 01 1ste', 'Jan  8 2012 should be week 1');\n    assert.equal(moment([2012, 0,  9]).format('w ww wo'),    '2 02 2de', 'Jan  9 2012 should be week 2');\n    assert.equal(moment([2012, 0, 15]).format('w ww wo'),    '2 02 2de', 'Jan 15 2012 should be week 2');\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\n\n\nfunction localeModule (name, lifecycle) {\n    QUnit.module('locale:' + name, {\n        setup : function () {\n            moment.locale(name);\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            moment.locale('en');\n            teardownDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n    defineCommonLocaleTests(name, -1, -1);\n}\n\nlocaleModule('ar-dz');\n\ntest('parse', function (assert) {\n    var tests = 'جانفي:جانفي_فيفري:فيفري_مارس:مارس_أفريل:أفريل_ماي:ماي_جوان:جوان_جويلية:جويلية_أوت:أوت_سبتمبر:سبتمبر_أكتوبر:أكتوبر_نوفمبر:نوفمبر_ديسمبر:ديسمبر'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(':');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, MMMM Do YYYY, h:mm:ss a',      'الأحد, فيفري 14 2010, 3:25:50 pm'],\n            ['ddd, hA',                            'احد, 3PM'],\n            ['M Mo MM MMMM MMM',                   '2 2 02 فيفري فيفري'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14 14'],\n            ['d do dddd ddd dd',                   '0 0 الأحد احد أح'],\n            ['DDD DDDo DDDD',                      '45 45 045'],\n            ['w wo ww',                            '7 7 07'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'pm PM'],\n            ['[the] DDDo [day of the year]',       'the 45 day of the year'],\n            ['LT',                                 '15:25'],\n            ['LTS',                                '15:25:50'],\n            ['L',                                  '14/02/2010'],\n            ['LL',                                 '14 فيفري 2010'],\n            ['LLL',                                '14 فيفري 2010 15:25'],\n            ['LLLL',                               'الأحد 14 فيفري 2010 15:25'],\n            ['l',                                  '14/2/2010'],\n            ['ll',                                 '14 فيفري 2010'],\n            ['lll',                                '14 فيفري 2010 15:25'],\n            ['llll',                               'احد 14 فيفري 2010 15:25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1', '1');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2', '2');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3', '3');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4', '4');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5', '5');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6', '6');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7', '7');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8', '8');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9', '9');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10', '10');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11', '11');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12', '12');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13', '13');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14', '14');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15', '15');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16', '16');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17', '17');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18', '18');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19', '19');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20', '20');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21', '21');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22', '22');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23', '23');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24', '24');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25', '25');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26', '26');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27', '27');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28', '28');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29', '29');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30', '30');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31', '31');\n});\n\ntest('format month', function (assert) {\n    var expected = 'جانفي جانفي_فيفري فيفري_مارس مارس_أفريل أفريل_ماي ماي_جوان جوان_جويلية جويلية_أوت أوت_سبتمبر سبتمبر_أكتوبر أكتوبر_نوفمبر نوفمبر_ديسمبر ديسمبر'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'الأحد احد أح_الإثنين اثنين إث_الثلاثاء ثلاثاء ثلا_الأربعاء اربعاء أر_الخميس خميس خم_الجمعة جمعة جم_السبت سبت سب'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'ثوان', '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'دقيقة',      '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'دقيقة',      '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 دقائق',     '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 دقائق',    '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'ساعة',       '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'ساعة',       '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 ساعات',       '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 ساعات',       '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 ساعات',      '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'يوم',         '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'يوم',         '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 أيام',        '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'يوم',         '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 أيام',        '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 أيام',       '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'شهر',       '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'شهر',       '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'شهر',       '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 أشهر',      '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 أشهر',      '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 أشهر',      '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'شهر',       '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 أشهر',      '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'سنة',        '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 سنوات',       '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'سنة',        '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 سنوات',       '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'في ثوان',  'prefix');\n    assert.equal(moment(0).from(30000), 'منذ ثوان', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'منذ ثوان',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'في ثوان', 'in a few seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), 'في 5 أيام', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'اليوم على الساعة 12:00',     'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'اليوم على الساعة 12:25',     'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'اليوم على الساعة 13:00',     'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'غدا على الساعة 12:00',      'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'اليوم على الساعة 11:00',     'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'أمس على الساعة 12:00',     'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('dddd [على الساعة] LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd [على الساعة] LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd [على الساعة] LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('dddd [على الساعة] LT'),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd [على الساعة] LT'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd [على الساعة] LT'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2016, 1, 4]).format('w ww wo'), '5 05 5', 'Feb 4 2016 should be week 5');\n    assert.equal(moment([2016,  0,  6]).format('w ww wo'), '1 01 1', 'Jan  6 2016 should be week 1');\n    assert.equal(moment([2016,  0,  7]).format('w ww wo'), '1 01 1', 'Jan  7 2016 should be week 1');\n    assert.equal(moment([2016,  0, 13]).format('w ww wo'), '2 02 2', 'Jan 13 2016 should be week 2');\n    assert.equal(moment([2016,  0, 14]).format('w ww wo'), '2 02 2', 'Jan 14 2016 should be week 2');\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\n\n\nfunction localeModule (name, lifecycle) {\n    QUnit.module('locale:' + name, {\n        setup : function () {\n            moment.locale(name);\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            moment.locale('en');\n            teardownDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n    defineCommonLocaleTests(name, -1, -1);\n}\n\nlocaleModule('ar-kw');\n\ntest('parse', function (assert) {\n    var tests = 'يناير:يناير_فبراير:فبراير_مارس:مارس_أبريل:أبريل_ماي:ماي_يونيو:يونيو_يوليوز:يوليوز_غشت:غشت_شتنبر:شتنبر_أكتوبر:أكتوبر_نونبر:نونبر_دجنبر:دجنبر'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(':');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, MMMM Do YYYY, h:mm:ss a',      'الأحد, فبراير 14 2010, 3:25:50 pm'],\n            ['ddd, hA',                            'احد, 3PM'],\n            ['M Mo MM MMMM MMM',                   '2 2 02 فبراير فبراير'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14 14'],\n            ['d do dddd ddd dd',                   '0 0 الأحد احد ح'],\n            ['DDD DDDo DDDD',                      '45 45 045'],\n            ['w wo ww',                            '9 9 09'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'pm PM'],\n            ['[the] DDDo [day of the year]',       'the 45 day of the year'],\n            ['LT',                                 '15:25'],\n            ['LTS',                                '15:25:50'],\n            ['L',                                  '14/02/2010'],\n            ['LL',                                 '14 فبراير 2010'],\n            ['LLL',                                '14 فبراير 2010 15:25'],\n            ['LLLL',                               'الأحد 14 فبراير 2010 15:25'],\n            ['l',                                  '14/2/2010'],\n            ['ll',                                 '14 فبراير 2010'],\n            ['lll',                                '14 فبراير 2010 15:25'],\n            ['llll',                               'احد 14 فبراير 2010 15:25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1', '1');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2', '2');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3', '3');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4', '4');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5', '5');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6', '6');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7', '7');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8', '8');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9', '9');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10', '10');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11', '11');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12', '12');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13', '13');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14', '14');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15', '15');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16', '16');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17', '17');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18', '18');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19', '19');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20', '20');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21', '21');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22', '22');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23', '23');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24', '24');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25', '25');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26', '26');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27', '27');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28', '28');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29', '29');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30', '30');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31', '31');\n});\n\ntest('format month', function (assert) {\n    var expected = 'يناير يناير_فبراير فبراير_مارس مارس_أبريل أبريل_ماي ماي_يونيو يونيو_يوليوز يوليوز_غشت غشت_شتنبر شتنبر_أكتوبر أكتوبر_نونبر نونبر_دجنبر دجنبر'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'الأحد احد ح_الإتنين اتنين ن_الثلاثاء ثلاثاء ث_الأربعاء اربعاء ر_الخميس خميس خ_الجمعة جمعة ج_السبت سبت س'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'ثوان', '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'دقيقة',      '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'دقيقة',      '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 دقائق',     '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 دقائق',    '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'ساعة',       '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'ساعة',       '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 ساعات',       '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 ساعات',       '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 ساعات',      '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'يوم',         '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'يوم',         '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 أيام',        '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'يوم',         '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 أيام',        '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 أيام',       '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'شهر',       '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'شهر',       '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'شهر',       '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 أشهر',      '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 أشهر',      '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 أشهر',      '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'شهر',       '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 أشهر',      '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'سنة',        '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 سنوات',       '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'سنة',        '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 سنوات',       '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'في ثوان',  'prefix');\n    assert.equal(moment(0).from(30000), 'منذ ثوان', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'منذ ثوان',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'في ثوان', 'in a few seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), 'في 5 أيام', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'اليوم على الساعة 12:00',     'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'اليوم على الساعة 12:25',     'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'اليوم على الساعة 13:00',     'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'غدا على الساعة 12:00',      'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'اليوم على الساعة 11:00',     'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'أمس على الساعة 12:00',     'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('dddd [على الساعة] LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd [على الساعة] LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd [على الساعة] LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('dddd [على الساعة] LT'),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd [على الساعة] LT'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd [على الساعة] LT'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2011, 11, 31]).format('w ww wo'), '1 01 1', 'Dec 31 2011 should be week 1');\n    assert.equal(moment([2012,  0,  1]).format('w ww wo'), '2 02 2', 'Jan  1 2012 should be week 2');\n    assert.equal(moment([2012,  0,  8]).format('w ww wo'), '3 03 3', 'Jan  8 2012 should be week 3');\n    assert.equal(moment([2012,  0, 14]).format('w ww wo'), '3 03 3', 'Jan 14 2012 should be week 3');\n    assert.equal(moment([2012,  0, 15]).format('w ww wo'), '4 04 4', 'Jan 15 2012 should be week 4');\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\n\n\nfunction localeModule (name, lifecycle) {\n    QUnit.module('locale:' + name, {\n        setup : function () {\n            moment.locale(name);\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            moment.locale('en');\n            teardownDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n    defineCommonLocaleTests(name, -1, -1);\n}\n\nlocaleModule('ar-ly');\n\nvar months = [\n    'يناير',\n    'فبراير',\n    'مارس',\n    'أبريل',\n    'مايو',\n    'يونيو',\n    'يوليو',\n    'أغسطس',\n    'سبتمبر',\n    'أكتوبر',\n    'نوفمبر',\n    'ديسمبر'\n];\n\ntest('parse', function (assert) {\n    var tests = months, i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1) + ' instead is month ' + moment(input, mmm).month());\n    }\n    for (i = 0; i < 12; i++) {\n        equalTest(tests[i], 'MMM', i);\n        equalTest(tests[i], 'MMM', i);\n        equalTest(tests[i], 'MMMM', i);\n        equalTest(tests[i], 'MMMM', i);\n        equalTest(tests[i].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, MMMM Do YYYY, h:mm:ss a',      'الأحد، فبراير 14 2010، 3:25:50 م'],\n            ['ddd, hA',                            'أحد، 3م'],\n            ['M Mo MM MMMM MMM',                   '2 2 02 فبراير فبراير'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14 14'],\n            ['d do dddd ddd dd',                   '0 0 الأحد أحد ح'],\n            ['DDD DDDo DDDD',                      '45 45 045'],\n            ['w wo ww',                            '8 8 08'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'م م'],\n            ['[the] DDDo [day of the year]',       'the 45 day of the year'],\n            ['LT',                                 '15:25'],\n            ['LTS',                                '15:25:50'],\n            ['L',                                  '14/\\u200f2/\\u200f2010'],\n            ['LL',                                 '14 فبراير 2010'],\n            ['LLL',                                '14 فبراير 2010 15:25'],\n            ['LLLL',                               'الأحد 14 فبراير 2010 15:25'],\n            ['l',                                  '14/\\u200f2/\\u200f2010'],\n            ['ll',                                 '14 فبراير 2010'],\n            ['lll',                                '14 فبراير 2010 15:25'],\n            ['llll',                               'أحد 14 فبراير 2010 15:25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1', '1');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2', '2');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3', '3');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4', '4');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5', '5');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6', '6');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7', '7');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8', '8');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9', '9');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10', '10');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11', '11');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12', '12');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13', '13');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14', '14');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15', '15');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16', '16');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17', '17');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18', '18');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19', '19');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20', '20');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21', '21');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22', '22');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23', '23');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24', '24');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25', '25');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26', '26');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27', '27');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28', '28');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29', '29');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30', '30');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31', '31');\n});\n\ntest('format month', function (assert) {\n    var expected = months, i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM'), expected[i], expected[i]);\n        assert.equal(moment([2011, i, 1]).format('MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'الأحد أحد ح_الإثنين إثنين ن_الثلاثاء ثلاثاء ث_الأربعاء أربعاء ر_الخميس خميس خ_الجمعة جمعة ج_السبت سبت س'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  '44 ثانية', '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'دقيقة واحدة',      '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'دقيقة واحدة',      '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  'دقيقتان',     '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 دقيقة',    '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'ساعة واحدة',       '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'ساعة واحدة',       '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  'ساعتان',       '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 ساعات',       '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 ساعة',      '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'يوم واحد',         '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'يوم واحد',         '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  'يومان',        '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'يوم واحد',         '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 أيام',        '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 يومًا',       '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'شهر واحد',       '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'شهر واحد',       '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'شهر واحد',       '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  'شهران',      '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  'شهران',      '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 أشهر',      '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'شهر واحد',       '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 أشهر',      '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'عام واحد',        '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), 'عامان',       '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'عام واحد',        '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 أعوام',       '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'بعد 30 ثانية',  'prefix');\n    assert.equal(moment(0).from(30000), 'منذ 30 ثانية', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'منذ ثانية واحدة',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'بعد 30 ثانية', 'in a few seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), 'بعد 5 أيام', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'اليوم عند الساعة 12:00',     'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'اليوم عند الساعة 12:25',     'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'اليوم عند الساعة 13:00',     'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'غدًا عند الساعة 12:00',      'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'اليوم عند الساعة 11:00',     'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'أمس عند الساعة 12:00',       'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('dddd [عند الساعة] LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd [عند الساعة] LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd [عند الساعة] LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('dddd [عند الساعة] LT'),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd [عند الساعة] LT'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd [عند الساعة] LT'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('weeks year starting wednesday custom', function (assert) {\n    assert.equal(moment('2003 1 6', 'gggg w d').format('YYYY-MM-DD'), '2002-12-28', 'Week 1 of 2003 should be Dec 28 2002');\n    assert.equal(moment('2003 1 0', 'gggg w e').format('YYYY-MM-DD'), '2002-12-28', 'Week 1 of 2003 should be Dec 28 2002');\n    assert.equal(moment('2003 1 6', 'gggg w d').format('gggg w d'), '2003 1 6', 'Saturday of week 1 of 2003 parsed should be formatted as 2003 1 6');\n    assert.equal(moment('2003 1 0', 'gggg w e').format('gggg w e'), '2003 1 0', '1st day of week 1 of 2003 parsed should be formatted as 2003 1 0');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2011, 11, 31]).format('w ww wo'), '1 01 1', 'Dec 31 2011 should be week 1');\n    assert.equal(moment([2012,  0,  6]).format('w ww wo'), '1 01 1', 'Jan  6 2012 should be week 1');\n    assert.equal(moment([2012,  0,  7]).format('w ww wo'), '2 02 2', 'Jan  7 2012 should be week 2');\n    assert.equal(moment([2012,  0, 13]).format('w ww wo'), '2 02 2', 'Jan 13 2012 should be week 2');\n    assert.equal(moment([2012,  0, 14]).format('w ww wo'), '3 03 3', 'Jan 14 2012 should be week 3');\n});\n\ntest('no leading zeros in long date formats', function (assert) {\n    var i, j, longDateStr, shortDateStr;\n    for (i = 1; i <= 9; ++i) {\n        for (j = 1; j <= 9; ++j) {\n            longDateStr = moment([2014, i, j]).format('L');\n            shortDateStr = moment([2014, i, j]).format('l');\n            assert.equal(longDateStr, shortDateStr, 'should not have leading zeros in month or day');\n        }\n    }\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\n\n\nfunction localeModule (name, lifecycle) {\n    QUnit.module('locale:' + name, {\n        setup : function () {\n            moment.locale(name);\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            moment.locale('en');\n            teardownDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n    defineCommonLocaleTests(name, -1, -1);\n}\n\nlocaleModule('ar-ma');\n\ntest('parse', function (assert) {\n    var tests = 'يناير:يناير_فبراير:فبراير_مارس:مارس_أبريل:أبريل_ماي:ماي_يونيو:يونيو_يوليوز:يوليوز_غشت:غشت_شتنبر:شتنبر_أكتوبر:أكتوبر_نونبر:نونبر_دجنبر:دجنبر'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(':');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, MMMM Do YYYY, h:mm:ss a',      'الأحد, فبراير 14 2010, 3:25:50 pm'],\n            ['ddd, hA',                            'احد, 3PM'],\n            ['M Mo MM MMMM MMM',                   '2 2 02 فبراير فبراير'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14 14'],\n            ['d do dddd ddd dd',                   '0 0 الأحد احد ح'],\n            ['DDD DDDo DDDD',                      '45 45 045'],\n            ['w wo ww',                            '8 8 08'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'pm PM'],\n            ['[the] DDDo [day of the year]',       'the 45 day of the year'],\n            ['LT',                                 '15:25'],\n            ['LTS',                                '15:25:50'],\n            ['L',                                  '14/02/2010'],\n            ['LL',                                 '14 فبراير 2010'],\n            ['LLL',                                '14 فبراير 2010 15:25'],\n            ['LLLL',                               'الأحد 14 فبراير 2010 15:25'],\n            ['l',                                  '14/2/2010'],\n            ['ll',                                 '14 فبراير 2010'],\n            ['lll',                                '14 فبراير 2010 15:25'],\n            ['llll',                               'احد 14 فبراير 2010 15:25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1', '1');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2', '2');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3', '3');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4', '4');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5', '5');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6', '6');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7', '7');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8', '8');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9', '9');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10', '10');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11', '11');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12', '12');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13', '13');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14', '14');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15', '15');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16', '16');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17', '17');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18', '18');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19', '19');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20', '20');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21', '21');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22', '22');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23', '23');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24', '24');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25', '25');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26', '26');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27', '27');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28', '28');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29', '29');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30', '30');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31', '31');\n});\n\ntest('format month', function (assert) {\n    var expected = 'يناير يناير_فبراير فبراير_مارس مارس_أبريل أبريل_ماي ماي_يونيو يونيو_يوليوز يوليوز_غشت غشت_شتنبر شتنبر_أكتوبر أكتوبر_نونبر نونبر_دجنبر دجنبر'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'الأحد احد ح_الإتنين اتنين ن_الثلاثاء ثلاثاء ث_الأربعاء اربعاء ر_الخميس خميس خ_الجمعة جمعة ج_السبت سبت س'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'ثوان', '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'دقيقة',      '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'دقيقة',      '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 دقائق',     '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 دقائق',    '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'ساعة',       '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'ساعة',       '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 ساعات',       '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 ساعات',       '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 ساعات',      '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'يوم',         '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'يوم',         '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 أيام',        '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'يوم',         '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 أيام',        '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 أيام',       '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'شهر',       '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'شهر',       '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'شهر',       '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 أشهر',      '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 أشهر',      '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 أشهر',      '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'شهر',       '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 أشهر',      '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'سنة',        '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 سنوات',       '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'سنة',        '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 سنوات',       '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'في ثوان',  'prefix');\n    assert.equal(moment(0).from(30000), 'منذ ثوان', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'منذ ثوان',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'في ثوان', 'in a few seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), 'في 5 أيام', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'اليوم على الساعة 12:00',     'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'اليوم على الساعة 12:25',     'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'اليوم على الساعة 13:00',     'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'غدا على الساعة 12:00',      'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'اليوم على الساعة 11:00',     'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'أمس على الساعة 12:00',     'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('dddd [على الساعة] LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd [على الساعة] LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd [على الساعة] LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('dddd [على الساعة] LT'),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd [على الساعة] LT'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd [على الساعة] LT'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2011, 11, 31]).format('w ww wo'), '1 01 1', 'Dec 31 2011 should be week 1');\n    assert.equal(moment([2012,  0,  6]).format('w ww wo'), '1 01 1', 'Jan  6 2012 should be week 1');\n    assert.equal(moment([2012,  0,  7]).format('w ww wo'), '2 02 2', 'Jan  7 2012 should be week 2');\n    assert.equal(moment([2012,  0, 13]).format('w ww wo'), '2 02 2', 'Jan 13 2012 should be week 2');\n    assert.equal(moment([2012,  0, 14]).format('w ww wo'), '3 03 3', 'Jan 14 2012 should be week 3');\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\n\n\nfunction localeModule (name, lifecycle) {\n    QUnit.module('locale:' + name, {\n        setup : function () {\n            moment.locale(name);\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            moment.locale('en');\n            teardownDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n    defineCommonLocaleTests(name, -1, -1);\n}\n\nlocaleModule('ar-sa');\n\ntest('parse', function (assert) {\n    var tests = 'يناير:يناير_فبراير:فبراير_مارس:مارس_أبريل:أبريل_مايو:مايو_يونيو:يونيو_يوليو:يوليو_أغسطس:أغسطس_سبتمبر:سبتمبر_أكتوبر:أكتوبر_نوفمبر:نوفمبر_ديسمبر:ديسمبر'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1) + ' instead is month ' + moment(input, mmm).month());\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(':');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, MMMM Do YYYY, h:mm:ss a',      'الأحد، فبراير ١٤ ٢٠١٠، ٣:٢٥:٥٠ م'],\n            ['ddd, hA',                            'أحد، ٣م'],\n            ['M Mo MM MMMM MMM',                   '٢ ٢ ٠٢ فبراير فبراير'],\n            ['YYYY YY',                            '٢٠١٠ ١٠'],\n            ['D Do DD',                            '١٤ ١٤ ١٤'],\n            ['d do dddd ddd dd',                   '٠ ٠ الأحد أحد ح'],\n            ['DDD DDDo DDDD',                      '٤٥ ٤٥ ٠٤٥'],\n            ['w wo ww',                            '٨ ٨ ٠٨'],\n            ['h hh',                               '٣ ٠٣'],\n            ['H HH',                               '١٥ ١٥'],\n            ['m mm',                               '٢٥ ٢٥'],\n            ['s ss',                               '٥٠ ٥٠'],\n            ['a A',                                'م م'],\n            ['[the] DDDo [day of the year]',       'the ٤٥ day of the year'],\n            ['LT',                                 '١٥:٢٥'],\n            ['LTS',                                '١٥:٢٥:٥٠'],\n            ['L',                                  '١٤/٠٢/٢٠١٠'],\n            ['LL',                                 '١٤ فبراير ٢٠١٠'],\n            ['LLL',                                '١٤ فبراير ٢٠١٠ ١٥:٢٥'],\n            ['LLLL',                               'الأحد ١٤ فبراير ٢٠١٠ ١٥:٢٥'],\n            ['l',                                  '١٤/٢/٢٠١٠'],\n            ['ll',                                 '١٤ فبراير ٢٠١٠'],\n            ['lll',                                '١٤ فبراير ٢٠١٠ ١٥:٢٥'],\n            ['llll',                               'أحد ١٤ فبراير ٢٠١٠ ١٥:٢٥']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '١', '1');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '٢', '2');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '٣', '3');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '٤', '4');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '٥', '5');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '٦', '6');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '٧', '7');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '٨', '8');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '٩', '9');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '١٠', '10');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '١١', '11');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '١٢', '12');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '١٣', '13');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '١٤', '14');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '١٥', '15');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '١٦', '16');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '١٧', '17');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '١٨', '18');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '١٩', '19');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '٢٠', '20');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '٢١', '21');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '٢٢', '22');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '٢٣', '23');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '٢٤', '24');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '٢٥', '25');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '٢٦', '26');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '٢٧', '27');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '٢٨', '28');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '٢٩', '29');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '٣٠', '30');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '٣١', '31');\n});\n\ntest('format month', function (assert) {\n    var expected = 'يناير يناير_فبراير فبراير_مارس مارس_أبريل أبريل_مايو مايو_يونيو يونيو_يوليو يوليو_أغسطس أغسطس_سبتمبر سبتمبر_أكتوبر أكتوبر_نوفمبر نوفمبر_ديسمبر ديسمبر'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'الأحد أحد ح_الإثنين إثنين ن_الثلاثاء ثلاثاء ث_الأربعاء أربعاء ر_الخميس خميس خ_الجمعة جمعة ج_السبت سبت س'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'ثوان', '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'دقيقة',      '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'دقيقة',      '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '٢ دقائق',     '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '٤٤ دقائق',    '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'ساعة',       '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'ساعة',       '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '٢ ساعات',       '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '٥ ساعات',       '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '٢١ ساعات',      '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'يوم',         '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'يوم',         '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '٢ أيام',        '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'يوم',         '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '٥ أيام',        '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '٢٥ أيام',       '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'شهر',       '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'شهر',       '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'شهر',       '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '٢ أشهر',      '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '٢ أشهر',      '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '٣ أشهر',      '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'شهر',       '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '٥ أشهر',      '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'سنة',        '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '٢ سنوات',       '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'سنة',        '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '٥ سنوات',       '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'في ثوان',  'prefix');\n    assert.equal(moment(0).from(30000), 'منذ ثوان', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'منذ ثوان',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'في ثوان', 'in a few seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), 'في ٥ أيام', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'اليوم على الساعة ١٢:٠٠',     'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'اليوم على الساعة ١٢:٢٥',     'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'اليوم على الساعة ١٣:٠٠',     'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'غدا على الساعة ١٢:٠٠',       'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'اليوم على الساعة ١١:٠٠',     'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'أمس على الساعة ١٢:٠٠',      'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('dddd [على الساعة] LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd [على الساعة] LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd [على الساعة] LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('dddd [على الساعة] LT'),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd [على الساعة] LT'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd [على الساعة] LT'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('weeks year starting wednesday custom', function (assert) {\n    assert.equal(moment('2003 1 6', 'gggg w d').format('YYYY-MM-DD'), '٢٠٠٣-٠١-٠٤', '2003 1 6 : gggg w d');\n    assert.equal(moment('2003 1 0', 'gggg w e').format('YYYY-MM-DD'), '٢٠٠٢-١٢-٢٩', '2003 1 0 : gggg w e');\n    assert.equal(moment('2003 1 6', 'gggg w d').format('gggg w d'), '٢٠٠٣ ١ ٦', '2003 1 6 : gggg w d');\n    assert.equal(moment('2003 1 0', 'gggg w e').format('gggg w e'), '٢٠٠٣ ١ ٠', '2003 1 0 : gggg w e');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2011, 11, 31]).format('w ww wo'), '٥٣ ٥٣ ٥٣', '2011 11 31');\n    assert.equal(moment([2012,  0,  6]).format('w ww wo'), '١ ٠١ ١', '2012 0 6');\n    assert.equal(moment([2012,  0,  7]).format('w ww wo'), '١ ٠١ ١', '2012 0 7');\n    assert.equal(moment([2012,  0, 13]).format('w ww wo'), '٢ ٠٢ ٢', '2012 0 13');\n    assert.equal(moment([2012,  0, 14]).format('w ww wo'), '٢ ٠٢ ٢', '2012 0 14');\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\n\n\nfunction localeModule (name, lifecycle) {\n    QUnit.module('locale:' + name, {\n        setup : function () {\n            moment.locale(name);\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            moment.locale('en');\n            teardownDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n    defineCommonLocaleTests(name, -1, -1);\n}\n\nlocaleModule('ar-tn');\n\ntest('parse', function (assert) {\n    var tests = 'جانفي:جانفي_فيفري:فيفري_مارس:مارس_أفريل:أفريل_ماي:ماي_جوان:جوان_جويلية:جويلية_أوت:أوت_سبتمبر:سبتمبر_أكتوبر:أكتوبر_نوفمبر:نوفمبر_ديسمبر:ديسمبر'.split('_'),\n        i;\n\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(':');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, MMMM Do YYYY, h:mm:ss a', 'الأحد, فيفري 14 2010, 3:25:50 pm'],\n            ['ddd, hA', 'أحد, 3PM'],\n            ['M Mo MM MMMM MMM', '2 2 02 فيفري فيفري'],\n            ['YYYY YY', '2010 10'],\n            ['D Do DD', '14 14 14'],\n            ['d do dddd ddd dd', '0 0 الأحد أحد ح'],\n            ['DDD DDDo DDDD', '45 45 045'],\n            ['w wo ww', '6 6 06'],\n            ['h hh', '3 03'],\n            ['H HH', '15 15'],\n            ['m mm', '25 25'],\n            ['s ss', '50 50'],\n            ['a A', 'pm PM'],\n            ['[the] DDDo [day of the year]', 'the 45 day of the year'],\n            ['LT', '15:25'],\n            ['LTS', '15:25:50'],\n            ['L', '14/02/2010'],\n            ['LL', '14 فيفري 2010'],\n            ['LLL', '14 فيفري 2010 15:25'],\n            ['LLLL', 'الأحد 14 فيفري 2010 15:25'],\n            ['l', '14/2/2010'],\n            ['ll', '14 فيفري 2010'],\n            ['lll', '14 فيفري 2010 15:25'],\n            ['llll', 'أحد 14 فيفري 2010 15:25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1', '1');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2', '2');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3', '3');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4', '4');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5', '5');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6', '6');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7', '7');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8', '8');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9', '9');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10', '10');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11', '11');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12', '12');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13', '13');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14', '14');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15', '15');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16', '16');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17', '17');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18', '18');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19', '19');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20', '20');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21', '21');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22', '22');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23', '23');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24', '24');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25', '25');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26', '26');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27', '27');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28', '28');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29', '29');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30', '30');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31', '31');\n});\n\ntest('format month', function (assert) {\n    var expected = 'جانفي جانفي_فيفري فيفري_مارس مارس_أفريل أفريل_ماي ماي_جوان جوان_جويلية جويلية_أوت أوت_سبتمبر سبتمبر_أكتوبر أكتوبر_نوفمبر نوفمبر_ديسمبر ديسمبر'.split('_'),\n        i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'الأحد أحد ح_الإثنين إثنين ن_الثلاثاء ثلاثاء ث_الأربعاء أربعاء ر_الخميس خميس خ_الجمعة جمعة ج_السبت سبت س'.split('_'),\n        i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({\n        s: 44\n    }), true), 'ثوان', '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({\n        s: 45\n    }), true), 'دقيقة', '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({\n        s: 89\n    }), true), 'دقيقة', '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({\n        s: 90\n    }), true), '2 دقائق', '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({\n        m: 44\n    }), true), '44 دقائق', '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({\n        m: 45\n    }), true), 'ساعة', '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({\n        m: 89\n    }), true), 'ساعة', '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({\n        m: 90\n    }), true), '2 ساعات', '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({\n        h: 5\n    }), true), '5 ساعات', '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({\n        h: 21\n    }), true), '21 ساعات', '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({\n        h: 22\n    }), true), 'يوم', '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({\n        h: 35\n    }), true), 'يوم', '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({\n        h: 36\n    }), true), '2 أيام', '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({\n        d: 1\n    }), true), 'يوم', '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({\n        d: 5\n    }), true), '5 أيام', '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({\n        d: 25\n    }), true), '25 أيام', '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({\n        d: 26\n    }), true), 'شهر', '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({\n        d: 30\n    }), true), 'شهر', '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({\n        d: 43\n    }), true), 'شهر', '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({\n        d: 46\n    }), true), '2 أشهر', '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({\n        d: 74\n    }), true), '2 أشهر', '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({\n        d: 76\n    }), true), '3 أشهر', '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({\n        M: 1\n    }), true), 'شهر', '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({\n        M: 5\n    }), true), '5 أشهر', '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({\n        d: 345\n    }), true), 'سنة', '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({\n        d: 548\n    }), true), '2 سنوات', '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({\n        y: 1\n    }), true), 'سنة', '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({\n        y: 5\n    }), true), '5 سنوات', '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'في ثوان', 'prefix');\n    assert.equal(moment(0).from(30000), 'منذ ثوان', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'منذ ثوان', 'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({\n        s: 30\n    }).fromNow(), 'في ثوان', 'in a few seconds');\n    assert.equal(moment().add({\n        d: 5\n    }).fromNow(), 'في 5 أيام', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                  'اليوم على الساعة 12:00', 'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),     'اليوم على الساعة 12:25', 'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),      'اليوم على الساعة 13:00', 'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),      'غدا على الساعة 12:00',  'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(), 'اليوم على الساعة 11:00', 'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(), 'أمس على الساعة 12:00',  'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({\n            d: i\n        });\n        assert.equal(m.calendar(), m.format('dddd [على الساعة] LT'), 'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(), m.format('dddd [على الساعة] LT'), 'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(), m.format('dddd [على الساعة] LT'), 'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({\n            d: i\n        });\n        assert.equal(m.calendar(), m.format('dddd [على الساعة] LT'), 'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(), m.format('dddd [على الساعة] LT'), 'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(), m.format('dddd [على الساعة] LT'), 'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({\n            w: 1\n        }),\n        weeksFromNow = moment().add({\n            w: 1\n        });\n\n    assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '1 week ago');\n    assert.equal(weeksFromNow.calendar(), weeksFromNow.format('L'), 'in 1 week');\n\n    weeksAgo = moment().subtract({\n        w: 2\n    });\n    weeksFromNow = moment().add({\n        w: 2\n    });\n\n    assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(), weeksFromNow.format('L'), 'in 2 weeks');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2012, 0,  1]).format('w ww wo'), '52 52 52', 'Jan  1 2012 should be week 52');\n    assert.equal(moment([2012, 0,  2]).format('w ww wo'), '1 01 1', 'Jan  2 2012 should be week 1');\n    assert.equal(moment([2012, 0,  8]).format('w ww wo'), '1 01 1', 'Jan  8 2012 should be week 1');\n    assert.equal(moment([2012, 0,  9]).format('w ww wo'),   '2 02 2', 'Jan  9 2012 should be week 2');\n    assert.equal(moment([2012, 0, 15]).format('w ww wo'),   '2 02 2', 'Jan 15 2012 should be week 2');\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\n\n\nfunction localeModule (name, lifecycle) {\n    QUnit.module('locale:' + name, {\n        setup : function () {\n            moment.locale(name);\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            moment.locale('en');\n            teardownDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n    defineCommonLocaleTests(name, -1, -1);\n}\n\nlocaleModule('ar');\n\nvar months = [\n    'كانون الثاني يناير',\n    'شباط فبراير',\n    'آذار مارس',\n    'نيسان أبريل',\n    'أيار مايو',\n    'حزيران يونيو',\n    'تموز يوليو',\n    'آب أغسطس',\n    'أيلول سبتمبر',\n    'تشرين الأول أكتوبر',\n    'تشرين الثاني نوفمبر',\n    'كانون الأول ديسمبر'\n];\n\ntest('parse', function (assert) {\n    var tests = months, i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1) + ' instead is month ' + moment(input, mmm).month());\n    }\n    for (i = 0; i < 12; i++) {\n        equalTest(tests[i], 'MMM', i);\n        equalTest(tests[i], 'MMM', i);\n        equalTest(tests[i], 'MMMM', i);\n        equalTest(tests[i], 'MMMM', i);\n        equalTest(tests[i].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, MMMM Do YYYY, h:mm:ss a',      'الأحد، شباط فبراير ١٤ ٢٠١٠، ٣:٢٥:٥٠ م'],\n            ['ddd, hA',                            'أحد، ٣م'],\n            ['M Mo MM MMMM MMM',                   '٢ ٢ ٠٢ شباط فبراير شباط فبراير'],\n            ['YYYY YY',                            '٢٠١٠ ١٠'],\n            ['D Do DD',                            '١٤ ١٤ ١٤'],\n            ['d do dddd ddd dd',                   '٠ ٠ الأحد أحد ح'],\n            ['DDD DDDo DDDD',                      '٤٥ ٤٥ ٠٤٥'],\n            ['w wo ww',                            '٨ ٨ ٠٨'],\n            ['h hh',                               '٣ ٠٣'],\n            ['H HH',                               '١٥ ١٥'],\n            ['m mm',                               '٢٥ ٢٥'],\n            ['s ss',                               '٥٠ ٥٠'],\n            ['a A',                                'م م'],\n            ['[the] DDDo [day of the year]',       'the ٤٥ day of the year'],\n            ['LT',                                 '١٥:٢٥'],\n            ['LTS',                                '١٥:٢٥:٥٠'],\n            ['L',                                  '١٤/\\u200f٢/\\u200f٢٠١٠'],\n            ['LL',                                 '١٤ شباط فبراير ٢٠١٠'],\n            ['LLL',                                '١٤ شباط فبراير ٢٠١٠ ١٥:٢٥'],\n            ['LLLL',                               'الأحد ١٤ شباط فبراير ٢٠١٠ ١٥:٢٥'],\n            ['l',                                  '١٤/\\u200f٢/\\u200f٢٠١٠'],\n            ['ll',                                 '١٤ شباط فبراير ٢٠١٠'],\n            ['lll',                                '١٤ شباط فبراير ٢٠١٠ ١٥:٢٥'],\n            ['llll',                               'أحد ١٤ شباط فبراير ٢٠١٠ ١٥:٢٥']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '١', '1');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '٢', '2');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '٣', '3');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '٤', '4');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '٥', '5');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '٦', '6');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '٧', '7');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '٨', '8');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '٩', '9');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '١٠', '10');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '١١', '11');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '١٢', '12');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '١٣', '13');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '١٤', '14');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '١٥', '15');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '١٦', '16');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '١٧', '17');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '١٨', '18');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '١٩', '19');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '٢٠', '20');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '٢١', '21');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '٢٢', '22');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '٢٣', '23');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '٢٤', '24');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '٢٥', '25');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '٢٦', '26');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '٢٧', '27');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '٢٨', '28');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '٢٩', '29');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '٣٠', '30');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '٣١', '31');\n});\n\ntest('format month', function (assert) {\n    var expected = months, i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM'), expected[i], expected[i]);\n        assert.equal(moment([2011, i, 1]).format('MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'الأحد أحد ح_الإثنين إثنين ن_الثلاثاء ثلاثاء ث_الأربعاء أربعاء ر_الخميس خميس خ_الجمعة جمعة ج_السبت سبت س'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  '٤٤ ثانية', '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'دقيقة واحدة',      '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'دقيقة واحدة',      '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  'دقيقتان',     '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '٤٤ دقيقة',    '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'ساعة واحدة',       '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'ساعة واحدة',       '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  'ساعتان',       '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '٥ ساعات',       '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '٢١ ساعة',      '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'يوم واحد',         '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'يوم واحد',         '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  'يومان',        '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'يوم واحد',         '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '٥ أيام',        '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '٢٥ يومًا',       '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'شهر واحد',       '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'شهر واحد',       '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'شهر واحد',       '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  'شهران',      '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  'شهران',      '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '٣ أشهر',      '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'شهر واحد',       '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '٥ أشهر',      '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'عام واحد',        '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), 'عامان',       '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'عام واحد',        '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '٥ أعوام',       '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'بعد ٣٠ ثانية',  'prefix');\n    assert.equal(moment(0).from(30000), 'منذ ٣٠ ثانية', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'منذ ثانية واحدة',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'بعد ٣٠ ثانية', 'in a few seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), 'بعد ٥ أيام', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'اليوم عند الساعة ١٢:٠٠',     'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'اليوم عند الساعة ١٢:٢٥',     'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'اليوم عند الساعة ١٣:٠٠',     'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'غدًا عند الساعة ١٢:٠٠',      'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'اليوم عند الساعة ١١:٠٠',     'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'أمس عند الساعة ١٢:٠٠',       'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('dddd [عند الساعة] LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd [عند الساعة] LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd [عند الساعة] LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('dddd [عند الساعة] LT'),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd [عند الساعة] LT'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd [عند الساعة] LT'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('weeks year starting wednesday custom', function (assert) {\n    assert.equal(moment('2003 1 6', 'gggg w d').format('YYYY-MM-DD'), '٢٠٠٢-١٢-٢٨', 'Week 1 of 2003 should be Dec 28 2002');\n    assert.equal(moment('2003 1 0', 'gggg w e').format('YYYY-MM-DD'), '٢٠٠٢-١٢-٢٨', 'Week 1 of 2003 should be Dec 28 2002');\n    assert.equal(moment('2003 1 6', 'gggg w d').format('gggg w d'), '٢٠٠٣ ١ ٦', 'Saturday of week 1 of 2003 parsed should be formatted as 2003 1 6');\n    assert.equal(moment('2003 1 0', 'gggg w e').format('gggg w e'), '٢٠٠٣ ١ ٠', '1st day of week 1 of 2003 parsed should be formatted as 2003 1 0');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2011, 11, 31]).format('w ww wo'), '١ ٠١ ١', 'Dec 31 2011 should be week 1');\n    assert.equal(moment([2012,  0,  6]).format('w ww wo'), '١ ٠١ ١', 'Jan  6 2012 should be week 1');\n    assert.equal(moment([2012,  0,  7]).format('w ww wo'), '٢ ٠٢ ٢', 'Jan  7 2012 should be week 2');\n    assert.equal(moment([2012,  0, 13]).format('w ww wo'), '٢ ٠٢ ٢', 'Jan 13 2012 should be week 2');\n    assert.equal(moment([2012,  0, 14]).format('w ww wo'), '٣ ٠٣ ٣', 'Jan 14 2012 should be week 3');\n});\n\ntest('no leading zeros in long date formats', function (assert) {\n    var i, j, longDateStr, shortDateStr;\n    for (i = 1; i <= 9; ++i) {\n        for (j = 1; j <= 9; ++j) {\n            longDateStr = moment([2014, i, j]).format('L');\n            shortDateStr = moment([2014, i, j]).format('l');\n            assert.equal(longDateStr, shortDateStr, 'should not have leading zeros in month or day');\n        }\n    }\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\n\n\nfunction localeModule (name, lifecycle) {\n    QUnit.module('locale:' + name, {\n        setup : function () {\n            moment.locale(name);\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            moment.locale('en');\n            teardownDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n    defineCommonLocaleTests(name, -1, -1);\n}\n\nlocaleModule('az');\n\ntest('parse', function (assert) {\n    var tests = 'yanvar yan_fevral fev_mart mar_Aprel apr_may may_iyun iyn_iyul iyl_Avqust avq_sentyabr sen_oktyabr okt_noyabr noy_dekabr dek'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, D MMMM YYYY, HH:mm:ss',        'Bazar, 14 fevral 2010, 15:25:50'],\n            ['ddd, A h',                           'Baz, gündüz 3'],\n            ['M Mo MM MMMM MMM',                   '2 2-nci 02 fevral fev'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14-üncü 14'],\n            ['d do dddd ddd dd',                   '0 0-ıncı Bazar Baz Bz'],\n            ['DDD DDDo DDDD',                      '45 45-inci 045'],\n            ['w wo ww',                            '7 7-nci 07'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'gündüz gündüz'],\n            ['[ilin] DDDo [günü]',                 'ilin 45-inci günü'],\n            ['LT',                                 '15:25'],\n            ['LTS',                                '15:25:50'],\n            ['L',                                  '14.02.2010'],\n            ['LL',                                 '14 fevral 2010'],\n            ['LLL',                                '14 fevral 2010 15:25'],\n            ['LLLL',                               'Bazar, 14 fevral 2010 15:25'],\n            ['l',                                  '14.2.2010'],\n            ['ll',                                 '14 fev 2010'],\n            ['lll',                                '14 fev 2010 15:25'],\n            ['llll',                               'Baz, 14 fev 2010 15:25']\n        ],\n        DDDo = [\n            [359, '360-ıncı'],\n            [199, '200-üncü'],\n            [149, '150-nci']\n        ],\n        dt = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        DDDoDt,\n        i;\n\n    for (i = 0; i < a.length; i++) {\n        assert.equal(dt.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n    for (i = 0; i < DDDo.length; i++) {\n        DDDoDt = moment([2010]);\n        assert.equal(DDDoDt.add(DDDo[i][0], 'days').format('DDDo'), DDDo[i][1], DDDo[i][0] + ' ---> ' + DDDo[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1-inci', '1st');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2-nci', '2nd');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3-üncü', '3rd');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4-üncü', '4th');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5-inci', '5th');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6-ncı', '6th');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7-nci', '7th');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8-inci', '8th');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9-uncu', '9th');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10-uncu', '10th');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11-inci', '11th');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12-nci', '12th');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13-üncü', '13th');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14-üncü', '14th');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15-inci', '15th');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16-ncı', '16th');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17-nci', '17th');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18-inci', '18th');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19-uncu', '19th');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20-nci', '20th');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21-inci', '21th');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22-nci', '22th');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23-üncü', '23th');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24-üncü', '24th');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25-inci', '25th');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26-ncı', '26th');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27-nci', '27th');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28-inci', '28th');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29-uncu', '29th');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30-uncu', '30th');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31-inci', '31st');\n});\n\ntest('format month', function (assert) {\n    var expected = 'yanvar yan_fevral fev_mart mar_aprel apr_may may_iyun iyn_iyul iyl_avqust avq_sentyabr sen_oktyabr okt_noyabr noy_dekabr dek'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'Bazar Baz Bz_Bazar ertəsi BzE BE_Çərşənbə axşamı ÇAx ÇA_Çərşənbə Çər Çə_Cümə axşamı CAx CA_Cümə Cüm Cü_Şənbə Şən Şə'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'birneçə saniyyə', '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'bir dəqiqə',      '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'bir dəqiqə',      '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 dəqiqə',     '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 dəqiqə',    '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'bir saat',       '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'bir saat',       '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 saat',       '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 saat',       '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 saat',      '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'bir gün',         '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'bir gün',         '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 gün',        '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'bir gün',         '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 gün',        '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 gün',       '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'bir ay',       '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'bir ay',       '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 ay',      '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 ay',      '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 ay',      '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'bir ay',       '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 ay',      '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'bir il',        '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 il',       '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'bir il',        '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 il',       '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'birneçə saniyyə sonra',  'prefix');\n    assert.equal(moment(0).from(30000), 'birneçə saniyyə əvvəl', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'birneçə saniyyə əvvəl',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'birneçə saniyyə sonra', 'in a few seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), '5 gün sonra', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'bugün saat 12:00',     'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'bugün saat 12:25',     'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'bugün saat 13:00',     'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'sabah saat 12:00',     'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'bugün saat 11:00',     'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'dünən 12:00',          'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('[gələn həftə] dddd [saat] LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[gələn həftə] dddd [saat] LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[gələn həftə] dddd [saat] LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('[keçən həftə] dddd [saat] LT'),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[keçən həftə] dddd [saat] LT'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[keçən həftə] dddd [saat] LT'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2011, 11, 26]).format('w ww wo'), '1 01 1-inci', 'Dec 26 2011 should be week 1');\n    assert.equal(moment([2012,  0,  1]).format('w ww wo'), '1 01 1-inci', 'Jan  1 2012 should be week 1');\n    assert.equal(moment([2012,  0,  2]).format('w ww wo'), '2 02 2-nci', 'Jan  2 2012 should be week 2');\n    assert.equal(moment([2012,  0,  8]).format('w ww wo'), '2 02 2-nci', 'Jan  8 2012 should be week 2');\n    assert.equal(moment([2012,  0,  9]).format('w ww wo'), '3 03 3-üncü', 'Jan  9 2012 should be week 3');\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\n\n\nfunction localeModule (name, lifecycle) {\n    QUnit.module('locale:' + name, {\n        setup : function () {\n            moment.locale(name);\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            moment.locale('en');\n            teardownDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n    defineCommonLocaleTests(name, -1, -1);\n}\n\nlocaleModule('be');\n\ntest('parse', function (assert) {\n    var tests = 'студзень студ_люты лют_сакавік сак_красавік крас_травень трав_чэрвень чэрв_ліпень ліп_жнівень жнів_верасень вер_кастрычнік каст_лістапад ліст_снежань снеж'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, Do MMMM YYYY, HH:mm:ss',       'нядзеля, 14-га лютага 2010, 15:25:50'],\n            ['ddd, h A',                           'нд, 3 дня'],\n            ['M Mo MM MMMM MMM',                   '2 2-і 02 люты лют'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14-га 14'],\n            ['d do dddd ddd dd',                   '0 0-ы нядзеля нд нд'],\n            ['DDD DDDo DDDD',                      '45 45-ы 045'],\n            ['w wo ww',                            '7 7-ы 07'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'дня дня'],\n            ['DDDo [дзень года]',                   '45-ы дзень года'],\n            ['LT',                                 '15:25'],\n            ['LTS',                                '15:25:50'],\n            ['L',                                  '14.02.2010'],\n            ['LL',                                 '14 лютага 2010 г.'],\n            ['LLL',                                '14 лютага 2010 г., 15:25'],\n            ['LLLL',                               'нядзеля, 14 лютага 2010 г., 15:25'],\n            ['l',                                  '14.2.2010'],\n            ['ll',                                 '14 лют 2010 г.'],\n            ['lll',                                '14 лют 2010 г., 15:25'],\n            ['llll',                               'нд, 14 лют 2010 г., 15:25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format meridiem', function (assert) {\n    assert.equal(moment([2012, 11, 28, 0, 0]).format('A'), 'ночы', 'night');\n    assert.equal(moment([2012, 11, 28, 3, 59]).format('A'), 'ночы', 'night');\n    assert.equal(moment([2012, 11, 28, 4, 0]).format('A'), 'раніцы', 'morning');\n    assert.equal(moment([2012, 11, 28, 11, 59]).format('A'), 'раніцы', 'morning');\n    assert.equal(moment([2012, 11, 28, 12, 0]).format('A'), 'дня', 'afternoon');\n    assert.equal(moment([2012, 11, 28, 16, 59]).format('A'), 'дня', 'afternoon');\n    assert.equal(moment([2012, 11, 28, 17, 0]).format('A'), 'вечара', 'evening');\n    assert.equal(moment([2012, 11, 28, 23, 59]).format('A'), 'вечара', 'evening');\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1-ы', '1-ы');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2-і', '2-і');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3-і', '3-і');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4-ы', '4-ы');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5-ы', '5-ы');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6-ы', '6-ы');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7-ы', '7-ы');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8-ы', '8-ы');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9-ы', '9-ы');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10-ы', '10-ы');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11-ы', '11-ы');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12-ы', '12-ы');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13-ы', '13-ы');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14-ы', '14-ы');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15-ы', '15-ы');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16-ы', '16-ы');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17-ы', '17-ы');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18-ы', '18-ы');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19-ы', '19-ы');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20-ы', '20-ы');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21-ы', '21-ы');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22-і', '22-і');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23-і', '23-і');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24-ы', '24-ы');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25-ы', '25-ы');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26-ы', '26-ы');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27-ы', '27-ы');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28-ы', '28-ы');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29-ы', '29-ы');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30-ы', '30-ы');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31-ы', '31-ы');\n});\n\ntest('format month', function (assert) {\n    var expected = 'студзень студ_люты лют_сакавік сак_красавік крас_травень трав_чэрвень чэрв_ліпень ліп_жнівень жнів_верасень вер_кастрычнік каст_лістапад ліст_снежань снеж'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format month case', function (assert) {\n    var months = {\n        'nominative': 'студзень_люты_сакавік_красавік_травень_чэрвень_ліпень_жнівень_верасень_кастрычнік_лістапад_снежань'.split('_'),\n        'accusative': 'студзеня_лютага_сакавіка_красавіка_траўня_чэрвеня_ліпеня_жніўня_верасня_кастрычніка_лістапада_снежня'.split('_')\n    }, i;\n    for (i = 0; i < 12; i++) {\n        assert.equal(moment([2011, i, 1]).format('D MMMM'), '1 ' + months.accusative[i], '1 ' + months.accusative[i]);\n        assert.equal(moment([2011, i, 1]).format('MMMM'), months.nominative[i], '1 ' + months.nominative[i]);\n    }\n});\n\ntest('format month case with escaped symbols', function (assert) {\n    var months = {\n        'nominative': 'студзень_люты_сакавік_красавік_травень_чэрвень_ліпень_жнівень_верасень_кастрычнік_лістапад_снежань'.split('_'),\n        'accusative': 'студзеня_лютага_сакавіка_красавіка_траўня_чэрвеня_ліпеня_жніўня_верасня_кастрычніка_лістапада_снежня'.split('_')\n    }, i;\n    for (i = 0; i < 12; i++) {\n        assert.equal(moment([2013, i, 1]).format('D[] MMMM'), '1 ' + months.accusative[i], '1 ' + months.accusative[i]);\n        assert.equal(moment([2013, i, 1]).format('[<i>]D[</i>] [<b>]MMMM[</b>]'), '<i>1</i> <b>' + months.accusative[i] + '</b>', '1 <b>' + months.accusative[i] + '</b>');\n        assert.equal(moment([2013, i, 1]).format('D[-ы дзень] MMMM'), '1-ы дзень ' + months.accusative[i], '1-ы дзень ' + months.accusative[i]);\n        assert.equal(moment([2013, i, 1]).format('D, MMMM'), '1, ' + months.nominative[i], '1, ' + months.nominative[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'нядзеля нд нд_панядзелак пн пн_аўторак ат ат_серада ср ср_чацвер чц чц_пятніца пт пт_субота сб сб'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'некалькі секунд',    '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'хвіліна',   '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'хвіліна',   '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 хвіліны',  '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 31}), true),  '31 хвіліна',  '31 minutes = 31 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 хвіліны', '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'гадзіна',    '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'гадзіна',    '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 гадзіны',    '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 гадзін',    '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 гадзіна',   '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'дзень',      '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'дзень',      '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 дні',     '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'дзень',      '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 дзён',     '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 11}), true),  '11 дзён',     '11 days = 11 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 21}), true),  '21 дзень',     '21 days = 21 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 дзён',    '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'месяц',    '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'месяц',    '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'месяц',    '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 месяцы',   '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 месяцы',   '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 месяцы',   '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'месяц',    '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 месяцаў',   '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'год',     '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 гады',    '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'год',     '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 гадоў',    '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'праз некалькі секунд', 'prefix');\n    assert.equal(moment(0).from(30000), 'некалькі секунд таму', 'suffix');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'праз некалькі секунд', 'in a few seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), 'праз 5 дзён', 'in 5 days');\n    assert.equal(moment().add({m: 31}).fromNow(), 'праз 31 хвіліну', 'in 31 minutes = in 31 minutes');\n    assert.equal(moment().subtract({m: 31}).fromNow(), '31 хвіліну таму', '31 minutes ago = 31 minutes ago');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'Сёння ў 12:00',     'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'Сёння ў 12:25',     'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'Сёння ў 13:00',     'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'Заўтра ў 12:00',    'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'Сёння ў 11:00',     'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'Учора ў 12:00',     'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    function makeFormat(d) {\n        return '[У] dddd [ў] LT';\n    }\n\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format(makeFormat(m)),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format(makeFormat(m)),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format(makeFormat(m)),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n\n    function makeFormat(d) {\n        switch (d.day()) {\n            case 0:\n            case 3:\n            case 5:\n            case 6:\n                return '[У мінулую] dddd [ў] LT';\n            case 1:\n            case 2:\n            case 4:\n                return '[У мінулы] dddd [ў] LT';\n        }\n    }\n\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format(makeFormat(m)),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format(makeFormat(m)),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format(makeFormat(m)),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2011, 11, 26]).format('w ww wo'), '1 01 1-ы', 'Dec 26 2011 should be week 1');\n    assert.equal(moment([2012,  0,  1]).format('w ww wo'), '1 01 1-ы', 'Jan  1 2012 should be week 1');\n    assert.equal(moment([2012,  0,  2]).format('w ww wo'), '2 02 2-і', 'Jan  2 2012 should be week 2');\n    assert.equal(moment([2012,  0,  8]).format('w ww wo'), '2 02 2-і', 'Jan  8 2012 should be week 2');\n    assert.equal(moment([2012,  0,  9]).format('w ww wo'), '3 03 3-і', 'Jan  9 2012 should be week 3');\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\n\n\nfunction localeModule (name, lifecycle) {\n    QUnit.module('locale:' + name, {\n        setup : function () {\n            moment.locale(name);\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            moment.locale('en');\n            teardownDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n    defineCommonLocaleTests(name, -1, -1);\n}\n\nlocaleModule('bg');\n\ntest('parse', function (assert) {\n    var tests = 'януари янр_февруари фев_март мар_април апр_май май_юни юни_юли юли_август авг_септември сеп_октомври окт_ноември ное_декември дек'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, MMMM Do YYYY, H:mm:ss',        'неделя, февруари 14-ти 2010, 15:25:50'],\n            ['ddd, hA',                            'нед, 3PM'],\n            ['M Mo MM MMMM MMM',                   '2 2-ри 02 февруари фев'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14-ти 14'],\n            ['d do dddd ddd dd',                   '0 0-ев неделя нед нд'],\n            ['DDD DDDo DDDD',                      '45 45-ти 045'],\n            ['w wo ww',                            '7 7-ми 07'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'pm PM'],\n            ['[the] DDDo [day of the year]',       'the 45-ти day of the year'],\n            ['LT',                                 '15:25'],\n            ['LTS',                                '15:25:50'],\n            ['L',                                  '14.02.2010'],\n            ['LL',                                 '14 февруари 2010'],\n            ['LLL',                                '14 февруари 2010 15:25'],\n            ['LLLL',                               'неделя, 14 февруари 2010 15:25'],\n            ['l',                                  '14.2.2010'],\n            ['ll',                                 '14 фев 2010'],\n            ['lll',                                '14 фев 2010 15:25'],\n            ['llll',                               'нед, 14 фев 2010 15:25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1-ви', '1-ви');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2-ри', '2-ри');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3-ти', '3-ти');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4-ти', '4-ти');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5-ти', '5-ти');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6-ти', '6-ти');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7-ми', '7-ми');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8-ми', '8-ми');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9-ти', '9-ти');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10-ти', '10-ти');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11-ти', '11-ти');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12-ти', '12-ти');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13-ти', '13-ти');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14-ти', '14-ти');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15-ти', '15-ти');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16-ти', '16-ти');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17-ти', '17-ти');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18-ти', '18-ти');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19-ти', '19-ти');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20-ти', '20-ти');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21-ви', '21-ви');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22-ри', '22-ри');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23-ти', '23-ти');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24-ти', '24-ти');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25-ти', '25-ти');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26-ти', '26-ти');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27-ми', '27-ми');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28-ми', '28-ми');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29-ти', '29-ти');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30-ти', '30-ти');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31-ви', '31-ви');\n});\n\ntest('format month', function (assert) {\n    var expected = 'януари янр_февруари фев_март мар_април апр_май май_юни юни_юли юли_август авг_септември сеп_октомври окт_ноември ное_декември дек'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'неделя нед нд_понеделник пон пн_вторник вто вт_сряда сря ср_четвъртък чет чт_петък пет пт_събота съб сб'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'няколко секунди', '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'минута',          '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'минута',          '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 минути',        '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 минути',       '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'час',             '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'час',             '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 часа',          '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 часа',          '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 часа',         '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'ден',             '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'ден',             '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 дни',           '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'ден',             '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 дни',           '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 дни',          '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'месец',           '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'месец',           '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'месец',           '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 месеца',        '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 месеца',        '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 месеца',        '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'месец',           '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 месеца',        '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'година',          '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 години',        '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'година',          '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 години',        '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'след няколко секунди',  'prefix');\n    assert.equal(moment(0).from(30000), 'преди няколко секунди', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'преди няколко секунди',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'след няколко секунди', 'in a few seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), 'след 5 дни', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'Днес в 12:00',  'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'Днес в 12:25',  'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'Днес в 13:00',  'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'Утре в 12:00',  'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'Днес в 11:00',  'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'Вчера в 12:00', 'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('dddd [в] LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd [в] LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd [в] LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n\n    function makeFormat(d) {\n        switch (d.day()) {\n            case 0:\n            case 3:\n            case 6:\n                return '[В изминалата] dddd [в] LT';\n            case 1:\n            case 2:\n            case 4:\n            case 5:\n                return '[В изминалия] dddd [в] LT';\n        }\n    }\n\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format(makeFormat(m)),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format(makeFormat(m)),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format(makeFormat(m)),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2011, 11, 26]).format('w ww wo'), '1 01 1-ви', 'Dec 26 2011 should be week 1');\n    assert.equal(moment([2012,  0,  1]).format('w ww wo'), '1 01 1-ви', 'Jan  1 2012 should be week 1');\n    assert.equal(moment([2012,  0,  2]).format('w ww wo'), '2 02 2-ри', 'Jan  2 2012 should be week 2');\n    assert.equal(moment([2012,  0,  8]).format('w ww wo'), '2 02 2-ри', 'Jan  8 2012 should be week 2');\n    assert.equal(moment([2012,  0,  9]).format('w ww wo'), '3 03 3-ти', 'Jan  9 2012 should be week 3');\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\n\n\nfunction localeModule (name, lifecycle) {\n    QUnit.module('locale:' + name, {\n        setup : function () {\n            moment.locale(name);\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            moment.locale('en');\n            teardownDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n    defineCommonLocaleTests(name, -1, -1);\n}\n\nlocaleModule('bn');\n\ntest('parse', function (assert) {\n    var tests = 'জানুয়ারী জানু_ফেব্রুয়ারি ফেব_মার্চ মার্চ_এপ্রিল এপ্র_মে মে_জুন জুন_জুলাই জুল_আগস্ট আগ_সেপ্টেম্বর সেপ্ট_অক্টোবর অক্টো_নভেম্বর নভে_ডিসেম্বর ডিসে'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, Do MMMM YYYY, a h:mm:ss সময়',  'রবিবার, ১৪ ফেব্রুয়ারি ২০১০, দুপুর ৩:২৫:৫০ সময়'],\n            ['ddd, a h সময়',                       'রবি, দুপুর ৩ সময়'],\n            ['M Mo MM MMMM MMM',                   '২ ২ ০২ ফেব্রুয়ারি ফেব'],\n            ['YYYY YY',                            '২০১০ ১০'],\n            ['D Do DD',                            '১৪ ১৪ ১৪'],\n            ['d do dddd ddd dd',                   '০ ০ রবিবার রবি রবি'],\n            ['DDD DDDo DDDD',                      '৪৫ ৪৫ ০৪৫'],\n            ['w wo ww',                            '৮ ৮ ০৮'],\n            ['h hh',                               '৩ ০৩'],\n            ['H HH',                               '১৫ ১৫'],\n            ['m mm',                               '২৫ ২৫'],\n            ['s ss',                               '৫০ ৫০'],\n            ['a A',                                'দুপুর দুপুর'],\n            ['LT',                                 'দুপুর ৩:২৫ সময়'],\n            ['LTS',                                'দুপুর ৩:২৫:৫০ সময়'],\n            ['L',                                  '১৪/০২/২০১০'],\n            ['LL',                                 '১৪ ফেব্রুয়ারি ২০১০'],\n            ['LLL',                                '১৪ ফেব্রুয়ারি ২০১০, দুপুর ৩:২৫ সময়'],\n            ['LLLL',                               'রবিবার, ১৪ ফেব্রুয়ারি ২০১০, দুপুর ৩:২৫ সময়'],\n            ['l',                                  '১৪/২/২০১০'],\n            ['ll',                                 '১৪ ফেব ২০১০'],\n            ['lll',                                '১৪ ফেব ২০১০, দুপুর ৩:২৫ সময়'],\n            ['llll',                               'রবি, ১৪ ফেব ২০১০, দুপুর ৩:২৫ সময়']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '১', '১');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '২', '২');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '৩', '৩');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '৪', '৪');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '৫', '৫');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '৬', '৬');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '৭', '৭');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '৮', '৮');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '৯', '৯');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '১০', '১০');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '১১', '১১');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '১২', '১২');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '১৩', '১৩');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '১৪', '১৪');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '১৫', '১৫');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '১৬', '১৬');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '১৭', '১৭');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '১৮', '১৮');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '১৯', '১৯');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '২০', '২০');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '২১', '২১');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '২২', '২২');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '২৩', '২৩');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '২৪', '২৪');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '২৫', '২৫');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '২৬', '২৬');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '২৭', '২৭');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '২৮', '२৮');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '২৯', '২৯');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '৩০', '৩০');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '৩১', '৩১');\n});\n\ntest('format month', function (assert) {\n    var expected = 'জানুয়ারী জানু_ফেব্রুয়ারি ফেব_মার্চ মার্চ_এপ্রিল এপ্র_মে মে_জুন জুন_জুলাই জুল_আগস্ট আগ_সেপ্টেম্বর সেপ্ট_অক্টোবর অক্টো_নভেম্বর নভে_ডিসেম্বর ডিসে'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'রবিবার রবি রবি_সোমবার সোম সোম_মঙ্গলবার মঙ্গল মঙ্গ_বুধবার বুধ বুধ_বৃহস্পতিবার বৃহস্পতি বৃহঃ_শুক্রবার শুক্র শুক্র_শনিবার শনি শনি'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'কয়েক সেকেন্ড', '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'এক মিনিট',      '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'এক মিনিট',      '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '২ মিনিট',     '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '৪৪ মিনিট',    '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'এক ঘন্টা',       '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'এক ঘন্টা',       '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '২ ঘন্টা',       '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '৫ ঘন্টা',       '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '২১ ঘন্টা',      '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'এক দিন',         '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'এক দিন',         '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '২ দিন',        '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'এক দিন',         '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '৫ দিন',        '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '২৫ দিন',       '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'এক মাস',       '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'এক মাস',       '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '২ মাস',      '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '২ মাস',      '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '৩ মাস',      '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'এক মাস',       '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '৫ মাস',      '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'এক বছর',        '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '২ বছর',       '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'এক বছর',        '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '৫ বছর',       '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'কয়েক সেকেন্ড পরে',  'prefix');\n    assert.equal(moment(0).from(30000), 'কয়েক সেকেন্ড আগে', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'কয়েক সেকেন্ড আগে',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'কয়েক সেকেন্ড পরে', 'কয়েক সেকেন্ড পরে');\n    assert.equal(moment().add({d: 5}).fromNow(), '৫ দিন পরে', '৫ দিন পরে');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'আজ দুপুর ১২:০০ সময়',       'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'আজ দুপুর ১২:২৫ সময়',       'Now plus 25 min');\n    assert.equal(moment(a).add({h: 3}).calendar(),       'আজ দুপুর ৩:০০ সময়',        'Now plus 3 hours');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'আগামীকাল দুপুর ১২:০০ সময়', 'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'আজ দুপুর ১১:০০ সময়',       'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'গতকাল দুপুর ১২:০০ সময়',    'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('dddd[,] LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd[,] LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd[,] LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('[গত] dddd[,] LT'),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[গত] dddd[,] LT'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[গত] dddd[,] LT'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('meridiem', function (assert) {\n    assert.equal(moment([2011, 2, 23,  2, 30]).format('a'), 'রাত', 'before dawn');\n    assert.equal(moment([2011, 2, 23,  9, 30]).format('a'), 'সকাল', 'morning');\n    assert.equal(moment([2011, 2, 23, 14, 30]).format('a'), 'দুপুর', 'during day');\n    assert.equal(moment([2011, 2, 23, 17, 30]).format('a'), 'বিকাল', 'evening');\n    assert.equal(moment([2011, 2, 23, 19, 30]).format('a'), 'বিকাল', 'late evening');\n    assert.equal(moment([2011, 2, 23, 21, 20]).format('a'), 'রাত', 'night');\n\n    assert.equal(moment([2011, 2, 23,  2, 30]).format('A'), 'রাত', 'before dawn');\n    assert.equal(moment([2011, 2, 23,  9, 30]).format('A'), 'সকাল', 'morning');\n    assert.equal(moment([2011, 2, 23, 14, 30]).format('A'), 'দুপুর', ' during day');\n    assert.equal(moment([2011, 2, 23, 17, 30]).format('A'), 'বিকাল', 'evening');\n    assert.equal(moment([2011, 2, 23, 19, 30]).format('A'), 'বিকাল', 'late evening');\n    assert.equal(moment([2011, 2, 23, 21, 20]).format('A'), 'রাত', 'night');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2012, 0,  1]).format('w ww wo'), '১ ০১ ১', 'Jan  1 2012 should be week 1');\n    assert.equal(moment([2012, 0,  7]).format('w ww wo'), '১ ০১ ১', 'Jan  7 2012 should be week 1');\n    assert.equal(moment([2012, 0,  8]).format('w ww wo'), '২ ০২ ২', 'Jan  8 2012 should be week 2');\n    assert.equal(moment([2012, 0, 14]).format('w ww wo'), '২ ০২ ২', 'Jan 14 2012 should be week 2');\n    assert.equal(moment([2012, 0, 15]).format('w ww wo'), '৩ ০৩ ৩', 'Jan 15 2012 should be week 3');\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\n\n\nfunction localeModule (name, lifecycle) {\n    QUnit.module('locale:' + name, {\n        setup : function () {\n            moment.locale(name);\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            moment.locale('en');\n            teardownDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n    defineCommonLocaleTests(name, -1, -1);\n}\n\nlocaleModule('bo');\n\ntest('parse', function (assert) {\n    var tests = 'ཟླ་བ་དང་པོ ཟླ་བ་དང་པོ._ཟླ་བ་གཉིས་པ ཟླ་བ་གཉིས་པ_ཟླ་བ་གསུམ་པ ཟླ་བ་གསུམ་པ_ཟླ་བ་བཞི་པ ཟླ་བ་བཞི་པ_ཟླ་བ་ལྔ་པ ཟླ་བ་ལྔ་པ_ཟླ་བ་དྲུག་པ ཟླ་བ་དྲུག་པ_ཟླ་བ་བདུན་པ ཟླ་བ་བདུན་པ_ཟླ་བ་བརྒྱད་པ ཟླ་བ་བརྒྱད་པ_ཟླ་བ་དགུ་པ ཟླ་བ་དགུ་པ_ཟླ་བ་བཅུ་པ ཟླ་བ་བཅུ་པ_ཟླ་བ་བཅུ་གཅིག་པ ཟླ་བ་བཅུ་གཅིག་པ_ཟླ་བ་བཅུ་གཉིས་པ ཟླ་བ་བཅུ་གཉིས་པ'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, Do MMMM YYYY, a h:mm:ss ལ་',  'གཟའ་ཉི་མ་, ༡༤ ཟླ་བ་གཉིས་པ ༢༠༡༠, ཉིན་གུང ༣:༢༥:༥༠ ལ་'],\n            ['ddd, a h ལ་',                       'ཉི་མ་, ཉིན་གུང ༣ ལ་'],\n            ['M Mo MM MMMM MMM',                   '༢ ༢ ༠༢ ཟླ་བ་གཉིས་པ ཟླ་བ་གཉིས་པ'],\n            ['YYYY YY',                            '༢༠༡༠ ༡༠'],\n            ['D Do DD',                            '༡༤ ༡༤ ༡༤'],\n            ['d do dddd ddd dd',                   '༠ ༠ གཟའ་ཉི་མ་ ཉི་མ་ ཉི་མ་'],\n            ['DDD DDDo DDDD',                      '༤༥ ༤༥ ༠༤༥'],\n            ['w wo ww',                            '༨ ༨ ༠༨'],\n            ['h hh',                               '༣ ༠༣'],\n            ['H HH',                               '༡༥ ༡༥'],\n            ['m mm',                               '༢༥ ༢༥'],\n            ['s ss',                               '༥༠ ༥༠'],\n            ['a A',                                'ཉིན་གུང ཉིན་གུང'],\n            ['LT',                                 'ཉིན་གུང ༣:༢༥'],\n            ['LTS',                                'ཉིན་གུང ༣:༢༥:༥༠'],\n            ['L',                                  '༡༤/༠༢/༢༠༡༠'],\n            ['LL',                                 '༡༤ ཟླ་བ་གཉིས་པ ༢༠༡༠'],\n            ['LLL',                                '༡༤ ཟླ་བ་གཉིས་པ ༢༠༡༠, ཉིན་གུང ༣:༢༥'],\n            ['LLLL',                               'གཟའ་ཉི་མ་, ༡༤ ཟླ་བ་གཉིས་པ ༢༠༡༠, ཉིན་གུང ༣:༢༥'],\n            ['l',                                  '༡༤/༢/༢༠༡༠'],\n            ['ll',                                 '༡༤ ཟླ་བ་གཉིས་པ ༢༠༡༠'],\n            ['lll',                                '༡༤ ཟླ་བ་གཉིས་པ ༢༠༡༠, ཉིན་གུང ༣:༢༥'],\n            ['llll',                               'ཉི་མ་, ༡༤ ཟླ་བ་གཉིས་པ ༢༠༡༠, ཉིན་གུང ༣:༢༥']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '༡', '༡');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '༢', '༢');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '༣', '༣');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '༤', '༤');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '༥', '༥');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '༦', '༦');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '༧', '༧');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '༨', '༨');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '༩', '༩');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '༡༠', '༡༠');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '༡༡', '༡༡');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '༡༢', '༡༢');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '༡༣', '༡༣');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '༡༤', '༡༤');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '༡༥', '༡༥');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '༡༦', '༡༦');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '༡༧', '༡༧');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '༡༨', '༡༨');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '༡༩', '༡༩');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '༢༠', '༢༠');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '༢༡', '༢༡');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '༢༢', '༢༢');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '༢༣', '༢༣');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '༢༤', '༢༤');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '༢༥', '༢༥');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '༢༦', '༢༦');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '༢༧', '༢༧');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '༢༨', '༢༨');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '༢༩', '༢༩');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '༣༠', '༣༠');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '༣༡', '༣༡');\n});\n\ntest('format month', function (assert) {\n    var expected = 'ཟླ་བ་དང་པོ ཟླ་བ་དང་པོ_ཟླ་བ་གཉིས་པ ཟླ་བ་གཉིས་པ_ཟླ་བ་གསུམ་པ ཟླ་བ་གསུམ་པ_ཟླ་བ་བཞི་པ ཟླ་བ་བཞི་པ_ཟླ་བ་ལྔ་པ ཟླ་བ་ལྔ་པ_ཟླ་བ་དྲུག་པ ཟླ་བ་དྲུག་པ_ཟླ་བ་བདུན་པ ཟླ་བ་བདུན་པ_ཟླ་བ་བརྒྱད་པ ཟླ་བ་བརྒྱད་པ_ཟླ་བ་དགུ་པ ཟླ་བ་དགུ་པ_ཟླ་བ་བཅུ་པ ཟླ་བ་བཅུ་པ_ཟླ་བ་བཅུ་གཅིག་པ ཟླ་བ་བཅུ་གཅིག་པ_ཟླ་བ་བཅུ་གཉིས་པ ཟླ་བ་བཅུ་གཉིས་པ'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'གཟའ་ཉི་མ་ ཉི་མ་ ཉི་མ་_གཟའ་ཟླ་བ་ ཟླ་བ་ ཟླ་བ་_གཟའ་མིག་དམར་ མིག་དམར་ མིག་དམར་_གཟའ་ལྷག་པ་ ལྷག་པ་ ལྷག་པ་_གཟའ་ཕུར་བུ ཕུར་བུ ཕུར་བུ_གཟའ་པ་སངས་ པ་སངས་ པ་སངས་_གཟའ་སྤེན་པ་ སྤེན་པ་ སྤེན་པ་'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'ལམ་སང', '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'སྐར་མ་གཅིག',      '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'སྐར་མ་གཅིག',      '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '༢ སྐར་མ',     '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '༤༤ སྐར་མ',    '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'ཆུ་ཚོད་གཅིག',       '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'ཆུ་ཚོད་གཅིག',       '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '༢ ཆུ་ཚོད',       '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '༥ ཆུ་ཚོད',       '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '༢༡ ཆུ་ཚོད',      '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'ཉིན་གཅིག',         '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'ཉིན་གཅིག',         '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '༢ ཉིན་',        '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'ཉིན་གཅིག',         '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '༥ ཉིན་',        '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '༢༥ ཉིན་',       '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'ཟླ་བ་གཅིག',       '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'ཟླ་བ་གཅིག',       '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'ཟླ་བ་གཅིག',       '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '༢ ཟླ་བ',      '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '༢ ཟླ་བ',      '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '༣ ཟླ་བ',      '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'ཟླ་བ་གཅིག',       '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '༥ ཟླ་བ',      '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'ལོ་གཅིག',        '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '༢ ལོ',       '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'ལོ་གཅིག',        '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '༥ ལོ',       '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'ལམ་སང ལ་',  'prefix');\n    assert.equal(moment(0).from(30000), 'ལམ་སང སྔན་ལ', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'ལམ་སང སྔན་ལ',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'ལམ་སང ལ་', 'ལམ་སང ལ་');\n    assert.equal(moment().add({d: 5}).fromNow(), '༥ ཉིན་ ལ་', '༥ ཉིན་ ལ་');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'དི་རིང ཉིན་གུང ༡༢:༠༠',  'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'དི་རིང ཉིན་གུང ༡༢:༢༥',  'Now plus 25 min');\n    assert.equal(moment(a).add({h: 3}).calendar(),       'དི་རིང ཉིན་གུང ༣:༠༠',   'Now plus 3 hours');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'སང་ཉིན ཉིན་གུང ༡༢:༠༠',  'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'དི་རིང ཉིན་གུང ༡༡:༠༠',  'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'ཁ་སང ཉིན་གུང ༡༢:༠༠',    'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('[བདུན་ཕྲག་རྗེས་མ][,] LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[བདུན་ཕྲག་རྗེས་མ][,] LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[བདུན་ཕྲག་རྗེས་མ][,] LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('[བདུན་ཕྲག་མཐའ་མ] dddd[,] LT'),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[བདུན་ཕྲག་མཐའ་མ] dddd[,] LT'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[བདུན་ཕྲག་མཐའ་མ] dddd[,] LT'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('meridiem', function (assert) {\n    assert.equal(moment([2011, 2, 23,  2, 30]).format('a'), 'མཚན་མོ', 'before dawn');\n    assert.equal(moment([2011, 2, 23,  9, 30]).format('a'), 'ཞོགས་ཀས', 'morning');\n    assert.equal(moment([2011, 2, 23, 14, 30]).format('a'), 'ཉིན་གུང', 'during day');\n    assert.equal(moment([2011, 2, 23, 17, 30]).format('a'), 'དགོང་དག', 'evening');\n    assert.equal(moment([2011, 2, 23, 19, 30]).format('a'), 'དགོང་དག', 'late evening');\n    assert.equal(moment([2011, 2, 23, 21, 20]).format('a'), 'མཚན་མོ', 'night');\n\n    assert.equal(moment([2011, 2, 23,  2, 30]).format('A'), 'མཚན་མོ', 'before dawn');\n    assert.equal(moment([2011, 2, 23,  9, 30]).format('A'), 'ཞོགས་ཀས', 'morning');\n    assert.equal(moment([2011, 2, 23, 14, 30]).format('A'), 'ཉིན་གུང', ' during day');\n    assert.equal(moment([2011, 2, 23, 17, 30]).format('A'), 'དགོང་དག', 'evening');\n    assert.equal(moment([2011, 2, 23, 19, 30]).format('A'), 'དགོང་དག', 'late evening');\n    assert.equal(moment([2011, 2, 23, 21, 20]).format('A'), 'མཚན་མོ', 'night');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2012, 0,  1]).format('w ww wo'), '༡ ༠༡ ༡', 'Jan  1 2012 should be week 1');\n    assert.equal(moment([2012, 0,  7]).format('w ww wo'), '༡ ༠༡ ༡', 'Jan  7 2012 should be week 1');\n    assert.equal(moment([2012, 0,  8]).format('w ww wo'), '༢ ༠༢ ༢', 'Jan  8 2012 should be week 2');\n    assert.equal(moment([2012, 0, 14]).format('w ww wo'), '༢ ༠༢ ༢', 'Jan 14 2012 should be week 2');\n    assert.equal(moment([2012, 0, 15]).format('w ww wo'), '༣ ༠༣ ༣', 'Jan 15 2012 should be week 3');\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\n\n\nfunction localeModule (name, lifecycle) {\n    QUnit.module('locale:' + name, {\n        setup : function () {\n            moment.locale(name);\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            moment.locale('en');\n            teardownDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n    defineCommonLocaleTests(name, -1, -1);\n}\n\nlocaleModule('br');\n\ntest('parse', function (assert) {\n    var tests = 'Genver Gen_C\\'hwevrer C\\'hwe_Meurzh Meu_Ebrel Ebr_Mae Mae_Mezheven Eve_Gouere Gou_Eost Eos_Gwengolo Gwe_Here Her_Du Du_Kerzu Ker'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    moment.locale('br');\n    var a = [\n            ['dddd, MMMM Do YYYY, h:mm:ss a',      'Sul, C\\'hwevrer 14vet 2010, 3:25:50 pm'],\n            ['ddd, h A',                            'Sul, 3 PM'],\n            ['M Mo MM MMMM MMM',                   '2 2vet 02 C\\'hwevrer C\\'hwe'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14vet 14'],\n            ['d do dddd ddd dd',                   '0 0vet Sul Sul Su'],\n            ['DDD DDDo DDDD',                      '45 45vet 045'],\n            ['w wo ww',                            '6 6vet 06'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['DDDo [devezh] [ar] [vloaz]',       '45vet devezh ar vloaz'],\n            ['L',                                  '14/02/2010'],\n            ['LL',                                 '14 a viz C\\'hwevrer 2010'],\n            ['LLL',                                '14 a viz C\\'hwevrer 2010 3e25 PM'],\n            ['LLLL',                               'Sul, 14 a viz C\\'hwevrer 2010 3e25 PM']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    moment.locale('br');\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1añ', '1añ');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2vet', '2vet');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3vet', '3vet');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4vet', '4vet');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5vet', '5vet');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6vet', '6vet');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7vet', '7vet');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8vet', '8vet');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9vet', '9vet');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10vet', '10vet');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11vet', '11vet');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12vet', '12vet');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13vet', '13vet');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14vet', '14vet');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15vet', '15vet');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16vet', '16vet');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17vet', '17vet');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18vet', '18vet');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19vet', '19vet');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20vet', '20vet');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21vet', '21vet');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22vet', '22vet');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23vet', '23vet');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24vet', '24vet');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25vet', '25vet');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26vet', '26vet');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27vet', '27vet');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28vet', '28vet');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29vet', '29vet');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30vet', '30vet');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31vet', '31vet');\n});\n\ntest('format month', function (assert) {\n    moment.locale('br');\n    var expected = 'Genver Gen_C\\'hwevrer C\\'hwe_Meurzh Meu_Ebrel Ebr_Mae Mae_Mezheven Eve_Gouere Gou_Eost Eos_Gwengolo Gwe_Here Her_Du Du_Kerzu Ker'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    moment.locale('br');\n    var expected = 'Sul Sul Su_Lun Lun Lu_Meurzh Meu Me_Merc\\'her Mer Mer_Yaou Yao Ya_Gwener Gwe Gw_Sadorn Sad Sa'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    moment.locale('br');\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'un nebeud segondennoù', '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'ur vunutenn',      '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'ur vunutenn',      '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 vunutenn',     '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 munutenn',    '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'un eur',       '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'un eur',       '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 eur',       '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 eur',       '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 eur',      '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'un devezh',         '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'un devezh',         '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 zevezh',        '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'un devezh',         '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 devezh',        '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 devezh',       '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'ur miz',       '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'ur miz',       '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'ur miz',       '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 viz',      '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 viz',      '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 miz',      '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'ur miz',       '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 miz',      '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'ur bloaz',        '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 vloaz',       '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'ur bloaz',        '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 bloaz',       '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    moment.locale('br');\n    assert.equal(moment(30000).from(0), 'a-benn un nebeud segondennoù',  'prefix');\n    assert.equal(moment(0).from(30000), 'un nebeud segondennoù \\'zo', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    moment.locale('br');\n    assert.equal(moment().fromNow(), 'un nebeud segondennoù \\'zo',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    moment.locale('br');\n    assert.equal(moment().add({s: 30}).fromNow(), 'a-benn un nebeud segondennoù', 'in a few seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), 'a-benn 5 devezh', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    moment.locale('br');\n\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'Hiziv da 12e00 PM',        'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'Hiziv da 12e25 PM',        'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'Hiziv da 1e00 PM',         'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'Warc\\'hoazh da 12e00 PM',  'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'Hiziv da 11e00 AM',        'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'Dec\\'h da 12e00 PM',       'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    moment.locale('br');\n\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('dddd [da] LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd [da] LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd [da] LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    moment.locale('br');\n\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('dddd [paset da] LT'),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd [paset da] LT'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd [paset da] LT'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    moment.locale('br');\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('special mutations for years', function (assert) {\n    moment.locale('br');\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true), 'ur bloaz', 'mutation 1 year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 2}), true), '2 vloaz', 'mutation 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 3}), true), '3 bloaz', 'mutation 3 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 4}), true), '4 bloaz', 'mutation 4 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true), '5 bloaz', 'mutation 5 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 9}), true), '9 bloaz', 'mutation 9 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 10}), true), '10 vloaz', 'mutation 10 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 21}), true), '21 bloaz', 'mutation 21 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 22}), true), '22 vloaz', 'mutation 22 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 133}), true), '133 bloaz', 'mutation 133 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 148}), true), '148 vloaz', 'mutation 148 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 261}), true), '261 bloaz', 'mutation 261 years');\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\n\n\nfunction localeModule (name, lifecycle) {\n    QUnit.module('locale:' + name, {\n        setup : function () {\n            moment.locale(name);\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            moment.locale('en');\n            teardownDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n    defineCommonLocaleTests(name, -1, -1);\n}\n\nlocaleModule('bs');\n\ntest('parse', function (assert) {\n    var tests = 'januar jan._februar feb._mart mar._april apr._maj maj._juni jun._juli jul._august aug._septembar sep._oktobar okt._novembar nov._decembar dec.'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1) + ' inp ' + mmm);\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, Do MMMM YYYY, h:mm:ss a',      'nedjelja, 14. februar 2010, 3:25:50 pm'],\n            ['ddd, hA',                            'ned., 3PM'],\n            ['M Mo MM MMMM MMM',                   '2 2. 02 februar feb.'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14. 14'],\n            ['d do dddd ddd dd',                   '0 0. nedjelja ned. ne'],\n            ['DDD DDDo DDDD',                      '45 45. 045'],\n            ['w wo ww',                            '7 7. 07'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'pm PM'],\n            ['[the] DDDo [day of the year]',       'the 45. day of the year'],\n            ['LTS',                                '15:25:50'],\n            ['L',                                  '14.02.2010'],\n            ['LL',                                 '14. februar 2010'],\n            ['LLL',                                '14. februar 2010 15:25'],\n            ['LLLL',                               'nedjelja, 14. februar 2010 15:25'],\n            ['l',                                  '14.2.2010'],\n            ['ll',                                 '14. feb. 2010'],\n            ['lll',                                '14. feb. 2010 15:25'],\n            ['llll',                               'ned., 14. feb. 2010 15:25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1.', '1.');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2.', '2.');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3.', '3.');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4.', '4.');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5.', '5.');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6.', '6.');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7.', '7.');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8.', '8.');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9.', '9.');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10.', '10.');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11.', '11.');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12.', '12.');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13.', '13.');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14.', '14.');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15.', '15.');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16.', '16.');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17.', '17.');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18.', '18.');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19.', '19.');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20.', '20.');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21.', '21.');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22.', '22.');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23.', '23.');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24.', '24.');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25.', '25.');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26.', '26.');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27.', '27.');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28.', '28.');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29.', '29.');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30.', '30.');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31.', '31.');\n});\n\ntest('format month', function (assert) {\n    var expected = 'januar jan._februar feb._mart mar._april apr._maj maj._juni jun._juli jul._august aug._septembar sep._oktobar okt._novembar nov._decembar dec.'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'nedjelja ned. ne_ponedjeljak pon. po_utorak uto. ut_srijeda sri. sr_četvrtak čet. če_petak pet. pe_subota sub. su'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'par sekundi', '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'jedna minuta',   '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'jedna minuta',   '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 minute',     '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 minuta',     '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'jedan sat',      '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'jedan sat',      '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 sata',        '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 sati',         '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 sati',        '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'dan',       '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'dan',       '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 dana',        '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'dan',       '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 dana',        '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 dana',       '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'mjesec',     '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'mjesec',     '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'mjesec',     '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 mjeseca',     '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 mjeseca',     '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 mjeseca',     '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'mjesec',     '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 mjeseci',    '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'godinu',     '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 godine',       '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'godinu',     '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 godina',        '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'za par sekundi',  'prefix');\n    assert.equal(moment(0).from(30000), 'prije par sekundi', 'prefix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'prije par sekundi',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'za par sekundi', 'in a few seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), 'za 5 dana', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'danas u 12:00',  'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'danas u 12:25',  'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'danas u 13:00',  'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'sutra u 12:00',  'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'danas u 11:00',  'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'jučer u 12:00',  'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n\n    function makeFormat(d) {\n        switch (d.day()) {\n            case 0:\n                return '[u] [nedjelju] [u] LT';\n            case 3:\n                return '[u] [srijedu] [u] LT';\n            case 6:\n                return '[u] [subotu] [u] LT';\n            case 1:\n            case 2:\n            case 4:\n            case 5:\n                return '[u] dddd [u] LT';\n        }\n    }\n\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format(makeFormat(m)),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format(makeFormat(m)),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format(makeFormat(m)),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n\n    function makeFormat(d) {\n        switch (d.day()) {\n            case 0:\n            case 3:\n                return '[prošlu] dddd [u] LT';\n            case 6:\n                return '[prošle] [subote] [u] LT';\n            case 1:\n            case 2:\n            case 4:\n            case 5:\n                return '[prošli] dddd [u] LT';\n        }\n    }\n\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format(makeFormat(m)),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format(makeFormat(m)),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format(makeFormat(m)),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2011, 11, 26]).format('w ww wo'), '1 01 1.', 'Dec 26 2011 should be week 1');\n    assert.equal(moment([2012,  0,  1]).format('w ww wo'), '1 01 1.', 'Jan  1 2012 should be week 1');\n    assert.equal(moment([2012,  0,  2]).format('w ww wo'), '2 02 2.', 'Jan  2 2012 should be week 2');\n    assert.equal(moment([2012,  0,  8]).format('w ww wo'), '2 02 2.', 'Jan  8 2012 should be week 2');\n    assert.equal(moment([2012,  0,  9]).format('w ww wo'), '3 03 3.', 'Jan  9 2012 should be week 3');\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\n\n\nfunction localeModule (name, lifecycle) {\n    QUnit.module('locale:' + name, {\n        setup : function () {\n            moment.locale(name);\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            moment.locale('en');\n            teardownDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n    defineCommonLocaleTests(name, -1, -1);\n}\n\nlocaleModule('ca');\n\ntest('parse', function (assert) {\n    var tests = 'gener gen._febrer febr._març març_abril abr._maig maig_juny juny_juliol jul._agost ag._setembre set._octubre oct._novembre nov._desembre des.'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, Do MMMM YYYY, h:mm:ss a',      'diumenge, 14è de febrer 2010, 3:25:50 pm'],\n            ['ddd, hA',                            'dg., 3PM'],\n            ['M Mo MM MMMM MMM',                   '2 2n 02 febrer febr.'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14è 14'],\n            ['d do dddd ddd dd',                   '0 0è diumenge dg. Dg'],\n            ['DDD DDDo DDDD',                      '45 45è 045'],\n            ['w wo ww',                            '6 6a 06'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'pm PM'],\n            ['[the] DDDo [day of the year]',       'the 45è day of the year'],\n            ['LTS',                                '15:25:50'],\n            ['L',                                  '14/02/2010'],\n            ['LL',                                 'el 14 de febrer de 2010'],\n            ['LLL',                                'el 14 de febrer de 2010 a les 15:25'],\n            ['LLLL',                               'el diumenge 14 de febrer de 2010 a les 15:25'],\n            ['l',                                  '14/2/2010'],\n            ['ll',                                 '14 febr. 2010'],\n            ['lll',                                '14 febr. 2010, 15:25'],\n            ['llll',                               'dg. 14 febr. 2010, 15:25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1r', '1r');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2n', '2n');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3r', '3r');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4t', '4t');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5è', '5è');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6è', '6è');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7è', '7è');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8è', '8è');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9è', '9è');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10è', '10è');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11è', '11è');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12è', '12è');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13è', '13è');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14è', '14è');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15è', '15è');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16è', '16è');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17è', '17è');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18è', '18è');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19è', '19è');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20è', '20è');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21è', '21è');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22è', '22è');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23è', '23è');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24è', '24è');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25è', '25è');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26è', '26è');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27è', '27è');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28è', '28è');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29è', '29è');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30è', '30è');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31è', '31è');\n});\n\ntest('format month', function (assert) {\n    var expected = 'gener gen._febrer febr._març març_abril abr._maig maig_juny juny_juliol jul._agost ag._setembre set._octubre oct._novembre nov._desembre des.'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'diumenge dg. Dg_dilluns dl. Dl_dimarts dt. Dt_dimecres dc. Dc_dijous dj. Dj_divendres dv. Dv_dissabte ds. Ds'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'uns segons', '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'un minut',      '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'un minut',      '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 minuts',     '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 minuts',    '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'una hora',       '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'una hora',       '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 hores',       '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 hores',       '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 hores',      '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'un dia',         '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'un dia',         '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 dies',        '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'un dia',         '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 dies',        '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 dies',       '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'un mes',       '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'un mes',       '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'un mes',       '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 mesos',      '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 mesos',      '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 mesos',      '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'un mes',       '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 mesos',      '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'un any',        '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 anys',       '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'un any',        '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 anys',       '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'd\\'aquí uns segons',  'prefix');\n    assert.equal(moment(0).from(30000), 'fa uns segons', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'fa uns segons',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'd\\'aquí uns segons', 'd\\'aquí uns segons');\n    assert.equal(moment().add({d: 5}).fromNow(), 'd\\'aquí 5 dies', 'd\\'aquí 5 dies');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                       'avui a les 12:00',     'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),          'avui a les 12:25',     'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),           'avui a les 13:00',     'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),           'demà a les 12:00',     'tomorrow at the same time');\n    assert.equal(moment(a).add({d: 1, h : -1}).calendar(),   'demà a les 11:00',     'tomorrow minus 1 hour');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),      'avui a les 11:00',     'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),      'ahir a les 12:00',     'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('dddd [a ' + ((m.hours() !== 1) ? 'les' : 'la') + '] LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd [a ' + ((m.hours() !== 1) ? 'les' : 'la') + '] LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd [a ' + ((m.hours() !== 1) ? 'les' : 'la') + '] LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('[el] dddd [passat a ' + ((m.hours() !== 1) ? 'les' : 'la') + '] LT'),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[el] dddd [passat a ' + ((m.hours() !== 1) ? 'les' : 'la') + '] LT'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[el] dddd [passat a ' + ((m.hours() !== 1) ? 'les' : 'la') + '] LT'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2012, 0,  1]).format('w ww wo'), '52 52 52a', 'Jan  1 2012 should be week 52');\n    assert.equal(moment([2012, 0,  2]).format('w ww wo'),   '1 01 1a', 'Jan  2 2012 should be week 1');\n    assert.equal(moment([2012, 0,  8]).format('w ww wo'),   '1 01 1a', 'Jan  8 2012 should be week 1');\n    assert.equal(moment([2012, 0,  9]).format('w ww wo'),   '2 02 2a', 'Jan  9 2012 should be week 2');\n    assert.equal(moment([2012, 0, 15]).format('w ww wo'),   '2 02 2a', 'Jan 15 2012 should be week 2');\n});\n\ntest('day and month', function (assert) {\n    assert.equal(moment([2012, 1, 15]).format('D MMMM'), '15 de febrer');\n    assert.equal(moment([2012, 9, 15]).format('D MMMM'), '15 d\\'octubre');\n    assert.equal(moment([2012, 9, 15]).format('MMMM, D'), 'octubre, 15');\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\n\n\nfunction localeModule (name, lifecycle) {\n    QUnit.module('locale:' + name, {\n        setup : function () {\n            moment.locale(name);\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            moment.locale('en');\n            teardownDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n    defineCommonLocaleTests(name, -1, -1);\n}\n\nlocaleModule('cs');\n\ntest('parse', function (assert) {\n    var tests = 'leden led_únor úno_březen bře_duben dub_květen kvě_červen čvn_červenec čvc_srpen srp_září zář_říjen říj_listopad lis_prosinec pro'.split('_'), i;\n    function equalTest(input, mmm, monthIndex) {\n        assert.equal(moment(input, mmm).month(), monthIndex, input + ' ' + mmm + ' should be month ' + (monthIndex + 1));\n    }\n    function equalTestStrict(input, mmm, monthIndex) {\n        assert.equal(moment(input, mmm, true).month(), monthIndex, input + ' ' + mmm + ' should be strict month ' + (monthIndex + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n\n        equalTestStrict(tests[i][1], 'MMM', i);\n        equalTestStrict(tests[i][0], 'MMMM', i);\n        equalTestStrict(tests[i][1].toLocaleLowerCase(), 'MMM', i);\n        equalTestStrict(tests[i][1].toLocaleUpperCase(), 'MMM', i);\n        equalTestStrict(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTestStrict(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, MMMM Do YYYY, h:mm:ss',  'neděle, únor 14. 2010, 3:25:50'],\n            ['ddd, h',                       'ne, 3'],\n            ['M Mo MM MMMM MMM',             '2 2. 02 únor úno'],\n            ['YYYY YY',                      '2010 10'],\n            ['D Do DD',                      '14 14. 14'],\n            ['d do dddd ddd dd',             '0 0. neděle ne ne'],\n            ['DDD DDDo DDDD',                '45 45. 045'],\n            ['w wo ww',                      '6 6. 06'],\n            ['h hh',                         '3 03'],\n            ['H HH',                         '15 15'],\n            ['m mm',                         '25 25'],\n            ['s ss',                         '50 50'],\n            ['a A',                          'pm PM'],\n            ['DDDo [den v roce]',            '45. den v roce'],\n            ['LTS',                          '15:25:50'],\n            ['L',                            '14.02.2010'],\n            ['LL',                           '14. únor 2010'],\n            ['LLL',                          '14. únor 2010 15:25'],\n            ['LLLL',                         'neděle 14. únor 2010 15:25'],\n            ['l',                            '14. 2. 2010'],\n            ['ll',                           '14. úno 2010'],\n            ['lll',                          '14. úno 2010 15:25'],\n            ['llll',                         'ne 14. úno 2010 15:25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1.', '1.');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2.', '2.');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3.', '3.');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4.', '4.');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5.', '5.');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6.', '6.');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7.', '7.');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8.', '8.');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9.', '9.');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10.', '10.');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11.', '11.');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12.', '12.');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13.', '13.');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14.', '14.');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15.', '15.');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16.', '16.');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17.', '17.');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18.', '18.');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19.', '19.');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20.', '20.');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21.', '21.');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22.', '22.');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23.', '23.');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24.', '24.');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25.', '25.');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26.', '26.');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27.', '27.');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28.', '28.');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29.', '29.');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30.', '30.');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31.', '31.');\n});\n\ntest('format month', function (assert) {\n    var expected = 'leden led_únor úno_březen bře_duben dub_květen kvě_červen čvn_červenec čvc_srpen srp_září zář_říjen říj_listopad lis_prosinec pro'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'neděle ne ne_pondělí po po_úterý út út_středa st st_čtvrtek čt čt_pátek pá pá_sobota so so'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'pár sekund',  '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'minuta',        '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'minuta',        '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 minuty',      '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 minut',     '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'hodina',       '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'hodina',       '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 hodiny',     '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 hodin',      '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 hodin',     '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'den',       '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'den',       '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 dny',         '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'den',       '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 dní',         '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 dní',        '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'měsíc',       '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'měsíc',       '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'měsíc',       '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 měsíce',    '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 měsíce',    '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 měsíce',    '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'měsíc',       '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 měsíců',    '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'rok',           '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 roky',        '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'rok',           '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 let',         '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'za pár sekund',  'prefix');\n    assert.equal(moment(0).from(30000), 'před pár sekundami', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'před pár sekundami',  'now from now should display as in the past');\n});\n\ntest('fromNow (future)', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'za pár sekund', 'in a few seconds');\n    assert.equal(moment().add({m: 1}).fromNow(), 'za minutu', 'in a minute');\n    assert.equal(moment().add({m: 3}).fromNow(), 'za 3 minuty', 'in 3 minutes');\n    assert.equal(moment().add({m: 10}).fromNow(), 'za 10 minut', 'in 10 minutes');\n    assert.equal(moment().add({h: 1}).fromNow(), 'za hodinu', 'in an hour');\n    assert.equal(moment().add({h: 3}).fromNow(), 'za 3 hodiny', 'in 3 hours');\n    assert.equal(moment().add({h: 10}).fromNow(), 'za 10 hodin', 'in 10 hours');\n    assert.equal(moment().add({d: 1}).fromNow(), 'za den', 'in a day');\n    assert.equal(moment().add({d: 3}).fromNow(), 'za 3 dny', 'in 3 days');\n    assert.equal(moment().add({d: 10}).fromNow(), 'za 10 dní', 'in 10 days');\n    assert.equal(moment().add({M: 1}).fromNow(), 'za měsíc', 'in a month');\n    assert.equal(moment().add({M: 3}).fromNow(), 'za 3 měsíce', 'in 3 months');\n    assert.equal(moment().add({M: 10}).fromNow(), 'za 10 měsíců', 'in 10 months');\n    assert.equal(moment().add({y: 1}).fromNow(), 'za rok', 'in a year');\n    assert.equal(moment().add({y: 3}).fromNow(), 'za 3 roky', 'in 3 years');\n    assert.equal(moment().add({y: 10}).fromNow(), 'za 10 let', 'in 10 years');\n});\n\ntest('fromNow (past)', function (assert) {\n    assert.equal(moment().subtract({s: 30}).fromNow(), 'před pár sekundami', 'a few seconds ago');\n    assert.equal(moment().subtract({m: 1}).fromNow(), 'před minutou', 'a minute ago');\n    assert.equal(moment().subtract({m: 3}).fromNow(), 'před 3 minutami', '3 minutes ago');\n    assert.equal(moment().subtract({m: 10}).fromNow(), 'před 10 minutami', '10 minutes ago');\n    assert.equal(moment().subtract({h: 1}).fromNow(), 'před hodinou', 'an hour ago');\n    assert.equal(moment().subtract({h: 3}).fromNow(), 'před 3 hodinami', '3 hours ago');\n    assert.equal(moment().subtract({h: 10}).fromNow(), 'před 10 hodinami', '10 hours ago');\n    assert.equal(moment().subtract({d: 1}).fromNow(), 'před dnem', 'a day ago');\n    assert.equal(moment().subtract({d: 3}).fromNow(), 'před 3 dny', '3 days ago');\n    assert.equal(moment().subtract({d: 10}).fromNow(), 'před 10 dny', '10 days ago');\n    assert.equal(moment().subtract({M: 1}).fromNow(), 'před měsícem', 'a month ago');\n    assert.equal(moment().subtract({M: 3}).fromNow(), 'před 3 měsíci', '3 months ago');\n    assert.equal(moment().subtract({M: 10}).fromNow(), 'před 10 měsíci', '10 months ago');\n    assert.equal(moment().subtract({y: 1}).fromNow(), 'před rokem', 'a year ago');\n    assert.equal(moment().subtract({y: 3}).fromNow(), 'před 3 lety', '3 years ago');\n    assert.equal(moment().subtract({y: 10}).fromNow(), 'před 10 lety', '10 years ago');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'dnes v 12:00',     'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'dnes v 12:25',     'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'dnes v 13:00',     'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'zítra v 12:00',    'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'dnes v 11:00',     'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'včera v 12:00',    'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m, nextDay;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        nextDay = '';\n        switch (m.day()) {\n            case 0:\n                nextDay = 'v neděli';\n                break;\n            case 1:\n                nextDay = 'v pondělí';\n                break;\n            case 2:\n                nextDay = 'v úterý';\n                break;\n            case 3:\n                nextDay = 've středu';\n                break;\n            case 4:\n                nextDay = 've čtvrtek';\n                break;\n            case 5:\n                nextDay = 'v pátek';\n                break;\n            case 6:\n                nextDay = 'v sobotu';\n                break;\n        }\n        assert.equal(m.calendar(),       m.format('[' + nextDay + '] [v] LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[' + nextDay + '] [v] LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[' + nextDay + '] [v] LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m, lastDay;\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        lastDay = '';\n        switch (m.day()) {\n            case 0:\n                lastDay = 'minulou neděli';\n                break;\n            case 1:\n                lastDay = 'minulé pondělí';\n                break;\n            case 2:\n                lastDay = 'minulé úterý';\n                break;\n            case 3:\n                lastDay = 'minulou středu';\n                break;\n            case 4:\n                lastDay = 'minulý čtvrtek';\n                break;\n            case 5:\n                lastDay = 'minulý pátek';\n                break;\n            case 6:\n                lastDay = 'minulou sobotu';\n                break;\n        }\n        assert.equal(m.calendar(),       m.format('[' + lastDay + '] [v] LT'),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[' + lastDay + '] [v] LT'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[' + lastDay + '] [v] LT'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('humanize duration', function (assert) {\n    assert.equal(moment.duration(1, 'minutes').humanize(), 'minuta', 'a minute (future)');\n    assert.equal(moment.duration(1, 'minutes').humanize(true), 'za minutu', 'in a minute');\n    assert.equal(moment.duration(-1, 'minutes').humanize(), 'minuta', 'a minute (past)');\n    assert.equal(moment.duration(-1, 'minutes').humanize(true), 'před minutou', 'a minute ago');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2012, 0,  1]).format('w ww wo'), '52 52 52.', 'Jan  1 2012 should be week 52');\n    assert.equal(moment([2012, 0,  2]).format('w ww wo'),   '1 01 1.', 'Jan  2 2012 should be week 1');\n    assert.equal(moment([2012, 0,  8]).format('w ww wo'),   '1 01 1.', 'Jan  8 2012 should be week 1');\n    assert.equal(moment([2012, 0,  9]).format('w ww wo'),   '2 02 2.', 'Jan  9 2012 should be week 2');\n    assert.equal(moment([2012, 0, 15]).format('w ww wo'),   '2 02 2.', 'Jan 15 2012 should be week 2');\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\n\n\nfunction localeModule (name, lifecycle) {\n    QUnit.module('locale:' + name, {\n        setup : function () {\n            moment.locale(name);\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            moment.locale('en');\n            teardownDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n    defineCommonLocaleTests(name, -1, -1);\n}\n\nlocaleModule('cv');\n\ntest('parse', function (assert) {\n    var tests = 'кӑрлач кӑр_нарӑс нар_пуш пуш_ака ака_май май_ҫӗртме ҫӗр_утӑ утӑ_ҫурла ҫур_авӑн авн_юпа юпа_чӳк чӳк_раштав раш'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, MMMM Do YYYY, h:mm:ss a',      'вырсарникун, нарӑс 14-мӗш 2010, 3:25:50 pm'],\n            ['ddd, hA',                            'выр, 3PM'],\n            ['M Mo MM MMMM MMM',                   '2 2-мӗш 02 нарӑс нар'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14-мӗш 14'],\n            ['d do dddd ddd dd',                   '0 0-мӗш вырсарникун выр вр'],\n            ['DDD DDDo DDDD',                      '45 45-мӗш 045'],\n            ['w wo ww',                            '7 7-мӗш 07'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'pm PM'],\n            ['Ҫулӑн DDDo кунӗ',                    'Ҫулӑн 45-мӗш кунӗ'],\n            ['LTS',                                '15:25:50'],\n            ['L',                                  '14-02-2010'],\n            ['LL',                                 '2010 ҫулхи нарӑс уйӑхӗн 14-мӗшӗ'],\n            ['LLL',                                '2010 ҫулхи нарӑс уйӑхӗн 14-мӗшӗ, 15:25'],\n            ['LLLL',                               'вырсарникун, 2010 ҫулхи нарӑс уйӑхӗн 14-мӗшӗ, 15:25'],\n            ['l',                                  '14-2-2010'],\n            ['ll',                                 '2010 ҫулхи нар уйӑхӗн 14-мӗшӗ'],\n            ['lll',                                '2010 ҫулхи нар уйӑхӗн 14-мӗшӗ, 15:25'],\n            ['llll',                               'выр, 2010 ҫулхи нар уйӑхӗн 14-мӗшӗ, 15:25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1-мӗш', '1-мӗш');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2-мӗш', '2-мӗш');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3-мӗш', '3-мӗш');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4-мӗш', '4-мӗш');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5-мӗш', '5-мӗш');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6-мӗш', '6-мӗш');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7-мӗш', '7-мӗш');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8-мӗш', '8-мӗш');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9-мӗш', '9-мӗш');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10-мӗш', '10-мӗш');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11-мӗш', '11-мӗш');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12-мӗш', '12-мӗш');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13-мӗш', '13-мӗш');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14-мӗш', '14-мӗш');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15-мӗш', '15-мӗш');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16-мӗш', '16-мӗш');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17-мӗш', '17-мӗш');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18-мӗш', '18-мӗш');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19-мӗш', '19-мӗш');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20-мӗш', '20-мӗш');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21-мӗш', '21-мӗш');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22-мӗш', '22-мӗш');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23-мӗш', '23-мӗш');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24-мӗш', '24-мӗш');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25-мӗш', '25-мӗш');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26-мӗш', '26-мӗш');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27-мӗш', '27-мӗш');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28-мӗш', '28-мӗш');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29-мӗш', '29-мӗш');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30-мӗш', '30-мӗш');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31-мӗш', '31-мӗш');\n});\n\ntest('format month', function (assert) {\n    var expected = 'кӑрлач кӑр_нарӑс нар_пуш пуш_ака ака_май май_ҫӗртме ҫӗр_утӑ утӑ_ҫурла ҫур_авӑн авн_юпа юпа_чӳк чӳк_раштав раш'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'вырсарникун выр вр_тунтикун тун тн_ытларикун ытл ыт_юнкун юн юн_кӗҫнерникун кӗҫ кҫ_эрнекун эрн эр_шӑматкун шӑм шм'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'пӗр-ик ҫеккунт', '44 sekunder = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'пӗр минут',      '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'пӗр минут',      '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 минут',     '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 минут',    '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'пӗр сехет',       '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'пӗр сехет',       '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 сехет',       '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 сехет',       '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 сехет',      '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'пӗр кун',         '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'пӗр кун',         '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 кун',        '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'пӗр кун',         '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 кун',        '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 кун',       '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'пӗр уйӑх',       '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'пӗр уйӑх',       '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'пӗр уйӑх',       '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 уйӑх',      '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 уйӑх',      '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 уйӑх',      '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'пӗр уйӑх',       '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 уйӑх',      '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'пӗр ҫул',        '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 ҫул',       '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'пӗр ҫул',        '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 ҫул',       '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'пӗр-ик ҫеккунтран',  'prefix');\n    assert.equal(moment(0).from(30000), 'пӗр-ик ҫеккунт каялла', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'пӗр-ик ҫеккунт каялла',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'пӗр-ик ҫеккунтран', 'in a few seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), '5 кунран', 'in 5 days');\n    assert.equal(moment().add({h: 2}).fromNow(), '2 сехетрен', 'in 2 hours, the right suffix!');\n    assert.equal(moment().add({y: 3}).fromNow(), '3 ҫултан', 'in 3 years, the right suffix!');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n    assert.equal(moment(a).calendar(),                   'Паян 12:00 сехетре',     'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'Паян 12:25 сехетре',     'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'Паян 13:00 сехетре',     'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'Ыран 12:00 сехетре',     'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'Паян 11:00 сехетре',     'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'Ӗнер 12:00 сехетре',     'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('[Ҫитес] dddd LT [сехетре]'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[Ҫитес] dddd LT [сехетре]'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[Ҫитес] dddd LT [сехетре]'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('[Иртнӗ] dddd LT [сехетре]'),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[Иртнӗ] dddd LT [сехетре]'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[Иртнӗ] dddd LT [сехетре]'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\n// Monday is the first day of the week.\n// The week that contains Jan 1st is the first week of the year.\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2011, 11, 26]).format('w ww wo'), '1 01 1-мӗш', 'Dec 26 2011 should be week 1');\n    assert.equal(moment([2012,  0,  1]).format('w ww wo'), '1 01 1-мӗш', 'Jan  1 2012 should be week 1');\n    assert.equal(moment([2012,  0,  2]).format('w ww wo'), '2 02 2-мӗш', 'Jan  2 2012 should be week 2');\n    assert.equal(moment([2012,  0,  8]).format('w ww wo'), '2 02 2-мӗш', 'Jan  8 2012 should be week 2');\n    assert.equal(moment([2012,  0,  9]).format('w ww wo'), '3 03 3-мӗш', 'Jan  9 2012 should be week 3');\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\n\n\nfunction localeModule (name, lifecycle) {\n    QUnit.module('locale:' + name, {\n        setup : function () {\n            moment.locale(name);\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            moment.locale('en');\n            teardownDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n    defineCommonLocaleTests(name, -1, -1);\n}\n\nlocaleModule('cy');\n\ntest('parse', function (assert) {\n    var tests = 'Ionawr Ion_Chwefror Chwe_Mawrth Maw_Ebrill Ebr_Mai Mai_Mehefin Meh_Gorffennaf Gor_Awst Aws_Medi Med_Hydref Hyd_Tachwedd Tach_Rhagfyr Rhag'.split('_'),\n        i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, MMMM Do YYYY, h:mm:ss a',      'Dydd Sul, Chwefror 14eg 2010, 3:25:50 pm'],\n            ['ddd, hA',                            'Sul, 3PM'],\n            ['M Mo MM MMMM MMM',                   '2 2il 02 Chwefror Chwe'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14eg 14'],\n            ['d do dddd ddd dd',                   '0 0 Dydd Sul Sul Su'],\n            ['DDD DDDo DDDD',                      '45 45ain 045'],\n            ['w wo ww',                            '6 6ed 06'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'pm PM'],\n            ['[the] DDDo [day of the year]',       'the 45ain day of the year'],\n            ['LTS',                                '15:25:50'],\n            ['L',                                  '14/02/2010'],\n            ['LL',                                 '14 Chwefror 2010'],\n            ['LLL',                                '14 Chwefror 2010 15:25'],\n            ['LLLL',                               'Dydd Sul, 14 Chwefror 2010 15:25'],\n            ['l',                                  '14/2/2010'],\n            ['ll',                                 '14 Chwe 2010'],\n            ['lll',                                '14 Chwe 2010 15:25'],\n            ['llll',                               'Sul, 14 Chwe 2010 15:25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1af', '1af');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2il', '2il');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3ydd', '3ydd');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4ydd', '4ydd');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5ed', '5ed');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6ed', '6ed');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7ed', '7ed');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8fed', '8fed');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9fed', '9fed');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10fed', '10fed');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11eg', '11eg');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12fed', '12fed');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13eg', '13eg');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14eg', '14eg');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15fed', '15fed');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16eg', '16eg');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17eg', '17eg');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18fed', '18fed');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19eg', '19eg');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20fed', '20fed');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21ain', '21ain');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22ain', '22ain');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23ain', '23ain');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24ain', '24ain');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25ain', '25ain');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26ain', '26ain');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27ain', '27ain');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28ain', '28ain');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29ain', '29ain');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30ain', '30ain');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31ain', '31ain');\n});\n\ntest('format month', function (assert) {\n    var expected = 'Ionawr Ion_Chwefror Chwe_Mawrth Maw_Ebrill Ebr_Mai Mai_Mehefin Meh_Gorffennaf Gor_Awst Aws_Medi Med_Hydref Hyd_Tachwedd Tach_Rhagfyr Rhag'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'Dydd Sul Sul Su_Dydd Llun Llun Ll_Dydd Mawrth Maw Ma_Dydd Mercher Mer Me_Dydd Iau Iau Ia_Dydd Gwener Gwe Gw_Dydd Sadwrn Sad Sa'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'ychydig eiliadau', '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'munud',   '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'munud',   '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 munud',  '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 munud', '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'awr',    '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'awr',    '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 awr',    '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 awr',    '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 awr',   '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'diwrnod',      '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'diwrnod',      '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 diwrnod',     '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'diwrnod',      '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 diwrnod',     '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 diwrnod',    '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'mis',    '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'mis',    '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'mis',    '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 mis',   '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 mis',   '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 mis',   '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'mis',    '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 mis',   '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'blwyddyn',     '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 flynedd',    '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'blwyddyn',     '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 flynedd',    '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'mewn ychydig eiliadau', 'prefix');\n    assert.equal(moment(0).from(30000), 'ychydig eiliadau yn ôl', 'suffix');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'mewn ychydig eiliadau', 'in a few seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), 'mewn 5 diwrnod', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'Heddiw am 12:00',    'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'Heddiw am 12:25',    'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'Heddiw am 13:00',    'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'Yfory am 12:00',     'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'Heddiw am 11:00',    'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'Ddoe am 12:00',      'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('dddd [am] LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd [am] LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd [am] LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('dddd [diwethaf am] LT'),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd [diwethaf am] LT'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd [diwethaf am] LT'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2012, 0,  1]).format('w ww wo'), '52 52 52ain', 'Jan  1 2012 should be week 52');\n    assert.equal(moment([2012, 0,  2]).format('w ww wo'), '1 01 1af', 'Jan  2 2012 should be week 1');\n    assert.equal(moment([2012, 0,  8]).format('w ww wo'), '1 01 1af', 'Jan  8 2012 should be week 1');\n    assert.equal(moment([2012, 0,  9]).format('w ww wo'),   '2 02 2il', 'Jan  9 2012 should be week 2');\n    assert.equal(moment([2012, 0, 15]).format('w ww wo'),   '2 02 2il', 'Jan 15 2012 should be week 2');\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\n\n\nfunction localeModule (name, lifecycle) {\n    QUnit.module('locale:' + name, {\n        setup : function () {\n            moment.locale(name);\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            moment.locale('en');\n            teardownDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n    defineCommonLocaleTests(name, -1, -1);\n}\n\nlocaleModule('da');\n\ntest('parse', function (assert) {\n    var tests = 'januar jan_februar feb_marts mar_april apr_maj maj_juni jun_juli jul_august aug_september sep_oktober okt_november nov_december dec'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd [den] Do MMMM YYYY, h:mm:ss a', 'søndag den 14. februar 2010, 3:25:50 pm'],\n            ['ddd hA',                             'søn 3PM'],\n            ['M Mo MM MMMM MMM',                   '2 2. 02 februar feb'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14. 14'],\n            ['d do dddd ddd dd',                   '0 0. søndag søn sø'],\n            ['DDD DDDo DDDD',                      '45 45. 045'],\n            ['w wo ww',                            '6 6. 06'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'pm PM'],\n            ['[den] DDDo [dag på året]',           'den 45. dag på året'],\n            ['LTS',                                '15:25:50'],\n            ['L',                                  '14/02/2010'],\n            ['LL',                                 '14. februar 2010'],\n            ['LLL',                                '14. februar 2010 15:25'],\n            ['LLLL',                               'søndag d. 14. februar 2010 kl. 15:25'],\n            ['l',                                  '14/2/2010'],\n            ['ll',                                 '14. feb 2010'],\n            ['lll',                                '14. feb 2010 15:25'],\n            ['llll',                               'søn d. 14. feb 2010 kl. 15:25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1.', '1.');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2.', '2.');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3.', '3.');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4.', '4.');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5.', '5.');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6.', '6.');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7.', '7.');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8.', '8.');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9.', '9.');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10.', '10.');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11.', '11.');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12.', '12.');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13.', '13.');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14.', '14.');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15.', '15.');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16.', '16.');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17.', '17.');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18.', '18.');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19.', '19.');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20.', '20.');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21.', '21.');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22.', '22.');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23.', '23.');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24.', '24.');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25.', '25.');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26.', '26.');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27.', '27.');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28.', '28.');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29.', '29.');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30.', '30.');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31.', '31.');\n});\n\ntest('format month', function (assert) {\n    var expected = 'januar jan_februar feb_marts mar_april apr_maj maj_juni jun_juli jul_august aug_september sep_oktober okt_november nov_december dec'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'søndag søn sø_mandag man ma_tirsdag tir ti_onsdag ons on_torsdag tor to_fredag fre fr_lørdag lør lø'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'få sekunder', '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'et minut',    '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'et minut',    '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 minutter',  '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 minutter', '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'en time',     '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'en time',     '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 timer',     '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 timer',     '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 timer',    '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'en dag',      '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'en dag',      '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 dage',      '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'en dag',      '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 dage',      '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 dage',     '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'en måned',    '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'en måned',    '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'en måned',    '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 måneder',   '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 måneder',   '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 måneder',   '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'en måned',    '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 måneder',   '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'et år',       '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 år',        '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'et år',       '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 år',        '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'om få sekunder',  'prefix');\n    assert.equal(moment(0).from(30000), 'få sekunder siden', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'få sekunder siden',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'om få sekunder', 'in a few seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), 'om 5 dage', 'in 5 days');\n});\n\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'i dag kl. 12:00',    'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'i dag kl. 12:25',    'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'i dag kl. 13:00',    'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'i morgen kl. 12:00', 'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'i dag kl. 11:00',    'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'i går kl. 12:00',    'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('på dddd [kl.] LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('på dddd [kl.] LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('på dddd [kl.] LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('[i] dddd[s kl.] LT'),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[i] dddd[s kl.] LT'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[i] dddd[s kl.] LT'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2012, 0,  1]).format('w ww wo'), '52 52 52.', 'Jan  1 2012 should be week 52');\n    assert.equal(moment([2012, 0,  2]).format('w ww wo'),   '1 01 1.', 'Jan  2 2012 should be week 1');\n    assert.equal(moment([2012, 0,  8]).format('w ww wo'),   '1 01 1.', 'Jan  8 2012 should be week 1');\n    assert.equal(moment([2012, 0,  9]).format('w ww wo'),   '2 02 2.', 'Jan  9 2012 should be week 2');\n    assert.equal(moment([2012, 0, 15]).format('w ww wo'),   '2 02 2.', 'Jan 15 2012 should be week 2');\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\n\n\nfunction localeModule (name, lifecycle) {\n    QUnit.module('locale:' + name, {\n        setup : function () {\n            moment.locale(name);\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            moment.locale('en');\n            teardownDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n    defineCommonLocaleTests(name, -1, -1);\n}\n\nlocaleModule('de-at');\n\ntest('parse', function (assert) {\n    var tests = 'Jänner Jän._Februar Febr._März Mrz._April Apr._Mai Mai_Juni Jun._Juli Jul._August Aug._September Sept._Oktober Okt._November Nov._Dezember Dez.'.split('_'), i;\n\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, Do MMMM YYYY, h:mm:ss a', 'Sonntag, 14. Februar 2010, 3:25:50 pm'],\n            ['ddd, hA', 'So., 3PM'],\n            ['M Mo MM MMMM MMM', '2 2. 02 Februar Febr.'],\n            ['YYYY YY', '2010 10'],\n            ['D Do DD', '14 14. 14'],\n            ['d do dddd ddd dd', '0 0. Sonntag So. So'],\n            ['DDD DDDo DDDD', '45 45. 045'],\n            ['w wo ww', '6 6. 06'],\n            ['h hh', '3 03'],\n            ['H HH', '15 15'],\n            ['m mm', '25 25'],\n            ['s ss', '50 50'],\n            ['a A', 'pm PM'],\n            ['[the] DDDo [day of the year]', 'the 45. day of the year'],\n            ['LTS', '15:25:50'],\n            ['L', '14.02.2010'],\n            ['LL', '14. Februar 2010'],\n            ['LLL', '14. Februar 2010 15:25'],\n            ['LLLL', 'Sonntag, 14. Februar 2010 15:25'],\n            ['l', '14.2.2010'],\n            ['ll', '14. Febr. 2010'],\n            ['lll', '14. Febr. 2010 15:25'],\n            ['llll', 'So., 14. Febr. 2010 15:25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1.', '1.');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2.', '2.');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3.', '3.');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4.', '4.');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5.', '5.');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6.', '6.');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7.', '7.');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8.', '8.');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9.', '9.');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10.', '10.');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11.', '11.');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12.', '12.');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13.', '13.');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14.', '14.');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15.', '15.');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16.', '16.');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17.', '17.');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18.', '18.');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19.', '19.');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20.', '20.');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21.', '21.');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22.', '22.');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23.', '23.');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24.', '24.');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25.', '25.');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26.', '26.');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27.', '27.');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28.', '28.');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29.', '29.');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30.', '30.');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31.', '31.');\n});\n\ntest('format month', function (assert) {\n    var expected = 'Jänner Jän._Februar Febr._März Mrz._April Apr._Mai Mai_Juni Jun._Juli Jul._August Aug._September Sept._Oktober Okt._November Nov._Dezember Dez.'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'Sonntag So. So_Montag Mo. Mo_Dienstag Di. Di_Mittwoch Mi. Mi_Donnerstag Do. Do_Freitag Fr. Fr_Samstag Sa. Sa'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true), 'ein paar Sekunden', '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true), 'eine Minute', '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true), 'eine Minute', '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true), '2 Minuten', '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true), '44 Minuten', '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true), 'eine Stunde', '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true), 'eine Stunde', '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true), '2 Stunden', '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true), '5 Stunden', '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true), '21 Stunden', '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true), 'ein Tag', '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true), 'ein Tag', '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true), '2 Tage', '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true), 'ein Tag', '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true), '5 Tage', '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true), '25 Tage', '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true), 'ein Monat', '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true), 'ein Monat', '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true), '2 Monate', '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true), '2 Monate', '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true), '3 Monate', '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true), 'ein Monat', '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true), '5 Monate', '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'ein Jahr', '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 Jahre', '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true), 'ein Jahr', '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true), '5 Jahre', '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'in ein paar Sekunden', 'prefix');\n    assert.equal(moment(0).from(30000), 'vor ein paar Sekunden', 'suffix');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'in ein paar Sekunden', 'in a few seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), 'in 5 Tagen', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                  'heute um 12:00 Uhr',   'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),     'heute um 12:25 Uhr',   'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),      'heute um 13:00 Uhr',   'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),      'morgen um 12:00 Uhr',  'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(), 'heute um 11:00 Uhr',   'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(), 'gestern um 12:00 Uhr', 'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(), m.format('dddd [um] LT [Uhr]'), 'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(), m.format('dddd [um] LT [Uhr]'), 'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(), m.format('dddd [um] LT [Uhr]'), 'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(), m.format('[letzten] dddd [um] LT [Uhr]'), 'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(), m.format('[letzten] dddd [um] LT [Uhr]'), 'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(), m.format('[letzten] dddd [um] LT [Uhr]'), 'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '1 week ago');\n    assert.equal(weeksFromNow.calendar(), weeksFromNow.format('L'), 'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(), weeksFromNow.format('L'), 'in 2 weeks');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2012, 0, 1]).format('w ww wo'), '52 52 52.', 'Jan  1 2012 should be week 52');\n    assert.equal(moment([2012, 0, 2]).format('w ww wo'), '1 01 1.', 'Jan  2 2012 should be week 1');\n    assert.equal(moment([2012, 0, 8]).format('w ww wo'), '1 01 1.', 'Jan  8 2012 should be week 1');\n    assert.equal(moment([2012, 0, 9]).format('w ww wo'), '2 02 2.', 'Jan  9 2012 should be week 2');\n    assert.equal(moment([2012, 0, 15]).format('w ww wo'), '2 02 2.', 'Jan 15 2012 should be week 2');\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\n\n\nfunction localeModule (name, lifecycle) {\n    QUnit.module('locale:' + name, {\n        setup : function () {\n            moment.locale(name);\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            moment.locale('en');\n            teardownDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n    defineCommonLocaleTests(name, -1, -1);\n}\n\nlocaleModule('de-ch');\n\ntest('parse', function (assert) {\n    var tests = 'Januar Jan._Februar Febr._März März_April April_Mai Mai_Juni Juni_Juli Juli_August Aug._September Sept._Oktober Okt._November Nov._Dezember Dez.'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, Do MMMM YYYY, h.mm.ss a',      'Sonntag, 14. Februar 2010, 3.25.50 pm'],\n            ['ddd, hA',                            'So, 3PM'],\n            ['M Mo MM MMMM MMM',                   '2 2. 02 Februar Febr.'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14. 14'],\n            ['d do dddd ddd dd',                   '0 0. Sonntag So So'],\n            ['DDD DDDo DDDD',                      '45 45. 045'],\n            ['w wo ww',                            '6 6. 06'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'pm PM'],\n            ['[the] DDDo [day of the year]',       'the 45. day of the year'],\n            ['LTS',                                '15.25.50'],\n            ['L',                                  '14.02.2010'],\n            ['LL',                                 '14. Februar 2010'],\n            ['LLL',                                '14. Februar 2010 15.25'],\n            ['LLLL',                               'Sonntag, 14. Februar 2010 15.25'],\n            ['l',                                  '14.2.2010'],\n            ['ll',                                 '14. Febr. 2010'],\n            ['lll',                                '14. Febr. 2010 15.25'],\n            ['llll',                               'So, 14. Febr. 2010 15.25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1.', '1.');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2.', '2.');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3.', '3.');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4.', '4.');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5.', '5.');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6.', '6.');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7.', '7.');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8.', '8.');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9.', '9.');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10.', '10.');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11.', '11.');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12.', '12.');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13.', '13.');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14.', '14.');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15.', '15.');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16.', '16.');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17.', '17.');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18.', '18.');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19.', '19.');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20.', '20.');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21.', '21.');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22.', '22.');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23.', '23.');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24.', '24.');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25.', '25.');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26.', '26.');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27.', '27.');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28.', '28.');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29.', '29.');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30.', '30.');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31.', '31.');\n});\n\ntest('format month', function (assert) {\n    var expected = 'Januar Jan._Februar Febr._März März_April April_Mai Mai_Juni Juni_Juli Juli_August Aug._September Sept._Oktober Okt._November Nov._Dezember Dez.'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'Sonntag So So_Montag Mo Mo_Dienstag Di Di_Mittwoch Mi Mi_Donnerstag Do Do_Freitag Fr Fr_Samstag Sa Sa'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'ein paar Sekunden',  '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'eine Minute',       '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'eine Minute',       '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 Minuten',          '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 Minuten',         '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'eine Stunde',       '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'eine Stunde',       '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 Stunden',          '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 Stunden',          '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 Stunden',         '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'ein Tag',          '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'ein Tag',          '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 Tage',            '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'ein Tag',          '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 Tage',            '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 Tage',           '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'ein Monat',        '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'ein Monat',        '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'ein Monat',        '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 Monate',          '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 Monate',          '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 Monate',          '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'ein Monat',        '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 Monate',          '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'ein Jahr',         '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 Jahre',           '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'ein Jahr',         '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 Jahre',           '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'in ein paar Sekunden', 'prefix');\n    assert.equal(moment(0).from(30000), 'vor ein paar Sekunden', 'suffix');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'in ein paar Sekunden', 'in a few seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), 'in 5 Tagen', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'heute um 12.00 Uhr',   'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'heute um 12.25 Uhr',   'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'heute um 13.00 Uhr',   'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'morgen um 12.00 Uhr',  'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'heute um 11.00 Uhr',   'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'gestern um 12.00 Uhr', 'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('dddd [um] LT [Uhr]'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd [um] LT [Uhr]'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd [um] LT [Uhr]'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('[letzten] dddd [um] LT [Uhr]'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[letzten] dddd [um] LT [Uhr]'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[letzten] dddd [um] LT [Uhr]'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2012, 0,  1]).format('w ww wo'), '52 52 52.', 'Jan  1 2012 should be week 52');\n    assert.equal(moment([2012, 0,  2]).format('w ww wo'),   '1 01 1.', 'Jan  2 2012 should be week 1');\n    assert.equal(moment([2012, 0,  8]).format('w ww wo'),   '1 01 1.', 'Jan  8 2012 should be week 1');\n    assert.equal(moment([2012, 0,  9]).format('w ww wo'),   '2 02 2.', 'Jan  9 2012 should be week 2');\n    assert.equal(moment([2012, 0, 15]).format('w ww wo'),   '2 02 2.', 'Jan 15 2012 should be week 2');\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\n\n\nfunction localeModule (name, lifecycle) {\n    QUnit.module('locale:' + name, {\n        setup : function () {\n            moment.locale(name);\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            moment.locale('en');\n            teardownDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n    defineCommonLocaleTests(name, -1, -1);\n}\n\nlocaleModule('de');\n\ntest('parse', function (assert) {\n    var tests = 'Januar Jan._Februar Febr._März Mrz._April Apr._Mai Mai_Juni Jun._Juli Jul._August Aug._September Sept._Oktober Okt._November Nov._Dezember Dez.'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, Do MMMM YYYY, h:mm:ss a',      'Sonntag, 14. Februar 2010, 3:25:50 pm'],\n            ['ddd, hA',                            'So., 3PM'],\n            ['M Mo MM MMMM MMM',                   '2 2. 02 Februar Febr.'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14. 14'],\n            ['d do dddd ddd dd',                   '0 0. Sonntag So. So'],\n            ['DDD DDDo DDDD',                      '45 45. 045'],\n            ['w wo ww',                            '6 6. 06'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'pm PM'],\n            ['[the] DDDo [day of the year]',       'the 45. day of the year'],\n            ['LTS',                                '15:25:50'],\n            ['L',                                  '14.02.2010'],\n            ['LL',                                 '14. Februar 2010'],\n            ['LLL',                                '14. Februar 2010 15:25'],\n            ['LLLL',                               'Sonntag, 14. Februar 2010 15:25'],\n            ['l',                                  '14.2.2010'],\n            ['ll',                                 '14. Febr. 2010'],\n            ['lll',                                '14. Febr. 2010 15:25'],\n            ['llll',                               'So., 14. Febr. 2010 15:25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1.', '1.');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2.', '2.');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3.', '3.');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4.', '4.');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5.', '5.');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6.', '6.');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7.', '7.');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8.', '8.');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9.', '9.');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10.', '10.');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11.', '11.');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12.', '12.');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13.', '13.');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14.', '14.');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15.', '15.');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16.', '16.');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17.', '17.');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18.', '18.');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19.', '19.');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20.', '20.');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21.', '21.');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22.', '22.');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23.', '23.');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24.', '24.');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25.', '25.');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26.', '26.');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27.', '27.');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28.', '28.');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29.', '29.');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30.', '30.');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31.', '31.');\n});\n\ntest('format month', function (assert) {\n    var expected = 'Januar Jan._Februar Febr._März Mrz._April Apr._Mai Mai_Juni Jun._Juli Jul._August Aug._September Sept._Oktober Okt._November Nov._Dezember Dez.'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'Sonntag So. So_Montag Mo. Mo_Dienstag Di. Di_Mittwoch Mi. Mi_Donnerstag Do. Do_Freitag Fr. Fr_Samstag Sa. Sa'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'ein paar Sekunden',  '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'eine Minute',       '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'eine Minute',       '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 Minuten',          '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 Minuten',         '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'eine Stunde',       '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'eine Stunde',       '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 Stunden',          '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 Stunden',          '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 Stunden',         '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'ein Tag',          '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'ein Tag',          '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 Tage',            '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'ein Tag',          '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 Tage',            '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 Tage',           '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'ein Monat',        '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'ein Monat',        '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'ein Monat',        '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 Monate',          '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 Monate',          '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 Monate',          '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'ein Monat',        '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 Monate',          '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'ein Jahr',         '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 Jahre',           '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'ein Jahr',         '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 Jahre',           '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'in ein paar Sekunden', 'prefix');\n    assert.equal(moment(0).from(30000), 'vor ein paar Sekunden', 'suffix');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'in ein paar Sekunden', 'in a few seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), 'in 5 Tagen', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'heute um 12:00 Uhr',   'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'heute um 12:25 Uhr',   'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'heute um 13:00 Uhr',   'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'morgen um 12:00 Uhr',  'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'heute um 11:00 Uhr',   'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'gestern um 12:00 Uhr', 'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('dddd [um] LT [Uhr]'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd [um] LT [Uhr]'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd [um] LT [Uhr]'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('[letzten] dddd [um] LT [Uhr]'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[letzten] dddd [um] LT [Uhr]'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[letzten] dddd [um] LT [Uhr]'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2012, 0,  1]).format('w ww wo'), '52 52 52.', 'Jan  1 2012 should be week 52');\n    assert.equal(moment([2012, 0,  2]).format('w ww wo'),   '1 01 1.', 'Jan  2 2012 should be week 1');\n    assert.equal(moment([2012, 0,  8]).format('w ww wo'),   '1 01 1.', 'Jan  8 2012 should be week 1');\n    assert.equal(moment([2012, 0,  9]).format('w ww wo'),   '2 02 2.', 'Jan  9 2012 should be week 2');\n    assert.equal(moment([2012, 0, 15]).format('w ww wo'),   '2 02 2.', 'Jan 15 2012 should be week 2');\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\n\n\nfunction localeModule (name, lifecycle) {\n    QUnit.module('locale:' + name, {\n        setup : function () {\n            moment.locale(name);\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            moment.locale('en');\n            teardownDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n    defineCommonLocaleTests(name, -1, -1);\n}\n\nlocaleModule('dv');\n\ntest('parse', function (assert) {\n    var i,\n        tests = [\n            'ޖެނުއަރީ',\n            'ފެބްރުއަރީ',\n            'މާރިޗު',\n            'އޭޕްރީލު',\n            'މޭ',\n            'ޖޫން',\n            'ޖުލައި',\n            'އޯގަސްޓު',\n            'ސެޕްޓެމްބަރު',\n            'އޮކްޓޯބަރު',\n            'ނޮވެމްބަރު',\n            'ޑިސެމްބަރު'\n        ];\n\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n\n    for (i = 0; i < 12; i++) {\n        equalTest(tests[i], 'MMM', i);\n        equalTest(tests[i], 'MMMM', i);\n        equalTest(tests[i].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, MMMM Do YYYY, h:mm:ss a',      'އާދިއްތަ، ފެބްރުއަރީ 14 2010، 3:25:50 މފ'],\n            ['ddd, hA',                            'އާދިއްތަ، 3މފ'],\n            ['M Mo MM MMMM MMM',                   '2 2 02 ފެބްރުއަރީ ފެބްރުއަރީ'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14 14'],\n            ['d do dddd ddd dd',                   '0 0 އާދިއްތަ އާދިއްތަ އާދި'],\n            ['DDD DDDo DDDD',                      '45 45 045'],\n            ['w wo ww',                            '8 8 08'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'މފ މފ'],\n            ['LTS',                                '15:25:50'],\n            ['L',                                  '14/2/2010'],\n            ['LL',                                 '14 ފެބްރުއަރީ 2010'],\n            ['LLL',                                '14 ފެބްރުއަރީ 2010 15:25'],\n            ['LLLL',                               'އާދިއްތަ 14 ފެބްރުއަރީ 2010 15:25'],\n            ['l',                                  '14/2/2010'],\n            ['ll',                                 '14 ފެބްރުއަރީ 2010'],\n            ['lll',                                '14 ފެބްރުއަރީ 2010 15:25'],\n            ['llll',                               'އާދިއްތަ 14 ފެބްރުއަރީ 2010 15:25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format month', function (assert) {\n    var i,\n        expected = [\n            'ޖެނުއަރީ',\n            'ފެބްރުއަރީ',\n            'މާރިޗު',\n            'އޭޕްރީލު',\n            'މޭ',\n            'ޖޫން',\n            'ޖުލައި',\n            'އޯގަސްޓު',\n            'ސެޕްޓެމްބަރު',\n            'އޮކްޓޯބަރު',\n            'ނޮވެމްބަރު',\n            'ޑިސެމްބަރު'\n        ];\n\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM'), expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var i,\n        expected = [\n            'އާދިއްތަ',\n            'ހޯމަ',\n            'އަންގާރަ',\n            'ބުދަ',\n            'ބުރާސްފަތި',\n            'ހުކުރު',\n            'ހޮނިހިރު'\n        ];\n\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd'), expected[i]);\n    }\n});\n\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'ސިކުންތުކޮޅެއް',  '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'މިނިޓެއް',        '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'މިނިޓެއް',        '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  'މިނިޓު 2',        '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  'މިނިޓު 44',       '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'ގަޑިއިރެއް',      '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'ގަޑިއިރެއް',      '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  'ގަޑިއިރު 2',      '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   'ގަޑިއިރު 5',      '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  'ގަޑިއިރު 21',     '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'ދުވަހެއް',        '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'ދުވަހެއް',        '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  'ދުވަސް 2',        '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'ދުވަހެއް',        '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   'ދުވަސް 5',        '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  'ދުވަސް 25',       '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'މަހެއް',          '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'މަހެއް',          '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'މަހެއް',          '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  'މަސް 2',          '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  'މަސް 2',          '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  'މަސް 3',          '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'މަހެއް',          '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   'މަސް 5',          '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'އަހަރެއް',        '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), 'އަހަރު 2',        '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'އަހަރެއް',        '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   'އަހަރު 5',        '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'ތެރޭގައި ސިކުންތުކޮޅެއް', 'prefix');\n    assert.equal(moment(0).from(30000), 'ކުރިން ސިކުންތުކޮޅެއް', 'suffix');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'ތެރޭގައި ސިކުންތުކޮޅެއް', 'in a few seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), 'ތެރޭގައި ދުވަސް 5', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'މިއަދު 12:00',  'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'މިއަދު 12:25',  'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'މިއަދު 13:00',  'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'މާދަމާ 12:00',  'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'މިއަދު 11:00',  'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'އިއްޔެ 12:00',  'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('dddd LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('[ފާއިތުވި] dddd LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[ފާއިތުވި] dddd LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[ފާއިތުވި] dddd LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2012, 0,  1]).format('w ww wo'),   '1 01 1', 'Jan  1 2012 should be week 1');\n    assert.equal(moment([2012, 0,  2]).format('w ww wo'),   '1 01 1', 'Jan  2 2012 should be week 1');\n    assert.equal(moment([2012, 0,  8]).format('w ww wo'),   '2 02 2', 'Jan  8 2012 should be week 2');\n    assert.equal(moment([2012, 0,  9]).format('w ww wo'),   '2 02 2', 'Jan  9 2012 should be week 2');\n    assert.equal(moment([2012, 0, 15]).format('w ww wo'),   '3 03 3', 'Jan 15 2012 should be week 3');\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\n\n\nfunction localeModule (name, lifecycle) {\n    QUnit.module('locale:' + name, {\n        setup : function () {\n            moment.locale(name);\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            moment.locale('en');\n            teardownDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n    defineCommonLocaleTests(name, -1, -1);\n}\n\nlocaleModule('el');\n\ntest('parse', function (assert) {\n    var i,\n        tests = 'Ιανουάριος Ιαν_Φεβρουάριος Φεβ_Μάρτιος Μαρ_Απρίλιος Απρ_Μάιος Μαϊ_Ιούνιος Ιουν_Ιούλιος Ιουλ_Αύγουστος Αυγ_Σεπτέμβριος Σεπ_Οκτώβριος Οκτ_Νοέμβριος Νοε_Δεκέμβριος Δεκ'.split('_');\n\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('parse meridiem', function (assert) {\n    var i,\n        b = moment(),\n        meridiemTests = [\n            // h a patterns, expected hours, isValid\n            ['10 πμ',   10, true],\n            ['10 μμ',   22, true],\n            ['10 π.μ.', 10, true],\n            ['10 μ.μ.', 22, true],\n            ['10 π',    10, true],\n            ['10 μ',    22, true],\n            ['10 ΠΜ',   10, true],\n            ['10 ΜΜ',   22, true],\n            ['10 Π.Μ.', 10, true],\n            ['10 Μ.Μ.', 22, true],\n            ['10 Π',    10, true],\n            ['10 Μ',    22, true],\n            ['10 am',   10, false],\n            ['10 pm',   10, false]\n        ],\n        parsed;\n\n    // test that a formatted moment including meridiem string can be parsed back to the same moment\n    assert.ok(b.isSame(moment(b.format('h:mm:ss a'), 'h:mm:ss a', 'el', true), 'seconds'), b.format('h:mm:ss a') + ' should be equal to ' + moment(b.format('h:mm:ss a'), 'h:mm:ss a', 'el', true).format('h:mm:ss a'));\n\n    // test that a formatted moment having a meridiem string can be parsed with strict flag\n    assert.ok(moment(b.format('h:mm:ss a'), 'h:mm:ss a', 'el', true).isValid(), b.format('h:mm:ss a') + ' should be parsed as valid');\n\n    for (i = 0; i < meridiemTests.length; i++) {\n        parsed = moment(meridiemTests[i][0], 'h a', 'el', true);\n        assert.equal(parsed.isValid(), meridiemTests[i][2], 'validity for ' + meridiemTests[i][0]);\n        if (parsed.isValid()) {\n            assert.equal(parsed.hours(), meridiemTests[i][1], 'hours for ' + meridiemTests[i][0]);\n        }\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, MMMM Do YYYY, h:mm:ss a',      'Κυριακή, Φεβρουάριος 14η 2010, 3:25:50 μμ'],\n            ['dddd, D MMMM YYYY, h:mm:ss a',       'Κυριακή, 14 Φεβρουαρίου 2010, 3:25:50 μμ'],\n            ['ddd, hA',                            'Κυρ, 3ΜΜ'],\n            ['dddd, MMMM YYYY',                    'Κυριακή, Φεβρουάριος 2010'],\n            ['M Mo MM MMMM MMM',                   '2 2η 02 Φεβρουάριος Φεβ'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14η 14'],\n            ['d do dddd ddd dd',                   '0 0η Κυριακή Κυρ Κυ'],\n            ['DDD DDDo DDDD',                      '45 45η 045'],\n            ['w wo ww',                            '6 6η 06'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'μμ ΜΜ'],\n            ['[the] DDDo [day of the year]',       'the 45η day of the year'],\n            ['LTS',                                '3:25:50 ΜΜ'],\n            ['L',                                  '14/02/2010'],\n            ['LL',                                 '14 Φεβρουαρίου 2010'],\n            ['LLL',                                '14 Φεβρουαρίου 2010 3:25 ΜΜ'],\n            ['LLLL',                               'Κυριακή, 14 Φεβρουαρίου 2010 3:25 ΜΜ'],\n            ['l',                                  '14/2/2010'],\n            ['ll',                                 '14 Φεβ 2010'],\n            ['lll',                                '14 Φεβ 2010 3:25 ΜΜ'],\n            ['llll',                               'Κυρ, 14 Φεβ 2010 3:25 ΜΜ']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1η', '1η');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2η', '2η');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3η', '3η');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4η', '4η');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5η', '5η');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6η', '6η');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7η', '7η');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8η', '8η');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9η', '9η');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10η', '10η');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11η', '11η');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12η', '12η');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13η', '13η');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14η', '14η');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15η', '15η');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16η', '16η');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17η', '17η');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18η', '18η');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19η', '19η');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20η', '20η');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21η', '21η');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22η', '22η');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23η', '23η');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24η', '24η');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25η', '25η');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26η', '26η');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27η', '27η');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28η', '28η');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29η', '29η');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30η', '30η');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31η', '31η');\n});\n\ntest('format month', function (assert) {\n    var i,\n        expected = 'Ιανουάριος Ιαν_Φεβρουάριος Φεβ_Μάρτιος Μαρ_Απρίλιος Απρ_Μάιος Μαϊ_Ιούνιος Ιουν_Ιούλιος Ιουλ_Αύγουστος Αυγ_Σεπτέμβριος Σεπ_Οκτώβριος Οκτ_Νοέμβριος Νοε_Δεκέμβριος Δεκ'.split('_');\n\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var i,\n        expected = 'Κυριακή Κυρ Κυ_Δευτέρα Δευ Δε_Τρίτη Τρι Τρ_Τετάρτη Τετ Τε_Πέμπτη Πεμ Πε_Παρασκευή Παρ Πα_Σάββατο Σαβ Σα'.split('_');\n\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'λίγα δευτερόλεπτα',   '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'ένα λεπτό',           '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'ένα λεπτό',           '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 λεπτά',             '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 λεπτά',            '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'μία ώρα',             '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'μία ώρα',             '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 ώρες',              '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 ώρες',              '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 ώρες',             '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'μία μέρα',            '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'μία μέρα',            '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 μέρες',             '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'μία μέρα',            '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 μέρες',             '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 μέρες',            '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'ένας μήνας',          '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'ένας μήνας',          '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'ένας μήνας',          '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 μήνες',             '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 μήνες',             '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 μήνες',             '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'ένας μήνας',          '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 μήνες',             '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'ένας χρόνος',         '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 χρόνια',            '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'ένας χρόνος',         '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 χρόνια',            '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'σε λίγα δευτερόλεπτα',  'prefix');\n    assert.equal(moment(0).from(30000), 'λίγα δευτερόλεπτα πριν', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'λίγα δευτερόλεπτα πριν',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'σε λίγα δευτερόλεπτα', 'in a few seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), 'σε 5 μέρες', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'Σήμερα στις 12:00 ΜΜ',     'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'Σήμερα στις 12:25 ΜΜ',     'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'Σήμερα στη 1:00 ΜΜ',      'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'Αύριο στις 12:00 ΜΜ',      'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'Σήμερα στις 11:00 ΠΜ',      'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'Χθες στις 12:00 ΜΜ',       'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('dddd [' + (m.hours() % 12 === 1 ? 'στη' : 'στις') + '] LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd [στις] LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd [στις] LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m, dayString;\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        dayString = m.day() === 6 ? '[το προηγούμενο Σάββατο]' : '[την προηγούμενη] dddd';\n        assert.equal(m.calendar(),       m.format(dayString + ' [' + (m.hours() % 12 === 1 ? 'στη' : 'στις') + '] LT'),  'Today - ' + i + ' days current time');\n        m.hours(1).minutes(30).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format(dayString + ' [στη] LT'),  'Today - ' + i + ' days one o clock');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format(dayString + ' [στις] LT'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format(dayString + ' [στις] LT'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('weeks year starting sunday format', function (assert) {\n    assert.equal(moment([2012, 0,  1]).format('w ww wo'), '52 52 52η', 'Jan  1 2012 should be week 52');\n    assert.equal(moment([2012, 0,  7]).format('w ww wo'),   '1 01 1η', 'Jan  7 2012 should be week 1');\n    assert.equal(moment([2012, 0,  8]).format('w ww wo'),   '1 01 1η', 'Jan  8 2012 should be week 1');\n    assert.equal(moment([2012, 0, 14]).format('w ww wo'),   '2 02 2η', 'Jan 14 2012 should be week 2');\n    assert.equal(moment([2012, 0, 15]).format('w ww wo'),   '2 02 2η', 'Jan 15 2012 should be week 2');\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\n\n\nfunction localeModule (name, lifecycle) {\n    QUnit.module('locale:' + name, {\n        setup : function () {\n            moment.locale(name);\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            moment.locale('en');\n            teardownDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n    defineCommonLocaleTests(name, -1, -1);\n}\n\nlocaleModule('en-au');\n\ntest('parse', function (assert) {\n    var tests = 'January Jan_February Feb_March Mar_April Apr_May May_June Jun_July Jul_August Aug_September Sep_October Oct_November Nov_December Dec'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, MMMM Do YYYY, h:mm:ss a',      'Sunday, February 14th 2010, 3:25:50 pm'],\n            ['ddd, hA',                            'Sun, 3PM'],\n            ['M Mo MM MMMM MMM',                   '2 2nd 02 February Feb'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14th 14'],\n            ['d do dddd ddd dd',                   '0 0th Sunday Sun Su'],\n            ['DDD DDDo DDDD',                      '45 45th 045'],\n            ['w wo ww',                            '6 6th 06'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'pm PM'],\n            ['[the] DDDo [day of the year]',       'the 45th day of the year'],\n            ['LTS',                                '3:25:50 PM'],\n            ['L',                                  '14/02/2010'],\n            ['LL',                                 '14 February 2010'],\n            ['LLL',                                '14 February 2010 3:25 PM'],\n            ['LLLL',                               'Sunday, 14 February 2010 3:25 PM'],\n            ['l',                                  '14/2/2010'],\n            ['ll',                                 '14 Feb 2010'],\n            ['lll',                                '14 Feb 2010 3:25 PM'],\n            ['llll',                               'Sun, 14 Feb 2010 3:25 PM']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1st', '1st');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2nd', '2nd');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3rd', '3rd');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4th', '4th');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5th', '5th');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6th', '6th');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7th', '7th');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8th', '8th');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9th', '9th');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10th', '10th');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11th', '11th');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12th', '12th');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13th', '13th');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14th', '14th');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15th', '15th');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16th', '16th');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17th', '17th');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18th', '18th');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19th', '19th');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20th', '20th');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21st', '21st');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22nd', '22nd');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23rd', '23rd');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24th', '24th');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25th', '25th');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26th', '26th');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27th', '27th');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28th', '28th');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29th', '29th');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30th', '30th');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31st', '31st');\n});\n\ntest('format month', function (assert) {\n    var expected = 'January Jan_February Feb_March Mar_April Apr_May May_June Jun_July Jul_August Aug_September Sep_October Oct_November Nov_December Dec'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'Sunday Sun Su_Monday Mon Mo_Tuesday Tue Tu_Wednesday Wed We_Thursday Thu Th_Friday Fri Fr_Saturday Sat Sa'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'a few seconds', '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'a minute',      '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'a minute',      '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 minutes',     '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 minutes',    '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'an hour',       '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'an hour',       '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 hours',       '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 hours',       '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 hours',      '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'a day',         '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'a day',         '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 days',        '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'a day',         '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 days',        '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 days',       '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'a month',       '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'a month',       '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'a month',       '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 months',      '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 months',      '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 months',      '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'a month',       '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 months',      '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'a year',        '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 years',       '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'a year',        '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 years',       '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'in a few seconds',  'prefix');\n    assert.equal(moment(0).from(30000), 'a few seconds ago', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'a few seconds ago',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'in a few seconds', 'in a few seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), 'in 5 days', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'Today at 12:00 PM',     'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'Today at 12:25 PM',     'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'Today at 1:00 PM',      'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'Tomorrow at 12:00 PM',  'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'Today at 11:00 AM',     'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'Yesterday at 12:00 PM', 'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('dddd [at] LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd [at] LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd [at] LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('[Last] dddd [at] LT'),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[Last] dddd [at] LT'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[Last] dddd [at] LT'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2012, 0,  1]).format('w ww wo'), '52 52 52nd', 'Jan  1 2012 should be week 52');\n    assert.equal(moment([2012, 0,  2]).format('w ww wo'),   '1 01 1st', 'Jan  2 2012 should be week 1');\n    assert.equal(moment([2012, 0,  8]).format('w ww wo'),   '1 01 1st', 'Jan  8 2012 should be week 1');\n    assert.equal(moment([2012, 0,  9]).format('w ww wo'),   '2 02 2nd', 'Jan  9 2012 should be week 2');\n    assert.equal(moment([2012, 0, 15]).format('w ww wo'),   '2 02 2nd', 'Jan 15 2012 should be week 2');\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\n\n\nfunction localeModule (name, lifecycle) {\n    QUnit.module('locale:' + name, {\n        setup : function () {\n            moment.locale(name);\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            moment.locale('en');\n            teardownDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n    defineCommonLocaleTests(name, -1, -1);\n}\n\nlocaleModule('en-ca');\n\ntest('parse', function (assert) {\n    var i,\n        tests = 'January Jan_February Feb_March Mar_April Apr_May May_June Jun_July Jul_August Aug_September Sep_October Oct_November Nov_December Dec'.split('_');\n\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, MMMM Do YYYY, h:mm:ss a',      'Sunday, February 14th 2010, 3:25:50 pm'],\n            ['ddd, hA',                            'Sun, 3PM'],\n            ['M Mo MM MMMM MMM',                   '2 2nd 02 February Feb'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14th 14'],\n            ['d do dddd ddd dd',                   '0 0th Sunday Sun Su'],\n            ['DDD DDDo DDDD',                      '45 45th 045'],\n            ['w wo ww',                            '8 8th 08'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'pm PM'],\n            ['[the] DDDo [day of the year]',       'the 45th day of the year'],\n            ['L',                                  '2010-02-14'],\n            ['LTS',                                '3:25:50 PM'],\n            ['LL',                                 'February 14, 2010'],\n            ['LLL',                                'February 14, 2010 3:25 PM'],\n            ['LLLL',                               'Sunday, February 14, 2010 3:25 PM'],\n            ['l',                                  '2010-2-14'],\n            ['ll',                                 'Feb 14, 2010'],\n            ['lll',                                'Feb 14, 2010 3:25 PM'],\n            ['llll',                               'Sun, Feb 14, 2010 3:25 PM']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1st', '1st');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2nd', '2nd');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3rd', '3rd');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4th', '4th');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5th', '5th');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6th', '6th');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7th', '7th');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8th', '8th');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9th', '9th');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10th', '10th');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11th', '11th');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12th', '12th');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13th', '13th');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14th', '14th');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15th', '15th');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16th', '16th');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17th', '17th');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18th', '18th');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19th', '19th');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20th', '20th');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21st', '21st');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22nd', '22nd');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23rd', '23rd');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24th', '24th');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25th', '25th');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26th', '26th');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27th', '27th');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28th', '28th');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29th', '29th');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30th', '30th');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31st', '31st');\n});\n\ntest('format month', function (assert) {\n    var i,\n        expected = 'January Jan_February Feb_March Mar_April Apr_May May_June Jun_July Jul_August Aug_September Sep_October Oct_November Nov_December Dec'.split('_');\n\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var i,\n        expected = 'Sunday Sun Su_Monday Mon Mo_Tuesday Tue Tu_Wednesday Wed We_Thursday Thu Th_Friday Fri Fr_Saturday Sat Sa'.split('_');\n\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'a few seconds', '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'a minute',      '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'a minute',      '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 minutes',     '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 minutes',    '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'an hour',       '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'an hour',       '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 hours',       '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 hours',       '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 hours',      '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'a day',         '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'a day',         '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 days',        '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'a day',         '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 days',        '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 days',       '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'a month',       '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'a month',       '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'a month',       '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 months',      '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 months',      '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 months',      '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'a month',       '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 months',      '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'a year',        '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 years',       '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'a year',        '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 years',       '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'in a few seconds',  'prefix');\n    assert.equal(moment(0).from(30000), 'a few seconds ago', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'a few seconds ago',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'in a few seconds', 'in a few seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), 'in 5 days', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'Today at 12:00 PM',     'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'Today at 12:25 PM',     'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'Today at 1:00 PM',      'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'Tomorrow at 12:00 PM',  'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'Today at 11:00 AM',     'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'Yesterday at 12:00 PM', 'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('dddd [at] LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd [at] LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd [at] LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('[Last] dddd [at] LT'),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[Last] dddd [at] LT'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[Last] dddd [at] LT'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('weeks year starting sunday format', function (assert) {\n    assert.equal(moment([2012, 0,  1]).format('w ww wo'), '1 01 1st', 'Jan  1 2012 should be week 1');\n    assert.equal(moment([2012, 0,  7]).format('w ww wo'), '1 01 1st', 'Jan  7 2012 should be week 1');\n    assert.equal(moment([2012, 0,  8]).format('w ww wo'), '2 02 2nd', 'Jan  8 2012 should be week 2');\n    assert.equal(moment([2012, 0, 14]).format('w ww wo'), '2 02 2nd', 'Jan 14 2012 should be week 2');\n    assert.equal(moment([2012, 0, 15]).format('w ww wo'), '3 03 3rd', 'Jan 15 2012 should be week 3');\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\n\n\nfunction localeModule (name, lifecycle) {\n    QUnit.module('locale:' + name, {\n        setup : function () {\n            moment.locale(name);\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            moment.locale('en');\n            teardownDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n    defineCommonLocaleTests(name, -1, -1);\n}\n\nlocaleModule('en-gb');\n\ntest('parse', function (assert) {\n    var tests = 'January Jan_February Feb_March Mar_April Apr_May May_June Jun_July Jul_August Aug_September Sep_October Oct_November Nov_December Dec'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, MMMM Do YYYY, h:mm:ss a',      'Sunday, February 14th 2010, 3:25:50 pm'],\n            ['ddd, hA',                            'Sun, 3PM'],\n            ['M Mo MM MMMM MMM',                   '2 2nd 02 February Feb'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14th 14'],\n            ['d do dddd ddd dd',                   '0 0th Sunday Sun Su'],\n            ['DDD DDDo DDDD',                      '45 45th 045'],\n            ['w wo ww',                            '6 6th 06'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'pm PM'],\n            ['[the] DDDo [day of the year]',       'the 45th day of the year'],\n            ['LTS',                                '15:25:50'],\n            ['L',                                  '14/02/2010'],\n            ['LL',                                 '14 February 2010'],\n            ['LLL',                                '14 February 2010 15:25'],\n            ['LLLL',                               'Sunday, 14 February 2010 15:25'],\n            ['l',                                  '14/2/2010'],\n            ['ll',                                 '14 Feb 2010'],\n            ['lll',                                '14 Feb 2010 15:25'],\n            ['llll',                               'Sun, 14 Feb 2010 15:25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1st', '1st');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2nd', '2nd');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3rd', '3rd');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4th', '4th');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5th', '5th');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6th', '6th');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7th', '7th');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8th', '8th');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9th', '9th');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10th', '10th');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11th', '11th');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12th', '12th');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13th', '13th');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14th', '14th');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15th', '15th');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16th', '16th');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17th', '17th');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18th', '18th');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19th', '19th');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20th', '20th');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21st', '21st');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22nd', '22nd');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23rd', '23rd');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24th', '24th');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25th', '25th');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26th', '26th');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27th', '27th');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28th', '28th');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29th', '29th');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30th', '30th');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31st', '31st');\n});\n\ntest('format month', function (assert) {\n    var expected = 'January Jan_February Feb_March Mar_April Apr_May May_June Jun_July Jul_August Aug_September Sep_October Oct_November Nov_December Dec'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'Sunday Sun Su_Monday Mon Mo_Tuesday Tue Tu_Wednesday Wed We_Thursday Thu Th_Friday Fri Fr_Saturday Sat Sa'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'a few seconds', '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'a minute',      '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'a minute',      '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 minutes',     '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 minutes',    '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'an hour',       '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'an hour',       '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 hours',       '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 hours',       '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 hours',      '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'a day',         '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'a day',         '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 days',        '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'a day',         '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 days',        '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 days',       '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'a month',       '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'a month',       '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'a month',       '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 months',      '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 months',      '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 months',      '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'a month',       '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 months',      '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'a year',        '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 years',       '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'a year',        '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 years',       '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'in a few seconds',  'prefix');\n    assert.equal(moment(0).from(30000), 'a few seconds ago', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'a few seconds ago',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'in a few seconds', 'in a few seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), 'in 5 days', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'Today at 12:00',      'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'Today at 12:25',      'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'Today at 13:00',      'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'Tomorrow at 12:00',   'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'Today at 11:00',      'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'Yesterday at 12:00',  'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('dddd [at] LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd [at] LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd [at] LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('[Last] dddd [at] LT'),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[Last] dddd [at] LT'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[Last] dddd [at] LT'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2012, 0,  1]).format('w ww wo'), '52 52 52nd', 'Jan  1 2012 should be week 52');\n    assert.equal(moment([2012, 0,  2]).format('w ww wo'),   '1 01 1st', 'Jan  2 2012 should be week 1');\n    assert.equal(moment([2012, 0,  8]).format('w ww wo'),   '1 01 1st', 'Jan  8 2012 should be week 1');\n    assert.equal(moment([2012, 0,  9]).format('w ww wo'),   '2 02 2nd', 'Jan  9 2012 should be week 2');\n    assert.equal(moment([2012, 0, 15]).format('w ww wo'),   '2 02 2nd', 'Jan 15 2012 should be week 2');\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\n\n\nfunction localeModule (name, lifecycle) {\n    QUnit.module('locale:' + name, {\n        setup : function () {\n            moment.locale(name);\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            moment.locale('en');\n            teardownDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n    defineCommonLocaleTests(name, -1, -1);\n}\n\nlocaleModule('en-ie');\n\ntest('parse', function (assert) {\n    var tests = 'January Jan_February Feb_March Mar_April Apr_May May_June Jun_July Jul_August Aug_September Sep_October Oct_November Nov_December Dec'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, MMMM Do YYYY, h:mm:ss a',      'Sunday, February 14th 2010, 3:25:50 pm'],\n            ['ddd, hA',                            'Sun, 3PM'],\n            ['M Mo MM MMMM MMM',                   '2 2nd 02 February Feb'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14th 14'],\n            ['d do dddd ddd dd',                   '0 0th Sunday Sun Su'],\n            ['DDD DDDo DDDD',                      '45 45th 045'],\n            ['w wo ww',                            '6 6th 06'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'pm PM'],\n            ['[the] DDDo [day of the year]',       'the 45th day of the year'],\n            ['LTS',                                '15:25:50'],\n            ['L',                                  '14-02-2010'],\n            ['LL',                                 '14 February 2010'],\n            ['LLL',                                '14 February 2010 15:25'],\n            ['LLLL',                               'Sunday 14 February 2010 15:25'],\n            ['l',                                  '14-2-2010'],\n            ['ll',                                 '14 Feb 2010'],\n            ['lll',                                '14 Feb 2010 15:25'],\n            ['llll',                               'Sun 14 Feb 2010 15:25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1st', '1st');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2nd', '2nd');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3rd', '3rd');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4th', '4th');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5th', '5th');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6th', '6th');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7th', '7th');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8th', '8th');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9th', '9th');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10th', '10th');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11th', '11th');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12th', '12th');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13th', '13th');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14th', '14th');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15th', '15th');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16th', '16th');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17th', '17th');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18th', '18th');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19th', '19th');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20th', '20th');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21st', '21st');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22nd', '22nd');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23rd', '23rd');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24th', '24th');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25th', '25th');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26th', '26th');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27th', '27th');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28th', '28th');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29th', '29th');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30th', '30th');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31st', '31st');\n});\n\ntest('format month', function (assert) {\n    var expected = 'January Jan_February Feb_March Mar_April Apr_May May_June Jun_July Jul_August Aug_September Sep_October Oct_November Nov_December Dec'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'Sunday Sun Su_Monday Mon Mo_Tuesday Tue Tu_Wednesday Wed We_Thursday Thu Th_Friday Fri Fr_Saturday Sat Sa'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'a few seconds', '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'a minute',      '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'a minute',      '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 minutes',     '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 minutes',    '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'an hour',       '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'an hour',       '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 hours',       '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 hours',       '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 hours',      '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'a day',         '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'a day',         '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 days',        '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'a day',         '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 days',        '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 days',       '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'a month',       '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'a month',       '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'a month',       '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 months',      '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 months',      '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 months',      '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'a month',       '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 months',      '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'a year',        '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 years',       '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'a year',        '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 years',       '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'in a few seconds',  'prefix');\n    assert.equal(moment(0).from(30000), 'a few seconds ago', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'a few seconds ago',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'in a few seconds', 'in a few seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), 'in 5 days', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'Today at 12:00',      'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'Today at 12:25',      'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'Today at 13:00',      'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'Tomorrow at 12:00',   'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'Today at 11:00',      'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'Yesterday at 12:00',  'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('dddd [at] LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd [at] LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd [at] LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('[Last] dddd [at] LT'),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[Last] dddd [at] LT'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[Last] dddd [at] LT'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2012, 0,  1]).format('w ww wo'), '52 52 52nd', 'Jan  1 2012 should be week 52');\n    assert.equal(moment([2012, 0,  2]).format('w ww wo'),   '1 01 1st', 'Jan  2 2012 should be week 1');\n    assert.equal(moment([2012, 0,  8]).format('w ww wo'),   '1 01 1st', 'Jan  8 2012 should be week 1');\n    assert.equal(moment([2012, 0,  9]).format('w ww wo'),   '2 02 2nd', 'Jan  9 2012 should be week 2');\n    assert.equal(moment([2012, 0, 15]).format('w ww wo'),   '2 02 2nd', 'Jan 15 2012 should be week 2');\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\n\n\nfunction localeModule (name, lifecycle) {\n    QUnit.module('locale:' + name, {\n        setup : function () {\n            moment.locale(name);\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            moment.locale('en');\n            teardownDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n    defineCommonLocaleTests(name, -1, -1);\n}\n\nlocaleModule('en-nz');\n\ntest('parse', function (assert) {\n    var tests = 'January Jan_February Feb_March Mar_April Apr_May May_June Jun_July Jul_August Aug_September Sep_October Oct_November Nov_December Dec'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, MMMM Do YYYY, h:mm:ss a',      'Sunday, February 14th 2010, 3:25:50 pm'],\n            ['ddd, hA',                            'Sun, 3PM'],\n            ['M Mo MM MMMM MMM',                   '2 2nd 02 February Feb'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14th 14'],\n            ['d do dddd ddd dd',                   '0 0th Sunday Sun Su'],\n            ['DDD DDDo DDDD',                      '45 45th 045'],\n            ['w wo ww',                            '6 6th 06'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'pm PM'],\n            ['[the] DDDo [day of the year]',       'the 45th day of the year'],\n            ['LTS',                                '3:25:50 PM'],\n            ['L',                                  '14/02/2010'],\n            ['LL',                                 '14 February 2010'],\n            ['LLL',                                '14 February 2010 3:25 PM'],\n            ['LLLL',                               'Sunday, 14 February 2010 3:25 PM'],\n            ['l',                                  '14/2/2010'],\n            ['ll',                                 '14 Feb 2010'],\n            ['lll',                                '14 Feb 2010 3:25 PM'],\n            ['llll',                               'Sun, 14 Feb 2010 3:25 PM']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1st', '1st');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2nd', '2nd');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3rd', '3rd');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4th', '4th');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5th', '5th');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6th', '6th');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7th', '7th');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8th', '8th');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9th', '9th');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10th', '10th');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11th', '11th');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12th', '12th');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13th', '13th');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14th', '14th');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15th', '15th');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16th', '16th');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17th', '17th');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18th', '18th');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19th', '19th');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20th', '20th');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21st', '21st');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22nd', '22nd');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23rd', '23rd');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24th', '24th');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25th', '25th');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26th', '26th');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27th', '27th');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28th', '28th');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29th', '29th');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30th', '30th');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31st', '31st');\n});\n\ntest('format month', function (assert) {\n    var expected = 'January Jan_February Feb_March Mar_April Apr_May May_June Jun_July Jul_August Aug_September Sep_October Oct_November Nov_December Dec'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'Sunday Sun Su_Monday Mon Mo_Tuesday Tue Tu_Wednesday Wed We_Thursday Thu Th_Friday Fri Fr_Saturday Sat Sa'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'a few seconds', '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'a minute',      '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'a minute',      '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 minutes',     '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 minutes',    '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'an hour',       '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'an hour',       '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 hours',       '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 hours',       '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 hours',      '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'a day',         '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'a day',         '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 days',        '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'a day',         '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 days',        '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 days',       '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'a month',       '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'a month',       '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'a month',       '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 months',      '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 months',      '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 months',      '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'a month',       '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 months',      '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'a year',        '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 years',       '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'a year',        '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 years',       '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'in a few seconds',  'prefix');\n    assert.equal(moment(0).from(30000), 'a few seconds ago', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'a few seconds ago',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'in a few seconds', 'in a few seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), 'in 5 days', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'Today at 12:00 PM',     'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'Today at 12:25 PM',     'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'Today at 1:00 PM',      'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'Tomorrow at 12:00 PM',  'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'Today at 11:00 AM',     'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'Yesterday at 12:00 PM', 'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('dddd [at] LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd [at] LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd [at] LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('[Last] dddd [at] LT'),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[Last] dddd [at] LT'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[Last] dddd [at] LT'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2012, 0,  1]).format('w ww wo'), '52 52 52nd', 'Jan  1 2012 should be week 52');\n    assert.equal(moment([2012, 0,  2]).format('w ww wo'),   '1 01 1st', 'Jan  2 2012 should be week 1');\n    assert.equal(moment([2012, 0,  8]).format('w ww wo'),   '1 01 1st', 'Jan  8 2012 should be week 1');\n    assert.equal(moment([2012, 0,  9]).format('w ww wo'),   '2 02 2nd', 'Jan  9 2012 should be week 2');\n    assert.equal(moment([2012, 0, 15]).format('w ww wo'),   '2 02 2nd', 'Jan 15 2012 should be week 2');\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\n\n\nfunction localeModule (name, lifecycle) {\n    QUnit.module('locale:' + name, {\n        setup : function () {\n            moment.locale(name);\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            moment.locale('en');\n            teardownDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n    defineCommonLocaleTests(name, -1, -1);\n}\n\nlocaleModule('en');\n\ntest('parse', function (assert) {\n    var i,\n        tests = 'January Jan_February Feb_March Mar_April Apr_May May_June Jun_July Jul_August Aug_September Sep_October Oct_November Nov_December Dec'.split('_');\n\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, MMMM Do YYYY, h:mm:ss a',      'Sunday, February 14th 2010, 3:25:50 pm'],\n            ['ddd, hA',                            'Sun, 3PM'],\n            ['M Mo MM MMMM MMM',                   '2 2nd 02 February Feb'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14th 14'],\n            ['d do dddd ddd dd',                   '0 0th Sunday Sun Su'],\n            ['DDD DDDo DDDD',                      '45 45th 045'],\n            ['w wo ww',                            '8 8th 08'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'pm PM'],\n            ['[the] DDDo [day of the year]',       'the 45th day of the year'],\n            ['LTS',                                '3:25:50 PM'],\n            ['L',                                  '02/14/2010'],\n            ['LL',                                 'February 14, 2010'],\n            ['LLL',                                'February 14, 2010 3:25 PM'],\n            ['LLLL',                               'Sunday, February 14, 2010 3:25 PM'],\n            ['l',                                  '2/14/2010'],\n            ['ll',                                 'Feb 14, 2010'],\n            ['lll',                                'Feb 14, 2010 3:25 PM'],\n            ['llll',                               'Sun, Feb 14, 2010 3:25 PM']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1st', '1st');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2nd', '2nd');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3rd', '3rd');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4th', '4th');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5th', '5th');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6th', '6th');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7th', '7th');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8th', '8th');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9th', '9th');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10th', '10th');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11th', '11th');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12th', '12th');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13th', '13th');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14th', '14th');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15th', '15th');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16th', '16th');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17th', '17th');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18th', '18th');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19th', '19th');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20th', '20th');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21st', '21st');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22nd', '22nd');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23rd', '23rd');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24th', '24th');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25th', '25th');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26th', '26th');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27th', '27th');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28th', '28th');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29th', '29th');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30th', '30th');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31st', '31st');\n});\n\ntest('format month', function (assert) {\n    var i,\n        expected = 'January Jan_February Feb_March Mar_April Apr_May May_June Jun_July Jul_August Aug_September Sep_October Oct_November Nov_December Dec'.split('_');\n\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var i,\n        expected = 'Sunday Sun Su_Monday Mon Mo_Tuesday Tue Tu_Wednesday Wed We_Thursday Thu Th_Friday Fri Fr_Saturday Sat Sa'.split('_');\n\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'a few seconds', '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'a minute',      '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'a minute',      '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 minutes',     '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 minutes',    '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'an hour',       '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'an hour',       '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 hours',       '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 hours',       '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 hours',      '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'a day',         '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'a day',         '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 days',        '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'a day',         '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 days',        '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 days',       '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'a month',       '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'a month',       '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'a month',       '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 months',      '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 months',      '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 months',      '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'a month',       '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 months',      '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'a year',        '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 years',       '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'a year',        '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 years',       '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'in a few seconds',  'prefix');\n    assert.equal(moment(0).from(30000), 'a few seconds ago', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'a few seconds ago',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'in a few seconds', 'in a few seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), 'in 5 days', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'Today at 12:00 PM',     'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'Today at 12:25 PM',     'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'Today at 1:00 PM',      'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'Tomorrow at 12:00 PM',  'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'Today at 11:00 AM',     'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'Yesterday at 12:00 PM', 'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('dddd [at] LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd [at] LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd [at] LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('[Last] dddd [at] LT'),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[Last] dddd [at] LT'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[Last] dddd [at] LT'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('weeks year starting sunday format', function (assert) {\n    assert.equal(moment([2012, 0,  1]).format('w ww wo'), '1 01 1st', 'Jan  1 2012 should be week 1');\n    assert.equal(moment([2012, 0,  7]).format('w ww wo'), '1 01 1st', 'Jan  7 2012 should be week 1');\n    assert.equal(moment([2012, 0,  8]).format('w ww wo'), '2 02 2nd', 'Jan  8 2012 should be week 2');\n    assert.equal(moment([2012, 0, 14]).format('w ww wo'), '2 02 2nd', 'Jan 14 2012 should be week 2');\n    assert.equal(moment([2012, 0, 15]).format('w ww wo'), '3 03 3rd', 'Jan 15 2012 should be week 3');\n});\n\ntest('weekdays strict parsing', function (assert) {\n    var m = moment('2015-01-01T12', moment.ISO_8601, true),\n        enLocale = moment.localeData('en');\n\n    for (var i = 0; i < 7; ++i) {\n        assert.equal(moment(enLocale.weekdays(m.day(i), ''), 'dddd', true).isValid(), true, 'parse weekday ' + i);\n        assert.equal(moment(enLocale.weekdaysShort(m.day(i), ''), 'ddd', true).isValid(), true, 'parse short weekday ' + i);\n        assert.equal(moment(enLocale.weekdaysMin(m.day(i), ''), 'dd', true).isValid(), true, 'parse min weekday ' + i);\n\n        // negative tests\n        assert.equal(moment(enLocale.weekdaysMin(m.day(i), ''), 'ddd', true).isValid(), false, 'parse short weekday ' + i);\n        assert.equal(moment(enLocale.weekdaysShort(m.day(i), ''), 'dd', true).isValid(), false, 'parse min weekday ' + i);\n    }\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\n\n\nfunction localeModule (name, lifecycle) {\n    QUnit.module('locale:' + name, {\n        setup : function () {\n            moment.locale(name);\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            moment.locale('en');\n            teardownDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n    defineCommonLocaleTests(name, -1, -1);\n}\n\nlocaleModule('eo');\n\ntest('parse', function (assert) {\n    var tests = 'januaro jan_februaro feb_marto mar_aprilo apr_majo maj_junio jun_julio jul_aŭgusto aŭg_septembro sep_oktobro okt_novembro nov_decembro dec'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, MMMM Do YYYY, h:mm:ss a',      'dimanĉo, februaro 14a 2010, 3:25:50 p.t.m.'],\n            ['ddd, hA',                            'dim, 3P.T.M.'],\n            ['M Mo MM MMMM MMM',                   '2 2a 02 februaro feb'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14a 14'],\n            ['d do dddd ddd dd',                   '0 0a dimanĉo dim di'],\n            ['DDD DDDo DDDD',                      '45 45a 045'],\n            ['w wo ww',                            '7 7a 07'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'p.t.m. P.T.M.'],\n            ['[la] DDDo [tago] [de] [la] [jaro]',  'la 45a tago de la jaro'],\n            ['LTS',                                '15:25:50'],\n            ['L',                                  '2010-02-14'],\n            ['LL',                                 '14-a de februaro, 2010'],\n            ['LLL',                                '14-a de februaro, 2010 15:25'],\n            ['LLLL',                               'dimanĉo, la 14-a de februaro, 2010 15:25'],\n            ['l',                                  '2010-2-14'],\n            ['ll',                                 '14-a de feb, 2010'],\n            ['lll',                                '14-a de feb, 2010 15:25'],\n            ['llll',                               'dim, la 14-a de feb, 2010 15:25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1a', '1a');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2a', '2a');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3a', '3a');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4a', '4a');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5a', '5a');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6a', '6a');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7a', '7a');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8a', '8a');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9a', '9a');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10a', '10a');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11a', '11a');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12a', '12a');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13a', '13a');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14a', '14a');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15a', '15a');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16a', '16a');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17a', '17a');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18a', '18a');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19a', '19a');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20a', '20a');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21a', '21a');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22a', '22a');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23a', '23a');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24a', '24a');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25a', '25a');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26a', '26a');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27a', '27a');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28a', '28a');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29a', '29a');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30a', '30a');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31a', '31a');\n});\n\ntest('format month', function (assert) {\n    var expected = 'januaro jan_februaro feb_marto mar_aprilo apr_majo maj_junio jun_julio jul_aŭgusto aŭg_septembro sep_oktobro okt_novembro nov_decembro dec'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'dimanĉo dim di_lundo lun lu_mardo mard ma_merkredo merk me_ĵaŭdo ĵaŭ ĵa_vendredo ven ve_sabato sab sa'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'sekundoj', '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'minuto',      '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'minuto',      '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 minutoj',     '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 minutoj',    '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'horo',       '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'horo',       '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 horoj',       '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 horoj',       '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 horoj',      '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'tago',         '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'tago',         '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 tagoj',        '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'tago',         '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 tagoj',        '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 tagoj',       '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'monato',       '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'monato',       '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'monato',       '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 monatoj',      '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 monatoj',      '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 monatoj',      '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'monato',       '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 monatoj',      '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'jaro',        '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 jaroj',       '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'jaro',        '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 jaroj',       '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'post sekundoj',  'post prefix');\n    assert.equal(moment(0).from(30000), 'antaŭ sekundoj', 'antaŭ prefix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'antaŭ sekundoj',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'post sekundoj', 'post sekundoj');\n    assert.equal(moment().add({d: 5}).fromNow(), 'post 5 tagoj', 'post 5 tagoj');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'Hodiaŭ je 12:00',     'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'Hodiaŭ je 12:25',     'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'Hodiaŭ je 13:00',     'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'Morgaŭ je 12:00',     'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'Hodiaŭ je 11:00',     'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'Hieraŭ je 12:00',     'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('dddd [je] LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd [je] LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd [je] LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('[pasinta] dddd [je] LT'),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[pasinta] dddd [je] LT'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[pasinta] dddd [je] LT'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2011, 11, 26]).format('w ww wo'), '1 01 1a', 'Dec 26 2011 should be week 1');\n    assert.equal(moment([2012,  0,  1]).format('w ww wo'), '1 01 1a', 'Jan  1 2012 should be week 1');\n    assert.equal(moment([2012,  0,  2]).format('w ww wo'), '2 02 2a', 'Jan  2 2012 should be week 2');\n    assert.equal(moment([2012,  0,  8]).format('w ww wo'), '2 02 2a', 'Jan  8 2012 should be week 2');\n    assert.equal(moment([2012,  0,  9]).format('w ww wo'), '3 03 3a', 'Jan  9 2012 should be week 3');\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\n\n\nfunction localeModule (name, lifecycle) {\n    QUnit.module('locale:' + name, {\n        setup : function () {\n            moment.locale(name);\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            moment.locale('en');\n            teardownDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n    defineCommonLocaleTests(name, -1, -1);\n}\n\nlocaleModule('es-do');\n\ntest('parse', function (assert) {\n    var tests = 'enero ene._febrero feb._marzo mar._abril abr._mayo may._junio jun._julio jul._agosto ago._septiembre sep._octubre oct._noviembre nov._diciembre dic.'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, MMMM Do YYYY, h:mm:ss a',      'domingo, febrero 14º 2010, 3:25:50 pm'],\n            ['ddd, hA',                            'dom., 3PM'],\n            ['M Mo MM MMMM MMM',                   '2 2º 02 febrero feb.'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14º 14'],\n            ['d do dddd ddd dd',                   '0 0º domingo dom. do'],\n            ['DDD DDDo DDDD',                      '45 45º 045'],\n            ['w wo ww',                            '6 6º 06'],\n            ['YYYY-MMM-DD',                        '2010-feb-14'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'pm PM'],\n            ['[the] DDDo [day of the year]',       'the 45º day of the year'],\n            ['LTS',                                '3:25:50 PM'],\n            ['L',                                  '14/02/2010'],\n            ['LL',                                 '14 de febrero de 2010'],\n            ['LLL',                                '14 de febrero de 2010 3:25 PM'],\n            ['LLLL',                               'domingo, 14 de febrero de 2010 3:25 PM'],\n            ['l',                                  '14/2/2010'],\n            ['ll',                                 '14 de feb. de 2010'],\n            ['lll',                                '14 de feb. de 2010 3:25 PM'],\n            ['llll',                               'dom., 14 de feb. de 2010 3:25 PM']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1º', '1º');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2º', '2º');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3º', '3º');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4º', '4º');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5º', '5º');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6º', '6º');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7º', '7º');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8º', '8º');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9º', '9º');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10º', '10º');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11º', '11º');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12º', '12º');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13º', '13º');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14º', '14º');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15º', '15º');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16º', '16º');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17º', '17º');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18º', '18º');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19º', '19º');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20º', '20º');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21º', '21º');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22º', '22º');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23º', '23º');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24º', '24º');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25º', '25º');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26º', '26º');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27º', '27º');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28º', '28º');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29º', '29º');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30º', '30º');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31º', '31º');\n});\n\ntest('format month', function (assert) {\n    var expected = 'enero ene._febrero feb._marzo mar._abril abr._mayo may._junio jun._julio jul._agosto ago._septiembre sep._octubre oct._noviembre nov._diciembre dic.'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'domingo dom. do_lunes lun. lu_martes mar. ma_miércoles mié. mi_jueves jue. ju_viernes vie. vi_sábado sáb. sá'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'unos segundos', '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'un minuto',      '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'un minuto',      '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 minutos',     '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 minutos',    '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'una hora',       '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'una hora',       '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 horas',       '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 horas',       '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 horas',      '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'un día',         '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'un día',         '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 días',        '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'un día',         '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 días',        '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 días',       '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'un mes',       '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'un mes',       '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'un mes',       '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 meses',      '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 meses',      '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 meses',      '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'un mes',       '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 meses',      '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'un año',        '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 años',       '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'un año',        '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 años',       '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'en unos segundos',  'prefix');\n    assert.equal(moment(0).from(30000), 'hace unos segundos', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'hace unos segundos',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'en unos segundos', 'en unos segundos');\n    assert.equal(moment().add({d: 5}).fromNow(), 'en 5 días', 'en 5 días');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                       'hoy a las 12:00 PM',     'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),          'hoy a las 12:25 PM',     'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),           'hoy a las 1:00 PM',     'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),           'mañana a las 12:00 PM',  'tomorrow at the same time');\n    assert.equal(moment(a).add({d: 1, h : -1}).calendar(),   'mañana a las 11:00 AM',   'tomorrow minus 1 hour');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),      'hoy a las 11:00 AM',     'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),      'ayer a las 12:00 PM',    'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('dddd [a la' + ((m.hours() !== 1) ? 's' : '') + '] LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd [a la' + ((m.hours() !== 1) ? 's' : '') + '] LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd [a la' + ((m.hours() !== 1) ? 's' : '') + '] LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('[el] dddd [pasado a la' + ((m.hours() !== 1) ? 's' : '') + '] LT'),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[el] dddd [pasado a la' + ((m.hours() !== 1) ? 's' : '') + '] LT'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[el] dddd [pasado a la' + ((m.hours() !== 1) ? 's' : '') + '] LT'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2012, 0,  1]).format('w ww wo'), '52 52 52º', 'Jan  1 2012 should be week 52');\n    assert.equal(moment([2012, 0,  2]).format('w ww wo'),   '1 01 1º', 'Jan  2 2012 should be week 1');\n    assert.equal(moment([2012, 0,  8]).format('w ww wo'),   '1 01 1º', 'Jan  8 2012 should be week 1');\n    assert.equal(moment([2012, 0,  9]).format('w ww wo'),   '2 02 2º', 'Jan  9 2012 should be week 2');\n    assert.equal(moment([2012, 0, 15]).format('w ww wo'),   '2 02 2º', 'Jan 15 2012 should be week 2');\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\n\n\nfunction localeModule (name, lifecycle) {\n    QUnit.module('locale:' + name, {\n        setup : function () {\n            moment.locale(name);\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            moment.locale('en');\n            teardownDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n    defineCommonLocaleTests(name, -1, -1);\n}\n\nlocaleModule('es');\n\ntest('parse', function (assert) {\n    var tests = 'enero ene._febrero feb._marzo mar._abril abr._mayo may._junio jun._julio jul._agosto ago._septiembre sep._octubre oct._noviembre nov._diciembre dic.'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, MMMM Do YYYY, h:mm:ss a',      'domingo, febrero 14º 2010, 3:25:50 pm'],\n            ['ddd, hA',                            'dom., 3PM'],\n            ['M Mo MM MMMM MMM',                   '2 2º 02 febrero feb.'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14º 14'],\n            ['d do dddd ddd dd',                   '0 0º domingo dom. do'],\n            ['DDD DDDo DDDD',                      '45 45º 045'],\n            ['w wo ww',                            '6 6º 06'],\n            ['YYYY-MMM-DD',                        '2010-feb-14'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'pm PM'],\n            ['[the] DDDo [day of the year]',       'the 45º day of the year'],\n            ['LTS',                                '15:25:50'],\n            ['L',                                  '14/02/2010'],\n            ['LL',                                 '14 de febrero de 2010'],\n            ['LLL',                                '14 de febrero de 2010 15:25'],\n            ['LLLL',                               'domingo, 14 de febrero de 2010 15:25'],\n            ['l',                                  '14/2/2010'],\n            ['ll',                                 '14 de feb. de 2010'],\n            ['lll',                                '14 de feb. de 2010 15:25'],\n            ['llll',                               'dom., 14 de feb. de 2010 15:25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1º', '1º');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2º', '2º');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3º', '3º');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4º', '4º');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5º', '5º');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6º', '6º');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7º', '7º');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8º', '8º');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9º', '9º');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10º', '10º');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11º', '11º');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12º', '12º');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13º', '13º');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14º', '14º');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15º', '15º');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16º', '16º');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17º', '17º');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18º', '18º');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19º', '19º');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20º', '20º');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21º', '21º');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22º', '22º');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23º', '23º');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24º', '24º');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25º', '25º');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26º', '26º');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27º', '27º');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28º', '28º');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29º', '29º');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30º', '30º');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31º', '31º');\n});\n\ntest('format month', function (assert) {\n    var expected = 'enero ene._febrero feb._marzo mar._abril abr._mayo may._junio jun._julio jul._agosto ago._septiembre sep._octubre oct._noviembre nov._diciembre dic.'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'domingo dom. do_lunes lun. lu_martes mar. ma_miércoles mié. mi_jueves jue. ju_viernes vie. vi_sábado sáb. sá'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'unos segundos', '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'un minuto',      '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'un minuto',      '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 minutos',     '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 minutos',    '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'una hora',       '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'una hora',       '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 horas',       '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 horas',       '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 horas',      '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'un día',         '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'un día',         '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 días',        '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'un día',         '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 días',        '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 días',       '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'un mes',       '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'un mes',       '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'un mes',       '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 meses',      '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 meses',      '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 meses',      '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'un mes',       '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 meses',      '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'un año',        '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 años',       '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'un año',        '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 años',       '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'en unos segundos',  'prefix');\n    assert.equal(moment(0).from(30000), 'hace unos segundos', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'hace unos segundos',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'en unos segundos', 'en unos segundos');\n    assert.equal(moment().add({d: 5}).fromNow(), 'en 5 días', 'en 5 días');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                       'hoy a las 12:00',     'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),          'hoy a las 12:25',     'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),           'hoy a las 13:00',     'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),           'mañana a las 12:00',  'tomorrow at the same time');\n    assert.equal(moment(a).add({d: 1, h : -1}).calendar(),   'mañana a las 11:00',   'tomorrow minus 1 hour');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),      'hoy a las 11:00',     'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),      'ayer a las 12:00',    'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('dddd [a la' + ((m.hours() !== 1) ? 's' : '') + '] LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd [a la' + ((m.hours() !== 1) ? 's' : '') + '] LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd [a la' + ((m.hours() !== 1) ? 's' : '') + '] LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('[el] dddd [pasado a la' + ((m.hours() !== 1) ? 's' : '') + '] LT'),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[el] dddd [pasado a la' + ((m.hours() !== 1) ? 's' : '') + '] LT'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[el] dddd [pasado a la' + ((m.hours() !== 1) ? 's' : '') + '] LT'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2012, 0,  1]).format('w ww wo'), '52 52 52º', 'Jan  1 2012 should be week 52');\n    assert.equal(moment([2012, 0,  2]).format('w ww wo'),   '1 01 1º', 'Jan  2 2012 should be week 1');\n    assert.equal(moment([2012, 0,  8]).format('w ww wo'),   '1 01 1º', 'Jan  8 2012 should be week 1');\n    assert.equal(moment([2012, 0,  9]).format('w ww wo'),   '2 02 2º', 'Jan  9 2012 should be week 2');\n    assert.equal(moment([2012, 0, 15]).format('w ww wo'),   '2 02 2º', 'Jan 15 2012 should be week 2');\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\n\n\nfunction localeModule (name, lifecycle) {\n    QUnit.module('locale:' + name, {\n        setup : function () {\n            moment.locale(name);\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            moment.locale('en');\n            teardownDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n    defineCommonLocaleTests(name, -1, -1);\n}\n\nlocaleModule('et');\n\ntest('parse', function (assert) {\n    var tests = 'jaanuar jaan_veebruar veebr_märts märts_aprill apr_mai mai_juuni juuni_juuli juuli_august aug_september sept_oktoober okt_november nov_detsember dets'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' peaks olema kuu ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, Do MMMM YYYY, H:mm:ss',      'pühapäev, 14. veebruar 2010, 15:25:50'],\n            ['ddd, h',                           'P, 3'],\n            ['M Mo MM MMMM MMM',                 '2 2. 02 veebruar veebr'],\n            ['YYYY YY',                          '2010 10'],\n            ['D Do DD',                          '14 14. 14'],\n            ['d do dddd ddd dd',                 '0 0. pühapäev P P'],\n            ['DDD DDDo DDDD',                    '45 45. 045'],\n            ['w wo ww',                          '6 6. 06'],\n            ['h hh',                             '3 03'],\n            ['H HH',                             '15 15'],\n            ['m mm',                             '25 25'],\n            ['s ss',                             '50 50'],\n            ['a A',                              'pm PM'],\n            ['[aasta] DDDo [päev]',              'aasta 45. päev'],\n            ['LTS',                              '15:25:50'],\n            ['L',                                '14.02.2010'],\n            ['LL',                               '14. veebruar 2010'],\n            ['LLL',                              '14. veebruar 2010 15:25'],\n            ['LLLL',                             'pühapäev, 14. veebruar 2010 15:25'],\n            ['l',                                '14.2.2010'],\n            ['ll',                               '14. veebr 2010'],\n            ['lll',                              '14. veebr 2010 15:25'],\n            ['llll',                             'P, 14. veebr 2010 15:25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1.', '1.');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2.', '2.');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3.', '3.');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4.', '4.');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5.', '5.');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6.', '6.');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7.', '7.');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8.', '8.');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9.', '9.');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10.', '10.');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11.', '11.');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12.', '12.');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13.', '13.');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14.', '14.');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15.', '15.');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16.', '16.');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17.', '17.');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18.', '18.');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19.', '19.');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20.', '20.');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21.', '21.');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22.', '22.');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23.', '23.');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24.', '24.');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25.', '25.');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26.', '26.');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27.', '27.');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28.', '28.');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29.', '29.');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30.', '30.');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31.', '31.');\n});\n\ntest('format month', function (assert) {\n    var expected = 'jaanuar jaan_veebruar veebr_märts märts_aprill apr_mai mai_juuni juuni_juuli juuli_august aug_september sept_oktoober okt_november nov_detsember dets'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'pühapäev P P_esmaspäev E E_teisipäev T T_kolmapäev K K_neljapäev N N_reede R R_laupäev L L'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'paar sekundit',  '44 seconds = paar sekundit');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'üks minut',      '45 seconds = üks minut');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'üks minut',      '89 seconds = üks minut');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 minutit',      '90 seconds = 2 minutit');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 minutit',     '44 minutes = 44 minutit');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'üks tund',       '45 minutes = tund aega');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'üks tund',       '89 minutes = üks tund');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 tundi',        '90 minutes = 2 tundi');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 tundi',        '5 hours = 5 tundi');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 tundi',       '21 hours = 21 tundi');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'üks päev',       '22 hours = üks päev');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'üks päev',       '35 hours = üks päev');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 päeva',        '36 hours = 2 päeva');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'üks päev',       '1 day = üks päev');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 päeva',        '5 days = 5 päeva');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 päeva',       '25 days = 25 päeva');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'üks kuu',        '26 days = üks kuu');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'üks kuu',        '30 days = üks kuu');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'üks kuu',        '43 days = üks kuu');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 kuud',         '46 days = 2 kuud');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 kuud',         '75 days = 2 kuud');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 kuud',         '76 days = 3 kuud');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'üks kuu',        '1 month = üks kuu');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 kuud',         '5 months = 5 kuud');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'üks aasta',      '345 days = üks aasta');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 aastat',       '548 days = 2 aastat');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'üks aasta',      '1 year = üks aasta');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 aastat',       '5 years = 5 aastat');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'mõne sekundi pärast',  'prefix');\n    assert.equal(moment(0).from(30000), 'mõni sekund tagasi', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'mõni sekund tagasi',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'mõne sekundi pärast', 'in a few seconds');\n    assert.equal(moment().subtract({s: 30}).fromNow(), 'mõni sekund tagasi', 'a few seconds ago');\n\n    assert.equal(moment().add({m: 1}).fromNow(), 'ühe minuti pärast', 'in a minute');\n    assert.equal(moment().subtract({m: 1}).fromNow(), 'üks minut tagasi', 'a minute ago');\n\n    assert.equal(moment().add({m: 5}).fromNow(), '5 minuti pärast', 'in 5 minutes');\n    assert.equal(moment().subtract({m: 5}).fromNow(), '5 minutit tagasi', '5 minutes ago');\n\n    assert.equal(moment().add({d: 1}).fromNow(), 'ühe päeva pärast', 'in one day');\n    assert.equal(moment().subtract({d: 1}).fromNow(), 'üks päev tagasi', 'one day ago');\n\n    assert.equal(moment().add({d: 5}).fromNow(), '5 päeva pärast', 'in 5 days');\n    assert.equal(moment().subtract({d: 5}).fromNow(), '5 päeva tagasi', '5 days ago');\n\n    assert.equal(moment().add({M: 1}).fromNow(), 'kuu aja pärast', 'in a month');\n    assert.equal(moment().subtract({M: 1}).fromNow(), 'kuu aega tagasi', 'a month ago');\n\n    assert.equal(moment().add({M: 5}).fromNow(), '5 kuu pärast', 'in 5 months');\n    assert.equal(moment().subtract({M: 5}).fromNow(), '5 kuud tagasi', '5 months ago');\n\n    assert.equal(moment().add({y: 1}).fromNow(), 'ühe aasta pärast', 'in a year');\n    assert.equal(moment().subtract({y: 1}).fromNow(), 'aasta tagasi', 'a year ago');\n\n    assert.equal(moment().add({y: 5}).fromNow(), '5 aasta pärast', 'in 5 years');\n    assert.equal(moment().subtract({y: 5}).fromNow(), '5 aastat tagasi', '5 years ago');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'Täna, 12:00',     'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'Täna, 12:25',     'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'Täna, 13:00',     'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'Homme, 12:00',    'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'Täna, 11:00',     'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'Eile, 12:00',     'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('[Järgmine] dddd LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[Järgmine] dddd LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[Järgmine] dddd LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('[Eelmine] dddd LT'),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[Eelmine] dddd LT'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[Eelmine] dddd LT'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 nädal tagasi');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  '1 nädala pärast');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 nädalat tagasi');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  '2 nädala pärast');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2012, 0,  1]).format('w ww wo'), '52 52 52.', 'Jan  1 2012 should be week 52');\n    assert.equal(moment([2012, 0,  2]).format('w ww wo'),   '1 01 1.', 'Jan  2 2012 should be week 1');\n    assert.equal(moment([2012, 0,  8]).format('w ww wo'),   '1 01 1.', 'Jan  8 2012 should be week 1');\n    assert.equal(moment([2012, 0,  9]).format('w ww wo'),   '2 02 2.', 'Jan  9 2012 should be week 2');\n    assert.equal(moment([2012, 0, 15]).format('w ww wo'),   '2 02 2.', 'Jan 15 2012 should be week 2');\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\n\n\nfunction localeModule (name, lifecycle) {\n    QUnit.module('locale:' + name, {\n        setup : function () {\n            moment.locale(name);\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            moment.locale('en');\n            teardownDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n    defineCommonLocaleTests(name, -1, -1);\n}\n\nlocaleModule('eu');\n\ntest('parse', function (assert) {\n    var tests = 'urtarrila urt._otsaila ots._martxoa mar._apirila api._maiatza mai._ekaina eka._uztaila uzt._abuztua abu._iraila ira._urria urr._azaroa aza._abendua abe.'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, MMMM Do YYYY, h:mm:ss a',      'igandea, otsaila 14. 2010, 3:25:50 pm'],\n            ['ddd, hA',                            'ig., 3PM'],\n            ['M Mo MM MMMM MMM',                   '2 2. 02 otsaila ots.'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14. 14'],\n            ['d do dddd ddd dd',                   '0 0. igandea ig. ig'],\n            ['DDD DDDo DDDD',                      '45 45. 045'],\n            ['w wo ww',                            '7 7. 07'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'pm PM'],\n            ['[the] DDDo [day of the year]',       'the 45. day of the year'],\n            ['LTS',                                '15:25:50'],\n            ['L',                                  '2010-02-14'],\n            ['LL',                                 '2010ko otsailaren 14a'],\n            ['LLL',                                '2010ko otsailaren 14a 15:25'],\n            ['LLLL',                               'igandea, 2010ko otsailaren 14a 15:25'],\n            ['l',                                  '2010-2-14'],\n            ['ll',                                 '2010ko ots. 14a'],\n            ['lll',                                '2010ko ots. 14a 15:25'],\n            ['llll',                               'ig., 2010ko ots. 14a 15:25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1.', '1.');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2.', '2.');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3.', '3.');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4.', '4.');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5.', '5.');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6.', '6.');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7.', '7.');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8.', '8.');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9.', '9.');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10.', '10.');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11.', '11.');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12.', '12.');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13.', '13.');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14.', '14.');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15.', '15.');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16.', '16.');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17.', '17.');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18.', '18.');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19.', '19.');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20.', '20.');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21.', '21.');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22.', '22.');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23.', '23.');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24.', '24.');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25.', '25.');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26.', '26.');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27.', '27.');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28.', '28.');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29.', '29.');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30.', '30.');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31.', '31.');\n});\n\ntest('format month', function (assert) {\n    var expected = 'urtarrila urt._otsaila ots._martxoa mar._apirila api._maiatza mai._ekaina eka._uztaila uzt._abuztua abu._iraila ira._urria urr._azaroa aza._abendua abe.'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'igandea ig. ig_astelehena al. al_asteartea ar. ar_asteazkena az. az_osteguna og. og_ostirala ol. ol_larunbata lr. lr'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'segundo batzuk', '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'minutu bat',     '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'minutu bat',     '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 minutu',       '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 minutu',      '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'ordu bat',       '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'ordu bat',       '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 ordu',         '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 ordu',         '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 ordu',        '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'egun bat',       '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'egun bat',       '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 egun',         '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'egun bat',       '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 egun',         '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 egun',        '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'hilabete bat',   '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'hilabete bat',   '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'hilabete bat',   '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 hilabete',     '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 hilabete',     '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 hilabete',     '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'hilabete bat',   '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 hilabete',     '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'urte bat',       '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 urte',         '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'urte bat',       '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 urte',         '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'segundo batzuk barru',  'prefix');\n    assert.equal(moment(0).from(30000), 'duela segundo batzuk', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'duela segundo batzuk',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'segundo batzuk barru', 'in seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), '5 egun barru', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'gaur 12:00etan',  'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'gaur 12:25etan',  'now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'gaur 13:00etan',  'now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'bihar 12:00etan', 'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'gaur 11:00etan',  'now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'atzo 12:00etan',  'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('dddd LT[etan]'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd LT[etan]'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd LT[etan]'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('[aurreko] dddd LT[etan]'),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[aurreko] dddd LT[etan]'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[aurreko] dddd LT[etan]'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2011, 11, 26]).format('w ww wo'), '1 01 1.', 'Dec 26 2011 should be week 1');\n    assert.equal(moment([2012,  0,  1]).format('w ww wo'), '1 01 1.', 'Jan  1 2012 should be week 1');\n    assert.equal(moment([2012,  0,  2]).format('w ww wo'), '2 02 2.', 'Jan  2 2012 should be week 2');\n    assert.equal(moment([2012,  0,  8]).format('w ww wo'), '2 02 2.', 'Jan  8 2012 should be week 2');\n    assert.equal(moment([2012,  0,  9]).format('w ww wo'), '3 03 3.', 'Jan  9 2012 should be week 3');\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\n\n\nfunction localeModule (name, lifecycle) {\n    QUnit.module('locale:' + name, {\n        setup : function () {\n            moment.locale(name);\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            moment.locale('en');\n            teardownDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n    defineCommonLocaleTests(name, -1, -1);\n}\n\nlocaleModule('fa');\n\ntest('parse', function (assert) {\n    var tests = 'ژانویه_فوریه_مارس_آوریل_مه_ژوئن_ژوئیه_اوت_سپتامبر_اکتبر_نوامبر_دسامبر'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1) + ' instead is month ' + moment(input, mmm).month());\n    }\n    for (i = 0; i < 12; i++) {\n        equalTest(tests[i], 'MMM', i);\n        equalTest(tests[i], 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, MMMM Do YYYY, h:mm:ss a',      'یک\\u200cشنبه، فوریه ۱۴م ۲۰۱۰، ۳:۲۵:۵۰ بعد از ظهر'],\n            ['ddd, hA',                            'یک\\u200cشنبه، ۳بعد از ظهر'],\n            ['M Mo MM MMMM MMM',                   '۲ ۲م ۰۲ فوریه فوریه'],\n            ['YYYY YY',                            '۲۰۱۰ ۱۰'],\n            ['D Do DD',                            '۱۴ ۱۴م ۱۴'],\n            ['d do dddd ddd dd',                   '۰ ۰م یک\\u200cشنبه یک\\u200cشنبه ی'],\n            ['DDD DDDo DDDD',                      '۴۵ ۴۵م ۰۴۵'],\n            ['w wo ww',                            '۸ ۸م ۰۸'],\n            ['h hh',                               '۳ ۰۳'],\n            ['H HH',                               '۱۵ ۱۵'],\n            ['m mm',                               '۲۵ ۲۵'],\n            ['s ss',                               '۵۰ ۵۰'],\n            ['a A',                                'بعد از ظهر بعد از ظهر'],\n            ['DDDo [روز سال]',             '۴۵م روز سال'],\n            ['LTS',                                '۱۵:۲۵:۵۰'],\n            ['L',                                  '۱۴/۰۲/۲۰۱۰'],\n            ['LL',                                 '۱۴ فوریه ۲۰۱۰'],\n            ['LLL',                                '۱۴ فوریه ۲۰۱۰ ۱۵:۲۵'],\n            ['LLLL',                               'یک\\u200cشنبه، ۱۴ فوریه ۲۰۱۰ ۱۵:۲۵'],\n            ['l',                                  '۱۴/۲/۲۰۱۰'],\n            ['ll',                                 '۱۴ فوریه ۲۰۱۰'],\n            ['lll',                                '۱۴ فوریه ۲۰۱۰ ۱۵:۲۵'],\n            ['llll',                               'یک\\u200cشنبه، ۱۴ فوریه ۲۰۱۰ ۱۵:۲۵']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '۱م', '1');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '۲م', '2');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '۳م', '3');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '۴م', '4');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '۵م', '5');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '۶م', '6');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '۷م', '7');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '۸م', '8');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '۹م', '9');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '۱۰م', '10');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '۱۱م', '11');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '۱۲م', '12');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '۱۳م', '13');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '۱۴م', '14');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '۱۵م', '15');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '۱۶م', '16');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '۱۷م', '17');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '۱۸م', '18');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '۱۹م', '19');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '۲۰م', '20');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '۲۱م', '21');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '۲۲م', '22');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '۲۳م', '23');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '۲۴م', '24');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '۲۵م', '25');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '۲۶م', '26');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '۲۷م', '27');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '۲۸م', '28');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '۲۹م', '29');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '۳۰م', '30');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '۳۱م', '31');\n});\n\ntest('format month', function (assert) {\n    var expected = 'ژانویه ژانویه_فوریه فوریه_مارس مارس_آوریل آوریل_مه مه_ژوئن ژوئن_ژوئیه ژوئیه_اوت اوت_سپتامبر سپتامبر_اکتبر اکتبر_نوامبر نوامبر_دسامبر دسامبر'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'یک\\u200cشنبه یک\\u200cشنبه ی_دوشنبه دوشنبه د_سه\\u200cشنبه سه\\u200cشنبه س_چهارشنبه چهارشنبه چ_پنج\\u200cشنبه پنج\\u200cشنبه پ_جمعه جمعه ج_شنبه شنبه ش'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'چند ثانیه', '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'یک دقیقه',       '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'یک دقیقه',       '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '۲ دقیقه',     '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '۴۴ دقیقه',    '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'یک ساعت',     '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'یک ساعت',     '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '۲ ساعت',      '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '۵ ساعت',      '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '۲۱ ساعت',     '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'یک روز',      '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'یک روز',      '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '۲ روز',       '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'یک روز',      '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '۵ روز',       '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '۲۵ روز',      '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'یک ماه',      '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'یک ماه',      '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'یک ماه',      '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '۲ ماه',       '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '۲ ماه',       '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '۳ ماه',       '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'یک ماه',      '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '۵ ماه',       '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'یک سال',      '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '۲ سال',       '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'یک سال',      '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '۵ سال',       '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'در چند ثانیه', 'prefix');\n    assert.equal(moment(0).from(30000), 'چند ثانیه پیش', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'چند ثانیه پیش',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'در چند ثانیه', 'in a few seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), 'در ۵ روز', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'امروز ساعت ۱۲:۰۰', 'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'امروز ساعت ۱۲:۲۵', 'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'امروز ساعت ۱۳:۰۰', 'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'فردا ساعت ۱۲:۰۰', 'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'امروز ساعت ۱۱:۰۰', 'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'دیروز ساعت ۱۲:۰۰', 'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('dddd [ساعت] LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd [ساعت] LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd [ساعت] LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('dddd [پیش ساعت] LT'),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd [پیش ساعت] LT'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd [پیش ساعت] LT'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2011, 11, 31]).format('w ww wo'), '۱ ۰۱ ۱م', 'Dec 31 2011 should be week 1');\n    assert.equal(moment([2012,  0,  6]).format('w ww wo'), '۱ ۰۱ ۱م', 'Jan  6 2012 should be week 1');\n    assert.equal(moment([2012,  0,  7]).format('w ww wo'), '۲ ۰۲ ۲م', 'Jan  7 2012 should be week 2');\n    assert.equal(moment([2012,  0, 13]).format('w ww wo'), '۲ ۰۲ ۲م', 'Jan 13 2012 should be week 2');\n    assert.equal(moment([2012,  0, 14]).format('w ww wo'), '۳ ۰۳ ۳م', 'Jan 14 2012 should be week 3');\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\n\n\nfunction localeModule (name, lifecycle) {\n    QUnit.module('locale:' + name, {\n        setup : function () {\n            moment.locale(name);\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            moment.locale('en');\n            teardownDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n    defineCommonLocaleTests(name, -1, -1);\n}\n\nlocaleModule('fi');\n\ntest('parse', function (assert) {\n    var tests = 'tammikuu tammi_helmikuu helmi_maaliskuu maalis_huhtikuu huhti_toukokuu touko_kesäkuu kesä_heinäkuu heinä_elokuu elo_syyskuu syys_lokakuu loka_marraskuu marras_joulukuu joulu'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, MMMM Do YYYY, h:mm:ss a',      'sunnuntai, helmikuu 14. 2010, 3:25:50 pm'],\n            ['ddd, hA',                            'su, 3PM'],\n            ['M Mo MM MMMM MMM',                   '2 2. 02 helmikuu helmi'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14. 14'],\n            ['d do dddd ddd dd',                   '0 0. sunnuntai su su'],\n            ['DDD DDDo DDDD',                      '45 45. 045'],\n            ['w wo ww',                            '6 6. 06'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'pm PM'],\n            ['[vuoden] DDDo [päivä]',              'vuoden 45. päivä'],\n            ['LTS',                                '15.25.50'],\n            ['L',                                  '14.02.2010'],\n            ['LL',                                 '14. helmikuuta 2010'],\n            ['LLL',                                '14. helmikuuta 2010, klo 15.25'],\n            ['LLLL',                               'sunnuntai, 14. helmikuuta 2010, klo 15.25'],\n            ['l',                                  '14.2.2010'],\n            ['ll',                                 '14. helmi 2010'],\n            ['lll',                                '14. helmi 2010, klo 15.25'],\n            ['llll',                               'su, 14. helmi 2010, klo 15.25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1.', '1st');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2.', '2nd');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3.', '3rd');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4.', '4th');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5.', '5th');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6.', '6th');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7.', '7th');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8.', '8th');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9.', '9th');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10.', '10th');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11.', '11th');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12.', '12th');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13.', '13th');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14.', '14th');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15.', '15th');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16.', '16th');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17.', '17th');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18.', '18th');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19.', '19th');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20.', '20th');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21.', '21st');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22.', '22nd');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23.', '23rd');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24.', '24th');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25.', '25th');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26.', '26th');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27.', '27th');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28.', '28th');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29.', '29th');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30.', '30th');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31.', '31st');\n});\n\ntest('format month', function (assert) {\n    var expected = 'tammikuu tammi_helmikuu helmi_maaliskuu maalis_huhtikuu huhti_toukokuu touko_kesäkuu kesä_heinäkuu heinä_elokuu elo_syyskuu syys_lokakuu loka_marraskuu marras_joulukuu joulu'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'sunnuntai su su_maanantai ma ma_tiistai ti ti_keskiviikko ke ke_torstai to to_perjantai pe pe_lauantai la la'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'muutama sekunti', '44 seconds = few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'minuutti',      '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'minuutti',      '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  'kaksi minuuttia',     '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 minuuttia',    '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'tunti',       '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'tunti',       '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  'kaksi tuntia',       '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   'viisi tuntia',       '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 tuntia',      '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'päivä',         '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'päivä',         '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  'kaksi päivää',        '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'päivä',         '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   'viisi päivää',        '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 päivää',       '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'kuukausi',       '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'kuukausi',       '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'kuukausi',       '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  'kaksi kuukautta',      '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  'kaksi kuukautta',      '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  'kolme kuukautta',      '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'kuukausi',       '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   'viisi kuukautta',      '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'vuosi',        '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), 'kaksi vuotta',       '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'vuosi',        '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   'viisi vuotta',       '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'muutaman sekunnin päästä',  'prefix');\n    assert.equal(moment(0).from(30000), 'muutama sekunti sitten', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'muutama sekunti sitten',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'muutaman sekunnin päästä', 'in a few seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), 'viiden päivän päästä', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'tänään klo 12.00',    'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'tänään klo 12.25',    'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'tänään klo 13.00',    'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'huomenna klo 12.00',  'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'tänään klo 11.00',    'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'eilen klo 12.00',     'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('dddd [klo] LT'),  'today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd [klo] LT'),  'today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd [klo] LT'),  'today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('[viime] dddd[na] [klo] LT'),  'today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[viime] dddd[na] [klo] LT'),  'today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[viime] dddd[na] [klo] LT'),  'today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  'yksi viikko sitten');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'yhden viikon päästä');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  'kaksi viikkoa sitten');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'kaden viikon päästä');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2012, 0,  1]).format('w ww wo'), '52 52 52.', 'Jan  1 2012 should be week 52');\n    assert.equal(moment([2012, 0,  2]).format('w ww wo'),   '1 01 1.', 'Jan  2 2012 should be week 1');\n    assert.equal(moment([2012, 0,  8]).format('w ww wo'),   '1 01 1.', 'Jan  8 2012 should be week 1');\n    assert.equal(moment([2012, 0,  9]).format('w ww wo'),   '2 02 2.', 'Jan  9 2012 should be week 2');\n    assert.equal(moment([2012, 0, 15]).format('w ww wo'),   '2 02 2.', 'Jan 15 2012 should be week 2');\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\n\n\nfunction localeModule (name, lifecycle) {\n    QUnit.module('locale:' + name, {\n        setup : function () {\n            moment.locale(name);\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            moment.locale('en');\n            teardownDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n    defineCommonLocaleTests(name, -1, -1);\n}\n\nlocaleModule('fo');\n\ntest('parse', function (assert) {\n    var tests = 'januar jan_februar feb_mars mar_apríl apr_mai mai_juni jun_juli jul_august aug_september sep_oktober okt_november nov_desember des'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd [tann] Do MMMM YYYY, h:mm:ss a', 'sunnudagur tann 14. februar 2010, 3:25:50 pm'],\n            ['ddd hA',                             'sun 3PM'],\n            ['M Mo MM MMMM MMM',                   '2 2. 02 februar feb'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14. 14'],\n            ['d do dddd ddd dd',                   '0 0. sunnudagur sun su'],\n            ['DDD DDDo DDDD',                      '45 45. 045'],\n            ['w wo ww',                            '6 6. 06'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'pm PM'],\n            ['[tann] DDDo [dagin á árinum]',       'tann 45. dagin á árinum'],\n            ['LTS',                                '15:25:50'],\n            ['L',                                  '14/02/2010'],\n            ['LL',                                 '14 februar 2010'],\n            ['LLL',                                '14 februar 2010 15:25'],\n            ['LLLL',                               'sunnudagur 14. februar, 2010 15:25'],\n            ['l',                                  '14/2/2010'],\n            ['ll',                                 '14 feb 2010'],\n            ['lll',                                '14 feb 2010 15:25'],\n            ['llll',                               'sun 14. feb, 2010 15:25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1.', '1.');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2.', '2.');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3.', '3.');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4.', '4.');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5.', '5.');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6.', '6.');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7.', '7.');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8.', '8.');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9.', '9.');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10.', '10.');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11.', '11.');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12.', '12.');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13.', '13.');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14.', '14.');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15.', '15.');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16.', '16.');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17.', '17.');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18.', '18.');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19.', '19.');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20.', '20.');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21.', '21.');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22.', '22.');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23.', '23.');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24.', '24.');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25.', '25.');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26.', '26.');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27.', '27.');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28.', '28.');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29.', '29.');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30.', '30.');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31.', '31.');\n});\n\ntest('format month', function (assert) {\n    var expected = 'januar jan_februar feb_mars mar_apríl apr_mai mai_juni jun_juli jul_august aug_september sep_oktober okt_november nov_desember des'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'sunnudagur sun su_mánadagur mán má_týsdagur týs tý_mikudagur mik mi_hósdagur hós hó_fríggjadagur frí fr_leygardagur ley le'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'fá sekund', '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'ein minutt',    '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'ein minutt',    '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 minuttir',  '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 minuttir', '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'ein tími',     '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'ein tími',     '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 tímar',     '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 tímar',     '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 tímar',    '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'ein dagur',      '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'ein dagur',      '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 dagar',      '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'ein dagur',      '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 dagar',      '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 dagar',     '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'ein mánaði',    '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'ein mánaði',    '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'ein mánaði',    '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 mánaðir',   '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 mánaðir',   '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 mánaðir',   '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'ein mánaði',    '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 mánaðir',   '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'eitt ár',       '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 ár',        '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'eitt ár',       '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 ár',        '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'um fá sekund',  'prefix');\n    assert.equal(moment(0).from(30000), 'fá sekund síðani', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'fá sekund síðani',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'um fá sekund', 'in a few seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), 'um 5 dagar', 'in 5 days');\n});\n\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'Í dag kl. 12:00',    'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'Í dag kl. 12:25',    'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'Í dag kl. 13:00',    'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'Í morgin kl. 12:00', 'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'Í dag kl. 11:00',    'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'Í gjár kl. 12:00',   'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('dddd [kl.] LT'),  'today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd [kl.] LT'),  'today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd [kl.] LT'),  'today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('[síðstu] dddd [kl] LT'),  'today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[síðstu] dddd [kl] LT'),  'today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[síðstu] dddd [kl] LT'),  'today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  'yksi viikko sitten');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'yhden viikon päästä');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  'kaksi viikkoa sitten');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'kaden viikon päästä');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2012, 0,  1]).format('w ww wo'), '52 52 52.', 'Jan  1 2012 should be week 52');\n    assert.equal(moment([2012, 0,  2]).format('w ww wo'),   '1 01 1.', 'Jan  2 2012 should be week 1');\n    assert.equal(moment([2012, 0,  8]).format('w ww wo'),   '1 01 1.', 'Jan  8 2012 should be week 1');\n    assert.equal(moment([2012, 0,  9]).format('w ww wo'),   '2 02 2.', 'Jan  9 2012 should be week 2');\n    assert.equal(moment([2012, 0, 15]).format('w ww wo'),   '2 02 2.', 'Jan 15 2012 should be week 2');\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\n\n\nfunction localeModule (name, lifecycle) {\n    QUnit.module('locale:' + name, {\n        setup : function () {\n            moment.locale(name);\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            moment.locale('en');\n            teardownDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n    defineCommonLocaleTests(name, -1, -1);\n}\n\nlocaleModule('fr-ca');\n\ntest('parse', function (assert) {\n    var i,\n        tests = 'janvier janv._février févr._mars mars_avril avr._mai mai_juin juin_juillet juil._août août_septembre sept._octobre oct._novembre nov._décembre déc.'.split('_');\n\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, MMMM Do YYYY, h:mm:ss a', 'dimanche, février 14e 2010, 3:25:50 pm'],\n            ['ddd, hA',                       'dim., 3PM'],\n            ['M Mo MM MMMM MMM',              '2 2e 02 février févr.'],\n            ['YYYY YY',                       '2010 10'],\n            ['D Do DD',                       '14 14e 14'],\n            ['d do dddd ddd dd',              '0 0e dimanche dim. Di'],\n            ['DDD DDDo DDDD',                 '45 45e 045'],\n            ['w wo ww',                       '8 8e 08'],\n            ['h hh',                          '3 03'],\n            ['H HH',                          '15 15'],\n            ['m mm',                          '25 25'],\n            ['s ss',                          '50 50'],\n            ['a A',                           'pm PM'],\n            ['[le] Do [jour du mois]',        'le 14e jour du mois'],\n            ['[le] DDDo [jour de l’année]',   'le 45e jour de l’année'],\n            ['LTS',                           '15:25:50'],\n            ['L',                             '2010-02-14'],\n            ['LL',                            '14 février 2010'],\n            ['LLL',                           '14 février 2010 15:25'],\n            ['LLLL',                          'dimanche 14 février 2010 15:25'],\n            ['l',                             '2010-2-14'],\n            ['ll',                            '14 févr. 2010'],\n            ['lll',                           '14 févr. 2010 15:25'],\n            ['llll',                          'dim. 14 févr. 2010 15:25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2017, 0, 1]).format('Mo'),     '1er',     '1er');\n    assert.equal(moment([2017, 1, 1]).format('Mo'),     '2e',      '2e');\n\n    assert.equal(moment([2017, 0, 1]).format('Qo'),     '1er',     '1er');\n    assert.equal(moment([2017, 3, 1]).format('Qo'),     '2e',      '2e');\n\n    assert.equal(moment([2017, 0, 1]).format('Do'),     '1er',     '1er');\n    assert.equal(moment([2017, 0, 2]).format('Do'),     '2e',      '2e');\n\n    assert.equal(moment([2011, 0, 1]).format('DDDo'),   '1er',     '1er');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'),   '2e',      '2e');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'),   '3e',      '3e');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'),   '4e',      '4e');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'),   '5e',      '5e');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'),   '6e',      '6e');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'),   '7e',      '7e');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'),   '8e',      '8e');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'),   '9e',      '9e');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'),  '10e',     '10e');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'),  '11e',     '11e');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'),  '12e',     '12e');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'),  '13e',     '13e');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'),  '14e',     '14e');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'),  '15e',     '15e');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'),  '16e',     '16e');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'),  '17e',     '17e');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'),  '18e',     '18e');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'),  '19e',     '19e');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'),  '20e',     '20e');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'),  '21e',     '21e');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'),  '22e',     '22e');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'),  '23e',     '23e');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'),  '24e',     '24e');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'),  '25e',     '25e');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'),  '26e',     '26e');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'),  '27e',     '27e');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'),  '28e',     '28e');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'),  '29e',     '29e');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'),  '30e',     '30e');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'),  '31e',     '31e');\n\n    assert.equal(moment([2017, 0, 1]).format('do'),     '0e',      '0e');\n    assert.equal(moment([2017, 0, 2]).format('do'),     '1er',     '1er');\n\n    assert.equal(moment([2017, 0, 4]).format('wo Wo'),  '1re 1re', '1re 1re');\n    assert.equal(moment([2017, 0, 11]).format('wo Wo'), '2e 2e',   '2e 2e');\n});\n\ntest('format month', function (assert) {\n    var i,\n        expected = 'janvier janv._février févr._mars mars_avril avr._mai mai_juin juin_juillet juil._août août_septembre sept._octobre oct._novembre nov._décembre déc.'.split('_');\n\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var i,\n        expected = 'dimanche dim. Di_lundi lun. Lu_mardi mar. Ma_mercredi mer. Me_jeudi jeu. Je_vendredi ven. Ve_samedi sam. Sa'.split('_');\n\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'quelques secondes', '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'une minute',        '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'une minute',        '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 minutes',         '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 minutes',        '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'une heure',         '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'une heure',         '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 heures',          '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 heures',          '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 heures',         '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'un jour',           '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'un jour',           '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 jours',           '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'un jour',           '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 jours',           '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 jours',          '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'un mois',           '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'un mois',           '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'un mois',           '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 mois',            '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 mois',            '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 mois',            '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'un mois',           '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 mois',            '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'un an',             '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 ans',             '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'un an',             '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 ans',             '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'dans quelques secondes',   'prefix');\n    assert.equal(moment(0).from(30000), 'il y a quelques secondes', 'suffix');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'dans quelques secondes', 'in a few seconds');\n    assert.equal(moment().add({d: 5}).fromNow(),  'dans 5 jours',           'in 5 days');\n});\n\ntest('same day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                  'Aujourd’hui à 12:00', 'Today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),     'Aujourd’hui à 12:25', 'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),      'Aujourd’hui à 13:00', 'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),      'Demain à 12:00',      'Tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(), 'Aujourd’hui à 11:00', 'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(), 'Hier à 12:00',        'Yesterday at the same time');\n});\n\ntest('same next week', function (assert) {\n    var i, m;\n\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(), m.format('dddd [à] LT'), 'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(), m.format('dddd [à] LT'), 'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(), m.format('dddd [à] LT'), 'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('same last week', function (assert) {\n    var i, m;\n\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(), m.format('dddd [dernier à] LT'), 'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(), m.format('dddd [dernier à] LT'), 'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(), m.format('dddd [dernier à] LT'), 'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('same all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),     weeksAgo.format('L'),     '1 week ago');\n    assert.equal(weeksFromNow.calendar(), weeksFromNow.format('L'), 'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),     weeksAgo.format('L'),     '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(), weeksFromNow.format('L'), 'in 2 weeks');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2012, 0,  1]).format('w ww wo'), '1 01 1re', 'Jan  1 2012 should be week 1');\n    assert.equal(moment([2012, 0,  7]).format('w ww wo'), '1 01 1re', 'Jan  7 2012 should be week 1');\n    assert.equal(moment([2012, 0,  8]).format('w ww wo'), '2 02 2e',  'Jan  8 2012 should be week 2');\n    assert.equal(moment([2012, 0, 14]).format('w ww wo'), '2 02 2e',  'Jan 14 2012 should be week 2');\n    assert.equal(moment([2012, 0, 15]).format('w ww wo'), '3 03 3e',  'Jan 15 2012 should be week 3');\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\n\n\nfunction localeModule (name, lifecycle) {\n    QUnit.module('locale:' + name, {\n        setup : function () {\n            moment.locale(name);\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            moment.locale('en');\n            teardownDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n    defineCommonLocaleTests(name, -1, -1);\n}\n\nlocaleModule('fr-ch');\n\ntest('parse', function (assert) {\n    var i,\n        tests = 'janvier janv._février févr._mars mars_avril avr._mai mai_juin juin_juillet juil._août août_septembre sept._octobre oct._novembre nov._décembre déc.'.split('_');\n\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, MMMM Do YYYY, h:mm:ss a', 'dimanche, février 14e 2010, 3:25:50 pm'],\n            ['ddd, hA',                       'dim., 3PM'],\n            ['M Mo MM MMMM MMM',              '2 2e 02 février févr.'],\n            ['YYYY YY',                       '2010 10'],\n            ['D Do DD',                       '14 14e 14'],\n            ['d do dddd ddd dd',              '0 0e dimanche dim. Di'],\n            ['DDD DDDo DDDD',                 '45 45e 045'],\n            ['w wo ww',                       '6 6e 06'],\n            ['h hh',                          '3 03'],\n            ['H HH',                          '15 15'],\n            ['m mm',                          '25 25'],\n            ['s ss',                          '50 50'],\n            ['a A',                           'pm PM'],\n            ['[le] Do [jour du mois]',        'le 14e jour du mois'],\n            ['[le] DDDo [jour de l’année]',   'le 45e jour de l’année'],\n            ['LTS',                           '15:25:50'],\n            ['L',                             '14.02.2010'],\n            ['LL',                            '14 février 2010'],\n            ['LLL',                           '14 février 2010 15:25'],\n            ['LLLL',                          'dimanche 14 février 2010 15:25'],\n            ['l',                             '14.2.2010'],\n            ['ll',                            '14 févr. 2010'],\n            ['lll',                           '14 févr. 2010 15:25'],\n            ['llll',                          'dim. 14 févr. 2010 15:25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2017, 0, 1]).format('Mo'),     '1er',     '1er');\n    assert.equal(moment([2017, 1, 1]).format('Mo'),     '2e',      '2e');\n\n    assert.equal(moment([2017, 0, 1]).format('Qo'),     '1er',     '1er');\n    assert.equal(moment([2017, 3, 1]).format('Qo'),     '2e',      '2e');\n\n    assert.equal(moment([2017, 0, 1]).format('Do'),     '1er',     '1er');\n    assert.equal(moment([2017, 0, 2]).format('Do'),     '2e',      '2e');\n\n    assert.equal(moment([2011, 0, 1]).format('DDDo'),   '1er',     '1er');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'),   '2e',      '2e');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'),   '3e',      '3e');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'),   '4e',      '4e');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'),   '5e',      '5e');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'),   '6e',      '6e');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'),   '7e',      '7e');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'),   '8e',      '8e');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'),   '9e',      '9e');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'),  '10e',     '10e');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'),  '11e',     '11e');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'),  '12e',     '12e');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'),  '13e',     '13e');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'),  '14e',     '14e');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'),  '15e',     '15e');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'),  '16e',     '16e');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'),  '17e',     '17e');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'),  '18e',     '18e');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'),  '19e',     '19e');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'),  '20e',     '20e');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'),  '21e',     '21e');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'),  '22e',     '22e');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'),  '23e',     '23e');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'),  '24e',     '24e');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'),  '25e',     '25e');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'),  '26e',     '26e');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'),  '27e',     '27e');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'),  '28e',     '28e');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'),  '29e',     '29e');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'),  '30e',     '30e');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'),  '31e',     '31e');\n\n    assert.equal(moment([2017, 0, 1]).format('do'),     '0e',      '0e');\n    assert.equal(moment([2017, 0, 2]).format('do'),     '1er',     '1er');\n\n    assert.equal(moment([2017, 0, 4]).format('wo Wo'),  '1re 1re', '1re 1re');\n    assert.equal(moment([2017, 0, 11]).format('wo Wo'), '2e 2e',   '2e 2e');\n});\n\ntest('format month', function (assert) {\n    var i,\n        expected = 'janvier janv._février févr._mars mars_avril avr._mai mai_juin juin_juillet juil._août août_septembre sept._octobre oct._novembre nov._décembre déc.'.split('_');\n\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var i,\n        expected = 'dimanche dim. Di_lundi lun. Lu_mardi mar. Ma_mercredi mer. Me_jeudi jeu. Je_vendredi ven. Ve_samedi sam. Sa'.split('_');\n\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'quelques secondes', '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'une minute',        '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'une minute',        '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 minutes',         '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 minutes',        '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'une heure',         '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'une heure',         '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 heures',          '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 heures',          '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 heures',         '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'un jour',           '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'un jour',           '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 jours',           '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'un jour',           '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 jours',           '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 jours',          '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'un mois',           '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'un mois',           '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'un mois',           '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 mois',            '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 mois',            '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 mois',            '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'un mois',           '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 mois',            '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'un an',             '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 ans',             '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'un an',             '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 ans',             '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'dans quelques secondes',   'prefix');\n    assert.equal(moment(0).from(30000), 'il y a quelques secondes', 'suffix');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'dans quelques secondes', 'in a few seconds');\n    assert.equal(moment().add({d: 5}).fromNow(),  'dans 5 jours',           'in 5 days');\n});\n\ntest('same day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                  'Aujourd’hui à 12:00', 'Today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),     'Aujourd’hui à 12:25', 'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),      'Aujourd’hui à 13:00', 'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),      'Demain à 12:00',      'Tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(), 'Aujourd’hui à 11:00', 'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(), 'Hier à 12:00',        'Yesterday at the same time');\n});\n\ntest('same next week', function (assert) {\n    var i, m;\n\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(), m.format('dddd [à] LT'), 'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(), m.format('dddd [à] LT'), 'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(), m.format('dddd [à] LT'), 'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('same last week', function (assert) {\n    var i, m;\n\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(), m.format('dddd [dernier à] LT'), 'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(), m.format('dddd [dernier à] LT'), 'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(), m.format('dddd [dernier à] LT'), 'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('same all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),     weeksAgo.format('L'),     '1 week ago');\n    assert.equal(weeksFromNow.calendar(), weeksFromNow.format('L'), 'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),     weeksAgo.format('L'),     '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(), weeksFromNow.format('L'), 'in 2 weeks');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2012, 0,  1]).format('w ww wo'), '52 52 52e', 'Jan  1 2012 should be week 52');\n    assert.equal(moment([2012, 0,  2]).format('w ww wo'), '1 01 1re',  'Jan  2 2012 should be week 1');\n    assert.equal(moment([2012, 0,  8]).format('w ww wo'), '1 01 1re',  'Jan  8 2012 should be week 1');\n    assert.equal(moment([2012, 0,  9]).format('w ww wo'), '2 02 2e',   'Jan  9 2012 should be week 2');\n    assert.equal(moment([2012, 0, 15]).format('w ww wo'), '2 02 2e',   'Jan 15 2012 should be week 2');\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\n\n\nfunction localeModule (name, lifecycle) {\n    QUnit.module('locale:' + name, {\n        setup : function () {\n            moment.locale(name);\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            moment.locale('en');\n            teardownDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n    defineCommonLocaleTests(name, -1, -1);\n}\n\nlocaleModule('fr');\n\ntest('parse', function (assert) {\n    var i,\n        tests = 'janvier janv._février févr._mars mars_avril avr._mai mai_juin juin_juillet juil._août août_septembre sept._octobre oct._novembre nov._décembre déc.'.split('_');\n\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, MMMM Do YYYY, h:mm:ss a', 'dimanche, février 14 2010, 3:25:50 pm'],\n            ['ddd, hA',                       'dim., 3PM'],\n            ['M Mo MM MMMM MMM',              '2 2e 02 février févr.'],\n            ['YYYY YY',                       '2010 10'],\n            ['D Do DD',                       '14 14 14'],\n            ['d do dddd ddd dd',              '0 0e dimanche dim. Di'],\n            ['DDD DDDo DDDD',                 '45 45e 045'],\n            ['w wo ww',                       '6 6e 06'],\n            ['h hh',                          '3 03'],\n            ['H HH',                          '15 15'],\n            ['m mm',                          '25 25'],\n            ['s ss',                          '50 50'],\n            ['a A',                           'pm PM'],\n            ['[le] Do [jour du mois]',        'le 14 jour du mois'],\n            ['[le] DDDo [jour de l’année]',   'le 45e jour de l’année'],\n            ['LTS',                           '15:25:50'],\n            ['L',                             '14/02/2010'],\n            ['LL',                            '14 février 2010'],\n            ['LLL',                           '14 février 2010 15:25'],\n            ['LLLL',                          'dimanche 14 février 2010 15:25'],\n            ['l',                             '14/2/2010'],\n            ['ll',                            '14 févr. 2010'],\n            ['lll',                           '14 févr. 2010 15:25'],\n            ['llll',                          'dim. 14 févr. 2010 15:25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2017, 0, 1]).format('Mo'),     '1er',     '1er');\n    assert.equal(moment([2017, 1, 1]).format('Mo'),     '2e',      '2e');\n\n    assert.equal(moment([2017, 0, 1]).format('Qo'),     '1er',     '1er');\n    assert.equal(moment([2017, 3, 1]).format('Qo'),     '2e',      '2e');\n\n    assert.equal(moment([2017, 0, 1]).format('Do'),     '1er',     '1er');\n    assert.equal(moment([2017, 0, 2]).format('Do'),     '2',       '2');\n\n    assert.equal(moment([2011, 0, 1]).format('DDDo'),   '1er',     '1er');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'),   '2e',      '2e');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'),   '3e',      '3e');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'),   '4e',      '4e');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'),   '5e',      '5e');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'),   '6e',      '6e');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'),   '7e',      '7e');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'),   '8e',      '8e');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'),   '9e',      '9e');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'),  '10e',     '10e');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'),  '11e',     '11e');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'),  '12e',     '12e');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'),  '13e',     '13e');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'),  '14e',     '14e');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'),  '15e',     '15e');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'),  '16e',     '16e');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'),  '17e',     '17e');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'),  '18e',     '18e');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'),  '19e',     '19e');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'),  '20e',     '20e');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'),  '21e',     '21e');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'),  '22e',     '22e');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'),  '23e',     '23e');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'),  '24e',     '24e');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'),  '25e',     '25e');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'),  '26e',     '26e');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'),  '27e',     '27e');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'),  '28e',     '28e');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'),  '29e',     '29e');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'),  '30e',     '30e');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'),  '31e',     '31e');\n\n    assert.equal(moment([2017, 0, 1]).format('do'),     '0e',      '0e');\n    assert.equal(moment([2017, 0, 2]).format('do'),     '1er',     '1er');\n\n    assert.equal(moment([2017, 0, 4]).format('wo Wo'),  '1re 1re', '1re 1re');\n    assert.equal(moment([2017, 0, 11]).format('wo Wo'), '2e 2e',   '2e 2e');\n});\n\ntest('format month', function (assert) {\n    var i,\n        expected = 'janvier janv._février févr._mars mars_avril avr._mai mai_juin juin_juillet juil._août août_septembre sept._octobre oct._novembre nov._décembre déc.'.split('_');\n\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var i,\n        expected = 'dimanche dim. Di_lundi lun. Lu_mardi mar. Ma_mercredi mer. Me_jeudi jeu. Je_vendredi ven. Ve_samedi sam. Sa'.split('_');\n\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'quelques secondes', '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'une minute',        '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'une minute',        '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 minutes',         '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 minutes',        '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'une heure',         '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'une heure',         '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 heures',          '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 heures',          '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 heures',         '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'un jour',           '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'un jour',           '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 jours',           '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'un jour',           '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 jours',           '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 jours',          '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'un mois',           '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'un mois',           '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'un mois',           '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 mois',            '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 mois',            '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 mois',            '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'un mois',           '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 mois',            '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'un an',             '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 ans',             '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'un an',             '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 ans',             '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'dans quelques secondes',   'prefix');\n    assert.equal(moment(0).from(30000), 'il y a quelques secondes', 'suffix');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'dans quelques secondes', 'in a few seconds');\n    assert.equal(moment().add({d: 5}).fromNow(),  'dans 5 jours',           'in 5 days');\n});\n\ntest('same day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                  'Aujourd’hui à 12:00', 'Today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),     'Aujourd’hui à 12:25', 'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),      'Aujourd’hui à 13:00', 'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),      'Demain à 12:00',      'Tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(), 'Aujourd’hui à 11:00', 'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(), 'Hier à 12:00',        'Yesterday at the same time');\n});\n\ntest('same next week', function (assert) {\n    var i, m;\n\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(), m.format('dddd [à] LT'), 'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(), m.format('dddd [à] LT'), 'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(), m.format('dddd [à] LT'), 'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('same last week', function (assert) {\n    var i, m;\n\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(), m.format('dddd [dernier à] LT'), 'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(), m.format('dddd [dernier à] LT'), 'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(), m.format('dddd [dernier à] LT'), 'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('same all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),     weeksAgo.format('L'),     '1 week ago');\n    assert.equal(weeksFromNow.calendar(), weeksFromNow.format('L'), 'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),     weeksAgo.format('L'),     '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(), weeksFromNow.format('L'), 'in 2 weeks');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2012, 0,  1]).format('w ww wo'), '52 52 52e', 'Jan  1 2012 should be week 52');\n    assert.equal(moment([2012, 0,  2]).format('w ww wo'), '1 01 1re',  'Jan  2 2012 should be week 1');\n    assert.equal(moment([2012, 0,  8]).format('w ww wo'), '1 01 1re',  'Jan  8 2012 should be week 1');\n    assert.equal(moment([2012, 0,  9]).format('w ww wo'), '2 02 2e',   'Jan  9 2012 should be week 2');\n    assert.equal(moment([2012, 0, 15]).format('w ww wo'), '2 02 2e',   'Jan 15 2012 should be week 2');\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\n\n\nfunction localeModule (name, lifecycle) {\n    QUnit.module('locale:' + name, {\n        setup : function () {\n            moment.locale(name);\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            moment.locale('en');\n            teardownDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n    defineCommonLocaleTests(name, -1, -1);\n}\n\nlocaleModule('fy');\n\ntest('parse', function (assert) {\n    var tests = 'jannewaris jan._febrewaris feb._maart mrt._april apr._maaie mai._juny jun._july jul._augustus aug._septimber sep._oktober okt._novimber nov._desimber des.'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, MMMM Do YYYY, HH:mm:ss',       'snein, febrewaris 14de 2010, 15:25:50'],\n            ['ddd, HH',                            'si., 15'],\n            ['M Mo MM MMMM MMM',                   '2 2de 02 febrewaris feb.'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14de 14'],\n            ['d do dddd ddd dd',                   '0 0de snein si. Si'],\n            ['DDD DDDo DDDD',                      '45 45ste 045'],\n            ['w wo ww',                            '6 6de 06'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'pm PM'],\n            ['[the] DDDo [day of the year]',       'the 45ste day of the year'],\n            ['LTS',                                '15:25:50'],\n            ['L',                                  '14-02-2010'],\n            ['LL',                                 '14 febrewaris 2010'],\n            ['LLL',                                '14 febrewaris 2010 15:25'],\n            ['LLLL',                               'snein 14 febrewaris 2010 15:25'],\n            ['l',                                  '14-2-2010'],\n            ['ll',                                 '14 feb. 2010'],\n            ['lll',                                '14 feb. 2010 15:25'],\n            ['llll',                               'si. 14 feb. 2010 15:25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1ste', '1ste');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2de', '2de');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3de', '3de');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4de', '4de');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5de', '5de');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6de', '6de');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7de', '7de');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8ste', '8ste');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9de', '9de');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10de', '10de');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11de', '11de');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12de', '12de');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13de', '13de');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14de', '14de');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15de', '15de');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16de', '16de');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17de', '17de');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18de', '18de');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19de', '19de');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20ste', '20ste');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21ste', '21ste');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22ste', '22ste');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23ste', '23ste');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24ste', '24ste');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25ste', '25ste');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26ste', '26ste');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27ste', '27ste');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28ste', '28ste');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29ste', '29ste');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30ste', '30ste');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31ste', '31ste');\n});\n\ntest('format month', function (assert) {\n    var expected = 'jannewaris jan._febrewaris feb._maart mrt._april apr._maaie mai_juny jun._july jul._augustus aug._septimber sep._oktober okt._novimber nov._desimber des.'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'snein si. Si_moandei mo. Mo_tiisdei ti. Ti_woansdei wo. Wo_tongersdei to. To_freed fr. Fr_sneon so. So'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'in pear sekonden', '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'ien minút',      '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'ien minút',      '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 minuten',     '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 minuten',    '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'ien oere',       '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'ien oere',       '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 oeren',       '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 oeren',       '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 oeren',      '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'ien dei',         '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'ien dei',         '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 dagen',        '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'ien dei',         '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 dagen',        '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 dagen',       '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'ien moanne',       '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'ien moanne',       '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'ien moanne',       '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 moannen',      '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 moannen',      '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 moannen',      '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'ien moanne',       '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 moannen',      '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'ien jier',        '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 jierren',       '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'ien jier',        '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 jierren',       '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'oer in pear sekonden',  'prefix');\n    assert.equal(moment(0).from(30000), 'in pear sekonden lyn', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'in pear sekonden lyn',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'oer in pear sekonden', 'in a few seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), 'oer 5 dagen', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'hjoed om 12:00',     'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'hjoed om 12:25',     'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'hjoed om 13:00',     'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'moarn om 12:00',     'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'hjoed om 11:00',     'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'juster om 12:00',    'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('dddd [om] LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd [om] LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd [om] LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('[ôfrûne] dddd [om] LT'),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[ôfrûne] dddd [om] LT'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[ôfrûne] dddd [om] LT'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('month abbreviation', function (assert) {\n    assert.equal(moment([2012, 5, 23]).format('D-MMM-YYYY'), '23-jun-2012', 'format month abbreviation surrounded by dashes should not include a dot');\n    assert.equal(moment([2012, 5, 23]).format('D MMM YYYY'), '23 jun. 2012', 'format month abbreviation not surrounded by dashes should include a dot');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2012, 0,  1]).format('w ww wo'), '52 52 52ste', 'Jan  1 2012 should be week 52');\n    assert.equal(moment([2012, 0,  2]).format('w ww wo'),   '1 01 1ste', 'Jan  2 2012 should be week 1');\n    assert.equal(moment([2012, 0,  8]).format('w ww wo'),   '1 01 1ste', 'Jan  8 2012 should be week 1');\n    assert.equal(moment([2012, 0,  9]).format('w ww wo'),    '2 02 2de', 'Jan  9 2012 should be week 2');\n    assert.equal(moment([2012, 0, 15]).format('w ww wo'),    '2 02 2de', 'Jan 15 2012 should be week 2');\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\n\n\nfunction localeModule (name, lifecycle) {\n    QUnit.module('locale:' + name, {\n        setup : function () {\n            moment.locale(name);\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            moment.locale('en');\n            teardownDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n    defineCommonLocaleTests(name, -1, -1);\n}\n\nlocaleModule('gd');\n\nvar months = [\n    'Am Faoilleach,Faoi',\n    'An Gearran,Gear',\n    'Am Màrt,Màrt',\n    'An Giblean,Gibl',\n    'An Cèitean,Cèit',\n    'An t-Ògmhios,Ògmh',\n    'An t-Iuchar,Iuch',\n    'An Lùnastal,Lùn',\n    'An t-Sultain,Sult',\n    'An Dàmhair,Dàmh',\n    'An t-Samhain,Samh',\n    'An Dùbhlachd,Dùbh'\n];\n\ntest('parse', function (assert) {\n    function equalTest(monthName, monthFormat, monthNum) {\n        assert.equal(moment(monthName, monthFormat).month(), monthNum, monthName + ' should be month ' + (monthNum + 1));\n    }\n\n    for (var i = 0; i < 12; i++) {\n        var testMonth = months[i].split(',');\n        equalTest(testMonth[0], 'MMM', i);\n        equalTest(testMonth[1], 'MMM', i);\n        equalTest(testMonth[0], 'MMMM', i);\n        equalTest(testMonth[1], 'MMMM', i);\n        equalTest(testMonth[0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(testMonth[1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(testMonth[0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(testMonth[1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n        ['dddd, MMMM Do YYYY, h:mm:ss a', 'Didòmhnaich, An Gearran 14mh 2010, 3:25:50 pm'],\n        ['ddd, hA', 'Did, 3PM'],\n        ['M Mo MM MMMM MMM', '2 2na 02 An Gearran Gear'],\n        ['YYYY YY', '2010 10'],\n        ['D Do DD', '14 14mh 14'],\n        ['d do dddd ddd dd', '0 0mh Didòmhnaich Did Dò'],\n        ['DDD DDDo DDDD', '45 45mh 045'],\n        ['w wo ww', '6 6mh 06'],\n        ['h hh', '3 03'],\n        ['H HH', '15 15'],\n        ['m mm', '25 25'],\n        ['s ss', '50 50'],\n        ['a A', 'pm PM'],\n        ['[an] DDDo [latha den bhliadhna]', 'an 45mh latha den bhliadhna'],\n        ['LTS', '15:25:50'],\n        ['L', '14/02/2010'],\n        ['LL', '14 An Gearran 2010'],\n        ['LLL', '14 An Gearran 2010 15:25'],\n        ['LLLL', 'Didòmhnaich, 14 An Gearran 2010 15:25'],\n        ['l', '14/2/2010'],\n        ['ll', '14 Gear 2010'],\n        ['lll', '14 Gear 2010 15:25'],\n        ['llll', 'Did, 14 Gear 2010 15:25']\n    ],\n    b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n    i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1d', '1d');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2na', '2na');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3mh', '3mh');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4mh', '4mh');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5mh', '5mh');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6mh', '6mh');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7mh', '7mh');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8mh', '8mh');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9mh', '9mh');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10mh', '10mh');\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11mh', '11mh');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12na', '12na');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13mh', '13mh');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14mh', '14mh');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15mh', '15mh');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16mh', '16mh');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17mh', '17mh');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18mh', '18mh');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19mh', '19mh');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20mh', '20mh');\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21mh', '21mh');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22na', '22na');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23mh', '23mh');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24mh', '24mh');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25mh', '25mh');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26mh', '26mh');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27mh', '27mh');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28mh', '28mh');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29mh', '29mh');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30mh', '30mh');\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31mh', '31mh');\n});\n\ntest('format month', function (assert) {\n    var expected = months;\n    for (var i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM,MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = ['Didòmhnaich Did Dò', 'Diluain Dil Lu', 'Dimàirt Dim Mà', 'Diciadain Dic Ci', 'Diardaoin Dia Ar', 'Dihaoine Dih Ha', 'Disathairne Dis Sa'];\n    for (var i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true), 'beagan diogan', '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true), 'mionaid', '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true), 'mionaid', '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true), '2 mionaidean', '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true), '44 mionaidean', '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true), 'uair', '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true), 'uair', '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true), '2 uairean', '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true), '5 uairean', '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true), '21 uairean', '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true), 'latha', '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true), 'latha', '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true), '2 latha', '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true), 'latha', '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true), '5 latha', '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true), '25 latha', '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true), 'mìos', '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true), 'mìos', '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true), 'mìos', '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true), '2 mìosan', '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true), '2 mìosan', '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true), '3 mìosan', '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true), 'mìos', '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true), '5 mìosan', '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'bliadhna', '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 bliadhna', '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true), 'bliadhna', '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true), '5 bliadhna', '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'ann an beagan diogan', 'prefix');\n    assert.equal(moment(0).from(30000), 'bho chionn beagan diogan', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'bho chionn beagan diogan', 'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'ann an beagan diogan', 'in a few seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), 'ann an 5 latha', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                  'An-diugh aig 12:00',   'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),     'An-diugh aig 12:25',   'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),      'An-diugh aig 13:00',   'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),      'A-màireach aig 12:00', 'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(), 'An-diugh aig 11:00',   'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(), 'An-dè aig 12:00',      'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(), m.format('dddd [aig] LT'), 'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(), m.format('dddd [aig] LT'), 'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(), m.format('dddd [aig] LT'), 'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(), m.format('dddd [seo chaidh] [aig] LT'), 'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(), m.format('dddd [seo chaidh] [aig] LT'), 'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(), m.format('dddd [seo chaidh] [aig] LT'), 'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n       weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '1 week ago');\n    assert.equal(weeksFromNow.calendar(), weeksFromNow.format('L'), 'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(), weeksFromNow.format('L'), 'in 2 weeks');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2012, 0, 1]).format('w ww wo'), '52 52 52na', 'Faoi  1 2012 should be week 52');\n    assert.equal(moment([2012, 0, 2]).format('w ww wo'), '1 01 1d', 'Faoi  2 2012 should be week 1');\n    assert.equal(moment([2012, 0, 8]).format('w ww wo'), '1 01 1d', 'Faoi  8 2012 should be week 1');\n    assert.equal(moment([2012, 0, 9]).format('w ww wo'), '2 02 2na', 'Faoi  9 2012 should be week 2');\n    assert.equal(moment([2012, 0, 15]).format('w ww wo'), '2 02 2na', 'Faoi 15 2012 should be week 2');\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\n\n\nfunction localeModule (name, lifecycle) {\n    QUnit.module('locale:' + name, {\n        setup : function () {\n            moment.locale(name);\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            moment.locale('en');\n            teardownDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n    defineCommonLocaleTests(name, -1, -1);\n}\n\nlocaleModule('gl');\n\ntest('parse', function (assert) {\n    var tests = 'xaneiro xan._febreiro feb._marzo mar._abril abr._maio mai._xuño xuñ._xullo xul._agosto ago._setembro set._outubro out._novembro nov._decembro dec.'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, MMMM Do YYYY, h:mm:ss a',      'domingo, febreiro 14º 2010, 3:25:50 pm'],\n            ['ddd, hA',                            'dom., 3PM'],\n            ['M Mo MM MMMM MMM',                   '2 2º 02 febreiro feb.'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14º 14'],\n            ['d do dddd ddd dd',                   '0 0º domingo dom. do'],\n            ['DDD DDDo DDDD',                      '45 45º 045'],\n            ['w wo ww',                            '6 6º 06'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'pm PM'],\n            ['[the] DDDo [day of the year]',       'the 45º day of the year'],\n            ['LTS',                                '15:25:50'],\n            ['L',                                  '14/02/2010'],\n            ['LL',                                 '14 de febreiro de 2010'],\n            ['LLL',                                '14 de febreiro de 2010 15:25'],\n            ['LLLL',                               'domingo, 14 de febreiro de 2010 15:25'],\n            ['l',                                  '14/2/2010'],\n            ['ll',                                 '14 de feb. de 2010'],\n            ['lll',                                '14 de feb. de 2010 15:25'],\n            ['llll',                               'dom., 14 de feb. de 2010 15:25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1º', '1º');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2º', '2º');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3º', '3º');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4º', '4º');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5º', '5º');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6º', '6º');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7º', '7º');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8º', '8º');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9º', '9º');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10º', '10º');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11º', '11º');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12º', '12º');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13º', '13º');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14º', '14º');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15º', '15º');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16º', '16º');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17º', '17º');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18º', '18º');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19º', '19º');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20º', '20º');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21º', '21º');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22º', '22º');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23º', '23º');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24º', '24º');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25º', '25º');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26º', '26º');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27º', '27º');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28º', '28º');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29º', '29º');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30º', '30º');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31º', '31º');\n});\n\ntest('format month', function (assert) {\n    var expected = 'xaneiro xan._febreiro feb._marzo mar._abril abr._maio mai._xuño xuñ._xullo xul._agosto ago._setembro set._outubro out._novembro nov._decembro dec.'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'domingo dom. do_luns lun. lu_martes mar. ma_mércores mér. mé_xoves xov. xo_venres ven. ve_sábado sáb. sá'.split('_'),\n    i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'uns segundos', '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'un minuto',      '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'un minuto',      '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 minutos',     '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 minutos',    '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'unha hora',       '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'unha hora',       '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 horas',       '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 horas',       '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 horas',      '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'un día',         '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'un día',         '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 días',        '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'un día',         '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 días',        '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 días',       '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'un mes',       '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'un mes',       '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'un mes',       '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 meses',      '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 meses',      '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 meses',      '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'un mes',       '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 meses',      '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'un ano',        '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 anos',       '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'un ano',        '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 anos',       '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'nuns segundos',  'prefix');\n    assert.equal(moment(0).from(30000), 'hai uns segundos', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'hai uns segundos',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'nuns segundos', 'nuns segundos');\n    assert.equal(moment().add({d: 5}).fromNow(), 'en 5 días', 'en 5 días');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                       'hoxe ás 12:00',  'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),          'hoxe ás 12:25',  'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),           'hoxe ás 13:00',  'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),           'mañá ás 12:00',  'tomorrow at the same time');\n    assert.equal(moment(a).add({d: 1, h : -1}).calendar(),   'mañá ás 11:00',   'tomorrow minus 1 hour');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),      'hoxe ás 11:00',   'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),      'onte á 12:00',   'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('dddd [' + ((m.hours() !== 1) ? 'ás' : 'a') + '] LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd [' + ((m.hours() !== 1) ? 'ás' : 'a') + '] LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd [' + ((m.hours() !== 1) ? 'ás' : 'a') + '] LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('[o] dddd [pasado ' + ((m.hours() !== 1) ? 'ás' : 'a') + '] LT'),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[o] dddd [pasado ' + ((m.hours() !== 1) ? 'ás' : 'a') + '] LT'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[o] dddd [pasado ' + ((m.hours() !== 1) ? 'ás' : 'a') + '] LT'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('regression tests', function (assert) {\n    var lastWeek = moment().subtract({d: 4}).hours(1);\n    assert.equal(lastWeek.calendar(), lastWeek.format('[o] dddd [pasado a] LT'), '1 o\\'clock bug');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2012, 0,  1]).format('w ww wo'), '52 52 52º', 'Jan  1 2012 should be week 52');\n    assert.equal(moment([2012, 0,  2]).format('w ww wo'),   '1 01 1º', 'Jan  2 2012 should be week 1');\n    assert.equal(moment([2012, 0,  8]).format('w ww wo'),   '1 01 1º', 'Jan  8 2012 should be week 1');\n    assert.equal(moment([2012, 0,  9]).format('w ww wo'),   '2 02 2º', 'Jan  9 2012 should be week 2');\n    assert.equal(moment([2012, 0, 15]).format('w ww wo'),   '2 02 2º', 'Jan 15 2012 should be week 2');\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\n\n\nfunction localeModule (name, lifecycle) {\n    QUnit.module('locale:' + name, {\n        setup : function () {\n            moment.locale(name);\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            moment.locale('en');\n            teardownDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n    defineCommonLocaleTests(name, -1, -1);\n}\n\nlocaleModule('gom-latn');\n\ntest('parse', function (assert) {\n    var i,\n        tests = 'Janer Jan._Febrer Feb._Mars Mars_Abril Abr._Mai Mai_Jun Jun_Julai Jul._Agost Ago._Setembr Set._Otubr Otu._Novembr Nov._Dezembr Dez.'.split('_');\n\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, MMMM Do YYYY, h:mm:ss a',      'Aitar, Febrer 14er 2010, 3:25:50 donparam'],\n            ['ddd, hA',                            'Ait., 3donparam'],\n            ['M Mo MM MMMM MMM',                   '2 2 02 Febrer Feb.'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14er 14'],\n            ['d do dddd ddd dd',                   '0 0 Aitar Ait. Ai'],\n            ['DDD DDDo DDDD',                      '45 45 045'],\n            ['w wo ww',                            '6 6 06'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'donparam donparam'],\n            ['[the] DDDo [day of the year]',       'the 45 day of the year'],\n            ['LTS',                                'donparam 3:25:50 vazta'],\n            ['L',                                  '14-02-2010'],\n            ['LL',                                 '14 Febrer 2010'],\n            ['LLL',                                '14 Febrer 2010 donparam 3:25 vazta'],\n            ['LLLL',                               'Aitar, Febrerachea 14er, 2010, donparam 3:25 vazta'],\n            ['l',                                  '14-2-2010'],\n            ['ll',                                 '14 Feb. 2010'],\n            ['lll',                                '14 Feb. 2010 donparam 3:25 vazta'],\n            ['llll',                               'Ait., 14 Feb. 2010, donparam 3:25 vazta']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1', '1');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2', '2');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3', '3');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4', '4');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5', '5');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6', '6');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7', '7');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8', '8');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9', '9');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10', '10');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11', '11');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12', '12');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13', '13');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14', '14');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15', '15');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16', '16');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17', '17');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18', '18');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19', '19');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20', '20');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21', '21');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22', '22');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23', '23');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24', '24');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25', '25');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26', '26');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27', '27');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28', '28');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29', '29');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30', '30');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31', '31');\n});\n\ntest('format month', function (assert) {\n    var i,\n        expected = 'Janer Jan._Febrer Feb._Mars Mars_Abril Abr._Mai Mai_Jun Jun_Julai Jul._Agost Ago._Setembr Set._Otubr Otu._Novembr Nov._Dezembr Dez.'.split('_');\n\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var i,\n        expected = 'Aitar Ait. Ai_Somar Som. Sm_Mongllar Mon. Mo_Budvar Bud. Bu_Brestar Bre. Br_Sukrar Suk. Su_Son\\'var Son. Sn'.split('_');\n\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'thodde secondanim', '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'eka mintan',      '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'eka mintan',      '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 mintanim',     '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 mintanim',    '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'eka horan',       '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'eka horan',       '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 horanim',       '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 horanim',       '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 horanim',      '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'eka disan',         '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'eka disan',         '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 disanim',        '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'eka disan',         '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 disanim',        '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 disanim',       '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'eka mhoinean',       '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'eka mhoinean',       '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'eka mhoinean',       '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 mhoineanim',      '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 mhoineanim',      '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 mhoineanim',      '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'eka mhoinean',       '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 mhoineanim',      '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'eka vorsan',        '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 vorsanim',       '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'eka vorsan',        '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 vorsanim',       '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'thodde second',  'prefix');\n    assert.equal(moment(0).from(30000), 'thodde second adim', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'thodde second adim',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'thodde second', 'in a few seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), '5 dis', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'Aiz donparam 12:00 vazta',     'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'Aiz donparam 12:25 vazta',     'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'Aiz donparam 1:00 vazta',      'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'Faleam donparam 12:00 vazta',  'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'Aiz sokalli 11:00 vazta',     'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'Kal donparam 12:00 vazta', 'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('[Ieta to] dddd[,] LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[Ieta to] dddd[,] LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[Ieta to] dddd[,] LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('[Fatlo] dddd[,] LT'),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[Fatlo] dddd[,] LT'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[Fatlo] dddd[,] LT'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('weeks year starting sunday format', function (assert) {\n    assert.equal(moment([2012, 0,  1]).format('w ww wo'), '52 52 52', 'Jan  1 2012 should be week 52');\n    assert.equal(moment([2012, 0,  2]).format('w ww wo'), '1 01 1', 'Jan  2 2012 should be week 1');\n    assert.equal(moment([2012, 0,  8]).format('w ww wo'), '1 01 1', 'Jan  8 2012 should be week 1');\n    assert.equal(moment([2012, 0, 14]).format('w ww wo'), '2 02 2', 'Jan 14 2012 should be week 2');\n    assert.equal(moment([2012, 0, 15]).format('w ww wo'), '2 02 2', 'Jan 15 2012 should be week 2');\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\n\n\nfunction localeModule (name, lifecycle) {\n    QUnit.module('locale:' + name, {\n        setup : function () {\n            moment.locale(name);\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            moment.locale('en');\n            teardownDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n    defineCommonLocaleTests(name, -1, -1);\n}\n\nlocaleModule('he');\n\ntest('parse', function (assert) {\n    var tests = 'ינואר ינו׳_פברואר פבר׳_מרץ מרץ_אפריל אפר׳_מאי מאי_יוני יוני_יולי יולי_אוגוסט אוג׳_ספטמבר ספט׳_אוקטובר אוק׳_נובמבר נוב׳_דצמבר דצמ׳'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, MMMM Do YYYY, h:mm:ss a',      'ראשון, פברואר 14 2010, 3:25:50 אחה\"צ'],\n            ['ddd, h A',                           'א׳, 3 אחרי הצהריים'],\n            ['M Mo MM MMMM MMM',                   '2 2 02 פברואר פבר׳'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14 14'],\n            ['d do dddd ddd dd',                   '0 0 ראשון א׳ א'],\n            ['DDD DDDo DDDD',                      '45 45 045'],\n            ['w wo ww',                            '8 8 08'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'אחה\"צ אחרי הצהריים'],\n            ['[the] DDDo [day of the year]',       'the 45 day of the year'],\n            ['LTS',                                '15:25:50'],\n            ['L',                                  '14/02/2010'],\n            ['LL',                                 '14 בפברואר 2010'],\n            ['LLL',                                '14 בפברואר 2010 15:25'],\n            ['LLLL',                               'ראשון, 14 בפברואר 2010 15:25'],\n            ['l',                                  '14/2/2010'],\n            ['ll',                                 '14 פבר׳ 2010'],\n            ['lll',                                '14 פבר׳ 2010 15:25'],\n            ['llll',                               'א׳, 14 פבר׳ 2010 15:25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format month', function (assert) {\n    var expected = 'ינואר ינו׳_פברואר פבר׳_מרץ מרץ_אפריל אפר׳_מאי מאי_יוני יוני_יולי יולי_אוגוסט אוג׳_ספטמבר ספט׳_אוקטובר אוק׳_נובמבר נוב׳_דצמבר דצמ׳'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'ראשון א׳ א|שני ב׳ ב|שלישי ג׳ ג|רביעי ד׳ ד|חמישי ה׳ ה|שישי ו׳ ו|שבת ש׳ ש'.split('|'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'מספר שניות', '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'דקה',      '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'דקה',      '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 דקות',     '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 דקות',    '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'שעה',       '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'שעה',       '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  'שעתיים',       '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 שעות',       '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 שעות',      '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'יום',         '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'יום',         '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  'יומיים',        '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'יום',         '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 ימים',        '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 ימים',       '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'חודש',       '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'חודש',       '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'חודש',       '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  'חודשיים',      '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  'חודשיים',      '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 חודשים',      '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'חודש',       '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 חודשים',      '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'שנה',        '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), 'שנתיים',       '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 3699}), true), '10 שנים',        '345 days = 10 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 7340}), true), '20 שנה',       '548 days = 20 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'שנה',        '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 שנים',       '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'בעוד מספר שניות',  'prefix');\n    assert.equal(moment(0).from(30000), 'לפני מספר שניות', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'לפני מספר שניות',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'בעוד מספר שניות', 'in a few seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), 'בעוד 5 ימים', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'היום ב־12:00',   'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'היום ב־12:25',   'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'היום ב־13:00',   'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'מחר ב־12:00',   'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'היום ב־11:00',   'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'אתמול ב־12:00',  'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('dddd [בשעה] LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd [בשעה] LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd [בשעה] LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('[ביום] dddd [האחרון בשעה] LT'),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[ביום] dddd [האחרון בשעה] LT'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[ביום] dddd [האחרון בשעה] LT'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('weeks year starting sunday format', function (assert) {\n    assert.equal(moment([2012, 0,  1]).format('w ww wo'), '1 01 1', 'Jan  1 2012 should be week 1');\n    assert.equal(moment([2012, 0,  7]).format('w ww wo'), '1 01 1', 'Jan  7 2012 should be week 1');\n    assert.equal(moment([2012, 0,  8]).format('w ww wo'), '2 02 2', 'Jan  8 2012 should be week 2');\n    assert.equal(moment([2012, 0, 14]).format('w ww wo'), '2 02 2', 'Jan 14 2012 should be week 2');\n    assert.equal(moment([2012, 0, 15]).format('w ww wo'), '3 03 3', 'Jan 15 2012 should be week 3');\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\n\n\nfunction localeModule (name, lifecycle) {\n    QUnit.module('locale:' + name, {\n        setup : function () {\n            moment.locale(name);\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            moment.locale('en');\n            teardownDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n    defineCommonLocaleTests(name, -1, -1);\n}\n\nlocaleModule('hi');\n\ntest('parse', function (assert) {\n    var tests = 'जनवरी जन._फ़रवरी फ़र._मार्च मार्च_अप्रैल अप्रै._मई मई_जून जून_जुलाई जुल._अगस्त अग._सितम्बर सित._अक्टूबर अक्टू._नवम्बर नव._दिसम्बर दिस.'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, Do MMMM YYYY, a h:mm:ss बजे',  'रविवार, १४ फ़रवरी २०१०, दोपहर ३:२५:५० बजे'],\n            ['ddd, a h बजे',                       'रवि, दोपहर ३ बजे'],\n            ['M Mo MM MMMM MMM',                   '२ २ ०२ फ़रवरी फ़र.'],\n            ['YYYY YY',                            '२०१० १०'],\n            ['D Do DD',                            '१४ १४ १४'],\n            ['d do dddd ddd dd',                   '० ० रविवार रवि र'],\n            ['DDD DDDo DDDD',                      '४५ ४५ ०४५'],\n            ['w wo ww',                            '८ ८ ०८'],\n            ['h hh',                               '३ ०३'],\n            ['H HH',                               '१५ १५'],\n            ['m mm',                               '२५ २५'],\n            ['s ss',                               '५० ५०'],\n            ['a A',                                'दोपहर दोपहर'],\n            ['LTS',                                'दोपहर ३:२५:५० बजे'],\n            ['L',                                  '१४/०२/२०१०'],\n            ['LL',                                 '१४ फ़रवरी २०१०'],\n            ['LLL',                                '१४ फ़रवरी २०१०, दोपहर ३:२५ बजे'],\n            ['LLLL',                               'रविवार, १४ फ़रवरी २०१०, दोपहर ३:२५ बजे'],\n            ['l',                                  '१४/२/२०१०'],\n            ['ll',                                 '१४ फ़र. २०१०'],\n            ['lll',                                '१४ फ़र. २०१०, दोपहर ३:२५ बजे'],\n            ['llll',                               'रवि, १४ फ़र. २०१०, दोपहर ३:२५ बजे']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '१', '१');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '२', '२');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '३', '३');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '४', '४');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '५', '५');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '६', '६');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '७', '७');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '८', '८');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '९', '९');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '१०', '१०');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '११', '११');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '१२', '१२');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '१३', '१३');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '१४', '१४');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '१५', '१५');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '१६', '१६');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '१७', '१७');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '१८', '१८');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '१९', '१९');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '२०', '२०');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '२१', '२१');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '२२', '२२');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '२३', '२३');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '२४', '२४');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '२५', '२५');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '२६', '२६');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '२७', '२७');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '२८', '२८');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '२९', '२९');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '३०', '३०');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '३१', '३१');\n});\n\ntest('format month', function (assert) {\n    var expected = 'जनवरी जन._फ़रवरी फ़र._मार्च मार्च_अप्रैल अप्रै._मई मई_जून जून_जुलाई जुल._अगस्त अग._सितम्बर सित._अक्टूबर अक्टू._नवम्बर नव._दिसम्बर दिस.'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'रविवार रवि र_सोमवार सोम सो_मंगलवार मंगल मं_बुधवार बुध बु_गुरूवार गुरू गु_शुक्रवार शुक्र शु_शनिवार शनि श'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'कुछ ही क्षण', '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'एक मिनट',      '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'एक मिनट',      '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '२ मिनट',     '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '४४ मिनट',    '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'एक घंटा',       '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'एक घंटा',       '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '२ घंटे',       '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '५ घंटे',       '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '२१ घंटे',      '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'एक दिन',         '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'एक दिन',         '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '२ दिन',        '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'एक दिन',         '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '५ दिन',        '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '२५ दिन',       '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'एक महीने',       '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'एक महीने',       '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'एक महीने',       '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '२ महीने',      '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '२ महीने',      '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '३ महीने',      '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'एक महीने',       '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '५ महीने',      '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'एक वर्ष',        '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '२ वर्ष',       '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'एक वर्ष',        '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '५ वर्ष',       '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'कुछ ही क्षण में',  'prefix');\n    assert.equal(moment(0).from(30000), 'कुछ ही क्षण पहले', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'कुछ ही क्षण पहले',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'कुछ ही क्षण में', 'कुछ ही क्षण में');\n    assert.equal(moment().add({d: 5}).fromNow(), '५ दिन में', '५ दिन में');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'आज दोपहर १२:०० बजे',    'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'आज दोपहर १२:२५ बजे',    'Now plus 25 min');\n    assert.equal(moment(a).add({h: 3}).calendar(),       'आज दोपहर ३:०० बजे',     'Now plus 3 hours');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'कल दोपहर १२:०० बजे',    'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'आज दोपहर ११:०० बजे',    'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'कल दोपहर १२:०० बजे',    'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('dddd[,] LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd[,] LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd[,] LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('[पिछले] dddd[,] LT'),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[पिछले] dddd[,] LT'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[पिछले] dddd[,] LT'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('meridiem', function (assert) {\n    assert.equal(moment([2011, 2, 23,  2, 30]).format('a'), 'रात', 'before dawn');\n    assert.equal(moment([2011, 2, 23,  9, 30]).format('a'), 'सुबह', 'morning');\n    assert.equal(moment([2011, 2, 23, 14, 30]).format('a'), 'दोपहर', 'during day');\n    assert.equal(moment([2011, 2, 23, 17, 30]).format('a'), 'शाम', 'evening');\n    assert.equal(moment([2011, 2, 23, 19, 30]).format('a'), 'शाम', 'late evening');\n    assert.equal(moment([2011, 2, 23, 21, 20]).format('a'), 'रात', 'night');\n\n    assert.equal(moment([2011, 2, 23,  2, 30]).format('A'), 'रात', 'before dawn');\n    assert.equal(moment([2011, 2, 23,  9, 30]).format('A'), 'सुबह', 'morning');\n    assert.equal(moment([2011, 2, 23, 14, 30]).format('A'), 'दोपहर', ' during day');\n    assert.equal(moment([2011, 2, 23, 17, 30]).format('A'), 'शाम', 'evening');\n    assert.equal(moment([2011, 2, 23, 19, 30]).format('A'), 'शाम', 'late evening');\n    assert.equal(moment([2011, 2, 23, 21, 20]).format('A'), 'रात', 'night');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2012, 0,  1]).format('w ww wo'), '१ ०१ १', 'Jan  1 2012 should be week 1');\n    assert.equal(moment([2012, 0,  7]).format('w ww wo'), '१ ०१ १', 'Jan  7 2012 should be week 1');\n    assert.equal(moment([2012, 0,  8]).format('w ww wo'), '२ ०२ २', 'Jan  8 2012 should be week 2');\n    assert.equal(moment([2012, 0, 14]).format('w ww wo'), '२ ०२ २', 'Jan 14 2012 should be week 2');\n    assert.equal(moment([2012, 0, 15]).format('w ww wo'), '३ ०३ ३', 'Jan 15 2012 should be week 3');\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\n\n\nfunction localeModule (name, lifecycle) {\n    QUnit.module('locale:' + name, {\n        setup : function () {\n            moment.locale(name);\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            moment.locale('en');\n            teardownDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n    defineCommonLocaleTests(name, -1, -1);\n}\n\nlocaleModule('hr');\n\ntest('parse', function (assert) {\n    var tests = 'siječanj sij._veljača velj._ožujak ožu._travanj tra._svibanj svi._lipanj lip._srpanj srp._kolovoz kol._rujan ruj._listopad lis._studeni stu._prosinac pro.'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, Do MMMM YYYY, h:mm:ss a',      'nedjelja, 14. veljače 2010, 3:25:50 pm'],\n            ['ddd, hA',                            'ned., 3PM'],\n            ['M Mo MM MMMM MMM',                   '2 2. 02 veljača velj.'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14. 14'],\n            ['d do dddd ddd dd',                   '0 0. nedjelja ned. ne'],\n            ['DDD DDDo DDDD',                      '45 45. 045'],\n            ['w wo ww',                            '7 7. 07'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'pm PM'],\n            ['[the] DDDo [day of the year]',       'the 45. day of the year'],\n            ['LTS',                                '15:25:50'],\n            ['L',                                  '14.02.2010'],\n            ['LL',                                 '14. veljača 2010'],\n            ['LLL',                                '14. veljača 2010 15:25'],\n            ['LLLL',                               'nedjelja, 14. veljača 2010 15:25'],\n            ['l',                                  '14.2.2010'],\n            ['ll',                                 '14. velj. 2010'],\n            ['lll',                                '14. velj. 2010 15:25'],\n            ['llll',                               'ned., 14. velj. 2010 15:25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1.', '1.');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2.', '2.');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3.', '3.');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4.', '4.');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5.', '5.');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6.', '6.');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7.', '7.');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8.', '8.');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9.', '9.');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10.', '10.');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11.', '11.');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12.', '12.');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13.', '13.');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14.', '14.');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15.', '15.');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16.', '16.');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17.', '17.');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18.', '18.');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19.', '19.');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20.', '20.');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21.', '21.');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22.', '22.');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23.', '23.');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24.', '24.');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25.', '25.');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26.', '26.');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27.', '27.');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28.', '28.');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29.', '29.');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30.', '30.');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31.', '31.');\n});\n\ntest('format month', function (assert) {\n    var expected = 'siječanj sij._veljača velj._ožujak ožu._travanj tra._svibanj svi._lipanj lip._srpanj srp._kolovoz kol._rujan ruj._listopad lis._studeni stu._prosinac pro.'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'nedjelja ned. ne_ponedjeljak pon. po_utorak uto. ut_srijeda sri. sr_četvrtak čet. če_petak pet. pe_subota sub. su'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'par sekundi', '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'jedna minuta',   '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'jedna minuta',   '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 minute',     '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 minuta',     '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'jedan sat',      '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'jedan sat',      '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 sata',        '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 sati',         '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 sati',        '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'dan',       '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'dan',       '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 dana',        '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'dan',       '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 dana',        '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 dana',       '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'mjesec',     '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'mjesec',     '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'mjesec',     '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 mjeseca',     '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 mjeseca',     '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 mjeseca',     '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'mjesec',     '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 mjeseci',    '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'godinu',     '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 godine',       '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'godinu',     '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 godina',        '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'za par sekundi',  'prefix');\n    assert.equal(moment(0).from(30000), 'prije par sekundi', 'prefix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'prije par sekundi',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'za par sekundi', 'in a few seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), 'za 5 dana', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'danas u 12:00',  'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'danas u 12:25',  'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'danas u 13:00',  'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'sutra u 12:00',  'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'danas u 11:00',  'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'jučer u 12:00',  'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n\n    function makeFormat(d) {\n        switch (d.day()) {\n            case 0:\n                return '[u] [nedjelju] [u] LT';\n            case 3:\n                return '[u] [srijedu] [u] LT';\n            case 6:\n                return '[u] [subotu] [u] LT';\n            case 1:\n            case 2:\n            case 4:\n            case 5:\n                return '[u] dddd [u] LT';\n        }\n    }\n\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format(makeFormat(m)),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format(makeFormat(m)),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format(makeFormat(m)),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n\n    function makeFormat(d) {\n        switch (d.day()) {\n            case 0:\n            case 3:\n                return '[prošlu] dddd [u] LT';\n            case 6:\n                return '[prošle] [subote] [u] LT';\n            case 1:\n            case 2:\n            case 4:\n            case 5:\n                return '[prošli] dddd [u] LT';\n        }\n    }\n\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format(makeFormat(m)),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format(makeFormat(m)),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format(makeFormat(m)),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2011, 11, 26]).format('w ww wo'), '1 01 1.', 'Dec 26 2011 should be week 1');\n    assert.equal(moment([2012,  0,  1]).format('w ww wo'), '1 01 1.', 'Jan  1 2012 should be week 1');\n    assert.equal(moment([2012,  0,  2]).format('w ww wo'), '2 02 2.', 'Jan  2 2012 should be week 2');\n    assert.equal(moment([2012,  0,  8]).format('w ww wo'), '2 02 2.', 'Jan  8 2012 should be week 2');\n    assert.equal(moment([2012,  0,  9]).format('w ww wo'), '3 03 3.', 'Jan  9 2012 should be week 3');\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\n\n\nfunction localeModule (name, lifecycle) {\n    QUnit.module('locale:' + name, {\n        setup : function () {\n            moment.locale(name);\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            moment.locale('en');\n            teardownDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n    defineCommonLocaleTests(name, -1, -1);\n}\n\nlocaleModule('hu');\n\ntest('parse', function (assert) {\n    var tests = 'január jan_február feb_március márc_április ápr_május máj_június jún_július júl_augusztus aug_szeptember szept_október okt_november nov_december dec'.split('_'),\n        i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, MMMM Do YYYY, HH:mm:ss',      'vasárnap, február 14. 2010, 15:25:50'],\n            ['ddd, HH',                            'vas, 15'],\n            ['M Mo MM MMMM MMM',                   '2 2. 02 február feb'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14. 14'],\n            ['d do dddd ddd dd',                   '0 0. vasárnap vas v'],\n            ['DDD DDDo DDDD',                      '45 45. 045'],\n            ['w wo ww',                            '6 6. 06'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['[az év] DDDo [napja]',               'az év 45. napja'],\n            ['LTS',                                '15:25:50'],\n            ['L',                                  '2010.02.14.'],\n            ['LL',                                 '2010. február 14.'],\n            ['LLL',                                '2010. február 14. 15:25'],\n            ['LLLL',                               '2010. február 14., vasárnap 15:25'],\n            ['l',                                  '2010.2.14.'],\n            ['ll',                                 '2010. feb 14.'],\n            ['lll',                                '2010. feb 14. 15:25'],\n            ['llll',                               '2010. feb 14., vas 15:25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('meridiem', function (assert) {\n    assert.equal(moment([2011, 2, 23,  0,  0]).format('a'), 'de', 'am');\n    assert.equal(moment([2011, 2, 23, 11, 59]).format('a'), 'de', 'am');\n    assert.equal(moment([2011, 2, 23, 12,  0]).format('a'), 'du', 'pm');\n    assert.equal(moment([2011, 2, 23, 23, 59]).format('a'), 'du', 'pm');\n\n    assert.equal(moment([2011, 2, 23,  0,  0]).format('A'), 'DE', 'AM');\n    assert.equal(moment([2011, 2, 23, 11, 59]).format('A'), 'DE', 'AM');\n    assert.equal(moment([2011, 2, 23, 12,  0]).format('A'), 'DU', 'PM');\n    assert.equal(moment([2011, 2, 23, 23, 59]).format('A'), 'DU', 'PM');\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1.', '1.');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2.', '2.');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3.', '3.');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4.', '4.');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5.', '5.');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6.', '6.');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7.', '7.');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8.', '8.');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9.', '9.');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10.', '10.');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11.', '11.');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12.', '12.');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13.', '13.');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14.', '14.');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15.', '15.');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16.', '16.');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17.', '17.');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18.', '18.');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19.', '19.');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20.', '20.');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21.', '21.');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22.', '22.');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23.', '23.');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24.', '24.');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25.', '25.');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26.', '26.');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27.', '27.');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28.', '28.');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29.', '29.');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30.', '30.');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31.', '31.');\n});\n\ntest('format month', function (assert) {\n    var expected = 'január jan_február feb_március márc_április ápr_május máj_június jún_július júl_augusztus aug_szeptember szept_október okt_november nov_december dec'.split('_'),\n        i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'vasárnap vas_hétfő hét_kedd kedd_szerda sze_csütörtök csüt_péntek pén_szombat szo'.split('_'),\n        i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'néhány másodperc', '44 másodperc = néhány másodperc');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'egy perc',         '45 másodperc = egy perc');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'egy perc',         '89 másodperc = egy perc');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 perc',           '90 másodperc = 2 perc');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 perc',          '44 perc = 44 perc');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'egy óra',          '45 perc = egy óra');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'egy óra',          '89 perc = egy óra');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 óra',            '90 perc = 2 óra');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 óra',            '5 óra = 5 óra');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 óra',           '21 óra = 21 óra');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'egy nap',          '22 óra = egy nap');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'egy nap',          '35 óra = egy nap');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 nap',            '36 óra = 2 nap');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'egy nap',          '1 nap = egy nap');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 nap',            '5 nap = 5 nap');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 nap',           '25 nap = 25 nap');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'egy hónap',        '26 nap = egy hónap');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'egy hónap',        '30 nap = egy hónap');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'egy hónap',        '45 nap = egy hónap');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 hónap',          '46 nap = 2 hónap');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 hónap',          '75 nap = 2 hónap');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 hónap',          '76 nap = 3 hónap');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'egy hónap',        '1 hónap = egy hónap');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 hónap',          '5 hónap = 5 hónap');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'egy év',           '345 nap = egy év');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 év',             '548 nap = 2 év');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'egy év',           '1 év = egy év');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 év',             '5 év = 5 év');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'néhány másodperc múlva',  'prefix');\n    assert.equal(moment(0).from(30000), 'néhány másodperce', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'néhány másodperce',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'néhány másodperc múlva', 'néhány másodperc múlva');\n    assert.equal(moment().add({d: 5}).fromNow(), '5 nap múlva', '5 nap múlva');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'ma 12:00-kor',     'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'ma 12:25-kor',     'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'ma 13:00-kor',     'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'holnap 12:00-kor', 'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'ma 11:00-kor',     'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'tegnap 12:00-kor', 'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m, days = 'vasárnap_hétfőn_kedden_szerdán_csütörtökön_pénteken_szombaton'.split('_');\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('[' + days[m.day()] + '] LT[-kor]'),  'today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[' + days[m.day()] + '] LT[-kor]'),  'today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[' + days[m.day()] + '] LT[-kor]'),  'today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m, days = 'vasárnap_hétfőn_kedden_szerdán_csütörtökön_pénteken_szombaton'.split('_');\n\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('[múlt ' + days[m.day()] + '] LT[-kor]'),  'today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[múlt ' + days[m.day()] + '] LT[-kor]'),  'today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[múlt ' + days[m.day()] + '] LT[-kor]'),  'today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  'egy héte');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'egy hét múlva');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 hete');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  '2 hét múlva');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2011, 11, 26]).format('w ww wo'), '52 52 52.', 'Dec 26 2011 should be week 52');\n    assert.equal(moment([2012,  0,  1]).format('w ww wo'), '52 52 52.', 'Jan  1 2012 should be week 52');\n    assert.equal(moment([2012,  0,  2]).format('w ww wo'), '1 01 1.', 'Jan  2 2012 should be week 1');\n    assert.equal(moment([2012,  0,  8]).format('w ww wo'), '1 01 1.', 'Jan  8 2012 should be week 1');\n    assert.equal(moment([2012,  0,  9]).format('w ww wo'), '2 02 2.', 'Jan  9 2012 should be week 2');\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\n\n\nfunction localeModule (name, lifecycle) {\n    QUnit.module('locale:' + name, {\n        setup : function () {\n            moment.locale(name);\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            moment.locale('en');\n            teardownDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n    defineCommonLocaleTests(name, -1, -1);\n}\n\nlocaleModule('hy-am');\n\ntest('parse', function (assert) {\n    var tests = 'հունվար հնվ_փետրվար փտր_մարտ մրտ_ապրիլ ապր_մայիս մյս_հունիս հնս_հուլիս հլս_օգոստոս օգս_սեպտեմբեր սպտ_հոկտեմբեր հկտ_նոյեմբեր նմբ_դեկտեմբեր դկտ'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('parse exceptional case', function (assert) {\n    assert.equal(moment('11 մայիսի 1989', ['DD MMMM YYYY']).format('DD-MM-YYYY'), '11-05-1989');\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, Do MMMM YYYY, HH:mm:ss',       'կիրակի, 14 փետրվարի 2010, 15:25:50'],\n            ['ddd, h A',                           'կրկ, 3 ցերեկվա'],\n            ['M Mo MM MMMM MMM',                   '2 2 02 փետրվար փտր'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14 14'],\n            ['d do dddd ddd dd',                   '0 0 կիրակի կրկ կրկ'],\n            ['DDD DDDo DDDD',                      '45 45-րդ 045'],\n            ['w wo ww',                            '7 7-րդ 07'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'ցերեկվա ցերեկվա'],\n            ['[տարվա] DDDo [օրը]',                 'տարվա 45-րդ օրը'],\n            ['LTS',                                '15:25:50'],\n            ['L',                                  '14.02.2010'],\n            ['LL',                                 '14 փետրվարի 2010 թ.'],\n            ['LLL',                                '14 փետրվարի 2010 թ., 15:25'],\n            ['LLLL',                               'կիրակի, 14 փետրվարի 2010 թ., 15:25'],\n            ['l',                                  '14.2.2010'],\n            ['ll',                                 '14 փտր 2010 թ.'],\n            ['lll',                                '14 փտր 2010 թ., 15:25'],\n            ['llll',                               'կրկ, 14 փտր 2010 թ., 15:25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format meridiem', function (assert) {\n    assert.equal(moment([2012, 11, 28, 0, 0]).format('A'), 'գիշերվա', 'night');\n    assert.equal(moment([2012, 11, 28, 3, 59]).format('A'), 'գիշերվա', 'night');\n    assert.equal(moment([2012, 11, 28, 4, 0]).format('A'), 'առավոտվա', 'morning');\n    assert.equal(moment([2012, 11, 28, 11, 59]).format('A'), 'առավոտվա', 'morning');\n    assert.equal(moment([2012, 11, 28, 12, 0]).format('A'), 'ցերեկվա', 'afternoon');\n    assert.equal(moment([2012, 11, 28, 16, 59]).format('A'), 'ցերեկվա', 'afternoon');\n    assert.equal(moment([2012, 11, 28, 17, 0]).format('A'), 'երեկոյան', 'evening');\n    assert.equal(moment([2012, 11, 28, 23, 59]).format('A'), 'երեկոյան', 'evening');\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1-ին', '1-ին');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2-րդ', '2-րդ');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3-րդ', '3-րդ');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4-րդ', '4-րդ');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5-րդ', '5-րդ');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6-րդ', '6-րդ');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7-րդ', '7-րդ');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8-րդ', '8-րդ');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9-րդ', '9-րդ');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10-րդ', '10-րդ');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11-րդ', '11-րդ');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12-րդ', '12-րդ');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13-րդ', '13-րդ');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14-րդ', '14-րդ');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15-րդ', '15-րդ');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16-րդ', '16-րդ');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17-րդ', '17-րդ');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18-րդ', '18-րդ');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19-րդ', '19-րդ');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20-րդ', '20-րդ');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21-րդ', '21-րդ');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22-րդ', '22-րդ');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23-րդ', '23-րդ');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24-րդ', '24-րդ');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25-րդ', '25-րդ');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26-րդ', '26-րդ');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27-րդ', '27-րդ');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28-րդ', '28-րդ');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29-րդ', '29-րդ');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30-րդ', '30-րդ');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31-րդ', '31-րդ');\n});\n\ntest('format month', function (assert) {\n    var expected = 'հունվար հնվ_փետրվար փտր_մարտ մրտ_ապրիլ ապր_մայիս մյս_հունիս հնս_հուլիս հլս_օգոստոս օգս_սեպտեմբեր սպտ_հոկտեմբեր հկտ_նոյեմբեր նմբ_դեկտեմբեր դկտ'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format month case', function (assert) {\n    var months = {\n        'nominative': 'հունվար_փետրվար_մարտ_ապրիլ_մայիս_հունիս_հուլիս_օգոստոս_սեպտեմբեր_հոկտեմբեր_նոյեմբեր_դեկտեմբեր'.split('_'),\n        'accusative': 'հունվարի_փետրվարի_մարտի_ապրիլի_մայիսի_հունիսի_հուլիսի_օգոստոսի_սեպտեմբերի_հոկտեմբերի_նոյեմբերի_դեկտեմբերի'.split('_')\n    }, i;\n    for (i = 0; i < 12; i++) {\n        assert.equal(moment([2011, i, 1]).format('D MMMM'), '1 ' + months.accusative[i], '1 ' + months.accusative[i]);\n        assert.equal(moment([2011, i, 1]).format('MMMM'), months.nominative[i], '1 ' + months.nominative[i]);\n    }\n});\n\ntest('format month short case', function (assert) {\n    var monthsShort = {\n        'nominative': 'հնվ_փտր_մրտ_ապր_մյս_հնս_հլս_օգս_սպտ_հկտ_նմբ_դկտ'.split('_'),\n        'accusative': 'հնվ_փտր_մրտ_ապր_մյս_հնս_հլս_օգս_սպտ_հկտ_նմբ_դկտ'.split('_')\n    }, i;\n    for (i = 0; i < 12; i++) {\n        assert.equal(moment([2011, i, 1]).format('D MMM'), '1 ' + monthsShort.accusative[i], '1 ' + monthsShort.accusative[i]);\n        assert.equal(moment([2011, i, 1]).format('MMM'), monthsShort.nominative[i], '1 ' + monthsShort.nominative[i]);\n    }\n});\n\ntest('format month case with escaped symbols', function (assert) {\n    var months = {\n        'nominative': 'հունվար_փետրվար_մարտ_ապրիլ_մայիս_հունիս_հուլիս_օգոստոս_սեպտեմբեր_հոկտեմբեր_նոյեմբեր_դեկտեմբեր'.split('_'),\n        'accusative': 'հունվարի_փետրվարի_մարտի_ապրիլի_մայիսի_հունիսի_հուլիսի_օգոստոսի_սեպտեմբերի_հոկտեմբերի_նոյեմբերի_դեկտեմբերի'.split('_')\n    }, i;\n    for (i = 0; i < 12; i++) {\n        assert.equal(moment([2013, i, 1]).format('D[] MMMM'), '1 ' + months.accusative[i], '1 ' + months.accusative[i]);\n        assert.equal(moment([2013, i, 1]).format('[<i>]D[</i>] [<b>]MMMM[</b>]'), '<i>1</i> <b>' + months.accusative[i] + '</b>', '1 <b>' + months.accusative[i] + '</b>');\n        assert.equal(moment([2013, i, 1]).format('D[-ին օրը] MMMM'), '1-ին օրը ' + months.accusative[i], '1-ին օրը ' + months.accusative[i]);\n        assert.equal(moment([2013, i, 1]).format('D, MMMM'), '1, ' + months.nominative[i], '1, ' + months.nominative[i]);\n    }\n});\n\ntest('format month short case with escaped symbols', function (assert) {\n    var monthsShort = {\n        'nominative': 'հնվ_փտր_մրտ_ապր_մյս_հնս_հլս_օգս_սպտ_հկտ_նմբ_դկտ'.split('_'),\n        'accusative': 'հնվ_փտր_մրտ_ապր_մյս_հնս_հլս_օգս_սպտ_հկտ_նմբ_դկտ'.split('_')\n    }, i;\n    for (i = 0; i < 12; i++) {\n        assert.equal(moment([2013, i, 1]).format('D[] MMM'), '1 ' + monthsShort.accusative[i], '1 ' + monthsShort.accusative[i]);\n        assert.equal(moment([2013, i, 1]).format('[<i>]D[</i>] [<b>]MMM[</b>]'), '<i>1</i> <b>' + monthsShort.accusative[i] + '</b>', '1 <b>' + monthsShort.accusative[i] + '</b>');\n        assert.equal(moment([2013, i, 1]).format('D[-ին օրը] MMM'), '1-ին օրը ' + monthsShort.accusative[i], '1-ին օրը ' + monthsShort.accusative[i]);\n        assert.equal(moment([2013, i, 1]).format('D, MMM'), '1, ' + monthsShort.nominative[i], '1, ' + monthsShort.nominative[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'կիրակի կրկ կրկ_երկուշաբթի երկ երկ_երեքշաբթի երք երք_չորեքշաբթի չրք չրք_հինգշաբթի հնգ հնգ_ուրբաթ ուրբ ուրբ_շաբաթ շբթ շբթ'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'մի քանի վայրկյան',    '44 seconds = seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'րոպե',   '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'րոպե',   '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 րոպե',  '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 րոպե', '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'ժամ',    '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'ժամ',    '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 ժամ',    '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 ժամ',    '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 ժամ',   '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'օր',      '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'օր',      '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 օր',     '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'օր',      '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 օր',     '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 11}), true),  '11 օր',     '11 days = 11 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 21}), true),  '21 օր',     '21 days = 21 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 օր',    '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'ամիս',    '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'ամիս',    '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'ամիս',    '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 ամիս',   '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 ամիս',   '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 ամիս',   '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'ամիս',    '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 ամիս',   '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'տարի',     '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 տարի',    '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'տարի',     '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 տարի',    '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'մի քանի վայրկյան հետո', 'prefix');\n    assert.equal(moment(0).from(30000), 'մի քանի վայրկյան առաջ', 'suffix');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'մի քանի վայրկյան հետո', 'in seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), '5 օր հետո', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'այսօր 12:00',   'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'այսօր 12:25',   'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'այսօր 13:00',   'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'վաղը 12:00',    'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'այսօր 11:00',   'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'երեկ 12:00',    'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    function makeFormat(d) {\n        return 'dddd [օրը ժամը] LT';\n    }\n\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format(makeFormat(m)),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format(makeFormat(m)),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format(makeFormat(m)),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n\n    function makeFormat(d) {\n        return '[անցած] dddd [օրը ժամը] LT';\n    }\n\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format(makeFormat(m)),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format(makeFormat(m)),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format(makeFormat(m)),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2011, 11, 26]).format('w ww wo'), '1 01 1-ին', 'Dec 26 2011 should be week 1');\n    assert.equal(moment([2012,  0,  1]).format('w ww wo'), '1 01 1-ին', 'Jan  1 2012 should be week 1');\n    assert.equal(moment([2012,  0,  2]).format('w ww wo'), '2 02 2-րդ', 'Jan  2 2012 should be week 2');\n    assert.equal(moment([2012,  0,  8]).format('w ww wo'), '2 02 2-րդ', 'Jan  8 2012 should be week 2');\n    assert.equal(moment([2012,  0,  9]).format('w ww wo'), '3 03 3-րդ', 'Jan  9 2012 should be week 3');\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\n\n\nfunction localeModule (name, lifecycle) {\n    QUnit.module('locale:' + name, {\n        setup : function () {\n            moment.locale(name);\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            moment.locale('en');\n            teardownDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n    defineCommonLocaleTests(name, -1, -1);\n}\n\nlocaleModule('id');\n\ntest('parse', function (assert) {\n    var tests = 'Januari Jan_Februari Feb_Maret Mar_April Apr_Mei Mei_Juni Jun_Juli Jul_Agustus Ags_September Sep_Oktober Okt_November Nov_Desember Des'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, MMMM Do YYYY, h:mm:ss a',      'Minggu, Februari 14 2010, 3:25:50 sore'],\n            ['ddd, hA',                            'Min, 3sore'],\n            ['M Mo MM MMMM MMM',                   '2 2 02 Februari Feb'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14 14'],\n            ['d do dddd ddd dd',                   '0 0 Minggu Min Mg'],\n            ['DDD DDDo DDDD',                      '45 45 045'],\n            ['w wo ww',                            '7 7 07'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'sore sore'],\n            ['[the] DDDo [day of the year]',       'the 45 day of the year'],\n            ['LTS',                                '15.25.50'],\n            ['L',                                  '14/02/2010'],\n            ['LL',                                 '14 Februari 2010'],\n            ['LLL',                                '14 Februari 2010 pukul 15.25'],\n            ['LLLL',                               'Minggu, 14 Februari 2010 pukul 15.25'],\n            ['l',                                  '14/2/2010'],\n            ['ll',                                 '14 Feb 2010'],\n            ['lll',                                '14 Feb 2010 pukul 15.25'],\n            ['llll',                               'Min, 14 Feb 2010 pukul 15.25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format month', function (assert) {\n    var expected = 'Januari Jan_Februari Feb_Maret Mar_April Apr_Mei Mei_Juni Jun_Juli Jul_Agustus Ags_September Sep_Oktober Okt_November Nov_Desember Des'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'Minggu Min Mg_Senin Sen Sn_Selasa Sel Sl_Rabu Rab Rb_Kamis Kam Km_Jumat Jum Jm_Sabtu Sab Sb'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'beberapa detik', '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'semenit',      '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'semenit',      '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 menit',     '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 menit',    '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'sejam',       '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'sejam',       '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 jam',       '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 jam',       '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 jam',      '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'sehari',         '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'sehari',         '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 hari',        '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'sehari',         '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 hari',        '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 hari',       '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'sebulan',       '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'sebulan',       '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'sebulan',       '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 bulan',      '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 bulan',      '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 bulan',      '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'sebulan',       '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 bulan',      '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'setahun',        '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 tahun',       '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'setahun',        '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 tahun',       '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'dalam beberapa detik',  'prefix');\n    assert.equal(moment(0).from(30000), 'beberapa detik yang lalu', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'beberapa detik yang lalu',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'dalam beberapa detik', 'in a few seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), 'dalam 5 hari', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'Hari ini pukul 12.00', 'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'Hari ini pukul 12.25', 'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'Hari ini pukul 13.00', 'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'Besok pukul 12.00',    'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'Hari ini pukul 11.00', 'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'Kemarin pukul 12.00',  'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('dddd [pukul] LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd [pukul] LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd [pukul] LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('dddd [lalu pukul] LT'),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd [lalu pukul] LT'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd [lalu pukul] LT'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2011, 11, 26]).format('w ww wo'), '1 01 1', 'Dec 26 2011 should be week 1');\n    assert.equal(moment([2012,  0,  1]).format('w ww wo'), '1 01 1', 'Jan  1 2012 should be week 1');\n    assert.equal(moment([2012,  0,  2]).format('w ww wo'), '2 02 2', 'Jan  2 2012 should be week 2');\n    assert.equal(moment([2012,  0,  8]).format('w ww wo'), '2 02 2', 'Jan  8 2012 should be week 2');\n    assert.equal(moment([2012,  0,  9]).format('w ww wo'), '3 03 3', 'Jan  9 2012 should be week 3');\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\n\n\nfunction localeModule (name, lifecycle) {\n    QUnit.module('locale:' + name, {\n        setup : function () {\n            moment.locale(name);\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            moment.locale('en');\n            teardownDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n    defineCommonLocaleTests(name, -1, -1);\n}\n\nlocaleModule('is');\n\ntest('parse', function (assert) {\n    var tests = 'janúar jan_febrúar feb_mars mar_apríl apr_maí maí_júní jún_júlí júl_ágúst ágú_september sep_október okt_nóvember nóv_desember des'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, Do MMMM YYYY, h:mm:ss a',      'sunnudagur, 14. febrúar 2010, 3:25:50 pm'],\n            ['ddd, hA',                            'sun, 3PM'],\n            ['M Mo MM MMMM MMM',                   '2 2. 02 febrúar feb'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14. 14'],\n            ['d do dddd ddd dd',                   '0 0. sunnudagur sun Su'],\n            ['DDD DDDo DDDD',                      '45 45. 045'],\n            ['w wo ww',                            '6 6. 06'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'pm PM'],\n            ['[the] DDDo [day of the year]',       'the 45. day of the year'],\n            ['LTS',                                '15:25:50'],\n            ['L',                                  '14.02.2010'],\n            ['LL',                                 '14. febrúar 2010'],\n            ['LLL',                                '14. febrúar 2010 kl. 15:25'],\n            ['LLLL',                               'sunnudagur, 14. febrúar 2010 kl. 15:25'],\n            ['l',                                  '14.2.2010'],\n            ['ll',                                 '14. feb 2010'],\n            ['lll',                                '14. feb 2010 kl. 15:25'],\n            ['llll',                               'sun, 14. feb 2010 kl. 15:25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1.', '1.');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2.', '2.');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3.', '3.');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4.', '4.');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5.', '5.');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6.', '6.');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7.', '7.');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8.', '8.');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9.', '9.');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10.', '10.');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11.', '11.');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12.', '12.');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13.', '13.');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14.', '14.');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15.', '15.');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16.', '16.');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17.', '17.');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18.', '18.');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19.', '19.');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20.', '20.');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21.', '21.');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22.', '22.');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23.', '23.');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24.', '24.');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25.', '25.');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26.', '26.');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27.', '27.');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28.', '28.');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29.', '29.');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30.', '30.');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31.', '31.');\n});\n\ntest('format month', function (assert) {\n    var expected = 'janúar jan_febrúar feb_mars mar_apríl apr_maí maí_júní jún_júlí júl_ágúst ágú_september sep_október okt_nóvember nóv_desember des'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'sunnudagur sun Su_mánudagur mán Má_þriðjudagur þri Þr_miðvikudagur mið Mi_fimmtudagur fim Fi_föstudagur fös Fö_laugardagur lau La'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'nokkrar sekúndur', '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'mínúta',      '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'mínúta',      '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 mínútur',     '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 mínútur',    '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 21}), true),  '21 mínúta',    '21 minutes = 21 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'klukkustund',       '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'klukkustund',       '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 klukkustundir',       '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 klukkustundir',       '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 klukkustund',      '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'dagur',         '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'dagur',         '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 dagar',        '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'dagur',         '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 dagar',        '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 dagar',       '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 11}), true),  '11 dagar',       '11 days = 11 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 21}), true),  '21 dagur',       '21 days = 21 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'mánuður',       '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'mánuður',       '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'mánuður',       '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 mánuðir',      '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 mánuðir',      '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 mánuðir',      '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'mánuður',       '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 mánuðir',      '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'ár',        '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 ár',       '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'ár',        '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 ár',       '5 years = 5 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 21}), true),  '21 ár',       '21 years = 21 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'eftir nokkrar sekúndur',  'prefix');\n    assert.equal(moment(0).from(30000), 'fyrir nokkrum sekúndum síðan', 'suffix');\n    assert.equal(moment().subtract({m: 1}).fromNow(), 'fyrir mínútu síðan', 'a minute ago');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'fyrir nokkrum sekúndum síðan',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'eftir nokkrar sekúndur', 'in a few seconds');\n    assert.equal(moment().add({m: 1}).fromNow(), 'eftir mínútu', 'in a minute');\n    assert.equal(moment().add({d: 5}).fromNow(), 'eftir 5 daga', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'í dag kl. 12:00',     'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'í dag kl. 12:25',     'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'í dag kl. 13:00',     'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'á morgun kl. 12:00',  'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'í dag kl. 11:00',     'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'í gær kl. 12:00',     'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('dddd [kl.] LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd [kl.] LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd [kl.] LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('[síðasta] dddd [kl.] LT'),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[síðasta] dddd [kl.] LT'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[síðasta] dddd [kl.] LT'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2012, 0,  1]).format('w ww wo'), '52 52 52.', 'Jan  1 2012 should be week 52');\n    assert.equal(moment([2012, 0,  2]).format('w ww wo'),  '1 01 1.', 'Jan  2 2012 should be week 1');\n    assert.equal(moment([2012, 0,  8]).format('w ww wo'),  '1 01 1.', 'Jan  8 2012 should be week 1');\n    assert.equal(moment([2012, 0,  9]).format('w ww wo'),  '2 02 2.', 'Jan  9 2012 should be week 2');\n    assert.equal(moment([2012, 0, 15]).format('w ww wo'),  '2 02 2.', 'Jan 15 2012 should be week 2');\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\n\n\nfunction localeModule (name, lifecycle) {\n    QUnit.module('locale:' + name, {\n        setup : function () {\n            moment.locale(name);\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            moment.locale('en');\n            teardownDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n    defineCommonLocaleTests(name, -1, -1);\n}\n\nlocaleModule('it');\n\ntest('parse', function (assert) {\n    var tests = 'gennaio gen_febbraio feb_marzo mar_aprile apr_maggio mag_giugno giu_luglio lug_agosto ago_settembre set_ottobre ott_novembre nov_dicembre dic'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, MMMM Do YYYY, h:mm:ss a',      'domenica, febbraio 14º 2010, 3:25:50 pm'],\n            ['ddd, hA',                            'dom, 3PM'],\n            ['M Mo MM MMMM MMM',                   '2 2º 02 febbraio feb'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14º 14'],\n            ['d do dddd ddd dd',                   '0 0º domenica dom do'],\n            ['DDD DDDo DDDD',                      '45 45º 045'],\n            ['w wo ww',                            '6 6º 06'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'pm PM'],\n            ['[the] DDDo [day of the year]',       'the 45º day of the year'],\n            ['LTS',                                '15:25:50'],\n            ['L',                                  '14/02/2010'],\n            ['LL',                                 '14 febbraio 2010'],\n            ['LLL',                                '14 febbraio 2010 15:25'],\n            ['LLLL',                               'domenica, 14 febbraio 2010 15:25'],\n            ['l',                                  '14/2/2010'],\n            ['ll',                                 '14 feb 2010'],\n            ['lll',                                '14 feb 2010 15:25'],\n            ['llll',                               'dom, 14 feb 2010 15:25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1º', '1º');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2º', '2º');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3º', '3º');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4º', '4º');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5º', '5º');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6º', '6º');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7º', '7º');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8º', '8º');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9º', '9º');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10º', '10º');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11º', '11º');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12º', '12º');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13º', '13º');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14º', '14º');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15º', '15º');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16º', '16º');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17º', '17º');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18º', '18º');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19º', '19º');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20º', '20º');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21º', '21º');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22º', '22º');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23º', '23º');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24º', '24º');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25º', '25º');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26º', '26º');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27º', '27º');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28º', '28º');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29º', '29º');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30º', '30º');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31º', '31º');\n});\n\ntest('format month', function (assert) {\n    var expected = 'gennaio gen_febbraio feb_marzo mar_aprile apr_maggio mag_giugno giu_luglio lug_agosto ago_settembre set_ottobre ott_novembre nov_dicembre dic'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'domenica dom do_lunedì lun lu_martedì mar ma_mercoledì mer me_giovedì gio gi_venerdì ven ve_sabato sab sa'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'alcuni secondi', '44 seconds = seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'un minuto',      '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'un minuto',      '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 minuti',       '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 minuti',      '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'un\\'ora',        '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'un\\'ora',        '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 ore',          '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 ore',          '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 ore',         '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'un giorno',      '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'un giorno',      '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 giorni',       '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'un giorno',      '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 giorni',       '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 giorni',      '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'un mese',        '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'un mese',        '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'un mese',        '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 mesi',         '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 mesi',         '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 mesi',         '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'un mese',        '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 mesi',         '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'un anno',        '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 anni',         '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'un anno',        '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 anni',         '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'in alcuni secondi', 'prefix');\n    assert.equal(moment(0).from(30000), 'alcuni secondi fa', 'suffix');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'in alcuni secondi', 'in seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), 'tra 5 giorni', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'Oggi alle 12:00',     'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'Oggi alle 12:25',     'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'Oggi alle 13:00',     'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'Domani alle 12:00',   'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'Oggi alle 11:00',     'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'Ieri alle 12:00',     'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('dddd [alle] LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd [alle] LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd [alle] LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m, weekday, datestring;\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        // Different date string\n        weekday = parseInt(m.format('d'), 10);\n        datestring = (weekday === 0) ? '[la scorsa] dddd [alle] LT' : '[lo scorso] dddd [alle] LT';\n        assert.equal(m.calendar(), m.format(datestring), 'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(), m.format(datestring), 'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(), m.format(datestring), 'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2012, 0,  1]).format('w ww wo'), '52 52 52º', 'Jan  1 2012 should be week 52');\n    assert.equal(moment([2012, 0,  2]).format('w ww wo'),  '1 01 1º', 'Jan  2 2012 should be week 1');\n    assert.equal(moment([2012, 0,  8]).format('w ww wo'),  '1 01 1º', 'Jan  8 2012 should be week 1');\n    assert.equal(moment([2012, 0,  9]).format('w ww wo'),  '2 02 2º', 'Jan  9 2012 should be week 2');\n    assert.equal(moment([2012, 0, 15]).format('w ww wo'),  '2 02 2º', 'Jan 15 2012 should be week 2');\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\n\n\nfunction localeModule (name, lifecycle) {\n    QUnit.module('locale:' + name, {\n        setup : function () {\n            moment.locale(name);\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            moment.locale('en');\n            teardownDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n    defineCommonLocaleTests(name, -1, -1);\n}\n\nlocaleModule('ja');\n\ntest('parse', function (assert) {\n    var tests = '1月 1月_2月 2月_3月 3月_4月 4月_5月 5月_6月 6月_7月 7月_8月 8月_9月 9月_10月 10月_11月 11月_12月 12月'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, MMMM Do YYYY, a h:mm:ss',      '日曜日, 2月 14日 2010, 午後 3:25:50'],\n            ['ddd, Ah',                            '日, 午後3'],\n            ['M Mo MM MMMM MMM',                   '2 2 02 2月 2月'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14日 14'],\n            ['d do dddd ddd dd',                   '0 0日 日曜日 日 日'],\n            ['DDD DDDo DDDD',                      '45 45日 045'],\n            ['w wo ww',                            '8 8 08'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                '午後 午後'],\n            ['[the] DDDo [day of the year]',       'the 45日 day of the year'],\n            ['LTS',                                '15:25:50'],\n            ['L',                                  '2010/02/14'],\n            ['LL',                                 '2010年2月14日'],\n            ['LLL',                                '2010年2月14日 15:25'],\n            ['LLLL',                               '2010年2月14日 15:25 日曜日'],\n            ['l',                                  '2010/02/14'],\n            ['ll',                                 '2010年2月14日'],\n            ['lll',                                '2010年2月14日 15:25'],\n            ['llll',                               '2010年2月14日 15:25 日曜日']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format month', function (assert) {\n    var expected = '1月 1月_2月 2月_3月 3月_4月 4月_5月 5月_6月 6月_7月 7月_8月 8月_9月 9月_10月 10月_11月 11月_12月 12月'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = '日曜日 日 日_月曜日 月 月_火曜日 火 火_水曜日 水 水_木曜日 木 木_金曜日 金 金_土曜日 土 土'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  '数秒',   '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  '1分', '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  '1分', '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2分',  '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44分', '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  '1時間', '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  '1時間', '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2時間',  '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5時間',  '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21時間', '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  '1日',   '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  '1日',   '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2日',   '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   '1日',   '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5日',   '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25日',  '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  '1ヶ月', '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  '1ヶ月', '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  '1ヶ月', '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2ヶ月',  '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2ヶ月',  '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3ヶ月',  '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   '1ヶ月', '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5ヶ月',  '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), '1年',   '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2年',   '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   '1年',   '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5年',   '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), '数秒後',  'prefix');\n    assert.equal(moment(0).from(30000), '数秒前', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), '数秒前',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), '数秒後', 'in a few seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), '5日後', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   '今日 12:00', 'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      '今日 12:25', 'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       '今日 13:00', 'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       '明日 12:00', 'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  '今日 11:00', 'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  '昨日 12:00', 'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('[来週]dddd LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[来週]dddd LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[来週]dddd LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('[前週]dddd LT'),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[前週]dddd LT'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[前週]dddd LT'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),      '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),      '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('weeks year starting sunday format', function (assert) {\n    assert.equal(moment([2012, 0,  1]).format('w ww wo'), '1 01 1', 'Jan  1 2012 should be week 1');\n    assert.equal(moment([2012, 0,  7]).format('w ww wo'), '1 01 1', 'Jan  7 2012 should be week 1');\n    assert.equal(moment([2012, 0,  8]).format('w ww wo'), '2 02 2', 'Jan  8 2012 should be week 2');\n    assert.equal(moment([2012, 0, 14]).format('w ww wo'), '2 02 2', 'Jan 14 2012 should be week 2');\n    assert.equal(moment([2012, 0, 15]).format('w ww wo'), '3 03 3', 'Jan 15 2012 should be week 3');\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\n\n\nfunction localeModule (name, lifecycle) {\n    QUnit.module('locale:' + name, {\n        setup : function () {\n            moment.locale(name);\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            moment.locale('en');\n            teardownDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n    defineCommonLocaleTests(name, -1, -1);\n}\n\nlocaleModule('jv');\n\ntest('parse', function (assert) {\n    var tests = 'Januari Jan_Februari Feb_Maret Mar_April Apr_Mei Mei_Juni Jun_Juli Jul_Agustus Ags_September Sep_Oktober Okt_Nopember Nop_Desember Des'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, MMMM Do YYYY, h:mm:ss a',      'Minggu, Februari 14 2010, 3:25:50 sonten'],\n            ['ddd, hA',                            'Min, 3sonten'],\n            ['M Mo MM MMMM MMM',                   '2 2 02 Februari Feb'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14 14'],\n            ['d do dddd ddd dd',                   '0 0 Minggu Min Mg'],\n            ['DDD DDDo DDDD',                      '45 45 045'],\n            ['w wo ww',                            '7 7 07'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'sonten sonten'],\n            ['[the] DDDo [day of the year]',       'the 45 day of the year'],\n            ['LTS',                                '15.25.50'],\n            ['L',                                  '14/02/2010'],\n            ['LL',                                 '14 Februari 2010'],\n            ['LLL',                                '14 Februari 2010 pukul 15.25'],\n            ['LLLL',                               'Minggu, 14 Februari 2010 pukul 15.25'],\n            ['l',                                  '14/2/2010'],\n            ['ll',                                 '14 Feb 2010'],\n            ['lll',                                '14 Feb 2010 pukul 15.25'],\n            ['llll',                               'Min, 14 Feb 2010 pukul 15.25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format month', function (assert) {\n    var expected = 'Januari Jan_Februari Feb_Maret Mar_April Apr_Mei Mei_Juni Jun_Juli Jul_Agustus Ags_September Sep_Oktober Okt_Nopember Nop_Desember Des'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'Minggu Min Mg_Senen Sen Sn_Seloso Sel Sl_Rebu Reb Rb_Kemis Kem Km_Jemuwah Jem Jm_Septu Sep Sp'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'sawetawis detik', '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'setunggal menit',      '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'setunggal menit',      '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 menit',     '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 menit',    '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'setunggal jam',       '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'setunggal jam',       '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 jam',       '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 jam',       '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 jam',      '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'sedinten',         '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'sedinten',         '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 dinten',        '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'sedinten',         '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 dinten',        '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 dinten',       '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'sewulan',       '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'sewulan',       '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'sewulan',       '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 wulan',      '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 wulan',      '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 wulan',      '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'sewulan',       '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 wulan',      '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'setaun',        '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 taun',       '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'setaun',        '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 taun',       '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'wonten ing sawetawis detik',  'prefix');\n    assert.equal(moment(0).from(30000), 'sawetawis detik ingkang kepengker', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'sawetawis detik ingkang kepengker',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'wonten ing sawetawis detik', 'in a few seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), 'wonten ing 5 dinten', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'Dinten puniko pukul 12.00', 'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'Dinten puniko pukul 12.25', 'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'Dinten puniko pukul 13.00', 'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'Mbenjang pukul 12.00',      'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'Dinten puniko pukul 11.00', 'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'Kala wingi pukul 12.00',    'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('dddd [pukul] LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd [pukul] LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd [pukul] LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('dddd [kepengker pukul] LT'),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd [kepengker pukul] LT'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd [kepengker pukul] LT'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\n// Monday is the first day of the week.\n// The week that contains Jan 1st is the first week of the year.\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2011, 11, 26]).format('w ww wo'), '1 01 1', 'Dec 26 2011 should be week 1');\n    assert.equal(moment([2012,  0,  1]).format('w ww wo'), '1 01 1', 'Jan  1 2012 should be week 1');\n    assert.equal(moment([2012,  0,  2]).format('w ww wo'), '2 02 2', 'Jan  2 2012 should be week 2');\n    assert.equal(moment([2012,  0,  8]).format('w ww wo'), '2 02 2', 'Jan  8 2012 should be week 2');\n    assert.equal(moment([2012,  0,  9]).format('w ww wo'), '3 03 3', 'Jan  9 2012 should be week 3');\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\n\n\nfunction localeModule (name, lifecycle) {\n    QUnit.module('locale:' + name, {\n        setup : function () {\n            moment.locale(name);\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            moment.locale('en');\n            teardownDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n    defineCommonLocaleTests(name, -1, -1);\n}\n\nlocaleModule('ka');\n\ntest('parse', function (assert) {\n    var i,\n        tests = 'იანვარი იან_თებერვალი თებ_მარტი მარ_აპრილი აპრ_მაისი მაი_ივნისი ივნ_ივლისი ივლ_აგვისტო აგვ_სექტემბერი სექ_ოქტომბერი ოქტ_ნოემბერი ნოე_დეკემბერი დეკ'.split('_');\n\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' უნდა იყოს თვე ' + (i + 1));\n    }\n\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, MMMM Do YYYY, h:mm:ss a', 'კვირა, თებერვალი მე-14 2010, 3:25:50 pm'],\n            ['ddd, hA',                       'კვი, 3PM'],\n            ['M Mo MM MMMM MMM',              '2 მე-2 02 თებერვალი თებ'],\n            ['YYYY YY',                       '2010 10'],\n            ['D Do DD',                       '14 მე-14 14'],\n            ['d do dddd ddd dd',              '0 0 კვირა კვი კვ'],\n            ['DDD DDDo DDDD',                 '45 45-ე 045'],\n            ['w wo ww',                       '7 მე-7 07'],\n            ['h hh',                          '3 03'],\n            ['H HH',                          '15 15'],\n            ['m mm',                          '25 25'],\n            ['s ss',                          '50 50'],\n            ['a A',                           'pm PM'],\n            ['წლის DDDo დღე',                 'წლის 45-ე დღე'],\n            ['LTS',                           '3:25:50 PM'],\n            ['L',                             '14/02/2010'],\n            ['LL',                            '14 თებერვალს 2010'],\n            ['LLL',                           '14 თებერვალს 2010 3:25 PM'],\n            ['LLLL',                          'კვირა, 14 თებერვალს 2010 3:25 PM'],\n            ['l',                             '14/2/2010'],\n            ['ll',                            '14 თებ 2010'],\n            ['lll',                           '14 თებ 2010 3:25 PM'],\n            ['llll',                          'კვი, 14 თებ 2010 3:25 PM']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'),  '1-ლი',  '1-ლი');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'),  'მე-2',  'მე-2');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'),  'მე-3',  'მე-3');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'),  'მე-4',  'მე-4');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'),  'მე-5',  'მე-5');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'),  'მე-6',  'მე-6');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'),  'მე-7',  'მე-7');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'),  'მე-8',  'მე-8');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'),  'მე-9',  'მე-9');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), 'მე-10', 'მე-10');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), 'მე-11', 'მე-11');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), 'მე-12', 'მე-12');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), 'მე-13', 'მე-13');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), 'მე-14', 'მე-14');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), 'მე-15', 'მე-15');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), 'მე-16', 'მე-16');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), 'მე-17', 'მე-17');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), 'მე-18', 'მე-18');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), 'მე-19', 'მე-19');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), 'მე-20', 'მე-20');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21-ე', '21-ე');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22-ე', '22-ე');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23-ე', '23-ე');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24-ე', '24-ე');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25-ე', '25-ე');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26-ე', '26-ე');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27-ე', '27-ე');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28-ე', '28-ე');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29-ე', '29-ე');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30-ე', '30-ე');\n\n    assert.equal(moment('2011 40', 'YYYY DDD').format('DDDo'),  'მე-40',  'მე-40');\n    assert.equal(moment('2011 50', 'YYYY DDD').format('DDDo'),  '50-ე',   '50-ე');\n    assert.equal(moment('2011 60', 'YYYY DDD').format('DDDo'),  'მე-60',  'მე-60');\n    assert.equal(moment('2011 100', 'YYYY DDD').format('DDDo'), 'მე-100', 'მე-100');\n    assert.equal(moment('2011 101', 'YYYY DDD').format('DDDo'), '101-ე',  '101-ე');\n});\n\ntest('format month', function (assert) {\n    var i,\n        expected = 'იანვარი იან_თებერვალი თებ_მარტი მარ_აპრილი აპრ_მაისი მაი_ივნისი ივნ_ივლისი ივლ_აგვისტო აგვ_სექტემბერი სექ_ოქტომბერი ოქტ_ნოემბერი ნოე_დეკემბერი დეკ'.split('_');\n\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var i,\n        expected = 'კვირა კვი კვ_ორშაბათი ორშ ორ_სამშაბათი სამ სა_ოთხშაბათი ოთხ ოთ_ხუთშაბათი ხუთ ხუ_პარასკევი პარ პა_შაბათი შაბ შა'.split('_');\n\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}),  true), 'რამდენიმე წამი', '44 წამი  = რამდენიმე წამი');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}),  true), 'წუთი',           '45 წამი  = წუთი');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}),  true), 'წუთი',           '89 წამი  = წუთი');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}),  true), '2 წუთი',         '90 წამი  = 2 წუთი');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}),  true), '44 წუთი',        '44 წამი  = 44 წუთი');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}),  true), 'საათი',          '45 წამი  = საათი');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}),  true), 'საათი',          '89 წამი  = საათი');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}),  true), '2 საათი',        '90 წამი  = 2 საათი');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}),   true), '5 საათი',        '5 საათი  = 5 საათი');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}),  true), '21 საათი',       '21 საათი = 21 საათი');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}),  true), 'დღე',            '22 საათი = დღე');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}),  true), 'დღე',            '35 საათი = დღე');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}),  true), '2 დღე',          '36 საათი = 2 დღე');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}),   true), 'დღე',            '1 დღე    = დღე');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}),   true), '5 დღე',          '5 დღე    = 5 დღე');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}),  true), '25 დღე',         '25 დღე   = 25 დღე');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}),  true), 'თვე',            '26 დღე   = თვე');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}),  true), 'თვე',            '30 დღე   = თვე');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}),  true), 'თვე',            '45 დღე   = თვე');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}),  true), '2 თვე',          '46 დღე   = 2 თვე');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}),  true), '2 თვე',          '75 დღე   = 2 თვე');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}),  true), '3 თვე',          '76 დღე   = 3 თვე');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}),   true), 'თვე',            '1 თვე    = თვე');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}),   true), '5 თვე',          '5 თვე    = 5 თვე');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'წელი',           '345 დღე  = წელი');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 წელი',         '548 დღე  = 2 წელი');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}),   true), 'წელი',           '1 წელი   = წელი');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}),   true), '5 წელი',         '5 წელი   = 5 წელი');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'რამდენიმე წამში',     'ში სუფიქსი');\n    assert.equal(moment(0).from(30000), 'რამდენიმე წამის უკან', 'უკან სუფიქსი');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'რამდენიმე წამის უკან', 'უნდა აჩვენოს როგორც წარსული');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'რამდენიმე წამში', 'რამდენიმე წამში');\n    assert.equal(moment().add({d: 5}).fromNow(), '5 დღეში', '5 დღეში');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'დღეს 12:00 PM-ზე',  'დღეს ამავე დროს');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'დღეს 12:25 PM-ზე',  'ახლანდელ დროს დამატებული 25 წუთი');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'დღეს 1:00 PM-ზე',   'ახლანდელ დროს დამატებული 1 საათი');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'ხვალ 12:00 PM-ზე',  'ხვალ ამავე დროს');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'დღეს 11:00 AM-ზე',  'ახლანდელ დროს გამოკლებული 1 საათი');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'გუშინ 12:00 PM-ზე', 'გუშინ ამავე დროს');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('[შემდეგ] dddd LT[-ზე]'),  'დღეს + ' + i + ' დღე ახლანდელ დროს');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[შემდეგ] dddd LT[-ზე]'),  'დღეს + ' + i + ' დღე დღის დასაწყისში');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[შემდეგ] dddd LT[-ზე]'),  'დღეს + ' + i + ' დღე დღის დასასრულს');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('[წინა] dddd LT[-ზე]'),  'დღეს - ' + i + ' დღე ახლანდელ დროს');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[წინა] dddd LT[-ზე]'),  'დღეს - ' + i + ' დღე დღის დასაწყისში');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[წინა] dddd LT[-ზე]'),  'დღეს - ' + i + ' დღე დღის დასასრულს');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 კვირის უკან');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  '1 კვირაში');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 კვირის წინ');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  '2 კვირაში');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2011, 11, 26]).format('w ww wo'), '1 01 1-ლი', 'დეკ 26 2011 უნდა იყოს კვირა 1');\n    assert.equal(moment([2012,  0,  1]).format('w ww wo'), '1 01 1-ლი', 'იან  1 2012 უნდა იყოს კვირა 1');\n    assert.equal(moment([2012,  0,  2]).format('w ww wo'), '2 02 მე-2', 'იან  2 2012 უნდა იყოს კვირა 2');\n    assert.equal(moment([2012,  0,  8]).format('w ww wo'), '2 02 მე-2', 'იან  8 2012 უნდა იყოს კვირა 2');\n    assert.equal(moment([2012,  0,  9]).format('w ww wo'), '3 03 მე-3', 'იან  9 2012 უნდა იყოს კვირა 3');\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\n\n\nfunction localeModule (name, lifecycle) {\n    QUnit.module('locale:' + name, {\n        setup : function () {\n            moment.locale(name);\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            moment.locale('en');\n            teardownDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n    defineCommonLocaleTests(name, -1, -1);\n}\n\nlocaleModule('kk');\n\ntest('parse', function (assert) {\n    var tests = 'қаңтар қаң_ақпан ақп_наурыз нау_сәуір сәу_мамыр мам_маусым мау_шілде шіл_тамыз там_қыркүйек қыр_қазан қаз_қараша қар_желтоқсан жел'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, Do MMMM YYYY, HH:mm:ss',       'жексенбі, 14-ші ақпан 2010, 15:25:50'],\n            ['ddd, hA',                            'жек, 3PM'],\n            ['M Mo MM MMMM MMM',                   '2 2-ші 02 ақпан ақп'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14-ші 14'],\n            ['d do dddd ddd dd',                   '0 0-ші жексенбі жек жк'],\n            ['DDD DDDo DDDD',                      '45 45-ші 045'],\n            ['w wo ww',                            '7 7-ші 07'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'pm PM'],\n            ['[жылдың] DDDo [күні]',               'жылдың 45-ші күні'],\n            ['LTS',                                '15:25:50'],\n            ['L',                                  '14.02.2010'],\n            ['LL',                                 '14 ақпан 2010'],\n            ['LLL',                                '14 ақпан 2010 15:25'],\n            ['LLLL',                               'жексенбі, 14 ақпан 2010 15:25'],\n            ['l',                                  '14.2.2010'],\n            ['ll',                                 '14 ақп 2010'],\n            ['lll',                                '14 ақп 2010 15:25'],\n            ['llll',                               'жек, 14 ақп 2010 15:25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1-ші', '1st');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2-ші', '2nd');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3-ші', '3rd');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4-ші', '4th');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5-ші', '5th');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6-шы', '6th');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7-ші', '7th');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8-ші', '8th');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9-шы', '9th');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10-шы', '10th');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11-ші', '11th');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12-ші', '12th');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13-ші', '13th');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14-ші', '14th');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15-ші', '15th');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16-шы', '16th');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17-ші', '17th');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18-ші', '18th');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19-шы', '19th');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20-шы', '20th');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21-ші', '21st');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22-ші', '22nd');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23-ші', '23rd');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24-ші', '24th');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25-ші', '25th');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26-шы', '26th');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27-ші', '27th');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28-ші', '28th');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29-шы', '29th');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30-шы', '30th');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31-ші', '31st');\n});\n\ntest('format month', function (assert) {\n    var expected = 'қаңтар қаң_ақпан ақп_наурыз нау_сәуір сәу_мамыр мам_маусым мау_шілде шіл_тамыз там_қыркүйек қыр_қазан қаз_қараша қар_желтоқсан жел'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'жексенбі жек жк_дүйсенбі дүй дй_сейсенбі сей сй_сәрсенбі сәр ср_бейсенбі бей бй_жұма жұм жм_сенбі сен сн'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'бірнеше секунд', '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'бір минут',      '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'бір минут',      '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 минут',     '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 минут',    '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'бір сағат',       '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'бір сағат',       '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 сағат',       '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 сағат',       '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 сағат',      '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'бір күн',         '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'бір күн',         '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 күн',        '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'бір күн',         '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 күн',        '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 күн',       '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'бір ай',       '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'бір ай',       '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'бір ай',       '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 ай',      '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 ай',      '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 ай',      '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'бір ай',       '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 ай',      '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'бір жыл',        '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 жыл',       '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'бір жыл',        '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 жыл',       '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'бірнеше секунд ішінде',  'prefix');\n    assert.equal(moment(0).from(30000), 'бірнеше секунд бұрын', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'бірнеше секунд бұрын',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'бірнеше секунд ішінде', 'in a few seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), '5 күн ішінде', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'Бүгін сағат 12:00',  'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'Бүгін сағат 12:25',  'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'Бүгін сағат 13:00',  'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'Ертең сағат 12:00',  'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'Бүгін сағат 11:00',  'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'Кеше сағат 12:00',   'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('dddd [сағат] LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd [сағат] LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd [сағат] LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('[Өткен аптаның] dddd [сағат] LT'),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[Өткен аптаның] dddd [сағат] LT'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[Өткен аптаның] dddd [сағат] LT'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2012, 0,  1]).format('w ww wo'),   '1 01 1-ші', 'Jan  1 2012 should be week 1');\n    assert.equal(moment([2012, 0,  2]).format('w ww wo'),   '2 02 2-ші', 'Jan  2 2012 should be week 2');\n    assert.equal(moment([2012, 0,  8]).format('w ww wo'),   '2 02 2-ші', 'Jan  8 2012 should be week 2');\n    assert.equal(moment([2012, 0,  9]).format('w ww wo'),   '3 03 3-ші', 'Jan  9 2012 should be week 3');\n    assert.equal(moment([2012, 0, 15]).format('w ww wo'),   '3 03 3-ші', 'Jan 15 2012 should be week 3');\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\n\n\nfunction localeModule (name, lifecycle) {\n    QUnit.module('locale:' + name, {\n        setup : function () {\n            moment.locale(name);\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            moment.locale('en');\n            teardownDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n    defineCommonLocaleTests(name, -1, -1);\n}\n\nlocaleModule('km');\n\ntest('parse', function (assert) {\n    var tests = 'មករា មករា_កុម្ភៈ កុម្ភៈ_មីនា មីនា_មេសា មេសា_ឧសភា ឧសភា_មិថុនា មិថុនា_កក្កដា កក្កដា_សីហា សីហា_កញ្ញា កញ្ញា_តុលា តុលា_វិច្ឆិកា វិច្ឆិកា_ធ្នូ ធ្នូ'.split('_'),\n        i;\n\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, MMMM Do YYYY, h:mm:ss a', 'អាទិត្យ, កុម្ភៈ 14 2010, 3:25:50 pm'],\n            ['ddd, hA', 'អាទិត្យ, 3PM'],\n            ['M Mo MM MMMM MMM', '2 2 02 កុម្ភៈ កុម្ភៈ'],\n            ['YYYY YY', '2010 10'],\n            ['D Do DD', '14 14 14'],\n            ['d do dddd ddd dd', '0 0 អាទិត្យ អាទិត្យ អាទិត្យ'],\n            ['DDD DDDo DDDD', '45 45 045'],\n            ['w wo ww', '6 6 06'],\n            ['h hh', '3 03'],\n            ['H HH', '15 15'],\n            ['m mm', '25 25'],\n            ['s ss', '50 50'],\n            ['a A', 'pm PM'],\n            ['[the] DDDo [day of the year]', 'the 45 day of the year'],\n            ['LTS', '15:25:50'],\n            ['L', '14/02/2010'],\n            ['LL', '14 កុម្ភៈ 2010'],\n            ['LLL', '14 កុម្ភៈ 2010 15:25'],\n            ['LLLL', 'អាទិត្យ, 14 កុម្ភៈ 2010 15:25'],\n            ['l', '14/2/2010'],\n            ['ll', '14 កុម្ភៈ 2010'],\n            ['lll', '14 កុម្ភៈ 2010 15:25'],\n            ['llll', 'អាទិត្យ, 14 កុម្ភៈ 2010 15:25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1', '1st');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2', '2nd');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3', '3rd');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4', '4th');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5', '5th');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6', '6th');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7', '7th');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8', '8th');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9', '9th');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10', '10th');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11', '11th');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12', '12th');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13', '13th');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14', '14th');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15', '15th');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16', '16th');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17', '17th');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18', '18th');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19', '19th');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20', '20th');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21', '21st');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22', '22nd');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23', '23rd');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24', '24th');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25', '25th');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26', '26th');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27', '27th');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28', '28th');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29', '29th');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30', '30th');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31', '31st');\n});\n\ntest('format month', function (assert) {\n    var expected = 'មករា មករា_កុម្ភៈ កុម្ភៈ_មីនា មីនា_មេសា មេសា_ឧសភា ឧសភា_មិថុនា មិថុនា_កក្កដា កក្កដា_សីហា សីហា_កញ្ញា កញ្ញា_តុលា តុលា_វិច្ឆិកា វិច្ឆិកា_ធ្នូ ធ្នូ'.split('_'),\n        i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'អាទិត្យ អាទិត្យ អាទិត្យ_ច័ន្ទ ច័ន្ទ ច័ន្ទ_អង្គារ អង្គារ អង្គារ_ពុធ ពុធ ពុធ_ព្រហស្បតិ៍ ព្រហស្បតិ៍ ព្រហស្បតិ៍_សុក្រ សុក្រ សុក្រ_សៅរ៍ សៅរ៍ សៅរ៍'.split('_'),\n        i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true), 'ប៉ុន្មានវិនាទី', '44 seconds = ប៉ុន្មានវិនាទី');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true), 'មួយនាទី', '45 seconds = មួយនាទី');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true), 'មួយនាទី', '89 seconds = មួយនាទី');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true), '2 នាទី', '90 seconds = 2 នាទី');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true), '44 នាទី', '44 minutes = 44 នាទី');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true), 'មួយម៉ោង', '45 minutes = មួយម៉ោង');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true), 'មួយម៉ោង', '89 minutes = មួយម៉ោង');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true), '2 ម៉ោង', '90 minutes = 2 ម៉ោង');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true), '5 ម៉ោង', '5 hours = 5 ម៉ោង');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true), '21 ម៉ោង', '21 hours = 21 ម៉ោង');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true), 'មួយថ្ងៃ', '22 hours = មួយថ្ងៃ');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true), 'មួយថ្ងៃ', '35 hours = មួយថ្ងៃ');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true), '2 ថ្ងៃ', '36 hours = 2 ថ្ងៃ');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true), 'មួយថ្ងៃ', '1 day = មួយថ្ងៃ');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true), '5 ថ្ងៃ', '5 days = 5 ថ្ងៃ');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true), '25 ថ្ងៃ', '25 days = 25 ថ្ងៃ');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true), 'មួយខែ', '26 days = មួយខែ');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true), 'មួយខែ', '30 days = មួយខែ');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true), 'មួយខែ', '43 days = មួយខែ');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true), '2 ខែ', '46 days = 2 ខែ');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true), '2 ខែ', '75 days = 2 ខែ');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true), '3 ខែ', '76 days = 3 ខែ');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true), 'មួយខែ', '1 month = មួយខែ');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true), '5 ខែ', '5 months = 5 ខែ');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'មួយឆ្នាំ', '345 days = មួយឆ្នាំ');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 ឆ្នាំ', '548 days = 2 ឆ្នាំ');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true), 'មួយឆ្នាំ', '1 year = មួយឆ្នាំ');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true), '5 ឆ្នាំ', '5 years = 5 ឆ្នាំ');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'ប៉ុន្មានវិនាទីទៀត', 'prefix');\n    assert.equal(moment(0).from(30000), 'ប៉ុន្មានវិនាទីមុន', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'ប៉ុន្មានវិនាទីមុន', 'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({\n        s: 30\n    }).fromNow(), 'ប៉ុន្មានវិនាទីទៀត', 'in a few seconds');\n    assert.equal(moment().add({\n        d: 5\n    }).fromNow(), '5 ថ្ងៃទៀត', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                  'ថ្ងៃនេះ ម៉ោង 12:00',  'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),     'ថ្ងៃនេះ ម៉ោង 12:25',  'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),      'ថ្ងៃនេះ ម៉ោង 13:00',  'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),      'ស្អែក ម៉ោង 12:00',    'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(), 'ថ្ងៃនេះ ម៉ោង 11:00',  'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(), 'ម្សិលមិញ ម៉ោង 12:00', 'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({\n            d: i\n        });\n        assert.equal(m.calendar(), m.format('dddd [ម៉ោង] LT'), 'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(), m.format('dddd [ម៉ោង] LT'), 'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(), m.format('dddd [ម៉ោង] LT'), 'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({\n            d: i\n        });\n        assert.equal(m.calendar(), m.format('dddd [សប្តាហ៍មុន] [ម៉ោង] LT'), 'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(), m.format('dddd [សប្តាហ៍មុន] [ម៉ោង] LT'), 'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(), m.format('dddd [សប្តាហ៍មុន] [ម៉ោង] LT'), 'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({\n            w: 1\n        }),\n        weeksFromNow = moment().add({\n            w: 1\n        });\n\n    assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '1 week ago');\n    assert.equal(weeksFromNow.calendar(), weeksFromNow.format('L'), 'in 1 week');\n\n    weeksAgo = moment().subtract({\n        w: 2\n    });\n    weeksFromNow = moment().add({\n        w: 2\n    });\n\n    assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(), weeksFromNow.format('L'), 'in 2 weeks');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2012, 0, 1]).format('w ww wo'), '52 52 52', 'Jan  1 2012 should be week 52');\n    assert.equal(moment([2012, 0, 2]).format('w ww wo'), '1 01 1', 'Jan  2 2012 should be week 1');\n    assert.equal(moment([2012, 0, 8]).format('w ww wo'), '1 01 1', 'Jan  8 2012 should be week 1');\n    assert.equal(moment([2012, 0, 9]).format('w ww wo'), '2 02 2', 'Jan  9 2012 should be week 2');\n    assert.equal(moment([2012, 0, 15]).format('w ww wo'), '2 02 2', 'Jan 15 2012 should be week 2');\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\n\n\nfunction localeModule (name, lifecycle) {\n    QUnit.module('locale:' + name, {\n        setup : function () {\n            moment.locale(name);\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            moment.locale('en');\n            teardownDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n    defineCommonLocaleTests(name, -1, -1);\n}\n\nlocaleModule('kn');\n\ntest('parse', function (assert) {\n    var tests = 'ಜನವರಿ ಜನ_ಫೆಬ್ರವರಿ ಫೆಬ್ರ_ಮಾರ್ಚ್ ಮಾರ್ಚ್_ಏಪ್ರಿಲ್ ಏಪ್ರಿಲ್_ಮೇ ಮೇ_ಜೂನ್ ಜೂನ್_ಜುಲೈ ಜುಲೈ_ಆಗಸ್ಟ್ ಆಗಸ್ಟ್_ಸೆಪ್ಟೆಂಬರ್ ಸೆಪ್ಟೆಂಬ_ಅಕ್ಟೋಬರ್ ಅಕ್ಟೋಬ_ನವೆಂಬರ್ ನವೆಂಬ_ಡಿಸೆಂಬರ್ ಡಿಸೆಂಬ'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, Do MMMM YYYY, a h:mm:ss',      'ಭಾನುವಾರ, ೧೪ನೇ ಫೆಬ್ರವರಿ ೨೦೧೦, ಮಧ್ಯಾಹ್ನ ೩:೨೫:೫೦'],\n            ['ddd, a h ಗಂಟೆ',                      'ಭಾನು, ಮಧ್ಯಾಹ್ನ ೩ ಗಂಟೆ'],\n            ['M Mo MM MMMM MMM',                   '೨ ೨ನೇ ೦೨ ಫೆಬ್ರವರಿ ಫೆಬ್ರ'],\n            ['YYYY YY',                            '೨೦೧೦ ೧೦'],\n            ['D Do DD',                            '೧೪ ೧೪ನೇ ೧೪'],\n            ['d do dddd ddd dd',                   '೦ ೦ನೇ ಭಾನುವಾರ ಭಾನು ಭಾ'],\n            ['DDD DDDo DDDD',                      '೪೫ ೪೫ನೇ ೦೪೫'],\n            ['w wo ww',                            '೮ ೮ನೇ ೦೮'],\n            ['h hh',                               '೩ ೦೩'],\n            ['H HH',                               '೧೫ ೧೫'],\n            ['m mm',                               '೨೫ ೨೫'],\n            ['s ss',                               '೫೦ ೫೦'],\n            ['a A',                                'ಮಧ್ಯಾಹ್ನ ಮಧ್ಯಾಹ್ನ'],\n            ['LTS',                                'ಮಧ್ಯಾಹ್ನ ೩:೨೫:೫೦'],\n            ['L',                                  '೧೪/೦೨/೨೦೧೦'],\n            ['LL',                                 '೧೪ ಫೆಬ್ರವರಿ ೨೦೧೦'],\n            ['LLL',                                '೧೪ ಫೆಬ್ರವರಿ ೨೦೧೦, ಮಧ್ಯಾಹ್ನ ೩:೨೫'],\n            ['LLLL',                               'ಭಾನುವಾರ, ೧೪ ಫೆಬ್ರವರಿ ೨೦೧೦, ಮಧ್ಯಾಹ್ನ ೩:೨೫'],\n            ['l',                                  '೧೪/೨/೨೦೧೦'],\n            ['ll',                                 '೧೪ ಫೆಬ್ರ ೨೦೧೦'],\n            ['lll',                                '೧೪ ಫೆಬ್ರ ೨೦೧೦, ಮಧ್ಯಾಹ್ನ ೩:೨೫'],\n            ['llll',                               'ಭಾನು, ೧೪ ಫೆಬ್ರ ೨೦೧೦, ಮಧ್ಯಾಹ್ನ ೩:೨೫']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '೧ನೇ', '೧ನೇ');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '೨ನೇ', '೨ನೇ');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '೩ನೇ', '೩ನೇ');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '೪ನೇ', '೪ನೇ');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '೫ನೇ', '೫ನೇ');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '೬ನೇ', '೬ನೇ');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '೭ನೇ', '೭ನೇ');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '೮ನೇ', '೮ನೇ');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '೯ನೇ', '೯ನೇ');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '೧೦ನೇ', '೧೦ನೇ');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '೧೧ನೇ', '೧೧ನೇ');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '೧೨ನೇ', '೧೨ನೇ');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '೧೩ನೇ', '೧೩ನೇ');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '೧೪ನೇ', '೧೪ನೇ');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '೧೫ನೇ', '೧೫ನೇ');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '೧೬ನೇ', '೧೬ನೇ');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '೧೭ನೇ', '೧೭ನೇ');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '೧೮ನೇ', '೧೮ನೇ');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '೧೯ನೇ', '೧೯ನೇ');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '೨೦ನೇ', '೨೦ನೇ');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '೨೧ನೇ', '೨೧ನೇ');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '೨೨ನೇ', '೨೨ನೇ');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '೨೩ನೇ', '೨೩ನೇ');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '೨೪ನೇ', '೨೪ನೇ');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '೨೫ನೇ', '೨೫ನೇ');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '೨೬ನೇ', '೨೬ನೇ');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '೨೭ನೇ', '೨೭ನೇ');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '೨೮ನೇ', '೨೮ನೇ');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '೨೯ನೇ', '೨೯ನೇ');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '೩೦ನೇ', '೩೦ನೇ');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '೩೧ನೇ', '೩೧ನೇ');\n});\n\ntest('format month', function (assert) {\n    var expected = 'ಜನವರಿ ಜನ_ಫೆಬ್ರವರಿ ಫೆಬ್ರ_ಮಾರ್ಚ್ ಮಾರ್ಚ್_ಏಪ್ರಿಲ್ ಏಪ್ರಿಲ್_ಮೇ ಮೇ_ಜೂನ್ ಜೂನ್_ಜುಲೈ ಜುಲೈ_ಆಗಸ್ಟ್ ಆಗಸ್ಟ್_ಸೆಪ್ಟೆಂಬರ್ ಸೆಪ್ಟೆಂಬ_ಅಕ್ಟೋಬರ್ ಅಕ್ಟೋಬ_ನವೆಂಬರ್ ನವೆಂಬ_ಡಿಸೆಂಬರ್ ಡಿಸೆಂಬ'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'ಭಾನುವಾರ ಭಾನು ಭಾ_ಸೋಮವಾರ ಸೋಮ ಸೋ_ಮಂಗಳವಾರ ಮಂಗಳ ಮಂ_ಬುಧವಾರ ಬುಧ ಬು_ಗುರುವಾರ ಗುರು ಗು_ಶುಕ್ರವಾರ ಶುಕ್ರ ಶು_ಶನಿವಾರ ಶನಿ ಶ'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'ಕೆಲವು ಕ್ಷಣಗಳು', '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'ಒಂದು ನಿಮಿಷ',      '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'ಒಂದು ನಿಮಿಷ',      '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '೨ ನಿಮಿಷ',     '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '೪೪ ನಿಮಿಷ',    '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'ಒಂದು ಗಂಟೆ',       '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'ಒಂದು ಗಂಟೆ',       '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '೨ ಗಂಟೆ',       '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '೫ ಗಂಟೆ',       '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '೨೧ ಗಂಟೆ',      '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'ಒಂದು ದಿನ',         '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'ಒಂದು ದಿನ',         '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '೨ ದಿನ',        '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'ಒಂದು ದಿನ',         '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '೫ ದಿನ',        '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '೨೫ ದಿನ',       '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'ಒಂದು ತಿಂಗಳು',       '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'ಒಂದು ತಿಂಗಳು',       '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'ಒಂದು ತಿಂಗಳು',       '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '೨ ತಿಂಗಳು',      '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '೨ ತಿಂಗಳು',      '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '೩ ತಿಂಗಳು',      '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'ಒಂದು ತಿಂಗಳು',       '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '೫ ತಿಂಗಳು',      '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'ಒಂದು ವರ್ಷ',        '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '೨ ವರ್ಷ',       '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'ಒಂದು ವರ್ಷ',        '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '೫ ವರ್ಷ',       '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'ಕೆಲವು ಕ್ಷಣಗಳು ನಂತರ',  'prefix');\n    assert.equal(moment(0).from(30000), 'ಕೆಲವು ಕ್ಷಣಗಳು ಹಿಂದೆ', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'ಕೆಲವು ಕ್ಷಣಗಳು ಹಿಂದೆ',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'ಕೆಲವು ಕ್ಷಣಗಳು ನಂತರ', 'ಕೆಲವು ಕ್ಷಣಗಳು ನಂತರ');\n    assert.equal(moment().add({d: 5}).fromNow(), '೫ ದಿನ ನಂತರ', '೫ ದಿನ ನಂತರ');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'ಇಂದು ಮಧ್ಯಾಹ್ನ ೧೨:೦೦',    'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'ಇಂದು ಮಧ್ಯಾಹ್ನ ೧೨:೨೫',    'Now plus 25 min');\n    assert.equal(moment(a).add({h: 3}).calendar(),       'ಇಂದು ಮಧ್ಯಾಹ್ನ ೩:೦೦',     'Now plus 3 hours');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'ನಾಳೆ ಮಧ್ಯಾಹ್ನ ೧೨:೦೦',    'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'ಇಂದು ಮಧ್ಯಾಹ್ನ ೧೧:೦೦',    'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'ನಿನ್ನೆ ಮಧ್ಯಾಹ್ನ ೧೨:೦೦',    'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('dddd[,] LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd[,] LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd[,] LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('[ಕೊನೆಯ] dddd[,] LT'),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[ಕೊನೆಯ] dddd[,] LT'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[ಕೊನೆಯ] dddd[,] LT'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('meridiem', function (assert) {\n    assert.equal(moment([2011, 2, 23,  2, 30]).format('a'), 'ರಾತ್ರಿ', 'before dawn');\n    assert.equal(moment([2011, 2, 23,  9, 30]).format('a'), 'ಬೆಳಿಗ್ಗೆ', 'morning');\n    assert.equal(moment([2011, 2, 23, 14, 30]).format('a'), 'ಮಧ್ಯಾಹ್ನ', 'during day');\n    assert.equal(moment([2011, 2, 23, 17, 30]).format('a'), 'ಸಂಜೆ', 'evening');\n    assert.equal(moment([2011, 2, 23, 19, 30]).format('a'), 'ಸಂಜೆ', 'late evening');\n    assert.equal(moment([2011, 2, 23, 21, 20]).format('a'), 'ರಾತ್ರಿ', 'night');\n\n    assert.equal(moment([2011, 2, 23,  2, 30]).format('A'), 'ರಾತ್ರಿ', 'before dawn');\n    assert.equal(moment([2011, 2, 23,  9, 30]).format('A'), 'ಬೆಳಿಗ್ಗೆ', 'morning');\n    assert.equal(moment([2011, 2, 23, 14, 30]).format('A'), 'ಮಧ್ಯಾಹ್ನ', ' during day');\n    assert.equal(moment([2011, 2, 23, 17, 30]).format('A'), 'ಸಂಜೆ', 'evening');\n    assert.equal(moment([2011, 2, 23, 19, 30]).format('A'), 'ಸಂಜೆ', 'late evening');\n    assert.equal(moment([2011, 2, 23, 21, 20]).format('A'), 'ರಾತ್ರಿ', 'night');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2012, 0,  1]).format('w ww wo'), '೧ ೦೧ ೧ನೇ', 'Jan  1 2012 should be week 1');\n    assert.equal(moment([2012, 0,  7]).format('w ww wo'), '೧ ೦೧ ೧ನೇ', 'Jan  7 2012 should be week 1');\n    assert.equal(moment([2012, 0,  8]).format('w ww wo'), '೨ ೦೨ ೨ನೇ', 'Jan  8 2012 should be week 2');\n    assert.equal(moment([2012, 0, 14]).format('w ww wo'), '೨ ೦೨ ೨ನೇ', 'Jan 14 2012 should be week 2');\n    assert.equal(moment([2012, 0, 15]).format('w ww wo'), '೩ ೦೩ ೩ನೇ', 'Jan 15 2012 should be week 3');\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\n\n\nfunction localeModule (name, lifecycle) {\n    QUnit.module('locale:' + name, {\n        setup : function () {\n            moment.locale(name);\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            moment.locale('en');\n            teardownDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n    defineCommonLocaleTests(name, -1, -1);\n}\n\nlocaleModule('ko');\n\ntest('parse', function (assert) {\n    var tests = '1월 1월_2월 2월_3월 3월_4월 4월_5월 5월_6월 6월_7월 7월_8월 8월_9월 9월_10월 10월_11월 11월_12월 12월'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('parse meridiem', function (assert) {\n    var elements = [{\n        expression : '1981년 9월 8일 오후 2시 30분',\n        inputFormat : 'YYYY[년] M[월] D[일] A h[시] m[분]',\n        outputFormat : 'A',\n        expected : '오후'\n    }, {\n        expression : '1981년 9월 8일 오전 2시 30분',\n        inputFormat : 'YYYY[년] M[월] D[일] A h[시] m[분]',\n        outputFormat : 'A h시',\n        expected : '오전 2시'\n    }, {\n        expression : '14시 30분',\n        inputFormat : 'H[시] m[분]',\n        outputFormat : 'A',\n        expected : '오후'\n    }, {\n        expression : '오후 4시',\n        inputFormat : 'A h[시]',\n        outputFormat : 'H',\n        expected : '16'\n    }], i, l, it, actual;\n\n    for (i = 0, l = elements.length; i < l; ++i) {\n        it = elements[i];\n        actual = moment(it.expression, it.inputFormat).format(it.outputFormat);\n\n        assert.equal(\n            actual,\n            it.expected,\n            '\\'' + it.outputFormat + '\\' of \\'' + it.expression + '\\' must be \\'' + it.expected + '\\' but was \\'' + actual + '\\'.'\n        );\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['YYYY년 MMMM Do dddd a h:mm:ss',      '2010년 2월 14일 일요일 오후 3:25:50'],\n            ['ddd A h',                            '일 오후 3'],\n            ['M Mo MM MMMM MMM',                   '2 2일 02 2월 2월'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14일 14'],\n            ['d do dddd ddd dd',                   '0 0일 일요일 일 일'],\n            ['DDD DDDo DDDD',                      '45 45일 045'],\n            ['w wo ww',                            '8 8일 08'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                '오후 오후'],\n            ['일년 중 DDDo째 되는 날',                 '일년 중 45일째 되는 날'],\n            ['LTS',                                '오후 3:25:50'],\n            ['L',                                  '2010.02.14'],\n            ['LL',                                 '2010년 2월 14일'],\n            ['LLL',                                '2010년 2월 14일 오후 3:25'],\n            ['LLLL',                               '2010년 2월 14일 일요일 오후 3:25'],\n            ['l',                                  '2010.02.14'],\n            ['ll',                                 '2010년 2월 14일'],\n            ['lll',                                '2010년 2월 14일 오후 3:25'],\n            ['llll',                               '2010년 2월 14일 일요일 오후 3:25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1일', '1일');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2일', '2일');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3일', '3일');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4일', '4일');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5일', '5일');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6일', '6일');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7일', '7일');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8일', '8일');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9일', '9일');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10일', '10일');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11일', '11일');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12일', '12일');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13일', '13일');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14일', '14일');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15일', '15일');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16일', '16일');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17일', '17일');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18일', '18일');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19일', '19일');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20일', '20일');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21일', '21일');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22일', '22일');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23일', '23일');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24일', '24일');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25일', '25일');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26일', '26일');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27일', '27일');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28일', '28일');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29일', '29일');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30일', '30일');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31일', '31일');\n});\n\ntest('format month', function (assert) {\n    var expected = '1월 1월_2월 2월_3월 3월_4월 4월_5월 5월_6월 6월_7월 7월_8월 8월_9월 9월_10월 10월_11월 11월_12월 12월'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = '일요일 일 일_월요일 월 월_화요일 화 화_수요일 수 수_목요일 목 목_금요일 금 금_토요일 토 토'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  '몇 초', '44초 = 몇 초');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  '1분',      '45초 = 1분');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  '1분',      '89초 = 1분');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2분',     '90초 = 2분');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44분',    '44분 = 44분');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  '한 시간',       '45분 = 한 시간');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  '한 시간',       '89분 = 한 시간');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2시간',       '90분 = 2시간');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5시간',       '5시간 = 5시간');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21시간',      '21시간 = 21시간');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  '하루',         '22시간 = 하루');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  '하루',         '35시간 = 하루');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2일',        '36시간 = 2일');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   '하루',         '하루 = 하루');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5일',        '5일 = 5일');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25일',       '25일 = 25일');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  '한 달',       '26일 = 한 달');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  '한 달',       '30일 = 한 달');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  '한 달',       '45일 = 한 달');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2달',      '46일 = 2달');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2달',      '75일 = 2달');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3달',      '76일 = 3달');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   '한 달',       '1달 = 한 달');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5달',      '5달 = 5달');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), '일 년',        '345일 = 일 년');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2년',       '548일 = 2년');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   '일 년',        '일 년 = 일 년');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5년',       '5년 = 5년');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), '몇 초 후',  'prefix');\n    assert.equal(moment(0).from(30000), '몇 초 전', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), '몇 초 전',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), '몇 초 후', 'in a few seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), '5일 후', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   '오늘 오후 12:00', 'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      '오늘 오후 12:25', 'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       '오늘 오후 1:00',  'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       '내일 오후 12:00', 'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  '오늘 오전 11:00', 'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  '어제 오후 12:00', 'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('dddd LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('지난주 dddd LT'),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('지난주 dddd LT'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('지난주 dddd LT'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('weeks year starting sunday format', function (assert) {\n    assert.equal(moment([2012, 0,  1]).format('w ww wo'), '1 01 1일', 'Jan  1 2012 should be week 1');\n    assert.equal(moment([2012, 0,  7]).format('w ww wo'), '1 01 1일', 'Jan  7 2012 should be week 1');\n    assert.equal(moment([2012, 0,  8]).format('w ww wo'), '2 02 2일', 'Jan  8 2012 should be week 2');\n    assert.equal(moment([2012, 0, 14]).format('w ww wo'), '2 02 2일', 'Jan 14 2012 should be week 2');\n    assert.equal(moment([2012, 0, 15]).format('w ww wo'), '3 03 3일', 'Jan 15 2012 should be week 3');\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\n\n\nfunction localeModule (name, lifecycle) {\n    QUnit.module('locale:' + name, {\n        setup : function () {\n            moment.locale(name);\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            moment.locale('en');\n            teardownDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n    defineCommonLocaleTests(name, -1, -1);\n}\n\nlocaleModule('ky');\n\ntest('parse', function (assert) {\n    var tests = 'январь янв_февраль фев_март март_апрель апр_май май_июнь июнь_июль июль_август авг_сентябрь сен_октябрь окт_ноябрь ноя_декабрь дек'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, Do MMMM YYYY, HH:mm:ss',       'Жекшемби, 14-чү февраль 2010, 15:25:50'],\n            ['ddd, hA',                            'Жек, 3PM'],\n            ['M Mo MM MMMM MMM',                   '2 2-чи 02 февраль фев'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14-чү 14'],\n            ['d do dddd ddd dd',                   '0 0-чү Жекшемби Жек Жк'],\n            ['DDD DDDo DDDD',                      '45 45-чи 045'],\n            ['w wo ww',                            '7 7-чи 07'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'pm PM'],\n            ['[жылдын] DDDo [күнү]',               'жылдын 45-чи күнү'],\n            ['LTS',                                '15:25:50'],\n            ['L',                                  '14.02.2010'],\n            ['LL',                                 '14 февраль 2010'],\n            ['LLL',                                '14 февраль 2010 15:25'],\n            ['LLLL',                               'Жекшемби, 14 февраль 2010 15:25'],\n            ['l',                                  '14.2.2010'],\n            ['ll',                                 '14 фев 2010'],\n            ['lll',                                '14 фев 2010 15:25'],\n            ['llll',                               'Жек, 14 фев 2010 15:25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1-чи', '1st');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2-чи', '2nd');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3-чү', '3rd');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4-чү', '4th');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5-чи', '5th');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6-чы', '6th');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7-чи', '7th');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8-чи', '8th');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9-чу', '9th');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10-чу', '10th');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11-чи', '11th');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12-чи', '12th');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13-чү', '13th');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14-чү', '14th');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15-чи', '15th');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16-чы', '16th');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17-чи', '17th');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18-чи', '18th');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19-чу', '19th');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20-чы', '20th');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21-чи', '21st');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22-чи', '22nd');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23-чү', '23rd');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24-чү', '24th');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25-чи', '25th');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26-чы', '26th');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27-чи', '27th');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28-чи', '28th');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29-чу', '29th');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30-чу', '30th');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31-чи', '31st');\n});\n\ntest('format month', function (assert) {\n    var expected = 'январь янв_февраль фев_март март_апрель апр_май май_июнь июнь_июль июль_август авг_сентябрь сен_октябрь окт_ноябрь ноя_декабрь дек'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'Жекшемби Жек Жк_Дүйшөмбү Дүй Дй_Шейшемби Шей Шй_Шаршемби Шар Шр_Бейшемби Бей Бй_Жума Жум Жм_Ишемби Ише Иш'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'бирнече секунд', '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'бир мүнөт',      '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'бир мүнөт',      '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 мүнөт',     '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 мүнөт',    '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'бир саат',       '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'бир саат',       '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 саат',       '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 саат',       '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 саат',      '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'бир күн',         '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'бир күн',         '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 күн',        '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'бир күн',         '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 күн',        '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 күн',       '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'бир ай',       '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'бир ай',       '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'бир ай',       '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 ай',      '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 ай',      '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 ай',      '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'бир ай',       '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 ай',      '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'бир жыл',        '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 жыл',       '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'бир жыл',        '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 жыл',       '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'бирнече секунд ичинде',  'prefix');\n    assert.equal(moment(0).from(30000), 'бирнече секунд мурун', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'бирнече секунд мурун',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'бирнече секунд ичинде', 'in a few seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), '5 күн ичинде', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'Бүгүн саат 12:00',  'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'Бүгүн саат 12:25',  'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'Бүгүн саат 13:00',  'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'Эртең саат 12:00',  'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'Бүгүн саат 11:00',  'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'Кече саат 12:00',   'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('dddd [саат] LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd [саат] LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd [саат] LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('[Өткен аптанын] dddd [күнү] [саат] LT'),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[Өткен аптанын] dddd [күнү] [саат] LT'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[Өткен аптанын] dddd [күнү] [саат] LT'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2012, 0,  1]).format('w ww wo'),   '1 01 1-чи', 'Jan  1 2012 should be week 1');\n    assert.equal(moment([2012, 0,  2]).format('w ww wo'),   '2 02 2-чи', 'Jan  2 2012 should be week 2');\n    assert.equal(moment([2012, 0,  8]).format('w ww wo'),   '2 02 2-чи', 'Jan  8 2012 should be week 2');\n    assert.equal(moment([2012, 0,  9]).format('w ww wo'),   '3 03 3-чү', 'Jan  9 2012 should be week 3');\n    assert.equal(moment([2012, 0, 15]).format('w ww wo'),   '3 03 3-чү', 'Jan 15 2012 should be week 3');\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\n\n\nfunction localeModule (name, lifecycle) {\n    QUnit.module('locale:' + name, {\n        setup : function () {\n            moment.locale(name);\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            moment.locale('en');\n            teardownDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n    defineCommonLocaleTests(name, -1, -1);\n}\n\nlocaleModule('lb');\n\ntest('parse', function (assert) {\n    var tests = 'Januar Jan._Februar Febr._Mäerz Mrz._Abrëll Abr._Mee Mee_Juni Jun._Juli Jul._August Aug._September Sept._Oktober Okt._November Nov._Dezember Dez.'.split('_'), i;\n\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, Do MMMM YYYY, HH:mm:ss', 'Sonndeg, 14. Februar 2010, 15:25:50'],\n            ['ddd, HH:mm', 'So., 15:25'],\n            ['M Mo MM MMMM MMM', '2 2. 02 Februar Febr.'],\n            ['YYYY YY', '2010 10'],\n            ['D Do DD', '14 14. 14'],\n            ['d do dddd ddd dd', '0 0. Sonndeg So. So'],\n            ['DDD DDDo DDDD', '45 45. 045'],\n            ['w wo ww', '6 6. 06'],\n            ['h hh', '3 03'],\n            ['H HH', '15 15'],\n            ['m mm', '25 25'],\n            ['s ss', '50 50'],\n            ['a A', 'pm PM'],\n            ['[the] DDDo [day of the year]', 'the 45. day of the year'],\n            ['LTS', '15:25:50 Auer'],\n            ['L', '14.02.2010'],\n            ['LL', '14. Februar 2010'],\n            ['LLL', '14. Februar 2010 15:25 Auer'],\n            ['LLLL', 'Sonndeg, 14. Februar 2010 15:25 Auer'],\n            ['l', '14.2.2010'],\n            ['ll', '14. Febr. 2010'],\n            ['lll', '14. Febr. 2010 15:25 Auer'],\n            ['llll', 'So., 14. Febr. 2010 15:25 Auer']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format month', function (assert) {\n    var expected = 'Januar Jan._Februar Febr._Mäerz Mrz._Abrëll Abr._Mee Mee_Juni Jun._Juli Jul._August Aug._September Sept._Oktober Okt._November Nov._Dezember Dez.'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'Sonndeg So. So_Méindeg Mé. Mé_Dënschdeg Dë. Dë_Mëttwoch Më. Më_Donneschdeg Do. Do_Freideg Fr. Fr_Samschdeg Sa. Sa'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true), 'e puer Sekonnen', '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true), 'eng Minutt', '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true), 'eng Minutt', '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true), '2 Minutten', '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true), '44 Minutten', '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true), 'eng Stonn', '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true), 'eng Stonn', '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true), '2 Stonnen', '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true), '5 Stonnen', '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true), '21 Stonnen', '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true), 'een Dag', '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true), 'een Dag', '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true), '2 Deeg', '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true), 'een Dag', '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true), '5 Deeg', '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true), '25 Deeg', '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true), 'ee Mount', '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true), 'ee Mount', '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true), 'ee Mount', '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true), '2 Méint', '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true), '2 Méint', '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true), '3 Méint', '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true), 'ee Mount', '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true), '5 Méint', '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'ee Joer', '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 Joer', '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true), 'ee Joer', '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true), '5 Joer', '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'an e puer Sekonnen', 'prefix');\n    assert.equal(moment(0).from(30000), 'virun e puer Sekonnen', 'suffix');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'an e puer Sekonnen', 'in a few seconds');\n    assert.equal(moment().add({d: 1}).fromNow(), 'an engem Dag', 'in one day');\n    assert.equal(moment().add({d: 2}).fromNow(), 'an 2 Deeg', 'in 2 days');\n    assert.equal(moment().add({d: 3}).fromNow(), 'an 3 Deeg', 'in 3 days');\n    assert.equal(moment().add({d: 4}).fromNow(), 'a 4 Deeg', 'in 4 days');\n    assert.equal(moment().add({d: 5}).fromNow(), 'a 5 Deeg', 'in 5 days');\n    assert.equal(moment().add({d: 6}).fromNow(), 'a 6 Deeg', 'in 6 days');\n    assert.equal(moment().add({d: 7}).fromNow(), 'a 7 Deeg', 'in 7 days');\n    assert.equal(moment().add({d: 8}).fromNow(), 'an 8 Deeg', 'in 8 days');\n    assert.equal(moment().add({d: 9}).fromNow(), 'an 9 Deeg', 'in 9 days');\n    assert.equal(moment().add({d: 10}).fromNow(), 'an 10 Deeg', 'in 10 days');\n    assert.equal(moment().add({y: 100}).fromNow(), 'an 100 Joer', 'in 100 years');\n    assert.equal(moment().add({y: 400}).fromNow(), 'a 400 Joer', 'in 400 years');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'Haut um 12:00 Auer',     'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'Haut um 12:25 Auer',     'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'Haut um 13:00 Auer',     'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'Muer um 12:00 Auer',     'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'Haut um 11:00 Auer',     'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'Gëschter um 12:00 Auer', 'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('dddd [um] LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd [um] LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd [um] LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m, weekday, datestring;\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n\n        // Different date string for 'Dënschdeg' (Tuesday) and 'Donneschdeg' (Thursday)\n        weekday = parseInt(m.format('d'), 10);\n        datestring = (weekday === 2 || weekday === 4 ? '[Leschten] dddd [um] LT' : '[Leschte] dddd [um] LT');\n\n        assert.equal(m.calendar(), m.format(datestring), 'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(), m.format(datestring), 'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(), m.format(datestring), 'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('weeks year starting sunday format', function (assert) {\n    assert.equal(moment([2012, 0,  1]).format('w ww wo'), '52 52 52.', 'Jan  1 2012 should be week 52');\n    assert.equal(moment([2012, 0,  7]).format('w ww wo'), '1 01 1.',   'Jan  7 2012 should be week 1');\n    assert.equal(moment([2012, 0,  8]).format('w ww wo'), '1 01 1.',   'Jan  8 2012 should be week 1');\n    assert.equal(moment([2012, 0, 14]).format('w ww wo'), '2 02 2.',   'Jan 14 2012 should be week 2');\n    assert.equal(moment([2012, 0, 15]).format('w ww wo'), '2 02 2.',   'Jan 15 2012 should be week 2');\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\n\n\nfunction localeModule (name, lifecycle) {\n    QUnit.module('locale:' + name, {\n        setup : function () {\n            moment.locale(name);\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            moment.locale('en');\n            teardownDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n    defineCommonLocaleTests(name, -1, -1);\n}\n\nlocaleModule('lo');\n\ntest('parse', function (assert) {\n    var tests = 'ມັງກອນ ມັງກອນ_ກຸມພາ ກຸມພາ_ມີນາ ມີນາ_ເມສາ ເມສາ_ພຶດສະພາ ພຶດສະພາ_ມິຖຸນາ ມິຖຸນາ_ກໍລະກົດ ກໍລະກົດ_ສິງຫາ ສິງຫາ_ກັນຍາ ກັນຍາ_ຕຸລາ ຕຸລາ_ພະຈິກ ພະຈິກ_ທັນວາ ທັນວາ'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, MMMM Do YYYY, h:mm:ss a',      'ອາທິດ, ກຸມພາ ທີ່14 2010, 3:25:50 ຕອນແລງ'],\n            ['ddd, hA',                            'ທິດ, 3ຕອນແລງ'],\n            ['M Mo MM MMMM MMM',                   '2 ທີ່2 02 ກຸມພາ ກຸມພາ'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 ທີ່14 14'],\n            ['d do dddd ddd dd',                   '0 ທີ່0 ອາທິດ ທິດ ທ'],\n            ['DDD DDDo DDDD',                      '45 ທີ່45 045'],\n            ['w wo ww',                            '8 ທີ່8 08'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'ຕອນແລງ ຕອນແລງ'],\n            ['[ວັນ]DDDo [ຂອງປີ]',                   'ວັນທີ່45 ຂອງປີ'],\n            ['LTS',                                '15:25:50'],\n            ['L',                                  '14/02/2010'],\n            ['LL',                                 '14 ກຸມພາ 2010'],\n            ['LLL',                                '14 ກຸມພາ 2010 15:25'],\n            ['LLLL',                               'ວັນອາທິດ 14 ກຸມພາ 2010 15:25'],\n            ['l',                                  '14/2/2010'],\n            ['ll',                                 '14 ກຸມພາ 2010'],\n            ['lll',                                '14 ກຸມພາ 2010 15:25'],\n            ['llll',                               'ວັນທິດ 14 ກຸມພາ 2010 15:25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), 'ທີ່1', 'ທີ່1');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), 'ທີ່2', 'ທີ່2');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), 'ທີ່3', 'ທີ່3');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), 'ທີ່4', 'ທີ່4');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), 'ທີ່5', 'ທີ່5');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), 'ທີ່6', 'ທີ່6');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), 'ທີ່7', 'ທີ່7');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), 'ທີ່8', 'ທີ່8');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), 'ທີ່9', 'ທີ່9');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), 'ທີ່10', 'ທີ່10');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), 'ທີ່11', 'ທີ່11');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), 'ທີ່12', 'ທີ່12');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), 'ທີ່13', 'ທີ່13');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), 'ທີ່14', 'ທີ່14');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), 'ທີ່15', 'ທີ່15');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), 'ທີ່16', 'ທີ່16');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), 'ທີ່17', 'ທີ່17');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), 'ທີ່18', 'ທີ່18');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), 'ທີ່19', 'ທີ່19');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), 'ທີ່20', 'ທີ່20');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), 'ທີ່21', 'ທີ່21');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), 'ທີ່22', 'ທີ່22');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), 'ທີ່23', 'ທີ່23');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), 'ທີ່24', 'ທີ່24');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), 'ທີ່25', 'ທີ່25');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), 'ທີ່26', 'ທີ່26');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), 'ທີ່27', 'ທີ່27');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), 'ທີ່28', 'ທີ່28');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), 'ທີ່29', 'ທີ່29');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), 'ທີ່30', 'ທີ່30');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), 'ທີ່31', 'ທີ່31');\n});\n\ntest('format month', function (assert) {\n    var expected = 'ມັງກອນ ມັງກອນ_ກຸມພາ ກຸມພາ_ມີນາ ມີນາ_ເມສາ ເມສາ_ພຶດສະພາ ພຶດສະພາ_ມິຖຸນາ ມິຖຸນາ_ກໍລະກົດ ກໍລະກົດ_ສິງຫາ ສິງຫາ_ກັນຍາ ກັນຍາ_ຕຸລາ ຕຸລາ_ພະຈິກ ພະຈິກ_ທັນວາ ທັນວາ'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'ອາທິດ ທິດ ທ_ຈັນ ຈັນ ຈ_ອັງຄານ ອັງຄານ ອຄ_ພຸດ ພຸດ ພ_ພະຫັດ ພະຫັດ ພຫ_ສຸກ ສຸກ ສກ_ເສົາ ເສົາ ສ'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'ບໍ່ເທົ່າໃດວິນາທີ', '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  '1 ນາທີ',      '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  '1 ນາທີ',      '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 ນາທີ',     '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 ນາທີ',    '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  '1 ຊົ່ວໂມງ',       '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  '1 ຊົ່ວໂມງ',       '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 ຊົ່ວໂມງ',       '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 ຊົ່ວໂມງ',       '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 ຊົ່ວໂມງ',      '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  '1 ມື້',         '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  '1 ມື້',         '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 ມື້',        '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   '1 ມື້',         '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 ມື້',        '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 ມື້',       '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  '1 ເດືອນ',       '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  '1 ເດືອນ',       '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  '1 ເດືອນ',       '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 ເດືອນ',      '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 ເດືອນ',      '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 ເດືອນ',      '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   '1 ເດືອນ',       '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 ເດືອນ',      '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), '1 ປີ',        '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 ປີ',       '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   '1 ປີ',        '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 ປີ',       '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'ອີກ ບໍ່ເທົ່າໃດວິນາທີ',  'prefix');\n    assert.equal(moment(0).from(30000), 'ບໍ່ເທົ່າໃດວິນາທີຜ່ານມາ', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'ບໍ່ເທົ່າໃດວິນາທີຜ່ານມາ',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'ອີກ ບໍ່ເທົ່າໃດວິນາທີ', 'in a few seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), 'ອີກ 5 ມື້', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'ມື້ນີ້ເວລາ 12:00',    'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'ມື້ນີ້ເວລາ 12:25',    'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'ມື້ນີ້ເວລາ 13:00',    'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'ມື້ອື່ນເວລາ 12:00',   'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'ມື້ນີ້ເວລາ 11:00',    'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'ມື້ວານນີ້ເວລາ 12:00',  'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('[ວັນ]dddd[ໜ້າເວລາ] LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[ວັນ]dddd[ໜ້າເວລາ] LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[ວັນ]dddd[ໜ້າເວລາ] LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('[ວັນ]dddd[ແລ້ວນີ້ເວລາ] LT'),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[ວັນ]dddd[ແລ້ວນີ້ເວລາ] LT'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[ວັນ]dddd[ແລ້ວນີ້ເວລາ] LT'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('weeks year starting sunday format', function (assert) {\n    assert.equal(moment([2012, 0,  1]).format('w ww wo'), '1 01 ທີ່1', 'Jan  1 2012 should be week 1');\n    assert.equal(moment([2012, 0,  7]).format('w ww wo'), '1 01 ທີ່1', 'Jan  7 2012 should be week 1');\n    assert.equal(moment([2012, 0,  8]).format('w ww wo'), '2 02 ທີ່2', 'Jan  8 2012 should be week 2');\n    assert.equal(moment([2012, 0, 14]).format('w ww wo'), '2 02 ທີ່2', 'Jan 14 2012 should be week 2');\n    assert.equal(moment([2012, 0, 15]).format('w ww wo'), '3 03 ທີ່3', 'Jan 15 2012 should be week 3');\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\n\n\nfunction localeModule (name, lifecycle) {\n    QUnit.module('locale:' + name, {\n        setup : function () {\n            moment.locale(name);\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            moment.locale('en');\n            teardownDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n    defineCommonLocaleTests(name, -1, -1);\n}\n\nlocaleModule('lt');\n\ntest('parse', function (assert) {\n    var tests = 'sausis sau_vasaris vas_kovas kov_balandis bal_gegužė geg_birželis bir_liepa lie_rugpjūtis rgp_rugsėjis rgs_spalis spa_lapkritis lap_gruodis grd'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, Do MMMM YYYY, h:mm:ss a',      'sekmadienis, 14-oji vasario 2010, 3:25:50 pm'],\n            ['ddd, hA',                            'Sek, 3PM'],\n            ['M Mo MM MMMM MMM',                   '2 2-oji 02 vasaris vas'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14-oji 14'],\n            ['d do dddd ddd dd',                   '0 0-oji sekmadienis Sek S'],\n            ['DDD DDDo DDDD',                      '45 45-oji 045'],\n            ['w wo ww',                            '6 6-oji 06'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'pm PM'],\n            ['DDDo [metų diena]',                  '45-oji metų diena'],\n            ['LTS',                                '15:25:50'],\n            ['L',                                  '2010-02-14'],\n            ['LL',                                 '2010 m. vasario 14 d.'],\n            ['LLL',                                '2010 m. vasario 14 d., 15:25 val.'],\n            ['LLLL',                               '2010 m. vasario 14 d., sekmadienis, 15:25 val.'],\n            ['l',                                  '2010-02-14'],\n            ['ll',                                 '2010 m. vasario 14 d.'],\n            ['lll',                                '2010 m. vasario 14 d., 15:25 val.'],\n            ['llll',                               '2010 m. vasario 14 d., Sek, 15:25 val.']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1-oji', '1-oji');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2-oji', '2-oji');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3-oji', '3-oji');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4-oji', '4-oji');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5-oji', '5-oji');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6-oji', '6-oji');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7-oji', '7-oji');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8-oji', '8-oji');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9-oji', '9-oji');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10-oji', '10-oji');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11-oji', '11-oji');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12-oji', '12-oji');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13-oji', '13-oji');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14-oji', '14-oji');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15-oji', '15-oji');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16-oji', '16-oji');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17-oji', '17-oji');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18-oji', '18-oji');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19-oji', '19-oji');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20-oji', '20-oji');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21-oji', '21-oji');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22-oji', '22-oji');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23-oji', '23-oji');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24-oji', '24-oji');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25-oji', '25-oji');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26-oji', '26-oji');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27-oji', '27-oji');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28-oji', '28-oji');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29-oji', '29-oji');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30-oji', '30-oji');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31-oji', '31-oji');\n});\n\ntest('format month', function (assert) {\n    var expected = 'sausis sau_vasaris vas_kovas kov_balandis bal_gegužė geg_birželis bir_liepa lie_rugpjūtis rgp_rugsėjis rgs_spalis spa_lapkritis lap_gruodis grd'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'sekmadienis Sek S_pirmadienis Pir P_antradienis Ant A_trečiadienis Tre T_ketvirtadienis Ket K_penktadienis Pen Pn_šeštadienis Šeš Š'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('format week on US calendar', function (assert) {\n    // Tests, whether the weekday names are correct, even if the week does not start on Monday\n    moment.updateLocale('lt', {week: {dow: 0, doy: 6}});\n    var expected = 'sekmadienis Sek S_pirmadienis Pir P_antradienis Ant A_trečiadienis Tre T_ketvirtadienis Ket K_penktadienis Pen Pn_šeštadienis Šeš Š'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n    moment.updateLocale('lt', null);\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'kelios sekundės', '44 seconds = seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'minutė',          '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'minutė',          '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 minutės',       '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 10}), true),  '10 minučių',       '10 minutes = 10 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 11}), true),  '11 minučių',       '11 minutes = 11 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 19}), true),  '19 minučių',       '19 minutes = 19 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 20}), true),  '20 minučių',       '20 minutes = 20 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 minutės',      '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'valanda',         '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'valanda',         '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 valandos',      '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 valandos',      '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 10}), true),  '10 valandų',      '10 hours = 10 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 valandos',     '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'diena',           '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'diena',           '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 dienos',        '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'diena',           '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 dienos',        '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 10}), true),  '10 dienų',        '10 days = 10 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 dienos',       '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'mėnuo',           '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'mėnuo',           '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'mėnuo',           '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 mėnesiai',      '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 mėnesiai',      '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 mėnesiai',      '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'mėnuo',           '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 mėnesiai',      '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 10}), true),  '10 mėnesių',      '10 months = 10 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'metai',           '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 metai',         '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'metai',           '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 metai',         '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'po kelių sekundžių',  'prefix');\n    assert.equal(moment(0).from(30000), 'prieš kelias sekundes', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'prieš kelias sekundes',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'po kelių sekundžių', 'in seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), 'po 5 dienų', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'Šiandien 12:00',  'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'Šiandien 12:25',  'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'Šiandien 13:00',  'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'Rytoj 12:00',     'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'Šiandien 11:00',  'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'Vakar 12:00',     'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('dddd LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('[Praėjusį] dddd LT'),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[Praėjusį] dddd LT'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[Praėjusį] dddd LT'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2012, 0,  1]).format('w ww wo'), '52 52 52-oji', 'Jan  1 2012 should be week 52');\n    assert.equal(moment([2012, 0,  2]).format('w ww wo'),  '1 01 1-oji', 'Jan  2 2012 should be week 1');\n    assert.equal(moment([2012, 0,  8]).format('w ww wo'),  '1 01 1-oji', 'Jan  8 2012 should be week 1');\n    assert.equal(moment([2012, 0,  9]).format('w ww wo'),  '2 02 2-oji', 'Jan  9 2012 should be week 2');\n    assert.equal(moment([2012, 0, 15]).format('w ww wo'),  '2 02 2-oji', 'Jan 15 2012 should be week 2');\n});\n\ntest('month cases', function (assert) {\n    assert.equal(moment([2015, 4, 1]).format('LL'), '2015 m. gegužės 1 d.', 'uses format instead of standalone form');\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\n\n\nfunction localeModule (name, lifecycle) {\n    QUnit.module('locale:' + name, {\n        setup : function () {\n            moment.locale(name);\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            moment.locale('en');\n            teardownDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n    defineCommonLocaleTests(name, -1, -1);\n}\n\nlocaleModule('lv');\n\ntest('parse', function (assert) {\n    var tests = 'janvāris jan_februāris feb_marts mar_aprīlis apr_maijs mai_jūnijs jūn_jūlijs jūl_augusts aug_septembris sep_oktobris okt_novembris nov_decembris dec'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, Do MMMM YYYY, h:mm:ss a',      'svētdiena, 14. februāris 2010, 3:25:50 pm'],\n            ['ddd, hA',                            'Sv, 3PM'],\n            ['M Mo MM MMMM MMM',                   '2 2. 02 februāris feb'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14. 14'],\n            ['d do dddd ddd dd',                   '0 0. svētdiena Sv Sv'],\n            ['DDD DDDo DDDD',                      '45 45. 045'],\n            ['w wo ww',                            '6 6. 06'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'pm PM'],\n            ['[the] DDDo [day of the year]',       'the 45. day of the year'],\n            ['LTS',                                '15:25:50'],\n            ['L',                                  '14.02.2010.'],\n            ['LL',                                 '2010. gada 14. februāris'],\n            ['LLL',                                '2010. gada 14. februāris, 15:25'],\n            ['LLLL',                               '2010. gada 14. februāris, svētdiena, 15:25'],\n            ['l',                                  '14.2.2010.'],\n            ['ll',                                 '2010. gada 14. feb'],\n            ['lll',                                '2010. gada 14. feb, 15:25'],\n            ['llll',                               '2010. gada 14. feb, Sv, 15:25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1.', '1.');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2.', '2.');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3.', '3.');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4.', '4.');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5.', '5.');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6.', '6.');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7.', '7.');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8.', '8.');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9.', '9.');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10.', '10.');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11.', '11.');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12.', '12.');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13.', '13.');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14.', '14.');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15.', '15.');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16.', '16.');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17.', '17.');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18.', '18.');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19.', '19.');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20.', '20.');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21.', '21.');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22.', '22.');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23.', '23.');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24.', '24.');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25.', '25.');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26.', '26.');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27.', '27.');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28.', '28.');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29.', '29.');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30.', '30.');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31.', '31.');\n});\n\ntest('format month', function (assert) {\n    var expected = 'janvāris jan_februāris feb_marts mar_aprīlis apr_maijs mai_jūnijs jūn_jūlijs jūl_augusts aug_septembris sep_oktobris okt_novembris nov_decembris dec'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'svētdiena Sv Sv_pirmdiena P P_otrdiena O O_trešdiena T T_ceturtdiena C C_piektdiena Pk Pk_sestdiena S S'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\n// Includes testing the cases of withoutSuffix = true and false.\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),   'dažas sekundes',       '44 seconds = seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), false),  'pirms dažām sekundēm', '44 seconds with suffix = seconds ago');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),   'minūte',               '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), false),  'pirms minūtes',        '45 seconds with suffix = a minute ago');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),   'minūte',               '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: -89}), false), 'pēc minūtes',          '89 seconds with suffix/prefix = in a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),   '2 minūtes',            '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), false),  'pirms 2 minūtēm',      '90 seconds with suffix = 2 minutes ago');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),   '44 minūtes',           '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), false),  'pirms 44 minūtēm',     '44 minutes with suffix = 44 minutes ago');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),   'stunda',               '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), false),  'pirms stundas',        '45 minutes with suffix = an hour ago');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),   'stunda',               '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),   '2 stundas',            '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: -90}), false), 'pēc 2 stundām',        '90 minutes with suffix = in 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),    '5 stundas',            '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), false),   'pirms 5 stundām',      '5 hours with suffix = 5 hours ago');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),   '21 stunda',            '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), false),  'pirms 21 stundas',     '21 hours with suffix = 21 hours ago');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),   'diena',                '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), false),  'pirms dienas',         '22 hours with suffix = a day ago');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),   'diena',                '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),   '2 dienas',             '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), false),  'pirms 2 dienām',       '36 hours with suffix = 2 days ago');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),    'diena',                '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),    '5 dienas',             '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), false),   'pirms 5 dienām',       '5 days with suffix = 5 days ago');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),   '25 dienas',            '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), false),  'pirms 25 dienām',      '25 days with suffix = 25 days ago');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),   'mēnesis',              '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), false),  'pirms mēneša',         '26 days with suffix = a month ago');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),   'mēnesis',              '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),   'mēnesis',              '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),   '2 mēneši',             '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), false),  'pirms 2 mēnešiem',     '46 days with suffix = 2 months ago');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),   '2 mēneši',             '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),   '3 mēneši',             '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), false),  'pirms 3 mēnešiem',     '76 days with suffix = 3 months ago');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),    'mēnesis',              '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),    '5 mēneši',             '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), false),   'pirms 5 mēnešiem',     '5 months with suffix = 5 months ago');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true),  'gads',                 '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), false), 'pirms gada',           '345 days with suffix = a year ago');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true),  '2 gadi',               '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), false), 'pirms 2 gadiem',       '548 days with suffix = 2 years ago');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),    'gads',                 '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),    '5 gadi',               '5 years = 5 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), false),   'pirms 5 gadiem',       '5 years with suffix = 5 years ago');\n\n    // test that numbers ending with 1 are singular except for when they end with 11 in which case they are plural\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 11}), true),   '11 gadi',              '11 years = 11 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 21}), true),   '21 gads',              '21 year = 21 year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 211}), true),  '211 gadi',             '211 years = 211 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 221}), false), 'pirms 221 gada',       '221 year with suffix = 221 years ago');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'pēc dažām sekundēm',  'prefix');\n    assert.equal(moment(0).from(30000), 'pirms dažām sekundēm', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'pirms dažām sekundēm',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'pēc dažām sekundēm', 'in seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), 'pēc 5 dienām', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'Šodien pulksten 12:00',  'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'Šodien pulksten 12:25',  'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'Šodien pulksten 13:00',  'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'Rīt pulksten 12:00',     'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'Šodien pulksten 11:00',  'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'Vakar pulksten 12:00',   'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('dddd [pulksten] LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd [pulksten] LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd [pulksten] LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('[Pagājušā] dddd [pulksten] LT'),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[Pagājušā] dddd [pulksten] LT'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[Pagājušā] dddd [pulksten] LT'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2012, 0,  1]).format('w ww wo'), '52 52 52.', 'Jan  1 2012 should be week 52');\n    assert.equal(moment([2012, 0,  2]).format('w ww wo'),  '1 01 1.', 'Jan  2 2012 should be week 1');\n    assert.equal(moment([2012, 0,  8]).format('w ww wo'),  '1 01 1.', 'Jan  8 2012 should be week 1');\n    assert.equal(moment([2012, 0,  9]).format('w ww wo'),  '2 02 2.', 'Jan  9 2012 should be week 2');\n    assert.equal(moment([2012, 0, 15]).format('w ww wo'),  '2 02 2.', 'Jan 15 2012 should be week 2');\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\n\n\nfunction localeModule (name, lifecycle) {\n    QUnit.module('locale:' + name, {\n        setup : function () {\n            moment.locale(name);\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            moment.locale('en');\n            teardownDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n    defineCommonLocaleTests(name, -1, -1);\n}\n\nlocaleModule('me');\n\ntest('parse', function (assert) {\n    var tests = 'januar jan._februar feb._mart mar._april apr._maj maj_jun jun_jul jul_avgust avg._septembar sep._oktobar okt._novembar nov._decembar dec.'.split('_'),\n        i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, Do MMMM YYYY, h:mm:ss a',      'nedjelja, 14. februar 2010, 3:25:50 pm'],\n            ['ddd, hA',                            'ned., 3PM'],\n            ['M Mo MM MMMM MMM',                   '2 2. 02 februar feb.'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14. 14'],\n            ['d do dddd ddd dd',                   '0 0. nedjelja ned. ne'],\n            ['DDD DDDo DDDD',                      '45 45. 045'],\n            ['w wo ww',                            '7 7. 07'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'pm PM'],\n            ['[the] DDDo [day of the year]',       'the 45. day of the year'],\n            ['LTS',                                '15:25:50'],\n            ['L',                                  '14.02.2010'],\n            ['LL',                                 '14. februar 2010'],\n            ['LLL',                                '14. februar 2010 15:25'],\n            ['LLLL',                               'nedjelja, 14. februar 2010 15:25'],\n            ['l',                                  '14.2.2010'],\n            ['ll',                                 '14. feb. 2010'],\n            ['lll',                                '14. feb. 2010 15:25'],\n            ['llll',                               'ned., 14. feb. 2010 15:25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1.', '1.');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2.', '2.');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3.', '3.');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4.', '4.');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5.', '5.');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6.', '6.');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7.', '7.');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8.', '8.');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9.', '9.');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10.', '10.');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11.', '11.');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12.', '12.');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13.', '13.');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14.', '14.');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15.', '15.');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16.', '16.');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17.', '17.');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18.', '18.');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19.', '19.');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20.', '20.');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21.', '21.');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22.', '22.');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23.', '23.');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24.', '24.');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25.', '25.');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26.', '26.');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27.', '27.');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28.', '28.');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29.', '29.');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30.', '30.');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31.', '31.');\n});\n\ntest('format month', function (assert) {\n    var expected = 'januar jan._februar feb._mart mar._april apr._maj maj_jun jun_jul jul_avgust avg._septembar sep._oktobar okt._novembar nov._decembar dec.'.split('_'),\n        i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'nedjelja ned. ne_ponedjeljak pon. po_utorak uto. ut_srijeda sri. sr_četvrtak čet. če_petak pet. pe_subota sub. su'.split('_'),\n        i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'nekoliko sekundi', '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'jedan minut',   '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'jedan minut',   '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 minuta',     '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 minuta',     '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'jedan sat',      '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'jedan sat',      '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 sata',        '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 sati',         '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 sati',        '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'dan',       '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'dan',       '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 dana',        '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'dan',       '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 dana',        '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 dana',       '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'mjesec',     '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'mjesec',     '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'mjesec',     '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 mjeseca',     '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 mjeseca',     '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 mjeseca',     '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'mjesec',     '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 mjeseci',    '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'godinu',     '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 godine',       '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'godinu',     '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 godina',        '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'za nekoliko sekundi',  'prefix');\n    assert.equal(moment(0).from(30000), 'prije nekoliko sekundi', 'prefix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'prije nekoliko sekundi',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'za nekoliko sekundi', 'in a few seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), 'za 5 dana', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'danas u 12:00',  'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'danas u 12:25',  'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'danas u 13:00',  'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'sjutra u 12:00', 'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'danas u 11:00',  'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'juče u 12:00',   'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n\n    function makeFormat(d) {\n        switch (d.day()) {\n            case 0:\n                return '[u] [nedjelju] [u] LT';\n            case 3:\n                return '[u] [srijedu] [u] LT';\n            case 6:\n                return '[u] [subotu] [u] LT';\n            case 1:\n            case 2:\n            case 4:\n            case 5:\n                return '[u] dddd [u] LT';\n        }\n    }\n\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format(makeFormat(m)),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format(makeFormat(m)),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format(makeFormat(m)),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n\n    function makeFormat(d) {\n        var lastWeekDay = [\n                '[prošle] [nedjelje] [u] LT',\n                '[prošlog] [ponedjeljka] [u] LT',\n                '[prošlog] [utorka] [u] LT',\n                '[prošle] [srijede] [u] LT',\n                '[prošlog] [četvrtka] [u] LT',\n                '[prošlog] [petka] [u] LT',\n                '[prošle] [subote] [u] LT'\n            ];\n\n        return lastWeekDay[d.day()];\n    }\n\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format(makeFormat(m)),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format(makeFormat(m)),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format(makeFormat(m)),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\n// Monday is the first day of the week.\n// The week that contains Jan 1st is the first week of the year.\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2011, 11, 26]).format('w ww wo'), '1 01 1.', 'Dec 26 2011 should be week 1');\n    assert.equal(moment([2012,  0,  1]).format('w ww wo'), '1 01 1.', 'Jan  1 2012 should be week 1');\n    assert.equal(moment([2012,  0,  2]).format('w ww wo'), '2 02 2.', 'Jan  2 2012 should be week 2');\n    assert.equal(moment([2012,  0,  8]).format('w ww wo'), '2 02 2.', 'Jan  8 2012 should be week 2');\n    assert.equal(moment([2012,  0,  9]).format('w ww wo'), '3 03 3.', 'Jan  9 2012 should be week 3');\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\n\n\nfunction localeModule (name, lifecycle) {\n    QUnit.module('locale:' + name, {\n        setup : function () {\n            moment.locale(name);\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            moment.locale('en');\n            teardownDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n    defineCommonLocaleTests(name, -1, -1);\n}\n\nlocaleModule('mi');\n\ntest('parse', function (assert) {\n    var tests = 'Kohi-tāte Kohi_Hui-tanguru Hui_Poutū-te-rangi Pou_Paenga-whāwhā Pae_Haratua Hara_Pipiri Pipi_Hōngoingoi Hōngoi_Here-turi-kōkā Here_Mahuru Mahu_Whiringa-ā-nuku Whi-nu_Whiringa-ā-rangi Whi-ra_Hakihea Haki'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, MMMM Do YYYY, h:mm:ss a',      'Rātapu, Hui-tanguru 14º 2010, 3:25:50 pm'],\n            ['ddd, hA',                            'Ta, 3PM'],\n            ['M Mo MM MMMM MMM',                   '2 2º 02 Hui-tanguru Hui'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14º 14'],\n            ['d do dddd ddd dd',                   '0 0º Rātapu Ta Ta'],\n            ['DDD DDDo DDDD',                      '45 45º 045'],\n            ['w wo ww',                            '6 6º 06'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'pm PM'],\n            ['[the] DDDo [day of the year]',       'the 45º day of the year'],\n            ['LTS',                                '15:25:50'],\n            ['L',                                  '14/02/2010'],\n            ['LL',                                 '14 Hui-tanguru 2010'],\n            ['LLL',                                '14 Hui-tanguru 2010 i 15:25'],\n            ['LLLL',                               'Rātapu, 14 Hui-tanguru 2010 i 15:25'],\n            ['l',                                  '14/2/2010'],\n            ['ll',                                 '14 Hui 2010'],\n            ['lll',                                '14 Hui 2010 i 15:25'],\n            ['llll',                               'Ta, 14 Hui 2010 i 15:25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1º', '1º');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2º', '2º');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3º', '3º');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4º', '4º');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5º', '5º');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6º', '6º');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7º', '7º');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8º', '8º');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9º', '9º');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10º', '10º');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11º', '11º');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12º', '12º');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13º', '13º');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14º', '14º');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15º', '15º');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16º', '16º');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17º', '17º');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18º', '18º');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19º', '19º');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20º', '20º');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21º', '21º');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22º', '22º');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23º', '23º');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24º', '24º');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25º', '25º');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26º', '26º');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27º', '27º');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28º', '28º');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29º', '29º');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30º', '30º');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31º', '31º');\n});\n\ntest('format month', function (assert) {\n    var expected = 'Kohi-tāte Kohi_Hui-tanguru Hui_Poutū-te-rangi Pou_Paenga-whāwhā Pae_Haratua Hara_Pipiri Pipi_Hōngoingoi Hōngoi_Here-turi-kōkā Here_Mahuru Mahu_Whiringa-ā-nuku Whi-nu_Whiringa-ā-rangi Whi-ra_Hakihea Haki'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'Rātapu Ta Ta_Mane Ma Ma_Tūrei Tū Tū_Wenerei We We_Tāite Tāi Tāi_Paraire Pa Pa_Hātarei Hā Hā'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'te hēkona ruarua', '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'he meneti',        '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'he meneti',        '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 meneti',         '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 meneti',        '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'te haora',         '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'te haora',         '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 haora',          '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 haora',          '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 haora',         '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'he ra',            '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'he ra',            '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 ra',             '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'he ra',            '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 ra',             '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 ra',            '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'he marama',        '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'he marama',        '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'he marama',        '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 marama',         '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 marama',         '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 marama',         '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'he marama',         '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 marama',         '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'he tau',           '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 tau',            '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'he tau',           '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 tau',            '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'i roto i te hēkona ruarua',  'prefix');\n    assert.equal(moment(0).from(30000), 'te hēkona ruarua i mua', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'te hēkona ruarua i mua',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'i roto i te hēkona ruarua', 'in a few seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), 'i roto i 5 ra', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'i teie mahana, i 12:00', 'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'i teie mahana, i 12:25', 'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'i teie mahana, i 13:00', 'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'apopo i 12:00',       'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'i teie mahana, i 11:00', 'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'inanahi i 12:00',     'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('dddd [i] LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd [i] LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd [i] LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('dddd [whakamutunga i] LT'), 'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd [whakamutunga i] LT'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd [whakamutunga i] LT'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2012, 0,  1]).format('w ww wo'), '52 52 52º', 'Jan  1 2012 should be week 52');\n    assert.equal(moment([2012, 0,  2]).format('w ww wo'),   '1 01 1º', 'Jan  2 2012 should be week 1');\n    assert.equal(moment([2012, 0,  8]).format('w ww wo'),   '1 01 1º', 'Jan  8 2012 should be week 1');\n    assert.equal(moment([2012, 0,  9]).format('w ww wo'),   '2 02 2º', 'Jan  9 2012 should be week 2');\n    assert.equal(moment([2012, 0, 15]).format('w ww wo'),   '2 02 2º', 'Jan 15 2012 should be week 2');\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\n\n\nfunction localeModule (name, lifecycle) {\n    QUnit.module('locale:' + name, {\n        setup : function () {\n            moment.locale(name);\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            moment.locale('en');\n            teardownDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n    defineCommonLocaleTests(name, -1, -1);\n}\n\nlocaleModule('mk');\n\ntest('parse', function (assert) {\n    var tests = 'јануари јан_февруари фев_март мар_април апр_мај мај_јуни јун_јули јул_август авг_септември сеп_октомври окт_ноември ное_декември дек'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, MMMM Do YYYY, H:mm:ss',        'недела, февруари 14-ти 2010, 15:25:50'],\n            ['ddd, hA',                            'нед, 3PM'],\n            ['M Mo MM MMMM MMM',                   '2 2-ри 02 февруари фев'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14-ти 14'],\n            ['d do dddd ddd dd',                   '0 0-ев недела нед нe'],\n            ['DDD DDDo DDDD',                      '45 45-ти 045'],\n            ['w wo ww',                            '7 7-ми 07'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'pm PM'],\n            ['[the] DDDo [day of the year]',       'the 45-ти day of the year'],\n            ['LTS',                                '15:25:50'],\n            ['L',                                  '14.02.2010'],\n            ['LL',                                 '14 февруари 2010'],\n            ['LLL',                                '14 февруари 2010 15:25'],\n            ['LLLL',                               'недела, 14 февруари 2010 15:25'],\n            ['l',                                  '14.2.2010'],\n            ['ll',                                 '14 фев 2010'],\n            ['lll',                                '14 фев 2010 15:25'],\n            ['llll',                               'нед, 14 фев 2010 15:25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1-ви', '1-ви');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2-ри', '2-ри');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3-ти', '3-ти');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4-ти', '4-ти');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5-ти', '5-ти');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6-ти', '6-ти');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7-ми', '7-ми');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8-ми', '8-ми');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9-ти', '9-ти');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10-ти', '10-ти');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11-ти', '11-ти');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12-ти', '12-ти');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13-ти', '13-ти');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14-ти', '14-ти');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15-ти', '15-ти');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16-ти', '16-ти');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17-ти', '17-ти');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18-ти', '18-ти');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19-ти', '19-ти');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20-ти', '20-ти');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21-ви', '21-ви');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22-ри', '22-ри');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23-ти', '23-ти');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24-ти', '24-ти');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25-ти', '25-ти');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26-ти', '26-ти');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27-ми', '27-ми');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28-ми', '28-ми');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29-ти', '29-ти');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30-ти', '30-ти');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31-ви', '31-ви');\n});\n\ntest('format month', function (assert) {\n    var expected = 'јануари јан_февруари фев_март мар_април апр_мај мај_јуни јун_јули јул_август авг_септември сеп_октомври окт_ноември ное_декември дек'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'недела нед нe_понеделник пон пo_вторник вто вт_среда сре ср_четврток чет че_петок пет пе_сабота саб сa'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'неколку секунди', '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'минута',          '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'минута',          '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 минути',        '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 минути',       '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'час',             '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'час',             '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 часа',          '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 часа',          '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 часа',         '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'ден',             '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'ден',             '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 дена',          '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'ден',             '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 дена',          '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 дена',         '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'месец',           '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'месец',           '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'месец',           '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 месеци',        '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 месеци',        '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 месеци',        '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'месец',           '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 месеци',        '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'година',          '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 години',        '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'година',          '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 години',        '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'после неколку секунди', 'prefix');\n    assert.equal(moment(0).from(30000), 'пред неколку секунди',  'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'пред неколку секунди',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'после неколку секунди', 'in a few seconds');\n    assert.equal(moment().add({d: 5}).fromNow(),  'после 5 дена', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'Денес во 12:00',  'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'Денес во 12:25',  'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'Денес во 13:00',  'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'Утре во 12:00',   'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'Денес во 11:00',  'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'Вчера во 12:00',  'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('[Во] dddd [во] LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[Во] dddd [во] LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[Во] dddd [во] LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n\n    function makeFormat(d) {\n        switch (d.day()) {\n            case 0:\n            case 3:\n            case 6:\n                return '[Изминатата] dddd [во] LT';\n            case 1:\n            case 2:\n            case 4:\n            case 5:\n                return '[Изминатиот] dddd [во] LT';\n        }\n    }\n\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format(makeFormat(m)),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format(makeFormat(m)),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format(makeFormat(m)),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2011, 11, 26]).format('w ww wo'), '1 01 1-ви', 'Dec 26 2011 should be week 1');\n    assert.equal(moment([2012,  0,  1]).format('w ww wo'), '1 01 1-ви', 'Jan  1 2012 should be week 1');\n    assert.equal(moment([2012,  0,  2]).format('w ww wo'), '2 02 2-ри', 'Jan  2 2012 should be week 2');\n    assert.equal(moment([2012,  0,  8]).format('w ww wo'), '2 02 2-ри', 'Jan  8 2012 should be week 2');\n    assert.equal(moment([2012,  0,  9]).format('w ww wo'), '3 03 3-ти', 'Jan  9 2012 should be week 3');\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\n\n\nfunction localeModule (name, lifecycle) {\n    QUnit.module('locale:' + name, {\n        setup : function () {\n            moment.locale(name);\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            moment.locale('en');\n            teardownDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n    defineCommonLocaleTests(name, -1, -1);\n}\n\nlocaleModule('ml');\n\ntest('parse', function (assert) {\n    var tests = 'ജനുവരി ജനു._ഫെബ്രുവരി ഫെബ്രു._മാർച്ച് മാർ._ഏപ്രിൽ ഏപ്രി._മേയ് മേയ്_ജൂൺ ജൂൺ_ജൂലൈ ജൂലൈ._ഓഗസ്റ്റ് ഓഗ._സെപ്റ്റംബർ സെപ്റ്റ._ഒക്ടോബർ ഒക്ടോ._നവംബർ നവം._ഡിസംബർ ഡിസം.'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, Do MMMM YYYY, a h:mm:ss -നു',  'ഞായറാഴ്ച, 14 ഫെബ്രുവരി 2010, ഉച്ച കഴിഞ്ഞ് 3:25:50 -നു'],\n            ['ddd, a h -നു',                       'ഞായർ, ഉച്ച കഴിഞ്ഞ് 3 -നു'],\n            ['M Mo MM MMMM MMM',                   '2 2 02 ഫെബ്രുവരി ഫെബ്രു.'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14 14'],\n            ['d do dddd ddd dd',                   '0 0 ഞായറാഴ്ച ഞായർ ഞാ'],\n            ['DDD DDDo DDDD',                      '45 45 045'],\n            ['w wo ww',                            '8 8 08'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'ഉച്ച കഴിഞ്ഞ് ഉച്ച കഴിഞ്ഞ്'],\n            ['LTS',                                'ഉച്ച കഴിഞ്ഞ് 3:25:50 -നു'],\n            ['L',                                  '14/02/2010'],\n            ['LL',                                 '14 ഫെബ്രുവരി 2010'],\n            ['LLL',                                '14 ഫെബ്രുവരി 2010, ഉച്ച കഴിഞ്ഞ് 3:25 -നു'],\n            ['LLLL',                               'ഞായറാഴ്ച, 14 ഫെബ്രുവരി 2010, ഉച്ച കഴിഞ്ഞ് 3:25 -നു'],\n            ['l',                                  '14/2/2010'],\n            ['ll',                                 '14 ഫെബ്രു. 2010'],\n            ['lll',                                '14 ഫെബ്രു. 2010, ഉച്ച കഴിഞ്ഞ് 3:25 -നു'],\n            ['llll',                               'ഞായർ, 14 ഫെബ്രു. 2010, ഉച്ച കഴിഞ്ഞ് 3:25 -നു']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1', '1');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2', '2');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3', '3');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4', '4');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5', '5');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6', '6');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7', '7');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8', '8');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9', '9');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10', '10');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11', '11');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12', '12');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13', '13');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14', '14');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15', '15');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16', '16');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17', '17');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18', '18');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19', '19');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20', '20');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21', '21');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22', '22');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23', '23');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24', '24');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25', '25');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26', '26');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27', '27');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28', '28');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29', '29');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30', '30');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31', '31');\n});\n\ntest('format month', function (assert) {\n    var expected = 'ജനുവരി ജനു._ഫെബ്രുവരി ഫെബ്രു._മാർച്ച് മാർ._ഏപ്രിൽ ഏപ്രി._മേയ് മേയ്_ജൂൺ ജൂൺ_ജൂലൈ ജൂലൈ._ഓഗസ്റ്റ് ഓഗ._സെപ്റ്റംബർ സെപ്റ്റ._ഒക്ടോബർ ഒക്ടോ._നവംബർ നവം._ഡിസംബർ ഡിസം.'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'ഞായറാഴ്ച ഞായർ ഞാ_തിങ്കളാഴ്ച തിങ്കൾ തി_ചൊവ്വാഴ്ച ചൊവ്വ ചൊ_ബുധനാഴ്ച ബുധൻ ബു_വ്യാഴാഴ്ച വ്യാഴം വ്യാ_വെള്ളിയാഴ്ച വെള്ളി വെ_ശനിയാഴ്ച ശനി ശ'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'അൽപ നിമിഷങ്ങൾ', '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'ഒരു മിനിറ്റ്',      '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'ഒരു മിനിറ്റ്',      '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 മിനിറ്റ്',     '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 മിനിറ്റ്',    '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'ഒരു മണിക്കൂർ',       '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'ഒരു മണിക്കൂർ',       '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 മണിക്കൂർ',       '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 മണിക്കൂർ',       '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 മണിക്കൂർ',      '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'ഒരു ദിവസം',         '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'ഒരു ദിവസം',         '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 ദിവസം',        '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'ഒരു ദിവസം',         '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 ദിവസം',        '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 ദിവസം',       '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'ഒരു മാസം',       '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'ഒരു മാസം',       '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'ഒരു മാസം',       '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 മാസം',      '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 മാസം',      '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 മാസം',      '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'ഒരു മാസം',       '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 മാസം',      '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'ഒരു വർഷം',        '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 വർഷം',       '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'ഒരു വർഷം',        '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 വർഷം',       '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'അൽപ നിമിഷങ്ങൾ കഴിഞ്ഞ്',  'prefix');\n    assert.equal(moment(0).from(30000), 'അൽപ നിമിഷങ്ങൾ മുൻപ്', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'അൽപ നിമിഷങ്ങൾ മുൻപ്',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'അൽപ നിമിഷങ്ങൾ കഴിഞ്ഞ്', 'അൽപ നിമിഷങ്ങൾ കഴിഞ്ഞ്');\n    assert.equal(moment().add({d: 5}).fromNow(), '5 ദിവസം കഴിഞ്ഞ്', '5 ദിവസം കഴിഞ്ഞ്');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'ഇന്ന് ഉച്ച കഴിഞ്ഞ് 12:00 -നു',   'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'ഇന്ന് ഉച്ച കഴിഞ്ഞ് 12:25 -നു',   'Now plus 25 min');\n    assert.equal(moment(a).add({h: 3}).calendar(),       'ഇന്ന് ഉച്ച കഴിഞ്ഞ് 3:00 -നു',    'Now plus 3 hours');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'നാളെ ഉച്ച കഴിഞ്ഞ് 12:00 -നു',    'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'ഇന്ന് രാവിലെ 11:00 -നു',         'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'ഇന്നലെ ഉച്ച കഴിഞ്ഞ് 12:00 -നു',  'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('dddd[,] LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd[,] LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd[,] LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('[കഴിഞ്ഞ] dddd[,] LT'),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[കഴിഞ്ഞ] dddd[,] LT'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[കഴിഞ്ഞ] dddd[,] LT'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('meridiem', function (assert) {\n    assert.equal(moment([2011, 2, 23,  2, 30]).format('a'), 'രാത്രി', 'before dawn');\n    assert.equal(moment([2011, 2, 23,  9, 30]).format('a'), 'രാവിലെ', 'morning');\n    assert.equal(moment([2011, 2, 23, 14, 30]).format('a'), 'ഉച്ച കഴിഞ്ഞ്', 'during day');\n    assert.equal(moment([2011, 2, 23, 17, 30]).format('a'), 'വൈകുന്നേരം', 'evening');\n    assert.equal(moment([2011, 2, 23, 19, 30]).format('a'), 'വൈകുന്നേരം', 'late evening');\n    assert.equal(moment([2011, 2, 23, 21, 20]).format('a'), 'രാത്രി', 'night');\n\n    assert.equal(moment([2011, 2, 23,  2, 30]).format('A'), 'രാത്രി', 'before dawn');\n    assert.equal(moment([2011, 2, 23,  9, 30]).format('A'), 'രാവിലെ', 'morning');\n    assert.equal(moment([2011, 2, 23, 14, 30]).format('A'), 'ഉച്ച കഴിഞ്ഞ്', ' during day');\n    assert.equal(moment([2011, 2, 23, 17, 30]).format('A'), 'വൈകുന്നേരം', 'evening');\n    assert.equal(moment([2011, 2, 23, 19, 30]).format('A'), 'വൈകുന്നേരം', 'late evening');\n    assert.equal(moment([2011, 2, 23, 21, 20]).format('A'), 'രാത്രി', 'night');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2012, 0,  1]).format('w ww wo'), '1 01 1', 'Jan  1 2012 should be week 1');\n    assert.equal(moment([2012, 0,  7]).format('w ww wo'), '1 01 1', 'Jan  7 2012 should be week 1');\n    assert.equal(moment([2012, 0,  8]).format('w ww wo'), '2 02 2', 'Jan  8 2012 should be week 2');\n    assert.equal(moment([2012, 0, 14]).format('w ww wo'), '2 02 2', 'Jan 14 2012 should be week 2');\n    assert.equal(moment([2012, 0, 15]).format('w ww wo'), '3 03 3', 'Jan 15 2012 should be week 3');\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\n\n\nfunction localeModule (name, lifecycle) {\n    QUnit.module('locale:' + name, {\n        setup : function () {\n            moment.locale(name);\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            moment.locale('en');\n            teardownDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n    defineCommonLocaleTests(name, -1, -1);\n}\n\nlocaleModule('mr');\n\ntest('parse', function (assert) {\n    var tests = 'जानेवारी जाने._फेब्रुवारी फेब्रु._मार्च मार्च._एप्रिल एप्रि._मे मे._जून जून._जुलै जुलै._ऑगस्ट ऑग._सप्टेंबर सप्टें._ऑक्टोबर ऑक्टो._नोव्हेंबर नोव्हें._डिसेंबर डिसें.'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, Do MMMM YYYY, a h:mm:ss वाजता', 'रविवार, १४ फेब्रुवारी २०१०, दुपारी ३:२५:५० वाजता'],\n            ['ddd, a h वाजता',                       'रवि, दुपारी ३ वाजता'],\n            ['M Mo MM MMMM MMM',                   '२ २ ०२ फेब्रुवारी फेब्रु.'],\n            ['YYYY YY',                            '२०१० १०'],\n            ['D Do DD',                            '१४ १४ १४'],\n            ['d do dddd ddd dd',                   '० ० रविवार रवि र'],\n            ['DDD DDDo DDDD',                      '४५ ४५ ०४५'],\n            ['w wo ww',                            '८ ८ ०८'],\n            ['h hh',                               '३ ०३'],\n            ['H HH',                               '१५ १५'],\n            ['m mm',                               '२५ २५'],\n            ['s ss',                               '५० ५०'],\n            ['a A',                                'दुपारी दुपारी'],\n            ['LTS',                                'दुपारी ३:२५:५० वाजता'],\n            ['L',                                  '१४/०२/२०१०'],\n            ['LL',                                 '१४ फेब्रुवारी २०१०'],\n            ['LLL',                                '१४ फेब्रुवारी २०१०, दुपारी ३:२५ वाजता'],\n            ['LLLL',                               'रविवार, १४ फेब्रुवारी २०१०, दुपारी ३:२५ वाजता'],\n            ['l',                                  '१४/२/२०१०'],\n            ['ll',                                 '१४ फेब्रु. २०१०'],\n            ['lll',                                '१४ फेब्रु. २०१०, दुपारी ३:२५ वाजता'],\n            ['llll',                               'रवि, १४ फेब्रु. २०१०, दुपारी ३:२५ वाजता']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '१', '१');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '२', '२');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '३', '३');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '४', '४');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '५', '५');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '६', '६');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '७', '७');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '८', '८');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '९', '९');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '१०', '१०');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '११', '११');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '१२', '१२');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '१३', '१३');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '१४', '१४');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '१५', '१५');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '१६', '१६');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '१७', '१७');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '१८', '१८');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '१९', '१९');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '२०', '२०');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '२१', '२१');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '२२', '२२');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '२३', '२३');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '२४', '२४');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '२५', '२५');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '२६', '२६');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '२७', '२७');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '२८', '२८');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '२९', '२९');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '३०', '३०');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '३१', '३१');\n});\n\ntest('format month', function (assert) {\n    var expected = 'जानेवारी जाने._फेब्रुवारी फेब्रु._मार्च मार्च._एप्रिल एप्रि._मे मे._जून जून._जुलै जुलै._ऑगस्ट ऑग._सप्टेंबर सप्टें._ऑक्टोबर ऑक्टो._नोव्हेंबर नोव्हें._डिसेंबर डिसें.'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'रविवार रवि र_सोमवार सोम सो_मंगळवार मंगळ मं_बुधवार बुध बु_गुरूवार गुरू गु_शुक्रवार शुक्र शु_शनिवार शनि श'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'काही सेकंद', '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'एक मिनिट',      '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'एक मिनिट',      '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '२ मिनिटे',     '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true), '४४ मिनिटे', '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'एक तास',       '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'एक तास',       '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '२ तास',       '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '५ तास',       '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '२१ तास',      '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'एक दिवस',         '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'एक दिवस',         '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '२ दिवस',        '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'एक दिवस',         '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '५ दिवस',        '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '२५ दिवस',       '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true), 'एक महिना', '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true), 'एक महिना', '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true), 'एक महिना', '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true), '२ महिने', '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true), '२ महिने', '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true), '३ महिने', '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true), 'एक महिना', '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true), '५ महिने', '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'एक वर्ष',        '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '२ वर्षे',       '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'एक वर्ष',        '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true), '५ वर्षे', '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'काही सेकंदांमध्ये', 'prefix');\n    assert.equal(moment(0).from(30000), 'काही सेकंदांपूर्वी', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'काही सेकंदांपूर्वी',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'काही सेकंदांमध्ये', 'in a few seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), '५ दिवसांमध्ये', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'आज दुपारी १२:०० वाजता',    'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'आज दुपारी १२:२५ वाजता',    'Now plus 25 min');\n    assert.equal(moment(a).add({h: 3}).calendar(),       'आज दुपारी ३:०० वाजता',     'Now plus 3 hours');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'उद्या दुपारी १२:०० वाजता', 'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'आज दुपारी ११:०० वाजता',    'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'काल दुपारी १२:०० वाजता',   'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('dddd[,] LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd[,] LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd[,] LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(), m.format('[मागील] dddd[,] LT'), 'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(), m.format('[मागील] dddd[,] LT'), 'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(), m.format('[मागील] dddd[,] LT'), 'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('meridiem', function (assert) {\n    assert.equal(moment([2011, 2, 23,  2, 30]).format('a'), 'रात्री', 'before dawn');\n    assert.equal(moment([2011, 2, 23,  9, 30]).format('a'), 'सकाळी', 'morning');\n    assert.equal(moment([2011, 2, 23, 14, 30]).format('a'), 'दुपारी', 'during day');\n    assert.equal(moment([2011, 2, 23, 17, 30]).format('a'), 'सायंकाळी', 'evening');\n    assert.equal(moment([2011, 2, 23, 19, 30]).format('a'), 'सायंकाळी', 'late evening');\n    assert.equal(moment([2011, 2, 23, 21, 20]).format('a'), 'रात्री', 'night');\n\n    assert.equal(moment([2011, 2, 23,  2, 30]).format('A'), 'रात्री', 'before dawn');\n    assert.equal(moment([2011, 2, 23,  9, 30]).format('A'), 'सकाळी', 'morning');\n    assert.equal(moment([2011, 2, 23, 14, 30]).format('A'), 'दुपारी', ' during day');\n    assert.equal(moment([2011, 2, 23, 17, 30]).format('A'), 'सायंकाळी', 'evening');\n    assert.equal(moment([2011, 2, 23, 19, 30]).format('A'), 'सायंकाळी', 'late evening');\n    assert.equal(moment([2011, 2, 23, 21, 20]).format('A'), 'रात्री', 'night');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2012, 0,  1]).format('w ww wo'), '१ ०१ १', 'Jan  1 2012 should be week 1');\n    assert.equal(moment([2012, 0,  7]).format('w ww wo'), '१ ०१ १', 'Jan  7 2012 should be week 1');\n    assert.equal(moment([2012, 0,  8]).format('w ww wo'), '२ ०२ २', 'Jan  8 2012 should be week 2');\n    assert.equal(moment([2012, 0, 14]).format('w ww wo'), '२ ०२ २', 'Jan 14 2012 should be week 2');\n    assert.equal(moment([2012, 0, 15]).format('w ww wo'), '३ ०३ ३', 'Jan 15 2012 should be week 3');\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\n\n\nfunction localeModule (name, lifecycle) {\n    QUnit.module('locale:' + name, {\n        setup : function () {\n            moment.locale(name);\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            moment.locale('en');\n            teardownDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n    defineCommonLocaleTests(name, -1, -1);\n}\n\nlocaleModule('ms-my');\n\ntest('parse', function (assert) {\n    var i,\n        tests = 'Januari Jan_Februari Feb_Mac Mac_April Apr_Mei Mei_Jun Jun_Julai Jul_Ogos Ogs_September Sep_Oktober Okt_November Nov_Disember Dis'.split('_');\n\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' sepatutnya bulan ' + (i + 1));\n    }\n\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, MMMM Do YYYY, h:mm:ss a',      'Ahad, Februari 14 2010, 3:25:50 petang'],\n            ['ddd, hA',                            'Ahd, 3petang'],\n            ['M Mo MM MMMM MMM',                   '2 2 02 Februari Feb'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14 14'],\n            ['d do dddd ddd dd',                   '0 0 Ahad Ahd Ah'],\n            ['DDD DDDo DDDD',                      '45 45 045'],\n            ['w wo ww',                            '7 7 07'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'petang petang'],\n            ['[hari] [ke] DDDo [tahun] ini', 'hari ke 45 tahun ini'],\n            ['LTS',                                '15.25.50'],\n            ['L',                                  '14/02/2010'],\n            ['LL',                                 '14 Februari 2010'],\n            ['LLL',                                '14 Februari 2010 pukul 15.25'],\n            ['LLLL',                               'Ahad, 14 Februari 2010 pukul 15.25'],\n            ['l',                                  '14/2/2010'],\n            ['ll',                                 '14 Feb 2010'],\n            ['lll',                                '14 Feb 2010 pukul 15.25'],\n            ['llll',                               'Ahd, 14 Feb 2010 pukul 15.25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1', '1');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2', '2');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3', '3');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4', '4');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5', '5');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6', '6');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7', '7');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8', '8');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9', '9');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10', '10');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11', '11');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12', '12');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13', '13');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14', '14');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15', '15');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16', '16');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17', '17');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18', '18');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19', '19');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20', '20');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21', '21');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22', '22');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23', '23');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24', '24');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25', '25');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26', '26');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27', '27');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28', '28');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29', '29');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30', '30');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31', '31');\n});\n\ntest('format month', function (assert) {\n    var i,\n        expected = 'Januari Jan_Februari Feb_Mac Mac_April Apr_Mei Mei_Jun Jun_Julai Jul_Ogos Ogs_September Sep_Oktober Okt_November Nov_Disember Dis'.split('_');\n\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var i,\n        expected = 'Ahad Ahd Ah_Isnin Isn Is_Selasa Sel Sl_Rabu Rab Rb_Khamis Kha Km_Jumaat Jum Jm_Sabtu Sab Sb'.split('_');\n\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'beberapa saat', '44 saat = beberapa saat');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'seminit',      '45 saat = seminit');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'seminit',      '89 saat = seminit');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 minit',     '90 saat = 2 minit');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 minit',    '44 minit = 44 minit');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'sejam',       '45 minit = sejam');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'sejam',       '89 minit = sejam');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 jam',       '90 minit = 2 jam');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 jam',       '5 jam = 5 jam');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 jam',      '21 jam = 21 jam');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'sehari',         '22 jam = sehari');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'sehari',         '35 jam = sehari');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 hari',        '36 jam = 2 hari');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'sehari',         '1 hari = sehari');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 hari',        '5 hari = 5 hari');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 hari',       '25 hari = 25 hari');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'sebulan',       '26 hari = sebulan');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'sebulan',       '30 hari = sebulan');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'sebulan',       '45 hari = sebulan');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 bulan',      '46 hari = 2 bulan');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 bulan',      '75 hari = 2 bulan');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 bulan',      '76 hari = 3 bulan');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'sebulan',       '1 bulan = sebulan');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 bulan',      '5 bulan = 5 bulan');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'setahun',        '345 hari = setahun');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 tahun',       '548 hari = 2 tahun');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'setahun',        '1 tahun = setahun');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 tahun',       '5 tahun = 5 tahun');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'dalam beberapa saat',  'prefix');\n    assert.equal(moment(0).from(30000), 'beberapa saat yang lepas', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'beberapa saat yang lepas',  'waktu sekarang dari sekarang sepatutnya menunjukkan sebagai telah lepas');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'dalam beberapa saat', 'dalam beberapa saat');\n    assert.equal(moment().add({d: 5}).fromNow(), 'dalam 5 hari', 'dalam 5 hari');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'Hari ini pukul 12.00',  'hari ini pada waktu yang sama');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'Hari ini pukul 12.25',  'Sekarang tambah 25 minit');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'Hari ini pukul 13.00',  'Sekarang tambah 1 jam');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'Esok pukul 12.00',      'esok pada waktu yang sama');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'Hari ini pukul 11.00',  'Sekarang tolak 1 jam');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'Kelmarin pukul 12.00',  'kelmarin pada waktu yang sama');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('dddd [pukul] LT'),  'Hari ini + ' + i + ' hari waktu sekarang');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd [pukul] LT'),  'Hari ini + ' + i + ' hari permulaan hari');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd [pukul] LT'),  'Hari ini + ' + i + ' hari tamat hari');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('dddd [lepas] [pukul] LT'),  'Hari ini - ' + i + ' hari waktu sekarang');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd [lepas] [pukul] LT'),  'Hari ini - ' + i + ' hari permulaan hari');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd [lepas] [pukul] LT'),  'Hari ini - ' + i + ' hari tamat hari');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 minggu lepas');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'dalam 1 minggu');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 minggu lepas');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'dalam 2 minggu');\n});\n\ntest('weeks year starting sunday format', function (assert) {\n    assert.equal(moment([2012, 0,  1]).format('w ww wo'), '1 01 1', 'Jan  1 2012 sepatutnya minggu 1');\n    assert.equal(moment([2012, 0,  7]).format('w ww wo'), '2 02 2', 'Jan  7 2012 sepatutnya minggu 2');\n    assert.equal(moment([2012, 0,  8]).format('w ww wo'), '2 02 2', 'Jan  8 2012 sepatutnya minggu 2');\n    assert.equal(moment([2012, 0, 14]).format('w ww wo'), '3 03 3', 'Jan 14 2012 sepatutnya minggu 3');\n    assert.equal(moment([2012, 0, 15]).format('w ww wo'), '3 03 3', 'Jan 15 2012 sepatutnya minggu 3');\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\n\n\nfunction localeModule (name, lifecycle) {\n    QUnit.module('locale:' + name, {\n        setup : function () {\n            moment.locale(name);\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            moment.locale('en');\n            teardownDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n    defineCommonLocaleTests(name, -1, -1);\n}\n\nlocaleModule('ms');\n\ntest('parse', function (assert) {\n    var i,\n        tests = 'Januari Jan_Februari Feb_Mac Mac_April Apr_Mei Mei_Jun Jun_Julai Jul_Ogos Ogs_September Sep_Oktober Okt_November Nov_Disember Dis'.split('_');\n\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' sepatutnya bulan ' + (i + 1));\n    }\n\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, MMMM Do YYYY, h:mm:ss a',      'Ahad, Februari 14 2010, 3:25:50 petang'],\n            ['ddd, hA',                            'Ahd, 3petang'],\n            ['M Mo MM MMMM MMM',                   '2 2 02 Februari Feb'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14 14'],\n            ['d do dddd ddd dd',                   '0 0 Ahad Ahd Ah'],\n            ['DDD DDDo DDDD',                      '45 45 045'],\n            ['w wo ww',                            '7 7 07'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'petang petang'],\n            ['[hari] [ke] DDDo [tahun] ini', 'hari ke 45 tahun ini'],\n            ['LTS',                                '15.25.50'],\n            ['L',                                  '14/02/2010'],\n            ['LL',                                 '14 Februari 2010'],\n            ['LLL',                                '14 Februari 2010 pukul 15.25'],\n            ['LLLL',                               'Ahad, 14 Februari 2010 pukul 15.25'],\n            ['l',                                  '14/2/2010'],\n            ['ll',                                 '14 Feb 2010'],\n            ['lll',                                '14 Feb 2010 pukul 15.25'],\n            ['llll',                               'Ahd, 14 Feb 2010 pukul 15.25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1', '1');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2', '2');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3', '3');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4', '4');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5', '5');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6', '6');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7', '7');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8', '8');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9', '9');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10', '10');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11', '11');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12', '12');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13', '13');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14', '14');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15', '15');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16', '16');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17', '17');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18', '18');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19', '19');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20', '20');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21', '21');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22', '22');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23', '23');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24', '24');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25', '25');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26', '26');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27', '27');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28', '28');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29', '29');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30', '30');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31', '31');\n});\n\ntest('format month', function (assert) {\n    var i,\n        expected = 'Januari Jan_Februari Feb_Mac Mac_April Apr_Mei Mei_Jun Jun_Julai Jul_Ogos Ogs_September Sep_Oktober Okt_November Nov_Disember Dis'.split('_');\n\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var i,\n        expected = 'Ahad Ahd Ah_Isnin Isn Is_Selasa Sel Sl_Rabu Rab Rb_Khamis Kha Km_Jumaat Jum Jm_Sabtu Sab Sb'.split('_');\n\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'beberapa saat', '44 saat = beberapa saat');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'seminit',      '45 saat = seminit');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'seminit',      '89 saat = seminit');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 minit',     '90 saat = 2 minit');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 minit',    '44 minit = 44 minit');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'sejam',       '45 minit = sejam');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'sejam',       '89 minit = sejam');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 jam',       '90 minit = 2 jam');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 jam',       '5 jam = 5 jam');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 jam',      '21 jam = 21 jam');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'sehari',         '22 jam = sehari');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'sehari',         '35 jam = sehari');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 hari',        '36 jam = 2 hari');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'sehari',         '1 hari = sehari');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 hari',        '5 hari = 5 hari');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 hari',       '25 hari = 25 hari');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'sebulan',       '26 hari = sebulan');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'sebulan',       '30 hari = sebulan');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'sebulan',       '45 hari = sebulan');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 bulan',      '46 hari = 2 bulan');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 bulan',      '75 hari = 2 bulan');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 bulan',      '76 hari = 3 bulan');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'sebulan',       '1 bulan = sebulan');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 bulan',      '5 bulan = 5 bulan');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'setahun',        '345 hari = setahun');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 tahun',       '548 hari = 2 tahun');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'setahun',        '1 tahun = setahun');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 tahun',       '5 tahun = 5 tahun');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'dalam beberapa saat',  'prefix');\n    assert.equal(moment(0).from(30000), 'beberapa saat yang lepas', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'beberapa saat yang lepas',  'waktu sekarang dari sekarang sepatutnya menunjukkan sebagai telah lepas');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'dalam beberapa saat', 'dalam beberapa saat');\n    assert.equal(moment().add({d: 5}).fromNow(), 'dalam 5 hari', 'dalam 5 hari');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'Hari ini pukul 12.00',  'hari ini pada waktu yang sama');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'Hari ini pukul 12.25',  'Sekarang tambah 25 minit');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'Hari ini pukul 13.00',  'Sekarang tambah 1 jam');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'Esok pukul 12.00',      'esok pada waktu yang sama');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'Hari ini pukul 11.00',  'Sekarang tolak 1 jam');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'Kelmarin pukul 12.00',  'kelmarin pada waktu yang sama');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('dddd [pukul] LT'),  'Hari ini + ' + i + ' hari waktu sekarang');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd [pukul] LT'),  'Hari ini + ' + i + ' hari permulaan hari');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd [pukul] LT'),  'Hari ini + ' + i + ' hari tamat hari');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('dddd [lepas] [pukul] LT'),  'Hari ini - ' + i + ' hari waktu sekarang');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd [lepas] [pukul] LT'),  'Hari ini - ' + i + ' hari permulaan hari');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd [lepas] [pukul] LT'),  'Hari ini - ' + i + ' hari tamat hari');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 minggu lepas');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'dalam 1 minggu');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 minggu lepas');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'dalam 2 minggu');\n});\n\ntest('weeks year starting sunday format', function (assert) {\n    assert.equal(moment([2012, 0,  1]).format('w ww wo'), '1 01 1', 'Jan  1 2012 sepatutnya minggu 1');\n    assert.equal(moment([2012, 0,  7]).format('w ww wo'), '2 02 2', 'Jan  7 2012 sepatutnya minggu 2');\n    assert.equal(moment([2012, 0,  8]).format('w ww wo'), '2 02 2', 'Jan  8 2012 sepatutnya minggu 2');\n    assert.equal(moment([2012, 0, 14]).format('w ww wo'), '3 03 3', 'Jan 14 2012 sepatutnya minggu 3');\n    assert.equal(moment([2012, 0, 15]).format('w ww wo'), '3 03 3', 'Jan 15 2012 sepatutnya minggu 3');\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\n\n\nfunction localeModule (name, lifecycle) {\n    QUnit.module('locale:' + name, {\n        setup : function () {\n            moment.locale(name);\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            moment.locale('en');\n            teardownDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n    defineCommonLocaleTests(name, -1, -1);\n}\n\nlocaleModule('my');\n\ntest('parse', function (assert) {\n    var tests = 'ဇန်နဝါရီ ဇန်_ဖေဖော်ဝါရီ ဖေ_မတ် မတ်_ဧပြီ ပြီ_မေ မေ_ဇွန် ဇွန်_ဇူလိုင် လိုင်_သြဂုတ် သြ_စက်တင်ဘာ စက်_အောက်တိုဘာ အောက်_နိုဝင်ဘာ နို_ဒီဇင်ဘာ ဒီ'.split('_'),\n        i;\n\n    function equalTest (input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, MMMM Do YYYY, h:mm:ss a', 'တနင်္ဂနွေ, ဖေဖော်ဝါရီ ၁၄ ၂၀၁၀, ၃:၂၅:၅၀ pm'],\n            ['ddd, hA', 'နွေ, ၃PM'],\n            ['M Mo MM MMMM MMM', '၂ ၂ ၀၂ ဖေဖော်ဝါရီ ဖေ'],\n            ['YYYY YY', '၂၀၁၀ ၁၀'],\n            ['D Do DD', '၁၄ ၁၄ ၁၄'],\n            ['d do dddd ddd dd', '၀ ၀ တနင်္ဂနွေ နွေ နွေ'],\n            ['DDD DDDo DDDD', '၄၅ ၄၅ ၀၄၅'],\n            ['w wo ww', '၆ ၆ ၀၆'],\n            ['h hh', '၃ ၀၃'],\n            ['H HH', '၁၅ ၁၅'],\n            ['m mm', '၂၅ ၂၅'],\n            ['s ss', '၅၀ ၅၀'],\n            ['a A', 'pm PM'],\n            ['[နှစ်၏] DDDo [ရက်မြောက်]', 'နှစ်၏ ၄၅ ရက်မြောက်'],\n            ['LTS', '၁၅:၂၅:၅၀'],\n            ['L', '၁၄/၀၂/၂၀၁၀'],\n            ['LL', '၁၄ ဖေဖော်ဝါရီ ၂၀၁၀'],\n            ['LLL', '၁၄ ဖေဖော်ဝါရီ ၂၀၁၀ ၁၅:၂၅'],\n            ['LLLL', 'တနင်္ဂနွေ ၁၄ ဖေဖော်ဝါရီ ၂၀၁၀ ၁၅:၂၅'],\n            ['l', '၁၄/၂/၂၀၁၀'],\n            ['ll', '၁၄ ဖေ ၂၀၁၀'],\n            ['lll', '၁၄ ဖေ ၂၀၁၀ ၁၅:၂၅'],\n            ['llll', 'နွေ ၁၄ ဖေ ၂၀၁၀ ၁၅:၂၅']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '၁', '၁');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '၂', '၂');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '၃', '၃');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '၄', '၄');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '၅', '၅');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '၆', '၆');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '၇', '၇');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '၈', '၈');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '၉', '၉');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '၁၀', '၁၀');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '၁၁', '၁၁');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '၁၂', '၁၂');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '၁၃', '၁၃');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '၁၄', '၁၄');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '၁၅', '၁၅');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '၁၆', '၁၆');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '၁၇', '၁၇');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '၁၈', '၁၈');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '၁၉', '၁၉');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '၂၀', '၂၀');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '၂၁', '၂၁');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '၂၂', '၂၂');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '၂၃', '၂၃');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '၂၄', '၂၄');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '၂၅', '၂၅');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '၂၆', '၂၆');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '၂၇', '၂၇');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '၂၈', '၂၈');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '၂၉', '၂၉');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '၃၀', '၃၀');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '၃၁', '၃၁');\n});\n\ntest('format month', function (assert) {\n    var expected = 'ဇန်နဝါရီ ဇန်_ဖေဖော်ဝါရီ ဖေ_မတ် မတ်_ဧပြီ ပြီ_မေ မေ_ဇွန် ဇွန်_ဇူလိုင် လိုင်_သြဂုတ် သြ_စက်တင်ဘာ စက်_အောက်တိုဘာ အောက်_နိုဝင်ဘာ နို_ဒီဇင်ဘာ ဒီ'.split('_'),\n        i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'တနင်္ဂနွေ နွေ နွေ_တနင်္လာ လာ လာ_အင်္ဂါ ဂါ ဂါ_ဗုဒ္ဓဟူး ဟူး ဟူး_ကြာသပတေး ကြာ ကြာ_သောကြာ သော သော_စနေ နေ နေ'.split('_'),\n        i;\n\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({\n        s: 44\n    }), true), 'စက္ကန်.အနည်းငယ်', '၄၄ စက္ကန်. = စက္ကန်.အနည်းငယ်');\n    assert.equal(start.from(moment([2007, 1, 28]).add({\n        s: 45\n    }), true), 'တစ်မိနစ်', '၄၅ စက္ကန်. = တစ်မိနစ်');\n    assert.equal(start.from(moment([2007, 1, 28]).add({\n        s: 89\n    }), true), 'တစ်မိနစ်', '၈၉ စက္ကန်. = တစ်မိနစ်');\n    assert.equal(start.from(moment([2007, 1, 28]).add({\n        s: 90\n    }), true), '၂ မိနစ်', '၉၀ စက္ကန်. =  ၂ မိနစ်');\n    assert.equal(start.from(moment([2007, 1, 28]).add({\n        m: 44\n    }), true), '၄၄ မိနစ်', '၄၄ မိနစ် = ၄၄ မိနစ်');\n    assert.equal(start.from(moment([2007, 1, 28]).add({\n        m: 45\n    }), true), 'တစ်နာရီ', '၄၅ မိနစ် = ၁ နာရီ');\n    assert.equal(start.from(moment([2007, 1, 28]).add({\n        m: 89\n    }), true), 'တစ်နာရီ', '၈၉ မိနစ် = တစ်နာရီ');\n    assert.equal(start.from(moment([2007, 1, 28]).add({\n        m: 90\n    }), true), '၂ နာရီ', 'မိနစ် ၉၀= ၂ နာရီ');\n    assert.equal(start.from(moment([2007, 1, 28]).add({\n        h: 5\n    }), true), '၅ နာရီ', '၅ နာရီ= ၅ နာရီ');\n    assert.equal(start.from(moment([2007, 1, 28]).add({\n        h: 21\n    }), true), '၂၁ နာရီ', '၂၁ နာရီ =၂၁ နာရီ');\n    assert.equal(start.from(moment([2007, 1, 28]).add({\n        h: 22\n    }), true), 'တစ်ရက်', '၂၂ နာရီ =တစ်ရက်');\n    assert.equal(start.from(moment([2007, 1, 28]).add({\n        h: 35\n    }), true), 'တစ်ရက်', '၃၅ နာရီ =တစ်ရက်');\n    assert.equal(start.from(moment([2007, 1, 28]).add({\n        h: 36\n    }), true), '၂ ရက်', '၃၆ နာရီ = ၂ ရက်');\n    assert.equal(start.from(moment([2007, 1, 28]).add({\n        d: 1\n    }), true), 'တစ်ရက်', '၁ ရက်= တစ်ရက်');\n    assert.equal(start.from(moment([2007, 1, 28]).add({\n        d: 5\n    }), true), '၅ ရက်', '၅ ရက် = ၅ ရက်');\n    assert.equal(start.from(moment([2007, 1, 28]).add({\n        d: 25\n    }), true), '၂၅ ရက်', '၂၅ ရက်= ၂၅ ရက်');\n    assert.equal(start.from(moment([2007, 1, 28]).add({\n        d: 26\n    }), true), 'တစ်လ', '၂၆ ရက် = တစ်လ');\n    assert.equal(start.from(moment([2007, 1, 28]).add({\n        d: 30\n    }), true), 'တစ်လ', 'ရက် ၃၀ = တစ်လ');\n    assert.equal(start.from(moment([2007, 1, 28]).add({\n        d: 43\n    }), true), 'တစ်လ', '၄၃ ရက် = တစ်လ');\n    assert.equal(start.from(moment([2007, 1, 28]).add({\n        d: 46\n    }), true), '၂ လ', '၄၆ ရက် = ၂ လ');\n    assert.equal(start.from(moment([2007, 1, 28]).add({\n        d: 74\n    }), true), '၂ လ', '၇၅ ရက်= ၂ လ');\n    assert.equal(start.from(moment([2007, 1, 28]).add({\n        d: 76\n    }), true), '၃ လ', '၇၆ ရက် = ၃ လ');\n    assert.equal(start.from(moment([2007, 1, 28]).add({\n        M: 1\n    }), true), 'တစ်လ', '၁ လ = တစ်လ');\n    assert.equal(start.from(moment([2007, 1, 28]).add({\n        M: 5\n    }), true), '၅ လ', '၅ လ = ၅ လ');\n    assert.equal(start.from(moment([2007, 1, 28]).add({\n        d: 345\n    }), true), 'တစ်နှစ်', '၃၄၅ ရက် = တစ်နှစ်');\n    assert.equal(start.from(moment([2007, 1, 28]).add({\n        d: 548\n    }), true), '၂ နှစ်', '၅၄၈ ရက် = ၂ နှစ်');\n    assert.equal(start.from(moment([2007, 1, 28]).add({\n        y: 1\n    }), true), 'တစ်နှစ်', '၁ နှစ် = တစ်နှစ်');\n    assert.equal(start.from(moment([2007, 1, 28]).add({\n        y: 5\n    }), true), '၅ နှစ်', '၅ နှစ် = ၅ နှစ်');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'လာမည့် စက္ကန်.အနည်းငယ် မှာ', 'prefix');\n    assert.equal(moment(0).from(30000), 'လွန်ခဲ့သော စက္ကန်.အနည်းငယ် က', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'လွန်ခဲ့သော စက္ကန်.အနည်းငယ် က', 'ယခုမှစပြီး အတိတ်တွင်ဖော်ပြသလိုဖော်ပြမည်');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({\n        s: 30\n    }).fromNow(), 'လာမည့် စက္ကန်.အနည်းငယ် မှာ', 'လာမည့် စက္ကန်.အနည်းငယ် မှာ');\n    assert.equal(moment().add({\n        d: 5\n    }).fromNow(), 'လာမည့် ၅ ရက် မှာ', 'လာမည့် ၅ ရက် မှာ');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                  'ယနေ. ၁၂:၀၀ မှာ',      'ယနေ. ဒီအချိန်');\n    assert.equal(moment(a).add({m: 25}).calendar(),     'ယနေ. ၁၂:၂၅ မှာ',      'ယခုမှ ၂၅ မိနစ်ပေါင်းထည့်');\n    assert.equal(moment(a).add({h: 1}).calendar(),      'ယနေ. ၁၃:၀၀ မှာ',      'ယခုမှ ၁ နာရီပေါင်းထည့်');\n    assert.equal(moment(a).add({d: 1}).calendar(),      'မနက်ဖြန် ၁၂:၀၀ မှာ',  'မနက်ဖြန် ဒီအချိန်');\n    assert.equal(moment(a).subtract({h: 1}).calendar(), 'ယနေ. ၁၁:၀၀ မှာ',      'ယခုမှ ၁ နာရီနှုတ်');\n    assert.equal(moment(a).subtract({d: 1}).calendar(), 'မနေ.က ၁၂:၀၀ မှာ',     'မနေ.က ဒီအချိန်');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({\n            d: i\n        });\n        assert.equal(m.calendar(), m.format('dddd LT [မှာ]'), 'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(), m.format('dddd LT [မှာ]'), 'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(), m.format('dddd LT [မှာ]'), 'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({\n            d: i\n        });\n        assert.equal(m.calendar(), m.format('[ပြီးခဲ့သော] dddd LT [မှာ]'), 'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(), m.format('[ပြီးခဲ့သော] dddd LT [မှာ]'), 'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(), m.format('[ပြီးခဲ့သော] dddd LT [မှာ]'), 'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({\n            w: 1\n        }),\n        weeksFromNow = moment().add({\n            w: 1\n        });\n\n    assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), 'လွန်ခဲ့သော ၁ ပတ်က');\n    assert.equal(weeksFromNow.calendar(), weeksFromNow.format('L'), '၁ ပတ်အတွင်း');\n\n    weeksAgo = moment().subtract({\n        w: 2\n    });\n    weeksFromNow = moment().add({\n        w: 2\n    });\n\n    assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '၂ ပတ် အရင်က');\n    assert.equal(weeksFromNow.calendar(), weeksFromNow.format('L'), '၂ ပတ် အတွင်း');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2012, 0, 1]).format('w ww wo'), '၅၂ ၅၂ ၅၂', 'Jan  1 2012 should be week 52');\n    assert.equal(moment([2012, 0, 2]).format('w ww wo'), '၁ ၀၁ ၁', 'Jan  2 2012 should be week 1');\n    assert.equal(moment([2012, 0, 8]).format('w ww wo'), '၁ ၀၁ ၁', 'Jan  8 2012 should be week 1');\n    assert.equal(moment([2012, 0, 9]).format('w ww wo'), '၂ ၀၂ ၂', 'Jan  9 2012 should be week 2');\n    assert.equal(moment([2012, 0, 15]).format('w ww wo'), '၂ ၀၂ ၂', 'Jan 15 2012 should be week 2');\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\n\n\nfunction localeModule (name, lifecycle) {\n    QUnit.module('locale:' + name, {\n        setup : function () {\n            moment.locale(name);\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            moment.locale('en');\n            teardownDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n    defineCommonLocaleTests(name, -1, -1);\n}\n\nlocaleModule('nb');\n\ntest('parse', function (assert) {\n    var tests = 'januar jan._februar feb._mars mars_april april_mai mai_juni juni_juli juli_august aug._september sep._oktober okt._november nov._desember des.'.split('_'),\n        i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, MMMM Do YYYY, h:mm:ss a',      'søndag, februar 14. 2010, 3:25:50 pm'],\n            ['ddd, hA',                            'sø., 3PM'],\n            ['M Mo MM MMMM MMM',                   '2 2. 02 februar feb.'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14. 14'],\n            ['d do dddd ddd dd',                   '0 0. søndag sø. sø'],\n            ['DDD DDDo DDDD',                      '45 45. 045'],\n            ['w wo ww',                            '6 6. 06'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'pm PM'],\n            ['[den] DDDo [dagen i året]',          'den 45. dagen i året'],\n            ['LTS',                                '15:25:50'],\n            ['L',                                  '14.02.2010'],\n            ['LL',                                 '14. februar 2010'],\n            ['LLL',                                '14. februar 2010 kl. 15:25'],\n            ['LLLL',                               'søndag 14. februar 2010 kl. 15:25'],\n            ['l',                                  '14.2.2010'],\n            ['ll',                                 '14. feb. 2010'],\n            ['lll',                                '14. feb. 2010 kl. 15:25'],\n            ['llll',                               'sø. 14. feb. 2010 kl. 15:25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1.', '1.');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2.', '2.');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3.', '3.');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4.', '4.');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5.', '5.');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6.', '6.');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7.', '7.');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8.', '8.');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9.', '9.');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10.', '10.');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11.', '11.');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12.', '12.');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13.', '13.');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14.', '14.');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15.', '15.');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16.', '16.');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17.', '17.');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18.', '18.');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19.', '19.');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20.', '20.');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21.', '21.');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22.', '22.');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23.', '23.');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24.', '24.');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25.', '25.');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26.', '26.');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27.', '27.');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28.', '28.');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29.', '29.');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30.', '30.');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31.', '31.');\n});\n\ntest('format month', function (assert) {\n    var expected = 'januar jan._februar feb._mars mars_april april_mai mai_juni juni_juli juli_august aug._september sep._oktober okt._november nov._desember des.'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'søndag sø. sø_mandag ma. ma_tirsdag ti. ti_onsdag on. on_torsdag to. to_fredag fr. fr_lørdag lø. lø'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'noen sekunder', '44 sekunder = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'ett minutt',      '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'ett minutt',      '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 minutter',     '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 minutter',    '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'en time',       '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'en time',       '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 timer',       '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 timer',       '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 timer',      '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'en dag',         '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'en dag',         '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 dager',        '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'en dag',         '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 dager',        '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 dager',       '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'en måned',       '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'en måned',       '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'en måned',       '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 måneder',      '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 måneder',      '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 måneder',      '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'en måned',       '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 måneder',      '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'ett år',        '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 år',       '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'ett år',        '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 år',       '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'om noen sekunder',  'prefix');\n    assert.equal(moment(0).from(30000), 'noen sekunder siden', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'noen sekunder siden',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'om noen sekunder', 'in a few seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), 'om 5 dager', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'i dag kl. 12:00',     'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'i dag kl. 12:25',     'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'i dag kl. 13:00',     'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'i morgen kl. 12:00',  'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'i dag kl. 11:00',     'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'i går kl. 12:00',     'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('dddd [kl.] LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd [kl.] LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd [kl.] LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('[forrige] dddd [kl.] LT'),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[forrige] dddd [kl.] LT'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[forrige] dddd [kl.] LT'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2012, 0,  1]).format('w ww wo'), '52 52 52.', 'Jan  1 2012 should be week 52');\n    assert.equal(moment([2012, 0,  2]).format('w ww wo'),  '1 01 1.', 'Jan  2 2012 should be week 1');\n    assert.equal(moment([2012, 0,  8]).format('w ww wo'),  '1 01 1.', 'Jan  8 2012 should be week 1');\n    assert.equal(moment([2012, 0,  9]).format('w ww wo'),  '2 02 2.', 'Jan  9 2012 should be week 2');\n    assert.equal(moment([2012, 0, 15]).format('w ww wo'),  '2 02 2.', 'Jan 15 2012 should be week 2');\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\n\n\nfunction localeModule (name, lifecycle) {\n    QUnit.module('locale:' + name, {\n        setup : function () {\n            moment.locale(name);\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            moment.locale('en');\n            teardownDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n    defineCommonLocaleTests(name, -1, -1);\n}\n\nlocaleModule('ne');\n\ntest('parse', function (assert) {\n    var tests = 'जनवरी जन._फेब्रुवरी फेब्रु._मार्च मार्च_अप्रिल अप्रि._मई मई_जुन जुन_जुलाई जुलाई._अगष्ट अग._सेप्टेम्बर सेप्ट._अक्टोबर अक्टो._नोभेम्बर नोभे._डिसेम्बर डिसे.'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, Do MMMM YYYY, aको h:mm:ss बजे',      'आइतबार, १४ फेब्रुवरी २०१०, दिउँसोको ३:२५:५० बजे'],\n            ['ddd, aको h बजे',                                                'आइत., दिउँसोको ३ बजे'],\n            ['M Mo MM MMMM MMM',                   '२ २ ०२ फेब्रुवरी फेब्रु.'],\n            ['YYYY YY',                            '२०१० १०'],\n            ['D Do DD',                            '१४ १४ १४'],\n            ['d do dddd ddd dd',                   '० ० आइतबार आइत. आ.'],\n            ['DDD DDDo DDDD',                      '४५ ४५ ०४५'],\n            ['w wo ww',                            '८ ८ ०८'],\n            ['h hh',                               '३ ०३'],\n            ['H HH',                               '१५ १५'],\n            ['m mm',                               '२५ २५'],\n            ['s ss',                               '५० ५०'],\n            ['a A',                                'दिउँसो दिउँसो'],\n            ['LTS',                                'दिउँसोको ३:२५:५० बजे'],\n            ['L',                                  '१४/०२/२०१०'],\n            ['LL',                                 '१४ फेब्रुवरी २०१०'],\n            ['LLL',                                '१४ फेब्रुवरी २०१०, दिउँसोको ३:२५ बजे'],\n            ['LLLL',                               'आइतबार, १४ फेब्रुवरी २०१०, दिउँसोको ३:२५ बजे'],\n            ['l',                                  '१४/२/२०१०'],\n            ['ll',                                 '१४ फेब्रु. २०१०'],\n            ['lll',                                '१४ फेब्रु. २०१०, दिउँसोको ३:२५ बजे'],\n            ['llll',                               'आइत., १४ फेब्रु. २०१०, दिउँसोको ३:२५ बजे']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '१', '१');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '२', '२');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '३', '३');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '४', '४');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '५', '५');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '६', '६');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '७', '७');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '८', '८');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '९', '९');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '१०', '१०');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '११', '११');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '१२', '१२');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '१३', '१३');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '१४', '१४');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '१५', '१५');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '१६', '१६');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '१७', '१७');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '१८', '१८');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '१९', '१९');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '२०', '२०');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '२१', '२१');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '२२', '२२');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '२३', '२३');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '२४', '२४');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '२५', '२५');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '२६', '२६');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '२७', '२७');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '२८', '२८');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '२९', '२९');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '३०', '३०');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '३१', '३१');\n});\n\ntest('format month', function (assert) {\n    var expected = 'जनवरी जन._फेब्रुवरी फेब्रु._मार्च मार्च_अप्रिल अप्रि._मई मई_जुन जुन_जुलाई जुलाई._अगष्ट अग._सेप्टेम्बर सेप्ट._अक्टोबर अक्टो._नोभेम्बर नोभे._डिसेम्बर डिसे.'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'आइतबार आइत. आ._सोमबार सोम. सो._मङ्गलबार मङ्गल. मं._बुधबार बुध. बु._बिहिबार बिहि. बि._शुक्रबार शुक्र. शु._शनिबार शनि. श.'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'केही क्षण', '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'एक मिनेट',      '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'एक मिनेट',      '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '२ मिनेट',     '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '४४ मिनेट',    '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'एक घण्टा',       '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'एक घण्टा',       '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '२ घण्टा',       '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '५ घण्टा',       '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '२१ घण्टा',      '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'एक दिन',         '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'एक दिन',         '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '२ दिन',        '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'एक दिन',         '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '५ दिन',        '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '२५ दिन',       '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'एक महिना',       '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'एक महिना',       '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'एक महिना',       '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '२ महिना',      '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '२ महिना',      '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '३ महिना',      '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'एक महिना',       '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '५ महिना',      '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'एक बर्ष',        '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '२ बर्ष',       '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'एक बर्ष',        '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '५ बर्ष',       '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'केही क्षणमा',  'prefix');\n    assert.equal(moment(0).from(30000), 'केही क्षण अगाडि', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'केही क्षण अगाडि',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'केही क्षणमा', 'केही क्षणमा');\n    assert.equal(moment().add({d: 5}).fromNow(), '५ दिनमा', '५ दिनमा');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'आज दिउँसोको १२:०० बजे',    'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'आज दिउँसोको १२:२५ बजे',    'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'आज दिउँसोको १:०० बजे',     'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'भोलि दिउँसोको १२:०० बजे',  'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'आज बिहानको ११:०० बजे',     'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'हिजो दिउँसोको १२:०० बजे',  'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('[आउँदो] dddd[,] LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[आउँदो] dddd[,] LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[आउँदो] dddd[,] LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('[गएको] dddd[,] LT'),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[गएको] dddd[,] LT'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[गएको] dddd[,] LT'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('meridiem', function (assert) {\n    assert.equal(moment([2011, 2, 23,  2, 30]).format('a'), 'राति', 'before dawn');\n    assert.equal(moment([2011, 2, 23,  9, 30]).format('a'), 'बिहान', 'morning');\n    assert.equal(moment([2011, 2, 23, 14, 30]).format('a'), 'दिउँसो', 'during day');\n    assert.equal(moment([2011, 2, 23, 17, 30]).format('a'), 'साँझ', 'evening');\n    assert.equal(moment([2011, 2, 23, 19, 30]).format('a'), 'साँझ', 'late evening');\n    assert.equal(moment([2011, 2, 23, 21, 20]).format('a'), 'राति', 'night');\n\n    assert.equal(moment([2011, 2, 23,  2, 30]).format('A'), 'राति', 'before dawn');\n    assert.equal(moment([2011, 2, 23,  9, 30]).format('A'), 'बिहान', 'morning');\n    assert.equal(moment([2011, 2, 23, 14, 30]).format('A'), 'दिउँसो', 'during day');\n    assert.equal(moment([2011, 2, 23, 17, 30]).format('A'), 'साँझ', 'evening');\n    assert.equal(moment([2011, 2, 23, 19, 30]).format('A'), 'साँझ', 'late evening');\n    assert.equal(moment([2011, 2, 23, 21, 20]).format('A'), 'राति', 'night');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2011, 11, 26]).format('w ww wo'), '५३ ५३ ५३', 'Dec 26 2011 should be week 53');\n    assert.equal(moment([2012,  0,  1]).format('w ww wo'), '१ ०१ १', 'Jan  1 2012 should be week 1');\n    assert.equal(moment([2012,  0,  2]).format('w ww wo'), '१ ०१ १', 'Jan  2 2012 should be week 1');\n    assert.equal(moment([2012,  0,  8]).format('w ww wo'), '२ ०२ २', 'Jan  8 2012 should be week 2');\n    assert.equal(moment([2012,  0,  9]).format('w ww wo'), '२ ०२ २', 'Jan  9 2012 should be week 2');\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\n\n\nfunction localeModule (name, lifecycle) {\n    QUnit.module('locale:' + name, {\n        setup : function () {\n            moment.locale(name);\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            moment.locale('en');\n            teardownDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n    defineCommonLocaleTests(name, -1, -1);\n}\n\nlocaleModule('nl-be');\n\ntest('parse', function (assert) {\n    var tests = 'januari jan._februari feb._maart mrt._april apr._mei mei._juni jun._juli jul._augustus aug._september sep._oktober okt._november nov._december dec.'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, MMMM Do YYYY, HH:mm:ss',       'zondag, februari 14de 2010, 15:25:50'],\n            ['ddd, HH',                            'zo., 15'],\n            ['M Mo MM MMMM MMM',                   '2 2de 02 februari feb.'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14de 14'],\n            ['d do dddd ddd dd',                   '0 0de zondag zo. Zo'],\n            ['DDD DDDo DDDD',                      '45 45ste 045'],\n            ['w wo ww',                            '6 6de 06'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'pm PM'],\n            ['[the] DDDo [day of the year]',       'the 45ste day of the year'],\n            ['LTS',                                '15:25:50'],\n            ['L',                                  '14/02/2010'],\n            ['LL',                                 '14 februari 2010'],\n            ['LLL',                                '14 februari 2010 15:25'],\n            ['LLLL',                               'zondag 14 februari 2010 15:25'],\n            ['l',                                  '14/2/2010'],\n            ['ll',                                 '14 feb. 2010'],\n            ['lll',                                '14 feb. 2010 15:25'],\n            ['llll',                               'zo. 14 feb. 2010 15:25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1ste', '1ste');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2de', '2de');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3de', '3de');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4de', '4de');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5de', '5de');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6de', '6de');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7de', '7de');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8ste', '8ste');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9de', '9de');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10de', '10de');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11de', '11de');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12de', '12de');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13de', '13de');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14de', '14de');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15de', '15de');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16de', '16de');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17de', '17de');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18de', '18de');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19de', '19de');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20ste', '20ste');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21ste', '21ste');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22ste', '22ste');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23ste', '23ste');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24ste', '24ste');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25ste', '25ste');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26ste', '26ste');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27ste', '27ste');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28ste', '28ste');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29ste', '29ste');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30ste', '30ste');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31ste', '31ste');\n});\n\ntest('format month', function (assert) {\n    var expected = 'januari jan._februari feb._maart mrt._april apr._mei mei_juni jun._juli jul._augustus aug._september sep._oktober okt._november nov._december dec.'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'zondag zo. Zo_maandag ma. Ma_dinsdag di. Di_woensdag wo. Wo_donderdag do. Do_vrijdag vr. Vr_zaterdag za. Za'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'een paar seconden', '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'één minuut',      '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'één minuut',      '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 minuten',     '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 minuten',    '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'één uur',       '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'één uur',       '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 uur',       '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 uur',       '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 uur',      '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'één dag',         '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'één dag',         '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 dagen',        '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'één dag',         '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 dagen',        '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 dagen',       '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'één maand',       '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'één maand',       '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'één maand',       '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 maanden',      '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 maanden',      '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 maanden',      '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'één maand',       '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 maanden',      '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'één jaar',        '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 jaar',       '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'één jaar',        '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 jaar',       '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'over een paar seconden',  'prefix');\n    assert.equal(moment(0).from(30000), 'een paar seconden geleden', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'een paar seconden geleden',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'over een paar seconden', 'in a few seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), 'over 5 dagen', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'vandaag om 12:00',   'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'vandaag om 12:25',   'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'vandaag om 13:00',   'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'morgen om 12:00',    'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'vandaag om 11:00',   'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'gisteren om 12:00',  'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('dddd [om] LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd [om] LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd [om] LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('[afgelopen] dddd [om] LT'),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[afgelopen] dddd [om] LT'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[afgelopen] dddd [om] LT'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('month abbreviation', function (assert) {\n    assert.equal(moment([2012, 5, 23]).format('D-MMM-YYYY'), '23-jun-2012', 'format month abbreviation surrounded by dashes should not include a dot');\n    assert.equal(moment([2012, 5, 23]).unix(), moment('23-jun-2012', 'D-MMM-YYYY').unix(), 'parse month abbreviation surrounded by dashes without dot');\n    assert.equal(moment([2012, 5, 23]).format('D MMM YYYY'), '23 jun. 2012', 'format month abbreviation not surrounded by dashes should include a dot');\n    assert.equal(moment([2012, 5, 23]).unix(), moment('23 jun. 2012', 'D MMM YYYY').unix(), 'parse month abbreviation not surrounded by dashes with dot');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2012, 0,  1]).format('w ww wo'), '52 52 52ste', 'Jan  1 2012 should be week 52');\n    assert.equal(moment([2012, 0,  2]).format('w ww wo'),   '1 01 1ste', 'Jan  2 2012 should be week 1');\n    assert.equal(moment([2012, 0,  8]).format('w ww wo'),   '1 01 1ste', 'Jan  8 2012 should be week 1');\n    assert.equal(moment([2012, 0,  9]).format('w ww wo'),    '2 02 2de', 'Jan  9 2012 should be week 2');\n    assert.equal(moment([2012, 0, 15]).format('w ww wo'),    '2 02 2de', 'Jan 15 2012 should be week 2');\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\n\n\nfunction localeModule (name, lifecycle) {\n    QUnit.module('locale:' + name, {\n        setup : function () {\n            moment.locale(name);\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            moment.locale('en');\n            teardownDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n    defineCommonLocaleTests(name, -1, -1);\n}\n\nlocaleModule('nl');\n\ntest('parse', function (assert) {\n    var tests = 'januari jan._februari feb._maart mrt._april apr._mei mei._juni jun._juli jul._augustus aug._september sep._oktober okt._november nov._december dec.'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, MMMM Do YYYY, HH:mm:ss',       'zondag, februari 14de 2010, 15:25:50'],\n            ['ddd, HH',                            'zo., 15'],\n            ['M Mo MM MMMM MMM',                   '2 2de 02 februari feb.'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14de 14'],\n            ['d do dddd ddd dd',                   '0 0de zondag zo. Zo'],\n            ['DDD DDDo DDDD',                      '45 45ste 045'],\n            ['w wo ww',                            '6 6de 06'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'pm PM'],\n            ['[the] DDDo [day of the year]',       'the 45ste day of the year'],\n            ['LTS',                                '15:25:50'],\n            ['L',                                  '14-02-2010'],\n            ['LL',                                 '14 februari 2010'],\n            ['LLL',                                '14 februari 2010 15:25'],\n            ['LLLL',                               'zondag 14 februari 2010 15:25'],\n            ['l',                                  '14-2-2010'],\n            ['ll',                                 '14 feb. 2010'],\n            ['lll',                                '14 feb. 2010 15:25'],\n            ['llll',                               'zo. 14 feb. 2010 15:25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1ste', '1ste');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2de', '2de');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3de', '3de');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4de', '4de');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5de', '5de');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6de', '6de');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7de', '7de');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8ste', '8ste');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9de', '9de');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10de', '10de');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11de', '11de');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12de', '12de');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13de', '13de');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14de', '14de');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15de', '15de');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16de', '16de');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17de', '17de');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18de', '18de');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19de', '19de');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20ste', '20ste');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21ste', '21ste');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22ste', '22ste');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23ste', '23ste');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24ste', '24ste');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25ste', '25ste');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26ste', '26ste');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27ste', '27ste');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28ste', '28ste');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29ste', '29ste');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30ste', '30ste');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31ste', '31ste');\n});\n\ntest('format month', function (assert) {\n    var expected = 'januari jan._februari feb._maart mrt._april apr._mei mei_juni jun._juli jul._augustus aug._september sep._oktober okt._november nov._december dec.'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'zondag zo. Zo_maandag ma. Ma_dinsdag di. Di_woensdag wo. Wo_donderdag do. Do_vrijdag vr. Vr_zaterdag za. Za'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'een paar seconden', '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'één minuut',      '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'één minuut',      '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 minuten',     '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 minuten',    '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'één uur',       '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'één uur',       '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 uur',       '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 uur',       '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 uur',      '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'één dag',         '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'één dag',         '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 dagen',        '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'één dag',         '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 dagen',        '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 dagen',       '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'één maand',       '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'één maand',       '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'één maand',       '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 maanden',      '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 maanden',      '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 maanden',      '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'één maand',       '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 maanden',      '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'één jaar',        '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 jaar',       '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'één jaar',        '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 jaar',       '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'over een paar seconden',  'prefix');\n    assert.equal(moment(0).from(30000), 'een paar seconden geleden', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'een paar seconden geleden',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'over een paar seconden', 'in a few seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), 'over 5 dagen', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'vandaag om 12:00',   'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'vandaag om 12:25',   'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'vandaag om 13:00',   'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'morgen om 12:00',    'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'vandaag om 11:00',   'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'gisteren om 12:00',  'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('dddd [om] LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd [om] LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd [om] LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('[afgelopen] dddd [om] LT'),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[afgelopen] dddd [om] LT'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[afgelopen] dddd [om] LT'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('month abbreviation', function (assert) {\n    assert.equal(moment([2012, 5, 23]).format('D-MMM-YYYY'), '23-jun-2012', 'format month abbreviation surrounded by dashes should not include a dot');\n    assert.equal(moment([2012, 5, 23]).unix(), moment('23-jun-2012', 'D-MMM-YYYY').unix(), 'parse month abbreviation surrounded by dashes without dot');\n    assert.equal(moment([2012, 5, 23]).format('D MMM YYYY'), '23 jun. 2012', 'format month abbreviation not surrounded by dashes should include a dot');\n    assert.equal(moment([2012, 5, 23]).unix(), moment('23 jun. 2012', 'D MMM YYYY').unix(), 'parse month abbreviation not surrounded by dashes with dot');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2012, 0,  1]).format('w ww wo'), '52 52 52ste', 'Jan  1 2012 should be week 52');\n    assert.equal(moment([2012, 0,  2]).format('w ww wo'),   '1 01 1ste', 'Jan  2 2012 should be week 1');\n    assert.equal(moment([2012, 0,  8]).format('w ww wo'),   '1 01 1ste', 'Jan  8 2012 should be week 1');\n    assert.equal(moment([2012, 0,  9]).format('w ww wo'),    '2 02 2de', 'Jan  9 2012 should be week 2');\n    assert.equal(moment([2012, 0, 15]).format('w ww wo'),    '2 02 2de', 'Jan 15 2012 should be week 2');\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\n\n\nfunction localeModule (name, lifecycle) {\n    QUnit.module('locale:' + name, {\n        setup : function () {\n            moment.locale(name);\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            moment.locale('en');\n            teardownDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n    defineCommonLocaleTests(name, -1, -1);\n}\n\nlocaleModule('nn');\n\ntest('parse', function (assert) {\n    var tests = 'januar jan_februar feb_mars mar_april apr_mai mai_juni jun_juli jul_august aug_september sep_oktober okt_november nov_desember des'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, MMMM Do YYYY, h:mm:ss a',      'sundag, februar 14. 2010, 3:25:50 pm'],\n            ['ddd, hA',                            'sun, 3PM'],\n            ['M Mo MM MMMM MMM',                   '2 2. 02 februar feb'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14. 14'],\n            ['d do dddd ddd dd',                   '0 0. sundag sun su'],\n            ['DDD DDDo DDDD',                      '45 45. 045'],\n            ['w wo ww',                            '6 6. 06'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'pm PM'],\n            ['[the] DDDo [day of the year]',       'the 45. day of the year'],\n            ['LTS',                                '15:25:50'],\n            ['L',                                  '14.02.2010'],\n            ['LL',                                 '14. februar 2010'],\n            ['LLL',                                '14. februar 2010 kl. 15:25'],\n            ['LLLL',                               'sundag 14. februar 2010 kl. 15:25'],\n            ['l',                                  '14.2.2010'],\n            ['ll',                                 '14. feb 2010'],\n            ['lll',                                '14. feb 2010 kl. 15:25'],\n            ['llll',                               'sun 14. feb 2010 kl. 15:25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1.', '1.');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2.', '2.');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3.', '3.');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4.', '4.');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5.', '5.');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6.', '6.');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7.', '7.');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8.', '8.');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9.', '9.');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10.', '10.');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11.', '11.');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12.', '12.');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13.', '13.');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14.', '14.');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15.', '15.');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16.', '16.');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17.', '17.');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18.', '18.');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19.', '19.');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20.', '20.');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21.', '21.');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22.', '22.');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23.', '23.');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24.', '24.');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25.', '25.');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26.', '26.');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27.', '27.');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28.', '28.');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29.', '29.');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30.', '30.');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31.', '31.');\n});\n\ntest('format month', function (assert) {\n    var expected = 'januar jan_februar feb_mars mar_april apr_mai mai_juni jun_juli jul_august aug_september sep_oktober okt_november nov_desember des'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'sundag sun su_måndag mån må_tysdag tys ty_onsdag ons on_torsdag tor to_fredag fre fr_laurdag lau lø'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'nokre sekund', '44 sekunder = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'eit minutt',   '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'eit minutt',   '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 minutt',     '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 minutt',    '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'ein time',     '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'ein time',     '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 timar',      '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 timar',      '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 timar',     '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'ein dag',      '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'ein dag',      '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 dagar',      '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'ein dag',      '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 dagar',      '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 dagar',     '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'ein månad',    '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'ein månad',    '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'ein månad',    '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 månader',    '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 månader',    '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 månader',    '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'ein månad',    '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 månader',    '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'eit år',       '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 år',         '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'eit år',       '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 år',         '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'om nokre sekund',  'prefix');\n    assert.equal(moment(0).from(30000), 'nokre sekund sidan', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'nokre sekund sidan',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'om nokre sekund', 'in a few seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), 'om 5 dagar', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'I dag klokka 12:00',     'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'I dag klokka 12:25',     'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'I dag klokka 13:00',     'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'I morgon klokka 12:00',  'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'I dag klokka 11:00',     'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'I går klokka 12:00',     'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('dddd [klokka] LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd [klokka] LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd [klokka] LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('[Føregåande] dddd [klokka] LT'),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[Føregåande] dddd [klokka] LT'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[Føregåande] dddd [klokka] LT'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2012, 0,  1]).format('w ww wo'), '52 52 52.', 'Jan  1 2012 should be week 52');\n    assert.equal(moment([2012, 0,  2]).format('w ww wo'),   '1 01 1.', 'Jan  2 2012 should be week 1');\n    assert.equal(moment([2012, 0,  8]).format('w ww wo'),   '1 01 1.', 'Jan  8 2012 should be week 1');\n    assert.equal(moment([2012, 0,  9]).format('w ww wo'),   '2 02 2.', 'Jan  9 2012 should be week 2');\n    assert.equal(moment([2012, 0, 15]).format('w ww wo'),   '2 02 2.', 'Jan 15 2012 should be week 2');\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\n\n\nfunction localeModule (name, lifecycle) {\n    QUnit.module('locale:' + name, {\n        setup : function () {\n            moment.locale(name);\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            moment.locale('en');\n            teardownDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n    defineCommonLocaleTests(name, -1, -1);\n}\n\nlocaleModule('pa-in');\n\ntest('parse', function (assert) {\n    var tests = 'ਜਨਵਰੀ ਜਨਵਰੀ_ਫ਼ਰਵਰੀ ਫ਼ਰਵਰੀ_ਮਾਰਚ ਮਾਰਚ_ਅਪ੍ਰੈਲ ਅਪ੍ਰੈਲ_ਮਈ ਮਈ_ਜੂਨ ਜੂਨ_ਜੁਲਾਈ ਜੁਲਾਈ_ਅਗਸਤ ਅਗਸਤ_ਸਤੰਬਰ ਸਤੰਬਰ_ਅਕਤੂਬਰ ਅਕਤੂਬਰ_ਨਵੰਬਰ ਨਵੰਬਰ_ਦਸੰਬਰ ਦਸੰਬਰ'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, Do MMMM YYYY, a h:mm:ss ਵਜੇ',  'ਐਤਵਾਰ, ੧੪ ਫ਼ਰਵਰੀ ੨੦੧੦, ਦੁਪਹਿਰ ੩:੨੫:੫੦ ਵਜੇ'],\n            ['ddd, a h ਵਜੇ',                       'ਐਤ, ਦੁਪਹਿਰ ੩ ਵਜੇ'],\n            ['M Mo MM MMMM MMM',                   '੨ ੨ ੦੨ ਫ਼ਰਵਰੀ ਫ਼ਰਵਰੀ'],\n            ['YYYY YY',                            '੨੦੧੦ ੧੦'],\n            ['D Do DD',                            '੧੪ ੧੪ ੧੪'],\n            ['d do dddd ddd dd',                   '੦ ੦ ਐਤਵਾਰ ਐਤ ਐਤ'],\n            ['DDD DDDo DDDD',                      '੪੫ ੪੫ ੦੪੫'],\n            ['w wo ww',                            '੮ ੮ ੦੮'],\n            ['h hh',                               '੩ ੦੩'],\n            ['H HH',                               '੧੫ ੧੫'],\n            ['m mm',                               '੨੫ ੨੫'],\n            ['s ss',                               '੫੦ ੫੦'],\n            ['a A',                                'ਦੁਪਹਿਰ ਦੁਪਹਿਰ'],\n            ['LTS',                                'ਦੁਪਹਿਰ ੩:੨੫:੫੦ ਵਜੇ'],\n            ['L',                                  '੧੪/੦੨/੨੦੧੦'],\n            ['LL',                                 '੧੪ ਫ਼ਰਵਰੀ ੨੦੧੦'],\n            ['LLL',                                '੧੪ ਫ਼ਰਵਰੀ ੨੦੧੦, ਦੁਪਹਿਰ ੩:੨੫ ਵਜੇ'],\n            ['LLLL',                               'ਐਤਵਾਰ, ੧੪ ਫ਼ਰਵਰੀ ੨੦੧੦, ਦੁਪਹਿਰ ੩:੨੫ ਵਜੇ'],\n            ['l',                                  '੧੪/੨/੨੦੧੦'],\n            ['ll',                                 '੧੪ ਫ਼ਰਵਰੀ ੨੦੧੦'],\n            ['lll',                                '੧੪ ਫ਼ਰਵਰੀ ੨੦੧੦, ਦੁਪਹਿਰ ੩:੨੫ ਵਜੇ'],\n            ['llll',                               'ਐਤ, ੧੪ ਫ਼ਰਵਰੀ ੨੦੧੦, ਦੁਪਹਿਰ ੩:੨੫ ਵਜੇ']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '੧', '੧');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '੨', '੨');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '੩', '੩');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '੪', '੪');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '੫', '੫');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '੬', '੬');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '੭', '੭');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '੮', '੮');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '੯', '੯');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '੧੦', '੧੦');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '੧੧', '੧੧');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '੧੨', '੧੨');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '੧੩', '੧੩');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '੧੪', '੧੪');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '੧੫', '੧੫');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '੧੬', '੧੬');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '੧੭', '੧੭');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '੧੮', '੧੮');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '੧੯', '੧੯');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '੨੦', '੨੦');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '੨੧', '੨੧');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '੨੨', '੨੨');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '੨੩', '੨੩');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '੨੪', '੨੪');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '੨੫', '੨੫');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '੨੬', '੨੬');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '੨੭', '੨੭');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '੨੮', '੨੮');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '੨੯', '੨੯');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '੩੦', '੩੦');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '੩੧', '੩੧');\n});\n\ntest('format month', function (assert) {\n    var expected = 'ਜਨਵਰੀ ਜਨਵਰੀ_ਫ਼ਰਵਰੀ ਫ਼ਰਵਰੀ_ਮਾਰਚ ਮਾਰਚ_ਅਪ੍ਰੈਲ ਅਪ੍ਰੈਲ_ਮਈ ਮਈ_ਜੂਨ ਜੂਨ_ਜੁਲਾਈ ਜੁਲਾਈ_ਅਗਸਤ ਅਗਸਤ_ਸਤੰਬਰ ਸਤੰਬਰ_ਅਕਤੂਬਰ ਅਕਤੂਬਰ_ਨਵੰਬਰ ਨਵੰਬਰ_ਦਸੰਬਰ ਦਸੰਬਰ'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'ਐਤਵਾਰ ਐਤ ਐਤ_ਸੋਮਵਾਰ ਸੋਮ ਸੋਮ_ਮੰਗਲਵਾਰ ਮੰਗਲ ਮੰਗਲ_ਬੁਧਵਾਰ ਬੁਧ ਬੁਧ_ਵੀਰਵਾਰ ਵੀਰ ਵੀਰ_ਸ਼ੁੱਕਰਵਾਰ ਸ਼ੁਕਰ ਸ਼ੁਕਰ_ਸ਼ਨੀਚਰਵਾਰ ਸ਼ਨੀ ਸ਼ਨੀ'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'ਕੁਝ ਸਕਿੰਟ', '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'ਇਕ ਮਿੰਟ',      '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'ਇਕ ਮਿੰਟ',      '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '੨ ਮਿੰਟ',     '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '੪੪ ਮਿੰਟ',    '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'ਇੱਕ ਘੰਟਾ',       '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'ਇੱਕ ਘੰਟਾ',       '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '੨ ਘੰਟੇ',       '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '੫ ਘੰਟੇ',       '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '੨੧ ਘੰਟੇ',      '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'ਇੱਕ ਦਿਨ',         '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'ਇੱਕ ਦਿਨ',         '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '੨ ਦਿਨ',        '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'ਇੱਕ ਦਿਨ',         '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '੫ ਦਿਨ',        '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '੨੫ ਦਿਨ',       '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'ਇੱਕ ਮਹੀਨਾ',       '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'ਇੱਕ ਮਹੀਨਾ',       '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'ਇੱਕ ਮਹੀਨਾ',       '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '੨ ਮਹੀਨੇ',      '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '੨ ਮਹੀਨੇ',      '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '੩ ਮਹੀਨੇ',      '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'ਇੱਕ ਮਹੀਨਾ',       '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '੫ ਮਹੀਨੇ',      '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'ਇੱਕ ਸਾਲ',        '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '੨ ਸਾਲ',       '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'ਇੱਕ ਸਾਲ',        '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '੫ ਸਾਲ',       '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'ਕੁਝ ਸਕਿੰਟ ਵਿੱਚ',  'prefix');\n    assert.equal(moment(0).from(30000), 'ਕੁਝ ਸਕਿੰਟ ਪਿਛਲੇ', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'ਕੁਝ ਸਕਿੰਟ ਪਿਛਲੇ',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'ਕੁਝ ਸਕਿੰਟ ਵਿੱਚ', 'ਕੁਝ ਸਕਿੰਟ ਵਿੱਚ');\n    assert.equal(moment().add({d: 5}).fromNow(), '੫ ਦਿਨ ਵਿੱਚ', '੫ ਦਿਨ ਵਿੱਚ');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'ਅਜ ਦੁਪਹਿਰ ੧੨:੦੦ ਵਜੇ',  'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'ਅਜ ਦੁਪਹਿਰ ੧੨:੨੫ ਵਜੇ',  'Now plus 25 min');\n    assert.equal(moment(a).add({h: 3}).calendar(),       'ਅਜ ਦੁਪਹਿਰ ੩:੦੦ ਵਜੇ',   'Now plus 3 hours');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'ਕਲ ਦੁਪਹਿਰ ੧੨:੦੦ ਵਜੇ',  'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'ਅਜ ਦੁਪਹਿਰ ੧੧:੦੦ ਵਜੇ',  'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'ਕਲ ਦੁਪਹਿਰ ੧੨:੦੦ ਵਜੇ',  'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('dddd[,] LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd[,] LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd[,] LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('[ਪਿਛਲੇ] dddd[,] LT'),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[ਪਿਛਲੇ] dddd[,] LT'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[ਪਿਛਲੇ] dddd[,] LT'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('meridiem invariant', function (assert) {\n    assert.equal(moment([2011, 2, 23,  2, 30]).format('a'), 'ਰਾਤ', 'before dawn');\n    assert.equal(moment([2011, 2, 23,  9, 30]).format('a'), 'ਸਵੇਰ', 'morning');\n    assert.equal(moment([2011, 2, 23, 14, 30]).format('a'), 'ਦੁਪਹਿਰ', 'during day');\n    assert.equal(moment([2011, 2, 23, 17, 30]).format('a'), 'ਸ਼ਾਮ', 'evening');\n    assert.equal(moment([2011, 2, 23, 19, 30]).format('a'), 'ਸ਼ਾਮ', 'late evening');\n    assert.equal(moment([2011, 2, 23, 21, 20]).format('a'), 'ਰਾਤ', 'night');\n\n    assert.equal(moment([2011, 2, 23,  2, 30]).format('A'), 'ਰਾਤ', 'before dawn');\n    assert.equal(moment([2011, 2, 23,  9, 30]).format('A'), 'ਸਵੇਰ', 'morning');\n    assert.equal(moment([2011, 2, 23, 14, 30]).format('A'), 'ਦੁਪਹਿਰ', ' during day');\n    assert.equal(moment([2011, 2, 23, 17, 30]).format('A'), 'ਸ਼ਾਮ', 'evening');\n    assert.equal(moment([2011, 2, 23, 19, 30]).format('A'), 'ਸ਼ਾਮ', 'late evening');\n    assert.equal(moment([2011, 2, 23, 21, 20]).format('A'), 'ਰਾਤ', 'night');\n});\n\ntest('weeks year starting sunday', function (assert) {\n    assert.equal(moment([2012, 0,  1]).week(), 1, 'Jan  1 2012 should be week 1');\n    assert.equal(moment([2012, 0,  7]).week(), 1, 'Jan  7 2012 should be week 1');\n    assert.equal(moment([2012, 0,  8]).week(), 2, 'Jan  8 2012 should be week 2');\n    assert.equal(moment([2012, 0, 14]).week(), 2, 'Jan 14 2012 should be week 2');\n    assert.equal(moment([2012, 0, 15]).week(), 3, 'Jan 15 2012 should be week 3');\n});\n\ntest('weeks year starting monday', function (assert) {\n    assert.equal(moment([2006, 11, 31]).week(), 1, 'Dec 31 2006 should be week 1');\n    assert.equal(moment([2007,  0,  1]).week(), 1, 'Jan  1 2007 should be week 1');\n    assert.equal(moment([2007,  0,  6]).week(), 1, 'Jan  6 2007 should be week 1');\n    assert.equal(moment([2007,  0,  7]).week(), 2, 'Jan  7 2007 should be week 2');\n    assert.equal(moment([2007,  0, 13]).week(), 2, 'Jan 13 2007 should be week 2');\n    assert.equal(moment([2007,  0, 14]).week(), 3, 'Jan 14 2007 should be week 3');\n});\n\ntest('weeks year starting tuesday', function (assert) {\n    assert.equal(moment([2007, 11, 29]).week(), 52, 'Dec 29 2007 should be week 52');\n    assert.equal(moment([2008,  0,  1]).week(), 1, 'Jan  1 2008 should be week 1');\n    assert.equal(moment([2008,  0,  5]).week(), 1, 'Jan  5 2008 should be week 1');\n    assert.equal(moment([2008,  0,  6]).week(), 2, 'Jan  6 2008 should be week 2');\n    assert.equal(moment([2008,  0, 12]).week(), 2, 'Jan 12 2008 should be week 2');\n    assert.equal(moment([2008,  0, 13]).week(), 3, 'Jan 13 2008 should be week 3');\n});\n\ntest('weeks year starting wednesday', function (assert) {\n    assert.equal(moment([2002, 11, 29]).week(), 1, 'Dec 29 2002 should be week 1');\n    assert.equal(moment([2003,  0,  1]).week(), 1, 'Jan  1 2003 should be week 1');\n    assert.equal(moment([2003,  0,  4]).week(), 1, 'Jan  4 2003 should be week 1');\n    assert.equal(moment([2003,  0,  5]).week(), 2, 'Jan  5 2003 should be week 2');\n    assert.equal(moment([2003,  0, 11]).week(), 2, 'Jan 11 2003 should be week 2');\n    assert.equal(moment([2003,  0, 12]).week(), 3, 'Jan 12 2003 should be week 3');\n});\n\ntest('weeks year starting thursday', function (assert) {\n    assert.equal(moment([2008, 11, 28]).week(), 1, 'Dec 28 2008 should be week 1');\n    assert.equal(moment([2009,  0,  1]).week(), 1, 'Jan  1 2009 should be week 1');\n    assert.equal(moment([2009,  0,  3]).week(), 1, 'Jan  3 2009 should be week 1');\n    assert.equal(moment([2009,  0,  4]).week(), 2, 'Jan  4 2009 should be week 2');\n    assert.equal(moment([2009,  0, 10]).week(), 2, 'Jan 10 2009 should be week 2');\n    assert.equal(moment([2009,  0, 11]).week(), 3, 'Jan 11 2009 should be week 3');\n});\n\ntest('weeks year starting friday', function (assert) {\n    assert.equal(moment([2009, 11, 27]).week(), 1, 'Dec 27 2009 should be week 1');\n    assert.equal(moment([2010,  0,  1]).week(), 1, 'Jan  1 2010 should be week 1');\n    assert.equal(moment([2010,  0,  2]).week(), 1, 'Jan  2 2010 should be week 1');\n    assert.equal(moment([2010,  0,  3]).week(), 2, 'Jan  3 2010 should be week 2');\n    assert.equal(moment([2010,  0,  9]).week(), 2, 'Jan  9 2010 should be week 2');\n    assert.equal(moment([2010,  0, 10]).week(), 3, 'Jan 10 2010 should be week 3');\n});\n\ntest('weeks year starting saturday', function (assert) {\n    assert.equal(moment([2010, 11, 26]).week(), 1, 'Dec 26 2010 should be week 1');\n    assert.equal(moment([2011,  0,  1]).week(), 1, 'Jan  1 2011 should be week 1');\n    assert.equal(moment([2011,  0,  2]).week(), 2, 'Jan  2 2011 should be week 2');\n    assert.equal(moment([2011,  0,  8]).week(), 2, 'Jan  8 2011 should be week 2');\n    assert.equal(moment([2011,  0,  9]).week(), 3, 'Jan  9 2011 should be week 3');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2012, 0,  1]).format('w ww wo'), '੧ ੦੧ ੧', 'Jan  1 2012 should be week 1');\n    assert.equal(moment([2012, 0,  7]).format('w ww wo'), '੧ ੦੧ ੧', 'Jan  7 2012 should be week 1');\n    assert.equal(moment([2012, 0,  8]).format('w ww wo'), '੨ ੦੨ ੨', 'Jan  8 2012 should be week 2');\n    assert.equal(moment([2012, 0, 14]).format('w ww wo'), '੨ ੦੨ ੨', 'Jan 14 2012 should be week 2');\n    assert.equal(moment([2012, 0, 15]).format('w ww wo'), '੩ ੦੩ ੩', 'Jan 15 2012 should be week 3');\n});\n\ntest('lenient day of month ordinal parsing', function (assert) {\n    var i, ordinalStr, testMoment;\n    for (i = 1; i <= 31; ++i) {\n        ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n        testMoment = moment(ordinalStr, 'YYYY MM Do');\n        assert.equal(testMoment.year(), 2014,\n                'lenient day of month ordinal parsing ' + i + ' year check');\n        assert.equal(testMoment.month(), 0,\n                'lenient day of month ordinal parsing ' + i + ' month check');\n        assert.equal(testMoment.date(), i,\n                'lenient day of month ordinal parsing ' + i + ' date check');\n    }\n});\n\ntest('lenient day of month ordinal parsing of number', function (assert) {\n    var i, testMoment;\n    for (i = 1; i <= 31; ++i) {\n        testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n        assert.equal(testMoment.year(), 2014,\n                'lenient day of month ordinal parsing of number ' + i + ' year check');\n        assert.equal(testMoment.month(), 0,\n                'lenient day of month ordinal parsing of number ' + i + ' month check');\n        assert.equal(testMoment.date(), i,\n                'lenient day of month ordinal parsing of number ' + i + ' date check');\n    }\n});\n\ntest('strict day of month ordinal parsing', function (assert) {\n    var i, ordinalStr, testMoment;\n    for (i = 1; i <= 31; ++i) {\n        ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n        testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n        assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n    }\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\n\n\nfunction localeModule (name, lifecycle) {\n    QUnit.module('locale:' + name, {\n        setup : function () {\n            moment.locale(name);\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            moment.locale('en');\n            teardownDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n    defineCommonLocaleTests(name, -1, -1);\n}\n\nlocaleModule('pl');\n\ntest('parse', function (assert) {\n    var tests = 'styczeń stycznia sty_luty lutego lut_marzec marca mar_kwiecień kwietnia kwi_maj maja maj_czerwiec czerwca cze_lipiec lipca lip_sierpień sierpnia sie_wrzesień września wrz_październik października paź_listopad listopada lis_grudzień grudnia gru'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][2], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][2], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][2].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][2].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('parse strict', function (assert) {\n    var tests = 'styczeń stycznia sty_luty lutego lut_marzec marca mar_kwiecień kwietnia kwi_maj maja maj_czerwiec czerwca cze_lipiec lipca lip_sierpień sierpnia sie_wrzesień września wrz_październik października paź_listopad listopada lis_grudzień grudnia gru'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm, true).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][2], 'MMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][2].toLocaleLowerCase(), 'MMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][2].toLocaleUpperCase(), 'MMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, MMMM Do YYYY, h:mm:ss a',      'niedziela, luty 14. 2010, 3:25:50 pm'],\n            ['ddd, hA',                            'ndz, 3PM'],\n            ['M Mo MM MMMM MMM',                   '2 2. 02 luty lut'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14. 14'],\n            ['d do dddd ddd dd',                   '0 0. niedziela ndz Nd'],\n            ['DDD DDDo DDDD',                      '45 45. 045'],\n            ['w wo ww',                            '6 6. 06'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'pm PM'],\n            ['[the] DDDo [day of the year]',       'the 45. day of the year'],\n            ['LTS',                                '15:25:50'],\n            ['L',                                  '14.02.2010'],\n            ['LL',                                 '14 lutego 2010'],\n            ['LLL',                                '14 lutego 2010 15:25'],\n            ['LLLL',                               'niedziela, 14 lutego 2010 15:25'],\n            ['l',                                  '14.2.2010'],\n            ['ll',                                 '14 lut 2010'],\n            ['lll',                                '14 lut 2010 15:25'],\n            ['llll',                               'ndz, 14 lut 2010 15:25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1.', '1.');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2.', '2.');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3.', '3.');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4.', '4.');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5.', '5.');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6.', '6.');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7.', '7.');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8.', '8.');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9.', '9.');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10.', '10.');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11.', '11.');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12.', '12.');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13.', '13.');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14.', '14.');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15.', '15.');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16.', '16.');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17.', '17.');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18.', '18.');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19.', '19.');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20.', '20.');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21.', '21.');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22.', '22.');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23.', '23.');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24.', '24.');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25.', '25.');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26.', '26.');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27.', '27.');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28.', '28.');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29.', '29.');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30.', '30.');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31.', '31.');\n});\n\ntest('format month', function (assert) {\n    var expected = 'styczeń sty_luty lut_marzec mar_kwiecień kwi_maj maj_czerwiec cze_lipiec lip_sierpień sie_wrzesień wrz_październik paź_listopad lis_grudzień gru'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'niedziela ndz Nd_poniedziałek pon Pn_wtorek wt Wt_środa śr Śr_czwartek czw Cz_piątek pt Pt_sobota sob So'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'kilka sekund',  '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'minuta',        '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'minuta',        '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 minuty',      '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 minuty',     '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'godzina',       '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'godzina',       '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 godziny',     '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 godzin',      '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 godzin',     '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  '1 dzień',       '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  '1 dzień',       '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 dni',         '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   '1 dzień',       '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 dni',         '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 dni',        '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'miesiąc',       '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'miesiąc',       '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'miesiąc',       '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 miesiące',    '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 miesiące',    '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 miesiące',    '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'miesiąc',       '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 miesięcy',    '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'rok',           '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 lata',        '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'rok',           '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 lat',         '5 years = 5 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 112}), true), '112 lat',       '112 years = 112 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 122}), true), '122 lata',      '122 years = 122 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 213}), true), '213 lat',       '213 years = 213 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 223}), true), '223 lata',      '223 years = 223 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'za kilka sekund',  'prefix');\n    assert.equal(moment(0).from(30000), 'kilka sekund temu', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'kilka sekund temu',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'za kilka sekund', 'in a few seconds');\n    assert.equal(moment().add({h: 1}).fromNow(), 'za godzinę', 'in an hour');\n    assert.equal(moment().add({d: 5}).fromNow(), 'za 5 dni', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'Dziś o 12:00',    'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'Dziś o 12:25',    'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'Dziś o 13:00',    'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'Jutro o 12:00',   'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'Dziś o 11:00',    'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'Wczoraj o 12:00', 'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('[W] dddd [o] LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[W] dddd [o] LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[W] dddd [o] LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n\n    function makeFormat(d) {\n        switch (d.day()) {\n            case 0:\n                return '[W zeszłą niedzielę o] LT';\n            case 3:\n                return '[W zeszłą środę o] LT';\n            case 6:\n                return '[W zeszłą sobotę o] LT';\n            default:\n                return '[W zeszły] dddd [o] LT';\n        }\n    }\n\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(), m.format(makeFormat(m)), 'Today - ' + i + ' days current time');\n\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(), m.format(makeFormat(m)), 'Today - ' + i + ' days beginning of day');\n\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(), m.format(makeFormat(m)), 'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2012, 0,  1]).format('w ww wo'), '52 52 52.', 'Jan  1 2012 should be week 52');\n    assert.equal(moment([2012, 0,  2]).format('w ww wo'),   '1 01 1.', 'Jan  2 2012 should be week 1');\n    assert.equal(moment([2012, 0,  8]).format('w ww wo'),   '1 01 1.', 'Jan  8 2012 should be week 1');\n    assert.equal(moment([2012, 0,  9]).format('w ww wo'),   '2 02 2.', 'Jan  9 2012 should be week 2');\n    assert.equal(moment([2012, 0, 15]).format('w ww wo'),   '2 02 2.', 'Jan 15 2012 should be week 2');\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\n\n\nfunction localeModule (name, lifecycle) {\n    QUnit.module('locale:' + name, {\n        setup : function () {\n            moment.locale(name);\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            moment.locale('en');\n            teardownDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n    defineCommonLocaleTests(name, -1, -1);\n}\n\nlocaleModule('pt-br');\n\ntest('parse', function (assert) {\n    var tests = 'janeiro jan_fevereiro fev_março mar_abril abr_maio mai_junho jun_julho jul_agosto ago_setembro set_outubro out_novembro nov_dezembro dez'.split('_'), i;\n\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, MMMM Do YYYY, h:mm:ss a',      'Domingo, Fevereiro 14º 2010, 3:25:50 pm'],\n            ['ddd, hA',                            'Dom, 3PM'],\n            ['M Mo MM MMMM MMM',                   '2 2º 02 Fevereiro Fev'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14º 14'],\n            ['d do dddd ddd',                      '0 0º Domingo Dom'],\n            ['DDD DDDo DDDD',                      '45 45º 045'],\n            ['w wo ww',                            '8 8º 08'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'pm PM'],\n            ['[the] DDDo [day of the year]',       'the 45º day of the year'],\n            ['LTS',                                '15:25:50'],\n            ['L',                                  '14/02/2010'],\n            ['LL',                                 '14 de Fevereiro de 2010'],\n            ['LLL',                                '14 de Fevereiro de 2010 às 15:25'],\n            ['LLLL',                               'Domingo, 14 de Fevereiro de 2010 às 15:25'],\n            ['l',                                  '14/2/2010'],\n            ['ll',                                 '14 de Fev de 2010'],\n            ['lll',                                '14 de Fev de 2010 às 15:25'],\n            ['llll',                               'Dom, 14 de Fev de 2010 às 15:25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1º', '1º');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2º', '2º');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3º', '3º');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4º', '4º');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5º', '5º');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6º', '6º');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7º', '7º');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8º', '8º');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9º', '9º');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10º', '10º');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11º', '11º');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12º', '12º');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13º', '13º');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14º', '14º');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15º', '15º');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16º', '16º');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17º', '17º');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18º', '18º');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19º', '19º');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20º', '20º');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21º', '21º');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22º', '22º');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23º', '23º');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24º', '24º');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25º', '25º');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26º', '26º');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27º', '27º');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28º', '28º');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29º', '29º');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30º', '30º');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31º', '31º');\n});\n\ntest('format month', function (assert) {\n    var expected = 'Janeiro Jan_Fevereiro Fev_Março Mar_Abril Abr_Maio Mai_Junho Jun_Julho Jul_Agosto Ago_Setembro Set_Outubro Out_Novembro Nov_Dezembro Dez'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'Domingo Dom Do_Segunda-feira Seg 2ª_Terça-feira Ter 3ª_Quarta-feira Qua 4ª_Quinta-feira Qui 5ª_Sexta-feira Sex 6ª_Sábado Sáb Sá'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'poucos segundos', '44 seconds = seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'um minuto',   '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'um minuto',   '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 minutos',  '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 minutos', '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'uma hora',    '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'uma hora',    '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 horas',    '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 horas',    '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 horas',   '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'um dia',      '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'um dia',      '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 dias',     '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'um dia',      '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 dias',     '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 dias',    '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'um mês',    '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'um mês',    '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'um mês',    '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 meses',   '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 meses',   '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 meses',   '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'um mês',    '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 meses',   '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'um ano',     '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 anos',    '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'um ano',     '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 anos',    '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'em poucos segundos', 'prefix');\n    assert.equal(moment(0).from(30000), 'poucos segundos atrás', 'suffix');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'em poucos segundos', 'in seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), 'em 5 dias', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'Hoje às 12:00',    'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'Hoje às 12:25',    'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'Hoje às 13:00',    'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'Amanhã às 12:00',  'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'Hoje às 11:00',    'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'Ontem às 12:00',   'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('dddd [às] LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd [às] LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd [às] LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format((m.day() === 0 || m.day() === 6) ? '[Último] dddd [às] LT' : '[Última] dddd [às] LT'),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format((m.day() === 0 || m.day() === 6) ? '[Último] dddd [às] LT' : '[Última] dddd [às] LT'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format((m.day() === 0 || m.day() === 6) ? '[Último] dddd [às] LT' : '[Última] dddd [às] LT'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('weeks year starting sunday format', function (assert) {\n    assert.equal(moment([2012, 0,  1]).format('w ww wo'), '1 01 1º', 'Jan  1 2012 should be week 1');\n    assert.equal(moment([2012, 0,  7]).format('w ww wo'), '1 01 1º', 'Jan  7 2012 should be week 1');\n    assert.equal(moment([2012, 0,  8]).format('w ww wo'), '2 02 2º', 'Jan  8 2012 should be week 2');\n    assert.equal(moment([2012, 0, 14]).format('w ww wo'), '2 02 2º', 'Jan 14 2012 should be week 2');\n    assert.equal(moment([2012, 0, 15]).format('w ww wo'), '3 03 3º', 'Jan 15 2012 should be week 3');\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\n\n\nfunction localeModule (name, lifecycle) {\n    QUnit.module('locale:' + name, {\n        setup : function () {\n            moment.locale(name);\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            moment.locale('en');\n            teardownDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n    defineCommonLocaleTests(name, -1, -1);\n}\n\nlocaleModule('pt');\n\ntest('parse', function (assert) {\n    var tests = 'Janeiro Jan_Fevereiro Fev_Março Mar_Abril Abr_Maio Mai_Junho Jun_Julho Jul_Agosto Ago_Setembro Set_Outubro Out_Novembro Nov_Dezembro Dez'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, MMMM Do YYYY, h:mm:ss a',      'Domingo, Fevereiro 14º 2010, 3:25:50 pm'],\n            ['ddd, hA',                            'Dom, 3PM'],\n            ['M Mo MM MMMM MMM',                   '2 2º 02 Fevereiro Fev'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14º 14'],\n            ['d do dddd ddd',                      '0 0º Domingo Dom'],\n            ['DDD DDDo DDDD',                      '45 45º 045'],\n            ['w wo ww',                            '6 6º 06'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'pm PM'],\n            ['[the] DDDo [day of the year]',       'the 45º day of the year'],\n            ['LTS',                                '15:25:50'],\n            ['L',                                  '14/02/2010'],\n            ['LL',                                 '14 de Fevereiro de 2010'],\n            ['LLL',                                '14 de Fevereiro de 2010 15:25'],\n            ['LLLL',                               'Domingo, 14 de Fevereiro de 2010 15:25'],\n            ['l',                                  '14/2/2010'],\n            ['ll',                                 '14 de Fev de 2010'],\n            ['lll',                                '14 de Fev de 2010 15:25'],\n            ['llll',                               'Dom, 14 de Fev de 2010 15:25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1º', '1º');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2º', '2º');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3º', '3º');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4º', '4º');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5º', '5º');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6º', '6º');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7º', '7º');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8º', '8º');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9º', '9º');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10º', '10º');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11º', '11º');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12º', '12º');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13º', '13º');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14º', '14º');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15º', '15º');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16º', '16º');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17º', '17º');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18º', '18º');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19º', '19º');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20º', '20º');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21º', '21º');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22º', '22º');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23º', '23º');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24º', '24º');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25º', '25º');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26º', '26º');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27º', '27º');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28º', '28º');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29º', '29º');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30º', '30º');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31º', '31º');\n});\n\ntest('format month', function (assert) {\n    var expected = 'Janeiro Jan_Fevereiro Fev_Março Mar_Abril Abr_Maio Mai_Junho Jun_Julho Jul_Agosto Ago_Setembro Set_Outubro Out_Novembro Nov_Dezembro Dez'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'Domingo Dom Do_Segunda-Feira Seg 2ª_Terça-Feira Ter 3ª_Quarta-Feira Qua 4ª_Quinta-Feira Qui 5ª_Sexta-Feira Sex 6ª_Sábado Sáb Sá'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'segundos',    '44 seconds = seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'um minuto',   '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'um minuto',   '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 minutos',  '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 minutos', '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'uma hora',    '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'uma hora',    '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 horas',    '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 horas',    '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 horas',   '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'um dia',      '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'um dia',      '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 dias',     '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'um dia',      '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 dias',     '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 dias',    '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'um mês',    '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'um mês',    '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'um mês',    '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 meses',   '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 meses',   '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 meses',   '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'um mês',    '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 meses',   '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'um ano',     '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 anos',    '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'um ano',     '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 anos',    '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'em segundos', 'prefix');\n    assert.equal(moment(0).from(30000), 'há segundos', 'suffix');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'em segundos', 'in seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), 'em 5 dias', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'Hoje às 12:00',    'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'Hoje às 12:25',    'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'Hoje às 13:00',    'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'Amanhã às 12:00',  'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'Hoje às 11:00',    'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'Ontem às 12:00',   'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('dddd [às] LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd [às] LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd [às] LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format((m.day() === 0 || m.day() === 6) ? '[Último] dddd [às] LT' : '[Última] dddd [às] LT'),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format((m.day() === 0 || m.day() === 6) ? '[Último] dddd [às] LT' : '[Última] dddd [às] LT'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format((m.day() === 0 || m.day() === 6) ? '[Último] dddd [às] LT' : '[Última] dddd [às] LT'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2012, 0,  1]).format('w ww wo'), '52 52 52º', 'Jan  1 2012 should be week 52');\n    assert.equal(moment([2012, 0,  2]).format('w ww wo'),  '1 01 1º', 'Jan  2 2012 should be week 1');\n    assert.equal(moment([2012, 0,  8]).format('w ww wo'),  '1 01 1º', 'Jan  8 2012 should be week 1');\n    assert.equal(moment([2012, 0,  9]).format('w ww wo'),  '2 02 2º', 'Jan  9 2012 should be week 2');\n    assert.equal(moment([2012, 0, 15]).format('w ww wo'),  '2 02 2º', 'Jan 15 2012 should be week 2');\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\n\n\nfunction localeModule (name, lifecycle) {\n    QUnit.module('locale:' + name, {\n        setup : function () {\n            moment.locale(name);\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            moment.locale('en');\n            teardownDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n    defineCommonLocaleTests(name, -1, -1);\n}\n\nlocaleModule('ro');\n\ntest('parse', function (assert) {\n    var tests = 'ianuarie ian._februarie febr._martie mart._aprilie apr._mai mai_iunie iun._iulie iul._august aug._septembrie sept._octombrie oct._noiembrie nov._decembrie dec.'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, MMMM Do YYYY, h:mm:ss A',  'duminică, februarie 14 2010, 3:25:50 PM'],\n            ['ddd, hA',                        'Dum, 3PM'],\n            ['M Mo MM MMMM MMM',               '2 2 02 februarie febr.'],\n            ['YYYY YY',                        '2010 10'],\n            ['D Do DD',                        '14 14 14'],\n            ['d do dddd ddd dd',               '0 0 duminică Dum Du'],\n            ['DDD DDDo DDDD',                  '45 45 045'],\n            ['w wo ww',                        '7 7 07'],\n            ['h hh',                           '3 03'],\n            ['H HH',                           '15 15'],\n            ['m mm',                           '25 25'],\n            ['s ss',                           '50 50'],\n            ['a A',                            'pm PM'],\n            ['[a] DDDo[a zi a anului]',        'a 45a zi a anului'],\n            ['LTS',                            '15:25:50'],\n            ['L',                              '14.02.2010'],\n            ['LL',                             '14 februarie 2010'],\n            ['LLL',                            '14 februarie 2010 15:25'],\n            ['LLLL',                           'duminică, 14 februarie 2010 15:25'],\n            ['l',                              '14.2.2010'],\n            ['ll',                             '14 febr. 2010'],\n            ['lll',                            '14 febr. 2010 15:25'],\n            ['llll',                           'Dum, 14 febr. 2010 15:25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1', '1');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2', '2');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3', '3');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4', '4');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5', '5');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6', '6');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7', '7');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8', '8');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9', '9');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10', '10');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11', '11');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12', '12');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13', '13');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14', '14');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15', '15');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16', '16');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17', '17');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18', '18');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19', '19');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20', '20');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21', '21');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22', '22');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23', '23');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24', '24');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25', '25');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26', '26');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27', '27');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28', '28');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29', '29');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30', '30');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31', '31');\n});\n\ntest('format month', function (assert) {\n    var expected = 'ianuarie ian._februarie febr._martie mart._aprilie apr._mai mai_iunie iun._iulie iul._august aug._septembrie sept._octombrie oct._noiembrie nov._decembrie dec.'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'duminică Dum Du_luni Lun Lu_marți Mar Ma_miercuri Mie Mi_joi Joi Jo_vineri Vin Vi_sâmbătă Sâm Sâ'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'câteva secunde', '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'un minut',       '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'un minut',       '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 minute',       '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 de minute',   '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'o oră',          '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'o oră',          '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 ore',          '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 ore',          '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 de ore',      '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'o zi',           '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'o zi',           '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 zile',         '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'o zi',           '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 zile',         '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 de zile',     '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'o lună',         '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'o lună',         '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'o lună',         '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 luni',         '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 luni',         '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 luni',         '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'o lună',         '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 luni',         '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'un an',          '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 ani',          '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'un an',          '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 ani',          '5 years = 5 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 19}), true),   '19 ani',        '19 years = 19 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 20}), true),   '20 de ani',     '20 years = 20 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 100}), true),   '100 de ani',   '100 years = 100 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 101}), true),   '101 ani',      '101 years = 101 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 119}), true),   '119 ani',      '119 years = 119 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 120}), true),   '120 de ani',   '120 years = 120 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 219}), true),   '219 ani',      '219 years = 219 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 220}), true),   '220 de ani',   '220 years = 220 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'peste câteva secunde',   'prefix');\n    assert.equal(moment(0).from(30000), 'câteva secunde în urmă', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'câteva secunde în urmă',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'peste câteva secunde', 'in a few seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), 'peste 5 zile', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'azi la 12:00',     'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'azi la 12:25',     'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'azi la 13:00',     'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'mâine la 12:00',   'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'azi la 11:00',     'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'ieri la 12:00',    'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('dddd [la] LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd [la] LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd [la] LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('[fosta] dddd [la] LT'),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[fosta] dddd [la] LT'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[fosta] dddd [la] LT'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2011, 11, 26]).format('w ww wo'), '1 01 1', 'Dec 26 2011 should be week 1');\n    assert.equal(moment([2012,  0,  1]).format('w ww wo'), '1 01 1', 'Jan  1 2012 should be week 1');\n    assert.equal(moment([2012,  0,  2]).format('w ww wo'), '2 02 2', 'Jan  2 2012 should be week 2');\n    assert.equal(moment([2012,  0,  8]).format('w ww wo'), '2 02 2', 'Jan  8 2012 should be week 2');\n    assert.equal(moment([2012,  0,  9]).format('w ww wo'), '3 03 3', 'Jan  9 2012 should be week 3');\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\n\n\nfunction localeModule (name, lifecycle) {\n    QUnit.module('locale:' + name, {\n        setup : function () {\n            moment.locale(name);\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            moment.locale('en');\n            teardownDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n    defineCommonLocaleTests(name, -1, -1);\n}\n\nlocaleModule('ru');\n\ntest('parse', function (assert) {\n    var tests = 'январь янв._февраль февр._март март_апрель апр._май май_июнь июнь_июль июль_август авг._сентябрь сент._октябрь окт._ноябрь нояб._декабрь дек.'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    function equalTestStrict(input, mmm, monthIndex) {\n        assert.equal(moment(input, mmm, true).month(), monthIndex, input + ' ' + mmm + ' should be strict month ' + (monthIndex + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n\n        equalTestStrict(tests[i][1], 'MMM', i);\n        equalTestStrict(tests[i][0], 'MMMM', i);\n        equalTestStrict(tests[i][1].toLocaleLowerCase(), 'MMM', i);\n        equalTestStrict(tests[i][1].toLocaleUpperCase(), 'MMM', i);\n        equalTestStrict(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTestStrict(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('parse exceptional case', function (assert) {\n    assert.equal(moment('11 Мая 1989', ['DD MMMM YYYY']).format('DD-MM-YYYY'), '11-05-1989');\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, Do MMMM YYYY, HH:mm:ss',       'воскресенье, 14-го февраля 2010, 15:25:50'],\n            ['ddd, h A',                           'вс, 3 дня'],\n            ['M Mo MM MMMM MMM',                   '2 2-й 02 февраль февр.'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14-го 14'],\n            ['d do dddd ddd dd',                   '0 0-й воскресенье вс вс'],\n            ['DDD DDDo DDDD',                      '45 45-й 045'],\n            ['w wo ww',                            '7 7-я 07'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'дня дня'],\n            ['DDDo [день года]',                   '45-й день года'],\n            ['LTS',                                '15:25:50'],\n            ['L',                                  '14.02.2010'],\n            ['LL',                                 '14 февраля 2010 г.'],\n            ['LLL',                                '14 февраля 2010 г., 15:25'],\n            ['LLLL',                               'воскресенье, 14 февраля 2010 г., 15:25'],\n            ['l',                                  '14.2.2010'],\n            ['ll',                                 '14 февр. 2010 г.'],\n            ['lll',                                '14 февр. 2010 г., 15:25'],\n            ['llll',                               'вс, 14 февр. 2010 г., 15:25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format meridiem', function (assert) {\n    assert.equal(moment([2012, 11, 28, 0, 0]).format('A'), 'ночи', 'night');\n    assert.equal(moment([2012, 11, 28, 3, 59]).format('A'), 'ночи', 'night');\n    assert.equal(moment([2012, 11, 28, 4, 0]).format('A'), 'утра', 'morning');\n    assert.equal(moment([2012, 11, 28, 11, 59]).format('A'), 'утра', 'morning');\n    assert.equal(moment([2012, 11, 28, 12, 0]).format('A'), 'дня', 'afternoon');\n    assert.equal(moment([2012, 11, 28, 16, 59]).format('A'), 'дня', 'afternoon');\n    assert.equal(moment([2012, 11, 28, 17, 0]).format('A'), 'вечера', 'evening');\n    assert.equal(moment([2012, 11, 28, 23, 59]).format('A'), 'вечера', 'evening');\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1-й', '1-й');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2-й', '2-й');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3-й', '3-й');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4-й', '4-й');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5-й', '5-й');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6-й', '6-й');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7-й', '7-й');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8-й', '8-й');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9-й', '9-й');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10-й', '10-й');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11-й', '11-й');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12-й', '12-й');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13-й', '13-й');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14-й', '14-й');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15-й', '15-й');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16-й', '16-й');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17-й', '17-й');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18-й', '18-й');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19-й', '19-й');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20-й', '20-й');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21-й', '21-й');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22-й', '22-й');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23-й', '23-й');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24-й', '24-й');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25-й', '25-й');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26-й', '26-й');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27-й', '27-й');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28-й', '28-й');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29-й', '29-й');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30-й', '30-й');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31-й', '31-й');\n});\n\ntest('format month', function (assert) {\n    var expected = 'январь янв._февраль февр._март март_апрель апр._май май_июнь июнь_июль июль_август авг._сентябрь сент._октябрь окт._ноябрь нояб._декабрь дек.'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format month case', function (assert) {\n    var months = {\n        'nominative': 'январь_февраль_март_апрель_май_июнь_июль_август_сентябрь_октябрь_ноябрь_декабрь'.split('_'),\n        'accusative': 'января_февраля_марта_апреля_мая_июня_июля_августа_сентября_октября_ноября_декабря'.split('_')\n    }, i;\n    for (i = 0; i < 12; i++) {\n        assert.equal(moment([2011, i, 1]).format('D MMMM'), '1 ' + months.accusative[i], '1 ' + months.accusative[i]);\n        assert.equal(moment([2011, i, 1]).format('MMMM'), months.nominative[i], '1 ' + months.nominative[i]);\n    }\n});\n\ntest('format month short case', function (assert) {\n    var monthsShort = {\n        'nominative': 'янв._февр._март_апр._май_июнь_июль_авг._сент._окт._нояб._дек.'.split('_'),\n        'accusative': 'янв._февр._мар._апр._мая_июня_июля_авг._сент._окт._нояб._дек.'.split('_')\n    }, i;\n    for (i = 0; i < 12; i++) {\n        assert.equal(moment([2011, i, 1]).format('D MMM'), '1 ' + monthsShort.accusative[i], '1 ' + monthsShort.accusative[i]);\n        assert.equal(moment([2011, i, 1]).format('MMM'), monthsShort.nominative[i], '1 ' + monthsShort.nominative[i]);\n    }\n});\n\ntest('format month case with escaped symbols', function (assert) {\n    var months = {\n        'nominative': 'январь_февраль_март_апрель_май_июнь_июль_август_сентябрь_октябрь_ноябрь_декабрь'.split('_'),\n        'accusative': 'января_февраля_марта_апреля_мая_июня_июля_августа_сентября_октября_ноября_декабря'.split('_')\n    }, i;\n    for (i = 0; i < 12; i++) {\n        assert.equal(moment([2013, i, 1]).format('D[] MMMM'), '1 ' + months.accusative[i], '1 ' + months.accusative[i]);\n        assert.equal(moment([2013, i, 1]).format('[<i>]D[</i>] [<b>]MMMM[</b>]'), '<i>1</i> <b>' + months.accusative[i] + '</b>', '1 <b>' + months.accusative[i] + '</b>');\n        assert.equal(moment([2013, i, 1]).format('D[-й день] MMMM'), '1-й день ' + months.accusative[i], '1-й день ' + months.accusative[i]);\n        assert.equal(moment([2013, i, 1]).format('D, MMMM'), '1, ' + months.nominative[i], '1, ' + months.nominative[i]);\n    }\n});\n\ntest('format month short case with escaped symbols', function (assert) {\n    var monthsShort = {\n        'nominative': 'янв._февр._март_апр._май_июнь_июль_авг._сент._окт._нояб._дек.'.split('_'),\n        'accusative': 'янв._февр._мар._апр._мая_июня_июля_авг._сент._окт._нояб._дек.'.split('_')\n    }, i;\n    for (i = 0; i < 12; i++) {\n        assert.equal(moment([2013, i, 1]).format('D[] MMM'), '1 ' + monthsShort.accusative[i], '1 ' + monthsShort.accusative[i]);\n        assert.equal(moment([2013, i, 1]).format('[<i>]D[</i>] [<b>]MMM[</b>]'), '<i>1</i> <b>' + monthsShort.accusative[i] + '</b>', '1 <b>' + monthsShort.accusative[i] + '</b>');\n        assert.equal(moment([2013, i, 1]).format('D[-й день] MMM'), '1-й день ' + monthsShort.accusative[i], '1-й день ' + monthsShort.accusative[i]);\n        assert.equal(moment([2013, i, 1]).format('D, MMM'), '1, ' + monthsShort.nominative[i], '1, ' + monthsShort.nominative[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'воскресенье вс вс_понедельник пн пн_вторник вт вт_среда ср ср_четверг чт чт_пятница пт пт_суббота сб сб'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'несколько секунд',    '44 seconds = seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'минута',   '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'минута',   '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 минуты',  '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 31}), true),  '31 минута',  '31 minutes = 31 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 минуты', '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'час',    '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'час',    '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 часа',    '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 часов',    '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 час',   '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'день',      '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'день',      '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 дня',     '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'день',      '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 дней',     '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 11}), true),  '11 дней',     '11 days = 11 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 21}), true),  '21 день',     '21 days = 21 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 дней',    '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'месяц',    '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'месяц',    '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'месяц',    '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 месяца',   '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 месяца',   '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 месяца',   '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'месяц',    '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 месяцев',   '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'год',     '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 года',    '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'год',     '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 лет',    '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'через несколько секунд', 'prefix');\n    assert.equal(moment(0).from(30000), 'несколько секунд назад', 'suffix');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'через несколько секунд', 'in seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), 'через 5 дней', 'in 5 days');\n    assert.equal(moment().add({m: 31}).fromNow(), 'через 31 минуту', 'in 31 minutes = in 31 minutes');\n    assert.equal(moment().subtract({m: 31}).fromNow(), '31 минуту назад', '31 minutes ago = 31 minutes ago');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'Сегодня в 12:00',     'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'Сегодня в 12:25',     'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'Сегодня в 13:00',     'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'Завтра в 12:00',      'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'Сегодня в 11:00',     'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'Вчера в 12:00',       'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m, now;\n\n    function makeFormatNext(d) {\n        switch (d.day()) {\n            case 0:\n                return '[В следующее] dddd [в] LT';\n            case 1:\n            case 2:\n            case 4:\n                return '[В следующий] dddd [в] LT';\n            case 3:\n            case 5:\n            case 6:\n                return '[В следующую] dddd [в] LT';\n        }\n    }\n\n    function makeFormatThis(d) {\n        if (d.day() === 2) {\n            return '[Во] dddd [в] LT';\n        }\n        else {\n            return '[В] dddd [в] LT';\n        }\n    }\n\n    now = moment().startOf('week');\n    for (i = 2; i < 7; i++) {\n        m = moment(now).add({d: i});\n        assert.equal(m.calendar(now),       m.format(makeFormatThis(m)),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(now),       m.format(makeFormatThis(m)),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(now),       m.format(makeFormatThis(m)),  'Today + ' + i + ' days end of day');\n    }\n\n    now = moment().endOf('week');\n    for (i = 2; i < 7; i++) {\n        m = moment(now).add({d: i});\n        assert.equal(m.calendar(now),       m.format(makeFormatNext(m)),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(now),       m.format(makeFormatNext(m)),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(now),       m.format(makeFormatNext(m)),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m, now;\n\n    function makeFormatLast(d) {\n        switch (d.day()) {\n            case 0:\n                return '[В прошлое] dddd [в] LT';\n            case 1:\n            case 2:\n            case 4:\n                return '[В прошлый] dddd [в] LT';\n            case 3:\n            case 5:\n            case 6:\n                return '[В прошлую] dddd [в] LT';\n        }\n    }\n\n    function makeFormatThis(d) {\n        if (d.day() === 2) {\n            return '[Во] dddd [в] LT';\n        }\n        else {\n            return '[В] dddd [в] LT';\n        }\n    }\n\n    now = moment().startOf('week');\n    for (i = 2; i < 7; i++) {\n        m = moment(now).subtract({d: i});\n        assert.equal(m.calendar(now),       m.format(makeFormatLast(m)),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(now),       m.format(makeFormatLast(m)),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(now),       m.format(makeFormatLast(m)),  'Today - ' + i + ' days end of day');\n    }\n\n    now = moment().endOf('week');\n    for (i = 2; i < 7; i++) {\n        m = moment(now).subtract({d: i});\n        assert.equal(m.calendar(now),       m.format(makeFormatThis(m)),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(now),       m.format(makeFormatThis(m)),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(now),       m.format(makeFormatThis(m)),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2011, 11, 26]).format('w ww wo'), '1 01 1-я', 'Dec 26 2011 should be week 1');\n    assert.equal(moment([2012,  0,  1]).format('w ww wo'), '1 01 1-я', 'Jan  1 2012 should be week 1');\n    assert.equal(moment([2012,  0,  2]).format('w ww wo'), '2 02 2-я', 'Jan  2 2012 should be week 2');\n    assert.equal(moment([2012,  0,  8]).format('w ww wo'), '2 02 2-я', 'Jan  8 2012 should be week 2');\n    assert.equal(moment([2012,  0,  9]).format('w ww wo'), '3 03 3-я', 'Jan  9 2012 should be week 3');\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\n\n\nfunction localeModule (name, lifecycle) {\n    QUnit.module('locale:' + name, {\n        setup : function () {\n            moment.locale(name);\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            moment.locale('en');\n            teardownDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n    defineCommonLocaleTests(name, -1, -1);\n}\n\nlocaleModule('sd');\n\nvar months = [\n    'جنوري',\n    'فيبروري',\n    'مارچ',\n    'اپريل',\n    'مئي',\n    'جون',\n    'جولاءِ',\n    'آگسٽ',\n    'سيپٽمبر',\n    'آڪٽوبر',\n    'نومبر',\n    'ڊسمبر'\n];\nvar days = [\n    'آچر',\n    'سومر',\n    'اڱارو',\n    'اربع',\n    'خميس',\n    'جمع',\n    'ڇنڇر'\n];\n\ntest('parse', function (assert) {\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (var i = 0; i < 12; i++) {\n        equalTest(months[i], 'MMM', i);\n        equalTest(months[i], 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, MMMM Do YYYY, h:mm:ss a',      'آچر، فيبروري 14 2010، 3:25:50 شام'],\n            ['ddd, hA',                            'آچر، 3شام'],\n            ['M Mo MM MMMM MMM',                   '2 2 02 فيبروري فيبروري'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14 14'],\n            ['d do dddd ddd dd',                   '0 0 آچر آچر آچر'],\n            ['DDD DDDo DDDD',                      '45 45 045'],\n            ['w wo ww',                            '6 6 06'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'شام شام'],\n            ['[سال جو] DDDo[ڏينهن]',       'سال جو 45ڏينهن'],\n            ['LTS',                                '15:25:50'],\n            ['L',                                  '14/02/2010'],\n            ['LL',                                 '14 فيبروري 2010'],\n            ['LLL',                                '14 فيبروري 2010 15:25'],\n            ['LLLL',                               'آچر، 14 فيبروري 2010 15:25'],\n            ['l',                                  '14/2/2010'],\n            ['ll',                                 '14 فيبروري 2010'],\n            ['lll',                                '14 فيبروري 2010 15:25'],\n            ['llll',                               'آچر، 14 فيبروري 2010 15:25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1', '1');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2', '2');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3', '3');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4', '4');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5', '5');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6', '6');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7', '7');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8', '8');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9', '9');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10', '10');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11', '11');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12', '12');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13', '13');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14', '14');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15', '15');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16', '16');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17', '17');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18', '18');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19', '19');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20', '20');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21', '21');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22', '22');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23', '23');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24', '24');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25', '25');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26', '26');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27', '27');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28', '28');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29', '29');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30', '30');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31', '31');\n});\n\ntest('format month', function (assert) {\n    for (var i = 0; i < months.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), months[i] + ' ' + months[i], months[i] + ' ' + months[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    for (var i = 0; i < days.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), days[i] + ' ' + days[i] + ' ' + days[i], days[i] + ' ' + days[i] + ' ' + days[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'چند سيڪنڊ', '44 seconds = چند سيڪنڊ');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'هڪ منٽ',      '45 seconds = هڪ منٽ');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'هڪ منٽ',      '89 seconds = هڪ منٽ');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 منٽ',     '90 seconds = 2 منٽ');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 منٽ',    '44 minutes = 44 منٽ');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'هڪ ڪلاڪ',       '45 minutes = هڪ ڪلاڪ');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'هڪ ڪلاڪ',       '89 minutes = هڪ ڪلاڪ');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 ڪلاڪ',       '90 minutes = 2 ڪلاڪ');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 ڪلاڪ',       '5 hours = 5 ڪلاڪ');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 ڪلاڪ',      '21 hours = 21 ڪلاڪ');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'هڪ ڏينهن',         '22 hours = هڪ ڏينهن');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'هڪ ڏينهن',         '35 hours = هڪ ڏينهن');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 ڏينهن',        '36 hours = 2 ڏينهن');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'هڪ ڏينهن',         '1 day = هڪ ڏينهن');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 ڏينهن',        '5 days = 5 ڏينهن');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 ڏينهن',       '25 days = 25 ڏينهن');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'هڪ مهينو',       '26 days = هڪ مهينو');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'هڪ مهينو',       '30 days = هڪ مهينو');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'هڪ مهينو',       '43 days = هڪ مهينو');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 مهينا',      '46 days = 2 مهينا');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 مهينا',      '75 days = 2 مهينا');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 مهينا',      '76 days = 3 مهينا');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'هڪ مهينو',       '1 month = هڪ مهينو');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 مهينا',      '5 months = 5 مهينا');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'هڪ سال',        '345 days = هڪ سال');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 سال',       '548 days = 2 سال');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'هڪ سال',        '1 year = هڪ سال');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 سال',       '5 years = 5 سال');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'چند سيڪنڊ پوء',  'prefix');\n    assert.equal(moment(0).from(30000), 'چند سيڪنڊ اڳ', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'چند سيڪنڊ اڳ',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'چند سيڪنڊ پوء', 'in a few seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), '5 ڏينهن پوء', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'اڄ 12:00',      'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'اڄ 12:25',      'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'اڄ 13:00',      'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'سڀاڻي 12:00',   'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'اڄ 11:00',      'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'ڪالهه 12:00',  'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('dddd [اڳين هفتي تي] LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd [اڳين هفتي تي] LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd [اڳين هفتي تي] LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('[گزريل هفتي] dddd [تي] LT'),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[گزريل هفتي] dddd [تي] LT'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[گزريل هفتي] dddd [تي] LT'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2012, 0,  1]).format('w ww wo'), '52 52 52', 'Jan  1 2012 should be week 52');\n    assert.equal(moment([2012, 0,  2]).format('w ww wo'),   '1 01 1', 'Jan  2 2012 should be week 1');\n    assert.equal(moment([2012, 0,  8]).format('w ww wo'),   '1 01 1', 'Jan  8 2012 should be week 1');\n    assert.equal(moment([2012, 0,  9]).format('w ww wo'),   '2 02 2', 'Jan  9 2012 should be week 2');\n    assert.equal(moment([2012, 0, 15]).format('w ww wo'),   '2 02 2', 'Jan 15 2012 should be week 2');\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\n\n\nfunction localeModule (name, lifecycle) {\n    QUnit.module('locale:' + name, {\n        setup : function () {\n            moment.locale(name);\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            moment.locale('en');\n            teardownDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n    defineCommonLocaleTests(name, -1, -1);\n}\n\nlocaleModule('se');\n\ntest('parse', function (assert) {\n    var i,\n        tests = 'ođđajagemánnu ođđj_guovvamánnu guov_njukčamánnu njuk_cuoŋománnu cuo_miessemánnu mies_geassemánnu geas_suoidnemánnu suoi_borgemánnu borg_čakčamánnu čakč_golggotmánnu golg_skábmamánnu skáb_juovlamánnu juov'.split('_');\n\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, MMMM Do YYYY, h:mm:ss a',      'sotnabeaivi, guovvamánnu 14. 2010, 3:25:50 pm'],\n            ['ddd, hA',                            'sotn, 3PM'],\n            ['M Mo MM MMMM MMM',                   '2 2. 02 guovvamánnu guov'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14. 14'],\n            ['d do dddd ddd dd',                   '0 0. sotnabeaivi sotn s'],\n            ['DDD DDDo DDDD',                      '45 45. 045'],\n            ['w wo ww',                            '6 6. 06'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'pm PM'],\n            ['[jagi] DDDo [beaivi]',               'jagi 45. beaivi'],\n            ['LTS',                                '15:25:50'],\n            ['L',                                  '14.02.2010'],\n            ['LL',                                 'guovvamánnu 14. b. 2010'],\n            ['LLL',                                'guovvamánnu 14. b. 2010 ti. 15:25'],\n            ['LLLL',                               'sotnabeaivi, guovvamánnu 14. b. 2010 ti. 15:25'],\n            ['l',                                  '14.2.2010'],\n            ['ll',                                 'guov 14. b. 2010'],\n            ['lll',                                'guov 14. b. 2010 ti. 15:25'],\n            ['llll',                               'sotn, guov 14. b. 2010 ti. 15:25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1.', '1.');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2.', '2.');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3.', '3.');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4.', '4.');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5.', '5.');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6.', '6.');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7.', '7.');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8.', '8.');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9.', '9.');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10.', '10.');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11.', '11.');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12.', '12.');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13.', '13.');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14.', '14.');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15.', '15.');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16.', '16.');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17.', '17.');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18.', '18.');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19.', '19.');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20.', '20.');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21.', '21.');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22.', '22.');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23.', '23.');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24.', '24.');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25.', '25.');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26.', '26.');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27.', '27.');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28.', '28.');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29.', '29.');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30.', '30.');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31.', '31.');\n});\n\ntest('format month', function (assert) {\n    var i,\n        expected = 'ođđajagemánnu ođđj_guovvamánnu guov_njukčamánnu njuk_cuoŋománnu cuo_miessemánnu mies_geassemánnu geas_suoidnemánnu suoi_borgemánnu borg_čakčamánnu čakč_golggotmánnu golg_skábmamánnu skáb_juovlamánnu juov'.split('_');\n\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var i,\n        expected = 'sotnabeaivi sotn s_vuossárga vuos v_maŋŋebárga maŋ m_gaskavahkku gask g_duorastat duor d_bearjadat bear b_lávvardat láv L'.split('_');\n\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'moadde sekunddat', '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'okta minuhta',  '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'okta minuhta',  '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 minuhtat',    '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 minuhtat',   '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'okta diimmu',   '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'okta diimmu',   '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 diimmut',     '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 diimmut',     '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 diimmut',    '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'okta beaivi',   '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'okta beaivi',   '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 beaivvit',    '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'okta beaivi',   '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 beaivvit',    '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 beaivvit',   '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'okta mánnu',    '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'okta mánnu',    '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'okta mánnu',    '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 mánut',       '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 mánut',       '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 mánut',       '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'okta mánnu',    '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 mánut',       '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'okta jahki',    '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 jagit',       '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'okta jahki',    '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 jagit',       '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'moadde sekunddat geažes',  'prefix');\n    assert.equal(moment(0).from(30000), 'maŋit moadde sekunddat', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'maŋit moadde sekunddat',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'moadde sekunddat geažes', 'in a few seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), '5 beaivvit geažes', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'otne ti 12:00',     'Today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'otne ti 12:25',     'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'otne ti 13:00',     'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'ihttin ti 12:00',   'Tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'otne ti 11:00',     'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'ikte ti 12:00',     'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('dddd [ti] LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd [ti] LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd [ti] LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('[ovddit] dddd [ti] LT'),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[ovddit] dddd [ti] LT'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[ovddit] dddd [ti] LT'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2012, 0,  1]).format('w ww wo'), '52 52 52.', 'Jan  1 2012 should be week 52');\n    assert.equal(moment([2012, 0,  2]).format('w ww wo'),  '1 01 1.', 'Jan  2 2012 should be week 1');\n    assert.equal(moment([2012, 0,  8]).format('w ww wo'),  '1 01 1.', 'Jan  8 2012 should be week 1');\n    assert.equal(moment([2012, 0,  9]).format('w ww wo'),  '2 02 2.', 'Jan  9 2012 should be week 2');\n    assert.equal(moment([2012, 0, 15]).format('w ww wo'),  '2 02 2.', 'Jan 15 2012 should be week 2');\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\n\n\nfunction localeModule (name, lifecycle) {\n    QUnit.module('locale:' + name, {\n        setup : function () {\n            moment.locale(name);\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            moment.locale('en');\n            teardownDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n    defineCommonLocaleTests(name, -1, -1);\n}\n\nlocaleModule('si');\n\n/*jshint -W100*/\ntest('parse', function (assert) {\n    var tests = 'ජනවාරි ජන_පෙබරවාරි පෙබ_මාර්තු මාර්_අප්‍රේල් අප්_මැයි මැයි_ජූනි ජූනි_ජූලි ජූලි_අගෝස්තු අගෝ_සැප්තැම්බර් සැප්_ඔක්තෝබර් ඔක්_නොවැම්බර් නොවැ_දෙසැම්බර් දෙසැ'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['YYYY MMMM Do dddd, a h:mm:ss',       '2010 පෙබරවාරි 14 වැනි ඉරිදා, ප.ව. 3:25:50'],\n            ['YYYY MMMM Do dddd, a h:mm:ss',       '2010 පෙබරවාරි 14 වැනි ඉරිදා, ප.ව. 3:25:50'],\n            ['ddd, A h',                            'ඉරි, පස් වරු 3'],\n            ['M Mo MM MMMM MMM',                   '2 2 වැනි 02 පෙබරවාරි පෙබ'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14 වැනි 14'],\n            ['d do dddd ddd dd',                   '0 0 වැනි ඉරිදා ඉරි ඉ'],\n            ['DDD DDDo DDDD',                      '45 45 වැනි 045'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'ප.ව. පස් වරු'],\n            ['[වසරේ] DDDo [දිනය]',                      'වසරේ 45 වැනි දිනය'],\n            ['LTS',                                'ප.ව. 3:25:50'],\n            ['LT',                                 'ප.ව. 3:25'],\n            ['L',                                  '2010/02/14'],\n            ['LL',                                 '2010 පෙබරවාරි 14'],\n            ['LLL',                                '2010 පෙබරවාරි 14, ප.ව. 3:25'],\n            ['LLLL',                               '2010 පෙබරවාරි 14 වැනි ඉරිදා, ප.ව. 3:25:50'],\n            ['l',                                  '2010/2/14'],\n            ['ll',                                 '2010 පෙබ 14'],\n            ['lll',                                '2010 පෙබ 14, ප.ව. 3:25'],\n            ['llll',                               '2010 පෙබ 14 වැනි ඉරි, ප.ව. 3:25:50']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1 වැනි', '1 වැනි');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2 වැනි', '2 වැනි');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3 වැනි', '3 වැනි');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4 වැනි', '4 වැනි');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5 වැනි', '5 වැනි');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6 වැනි', '6 වැනි');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7 වැනි', '7 වැනි');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8 වැනි', '8 වැනි');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9 වැනි', '9 වැනි');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10 වැනි', '10 වැනි');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11 වැනි', '11 වැනි');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12 වැනි', '12 වැනි');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13 වැනි', '13 වැනි');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14 වැනි', '14 වැනි');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15 වැනි', '15 වැනි');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16 වැනි', '16 වැනි');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17 වැනි', '17 වැනි');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18 වැනි', '18 වැනි');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19 වැනි', '19 වැනි');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20 වැනි', '20 වැනි');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21 වැනි', '21 වැනි');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22 වැනි', '22 වැනි');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23 වැනි', '23 වැනි');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24 වැනි', '24 වැනි');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25 වැනි', '25 වැනි');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26 වැනි', '26 වැනි');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27 වැනි', '27 වැනි');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28 වැනි', '28 වැනි');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29 වැනි', '29 වැනි');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30 වැනි', '30 වැනි');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31 වැනි', '31 වැනි');\n});\n\ntest('format month', function (assert) {\n    var expected = 'ජනවාරි ජන_පෙබරවාරි පෙබ_මාර්තු මාර්_අප්‍රේල් අප්_මැයි මැයි_ජූනි ජූනි_ජූලි ජූලි_අගෝස්තු අගෝ_සැප්තැම්බර් සැප්_ඔක්තෝබර් ඔක්_නොවැම්බර් නොවැ_දෙසැම්බර් දෙසැ'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'ඉරිදා ඉරි ඉ_සඳුදා සඳු ස_අඟහරුවාදා අඟ අ_බදාදා බදා බ_බ්‍රහස්පතින්දා බ්‍රහ බ්‍ර_සිකුරාදා සිකු සි_සෙනසුරාදා සෙන සෙ'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'තත්පර කිහිපය', '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'මිනිත්තුව',      '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'මිනිත්තුව',      '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  'මිනිත්තු 2',     '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  'මිනිත්තු 44',    '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'පැය',       '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'පැය',       '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  'පැය 2',       '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   'පැය 5',       '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  'පැය 21',      '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'දිනය',         '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'දිනය',         '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  'දින 2',        '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'දිනය',         '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   'දින 5',        '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  'දින 25',       '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'මාසය',       '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'මාසය',       '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'මාසය',       '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  'මාස 2',      '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  'මාස 2',      '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  'මාස 3',      '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'මාසය',       '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   'මාස 5',      '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'වසර',        '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), 'වසර 2',       '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'වසර',        '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   'වසර 5',       '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'තත්පර කිහිපයකින්',  'prefix');\n    assert.equal(moment(0).from(30000), 'තත්පර කිහිපයකට පෙර', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'තත්පර කිහිපයකට පෙර',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'තත්පර කිහිපයකින්', 'in a few seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), 'දින 5කින්', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'අද ප.ව. 12:00ට',     'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'අද ප.ව. 12:25ට',     'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'අද ප.ව. 1:00ට',      'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'හෙට ප.ව. 12:00ට',   'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'අද පෙ.ව. 11:00ට',    'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'ඊයේ ප.ව. 12:00ට',   'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('dddd LT[ට]'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd LT[ට]'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd LT[ට]'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('[පසුගිය] dddd LT[ට]'),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[පසුගිය] dddd LT[ට]'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[පසුගිය] dddd LT[ට]'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\n\n\nfunction localeModule (name, lifecycle) {\n    QUnit.module('locale:' + name, {\n        setup : function () {\n            moment.locale(name);\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            moment.locale('en');\n            teardownDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n    defineCommonLocaleTests(name, -1, -1);\n}\n\nlocaleModule('sk');\n\ntest('parse', function (assert) {\n    var tests = 'január jan._február feb._marec mar._apríl apr._máj máj_jún jún._júl júl._august aug._september sep._október okt._november nov._december dec.'.split('_'), i;\n    function equalTest(input, mmm, monthIndex) {\n        assert.equal(moment(input, mmm).month(), monthIndex, input + ' should be month ' + (monthIndex + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, MMMM Do YYYY, h:mm:ss',  'nedeľa, február 14. 2010, 3:25:50'],\n            ['ddd, h',                       'ne, 3'],\n            ['M Mo MM MMMM MMM',             '2 2. 02 február feb'],\n            ['YYYY YY',                      '2010 10'],\n            ['D Do DD',                      '14 14. 14'],\n            ['d do dddd ddd dd',             '0 0. nedeľa ne ne'],\n            ['DDD DDDo DDDD',                '45 45. 045'],\n            ['w wo ww',                      '6 6. 06'],\n            ['h hh',                         '3 03'],\n            ['H HH',                         '15 15'],\n            ['m mm',                         '25 25'],\n            ['s ss',                         '50 50'],\n            ['a A',                          'pm PM'],\n            ['DDDo [deň v roku]',            '45. deň v roku'],\n            ['LTS',                          '15:25:50'],\n            ['L',                            '14.02.2010'],\n            ['LL',                           '14. február 2010'],\n            ['LLL',                          '14. február 2010 15:25'],\n            ['LLLL',                         'nedeľa 14. február 2010 15:25'],\n            ['l',                            '14.2.2010'],\n            ['ll',                           '14. feb 2010'],\n            ['lll',                          '14. feb 2010 15:25'],\n            ['llll',                         'ne 14. feb 2010 15:25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1.', '1.');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2.', '2.');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3.', '3.');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4.', '4.');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5.', '5.');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6.', '6.');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7.', '7.');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8.', '8.');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9.', '9.');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10.', '10.');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11.', '11.');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12.', '12.');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13.', '13.');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14.', '14.');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15.', '15.');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16.', '16.');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17.', '17.');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18.', '18.');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19.', '19.');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20.', '20.');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21.', '21.');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22.', '22.');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23.', '23.');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24.', '24.');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25.', '25.');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26.', '26.');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27.', '27.');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28.', '28.');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29.', '29.');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30.', '30.');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31.', '31.');\n});\n\ntest('format month', function (assert) {\n    var expected = 'január jan_február feb_marec mar_apríl apr_máj máj_jún jún_júl júl_august aug_september sep_október okt_november nov_december dec'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'nedeľa ne ne_pondelok po po_utorok ut ut_streda st st_štvrtok št št_piatok pi pi_sobota so so'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'pár sekúnd',  '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'minúta',        '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'minúta',        '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 minúty',      '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 minút',     '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'hodina',       '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'hodina',       '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 hodiny',     '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 hodín',      '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 hodín',     '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'deň',       '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'deň',       '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 dni',         '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'deň',       '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 dní',         '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 dní',        '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'mesiac',       '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'mesiac',       '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'mesiac',       '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 mesiace',    '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 mesiace',    '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 mesiace',    '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'mesiac',       '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 mesiacov',    '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'rok',           '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 roky',        '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'rok',           '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 rokov',         '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'za pár sekúnd',  'prefix');\n    assert.equal(moment(0).from(30000), 'pred pár sekundami', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'pred pár sekundami',  'now from now should display as in the past');\n});\n\ntest('fromNow (future)', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'za pár sekúnd', 'in a few seconds');\n    assert.equal(moment().add({m: 1}).fromNow(), 'za minútu', 'in a minute');\n    assert.equal(moment().add({m: 3}).fromNow(), 'za 3 minúty', 'in 3 minutes');\n    assert.equal(moment().add({m: 10}).fromNow(), 'za 10 minút', 'in 10 minutes');\n    assert.equal(moment().add({h: 1}).fromNow(), 'za hodinu', 'in an hour');\n    assert.equal(moment().add({h: 3}).fromNow(), 'za 3 hodiny', 'in 3 hours');\n    assert.equal(moment().add({h: 10}).fromNow(), 'za 10 hodín', 'in 10 hours');\n    assert.equal(moment().add({d: 1}).fromNow(), 'za deň', 'in a day');\n    assert.equal(moment().add({d: 3}).fromNow(), 'za 3 dni', 'in 3 days');\n    assert.equal(moment().add({d: 10}).fromNow(), 'za 10 dní', 'in 10 days');\n    assert.equal(moment().add({M: 1}).fromNow(), 'za mesiac', 'in a month');\n    assert.equal(moment().add({M: 3}).fromNow(), 'za 3 mesiace', 'in 3 months');\n    assert.equal(moment().add({M: 10}).fromNow(), 'za 10 mesiacov', 'in 10 months');\n    assert.equal(moment().add({y: 1}).fromNow(), 'za rok', 'in a year');\n    assert.equal(moment().add({y: 3}).fromNow(), 'za 3 roky', 'in 3 years');\n    assert.equal(moment().add({y: 10}).fromNow(), 'za 10 rokov', 'in 10 years');\n});\n\ntest('fromNow (past)', function (assert) {\n    assert.equal(moment().subtract({s: 30}).fromNow(), 'pred pár sekundami', 'a few seconds ago');\n    assert.equal(moment().subtract({m: 1}).fromNow(), 'pred minútou', 'a minute ago');\n    assert.equal(moment().subtract({m: 3}).fromNow(), 'pred 3 minútami', '3 minutes ago');\n    assert.equal(moment().subtract({m: 10}).fromNow(), 'pred 10 minútami', '10 minutes ago');\n    assert.equal(moment().subtract({h: 1}).fromNow(), 'pred hodinou', 'an hour ago');\n    assert.equal(moment().subtract({h: 3}).fromNow(), 'pred 3 hodinami', '3 hours ago');\n    assert.equal(moment().subtract({h: 10}).fromNow(), 'pred 10 hodinami', '10 hours ago');\n    assert.equal(moment().subtract({d: 1}).fromNow(), 'pred dňom', 'a day ago');\n    assert.equal(moment().subtract({d: 3}).fromNow(), 'pred 3 dňami', '3 days ago');\n    assert.equal(moment().subtract({d: 10}).fromNow(), 'pred 10 dňami', '10 days ago');\n    assert.equal(moment().subtract({M: 1}).fromNow(), 'pred mesiacom', 'a month ago');\n    assert.equal(moment().subtract({M: 3}).fromNow(), 'pred 3 mesiacmi', '3 months ago');\n    assert.equal(moment().subtract({M: 10}).fromNow(), 'pred 10 mesiacmi', '10 months ago');\n    assert.equal(moment().subtract({y: 1}).fromNow(), 'pred rokom', 'a year ago');\n    assert.equal(moment().subtract({y: 3}).fromNow(), 'pred 3 rokmi', '3 years ago');\n    assert.equal(moment().subtract({y: 10}).fromNow(), 'pred 10 rokmi', '10 years ago');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'dnes o 12:00',     'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'dnes o 12:25',     'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'dnes o 13:00',     'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'zajtra o 12:00',   'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'dnes o 11:00',     'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'včera o 12:00',    'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m, nextDay;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        nextDay = '';\n        switch (m.day()) {\n            case 0:\n                nextDay = 'v nedeľu';\n                break;\n            case 1:\n                nextDay = 'v pondelok';\n                break;\n            case 2:\n                nextDay = 'v utorok';\n                break;\n            case 3:\n                nextDay = 'v stredu';\n                break;\n            case 4:\n                nextDay = 'vo štvrtok';\n                break;\n            case 5:\n                nextDay = 'v piatok';\n                break;\n            case 6:\n                nextDay = 'v sobotu';\n                break;\n        }\n        assert.equal(m.calendar(),       m.format('[' + nextDay + '] [o] LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[' + nextDay + '] [o] LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[' + nextDay + '] [o] LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m, lastDay;\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        lastDay = '';\n        switch (m.day()) {\n            case 0:\n                lastDay = 'minulú nedeľu';\n                break;\n            case 1:\n                lastDay = 'minulý pondelok';\n                break;\n            case 2:\n                lastDay = 'minulý utorok';\n                break;\n            case 3:\n                lastDay = 'minulú stredu';\n                break;\n            case 4:\n                lastDay = 'minulý štvrtok';\n                break;\n            case 5:\n                lastDay = 'minulý piatok';\n                break;\n            case 6:\n                lastDay = 'minulú sobotu';\n                break;\n        }\n        assert.equal(m.calendar(),       m.format('[' + lastDay + '] [o] LT'),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[' + lastDay + '] [o] LT'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[' + lastDay + '] [o] LT'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('humanize duration', function (assert) {\n    assert.equal(moment.duration(1, 'minutes').humanize(), 'minúta', 'a minute (future)');\n    assert.equal(moment.duration(1, 'minutes').humanize(true), 'za minútu', 'in a minute');\n    assert.equal(moment.duration(-1, 'minutes').humanize(), 'minúta', 'a minute (past)');\n    assert.equal(moment.duration(-1, 'minutes').humanize(true), 'pred minútou', 'a minute ago');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2012, 0,  1]).format('w ww wo'), '52 52 52.', 'Jan  1 2012 should be week 52');\n    assert.equal(moment([2012, 0,  2]).format('w ww wo'),   '1 01 1.', 'Jan  2 2012 should be week 1');\n    assert.equal(moment([2012, 0,  8]).format('w ww wo'),   '1 01 1.', 'Jan  8 2012 should be week 1');\n    assert.equal(moment([2012, 0,  9]).format('w ww wo'),   '2 02 2.', 'Jan  9 2012 should be week 2');\n    assert.equal(moment([2012, 0, 15]).format('w ww wo'),   '2 02 2.', 'Jan 15 2012 should be week 2');\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\n\n\nfunction localeModule (name, lifecycle) {\n    QUnit.module('locale:' + name, {\n        setup : function () {\n            moment.locale(name);\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            moment.locale('en');\n            teardownDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n    defineCommonLocaleTests(name, -1, -1);\n}\n\nlocaleModule('sl');\n\ntest('parse', function (assert) {\n    var tests = 'januar jan._februar feb._marec mar._april apr._maj maj_junij jun._julij jul._avgust avg._september sep._oktober okt._november nov._december dec.'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, Do MMMM YYYY, h:mm:ss a',      'nedelja, 14. februar 2010, 3:25:50 pm'],\n            ['ddd, hA',                            'ned., 3PM'],\n            ['M Mo MM MMMM MMM',                   '2 2. 02 februar feb.'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14. 14'],\n            ['d do dddd ddd dd',                   '0 0. nedelja ned. ne'],\n            ['DDD DDDo DDDD',                      '45 45. 045'],\n            ['w wo ww',                            '7 7. 07'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'pm PM'],\n            ['[the] DDDo [day of the year]',       'the 45. day of the year'],\n            ['LTS',                                '15:25:50'],\n            ['L',                                  '14.02.2010'],\n            ['LL',                                 '14. februar 2010'],\n            ['LLL',                                '14. februar 2010 15:25'],\n            ['LLLL',                               'nedelja, 14. februar 2010 15:25'],\n            ['l',                                  '14.2.2010'],\n            ['ll',                                 '14. feb. 2010'],\n            ['lll',                                '14. feb. 2010 15:25'],\n            ['llll',                               'ned., 14. feb. 2010 15:25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1.', '1.');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2.', '2.');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3.', '3.');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4.', '4.');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5.', '5.');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6.', '6.');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7.', '7.');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8.', '8.');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9.', '9.');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10.', '10.');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11.', '11.');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12.', '12.');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13.', '13.');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14.', '14.');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15.', '15.');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16.', '16.');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17.', '17.');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18.', '18.');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19.', '19.');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20.', '20.');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21.', '21.');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22.', '22.');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23.', '23.');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24.', '24.');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25.', '25.');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26.', '26.');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27.', '27.');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28.', '28.');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29.', '29.');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30.', '30.');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31.', '31.');\n});\n\ntest('format month', function (assert) {\n    var expected = 'januar jan._februar feb._marec mar._april apr._maj maj._junij jun._julij jul._avgust avg._september sep._oktober okt._november nov._december dec.'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'nedelja ned. ne_ponedeljek pon. po_torek tor. to_sreda sre. sr_četrtek čet. če_petek pet. pe_sobota sob. so'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'nekaj sekund', '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'ena minuta',   '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'ena minuta',   '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 minuti',     '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 minut',     '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'ena ura',      '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'ena ura',      '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 uri',        '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 ur',         '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 ur',        '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'en dan',       '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'en dan',       '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 dni',        '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'en dan',       '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 dni',        '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 dni',       '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'en mesec',     '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'en mesec',     '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'en mesec',     '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 meseca',     '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 meseca',     '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 mesece',     '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'en mesec',     '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 mesecev',    '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'eno leto',     '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 leti',       '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'eno leto',     '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 let',        '5 years = 5 years');\n\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 1}), true),  'ena minuta', 'a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 2}), true),  '2 minuti',   '2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 3}), true),  '3 minute',   '3 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 4}), true),  '4 minute',   '4 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 5}), true),  '5 minut',    '5 minutes');\n\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 1}), true),  'ena ura', 'an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 2}), true),  '2 uri',   '2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 3}), true),  '3 ure',   '3 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 4}), true),  '4 ure',   '4 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),  '5 ur',    '5 hours');\n\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),  'en dan', 'a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 2}), true),  '2 dni',  '2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 3}), true),  '3 dni',  '3 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 4}), true),  '4 dni',  '4 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),  '5 dni',  '5 days');\n\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),  'en mesec',  'a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 2}), true),  '2 meseca',  '2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 3}), true),  '3 mesece',  '3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 4}), true),  '4 mesece',  '4 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),  '5 mesecev', '5 months');\n\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),  'eno leto', 'a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 2}), true),  '2 leti',   '2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 3}), true),  '3 leta',   '3 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 4}), true),  '4 leta',   '4 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),  '5 let',    '5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'čez nekaj sekund',  'prefix');\n    assert.equal(moment(0).from(30000), 'pred nekaj sekundami', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'pred nekaj sekundami',  'now from now should display as in the past');\n});\n\ntest('fromNow (future)', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'čez nekaj sekund', 'in a few seconds');\n    assert.equal(moment().add({m: 1}).fromNow(),  'čez eno minuto', 'in a minute');\n    assert.equal(moment().add({m: 2}).fromNow(),  'čez 2 minuti',   'in 2 minutes');\n    assert.equal(moment().add({m: 3}).fromNow(),  'čez 3 minute',   'in 3 minutes');\n    assert.equal(moment().add({m: 4}).fromNow(),  'čez 4 minute',   'in 4 minutes');\n    assert.equal(moment().add({m: 5}).fromNow(),  'čez 5 minut',    'in 5 minutes');\n\n    assert.equal(moment().add({h: 1}).fromNow(),  'čez eno uro', 'in an hour');\n    assert.equal(moment().add({h: 2}).fromNow(),  'čez 2 uri',   'in 2 hours');\n    assert.equal(moment().add({h: 3}).fromNow(),  'čez 3 ure',   'in 3 hours');\n    assert.equal(moment().add({h: 4}).fromNow(),  'čez 4 ure',   'in 4 hours');\n    assert.equal(moment().add({h: 5}).fromNow(),  'čez 5 ur',    'in 5 hours');\n\n    assert.equal(moment().add({d: 1}).fromNow(),  'čez en dan', 'in a day');\n    assert.equal(moment().add({d: 2}).fromNow(),  'čez 2 dni',  'in 2 days');\n    assert.equal(moment().add({d: 3}).fromNow(),  'čez 3 dni',  'in 3 days');\n    assert.equal(moment().add({d: 4}).fromNow(),  'čez 4 dni',  'in 4 days');\n    assert.equal(moment().add({d: 5}).fromNow(),  'čez 5 dni',  'in 5 days');\n\n    assert.equal(moment().add({M: 1}).fromNow(),  'čez en mesec',  'in a month');\n    assert.equal(moment().add({M: 2}).fromNow(),  'čez 2 meseca',  'in 2 months');\n    assert.equal(moment().add({M: 3}).fromNow(),  'čez 3 mesece',  'in 3 months');\n    assert.equal(moment().add({M: 4}).fromNow(),  'čez 4 mesece',  'in 4 months');\n    assert.equal(moment().add({M: 5}).fromNow(),  'čez 5 mesecev', 'in 5 months');\n\n    assert.equal(moment().add({y: 1}).fromNow(),  'čez eno leto', 'in a year');\n    assert.equal(moment().add({y: 2}).fromNow(),  'čez 2 leti',   'in 2 years');\n    assert.equal(moment().add({y: 3}).fromNow(),  'čez 3 leta',   'in 3 years');\n    assert.equal(moment().add({y: 4}).fromNow(),  'čez 4 leta',   'in 4 years');\n    assert.equal(moment().add({y: 5}).fromNow(),  'čez 5 let',    'in 5 years');\n\n    assert.equal(moment().subtract({s: 30}).fromNow(), 'pred nekaj sekundami', 'a few seconds ago');\n\n    assert.equal(moment().subtract({m: 1}).fromNow(),  'pred eno minuto', 'a minute ago');\n    assert.equal(moment().subtract({m: 2}).fromNow(),  'pred 2 minutama', '2 minutes ago');\n    assert.equal(moment().subtract({m: 3}).fromNow(),  'pred 3 minutami', '3 minutes ago');\n    assert.equal(moment().subtract({m: 4}).fromNow(),  'pred 4 minutami', '4 minutes ago');\n    assert.equal(moment().subtract({m: 5}).fromNow(),  'pred 5 minutami', '5 minutes ago');\n\n    assert.equal(moment().subtract({h: 1}).fromNow(),  'pred eno uro', 'an hour ago');\n    assert.equal(moment().subtract({h: 2}).fromNow(),  'pred 2 urama', '2 hours ago');\n    assert.equal(moment().subtract({h: 3}).fromNow(),  'pred 3 urami', '3 hours ago');\n    assert.equal(moment().subtract({h: 4}).fromNow(),  'pred 4 urami', '4 hours ago');\n    assert.equal(moment().subtract({h: 5}).fromNow(),  'pred 5 urami', '5 hours ago');\n\n    assert.equal(moment().subtract({d: 1}).fromNow(),  'pred enim dnem', 'a day ago');\n    assert.equal(moment().subtract({d: 2}).fromNow(),  'pred 2 dnevoma', '2 days ago');\n    assert.equal(moment().subtract({d: 3}).fromNow(),  'pred 3 dnevi',   '3 days ago');\n    assert.equal(moment().subtract({d: 4}).fromNow(),  'pred 4 dnevi',   '4 days ago');\n    assert.equal(moment().subtract({d: 5}).fromNow(),  'pred 5 dnevi',   '5 days ago');\n\n    assert.equal(moment().subtract({M: 1}).fromNow(),  'pred enim mesecem', 'a month ago');\n    assert.equal(moment().subtract({M: 2}).fromNow(),  'pred 2 mesecema',   '2 months ago');\n    assert.equal(moment().subtract({M: 3}).fromNow(),  'pred 3 meseci',     '3 months ago');\n    assert.equal(moment().subtract({M: 4}).fromNow(),  'pred 4 meseci',     '4 months ago');\n    assert.equal(moment().subtract({M: 5}).fromNow(),  'pred 5 meseci',     '5 months ago');\n\n    assert.equal(moment().subtract({y: 1}).fromNow(),  'pred enim letom', 'a year ago');\n    assert.equal(moment().subtract({y: 2}).fromNow(),  'pred 2 letoma',   '2 years ago');\n    assert.equal(moment().subtract({y: 3}).fromNow(),  'pred 3 leti',     '3 years ago');\n    assert.equal(moment().subtract({y: 4}).fromNow(),  'pred 4 leti',     '4 years ago');\n    assert.equal(moment().subtract({y: 5}).fromNow(),  'pred 5 leti',     '5 years ago');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'danes ob 12:00',  'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'danes ob 12:25',  'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'danes ob 13:00',  'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'jutri ob 12:00',  'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'danes ob 11:00',  'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'včeraj ob 12:00', 'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n\n    function makeFormat(d) {\n        switch (d.day()) {\n            case 0:\n                return '[v] [nedeljo] [ob] LT';\n            case 3:\n                return '[v] [sredo] [ob] LT';\n            case 6:\n                return '[v] [soboto] [ob] LT';\n            case 1:\n            case 2:\n            case 4:\n            case 5:\n                return '[v] dddd [ob] LT';\n        }\n    }\n\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format(makeFormat(m)),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format(makeFormat(m)),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format(makeFormat(m)),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n\n    function makeFormat(d) {\n        switch (d.day()) {\n            case 0:\n                return '[prejšnjo] [nedeljo] [ob] LT';\n            case 3:\n                return '[prejšnjo] [sredo] [ob] LT';\n            case 6:\n                return '[prejšnjo] [soboto] [ob] LT';\n            case 1:\n            case 2:\n            case 4:\n            case 5:\n                return '[prejšnji] dddd [ob] LT';\n        }\n    }\n\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format(makeFormat(m)),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format(makeFormat(m)),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format(makeFormat(m)),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2011, 11, 26]).format('w ww wo'), '1 01 1.', 'Dec 26 2011 should be week 1');\n    assert.equal(moment([2012,  0,  1]).format('w ww wo'), '1 01 1.', 'Jan  1 2012 should be week 1');\n    assert.equal(moment([2012,  0,  2]).format('w ww wo'), '2 02 2.', 'Jan  2 2012 should be week 2');\n    assert.equal(moment([2012,  0,  8]).format('w ww wo'), '2 02 2.', 'Jan  8 2012 should be week 2');\n    assert.equal(moment([2012,  0,  9]).format('w ww wo'), '3 03 3.', 'Jan  9 2012 should be week 3');\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\n\n\nfunction localeModule (name, lifecycle) {\n    QUnit.module('locale:' + name, {\n        setup : function () {\n            moment.locale(name);\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            moment.locale('en');\n            teardownDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n    defineCommonLocaleTests(name, -1, -1);\n}\n\nlocaleModule('sq');\n\ntest('parse', function (assert) {\n    var i,\n        tests = 'Janar Jan_Shkurt Shk_Mars Mar_Prill Pri_Maj Maj_Qershor Qer_Korrik Kor_Gusht Gus_Shtator Sht_Tetor Tet_Nëntor Nën_Dhjetor Dhj'.split('_');\n\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, MMMM Do YYYY, HH:mm:ss',       'E Diel, Shkurt 14. 2010, 15:25:50'],\n            ['ddd, HH',                            'Die, 15'],\n            ['M Mo MM MMMM MMM',                   '2 2. 02 Shkurt Shk'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14. 14'],\n            ['d do dddd ddd dd',                   '0 0. E Diel Die D'],\n            ['DDD DDDo DDDD',                      '45 45. 045'],\n            ['w wo ww',                            '6 6. 06'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'MD MD'],\n            ['[the] DDDo [day of the year]',       'the 45. day of the year'],\n            ['LTS',                                '15:25:50'],\n            ['L',                                  '14/02/2010'],\n            ['LL',                                 '14 Shkurt 2010'],\n            ['LLL',                                '14 Shkurt 2010 15:25'],\n            ['LLLL',                               'E Diel, 14 Shkurt 2010 15:25'],\n            ['l',                                  '14/2/2010'],\n            ['ll',                                 '14 Shk 2010'],\n            ['lll',                                '14 Shk 2010 15:25'],\n            ['llll',                               'Die, 14 Shk 2010 15:25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('meridiem', function (assert) {\n    assert.equal(moment([2011, 2, 23,  0, 0]).format('A'), 'PD', 'before dawn');\n    assert.equal(moment([2011, 2, 23, 12, 0]).format('A'), 'MD', 'noon');\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1.', '1.');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2.', '2.');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3.', '3.');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4.', '4.');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5.', '5.');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6.', '6.');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7.', '7.');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8.', '8.');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9.', '9.');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10.', '10.');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11.', '11.');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12.', '12.');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13.', '13.');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14.', '14.');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15.', '15.');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16.', '16.');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17.', '17.');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18.', '18.');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19.', '19.');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20.', '20.');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21.', '21.');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22.', '22.');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23.', '23.');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24.', '24.');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25.', '25.');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26.', '26.');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27.', '27.');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28.', '28.');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29.', '29.');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30.', '30.');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31.', '31.');\n});\n\ntest('format month', function (assert) {\n    var i,\n        expected = 'Janar Jan_Shkurt Shk_Mars Mar_Prill Pri_Maj Maj_Qershor Qer_Korrik Kor_Gusht Gus_Shtator Sht_Tetor Tet_Nëntor Nën_Dhjetor Dhj'.split('_');\n\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var i,\n        expected = 'E Diel Die D_E Hënë Hën H_E Martë Mar Ma_E Mërkurë Mër Më_E Enjte Enj E_E Premte Pre P_E Shtunë Sht Sh'.split('_');\n\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'disa sekonda', '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'një minutë',      '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'një minutë',      '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 minuta',     '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 minuta',    '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'një orë',       '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'një orë',       '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 orë',       '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 orë',       '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 orë',      '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'një ditë',         '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'një ditë',         '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 ditë',        '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'një ditë',         '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 ditë',        '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 ditë',       '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'një muaj',       '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'një muaj',       '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'një muaj',       '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 muaj',      '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 muaj',      '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 muaj',      '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'një muaj',       '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 muaj',      '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'një vit',        '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 vite',       '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'një vit',        '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 vite',       '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'në disa sekonda',  'prefix');\n    assert.equal(moment(0).from(30000), 'disa sekonda më parë', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'disa sekonda më parë',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'në disa sekonda', 'in a few seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), 'në 5 ditë', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'Sot në 12:00',   'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'Sot në 12:25',   'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'Sot në 13:00',   'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'Nesër në 12:00', 'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'Sot në 11:00',   'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'Dje në 12:00',   'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('dddd [në] LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd [në] LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd [në] LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('dddd [e kaluar në] LT'),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd [e kaluar në] LT'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd [e kaluar në] LT'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2012, 0,  1]).format('w ww wo'), '52 52 52.', 'Jan  1 2012 should be week 52');\n    assert.equal(moment([2012, 0,  2]).format('w ww wo'),   '1 01 1.', 'Jan  2 2012 should be week 1');\n    assert.equal(moment([2012, 0,  8]).format('w ww wo'),   '1 01 1.', 'Jan  8 2012 should be week 1');\n    assert.equal(moment([2012, 0,  9]).format('w ww wo'),   '2 02 2.', 'Jan  9 2012 should be week 2');\n    assert.equal(moment([2012, 0, 15]).format('w ww wo'),   '2 02 2.', 'Jan 15 2012 should be week 2');\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\n\n\nfunction localeModule (name, lifecycle) {\n    QUnit.module('locale:' + name, {\n        setup : function () {\n            moment.locale(name);\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            moment.locale('en');\n            teardownDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n    defineCommonLocaleTests(name, -1, -1);\n}\n\nlocaleModule('sr-cyrl');\n\ntest('parse', function (assert) {\n    var tests = 'јануар јан._фебруар феб._март мар._април апр._мај мај_јун јун_јул јул_август авг._септембар сеп._октобар окт._новембар нов._децембар дец.'.split('_'),\n        i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, Do MMMM YYYY, h:mm:ss a',      'недеља, 14. фебруар 2010, 3:25:50 pm'],\n            ['ddd, hA',                            'нед., 3PM'],\n            ['M Mo MM MMMM MMM',                   '2 2. 02 фебруар феб.'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14. 14'],\n            ['d do dddd ddd dd',                   '0 0. недеља нед. не'],\n            ['DDD DDDo DDDD',                      '45 45. 045'],\n            ['w wo ww',                            '7 7. 07'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'pm PM'],\n            ['[the] DDDo [day of the year]',       'the 45. day of the year'],\n            ['LTS',                                '15:25:50'],\n            ['L',                                  '14.02.2010'],\n            ['LL',                                 '14. фебруар 2010'],\n            ['LLL',                                '14. фебруар 2010 15:25'],\n            ['LLLL',                               'недеља, 14. фебруар 2010 15:25'],\n            ['l',                                  '14.2.2010'],\n            ['ll',                                 '14. феб. 2010'],\n            ['lll',                                '14. феб. 2010 15:25'],\n            ['llll',                               'нед., 14. феб. 2010 15:25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1.', '1.');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2.', '2.');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3.', '3.');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4.', '4.');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5.', '5.');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6.', '6.');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7.', '7.');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8.', '8.');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9.', '9.');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10.', '10.');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11.', '11.');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12.', '12.');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13.', '13.');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14.', '14.');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15.', '15.');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16.', '16.');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17.', '17.');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18.', '18.');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19.', '19.');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20.', '20.');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21.', '21.');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22.', '22.');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23.', '23.');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24.', '24.');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25.', '25.');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26.', '26.');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27.', '27.');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28.', '28.');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29.', '29.');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30.', '30.');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31.', '31.');\n});\n\ntest('format month', function (assert) {\n    var expected = 'јануар јан._фебруар феб._март мар._април апр._мај мај_јун јун_јул јул_август авг._септембар сеп._октобар окт._новембар нов._децембар дец.'.split('_'),\n        i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'недеља нед. не_понедељак пон. по_уторак уто. ут_среда сре. ср_четвртак чет. че_петак пет. пе_субота суб. су'.split('_'),\n        i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'неколико секунди', '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'један минут',   '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'један минут',   '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 минуте',     '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 минута',     '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'један сат',      '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'један сат',      '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 сата',        '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 сати',         '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 сати',        '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'дан',       '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'дан',       '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 дана',        '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'дан',       '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 дана',        '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 дана',       '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'месец',     '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'месец',     '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'месец',     '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 месеца',     '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 месеца',     '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 месеца',     '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'месец',     '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 месеци',    '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'годину',     '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 године',       '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'годину',     '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 година',        '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'за неколико секунди',  'prefix');\n    assert.equal(moment(0).from(30000), 'пре неколико секунди', 'prefix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'пре неколико секунди',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'за неколико секунди', 'in a few seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), 'за 5 дана', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'данас у 12:00',  'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'данас у 12:25',  'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'данас у 13:00',  'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'сутра у 12:00',  'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'данас у 11:00',  'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'јуче у 12:00',   'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n\n    function makeFormat(d) {\n        switch (d.day()) {\n            case 0:\n                return '[у] [недељу] [у] LT';\n            case 3:\n                return '[у] [среду] [у] LT';\n            case 6:\n                return '[у] [суботу] [у] LT';\n            case 1:\n            case 2:\n            case 4:\n            case 5:\n                return '[у] dddd [у] LT';\n        }\n    }\n\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format(makeFormat(m)),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format(makeFormat(m)),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format(makeFormat(m)),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n\n    function makeFormat(d) {\n        var lastWeekDay = [\n                '[прошле] [недеље] [у] LT',\n                '[прошлог] [понедељка] [у] LT',\n                '[прошлог] [уторка] [у] LT',\n                '[прошле] [среде] [у] LT',\n                '[прошлог] [четвртка] [у] LT',\n                '[прошлог] [петка] [у] LT',\n                '[прошле] [суботе] [у] LT'\n            ];\n\n        return lastWeekDay[d.day()];\n    }\n\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format(makeFormat(m)),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format(makeFormat(m)),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format(makeFormat(m)),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2011, 11, 26]).format('w ww wo'), '1 01 1.', 'Dec 26 2011 should be week 1');\n    assert.equal(moment([2012,  0,  1]).format('w ww wo'), '1 01 1.', 'Jan  1 2012 should be week 1');\n    assert.equal(moment([2012,  0,  2]).format('w ww wo'), '2 02 2.', 'Jan  2 2012 should be week 2');\n    assert.equal(moment([2012,  0,  8]).format('w ww wo'), '2 02 2.', 'Jan  8 2012 should be week 2');\n    assert.equal(moment([2012,  0,  9]).format('w ww wo'), '3 03 3.', 'Jan  9 2012 should be week 3');\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\n\n\nfunction localeModule (name, lifecycle) {\n    QUnit.module('locale:' + name, {\n        setup : function () {\n            moment.locale(name);\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            moment.locale('en');\n            teardownDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n    defineCommonLocaleTests(name, -1, -1);\n}\n\nlocaleModule('sr');\n\ntest('parse', function (assert) {\n    var tests = 'januar jan._februar feb._mart mar._april apr._maj maj_jun jun_jul jul_avgust avg._septembar sep._oktobar okt._novembar nov._decembar dec.'.split('_'),\n        i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, Do MMMM YYYY, h:mm:ss a',      'nedelja, 14. februar 2010, 3:25:50 pm'],\n            ['ddd, hA',                            'ned., 3PM'],\n            ['M Mo MM MMMM MMM',                   '2 2. 02 februar feb.'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14. 14'],\n            ['d do dddd ddd dd',                   '0 0. nedelja ned. ne'],\n            ['DDD DDDo DDDD',                      '45 45. 045'],\n            ['w wo ww',                            '7 7. 07'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'pm PM'],\n            ['[the] DDDo [day of the year]',       'the 45. day of the year'],\n            ['LTS',                                '15:25:50'],\n            ['L',                                  '14.02.2010'],\n            ['LL',                                 '14. februar 2010'],\n            ['LLL',                                '14. februar 2010 15:25'],\n            ['LLLL',                               'nedelja, 14. februar 2010 15:25'],\n            ['l',                                  '14.2.2010'],\n            ['ll',                                 '14. feb. 2010'],\n            ['lll',                                '14. feb. 2010 15:25'],\n            ['llll',                               'ned., 14. feb. 2010 15:25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1.', '1.');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2.', '2.');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3.', '3.');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4.', '4.');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5.', '5.');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6.', '6.');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7.', '7.');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8.', '8.');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9.', '9.');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10.', '10.');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11.', '11.');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12.', '12.');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13.', '13.');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14.', '14.');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15.', '15.');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16.', '16.');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17.', '17.');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18.', '18.');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19.', '19.');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20.', '20.');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21.', '21.');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22.', '22.');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23.', '23.');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24.', '24.');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25.', '25.');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26.', '26.');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27.', '27.');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28.', '28.');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29.', '29.');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30.', '30.');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31.', '31.');\n});\n\ntest('format month', function (assert) {\n    var expected = 'januar jan._februar feb._mart mar._april apr._maj maj_jun jun_jul jul_avgust avg._septembar sep._oktobar okt._novembar nov._decembar dec.'.split('_'),\n        i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'nedelja ned. ne_ponedeljak pon. po_utorak uto. ut_sreda sre. sr_četvrtak čet. če_petak pet. pe_subota sub. su'.split('_'),\n        i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'nekoliko sekundi', '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'jedan minut',   '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'jedan minut',   '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 minute',     '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 minuta',     '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'jedan sat',      '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'jedan sat',      '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 sata',        '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 sati',         '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 sati',        '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'dan',       '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'dan',       '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 dana',        '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'dan',       '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 dana',        '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 dana',       '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'mesec',     '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'mesec',     '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'mesec',     '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 meseca',     '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 meseca',     '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 meseca',     '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'mesec',     '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 meseci',    '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'godinu',     '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 godine',       '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'godinu',     '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 godina',        '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'za nekoliko sekundi',  'prefix');\n    assert.equal(moment(0).from(30000), 'pre nekoliko sekundi', 'prefix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'pre nekoliko sekundi',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'za nekoliko sekundi', 'in a few seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), 'za 5 dana', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'danas u 12:00',  'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'danas u 12:25',  'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'danas u 13:00',  'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'sutra u 12:00',  'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'danas u 11:00',  'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'juče u 12:00',   'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n\n    function makeFormat(d) {\n        switch (d.day()) {\n            case 0:\n                return '[u] [nedelju] [u] LT';\n            case 3:\n                return '[u] [sredu] [u] LT';\n            case 6:\n                return '[u] [subotu] [u] LT';\n            case 1:\n            case 2:\n            case 4:\n            case 5:\n                return '[u] dddd [u] LT';\n        }\n    }\n\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format(makeFormat(m)),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format(makeFormat(m)),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format(makeFormat(m)),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n\n    function makeFormat(d) {\n        var lastWeekDay = [\n                '[prošle] [nedelje] [u] LT',\n                '[prošlog] [ponedeljka] [u] LT',\n                '[prošlog] [utorka] [u] LT',\n                '[prošle] [srede] [u] LT',\n                '[prošlog] [četvrtka] [u] LT',\n                '[prošlog] [petka] [u] LT',\n                '[prošle] [subote] [u] LT'\n            ];\n\n        return lastWeekDay[d.day()];\n    }\n\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format(makeFormat(m)),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format(makeFormat(m)),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format(makeFormat(m)),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2011, 11, 26]).format('w ww wo'), '1 01 1.', 'Dec 26 2011 should be week 1');\n    assert.equal(moment([2012,  0,  1]).format('w ww wo'), '1 01 1.', 'Jan  1 2012 should be week 1');\n    assert.equal(moment([2012,  0,  2]).format('w ww wo'), '2 02 2.', 'Jan  2 2012 should be week 2');\n    assert.equal(moment([2012,  0,  8]).format('w ww wo'), '2 02 2.', 'Jan  8 2012 should be week 2');\n    assert.equal(moment([2012,  0,  9]).format('w ww wo'), '3 03 3.', 'Jan  9 2012 should be week 3');\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\n\n\nfunction localeModule (name, lifecycle) {\n    QUnit.module('locale:' + name, {\n        setup : function () {\n            moment.locale(name);\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            moment.locale('en');\n            teardownDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n    defineCommonLocaleTests(name, -1, -1);\n}\n\nlocaleModule('ss');\n\ntest('parse', function (assert) {\n    var tests = \"Bhimbidvwane Bhi_Indlovana Ina_Indlov'lenkhulu Inu_Mabasa Mab_Inkhwekhweti Ink_Inhlaba Inh_Kholwane Kho_Ingci Igc_Inyoni Iny_Imphala Imp_Lweti lwe_Ingongoni Igo\".split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('parse meridiem', function (assert) {\n    var i,\n        b = moment(),\n        meridiemTests = [\n            // h a patterns, expected hours, isValid\n            ['10 ekuseni',   10, true],\n            ['11 emini',   11, true],\n            ['3 entsambama',   15, true],\n            ['4 entsambama',   16, true],\n            ['6 entsambama',   18, true],\n            ['7 ebusuku',   19, true],\n            ['12 ebusuku',   0, true],\n            ['10 am',   10, false],\n            ['10 pm',   10, false]\n        ],\n        parsed;\n\n    // test that a formatted moment including meridiem string can be parsed back to the same moment\n    assert.ok(b.isSame(moment(b.format('h:mm:ss a'), 'h:mm:ss a', 'ss', true), 'seconds'), b.format('h:mm:ss a') + ' should be equal to ' + moment(b.format('h:mm:ss a'), 'h:mm:ss a', 'ss', true).format('h:mm:ss a'));\n\n    // test that a formatted moment having a meridiem string can be parsed with strict flag\n    assert.ok(moment(b.format('h:mm:ss a'), 'h:mm:ss a', 'ss', true).isValid(), b.format('h:mm:ss a') + ' should be parsed as valid');\n\n    for (i = 0; i < meridiemTests.length; i++) {\n        parsed = moment(meridiemTests[i][0], 'h a', 'ss', true);\n        assert.equal(parsed.isValid(), meridiemTests[i][2], 'validity for ' + meridiemTests[i][0]);\n        if (parsed.isValid()) {\n            assert.equal(parsed.hours(), meridiemTests[i][1], 'hours for ' + meridiemTests[i][0]);\n        }\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, MMMM Do YYYY, h:mm:ss a',      'Lisontfo, Indlovana 14 2010, 3:25:50 entsambama'],\n            ['ddd, h A',                            'Lis, 3 entsambama'],\n            ['M Mo MM MMMM MMM',                   '2 2 02 Indlovana Ina'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14 14'],\n            ['d do dddd ddd dd',                   '0 0 Lisontfo Lis Li'],\n            ['DDD DDDo DDDD',                      '45 45 045'],\n            ['w wo ww',                            '6 6 06'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'entsambama entsambama'],\n            ['[Lilanga] DDDo [lilanga lelinyaka]', 'Lilanga 45 lilanga lelinyaka'],\n            ['LTS',                                '3:25:50 entsambama'],\n            ['L',                                  '14/02/2010'],\n            ['LL',                                 '14 Indlovana 2010'],\n            ['LLL',                                '14 Indlovana 2010 3:25 entsambama'],\n            ['LLLL',                               'Lisontfo, 14 Indlovana 2010 3:25 entsambama'],\n            ['l',                                  '14/2/2010'],\n            ['ll',                                 '14 Ina 2010'],\n            ['lll',                                '14 Ina 2010 3:25 entsambama'],\n            ['llll',                               'Lis, 14 Ina 2010 3:25 entsambama']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1', '1');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2', '2');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3', '3');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4', '4');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5', '5');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6', '6');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7', '7');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8', '8');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9', '9');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10', '10');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11', '11');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12', '12');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13', '13');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14', '14');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15', '15');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16', '16');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17', '17');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18', '18');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19', '19');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20', '20');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21', '21');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22', '22');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23', '23');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24', '24');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25', '25');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26', '26');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27', '27');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28', '28');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29', '29');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30', '30');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31', '31');\n});\n\ntest('format month', function (assert) {\n    var expected = \"Bhimbidvwane Bhi_Indlovana Ina_Indlov'lenkhulu Inu_Mabasa Mab_Inkhwekhweti Ink_Inhlaba Inh_Kholwane Kho_Ingci Igc_Inyoni Iny_Imphala Imp_Lweti Lwe_Ingongoni Igo\".split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'Lisontfo Lis Li_Umsombuluko Umb Us_Lesibili Lsb Lb_Lesitsatfu Les Lt_Lesine Lsi Ls_Lesihlanu Lsh Lh_Umgcibelo Umg Ug'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'emizuzwana lomcane', '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'umzuzu',      '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'umzuzu',      '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 emizuzu',     '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 emizuzu',    '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'lihora',       '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'lihora',       '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 emahora',       '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 emahora',       '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 emahora',      '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'lilanga',         '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'lilanga',         '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 emalanga',        '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'lilanga',         '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 emalanga',        '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 emalanga',       '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'inyanga',       '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'inyanga',       '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'inyanga',       '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 tinyanga',      '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 tinyanga',      '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 tinyanga',      '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'inyanga',       '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 tinyanga',      '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'umnyaka',        '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 iminyaka',       '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'umnyaka',        '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 iminyaka',       '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'nga emizuzwana lomcane',  'prefix');\n    assert.equal(moment(0).from(30000), 'wenteka nga emizuzwana lomcane', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'wenteka nga emizuzwana lomcane',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'nga emizuzwana lomcane', 'in a few seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), 'nga 5 emalanga', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'Namuhla nga 12:00 emini',      'Today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'Namuhla nga 12:25 emini',      'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'Namuhla nga 1:00 emini',      'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'Kusasa nga 12:00 emini',   'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'Namuhla nga 11:00 emini',      'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'Itolo nga 12:00 emini',  'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('dddd [nga] LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd [nga] LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd [nga] LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('dddd [leliphelile] [nga] LT'),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd [leliphelile] [nga] LT'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd [leliphelile] [nga] LT'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2012, 0,  1]).format('w ww wo'), '52 52 52', 'Jan  1 2012 should be week 52');\n    assert.equal(moment([2012, 0,  2]).format('w ww wo'),   '1 01 1', 'Jan  4 2012 should be week 1');\n    assert.equal(moment([2012, 0,  8]).format('w ww wo'),   '1 01 1', 'Jan  8 2012 should be week 1');\n    assert.equal(moment([2012, 0,  9]).format('w ww wo'),   '2 02 2', 'Jan  9 2012 should be week 2');\n    assert.equal(moment([2012, 0, 15]).format('w ww wo'),   '2 02 2', 'Jan 15 2012 should be week 2');\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\n\n\nfunction localeModule (name, lifecycle) {\n    QUnit.module('locale:' + name, {\n        setup : function () {\n            moment.locale(name);\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            moment.locale('en');\n            teardownDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n    defineCommonLocaleTests(name, -1, -1);\n}\n\nlocaleModule('sv');\n\ntest('parse', function (assert) {\n    var tests = 'januari jan_februari feb_mars mar_april apr_maj maj_juni jun_juli jul_augusti aug_september sep_oktober okt_november nov_december dec'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, MMMM Do YYYY, h:mm:ss a',      'söndag, februari 14e 2010, 3:25:50 pm'],\n            ['ddd, hA',                            'sön, 3PM'],\n            ['M Mo MM MMMM MMM',                   '2 2a 02 februari feb'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14e 14'],\n            ['d do dddd ddd dd',                   '0 0e söndag sön sö'],\n            ['DDD DDDo DDDD',                      '45 45e 045'],\n            ['w wo ww',                            '6 6e 06'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'pm PM'],\n            ['[the] DDDo [day of the year]',       'the 45e day of the year'],\n            ['LTS',                                '15:25:50'],\n            ['L',                                  '2010-02-14'],\n            ['LL',                                 '14 februari 2010'],\n            ['LLL',                                '14 februari 2010 kl. 15:25'],\n            ['LLLL',                               'söndag 14 februari 2010 kl. 15:25'],\n            ['l',                                  '2010-2-14'],\n            ['ll',                                 '14 feb 2010'],\n            ['lll',                                '14 feb 2010 15:25'],\n            ['llll',                               'sön 14 feb 2010 15:25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1a', '1a');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2a', '2a');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3e', '3e');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4e', '4e');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5e', '5e');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6e', '6e');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7e', '7e');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8e', '8e');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9e', '9e');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10e', '10e');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11e', '11e');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12e', '12e');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13e', '13e');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14e', '14e');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15e', '15e');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16e', '16e');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17e', '17e');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18e', '18e');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19e', '19e');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20e', '20e');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21a', '21a');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22a', '22a');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23e', '23e');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24e', '24e');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25e', '25e');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26e', '26e');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27e', '27e');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28e', '28e');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29e', '29e');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30e', '30e');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31a', '31a');\n});\n\ntest('format month', function (assert) {\n    var expected = 'januari jan_februari feb_mars mar_april apr_maj maj_juni jun_juli jul_augusti aug_september sep_oktober okt_november nov_december dec'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'söndag sön sö_måndag mån må_tisdag tis ti_onsdag ons on_torsdag tor to_fredag fre fr_lördag lör lö'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'några sekunder', '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'en minut',      '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'en minut',      '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 minuter',     '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 minuter',    '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'en timme',       '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'en timme',       '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 timmar',       '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 timmar',       '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 timmar',      '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'en dag',         '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'en dag',         '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 dagar',        '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'en dag',         '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 dagar',        '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 dagar',       '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'en månad',       '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'en månad',       '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'en månad',       '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 månader',      '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 månader',      '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 månader',      '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'en månad',       '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 månader',      '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'ett år',        '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 år',       '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'ett år',        '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 år',       '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'om några sekunder',  'prefix');\n    assert.equal(moment(0).from(30000), 'för några sekunder sedan', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'för några sekunder sedan',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'om några sekunder', 'in a few seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), 'om 5 dagar', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'Idag 12:00',     'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'Idag 12:25',     'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'Idag 13:00',     'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'Imorgon 12:00',  'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'Idag 11:00',     'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'Igår 12:00',     'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('[På] dddd LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[På] dddd LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[På] dddd LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('[I] dddd[s] LT'),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[I] dddd[s] LT'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[I] dddd[s] LT'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2012, 0,  1]).format('w ww wo'), '52 52 52a', 'Jan  1 2012 should be week 52');\n    assert.equal(moment([2012, 0,  2]).format('w ww wo'),   '1 01 1a', 'Jan  2 2012 should be week 1');\n    assert.equal(moment([2012, 0,  8]).format('w ww wo'),   '1 01 1a', 'Jan  8 2012 should be week 1');\n    assert.equal(moment([2012, 0,  9]).format('w ww wo'),   '2 02 2a', 'Jan  9 2012 should be week 2');\n    assert.equal(moment([2012, 0, 15]).format('w ww wo'),   '2 02 2a', 'Jan 15 2012 should be week 2');\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\n\n\nfunction localeModule (name, lifecycle) {\n    QUnit.module('locale:' + name, {\n        setup : function () {\n            moment.locale(name);\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            moment.locale('en');\n            teardownDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n    defineCommonLocaleTests(name, -1, -1);\n}\n\nlocaleModule('sw');\n\ntest('parse', function (assert) {\n    var tests = 'Januari Jan_Februari Feb_Machi Mac_Aprili Apr_Mei Mei_Juni Jun_Julai Jul_Agosti Ago_Septemba Sep_Oktoba Okt_Novemba Nov_Desemba Des'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, MMMM Do YYYY, h:mm:ss a',      'Jumapili, Februari 14 2010, 3:25:50 pm'],\n            ['ddd, hA',                            'Jpl, 3PM'],\n            ['M Mo MM MMMM MMM',                   '2 2 02 Februari Feb'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14 14'],\n            ['d do dddd ddd dd',                   '0 0 Jumapili Jpl J2'],\n            ['DDD DDDo DDDD',                      '45 45 045'],\n            ['w wo ww',                            '7 7 07'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'pm PM'],\n            ['[siku] DDDo [ya mwaka]',             'siku 45 ya mwaka'],\n            ['LTS',                                '15:25:50'],\n            ['L',                                  '14.02.2010'],\n            ['LL',                                 '14 Februari 2010'],\n            ['LLL',                                '14 Februari 2010 15:25'],\n            ['LLLL',                               'Jumapili, 14 Februari 2010 15:25'],\n            ['l',                                  '14.2.2010'],\n            ['ll',                                 '14 Feb 2010'],\n            ['lll',                                '14 Feb 2010 15:25'],\n            ['llll',                               'Jpl, 14 Feb 2010 15:25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1', '1');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2', '2');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3', '3');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4', '4');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5', '5');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6', '6');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7', '7');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8', '8');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9', '9');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10', '10');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11', '11');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12', '12');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13', '13');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14', '14');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15', '15');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16', '16');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17', '17');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18', '18');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19', '19');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20', '20');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21', '21');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22', '22');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23', '23');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24', '24');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25', '25');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26', '26');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27', '27');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28', '28');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29', '29');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30', '30');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31', '31');\n});\n\ntest('format month', function (assert) {\n    var expected = 'Januari Jan_Februari Feb_Machi Mac_Aprili Apr_Mei Mei_Juni Jun_Julai Jul_Agosti Ago_Septemba Sep_Oktoba Okt_Novemba Nov_Desemba Des'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'Jumapili Jpl J2_Jumatatu Jtat J3_Jumanne Jnne J4_Jumatano Jtan J5_Alhamisi Alh Al_Ijumaa Ijm Ij_Jumamosi Jmos J1'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'hivi punde',   '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'dakika moja',  '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'dakika moja',  '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  'dakika 2',     '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  'dakika 44',    '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'saa limoja',   '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'saa limoja',   '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  'masaa 2',      '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   'masaa 5',      '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  'masaa 21',     '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'siku moja',    '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'siku moja',    '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  'masiku 2',     '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'siku moja',    '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   'masiku 5',     '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  'masiku 25',    '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'mwezi mmoja',  '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'mwezi mmoja',  '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'mwezi mmoja',  '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  'miezi 2',      '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  'miezi 2',      '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  'miezi 3',      '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'mwezi mmoja',  '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   'miezi 5',      '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'mwaka mmoja',  '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), 'miaka 2',      '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'mwaka mmoja',  '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   'miaka 5',      '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'hivi punde baadaye',  'prefix');\n    assert.equal(moment(0).from(30000), 'tokea hivi punde', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'tokea hivi punde',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'hivi punde baadaye', 'in a few seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), 'masiku 5 baadaye', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n    assert.equal(moment(a).calendar(),                   'leo saa 12:00',      'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'leo saa 12:25',      'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'leo saa 13:00',      'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'kesho saa 12:00',    'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'leo saa 11:00',      'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'jana 12:00',         'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('[wiki ijayo] dddd [saat] LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[wiki ijayo] dddd [saat] LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[wiki ijayo] dddd [saat] LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('[wiki iliyopita] dddd [saat] LT'),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[wiki iliyopita] dddd [saat] LT'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[wiki iliyopita] dddd [saat] LT'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),      '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('weeks year starting sunday format', function (assert) {\n    assert.equal(moment([2011, 11, 26]).format('w ww wo'), '1 01 1', 'Dec 26 2011 should be week 1');\n    assert.equal(moment([2012,  0,  1]).format('w ww wo'), '1 01 1', 'Jan  1 2012 should be week 1');\n    assert.equal(moment([2012,  0,  2]).format('w ww wo'), '2 02 2', 'Jan  2 2012 should be week 2');\n    assert.equal(moment([2012,  0,  8]).format('w ww wo'), '2 02 2', 'Jan  8 2012 should be week 2');\n    assert.equal(moment([2012,  0,  9]).format('w ww wo'), '3 03 3', 'Jan  9 2012 should be week 3');\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\n\n\nfunction localeModule (name, lifecycle) {\n    QUnit.module('locale:' + name, {\n        setup : function () {\n            moment.locale(name);\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            moment.locale('en');\n            teardownDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n    defineCommonLocaleTests(name, -1, -1);\n}\n\nlocaleModule('ta');\n\ntest('parse', function (assert) {\n    var tests = 'ஜனவரி ஜனவரி_பிப்ரவரி பிப்ரவரி_மார்ச் மார்ச்_ஏப்ரல் ஏப்ரல்_மே மே_ஜூன் ஜூன்_ஜூலை ஜூலை_ஆகஸ்ட் ஆகஸ்ட்_செப்டெம்பர் செப்டெம்பர்_அக்டோபர் அக்டோபர்_நவம்பர் நவம்பர்_டிசம்பர் டிசம்பர்'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, MMMM Do YYYY, h:mm:ss a', 'ஞாயிற்றுக்கிழமை, பிப்ரவரி ௧௪வது ௨௦௧௦, ௩:௨௫:௫௦  எற்பாடு'],\n            ['ddd, hA',                       'ஞாயிறு, ௩ எற்பாடு'],\n            ['M Mo MM MMMM MMM',              '௨ ௨வது ௦௨ பிப்ரவரி பிப்ரவரி'],\n            ['YYYY YY',                       '௨௦௧௦ ௧௦'],\n            ['D Do DD',                       '௧௪ ௧௪வது ௧௪'],\n            ['d do dddd ddd dd',              '௦ ௦வது ஞாயிற்றுக்கிழமை ஞாயிறு ஞா'],\n            ['DDD DDDo DDDD',                 '௪௫ ௪௫வது ௦௪௫'],\n            ['w wo ww',                       '௮ ௮வது ௦௮'],\n            ['h hh',                          '௩ ௦௩'],\n            ['H HH',                          '௧௫ ௧௫'],\n            ['m mm',                          '௨௫ ௨௫'],\n            ['s ss',                          '௫௦ ௫௦'],\n            ['a A',                           ' எற்பாடு  எற்பாடு'],\n            ['[ஆண்டின்] DDDo  [நாள்]', 'ஆண்டின் ௪௫வது  நாள்'],\n            ['LTS',                           '௧௫:௨௫:௫௦'],\n            ['L',                             '௧௪/௦௨/௨௦௧௦'],\n            ['LL',                            '௧௪ பிப்ரவரி ௨௦௧௦'],\n            ['LLL',                           '௧௪ பிப்ரவரி ௨௦௧௦, ௧௫:௨௫'],\n            ['LLLL',                          'ஞாயிற்றுக்கிழமை, ௧௪ பிப்ரவரி ௨௦௧௦, ௧௫:௨௫'],\n            ['l',                             '௧௪/௨/௨௦௧௦'],\n            ['ll',                            '௧௪ பிப்ரவரி ௨௦௧௦'],\n            ['lll',                           '௧௪ பிப்ரவரி ௨௦௧௦, ௧௫:௨௫'],\n            ['llll',                          'ஞாயிறு, ௧௪ பிப்ரவரி ௨௦௧௦, ௧௫:௨௫']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '௧வது', '௧வது');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '௨வது', '௨வது');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '௩வது', '௩வது');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '௪வது', '௪வது');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '௫வது', '௫வது');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '௬வது', '௬வது');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '௭வது', '௭வது');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '௮வது', '௮வது');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '௯வது', '௯வது');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '௧௦வது', '௧௦வது');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '௧௧வது', '௧௧வது');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '௧௨வது', '௧௨வது');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '௧௩வது', '௧௩வது');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '௧௪வது', '௧௪வது');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '௧௫வது', '௧௫வது');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '௧௬வது', '௧௬வது');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '௧௭வது', '௧௭வது');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '௧௮வது', '௧௮வது');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '௧௯வது', '௧௯வது');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '௨௦வது', '௨௦வது');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '௨௧வது', '௨௧வது');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '௨௨வது', '௨௨வது');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '௨௩வது', '௨௩வது');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '௨௪வது', '௨௪வது');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '௨௫வது', '௨௫வது');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '௨௬வது', '௨௬வது');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '௨௭வது', '௨௭வது');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '௨௮வது', '௨௮வது');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '௨௯வது', '௨௯வது');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '௩௦வது', '௩௦வது');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '௩௧வது', '௩௧வது');\n});\n\ntest('format month', function (assert) {\n    var expected = 'ஜனவரி ஜனவரி_பிப்ரவரி பிப்ரவரி_மார்ச் மார்ச்_ஏப்ரல் ஏப்ரல்_மே மே_ஜூன் ஜூன்_ஜூலை ஜூலை_ஆகஸ்ட் ஆகஸ்ட்_செப்டெம்பர் செப்டெம்பர்_அக்டோபர் அக்டோபர்_நவம்பர் நவம்பர்_டிசம்பர் டிசம்பர்'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'ஞாயிற்றுக்கிழமை ஞாயிறு ஞா_திங்கட்கிழமை திங்கள் தி_செவ்வாய்கிழமை செவ்வாய் செ_புதன்கிழமை புதன் பு_வியாழக்கிழமை வியாழன் வி_வெள்ளிக்கிழமை வெள்ளி வெ_சனிக்கிழமை சனி ச'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'ஒரு சில விநாடிகள்', '44 விநாடிகள் = ஒரு சில விநாடிகள்');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'ஒரு நிமிடம்',      '45 விநாடிகள் = ஒரு நிமிடம்');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'ஒரு நிமிடம்',      '89 விநாடிகள் = ஒரு நிமிடம்');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '௨ நிமிடங்கள்',     '90 விநாடிகள் = ௨ நிமிடங்கள்');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '௪௪ நிமிடங்கள்',    '44 நிமிடங்கள் = 44 நிமிடங்கள்');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'ஒரு மணி நேரம்',       '45 நிமிடங்கள் = ஒரு மணி நேரம்');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'ஒரு மணி நேரம்',       '89 நிமிடங்கள் = ஒரு மணி நேரம்');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '௨ மணி நேரம்',       '90 நிமிடங்கள் = ௨ மணி நேரம்');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '௫ மணி நேரம்',       '5 மணி நேரம் = 5 மணி நேரம்');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '௨௧ மணி நேரம்',      '௨௧ மணி நேரம் = ௨௧ மணி நேரம்');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'ஒரு நாள்',         '௨௨ மணி நேரம் = ஒரு நாள்');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'ஒரு நாள்',         '௩5 மணி நேரம் = ஒரு நாள்');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '௨ நாட்கள்',        '௩6 மணி நேரம் = ௨ days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'ஒரு நாள்',         '௧ நாள் = ஒரு நாள்');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '௫ நாட்கள்',        '5 நாட்கள் = 5 நாட்கள்');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '௨௫ நாட்கள்',       '௨5 நாட்கள் = ௨5 நாட்கள்');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'ஒரு மாதம்',       '௨6 நாட்கள் = ஒரு மாதம்');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'ஒரு மாதம்',       '௩0 நாட்கள் = ஒரு மாதம்');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'ஒரு மாதம்',       '45 நாட்கள் = ஒரு மாதம்');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '௨ மாதங்கள்',      '46 நாட்கள் = ௨ மாதங்கள்');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '௨ மாதங்கள்',      '75 நாட்கள் = ௨ மாதங்கள்');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '௩ மாதங்கள்',      '76 நாட்கள் = ௩ மாதங்கள்');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'ஒரு மாதம்',       '௧ மாதம் = ஒரு மாதம்');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '௫ மாதங்கள்',      '5 மாதங்கள் = 5 மாதங்கள்');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'ஒரு வருடம்',        '௩45 நாட்கள் = ஒரு வருடம்');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '௨ ஆண்டுகள்',       '548 நாட்கள் = ௨ ஆண்டுகள்');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'ஒரு வருடம்',        '௧ வருடம் = ஒரு வருடம்');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '௫ ஆண்டுகள்',       '5 ஆண்டுகள் = 5 ஆண்டுகள்');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'ஒரு சில விநாடிகள் இல்',  'prefix');\n    assert.equal(moment(0).from(30000), 'ஒரு சில விநாடிகள் முன்', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'ஒரு சில விநாடிகள் முன்',  'இப்போது இருந்து கடந்த காலத்தில் காட்ட வேண்டும்');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'ஒரு சில விநாடிகள் இல்', 'ஒரு சில விநாடிகள் இல்');\n    assert.equal(moment().add({d: 5}).fromNow(), '௫ நாட்கள் இல்', '5 நாட்கள் இல்');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'இன்று ௧௨:௦௦',   'இன்று  12:00');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'இன்று ௧௨:௨௫',   'இன்று  12:25');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'இன்று ௧௩:௦௦',   'இன்று  13:00');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'நாளை ௧௨:௦௦',    'நாளை  12:00');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'இன்று ௧௧:௦௦',   'இன்று  11:00');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'நேற்று ௧௨:௦௦',  'நேற்று  12:00');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('dddd, LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd, LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd, LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('[கடந்த வாரம்] dddd, LT'),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[கடந்த வாரம்] dddd, LT'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[கடந்த வாரம்] dddd, LT'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('meridiem', function (assert) {\n    assert.equal(moment([2011, 2, 23,  0, 30]).format('a'), ' யாமம்', '(after) midnight');\n    assert.equal(moment([2011, 2, 23,  2, 30]).format('a'), ' வைகறை', 'before dawn');\n    assert.equal(moment([2011, 2, 23,  9, 30]).format('a'), ' காலை', 'morning');\n    assert.equal(moment([2011, 2, 23, 14, 30]).format('a'), ' எற்பாடு', 'during day');\n    assert.equal(moment([2011, 2, 23, 17, 30]).format('a'), ' எற்பாடு', 'evening');\n    assert.equal(moment([2011, 2, 23, 19, 30]).format('a'), ' மாலை', 'late evening');\n    assert.equal(moment([2011, 2, 23, 23, 30]).format('a'), ' யாமம்', '(before) midnight');\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\n\n\nfunction localeModule (name, lifecycle) {\n    QUnit.module('locale:' + name, {\n        setup : function () {\n            moment.locale(name);\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            moment.locale('en');\n            teardownDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n    defineCommonLocaleTests(name, -1, -1);\n}\n\nlocaleModule('te');\n\ntest('parse', function (assert) {\n    var tests = 'జనవరి జన._ఫిబ్రవరి ఫిబ్ర._మార్చి మార్చి_ఏప్రిల్ ఏప్రి._మే మే_జూన్ జూన్_జూలై జూలై_ఆగస్టు ఆగ._సెప్టెంబర్ సెప్._అక్టోబర్ అక్టో._నవంబర్ నవ._డిసెంబర్ డిసె.'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, Do తేదీ MMMM YYYY, a h:mm:ss',  'ఆదివారం, 14వ తేదీ ఫిబ్రవరి 2010, మధ్యాహ్నం 3:25:50'],\n            ['ddd, a h గంటలు',                 'ఆది, మధ్యాహ్నం 3 గంటలు'],\n            ['M Mo నెల MM MMMM MMM',                   '2 2వ నెల 02 ఫిబ్రవరి ఫిబ్ర.'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14వ 14'],\n            ['d do dddd ddd dd',                   '0 0వ ఆదివారం ఆది ఆ'],\n            ['DDD DDDo DDDD',                      '45 45వ 045'],\n            ['w wo ww',                            '8 8వ 08'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'మధ్యాహ్నం మధ్యాహ్నం'],\n            ['LTS',                                'మధ్యాహ్నం 3:25:50'],\n            ['L',                                  '14/02/2010'],\n            ['LL',                                 '14 ఫిబ్రవరి 2010'],\n            ['LLL',                                '14 ఫిబ్రవరి 2010, మధ్యాహ్నం 3:25'],\n            ['LLLL',                               'ఆదివారం, 14 ఫిబ్రవరి 2010, మధ్యాహ్నం 3:25'],\n            ['l',                                  '14/2/2010'],\n            ['ll',                                 '14 ఫిబ్ర. 2010'],\n            ['lll',                                '14 ఫిబ్ర. 2010, మధ్యాహ్నం 3:25'],\n            ['llll',                               'ఆది, 14 ఫిబ్ర. 2010, మధ్యాహ్నం 3:25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1వ', '1వ');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2వ', '2వ');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3వ', '3వ');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4వ', '4వ');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5వ', '5వ');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6వ', '6వ');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7వ', '7వ');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8వ', '8వ');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9వ', '9వ');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10వ', '10వ');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11వ', '11వ');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12వ', '12వ');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13వ', '13వ');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14వ', '14వ');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15వ', '15వ');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16వ', '16వ');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17వ', '17వ');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18వ', '18వ');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19వ', '19వ');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20వ', '20వ');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21వ', '21వ');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22వ', '22వ');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23వ', '23వ');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24వ', '24వ');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25వ', '25వ');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26వ', '26వ');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27వ', '27వ');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28వ', '28వ');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29వ', '29వ');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30వ', '30వ');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31వ', '31వ');\n});\n\ntest('format month', function (assert) {\n    var expected = 'జనవరి జన._ఫిబ్రవరి ఫిబ్ర._మార్చి మార్చి_ఏప్రిల్ ఏప్రి._మే మే_జూన్ జూన్_జూలై జూలై_ఆగస్టు ఆగ._సెప్టెంబర్ సెప్._అక్టోబర్ అక్టో._నవంబర్ నవ._డిసెంబర్ డిసె.'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'ఆదివారం ఆది ఆ_సోమవారం సోమ సో_మంగళవారం మంగళ మం_బుధవారం బుధ బు_గురువారం గురు గు_శుక్రవారం శుక్ర శు_శనివారం శని శ'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'కొన్ని క్షణాలు', '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'ఒక నిమిషం',      '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'ఒక నిమిషం',      '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 నిమిషాలు',     '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 నిమిషాలు',    '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'ఒక గంట',       '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'ఒక గంట',       '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 గంటలు',       '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 గంటలు',       '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 గంటలు',      '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'ఒక రోజు',         '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'ఒక రోజు',         '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 రోజులు',        '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'ఒక రోజు',         '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 రోజులు',        '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 రోజులు',       '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'ఒక నెల',       '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'ఒక నెల',       '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'ఒక నెల',       '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 నెలలు',      '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 నెలలు',      '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 నెలలు',      '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'ఒక నెల',       '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 నెలలు',      '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'ఒక సంవత్సరం',        '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 సంవత్సరాలు',       '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'ఒక సంవత్సరం',        '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 సంవత్సరాలు',       '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'కొన్ని క్షణాలు లో',  'prefix');\n    assert.equal(moment(0).from(30000), 'కొన్ని క్షణాలు క్రితం', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'కొన్ని క్షణాలు క్రితం',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'కొన్ని క్షణాలు లో', 'కొన్ని క్షణాలు లో');\n    assert.equal(moment().add({d: 5}).fromNow(), '5 రోజులు లో', '5 రోజులు లో');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'నేడు మధ్యాహ్నం 12:00',   'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'నేడు మధ్యాహ్నం 12:25',   'Now plus 25 min');\n    assert.equal(moment(a).add({h: 3}).calendar(),       'నేడు మధ్యాహ్నం 3:00',    'Now plus 3 hours');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'రేపు మధ్యాహ్నం 12:00',   'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'నేడు మధ్యాహ్నం 11:00',   'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'నిన్న మధ్యాహ్నం 12:00',  'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('dddd[,] LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd[,] LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd[,] LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('[గత] dddd[,] LT'),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[గత] dddd[,] LT'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[గత] dddd[,] LT'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('meridiem', function (assert) {\n    assert.equal(moment([2011, 2, 23,  2, 30]).format('a'), 'రాత్రి', 'before dawn');\n    assert.equal(moment([2011, 2, 23,  9, 30]).format('a'), 'ఉదయం', 'morning');\n    assert.equal(moment([2011, 2, 23, 14, 30]).format('a'), 'మధ్యాహ్నం', 'during day');\n    assert.equal(moment([2011, 2, 23, 17, 30]).format('a'), 'సాయంత్రం', 'evening');\n    assert.equal(moment([2011, 2, 23, 19, 30]).format('a'), 'సాయంత్రం', 'late evening');\n    assert.equal(moment([2011, 2, 23, 21, 20]).format('a'), 'రాత్రి', 'night');\n\n    assert.equal(moment([2011, 2, 23,  2, 30]).format('A'), 'రాత్రి', 'before dawn');\n    assert.equal(moment([2011, 2, 23,  9, 30]).format('A'), 'ఉదయం', 'morning');\n    assert.equal(moment([2011, 2, 23, 14, 30]).format('A'), 'మధ్యాహ్నం', ' during day');\n    assert.equal(moment([2011, 2, 23, 17, 30]).format('A'), 'సాయంత్రం', 'evening');\n    assert.equal(moment([2011, 2, 23, 19, 30]).format('A'), 'సాయంత్రం', 'late evening');\n    assert.equal(moment([2011, 2, 23, 21, 20]).format('A'), 'రాత్రి', 'night');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2012, 0,  1]).format('w ww wo'), '1 01 1వ', 'Jan  1 2012 should be week 1');\n    assert.equal(moment([2012, 0,  7]).format('w ww wo'), '1 01 1వ', 'Jan  7 2012 should be week 1');\n    assert.equal(moment([2012, 0,  8]).format('w ww wo'), '2 02 2వ', 'Jan  8 2012 should be week 2');\n    assert.equal(moment([2012, 0, 14]).format('w ww wo'), '2 02 2వ', 'Jan 14 2012 should be week 2');\n    assert.equal(moment([2012, 0, 15]).format('w ww wo'), '3 03 3వ', 'Jan 15 2012 should be week 3');\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\n\n\nfunction localeModule (name, lifecycle) {\n    QUnit.module('locale:' + name, {\n        setup : function () {\n            moment.locale(name);\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            moment.locale('en');\n            teardownDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n    defineCommonLocaleTests(name, -1, -1);\n}\n\nlocaleModule('tet');\n\ntest('parse', function (assert) {\n    var tests = 'Janeiru Jan_Fevereiru Fev_Marsu Mar_Abril Abr_Maiu Mai_Juniu Jun_Juliu Jul_Augustu Aug_Setembru Set_Outubru Out_Novembru Nov_Dezembru Dez'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, MMMM Do YYYY, h:mm:ss a',      'Domingu, Fevereiru 14th 2010, 3:25:50 pm'],\n            ['ddd, hA',                            'Dom, 3PM'],\n            ['M Mo MM MMMM MMM',                   '2 2nd 02 Fevereiru Fev'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14th 14'],\n            ['d do dddd ddd dd',                   '0 0th Domingu Dom Do'],\n            ['DDD DDDo DDDD',                      '45 45th 045'],\n            ['w wo ww',                            '6 6th 06'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'pm PM'],\n            ['[the] DDDo [day of the year]',       'the 45th day of the year'],\n            ['LTS',                                '15:25:50'],\n            ['L',                                  '14/02/2010'],\n            ['LL',                                 '14 Fevereiru 2010'],\n            ['LLL',                                '14 Fevereiru 2010 15:25'],\n            ['LLLL',                               'Domingu, 14 Fevereiru 2010 15:25'],\n            ['l',                                  '14/2/2010'],\n            ['ll',                                 '14 Fev 2010'],\n            ['lll',                                '14 Fev 2010 15:25'],\n            ['llll',                               'Dom, 14 Fev 2010 15:25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1st', '1st');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2nd', '2nd');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3rd', '3rd');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4th', '4th');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5th', '5th');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6th', '6th');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7th', '7th');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8th', '8th');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9th', '9th');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10th', '10th');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11th', '11th');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12th', '12th');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13th', '13th');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14th', '14th');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15th', '15th');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16th', '16th');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17th', '17th');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18th', '18th');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19th', '19th');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20th', '20th');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21st', '21st');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22nd', '22nd');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23rd', '23rd');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24th', '24th');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25th', '25th');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26th', '26th');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27th', '27th');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28th', '28th');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29th', '29th');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30th', '30th');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31st', '31st');\n});\n\ntest('format month', function (assert) {\n    var expected = 'Janeiru Jan_Fevereiru Fev_Marsu Mar_Abril Abr_Maiu Mai_Juniu Jun_Juliu Jul_Augustu Aug_Setembru Set_Outubru Out_Novembru Nov_Dezembru Dez'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'Domingu Dom Do_Segunda Seg Seg_Tersa Ters Te_Kuarta Kua Ku_Kinta Kint Ki_Sexta Sext Sex_Sabadu Sab Sa'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'minutu balun', '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'minutu ida',      '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'minutu ida',      '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  'minutus 2',     '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  'minutus 44',    '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'horas ida',       '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'horas ida',       '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  'horas 2',       '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   'horas 5',       '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  'horas 21',      '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'loron ida',         '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'loron ida',         '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  'loron 2',        '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'loron ida',         '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   'loron 5',        '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  'loron 25',       '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'fulan ida',       '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'fulan ida',       '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'fulan ida',       '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  'fulan 2',      '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  'fulan 2',      '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  'fulan 3',      '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'fulan ida',       '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   'fulan 5',      '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'tinan ida',        '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), 'tinan 2',       '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'tinan ida',        '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   'tinan 5',       '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'iha minutu balun',  'prefix');\n    assert.equal(moment(0).from(30000), 'minutu balun liuba', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'minutu balun liuba',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'iha minutu balun', 'in a few seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), 'iha loron 5', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'Ohin iha 12:00',      'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'Ohin iha 12:25',      'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'Ohin iha 13:00',      'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'Aban iha 12:00',   'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'Ohin iha 11:00',      'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'Horiseik iha 12:00',  'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('dddd [iha] LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd [iha] LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd [iha] LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('dddd [semana kotuk] [iha] LT'),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd [semana kotuk] [iha] LT'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd [semana kotuk] [iha] LT'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2012, 0,  1]).format('w ww wo'), '52 52 52nd', 'Jan  1 2012 should be week 52');\n    assert.equal(moment([2012, 0,  2]).format('w ww wo'),   '1 01 1st', 'Jan  2 2012 should be week 1');\n    assert.equal(moment([2012, 0,  8]).format('w ww wo'),   '1 01 1st', 'Jan  8 2012 should be week 1');\n    assert.equal(moment([2012, 0,  9]).format('w ww wo'),   '2 02 2nd', 'Jan  9 2012 should be week 2');\n    assert.equal(moment([2012, 0, 15]).format('w ww wo'),   '2 02 2nd', 'Jan 15 2012 should be week 2');\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\n\n\nfunction localeModule (name, lifecycle) {\n    QUnit.module('locale:' + name, {\n        setup : function () {\n            moment.locale(name);\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            moment.locale('en');\n            teardownDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n    defineCommonLocaleTests(name, -1, -1);\n}\n\nlocaleModule('th');\n\ntest('parse', function (assert) {\n    var tests = 'มกราคม ม.ค._กุมภาพันธ์ ก.พ._มีนาคม มี.ค._เมษายน เม.ย._พฤษภาคม พ.ค._มิถุนายน มิ.ย._กรกฎาคม ก.ค._สิงหาคม ส.ค._กันยายน ก.ย._ตุลาคม ต.ค._พฤศจิกายน พ.ย._ธันวาคม ธ.ค.'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, Do MMMM YYYY, h:mm:ss a',      'อาทิตย์, 14 กุมภาพันธ์ 2010, 3:25:50 หลังเที่ยง'],\n            ['ddd, h A',                           'อาทิตย์, 3 หลังเที่ยง'],\n            ['M Mo MM MMMM MMM',                   '2 2 02 กุมภาพันธ์ ก.พ.'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14 14'],\n            ['d do dddd ddd dd',                   '0 0 อาทิตย์ อาทิตย์ อา.'],\n            ['DDD DDDo DDDD',                      '45 45 045'],\n            ['w wo ww',                            '8 8 08'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'หลังเที่ยง หลังเที่ยง'],\n            ['[the] DDDo [day of the year]',       'the 45 day of the year'],\n            ['LTS',                                '15:25:50'],\n            ['L',                                  '14/02/2010'],\n            ['LL',                                 '14 กุมภาพันธ์ 2010'],\n            ['LLL',                                '14 กุมภาพันธ์ 2010 เวลา 15:25'],\n            ['LLLL',                               'วันอาทิตย์ที่ 14 กุมภาพันธ์ 2010 เวลา 15:25'],\n            ['l',                                  '14/2/2010'],\n            ['ll',                                 '14 ก.พ. 2010'],\n            ['lll',                                '14 ก.พ. 2010 เวลา 15:25'],\n            ['llll',                               'วันอาทิตย์ที่ 14 ก.พ. 2010 เวลา 15:25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format month', function (assert) {\n    var expected = 'มกราคม ม.ค._กุมภาพันธ์ ก.พ._มีนาคม มี.ค._เมษายน เม.ย._พฤษภาคม พ.ค._มิถุนายน มิ.ย._กรกฎาคม ก.ค._สิงหาคม ส.ค._กันยายน ก.ย._ตุลาคม ต.ค._พฤศจิกายน พ.ย._ธันวาคม ธ.ค.'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'อาทิตย์ อาทิตย์ อา._จันทร์ จันทร์ จ._อังคาร อังคาร อ._พุธ พุธ พ._พฤหัสบดี พฤหัส พฤ._ศุกร์ ศุกร์ ศ._เสาร์ เสาร์ ส.'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'ไม่กี่วินาที',   '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  '1 นาที', '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  '1 นาที', '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 นาที',  '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 นาที', '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  '1 ชั่วโมง', '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  '1 ชั่วโมง', '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 ชั่วโมง',  '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 ชั่วโมง',  '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 ชั่วโมง', '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  '1 วัน',   '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  '1 วัน',   '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 วัน',   '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   '1 วัน',   '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 วัน',   '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 วัน',  '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  '1 เดือน', '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  '1 เดือน', '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  '1 เดือน', '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 เดือน',  '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 เดือน',  '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 เดือน',  '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   '1 เดือน', '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 เดือน',  '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), '1 ปี',   '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 ปี',   '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   '1 ปี',   '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 ปี',   '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'อีก ไม่กี่วินาที',  'prefix');\n    assert.equal(moment(0).from(30000), 'ไม่กี่วินาทีที่แล้ว', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'ไม่กี่วินาทีที่แล้ว',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'อีก ไม่กี่วินาที', 'in a few seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), 'อีก 5 วัน', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'วันนี้ เวลา 12:00',      'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'วันนี้ เวลา 12:25',     'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'วันนี้ เวลา 13:00',      'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'พรุ่งนี้ เวลา 12:00',    'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'วันนี้ เวลา 11:00',      'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'เมื่อวานนี้ เวลา 12:00', 'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('dddd[หน้า เวลา] LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd[หน้า เวลา] LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd[หน้า เวลา] LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('[วัน]dddd[ที่แล้ว เวลา] LT'),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[วัน]dddd[ที่แล้ว เวลา] LT'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[วัน]dddd[ที่แล้ว เวลา] LT'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),      '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),      '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('weeks year starting sunday format', function (assert) {\n    assert.equal(moment([2012, 0,  1]).format('w ww wo'), '1 01 1', 'Jan  1 2012 should be week 1');\n    assert.equal(moment([2012, 0,  7]).format('w ww wo'), '1 01 1', 'Jan  7 2012 should be week 1');\n    assert.equal(moment([2012, 0,  8]).format('w ww wo'), '2 02 2', 'Jan  8 2012 should be week 2');\n    assert.equal(moment([2012, 0, 14]).format('w ww wo'), '2 02 2', 'Jan 14 2012 should be week 2');\n    assert.equal(moment([2012, 0, 15]).format('w ww wo'), '3 03 3', 'Jan 15 2012 should be week 3');\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\n\n\nfunction localeModule (name, lifecycle) {\n    QUnit.module('locale:' + name, {\n        setup : function () {\n            moment.locale(name);\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            moment.locale('en');\n            teardownDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n    defineCommonLocaleTests(name, -1, -1);\n}\n\nlocaleModule('tl-ph');\n\ntest('parse', function (assert) {\n    var tests = 'Enero Ene_Pebrero Peb_Marso Mar_Abril Abr_Mayo May_Hunyo Hun_Hulyo Hul_Agosto Ago_Setyembre Set_Oktubre Okt_Nobyembre Nob_Disyembre Dis'.split('_'),\n        i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, MMMM Do YYYY, h:mm:ss a',      'Linggo, Pebrero 14 2010, 3:25:50 pm'],\n            ['ddd, hA',                            'Lin, 3PM'],\n            ['M Mo MM MMMM MMM',                   '2 2 02 Pebrero Peb'],\n            ['YYYY YY',                             '2010 10'],\n            ['D Do DD',                            '14 14 14'],\n            ['d do dddd ddd dd',                   '0 0 Linggo Lin Li'],\n            ['DDD DDDo DDDD',                      '45 45 045'],\n            ['w wo ww',                            '6 6 06'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'pm PM'],\n            ['[the] DDDo [day of the year]',       'the 45 day of the year'],\n            ['LTS',                                '15:25:50'],\n            ['L',                                  '02/14/2010'],\n            ['LL',                                 'Pebrero 14, 2010'],\n            ['LLL',                                'Pebrero 14, 2010 15:25'],\n            ['LLLL',                               'Linggo, Pebrero 14, 2010 15:25'],\n            ['l',                                  '2/14/2010'],\n            ['ll',                                 'Peb 14, 2010'],\n            ['lll',                                'Peb 14, 2010 15:25'],\n            ['llll',                               'Lin, Peb 14, 2010 15:25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1', '1');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2', '2');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3', '3');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4', '4');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5', '5');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6', '6');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7', '7');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8', '8');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9', '9');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10', '10');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11', '11');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12', '12');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13', '13');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14', '14');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15', '15');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16', '16');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17', '17');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18', '18');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19', '19');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20', '20');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21', '21');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22', '22');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23', '23');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24', '24');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25', '25');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26', '26');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27', '27');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28', '28');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29', '29');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30', '30');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31', '31');\n});\n\ntest('format month', function (assert) {\n    var expected = 'Enero Ene_Pebrero Peb_Marso Mar_Abril Abr_Mayo May_Hunyo Hun_Hulyo Hul_Agosto Ago_Setyembre Set_Oktubre Okt_Nobyembre Nob_Disyembre Dis'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'Linggo Lin Li_Lunes Lun Lu_Martes Mar Ma_Miyerkules Miy Mi_Huwebes Huw Hu_Biyernes Biy Bi_Sabado Sab Sab'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'ilang segundo', '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'isang minuto',   '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'isang minuto',   '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 minuto',  '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 minuto', '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'isang oras',    '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'isang oras',    '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 oras',    '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 oras',    '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 oras',   '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'isang araw',      '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'isang araw',      '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 araw',     '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'isang araw',      '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 araw',     '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 araw',    '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'isang buwan',    '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'isang buwan',    '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'isang buwan',    '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 buwan',   '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 buwan',   '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 buwan',   '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'isang buwan',    '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 buwan',   '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'isang taon',     '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 taon',    '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'isang taon',     '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 taon',    '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'sa loob ng ilang segundo', 'prefix');\n    assert.equal(moment(0).from(30000), 'ilang segundo ang nakalipas', 'suffix');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'sa loob ng ilang segundo', 'in a few seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), 'sa loob ng 5 araw', 'in 5 days');\n});\n\ntest('same day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   '12:00 ngayong araw',    'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      '12:25 ngayong araw',    'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       '13:00 ngayong araw',    'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'Bukas ng 12:00',     'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  '11:00 ngayong araw',    'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  '12:00 kahapon',   'yesterday at the same time');\n});\n\ntest('same next week', function (assert) {\n    var i, m;\n\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('LT [sa susunod na] dddd'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('LT [sa susunod na] dddd'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('LT [sa susunod na] dddd'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('same last week', function (assert) {\n    var i, m;\n\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('LT [noong nakaraang] dddd'),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('LT [noong nakaraang] dddd'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('LT [noong nakaraang] dddd'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('same all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2012, 0,  1]).format('w ww wo'), '52 52 52', 'Jan  1 2012 should be week 52');\n    assert.equal(moment([2012, 0,  2]).format('w ww wo'), '1 01 1', 'Jan  2 2012 should be week 1');\n    assert.equal(moment([2012, 0,  8]).format('w ww wo'), '1 01 1', 'Jan  8 2012 should be week 1');\n    assert.equal(moment([2012, 0,  9]).format('w ww wo'),   '2 02 2', 'Jan  9 2012 should be week 2');\n    assert.equal(moment([2012, 0, 15]).format('w ww wo'),   '2 02 2', 'Jan 15 2012 should be week 2');\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\n\n\nfunction localeModule (name, lifecycle) {\n    QUnit.module('locale:' + name, {\n        setup : function () {\n            moment.locale(name);\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            moment.locale('en');\n            teardownDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n    defineCommonLocaleTests(name, -1, -1);\n}\n\nlocaleModule('tlh');\n\n//Current parsing method doesn't allow parsing correctly months 10, 11 and 12.\n/*\n * test('parse', function (assert) {\n    var tests = 'tera’ jar wa’.jar wa’_tera’ jar cha’.jar cha’_tera’ jar wej.jar wej_tera’ jar loS.jar loS_tera’ jar vagh.jar vagh_tera’ jar jav.jar jav_tera’ jar Soch.jar Soch_tera’ jar chorgh.jar chorgh_tera’ jar Hut.jar Hut_tera’ jar wa’maH.jar wa’maH_tera’ jar wa’maH wa’.jar wa’maH wa’_tera’ jar wa’maH cha’.jar wa’maH cha’'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split('.');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n*/\ntest('format', function (assert) {\n    var a = [\n            ['dddd, MMMM Do YYYY, h:mm:ss a',      'lojmItjaj, tera’ jar cha’ 14. 2010, 3:25:50 pm'],\n            ['ddd, hA',                            'lojmItjaj, 3PM'],\n            ['M Mo MM MMMM MMM',                   '2 2. 02 tera’ jar cha’ jar cha’'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14. 14'],\n            ['d do dddd ddd dd',                   '0 0. lojmItjaj lojmItjaj lojmItjaj'],\n            ['DDD DDDo DDDD',                      '45 45. 045'],\n            ['w wo ww',                            '6 6. 06'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'pm PM'],\n            ['[DIS jaj] DDDo',                     'DIS jaj 45.'],\n            ['LTS',                                '15:25:50'],\n            ['L',                                  '14.02.2010'],\n            ['LL',                                 '14 tera’ jar cha’ 2010'],\n            ['LLL',                                '14 tera’ jar cha’ 2010 15:25'],\n            ['LLLL',                               'lojmItjaj, 14 tera’ jar cha’ 2010 15:25'],\n            ['l',                                  '14.2.2010'],\n            ['ll',                                 '14 jar cha’ 2010'],\n            ['lll',                                '14 jar cha’ 2010 15:25'],\n            ['llll',                               'lojmItjaj, 14 jar cha’ 2010 15:25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1.', '1.');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2.', '2.');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3.', '3.');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4.', '4.');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5.', '5.');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6.', '6.');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7.', '7.');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8.', '8.');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9.', '9.');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10.', '10.');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11.', '11.');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12.', '12.');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13.', '13.');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14.', '14.');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15.', '15.');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16.', '16.');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17.', '17.');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18.', '18.');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19.', '19.');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20.', '20.');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21.', '21.');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22.', '22.');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23.', '23.');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24.', '24.');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25.', '25.');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26.', '26.');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27.', '27.');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28.', '28.');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29.', '29.');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30.', '30.');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31.', '31.');\n});\n\ntest('format month', function (assert) {\n    var expected = 'tera’ jar wa’ jar wa’_tera’ jar cha’ jar cha’_tera’ jar wej jar wej_tera’ jar loS jar loS_tera’ jar vagh jar vagh_tera’ jar jav jar jav_tera’ jar Soch jar Soch_tera’ jar chorgh jar chorgh_tera’ jar Hut jar Hut_tera’ jar wa’maH jar wa’maH_tera’ jar wa’maH wa’ jar wa’maH wa’_tera’ jar wa’maH cha’ jar wa’maH cha’'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'lojmItjaj lojmItjaj lojmItjaj_DaSjaj DaSjaj DaSjaj_povjaj povjaj povjaj_ghItlhjaj ghItlhjaj ghItlhjaj_loghjaj loghjaj loghjaj_buqjaj buqjaj buqjaj_ghInjaj ghInjaj ghInjaj'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'puS lup',  '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'wa’ tup',        '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'wa’ tup',        '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  'cha’ tup',      '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  'loSmaH loS tup',     '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'wa’ rep',       '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'wa’ rep',       '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  'cha’ rep',     '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   'vagh rep',      '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  'cha’maH wa’ rep',     '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'wa’ jaj',       '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'wa’ jaj',       '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  'cha’ jaj',         '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'wa’ jaj',       '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   'vagh jaj',         '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  'cha’maH vagh jaj',        '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'wa’ jar',       '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'wa’ jar',       '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'wa’ jar',       '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  'cha’ jar',    '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  'cha’ jar',    '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  'wej jar',    '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'wa’ jar',       '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   'vagh jar',    '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'wa’ DIS',           '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), 'cha’ DIS',        '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'wa’ DIS',           '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   'vagh DIS',         '5 years = 5 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 112}), true), 'wa’vatlh wa’maH cha’ DIS',       '112 years = 112 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 122}), true), 'wa’vatlh cha’maH cha’ DIS',      '122 years = 122 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 213}), true), 'cha’vatlh wa’maH wej DIS',       '213 years = 213 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 223}), true), 'cha’vatlh cha’maH wej DIS',      '223 years = 223 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'puS lup pIq',  'suffix');\n    assert.equal(moment(0).from(30000), 'puS lup ret', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'puS lup ret',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'puS lup pIq', 'in a few seconds');\n    assert.equal(moment().add({h: 1}).fromNow(), 'wa’ rep pIq', 'in an hour');\n    assert.equal(moment().add({d: 5}).fromNow(), 'vagh leS', 'in 5 days');\n    assert.equal(moment().add({M: 2}).fromNow(), 'cha’ waQ', 'in 2 months');\n    assert.equal(moment().add({y: 1}).fromNow(), 'wa’ nem', 'in a year');\n    assert.equal(moment().add({s: -30}).fromNow(), 'puS lup ret', 'a few seconds ago');\n    assert.equal(moment().add({h: -1}).fromNow(), 'wa’ rep ret', 'an hour ago');\n    assert.equal(moment().add({d: -5}).fromNow(), 'vagh Hu’', '5 days ago');\n    assert.equal(moment().add({M: -2}).fromNow(), 'cha’ wen', '2 months ago');\n    assert.equal(moment().add({y: -1}).fromNow(), 'wa’ ben', 'a year ago');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'DaHjaj 12:00',     'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'DaHjaj 12:25',     'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'DaHjaj 13:00',     'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'wa’leS 12:00',     'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'DaHjaj 11:00',     'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'wa’Hu’ 12:00',     'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('LLL'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('LLL'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('LLL'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(), m.format('LLL'), 'Today - ' + i + ' days current time');\n\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(), m.format('LLL'), 'Today - ' + i + ' days beginning of day');\n\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(), m.format('LLL'), 'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2012, 0,  1]).format('w ww wo'), '52 52 52.', 'Jan  1 2012 should be week 52');\n    assert.equal(moment([2012, 0,  2]).format('w ww wo'),   '1 01 1.', 'Jan  2 2012 should be week 1');\n    assert.equal(moment([2012, 0,  8]).format('w ww wo'),   '1 01 1.', 'Jan  8 2012 should be week 1');\n    assert.equal(moment([2012, 0,  9]).format('w ww wo'),   '2 02 2.', 'Jan  9 2012 should be week 2');\n    assert.equal(moment([2012, 0, 15]).format('w ww wo'),   '2 02 2.', 'Jan 15 2012 should be week 2');\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\n\n\nfunction localeModule (name, lifecycle) {\n    QUnit.module('locale:' + name, {\n        setup : function () {\n            moment.locale(name);\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            moment.locale('en');\n            teardownDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n    defineCommonLocaleTests(name, -1, -1);\n}\n\nlocaleModule('tr');\n\ntest('parse', function (assert) {\n    var tests = 'Ocak Oca_Şubat Şub_Mart Mar_Nisan Nis_Mayıs May_Haziran Haz_Temmuz Tem_Ağustos Ağu_Eylül Eyl_Ekim Eki_Kasım Kas_Aralık Ara'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, MMMM Do YYYY, h:mm:ss a',      'Pazar, Şubat 14\\'üncü 2010, 3:25:50 pm'],\n            ['ddd, hA',                            'Paz, 3PM'],\n            ['M Mo MM MMMM MMM',                   '2 2\\'nci 02 Şubat Şub'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14\\'üncü 14'],\n            ['d do dddd ddd dd',                   '0 0\\'ıncı Pazar Paz Pz'],\n            ['DDD DDDo DDDD',                      '45 45\\'inci 045'],\n            ['w wo ww',                            '7 7\\'nci 07'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'pm PM'],\n            ['[yılın] DDDo [günü]',                'yılın 45\\'inci günü'],\n            ['LTS',                                '15:25:50'],\n            ['L',                                  '14.02.2010'],\n            ['LL',                                 '14 Şubat 2010'],\n            ['LLL',                                '14 Şubat 2010 15:25'],\n            ['LLLL',                               'Pazar, 14 Şubat 2010 15:25'],\n            ['l',                                  '14.2.2010'],\n            ['ll',                                 '14 Şub 2010'],\n            ['lll',                                '14 Şub 2010 15:25'],\n            ['llll',                               'Paz, 14 Şub 2010 15:25']\n        ],\n        DDDo = [\n            [359, '360\\'ıncı'],\n            [199, '200\\'üncü'],\n            [149, '150\\'nci']\n        ],\n        dt = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        DDDoDt,\n        i;\n\n    for (i = 0; i < a.length; i++) {\n        assert.equal(dt.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n    for (i = 0; i < DDDo.length; i++) {\n        DDDoDt = moment([2010]);\n        assert.equal(DDDoDt.add(DDDo[i][0], 'days').format('DDDo'), DDDo[i][1], DDDo[i][0] + ' ---> ' + DDDo[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1\\'inci', '1st');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2\\'nci', '2nd');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3\\'üncü', '3rd');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4\\'üncü', '4th');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5\\'inci', '5th');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6\\'ncı', '6th');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7\\'nci', '7th');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8\\'inci', '8th');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9\\'uncu', '9th');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10\\'uncu', '10th');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11\\'inci', '11th');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12\\'nci', '12th');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13\\'üncü', '13th');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14\\'üncü', '14th');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15\\'inci', '15th');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16\\'ncı', '16th');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17\\'nci', '17th');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18\\'inci', '18th');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19\\'uncu', '19th');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20\\'nci', '20th');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21\\'inci', '21th');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22\\'nci', '22th');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23\\'üncü', '23th');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24\\'üncü', '24th');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25\\'inci', '25th');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26\\'ncı', '26th');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27\\'nci', '27th');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28\\'inci', '28th');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29\\'uncu', '29th');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30\\'uncu', '30th');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31\\'inci', '31st');\n});\n\ntest('format month', function (assert) {\n    var expected = 'Ocak Oca_Şubat Şub_Mart Mar_Nisan Nis_Mayıs May_Haziran Haz_Temmuz Tem_Ağustos Ağu_Eylül Eyl_Ekim Eki_Kasım Kas_Aralık Ara'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'Pazar Paz Pz_Pazartesi Pts Pt_Salı Sal Sa_Çarşamba Çar Ça_Perşembe Per Pe_Cuma Cum Cu_Cumartesi Cts Ct'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'birkaç saniye', '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'bir dakika',      '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'bir dakika',      '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 dakika',     '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 dakika',    '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'bir saat',       '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'bir saat',       '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 saat',       '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 saat',       '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 saat',      '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'bir gün',         '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'bir gün',         '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 gün',        '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'bir gün',         '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 gün',        '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 gün',       '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'bir ay',       '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'bir ay',       '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'bir ay',       '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 ay',      '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 ay',      '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 ay',      '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'bir ay',       '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 ay',      '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'bir yıl',        '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 yıl',       '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'bir yıl',        '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 yıl',       '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'birkaç saniye sonra',  'prefix');\n    assert.equal(moment(0).from(30000), 'birkaç saniye önce', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'birkaç saniye önce',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'birkaç saniye sonra', 'in a few seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), '5 gün sonra', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'bugün saat 12:00',     'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'bugün saat 12:25',     'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'bugün saat 13:00',     'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'yarın saat 12:00',     'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'bugün saat 11:00',     'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'dün 12:00',            'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('[haftaya] dddd [saat] LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[haftaya] dddd [saat] LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[haftaya] dddd [saat] LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('[geçen hafta] dddd [saat] LT'),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[geçen hafta] dddd [saat] LT'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[geçen hafta] dddd [saat] LT'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2011, 11, 26]).format('w ww wo'), '1 01 1\\'inci', 'Dec 26 2011 should be week 1');\n    assert.equal(moment([2012,  0,  1]).format('w ww wo'), '1 01 1\\'inci', 'Jan  1 2012 should be week 1');\n    assert.equal(moment([2012,  0,  2]).format('w ww wo'), '2 02 2\\'nci', 'Jan  2 2012 should be week 2');\n    assert.equal(moment([2012,  0,  8]).format('w ww wo'), '2 02 2\\'nci', 'Jan  8 2012 should be week 2');\n    assert.equal(moment([2012,  0,  9]).format('w ww wo'), '3 03 3\\'üncü', 'Jan  9 2012 should be week 3');\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\n\n\nfunction localeModule (name, lifecycle) {\n    QUnit.module('locale:' + name, {\n        setup : function () {\n            moment.locale(name);\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            moment.locale('en');\n            teardownDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n    defineCommonLocaleTests(name, -1, -1);\n}\n\nlocaleModule('tzl');\n\ntest('parse', function (assert) {\n    var tests = 'Januar Jan_Fevraglh Fev_Març Mar_Avrïu Avr_Mai Mai_Gün Gün_Julia Jul_Guscht Gus_Setemvar Set_Listopäts Lis_Noemvar Noe_Zecemvar Zec'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, MMMM Do YYYY, h.mm.ss a',      'Súladi, Fevraglh 14. 2010, 3.25.50 d\\'o'],\n            ['ddd, hA',                            'Súl, 3D\\'O'],\n            ['M Mo MM MMMM MMM',                   '2 2. 02 Fevraglh Fev'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14. 14'],\n            ['d do dddd ddd dd',                   '0 0. Súladi Súl Sú'],\n            ['DDD DDDo DDDD',                      '45 45. 045'],\n            ['w wo ww',                            '6 6. 06'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'd\\'o D\\'O'],\n            ['[the] DDDo [day of the year]',       'the 45. day of the year'],\n            ['LTS',                                '15.25.50'],\n            ['L',                                  '14.02.2010'],\n            ['LL',                                 '14. Fevraglh dallas 2010'],\n            ['LLL',                                '14. Fevraglh dallas 2010 15.25'],\n            ['LLLL',                               'Súladi, li 14. Fevraglh dallas 2010 15.25'],\n            ['l',                                  '14.2.2010'],\n            ['ll',                                 '14. Fev dallas 2010'],\n            ['lll',                                '14. Fev dallas 2010 15.25'],\n            ['llll',                               'Súl, li 14. Fev dallas 2010 15.25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1.', '1.');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2.', '2.');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3.', '3.');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4.', '4.');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5.', '5.');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6.', '6.');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7.', '7.');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8.', '8.');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9.', '9.');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10.', '10.');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11.', '11.');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12.', '12.');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13.', '13.');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14.', '14.');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15.', '15.');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16.', '16.');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17.', '17.');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18.', '18.');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19.', '19.');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20.', '20.');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21.', '21.');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22.', '22.');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23.', '23.');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24.', '24.');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25.', '25.');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26.', '26.');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27.', '27.');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28.', '28.');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29.', '29.');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30.', '30.');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31.', '31.');\n});\n\ntest('format month', function (assert) {\n    var expected = 'Januar Jan_Fevraglh Fev_Març Mar_Avrïu Avr_Mai Mai_Gün Gün_Julia Jul_Guscht Gus_Setemvar Set_Listopäts Lis_Noemvar Noe_Zecemvar Zec'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'Súladi Súl Sú_Lúneçi Lún Lú_Maitzi Mai Ma_Márcuri Már Má_Xhúadi Xhú Xh_Viénerçi Vié Vi_Sáturi Sát Sá'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'viensas secunds', '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  '\\'n míut',      '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  '\\'n míut',      '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 míuts',     '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 míuts',    '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  '\\'n þora',       '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  '\\'n þora',       '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 þoras',       '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 þoras',       '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 þoras',      '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  '\\'n ziua',         '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  '\\'n ziua',         '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 ziuas',        '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   '\\'n ziua',         '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 ziuas',        '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 ziuas',       '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  '\\'n mes',       '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  '\\'n mes',       '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  '\\'n mes',       '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 mesen',      '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 mesen',      '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 mesen',      '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   '\\'n mes',       '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 mesen',      '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), '\\'n ar',        '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 ars',       '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   '\\'n ar',        '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 ars',       '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'osprei viensas secunds',  'prefix');\n    assert.equal(moment(0).from(30000), 'ja\\'iensas secunds', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'ja\\'iensas secunds',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'osprei viensas secunds', 'in a few seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), 'osprei 5 ziuas', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'oxhi à 12.00',      'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'oxhi à 12.25',      'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'oxhi à 13.00',      'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'demà à 12.00',      'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'oxhi à 11.00',      'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'ieiri à 12.00',     'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('dddd [à] LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd [à] LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd [à] LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('[sür el] dddd [lasteu à] LT'),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[sür el] dddd [lasteu à] LT'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[sür el] dddd [lasteu à] LT'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\n// Monday is the first day of the week.\n// The week that contains Jan 4th is the first week of the year.\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2012, 0,  1]).format('w ww wo'), '52 52 52.', 'Jan  1 2012 should be week 52');\n    assert.equal(moment([2012, 0,  2]).format('w ww wo'),   '1 01 1.', 'Jan  2 2012 should be week 1');\n    assert.equal(moment([2012, 0,  8]).format('w ww wo'),   '1 01 1.', 'Jan  8 2012 should be week 1');\n    assert.equal(moment([2012, 0,  9]).format('w ww wo'),   '2 02 2.', 'Jan  9 2012 should be week 2');\n    assert.equal(moment([2012, 0, 15]).format('w ww wo'),   '2 02 2.', 'Jan 15 2012 should be week 2');\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\n\n\nfunction localeModule (name, lifecycle) {\n    QUnit.module('locale:' + name, {\n        setup : function () {\n            moment.locale(name);\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            moment.locale('en');\n            teardownDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n    defineCommonLocaleTests(name, -1, -1);\n}\n\nlocaleModule('tzm-latn');\n\ntest('parse', function (assert) {\n    var tests = 'innayr innayr_brˤayrˤ brˤayrˤ_marˤsˤ marˤsˤ_ibrir ibrir_mayyw mayyw_ywnyw ywnyw_ywlywz ywlywz_ɣwšt ɣwšt_šwtanbir šwtanbir_ktˤwbrˤ ktˤwbrˤ_nwwanbir nwwanbir_dwjnbir dwjnbir'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, MMMM Do YYYY, h:mm:ss a',      'asamas, brˤayrˤ 14 2010, 3:25:50 pm'],\n            ['ddd, hA',                            'asamas, 3PM'],\n            ['M Mo MM MMMM MMM',                   '2 2 02 brˤayrˤ brˤayrˤ'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14 14'],\n            ['d do dddd ddd dd',                   '0 0 asamas asamas asamas'],\n            ['DDD DDDo DDDD',                      '45 45 045'],\n            ['w wo ww',                            '8 8 08'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'pm PM'],\n            ['[the] DDDo [day of the year]',       'the 45 day of the year'],\n            ['LTS',                                '15:25:50'],\n            ['L',                                  '14/02/2010'],\n            ['LL',                                 '14 brˤayrˤ 2010'],\n            ['LLL',                                '14 brˤayrˤ 2010 15:25'],\n            ['LLLL',                               'asamas 14 brˤayrˤ 2010 15:25'],\n            ['l',                                  '14/2/2010'],\n            ['ll',                                 '14 brˤayrˤ 2010'],\n            ['lll',                                '14 brˤayrˤ 2010 15:25'],\n            ['llll',                               'asamas 14 brˤayrˤ 2010 15:25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1', '1');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2', '2');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3', '3');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4', '4');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5', '5');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6', '6');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7', '7');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8', '8');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9', '9');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10', '10');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11', '11');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12', '12');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13', '13');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14', '14');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15', '15');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16', '16');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17', '17');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18', '18');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19', '19');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20', '20');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21', '21');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22', '22');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23', '23');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24', '24');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25', '25');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26', '26');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27', '27');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28', '28');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29', '29');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30', '30');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31', '31');\n});\n\ntest('format month', function (assert) {\n    var expected = 'innayr innayr_brˤayrˤ brˤayrˤ_marˤsˤ marˤsˤ_ibrir ibrir_mayyw mayyw_ywnyw ywnyw_ywlywz ywlywz_ɣwšt ɣwšt_šwtanbir šwtanbir_ktˤwbrˤ ktˤwbrˤ_nwwanbir nwwanbir_dwjnbir dwjnbir'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'asamas asamas asamas_aynas aynas aynas_asinas asinas asinas_akras akras akras_akwas akwas akwas_asimwas asimwas asimwas_asiḍyas asiḍyas asiḍyas'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'imik', '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'minuḍ',      '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'minuḍ',      '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 minuḍ',     '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 minuḍ',    '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'saɛa',       '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'saɛa',       '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 tassaɛin',       '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 tassaɛin',       '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 tassaɛin',      '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'ass',         '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'ass',         '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 ossan',        '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'ass',         '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 ossan',        '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 ossan',       '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'ayowr',       '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'ayowr',       '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'ayowr',       '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 iyyirn',      '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 iyyirn',      '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 iyyirn',      '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'ayowr',       '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 iyyirn',      '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'asgas',        '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 isgasn',       '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'asgas',        '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 isgasn',       '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'dadkh s yan imik',  'prefix');\n    assert.equal(moment(0).from(30000), 'yan imik', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'yan imik',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'dadkh s yan imik', 'in a few seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), 'dadkh s yan 5 ossan', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'asdkh g 12:00',   'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'asdkh g 12:25',   'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'asdkh g 13:00',   'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'aska g 12:00',    'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'asdkh g 11:00',   'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'assant g 12:00',  'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('dddd [g] LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd [g] LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd [g] LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('dddd [g] LT'),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd [g] LT'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd [g] LT'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2011, 11, 31]).format('w ww wo'), '1 01 1', 'Dec 31 2011 should be week 1');\n    assert.equal(moment([2012,  0,  6]).format('w ww wo'), '1 01 1', 'Jan  6 2012 should be week 1');\n    assert.equal(moment([2012,  0,  7]).format('w ww wo'), '2 02 2', 'Jan  7 2012 should be week 2');\n    assert.equal(moment([2012,  0, 13]).format('w ww wo'), '2 02 2', 'Jan 13 2012 should be week 2');\n    assert.equal(moment([2012,  0, 14]).format('w ww wo'), '3 03 3', 'Jan 14 2012 should be week 3');\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\n\n\nfunction localeModule (name, lifecycle) {\n    QUnit.module('locale:' + name, {\n        setup : function () {\n            moment.locale(name);\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            moment.locale('en');\n            teardownDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n    defineCommonLocaleTests(name, -1, -1);\n}\n\nlocaleModule('tzm');\n\ntest('parse', function (assert) {\n    var tests = 'ⵉⵏⵏⴰⵢⵔ ⵉⵏⵏⴰⵢⵔ_ⴱⵕⴰⵢⵕ ⴱⵕⴰⵢⵕ_ⵎⴰⵕⵚ ⵎⴰⵕⵚ_ⵉⴱⵔⵉⵔ ⵉⴱⵔⵉⵔ_ⵎⴰⵢⵢⵓ ⵎⴰⵢⵢⵓ_ⵢⵓⵏⵢⵓ ⵢⵓⵏⵢⵓ_ⵢⵓⵍⵢⵓⵣ ⵢⵓⵍⵢⵓⵣ_ⵖⵓⵛⵜ ⵖⵓⵛⵜ_ⵛⵓⵜⴰⵏⴱⵉⵔ ⵛⵓⵜⴰⵏⴱⵉⵔ_ⴽⵟⵓⴱⵕ ⴽⵟⵓⴱⵕ_ⵏⵓⵡⴰⵏⴱⵉⵔ ⵏⵓⵡⴰⵏⴱⵉⵔ_ⴷⵓⵊⵏⴱⵉⵔ ⴷⵓⵊⵏⴱⵉⵔ'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, MMMM Do YYYY, h:mm:ss a',      'ⴰⵙⴰⵎⴰⵙ, ⴱⵕⴰⵢⵕ 14 2010, 3:25:50 pm'],\n            ['ddd, hA',                            'ⴰⵙⴰⵎⴰⵙ, 3PM'],\n            ['M Mo MM MMMM MMM',                   '2 2 02 ⴱⵕⴰⵢⵕ ⴱⵕⴰⵢⵕ'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14 14'],\n            ['d do dddd ddd dd',                   '0 0 ⴰⵙⴰⵎⴰⵙ ⴰⵙⴰⵎⴰⵙ ⴰⵙⴰⵎⴰⵙ'],\n            ['DDD DDDo DDDD',                      '45 45 045'],\n            ['w wo ww',                            '8 8 08'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'pm PM'],\n            ['[the] DDDo [day of the year]',       'the 45 day of the year'],\n            ['LTS',                                '15:25:50'],\n            ['L',                                  '14/02/2010'],\n            ['LL',                                 '14 ⴱⵕⴰⵢⵕ 2010'],\n            ['LLL',                                '14 ⴱⵕⴰⵢⵕ 2010 15:25'],\n            ['LLLL',                               'ⴰⵙⴰⵎⴰⵙ 14 ⴱⵕⴰⵢⵕ 2010 15:25'],\n            ['l',                                  '14/2/2010'],\n            ['ll',                                 '14 ⴱⵕⴰⵢⵕ 2010'],\n            ['lll',                                '14 ⴱⵕⴰⵢⵕ 2010 15:25'],\n            ['llll',                               'ⴰⵙⴰⵎⴰⵙ 14 ⴱⵕⴰⵢⵕ 2010 15:25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1', '1');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2', '2');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3', '3');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4', '4');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5', '5');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6', '6');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7', '7');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8', '8');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9', '9');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10', '10');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11', '11');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12', '12');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13', '13');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14', '14');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15', '15');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16', '16');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17', '17');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18', '18');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19', '19');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20', '20');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21', '21');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22', '22');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23', '23');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24', '24');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25', '25');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26', '26');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27', '27');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28', '28');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29', '29');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30', '30');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31', '31');\n});\n\ntest('format month', function (assert) {\n    var expected = 'ⵉⵏⵏⴰⵢⵔ ⵉⵏⵏⴰⵢⵔ_ⴱⵕⴰⵢⵕ ⴱⵕⴰⵢⵕ_ⵎⴰⵕⵚ ⵎⴰⵕⵚ_ⵉⴱⵔⵉⵔ ⵉⴱⵔⵉⵔ_ⵎⴰⵢⵢⵓ ⵎⴰⵢⵢⵓ_ⵢⵓⵏⵢⵓ ⵢⵓⵏⵢⵓ_ⵢⵓⵍⵢⵓⵣ ⵢⵓⵍⵢⵓⵣ_ⵖⵓⵛⵜ ⵖⵓⵛⵜ_ⵛⵓⵜⴰⵏⴱⵉⵔ ⵛⵓⵜⴰⵏⴱⵉⵔ_ⴽⵟⵓⴱⵕ ⴽⵟⵓⴱⵕ_ⵏⵓⵡⴰⵏⴱⵉⵔ ⵏⵓⵡⴰⵏⴱⵉⵔ_ⴷⵓⵊⵏⴱⵉⵔ ⴷⵓⵊⵏⴱⵉⵔ'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'ⴰⵙⴰⵎⴰⵙ ⴰⵙⴰⵎⴰⵙ ⴰⵙⴰⵎⴰⵙ_ⴰⵢⵏⴰⵙ ⴰⵢⵏⴰⵙ ⴰⵢⵏⴰⵙ_ⴰⵙⵉⵏⴰⵙ ⴰⵙⵉⵏⴰⵙ ⴰⵙⵉⵏⴰⵙ_ⴰⴽⵔⴰⵙ ⴰⴽⵔⴰⵙ ⴰⴽⵔⴰⵙ_ⴰⴽⵡⴰⵙ ⴰⴽⵡⴰⵙ ⴰⴽⵡⴰⵙ_ⴰⵙⵉⵎⵡⴰⵙ ⴰⵙⵉⵎⵡⴰⵙ ⴰⵙⵉⵎⵡⴰⵙ_ⴰⵙⵉⴹⵢⴰⵙ ⴰⵙⵉⴹⵢⴰⵙ ⴰⵙⵉⴹⵢⴰⵙ'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'ⵉⵎⵉⴽ', '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'ⵎⵉⵏⵓⴺ',      '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'ⵎⵉⵏⵓⴺ',      '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 ⵎⵉⵏⵓⴺ',     '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 ⵎⵉⵏⵓⴺ',    '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'ⵙⴰⵄⴰ',       '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'ⵙⴰⵄⴰ',       '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 ⵜⴰⵙⵙⴰⵄⵉⵏ',       '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 ⵜⴰⵙⵙⴰⵄⵉⵏ',       '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 ⵜⴰⵙⵙⴰⵄⵉⵏ',      '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'ⴰⵙⵙ',         '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'ⴰⵙⵙ',         '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 oⵙⵙⴰⵏ',        '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'ⴰⵙⵙ',         '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 oⵙⵙⴰⵏ',        '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 oⵙⵙⴰⵏ',       '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'ⴰⵢoⵓⵔ',       '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'ⴰⵢoⵓⵔ',       '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'ⴰⵢoⵓⵔ',       '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 ⵉⵢⵢⵉⵔⵏ',      '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 ⵉⵢⵢⵉⵔⵏ',      '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 ⵉⵢⵢⵉⵔⵏ',      '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'ⴰⵢoⵓⵔ',       '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 ⵉⵢⵢⵉⵔⵏ',      '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'ⴰⵙⴳⴰⵙ',        '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 ⵉⵙⴳⴰⵙⵏ',       '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'ⴰⵙⴳⴰⵙ',        '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 ⵉⵙⴳⴰⵙⵏ',       '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'ⴷⴰⴷⵅ ⵙ ⵢⴰⵏ ⵉⵎⵉⴽ',  'prefix');\n    assert.equal(moment(0).from(30000), 'ⵢⴰⵏ ⵉⵎⵉⴽ', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'ⵢⴰⵏ ⵉⵎⵉⴽ',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'ⴷⴰⴷⵅ ⵙ ⵢⴰⵏ ⵉⵎⵉⴽ', 'in a few seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), 'ⴷⴰⴷⵅ ⵙ ⵢⴰⵏ 5 oⵙⵙⴰⵏ', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'ⴰⵙⴷⵅ ⴴ 12:00',  'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'ⴰⵙⴷⵅ ⴴ 12:25',  'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'ⴰⵙⴷⵅ ⴴ 13:00',  'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'ⴰⵙⴽⴰ ⴴ 12:00',  'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'ⴰⵙⴷⵅ ⴴ 11:00',  'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'ⴰⵚⴰⵏⵜ ⴴ 12:00',  'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('dddd [ⴴ] LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd [ⴴ] LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd [ⴴ] LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('dddd [ⴴ] LT'),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd [ⴴ] LT'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd [ⴴ] LT'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2011, 11, 31]).format('w ww wo'), '1 01 1', 'Dec 31 2011 should be week 1');\n    assert.equal(moment([2012,  0,  6]).format('w ww wo'), '1 01 1', 'Jan  6 2012 should be week 1');\n    assert.equal(moment([2012,  0,  7]).format('w ww wo'), '2 02 2', 'Jan  7 2012 should be week 2');\n    assert.equal(moment([2012,  0, 13]).format('w ww wo'), '2 02 2', 'Jan 13 2012 should be week 2');\n    assert.equal(moment([2012,  0, 14]).format('w ww wo'), '3 03 3', 'Jan 14 2012 should be week 3');\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\n\n\nfunction localeModule (name, lifecycle) {\n    QUnit.module('locale:' + name, {\n        setup : function () {\n            moment.locale(name);\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            moment.locale('en');\n            teardownDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n    defineCommonLocaleTests(name, -1, -1);\n}\n\nlocaleModule('uk');\n\ntest('parse', function (assert) {\n    var tests = 'січень січ_лютий лют_березень бер_квітень квіт_травень трав_червень черв_липень лип_серпень серп_вересень вер_жовтень жовт_листопад лист_грудень груд'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, Do MMMM YYYY, HH:mm:ss',       'неділя, 14-го лютого 2010, 15:25:50'],\n            ['ddd, h A',                           'нд, 3 дня'],\n            ['M Mo MM MMMM MMM',                   '2 2-й 02 лютий лют'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14-го 14'],\n            ['d do dddd ddd dd',                   '0 0-й неділя нд нд'],\n            ['DDD DDDo DDDD',                      '45 45-й 045'],\n            ['w wo ww',                            '7 7-й 07'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'дня дня'],\n            ['DDDo [день року]',                  '45-й день року'],\n            ['LTS',                                '15:25:50'],\n            ['L',                                  '14.02.2010'],\n            ['LL',                                 '14 лютого 2010 р.'],\n            ['LLL',                                '14 лютого 2010 р., 15:25'],\n            ['LLLL',                               'неділя, 14 лютого 2010 р., 15:25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format meridiem', function (assert) {\n    assert.equal(moment([2012, 11, 28, 0, 0]).format('A'), 'ночі', 'night');\n    assert.equal(moment([2012, 11, 28, 3, 59]).format('A'), 'ночі', 'night');\n    assert.equal(moment([2012, 11, 28, 4, 0]).format('A'), 'ранку', 'morning');\n    assert.equal(moment([2012, 11, 28, 11, 59]).format('A'), 'ранку', 'morning');\n    assert.equal(moment([2012, 11, 28, 12, 0]).format('A'), 'дня', 'afternoon');\n    assert.equal(moment([2012, 11, 28, 16, 59]).format('A'), 'дня', 'afternoon');\n    assert.equal(moment([2012, 11, 28, 17, 0]).format('A'), 'вечора', 'evening');\n    assert.equal(moment([2012, 11, 28, 23, 59]).format('A'), 'вечора', 'evening');\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1-й', '1-й');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2-й', '2-й');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3-й', '3-й');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4-й', '4-й');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5-й', '5-й');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6-й', '6-й');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7-й', '7-й');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8-й', '8-й');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9-й', '9-й');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10-й', '10-й');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11-й', '11-й');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12-й', '12-й');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13-й', '13-й');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14-й', '14-й');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15-й', '15-й');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16-й', '16-й');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17-й', '17-й');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18-й', '18-й');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19-й', '19-й');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20-й', '20-й');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21-й', '21-й');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22-й', '22-й');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23-й', '23-й');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24-й', '24-й');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25-й', '25-й');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26-й', '26-й');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27-й', '27-й');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28-й', '28-й');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29-й', '29-й');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30-й', '30-й');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31-й', '31-й');\n});\n\ntest('format month', function (assert) {\n    var expected = 'січень січ_лютий лют_березень бер_квітень квіт_травень трав_червень черв_липень лип_серпень серп_вересень вер_жовтень жовт_листопад лист_грудень груд'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format month case', function (assert) {\n    var months = {\n        'nominative': 'січень_лютий_березень_квітень_травень_червень_липень_серпень_вересень_жовтень_листопад_грудень'.split('_'),\n        'accusative': 'січня_лютого_березня_квітня_травня_червня_липня_серпня_вересня_жовтня_листопада_грудня'.split('_')\n    }, i;\n    for (i = 0; i < 12; i++) {\n        assert.equal(moment([2011, i, 1]).format('D MMMM'), '1 ' + months.accusative[i], '1 ' + months.accusative[i]);\n        assert.equal(moment([2011, i, 1]).format('MMMM'), months.nominative[i], '1 ' + months.nominative[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'неділя нд нд_понеділок пн пн_вівторок вт вт_середа ср ср_четвер чт чт_п’ятниця пт пт_субота сб сб'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'декілька секунд',    '44 seconds = seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'хвилина',   '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'хвилина',   '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 хвилини',  '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 хвилини', '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'годину',    '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'годину',    '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 години',    '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 годин',    '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 година',   '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'день',      '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'день',      '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 дні',     '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'день',      '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 днів',     '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 11}), true),  '11 днів',     '11 days = 11 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 21}), true),  '21 день',     '21 days = 21 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 днів',    '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'місяць',    '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'місяць',    '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'місяць',    '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 місяці',   '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 місяці',   '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 місяці',   '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'місяць',    '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 місяців',   '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'рік',     '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 роки',    '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'рік',     '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 років',    '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'за декілька секунд', 'prefix');\n    assert.equal(moment(0).from(30000), 'декілька секунд тому', 'suffix');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'за декілька секунд', 'in seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), 'за 5 днів', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'Сьогодні о 12:00',   'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'Сьогодні о 12:25',   'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'Сьогодні о 13:00',   'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'Завтра о 12:00',     'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 2}).calendar(),  'Сьогодні о 10:00',   'Now minus 2 hours');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'Вчора о 12:00',      'yesterday at the same time');\n    // A special case for Ukrainian since 11 hours have different preposition\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'Сьогодні об 11:00',  'same day at 11 o\\'clock');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('[У] dddd [о' + (m.hours() === 11 ? 'б' : '') + '] LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[У] dddd [о] LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[У] dddd [о] LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n\n    function makeFormat(d) {\n        switch (d.day()) {\n            case 0:\n            case 3:\n            case 5:\n            case 6:\n                return '[Минулої] dddd [о' + (d.hours() === 11 ? 'б' : '') + '] LT';\n            case 1:\n            case 2:\n            case 4:\n                return '[Минулого] dddd [о' + (d.hours() === 11 ? 'б' : '') + '] LT';\n        }\n    }\n\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format(makeFormat(m)),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format(makeFormat(m)),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format(makeFormat(m)),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2011, 11, 26]).format('w ww wo'), '1 01 1-й', 'Dec 26 2011 should be week 1');\n    assert.equal(moment([2012,  0,  1]).format('w ww wo'), '1 01 1-й', 'Jan  1 2012 should be week 1');\n    assert.equal(moment([2012,  0,  2]).format('w ww wo'), '2 02 2-й', 'Jan  2 2012 should be week 2');\n    assert.equal(moment([2012,  0,  8]).format('w ww wo'), '2 02 2-й', 'Jan  8 2012 should be week 2');\n    assert.equal(moment([2012,  0,  9]).format('w ww wo'), '3 03 3-й', 'Jan  9 2012 should be week 3');\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\n\n\nfunction localeModule (name, lifecycle) {\n    QUnit.module('locale:' + name, {\n        setup : function () {\n            moment.locale(name);\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            moment.locale('en');\n            teardownDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n    defineCommonLocaleTests(name, -1, -1);\n}\n\nlocaleModule('ur');\n\nvar months = [\n    'جنوری',\n    'فروری',\n    'مارچ',\n    'اپریل',\n    'مئی',\n    'جون',\n    'جولائی',\n    'اگست',\n    'ستمبر',\n    'اکتوبر',\n    'نومبر',\n    'دسمبر'\n];\nvar days = [\n    'اتوار',\n    'پیر',\n    'منگل',\n    'بدھ',\n    'جمعرات',\n    'جمعہ',\n    'ہفتہ'\n];\n\ntest('parse', function (assert) {\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (var i = 0; i < 12; i++) {\n        equalTest(months[i], 'MMM', i);\n        equalTest(months[i], 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, MMMM Do YYYY, h:mm:ss a',      'اتوار، فروری 14 2010، 3:25:50 شام'],\n            ['ddd, hA',                            'اتوار، 3شام'],\n            ['M Mo MM MMMM MMM',                   '2 2 02 فروری فروری'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14 14'],\n            ['d do dddd ddd dd',                   '0 0 اتوار اتوار اتوار'],\n            ['DDD DDDo DDDD',                      '45 45 045'],\n            ['w wo ww',                            '6 6 06'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'شام شام'],\n            ['[سال کا] DDDo[واں دن]',       'سال کا 45واں دن'],\n            ['LTS',                                '15:25:50'],\n            ['L',                                  '14/02/2010'],\n            ['LL',                                 '14 فروری 2010'],\n            ['LLL',                                '14 فروری 2010 15:25'],\n            ['LLLL',                               'اتوار، 14 فروری 2010 15:25'],\n            ['l',                                  '14/2/2010'],\n            ['ll',                                 '14 فروری 2010'],\n            ['lll',                                '14 فروری 2010 15:25'],\n            ['llll',                               'اتوار، 14 فروری 2010 15:25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1', '1');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2', '2');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3', '3');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4', '4');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5', '5');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6', '6');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7', '7');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8', '8');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9', '9');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10', '10');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11', '11');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12', '12');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13', '13');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14', '14');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15', '15');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16', '16');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17', '17');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18', '18');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19', '19');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20', '20');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21', '21');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22', '22');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23', '23');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24', '24');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25', '25');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26', '26');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27', '27');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28', '28');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29', '29');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30', '30');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31', '31');\n});\n\ntest('format month', function (assert) {\n    for (var i = 0; i < months.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), months[i] + ' ' + months[i], months[i] + ' ' + months[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    for (var i = 0; i < days.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), days[i] + ' ' + days[i] + ' ' + days[i], days[i] + ' ' + days[i] + ' ' + days[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'چند سیکنڈ', '44 seconds = چند سیکنڈ');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'ایک منٹ',      '45 seconds = ایک منٹ');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'ایک منٹ',      '89 seconds = ایک منٹ');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 منٹ',     '90 seconds = 2 منٹ');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 منٹ',    '44 minutes = 44 منٹ');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'ایک گھنٹہ',       '45 minutes = ایک گھنٹہ');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'ایک گھنٹہ',       '89 minutes = ایک گھنٹہ');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 گھنٹے',       '90 minutes = 2 گھنٹے');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 گھنٹے',       '5 hours = 5 گھنٹے');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 گھنٹے',      '21 hours = 21 گھنٹے');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'ایک دن',         '22 hours = ایک دن');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'ایک دن',         '35 hours = ایک دن');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 دن',        '36 hours = 2 دن');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'ایک دن',         '1 day = ایک دن');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 دن',        '5 days = 5 دن');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 دن',       '25 days = 25 دن');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'ایک ماہ',       '26 days = ایک ماہ');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'ایک ماہ',       '30 days = ایک ماہ');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'ایک ماہ',       '43 days = ایک ماہ');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 ماہ',      '46 days = 2 ماہ');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 ماہ',      '75 days = 2 ماہ');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 ماہ',      '76 days = 3 ماہ');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'ایک ماہ',       '1 month = ایک ماہ');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 ماہ',      '5 months = 5 ماہ');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'ایک سال',        '345 days = ایک سال');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 سال',       '548 days = 2 سال');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'ایک سال',        '1 year = ایک سال');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 سال',       '5 years = 5 سال');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'چند سیکنڈ بعد',  'prefix');\n    assert.equal(moment(0).from(30000), 'چند سیکنڈ قبل', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'چند سیکنڈ قبل',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'چند سیکنڈ بعد', 'in a few seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), '5 دن بعد', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'آج بوقت 12:00',      'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'آج بوقت 12:25',      'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'آج بوقت 13:00',      'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'کل بوقت 12:00',   'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'آج بوقت 11:00',      'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'گذشتہ روز بوقت 12:00',  'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('dddd [بوقت] LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd [بوقت] LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd [بوقت] LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('[گذشتہ] dddd [بوقت] LT'),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[گذشتہ] dddd [بوقت] LT'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[گذشتہ] dddd [بوقت] LT'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2012, 0,  1]).format('w ww wo'), '52 52 52', 'Jan  1 2012 should be week 52');\n    assert.equal(moment([2012, 0,  2]).format('w ww wo'),   '1 01 1', 'Jan  2 2012 should be week 1');\n    assert.equal(moment([2012, 0,  8]).format('w ww wo'),   '1 01 1', 'Jan  8 2012 should be week 1');\n    assert.equal(moment([2012, 0,  9]).format('w ww wo'),   '2 02 2', 'Jan  9 2012 should be week 2');\n    assert.equal(moment([2012, 0, 15]).format('w ww wo'),   '2 02 2', 'Jan 15 2012 should be week 2');\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\n\n\nfunction localeModule (name, lifecycle) {\n    QUnit.module('locale:' + name, {\n        setup : function () {\n            moment.locale(name);\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            moment.locale('en');\n            teardownDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n    defineCommonLocaleTests(name, -1, -1);\n}\n\nlocaleModule('uz-latn');\n\ntest('parse', function (assert) {\n    var tests = 'Yanvar Yan_Fevral Fev_Mart Mar_Aprel Apr_May May_Iyun Iyun_Iyul Iyul_Avgust Avg_Sentabr Sen_Oktabr Okt_Noyabr Noy_Dekabr Dek'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, Do-MMMM YYYY, h:mm:ss',        'Yakshanba, 14-Fevral 2010, 3:25:50'],\n            ['ddd, h:mm',                          'Yak, 3:25'],\n            ['M Mo MM MMMM MMM',                   '2 2 02 Fevral Fev'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14 14'],\n            ['d do dddd ddd dd',                   '0 0 Yakshanba Yak Ya'],\n            ['DDD DDDo DDDD',                      '45 45 045'],\n            ['w wo ww',                            '7 7 07'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'pm PM'],\n            ['[yilning] DDDo-[kuni]',             'yilning 45-kuni'],\n            ['LTS',                                '15:25:50'],\n            ['L',                                  '14/02/2010'],\n            ['LL',                                 '14 Fevral 2010'],\n            ['LLL',                                '14 Fevral 2010 15:25'],\n            ['LLLL',                               '14 Fevral 2010, Yakshanba 15:25'],\n            ['l',                                  '14/2/2010'],\n            ['ll',                                 '14 Fev 2010'],\n            ['lll',                                '14 Fev 2010 15:25'],\n            ['llll',                               '14 Fev 2010, Yak 15:25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2016, 0, 1]).format('DDDo'), '1', '1');\n    assert.equal(moment([2016, 0, 2]).format('DDDo'), '2', '2');\n    assert.equal(moment([2016, 0, 3]).format('DDDo'), '3', '3');\n    assert.equal(moment([2016, 0, 4]).format('DDDo'), '4', '4');\n    assert.equal(moment([2016, 0, 5]).format('DDDo'), '5', '5');\n    assert.equal(moment([2016, 0, 6]).format('DDDo'), '6', '6');\n    assert.equal(moment([2016, 0, 7]).format('DDDo'), '7', '7');\n    assert.equal(moment([2016, 0, 8]).format('DDDo'), '8', '8');\n    assert.equal(moment([2016, 0, 9]).format('DDDo'), '9', '9');\n    assert.equal(moment([2016, 0, 10]).format('DDDo'), '10', '10');\n\n    assert.equal(moment([2016, 0, 11]).format('DDDo'), '11', '11');\n    assert.equal(moment([2016, 0, 12]).format('DDDo'), '12', '12');\n    assert.equal(moment([2016, 0, 13]).format('DDDo'), '13', '13');\n    assert.equal(moment([2016, 0, 14]).format('DDDo'), '14', '14');\n    assert.equal(moment([2016, 0, 15]).format('DDDo'), '15', '15');\n    assert.equal(moment([2016, 0, 16]).format('DDDo'), '16', '16');\n    assert.equal(moment([2016, 0, 17]).format('DDDo'), '17', '17');\n    assert.equal(moment([2016, 0, 18]).format('DDDo'), '18', '18');\n    assert.equal(moment([2016, 0, 19]).format('DDDo'), '19', '19');\n    assert.equal(moment([2016, 0, 20]).format('DDDo'), '20', '20');\n\n    assert.equal(moment([2016, 0, 21]).format('DDDo'), '21', '21');\n    assert.equal(moment([2016, 0, 22]).format('DDDo'), '22', '22');\n    assert.equal(moment([2016, 0, 23]).format('DDDo'), '23', '23');\n    assert.equal(moment([2016, 0, 24]).format('DDDo'), '24', '24');\n    assert.equal(moment([2016, 0, 25]).format('DDDo'), '25', '25');\n    assert.equal(moment([2016, 0, 26]).format('DDDo'), '26', '26');\n    assert.equal(moment([2016, 0, 27]).format('DDDo'), '27', '27');\n    assert.equal(moment([2016, 0, 28]).format('DDDo'), '28', '28');\n    assert.equal(moment([2016, 0, 29]).format('DDDo'), '29', '29');\n    assert.equal(moment([2016, 0, 30]).format('DDDo'), '30', '30');\n\n    assert.equal(moment([2016, 0, 31]).format('DDDo'), '31', '31');\n});\n\ntest('format month', function (assert) {\n    var expected = 'Yanvar Yan_Fevral Fev_Mart Mar_Aprel Apr_May May_Iyun Iyun_Iyul Iyul_Avgust Avg_Sentabr Sen_Oktabr Okt_Noyabr Noy_Dekabr Dek'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2016, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'Yakshanba Yak Ya_Dushanba Dush Du_Seshanba Sesh Se_Chorshanba Chor Cho_Payshanba Pay Pa_Juma Jum Ju_Shanba Shan Sha'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2016, 0, 3 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2017, 1, 28]);\n    assert.equal(start.from(moment([2017, 1, 28]).add({s: 44}), true),  'soniya', '44 soniya = soniya');\n    assert.equal(start.from(moment([2017, 1, 28]).add({s: 45}), true),  'bir daqiqa',      '45 soniya = bir daqiqa');\n    assert.equal(start.from(moment([2017, 1, 28]).add({s: 89}), true),  'bir daqiqa',      '89 soniya = bir daqiqa');\n    assert.equal(start.from(moment([2017, 1, 28]).add({s: 90}), true),  '2 daqiqa',     '90 soniya = 2 daqiqa');\n    assert.equal(start.from(moment([2017, 1, 28]).add({m: 44}), true),  '44 daqiqa',    '44 daqiqa = 44 daqiqa');\n    assert.equal(start.from(moment([2017, 1, 28]).add({m: 45}), true),  'bir soat',       '45 minut = bir soat');\n    assert.equal(start.from(moment([2017, 1, 28]).add({m: 89}), true),  'bir soat',       '89 minut = bir soat');\n    assert.equal(start.from(moment([2017, 1, 28]).add({m: 90}), true),  '2 soat',       '90 minut = 2 soat');\n    assert.equal(start.from(moment([2017, 1, 28]).add({h: 5}), true),   '5 soat',       '5 soat = 5 soat');\n    assert.equal(start.from(moment([2017, 1, 28]).add({h: 21}), true),  '21 soat',      '21 soat = 21 soat');\n    assert.equal(start.from(moment([2017, 1, 28]).add({h: 22}), true),  'bir kun',         '22 soat = bir kun');\n    assert.equal(start.from(moment([2017, 1, 28]).add({h: 35}), true),  'bir kun',         '35 soat = bir kun');\n    assert.equal(start.from(moment([2017, 1, 28]).add({h: 36}), true),  '2 kun',        '36 soat = 2 kun');\n    assert.equal(start.from(moment([2017, 1, 28]).add({d: 1}), true),   'bir kun',         '1 kun = 1 kun');\n    assert.equal(start.from(moment([2017, 1, 28]).add({d: 5}), true),   '5 kun',        '5 kun = 5 kun');\n    assert.equal(start.from(moment([2017, 1, 28]).add({d: 25}), true),  '25 kun',       '25 kun = 25 kun');\n    assert.equal(start.from(moment([2017, 1, 28]).add({d: 26}), true),  'bir oy',       '26 kun = bir oy');\n    assert.equal(start.from(moment([2017, 1, 28]).add({d: 30}), true),  'bir oy',       '30 kun = bir oy');\n    assert.equal(start.from(moment([2017, 1, 28]).add({d: 43}), true),  'bir oy',       '45 kun = bir oy');\n    assert.equal(start.from(moment([2017, 1, 28]).add({d: 46}), true),  '2 oy',      '46 kun = 2 oy');\n    assert.equal(start.from(moment([2017, 1, 28]).add({d: 74}), true),  '2 oy',      '75 kun = 2 oy');\n    assert.equal(start.from(moment([2017, 1, 28]).add({d: 76}), true),  '3 oy',      '76 kun = 3 oy');\n    assert.equal(start.from(moment([2017, 1, 28]).add({M: 1}), true),   'bir oy',       'bir oy = bir oy');\n    assert.equal(start.from(moment([2017, 1, 28]).add({M: 5}), true),   '5 oy',      '5 oy = 5 oy');\n    assert.equal(start.from(moment([2017, 1, 28]).add({d: 345}), true), 'bir yil',        '345 kun = bir yil');\n    assert.equal(start.from(moment([2017, 1, 28]).add({d: 548}), true), '2 yil',       '548 kun = 2 yil');\n    assert.equal(start.from(moment([2017, 1, 28]).add({y: 1}), true),   'bir yil',        '1 yil = bir yil');\n    assert.equal(start.from(moment([2017, 1, 28]).add({y: 5}), true),   '5 yil',       '5 yil = 5 yil');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'Yaqin soniya ichida',  'prefix');\n    assert.equal(moment(0).from(30000), 'Bir necha soniya oldin', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'Bir necha soniya oldin',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'Yaqin soniya ichida', 'in a few seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), 'Yaqin 5 kun ichida', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'Bugun soat 12:00 da',  'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'Bugun soat 12:25 da',  'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'Bugun soat 13:00 da',  'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'Ertaga 12:00 da',      'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'Bugun soat 11:00 da',  'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'Kecha soat 12:00 da',   'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('dddd [kuni soat] LT [da]'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd [kuni soat] LT [da]'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd [kuni soat] LT [da]'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('[O\\'tgan] dddd [kuni soat] LT [da]'),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[O\\'tgan] dddd [kuni soat] LT [da]'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[O\\'tgan] dddd [kuni soat] LT [da]'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2012, 0,  1]).format('w ww wo'), '1 01 1', 'Jan  1 2012 should be week 52');\n    assert.equal(moment([2012, 0,  2]).format('w ww wo'),   '2 02 2', 'Jan  2 2012 should be week 1');\n    assert.equal(moment([2012, 0,  8]).format('w ww wo'),   '2 02 2', 'Jan  8 2012 should be week 1');\n    assert.equal(moment([2012, 0,  9]).format('w ww wo'),   '3 03 3', 'Jan  9 2012 should be week 2');\n    assert.equal(moment([2012, 0, 15]).format('w ww wo'),   '3 03 3', 'Jan 15 2012 should be week 2');\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\n\n\nfunction localeModule (name, lifecycle) {\n    QUnit.module('locale:' + name, {\n        setup : function () {\n            moment.locale(name);\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            moment.locale('en');\n            teardownDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n    defineCommonLocaleTests(name, -1, -1);\n}\n\nlocaleModule('uz');\n\ntest('parse', function (assert) {\n    var tests = 'январ янв_феврал фев_март мар_апрел апр_май май_июн июн_июл июл_август авг_сентябр сен_октябр окт_ноябр ноя_декабр дек'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, Do-MMMM YYYY, h:mm:ss',        'Якшанба, 14-феврал 2010, 3:25:50'],\n            ['ddd, h:mm',                          'Якш, 3:25'],\n            ['M Mo MM MMMM MMM',                   '2 2 02 феврал фев'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14 14'],\n            ['d do dddd ddd dd',                   '0 0 Якшанба Якш Як'],\n            ['DDD DDDo DDDD',                      '45 45 045'],\n            ['w wo ww',                            '7 7 07'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'pm PM'],\n            ['[йилнинг] DDDo-[куни]',             'йилнинг 45-куни'],\n            ['LTS',                                '15:25:50'],\n            ['L',                                  '14/02/2010'],\n            ['LL',                                 '14 феврал 2010'],\n            ['LLL',                                '14 феврал 2010 15:25'],\n            ['LLLL',                               '14 феврал 2010, Якшанба 15:25'],\n            ['l',                                  '14/2/2010'],\n            ['ll',                                 '14 фев 2010'],\n            ['lll',                                '14 фев 2010 15:25'],\n            ['llll',                               '14 фев 2010, Якш 15:25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1', '1');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2', '2');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3', '3');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4', '4');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5', '5');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6', '6');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7', '7');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8', '8');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9', '9');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10', '10');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11', '11');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12', '12');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13', '13');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14', '14');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15', '15');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16', '16');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17', '17');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18', '18');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19', '19');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20', '20');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21', '21');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22', '22');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23', '23');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24', '24');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25', '25');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26', '26');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27', '27');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28', '28');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29', '29');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30', '30');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31', '31');\n});\n\ntest('format month', function (assert) {\n    var expected = 'январ янв_феврал фев_март мар_апрел апр_май май_июн июн_июл июл_август авг_сентябр сен_октябр окт_ноябр ноя_декабр дек'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'Якшанба Якш Як_Душанба Душ Ду_Сешанба Сеш Се_Чоршанба Чор Чо_Пайшанба Пай Па_Жума Жум Жу_Шанба Шан Ша'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'фурсат', '44 секунд = фурсат');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'бир дакика',      '45 секунд = бир дакика');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'бир дакика',      '89 секунд = бир дакика');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 дакика',     '90 секунд = 2 дакика');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 дакика',    '44 дакика = 44 дакика');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'бир соат',       '45 минут = бир соат');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'бир соат',       '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 соат',       '90 минут = 2 соат');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 соат',       '5 соат = 5 соат');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 соат',      '21 соат = 21 соат');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'бир кун',         '22 соат = бир кун');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'бир кун',         '35 соат = бир кун');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 кун',        '36 соат = 2 кун');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'бир кун',         '1 кун = 1 кун');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 кун',        '5 кун = 5 кун');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 кун',       '25 кун = 25 кун');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'бир ой',       '26 кун = бир ой');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'бир ой',       '30 кун = бир ой');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'бир ой',       '45 кун = бир ой');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 ой',      '46 кун = 2 ой');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 ой',      '75 кун = 2 ой');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 ой',      '76 кун = 3 ой');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'бир ой',       'бир ой = бир ой');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 ой',      '5 ой = 5 ой');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'бир йил',        '345 кун = бир йил');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 йил',       '548 кун = 2 йил');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'бир йил',        '1 йил = бир йил');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 йил',       '5 йил = 5 йил');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'Якин фурсат ичида',  'prefix');\n    assert.equal(moment(0).from(30000), 'Бир неча фурсат олдин', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'Бир неча фурсат олдин',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'Якин фурсат ичида', 'in a few seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), 'Якин 5 кун ичида', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'Бугун соат 12:00 да',  'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'Бугун соат 12:25 да',  'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'Бугун соат 13:00 да',  'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'Эртага 12:00 да',      'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'Бугун соат 11:00 да',  'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'Кеча соат 12:00 да',   'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('dddd [куни соат] LT [да]'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd [куни соат] LT [да]'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd [куни соат] LT [да]'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('[Утган] dddd [куни соат] LT [да]'),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[Утган] dddd [куни соат] LT [да]'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[Утган] dddd [куни соат] LT [да]'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2012, 0,  1]).format('w ww wo'), '1 01 1', 'Jan  1 2012 should be week 52');\n    assert.equal(moment([2012, 0,  2]).format('w ww wo'),   '2 02 2', 'Jan  2 2012 should be week 1');\n    assert.equal(moment([2012, 0,  8]).format('w ww wo'),   '2 02 2', 'Jan  8 2012 should be week 1');\n    assert.equal(moment([2012, 0,  9]).format('w ww wo'),   '3 03 3', 'Jan  9 2012 should be week 2');\n    assert.equal(moment([2012, 0, 15]).format('w ww wo'),   '3 03 3', 'Jan 15 2012 should be week 2');\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\n\n\nfunction localeModule (name, lifecycle) {\n    QUnit.module('locale:' + name, {\n        setup : function () {\n            moment.locale(name);\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            moment.locale('en');\n            teardownDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n    defineCommonLocaleTests(name, -1, -1);\n}\n\nlocaleModule('vi');\n\ntest('parse', function (assert) {\n    var i,\n        tests = 'tháng 1,Th01_tháng 2,Th02_tháng 3,Th03_tháng 4,Th04_tháng 5,Th05_tháng 6,Th06_tháng 7,Th07_tháng 8,Th08_tháng 9,Th09_tháng 10,Th10_tháng 11,Th11_tháng 12,Th12'.split('_');\n\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + i);\n    }\n\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(',');\n        equalTest(tests[i][0], '[tháng] M', i);\n        equalTest(tests[i][1], '[Th]M', i);\n        equalTest(tests[i][0], '[tháng] MM', i);\n        equalTest(tests[i][1], '[Th]MM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), '[THÁNG] M', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), '[TH]M', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), '[THÁNG] MM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), '[TH]MM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, MMMM Do YYYY, h:mm:ss a',      'chủ nhật, tháng 2 14 2010, 3:25:50 ch'],\n            ['ddd, hA',                            'CN, 3CH'],\n            ['M Mo MM MMMM MMM',                   '2 2 02 tháng 2 Th02'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14 14'],\n            ['d do dddd ddd dd',                   '0 0 chủ nhật CN CN'],\n            ['DDD DDDo DDDD',                      '45 45 045'],\n            ['w wo ww',                            '6 6 06'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'ch CH'],\n            ['[ngày thứ] DDDo [của năm]',          'ngày thứ 45 của năm'],\n            ['LTS',                                '15:25:50'],\n            ['L',                                  '14/02/2010'],\n            ['LL',                                 '14 tháng 2 năm 2010'],\n            ['LLL',                                '14 tháng 2 năm 2010 15:25'],\n            ['LLLL',                               'chủ nhật, 14 tháng 2 năm 2010 15:25'],\n            ['l',                                  '14/2/2010'],\n            ['ll',                                 '14 Th02 2010'],\n            ['lll',                                '14 Th02 2010 15:25'],\n            ['llll',                               'CN, 14 Th02 2010 15:25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1', '1');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2', '2');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3', '3');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4', '4');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5', '5');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6', '6');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7', '7');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8', '8');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9', '9');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10', '10');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11', '11');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12', '12');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13', '13');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14', '14');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15', '15');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16', '16');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17', '17');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18', '18');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19', '19');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20', '20');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21', '21');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22', '22');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23', '23');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24', '24');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25', '25');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26', '26');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27', '27');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28', '28');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29', '29');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30', '30');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31', '31');\n});\n\ntest('format month', function (assert) {\n    var i,\n        expected = 'tháng 1,Th01_tháng 2,Th02_tháng 3,Th03_tháng 4,Th04_tháng 5,Th05_tháng 6,Th06_tháng 7,Th07_tháng 8,Th08_tháng 9,Th09_tháng 10,Th10_tháng 11,Th11_tháng 12,Th12'.split('_');\n\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM,MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var i,\n        expected = 'chủ nhật CN CN_thứ hai T2 T2_thứ ba T3 T3_thứ tư T4 T4_thứ năm T5 T5_thứ sáu T6 T6_thứ bảy T7 T7'.split('_');\n\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'vài giây', '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'một phút',      '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'một phút',      '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 phút',     '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 phút',    '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'một giờ',       '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'một giờ',       '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 giờ',       '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 giờ',       '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 giờ',      '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'một ngày',         '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'một ngày',         '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 ngày',        '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'một ngày',         '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 ngày',        '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 ngày',       '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'một tháng',       '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'một tháng',       '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'một tháng',       '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 tháng',      '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 tháng',      '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 tháng',      '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'một tháng',       '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 tháng',      '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'một năm',        '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 năm',       '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'một năm',        '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 năm',       '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'vài giây tới',  'prefix');\n    assert.equal(moment(0).from(30000), 'vài giây trước', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'vài giây trước',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'vài giây tới', 'in a few seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), '5 ngày tới', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'Hôm nay lúc 12:00',   'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'Hôm nay lúc 12:25',   'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'Hôm nay lúc 13:00',   'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'Ngày mai lúc 12:00',  'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'Hôm nay lúc 11:00',   'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'Hôm qua lúc 12:00',   'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('dddd [tuần tới lúc] LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd [tuần tới lúc] LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd [tuần tới lúc] LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('dddd [tuần rồi lúc] LT'),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd [tuần rồi lúc] LT'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd [tuần rồi lúc] LT'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2012, 0,  1]).format('w ww wo'), '52 52 52', 'Jan  1 2012 should be week 52');\n    assert.equal(moment([2012, 0,  2]).format('w ww wo'),   '1 01 1', 'Jan  2 2012 should be week 1');\n    assert.equal(moment([2012, 0,  8]).format('w ww wo'),   '1 01 1', 'Jan  8 2012 should be week 1');\n    assert.equal(moment([2012, 0,  9]).format('w ww wo'),   '2 02 2', 'Jan  9 2012 should be week 2');\n    assert.equal(moment([2012, 0, 15]).format('w ww wo'),   '2 02 2', 'Jan 15 2012 should be week 2');\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\n\n\nfunction localeModule (name, lifecycle) {\n    QUnit.module('locale:' + name, {\n        setup : function () {\n            moment.locale(name);\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            moment.locale('en');\n            teardownDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n    defineCommonLocaleTests(name, -1, -1);\n}\n\nlocaleModule('x-pseudo');\n\ntest('parse', function (assert) {\n    var tests = 'J~áñúá~rý J~áñ_F~ébrú~árý ~Féb_~Márc~h ~Már_Áp~ríl ~Ápr_~Máý ~Máý_~Júñé~ ~Júñ_Júl~ý ~Júl_Áú~gúst~ ~Áúg_Sép~témb~ér ~Sép_Ó~ctób~ér ~Óct_Ñ~óvém~bér ~Ñóv_~Décé~mbér ~Déc'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, MMMM Do YYYY, h:mm:ss a',      'S~úñdá~ý, F~ébrú~árý 14th 2010, 3:25:50 pm'],\n            ['ddd, hA',                            'S~úñ, 3PM'],\n            ['M Mo MM MMMM MMM',                   '2 2nd 02 F~ébrú~árý ~Féb'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14th 14'],\n            ['d do dddd ddd dd',                   '0 0th S~úñdá~ý S~úñ S~ú'],\n            ['DDD DDDo DDDD',                      '45 45th 045'],\n            ['w wo ww',                            '6 6th 06'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'pm PM'],\n            ['[the] DDDo [day of the year]',       'the 45th day of the year'],\n            ['LT',                                 '15:25'],\n            ['L',                                  '14/02/2010'],\n            ['LL',                                 '14 F~ébrú~árý 2010'],\n            ['LLL',                                '14 F~ébrú~árý 2010 15:25'],\n            ['LLLL',                               'S~úñdá~ý, 14 F~ébrú~árý 2010 15:25'],\n            ['l',                                  '14/2/2010'],\n            ['ll',                                 '14 ~Féb 2010'],\n            ['lll',                                '14 ~Féb 2010 15:25'],\n            ['llll',                               'S~úñ, 14 ~Féb 2010 15:25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1st', '1st');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2nd', '2nd');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3rd', '3rd');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4th', '4th');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5th', '5th');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6th', '6th');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7th', '7th');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8th', '8th');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9th', '9th');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10th', '10th');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11th', '11th');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12th', '12th');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13th', '13th');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14th', '14th');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15th', '15th');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16th', '16th');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17th', '17th');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18th', '18th');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19th', '19th');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20th', '20th');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21st', '21st');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22nd', '22nd');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23rd', '23rd');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24th', '24th');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25th', '25th');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26th', '26th');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27th', '27th');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28th', '28th');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29th', '29th');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30th', '30th');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31st', '31st');\n});\n\ntest('format month', function (assert) {\n    var expected = 'J~áñúá~rý J~áñ_F~ébrú~árý ~Féb_~Márc~h ~Már_Áp~ríl ~Ápr_~Máý ~Máý_~Júñé~ ~Júñ_Júl~ý ~Júl_Áú~gúst~ ~Áúg_Sép~témb~ér ~Sép_Ó~ctób~ér ~Óct_Ñ~óvém~bér ~Ñóv_~Décé~mbér ~Déc'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'S~úñdá~ý S~úñ S~ú_Mó~ñdáý~ ~Móñ Mó~_Túé~sdáý~ ~Túé Tú_Wéd~ñésd~áý ~Wéd ~Wé_T~húrs~dáý ~Thú T~h_~Fríd~áý ~Frí Fr~_S~átúr~dáý ~Sát Sá'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'á ~féw ~sécó~ñds', '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'á ~míñ~úté',      '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'á ~míñ~úté',      '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 m~íñú~tés',     '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 m~íñú~tés',    '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'á~ñ hó~úr',       '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'á~ñ hó~úr',       '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 h~óúrs',       '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 h~óúrs',       '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 h~óúrs',      '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'á ~dáý',         '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'á ~dáý',         '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 d~áýs',        '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'á ~dáý',         '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 d~áýs',        '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 d~áýs',       '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'á ~móñ~th',       '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'á ~móñ~th',       '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'á ~móñ~th',       '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 m~óñt~hs',      '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 m~óñt~hs',      '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 m~óñt~hs',      '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'á ~móñ~th',       '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 m~óñt~hs',      '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'á ~ýéár',        '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 ý~éárs',       '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'á ~ýéár',        '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 ý~éárs',       '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'í~ñ á ~féw ~sécó~ñds',  'prefix');\n    assert.equal(moment(0).from(30000), 'á ~féw ~sécó~ñds á~gó', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'á ~féw ~sécó~ñds á~gó',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'í~ñ á ~féw ~sécó~ñds', 'in a few seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), 'í~ñ 5 d~áýs', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(2).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                     'T~ódá~ý át 02:00',      'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'T~ódá~ý át 02:25',      'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'T~ódá~ý át 03:00',      'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'T~ómó~rró~w át 02:00',   'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'T~ódá~ý át 01:00',      'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'Ý~ést~érdá~ý át 02:00',  'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('dddd [át] LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd [át] LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd [át] LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('[L~ást] dddd [át] LT'),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[L~ást] dddd [át] LT'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[L~ást] dddd [át] LT'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2012, 0,  1]).format('w ww wo'), '52 52 52nd', 'Jan  1 2012 should be week 52');\n    assert.equal(moment([2012, 0,  2]).format('w ww wo'),   '1 01 1st', 'Jan  2 2012 should be week 1');\n    assert.equal(moment([2012, 0,  8]).format('w ww wo'),   '1 01 1st', 'Jan  8 2012 should be week 1');\n    assert.equal(moment([2012, 0,  9]).format('w ww wo'),   '2 02 2nd', 'Jan  9 2012 should be week 2');\n    assert.equal(moment([2012, 0, 15]).format('w ww wo'),   '2 02 2nd', 'Jan 15 2012 should be week 2');\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\n\n\nfunction localeModule (name, lifecycle) {\n    QUnit.module('locale:' + name, {\n        setup : function () {\n            moment.locale(name);\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            moment.locale('en');\n            teardownDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n    defineCommonLocaleTests(name, -1, -1);\n}\n\nlocaleModule('yo');\n\ntest('parse', function (assert) {\n    var tests = 'Sẹ́rẹ́ Sẹ́r_Èrèlè Èrl_Ẹrẹ̀nà Ẹrn_Ìgbé Ìgb_Èbibi Èbi_Òkùdu Òkù_Agẹmo Agẹ_Ògún Ògú_Owewe Owe_Ọ̀wàrà Ọ̀wà_Bélú Bél_Ọ̀pẹ̀̀ Ọ̀pẹ̀̀'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, MMMM Do YYYY, h:mm:ss a', 'Àìkú, Èrèlè ọjọ́ 14 2010, 3:25:50 pm'],\n            ['ddd, hA', 'Àìk, 3PM'],\n            ['M Mo MM MMMM MMM', '2 ọjọ́ 2 02 Èrèlè Èrl'],\n            ['YYYY YY', '2010 10'],\n            ['D Do DD', '14 ọjọ́ 14 14'],\n            ['d do dddd ddd dd', '0 ọjọ́ 0 Àìkú Àìk Àì'],\n            ['DDD DDDo DDDD', '45 ọjọ́ 45 045'],\n            ['w wo ww', '6 ọjọ́ 6 06'],\n            ['h hh', '3 03'],\n            ['H HH', '15 15'],\n            ['m mm', '25 25'],\n            ['s ss', '50 50'],\n            ['a A', 'pm PM'],\n            ['[the] DDDo [day of the year]', 'the ọjọ́ 45 day of the year'],\n            ['LTS', '3:25:50 PM'],\n            ['L', '14/02/2010'],\n            ['LL', '14 Èrèlè 2010'],\n            ['LLL', '14 Èrèlè 2010 3:25 PM'],\n            ['LLLL', 'Àìkú, 14 Èrèlè 2010 3:25 PM'],\n            ['l', '14/2/2010'],\n            ['ll', '14 Èrl 2010'],\n            ['lll', '14 Èrl 2010 3:25 PM'],\n            ['llll', 'Àìk, 14 Èrl 2010 3:25 PM']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), 'ọjọ́ 1', 'ọjọ́ 1');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), 'ọjọ́ 2', 'ọjọ́ 2');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), 'ọjọ́ 3', 'ọjọ́ 3');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), 'ọjọ́ 4', 'ọjọ́ 4');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), 'ọjọ́ 5', 'ọjọ́ 5');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), 'ọjọ́ 6', 'ọjọ́ 6');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), 'ọjọ́ 7', 'ọjọ́ 7');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), 'ọjọ́ 8', 'ọjọ́ 8');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), 'ọjọ́ 9', 'ọjọ́ 9');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), 'ọjọ́ 10', 'ọjọ́ 10');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), 'ọjọ́ 11', 'ọjọ́ 11');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), 'ọjọ́ 12', 'ọjọ́ 12');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), 'ọjọ́ 13', 'ọjọ́ 13');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), 'ọjọ́ 14', 'ọjọ́ 14');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), 'ọjọ́ 15', 'ọjọ́ 15');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), 'ọjọ́ 16', 'ọjọ́ 16');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), 'ọjọ́ 17', 'ọjọ́ 17');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), 'ọjọ́ 18', 'ọjọ́ 18');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), 'ọjọ́ 19', 'ọjọ́ 19');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), 'ọjọ́ 20', 'ọjọ́ 20');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), 'ọjọ́ 21', 'ọjọ́ 21');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), 'ọjọ́ 22', 'ọjọ́ 22');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), 'ọjọ́ 23', 'ọjọ́ 23');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), 'ọjọ́ 24', 'ọjọ́ 24');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), 'ọjọ́ 25', 'ọjọ́ 25');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), 'ọjọ́ 26', 'ọjọ́ 26');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), 'ọjọ́ 27', 'ọjọ́ 27');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), 'ọjọ́ 28', 'ọjọ́ 28');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), 'ọjọ́ 29', 'ọjọ́ 29');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), 'ọjọ́ 30', 'ọjọ́ 30');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), 'ọjọ́ 31', 'ọjọ́ 31');\n});\n\ntest('format month', function (assert) {\n    var expected = 'Sẹ́rẹ́ Sẹ́r_Èrèlè Èrl_Ẹrẹ̀nà Ẹrn_Ìgbé Ìgb_Èbibi Èbi_Òkùdu Òkù_Agẹmo Agẹ_Ògún Ògú_Owewe Owe_Ọ̀wàrà Ọ̀wà_Bélú Bél_Ọ̀pẹ̀̀ Ọ̀pẹ̀̀'.split('_'),\n        i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'Àìkú Àìk Àì_Ajé Ajé Aj_Ìsẹ́gun Ìsẹ́ Ìs_Ọjọ́rú Ọjr Ọr_Ọjọ́bọ Ọjb Ọb_Ẹtì Ẹtì Ẹt_Àbámẹ́ta Àbá Àb'.split('_'),\n        i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'ìsẹjú aayá die', '44 seconds = ìsẹjú aayá die');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'ìsẹjú kan',      '45 seconds = ìsẹjú kan');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'ìsẹjú kan',      '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  'ìsẹjú 2',        '90 seconds = ìsẹjú 2');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  'ìsẹjú 44',       'ìsẹjú 44 = ìsẹjú 44');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'wákati kan',     'ìsẹjú 45 = wákati kan');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'wákati kan',     'ìsẹjú 89 = wákati kan');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  'wákati 2',       'ìsẹjú 90 = wákati 2');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   'wákati 5',       'wákati 5 = wákati 5');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  'wákati 21',      'wákati 21 = wákati 21');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'ọjọ́ kan',        '22 wákati = ọjọ́ kan');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'ọjọ́ kan',        '35 wákati = ọjọ́ kan');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  'ọjọ́ 2',          'wákati 36 = ọjọ́ 2');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'ọjọ́ kan',        '1  = ọjọ́ kan');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   'ọjọ́ 5',          'ọjọ́ 5 = ọjọ́  5');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  'ọjọ́ 25',         'ọjọ́ 25 = ọjọ́ 25');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'osù kan',        'ọjọ́ 26 = osù kan');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'osù kan',        'ọjọ́ 30 = osù kan');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'osù kan',        'ọjọ́ 43 = osù kan');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  'osù 2',          'ọjọ́ 46 = osù 2');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  'osù 2',          'ọjọ́ 75 = osù 2');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  'osù 3',          'ọjọ́ 76 = osù 3');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'osù kan',        'osù 1 = osù kan');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   'osù 5',          'osù 5 = osù 5');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'ọdún kan',       'ọjọ 345 = ọdún kan');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), 'ọdún 2',         'ọjọ 548 = ọdún 2');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'ọdún kan',       'ọdún 1 = ọdún kan');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   'ọdún 5',         'ọdún 5 = ọdún 5');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'ní ìsẹjú aayá die', 'prefix');\n    assert.equal(moment(0).from(30000), 'ìsẹjú aayá die kọjá', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'ìsẹjú aayá die kọjá', 'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'ní ìsẹjú aayá die', 'ní ìsẹjú aayá die');\n    assert.equal(moment().add({d: 5}).fromNow(), 'ní ọjọ́ 5', 'ní ọjọ́ 5');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                     'Ònì ni 12:00 PM',   'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'Ònì ni 12:25 PM',   'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'Ònì ni 1:00 PM',    'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'Ọ̀la ni 12:00 PM',   'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'Ònì ni 11:00 AM',   'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'Àna ni 12:00 PM',   'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(), m.format('dddd [Ọsẹ̀ tón\\'bọ] [ni] LT'), 'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(), m.format('dddd [Ọsẹ̀ tón\\'bọ] [ni] LT'), 'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(), m.format('dddd [Ọsẹ̀ tón\\'bọ] [ni] LT'), 'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(), m.format('dddd [Ọsẹ̀ tólọ́] [ni] LT'), 'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(), m.format('dddd [Ọsẹ̀ tólọ́] [ni] LT'), 'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(), m.format('dddd [Ọsẹ̀ tólọ́] [ni] LT'), 'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '1 week ago');\n    assert.equal(weeksFromNow.calendar(), weeksFromNow.format('L'), 'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(), weeksFromNow.format('L'), 'in 2 weeks');\n});\n\ntest('weeks year starting sunday format', function (assert) {\n    assert.equal(moment([2012, 0,  1]).format('w ww wo'), '52 52 ọjọ́ 52', 'Jan  1 2012 should be week 52');\n    assert.equal(moment([2012, 0,  2]).format('w ww wo'),   '1 01 ọjọ́ 1', 'Jan  2 2012 should be week 1');\n    assert.equal(moment([2012, 0,  8]).format('w ww wo'),   '1 01 ọjọ́ 1', 'Jan  8 2012 should be week 1');\n    assert.equal(moment([2012, 0,  9]).format('w ww wo'),   '2 02 ọjọ́ 2', 'Jan  9 2012 should be week 2');\n    assert.equal(moment([2012, 0, 15]).format('w ww wo'),   '2 02 ọjọ́ 2', 'Jan 15 2012 should be week 2');\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\n\n\nfunction localeModule (name, lifecycle) {\n    QUnit.module('locale:' + name, {\n        setup : function () {\n            moment.locale(name);\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            moment.locale('en');\n            teardownDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n    defineCommonLocaleTests(name, -1, -1);\n}\n\nlocaleModule('zh-cn');\n\ntest('parse', function (assert) {\n    var tests = '一月 1月_二月 2月_三月 3月_四月 4月_五月 5月_六月 6月_七月 7月_八月 8月_九月 9月_十月 10月_十一月 11月_十二月 12月'.split('_'), i;\n\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, MMMM Do YYYY, a h:mm:ss',      '星期日, 二月 14日 2010, 下午 3:25:50'],\n            ['ddd, Ah',                            '周日, 下午3'],\n            ['M Mo MM MMMM MMM',                   '2 2月 02 二月 2月'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14日 14'],\n            ['d do dddd ddd dd',                   '0 0日 星期日 周日 日'],\n            ['DDD DDDo DDDD',                      '45 45日 045'],\n            ['w wo ww',                            '6 6周 06'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                '下午 下午'],\n            ['[这年的第] DDDo',                    '这年的第 45日'],\n            ['LTS',                                '15:25:50'],\n            ['L',                                  '2010年2月14日'],\n            ['LL',                                 '2010年2月14日'],\n            ['LLL',                                '2010年2月14日下午3点25分'],\n            ['LLLL',                               '2010年2月14日星期日下午3点25分'],\n            ['l',                                  '2010年2月14日'],\n            ['ll',                                 '2010年2月14日'],\n            ['lll',                                '2010年2月14日 15:25'],\n            ['llll',                               '2010年2月14日星期日 15:25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format month', function (assert) {\n    var expected = '一月 1月_二月 2月_三月 3月_四月 4月_五月 5月_六月 6月_七月 7月_八月 8月_九月 9月_十月 10月_十一月 11月_十二月 12月'.split('_'), i;\n\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = '星期日 周日 日_星期一 周一 一_星期二 周二 二_星期三 周三 三_星期四 周四 四_星期五 周五 五_星期六 周六 六'.split('_'), i;\n\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  '几秒',   '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  '1 分钟', '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  '1 分钟', '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 分钟',  '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 分钟', '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  '1 小时', '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  '1 小时', '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 小时',  '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 小时',  '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 小时', '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  '1 天',   '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  '1 天',   '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 天',   '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   '1 天',   '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 天',   '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 天',  '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  '1 个月', '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  '1 个月', '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  '1 个月', '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 个月',  '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 个月',  '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 个月',  '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   '1 个月', '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 个月',  '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), '1 年',   '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 年',   '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   '1 年',   '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 年',   '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), '几秒内',  'prefix');\n    assert.equal(moment(0).from(30000), '几秒前', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), '几秒前',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), '几秒内', 'in a few seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), '5 天内', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   '今天12:00', 'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      '今天12:25', 'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       '今天13:00', 'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       '明天12:00', 'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  '今天11:00', 'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  '昨天12:00', 'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('[下]ddddLT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[下]ddddLT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[下]ddddLT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('[上]ddddLT'),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[上]ddddLT'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[上]ddddLT'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),      '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),      '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('meridiem', function (assert) {\n    assert.equal(moment([2011, 2, 23,  0, 0]).format('A'), '凌晨', 'before dawn');\n    assert.equal(moment([2011, 2, 23,  6, 0]).format('A'), '早上', 'morning');\n    assert.equal(moment([2011, 2, 23,  9, 0]).format('A'), '上午', 'before noon');\n    assert.equal(moment([2011, 2, 23, 12, 0]).format('A'), '中午', 'noon');\n    assert.equal(moment([2011, 2, 23, 13, 0]).format('A'), '下午', 'afternoon');\n    assert.equal(moment([2011, 2, 23, 18, 0]).format('A'), '晚上', 'night');\n});\n\ntest('weeks year starting sunday format', function (assert) {\n    assert.equal(moment([2012, 0,  1]).format('w ww wo'), '52 52 52周', 'Jan  1 2012 应该是第52周');\n    assert.equal(moment([2012, 0,  7]).format('w ww wo'), '1 01 1周', 'Jan  7 2012 应该是第 1周');\n    assert.equal(moment([2012, 0, 14]).format('w ww wo'), '2 02 2周', 'Jan 14 2012 应该是第 2周');\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\n\n\nfunction localeModule (name, lifecycle) {\n    QUnit.module('locale:' + name, {\n        setup : function () {\n            moment.locale(name);\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            moment.locale('en');\n            teardownDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n    defineCommonLocaleTests(name, -1, -1);\n}\n\nlocaleModule('zh-hk');\n\ntest('parse', function (assert) {\n    var tests = '一月 1月_二月 2月_三月 3月_四月 4月_五月 5月_六月 6月_七月 7月_八月 8月_九月 9月_十月 10月_十一月 11月_十二月 12月'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, MMMM Do YYYY, a h:mm:ss',      '星期日, 二月 14日 2010, 下午 3:25:50'],\n            ['ddd, Ah',                            '週日, 下午3'],\n            ['M Mo MM MMMM MMM',                   '2 2月 02 二月 2月'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14日 14'],\n            ['d do dddd ddd dd',                   '0 0日 星期日 週日 日'],\n            ['DDD DDDo DDDD',                      '45 45日 045'],\n            ['w wo ww',                            '8 8週 08'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                '下午 下午'],\n            ['[這年的第] DDDo',                    '這年的第 45日'],\n            ['LTS',                                '15:25:50'],\n            ['L',                                  '2010年2月14日'],\n            ['LL',                                 '2010年2月14日'],\n            ['LLL',                                '2010年2月14日 15:25'],\n            ['LLLL',                               '2010年2月14日星期日 15:25'],\n            ['l',                                  '2010年2月14日'],\n            ['ll',                                 '2010年2月14日'],\n            ['lll',                                '2010年2月14日 15:25'],\n            ['llll',                               '2010年2月14日星期日 15:25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format month', function (assert) {\n    var expected = '一月 1月_二月 2月_三月 3月_四月 4月_五月 5月_六月 6月_七月 7月_八月 8月_九月 9月_十月 10月_十一月 11月_十二月 12月'.split('_'), i;\n\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = '星期日 週日 日_星期一 週一 一_星期二 週二 二_星期三 週三 三_星期四 週四 四_星期五 週五 五_星期六 週六 六'.split('_'), i;\n\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  '幾秒',   '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  '1 分鐘', '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  '1 分鐘', '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 分鐘',  '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 分鐘', '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  '1 小時', '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  '1 小時', '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 小時',  '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 小時',  '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 小時', '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  '1 天',   '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  '1 天',   '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 天',   '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   '1 天',   '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 天',   '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 天',  '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  '1 個月', '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  '1 個月', '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  '1 個月', '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 個月',  '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 個月',  '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 個月',  '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   '1 個月', '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 個月',  '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), '1 年',   '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 年',   '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   '1 年',   '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 年',   '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), '幾秒內',  'prefix');\n    assert.equal(moment(0).from(30000), '幾秒前', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), '幾秒前',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), '幾秒內', 'in a few seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), '5 天內', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   '今天12:00', 'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      '今天12:25', 'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       '今天13:00', 'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       '明天12:00', 'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  '今天11:00', 'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  '昨天12:00', 'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('[下]ddddLT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[下]ddddLT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[下]ddddLT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('[上]ddddLT'),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[上]ddddLT'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[上]ddddLT'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),      '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),      '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('meridiem', function (assert) {\n    assert.equal(moment([2011, 2, 23,  0, 0]).format('a'), '凌晨', 'before dawn');\n    assert.equal(moment([2011, 2, 23,  6, 0]).format('a'), '早上', 'morning');\n    assert.equal(moment([2011, 2, 23,  9, 0]).format('a'), '上午', 'before noon');\n    assert.equal(moment([2011, 2, 23, 12, 0]).format('a'), '中午', 'noon');\n    assert.equal(moment([2011, 2, 23, 13, 0]).format('a'), '下午', 'after noon');\n    assert.equal(moment([2011, 2, 23, 18, 0]).format('a'), '晚上', 'night');\n\n    assert.equal(moment([2011, 2, 23,  0, 0]).format('A'), '凌晨', 'before dawn');\n    assert.equal(moment([2011, 2, 23,  6, 0]).format('A'), '早上', 'morning');\n    assert.equal(moment([2011, 2, 23,  9, 0]).format('A'), '上午', 'before noon');\n    assert.equal(moment([2011, 2, 23, 12, 0]).format('A'), '中午', 'noon');\n    assert.equal(moment([2011, 2, 23, 13, 0]).format('A'), '下午', 'afternoon');\n    assert.equal(moment([2011, 2, 23, 18, 0]).format('A'), '晚上', 'night');\n});\n\ntest('weeks year starting sunday format', function (assert) {\n    assert.equal(moment([2012, 0,  1]).format('w ww wo'), '1 01 1週', 'Jan  1 2012 應該是第 1週');\n    assert.equal(moment([2012, 0,  7]).format('w ww wo'), '1 01 1週', 'Jan  7 2012 應該是第 1週');\n    assert.equal(moment([2012, 0,  8]).format('w ww wo'), '2 02 2週', 'Jan  8 2012 應該是第 2週');\n    assert.equal(moment([2012, 0, 14]).format('w ww wo'), '2 02 2週', 'Jan 14 2012 應該是第 2週');\n    assert.equal(moment([2012, 0, 15]).format('w ww wo'), '3 03 3週', 'Jan 15 2012 應該是第 3週');\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\n\n\nfunction localeModule (name, lifecycle) {\n    QUnit.module('locale:' + name, {\n        setup : function () {\n            moment.locale(name);\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            moment.locale('en');\n            teardownDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n    defineCommonLocaleTests(name, -1, -1);\n}\n\nlocaleModule('zh-tw');\n\ntest('parse', function (assert) {\n    var tests = '一月 1月_二月 2月_三月 3月_四月 4月_五月 5月_六月 6月_七月 7月_八月 8月_九月 9月_十月 10月_十一月 11月_十二月 12月'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, MMMM Do YYYY, a h:mm:ss',      '星期日, 二月 14日 2010, 下午 3:25:50'],\n            ['ddd, Ah',                            '週日, 下午3'],\n            ['M Mo MM MMMM MMM',                   '2 2月 02 二月 2月'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14日 14'],\n            ['d do dddd ddd dd',                   '0 0日 星期日 週日 日'],\n            ['DDD DDDo DDDD',                      '45 45日 045'],\n            ['w wo ww',                            '8 8週 08'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                '下午 下午'],\n            ['[這年的第] DDDo',                    '這年的第 45日'],\n            ['LTS',                                '15:25:50'],\n            ['L',                                  '2010年2月14日'],\n            ['LL',                                 '2010年2月14日'],\n            ['LLL',                                '2010年2月14日 15:25'],\n            ['LLLL',                               '2010年2月14日星期日 15:25'],\n            ['l',                                  '2010年2月14日'],\n            ['ll',                                 '2010年2月14日'],\n            ['lll',                                '2010年2月14日 15:25'],\n            ['llll',                               '2010年2月14日星期日 15:25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format month', function (assert) {\n    var expected = '一月 1月_二月 2月_三月 3月_四月 4月_五月 5月_六月 6月_七月 7月_八月 8月_九月 9月_十月 10月_十一月 11月_十二月 12月'.split('_'), i;\n\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = '星期日 週日 日_星期一 週一 一_星期二 週二 二_星期三 週三 三_星期四 週四 四_星期五 週五 五_星期六 週六 六'.split('_'), i;\n\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  '幾秒',   '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  '1 分鐘', '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  '1 分鐘', '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 分鐘',  '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 分鐘', '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  '1 小時', '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  '1 小時', '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 小時',  '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 小時',  '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 小時', '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  '1 天',   '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  '1 天',   '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 天',   '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   '1 天',   '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 天',   '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 天',  '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  '1 個月', '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  '1 個月', '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  '1 個月', '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 個月',  '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 個月',  '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 個月',  '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   '1 個月', '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 個月',  '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), '1 年',   '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 年',   '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   '1 年',   '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 年',   '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), '幾秒內',  'prefix');\n    assert.equal(moment(0).from(30000), '幾秒前', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), '幾秒前',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), '幾秒內', 'in a few seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), '5 天內', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   '今天12:00', 'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      '今天12:25', 'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       '今天13:00', 'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       '明天12:00', 'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  '今天11:00', 'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  '昨天12:00', 'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('[下]ddddLT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[下]ddddLT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[下]ddddLT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('[上]ddddLT'),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[上]ddddLT'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[上]ddddLT'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),      '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),      '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('meridiem', function (assert) {\n    assert.equal(moment([2011, 2, 23,  0, 0]).format('a'), '凌晨', 'before dawn');\n    assert.equal(moment([2011, 2, 23,  6, 0]).format('a'), '早上', 'morning');\n    assert.equal(moment([2011, 2, 23,  9, 0]).format('a'), '上午', 'before noon');\n    assert.equal(moment([2011, 2, 23, 12, 0]).format('a'), '中午', 'noon');\n    assert.equal(moment([2011, 2, 23, 13, 0]).format('a'), '下午', 'after noon');\n    assert.equal(moment([2011, 2, 23, 18, 0]).format('a'), '晚上', 'night');\n\n    assert.equal(moment([2011, 2, 23,  0, 0]).format('A'), '凌晨', 'before dawn');\n    assert.equal(moment([2011, 2, 23,  6, 0]).format('A'), '早上', 'morning');\n    assert.equal(moment([2011, 2, 23,  9, 0]).format('A'), '上午', 'before noon');\n    assert.equal(moment([2011, 2, 23, 12, 0]).format('A'), '中午', 'noon');\n    assert.equal(moment([2011, 2, 23, 13, 0]).format('A'), '下午', 'afternoon');\n    assert.equal(moment([2011, 2, 23, 18, 0]).format('A'), '晚上', 'night');\n});\n\ntest('weeks year starting sunday format', function (assert) {\n    assert.equal(moment([2012, 0,  1]).format('w ww wo'), '1 01 1週', 'Jan  1 2012 應該是第 1週');\n    assert.equal(moment([2012, 0,  7]).format('w ww wo'), '1 01 1週', 'Jan  7 2012 應該是第 1週');\n    assert.equal(moment([2012, 0,  8]).format('w ww wo'), '2 02 2週', 'Jan  8 2012 應該是第 2週');\n    assert.equal(moment([2012, 0, 14]).format('w ww wo'), '2 02 2週', 'Jan 14 2012 應該是第 2週');\n    assert.equal(moment([2012, 0, 15]).format('w ww wo'), '3 03 3週', 'Jan 15 2012 應該是第 3週');\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\nfunction module$1 (name, lifecycle) {\n    QUnit.module(name, {\n        setup : function () {\n            moment.locale('en');\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'core');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            teardownDeprecationHandler(test, moment, 'core');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n}\n\nmodule$1('add and subtract');\n\ntest('add short reverse args', function (assert) {\n    var a = moment(), b, c, d;\n    a.year(2011);\n    a.month(9);\n    a.date(12);\n    a.hours(6);\n    a.minutes(7);\n    a.seconds(8);\n    a.milliseconds(500);\n\n    assert.equal(a.add({ms: 50}).milliseconds(), 550, 'Add milliseconds');\n    assert.equal(a.add({s: 1}).seconds(), 9, 'Add seconds');\n    assert.equal(a.add({m: 1}).minutes(), 8, 'Add minutes');\n    assert.equal(a.add({h: 1}).hours(), 7, 'Add hours');\n    assert.equal(a.add({d: 1}).date(), 13, 'Add date');\n    assert.equal(a.add({w: 1}).date(), 20, 'Add week');\n    assert.equal(a.add({M: 1}).month(), 10, 'Add month');\n    assert.equal(a.add({y: 1}).year(), 2012, 'Add year');\n    assert.equal(a.add({Q: 1}).month(), 1, 'Add quarter');\n\n    b = moment([2010, 0, 31]).add({M: 1});\n    c = moment([2010, 1, 28]).subtract({M: 1});\n    d = moment([2010, 1, 28]).subtract({Q: 1});\n\n    assert.equal(b.month(), 1, 'add month, jan 31st to feb 28th');\n    assert.equal(b.date(), 28, 'add month, jan 31st to feb 28th');\n    assert.equal(c.month(), 0, 'subtract month, feb 28th to jan 28th');\n    assert.equal(c.date(), 28, 'subtract month, feb 28th to jan 28th');\n    assert.equal(d.month(), 10, 'subtract quarter, feb 28th 2010 to nov 28th 2009');\n    assert.equal(d.date(), 28, 'subtract quarter, feb 28th 2010 to nov 28th 2009');\n    assert.equal(d.year(), 2009, 'subtract quarter, feb 28th 2010 to nov 28th 2009');\n});\n\ntest('add long reverse args', function (assert) {\n    var a = moment();\n    a.year(2011);\n    a.month(9);\n    a.date(12);\n    a.hours(6);\n    a.minutes(7);\n    a.seconds(8);\n    a.milliseconds(500);\n\n    assert.equal(a.add({milliseconds: 50}).milliseconds(), 550, 'Add milliseconds');\n    assert.equal(a.add({seconds: 1}).seconds(), 9, 'Add seconds');\n    assert.equal(a.add({minutes: 1}).minutes(), 8, 'Add minutes');\n    assert.equal(a.add({hours: 1}).hours(), 7, 'Add hours');\n    assert.equal(a.add({days: 1}).date(), 13, 'Add date');\n    assert.equal(a.add({weeks: 1}).date(), 20, 'Add week');\n    assert.equal(a.add({months: 1}).month(), 10, 'Add month');\n    assert.equal(a.add({years: 1}).year(), 2012, 'Add year');\n    assert.equal(a.add({quarters: 1}).month(), 1, 'Add quarter');\n});\n\ntest('add long singular reverse args', function (assert) {\n    var a = moment();\n    a.year(2011);\n    a.month(9);\n    a.date(12);\n    a.hours(6);\n    a.minutes(7);\n    a.seconds(8);\n    a.milliseconds(500);\n\n    assert.equal(a.add({millisecond: 50}).milliseconds(), 550, 'Add milliseconds');\n    assert.equal(a.add({second: 1}).seconds(), 9, 'Add seconds');\n    assert.equal(a.add({minute: 1}).minutes(), 8, 'Add minutes');\n    assert.equal(a.add({hour: 1}).hours(), 7, 'Add hours');\n    assert.equal(a.add({day: 1}).date(), 13, 'Add date');\n    assert.equal(a.add({week: 1}).date(), 20, 'Add week');\n    assert.equal(a.add({month: 1}).month(), 10, 'Add month');\n    assert.equal(a.add({year: 1}).year(), 2012, 'Add year');\n    assert.equal(a.add({quarter: 1}).month(), 1, 'Add quarter');\n});\n\ntest('add string long reverse args', function (assert) {\n    var a = moment(), b;\n\n    test.expectedDeprecations('moment().add(period, number)');\n\n    a.year(2011);\n    a.month(9);\n    a.date(12);\n    a.hours(6);\n    a.minutes(7);\n    a.seconds(8);\n    a.milliseconds(500);\n\n    b = a.clone();\n\n    assert.equal(a.add('millisecond', 50).milliseconds(), 550, 'Add milliseconds');\n    assert.equal(a.add('second', 1).seconds(), 9, 'Add seconds');\n    assert.equal(a.add('minute', 1).minutes(), 8, 'Add minutes');\n    assert.equal(a.add('hour', 1).hours(), 7, 'Add hours');\n    assert.equal(a.add('day', 1).date(), 13, 'Add date');\n    assert.equal(a.add('week', 1).date(), 20, 'Add week');\n    assert.equal(a.add('month', 1).month(), 10, 'Add month');\n    assert.equal(a.add('year', 1).year(), 2012, 'Add year');\n    assert.equal(b.add('day', '01').date(), 13, 'Add date');\n    assert.equal(a.add('quarter', 1).month(), 1, 'Add quarter');\n});\n\ntest('add string long singular reverse args', function (assert) {\n    var a = moment(), b;\n\n    test.expectedDeprecations('moment().add(period, number)');\n\n    a.year(2011);\n    a.month(9);\n    a.date(12);\n    a.hours(6);\n    a.minutes(7);\n    a.seconds(8);\n    a.milliseconds(500);\n\n    b = a.clone();\n\n    assert.equal(a.add('milliseconds', 50).milliseconds(), 550, 'Add milliseconds');\n    assert.equal(a.add('seconds', 1).seconds(), 9, 'Add seconds');\n    assert.equal(a.add('minutes', 1).minutes(), 8, 'Add minutes');\n    assert.equal(a.add('hours', 1).hours(), 7, 'Add hours');\n    assert.equal(a.add('days', 1).date(), 13, 'Add date');\n    assert.equal(a.add('weeks', 1).date(), 20, 'Add week');\n    assert.equal(a.add('months', 1).month(), 10, 'Add month');\n    assert.equal(a.add('years', 1).year(), 2012, 'Add year');\n    assert.equal(b.add('days', '01').date(), 13, 'Add date');\n    assert.equal(a.add('quarters', 1).month(), 1, 'Add quarter');\n});\n\ntest('add string short reverse args', function (assert) {\n    var a = moment();\n    test.expectedDeprecations('moment().add(period, number)');\n\n    a.year(2011);\n    a.month(9);\n    a.date(12);\n    a.hours(6);\n    a.minutes(7);\n    a.seconds(8);\n    a.milliseconds(500);\n\n    assert.equal(a.add('ms', 50).milliseconds(), 550, 'Add milliseconds');\n    assert.equal(a.add('s', 1).seconds(), 9, 'Add seconds');\n    assert.equal(a.add('m', 1).minutes(), 8, 'Add minutes');\n    assert.equal(a.add('h', 1).hours(), 7, 'Add hours');\n    assert.equal(a.add('d', 1).date(), 13, 'Add date');\n    assert.equal(a.add('w', 1).date(), 20, 'Add week');\n    assert.equal(a.add('M', 1).month(), 10, 'Add month');\n    assert.equal(a.add('y', 1).year(), 2012, 'Add year');\n    assert.equal(a.add('Q', 1).month(), 1, 'Add quarter');\n});\n\ntest('add string long', function (assert) {\n    var a = moment();\n    a.year(2011);\n    a.month(9);\n    a.date(12);\n    a.hours(6);\n    a.minutes(7);\n    a.seconds(8);\n    a.milliseconds(500);\n\n    assert.equal(a.add(50, 'millisecond').milliseconds(), 550, 'Add milliseconds');\n    assert.equal(a.add(1, 'second').seconds(), 9, 'Add seconds');\n    assert.equal(a.add(1, 'minute').minutes(), 8, 'Add minutes');\n    assert.equal(a.add(1, 'hour').hours(), 7, 'Add hours');\n    assert.equal(a.add(1, 'day').date(), 13, 'Add date');\n    assert.equal(a.add(1, 'week').date(), 20, 'Add week');\n    assert.equal(a.add(1, 'month').month(), 10, 'Add month');\n    assert.equal(a.add(1, 'year').year(), 2012, 'Add year');\n    assert.equal(a.add(1, 'quarter').month(), 1, 'Add quarter');\n});\n\ntest('add string long singular', function (assert) {\n    var a = moment();\n    a.year(2011);\n    a.month(9);\n    a.date(12);\n    a.hours(6);\n    a.minutes(7);\n    a.seconds(8);\n    a.milliseconds(500);\n\n    assert.equal(a.add(50, 'milliseconds').milliseconds(), 550, 'Add milliseconds');\n    assert.equal(a.add(1, 'seconds').seconds(), 9, 'Add seconds');\n    assert.equal(a.add(1, 'minutes').minutes(), 8, 'Add minutes');\n    assert.equal(a.add(1, 'hours').hours(), 7, 'Add hours');\n    assert.equal(a.add(1, 'days').date(), 13, 'Add date');\n    assert.equal(a.add(1, 'weeks').date(), 20, 'Add week');\n    assert.equal(a.add(1, 'months').month(), 10, 'Add month');\n    assert.equal(a.add(1, 'years').year(), 2012, 'Add year');\n    assert.equal(a.add(1, 'quarters').month(), 1, 'Add quarter');\n});\n\ntest('add string short', function (assert) {\n    var a = moment();\n    a.year(2011);\n    a.month(9);\n    a.date(12);\n    a.hours(6);\n    a.minutes(7);\n    a.seconds(8);\n    a.milliseconds(500);\n\n    assert.equal(a.add(50, 'ms').milliseconds(), 550, 'Add milliseconds');\n    assert.equal(a.add(1, 's').seconds(), 9, 'Add seconds');\n    assert.equal(a.add(1, 'm').minutes(), 8, 'Add minutes');\n    assert.equal(a.add(1, 'h').hours(), 7, 'Add hours');\n    assert.equal(a.add(1, 'd').date(), 13, 'Add date');\n    assert.equal(a.add(1, 'w').date(), 20, 'Add week');\n    assert.equal(a.add(1, 'M').month(), 10, 'Add month');\n    assert.equal(a.add(1, 'y').year(), 2012, 'Add year');\n    assert.equal(a.add(1, 'Q').month(), 1, 'Add quarter');\n});\n\ntest('add strings string short reversed', function (assert) {\n    var a = moment();\n    test.expectedDeprecations('moment().add(period, number)');\n\n    a.year(2011);\n    a.month(9);\n    a.date(12);\n    a.hours(6);\n    a.minutes(7);\n    a.seconds(8);\n    a.milliseconds(500);\n\n    assert.equal(a.add('ms', '50').milliseconds(), 550, 'Add milliseconds');\n    assert.equal(a.add('s', '1').seconds(), 9, 'Add seconds');\n    assert.equal(a.add('m', '1').minutes(), 8, 'Add minutes');\n    assert.equal(a.add('h', '1').hours(), 7, 'Add hours');\n    assert.equal(a.add('d', '1').date(), 13, 'Add date');\n    assert.equal(a.add('w', '1').date(), 20, 'Add week');\n    assert.equal(a.add('M', '1').month(), 10, 'Add month');\n    assert.equal(a.add('y', '1').year(), 2012, 'Add year');\n    assert.equal(a.add('Q', '1').month(), 1, 'Add quarter');\n});\n\ntest('subtract strings string short reversed', function (assert) {\n    var a = moment();\n    test.expectedDeprecations('moment().subtract(period, number)');\n\n    a.year(2011);\n    a.month(9);\n    a.date(12);\n    a.hours(6);\n    a.minutes(7);\n    a.seconds(8);\n    a.milliseconds(500);\n\n    assert.equal(a.subtract('ms', '50').milliseconds(), 450, 'Subtract milliseconds');\n    assert.equal(a.subtract('s', '1').seconds(), 7, 'Subtract seconds');\n    assert.equal(a.subtract('m', '1').minutes(), 6, 'Subtract minutes');\n    assert.equal(a.subtract('h', '1').hours(), 5, 'Subtract hours');\n    assert.equal(a.subtract('d', '1').date(), 11, 'Subtract date');\n    assert.equal(a.subtract('w', '1').date(), 4, 'Subtract week');\n    assert.equal(a.subtract('M', '1').month(), 8, 'Subtract month');\n    assert.equal(a.subtract('y', '1').year(), 2010, 'Subtract year');\n    assert.equal(a.subtract('Q', '1').month(), 5, 'Subtract quarter');\n});\n\ntest('add strings string short', function (assert) {\n    var a = moment();\n    a.year(2011);\n    a.month(9);\n    a.date(12);\n    a.hours(6);\n    a.minutes(7);\n    a.seconds(8);\n    a.milliseconds(500);\n\n    assert.equal(a.add('50', 'ms').milliseconds(), 550, 'Add milliseconds');\n    assert.equal(a.add('1', 's').seconds(), 9, 'Add seconds');\n    assert.equal(a.add('1', 'm').minutes(), 8, 'Add minutes');\n    assert.equal(a.add('1', 'h').hours(), 7, 'Add hours');\n    assert.equal(a.add('1', 'd').date(), 13, 'Add date');\n    assert.equal(a.add('1', 'w').date(), 20, 'Add week');\n    assert.equal(a.add('1', 'M').month(), 10, 'Add month');\n    assert.equal(a.add('1', 'y').year(), 2012, 'Add year');\n    assert.equal(a.add('1', 'Q').month(), 1, 'Add quarter');\n});\n\ntest('add no string with milliseconds default', function (assert) {\n    var a = moment();\n    a.year(2011);\n    a.month(9);\n    a.date(12);\n    a.hours(6);\n    a.minutes(7);\n    a.seconds(8);\n    a.milliseconds(500);\n\n    assert.equal(a.add(50).milliseconds(), 550, 'Add milliseconds');\n});\n\ntest('subtract strings string short', function (assert) {\n    var a = moment();\n    a.year(2011);\n    a.month(9);\n    a.date(12);\n    a.hours(6);\n    a.minutes(7);\n    a.seconds(8);\n    a.milliseconds(500);\n\n    assert.equal(a.subtract('50', 'ms').milliseconds(), 450, 'Subtract milliseconds');\n    assert.equal(a.subtract('1', 's').seconds(), 7, 'Subtract seconds');\n    assert.equal(a.subtract('1', 'm').minutes(), 6, 'Subtract minutes');\n    assert.equal(a.subtract('1', 'h').hours(), 5, 'Subtract hours');\n    assert.equal(a.subtract('1', 'd').date(), 11, 'Subtract date');\n    assert.equal(a.subtract('1', 'w').date(), 4, 'Subtract week');\n    assert.equal(a.subtract('1', 'M').month(), 8, 'Subtract month');\n    assert.equal(a.subtract('1', 'y').year(), 2010, 'Subtract year');\n    assert.equal(a.subtract('1', 'Q').month(), 5, 'Subtract quarter');\n});\n\ntest('add across DST', function (assert) {\n    // Detect Safari bug and bail. Hours on 13th March 2011 are shifted\n    // with 1 ahead.\n    if (new Date(2011, 2, 13, 5, 0, 0).getHours() !== 5) {\n        expect(0);\n        return;\n    }\n\n    var a = moment(new Date(2011, 2, 12, 5, 0, 0)),\n        b = moment(new Date(2011, 2, 12, 5, 0, 0)),\n        c = moment(new Date(2011, 2, 12, 5, 0, 0)),\n        d = moment(new Date(2011, 2, 12, 5, 0, 0)),\n        e = moment(new Date(2011, 2, 12, 5, 0, 0));\n    a.add(1, 'days');\n    b.add(24, 'hours');\n    c.add(1, 'months');\n    e.add(1, 'quarter');\n\n    assert.equal(a.hours(), 5, 'adding days over DST difference should result in the same hour');\n    if (b.isDST() && !d.isDST()) {\n        assert.equal(b.hours(), 6, 'adding hours over DST difference should result in a different hour');\n    } else if (!b.isDST() && d.isDST()) {\n        assert.equal(b.hours(), 4, 'adding hours over DST difference should result in a different hour');\n    } else {\n        assert.equal(b.hours(), 5, 'adding hours over DST difference should result in a same hour if the timezone does not have daylight savings time');\n    }\n    assert.equal(c.hours(), 5, 'adding months over DST difference should result in the same hour');\n    assert.equal(e.hours(), 5, 'adding quarters over DST difference should result in the same hour');\n});\n\ntest('add decimal values of days and months', function (assert) {\n    assert.equal(moment([2016,3,3]).add(1.5, 'days').date(), 5, 'adding 1.5 days is rounded to adding 2 day');\n    assert.equal(moment([2016,3,3]).add(-1.5, 'days').date(), 1, 'adding -1.5 days is rounded to adding -2 day');\n    assert.equal(moment([2016,3,1]).add(-1.5, 'days').date(), 30, 'adding -1.5 days on first of month wraps around');\n    assert.equal(moment([2016,3,3]).add(1.5, 'months').month(), 5, 'adding 1.5 months adds 2 months');\n    assert.equal(moment([2016,3,3]).add(-1.5, 'months').month(), 1, 'adding -1.5 months adds -2 months');\n    assert.equal(moment([2016,0,3]).add(-1.5, 'months').month(), 10, 'adding -1.5 months at start of year wraps back');\n    assert.equal(moment([2016,3,3]).subtract(1.5, 'days').date(),1, 'subtract 1.5 days is rounded to subtract 2 day');\n    assert.equal(moment([2016,3,2]).subtract(1.5, 'days').date(), 31, 'subtract 1.5 days subtracts 2 days');\n    assert.equal(moment([2016,1,1]).subtract(1.1, 'days').date(), 31, 'subtract 1.1 days wraps to previous month');\n    assert.equal(moment([2016,3,3]).subtract(-1.5, 'days').date(), 5, 'subtract -1.5 days is rounded to subtract -2 day');\n    assert.equal(moment([2016,3,30]).subtract(-1.5, 'days').date(), 2, 'subtract -1.5 days on last of month wraps around');\n    assert.equal(moment([2016,3,3]).subtract(1.5, 'months').month(), 1, 'subtract 1.5 months subtract 2 months');\n    assert.equal(moment([2016,3,3]).subtract(-1.5, 'months').month(), 5, 'subtract -1.5 months subtract -2 month');\n    assert.equal(moment([2016,11,31]).subtract(-1.5, 'months').month(),1, 'subtract -1.5 months at end of year wraps back');\n    assert.equal(moment([2016, 0,1]).add(1.5, 'years').format('YYYY-MM-DD'), '2017-07-01', 'add 1.5 years adds 1 year six months');\n    assert.equal(moment([2016, 0,1]).add(1.6, 'years').format('YYYY-MM-DD'), '2017-08-01', 'add 1.6 years becomes 1.6*12 = 19.2, round, 19 months');\n    assert.equal(moment([2016,0,1]).add(1.1, 'quarters').format('YYYY-MM-DD'), '2016-04-01', 'add 1.1 quarters 1.1*3=3.3, round, 3 months');\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\nfunction module$1 (name, lifecycle) {\n    QUnit.module(name, {\n        setup : function () {\n            moment.locale('en');\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'core');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            teardownDeprecationHandler(test, moment, 'core');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n}\n\n// These tests are for locale independent features\n// locale dependent tests would be in locale test folder\nmodule$1('calendar');\n\ntest('passing a function', function (assert) {\n    var a  = moment().hours(13).minutes(0).seconds(0);\n    assert.equal(moment(a).calendar(null, {\n        'sameDay': function () {\n            return 'h:mmA';\n        }\n    }), '1:00PM', 'should equate');\n});\n\ntest('extending calendar options', function (assert) {\n    var calendarFormat = moment.calendarFormat;\n\n    moment.calendarFormat = function (myMoment, now) {\n        var diff = myMoment.diff(now, 'days', true);\n        var nextMonth = now.clone().add(1, 'month');\n\n        var retVal =  diff < -6 ? 'sameElse' :\n            diff < -1 ? 'lastWeek' :\n            diff < 0 ? 'lastDay' :\n            diff < 1 ? 'sameDay' :\n            diff < 2 ? 'nextDay' :\n            diff < 7 ? 'nextWeek' :\n            (myMoment.month() === now.month() && myMoment.year() === now.year()) ? 'thisMonth' :\n            (nextMonth.month() === myMoment.month() && nextMonth.year() === myMoment.year()) ? 'nextMonth' : 'sameElse';\n        return retVal;\n    };\n\n    moment.updateLocale('en', {\n        calendar : {\n                sameDay : '[Today at] LT',\n                nextDay : '[Tomorrow at] LT',\n                nextWeek : 'dddd [at] LT',\n                lastDay : '[Yesterday at] LT',\n                lastWeek : '[Last] dddd [at] LT',\n                thisMonth : '[This month on the] Do',\n                nextMonth : '[Next month on the] Do',\n                sameElse : 'L'\n            }\n    });\n    var a = moment('2016-01-01').add(28, 'days');\n    var b = moment('2016-01-01').add(1, 'month');\n    try {\n        assert.equal(a.calendar('2016-01-01'), 'This month on the 29th', 'Ad hoc calendar format for this month');\n        assert.equal(b.calendar('2016-01-01'), 'Next month on the 1st', 'Ad hoc calendar format for next month');\n        assert.equal(a.locale('fr').calendar('2016-01-01'), a.locale('fr').format('L'), 'French falls back to default because thisMonth is not defined in that locale');\n    } finally {\n        moment.calendarFormat = calendarFormat;\n        moment.updateLocale('en', null);\n    }\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\nfunction module$1 (name, lifecycle) {\n    QUnit.module(name, {\n        setup : function () {\n            moment.locale('en');\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'core');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            teardownDeprecationHandler(test, moment, 'core');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n}\n\nmodule$1('create');\n\ntest('array', function (assert) {\n    assert.ok(moment([2010]).toDate() instanceof Date, '[2010]');\n    assert.ok(moment([2010, 1]).toDate() instanceof Date, '[2010, 1]');\n    assert.ok(moment([2010, 1, 12]).toDate() instanceof Date, '[2010, 1, 12]');\n    assert.ok(moment([2010, 1, 12, 1]).toDate() instanceof Date, '[2010, 1, 12, 1]');\n    assert.ok(moment([2010, 1, 12, 1, 1]).toDate() instanceof Date, '[2010, 1, 12, 1, 1]');\n    assert.ok(moment([2010, 1, 12, 1, 1, 1]).toDate() instanceof Date, '[2010, 1, 12, 1, 1, 1]');\n    assert.ok(moment([2010, 1, 12, 1, 1, 1, 1]).toDate() instanceof Date, '[2010, 1, 12, 1, 1, 1, 1]');\n    assert.equal(+moment(new Date(2010, 1, 14, 15, 25, 50, 125)), +moment([2010, 1, 14, 15, 25, 50, 125]), 'constructing with array === constructing with new Date()');\n});\n\ntest('array with invalid arguments', function (assert) {\n    assert.ok(!moment([2010, null, null]).isValid(), '[2010, null, null]');\n    assert.ok(!moment([1945, null, null]).isValid(), '[1945, null, null] (pre-1970)');\n});\n\ntest('array copying', function (assert) {\n    var importantArray = [2009, 11];\n    moment(importantArray);\n    assert.deepEqual(importantArray, [2009, 11], 'initializer should not mutate the original array');\n});\n\ntest('object', function (assert) {\n    var fmt = 'YYYY-MM-DD HH:mm:ss.SSS',\n        tests = [\n            [{year: 2010}, '2010-01-01 00:00:00.000'],\n            [{year: 2010, month: 1}, '2010-02-01 00:00:00.000'],\n            [{year: 2010, month: 1, day: 12}, '2010-02-12 00:00:00.000'],\n            [{year: 2010, month: 1, date: 12}, '2010-02-12 00:00:00.000'],\n            [{year: 2010, month: 1, day: 12, hours: 1}, '2010-02-12 01:00:00.000'],\n            [{year: 2010, month: 1, date: 12, hours: 1}, '2010-02-12 01:00:00.000'],\n            [{year: 2010, month: 1, day: 12, hours: 1, minutes: 1}, '2010-02-12 01:01:00.000'],\n            [{year: 2010, month: 1, date: 12, hours: 1, minutes: 1}, '2010-02-12 01:01:00.000'],\n            [{year: 2010, month: 1, day: 12, hours: 1, minutes: 1, seconds: 1}, '2010-02-12 01:01:01.000'],\n            [{year: 2010, month: 1, day: 12, hours: 1, minutes: 1, seconds: 1, milliseconds: 1}, '2010-02-12 01:01:01.001'],\n            [{years: 2010, months: 1, days: 14, hours: 15, minutes: 25, seconds: 50, milliseconds: 125}, '2010-02-14 15:25:50.125'],\n            [{year: 2010, month: 1, day: 14, hour: 15, minute: 25, second: 50, millisecond: 125}, '2010-02-14 15:25:50.125'],\n            [{y: 2010, M: 1, d: 14, h: 15, m: 25, s: 50, ms: 125}, '2010-02-14 15:25:50.125']\n        ], i;\n    for (i = 0; i < tests.length; ++i) {\n        assert.equal(moment(tests[i][0]).format(fmt), tests[i][1]);\n    }\n});\n\ntest('multi format array copying', function (assert) {\n    var importantArray = ['MM/DD/YYYY', 'YYYY-MM-DD', 'MM-DD-YYYY'];\n    moment('1999-02-13', importantArray);\n    assert.deepEqual(importantArray, ['MM/DD/YYYY', 'YYYY-MM-DD', 'MM-DD-YYYY'], 'initializer should not mutate the original array');\n});\n\ntest('number', function (assert) {\n    assert.ok(moment(1000).toDate() instanceof Date, '1000');\n    assert.equal(moment(1000).valueOf(), 1000, 'asserting valueOf');\n    assert.equal(moment.utc(1000).valueOf(), 1000, 'asserting valueOf');\n});\n\ntest('unix', function (assert) {\n    assert.equal(moment.unix(1).valueOf(), 1000, '1 unix timestamp == 1000 Date.valueOf');\n    assert.equal(moment(1000).unix(), 1, '1000 Date.valueOf == 1 unix timestamp');\n    assert.equal(moment.unix(1000).valueOf(), 1000000, '1000 unix timestamp == 1000000 Date.valueOf');\n    assert.equal(moment(1500).unix(), 1, '1500 Date.valueOf == 1 unix timestamp');\n    assert.equal(moment(1900).unix(), 1, '1900 Date.valueOf == 1 unix timestamp');\n    assert.equal(moment(2100).unix(), 2, '2100 Date.valueOf == 2 unix timestamp');\n    assert.equal(moment(1333129333524).unix(), 1333129333, '1333129333524 Date.valueOf == 1333129333 unix timestamp');\n    assert.equal(moment(1333129333524000).unix(), 1333129333524, '1333129333524000 Date.valueOf == 1333129333524 unix timestamp');\n});\n\ntest('date', function (assert) {\n    assert.ok(moment(new Date()).toDate() instanceof Date, 'new Date()');\n    assert.equal(moment(new Date(2016,0,1), 'YYYY-MM-DD').format('YYYY-MM-DD'), '2016-01-01', 'If date is provided, format string is ignored');\n});\n\ntest('date with a format as an array', function (assert) {\n    var tests = [\n        new Date(2016, 9, 27),\n        new Date(2016, 9, 28),\n        new Date(2016, 9, 29),\n        new Date(2016, 9, 30),\n        new Date(2016, 9, 31)\n    ], i;\n\n    for (i = 0; i < tests.length; i++) {\n        assert.equal(moment(tests[i]).format(), moment(tests[i], ['MM/DD/YYYY'], false).format(), 'Passing date with a format array should still return the correct date');\n    }\n});\n\ntest('date mutation', function (assert) {\n    var a = new Date();\n    assert.ok(moment(a).toDate() !== a, 'the date moment uses should not be the date passed in');\n});\n\ntest('moment', function (assert) {\n    assert.ok(moment(moment()).toDate() instanceof Date, 'moment(moment())');\n    assert.ok(moment(moment(moment())).toDate() instanceof Date, 'moment(moment(moment()))');\n});\n\ntest('cloning moment should only copy own properties', function (assert) {\n    assert.ok(!moment().clone().hasOwnProperty('month'), 'Should not clone prototype methods');\n});\n\ntest('cloning moment works with weird clones', function (assert) {\n    var extend = function (a, b) {\n        var i;\n        for (i in b) {\n            a[i] = b[i];\n        }\n        return a;\n    },\n    now = moment(),\n    nowu = moment.utc();\n\n    assert.equal(+extend({}, now).clone(), +now, 'cloning extend-ed now is now');\n    assert.equal(+extend({}, nowu).clone(), +nowu, 'cloning extend-ed utc now is utc now');\n});\n\ntest('cloning respects moment.momentProperties', function (assert) {\n    var m = moment();\n\n    assert.equal(m.clone()._special, undefined, 'cloning ignores extra properties');\n    m._special = 'bacon';\n    moment.momentProperties.push('_special');\n    assert.equal(m.clone()._special, 'bacon', 'cloning respects momentProperties');\n    moment.momentProperties.pop();\n});\n\ntest('undefined', function (assert) {\n    assert.ok(moment().toDate() instanceof Date, 'undefined');\n});\n\ntest('iso with bad input', function (assert) {\n    assert.ok(!moment('a', moment.ISO_8601).isValid(), 'iso parsing with invalid string');\n    assert.ok(!moment('a', moment.ISO_8601, true).isValid(), 'iso parsing with invalid string, strict');\n});\n\ntest('iso format 24hrs', function (assert) {\n    assert.equal(moment('2014-01-01T24:00:00.000').format('YYYY-MM-DD[T]HH:mm:ss.SSS'),\n            '2014-01-02T00:00:00.000', 'iso format with 24:00 localtime');\n    assert.equal(moment.utc('2014-01-01T24:00:00.000').format('YYYY-MM-DD[T]HH:mm:ss.SSS'),\n            '2014-01-02T00:00:00.000', 'iso format with 24:00 utc');\n});\n\ntest('string without format - json', function (assert) {\n    assert.equal(moment('Date(1325132654000)').valueOf(), 1325132654000, 'Date(1325132654000)');\n    assert.equal(moment('Date(-1325132654000)').valueOf(), -1325132654000, 'Date(-1325132654000)');\n    assert.equal(moment('/Date(1325132654000)/').valueOf(), 1325132654000, '/Date(1325132654000)/');\n    assert.equal(moment('/Date(1325132654000+0700)/').valueOf(), 1325132654000, '/Date(1325132654000+0700)/');\n    assert.equal(moment('/Date(1325132654000-0700)/').valueOf(), 1325132654000, '/Date(1325132654000-0700)/');\n});\n\ntest('string with format dropped am/pm bug', function (assert) {\n    moment.locale('en');\n\n    assert.equal(moment('05/1/2012 12:25:00', 'MM/DD/YYYY h:m:s a').format('MM/DD/YYYY'), '05/01/2012', 'should not break if am/pm is left off from the parsing tokens');\n    assert.equal(moment('05/1/2012 12:25:00 am', 'MM/DD/YYYY h:m:s a').format('MM/DD/YYYY'), '05/01/2012', 'should not break if am/pm is left off from the parsing tokens');\n    assert.equal(moment('05/1/2012 12:25:00 pm', 'MM/DD/YYYY h:m:s a').format('MM/DD/YYYY'), '05/01/2012', 'should not break if am/pm is left off from the parsing tokens');\n\n    assert.ok(moment('05/1/2012 12:25:00', 'MM/DD/YYYY h:m:s a').isValid());\n    assert.ok(moment('05/1/2012 12:25:00 am', 'MM/DD/YYYY h:m:s a').isValid());\n    assert.ok(moment('05/1/2012 12:25:00 pm', 'MM/DD/YYYY h:m:s a').isValid());\n});\n\ntest('empty string with formats', function (assert) {\n    assert.equal(moment('', 'MM').format('YYYY-MM-DD HH:mm:ss'), 'Invalid date');\n    assert.equal(moment(' ', 'MM').format('YYYY-MM-DD HH:mm:ss'), 'Invalid date');\n    assert.equal(moment(' ', 'DD').format('YYYY-MM-DD HH:mm:ss'), 'Invalid date');\n    assert.equal(moment(' ', ['MM', 'DD']).format('YYYY-MM-DD HH:mm:ss'), 'Invalid date');\n\n    assert.ok(!moment('', 'MM').isValid());\n    assert.ok(!moment(' ', 'MM').isValid());\n    assert.ok(!moment(' ', 'DD').isValid());\n    assert.ok(!moment(' ', ['MM', 'DD']).isValid());\n});\n\ntest('undefined argument with formats', function (assert) {\n    assert.equal(moment(undefined, 'MM').format('YYYY-MM-DD HH:mm:ss'), 'Invalid date');\n    assert.equal(moment(undefined, 'DD').format('YYYY-MM-DD HH:mm:ss'), 'Invalid date');\n    assert.equal(moment(undefined, ['MM', 'DD']).format('YYYY-MM-DD HH:mm:ss'), 'Invalid date');\n\n    assert.ok(!moment(undefined, 'MM').isValid());\n    assert.ok(!moment(undefined, 'MM').isValid());\n    assert.ok(!moment(undefined, 'DD').isValid());\n    assert.ok(!moment(undefined, ['MM', 'DD']).isValid());\n});\n\ntest('defaulting to current date', function (assert) {\n    var now = moment();\n    assert.equal(moment('12:13:14', 'hh:mm:ss').format('YYYY-MM-DD hh:mm:ss'),\n                 now.clone().hour(12).minute(13).second(14).format('YYYY-MM-DD hh:mm:ss'),\n                 'given only time default to current date');\n    assert.equal(moment('05', 'DD').format('YYYY-MM-DD'),\n                 now.clone().date(5).format('YYYY-MM-DD'),\n                 'given day of month default to current month, year');\n    assert.equal(moment('05', 'MM').format('YYYY-MM-DD'),\n                 now.clone().month(4).date(1).format('YYYY-MM-DD'),\n                 'given month default to current year');\n    assert.equal(moment('1996', 'YYYY').format('YYYY-MM-DD'),\n                 now.clone().year(1996).month(0).date(1).format('YYYY-MM-DD'),\n                 'given year do not default');\n});\n\ntest('matching am/pm', function (assert) {\n    assert.equal(moment('2012-09-03T03:00PM',   'YYYY-MM-DDThh:mmA').format('YYYY-MM-DDThh:mmA'), '2012-09-03T03:00PM', 'am/pm should parse correctly for PM');\n    assert.equal(moment('2012-09-03T03:00P.M.', 'YYYY-MM-DDThh:mmA').format('YYYY-MM-DDThh:mmA'), '2012-09-03T03:00PM', 'am/pm should parse correctly for P.M.');\n    assert.equal(moment('2012-09-03T03:00P',    'YYYY-MM-DDThh:mmA').format('YYYY-MM-DDThh:mmA'), '2012-09-03T03:00PM', 'am/pm should parse correctly for P');\n    assert.equal(moment('2012-09-03T03:00pm',   'YYYY-MM-DDThh:mmA').format('YYYY-MM-DDThh:mmA'), '2012-09-03T03:00PM', 'am/pm should parse correctly for pm');\n    assert.equal(moment('2012-09-03T03:00p.m.', 'YYYY-MM-DDThh:mmA').format('YYYY-MM-DDThh:mmA'), '2012-09-03T03:00PM', 'am/pm should parse correctly for p.m.');\n    assert.equal(moment('2012-09-03T03:00p',    'YYYY-MM-DDThh:mmA').format('YYYY-MM-DDThh:mmA'), '2012-09-03T03:00PM', 'am/pm should parse correctly for p');\n\n    assert.equal(moment('2012-09-03T03:00AM',   'YYYY-MM-DDThh:mmA').format('YYYY-MM-DDThh:mmA'), '2012-09-03T03:00AM', 'am/pm should parse correctly for AM');\n    assert.equal(moment('2012-09-03T03:00A.M.', 'YYYY-MM-DDThh:mmA').format('YYYY-MM-DDThh:mmA'), '2012-09-03T03:00AM', 'am/pm should parse correctly for A.M.');\n    assert.equal(moment('2012-09-03T03:00A',    'YYYY-MM-DDThh:mmA').format('YYYY-MM-DDThh:mmA'), '2012-09-03T03:00AM', 'am/pm should parse correctly for A');\n    assert.equal(moment('2012-09-03T03:00am',   'YYYY-MM-DDThh:mmA').format('YYYY-MM-DDThh:mmA'), '2012-09-03T03:00AM', 'am/pm should parse correctly for am');\n    assert.equal(moment('2012-09-03T03:00a.m.', 'YYYY-MM-DDThh:mmA').format('YYYY-MM-DDThh:mmA'), '2012-09-03T03:00AM', 'am/pm should parse correctly for a.m.');\n    assert.equal(moment('2012-09-03T03:00a',    'YYYY-MM-DDThh:mmA').format('YYYY-MM-DDThh:mmA'), '2012-09-03T03:00AM', 'am/pm should parse correctly for a');\n\n    assert.equal(moment('5:00p.m.March 4 2012', 'h:mmAMMMM D YYYY').format('YYYY-MM-DDThh:mmA'), '2012-03-04T05:00PM', 'am/pm should parse correctly before month names');\n});\n\ntest('string with format', function (assert) {\n    moment.locale('en');\n    var a = [\n        ['YYYY-Q',              '2014-4'],\n        ['MM-DD-YYYY',          '12-02-1999'],\n        ['DD-MM-YYYY',          '12-02-1999'],\n        ['DD/MM/YYYY',          '12/02/1999'],\n        ['DD_MM_YYYY',          '12_02_1999'],\n        ['DD:MM:YYYY',          '12:02:1999'],\n        ['D-M-YY',              '2-2-99'],\n        ['YY',                  '99'],\n        ['DDD-YYYY',            '300-1999'],\n        ['DD-MM-YYYY h:m:s',    '12-02-1999 2:45:10'],\n        ['DD-MM-YYYY h:m:s a',  '12-02-1999 2:45:10 am'],\n        ['DD-MM-YYYY h:m:s a',  '12-02-1999 2:45:10 pm'],\n        ['h:mm a',              '12:00 pm'],\n        ['h:mm a',              '12:30 pm'],\n        ['h:mm a',              '12:00 am'],\n        ['h:mm a',              '12:30 am'],\n        ['HH:mm',               '12:00'],\n        ['kk:mm',               '12:00'],\n        ['YYYY-MM-DDTHH:mm:ss', '2011-11-11T11:11:11'],\n        ['MM-DD-YYYY [M]',      '12-02-1999 M'],\n        ['ddd MMM DD HH:mm:ss YYYY', 'Tue Apr 07 22:52:51 2009'],\n        ['HH:mm:ss',            '12:00:00'],\n        ['HH:mm:ss',            '12:30:00'],\n        ['HH:mm:ss',            '00:00:00'],\n        ['HH:mm:ss S',          '00:30:00 1'],\n        ['HH:mm:ss SS',         '00:30:00 12'],\n        ['HH:mm:ss SSS',        '00:30:00 123'],\n        ['HH:mm:ss S',          '00:30:00 7'],\n        ['HH:mm:ss SS',         '00:30:00 78'],\n        ['HH:mm:ss SSS',        '00:30:00 789'],\n        ['kk:mm:ss',            '12:00:00'],\n        ['kk:mm:ss',            '12:30:00'],\n        ['kk:mm:ss',            '24:00:00'],\n        ['kk:mm:ss S',          '24:30:00 1'],\n        ['kk:mm:ss SS',         '24:30:00 12'],\n        ['kk:mm:ss SSS',        '24:30:00 123'],\n        ['kk:mm:ss S',          '24:30:00 7'],\n        ['kk:mm:ss SS',         '24:30:00 78'],\n        ['kk:mm:ss SSS',        '24:30:00 789'],\n        ['X',                   '1234567890'],\n        ['x',                   '1234567890123'],\n        ['LT',                  '12:30 AM'],\n        ['LTS',                 '12:30:29 AM'],\n        ['L',                   '09/02/1999'],\n        ['l',                   '9/2/1999'],\n        ['LL',                  'September 2, 1999'],\n        ['ll',                  'Sep 2, 1999'],\n        ['LLL',                 'September 2, 1999 12:30 AM'],\n        ['lll',                 'Sep 2, 1999 12:30 AM'],\n        ['LLLL',                'Thursday, September 2, 1999 12:30 AM'],\n        ['llll',                'Thu, Sep 2, 1999 12:30 AM']\n    ],\n    m,\n    i;\n\n    for (i = 0; i < a.length; i++) {\n        m = moment(a[i][1], a[i][0]);\n        assert.ok(m.isValid());\n        assert.equal(m.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('2 digit year with YYYY format', function (assert) {\n    assert.equal(moment('9/2/99', 'D/M/YYYY').format('DD/MM/YYYY'), '09/02/1999', 'D/M/YYYY ---> 9/2/99');\n    assert.equal(moment('9/2/1999', 'D/M/YYYY').format('DD/MM/YYYY'), '09/02/1999', 'D/M/YYYY ---> 9/2/1999');\n    assert.equal(moment('9/2/68', 'D/M/YYYY').format('DD/MM/YYYY'), '09/02/2068', 'D/M/YYYY ---> 9/2/68');\n    assert.equal(moment('9/2/69', 'D/M/YYYY').format('DD/MM/YYYY'), '09/02/1969', 'D/M/YYYY ---> 9/2/69');\n});\n\ntest('unix timestamp format', function (assert) {\n    var formats = ['X', 'X.S', 'X.SS', 'X.SSS'], i, format;\n\n    for (i = 0; i < formats.length; i++) {\n        format = formats[i];\n        assert.equal(moment('1234567890',     format).valueOf(), 1234567890 * 1000,       format + ' matches timestamp without milliseconds');\n        assert.equal(moment('1234567890.1',   format).valueOf(), 1234567890 * 1000 + 100, format + ' matches timestamp with deciseconds');\n        assert.equal(moment('1234567890.12',  format).valueOf(), 1234567890 * 1000 + 120, format + ' matches timestamp with centiseconds');\n        assert.equal(moment('1234567890.123', format).valueOf(), 1234567890 * 1000 + 123, format + ' matches timestamp with milliseconds');\n    }\n});\n\ntest('unix offset milliseconds', function (assert) {\n    assert.equal(moment('1234567890123', 'x').valueOf(), 1234567890123, 'x matches unix offset in milliseconds');\n});\n\ntest('milliseconds format', function (assert) {\n    assert.equal(moment('1', 'S').get('ms'), 100, 'deciseconds');\n    // assert.equal(moment('10', 'S', true).isValid(), false, 'deciseconds with two digits');\n    // assert.equal(moment('1', 'SS', true).isValid(), false, 'centiseconds with one digits');\n    assert.equal(moment('12', 'SS').get('ms'), 120, 'centiseconds');\n    // assert.equal(moment('123', 'SS', true).isValid(), false, 'centiseconds with three digits');\n    assert.equal(moment('123', 'SSS').get('ms'), 123, 'milliseconds');\n    assert.equal(moment('1234', 'SSSS').get('ms'), 123, 'milliseconds with SSSS');\n    assert.equal(moment('123456789101112', 'SSSS').get('ms'), 123, 'milliseconds with SSSS');\n});\n\ntest('string with format no separators', function (assert) {\n    moment.locale('en');\n    var a = [\n        ['MMDDYYYY',          '12021999'],\n        ['DDMMYYYY',          '12021999'],\n        ['YYYYMMDD',          '19991202'],\n        ['DDMMMYYYY',         '10Sep2001']\n    ], i;\n\n    for (i = 0; i < a.length; i++) {\n        assert.equal(moment(a[i][1], a[i][0]).format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('string with format (timezone)', function (assert) {\n    assert.equal(moment('5 -0700', 'H ZZ').toDate().getUTCHours(), 12, 'parse hours \\'5 -0700\\' ---> \\'H ZZ\\'');\n    assert.equal(moment('5 -07:00', 'H Z').toDate().getUTCHours(), 12, 'parse hours \\'5 -07:00\\' ---> \\'H Z\\'');\n    assert.equal(moment('5 -0730', 'H ZZ').toDate().getUTCMinutes(), 30, 'parse hours \\'5 -0730\\' ---> \\'H ZZ\\'');\n    assert.equal(moment('5 -07:30', 'H Z').toDate().getUTCMinutes(), 30, 'parse hours \\'5 -07:0\\' ---> \\'H Z\\'');\n    assert.equal(moment('5 +0100', 'H ZZ').toDate().getUTCHours(), 4, 'parse hours \\'5 +0100\\' ---> \\'H ZZ\\'');\n    assert.equal(moment('5 +01:00', 'H Z').toDate().getUTCHours(), 4, 'parse hours \\'5 +01:00\\' ---> \\'H Z\\'');\n    assert.equal(moment('5 +0130', 'H ZZ').toDate().getUTCMinutes(), 30, 'parse hours \\'5 +0130\\' ---> \\'H ZZ\\'');\n    assert.equal(moment('5 +01:30', 'H Z').toDate().getUTCMinutes(), 30, 'parse hours \\'5 +01:30\\' ---> \\'H Z\\'');\n});\n\ntest('string with format (timezone offset)', function (assert) {\n    var a, b, c, d, e, f;\n    a = new Date(Date.UTC(2011, 0, 1, 1));\n    b = moment('2011 1 1 0 -01:00', 'YYYY MM DD HH Z');\n    assert.equal(a.getHours(), b.hours(), 'date created with utc == parsed string with timezone offset');\n    assert.equal(+a, +b, 'date created with utc == parsed string with timezone offset');\n    c = moment('2011 2 1 10 -05:00', 'YYYY MM DD HH Z');\n    d = moment('2011 2 1 8 -07:00', 'YYYY MM DD HH Z');\n    assert.equal(c.hours(), d.hours(), '10 am central time == 8 am pacific time');\n    e = moment.utc('Fri, 20 Jul 2012 17:15:00', 'ddd, DD MMM YYYY HH:mm:ss');\n    f = moment.utc('Fri, 20 Jul 2012 10:15:00 -0700', 'ddd, DD MMM YYYY HH:mm:ss ZZ');\n    assert.equal(e.hours(), f.hours(), 'parse timezone offset in utc');\n});\n\ntest('string with timezone around start of year', function (assert) {\n    assert.equal(moment('2000-01-01T00:00:00.000+01:00').toISOString(), '1999-12-31T23:00:00.000Z', '+1:00 around 2000');\n    assert.equal(moment('2000-01-01T00:00:00.000-01:00').toISOString(), '2000-01-01T01:00:00.000Z', '-1:00 around 2000');\n    assert.equal(moment('1970-01-01T00:00:00.000+01:00').toISOString(), '1969-12-31T23:00:00.000Z', '+1:00 around 1970');\n    assert.equal(moment('1970-01-01T00:00:00.000-01:00').toISOString(), '1970-01-01T01:00:00.000Z', '-1:00 around 1970');\n    assert.equal(moment('1200-01-01T00:00:00.000+01:00').toISOString(), '1199-12-31T23:00:00.000Z', '+1:00 around 1200');\n    assert.equal(moment('1200-01-01T00:00:00.000-01:00').toISOString(), '1200-01-01T01:00:00.000Z', '-1:00 around 1200');\n});\n\ntest('string with array of formats', function (assert) {\n    var thursdayForCurrentWeek = moment()\n      .day(4)\n      .format('YYYY MM DD');\n\n    assert.equal(moment('11-02-1999', ['MM-DD-YYYY', 'DD-MM-YYYY']).format('MM DD YYYY'), '11 02 1999', 'switching month and day');\n    assert.equal(moment('02-11-1999', ['MM/DD/YYYY', 'YYYY MM DD', 'MM-DD-YYYY']).format('MM DD YYYY'), '02 11 1999', 'year last');\n    assert.equal(moment('1999-02-11', ['MM/DD/YYYY', 'YYYY MM DD', 'MM-DD-YYYY']).format('MM DD YYYY'), '02 11 1999', 'year first');\n\n    assert.equal(moment('02-11-1999', ['MM/DD/YYYY', 'YYYY MM DD']).format('MM DD YYYY'), '02 11 1999', 'year last');\n    assert.equal(moment('1999-02-11', ['MM/DD/YYYY', 'YYYY MM DD']).format('MM DD YYYY'), '02 11 1999', 'year first');\n    assert.equal(moment('02-11-1999', ['YYYY MM DD', 'MM/DD/YYYY']).format('MM DD YYYY'), '02 11 1999', 'year last');\n    assert.equal(moment('1999-02-11', ['YYYY MM DD', 'MM/DD/YYYY']).format('MM DD YYYY'), '02 11 1999', 'year first');\n\n    assert.equal(moment('13-11-1999', ['MM/DD/YYYY', 'DD/MM/YYYY']).format('MM DD YYYY'), '11 13 1999', 'second must be month');\n    assert.equal(moment('11-13-1999', ['MM/DD/YYYY', 'DD/MM/YYYY']).format('MM DD YYYY'), '11 13 1999', 'first must be month');\n    assert.equal(moment('01-02-2000', ['MM/DD/YYYY', 'DD/MM/YYYY']).format('MM DD YYYY'), '01 02 2000', 'either can be a month, month first format');\n    assert.equal(moment('02-01-2000', ['DD/MM/YYYY', 'MM/DD/YYYY']).format('MM DD YYYY'), '01 02 2000', 'either can be a month, day first format');\n\n    assert.equal(moment('11-02-10', ['MM/DD/YY', 'YY MM DD', 'DD-MM-YY']).format('MM DD YYYY'), '02 11 2010', 'all unparsed substrings have influence on format penalty');\n    assert.equal(moment('11-02-10', ['MM-DD-YY HH:mm', 'YY MM DD']).format('MM DD YYYY'), '02 10 2011', 'prefer formats without extra tokens');\n    assert.equal(moment('11-02-10 junk', ['MM-DD-YY', 'YY.MM.DD [junk]']).format('MM DD YYYY'), '02 10 2011', 'prefer formats that dont result in extra characters');\n    assert.equal(moment('11-22-10', ['YY-MM-DD', 'YY-DD-MM']).format('MM DD YYYY'), '10 22 2011', 'prefer valid results');\n\n    assert.equal(moment('gibberish', ['YY-MM-DD', 'YY-DD-MM']).format('MM DD YYYY'), 'Invalid date', 'doest throw for invalid strings');\n    assert.equal(moment('gibberish', []).format('MM DD YYYY'), 'Invalid date', 'doest throw for an empty array');\n\n    // https://github.com/moment/moment/issues/1143\n    assert.equal(moment(\n        'System Administrator and Database Assistant (7/1/2011), System Administrator and Database Assistant (7/1/2011), Database Coordinator (7/1/2011), Vice President (7/1/2011), System Administrator and Database Assistant (5/31/2012), Database Coordinator (7/1/2012), System Administrator and Database Assistant (7/1/2013)',\n        ['MM/DD/YYYY', 'MM-DD-YYYY', 'YYYY-MM-DD', 'YYYY-MM-DDTHH:mm:ssZ'])\n        .format('YYYY-MM-DD'), '2011-07-01', 'Works for long strings');\n\n    assert.equal(moment('11-02-10', ['MM.DD.YY', 'DD-MM-YY']).format('MM DD YYYY'), '02 11 2010', 'escape RegExp special characters on comparing');\n\n    assert.equal(moment('13-10-98', ['DD MM YY', 'DD MM YYYY'])._f, 'DD MM YY', 'use two digit year');\n    assert.equal(moment('13-10-1998', ['DD MM YY', 'DD MM YYYY'])._f, 'DD MM YYYY', 'use four digit year');\n\n    assert.equal(moment('01', ['MM', 'DD'])._f, 'MM', 'Should use first valid format');\n\n    assert.equal(moment('Thursday 8:30pm', ['dddd h:mma']).format('YYYY MM DD dddd h:mma'), thursdayForCurrentWeek + ' Thursday 8:30pm', 'Default to current week');\n});\n\ntest('string with array of formats + ISO', function (assert) {\n    assert.equal(moment('1994', [moment.ISO_8601, 'MM', 'HH:mm', 'YYYY']).year(), 1994, 'iso: assert parse YYYY');\n    assert.equal(moment('17:15', [moment.ISO_8601, 'MM', 'HH:mm', 'YYYY']).hour(), 17, 'iso: assert parse HH:mm (1)');\n    assert.equal(moment('24:15', [moment.ISO_8601, 'MM', 'kk:mm', 'YYYY']).hour(), 0, 'iso: assert parse kk:mm');\n    assert.equal(moment('17:15', [moment.ISO_8601, 'MM', 'HH:mm', 'YYYY']).minutes(), 15, 'iso: assert parse HH:mm (2)');\n    assert.equal(moment('06', [moment.ISO_8601, 'MM', 'HH:mm', 'YYYY']).month(), 6 - 1, 'iso: assert parse MM');\n    assert.equal(moment('2012-06-01', [moment.ISO_8601, 'MM', 'HH:mm', 'YYYY']).parsingFlags().iso, true, 'iso: assert parse iso');\n    assert.equal(moment('2014-05-05', [moment.ISO_8601, 'YYYY-MM-DD']).parsingFlags().iso, true, 'iso: edge case array precedence iso');\n    assert.equal(moment('2014-05-05', ['YYYY-MM-DD', moment.ISO_8601]).parsingFlags().iso, false, 'iso: edge case array precedence not iso');\n});\n\ntest('string with format - years', function (assert) {\n    assert.equal(moment('67', 'YY').format('YYYY'), '2067', '67 > 2067');\n    assert.equal(moment('68', 'YY').format('YYYY'), '2068', '68 > 2068');\n    assert.equal(moment('69', 'YY').format('YYYY'), '1969', '69 > 1969');\n    assert.equal(moment('70', 'YY').format('YYYY'), '1970', '70 > 1970');\n});\n\ntest('implicit cloning', function (assert) {\n    var momentA = moment([2011, 10, 10]),\n    momentB = moment(momentA);\n    momentA.month(5);\n    assert.equal(momentB.month(), 10, 'Calling moment() on a moment will create a clone');\n    assert.equal(momentA.month(), 5, 'Calling moment() on a moment will create a clone');\n});\n\ntest('explicit cloning', function (assert) {\n    var momentA = moment([2011, 10, 10]),\n    momentB = momentA.clone();\n    momentA.month(5);\n    assert.equal(momentB.month(), 10, 'Calling moment() on a moment will create a clone');\n    assert.equal(momentA.month(), 5, 'Calling moment() on a moment will create a clone');\n});\n\ntest('cloning carrying over utc mode', function (assert) {\n    assert.equal(moment().local().clone()._isUTC, false, 'An explicit cloned local moment should have _isUTC == false');\n    assert.equal(moment().utc().clone()._isUTC, true, 'An cloned utc moment should have _isUTC == true');\n    assert.equal(moment().clone()._isUTC, false, 'An explicit cloned local moment should have _isUTC == false');\n    assert.equal(moment.utc().clone()._isUTC, true, 'An explicit cloned utc moment should have _isUTC == true');\n    assert.equal(moment(moment().local())._isUTC, false, 'An implicit cloned local moment should have _isUTC == false');\n    assert.equal(moment(moment().utc())._isUTC, true, 'An implicit cloned utc moment should have _isUTC == true');\n    assert.equal(moment(moment())._isUTC, false, 'An implicit cloned local moment should have _isUTC == false');\n    assert.equal(moment(moment.utc())._isUTC, true, 'An implicit cloned utc moment should have _isUTC == true');\n});\n\ntest('parsing RFC 2822', function (assert) {\n    var testCases = {\n        'clean RFC2822 datetime with all options': 'Tue, 01 Nov 2016 01:23:45 UT',\n        'clean RFC2822 datetime without comma': 'Tue 01 Nov 2016 02:23:45 GMT',\n        'clean RFC2822 datetime without seconds': 'Tue, 01 Nov 2016 03:23 +0000',\n        'clean RFC2822 datetime without century': 'Tue, 01 Nov 16 04:23:45 Z',\n        'clean RFC2822 datetime without day': '01 Nov 2016 05:23:45 z',\n        'clean RFC2822 datetime with single-digit day-of-month': 'Tue, 1 Nov 2016 06:23:45 GMT',\n        'RFC2822 datetime with CFWSs': '(Init Comment) Tue,\\n 1 Nov              2016 (Split\\n Comment)  07:23:45 +0000 (GMT)'\n    };\n    var testCase;\n\n    for (testCase in testCases) {\n        var testResult = moment(testCases[testCase], moment.RFC_2822, true);\n        assert.ok(testResult.isValid(), testResult);\n        assert.ok(testResult.parsingFlags().rfc2822, testResult + ' - rfc2822 parsingFlag');\n    }\n});\n\ntest('non RFC 2822 strings', function (assert) {\n    var testCases = {\n        'RFC2822 datetime with all options but invalid day delimiter': 'Tue. 01 Nov 2016 01:23:45 GMT',\n        'RFC2822 datetime with mismatching Day (week v date)': 'Mon, 01 Nov 2016 01:23:45 GMT'\n    };\n    var testCase;\n\n    for (testCase in testCases) {\n        var testResult = moment(testCases[testCase], moment.RFC_2822, true);\n        assert.ok(!testResult.isValid(), testResult);\n        assert.ok(!testResult.parsingFlags().rfc2822, testResult + ' - rfc2822 parsingFlag');\n    }\n});\n\ntest('parsing iso', function (assert) {\n    var offset = moment([2011, 9, 8]).utcOffset(),\n    pad = function (input) {\n        if (input < 10) {\n            return '0' + input;\n        }\n        return '' + input;\n    },\n    hourOffset = (offset > 0 ? Math.floor(offset / 60) : Math.ceil(offset / 60)),\n    minOffset = offset - (hourOffset * 60),\n    tz = (offset >= 0) ?\n        '+' + pad(hourOffset) + ':' + pad(minOffset) :\n        '-' + pad(-hourOffset) + ':' + pad(-minOffset),\n    tz2 = tz.replace(':', ''),\n    tz3 = tz2.slice(0, 3),\n    //Tz3 removes minutes digit so will break the tests when parsed if they all use the same minutes digit\n    minutesForTz3 = pad((4 + minOffset) % 60),\n    minute = pad(4 + minOffset),\n\n    formats = [\n        ['2011-10-08',                    '2011-10-08T00:00:00.000' + tz],\n        ['2011-10-08T18',                 '2011-10-08T18:00:00.000' + tz],\n        ['2011-10-08T18:04',              '2011-10-08T18:04:00.000' + tz],\n        ['2011-10-08T18:04:20',           '2011-10-08T18:04:20.000' + tz],\n        ['2011-10-08T18:04' + tz,         '2011-10-08T18:04:00.000' + tz],\n        ['2011-10-08T18:04:20' + tz,      '2011-10-08T18:04:20.000' + tz],\n        ['2011-10-08T18:04' + tz2,        '2011-10-08T18:04:00.000' + tz],\n        ['2011-10-08T18:04:20' + tz2,     '2011-10-08T18:04:20.000' + tz],\n        ['2011-10-08T18:04' + tz3,        '2011-10-08T18:' + minutesForTz3 + ':00.000' + tz],\n        ['2011-10-08T18:04:20' + tz3,     '2011-10-08T18:' + minutesForTz3 + ':20.000' + tz],\n        ['2011-10-08T18:04:20.1' + tz2,   '2011-10-08T18:04:20.100' + tz],\n        ['2011-10-08T18:04:20.11' + tz2,  '2011-10-08T18:04:20.110' + tz],\n        ['2011-10-08T18:04:20.111' + tz2, '2011-10-08T18:04:20.111' + tz],\n        ['2011-10-08 18',                 '2011-10-08T18:00:00.000' + tz],\n        ['2011-10-08 18:04',              '2011-10-08T18:04:00.000' + tz],\n        ['2011-10-08 18:04:20',           '2011-10-08T18:04:20.000' + tz],\n        ['2011-10-08 18:04' + tz,         '2011-10-08T18:04:00.000' + tz],\n        ['2011-10-08 18:04:20' + tz,      '2011-10-08T18:04:20.000' + tz],\n        ['2011-10-08 18:04' + tz2,        '2011-10-08T18:04:00.000' + tz],\n        ['2011-10-08 18:04:20' + tz2,     '2011-10-08T18:04:20.000' + tz],\n        ['2011-10-08 18:04' + tz3,        '2011-10-08T18:' + minutesForTz3 + ':00.000' + tz],\n        ['2011-10-08 18:04:20' + tz3,     '2011-10-08T18:' + minutesForTz3 + ':20.000' + tz],\n        ['2011-10-08 18:04:20.1' + tz2,   '2011-10-08T18:04:20.100' + tz],\n        ['2011-10-08 18:04:20.11' + tz2,  '2011-10-08T18:04:20.110' + tz],\n        ['2011-10-08 18:04:20.111' + tz2, '2011-10-08T18:04:20.111' + tz],\n        ['2011-W40',                      '2011-10-03T00:00:00.000' + tz],\n        ['2011-W40-6',                    '2011-10-08T00:00:00.000' + tz],\n        ['2011-W40-6T18',                 '2011-10-08T18:00:00.000' + tz],\n        ['2011-W40-6T18:04',              '2011-10-08T18:04:00.000' + tz],\n        ['2011-W40-6T18:04:20',           '2011-10-08T18:04:20.000' + tz],\n        ['2011-W40-6T18:04' + tz,         '2011-10-08T18:04:00.000' + tz],\n        ['2011-W40-6T18:04:20' + tz,      '2011-10-08T18:04:20.000' + tz],\n        ['2011-W40-6T18:04' + tz2,        '2011-10-08T18:04:00.000' + tz],\n        ['2011-W40-6T18:04:20' + tz2,     '2011-10-08T18:04:20.000' + tz],\n        ['2011-W40-6T18:04' + tz3,        '2011-10-08T18:' + minutesForTz3 + ':00.000' + tz],\n        ['2011-W40-6T18:04:20' + tz3,     '2011-10-08T18:' + minutesForTz3 + ':20.000' + tz],\n        ['2011-W40-6T18:04:20.1' + tz2,   '2011-10-08T18:04:20.100' + tz],\n        ['2011-W40-6T18:04:20.11' + tz2,  '2011-10-08T18:04:20.110' + tz],\n        ['2011-W40-6T18:04:20.111' + tz2, '2011-10-08T18:04:20.111' + tz],\n        ['2011-W40-6 18',                 '2011-10-08T18:00:00.000' + tz],\n        ['2011-W40-6 18:04',              '2011-10-08T18:04:00.000' + tz],\n        ['2011-W40-6 18:04:20',           '2011-10-08T18:04:20.000' + tz],\n        ['2011-W40-6 18:04' + tz,         '2011-10-08T18:04:00.000' + tz],\n        ['2011-W40-6 18:04:20' + tz,      '2011-10-08T18:04:20.000' + tz],\n        ['2011-W40-6 18:04' + tz2,        '2011-10-08T18:04:00.000' + tz],\n        ['2011-W40-6 18:04:20' + tz2,     '2011-10-08T18:04:20.000' + tz],\n        ['2011-W40-6 18:04' + tz3,        '2011-10-08T18:' + minutesForTz3 + ':00.000' + tz],\n        ['2011-W40-6 18:04:20' + tz3,     '2011-10-08T18:' + minutesForTz3 + ':20.000' + tz],\n        ['2011-W40-6 18:04:20.1' + tz2,   '2011-10-08T18:04:20.100' + tz],\n        ['2011-W40-6 18:04:20.11' + tz2,  '2011-10-08T18:04:20.110' + tz],\n        ['2011-W40-6 18:04:20.111' + tz2, '2011-10-08T18:04:20.111' + tz],\n        ['2011-281',                      '2011-10-08T00:00:00.000' + tz],\n        ['2011-281T18',                   '2011-10-08T18:00:00.000' + tz],\n        ['2011-281T18:04',                '2011-10-08T18:04:00.000' + tz],\n        ['2011-281T18:04:20',             '2011-10-08T18:04:20.000' + tz],\n        ['2011-281T18:04' + tz,           '2011-10-08T18:04:00.000' + tz],\n        ['2011-281T18:04:20' + tz,        '2011-10-08T18:04:20.000' + tz],\n        ['2011-281T18:04' + tz2,          '2011-10-08T18:04:00.000' + tz],\n        ['2011-281T18:04:20' + tz2,       '2011-10-08T18:04:20.000' + tz],\n        ['2011-281T18:04' + tz3,          '2011-10-08T18:' + minutesForTz3 + ':00.000' + tz],\n        ['2011-281T18:04:20' + tz3,       '2011-10-08T18:' + minutesForTz3 + ':20.000' + tz],\n        ['2011-281T18:04:20.1' + tz2,     '2011-10-08T18:04:20.100' + tz],\n        ['2011-281T18:04:20.11' + tz2,    '2011-10-08T18:04:20.110' + tz],\n        ['2011-281T18:04:20.111' + tz2,   '2011-10-08T18:04:20.111' + tz],\n        ['2011-281 18',                   '2011-10-08T18:00:00.000' + tz],\n        ['2011-281 18:04',                '2011-10-08T18:04:00.000' + tz],\n        ['2011-281 18:04:20',             '2011-10-08T18:04:20.000' + tz],\n        ['2011-281 18:04' + tz,           '2011-10-08T18:04:00.000' + tz],\n        ['2011-281 18:04:20' + tz,        '2011-10-08T18:04:20.000' + tz],\n        ['2011-281 18:04' + tz2,          '2011-10-08T18:04:00.000' + tz],\n        ['2011-281 18:04:20' + tz2,       '2011-10-08T18:04:20.000' + tz],\n        ['2011-281 18:04' + tz3,          '2011-10-08T18:' + minutesForTz3 + ':00.000' + tz],\n        ['2011-281 18:04:20' + tz3,       '2011-10-08T18:' + minutesForTz3 + ':20.000' + tz],\n        ['2011-281 18:04:20.1' + tz2,     '2011-10-08T18:04:20.100' + tz],\n        ['2011-281 18:04:20.11' + tz2,    '2011-10-08T18:04:20.110' + tz],\n        ['2011-281 18:04:20.111' + tz2,   '2011-10-08T18:04:20.111' + tz],\n        ['20111008T18',                   '2011-10-08T18:00:00.000' + tz],\n        ['20111008T1804',                 '2011-10-08T18:04:00.000' + tz],\n        ['20111008T180420',               '2011-10-08T18:04:20.000' + tz],\n        ['20111008T1804' + tz,            '2011-10-08T18:04:00.000' + tz],\n        ['20111008T180420' + tz,          '2011-10-08T18:04:20.000' + tz],\n        ['20111008T1804' + tz2,           '2011-10-08T18:04:00.000' + tz],\n        ['20111008T180420' + tz2,         '2011-10-08T18:04:20.000' + tz],\n        ['20111008T1804' + tz3,           '2011-10-08T18:' + minutesForTz3 + ':00.000' + tz],\n        ['20111008T180420' + tz3,         '2011-10-08T18:' + minutesForTz3 + ':20.000' + tz],\n        ['20111008T180420,1' + tz2,       '2011-10-08T18:04:20.100' + tz],\n        ['20111008T180420,11' + tz2,      '2011-10-08T18:04:20.110' + tz],\n        ['20111008T180420,111' + tz2,     '2011-10-08T18:04:20.111' + tz],\n        ['20111008 18',                   '2011-10-08T18:00:00.000' + tz],\n        ['20111008 1804',                 '2011-10-08T18:04:00.000' + tz],\n        ['20111008 180420',               '2011-10-08T18:04:20.000' + tz],\n        ['20111008 1804' + tz,            '2011-10-08T18:04:00.000' + tz],\n        ['20111008 180420' + tz,          '2011-10-08T18:04:20.000' + tz],\n        ['20111008 1804' + tz2,           '2011-10-08T18:04:00.000' + tz],\n        ['20111008 180420' + tz2,         '2011-10-08T18:04:20.000' + tz],\n        ['20111008 1804' + tz3,           '2011-10-08T18:' + minutesForTz3 + ':00.000' + tz],\n        ['20111008 180420' + tz3,         '2011-10-08T18:' + minutesForTz3 + ':20.000' + tz],\n        ['20111008 180420,1' + tz2,       '2011-10-08T18:04:20.100' + tz],\n        ['20111008 180420,11' + tz2,      '2011-10-08T18:04:20.110' + tz],\n        ['20111008 180420,111' + tz2,     '2011-10-08T18:04:20.111' + tz],\n        ['2011W40',                       '2011-10-03T00:00:00.000' + tz],\n        ['2011W406',                      '2011-10-08T00:00:00.000' + tz],\n        ['2011W406T18',                   '2011-10-08T18:00:00.000' + tz],\n        ['2011W406T1804',                 '2011-10-08T18:04:00.000' + tz],\n        ['2011W406T180420',               '2011-10-08T18:04:20.000' + tz],\n        ['2011W406 1804' + tz2,           '2011-10-08T18:04:00.000' + tz],\n        ['2011W406T1804' + tz,            '2011-10-08T18:04:00.000' + tz],\n        ['2011W406T180420' + tz,          '2011-10-08T18:04:20.000' + tz],\n        ['2011W406T1804' + tz2,           '2011-10-08T18:04:00.000' + tz],\n        ['2011W406T180420' + tz2,         '2011-10-08T18:04:20.000' + tz],\n        ['2011W406T1804' + tz3,           '2011-10-08T18:' + minutesForTz3 + ':00.000' + tz],\n        ['2011W406T180420' + tz3,         '2011-10-08T18:' + minutesForTz3 + ':20.000' + tz],\n        ['2011W406T180420,1' + tz2,       '2011-10-08T18:04:20.100' + tz],\n        ['2011W406T180420,11' + tz2,      '2011-10-08T18:04:20.110' + tz],\n        ['2011W406T180420,111' + tz2,     '2011-10-08T18:04:20.111' + tz],\n        ['2011W406 18',                   '2011-10-08T18:00:00.000' + tz],\n        ['2011W406 1804',                 '2011-10-08T18:04:00.000' + tz],\n        ['2011W406 180420',               '2011-10-08T18:04:20.000' + tz],\n        ['2011W406 1804' + tz,            '2011-10-08T18:04:00.000' + tz],\n        ['2011W406 180420' + tz,          '2011-10-08T18:04:20.000' + tz],\n        ['2011W406 180420' + tz2,         '2011-10-08T18:04:20.000' + tz],\n        ['2011W406 1804' + tz3,           '2011-10-08T18:' + minutesForTz3 + ':00.000' + tz],\n        ['2011W406 180420' + tz3,         '2011-10-08T18:' + minutesForTz3 + ':20.000' + tz],\n        ['2011W406 180420,1' + tz2,       '2011-10-08T18:04:20.100' + tz],\n        ['2011W406 180420,11' + tz2,      '2011-10-08T18:04:20.110' + tz],\n        ['2011W406 180420,111' + tz2,     '2011-10-08T18:04:20.111' + tz],\n        ['2011281',                       '2011-10-08T00:00:00.000' + tz],\n        ['2011281T18',                    '2011-10-08T18:00:00.000' + tz],\n        ['2011281T1804',                  '2011-10-08T18:04:00.000' + tz],\n        ['2011281T180420',                '2011-10-08T18:04:20.000' + tz],\n        ['2011281T1804' + tz,             '2011-10-08T18:04:00.000' + tz],\n        ['2011281T180420' + tz,           '2011-10-08T18:04:20.000' + tz],\n        ['2011281T1804' + tz2,            '2011-10-08T18:04:00.000' + tz],\n        ['2011281T180420' + tz2,          '2011-10-08T18:04:20.000' + tz],\n        ['2011281T1804' + tz3,            '2011-10-08T18:' + minutesForTz3 + ':00.000' + tz],\n        ['2011281T180420' + tz3,          '2011-10-08T18:' + minutesForTz3 + ':20.000' + tz],\n        ['2011281T180420,1' + tz2,        '2011-10-08T18:04:20.100' + tz],\n        ['2011281T180420,11' + tz2,       '2011-10-08T18:04:20.110' + tz],\n        ['2011281T180420,111' + tz2,      '2011-10-08T18:04:20.111' + tz],\n        ['2011281 18',                    '2011-10-08T18:00:00.000' + tz],\n        ['2011281 1804',                  '2011-10-08T18:04:00.000' + tz],\n        ['2011281 180420',                '2011-10-08T18:04:20.000' + tz],\n        ['2011281 1804' + tz,             '2011-10-08T18:04:00.000' + tz],\n        ['2011281 180420' + tz,           '2011-10-08T18:04:20.000' + tz],\n        ['2011281 1804' + tz2,            '2011-10-08T18:04:00.000' + tz],\n        ['2011281 180420' + tz2,          '2011-10-08T18:04:20.000' + tz],\n        ['2011281 1804' + tz3,            '2011-10-08T18:' + minutesForTz3 + ':00.000' + tz],\n        ['2011281 180420' + tz3,          '2011-10-08T18:' + minutesForTz3 + ':20.000' + tz],\n        ['2011281 180420,1' + tz2,        '2011-10-08T18:04:20.100' + tz],\n        ['2011281 180420,11' + tz2,       '2011-10-08T18:04:20.110' + tz],\n        ['2011281 180420,111' + tz2,      '2011-10-08T18:04:20.111' + tz]\n    ], i;\n    for (i = 0; i < formats.length; i++) {\n        assert.equal(moment(formats[i][0]).format('YYYY-MM-DDTHH:mm:ss.SSSZ'),\n                formats[i][1], 'moment should be able to parse ISO ' + formats[i][0]);\n        assert.equal(moment(formats[i][0], moment.ISO_8601).format('YYYY-MM-DDTHH:mm:ss.SSSZ'),\n                formats[i][1], 'moment should be able to parse specified ISO ' + formats[i][0]);\n        assert.equal(moment(formats[i][0], moment.ISO_8601, true).format('YYYY-MM-DDTHH:mm:ss.SSSZ'),\n                formats[i][1], 'moment should be able to parse specified strict ISO ' + formats[i][0]);\n    }\n});\n\ntest('non iso 8601 strings', function (assert) {\n    assert.ok(!moment('2015-10T10:15', moment.ISO_8601, true).isValid(), 'incomplete date with time');\n    assert.ok(!moment('2015-W10T10:15', moment.ISO_8601, true).isValid(), 'incomplete week date with time');\n    assert.ok(!moment('201510', moment.ISO_8601, true).isValid(), 'basic YYYYMM is not allowed');\n    assert.ok(!moment('2015W10T1015', moment.ISO_8601, true).isValid(), 'incomplete week date with time (basic)');\n    assert.ok(!moment('2015-10-08T1015', moment.ISO_8601, true).isValid(), 'mixing extended and basic format');\n    assert.ok(!moment('20151008T10:15', moment.ISO_8601, true).isValid(), 'mixing basic and extended format');\n    assert.ok(!moment('2015-10-1', moment.ISO_8601, true).isValid(), 'missing zero padding for day');\n});\n\ntest('parsing iso week year/week/weekday', function (assert) {\n    assert.equal(moment.utc('2007-W01').format(), '2007-01-01T00:00:00Z', '2008 week 1 (1st Jan Mon)');\n    assert.equal(moment.utc('2008-W01').format(), '2007-12-31T00:00:00Z', '2008 week 1 (1st Jan Tue)');\n    assert.equal(moment.utc('2003-W01').format(), '2002-12-30T00:00:00Z', '2008 week 1 (1st Jan Wed)');\n    assert.equal(moment.utc('2009-W01').format(), '2008-12-29T00:00:00Z', '2009 week 1 (1st Jan Thu)');\n    assert.equal(moment.utc('2010-W01').format(), '2010-01-04T00:00:00Z', '2010 week 1 (1st Jan Fri)');\n    assert.equal(moment.utc('2011-W01').format(), '2011-01-03T00:00:00Z', '2011 week 1 (1st Jan Sat)');\n    assert.equal(moment.utc('2012-W01').format(), '2012-01-02T00:00:00Z', '2012 week 1 (1st Jan Sun)');\n});\n\ntest('parsing week year/week/weekday (dow 1, doy 4)', function (assert) {\n    moment.locale('dow:1,doy:4', {week: {dow: 1, doy: 4}});\n\n    assert.equal(moment.utc('2007-01', 'gggg-ww').format(), '2007-01-01T00:00:00Z', '2007 week 1 (1st Jan Mon)');\n    assert.equal(moment.utc('2008-01', 'gggg-ww').format(), '2007-12-31T00:00:00Z', '2008 week 1 (1st Jan Tue)');\n    assert.equal(moment.utc('2003-01', 'gggg-ww').format(), '2002-12-30T00:00:00Z', '2003 week 1 (1st Jan Wed)');\n    assert.equal(moment.utc('2009-01', 'gggg-ww').format(), '2008-12-29T00:00:00Z', '2009 week 1 (1st Jan Thu)');\n    assert.equal(moment.utc('2010-01', 'gggg-ww').format(), '2010-01-04T00:00:00Z', '2010 week 1 (1st Jan Fri)');\n    assert.equal(moment.utc('2011-01', 'gggg-ww').format(), '2011-01-03T00:00:00Z', '2011 week 1 (1st Jan Sat)');\n    assert.equal(moment.utc('2012-01', 'gggg-ww').format(), '2012-01-02T00:00:00Z', '2012 week 1 (1st Jan Sun)');\n\n    moment.defineLocale('dow:1,doy:4', null);\n});\n\ntest('parsing week year/week/weekday (dow 1, doy 7)', function (assert) {\n    moment.locale('dow:1,doy:7', {week: {dow: 1, doy: 7}});\n\n    assert.equal(moment.utc('2007-01', 'gggg-ww').format(), '2007-01-01T00:00:00Z', '2007 week 1 (1st Jan Mon)');\n    assert.equal(moment.utc('2008-01', 'gggg-ww').format(), '2007-12-31T00:00:00Z', '2008 week 1 (1st Jan Tue)');\n    assert.equal(moment.utc('2003-01', 'gggg-ww').format(), '2002-12-30T00:00:00Z', '2003 week 1 (1st Jan Wed)');\n    assert.equal(moment.utc('2009-01', 'gggg-ww').format(), '2008-12-29T00:00:00Z', '2009 week 1 (1st Jan Thu)');\n    assert.equal(moment.utc('2010-01', 'gggg-ww').format(), '2009-12-28T00:00:00Z', '2010 week 1 (1st Jan Fri)');\n    assert.equal(moment.utc('2011-01', 'gggg-ww').format(), '2010-12-27T00:00:00Z', '2011 week 1 (1st Jan Sat)');\n    assert.equal(moment.utc('2012-01', 'gggg-ww').format(), '2011-12-26T00:00:00Z', '2012 week 1 (1st Jan Sun)');\n    moment.defineLocale('dow:1,doy:7', null);\n});\n\ntest('parsing week year/week/weekday (dow 0, doy 6)', function (assert) {\n    moment.locale('dow:0,doy:6', {week: {dow: 0, doy: 6}});\n\n    assert.equal(moment.utc('2007-01', 'gggg-ww').format(), '2006-12-31T00:00:00Z', '2007 week 1 (1st Jan Mon)');\n    assert.equal(moment.utc('2008-01', 'gggg-ww').format(), '2007-12-30T00:00:00Z', '2008 week 1 (1st Jan Tue)');\n    assert.equal(moment.utc('2003-01', 'gggg-ww').format(), '2002-12-29T00:00:00Z', '2003 week 1 (1st Jan Wed)');\n    assert.equal(moment.utc('2009-01', 'gggg-ww').format(), '2008-12-28T00:00:00Z', '2009 week 1 (1st Jan Thu)');\n    assert.equal(moment.utc('2010-01', 'gggg-ww').format(), '2009-12-27T00:00:00Z', '2010 week 1 (1st Jan Fri)');\n    assert.equal(moment.utc('2011-01', 'gggg-ww').format(), '2010-12-26T00:00:00Z', '2011 week 1 (1st Jan Sat)');\n    assert.equal(moment.utc('2012-01', 'gggg-ww').format(), '2012-01-01T00:00:00Z', '2012 week 1 (1st Jan Sun)');\n    moment.defineLocale('dow:0,doy:6', null);\n});\n\ntest('parsing week year/week/weekday (dow 6, doy 12)', function (assert) {\n    moment.locale('dow:6,doy:12', {week: {dow: 6, doy: 12}});\n\n    assert.equal(moment.utc('2007-01', 'gggg-ww').format(), '2006-12-30T00:00:00Z', '2007 week 1 (1st Jan Mon)');\n    assert.equal(moment.utc('2008-01', 'gggg-ww').format(), '2007-12-29T00:00:00Z', '2008 week 1 (1st Jan Tue)');\n    assert.equal(moment.utc('2003-01', 'gggg-ww').format(), '2002-12-28T00:00:00Z', '2003 week 1 (1st Jan Wed)');\n    assert.equal(moment.utc('2009-01', 'gggg-ww').format(), '2008-12-27T00:00:00Z', '2009 week 1 (1st Jan Thu)');\n    assert.equal(moment.utc('2010-01', 'gggg-ww').format(), '2009-12-26T00:00:00Z', '2010 week 1 (1st Jan Fri)');\n    assert.equal(moment.utc('2011-01', 'gggg-ww').format(), '2011-01-01T00:00:00Z', '2011 week 1 (1st Jan Sat)');\n    assert.equal(moment.utc('2012-01', 'gggg-ww').format(), '2011-12-31T00:00:00Z', '2012 week 1 (1st Jan Sun)');\n    moment.defineLocale('dow:6,doy:12', null);\n});\n\ntest('parsing ISO with Z', function (assert) {\n    var i, mom, formats = [\n        ['2011-10-08T18:04',             '2011-10-08T18:04:00.000'],\n        ['2011-10-08T18:04:20',          '2011-10-08T18:04:20.000'],\n        ['2011-10-08T18:04:20.1',        '2011-10-08T18:04:20.100'],\n        ['2011-10-08T18:04:20.11',       '2011-10-08T18:04:20.110'],\n        ['2011-10-08T18:04:20.111',      '2011-10-08T18:04:20.111'],\n        ['2011-W40-6T18',                '2011-10-08T18:00:00.000'],\n        ['2011-W40-6T18:04',             '2011-10-08T18:04:00.000'],\n        ['2011-W40-6T18:04:20',          '2011-10-08T18:04:20.000'],\n        ['2011-W40-6T18:04:20.1',        '2011-10-08T18:04:20.100'],\n        ['2011-W40-6T18:04:20.11',       '2011-10-08T18:04:20.110'],\n        ['2011-W40-6T18:04:20.111',      '2011-10-08T18:04:20.111'],\n        ['2011-281T18',                  '2011-10-08T18:00:00.000'],\n        ['2011-281T18:04',               '2011-10-08T18:04:00.000'],\n        ['2011-281T18:04:20',            '2011-10-08T18:04:20.000'],\n        ['2011-281T18:04:20',            '2011-10-08T18:04:20.000'],\n        ['2011-281T18:04:20.1',          '2011-10-08T18:04:20.100'],\n        ['2011-281T18:04:20.11',         '2011-10-08T18:04:20.110'],\n        ['2011-281T18:04:20.111',        '2011-10-08T18:04:20.111']\n    ];\n\n    for (i = 0; i < formats.length; i++) {\n        mom = moment(formats[i][0] + 'Z').utc();\n        assert.equal(mom.format('YYYY-MM-DDTHH:mm:ss.SSS'), formats[i][1], 'moment should be able to parse ISO in UTC ' + formats[i][0] + 'Z');\n\n        mom = moment(formats[i][0] + ' Z').utc();\n        assert.equal(mom.format('YYYY-MM-DDTHH:mm:ss.SSS'), formats[i][1], 'moment should be able to parse ISO in UTC ' + formats[i][0] + ' Z');\n    }\n});\n\ntest('parsing iso with T', function (assert) {\n    assert.equal(moment('2011-10-08T18')._f, 'YYYY-MM-DDTHH', 'should include \\'T\\' in the format');\n    assert.equal(moment('2011-10-08T18:20')._f, 'YYYY-MM-DDTHH:mm', 'should include \\'T\\' in the format');\n    assert.equal(moment('2011-10-08T18:20:13')._f, 'YYYY-MM-DDTHH:mm:ss', 'should include \\'T\\' in the format');\n    assert.equal(moment('2011-10-08T18:20:13.321')._f, 'YYYY-MM-DDTHH:mm:ss.SSSS', 'should include \\'T\\' in the format');\n\n    assert.equal(moment('2011-10-08 18')._f, 'YYYY-MM-DD HH', 'should not include \\'T\\' in the format');\n    assert.equal(moment('2011-10-08 18:20')._f, 'YYYY-MM-DD HH:mm', 'should not include \\'T\\' in the format');\n    assert.equal(moment('2011-10-08 18:20:13')._f, 'YYYY-MM-DD HH:mm:ss', 'should not include \\'T\\' in the format');\n    assert.equal(moment('2011-10-08 18:20:13.321')._f, 'YYYY-MM-DD HH:mm:ss.SSSS', 'should not include \\'T\\' in the format');\n});\n\ntest('parsing iso Z timezone', function (assert) {\n    var i,\n    formats = [\n        ['2011-10-08T18:04Z',             '2011-10-08T18:04:00.000+00:00'],\n        ['2011-10-08T18:04:20Z',          '2011-10-08T18:04:20.000+00:00'],\n        ['2011-10-08T18:04:20.111Z',      '2011-10-08T18:04:20.111+00:00']\n    ];\n    for (i = 0; i < formats.length; i++) {\n        assert.equal(moment.utc(formats[i][0]).format('YYYY-MM-DDTHH:mm:ss.SSSZ'), formats[i][1], 'moment should be able to parse ISO ' + formats[i][0]);\n    }\n});\n\ntest('parsing iso Z timezone into local', function (assert) {\n    var m = moment('2011-10-08T18:04:20.111Z');\n\n    assert.equal(m.utc().format('YYYY-MM-DDTHH:mm:ss.SSS'), '2011-10-08T18:04:20.111', 'moment should be able to parse ISO 2011-10-08T18:04:20.111Z');\n});\n\ntest('parsing iso with more subsecond precision digits', function (assert) {\n    assert.equal(moment.utc('2013-07-31T22:00:00.0000000Z').format(), '2013-07-31T22:00:00Z', 'more than 3 subsecond digits');\n});\n\ntest('null or empty', function (assert) {\n    assert.equal(moment('').isValid(), false, 'moment(\\'\\') is not valid');\n    assert.equal(moment(null).isValid(), false, 'moment(null) is not valid');\n    assert.equal(moment(null, 'YYYY-MM-DD').isValid(), false, 'moment(\\'\\', \\'format\\') is not valid');\n    assert.equal(moment('', 'YYYY-MM-DD').isValid(), false, 'moment(\\'\\', \\'format\\') is not valid');\n    assert.equal(moment.utc('').isValid(), false, 'moment.utc(\\'\\') is not valid');\n    assert.equal(moment.utc(null).isValid(), false, 'moment.utc(null) is not valid');\n    assert.equal(moment.utc(null, 'YYYY-MM-DD').isValid(), false, 'moment.utc(null) is not valid');\n    assert.equal(moment.utc('', 'YYYY-MM-DD').isValid(), false, 'moment.utc(\\'\\', \\'YYYY-MM-DD\\') is not valid');\n});\n\ntest('first century', function (assert) {\n    assert.equal(moment([0, 0, 1]).format('YYYY-MM-DD'), '0000-01-01', 'Year AD 0');\n    assert.equal(moment([99, 0, 1]).format('YYYY-MM-DD'), '0099-01-01', 'Year AD 99');\n    assert.equal(moment([999, 0, 1]).format('YYYY-MM-DD'), '0999-01-01', 'Year AD 999');\n    assert.equal(moment('0 1 1', 'YYYY MM DD').format('YYYY-MM-DD'), '0000-01-01', 'Year AD 0');\n    assert.equal(moment('999 1 1', 'YYYY MM DD').format('YYYY-MM-DD'), '0999-01-01', 'Year AD 999');\n    assert.equal(moment('0 1 1', 'YYYYY MM DD').format('YYYYY-MM-DD'), '00000-01-01', 'Year AD 0');\n    assert.equal(moment('99 1 1', 'YYYYY MM DD').format('YYYYY-MM-DD'), '00099-01-01', 'Year AD 99');\n    assert.equal(moment('999 1 1', 'YYYYY MM DD').format('YYYYY-MM-DD'), '00999-01-01', 'Year AD 999');\n});\n\ntest('six digit years', function (assert) {\n    assert.equal(moment([-270000, 0, 1]).format('YYYYY-MM-DD'), '-270000-01-01', 'format BC 270,001');\n    assert.equal(moment([270000, 0, 1]).format('YYYYY-MM-DD'), '270000-01-01', 'format AD 270,000');\n    assert.equal(moment('-270000-01-01', 'YYYYY-MM-DD').toDate().getFullYear(), -270000, 'parse BC 270,001');\n    assert.equal(moment('270000-01-01',  'YYYYY-MM-DD').toDate().getFullYear(), 270000, 'parse AD 270,000');\n    assert.equal(moment('+270000-01-01', 'YYYYY-MM-DD').toDate().getFullYear(), 270000, 'parse AD +270,000');\n    assert.equal(moment.utc('-270000-01-01', 'YYYYY-MM-DD').toDate().getUTCFullYear(), -270000, 'parse utc BC 270,001');\n    assert.equal(moment.utc('270000-01-01',  'YYYYY-MM-DD').toDate().getUTCFullYear(), 270000, 'parse utc AD 270,000');\n    assert.equal(moment.utc('+270000-01-01', 'YYYYY-MM-DD').toDate().getUTCFullYear(), 270000, 'parse utc AD +270,000');\n});\n\ntest('negative four digit years', function (assert) {\n    assert.equal(moment('-1000-01-01', 'YYYYY-MM-DD').toDate().getFullYear(), -1000, 'parse BC 1,001');\n    assert.equal(moment.utc('-1000-01-01', 'YYYYY-MM-DD').toDate().getUTCFullYear(), -1000, 'parse utc BC 1,001');\n});\n\ntest('strict parsing', function (assert) {\n    assert.equal(moment('2014-', 'YYYY-Q', true).isValid(), false, 'fail missing quarter');\n\n    assert.equal(moment('2012-05', 'YYYY-MM', true).format('YYYY-MM'), '2012-05', 'parse correct string');\n    assert.equal(moment(' 2012-05', 'YYYY-MM', true).isValid(), false, 'fail on extra whitespace');\n    assert.equal(moment('foo 2012-05', '[foo] YYYY-MM', true).format('YYYY-MM'), '2012-05', 'handle fixed text');\n    assert.equal(moment('2012 05', 'YYYY-MM', true).isValid(), false, 'fail on different separator');\n    assert.equal(moment('2012 05', 'YYYY MM DD', true).isValid(), false, 'fail on too many tokens');\n\n    assert.equal(moment('05 30 2010', ['DD MM YYYY', 'MM DD YYYY'], true).format('MM DD YYYY'), '05 30 2010', 'array with bad date');\n    assert.equal(moment('05 30 2010', ['', 'MM DD YYYY'], true).format('MM DD YYYY'), '05 30 2010', 'array with invalid format');\n    assert.equal(moment('05 30 2010', [' DD MM YYYY', 'MM DD YYYY'], true).format('MM DD YYYY'), '05 30 2010', 'array with non-matching format');\n\n    assert.equal(moment('2010.*...', 'YYYY.*', true).isValid(), false, 'invalid format with regex chars');\n    assert.equal(moment('2010.*', 'YYYY.*', true).year(), 2010, 'valid format with regex chars');\n    assert.equal(moment('.*2010.*', '.*YYYY.*', true).year(), 2010, 'valid format with regex chars on both sides');\n\n    //strict tokens\n    assert.equal(moment('-5-05-25', 'YYYY-MM-DD', true).isValid(), false, 'invalid negative year');\n    assert.equal(moment('2-05-25', 'YYYY-MM-DD', true).isValid(), false, 'invalid one-digit year');\n    assert.equal(moment('20-05-25', 'YYYY-MM-DD', true).isValid(), false, 'invalid two-digit year');\n    assert.equal(moment('201-05-25', 'YYYY-MM-DD', true).isValid(), false, 'invalid three-digit year');\n    assert.equal(moment('2010-05-25', 'YYYY-MM-DD', true).isValid(), true, 'valid four-digit year');\n    assert.equal(moment('22010-05-25', 'YYYY-MM-DD', true).isValid(), false, 'invalid five-digit year');\n\n    assert.equal(moment('12-05-25', 'YY-MM-DD', true).isValid(), true, 'valid two-digit year');\n    assert.equal(moment('2012-05-25', 'YY-MM-DD', true).isValid(), false, 'invalid four-digit year');\n\n    assert.equal(moment('-5-05-25', 'Y-MM-DD', true).isValid(), true, 'valid negative year');\n    assert.equal(moment('2-05-25', 'Y-MM-DD', true).isValid(), true, 'valid one-digit year');\n    assert.equal(moment('20-05-25', 'Y-MM-DD', true).isValid(), true, 'valid two-digit year');\n    assert.equal(moment('201-05-25', 'Y-MM-DD', true).isValid(), true, 'valid three-digit year');\n\n    assert.equal(moment('2012-5-25', 'YYYY-M-DD', true).isValid(), true, 'valid one-digit month');\n    assert.equal(moment('2012-5-25', 'YYYY-MM-DD', true).isValid(), false, 'invalid one-digit month');\n    assert.equal(moment('2012-05-25', 'YYYY-M-DD', true).isValid(), true, 'valid one-digit month');\n    assert.equal(moment('2012-05-25', 'YYYY-MM-DD', true).isValid(), true, 'valid one-digit month');\n\n    assert.equal(moment('2012-05-2', 'YYYY-MM-D', true).isValid(), true, 'valid one-digit day');\n    assert.equal(moment('2012-05-2', 'YYYY-MM-DD', true).isValid(), false, 'invalid one-digit day');\n    assert.equal(moment('2012-05-02', 'YYYY-MM-D', true).isValid(), true, 'valid two-digit day');\n    assert.equal(moment('2012-05-02', 'YYYY-MM-DD', true).isValid(), true, 'valid two-digit day');\n\n    assert.equal(moment('+002012-05-25', 'YYYYY-MM-DD', true).isValid(), true, 'valid six-digit year');\n    assert.equal(moment('+2012-05-25', 'YYYYY-MM-DD', true).isValid(), false, 'invalid four-digit year');\n\n    //thse are kinda pointless, but they should work as expected\n    assert.equal(moment('1', 'S', true).isValid(), true, 'valid one-digit milisecond');\n    assert.equal(moment('12', 'S', true).isValid(), false, 'invalid two-digit milisecond');\n    assert.equal(moment('123', 'S', true).isValid(), false, 'invalid three-digit milisecond');\n\n    assert.equal(moment('1', 'SS', true).isValid(), false, 'invalid one-digit milisecond');\n    assert.equal(moment('12', 'SS', true).isValid(), true, 'valid two-digit milisecond');\n    assert.equal(moment('123', 'SS', true).isValid(), false, 'invalid three-digit milisecond');\n\n    assert.equal(moment('1', 'SSS', true).isValid(), false, 'invalid one-digit milisecond');\n    assert.equal(moment('12', 'SSS', true).isValid(), false, 'invalid two-digit milisecond');\n    assert.equal(moment('123', 'SSS', true).isValid(), true, 'valid three-digit milisecond');\n\n    // strict parsing respects month length\n    assert.ok(moment('1 January 2000', 'D MMMM YYYY', true).isValid(), 'capital long-month + MMMM');\n    assert.ok(!moment('1 January 2000', 'D MMM YYYY', true).isValid(), 'capital long-month + MMM');\n    assert.ok(!moment('1 Jan 2000', 'D MMMM YYYY', true).isValid(), 'capital short-month + MMMM');\n    assert.ok(moment('1 Jan 2000', 'D MMM YYYY', true).isValid(), 'capital short-month + MMM');\n    assert.ok(moment('1 january 2000', 'D MMMM YYYY', true).isValid(), 'lower long-month + MMMM');\n    assert.ok(!moment('1 january 2000', 'D MMM YYYY', true).isValid(), 'lower long-month + MMM');\n    assert.ok(!moment('1 jan 2000', 'D MMMM YYYY', true).isValid(), 'lower short-month + MMMM');\n    assert.ok(moment('1 jan 2000', 'D MMM YYYY', true).isValid(), 'lower short-month + MMM');\n});\n\ntest('parsing into a locale', function (assert) {\n    moment.defineLocale('parselocale', {\n        months : 'one_two_three_four_five_six_seven_eight_nine_ten_eleven_twelve'.split('_'),\n        monthsShort : 'one_two_three_four_five_six_seven_eight_nine_ten_eleven_twelve'.split('_')\n    });\n\n    moment.locale('en');\n\n    assert.equal(moment('2012 seven', 'YYYY MMM', 'parselocale').month(), 6, 'should be able to parse in a specific locale');\n\n    moment.locale('parselocale');\n\n    assert.equal(moment('2012 july', 'YYYY MMM', 'en').month(), 6, 'should be able to parse in a specific locale');\n\n    moment.defineLocale('parselocale', null);\n});\n\nfunction getVerifier(test$$1) {\n    return function (input, format, expected, description, asymetrical) {\n        var m = moment(input, format);\n        test$$1.equal(m.format('YYYY MM DD'), expected, 'compare: ' + description);\n\n        //test round trip\n        if (!asymetrical) {\n            test$$1.equal(m.format(format), input, 'round trip: ' + description);\n        }\n    };\n}\n\ntest('parsing week and weekday information', function (assert) {\n    var ver = getVerifier(assert);\n    var currentWeekOfYear = moment().weeks();\n    var expectedDate2012 = moment([2012, 0, 1])\n      .day(0)\n      .add((currentWeekOfYear - 1), 'weeks')\n      .format('YYYY MM DD');\n    var expectedDate1999 = moment([1999, 0, 1])\n      .day(0)\n      .add((currentWeekOfYear - 1), 'weeks')\n      .format('YYYY MM DD');\n\n    // year\n    ver('12', 'gg', expectedDate2012, 'week-year two digits');\n    ver('2012', 'gggg', expectedDate2012, 'week-year four digits');\n    ver('99', 'gg', expectedDate1999, 'week-year two digits previous year');\n    ver('1999', 'gggg', expectedDate1999, 'week-year four digits previous year');\n\n    ver('99', 'GG', '1999 01 04', 'iso week-year two digits');\n    ver('1999', 'GGGG', '1999 01 04', 'iso week-year four digits');\n\n    ver('13', 'GG', '2012 12 31', 'iso week-year two digits previous year');\n    ver('2013', 'GGGG', '2012 12 31', 'iso week-year four digits previous year');\n\n    // year + week\n    ver('1999 37', 'gggg w', '1999 09 05', 'week');\n    ver('1999 37', 'gggg ww', '1999 09 05', 'week double');\n    ver('1999 37', 'GGGG W', '1999 09 13', 'iso week');\n    ver('1999 37', 'GGGG WW', '1999 09 13', 'iso week double');\n\n    ver('1999 37 4', 'GGGG WW E', '1999 09 16', 'iso day');\n    ver('1999 37 04', 'GGGG WW E', '1999 09 16', 'iso day wide', true);\n\n    ver('1999 37 4', 'gggg ww e', '1999 09 09', 'day');\n    ver('1999 37 04', 'gggg ww e', '1999 09 09', 'day wide', true);\n\n    // year + week + day\n    ver('1999 37 4', 'gggg ww d', '1999 09 09', 'd');\n    ver('1999 37 Th', 'gggg ww dd', '1999 09 09', 'dd');\n    ver('1999 37 Thu', 'gggg ww ddd', '1999 09 09', 'ddd');\n    ver('1999 37 Thursday', 'gggg ww dddd', '1999 09 09', 'dddd');\n\n    // lower-order only\n    assert.equal(moment('22', 'ww').week(), 22, 'week sets the week by itself');\n    assert.equal(moment('22', 'ww').weekYear(), moment().weekYear(), 'week keeps this year');\n    assert.equal(moment('2012 22', 'YYYY ww').weekYear(), 2012, 'week keeps parsed year');\n\n    assert.equal(moment('22', 'WW').isoWeek(), 22, 'iso week sets the week by itself');\n    assert.equal(moment('2012 22', 'YYYY WW').weekYear(), 2012, 'iso week keeps parsed year');\n    assert.equal(moment('22', 'WW').isoWeekYear(), moment().isoWeekYear(), 'iso week keeps this year');\n\n    // order\n    ver('6 2013 2', 'e gggg w', '2013 01 12', 'order doesn\\'t matter');\n    ver('6 2013 2', 'E GGGG W', '2013 01 12', 'iso order doesn\\'t matter');\n\n    //can parse other stuff too\n    assert.equal(moment('1999-W37-4 3:30', 'GGGG-[W]WW-E HH:mm').format('YYYY MM DD HH:mm'), '1999 09 16 03:30', 'parsing weeks and hours');\n\n    // In safari, all years before 1300 are shifted back with one day.\n    // http://stackoverflow.com/questions/20768975/safari-subtracts-1-day-from-dates-before-1300\n    if (new Date('1300-01-01').getUTCFullYear() === 1300) {\n        // Years less than 100\n        ver('0098-06', 'GGGG-WW', '0098 02 03', 'small years work', true);\n    }\n});\n\ntest('parsing localized weekdays', function (assert) {\n    var ver = getVerifier(assert);\n    try {\n        moment.locale('dow:1,doy:4', {\n            weekdays : 'dimanche_lundi_mardi_mercredi_jeudi_vendredi_samedi'.split('_'),\n            weekdaysShort : 'dim._lun._mar._mer._jeu._ven._sam.'.split('_'),\n            weekdaysMin : 'Di_Lu_Ma_Me_Je_Ve_Sa'.split('_'),\n            week: {dow: 1, doy: 4}\n        });\n        ver('1999 37 4', 'GGGG WW E', '1999 09 16', 'iso ignores locale');\n        ver('1999 37 7', 'GGGG WW E', '1999 09 19', 'iso ignores locale');\n\n        ver('1999 37 0', 'gggg ww e', '1999 09 13', 'localized e uses local doy and dow: 0 = monday');\n        ver('1999 37 4', 'gggg ww e', '1999 09 17', 'localized e uses local doy and dow: 4 = friday');\n\n        ver('1999 37 1', 'gggg ww d', '1999 09 13', 'localized d uses 0-indexed days: 1 = monday');\n        ver('1999 37 Lu', 'gggg ww dd', '1999 09 13', 'localized d uses 0-indexed days: Mo');\n        ver('1999 37 lun.', 'gggg ww ddd', '1999 09 13', 'localized d uses 0-indexed days: Mon');\n        ver('1999 37 lundi', 'gggg ww dddd', '1999 09 13', 'localized d uses 0-indexed days: Monday');\n        ver('1999 37 4', 'gggg ww d', '1999 09 16', 'localized d uses 0-indexed days: 4');\n\n        //sunday goes at the end of the week\n        ver('1999 37 0', 'gggg ww d', '1999 09 19', 'localized d uses 0-indexed days: 0 = sund');\n        ver('1999 37 Di', 'gggg ww dd', '1999 09 19', 'localized d uses 0-indexed days: 0 = sund');\n    }\n    finally {\n        moment.defineLocale('dow:1,doy:4', null);\n        moment.locale('en');\n    }\n});\n\ntest('parsing with customized two-digit year', function (assert) {\n    var original = moment.parseTwoDigitYear;\n    try {\n        assert.equal(moment('68', 'YY').year(), 2068);\n        assert.equal(moment('69', 'YY').year(), 1969);\n        moment.parseTwoDigitYear = function (input) {\n            return +input + (+input > 30 ? 1900 : 2000);\n        };\n        assert.equal(moment('68', 'YY').year(), 1968);\n        assert.equal(moment('67', 'YY').year(), 1967);\n        assert.equal(moment('31', 'YY').year(), 1931);\n        assert.equal(moment('30', 'YY').year(), 2030);\n    }\n    finally {\n        moment.parseTwoDigitYear = original;\n    }\n});\n\ntest('array with strings', function (assert) {\n    assert.equal(moment(['2014', '7', '31']).isValid(), true, 'string array + isValid');\n});\n\ntest('object with strings', function (assert) {\n    assert.equal(moment({year: '2014', month: '7', day: '31'}).isValid(), true, 'string object + isValid');\n});\n\ntest('utc with array of formats', function (assert) {\n    assert.equal(moment.utc('2014-01-01', ['YYYY-MM-DD', 'YYYY-MM']).format(), '2014-01-01T00:00:00Z', 'moment.utc works with array of formats');\n});\n\ntest('parsing invalid string weekdays', function (assert) {\n    assert.equal(false, moment('a', 'dd').isValid(),\n            'dd with invalid weekday, non-strict');\n    assert.equal(false, moment('a', 'dd', true).isValid(),\n            'dd with invalid weekday, strict');\n    assert.equal(false, moment('a', 'ddd').isValid(),\n            'ddd with invalid weekday, non-strict');\n    assert.equal(false, moment('a', 'ddd', true).isValid(),\n            'ddd with invalid weekday, strict');\n    assert.equal(false, moment('a', 'dddd').isValid(),\n            'dddd with invalid weekday, non-strict');\n    assert.equal(false, moment('a', 'dddd', true).isValid(),\n            'dddd with invalid weekday, strict');\n});\n\ntest('milliseconds', function (assert) {\n    assert.equal(moment('1', 'S').millisecond(), 100);\n    assert.equal(moment('12', 'SS').millisecond(), 120);\n    assert.equal(moment('123', 'SSS').millisecond(), 123);\n    assert.equal(moment('1234', 'SSSS').millisecond(), 123);\n    assert.equal(moment('12345', 'SSSSS').millisecond(), 123);\n    assert.equal(moment('123456', 'SSSSSS').millisecond(), 123);\n    assert.equal(moment('1234567', 'SSSSSSS').millisecond(), 123);\n    assert.equal(moment('12345678', 'SSSSSSSS').millisecond(), 123);\n    assert.equal(moment('123456789', 'SSSSSSSSS').millisecond(), 123);\n});\n\ntest('hmm', function (assert) {\n    assert.equal(moment('123', 'hmm', true).format('HH:mm:ss'), '01:23:00', '123 with hmm');\n    assert.equal(moment('123a', 'hmmA', true).format('HH:mm:ss'), '01:23:00', '123a with hmmA');\n    assert.equal(moment('123p', 'hmmA', true).format('HH:mm:ss'), '13:23:00', '123p with hmmA');\n\n    assert.equal(moment('1234', 'hmm', true).format('HH:mm:ss'), '12:34:00', '1234 with hmm');\n    assert.equal(moment('1234a', 'hmmA', true).format('HH:mm:ss'), '00:34:00', '1234a with hmmA');\n    assert.equal(moment('1234p', 'hmmA', true).format('HH:mm:ss'), '12:34:00', '1234p with hmmA');\n\n    assert.equal(moment('12345', 'hmmss', true).format('HH:mm:ss'), '01:23:45', '12345 with hmmss');\n    assert.equal(moment('12345a', 'hmmssA', true).format('HH:mm:ss'), '01:23:45', '12345a with hmmssA');\n    assert.equal(moment('12345p', 'hmmssA', true).format('HH:mm:ss'), '13:23:45', '12345p with hmmssA');\n    assert.equal(moment('112345', 'hmmss', true).format('HH:mm:ss'), '11:23:45', '112345 with hmmss');\n    assert.equal(moment('112345a', 'hmmssA', true).format('HH:mm:ss'), '11:23:45', '112345a with hmmssA');\n    assert.equal(moment('112345p', 'hmmssA', true).format('HH:mm:ss'), '23:23:45', '112345p with hmmssA');\n\n    assert.equal(moment('023', 'Hmm', true).format('HH:mm:ss'), '00:23:00', '023 with Hmm');\n    assert.equal(moment('123', 'Hmm', true).format('HH:mm:ss'), '01:23:00', '123 with Hmm');\n    assert.equal(moment('1234', 'Hmm', true).format('HH:mm:ss'), '12:34:00', '1234 with Hmm');\n    assert.equal(moment('1534', 'Hmm', true).format('HH:mm:ss'), '15:34:00', '1234 with Hmm');\n    assert.equal(moment('12345', 'Hmmss', true).format('HH:mm:ss'), '01:23:45', '12345 with Hmmss');\n    assert.equal(moment('112345', 'Hmmss', true).format('HH:mm:ss'), '11:23:45', '112345 with Hmmss');\n    assert.equal(moment('172345', 'Hmmss', true).format('HH:mm:ss'), '17:23:45', '112345 with Hmmss');\n});\n\ntest('Y token', function (assert) {\n    assert.equal(moment('1-1-2010', 'M-D-Y', true).year(), 2010, 'parsing Y');\n});\n\ntest('parsing flags retain parsed date parts', function (assert) {\n    var a = moment('10 p', 'hh:mm a');\n    assert.equal(a.parsingFlags().parsedDateParts[3], 10, 'parsed 10 as the hour');\n    assert.equal(a.parsingFlags().parsedDateParts[0], undefined, 'year was not parsed');\n    assert.equal(a.parsingFlags().meridiem, 'p', 'meridiem flag was added');\n    var b = moment('10:30', ['MMDDYY', 'HH:mm']);\n    assert.equal(b.parsingFlags().parsedDateParts[3], 10, 'multiple format parshing matched hour');\n    assert.equal(b.parsingFlags().parsedDateParts[0], undefined, 'array is properly copied, no residual data from first token parse');\n});\n\ntest('parsing only meridiem results in invalid date', function (assert) {\n    assert.ok(!moment('alkj', 'hh:mm a').isValid(), 'because an a token is used, a meridiem will be parsed but nothing else was so invalid');\n    assert.ok(moment('02:30 p more extra stuff', 'hh:mm a').isValid(), 'because other tokens were parsed, date is valid');\n    assert.ok(moment('1/1/2016 extra data', ['a', 'M/D/YYYY']).isValid(), 'took second format, does not pick up on meridiem parsed from first format (good copy)');\n});\n\ntest('invalid dates return invalid for methods that access the _d prop', function (assert) {\n    var momentAsDate = moment(['2015', '12', '1']).toDate();\n    assert.ok(momentAsDate instanceof Date, 'toDate returns a Date object');\n    assert.ok(isNaN(momentAsDate.getTime()), 'toDate returns an invalid Date invalid');\n});\n\ntest('k, kk', function (assert) {\n    for (var i = -1; i <= 24; i++) {\n        var kVal = i + ':15:59';\n        var kkVal = (i < 10 ? '0' : '') + i + ':15:59';\n        if (i !== 24) {\n            assert.ok(moment(kVal, 'k:mm:ss').isSame(moment(kVal, 'H:mm:ss')), kVal + ' k parsing');\n            assert.ok(moment(kkVal, 'kk:mm:ss').isSame(moment(kkVal, 'HH:mm:ss')), kkVal + ' kk parsing');\n        } else {\n            assert.equal(moment(kVal, 'k:mm:ss').format('k:mm:ss'), kVal, kVal + ' k parsing');\n            assert.equal(moment(kkVal, 'kk:mm:ss').format('kk:mm:ss'), kkVal, kkVal + ' skk parsing');\n        }\n    }\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\nfunction module$1 (name, lifecycle) {\n    QUnit.module(name, {\n        setup : function () {\n            moment.locale('en');\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'core');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            teardownDeprecationHandler(test, moment, 'core');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n}\n\nmodule$1('creation data');\n\ntest('valid date', function (assert) {\n    var dat = moment('1992-10-22');\n    var orig = dat.creationData();\n\n    assert.equal(dat.isValid(), true, '1992-10-22 is valid');\n    assert.equal(orig.input, '1992-10-22', 'original input is not correct.');\n    assert.equal(orig.format, 'YYYY-MM-DD', 'original format is defined.');\n    assert.equal(orig.locale._abbr, 'en', 'default locale is en');\n    assert.equal(orig.isUTC, false, 'not a UTC date');\n});\n\ntest('valid date at fr locale', function (assert) {\n    var dat = moment('1992-10-22', 'YYYY-MM-DD', 'fr');\n    var orig = dat.creationData();\n\n    assert.equal(orig.locale._abbr, 'fr', 'locale is fr');\n});\n\ntest('valid date with formats', function (assert) {\n    var dat = moment('29-06-1995', ['MM-DD-YYYY', 'DD-MM', 'DD-MM-YYYY']);\n    var orig = dat.creationData();\n\n    assert.equal(orig.format, 'DD-MM-YYYY', 'DD-MM-YYYY format is defined.');\n});\n\ntest('strict', function (assert) {\n    assert.ok(moment('2015-01-02', 'YYYY-MM-DD', true).creationData().strict, 'strict is true');\n    assert.ok(!moment('2015-01-02', 'YYYY-MM-DD').creationData().strict, 'strict is true');\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\nfunction module$1 (name, lifecycle) {\n    QUnit.module(name, {\n        setup : function () {\n            moment.locale('en');\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'core');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            teardownDeprecationHandler(test, moment, 'core');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n}\n\nmodule$1('days in month');\n\ntest('days in month', function (assert) {\n    each([31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31], function (days, i) {\n        var firstDay = moment([2012, i]),\n            lastDay  = moment([2012, i, days]);\n        assert.equal(firstDay.daysInMonth(), days, firstDay.format('L') + ' should have ' + days + ' days.');\n        assert.equal(lastDay.daysInMonth(), days, lastDay.format('L') + ' should have ' + days + ' days.');\n    });\n});\n\ntest('days in month leap years', function (assert) {\n    assert.equal(moment([2010, 1]).daysInMonth(), 28, 'Feb 2010 should have 28 days');\n    assert.equal(moment([2100, 1]).daysInMonth(), 28, 'Feb 2100 should have 28 days');\n    assert.equal(moment([2008, 1]).daysInMonth(), 29, 'Feb 2008 should have 29 days');\n    assert.equal(moment([2000, 1]).daysInMonth(), 29, 'Feb 2000 should have 29 days');\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\nfunction module$1 (name, lifecycle) {\n    QUnit.module(name, {\n        setup : function () {\n            moment.locale('en');\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'core');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            teardownDeprecationHandler(test, moment, 'core');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n}\n\nmodule$1('days in year');\n\n// https://github.com/moment/moment/issues/3717\ntest('YYYYDDD should not parse DDD=000', function (assert) {\n    assert.equal(moment(7000000, moment.ISO_8601, true).isValid(), false);\n    assert.equal(moment('7000000', moment.ISO_8601, true).isValid(), false);\n    assert.equal(moment(7000000, moment.ISO_8601, false).isValid(), false);\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\nfunction module$1 (name, lifecycle) {\n    QUnit.module(name, {\n        setup : function () {\n            moment.locale('en');\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'core');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            teardownDeprecationHandler(test, moment, 'core');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n}\n\nfunction hasOwnProp(a, b) {\n    return Object.prototype.hasOwnProperty.call(a, b);\n}\n\nfunction extend(a, b) {\n    for (var i in b) {\n        if (hasOwnProp(b, i)) {\n            a[i] = b[i];\n        }\n    }\n\n    if (hasOwnProp(b, 'toString')) {\n        a.toString = b.toString;\n    }\n\n    if (hasOwnProp(b, 'valueOf')) {\n        a.valueOf = b.valueOf;\n    }\n\n    return a;\n}\n\nvar hookCallback;\n\nfunction hooks () {\n    return hookCallback.apply(null, arguments);\n}\n\nfunction warn(msg) {\n    if (hooks.suppressDeprecationWarnings === false &&\n            (typeof console !==  'undefined') && console.warn) {\n        console.warn('Deprecation warning: ' + msg);\n    }\n}\n\nfunction deprecate(msg, fn) {\n    var firstTime = true;\n\n    return extend(function () {\n        if (hooks.deprecationHandler != null) {\n            hooks.deprecationHandler(null, msg);\n        }\n        if (firstTime) {\n            var args = [];\n            var arg;\n            for (var i = 0; i < arguments.length; i++) {\n                arg = '';\n                if (typeof arguments[i] === 'object') {\n                    arg += '\\n[' + i + '] ';\n                    for (var key in arguments[0]) {\n                        arg += key + ': ' + arguments[0][key] + ', ';\n                    }\n                    arg = arg.slice(0, -2); // Remove trailing comma and space\n                } else {\n                    arg = arguments[i];\n                }\n                args.push(arg);\n            }\n            warn(msg + '\\nArguments: ' + Array.prototype.slice.call(args).join('') + '\\n' + (new Error()).stack);\n            firstTime = false;\n        }\n        return fn.apply(this, arguments);\n    }, fn);\n}\n\nvar deprecations = {};\n\n\n\nhooks.suppressDeprecationWarnings = false;\nhooks.deprecationHandler = null;\n\nmodule$1('deprecate');\n\ntest('deprecate', function (assert) {\n    // NOTE: hooks inside deprecate.js and moment are different, so this is can\n    // not be test.expectedDeprecations(...)\n    var fn = function () {};\n    var deprecatedFn = deprecate('testing deprecation', fn);\n    deprecatedFn();\n\n    expect(0);\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\nfunction module$1 (name, lifecycle) {\n    QUnit.module(name, {\n        setup : function () {\n            moment.locale('en');\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'core');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            teardownDeprecationHandler(test, moment, 'core');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n}\n\nfunction equal(assert, a, b, message) {\n    assert.ok(Math.abs(a - b) < 0.00000001, '(' + a + ' === ' + b + ') ' + message);\n}\n\nfunction dstForYear(year) {\n    var start = moment([year]),\n        end = moment([year + 1]),\n        current = start.clone(),\n        last;\n\n    while (current < end) {\n        last = current.clone();\n        current.add(24, 'hour');\n        if (last.utcOffset() !== current.utcOffset()) {\n            end = current.clone();\n            current = last.clone();\n            break;\n        }\n    }\n\n    while (current < end) {\n        last = current.clone();\n        current.add(1, 'hour');\n        if (last.utcOffset() !== current.utcOffset()) {\n            return {\n                moment : last,\n                diff : -(current.utcOffset() - last.utcOffset()) / 60\n            };\n        }\n    }\n}\n\nmodule$1('diff');\n\ntest('diff', function (assert) {\n    assert.equal(moment(1000).diff(0), 1000, '1 second - 0 = 1000');\n    assert.equal(moment(1000).diff(500), 500, '1 second - 0.5 seconds = 500');\n    assert.equal(moment(0).diff(1000), -1000, '0 - 1 second = -1000');\n    assert.equal(moment(new Date(1000)).diff(1000), 0, '1 second - 1 second = 0');\n    var oneHourDate = new Date(2015, 5, 21),\n    nowDate = new Date(+oneHourDate);\n    oneHourDate.setHours(oneHourDate.getHours() + 1);\n    assert.equal(moment(oneHourDate).diff(nowDate), 60 * 60 * 1000, '1 hour from now = 3600000');\n});\n\ntest('diff key after', function (assert) {\n    assert.equal(moment([2010]).diff([2011], 'years'), -1, 'year diff');\n    assert.equal(moment([2010]).diff([2010, 2], 'months'), -2, 'month diff');\n    assert.equal(moment([2010]).diff([2010, 0, 7], 'weeks'), 0, 'week diff');\n    assert.equal(moment([2010]).diff([2010, 0, 8], 'weeks'), -1, 'week diff');\n    assert.equal(moment([2010]).diff([2010, 0, 21], 'weeks'), -2, 'week diff');\n    assert.equal(moment([2010]).diff([2010, 0, 22], 'weeks'), -3, 'week diff');\n    assert.equal(moment([2010]).diff([2010, 0, 4], 'days'), -3, 'day diff');\n    assert.equal(moment([2010]).diff([2010, 0, 1, 4], 'hours'), -4, 'hour diff');\n    assert.equal(moment([2010]).diff([2010, 0, 1, 0, 5], 'minutes'), -5, 'minute diff');\n    assert.equal(moment([2010]).diff([2010, 0, 1, 0, 0, 6], 'seconds'), -6, 'second diff');\n});\n\ntest('diff key before', function (assert) {\n    assert.equal(moment([2011]).diff([2010], 'years'), 1, 'year diff');\n    assert.equal(moment([2010, 2]).diff([2010], 'months'), 2, 'month diff');\n    assert.equal(moment([2010, 0, 4]).diff([2010], 'days'), 3, 'day diff');\n    assert.equal(moment([2010, 0, 7]).diff([2010], 'weeks'), 0, 'week diff');\n    assert.equal(moment([2010, 0, 8]).diff([2010], 'weeks'), 1, 'week diff');\n    assert.equal(moment([2010, 0, 21]).diff([2010], 'weeks'), 2, 'week diff');\n    assert.equal(moment([2010, 0, 22]).diff([2010], 'weeks'), 3, 'week diff');\n    assert.equal(moment([2010, 0, 1, 4]).diff([2010], 'hours'), 4, 'hour diff');\n    assert.equal(moment([2010, 0, 1, 0, 5]).diff([2010], 'minutes'), 5, 'minute diff');\n    assert.equal(moment([2010, 0, 1, 0, 0, 6]).diff([2010], 'seconds'), 6, 'second diff');\n});\n\ntest('diff key before singular', function (assert) {\n    assert.equal(moment([2011]).diff([2010], 'year'), 1, 'year diff singular');\n    assert.equal(moment([2010, 2]).diff([2010], 'month'), 2, 'month diff singular');\n    assert.equal(moment([2010, 0, 4]).diff([2010], 'day'), 3, 'day diff singular');\n    assert.equal(moment([2010, 0, 7]).diff([2010], 'week'), 0, 'week diff singular');\n    assert.equal(moment([2010, 0, 8]).diff([2010], 'week'), 1, 'week diff singular');\n    assert.equal(moment([2010, 0, 21]).diff([2010], 'week'), 2, 'week diff singular');\n    assert.equal(moment([2010, 0, 22]).diff([2010], 'week'), 3, 'week diff singular');\n    assert.equal(moment([2010, 0, 1, 4]).diff([2010], 'hour'), 4, 'hour diff singular');\n    assert.equal(moment([2010, 0, 1, 0, 5]).diff([2010], 'minute'), 5, 'minute diff singular');\n    assert.equal(moment([2010, 0, 1, 0, 0, 6]).diff([2010], 'second'), 6, 'second diff singular');\n});\n\ntest('diff key before abbreviated', function (assert) {\n    assert.equal(moment([2011]).diff([2010], 'y'), 1, 'year diff abbreviated');\n    assert.equal(moment([2010, 2]).diff([2010], 'M'), 2, 'month diff abbreviated');\n    assert.equal(moment([2010, 0, 4]).diff([2010], 'd'), 3, 'day diff abbreviated');\n    assert.equal(moment([2010, 0, 7]).diff([2010], 'w'), 0, 'week diff abbreviated');\n    assert.equal(moment([2010, 0, 8]).diff([2010], 'w'), 1, 'week diff abbreviated');\n    assert.equal(moment([2010, 0, 21]).diff([2010], 'w'), 2, 'week diff abbreviated');\n    assert.equal(moment([2010, 0, 22]).diff([2010], 'w'), 3, 'week diff abbreviated');\n    assert.equal(moment([2010, 0, 1, 4]).diff([2010], 'h'), 4, 'hour diff abbreviated');\n    assert.equal(moment([2010, 0, 1, 0, 5]).diff([2010], 'm'), 5, 'minute diff abbreviated');\n    assert.equal(moment([2010, 0, 1, 0, 0, 6]).diff([2010], 's'), 6, 'second diff abbreviated');\n});\n\ntest('diff month', function (assert) {\n    assert.equal(moment([2011, 0, 31]).diff([2011, 2, 1], 'months'), -1, 'month diff');\n});\n\ntest('diff across DST', function (assert) {\n    var dst = dstForYear(2012), a, b, daysInMonth;\n    if (!dst) {\n        assert.equal(42, 42, 'at least one assertion');\n        return;\n    }\n\n    a = dst.moment;\n    b = a.clone().utc().add(12, 'hours').local();\n    daysInMonth = (a.daysInMonth() + b.daysInMonth()) / 2;\n    assert.equal(b.diff(a, 'milliseconds', true), 12 * 60 * 60 * 1000,\n            'ms diff across DST');\n    assert.equal(b.diff(a, 'seconds', true), 12 * 60 * 60,\n            'second diff across DST');\n    assert.equal(b.diff(a, 'minutes', true), 12 * 60,\n            'minute diff across DST');\n    assert.equal(b.diff(a, 'hours', true), 12,\n            'hour diff across DST');\n    assert.equal(b.diff(a, 'days', true), (12 - dst.diff) / 24,\n            'day diff across DST');\n    equal(assert, b.diff(a, 'weeks', true),  (12 - dst.diff) / 24 / 7,\n            'week diff across DST');\n    assert.ok(0.95 / (2 * 31) < b.diff(a, 'months', true),\n            'month diff across DST, lower bound');\n    assert.ok(b.diff(a, 'month', true) < 1.05 / (2 * 28),\n            'month diff across DST, upper bound');\n    assert.ok(0.95 / (2 * 31 * 12) < b.diff(a, 'years', true),\n            'year diff across DST, lower bound');\n    assert.ok(b.diff(a, 'year', true) < 1.05 / (2 * 28 * 12),\n            'year diff across DST, upper bound');\n\n    a = dst.moment;\n    b = a.clone().utc().add(12 + dst.diff, 'hours').local();\n    daysInMonth = (a.daysInMonth() + b.daysInMonth()) / 2;\n\n    assert.equal(b.diff(a, 'milliseconds', true),\n            (12 + dst.diff) * 60 * 60 * 1000,\n            'ms diff across DST');\n    assert.equal(b.diff(a, 'seconds', true),  (12 + dst.diff) * 60 * 60,\n            'second diff across DST');\n    assert.equal(b.diff(a, 'minutes', true),  (12 + dst.diff) * 60,\n            'minute diff across DST');\n    assert.equal(b.diff(a, 'hours', true),  (12 + dst.diff),\n            'hour diff across DST');\n    assert.equal(b.diff(a, 'days', true),  12 / 24, 'day diff across DST');\n    equal(assert, b.diff(a, 'weeks', true),  12 / 24 / 7,\n            'week diff across DST');\n    assert.ok(0.95 / (2 * 31) < b.diff(a, 'months', true),\n            'month diff across DST, lower bound');\n    assert.ok(b.diff(a, 'month', true) < 1.05 / (2 * 28),\n            'month diff across DST, upper bound');\n    assert.ok(0.95 / (2 * 31 * 12) < b.diff(a, 'years', true),\n            'year diff across DST, lower bound');\n    assert.ok(b.diff(a, 'year', true) < 1.05 / (2 * 28 * 12),\n            'year diff across DST, upper bound');\n});\n\ntest('diff overflow', function (assert) {\n    assert.equal(moment([2011]).diff([2010], 'months'), 12, 'month diff');\n    assert.equal(moment([2010, 0, 2]).diff([2010], 'hours'), 24, 'hour diff');\n    assert.equal(moment([2010, 0, 1, 2]).diff([2010], 'minutes'), 120, 'minute diff');\n    assert.equal(moment([2010, 0, 1, 0, 4]).diff([2010], 'seconds'), 240, 'second diff');\n});\n\ntest('diff between utc and local', function (assert) {\n    if (moment([2012]).utcOffset() === moment([2011]).utcOffset()) {\n        // Russia's utc offset on 1st of Jan 2012 vs 2011 is different\n        assert.equal(moment([2012]).utc().diff([2011], 'years'), 1, 'year diff');\n    }\n    assert.equal(moment([2010, 2, 2]).utc().diff([2010, 0, 2], 'months'), 2, 'month diff');\n    assert.equal(moment([2010, 0, 4]).utc().diff([2010], 'days'), 3, 'day diff');\n    assert.equal(moment([2010, 0, 22]).utc().diff([2010], 'weeks'), 3, 'week diff');\n    assert.equal(moment([2010, 0, 1, 4]).utc().diff([2010], 'hours'), 4, 'hour diff');\n    assert.equal(moment([2010, 0, 1, 0, 5]).utc().diff([2010], 'minutes'), 5, 'minute diff');\n    assert.equal(moment([2010, 0, 1, 0, 0, 6]).utc().diff([2010], 'seconds'), 6, 'second diff');\n});\n\ntest('diff floored', function (assert) {\n    assert.equal(moment([2010, 0, 1, 23]).diff([2010], 'day'), 0, '23 hours = 0 days');\n    assert.equal(moment([2010, 0, 1, 23, 59]).diff([2010], 'day'), 0, '23:59 hours = 0 days');\n    assert.equal(moment([2010, 0, 1, 24]).diff([2010], 'day'), 1, '24 hours = 1 day');\n    assert.equal(moment([2010, 0, 2]).diff([2011, 0, 1], 'year'), 0, 'year rounded down');\n    assert.equal(moment([2011, 0, 1]).diff([2010, 0, 2], 'year'), 0, 'year rounded down');\n    assert.equal(moment([2010, 0, 2]).diff([2011, 0, 2], 'year'), -1, 'year rounded down');\n    assert.equal(moment([2011, 0, 2]).diff([2010, 0, 2], 'year'), 1, 'year rounded down');\n});\n\ntest('year diffs include dates', function (assert) {\n    assert.ok(moment([2012, 1, 19]).diff(moment([2002, 1, 20]), 'years', true) < 10, 'year diff should include date of month');\n});\n\ntest('month diffs', function (assert) {\n    // due to floating point math errors, these tests just need to be accurate within 0.00000001\n    assert.equal(moment([2012, 0, 1]).diff([2012, 1, 1], 'months', true), -1, 'Jan 1 to Feb 1 should be 1 month');\n    equal(assert, moment([2012, 0, 1]).diff([2012, 0, 1, 12], 'months', true), -0.5 / 31, 'Jan 1 to Jan 1 noon should be 0.5 / 31 months');\n    assert.equal(moment([2012, 0, 15]).diff([2012, 1, 15], 'months', true), -1, 'Jan 15 to Feb 15 should be 1 month');\n    assert.equal(moment([2012, 0, 28]).diff([2012, 1, 28], 'months', true), -1, 'Jan 28 to Feb 28 should be 1 month');\n    assert.ok(moment([2012, 0, 31]).diff([2012, 1, 29], 'months', true), -1, 'Jan 31 to Feb 29 should be 1 month');\n    assert.ok(-1 > moment([2012, 0, 31]).diff([2012, 2, 1], 'months', true), 'Jan 31 to Mar 1 should be more than 1 month');\n    assert.ok(-30 / 28 < moment([2012, 0, 31]).diff([2012, 2, 1], 'months', true), 'Jan 31 to Mar 1 should be less than 1 month and 1 day');\n    equal(assert, moment([2012, 0, 1]).diff([2012, 0, 31], 'months', true), -(30 / 31), 'Jan 1 to Jan 31 should be 30 / 31 months');\n    assert.ok(0 < moment('2014-02-01').diff(moment('2014-01-31'), 'months', true), 'jan-31 to feb-1 diff is positive');\n});\n\ntest('exact month diffs', function (assert) {\n    // generate all pairs of months and compute month diff, with fixed day\n    // of month = 15.\n\n    var m1, m2;\n    for (m1 = 0; m1 < 12; ++m1) {\n        for (m2 = m1; m2 < 12; ++m2) {\n            assert.equal(moment([2013, m2, 15]).diff(moment([2013, m1, 15]), 'months', true), m2 - m1,\n                         'month diff from 2013-' + m1 + '-15 to 2013-' + m2 + '-15');\n        }\n    }\n});\n\ntest('year diffs', function (assert) {\n    // due to floating point math errors, these tests just need to be accurate within 0.00000001\n    equal(assert, moment([2012, 0, 1]).diff([2013, 0, 1], 'years', true), -1, 'Jan 1 2012 to Jan 1 2013 should be 1 year');\n    equal(assert, moment([2012, 1, 28]).diff([2013, 1, 28], 'years', true), -1, 'Feb 28 2012 to Feb 28 2013 should be 1 year');\n    equal(assert, moment([2012, 2, 1]).diff([2013, 2, 1], 'years', true), -1, 'Mar 1 2012 to Mar 1 2013 should be 1 year');\n    equal(assert, moment([2012, 11, 1]).diff([2013, 11, 1], 'years', true), -1, 'Dec 1 2012 to Dec 1 2013 should be 1 year');\n    equal(assert, moment([2012, 11, 31]).diff([2013, 11, 31], 'years', true), -1, 'Dec 31 2012 to Dec 31 2013 should be 1 year');\n    equal(assert, moment([2012, 0, 1]).diff([2013, 6, 1], 'years', true), -1.5, 'Jan 1 2012 to Jul 1 2013 should be 1.5 years');\n    equal(assert, moment([2012, 0, 31]).diff([2013, 6, 31], 'years', true), -1.5, 'Jan 31 2012 to Jul 31 2013 should be 1.5 years');\n    equal(assert, moment([2012, 0, 1]).diff([2013, 0, 1, 12], 'years', true), -1 - (0.5 / 31) / 12, 'Jan 1 2012 to Jan 1 2013 noon should be 1+(0.5 / 31) / 12 years');\n    equal(assert, moment([2012, 0, 1]).diff([2013, 6, 1, 12], 'years', true), -1.5 - (0.5 / 31) / 12, 'Jan 1 2012 to Jul 1 2013 noon should be 1.5+(0.5 / 31) / 12 years');\n    equal(assert, moment([2012, 1, 29]).diff([2013, 1, 28], 'years', true), -1, 'Feb 29 2012 to Feb 28 2013 should be 1-(1 / 28.5) / 12 years');\n});\n\ntest('negative zero', function (assert) {\n    function isNegative (n) {\n        return (1 / n) < 0;\n    }\n    assert.ok(!isNegative(moment([2012, 0, 1]).diff(moment([2012, 0, 1]), 'months')), 'month diff on same date is zero, not -0');\n    assert.ok(!isNegative(moment([2012, 0, 1]).diff(moment([2012, 0, 1]), 'years')), 'year diff on same date is zero, not -0');\n    assert.ok(!isNegative(moment([2012, 0, 1]).diff(moment([2012, 0, 1]), 'quarters')), 'quarter diff on same date is zero, not -0');\n    assert.ok(!isNegative(moment([2012, 0, 1]).diff(moment([2012, 0, 1, 1]), 'days')), 'days diff on same date is zero, not -0');\n    assert.ok(!isNegative(moment([2012, 0, 1]).diff(moment([2012, 0, 1, 0, 1]), 'hours')), 'hour diff on same hour is zero, not -0');\n    assert.ok(!isNegative(moment([2012, 0, 1]).diff(moment([2012, 0, 1, 0, 0, 1]), 'minutes')), 'minute diff on same minute is zero, not -0');\n    assert.ok(!isNegative(moment([2012, 0, 1]).diff(moment([2012, 0, 1, 0, 0, 0, 1]), 'seconds')), 'second diff on same second is zero, not -0');\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\nfunction module$1 (name, lifecycle) {\n    QUnit.module(name, {\n        setup : function () {\n            moment.locale('en');\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'core');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            teardownDeprecationHandler(test, moment, 'core');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n}\n\nmodule$1('duration');\n\ntest('object instantiation', function (assert) {\n    var d = moment.duration({\n        years: 2,\n        months: 3,\n        weeks: 2,\n        days: 1,\n        hours: 8,\n        minutes: 9,\n        seconds: 20,\n        milliseconds: 12\n    });\n\n    assert.equal(d.years(),        2,  'years');\n    assert.equal(d.months(),       3,  'months');\n    assert.equal(d.weeks(),        2,  'weeks');\n    assert.equal(d.days(),         15, 'days'); // two weeks + 1 day\n    assert.equal(d.hours(),        8,  'hours');\n    assert.equal(d.minutes(),      9,  'minutes');\n    assert.equal(d.seconds(),      20, 'seconds');\n    assert.equal(d.milliseconds(), 12, 'milliseconds');\n});\n\ntest('object instantiation with strings', function (assert) {\n    var d = moment.duration({\n        years: '2',\n        months: '3',\n        weeks: '2',\n        days: '1',\n        hours: '8',\n        minutes: '9',\n        seconds: '20',\n        milliseconds: '12'\n    });\n\n    assert.equal(d.years(),        2,  'years');\n    assert.equal(d.months(),       3,  'months');\n    assert.equal(d.weeks(),        2,  'weeks');\n    assert.equal(d.days(),         15, 'days'); // two weeks + 1 day\n    assert.equal(d.hours(),        8,  'hours');\n    assert.equal(d.minutes(),      9,  'minutes');\n    assert.equal(d.seconds(),      20, 'seconds');\n    assert.equal(d.milliseconds(), 12, 'milliseconds');\n});\n\ntest('milliseconds instantiation', function (assert) {\n    assert.equal(moment.duration(72).milliseconds(), 72, 'milliseconds');\n    assert.equal(moment.duration(72).humanize(), 'a few seconds', 'Duration should be valid');\n});\n\ntest('undefined instantiation', function (assert) {\n    assert.equal(moment.duration(undefined).milliseconds(), 0, 'milliseconds');\n    assert.equal(moment.duration(undefined).isValid(), true, '_isValid');\n    assert.equal(moment.duration(undefined).humanize(), 'a few seconds', 'Duration should be valid');\n});\n\ntest('null instantiation', function (assert) {\n    assert.equal(moment.duration(null).milliseconds(), 0, 'milliseconds');\n    assert.equal(moment.duration(null).isValid(), true, '_isValid');\n    assert.equal(moment.duration(null).humanize(), 'a few seconds', 'Duration should be valid');\n});\n\ntest('NaN instantiation', function (assert) {\n    assert.ok(isNaN(moment.duration(NaN).milliseconds()), 'milliseconds should be NaN');\n    assert.equal(moment.duration(NaN).isValid(), false, '_isValid');\n    assert.equal(moment.duration(NaN).humanize(), 'Invalid date', 'Duration should be invalid');\n});\n\ntest('instantiation by type', function (assert) {\n    assert.equal(moment.duration(1, 'years').years(),                 1, 'years');\n    assert.equal(moment.duration(1, 'y').years(),                     1, 'y');\n    assert.equal(moment.duration(2, 'months').months(),               2, 'months');\n    assert.equal(moment.duration(2, 'M').months(),                    2, 'M');\n    assert.equal(moment.duration(3, 'weeks').weeks(),                 3, 'weeks');\n    assert.equal(moment.duration(3, 'w').weeks(),                     3, 'weeks');\n    assert.equal(moment.duration(4, 'days').days(),                   4, 'days');\n    assert.equal(moment.duration(4, 'd').days(),                      4, 'd');\n    assert.equal(moment.duration(5, 'hours').hours(),                 5, 'hours');\n    assert.equal(moment.duration(5, 'h').hours(),                     5, 'h');\n    assert.equal(moment.duration(6, 'minutes').minutes(),             6, 'minutes');\n    assert.equal(moment.duration(6, 'm').minutes(),                   6, 'm');\n    assert.equal(moment.duration(7, 'seconds').seconds(),             7, 'seconds');\n    assert.equal(moment.duration(7, 's').seconds(),                   7, 's');\n    assert.equal(moment.duration(8, 'milliseconds').milliseconds(),   8, 'milliseconds');\n    assert.equal(moment.duration(8, 'ms').milliseconds(),             8, 'ms');\n});\n\ntest('shortcuts', function (assert) {\n    assert.equal(moment.duration({y: 1}).years(),         1, 'years = y');\n    assert.equal(moment.duration({M: 2}).months(),        2, 'months = M');\n    assert.equal(moment.duration({w: 3}).weeks(),         3, 'weeks = w');\n    assert.equal(moment.duration({d: 4}).days(),          4, 'days = d');\n    assert.equal(moment.duration({h: 5}).hours(),         5, 'hours = h');\n    assert.equal(moment.duration({m: 6}).minutes(),       6, 'minutes = m');\n    assert.equal(moment.duration({s: 7}).seconds(),       7, 'seconds = s');\n    assert.equal(moment.duration({ms: 8}).milliseconds(), 8, 'milliseconds = ms');\n});\n\ntest('generic getter', function (assert) {\n    assert.equal(moment.duration(1, 'years').get('years'),                1, 'years');\n    assert.equal(moment.duration(1, 'years').get('year'),                 1, 'years = year');\n    assert.equal(moment.duration(1, 'years').get('y'),                    1, 'years = y');\n    assert.equal(moment.duration(2, 'months').get('months'),              2, 'months');\n    assert.equal(moment.duration(2, 'months').get('month'),               2, 'months = month');\n    assert.equal(moment.duration(2, 'months').get('M'),                   2, 'months = M');\n    assert.equal(moment.duration(3, 'weeks').get('weeks'),                3, 'weeks');\n    assert.equal(moment.duration(3, 'weeks').get('week'),                 3, 'weeks = week');\n    assert.equal(moment.duration(3, 'weeks').get('w'),                    3, 'weeks = w');\n    assert.equal(moment.duration(4, 'days').get('days'),                  4, 'days');\n    assert.equal(moment.duration(4, 'days').get('day'),                   4, 'days = day');\n    assert.equal(moment.duration(4, 'days').get('d'),                     4, 'days = d');\n    assert.equal(moment.duration(5, 'hours').get('hours'),                5, 'hours');\n    assert.equal(moment.duration(5, 'hours').get('hour'),                 5, 'hours = hour');\n    assert.equal(moment.duration(5, 'hours').get('h'),                    5, 'hours = h');\n    assert.equal(moment.duration(6, 'minutes').get('minutes'),            6, 'minutes');\n    assert.equal(moment.duration(6, 'minutes').get('minute'),             6, 'minutes = minute');\n    assert.equal(moment.duration(6, 'minutes').get('m'),                  6, 'minutes = m');\n    assert.equal(moment.duration(7, 'seconds').get('seconds'),            7, 'seconds');\n    assert.equal(moment.duration(7, 'seconds').get('second'),             7, 'seconds = second');\n    assert.equal(moment.duration(7, 'seconds').get('s'),                  7, 'seconds = s');\n    assert.equal(moment.duration(8, 'milliseconds').get('milliseconds'),  8, 'milliseconds');\n    assert.equal(moment.duration(8, 'milliseconds').get('millisecond'),   8, 'milliseconds = millisecond');\n    assert.equal(moment.duration(8, 'milliseconds').get('ms'),            8, 'milliseconds = ms');\n});\n\ntest('instantiation from another duration', function (assert) {\n    var simple = moment.duration(1234),\n        lengthy = moment.duration(60 * 60 * 24 * 360 * 1e3),\n        complicated = moment.duration({\n            years: 2,\n            months: 3,\n            weeks: 4,\n            days: 1,\n            hours: 8,\n            minutes: 9,\n            seconds: 20,\n            milliseconds: 12\n        }),\n        modified = moment.duration(1, 'day').add(moment.duration(1, 'day'));\n\n    assert.deepEqual(moment.duration(simple), simple, 'simple clones are equal');\n    assert.deepEqual(moment.duration(lengthy), lengthy, 'lengthy clones are equal');\n    assert.deepEqual(moment.duration(complicated), complicated, 'complicated clones are equal');\n    assert.deepEqual(moment.duration(modified), modified, 'cloning modified duration works');\n});\n\ntest('instantiation from 24-hour time zero', function (assert) {\n    assert.equal(moment.duration('00:00').years(), 0, '0 years');\n    assert.equal(moment.duration('00:00').days(), 0, '0 days');\n    assert.equal(moment.duration('00:00').hours(), 0, '0 hours');\n    assert.equal(moment.duration('00:00').minutes(), 0, '0 minutes');\n    assert.equal(moment.duration('00:00').seconds(), 0, '0 seconds');\n    assert.equal(moment.duration('00:00').milliseconds(), 0, '0 milliseconds');\n});\n\ntest('instantiation from 24-hour time <24 hours', function (assert) {\n    assert.equal(moment.duration('06:45').years(), 0, '0 years');\n    assert.equal(moment.duration('06:45').days(), 0, '0 days');\n    assert.equal(moment.duration('06:45').hours(), 6, '6 hours');\n    assert.equal(moment.duration('06:45').minutes(), 45, '45 minutes');\n    assert.equal(moment.duration('06:45').seconds(), 0, '0 seconds');\n    assert.equal(moment.duration('06:45').milliseconds(), 0, '0 milliseconds');\n});\n\ntest('instantiation from 24-hour time >24 hours', function (assert) {\n    assert.equal(moment.duration('26:45').years(), 0, '0 years');\n    assert.equal(moment.duration('26:45').days(), 1, '0 days');\n    assert.equal(moment.duration('26:45').hours(), 2, '2 hours');\n    assert.equal(moment.duration('26:45').minutes(), 45, '45 minutes');\n    assert.equal(moment.duration('26:45').seconds(), 0, '0 seconds');\n    assert.equal(moment.duration('26:45').milliseconds(), 0, '0 milliseconds');\n});\n\ntest('instatiation from serialized C# TimeSpan zero', function (assert) {\n    assert.equal(moment.duration('00:00:00').years(), 0, '0 years');\n    assert.equal(moment.duration('00:00:00').days(), 0, '0 days');\n    assert.equal(moment.duration('00:00:00').hours(), 0, '0 hours');\n    assert.equal(moment.duration('00:00:00').minutes(), 0, '0 minutes');\n    assert.equal(moment.duration('00:00:00').seconds(), 0, '0 seconds');\n    assert.equal(moment.duration('00:00:00').milliseconds(), 0, '0 milliseconds');\n});\n\ntest('instatiation from serialized C# TimeSpan with days', function (assert) {\n    assert.equal(moment.duration('1.02:03:04.9999999').years(), 0, '0 years');\n    assert.equal(moment.duration('1.02:03:04.9999999').days(), 1, '1 day');\n    assert.equal(moment.duration('1.02:03:04.9999999').hours(), 2, '2 hours');\n    assert.equal(moment.duration('1.02:03:04.9999999').minutes(), 3, '3 minutes');\n    assert.equal(moment.duration('1.02:03:04.9999999').seconds(), 5, '5 seconds');\n    assert.equal(moment.duration('1.02:03:04.9999999').milliseconds(), 0, '0 milliseconds');\n\n    assert.equal(moment.duration('1 02:03:04.9999999').years(), 0, '0 years');\n    assert.equal(moment.duration('1 02:03:04.9999999').days(), 1, '1 day');\n    assert.equal(moment.duration('1 02:03:04.9999999').hours(), 2, '2 hours');\n    assert.equal(moment.duration('1 02:03:04.9999999').minutes(), 3, '3 minutes');\n    assert.equal(moment.duration('1 02:03:04.9999999').seconds(), 5, '5 seconds');\n    assert.equal(moment.duration('1 02:03:04.9999999').milliseconds(), 0, '0 milliseconds');\n});\n\ntest('instatiation from serialized C# TimeSpan without days', function (assert) {\n    assert.equal(moment.duration('01:02:03.9999999').years(), 0, '0 years');\n    assert.equal(moment.duration('01:02:03.9999999').days(), 0, '0 days');\n    assert.equal(moment.duration('01:02:03.9999999').hours(), 1, '1 hour');\n    assert.equal(moment.duration('01:02:03.9999999').minutes(), 2, '2 minutes');\n    assert.equal(moment.duration('01:02:03.9999999').seconds(), 4, '4 seconds');\n    assert.equal(moment.duration('01:02:03.9999999').milliseconds(), 0, '0 milliseconds');\n\n    assert.equal(moment.duration('23:59:59.9999999').days(), 1, '1 days');\n    assert.equal(moment.duration('23:59:59.9999999').hours(), 0, '0 hours');\n    assert.equal(moment.duration('23:59:59.9999999').minutes(), 0, '0 minutes');\n    assert.equal(moment.duration('23:59:59.9999999').seconds(), 0, '0 seconds');\n    assert.equal(moment.duration('23:59:59.9999999').milliseconds(), 0, '0 milliseconds');\n\n    assert.equal(moment.duration('500:59:59.8888888').days(), 20, '500 hours overflows to 20 days');\n    assert.equal(moment.duration('500:59:59.8888888').hours(), 20, '500 hours overflows to 20 hours');\n});\n\ntest('instatiation from serialized C# TimeSpan without days or milliseconds', function (assert) {\n    assert.equal(moment.duration('01:02:03').years(), 0, '0 years');\n    assert.equal(moment.duration('01:02:03').days(), 0, '0 days');\n    assert.equal(moment.duration('01:02:03').hours(), 1, '1 hour');\n    assert.equal(moment.duration('01:02:03').minutes(), 2, '2 minutes');\n    assert.equal(moment.duration('01:02:03').seconds(), 3, '3 seconds');\n    assert.equal(moment.duration('01:02:03').milliseconds(), 0, '0 milliseconds');\n});\n\ntest('instatiation from serialized C# TimeSpan without milliseconds', function (assert) {\n    assert.equal(moment.duration('1.02:03:04').years(), 0, '0 years');\n    assert.equal(moment.duration('1.02:03:04').days(), 1, '1 day');\n    assert.equal(moment.duration('1.02:03:04').hours(), 2, '2 hours');\n    assert.equal(moment.duration('1.02:03:04').minutes(), 3, '3 minutes');\n    assert.equal(moment.duration('1.02:03:04').seconds(), 4, '4 seconds');\n    assert.equal(moment.duration('1.02:03:04').milliseconds(), 0, '0 milliseconds');\n});\n\ntest('instantiation from serialized C# TimeSpan with low millisecond precision', function (assert) {\n    assert.equal(moment.duration('00:00:15.72').years(), 0, '0 years');\n    assert.equal(moment.duration('00:00:15.72').days(), 0, '0 days');\n    assert.equal(moment.duration('00:00:15.72').hours(), 0, '0 hours');\n    assert.equal(moment.duration('00:00:15.72').minutes(), 0, '0 minutes');\n    assert.equal(moment.duration('00:00:15.72').seconds(), 15, '15 seconds');\n    assert.equal(moment.duration('00:00:15.72').milliseconds(), 720, '720 milliseconds');\n\n    assert.equal(moment.duration('00:00:15.7').milliseconds(), 700, '700 milliseconds');\n\n    assert.equal(moment.duration('00:00:15.').milliseconds(), 0, '0 milliseconds');\n});\n\ntest('instantiation from serialized C# TimeSpan with high millisecond precision', function (assert) {\n    assert.equal(moment.duration('00:00:15.7200000').seconds(), 15, '15 seconds');\n    assert.equal(moment.duration('00:00:15.7200000').milliseconds(), 720, '720 milliseconds');\n\n    assert.equal(moment.duration('00:00:15.7209999').seconds(), 15, '15 seconds');\n    assert.equal(moment.duration('00:00:15.7209999').milliseconds(), 721, '721 milliseconds');\n\n    assert.equal(moment.duration('00:00:15.7205000').seconds(), 15, '15 seconds');\n    assert.equal(moment.duration('00:00:15.7205000').milliseconds(), 721, '721 milliseconds');\n\n    assert.equal(moment.duration('-00:00:15.7205000').seconds(), -15, '15 seconds');\n    assert.equal(moment.duration('-00:00:15.7205000').milliseconds(), -721, '721 milliseconds');\n});\n\ntest('instatiation from serialized C# TimeSpan maxValue', function (assert) {\n    var d = moment.duration('10675199.02:48:05.4775807');\n\n    assert.equal(d.years(), 29227, '29227 years');\n    assert.equal(d.months(), 8, '8 months');\n    assert.equal(d.days(), 12, '12 day');  // if you have to change this value -- just do it\n\n    assert.equal(d.hours(), 2, '2 hours');\n    assert.equal(d.minutes(), 48, '48 minutes');\n    assert.equal(d.seconds(), 5, '5 seconds');\n    assert.equal(d.milliseconds(), 478, '478 milliseconds');\n});\n\ntest('instatiation from serialized C# TimeSpan minValue', function (assert) {\n    var d = moment.duration('-10675199.02:48:05.4775808');\n\n    assert.equal(d.years(), -29227, '29653 years');\n    assert.equal(d.months(), -8, '8 day');\n    assert.equal(d.days(), -12, '12 day');  // if you have to change this value -- just do it\n\n    assert.equal(d.hours(), -2, '2 hours');\n    assert.equal(d.minutes(), -48, '48 minutes');\n    assert.equal(d.seconds(), -5, '5 seconds');\n    assert.equal(d.milliseconds(), -478, '478 milliseconds');\n});\n\ntest('instantiation from ISO 8601 duration', function (assert) {\n    assert.equal(moment.duration('P1Y2M3DT4H5M6S').asSeconds(), moment.duration({y: 1, M: 2, d: 3, h: 4, m: 5, s: 6}).asSeconds(), 'all fields');\n    assert.equal(moment.duration('P3W3D').asSeconds(), moment.duration({w: 3, d: 3}).asSeconds(), 'week and day fields');\n    assert.equal(moment.duration('P1M').asSeconds(), moment.duration({M: 1}).asSeconds(), 'single month field');\n    assert.equal(moment.duration('PT1M').asSeconds(), moment.duration({m: 1}).asSeconds(), 'single minute field');\n    assert.equal(moment.duration('P1MT2H').asSeconds(), moment.duration({M: 1, h: 2}).asSeconds(), 'random fields missing');\n    assert.equal(moment.duration('-P60D').asSeconds(), moment.duration({d: -60}).asSeconds(), 'negative days');\n    assert.equal(moment.duration('PT0.5S').asSeconds(), moment.duration({s: 0.5}).asSeconds(), 'fractional seconds');\n    assert.equal(moment.duration('PT0,5S').asSeconds(), moment.duration({s: 0.5}).asSeconds(), 'fractional seconds (comma)');\n});\n\ntest('serialization to ISO 8601 duration strings', function (assert) {\n    assert.equal(moment.duration({y: 1, M: 2, d: 3, h: 4, m: 5, s: 6}).toISOString(), 'P1Y2M3DT4H5M6S', 'all fields');\n    assert.equal(moment.duration({M: -1}).toISOString(), '-P1M', 'one month ago');\n    assert.equal(moment.duration({m: -1}).toISOString(), '-PT1M', 'one minute ago');\n    assert.equal(moment.duration({s: -0.5}).toISOString(), '-PT0.5S', 'one half second ago');\n    assert.equal(moment.duration({y: -1, M: 1}).toISOString(), '-P11M', 'a month after a year ago');\n    assert.equal(moment.duration({}).toISOString(), 'P0D', 'zero duration');\n    assert.equal(moment.duration({M: 16, d:40, s: 86465}).toISOString(), 'P1Y4M40DT24H1M5S', 'all fields');\n});\n\ntest('toString acts as toISOString', function (assert) {\n    assert.equal(moment.duration({y: 1, M: 2, d: 3, h: 4, m: 5, s: 6}).toString(), 'P1Y2M3DT4H5M6S', 'all fields');\n    assert.equal(moment.duration({M: -1}).toString(), '-P1M', 'one month ago');\n    assert.equal(moment.duration({m: -1}).toString(), '-PT1M', 'one minute ago');\n    assert.equal(moment.duration({s: -0.5}).toString(), '-PT0.5S', 'one half second ago');\n    assert.equal(moment.duration({y: -1, M: 1}).toString(), '-P11M', 'a month after a year ago');\n    assert.equal(moment.duration({}).toString(), 'P0D', 'zero duration');\n    assert.equal(moment.duration({M: 16, d:40, s: 86465}).toString(), 'P1Y4M40DT24H1M5S', 'all fields');\n});\n\ntest('toIsoString deprecation', function (assert) {\n    test.expectedDeprecations('toIsoString()');\n\n    assert.equal(moment.duration({}).toIsoString(), moment.duration({}).toISOString(), 'toIsoString delegates to toISOString');\n});\n\ntest('`isodate` (python) test cases', function (assert) {\n    assert.equal(moment.duration('P18Y9M4DT11H9M8S').asSeconds(), moment.duration({y: 18, M: 9, d: 4, h: 11, m: 9, s: 8}).asSeconds(), 'python isodate 1');\n    assert.equal(moment.duration('P2W').asSeconds(), moment.duration({w: 2}).asSeconds(), 'python isodate 2');\n    assert.equal(moment.duration('P3Y6M4DT12H30M5S').asSeconds(), moment.duration({y: 3, M: 6, d: 4, h: 12, m: 30, s: 5}).asSeconds(), 'python isodate 3');\n    assert.equal(moment.duration('P23DT23H').asSeconds(), moment.duration({d: 23, h: 23}).asSeconds(), 'python isodate 4');\n    assert.equal(moment.duration('P4Y').asSeconds(), moment.duration({y: 4}).asSeconds(), 'python isodate 5');\n    assert.equal(moment.duration('P1M').asSeconds(), moment.duration({M: 1}).asSeconds(), 'python isodate 6');\n    assert.equal(moment.duration('PT1M').asSeconds(), moment.duration({m: 1}).asSeconds(), 'python isodate 7');\n    assert.equal(moment.duration('P0.5Y').asSeconds(), moment.duration({y: 0.5}).asSeconds(), 'python isodate 8');\n    assert.equal(moment.duration('PT36H').asSeconds(), moment.duration({h: 36}).asSeconds(), 'python isodate 9');\n    assert.equal(moment.duration('P1DT12H').asSeconds(), moment.duration({d: 1, h: 12}).asSeconds(), 'python isodate 10');\n    assert.equal(moment.duration('-P2W').asSeconds(), moment.duration({w: -2}).asSeconds(), 'python isodate 11');\n    assert.equal(moment.duration('-P2.2W').asSeconds(), moment.duration({w: -2.2}).asSeconds(), 'python isodate 12');\n    assert.equal(moment.duration('P1DT2H3M4S').asSeconds(), moment.duration({d: 1, h: 2, m: 3, s: 4}).asSeconds(), 'python isodate 13');\n    assert.equal(moment.duration('P1DT2H3M').asSeconds(), moment.duration({d: 1, h: 2, m: 3}).asSeconds(), 'python isodate 14');\n    assert.equal(moment.duration('P1DT2H').asSeconds(), moment.duration({d: 1, h: 2}).asSeconds(), 'python isodate 15');\n    assert.equal(moment.duration('PT2H').asSeconds(), moment.duration({h: 2}).asSeconds(), 'python isodate 16');\n    assert.equal(moment.duration('PT2.3H').asSeconds(), moment.duration({h: 2.3}).asSeconds(), 'python isodate 17');\n    assert.equal(moment.duration('PT2H3M4S').asSeconds(), moment.duration({h: 2, m: 3, s: 4}).asSeconds(), 'python isodate 18');\n    assert.equal(moment.duration('PT3M4S').asSeconds(), moment.duration({m: 3, s: 4}).asSeconds(), 'python isodate 19');\n    assert.equal(moment.duration('PT22S').asSeconds(), moment.duration({s: 22}).asSeconds(), 'python isodate 20');\n    assert.equal(moment.duration('PT22.22S').asSeconds(), moment.duration({s: 22.22}).asSeconds(), 'python isodate 21');\n    assert.equal(moment.duration('-P2Y').asSeconds(), moment.duration({y: -2}).asSeconds(), 'python isodate 22');\n    assert.equal(moment.duration('-P3Y6M4DT12H30M5S').asSeconds(), moment.duration({y: -3, M: -6, d: -4, h: -12, m: -30, s: -5}).asSeconds(), 'python isodate 23');\n    assert.equal(moment.duration('-P1DT2H3M4S').asSeconds(), moment.duration({d: -1, h: -2, m: -3, s: -4}).asSeconds(), 'python isodate 24');\n    assert.equal(moment.duration('PT-6H3M').asSeconds(), moment.duration({h: -6, m: 3}).asSeconds(), 'python isodate 25');\n    assert.equal(moment.duration('-PT-6H3M').asSeconds(), moment.duration({h: 6, m: -3}).asSeconds(), 'python isodate 26');\n    assert.equal(moment.duration('-P-3Y-6M-4DT-12H-30M-5S').asSeconds(), moment.duration({y: 3, M: 6, d: 4, h: 12, m: 30, s: 5}).asSeconds(), 'python isodate 27');\n    assert.equal(moment.duration('P-3Y-6M-4DT-12H-30M-5S').asSeconds(), moment.duration({y: -3, M: -6, d: -4, h: -12, m: -30, s: -5}).asSeconds(), 'python isodate 28');\n    assert.equal(moment.duration('-P-2W').asSeconds(), moment.duration({w: 2}).asSeconds(), 'python isodate 29');\n    assert.equal(moment.duration('P-2W').asSeconds(), moment.duration({w: -2}).asSeconds(), 'python isodate 30');\n});\n\ntest('ISO 8601 misuse cases', function (assert) {\n    assert.equal(moment.duration('P').asSeconds(), 0, 'lonely P');\n    assert.equal(moment.duration('PT').asSeconds(), 0, 'just P and T');\n    assert.equal(moment.duration('P1H').asSeconds(), 0, 'missing T');\n    assert.equal(moment.duration('P1D1Y').asSeconds(), 0, 'out of order');\n    assert.equal(moment.duration('PT.5S').asSeconds(), 0.5, 'accept no leading zero for decimal');\n    assert.equal(moment.duration('PT1,S').asSeconds(), 1, 'accept trailing decimal separator');\n    assert.equal(moment.duration('PT1M0,,5S').asSeconds(), 60, 'extra decimal separators are ignored as 0');\n});\n\ntest('humanize', function (assert) {\n    moment.locale('en');\n    assert.equal(moment.duration({seconds: 44}).humanize(),  'a few seconds', '44 seconds = a few seconds');\n    assert.equal(moment.duration({seconds: 45}).humanize(),  'a minute',      '45 seconds = a minute');\n    assert.equal(moment.duration({seconds: 89}).humanize(),  'a minute',      '89 seconds = a minute');\n    assert.equal(moment.duration({seconds: 90}).humanize(),  '2 minutes',     '90 seconds = 2 minutes');\n    assert.equal(moment.duration({minutes: 44}).humanize(),  '44 minutes',    '44 minutes = 44 minutes');\n    assert.equal(moment.duration({minutes: 45}).humanize(),  'an hour',       '45 minutes = an hour');\n    assert.equal(moment.duration({minutes: 89}).humanize(),  'an hour',       '89 minutes = an hour');\n    assert.equal(moment.duration({minutes: 90}).humanize(),  '2 hours',       '90 minutes = 2 hours');\n    assert.equal(moment.duration({hours: 5}).humanize(),     '5 hours',       '5 hours = 5 hours');\n    assert.equal(moment.duration({hours: 21}).humanize(),    '21 hours',      '21 hours = 21 hours');\n    assert.equal(moment.duration({hours: 22}).humanize(),    'a day',         '22 hours = a day');\n    assert.equal(moment.duration({hours: 35}).humanize(),    'a day',         '35 hours = a day');\n    assert.equal(moment.duration({hours: 36}).humanize(),    '2 days',        '36 hours = 2 days');\n    assert.equal(moment.duration({days: 1}).humanize(),      'a day',         '1 day = a day');\n    assert.equal(moment.duration({days: 5}).humanize(),      '5 days',        '5 days = 5 days');\n    assert.equal(moment.duration({weeks: 1}).humanize(),     '7 days',        '1 week = 7 days');\n    assert.equal(moment.duration({days: 25}).humanize(),     '25 days',       '25 days = 25 days');\n    assert.equal(moment.duration({days: 26}).humanize(),     'a month',       '26 days = a month');\n    assert.equal(moment.duration({days: 30}).humanize(),     'a month',       '30 days = a month');\n    assert.equal(moment.duration({days: 45}).humanize(),     'a month',       '45 days = a month');\n    assert.equal(moment.duration({days: 46}).humanize(),     '2 months',      '46 days = 2 months');\n    assert.equal(moment.duration({days: 74}).humanize(),     '2 months',      '74 days = 2 months');\n    assert.equal(moment.duration({days: 77}).humanize(),     '3 months',      '77 days = 3 months');\n    assert.equal(moment.duration({months: 1}).humanize(),    'a month',       '1 month = a month');\n    assert.equal(moment.duration({months: 5}).humanize(),    '5 months',      '5 months = 5 months');\n    assert.equal(moment.duration({days: 344}).humanize(),    'a year',        '344 days = a year');\n    assert.equal(moment.duration({days: 345}).humanize(),    'a year',        '345 days = a year');\n    assert.equal(moment.duration({days: 547}).humanize(),    'a year',        '547 days = a year');\n    assert.equal(moment.duration({days: 548}).humanize(),    '2 years',       '548 days = 2 years');\n    assert.equal(moment.duration({years: 1}).humanize(),     'a year',        '1 year = a year');\n    assert.equal(moment.duration({years: 5}).humanize(),     '5 years',       '5 years = 5 years');\n    assert.equal(moment.duration(7200000).humanize(),        '2 hours',       '7200000 = 2 minutes');\n});\n\ntest('humanize duration with suffix', function (assert) {\n    moment.locale('en');\n    assert.equal(moment.duration({seconds:  44}).humanize(true),  'in a few seconds', '44 seconds = a few seconds');\n    assert.equal(moment.duration({seconds: -44}).humanize(true),  'a few seconds ago', '44 seconds = a few seconds');\n});\n\ntest('bubble value up', function (assert) {\n    assert.equal(moment.duration({milliseconds: 61001}).milliseconds(), 1, '61001 milliseconds has 1 millisecond left over');\n    assert.equal(moment.duration({milliseconds: 61001}).seconds(),      1, '61001 milliseconds has 1 second left over');\n    assert.equal(moment.duration({milliseconds: 61001}).minutes(),      1, '61001 milliseconds has 1 minute left over');\n\n    assert.equal(moment.duration({minutes: 350}).minutes(), 50, '350 minutes has 50 minutes left over');\n    assert.equal(moment.duration({minutes: 350}).hours(),   5,  '350 minutes has 5 hours left over');\n});\n\ntest('clipping', function (assert) {\n    assert.equal(moment.duration({months: 11}).months(), 11, '11 months is 11 months');\n    assert.equal(moment.duration({months: 11}).years(),  0,  '11 months makes no year');\n    assert.equal(moment.duration({months: 12}).months(), 0,  '12 months is 0 months left over');\n    assert.equal(moment.duration({months: 12}).years(),  1,  '12 months makes 1 year');\n    assert.equal(moment.duration({months: 13}).months(), 1,  '13 months is 1 month left over');\n    assert.equal(moment.duration({months: 13}).years(),  1,  '13 months makes 1 year');\n\n    assert.equal(moment.duration({days: 30}).days(),   30, '30 days is 30 days');\n    assert.equal(moment.duration({days: 30}).months(), 0,  '30 days makes no month');\n    assert.equal(moment.duration({days: 31}).days(),   0,  '31 days is 0 days left over');\n    assert.equal(moment.duration({days: 31}).months(), 1,  '31 days is a month');\n    assert.equal(moment.duration({days: 32}).days(),   1,  '32 days is 1 day left over');\n    assert.equal(moment.duration({days: 32}).months(), 1,  '32 days is a month');\n\n    assert.equal(moment.duration({hours: 23}).hours(), 23, '23 hours is 23 hours');\n    assert.equal(moment.duration({hours: 23}).days(),  0,  '23 hours makes no day');\n    assert.equal(moment.duration({hours: 24}).hours(), 0,  '24 hours is 0 hours left over');\n    assert.equal(moment.duration({hours: 24}).days(),  1,  '24 hours makes 1 day');\n    assert.equal(moment.duration({hours: 25}).hours(), 1,  '25 hours is 1 hour left over');\n    assert.equal(moment.duration({hours: 25}).days(),  1,  '25 hours makes 1 day');\n});\n\ntest('bubbling consistency', function (assert) {\n    var days = 0, months = 0, newDays, newMonths, totalDays, d;\n    for (totalDays = 1; totalDays <= 500; ++totalDays) {\n        d = moment.duration(totalDays, 'days');\n        newDays = d.days();\n        newMonths = d.months() + d.years() * 12;\n        assert.ok(\n                (months === newMonths && days + 1 === newDays) ||\n                (months + 1 === newMonths && newDays === 0),\n                'consistent total days ' + totalDays +\n                ' was ' + months + ' ' + days +\n                ' now ' + newMonths + ' ' + newDays);\n        days = newDays;\n        months = newMonths;\n    }\n});\n\ntest('effective equivalency', function (assert) {\n    assert.deepEqual(moment.duration({seconds: 1})._data,  moment.duration({milliseconds: 1000})._data, '1 second is the same as 1000 milliseconds');\n    assert.deepEqual(moment.duration({seconds: 60})._data, moment.duration({minutes: 1})._data,         '1 minute is the same as 60 seconds');\n    assert.deepEqual(moment.duration({minutes: 60})._data, moment.duration({hours: 1})._data,           '1 hour is the same as 60 minutes');\n    assert.deepEqual(moment.duration({hours: 24})._data,   moment.duration({days: 1})._data,            '1 day is the same as 24 hours');\n    assert.deepEqual(moment.duration({days: 7})._data,     moment.duration({weeks: 1})._data,           '1 week is the same as 7 days');\n    assert.deepEqual(moment.duration({days: 31})._data,    moment.duration({months: 1})._data,          '1 month is the same as 30 days');\n    assert.deepEqual(moment.duration({months: 12})._data,  moment.duration({years: 1})._data,           '1 years is the same as 12 months');\n});\n\ntest('asGetters', function (assert) {\n    // 400 years have exactly 146097 days\n\n    // years\n    assert.equal(moment.duration(1, 'year').asYears(),            1,           '1 year as years');\n    assert.equal(moment.duration(1, 'year').asMonths(),           12,          '1 year as months');\n    assert.equal(moment.duration(400, 'year').asMonths(),         4800,        '400 years as months');\n    assert.equal(moment.duration(1, 'year').asWeeks().toFixed(3), 52.143,      '1 year as weeks');\n    assert.equal(moment.duration(1, 'year').asDays(),             365,         '1 year as days');\n    assert.equal(moment.duration(2, 'year').asDays(),             730,         '2 years as days');\n    assert.equal(moment.duration(3, 'year').asDays(),             1096,        '3 years as days');\n    assert.equal(moment.duration(4, 'year').asDays(),             1461,        '4 years as days');\n    assert.equal(moment.duration(400, 'year').asDays(),           146097,      '400 years as days');\n    assert.equal(moment.duration(1, 'year').asHours(),            8760,        '1 year as hours');\n    assert.equal(moment.duration(1, 'year').asMinutes(),          525600,      '1 year as minutes');\n    assert.equal(moment.duration(1, 'year').asSeconds(),          31536000,    '1 year as seconds');\n    assert.equal(moment.duration(1, 'year').asMilliseconds(),     31536000000, '1 year as milliseconds');\n\n    // months\n    assert.equal(moment.duration(1, 'month').asYears().toFixed(4), 0.0833,     '1 month as years');\n    assert.equal(moment.duration(1, 'month').asMonths(),           1,          '1 month as months');\n    assert.equal(moment.duration(1, 'month').asWeeks().toFixed(3), 4.286,      '1 month as weeks');\n    assert.equal(moment.duration(1, 'month').asDays(),             30,         '1 month as days');\n    assert.equal(moment.duration(2, 'month').asDays(),             61,         '2 months as days');\n    assert.equal(moment.duration(3, 'month').asDays(),             91,         '3 months as days');\n    assert.equal(moment.duration(4, 'month').asDays(),             122,        '4 months as days');\n    assert.equal(moment.duration(5, 'month').asDays(),             152,        '5 months as days');\n    assert.equal(moment.duration(6, 'month').asDays(),             183,        '6 months as days');\n    assert.equal(moment.duration(7, 'month').asDays(),             213,        '7 months as days');\n    assert.equal(moment.duration(8, 'month').asDays(),             243,        '8 months as days');\n    assert.equal(moment.duration(9, 'month').asDays(),             274,        '9 months as days');\n    assert.equal(moment.duration(10, 'month').asDays(),            304,        '10 months as days');\n    assert.equal(moment.duration(11, 'month').asDays(),            335,        '11 months as days');\n    assert.equal(moment.duration(12, 'month').asDays(),            365,        '12 months as days');\n    assert.equal(moment.duration(24, 'month').asDays(),            730,        '24 months as days');\n    assert.equal(moment.duration(36, 'month').asDays(),            1096,       '36 months as days');\n    assert.equal(moment.duration(48, 'month').asDays(),            1461,       '48 months as days');\n    assert.equal(moment.duration(4800, 'month').asDays(),          146097,     '4800 months as days');\n    assert.equal(moment.duration(1, 'month').asHours(),            720,        '1 month as hours');\n    assert.equal(moment.duration(1, 'month').asMinutes(),          43200,      '1 month as minutes');\n    assert.equal(moment.duration(1, 'month').asSeconds(),          2592000,    '1 month as seconds');\n    assert.equal(moment.duration(1, 'month').asMilliseconds(),     2592000000, '1 month as milliseconds');\n\n    // weeks\n    assert.equal(moment.duration(1, 'week').asYears().toFixed(4),  0.0192,    '1 week as years');\n    assert.equal(moment.duration(1, 'week').asMonths().toFixed(3), 0.230,     '1 week as months');\n    assert.equal(moment.duration(1, 'week').asWeeks(),             1,         '1 week as weeks');\n    assert.equal(moment.duration(1, 'week').asDays(),              7,         '1 week as days');\n    assert.equal(moment.duration(1, 'week').asHours(),             168,       '1 week as hours');\n    assert.equal(moment.duration(1, 'week').asMinutes(),           10080,     '1 week as minutes');\n    assert.equal(moment.duration(1, 'week').asSeconds(),           604800,    '1 week as seconds');\n    assert.equal(moment.duration(1, 'week').asMilliseconds(),      604800000, '1 week as milliseconds');\n\n    // days\n    assert.equal(moment.duration(1, 'day').asYears().toFixed(4),  0.0027,   '1 day as years');\n    assert.equal(moment.duration(1, 'day').asMonths().toFixed(3), 0.033,    '1 day as months');\n    assert.equal(moment.duration(1, 'day').asWeeks().toFixed(3),  0.143,    '1 day as weeks');\n    assert.equal(moment.duration(1, 'day').asDays(),              1,        '1 day as days');\n    assert.equal(moment.duration(1, 'day').asHours(),             24,       '1 day as hours');\n    assert.equal(moment.duration(1, 'day').asMinutes(),           1440,     '1 day as minutes');\n    assert.equal(moment.duration(1, 'day').asSeconds(),           86400,    '1 day as seconds');\n    assert.equal(moment.duration(1, 'day').asMilliseconds(),      86400000, '1 day as milliseconds');\n\n    // hours\n    assert.equal(moment.duration(1, 'hour').asYears().toFixed(6),  0.000114, '1 hour as years');\n    assert.equal(moment.duration(1, 'hour').asMonths().toFixed(5), 0.00137,  '1 hour as months');\n    assert.equal(moment.duration(1, 'hour').asWeeks().toFixed(5),  0.00595,  '1 hour as weeks');\n    assert.equal(moment.duration(1, 'hour').asDays().toFixed(4),   0.0417,   '1 hour as days');\n    assert.equal(moment.duration(1, 'hour').asHours(),             1,        '1 hour as hours');\n    assert.equal(moment.duration(1, 'hour').asMinutes(),           60,       '1 hour as minutes');\n    assert.equal(moment.duration(1, 'hour').asSeconds(),           3600,     '1 hour as seconds');\n    assert.equal(moment.duration(1, 'hour').asMilliseconds(),      3600000,  '1 hour as milliseconds');\n\n    // minutes\n    assert.equal(moment.duration(1, 'minute').asYears().toFixed(8),  0.00000190, '1 minute as years');\n    assert.equal(moment.duration(1, 'minute').asMonths().toFixed(7), 0.0000228,  '1 minute as months');\n    assert.equal(moment.duration(1, 'minute').asWeeks().toFixed(7),  0.0000992,  '1 minute as weeks');\n    assert.equal(moment.duration(1, 'minute').asDays().toFixed(6),   0.000694,   '1 minute as days');\n    assert.equal(moment.duration(1, 'minute').asHours().toFixed(4),  0.0167,     '1 minute as hours');\n    assert.equal(moment.duration(1, 'minute').asMinutes(),           1,          '1 minute as minutes');\n    assert.equal(moment.duration(1, 'minute').asSeconds(),           60,         '1 minute as seconds');\n    assert.equal(moment.duration(1, 'minute').asMilliseconds(),      60000,      '1 minute as milliseconds');\n\n    // seconds\n    assert.equal(moment.duration(1, 'second').asYears().toFixed(10),  0.0000000317, '1 second as years');\n    assert.equal(moment.duration(1, 'second').asMonths().toFixed(9),  0.000000380,  '1 second as months');\n    assert.equal(moment.duration(1, 'second').asWeeks().toFixed(8),   0.00000165,   '1 second as weeks');\n    assert.equal(moment.duration(1, 'second').asDays().toFixed(7),    0.0000116,    '1 second as days');\n    assert.equal(moment.duration(1, 'second').asHours().toFixed(6),   0.000278,     '1 second as hours');\n    assert.equal(moment.duration(1, 'second').asMinutes().toFixed(4), 0.0167,       '1 second as minutes');\n    assert.equal(moment.duration(1, 'second').asSeconds(),            1,            '1 second as seconds');\n    assert.equal(moment.duration(1, 'second').asMilliseconds(),       1000,         '1 second as milliseconds');\n\n    // milliseconds\n    assert.equal(moment.duration(1, 'millisecond').asYears().toFixed(13),  0.0000000000317, '1 millisecond as years');\n    assert.equal(moment.duration(1, 'millisecond').asMonths().toFixed(12), 0.000000000380,  '1 millisecond as months');\n    assert.equal(moment.duration(1, 'millisecond').asWeeks().toFixed(11),  0.00000000165,   '1 millisecond as weeks');\n    assert.equal(moment.duration(1, 'millisecond').asDays().toFixed(10),   0.0000000116,    '1 millisecond as days');\n    assert.equal(moment.duration(1, 'millisecond').asHours().toFixed(9),   0.000000278,     '1 millisecond as hours');\n    assert.equal(moment.duration(1, 'millisecond').asMinutes().toFixed(7), 0.0000167,       '1 millisecond as minutes');\n    assert.equal(moment.duration(1, 'millisecond').asSeconds(),            0.001,           '1 millisecond as seconds');\n    assert.equal(moment.duration(1, 'millisecond').asMilliseconds(),       1,               '1 millisecond as milliseconds');\n});\n\ntest('as getters for small units', function (assert) {\n    var dS = moment.duration(1, 'milliseconds'),\n        ds = moment.duration(3, 'seconds'),\n        dm = moment.duration(13, 'minutes');\n\n    // Tests for issue #1867.\n    // Floating point errors for small duration units were introduced in version 2.8.0.\n    assert.equal(dS.as('milliseconds'), 1, 'as(\"milliseconds\")');\n    assert.equal(dS.asMilliseconds(),   1, 'asMilliseconds()');\n    assert.equal(ds.as('seconds'),      3, 'as(\"seconds\")');\n    assert.equal(ds.asSeconds(),        3, 'asSeconds()');\n    assert.equal(dm.as('minutes'),      13, 'as(\"minutes\")');\n    assert.equal(dm.asMinutes(),        13, 'asMinutes()');\n});\n\ntest('minutes getter for floating point hours', function (assert) {\n    // Tests for issue #2978.\n    // For certain floating point hours, .minutes() getter produced incorrect values due to the rounding errors\n    assert.equal(moment.duration(2.3, 'h').minutes(), 18, 'minutes()');\n    assert.equal(moment.duration(4.1, 'h').minutes(), 6, 'minutes()');\n});\n\ntest('isDuration', function (assert) {\n    assert.ok(moment.isDuration(moment.duration(12345678)), 'correctly says true');\n    assert.ok(!moment.isDuration(moment()), 'moment object is not a duration');\n    assert.ok(!moment.isDuration({milliseconds: 1}), 'plain object is not a duration');\n});\n\ntest('add', function (assert) {\n    var d = moment.duration({months: 4, weeks: 3, days: 2});\n    // for some reason, d._data._months does not get updated; use d._months instead.\n    assert.equal(d.add(1, 'month')._months, 5, 'Add months');\n    assert.equal(d.add(5, 'days')._days, 28, 'Add days');\n    assert.equal(d.add(10000)._milliseconds, 10000, 'Add milliseconds');\n    assert.equal(d.add({h: 23, m: 59})._milliseconds, 23 * 60 * 60 * 1000 + 59 * 60 * 1000 + 10000, 'Add hour:minute');\n});\n\ntest('add and bubble', function (assert) {\n    var d;\n\n    assert.equal(moment.duration(1, 'second').add(1000, 'milliseconds').seconds(), 2, 'Adding milliseconds should bubble up to seconds');\n    assert.equal(moment.duration(1, 'minute').add(60, 'second').minutes(), 2, 'Adding seconds should bubble up to minutes');\n    assert.equal(moment.duration(1, 'hour').add(60, 'minutes').hours(), 2, 'Adding minutes should bubble up to hours');\n    assert.equal(moment.duration(1, 'day').add(24, 'hours').days(), 2, 'Adding hours should bubble up to days');\n\n    d = moment.duration(-1, 'day').add(1, 'hour');\n    assert.equal(d.hours(), -23, '-1 day + 1 hour == -23 hour (component)');\n    assert.equal(d.asHours(), -23, '-1 day + 1 hour == -23 hours');\n\n    d = moment.duration(-1, 'year').add(1, 'day');\n    assert.equal(d.days(), -30, '- 1 year + 1 day == -30 days (component)');\n    assert.equal(d.months(), -11, '- 1 year + 1 day == -11 months (component)');\n    assert.equal(d.years(), 0, '- 1 year + 1 day == 0 years (component)');\n    assert.equal(d.asDays(), -364, '- 1 year + 1 day == -364 days');\n\n    d = moment.duration(-1, 'year').add(1, 'hour');\n    assert.equal(d.hours(), -23, '- 1 year + 1 hour == -23 hours (component)');\n    assert.equal(d.days(), -30, '- 1 year + 1 hour == -30 days (component)');\n    assert.equal(d.months(), -11, '- 1 year + 1 hour == -11 months (component)');\n    assert.equal(d.years(), 0, '- 1 year + 1 hour == 0 years (component)');\n});\n\ntest('subtract and bubble', function (assert) {\n    var d;\n\n    assert.equal(moment.duration(2, 'second').subtract(1000, 'milliseconds').seconds(), 1, 'Subtracting milliseconds should bubble up to seconds');\n    assert.equal(moment.duration(2, 'minute').subtract(60, 'second').minutes(), 1, 'Subtracting seconds should bubble up to minutes');\n    assert.equal(moment.duration(2, 'hour').subtract(60, 'minutes').hours(), 1, 'Subtracting minutes should bubble up to hours');\n    assert.equal(moment.duration(2, 'day').subtract(24, 'hours').days(), 1, 'Subtracting hours should bubble up to days');\n\n    d = moment.duration(1, 'day').subtract(1, 'hour');\n    assert.equal(d.hours(), 23, '1 day - 1 hour == 23 hour (component)');\n    assert.equal(d.asHours(), 23, '1 day - 1 hour == 23 hours');\n\n    d = moment.duration(1, 'year').subtract(1, 'day');\n    assert.equal(d.days(), 30, '1 year - 1 day == 30 days (component)');\n    assert.equal(d.months(), 11, '1 year - 1 day == 11 months (component)');\n    assert.equal(d.years(), 0, '1 year - 1 day == 0 years (component)');\n    assert.equal(d.asDays(), 364, '1 year - 1 day == 364 days');\n\n    d = moment.duration(1, 'year').subtract(1, 'hour');\n    assert.equal(d.hours(), 23, '1 year - 1 hour == 23 hours (component)');\n    assert.equal(d.days(), 30, '1 year - 1 hour == 30 days (component)');\n    assert.equal(d.months(), 11, '1 year - 1 hour == 11 months (component)');\n    assert.equal(d.years(), 0, '1 year - 1 hour == 0 years (component)');\n});\n\ntest('subtract', function (assert) {\n    var d = moment.duration({months: 2, weeks: 2, days: 0, hours: 5});\n    // for some reason, d._data._months does not get updated; use d._months instead.\n    assert.equal(d.subtract(1, 'months')._months, 1, 'Subtract months');\n    assert.equal(d.subtract(14, 'days')._days, 0, 'Subtract days');\n    assert.equal(d.subtract(10000)._milliseconds, 5 * 60 * 60 * 1000 - 10000, 'Subtract milliseconds');\n    assert.equal(d.subtract({h: 1, m: 59})._milliseconds, 3 * 60 * 60 * 1000 + 1 * 60 * 1000 - 10000, 'Subtract hour:minute');\n});\n\ntest('JSON.stringify duration', function (assert) {\n    var d = moment.duration(1024, 'h');\n\n    assert.equal(JSON.stringify(d), '\"' + d.toISOString() + '\"', 'JSON.stringify on duration should return ISO string');\n});\n\ntest('duration plugins', function (assert) {\n    var durationObject = moment.duration();\n    moment.duration.fn.foo = function (arg) {\n        assert.equal(this, durationObject);\n        assert.equal(arg, 5);\n    };\n    durationObject.foo(5);\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\nfunction module$1 (name, lifecycle) {\n    QUnit.module(name, {\n        setup : function () {\n            moment.locale('en');\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'core');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            teardownDeprecationHandler(test, moment, 'core');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n}\n\nmodule$1('duration from moments');\n\ntest('pure year diff', function (assert) {\n    var m1 = moment('2012-01-01T00:00:00.000Z'),\n        m2 = moment('2013-01-01T00:00:00.000Z');\n\n    assert.equal(moment.duration({from: m1, to: m2}).as('years'), 1, 'year moment difference');\n    assert.equal(moment.duration({from: m2, to: m1}).as('years'), -1, 'negative year moment difference');\n});\n\ntest('month and day diff', function (assert) {\n    var m1 = moment('2012-01-15T00:00:00.000Z'),\n        m2 = moment('2012-02-17T00:00:00.000Z'),\n        d = moment.duration({from: m1, to: m2});\n\n    assert.equal(d.get('days'), 2);\n    assert.equal(d.get('months'), 1);\n});\n\ntest('day diff, separate months', function (assert) {\n    var m1 = moment('2012-01-15T00:00:00.000Z'),\n        m2 = moment('2012-02-13T00:00:00.000Z'),\n        d = moment.duration({from: m1, to: m2});\n\n    assert.equal(d.as('days'), 29);\n});\n\ntest('hour diff', function (assert) {\n    var m1 = moment('2012-01-15T17:00:00.000Z'),\n        m2 = moment('2012-01-16T03:00:00.000Z'),\n        d = moment.duration({from: m1, to: m2});\n\n    assert.equal(d.as('hours'), 10);\n});\n\ntest('minute diff', function (assert) {\n    var m1 = moment('2012-01-15T17:45:00.000Z'),\n        m2 = moment('2012-01-16T03:15:00.000Z'),\n        d = moment.duration({from: m1, to: m2});\n\n    assert.equal(d.as('hours'), 9.5);\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\nfunction module$1 (name, lifecycle) {\n    QUnit.module(name, {\n        setup : function () {\n            moment.locale('en');\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'core');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            teardownDeprecationHandler(test, moment, 'core');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n}\n\nmodule$1('invalid');\n\ntest('invalid duration', function (assert) {\n    var m = moment.duration.invalid(); // should be invalid\n    assert.equal(m.isValid(), false);\n    assert.ok(isNaN(m.valueOf()));\n});\n\ntest('valid duration', function (assert) {\n    var m = moment.duration({d: null}); // should be valid, for now\n    assert.equal(m.isValid(), true);\n    assert.equal(m.valueOf(), 0);\n});\n\ntest('invalid duration - only smallest unit can have decimal', function (assert) {\n    var m = moment.duration({'days': 3.5, 'hours': 1.1}); // should be invalid\n    assert.equal(m.isValid(), false);\n    assert.ok(isNaN(m.valueOf())); // .valueOf() returns NaN for invalid durations\n});\n\ntest('valid duration - smallest unit can have decimal', function (assert) {\n    var m = moment.duration({'days': 3, 'hours': 1.1}); // should be valid\n    assert.equal(m.isValid(), true);\n    assert.equal(m.asHours(), 73.1);\n});\n\ntest('invalid duration with two arguments', function (assert) {\n    var m = moment.duration(NaN, 'days');\n    assert.equal(m.isValid(), false);\n    assert.ok(isNaN(m.valueOf()));\n});\n\ntest('invalid duration operations', function (assert) {\n    var invalids = [\n            moment.duration(NaN),\n            moment.duration(NaN, 'days'),\n            moment.duration.invalid()\n        ],\n        i,\n        invalid,\n        valid = moment.duration();\n\n    for (i = 0; i < invalids.length; ++i) {\n        invalid = invalids[i];\n\n        assert.ok(!invalid.add(5, 'hours').isValid(), 'invalid.add is invalid; i=' + i);\n        assert.ok(!invalid.subtract(30, 'days').isValid(), 'invalid.subtract is invalid; i=' + i);\n        assert.ok(!invalid.abs().isValid(), 'invalid.abs is invalid; i=' + i);\n        assert.ok(isNaN(invalid.as('years')), 'invalid.as is NaN; i=' + i);\n        assert.ok(isNaN(invalid.asMilliseconds()), 'invalid.asMilliseconds is NaN; i=' + i);\n        assert.ok(isNaN(invalid.asSeconds()), 'invalid.asSeconds is NaN; i=' + i);\n        assert.ok(isNaN(invalid.asMinutes()), 'invalid.asMinutes is NaN; i=' + i);\n        assert.ok(isNaN(invalid.asHours()), 'invalid.asHours is NaN; i=' + i);\n        assert.ok(isNaN(invalid.asDays()), 'invalid.asDays is NaN; i=' + i);\n        assert.ok(isNaN(invalid.asWeeks()), 'invalid.asWeeks is NaN; i=' + i);\n        assert.ok(isNaN(invalid.asMonths()), 'invalid.asMonths is NaN; i=' + i);\n        assert.ok(isNaN(invalid.asYears()), 'invalid.asYears is NaN; i=' + i);\n        assert.ok(isNaN(invalid.valueOf()), 'invalid.valueOf is NaN; i=' + i);\n        assert.ok(isNaN(invalid.get('hours')), 'invalid.get is NaN; i=' + i);\n\n        assert.ok(isNaN(invalid.milliseconds()), 'invalid.milliseconds is NaN; i=' + i);\n        assert.ok(isNaN(invalid.seconds()), 'invalid.seconds is NaN; i=' + i);\n        assert.ok(isNaN(invalid.minutes()), 'invalid.minutes is NaN; i=' + i);\n        assert.ok(isNaN(invalid.hours()), 'invalid.hours is NaN; i=' + i);\n        assert.ok(isNaN(invalid.days()), 'invalid.days is NaN; i=' + i);\n        assert.ok(isNaN(invalid.weeks()), 'invalid.weeks is NaN; i=' + i);\n        assert.ok(isNaN(invalid.months()), 'invalid.months is NaN; i=' + i);\n        assert.ok(isNaN(invalid.years()), 'invalid.years is NaN; i=' + i);\n\n        assert.equal(invalid.humanize(),\n                     invalid.localeData().invalidDate(),\n                     'invalid.humanize is localized invalid duration string; i=' + i);\n        assert.equal(invalid.toISOString(),\n                     invalid.localeData().invalidDate(),\n                     'invalid.toISOString is localized invalid duration string; i=' + i);\n        assert.equal(invalid.toString(),\n                     invalid.localeData().invalidDate(),\n                     'invalid.toString is localized invalid duration string; i=' + i);\n        assert.equal(invalid.toJSON(), invalid.localeData().invalidDate(), 'invalid.toJSON is null; i=' + i);\n        assert.equal(invalid.locale(), 'en', 'invalid.locale; i=' + i);\n        assert.equal(invalid.localeData()._abbr, 'en', 'invalid.localeData()._abbr; i=' + i);\n    }\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\nfunction module$1 (name, lifecycle) {\n    QUnit.module(name, {\n        setup : function () {\n            moment.locale('en');\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'core');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            teardownDeprecationHandler(test, moment, 'core');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n}\n\nmodule$1('format');\n\ntest('format YY', function (assert) {\n    var b = moment(new Date(2009, 1, 14, 15, 25, 50, 125));\n    assert.equal(b.format('YY'), '09', 'YY ---> 09');\n});\n\ntest('format escape brackets', function (assert) {\n    moment.locale('en');\n\n    var b = moment(new Date(2009, 1, 14, 15, 25, 50, 125));\n    assert.equal(b.format('[day]'), 'day', 'Single bracket');\n    assert.equal(b.format('[day] YY [YY]'), 'day 09 YY', 'Double bracket');\n    assert.equal(b.format('[YY'), '[09', 'Un-ended bracket');\n    assert.equal(b.format('[[YY]]'), '[YY]', 'Double nested brackets');\n    assert.equal(b.format('[[]'), '[', 'Escape open bracket');\n    assert.equal(b.format('[Last]'), 'Last', 'localized tokens');\n    assert.equal(b.format('[L] L'), 'L 02/14/2009', 'localized tokens with escaped localized tokens');\n    assert.equal(b.format('[L LL LLL LLLL aLa]'), 'L LL LLL LLLL aLa', 'localized tokens with escaped localized tokens');\n    assert.equal(b.format('[LLL] LLL'), 'LLL February 14, 2009 3:25 PM', 'localized tokens with escaped localized tokens (recursion)');\n    assert.equal(b.format('YYYY[\\n]DD[\\n]'), '2009\\n14\\n', 'Newlines');\n});\n\ntest('handle negative years', function (assert) {\n    moment.locale('en');\n    assert.equal(moment.utc().year(-1).format('YY'), '-01', 'YY with negative year');\n    assert.equal(moment.utc().year(-1).format('YYYY'), '-0001', 'YYYY with negative year');\n    assert.equal(moment.utc().year(-12).format('YY'), '-12', 'YY with negative year');\n    assert.equal(moment.utc().year(-12).format('YYYY'), '-0012', 'YYYY with negative year');\n    assert.equal(moment.utc().year(-123).format('YY'), '-23', 'YY with negative year');\n    assert.equal(moment.utc().year(-123).format('YYYY'), '-0123', 'YYYY with negative year');\n    assert.equal(moment.utc().year(-1234).format('YY'), '-34', 'YY with negative year');\n    assert.equal(moment.utc().year(-1234).format('YYYY'), '-1234', 'YYYY with negative year');\n    assert.equal(moment.utc().year(-12345).format('YY'), '-45', 'YY with negative year');\n    assert.equal(moment.utc().year(-12345).format('YYYY'), '-12345', 'YYYY with negative year');\n});\n\ntest('format milliseconds', function (assert) {\n    var b = moment(new Date(2009, 1, 14, 15, 25, 50, 123));\n    assert.equal(b.format('S'), '1', 'Deciseconds');\n    assert.equal(b.format('SS'), '12', 'Centiseconds');\n    assert.equal(b.format('SSS'), '123', 'Milliseconds');\n    b.milliseconds(789);\n    assert.equal(b.format('S'), '7', 'Deciseconds');\n    assert.equal(b.format('SS'), '78', 'Centiseconds');\n    assert.equal(b.format('SSS'), '789', 'Milliseconds');\n});\n\ntest('format timezone', function (assert) {\n    var b = moment(new Date(2010, 1, 14, 15, 25, 50, 125));\n    assert.ok(b.format('Z').match(/^[\\+\\-]\\d\\d:\\d\\d$/), b.format('Z') + ' should be something like \\'+07:30\\'');\n    assert.ok(b.format('ZZ').match(/^[\\+\\-]\\d{4}$/), b.format('ZZ') + ' should be something like \\'+0700\\'');\n});\n\ntest('format multiple with utc offset', function (assert) {\n    var b = moment('2012-10-08 -1200', ['YYYY-MM-DD HH:mm ZZ', 'YYYY-MM-DD ZZ', 'YYYY-MM-DD']);\n    assert.equal(b.format('YYYY-MM'), '2012-10', 'Parsing multiple formats should not crash with different sized formats');\n});\n\ntest('isDST', function (assert) {\n    var janOffset = new Date(2011, 0, 1).getTimezoneOffset(),\n        julOffset = new Date(2011, 6, 1).getTimezoneOffset(),\n        janIsDst = janOffset < julOffset,\n        julIsDst = julOffset < janOffset,\n        jan1 = moment([2011]),\n        jul1 = moment([2011, 6]);\n\n    if (janIsDst && julIsDst) {\n        assert.ok(0, 'January and July cannot both be in DST');\n        assert.ok(0, 'January and July cannot both be in DST');\n    } else if (janIsDst) {\n        assert.ok(jan1.isDST(), 'January 1 is DST');\n        assert.ok(!jul1.isDST(), 'July 1 is not DST');\n    } else if (julIsDst) {\n        assert.ok(!jan1.isDST(), 'January 1 is not DST');\n        assert.ok(jul1.isDST(), 'July 1 is DST');\n    } else {\n        assert.ok(!jan1.isDST(), 'January 1 is not DST');\n        assert.ok(!jul1.isDST(), 'July 1 is not DST');\n    }\n});\n\ntest('unix timestamp', function (assert) {\n    var m = moment('1234567890.123', 'X');\n    assert.equal(m.format('X'), '1234567890', 'unix timestamp without milliseconds');\n    assert.equal(m.format('X.S'), '1234567890.1', 'unix timestamp with deciseconds');\n    assert.equal(m.format('X.SS'), '1234567890.12', 'unix timestamp with centiseconds');\n    assert.equal(m.format('X.SSS'), '1234567890.123', 'unix timestamp with milliseconds');\n\n    m = moment(1234567890.123, 'X');\n    assert.equal(m.format('X'), '1234567890', 'unix timestamp as integer');\n});\n\ntest('unix offset milliseconds', function (assert) {\n    var m = moment('1234567890123', 'x');\n    assert.equal(m.format('x'), '1234567890123', 'unix offset in milliseconds');\n\n    m = moment(1234567890123, 'x');\n    assert.equal(m.format('x'), '1234567890123', 'unix offset in milliseconds as integer');\n});\n\ntest('utcOffset sanity checks', function (assert) {\n    assert.equal(moment().utcOffset() % 15, 0,\n            'utc offset should be a multiple of 15 (was ' + moment().utcOffset() + ')');\n\n    assert.equal(moment().utcOffset(), -(new Date()).getTimezoneOffset(),\n        'utcOffset should return the opposite of getTimezoneOffset');\n});\n\ntest('default format', function (assert) {\n    var isoRegex = /\\d{4}.\\d\\d.\\d\\dT\\d\\d.\\d\\d.\\d\\d[\\+\\-]\\d\\d:\\d\\d/;\n    assert.ok(isoRegex.exec(moment().format()), 'default format (' + moment().format() + ') should match ISO');\n});\n\ntest('default UTC format', function (assert) {\n    var isoRegex = /\\d{4}.\\d\\d.\\d\\dT\\d\\d.\\d\\d.\\d\\dZ/;\n    assert.ok(isoRegex.exec(moment.utc().format()), 'default UTC format (' + moment.utc().format() + ') should match ISO');\n});\n\ntest('toJSON', function (assert) {\n    var supportsJson = typeof JSON !== 'undefined' && JSON.stringify && JSON.stringify.call,\n        date = moment('2012-10-09T21:30:40.678+0100');\n\n    assert.equal(date.toJSON(), '2012-10-09T20:30:40.678Z', 'should output ISO8601 on moment.fn.toJSON');\n\n    if (supportsJson) {\n        assert.equal(JSON.stringify({\n            date : date\n        }), '{\"date\":\"2012-10-09T20:30:40.678Z\"}', 'should output ISO8601 on JSON.stringify');\n    }\n});\n\ntest('toISOString', function (assert) {\n    var date = moment.utc('2012-10-09T20:30:40.678');\n\n    assert.equal(date.toISOString(), '2012-10-09T20:30:40.678Z', 'should output ISO8601 on moment.fn.toISOString');\n\n    // big years\n    date = moment.utc('+020123-10-09T20:30:40.678');\n    assert.equal(date.toISOString(), '+020123-10-09T20:30:40.678Z', 'ISO8601 format on big positive year');\n    // negative years\n    date = moment.utc('-000001-10-09T20:30:40.678');\n    assert.equal(date.toISOString(), '-000001-10-09T20:30:40.678Z', 'ISO8601 format on negative year');\n    // big negative years\n    date = moment.utc('-020123-10-09T20:30:40.678');\n    assert.equal(date.toISOString(), '-020123-10-09T20:30:40.678Z', 'ISO8601 format on big negative year');\n\n    //invalid dates\n    date = moment.utc('2017-12-32');\n    assert.equal(date.toISOString(), null, 'An invalid date to iso string is null');\n});\n\n// See https://nodejs.org/dist/latest/docs/api/util.html#util_custom_inspect_function_on_objects\ntest('inspect', function (assert) {\n    function roundtrip(m) {\n        /*jshint evil:true */\n        return (new Function('moment', 'return ' + m.inspect()))(moment);\n    }\n    function testInspect(date, string) {\n        var inspected = date.inspect();\n        assert.equal(inspected, string);\n        assert.ok(date.isSame(roundtrip(date)), 'Tried to parse ' + inspected);\n    }\n\n    testInspect(\n        moment('2012-10-09T20:30:40.678'),\n        'moment(\"2012-10-09T20:30:40.678\")'\n    );\n    testInspect(\n        moment('+020123-10-09T20:30:40.678'),\n        'moment(\"+020123-10-09T20:30:40.678\")'\n    );\n    testInspect(\n        moment.utc('2012-10-09T20:30:40.678'),\n        'moment.utc(\"2012-10-09T20:30:40.678+00:00\")'\n    );\n    testInspect(\n        moment.utc('+020123-10-09T20:30:40.678'),\n        'moment.utc(\"+020123-10-09T20:30:40.678+00:00\")'\n    );\n    testInspect(\n        moment.utc('+020123-10-09T20:30:40.678+01:00'),\n        'moment.utc(\"+020123-10-09T19:30:40.678+00:00\")'\n    );\n    testInspect(\n        moment.parseZone('2016-06-11T17:30:40.678+0430'),\n        'moment.parseZone(\"2016-06-11T17:30:40.678+04:30\")'\n    );\n    testInspect(\n        moment.parseZone('+112016-06-11T17:30:40.678+0430'),\n        'moment.parseZone(\"+112016-06-11T17:30:40.678+04:30\")'\n    );\n\n    assert.equal(\n        moment(new Date('nope')).inspect(),\n        'moment.invalid(/* Invalid Date */)'\n    );\n    assert.equal(\n        moment('blah', 'YYYY').inspect(),\n        'moment.invalid(/* blah */)'\n    );\n});\n\ntest('long years', function (assert) {\n    assert.equal(moment.utc().year(2).format('YYYYYY'), '+000002', 'small year with YYYYYY');\n    assert.equal(moment.utc().year(2012).format('YYYYYY'), '+002012', 'regular year with YYYYYY');\n    assert.equal(moment.utc().year(20123).format('YYYYYY'), '+020123', 'big year with YYYYYY');\n\n    assert.equal(moment.utc().year(-1).format('YYYYYY'), '-000001', 'small negative year with YYYYYY');\n    assert.equal(moment.utc().year(-2012).format('YYYYYY'), '-002012', 'negative year with YYYYYY');\n    assert.equal(moment.utc().year(-20123).format('YYYYYY'), '-020123', 'big negative year with YYYYYY');\n});\n\ntest('toISOString() when 0 year', function (assert) {\n    // https://github.com/moment/moment/issues/3765\n    var date = moment('0000-01-01T21:00:00.000Z');\n    assert.equal(date.toISOString(), '0000-01-01T21:00:00.000Z');\n    assert.equal(date.toDate().toISOString(), '0000-01-01T21:00:00.000Z');\n});\n\ntest('iso week formats', function (assert) {\n    // https://en.wikipedia.org/wiki/ISO_week_date\n    var cases = {\n        '2005-01-02': '2004-53',\n        '2005-12-31': '2005-52',\n        '2007-01-01': '2007-01',\n        '2007-12-30': '2007-52',\n        '2007-12-31': '2008-01',\n        '2008-01-01': '2008-01',\n        '2008-12-28': '2008-52',\n        '2008-12-29': '2009-01',\n        '2008-12-30': '2009-01',\n        '2008-12-31': '2009-01',\n        '2009-01-01': '2009-01',\n        '2009-12-31': '2009-53',\n        '2010-01-01': '2009-53',\n        '2010-01-02': '2009-53',\n        '2010-01-03': '2009-53',\n        '404-12-31': '0404-53',\n        '405-12-31': '0405-52'\n    }, i, isoWeek, formatted2, formatted1;\n\n    for (i in cases) {\n        isoWeek = cases[i].split('-').pop();\n        formatted2 = moment(i, 'YYYY-MM-DD').format('WW');\n        assert.equal(isoWeek, formatted2, i + ': WW should be ' + isoWeek + ', but ' + formatted2);\n        isoWeek = isoWeek.replace(/^0+/, '');\n        formatted1 = moment(i, 'YYYY-MM-DD').format('W');\n        assert.equal(isoWeek, formatted1, i + ': W should be ' + isoWeek + ', but ' + formatted1);\n    }\n});\n\ntest('iso week year formats', function (assert) {\n    // https://en.wikipedia.org/wiki/ISO_week_date\n    var cases = {\n        '2005-01-02': '2004-53',\n        '2005-12-31': '2005-52',\n        '2007-01-01': '2007-01',\n        '2007-12-30': '2007-52',\n        '2007-12-31': '2008-01',\n        '2008-01-01': '2008-01',\n        '2008-12-28': '2008-52',\n        '2008-12-29': '2009-01',\n        '2008-12-30': '2009-01',\n        '2008-12-31': '2009-01',\n        '2009-01-01': '2009-01',\n        '2009-12-31': '2009-53',\n        '2010-01-01': '2009-53',\n        '2010-01-02': '2009-53',\n        '2010-01-03': '2009-53',\n        '404-12-31': '0404-53',\n        '405-12-31': '0405-52'\n    }, i, isoWeekYear, formatted5, formatted4, formatted2;\n\n    for (i in cases) {\n        isoWeekYear = cases[i].split('-')[0];\n        formatted5 = moment(i, 'YYYY-MM-DD').format('GGGGG');\n        assert.equal('0' + isoWeekYear, formatted5, i + ': GGGGG should be ' + isoWeekYear + ', but ' + formatted5);\n        formatted4 = moment(i, 'YYYY-MM-DD').format('GGGG');\n        assert.equal(isoWeekYear, formatted4, i + ': GGGG should be ' + isoWeekYear + ', but ' + formatted4);\n        formatted2 = moment(i, 'YYYY-MM-DD').format('GG');\n        assert.equal(isoWeekYear.slice(2, 4), formatted2, i + ': GG should be ' + isoWeekYear + ', but ' + formatted2);\n    }\n});\n\ntest('week year formats', function (assert) {\n    // https://en.wikipedia.org/wiki/ISO_week_date\n    var cases = {\n        '2005-01-02': '2004-53',\n        '2005-12-31': '2005-52',\n        '2007-01-01': '2007-01',\n        '2007-12-30': '2007-52',\n        '2007-12-31': '2008-01',\n        '2008-01-01': '2008-01',\n        '2008-12-28': '2008-52',\n        '2008-12-29': '2009-01',\n        '2008-12-30': '2009-01',\n        '2008-12-31': '2009-01',\n        '2009-01-01': '2009-01',\n        '2009-12-31': '2009-53',\n        '2010-01-01': '2009-53',\n        '2010-01-02': '2009-53',\n        '2010-01-03': '2009-53',\n        '404-12-31': '0404-53',\n        '405-12-31': '0405-52'\n    }, i, isoWeekYear, formatted5, formatted4, formatted2;\n\n    moment.defineLocale('dow:1,doy:4', {week: {dow: 1, doy: 4}});\n\n    for (i in cases) {\n        isoWeekYear = cases[i].split('-')[0];\n        formatted5 = moment(i, 'YYYY-MM-DD').format('ggggg');\n        assert.equal('0' + isoWeekYear, formatted5, i + ': ggggg should be ' + isoWeekYear + ', but ' + formatted5);\n        formatted4 = moment(i, 'YYYY-MM-DD').format('gggg');\n        assert.equal(isoWeekYear, formatted4, i + ': gggg should be ' + isoWeekYear + ', but ' + formatted4);\n        formatted2 = moment(i, 'YYYY-MM-DD').format('gg');\n        assert.equal(isoWeekYear.slice(2, 4), formatted2, i + ': gg should be ' + isoWeekYear + ', but ' + formatted2);\n    }\n    moment.defineLocale('dow:1,doy:4', null);\n});\n\ntest('iso weekday formats', function (assert) {\n    assert.equal(moment([1985, 1,  4]).format('E'), '1', 'Feb  4 1985 is Monday    -- 1st day');\n    assert.equal(moment([2029, 8, 18]).format('E'), '2', 'Sep 18 2029 is Tuesday   -- 2nd day');\n    assert.equal(moment([2013, 3, 24]).format('E'), '3', 'Apr 24 2013 is Wednesday -- 3rd day');\n    assert.equal(moment([2015, 2,  5]).format('E'), '4', 'Mar  5 2015 is Thursday  -- 4th day');\n    assert.equal(moment([1970, 0,  2]).format('E'), '5', 'Jan  2 1970 is Friday    -- 5th day');\n    assert.equal(moment([2001, 4, 12]).format('E'), '6', 'May 12 2001 is Saturday  -- 6th day');\n    assert.equal(moment([2000, 0,  2]).format('E'), '7', 'Jan  2 2000 is Sunday    -- 7th day');\n});\n\ntest('weekday formats', function (assert) {\n    moment.defineLocale('dow: 3,doy: 5', {week: {dow: 3, doy: 5}});\n    assert.equal(moment([1985, 1,  6]).format('e'), '0', 'Feb  6 1985 is Wednesday -- 0th day');\n    assert.equal(moment([2029, 8, 20]).format('e'), '1', 'Sep 20 2029 is Thursday  -- 1st day');\n    assert.equal(moment([2013, 3, 26]).format('e'), '2', 'Apr 26 2013 is Friday    -- 2nd day');\n    assert.equal(moment([2015, 2,  7]).format('e'), '3', 'Mar  7 2015 is Saturday  -- 3nd day');\n    assert.equal(moment([1970, 0,  4]).format('e'), '4', 'Jan  4 1970 is Sunday    -- 4th day');\n    assert.equal(moment([2001, 4, 14]).format('e'), '5', 'May 14 2001 is Monday    -- 5th day');\n    assert.equal(moment([2000, 0,  4]).format('e'), '6', 'Jan  4 2000 is Tuesday   -- 6th day');\n    moment.defineLocale('dow: 3,doy: 5', null);\n});\n\ntest('toString is just human readable format', function (assert) {\n    var b = moment(new Date(2009, 1, 5, 15, 25, 50, 125));\n    assert.equal(b.toString(), b.format('ddd MMM DD YYYY HH:mm:ss [GMT]ZZ'));\n});\n\ntest('toJSON skips postformat', function (assert) {\n    moment.defineLocale('postformat', {\n        postformat: function (s) {\n            s.replace(/./g, 'X');\n        }\n    });\n    assert.equal(moment.utc([2000, 0, 1]).toJSON(), '2000-01-01T00:00:00.000Z', 'toJSON doesn\\'t postformat');\n    moment.defineLocale('postformat', null);\n});\n\ntest('calendar day timezone', function (assert) {\n    moment.locale('en');\n    var zones = [60, -60, 90, -90, 360, -360, 720, -720],\n        b = moment().utc().startOf('day').subtract({m : 1}),\n        c = moment().local().startOf('day').subtract({m : 1}),\n        d = moment().local().startOf('day').subtract({d : 2}),\n        i, z, a;\n\n    for (i = 0; i < zones.length; ++i) {\n        z = zones[i];\n        a = moment().utcOffset(z).startOf('day').subtract({m: 1});\n        assert.equal(moment(a).utcOffset(z).calendar(), 'Yesterday at 11:59 PM',\n                     'Yesterday at 11:59 PM, not Today, or the wrong time, tz = ' + z);\n    }\n\n    assert.equal(moment(b).utc().calendar(), 'Yesterday at 11:59 PM', 'Yesterday at 11:59 PM, not Today, or the wrong time');\n    assert.equal(moment(c).local().calendar(), 'Yesterday at 11:59 PM', 'Yesterday at 11:59 PM, not Today, or the wrong time');\n    assert.equal(moment(c).local().calendar(d), 'Tomorrow at 11:59 PM', 'Tomorrow at 11:59 PM, not Yesterday, or the wrong time');\n});\n\ntest('calendar with custom formats', function (assert) {\n    assert.equal(moment().calendar(null, {sameDay: '[Today]'}), 'Today', 'Today');\n    assert.equal(moment().add(1, 'days').calendar(null, {nextDay: '[Tomorrow]'}), 'Tomorrow', 'Tomorrow');\n    assert.equal(moment([1985, 1, 4]).calendar(null, {sameElse: 'YYYY-MM-DD'}), '1985-02-04', 'Else');\n});\n\ntest('invalid', function (assert) {\n    assert.equal(moment.invalid().format(), 'Invalid date');\n    assert.equal(moment.invalid().format('YYYY-MM-DD'), 'Invalid date');\n});\n\ntest('quarter formats', function (assert) {\n    assert.equal(moment([1985, 1,  4]).format('Q'), '1', 'Feb  4 1985 is Q1');\n    assert.equal(moment([2029, 8, 18]).format('Q'), '3', 'Sep 18 2029 is Q3');\n    assert.equal(moment([2013, 3, 24]).format('Q'), '2', 'Apr 24 2013 is Q2');\n    assert.equal(moment([2015, 2,  5]).format('Q'), '1', 'Mar  5 2015 is Q1');\n    assert.equal(moment([1970, 0,  2]).format('Q'), '1', 'Jan  2 1970 is Q1');\n    assert.equal(moment([2001, 11, 12]).format('Q'), '4', 'Dec 12 2001 is Q4');\n    assert.equal(moment([2000, 0,  2]).format('[Q]Q-YYYY'), 'Q1-2000', 'Jan  2 2000 is Q1');\n});\n\ntest('quarter ordinal formats', function (assert) {\n    assert.equal(moment([1985, 1, 4]).format('Qo'), '1st', 'Feb 4 1985 is 1st quarter');\n    assert.equal(moment([2029, 8, 18]).format('Qo'), '3rd', 'Sep 18 2029 is 3rd quarter');\n    assert.equal(moment([2013, 3, 24]).format('Qo'), '2nd', 'Apr 24 2013 is 2nd quarter');\n    assert.equal(moment([2015, 2,  5]).format('Qo'), '1st', 'Mar  5 2015 is 1st quarter');\n    assert.equal(moment([1970, 0,  2]).format('Qo'), '1st', 'Jan  2 1970 is 1st quarter');\n    assert.equal(moment([2001, 11, 12]).format('Qo'), '4th', 'Dec 12 2001 is 4th quarter');\n    assert.equal(moment([2000, 0,  2]).format('Qo [quarter] YYYY'), '1st quarter 2000', 'Jan  2 2000 is 1st quarter');\n});\n\n// test('full expanded format is returned from abbreviated formats', function (assert) {\n//     function objectKeys(obj) {\n//         if (Object.keys) {\n//             return Object.keys(obj);\n//         } else {\n//             // IE8\n//             var res = [], i;\n//             for (i in obj) {\n//                 if (obj.hasOwnProperty(i)) {\n//                     res.push(i);\n//                 }\n//             }\n//             return res;\n//         }\n//     }\n\n//     var locales =\n//         'ar-sa ar-tn ar az be bg bn bo br bs ca cs cv cy da de-at de dv el ' +\n//         'en-au en-ca en-gb en-ie en-nz eo es et eu fa fi fo fr-ca fr-ch fr fy ' +\n//         'gd gl he hi hr hu hy-am id is it ja jv ka kk km ko lb lo lt lv me mk ml ' +\n//         'mr ms-my ms my nb ne nl nn pl pt-br pt ro ru se si sk sl sq sr-cyrl ' +\n//         'sr sv sw ta te th tl-ph tlh tr tzl tzm-latn tzm uk uz vi zh-cn zh-tw';\n\n//     each(locales.split(' '), function (locale) {\n//         var data, tokens;\n//         data = moment().locale(locale).localeData()._longDateFormat;\n//         tokens = objectKeys(data);\n//         each(tokens, function (token) {\n//             // Check each format string to make sure it does not contain any\n//             // tokens that need to be expanded.\n//             each(tokens, function (i) {\n//                 // strip escaped sequences\n//                 var format = data[i].replace(/(\\[[^\\]]*\\])/g, '');\n//                 assert.equal(false, !!~format.indexOf(token), 'locale ' + locale + ' contains ' + token + ' in ' + i);\n//             });\n//         });\n//     });\n// });\n\ntest('milliseconds', function (assert) {\n    var m = moment('123', 'SSS');\n\n    assert.equal(m.format('S'), '1');\n    assert.equal(m.format('SS'), '12');\n    assert.equal(m.format('SSS'), '123');\n    assert.equal(m.format('SSSS'), '1230');\n    assert.equal(m.format('SSSSS'), '12300');\n    assert.equal(m.format('SSSSSS'), '123000');\n    assert.equal(m.format('SSSSSSS'), '1230000');\n    assert.equal(m.format('SSSSSSSS'), '12300000');\n    assert.equal(m.format('SSSSSSSSS'), '123000000');\n});\n\ntest('hmm and hmmss', function (assert) {\n    assert.equal(moment('12:34:56', 'HH:mm:ss').format('hmm'), '1234');\n    assert.equal(moment('01:34:56', 'HH:mm:ss').format('hmm'), '134');\n    assert.equal(moment('13:34:56', 'HH:mm:ss').format('hmm'), '134');\n\n    assert.equal(moment('12:34:56', 'HH:mm:ss').format('hmmss'), '123456');\n    assert.equal(moment('01:34:56', 'HH:mm:ss').format('hmmss'), '13456');\n    assert.equal(moment('13:34:56', 'HH:mm:ss').format('hmmss'), '13456');\n});\n\ntest('Hmm and Hmmss', function (assert) {\n    assert.equal(moment('12:34:56', 'HH:mm:ss').format('Hmm'), '1234');\n    assert.equal(moment('01:34:56', 'HH:mm:ss').format('Hmm'), '134');\n    assert.equal(moment('13:34:56', 'HH:mm:ss').format('Hmm'), '1334');\n\n    assert.equal(moment('12:34:56', 'HH:mm:ss').format('Hmmss'), '123456');\n    assert.equal(moment('01:34:56', 'HH:mm:ss').format('Hmmss'), '13456');\n    assert.equal(moment('08:34:56', 'HH:mm:ss').format('Hmmss'), '83456');\n    assert.equal(moment('18:34:56', 'HH:mm:ss').format('Hmmss'), '183456');\n});\n\ntest('k and kk', function (assert) {\n    assert.equal(moment('01:23:45', 'HH:mm:ss').format('k'), '1');\n    assert.equal(moment('12:34:56', 'HH:mm:ss').format('k'), '12');\n    assert.equal(moment('01:23:45', 'HH:mm:ss').format('kk'), '01');\n    assert.equal(moment('12:34:56', 'HH:mm:ss').format('kk'), '12');\n    assert.equal(moment('00:34:56', 'HH:mm:ss').format('kk'), '24');\n    assert.equal(moment('00:00:00', 'HH:mm:ss').format('kk'), '24');\n});\n\ntest('Y token', function (assert) {\n    assert.equal(moment('2010-01-01', 'YYYY-MM-DD', true).format('Y'), '2010', 'format 2010 with Y');\n    assert.equal(moment('-123-01-01', 'Y-MM-DD', true).format('Y'), '-123', 'format -123 with Y');\n    assert.equal(moment('12345-01-01', 'Y-MM-DD', true).format('Y'), '+12345', 'format 12345 with Y');\n    assert.equal(moment('0-01-01', 'Y-MM-DD', true).format('Y'), '0', 'format 0 with Y');\n    assert.equal(moment('1-01-01', 'Y-MM-DD', true).format('Y'), '1', 'format 1 with Y');\n    assert.equal(moment('9999-01-01', 'Y-MM-DD', true).format('Y'), '9999', 'format 9999 with Y');\n    assert.equal(moment('10000-01-01', 'Y-MM-DD', true).format('Y'), '+10000', 'format 10000 with Y');\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\nfunction module$1 (name, lifecycle) {\n    QUnit.module(name, {\n        setup : function () {\n            moment.locale('en');\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'core');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            teardownDeprecationHandler(test, moment, 'core');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n}\n\nmodule$1('from_to');\n\ntest('from', function (assert) {\n    var start = moment();\n    moment.locale('en');\n    assert.equal(start.from(start.clone().add(5, 'seconds')),  'a few seconds ago', '5 seconds = a few seconds ago');\n    assert.equal(start.from(start.clone().add(1, 'minute')),  'a minute ago', '1 minute = a minute ago');\n    assert.equal(start.from(start.clone().add(5, 'minutes')),  '5 minutes ago', '5 minutes = 5 minutes ago');\n\n    assert.equal(start.from(start.clone().subtract(5, 'seconds')),  'in a few seconds', '5 seconds = in a few seconds');\n    assert.equal(start.from(start.clone().subtract(1, 'minute')),  'in a minute', '1 minute = in a minute');\n    assert.equal(start.from(start.clone().subtract(5, 'minutes')),  'in 5 minutes', '5 minutes = in 5 minutes');\n});\n\ntest('from with absolute duration', function (assert) {\n    var start = moment();\n    moment.locale('en');\n    assert.equal(start.from(start.clone().add(5, 'seconds'), true),  'a few seconds', '5 seconds = a few seconds');\n    assert.equal(start.from(start.clone().add(1, 'minute'), true),  'a minute', '1 minute = a minute');\n    assert.equal(start.from(start.clone().add(5, 'minutes'), true),  '5 minutes', '5 minutes = 5 minutes');\n\n    assert.equal(start.from(start.clone().subtract(5, 'seconds'), true),  'a few seconds', '5 seconds = a few seconds');\n    assert.equal(start.from(start.clone().subtract(1, 'minute'), true),  'a minute', '1 minute = a minute');\n    assert.equal(start.from(start.clone().subtract(5, 'minutes'), true),  '5 minutes', '5 minutes = 5 minutes');\n});\n\ntest('to', function (assert) {\n    var start = moment();\n    moment.locale('en');\n    assert.equal(start.to(start.clone().subtract(5, 'seconds')),  'a few seconds ago', '5 seconds = a few seconds ago');\n    assert.equal(start.to(start.clone().subtract(1, 'minute')),  'a minute ago', '1 minute = a minute ago');\n    assert.equal(start.to(start.clone().subtract(5, 'minutes')),  '5 minutes ago', '5 minutes = 5 minutes ago');\n\n    assert.equal(start.to(start.clone().add(5, 'seconds')),  'in a few seconds', '5 seconds = in a few seconds');\n    assert.equal(start.to(start.clone().add(1, 'minute')),  'in a minute', '1 minute = in a minute');\n    assert.equal(start.to(start.clone().add(5, 'minutes')),  'in 5 minutes', '5 minutes = in 5 minutes');\n});\n\ntest('to with absolute duration', function (assert) {\n    var start = moment();\n    moment.locale('en');\n    assert.equal(start.to(start.clone().add(5, 'seconds'), true),  'a few seconds', '5 seconds = a few seconds');\n    assert.equal(start.to(start.clone().add(1, 'minute'), true),  'a minute', '1 minute = a minute');\n    assert.equal(start.to(start.clone().add(5, 'minutes'), true),  '5 minutes', '5 minutes = 5 minutes');\n\n    assert.equal(start.to(start.clone().subtract(5, 'seconds'), true),  'a few seconds', '5 seconds = a few seconds');\n    assert.equal(start.to(start.clone().subtract(1, 'minute'), true),  'a minute', '1 minute = a minute');\n    assert.equal(start.to(start.clone().subtract(5, 'minutes'), true),  '5 minutes', '5 minutes = 5 minutes');\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\nfunction module$1 (name, lifecycle) {\n    QUnit.module(name, {\n        setup : function () {\n            moment.locale('en');\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'core');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            teardownDeprecationHandler(test, moment, 'core');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n}\n\nmodule$1('getters and setters');\n\ntest('getters', function (assert) {\n    var a = moment([2011, 9, 12, 6, 7, 8, 9]);\n    assert.equal(a.year(), 2011, 'year');\n    assert.equal(a.month(), 9, 'month');\n    assert.equal(a.date(), 12, 'date');\n    assert.equal(a.day(), 3, 'day');\n    assert.equal(a.hours(), 6, 'hour');\n    assert.equal(a.minutes(), 7, 'minute');\n    assert.equal(a.seconds(), 8, 'second');\n    assert.equal(a.milliseconds(), 9, 'milliseconds');\n});\n\ntest('getters programmatic', function (assert) {\n    var a = moment([2011, 9, 12, 6, 7, 8, 9]);\n    assert.equal(a.get('year'), 2011, 'year');\n    assert.equal(a.get('month'), 9, 'month');\n    assert.equal(a.get('date'), 12, 'date');\n    assert.equal(a.get('day'), 3, 'day');\n    assert.equal(a.get('hour'), 6, 'hour');\n    assert.equal(a.get('minute'), 7, 'minute');\n    assert.equal(a.get('second'), 8, 'second');\n    assert.equal(a.get('milliseconds'), 9, 'milliseconds');\n\n    //actual getters tested elsewhere\n    assert.equal(a.get('weekday'), a.weekday(), 'weekday');\n    assert.equal(a.get('isoWeekday'), a.isoWeekday(), 'isoWeekday');\n    assert.equal(a.get('week'), a.week(), 'week');\n    assert.equal(a.get('isoWeek'), a.isoWeek(), 'isoWeek');\n    assert.equal(a.get('dayOfYear'), a.dayOfYear(), 'dayOfYear');\n\n    //getter no longer sets values when passed an object\n    assert.equal(moment([2016,0,1]).get({year:2015}).year(), 2016, 'getter no longer sets values when passed an object');\n});\n\ntest('setters plural', function (assert) {\n    var a = moment();\n    test.expectedDeprecations('years accessor', 'months accessor', 'dates accessor');\n\n    a.years(2011);\n    a.months(9);\n    a.dates(12);\n    a.hours(6);\n    a.minutes(7);\n    a.seconds(8);\n    a.milliseconds(9);\n    assert.equal(a.years(), 2011, 'years');\n    assert.equal(a.months(), 9, 'months');\n    assert.equal(a.dates(), 12, 'dates');\n    assert.equal(a.days(), 3, 'days');\n    assert.equal(a.hours(), 6, 'hours');\n    assert.equal(a.minutes(), 7, 'minutes');\n    assert.equal(a.seconds(), 8, 'seconds');\n    assert.equal(a.milliseconds(), 9, 'milliseconds');\n});\n\ntest('setters singular', function (assert) {\n    var a = moment();\n    a.year(2011);\n    a.month(9);\n    a.date(12);\n    a.hour(6);\n    a.minute(7);\n    a.second(8);\n    a.millisecond(9);\n    assert.equal(a.year(), 2011, 'year');\n    assert.equal(a.month(), 9, 'month');\n    assert.equal(a.date(), 12, 'date');\n    assert.equal(a.day(), 3, 'day');\n    assert.equal(a.hour(), 6, 'hour');\n    assert.equal(a.minute(), 7, 'minute');\n    assert.equal(a.second(), 8, 'second');\n    assert.equal(a.millisecond(), 9, 'milliseconds');\n});\n\ntest('setters', function (assert) {\n    var a = moment();\n    a.year(2011);\n    a.month(9);\n    a.date(12);\n    a.hours(6);\n    a.minutes(7);\n    a.seconds(8);\n    a.milliseconds(9);\n    assert.equal(a.year(), 2011, 'year');\n    assert.equal(a.month(), 9, 'month');\n    assert.equal(a.date(), 12, 'date');\n    assert.equal(a.day(), 3, 'day');\n    assert.equal(a.hours(), 6, 'hour');\n    assert.equal(a.minutes(), 7, 'minute');\n    assert.equal(a.seconds(), 8, 'second');\n    assert.equal(a.milliseconds(), 9, 'milliseconds');\n\n    // Test month() behavior. See https://github.com/timrwood/moment/pull/822\n    a = moment('20130531', 'YYYYMMDD');\n    a.month(3);\n    assert.equal(a.month(), 3, 'month edge case');\n});\n\ntest('setter programmatic', function (assert) {\n    var a = moment();\n    a.set('year', 2011);\n    a.set('month', 9);\n    a.set('date', 12);\n    a.set('hours', 6);\n    a.set('minutes', 7);\n    a.set('seconds', 8);\n    a.set('milliseconds', 9);\n    assert.equal(a.year(), 2011, 'year');\n    assert.equal(a.month(), 9, 'month');\n    assert.equal(a.date(), 12, 'date');\n    assert.equal(a.day(), 3, 'day');\n    assert.equal(a.hours(), 6, 'hour');\n    assert.equal(a.minutes(), 7, 'minute');\n    assert.equal(a.seconds(), 8, 'second');\n    assert.equal(a.milliseconds(), 9, 'milliseconds');\n\n    // Test month() behavior. See https://github.com/timrwood/moment/pull/822\n    a = moment('20130531', 'YYYYMMDD');\n    a.month(3);\n    assert.equal(a.month(), 3, 'month edge case');\n});\n\ntest('setters programatic with weeks', function (assert) {\n    var a = moment();\n    a.set('weekYear', 2001);\n    a.set('week', 49);\n    a.set('day', 4);\n\n    assert.equal(a.weekYear(), 2001, 'weekYear');\n    assert.equal(a.week(), 49, 'week');\n    assert.equal(a.day(), 4, 'day');\n\n    a.set('weekday', 1);\n    assert.equal(a.weekday(), 1, 'weekday');\n});\n\ntest('setters programatic with weeks ISO', function (assert) {\n    var a = moment();\n    a.set('isoWeekYear', 2001);\n    a.set('isoWeek', 49);\n    a.set('isoWeekday', 4);\n\n    assert.equal(a.isoWeekYear(), 2001, 'isoWeekYear');\n    assert.equal(a.isoWeek(), 49, 'isoWeek');\n    assert.equal(a.isoWeekday(), 4, 'isoWeekday');\n});\n\ntest('setters strings', function (assert) {\n    var a = moment([2012]).locale('en');\n    assert.equal(a.clone().day(0).day('Wednesday').day(), 3, 'day full name');\n    assert.equal(a.clone().day(0).day('Wed').day(), 3, 'day short name');\n    assert.equal(a.clone().day(0).day('We').day(), 3, 'day minimal name');\n    assert.equal(a.clone().day(0).day('invalid').day(), 0, 'invalid day name');\n    assert.equal(a.clone().month(0).month('April').month(), 3, 'month full name');\n    assert.equal(a.clone().month(0).month('Apr').month(), 3, 'month short name');\n    assert.equal(a.clone().month(0).month('invalid').month(), 0, 'invalid month name');\n});\n\ntest('setters - falsey values', function (assert) {\n    var a = moment();\n    // ensure minutes wasn't coincidentally 0 already\n    a.minutes(1);\n    a.minutes(0);\n    assert.equal(a.minutes(), 0, 'falsey value');\n});\n\ntest('chaining setters', function (assert) {\n    var a = moment();\n    a.year(2011)\n     .month(9)\n     .date(12)\n     .hours(6)\n     .minutes(7)\n     .seconds(8);\n    assert.equal(a.year(), 2011, 'year');\n    assert.equal(a.month(), 9, 'month');\n    assert.equal(a.date(), 12, 'date');\n    assert.equal(a.day(), 3, 'day');\n    assert.equal(a.hours(), 6, 'hour');\n    assert.equal(a.minutes(), 7, 'minute');\n    assert.equal(a.seconds(), 8, 'second');\n});\n\ntest('setter with multiple unit values', function (assert) {\n    var a = moment();\n    a.set({\n        year: 2011,\n        month: 9,\n        date: 12,\n        hours: 6,\n        minutes: 7,\n        seconds: 8,\n        milliseconds: 9\n    });\n    assert.equal(a.year(), 2011, 'year');\n    assert.equal(a.month(), 9, 'month');\n    assert.equal(a.date(), 12, 'date');\n    assert.equal(a.day(), 3, 'day');\n    assert.equal(a.hours(), 6, 'hour');\n    assert.equal(a.minutes(), 7, 'minute');\n    assert.equal(a.seconds(), 8, 'second');\n    assert.equal(a.milliseconds(), 9, 'milliseconds');\n\n    var c = moment([2016,0,1]);\n    assert.equal(c.set({weekYear: 2016}).weekYear(), 2016, 'week year correctly sets with object syntax');\n    assert.equal(c.set({quarter: 3}).quarter(), 3, 'quarter sets correctly with object syntax');\n});\n\ntest('day setter', function (assert) {\n    var a = moment([2011, 0, 15]);\n    assert.equal(moment(a).day(0).date(), 9, 'set from saturday to sunday');\n    assert.equal(moment(a).day(6).date(), 15, 'set from saturday to saturday');\n    assert.equal(moment(a).day(3).date(), 12, 'set from saturday to wednesday');\n\n    a = moment([2011, 0, 9]);\n    assert.equal(moment(a).day(0).date(), 9, 'set from sunday to sunday');\n    assert.equal(moment(a).day(6).date(), 15, 'set from sunday to saturday');\n    assert.equal(moment(a).day(3).date(), 12, 'set from sunday to wednesday');\n\n    a = moment([2011, 0, 12]);\n    assert.equal(moment(a).day(0).date(), 9, 'set from wednesday to sunday');\n    assert.equal(moment(a).day(6).date(), 15, 'set from wednesday to saturday');\n    assert.equal(moment(a).day(3).date(), 12, 'set from wednesday to wednesday');\n\n    assert.equal(moment(a).day(-7).date(), 2, 'set from wednesday to last sunday');\n    assert.equal(moment(a).day(-1).date(), 8, 'set from wednesday to last saturday');\n    assert.equal(moment(a).day(-4).date(), 5, 'set from wednesday to last wednesday');\n\n    assert.equal(moment(a).day(7).date(), 16, 'set from wednesday to next sunday');\n    assert.equal(moment(a).day(13).date(), 22, 'set from wednesday to next saturday');\n    assert.equal(moment(a).day(10).date(), 19, 'set from wednesday to next wednesday');\n\n    assert.equal(moment(a).day(14).date(), 23, 'set from wednesday to second next sunday');\n    assert.equal(moment(a).day(20).date(), 29, 'set from wednesday to second next saturday');\n    assert.equal(moment(a).day(17).date(), 26, 'set from wednesday to second next wednesday');\n});\n\ntest('object set ordering', function (assert) {\n    var a = moment([2016,3,30]);\n    assert.equal(a.set({date:31, month:4}).date(), 31, 'setter order automatically arranged by size');\n    var b = moment([2015,1,28]);\n    assert.equal(b.set({date:29, year: 2016}).format('YYYY-MM-DD'), '2016-02-29', 'year is prioritized over date');\n    //check a nonexistent time in US isn't set\n    var c = moment([2016,2,13]);\n    c.set({\n        hour:2,\n        minutes:30,\n        date: 14\n    });\n    assert.equal(c.format('YYYY-MM-DDTHH:mm'), '2016-03-14T02:30', 'setting hours, minutes date puts date first allowing time set to work');\n});\n\ntest('string setters', function (assert) {\n    var a = moment();\n    a.year('2011');\n    a.month('9');\n    a.date('12');\n    a.hours('6');\n    a.minutes('7');\n    a.seconds('8');\n    a.milliseconds('9');\n    assert.equal(a.year(), 2011, 'year');\n    assert.equal(a.month(), 9, 'month');\n    assert.equal(a.date(), 12, 'date');\n    assert.equal(a.day(), 3, 'day');\n    assert.equal(a.hours(), 6, 'hour');\n    assert.equal(a.minutes(), 7, 'minute');\n    assert.equal(a.seconds(), 8, 'second');\n    assert.equal(a.milliseconds(), 9, 'milliseconds');\n});\n\ntest('setters across DST +1', function (assert) {\n    var oldUpdateOffset = moment.updateOffset,\n        // Based on a real story somewhere in America/Los_Angeles\n        dstAt = moment('2014-03-09T02:00:00-08:00').parseZone(),\n        m;\n\n    moment.updateOffset = function (mom, keepTime) {\n        if (mom.isBefore(dstAt)) {\n            mom.utcOffset(-8, keepTime);\n        } else {\n            mom.utcOffset(-7, keepTime);\n        }\n    };\n\n    m = moment('2014-03-15T00:00:00-07:00').parseZone();\n    m.year(2013);\n    assert.equal(m.format(), '2013-03-15T00:00:00-08:00', 'year across +1');\n\n    m = moment('2014-03-15T00:00:00-07:00').parseZone();\n    m.month(0);\n    assert.equal(m.format(), '2014-01-15T00:00:00-08:00', 'month across +1');\n\n    m = moment('2014-03-15T00:00:00-07:00').parseZone();\n    m.date(1);\n    assert.equal(m.format(), '2014-03-01T00:00:00-08:00', 'date across +1');\n\n    m = moment('2014-03-09T03:05:00-07:00').parseZone();\n    m.hour(0);\n    assert.equal(m.format(), '2014-03-09T00:05:00-08:00', 'hour across +1');\n\n    moment.updateOffset = oldUpdateOffset;\n});\n\ntest('setters across DST -1', function (assert) {\n    var oldUpdateOffset = moment.updateOffset,\n        // Based on a real story somewhere in America/Los_Angeles\n        dstAt = moment('2014-11-02T02:00:00-07:00').parseZone(),\n        m;\n\n    moment.updateOffset = function (mom, keepTime) {\n        if (mom.isBefore(dstAt)) {\n            mom.utcOffset(-7, keepTime);\n        } else {\n            mom.utcOffset(-8, keepTime);\n        }\n    };\n\n    m = moment('2014-11-15T00:00:00-08:00').parseZone();\n    m.year(2013);\n    assert.equal(m.format(), '2013-11-15T00:00:00-07:00', 'year across -1');\n\n    m = moment('2014-11-15T00:00:00-08:00').parseZone();\n    m.month(0);\n    assert.equal(m.format(), '2014-01-15T00:00:00-07:00', 'month across -1');\n\n    m = moment('2014-11-15T00:00:00-08:00').parseZone();\n    m.date(1);\n    assert.equal(m.format(), '2014-11-01T00:00:00-07:00', 'date across -1');\n\n    m = moment('2014-11-02T03:30:00-08:00').parseZone();\n    m.hour(0);\n    assert.equal(m.format(), '2014-11-02T00:30:00-07:00', 'hour across -1');\n\n    moment.updateOffset = oldUpdateOffset;\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\nfunction module$1 (name, lifecycle) {\n    QUnit.module(name, {\n        setup : function () {\n            moment.locale('en');\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'core');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            teardownDeprecationHandler(test, moment, 'core');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n}\n\nmodule$1('instanceof');\n\ntest('instanceof', function (assert) {\n    var mm = moment([2010, 0, 1]);\n\n    var extend = function (a, b) {\n        var i;\n        for (i in b) {\n            a[i] = b[i];\n        }\n        return a;\n    };\n\n    assert.equal(moment() instanceof moment, true, 'simple moment object');\n    assert.equal(extend({}, moment()) instanceof moment, false, 'extended moment object');\n    assert.equal(moment(null) instanceof moment, true, 'invalid moment object');\n\n    assert.equal(new Date() instanceof moment, false, 'date object is not moment object');\n    assert.equal(Object instanceof moment, false, 'Object is not moment object');\n    assert.equal('foo' instanceof moment, false, 'string is not moment object');\n    assert.equal(1 instanceof moment, false, 'number is not moment object');\n    assert.equal(NaN instanceof moment, false, 'NaN is not moment object');\n    assert.equal(null instanceof moment, false, 'null is not moment object');\n    assert.equal(undefined instanceof moment, false, 'undefined is not moment object');\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\nfunction module$1 (name, lifecycle) {\n    QUnit.module(name, {\n        setup : function () {\n            moment.locale('en');\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'core');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            teardownDeprecationHandler(test, moment, 'core');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n}\n\nmodule$1('invalid');\n\ntest('invalid', function (assert) {\n    var m = moment.invalid();\n    assert.equal(m.isValid(), false);\n    assert.equal(m.parsingFlags().userInvalidated, true);\n    assert.ok(isNaN(m.valueOf()));\n});\n\ntest('invalid with existing flag', function (assert) {\n    var m = moment.invalid({invalidMonth : 'whatchamacallit'});\n    assert.equal(m.isValid(), false);\n    assert.equal(m.parsingFlags().userInvalidated, false);\n    assert.equal(m.parsingFlags().invalidMonth, 'whatchamacallit');\n    assert.ok(isNaN(m.valueOf()));\n});\n\ntest('invalid with custom flag', function (assert) {\n    var m = moment.invalid({tooBusyWith : 'reiculating splines'});\n    assert.equal(m.isValid(), false);\n    assert.equal(m.parsingFlags().userInvalidated, false);\n    assert.equal(m.parsingFlags().tooBusyWith, 'reiculating splines');\n    assert.ok(isNaN(m.valueOf()));\n});\n\ntest('invalid operations', function (assert) {\n    var invalids = [\n            moment.invalid(),\n            moment('xyz', 'l'),\n            moment('2015-01-35', 'YYYY-MM-DD'),\n            moment('2015-01-25 a', 'YYYY-MM-DD', true)\n        ],\n        i,\n        invalid,\n        valid = moment();\n\n    test.expectedDeprecations('moment().min', 'moment().max', 'isDSTShifted');\n\n    for (i = 0; i < invalids.length; ++i) {\n        invalid = invalids[i];\n\n        assert.ok(!invalid.clone().add(5, 'hours').isValid(), 'invalid.add is invalid');\n        assert.equal(invalid.calendar(), 'Invalid date', 'invalid.calendar is \\'Invalid date\\'');\n        assert.ok(!invalid.clone().isValid(), 'invalid.clone is invalid');\n        assert.ok(isNaN(invalid.diff(valid)), 'invalid.diff(valid) is NaN');\n        assert.ok(isNaN(valid.diff(invalid)), 'valid.diff(invalid) is NaN');\n        assert.ok(isNaN(invalid.diff(invalid)), 'invalid.diff(invalid) is NaN');\n        assert.ok(!invalid.clone().endOf('month').isValid(), 'invalid.endOf is invalid');\n        assert.equal(invalid.format(), 'Invalid date', 'invalid.format is \\'Invalid date\\'');\n        assert.equal(invalid.from(), 'Invalid date');\n        assert.equal(invalid.from(valid), 'Invalid date');\n        assert.equal(valid.from(invalid), 'Invalid date');\n        assert.equal(invalid.fromNow(), 'Invalid date');\n        assert.equal(invalid.to(), 'Invalid date');\n        assert.equal(invalid.to(valid), 'Invalid date');\n        assert.equal(valid.to(invalid), 'Invalid date');\n        assert.equal(invalid.toNow(), 'Invalid date');\n        assert.ok(isNaN(invalid.get('year')), 'invalid.get is NaN');\n        // TODO invalidAt\n        assert.ok(!invalid.isAfter(valid));\n        assert.ok(!valid.isAfter(invalid));\n        assert.ok(!invalid.isAfter(invalid));\n        assert.ok(!invalid.isBefore(valid));\n        assert.ok(!valid.isBefore(invalid));\n        assert.ok(!invalid.isBefore(invalid));\n        assert.ok(!invalid.isBetween(valid, valid));\n        assert.ok(!valid.isBetween(invalid, valid));\n        assert.ok(!valid.isBetween(valid, invalid));\n        assert.ok(!invalid.isSame(invalid));\n        assert.ok(!invalid.isSame(valid));\n        assert.ok(!valid.isSame(invalid));\n        assert.ok(!invalid.isValid());\n        assert.equal(invalid.locale(), 'en');\n        assert.equal(invalid.localeData()._abbr, 'en');\n        assert.ok(!invalid.clone().max(valid).isValid());\n        assert.ok(!valid.clone().max(invalid).isValid());\n        assert.ok(!invalid.clone().max(invalid).isValid());\n        assert.ok(!invalid.clone().min(valid).isValid());\n        assert.ok(!valid.clone().min(invalid).isValid());\n        assert.ok(!invalid.clone().min(invalid).isValid());\n        assert.ok(!moment.min(invalid, valid).isValid());\n        assert.ok(!moment.min(valid, invalid).isValid());\n        assert.ok(!moment.max(invalid, valid).isValid());\n        assert.ok(!moment.max(valid, invalid).isValid());\n        assert.ok(!invalid.clone().set('year', 2005).isValid());\n        assert.ok(!invalid.clone().startOf('month').isValid());\n\n        assert.ok(!invalid.clone().subtract(5, 'days').isValid());\n        assert.deepEqual(invalid.toArray(), [NaN, NaN, NaN, NaN, NaN, NaN, NaN]);\n        assert.deepEqual(invalid.toObject(), {\n            years: NaN,\n            months: NaN,\n            date: NaN,\n            hours: NaN,\n            minutes: NaN,\n            seconds: NaN,\n            milliseconds: NaN\n        });\n        assert.ok(moment.isDate(invalid.toDate()));\n        assert.ok(isNaN(invalid.toDate().valueOf()));\n        assert.equal(invalid.toJSON(), null);\n        assert.equal(invalid.toString(), 'Invalid date');\n        assert.ok(isNaN(invalid.unix()));\n        assert.ok(isNaN(invalid.valueOf()));\n\n        assert.ok(isNaN(invalid.year()));\n        assert.ok(isNaN(invalid.weekYear()));\n        assert.ok(isNaN(invalid.isoWeekYear()));\n        assert.ok(isNaN(invalid.quarter()));\n        assert.ok(isNaN(invalid.quarters()));\n        assert.ok(isNaN(invalid.month()));\n        assert.ok(isNaN(invalid.daysInMonth()));\n        assert.ok(isNaN(invalid.week()));\n        assert.ok(isNaN(invalid.weeks()));\n        assert.ok(isNaN(invalid.isoWeek()));\n        assert.ok(isNaN(invalid.isoWeeks()));\n        assert.ok(isNaN(invalid.weeksInYear()));\n        assert.ok(isNaN(invalid.isoWeeksInYear()));\n        assert.ok(isNaN(invalid.date()));\n        assert.ok(isNaN(invalid.day()));\n        assert.ok(isNaN(invalid.days()));\n        assert.ok(isNaN(invalid.weekday()));\n        assert.ok(isNaN(invalid.isoWeekday()));\n        assert.ok(isNaN(invalid.dayOfYear()));\n        assert.ok(isNaN(invalid.hour()));\n        assert.ok(isNaN(invalid.hours()));\n        assert.ok(isNaN(invalid.minute()));\n        assert.ok(isNaN(invalid.minutes()));\n        assert.ok(isNaN(invalid.second()));\n        assert.ok(isNaN(invalid.seconds()));\n        assert.ok(isNaN(invalid.millisecond()));\n        assert.ok(isNaN(invalid.milliseconds()));\n        assert.ok(isNaN(invalid.utcOffset()));\n\n        assert.ok(!invalid.clone().year(2001).isValid());\n        assert.ok(!invalid.clone().weekYear(2001).isValid());\n        assert.ok(!invalid.clone().isoWeekYear(2001).isValid());\n        assert.ok(!invalid.clone().quarter(1).isValid());\n        assert.ok(!invalid.clone().quarters(1).isValid());\n        assert.ok(!invalid.clone().month(1).isValid());\n        assert.ok(!invalid.clone().week(1).isValid());\n        assert.ok(!invalid.clone().weeks(1).isValid());\n        assert.ok(!invalid.clone().isoWeek(1).isValid());\n        assert.ok(!invalid.clone().isoWeeks(1).isValid());\n        assert.ok(!invalid.clone().date(1).isValid());\n        assert.ok(!invalid.clone().day(1).isValid());\n        assert.ok(!invalid.clone().days(1).isValid());\n        assert.ok(!invalid.clone().weekday(1).isValid());\n        assert.ok(!invalid.clone().isoWeekday(1).isValid());\n        assert.ok(!invalid.clone().dayOfYear(1).isValid());\n        assert.ok(!invalid.clone().hour(1).isValid());\n        assert.ok(!invalid.clone().hours(1).isValid());\n        assert.ok(!invalid.clone().minute(1).isValid());\n        assert.ok(!invalid.clone().minutes(1).isValid());\n        assert.ok(!invalid.clone().second(1).isValid());\n        assert.ok(!invalid.clone().seconds(1).isValid());\n        assert.ok(!invalid.clone().millisecond(1).isValid());\n        assert.ok(!invalid.clone().milliseconds(1).isValid());\n        assert.ok(!invalid.clone().utcOffset(1).isValid());\n\n        assert.ok(!invalid.clone().utc().isValid());\n        assert.ok(!invalid.clone().local().isValid());\n        assert.ok(!invalid.clone().parseZone('05:30').isValid());\n        assert.ok(!invalid.hasAlignedHourOffset());\n        assert.ok(!invalid.isDST());\n        assert.ok(!invalid.isDSTShifted());\n        assert.ok(!invalid.isLocal());\n        assert.ok(!invalid.isUtcOffset());\n        assert.ok(!invalid.isUtc());\n        assert.ok(!invalid.isUTC());\n\n        assert.ok(!invalid.isLeapYear());\n\n        assert.equal(moment.duration({from: invalid, to: valid}).asMilliseconds(), 0);\n        assert.equal(moment.duration({from: valid, to: invalid}).asMilliseconds(), 0);\n        assert.equal(moment.duration({from: invalid, to: invalid}).asMilliseconds(), 0);\n    }\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\nfunction module$1 (name, lifecycle) {\n    QUnit.module(name, {\n        setup : function () {\n            moment.locale('en');\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'core');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            teardownDeprecationHandler(test, moment, 'core');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n}\n\nmodule$1('is after');\n\ntest('is after without units', function (assert) {\n    var m = moment(new Date(2011, 3, 2, 3, 4, 5, 10)), mCopy = moment(m);\n    assert.equal(m.isAfter(moment(new Date(2012, 3, 2, 3, 5, 5, 10))), false, 'year is later');\n    assert.equal(m.isAfter(moment(new Date(2010, 3, 2, 3, 3, 5, 10))), true, 'year is earlier');\n    assert.equal(m.isAfter(moment(new Date(2011, 4, 2, 3, 4, 5, 10))), false, 'month is later');\n    assert.equal(m.isAfter(moment(new Date(2011, 2, 2, 3, 4, 5, 10))), true, 'month is earlier');\n    assert.equal(m.isAfter(moment(new Date(2011, 3, 3, 3, 4, 5, 10))), false, 'day is later');\n    assert.equal(m.isAfter(moment(new Date(2011, 3, 1, 3, 4, 5, 10))), true, 'day is earlier');\n    assert.equal(m.isAfter(moment(new Date(2011, 3, 2, 4, 4, 5, 10))), false, 'hour is later');\n    assert.equal(m.isAfter(moment(new Date(2011, 3, 2, 2, 4, 5, 10))), true, 'hour is earlier');\n    assert.equal(m.isAfter(moment(new Date(2011, 3, 2, 3, 5, 5, 10))), false, 'minute is later');\n    assert.equal(m.isAfter(moment(new Date(2011, 3, 2, 3, 3, 5, 10))), true, 'minute is earlier');\n    assert.equal(m.isAfter(moment(new Date(2011, 3, 2, 3, 4, 6, 10))), false, 'second is later');\n    assert.equal(m.isAfter(moment(new Date(2011, 3, 2, 3, 4, 4, 11))), true, 'second is earlier');\n    assert.equal(m.isAfter(moment(new Date(2011, 3, 2, 3, 4, 5, 10))), false, 'millisecond match');\n    assert.equal(m.isAfter(moment(new Date(2011, 3, 2, 3, 4, 5, 11))), false, 'millisecond is later');\n    assert.equal(m.isAfter(moment(new Date(2011, 3, 2, 3, 4, 5, 9))), true, 'millisecond is earlier');\n    assert.equal(m.isAfter(m), false, 'moments are not after themselves');\n    assert.equal(+m, +mCopy, 'isAfter second should not change moment');\n});\n\ntest('is after year', function (assert) {\n    var m = moment(new Date(2011, 1, 2, 3, 4, 5, 6)), mCopy = moment(m);\n    assert.equal(m.isAfter(moment(new Date(2011, 5, 6, 7, 8, 9, 10)), 'year'), false, 'year match');\n    assert.equal(m.isAfter(moment(new Date(2010, 5, 6, 7, 8, 9, 10)), 'years'), true, 'plural should work');\n    assert.equal(m.isAfter(moment(new Date(2013, 5, 6, 7, 8, 9, 10)), 'year'), false, 'year is later');\n    assert.equal(m.isAfter(moment(new Date(2010, 5, 6, 7, 8, 9, 10)), 'year'), true, 'year is earlier');\n    assert.equal(m.isAfter(moment(new Date(2011, 0, 1, 0, 0, 0, 0)), 'year'), false, 'exact start of year');\n    assert.equal(m.isAfter(moment(new Date(2011, 11, 31, 23, 59, 59, 999)), 'year'), false, 'exact end of year');\n    assert.equal(m.isAfter(moment(new Date(2012, 0, 1, 0, 0, 0, 0)), 'year'), false, 'start of next year');\n    assert.equal(m.isAfter(moment(new Date(2010, 11, 31, 23, 59, 59, 999)), 'year'), true, 'end of previous year');\n    assert.equal(m.isAfter(moment(new Date(1980, 11, 31, 23, 59, 59, 999)), 'year'), true, 'end of year far before');\n    assert.equal(m.isAfter(m, 'year'), false, 'same moments are not after the same year');\n    assert.equal(+m, +mCopy, 'isAfter year should not change moment');\n});\n\ntest('is after month', function (assert) {\n    var m = moment(new Date(2011, 2, 3, 4, 5, 6, 7)), mCopy = moment(m);\n    assert.equal(m.isAfter(moment(new Date(2011, 2, 6, 7, 8, 9, 10)), 'month'), false, 'month match');\n    assert.equal(m.isAfter(moment(new Date(2010, 2, 6, 7, 8, 9, 10)), 'months'), true, 'plural should work');\n    assert.equal(m.isAfter(moment(new Date(2012, 2, 6, 7, 8, 9, 10)), 'month'), false, 'year is later');\n    assert.equal(m.isAfter(moment(new Date(2010, 2, 6, 7, 8, 9, 10)), 'month'), true, 'year is earlier');\n    assert.equal(m.isAfter(moment(new Date(2011, 5, 6, 7, 8, 9, 10)), 'month'), false, 'month is later');\n    assert.equal(m.isAfter(moment(new Date(2011, 1, 6, 7, 8, 9, 10)), 'month'), true, 'month is earlier');\n    assert.equal(m.isAfter(moment(new Date(2011, 2, 1, 0, 0, 0, 0)), 'month'), false, 'exact start of month');\n    assert.equal(m.isAfter(moment(new Date(2011, 2, 31, 23, 59, 59, 999)), 'month'), false, 'exact end of month');\n    assert.equal(m.isAfter(moment(new Date(2011, 3, 1, 0, 0, 0, 0)), 'month'), false, 'start of next month');\n    assert.equal(m.isAfter(moment(new Date(2011, 1, 27, 23, 59, 59, 999)), 'month'), true, 'end of previous month');\n    assert.equal(m.isAfter(moment(new Date(2010, 12, 31, 23, 59, 59, 999)), 'month'), true, 'later month but earlier year');\n    assert.equal(m.isAfter(m, 'month'), false, 'same moments are not after the same month');\n    assert.equal(+m, +mCopy, 'isAfter month should not change moment');\n});\n\ntest('is after day', function (assert) {\n    var m = moment(new Date(2011, 3, 2, 3, 4, 5, 6)), mCopy = moment(m);\n    assert.equal(m.isAfter(moment(new Date(2011, 3, 2, 7, 8, 9, 10)), 'day'), false, 'day match');\n    assert.equal(m.isAfter(moment(new Date(2010, 3, 2, 7, 8, 9, 10)), 'days'), true, 'plural should work');\n    assert.equal(m.isAfter(moment(new Date(2012, 3, 2, 7, 8, 9, 10)), 'day'), false, 'year is later');\n    assert.equal(m.isAfter(moment(new Date(2010, 3, 2, 7, 8, 9, 10)), 'day'), true, 'year is earlier');\n    assert.equal(m.isAfter(moment(new Date(2011, 4, 2, 7, 8, 9, 10)), 'day'), false, 'month is later');\n    assert.equal(m.isAfter(moment(new Date(2011, 2, 2, 7, 8, 9, 10)), 'day'), true, 'month is earlier');\n    assert.equal(m.isAfter(moment(new Date(2011, 3, 3, 7, 8, 9, 10)), 'day'), false, 'day is later');\n    assert.equal(m.isAfter(moment(new Date(2011, 3, 1, 7, 8, 9, 10)), 'day'), true, 'day is earlier');\n    assert.equal(m.isAfter(moment(new Date(2011, 3, 2, 0, 0, 0, 0)), 'day'), false, 'exact start of day');\n    assert.equal(m.isAfter(moment(new Date(2011, 3, 2, 23, 59, 59, 999)), 'day'), false, 'exact end of day');\n    assert.equal(m.isAfter(moment(new Date(2011, 3, 3, 0, 0, 0, 0)), 'day'), false, 'start of next day');\n    assert.equal(m.isAfter(moment(new Date(2011, 3, 1, 23, 59, 59, 999)), 'day'), true, 'end of previous day');\n    assert.equal(m.isAfter(moment(new Date(2010, 3, 10, 0, 0, 0, 0)), 'day'), true, 'later day but earlier year');\n    assert.equal(m.isAfter(m, 'day'), false, 'same moments are not after the same day');\n    assert.equal(+m, +mCopy, 'isAfter day should not change moment');\n});\n\ntest('is after hour', function (assert) {\n    var m = moment(new Date(2011, 3, 2, 3, 4, 5, 6)), mCopy = moment(m);\n    assert.equal(m.isAfter(moment(new Date(2011, 3, 2, 3, 8, 9, 10)), 'hour'), false, 'hour match');\n    assert.equal(m.isAfter(moment(new Date(2010, 3, 2, 3, 8, 9, 10)), 'hours'), true, 'plural should work');\n    assert.equal(m.isAfter(moment(new Date(2012, 3, 2, 3, 8, 9, 10)), 'hour'), false, 'year is later');\n    assert.equal(m.isAfter(moment(new Date(2010, 3, 2, 3, 8, 9, 10)), 'hour'), true, 'year is earlier');\n    assert.equal(m.isAfter(moment(new Date(2011, 4, 2, 3, 8, 9, 10)), 'hour'), false, 'month is later');\n    assert.equal(m.isAfter(moment(new Date(2011, 1, 2, 3, 8, 9, 10)), 'hour'), true, 'month is earlier');\n    assert.equal(m.isAfter(moment(new Date(2011, 3, 3, 3, 8, 9, 10)), 'hour'), false, 'day is later');\n    assert.equal(m.isAfter(moment(new Date(2011, 3, 1, 3, 8, 9, 10)), 'hour'), true, 'day is earlier');\n    assert.equal(m.isAfter(moment(new Date(2011, 3, 2, 4, 8, 9, 10)), 'hour'), false, 'hour is later');\n    assert.equal(m.isAfter(moment(new Date(2011, 3, 2, 3, 8, 9, 10)), 'hour'), false, 'hour is earlier');\n    assert.equal(m.isAfter(moment(new Date(2011, 3, 2, 3, 0, 0, 0)), 'hour'), false, 'exact start of hour');\n    assert.equal(m.isAfter(moment(new Date(2011, 3, 2, 3, 59, 59, 999)), 'hour'), false, 'exact end of hour');\n    assert.equal(m.isAfter(moment(new Date(2011, 3, 2, 4, 0, 0, 0)), 'hour'), false, 'start of next hour');\n    assert.equal(m.isAfter(moment(new Date(2011, 3, 2, 2, 59, 59, 999)), 'hour'), true, 'end of previous hour');\n    assert.equal(m.isAfter(m, 'hour'), false, 'same moments are not after the same hour');\n    assert.equal(+m, +mCopy, 'isAfter hour should not change moment');\n});\n\ntest('is after minute', function (assert) {\n    var m = moment(new Date(2011, 3, 2, 3, 4, 5, 6)), mCopy = moment(m);\n    assert.equal(m.isAfter(moment(new Date(2011, 3, 2, 3, 4, 9, 10)), 'minute'), false, 'minute match');\n    assert.equal(m.isAfter(moment(new Date(2010, 3, 2, 3, 4, 9, 10)), 'minutes'), true, 'plural should work');\n    assert.equal(m.isAfter(moment(new Date(2012, 3, 2, 3, 4, 9, 10)), 'minute'), false, 'year is later');\n    assert.equal(m.isAfter(moment(new Date(2010, 3, 2, 3, 4, 9, 10)), 'minute'), true, 'year is earlier');\n    assert.equal(m.isAfter(moment(new Date(2011, 4, 2, 3, 4, 9, 10)), 'minute'), false, 'month is later');\n    assert.equal(m.isAfter(moment(new Date(2011, 2, 2, 3, 4, 9, 10)), 'minute'), true, 'month is earlier');\n    assert.equal(m.isAfter(moment(new Date(2011, 3, 3, 3, 4, 9, 10)), 'minute'), false, 'day is later');\n    assert.equal(m.isAfter(moment(new Date(2011, 3, 1, 3, 4, 9, 10)), 'minute'), true, 'day is earlier');\n    assert.equal(m.isAfter(moment(new Date(2011, 3, 2, 4, 4, 9, 10)), 'minute'), false, 'hour is later');\n    assert.equal(m.isAfter(moment(new Date(2011, 3, 2, 2, 4, 9, 10)), 'minute'), true, 'hour is earler');\n    assert.equal(m.isAfter(moment(new Date(2011, 3, 2, 3, 5, 9, 10)), 'minute'), false, 'minute is later');\n    assert.equal(m.isAfter(moment(new Date(2011, 3, 2, 3, 3, 9, 10)), 'minute'), true, 'minute is earlier');\n    assert.equal(m.isAfter(moment(new Date(2011, 3, 2, 3, 4, 0, 0)), 'minute'), false, 'exact start of minute');\n    assert.equal(m.isAfter(moment(new Date(2011, 3, 2, 3, 4, 59, 999)), 'minute'), false, 'exact end of minute');\n    assert.equal(m.isAfter(moment(new Date(2011, 3, 2, 3, 5, 0, 0)), 'minute'), false, 'start of next minute');\n    assert.equal(m.isAfter(moment(new Date(2011, 3, 2, 3, 3, 59, 999)), 'minute'), true, 'end of previous minute');\n    assert.equal(m.isAfter(m, 'minute'), false, 'same moments are not after the same minute');\n    assert.equal(+m, +mCopy, 'isAfter minute should not change moment');\n});\n\ntest('is after second', function (assert) {\n    var m = moment(new Date(2011, 3, 2, 3, 4, 5, 10)), mCopy = moment(m);\n    assert.equal(m.isAfter(moment(new Date(2011, 3, 2, 3, 4, 5, 10)), 'second'), false, 'second match');\n    assert.equal(m.isAfter(moment(new Date(2010, 3, 2, 3, 4, 5, 10)), 'seconds'), true, 'plural should work');\n    assert.equal(m.isAfter(moment(new Date(2012, 3, 2, 3, 4, 5, 10)), 'second'), false, 'year is later');\n    assert.equal(m.isAfter(moment(new Date(2010, 3, 2, 3, 4, 5, 10)), 'second'), true, 'year is earlier');\n    assert.equal(m.isAfter(moment(new Date(2011, 4, 2, 3, 4, 5, 10)), 'second'), false, 'month is later');\n    assert.equal(m.isAfter(moment(new Date(2011, 2, 2, 3, 4, 5, 10)), 'second'), true, 'month is earlier');\n    assert.equal(m.isAfter(moment(new Date(2011, 3, 3, 3, 4, 5, 10)), 'second'), false, 'day is later');\n    assert.equal(m.isAfter(moment(new Date(2011, 3, 1, 1, 4, 5, 10)), 'second'), true, 'day is earlier');\n    assert.equal(m.isAfter(moment(new Date(2011, 3, 2, 4, 4, 5, 10)), 'second'), false, 'hour is later');\n    assert.equal(m.isAfter(moment(new Date(2011, 3, 1, 4, 1, 5, 10)), 'second'), true, 'hour is earlier');\n    assert.equal(m.isAfter(moment(new Date(2011, 3, 2, 3, 5, 5, 10)), 'second'), false, 'minute is later');\n    assert.equal(m.isAfter(moment(new Date(2011, 3, 2, 3, 3, 5, 10)), 'second'), true, 'minute is earlier');\n    assert.equal(m.isAfter(moment(new Date(2011, 3, 2, 3, 4, 6, 10)), 'second'), false, 'second is later');\n    assert.equal(m.isAfter(moment(new Date(2011, 3, 2, 3, 4, 4, 5)), 'second'), true, 'second is earlier');\n    assert.equal(m.isAfter(moment(new Date(2011, 3, 2, 3, 4, 5, 0)), 'second'), false, 'exact start of second');\n    assert.equal(m.isAfter(moment(new Date(2011, 3, 2, 3, 4, 5, 999)), 'second'), false, 'exact end of second');\n    assert.equal(m.isAfter(moment(new Date(2011, 3, 2, 3, 4, 6, 0)), 'second'), false, 'start of next second');\n    assert.equal(m.isAfter(moment(new Date(2011, 3, 2, 3, 4, 4, 999)), 'second'), true, 'end of previous second');\n    assert.equal(m.isAfter(m, 'second'), false, 'same moments are not after the same second');\n    assert.equal(+m, +mCopy, 'isAfter second should not change moment');\n});\n\ntest('is after millisecond', function (assert) {\n    var m = moment(new Date(2011, 3, 2, 3, 4, 5, 10)), mCopy = moment(m);\n    assert.equal(m.isAfter(moment(new Date(2011, 3, 2, 3, 4, 5, 10)), 'millisecond'), false, 'millisecond match');\n    assert.equal(m.isAfter(moment(new Date(2010, 3, 2, 3, 4, 5, 10)), 'milliseconds'), true, 'plural should work');\n    assert.equal(m.isAfter(moment(new Date(2012, 3, 2, 3, 4, 5, 10)), 'millisecond'), false, 'year is later');\n    assert.equal(m.isAfter(moment(new Date(2010, 3, 2, 3, 4, 5, 10)), 'millisecond'), true, 'year is earlier');\n    assert.equal(m.isAfter(moment(new Date(2011, 4, 2, 3, 4, 5, 10)), 'millisecond'), false, 'month is later');\n    assert.equal(m.isAfter(moment(new Date(2011, 2, 2, 3, 4, 5, 10)), 'millisecond'), true, 'month is earlier');\n    assert.equal(m.isAfter(moment(new Date(2011, 3, 3, 3, 4, 5, 10)), 'millisecond'), false, 'day is later');\n    assert.equal(m.isAfter(moment(new Date(2011, 3, 1, 1, 4, 5, 10)), 'millisecond'), true, 'day is earlier');\n    assert.equal(m.isAfter(moment(new Date(2011, 3, 2, 4, 4, 5, 10)), 'millisecond'), false, 'hour is later');\n    assert.equal(m.isAfter(moment(new Date(2011, 3, 1, 4, 1, 5, 10)), 'millisecond'), true, 'hour is earlier');\n    assert.equal(m.isAfter(moment(new Date(2011, 3, 2, 3, 5, 5, 10)), 'millisecond'), false, 'minute is later');\n    assert.equal(m.isAfter(moment(new Date(2011, 3, 2, 3, 3, 5, 10)), 'millisecond'), true, 'minute is earlier');\n    assert.equal(m.isAfter(moment(new Date(2011, 3, 2, 3, 4, 6, 10)), 'millisecond'), false, 'second is later');\n    assert.equal(m.isAfter(moment(new Date(2011, 3, 2, 3, 4, 4, 5)), 'millisecond'), true, 'second is earlier');\n    assert.equal(m.isAfter(moment(new Date(2011, 3, 2, 3, 4, 6, 11)), 'millisecond'), false, 'millisecond is later');\n    assert.equal(m.isAfter(moment(new Date(2011, 3, 2, 3, 4, 4, 9)), 'millisecond'), true, 'millisecond is earlier');\n    assert.equal(m.isAfter(m, 'millisecond'), false, 'same moments are not after the same millisecond');\n    assert.equal(+m, +mCopy, 'isAfter millisecond should not change moment');\n});\n\ntest('is after invalid', function (assert) {\n    var m = moment(), invalid = moment.invalid();\n    assert.equal(m.isAfter(invalid), false, 'valid moment is not after invalid moment');\n    assert.equal(invalid.isAfter(m), false, 'invalid moment is not after valid moment');\n    assert.equal(m.isAfter(invalid, 'year'), false, 'invalid moment year');\n    assert.equal(m.isAfter(invalid, 'month'), false, 'invalid moment month');\n    assert.equal(m.isAfter(invalid, 'day'), false, 'invalid moment day');\n    assert.equal(m.isAfter(invalid, 'hour'), false, 'invalid moment hour');\n    assert.equal(m.isAfter(invalid, 'minute'), false, 'invalid moment minute');\n    assert.equal(m.isAfter(invalid, 'second'), false, 'invalid moment second');\n    assert.equal(m.isAfter(invalid, 'milliseconds'), false, 'invalid moment milliseconds');\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\nfunction isArray(input) {\n    return input instanceof Array || Object.prototype.toString.call(input) === '[object Array]';\n}\n\ntest('isArray recognizes Array objects', function (assert) {\n    assert.ok(isArray([1,2,3]), 'array args');\n    assert.ok(isArray([]), 'empty array');\n    assert.ok(isArray(new Array(1,2,3)), 'array constructor');\n});\n\ntest('isArray rejects non-Array objects', function (assert) {\n    assert.ok(!isArray(), 'nothing');\n    assert.ok(!isArray(undefined), 'undefined');\n    assert.ok(!isArray(null), 'null');\n    assert.ok(!isArray(123), 'number');\n    assert.ok(!isArray('[1,2,3]'), 'string');\n    assert.ok(!isArray(new Date()), 'date');\n    assert.ok(!isArray({a:1,b:2}), 'object');\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\nfunction module$1 (name, lifecycle) {\n    QUnit.module(name, {\n        setup : function () {\n            moment.locale('en');\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'core');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            teardownDeprecationHandler(test, moment, 'core');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n}\n\nmodule$1('is before');\n\ntest('is after without units', function (assert) {\n    var m = moment(new Date(2011, 3, 2, 3, 4, 5, 10)), mCopy = moment(m);\n    assert.equal(m.isBefore(moment(new Date(2012, 3, 2, 3, 5, 5, 10))), true, 'year is later');\n    assert.equal(m.isBefore(moment(new Date(2010, 3, 2, 3, 3, 5, 10))), false, 'year is earlier');\n    assert.equal(m.isBefore(moment(new Date(2011, 4, 2, 3, 4, 5, 10))), true, 'month is later');\n    assert.equal(m.isBefore(moment(new Date(2011, 2, 2, 3, 4, 5, 10))), false, 'month is earlier');\n    assert.equal(m.isBefore(moment(new Date(2011, 3, 3, 3, 4, 5, 10))), true, 'day is later');\n    assert.equal(m.isBefore(moment(new Date(2011, 3, 1, 3, 4, 5, 10))), false, 'day is earlier');\n    assert.equal(m.isBefore(moment(new Date(2011, 3, 2, 4, 4, 5, 10))), true, 'hour is later');\n    assert.equal(m.isBefore(moment(new Date(2011, 3, 2, 2, 4, 5, 10))), false, 'hour is earlier');\n    assert.equal(m.isBefore(moment(new Date(2011, 3, 2, 3, 5, 5, 10))), true, 'minute is later');\n    assert.equal(m.isBefore(moment(new Date(2011, 3, 2, 3, 3, 5, 10))), false, 'minute is earlier');\n    assert.equal(m.isBefore(moment(new Date(2011, 3, 2, 3, 4, 6, 10))), true, 'second is later');\n    assert.equal(m.isBefore(moment(new Date(2011, 3, 2, 3, 4, 4, 11))), false, 'second is earlier');\n    assert.equal(m.isBefore(moment(new Date(2011, 3, 2, 3, 4, 5, 10))), false, 'millisecond match');\n    assert.equal(m.isBefore(moment(new Date(2011, 3, 2, 3, 4, 5, 11))), true, 'millisecond is later');\n    assert.equal(m.isBefore(moment(new Date(2011, 3, 2, 3, 4, 5, 9))), false, 'millisecond is earlier');\n    assert.equal(m.isBefore(m), false, 'moments are not before themselves');\n    assert.equal(+m, +mCopy, 'isBefore second should not change moment');\n});\n\ntest('is before year', function (assert) {\n    var m = moment(new Date(2011, 1, 2, 3, 4, 5, 6)), mCopy = moment(m);\n    assert.equal(m.isBefore(moment(new Date(2011, 5, 6, 7, 8, 9, 10)), 'year'), false, 'year match');\n    assert.equal(m.isBefore(moment(new Date(2012, 5, 6, 7, 8, 9, 10)), 'years'), true, 'plural should work');\n    assert.equal(m.isBefore(moment(new Date(2013, 5, 6, 7, 8, 9, 10)), 'year'), true, 'year is later');\n    assert.equal(m.isBefore(moment(new Date(2010, 5, 6, 7, 8, 9, 10)), 'year'), false, 'year is earlier');\n    assert.equal(m.isBefore(moment(new Date(2011, 0, 1, 0, 0, 0, 0)), 'year'), false, 'exact start of year');\n    assert.equal(m.isBefore(moment(new Date(2011, 11, 31, 23, 59, 59, 999)), 'year'), false, 'exact end of year');\n    assert.equal(m.isBefore(moment(new Date(2012, 0, 1, 0, 0, 0, 0)), 'year'), true, 'start of next year');\n    assert.equal(m.isBefore(moment(new Date(2010, 11, 31, 23, 59, 59, 999)), 'year'), false, 'end of previous year');\n    assert.equal(m.isBefore(moment(new Date(1980, 11, 31, 23, 59, 59, 999)), 'year'), false, 'end of year far before');\n    assert.equal(m.isBefore(m, 'year'), false, 'same moments are not before the same year');\n    assert.equal(+m, +mCopy, 'isBefore year should not change moment');\n});\n\ntest('is before month', function (assert) {\n    var m = moment(new Date(2011, 2, 3, 4, 5, 6, 7)), mCopy = moment(m);\n    assert.equal(m.isBefore(moment(new Date(2011, 2, 6, 7, 8, 9, 10)), 'month'), false, 'month match');\n    assert.equal(m.isBefore(moment(new Date(2012, 2, 6, 7, 8, 9, 10)), 'months'), true, 'plural should work');\n    assert.equal(m.isBefore(moment(new Date(2012, 2, 6, 7, 8, 9, 10)), 'month'), true, 'year is later');\n    assert.equal(m.isBefore(moment(new Date(2010, 2, 6, 7, 8, 9, 10)), 'month'), false, 'year is earlier');\n    assert.equal(m.isBefore(moment(new Date(2011, 5, 6, 7, 8, 9, 10)), 'month'), true, 'month is later');\n    assert.equal(m.isBefore(moment(new Date(2011, 1, 6, 7, 8, 9, 10)), 'month'), false, 'month is earlier');\n    assert.equal(m.isBefore(moment(new Date(2011, 2, 1, 0, 0, 0, 0)), 'month'), false, 'exact start of month');\n    assert.equal(m.isBefore(moment(new Date(2011, 2, 31, 23, 59, 59, 999)), 'month'), false, 'exact end of month');\n    assert.equal(m.isBefore(moment(new Date(2011, 3, 1, 0, 0, 0, 0)), 'month'), true, 'start of next month');\n    assert.equal(m.isBefore(moment(new Date(2011, 1, 27, 23, 59, 59, 999)), 'month'), false, 'end of previous month');\n    assert.equal(m.isBefore(moment(new Date(2010, 12, 31, 23, 59, 59, 999)), 'month'), false, 'later month but earlier year');\n    assert.equal(m.isBefore(m, 'month'), false, 'same moments are not before the same month');\n    assert.equal(+m, +mCopy, 'isBefore month should not change moment');\n});\n\ntest('is before day', function (assert) {\n    var m = moment(new Date(2011, 3, 2, 3, 4, 5, 6)), mCopy = moment(m);\n    assert.equal(m.isBefore(moment(new Date(2011, 3, 2, 7, 8, 9, 10)), 'day'), false, 'day match');\n    assert.equal(m.isBefore(moment(new Date(2012, 3, 2, 7, 8, 9, 10)), 'days'), true, 'plural should work');\n    assert.equal(m.isBefore(moment(new Date(2012, 3, 2, 7, 8, 9, 10)), 'day'), true, 'year is later');\n    assert.equal(m.isBefore(moment(new Date(2010, 3, 2, 7, 8, 9, 10)), 'day'), false, 'year is earlier');\n    assert.equal(m.isBefore(moment(new Date(2011, 4, 2, 7, 8, 9, 10)), 'day'), true, 'month is later');\n    assert.equal(m.isBefore(moment(new Date(2011, 2, 2, 7, 8, 9, 10)), 'day'), false, 'month is earlier');\n    assert.equal(m.isBefore(moment(new Date(2011, 3, 3, 7, 8, 9, 10)), 'day'), true, 'day is later');\n    assert.equal(m.isBefore(moment(new Date(2011, 3, 1, 7, 8, 9, 10)), 'day'), false, 'day is earlier');\n    assert.equal(m.isBefore(moment(new Date(2011, 3, 2, 0, 0, 0, 0)), 'day'), false, 'exact start of day');\n    assert.equal(m.isBefore(moment(new Date(2011, 3, 2, 23, 59, 59, 999)), 'day'), false, 'exact end of day');\n    assert.equal(m.isBefore(moment(new Date(2011, 3, 3, 0, 0, 0, 0)), 'day'), true, 'start of next day');\n    assert.equal(m.isBefore(moment(new Date(2011, 3, 1, 23, 59, 59, 999)), 'day'), false, 'end of previous day');\n    assert.equal(m.isBefore(moment(new Date(2010, 3, 10, 0, 0, 0, 0)), 'day'), false, 'later day but earlier year');\n    assert.equal(m.isBefore(m, 'day'), false, 'same moments are not before the same day');\n    assert.equal(+m, +mCopy, 'isBefore day should not change moment');\n});\n\ntest('is before hour', function (assert) {\n    var m = moment(new Date(2011, 3, 2, 3, 4, 5, 6)), mCopy = moment(m);\n    assert.equal(m.isBefore(moment(new Date(2011, 3, 2, 3, 8, 9, 10)), 'hour'), false, 'hour match');\n    assert.equal(m.isBefore(moment(new Date(2012, 3, 2, 3, 8, 9, 10)), 'hours'), true, 'plural should work');\n    assert.equal(m.isBefore(moment(new Date(2012, 3, 2, 3, 8, 9, 10)), 'hour'), true, 'year is later');\n    assert.equal(m.isBefore(moment(new Date(2010, 3, 2, 3, 8, 9, 10)), 'hour'), false, 'year is earlier');\n    assert.equal(m.isBefore(moment(new Date(2011, 4, 2, 3, 8, 9, 10)), 'hour'), true, 'month is later');\n    assert.equal(m.isBefore(moment(new Date(2011, 1, 2, 3, 8, 9, 10)), 'hour'), false, 'month is earlier');\n    assert.equal(m.isBefore(moment(new Date(2011, 3, 3, 3, 8, 9, 10)), 'hour'), true, 'day is later');\n    assert.equal(m.isBefore(moment(new Date(2011, 3, 1, 3, 8, 9, 10)), 'hour'), false, 'day is earlier');\n    assert.equal(m.isBefore(moment(new Date(2011, 3, 2, 4, 8, 9, 10)), 'hour'), true, 'hour is later');\n    assert.equal(m.isBefore(moment(new Date(2011, 3, 2, 3, 8, 9, 10)), 'hour'), false, 'hour is earlier');\n    assert.equal(m.isBefore(moment(new Date(2011, 3, 2, 3, 0, 0, 0)), 'hour'), false, 'exact start of hour');\n    assert.equal(m.isBefore(moment(new Date(2011, 3, 2, 3, 59, 59, 999)), 'hour'), false, 'exact end of hour');\n    assert.equal(m.isBefore(moment(new Date(2011, 3, 2, 4, 0, 0, 0)), 'hour'), true, 'start of next hour');\n    assert.equal(m.isBefore(moment(new Date(2011, 3, 2, 2, 59, 59, 999)), 'hour'), false, 'end of previous hour');\n    assert.equal(m.isBefore(m, 'hour'), false, 'same moments are not before the same hour');\n    assert.equal(+m, +mCopy, 'isBefore hour should not change moment');\n});\n\ntest('is before minute', function (assert) {\n    var m = moment(new Date(2011, 3, 2, 3, 4, 5, 6)), mCopy = moment(m);\n    assert.equal(m.isBefore(moment(new Date(2011, 3, 2, 3, 4, 9, 10)), 'minute'), false, 'minute match');\n    assert.equal(m.isBefore(moment(new Date(2012, 3, 2, 3, 4, 9, 10)), 'minutes'), true, 'plural should work');\n    assert.equal(m.isBefore(moment(new Date(2012, 3, 2, 3, 4, 9, 10)), 'minute'), true, 'year is later');\n    assert.equal(m.isBefore(moment(new Date(2010, 3, 2, 3, 4, 9, 10)), 'minute'), false, 'year is earlier');\n    assert.equal(m.isBefore(moment(new Date(2011, 4, 2, 3, 4, 9, 10)), 'minute'), true, 'month is later');\n    assert.equal(m.isBefore(moment(new Date(2011, 2, 2, 3, 4, 9, 10)), 'minute'), false, 'month is earlier');\n    assert.equal(m.isBefore(moment(new Date(2011, 3, 3, 3, 4, 9, 10)), 'minute'), true, 'day is later');\n    assert.equal(m.isBefore(moment(new Date(2011, 3, 1, 3, 4, 9, 10)), 'minute'), false, 'day is earlier');\n    assert.equal(m.isBefore(moment(new Date(2011, 3, 2, 4, 4, 9, 10)), 'minute'), true, 'hour is later');\n    assert.equal(m.isBefore(moment(new Date(2011, 3, 2, 2, 4, 9, 10)), 'minute'), false, 'hour is earler');\n    assert.equal(m.isBefore(moment(new Date(2011, 3, 2, 3, 5, 9, 10)), 'minute'), true, 'minute is later');\n    assert.equal(m.isBefore(moment(new Date(2011, 3, 2, 3, 3, 9, 10)), 'minute'), false, 'minute is earlier');\n    assert.equal(m.isBefore(moment(new Date(2011, 3, 2, 3, 4, 0, 0)), 'minute'), false, 'exact start of minute');\n    assert.equal(m.isBefore(moment(new Date(2011, 3, 2, 3, 4, 59, 999)), 'minute'), false, 'exact end of minute');\n    assert.equal(m.isBefore(moment(new Date(2011, 3, 2, 3, 5, 0, 0)), 'minute'), true, 'start of next minute');\n    assert.equal(m.isBefore(moment(new Date(2011, 3, 2, 3, 3, 59, 999)), 'minute'), false, 'end of previous minute');\n    assert.equal(m.isBefore(m, 'minute'), false, 'same moments are not before the same minute');\n    assert.equal(+m, +mCopy, 'isBefore minute should not change moment');\n});\n\ntest('is before second', function (assert) {\n    var m = moment(new Date(2011, 3, 2, 3, 4, 5, 10)), mCopy = moment(m);\n    assert.equal(m.isBefore(moment(new Date(2011, 3, 2, 3, 4, 5, 10)), 'second'), false, 'second match');\n    assert.equal(m.isBefore(moment(new Date(2012, 3, 2, 3, 4, 5, 10)), 'seconds'), true, 'plural should work');\n    assert.equal(m.isBefore(moment(new Date(2012, 3, 2, 3, 4, 5, 10)), 'second'), true, 'year is later');\n    assert.equal(m.isBefore(moment(new Date(2010, 3, 2, 3, 4, 5, 10)), 'second'), false, 'year is earlier');\n    assert.equal(m.isBefore(moment(new Date(2011, 4, 2, 3, 4, 5, 10)), 'second'), true, 'month is later');\n    assert.equal(m.isBefore(moment(new Date(2011, 2, 2, 3, 4, 5, 10)), 'second'), false, 'month is earlier');\n    assert.equal(m.isBefore(moment(new Date(2011, 3, 3, 3, 4, 5, 10)), 'second'), true, 'day is later');\n    assert.equal(m.isBefore(moment(new Date(2011, 3, 1, 1, 4, 5, 10)), 'second'), false, 'day is earlier');\n    assert.equal(m.isBefore(moment(new Date(2011, 3, 2, 4, 4, 5, 10)), 'second'), true, 'hour is later');\n    assert.equal(m.isBefore(moment(new Date(2011, 3, 1, 4, 1, 5, 10)), 'second'), false, 'hour is earlier');\n    assert.equal(m.isBefore(moment(new Date(2011, 3, 2, 3, 5, 5, 10)), 'second'), true, 'minute is later');\n    assert.equal(m.isBefore(moment(new Date(2011, 3, 2, 3, 3, 5, 10)), 'second'), false, 'minute is earlier');\n    assert.equal(m.isBefore(moment(new Date(2011, 3, 2, 3, 4, 6, 10)), 'second'), true, 'second is later');\n    assert.equal(m.isBefore(moment(new Date(2011, 3, 2, 3, 4, 4, 5)), 'second'), false, 'second is earlier');\n    assert.equal(m.isBefore(moment(new Date(2011, 3, 2, 3, 4, 5, 0)), 'second'), false, 'exact start of second');\n    assert.equal(m.isBefore(moment(new Date(2011, 3, 2, 3, 4, 5, 999)), 'second'), false, 'exact end of second');\n    assert.equal(m.isBefore(moment(new Date(2011, 3, 2, 3, 4, 6, 0)), 'second'), true, 'start of next second');\n    assert.equal(m.isBefore(moment(new Date(2011, 3, 2, 3, 4, 4, 999)), 'second'), false, 'end of previous second');\n    assert.equal(m.isBefore(m, 'second'), false, 'same moments are not before the same second');\n    assert.equal(+m, +mCopy, 'isBefore second should not change moment');\n});\n\ntest('is before millisecond', function (assert) {\n    var m = moment(new Date(2011, 3, 2, 3, 4, 5, 10)), mCopy = moment(m);\n    assert.equal(m.isBefore(moment(new Date(2011, 3, 2, 3, 4, 5, 10)), 'millisecond'), false, 'millisecond match');\n    assert.equal(m.isBefore(moment(new Date(2010, 3, 2, 3, 4, 5, 10)), 'milliseconds'), false, 'plural should work');\n    assert.equal(m.isBefore(moment(new Date(2012, 3, 2, 3, 4, 5, 10)), 'millisecond'), true, 'year is later');\n    assert.equal(m.isBefore(moment(new Date(2010, 3, 2, 3, 4, 5, 10)), 'millisecond'), false, 'year is earlier');\n    assert.equal(m.isBefore(moment(new Date(2011, 4, 2, 3, 4, 5, 10)), 'millisecond'), true, 'month is later');\n    assert.equal(m.isBefore(moment(new Date(2011, 2, 2, 3, 4, 5, 10)), 'millisecond'), false, 'month is earlier');\n    assert.equal(m.isBefore(moment(new Date(2011, 3, 3, 3, 4, 5, 10)), 'millisecond'), true, 'day is later');\n    assert.equal(m.isBefore(moment(new Date(2011, 3, 1, 1, 4, 5, 10)), 'millisecond'), false, 'day is earlier');\n    assert.equal(m.isBefore(moment(new Date(2011, 3, 2, 4, 4, 5, 10)), 'millisecond'), true, 'hour is later');\n    assert.equal(m.isBefore(moment(new Date(2011, 3, 1, 4, 1, 5, 10)), 'millisecond'), false, 'hour is earlier');\n    assert.equal(m.isBefore(moment(new Date(2011, 3, 2, 3, 5, 5, 10)), 'millisecond'), true, 'minute is later');\n    assert.equal(m.isBefore(moment(new Date(2011, 3, 2, 3, 3, 5, 10)), 'millisecond'), false, 'minute is earlier');\n    assert.equal(m.isBefore(moment(new Date(2011, 3, 2, 3, 4, 6, 10)), 'millisecond'), true, 'second is later');\n    assert.equal(m.isBefore(moment(new Date(2011, 3, 2, 3, 4, 4, 5)), 'millisecond'), false, 'second is earlier');\n    assert.equal(m.isBefore(moment(new Date(2011, 3, 2, 3, 4, 6, 11)), 'millisecond'), true, 'millisecond is later');\n    assert.equal(m.isBefore(moment(new Date(2011, 3, 2, 3, 4, 4, 9)), 'millisecond'), false, 'millisecond is earlier');\n    assert.equal(m.isBefore(m, 'millisecond'), false, 'same moments are not before the same millisecond');\n    assert.equal(+m, +mCopy, 'isBefore millisecond should not change moment');\n});\n\ntest('is before invalid', function (assert) {\n    var m = moment(), invalid = moment.invalid();\n    assert.equal(m.isBefore(invalid), false, 'valid moment is not before invalid moment');\n    assert.equal(invalid.isBefore(m), false, 'invalid moment is not before valid moment');\n    assert.equal(m.isBefore(invalid, 'year'), false, 'invalid moment year');\n    assert.equal(m.isBefore(invalid, 'month'), false, 'invalid moment month');\n    assert.equal(m.isBefore(invalid, 'day'), false, 'invalid moment day');\n    assert.equal(m.isBefore(invalid, 'hour'), false, 'invalid moment hour');\n    assert.equal(m.isBefore(invalid, 'minute'), false, 'invalid moment minute');\n    assert.equal(m.isBefore(invalid, 'second'), false, 'invalid moment second');\n    assert.equal(m.isBefore(invalid, 'milliseconds'), false, 'invalid moment milliseconds');\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\nfunction module$1 (name, lifecycle) {\n    QUnit.module(name, {\n        setup : function () {\n            moment.locale('en');\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'core');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            teardownDeprecationHandler(test, moment, 'core');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n}\n\nmodule$1('is between');\n\ntest('is between without units', function (assert) {\n    var m = moment(new Date(2011, 3, 2, 3, 4, 5, 10)), mCopy = moment(m);\n    assert.equal(m.isBetween(\n                moment(new Date(2009, 3, 2, 3, 4, 5, 10)),\n                moment(new Date(2011, 3, 2, 3, 4, 5, 10))), false, 'year is later');\n    assert.equal(m.isBetween(\n                moment(new Date(2011, 3, 2, 3, 4, 5, 10)),\n                moment(new Date(2013, 3, 2, 3, 4, 5, 10))), false, 'year is earlier');\n    assert.equal(m.isBetween(\n                moment(new Date(2010, 3, 2, 3, 4, 5, 10)),\n                moment(new Date(2012, 3, 2, 3, 4, 5, 10))), true, 'year is between');\n    assert.equal(m.isBetween(\n                moment(new Date(2011, 1, 2, 3, 4, 5, 10)),\n                moment(new Date(2011, 3, 2, 3, 4, 5, 10))), false, 'month is later');\n    assert.equal(m.isBetween(\n                moment(new Date(2011, 3, 2, 3, 4, 5, 10)),\n                moment(new Date(2011, 5, 2, 3, 4, 5, 10))), false, 'month is earlier');\n    assert.equal(m.isBetween(\n                moment(new Date(2011, 2, 2, 3, 4, 5, 10)),\n                moment(new Date(2011, 4, 2, 3, 4, 5, 10))), true, 'month is between');\n    assert.equal(m.isBetween(\n                moment(new Date(2011, 3, 1, 3, 4, 5, 10)),\n                moment(new Date(2011, 3, 2, 3, 4, 5, 10))), false, 'day is later');\n    assert.equal(m.isBetween(\n                moment(new Date(2011, 3, 2, 3, 4, 5, 10)),\n                moment(new Date(2011, 3, 4, 3, 4, 5, 10))), false, 'day is earlier');\n    assert.equal(m.isBetween(\n                moment(new Date(2011, 3, 1, 3, 4, 5, 10)),\n                moment(new Date(2011, 3, 3, 3, 4, 5, 10))), true, 'day is between');\n    assert.equal(m.isBetween(\n                moment(new Date(2011, 3, 2, 1, 4, 5, 10)),\n                moment(new Date(2011, 3, 2, 3, 4, 5, 10))), false, 'hour is later');\n    assert.equal(m.isBetween(\n                moment(new Date(2011, 3, 2, 3, 4, 5, 10)),\n                moment(new Date(2011, 3, 2, 5, 4, 5, 10))), false, 'hour is earlier');\n    assert.equal(m.isBetween(\n                moment(new Date(2011, 3, 2, 2, 4, 5, 10)),\n                moment(new Date(2011, 3, 2, 4, 4, 5, 10))), true, 'hour is between');\n    assert.equal(m.isBetween(\n                moment(new Date(2011, 3, 2, 3, 4, 5, 10)),\n                moment(new Date(2011, 3, 2, 3, 6, 5, 10))), false, 'minute is later');\n    assert.equal(m.isBetween(\n                moment(new Date(2011, 3, 2, 3, 2, 5, 10)),\n                moment(new Date(2011, 3, 2, 3, 4, 5, 10))), false, 'minute is earlier');\n    assert.equal(m.isBetween(\n                moment(new Date(2011, 3, 2, 3, 3, 5, 10)),\n                moment(new Date(2011, 3, 2, 3, 5, 5, 10))), true, 'minute is between');\n    assert.equal(m.isBetween(\n                moment(new Date(2011, 3, 2, 3, 4, 5, 10)),\n                moment(new Date(2011, 3, 2, 3, 4, 7, 10))), false, 'second is later');\n    assert.equal(m.isBetween(\n                moment(new Date(2011, 3, 2, 3, 4, 3, 10)),\n                moment(new Date(2011, 3, 2, 3, 4, 5, 10))), false, 'second is earlier');\n    assert.equal(m.isBetween(\n                moment(new Date(2011, 3, 2, 3, 4, 4, 10)),\n                moment(new Date(2011, 3, 2, 3, 4, 6, 10))), true, 'second is between');\n    assert.equal(m.isBetween(\n                moment(new Date(2011, 3, 2, 3, 4, 5, 10)),\n                moment(new Date(2011, 3, 2, 3, 4, 5, 12))), false, 'millisecond is later');\n    assert.equal(m.isBetween(\n                moment(new Date(2011, 3, 2, 3, 4, 5, 8)),\n                moment(new Date(2011, 3, 2, 3, 4, 5, 10))), false, 'millisecond is earlier');\n    assert.equal(m.isBetween(\n                moment(new Date(2011, 3, 2, 3, 4, 5, 9)),\n                moment(new Date(2011, 3, 2, 3, 4, 5, 11))), true, 'millisecond is between');\n    assert.equal(m.isBetween(m, m), false, 'moments are not between themselves');\n    assert.equal(+m, +mCopy, 'isBetween second should not change moment');\n});\n\ntest('is between without units inclusivity', function (assert) {\n    var m = moment(new Date(2011, 3, 2, 3, 4, 5, 10)), mCopy = moment(m);\n    assert.equal(m.isBetween(\n        moment(new Date(2011, 3, 2, 3, 4, 5, 10)),\n        moment(new Date(2012, 3, 2, 3, 4, 5, 10)), null, '()'), false, 'start and end are excluded, start is equal to moment');\n    assert.equal(m.isBetween(\n        moment(new Date(2010, 3, 2, 3, 4, 5, 10)),\n        moment(new Date(2011, 3, 2, 3, 4, 5, 10)), null, '()'), false, 'start and end are excluded, end is equal to moment');\n    assert.equal(m.isBetween(\n        moment(new Date(2010, 3, 2, 3, 4, 5, 10)),\n        moment(new Date(2012, 3, 2, 3, 4, 5, 10)), null, '()'), true, 'start and end are excluded, is between');\n    assert.equal(m.isBetween(\n        moment(new Date(2009, 3, 2, 3, 4, 5, 10)),\n        moment(new Date(2010, 3, 2, 3, 4, 5, 10)), null, '()'), false, 'start and end are excluded, is not between');\n    assert.equal(m.isBetween(\n        moment(new Date(2011, 3, 2, 3, 4, 5, 10)),\n        moment(new Date(2011, 3, 2, 3, 4, 5, 10)), null, '()'), false, 'start and end are excluded, should fail on same start/end date.');\n\n    assert.equal(m.isBetween(\n        moment(new Date(2011, 3, 2, 3, 4, 5, 10)),\n        moment(new Date(2012, 3, 2, 3, 4, 5, 10)), null, '(]'), false, 'start is excluded and end is included should fail on same start date');\n    assert.equal(m.isBetween(\n        moment(new Date(2010, 3, 2, 3, 4, 5, 10)),\n        moment(new Date(2011, 3, 2, 3, 4, 5, 10)), null, '(]'), true, 'start is excluded and end is included should succeed on end date');\n    assert.equal(m.isBetween(\n        moment(new Date(2010, 3, 2, 3, 4, 5, 10)),\n        moment(new Date(2012, 3, 2, 3, 4, 5, 10)), null, '(]'), true, 'start is excluded and end is included, is between');\n    assert.equal(m.isBetween(\n        moment(new Date(2009, 3, 2, 3, 4, 5, 10)),\n        moment(new Date(2010, 3, 2, 3, 4, 5, 10)), null, '(]'), false, 'start is excluded and end is included, is not between');\n    assert.equal(m.isBetween(\n        moment(new Date(2011, 3, 2, 3, 4, 5, 10)),\n        moment(new Date(2011, 3, 2, 3, 4, 5, 10)), null, '(]'), false, 'start is excluded and end is included, should fail on same start/end date.');\n\n    assert.equal(m.isBetween(\n        moment(new Date(2011, 3, 2, 3, 4, 5, 10)),\n        moment(new Date(2012, 3, 2, 3, 4, 5, 10)), null, '[)'), true, 'start is included and end is excluded should succeed on same start date');\n    assert.equal(m.isBetween(\n        moment(new Date(2010, 3, 2, 3, 4, 5, 10)),\n        moment(new Date(2011, 3, 2, 3, 4, 5, 10)), null, '[)'), false, 'start is included and end is excluded should fail on same end date');\n    assert.equal(m.isBetween(\n        moment(new Date(2010, 3, 2, 3, 4, 5, 10)),\n        moment(new Date(2012, 3, 2, 3, 4, 5, 10)), null, '[)'), true, 'start is included and end is excluded, is between');\n    assert.equal(m.isBetween(\n        moment(new Date(2009, 3, 2, 3, 4, 5, 10)),\n        moment(new Date(2010, 3, 2, 3, 4, 5, 10)), null, '[)'), false, 'start is included and end is excluded, is not between');\n    assert.equal(m.isBetween(\n        moment(new Date(2011, 3, 2, 3, 4, 5, 10)),\n        moment(new Date(2011, 3, 2, 3, 4, 5, 10)), null, '[)'), false, 'start is included and end is excluded, should fail on same end and start date');\n\n    assert.equal(m.isBetween(\n        moment(new Date(2011, 3, 2, 3, 4, 5, 10)),\n        moment(new Date(2012, 3, 2, 3, 4, 5, 10)), null, '[]'), true, 'start and end inclusive should succeed on same start date');\n    assert.equal(m.isBetween(\n        moment(new Date(2010, 3, 2, 3, 4, 5, 10)),\n        moment(new Date(2011, 3, 2, 3, 4, 5, 10)), null, '[]'), true, 'start and end inclusive should succeed on same end date');\n    assert.equal(m.isBetween(\n        moment(new Date(2010, 3, 2, 3, 4, 5, 10)),\n        moment(new Date(2012, 3, 2, 3, 4, 5, 10)), null, '[]'), true, 'start and end inclusive, is between');\n    assert.equal(m.isBetween(\n        moment(new Date(2009, 3, 2, 3, 4, 5, 10)),\n        moment(new Date(2010, 3, 2, 3, 4, 5, 10)), null, '[]'), false, 'start and end inclusive, is not between');\n    assert.equal(m.isBetween(\n        moment(new Date(2011, 3, 2, 3, 4, 5, 10)),\n        moment(new Date(2011, 3, 2, 3, 4, 5, 10)), null, '[]'), true, 'start and end inclusive, should handle same end and start date');\n});\n\ntest('is between milliseconds inclusivity', function (assert) {\n    var m = moment(new Date(2011, 3, 2, 3, 4, 5, 10)), mCopy = moment(m);\n    assert.equal(m.isBetween(\n        moment(new Date(2010, 3, 2, 3, 4, 5, 10)),\n        moment(new Date(2012, 3, 2, 3, 4, 5, 10)), 'milliseconds'), true, 'options, no inclusive');\n    assert.equal(m.isBetween(\n        moment(new Date(2011, 3, 2, 3, 4, 5, 10)),\n        moment(new Date(2012, 3, 2, 3, 4, 5, 10)), 'milliseconds', '()'), false, 'start and end are excluded, start is equal to moment');\n    assert.equal(m.isBetween(\n        moment(new Date(2010, 3, 2, 3, 4, 5, 10)),\n        moment(new Date(2011, 3, 2, 3, 4, 5, 10)), 'milliseconds', '()'), false, 'start and end are excluded, end is equal to moment');\n    assert.equal(m.isBetween(\n        moment(new Date(2010, 3, 2, 3, 4, 5, 10)),\n        moment(new Date(2012, 3, 2, 3, 4, 5, 10)), 'milliseconds', '()'), true, 'start and end are excluded, is between');\n    assert.equal(m.isBetween(\n        moment(new Date(2009, 3, 2, 3, 4, 5, 10)),\n        moment(new Date(2010, 3, 2, 3, 4, 5, 10)), 'milliseconds', '()'), false, 'start and end are excluded, is not between');\n    assert.equal(m.isBetween(\n        moment(new Date(2011, 3, 2, 3, 4, 5, 10)),\n        moment(new Date(2011, 3, 2, 3, 4, 5, 10)), 'milliseconds', '()'), false, 'start and end are excluded, should fail on same start/end date.');\n\n    assert.equal(m.isBetween(\n        moment(new Date(2011, 3, 2, 3, 4, 5, 10)),\n        moment(new Date(2012, 3, 2, 3, 4, 5, 10)), 'milliseconds', '(]'), false, 'start is excluded and end is included should fail on same start date');\n    assert.equal(m.isBetween(\n        moment(new Date(2010, 3, 2, 3, 4, 5, 10)),\n        moment(new Date(2011, 3, 2, 3, 4, 5, 10)), 'milliseconds', '(]'), true, 'start is excluded and end is included should succeed on end date');\n    assert.equal(m.isBetween(\n        moment(new Date(2010, 3, 2, 3, 4, 5, 10)),\n        moment(new Date(2012, 3, 2, 3, 4, 5, 10)), 'milliseconds', '(]'), true, 'start is excluded and end is included, is between');\n    assert.equal(m.isBetween(\n        moment(new Date(2009, 3, 2, 3, 4, 5, 10)),\n        moment(new Date(2010, 3, 2, 3, 4, 5, 10)), 'milliseconds', '(]'), false, 'start is excluded and end is included, is not between');\n    assert.equal(m.isBetween(\n        moment(new Date(2011, 3, 2, 3, 4, 5, 10)),\n        moment(new Date(2011, 3, 2, 3, 4, 5, 10)), 'milliseconds', '(]'), false, 'start is excluded and end is included, should fail on same start/end date.');\n\n    assert.equal(m.isBetween(\n        moment(new Date(2011, 3, 2, 3, 4, 5, 10)),\n        moment(new Date(2012, 3, 2, 3, 4, 5, 10)), 'milliseconds', '[)'), true, 'start is included and end is excluded should succeed on same start date');\n    assert.equal(m.isBetween(\n        moment(new Date(2010, 3, 2, 3, 4, 5, 10)),\n        moment(new Date(2011, 3, 2, 3, 4, 5, 10)), 'milliseconds', '[)'), false, 'start is included and end is excluded should fail on same end date');\n    assert.equal(m.isBetween(\n        moment(new Date(2010, 3, 2, 3, 4, 5, 10)),\n        moment(new Date(2012, 3, 2, 3, 4, 5, 10)), 'milliseconds', '[)'), true, 'start is included and end is excluded, is between');\n    assert.equal(m.isBetween(\n        moment(new Date(2009, 3, 2, 3, 4, 5, 10)),\n        moment(new Date(2010, 3, 2, 3, 4, 5, 10)), 'milliseconds', '[)'), false, 'start is included and end is excluded, is not between');\n    assert.equal(m.isBetween(\n        moment(new Date(2011, 3, 2, 3, 4, 5, 10)),\n        moment(new Date(2011, 3, 2, 3, 4, 5, 10)), 'milliseconds', '[)'), false, 'start is included and end is excluded, should fail on same end and start date');\n\n    assert.equal(m.isBetween(\n        moment(new Date(2011, 3, 2, 3, 4, 5, 10)),\n        moment(new Date(2012, 3, 2, 3, 4, 5, 10)), 'milliseconds', '[]'), true, 'start and end inclusive should succeed on same start date');\n    assert.equal(m.isBetween(\n        moment(new Date(2010, 3, 2, 3, 4, 5, 10)),\n        moment(new Date(2011, 3, 2, 3, 4, 5, 10)), 'milliseconds', '[]'), true, 'start and end inclusive should succeed on same end date');\n    assert.equal(m.isBetween(\n        moment(new Date(2010, 3, 2, 3, 4, 5, 10)),\n        moment(new Date(2012, 3, 2, 3, 4, 5, 10)), 'milliseconds', '[]'), true, 'start and end inclusive, is between');\n    assert.equal(m.isBetween(\n        moment(new Date(2009, 3, 2, 3, 4, 5, 10)),\n        moment(new Date(2010, 3, 2, 3, 4, 5, 10)), 'milliseconds', '[]'), false, 'start and end inclusive, is not between');\n    assert.equal(m.isBetween(\n        moment(new Date(2011, 3, 2, 3, 4, 5, 10)),\n        moment(new Date(2011, 3, 2, 3, 4, 5, 10)), 'milliseconds', '[]'), true, 'start and end inclusive, should handle same end and start date');\n});\n\ntest('is between year', function (assert) {\n    var m = moment(new Date(2011, 1, 2, 3, 4, 5, 6)), mCopy = moment(m);\n    assert.equal(m.isBetween(\n                moment(new Date(2011, 5, 6, 7, 8, 9, 10)),\n                moment(new Date(2011, 5, 6, 7, 8, 9, 10)), 'year'), false, 'year match');\n    assert.equal(m.isBetween(\n                moment(new Date(2010, 5, 6, 7, 8, 9, 10)),\n                moment(new Date(2012, 5, 6, 7, 8, 9, 10)), 'years'), true, 'plural should work');\n    assert.equal(m.isBetween(\n                moment(new Date(2010, 5, 6, 7, 8, 9, 10)),\n                moment(new Date(2012, 5, 6, 7, 8, 9, 10)), 'year'), true, 'year is between');\n    assert.equal(m.isBetween(\n                moment(new Date(2011, 5, 6, 7, 8, 9, 10)),\n                moment(new Date(2013, 5, 6, 7, 8, 9, 10)), 'year'), false, 'year is earlier');\n    assert.equal(m.isBetween(\n                moment(new Date(2010, 5, 6, 7, 8, 9, 10)),\n                moment(new Date(2011, 5, 6, 7, 8, 9, 10)), 'year'), false, 'year is later');\n    assert.equal(m.isBetween(m, 'year'), false, 'same moments are not between the same year');\n    assert.equal(+m, +mCopy, 'isBetween year should not change moment');\n});\n\ntest('is between month', function (assert) {\n    var m = moment(new Date(2011, 1, 2, 3, 4, 5, 6)), mCopy = moment(m);\n    assert.equal(m.isBetween(\n                moment(new Date(2011, 1, 6, 7, 8, 9, 10)),\n                moment(new Date(2011, 1, 6, 7, 8, 9, 10)), 'month'), false, 'month match');\n    assert.equal(m.isBetween(\n                moment(new Date(2011, 0, 6, 7, 8, 9, 10)),\n                moment(new Date(2011, 2, 6, 7, 8, 9, 10)), 'months'), true, 'plural should work');\n    assert.equal(m.isBetween(\n                moment(new Date(2011, 0, 31, 23, 59, 59, 999)),\n                moment(new Date(2011, 2, 1, 0, 0, 0, 0)), 'month'), true, 'month is between');\n    assert.equal(m.isBetween(\n                moment(new Date(2011, 1, 6, 7, 8, 9, 10)),\n                moment(new Date(2011, 2, 6, 7, 8, 9, 10)), 'month'), false, 'month is earlier');\n    assert.equal(m.isBetween(\n                moment(new Date(2011, 11, 6, 7, 8, 9, 10)),\n                moment(new Date(2011, 1, 6, 7, 8, 9, 10)), 'month'), false, 'month is later');\n    assert.equal(m.isBetween(m, 'month'), false, 'same moments are not between the same month');\n    assert.equal(+m, +mCopy, 'isBetween month should not change moment');\n});\n\ntest('is between day', function (assert) {\n    var m = moment(new Date(2011, 1, 2, 3, 4, 5, 6)), mCopy = moment(m);\n    assert.equal(m.isBetween(\n                moment(new Date(2011, 1, 2, 7, 8, 9, 10)),\n                moment(new Date(2011, 1, 2, 7, 8, 9, 10)), 'day'), false, 'day match');\n    assert.equal(m.isBetween(\n                moment(new Date(2011, 1, 1, 7, 8, 9, 10)),\n                moment(new Date(2011, 1, 3, 7, 8, 9, 10)), 'days'), true, 'plural should work');\n    assert.equal(m.isBetween(\n                moment(new Date(2011, 1, 1, 7, 8, 9, 10)),\n                moment(new Date(2011, 1, 3, 7, 8, 9, 10)), 'day'), true, 'day is between');\n    assert.equal(m.isBetween(\n                moment(new Date(2011, 1, 2, 7, 8, 9, 10)),\n                moment(new Date(2011, 1, 4, 7, 8, 9, 10)), 'day'), false, 'day is earlier');\n    assert.equal(m.isBetween(\n                moment(new Date(2011, 1, 1, 7, 8, 9, 10)),\n                moment(new Date(2011, 1, 2, 7, 8, 9, 10)), 'day'), false, 'day is later');\n    assert.equal(m.isBetween(m, 'day'), false, 'same moments are not between the same day');\n    assert.equal(+m, +mCopy, 'isBetween day should not change moment');\n});\n\ntest('is between hour', function (assert) {\n    var m = moment(new Date(2011, 1, 2, 3, 4, 5, 6)), mCopy = moment(m);\n    assert.equal(m.isBetween(\n                moment(new Date(2011, 1, 2, 3, 5, 9, 10)),\n                moment(new Date(2011, 1, 2, 3, 9, 9, 10)), 'hour'), false, 'hour match');\n    assert.equal(m.isBetween(\n                moment(new Date(2011, 1, 2, 1, 59, 59, 999)),\n                moment(new Date(2011, 1, 2, 4, 0, 0, 0)), 'hours'), true, 'plural should work');\n    assert.equal(m.isBetween(\n                moment(new Date(2011, 1, 2, 2, 59, 59, 999)),\n                moment(new Date(2011, 1, 2, 4, 0, 0, 0)), 'hour'), true, 'hour is between');\n    assert.equal(m.isBetween(\n                moment(new Date(2011, 1, 2, 7, 8, 9, 10)),\n                moment(new Date(2011, 1, 2, 7, 8, 9, 10)), 'hour'), false, 'hour is earlier');\n    assert.equal(m.isBetween(\n                moment(new Date(2011, 1, 2, 7, 8, 9, 10)),\n                moment(new Date(2011, 1, 2, 7, 8, 9, 10)), 'hour'), false, 'hour is later');\n    assert.equal(m.isBetween(m, 'hour'), false, 'same moments are not between the same hour');\n    assert.equal(+m, +mCopy, 'isBetween hour should not change moment');\n});\n\ntest('is between minute', function (assert) {\n    var m = moment(new Date(2011, 1, 2, 3, 4, 5, 6)), mCopy = moment(m);\n    assert.equal(m.isBetween(\n                moment(new Date(2011, 1, 2, 3, 4, 9, 10)),\n                moment(new Date(2011, 1, 2, 3, 4, 9, 10)), 'minute'), false, 'minute match');\n    assert.equal(m.isBetween(\n                moment(new Date(2011, 1, 2, 3, 3, 9, 10)),\n                moment(new Date(2011, 1, 2, 3, 5, 9, 10)), 'minutes'), true, 'plural should work');\n    assert.equal(m.isBetween(\n                moment(new Date(2011, 1, 2, 3, 3, 59, 999)),\n                moment(new Date(2011, 1, 2, 3, 5, 0, 0)), 'minute'), true, 'minute is between');\n    assert.equal(m.isBetween(\n                moment(new Date(2011, 1, 2, 3, 5, 0, 0)),\n                moment(new Date(2011, 1, 2, 3, 8, 9, 10)), 'minute'), false, 'minute is earlier');\n    assert.equal(m.isBetween(\n                moment(new Date(2011, 1, 2, 3, 2, 9, 10)),\n                moment(new Date(2011, 1, 2, 3, 3, 59, 999)), 'minute'), false, 'minute is later');\n    assert.equal(m.isBetween(m, 'minute'), false, 'same moments are not between the same minute');\n    assert.equal(+m, +mCopy, 'isBetween minute should not change moment');\n});\n\ntest('is between second', function (assert) {\n    var m = moment(new Date(2011, 1, 2, 3, 4, 5, 6)), mCopy = moment(m);\n    assert.equal(m.isBetween(\n                moment(new Date(2011, 1, 2, 3, 4, 5, 10)),\n                moment(new Date(2011, 1, 2, 3, 4, 5, 10)), 'second'), false, 'second match');\n    assert.equal(m.isBetween(\n                moment(new Date(2011, 1, 2, 3, 4, 4, 10)),\n                moment(new Date(2011, 1, 2, 3, 4, 6, 10)), 'seconds'), true, 'plural should work');\n    assert.equal(m.isBetween(\n                moment(new Date(2011, 1, 2, 3, 4, 4, 999)),\n                moment(new Date(2011, 1, 2, 3, 4, 6, 0)), 'second'), true, 'second is between');\n    assert.equal(m.isBetween(\n                moment(new Date(2011, 1, 2, 3, 4, 6, 0)),\n                moment(new Date(2011, 1, 2, 3, 4, 7, 10)), 'second'), false, 'second is earlier');\n    assert.equal(m.isBetween(\n                moment(new Date(2011, 1, 2, 3, 4, 3, 10)),\n                moment(new Date(2011, 1, 2, 3, 4, 4, 999)), 'second'), false, 'second is later');\n    assert.equal(m.isBetween(m, 'second'), false, 'same moments are not between the same second');\n    assert.equal(+m, +mCopy, 'isBetween second should not change moment');\n});\n\ntest('is between millisecond', function (assert) {\n    var m = moment(new Date(2011, 1, 2, 3, 4, 5, 6)), mCopy = moment(m);\n    assert.equal(m.isBetween(\n                moment(new Date(2011, 1, 2, 3, 4, 5, 6)),\n                moment(new Date(2011, 1, 2, 3, 4, 5, 6)), 'millisecond'), false, 'millisecond match');\n    assert.equal(m.isBetween(\n                moment(new Date(2011, 1, 2, 3, 4, 5, 5)),\n                moment(new Date(2011, 1, 2, 3, 4, 5, 7)), 'milliseconds'), true, 'plural should work');\n    assert.equal(m.isBetween(\n                moment(new Date(2011, 1, 2, 3, 4, 5, 5)),\n                moment(new Date(2011, 1, 2, 3, 4, 5, 7)), 'millisecond'), true, 'millisecond is between');\n    assert.equal(m.isBetween(\n                moment(new Date(2011, 1, 2, 3, 4, 5, 7)),\n                moment(new Date(2011, 1, 2, 3, 4, 5, 10)), 'millisecond'), false, 'millisecond is earlier');\n    assert.equal(m.isBetween(\n                moment(new Date(2011, 1, 2, 3, 4, 5, 4)),\n                moment(new Date(2011, 1, 2, 3, 4, 5, 6)), 'millisecond'), false, 'millisecond is later');\n    assert.equal(m.isBetween(m, 'millisecond'), false, 'same moments are not between the same millisecond');\n    assert.equal(+m, +mCopy, 'isBetween millisecond should not change moment');\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\nfunction module$1 (name, lifecycle) {\n    QUnit.module(name, {\n        setup : function () {\n            moment.locale('en');\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'core');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            teardownDeprecationHandler(test, moment, 'core');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n}\n\nmodule$1('is date');\n\ntest('isDate recognizes Date objects', function (assert) {\n    assert.ok(moment.isDate(new Date()), 'no args (now)');\n    assert.ok(moment.isDate(new Date([2014, 2, 15])), 'array args');\n    assert.ok(moment.isDate(new Date('2014-03-15')), 'string args');\n    assert.ok(moment.isDate(new Date('does NOT look like a date')), 'invalid date');\n});\n\ntest('isDate rejects non-Date objects', function (assert) {\n    assert.ok(!moment.isDate(), 'nothing');\n    assert.ok(!moment.isDate(undefined), 'undefined');\n    assert.ok(!moment.isDate(null), 'string args');\n    assert.ok(!moment.isDate(42), 'number');\n    assert.ok(!moment.isDate('2014-03-15'), 'string');\n    assert.ok(!moment.isDate([2014, 2, 15]), 'array');\n    assert.ok(!moment.isDate({year: 2014, month: 2, day: 15}), 'object');\n    assert.ok(!moment.isDate({\n        toString: function () {\n            return '[object Date]';\n        }\n    }), 'lying object');\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\nfunction module$1 (name, lifecycle) {\n    QUnit.module(name, {\n        setup : function () {\n            moment.locale('en');\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'core');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            teardownDeprecationHandler(test, moment, 'core');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n}\n\nmodule$1('is moment');\n\ntest('is moment object', function (assert) {\n    var MyObj = function () {},\n        extend = function (a, b) {\n            var i;\n            for (i in b) {\n                a[i] = b[i];\n            }\n            return a;\n        };\n    MyObj.prototype.toDate = function () {\n        return new Date();\n    };\n\n    assert.ok(moment.isMoment(moment()), 'simple moment object');\n    assert.ok(moment.isMoment(moment(null)), 'invalid moment object');\n    assert.ok(moment.isMoment(extend({}, moment())), 'externally cloned moments are moments');\n    assert.ok(moment.isMoment(extend({}, moment.utc())), 'externally cloned utc moments are moments');\n\n    assert.ok(!moment.isMoment(new MyObj()), 'myObj is not moment object');\n    assert.ok(!moment.isMoment(moment), 'moment function is not moment object');\n    assert.ok(!moment.isMoment(new Date()), 'date object is not moment object');\n    assert.ok(!moment.isMoment(Object), 'Object is not moment object');\n    assert.ok(!moment.isMoment('foo'), 'string is not moment object');\n    assert.ok(!moment.isMoment(1), 'number is not moment object');\n    assert.ok(!moment.isMoment(NaN), 'NaN is not moment object');\n    assert.ok(!moment.isMoment(null), 'null is not moment object');\n    assert.ok(!moment.isMoment(undefined), 'undefined is not moment object');\n});\n\ntest('is moment with hacked hasOwnProperty', function (assert) {\n    var obj = {};\n    // HACK to suppress jshint warning about bad property name\n    obj['hasOwnMoney'.replace('Money', 'Property')] = function () {\n        return true;\n    };\n\n    assert.ok(!moment.isMoment(obj), 'isMoment works even if passed object has a wrong hasOwnProperty implementation (ie8)');\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\nfunction isNumber(input) {\n    return typeof input === 'number' || Object.prototype.toString.call(input) === '[object Number]';\n}\n\ntest('isNumber recognizes numbers', function (assert) {\n    assert.ok(isNumber(1), 'simple integer');\n    assert.ok(isNumber(0), 'simple number');\n    assert.ok(isNumber(-0), 'silly number');\n    assert.ok(isNumber(1010010293029), 'large number');\n    assert.ok(isNumber(Infinity), 'largest number');\n    assert.ok(isNumber(-Infinity), 'smallest number');\n    assert.ok(isNumber(NaN), 'not number');\n    assert.ok(isNumber(1.100393830000), 'decimal numbers');\n    assert.ok(isNumber(Math.LN2), 'natural log of two');\n    assert.ok(isNumber(Math.PI), 'delicious number');\n    assert.ok(isNumber(5e10), 'scientifically notated number');\n    assert.ok(isNumber(new Number(1)), 'number primitive wrapped in an object'); // jshint ignore:line\n});\n\ntest('isNumber rejects non-numbers', function (assert) {\n    assert.ok(!isNumber(), 'nothing');\n    assert.ok(!isNumber(undefined), 'undefined');\n    assert.ok(!isNumber(null), 'null');\n    assert.ok(!isNumber([1]), 'array');\n    assert.ok(!isNumber('[1,2,3]'), 'string');\n    assert.ok(!isNumber(new Date()), 'date');\n    assert.ok(!isNumber({a:1,b:2}), 'object');\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\nfunction module$1 (name, lifecycle) {\n    QUnit.module(name, {\n        setup : function () {\n            moment.locale('en');\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'core');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            teardownDeprecationHandler(test, moment, 'core');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n}\n\nmodule$1('is same');\n\ntest('is same without units', function (assert) {\n    var m = moment(new Date(2011, 3, 2, 3, 4, 5, 10)), mCopy = moment(m);\n    assert.equal(m.isSame(moment(new Date(2012, 3, 2, 3, 5, 5, 10))), false, 'year is later');\n    assert.equal(m.isSame(moment(new Date(2010, 3, 2, 3, 3, 5, 10))), false, 'year is earlier');\n    assert.equal(m.isSame(moment(new Date(2011, 4, 2, 3, 4, 5, 10))), false, 'month is later');\n    assert.equal(m.isSame(moment(new Date(2011, 2, 2, 3, 4, 5, 10))), false, 'month is earlier');\n    assert.equal(m.isSame(moment(new Date(2011, 3, 3, 3, 4, 5, 10))), false, 'day is later');\n    assert.equal(m.isSame(moment(new Date(2011, 3, 1, 3, 4, 5, 10))), false, 'day is earlier');\n    assert.equal(m.isSame(moment(new Date(2011, 3, 2, 4, 4, 5, 10))), false, 'hour is later');\n    assert.equal(m.isSame(moment(new Date(2011, 3, 2, 2, 4, 5, 10))), false, 'hour is earlier');\n    assert.equal(m.isSame(moment(new Date(2011, 3, 2, 3, 5, 5, 10))), false, 'minute is later');\n    assert.equal(m.isSame(moment(new Date(2011, 3, 2, 3, 3, 5, 10))), false, 'minute is earlier');\n    assert.equal(m.isSame(moment(new Date(2011, 3, 2, 3, 4, 6, 10))), false, 'second is later');\n    assert.equal(m.isSame(moment(new Date(2011, 3, 2, 3, 4, 4, 11))), false, 'second is earlier');\n    assert.equal(m.isSame(moment(new Date(2011, 3, 2, 3, 4, 5, 10))), true, 'millisecond match');\n    assert.equal(m.isSame(moment(new Date(2011, 3, 2, 3, 4, 5, 11))), false, 'millisecond is later');\n    assert.equal(m.isSame(moment(new Date(2011, 3, 2, 3, 4, 5, 9))), false, 'millisecond is earlier');\n    assert.equal(m.isSame(m), true, 'moments are the same as themselves');\n    assert.equal(+m, +mCopy, 'isSame second should not change moment');\n});\n\ntest('is same year', function (assert) {\n    var m = moment(new Date(2011, 1, 2, 3, 4, 5, 6)), mCopy = moment(m);\n    assert.equal(m.isSame(moment(new Date(2011, 5, 6, 7, 8, 9, 10)), 'year'), true, 'year match');\n    assert.equal(m.isSame(moment(new Date(2011, 5, 6, 7, 8, 9, 10)), 'years'), true, 'plural should work');\n    assert.equal(m.isSame(moment(new Date(2012, 5, 6, 7, 8, 9, 10)), 'year'), false, 'year mismatch');\n    assert.equal(m.isSame(moment(new Date(2011, 0, 1, 0, 0, 0, 0)), 'year'), true, 'exact start of year');\n    assert.equal(m.isSame(moment(new Date(2011, 11, 31, 23, 59, 59, 999)), 'year'), true, 'exact end of year');\n    assert.equal(m.isSame(moment(new Date(2012, 0, 1, 0, 0, 0, 0)), 'year'), false, 'start of next year');\n    assert.equal(m.isSame(moment(new Date(2010, 11, 31, 23, 59, 59, 999)), 'year'), false, 'end of previous year');\n    assert.equal(m.isSame(m, 'year'), true, 'same moments are in the same year');\n    assert.equal(+m, +mCopy, 'isSame year should not change moment');\n});\n\ntest('is same month', function (assert) {\n    var m = moment(new Date(2011, 2, 3, 4, 5, 6, 7)), mCopy = moment(m);\n    assert.equal(m.isSame(moment(new Date(2011, 2, 6, 7, 8, 9, 10)), 'month'), true, 'month match');\n    assert.equal(m.isSame(moment(new Date(2011, 2, 6, 7, 8, 9, 10)), 'months'), true, 'plural should work');\n    assert.equal(m.isSame(moment(new Date(2012, 2, 6, 7, 8, 9, 10)), 'month'), false, 'year mismatch');\n    assert.equal(m.isSame(moment(new Date(2011, 5, 6, 7, 8, 9, 10)), 'month'), false, 'month mismatch');\n    assert.equal(m.isSame(moment(new Date(2011, 2, 1, 0, 0, 0, 0)), 'month'), true, 'exact start of month');\n    assert.equal(m.isSame(moment(new Date(2011, 2, 31, 23, 59, 59, 999)), 'month'), true, 'exact end of month');\n    assert.equal(m.isSame(moment(new Date(2011, 3, 1, 0, 0, 0, 0)), 'month'), false, 'start of next month');\n    assert.equal(m.isSame(moment(new Date(2011, 1, 27, 23, 59, 59, 999)), 'month'), false, 'end of previous month');\n    assert.equal(m.isSame(m, 'month'), true, 'same moments are in the same month');\n    assert.equal(+m, +mCopy, 'isSame month should not change moment');\n});\n\ntest('is same day', function (assert) {\n    var m = moment(new Date(2011, 1, 2, 3, 4, 5, 6)), mCopy = moment(m);\n    assert.equal(m.isSame(moment(new Date(2011, 1, 2, 7, 8, 9, 10)), 'day'), true, 'day match');\n    assert.equal(m.isSame(moment(new Date(2011, 1, 2, 7, 8, 9, 10)), 'days'), true, 'plural should work');\n    assert.equal(m.isSame(moment(new Date(2012, 1, 2, 7, 8, 9, 10)), 'day'), false, 'year mismatch');\n    assert.equal(m.isSame(moment(new Date(2011, 2, 2, 7, 8, 9, 10)), 'day'), false, 'month mismatch');\n    assert.equal(m.isSame(moment(new Date(2011, 1, 3, 7, 8, 9, 10)), 'day'), false, 'day mismatch');\n    assert.equal(m.isSame(moment(new Date(2011, 1, 2, 0, 0, 0, 0)), 'day'), true, 'exact start of day');\n    assert.equal(m.isSame(moment(new Date(2011, 1, 2, 23, 59, 59, 999)), 'day'), true, 'exact end of day');\n    assert.equal(m.isSame(moment(new Date(2011, 1, 3, 0, 0, 0, 0)), 'day'), false, 'start of next day');\n    assert.equal(m.isSame(moment(new Date(2011, 1, 1, 23, 59, 59, 999)), 'day'), false, 'end of previous day');\n    assert.equal(m.isSame(m, 'day'), true, 'same moments are in the same day');\n    assert.equal(+m, +mCopy, 'isSame day should not change moment');\n});\n\ntest('is same hour', function (assert) {\n    var m = moment(new Date(2011, 1, 2, 3, 4, 5, 6)), mCopy = moment(m);\n    assert.equal(m.isSame(moment(new Date(2011, 1, 2, 3, 8, 9, 10)), 'hour'), true, 'hour match');\n    assert.equal(m.isSame(moment(new Date(2011, 1, 2, 3, 8, 9, 10)), 'hours'), true, 'plural should work');\n    assert.equal(m.isSame(moment(new Date(2012, 1, 2, 3, 8, 9, 10)), 'hour'), false, 'year mismatch');\n    assert.equal(m.isSame(moment(new Date(2011, 2, 2, 3, 8, 9, 10)), 'hour'), false, 'month mismatch');\n    assert.equal(m.isSame(moment(new Date(2011, 1, 3, 3, 8, 9, 10)), 'hour'), false, 'day mismatch');\n    assert.equal(m.isSame(moment(new Date(2011, 1, 2, 4, 8, 9, 10)), 'hour'), false, 'hour mismatch');\n    assert.equal(m.isSame(moment(new Date(2011, 1, 2, 3, 0, 0, 0)), 'hour'), true, 'exact start of hour');\n    assert.equal(m.isSame(moment(new Date(2011, 1, 2, 3, 59, 59, 999)), 'hour'), true, 'exact end of hour');\n    assert.equal(m.isSame(moment(new Date(2011, 1, 2, 4, 0, 0, 0)), 'hour'), false, 'start of next hour');\n    assert.equal(m.isSame(moment(new Date(2011, 1, 2, 2, 59, 59, 999)), 'hour'), false, 'end of previous hour');\n    assert.equal(m.isSame(m, 'hour'), true, 'same moments are in the same hour');\n    assert.equal(+m, +mCopy, 'isSame hour should not change moment');\n});\n\ntest('is same minute', function (assert) {\n    var m = moment(new Date(2011, 1, 2, 3, 4, 5, 6)), mCopy = moment(m);\n    assert.equal(m.isSame(moment(new Date(2011, 1, 2, 3, 4, 9, 10)), 'minute'), true, 'minute match');\n    assert.equal(m.isSame(moment(new Date(2011, 1, 2, 3, 4, 9, 10)), 'minutes'), true, 'plural should work');\n    assert.equal(m.isSame(moment(new Date(2012, 1, 2, 3, 4, 9, 10)), 'minute'), false, 'year mismatch');\n    assert.equal(m.isSame(moment(new Date(2011, 2, 2, 3, 4, 9, 10)), 'minute'), false, 'month mismatch');\n    assert.equal(m.isSame(moment(new Date(2011, 1, 3, 3, 4, 9, 10)), 'minute'), false, 'day mismatch');\n    assert.equal(m.isSame(moment(new Date(2011, 1, 2, 4, 4, 9, 10)), 'minute'), false, 'hour mismatch');\n    assert.equal(m.isSame(moment(new Date(2011, 1, 2, 3, 5, 9, 10)), 'minute'), false, 'minute mismatch');\n    assert.equal(m.isSame(moment(new Date(2011, 1, 2, 3, 4, 0, 0)), 'minute'), true, 'exact start of minute');\n    assert.equal(m.isSame(moment(new Date(2011, 1, 2, 3, 4, 59, 999)), 'minute'), true, 'exact end of minute');\n    assert.equal(m.isSame(moment(new Date(2011, 1, 2, 3, 5, 0, 0)), 'minute'), false, 'start of next minute');\n    assert.equal(m.isSame(moment(new Date(2011, 1, 2, 3, 3, 59, 999)), 'minute'), false, 'end of previous minute');\n    assert.equal(m.isSame(m, 'minute'), true, 'same moments are in the same minute');\n    assert.equal(+m, +mCopy, 'isSame minute should not change moment');\n});\n\ntest('is same second', function (assert) {\n    var m = moment(new Date(2011, 1, 2, 3, 4, 5, 6)), mCopy = moment(m);\n    assert.equal(m.isSame(moment(new Date(2011, 1, 2, 3, 4, 5, 10)), 'second'), true, 'second match');\n    assert.equal(m.isSame(moment(new Date(2011, 1, 2, 3, 4, 5, 10)), 'seconds'), true, 'plural should work');\n    assert.equal(m.isSame(moment(new Date(2012, 1, 2, 3, 4, 5, 10)), 'second'), false, 'year mismatch');\n    assert.equal(m.isSame(moment(new Date(2011, 2, 2, 3, 4, 5, 10)), 'second'), false, 'month mismatch');\n    assert.equal(m.isSame(moment(new Date(2011, 1, 3, 3, 4, 5, 10)), 'second'), false, 'day mismatch');\n    assert.equal(m.isSame(moment(new Date(2011, 1, 2, 4, 4, 5, 10)), 'second'), false, 'hour mismatch');\n    assert.equal(m.isSame(moment(new Date(2011, 1, 2, 3, 5, 5, 10)), 'second'), false, 'minute mismatch');\n    assert.equal(m.isSame(moment(new Date(2011, 1, 2, 3, 4, 6, 10)), 'second'), false, 'second mismatch');\n    assert.equal(m.isSame(moment(new Date(2011, 1, 2, 3, 4, 5, 0)), 'second'), true, 'exact start of second');\n    assert.equal(m.isSame(moment(new Date(2011, 1, 2, 3, 4, 5, 999)), 'second'), true, 'exact end of second');\n    assert.equal(m.isSame(moment(new Date(2011, 1, 2, 3, 4, 6, 0)), 'second'), false, 'start of next second');\n    assert.equal(m.isSame(moment(new Date(2011, 1, 2, 3, 4, 4, 999)), 'second'), false, 'end of previous second');\n    assert.equal(m.isSame(m, 'second'), true, 'same moments are in the same second');\n    assert.equal(+m, +mCopy, 'isSame second should not change moment');\n});\n\ntest('is same millisecond', function (assert) {\n    var m = moment(new Date(2011, 3, 2, 3, 4, 5, 10)), mCopy = moment(m);\n    assert.equal(m.isSame(moment(new Date(2011, 3, 2, 3, 4, 5, 10)), 'millisecond'), true, 'millisecond match');\n    assert.equal(m.isSame(moment(new Date(2011, 3, 2, 3, 4, 5, 10)), 'milliseconds'), true, 'plural should work');\n    assert.equal(m.isSame(moment(new Date(2012, 3, 2, 3, 4, 5, 10)), 'millisecond'), false, 'year is later');\n    assert.equal(m.isSame(moment(new Date(2010, 3, 2, 3, 4, 5, 10)), 'millisecond'), false, 'year is earlier');\n    assert.equal(m.isSame(moment(new Date(2011, 4, 2, 3, 4, 5, 10)), 'millisecond'), false, 'month is later');\n    assert.equal(m.isSame(moment(new Date(2011, 2, 2, 3, 4, 5, 10)), 'millisecond'), false, 'month is earlier');\n    assert.equal(m.isSame(moment(new Date(2011, 3, 3, 3, 4, 5, 10)), 'millisecond'), false, 'day is later');\n    assert.equal(m.isSame(moment(new Date(2011, 3, 1, 1, 4, 5, 10)), 'millisecond'), false, 'day is earlier');\n    assert.equal(m.isSame(moment(new Date(2011, 3, 2, 4, 4, 5, 10)), 'millisecond'), false, 'hour is later');\n    assert.equal(m.isSame(moment(new Date(2011, 3, 1, 4, 1, 5, 10)), 'millisecond'), false, 'hour is earlier');\n    assert.equal(m.isSame(moment(new Date(2011, 3, 2, 3, 5, 5, 10)), 'millisecond'), false, 'minute is later');\n    assert.equal(m.isSame(moment(new Date(2011, 3, 2, 3, 3, 5, 10)), 'millisecond'), false, 'minute is earlier');\n    assert.equal(m.isSame(moment(new Date(2011, 3, 2, 3, 4, 6, 10)), 'millisecond'), false, 'second is later');\n    assert.equal(m.isSame(moment(new Date(2011, 3, 2, 3, 4, 4, 5)), 'millisecond'), false, 'second is earlier');\n    assert.equal(m.isSame(moment(new Date(2011, 3, 2, 3, 4, 6, 11)), 'millisecond'), false, 'millisecond is later');\n    assert.equal(m.isSame(moment(new Date(2011, 3, 2, 3, 4, 4, 9)), 'millisecond'), false, 'millisecond is earlier');\n    assert.equal(m.isSame(m, 'millisecond'), true, 'same moments are in the same millisecond');\n    assert.equal(+m, +mCopy, 'isSame millisecond should not change moment');\n});\n\ntest('is same with utc offset moments', function (assert) {\n    assert.ok(moment.parseZone('2013-02-01T00:00:00-05:00').isSame(moment('2013-02-01'), 'year'), 'zoned vs local moment');\n    assert.ok(moment('2013-02-01').isSame(moment('2013-02-01').utcOffset('-05:00'), 'year'), 'local vs zoned moment');\n    assert.ok(moment.parseZone('2013-02-01T00:00:00-05:00').isSame(moment.parseZone('2013-02-01T00:00:00-06:30'), 'year'),\n            'zoned vs (differently) zoned moment');\n});\n\ntest('is same with invalid moments', function (assert) {\n    assert.equal(moment.invalid().isSame(moment.invalid()), false, 'invalid moments are not considered equal');\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\nfunction module$1 (name, lifecycle) {\n    QUnit.module(name, {\n        setup : function () {\n            moment.locale('en');\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'core');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            teardownDeprecationHandler(test, moment, 'core');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n}\n\nmodule$1('is same or after');\n\ntest('is same or after without units', function (assert) {\n    var m = moment(new Date(2011, 3, 2, 3, 4, 5, 10)), mCopy = moment(m);\n    assert.equal(m.isSameOrAfter(moment(new Date(2012, 3, 2, 3, 5, 5, 10))), false, 'year is later');\n    assert.equal(m.isSameOrAfter(moment(new Date(2010, 3, 2, 3, 3, 5, 10))), true, 'year is earlier');\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 4, 2, 3, 4, 5, 10))), false, 'month is later');\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 2, 2, 3, 4, 5, 10))), true, 'month is earlier');\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 3, 3, 3, 4, 5, 10))), false, 'day is later');\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 3, 1, 3, 4, 5, 10))), true, 'day is earlier');\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 3, 2, 4, 4, 5, 10))), false, 'hour is later');\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 3, 2, 2, 4, 5, 10))), true, 'hour is earlier');\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 3, 2, 3, 5, 5, 10))), false, 'minute is later');\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 3, 2, 3, 3, 5, 10))), true, 'minute is earlier');\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 3, 2, 3, 4, 6, 10))), false, 'second is later');\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 3, 2, 3, 4, 4, 11))), true, 'second is earlier');\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 3, 2, 3, 4, 5, 10))), true, 'millisecond match');\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 3, 2, 3, 4, 5, 11))), false, 'millisecond is later');\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 3, 2, 3, 4, 5, 9))), true, 'millisecond is earlier');\n    assert.equal(m.isSameOrAfter(m), true, 'moments are the same as themselves');\n    assert.equal(+m, +mCopy, 'isSameOrAfter second should not change moment');\n});\n\ntest('is same or after year', function (assert) {\n    var m = moment(new Date(2011, 1, 2, 3, 4, 5, 6)), mCopy = moment(m);\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 5, 6, 7, 8, 9, 10)), 'year'), true, 'year match');\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 5, 6, 7, 8, 9, 10)), 'years'), true, 'plural should work');\n    assert.equal(m.isSameOrAfter(moment(new Date(2012, 5, 6, 7, 8, 9, 10)), 'year'), false, 'year is later');\n    assert.equal(m.isSameOrAfter(moment(new Date(2010, 5, 6, 7, 8, 9, 10)), 'year'), true, 'year is earlier');\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 0, 1, 0, 0, 0, 0)), 'year'), true, 'exact start of year');\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 11, 31, 23, 59, 59, 999)), 'year'), true, 'exact end of year');\n    assert.equal(m.isSameOrAfter(moment(new Date(2012, 0, 1, 0, 0, 0, 0)), 'year'), false, 'start of next year');\n    assert.equal(m.isSameOrAfter(moment(new Date(2010, 11, 31, 23, 59, 59, 999)), 'year'), true, 'end of previous year');\n    assert.equal(m.isSameOrAfter(m, 'year'), true, 'same moments are in the same year');\n    assert.equal(+m, +mCopy, 'isSameOrAfter year should not change moment');\n});\n\ntest('is same or after month', function (assert) {\n    var m = moment(new Date(2011, 2, 3, 4, 5, 6, 7)), mCopy = moment(m);\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 2, 6, 7, 8, 9, 10)), 'month'), true, 'month match');\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 2, 6, 7, 8, 9, 10)), 'months'), true, 'plural should work');\n    assert.equal(m.isSameOrAfter(moment(new Date(2012, 2, 6, 7, 8, 9, 10)), 'month'), false, 'year is later');\n    assert.equal(m.isSameOrAfter(moment(new Date(2010, 2, 6, 7, 8, 9, 10)), 'month'), true, 'year is earlier');\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 5, 6, 7, 8, 9, 10)), 'month'), false, 'month is later');\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 1, 6, 7, 8, 9, 10)), 'month'), true, 'month is earlier');\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 2, 1, 0, 0, 0, 0)), 'month'), true, 'exact start of month');\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 2, 31, 23, 59, 59, 999)), 'month'), true, 'exact end of month');\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 3, 1, 0, 0, 0, 0)), 'month'), false, 'start of next month');\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 1, 27, 23, 59, 59, 999)), 'month'), true, 'end of previous month');\n    assert.equal(m.isSameOrAfter(m, 'month'), true, 'same moments are in the same month');\n    assert.equal(+m, +mCopy, 'isSameOrAfter month should not change moment');\n});\n\ntest('is same or after day', function (assert) {\n    var m = moment(new Date(2011, 1, 2, 3, 4, 5, 6)), mCopy = moment(m);\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 1, 2, 7, 8, 9, 10)), 'day'), true, 'day match');\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 1, 2, 7, 8, 9, 10)), 'days'), true, 'plural should work');\n    assert.equal(m.isSameOrAfter(moment(new Date(2012, 1, 2, 7, 8, 9, 10)), 'day'), false, 'year is later');\n    assert.equal(m.isSameOrAfter(moment(new Date(2010, 1, 2, 7, 8, 9, 10)), 'day'), true, 'year is earlier');\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 2, 2, 7, 8, 9, 10)), 'day'), false, 'month is later');\n    assert.equal(m.isSameOrAfter(moment(new Date(2010, 12, 2, 7, 8, 9, 10)), 'day'), true, 'month is earlier');\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 1, 3, 7, 8, 9, 10)), 'day'), false, 'day is later');\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 1, 1, 7, 8, 9, 10)), 'day'), true, 'day is earlier');\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 1, 2, 0, 0, 0, 0)), 'day'), true, 'exact start of day');\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 1, 2, 23, 59, 59, 999)), 'day'), true, 'exact end of day');\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 1, 3, 0, 0, 0, 0)), 'day'), false, 'start of next day');\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 1, 1, 23, 59, 59, 999)), 'day'), true, 'end of previous day');\n    assert.equal(m.isSameOrAfter(m, 'day'), true, 'same moments are in the same day');\n    assert.equal(+m, +mCopy, 'isSameOrAfter day should not change moment');\n});\n\ntest('is same or after hour', function (assert) {\n    var m = moment(new Date(2011, 1, 2, 3, 4, 5, 6)), mCopy = moment(m);\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 1, 2, 3, 8, 9, 10)), 'hour'), true, 'hour match');\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 1, 2, 3, 8, 9, 10)), 'hours'), true, 'plural should work');\n    assert.equal(m.isSameOrAfter(moment(new Date(2012, 1, 2, 3, 8, 9, 10)), 'hour'), false, 'year is later');\n    assert.equal(m.isSameOrAfter(moment(new Date(2010, 1, 2, 3, 8, 9, 10)), 'hour'), true, 'year is earlier');\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 2, 2, 3, 8, 9, 10)), 'hour'), false, 'month is later');\n    assert.equal(m.isSameOrAfter(moment(new Date(2010, 12, 2, 3, 8, 9, 10)), 'hour'), true, 'month is earlier');\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 1, 3, 3, 8, 9, 10)), 'hour'), false, 'day is later');\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 1, 1, 3, 8, 9, 10)), 'hour'), true, 'day is earlier');\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 1, 2, 4, 8, 9, 10)), 'hour'), false, 'hour is later');\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 1, 2, 2, 8, 9, 10)), 'hour'), true, 'hour is earlier');\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 1, 2, 3, 0, 0, 0)), 'hour'), true, 'exact start of hour');\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 1, 2, 3, 59, 59, 999)), 'hour'), true, 'exact end of hour');\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 1, 2, 4, 0, 0, 0)), 'hour'), false, 'start of next hour');\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 1, 2, 2, 59, 59, 999)), 'hour'), true, 'end of previous hour');\n    assert.equal(m.isSameOrAfter(m, 'hour'), true, 'same moments are in the same hour');\n    assert.equal(+m, +mCopy, 'isSameOrAfter hour should not change moment');\n});\n\ntest('is same or after minute', function (assert) {\n    var m = moment(new Date(2011, 1, 2, 3, 4, 5, 6)), mCopy = moment(m);\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 1, 2, 3, 4, 9, 10)), 'minute'), true, 'minute match');\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 1, 2, 3, 4, 9, 10)), 'minutes'), true, 'plural should work');\n    assert.equal(m.isSameOrAfter(moment(new Date(2012, 1, 2, 3, 4, 9, 10)), 'minute'), false, 'year is later');\n    assert.equal(m.isSameOrAfter(moment(new Date(2010, 1, 2, 3, 4, 9, 10)), 'minute'), true, 'year is earlier');\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 2, 2, 3, 4, 9, 10)), 'minute'), false, 'month is later');\n    assert.equal(m.isSameOrAfter(moment(new Date(2010, 12, 2, 3, 4, 9, 10)), 'minute'), true, 'month is earlier');\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 1, 3, 3, 4, 9, 10)), 'minute'), false, 'day is later');\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 1, 1, 3, 4, 9, 10)), 'minute'), true, 'day is earlier');\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 1, 2, 4, 4, 9, 10)), 'minute'), false, 'hour is later');\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 1, 2, 2, 4, 9, 10)), 'minute'), true, 'hour is earlier');\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 1, 2, 3, 5, 9, 10)), 'minute'), false, 'minute is later');\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 1, 2, 3, 3, 9, 10)), 'minute'), true, 'minute is earlier');\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 1, 2, 3, 4, 0, 0)), 'minute'), true, 'exact start of minute');\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 1, 2, 3, 4, 59, 999)), 'minute'), true, 'exact end of minute');\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 1, 2, 3, 5, 0, 0)), 'minute'), false, 'start of next minute');\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 1, 2, 3, 3, 59, 999)), 'minute'), true, 'end of previous minute');\n    assert.equal(m.isSameOrAfter(m, 'minute'), true, 'same moments are in the same minute');\n    assert.equal(+m, +mCopy, 'isSameOrAfter minute should not change moment');\n});\n\ntest('is same or after second', function (assert) {\n    var m = moment(new Date(2011, 1, 2, 3, 4, 5, 6)), mCopy = moment(m);\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 1, 2, 3, 4, 5, 10)), 'second'), true, 'second match');\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 1, 2, 3, 4, 5, 10)), 'seconds'), true, 'plural should work');\n    assert.equal(m.isSameOrAfter(moment(new Date(2012, 1, 2, 3, 4, 5, 10)), 'second'), false, 'year is later');\n    assert.equal(m.isSameOrAfter(moment(new Date(2010, 1, 2, 3, 4, 5, 10)), 'second'), true, 'year is earlier');\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 2, 2, 3, 4, 5, 10)), 'second'), false, 'month is later');\n    assert.equal(m.isSameOrAfter(moment(new Date(2010, 12, 2, 3, 4, 5, 10)), 'second'), true, 'month is earlier');\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 1, 3, 3, 4, 5, 10)), 'second'), false, 'day is later');\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 1, 1, 3, 4, 5, 10)), 'second'), true, 'day is earlier');\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 1, 2, 4, 4, 5, 10)), 'second'), false, 'hour is later');\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 1, 2, 2, 4, 5, 10)), 'second'), true, 'hour is earlier');\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 1, 2, 3, 5, 5, 10)), 'second'), false, 'minute is later');\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 1, 2, 3, 3, 5, 10)), 'second'), true, 'minute is earlier');\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 1, 2, 3, 4, 6, 10)), 'second'), false, 'second is later');\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 1, 2, 3, 4, 4, 10)), 'second'), true, 'second is earlier');\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 1, 2, 3, 4, 5, 0)), 'second'), true, 'exact start of second');\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 1, 2, 3, 4, 5, 999)), 'second'), true, 'exact end of second');\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 1, 2, 3, 4, 6, 0)), 'second'), false, 'start of next second');\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 1, 2, 3, 4, 4, 999)), 'second'), true, 'end of previous second');\n    assert.equal(m.isSameOrAfter(m, 'second'), true, 'same moments are in the same second');\n    assert.equal(+m, +mCopy, 'isSameOrAfter second should not change moment');\n});\n\ntest('is same or after millisecond', function (assert) {\n    var m = moment(new Date(2011, 3, 2, 3, 4, 5, 10)), mCopy = moment(m);\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 3, 2, 3, 4, 5, 10)), 'millisecond'), true, 'millisecond match');\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 3, 2, 3, 4, 5, 10)), 'milliseconds'), true, 'plural should work');\n    assert.equal(m.isSameOrAfter(moment(new Date(2012, 3, 2, 3, 4, 5, 10)), 'millisecond'), false, 'year is later');\n    assert.equal(m.isSameOrAfter(moment(new Date(2010, 3, 2, 3, 4, 5, 10)), 'millisecond'), true, 'year is earlier');\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 4, 2, 3, 4, 5, 10)), 'millisecond'), false, 'month is later');\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 2, 2, 3, 4, 5, 10)), 'millisecond'), true, 'month is earlier');\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 3, 3, 3, 4, 5, 10)), 'millisecond'), false, 'day is later');\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 3, 1, 1, 4, 5, 10)), 'millisecond'), true, 'day is earlier');\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 3, 2, 4, 4, 5, 10)), 'millisecond'), false, 'hour is later');\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 3, 1, 4, 1, 5, 10)), 'millisecond'), true, 'hour is earlier');\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 3, 2, 3, 5, 5, 10)), 'millisecond'), false, 'minute is later');\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 3, 2, 3, 3, 5, 10)), 'millisecond'), true, 'minute is earlier');\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 3, 2, 3, 4, 6, 10)), 'millisecond'), false, 'second is later');\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 3, 2, 3, 4, 4, 5)), 'millisecond'), true, 'second is earlier');\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 3, 2, 3, 4, 6, 11)), 'millisecond'), false, 'millisecond is later');\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 3, 2, 3, 4, 4, 9)), 'millisecond'), true, 'millisecond is earlier');\n    assert.equal(m.isSameOrAfter(m, 'millisecond'), true, 'same moments are in the same millisecond');\n    assert.equal(+m, +mCopy, 'isSameOrAfter millisecond should not change moment');\n});\n\ntest('is same or after with utc offset moments', function (assert) {\n    assert.ok(moment.parseZone('2013-02-01T00:00:00-05:00').isSameOrAfter(moment('2013-02-01'), 'year'), 'zoned vs local moment');\n    assert.ok(moment('2013-02-01').isSameOrAfter(moment('2013-02-01').utcOffset('-05:00'), 'year'), 'local vs zoned moment');\n    assert.ok(moment.parseZone('2013-02-01T00:00:00-05:00').isSameOrAfter(moment.parseZone('2013-02-01T00:00:00-06:30'), 'year'),\n            'zoned vs (differently) zoned moment');\n});\n\ntest('is same or after with invalid moments', function (assert) {\n    var m = moment(), invalid = moment.invalid();\n    assert.equal(invalid.isSameOrAfter(invalid), false, 'invalid moments are not considered equal');\n    assert.equal(m.isSameOrAfter(invalid), false, 'valid moment is not after invalid moment');\n    assert.equal(invalid.isSameOrAfter(m), false, 'invalid moment is not after valid moment');\n    assert.equal(m.isSameOrAfter(invalid, 'year'), false, 'invalid moment year');\n    assert.equal(m.isSameOrAfter(invalid, 'month'), false, 'invalid moment month');\n    assert.equal(m.isSameOrAfter(invalid, 'day'), false, 'invalid moment day');\n    assert.equal(m.isSameOrAfter(invalid, 'hour'), false, 'invalid moment hour');\n    assert.equal(m.isSameOrAfter(invalid, 'minute'), false, 'invalid moment minute');\n    assert.equal(m.isSameOrAfter(invalid, 'second'), false, 'invalid moment second');\n    assert.equal(m.isSameOrAfter(invalid, 'milliseconds'), false, 'invalid moment milliseconds');\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\nfunction module$1 (name, lifecycle) {\n    QUnit.module(name, {\n        setup : function () {\n            moment.locale('en');\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'core');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            teardownDeprecationHandler(test, moment, 'core');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n}\n\nmodule$1('is same or before');\n\ntest('is same or before without units', function (assert) {\n    var m = moment(new Date(2011, 3, 2, 3, 4, 5, 10)), mCopy = moment(m);\n    assert.equal(m.isSameOrBefore(moment(new Date(2012, 3, 2, 3, 5, 5, 10))), true, 'year is later');\n    assert.equal(m.isSameOrBefore(moment(new Date(2010, 3, 2, 3, 3, 5, 10))), false, 'year is earlier');\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 4, 2, 3, 4, 5, 10))), true, 'month is later');\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 2, 2, 3, 4, 5, 10))), false, 'month is earlier');\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 3, 3, 3, 4, 5, 10))), true, 'day is later');\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 3, 1, 3, 4, 5, 10))), false, 'day is earlier');\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 3, 2, 4, 4, 5, 10))), true, 'hour is later');\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 3, 2, 2, 4, 5, 10))), false, 'hour is earlier');\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 3, 2, 3, 5, 5, 10))), true, 'minute is later');\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 3, 2, 3, 3, 5, 10))), false, 'minute is earlier');\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 3, 2, 3, 4, 6, 10))), true, 'second is later');\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 3, 2, 3, 4, 4, 11))), false, 'second is earlier');\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 3, 2, 3, 4, 5, 10))), true, 'millisecond match');\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 3, 2, 3, 4, 5, 11))), true, 'millisecond is later');\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 3, 2, 3, 4, 5, 9))), false, 'millisecond is earlier');\n    assert.equal(m.isSameOrBefore(m), true, 'moments are the same as themselves');\n    assert.equal(+m, +mCopy, 'isSameOrBefore second should not change moment');\n});\n\ntest('is same or before year', function (assert) {\n    var m = moment(new Date(2011, 1, 2, 3, 4, 5, 6)), mCopy = moment(m);\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 5, 6, 7, 8, 9, 10)), 'year'), true, 'year match');\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 5, 6, 7, 8, 9, 10)), 'years'), true, 'plural should work');\n    assert.equal(m.isSameOrBefore(moment(new Date(2012, 5, 6, 7, 8, 9, 10)), 'year'), true, 'year is later');\n    assert.equal(m.isSameOrBefore(moment(new Date(2010, 5, 6, 7, 8, 9, 10)), 'year'), false, 'year is earlier');\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 0, 1, 0, 0, 0, 0)), 'year'), true, 'exact start of year');\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 11, 31, 23, 59, 59, 999)), 'year'), true, 'exact end of year');\n    assert.equal(m.isSameOrBefore(moment(new Date(2012, 0, 1, 0, 0, 0, 0)), 'year'), true, 'start of next year');\n    assert.equal(m.isSameOrBefore(moment(new Date(2010, 11, 31, 23, 59, 59, 999)), 'year'), false, 'end of previous year');\n    assert.equal(m.isSameOrBefore(m, 'year'), true, 'same moments are in the same year');\n    assert.equal(+m, +mCopy, 'isSameOrBefore year should not change moment');\n});\n\ntest('is same or before month', function (assert) {\n    var m = moment(new Date(2011, 2, 3, 4, 5, 6, 7)), mCopy = moment(m);\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 2, 6, 7, 8, 9, 10)), 'month'), true, 'month match');\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 2, 6, 7, 8, 9, 10)), 'months'), true, 'plural should work');\n    assert.equal(m.isSameOrBefore(moment(new Date(2012, 2, 6, 7, 8, 9, 10)), 'month'), true, 'year is later');\n    assert.equal(m.isSameOrBefore(moment(new Date(2010, 2, 6, 7, 8, 9, 10)), 'month'), false, 'year is earlier');\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 5, 6, 7, 8, 9, 10)), 'month'), true, 'month is later');\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 1, 6, 7, 8, 9, 10)), 'month'), false, 'month is earlier');\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 2, 1, 0, 0, 0, 0)), 'month'), true, 'exact start of month');\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 2, 31, 23, 59, 59, 999)), 'month'), true, 'exact end of month');\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 3, 1, 0, 0, 0, 0)), 'month'), true, 'start of next month');\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 1, 27, 23, 59, 59, 999)), 'month'), false, 'end of previous month');\n    assert.equal(m.isSameOrBefore(m, 'month'), true, 'same moments are in the same month');\n    assert.equal(+m, +mCopy, 'isSameOrBefore month should not change moment');\n});\n\ntest('is same or before day', function (assert) {\n    var m = moment(new Date(2011, 1, 2, 3, 4, 5, 6)), mCopy = moment(m);\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 1, 2, 7, 8, 9, 10)), 'day'), true, 'day match');\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 1, 2, 7, 8, 9, 10)), 'days'), true, 'plural should work');\n    assert.equal(m.isSameOrBefore(moment(new Date(2012, 1, 2, 7, 8, 9, 10)), 'day'), true, 'year is later');\n    assert.equal(m.isSameOrBefore(moment(new Date(2010, 1, 2, 7, 8, 9, 10)), 'day'), false, 'year is earlier');\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 2, 2, 7, 8, 9, 10)), 'day'), true, 'month is later');\n    assert.equal(m.isSameOrBefore(moment(new Date(2010, 12, 2, 7, 8, 9, 10)), 'day'), false, 'month is earlier');\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 1, 3, 7, 8, 9, 10)), 'day'), true, 'day is later');\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 1, 1, 7, 8, 9, 10)), 'day'), false, 'day is earlier');\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 1, 2, 0, 0, 0, 0)), 'day'), true, 'exact start of day');\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 1, 2, 23, 59, 59, 999)), 'day'), true, 'exact end of day');\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 1, 3, 0, 0, 0, 0)), 'day'), true, 'start of next day');\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 1, 1, 23, 59, 59, 999)), 'day'), false, 'end of previous day');\n    assert.equal(m.isSameOrBefore(m, 'day'), true, 'same moments are in the same day');\n    assert.equal(+m, +mCopy, 'isSameOrBefore day should not change moment');\n});\n\ntest('is same or before hour', function (assert) {\n    var m = moment(new Date(2011, 1, 2, 3, 4, 5, 6)), mCopy = moment(m);\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 1, 2, 3, 8, 9, 10)), 'hour'), true, 'hour match');\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 1, 2, 3, 8, 9, 10)), 'hours'), true, 'plural should work');\n    assert.equal(m.isSameOrBefore(moment(new Date(2012, 1, 2, 3, 8, 9, 10)), 'hour'), true, 'year is later');\n    assert.equal(m.isSameOrBefore(moment(new Date(2010, 1, 2, 3, 8, 9, 10)), 'hour'), false, 'year is earlier');\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 2, 2, 3, 8, 9, 10)), 'hour'), true, 'month is later');\n    assert.equal(m.isSameOrBefore(moment(new Date(2010, 12, 2, 3, 8, 9, 10)), 'hour'), false, 'month is earlier');\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 1, 3, 3, 8, 9, 10)), 'hour'), true, 'day is later');\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 1, 1, 3, 8, 9, 10)), 'hour'), false, 'day is earlier');\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 1, 2, 4, 8, 9, 10)), 'hour'), true, 'hour is later');\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 1, 2, 2, 8, 9, 10)), 'hour'), false, 'hour is earlier');\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 1, 2, 3, 0, 0, 0)), 'hour'), true, 'exact start of hour');\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 1, 2, 3, 59, 59, 999)), 'hour'), true, 'exact end of hour');\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 1, 2, 4, 0, 0, 0)), 'hour'), true, 'start of next hour');\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 1, 2, 2, 59, 59, 999)), 'hour'), false, 'end of previous hour');\n    assert.equal(m.isSameOrBefore(m, 'hour'), true, 'same moments are in the same hour');\n    assert.equal(+m, +mCopy, 'isSameOrBefore hour should not change moment');\n});\n\ntest('is same or before minute', function (assert) {\n    var m = moment(new Date(2011, 1, 2, 3, 4, 5, 6)), mCopy = moment(m);\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 1, 2, 3, 4, 9, 10)), 'minute'), true, 'minute match');\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 1, 2, 3, 4, 9, 10)), 'minutes'), true, 'plural should work');\n    assert.equal(m.isSameOrBefore(moment(new Date(2012, 1, 2, 3, 4, 9, 10)), 'minute'), true, 'year is later');\n    assert.equal(m.isSameOrBefore(moment(new Date(2010, 1, 2, 3, 4, 9, 10)), 'minute'), false, 'year is earlier');\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 2, 2, 3, 4, 9, 10)), 'minute'), true, 'month is later');\n    assert.equal(m.isSameOrBefore(moment(new Date(2010, 12, 2, 3, 4, 9, 10)), 'minute'), false, 'month is earlier');\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 1, 3, 3, 4, 9, 10)), 'minute'), true, 'day is later');\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 1, 1, 3, 4, 9, 10)), 'minute'), false, 'day is earlier');\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 1, 2, 4, 4, 9, 10)), 'minute'), true, 'hour is later');\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 1, 2, 2, 4, 9, 10)), 'minute'), false, 'hour is earlier');\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 1, 2, 3, 5, 9, 10)), 'minute'), true, 'minute is later');\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 1, 2, 3, 3, 9, 10)), 'minute'), false, 'minute is earlier');\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 1, 2, 3, 4, 0, 0)), 'minute'), true, 'exact start of minute');\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 1, 2, 3, 4, 59, 999)), 'minute'), true, 'exact end of minute');\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 1, 2, 3, 5, 0, 0)), 'minute'), true, 'start of next minute');\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 1, 2, 3, 3, 59, 999)), 'minute'), false, 'end of previous minute');\n    assert.equal(m.isSameOrBefore(m, 'minute'), true, 'same moments are in the same minute');\n    assert.equal(+m, +mCopy, 'isSameOrBefore minute should not change moment');\n});\n\ntest('is same or before second', function (assert) {\n    var m = moment(new Date(2011, 1, 2, 3, 4, 5, 6)), mCopy = moment(m);\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 1, 2, 3, 4, 5, 10)), 'second'), true, 'second match');\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 1, 2, 3, 4, 5, 10)), 'seconds'), true, 'plural should work');\n    assert.equal(m.isSameOrBefore(moment(new Date(2012, 1, 2, 3, 4, 5, 10)), 'second'), true, 'year is later');\n    assert.equal(m.isSameOrBefore(moment(new Date(2010, 1, 2, 3, 4, 5, 10)), 'second'), false, 'year is earlier');\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 2, 2, 3, 4, 5, 10)), 'second'), true, 'month is later');\n    assert.equal(m.isSameOrBefore(moment(new Date(2010, 12, 2, 3, 4, 5, 10)), 'second'), false, 'month is earlier');\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 1, 3, 3, 4, 5, 10)), 'second'), true, 'day is later');\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 1, 1, 3, 4, 5, 10)), 'second'), false, 'day is earlier');\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 1, 2, 4, 4, 5, 10)), 'second'), true, 'hour is later');\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 1, 2, 2, 4, 5, 10)), 'second'), false, 'hour is earlier');\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 1, 2, 3, 5, 5, 10)), 'second'), true, 'minute is later');\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 1, 2, 3, 3, 5, 10)), 'second'), false, 'minute is earlier');\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 1, 2, 3, 4, 6, 10)), 'second'), true, 'second is later');\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 1, 2, 3, 4, 4, 10)), 'second'), false, 'second is earlier');\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 1, 2, 3, 4, 5, 0)), 'second'), true, 'exact start of second');\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 1, 2, 3, 4, 5, 999)), 'second'), true, 'exact end of second');\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 1, 2, 3, 4, 6, 0)), 'second'), true, 'start of next second');\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 1, 2, 3, 4, 4, 999)), 'second'), false, 'end of previous second');\n    assert.equal(m.isSameOrBefore(m, 'second'), true, 'same moments are in the same second');\n    assert.equal(+m, +mCopy, 'isSameOrBefore second should not change moment');\n});\n\ntest('is same or before millisecond', function (assert) {\n    var m = moment(new Date(2011, 3, 2, 3, 4, 5, 10)), mCopy = moment(m);\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 3, 2, 3, 4, 5, 10)), 'millisecond'), true, 'millisecond match');\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 3, 2, 3, 4, 5, 10)), 'milliseconds'), true, 'plural should work');\n    assert.equal(m.isSameOrBefore(moment(new Date(2012, 3, 2, 3, 4, 5, 10)), 'millisecond'), true, 'year is later');\n    assert.equal(m.isSameOrBefore(moment(new Date(2010, 3, 2, 3, 4, 5, 10)), 'millisecond'), false, 'year is earlier');\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 4, 2, 3, 4, 5, 10)), 'millisecond'), true, 'month is later');\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 2, 2, 3, 4, 5, 10)), 'millisecond'), false, 'month is earlier');\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 3, 3, 3, 4, 5, 10)), 'millisecond'), true, 'day is later');\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 3, 1, 1, 4, 5, 10)), 'millisecond'), false, 'day is earlier');\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 3, 2, 4, 4, 5, 10)), 'millisecond'), true, 'hour is later');\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 3, 1, 4, 1, 5, 10)), 'millisecond'), false, 'hour is earlier');\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 3, 2, 3, 5, 5, 10)), 'millisecond'), true, 'minute is later');\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 3, 2, 3, 3, 5, 10)), 'millisecond'), false, 'minute is earlier');\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 3, 2, 3, 4, 6, 10)), 'millisecond'), true, 'second is later');\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 3, 2, 3, 4, 4, 5)), 'millisecond'), false, 'second is earlier');\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 3, 2, 3, 4, 6, 11)), 'millisecond'), true, 'millisecond is later');\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 3, 2, 3, 4, 4, 9)), 'millisecond'), false, 'millisecond is earlier');\n    assert.equal(m.isSameOrBefore(m, 'millisecond'), true, 'same moments are in the same millisecond');\n    assert.equal(+m, +mCopy, 'isSameOrBefore millisecond should not change moment');\n});\n\ntest('is same with utc offset moments', function (assert) {\n    assert.ok(moment.parseZone('2013-02-01T00:00:00-05:00').isSameOrBefore(moment('2013-02-01'), 'year'), 'zoned vs local moment');\n    assert.ok(moment('2013-02-01').isSameOrBefore(moment('2013-02-01').utcOffset('-05:00'), 'year'), 'local vs zoned moment');\n    assert.ok(\n      moment.parseZone('2013-02-01T00:00:00-05:00').isSameOrBefore(moment.parseZone('2013-02-01T00:00:00-06:30'), 'year'),\n      'zoned vs (differently) zoned moment'\n    );\n});\n\ntest('is same with invalid moments', function (assert) {\n    var m = moment(), invalid = moment.invalid();\n    assert.equal(invalid.isSameOrBefore(invalid), false, 'invalid moments are not considered equal');\n    assert.equal(m.isSameOrBefore(invalid), false, 'valid moment is not before invalid moment');\n    assert.equal(invalid.isSameOrBefore(m), false, 'invalid moment is not before valid moment');\n    assert.equal(m.isSameOrBefore(invalid, 'year'), false, 'invalid moment year');\n    assert.equal(m.isSameOrBefore(invalid, 'month'), false, 'invalid moment month');\n    assert.equal(m.isSameOrBefore(invalid, 'day'), false, 'invalid moment day');\n    assert.equal(m.isSameOrBefore(invalid, 'hour'), false, 'invalid moment hour');\n    assert.equal(m.isSameOrBefore(invalid, 'minute'), false, 'invalid moment minute');\n    assert.equal(m.isSameOrBefore(invalid, 'second'), false, 'invalid moment second');\n    assert.equal(m.isSameOrBefore(invalid, 'milliseconds'), false, 'invalid moment milliseconds');\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\nfunction module$1 (name, lifecycle) {\n    QUnit.module(name, {\n        setup : function () {\n            moment.locale('en');\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'core');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            teardownDeprecationHandler(test, moment, 'core');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n}\n\nmodule$1('is valid');\n\ntest('array bad month', function (assert) {\n    assert.equal(moment([2010, -1]).isValid(), false, 'month -1 invalid');\n    assert.equal(moment([2100, 12]).isValid(), false, 'month 12 invalid');\n});\n\ntest('array good month', function (assert) {\n    for (var i = 0; i < 12; i++) {\n        assert.equal(moment([2010, i]).isValid(), true, 'month ' + i);\n        assert.equal(moment.utc([2010, i]).isValid(), true, 'month ' + i);\n    }\n});\n\ntest('array bad date', function (assert) {\n    var tests = [\n        moment([2010, 0, 0]),\n        moment([2100, 0, 32]),\n        moment.utc([2010, 0, 0]),\n        moment.utc([2100, 0, 32])\n    ],\n    i, m;\n\n    for (i in tests) {\n        m = tests[i];\n        assert.equal(m.isValid(), false);\n    }\n});\n\ntest('h/hh with hour > 12', function (assert) {\n    assert.ok(moment('06/20/2014 11:51 PM', 'MM/DD/YYYY hh:mm A', true).isValid(), '11 for hh');\n    assert.ok(moment('06/20/2014 11:51 AM', 'MM/DD/YYYY hh:mm A', true).isValid(), '11 for hh');\n    assert.ok(moment('06/20/2014 23:51 PM', 'MM/DD/YYYY hh:mm A').isValid(), 'non-strict validity 23 for hh');\n    assert.ok(moment('06/20/2014 23:51 PM', 'MM/DD/YYYY hh:mm A').parsingFlags().bigHour, 'non-strict bigHour 23 for hh');\n    assert.ok(!moment('06/20/2014 23:51 PM', 'MM/DD/YYYY hh:mm A', true).isValid(), 'validity 23 for hh');\n    assert.ok(moment('06/20/2014 23:51 PM', 'MM/DD/YYYY hh:mm A', true).parsingFlags().bigHour, 'bigHour 23 for hh');\n});\n\ntest('array bad date leap year', function (assert) {\n    assert.equal(moment([2010, 1, 29]).isValid(), false, '2010 feb 29');\n    assert.equal(moment([2100, 1, 29]).isValid(), false, '2100 feb 29');\n    assert.equal(moment([2008, 1, 30]).isValid(), false, '2008 feb 30');\n    assert.equal(moment([2000, 1, 30]).isValid(), false, '2000 feb 30');\n\n    assert.equal(moment.utc([2010, 1, 29]).isValid(), false, 'utc 2010 feb 29');\n    assert.equal(moment.utc([2100, 1, 29]).isValid(), false, 'utc 2100 feb 29');\n    assert.equal(moment.utc([2008, 1, 30]).isValid(), false, 'utc 2008 feb 30');\n    assert.equal(moment.utc([2000, 1, 30]).isValid(), false, 'utc 2000 feb 30');\n});\n\ntest('string + formats bad date', function (assert) {\n    assert.equal(moment('2020-00-00', []).isValid(), false, 'invalid on empty array');\n    assert.equal(moment('2020-00-00', ['YYYY-MM-DD', 'DD-MM-YYYY']).isValid(), false, 'invalid on all in array');\n    assert.equal(moment('2020-00-00', ['DD-MM-YYYY', 'YYYY-MM-DD']).isValid(), false, 'invalid on all in array');\n    assert.equal(moment('2020-01-01', ['YYYY-MM-DD', 'DD-MM-YYYY']).isValid(), true, 'valid on first');\n    assert.equal(moment('2020-01-01', ['DD-MM-YYYY', 'YYYY-MM-DD']).isValid(), true, 'valid on last');\n    assert.equal(moment('2020-01-01', ['YYYY-MM-DD', 'YYYY-DD-MM']).isValid(), true, 'valid on both');\n    assert.equal(moment('2020-13-01', ['YYYY-MM-DD', 'YYYY-DD-MM']).isValid(), true, 'valid on last');\n\n    assert.equal(moment('12-13-2012', ['DD-MM-YYYY', 'YYYY-MM-DD']).isValid(), false, 'month rollover');\n    assert.equal(moment('12-13-2012', ['DD-MM-YYYY', 'DD-MM-YYYY']).isValid(), false, 'month rollover');\n    assert.equal(moment('38-12-2012', ['DD-MM-YYYY']).isValid(), false, 'day rollover');\n});\n\ntest('string nonsensical with format', function (assert) {\n    assert.equal(moment('fail', 'MM-DD-YYYY').isValid(), false, 'string \\'fail\\' with format \\'MM-DD-YYYY\\'');\n    assert.equal(moment('xx-xx-2001', 'DD-MM-YYY').isValid(), true, 'string \\'xx-xx-2001\\' with format \\'MM-DD-YYYY\\'');\n});\n\ntest('string with bad month name', function (assert) {\n    assert.equal(moment('01-Nam-2012', 'DD-MMM-YYYY').isValid(), false, '\\'Nam\\' is an invalid month');\n    assert.equal(moment('01-Aug-2012', 'DD-MMM-YYYY').isValid(), true, '\\'Aug\\' is a valid month');\n});\n\ntest('string with spaceless format', function (assert) {\n    assert.equal(moment('10Sep2001', 'DDMMMYYYY').isValid(), true, 'Parsing 10Sep2001 should result in a valid date');\n});\n\ntest('invalid string iso 8601', function (assert) {\n    var tests = [\n        '2010-00-00',\n        '2010-01-00',\n        '2010-01-40',\n        '2010-01-01T24:01',  // 24:00:00 is actually valid\n        '2010-01-01T23:60',\n        '2010-01-01T23:59:60'\n    ], i;\n\n    for (i = 0; i < tests.length; i++) {\n        assert.equal(moment(tests[i], moment.ISO_8601).isValid(), false, tests[i] + ' should be invalid');\n        assert.equal(moment.utc(tests[i], moment.ISO_8601).isValid(), false, tests[i] + ' should be invalid');\n    }\n});\n\ntest('invalid string iso 8601 + timezone', function (assert) {\n    var tests = [\n        '2010-00-00T+00:00',\n        '2010-01-00T+00:00',\n        '2010-01-40T+00:00',\n        '2010-01-40T24:01+00:00',\n        '2010-01-40T23:60+00:00',\n        '2010-01-40T23:59:60+00:00',\n        '2010-01-40T23:59:59.9999+00:00',\n        '2010-01-40T23:59:59,9999+00:00'\n    ], i;\n\n    for (i = 0; i < tests.length; i++) {\n        assert.equal(moment(tests[i], moment.ISO_8601).isValid(), false, tests[i] + ' should be invalid');\n        assert.equal(moment.utc(tests[i], moment.ISO_8601).isValid(), false, tests[i] + ' should be invalid');\n    }\n});\n\ntest('valid string iso 8601 - not strict', function (assert) {\n    var tests = [\n        '2010-01-30 00:00:00,000Z',\n        '20100101',\n        '20100130',\n        '20100130T23+00:00',\n        '20100130T2359+0000',\n        '20100130T235959+0000',\n        '20100130T235959,999+0000',\n        '20100130T235959,999-0700',\n        '20100130T000000,000+0700',\n        '20100130 000000,000Z'\n    ];\n\n    for (var i = 0; i < tests.length; i++) {\n        assert.equal(moment(tests[i]).isValid(), true, tests[i] + ' should be valid in normal');\n        assert.equal(moment.utc(tests[i]).isValid(), true, tests[i] + ' should be valid in normal');\n    }\n});\n\ntest('valid string iso 8601 + timezone', function (assert) {\n    var tests = [\n        '2010-01-01',\n        '2010-01-30',\n        '2010-01-30T23+00:00',\n        '2010-01-30T23:59+00:00',\n        '2010-01-30T23:59:59+00:00',\n        '2010-01-30T23:59:59.999+00:00',\n        '2010-01-30T23:59:59.999-07:00',\n        '2010-01-30T00:00:00.000+07:00',\n        '2010-01-30T23:59:59.999-07',\n        '2010-01-30T00:00:00.000+07',\n        '2010-01-30 00:00:00.000Z'\n    ], i;\n\n    for (i = 0; i < tests.length; i++) {\n        assert.equal(moment(tests[i]).isValid(), true, tests[i] + ' should be valid in normal');\n        assert.equal(moment.utc(tests[i]).isValid(), true, tests[i] + ' should be valid in normal');\n        assert.equal(moment(tests[i], moment.ISO_8601, true).isValid(), true, tests[i] + ' should be valid in strict');\n        assert.equal(moment.utc(tests[i], moment.ISO_8601, true).isValid(), true, tests[i] + ' should be valid in strict');\n    }\n});\n\ntest('invalidAt', function (assert) {\n    assert.equal(moment([2000, 12]).invalidAt(), 1, 'month 12 is invalid: 0-11');\n    assert.equal(moment([2000, 1, 30]).invalidAt(), 2, '30 is not a valid february day');\n    assert.equal(moment([2000, 1, 29, 25]).invalidAt(), 3, '25 is invalid hour');\n    assert.equal(moment([2000, 1, 29, 24,  1]).invalidAt(), 3, '24:01 is invalid hour');\n    assert.equal(moment([2000, 1, 29, 23, 60]).invalidAt(), 4, '60 is invalid minute');\n    assert.equal(moment([2000, 1, 29, 23, 59, 60]).invalidAt(), 5, '60 is invalid second');\n    assert.equal(moment([2000, 1, 29, 23, 59, 59, 1000]).invalidAt(), 6, '1000 is invalid millisecond');\n    assert.equal(moment([2000, 1, 29, 23, 59, 59, 999]).invalidAt(), -1, '-1 if everything is fine');\n});\n\ntest('valid Unix timestamp', function (assert) {\n    assert.equal(moment(1371065286, 'X').isValid(), true, 'number integer');\n    assert.equal(moment(1379066897.0, 'X').isValid(), true, 'number whole 1dp');\n    assert.equal(moment(1379066897.7, 'X').isValid(), true, 'number 1dp');\n    assert.equal(moment(1379066897.00, 'X').isValid(), true, 'number whole 2dp');\n    assert.equal(moment(1379066897.07, 'X').isValid(), true, 'number 2dp');\n    assert.equal(moment(1379066897.17, 'X').isValid(), true, 'number 2dp');\n    assert.equal(moment(1379066897.000, 'X').isValid(), true, 'number whole 3dp');\n    assert.equal(moment(1379066897.007, 'X').isValid(), true, 'number 3dp');\n    assert.equal(moment(1379066897.017, 'X').isValid(), true, 'number 3dp');\n    assert.equal(moment(1379066897.157, 'X').isValid(), true, 'number 3dp');\n    assert.equal(moment('1371065286', 'X').isValid(), true, 'string integer');\n    assert.equal(moment('1379066897.', 'X').isValid(), true, 'string trailing .');\n    assert.equal(moment('1379066897.0', 'X').isValid(), true, 'string whole 1dp');\n    assert.equal(moment('1379066897.7', 'X').isValid(), true, 'string 1dp');\n    assert.equal(moment('1379066897.00', 'X').isValid(), true, 'string whole 2dp');\n    assert.equal(moment('1379066897.07', 'X').isValid(), true, 'string 2dp');\n    assert.equal(moment('1379066897.17', 'X').isValid(), true, 'string 2dp');\n    assert.equal(moment('1379066897.000', 'X').isValid(), true, 'string whole 3dp');\n    assert.equal(moment('1379066897.007', 'X').isValid(), true, 'string 3dp');\n    assert.equal(moment('1379066897.017', 'X').isValid(), true, 'string 3dp');\n    assert.equal(moment('1379066897.157', 'X').isValid(), true, 'string 3dp');\n});\n\ntest('invalid Unix timestamp', function (assert) {\n    assert.equal(moment(undefined, 'X').isValid(), false, 'undefined');\n    assert.equal(moment('undefined', 'X').isValid(), false, 'string undefined');\n    try {\n        assert.equal(moment(null, 'X').isValid(), false, 'null');\n    } catch (e) {\n        assert.ok(true, 'null');\n    }\n\n    assert.equal(moment('null', 'X').isValid(), false, 'string null');\n    assert.equal(moment([], 'X').isValid(), false, 'array');\n    assert.equal(moment('{}', 'X').isValid(), false, 'object');\n    try {\n        assert.equal(moment('', 'X').isValid(), false, 'string empty');\n    } catch (e) {\n        assert.ok(true, 'string empty');\n    }\n\n    assert.equal(moment(' ', 'X').isValid(), false, 'string space');\n});\n\ntest('valid Unix offset milliseconds', function (assert) {\n    assert.equal(moment(1234567890123, 'x').isValid(), true, 'number integer');\n    assert.equal(moment('1234567890123', 'x').isValid(), true, 'string integer');\n});\n\ntest('invalid Unix offset milliseconds', function (assert) {\n    assert.equal(moment(undefined, 'x').isValid(), false, 'undefined');\n    assert.equal(moment('undefined', 'x').isValid(), false, 'string undefined');\n    try {\n        assert.equal(moment(null, 'x').isValid(), false, 'null');\n    } catch (e) {\n        assert.ok(true, 'null');\n    }\n\n    assert.equal(moment('null', 'x').isValid(), false, 'string null');\n    assert.equal(moment([], 'x').isValid(), false, 'array');\n    assert.equal(moment('{}', 'x').isValid(), false, 'object');\n    try {\n        assert.equal(moment('', 'x').isValid(), false, 'string empty');\n    } catch (e) {\n        assert.ok(true, 'string empty');\n    }\n\n    assert.equal(moment(' ', 'x').isValid(), false, 'string space');\n});\n\ntest('empty', function (assert) {\n    assert.equal(moment(null).isValid(), false, 'null');\n    assert.equal(moment('').isValid(), false, 'empty string');\n    assert.equal(moment(null, 'YYYY').isValid(), false, 'format + null');\n    assert.equal(moment('', 'YYYY').isValid(), false, 'format + empty string');\n    assert.equal(moment(' ', 'YYYY').isValid(), false, 'format + empty when trimmed');\n});\n\ntest('days of the year', function (assert) {\n    assert.equal(moment('2010 300', 'YYYY DDDD').isValid(), true, 'day 300 of year valid');\n    assert.equal(moment('2010 365', 'YYYY DDDD').isValid(), true, 'day 365 of year valid');\n    assert.equal(moment('2010 366', 'YYYY DDDD').isValid(), false, 'day 366 of year invalid');\n    assert.equal(moment('2012 365', 'YYYY DDDD').isValid(), true, 'day 365 of leap year valid');\n    assert.equal(moment('2012 366', 'YYYY DDDD').isValid(), true, 'day 366 of leap year valid');\n    assert.equal(moment('2012 367', 'YYYY DDDD').isValid(), false, 'day 367 of leap year invalid');\n});\n\ntest('24:00:00.000 is valid', function (assert) {\n    assert.equal(moment('2014-01-01 24', 'YYYY-MM-DD HH').isValid(), true, '24 is valid');\n    assert.equal(moment('2014-01-01 24:00', 'YYYY-MM-DD HH:mm').isValid(), true, '24:00 is valid');\n    assert.equal(moment('2014-01-01 24:01', 'YYYY-MM-DD HH:mm').isValid(), false, '24:01 is not valid');\n});\n\ntest('oddball permissiveness', function (assert) {\n    // https://github.com/moment/moment/issues/1128\n    assert.ok(moment('2010-10-3199', ['MM/DD/YYYY', 'MM-DD-YYYY', 'YYYY-MM-DD']).isValid());\n\n    // https://github.com/moment/moment/issues/1122\n    assert.ok(moment('3:25', ['h:mma', 'hh:mma', 'H:mm', 'HH:mm']).isValid());\n});\n\ntest('0 hour is invalid in strict', function (assert) {\n    assert.equal(moment('00:01', 'hh:mm', true).isValid(), false, '00 hour is invalid in strict');\n    assert.equal(moment('00:01', 'hh:mm').isValid(), true, '00 hour is valid in normal');\n    assert.equal(moment('0:01', 'h:mm', true).isValid(), false, '0 hour is invalid in strict');\n    assert.equal(moment('0:01', 'h:mm').isValid(), true, '0 hour is valid in normal');\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\nfunction module$1 (name, lifecycle) {\n    QUnit.module(name, {\n        setup : function () {\n            moment.locale('en');\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'core');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            teardownDeprecationHandler(test, moment, 'core');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n}\n\nmodule$1('leap year');\n\ntest('leap year', function (assert) {\n    assert.equal(moment([2010, 0, 1]).isLeapYear(), false, '2010');\n    assert.equal(moment([2100, 0, 1]).isLeapYear(), false, '2100');\n    assert.equal(moment([2008, 0, 1]).isLeapYear(), true, '2008');\n    assert.equal(moment([2000, 0, 1]).isLeapYear(), true, '2000');\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\nfunction module$1 (name, lifecycle) {\n    QUnit.module(name, {\n        setup : function () {\n            moment.locale('en');\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'core');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            teardownDeprecationHandler(test, moment, 'core');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n}\n\nmodule$1('listers');\n\ntest('default', function (assert) {\n    assert.deepEqual(moment.months(), ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December']);\n    assert.deepEqual(moment.monthsShort(), ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']);\n    assert.deepEqual(moment.weekdays(), ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday']);\n    assert.deepEqual(moment.weekdaysShort(), ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat']);\n    assert.deepEqual(moment.weekdaysMin(), ['Su', 'Mo', 'Tu', 'We', 'Th', 'Fr', 'Sa']);\n});\n\ntest('index', function (assert) {\n    assert.equal(moment.months(0), 'January');\n    assert.equal(moment.months(2), 'March');\n    assert.equal(moment.monthsShort(0), 'Jan');\n    assert.equal(moment.monthsShort(2), 'Mar');\n    assert.equal(moment.weekdays(0), 'Sunday');\n    assert.equal(moment.weekdays(2), 'Tuesday');\n    assert.equal(moment.weekdaysShort(0), 'Sun');\n    assert.equal(moment.weekdaysShort(2), 'Tue');\n    assert.equal(moment.weekdaysMin(0), 'Su');\n    assert.equal(moment.weekdaysMin(2), 'Tu');\n});\n\ntest('localized', function (assert) {\n    var months = 'one_two_three_four_five_six_seven_eight_nine_ten_eleven_twelve'.split('_'),\n        monthsShort = 'on_tw_th_fo_fi_si_se_ei_ni_te_el_tw'.split('_'),\n        weekdays = 'one_two_three_four_five_six_seven'.split('_'),\n        weekdaysShort = 'on_tw_th_fo_fi_si_se'.split('_'),\n        weekdaysMin = '1_2_3_4_5_6_7'.split('_'),\n        weekdaysLocale = 'four_five_six_seven_one_two_three'.split('_'),\n        weekdaysShortLocale = 'fo_fi_si_se_on_tw_th'.split('_'),\n        weekdaysMinLocale = '4_5_6_7_1_2_3'.split('_'),\n        week = {\n            dow : 3,\n            doy : 6\n        };\n\n    moment.locale('numerologists', {\n        months : months,\n        monthsShort : monthsShort,\n        weekdays : weekdays,\n        weekdaysShort: weekdaysShort,\n        weekdaysMin: weekdaysMin,\n        week : week\n    });\n\n    assert.deepEqual(moment.months(), months);\n    assert.deepEqual(moment.monthsShort(), monthsShort);\n    assert.deepEqual(moment.weekdays(), weekdays);\n    assert.deepEqual(moment.weekdaysShort(), weekdaysShort);\n    assert.deepEqual(moment.weekdaysMin(), weekdaysMin);\n\n    assert.equal(moment.months(0), 'one');\n    assert.equal(moment.monthsShort(0), 'on');\n    assert.equal(moment.weekdays(0), 'one');\n    assert.equal(moment.weekdaysShort(0), 'on');\n    assert.equal(moment.weekdaysMin(0), '1');\n\n    assert.equal(moment.months(2), 'three');\n    assert.equal(moment.monthsShort(2), 'th');\n    assert.equal(moment.weekdays(2), 'three');\n    assert.equal(moment.weekdaysShort(2), 'th');\n    assert.equal(moment.weekdaysMin(2), '3');\n\n    assert.deepEqual(moment.weekdays(true), weekdaysLocale);\n    assert.deepEqual(moment.weekdaysShort(true), weekdaysShortLocale);\n    assert.deepEqual(moment.weekdaysMin(true), weekdaysMinLocale);\n\n    assert.equal(moment.weekdays(true, 0), 'four');\n    assert.equal(moment.weekdaysShort(true, 0), 'fo');\n    assert.equal(moment.weekdaysMin(true, 0), '4');\n\n    assert.equal(moment.weekdays(false, 2), 'three');\n    assert.equal(moment.weekdaysShort(false, 2), 'th');\n    assert.equal(moment.weekdaysMin(false, 2), '3');\n});\n\ntest('with functions', function (assert) {\n    var monthsShort = 'one_two_three_four_five_six_seven_eight_nine_ten_eleven_twelve'.split('_'),\n        monthsShortWeird = 'onesy_twosy_threesy_foursy_fivesy_sixsy_sevensy_eightsy_ninesy_tensy_elevensy_twelvesy'.split('_');\n\n    moment.locale('difficult', {\n\n        monthsShort: function (m, format) {\n            var arr = format.match(/-MMM-/) ? monthsShortWeird : monthsShort;\n            return arr[m.month()];\n        }\n    });\n\n    assert.deepEqual(moment.monthsShort(), monthsShort);\n    assert.deepEqual(moment.monthsShort('MMM'), monthsShort);\n    assert.deepEqual(moment.monthsShort('-MMM-'), monthsShortWeird);\n\n    assert.deepEqual(moment.monthsShort('MMM', 2), 'three');\n    assert.deepEqual(moment.monthsShort('-MMM-', 2), 'threesy');\n    assert.deepEqual(moment.monthsShort(2), 'three');\n});\n\ntest('with locale data', function (assert) {\n    var months = 'one_two_three_four_five_six_seven_eight_nine_ten_eleven_twelve'.split('_'),\n        monthsShort = 'on_tw_th_fo_fi_si_se_ei_ni_te_el_tw'.split('_'),\n        weekdays = 'one_two_three_four_five_six_seven'.split('_'),\n        weekdaysShort = 'on_tw_th_fo_fi_si_se'.split('_'),\n        weekdaysMin = '1_2_3_4_5_6_7'.split('_'),\n        weekdaysLocale = 'four_five_six_seven_one_two_three'.split('_'),\n        weekdaysShortLocale = 'fo_fi_si_se_on_tw_th'.split('_'),\n        weekdaysMinLocale = '4_5_6_7_1_2_3'.split('_'),\n        week = {\n            dow : 3,\n            doy : 6\n        };\n\n    var customLocale = moment.localeData('numerologists');\n\n    assert.deepEqual(customLocale.months(), months);\n    assert.deepEqual(customLocale.monthsShort(), monthsShort);\n    assert.deepEqual(customLocale.weekdays(), weekdays);\n    assert.deepEqual(customLocale.weekdaysShort(), weekdaysShort);\n    assert.deepEqual(customLocale.weekdaysMin(), weekdaysMin);\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\nfunction module$1 (name, lifecycle) {\n    QUnit.module(name, {\n        setup : function () {\n            moment.locale('en');\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'core');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            teardownDeprecationHandler(test, moment, 'core');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n}\n\nvar indexOf;\n\nif (Array.prototype.indexOf) {\n    indexOf = Array.prototype.indexOf;\n} else {\n    indexOf = function (o) {\n        // I know\n        var i;\n        for (i = 0; i < this.length; ++i) {\n            if (this[i] === o) {\n                return i;\n            }\n        }\n        return -1;\n    };\n}\n\nvar indexOf$1 = indexOf;\n\nmodule$1('locale', {\n    setup : function () {\n        // TODO: Remove once locales are switched to ES6\n        each([{\n            name: 'en-gb',\n            data: {}\n        }, {\n            name: 'en-ca',\n            data: {}\n        }, {\n            name: 'es',\n            data: {\n                relativeTime: {past: 'hace %s', s: 'unos segundos', d: 'un día'},\n                months: 'enero_febrero_marzo_abril_mayo_junio_julio_agosto_septiembre_octubre_noviembre_diciembre'.split('_')\n            }\n        }, {\n            name: 'fr',\n            data: {}\n        }, {\n            name: 'fr-ca',\n            data: {}\n        }, {\n            name: 'it',\n            data: {}\n        }, {\n            name: 'zh-cn',\n            data: {\n                months: '一月_二月_三月_四月_五月_六月_七月_八月_九月_十月_十一月_十二月'.split('_')\n            }\n        }], function (locale) {\n            if (moment.locale(locale.name) !== locale.name) {\n                moment.defineLocale(locale.name, locale.data);\n            }\n        });\n        moment.locale('en');\n    }\n});\n\ntest('library getters and setters', function (assert) {\n    var r = moment.locale('en');\n\n    assert.equal(r, 'en', 'locale should return en by default');\n    assert.equal(moment.locale(), 'en', 'locale should return en by default');\n\n    moment.locale('fr');\n    assert.equal(moment.locale(), 'fr', 'locale should return the changed locale');\n\n    moment.locale('en-gb');\n    assert.equal(moment.locale(), 'en-gb', 'locale should return the changed locale');\n\n    moment.locale('en');\n    assert.equal(moment.locale(), 'en', 'locale should reset');\n\n    moment.locale('does-not-exist');\n    assert.equal(moment.locale(), 'en', 'locale should reset');\n\n    moment.locale('EN');\n    assert.equal(moment.locale(), 'en', 'Normalize locale key case');\n\n    moment.locale('EN_gb');\n    assert.equal(moment.locale(), 'en-gb', 'Normalize locale key underscore');\n});\n\ntest('library setter array of locales', function (assert) {\n    assert.equal(moment.locale(['non-existent', 'fr', 'also-non-existent']), 'fr', 'passing an array uses the first valid locale');\n    assert.equal(moment.locale(['es', 'fr', 'also-non-existent']), 'es', 'passing an array uses the first valid locale');\n});\n\ntest('library setter locale substrings', function (assert) {\n    assert.equal(moment.locale('fr-crap'), 'fr', 'use substrings');\n    assert.equal(moment.locale('fr-does-not-exist'), 'fr', 'uses deep substrings');\n    assert.equal(moment.locale('fr-CA-does-not-exist'), 'fr-ca', 'uses deepest substring');\n});\n\ntest('library getter locale array and substrings', function (assert) {\n    assert.equal(moment.locale(['en-CH', 'fr']), 'en', 'prefer root locale to shallower ones');\n    assert.equal(moment.locale(['en-gb-leeds', 'en-CA']), 'en-gb', 'prefer root locale to shallower ones');\n    assert.equal(moment.locale(['en-fake', 'en-CA']), 'en-ca', 'prefer alternatives with shared roots');\n    assert.equal(moment.locale(['en-fake', 'en-fake2', 'en-ca']), 'en-ca', 'prefer alternatives with shared roots');\n    assert.equal(moment.locale(['fake-CA', 'fake-MX', 'fr']), 'fr', 'always find something if possible');\n    assert.equal(moment.locale(['fake-CA', 'fake-MX', 'fr']), 'fr', 'always find something if possible');\n    assert.equal(moment.locale(['fake-CA', 'fake-MX', 'fr-fake-fake-fake']), 'fr', 'always find something if possible');\n    assert.equal(moment.locale(['en', 'en-CA']), 'en', 'prefer earlier if it works');\n});\n\ntest('library ensure inheritance', function (assert) {\n    moment.locale('made-up', {\n        // I put them out of order\n        months : 'February_March_April_May_June_July_August_September_October_November_December_January'.split('_')\n        // the rest of the properties should be inherited.\n    });\n\n    assert.equal(moment([2012, 5, 6]).format('MMMM'), 'July', 'Override some of the configs');\n    assert.equal(moment([2012, 5, 6]).format('MMM'), 'Jun', 'But not all of them');\n});\n\ntest('library ensure inheritance LT L LL LLL LLLL', function (assert) {\n    var locale = 'test-inherit-lt';\n\n    moment.defineLocale(locale, {\n        longDateFormat : {\n            LT : '-[LT]-',\n            L : '-[L]-',\n            LL : '-[LL]-',\n            LLL : '-[LLL]-',\n            LLLL : '-[LLLL]-'\n        },\n        calendar : {\n            sameDay : '[sameDay] LT',\n            nextDay : '[nextDay] L',\n            nextWeek : '[nextWeek] LL',\n            lastDay : '[lastDay] LLL',\n            lastWeek : '[lastWeek] LLLL',\n            sameElse : 'L'\n        }\n    });\n\n    moment.locale('es');\n\n    assert.equal(moment().locale(locale).calendar(), 'sameDay -LT-', 'Should use instance locale in LT formatting');\n    assert.equal(moment().add(1, 'days').locale(locale).calendar(), 'nextDay -L-', 'Should use instance locale in L formatting');\n    assert.equal(moment().add(-1, 'days').locale(locale).calendar(), 'lastDay -LLL-', 'Should use instance locale in LL formatting');\n    assert.equal(moment().add(4, 'days').locale(locale).calendar(), 'nextWeek -LL-', 'Should use instance locale in LLL formatting');\n    assert.equal(moment().add(-4, 'days').locale(locale).calendar(), 'lastWeek -LLLL-', 'Should use instance locale in LLLL formatting');\n});\n\ntest('library localeData', function (assert) {\n    moment.locale('en');\n\n    var jan = moment([2000, 0]);\n\n    assert.equal(moment.localeData().months(jan), 'January', 'no arguments returns global');\n    assert.equal(moment.localeData('zh-cn').months(jan), '一月', 'a string returns the locale based on key');\n    assert.equal(moment.localeData(moment().locale('es')).months(jan), 'enero', 'if you pass in a moment it uses the moment\\'s locale');\n});\n\ntest('library deprecations', function (assert) {\n    test.expectedDeprecations('moment.lang');\n    moment.lang('dude', {months: ['Movember']});\n    assert.equal(moment.locale(), 'dude', 'setting the lang sets the locale');\n    assert.equal(moment.lang(), moment.locale());\n    assert.equal(moment.langData(), moment.localeData(), 'langData is localeData');\n    moment.defineLocale('dude', null);\n});\n\ntest('defineLocale', function (assert) {\n    moment.locale('en');\n    moment.defineLocale('dude', {months: ['Movember']});\n    assert.equal(moment().locale(), 'dude', 'defineLocale also sets it');\n    assert.equal(moment().locale('dude').locale(), 'dude', 'defineLocale defines a locale');\n    moment.defineLocale('dude', null);\n});\n\ntest('locales', function (assert) {\n    moment.defineLocale('dude', {months: ['Movember']});\n    assert.equal(true, !!~indexOf$1.call(moment.locales(), 'dude'), 'locales returns an array of defined locales');\n    assert.equal(true, !!~indexOf$1.call(moment.locales(), 'en'), 'locales should always include english');\n    moment.defineLocale('dude', null);\n});\n\ntest('library convenience', function (assert) {\n    moment.locale('something', {week: {dow: 3}});\n    moment.locale('something');\n    assert.equal(moment.locale(), 'something', 'locale can be used to create the locale too');\n    moment.defineLocale('something', null);\n});\n\ntest('firstDayOfWeek firstDayOfYear locale getters', function (assert) {\n    moment.locale('something', {week: {dow: 3, doy: 4}});\n    moment.locale('something');\n    assert.equal(moment.localeData().firstDayOfWeek(), 3, 'firstDayOfWeek');\n    assert.equal(moment.localeData().firstDayOfYear(), 4, 'firstDayOfYear');\n    moment.defineLocale('something', null);\n});\n\ntest('instance locale method', function (assert) {\n    moment.locale('en');\n\n    assert.equal(moment([2012, 5, 6]).format('MMMM'), 'June', 'Normally default to global');\n    assert.equal(moment([2012, 5, 6]).locale('es').format('MMMM'), 'junio', 'Use the instance specific locale');\n    assert.equal(moment([2012, 5, 6]).format('MMMM'), 'June', 'Using an instance specific locale does not affect other moments');\n});\n\ntest('instance locale method with array', function (assert) {\n    var m = moment().locale(['non-existent', 'fr', 'also-non-existent']);\n    assert.equal(m.locale(), 'fr', 'passing an array uses the first valid locale');\n    m = moment().locale(['es', 'fr', 'also-non-existent']);\n    assert.equal(m.locale(), 'es', 'passing an array uses the first valid locale');\n});\n\ntest('instance getter locale substrings', function (assert) {\n    var m = moment();\n\n    m.locale('fr-crap');\n    assert.equal(m.locale(), 'fr', 'use substrings');\n\n    m.locale('fr-does-not-exist');\n    assert.equal(m.locale(), 'fr', 'uses deep substrings');\n});\n\ntest('instance locale persists with manipulation', function (assert) {\n    moment.locale('en');\n\n    assert.equal(moment([2012, 5, 6]).locale('es').add({days: 1}).format('MMMM'), 'junio', 'With addition');\n    assert.equal(moment([2012, 5, 6]).locale('es').day(0).format('MMMM'), 'junio', 'With day getter');\n    assert.equal(moment([2012, 5, 6]).locale('es').endOf('day').format('MMMM'), 'junio', 'With endOf');\n});\n\ntest('instance locale persists with cloning', function (assert) {\n    moment.locale('en');\n\n    var a = moment([2012, 5, 6]).locale('es'),\n        b = a.clone(),\n        c = moment(a);\n\n    assert.equal(b.format('MMMM'), 'junio', 'using moment.fn.clone()');\n    assert.equal(b.format('MMMM'), 'junio', 'using moment()');\n});\n\ntest('duration locale method', function (assert) {\n    moment.locale('en');\n\n    assert.equal(moment.duration({seconds:  44}).humanize(), 'a few seconds', 'Normally default to global');\n    assert.equal(moment.duration({seconds:  44}).locale('es').humanize(), 'unos segundos', 'Use the instance specific locale');\n    assert.equal(moment.duration({seconds:  44}).humanize(), 'a few seconds', 'Using an instance specific locale does not affect other durations');\n});\n\ntest('duration locale persists with cloning', function (assert) {\n    moment.locale('en');\n\n    var a = moment.duration({seconds:  44}).locale('es'),\n        b = moment.duration(a);\n\n    assert.equal(b.humanize(), 'unos segundos', 'using moment.duration()');\n});\n\ntest('changing the global locale doesn\\'t affect existing duration instances', function (assert) {\n    var mom = moment.duration();\n    moment.locale('fr');\n    assert.equal('en', mom.locale());\n});\n\ntest('duration deprecations', function (assert) {\n    test.expectedDeprecations('moment().lang()');\n    assert.equal(moment.duration().lang(), moment.duration().localeData(), 'duration.lang is the same as duration.localeData');\n});\n\ntest('from and fromNow with invalid date', function (assert) {\n    assert.equal(moment(NaN).from(), 'Invalid date', 'moment.from with invalid moment');\n    assert.equal(moment(NaN).fromNow(), 'Invalid date', 'moment.fromNow with invalid moment');\n});\n\ntest('from relative time future', function (assert) {\n    var start = moment([2007, 1, 28]);\n\n    assert.equal(start.from(moment([2007, 1, 28]).subtract({s: 44})),  'in a few seconds', '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).subtract({s: 45})),  'in a minute',      '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).subtract({s: 89})),  'in a minute',      '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).subtract({s: 90})),  'in 2 minutes',     '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).subtract({m: 44})),  'in 44 minutes',    '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).subtract({m: 45})),  'in an hour',       '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).subtract({m: 89})),  'in an hour',       '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).subtract({m: 90})),  'in 2 hours',       '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).subtract({h: 5})),   'in 5 hours',       '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).subtract({h: 21})),  'in 21 hours',      '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).subtract({h: 22})),  'in a day',         '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).subtract({h: 35})),  'in a day',         '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).subtract({h: 36})),  'in 2 days',        '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).subtract({d: 1})),   'in a day',         '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).subtract({d: 5})),   'in 5 days',        '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).subtract({d: 25})),  'in 25 days',       '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).subtract({d: 26})),  'in a month',       '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).subtract({d: 30})),  'in a month',       '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).subtract({d: 45})),  'in a month',       '45 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).subtract({d: 47})),  'in 2 months',      '47 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).subtract({d: 74})),  'in 2 months',      '74 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).subtract({d: 78})),  'in 3 months',      '78 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).subtract({M: 1})),   'in a month',       '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).subtract({M: 5})),   'in 5 months',      '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).subtract({d: 315})), 'in 10 months',     '315 days = 10 months');\n    assert.equal(start.from(moment([2007, 1, 28]).subtract({d: 344})), 'in a year',        '344 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).subtract({d: 345})), 'in a year',        '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).subtract({d: 548})), 'in 2 years',       '548 days = in 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).subtract({y: 1})),   'in a year',        '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).subtract({y: 5})),   'in 5 years',       '5 years = 5 years');\n});\n\ntest('from relative time past', function (assert) {\n    var start = moment([2007, 1, 28]);\n\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44})),  'a few seconds ago', '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45})),  'a minute ago',      '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89})),  'a minute ago',      '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90})),  '2 minutes ago',     '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44})),  '44 minutes ago',    '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45})),  'an hour ago',       '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89})),  'an hour ago',       '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90})),  '2 hours ago',       '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5})),   '5 hours ago',       '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21})),  '21 hours ago',      '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22})),  'a day ago',         '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35})),  'a day ago',         '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36})),  '2 days ago',        '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1})),   'a day ago',         '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5})),   '5 days ago',        '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25})),  '25 days ago',       '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26})),  'a month ago',       '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30})),  'a month ago',       '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43})),  'a month ago',       '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46})),  '2 months ago',      '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74})),  '2 months ago',      '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76})),  '3 months ago',      '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1})),   'a month ago',       '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5})),   '5 months ago',      '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 315})), '10 months ago',     '315 days = 10 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 344})), 'a year ago',        '344 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345})), 'a year ago',        '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548})), '2 years ago',       '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1})),   'a year ago',        '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5})),   '5 years ago',       '5 years = 5 years');\n});\n\ntest('instance locale used with from', function (assert) {\n    moment.locale('en');\n\n    var a = moment([2012, 5, 6]).locale('es'),\n        b = moment([2012, 5, 7]);\n\n    assert.equal(a.from(b), 'hace un día', 'preserve locale of first moment');\n    assert.equal(b.from(a), 'in a day', 'do not preserve locale of second moment');\n});\n\ntest('instance localeData', function (assert) {\n    moment.defineLocale('dude', {week: {dow: 3}});\n    assert.equal(moment().locale('dude').localeData()._week.dow, 3);\n    moment.defineLocale('dude', null);\n});\n\ntest('month name callback function', function (assert) {\n    function fakeReplace(m, format) {\n        if (/test/.test(format)) {\n            return 'test';\n        }\n        if (m.date() === 1) {\n            return 'date';\n        }\n        return 'default';\n    }\n\n    moment.locale('made-up-2', {\n        months : fakeReplace,\n        monthsShort : fakeReplace,\n        weekdays : fakeReplace,\n        weekdaysShort : fakeReplace,\n        weekdaysMin : fakeReplace\n    });\n\n    assert.equal(moment().format('[test] dd ddd dddd MMM MMMM'), 'test test test test test test', 'format month name function should be able to access the format string');\n    assert.equal(moment([2011, 0, 1]).format('dd ddd dddd MMM MMMM'), 'date date date date date', 'format month name function should be able to access the moment object');\n    assert.equal(moment([2011, 0, 2]).format('dd ddd dddd MMM MMMM'), 'default default default default default', 'format month name function should be able to access the moment object');\n});\n\ntest('changing parts of a locale config', function (assert) {\n    test.expectedDeprecations('defineLocaleOverride');\n\n    moment.locale('partial-lang', {\n        months : 'a b c d e f g h i j k l'.split(' ')\n    });\n\n    assert.equal(moment([2011, 0, 1]).format('MMMM'), 'a', 'should be able to set locale values when creating the localeuage');\n\n    moment.locale('partial-lang', {\n        monthsShort : 'A B C D E F G H I J K L'.split(' ')\n    });\n\n    assert.equal(moment([2011, 0, 1]).format('MMMM MMM'), 'a A', 'should be able to set locale values after creating the localeuage');\n\n    moment.defineLocale('partial-lang', null);\n});\n\ntest('start/endOf week feature for first-day-is-monday locales', function (assert) {\n    moment.locale('monday-lang', {\n        week : {\n            dow : 1 // Monday is the first day of the week\n        }\n    });\n\n    moment.locale('monday-lang');\n    assert.equal(moment([2013, 0, 1]).startOf('week').day(), 1, 'for locale monday-lang first day of the week should be monday');\n    assert.equal(moment([2013, 0, 1]).endOf('week').day(), 0, 'for locale monday-lang last day of the week should be sunday');\n    moment.defineLocale('monday-lang', null);\n});\n\ntest('meridiem parsing', function (assert) {\n    moment.locale('meridiem-parsing', {\n        meridiemParse : /[bd]/i,\n        isPM : function (input) {\n            return input === 'b';\n        }\n    });\n\n    moment.locale('meridiem-parsing');\n    assert.equal(moment('2012-01-01 3b', 'YYYY-MM-DD ha').hour(), 15, 'Custom parsing of meridiem should work');\n    assert.equal(moment('2012-01-01 3d', 'YYYY-MM-DD ha').hour(), 3, 'Custom parsing of meridiem should work');\n    moment.defineLocale('meridiem-parsing', null);\n});\n\ntest('invalid date formatting', function (assert) {\n    moment.locale('has-invalid', {\n        invalidDate: 'KHAAAAAAAAAAAN!'\n    });\n\n    assert.equal(moment.invalid().format(), 'KHAAAAAAAAAAAN!');\n    assert.equal(moment.invalid().format('YYYY-MM-DD'), 'KHAAAAAAAAAAAN!');\n    moment.defineLocale('has-invalid', null);\n});\n\ntest('return locale name', function (assert) {\n    var registered = moment.locale('return-this', {});\n\n    assert.equal(registered, 'return-this', 'returns the locale configured');\n    moment.locale('return-this', null);\n});\n\ntest('changing the global locale doesn\\'t affect existing instances', function (assert) {\n    var mom = moment();\n    moment.locale('fr');\n    assert.equal('en', mom.locale());\n});\n\ntest('setting a language on instance returns the original moment for chaining', function (assert) {\n    test.expectedDeprecations('moment().lang()');\n    var mom = moment();\n\n    assert.equal(mom.lang('fr'), mom, 'setting the language (lang) returns the original moment for chaining');\n    assert.equal(mom.locale('it'), mom, 'setting the language (locale) returns the original moment for chaining');\n});\n\ntest('lang(key) changes the language of the instance', function (assert) {\n    test.expectedDeprecations('moment().lang()');\n    var m = moment().month(0);\n    m.lang('fr');\n    assert.equal(m.locale(), 'fr', 'm.lang(key) changes instance locale');\n});\n\ntest('moment#locale(false) resets to global locale', function (assert) {\n    var m = moment();\n\n    moment.locale('fr');\n    m.locale('it');\n\n    assert.equal(moment.locale(), 'fr', 'global locale is it');\n    assert.equal(m.locale(), 'it', 'instance locale is it');\n    m.locale(false);\n    assert.equal(m.locale(), 'fr', 'instance locale reset to global locale');\n});\n\ntest('moment().locale with missing key doesn\\'t change locale', function (assert) {\n    assert.equal(moment().locale('boo').localeData(), moment.localeData(),\n            'preserve global locale in case of bad locale id');\n});\n\ntest('moment().lang with missing key doesn\\'t change locale', function (assert) {\n    test.expectedDeprecations('moment().lang()');\n    assert.equal(moment().lang('boo').localeData(), moment.localeData(),\n            'preserve global locale in case of bad locale id');\n});\n\n\n// TODO: Enable this after fixing pl months parse hack hack\n// test('monthsParseExact', function (assert) {\n//     var locale = 'test-months-parse-exact';\n\n//     moment.defineLocale(locale, {\n//         monthsParseExact: true,\n//         months: 'A_AA_AAA_B_B B_BB  B_C_C-C_C,C2C_D_D+D_D`D*D'.split('_'),\n//         monthsShort: 'E_EE_EEE_F_FF_FFF_G_GG_GGG_H_HH_HHH'.split('_')\n//     });\n\n//     assert.equal(moment('A', 'MMMM', true).month(), 0, 'parse long month 0 with MMMM');\n//     assert.equal(moment('AA', 'MMMM', true).month(), 1, 'parse long month 1 with MMMM');\n//     assert.equal(moment('AAA', 'MMMM', true).month(), 2, 'parse long month 2 with MMMM');\n//     assert.equal(moment('B B', 'MMMM', true).month(), 4, 'parse long month 4 with MMMM');\n//     assert.equal(moment('BB  B', 'MMMM', true).month(), 5, 'parse long month 5 with MMMM');\n//     assert.equal(moment('C-C', 'MMMM', true).month(), 7, 'parse long month 7 with MMMM');\n//     assert.equal(moment('C,C2C', 'MMMM', true).month(), 8, 'parse long month 8 with MMMM');\n//     assert.equal(moment('D+D', 'MMMM', true).month(), 10, 'parse long month 10 with MMMM');\n//     assert.equal(moment('D`D*D', 'MMMM', true).month(), 11, 'parse long month 11 with MMMM');\n\n//     assert.equal(moment('E', 'MMM', true).month(), 0, 'parse long month 0 with MMM');\n//     assert.equal(moment('EE', 'MMM', true).month(), 1, 'parse long month 1 with MMM');\n//     assert.equal(moment('EEE', 'MMM', true).month(), 2, 'parse long month 2 with MMM');\n\n//     assert.equal(moment('A', 'MMM').month(), 0, 'non-strict parse long month 0 with MMM');\n//     assert.equal(moment('AA', 'MMM').month(), 1, 'non-strict parse long month 1 with MMM');\n//     assert.equal(moment('AAA', 'MMM').month(), 2, 'non-strict parse long month 2 with MMM');\n//     assert.equal(moment('E', 'MMMM').month(), 0, 'non-strict parse short month 0 with MMMM');\n//     assert.equal(moment('EE', 'MMMM').month(), 1, 'non-strict parse short month 1 with MMMM');\n//     assert.equal(moment('EEE', 'MMMM').month(), 2, 'non-strict parse short month 2 with MMMM');\n// });\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\nfunction module$1 (name, lifecycle) {\n    QUnit.module(name, {\n        setup : function () {\n            moment.locale('en');\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'core');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            teardownDeprecationHandler(test, moment, 'core');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n}\n\nmodule$1('locale inheritance');\n\ntest('calendar', function (assert) {\n    moment.defineLocale('base-cal', {\n        calendar : {\n            sameDay: '[Today at] HH:mm',\n            nextDay: '[Tomorrow at] HH:mm',\n            nextWeek: '[Next week at] HH:mm',\n            lastDay: '[Yesterday at] HH:mm',\n            lastWeek: '[Last week at] HH:mm',\n            sameElse: '[whatever]'\n        }\n    });\n    moment.defineLocale('child-cal', {\n        parentLocale: 'base-cal',\n        calendar: {\n            sameDay: '[Today] HH:mm',\n            nextDay: '[Tomorrow] HH:mm',\n            nextWeek: '[Next week] HH:mm'\n        }\n    });\n\n    moment.locale('child-cal');\n    var anchor = moment.utc('2015-05-05T12:00:00', moment.ISO_8601);\n    assert.equal(anchor.clone().add(3, 'hours').calendar(anchor), 'Today 15:00', 'today uses child version');\n    assert.equal(anchor.clone().add(1, 'day').calendar(anchor), 'Tomorrow 12:00', 'tomorrow uses child version');\n    assert.equal(anchor.clone().add(3, 'days').calendar(anchor), 'Next week 12:00', 'next week uses child version');\n\n    assert.equal(anchor.clone().subtract(1, 'day').calendar(anchor), 'Yesterday at 12:00', 'yesterday uses parent version');\n    assert.equal(anchor.clone().subtract(3, 'days').calendar(anchor), 'Last week at 12:00', 'last week uses parent version');\n    assert.equal(anchor.clone().subtract(7, 'days').calendar(anchor), 'whatever', 'sameElse uses parent version -');\n    assert.equal(anchor.clone().add(7, 'days').calendar(anchor), 'whatever', 'sameElse uses parent version +');\n});\n\ntest('missing', function (assert) {\n    moment.defineLocale('base-cal-2', {\n        calendar: {\n            sameDay: '[Today at] HH:mm',\n            nextDay: '[Tomorrow at] HH:mm',\n            nextWeek: '[Next week at] HH:mm',\n            lastDay: '[Yesterday at] HH:mm',\n            lastWeek: '[Last week at] HH:mm',\n            sameElse: '[whatever]'\n        }\n    });\n    moment.defineLocale('child-cal-2', {\n        parentLocale: 'base-cal-2'\n    });\n    moment.locale('child-cal-2');\n    var anchor = moment.utc('2015-05-05T12:00:00', moment.ISO_8601);\n    assert.equal(anchor.clone().add(3, 'hours').calendar(anchor), 'Today at 15:00', 'today uses parent version');\n    assert.equal(anchor.clone().add(1, 'day').calendar(anchor), 'Tomorrow at 12:00', 'tomorrow uses parent version');\n    assert.equal(anchor.clone().add(3, 'days').calendar(anchor), 'Next week at 12:00', 'next week uses parent version');\n    assert.equal(anchor.clone().subtract(1, 'day').calendar(anchor), 'Yesterday at 12:00', 'yesterday uses parent version');\n    assert.equal(anchor.clone().subtract(3, 'days').calendar(anchor), 'Last week at 12:00', 'last week uses parent version');\n    assert.equal(anchor.clone().subtract(7, 'days').calendar(anchor), 'whatever', 'sameElse uses parent version -');\n    assert.equal(anchor.clone().add(7, 'days').calendar(anchor), 'whatever', 'sameElse uses parent version +');\n});\n\n// Test function vs obj both directions\n\ntest('long date format', function (assert) {\n    moment.defineLocale('base-ldf', {\n        longDateFormat : {\n            LTS  : 'h:mm:ss A',\n            LT   : 'h:mm A',\n            L    : 'MM/DD/YYYY',\n            LL   : 'MMMM D, YYYY',\n            LLL  : 'MMMM D, YYYY h:mm A',\n            LLLL : 'dddd, MMMM D, YYYY h:mm A'\n        }\n    });\n    moment.defineLocale('child-ldf', {\n        parentLocale: 'base-ldf',\n        longDateFormat: {\n            LLL  : '[child] MMMM D, YYYY h:mm A',\n            LLLL : '[child] dddd, MMMM D, YYYY h:mm A'\n        }\n    });\n\n    moment.locale('child-ldf');\n    var anchor = moment.utc('2015-09-06T12:34:56', moment.ISO_8601);\n    assert.equal(anchor.format('LTS'), '12:34:56 PM', 'LTS uses base');\n    assert.equal(anchor.format('LT'), '12:34 PM', 'LT uses base');\n    assert.equal(anchor.format('L'), '09/06/2015', 'L uses base');\n    assert.equal(anchor.format('l'), '9/6/2015', 'l uses base');\n    assert.equal(anchor.format('LL'), 'September 6, 2015', 'LL uses base');\n    assert.equal(anchor.format('ll'), 'Sep 6, 2015', 'll uses base');\n    assert.equal(anchor.format('LLL'), 'child September 6, 2015 12:34 PM', 'LLL uses child');\n    assert.equal(anchor.format('lll'), 'child Sep 6, 2015 12:34 PM', 'lll uses child');\n    assert.equal(anchor.format('LLLL'), 'child Sunday, September 6, 2015 12:34 PM', 'LLLL uses child');\n    assert.equal(anchor.format('llll'), 'child Sun, Sep 6, 2015 12:34 PM', 'llll uses child');\n});\n\ntest('ordinal', function (assert) {\n    moment.defineLocale('base-ordinal-1', {\n        ordinal : '%dx'\n    });\n    moment.defineLocale('child-ordinal-1', {\n        parentLocale: 'base-ordinal-1',\n        ordinal : '%dy'\n    });\n\n    assert.equal(moment.utc('2015-02-03', moment.ISO_8601).format('Do'), '3y', 'ordinal uses child string');\n\n    moment.defineLocale('base-ordinal-2', {\n        ordinal : '%dx'\n    });\n    moment.defineLocale('child-ordinal-2', {\n        parentLocale: 'base-ordinal-2',\n        ordinal : function (num) {\n            return num + 'y';\n        }\n    });\n\n    assert.equal(moment.utc('2015-02-03', moment.ISO_8601).format('Do'), '3y', 'ordinal uses child function');\n\n    moment.defineLocale('base-ordinal-3', {\n        ordinal : function (num) {\n            return num + 'x';\n        }\n    });\n    moment.defineLocale('child-ordinal-3', {\n        parentLocale: 'base-ordinal-3',\n        ordinal : '%dy'\n    });\n\n    assert.equal(moment.utc('2015-02-03', moment.ISO_8601).format('Do'), '3y', 'ordinal uses child string (overwrite parent function)');\n});\n\ntest('ordinal parse', function (assert) {\n    moment.defineLocale('base-ordinal-parse-1', {\n        dayOfMonthOrdinalParse : /\\d{1,2}x/\n    });\n    moment.defineLocale('child-ordinal-parse-1', {\n        parentLocale: 'base-ordinal-parse-1',\n        dayOfMonthOrdinalParse : /\\d{1,2}y/\n    });\n\n    assert.ok(moment.utc('2015-01-1y', 'YYYY-MM-Do', true).isValid(), 'ordinal parse uses child');\n\n    moment.defineLocale('base-ordinal-parse-2', {\n        dayOfMonthOrdinalParse : /\\d{1,2}x/\n    });\n    moment.defineLocale('child-ordinal-parse-2', {\n        parentLocale: 'base-ordinal-parse-2',\n        dayOfMonthOrdinalParse : /\\d{1,2}/\n    });\n\n    assert.ok(moment.utc('2015-01-1', 'YYYY-MM-Do', true).isValid(), 'ordinal parse uses child (default)');\n});\n\ntest('months', function (assert) {\n    moment.defineLocale('base-months', {\n        months : 'One_Two_Three_Four_Five_Six_Seven_Eight_Nine_Ten_Eleven_Twelve'.split('_')\n    });\n    moment.defineLocale('child-months', {\n        parentLocale: 'base-months',\n        months : 'First_Second_Third_Fourth_Fifth_Sixth_Seventh_Eighth_Ninth_Tenth_Eleventh_Twelveth '.split('_')\n    });\n    assert.ok(moment.utc('2015-01-01', 'YYYY-MM-DD').format('MMMM'), 'First', 'months uses child');\n});\n\ntest('define child locale before parent', function (assert) {\n    moment.defineLocale('months-x', null);\n    moment.defineLocale('base-months-x', null);\n\n    moment.defineLocale('months-x', {\n        parentLocale: 'base-months-x',\n        months : 'First_Second_Third_Fourth_Fifth_Sixth_Seventh_Eighth_Ninth_Tenth_Eleventh_Twelveth '.split('_')\n    });\n    assert.equal(moment.locale(), 'en', 'failed to set a locale requiring missing parent');\n    moment.defineLocale('base-months-x', {\n        months : 'One_Two_Three_Four_Five_Six_Seven_Eight_Nine_Ten_Eleven_Twelve'.split('_')\n    });\n    assert.equal(moment.locale(), 'base-months-x', 'defineLocale should also set the locale (regardless of child locales)');\n\n    assert.equal(moment().locale('months-x').month(0).format('MMMM'), 'First', 'loading child before parent locale works');\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\nfunction module$1 (name, lifecycle) {\n    QUnit.module(name, {\n        setup : function () {\n            moment.locale('en');\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'core');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            teardownDeprecationHandler(test, moment, 'core');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n}\n\nmodule$1('locale update');\n\ntest('calendar', function (assert) {\n    moment.defineLocale('cal', null);\n    moment.defineLocale('cal', {\n        calendar : {\n            sameDay: '[Today at] HH:mm',\n            nextDay: '[Tomorrow at] HH:mm',\n            nextWeek: '[Next week at] HH:mm',\n            lastDay: '[Yesterday at] HH:mm',\n            lastWeek: '[Last week at] HH:mm',\n            sameElse: '[whatever]'\n        }\n    });\n    moment.updateLocale('cal', {\n        calendar: {\n            sameDay: '[Today] HH:mm',\n            nextDay: '[Tomorrow] HH:mm',\n            nextWeek: '[Next week] HH:mm'\n        }\n    });\n\n    moment.locale('cal');\n    var anchor = moment.utc('2015-05-05T12:00:00', moment.ISO_8601);\n    assert.equal(anchor.clone().add(3, 'hours').calendar(anchor), 'Today 15:00', 'today uses child version');\n    assert.equal(anchor.clone().add(1, 'day').calendar(anchor), 'Tomorrow 12:00', 'tomorrow uses child version');\n    assert.equal(anchor.clone().add(3, 'days').calendar(anchor), 'Next week 12:00', 'next week uses child version');\n\n    assert.equal(anchor.clone().subtract(1, 'day').calendar(anchor), 'Yesterday at 12:00', 'yesterday uses parent version');\n    assert.equal(anchor.clone().subtract(3, 'days').calendar(anchor), 'Last week at 12:00', 'last week uses parent version');\n    assert.equal(anchor.clone().subtract(7, 'days').calendar(anchor), 'whatever', 'sameElse uses parent version -');\n    assert.equal(anchor.clone().add(7, 'days').calendar(anchor), 'whatever', 'sameElse uses parent version +');\n});\n\ntest('missing', function (assert) {\n    moment.defineLocale('cal-2', null);\n    moment.defineLocale('cal-2', {\n        calendar: {\n            sameDay: '[Today at] HH:mm',\n            nextDay: '[Tomorrow at] HH:mm',\n            nextWeek: '[Next week at] HH:mm',\n            lastDay: '[Yesterday at] HH:mm',\n            lastWeek: '[Last week at] HH:mm',\n            sameElse: '[whatever]'\n        }\n    });\n    moment.updateLocale('cal-2', {\n    });\n    moment.locale('cal-2');\n    var anchor = moment.utc('2015-05-05T12:00:00', moment.ISO_8601);\n    assert.equal(anchor.clone().add(3, 'hours').calendar(anchor), 'Today at 15:00', 'today uses parent version');\n    assert.equal(anchor.clone().add(1, 'day').calendar(anchor), 'Tomorrow at 12:00', 'tomorrow uses parent version');\n    assert.equal(anchor.clone().add(3, 'days').calendar(anchor), 'Next week at 12:00', 'next week uses parent version');\n    assert.equal(anchor.clone().subtract(1, 'day').calendar(anchor), 'Yesterday at 12:00', 'yesterday uses parent version');\n    assert.equal(anchor.clone().subtract(3, 'days').calendar(anchor), 'Last week at 12:00', 'last week uses parent version');\n    assert.equal(anchor.clone().subtract(7, 'days').calendar(anchor), 'whatever', 'sameElse uses parent version -');\n    assert.equal(anchor.clone().add(7, 'days').calendar(anchor), 'whatever', 'sameElse uses parent version +');\n});\n\n// Test function vs obj both directions\n\ntest('long date format', function (assert) {\n    moment.defineLocale('ldf', null);\n    moment.defineLocale('ldf', {\n        longDateFormat : {\n            LTS  : 'h:mm:ss A',\n            LT   : 'h:mm A',\n            L    : 'MM/DD/YYYY',\n            LL   : 'MMMM D, YYYY',\n            LLL  : 'MMMM D, YYYY h:mm A',\n            LLLL : 'dddd, MMMM D, YYYY h:mm A'\n        }\n    });\n    moment.updateLocale('ldf', {\n        longDateFormat: {\n            LLL  : '[child] MMMM D, YYYY h:mm A',\n            LLLL : '[child] dddd, MMMM D, YYYY h:mm A'\n        }\n    });\n\n    moment.locale('ldf');\n    var anchor = moment.utc('2015-09-06T12:34:56', moment.ISO_8601);\n    assert.equal(anchor.format('LTS'), '12:34:56 PM', 'LTS uses base');\n    assert.equal(anchor.format('LT'), '12:34 PM', 'LT uses base');\n    assert.equal(anchor.format('L'), '09/06/2015', 'L uses base');\n    assert.equal(anchor.format('l'), '9/6/2015', 'l uses base');\n    assert.equal(anchor.format('LL'), 'September 6, 2015', 'LL uses base');\n    assert.equal(anchor.format('ll'), 'Sep 6, 2015', 'll uses base');\n    assert.equal(anchor.format('LLL'), 'child September 6, 2015 12:34 PM', 'LLL uses child');\n    assert.equal(anchor.format('lll'), 'child Sep 6, 2015 12:34 PM', 'lll uses child');\n    assert.equal(anchor.format('LLLL'), 'child Sunday, September 6, 2015 12:34 PM', 'LLLL uses child');\n    assert.equal(anchor.format('llll'), 'child Sun, Sep 6, 2015 12:34 PM', 'llll uses child');\n});\n\ntest('ordinal', function (assert) {\n    moment.defineLocale('ordinal-1', null);\n    moment.defineLocale('ordinal-1', {\n        ordinal : '%dx'\n    });\n    moment.updateLocale('ordinal-1', {\n        ordinal : '%dy'\n    });\n\n    assert.equal(moment.utc('2015-02-03', moment.ISO_8601).format('Do'), '3y', 'ordinal uses child string');\n\n    moment.defineLocale('ordinal-2', null);\n    moment.defineLocale('ordinal-2', {\n        ordinal : '%dx'\n    });\n    moment.updateLocale('ordinal-2', {\n        ordinal : function (num) {\n            return num + 'y';\n        }\n    });\n\n    assert.equal(moment.utc('2015-02-03', moment.ISO_8601).format('Do'), '3y', 'ordinal uses child function');\n\n    moment.defineLocale('ordinal-3', null);\n    moment.defineLocale('ordinal-3', {\n        ordinal : function (num) {\n            return num + 'x';\n        }\n    });\n    moment.updateLocale('ordinal-3', {\n        ordinal : '%dy'\n    });\n\n    assert.equal(moment.utc('2015-02-03', moment.ISO_8601).format('Do'), '3y', 'ordinal uses child string (overwrite parent function)');\n});\n\ntest('ordinal parse', function (assert) {\n    moment.defineLocale('ordinal-parse-1', null);\n    moment.defineLocale('ordinal-parse-1', {\n        dayOfMonthOrdinalParse : /\\d{1,2}x/\n    });\n    moment.updateLocale('ordinal-parse-1', {\n        dayOfMonthOrdinalParse : /\\d{1,2}y/\n    });\n\n    assert.ok(moment.utc('2015-01-1y', 'YYYY-MM-Do', true).isValid(), 'ordinal parse uses child');\n\n    moment.defineLocale('ordinal-parse-2', null);\n    moment.defineLocale('ordinal-parse-2', {\n        dayOfMonthOrdinalParse : /\\d{1,2}x/\n    });\n    moment.updateLocale('ordinal-parse-2', {\n        dayOfMonthOrdinalParse : /\\d{1,2}/\n    });\n\n    assert.ok(moment.utc('2015-01-1', 'YYYY-MM-Do', true).isValid(), 'ordinal parse uses child (default)');\n});\n\ntest('months', function (assert) {\n    moment.defineLocale('months', null);\n    moment.defineLocale('months', {\n        months : 'One_Two_Three_Four_Five_Six_Seven_Eight_Nine_Ten_Eleven_Twelve'.split('_')\n    });\n    moment.updateLocale('months', {\n        parentLocale: 'base-months',\n        months : 'First_Second_Third_Fourth_Fifth_Sixth_Seventh_Eighth_Ninth_Tenth_Eleventh_Twelveth '.split('_')\n    });\n    assert.ok(moment.utc('2015-01-01', 'YYYY-MM-DD').format('MMMM'), 'First', 'months uses child');\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\nfunction module$1 (name, lifecycle) {\n    QUnit.module(name, {\n        setup : function () {\n            moment.locale('en');\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'core');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            teardownDeprecationHandler(test, moment, 'core');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n}\n\nmodule$1('min max');\n\ntest('min', function (assert) {\n    var now = moment(),\n        future = now.clone().add(1, 'month'),\n        past = now.clone().subtract(1, 'month'),\n        invalid = moment.invalid();\n\n    assert.equal(moment.min(now, future, past), past, 'min(now, future, past)');\n    assert.equal(moment.min(future, now, past), past, 'min(future, now, past)');\n    assert.equal(moment.min(future, past, now), past, 'min(future, past, now)');\n    assert.equal(moment.min(past, future, now), past, 'min(past, future, now)');\n    assert.equal(moment.min(now, past), past, 'min(now, past)');\n    assert.equal(moment.min(past, now), past, 'min(past, now)');\n    assert.equal(moment.min(now), now, 'min(now, past)');\n\n    assert.equal(moment.min([now, future, past]), past, 'min([now, future, past])');\n    assert.equal(moment.min([now, past]), past, 'min(now, past)');\n    assert.equal(moment.min([now]), now, 'min(now)');\n\n    assert.equal(moment.min([now, invalid]), invalid, 'min(now, invalid)');\n    assert.equal(moment.min([invalid, now]), invalid, 'min(invalid, now)');\n});\n\ntest('max', function (assert) {\n    var now = moment(),\n        future = now.clone().add(1, 'month'),\n        past = now.clone().subtract(1, 'month'),\n        invalid = moment.invalid();\n\n    assert.equal(moment.max(now, future, past), future, 'max(now, future, past)');\n    assert.equal(moment.max(future, now, past), future, 'max(future, now, past)');\n    assert.equal(moment.max(future, past, now), future, 'max(future, past, now)');\n    assert.equal(moment.max(past, future, now), future, 'max(past, future, now)');\n    assert.equal(moment.max(now, past), now, 'max(now, past)');\n    assert.equal(moment.max(past, now), now, 'max(past, now)');\n    assert.equal(moment.max(now), now, 'max(now, past)');\n\n    assert.equal(moment.max([now, future, past]), future, 'max([now, future, past])');\n    assert.equal(moment.max([now, past]), now, 'max(now, past)');\n    assert.equal(moment.max([now]), now, 'max(now)');\n\n    assert.equal(moment.max([now, invalid]), invalid, 'max(now, invalid)');\n    assert.equal(moment.max([invalid, now]), invalid, 'max(invalid, now)');\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\nfunction module$1 (name, lifecycle) {\n    QUnit.module(name, {\n        setup : function () {\n            moment.locale('en');\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'core');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            teardownDeprecationHandler(test, moment, 'core');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n}\n\nmodule$1('mutable');\n\ntest('manipulation methods', function (assert) {\n    var m = moment();\n\n    assert.equal(m, m.year(2011), 'year() should be mutable');\n    assert.equal(m, m.month(1), 'month() should be mutable');\n    assert.equal(m, m.hours(7), 'hours() should be mutable');\n    assert.equal(m, m.minutes(33), 'minutes() should be mutable');\n    assert.equal(m, m.seconds(44), 'seconds() should be mutable');\n    assert.equal(m, m.milliseconds(55), 'milliseconds() should be mutable');\n    assert.equal(m, m.day(2), 'day() should be mutable');\n    assert.equal(m, m.startOf('week'), 'startOf() should be mutable');\n    assert.equal(m, m.add(1, 'days'), 'add() should be mutable');\n    assert.equal(m, m.subtract(2, 'years'), 'subtract() should be mutable');\n    assert.equal(m, m.local(), 'local() should be mutable');\n    assert.equal(m, m.utc(), 'utc() should be mutable');\n});\n\ntest('non mutable methods', function (assert) {\n    var m = moment();\n    assert.notEqual(m, m.clone(), 'clone() should not be mutable');\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\nfunction module$1 (name, lifecycle) {\n    QUnit.module(name, {\n        setup : function () {\n            moment.locale('en');\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'core');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            teardownDeprecationHandler(test, moment, 'core');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n}\n\nmodule$1('normalize units');\n\ntest('normalize units', function (assert) {\n    var fullKeys = ['year', 'quarter', 'month', 'isoWeek', 'week', 'day', 'hour', 'minute', 'second', 'millisecond', 'date', 'dayOfYear', 'weekday', 'isoWeekday', 'weekYear', 'isoWeekYear'],\n        aliases = ['y', 'Q', 'M', 'W', 'w', 'd', 'h', 'm', 's', 'ms', 'D', 'DDD', 'e', 'E', 'gg', 'GG'],\n        length = fullKeys.length,\n        fullKey,\n        fullKeyCaps,\n        fullKeyPlural,\n        fullKeyCapsPlural,\n        fullKeyLower,\n        alias,\n        index;\n\n    for (index = 0; index < length; index += 1) {\n        fullKey = fullKeys[index];\n        fullKeyCaps = fullKey.toUpperCase();\n        fullKeyLower = fullKey.toLowerCase();\n        fullKeyPlural = fullKey + 's';\n        fullKeyCapsPlural = fullKeyCaps + 's';\n        alias = aliases[index];\n        assert.equal(moment.normalizeUnits(fullKey), fullKey, 'Testing full key ' + fullKey);\n        assert.equal(moment.normalizeUnits(fullKeyCaps), fullKey, 'Testing full key capitalised ' + fullKey);\n        assert.equal(moment.normalizeUnits(fullKeyPlural), fullKey, 'Testing full key plural ' + fullKey);\n        assert.equal(moment.normalizeUnits(fullKeyCapsPlural), fullKey, 'Testing full key capitalised and plural ' + fullKey);\n        assert.equal(moment.normalizeUnits(alias), fullKey, 'Testing alias ' + fullKey);\n    }\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\nfunction module$1 (name, lifecycle) {\n    QUnit.module(name, {\n        setup : function () {\n            moment.locale('en');\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'core');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            teardownDeprecationHandler(test, moment, 'core');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n}\n\nmodule$1('now');\n\ntest('now', function (assert) {\n    var startOfTest = new Date().valueOf(),\n        momentNowTime = moment.now(),\n        afterMomentCreationTime = new Date().valueOf();\n\n    assert.ok(startOfTest <= momentNowTime, 'moment now() time should be now, not in the past');\n    assert.ok(momentNowTime <= afterMomentCreationTime, 'moment now() time should be now, not in the future');\n});\n\ntest('now - Date mocked', function (assert) {\n    // We need to test mocking the global Date object, so disable 'Read Only' jshint check\n    /* jshint -W020 */\n    var RealDate = Date,\n        customTimeMs = moment('2015-01-01T01:30:00.000Z').valueOf();\n\n    function MockDate() {\n        return new RealDate(customTimeMs);\n    }\n\n    MockDate.now = function () {\n        return new MockDate().valueOf();\n    };\n\n    MockDate.prototype = RealDate.prototype;\n\n    Date = MockDate;\n\n    try {\n        assert.equal(moment().valueOf(), customTimeMs, 'moment now() time should use the global Date object');\n    } finally {\n        Date = RealDate;\n    }\n});\n\ntest('now - custom value', function (assert) {\n    var customTimeStr = '2015-01-01T01:30:00.000Z',\n        customTime = moment(customTimeStr, moment.ISO_8601).valueOf(),\n        oldFn = moment.now;\n\n    moment.now = function () {\n        return customTime;\n    };\n\n    try {\n        assert.equal(moment().toISOString(), customTimeStr, 'moment() constructor should use the function defined by moment.now, but it did not');\n        assert.equal(moment.utc().toISOString(), customTimeStr, 'moment() constructor should use the function defined by moment.now, but it did not');\n    } finally {\n        moment.now = oldFn;\n    }\n});\n\ntest('empty object, empty array', function (assert) {\n    function assertIsNow(gen, msg) {\n        var before = +(new Date()),\n            mid = gen(),\n            after = +(new Date());\n        assert.ok(before <= +mid && +mid <= after, 'should be now : ' + msg);\n    }\n    assertIsNow(function () {\n        return moment();\n    }, 'moment()');\n    assertIsNow(function () {\n        return moment([]);\n    }, 'moment([])');\n    assertIsNow(function () {\n        return moment({});\n    }, 'moment({})');\n    assertIsNow(function () {\n        return moment.utc();\n    }, 'moment.utc()');\n    assertIsNow(function () {\n        return moment.utc([]);\n    }, 'moment.utc([])');\n    assertIsNow(function () {\n        return moment.utc({});\n    }, 'moment.utc({})');\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\nfunction module$1 (name, lifecycle) {\n    QUnit.module(name, {\n        setup : function () {\n            moment.locale('en');\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'core');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            teardownDeprecationHandler(test, moment, 'core');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n}\n\nmodule$1('parsing flags');\n\nfunction flags () {\n    return moment.apply(null, arguments).parsingFlags();\n}\n\ntest('overflow with array', function (assert) {\n    //months\n    assert.equal(flags([2010, 0]).overflow, -1, 'month 0 valid');\n    assert.equal(flags([2010, 1]).overflow, -1, 'month 1 valid');\n    assert.equal(flags([2010, -1]).overflow, 1, 'month -1 invalid');\n    assert.equal(flags([2100, 12]).overflow, 1, 'month 12 invalid');\n\n    //days\n    assert.equal(flags([2010, 1, 16]).overflow, -1, 'date valid');\n    assert.equal(flags([2010, 1, -1]).overflow, 2, 'date -1 invalid');\n    assert.equal(flags([2010, 1, 0]).overflow, 2, 'date 0 invalid');\n    assert.equal(flags([2010, 1, 32]).overflow, 2, 'date 32 invalid');\n    assert.equal(flags([2012, 1, 29]).overflow, -1, 'date leap year valid');\n    assert.equal(flags([2010, 1, 29]).overflow, 2, 'date leap year invalid');\n\n    //hours\n    assert.equal(flags([2010, 1, 1, 8]).overflow, -1, 'hour valid');\n    assert.equal(flags([2010, 1, 1, 0]).overflow, -1, 'hour 0 valid');\n    assert.equal(flags([2010, 1, 1, -1]).overflow, 3, 'hour -1 invalid');\n    assert.equal(flags([2010, 1, 1, 25]).overflow, 3, 'hour 25 invalid');\n    assert.equal(flags([2010, 1, 1, 24, 1]).overflow, 3, 'hour 24:01 invalid');\n\n    //minutes\n    assert.equal(flags([2010, 1, 1, 8, 15]).overflow, -1, 'minute valid');\n    assert.equal(flags([2010, 1, 1, 8, 0]).overflow, -1, 'minute 0 valid');\n    assert.equal(flags([2010, 1, 1, 8, -1]).overflow, 4, 'minute -1 invalid');\n    assert.equal(flags([2010, 1, 1, 8, 60]).overflow, 4, 'minute 60 invalid');\n\n    //seconds\n    assert.equal(flags([2010, 1, 1, 8, 15, 12]).overflow, -1, 'second valid');\n    assert.equal(flags([2010, 1, 1, 8, 15, 0]).overflow, -1, 'second 0 valid');\n    assert.equal(flags([2010, 1, 1, 8, 15, -1]).overflow, 5, 'second -1 invalid');\n    assert.equal(flags([2010, 1, 1, 8, 15, 60]).overflow, 5, 'second 60 invalid');\n\n    //milliseconds\n    assert.equal(flags([2010, 1, 1, 8, 15, 12, 345]).overflow, -1, 'millisecond valid');\n    assert.equal(flags([2010, 1, 1, 8, 15, 12, 0]).overflow, -1, 'millisecond 0 valid');\n    assert.equal(flags([2010, 1, 1, 8, 15, 12, -1]).overflow, 6, 'millisecond -1 invalid');\n    assert.equal(flags([2010, 1, 1, 8, 15, 12, 1000]).overflow, 6, 'millisecond 1000 invalid');\n\n    // 24 hrs\n    assert.equal(flags([2010, 1, 1, 24, 0, 0, 0]).overflow, -1, '24:00:00.000 is fine');\n    assert.equal(flags([2010, 1, 1, 24, 1, 0, 0]).overflow, 3, '24:01:00.000 is wrong hour');\n    assert.equal(flags([2010, 1, 1, 24, 0, 1, 0]).overflow, 3, '24:00:01.000 is wrong hour');\n    assert.equal(flags([2010, 1, 1, 24, 0, 0, 1]).overflow, 3, '24:00:00.001 is wrong hour');\n});\n\ntest('overflow without format', function (assert) {\n    //months\n    assert.equal(flags('2001-01', 'YYYY-MM').overflow, -1, 'month 1 valid');\n    assert.equal(flags('2001-12', 'YYYY-MM').overflow, -1, 'month 12 valid');\n    assert.equal(flags('2001-13', 'YYYY-MM').overflow, 1, 'month 13 invalid');\n\n    //days\n    assert.equal(flags('2010-01-16', 'YYYY-MM-DD').overflow, -1, 'date 16 valid');\n    assert.equal(flags('2010-01-0',  'YYYY-MM-DD').overflow, 2, 'date 0 invalid');\n    assert.equal(flags('2010-01-32', 'YYYY-MM-DD').overflow, 2, 'date 32 invalid');\n    assert.equal(flags('2012-02-29', 'YYYY-MM-DD').overflow, -1, 'date leap year valid');\n    assert.equal(flags('2010-02-29', 'YYYY-MM-DD').overflow, 2, 'date leap year invalid');\n\n    //days of the year\n    assert.equal(flags('2010 300', 'YYYY DDDD').overflow, -1, 'day 300 of year valid');\n    assert.equal(flags('2010 365', 'YYYY DDDD').overflow, -1, 'day 365 of year valid');\n    assert.equal(flags('2010 366', 'YYYY DDDD').overflow, 2, 'day 366 of year invalid');\n    assert.equal(flags('2012 366', 'YYYY DDDD').overflow, -1, 'day 366 of leap year valid');\n    assert.equal(flags('2012 367', 'YYYY DDDD').overflow, 2, 'day 367 of leap year invalid');\n\n    //hours\n    assert.equal(flags('08', 'HH').overflow, -1, 'hour valid');\n    assert.equal(flags('00', 'HH').overflow, -1, 'hour 0 valid');\n    assert.equal(flags('25', 'HH').overflow, 3, 'hour 25 invalid');\n    assert.equal(flags('24:01', 'HH:mm').overflow, 3, 'hour 24:01 invalid');\n\n    //minutes\n    assert.equal(flags('08:15', 'HH:mm').overflow, -1, 'minute valid');\n    assert.equal(flags('08:00', 'HH:mm').overflow, -1, 'minute 0 valid');\n    assert.equal(flags('08:60', 'HH:mm').overflow, 4, 'minute 60 invalid');\n\n    //seconds\n    assert.equal(flags('08:15:12', 'HH:mm:ss').overflow, -1, 'second valid');\n    assert.equal(flags('08:15:00', 'HH:mm:ss').overflow, -1, 'second 0 valid');\n    assert.equal(flags('08:15:60', 'HH:mm:ss').overflow, 5, 'second 60 invalid');\n\n    //milliseconds\n    assert.equal(flags('08:15:12:345', 'HH:mm:ss:SSSS').overflow, -1, 'millisecond valid');\n    assert.equal(flags('08:15:12:000', 'HH:mm:ss:SSSS').overflow, -1, 'millisecond 0 valid');\n\n    //this is OK because we don't match the last digit, so it's 100 ms\n    assert.equal(flags('08:15:12:1000', 'HH:mm:ss:SSSS').overflow, -1, 'millisecond 1000 actually valid');\n});\n\ntest('extra tokens', function (assert) {\n    assert.deepEqual(flags('1982-05-25', 'YYYY-MM-DD').unusedTokens, [], 'nothing extra');\n    assert.deepEqual(flags('1982-05', 'YYYY-MM-DD').unusedTokens, ['DD'], 'extra formatting token');\n    assert.deepEqual(flags('1982', 'YYYY-MM-DD').unusedTokens, ['MM', 'DD'], 'multiple extra formatting tokens');\n    assert.deepEqual(flags('1982-05', 'YYYY-MM-').unusedTokens, [], 'extra non-formatting token');\n    assert.deepEqual(flags('1982-05-', 'YYYY-MM-DD').unusedTokens, ['DD'], 'non-extra non-formatting token');\n    assert.deepEqual(flags('1982 05 1982', 'YYYY-MM-DD').unusedTokens, [], 'different non-formatting token');\n});\n\ntest('extra tokens strict', function (assert) {\n    assert.deepEqual(flags('1982-05-25', 'YYYY-MM-DD', true).unusedTokens, [], 'nothing extra');\n    assert.deepEqual(flags('1982-05', 'YYYY-MM-DD', true).unusedTokens, ['-', 'DD'], 'extra formatting token');\n    assert.deepEqual(flags('1982', 'YYYY-MM-DD', true).unusedTokens, ['-', 'MM', '-', 'DD'], 'multiple extra formatting tokens');\n    assert.deepEqual(flags('1982-05', 'YYYY-MM-', true).unusedTokens, ['-'], 'extra non-formatting token');\n    assert.deepEqual(flags('1982-05-', 'YYYY-MM-DD', true).unusedTokens, ['DD'], 'non-extra non-formatting token');\n    assert.deepEqual(flags('1982 05 1982', 'YYYY-MM-DD', true).unusedTokens, ['-', '-'], 'different non-formatting token');\n});\n\ntest('unused input', function (assert) {\n    assert.deepEqual(flags('1982-05-25', 'YYYY-MM-DD').unusedInput, [], 'normal input');\n    assert.deepEqual(flags('1982-05-25 this is more stuff', 'YYYY-MM-DD').unusedInput, [' this is more stuff'], 'trailing nonsense');\n    assert.deepEqual(flags('1982-05-25 09:30', 'YYYY-MM-DD').unusedInput, [' 09:30'], ['trailing legit-looking input']);\n    assert.deepEqual(flags('1982-05-25 some junk', 'YYYY-MM-DD [some junk]').unusedInput, [], 'junk that actually gets matched');\n    assert.deepEqual(flags('stuff at beginning 1982-05-25', 'YYYY-MM-DD').unusedInput, ['stuff at beginning '], 'leading junk');\n    assert.deepEqual(flags('junk 1982 more junk 05 yet more junk25', 'YYYY-MM-DD').unusedInput, ['junk ', ' more junk ', ' yet more junk'], 'interstitial junk');\n});\n\ntest('unused input strict', function (assert) {\n    assert.deepEqual(flags('1982-05-25', 'YYYY-MM-DD', true).unusedInput, [], 'normal input');\n    assert.deepEqual(flags('1982-05-25 this is more stuff', 'YYYY-MM-DD', true).unusedInput, [' this is more stuff'], 'trailing nonsense');\n    assert.deepEqual(flags('1982-05-25 09:30', 'YYYY-MM-DD', true).unusedInput, [' 09:30'], ['trailing legit-looking input']);\n    assert.deepEqual(flags('1982-05-25 some junk', 'YYYY-MM-DD [some junk]', true).unusedInput, [], 'junk that actually gets matched');\n    assert.deepEqual(flags('stuff at beginning 1982-05-25', 'YYYY-MM-DD', true).unusedInput, ['stuff at beginning '], 'leading junk');\n    assert.deepEqual(flags('junk 1982 more junk 05 yet more junk25', 'YYYY-MM-DD', true).unusedInput, ['junk ', ' more junk ', ' yet more junk'], 'interstitial junk');\n});\n\ntest('chars left over', function (assert) {\n    assert.equal(flags('1982-05-25', 'YYYY-MM-DD').charsLeftOver, 0, 'normal input');\n    assert.equal(flags('1982-05-25 this is more stuff', 'YYYY-MM-DD').charsLeftOver, ' this is more stuff'.length, 'trailing nonsense');\n    assert.equal(flags('1982-05-25 09:30', 'YYYY-MM-DD').charsLeftOver, ' 09:30'.length, 'trailing legit-looking input');\n    assert.equal(flags('stuff at beginning 1982-05-25', 'YYYY-MM-DD').charsLeftOver, 'stuff at beginning '.length, 'leading junk');\n    assert.equal(flags('1982 junk 05 more junk25', 'YYYY-MM-DD').charsLeftOver, [' junk ', ' more junk'].join('').length, 'interstitial junk');\n    assert.equal(flags('stuff at beginning 1982 junk 05 more junk25', 'YYYY-MM-DD').charsLeftOver, ['stuff at beginning ', ' junk ', ' more junk'].join('').length, 'leading and interstitial junk');\n});\n\ntest('empty', function (assert) {\n    assert.equal(flags('1982-05-25', 'YYYY-MM-DD').empty, false, 'normal input');\n    assert.equal(flags('nothing here', 'YYYY-MM-DD').empty, true, 'pure garbage');\n    assert.equal(flags('junk but has the number 2000 in it', 'YYYY-MM-DD').empty, false, 'only mostly garbage');\n    assert.equal(flags('', 'YYYY-MM-DD').empty, true, 'empty string');\n    assert.equal(flags('', 'YYYY-MM-DD').empty, true, 'blank string');\n});\n\ntest('null', function (assert) {\n    assert.equal(flags('1982-05-25', 'YYYY-MM-DD').nullInput, false, 'normal input');\n    assert.equal(flags(null).nullInput, true, 'just null');\n    assert.equal(flags(null, 'YYYY-MM-DD').nullInput, true, 'null with format');\n});\n\ntest('invalid month', function (assert) {\n    assert.equal(flags('1982 May', 'YYYY MMMM').invalidMonth, null, 'normal input');\n    assert.equal(flags('1982 Laser', 'YYYY MMMM').invalidMonth, 'Laser', 'bad month name');\n});\n\ntest('empty format array', function (assert) {\n    assert.equal(flags('1982 May', ['YYYY MMM']).invalidFormat, false, 'empty format array');\n    assert.equal(flags('1982 May', []).invalidFormat, true, 'empty format array');\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\nfunction module$1 (name, lifecycle) {\n    QUnit.module(name, {\n        setup : function () {\n            moment.locale('en');\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'core');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            teardownDeprecationHandler(test, moment, 'core');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n}\n\nvar symbolMap = {\n        '1': '!',\n        '2': '@',\n        '3': '#',\n        '4': '$',\n        '5': '%',\n        '6': '^',\n        '7': '&',\n        '8': '*',\n        '9': '(',\n        '0': ')'\n    };\nvar numberMap = {\n        '!': '1',\n        '@': '2',\n        '#': '3',\n        '$': '4',\n        '%': '5',\n        '^': '6',\n        '&': '7',\n        '*': '8',\n        '(': '9',\n        ')': '0'\n    };\n\nmodule$1('preparse and postformat', {\n    setup: function () {\n        moment.locale('symbol', {\n            preparse: function (string) {\n                return string.replace(/[!@#$%\\^&*()]/g, function (match) {\n                    return numberMap[match];\n                });\n            },\n\n            postformat: function (string) {\n                return string.replace(/\\d/g, function (match) {\n                    return symbolMap[match];\n                });\n            }\n        });\n    },\n    teardown: function () {\n        moment.defineLocale('symbol', null);\n    }\n});\n\ntest('transform', function (assert) {\n    assert.equal(moment.utc('@)!@-)*-@&', 'YYYY-MM-DD').unix(), 1346025600, 'preparse string + format');\n    assert.equal(moment.utc('@)!@-)*-@&').unix(), 1346025600, 'preparse ISO8601 string');\n    assert.equal(moment.unix(1346025600).utc().format('YYYY-MM-DD'), '@)!@-)*-@&', 'postformat');\n});\n\ntest('transform from', function (assert) {\n    var start = moment([2007, 1, 28]);\n\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true), '@ minutes', 'postformat should work on moment.fn.from');\n    assert.equal(moment().add(6, 'd').fromNow(true), '^ days', 'postformat should work on moment.fn.fromNow');\n    assert.equal(moment.duration(10, 'h').humanize(), '!) hours', 'postformat should work on moment.duration.fn.humanize');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'Today at !@:)) PM',     'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'Today at !@:@% PM',     'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'Today at !:)) PM',      'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'Tomorrow at !@:)) PM',  'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'Today at !!:)) AM',     'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'Yesterday at !@:)) PM', 'yesterday at the same time');\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\nfunction module$1 (name, lifecycle) {\n    QUnit.module(name, {\n        setup : function () {\n            moment.locale('en');\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'core');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            teardownDeprecationHandler(test, moment, 'core');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n}\n\nmodule$1('quarter');\n\ntest('library quarter getter', function (assert) {\n    assert.equal(moment([1985,  1,  4]).quarter(), 1, 'Feb  4 1985 is Q1');\n    assert.equal(moment([2029,  8, 18]).quarter(), 3, 'Sep 18 2029 is Q3');\n    assert.equal(moment([2013,  3, 24]).quarter(), 2, 'Apr 24 2013 is Q2');\n    assert.equal(moment([2015,  2,  5]).quarter(), 1, 'Mar  5 2015 is Q1');\n    assert.equal(moment([1970,  0,  2]).quarter(), 1, 'Jan  2 1970 is Q1');\n    assert.equal(moment([2001, 11, 12]).quarter(), 4, 'Dec 12 2001 is Q4');\n    assert.equal(moment([2000,  0,  2]).quarter(), 1, 'Jan  2 2000 is Q1');\n});\n\ntest('quarter setter singular', function (assert) {\n    var m = moment([2014, 4, 11]);\n    assert.equal(m.quarter(2).month(), 4, 'set same quarter');\n    assert.equal(m.quarter(3).month(), 7, 'set 3rd quarter');\n    assert.equal(m.quarter(1).month(), 1, 'set 1st quarter');\n    assert.equal(m.quarter(4).month(), 10, 'set 4th quarter');\n});\n\ntest('quarter setter plural', function (assert) {\n    var m = moment([2014, 4, 11]);\n    assert.equal(m.quarters(2).month(), 4, 'set same quarter');\n    assert.equal(m.quarters(3).month(), 7, 'set 3rd quarter');\n    assert.equal(m.quarters(1).month(), 1, 'set 1st quarter');\n    assert.equal(m.quarters(4).month(), 10, 'set 4th quarter');\n});\n\ntest('quarter setter programmatic', function (assert) {\n    var m = moment([2014, 4, 11]);\n    assert.equal(m.set('quarter', 2).month(), 4, 'set same quarter');\n    assert.equal(m.set('quarter', 3).month(), 7, 'set 3rd quarter');\n    assert.equal(m.set('quarter', 1).month(), 1, 'set 1st quarter');\n    assert.equal(m.set('quarter', 4).month(), 10, 'set 4th quarter');\n});\n\ntest('quarter setter programmatic plural', function (assert) {\n    var m = moment([2014, 4, 11]);\n    assert.equal(m.set('quarters', 2).month(), 4, 'set same quarter');\n    assert.equal(m.set('quarters', 3).month(), 7, 'set 3rd quarter');\n    assert.equal(m.set('quarters', 1).month(), 1, 'set 1st quarter');\n    assert.equal(m.set('quarters', 4).month(), 10, 'set 4th quarter');\n});\n\ntest('quarter setter programmatic abbr', function (assert) {\n    var m = moment([2014, 4, 11]);\n    assert.equal(m.set('Q', 2).month(), 4, 'set same quarter');\n    assert.equal(m.set('Q', 3).month(), 7, 'set 3rd quarter');\n    assert.equal(m.set('Q', 1).month(), 1, 'set 1st quarter');\n    assert.equal(m.set('Q', 4).month(), 10, 'set 4th quarter');\n});\n\ntest('quarter setter only month changes', function (assert) {\n    var m = moment([2014, 4, 11, 1, 2, 3, 4]).quarter(4);\n    assert.equal(m.year(), 2014, 'keep year');\n    assert.equal(m.month(), 10, 'set month');\n    assert.equal(m.date(), 11, 'keep date');\n    assert.equal(m.hour(), 1, 'keep hour');\n    assert.equal(m.minute(), 2, 'keep minutes');\n    assert.equal(m.second(), 3, 'keep seconds');\n    assert.equal(m.millisecond(), 4, 'keep milliseconds');\n});\n\ntest('quarter setter bubble to next year', function (assert) {\n    var m = moment([2014, 4, 11, 1, 2, 3, 4]).quarter(7);\n    assert.equal(m.year(), 2015, 'year bubbled');\n    assert.equal(m.month(), 7, 'set month');\n    assert.equal(m.date(), 11, 'keep date');\n    assert.equal(m.hour(), 1, 'keep hour');\n    assert.equal(m.minute(), 2, 'keep minutes');\n    assert.equal(m.second(), 3, 'keep seconds');\n    assert.equal(m.millisecond(), 4, 'keep milliseconds');\n});\n\ntest('quarter diff', function (assert) {\n    assert.equal(moment('2014-01-01').diff(moment('2014-04-01'), 'quarter'),\n            -1, 'diff -1 quarter');\n    assert.equal(moment('2014-04-01').diff(moment('2014-01-01'), 'quarter'),\n            1, 'diff 1 quarter');\n    assert.equal(moment('2014-05-01').diff(moment('2014-01-01'), 'quarter'),\n            1, 'diff 1 quarter');\n    assert.ok(Math.abs((4 / 3) - moment('2014-05-01').diff(\n                    moment('2014-01-01'), 'quarter', true)) < 0.00001,\n            'diff 1 1/3 quarter');\n    assert.equal(moment('2015-01-01').diff(moment('2014-01-01'), 'quarter'),\n            4, 'diff 4 quarters');\n});\n\ntest('quarter setter bubble to previous year', function (assert) {\n    var m = moment([2014, 4, 11, 1, 2, 3, 4]).quarter(-3);\n    assert.equal(m.year(), 2013, 'year bubbled');\n    assert.equal(m.month(), 1, 'set month');\n    assert.equal(m.date(), 11, 'keep date');\n    assert.equal(m.hour(), 1, 'keep hour');\n    assert.equal(m.minute(), 2, 'keep minutes');\n    assert.equal(m.second(), 3, 'keep seconds');\n    assert.equal(m.millisecond(), 4, 'keep milliseconds');\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\nfunction module$1 (name, lifecycle) {\n    QUnit.module(name, {\n        setup : function () {\n            moment.locale('en');\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'core');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            teardownDeprecationHandler(test, moment, 'core');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n}\n\nmodule$1('relative time');\n\ntest('default thresholds fromNow', function (assert) {\n    var a = moment();\n\n    // Seconds to minutes threshold\n    a.subtract(44, 'seconds');\n    assert.equal(a.fromNow(), 'a few seconds ago', 'Below default seconds to minutes threshold');\n    a.subtract(1, 'seconds');\n    assert.equal(a.fromNow(), 'a minute ago', 'Above default seconds to minutes threshold');\n\n    // Minutes to hours threshold\n    a = moment();\n    a.subtract(44, 'minutes');\n    assert.equal(a.fromNow(), '44 minutes ago', 'Below default minute to hour threshold');\n    a.subtract(1, 'minutes');\n    assert.equal(a.fromNow(), 'an hour ago', 'Above default minute to hour threshold');\n\n    // Hours to days threshold\n    a = moment();\n    a.subtract(21, 'hours');\n    assert.equal(a.fromNow(), '21 hours ago', 'Below default hours to day threshold');\n    a.subtract(1, 'hours');\n    assert.equal(a.fromNow(), 'a day ago', 'Above default hours to day threshold');\n\n    // Days to month threshold\n    a = moment();\n    a.subtract(25, 'days');\n    assert.equal(a.fromNow(), '25 days ago', 'Below default days to month (singular) threshold');\n    a.subtract(1, 'days');\n    assert.equal(a.fromNow(), 'a month ago', 'Above default days to month (singular) threshold');\n\n    // months to year threshold\n    a = moment();\n    a.subtract(10, 'months');\n    assert.equal(a.fromNow(), '10 months ago', 'Below default days to years threshold');\n    a.subtract(1, 'month');\n    assert.equal(a.fromNow(), 'a year ago', 'Above default days to years threshold');\n});\n\ntest('default thresholds toNow', function (assert) {\n    var a = moment();\n\n    // Seconds to minutes threshold\n    a.subtract(44, 'seconds');\n    assert.equal(a.toNow(), 'in a few seconds', 'Below default seconds to minutes threshold');\n    a.subtract(1, 'seconds');\n    assert.equal(a.toNow(), 'in a minute', 'Above default seconds to minutes threshold');\n\n    // Minutes to hours threshold\n    a = moment();\n    a.subtract(44, 'minutes');\n    assert.equal(a.toNow(), 'in 44 minutes', 'Below default minute to hour threshold');\n    a.subtract(1, 'minutes');\n    assert.equal(a.toNow(), 'in an hour', 'Above default minute to hour threshold');\n\n    // Hours to days threshold\n    a = moment();\n    a.subtract(21, 'hours');\n    assert.equal(a.toNow(), 'in 21 hours', 'Below default hours to day threshold');\n    a.subtract(1, 'hours');\n    assert.equal(a.toNow(), 'in a day', 'Above default hours to day threshold');\n\n    // Days to month threshold\n    a = moment();\n    a.subtract(25, 'days');\n    assert.equal(a.toNow(), 'in 25 days', 'Below default days to month (singular) threshold');\n    a.subtract(1, 'days');\n    assert.equal(a.toNow(), 'in a month', 'Above default days to month (singular) threshold');\n\n    // months to year threshold\n    a = moment();\n    a.subtract(10, 'months');\n    assert.equal(a.toNow(), 'in 10 months', 'Below default days to years threshold');\n    a.subtract(1, 'month');\n    assert.equal(a.toNow(), 'in a year', 'Above default days to years threshold');\n});\n\ntest('custom thresholds', function (assert) {\n    var a;\n\n    // Seconds to minute threshold, under 30\n    moment.relativeTimeThreshold('s', 25);\n\n    a = moment();\n    a.subtract(24, 'seconds');\n    assert.equal(a.fromNow(), 'a few seconds ago', 'Below custom seconds to minute threshold, s < 30');\n    a.subtract(1, 'seconds');\n    assert.equal(a.fromNow(), 'a minute ago', 'Above custom seconds to minute threshold, s < 30');\n\n    // Seconds to minutes threshold\n    moment.relativeTimeThreshold('s', 55);\n\n    a = moment();\n    a.subtract(54, 'seconds');\n    assert.equal(a.fromNow(), 'a few seconds ago', 'Below custom seconds to minutes threshold');\n    a.subtract(1, 'seconds');\n    assert.equal(a.fromNow(), 'a minute ago', 'Above custom seconds to minutes threshold');\n\n    moment.relativeTimeThreshold('s', 45);\n\n    // A few seconds to seconds threshold\n    moment.relativeTimeThreshold('ss', 3);\n\n    a = moment();\n    a.subtract(3, 'seconds');\n    assert.equal(a.fromNow(), 'a few seconds ago', 'Below custom a few seconds to seconds threshold');\n    a.subtract(1, 'seconds');\n    assert.equal(a.fromNow(), '4 seconds ago', 'Above custom a few seconds to seconds threshold');\n\n    moment.relativeTimeThreshold('ss', 44);\n\n    // Minutes to hours threshold\n    moment.relativeTimeThreshold('m', 55);\n    a = moment();\n    a.subtract(54, 'minutes');\n    assert.equal(a.fromNow(), '54 minutes ago', 'Below custom minutes to hours threshold');\n    a.subtract(1, 'minutes');\n    assert.equal(a.fromNow(), 'an hour ago', 'Above custom minutes to hours threshold');\n    moment.relativeTimeThreshold('m', 45);\n\n    // Hours to days threshold\n    moment.relativeTimeThreshold('h', 24);\n    a = moment();\n    a.subtract(23, 'hours');\n    assert.equal(a.fromNow(), '23 hours ago', 'Below custom hours to days threshold');\n    a.subtract(1, 'hours');\n    assert.equal(a.fromNow(), 'a day ago', 'Above custom hours to days threshold');\n    moment.relativeTimeThreshold('h', 22);\n\n    // Days to month threshold\n    moment.relativeTimeThreshold('d', 28);\n    a = moment();\n    a.subtract(27, 'days');\n    assert.equal(a.fromNow(), '27 days ago', 'Below custom days to month (singular) threshold');\n    a.subtract(1, 'days');\n    assert.equal(a.fromNow(), 'a month ago', 'Above custom days to month (singular) threshold');\n    moment.relativeTimeThreshold('d', 26);\n\n    // months to years threshold\n    moment.relativeTimeThreshold('M', 9);\n    a = moment();\n    a.subtract(8, 'months');\n    assert.equal(a.fromNow(), '8 months ago', 'Below custom days to years threshold');\n    a.subtract(1, 'months');\n    assert.equal(a.fromNow(), 'a year ago', 'Above custom days to years threshold');\n    moment.relativeTimeThreshold('M', 11);\n});\n\ntest('custom rounding', function (assert) {\n    var roundingDefault = moment.relativeTimeRounding();\n\n    // Round relative time evaluation down\n    moment.relativeTimeRounding(Math.floor);\n\n    moment.relativeTimeThreshold('s', 60);\n    moment.relativeTimeThreshold('m', 60);\n    moment.relativeTimeThreshold('h', 24);\n    moment.relativeTimeThreshold('d', 27);\n    moment.relativeTimeThreshold('M', 12);\n\n    var a = moment.utc();\n    a.subtract({minutes: 59, seconds: 59});\n    assert.equal(a.toNow(), 'in 59 minutes', 'Round down towards the nearest minute');\n\n    a = moment.utc();\n    a.subtract({hours: 23, minutes: 59, seconds: 59});\n    assert.equal(a.toNow(), 'in 23 hours', 'Round down towards the nearest hour');\n\n    a = moment.utc();\n    a.subtract({days: 26, hours: 23, minutes: 59});\n    assert.equal(a.toNow(), 'in 26 days', 'Round down towards the nearest day (just under)');\n\n    a = moment.utc();\n    a.subtract({days: 27});\n    assert.equal(a.toNow(), 'in a month', 'Round down towards the nearest day (just over)');\n\n    a = moment.utc();\n    a.subtract({days: 364});\n    assert.equal(a.toNow(), 'in 11 months', 'Round down towards the nearest month');\n\n    a = moment.utc();\n    a.subtract({years: 1, days: 364});\n    assert.equal(a.toNow(), 'in a year', 'Round down towards the nearest year');\n\n    // Do not round relative time evaluation\n    var retainValue = function (value) {\n        return value.toFixed(3);\n    };\n    moment.relativeTimeRounding(retainValue);\n\n    a = moment.utc();\n    a.subtract({hours: 39});\n    assert.equal(a.toNow(), 'in 1.625 days', 'Round down towards the nearest year');\n\n    // Restore defaults\n    moment.relativeTimeThreshold('s', 45);\n    moment.relativeTimeThreshold('m', 45);\n    moment.relativeTimeThreshold('h', 22);\n    moment.relativeTimeThreshold('d', 26);\n    moment.relativeTimeThreshold('M', 11);\n    moment.relativeTimeRounding(roundingDefault);\n});\n\ntest('retrieve rounding settings', function (assert) {\n    moment.relativeTimeRounding(Math.round);\n    var roundingFunction = moment.relativeTimeRounding();\n\n    assert.equal(roundingFunction, Math.round, 'Can retrieve rounding setting');\n});\n\ntest('retrieve threshold settings', function (assert) {\n    moment.relativeTimeThreshold('m', 45);\n    var minuteThreshold = moment.relativeTimeThreshold('m');\n\n    assert.equal(minuteThreshold, 45, 'Can retrieve minute setting');\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\nfunction module$1 (name, lifecycle) {\n    QUnit.module(name, {\n        setup : function () {\n            moment.locale('en');\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'core');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            teardownDeprecationHandler(test, moment, 'core');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n}\n\nmodule$1('start and end of units');\n\ntest('start of year', function (assert) {\n    var m = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).startOf('year'),\n        ms = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).startOf('years'),\n        ma = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).startOf('y');\n    assert.equal(+m, +ms, 'Plural or singular should work');\n    assert.equal(+m, +ma, 'Full or abbreviated should work');\n    assert.equal(m.year(), 2011, 'keep the year');\n    assert.equal(m.month(), 0, 'strip out the month');\n    assert.equal(m.date(), 1, 'strip out the day');\n    assert.equal(m.hours(), 0, 'strip out the hours');\n    assert.equal(m.minutes(), 0, 'strip out the minutes');\n    assert.equal(m.seconds(), 0, 'strip out the seconds');\n    assert.equal(m.milliseconds(), 0, 'strip out the milliseconds');\n});\n\ntest('end of year', function (assert) {\n    var m = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).endOf('year'),\n        ms = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).endOf('years'),\n        ma = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).endOf('y');\n    assert.equal(+m, +ms, 'Plural or singular should work');\n    assert.equal(+m, +ma, 'Full or abbreviated should work');\n    assert.equal(m.year(), 2011, 'keep the year');\n    assert.equal(m.month(), 11, 'set the month');\n    assert.equal(m.date(), 31, 'set the day');\n    assert.equal(m.hours(), 23, 'set the hours');\n    assert.equal(m.minutes(), 59, 'set the minutes');\n    assert.equal(m.seconds(), 59, 'set the seconds');\n    assert.equal(m.milliseconds(), 999, 'set the seconds');\n});\n\ntest('start of quarter', function (assert) {\n    var m = moment(new Date(2011, 4, 2, 3, 4, 5, 6)).startOf('quarter'),\n        ms = moment(new Date(2011, 4, 2, 3, 4, 5, 6)).startOf('quarters'),\n        ma = moment(new Date(2011, 4, 2, 3, 4, 5, 6)).startOf('Q');\n    assert.equal(+m, +ms, 'Plural or singular should work');\n    assert.equal(+m, +ma, 'Full or abbreviated should work');\n    assert.equal(m.year(), 2011, 'keep the year');\n    assert.equal(m.quarter(), 2, 'keep the quarter');\n    assert.equal(m.month(), 3, 'strip out the month');\n    assert.equal(m.date(), 1, 'strip out the day');\n    assert.equal(m.hours(), 0, 'strip out the hours');\n    assert.equal(m.minutes(), 0, 'strip out the minutes');\n    assert.equal(m.seconds(), 0, 'strip out the seconds');\n    assert.equal(m.milliseconds(), 0, 'strip out the milliseconds');\n});\n\ntest('end of quarter', function (assert) {\n    var m = moment(new Date(2011, 4, 2, 3, 4, 5, 6)).endOf('quarter'),\n        ms = moment(new Date(2011, 4, 2, 3, 4, 5, 6)).endOf('quarters'),\n        ma = moment(new Date(2011, 4, 2, 3, 4, 5, 6)).endOf('Q');\n    assert.equal(+m, +ms, 'Plural or singular should work');\n    assert.equal(+m, +ma, 'Full or abbreviated should work');\n    assert.equal(m.year(), 2011, 'keep the year');\n    assert.equal(m.quarter(), 2, 'keep the quarter');\n    assert.equal(m.month(), 5, 'set the month');\n    assert.equal(m.date(), 30, 'set the day');\n    assert.equal(m.hours(), 23, 'set the hours');\n    assert.equal(m.minutes(), 59, 'set the minutes');\n    assert.equal(m.seconds(), 59, 'set the seconds');\n    assert.equal(m.milliseconds(), 999, 'set the seconds');\n});\n\ntest('start of month', function (assert) {\n    var m = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).startOf('month'),\n        ms = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).startOf('months'),\n        ma = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).startOf('M');\n    assert.equal(+m, +ms, 'Plural or singular should work');\n    assert.equal(+m, +ma, 'Full or abbreviated should work');\n    assert.equal(m.year(), 2011, 'keep the year');\n    assert.equal(m.month(), 1, 'keep the month');\n    assert.equal(m.date(), 1, 'strip out the day');\n    assert.equal(m.hours(), 0, 'strip out the hours');\n    assert.equal(m.minutes(), 0, 'strip out the minutes');\n    assert.equal(m.seconds(), 0, 'strip out the seconds');\n    assert.equal(m.milliseconds(), 0, 'strip out the milliseconds');\n});\n\ntest('end of month', function (assert) {\n    var m = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).endOf('month'),\n        ms = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).endOf('months'),\n        ma = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).endOf('M');\n    assert.equal(+m, +ms, 'Plural or singular should work');\n    assert.equal(+m, +ma, 'Full or abbreviated should work');\n    assert.equal(m.year(), 2011, 'keep the year');\n    assert.equal(m.month(), 1, 'keep the month');\n    assert.equal(m.date(), 28, 'set the day');\n    assert.equal(m.hours(), 23, 'set the hours');\n    assert.equal(m.minutes(), 59, 'set the minutes');\n    assert.equal(m.seconds(), 59, 'set the seconds');\n    assert.equal(m.milliseconds(), 999, 'set the seconds');\n});\n\ntest('start of week', function (assert) {\n    var m = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).startOf('week'),\n        ms = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).startOf('weeks'),\n        ma = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).startOf('w');\n    assert.equal(+m, +ms, 'Plural or singular should work');\n    assert.equal(+m, +ma, 'Full or abbreviated should work');\n    assert.equal(m.year(), 2011, 'keep the year');\n    assert.equal(m.month(), 0, 'rolls back to January');\n    assert.equal(m.day(), 0, 'set day of week');\n    assert.equal(m.date(), 30, 'set correct date');\n    assert.equal(m.hours(), 0, 'strip out the hours');\n    assert.equal(m.minutes(), 0, 'strip out the minutes');\n    assert.equal(m.seconds(), 0, 'strip out the seconds');\n    assert.equal(m.milliseconds(), 0, 'strip out the milliseconds');\n});\n\ntest('end of week', function (assert) {\n    var m = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).endOf('week'),\n        ms = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).endOf('weeks'),\n        ma = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).endOf('weeks');\n    assert.equal(+m, +ms, 'Plural or singular should work');\n    assert.equal(+m, +ma, 'Full or abbreviated should work');\n    assert.equal(m.year(), 2011, 'keep the year');\n    assert.equal(m.month(), 1, 'keep the month');\n    assert.equal(m.day(), 6, 'set the day of the week');\n    assert.equal(m.date(), 5, 'set the day');\n    assert.equal(m.hours(), 23, 'set the hours');\n    assert.equal(m.minutes(), 59, 'set the minutes');\n    assert.equal(m.seconds(), 59, 'set the seconds');\n    assert.equal(m.milliseconds(), 999, 'set the seconds');\n});\n\ntest('start of iso-week', function (assert) {\n    var m = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).startOf('isoWeek'),\n        ms = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).startOf('isoWeeks'),\n        ma = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).startOf('W');\n    assert.equal(+m, +ms, 'Plural or singular should work');\n    assert.equal(+m, +ma, 'Full or abbreviated should work');\n    assert.equal(m.year(), 2011, 'keep the year');\n    assert.equal(m.month(), 0, 'rollback to January');\n    assert.equal(m.isoWeekday(), 1, 'set day of iso-week');\n    assert.equal(m.date(), 31, 'set correct date');\n    assert.equal(m.hours(), 0, 'strip out the hours');\n    assert.equal(m.minutes(), 0, 'strip out the minutes');\n    assert.equal(m.seconds(), 0, 'strip out the seconds');\n    assert.equal(m.milliseconds(), 0, 'strip out the milliseconds');\n});\n\ntest('end of iso-week', function (assert) {\n    var m = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).endOf('isoWeek'),\n        ms = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).endOf('isoWeeks'),\n        ma = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).endOf('W');\n    assert.equal(+m, +ms, 'Plural or singular should work');\n    assert.equal(+m, +ma, 'Full or abbreviated should work');\n    assert.equal(m.year(), 2011, 'keep the year');\n    assert.equal(m.month(), 1, 'keep the month');\n    assert.equal(m.isoWeekday(), 7, 'set the day of the week');\n    assert.equal(m.date(), 6, 'set the day');\n    assert.equal(m.hours(), 23, 'set the hours');\n    assert.equal(m.minutes(), 59, 'set the minutes');\n    assert.equal(m.seconds(), 59, 'set the seconds');\n    assert.equal(m.milliseconds(), 999, 'set the seconds');\n});\n\ntest('start of day', function (assert) {\n    var m = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).startOf('day'),\n        ms = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).startOf('days'),\n        ma = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).startOf('d');\n    assert.equal(+m, +ms, 'Plural or singular should work');\n    assert.equal(+m, +ma, 'Full or abbreviated should work');\n    assert.equal(m.year(), 2011, 'keep the year');\n    assert.equal(m.month(), 1, 'keep the month');\n    assert.equal(m.date(), 2, 'keep the day');\n    assert.equal(m.hours(), 0, 'strip out the hours');\n    assert.equal(m.minutes(), 0, 'strip out the minutes');\n    assert.equal(m.seconds(), 0, 'strip out the seconds');\n    assert.equal(m.milliseconds(), 0, 'strip out the milliseconds');\n});\n\ntest('end of day', function (assert) {\n    var m = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).endOf('day'),\n        ms = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).endOf('days'),\n        ma = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).endOf('d');\n    assert.equal(+m, +ms, 'Plural or singular should work');\n    assert.equal(+m, +ma, 'Full or abbreviated should work');\n    assert.equal(m.year(), 2011, 'keep the year');\n    assert.equal(m.month(), 1, 'keep the month');\n    assert.equal(m.date(), 2, 'keep the day');\n    assert.equal(m.hours(), 23, 'set the hours');\n    assert.equal(m.minutes(), 59, 'set the minutes');\n    assert.equal(m.seconds(), 59, 'set the seconds');\n    assert.equal(m.milliseconds(), 999, 'set the seconds');\n});\n\ntest('start of date', function (assert) {\n    var m = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).startOf('date'),\n        ms = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).startOf('dates');\n\n    assert.equal(+m, +ms, 'Plural or singular should work');\n    assert.equal(m.year(), 2011, 'keep the year');\n    assert.equal(m.month(), 1, 'keep the month');\n    assert.equal(m.date(), 2, 'keep the day');\n    assert.equal(m.hours(), 0, 'strip out the hours');\n    assert.equal(m.minutes(), 0, 'strip out the minutes');\n    assert.equal(m.seconds(), 0, 'strip out the seconds');\n    assert.equal(m.milliseconds(), 0, 'strip out the milliseconds');\n});\n\ntest('end of date', function (assert) {\n    var m = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).endOf('date'),\n        ms = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).endOf('dates');\n\n    assert.equal(+m, +ms, 'Plural or singular should work');\n    assert.equal(m.year(), 2011, 'keep the year');\n    assert.equal(m.month(), 1, 'keep the month');\n    assert.equal(m.date(), 2, 'keep the day');\n    assert.equal(m.hours(), 23, 'set the hours');\n    assert.equal(m.minutes(), 59, 'set the minutes');\n    assert.equal(m.seconds(), 59, 'set the seconds');\n    assert.equal(m.milliseconds(), 999, 'set the seconds');\n});\n\n\ntest('start of hour', function (assert) {\n    var m = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).startOf('hour'),\n        ms = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).startOf('hours'),\n        ma = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).startOf('h');\n    assert.equal(+m, +ms, 'Plural or singular should work');\n    assert.equal(+m, +ma, 'Full or abbreviated should work');\n    assert.equal(m.year(), 2011, 'keep the year');\n    assert.equal(m.month(), 1, 'keep the month');\n    assert.equal(m.date(), 2, 'keep the day');\n    assert.equal(m.hours(), 3, 'keep the hours');\n    assert.equal(m.minutes(), 0, 'strip out the minutes');\n    assert.equal(m.seconds(), 0, 'strip out the seconds');\n    assert.equal(m.milliseconds(), 0, 'strip out the milliseconds');\n});\n\ntest('end of hour', function (assert) {\n    var m = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).endOf('hour'),\n        ms = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).endOf('hours'),\n        ma = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).endOf('h');\n    assert.equal(+m, +ms, 'Plural or singular should work');\n    assert.equal(+m, +ma, 'Full or abbreviated should work');\n    assert.equal(m.year(), 2011, 'keep the year');\n    assert.equal(m.month(), 1, 'keep the month');\n    assert.equal(m.date(), 2, 'keep the day');\n    assert.equal(m.hours(), 3, 'keep the hours');\n    assert.equal(m.minutes(), 59, 'set the minutes');\n    assert.equal(m.seconds(), 59, 'set the seconds');\n    assert.equal(m.milliseconds(), 999, 'set the seconds');\n});\n\ntest('start of minute', function (assert) {\n    var m = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).startOf('minute'),\n        ms = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).startOf('minutes'),\n        ma = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).startOf('m');\n    assert.equal(+m, +ms, 'Plural or singular should work');\n    assert.equal(+m, +ma, 'Full or abbreviated should work');\n    assert.equal(m.year(), 2011, 'keep the year');\n    assert.equal(m.month(), 1, 'keep the month');\n    assert.equal(m.date(), 2, 'keep the day');\n    assert.equal(m.hours(), 3, 'keep the hours');\n    assert.equal(m.minutes(), 4, 'keep the minutes');\n    assert.equal(m.seconds(), 0, 'strip out the seconds');\n    assert.equal(m.milliseconds(), 0, 'strip out the milliseconds');\n});\n\ntest('end of minute', function (assert) {\n    var m = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).endOf('minute'),\n        ms = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).endOf('minutes'),\n        ma = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).endOf('m');\n    assert.equal(+m, +ms, 'Plural or singular should work');\n    assert.equal(+m, +ma, 'Full or abbreviated should work');\n    assert.equal(m.year(), 2011, 'keep the year');\n    assert.equal(m.month(), 1, 'keep the month');\n    assert.equal(m.date(), 2, 'keep the day');\n    assert.equal(m.hours(), 3, 'keep the hours');\n    assert.equal(m.minutes(), 4, 'keep the minutes');\n    assert.equal(m.seconds(), 59, 'set the seconds');\n    assert.equal(m.milliseconds(), 999, 'set the seconds');\n});\n\ntest('start of second', function (assert) {\n    var m = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).startOf('second'),\n        ms = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).startOf('seconds'),\n        ma = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).startOf('s');\n    assert.equal(+m, +ms, 'Plural or singular should work');\n    assert.equal(+m, +ma, 'Full or abbreviated should work');\n    assert.equal(m.year(), 2011, 'keep the year');\n    assert.equal(m.month(), 1, 'keep the month');\n    assert.equal(m.date(), 2, 'keep the day');\n    assert.equal(m.hours(), 3, 'keep the hours');\n    assert.equal(m.minutes(), 4, 'keep the minutes');\n    assert.equal(m.seconds(), 5, 'keep the the seconds');\n    assert.equal(m.milliseconds(), 0, 'strip out the milliseconds');\n});\n\ntest('end of second', function (assert) {\n    var m = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).endOf('second'),\n        ms = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).endOf('seconds'),\n        ma = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).endOf('s');\n    assert.equal(+m, +ms, 'Plural or singular should work');\n    assert.equal(+m, +ma, 'Full or abbreviated should work');\n    assert.equal(m.year(), 2011, 'keep the year');\n    assert.equal(m.month(), 1, 'keep the month');\n    assert.equal(m.date(), 2, 'keep the day');\n    assert.equal(m.hours(), 3, 'keep the hours');\n    assert.equal(m.minutes(), 4, 'keep the minutes');\n    assert.equal(m.seconds(), 5, 'keep the seconds');\n    assert.equal(m.milliseconds(), 999, 'set the seconds');\n});\n\ntest('startOf across DST +1', function (assert) {\n    var oldUpdateOffset = moment.updateOffset,\n        // Based on a real story somewhere in America/Los_Angeles\n        dstAt = moment('2014-03-09T02:00:00-08:00').parseZone(),\n        m;\n\n    moment.updateOffset = function (mom, keepTime) {\n        if (mom.isBefore(dstAt)) {\n            mom.utcOffset(-8, keepTime);\n        } else {\n            mom.utcOffset(-7, keepTime);\n        }\n    };\n\n    m = moment('2014-03-15T00:00:00-07:00').parseZone();\n    m.startOf('y');\n    assert.equal(m.format(), '2014-01-01T00:00:00-08:00', 'startOf(\\'year\\') across +1');\n\n    m = moment('2014-03-15T00:00:00-07:00').parseZone();\n    m.startOf('M');\n    assert.equal(m.format(), '2014-03-01T00:00:00-08:00', 'startOf(\\'month\\') across +1');\n\n    m = moment('2014-03-09T09:00:00-07:00').parseZone();\n    m.startOf('d');\n    assert.equal(m.format(), '2014-03-09T00:00:00-08:00', 'startOf(\\'day\\') across +1');\n\n    m = moment('2014-03-09T03:05:00-07:00').parseZone();\n    m.startOf('h');\n    assert.equal(m.format(), '2014-03-09T03:00:00-07:00', 'startOf(\\'hour\\') after +1');\n\n    m = moment('2014-03-09T01:35:00-08:00').parseZone();\n    m.startOf('h');\n    assert.equal(m.format(), '2014-03-09T01:00:00-08:00', 'startOf(\\'hour\\') before +1');\n\n    // There is no such time as 2:30-7 to try startOf('hour') across that\n\n    moment.updateOffset = oldUpdateOffset;\n});\n\ntest('startOf across DST -1', function (assert) {\n    var oldUpdateOffset = moment.updateOffset,\n        // Based on a real story somewhere in America/Los_Angeles\n        dstAt = moment('2014-11-02T02:00:00-07:00').parseZone(),\n        m;\n\n    moment.updateOffset = function (mom, keepTime) {\n        if (mom.isBefore(dstAt)) {\n            mom.utcOffset(-7, keepTime);\n        } else {\n            mom.utcOffset(-8, keepTime);\n        }\n    };\n\n    m = moment('2014-11-15T00:00:00-08:00').parseZone();\n    m.startOf('y');\n    assert.equal(m.format(), '2014-01-01T00:00:00-07:00', 'startOf(\\'year\\') across -1');\n\n    m = moment('2014-11-15T00:00:00-08:00').parseZone();\n    m.startOf('M');\n    assert.equal(m.format(), '2014-11-01T00:00:00-07:00', 'startOf(\\'month\\') across -1');\n\n    m = moment('2014-11-02T09:00:00-08:00').parseZone();\n    m.startOf('d');\n    assert.equal(m.format(), '2014-11-02T00:00:00-07:00', 'startOf(\\'day\\') across -1');\n\n    // note that utc offset is -8\n    m = moment('2014-11-02T01:30:00-08:00').parseZone();\n    m.startOf('h');\n    assert.equal(m.format(), '2014-11-02T01:00:00-08:00', 'startOf(\\'hour\\') after +1');\n\n    // note that utc offset is -7\n    m = moment('2014-11-02T01:30:00-07:00').parseZone();\n    m.startOf('h');\n    assert.equal(m.format(), '2014-11-02T01:00:00-07:00', 'startOf(\\'hour\\') before +1');\n\n    moment.updateOffset = oldUpdateOffset;\n});\n\ntest('endOf millisecond and no-arg', function (assert) {\n    var m = moment();\n    assert.equal(+m, +m.clone().endOf(), 'endOf without argument should change time');\n    assert.equal(+m, +m.clone().endOf('ms'), 'endOf with ms argument should change time');\n    assert.equal(+m, +m.clone().endOf('millisecond'), 'endOf with millisecond argument should change time');\n    assert.equal(+m, +m.clone().endOf('milliseconds'), 'endOf with milliseconds argument should change time');\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\nfunction module$1 (name, lifecycle) {\n    QUnit.module(name, {\n        setup : function () {\n            moment.locale('en');\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'core');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            teardownDeprecationHandler(test, moment, 'core');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n}\n\nmodule$1('string prototype');\n\ntest('string prototype overrides call', function (assert) {\n    var prior = String.prototype.call, b;\n    String.prototype.call = function () {\n        return null;\n    };\n\n    b = moment(new Date(2011, 7, 28, 15, 25, 50, 125));\n    assert.equal(b.format('MMMM Do YYYY, h:mm a'), 'August 28th 2011, 3:25 pm');\n\n    String.prototype.call = prior;\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\nfunction module$1 (name, lifecycle) {\n    QUnit.module(name, {\n        setup : function () {\n            moment.locale('en');\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'core');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            teardownDeprecationHandler(test, moment, 'core');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n}\n\nmodule$1('to type');\n\ntest('toObject', function (assert) {\n    var expected = {\n        years:2010,\n        months:3,\n        date:5,\n        hours:15,\n        minutes:10,\n        seconds:3,\n        milliseconds:123\n    };\n    assert.deepEqual(moment(expected).toObject(), expected, 'toObject invalid');\n});\n\ntest('toArray', function (assert) {\n    var expected = [2014, 11, 26, 11, 46, 58, 17];\n    assert.deepEqual(moment(expected).toArray(), expected, 'toArray invalid');\n});\n\ntest('toDate returns a copy of the internal date', function (assert) {\n    var m = moment();\n    var d = m.toDate();\n    m.year(0);\n    assert.notEqual(d, m.toDate());\n});\n\ntest('toJSON', function (assert) {\n    if (Date.prototype.toISOString) {\n        var expected = new Date().toISOString();\n        assert.deepEqual(moment(expected).toJSON(), expected, 'toJSON invalid');\n    } else {\n        // IE8\n        expect(0);\n    }\n});\n\ntest('toJSON works when moment is frozen', function (assert) {\n    if (Date.prototype.toISOString) {\n        var expected = new Date().toISOString();\n        var m = moment(expected);\n        if (Object.freeze != null) {\n            Object.freeze(m);\n        }\n        assert.deepEqual(m.toJSON(), expected, 'toJSON when frozen invalid');\n    } else {\n        // IE8\n        expect(0);\n    }\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\nfunction module$1 (name, lifecycle) {\n    QUnit.module(name, {\n        setup : function () {\n            moment.locale('en');\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'core');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            teardownDeprecationHandler(test, moment, 'core');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n}\n\nmodule$1('utc');\n\ntest('utc and local', function (assert) {\n    var m = moment(Date.UTC(2011, 1, 2, 3, 4, 5, 6)), offset, expected;\n    m.utc();\n    // utc\n    assert.equal(m.date(), 2, 'the day should be correct for utc');\n    assert.equal(m.day(), 3, 'the date should be correct for utc');\n    assert.equal(m.hours(), 3, 'the hours should be correct for utc');\n\n    // local\n    m.local();\n    if (m.utcOffset() < -180) {\n        assert.equal(m.date(), 1, 'the date should be correct for local');\n        assert.equal(m.day(), 2, 'the day should be correct for local');\n    } else {\n        assert.equal(m.date(), 2, 'the date should be correct for local');\n        assert.equal(m.day(), 3, 'the day should be correct for local');\n    }\n    offset = Math.floor(m.utcOffset() / 60);\n    expected = (24 + 3 + offset) % 24;\n    assert.equal(m.hours(), expected, 'the hours (' + m.hours() + ') should be correct for local');\n    assert.equal(moment().utc().utcOffset(), 0, 'timezone in utc should always be zero');\n});\n\ntest('creating with utc and no arguments', function (assert) {\n    var startOfTest = new Date().valueOf(),\n        momentDefaultUtcTime = moment.utc().valueOf(),\n        afterMomentCreationTime = new Date().valueOf();\n\n    assert.ok(startOfTest <= momentDefaultUtcTime, 'moment UTC default time should be now, not in the past');\n    assert.ok(momentDefaultUtcTime <= afterMomentCreationTime, 'moment UTC default time should be now, not in the future');\n});\n\ntest('creating with utc and a date parameter array', function (assert) {\n    var m = moment.utc([2011, 1, 2, 3, 4, 5, 6]);\n    assert.equal(m.date(), 2, 'the day should be correct for utc array');\n    assert.equal(m.hours(), 3, 'the hours should be correct for utc array');\n\n    m = moment.utc('2011-02-02 3:04:05', 'YYYY-MM-DD HH:mm:ss');\n    assert.equal(m.date(), 2, 'the day should be correct for utc parsing format');\n    assert.equal(m.hours(), 3, 'the hours should be correct for utc parsing format');\n\n    m = moment.utc('2011-02-02T03:04:05+00:00');\n    assert.equal(m.date(), 2, 'the day should be correct for utc parsing iso');\n    assert.equal(m.hours(), 3, 'the hours should be correct for utc parsing iso');\n});\n\ntest('creating with utc without timezone', function (assert) {\n    var m = moment.utc('2012-01-02T08:20:00');\n    assert.equal(m.date(), 2, 'the day should be correct for utc parse without timezone');\n    assert.equal(m.hours(), 8, 'the hours should be correct for utc parse without timezone');\n\n    m = moment.utc('2012-01-02T08:20:00+09:00');\n    assert.equal(m.date(), 1, 'the day should be correct for utc parse with timezone');\n    assert.equal(m.hours(), 23, 'the hours should be correct for utc parse with timezone');\n});\n\ntest('cloning with utc offset', function (assert) {\n    var m = moment.utc('2012-01-02T08:20:00');\n    assert.equal(moment.utc(m)._isUTC, true, 'the local offset should be converted to UTC');\n    assert.equal(moment.utc(m.clone().utc())._isUTC, true, 'the local offset should stay in UTC');\n\n    m.utcOffset(120);\n    assert.equal(moment.utc(m)._isUTC, true, 'the explicit utc offset should stay in UTC');\n    assert.equal(moment.utc(m).utcOffset(), 0, 'the explicit utc offset should have an offset of 0');\n});\n\ntest('weekday with utc', function (assert) {\n    assert.equal(\n        moment('2013-09-15T00:00:00Z').utc().weekday(), // first minute of the day\n        moment('2013-09-15T23:59:00Z').utc().weekday(), // last minute of the day\n        'a UTC-moment\\'s .weekday() should not be affected by the local timezone'\n    );\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\nfunction module$1 (name, lifecycle) {\n    QUnit.module(name, {\n        setup : function () {\n            moment.locale('en');\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'core');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            teardownDeprecationHandler(test, moment, 'core');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n}\n\nmodule$1('utc offset');\n\ntest('setter / getter blackbox', function (assert) {\n    var m = moment([2010]);\n\n    assert.equal(m.clone().utcOffset(0).utcOffset(), 0, 'utcOffset 0');\n\n    assert.equal(m.clone().utcOffset(1).utcOffset(), 60, 'utcOffset 1 is 60');\n    assert.equal(m.clone().utcOffset(60).utcOffset(), 60, 'utcOffset 60');\n    assert.equal(m.clone().utcOffset('+01:00').utcOffset(), 60, 'utcOffset +01:00 is 60');\n    assert.equal(m.clone().utcOffset('+0100').utcOffset(), 60, 'utcOffset +0100 is 60');\n\n    assert.equal(m.clone().utcOffset(-1).utcOffset(), -60, 'utcOffset -1 is -60');\n    assert.equal(m.clone().utcOffset(-60).utcOffset(), -60, 'utcOffset -60');\n    assert.equal(m.clone().utcOffset('-01:00').utcOffset(), -60, 'utcOffset -01:00 is -60');\n    assert.equal(m.clone().utcOffset('-0100').utcOffset(), -60, 'utcOffset -0100 is -60');\n\n    assert.equal(m.clone().utcOffset(1.5).utcOffset(), 90, 'utcOffset 1.5 is 90');\n    assert.equal(m.clone().utcOffset(90).utcOffset(), 90, 'utcOffset 1.5 is 90');\n    assert.equal(m.clone().utcOffset('+01:30').utcOffset(), 90, 'utcOffset +01:30 is 90');\n    assert.equal(m.clone().utcOffset('+0130').utcOffset(), 90, 'utcOffset +0130 is 90');\n\n    assert.equal(m.clone().utcOffset(-1.5).utcOffset(), -90, 'utcOffset -1.5');\n    assert.equal(m.clone().utcOffset(-90).utcOffset(), -90, 'utcOffset -90');\n    assert.equal(m.clone().utcOffset('-01:30').utcOffset(), -90, 'utcOffset +01:30 is 90');\n    assert.equal(m.clone().utcOffset('-0130').utcOffset(), -90, 'utcOffset +0130 is 90');\n    assert.equal(m.clone().utcOffset('+00:10').utcOffset(), 10, 'utcOffset +00:10 is 10');\n    assert.equal(m.clone().utcOffset('-00:10').utcOffset(), -10, 'utcOffset +00:10 is 10');\n    assert.equal(m.clone().utcOffset('+0010').utcOffset(), 10, 'utcOffset +0010 is 10');\n    assert.equal(m.clone().utcOffset('-0010').utcOffset(), -10, 'utcOffset +0010 is 10');\n});\n\ntest('utcOffset shorthand hours -> minutes', function (assert) {\n    var i;\n    for (i = -15; i <= 15; ++i) {\n        assert.equal(moment().utcOffset(i).utcOffset(), i * 60,\n                '' + i + ' -> ' + i * 60);\n    }\n    assert.equal(moment().utcOffset(-16).utcOffset(), -16, '-16 -> -16');\n    assert.equal(moment().utcOffset(16).utcOffset(), 16, '16 -> 16');\n});\n\ntest('isLocal, isUtc, isUtcOffset', function (assert) {\n    assert.ok(moment().isLocal(), 'moment() creates objects in local time');\n    assert.ok(!moment.utc().isLocal(), 'moment.utc creates objects NOT in local time');\n    assert.ok(moment.utc().local().isLocal(), 'moment.fn.local() converts to local time');\n    assert.ok(!moment().utcOffset(5).isLocal(), 'moment.fn.utcOffset(N) puts objects NOT in local time');\n    assert.ok(moment().utcOffset(5).local().isLocal(), 'moment.fn.local() converts to local time');\n\n    assert.ok(moment.utc().isUtc(), 'moment.utc() creates objects in utc time');\n    assert.ok(moment().utcOffset(0).isUtc(), 'utcOffset(0) is equivalent to utc mode');\n    assert.ok(!moment().utcOffset(1).isUtc(), 'utcOffset(1) is NOT equivalent to utc mode');\n\n    assert.ok(!moment().isUtcOffset(), 'moment() creates objects NOT in utc-offset mode');\n    assert.ok(moment.utc().isUtcOffset(), 'moment.utc() creates objects in utc-offset mode');\n    assert.ok(moment().utcOffset(3).isUtcOffset(), 'utcOffset(N != 0) creates objects in utc-offset mode');\n    assert.ok(moment().utcOffset(0).isUtcOffset(), 'utcOffset(0) creates objects in utc-offset mode');\n});\n\ntest('isUTC', function (assert) {\n    assert.ok(moment.utc().isUTC(), 'moment.utc() creates objects in utc time');\n    assert.ok(moment().utcOffset(0).isUTC(), 'utcOffset(0) is equivalent to utc mode');\n    assert.ok(!moment().utcOffset(1).isUTC(), 'utcOffset(1) is NOT equivalent to utc mode');\n});\n\ntest('change hours when changing the utc offset', function (assert) {\n    var m = moment.utc([2000, 0, 1, 6]);\n    assert.equal(m.hour(), 6, 'UTC 6AM should be 6AM at +0000');\n\n    // sanity check\n    m.utcOffset(0);\n    assert.equal(m.hour(), 6, 'UTC 6AM should be 6AM at +0000');\n\n    m.utcOffset(-60);\n    assert.equal(m.hour(), 5, 'UTC 6AM should be 5AM at -0100');\n\n    m.utcOffset(60);\n    assert.equal(m.hour(), 7, 'UTC 6AM should be 7AM at +0100');\n});\n\ntest('change minutes when changing the utc offset', function (assert) {\n    var m = moment.utc([2000, 0, 1, 6, 31]);\n\n    m.utcOffset(0);\n    assert.equal(m.format('HH:mm'), '06:31', 'UTC 6:31AM should be 6:31AM at +0000');\n\n    m.utcOffset(-30);\n    assert.equal(m.format('HH:mm'), '06:01', 'UTC 6:31AM should be 6:01AM at -0030');\n\n    m.utcOffset(30);\n    assert.equal(m.format('HH:mm'), '07:01', 'UTC 6:31AM should be 7:01AM at +0030');\n\n    m.utcOffset(-1380);\n    assert.equal(m.format('HH:mm'), '07:31', 'UTC 6:31AM should be 7:31AM at +1380');\n});\n\ntest('distance from the unix epoch', function (assert) {\n    var zoneA = moment(),\n        zoneB = moment(zoneA),\n        zoneC = moment(zoneA),\n        zoneD = moment(zoneA),\n        zoneE = moment(zoneA);\n\n    zoneB.utc();\n    assert.equal(+zoneA, +zoneB, 'moment should equal moment.utc');\n\n    zoneC.utcOffset(60);\n    assert.equal(+zoneA, +zoneC, 'moment should equal moment.utcOffset(60)');\n\n    zoneD.utcOffset(-480);\n    assert.equal(+zoneA, +zoneD,\n            'moment should equal moment.utcOffset(-480)');\n\n    zoneE.utcOffset(-1000);\n    assert.equal(+zoneA, +zoneE,\n            'moment should equal moment.utcOffset(-1000)');\n});\n\ntest('update offset after changing any values', function (assert) {\n    var oldOffset = moment.updateOffset,\n        m = moment.utc([2000, 6, 1]);\n\n    moment.updateOffset = function (mom, keepTime) {\n        if (mom.__doChange) {\n            if (+mom > 962409600000) {\n                mom.utcOffset(-120, keepTime);\n            } else {\n                mom.utcOffset(-60, keepTime);\n            }\n        }\n    };\n\n    assert.equal(m.format('ZZ'), '+0000', 'should be at +0000');\n    assert.equal(m.format('HH:mm'), '00:00', 'should start 12AM at +0000 timezone');\n\n    m.__doChange = true;\n    m.add(1, 'h');\n\n    assert.equal(m.format('ZZ'), '-0200', 'should be at -0200');\n    assert.equal(m.format('HH:mm'), '23:00', '1AM at +0000 should be 11PM at -0200 timezone');\n\n    m.subtract(1, 'h');\n\n    assert.equal(m.format('ZZ'), '-0100', 'should be at -0100');\n    assert.equal(m.format('HH:mm'), '23:00', '12AM at +0000 should be 11PM at -0100 timezone');\n\n    moment.updateOffset = oldOffset;\n});\n\n//////////////////\ntest('getters and setters', function (assert) {\n    var a = moment([2011, 5, 20]);\n\n    assert.equal(a.clone().utcOffset(-120).year(2012).year(), 2012, 'should get and set year correctly');\n    assert.equal(a.clone().utcOffset(-120).month(1).month(), 1, 'should get and set month correctly');\n    assert.equal(a.clone().utcOffset(-120).date(2).date(), 2, 'should get and set date correctly');\n    assert.equal(a.clone().utcOffset(-120).day(1).day(), 1, 'should get and set day correctly');\n    assert.equal(a.clone().utcOffset(-120).hour(1).hour(), 1, 'should get and set hour correctly');\n    assert.equal(a.clone().utcOffset(-120).minute(1).minute(), 1, 'should get and set minute correctly');\n});\n\ntest('getters', function (assert) {\n    var a = moment.utc([2012, 0, 1, 0, 0, 0]);\n\n    assert.equal(a.clone().utcOffset(-120).year(),  2011, 'should get year correctly');\n    assert.equal(a.clone().utcOffset(-120).month(),   11, 'should get month correctly');\n    assert.equal(a.clone().utcOffset(-120).date(),    31, 'should get date correctly');\n    assert.equal(a.clone().utcOffset(-120).hour(),    22, 'should get hour correctly');\n    assert.equal(a.clone().utcOffset(-120).minute(),   0, 'should get minute correctly');\n\n    assert.equal(a.clone().utcOffset(120).year(),  2012, 'should get year correctly');\n    assert.equal(a.clone().utcOffset(120).month(),    0, 'should get month correctly');\n    assert.equal(a.clone().utcOffset(120).date(),     1, 'should get date correctly');\n    assert.equal(a.clone().utcOffset(120).hour(),     2, 'should get hour correctly');\n    assert.equal(a.clone().utcOffset(120).minute(),   0, 'should get minute correctly');\n\n    assert.equal(a.clone().utcOffset(90).year(),  2012, 'should get year correctly');\n    assert.equal(a.clone().utcOffset(90).month(),    0, 'should get month correctly');\n    assert.equal(a.clone().utcOffset(90).date(),     1, 'should get date correctly');\n    assert.equal(a.clone().utcOffset(90).hour(),     1, 'should get hour correctly');\n    assert.equal(a.clone().utcOffset(90).minute(),  30, 'should get minute correctly');\n});\n\ntest('from', function (assert) {\n    var zoneA = moment(),\n        zoneB = moment(zoneA).utcOffset(-720),\n        zoneC = moment(zoneA).utcOffset(-360),\n        zoneD = moment(zoneA).utcOffset(690),\n        other = moment(zoneA).add(35, 'm');\n\n    assert.equal(zoneA.from(other), zoneB.from(other), 'moment#from should be the same in all zones');\n    assert.equal(zoneA.from(other), zoneC.from(other), 'moment#from should be the same in all zones');\n    assert.equal(zoneA.from(other), zoneD.from(other), 'moment#from should be the same in all zones');\n});\n\ntest('diff', function (assert) {\n    var zoneA = moment(),\n        zoneB = moment(zoneA).utcOffset(-720),\n        zoneC = moment(zoneA).utcOffset(-360),\n        zoneD = moment(zoneA).utcOffset(690),\n        other = moment(zoneA).add(35, 'm');\n\n    assert.equal(zoneA.diff(other), zoneB.diff(other), 'moment#diff should be the same in all zones');\n    assert.equal(zoneA.diff(other), zoneC.diff(other), 'moment#diff should be the same in all zones');\n    assert.equal(zoneA.diff(other), zoneD.diff(other), 'moment#diff should be the same in all zones');\n\n    assert.equal(zoneA.diff(other, 'minute', true), zoneB.diff(other, 'minute', true), 'moment#diff should be the same in all zones');\n    assert.equal(zoneA.diff(other, 'minute', true), zoneC.diff(other, 'minute', true), 'moment#diff should be the same in all zones');\n    assert.equal(zoneA.diff(other, 'minute', true), zoneD.diff(other, 'minute', true), 'moment#diff should be the same in all zones');\n\n    assert.equal(zoneA.diff(other, 'hour', true), zoneB.diff(other, 'hour', true), 'moment#diff should be the same in all zones');\n    assert.equal(zoneA.diff(other, 'hour', true), zoneC.diff(other, 'hour', true), 'moment#diff should be the same in all zones');\n    assert.equal(zoneA.diff(other, 'hour', true), zoneD.diff(other, 'hour', true), 'moment#diff should be the same in all zones');\n});\n\ntest('unix offset and timestamp', function (assert) {\n    var zoneA = moment(),\n        zoneB = moment(zoneA).utcOffset(-720),\n        zoneC = moment(zoneA).utcOffset(-360),\n        zoneD = moment(zoneA).utcOffset(690);\n\n    assert.equal(zoneA.unix(), zoneB.unix(), 'moment#unix should be the same in all zones');\n    assert.equal(zoneA.unix(), zoneC.unix(), 'moment#unix should be the same in all zones');\n    assert.equal(zoneA.unix(), zoneD.unix(), 'moment#unix should be the same in all zones');\n\n    assert.equal(+zoneA, +zoneB, 'moment#valueOf should be the same in all zones');\n    assert.equal(+zoneA, +zoneC, 'moment#valueOf should be the same in all zones');\n    assert.equal(+zoneA, +zoneD, 'moment#valueOf should be the same in all zones');\n});\n\ntest('cloning', function (assert) {\n    assert.equal(moment().utcOffset(-120).clone().utcOffset(), -120,\n            'explicit cloning should retain the offset');\n    assert.equal(moment().utcOffset(120).clone().utcOffset(), 120,\n            'explicit cloning should retain the offset');\n    assert.equal(moment(moment().utcOffset(-120)).utcOffset(), -120,\n            'implicit cloning should retain the offset');\n    assert.equal(moment(moment().utcOffset(120)).utcOffset(), 120,\n            'implicit cloning should retain the offset');\n});\n\ntest('start of / end of', function (assert) {\n    var a = moment.utc([2010, 1, 2, 0, 0, 0]).utcOffset(-450);\n\n    assert.equal(a.clone().startOf('day').hour(), 0,\n            'start of day should work on moments with utc offset');\n    assert.equal(a.clone().startOf('day').minute(), 0,\n            'start of day should work on moments with utc offset');\n    assert.equal(a.clone().startOf('hour').minute(), 0,\n            'start of hour should work on moments with utc offset');\n\n    assert.equal(a.clone().endOf('day').hour(), 23,\n            'end of day should work on moments with utc offset');\n    assert.equal(a.clone().endOf('day').minute(), 59,\n            'end of day should work on moments with utc offset');\n    assert.equal(a.clone().endOf('hour').minute(), 59,\n            'end of hour should work on moments with utc offset');\n});\n\ntest('reset offset with moment#utc', function (assert) {\n    var a = moment.utc([2012]).utcOffset(-480);\n\n    assert.equal(a.clone().hour(),      16, 'different utc offset should have different hour');\n    assert.equal(a.clone().utc().hour(), 0, 'calling moment#utc should reset the offset');\n});\n\ntest('reset offset with moment#local', function (assert) {\n    var a = moment([2012]).utcOffset(-480);\n\n    assert.equal(a.clone().local().hour(), 0, 'calling moment#local should reset the offset');\n});\n\ntest('toDate', function (assert) {\n    var zoneA = new Date(),\n        zoneB = moment(zoneA).utcOffset(-720).toDate(),\n        zoneC = moment(zoneA).utcOffset(-360).toDate(),\n        zoneD = moment(zoneA).utcOffset(690).toDate();\n\n    assert.equal(+zoneA, +zoneB, 'moment#toDate should output a date with the right unix timestamp');\n    assert.equal(+zoneA, +zoneC, 'moment#toDate should output a date with the right unix timestamp');\n    assert.equal(+zoneA, +zoneD, 'moment#toDate should output a date with the right unix timestamp');\n});\n\ntest('same / before / after', function (assert) {\n    var zoneA = moment().utc(),\n        zoneB = moment(zoneA).utcOffset(-120),\n        zoneC = moment(zoneA).utcOffset(120);\n\n    assert.ok(zoneA.isSame(zoneB), 'two moments with different offsets should be the same');\n    assert.ok(zoneA.isSame(zoneC), 'two moments with different offsets should be the same');\n\n    assert.ok(zoneA.isSame(zoneB, 'hour'), 'two moments with different offsets should be the same hour');\n    assert.ok(zoneA.isSame(zoneC, 'hour'), 'two moments with different offsets should be the same hour');\n\n    zoneA.add(1, 'hour');\n\n    assert.ok(zoneA.isAfter(zoneB), 'isAfter should work with two moments with different offsets');\n    assert.ok(zoneA.isAfter(zoneC), 'isAfter should work with two moments with different offsets');\n\n    assert.ok(zoneA.isAfter(zoneB, 'hour'), 'isAfter:hour should work with two moments with different offsets');\n    assert.ok(zoneA.isAfter(zoneC, 'hour'), 'isAfter:hour should work with two moments with different offsets');\n\n    zoneA.subtract(2, 'hour');\n\n    assert.ok(zoneA.isBefore(zoneB), 'isBefore should work with two moments with different offsets');\n    assert.ok(zoneA.isBefore(zoneC), 'isBefore should work with two moments with different offsets');\n\n    assert.ok(zoneA.isBefore(zoneB, 'hour'), 'isBefore:hour should work with two moments with different offsets');\n    assert.ok(zoneA.isBefore(zoneC, 'hour'), 'isBefore:hour should work with two moments with different offsets');\n});\n\ntest('add / subtract over dst', function (assert) {\n    var oldOffset = moment.updateOffset,\n        m = moment.utc([2000, 2, 31, 3]);\n\n    moment.updateOffset = function (mom, keepTime) {\n        if (mom.clone().utc().month() > 2) {\n            mom.utcOffset(60, keepTime);\n        } else {\n            mom.utcOffset(0, keepTime);\n        }\n    };\n\n    assert.equal(m.hour(), 3, 'should start at 00:00');\n\n    m.add(24, 'hour');\n\n    assert.equal(m.hour(), 4, 'adding 24 hours should disregard dst');\n\n    m.subtract(24, 'hour');\n\n    assert.equal(m.hour(), 3, 'subtracting 24 hours should disregard dst');\n\n    m.add(1, 'day');\n\n    assert.equal(m.hour(), 3, 'adding 1 day should have the same hour');\n\n    m.subtract(1, 'day');\n\n    assert.equal(m.hour(), 3, 'subtracting 1 day should have the same hour');\n\n    m.add(1, 'month');\n\n    assert.equal(m.hour(), 3, 'adding 1 month should have the same hour');\n\n    m.subtract(1, 'month');\n\n    assert.equal(m.hour(), 3, 'subtracting 1 month should have the same hour');\n\n    moment.updateOffset = oldOffset;\n});\n\ntest('isDST', function (assert) {\n    var oldOffset = moment.updateOffset;\n\n    moment.updateOffset = function (mom, keepTime) {\n        if (mom.month() > 2 && mom.month() < 9) {\n            mom.utcOffset(60, keepTime);\n        } else {\n            mom.utcOffset(0, keepTime);\n        }\n    };\n\n    assert.ok(!moment().month(0).isDST(),  'Jan should not be summer dst');\n    assert.ok(moment().month(6).isDST(),   'Jul should be summer dst');\n    assert.ok(!moment().month(11).isDST(), 'Dec should not be summer dst');\n\n    moment.updateOffset = function (mom) {\n        if (mom.month() > 2 && mom.month() < 9) {\n            mom.utcOffset(0);\n        } else {\n            mom.utcOffset(60);\n        }\n    };\n\n    assert.ok(moment().month(0).isDST(),  'Jan should be winter dst');\n    assert.ok(!moment().month(6).isDST(), 'Jul should not be winter dst');\n    assert.ok(moment().month(11).isDST(), 'Dec should be winter dst');\n\n    moment.updateOffset = oldOffset;\n});\n\ntest('zone names', function (assert) {\n    assert.equal(moment().zoneAbbr(),   '', 'Local zone abbr should be empty');\n    assert.equal(moment().format('z'),  '', 'Local zone formatted abbr should be empty');\n    assert.equal(moment().zoneName(),   '', 'Local zone name should be empty');\n    assert.equal(moment().format('zz'), '', 'Local zone formatted name should be empty');\n\n    assert.equal(moment.utc().zoneAbbr(),   'UTC', 'UTC zone abbr should be UTC');\n    assert.equal(moment.utc().format('z'),  'UTC', 'UTC zone formatted abbr should be UTC');\n    assert.equal(moment.utc().zoneName(),   'Coordinated Universal Time', 'UTC zone abbr should be Coordinated Universal Time');\n    assert.equal(moment.utc().format('zz'), 'Coordinated Universal Time', 'UTC zone formatted abbr should be Coordinated Universal Time');\n});\n\ntest('hours alignment with UTC', function (assert) {\n    assert.equal(moment().utcOffset(-120).hasAlignedHourOffset(), true);\n    assert.equal(moment().utcOffset(180).hasAlignedHourOffset(), true);\n    assert.equal(moment().utcOffset(-90).hasAlignedHourOffset(), false);\n    assert.equal(moment().utcOffset(90).hasAlignedHourOffset(), false);\n});\n\ntest('hours alignment with other zone', function (assert) {\n    var m = moment().utcOffset(-120);\n\n    assert.equal(m.hasAlignedHourOffset(moment().utcOffset(-180)), true);\n    assert.equal(m.hasAlignedHourOffset(moment().utcOffset(180)), true);\n    assert.equal(m.hasAlignedHourOffset(moment().utcOffset(-90)), false);\n    assert.equal(m.hasAlignedHourOffset(moment().utcOffset(90)), false);\n\n    m = moment().utcOffset(-90);\n\n    assert.equal(m.hasAlignedHourOffset(moment().utcOffset(-180)), false);\n    assert.equal(m.hasAlignedHourOffset(moment().utcOffset(180)), false);\n    assert.equal(m.hasAlignedHourOffset(moment().utcOffset(-30)), true);\n    assert.equal(m.hasAlignedHourOffset(moment().utcOffset(30)), true);\n\n    m = moment().utcOffset(60);\n\n    assert.equal(m.hasAlignedHourOffset(moment().utcOffset(-180)), true);\n    assert.equal(m.hasAlignedHourOffset(moment().utcOffset(180)), true);\n    assert.equal(m.hasAlignedHourOffset(moment().utcOffset(-90)), false);\n    assert.equal(m.hasAlignedHourOffset(moment().utcOffset(90)), false);\n\n    m = moment().utcOffset(-25);\n\n    assert.equal(m.hasAlignedHourOffset(moment().utcOffset(35)), true);\n    assert.equal(m.hasAlignedHourOffset(moment().utcOffset(-85)), true);\n\n    assert.equal(m.hasAlignedHourOffset(moment().utcOffset(-35)), false);\n    assert.equal(m.hasAlignedHourOffset(moment().utcOffset(85)), false);\n});\n\ntest('parse zone', function (assert) {\n    var m = moment('2013-01-01T00:00:00-13:00').parseZone();\n    assert.equal(m.utcOffset(), -13 * 60);\n    assert.equal(m.hours(), 0);\n});\n\ntest('parse UTC zone', function (assert) {\n    var m = moment('2013-01-01T05:00:00+00:00').parseZone();\n    assert.equal(m.utcOffset(), 0);\n    assert.equal(m.hours(), 5);\n});\n\ntest('parse zone static', function (assert) {\n    var m = moment.parseZone('2013-01-01T00:00:00-13:00');\n    assert.equal(m.utcOffset(), -13 * 60);\n    assert.equal(m.hours(), 0);\n});\n\ntest('parse zone with more arguments', function (assert) {\n    var m;\n    m = moment.parseZone('2013 01 01 05 -13:00', 'YYYY MM DD HH ZZ');\n    assert.equal(m.format(), '2013-01-01T05:00:00-13:00', 'accept input and format');\n    m = moment.parseZone('2013-01-01-13:00', 'YYYY MM DD ZZ', true);\n    assert.equal(m.isValid(), false, 'accept input, format and strict flag');\n    m = moment.parseZone('2013-01-01-13:00', ['DD MM YYYY ZZ', 'YYYY MM DD ZZ']);\n    assert.equal(m.format(), '2013-01-01T00:00:00-13:00', 'accept input and array of formats');\n});\n\ntest('parse zone with a timezone from the format string', function (assert) {\n    var m = moment('11-12-2013 -0400 +1100', 'DD-MM-YYYY ZZ #####').parseZone();\n\n    assert.equal(m.utcOffset(), -4 * 60);\n});\n\ntest('parse zone without a timezone included in the format string', function (assert) {\n    var m = moment('11-12-2013 -0400 +1100', 'DD-MM-YYYY').parseZone();\n\n    assert.equal(m.utcOffset(), 11 * 60);\n});\n\ntest('timezone format', function (assert) {\n    assert.equal(moment().utcOffset(60).format('ZZ'), '+0100', '-60 -> +0100');\n    assert.equal(moment().utcOffset(90).format('ZZ'), '+0130', '-90 -> +0130');\n    assert.equal(moment().utcOffset(120).format('ZZ'), '+0200', '-120 -> +0200');\n\n    assert.equal(moment().utcOffset(-60).format('ZZ'), '-0100', '+60 -> -0100');\n    assert.equal(moment().utcOffset(-90).format('ZZ'), '-0130', '+90 -> -0130');\n    assert.equal(moment().utcOffset(-120).format('ZZ'), '-0200', '+120 -> -0200');\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\nfunction module$1 (name, lifecycle) {\n    QUnit.module(name, {\n        setup : function () {\n            moment.locale('en');\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'core');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            teardownDeprecationHandler(test, moment, 'core');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n}\n\nmodule$1('week year');\n\ntest('iso week year', function (assert) {\n    // Some examples taken from https://en.wikipedia.org/wiki/ISO_week\n    assert.equal(moment([2005, 0, 1]).isoWeekYear(), 2004);\n    assert.equal(moment([2005, 0, 2]).isoWeekYear(), 2004);\n    assert.equal(moment([2005, 0, 3]).isoWeekYear(), 2005);\n    assert.equal(moment([2005, 11, 31]).isoWeekYear(), 2005);\n    assert.equal(moment([2006, 0, 1]).isoWeekYear(), 2005);\n    assert.equal(moment([2006, 0, 2]).isoWeekYear(), 2006);\n    assert.equal(moment([2007, 0, 1]).isoWeekYear(), 2007);\n    assert.equal(moment([2007, 11, 30]).isoWeekYear(), 2007);\n    assert.equal(moment([2007, 11, 31]).isoWeekYear(), 2008);\n    assert.equal(moment([2008, 0, 1]).isoWeekYear(), 2008);\n    assert.equal(moment([2008, 11, 28]).isoWeekYear(), 2008);\n    assert.equal(moment([2008, 11, 29]).isoWeekYear(), 2009);\n    assert.equal(moment([2008, 11, 30]).isoWeekYear(), 2009);\n    assert.equal(moment([2008, 11, 31]).isoWeekYear(), 2009);\n    assert.equal(moment([2009, 0, 1]).isoWeekYear(), 2009);\n    assert.equal(moment([2010, 0, 1]).isoWeekYear(), 2009);\n    assert.equal(moment([2010, 0, 2]).isoWeekYear(), 2009);\n    assert.equal(moment([2010, 0, 3]).isoWeekYear(), 2009);\n    assert.equal(moment([2010, 0, 4]).isoWeekYear(), 2010);\n});\n\ntest('week year', function (assert) {\n    // Some examples taken from https://en.wikipedia.org/wiki/ISO_week\n    moment.locale('dow: 1,doy: 4', {week: {dow: 1, doy: 4}}); // like iso\n    assert.equal(moment([2005, 0, 1]).weekYear(), 2004);\n    assert.equal(moment([2005, 0, 2]).weekYear(), 2004);\n    assert.equal(moment([2005, 0, 3]).weekYear(), 2005);\n    assert.equal(moment([2005, 11, 31]).weekYear(), 2005);\n    assert.equal(moment([2006, 0, 1]).weekYear(), 2005);\n    assert.equal(moment([2006, 0, 2]).weekYear(), 2006);\n    assert.equal(moment([2007, 0, 1]).weekYear(), 2007);\n    assert.equal(moment([2007, 11, 30]).weekYear(), 2007);\n    assert.equal(moment([2007, 11, 31]).weekYear(), 2008);\n    assert.equal(moment([2008, 0, 1]).weekYear(), 2008);\n    assert.equal(moment([2008, 11, 28]).weekYear(), 2008);\n    assert.equal(moment([2008, 11, 29]).weekYear(), 2009);\n    assert.equal(moment([2008, 11, 30]).weekYear(), 2009);\n    assert.equal(moment([2008, 11, 31]).weekYear(), 2009);\n    assert.equal(moment([2009, 0, 1]).weekYear(), 2009);\n    assert.equal(moment([2010, 0, 1]).weekYear(), 2009);\n    assert.equal(moment([2010, 0, 2]).weekYear(), 2009);\n    assert.equal(moment([2010, 0, 3]).weekYear(), 2009);\n    assert.equal(moment([2010, 0, 4]).weekYear(), 2010);\n\n    moment.locale('dow: 1,doy: 7', {week: {dow: 1, doy: 7}});\n    assert.equal(moment([2004, 11, 26]).weekYear(), 2004);\n    assert.equal(moment([2004, 11, 27]).weekYear(), 2005);\n    assert.equal(moment([2005, 11, 25]).weekYear(), 2005);\n    assert.equal(moment([2005, 11, 26]).weekYear(), 2006);\n    assert.equal(moment([2006, 11, 31]).weekYear(), 2006);\n    assert.equal(moment([2007,  0,  1]).weekYear(), 2007);\n    assert.equal(moment([2007, 11, 30]).weekYear(), 2007);\n    assert.equal(moment([2007, 11, 31]).weekYear(), 2008);\n    assert.equal(moment([2008, 11, 28]).weekYear(), 2008);\n    assert.equal(moment([2008, 11, 29]).weekYear(), 2009);\n    assert.equal(moment([2009, 11, 27]).weekYear(), 2009);\n    assert.equal(moment([2009, 11, 28]).weekYear(), 2010);\n});\n\n// Verifies that the week number, week day computation is correct for all dow, doy combinations\ntest('week year roundtrip', function (assert) {\n    var dow, doy, wd, m, localeName;\n    for (dow = 0; dow < 7; ++dow) {\n        for (doy = dow; doy < dow + 7; ++doy) {\n            for (wd = 0; wd < 7; ++wd) {\n                localeName = 'dow: ' + dow + ', doy: ' + doy;\n                moment.locale(localeName, {week: {dow: dow, doy: doy}});\n                // We use the 10th week as the 1st one can spill to the previous year\n                m = moment('2015 10 ' + wd, 'gggg w d', true);\n                assert.equal(m.format('gggg w d'), '2015 10 ' + wd, 'dow: ' + dow + ' doy: ' + doy + ' wd: ' + wd);\n                m = moment('2015 10 ' + wd, 'gggg w e', true);\n                assert.equal(m.format('gggg w e'), '2015 10 ' + wd, 'dow: ' + dow + ' doy: ' + doy + ' wd: ' + wd);\n                moment.defineLocale(localeName, null);\n            }\n        }\n    }\n});\n\ntest('week numbers 2012/2013', function (assert) {\n    moment.locale('dow: 6, doy: 12', {week: {dow: 6, doy: 12}});\n    assert.equal(52, moment('2012-12-28', 'YYYY-MM-DD').week(), '2012-12-28 is week 52'); // 51 -- should be 52?\n    assert.equal(1, moment('2012-12-29', 'YYYY-MM-DD').week(), '2012-12-29 is week 1'); // 52 -- should be 1\n    assert.equal(1, moment('2013-01-01', 'YYYY-MM-DD').week(), '2013-01-01 is week 1'); // 52 -- should be 1\n    assert.equal(2, moment('2013-01-08', 'YYYY-MM-DD').week(), '2013-01-08 is week 2'); // 53 -- should be 2\n    assert.equal(2, moment('2013-01-11', 'YYYY-MM-DD').week(), '2013-01-11 is week 2'); // 53 -- should be 2\n    assert.equal(3, moment('2013-01-12', 'YYYY-MM-DD').week(), '2013-01-12 is week 3'); // 1 -- should be 3\n    assert.equal(52, moment('2012-01-01', 'YYYY-MM-DD').weeksInYear(), 'weeks in 2012 are 52'); // 52\n    moment.defineLocale('dow: 6, doy: 12', null);\n});\n\ntest('weeks numbers dow:1 doy:4', function (assert) {\n    moment.locale('dow: 1, doy: 4', {week: {dow: 1, doy: 4}});\n    assert.equal(moment([2012, 0, 1]).week(), 52, 'Jan  1 2012 should be week 52');\n    assert.equal(moment([2012, 0, 2]).week(),  1, 'Jan  2 2012 should be week 1');\n    assert.equal(moment([2012, 0, 8]).week(),  1, 'Jan  8 2012 should be week 1');\n    assert.equal(moment([2012, 0, 9]).week(),  2, 'Jan  9 2012 should be week 2');\n    assert.equal(moment([2012, 0, 15]).week(), 2, 'Jan 15 2012 should be week 2');\n    assert.equal(moment([2007, 0, 1]).week(),  1, 'Jan  1 2007 should be week 1');\n    assert.equal(moment([2007, 0, 7]).week(),  1, 'Jan  7 2007 should be week 1');\n    assert.equal(moment([2007, 0, 8]).week(),  2, 'Jan  8 2007 should be week 2');\n    assert.equal(moment([2007, 0, 14]).week(), 2, 'Jan 14 2007 should be week 2');\n    assert.equal(moment([2007, 0, 15]).week(), 3, 'Jan 15 2007 should be week 3');\n    assert.equal(moment([2007, 11, 31]).week(), 1, 'Dec 31 2007 should be week 1');\n    assert.equal(moment([2008,  0,  1]).week(), 1, 'Jan  1 2008 should be week 1');\n    assert.equal(moment([2008,  0,  6]).week(), 1, 'Jan  6 2008 should be week 1');\n    assert.equal(moment([2008,  0,  7]).week(), 2, 'Jan  7 2008 should be week 2');\n    assert.equal(moment([2008,  0, 13]).week(), 2, 'Jan 13 2008 should be week 2');\n    assert.equal(moment([2008,  0, 14]).week(), 3, 'Jan 14 2008 should be week 3');\n    assert.equal(moment([2002, 11, 30]).week(), 1, 'Dec 30 2002 should be week 1');\n    assert.equal(moment([2003,  0,  1]).week(), 1, 'Jan  1 2003 should be week 1');\n    assert.equal(moment([2003,  0,  5]).week(), 1, 'Jan  5 2003 should be week 1');\n    assert.equal(moment([2003,  0,  6]).week(), 2, 'Jan  6 2003 should be week 2');\n    assert.equal(moment([2003,  0, 12]).week(), 2, 'Jan 12 2003 should be week 2');\n    assert.equal(moment([2003,  0, 13]).week(), 3, 'Jan 13 2003 should be week 3');\n    assert.equal(moment([2008, 11, 29]).week(), 1, 'Dec 29 2008 should be week 1');\n    assert.equal(moment([2009,  0,  1]).week(), 1, 'Jan  1 2009 should be week 1');\n    assert.equal(moment([2009,  0,  4]).week(), 1, 'Jan  4 2009 should be week 1');\n    assert.equal(moment([2009,  0,  5]).week(), 2, 'Jan  5 2009 should be week 2');\n    assert.equal(moment([2009,  0, 11]).week(), 2, 'Jan 11 2009 should be week 2');\n    assert.equal(moment([2009,  0, 13]).week(), 3, 'Jan 12 2009 should be week 3');\n    assert.equal(moment([2009, 11, 28]).week(), 53, 'Dec 28 2009 should be week 53');\n    assert.equal(moment([2010,  0,  1]).week(), 53, 'Jan  1 2010 should be week 53');\n    assert.equal(moment([2010,  0,  3]).week(), 53, 'Jan  3 2010 should be week 53');\n    assert.equal(moment([2010,  0,  4]).week(),  1, 'Jan  4 2010 should be week 1');\n    assert.equal(moment([2010,  0, 10]).week(),  1, 'Jan 10 2010 should be week 1');\n    assert.equal(moment([2010,  0, 11]).week(),  2, 'Jan 11 2010 should be week 2');\n    assert.equal(moment([2010, 11, 27]).week(), 52, 'Dec 27 2010 should be week 52');\n    assert.equal(moment([2011,  0,  1]).week(), 52, 'Jan  1 2011 should be week 52');\n    assert.equal(moment([2011,  0,  2]).week(), 52, 'Jan  2 2011 should be week 52');\n    assert.equal(moment([2011,  0,  3]).week(),  1, 'Jan  3 2011 should be week 1');\n    assert.equal(moment([2011,  0,  9]).week(),  1, 'Jan  9 2011 should be week 1');\n    assert.equal(moment([2011,  0, 10]).week(),  2, 'Jan 10 2011 should be week 2');\n    moment.defineLocale('dow: 1, doy: 4', null);\n});\n\ntest('weeks numbers dow:6 doy:12', function (assert) {\n    moment.locale('dow: 6, doy: 12', {week: {dow: 6, doy: 12}});\n    assert.equal(moment([2011, 11, 31]).week(), 1, 'Dec 31 2011 should be week 1');\n    assert.equal(moment([2012,  0,  6]).week(), 1, 'Jan  6 2012 should be week 1');\n    assert.equal(moment([2012,  0,  7]).week(), 2, 'Jan  7 2012 should be week 2');\n    assert.equal(moment([2012,  0, 13]).week(), 2, 'Jan 13 2012 should be week 2');\n    assert.equal(moment([2012,  0, 14]).week(), 3, 'Jan 14 2012 should be week 3');\n    assert.equal(moment([2006, 11, 30]).week(), 1, 'Dec 30 2006 should be week 1');\n    assert.equal(moment([2007,  0,  5]).week(), 1, 'Jan  5 2007 should be week 1');\n    assert.equal(moment([2007,  0,  6]).week(), 2, 'Jan  6 2007 should be week 2');\n    assert.equal(moment([2007,  0, 12]).week(), 2, 'Jan 12 2007 should be week 2');\n    assert.equal(moment([2007,  0, 13]).week(), 3, 'Jan 13 2007 should be week 3');\n    assert.equal(moment([2007, 11, 29]).week(), 1, 'Dec 29 2007 should be week 1');\n    assert.equal(moment([2008,  0,  1]).week(), 1, 'Jan  1 2008 should be week 1');\n    assert.equal(moment([2008,  0,  4]).week(), 1, 'Jan  4 2008 should be week 1');\n    assert.equal(moment([2008,  0,  5]).week(), 2, 'Jan  5 2008 should be week 2');\n    assert.equal(moment([2008,  0, 11]).week(), 2, 'Jan 11 2008 should be week 2');\n    assert.equal(moment([2008,  0, 12]).week(), 3, 'Jan 12 2008 should be week 3');\n    assert.equal(moment([2002, 11, 28]).week(), 1, 'Dec 28 2002 should be week 1');\n    assert.equal(moment([2003,  0,  1]).week(), 1, 'Jan  1 2003 should be week 1');\n    assert.equal(moment([2003,  0,  3]).week(), 1, 'Jan  3 2003 should be week 1');\n    assert.equal(moment([2003,  0,  4]).week(), 2, 'Jan  4 2003 should be week 2');\n    assert.equal(moment([2003,  0, 10]).week(), 2, 'Jan 10 2003 should be week 2');\n    assert.equal(moment([2003,  0, 11]).week(), 3, 'Jan 11 2003 should be week 3');\n    assert.equal(moment([2008, 11, 27]).week(), 1, 'Dec 27 2008 should be week 1');\n    assert.equal(moment([2009,  0,  1]).week(), 1, 'Jan  1 2009 should be week 1');\n    assert.equal(moment([2009,  0,  2]).week(), 1, 'Jan  2 2009 should be week 1');\n    assert.equal(moment([2009,  0,  3]).week(), 2, 'Jan  3 2009 should be week 2');\n    assert.equal(moment([2009,  0,  9]).week(), 2, 'Jan  9 2009 should be week 2');\n    assert.equal(moment([2009,  0, 10]).week(), 3, 'Jan 10 2009 should be week 3');\n    assert.equal(moment([2009, 11, 26]).week(), 1, 'Dec 26 2009 should be week 1');\n    assert.equal(moment([2010,  0,  1]).week(), 1, 'Jan  1 2010 should be week 1');\n    assert.equal(moment([2010,  0,  2]).week(), 2, 'Jan  2 2010 should be week 2');\n    assert.equal(moment([2010,  0,  8]).week(), 2, 'Jan  8 2010 should be week 2');\n    assert.equal(moment([2010,  0,  9]).week(), 3, 'Jan  9 2010 should be week 3');\n    assert.equal(moment([2011, 0,  1]).week(), 1, 'Jan  1 2011 should be week 1');\n    assert.equal(moment([2011, 0,  7]).week(), 1, 'Jan  7 2011 should be week 1');\n    assert.equal(moment([2011, 0,  8]).week(), 2, 'Jan  8 2011 should be week 2');\n    assert.equal(moment([2011, 0, 14]).week(), 2, 'Jan 14 2011 should be week 2');\n    assert.equal(moment([2011, 0, 15]).week(), 3, 'Jan 15 2011 should be week 3');\n    moment.defineLocale('dow: 6, doy: 12', null);\n});\n\ntest('weeks numbers dow:1 doy:7', function (assert) {\n    moment.locale('dow: 1, doy: 7', {week: {dow: 1, doy: 7}});\n    assert.equal(moment([2011, 11, 26]).week(), 1, 'Dec 26 2011 should be week 1');\n    assert.equal(moment([2012,  0,  1]).week(), 1, 'Jan  1 2012 should be week 1');\n    assert.equal(moment([2012,  0,  2]).week(), 2, 'Jan  2 2012 should be week 2');\n    assert.equal(moment([2012,  0,  8]).week(), 2, 'Jan  8 2012 should be week 2');\n    assert.equal(moment([2012,  0,  9]).week(), 3, 'Jan  9 2012 should be week 3');\n    assert.equal(moment([2007, 0, 1]).week(),  1, 'Jan  1 2007 should be week 1');\n    assert.equal(moment([2007, 0, 7]).week(),  1, 'Jan  7 2007 should be week 1');\n    assert.equal(moment([2007, 0, 8]).week(),  2, 'Jan  8 2007 should be week 2');\n    assert.equal(moment([2007, 0, 14]).week(), 2, 'Jan 14 2007 should be week 2');\n    assert.equal(moment([2007, 0, 15]).week(), 3, 'Jan 15 2007 should be week 3');\n    assert.equal(moment([2007, 11, 31]).week(), 1, 'Dec 31 2007 should be week 1');\n    assert.equal(moment([2008,  0,  1]).week(), 1, 'Jan  1 2008 should be week 1');\n    assert.equal(moment([2008,  0,  6]).week(), 1, 'Jan  6 2008 should be week 1');\n    assert.equal(moment([2008,  0,  7]).week(), 2, 'Jan  7 2008 should be week 2');\n    assert.equal(moment([2008,  0, 13]).week(), 2, 'Jan 13 2008 should be week 2');\n    assert.equal(moment([2008,  0, 14]).week(), 3, 'Jan 14 2008 should be week 3');\n    assert.equal(moment([2002, 11, 30]).week(), 1, 'Dec 30 2002 should be week 1');\n    assert.equal(moment([2003,  0,  1]).week(), 1, 'Jan  1 2003 should be week 1');\n    assert.equal(moment([2003,  0,  5]).week(), 1, 'Jan  5 2003 should be week 1');\n    assert.equal(moment([2003,  0,  6]).week(), 2, 'Jan  6 2003 should be week 2');\n    assert.equal(moment([2003,  0, 12]).week(), 2, 'Jan 12 2003 should be week 2');\n    assert.equal(moment([2003,  0, 13]).week(), 3, 'Jan 13 2003 should be week 3');\n    assert.equal(moment([2008, 11, 29]).week(), 1, 'Dec 29 2008 should be week 1');\n    assert.equal(moment([2009,  0,  1]).week(), 1, 'Jan  1 2009 should be week 1');\n    assert.equal(moment([2009,  0,  4]).week(), 1, 'Jan  4 2009 should be week 1');\n    assert.equal(moment([2009,  0,  5]).week(), 2, 'Jan  5 2009 should be week 2');\n    assert.equal(moment([2009,  0, 11]).week(), 2, 'Jan 11 2009 should be week 2');\n    assert.equal(moment([2009,  0, 12]).week(), 3, 'Jan 12 2009 should be week 3');\n    assert.equal(moment([2009, 11, 28]).week(), 1, 'Dec 28 2009 should be week 1');\n    assert.equal(moment([2010,  0,  1]).week(), 1, 'Jan  1 2010 should be week 1');\n    assert.equal(moment([2010,  0,  3]).week(), 1, 'Jan  3 2010 should be week 1');\n    assert.equal(moment([2010,  0,  4]).week(), 2, 'Jan  4 2010 should be week 2');\n    assert.equal(moment([2010,  0, 10]).week(), 2, 'Jan 10 2010 should be week 2');\n    assert.equal(moment([2010,  0, 11]).week(), 3, 'Jan 11 2010 should be week 3');\n    assert.equal(moment([2010, 11, 27]).week(), 1, 'Dec 27 2010 should be week 1');\n    assert.equal(moment([2011,  0,  1]).week(), 1, 'Jan  1 2011 should be week 1');\n    assert.equal(moment([2011,  0,  2]).week(), 1, 'Jan  2 2011 should be week 1');\n    assert.equal(moment([2011,  0,  3]).week(), 2, 'Jan  3 2011 should be week 2');\n    assert.equal(moment([2011,  0,  9]).week(), 2, 'Jan  9 2011 should be week 2');\n    assert.equal(moment([2011,  0, 10]).week(), 3, 'Jan 10 2011 should be week 3');\n    moment.defineLocale('dow: 1, doy: 7', null);\n});\n\ntest('weeks numbers dow:0 doy:6', function (assert) {\n    moment.locale('dow: 0, doy: 6', {week: {dow: 0, doy: 6}});\n    assert.equal(moment([2012, 0,  1]).week(), 1, 'Jan  1 2012 should be week 1');\n    assert.equal(moment([2012, 0,  7]).week(), 1, 'Jan  7 2012 should be week 1');\n    assert.equal(moment([2012, 0,  8]).week(), 2, 'Jan  8 2012 should be week 2');\n    assert.equal(moment([2012, 0, 14]).week(), 2, 'Jan 14 2012 should be week 2');\n    assert.equal(moment([2012, 0, 15]).week(), 3, 'Jan 15 2012 should be week 3');\n    assert.equal(moment([2006, 11, 31]).week(), 1, 'Dec 31 2006 should be week 1');\n    assert.equal(moment([2007,  0,  1]).week(), 1, 'Jan  1 2007 should be week 1');\n    assert.equal(moment([2007,  0,  6]).week(), 1, 'Jan  6 2007 should be week 1');\n    assert.equal(moment([2007,  0,  7]).week(), 2, 'Jan  7 2007 should be week 2');\n    assert.equal(moment([2007,  0, 13]).week(), 2, 'Jan 13 2007 should be week 2');\n    assert.equal(moment([2007,  0, 14]).week(), 3, 'Jan 14 2007 should be week 3');\n    assert.equal(moment([2007, 11, 29]).week(), 52, 'Dec 29 2007 should be week 52');\n    assert.equal(moment([2008,  0,  1]).week(), 1, 'Jan  1 2008 should be week 1');\n    assert.equal(moment([2008,  0,  5]).week(), 1, 'Jan  5 2008 should be week 1');\n    assert.equal(moment([2008,  0,  6]).week(), 2, 'Jan  6 2008 should be week 2');\n    assert.equal(moment([2008,  0, 12]).week(), 2, 'Jan 12 2008 should be week 2');\n    assert.equal(moment([2008,  0, 13]).week(), 3, 'Jan 13 2008 should be week 3');\n    assert.equal(moment([2002, 11, 29]).week(), 1, 'Dec 29 2002 should be week 1');\n    assert.equal(moment([2003,  0,  1]).week(), 1, 'Jan  1 2003 should be week 1');\n    assert.equal(moment([2003,  0,  4]).week(), 1, 'Jan  4 2003 should be week 1');\n    assert.equal(moment([2003,  0,  5]).week(), 2, 'Jan  5 2003 should be week 2');\n    assert.equal(moment([2003,  0, 11]).week(), 2, 'Jan 11 2003 should be week 2');\n    assert.equal(moment([2003,  0, 12]).week(), 3, 'Jan 12 2003 should be week 3');\n    assert.equal(moment([2008, 11, 28]).week(), 1, 'Dec 28 2008 should be week 1');\n    assert.equal(moment([2009,  0,  1]).week(), 1, 'Jan  1 2009 should be week 1');\n    assert.equal(moment([2009,  0,  3]).week(), 1, 'Jan  3 2009 should be week 1');\n    assert.equal(moment([2009,  0,  4]).week(), 2, 'Jan  4 2009 should be week 2');\n    assert.equal(moment([2009,  0, 10]).week(), 2, 'Jan 10 2009 should be week 2');\n    assert.equal(moment([2009,  0, 11]).week(), 3, 'Jan 11 2009 should be week 3');\n    assert.equal(moment([2009, 11, 27]).week(), 1, 'Dec 27 2009 should be week 1');\n    assert.equal(moment([2010,  0,  1]).week(), 1, 'Jan  1 2010 should be week 1');\n    assert.equal(moment([2010,  0,  2]).week(), 1, 'Jan  2 2010 should be week 1');\n    assert.equal(moment([2010,  0,  3]).week(), 2, 'Jan  3 2010 should be week 2');\n    assert.equal(moment([2010,  0,  9]).week(), 2, 'Jan  9 2010 should be week 2');\n    assert.equal(moment([2010,  0, 10]).week(), 3, 'Jan 10 2010 should be week 3');\n    assert.equal(moment([2010, 11, 26]).week(), 1, 'Dec 26 2010 should be week 1');\n    assert.equal(moment([2011,  0,  1]).week(), 1, 'Jan  1 2011 should be week 1');\n    assert.equal(moment([2011,  0,  2]).week(), 2, 'Jan  2 2011 should be week 2');\n    assert.equal(moment([2011,  0,  8]).week(), 2, 'Jan  8 2011 should be week 2');\n    assert.equal(moment([2011,  0,  9]).week(), 3, 'Jan  9 2011 should be week 3');\n    moment.defineLocale('dow: 0, doy: 6', null);\n});\n\ntest('week year overflows', function (assert) {\n    assert.equal('2005-01-01', moment.utc('2004-W53-6', moment.ISO_8601, true).format('YYYY-MM-DD'), '2004-W53-6 is 1st Jan 2005');\n    assert.equal('2007-12-31', moment.utc('2008-W01-1', moment.ISO_8601, true).format('YYYY-MM-DD'), '2008-W01-1 is 31st Dec 2007');\n});\n\ntest('weeks overflow', function (assert) {\n    assert.equal(7, moment.utc('2004-W54-1', moment.ISO_8601, true).parsingFlags().overflow, '2004 has only 53 weeks');\n    assert.equal(7, moment.utc('2004-W00-1', moment.ISO_8601, true).parsingFlags().overflow, 'there is no 0th week');\n});\n\ntest('weekday overflow', function (assert) {\n    assert.equal(8, moment.utc('2004-W30-0', moment.ISO_8601, true).parsingFlags().overflow, 'there is no 0 iso weekday');\n    assert.equal(8, moment.utc('2004-W30-8', moment.ISO_8601, true).parsingFlags().overflow, 'there is no 8 iso weekday');\n    assert.equal(8, moment.utc('2004-w30-7', 'gggg-[w]ww-e', true).parsingFlags().overflow, 'there is no 7 \\'e\\' weekday');\n    assert.equal(8, moment.utc('2004-w30-7', 'gggg-[w]ww-d', true).parsingFlags().overflow, 'there is no 7 \\'d\\' weekday');\n});\n\ntest('week year setter works', function (assert) {\n    for (var year = 2000; year <= 2020; year += 1) {\n        assert.equal(moment.utc('2012-12-31T00:00:00.000Z').isoWeekYear(year).isoWeekYear(), year, 'setting iso-week-year to ' + year);\n        assert.equal(moment.utc('2012-12-31T00:00:00.000Z').weekYear(year).weekYear(), year, 'setting week-year to ' + year);\n    }\n\n    assert.equal(moment.utc('2004-W53-1', moment.ISO_8601, true).isoWeekYear(2013).format('GGGG-[W]WW-E'), '2013-W52-1', '2004-W53-1 to 2013');\n    assert.equal(moment.utc('2004-W53-1', moment.ISO_8601, true).isoWeekYear(2020).format('GGGG-[W]WW-E'), '2020-W53-1', '2004-W53-1 to 2020');\n    assert.equal(moment.utc('2005-W52-1', moment.ISO_8601, true).isoWeekYear(2004).format('GGGG-[W]WW-E'), '2004-W52-1', '2005-W52-1 to 2004');\n    assert.equal(moment.utc('2013-W30-4', moment.ISO_8601, true).isoWeekYear(2015).format('GGGG-[W]WW-E'), '2015-W30-4', '2013-W30-4 to 2015');\n\n    assert.equal(moment.utc('2005-w53-0', 'gggg-[w]ww-e', true).weekYear(2013).format('gggg-[w]ww-e'), '2013-w52-0', '2005-w53-0 to 2013');\n    assert.equal(moment.utc('2005-w53-0', 'gggg-[w]ww-e', true).weekYear(2016).format('gggg-[w]ww-e'), '2016-w53-0', '2005-w53-0 to 2016');\n    assert.equal(moment.utc('2004-w52-0', 'gggg-[w]ww-e', true).weekYear(2005).format('gggg-[w]ww-e'), '2005-w52-0', '2004-w52-0 to 2005');\n    assert.equal(moment.utc('2013-w30-4', 'gggg-[w]ww-e', true).weekYear(2015).format('gggg-[w]ww-e'), '2015-w30-4', '2013-w30-4 to 2015');\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\nfunction module$1 (name, lifecycle) {\n    QUnit.module(name, {\n        setup : function () {\n            moment.locale('en');\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'core');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            teardownDeprecationHandler(test, moment, 'core');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n}\n\nmodule$1('week day');\n\ntest('iso weekday', function (assert) {\n    var i;\n\n    for (i = 0; i < 7; ++i) {\n        moment.locale('dow:' + i + ',doy: 6', {week: {dow: i, doy: 6}});\n        assert.equal(moment([1985, 1,  4]).isoWeekday(), 1, 'Feb  4 1985 is Monday    -- 1st day');\n        assert.equal(moment([2029, 8, 18]).isoWeekday(), 2, 'Sep 18 2029 is Tuesday   -- 2nd day');\n        assert.equal(moment([2013, 3, 24]).isoWeekday(), 3, 'Apr 24 2013 is Wednesday -- 3rd day');\n        assert.equal(moment([2015, 2,  5]).isoWeekday(), 4, 'Mar  5 2015 is Thursday  -- 4th day');\n        assert.equal(moment([1970, 0,  2]).isoWeekday(), 5, 'Jan  2 1970 is Friday    -- 5th day');\n        assert.equal(moment([2001, 4, 12]).isoWeekday(), 6, 'May 12 2001 is Saturday  -- 6th day');\n        assert.equal(moment([2000, 0,  2]).isoWeekday(), 7, 'Jan  2 2000 is Sunday    -- 7th day');\n    }\n});\n\ntest('iso weekday setter', function (assert) {\n    var a = moment([2011, 0, 10]);\n    assert.equal(moment(a).isoWeekday(1).date(),  10, 'set from mon to mon');\n    assert.equal(moment(a).isoWeekday(4).date(),  13, 'set from mon to thu');\n    assert.equal(moment(a).isoWeekday(7).date(),  16, 'set from mon to sun');\n    assert.equal(moment(a).isoWeekday(-6).date(),  3, 'set from mon to last mon');\n    assert.equal(moment(a).isoWeekday(-3).date(),  6, 'set from mon to last thu');\n    assert.equal(moment(a).isoWeekday(0).date(),   9, 'set from mon to last sun');\n    assert.equal(moment(a).isoWeekday(8).date(),  17, 'set from mon to next mon');\n    assert.equal(moment(a).isoWeekday(11).date(), 20, 'set from mon to next thu');\n    assert.equal(moment(a).isoWeekday(14).date(), 23, 'set from mon to next sun');\n\n    a = moment([2011, 0, 13]);\n    assert.equal(moment(a).isoWeekday(1).date(), 10, 'set from thu to mon');\n    assert.equal(moment(a).isoWeekday(4).date(), 13, 'set from thu to thu');\n    assert.equal(moment(a).isoWeekday(7).date(), 16, 'set from thu to sun');\n    assert.equal(moment(a).isoWeekday(-6).date(),  3, 'set from thu to last mon');\n    assert.equal(moment(a).isoWeekday(-3).date(),  6, 'set from thu to last thu');\n    assert.equal(moment(a).isoWeekday(0).date(),   9, 'set from thu to last sun');\n    assert.equal(moment(a).isoWeekday(8).date(),  17, 'set from thu to next mon');\n    assert.equal(moment(a).isoWeekday(11).date(), 20, 'set from thu to next thu');\n    assert.equal(moment(a).isoWeekday(14).date(), 23, 'set from thu to next sun');\n\n    a = moment([2011, 0, 16]);\n    assert.equal(moment(a).isoWeekday(1).date(), 10, 'set from sun to mon');\n    assert.equal(moment(a).isoWeekday(4).date(), 13, 'set from sun to thu');\n    assert.equal(moment(a).isoWeekday(7).date(), 16, 'set from sun to sun');\n    assert.equal(moment(a).isoWeekday(-6).date(),  3, 'set from sun to last mon');\n    assert.equal(moment(a).isoWeekday(-3).date(),  6, 'set from sun to last thu');\n    assert.equal(moment(a).isoWeekday(0).date(),   9, 'set from sun to last sun');\n    assert.equal(moment(a).isoWeekday(8).date(),  17, 'set from sun to next mon');\n    assert.equal(moment(a).isoWeekday(11).date(), 20, 'set from sun to next thu');\n    assert.equal(moment(a).isoWeekday(14).date(), 23, 'set from sun to next sun');\n});\n\ntest('iso weekday setter with day name', function (assert) {\n    moment.locale('en');\n\n    var a = moment([2011, 0, 10]);\n    assert.equal(moment(a).isoWeekday('Monday').date(),   10, 'set from mon to mon');\n    assert.equal(moment(a).isoWeekday('Thursday').date(), 13, 'set from mon to thu');\n    assert.equal(moment(a).isoWeekday('Sunday').date(),   16, 'set from mon to sun');\n\n    a = moment([2011, 0, 13]);\n    assert.equal(moment(a).isoWeekday('Monday').date(),   10, 'set from thu to mon');\n    assert.equal(moment(a).isoWeekday('Thursday').date(), 13, 'set from thu to thu');\n    assert.equal(moment(a).isoWeekday('Sunday').date(),   16, 'set from thu to sun');\n\n    a = moment([2011, 0, 16]);\n    assert.equal(moment(a).isoWeekday('Monday').date(),   10, 'set from sun to mon');\n    assert.equal(moment(a).isoWeekday('Thursday').date(), 13, 'set from sun to thu');\n    assert.equal(moment(a).isoWeekday('Sunday').date(),   16, 'set from sun to sun');\n});\n\ntest('weekday first day of week Sunday (dow 0)', function (assert) {\n    moment.locale('dow: 0,doy: 6', {week: {dow: 0, doy: 6}});\n    assert.equal(moment([1985, 1,  3]).weekday(), 0, 'Feb  3 1985 is Sunday    -- 0th day');\n    assert.equal(moment([2029, 8, 17]).weekday(), 1, 'Sep 17 2029 is Monday    -- 1st day');\n    assert.equal(moment([2013, 3, 23]).weekday(), 2, 'Apr 23 2013 is Tuesday   -- 2nd day');\n    assert.equal(moment([2015, 2,  4]).weekday(), 3, 'Mar  4 2015 is Wednesday -- 3nd day');\n    assert.equal(moment([1970, 0,  1]).weekday(), 4, 'Jan  1 1970 is Thursday  -- 4th day');\n    assert.equal(moment([2001, 4, 11]).weekday(), 5, 'May 11 2001 is Friday    -- 5th day');\n    assert.equal(moment([2000, 0,  1]).weekday(), 6, 'Jan  1 2000 is Saturday  -- 6th day');\n});\n\ntest('weekday first day of week Monday (dow 1)', function (assert) {\n    moment.locale('dow: 1,doy: 6', {week: {dow: 1, doy: 6}});\n    assert.equal(moment([1985, 1,  4]).weekday(), 0, 'Feb  4 1985 is Monday    -- 0th day');\n    assert.equal(moment([2029, 8, 18]).weekday(), 1, 'Sep 18 2029 is Tuesday   -- 1st day');\n    assert.equal(moment([2013, 3, 24]).weekday(), 2, 'Apr 24 2013 is Wednesday -- 2nd day');\n    assert.equal(moment([2015, 2,  5]).weekday(), 3, 'Mar  5 2015 is Thursday  -- 3nd day');\n    assert.equal(moment([1970, 0,  2]).weekday(), 4, 'Jan  2 1970 is Friday    -- 4th day');\n    assert.equal(moment([2001, 4, 12]).weekday(), 5, 'May 12 2001 is Saturday  -- 5th day');\n    assert.equal(moment([2000, 0,  2]).weekday(), 6, 'Jan  2 2000 is Sunday    -- 6th day');\n});\n\ntest('weekday first day of week Tuesday (dow 2)', function (assert) {\n    moment.locale('dow: 2,doy: 6', {week: {dow: 2, doy: 6}});\n    assert.equal(moment([1985, 1,  5]).weekday(), 0, 'Feb  5 1985 is Tuesday   -- 0th day');\n    assert.equal(moment([2029, 8, 19]).weekday(), 1, 'Sep 19 2029 is Wednesday -- 1st day');\n    assert.equal(moment([2013, 3, 25]).weekday(), 2, 'Apr 25 2013 is Thursday  -- 2nd day');\n    assert.equal(moment([2015, 2,  6]).weekday(), 3, 'Mar  6 2015 is Friday    -- 3nd day');\n    assert.equal(moment([1970, 0,  3]).weekday(), 4, 'Jan  3 1970 is Staturday -- 4th day');\n    assert.equal(moment([2001, 4, 13]).weekday(), 5, 'May 13 2001 is Sunday    -- 5th day');\n    assert.equal(moment([2000, 0,  3]).weekday(), 6, 'Jan  3 2000 is Monday    -- 6th day');\n});\n\ntest('weekday first day of week Wednesday (dow 3)', function (assert) {\n    moment.locale('dow: 3,doy: 6', {week: {dow: 3, doy: 6}});\n    assert.equal(moment([1985, 1,  6]).weekday(), 0, 'Feb  6 1985 is Wednesday -- 0th day');\n    assert.equal(moment([2029, 8, 20]).weekday(), 1, 'Sep 20 2029 is Thursday  -- 1st day');\n    assert.equal(moment([2013, 3, 26]).weekday(), 2, 'Apr 26 2013 is Friday    -- 2nd day');\n    assert.equal(moment([2015, 2,  7]).weekday(), 3, 'Mar  7 2015 is Saturday  -- 3nd day');\n    assert.equal(moment([1970, 0,  4]).weekday(), 4, 'Jan  4 1970 is Sunday    -- 4th day');\n    assert.equal(moment([2001, 4, 14]).weekday(), 5, 'May 14 2001 is Monday    -- 5th day');\n    assert.equal(moment([2000, 0,  4]).weekday(), 6, 'Jan  4 2000 is Tuesday   -- 6th day');\n    moment.locale('dow:3,doy:6', null);\n});\n\ntest('weekday first day of week Thursday (dow 4)', function (assert) {\n    moment.locale('dow: 4,doy: 6', {week: {dow: 4, doy: 6}});\n    assert.equal(moment([1985, 1,  7]).weekday(), 0, 'Feb  7 1985 is Thursday  -- 0th day');\n    assert.equal(moment([2029, 8, 21]).weekday(), 1, 'Sep 21 2029 is Friday    -- 1st day');\n    assert.equal(moment([2013, 3, 27]).weekday(), 2, 'Apr 27 2013 is Saturday  -- 2nd day');\n    assert.equal(moment([2015, 2,  8]).weekday(), 3, 'Mar  8 2015 is Sunday    -- 3nd day');\n    assert.equal(moment([1970, 0,  5]).weekday(), 4, 'Jan  5 1970 is Monday    -- 4th day');\n    assert.equal(moment([2001, 4, 15]).weekday(), 5, 'May 15 2001 is Tuesday   -- 5th day');\n    assert.equal(moment([2000, 0,  5]).weekday(), 6, 'Jan  5 2000 is Wednesday -- 6th day');\n});\n\ntest('weekday first day of week Friday (dow 5)', function (assert) {\n    moment.locale('dow: 5,doy: 6', {week: {dow: 5, doy: 6}});\n    assert.equal(moment([1985, 1,  8]).weekday(), 0, 'Feb  8 1985 is Friday    -- 0th day');\n    assert.equal(moment([2029, 8, 22]).weekday(), 1, 'Sep 22 2029 is Staturday -- 1st day');\n    assert.equal(moment([2013, 3, 28]).weekday(), 2, 'Apr 28 2013 is Sunday    -- 2nd day');\n    assert.equal(moment([2015, 2,  9]).weekday(), 3, 'Mar  9 2015 is Monday    -- 3nd day');\n    assert.equal(moment([1970, 0,  6]).weekday(), 4, 'Jan  6 1970 is Tuesday   -- 4th day');\n    assert.equal(moment([2001, 4, 16]).weekday(), 5, 'May 16 2001 is Wednesday -- 5th day');\n    assert.equal(moment([2000, 0,  6]).weekday(), 6, 'Jan  6 2000 is Thursday  -- 6th day');\n});\n\ntest('weekday first day of week Saturday (dow 6)', function (assert) {\n    moment.locale('dow: 6,doy: 6', {week: {dow: 6, doy: 6}});\n    assert.equal(moment([1985, 1,  9]).weekday(), 0, 'Feb  9 1985 is Staturday -- 0th day');\n    assert.equal(moment([2029, 8, 23]).weekday(), 1, 'Sep 23 2029 is Sunday    -- 1st day');\n    assert.equal(moment([2013, 3, 29]).weekday(), 2, 'Apr 29 2013 is Monday    -- 2nd day');\n    assert.equal(moment([2015, 2, 10]).weekday(), 3, 'Mar 10 2015 is Tuesday   -- 3nd day');\n    assert.equal(moment([1970, 0,  7]).weekday(), 4, 'Jan  7 1970 is Wednesday -- 4th day');\n    assert.equal(moment([2001, 4, 17]).weekday(), 5, 'May 17 2001 is Thursday  -- 5th day');\n    assert.equal(moment([2000, 0,  7]).weekday(), 6, 'Jan  7 2000 is Friday    -- 6th day');\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\nfunction module$1 (name, lifecycle) {\n    QUnit.module(name, {\n        setup : function () {\n            moment.locale('en');\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'core');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            teardownDeprecationHandler(test, moment, 'core');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n}\n\nmodule$1('weeks');\n\ntest('day of year', function (assert) {\n    assert.equal(moment([2000,  0,  1]).dayOfYear(),   1, 'Jan  1 2000 should be day 1 of the year');\n    assert.equal(moment([2000,  1, 28]).dayOfYear(),  59, 'Feb 28 2000 should be day 59 of the year');\n    assert.equal(moment([2000,  1, 29]).dayOfYear(),  60, 'Feb 28 2000 should be day 60 of the year');\n    assert.equal(moment([2000, 11, 31]).dayOfYear(), 366, 'Dec 31 2000 should be day 366 of the year');\n    assert.equal(moment([2001,  0,  1]).dayOfYear(),   1, 'Jan  1 2001 should be day 1 of the year');\n    assert.equal(moment([2001,  1, 28]).dayOfYear(),  59, 'Feb 28 2001 should be day 59 of the year');\n    assert.equal(moment([2001,  2,  1]).dayOfYear(),  60, 'Mar  1 2001 should be day 60 of the year');\n    assert.equal(moment([2001, 11, 31]).dayOfYear(), 365, 'Dec 31 2001 should be day 365 of the year');\n});\n\ntest('day of year setters', function (assert) {\n    assert.equal(moment([2000,  0,  1]).dayOfYear(200).dayOfYear(), 200, 'Setting Jan  1 2000 day of the year to 200 should work');\n    assert.equal(moment([2000,  1, 28]).dayOfYear(200).dayOfYear(), 200, 'Setting Feb 28 2000 day of the year to 200 should work');\n    assert.equal(moment([2000,  1, 29]).dayOfYear(200).dayOfYear(), 200, 'Setting Feb 28 2000 day of the year to 200 should work');\n    assert.equal(moment([2000, 11, 31]).dayOfYear(200).dayOfYear(), 200, 'Setting Dec 31 2000 day of the year to 200 should work');\n    assert.equal(moment().dayOfYear(1).dayOfYear(),   1, 'Setting day of the year to 1 should work');\n    assert.equal(moment().dayOfYear(59).dayOfYear(),  59, 'Setting day of the year to 59 should work');\n    assert.equal(moment().dayOfYear(60).dayOfYear(),  60, 'Setting day of the year to 60 should work');\n    assert.equal(moment().dayOfYear(365).dayOfYear(), 365, 'Setting day of the year to 365 should work');\n});\n\ntest('iso weeks year starting sunday', function (assert) {\n    assert.equal(moment([2012, 0, 1]).isoWeek(), 52, 'Jan  1 2012 should be iso week 52');\n    assert.equal(moment([2012, 0, 2]).isoWeek(),  1, 'Jan  2 2012 should be iso week 1');\n    assert.equal(moment([2012, 0, 8]).isoWeek(),  1, 'Jan  8 2012 should be iso week 1');\n    assert.equal(moment([2012, 0, 9]).isoWeek(),  2, 'Jan  9 2012 should be iso week 2');\n    assert.equal(moment([2012, 0, 15]).isoWeek(), 2, 'Jan 15 2012 should be iso week 2');\n});\n\ntest('iso weeks year starting monday', function (assert) {\n    assert.equal(moment([2007, 0, 1]).isoWeek(),  1, 'Jan  1 2007 should be iso week 1');\n    assert.equal(moment([2007, 0, 7]).isoWeek(),  1, 'Jan  7 2007 should be iso week 1');\n    assert.equal(moment([2007, 0, 8]).isoWeek(),  2, 'Jan  8 2007 should be iso week 2');\n    assert.equal(moment([2007, 0, 14]).isoWeek(), 2, 'Jan 14 2007 should be iso week 2');\n    assert.equal(moment([2007, 0, 15]).isoWeek(), 3, 'Jan 15 2007 should be iso week 3');\n});\n\ntest('iso weeks year starting tuesday', function (assert) {\n    assert.equal(moment([2007, 11, 31]).isoWeek(), 1, 'Dec 31 2007 should be iso week 1');\n    assert.equal(moment([2008,  0,  1]).isoWeek(), 1, 'Jan  1 2008 should be iso week 1');\n    assert.equal(moment([2008,  0,  6]).isoWeek(), 1, 'Jan  6 2008 should be iso week 1');\n    assert.equal(moment([2008,  0,  7]).isoWeek(), 2, 'Jan  7 2008 should be iso week 2');\n    assert.equal(moment([2008,  0, 13]).isoWeek(), 2, 'Jan 13 2008 should be iso week 2');\n    assert.equal(moment([2008,  0, 14]).isoWeek(), 3, 'Jan 14 2008 should be iso week 3');\n});\n\ntest('iso weeks year starting wednesday', function (assert) {\n    assert.equal(moment([2002, 11, 30]).isoWeek(), 1, 'Dec 30 2002 should be iso week 1');\n    assert.equal(moment([2003,  0,  1]).isoWeek(), 1, 'Jan  1 2003 should be iso week 1');\n    assert.equal(moment([2003,  0,  5]).isoWeek(), 1, 'Jan  5 2003 should be iso week 1');\n    assert.equal(moment([2003,  0,  6]).isoWeek(), 2, 'Jan  6 2003 should be iso week 2');\n    assert.equal(moment([2003,  0, 12]).isoWeek(), 2, 'Jan 12 2003 should be iso week 2');\n    assert.equal(moment([2003,  0, 13]).isoWeek(), 3, 'Jan 13 2003 should be iso week 3');\n});\n\ntest('iso weeks year starting thursday', function (assert) {\n    assert.equal(moment([2008, 11, 29]).isoWeek(), 1, 'Dec 29 2008 should be iso week 1');\n    assert.equal(moment([2009,  0,  1]).isoWeek(), 1, 'Jan  1 2009 should be iso week 1');\n    assert.equal(moment([2009,  0,  4]).isoWeek(), 1, 'Jan  4 2009 should be iso week 1');\n    assert.equal(moment([2009,  0,  5]).isoWeek(), 2, 'Jan  5 2009 should be iso week 2');\n    assert.equal(moment([2009,  0, 11]).isoWeek(), 2, 'Jan 11 2009 should be iso week 2');\n    assert.equal(moment([2009,  0, 13]).isoWeek(), 3, 'Jan 12 2009 should be iso week 3');\n});\n\ntest('iso weeks year starting friday', function (assert) {\n    assert.equal(moment([2009, 11, 28]).isoWeek(), 53, 'Dec 28 2009 should be iso week 53');\n    assert.equal(moment([2010,  0,  1]).isoWeek(), 53, 'Jan  1 2010 should be iso week 53');\n    assert.equal(moment([2010,  0,  3]).isoWeek(), 53, 'Jan  3 2010 should be iso week 53');\n    assert.equal(moment([2010,  0,  4]).isoWeek(),  1, 'Jan  4 2010 should be iso week 1');\n    assert.equal(moment([2010,  0, 10]).isoWeek(),  1, 'Jan 10 2010 should be iso week 1');\n    assert.equal(moment([2010,  0, 11]).isoWeek(),  2, 'Jan 11 2010 should be iso week 2');\n});\n\ntest('iso weeks year starting saturday', function (assert) {\n    assert.equal(moment([2010, 11, 27]).isoWeek(), 52, 'Dec 27 2010 should be iso week 52');\n    assert.equal(moment([2011,  0,  1]).isoWeek(), 52, 'Jan  1 2011 should be iso week 52');\n    assert.equal(moment([2011,  0,  2]).isoWeek(), 52, 'Jan  2 2011 should be iso week 52');\n    assert.equal(moment([2011,  0,  3]).isoWeek(),  1, 'Jan  3 2011 should be iso week 1');\n    assert.equal(moment([2011,  0,  9]).isoWeek(),  1, 'Jan  9 2011 should be iso week 1');\n    assert.equal(moment([2011,  0, 10]).isoWeek(),  2, 'Jan 10 2011 should be iso week 2');\n});\n\ntest('iso weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2012, 0,  1]).format('W WW Wo'), '52 52 52nd', 'Jan  1 2012 should be iso week 52');\n    assert.equal(moment([2012, 0,  2]).format('W WW Wo'),   '1 01 1st', 'Jan  2 2012 should be iso week 1');\n    assert.equal(moment([2012, 0,  8]).format('W WW Wo'),   '1 01 1st', 'Jan  8 2012 should be iso week 1');\n    assert.equal(moment([2012, 0,  9]).format('W WW Wo'),   '2 02 2nd', 'Jan  9 2012 should be iso week 2');\n    assert.equal(moment([2012, 0, 15]).format('W WW Wo'),   '2 02 2nd', 'Jan 15 2012 should be iso week 2');\n});\n\ntest('weeks plural year starting sunday', function (assert) {\n    assert.equal(moment([2012, 0,  1]).weeks(), 1, 'Jan  1 2012 should be week 1');\n    assert.equal(moment([2012, 0,  7]).weeks(), 1, 'Jan  7 2012 should be week 1');\n    assert.equal(moment([2012, 0,  8]).weeks(), 2, 'Jan  8 2012 should be week 2');\n    assert.equal(moment([2012, 0, 14]).weeks(), 2, 'Jan 14 2012 should be week 2');\n    assert.equal(moment([2012, 0, 15]).weeks(), 3, 'Jan 15 2012 should be week 3');\n});\n\ntest('iso weeks plural year starting sunday', function (assert) {\n    assert.equal(moment([2012, 0, 1]).isoWeeks(), 52, 'Jan  1 2012 should be iso week 52');\n    assert.equal(moment([2012, 0, 2]).isoWeeks(),  1, 'Jan  2 2012 should be iso week 1');\n    assert.equal(moment([2012, 0, 8]).isoWeeks(),  1, 'Jan  8 2012 should be iso week 1');\n    assert.equal(moment([2012, 0, 9]).isoWeeks(),  2, 'Jan  9 2012 should be iso week 2');\n    assert.equal(moment([2012, 0, 15]).isoWeeks(), 2, 'Jan 15 2012 should be iso week 2');\n});\n\ntest('weeks setter', function (assert) {\n    assert.equal(moment([2012, 0,  1]).week(30).week(), 30, 'Setting Jan 1 2012 to week 30 should work');\n    assert.equal(moment([2012, 0,  7]).week(30).week(), 30, 'Setting Jan 7 2012 to week 30 should work');\n    assert.equal(moment([2012, 0,  8]).week(30).week(), 30, 'Setting Jan 8 2012 to week 30 should work');\n    assert.equal(moment([2012, 0, 14]).week(30).week(), 30, 'Setting Jan 14 2012 to week 30 should work');\n    assert.equal(moment([2012, 0, 15]).week(30).week(), 30, 'Setting Jan 15 2012 to week 30 should work');\n});\n\ntest('iso weeks setter', function (assert) {\n    assert.equal(moment([2012, 0,  1]).isoWeeks(25).isoWeeks(), 25, 'Setting Jan  1 2012 to week 25 should work');\n    assert.equal(moment([2012, 0,  2]).isoWeeks(24).isoWeeks(), 24, 'Setting Jan  2 2012 to week 24 should work');\n    assert.equal(moment([2012, 0,  8]).isoWeeks(23).isoWeeks(), 23, 'Setting Jan  8 2012 to week 23 should work');\n    assert.equal(moment([2012, 0,  9]).isoWeeks(22).isoWeeks(), 22, 'Setting Jan  9 2012 to week 22 should work');\n    assert.equal(moment([2012, 0, 15]).isoWeeks(21).isoWeeks(), 21, 'Setting Jan 15 2012 to week 21 should work');\n});\n\ntest('iso weeks setter day of year', function (assert) {\n    assert.equal(moment([2012, 0,  1]).isoWeek(1).dayOfYear(), 9, 'Setting Jan  1 2012 to week 1 should be day of year 8');\n    assert.equal(moment([2012, 0,  1]).isoWeek(1).year(),   2011, 'Setting Jan  1 2012 to week 1 should be year 2011');\n    assert.equal(moment([2012, 0,  2]).isoWeek(1).dayOfYear(), 2, 'Setting Jan  2 2012 to week 1 should be day of year 2');\n    assert.equal(moment([2012, 0,  8]).isoWeek(1).dayOfYear(), 8, 'Setting Jan  8 2012 to week 1 should be day of year 8');\n    assert.equal(moment([2012, 0,  9]).isoWeek(1).dayOfYear(), 2, 'Setting Jan  9 2012 to week 1 should be day of year 2');\n    assert.equal(moment([2012, 0, 15]).isoWeek(1).dayOfYear(), 8, 'Setting Jan 15 2012 to week 1 should be day of year 8');\n});\n\ntest('years with iso week 53', function (assert) {\n    // Based on a table taken from https://en.wikipedia.org/wiki/ISO_week_date\n    // (as downloaded on 2014-01-06) listing the 71 years in a 400-year cycle\n    // that have 53 weeks; in this case reflecting the 2000 based cycle\n    assert.equal(moment([2004, 11, 31]).isoWeek(), 53, 'Dec 31 2004 should be iso week 53');\n    assert.equal(moment([2009, 11, 31]).isoWeek(), 53, 'Dec 31 2009 should be iso week 53');\n    assert.equal(moment([2015, 11, 31]).isoWeek(), 53, 'Dec 31 2015 should be iso week 53');\n    assert.equal(moment([2020, 11, 31]).isoWeek(), 53, 'Dec 31 2020 should be iso week 53');\n    assert.equal(moment([2026, 11, 31]).isoWeek(), 53, 'Dec 31 2026 should be iso week 53');\n    assert.equal(moment([2032, 11, 31]).isoWeek(), 53, 'Dec 31 2032 should be iso week 53');\n    assert.equal(moment([2037, 11, 31]).isoWeek(), 53, 'Dec 31 2037 should be iso week 53');\n    assert.equal(moment([2043, 11, 31]).isoWeek(), 53, 'Dec 31 2043 should be iso week 53');\n    assert.equal(moment([2048, 11, 31]).isoWeek(), 53, 'Dec 31 2048 should be iso week 53');\n    assert.equal(moment([2054, 11, 31]).isoWeek(), 53, 'Dec 31 2054 should be iso week 53');\n    assert.equal(moment([2060, 11, 31]).isoWeek(), 53, 'Dec 31 2060 should be iso week 53');\n    assert.equal(moment([2065, 11, 31]).isoWeek(), 53, 'Dec 31 2065 should be iso week 53');\n    assert.equal(moment([2071, 11, 31]).isoWeek(), 53, 'Dec 31 2071 should be iso week 53');\n    assert.equal(moment([2076, 11, 31]).isoWeek(), 53, 'Dec 31 2076 should be iso week 53');\n    assert.equal(moment([2082, 11, 31]).isoWeek(), 53, 'Dec 31 2082 should be iso week 53');\n    assert.equal(moment([2088, 11, 31]).isoWeek(), 53, 'Dec 31 2088 should be iso week 53');\n    assert.equal(moment([2093, 11, 31]).isoWeek(), 53, 'Dec 31 2093 should be iso week 53');\n    assert.equal(moment([2099, 11, 31]).isoWeek(), 53, 'Dec 31 2099 should be iso week 53');\n    assert.equal(moment([2105, 11, 31]).isoWeek(), 53, 'Dec 31 2105 should be iso week 53');\n    assert.equal(moment([2111, 11, 31]).isoWeek(), 53, 'Dec 31 2111 should be iso week 53');\n    assert.equal(moment([2116, 11, 31]).isoWeek(), 53, 'Dec 31 2116 should be iso week 53');\n    assert.equal(moment([2122, 11, 31]).isoWeek(), 53, 'Dec 31 2122 should be iso week 53');\n    assert.equal(moment([2128, 11, 31]).isoWeek(), 53, 'Dec 31 2128 should be iso week 53');\n    assert.equal(moment([2133, 11, 31]).isoWeek(), 53, 'Dec 31 2133 should be iso week 53');\n    assert.equal(moment([2139, 11, 31]).isoWeek(), 53, 'Dec 31 2139 should be iso week 53');\n    assert.equal(moment([2144, 11, 31]).isoWeek(), 53, 'Dec 31 2144 should be iso week 53');\n    assert.equal(moment([2150, 11, 31]).isoWeek(), 53, 'Dec 31 2150 should be iso week 53');\n    assert.equal(moment([2156, 11, 31]).isoWeek(), 53, 'Dec 31 2156 should be iso week 53');\n    assert.equal(moment([2161, 11, 31]).isoWeek(), 53, 'Dec 31 2161 should be iso week 53');\n    assert.equal(moment([2167, 11, 31]).isoWeek(), 53, 'Dec 31 2167 should be iso week 53');\n    assert.equal(moment([2172, 11, 31]).isoWeek(), 53, 'Dec 31 2172 should be iso week 53');\n    assert.equal(moment([2178, 11, 31]).isoWeek(), 53, 'Dec 31 2178 should be iso week 53');\n    assert.equal(moment([2184, 11, 31]).isoWeek(), 53, 'Dec 31 2184 should be iso week 53');\n    assert.equal(moment([2189, 11, 31]).isoWeek(), 53, 'Dec 31 2189 should be iso week 53');\n    assert.equal(moment([2195, 11, 31]).isoWeek(), 53, 'Dec 31 2195 should be iso week 53');\n    assert.equal(moment([2201, 11, 31]).isoWeek(), 53, 'Dec 31 2201 should be iso week 53');\n    assert.equal(moment([2207, 11, 31]).isoWeek(), 53, 'Dec 31 2207 should be iso week 53');\n    assert.equal(moment([2212, 11, 31]).isoWeek(), 53, 'Dec 31 2212 should be iso week 53');\n    assert.equal(moment([2218, 11, 31]).isoWeek(), 53, 'Dec 31 2218 should be iso week 53');\n    assert.equal(moment([2224, 11, 31]).isoWeek(), 53, 'Dec 31 2224 should be iso week 53');\n    assert.equal(moment([2229, 11, 31]).isoWeek(), 53, 'Dec 31 2229 should be iso week 53');\n    assert.equal(moment([2235, 11, 31]).isoWeek(), 53, 'Dec 31 2235 should be iso week 53');\n    assert.equal(moment([2240, 11, 31]).isoWeek(), 53, 'Dec 31 2240 should be iso week 53');\n    assert.equal(moment([2246, 11, 31]).isoWeek(), 53, 'Dec 31 2246 should be iso week 53');\n    assert.equal(moment([2252, 11, 31]).isoWeek(), 53, 'Dec 31 2252 should be iso week 53');\n    assert.equal(moment([2257, 11, 31]).isoWeek(), 53, 'Dec 31 2257 should be iso week 53');\n    assert.equal(moment([2263, 11, 31]).isoWeek(), 53, 'Dec 31 2263 should be iso week 53');\n    assert.equal(moment([2268, 11, 31]).isoWeek(), 53, 'Dec 31 2268 should be iso week 53');\n    assert.equal(moment([2274, 11, 31]).isoWeek(), 53, 'Dec 31 2274 should be iso week 53');\n    assert.equal(moment([2280, 11, 31]).isoWeek(), 53, 'Dec 31 2280 should be iso week 53');\n    assert.equal(moment([2285, 11, 31]).isoWeek(), 53, 'Dec 31 2285 should be iso week 53');\n    assert.equal(moment([2291, 11, 31]).isoWeek(), 53, 'Dec 31 2291 should be iso week 53');\n    assert.equal(moment([2296, 11, 31]).isoWeek(), 53, 'Dec 31 2296 should be iso week 53');\n    assert.equal(moment([2303, 11, 31]).isoWeek(), 53, 'Dec 31 2303 should be iso week 53');\n    assert.equal(moment([2308, 11, 31]).isoWeek(), 53, 'Dec 31 2308 should be iso week 53');\n    assert.equal(moment([2314, 11, 31]).isoWeek(), 53, 'Dec 31 2314 should be iso week 53');\n    assert.equal(moment([2320, 11, 31]).isoWeek(), 53, 'Dec 31 2320 should be iso week 53');\n    assert.equal(moment([2325, 11, 31]).isoWeek(), 53, 'Dec 31 2325 should be iso week 53');\n    assert.equal(moment([2331, 11, 31]).isoWeek(), 53, 'Dec 31 2331 should be iso week 53');\n    assert.equal(moment([2336, 11, 31]).isoWeek(), 53, 'Dec 31 2336 should be iso week 53');\n    assert.equal(moment([2342, 11, 31]).isoWeek(), 53, 'Dec 31 2342 should be iso week 53');\n    assert.equal(moment([2348, 11, 31]).isoWeek(), 53, 'Dec 31 2348 should be iso week 53');\n    assert.equal(moment([2353, 11, 31]).isoWeek(), 53, 'Dec 31 2353 should be iso week 53');\n    assert.equal(moment([2359, 11, 31]).isoWeek(), 53, 'Dec 31 2359 should be iso week 53');\n    assert.equal(moment([2364, 11, 31]).isoWeek(), 53, 'Dec 31 2364 should be iso week 53');\n    assert.equal(moment([2370, 11, 31]).isoWeek(), 53, 'Dec 31 2370 should be iso week 53');\n    assert.equal(moment([2376, 11, 31]).isoWeek(), 53, 'Dec 31 2376 should be iso week 53');\n    assert.equal(moment([2381, 11, 31]).isoWeek(), 53, 'Dec 31 2381 should be iso week 53');\n    assert.equal(moment([2387, 11, 31]).isoWeek(), 53, 'Dec 31 2387 should be iso week 53');\n    assert.equal(moment([2392, 11, 31]).isoWeek(), 53, 'Dec 31 2392 should be iso week 53');\n    assert.equal(moment([2398, 11, 31]).isoWeek(), 53, 'Dec 31 2398 should be iso week 53');\n});\n\ntest('count years with iso week 53', function (assert) {\n    // Based on https://en.wikipedia.org/wiki/ISO_week_date (as seen on 2014-01-06)\n    // stating that there are 71 years in a 400-year cycle that have 53 weeks;\n    // in this case reflecting the 2000 based cycle\n    var count = 0, i;\n    for (i = 0; i < 400; i++) {\n        count += (moment([2000 + i, 11, 31]).isoWeek() === 53) ? 1 : 0;\n    }\n    assert.equal(count, 71, 'Should have 71 years in 400-year cycle with iso week 53');\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\nfunction module$1 (name, lifecycle) {\n    QUnit.module(name, {\n        setup : function () {\n            moment.locale('en');\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'core');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            teardownDeprecationHandler(test, moment, 'core');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n}\n\nmodule$1('weeks in year');\n\ntest('isoWeeksInYear', function (assert) {\n    assert.equal(moment([2004]).isoWeeksInYear(), 53, '2004 has 53 iso weeks');\n    assert.equal(moment([2005]).isoWeeksInYear(), 52, '2005 has 53 iso weeks');\n    assert.equal(moment([2006]).isoWeeksInYear(), 52, '2006 has 53 iso weeks');\n    assert.equal(moment([2007]).isoWeeksInYear(), 52, '2007 has 52 iso weeks');\n    assert.equal(moment([2008]).isoWeeksInYear(), 52, '2008 has 53 iso weeks');\n    assert.equal(moment([2009]).isoWeeksInYear(), 53, '2009 has 53 iso weeks');\n    assert.equal(moment([2010]).isoWeeksInYear(), 52, '2010 has 52 iso weeks');\n    assert.equal(moment([2011]).isoWeeksInYear(), 52, '2011 has 52 iso weeks');\n    assert.equal(moment([2012]).isoWeeksInYear(), 52, '2012 has 52 iso weeks');\n    assert.equal(moment([2013]).isoWeeksInYear(), 52, '2013 has 52 iso weeks');\n    assert.equal(moment([2014]).isoWeeksInYear(), 52, '2014 has 52 iso weeks');\n    assert.equal(moment([2015]).isoWeeksInYear(), 53, '2015 has 53 iso weeks');\n});\n\ntest('weeksInYear doy/dow = 1/4', function (assert) {\n    moment.locale('1/4', {week: {dow: 1, doy: 4}});\n\n    assert.equal(moment([2004]).weeksInYear(), 53, '2004 has 53 weeks');\n    assert.equal(moment([2005]).weeksInYear(), 52, '2005 has 53 weeks');\n    assert.equal(moment([2006]).weeksInYear(), 52, '2006 has 53 weeks');\n    assert.equal(moment([2007]).weeksInYear(), 52, '2007 has 52 weeks');\n    assert.equal(moment([2008]).weeksInYear(), 52, '2008 has 53 weeks');\n    assert.equal(moment([2009]).weeksInYear(), 53, '2009 has 53 weeks');\n    assert.equal(moment([2010]).weeksInYear(), 52, '2010 has 52 weeks');\n    assert.equal(moment([2011]).weeksInYear(), 52, '2011 has 52 weeks');\n    assert.equal(moment([2012]).weeksInYear(), 52, '2012 has 52 weeks');\n    assert.equal(moment([2013]).weeksInYear(), 52, '2013 has 52 weeks');\n    assert.equal(moment([2014]).weeksInYear(), 52, '2014 has 52 weeks');\n    assert.equal(moment([2015]).weeksInYear(), 53, '2015 has 53 weeks');\n});\n\ntest('weeksInYear doy/dow = 6/12', function (assert) {\n    moment.locale('6/12', {week: {dow: 6, doy: 12}});\n\n    assert.equal(moment([2004]).weeksInYear(), 53, '2004 has 53 weeks');\n    assert.equal(moment([2005]).weeksInYear(), 52, '2005 has 53 weeks');\n    assert.equal(moment([2006]).weeksInYear(), 52, '2006 has 53 weeks');\n    assert.equal(moment([2007]).weeksInYear(), 52, '2007 has 52 weeks');\n    assert.equal(moment([2008]).weeksInYear(), 52, '2008 has 53 weeks');\n    assert.equal(moment([2009]).weeksInYear(), 52, '2009 has 53 weeks');\n    assert.equal(moment([2010]).weeksInYear(), 53, '2010 has 52 weeks');\n    assert.equal(moment([2011]).weeksInYear(), 52, '2011 has 52 weeks');\n    assert.equal(moment([2012]).weeksInYear(), 52, '2012 has 52 weeks');\n    assert.equal(moment([2013]).weeksInYear(), 52, '2013 has 52 weeks');\n    assert.equal(moment([2014]).weeksInYear(), 52, '2014 has 52 weeks');\n    assert.equal(moment([2015]).weeksInYear(), 52, '2015 has 53 weeks');\n});\n\ntest('weeksInYear doy/dow = 1/7', function (assert) {\n    moment.locale('1/7', {week: {dow: 1, doy: 7}});\n\n    assert.equal(moment([2004]).weeksInYear(), 52, '2004 has 53 weeks');\n    assert.equal(moment([2005]).weeksInYear(), 52, '2005 has 53 weeks');\n    assert.equal(moment([2006]).weeksInYear(), 53, '2006 has 53 weeks');\n    assert.equal(moment([2007]).weeksInYear(), 52, '2007 has 52 weeks');\n    assert.equal(moment([2008]).weeksInYear(), 52, '2008 has 53 weeks');\n    assert.equal(moment([2009]).weeksInYear(), 52, '2009 has 53 weeks');\n    assert.equal(moment([2010]).weeksInYear(), 52, '2010 has 52 weeks');\n    assert.equal(moment([2011]).weeksInYear(), 52, '2011 has 52 weeks');\n    assert.equal(moment([2012]).weeksInYear(), 53, '2012 has 52 weeks');\n    assert.equal(moment([2013]).weeksInYear(), 52, '2013 has 52 weeks');\n    assert.equal(moment([2014]).weeksInYear(), 52, '2014 has 52 weeks');\n    assert.equal(moment([2015]).weeksInYear(), 52, '2015 has 53 weeks');\n});\n\ntest('weeksInYear doy/dow = 0/6', function (assert) {\n    moment.locale('0/6', {week: {dow: 0, doy: 6}});\n\n    assert.equal(moment([2004]).weeksInYear(), 52, '2004 has 53 weeks');\n    assert.equal(moment([2005]).weeksInYear(), 53, '2005 has 53 weeks');\n    assert.equal(moment([2006]).weeksInYear(), 52, '2006 has 53 weeks');\n    assert.equal(moment([2007]).weeksInYear(), 52, '2007 has 52 weeks');\n    assert.equal(moment([2008]).weeksInYear(), 52, '2008 has 53 weeks');\n    assert.equal(moment([2009]).weeksInYear(), 52, '2009 has 53 weeks');\n    assert.equal(moment([2010]).weeksInYear(), 52, '2010 has 52 weeks');\n    assert.equal(moment([2011]).weeksInYear(), 53, '2011 has 52 weeks');\n    assert.equal(moment([2012]).weeksInYear(), 52, '2012 has 52 weeks');\n    assert.equal(moment([2013]).weeksInYear(), 52, '2013 has 52 weeks');\n    assert.equal(moment([2014]).weeksInYear(), 52, '2014 has 52 weeks');\n    assert.equal(moment([2015]).weeksInYear(), 52, '2015 has 53 weeks');\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\nfunction module$1 (name, lifecycle) {\n    QUnit.module(name, {\n        setup : function () {\n            moment.locale('en');\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'core');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            teardownDeprecationHandler(test, moment, 'core');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n}\n\nfunction isNearSpringDST() {\n    return moment().subtract(1, 'day').utcOffset() !== moment().add(1, 'day').utcOffset();\n}\n\nmodule$1('zone switching');\n\ntest('local to utc, keepLocalTime = true', function (assert) {\n    var m = moment(),\n        fmt = 'YYYY-DD-MM HH:mm:ss';\n    assert.equal(m.clone().utc(true).format(fmt), m.format(fmt), 'local to utc failed to keep local time');\n});\n\ntest('local to utc, keepLocalTime = false', function (assert) {\n    var m = moment();\n    assert.equal(m.clone().utc().valueOf(), m.valueOf(), 'local to utc failed to keep utc time (implicit)');\n    assert.equal(m.clone().utc(false).valueOf(), m.valueOf(), 'local to utc failed to keep utc time (explicit)');\n});\n\ntest('local to zone, keepLocalTime = true', function (assert) {\n    test.expectedDeprecations('moment().zone');\n    var m = moment(),\n        fmt = 'YYYY-DD-MM HH:mm:ss',\n        z;\n\n    // Apparently there is -12:00 and +14:00\n    // https://en.wikipedia.org/wiki/UTC+14:00\n    // https://en.wikipedia.org/wiki/UTC-12:00\n    for (z = -12; z <= 14; ++z) {\n        assert.equal(m.clone().zone(z * 60, true).format(fmt), m.format(fmt),\n                'local to zone(' + z + ':00) failed to keep local time');\n    }\n});\n\ntest('local to zone, keepLocalTime = false', function (assert) {\n    test.expectedDeprecations('moment().zone');\n    var m = moment(),\n        z;\n\n    // Apparently there is -12:00 and +14:00\n    // https://en.wikipedia.org/wiki/UTC+14:00\n    // https://en.wikipedia.org/wiki/UTC-12:00\n    for (z = -12; z <= 14; ++z) {\n        assert.equal(m.clone().zone(z * 60).valueOf(), m.valueOf(),\n                'local to zone(' + z + ':00) failed to keep utc time (implicit)');\n        assert.equal(m.clone().zone(z * 60, false).valueOf(), m.valueOf(),\n                'local to zone(' + z + ':00) failed to keep utc time (explicit)');\n    }\n});\n\ntest('utc to local, keepLocalTime = true', function (assert) {\n    // Don't test near the spring DST transition\n    if (isNearSpringDST()) {\n        expect(0);\n        return;\n    }\n\n    var um = moment.utc(),\n        fmt = 'YYYY-DD-MM HH:mm:ss';\n\n    assert.equal(um.clone().local(true).format(fmt), um.format(fmt), 'utc to local failed to keep local time');\n});\n\ntest('utc to local, keepLocalTime = false', function (assert) {\n    var um = moment.utc();\n    assert.equal(um.clone().local().valueOf(), um.valueOf(), 'utc to local failed to keep utc time (implicit)');\n    assert.equal(um.clone().local(false).valueOf(), um.valueOf(), 'utc to local failed to keep utc time (explicit)');\n});\n\ntest('zone to local, keepLocalTime = true', function (assert) {\n    // Don't test near the spring DST transition\n    if (isNearSpringDST()) {\n        expect(0);\n        return;\n    }\n\n    test.expectedDeprecations('moment().zone');\n\n    var m = moment(),\n        fmt = 'YYYY-DD-MM HH:mm:ss',\n        z;\n\n    // Apparently there is -12:00 and +14:00\n    // https://en.wikipedia.org/wiki/UTC+14:00\n    // https://en.wikipedia.org/wiki/UTC-12:00\n    for (z = -12; z <= 14; ++z) {\n        m.zone(z * 60);\n\n        assert.equal(m.clone().local(true).format(fmt), m.format(fmt),\n                'zone(' + z + ':00) to local failed to keep local time');\n    }\n});\n\ntest('zone to local, keepLocalTime = false', function (assert) {\n    test.expectedDeprecations('moment().zone');\n    var m = moment(),\n        z;\n\n    // Apparently there is -12:00 and +14:00\n    // https://en.wikipedia.org/wiki/UTC+14:00\n    // https://en.wikipedia.org/wiki/UTC-12:00\n    for (z = -12; z <= 14; ++z) {\n        m.zone(z * 60);\n\n        assert.equal(m.clone().local(false).valueOf(), m.valueOf(),\n                'zone(' + z + ':00) to local failed to keep utc time (explicit)');\n        assert.equal(m.clone().local().valueOf(), m.valueOf(),\n                'zone(' + z + ':00) to local failed to keep utc time (implicit)');\n    }\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\nfunction module$1 (name, lifecycle) {\n    QUnit.module(name, {\n        setup : function () {\n            moment.locale('en');\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'core');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            teardownDeprecationHandler(test, moment, 'core');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n}\n\nmodule$1('zones', {\n    'setup': function () {\n        test.expectedDeprecations('moment().zone');\n    }\n});\n\ntest('set zone', function (assert) {\n    var zone = moment();\n\n    zone.zone(0);\n    assert.equal(zone.zone(), 0, 'should be able to set the zone to 0');\n\n    zone.zone(60);\n    assert.equal(zone.zone(), 60, 'should be able to set the zone to 60');\n\n    zone.zone(-60);\n    assert.equal(zone.zone(), -60, 'should be able to set the zone to -60');\n});\n\ntest('set zone shorthand', function (assert) {\n    var zone = moment();\n\n    zone.zone(1);\n    assert.equal(zone.zone(), 60, 'setting the zone to 1 should imply hours and convert to 60');\n\n    zone.zone(-1);\n    assert.equal(zone.zone(), -60, 'setting the zone to -1 should imply hours and convert to -60');\n\n    zone.zone(15);\n    assert.equal(zone.zone(), 900, 'setting the zone to 15 should imply hours and convert to 900');\n\n    zone.zone(-15);\n    assert.equal(zone.zone(), -900, 'setting the zone to -15 should imply hours and convert to -900');\n\n    zone.zone(16);\n    assert.equal(zone.zone(), 16, 'setting the zone to 16 should imply minutes');\n\n    zone.zone(-16);\n    assert.equal(zone.zone(), -16, 'setting the zone to -16 should imply minutes');\n});\n\ntest('set zone with string', function (assert) {\n    var zone = moment();\n\n    zone.zone('+00:00');\n    assert.equal(zone.zone(), 0, 'set the zone with a timezone string');\n\n    zone.zone('2013-03-07T07:00:00-08:00');\n    assert.equal(zone.zone(), 480, 'set the zone with a string that does not begin with the timezone');\n\n    zone.zone('2013-03-07T07:00:00+0100');\n    assert.equal(zone.zone(), -60, 'set the zone with a string that uses the +0000 syntax');\n\n    zone.zone('2013-03-07T07:00:00+02');\n    assert.equal(zone.zone(), -120, 'set the zone with a string that uses the +00 syntax');\n\n    zone.zone('03-07-2013T07:00:00-08:00');\n    assert.equal(zone.zone(), 480, 'set the zone with a string with a non-ISO 8601 date');\n});\n\ntest('change hours when changing the zone', function (assert) {\n    var zone = moment.utc([2000, 0, 1, 6]);\n\n    zone.zone(0);\n    assert.equal(zone.hour(), 6, 'UTC 6AM should be 6AM at +0000');\n\n    zone.zone(60);\n    assert.equal(zone.hour(), 5, 'UTC 6AM should be 5AM at -0100');\n\n    zone.zone(-60);\n    assert.equal(zone.hour(), 7, 'UTC 6AM should be 7AM at +0100');\n});\n\ntest('change minutes when changing the zone', function (assert) {\n    var zone = moment.utc([2000, 0, 1, 6, 31]);\n\n    zone.zone(0);\n    assert.equal(zone.format('HH:mm'), '06:31', 'UTC 6:31AM should be 6:31AM at +0000');\n\n    zone.zone(30);\n    assert.equal(zone.format('HH:mm'), '06:01', 'UTC 6:31AM should be 6:01AM at -0030');\n\n    zone.zone(-30);\n    assert.equal(zone.format('HH:mm'), '07:01', 'UTC 6:31AM should be 7:01AM at +0030');\n\n    zone.zone(1380);\n    assert.equal(zone.format('HH:mm'), '07:31', 'UTC 6:31AM should be 7:31AM at +1380');\n});\n\ntest('distance from the unix epoch', function (assert) {\n    var zoneA = moment(),\n        zoneB = moment(zoneA),\n        zoneC = moment(zoneA),\n        zoneD = moment(zoneA),\n        zoneE = moment(zoneA);\n\n    zoneB.utc();\n    assert.equal(+zoneA, +zoneB, 'moment should equal moment.utc');\n\n    zoneC.zone(-60);\n    assert.equal(+zoneA, +zoneC, 'moment should equal moment.zone(-60)');\n\n    zoneD.zone(480);\n    assert.equal(+zoneA, +zoneD, 'moment should equal moment.zone(480)');\n\n    zoneE.zone(1000);\n    assert.equal(+zoneA, +zoneE, 'moment should equal moment.zone(1000)');\n});\n\ntest('update offset after changing any values', function (assert) {\n    var oldOffset = moment.updateOffset,\n        m = moment.utc([2000, 6, 1]);\n\n    moment.updateOffset = function (mom, keepTime) {\n        if (mom.__doChange) {\n            if (+mom > 962409600000) {\n                mom.zone(120, keepTime);\n            } else {\n                mom.zone(60, keepTime);\n            }\n        }\n    };\n\n    assert.equal(m.format('ZZ'), '+0000', 'should be at +0000');\n    assert.equal(m.format('HH:mm'), '00:00', 'should start 12AM at +0000 timezone');\n\n    m.__doChange = true;\n    m.add(1, 'h');\n\n    assert.equal(m.format('ZZ'), '-0200', 'should be at -0200');\n    assert.equal(m.format('HH:mm'), '23:00', '1AM at +0000 should be 11PM at -0200 timezone');\n\n    m.subtract(1, 'h');\n\n    assert.equal(m.format('ZZ'), '-0100', 'should be at -0100');\n    assert.equal(m.format('HH:mm'), '23:00', '12AM at +0000 should be 11PM at -0100 timezone');\n\n    moment.updateOffset = oldOffset;\n});\n\ntest('getters and setters', function (assert) {\n    var a = moment([2011, 5, 20]);\n\n    assert.equal(a.clone().zone(120).year(2012).year(), 2012, 'should get and set year correctly');\n    assert.equal(a.clone().zone(120).month(1).month(), 1, 'should get and set month correctly');\n    assert.equal(a.clone().zone(120).date(2).date(), 2, 'should get and set date correctly');\n    assert.equal(a.clone().zone(120).day(1).day(), 1, 'should get and set day correctly');\n    assert.equal(a.clone().zone(120).hour(1).hour(), 1, 'should get and set hour correctly');\n    assert.equal(a.clone().zone(120).minute(1).minute(), 1, 'should get and set minute correctly');\n});\n\ntest('getters', function (assert) {\n    var a = moment.utc([2012, 0, 1, 0, 0, 0]);\n\n    assert.equal(a.clone().zone(120).year(),  2011, 'should get year correctly');\n    assert.equal(a.clone().zone(120).month(),   11, 'should get month correctly');\n    assert.equal(a.clone().zone(120).date(),    31, 'should get date correctly');\n    assert.equal(a.clone().zone(120).hour(),    22, 'should get hour correctly');\n    assert.equal(a.clone().zone(120).minute(),   0, 'should get minute correctly');\n\n    assert.equal(a.clone().zone(-120).year(),  2012, 'should get year correctly');\n    assert.equal(a.clone().zone(-120).month(),    0, 'should get month correctly');\n    assert.equal(a.clone().zone(-120).date(),     1, 'should get date correctly');\n    assert.equal(a.clone().zone(-120).hour(),     2, 'should get hour correctly');\n    assert.equal(a.clone().zone(-120).minute(),   0, 'should get minute correctly');\n\n    assert.equal(a.clone().zone(-90).year(),  2012, 'should get year correctly');\n    assert.equal(a.clone().zone(-90).month(),    0, 'should get month correctly');\n    assert.equal(a.clone().zone(-90).date(),     1, 'should get date correctly');\n    assert.equal(a.clone().zone(-90).hour(),     1, 'should get hour correctly');\n    assert.equal(a.clone().zone(-90).minute(),  30, 'should get minute correctly');\n});\n\ntest('from', function (assert) {\n    var zoneA = moment(),\n        zoneB = moment(zoneA).zone(720),\n        zoneC = moment(zoneA).zone(360),\n        zoneD = moment(zoneA).zone(-690),\n        other = moment(zoneA).add(35, 'm');\n\n    assert.equal(zoneA.from(other), zoneB.from(other), 'moment#from should be the same in all zones');\n    assert.equal(zoneA.from(other), zoneC.from(other), 'moment#from should be the same in all zones');\n    assert.equal(zoneA.from(other), zoneD.from(other), 'moment#from should be the same in all zones');\n});\n\ntest('diff', function (assert) {\n    var zoneA = moment(),\n        zoneB = moment(zoneA).zone(720),\n        zoneC = moment(zoneA).zone(360),\n        zoneD = moment(zoneA).zone(-690),\n        other = moment(zoneA).add(35, 'm');\n\n    assert.equal(zoneA.diff(other), zoneB.diff(other), 'moment#diff should be the same in all zones');\n    assert.equal(zoneA.diff(other), zoneC.diff(other), 'moment#diff should be the same in all zones');\n    assert.equal(zoneA.diff(other), zoneD.diff(other), 'moment#diff should be the same in all zones');\n\n    assert.equal(zoneA.diff(other, 'minute', true), zoneB.diff(other, 'minute', true), 'moment#diff should be the same in all zones');\n    assert.equal(zoneA.diff(other, 'minute', true), zoneC.diff(other, 'minute', true), 'moment#diff should be the same in all zones');\n    assert.equal(zoneA.diff(other, 'minute', true), zoneD.diff(other, 'minute', true), 'moment#diff should be the same in all zones');\n\n    assert.equal(zoneA.diff(other, 'hour', true), zoneB.diff(other, 'hour', true), 'moment#diff should be the same in all zones');\n    assert.equal(zoneA.diff(other, 'hour', true), zoneC.diff(other, 'hour', true), 'moment#diff should be the same in all zones');\n    assert.equal(zoneA.diff(other, 'hour', true), zoneD.diff(other, 'hour', true), 'moment#diff should be the same in all zones');\n});\n\ntest('unix offset and timestamp', function (assert) {\n    var zoneA = moment(),\n        zoneB = moment(zoneA).zone(720),\n        zoneC = moment(zoneA).zone(360),\n        zoneD = moment(zoneA).zone(-690);\n\n    assert.equal(zoneA.unix(), zoneB.unix(), 'moment#unix should be the same in all zones');\n    assert.equal(zoneA.unix(), zoneC.unix(), 'moment#unix should be the same in all zones');\n    assert.equal(zoneA.unix(), zoneD.unix(), 'moment#unix should be the same in all zones');\n\n    assert.equal(+zoneA, +zoneB, 'moment#valueOf should be the same in all zones');\n    assert.equal(+zoneA, +zoneC, 'moment#valueOf should be the same in all zones');\n    assert.equal(+zoneA, +zoneD, 'moment#valueOf should be the same in all zones');\n});\n\ntest('cloning', function (assert) {\n    assert.equal(moment().zone(120).clone().zone(),   120, 'explicit cloning should retain the zone');\n    assert.equal(moment().zone(-120).clone().zone(), -120, 'explicit cloning should retain the zone');\n    assert.equal(moment(moment().zone(120)).zone(),   120, 'implicit cloning should retain the zone');\n    assert.equal(moment(moment().zone(-120)).zone(), -120, 'implicit cloning should retain the zone');\n});\n\ntest('start of / end of', function (assert) {\n    var a = moment.utc([2010, 1, 2, 0, 0, 0]).zone(450);\n\n    assert.equal(a.clone().startOf('day').hour(), 0, 'start of day should work on moments with a zone');\n    assert.equal(a.clone().startOf('day').minute(), 0, 'start of day should work on moments with a zone');\n    assert.equal(a.clone().startOf('hour').minute(), 0, 'start of hour should work on moments with a zone');\n\n    assert.equal(a.clone().endOf('day').hour(), 23, 'end of day should work on moments with a zone');\n    assert.equal(a.clone().endOf('day').minute(), 59, 'end of day should work on moments with a zone');\n    assert.equal(a.clone().endOf('hour').minute(), 59, 'end of hour should work on moments with a zone');\n});\n\ntest('reset zone with moment#utc', function (assert) {\n    var a = moment.utc([2012]).zone(480);\n\n    assert.equal(a.clone().hour(),      16, 'different zone should have different hour');\n    assert.equal(a.clone().utc().hour(), 0, 'calling moment#utc should reset the offset');\n});\n\ntest('reset zone with moment#local', function (assert) {\n    var a = moment([2012]).zone(480);\n\n    assert.equal(a.clone().local().hour(), 0, 'calling moment#local should reset the offset');\n});\n\ntest('toDate', function (assert) {\n    var zoneA = new Date(),\n        zoneB = moment(zoneA).zone(720).toDate(),\n        zoneC = moment(zoneA).zone(360).toDate(),\n        zoneD = moment(zoneA).zone(-690).toDate();\n\n    assert.equal(+zoneA, +zoneB, 'moment#toDate should output a date with the right unix timestamp');\n    assert.equal(+zoneA, +zoneC, 'moment#toDate should output a date with the right unix timestamp');\n    assert.equal(+zoneA, +zoneD, 'moment#toDate should output a date with the right unix timestamp');\n});\n\ntest('same / before / after', function (assert) {\n    var zoneA = moment().utc(),\n        zoneB = moment(zoneA).zone(120),\n        zoneC = moment(zoneA).zone(-120);\n\n    assert.ok(zoneA.isSame(zoneB), 'two moments with different offsets should be the same');\n    assert.ok(zoneA.isSame(zoneC), 'two moments with different offsets should be the same');\n\n    assert.ok(zoneA.isSame(zoneB, 'hour'), 'two moments with different offsets should be the same hour');\n    assert.ok(zoneA.isSame(zoneC, 'hour'), 'two moments with different offsets should be the same hour');\n\n    zoneA.add(1, 'hour');\n\n    assert.ok(zoneA.isAfter(zoneB), 'isAfter should work with two moments with different offsets');\n    assert.ok(zoneA.isAfter(zoneC), 'isAfter should work with two moments with different offsets');\n\n    assert.ok(zoneA.isAfter(zoneB, 'hour'), 'isAfter:hour should work with two moments with different offsets');\n    assert.ok(zoneA.isAfter(zoneC, 'hour'), 'isAfter:hour should work with two moments with different offsets');\n\n    zoneA.subtract(2, 'hour');\n\n    assert.ok(zoneA.isBefore(zoneB), 'isBefore should work with two moments with different offsets');\n    assert.ok(zoneA.isBefore(zoneC), 'isBefore should work with two moments with different offsets');\n\n    assert.ok(zoneA.isBefore(zoneB, 'hour'), 'isBefore:hour should work with two moments with different offsets');\n    assert.ok(zoneA.isBefore(zoneC, 'hour'), 'isBefore:hour should work with two moments with different offsets');\n});\n\ntest('add / subtract over dst', function (assert) {\n    var oldOffset = moment.updateOffset,\n        m = moment.utc([2000, 2, 31, 3]);\n\n    moment.updateOffset = function (mom, keepTime) {\n        if (mom.clone().utc().month() > 2) {\n            mom.zone(-60, keepTime);\n        } else {\n            mom.zone(0, keepTime);\n        }\n    };\n\n    assert.equal(m.hour(), 3, 'should start at 00:00');\n\n    m.add(24, 'hour');\n\n    assert.equal(m.hour(), 4, 'adding 24 hours should disregard dst');\n\n    m.subtract(24, 'hour');\n\n    assert.equal(m.hour(), 3, 'subtracting 24 hours should disregard dst');\n\n    m.add(1, 'day');\n\n    assert.equal(m.hour(), 3, 'adding 1 day should have the same hour');\n\n    m.subtract(1, 'day');\n\n    assert.equal(m.hour(), 3, 'subtracting 1 day should have the same hour');\n\n    m.add(1, 'month');\n\n    assert.equal(m.hour(), 3, 'adding 1 month should have the same hour');\n\n    m.subtract(1, 'month');\n\n    assert.equal(m.hour(), 3, 'subtracting 1 month should have the same hour');\n\n    moment.updateOffset = oldOffset;\n});\n\ntest('isDST', function (assert) {\n    var oldOffset = moment.updateOffset;\n\n    moment.updateOffset = function (mom, keepTime) {\n        if (mom.month() > 2 && mom.month() < 9) {\n            mom.zone(-60, keepTime);\n        } else {\n            mom.zone(0, keepTime);\n        }\n    };\n\n    assert.ok(!moment().month(0).isDST(),  'Jan should not be summer dst');\n    assert.ok(moment().month(6).isDST(),   'Jul should be summer dst');\n    assert.ok(!moment().month(11).isDST(), 'Dec should not be summer dst');\n\n    moment.updateOffset = function (mom) {\n        if (mom.month() > 2 && mom.month() < 9) {\n            mom.zone(0);\n        } else {\n            mom.zone(-60);\n        }\n    };\n\n    assert.ok(moment().month(0).isDST(),  'Jan should be winter dst');\n    assert.ok(!moment().month(6).isDST(), 'Jul should not be winter dst');\n    assert.ok(moment().month(11).isDST(), 'Dec should be winter dst');\n\n    moment.updateOffset = oldOffset;\n});\n\ntest('zone names', function (assert) {\n    test.expectedDeprecations();\n    assert.equal(moment().zoneAbbr(),   '', 'Local zone abbr should be empty');\n    assert.equal(moment().format('z'),  '', 'Local zone formatted abbr should be empty');\n    assert.equal(moment().zoneName(),   '', 'Local zone name should be empty');\n    assert.equal(moment().format('zz'), '', 'Local zone formatted name should be empty');\n\n    assert.equal(moment.utc().zoneAbbr(),   'UTC', 'UTC zone abbr should be UTC');\n    assert.equal(moment.utc().format('z'),  'UTC', 'UTC zone formatted abbr should be UTC');\n    assert.equal(moment.utc().zoneName(),   'Coordinated Universal Time', 'UTC zone abbr should be Coordinated Universal Time');\n    assert.equal(moment.utc().format('zz'), 'Coordinated Universal Time', 'UTC zone formatted abbr should be Coordinated Universal Time');\n});\n\ntest('hours alignment with UTC', function (assert) {\n    assert.equal(moment().zone(120).hasAlignedHourOffset(), true);\n    assert.equal(moment().zone(-180).hasAlignedHourOffset(), true);\n    assert.equal(moment().zone(90).hasAlignedHourOffset(), false);\n    assert.equal(moment().zone(-90).hasAlignedHourOffset(), false);\n});\n\ntest('hours alignment with other zone', function (assert) {\n    var m = moment().zone(120);\n\n    assert.equal(m.hasAlignedHourOffset(moment().zone(180)), true);\n    assert.equal(m.hasAlignedHourOffset(moment().zone(-180)), true);\n    assert.equal(m.hasAlignedHourOffset(moment().zone(90)), false);\n    assert.equal(m.hasAlignedHourOffset(moment().zone(-90)), false);\n\n    m = moment().zone(90);\n\n    assert.equal(m.hasAlignedHourOffset(moment().zone(180)), false);\n    assert.equal(m.hasAlignedHourOffset(moment().zone(-180)), false);\n    assert.equal(m.hasAlignedHourOffset(moment().zone(30)), true);\n    assert.equal(m.hasAlignedHourOffset(moment().zone(-30)), true);\n\n    m = moment().zone(-60);\n\n    assert.equal(m.hasAlignedHourOffset(moment().zone(180)), true);\n    assert.equal(m.hasAlignedHourOffset(moment().zone(-180)), true);\n    assert.equal(m.hasAlignedHourOffset(moment().zone(90)), false);\n    assert.equal(m.hasAlignedHourOffset(moment().zone(-90)), false);\n\n    m = moment().zone(25);\n\n    assert.equal(m.hasAlignedHourOffset(moment().zone(-35)), true);\n    assert.equal(m.hasAlignedHourOffset(moment().zone(85)), true);\n\n    assert.equal(m.hasAlignedHourOffset(moment().zone(35)), false);\n    assert.equal(m.hasAlignedHourOffset(moment().zone(-85)), false);\n});\n\ntest('parse zone', function (assert) {\n    var m = moment('2013-01-01T00:00:00-13:00').parseZone();\n    assert.equal(m.zone(), 13 * 60);\n    assert.equal(m.hours(), 0);\n});\n\ntest('parse zone static', function (assert) {\n    var m = moment.parseZone('2013-01-01T00:00:00-13:00');\n    assert.equal(m.zone(), 13 * 60);\n    assert.equal(m.hours(), 0);\n});\n\ntest('parse zone with more arguments', function (assert) {\n    test.expectedDeprecations();\n    var m;\n    m = moment.parseZone('2013 01 01 05 -13:00', 'YYYY MM DD HH ZZ');\n    assert.equal(m.format(), '2013-01-01T05:00:00-13:00', 'accept input and format');\n    m = moment.parseZone('2013-01-01-13:00', 'YYYY MM DD ZZ', true);\n    assert.equal(m.isValid(), false, 'accept input, format and strict flag');\n    m = moment.parseZone('2013-01-01-13:00', ['DD MM YYYY ZZ', 'YYYY MM DD ZZ']);\n    assert.equal(m.format(), '2013-01-01T00:00:00-13:00', 'accept input and array of formats');\n});\n\ntest('parse zone with a timezone from the format string', function (assert) {\n    var m = moment('11-12-2013 -0400 +1100', 'DD-MM-YYYY ZZ #####').parseZone();\n\n    assert.equal(m.zone(), 4 * 60);\n});\n\ntest('parse zone without a timezone included in the format string', function (assert) {\n    var m = moment('11-12-2013 -0400 +1100', 'DD-MM-YYYY').parseZone();\n\n    assert.equal(m.zone(), -11 * 60);\n});\n\ntest('timezone format', function (assert) {\n    assert.equal(moment().zone(-60).format('ZZ'), '+0100', '-60 -> +0100');\n    assert.equal(moment().zone(-90).format('ZZ'), '+0130', '-90 -> +0130');\n    assert.equal(moment().zone(-120).format('ZZ'), '+0200', '-120 -> +0200');\n\n    assert.equal(moment().zone(+60).format('ZZ'), '-0100', '+60 -> -0100');\n    assert.equal(moment().zone(+90).format('ZZ'), '-0130', '+90 -> -0130');\n    assert.equal(moment().zone(+120).format('ZZ'), '-0200', '+120 -> -0200');\n});\n\ntest('parse zone without a timezone', function (assert) {\n    test.expectedDeprecations();\n    var m1 = moment.parseZone('2016-02-01T00:00:00');\n    var m2 = moment.parseZone('2016-02-01T00:00:00Z');\n    var m3 = moment.parseZone('2016-02-01T00:00:00+00:00'); //Someone might argue this is not necessary, you could even argue that is wrong being here.\n    var m4 = moment.parseZone('2016-02-01T00:00:00+0000'); //Someone might argue this is not necessary, you could even argue that is wrong being here.\n    assert.equal(\n        m1.format('M D YYYY HH:mm:ss ZZ'),\n        '2 1 2016 00:00:00 +0000',\n        'Not providing a timezone should keep the time and change the zone to 0'\n    );\n    assert.equal(\n        m2.format('M D YYYY HH:mm:ss ZZ'),\n        '2 1 2016 00:00:00 +0000',\n        'Not providing a timezone should keep the time and change the zone to 0'\n    );\n    assert.equal(\n        m3.format('M D YYYY HH:mm:ss ZZ'),\n        '2 1 2016 00:00:00 +0000',\n        'Not providing a timezone should keep the time and change the zone to 0'\n    );\n    assert.equal(\n        m4.format('M D YYYY HH:mm:ss ZZ'),\n        '2 1 2016 00:00:00 +0000',\n        'Not providing a timezone should keep the time and change the zone to 0'\n    );\n});\n\ntest('parse zone with a minutes unit abs less than 16 should retain minutes', function (assert) {\n    //ensure when minutes are explicitly parsed, they are retained\n    //instead of converted to hours, even if less than 16\n    var n = moment.parseZone('2013-01-01T00:00:00-00:15');\n    assert.equal(n.utcOffset(), -15);\n    assert.equal(n.zone(), 15);\n    assert.equal(n.hour(), 0);\n    var o = moment.parseZone('2013-01-01T00:00:00+00:15');\n    assert.equal(o.utcOffset(), 15);\n    assert.equal(o.zone(), -15);\n    assert.equal(o.hour(), 0);\n});\n\n})));\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/moment.d.ts",
    "content": "declare function moment(inp?: moment.MomentInput, format?: moment.MomentFormatSpecification, strict?: boolean): moment.Moment;\ndeclare function moment(inp?: moment.MomentInput, format?: moment.MomentFormatSpecification, language?: string, strict?: boolean): moment.Moment;\n\ndeclare namespace moment {\n  type RelativeTimeKey = 's' | 'm' | 'mm' | 'h' | 'hh' | 'd' | 'dd' | 'M' | 'MM' | 'y' | 'yy';\n  type CalendarKey = 'sameDay' | 'nextDay' | 'lastDay' | 'nextWeek' | 'lastWeek' | 'sameElse' | string;\n  type LongDateFormatKey = 'LTS' | 'LT' | 'L' | 'LL' | 'LLL' | 'LLLL' | 'lts' | 'lt' | 'l' | 'll' | 'lll' | 'llll';\n\n  interface Locale {\n    calendar(key?: CalendarKey, m?: Moment, now?: Moment): string;\n\n    longDateFormat(key: LongDateFormatKey): string;\n    invalidDate(): string;\n    ordinal(n: number): string;\n\n    preparse(inp: string): string;\n    postformat(inp: string): string;\n    relativeTime(n: number, withoutSuffix: boolean,\n                 key: RelativeTimeKey, isFuture: boolean): string;\n    pastFuture(diff: number, absRelTime: string): string;\n    set(config: Object): void;\n\n    months(): string[];\n    months(m: Moment, format?: string): string;\n    monthsShort(): string[];\n    monthsShort(m: Moment, format?: string): string;\n    monthsParse(monthName: string, format: string, strict: boolean): number;\n    monthsRegex(strict: boolean): RegExp;\n    monthsShortRegex(strict: boolean): RegExp;\n\n    week(m: Moment): number;\n    firstDayOfYear(): number;\n    firstDayOfWeek(): number;\n\n    weekdays(): string[];\n    weekdays(m: Moment, format?: string): string;\n    weekdaysMin(): string[];\n    weekdaysMin(m: Moment): string;\n    weekdaysShort(): string[];\n    weekdaysShort(m: Moment): string;\n    weekdaysParse(weekdayName: string, format: string, strict: boolean): number;\n    weekdaysRegex(strict: boolean): RegExp;\n    weekdaysShortRegex(strict: boolean): RegExp;\n    weekdaysMinRegex(strict: boolean): RegExp;\n\n    isPM(input: string): boolean;\n    meridiem(hour: number, minute: number, isLower: boolean): string;\n  }\n\n  interface StandaloneFormatSpec {\n    format: string[];\n    standalone: string[];\n    isFormat?: RegExp;\n  }\n\n  interface WeekSpec {\n    dow: number;\n    doy: number;\n  }\n\n  type CalendarSpecVal = string | ((m?: MomentInput, now?: Moment) => string);\n  interface CalendarSpec {\n    sameDay?: CalendarSpecVal;\n    nextDay?: CalendarSpecVal;\n    lastDay?: CalendarSpecVal;\n    nextWeek?: CalendarSpecVal;\n    lastWeek?: CalendarSpecVal;\n    sameElse?: CalendarSpecVal;\n\n    // any additional properties might be used with moment.calendarFormat\n    [x: string]: CalendarSpecVal | void; // undefined\n  }\n\n  type RelativeTimeSpecVal = (\n    string |\n    ((n: number, withoutSuffix: boolean,\n      key: RelativeTimeKey, isFuture: boolean) => string)\n  );\n  type RelativeTimeFuturePastVal = string | ((relTime: string) => string);\n\n  interface RelativeTimeSpec {\n    future: RelativeTimeFuturePastVal;\n    past: RelativeTimeFuturePastVal;\n    s: RelativeTimeSpecVal;\n    m: RelativeTimeSpecVal;\n    mm: RelativeTimeSpecVal;\n    h: RelativeTimeSpecVal;\n    hh: RelativeTimeSpecVal;\n    d: RelativeTimeSpecVal;\n    dd: RelativeTimeSpecVal;\n    M: RelativeTimeSpecVal;\n    MM: RelativeTimeSpecVal;\n    y: RelativeTimeSpecVal;\n    yy: RelativeTimeSpecVal;\n  }\n\n  interface LongDateFormatSpec {\n    LTS: string;\n    LT: string;\n    L: string;\n    LL: string;\n    LLL: string;\n    LLLL: string;\n\n    // lets forget for a sec that any upper/lower permutation will also work\n    lts?: string;\n    lt?: string;\n    l?: string;\n    ll?: string;\n    lll?: string;\n    llll?: string;\n  }\n\n  type MonthWeekdayFn = (momentToFormat: Moment, format?: string) => string;\n  type WeekdaySimpleFn = (momentToFormat: Moment) => string;\n\n  interface LocaleSpecification {\n    months?: string[] | StandaloneFormatSpec | MonthWeekdayFn;\n    monthsShort?: string[] | StandaloneFormatSpec | MonthWeekdayFn;\n\n    weekdays?: string[] | StandaloneFormatSpec | MonthWeekdayFn;\n    weekdaysShort?: string[] | StandaloneFormatSpec | WeekdaySimpleFn;\n    weekdaysMin?: string[] | StandaloneFormatSpec | WeekdaySimpleFn;\n\n    meridiemParse?: RegExp;\n    meridiem?: (hour: number, minute:number, isLower: boolean) => string;\n\n    isPM?: (input: string) => boolean;\n\n    longDateFormat?: LongDateFormatSpec;\n    calendar?: CalendarSpec;\n    relativeTime?: RelativeTimeSpec;\n    invalidDate?: string;\n    ordinal?: (n: number) => string;\n    ordinalParse?: RegExp;\n\n    week?: WeekSpec;\n\n    // Allow anything: in general any property that is passed as locale spec is\n    // put in the locale object so it can be used by locale functions\n    [x: string]: any;\n  }\n\n  interface MomentObjectOutput {\n    years: number;\n    /* One digit */\n    months: number;\n    /* Day of the month */\n    date: number;\n    hours: number;\n    minutes: number;\n    seconds: number;\n    milliseconds: number;\n  }\n\n  interface Duration {\n    humanize(withSuffix?: boolean): string;\n\n    abs(): Duration;\n\n    as(units: unitOfTime.Base): number;\n    get(units: unitOfTime.Base): number;\n\n    milliseconds(): number;\n    asMilliseconds(): number;\n\n    seconds(): number;\n    asSeconds(): number;\n\n    minutes(): number;\n    asMinutes(): number;\n\n    hours(): number;\n    asHours(): number;\n\n    days(): number;\n    asDays(): number;\n\n    weeks(): number;\n    asWeeks(): number;\n\n    months(): number;\n    asMonths(): number;\n\n    years(): number;\n    asYears(): number;\n\n    add(inp?: DurationInputArg1, unit?: DurationInputArg2): Duration;\n    subtract(inp?: DurationInputArg1, unit?: DurationInputArg2): Duration;\n\n    locale(): string;\n    locale(locale: LocaleSpecifier): Duration;\n    localeData(): Locale;\n\n    toISOString(): string;\n    toJSON(): string;\n\n    /**\n     * @deprecated since version 2.8.0\n     */\n    lang(locale: LocaleSpecifier): Moment;\n    /**\n     * @deprecated since version 2.8.0\n     */\n    lang(): Locale;\n    /**\n     * @deprecated\n     */\n    toIsoString(): string;\n  }\n\n  interface MomentRelativeTime {\n    future: any;\n    past: any;\n    s: any;\n    m: any;\n    mm: any;\n    h: any;\n    hh: any;\n    d: any;\n    dd: any;\n    M: any;\n    MM: any;\n    y: any;\n    yy: any;\n  }\n\n  interface MomentLongDateFormat {\n    L: string;\n    LL: string;\n    LLL: string;\n    LLLL: string;\n    LT: string;\n    LTS: string;\n\n    l?: string;\n    ll?: string;\n    lll?: string;\n    llll?: string;\n    lt?: string;\n    lts?: string;\n  }\n\n  interface MomentParsingFlags {\n    empty: boolean;\n    unusedTokens: string[];\n    unusedInput: string[];\n    overflow: number;\n    charsLeftOver: number;\n    nullInput: boolean;\n    invalidMonth: string | void; // null\n    invalidFormat: boolean;\n    userInvalidated: boolean;\n    iso: boolean;\n    parsedDateParts: any[];\n    meridiem: string | void; // null\n  }\n\n  interface MomentParsingFlagsOpt {\n    empty?: boolean;\n    unusedTokens?: string[];\n    unusedInput?: string[];\n    overflow?: number;\n    charsLeftOver?: number;\n    nullInput?: boolean;\n    invalidMonth?: string;\n    invalidFormat?: boolean;\n    userInvalidated?: boolean;\n    iso?: boolean;\n    parsedDateParts?: any[];\n    meridiem?: string;\n  }\n\n  interface MomentBuiltinFormat {\n    __momentBuiltinFormatBrand: any;\n  }\n\n  type MomentFormatSpecification = string | MomentBuiltinFormat | (string | MomentBuiltinFormat)[];\n\n  namespace unitOfTime {\n    type Base = (\n      \"year\" | \"years\" | \"y\" |\n      \"month\" | \"months\" | \"M\" |\n      \"week\" | \"weeks\" | \"w\" |\n      \"day\" | \"days\" | \"d\" |\n      \"hour\" | \"hours\" | \"h\" |\n      \"minute\" | \"minutes\" | \"m\" |\n      \"second\" | \"seconds\" | \"s\" |\n      \"millisecond\" | \"milliseconds\" | \"ms\"\n    );\n\n    type _quarter = \"quarter\" | \"quarters\" | \"Q\";\n    type _isoWeek = \"isoWeek\" | \"isoWeeks\" | \"W\";\n    type _date = \"date\" | \"dates\" | \"D\";\n    type DurationConstructor = Base | _quarter;\n\n    type DurationAs = Base;\n\n    type StartOf = Base | _quarter | _isoWeek | _date;\n\n    type Diff = Base | _quarter;\n\n    type MomentConstructor = Base | _date;\n\n    type All = Base | _quarter | _isoWeek | _date |\n      \"weekYear\" | \"weekYears\" | \"gg\" |\n      \"isoWeekYear\" | \"isoWeekYears\" | \"GG\" |\n      \"dayOfYear\" | \"dayOfYears\" | \"DDD\" |\n      \"weekday\" | \"weekdays\" | \"e\" |\n      \"isoWeekday\" | \"isoWeekdays\" | \"E\";\n  }\n\n  interface MomentInputObject {\n    years?: number;\n    year?: number;\n    y?: number;\n\n    months?: number;\n    month?: number;\n    M?: number;\n\n    days?: number;\n    day?: number;\n    d?: number;\n\n    dates?: number;\n    date?: number;\n    D?: number;\n\n    hours?: number;\n    hour?: number;\n    h?: number;\n\n    minutes?: number;\n    minute?: number;\n    m?: number;\n\n    seconds?: number;\n    second?: number;\n    s?: number;\n\n    milliseconds?: number;\n    millisecond?: number;\n    ms?: number;\n  }\n\n  interface DurationInputObject extends MomentInputObject {\n    quarters?: number;\n    quarter?: number;\n    Q?: number;\n\n    weeks?: number;\n    week?: number;\n    w?: number;\n  }\n\n  interface MomentSetObject extends MomentInputObject {\n    weekYears?: number;\n    weekYear?: number;\n    gg?: number;\n\n    isoWeekYears?: number;\n    isoWeekYear?: number;\n    GG?: number;\n\n    quarters?: number;\n    quarter?: number;\n    Q?: number;\n\n    weeks?: number;\n    week?: number;\n    w?: number;\n\n    isoWeeks?: number;\n    isoWeek?: number;\n    W?: number;\n\n    dayOfYears?: number;\n    dayOfYear?: number;\n    DDD?: number;\n\n    weekdays?: number;\n    weekday?: number;\n    e?: number;\n\n    isoWeekdays?: number;\n    isoWeekday?: number;\n    E?: number;\n  }\n\n  interface FromTo {\n    from: MomentInput;\n    to: MomentInput;\n  }\n\n  type MomentInput = Moment | Date | string | number | (number | string)[] | MomentInputObject | void; // null | undefined\n  type DurationInputArg1 = Duration | number | string | FromTo | DurationInputObject | void; // null | undefined\n  type DurationInputArg2 = unitOfTime.DurationConstructor;\n  type LocaleSpecifier = string | Moment | Duration | string[] | boolean;\n\n  interface MomentCreationData {\n    input: MomentInput;\n    format?: MomentFormatSpecification;\n    locale: Locale;\n    isUTC: boolean;\n    strict?: boolean;\n  }\n\n  interface Moment extends Object{\n    format(format?: string): string;\n\n    startOf(unitOfTime: unitOfTime.StartOf): Moment;\n    endOf(unitOfTime: unitOfTime.StartOf): Moment;\n\n    add(amount?: DurationInputArg1, unit?: DurationInputArg2): Moment;\n    /**\n     * @deprecated reverse syntax\n     */\n    add(unit: unitOfTime.DurationConstructor, amount: number|string): Moment;\n\n    subtract(amount?: DurationInputArg1, unit?: DurationInputArg2): Moment;\n    /**\n     * @deprecated reverse syntax\n     */\n    subtract(unit: unitOfTime.DurationConstructor, amount: number|string): Moment;\n\n    calendar(time?: MomentInput, formats?: CalendarSpec): string;\n\n    clone(): Moment;\n\n    /**\n     * @return Unix timestamp in milliseconds\n     */\n    valueOf(): number;\n\n    // current date/time in local mode\n    local(keepLocalTime?: boolean): Moment;\n    isLocal(): boolean;\n\n    // current date/time in UTC mode\n    utc(keepLocalTime?: boolean): Moment;\n    isUTC(): boolean;\n    /**\n     * @deprecated use isUTC\n     */\n    isUtc(): boolean;\n\n    parseZone(): Moment;\n    isValid(): boolean;\n    invalidAt(): number;\n\n    hasAlignedHourOffset(other?: MomentInput): boolean;\n\n    creationData(): MomentCreationData;\n    parsingFlags(): MomentParsingFlags;\n\n    year(y: number): Moment;\n    year(): number;\n    /**\n     * @deprecated use year(y)\n     */\n    years(y: number): Moment;\n    /**\n     * @deprecated use year()\n     */\n    years(): number;\n    quarter(): number;\n    quarter(q: number): Moment;\n    quarters(): number;\n    quarters(q: number): Moment;\n    month(M: number|string): Moment;\n    month(): number;\n    /**\n     * @deprecated use month(M)\n     */\n    months(M: number|string): Moment;\n    /**\n     * @deprecated use month()\n     */\n    months(): number;\n    day(d: number|string): Moment;\n    day(): number;\n    days(d: number|string): Moment;\n    days(): number;\n    date(d: number): Moment;\n    date(): number;\n    /**\n     * @deprecated use date(d)\n     */\n    dates(d: number): Moment;\n    /**\n     * @deprecated use date()\n     */\n    dates(): number;\n    hour(h: number): Moment;\n    hour(): number;\n    hours(h: number): Moment;\n    hours(): number;\n    minute(m: number): Moment;\n    minute(): number;\n    minutes(m: number): Moment;\n    minutes(): number;\n    second(s: number): Moment;\n    second(): number;\n    seconds(s: number): Moment;\n    seconds(): number;\n    millisecond(ms: number): Moment;\n    millisecond(): number;\n    milliseconds(ms: number): Moment;\n    milliseconds(): number;\n    weekday(): number;\n    weekday(d: number): Moment;\n    isoWeekday(): number;\n    isoWeekday(d: number|string): Moment;\n    weekYear(): number;\n    weekYear(d: number): Moment;\n    isoWeekYear(): number;\n    isoWeekYear(d: number): Moment;\n    week(): number;\n    week(d: number): Moment;\n    weeks(): number;\n    weeks(d: number): Moment;\n    isoWeek(): number;\n    isoWeek(d: number): Moment;\n    isoWeeks(): number;\n    isoWeeks(d: number): Moment;\n    weeksInYear(): number;\n    isoWeeksInYear(): number;\n    dayOfYear(): number;\n    dayOfYear(d: number): Moment;\n\n    from(inp: MomentInput, suffix?: boolean): string;\n    to(inp: MomentInput, suffix?: boolean): string;\n    fromNow(withoutSuffix?: boolean): string;\n    toNow(withoutPrefix?: boolean): string;\n\n    diff(b: MomentInput, unitOfTime?: unitOfTime.Diff, precise?: boolean): number;\n\n    toArray(): number[];\n    toDate(): Date;\n    toISOString(): string;\n    inspect(): string;\n    toJSON(): string;\n    unix(): number;\n\n    isLeapYear(): boolean;\n    /**\n     * @deprecated in favor of utcOffset\n     */\n    zone(): number;\n    zone(b: number|string): Moment;\n    utcOffset(): number;\n    utcOffset(b: number|string, keepLocalTime?: boolean): Moment;\n    isUtcOffset(): boolean;\n    daysInMonth(): number;\n    isDST(): boolean;\n\n    zoneAbbr(): string;\n    zoneName(): string;\n\n    isBefore(inp?: MomentInput, granularity?: unitOfTime.StartOf): boolean;\n    isAfter(inp?: MomentInput, granularity?: unitOfTime.StartOf): boolean;\n    isSame(inp?: MomentInput, granularity?: unitOfTime.StartOf): boolean;\n    isSameOrAfter(inp?: MomentInput, granularity?: unitOfTime.StartOf): boolean;\n    isSameOrBefore(inp?: MomentInput, granularity?: unitOfTime.StartOf): boolean;\n    isBetween(a: MomentInput, b: MomentInput, granularity?: unitOfTime.StartOf, inclusivity?: \"()\" | \"[)\" | \"(]\" | \"[]\"): boolean;\n\n    /**\n     * @deprecated as of 2.8.0, use locale\n     */\n    lang(language: LocaleSpecifier): Moment;\n    /**\n     * @deprecated as of 2.8.0, use locale\n     */\n    lang(): Locale;\n\n    locale(): string;\n    locale(locale: LocaleSpecifier): Moment;\n\n    localeData(): Locale;\n\n    /**\n     * @deprecated no reliable implementation\n     */\n    isDSTShifted(): boolean;\n\n    // NOTE(constructor): Same as moment constructor\n    /**\n     * @deprecated as of 2.7.0, use moment.min/max\n     */\n    max(inp?: MomentInput, format?: MomentFormatSpecification, strict?: boolean): Moment;\n    /**\n     * @deprecated as of 2.7.0, use moment.min/max\n     */\n    max(inp?: MomentInput, format?: MomentFormatSpecification, language?: string, strict?: boolean): Moment;\n\n    // NOTE(constructor): Same as moment constructor\n    /**\n     * @deprecated as of 2.7.0, use moment.min/max\n     */\n    min(inp?: MomentInput, format?: MomentFormatSpecification, strict?: boolean): Moment;\n    /**\n     * @deprecated as of 2.7.0, use moment.min/max\n     */\n    min(inp?: MomentInput, format?: MomentFormatSpecification, language?: string, strict?: boolean): Moment;\n\n    get(unit: unitOfTime.All): number;\n    set(unit: unitOfTime.All, value: number): Moment;\n    set(objectLiteral: MomentSetObject): Moment;\n\n    toObject(): MomentObjectOutput;\n  }\n\n  export var version: string;\n  export var fn: Moment;\n\n  // NOTE(constructor): Same as moment constructor\n  export function utc(inp?: MomentInput, format?: MomentFormatSpecification, strict?: boolean): Moment;\n  export function utc(inp?: MomentInput, format?: MomentFormatSpecification, language?: string, strict?: boolean): Moment;\n\n  export function unix(timestamp: number): Moment;\n\n  export function invalid(flags?: MomentParsingFlagsOpt): Moment;\n  export function isMoment(m: any): m is Moment;\n  export function isDate(m: any): m is Date;\n  export function isDuration(d: any): d is Duration;\n\n  /**\n   * @deprecated in 2.8.0\n   */\n  export function lang(language?: string): string;\n  /**\n   * @deprecated in 2.8.0\n   */\n  export function lang(language?: string, definition?: Locale): string;\n\n  export function locale(language?: string): string;\n  export function locale(language?: string[]): string;\n  export function locale(language?: string, definition?: LocaleSpecification | void): string; // null | undefined\n\n  export function localeData(key?: string | string[]): Locale;\n\n  export function duration(inp?: DurationInputArg1, unit?: DurationInputArg2): Duration;\n\n  // NOTE(constructor): Same as moment constructor\n  export function parseZone(inp?: MomentInput, format?: MomentFormatSpecification, strict?: boolean): Moment;\n  export function parseZone(inp?: MomentInput, format?: MomentFormatSpecification, language?: string, strict?: boolean): Moment;\n\n  export function months(): string[];\n  export function months(index: number): string;\n  export function months(format: string): string[];\n  export function months(format: string, index: number): string;\n  export function monthsShort(): string[];\n  export function monthsShort(index: number): string;\n  export function monthsShort(format: string): string[];\n  export function monthsShort(format: string, index: number): string;\n\n  export function weekdays(): string[];\n  export function weekdays(index: number): string;\n  export function weekdays(format: string): string[];\n  export function weekdays(format: string, index: number): string;\n  export function weekdays(localeSorted: boolean): string[];\n  export function weekdays(localeSorted: boolean, index: number): string;\n  export function weekdays(localeSorted: boolean, format: string): string[];\n  export function weekdays(localeSorted: boolean, format: string, index: number): string;\n  export function weekdaysShort(): string[];\n  export function weekdaysShort(index: number): string;\n  export function weekdaysShort(format: string): string[];\n  export function weekdaysShort(format: string, index: number): string;\n  export function weekdaysShort(localeSorted: boolean): string[];\n  export function weekdaysShort(localeSorted: boolean, index: number): string;\n  export function weekdaysShort(localeSorted: boolean, format: string): string[];\n  export function weekdaysShort(localeSorted: boolean, format: string, index: number): string;\n  export function weekdaysMin(): string[];\n  export function weekdaysMin(index: number): string;\n  export function weekdaysMin(format: string): string[];\n  export function weekdaysMin(format: string, index: number): string;\n  export function weekdaysMin(localeSorted: boolean): string[];\n  export function weekdaysMin(localeSorted: boolean, index: number): string;\n  export function weekdaysMin(localeSorted: boolean, format: string): string[];\n  export function weekdaysMin(localeSorted: boolean, format: string, index: number): string;\n\n  export function min(...moments: MomentInput[]): Moment;\n  export function max(...moments: MomentInput[]): Moment;\n\n  /**\n   * Returns unix time in milliseconds. Overwrite for profit.\n   */\n  export function now(): number;\n\n  export function defineLocale(language: string, localeSpec: LocaleSpecification | void): Locale; // null\n  export function updateLocale(language: string, localeSpec: LocaleSpecification | void): Locale; // null\n\n  export function locales(): string[];\n\n  export function normalizeUnits(unit: unitOfTime.All): string;\n  export function relativeTimeThreshold(threshold: string): number | boolean;\n  export function relativeTimeThreshold(threshold: string, limit: number): boolean;\n  export function relativeTimeRounding(fn: (num: number) => number): boolean;\n  export function relativeTimeRounding(): (num: number) => number;\n  export function calendarFormat(m: Moment, now: Moment): string;\n\n  /**\n   * Constant used to enable explicit ISO_8601 format parsing.\n   */\n  export var ISO_8601: MomentBuiltinFormat;\n\n  export var defaultFormat: string;\n  export var defaultFormatUtc: string;\n}\n\nexport = moment;\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/moment.js",
    "content": "//! moment.js\n//! version : 2.18.1\n//! authors : Tim Wood, Iskren Chernev, Moment.js contributors\n//! license : MIT\n//! momentjs.com\n\n;(function (global, factory) {\n    typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :\n    typeof define === 'function' && define.amd ? define(factory) :\n    global.moment = factory()\n}(this, (function () { 'use strict';\n\nvar hookCallback;\n\nfunction hooks () {\n    return hookCallback.apply(null, arguments);\n}\n\n// This is done to register the method called with moment()\n// without creating circular dependencies.\nfunction setHookCallback (callback) {\n    hookCallback = callback;\n}\n\nfunction isArray(input) {\n    return input instanceof Array || Object.prototype.toString.call(input) === '[object Array]';\n}\n\nfunction isObject(input) {\n    // IE8 will treat undefined and null as object if it wasn't for\n    // input != null\n    return input != null && Object.prototype.toString.call(input) === '[object Object]';\n}\n\nfunction isObjectEmpty(obj) {\n    var k;\n    for (k in obj) {\n        // even if its not own property I'd still call it non-empty\n        return false;\n    }\n    return true;\n}\n\nfunction isUndefined(input) {\n    return input === void 0;\n}\n\nfunction isNumber(input) {\n    return typeof input === 'number' || Object.prototype.toString.call(input) === '[object Number]';\n}\n\nfunction isDate(input) {\n    return input instanceof Date || Object.prototype.toString.call(input) === '[object Date]';\n}\n\nfunction map(arr, fn) {\n    var res = [], i;\n    for (i = 0; i < arr.length; ++i) {\n        res.push(fn(arr[i], i));\n    }\n    return res;\n}\n\nfunction hasOwnProp(a, b) {\n    return Object.prototype.hasOwnProperty.call(a, b);\n}\n\nfunction extend(a, b) {\n    for (var i in b) {\n        if (hasOwnProp(b, i)) {\n            a[i] = b[i];\n        }\n    }\n\n    if (hasOwnProp(b, 'toString')) {\n        a.toString = b.toString;\n    }\n\n    if (hasOwnProp(b, 'valueOf')) {\n        a.valueOf = b.valueOf;\n    }\n\n    return a;\n}\n\nfunction createUTC (input, format, locale, strict) {\n    return createLocalOrUTC(input, format, locale, strict, true).utc();\n}\n\nfunction defaultParsingFlags() {\n    // We need to deep clone this object.\n    return {\n        empty           : false,\n        unusedTokens    : [],\n        unusedInput     : [],\n        overflow        : -2,\n        charsLeftOver   : 0,\n        nullInput       : false,\n        invalidMonth    : null,\n        invalidFormat   : false,\n        userInvalidated : false,\n        iso             : false,\n        parsedDateParts : [],\n        meridiem        : null,\n        rfc2822         : false,\n        weekdayMismatch : false\n    };\n}\n\nfunction getParsingFlags(m) {\n    if (m._pf == null) {\n        m._pf = defaultParsingFlags();\n    }\n    return m._pf;\n}\n\nvar some;\nif (Array.prototype.some) {\n    some = Array.prototype.some;\n} else {\n    some = function (fun) {\n        var t = Object(this);\n        var len = t.length >>> 0;\n\n        for (var i = 0; i < len; i++) {\n            if (i in t && fun.call(this, t[i], i, t)) {\n                return true;\n            }\n        }\n\n        return false;\n    };\n}\n\nvar some$1 = some;\n\nfunction isValid(m) {\n    if (m._isValid == null) {\n        var flags = getParsingFlags(m);\n        var parsedParts = some$1.call(flags.parsedDateParts, function (i) {\n            return i != null;\n        });\n        var isNowValid = !isNaN(m._d.getTime()) &&\n            flags.overflow < 0 &&\n            !flags.empty &&\n            !flags.invalidMonth &&\n            !flags.invalidWeekday &&\n            !flags.nullInput &&\n            !flags.invalidFormat &&\n            !flags.userInvalidated &&\n            (!flags.meridiem || (flags.meridiem && parsedParts));\n\n        if (m._strict) {\n            isNowValid = isNowValid &&\n                flags.charsLeftOver === 0 &&\n                flags.unusedTokens.length === 0 &&\n                flags.bigHour === undefined;\n        }\n\n        if (Object.isFrozen == null || !Object.isFrozen(m)) {\n            m._isValid = isNowValid;\n        }\n        else {\n            return isNowValid;\n        }\n    }\n    return m._isValid;\n}\n\nfunction createInvalid (flags) {\n    var m = createUTC(NaN);\n    if (flags != null) {\n        extend(getParsingFlags(m), flags);\n    }\n    else {\n        getParsingFlags(m).userInvalidated = true;\n    }\n\n    return m;\n}\n\n// Plugins that add properties should also add the key here (null value),\n// so we can properly clone ourselves.\nvar momentProperties = hooks.momentProperties = [];\n\nfunction copyConfig(to, from) {\n    var i, prop, val;\n\n    if (!isUndefined(from._isAMomentObject)) {\n        to._isAMomentObject = from._isAMomentObject;\n    }\n    if (!isUndefined(from._i)) {\n        to._i = from._i;\n    }\n    if (!isUndefined(from._f)) {\n        to._f = from._f;\n    }\n    if (!isUndefined(from._l)) {\n        to._l = from._l;\n    }\n    if (!isUndefined(from._strict)) {\n        to._strict = from._strict;\n    }\n    if (!isUndefined(from._tzm)) {\n        to._tzm = from._tzm;\n    }\n    if (!isUndefined(from._isUTC)) {\n        to._isUTC = from._isUTC;\n    }\n    if (!isUndefined(from._offset)) {\n        to._offset = from._offset;\n    }\n    if (!isUndefined(from._pf)) {\n        to._pf = getParsingFlags(from);\n    }\n    if (!isUndefined(from._locale)) {\n        to._locale = from._locale;\n    }\n\n    if (momentProperties.length > 0) {\n        for (i = 0; i < momentProperties.length; i++) {\n            prop = momentProperties[i];\n            val = from[prop];\n            if (!isUndefined(val)) {\n                to[prop] = val;\n            }\n        }\n    }\n\n    return to;\n}\n\nvar updateInProgress = false;\n\n// Moment prototype object\nfunction Moment(config) {\n    copyConfig(this, config);\n    this._d = new Date(config._d != null ? config._d.getTime() : NaN);\n    if (!this.isValid()) {\n        this._d = new Date(NaN);\n    }\n    // Prevent infinite loop in case updateOffset creates new moment\n    // objects.\n    if (updateInProgress === false) {\n        updateInProgress = true;\n        hooks.updateOffset(this);\n        updateInProgress = false;\n    }\n}\n\nfunction isMoment (obj) {\n    return obj instanceof Moment || (obj != null && obj._isAMomentObject != null);\n}\n\nfunction absFloor (number) {\n    if (number < 0) {\n        // -0 -> 0\n        return Math.ceil(number) || 0;\n    } else {\n        return Math.floor(number);\n    }\n}\n\nfunction toInt(argumentForCoercion) {\n    var coercedNumber = +argumentForCoercion,\n        value = 0;\n\n    if (coercedNumber !== 0 && isFinite(coercedNumber)) {\n        value = absFloor(coercedNumber);\n    }\n\n    return value;\n}\n\n// compare two arrays, return the number of differences\nfunction compareArrays(array1, array2, dontConvert) {\n    var len = Math.min(array1.length, array2.length),\n        lengthDiff = Math.abs(array1.length - array2.length),\n        diffs = 0,\n        i;\n    for (i = 0; i < len; i++) {\n        if ((dontConvert && array1[i] !== array2[i]) ||\n            (!dontConvert && toInt(array1[i]) !== toInt(array2[i]))) {\n            diffs++;\n        }\n    }\n    return diffs + lengthDiff;\n}\n\nfunction warn(msg) {\n    if (hooks.suppressDeprecationWarnings === false &&\n            (typeof console !==  'undefined') && console.warn) {\n        console.warn('Deprecation warning: ' + msg);\n    }\n}\n\nfunction deprecate(msg, fn) {\n    var firstTime = true;\n\n    return extend(function () {\n        if (hooks.deprecationHandler != null) {\n            hooks.deprecationHandler(null, msg);\n        }\n        if (firstTime) {\n            var args = [];\n            var arg;\n            for (var i = 0; i < arguments.length; i++) {\n                arg = '';\n                if (typeof arguments[i] === 'object') {\n                    arg += '\\n[' + i + '] ';\n                    for (var key in arguments[0]) {\n                        arg += key + ': ' + arguments[0][key] + ', ';\n                    }\n                    arg = arg.slice(0, -2); // Remove trailing comma and space\n                } else {\n                    arg = arguments[i];\n                }\n                args.push(arg);\n            }\n            warn(msg + '\\nArguments: ' + Array.prototype.slice.call(args).join('') + '\\n' + (new Error()).stack);\n            firstTime = false;\n        }\n        return fn.apply(this, arguments);\n    }, fn);\n}\n\nvar deprecations = {};\n\nfunction deprecateSimple(name, msg) {\n    if (hooks.deprecationHandler != null) {\n        hooks.deprecationHandler(name, msg);\n    }\n    if (!deprecations[name]) {\n        warn(msg);\n        deprecations[name] = true;\n    }\n}\n\nhooks.suppressDeprecationWarnings = false;\nhooks.deprecationHandler = null;\n\nfunction isFunction(input) {\n    return input instanceof Function || Object.prototype.toString.call(input) === '[object Function]';\n}\n\nfunction set (config) {\n    var prop, i;\n    for (i in config) {\n        prop = config[i];\n        if (isFunction(prop)) {\n            this[i] = prop;\n        } else {\n            this['_' + i] = prop;\n        }\n    }\n    this._config = config;\n    // Lenient ordinal parsing accepts just a number in addition to\n    // number + (possibly) stuff coming from _dayOfMonthOrdinalParse.\n    // TODO: Remove \"ordinalParse\" fallback in next major release.\n    this._dayOfMonthOrdinalParseLenient = new RegExp(\n        (this._dayOfMonthOrdinalParse.source || this._ordinalParse.source) +\n            '|' + (/\\d{1,2}/).source);\n}\n\nfunction mergeConfigs(parentConfig, childConfig) {\n    var res = extend({}, parentConfig), prop;\n    for (prop in childConfig) {\n        if (hasOwnProp(childConfig, prop)) {\n            if (isObject(parentConfig[prop]) && isObject(childConfig[prop])) {\n                res[prop] = {};\n                extend(res[prop], parentConfig[prop]);\n                extend(res[prop], childConfig[prop]);\n            } else if (childConfig[prop] != null) {\n                res[prop] = childConfig[prop];\n            } else {\n                delete res[prop];\n            }\n        }\n    }\n    for (prop in parentConfig) {\n        if (hasOwnProp(parentConfig, prop) &&\n                !hasOwnProp(childConfig, prop) &&\n                isObject(parentConfig[prop])) {\n            // make sure changes to properties don't modify parent config\n            res[prop] = extend({}, res[prop]);\n        }\n    }\n    return res;\n}\n\nfunction Locale(config) {\n    if (config != null) {\n        this.set(config);\n    }\n}\n\nvar keys;\n\nif (Object.keys) {\n    keys = Object.keys;\n} else {\n    keys = function (obj) {\n        var i, res = [];\n        for (i in obj) {\n            if (hasOwnProp(obj, i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    };\n}\n\nvar keys$1 = keys;\n\nvar defaultCalendar = {\n    sameDay : '[Today at] LT',\n    nextDay : '[Tomorrow at] LT',\n    nextWeek : 'dddd [at] LT',\n    lastDay : '[Yesterday at] LT',\n    lastWeek : '[Last] dddd [at] LT',\n    sameElse : 'L'\n};\n\nfunction calendar (key, mom, now) {\n    var output = this._calendar[key] || this._calendar['sameElse'];\n    return isFunction(output) ? output.call(mom, now) : output;\n}\n\nvar defaultLongDateFormat = {\n    LTS  : 'h:mm:ss A',\n    LT   : 'h:mm A',\n    L    : 'MM/DD/YYYY',\n    LL   : 'MMMM D, YYYY',\n    LLL  : 'MMMM D, YYYY h:mm A',\n    LLLL : 'dddd, MMMM D, YYYY h:mm A'\n};\n\nfunction longDateFormat (key) {\n    var format = this._longDateFormat[key],\n        formatUpper = this._longDateFormat[key.toUpperCase()];\n\n    if (format || !formatUpper) {\n        return format;\n    }\n\n    this._longDateFormat[key] = formatUpper.replace(/MMMM|MM|DD|dddd/g, function (val) {\n        return val.slice(1);\n    });\n\n    return this._longDateFormat[key];\n}\n\nvar defaultInvalidDate = 'Invalid date';\n\nfunction invalidDate () {\n    return this._invalidDate;\n}\n\nvar defaultOrdinal = '%d';\nvar defaultDayOfMonthOrdinalParse = /\\d{1,2}/;\n\nfunction ordinal (number) {\n    return this._ordinal.replace('%d', number);\n}\n\nvar defaultRelativeTime = {\n    future : 'in %s',\n    past   : '%s ago',\n    s  : 'a few seconds',\n    ss : '%d seconds',\n    m  : 'a minute',\n    mm : '%d minutes',\n    h  : 'an hour',\n    hh : '%d hours',\n    d  : 'a day',\n    dd : '%d days',\n    M  : 'a month',\n    MM : '%d months',\n    y  : 'a year',\n    yy : '%d years'\n};\n\nfunction relativeTime (number, withoutSuffix, string, isFuture) {\n    var output = this._relativeTime[string];\n    return (isFunction(output)) ?\n        output(number, withoutSuffix, string, isFuture) :\n        output.replace(/%d/i, number);\n}\n\nfunction pastFuture (diff, output) {\n    var format = this._relativeTime[diff > 0 ? 'future' : 'past'];\n    return isFunction(format) ? format(output) : format.replace(/%s/i, output);\n}\n\nvar aliases = {};\n\nfunction addUnitAlias (unit, shorthand) {\n    var lowerCase = unit.toLowerCase();\n    aliases[lowerCase] = aliases[lowerCase + 's'] = aliases[shorthand] = unit;\n}\n\nfunction normalizeUnits(units) {\n    return typeof units === 'string' ? aliases[units] || aliases[units.toLowerCase()] : undefined;\n}\n\nfunction normalizeObjectUnits(inputObject) {\n    var normalizedInput = {},\n        normalizedProp,\n        prop;\n\n    for (prop in inputObject) {\n        if (hasOwnProp(inputObject, prop)) {\n            normalizedProp = normalizeUnits(prop);\n            if (normalizedProp) {\n                normalizedInput[normalizedProp] = inputObject[prop];\n            }\n        }\n    }\n\n    return normalizedInput;\n}\n\nvar priorities = {};\n\nfunction addUnitPriority(unit, priority) {\n    priorities[unit] = priority;\n}\n\nfunction getPrioritizedUnits(unitsObj) {\n    var units = [];\n    for (var u in unitsObj) {\n        units.push({unit: u, priority: priorities[u]});\n    }\n    units.sort(function (a, b) {\n        return a.priority - b.priority;\n    });\n    return units;\n}\n\nfunction makeGetSet (unit, keepTime) {\n    return function (value) {\n        if (value != null) {\n            set$1(this, unit, value);\n            hooks.updateOffset(this, keepTime);\n            return this;\n        } else {\n            return get(this, unit);\n        }\n    };\n}\n\nfunction get (mom, unit) {\n    return mom.isValid() ?\n        mom._d['get' + (mom._isUTC ? 'UTC' : '') + unit]() : NaN;\n}\n\nfunction set$1 (mom, unit, value) {\n    if (mom.isValid()) {\n        mom._d['set' + (mom._isUTC ? 'UTC' : '') + unit](value);\n    }\n}\n\n// MOMENTS\n\nfunction stringGet (units) {\n    units = normalizeUnits(units);\n    if (isFunction(this[units])) {\n        return this[units]();\n    }\n    return this;\n}\n\n\nfunction stringSet (units, value) {\n    if (typeof units === 'object') {\n        units = normalizeObjectUnits(units);\n        var prioritized = getPrioritizedUnits(units);\n        for (var i = 0; i < prioritized.length; i++) {\n            this[prioritized[i].unit](units[prioritized[i].unit]);\n        }\n    } else {\n        units = normalizeUnits(units);\n        if (isFunction(this[units])) {\n            return this[units](value);\n        }\n    }\n    return this;\n}\n\nfunction zeroFill(number, targetLength, forceSign) {\n    var absNumber = '' + Math.abs(number),\n        zerosToFill = targetLength - absNumber.length,\n        sign = number >= 0;\n    return (sign ? (forceSign ? '+' : '') : '-') +\n        Math.pow(10, Math.max(0, zerosToFill)).toString().substr(1) + absNumber;\n}\n\nvar formattingTokens = /(\\[[^\\[]*\\])|(\\\\)?([Hh]mm(ss)?|Mo|MM?M?M?|Do|DDDo|DD?D?D?|ddd?d?|do?|w[o|w]?|W[o|W]?|Qo?|YYYYYY|YYYYY|YYYY|YY|gg(ggg?)?|GG(GGG?)?|e|E|a|A|hh?|HH?|kk?|mm?|ss?|S{1,9}|x|X|zz?|ZZ?|.)/g;\n\nvar localFormattingTokens = /(\\[[^\\[]*\\])|(\\\\)?(LTS|LT|LL?L?L?|l{1,4})/g;\n\nvar formatFunctions = {};\n\nvar formatTokenFunctions = {};\n\n// token:    'M'\n// padded:   ['MM', 2]\n// ordinal:  'Mo'\n// callback: function () { this.month() + 1 }\nfunction addFormatToken (token, padded, ordinal, callback) {\n    var func = callback;\n    if (typeof callback === 'string') {\n        func = function () {\n            return this[callback]();\n        };\n    }\n    if (token) {\n        formatTokenFunctions[token] = func;\n    }\n    if (padded) {\n        formatTokenFunctions[padded[0]] = function () {\n            return zeroFill(func.apply(this, arguments), padded[1], padded[2]);\n        };\n    }\n    if (ordinal) {\n        formatTokenFunctions[ordinal] = function () {\n            return this.localeData().ordinal(func.apply(this, arguments), token);\n        };\n    }\n}\n\nfunction removeFormattingTokens(input) {\n    if (input.match(/\\[[\\s\\S]/)) {\n        return input.replace(/^\\[|\\]$/g, '');\n    }\n    return input.replace(/\\\\/g, '');\n}\n\nfunction makeFormatFunction(format) {\n    var array = format.match(formattingTokens), i, length;\n\n    for (i = 0, length = array.length; i < length; i++) {\n        if (formatTokenFunctions[array[i]]) {\n            array[i] = formatTokenFunctions[array[i]];\n        } else {\n            array[i] = removeFormattingTokens(array[i]);\n        }\n    }\n\n    return function (mom) {\n        var output = '', i;\n        for (i = 0; i < length; i++) {\n            output += isFunction(array[i]) ? array[i].call(mom, format) : array[i];\n        }\n        return output;\n    };\n}\n\n// format date using native date object\nfunction formatMoment(m, format) {\n    if (!m.isValid()) {\n        return m.localeData().invalidDate();\n    }\n\n    format = expandFormat(format, m.localeData());\n    formatFunctions[format] = formatFunctions[format] || makeFormatFunction(format);\n\n    return formatFunctions[format](m);\n}\n\nfunction expandFormat(format, locale) {\n    var i = 5;\n\n    function replaceLongDateFormatTokens(input) {\n        return locale.longDateFormat(input) || input;\n    }\n\n    localFormattingTokens.lastIndex = 0;\n    while (i >= 0 && localFormattingTokens.test(format)) {\n        format = format.replace(localFormattingTokens, replaceLongDateFormatTokens);\n        localFormattingTokens.lastIndex = 0;\n        i -= 1;\n    }\n\n    return format;\n}\n\nvar match1         = /\\d/;            //       0 - 9\nvar match2         = /\\d\\d/;          //      00 - 99\nvar match3         = /\\d{3}/;         //     000 - 999\nvar match4         = /\\d{4}/;         //    0000 - 9999\nvar match6         = /[+-]?\\d{6}/;    // -999999 - 999999\nvar match1to2      = /\\d\\d?/;         //       0 - 99\nvar match3to4      = /\\d\\d\\d\\d?/;     //     999 - 9999\nvar match5to6      = /\\d\\d\\d\\d\\d\\d?/; //   99999 - 999999\nvar match1to3      = /\\d{1,3}/;       //       0 - 999\nvar match1to4      = /\\d{1,4}/;       //       0 - 9999\nvar match1to6      = /[+-]?\\d{1,6}/;  // -999999 - 999999\n\nvar matchUnsigned  = /\\d+/;           //       0 - inf\nvar matchSigned    = /[+-]?\\d+/;      //    -inf - inf\n\nvar matchOffset    = /Z|[+-]\\d\\d:?\\d\\d/gi; // +00:00 -00:00 +0000 -0000 or Z\nvar matchShortOffset = /Z|[+-]\\d\\d(?::?\\d\\d)?/gi; // +00 -00 +00:00 -00:00 +0000 -0000 or Z\n\nvar matchTimestamp = /[+-]?\\d+(\\.\\d{1,3})?/; // 123456789 123456789.123\n\n// any word (or two) characters or numbers including two/three word month in arabic.\n// includes scottish gaelic two word and hyphenated months\nvar matchWord = /[0-9]*['a-z\\u00A0-\\u05FF\\u0700-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF]+|[\\u0600-\\u06FF\\/]+(\\s*?[\\u0600-\\u06FF]+){1,2}/i;\n\n\nvar regexes = {};\n\nfunction addRegexToken (token, regex, strictRegex) {\n    regexes[token] = isFunction(regex) ? regex : function (isStrict, localeData) {\n        return (isStrict && strictRegex) ? strictRegex : regex;\n    };\n}\n\nfunction getParseRegexForToken (token, config) {\n    if (!hasOwnProp(regexes, token)) {\n        return new RegExp(unescapeFormat(token));\n    }\n\n    return regexes[token](config._strict, config._locale);\n}\n\n// Code from http://stackoverflow.com/questions/3561493/is-there-a-regexp-escape-function-in-javascript\nfunction unescapeFormat(s) {\n    return regexEscape(s.replace('\\\\', '').replace(/\\\\(\\[)|\\\\(\\])|\\[([^\\]\\[]*)\\]|\\\\(.)/g, function (matched, p1, p2, p3, p4) {\n        return p1 || p2 || p3 || p4;\n    }));\n}\n\nfunction regexEscape(s) {\n    return s.replace(/[-\\/\\\\^$*+?.()|[\\]{}]/g, '\\\\$&');\n}\n\nvar tokens = {};\n\nfunction addParseToken (token, callback) {\n    var i, func = callback;\n    if (typeof token === 'string') {\n        token = [token];\n    }\n    if (isNumber(callback)) {\n        func = function (input, array) {\n            array[callback] = toInt(input);\n        };\n    }\n    for (i = 0; i < token.length; i++) {\n        tokens[token[i]] = func;\n    }\n}\n\nfunction addWeekParseToken (token, callback) {\n    addParseToken(token, function (input, array, config, token) {\n        config._w = config._w || {};\n        callback(input, config._w, config, token);\n    });\n}\n\nfunction addTimeToArrayFromToken(token, input, config) {\n    if (input != null && hasOwnProp(tokens, token)) {\n        tokens[token](input, config._a, config, token);\n    }\n}\n\nvar YEAR = 0;\nvar MONTH = 1;\nvar DATE = 2;\nvar HOUR = 3;\nvar MINUTE = 4;\nvar SECOND = 5;\nvar MILLISECOND = 6;\nvar WEEK = 7;\nvar WEEKDAY = 8;\n\nvar indexOf;\n\nif (Array.prototype.indexOf) {\n    indexOf = Array.prototype.indexOf;\n} else {\n    indexOf = function (o) {\n        // I know\n        var i;\n        for (i = 0; i < this.length; ++i) {\n            if (this[i] === o) {\n                return i;\n            }\n        }\n        return -1;\n    };\n}\n\nvar indexOf$1 = indexOf;\n\nfunction daysInMonth(year, month) {\n    return new Date(Date.UTC(year, month + 1, 0)).getUTCDate();\n}\n\n// FORMATTING\n\naddFormatToken('M', ['MM', 2], 'Mo', function () {\n    return this.month() + 1;\n});\n\naddFormatToken('MMM', 0, 0, function (format) {\n    return this.localeData().monthsShort(this, format);\n});\n\naddFormatToken('MMMM', 0, 0, function (format) {\n    return this.localeData().months(this, format);\n});\n\n// ALIASES\n\naddUnitAlias('month', 'M');\n\n// PRIORITY\n\naddUnitPriority('month', 8);\n\n// PARSING\n\naddRegexToken('M',    match1to2);\naddRegexToken('MM',   match1to2, match2);\naddRegexToken('MMM',  function (isStrict, locale) {\n    return locale.monthsShortRegex(isStrict);\n});\naddRegexToken('MMMM', function (isStrict, locale) {\n    return locale.monthsRegex(isStrict);\n});\n\naddParseToken(['M', 'MM'], function (input, array) {\n    array[MONTH] = toInt(input) - 1;\n});\n\naddParseToken(['MMM', 'MMMM'], function (input, array, config, token) {\n    var month = config._locale.monthsParse(input, token, config._strict);\n    // if we didn't find a month name, mark the date as invalid.\n    if (month != null) {\n        array[MONTH] = month;\n    } else {\n        getParsingFlags(config).invalidMonth = input;\n    }\n});\n\n// LOCALES\n\nvar MONTHS_IN_FORMAT = /D[oD]?(\\[[^\\[\\]]*\\]|\\s)+MMMM?/;\nvar defaultLocaleMonths = 'January_February_March_April_May_June_July_August_September_October_November_December'.split('_');\nfunction localeMonths (m, format) {\n    if (!m) {\n        return isArray(this._months) ? this._months :\n            this._months['standalone'];\n    }\n    return isArray(this._months) ? this._months[m.month()] :\n        this._months[(this._months.isFormat || MONTHS_IN_FORMAT).test(format) ? 'format' : 'standalone'][m.month()];\n}\n\nvar defaultLocaleMonthsShort = 'Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec'.split('_');\nfunction localeMonthsShort (m, format) {\n    if (!m) {\n        return isArray(this._monthsShort) ? this._monthsShort :\n            this._monthsShort['standalone'];\n    }\n    return isArray(this._monthsShort) ? this._monthsShort[m.month()] :\n        this._monthsShort[MONTHS_IN_FORMAT.test(format) ? 'format' : 'standalone'][m.month()];\n}\n\nfunction handleStrictParse(monthName, format, strict) {\n    var i, ii, mom, llc = monthName.toLocaleLowerCase();\n    if (!this._monthsParse) {\n        // this is not used\n        this._monthsParse = [];\n        this._longMonthsParse = [];\n        this._shortMonthsParse = [];\n        for (i = 0; i < 12; ++i) {\n            mom = createUTC([2000, i]);\n            this._shortMonthsParse[i] = this.monthsShort(mom, '').toLocaleLowerCase();\n            this._longMonthsParse[i] = this.months(mom, '').toLocaleLowerCase();\n        }\n    }\n\n    if (strict) {\n        if (format === 'MMM') {\n            ii = indexOf$1.call(this._shortMonthsParse, llc);\n            return ii !== -1 ? ii : null;\n        } else {\n            ii = indexOf$1.call(this._longMonthsParse, llc);\n            return ii !== -1 ? ii : null;\n        }\n    } else {\n        if (format === 'MMM') {\n            ii = indexOf$1.call(this._shortMonthsParse, llc);\n            if (ii !== -1) {\n                return ii;\n            }\n            ii = indexOf$1.call(this._longMonthsParse, llc);\n            return ii !== -1 ? ii : null;\n        } else {\n            ii = indexOf$1.call(this._longMonthsParse, llc);\n            if (ii !== -1) {\n                return ii;\n            }\n            ii = indexOf$1.call(this._shortMonthsParse, llc);\n            return ii !== -1 ? ii : null;\n        }\n    }\n}\n\nfunction localeMonthsParse (monthName, format, strict) {\n    var i, mom, regex;\n\n    if (this._monthsParseExact) {\n        return handleStrictParse.call(this, monthName, format, strict);\n    }\n\n    if (!this._monthsParse) {\n        this._monthsParse = [];\n        this._longMonthsParse = [];\n        this._shortMonthsParse = [];\n    }\n\n    // TODO: add sorting\n    // Sorting makes sure if one month (or abbr) is a prefix of another\n    // see sorting in computeMonthsParse\n    for (i = 0; i < 12; i++) {\n        // make the regex if we don't have it already\n        mom = createUTC([2000, i]);\n        if (strict && !this._longMonthsParse[i]) {\n            this._longMonthsParse[i] = new RegExp('^' + this.months(mom, '').replace('.', '') + '$', 'i');\n            this._shortMonthsParse[i] = new RegExp('^' + this.monthsShort(mom, '').replace('.', '') + '$', 'i');\n        }\n        if (!strict && !this._monthsParse[i]) {\n            regex = '^' + this.months(mom, '') + '|^' + this.monthsShort(mom, '');\n            this._monthsParse[i] = new RegExp(regex.replace('.', ''), 'i');\n        }\n        // test the regex\n        if (strict && format === 'MMMM' && this._longMonthsParse[i].test(monthName)) {\n            return i;\n        } else if (strict && format === 'MMM' && this._shortMonthsParse[i].test(monthName)) {\n            return i;\n        } else if (!strict && this._monthsParse[i].test(monthName)) {\n            return i;\n        }\n    }\n}\n\n// MOMENTS\n\nfunction setMonth (mom, value) {\n    var dayOfMonth;\n\n    if (!mom.isValid()) {\n        // No op\n        return mom;\n    }\n\n    if (typeof value === 'string') {\n        if (/^\\d+$/.test(value)) {\n            value = toInt(value);\n        } else {\n            value = mom.localeData().monthsParse(value);\n            // TODO: Another silent failure?\n            if (!isNumber(value)) {\n                return mom;\n            }\n        }\n    }\n\n    dayOfMonth = Math.min(mom.date(), daysInMonth(mom.year(), value));\n    mom._d['set' + (mom._isUTC ? 'UTC' : '') + 'Month'](value, dayOfMonth);\n    return mom;\n}\n\nfunction getSetMonth (value) {\n    if (value != null) {\n        setMonth(this, value);\n        hooks.updateOffset(this, true);\n        return this;\n    } else {\n        return get(this, 'Month');\n    }\n}\n\nfunction getDaysInMonth () {\n    return daysInMonth(this.year(), this.month());\n}\n\nvar defaultMonthsShortRegex = matchWord;\nfunction monthsShortRegex (isStrict) {\n    if (this._monthsParseExact) {\n        if (!hasOwnProp(this, '_monthsRegex')) {\n            computeMonthsParse.call(this);\n        }\n        if (isStrict) {\n            return this._monthsShortStrictRegex;\n        } else {\n            return this._monthsShortRegex;\n        }\n    } else {\n        if (!hasOwnProp(this, '_monthsShortRegex')) {\n            this._monthsShortRegex = defaultMonthsShortRegex;\n        }\n        return this._monthsShortStrictRegex && isStrict ?\n            this._monthsShortStrictRegex : this._monthsShortRegex;\n    }\n}\n\nvar defaultMonthsRegex = matchWord;\nfunction monthsRegex (isStrict) {\n    if (this._monthsParseExact) {\n        if (!hasOwnProp(this, '_monthsRegex')) {\n            computeMonthsParse.call(this);\n        }\n        if (isStrict) {\n            return this._monthsStrictRegex;\n        } else {\n            return this._monthsRegex;\n        }\n    } else {\n        if (!hasOwnProp(this, '_monthsRegex')) {\n            this._monthsRegex = defaultMonthsRegex;\n        }\n        return this._monthsStrictRegex && isStrict ?\n            this._monthsStrictRegex : this._monthsRegex;\n    }\n}\n\nfunction computeMonthsParse () {\n    function cmpLenRev(a, b) {\n        return b.length - a.length;\n    }\n\n    var shortPieces = [], longPieces = [], mixedPieces = [],\n        i, mom;\n    for (i = 0; i < 12; i++) {\n        // make the regex if we don't have it already\n        mom = createUTC([2000, i]);\n        shortPieces.push(this.monthsShort(mom, ''));\n        longPieces.push(this.months(mom, ''));\n        mixedPieces.push(this.months(mom, ''));\n        mixedPieces.push(this.monthsShort(mom, ''));\n    }\n    // Sorting makes sure if one month (or abbr) is a prefix of another it\n    // will match the longer piece.\n    shortPieces.sort(cmpLenRev);\n    longPieces.sort(cmpLenRev);\n    mixedPieces.sort(cmpLenRev);\n    for (i = 0; i < 12; i++) {\n        shortPieces[i] = regexEscape(shortPieces[i]);\n        longPieces[i] = regexEscape(longPieces[i]);\n    }\n    for (i = 0; i < 24; i++) {\n        mixedPieces[i] = regexEscape(mixedPieces[i]);\n    }\n\n    this._monthsRegex = new RegExp('^(' + mixedPieces.join('|') + ')', 'i');\n    this._monthsShortRegex = this._monthsRegex;\n    this._monthsStrictRegex = new RegExp('^(' + longPieces.join('|') + ')', 'i');\n    this._monthsShortStrictRegex = new RegExp('^(' + shortPieces.join('|') + ')', 'i');\n}\n\n// FORMATTING\n\naddFormatToken('Y', 0, 0, function () {\n    var y = this.year();\n    return y <= 9999 ? '' + y : '+' + y;\n});\n\naddFormatToken(0, ['YY', 2], 0, function () {\n    return this.year() % 100;\n});\n\naddFormatToken(0, ['YYYY',   4],       0, 'year');\naddFormatToken(0, ['YYYYY',  5],       0, 'year');\naddFormatToken(0, ['YYYYYY', 6, true], 0, 'year');\n\n// ALIASES\n\naddUnitAlias('year', 'y');\n\n// PRIORITIES\n\naddUnitPriority('year', 1);\n\n// PARSING\n\naddRegexToken('Y',      matchSigned);\naddRegexToken('YY',     match1to2, match2);\naddRegexToken('YYYY',   match1to4, match4);\naddRegexToken('YYYYY',  match1to6, match6);\naddRegexToken('YYYYYY', match1to6, match6);\n\naddParseToken(['YYYYY', 'YYYYYY'], YEAR);\naddParseToken('YYYY', function (input, array) {\n    array[YEAR] = input.length === 2 ? hooks.parseTwoDigitYear(input) : toInt(input);\n});\naddParseToken('YY', function (input, array) {\n    array[YEAR] = hooks.parseTwoDigitYear(input);\n});\naddParseToken('Y', function (input, array) {\n    array[YEAR] = parseInt(input, 10);\n});\n\n// HELPERS\n\nfunction daysInYear(year) {\n    return isLeapYear(year) ? 366 : 365;\n}\n\nfunction isLeapYear(year) {\n    return (year % 4 === 0 && year % 100 !== 0) || year % 400 === 0;\n}\n\n// HOOKS\n\nhooks.parseTwoDigitYear = function (input) {\n    return toInt(input) + (toInt(input) > 68 ? 1900 : 2000);\n};\n\n// MOMENTS\n\nvar getSetYear = makeGetSet('FullYear', true);\n\nfunction getIsLeapYear () {\n    return isLeapYear(this.year());\n}\n\nfunction createDate (y, m, d, h, M, s, ms) {\n    // can't just apply() to create a date:\n    // https://stackoverflow.com/q/181348\n    var date = new Date(y, m, d, h, M, s, ms);\n\n    // the date constructor remaps years 0-99 to 1900-1999\n    if (y < 100 && y >= 0 && isFinite(date.getFullYear())) {\n        date.setFullYear(y);\n    }\n    return date;\n}\n\nfunction createUTCDate (y) {\n    var date = new Date(Date.UTC.apply(null, arguments));\n\n    // the Date.UTC function remaps years 0-99 to 1900-1999\n    if (y < 100 && y >= 0 && isFinite(date.getUTCFullYear())) {\n        date.setUTCFullYear(y);\n    }\n    return date;\n}\n\n// start-of-first-week - start-of-year\nfunction firstWeekOffset(year, dow, doy) {\n    var // first-week day -- which january is always in the first week (4 for iso, 1 for other)\n        fwd = 7 + dow - doy,\n        // first-week day local weekday -- which local weekday is fwd\n        fwdlw = (7 + createUTCDate(year, 0, fwd).getUTCDay() - dow) % 7;\n\n    return -fwdlw + fwd - 1;\n}\n\n// https://en.wikipedia.org/wiki/ISO_week_date#Calculating_a_date_given_the_year.2C_week_number_and_weekday\nfunction dayOfYearFromWeeks(year, week, weekday, dow, doy) {\n    var localWeekday = (7 + weekday - dow) % 7,\n        weekOffset = firstWeekOffset(year, dow, doy),\n        dayOfYear = 1 + 7 * (week - 1) + localWeekday + weekOffset,\n        resYear, resDayOfYear;\n\n    if (dayOfYear <= 0) {\n        resYear = year - 1;\n        resDayOfYear = daysInYear(resYear) + dayOfYear;\n    } else if (dayOfYear > daysInYear(year)) {\n        resYear = year + 1;\n        resDayOfYear = dayOfYear - daysInYear(year);\n    } else {\n        resYear = year;\n        resDayOfYear = dayOfYear;\n    }\n\n    return {\n        year: resYear,\n        dayOfYear: resDayOfYear\n    };\n}\n\nfunction weekOfYear(mom, dow, doy) {\n    var weekOffset = firstWeekOffset(mom.year(), dow, doy),\n        week = Math.floor((mom.dayOfYear() - weekOffset - 1) / 7) + 1,\n        resWeek, resYear;\n\n    if (week < 1) {\n        resYear = mom.year() - 1;\n        resWeek = week + weeksInYear(resYear, dow, doy);\n    } else if (week > weeksInYear(mom.year(), dow, doy)) {\n        resWeek = week - weeksInYear(mom.year(), dow, doy);\n        resYear = mom.year() + 1;\n    } else {\n        resYear = mom.year();\n        resWeek = week;\n    }\n\n    return {\n        week: resWeek,\n        year: resYear\n    };\n}\n\nfunction weeksInYear(year, dow, doy) {\n    var weekOffset = firstWeekOffset(year, dow, doy),\n        weekOffsetNext = firstWeekOffset(year + 1, dow, doy);\n    return (daysInYear(year) - weekOffset + weekOffsetNext) / 7;\n}\n\n// FORMATTING\n\naddFormatToken('w', ['ww', 2], 'wo', 'week');\naddFormatToken('W', ['WW', 2], 'Wo', 'isoWeek');\n\n// ALIASES\n\naddUnitAlias('week', 'w');\naddUnitAlias('isoWeek', 'W');\n\n// PRIORITIES\n\naddUnitPriority('week', 5);\naddUnitPriority('isoWeek', 5);\n\n// PARSING\n\naddRegexToken('w',  match1to2);\naddRegexToken('ww', match1to2, match2);\naddRegexToken('W',  match1to2);\naddRegexToken('WW', match1to2, match2);\n\naddWeekParseToken(['w', 'ww', 'W', 'WW'], function (input, week, config, token) {\n    week[token.substr(0, 1)] = toInt(input);\n});\n\n// HELPERS\n\n// LOCALES\n\nfunction localeWeek (mom) {\n    return weekOfYear(mom, this._week.dow, this._week.doy).week;\n}\n\nvar defaultLocaleWeek = {\n    dow : 0, // Sunday is the first day of the week.\n    doy : 6  // The week that contains Jan 1st is the first week of the year.\n};\n\nfunction localeFirstDayOfWeek () {\n    return this._week.dow;\n}\n\nfunction localeFirstDayOfYear () {\n    return this._week.doy;\n}\n\n// MOMENTS\n\nfunction getSetWeek (input) {\n    var week = this.localeData().week(this);\n    return input == null ? week : this.add((input - week) * 7, 'd');\n}\n\nfunction getSetISOWeek (input) {\n    var week = weekOfYear(this, 1, 4).week;\n    return input == null ? week : this.add((input - week) * 7, 'd');\n}\n\n// FORMATTING\n\naddFormatToken('d', 0, 'do', 'day');\n\naddFormatToken('dd', 0, 0, function (format) {\n    return this.localeData().weekdaysMin(this, format);\n});\n\naddFormatToken('ddd', 0, 0, function (format) {\n    return this.localeData().weekdaysShort(this, format);\n});\n\naddFormatToken('dddd', 0, 0, function (format) {\n    return this.localeData().weekdays(this, format);\n});\n\naddFormatToken('e', 0, 0, 'weekday');\naddFormatToken('E', 0, 0, 'isoWeekday');\n\n// ALIASES\n\naddUnitAlias('day', 'd');\naddUnitAlias('weekday', 'e');\naddUnitAlias('isoWeekday', 'E');\n\n// PRIORITY\naddUnitPriority('day', 11);\naddUnitPriority('weekday', 11);\naddUnitPriority('isoWeekday', 11);\n\n// PARSING\n\naddRegexToken('d',    match1to2);\naddRegexToken('e',    match1to2);\naddRegexToken('E',    match1to2);\naddRegexToken('dd',   function (isStrict, locale) {\n    return locale.weekdaysMinRegex(isStrict);\n});\naddRegexToken('ddd',   function (isStrict, locale) {\n    return locale.weekdaysShortRegex(isStrict);\n});\naddRegexToken('dddd',   function (isStrict, locale) {\n    return locale.weekdaysRegex(isStrict);\n});\n\naddWeekParseToken(['dd', 'ddd', 'dddd'], function (input, week, config, token) {\n    var weekday = config._locale.weekdaysParse(input, token, config._strict);\n    // if we didn't get a weekday name, mark the date as invalid\n    if (weekday != null) {\n        week.d = weekday;\n    } else {\n        getParsingFlags(config).invalidWeekday = input;\n    }\n});\n\naddWeekParseToken(['d', 'e', 'E'], function (input, week, config, token) {\n    week[token] = toInt(input);\n});\n\n// HELPERS\n\nfunction parseWeekday(input, locale) {\n    if (typeof input !== 'string') {\n        return input;\n    }\n\n    if (!isNaN(input)) {\n        return parseInt(input, 10);\n    }\n\n    input = locale.weekdaysParse(input);\n    if (typeof input === 'number') {\n        return input;\n    }\n\n    return null;\n}\n\nfunction parseIsoWeekday(input, locale) {\n    if (typeof input === 'string') {\n        return locale.weekdaysParse(input) % 7 || 7;\n    }\n    return isNaN(input) ? null : input;\n}\n\n// LOCALES\n\nvar defaultLocaleWeekdays = 'Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday'.split('_');\nfunction localeWeekdays (m, format) {\n    if (!m) {\n        return isArray(this._weekdays) ? this._weekdays :\n            this._weekdays['standalone'];\n    }\n    return isArray(this._weekdays) ? this._weekdays[m.day()] :\n        this._weekdays[this._weekdays.isFormat.test(format) ? 'format' : 'standalone'][m.day()];\n}\n\nvar defaultLocaleWeekdaysShort = 'Sun_Mon_Tue_Wed_Thu_Fri_Sat'.split('_');\nfunction localeWeekdaysShort (m) {\n    return (m) ? this._weekdaysShort[m.day()] : this._weekdaysShort;\n}\n\nvar defaultLocaleWeekdaysMin = 'Su_Mo_Tu_We_Th_Fr_Sa'.split('_');\nfunction localeWeekdaysMin (m) {\n    return (m) ? this._weekdaysMin[m.day()] : this._weekdaysMin;\n}\n\nfunction handleStrictParse$1(weekdayName, format, strict) {\n    var i, ii, mom, llc = weekdayName.toLocaleLowerCase();\n    if (!this._weekdaysParse) {\n        this._weekdaysParse = [];\n        this._shortWeekdaysParse = [];\n        this._minWeekdaysParse = [];\n\n        for (i = 0; i < 7; ++i) {\n            mom = createUTC([2000, 1]).day(i);\n            this._minWeekdaysParse[i] = this.weekdaysMin(mom, '').toLocaleLowerCase();\n            this._shortWeekdaysParse[i] = this.weekdaysShort(mom, '').toLocaleLowerCase();\n            this._weekdaysParse[i] = this.weekdays(mom, '').toLocaleLowerCase();\n        }\n    }\n\n    if (strict) {\n        if (format === 'dddd') {\n            ii = indexOf$1.call(this._weekdaysParse, llc);\n            return ii !== -1 ? ii : null;\n        } else if (format === 'ddd') {\n            ii = indexOf$1.call(this._shortWeekdaysParse, llc);\n            return ii !== -1 ? ii : null;\n        } else {\n            ii = indexOf$1.call(this._minWeekdaysParse, llc);\n            return ii !== -1 ? ii : null;\n        }\n    } else {\n        if (format === 'dddd') {\n            ii = indexOf$1.call(this._weekdaysParse, llc);\n            if (ii !== -1) {\n                return ii;\n            }\n            ii = indexOf$1.call(this._shortWeekdaysParse, llc);\n            if (ii !== -1) {\n                return ii;\n            }\n            ii = indexOf$1.call(this._minWeekdaysParse, llc);\n            return ii !== -1 ? ii : null;\n        } else if (format === 'ddd') {\n            ii = indexOf$1.call(this._shortWeekdaysParse, llc);\n            if (ii !== -1) {\n                return ii;\n            }\n            ii = indexOf$1.call(this._weekdaysParse, llc);\n            if (ii !== -1) {\n                return ii;\n            }\n            ii = indexOf$1.call(this._minWeekdaysParse, llc);\n            return ii !== -1 ? ii : null;\n        } else {\n            ii = indexOf$1.call(this._minWeekdaysParse, llc);\n            if (ii !== -1) {\n                return ii;\n            }\n            ii = indexOf$1.call(this._weekdaysParse, llc);\n            if (ii !== -1) {\n                return ii;\n            }\n            ii = indexOf$1.call(this._shortWeekdaysParse, llc);\n            return ii !== -1 ? ii : null;\n        }\n    }\n}\n\nfunction localeWeekdaysParse (weekdayName, format, strict) {\n    var i, mom, regex;\n\n    if (this._weekdaysParseExact) {\n        return handleStrictParse$1.call(this, weekdayName, format, strict);\n    }\n\n    if (!this._weekdaysParse) {\n        this._weekdaysParse = [];\n        this._minWeekdaysParse = [];\n        this._shortWeekdaysParse = [];\n        this._fullWeekdaysParse = [];\n    }\n\n    for (i = 0; i < 7; i++) {\n        // make the regex if we don't have it already\n\n        mom = createUTC([2000, 1]).day(i);\n        if (strict && !this._fullWeekdaysParse[i]) {\n            this._fullWeekdaysParse[i] = new RegExp('^' + this.weekdays(mom, '').replace('.', '\\.?') + '$', 'i');\n            this._shortWeekdaysParse[i] = new RegExp('^' + this.weekdaysShort(mom, '').replace('.', '\\.?') + '$', 'i');\n            this._minWeekdaysParse[i] = new RegExp('^' + this.weekdaysMin(mom, '').replace('.', '\\.?') + '$', 'i');\n        }\n        if (!this._weekdaysParse[i]) {\n            regex = '^' + this.weekdays(mom, '') + '|^' + this.weekdaysShort(mom, '') + '|^' + this.weekdaysMin(mom, '');\n            this._weekdaysParse[i] = new RegExp(regex.replace('.', ''), 'i');\n        }\n        // test the regex\n        if (strict && format === 'dddd' && this._fullWeekdaysParse[i].test(weekdayName)) {\n            return i;\n        } else if (strict && format === 'ddd' && this._shortWeekdaysParse[i].test(weekdayName)) {\n            return i;\n        } else if (strict && format === 'dd' && this._minWeekdaysParse[i].test(weekdayName)) {\n            return i;\n        } else if (!strict && this._weekdaysParse[i].test(weekdayName)) {\n            return i;\n        }\n    }\n}\n\n// MOMENTS\n\nfunction getSetDayOfWeek (input) {\n    if (!this.isValid()) {\n        return input != null ? this : NaN;\n    }\n    var day = this._isUTC ? this._d.getUTCDay() : this._d.getDay();\n    if (input != null) {\n        input = parseWeekday(input, this.localeData());\n        return this.add(input - day, 'd');\n    } else {\n        return day;\n    }\n}\n\nfunction getSetLocaleDayOfWeek (input) {\n    if (!this.isValid()) {\n        return input != null ? this : NaN;\n    }\n    var weekday = (this.day() + 7 - this.localeData()._week.dow) % 7;\n    return input == null ? weekday : this.add(input - weekday, 'd');\n}\n\nfunction getSetISODayOfWeek (input) {\n    if (!this.isValid()) {\n        return input != null ? this : NaN;\n    }\n\n    // behaves the same as moment#day except\n    // as a getter, returns 7 instead of 0 (1-7 range instead of 0-6)\n    // as a setter, sunday should belong to the previous week.\n\n    if (input != null) {\n        var weekday = parseIsoWeekday(input, this.localeData());\n        return this.day(this.day() % 7 ? weekday : weekday - 7);\n    } else {\n        return this.day() || 7;\n    }\n}\n\nvar defaultWeekdaysRegex = matchWord;\nfunction weekdaysRegex (isStrict) {\n    if (this._weekdaysParseExact) {\n        if (!hasOwnProp(this, '_weekdaysRegex')) {\n            computeWeekdaysParse.call(this);\n        }\n        if (isStrict) {\n            return this._weekdaysStrictRegex;\n        } else {\n            return this._weekdaysRegex;\n        }\n    } else {\n        if (!hasOwnProp(this, '_weekdaysRegex')) {\n            this._weekdaysRegex = defaultWeekdaysRegex;\n        }\n        return this._weekdaysStrictRegex && isStrict ?\n            this._weekdaysStrictRegex : this._weekdaysRegex;\n    }\n}\n\nvar defaultWeekdaysShortRegex = matchWord;\nfunction weekdaysShortRegex (isStrict) {\n    if (this._weekdaysParseExact) {\n        if (!hasOwnProp(this, '_weekdaysRegex')) {\n            computeWeekdaysParse.call(this);\n        }\n        if (isStrict) {\n            return this._weekdaysShortStrictRegex;\n        } else {\n            return this._weekdaysShortRegex;\n        }\n    } else {\n        if (!hasOwnProp(this, '_weekdaysShortRegex')) {\n            this._weekdaysShortRegex = defaultWeekdaysShortRegex;\n        }\n        return this._weekdaysShortStrictRegex && isStrict ?\n            this._weekdaysShortStrictRegex : this._weekdaysShortRegex;\n    }\n}\n\nvar defaultWeekdaysMinRegex = matchWord;\nfunction weekdaysMinRegex (isStrict) {\n    if (this._weekdaysParseExact) {\n        if (!hasOwnProp(this, '_weekdaysRegex')) {\n            computeWeekdaysParse.call(this);\n        }\n        if (isStrict) {\n            return this._weekdaysMinStrictRegex;\n        } else {\n            return this._weekdaysMinRegex;\n        }\n    } else {\n        if (!hasOwnProp(this, '_weekdaysMinRegex')) {\n            this._weekdaysMinRegex = defaultWeekdaysMinRegex;\n        }\n        return this._weekdaysMinStrictRegex && isStrict ?\n            this._weekdaysMinStrictRegex : this._weekdaysMinRegex;\n    }\n}\n\n\nfunction computeWeekdaysParse () {\n    function cmpLenRev(a, b) {\n        return b.length - a.length;\n    }\n\n    var minPieces = [], shortPieces = [], longPieces = [], mixedPieces = [],\n        i, mom, minp, shortp, longp;\n    for (i = 0; i < 7; i++) {\n        // make the regex if we don't have it already\n        mom = createUTC([2000, 1]).day(i);\n        minp = this.weekdaysMin(mom, '');\n        shortp = this.weekdaysShort(mom, '');\n        longp = this.weekdays(mom, '');\n        minPieces.push(minp);\n        shortPieces.push(shortp);\n        longPieces.push(longp);\n        mixedPieces.push(minp);\n        mixedPieces.push(shortp);\n        mixedPieces.push(longp);\n    }\n    // Sorting makes sure if one weekday (or abbr) is a prefix of another it\n    // will match the longer piece.\n    minPieces.sort(cmpLenRev);\n    shortPieces.sort(cmpLenRev);\n    longPieces.sort(cmpLenRev);\n    mixedPieces.sort(cmpLenRev);\n    for (i = 0; i < 7; i++) {\n        shortPieces[i] = regexEscape(shortPieces[i]);\n        longPieces[i] = regexEscape(longPieces[i]);\n        mixedPieces[i] = regexEscape(mixedPieces[i]);\n    }\n\n    this._weekdaysRegex = new RegExp('^(' + mixedPieces.join('|') + ')', 'i');\n    this._weekdaysShortRegex = this._weekdaysRegex;\n    this._weekdaysMinRegex = this._weekdaysRegex;\n\n    this._weekdaysStrictRegex = new RegExp('^(' + longPieces.join('|') + ')', 'i');\n    this._weekdaysShortStrictRegex = new RegExp('^(' + shortPieces.join('|') + ')', 'i');\n    this._weekdaysMinStrictRegex = new RegExp('^(' + minPieces.join('|') + ')', 'i');\n}\n\n// FORMATTING\n\nfunction hFormat() {\n    return this.hours() % 12 || 12;\n}\n\nfunction kFormat() {\n    return this.hours() || 24;\n}\n\naddFormatToken('H', ['HH', 2], 0, 'hour');\naddFormatToken('h', ['hh', 2], 0, hFormat);\naddFormatToken('k', ['kk', 2], 0, kFormat);\n\naddFormatToken('hmm', 0, 0, function () {\n    return '' + hFormat.apply(this) + zeroFill(this.minutes(), 2);\n});\n\naddFormatToken('hmmss', 0, 0, function () {\n    return '' + hFormat.apply(this) + zeroFill(this.minutes(), 2) +\n        zeroFill(this.seconds(), 2);\n});\n\naddFormatToken('Hmm', 0, 0, function () {\n    return '' + this.hours() + zeroFill(this.minutes(), 2);\n});\n\naddFormatToken('Hmmss', 0, 0, function () {\n    return '' + this.hours() + zeroFill(this.minutes(), 2) +\n        zeroFill(this.seconds(), 2);\n});\n\nfunction meridiem (token, lowercase) {\n    addFormatToken(token, 0, 0, function () {\n        return this.localeData().meridiem(this.hours(), this.minutes(), lowercase);\n    });\n}\n\nmeridiem('a', true);\nmeridiem('A', false);\n\n// ALIASES\n\naddUnitAlias('hour', 'h');\n\n// PRIORITY\naddUnitPriority('hour', 13);\n\n// PARSING\n\nfunction matchMeridiem (isStrict, locale) {\n    return locale._meridiemParse;\n}\n\naddRegexToken('a',  matchMeridiem);\naddRegexToken('A',  matchMeridiem);\naddRegexToken('H',  match1to2);\naddRegexToken('h',  match1to2);\naddRegexToken('k',  match1to2);\naddRegexToken('HH', match1to2, match2);\naddRegexToken('hh', match1to2, match2);\naddRegexToken('kk', match1to2, match2);\n\naddRegexToken('hmm', match3to4);\naddRegexToken('hmmss', match5to6);\naddRegexToken('Hmm', match3to4);\naddRegexToken('Hmmss', match5to6);\n\naddParseToken(['H', 'HH'], HOUR);\naddParseToken(['k', 'kk'], function (input, array, config) {\n    var kInput = toInt(input);\n    array[HOUR] = kInput === 24 ? 0 : kInput;\n});\naddParseToken(['a', 'A'], function (input, array, config) {\n    config._isPm = config._locale.isPM(input);\n    config._meridiem = input;\n});\naddParseToken(['h', 'hh'], function (input, array, config) {\n    array[HOUR] = toInt(input);\n    getParsingFlags(config).bigHour = true;\n});\naddParseToken('hmm', function (input, array, config) {\n    var pos = input.length - 2;\n    array[HOUR] = toInt(input.substr(0, pos));\n    array[MINUTE] = toInt(input.substr(pos));\n    getParsingFlags(config).bigHour = true;\n});\naddParseToken('hmmss', function (input, array, config) {\n    var pos1 = input.length - 4;\n    var pos2 = input.length - 2;\n    array[HOUR] = toInt(input.substr(0, pos1));\n    array[MINUTE] = toInt(input.substr(pos1, 2));\n    array[SECOND] = toInt(input.substr(pos2));\n    getParsingFlags(config).bigHour = true;\n});\naddParseToken('Hmm', function (input, array, config) {\n    var pos = input.length - 2;\n    array[HOUR] = toInt(input.substr(0, pos));\n    array[MINUTE] = toInt(input.substr(pos));\n});\naddParseToken('Hmmss', function (input, array, config) {\n    var pos1 = input.length - 4;\n    var pos2 = input.length - 2;\n    array[HOUR] = toInt(input.substr(0, pos1));\n    array[MINUTE] = toInt(input.substr(pos1, 2));\n    array[SECOND] = toInt(input.substr(pos2));\n});\n\n// LOCALES\n\nfunction localeIsPM (input) {\n    // IE8 Quirks Mode & IE7 Standards Mode do not allow accessing strings like arrays\n    // Using charAt should be more compatible.\n    return ((input + '').toLowerCase().charAt(0) === 'p');\n}\n\nvar defaultLocaleMeridiemParse = /[ap]\\.?m?\\.?/i;\nfunction localeMeridiem (hours, minutes, isLower) {\n    if (hours > 11) {\n        return isLower ? 'pm' : 'PM';\n    } else {\n        return isLower ? 'am' : 'AM';\n    }\n}\n\n\n// MOMENTS\n\n// Setting the hour should keep the time, because the user explicitly\n// specified which hour he wants. So trying to maintain the same hour (in\n// a new timezone) makes sense. Adding/subtracting hours does not follow\n// this rule.\nvar getSetHour = makeGetSet('Hours', true);\n\n// months\n// week\n// weekdays\n// meridiem\nvar baseConfig = {\n    calendar: defaultCalendar,\n    longDateFormat: defaultLongDateFormat,\n    invalidDate: defaultInvalidDate,\n    ordinal: defaultOrdinal,\n    dayOfMonthOrdinalParse: defaultDayOfMonthOrdinalParse,\n    relativeTime: defaultRelativeTime,\n\n    months: defaultLocaleMonths,\n    monthsShort: defaultLocaleMonthsShort,\n\n    week: defaultLocaleWeek,\n\n    weekdays: defaultLocaleWeekdays,\n    weekdaysMin: defaultLocaleWeekdaysMin,\n    weekdaysShort: defaultLocaleWeekdaysShort,\n\n    meridiemParse: defaultLocaleMeridiemParse\n};\n\n// internal storage for locale config files\nvar locales = {};\nvar localeFamilies = {};\nvar globalLocale;\n\nfunction normalizeLocale(key) {\n    return key ? key.toLowerCase().replace('_', '-') : key;\n}\n\n// pick the locale from the array\n// try ['en-au', 'en-gb'] as 'en-au', 'en-gb', 'en', as in move through the list trying each\n// substring from most specific to least, but move to the next array item if it's a more specific variant than the current root\nfunction chooseLocale(names) {\n    var i = 0, j, next, locale, split;\n\n    while (i < names.length) {\n        split = normalizeLocale(names[i]).split('-');\n        j = split.length;\n        next = normalizeLocale(names[i + 1]);\n        next = next ? next.split('-') : null;\n        while (j > 0) {\n            locale = loadLocale(split.slice(0, j).join('-'));\n            if (locale) {\n                return locale;\n            }\n            if (next && next.length >= j && compareArrays(split, next, true) >= j - 1) {\n                //the next array item is better than a shallower substring of this one\n                break;\n            }\n            j--;\n        }\n        i++;\n    }\n    return null;\n}\n\nfunction loadLocale(name) {\n    var oldLocale = null;\n    // TODO: Find a better way to register and load all the locales in Node\n    if (!locales[name] && (typeof module !== 'undefined') &&\n            module && module.exports) {\n        try {\n            oldLocale = globalLocale._abbr;\n            require('./locale/' + name);\n            // because defineLocale currently also sets the global locale, we\n            // want to undo that for lazy loaded locales\n            getSetGlobalLocale(oldLocale);\n        } catch (e) { }\n    }\n    return locales[name];\n}\n\n// This function will load locale and then set the global locale.  If\n// no arguments are passed in, it will simply return the current global\n// locale key.\nfunction getSetGlobalLocale (key, values) {\n    var data;\n    if (key) {\n        if (isUndefined(values)) {\n            data = getLocale(key);\n        }\n        else {\n            data = defineLocale(key, values);\n        }\n\n        if (data) {\n            // moment.duration._locale = moment._locale = data;\n            globalLocale = data;\n        }\n    }\n\n    return globalLocale._abbr;\n}\n\nfunction defineLocale (name, config) {\n    if (config !== null) {\n        var parentConfig = baseConfig;\n        config.abbr = name;\n        if (locales[name] != null) {\n            deprecateSimple('defineLocaleOverride',\n                    'use moment.updateLocale(localeName, config) to change ' +\n                    'an existing locale. moment.defineLocale(localeName, ' +\n                    'config) should only be used for creating a new locale ' +\n                    'See http://momentjs.com/guides/#/warnings/define-locale/ for more info.');\n            parentConfig = locales[name]._config;\n        } else if (config.parentLocale != null) {\n            if (locales[config.parentLocale] != null) {\n                parentConfig = locales[config.parentLocale]._config;\n            } else {\n                if (!localeFamilies[config.parentLocale]) {\n                    localeFamilies[config.parentLocale] = [];\n                }\n                localeFamilies[config.parentLocale].push({\n                    name: name,\n                    config: config\n                });\n                return null;\n            }\n        }\n        locales[name] = new Locale(mergeConfigs(parentConfig, config));\n\n        if (localeFamilies[name]) {\n            localeFamilies[name].forEach(function (x) {\n                defineLocale(x.name, x.config);\n            });\n        }\n\n        // backwards compat for now: also set the locale\n        // make sure we set the locale AFTER all child locales have been\n        // created, so we won't end up with the child locale set.\n        getSetGlobalLocale(name);\n\n\n        return locales[name];\n    } else {\n        // useful for testing\n        delete locales[name];\n        return null;\n    }\n}\n\nfunction updateLocale(name, config) {\n    if (config != null) {\n        var locale, parentConfig = baseConfig;\n        // MERGE\n        if (locales[name] != null) {\n            parentConfig = locales[name]._config;\n        }\n        config = mergeConfigs(parentConfig, config);\n        locale = new Locale(config);\n        locale.parentLocale = locales[name];\n        locales[name] = locale;\n\n        // backwards compat for now: also set the locale\n        getSetGlobalLocale(name);\n    } else {\n        // pass null for config to unupdate, useful for tests\n        if (locales[name] != null) {\n            if (locales[name].parentLocale != null) {\n                locales[name] = locales[name].parentLocale;\n            } else if (locales[name] != null) {\n                delete locales[name];\n            }\n        }\n    }\n    return locales[name];\n}\n\n// returns locale data\nfunction getLocale (key) {\n    var locale;\n\n    if (key && key._locale && key._locale._abbr) {\n        key = key._locale._abbr;\n    }\n\n    if (!key) {\n        return globalLocale;\n    }\n\n    if (!isArray(key)) {\n        //short-circuit everything else\n        locale = loadLocale(key);\n        if (locale) {\n            return locale;\n        }\n        key = [key];\n    }\n\n    return chooseLocale(key);\n}\n\nfunction listLocales() {\n    return keys$1(locales);\n}\n\nfunction checkOverflow (m) {\n    var overflow;\n    var a = m._a;\n\n    if (a && getParsingFlags(m).overflow === -2) {\n        overflow =\n            a[MONTH]       < 0 || a[MONTH]       > 11  ? MONTH :\n            a[DATE]        < 1 || a[DATE]        > daysInMonth(a[YEAR], a[MONTH]) ? DATE :\n            a[HOUR]        < 0 || a[HOUR]        > 24 || (a[HOUR] === 24 && (a[MINUTE] !== 0 || a[SECOND] !== 0 || a[MILLISECOND] !== 0)) ? HOUR :\n            a[MINUTE]      < 0 || a[MINUTE]      > 59  ? MINUTE :\n            a[SECOND]      < 0 || a[SECOND]      > 59  ? SECOND :\n            a[MILLISECOND] < 0 || a[MILLISECOND] > 999 ? MILLISECOND :\n            -1;\n\n        if (getParsingFlags(m)._overflowDayOfYear && (overflow < YEAR || overflow > DATE)) {\n            overflow = DATE;\n        }\n        if (getParsingFlags(m)._overflowWeeks && overflow === -1) {\n            overflow = WEEK;\n        }\n        if (getParsingFlags(m)._overflowWeekday && overflow === -1) {\n            overflow = WEEKDAY;\n        }\n\n        getParsingFlags(m).overflow = overflow;\n    }\n\n    return m;\n}\n\n// iso 8601 regex\n// 0000-00-00 0000-W00 or 0000-W00-0 + T + 00 or 00:00 or 00:00:00 or 00:00:00.000 + +00:00 or +0000 or +00)\nvar extendedIsoRegex = /^\\s*((?:[+-]\\d{6}|\\d{4})-(?:\\d\\d-\\d\\d|W\\d\\d-\\d|W\\d\\d|\\d\\d\\d|\\d\\d))(?:(T| )(\\d\\d(?::\\d\\d(?::\\d\\d(?:[.,]\\d+)?)?)?)([\\+\\-]\\d\\d(?::?\\d\\d)?|\\s*Z)?)?$/;\nvar basicIsoRegex = /^\\s*((?:[+-]\\d{6}|\\d{4})(?:\\d\\d\\d\\d|W\\d\\d\\d|W\\d\\d|\\d\\d\\d|\\d\\d))(?:(T| )(\\d\\d(?:\\d\\d(?:\\d\\d(?:[.,]\\d+)?)?)?)([\\+\\-]\\d\\d(?::?\\d\\d)?|\\s*Z)?)?$/;\n\nvar tzRegex = /Z|[+-]\\d\\d(?::?\\d\\d)?/;\n\nvar isoDates = [\n    ['YYYYYY-MM-DD', /[+-]\\d{6}-\\d\\d-\\d\\d/],\n    ['YYYY-MM-DD', /\\d{4}-\\d\\d-\\d\\d/],\n    ['GGGG-[W]WW-E', /\\d{4}-W\\d\\d-\\d/],\n    ['GGGG-[W]WW', /\\d{4}-W\\d\\d/, false],\n    ['YYYY-DDD', /\\d{4}-\\d{3}/],\n    ['YYYY-MM', /\\d{4}-\\d\\d/, false],\n    ['YYYYYYMMDD', /[+-]\\d{10}/],\n    ['YYYYMMDD', /\\d{8}/],\n    // YYYYMM is NOT allowed by the standard\n    ['GGGG[W]WWE', /\\d{4}W\\d{3}/],\n    ['GGGG[W]WW', /\\d{4}W\\d{2}/, false],\n    ['YYYYDDD', /\\d{7}/]\n];\n\n// iso time formats and regexes\nvar isoTimes = [\n    ['HH:mm:ss.SSSS', /\\d\\d:\\d\\d:\\d\\d\\.\\d+/],\n    ['HH:mm:ss,SSSS', /\\d\\d:\\d\\d:\\d\\d,\\d+/],\n    ['HH:mm:ss', /\\d\\d:\\d\\d:\\d\\d/],\n    ['HH:mm', /\\d\\d:\\d\\d/],\n    ['HHmmss.SSSS', /\\d\\d\\d\\d\\d\\d\\.\\d+/],\n    ['HHmmss,SSSS', /\\d\\d\\d\\d\\d\\d,\\d+/],\n    ['HHmmss', /\\d\\d\\d\\d\\d\\d/],\n    ['HHmm', /\\d\\d\\d\\d/],\n    ['HH', /\\d\\d/]\n];\n\nvar aspNetJsonRegex = /^\\/?Date\\((\\-?\\d+)/i;\n\n// date from iso format\nfunction configFromISO(config) {\n    var i, l,\n        string = config._i,\n        match = extendedIsoRegex.exec(string) || basicIsoRegex.exec(string),\n        allowTime, dateFormat, timeFormat, tzFormat;\n\n    if (match) {\n        getParsingFlags(config).iso = true;\n\n        for (i = 0, l = isoDates.length; i < l; i++) {\n            if (isoDates[i][1].exec(match[1])) {\n                dateFormat = isoDates[i][0];\n                allowTime = isoDates[i][2] !== false;\n                break;\n            }\n        }\n        if (dateFormat == null) {\n            config._isValid = false;\n            return;\n        }\n        if (match[3]) {\n            for (i = 0, l = isoTimes.length; i < l; i++) {\n                if (isoTimes[i][1].exec(match[3])) {\n                    // match[2] should be 'T' or space\n                    timeFormat = (match[2] || ' ') + isoTimes[i][0];\n                    break;\n                }\n            }\n            if (timeFormat == null) {\n                config._isValid = false;\n                return;\n            }\n        }\n        if (!allowTime && timeFormat != null) {\n            config._isValid = false;\n            return;\n        }\n        if (match[4]) {\n            if (tzRegex.exec(match[4])) {\n                tzFormat = 'Z';\n            } else {\n                config._isValid = false;\n                return;\n            }\n        }\n        config._f = dateFormat + (timeFormat || '') + (tzFormat || '');\n        configFromStringAndFormat(config);\n    } else {\n        config._isValid = false;\n    }\n}\n\n// RFC 2822 regex: For details see https://tools.ietf.org/html/rfc2822#section-3.3\nvar basicRfcRegex = /^((?:Mon|Tue|Wed|Thu|Fri|Sat|Sun),?\\s)?(\\d?\\d\\s(?:Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)\\s(?:\\d\\d)?\\d\\d\\s)(\\d\\d:\\d\\d)(\\:\\d\\d)?(\\s(?:UT|GMT|[ECMP][SD]T|[A-IK-Za-ik-z]|[+-]\\d{4}))$/;\n\n// date and time from ref 2822 format\nfunction configFromRFC2822(config) {\n    var string, match, dayFormat,\n        dateFormat, timeFormat, tzFormat;\n    var timezones = {\n        ' GMT': ' +0000',\n        ' EDT': ' -0400',\n        ' EST': ' -0500',\n        ' CDT': ' -0500',\n        ' CST': ' -0600',\n        ' MDT': ' -0600',\n        ' MST': ' -0700',\n        ' PDT': ' -0700',\n        ' PST': ' -0800'\n    };\n    var military = 'YXWVUTSRQPONZABCDEFGHIKLM';\n    var timezone, timezoneIndex;\n\n    string = config._i\n        .replace(/\\([^\\)]*\\)|[\\n\\t]/g, ' ') // Remove comments and folding whitespace\n        .replace(/(\\s\\s+)/g, ' ') // Replace multiple-spaces with a single space\n        .replace(/^\\s|\\s$/g, ''); // Remove leading and trailing spaces\n    match = basicRfcRegex.exec(string);\n\n    if (match) {\n        dayFormat = match[1] ? 'ddd' + ((match[1].length === 5) ? ', ' : ' ') : '';\n        dateFormat = 'D MMM ' + ((match[2].length > 10) ? 'YYYY ' : 'YY ');\n        timeFormat = 'HH:mm' + (match[4] ? ':ss' : '');\n\n        // TODO: Replace the vanilla JS Date object with an indepentent day-of-week check.\n        if (match[1]) { // day of week given\n            var momentDate = new Date(match[2]);\n            var momentDay = ['Sun','Mon','Tue','Wed','Thu','Fri','Sat'][momentDate.getDay()];\n\n            if (match[1].substr(0,3) !== momentDay) {\n                getParsingFlags(config).weekdayMismatch = true;\n                config._isValid = false;\n                return;\n            }\n        }\n\n        switch (match[5].length) {\n            case 2: // military\n                if (timezoneIndex === 0) {\n                    timezone = ' +0000';\n                } else {\n                    timezoneIndex = military.indexOf(match[5][1].toUpperCase()) - 12;\n                    timezone = ((timezoneIndex < 0) ? ' -' : ' +') +\n                        (('' + timezoneIndex).replace(/^-?/, '0')).match(/..$/)[0] + '00';\n                }\n                break;\n            case 4: // Zone\n                timezone = timezones[match[5]];\n                break;\n            default: // UT or +/-9999\n                timezone = timezones[' GMT'];\n        }\n        match[5] = timezone;\n        config._i = match.splice(1).join('');\n        tzFormat = ' ZZ';\n        config._f = dayFormat + dateFormat + timeFormat + tzFormat;\n        configFromStringAndFormat(config);\n        getParsingFlags(config).rfc2822 = true;\n    } else {\n        config._isValid = false;\n    }\n}\n\n// date from iso format or fallback\nfunction configFromString(config) {\n    var matched = aspNetJsonRegex.exec(config._i);\n\n    if (matched !== null) {\n        config._d = new Date(+matched[1]);\n        return;\n    }\n\n    configFromISO(config);\n    if (config._isValid === false) {\n        delete config._isValid;\n    } else {\n        return;\n    }\n\n    configFromRFC2822(config);\n    if (config._isValid === false) {\n        delete config._isValid;\n    } else {\n        return;\n    }\n\n    // Final attempt, use Input Fallback\n    hooks.createFromInputFallback(config);\n}\n\nhooks.createFromInputFallback = deprecate(\n    'value provided is not in a recognized RFC2822 or ISO format. moment construction falls back to js Date(), ' +\n    'which is not reliable across all browsers and versions. Non RFC2822/ISO date formats are ' +\n    'discouraged and will be removed in an upcoming major release. Please refer to ' +\n    'http://momentjs.com/guides/#/warnings/js-date/ for more info.',\n    function (config) {\n        config._d = new Date(config._i + (config._useUTC ? ' UTC' : ''));\n    }\n);\n\n// Pick the first defined of two or three arguments.\nfunction defaults(a, b, c) {\n    if (a != null) {\n        return a;\n    }\n    if (b != null) {\n        return b;\n    }\n    return c;\n}\n\nfunction currentDateArray(config) {\n    // hooks is actually the exported moment object\n    var nowValue = new Date(hooks.now());\n    if (config._useUTC) {\n        return [nowValue.getUTCFullYear(), nowValue.getUTCMonth(), nowValue.getUTCDate()];\n    }\n    return [nowValue.getFullYear(), nowValue.getMonth(), nowValue.getDate()];\n}\n\n// convert an array to a date.\n// the array should mirror the parameters below\n// note: all values past the year are optional and will default to the lowest possible value.\n// [year, month, day , hour, minute, second, millisecond]\nfunction configFromArray (config) {\n    var i, date, input = [], currentDate, yearToUse;\n\n    if (config._d) {\n        return;\n    }\n\n    currentDate = currentDateArray(config);\n\n    //compute day of the year from weeks and weekdays\n    if (config._w && config._a[DATE] == null && config._a[MONTH] == null) {\n        dayOfYearFromWeekInfo(config);\n    }\n\n    //if the day of the year is set, figure out what it is\n    if (config._dayOfYear != null) {\n        yearToUse = defaults(config._a[YEAR], currentDate[YEAR]);\n\n        if (config._dayOfYear > daysInYear(yearToUse) || config._dayOfYear === 0) {\n            getParsingFlags(config)._overflowDayOfYear = true;\n        }\n\n        date = createUTCDate(yearToUse, 0, config._dayOfYear);\n        config._a[MONTH] = date.getUTCMonth();\n        config._a[DATE] = date.getUTCDate();\n    }\n\n    // Default to current date.\n    // * if no year, month, day of month are given, default to today\n    // * if day of month is given, default month and year\n    // * if month is given, default only year\n    // * if year is given, don't default anything\n    for (i = 0; i < 3 && config._a[i] == null; ++i) {\n        config._a[i] = input[i] = currentDate[i];\n    }\n\n    // Zero out whatever was not defaulted, including time\n    for (; i < 7; i++) {\n        config._a[i] = input[i] = (config._a[i] == null) ? (i === 2 ? 1 : 0) : config._a[i];\n    }\n\n    // Check for 24:00:00.000\n    if (config._a[HOUR] === 24 &&\n            config._a[MINUTE] === 0 &&\n            config._a[SECOND] === 0 &&\n            config._a[MILLISECOND] === 0) {\n        config._nextDay = true;\n        config._a[HOUR] = 0;\n    }\n\n    config._d = (config._useUTC ? createUTCDate : createDate).apply(null, input);\n    // Apply timezone offset from input. The actual utcOffset can be changed\n    // with parseZone.\n    if (config._tzm != null) {\n        config._d.setUTCMinutes(config._d.getUTCMinutes() - config._tzm);\n    }\n\n    if (config._nextDay) {\n        config._a[HOUR] = 24;\n    }\n}\n\nfunction dayOfYearFromWeekInfo(config) {\n    var w, weekYear, week, weekday, dow, doy, temp, weekdayOverflow;\n\n    w = config._w;\n    if (w.GG != null || w.W != null || w.E != null) {\n        dow = 1;\n        doy = 4;\n\n        // TODO: We need to take the current isoWeekYear, but that depends on\n        // how we interpret now (local, utc, fixed offset). So create\n        // a now version of current config (take local/utc/offset flags, and\n        // create now).\n        weekYear = defaults(w.GG, config._a[YEAR], weekOfYear(createLocal(), 1, 4).year);\n        week = defaults(w.W, 1);\n        weekday = defaults(w.E, 1);\n        if (weekday < 1 || weekday > 7) {\n            weekdayOverflow = true;\n        }\n    } else {\n        dow = config._locale._week.dow;\n        doy = config._locale._week.doy;\n\n        var curWeek = weekOfYear(createLocal(), dow, doy);\n\n        weekYear = defaults(w.gg, config._a[YEAR], curWeek.year);\n\n        // Default to current week.\n        week = defaults(w.w, curWeek.week);\n\n        if (w.d != null) {\n            // weekday -- low day numbers are considered next week\n            weekday = w.d;\n            if (weekday < 0 || weekday > 6) {\n                weekdayOverflow = true;\n            }\n        } else if (w.e != null) {\n            // local weekday -- counting starts from begining of week\n            weekday = w.e + dow;\n            if (w.e < 0 || w.e > 6) {\n                weekdayOverflow = true;\n            }\n        } else {\n            // default to begining of week\n            weekday = dow;\n        }\n    }\n    if (week < 1 || week > weeksInYear(weekYear, dow, doy)) {\n        getParsingFlags(config)._overflowWeeks = true;\n    } else if (weekdayOverflow != null) {\n        getParsingFlags(config)._overflowWeekday = true;\n    } else {\n        temp = dayOfYearFromWeeks(weekYear, week, weekday, dow, doy);\n        config._a[YEAR] = temp.year;\n        config._dayOfYear = temp.dayOfYear;\n    }\n}\n\n// constant that refers to the ISO standard\nhooks.ISO_8601 = function () {};\n\n// constant that refers to the RFC 2822 form\nhooks.RFC_2822 = function () {};\n\n// date from string and format string\nfunction configFromStringAndFormat(config) {\n    // TODO: Move this to another part of the creation flow to prevent circular deps\n    if (config._f === hooks.ISO_8601) {\n        configFromISO(config);\n        return;\n    }\n    if (config._f === hooks.RFC_2822) {\n        configFromRFC2822(config);\n        return;\n    }\n    config._a = [];\n    getParsingFlags(config).empty = true;\n\n    // This array is used to make a Date, either with `new Date` or `Date.UTC`\n    var string = '' + config._i,\n        i, parsedInput, tokens, token, skipped,\n        stringLength = string.length,\n        totalParsedInputLength = 0;\n\n    tokens = expandFormat(config._f, config._locale).match(formattingTokens) || [];\n\n    for (i = 0; i < tokens.length; i++) {\n        token = tokens[i];\n        parsedInput = (string.match(getParseRegexForToken(token, config)) || [])[0];\n        // console.log('token', token, 'parsedInput', parsedInput,\n        //         'regex', getParseRegexForToken(token, config));\n        if (parsedInput) {\n            skipped = string.substr(0, string.indexOf(parsedInput));\n            if (skipped.length > 0) {\n                getParsingFlags(config).unusedInput.push(skipped);\n            }\n            string = string.slice(string.indexOf(parsedInput) + parsedInput.length);\n            totalParsedInputLength += parsedInput.length;\n        }\n        // don't parse if it's not a known token\n        if (formatTokenFunctions[token]) {\n            if (parsedInput) {\n                getParsingFlags(config).empty = false;\n            }\n            else {\n                getParsingFlags(config).unusedTokens.push(token);\n            }\n            addTimeToArrayFromToken(token, parsedInput, config);\n        }\n        else if (config._strict && !parsedInput) {\n            getParsingFlags(config).unusedTokens.push(token);\n        }\n    }\n\n    // add remaining unparsed input length to the string\n    getParsingFlags(config).charsLeftOver = stringLength - totalParsedInputLength;\n    if (string.length > 0) {\n        getParsingFlags(config).unusedInput.push(string);\n    }\n\n    // clear _12h flag if hour is <= 12\n    if (config._a[HOUR] <= 12 &&\n        getParsingFlags(config).bigHour === true &&\n        config._a[HOUR] > 0) {\n        getParsingFlags(config).bigHour = undefined;\n    }\n\n    getParsingFlags(config).parsedDateParts = config._a.slice(0);\n    getParsingFlags(config).meridiem = config._meridiem;\n    // handle meridiem\n    config._a[HOUR] = meridiemFixWrap(config._locale, config._a[HOUR], config._meridiem);\n\n    configFromArray(config);\n    checkOverflow(config);\n}\n\n\nfunction meridiemFixWrap (locale, hour, meridiem) {\n    var isPm;\n\n    if (meridiem == null) {\n        // nothing to do\n        return hour;\n    }\n    if (locale.meridiemHour != null) {\n        return locale.meridiemHour(hour, meridiem);\n    } else if (locale.isPM != null) {\n        // Fallback\n        isPm = locale.isPM(meridiem);\n        if (isPm && hour < 12) {\n            hour += 12;\n        }\n        if (!isPm && hour === 12) {\n            hour = 0;\n        }\n        return hour;\n    } else {\n        // this is not supposed to happen\n        return hour;\n    }\n}\n\n// date from string and array of format strings\nfunction configFromStringAndArray(config) {\n    var tempConfig,\n        bestMoment,\n\n        scoreToBeat,\n        i,\n        currentScore;\n\n    if (config._f.length === 0) {\n        getParsingFlags(config).invalidFormat = true;\n        config._d = new Date(NaN);\n        return;\n    }\n\n    for (i = 0; i < config._f.length; i++) {\n        currentScore = 0;\n        tempConfig = copyConfig({}, config);\n        if (config._useUTC != null) {\n            tempConfig._useUTC = config._useUTC;\n        }\n        tempConfig._f = config._f[i];\n        configFromStringAndFormat(tempConfig);\n\n        if (!isValid(tempConfig)) {\n            continue;\n        }\n\n        // if there is any input that was not parsed add a penalty for that format\n        currentScore += getParsingFlags(tempConfig).charsLeftOver;\n\n        //or tokens\n        currentScore += getParsingFlags(tempConfig).unusedTokens.length * 10;\n\n        getParsingFlags(tempConfig).score = currentScore;\n\n        if (scoreToBeat == null || currentScore < scoreToBeat) {\n            scoreToBeat = currentScore;\n            bestMoment = tempConfig;\n        }\n    }\n\n    extend(config, bestMoment || tempConfig);\n}\n\nfunction configFromObject(config) {\n    if (config._d) {\n        return;\n    }\n\n    var i = normalizeObjectUnits(config._i);\n    config._a = map([i.year, i.month, i.day || i.date, i.hour, i.minute, i.second, i.millisecond], function (obj) {\n        return obj && parseInt(obj, 10);\n    });\n\n    configFromArray(config);\n}\n\nfunction createFromConfig (config) {\n    var res = new Moment(checkOverflow(prepareConfig(config)));\n    if (res._nextDay) {\n        // Adding is smart enough around DST\n        res.add(1, 'd');\n        res._nextDay = undefined;\n    }\n\n    return res;\n}\n\nfunction prepareConfig (config) {\n    var input = config._i,\n        format = config._f;\n\n    config._locale = config._locale || getLocale(config._l);\n\n    if (input === null || (format === undefined && input === '')) {\n        return createInvalid({nullInput: true});\n    }\n\n    if (typeof input === 'string') {\n        config._i = input = config._locale.preparse(input);\n    }\n\n    if (isMoment(input)) {\n        return new Moment(checkOverflow(input));\n    } else if (isDate(input)) {\n        config._d = input;\n    } else if (isArray(format)) {\n        configFromStringAndArray(config);\n    } else if (format) {\n        configFromStringAndFormat(config);\n    }  else {\n        configFromInput(config);\n    }\n\n    if (!isValid(config)) {\n        config._d = null;\n    }\n\n    return config;\n}\n\nfunction configFromInput(config) {\n    var input = config._i;\n    if (isUndefined(input)) {\n        config._d = new Date(hooks.now());\n    } else if (isDate(input)) {\n        config._d = new Date(input.valueOf());\n    } else if (typeof input === 'string') {\n        configFromString(config);\n    } else if (isArray(input)) {\n        config._a = map(input.slice(0), function (obj) {\n            return parseInt(obj, 10);\n        });\n        configFromArray(config);\n    } else if (isObject(input)) {\n        configFromObject(config);\n    } else if (isNumber(input)) {\n        // from milliseconds\n        config._d = new Date(input);\n    } else {\n        hooks.createFromInputFallback(config);\n    }\n}\n\nfunction createLocalOrUTC (input, format, locale, strict, isUTC) {\n    var c = {};\n\n    if (locale === true || locale === false) {\n        strict = locale;\n        locale = undefined;\n    }\n\n    if ((isObject(input) && isObjectEmpty(input)) ||\n            (isArray(input) && input.length === 0)) {\n        input = undefined;\n    }\n    // object construction must be done this way.\n    // https://github.com/moment/moment/issues/1423\n    c._isAMomentObject = true;\n    c._useUTC = c._isUTC = isUTC;\n    c._l = locale;\n    c._i = input;\n    c._f = format;\n    c._strict = strict;\n\n    return createFromConfig(c);\n}\n\nfunction createLocal (input, format, locale, strict) {\n    return createLocalOrUTC(input, format, locale, strict, false);\n}\n\nvar prototypeMin = deprecate(\n    'moment().min is deprecated, use moment.max instead. http://momentjs.com/guides/#/warnings/min-max/',\n    function () {\n        var other = createLocal.apply(null, arguments);\n        if (this.isValid() && other.isValid()) {\n            return other < this ? this : other;\n        } else {\n            return createInvalid();\n        }\n    }\n);\n\nvar prototypeMax = deprecate(\n    'moment().max is deprecated, use moment.min instead. http://momentjs.com/guides/#/warnings/min-max/',\n    function () {\n        var other = createLocal.apply(null, arguments);\n        if (this.isValid() && other.isValid()) {\n            return other > this ? this : other;\n        } else {\n            return createInvalid();\n        }\n    }\n);\n\n// Pick a moment m from moments so that m[fn](other) is true for all\n// other. This relies on the function fn to be transitive.\n//\n// moments should either be an array of moment objects or an array, whose\n// first element is an array of moment objects.\nfunction pickBy(fn, moments) {\n    var res, i;\n    if (moments.length === 1 && isArray(moments[0])) {\n        moments = moments[0];\n    }\n    if (!moments.length) {\n        return createLocal();\n    }\n    res = moments[0];\n    for (i = 1; i < moments.length; ++i) {\n        if (!moments[i].isValid() || moments[i][fn](res)) {\n            res = moments[i];\n        }\n    }\n    return res;\n}\n\n// TODO: Use [].sort instead?\nfunction min () {\n    var args = [].slice.call(arguments, 0);\n\n    return pickBy('isBefore', args);\n}\n\nfunction max () {\n    var args = [].slice.call(arguments, 0);\n\n    return pickBy('isAfter', args);\n}\n\nvar now = function () {\n    return Date.now ? Date.now() : +(new Date());\n};\n\nvar ordering = ['year', 'quarter', 'month', 'week', 'day', 'hour', 'minute', 'second', 'millisecond'];\n\nfunction isDurationValid(m) {\n    for (var key in m) {\n        if (!(ordering.indexOf(key) !== -1 && (m[key] == null || !isNaN(m[key])))) {\n            return false;\n        }\n    }\n\n    var unitHasDecimal = false;\n    for (var i = 0; i < ordering.length; ++i) {\n        if (m[ordering[i]]) {\n            if (unitHasDecimal) {\n                return false; // only allow non-integers for smallest unit\n            }\n            if (parseFloat(m[ordering[i]]) !== toInt(m[ordering[i]])) {\n                unitHasDecimal = true;\n            }\n        }\n    }\n\n    return true;\n}\n\nfunction isValid$1() {\n    return this._isValid;\n}\n\nfunction createInvalid$1() {\n    return createDuration(NaN);\n}\n\nfunction Duration (duration) {\n    var normalizedInput = normalizeObjectUnits(duration),\n        years = normalizedInput.year || 0,\n        quarters = normalizedInput.quarter || 0,\n        months = normalizedInput.month || 0,\n        weeks = normalizedInput.week || 0,\n        days = normalizedInput.day || 0,\n        hours = normalizedInput.hour || 0,\n        minutes = normalizedInput.minute || 0,\n        seconds = normalizedInput.second || 0,\n        milliseconds = normalizedInput.millisecond || 0;\n\n    this._isValid = isDurationValid(normalizedInput);\n\n    // representation for dateAddRemove\n    this._milliseconds = +milliseconds +\n        seconds * 1e3 + // 1000\n        minutes * 6e4 + // 1000 * 60\n        hours * 1000 * 60 * 60; //using 1000 * 60 * 60 instead of 36e5 to avoid floating point rounding errors https://github.com/moment/moment/issues/2978\n    // Because of dateAddRemove treats 24 hours as different from a\n    // day when working around DST, we need to store them separately\n    this._days = +days +\n        weeks * 7;\n    // It is impossible translate months into days without knowing\n    // which months you are are talking about, so we have to store\n    // it separately.\n    this._months = +months +\n        quarters * 3 +\n        years * 12;\n\n    this._data = {};\n\n    this._locale = getLocale();\n\n    this._bubble();\n}\n\nfunction isDuration (obj) {\n    return obj instanceof Duration;\n}\n\nfunction absRound (number) {\n    if (number < 0) {\n        return Math.round(-1 * number) * -1;\n    } else {\n        return Math.round(number);\n    }\n}\n\n// FORMATTING\n\nfunction offset (token, separator) {\n    addFormatToken(token, 0, 0, function () {\n        var offset = this.utcOffset();\n        var sign = '+';\n        if (offset < 0) {\n            offset = -offset;\n            sign = '-';\n        }\n        return sign + zeroFill(~~(offset / 60), 2) + separator + zeroFill(~~(offset) % 60, 2);\n    });\n}\n\noffset('Z', ':');\noffset('ZZ', '');\n\n// PARSING\n\naddRegexToken('Z',  matchShortOffset);\naddRegexToken('ZZ', matchShortOffset);\naddParseToken(['Z', 'ZZ'], function (input, array, config) {\n    config._useUTC = true;\n    config._tzm = offsetFromString(matchShortOffset, input);\n});\n\n// HELPERS\n\n// timezone chunker\n// '+10:00' > ['10',  '00']\n// '-1530'  > ['-15', '30']\nvar chunkOffset = /([\\+\\-]|\\d\\d)/gi;\n\nfunction offsetFromString(matcher, string) {\n    var matches = (string || '').match(matcher);\n\n    if (matches === null) {\n        return null;\n    }\n\n    var chunk   = matches[matches.length - 1] || [];\n    var parts   = (chunk + '').match(chunkOffset) || ['-', 0, 0];\n    var minutes = +(parts[1] * 60) + toInt(parts[2]);\n\n    return minutes === 0 ?\n      0 :\n      parts[0] === '+' ? minutes : -minutes;\n}\n\n// Return a moment from input, that is local/utc/zone equivalent to model.\nfunction cloneWithOffset(input, model) {\n    var res, diff;\n    if (model._isUTC) {\n        res = model.clone();\n        diff = (isMoment(input) || isDate(input) ? input.valueOf() : createLocal(input).valueOf()) - res.valueOf();\n        // Use low-level api, because this fn is low-level api.\n        res._d.setTime(res._d.valueOf() + diff);\n        hooks.updateOffset(res, false);\n        return res;\n    } else {\n        return createLocal(input).local();\n    }\n}\n\nfunction getDateOffset (m) {\n    // On Firefox.24 Date#getTimezoneOffset returns a floating point.\n    // https://github.com/moment/moment/pull/1871\n    return -Math.round(m._d.getTimezoneOffset() / 15) * 15;\n}\n\n// HOOKS\n\n// This function will be called whenever a moment is mutated.\n// It is intended to keep the offset in sync with the timezone.\nhooks.updateOffset = function () {};\n\n// MOMENTS\n\n// keepLocalTime = true means only change the timezone, without\n// affecting the local hour. So 5:31:26 +0300 --[utcOffset(2, true)]-->\n// 5:31:26 +0200 It is possible that 5:31:26 doesn't exist with offset\n// +0200, so we adjust the time as needed, to be valid.\n//\n// Keeping the time actually adds/subtracts (one hour)\n// from the actual represented time. That is why we call updateOffset\n// a second time. In case it wants us to change the offset again\n// _changeInProgress == true case, then we have to adjust, because\n// there is no such time in the given timezone.\nfunction getSetOffset (input, keepLocalTime, keepMinutes) {\n    var offset = this._offset || 0,\n        localAdjust;\n    if (!this.isValid()) {\n        return input != null ? this : NaN;\n    }\n    if (input != null) {\n        if (typeof input === 'string') {\n            input = offsetFromString(matchShortOffset, input);\n            if (input === null) {\n                return this;\n            }\n        } else if (Math.abs(input) < 16 && !keepMinutes) {\n            input = input * 60;\n        }\n        if (!this._isUTC && keepLocalTime) {\n            localAdjust = getDateOffset(this);\n        }\n        this._offset = input;\n        this._isUTC = true;\n        if (localAdjust != null) {\n            this.add(localAdjust, 'm');\n        }\n        if (offset !== input) {\n            if (!keepLocalTime || this._changeInProgress) {\n                addSubtract(this, createDuration(input - offset, 'm'), 1, false);\n            } else if (!this._changeInProgress) {\n                this._changeInProgress = true;\n                hooks.updateOffset(this, true);\n                this._changeInProgress = null;\n            }\n        }\n        return this;\n    } else {\n        return this._isUTC ? offset : getDateOffset(this);\n    }\n}\n\nfunction getSetZone (input, keepLocalTime) {\n    if (input != null) {\n        if (typeof input !== 'string') {\n            input = -input;\n        }\n\n        this.utcOffset(input, keepLocalTime);\n\n        return this;\n    } else {\n        return -this.utcOffset();\n    }\n}\n\nfunction setOffsetToUTC (keepLocalTime) {\n    return this.utcOffset(0, keepLocalTime);\n}\n\nfunction setOffsetToLocal (keepLocalTime) {\n    if (this._isUTC) {\n        this.utcOffset(0, keepLocalTime);\n        this._isUTC = false;\n\n        if (keepLocalTime) {\n            this.subtract(getDateOffset(this), 'm');\n        }\n    }\n    return this;\n}\n\nfunction setOffsetToParsedOffset () {\n    if (this._tzm != null) {\n        this.utcOffset(this._tzm, false, true);\n    } else if (typeof this._i === 'string') {\n        var tZone = offsetFromString(matchOffset, this._i);\n        if (tZone != null) {\n            this.utcOffset(tZone);\n        }\n        else {\n            this.utcOffset(0, true);\n        }\n    }\n    return this;\n}\n\nfunction hasAlignedHourOffset (input) {\n    if (!this.isValid()) {\n        return false;\n    }\n    input = input ? createLocal(input).utcOffset() : 0;\n\n    return (this.utcOffset() - input) % 60 === 0;\n}\n\nfunction isDaylightSavingTime () {\n    return (\n        this.utcOffset() > this.clone().month(0).utcOffset() ||\n        this.utcOffset() > this.clone().month(5).utcOffset()\n    );\n}\n\nfunction isDaylightSavingTimeShifted () {\n    if (!isUndefined(this._isDSTShifted)) {\n        return this._isDSTShifted;\n    }\n\n    var c = {};\n\n    copyConfig(c, this);\n    c = prepareConfig(c);\n\n    if (c._a) {\n        var other = c._isUTC ? createUTC(c._a) : createLocal(c._a);\n        this._isDSTShifted = this.isValid() &&\n            compareArrays(c._a, other.toArray()) > 0;\n    } else {\n        this._isDSTShifted = false;\n    }\n\n    return this._isDSTShifted;\n}\n\nfunction isLocal () {\n    return this.isValid() ? !this._isUTC : false;\n}\n\nfunction isUtcOffset () {\n    return this.isValid() ? this._isUTC : false;\n}\n\nfunction isUtc () {\n    return this.isValid() ? this._isUTC && this._offset === 0 : false;\n}\n\n// ASP.NET json date format regex\nvar aspNetRegex = /^(\\-)?(?:(\\d*)[. ])?(\\d+)\\:(\\d+)(?:\\:(\\d+)(\\.\\d*)?)?$/;\n\n// from http://docs.closure-library.googlecode.com/git/closure_goog_date_date.js.source.html\n// somewhat more in line with 4.4.3.2 2004 spec, but allows decimal anywhere\n// and further modified to allow for strings containing both week and day\nvar isoRegex = /^(-)?P(?:(-?[0-9,.]*)Y)?(?:(-?[0-9,.]*)M)?(?:(-?[0-9,.]*)W)?(?:(-?[0-9,.]*)D)?(?:T(?:(-?[0-9,.]*)H)?(?:(-?[0-9,.]*)M)?(?:(-?[0-9,.]*)S)?)?$/;\n\nfunction createDuration (input, key) {\n    var duration = input,\n        // matching against regexp is expensive, do it on demand\n        match = null,\n        sign,\n        ret,\n        diffRes;\n\n    if (isDuration(input)) {\n        duration = {\n            ms : input._milliseconds,\n            d  : input._days,\n            M  : input._months\n        };\n    } else if (isNumber(input)) {\n        duration = {};\n        if (key) {\n            duration[key] = input;\n        } else {\n            duration.milliseconds = input;\n        }\n    } else if (!!(match = aspNetRegex.exec(input))) {\n        sign = (match[1] === '-') ? -1 : 1;\n        duration = {\n            y  : 0,\n            d  : toInt(match[DATE])                         * sign,\n            h  : toInt(match[HOUR])                         * sign,\n            m  : toInt(match[MINUTE])                       * sign,\n            s  : toInt(match[SECOND])                       * sign,\n            ms : toInt(absRound(match[MILLISECOND] * 1000)) * sign // the millisecond decimal point is included in the match\n        };\n    } else if (!!(match = isoRegex.exec(input))) {\n        sign = (match[1] === '-') ? -1 : 1;\n        duration = {\n            y : parseIso(match[2], sign),\n            M : parseIso(match[3], sign),\n            w : parseIso(match[4], sign),\n            d : parseIso(match[5], sign),\n            h : parseIso(match[6], sign),\n            m : parseIso(match[7], sign),\n            s : parseIso(match[8], sign)\n        };\n    } else if (duration == null) {// checks for null or undefined\n        duration = {};\n    } else if (typeof duration === 'object' && ('from' in duration || 'to' in duration)) {\n        diffRes = momentsDifference(createLocal(duration.from), createLocal(duration.to));\n\n        duration = {};\n        duration.ms = diffRes.milliseconds;\n        duration.M = diffRes.months;\n    }\n\n    ret = new Duration(duration);\n\n    if (isDuration(input) && hasOwnProp(input, '_locale')) {\n        ret._locale = input._locale;\n    }\n\n    return ret;\n}\n\ncreateDuration.fn = Duration.prototype;\ncreateDuration.invalid = createInvalid$1;\n\nfunction parseIso (inp, sign) {\n    // We'd normally use ~~inp for this, but unfortunately it also\n    // converts floats to ints.\n    // inp may be undefined, so careful calling replace on it.\n    var res = inp && parseFloat(inp.replace(',', '.'));\n    // apply sign while we're at it\n    return (isNaN(res) ? 0 : res) * sign;\n}\n\nfunction positiveMomentsDifference(base, other) {\n    var res = {milliseconds: 0, months: 0};\n\n    res.months = other.month() - base.month() +\n        (other.year() - base.year()) * 12;\n    if (base.clone().add(res.months, 'M').isAfter(other)) {\n        --res.months;\n    }\n\n    res.milliseconds = +other - +(base.clone().add(res.months, 'M'));\n\n    return res;\n}\n\nfunction momentsDifference(base, other) {\n    var res;\n    if (!(base.isValid() && other.isValid())) {\n        return {milliseconds: 0, months: 0};\n    }\n\n    other = cloneWithOffset(other, base);\n    if (base.isBefore(other)) {\n        res = positiveMomentsDifference(base, other);\n    } else {\n        res = positiveMomentsDifference(other, base);\n        res.milliseconds = -res.milliseconds;\n        res.months = -res.months;\n    }\n\n    return res;\n}\n\n// TODO: remove 'name' arg after deprecation is removed\nfunction createAdder(direction, name) {\n    return function (val, period) {\n        var dur, tmp;\n        //invert the arguments, but complain about it\n        if (period !== null && !isNaN(+period)) {\n            deprecateSimple(name, 'moment().' + name  + '(period, number) is deprecated. Please use moment().' + name + '(number, period). ' +\n            'See http://momentjs.com/guides/#/warnings/add-inverted-param/ for more info.');\n            tmp = val; val = period; period = tmp;\n        }\n\n        val = typeof val === 'string' ? +val : val;\n        dur = createDuration(val, period);\n        addSubtract(this, dur, direction);\n        return this;\n    };\n}\n\nfunction addSubtract (mom, duration, isAdding, updateOffset) {\n    var milliseconds = duration._milliseconds,\n        days = absRound(duration._days),\n        months = absRound(duration._months);\n\n    if (!mom.isValid()) {\n        // No op\n        return;\n    }\n\n    updateOffset = updateOffset == null ? true : updateOffset;\n\n    if (milliseconds) {\n        mom._d.setTime(mom._d.valueOf() + milliseconds * isAdding);\n    }\n    if (days) {\n        set$1(mom, 'Date', get(mom, 'Date') + days * isAdding);\n    }\n    if (months) {\n        setMonth(mom, get(mom, 'Month') + months * isAdding);\n    }\n    if (updateOffset) {\n        hooks.updateOffset(mom, days || months);\n    }\n}\n\nvar add      = createAdder(1, 'add');\nvar subtract = createAdder(-1, 'subtract');\n\nfunction getCalendarFormat(myMoment, now) {\n    var diff = myMoment.diff(now, 'days', true);\n    return diff < -6 ? 'sameElse' :\n            diff < -1 ? 'lastWeek' :\n            diff < 0 ? 'lastDay' :\n            diff < 1 ? 'sameDay' :\n            diff < 2 ? 'nextDay' :\n            diff < 7 ? 'nextWeek' : 'sameElse';\n}\n\nfunction calendar$1 (time, formats) {\n    // We want to compare the start of today, vs this.\n    // Getting start-of-today depends on whether we're local/utc/offset or not.\n    var now = time || createLocal(),\n        sod = cloneWithOffset(now, this).startOf('day'),\n        format = hooks.calendarFormat(this, sod) || 'sameElse';\n\n    var output = formats && (isFunction(formats[format]) ? formats[format].call(this, now) : formats[format]);\n\n    return this.format(output || this.localeData().calendar(format, this, createLocal(now)));\n}\n\nfunction clone () {\n    return new Moment(this);\n}\n\nfunction isAfter (input, units) {\n    var localInput = isMoment(input) ? input : createLocal(input);\n    if (!(this.isValid() && localInput.isValid())) {\n        return false;\n    }\n    units = normalizeUnits(!isUndefined(units) ? units : 'millisecond');\n    if (units === 'millisecond') {\n        return this.valueOf() > localInput.valueOf();\n    } else {\n        return localInput.valueOf() < this.clone().startOf(units).valueOf();\n    }\n}\n\nfunction isBefore (input, units) {\n    var localInput = isMoment(input) ? input : createLocal(input);\n    if (!(this.isValid() && localInput.isValid())) {\n        return false;\n    }\n    units = normalizeUnits(!isUndefined(units) ? units : 'millisecond');\n    if (units === 'millisecond') {\n        return this.valueOf() < localInput.valueOf();\n    } else {\n        return this.clone().endOf(units).valueOf() < localInput.valueOf();\n    }\n}\n\nfunction isBetween (from, to, units, inclusivity) {\n    inclusivity = inclusivity || '()';\n    return (inclusivity[0] === '(' ? this.isAfter(from, units) : !this.isBefore(from, units)) &&\n        (inclusivity[1] === ')' ? this.isBefore(to, units) : !this.isAfter(to, units));\n}\n\nfunction isSame (input, units) {\n    var localInput = isMoment(input) ? input : createLocal(input),\n        inputMs;\n    if (!(this.isValid() && localInput.isValid())) {\n        return false;\n    }\n    units = normalizeUnits(units || 'millisecond');\n    if (units === 'millisecond') {\n        return this.valueOf() === localInput.valueOf();\n    } else {\n        inputMs = localInput.valueOf();\n        return this.clone().startOf(units).valueOf() <= inputMs && inputMs <= this.clone().endOf(units).valueOf();\n    }\n}\n\nfunction isSameOrAfter (input, units) {\n    return this.isSame(input, units) || this.isAfter(input,units);\n}\n\nfunction isSameOrBefore (input, units) {\n    return this.isSame(input, units) || this.isBefore(input,units);\n}\n\nfunction diff (input, units, asFloat) {\n    var that,\n        zoneDelta,\n        delta, output;\n\n    if (!this.isValid()) {\n        return NaN;\n    }\n\n    that = cloneWithOffset(input, this);\n\n    if (!that.isValid()) {\n        return NaN;\n    }\n\n    zoneDelta = (that.utcOffset() - this.utcOffset()) * 6e4;\n\n    units = normalizeUnits(units);\n\n    if (units === 'year' || units === 'month' || units === 'quarter') {\n        output = monthDiff(this, that);\n        if (units === 'quarter') {\n            output = output / 3;\n        } else if (units === 'year') {\n            output = output / 12;\n        }\n    } else {\n        delta = this - that;\n        output = units === 'second' ? delta / 1e3 : // 1000\n            units === 'minute' ? delta / 6e4 : // 1000 * 60\n            units === 'hour' ? delta / 36e5 : // 1000 * 60 * 60\n            units === 'day' ? (delta - zoneDelta) / 864e5 : // 1000 * 60 * 60 * 24, negate dst\n            units === 'week' ? (delta - zoneDelta) / 6048e5 : // 1000 * 60 * 60 * 24 * 7, negate dst\n            delta;\n    }\n    return asFloat ? output : absFloor(output);\n}\n\nfunction monthDiff (a, b) {\n    // difference in months\n    var wholeMonthDiff = ((b.year() - a.year()) * 12) + (b.month() - a.month()),\n        // b is in (anchor - 1 month, anchor + 1 month)\n        anchor = a.clone().add(wholeMonthDiff, 'months'),\n        anchor2, adjust;\n\n    if (b - anchor < 0) {\n        anchor2 = a.clone().add(wholeMonthDiff - 1, 'months');\n        // linear across the month\n        adjust = (b - anchor) / (anchor - anchor2);\n    } else {\n        anchor2 = a.clone().add(wholeMonthDiff + 1, 'months');\n        // linear across the month\n        adjust = (b - anchor) / (anchor2 - anchor);\n    }\n\n    //check for negative zero, return zero if negative zero\n    return -(wholeMonthDiff + adjust) || 0;\n}\n\nhooks.defaultFormat = 'YYYY-MM-DDTHH:mm:ssZ';\nhooks.defaultFormatUtc = 'YYYY-MM-DDTHH:mm:ss[Z]';\n\nfunction toString () {\n    return this.clone().locale('en').format('ddd MMM DD YYYY HH:mm:ss [GMT]ZZ');\n}\n\nfunction toISOString() {\n    if (!this.isValid()) {\n        return null;\n    }\n    var m = this.clone().utc();\n    if (m.year() < 0 || m.year() > 9999) {\n        return formatMoment(m, 'YYYYYY-MM-DD[T]HH:mm:ss.SSS[Z]');\n    }\n    if (isFunction(Date.prototype.toISOString)) {\n        // native implementation is ~50x faster, use it when we can\n        return this.toDate().toISOString();\n    }\n    return formatMoment(m, 'YYYY-MM-DD[T]HH:mm:ss.SSS[Z]');\n}\n\n/**\n * Return a human readable representation of a moment that can\n * also be evaluated to get a new moment which is the same\n *\n * @link https://nodejs.org/dist/latest/docs/api/util.html#util_custom_inspect_function_on_objects\n */\nfunction inspect () {\n    if (!this.isValid()) {\n        return 'moment.invalid(/* ' + this._i + ' */)';\n    }\n    var func = 'moment';\n    var zone = '';\n    if (!this.isLocal()) {\n        func = this.utcOffset() === 0 ? 'moment.utc' : 'moment.parseZone';\n        zone = 'Z';\n    }\n    var prefix = '[' + func + '(\"]';\n    var year = (0 <= this.year() && this.year() <= 9999) ? 'YYYY' : 'YYYYYY';\n    var datetime = '-MM-DD[T]HH:mm:ss.SSS';\n    var suffix = zone + '[\")]';\n\n    return this.format(prefix + year + datetime + suffix);\n}\n\nfunction format (inputString) {\n    if (!inputString) {\n        inputString = this.isUtc() ? hooks.defaultFormatUtc : hooks.defaultFormat;\n    }\n    var output = formatMoment(this, inputString);\n    return this.localeData().postformat(output);\n}\n\nfunction from (time, withoutSuffix) {\n    if (this.isValid() &&\n            ((isMoment(time) && time.isValid()) ||\n             createLocal(time).isValid())) {\n        return createDuration({to: this, from: time}).locale(this.locale()).humanize(!withoutSuffix);\n    } else {\n        return this.localeData().invalidDate();\n    }\n}\n\nfunction fromNow (withoutSuffix) {\n    return this.from(createLocal(), withoutSuffix);\n}\n\nfunction to (time, withoutSuffix) {\n    if (this.isValid() &&\n            ((isMoment(time) && time.isValid()) ||\n             createLocal(time).isValid())) {\n        return createDuration({from: this, to: time}).locale(this.locale()).humanize(!withoutSuffix);\n    } else {\n        return this.localeData().invalidDate();\n    }\n}\n\nfunction toNow (withoutSuffix) {\n    return this.to(createLocal(), withoutSuffix);\n}\n\n// If passed a locale key, it will set the locale for this\n// instance.  Otherwise, it will return the locale configuration\n// variables for this instance.\nfunction locale (key) {\n    var newLocaleData;\n\n    if (key === undefined) {\n        return this._locale._abbr;\n    } else {\n        newLocaleData = getLocale(key);\n        if (newLocaleData != null) {\n            this._locale = newLocaleData;\n        }\n        return this;\n    }\n}\n\nvar lang = deprecate(\n    'moment().lang() is deprecated. Instead, use moment().localeData() to get the language configuration. Use moment().locale() to change languages.',\n    function (key) {\n        if (key === undefined) {\n            return this.localeData();\n        } else {\n            return this.locale(key);\n        }\n    }\n);\n\nfunction localeData () {\n    return this._locale;\n}\n\nfunction startOf (units) {\n    units = normalizeUnits(units);\n    // the following switch intentionally omits break keywords\n    // to utilize falling through the cases.\n    switch (units) {\n        case 'year':\n            this.month(0);\n            /* falls through */\n        case 'quarter':\n        case 'month':\n            this.date(1);\n            /* falls through */\n        case 'week':\n        case 'isoWeek':\n        case 'day':\n        case 'date':\n            this.hours(0);\n            /* falls through */\n        case 'hour':\n            this.minutes(0);\n            /* falls through */\n        case 'minute':\n            this.seconds(0);\n            /* falls through */\n        case 'second':\n            this.milliseconds(0);\n    }\n\n    // weeks are a special case\n    if (units === 'week') {\n        this.weekday(0);\n    }\n    if (units === 'isoWeek') {\n        this.isoWeekday(1);\n    }\n\n    // quarters are also special\n    if (units === 'quarter') {\n        this.month(Math.floor(this.month() / 3) * 3);\n    }\n\n    return this;\n}\n\nfunction endOf (units) {\n    units = normalizeUnits(units);\n    if (units === undefined || units === 'millisecond') {\n        return this;\n    }\n\n    // 'date' is an alias for 'day', so it should be considered as such.\n    if (units === 'date') {\n        units = 'day';\n    }\n\n    return this.startOf(units).add(1, (units === 'isoWeek' ? 'week' : units)).subtract(1, 'ms');\n}\n\nfunction valueOf () {\n    return this._d.valueOf() - ((this._offset || 0) * 60000);\n}\n\nfunction unix () {\n    return Math.floor(this.valueOf() / 1000);\n}\n\nfunction toDate () {\n    return new Date(this.valueOf());\n}\n\nfunction toArray () {\n    var m = this;\n    return [m.year(), m.month(), m.date(), m.hour(), m.minute(), m.second(), m.millisecond()];\n}\n\nfunction toObject () {\n    var m = this;\n    return {\n        years: m.year(),\n        months: m.month(),\n        date: m.date(),\n        hours: m.hours(),\n        minutes: m.minutes(),\n        seconds: m.seconds(),\n        milliseconds: m.milliseconds()\n    };\n}\n\nfunction toJSON () {\n    // new Date(NaN).toJSON() === null\n    return this.isValid() ? this.toISOString() : null;\n}\n\nfunction isValid$2 () {\n    return isValid(this);\n}\n\nfunction parsingFlags () {\n    return extend({}, getParsingFlags(this));\n}\n\nfunction invalidAt () {\n    return getParsingFlags(this).overflow;\n}\n\nfunction creationData() {\n    return {\n        input: this._i,\n        format: this._f,\n        locale: this._locale,\n        isUTC: this._isUTC,\n        strict: this._strict\n    };\n}\n\n// FORMATTING\n\naddFormatToken(0, ['gg', 2], 0, function () {\n    return this.weekYear() % 100;\n});\n\naddFormatToken(0, ['GG', 2], 0, function () {\n    return this.isoWeekYear() % 100;\n});\n\nfunction addWeekYearFormatToken (token, getter) {\n    addFormatToken(0, [token, token.length], 0, getter);\n}\n\naddWeekYearFormatToken('gggg',     'weekYear');\naddWeekYearFormatToken('ggggg',    'weekYear');\naddWeekYearFormatToken('GGGG',  'isoWeekYear');\naddWeekYearFormatToken('GGGGG', 'isoWeekYear');\n\n// ALIASES\n\naddUnitAlias('weekYear', 'gg');\naddUnitAlias('isoWeekYear', 'GG');\n\n// PRIORITY\n\naddUnitPriority('weekYear', 1);\naddUnitPriority('isoWeekYear', 1);\n\n\n// PARSING\n\naddRegexToken('G',      matchSigned);\naddRegexToken('g',      matchSigned);\naddRegexToken('GG',     match1to2, match2);\naddRegexToken('gg',     match1to2, match2);\naddRegexToken('GGGG',   match1to4, match4);\naddRegexToken('gggg',   match1to4, match4);\naddRegexToken('GGGGG',  match1to6, match6);\naddRegexToken('ggggg',  match1to6, match6);\n\naddWeekParseToken(['gggg', 'ggggg', 'GGGG', 'GGGGG'], function (input, week, config, token) {\n    week[token.substr(0, 2)] = toInt(input);\n});\n\naddWeekParseToken(['gg', 'GG'], function (input, week, config, token) {\n    week[token] = hooks.parseTwoDigitYear(input);\n});\n\n// MOMENTS\n\nfunction getSetWeekYear (input) {\n    return getSetWeekYearHelper.call(this,\n            input,\n            this.week(),\n            this.weekday(),\n            this.localeData()._week.dow,\n            this.localeData()._week.doy);\n}\n\nfunction getSetISOWeekYear (input) {\n    return getSetWeekYearHelper.call(this,\n            input, this.isoWeek(), this.isoWeekday(), 1, 4);\n}\n\nfunction getISOWeeksInYear () {\n    return weeksInYear(this.year(), 1, 4);\n}\n\nfunction getWeeksInYear () {\n    var weekInfo = this.localeData()._week;\n    return weeksInYear(this.year(), weekInfo.dow, weekInfo.doy);\n}\n\nfunction getSetWeekYearHelper(input, week, weekday, dow, doy) {\n    var weeksTarget;\n    if (input == null) {\n        return weekOfYear(this, dow, doy).year;\n    } else {\n        weeksTarget = weeksInYear(input, dow, doy);\n        if (week > weeksTarget) {\n            week = weeksTarget;\n        }\n        return setWeekAll.call(this, input, week, weekday, dow, doy);\n    }\n}\n\nfunction setWeekAll(weekYear, week, weekday, dow, doy) {\n    var dayOfYearData = dayOfYearFromWeeks(weekYear, week, weekday, dow, doy),\n        date = createUTCDate(dayOfYearData.year, 0, dayOfYearData.dayOfYear);\n\n    this.year(date.getUTCFullYear());\n    this.month(date.getUTCMonth());\n    this.date(date.getUTCDate());\n    return this;\n}\n\n// FORMATTING\n\naddFormatToken('Q', 0, 'Qo', 'quarter');\n\n// ALIASES\n\naddUnitAlias('quarter', 'Q');\n\n// PRIORITY\n\naddUnitPriority('quarter', 7);\n\n// PARSING\n\naddRegexToken('Q', match1);\naddParseToken('Q', function (input, array) {\n    array[MONTH] = (toInt(input) - 1) * 3;\n});\n\n// MOMENTS\n\nfunction getSetQuarter (input) {\n    return input == null ? Math.ceil((this.month() + 1) / 3) : this.month((input - 1) * 3 + this.month() % 3);\n}\n\n// FORMATTING\n\naddFormatToken('D', ['DD', 2], 'Do', 'date');\n\n// ALIASES\n\naddUnitAlias('date', 'D');\n\n// PRIOROITY\naddUnitPriority('date', 9);\n\n// PARSING\n\naddRegexToken('D',  match1to2);\naddRegexToken('DD', match1to2, match2);\naddRegexToken('Do', function (isStrict, locale) {\n    // TODO: Remove \"ordinalParse\" fallback in next major release.\n    return isStrict ?\n      (locale._dayOfMonthOrdinalParse || locale._ordinalParse) :\n      locale._dayOfMonthOrdinalParseLenient;\n});\n\naddParseToken(['D', 'DD'], DATE);\naddParseToken('Do', function (input, array) {\n    array[DATE] = toInt(input.match(match1to2)[0], 10);\n});\n\n// MOMENTS\n\nvar getSetDayOfMonth = makeGetSet('Date', true);\n\n// FORMATTING\n\naddFormatToken('DDD', ['DDDD', 3], 'DDDo', 'dayOfYear');\n\n// ALIASES\n\naddUnitAlias('dayOfYear', 'DDD');\n\n// PRIORITY\naddUnitPriority('dayOfYear', 4);\n\n// PARSING\n\naddRegexToken('DDD',  match1to3);\naddRegexToken('DDDD', match3);\naddParseToken(['DDD', 'DDDD'], function (input, array, config) {\n    config._dayOfYear = toInt(input);\n});\n\n// HELPERS\n\n// MOMENTS\n\nfunction getSetDayOfYear (input) {\n    var dayOfYear = Math.round((this.clone().startOf('day') - this.clone().startOf('year')) / 864e5) + 1;\n    return input == null ? dayOfYear : this.add((input - dayOfYear), 'd');\n}\n\n// FORMATTING\n\naddFormatToken('m', ['mm', 2], 0, 'minute');\n\n// ALIASES\n\naddUnitAlias('minute', 'm');\n\n// PRIORITY\n\naddUnitPriority('minute', 14);\n\n// PARSING\n\naddRegexToken('m',  match1to2);\naddRegexToken('mm', match1to2, match2);\naddParseToken(['m', 'mm'], MINUTE);\n\n// MOMENTS\n\nvar getSetMinute = makeGetSet('Minutes', false);\n\n// FORMATTING\n\naddFormatToken('s', ['ss', 2], 0, 'second');\n\n// ALIASES\n\naddUnitAlias('second', 's');\n\n// PRIORITY\n\naddUnitPriority('second', 15);\n\n// PARSING\n\naddRegexToken('s',  match1to2);\naddRegexToken('ss', match1to2, match2);\naddParseToken(['s', 'ss'], SECOND);\n\n// MOMENTS\n\nvar getSetSecond = makeGetSet('Seconds', false);\n\n// FORMATTING\n\naddFormatToken('S', 0, 0, function () {\n    return ~~(this.millisecond() / 100);\n});\n\naddFormatToken(0, ['SS', 2], 0, function () {\n    return ~~(this.millisecond() / 10);\n});\n\naddFormatToken(0, ['SSS', 3], 0, 'millisecond');\naddFormatToken(0, ['SSSS', 4], 0, function () {\n    return this.millisecond() * 10;\n});\naddFormatToken(0, ['SSSSS', 5], 0, function () {\n    return this.millisecond() * 100;\n});\naddFormatToken(0, ['SSSSSS', 6], 0, function () {\n    return this.millisecond() * 1000;\n});\naddFormatToken(0, ['SSSSSSS', 7], 0, function () {\n    return this.millisecond() * 10000;\n});\naddFormatToken(0, ['SSSSSSSS', 8], 0, function () {\n    return this.millisecond() * 100000;\n});\naddFormatToken(0, ['SSSSSSSSS', 9], 0, function () {\n    return this.millisecond() * 1000000;\n});\n\n\n// ALIASES\n\naddUnitAlias('millisecond', 'ms');\n\n// PRIORITY\n\naddUnitPriority('millisecond', 16);\n\n// PARSING\n\naddRegexToken('S',    match1to3, match1);\naddRegexToken('SS',   match1to3, match2);\naddRegexToken('SSS',  match1to3, match3);\n\nvar token;\nfor (token = 'SSSS'; token.length <= 9; token += 'S') {\n    addRegexToken(token, matchUnsigned);\n}\n\nfunction parseMs(input, array) {\n    array[MILLISECOND] = toInt(('0.' + input) * 1000);\n}\n\nfor (token = 'S'; token.length <= 9; token += 'S') {\n    addParseToken(token, parseMs);\n}\n// MOMENTS\n\nvar getSetMillisecond = makeGetSet('Milliseconds', false);\n\n// FORMATTING\n\naddFormatToken('z',  0, 0, 'zoneAbbr');\naddFormatToken('zz', 0, 0, 'zoneName');\n\n// MOMENTS\n\nfunction getZoneAbbr () {\n    return this._isUTC ? 'UTC' : '';\n}\n\nfunction getZoneName () {\n    return this._isUTC ? 'Coordinated Universal Time' : '';\n}\n\nvar proto = Moment.prototype;\n\nproto.add               = add;\nproto.calendar          = calendar$1;\nproto.clone             = clone;\nproto.diff              = diff;\nproto.endOf             = endOf;\nproto.format            = format;\nproto.from              = from;\nproto.fromNow           = fromNow;\nproto.to                = to;\nproto.toNow             = toNow;\nproto.get               = stringGet;\nproto.invalidAt         = invalidAt;\nproto.isAfter           = isAfter;\nproto.isBefore          = isBefore;\nproto.isBetween         = isBetween;\nproto.isSame            = isSame;\nproto.isSameOrAfter     = isSameOrAfter;\nproto.isSameOrBefore    = isSameOrBefore;\nproto.isValid           = isValid$2;\nproto.lang              = lang;\nproto.locale            = locale;\nproto.localeData        = localeData;\nproto.max               = prototypeMax;\nproto.min               = prototypeMin;\nproto.parsingFlags      = parsingFlags;\nproto.set               = stringSet;\nproto.startOf           = startOf;\nproto.subtract          = subtract;\nproto.toArray           = toArray;\nproto.toObject          = toObject;\nproto.toDate            = toDate;\nproto.toISOString       = toISOString;\nproto.inspect           = inspect;\nproto.toJSON            = toJSON;\nproto.toString          = toString;\nproto.unix              = unix;\nproto.valueOf           = valueOf;\nproto.creationData      = creationData;\n\n// Year\nproto.year       = getSetYear;\nproto.isLeapYear = getIsLeapYear;\n\n// Week Year\nproto.weekYear    = getSetWeekYear;\nproto.isoWeekYear = getSetISOWeekYear;\n\n// Quarter\nproto.quarter = proto.quarters = getSetQuarter;\n\n// Month\nproto.month       = getSetMonth;\nproto.daysInMonth = getDaysInMonth;\n\n// Week\nproto.week           = proto.weeks        = getSetWeek;\nproto.isoWeek        = proto.isoWeeks     = getSetISOWeek;\nproto.weeksInYear    = getWeeksInYear;\nproto.isoWeeksInYear = getISOWeeksInYear;\n\n// Day\nproto.date       = getSetDayOfMonth;\nproto.day        = proto.days             = getSetDayOfWeek;\nproto.weekday    = getSetLocaleDayOfWeek;\nproto.isoWeekday = getSetISODayOfWeek;\nproto.dayOfYear  = getSetDayOfYear;\n\n// Hour\nproto.hour = proto.hours = getSetHour;\n\n// Minute\nproto.minute = proto.minutes = getSetMinute;\n\n// Second\nproto.second = proto.seconds = getSetSecond;\n\n// Millisecond\nproto.millisecond = proto.milliseconds = getSetMillisecond;\n\n// Offset\nproto.utcOffset            = getSetOffset;\nproto.utc                  = setOffsetToUTC;\nproto.local                = setOffsetToLocal;\nproto.parseZone            = setOffsetToParsedOffset;\nproto.hasAlignedHourOffset = hasAlignedHourOffset;\nproto.isDST                = isDaylightSavingTime;\nproto.isLocal              = isLocal;\nproto.isUtcOffset          = isUtcOffset;\nproto.isUtc                = isUtc;\nproto.isUTC                = isUtc;\n\n// Timezone\nproto.zoneAbbr = getZoneAbbr;\nproto.zoneName = getZoneName;\n\n// Deprecations\nproto.dates  = deprecate('dates accessor is deprecated. Use date instead.', getSetDayOfMonth);\nproto.months = deprecate('months accessor is deprecated. Use month instead', getSetMonth);\nproto.years  = deprecate('years accessor is deprecated. Use year instead', getSetYear);\nproto.zone   = deprecate('moment().zone is deprecated, use moment().utcOffset instead. http://momentjs.com/guides/#/warnings/zone/', getSetZone);\nproto.isDSTShifted = deprecate('isDSTShifted is deprecated. See http://momentjs.com/guides/#/warnings/dst-shifted/ for more information', isDaylightSavingTimeShifted);\n\nfunction createUnix (input) {\n    return createLocal(input * 1000);\n}\n\nfunction createInZone () {\n    return createLocal.apply(null, arguments).parseZone();\n}\n\nfunction preParsePostFormat (string) {\n    return string;\n}\n\nvar proto$1 = Locale.prototype;\n\nproto$1.calendar        = calendar;\nproto$1.longDateFormat  = longDateFormat;\nproto$1.invalidDate     = invalidDate;\nproto$1.ordinal         = ordinal;\nproto$1.preparse        = preParsePostFormat;\nproto$1.postformat      = preParsePostFormat;\nproto$1.relativeTime    = relativeTime;\nproto$1.pastFuture      = pastFuture;\nproto$1.set             = set;\n\n// Month\nproto$1.months            =        localeMonths;\nproto$1.monthsShort       =        localeMonthsShort;\nproto$1.monthsParse       =        localeMonthsParse;\nproto$1.monthsRegex       = monthsRegex;\nproto$1.monthsShortRegex  = monthsShortRegex;\n\n// Week\nproto$1.week = localeWeek;\nproto$1.firstDayOfYear = localeFirstDayOfYear;\nproto$1.firstDayOfWeek = localeFirstDayOfWeek;\n\n// Day of Week\nproto$1.weekdays       =        localeWeekdays;\nproto$1.weekdaysMin    =        localeWeekdaysMin;\nproto$1.weekdaysShort  =        localeWeekdaysShort;\nproto$1.weekdaysParse  =        localeWeekdaysParse;\n\nproto$1.weekdaysRegex       =        weekdaysRegex;\nproto$1.weekdaysShortRegex  =        weekdaysShortRegex;\nproto$1.weekdaysMinRegex    =        weekdaysMinRegex;\n\n// Hours\nproto$1.isPM = localeIsPM;\nproto$1.meridiem = localeMeridiem;\n\nfunction get$1 (format, index, field, setter) {\n    var locale = getLocale();\n    var utc = createUTC().set(setter, index);\n    return locale[field](utc, format);\n}\n\nfunction listMonthsImpl (format, index, field) {\n    if (isNumber(format)) {\n        index = format;\n        format = undefined;\n    }\n\n    format = format || '';\n\n    if (index != null) {\n        return get$1(format, index, field, 'month');\n    }\n\n    var i;\n    var out = [];\n    for (i = 0; i < 12; i++) {\n        out[i] = get$1(format, i, field, 'month');\n    }\n    return out;\n}\n\n// ()\n// (5)\n// (fmt, 5)\n// (fmt)\n// (true)\n// (true, 5)\n// (true, fmt, 5)\n// (true, fmt)\nfunction listWeekdaysImpl (localeSorted, format, index, field) {\n    if (typeof localeSorted === 'boolean') {\n        if (isNumber(format)) {\n            index = format;\n            format = undefined;\n        }\n\n        format = format || '';\n    } else {\n        format = localeSorted;\n        index = format;\n        localeSorted = false;\n\n        if (isNumber(format)) {\n            index = format;\n            format = undefined;\n        }\n\n        format = format || '';\n    }\n\n    var locale = getLocale(),\n        shift = localeSorted ? locale._week.dow : 0;\n\n    if (index != null) {\n        return get$1(format, (index + shift) % 7, field, 'day');\n    }\n\n    var i;\n    var out = [];\n    for (i = 0; i < 7; i++) {\n        out[i] = get$1(format, (i + shift) % 7, field, 'day');\n    }\n    return out;\n}\n\nfunction listMonths (format, index) {\n    return listMonthsImpl(format, index, 'months');\n}\n\nfunction listMonthsShort (format, index) {\n    return listMonthsImpl(format, index, 'monthsShort');\n}\n\nfunction listWeekdays (localeSorted, format, index) {\n    return listWeekdaysImpl(localeSorted, format, index, 'weekdays');\n}\n\nfunction listWeekdaysShort (localeSorted, format, index) {\n    return listWeekdaysImpl(localeSorted, format, index, 'weekdaysShort');\n}\n\nfunction listWeekdaysMin (localeSorted, format, index) {\n    return listWeekdaysImpl(localeSorted, format, index, 'weekdaysMin');\n}\n\ngetSetGlobalLocale('en', {\n    dayOfMonthOrdinalParse: /\\d{1,2}(th|st|nd|rd)/,\n    ordinal : function (number) {\n        var b = number % 10,\n            output = (toInt(number % 100 / 10) === 1) ? 'th' :\n            (b === 1) ? 'st' :\n            (b === 2) ? 'nd' :\n            (b === 3) ? 'rd' : 'th';\n        return number + output;\n    }\n});\n\n// Side effect imports\nhooks.lang = deprecate('moment.lang is deprecated. Use moment.locale instead.', getSetGlobalLocale);\nhooks.langData = deprecate('moment.langData is deprecated. Use moment.localeData instead.', getLocale);\n\nvar mathAbs = Math.abs;\n\nfunction abs () {\n    var data           = this._data;\n\n    this._milliseconds = mathAbs(this._milliseconds);\n    this._days         = mathAbs(this._days);\n    this._months       = mathAbs(this._months);\n\n    data.milliseconds  = mathAbs(data.milliseconds);\n    data.seconds       = mathAbs(data.seconds);\n    data.minutes       = mathAbs(data.minutes);\n    data.hours         = mathAbs(data.hours);\n    data.months        = mathAbs(data.months);\n    data.years         = mathAbs(data.years);\n\n    return this;\n}\n\nfunction addSubtract$1 (duration, input, value, direction) {\n    var other = createDuration(input, value);\n\n    duration._milliseconds += direction * other._milliseconds;\n    duration._days         += direction * other._days;\n    duration._months       += direction * other._months;\n\n    return duration._bubble();\n}\n\n// supports only 2.0-style add(1, 's') or add(duration)\nfunction add$1 (input, value) {\n    return addSubtract$1(this, input, value, 1);\n}\n\n// supports only 2.0-style subtract(1, 's') or subtract(duration)\nfunction subtract$1 (input, value) {\n    return addSubtract$1(this, input, value, -1);\n}\n\nfunction absCeil (number) {\n    if (number < 0) {\n        return Math.floor(number);\n    } else {\n        return Math.ceil(number);\n    }\n}\n\nfunction bubble () {\n    var milliseconds = this._milliseconds;\n    var days         = this._days;\n    var months       = this._months;\n    var data         = this._data;\n    var seconds, minutes, hours, years, monthsFromDays;\n\n    // if we have a mix of positive and negative values, bubble down first\n    // check: https://github.com/moment/moment/issues/2166\n    if (!((milliseconds >= 0 && days >= 0 && months >= 0) ||\n            (milliseconds <= 0 && days <= 0 && months <= 0))) {\n        milliseconds += absCeil(monthsToDays(months) + days) * 864e5;\n        days = 0;\n        months = 0;\n    }\n\n    // The following code bubbles up values, see the tests for\n    // examples of what that means.\n    data.milliseconds = milliseconds % 1000;\n\n    seconds           = absFloor(milliseconds / 1000);\n    data.seconds      = seconds % 60;\n\n    minutes           = absFloor(seconds / 60);\n    data.minutes      = minutes % 60;\n\n    hours             = absFloor(minutes / 60);\n    data.hours        = hours % 24;\n\n    days += absFloor(hours / 24);\n\n    // convert days to months\n    monthsFromDays = absFloor(daysToMonths(days));\n    months += monthsFromDays;\n    days -= absCeil(monthsToDays(monthsFromDays));\n\n    // 12 months -> 1 year\n    years = absFloor(months / 12);\n    months %= 12;\n\n    data.days   = days;\n    data.months = months;\n    data.years  = years;\n\n    return this;\n}\n\nfunction daysToMonths (days) {\n    // 400 years have 146097 days (taking into account leap year rules)\n    // 400 years have 12 months === 4800\n    return days * 4800 / 146097;\n}\n\nfunction monthsToDays (months) {\n    // the reverse of daysToMonths\n    return months * 146097 / 4800;\n}\n\nfunction as (units) {\n    if (!this.isValid()) {\n        return NaN;\n    }\n    var days;\n    var months;\n    var milliseconds = this._milliseconds;\n\n    units = normalizeUnits(units);\n\n    if (units === 'month' || units === 'year') {\n        days   = this._days   + milliseconds / 864e5;\n        months = this._months + daysToMonths(days);\n        return units === 'month' ? months : months / 12;\n    } else {\n        // handle milliseconds separately because of floating point math errors (issue #1867)\n        days = this._days + Math.round(monthsToDays(this._months));\n        switch (units) {\n            case 'week'   : return days / 7     + milliseconds / 6048e5;\n            case 'day'    : return days         + milliseconds / 864e5;\n            case 'hour'   : return days * 24    + milliseconds / 36e5;\n            case 'minute' : return days * 1440  + milliseconds / 6e4;\n            case 'second' : return days * 86400 + milliseconds / 1000;\n            // Math.floor prevents floating point math errors here\n            case 'millisecond': return Math.floor(days * 864e5) + milliseconds;\n            default: throw new Error('Unknown unit ' + units);\n        }\n    }\n}\n\n// TODO: Use this.as('ms')?\nfunction valueOf$1 () {\n    if (!this.isValid()) {\n        return NaN;\n    }\n    return (\n        this._milliseconds +\n        this._days * 864e5 +\n        (this._months % 12) * 2592e6 +\n        toInt(this._months / 12) * 31536e6\n    );\n}\n\nfunction makeAs (alias) {\n    return function () {\n        return this.as(alias);\n    };\n}\n\nvar asMilliseconds = makeAs('ms');\nvar asSeconds      = makeAs('s');\nvar asMinutes      = makeAs('m');\nvar asHours        = makeAs('h');\nvar asDays         = makeAs('d');\nvar asWeeks        = makeAs('w');\nvar asMonths       = makeAs('M');\nvar asYears        = makeAs('y');\n\nfunction get$2 (units) {\n    units = normalizeUnits(units);\n    return this.isValid() ? this[units + 's']() : NaN;\n}\n\nfunction makeGetter(name) {\n    return function () {\n        return this.isValid() ? this._data[name] : NaN;\n    };\n}\n\nvar milliseconds = makeGetter('milliseconds');\nvar seconds      = makeGetter('seconds');\nvar minutes      = makeGetter('minutes');\nvar hours        = makeGetter('hours');\nvar days         = makeGetter('days');\nvar months       = makeGetter('months');\nvar years        = makeGetter('years');\n\nfunction weeks () {\n    return absFloor(this.days() / 7);\n}\n\nvar round = Math.round;\nvar thresholds = {\n    ss: 44,         // a few seconds to seconds\n    s : 45,         // seconds to minute\n    m : 45,         // minutes to hour\n    h : 22,         // hours to day\n    d : 26,         // days to month\n    M : 11          // months to year\n};\n\n// helper function for moment.fn.from, moment.fn.fromNow, and moment.duration.fn.humanize\nfunction substituteTimeAgo(string, number, withoutSuffix, isFuture, locale) {\n    return locale.relativeTime(number || 1, !!withoutSuffix, string, isFuture);\n}\n\nfunction relativeTime$1 (posNegDuration, withoutSuffix, locale) {\n    var duration = createDuration(posNegDuration).abs();\n    var seconds  = round(duration.as('s'));\n    var minutes  = round(duration.as('m'));\n    var hours    = round(duration.as('h'));\n    var days     = round(duration.as('d'));\n    var months   = round(duration.as('M'));\n    var years    = round(duration.as('y'));\n\n    var a = seconds <= thresholds.ss && ['s', seconds]  ||\n            seconds < thresholds.s   && ['ss', seconds] ||\n            minutes <= 1             && ['m']           ||\n            minutes < thresholds.m   && ['mm', minutes] ||\n            hours   <= 1             && ['h']           ||\n            hours   < thresholds.h   && ['hh', hours]   ||\n            days    <= 1             && ['d']           ||\n            days    < thresholds.d   && ['dd', days]    ||\n            months  <= 1             && ['M']           ||\n            months  < thresholds.M   && ['MM', months]  ||\n            years   <= 1             && ['y']           || ['yy', years];\n\n    a[2] = withoutSuffix;\n    a[3] = +posNegDuration > 0;\n    a[4] = locale;\n    return substituteTimeAgo.apply(null, a);\n}\n\n// This function allows you to set the rounding function for relative time strings\nfunction getSetRelativeTimeRounding (roundingFunction) {\n    if (roundingFunction === undefined) {\n        return round;\n    }\n    if (typeof(roundingFunction) === 'function') {\n        round = roundingFunction;\n        return true;\n    }\n    return false;\n}\n\n// This function allows you to set a threshold for relative time strings\nfunction getSetRelativeTimeThreshold (threshold, limit) {\n    if (thresholds[threshold] === undefined) {\n        return false;\n    }\n    if (limit === undefined) {\n        return thresholds[threshold];\n    }\n    thresholds[threshold] = limit;\n    if (threshold === 's') {\n        thresholds.ss = limit - 1;\n    }\n    return true;\n}\n\nfunction humanize (withSuffix) {\n    if (!this.isValid()) {\n        return this.localeData().invalidDate();\n    }\n\n    var locale = this.localeData();\n    var output = relativeTime$1(this, !withSuffix, locale);\n\n    if (withSuffix) {\n        output = locale.pastFuture(+this, output);\n    }\n\n    return locale.postformat(output);\n}\n\nvar abs$1 = Math.abs;\n\nfunction toISOString$1() {\n    // for ISO strings we do not use the normal bubbling rules:\n    //  * milliseconds bubble up until they become hours\n    //  * days do not bubble at all\n    //  * months bubble up until they become years\n    // This is because there is no context-free conversion between hours and days\n    // (think of clock changes)\n    // and also not between days and months (28-31 days per month)\n    if (!this.isValid()) {\n        return this.localeData().invalidDate();\n    }\n\n    var seconds = abs$1(this._milliseconds) / 1000;\n    var days         = abs$1(this._days);\n    var months       = abs$1(this._months);\n    var minutes, hours, years;\n\n    // 3600 seconds -> 60 minutes -> 1 hour\n    minutes           = absFloor(seconds / 60);\n    hours             = absFloor(minutes / 60);\n    seconds %= 60;\n    minutes %= 60;\n\n    // 12 months -> 1 year\n    years  = absFloor(months / 12);\n    months %= 12;\n\n\n    // inspired by https://github.com/dordille/moment-isoduration/blob/master/moment.isoduration.js\n    var Y = years;\n    var M = months;\n    var D = days;\n    var h = hours;\n    var m = minutes;\n    var s = seconds;\n    var total = this.asSeconds();\n\n    if (!total) {\n        // this is the same as C#'s (Noda) and python (isodate)...\n        // but not other JS (goog.date)\n        return 'P0D';\n    }\n\n    return (total < 0 ? '-' : '') +\n        'P' +\n        (Y ? Y + 'Y' : '') +\n        (M ? M + 'M' : '') +\n        (D ? D + 'D' : '') +\n        ((h || m || s) ? 'T' : '') +\n        (h ? h + 'H' : '') +\n        (m ? m + 'M' : '') +\n        (s ? s + 'S' : '');\n}\n\nvar proto$2 = Duration.prototype;\n\nproto$2.isValid        = isValid$1;\nproto$2.abs            = abs;\nproto$2.add            = add$1;\nproto$2.subtract       = subtract$1;\nproto$2.as             = as;\nproto$2.asMilliseconds = asMilliseconds;\nproto$2.asSeconds      = asSeconds;\nproto$2.asMinutes      = asMinutes;\nproto$2.asHours        = asHours;\nproto$2.asDays         = asDays;\nproto$2.asWeeks        = asWeeks;\nproto$2.asMonths       = asMonths;\nproto$2.asYears        = asYears;\nproto$2.valueOf        = valueOf$1;\nproto$2._bubble        = bubble;\nproto$2.get            = get$2;\nproto$2.milliseconds   = milliseconds;\nproto$2.seconds        = seconds;\nproto$2.minutes        = minutes;\nproto$2.hours          = hours;\nproto$2.days           = days;\nproto$2.weeks          = weeks;\nproto$2.months         = months;\nproto$2.years          = years;\nproto$2.humanize       = humanize;\nproto$2.toISOString    = toISOString$1;\nproto$2.toString       = toISOString$1;\nproto$2.toJSON         = toISOString$1;\nproto$2.locale         = locale;\nproto$2.localeData     = localeData;\n\n// Deprecations\nproto$2.toIsoString = deprecate('toIsoString() is deprecated. Please use toISOString() instead (notice the capitals)', toISOString$1);\nproto$2.lang = lang;\n\n// Side effect imports\n\n// FORMATTING\n\naddFormatToken('X', 0, 0, 'unix');\naddFormatToken('x', 0, 0, 'valueOf');\n\n// PARSING\n\naddRegexToken('x', matchSigned);\naddRegexToken('X', matchTimestamp);\naddParseToken('X', function (input, array, config) {\n    config._d = new Date(parseFloat(input, 10) * 1000);\n});\naddParseToken('x', function (input, array, config) {\n    config._d = new Date(toInt(input));\n});\n\n// Side effect imports\n\n\nhooks.version = '2.18.1';\n\nsetHookCallback(createLocal);\n\nhooks.fn                    = proto;\nhooks.min                   = min;\nhooks.max                   = max;\nhooks.now                   = now;\nhooks.utc                   = createUTC;\nhooks.unix                  = createUnix;\nhooks.months                = listMonths;\nhooks.isDate                = isDate;\nhooks.locale                = getSetGlobalLocale;\nhooks.invalid               = createInvalid;\nhooks.duration              = createDuration;\nhooks.isMoment              = isMoment;\nhooks.weekdays              = listWeekdays;\nhooks.parseZone             = createInZone;\nhooks.localeData            = getLocale;\nhooks.isDuration            = isDuration;\nhooks.monthsShort           = listMonthsShort;\nhooks.weekdaysMin           = listWeekdaysMin;\nhooks.defineLocale          = defineLocale;\nhooks.updateLocale          = updateLocale;\nhooks.locales               = listLocales;\nhooks.weekdaysShort         = listWeekdaysShort;\nhooks.normalizeUnits        = normalizeUnits;\nhooks.relativeTimeRounding = getSetRelativeTimeRounding;\nhooks.relativeTimeThreshold = getSetRelativeTimeThreshold;\nhooks.calendarFormat        = getCalendarFormat;\nhooks.prototype             = proto;\n\nreturn hooks;\n\n})));\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/package.js",
    "content": "var profile = {\n    resourceTags: {\n        ignore: function(filename, mid){\n            // only include moment/moment\n            return mid != \"moment/moment\";\n        },\n        amd: function(filename, mid){\n            return /\\.js$/.test(filename);\n        }\n    }\n};\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/package.json",
    "content": "{\n    \"name\": \"moment\",\n    \"version\": \"2.18.1\",\n    \"description\": \"Parse, validate, manipulate, and display dates\",\n    \"homepage\": \"http://momentjs.com\",\n    \"author\": \"Iskren Ivov Chernev <iskren.chernev@gmail.com> (https://github.com/ichernev)\",\n    \"contributors\": [\n        \"Tim Wood <washwithcare@gmail.com> (http://timwoodcreates.com/)\",\n        \"Rocky Meza (http://rockymeza.com)\",\n        \"Matt Johnson <mj1856@hotmail.com> (http://codeofmatt.com)\",\n        \"Isaac Cambron <isaac@isaaccambron.com> (http://isaaccambron.com)\",\n        \"Andre Polykanine <andre@oire.org> (https://github.com/oire)\"\n    ],\n    \"keywords\": [\n        \"moment\",\n        \"date\",\n        \"time\",\n        \"parse\",\n        \"format\",\n        \"validate\",\n        \"i18n\",\n        \"l10n\",\n        \"ender\"\n    ],\n    \"main\": \"./moment.js\",\n    \"jsnext:main\": \"./src/moment.js\",\n    \"typings\": \"./moment.d.ts\",\n    \"engines\": {\n        \"node\": \"*\"\n    },\n    \"repository\": {\n        \"type\": \"git\",\n        \"url\": \"https://github.com/moment/moment.git\"\n    },\n    \"bugs\": {\n        \"url\": \"https://github.com/moment/moment/issues\"\n    },\n    \"license\": \"MIT\",\n    \"devDependencies\": {\n        \"uglify-js\": \"latest\",\n        \"es6-promise\": \"latest\",\n        \"grunt\": \"~0.4\",\n        \"grunt-cli\": \"latest\",\n        \"benchmark\": \"latest\",\n        \"grunt-contrib-clean\": \"latest\",\n        \"grunt-contrib-concat\": \"latest\",\n        \"grunt-contrib-copy\": \"latest\",\n        \"grunt-contrib-jshint\": \"latest\",\n        \"grunt-contrib-uglify\": \"latest\",\n        \"grunt-contrib-watch\": \"latest\",\n        \"grunt-env\": \"latest\",\n        \"grunt-jscs\": \"latest\",\n        \"grunt-karma\": \"latest\",\n        \"grunt-nuget\": \"latest\",\n        \"grunt-benchmark\": \"latest\",\n        \"grunt-string-replace\": \"latest\",\n        \"grunt-exec\": \"latest\",\n        \"load-grunt-tasks\": \"latest\",\n        \"karma\": \"latest\",\n        \"karma-chrome-launcher\": \"latest\",\n        \"karma-firefox-launcher\": \"latest\",\n        \"karma-qunit\": \"latest\",\n        \"karma-sauce-launcher\": \"latest\",\n        \"qunit\": \"^0.7.5\",\n        \"qunit-cli\": \"^0.1.4\",\n        \"rollup\": \"latest\",\n        \"spacejam\": \"latest\",\n        \"typescript\": \"^1.8.10\",\n        \"coveralls\": \"^2.11.2\",\n        \"nyc\": \"^2.1.4\"\n    },\n    \"ender\": \"./ender.js\",\n    \"dojoBuild\": \"package.js\",\n    \"jspm\": {\n        \"files\": [\n            \"moment.js\",\n            \"moment.d.ts\",\n            \"locale\"\n        ],\n        \"map\": {\n            \"moment\": \"./moment\"\n        },\n        \"buildConfig\": {\n            \"uglify\": true\n        }\n    },\n    \"scripts\": {\n        \"typescript-test\": \"tsc --project typing-tests\",\n        \"test\": \"grunt test\",\n        \"coverage\": \"nyc npm test && nyc report\",\n        \"coveralls\": \"nyc npm test && nyc report --reporter=text-lcov | coveralls\"\n    },\n    \"spm\": {\n        \"main\": \"moment.js\",\n        \"output\": [\n            \"locale/*.js\"\n        ]\n    }\n}\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/scripts/locales.js",
    "content": "var fs = require('fs'),\n    path = require('path'),\n    https = require('https');\n\nvar localeDir = path.join('src', 'locale');\n\nvar args = process.argv.slice(2);\n\nfunction help() {\n    console.log(process.argv[1], '[list|mention|find-commenters] ARGS');\n    console.log();\n    console.log('    list      show all authors in all locales');\n    console.log('    mention   show all authors in all locales, ready to copy-paste in github issue');\n    console.log('    find-commenters #ID  finds all people that participated in a github conversation');\n}\n\nfunction extract() {\n    var authors = {};\n    fs.readdirSync(localeDir).forEach(function (locale) {\n        var content = fs.readFileSync(path.join(localeDir, locale), {encoding: 'utf-8'}),\n            localeCode = locale.split('.')[0],\n            localeAuthors = [];\n        content.split('\\n').forEach(function (line) {\n            var match = line.match(/^\\/\\/! author.*github[.]com\\/(.*)$/);\n            if (match !== null) {\n                // console.log(\"  \", line);\n                localeAuthors.push(match[1]);\n            }\n        });\n        if (localeAuthors.length === 0) {\n            // use to debug\n            content.split('\\n').forEach(function (line) {\n                var match = line.match(/^\\/\\/! author(.*)$/);\n                if (match !== null) {\n                    localeAuthors.push('---' + match[1]);\n                }\n            });\n            console.log(localeCode, localeAuthors);\n        } else {\n            authors[localeCode] = localeAuthors;\n        }\n    });\n    return authors;\n}\n\nfunction list() {\n    var authors = extract();\n    Object.keys(authors).forEach(function (localeCode) {\n        console.log(localeCode, authors[localeCode]);\n    });\n}\n\nfunction mention() {\n    var authors = extract();\n    Object.keys(authors).forEach(function (localeCode) {\n        console.log('- [ ]', localeCode, authors[localeCode].map(function (author) { return '@' + author; }).join(' '));\n    });\n}\n\nfunction findCommenters(postId) {\n\n    function fetchComments(page, callback) {\n        var options = {\n                hostname: 'api.github.com',\n                port: 443,\n                path: '/repos/moment/moment/issues/' + postId + '/comments?page=' + page,\n                method: 'GET',\n                headers: {\n                    'User-Agent': 'node script'\n                }\n            },\n            links = {};\n        console.log('fetching', options.path);\n        https.get(options, function (res) {\n            if ('link' in res.headers) {\n                res.headers.link.split(', ').forEach(function(linkStr) {\n                    var pieces = linkStr.split('; ');\n                    var key = pieces[1].split('=')[1];\n                    var link = pieces[0];\n                    key = key.substr(1, key.length - 2);\n                    link = link.substr(1, link.length - 2);\n                    links[key] = link;\n                });\n            }\n            var bodyChunks = [], body;\n            res.on('data', function (chunk) {\n                bodyChunks.push(chunk);\n            });\n            res.on('end', function () {\n                body = bodyChunks.join('');\n                callback(page, JSON.parse(body), links);\n            });\n        });\n    }\n\n    var commenters = {};\n    var maxPage = 1;\n    fetchComments(1, function (page, body, links) {\n        handleBody(body, page);\n        if ('last' in links) {\n            maxPage = parseInt(links.last.split('=')[1], 10);\n        }\n        var pagesLeft = maxPage - 1;\n        for (var p = 2; p <= maxPage; p += 1) {\n            fetchComments(p, function (page, body, links) {\n                handleBody(body, page);\n                pagesLeft -= 1;\n                if (pagesLeft === 0) {\n                    handleCommenters(Object.keys(commenters));\n                }\n            });\n        }\n    });\n\n    function handleBody(body, page) {\n        body.forEach(function (comment) {\n            console.log(page, comment.user.login);\n            commenters[comment.user.login] = 1;\n        });\n    }\n\n    function handleCommenters(commenters) {\n        console.log('len of commenters', commenters.length);\n        console.log(commenters);\n    }\n}\n\nif (args.length === 0) {\n    help();\n    process.exit(0);\n}\n\nswitch (args[0]) {\n    case 'list':\n        list();\n        break;\n    case 'mention':\n        mention();\n        break;\n    case 'find-commenters':\n        findCommenters(args[1]);\n        break;\n    default:\n        console.log('unknown argument', args[0]);\n        break;\n}\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/scripts/npm_prepublish.sh",
    "content": "#!/bin/bash\n\nset -e\n\nif [ \"$#\" != 1 ]; then\n    echo \"Please provide tag to checkout\" >&2\n    exit 1\nfi\ntag=\"$1\"\n\nwhile [ \"$PWD\" != '/' -a ! -f moment.js ]; do\n    cd ..\ndone\n\nif [ ! -f moment.js ]; then\n    echo \"Run me from the moment repo\" >&2\n    exit 1\nfi\n\nbasename=$(basename $PWD)\nsrc=moment-npm-git\ndest=moment-npm\n\ncd ..\n\nrm -rf $src $dest\n\ngit clone $basename $src\nmkdir $dest\n\n\ncp $src/moment.js $dest\ncp $src/moment.d.ts $dest\ncp $src/package.json $dest\ncp $src/README.md $dest\ncp $src/CHANGELOG.md $dest\ncp $src/LICENSE $dest\ncp -r $src/locale $dest\ncp -r $src/min $dest\ncp -r $src/src $dest && rm -r $dest/src/test\ncp $src/ender.js $dest\ncp $src/package.js $dest\ncp $src/.npmignore $dest\n\nrm -rf $src\n\necho \"Check out $dest\"\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/lib/create/check-overflow.js",
    "content": "import { daysInMonth } from '../units/month';\nimport { YEAR, MONTH, DATE, HOUR, MINUTE, SECOND, MILLISECOND, WEEK, WEEKDAY } from '../units/constants';\nimport getParsingFlags from '../create/parsing-flags';\n\nexport default function checkOverflow (m) {\n    var overflow;\n    var a = m._a;\n\n    if (a && getParsingFlags(m).overflow === -2) {\n        overflow =\n            a[MONTH]       < 0 || a[MONTH]       > 11  ? MONTH :\n            a[DATE]        < 1 || a[DATE]        > daysInMonth(a[YEAR], a[MONTH]) ? DATE :\n            a[HOUR]        < 0 || a[HOUR]        > 24 || (a[HOUR] === 24 && (a[MINUTE] !== 0 || a[SECOND] !== 0 || a[MILLISECOND] !== 0)) ? HOUR :\n            a[MINUTE]      < 0 || a[MINUTE]      > 59  ? MINUTE :\n            a[SECOND]      < 0 || a[SECOND]      > 59  ? SECOND :\n            a[MILLISECOND] < 0 || a[MILLISECOND] > 999 ? MILLISECOND :\n            -1;\n\n        if (getParsingFlags(m)._overflowDayOfYear && (overflow < YEAR || overflow > DATE)) {\n            overflow = DATE;\n        }\n        if (getParsingFlags(m)._overflowWeeks && overflow === -1) {\n            overflow = WEEK;\n        }\n        if (getParsingFlags(m)._overflowWeekday && overflow === -1) {\n            overflow = WEEKDAY;\n        }\n\n        getParsingFlags(m).overflow = overflow;\n    }\n\n    return m;\n}\n\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/lib/create/date-from-array.js",
    "content": "export function createDate (y, m, d, h, M, s, ms) {\n    // can't just apply() to create a date:\n    // https://stackoverflow.com/q/181348\n    var date = new Date(y, m, d, h, M, s, ms);\n\n    // the date constructor remaps years 0-99 to 1900-1999\n    if (y < 100 && y >= 0 && isFinite(date.getFullYear())) {\n        date.setFullYear(y);\n    }\n    return date;\n}\n\nexport function createUTCDate (y) {\n    var date = new Date(Date.UTC.apply(null, arguments));\n\n    // the Date.UTC function remaps years 0-99 to 1900-1999\n    if (y < 100 && y >= 0 && isFinite(date.getUTCFullYear())) {\n        date.setUTCFullYear(y);\n    }\n    return date;\n}\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/lib/create/from-anything.js",
    "content": "import isArray from '../utils/is-array';\nimport isObject from '../utils/is-object';\nimport isObjectEmpty from '../utils/is-object-empty';\nimport isUndefined from '../utils/is-undefined';\nimport isNumber from '../utils/is-number';\nimport isDate from '../utils/is-date';\nimport map from '../utils/map';\nimport { createInvalid } from './valid';\nimport { Moment, isMoment } from '../moment/constructor';\nimport { getLocale } from '../locale/locales';\nimport { hooks } from '../utils/hooks';\nimport checkOverflow from './check-overflow';\nimport { isValid } from './valid';\n\nimport { configFromStringAndArray }  from './from-string-and-array';\nimport { configFromStringAndFormat } from './from-string-and-format';\nimport { configFromString }          from './from-string';\nimport { configFromArray }           from './from-array';\nimport { configFromObject }          from './from-object';\n\nfunction createFromConfig (config) {\n    var res = new Moment(checkOverflow(prepareConfig(config)));\n    if (res._nextDay) {\n        // Adding is smart enough around DST\n        res.add(1, 'd');\n        res._nextDay = undefined;\n    }\n\n    return res;\n}\n\nexport function prepareConfig (config) {\n    var input = config._i,\n        format = config._f;\n\n    config._locale = config._locale || getLocale(config._l);\n\n    if (input === null || (format === undefined && input === '')) {\n        return createInvalid({nullInput: true});\n    }\n\n    if (typeof input === 'string') {\n        config._i = input = config._locale.preparse(input);\n    }\n\n    if (isMoment(input)) {\n        return new Moment(checkOverflow(input));\n    } else if (isDate(input)) {\n        config._d = input;\n    } else if (isArray(format)) {\n        configFromStringAndArray(config);\n    } else if (format) {\n        configFromStringAndFormat(config);\n    }  else {\n        configFromInput(config);\n    }\n\n    if (!isValid(config)) {\n        config._d = null;\n    }\n\n    return config;\n}\n\nfunction configFromInput(config) {\n    var input = config._i;\n    if (isUndefined(input)) {\n        config._d = new Date(hooks.now());\n    } else if (isDate(input)) {\n        config._d = new Date(input.valueOf());\n    } else if (typeof input === 'string') {\n        configFromString(config);\n    } else if (isArray(input)) {\n        config._a = map(input.slice(0), function (obj) {\n            return parseInt(obj, 10);\n        });\n        configFromArray(config);\n    } else if (isObject(input)) {\n        configFromObject(config);\n    } else if (isNumber(input)) {\n        // from milliseconds\n        config._d = new Date(input);\n    } else {\n        hooks.createFromInputFallback(config);\n    }\n}\n\nexport function createLocalOrUTC (input, format, locale, strict, isUTC) {\n    var c = {};\n\n    if (locale === true || locale === false) {\n        strict = locale;\n        locale = undefined;\n    }\n\n    if ((isObject(input) && isObjectEmpty(input)) ||\n            (isArray(input) && input.length === 0)) {\n        input = undefined;\n    }\n    // object construction must be done this way.\n    // https://github.com/moment/moment/issues/1423\n    c._isAMomentObject = true;\n    c._useUTC = c._isUTC = isUTC;\n    c._l = locale;\n    c._i = input;\n    c._f = format;\n    c._strict = strict;\n\n    return createFromConfig(c);\n}\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/lib/create/from-array.js",
    "content": "import { hooks } from '../utils/hooks';\nimport { createDate, createUTCDate } from './date-from-array';\nimport { daysInYear } from '../units/year';\nimport { weekOfYear, weeksInYear, dayOfYearFromWeeks } from '../units/week-calendar-utils';\nimport { YEAR, MONTH, DATE, HOUR, MINUTE, SECOND, MILLISECOND } from '../units/constants';\nimport { createLocal } from './local';\nimport defaults from '../utils/defaults';\nimport getParsingFlags from './parsing-flags';\n\nfunction currentDateArray(config) {\n    // hooks is actually the exported moment object\n    var nowValue = new Date(hooks.now());\n    if (config._useUTC) {\n        return [nowValue.getUTCFullYear(), nowValue.getUTCMonth(), nowValue.getUTCDate()];\n    }\n    return [nowValue.getFullYear(), nowValue.getMonth(), nowValue.getDate()];\n}\n\n// convert an array to a date.\n// the array should mirror the parameters below\n// note: all values past the year are optional and will default to the lowest possible value.\n// [year, month, day , hour, minute, second, millisecond]\nexport function configFromArray (config) {\n    var i, date, input = [], currentDate, yearToUse;\n\n    if (config._d) {\n        return;\n    }\n\n    currentDate = currentDateArray(config);\n\n    //compute day of the year from weeks and weekdays\n    if (config._w && config._a[DATE] == null && config._a[MONTH] == null) {\n        dayOfYearFromWeekInfo(config);\n    }\n\n    //if the day of the year is set, figure out what it is\n    if (config._dayOfYear != null) {\n        yearToUse = defaults(config._a[YEAR], currentDate[YEAR]);\n\n        if (config._dayOfYear > daysInYear(yearToUse) || config._dayOfYear === 0) {\n            getParsingFlags(config)._overflowDayOfYear = true;\n        }\n\n        date = createUTCDate(yearToUse, 0, config._dayOfYear);\n        config._a[MONTH] = date.getUTCMonth();\n        config._a[DATE] = date.getUTCDate();\n    }\n\n    // Default to current date.\n    // * if no year, month, day of month are given, default to today\n    // * if day of month is given, default month and year\n    // * if month is given, default only year\n    // * if year is given, don't default anything\n    for (i = 0; i < 3 && config._a[i] == null; ++i) {\n        config._a[i] = input[i] = currentDate[i];\n    }\n\n    // Zero out whatever was not defaulted, including time\n    for (; i < 7; i++) {\n        config._a[i] = input[i] = (config._a[i] == null) ? (i === 2 ? 1 : 0) : config._a[i];\n    }\n\n    // Check for 24:00:00.000\n    if (config._a[HOUR] === 24 &&\n            config._a[MINUTE] === 0 &&\n            config._a[SECOND] === 0 &&\n            config._a[MILLISECOND] === 0) {\n        config._nextDay = true;\n        config._a[HOUR] = 0;\n    }\n\n    config._d = (config._useUTC ? createUTCDate : createDate).apply(null, input);\n    // Apply timezone offset from input. The actual utcOffset can be changed\n    // with parseZone.\n    if (config._tzm != null) {\n        config._d.setUTCMinutes(config._d.getUTCMinutes() - config._tzm);\n    }\n\n    if (config._nextDay) {\n        config._a[HOUR] = 24;\n    }\n}\n\nfunction dayOfYearFromWeekInfo(config) {\n    var w, weekYear, week, weekday, dow, doy, temp, weekdayOverflow;\n\n    w = config._w;\n    if (w.GG != null || w.W != null || w.E != null) {\n        dow = 1;\n        doy = 4;\n\n        // TODO: We need to take the current isoWeekYear, but that depends on\n        // how we interpret now (local, utc, fixed offset). So create\n        // a now version of current config (take local/utc/offset flags, and\n        // create now).\n        weekYear = defaults(w.GG, config._a[YEAR], weekOfYear(createLocal(), 1, 4).year);\n        week = defaults(w.W, 1);\n        weekday = defaults(w.E, 1);\n        if (weekday < 1 || weekday > 7) {\n            weekdayOverflow = true;\n        }\n    } else {\n        dow = config._locale._week.dow;\n        doy = config._locale._week.doy;\n\n        var curWeek = weekOfYear(createLocal(), dow, doy);\n\n        weekYear = defaults(w.gg, config._a[YEAR], curWeek.year);\n\n        // Default to current week.\n        week = defaults(w.w, curWeek.week);\n\n        if (w.d != null) {\n            // weekday -- low day numbers are considered next week\n            weekday = w.d;\n            if (weekday < 0 || weekday > 6) {\n                weekdayOverflow = true;\n            }\n        } else if (w.e != null) {\n            // local weekday -- counting starts from begining of week\n            weekday = w.e + dow;\n            if (w.e < 0 || w.e > 6) {\n                weekdayOverflow = true;\n            }\n        } else {\n            // default to begining of week\n            weekday = dow;\n        }\n    }\n    if (week < 1 || week > weeksInYear(weekYear, dow, doy)) {\n        getParsingFlags(config)._overflowWeeks = true;\n    } else if (weekdayOverflow != null) {\n        getParsingFlags(config)._overflowWeekday = true;\n    } else {\n        temp = dayOfYearFromWeeks(weekYear, week, weekday, dow, doy);\n        config._a[YEAR] = temp.year;\n        config._dayOfYear = temp.dayOfYear;\n    }\n}\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/lib/create/from-object.js",
    "content": "import { normalizeObjectUnits } from '../units/aliases';\nimport { configFromArray } from './from-array';\nimport map from '../utils/map';\n\nexport function configFromObject(config) {\n    if (config._d) {\n        return;\n    }\n\n    var i = normalizeObjectUnits(config._i);\n    config._a = map([i.year, i.month, i.day || i.date, i.hour, i.minute, i.second, i.millisecond], function (obj) {\n        return obj && parseInt(obj, 10);\n    });\n\n    configFromArray(config);\n}\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/lib/create/from-string-and-array.js",
    "content": "import { copyConfig } from '../moment/constructor';\nimport { configFromStringAndFormat } from './from-string-and-format';\nimport getParsingFlags from './parsing-flags';\nimport { isValid } from './valid';\nimport extend from '../utils/extend';\n\n// date from string and array of format strings\nexport function configFromStringAndArray(config) {\n    var tempConfig,\n        bestMoment,\n\n        scoreToBeat,\n        i,\n        currentScore;\n\n    if (config._f.length === 0) {\n        getParsingFlags(config).invalidFormat = true;\n        config._d = new Date(NaN);\n        return;\n    }\n\n    for (i = 0; i < config._f.length; i++) {\n        currentScore = 0;\n        tempConfig = copyConfig({}, config);\n        if (config._useUTC != null) {\n            tempConfig._useUTC = config._useUTC;\n        }\n        tempConfig._f = config._f[i];\n        configFromStringAndFormat(tempConfig);\n\n        if (!isValid(tempConfig)) {\n            continue;\n        }\n\n        // if there is any input that was not parsed add a penalty for that format\n        currentScore += getParsingFlags(tempConfig).charsLeftOver;\n\n        //or tokens\n        currentScore += getParsingFlags(tempConfig).unusedTokens.length * 10;\n\n        getParsingFlags(tempConfig).score = currentScore;\n\n        if (scoreToBeat == null || currentScore < scoreToBeat) {\n            scoreToBeat = currentScore;\n            bestMoment = tempConfig;\n        }\n    }\n\n    extend(config, bestMoment || tempConfig);\n}\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/lib/create/from-string-and-format.js",
    "content": "import { configFromISO, configFromRFC2822 } from './from-string';\nimport { configFromArray } from './from-array';\nimport { getParseRegexForToken }   from '../parse/regex';\nimport { addTimeToArrayFromToken } from '../parse/token';\nimport { expandFormat, formatTokenFunctions, formattingTokens } from '../format/format';\nimport checkOverflow from './check-overflow';\nimport { HOUR } from '../units/constants';\nimport { hooks } from '../utils/hooks';\nimport getParsingFlags from './parsing-flags';\n\n// constant that refers to the ISO standard\nhooks.ISO_8601 = function () {};\n\n// constant that refers to the RFC 2822 form\nhooks.RFC_2822 = function () {};\n\n// date from string and format string\nexport function configFromStringAndFormat(config) {\n    // TODO: Move this to another part of the creation flow to prevent circular deps\n    if (config._f === hooks.ISO_8601) {\n        configFromISO(config);\n        return;\n    }\n    if (config._f === hooks.RFC_2822) {\n        configFromRFC2822(config);\n        return;\n    }\n    config._a = [];\n    getParsingFlags(config).empty = true;\n\n    // This array is used to make a Date, either with `new Date` or `Date.UTC`\n    var string = '' + config._i,\n        i, parsedInput, tokens, token, skipped,\n        stringLength = string.length,\n        totalParsedInputLength = 0;\n\n    tokens = expandFormat(config._f, config._locale).match(formattingTokens) || [];\n\n    for (i = 0; i < tokens.length; i++) {\n        token = tokens[i];\n        parsedInput = (string.match(getParseRegexForToken(token, config)) || [])[0];\n        // console.log('token', token, 'parsedInput', parsedInput,\n        //         'regex', getParseRegexForToken(token, config));\n        if (parsedInput) {\n            skipped = string.substr(0, string.indexOf(parsedInput));\n            if (skipped.length > 0) {\n                getParsingFlags(config).unusedInput.push(skipped);\n            }\n            string = string.slice(string.indexOf(parsedInput) + parsedInput.length);\n            totalParsedInputLength += parsedInput.length;\n        }\n        // don't parse if it's not a known token\n        if (formatTokenFunctions[token]) {\n            if (parsedInput) {\n                getParsingFlags(config).empty = false;\n            }\n            else {\n                getParsingFlags(config).unusedTokens.push(token);\n            }\n            addTimeToArrayFromToken(token, parsedInput, config);\n        }\n        else if (config._strict && !parsedInput) {\n            getParsingFlags(config).unusedTokens.push(token);\n        }\n    }\n\n    // add remaining unparsed input length to the string\n    getParsingFlags(config).charsLeftOver = stringLength - totalParsedInputLength;\n    if (string.length > 0) {\n        getParsingFlags(config).unusedInput.push(string);\n    }\n\n    // clear _12h flag if hour is <= 12\n    if (config._a[HOUR] <= 12 &&\n        getParsingFlags(config).bigHour === true &&\n        config._a[HOUR] > 0) {\n        getParsingFlags(config).bigHour = undefined;\n    }\n\n    getParsingFlags(config).parsedDateParts = config._a.slice(0);\n    getParsingFlags(config).meridiem = config._meridiem;\n    // handle meridiem\n    config._a[HOUR] = meridiemFixWrap(config._locale, config._a[HOUR], config._meridiem);\n\n    configFromArray(config);\n    checkOverflow(config);\n}\n\n\nfunction meridiemFixWrap (locale, hour, meridiem) {\n    var isPm;\n\n    if (meridiem == null) {\n        // nothing to do\n        return hour;\n    }\n    if (locale.meridiemHour != null) {\n        return locale.meridiemHour(hour, meridiem);\n    } else if (locale.isPM != null) {\n        // Fallback\n        isPm = locale.isPM(meridiem);\n        if (isPm && hour < 12) {\n            hour += 12;\n        }\n        if (!isPm && hour === 12) {\n            hour = 0;\n        }\n        return hour;\n    } else {\n        // this is not supposed to happen\n        return hour;\n    }\n}\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/lib/create/from-string.js",
    "content": "import { configFromStringAndFormat } from './from-string-and-format';\nimport { hooks } from '../utils/hooks';\nimport { deprecate } from '../utils/deprecate';\nimport getParsingFlags from './parsing-flags';\n\n// iso 8601 regex\n// 0000-00-00 0000-W00 or 0000-W00-0 + T + 00 or 00:00 or 00:00:00 or 00:00:00.000 + +00:00 or +0000 or +00)\nvar extendedIsoRegex = /^\\s*((?:[+-]\\d{6}|\\d{4})-(?:\\d\\d-\\d\\d|W\\d\\d-\\d|W\\d\\d|\\d\\d\\d|\\d\\d))(?:(T| )(\\d\\d(?::\\d\\d(?::\\d\\d(?:[.,]\\d+)?)?)?)([\\+\\-]\\d\\d(?::?\\d\\d)?|\\s*Z)?)?$/;\nvar basicIsoRegex = /^\\s*((?:[+-]\\d{6}|\\d{4})(?:\\d\\d\\d\\d|W\\d\\d\\d|W\\d\\d|\\d\\d\\d|\\d\\d))(?:(T| )(\\d\\d(?:\\d\\d(?:\\d\\d(?:[.,]\\d+)?)?)?)([\\+\\-]\\d\\d(?::?\\d\\d)?|\\s*Z)?)?$/;\n\nvar tzRegex = /Z|[+-]\\d\\d(?::?\\d\\d)?/;\n\nvar isoDates = [\n    ['YYYYYY-MM-DD', /[+-]\\d{6}-\\d\\d-\\d\\d/],\n    ['YYYY-MM-DD', /\\d{4}-\\d\\d-\\d\\d/],\n    ['GGGG-[W]WW-E', /\\d{4}-W\\d\\d-\\d/],\n    ['GGGG-[W]WW', /\\d{4}-W\\d\\d/, false],\n    ['YYYY-DDD', /\\d{4}-\\d{3}/],\n    ['YYYY-MM', /\\d{4}-\\d\\d/, false],\n    ['YYYYYYMMDD', /[+-]\\d{10}/],\n    ['YYYYMMDD', /\\d{8}/],\n    // YYYYMM is NOT allowed by the standard\n    ['GGGG[W]WWE', /\\d{4}W\\d{3}/],\n    ['GGGG[W]WW', /\\d{4}W\\d{2}/, false],\n    ['YYYYDDD', /\\d{7}/]\n];\n\n// iso time formats and regexes\nvar isoTimes = [\n    ['HH:mm:ss.SSSS', /\\d\\d:\\d\\d:\\d\\d\\.\\d+/],\n    ['HH:mm:ss,SSSS', /\\d\\d:\\d\\d:\\d\\d,\\d+/],\n    ['HH:mm:ss', /\\d\\d:\\d\\d:\\d\\d/],\n    ['HH:mm', /\\d\\d:\\d\\d/],\n    ['HHmmss.SSSS', /\\d\\d\\d\\d\\d\\d\\.\\d+/],\n    ['HHmmss,SSSS', /\\d\\d\\d\\d\\d\\d,\\d+/],\n    ['HHmmss', /\\d\\d\\d\\d\\d\\d/],\n    ['HHmm', /\\d\\d\\d\\d/],\n    ['HH', /\\d\\d/]\n];\n\nvar aspNetJsonRegex = /^\\/?Date\\((\\-?\\d+)/i;\n\n// date from iso format\nexport function configFromISO(config) {\n    var i, l,\n        string = config._i,\n        match = extendedIsoRegex.exec(string) || basicIsoRegex.exec(string),\n        allowTime, dateFormat, timeFormat, tzFormat;\n\n    if (match) {\n        getParsingFlags(config).iso = true;\n\n        for (i = 0, l = isoDates.length; i < l; i++) {\n            if (isoDates[i][1].exec(match[1])) {\n                dateFormat = isoDates[i][0];\n                allowTime = isoDates[i][2] !== false;\n                break;\n            }\n        }\n        if (dateFormat == null) {\n            config._isValid = false;\n            return;\n        }\n        if (match[3]) {\n            for (i = 0, l = isoTimes.length; i < l; i++) {\n                if (isoTimes[i][1].exec(match[3])) {\n                    // match[2] should be 'T' or space\n                    timeFormat = (match[2] || ' ') + isoTimes[i][0];\n                    break;\n                }\n            }\n            if (timeFormat == null) {\n                config._isValid = false;\n                return;\n            }\n        }\n        if (!allowTime && timeFormat != null) {\n            config._isValid = false;\n            return;\n        }\n        if (match[4]) {\n            if (tzRegex.exec(match[4])) {\n                tzFormat = 'Z';\n            } else {\n                config._isValid = false;\n                return;\n            }\n        }\n        config._f = dateFormat + (timeFormat || '') + (tzFormat || '');\n        configFromStringAndFormat(config);\n    } else {\n        config._isValid = false;\n    }\n}\n\n// RFC 2822 regex: For details see https://tools.ietf.org/html/rfc2822#section-3.3\nvar basicRfcRegex = /^((?:Mon|Tue|Wed|Thu|Fri|Sat|Sun),?\\s)?(\\d?\\d\\s(?:Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)\\s(?:\\d\\d)?\\d\\d\\s)(\\d\\d:\\d\\d)(\\:\\d\\d)?(\\s(?:UT|GMT|[ECMP][SD]T|[A-IK-Za-ik-z]|[+-]\\d{4}))$/;\n\n// date and time from ref 2822 format\nexport function configFromRFC2822(config) {\n    var string, match, dayFormat,\n        dateFormat, timeFormat, tzFormat;\n    var timezones = {\n        ' GMT': ' +0000',\n        ' EDT': ' -0400',\n        ' EST': ' -0500',\n        ' CDT': ' -0500',\n        ' CST': ' -0600',\n        ' MDT': ' -0600',\n        ' MST': ' -0700',\n        ' PDT': ' -0700',\n        ' PST': ' -0800'\n    };\n    var military = 'YXWVUTSRQPONZABCDEFGHIKLM';\n    var timezone, timezoneIndex;\n\n    string = config._i\n        .replace(/\\([^\\)]*\\)|[\\n\\t]/g, ' ') // Remove comments and folding whitespace\n        .replace(/(\\s\\s+)/g, ' ') // Replace multiple-spaces with a single space\n        .replace(/^\\s|\\s$/g, ''); // Remove leading and trailing spaces\n    match = basicRfcRegex.exec(string);\n\n    if (match) {\n        dayFormat = match[1] ? 'ddd' + ((match[1].length === 5) ? ', ' : ' ') : '';\n        dateFormat = 'D MMM ' + ((match[2].length > 10) ? 'YYYY ' : 'YY ');\n        timeFormat = 'HH:mm' + (match[4] ? ':ss' : '');\n\n        // TODO: Replace the vanilla JS Date object with an indepentent day-of-week check.\n        if (match[1]) { // day of week given\n            var momentDate = new Date(match[2]);\n            var momentDay = ['Sun','Mon','Tue','Wed','Thu','Fri','Sat'][momentDate.getDay()];\n\n            if (match[1].substr(0,3) !== momentDay) {\n                getParsingFlags(config).weekdayMismatch = true;\n                config._isValid = false;\n                return;\n            }\n        }\n\n        switch (match[5].length) {\n            case 2: // military\n                if (timezoneIndex === 0) {\n                    timezone = ' +0000';\n                } else {\n                    timezoneIndex = military.indexOf(match[5][1].toUpperCase()) - 12;\n                    timezone = ((timezoneIndex < 0) ? ' -' : ' +') +\n                        (('' + timezoneIndex).replace(/^-?/, '0')).match(/..$/)[0] + '00';\n                }\n                break;\n            case 4: // Zone\n                timezone = timezones[match[5]];\n                break;\n            default: // UT or +/-9999\n                timezone = timezones[' GMT'];\n        }\n        match[5] = timezone;\n        config._i = match.splice(1).join('');\n        tzFormat = ' ZZ';\n        config._f = dayFormat + dateFormat + timeFormat + tzFormat;\n        configFromStringAndFormat(config);\n        getParsingFlags(config).rfc2822 = true;\n    } else {\n        config._isValid = false;\n    }\n}\n\n// date from iso format or fallback\nexport function configFromString(config) {\n    var matched = aspNetJsonRegex.exec(config._i);\n\n    if (matched !== null) {\n        config._d = new Date(+matched[1]);\n        return;\n    }\n\n    configFromISO(config);\n    if (config._isValid === false) {\n        delete config._isValid;\n    } else {\n        return;\n    }\n\n    configFromRFC2822(config);\n    if (config._isValid === false) {\n        delete config._isValid;\n    } else {\n        return;\n    }\n\n    // Final attempt, use Input Fallback\n    hooks.createFromInputFallback(config);\n}\n\nhooks.createFromInputFallback = deprecate(\n    'value provided is not in a recognized RFC2822 or ISO format. moment construction falls back to js Date(), ' +\n    'which is not reliable across all browsers and versions. Non RFC2822/ISO date formats are ' +\n    'discouraged and will be removed in an upcoming major release. Please refer to ' +\n    'http://momentjs.com/guides/#/warnings/js-date/ for more info.',\n    function (config) {\n        config._d = new Date(config._i + (config._useUTC ? ' UTC' : ''));\n    }\n);\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/lib/create/local.js",
    "content": "import { createLocalOrUTC } from './from-anything';\n\nexport function createLocal (input, format, locale, strict) {\n    return createLocalOrUTC(input, format, locale, strict, false);\n}\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/lib/create/parsing-flags.js",
    "content": "function defaultParsingFlags() {\n    // We need to deep clone this object.\n    return {\n        empty           : false,\n        unusedTokens    : [],\n        unusedInput     : [],\n        overflow        : -2,\n        charsLeftOver   : 0,\n        nullInput       : false,\n        invalidMonth    : null,\n        invalidFormat   : false,\n        userInvalidated : false,\n        iso             : false,\n        parsedDateParts : [],\n        meridiem        : null,\n        rfc2822         : false,\n        weekdayMismatch : false\n    };\n}\n\nexport default function getParsingFlags(m) {\n    if (m._pf == null) {\n        m._pf = defaultParsingFlags();\n    }\n    return m._pf;\n}\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/lib/create/utc.js",
    "content": "import { createLocalOrUTC } from './from-anything';\n\nexport function createUTC (input, format, locale, strict) {\n    return createLocalOrUTC(input, format, locale, strict, true).utc();\n}\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/lib/create/valid.js",
    "content": "import extend from '../utils/extend';\nimport { createUTC } from './utc';\nimport getParsingFlags from '../create/parsing-flags';\nimport some from '../utils/some';\n\nexport function isValid(m) {\n    if (m._isValid == null) {\n        var flags = getParsingFlags(m);\n        var parsedParts = some.call(flags.parsedDateParts, function (i) {\n            return i != null;\n        });\n        var isNowValid = !isNaN(m._d.getTime()) &&\n            flags.overflow < 0 &&\n            !flags.empty &&\n            !flags.invalidMonth &&\n            !flags.invalidWeekday &&\n            !flags.nullInput &&\n            !flags.invalidFormat &&\n            !flags.userInvalidated &&\n            (!flags.meridiem || (flags.meridiem && parsedParts));\n\n        if (m._strict) {\n            isNowValid = isNowValid &&\n                flags.charsLeftOver === 0 &&\n                flags.unusedTokens.length === 0 &&\n                flags.bigHour === undefined;\n        }\n\n        if (Object.isFrozen == null || !Object.isFrozen(m)) {\n            m._isValid = isNowValid;\n        }\n        else {\n            return isNowValid;\n        }\n    }\n    return m._isValid;\n}\n\nexport function createInvalid (flags) {\n    var m = createUTC(NaN);\n    if (flags != null) {\n        extend(getParsingFlags(m), flags);\n    }\n    else {\n        getParsingFlags(m).userInvalidated = true;\n    }\n\n    return m;\n}\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/lib/duration/abs.js",
    "content": "var mathAbs = Math.abs;\n\nexport function abs () {\n    var data           = this._data;\n\n    this._milliseconds = mathAbs(this._milliseconds);\n    this._days         = mathAbs(this._days);\n    this._months       = mathAbs(this._months);\n\n    data.milliseconds  = mathAbs(data.milliseconds);\n    data.seconds       = mathAbs(data.seconds);\n    data.minutes       = mathAbs(data.minutes);\n    data.hours         = mathAbs(data.hours);\n    data.months        = mathAbs(data.months);\n    data.years         = mathAbs(data.years);\n\n    return this;\n}\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/lib/duration/add-subtract.js",
    "content": "import { createDuration } from './create';\n\nfunction addSubtract (duration, input, value, direction) {\n    var other = createDuration(input, value);\n\n    duration._milliseconds += direction * other._milliseconds;\n    duration._days         += direction * other._days;\n    duration._months       += direction * other._months;\n\n    return duration._bubble();\n}\n\n// supports only 2.0-style add(1, 's') or add(duration)\nexport function add (input, value) {\n    return addSubtract(this, input, value, 1);\n}\n\n// supports only 2.0-style subtract(1, 's') or subtract(duration)\nexport function subtract (input, value) {\n    return addSubtract(this, input, value, -1);\n}\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/lib/duration/as.js",
    "content": "import { daysToMonths, monthsToDays } from './bubble';\nimport { normalizeUnits } from '../units/aliases';\nimport toInt from '../utils/to-int';\n\nexport function as (units) {\n    if (!this.isValid()) {\n        return NaN;\n    }\n    var days;\n    var months;\n    var milliseconds = this._milliseconds;\n\n    units = normalizeUnits(units);\n\n    if (units === 'month' || units === 'year') {\n        days   = this._days   + milliseconds / 864e5;\n        months = this._months + daysToMonths(days);\n        return units === 'month' ? months : months / 12;\n    } else {\n        // handle milliseconds separately because of floating point math errors (issue #1867)\n        days = this._days + Math.round(monthsToDays(this._months));\n        switch (units) {\n            case 'week'   : return days / 7     + milliseconds / 6048e5;\n            case 'day'    : return days         + milliseconds / 864e5;\n            case 'hour'   : return days * 24    + milliseconds / 36e5;\n            case 'minute' : return days * 1440  + milliseconds / 6e4;\n            case 'second' : return days * 86400 + milliseconds / 1000;\n            // Math.floor prevents floating point math errors here\n            case 'millisecond': return Math.floor(days * 864e5) + milliseconds;\n            default: throw new Error('Unknown unit ' + units);\n        }\n    }\n}\n\n// TODO: Use this.as('ms')?\nexport function valueOf () {\n    if (!this.isValid()) {\n        return NaN;\n    }\n    return (\n        this._milliseconds +\n        this._days * 864e5 +\n        (this._months % 12) * 2592e6 +\n        toInt(this._months / 12) * 31536e6\n    );\n}\n\nfunction makeAs (alias) {\n    return function () {\n        return this.as(alias);\n    };\n}\n\nexport var asMilliseconds = makeAs('ms');\nexport var asSeconds      = makeAs('s');\nexport var asMinutes      = makeAs('m');\nexport var asHours        = makeAs('h');\nexport var asDays         = makeAs('d');\nexport var asWeeks        = makeAs('w');\nexport var asMonths       = makeAs('M');\nexport var asYears        = makeAs('y');\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/lib/duration/bubble.js",
    "content": "import absFloor from '../utils/abs-floor';\nimport absCeil from '../utils/abs-ceil';\nimport { createUTCDate } from '../create/date-from-array';\n\nexport function bubble () {\n    var milliseconds = this._milliseconds;\n    var days         = this._days;\n    var months       = this._months;\n    var data         = this._data;\n    var seconds, minutes, hours, years, monthsFromDays;\n\n    // if we have a mix of positive and negative values, bubble down first\n    // check: https://github.com/moment/moment/issues/2166\n    if (!((milliseconds >= 0 && days >= 0 && months >= 0) ||\n            (milliseconds <= 0 && days <= 0 && months <= 0))) {\n        milliseconds += absCeil(monthsToDays(months) + days) * 864e5;\n        days = 0;\n        months = 0;\n    }\n\n    // The following code bubbles up values, see the tests for\n    // examples of what that means.\n    data.milliseconds = milliseconds % 1000;\n\n    seconds           = absFloor(milliseconds / 1000);\n    data.seconds      = seconds % 60;\n\n    minutes           = absFloor(seconds / 60);\n    data.minutes      = minutes % 60;\n\n    hours             = absFloor(minutes / 60);\n    data.hours        = hours % 24;\n\n    days += absFloor(hours / 24);\n\n    // convert days to months\n    monthsFromDays = absFloor(daysToMonths(days));\n    months += monthsFromDays;\n    days -= absCeil(monthsToDays(monthsFromDays));\n\n    // 12 months -> 1 year\n    years = absFloor(months / 12);\n    months %= 12;\n\n    data.days   = days;\n    data.months = months;\n    data.years  = years;\n\n    return this;\n}\n\nexport function daysToMonths (days) {\n    // 400 years have 146097 days (taking into account leap year rules)\n    // 400 years have 12 months === 4800\n    return days * 4800 / 146097;\n}\n\nexport function monthsToDays (months) {\n    // the reverse of daysToMonths\n    return months * 146097 / 4800;\n}\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/lib/duration/constructor.js",
    "content": "import { normalizeObjectUnits } from '../units/aliases';\nimport { getLocale } from '../locale/locales';\nimport isDurationValid from './valid.js';\n\nexport function Duration (duration) {\n    var normalizedInput = normalizeObjectUnits(duration),\n        years = normalizedInput.year || 0,\n        quarters = normalizedInput.quarter || 0,\n        months = normalizedInput.month || 0,\n        weeks = normalizedInput.week || 0,\n        days = normalizedInput.day || 0,\n        hours = normalizedInput.hour || 0,\n        minutes = normalizedInput.minute || 0,\n        seconds = normalizedInput.second || 0,\n        milliseconds = normalizedInput.millisecond || 0;\n\n    this._isValid = isDurationValid(normalizedInput);\n\n    // representation for dateAddRemove\n    this._milliseconds = +milliseconds +\n        seconds * 1e3 + // 1000\n        minutes * 6e4 + // 1000 * 60\n        hours * 1000 * 60 * 60; //using 1000 * 60 * 60 instead of 36e5 to avoid floating point rounding errors https://github.com/moment/moment/issues/2978\n    // Because of dateAddRemove treats 24 hours as different from a\n    // day when working around DST, we need to store them separately\n    this._days = +days +\n        weeks * 7;\n    // It is impossible translate months into days without knowing\n    // which months you are are talking about, so we have to store\n    // it separately.\n    this._months = +months +\n        quarters * 3 +\n        years * 12;\n\n    this._data = {};\n\n    this._locale = getLocale();\n\n    this._bubble();\n}\n\nexport function isDuration (obj) {\n    return obj instanceof Duration;\n}\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/lib/duration/create.js",
    "content": "import { Duration, isDuration } from './constructor';\nimport isNumber from '../utils/is-number';\nimport toInt from '../utils/to-int';\nimport absRound from '../utils/abs-round';\nimport hasOwnProp from '../utils/has-own-prop';\nimport { DATE, HOUR, MINUTE, SECOND, MILLISECOND } from '../units/constants';\nimport { cloneWithOffset } from '../units/offset';\nimport { createLocal } from '../create/local';\nimport { createInvalid as invalid } from './valid';\n\n// ASP.NET json date format regex\nvar aspNetRegex = /^(\\-)?(?:(\\d*)[. ])?(\\d+)\\:(\\d+)(?:\\:(\\d+)(\\.\\d*)?)?$/;\n\n// from http://docs.closure-library.googlecode.com/git/closure_goog_date_date.js.source.html\n// somewhat more in line with 4.4.3.2 2004 spec, but allows decimal anywhere\n// and further modified to allow for strings containing both week and day\nvar isoRegex = /^(-)?P(?:(-?[0-9,.]*)Y)?(?:(-?[0-9,.]*)M)?(?:(-?[0-9,.]*)W)?(?:(-?[0-9,.]*)D)?(?:T(?:(-?[0-9,.]*)H)?(?:(-?[0-9,.]*)M)?(?:(-?[0-9,.]*)S)?)?$/;\n\nexport function createDuration (input, key) {\n    var duration = input,\n        // matching against regexp is expensive, do it on demand\n        match = null,\n        sign,\n        ret,\n        diffRes;\n\n    if (isDuration(input)) {\n        duration = {\n            ms : input._milliseconds,\n            d  : input._days,\n            M  : input._months\n        };\n    } else if (isNumber(input)) {\n        duration = {};\n        if (key) {\n            duration[key] = input;\n        } else {\n            duration.milliseconds = input;\n        }\n    } else if (!!(match = aspNetRegex.exec(input))) {\n        sign = (match[1] === '-') ? -1 : 1;\n        duration = {\n            y  : 0,\n            d  : toInt(match[DATE])                         * sign,\n            h  : toInt(match[HOUR])                         * sign,\n            m  : toInt(match[MINUTE])                       * sign,\n            s  : toInt(match[SECOND])                       * sign,\n            ms : toInt(absRound(match[MILLISECOND] * 1000)) * sign // the millisecond decimal point is included in the match\n        };\n    } else if (!!(match = isoRegex.exec(input))) {\n        sign = (match[1] === '-') ? -1 : 1;\n        duration = {\n            y : parseIso(match[2], sign),\n            M : parseIso(match[3], sign),\n            w : parseIso(match[4], sign),\n            d : parseIso(match[5], sign),\n            h : parseIso(match[6], sign),\n            m : parseIso(match[7], sign),\n            s : parseIso(match[8], sign)\n        };\n    } else if (duration == null) {// checks for null or undefined\n        duration = {};\n    } else if (typeof duration === 'object' && ('from' in duration || 'to' in duration)) {\n        diffRes = momentsDifference(createLocal(duration.from), createLocal(duration.to));\n\n        duration = {};\n        duration.ms = diffRes.milliseconds;\n        duration.M = diffRes.months;\n    }\n\n    ret = new Duration(duration);\n\n    if (isDuration(input) && hasOwnProp(input, '_locale')) {\n        ret._locale = input._locale;\n    }\n\n    return ret;\n}\n\ncreateDuration.fn = Duration.prototype;\ncreateDuration.invalid = invalid;\n\nfunction parseIso (inp, sign) {\n    // We'd normally use ~~inp for this, but unfortunately it also\n    // converts floats to ints.\n    // inp may be undefined, so careful calling replace on it.\n    var res = inp && parseFloat(inp.replace(',', '.'));\n    // apply sign while we're at it\n    return (isNaN(res) ? 0 : res) * sign;\n}\n\nfunction positiveMomentsDifference(base, other) {\n    var res = {milliseconds: 0, months: 0};\n\n    res.months = other.month() - base.month() +\n        (other.year() - base.year()) * 12;\n    if (base.clone().add(res.months, 'M').isAfter(other)) {\n        --res.months;\n    }\n\n    res.milliseconds = +other - +(base.clone().add(res.months, 'M'));\n\n    return res;\n}\n\nfunction momentsDifference(base, other) {\n    var res;\n    if (!(base.isValid() && other.isValid())) {\n        return {milliseconds: 0, months: 0};\n    }\n\n    other = cloneWithOffset(other, base);\n    if (base.isBefore(other)) {\n        res = positiveMomentsDifference(base, other);\n    } else {\n        res = positiveMomentsDifference(other, base);\n        res.milliseconds = -res.milliseconds;\n        res.months = -res.months;\n    }\n\n    return res;\n}\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/lib/duration/duration.js",
    "content": "// Side effect imports\nimport './prototype';\n\nimport { createDuration } from './create';\nimport { isDuration } from './constructor';\nimport {\n    getSetRelativeTimeRounding,\n    getSetRelativeTimeThreshold\n} from './humanize';\n\nexport {\n    createDuration,\n    isDuration,\n    getSetRelativeTimeRounding,\n    getSetRelativeTimeThreshold\n};\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/lib/duration/get.js",
    "content": "import { normalizeUnits } from '../units/aliases';\nimport absFloor from '../utils/abs-floor';\n\nexport function get (units) {\n    units = normalizeUnits(units);\n    return this.isValid() ? this[units + 's']() : NaN;\n}\n\nfunction makeGetter(name) {\n    return function () {\n        return this.isValid() ? this._data[name] : NaN;\n    };\n}\n\nexport var milliseconds = makeGetter('milliseconds');\nexport var seconds      = makeGetter('seconds');\nexport var minutes      = makeGetter('minutes');\nexport var hours        = makeGetter('hours');\nexport var days         = makeGetter('days');\nexport var months       = makeGetter('months');\nexport var years        = makeGetter('years');\n\nexport function weeks () {\n    return absFloor(this.days() / 7);\n}\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/lib/duration/humanize.js",
    "content": "import { createDuration } from './create';\n\nvar round = Math.round;\nvar thresholds = {\n    ss: 44,         // a few seconds to seconds\n    s : 45,         // seconds to minute\n    m : 45,         // minutes to hour\n    h : 22,         // hours to day\n    d : 26,         // days to month\n    M : 11          // months to year\n};\n\n// helper function for moment.fn.from, moment.fn.fromNow, and moment.duration.fn.humanize\nfunction substituteTimeAgo(string, number, withoutSuffix, isFuture, locale) {\n    return locale.relativeTime(number || 1, !!withoutSuffix, string, isFuture);\n}\n\nfunction relativeTime (posNegDuration, withoutSuffix, locale) {\n    var duration = createDuration(posNegDuration).abs();\n    var seconds  = round(duration.as('s'));\n    var minutes  = round(duration.as('m'));\n    var hours    = round(duration.as('h'));\n    var days     = round(duration.as('d'));\n    var months   = round(duration.as('M'));\n    var years    = round(duration.as('y'));\n\n    var a = seconds <= thresholds.ss && ['s', seconds]  ||\n            seconds < thresholds.s   && ['ss', seconds] ||\n            minutes <= 1             && ['m']           ||\n            minutes < thresholds.m   && ['mm', minutes] ||\n            hours   <= 1             && ['h']           ||\n            hours   < thresholds.h   && ['hh', hours]   ||\n            days    <= 1             && ['d']           ||\n            days    < thresholds.d   && ['dd', days]    ||\n            months  <= 1             && ['M']           ||\n            months  < thresholds.M   && ['MM', months]  ||\n            years   <= 1             && ['y']           || ['yy', years];\n\n    a[2] = withoutSuffix;\n    a[3] = +posNegDuration > 0;\n    a[4] = locale;\n    return substituteTimeAgo.apply(null, a);\n}\n\n// This function allows you to set the rounding function for relative time strings\nexport function getSetRelativeTimeRounding (roundingFunction) {\n    if (roundingFunction === undefined) {\n        return round;\n    }\n    if (typeof(roundingFunction) === 'function') {\n        round = roundingFunction;\n        return true;\n    }\n    return false;\n}\n\n// This function allows you to set a threshold for relative time strings\nexport function getSetRelativeTimeThreshold (threshold, limit) {\n    if (thresholds[threshold] === undefined) {\n        return false;\n    }\n    if (limit === undefined) {\n        return thresholds[threshold];\n    }\n    thresholds[threshold] = limit;\n    if (threshold === 's') {\n        thresholds.ss = limit - 1;\n    }\n    return true;\n}\n\nexport function humanize (withSuffix) {\n    if (!this.isValid()) {\n        return this.localeData().invalidDate();\n    }\n\n    var locale = this.localeData();\n    var output = relativeTime(this, !withSuffix, locale);\n\n    if (withSuffix) {\n        output = locale.pastFuture(+this, output);\n    }\n\n    return locale.postformat(output);\n}\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/lib/duration/iso-string.js",
    "content": "import absFloor from '../utils/abs-floor';\nvar abs = Math.abs;\n\nexport function toISOString() {\n    // for ISO strings we do not use the normal bubbling rules:\n    //  * milliseconds bubble up until they become hours\n    //  * days do not bubble at all\n    //  * months bubble up until they become years\n    // This is because there is no context-free conversion between hours and days\n    // (think of clock changes)\n    // and also not between days and months (28-31 days per month)\n    if (!this.isValid()) {\n        return this.localeData().invalidDate();\n    }\n\n    var seconds = abs(this._milliseconds) / 1000;\n    var days         = abs(this._days);\n    var months       = abs(this._months);\n    var minutes, hours, years;\n\n    // 3600 seconds -> 60 minutes -> 1 hour\n    minutes           = absFloor(seconds / 60);\n    hours             = absFloor(minutes / 60);\n    seconds %= 60;\n    minutes %= 60;\n\n    // 12 months -> 1 year\n    years  = absFloor(months / 12);\n    months %= 12;\n\n\n    // inspired by https://github.com/dordille/moment-isoduration/blob/master/moment.isoduration.js\n    var Y = years;\n    var M = months;\n    var D = days;\n    var h = hours;\n    var m = minutes;\n    var s = seconds;\n    var total = this.asSeconds();\n\n    if (!total) {\n        // this is the same as C#'s (Noda) and python (isodate)...\n        // but not other JS (goog.date)\n        return 'P0D';\n    }\n\n    return (total < 0 ? '-' : '') +\n        'P' +\n        (Y ? Y + 'Y' : '') +\n        (M ? M + 'M' : '') +\n        (D ? D + 'D' : '') +\n        ((h || m || s) ? 'T' : '') +\n        (h ? h + 'H' : '') +\n        (m ? m + 'M' : '') +\n        (s ? s + 'S' : '');\n}\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/lib/duration/prototype.js",
    "content": "import { Duration } from './constructor';\n\nvar proto = Duration.prototype;\n\nimport { abs } from './abs';\nimport { add, subtract } from './add-subtract';\nimport { as, asMilliseconds, asSeconds, asMinutes, asHours, asDays, asWeeks, asMonths, asYears, valueOf } from './as';\nimport { bubble } from './bubble';\nimport { get, milliseconds, seconds, minutes, hours, days, months, years, weeks } from './get';\nimport { humanize } from './humanize';\nimport { toISOString } from './iso-string';\nimport { lang, locale, localeData } from '../moment/locale';\nimport { isValid } from './valid';\n\nproto.isValid        = isValid;\nproto.abs            = abs;\nproto.add            = add;\nproto.subtract       = subtract;\nproto.as             = as;\nproto.asMilliseconds = asMilliseconds;\nproto.asSeconds      = asSeconds;\nproto.asMinutes      = asMinutes;\nproto.asHours        = asHours;\nproto.asDays         = asDays;\nproto.asWeeks        = asWeeks;\nproto.asMonths       = asMonths;\nproto.asYears        = asYears;\nproto.valueOf        = valueOf;\nproto._bubble        = bubble;\nproto.get            = get;\nproto.milliseconds   = milliseconds;\nproto.seconds        = seconds;\nproto.minutes        = minutes;\nproto.hours          = hours;\nproto.days           = days;\nproto.weeks          = weeks;\nproto.months         = months;\nproto.years          = years;\nproto.humanize       = humanize;\nproto.toISOString    = toISOString;\nproto.toString       = toISOString;\nproto.toJSON         = toISOString;\nproto.locale         = locale;\nproto.localeData     = localeData;\n\n// Deprecations\nimport { deprecate } from '../utils/deprecate';\n\nproto.toIsoString = deprecate('toIsoString() is deprecated. Please use toISOString() instead (notice the capitals)', toISOString);\nproto.lang = lang;\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/lib/duration/valid.js",
    "content": "import toInt from '../utils/to-int';\nimport {Duration} from './constructor';\nimport {createDuration} from './create';\n\nvar ordering = ['year', 'quarter', 'month', 'week', 'day', 'hour', 'minute', 'second', 'millisecond'];\n\nexport default function isDurationValid(m) {\n    for (var key in m) {\n        if (!(ordering.indexOf(key) !== -1 && (m[key] == null || !isNaN(m[key])))) {\n            return false;\n        }\n    }\n\n    var unitHasDecimal = false;\n    for (var i = 0; i < ordering.length; ++i) {\n        if (m[ordering[i]]) {\n            if (unitHasDecimal) {\n                return false; // only allow non-integers for smallest unit\n            }\n            if (parseFloat(m[ordering[i]]) !== toInt(m[ordering[i]])) {\n                unitHasDecimal = true;\n            }\n        }\n    }\n\n    return true;\n}\n\nexport function isValid() {\n    return this._isValid;\n}\n\nexport function createInvalid() {\n    return createDuration(NaN);\n}\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/lib/format/format.js",
    "content": "import zeroFill from '../utils/zero-fill';\nimport isFunction from '../utils/is-function';\n\nexport var formattingTokens = /(\\[[^\\[]*\\])|(\\\\)?([Hh]mm(ss)?|Mo|MM?M?M?|Do|DDDo|DD?D?D?|ddd?d?|do?|w[o|w]?|W[o|W]?|Qo?|YYYYYY|YYYYY|YYYY|YY|gg(ggg?)?|GG(GGG?)?|e|E|a|A|hh?|HH?|kk?|mm?|ss?|S{1,9}|x|X|zz?|ZZ?|.)/g;\n\nvar localFormattingTokens = /(\\[[^\\[]*\\])|(\\\\)?(LTS|LT|LL?L?L?|l{1,4})/g;\n\nvar formatFunctions = {};\n\nexport var formatTokenFunctions = {};\n\n// token:    'M'\n// padded:   ['MM', 2]\n// ordinal:  'Mo'\n// callback: function () { this.month() + 1 }\nexport function addFormatToken (token, padded, ordinal, callback) {\n    var func = callback;\n    if (typeof callback === 'string') {\n        func = function () {\n            return this[callback]();\n        };\n    }\n    if (token) {\n        formatTokenFunctions[token] = func;\n    }\n    if (padded) {\n        formatTokenFunctions[padded[0]] = function () {\n            return zeroFill(func.apply(this, arguments), padded[1], padded[2]);\n        };\n    }\n    if (ordinal) {\n        formatTokenFunctions[ordinal] = function () {\n            return this.localeData().ordinal(func.apply(this, arguments), token);\n        };\n    }\n}\n\nfunction removeFormattingTokens(input) {\n    if (input.match(/\\[[\\s\\S]/)) {\n        return input.replace(/^\\[|\\]$/g, '');\n    }\n    return input.replace(/\\\\/g, '');\n}\n\nfunction makeFormatFunction(format) {\n    var array = format.match(formattingTokens), i, length;\n\n    for (i = 0, length = array.length; i < length; i++) {\n        if (formatTokenFunctions[array[i]]) {\n            array[i] = formatTokenFunctions[array[i]];\n        } else {\n            array[i] = removeFormattingTokens(array[i]);\n        }\n    }\n\n    return function (mom) {\n        var output = '', i;\n        for (i = 0; i < length; i++) {\n            output += isFunction(array[i]) ? array[i].call(mom, format) : array[i];\n        }\n        return output;\n    };\n}\n\n// format date using native date object\nexport function formatMoment(m, format) {\n    if (!m.isValid()) {\n        return m.localeData().invalidDate();\n    }\n\n    format = expandFormat(format, m.localeData());\n    formatFunctions[format] = formatFunctions[format] || makeFormatFunction(format);\n\n    return formatFunctions[format](m);\n}\n\nexport function expandFormat(format, locale) {\n    var i = 5;\n\n    function replaceLongDateFormatTokens(input) {\n        return locale.longDateFormat(input) || input;\n    }\n\n    localFormattingTokens.lastIndex = 0;\n    while (i >= 0 && localFormattingTokens.test(format)) {\n        format = format.replace(localFormattingTokens, replaceLongDateFormatTokens);\n        localFormattingTokens.lastIndex = 0;\n        i -= 1;\n    }\n\n    return format;\n}\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/lib/locale/base-config.js",
    "content": "import { defaultCalendar } from './calendar';\nimport { defaultLongDateFormat } from './formats';\nimport { defaultInvalidDate } from './invalid';\nimport { defaultOrdinal, defaultDayOfMonthOrdinalParse } from './ordinal';\nimport { defaultRelativeTime } from './relative';\n\n// months\nimport {\n    defaultLocaleMonths,\n    defaultLocaleMonthsShort,\n} from '../units/month';\n\n// week\nimport { defaultLocaleWeek } from '../units/week';\n\n// weekdays\nimport {\n    defaultLocaleWeekdays,\n    defaultLocaleWeekdaysMin,\n    defaultLocaleWeekdaysShort,\n} from '../units/day-of-week';\n\n// meridiem\nimport { defaultLocaleMeridiemParse } from '../units/hour';\n\nexport var baseConfig = {\n    calendar: defaultCalendar,\n    longDateFormat: defaultLongDateFormat,\n    invalidDate: defaultInvalidDate,\n    ordinal: defaultOrdinal,\n    dayOfMonthOrdinalParse: defaultDayOfMonthOrdinalParse,\n    relativeTime: defaultRelativeTime,\n\n    months: defaultLocaleMonths,\n    monthsShort: defaultLocaleMonthsShort,\n\n    week: defaultLocaleWeek,\n\n    weekdays: defaultLocaleWeekdays,\n    weekdaysMin: defaultLocaleWeekdaysMin,\n    weekdaysShort: defaultLocaleWeekdaysShort,\n\n    meridiemParse: defaultLocaleMeridiemParse\n};\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/lib/locale/calendar.js",
    "content": "export var defaultCalendar = {\n    sameDay : '[Today at] LT',\n    nextDay : '[Tomorrow at] LT',\n    nextWeek : 'dddd [at] LT',\n    lastDay : '[Yesterday at] LT',\n    lastWeek : '[Last] dddd [at] LT',\n    sameElse : 'L'\n};\n\nimport isFunction from '../utils/is-function';\n\nexport function calendar (key, mom, now) {\n    var output = this._calendar[key] || this._calendar['sameElse'];\n    return isFunction(output) ? output.call(mom, now) : output;\n}\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/lib/locale/constructor.js",
    "content": "export function Locale(config) {\n    if (config != null) {\n        this.set(config);\n    }\n}\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/lib/locale/en.js",
    "content": "import './prototype';\nimport { getSetGlobalLocale } from './locales';\nimport toInt from '../utils/to-int';\n\ngetSetGlobalLocale('en', {\n    dayOfMonthOrdinalParse: /\\d{1,2}(th|st|nd|rd)/,\n    ordinal : function (number) {\n        var b = number % 10,\n            output = (toInt(number % 100 / 10) === 1) ? 'th' :\n            (b === 1) ? 'st' :\n            (b === 2) ? 'nd' :\n            (b === 3) ? 'rd' : 'th';\n        return number + output;\n    }\n});\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/lib/locale/formats.js",
    "content": "export var defaultLongDateFormat = {\n    LTS  : 'h:mm:ss A',\n    LT   : 'h:mm A',\n    L    : 'MM/DD/YYYY',\n    LL   : 'MMMM D, YYYY',\n    LLL  : 'MMMM D, YYYY h:mm A',\n    LLLL : 'dddd, MMMM D, YYYY h:mm A'\n};\n\nexport function longDateFormat (key) {\n    var format = this._longDateFormat[key],\n        formatUpper = this._longDateFormat[key.toUpperCase()];\n\n    if (format || !formatUpper) {\n        return format;\n    }\n\n    this._longDateFormat[key] = formatUpper.replace(/MMMM|MM|DD|dddd/g, function (val) {\n        return val.slice(1);\n    });\n\n    return this._longDateFormat[key];\n}\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/lib/locale/invalid.js",
    "content": "export var defaultInvalidDate = 'Invalid date';\n\nexport function invalidDate () {\n    return this._invalidDate;\n}\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/lib/locale/lists.js",
    "content": "import isNumber from '../utils/is-number';\nimport { getLocale } from './locales';\nimport { createUTC } from '../create/utc';\n\nfunction get (format, index, field, setter) {\n    var locale = getLocale();\n    var utc = createUTC().set(setter, index);\n    return locale[field](utc, format);\n}\n\nfunction listMonthsImpl (format, index, field) {\n    if (isNumber(format)) {\n        index = format;\n        format = undefined;\n    }\n\n    format = format || '';\n\n    if (index != null) {\n        return get(format, index, field, 'month');\n    }\n\n    var i;\n    var out = [];\n    for (i = 0; i < 12; i++) {\n        out[i] = get(format, i, field, 'month');\n    }\n    return out;\n}\n\n// ()\n// (5)\n// (fmt, 5)\n// (fmt)\n// (true)\n// (true, 5)\n// (true, fmt, 5)\n// (true, fmt)\nfunction listWeekdaysImpl (localeSorted, format, index, field) {\n    if (typeof localeSorted === 'boolean') {\n        if (isNumber(format)) {\n            index = format;\n            format = undefined;\n        }\n\n        format = format || '';\n    } else {\n        format = localeSorted;\n        index = format;\n        localeSorted = false;\n\n        if (isNumber(format)) {\n            index = format;\n            format = undefined;\n        }\n\n        format = format || '';\n    }\n\n    var locale = getLocale(),\n        shift = localeSorted ? locale._week.dow : 0;\n\n    if (index != null) {\n        return get(format, (index + shift) % 7, field, 'day');\n    }\n\n    var i;\n    var out = [];\n    for (i = 0; i < 7; i++) {\n        out[i] = get(format, (i + shift) % 7, field, 'day');\n    }\n    return out;\n}\n\nexport function listMonths (format, index) {\n    return listMonthsImpl(format, index, 'months');\n}\n\nexport function listMonthsShort (format, index) {\n    return listMonthsImpl(format, index, 'monthsShort');\n}\n\nexport function listWeekdays (localeSorted, format, index) {\n    return listWeekdaysImpl(localeSorted, format, index, 'weekdays');\n}\n\nexport function listWeekdaysShort (localeSorted, format, index) {\n    return listWeekdaysImpl(localeSorted, format, index, 'weekdaysShort');\n}\n\nexport function listWeekdaysMin (localeSorted, format, index) {\n    return listWeekdaysImpl(localeSorted, format, index, 'weekdaysMin');\n}\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/lib/locale/locale.js",
    "content": "// Side effect imports\nimport './prototype';\n\nimport {\n    getSetGlobalLocale,\n    defineLocale,\n    updateLocale,\n    getLocale,\n    listLocales\n} from './locales';\n\nimport {\n    listMonths,\n    listMonthsShort,\n    listWeekdays,\n    listWeekdaysShort,\n    listWeekdaysMin\n} from './lists';\n\nexport {\n    getSetGlobalLocale,\n    defineLocale,\n    updateLocale,\n    getLocale,\n    listLocales,\n    listMonths,\n    listMonthsShort,\n    listWeekdays,\n    listWeekdaysShort,\n    listWeekdaysMin\n};\n\nimport { deprecate } from '../utils/deprecate';\nimport { hooks } from '../utils/hooks';\n\nhooks.lang = deprecate('moment.lang is deprecated. Use moment.locale instead.', getSetGlobalLocale);\nhooks.langData = deprecate('moment.langData is deprecated. Use moment.localeData instead.', getLocale);\n\nimport './en';\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/lib/locale/locales.js",
    "content": "import isArray from '../utils/is-array';\nimport hasOwnProp from '../utils/has-own-prop';\nimport isUndefined from '../utils/is-undefined';\nimport compareArrays from '../utils/compare-arrays';\nimport { deprecateSimple } from '../utils/deprecate';\nimport { mergeConfigs } from './set';\nimport { Locale } from './constructor';\nimport keys from '../utils/keys';\n\nimport { baseConfig } from './base-config';\n\n// internal storage for locale config files\nvar locales = {};\nvar localeFamilies = {};\nvar globalLocale;\n\nfunction normalizeLocale(key) {\n    return key ? key.toLowerCase().replace('_', '-') : key;\n}\n\n// pick the locale from the array\n// try ['en-au', 'en-gb'] as 'en-au', 'en-gb', 'en', as in move through the list trying each\n// substring from most specific to least, but move to the next array item if it's a more specific variant than the current root\nfunction chooseLocale(names) {\n    var i = 0, j, next, locale, split;\n\n    while (i < names.length) {\n        split = normalizeLocale(names[i]).split('-');\n        j = split.length;\n        next = normalizeLocale(names[i + 1]);\n        next = next ? next.split('-') : null;\n        while (j > 0) {\n            locale = loadLocale(split.slice(0, j).join('-'));\n            if (locale) {\n                return locale;\n            }\n            if (next && next.length >= j && compareArrays(split, next, true) >= j - 1) {\n                //the next array item is better than a shallower substring of this one\n                break;\n            }\n            j--;\n        }\n        i++;\n    }\n    return null;\n}\n\nfunction loadLocale(name) {\n    var oldLocale = null;\n    // TODO: Find a better way to register and load all the locales in Node\n    if (!locales[name] && (typeof module !== 'undefined') &&\n            module && module.exports) {\n        try {\n            oldLocale = globalLocale._abbr;\n            require('./locale/' + name);\n            // because defineLocale currently also sets the global locale, we\n            // want to undo that for lazy loaded locales\n            getSetGlobalLocale(oldLocale);\n        } catch (e) { }\n    }\n    return locales[name];\n}\n\n// This function will load locale and then set the global locale.  If\n// no arguments are passed in, it will simply return the current global\n// locale key.\nexport function getSetGlobalLocale (key, values) {\n    var data;\n    if (key) {\n        if (isUndefined(values)) {\n            data = getLocale(key);\n        }\n        else {\n            data = defineLocale(key, values);\n        }\n\n        if (data) {\n            // moment.duration._locale = moment._locale = data;\n            globalLocale = data;\n        }\n    }\n\n    return globalLocale._abbr;\n}\n\nexport function defineLocale (name, config) {\n    if (config !== null) {\n        var parentConfig = baseConfig;\n        config.abbr = name;\n        if (locales[name] != null) {\n            deprecateSimple('defineLocaleOverride',\n                    'use moment.updateLocale(localeName, config) to change ' +\n                    'an existing locale. moment.defineLocale(localeName, ' +\n                    'config) should only be used for creating a new locale ' +\n                    'See http://momentjs.com/guides/#/warnings/define-locale/ for more info.');\n            parentConfig = locales[name]._config;\n        } else if (config.parentLocale != null) {\n            if (locales[config.parentLocale] != null) {\n                parentConfig = locales[config.parentLocale]._config;\n            } else {\n                if (!localeFamilies[config.parentLocale]) {\n                    localeFamilies[config.parentLocale] = [];\n                }\n                localeFamilies[config.parentLocale].push({\n                    name: name,\n                    config: config\n                });\n                return null;\n            }\n        }\n        locales[name] = new Locale(mergeConfigs(parentConfig, config));\n\n        if (localeFamilies[name]) {\n            localeFamilies[name].forEach(function (x) {\n                defineLocale(x.name, x.config);\n            });\n        }\n\n        // backwards compat for now: also set the locale\n        // make sure we set the locale AFTER all child locales have been\n        // created, so we won't end up with the child locale set.\n        getSetGlobalLocale(name);\n\n\n        return locales[name];\n    } else {\n        // useful for testing\n        delete locales[name];\n        return null;\n    }\n}\n\nexport function updateLocale(name, config) {\n    if (config != null) {\n        var locale, parentConfig = baseConfig;\n        // MERGE\n        if (locales[name] != null) {\n            parentConfig = locales[name]._config;\n        }\n        config = mergeConfigs(parentConfig, config);\n        locale = new Locale(config);\n        locale.parentLocale = locales[name];\n        locales[name] = locale;\n\n        // backwards compat for now: also set the locale\n        getSetGlobalLocale(name);\n    } else {\n        // pass null for config to unupdate, useful for tests\n        if (locales[name] != null) {\n            if (locales[name].parentLocale != null) {\n                locales[name] = locales[name].parentLocale;\n            } else if (locales[name] != null) {\n                delete locales[name];\n            }\n        }\n    }\n    return locales[name];\n}\n\n// returns locale data\nexport function getLocale (key) {\n    var locale;\n\n    if (key && key._locale && key._locale._abbr) {\n        key = key._locale._abbr;\n    }\n\n    if (!key) {\n        return globalLocale;\n    }\n\n    if (!isArray(key)) {\n        //short-circuit everything else\n        locale = loadLocale(key);\n        if (locale) {\n            return locale;\n        }\n        key = [key];\n    }\n\n    return chooseLocale(key);\n}\n\nexport function listLocales() {\n    return keys(locales);\n}\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/lib/locale/ordinal.js",
    "content": "export var defaultOrdinal = '%d';\nexport var defaultDayOfMonthOrdinalParse = /\\d{1,2}/;\n\nexport function ordinal (number) {\n    return this._ordinal.replace('%d', number);\n}\n\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/lib/locale/pre-post-format.js",
    "content": "export function preParsePostFormat (string) {\n    return string;\n}\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/lib/locale/prototype.js",
    "content": "import { Locale } from './constructor';\n\nvar proto = Locale.prototype;\n\nimport { calendar } from './calendar';\nimport { longDateFormat } from './formats';\nimport { invalidDate } from './invalid';\nimport { ordinal } from './ordinal';\nimport { preParsePostFormat } from './pre-post-format';\nimport { relativeTime, pastFuture } from './relative';\nimport { set } from './set';\n\nproto.calendar        = calendar;\nproto.longDateFormat  = longDateFormat;\nproto.invalidDate     = invalidDate;\nproto.ordinal         = ordinal;\nproto.preparse        = preParsePostFormat;\nproto.postformat      = preParsePostFormat;\nproto.relativeTime    = relativeTime;\nproto.pastFuture      = pastFuture;\nproto.set             = set;\n\n// Month\nimport {\n    localeMonthsParse,\n    localeMonths,\n    localeMonthsShort,\n    monthsRegex,\n    monthsShortRegex\n} from '../units/month';\n\nproto.months            =        localeMonths;\nproto.monthsShort       =        localeMonthsShort;\nproto.monthsParse       =        localeMonthsParse;\nproto.monthsRegex       = monthsRegex;\nproto.monthsShortRegex  = monthsShortRegex;\n\n// Week\nimport { localeWeek, localeFirstDayOfYear, localeFirstDayOfWeek } from '../units/week';\nproto.week = localeWeek;\nproto.firstDayOfYear = localeFirstDayOfYear;\nproto.firstDayOfWeek = localeFirstDayOfWeek;\n\n// Day of Week\nimport {\n    localeWeekdaysParse,\n    localeWeekdays,\n    localeWeekdaysMin,\n    localeWeekdaysShort,\n\n    weekdaysRegex,\n    weekdaysShortRegex,\n    weekdaysMinRegex\n} from '../units/day-of-week';\n\nproto.weekdays       =        localeWeekdays;\nproto.weekdaysMin    =        localeWeekdaysMin;\nproto.weekdaysShort  =        localeWeekdaysShort;\nproto.weekdaysParse  =        localeWeekdaysParse;\n\nproto.weekdaysRegex       =        weekdaysRegex;\nproto.weekdaysShortRegex  =        weekdaysShortRegex;\nproto.weekdaysMinRegex    =        weekdaysMinRegex;\n\n// Hours\nimport { localeIsPM, localeMeridiem } from '../units/hour';\n\nproto.isPM = localeIsPM;\nproto.meridiem = localeMeridiem;\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/lib/locale/relative.js",
    "content": "export var defaultRelativeTime = {\n    future : 'in %s',\n    past   : '%s ago',\n    s  : 'a few seconds',\n    ss : '%d seconds',\n    m  : 'a minute',\n    mm : '%d minutes',\n    h  : 'an hour',\n    hh : '%d hours',\n    d  : 'a day',\n    dd : '%d days',\n    M  : 'a month',\n    MM : '%d months',\n    y  : 'a year',\n    yy : '%d years'\n};\n\nimport isFunction from '../utils/is-function';\n\nexport function relativeTime (number, withoutSuffix, string, isFuture) {\n    var output = this._relativeTime[string];\n    return (isFunction(output)) ?\n        output(number, withoutSuffix, string, isFuture) :\n        output.replace(/%d/i, number);\n}\n\nexport function pastFuture (diff, output) {\n    var format = this._relativeTime[diff > 0 ? 'future' : 'past'];\n    return isFunction(format) ? format(output) : format.replace(/%s/i, output);\n}\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/lib/locale/set.js",
    "content": "import isFunction from '../utils/is-function';\nimport extend from '../utils/extend';\nimport isObject from '../utils/is-object';\nimport hasOwnProp from '../utils/has-own-prop';\n\nexport function set (config) {\n    var prop, i;\n    for (i in config) {\n        prop = config[i];\n        if (isFunction(prop)) {\n            this[i] = prop;\n        } else {\n            this['_' + i] = prop;\n        }\n    }\n    this._config = config;\n    // Lenient ordinal parsing accepts just a number in addition to\n    // number + (possibly) stuff coming from _dayOfMonthOrdinalParse.\n    // TODO: Remove \"ordinalParse\" fallback in next major release.\n    this._dayOfMonthOrdinalParseLenient = new RegExp(\n        (this._dayOfMonthOrdinalParse.source || this._ordinalParse.source) +\n            '|' + (/\\d{1,2}/).source);\n}\n\nexport function mergeConfigs(parentConfig, childConfig) {\n    var res = extend({}, parentConfig), prop;\n    for (prop in childConfig) {\n        if (hasOwnProp(childConfig, prop)) {\n            if (isObject(parentConfig[prop]) && isObject(childConfig[prop])) {\n                res[prop] = {};\n                extend(res[prop], parentConfig[prop]);\n                extend(res[prop], childConfig[prop]);\n            } else if (childConfig[prop] != null) {\n                res[prop] = childConfig[prop];\n            } else {\n                delete res[prop];\n            }\n        }\n    }\n    for (prop in parentConfig) {\n        if (hasOwnProp(parentConfig, prop) &&\n                !hasOwnProp(childConfig, prop) &&\n                isObject(parentConfig[prop])) {\n            // make sure changes to properties don't modify parent config\n            res[prop] = extend({}, res[prop]);\n        }\n    }\n    return res;\n}\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/lib/moment/add-subtract.js",
    "content": "import { get, set } from './get-set';\nimport { setMonth } from '../units/month';\nimport { createDuration } from '../duration/create';\nimport { deprecateSimple } from '../utils/deprecate';\nimport { hooks } from '../utils/hooks';\nimport absRound from '../utils/abs-round';\n\n\n// TODO: remove 'name' arg after deprecation is removed\nfunction createAdder(direction, name) {\n    return function (val, period) {\n        var dur, tmp;\n        //invert the arguments, but complain about it\n        if (period !== null && !isNaN(+period)) {\n            deprecateSimple(name, 'moment().' + name  + '(period, number) is deprecated. Please use moment().' + name + '(number, period). ' +\n            'See http://momentjs.com/guides/#/warnings/add-inverted-param/ for more info.');\n            tmp = val; val = period; period = tmp;\n        }\n\n        val = typeof val === 'string' ? +val : val;\n        dur = createDuration(val, period);\n        addSubtract(this, dur, direction);\n        return this;\n    };\n}\n\nexport function addSubtract (mom, duration, isAdding, updateOffset) {\n    var milliseconds = duration._milliseconds,\n        days = absRound(duration._days),\n        months = absRound(duration._months);\n\n    if (!mom.isValid()) {\n        // No op\n        return;\n    }\n\n    updateOffset = updateOffset == null ? true : updateOffset;\n\n    if (milliseconds) {\n        mom._d.setTime(mom._d.valueOf() + milliseconds * isAdding);\n    }\n    if (days) {\n        set(mom, 'Date', get(mom, 'Date') + days * isAdding);\n    }\n    if (months) {\n        setMonth(mom, get(mom, 'Month') + months * isAdding);\n    }\n    if (updateOffset) {\n        hooks.updateOffset(mom, days || months);\n    }\n}\n\nexport var add      = createAdder(1, 'add');\nexport var subtract = createAdder(-1, 'subtract');\n\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/lib/moment/calendar.js",
    "content": "import { createLocal } from '../create/local';\nimport { cloneWithOffset } from '../units/offset';\nimport isFunction from '../utils/is-function';\nimport { hooks } from '../utils/hooks';\n\nexport function getCalendarFormat(myMoment, now) {\n    var diff = myMoment.diff(now, 'days', true);\n    return diff < -6 ? 'sameElse' :\n            diff < -1 ? 'lastWeek' :\n            diff < 0 ? 'lastDay' :\n            diff < 1 ? 'sameDay' :\n            diff < 2 ? 'nextDay' :\n            diff < 7 ? 'nextWeek' : 'sameElse';\n}\n\nexport function calendar (time, formats) {\n    // We want to compare the start of today, vs this.\n    // Getting start-of-today depends on whether we're local/utc/offset or not.\n    var now = time || createLocal(),\n        sod = cloneWithOffset(now, this).startOf('day'),\n        format = hooks.calendarFormat(this, sod) || 'sameElse';\n\n    var output = formats && (isFunction(formats[format]) ? formats[format].call(this, now) : formats[format]);\n\n    return this.format(output || this.localeData().calendar(format, this, createLocal(now)));\n}\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/lib/moment/clone.js",
    "content": "import { Moment } from './constructor';\n\nexport function clone () {\n    return new Moment(this);\n}\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/lib/moment/compare.js",
    "content": "import { isMoment } from './constructor';\nimport { normalizeUnits } from '../units/aliases';\nimport { createLocal } from '../create/local';\nimport isUndefined from '../utils/is-undefined';\n\nexport function isAfter (input, units) {\n    var localInput = isMoment(input) ? input : createLocal(input);\n    if (!(this.isValid() && localInput.isValid())) {\n        return false;\n    }\n    units = normalizeUnits(!isUndefined(units) ? units : 'millisecond');\n    if (units === 'millisecond') {\n        return this.valueOf() > localInput.valueOf();\n    } else {\n        return localInput.valueOf() < this.clone().startOf(units).valueOf();\n    }\n}\n\nexport function isBefore (input, units) {\n    var localInput = isMoment(input) ? input : createLocal(input);\n    if (!(this.isValid() && localInput.isValid())) {\n        return false;\n    }\n    units = normalizeUnits(!isUndefined(units) ? units : 'millisecond');\n    if (units === 'millisecond') {\n        return this.valueOf() < localInput.valueOf();\n    } else {\n        return this.clone().endOf(units).valueOf() < localInput.valueOf();\n    }\n}\n\nexport function isBetween (from, to, units, inclusivity) {\n    inclusivity = inclusivity || '()';\n    return (inclusivity[0] === '(' ? this.isAfter(from, units) : !this.isBefore(from, units)) &&\n        (inclusivity[1] === ')' ? this.isBefore(to, units) : !this.isAfter(to, units));\n}\n\nexport function isSame (input, units) {\n    var localInput = isMoment(input) ? input : createLocal(input),\n        inputMs;\n    if (!(this.isValid() && localInput.isValid())) {\n        return false;\n    }\n    units = normalizeUnits(units || 'millisecond');\n    if (units === 'millisecond') {\n        return this.valueOf() === localInput.valueOf();\n    } else {\n        inputMs = localInput.valueOf();\n        return this.clone().startOf(units).valueOf() <= inputMs && inputMs <= this.clone().endOf(units).valueOf();\n    }\n}\n\nexport function isSameOrAfter (input, units) {\n    return this.isSame(input, units) || this.isAfter(input,units);\n}\n\nexport function isSameOrBefore (input, units) {\n    return this.isSame(input, units) || this.isBefore(input,units);\n}\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/lib/moment/constructor.js",
    "content": "import { hooks } from '../utils/hooks';\nimport hasOwnProp from '../utils/has-own-prop';\nimport isUndefined from '../utils/is-undefined';\nimport getParsingFlags from '../create/parsing-flags';\n\n// Plugins that add properties should also add the key here (null value),\n// so we can properly clone ourselves.\nvar momentProperties = hooks.momentProperties = [];\n\nexport function copyConfig(to, from) {\n    var i, prop, val;\n\n    if (!isUndefined(from._isAMomentObject)) {\n        to._isAMomentObject = from._isAMomentObject;\n    }\n    if (!isUndefined(from._i)) {\n        to._i = from._i;\n    }\n    if (!isUndefined(from._f)) {\n        to._f = from._f;\n    }\n    if (!isUndefined(from._l)) {\n        to._l = from._l;\n    }\n    if (!isUndefined(from._strict)) {\n        to._strict = from._strict;\n    }\n    if (!isUndefined(from._tzm)) {\n        to._tzm = from._tzm;\n    }\n    if (!isUndefined(from._isUTC)) {\n        to._isUTC = from._isUTC;\n    }\n    if (!isUndefined(from._offset)) {\n        to._offset = from._offset;\n    }\n    if (!isUndefined(from._pf)) {\n        to._pf = getParsingFlags(from);\n    }\n    if (!isUndefined(from._locale)) {\n        to._locale = from._locale;\n    }\n\n    if (momentProperties.length > 0) {\n        for (i = 0; i < momentProperties.length; i++) {\n            prop = momentProperties[i];\n            val = from[prop];\n            if (!isUndefined(val)) {\n                to[prop] = val;\n            }\n        }\n    }\n\n    return to;\n}\n\nvar updateInProgress = false;\n\n// Moment prototype object\nexport function Moment(config) {\n    copyConfig(this, config);\n    this._d = new Date(config._d != null ? config._d.getTime() : NaN);\n    if (!this.isValid()) {\n        this._d = new Date(NaN);\n    }\n    // Prevent infinite loop in case updateOffset creates new moment\n    // objects.\n    if (updateInProgress === false) {\n        updateInProgress = true;\n        hooks.updateOffset(this);\n        updateInProgress = false;\n    }\n}\n\nexport function isMoment (obj) {\n    return obj instanceof Moment || (obj != null && obj._isAMomentObject != null);\n}\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/lib/moment/creation-data.js",
    "content": "export function creationData() {\n    return {\n        input: this._i,\n        format: this._f,\n        locale: this._locale,\n        isUTC: this._isUTC,\n        strict: this._strict\n    };\n}\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/lib/moment/diff.js",
    "content": "import absFloor from '../utils/abs-floor';\nimport { cloneWithOffset } from '../units/offset';\nimport { normalizeUnits } from '../units/aliases';\n\nexport function diff (input, units, asFloat) {\n    var that,\n        zoneDelta,\n        delta, output;\n\n    if (!this.isValid()) {\n        return NaN;\n    }\n\n    that = cloneWithOffset(input, this);\n\n    if (!that.isValid()) {\n        return NaN;\n    }\n\n    zoneDelta = (that.utcOffset() - this.utcOffset()) * 6e4;\n\n    units = normalizeUnits(units);\n\n    if (units === 'year' || units === 'month' || units === 'quarter') {\n        output = monthDiff(this, that);\n        if (units === 'quarter') {\n            output = output / 3;\n        } else if (units === 'year') {\n            output = output / 12;\n        }\n    } else {\n        delta = this - that;\n        output = units === 'second' ? delta / 1e3 : // 1000\n            units === 'minute' ? delta / 6e4 : // 1000 * 60\n            units === 'hour' ? delta / 36e5 : // 1000 * 60 * 60\n            units === 'day' ? (delta - zoneDelta) / 864e5 : // 1000 * 60 * 60 * 24, negate dst\n            units === 'week' ? (delta - zoneDelta) / 6048e5 : // 1000 * 60 * 60 * 24 * 7, negate dst\n            delta;\n    }\n    return asFloat ? output : absFloor(output);\n}\n\nfunction monthDiff (a, b) {\n    // difference in months\n    var wholeMonthDiff = ((b.year() - a.year()) * 12) + (b.month() - a.month()),\n        // b is in (anchor - 1 month, anchor + 1 month)\n        anchor = a.clone().add(wholeMonthDiff, 'months'),\n        anchor2, adjust;\n\n    if (b - anchor < 0) {\n        anchor2 = a.clone().add(wholeMonthDiff - 1, 'months');\n        // linear across the month\n        adjust = (b - anchor) / (anchor - anchor2);\n    } else {\n        anchor2 = a.clone().add(wholeMonthDiff + 1, 'months');\n        // linear across the month\n        adjust = (b - anchor) / (anchor2 - anchor);\n    }\n\n    //check for negative zero, return zero if negative zero\n    return -(wholeMonthDiff + adjust) || 0;\n}\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/lib/moment/format.js",
    "content": "import { formatMoment } from '../format/format';\nimport { hooks } from '../utils/hooks';\nimport isFunction from '../utils/is-function';\n\nhooks.defaultFormat = 'YYYY-MM-DDTHH:mm:ssZ';\nhooks.defaultFormatUtc = 'YYYY-MM-DDTHH:mm:ss[Z]';\n\nexport function toString () {\n    return this.clone().locale('en').format('ddd MMM DD YYYY HH:mm:ss [GMT]ZZ');\n}\n\nexport function toISOString() {\n    if (!this.isValid()) {\n        return null;\n    }\n    var m = this.clone().utc();\n    if (m.year() < 0 || m.year() > 9999) {\n        return formatMoment(m, 'YYYYYY-MM-DD[T]HH:mm:ss.SSS[Z]');\n    }\n    if (isFunction(Date.prototype.toISOString)) {\n        // native implementation is ~50x faster, use it when we can\n        return this.toDate().toISOString();\n    }\n    return formatMoment(m, 'YYYY-MM-DD[T]HH:mm:ss.SSS[Z]');\n}\n\n/**\n * Return a human readable representation of a moment that can\n * also be evaluated to get a new moment which is the same\n *\n * @link https://nodejs.org/dist/latest/docs/api/util.html#util_custom_inspect_function_on_objects\n */\nexport function inspect () {\n    if (!this.isValid()) {\n        return 'moment.invalid(/* ' + this._i + ' */)';\n    }\n    var func = 'moment';\n    var zone = '';\n    if (!this.isLocal()) {\n        func = this.utcOffset() === 0 ? 'moment.utc' : 'moment.parseZone';\n        zone = 'Z';\n    }\n    var prefix = '[' + func + '(\"]';\n    var year = (0 <= this.year() && this.year() <= 9999) ? 'YYYY' : 'YYYYYY';\n    var datetime = '-MM-DD[T]HH:mm:ss.SSS';\n    var suffix = zone + '[\")]';\n\n    return this.format(prefix + year + datetime + suffix);\n}\n\nexport function format (inputString) {\n    if (!inputString) {\n        inputString = this.isUtc() ? hooks.defaultFormatUtc : hooks.defaultFormat;\n    }\n    var output = formatMoment(this, inputString);\n    return this.localeData().postformat(output);\n}\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/lib/moment/from.js",
    "content": "import { createDuration } from '../duration/create';\nimport { createLocal } from '../create/local';\nimport { isMoment } from '../moment/constructor';\n\nexport function from (time, withoutSuffix) {\n    if (this.isValid() &&\n            ((isMoment(time) && time.isValid()) ||\n             createLocal(time).isValid())) {\n        return createDuration({to: this, from: time}).locale(this.locale()).humanize(!withoutSuffix);\n    } else {\n        return this.localeData().invalidDate();\n    }\n}\n\nexport function fromNow (withoutSuffix) {\n    return this.from(createLocal(), withoutSuffix);\n}\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/lib/moment/get-set.js",
    "content": "import { normalizeUnits, normalizeObjectUnits } from '../units/aliases';\nimport { getPrioritizedUnits } from '../units/priorities';\nimport { hooks } from '../utils/hooks';\nimport isFunction from '../utils/is-function';\n\n\nexport function makeGetSet (unit, keepTime) {\n    return function (value) {\n        if (value != null) {\n            set(this, unit, value);\n            hooks.updateOffset(this, keepTime);\n            return this;\n        } else {\n            return get(this, unit);\n        }\n    };\n}\n\nexport function get (mom, unit) {\n    return mom.isValid() ?\n        mom._d['get' + (mom._isUTC ? 'UTC' : '') + unit]() : NaN;\n}\n\nexport function set (mom, unit, value) {\n    if (mom.isValid()) {\n        mom._d['set' + (mom._isUTC ? 'UTC' : '') + unit](value);\n    }\n}\n\n// MOMENTS\n\nexport function stringGet (units) {\n    units = normalizeUnits(units);\n    if (isFunction(this[units])) {\n        return this[units]();\n    }\n    return this;\n}\n\n\nexport function stringSet (units, value) {\n    if (typeof units === 'object') {\n        units = normalizeObjectUnits(units);\n        var prioritized = getPrioritizedUnits(units);\n        for (var i = 0; i < prioritized.length; i++) {\n            this[prioritized[i].unit](units[prioritized[i].unit]);\n        }\n    } else {\n        units = normalizeUnits(units);\n        if (isFunction(this[units])) {\n            return this[units](value);\n        }\n    }\n    return this;\n}\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/lib/moment/locale.js",
    "content": "import { getLocale } from '../locale/locales';\nimport { deprecate } from '../utils/deprecate';\n\n// If passed a locale key, it will set the locale for this\n// instance.  Otherwise, it will return the locale configuration\n// variables for this instance.\nexport function locale (key) {\n    var newLocaleData;\n\n    if (key === undefined) {\n        return this._locale._abbr;\n    } else {\n        newLocaleData = getLocale(key);\n        if (newLocaleData != null) {\n            this._locale = newLocaleData;\n        }\n        return this;\n    }\n}\n\nexport var lang = deprecate(\n    'moment().lang() is deprecated. Instead, use moment().localeData() to get the language configuration. Use moment().locale() to change languages.',\n    function (key) {\n        if (key === undefined) {\n            return this.localeData();\n        } else {\n            return this.locale(key);\n        }\n    }\n);\n\nexport function localeData () {\n    return this._locale;\n}\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/lib/moment/min-max.js",
    "content": "import { deprecate } from '../utils/deprecate';\nimport isArray from '../utils/is-array';\nimport { createLocal } from '../create/local';\nimport { createInvalid } from '../create/valid';\n\nexport var prototypeMin = deprecate(\n    'moment().min is deprecated, use moment.max instead. http://momentjs.com/guides/#/warnings/min-max/',\n    function () {\n        var other = createLocal.apply(null, arguments);\n        if (this.isValid() && other.isValid()) {\n            return other < this ? this : other;\n        } else {\n            return createInvalid();\n        }\n    }\n);\n\nexport var prototypeMax = deprecate(\n    'moment().max is deprecated, use moment.min instead. http://momentjs.com/guides/#/warnings/min-max/',\n    function () {\n        var other = createLocal.apply(null, arguments);\n        if (this.isValid() && other.isValid()) {\n            return other > this ? this : other;\n        } else {\n            return createInvalid();\n        }\n    }\n);\n\n// Pick a moment m from moments so that m[fn](other) is true for all\n// other. This relies on the function fn to be transitive.\n//\n// moments should either be an array of moment objects or an array, whose\n// first element is an array of moment objects.\nfunction pickBy(fn, moments) {\n    var res, i;\n    if (moments.length === 1 && isArray(moments[0])) {\n        moments = moments[0];\n    }\n    if (!moments.length) {\n        return createLocal();\n    }\n    res = moments[0];\n    for (i = 1; i < moments.length; ++i) {\n        if (!moments[i].isValid() || moments[i][fn](res)) {\n            res = moments[i];\n        }\n    }\n    return res;\n}\n\n// TODO: Use [].sort instead?\nexport function min () {\n    var args = [].slice.call(arguments, 0);\n\n    return pickBy('isBefore', args);\n}\n\nexport function max () {\n    var args = [].slice.call(arguments, 0);\n\n    return pickBy('isAfter', args);\n}\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/lib/moment/moment.js",
    "content": "import { createLocal } from '../create/local';\nimport { createUTC } from '../create/utc';\nimport { createInvalid } from '../create/valid';\nimport { isMoment } from './constructor';\nimport { min, max } from './min-max';\nimport { now } from './now';\nimport momentPrototype from './prototype';\n\nfunction createUnix (input) {\n    return createLocal(input * 1000);\n}\n\nfunction createInZone () {\n    return createLocal.apply(null, arguments).parseZone();\n}\n\nexport {\n    now,\n    min,\n    max,\n    isMoment,\n    createUTC,\n    createUnix,\n    createLocal,\n    createInZone,\n    createInvalid,\n    momentPrototype\n};\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/lib/moment/now.js",
    "content": "export var now = function () {\n    return Date.now ? Date.now() : +(new Date());\n};\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/lib/moment/prototype.js",
    "content": "import { Moment } from './constructor';\n\nvar proto = Moment.prototype;\n\nimport { add, subtract } from './add-subtract';\nimport { calendar, getCalendarFormat } from './calendar';\nimport { clone } from './clone';\nimport { isBefore, isBetween, isSame, isAfter, isSameOrAfter, isSameOrBefore } from './compare';\nimport { diff } from './diff';\nimport { format, toString, toISOString, inspect } from './format';\nimport { from, fromNow } from './from';\nimport { to, toNow } from './to';\nimport { stringGet, stringSet } from './get-set';\nimport { locale, localeData, lang } from './locale';\nimport { prototypeMin, prototypeMax } from './min-max';\nimport { startOf, endOf } from './start-end-of';\nimport { valueOf, toDate, toArray, toObject, toJSON, unix } from './to-type';\nimport { isValid, parsingFlags, invalidAt } from './valid';\nimport { creationData } from './creation-data';\n\nproto.add               = add;\nproto.calendar          = calendar;\nproto.clone             = clone;\nproto.diff              = diff;\nproto.endOf             = endOf;\nproto.format            = format;\nproto.from              = from;\nproto.fromNow           = fromNow;\nproto.to                = to;\nproto.toNow             = toNow;\nproto.get               = stringGet;\nproto.invalidAt         = invalidAt;\nproto.isAfter           = isAfter;\nproto.isBefore          = isBefore;\nproto.isBetween         = isBetween;\nproto.isSame            = isSame;\nproto.isSameOrAfter     = isSameOrAfter;\nproto.isSameOrBefore    = isSameOrBefore;\nproto.isValid           = isValid;\nproto.lang              = lang;\nproto.locale            = locale;\nproto.localeData        = localeData;\nproto.max               = prototypeMax;\nproto.min               = prototypeMin;\nproto.parsingFlags      = parsingFlags;\nproto.set               = stringSet;\nproto.startOf           = startOf;\nproto.subtract          = subtract;\nproto.toArray           = toArray;\nproto.toObject          = toObject;\nproto.toDate            = toDate;\nproto.toISOString       = toISOString;\nproto.inspect           = inspect;\nproto.toJSON            = toJSON;\nproto.toString          = toString;\nproto.unix              = unix;\nproto.valueOf           = valueOf;\nproto.creationData      = creationData;\n\n// Year\nimport { getSetYear, getIsLeapYear } from '../units/year';\nproto.year       = getSetYear;\nproto.isLeapYear = getIsLeapYear;\n\n// Week Year\nimport { getSetWeekYear, getSetISOWeekYear, getWeeksInYear, getISOWeeksInYear } from '../units/week-year';\nproto.weekYear    = getSetWeekYear;\nproto.isoWeekYear = getSetISOWeekYear;\n\n// Quarter\nimport { getSetQuarter } from '../units/quarter';\nproto.quarter = proto.quarters = getSetQuarter;\n\n// Month\nimport { getSetMonth, getDaysInMonth } from '../units/month';\nproto.month       = getSetMonth;\nproto.daysInMonth = getDaysInMonth;\n\n// Week\nimport { getSetWeek, getSetISOWeek } from '../units/week';\nproto.week           = proto.weeks        = getSetWeek;\nproto.isoWeek        = proto.isoWeeks     = getSetISOWeek;\nproto.weeksInYear    = getWeeksInYear;\nproto.isoWeeksInYear = getISOWeeksInYear;\n\n// Day\nimport { getSetDayOfMonth } from '../units/day-of-month';\nimport { getSetDayOfWeek, getSetISODayOfWeek, getSetLocaleDayOfWeek } from '../units/day-of-week';\nimport { getSetDayOfYear } from '../units/day-of-year';\nproto.date       = getSetDayOfMonth;\nproto.day        = proto.days             = getSetDayOfWeek;\nproto.weekday    = getSetLocaleDayOfWeek;\nproto.isoWeekday = getSetISODayOfWeek;\nproto.dayOfYear  = getSetDayOfYear;\n\n// Hour\nimport { getSetHour } from '../units/hour';\nproto.hour = proto.hours = getSetHour;\n\n// Minute\nimport { getSetMinute } from '../units/minute';\nproto.minute = proto.minutes = getSetMinute;\n\n// Second\nimport { getSetSecond } from '../units/second';\nproto.second = proto.seconds = getSetSecond;\n\n// Millisecond\nimport { getSetMillisecond } from '../units/millisecond';\nproto.millisecond = proto.milliseconds = getSetMillisecond;\n\n// Offset\nimport {\n    getSetOffset,\n    setOffsetToUTC,\n    setOffsetToLocal,\n    setOffsetToParsedOffset,\n    hasAlignedHourOffset,\n    isDaylightSavingTime,\n    isDaylightSavingTimeShifted,\n    getSetZone,\n    isLocal,\n    isUtcOffset,\n    isUtc\n} from '../units/offset';\nproto.utcOffset            = getSetOffset;\nproto.utc                  = setOffsetToUTC;\nproto.local                = setOffsetToLocal;\nproto.parseZone            = setOffsetToParsedOffset;\nproto.hasAlignedHourOffset = hasAlignedHourOffset;\nproto.isDST                = isDaylightSavingTime;\nproto.isLocal              = isLocal;\nproto.isUtcOffset          = isUtcOffset;\nproto.isUtc                = isUtc;\nproto.isUTC                = isUtc;\n\n// Timezone\nimport { getZoneAbbr, getZoneName } from '../units/timezone';\nproto.zoneAbbr = getZoneAbbr;\nproto.zoneName = getZoneName;\n\n// Deprecations\nimport { deprecate } from '../utils/deprecate';\nproto.dates  = deprecate('dates accessor is deprecated. Use date instead.', getSetDayOfMonth);\nproto.months = deprecate('months accessor is deprecated. Use month instead', getSetMonth);\nproto.years  = deprecate('years accessor is deprecated. Use year instead', getSetYear);\nproto.zone   = deprecate('moment().zone is deprecated, use moment().utcOffset instead. http://momentjs.com/guides/#/warnings/zone/', getSetZone);\nproto.isDSTShifted = deprecate('isDSTShifted is deprecated. See http://momentjs.com/guides/#/warnings/dst-shifted/ for more information', isDaylightSavingTimeShifted);\n\nexport default proto;\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/lib/moment/start-end-of.js",
    "content": "import { normalizeUnits } from '../units/aliases';\n\nexport function startOf (units) {\n    units = normalizeUnits(units);\n    // the following switch intentionally omits break keywords\n    // to utilize falling through the cases.\n    switch (units) {\n        case 'year':\n            this.month(0);\n            /* falls through */\n        case 'quarter':\n        case 'month':\n            this.date(1);\n            /* falls through */\n        case 'week':\n        case 'isoWeek':\n        case 'day':\n        case 'date':\n            this.hours(0);\n            /* falls through */\n        case 'hour':\n            this.minutes(0);\n            /* falls through */\n        case 'minute':\n            this.seconds(0);\n            /* falls through */\n        case 'second':\n            this.milliseconds(0);\n    }\n\n    // weeks are a special case\n    if (units === 'week') {\n        this.weekday(0);\n    }\n    if (units === 'isoWeek') {\n        this.isoWeekday(1);\n    }\n\n    // quarters are also special\n    if (units === 'quarter') {\n        this.month(Math.floor(this.month() / 3) * 3);\n    }\n\n    return this;\n}\n\nexport function endOf (units) {\n    units = normalizeUnits(units);\n    if (units === undefined || units === 'millisecond') {\n        return this;\n    }\n\n    // 'date' is an alias for 'day', so it should be considered as such.\n    if (units === 'date') {\n        units = 'day';\n    }\n\n    return this.startOf(units).add(1, (units === 'isoWeek' ? 'week' : units)).subtract(1, 'ms');\n}\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/lib/moment/to-type.js",
    "content": "export function valueOf () {\n    return this._d.valueOf() - ((this._offset || 0) * 60000);\n}\n\nexport function unix () {\n    return Math.floor(this.valueOf() / 1000);\n}\n\nexport function toDate () {\n    return new Date(this.valueOf());\n}\n\nexport function toArray () {\n    var m = this;\n    return [m.year(), m.month(), m.date(), m.hour(), m.minute(), m.second(), m.millisecond()];\n}\n\nexport function toObject () {\n    var m = this;\n    return {\n        years: m.year(),\n        months: m.month(),\n        date: m.date(),\n        hours: m.hours(),\n        minutes: m.minutes(),\n        seconds: m.seconds(),\n        milliseconds: m.milliseconds()\n    };\n}\n\nexport function toJSON () {\n    // new Date(NaN).toJSON() === null\n    return this.isValid() ? this.toISOString() : null;\n}\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/lib/moment/to.js",
    "content": "import { createDuration } from '../duration/create';\nimport { createLocal } from '../create/local';\nimport { isMoment } from '../moment/constructor';\n\nexport function to (time, withoutSuffix) {\n    if (this.isValid() &&\n            ((isMoment(time) && time.isValid()) ||\n             createLocal(time).isValid())) {\n        return createDuration({from: this, to: time}).locale(this.locale()).humanize(!withoutSuffix);\n    } else {\n        return this.localeData().invalidDate();\n    }\n}\n\nexport function toNow (withoutSuffix) {\n    return this.to(createLocal(), withoutSuffix);\n}\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/lib/moment/valid.js",
    "content": "import { isValid as _isValid } from '../create/valid';\nimport extend from '../utils/extend';\nimport getParsingFlags from '../create/parsing-flags';\n\nexport function isValid () {\n    return _isValid(this);\n}\n\nexport function parsingFlags () {\n    return extend({}, getParsingFlags(this));\n}\n\nexport function invalidAt () {\n    return getParsingFlags(this).overflow;\n}\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/lib/parse/regex.js",
    "content": "export var match1         = /\\d/;            //       0 - 9\nexport var match2         = /\\d\\d/;          //      00 - 99\nexport var match3         = /\\d{3}/;         //     000 - 999\nexport var match4         = /\\d{4}/;         //    0000 - 9999\nexport var match6         = /[+-]?\\d{6}/;    // -999999 - 999999\nexport var match1to2      = /\\d\\d?/;         //       0 - 99\nexport var match3to4      = /\\d\\d\\d\\d?/;     //     999 - 9999\nexport var match5to6      = /\\d\\d\\d\\d\\d\\d?/; //   99999 - 999999\nexport var match1to3      = /\\d{1,3}/;       //       0 - 999\nexport var match1to4      = /\\d{1,4}/;       //       0 - 9999\nexport var match1to6      = /[+-]?\\d{1,6}/;  // -999999 - 999999\n\nexport var matchUnsigned  = /\\d+/;           //       0 - inf\nexport var matchSigned    = /[+-]?\\d+/;      //    -inf - inf\n\nexport var matchOffset    = /Z|[+-]\\d\\d:?\\d\\d/gi; // +00:00 -00:00 +0000 -0000 or Z\nexport var matchShortOffset = /Z|[+-]\\d\\d(?::?\\d\\d)?/gi; // +00 -00 +00:00 -00:00 +0000 -0000 or Z\n\nexport var matchTimestamp = /[+-]?\\d+(\\.\\d{1,3})?/; // 123456789 123456789.123\n\n// any word (or two) characters or numbers including two/three word month in arabic.\n// includes scottish gaelic two word and hyphenated months\nexport var matchWord = /[0-9]*['a-z\\u00A0-\\u05FF\\u0700-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF]+|[\\u0600-\\u06FF\\/]+(\\s*?[\\u0600-\\u06FF]+){1,2}/i;\n\n\nimport hasOwnProp from '../utils/has-own-prop';\nimport isFunction from '../utils/is-function';\n\nvar regexes = {};\n\nexport function addRegexToken (token, regex, strictRegex) {\n    regexes[token] = isFunction(regex) ? regex : function (isStrict, localeData) {\n        return (isStrict && strictRegex) ? strictRegex : regex;\n    };\n}\n\nexport function getParseRegexForToken (token, config) {\n    if (!hasOwnProp(regexes, token)) {\n        return new RegExp(unescapeFormat(token));\n    }\n\n    return regexes[token](config._strict, config._locale);\n}\n\n// Code from http://stackoverflow.com/questions/3561493/is-there-a-regexp-escape-function-in-javascript\nfunction unescapeFormat(s) {\n    return regexEscape(s.replace('\\\\', '').replace(/\\\\(\\[)|\\\\(\\])|\\[([^\\]\\[]*)\\]|\\\\(.)/g, function (matched, p1, p2, p3, p4) {\n        return p1 || p2 || p3 || p4;\n    }));\n}\n\nexport function regexEscape(s) {\n    return s.replace(/[-\\/\\\\^$*+?.()|[\\]{}]/g, '\\\\$&');\n}\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/lib/parse/token.js",
    "content": "import hasOwnProp from '../utils/has-own-prop';\nimport isNumber from '../utils/is-number';\nimport toInt from '../utils/to-int';\n\nvar tokens = {};\n\nexport function addParseToken (token, callback) {\n    var i, func = callback;\n    if (typeof token === 'string') {\n        token = [token];\n    }\n    if (isNumber(callback)) {\n        func = function (input, array) {\n            array[callback] = toInt(input);\n        };\n    }\n    for (i = 0; i < token.length; i++) {\n        tokens[token[i]] = func;\n    }\n}\n\nexport function addWeekParseToken (token, callback) {\n    addParseToken(token, function (input, array, config, token) {\n        config._w = config._w || {};\n        callback(input, config._w, config, token);\n    });\n}\n\nexport function addTimeToArrayFromToken(token, input, config) {\n    if (input != null && hasOwnProp(tokens, token)) {\n        tokens[token](input, config._a, config, token);\n    }\n}\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/lib/units/aliases.js",
    "content": "import hasOwnProp from '../utils/has-own-prop';\n\nvar aliases = {};\n\nexport function addUnitAlias (unit, shorthand) {\n    var lowerCase = unit.toLowerCase();\n    aliases[lowerCase] = aliases[lowerCase + 's'] = aliases[shorthand] = unit;\n}\n\nexport function normalizeUnits(units) {\n    return typeof units === 'string' ? aliases[units] || aliases[units.toLowerCase()] : undefined;\n}\n\nexport function normalizeObjectUnits(inputObject) {\n    var normalizedInput = {},\n        normalizedProp,\n        prop;\n\n    for (prop in inputObject) {\n        if (hasOwnProp(inputObject, prop)) {\n            normalizedProp = normalizeUnits(prop);\n            if (normalizedProp) {\n                normalizedInput[normalizedProp] = inputObject[prop];\n            }\n        }\n    }\n\n    return normalizedInput;\n}\n\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/lib/units/constants.js",
    "content": "export var YEAR = 0;\nexport var MONTH = 1;\nexport var DATE = 2;\nexport var HOUR = 3;\nexport var MINUTE = 4;\nexport var SECOND = 5;\nexport var MILLISECOND = 6;\nexport var WEEK = 7;\nexport var WEEKDAY = 8;\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/lib/units/day-of-month.js",
    "content": "import { makeGetSet } from '../moment/get-set';\nimport { addFormatToken } from '../format/format';\nimport { addUnitAlias } from './aliases';\nimport { addUnitPriority } from './priorities';\nimport { addRegexToken, match1to2, match2 } from '../parse/regex';\nimport { addParseToken } from '../parse/token';\nimport { DATE } from './constants';\nimport toInt from '../utils/to-int';\n\n// FORMATTING\n\naddFormatToken('D', ['DD', 2], 'Do', 'date');\n\n// ALIASES\n\naddUnitAlias('date', 'D');\n\n// PRIOROITY\naddUnitPriority('date', 9);\n\n// PARSING\n\naddRegexToken('D',  match1to2);\naddRegexToken('DD', match1to2, match2);\naddRegexToken('Do', function (isStrict, locale) {\n    // TODO: Remove \"ordinalParse\" fallback in next major release.\n    return isStrict ?\n      (locale._dayOfMonthOrdinalParse || locale._ordinalParse) :\n      locale._dayOfMonthOrdinalParseLenient;\n});\n\naddParseToken(['D', 'DD'], DATE);\naddParseToken('Do', function (input, array) {\n    array[DATE] = toInt(input.match(match1to2)[0], 10);\n});\n\n// MOMENTS\n\nexport var getSetDayOfMonth = makeGetSet('Date', true);\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/lib/units/day-of-week.js",
    "content": "import { addFormatToken } from '../format/format';\nimport { addUnitAlias } from './aliases';\nimport { addUnitPriority } from './priorities';\nimport { addRegexToken, match1to2, matchWord, regexEscape } from '../parse/regex';\nimport { addWeekParseToken } from '../parse/token';\nimport toInt from '../utils/to-int';\nimport isArray from '../utils/is-array';\nimport indexOf from '../utils/index-of';\nimport hasOwnProp from '../utils/has-own-prop';\nimport { createUTC } from '../create/utc';\nimport getParsingFlags from '../create/parsing-flags';\n\n// FORMATTING\n\naddFormatToken('d', 0, 'do', 'day');\n\naddFormatToken('dd', 0, 0, function (format) {\n    return this.localeData().weekdaysMin(this, format);\n});\n\naddFormatToken('ddd', 0, 0, function (format) {\n    return this.localeData().weekdaysShort(this, format);\n});\n\naddFormatToken('dddd', 0, 0, function (format) {\n    return this.localeData().weekdays(this, format);\n});\n\naddFormatToken('e', 0, 0, 'weekday');\naddFormatToken('E', 0, 0, 'isoWeekday');\n\n// ALIASES\n\naddUnitAlias('day', 'd');\naddUnitAlias('weekday', 'e');\naddUnitAlias('isoWeekday', 'E');\n\n// PRIORITY\naddUnitPriority('day', 11);\naddUnitPriority('weekday', 11);\naddUnitPriority('isoWeekday', 11);\n\n// PARSING\n\naddRegexToken('d',    match1to2);\naddRegexToken('e',    match1to2);\naddRegexToken('E',    match1to2);\naddRegexToken('dd',   function (isStrict, locale) {\n    return locale.weekdaysMinRegex(isStrict);\n});\naddRegexToken('ddd',   function (isStrict, locale) {\n    return locale.weekdaysShortRegex(isStrict);\n});\naddRegexToken('dddd',   function (isStrict, locale) {\n    return locale.weekdaysRegex(isStrict);\n});\n\naddWeekParseToken(['dd', 'ddd', 'dddd'], function (input, week, config, token) {\n    var weekday = config._locale.weekdaysParse(input, token, config._strict);\n    // if we didn't get a weekday name, mark the date as invalid\n    if (weekday != null) {\n        week.d = weekday;\n    } else {\n        getParsingFlags(config).invalidWeekday = input;\n    }\n});\n\naddWeekParseToken(['d', 'e', 'E'], function (input, week, config, token) {\n    week[token] = toInt(input);\n});\n\n// HELPERS\n\nfunction parseWeekday(input, locale) {\n    if (typeof input !== 'string') {\n        return input;\n    }\n\n    if (!isNaN(input)) {\n        return parseInt(input, 10);\n    }\n\n    input = locale.weekdaysParse(input);\n    if (typeof input === 'number') {\n        return input;\n    }\n\n    return null;\n}\n\nfunction parseIsoWeekday(input, locale) {\n    if (typeof input === 'string') {\n        return locale.weekdaysParse(input) % 7 || 7;\n    }\n    return isNaN(input) ? null : input;\n}\n\n// LOCALES\n\nexport var defaultLocaleWeekdays = 'Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday'.split('_');\nexport function localeWeekdays (m, format) {\n    if (!m) {\n        return isArray(this._weekdays) ? this._weekdays :\n            this._weekdays['standalone'];\n    }\n    return isArray(this._weekdays) ? this._weekdays[m.day()] :\n        this._weekdays[this._weekdays.isFormat.test(format) ? 'format' : 'standalone'][m.day()];\n}\n\nexport var defaultLocaleWeekdaysShort = 'Sun_Mon_Tue_Wed_Thu_Fri_Sat'.split('_');\nexport function localeWeekdaysShort (m) {\n    return (m) ? this._weekdaysShort[m.day()] : this._weekdaysShort;\n}\n\nexport var defaultLocaleWeekdaysMin = 'Su_Mo_Tu_We_Th_Fr_Sa'.split('_');\nexport function localeWeekdaysMin (m) {\n    return (m) ? this._weekdaysMin[m.day()] : this._weekdaysMin;\n}\n\nfunction handleStrictParse(weekdayName, format, strict) {\n    var i, ii, mom, llc = weekdayName.toLocaleLowerCase();\n    if (!this._weekdaysParse) {\n        this._weekdaysParse = [];\n        this._shortWeekdaysParse = [];\n        this._minWeekdaysParse = [];\n\n        for (i = 0; i < 7; ++i) {\n            mom = createUTC([2000, 1]).day(i);\n            this._minWeekdaysParse[i] = this.weekdaysMin(mom, '').toLocaleLowerCase();\n            this._shortWeekdaysParse[i] = this.weekdaysShort(mom, '').toLocaleLowerCase();\n            this._weekdaysParse[i] = this.weekdays(mom, '').toLocaleLowerCase();\n        }\n    }\n\n    if (strict) {\n        if (format === 'dddd') {\n            ii = indexOf.call(this._weekdaysParse, llc);\n            return ii !== -1 ? ii : null;\n        } else if (format === 'ddd') {\n            ii = indexOf.call(this._shortWeekdaysParse, llc);\n            return ii !== -1 ? ii : null;\n        } else {\n            ii = indexOf.call(this._minWeekdaysParse, llc);\n            return ii !== -1 ? ii : null;\n        }\n    } else {\n        if (format === 'dddd') {\n            ii = indexOf.call(this._weekdaysParse, llc);\n            if (ii !== -1) {\n                return ii;\n            }\n            ii = indexOf.call(this._shortWeekdaysParse, llc);\n            if (ii !== -1) {\n                return ii;\n            }\n            ii = indexOf.call(this._minWeekdaysParse, llc);\n            return ii !== -1 ? ii : null;\n        } else if (format === 'ddd') {\n            ii = indexOf.call(this._shortWeekdaysParse, llc);\n            if (ii !== -1) {\n                return ii;\n            }\n            ii = indexOf.call(this._weekdaysParse, llc);\n            if (ii !== -1) {\n                return ii;\n            }\n            ii = indexOf.call(this._minWeekdaysParse, llc);\n            return ii !== -1 ? ii : null;\n        } else {\n            ii = indexOf.call(this._minWeekdaysParse, llc);\n            if (ii !== -1) {\n                return ii;\n            }\n            ii = indexOf.call(this._weekdaysParse, llc);\n            if (ii !== -1) {\n                return ii;\n            }\n            ii = indexOf.call(this._shortWeekdaysParse, llc);\n            return ii !== -1 ? ii : null;\n        }\n    }\n}\n\nexport function localeWeekdaysParse (weekdayName, format, strict) {\n    var i, mom, regex;\n\n    if (this._weekdaysParseExact) {\n        return handleStrictParse.call(this, weekdayName, format, strict);\n    }\n\n    if (!this._weekdaysParse) {\n        this._weekdaysParse = [];\n        this._minWeekdaysParse = [];\n        this._shortWeekdaysParse = [];\n        this._fullWeekdaysParse = [];\n    }\n\n    for (i = 0; i < 7; i++) {\n        // make the regex if we don't have it already\n\n        mom = createUTC([2000, 1]).day(i);\n        if (strict && !this._fullWeekdaysParse[i]) {\n            this._fullWeekdaysParse[i] = new RegExp('^' + this.weekdays(mom, '').replace('.', '\\.?') + '$', 'i');\n            this._shortWeekdaysParse[i] = new RegExp('^' + this.weekdaysShort(mom, '').replace('.', '\\.?') + '$', 'i');\n            this._minWeekdaysParse[i] = new RegExp('^' + this.weekdaysMin(mom, '').replace('.', '\\.?') + '$', 'i');\n        }\n        if (!this._weekdaysParse[i]) {\n            regex = '^' + this.weekdays(mom, '') + '|^' + this.weekdaysShort(mom, '') + '|^' + this.weekdaysMin(mom, '');\n            this._weekdaysParse[i] = new RegExp(regex.replace('.', ''), 'i');\n        }\n        // test the regex\n        if (strict && format === 'dddd' && this._fullWeekdaysParse[i].test(weekdayName)) {\n            return i;\n        } else if (strict && format === 'ddd' && this._shortWeekdaysParse[i].test(weekdayName)) {\n            return i;\n        } else if (strict && format === 'dd' && this._minWeekdaysParse[i].test(weekdayName)) {\n            return i;\n        } else if (!strict && this._weekdaysParse[i].test(weekdayName)) {\n            return i;\n        }\n    }\n}\n\n// MOMENTS\n\nexport function getSetDayOfWeek (input) {\n    if (!this.isValid()) {\n        return input != null ? this : NaN;\n    }\n    var day = this._isUTC ? this._d.getUTCDay() : this._d.getDay();\n    if (input != null) {\n        input = parseWeekday(input, this.localeData());\n        return this.add(input - day, 'd');\n    } else {\n        return day;\n    }\n}\n\nexport function getSetLocaleDayOfWeek (input) {\n    if (!this.isValid()) {\n        return input != null ? this : NaN;\n    }\n    var weekday = (this.day() + 7 - this.localeData()._week.dow) % 7;\n    return input == null ? weekday : this.add(input - weekday, 'd');\n}\n\nexport function getSetISODayOfWeek (input) {\n    if (!this.isValid()) {\n        return input != null ? this : NaN;\n    }\n\n    // behaves the same as moment#day except\n    // as a getter, returns 7 instead of 0 (1-7 range instead of 0-6)\n    // as a setter, sunday should belong to the previous week.\n\n    if (input != null) {\n        var weekday = parseIsoWeekday(input, this.localeData());\n        return this.day(this.day() % 7 ? weekday : weekday - 7);\n    } else {\n        return this.day() || 7;\n    }\n}\n\nvar defaultWeekdaysRegex = matchWord;\nexport function weekdaysRegex (isStrict) {\n    if (this._weekdaysParseExact) {\n        if (!hasOwnProp(this, '_weekdaysRegex')) {\n            computeWeekdaysParse.call(this);\n        }\n        if (isStrict) {\n            return this._weekdaysStrictRegex;\n        } else {\n            return this._weekdaysRegex;\n        }\n    } else {\n        if (!hasOwnProp(this, '_weekdaysRegex')) {\n            this._weekdaysRegex = defaultWeekdaysRegex;\n        }\n        return this._weekdaysStrictRegex && isStrict ?\n            this._weekdaysStrictRegex : this._weekdaysRegex;\n    }\n}\n\nvar defaultWeekdaysShortRegex = matchWord;\nexport function weekdaysShortRegex (isStrict) {\n    if (this._weekdaysParseExact) {\n        if (!hasOwnProp(this, '_weekdaysRegex')) {\n            computeWeekdaysParse.call(this);\n        }\n        if (isStrict) {\n            return this._weekdaysShortStrictRegex;\n        } else {\n            return this._weekdaysShortRegex;\n        }\n    } else {\n        if (!hasOwnProp(this, '_weekdaysShortRegex')) {\n            this._weekdaysShortRegex = defaultWeekdaysShortRegex;\n        }\n        return this._weekdaysShortStrictRegex && isStrict ?\n            this._weekdaysShortStrictRegex : this._weekdaysShortRegex;\n    }\n}\n\nvar defaultWeekdaysMinRegex = matchWord;\nexport function weekdaysMinRegex (isStrict) {\n    if (this._weekdaysParseExact) {\n        if (!hasOwnProp(this, '_weekdaysRegex')) {\n            computeWeekdaysParse.call(this);\n        }\n        if (isStrict) {\n            return this._weekdaysMinStrictRegex;\n        } else {\n            return this._weekdaysMinRegex;\n        }\n    } else {\n        if (!hasOwnProp(this, '_weekdaysMinRegex')) {\n            this._weekdaysMinRegex = defaultWeekdaysMinRegex;\n        }\n        return this._weekdaysMinStrictRegex && isStrict ?\n            this._weekdaysMinStrictRegex : this._weekdaysMinRegex;\n    }\n}\n\n\nfunction computeWeekdaysParse () {\n    function cmpLenRev(a, b) {\n        return b.length - a.length;\n    }\n\n    var minPieces = [], shortPieces = [], longPieces = [], mixedPieces = [],\n        i, mom, minp, shortp, longp;\n    for (i = 0; i < 7; i++) {\n        // make the regex if we don't have it already\n        mom = createUTC([2000, 1]).day(i);\n        minp = this.weekdaysMin(mom, '');\n        shortp = this.weekdaysShort(mom, '');\n        longp = this.weekdays(mom, '');\n        minPieces.push(minp);\n        shortPieces.push(shortp);\n        longPieces.push(longp);\n        mixedPieces.push(minp);\n        mixedPieces.push(shortp);\n        mixedPieces.push(longp);\n    }\n    // Sorting makes sure if one weekday (or abbr) is a prefix of another it\n    // will match the longer piece.\n    minPieces.sort(cmpLenRev);\n    shortPieces.sort(cmpLenRev);\n    longPieces.sort(cmpLenRev);\n    mixedPieces.sort(cmpLenRev);\n    for (i = 0; i < 7; i++) {\n        shortPieces[i] = regexEscape(shortPieces[i]);\n        longPieces[i] = regexEscape(longPieces[i]);\n        mixedPieces[i] = regexEscape(mixedPieces[i]);\n    }\n\n    this._weekdaysRegex = new RegExp('^(' + mixedPieces.join('|') + ')', 'i');\n    this._weekdaysShortRegex = this._weekdaysRegex;\n    this._weekdaysMinRegex = this._weekdaysRegex;\n\n    this._weekdaysStrictRegex = new RegExp('^(' + longPieces.join('|') + ')', 'i');\n    this._weekdaysShortStrictRegex = new RegExp('^(' + shortPieces.join('|') + ')', 'i');\n    this._weekdaysMinStrictRegex = new RegExp('^(' + minPieces.join('|') + ')', 'i');\n}\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/lib/units/day-of-year.js",
    "content": "import { addFormatToken } from '../format/format';\nimport { addUnitAlias } from './aliases';\nimport { addUnitPriority } from './priorities';\nimport { addRegexToken, match3, match1to3 } from '../parse/regex';\nimport { daysInYear } from './year';\nimport { createUTCDate } from '../create/date-from-array';\nimport { addParseToken } from '../parse/token';\nimport toInt from '../utils/to-int';\n\n// FORMATTING\n\naddFormatToken('DDD', ['DDDD', 3], 'DDDo', 'dayOfYear');\n\n// ALIASES\n\naddUnitAlias('dayOfYear', 'DDD');\n\n// PRIORITY\naddUnitPriority('dayOfYear', 4);\n\n// PARSING\n\naddRegexToken('DDD',  match1to3);\naddRegexToken('DDDD', match3);\naddParseToken(['DDD', 'DDDD'], function (input, array, config) {\n    config._dayOfYear = toInt(input);\n});\n\n// HELPERS\n\n// MOMENTS\n\nexport function getSetDayOfYear (input) {\n    var dayOfYear = Math.round((this.clone().startOf('day') - this.clone().startOf('year')) / 864e5) + 1;\n    return input == null ? dayOfYear : this.add((input - dayOfYear), 'd');\n}\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/lib/units/hour.js",
    "content": "import { makeGetSet } from '../moment/get-set';\nimport { addFormatToken } from '../format/format';\nimport { addUnitAlias } from './aliases';\nimport { addUnitPriority } from './priorities';\nimport { addRegexToken, match1to2, match2, match3to4, match5to6 } from '../parse/regex';\nimport { addParseToken } from '../parse/token';\nimport { HOUR, MINUTE, SECOND } from './constants';\nimport toInt from '../utils/to-int';\nimport zeroFill from '../utils/zero-fill';\nimport getParsingFlags from '../create/parsing-flags';\n\n// FORMATTING\n\nfunction hFormat() {\n    return this.hours() % 12 || 12;\n}\n\nfunction kFormat() {\n    return this.hours() || 24;\n}\n\naddFormatToken('H', ['HH', 2], 0, 'hour');\naddFormatToken('h', ['hh', 2], 0, hFormat);\naddFormatToken('k', ['kk', 2], 0, kFormat);\n\naddFormatToken('hmm', 0, 0, function () {\n    return '' + hFormat.apply(this) + zeroFill(this.minutes(), 2);\n});\n\naddFormatToken('hmmss', 0, 0, function () {\n    return '' + hFormat.apply(this) + zeroFill(this.minutes(), 2) +\n        zeroFill(this.seconds(), 2);\n});\n\naddFormatToken('Hmm', 0, 0, function () {\n    return '' + this.hours() + zeroFill(this.minutes(), 2);\n});\n\naddFormatToken('Hmmss', 0, 0, function () {\n    return '' + this.hours() + zeroFill(this.minutes(), 2) +\n        zeroFill(this.seconds(), 2);\n});\n\nfunction meridiem (token, lowercase) {\n    addFormatToken(token, 0, 0, function () {\n        return this.localeData().meridiem(this.hours(), this.minutes(), lowercase);\n    });\n}\n\nmeridiem('a', true);\nmeridiem('A', false);\n\n// ALIASES\n\naddUnitAlias('hour', 'h');\n\n// PRIORITY\naddUnitPriority('hour', 13);\n\n// PARSING\n\nfunction matchMeridiem (isStrict, locale) {\n    return locale._meridiemParse;\n}\n\naddRegexToken('a',  matchMeridiem);\naddRegexToken('A',  matchMeridiem);\naddRegexToken('H',  match1to2);\naddRegexToken('h',  match1to2);\naddRegexToken('k',  match1to2);\naddRegexToken('HH', match1to2, match2);\naddRegexToken('hh', match1to2, match2);\naddRegexToken('kk', match1to2, match2);\n\naddRegexToken('hmm', match3to4);\naddRegexToken('hmmss', match5to6);\naddRegexToken('Hmm', match3to4);\naddRegexToken('Hmmss', match5to6);\n\naddParseToken(['H', 'HH'], HOUR);\naddParseToken(['k', 'kk'], function (input, array, config) {\n    var kInput = toInt(input);\n    array[HOUR] = kInput === 24 ? 0 : kInput;\n});\naddParseToken(['a', 'A'], function (input, array, config) {\n    config._isPm = config._locale.isPM(input);\n    config._meridiem = input;\n});\naddParseToken(['h', 'hh'], function (input, array, config) {\n    array[HOUR] = toInt(input);\n    getParsingFlags(config).bigHour = true;\n});\naddParseToken('hmm', function (input, array, config) {\n    var pos = input.length - 2;\n    array[HOUR] = toInt(input.substr(0, pos));\n    array[MINUTE] = toInt(input.substr(pos));\n    getParsingFlags(config).bigHour = true;\n});\naddParseToken('hmmss', function (input, array, config) {\n    var pos1 = input.length - 4;\n    var pos2 = input.length - 2;\n    array[HOUR] = toInt(input.substr(0, pos1));\n    array[MINUTE] = toInt(input.substr(pos1, 2));\n    array[SECOND] = toInt(input.substr(pos2));\n    getParsingFlags(config).bigHour = true;\n});\naddParseToken('Hmm', function (input, array, config) {\n    var pos = input.length - 2;\n    array[HOUR] = toInt(input.substr(0, pos));\n    array[MINUTE] = toInt(input.substr(pos));\n});\naddParseToken('Hmmss', function (input, array, config) {\n    var pos1 = input.length - 4;\n    var pos2 = input.length - 2;\n    array[HOUR] = toInt(input.substr(0, pos1));\n    array[MINUTE] = toInt(input.substr(pos1, 2));\n    array[SECOND] = toInt(input.substr(pos2));\n});\n\n// LOCALES\n\nexport function localeIsPM (input) {\n    // IE8 Quirks Mode & IE7 Standards Mode do not allow accessing strings like arrays\n    // Using charAt should be more compatible.\n    return ((input + '').toLowerCase().charAt(0) === 'p');\n}\n\nexport var defaultLocaleMeridiemParse = /[ap]\\.?m?\\.?/i;\nexport function localeMeridiem (hours, minutes, isLower) {\n    if (hours > 11) {\n        return isLower ? 'pm' : 'PM';\n    } else {\n        return isLower ? 'am' : 'AM';\n    }\n}\n\n\n// MOMENTS\n\n// Setting the hour should keep the time, because the user explicitly\n// specified which hour he wants. So trying to maintain the same hour (in\n// a new timezone) makes sense. Adding/subtracting hours does not follow\n// this rule.\nexport var getSetHour = makeGetSet('Hours', true);\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/lib/units/millisecond.js",
    "content": "import { makeGetSet } from '../moment/get-set';\nimport { addFormatToken } from '../format/format';\nimport { addUnitAlias } from './aliases';\nimport { addUnitPriority } from './priorities';\nimport { addRegexToken, match1, match2, match3, match1to3, matchUnsigned } from '../parse/regex';\nimport { addParseToken } from '../parse/token';\nimport { MILLISECOND } from './constants';\nimport toInt from '../utils/to-int';\n\n// FORMATTING\n\naddFormatToken('S', 0, 0, function () {\n    return ~~(this.millisecond() / 100);\n});\n\naddFormatToken(0, ['SS', 2], 0, function () {\n    return ~~(this.millisecond() / 10);\n});\n\naddFormatToken(0, ['SSS', 3], 0, 'millisecond');\naddFormatToken(0, ['SSSS', 4], 0, function () {\n    return this.millisecond() * 10;\n});\naddFormatToken(0, ['SSSSS', 5], 0, function () {\n    return this.millisecond() * 100;\n});\naddFormatToken(0, ['SSSSSS', 6], 0, function () {\n    return this.millisecond() * 1000;\n});\naddFormatToken(0, ['SSSSSSS', 7], 0, function () {\n    return this.millisecond() * 10000;\n});\naddFormatToken(0, ['SSSSSSSS', 8], 0, function () {\n    return this.millisecond() * 100000;\n});\naddFormatToken(0, ['SSSSSSSSS', 9], 0, function () {\n    return this.millisecond() * 1000000;\n});\n\n\n// ALIASES\n\naddUnitAlias('millisecond', 'ms');\n\n// PRIORITY\n\naddUnitPriority('millisecond', 16);\n\n// PARSING\n\naddRegexToken('S',    match1to3, match1);\naddRegexToken('SS',   match1to3, match2);\naddRegexToken('SSS',  match1to3, match3);\n\nvar token;\nfor (token = 'SSSS'; token.length <= 9; token += 'S') {\n    addRegexToken(token, matchUnsigned);\n}\n\nfunction parseMs(input, array) {\n    array[MILLISECOND] = toInt(('0.' + input) * 1000);\n}\n\nfor (token = 'S'; token.length <= 9; token += 'S') {\n    addParseToken(token, parseMs);\n}\n// MOMENTS\n\nexport var getSetMillisecond = makeGetSet('Milliseconds', false);\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/lib/units/minute.js",
    "content": "import { makeGetSet } from '../moment/get-set';\nimport { addFormatToken } from '../format/format';\nimport { addUnitAlias } from './aliases';\nimport { addUnitPriority } from './priorities';\nimport { addRegexToken, match1to2, match2 } from '../parse/regex';\nimport { addParseToken } from '../parse/token';\nimport { MINUTE } from './constants';\n\n// FORMATTING\n\naddFormatToken('m', ['mm', 2], 0, 'minute');\n\n// ALIASES\n\naddUnitAlias('minute', 'm');\n\n// PRIORITY\n\naddUnitPriority('minute', 14);\n\n// PARSING\n\naddRegexToken('m',  match1to2);\naddRegexToken('mm', match1to2, match2);\naddParseToken(['m', 'mm'], MINUTE);\n\n// MOMENTS\n\nexport var getSetMinute = makeGetSet('Minutes', false);\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/lib/units/month.js",
    "content": "import { get } from '../moment/get-set';\nimport hasOwnProp from '../utils/has-own-prop';\nimport { addFormatToken } from '../format/format';\nimport { addUnitAlias } from './aliases';\nimport { addUnitPriority } from './priorities';\nimport { addRegexToken, match1to2, match2, matchWord, regexEscape } from '../parse/regex';\nimport { addParseToken } from '../parse/token';\nimport { hooks } from '../utils/hooks';\nimport { MONTH } from './constants';\nimport toInt from '../utils/to-int';\nimport isArray from '../utils/is-array';\nimport isNumber from '../utils/is-number';\nimport indexOf from '../utils/index-of';\nimport { createUTC } from '../create/utc';\nimport getParsingFlags from '../create/parsing-flags';\n\nexport function daysInMonth(year, month) {\n    return new Date(Date.UTC(year, month + 1, 0)).getUTCDate();\n}\n\n// FORMATTING\n\naddFormatToken('M', ['MM', 2], 'Mo', function () {\n    return this.month() + 1;\n});\n\naddFormatToken('MMM', 0, 0, function (format) {\n    return this.localeData().monthsShort(this, format);\n});\n\naddFormatToken('MMMM', 0, 0, function (format) {\n    return this.localeData().months(this, format);\n});\n\n// ALIASES\n\naddUnitAlias('month', 'M');\n\n// PRIORITY\n\naddUnitPriority('month', 8);\n\n// PARSING\n\naddRegexToken('M',    match1to2);\naddRegexToken('MM',   match1to2, match2);\naddRegexToken('MMM',  function (isStrict, locale) {\n    return locale.monthsShortRegex(isStrict);\n});\naddRegexToken('MMMM', function (isStrict, locale) {\n    return locale.monthsRegex(isStrict);\n});\n\naddParseToken(['M', 'MM'], function (input, array) {\n    array[MONTH] = toInt(input) - 1;\n});\n\naddParseToken(['MMM', 'MMMM'], function (input, array, config, token) {\n    var month = config._locale.monthsParse(input, token, config._strict);\n    // if we didn't find a month name, mark the date as invalid.\n    if (month != null) {\n        array[MONTH] = month;\n    } else {\n        getParsingFlags(config).invalidMonth = input;\n    }\n});\n\n// LOCALES\n\nvar MONTHS_IN_FORMAT = /D[oD]?(\\[[^\\[\\]]*\\]|\\s)+MMMM?/;\nexport var defaultLocaleMonths = 'January_February_March_April_May_June_July_August_September_October_November_December'.split('_');\nexport function localeMonths (m, format) {\n    if (!m) {\n        return isArray(this._months) ? this._months :\n            this._months['standalone'];\n    }\n    return isArray(this._months) ? this._months[m.month()] :\n        this._months[(this._months.isFormat || MONTHS_IN_FORMAT).test(format) ? 'format' : 'standalone'][m.month()];\n}\n\nexport var defaultLocaleMonthsShort = 'Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec'.split('_');\nexport function localeMonthsShort (m, format) {\n    if (!m) {\n        return isArray(this._monthsShort) ? this._monthsShort :\n            this._monthsShort['standalone'];\n    }\n    return isArray(this._monthsShort) ? this._monthsShort[m.month()] :\n        this._monthsShort[MONTHS_IN_FORMAT.test(format) ? 'format' : 'standalone'][m.month()];\n}\n\nfunction handleStrictParse(monthName, format, strict) {\n    var i, ii, mom, llc = monthName.toLocaleLowerCase();\n    if (!this._monthsParse) {\n        // this is not used\n        this._monthsParse = [];\n        this._longMonthsParse = [];\n        this._shortMonthsParse = [];\n        for (i = 0; i < 12; ++i) {\n            mom = createUTC([2000, i]);\n            this._shortMonthsParse[i] = this.monthsShort(mom, '').toLocaleLowerCase();\n            this._longMonthsParse[i] = this.months(mom, '').toLocaleLowerCase();\n        }\n    }\n\n    if (strict) {\n        if (format === 'MMM') {\n            ii = indexOf.call(this._shortMonthsParse, llc);\n            return ii !== -1 ? ii : null;\n        } else {\n            ii = indexOf.call(this._longMonthsParse, llc);\n            return ii !== -1 ? ii : null;\n        }\n    } else {\n        if (format === 'MMM') {\n            ii = indexOf.call(this._shortMonthsParse, llc);\n            if (ii !== -1) {\n                return ii;\n            }\n            ii = indexOf.call(this._longMonthsParse, llc);\n            return ii !== -1 ? ii : null;\n        } else {\n            ii = indexOf.call(this._longMonthsParse, llc);\n            if (ii !== -1) {\n                return ii;\n            }\n            ii = indexOf.call(this._shortMonthsParse, llc);\n            return ii !== -1 ? ii : null;\n        }\n    }\n}\n\nexport function localeMonthsParse (monthName, format, strict) {\n    var i, mom, regex;\n\n    if (this._monthsParseExact) {\n        return handleStrictParse.call(this, monthName, format, strict);\n    }\n\n    if (!this._monthsParse) {\n        this._monthsParse = [];\n        this._longMonthsParse = [];\n        this._shortMonthsParse = [];\n    }\n\n    // TODO: add sorting\n    // Sorting makes sure if one month (or abbr) is a prefix of another\n    // see sorting in computeMonthsParse\n    for (i = 0; i < 12; i++) {\n        // make the regex if we don't have it already\n        mom = createUTC([2000, i]);\n        if (strict && !this._longMonthsParse[i]) {\n            this._longMonthsParse[i] = new RegExp('^' + this.months(mom, '').replace('.', '') + '$', 'i');\n            this._shortMonthsParse[i] = new RegExp('^' + this.monthsShort(mom, '').replace('.', '') + '$', 'i');\n        }\n        if (!strict && !this._monthsParse[i]) {\n            regex = '^' + this.months(mom, '') + '|^' + this.monthsShort(mom, '');\n            this._monthsParse[i] = new RegExp(regex.replace('.', ''), 'i');\n        }\n        // test the regex\n        if (strict && format === 'MMMM' && this._longMonthsParse[i].test(monthName)) {\n            return i;\n        } else if (strict && format === 'MMM' && this._shortMonthsParse[i].test(monthName)) {\n            return i;\n        } else if (!strict && this._monthsParse[i].test(monthName)) {\n            return i;\n        }\n    }\n}\n\n// MOMENTS\n\nexport function setMonth (mom, value) {\n    var dayOfMonth;\n\n    if (!mom.isValid()) {\n        // No op\n        return mom;\n    }\n\n    if (typeof value === 'string') {\n        if (/^\\d+$/.test(value)) {\n            value = toInt(value);\n        } else {\n            value = mom.localeData().monthsParse(value);\n            // TODO: Another silent failure?\n            if (!isNumber(value)) {\n                return mom;\n            }\n        }\n    }\n\n    dayOfMonth = Math.min(mom.date(), daysInMonth(mom.year(), value));\n    mom._d['set' + (mom._isUTC ? 'UTC' : '') + 'Month'](value, dayOfMonth);\n    return mom;\n}\n\nexport function getSetMonth (value) {\n    if (value != null) {\n        setMonth(this, value);\n        hooks.updateOffset(this, true);\n        return this;\n    } else {\n        return get(this, 'Month');\n    }\n}\n\nexport function getDaysInMonth () {\n    return daysInMonth(this.year(), this.month());\n}\n\nvar defaultMonthsShortRegex = matchWord;\nexport function monthsShortRegex (isStrict) {\n    if (this._monthsParseExact) {\n        if (!hasOwnProp(this, '_monthsRegex')) {\n            computeMonthsParse.call(this);\n        }\n        if (isStrict) {\n            return this._monthsShortStrictRegex;\n        } else {\n            return this._monthsShortRegex;\n        }\n    } else {\n        if (!hasOwnProp(this, '_monthsShortRegex')) {\n            this._monthsShortRegex = defaultMonthsShortRegex;\n        }\n        return this._monthsShortStrictRegex && isStrict ?\n            this._monthsShortStrictRegex : this._monthsShortRegex;\n    }\n}\n\nvar defaultMonthsRegex = matchWord;\nexport function monthsRegex (isStrict) {\n    if (this._monthsParseExact) {\n        if (!hasOwnProp(this, '_monthsRegex')) {\n            computeMonthsParse.call(this);\n        }\n        if (isStrict) {\n            return this._monthsStrictRegex;\n        } else {\n            return this._monthsRegex;\n        }\n    } else {\n        if (!hasOwnProp(this, '_monthsRegex')) {\n            this._monthsRegex = defaultMonthsRegex;\n        }\n        return this._monthsStrictRegex && isStrict ?\n            this._monthsStrictRegex : this._monthsRegex;\n    }\n}\n\nfunction computeMonthsParse () {\n    function cmpLenRev(a, b) {\n        return b.length - a.length;\n    }\n\n    var shortPieces = [], longPieces = [], mixedPieces = [],\n        i, mom;\n    for (i = 0; i < 12; i++) {\n        // make the regex if we don't have it already\n        mom = createUTC([2000, i]);\n        shortPieces.push(this.monthsShort(mom, ''));\n        longPieces.push(this.months(mom, ''));\n        mixedPieces.push(this.months(mom, ''));\n        mixedPieces.push(this.monthsShort(mom, ''));\n    }\n    // Sorting makes sure if one month (or abbr) is a prefix of another it\n    // will match the longer piece.\n    shortPieces.sort(cmpLenRev);\n    longPieces.sort(cmpLenRev);\n    mixedPieces.sort(cmpLenRev);\n    for (i = 0; i < 12; i++) {\n        shortPieces[i] = regexEscape(shortPieces[i]);\n        longPieces[i] = regexEscape(longPieces[i]);\n    }\n    for (i = 0; i < 24; i++) {\n        mixedPieces[i] = regexEscape(mixedPieces[i]);\n    }\n\n    this._monthsRegex = new RegExp('^(' + mixedPieces.join('|') + ')', 'i');\n    this._monthsShortRegex = this._monthsRegex;\n    this._monthsStrictRegex = new RegExp('^(' + longPieces.join('|') + ')', 'i');\n    this._monthsShortStrictRegex = new RegExp('^(' + shortPieces.join('|') + ')', 'i');\n}\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/lib/units/offset.js",
    "content": "import zeroFill from '../utils/zero-fill';\nimport { createDuration } from '../duration/create';\nimport { addSubtract } from '../moment/add-subtract';\nimport { isMoment, copyConfig } from '../moment/constructor';\nimport { addFormatToken } from '../format/format';\nimport { addRegexToken, matchOffset, matchShortOffset } from '../parse/regex';\nimport { addParseToken } from '../parse/token';\nimport { createLocal } from '../create/local';\nimport { prepareConfig } from '../create/from-anything';\nimport { createUTC } from '../create/utc';\nimport isDate from '../utils/is-date';\nimport toInt from '../utils/to-int';\nimport isUndefined from '../utils/is-undefined';\nimport compareArrays from '../utils/compare-arrays';\nimport { hooks } from '../utils/hooks';\n\n// FORMATTING\n\nfunction offset (token, separator) {\n    addFormatToken(token, 0, 0, function () {\n        var offset = this.utcOffset();\n        var sign = '+';\n        if (offset < 0) {\n            offset = -offset;\n            sign = '-';\n        }\n        return sign + zeroFill(~~(offset / 60), 2) + separator + zeroFill(~~(offset) % 60, 2);\n    });\n}\n\noffset('Z', ':');\noffset('ZZ', '');\n\n// PARSING\n\naddRegexToken('Z',  matchShortOffset);\naddRegexToken('ZZ', matchShortOffset);\naddParseToken(['Z', 'ZZ'], function (input, array, config) {\n    config._useUTC = true;\n    config._tzm = offsetFromString(matchShortOffset, input);\n});\n\n// HELPERS\n\n// timezone chunker\n// '+10:00' > ['10',  '00']\n// '-1530'  > ['-15', '30']\nvar chunkOffset = /([\\+\\-]|\\d\\d)/gi;\n\nfunction offsetFromString(matcher, string) {\n    var matches = (string || '').match(matcher);\n\n    if (matches === null) {\n        return null;\n    }\n\n    var chunk   = matches[matches.length - 1] || [];\n    var parts   = (chunk + '').match(chunkOffset) || ['-', 0, 0];\n    var minutes = +(parts[1] * 60) + toInt(parts[2]);\n\n    return minutes === 0 ?\n      0 :\n      parts[0] === '+' ? minutes : -minutes;\n}\n\n// Return a moment from input, that is local/utc/zone equivalent to model.\nexport function cloneWithOffset(input, model) {\n    var res, diff;\n    if (model._isUTC) {\n        res = model.clone();\n        diff = (isMoment(input) || isDate(input) ? input.valueOf() : createLocal(input).valueOf()) - res.valueOf();\n        // Use low-level api, because this fn is low-level api.\n        res._d.setTime(res._d.valueOf() + diff);\n        hooks.updateOffset(res, false);\n        return res;\n    } else {\n        return createLocal(input).local();\n    }\n}\n\nfunction getDateOffset (m) {\n    // On Firefox.24 Date#getTimezoneOffset returns a floating point.\n    // https://github.com/moment/moment/pull/1871\n    return -Math.round(m._d.getTimezoneOffset() / 15) * 15;\n}\n\n// HOOKS\n\n// This function will be called whenever a moment is mutated.\n// It is intended to keep the offset in sync with the timezone.\nhooks.updateOffset = function () {};\n\n// MOMENTS\n\n// keepLocalTime = true means only change the timezone, without\n// affecting the local hour. So 5:31:26 +0300 --[utcOffset(2, true)]-->\n// 5:31:26 +0200 It is possible that 5:31:26 doesn't exist with offset\n// +0200, so we adjust the time as needed, to be valid.\n//\n// Keeping the time actually adds/subtracts (one hour)\n// from the actual represented time. That is why we call updateOffset\n// a second time. In case it wants us to change the offset again\n// _changeInProgress == true case, then we have to adjust, because\n// there is no such time in the given timezone.\nexport function getSetOffset (input, keepLocalTime, keepMinutes) {\n    var offset = this._offset || 0,\n        localAdjust;\n    if (!this.isValid()) {\n        return input != null ? this : NaN;\n    }\n    if (input != null) {\n        if (typeof input === 'string') {\n            input = offsetFromString(matchShortOffset, input);\n            if (input === null) {\n                return this;\n            }\n        } else if (Math.abs(input) < 16 && !keepMinutes) {\n            input = input * 60;\n        }\n        if (!this._isUTC && keepLocalTime) {\n            localAdjust = getDateOffset(this);\n        }\n        this._offset = input;\n        this._isUTC = true;\n        if (localAdjust != null) {\n            this.add(localAdjust, 'm');\n        }\n        if (offset !== input) {\n            if (!keepLocalTime || this._changeInProgress) {\n                addSubtract(this, createDuration(input - offset, 'm'), 1, false);\n            } else if (!this._changeInProgress) {\n                this._changeInProgress = true;\n                hooks.updateOffset(this, true);\n                this._changeInProgress = null;\n            }\n        }\n        return this;\n    } else {\n        return this._isUTC ? offset : getDateOffset(this);\n    }\n}\n\nexport function getSetZone (input, keepLocalTime) {\n    if (input != null) {\n        if (typeof input !== 'string') {\n            input = -input;\n        }\n\n        this.utcOffset(input, keepLocalTime);\n\n        return this;\n    } else {\n        return -this.utcOffset();\n    }\n}\n\nexport function setOffsetToUTC (keepLocalTime) {\n    return this.utcOffset(0, keepLocalTime);\n}\n\nexport function setOffsetToLocal (keepLocalTime) {\n    if (this._isUTC) {\n        this.utcOffset(0, keepLocalTime);\n        this._isUTC = false;\n\n        if (keepLocalTime) {\n            this.subtract(getDateOffset(this), 'm');\n        }\n    }\n    return this;\n}\n\nexport function setOffsetToParsedOffset () {\n    if (this._tzm != null) {\n        this.utcOffset(this._tzm, false, true);\n    } else if (typeof this._i === 'string') {\n        var tZone = offsetFromString(matchOffset, this._i);\n        if (tZone != null) {\n            this.utcOffset(tZone);\n        }\n        else {\n            this.utcOffset(0, true);\n        }\n    }\n    return this;\n}\n\nexport function hasAlignedHourOffset (input) {\n    if (!this.isValid()) {\n        return false;\n    }\n    input = input ? createLocal(input).utcOffset() : 0;\n\n    return (this.utcOffset() - input) % 60 === 0;\n}\n\nexport function isDaylightSavingTime () {\n    return (\n        this.utcOffset() > this.clone().month(0).utcOffset() ||\n        this.utcOffset() > this.clone().month(5).utcOffset()\n    );\n}\n\nexport function isDaylightSavingTimeShifted () {\n    if (!isUndefined(this._isDSTShifted)) {\n        return this._isDSTShifted;\n    }\n\n    var c = {};\n\n    copyConfig(c, this);\n    c = prepareConfig(c);\n\n    if (c._a) {\n        var other = c._isUTC ? createUTC(c._a) : createLocal(c._a);\n        this._isDSTShifted = this.isValid() &&\n            compareArrays(c._a, other.toArray()) > 0;\n    } else {\n        this._isDSTShifted = false;\n    }\n\n    return this._isDSTShifted;\n}\n\nexport function isLocal () {\n    return this.isValid() ? !this._isUTC : false;\n}\n\nexport function isUtcOffset () {\n    return this.isValid() ? this._isUTC : false;\n}\n\nexport function isUtc () {\n    return this.isValid() ? this._isUTC && this._offset === 0 : false;\n}\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/lib/units/priorities.js",
    "content": "var priorities = {};\n\nexport function addUnitPriority(unit, priority) {\n    priorities[unit] = priority;\n}\n\nexport function getPrioritizedUnits(unitsObj) {\n    var units = [];\n    for (var u in unitsObj) {\n        units.push({unit: u, priority: priorities[u]});\n    }\n    units.sort(function (a, b) {\n        return a.priority - b.priority;\n    });\n    return units;\n}\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/lib/units/quarter.js",
    "content": "import { addFormatToken } from '../format/format';\nimport { addUnitAlias } from './aliases';\nimport { addUnitPriority } from './priorities';\nimport { addRegexToken, match1 } from '../parse/regex';\nimport { addParseToken } from '../parse/token';\nimport { MONTH } from './constants';\nimport toInt from '../utils/to-int';\n\n// FORMATTING\n\naddFormatToken('Q', 0, 'Qo', 'quarter');\n\n// ALIASES\n\naddUnitAlias('quarter', 'Q');\n\n// PRIORITY\n\naddUnitPriority('quarter', 7);\n\n// PARSING\n\naddRegexToken('Q', match1);\naddParseToken('Q', function (input, array) {\n    array[MONTH] = (toInt(input) - 1) * 3;\n});\n\n// MOMENTS\n\nexport function getSetQuarter (input) {\n    return input == null ? Math.ceil((this.month() + 1) / 3) : this.month((input - 1) * 3 + this.month() % 3);\n}\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/lib/units/second.js",
    "content": "import { makeGetSet } from '../moment/get-set';\nimport { addFormatToken } from '../format/format';\nimport { addUnitAlias } from './aliases';\nimport { addUnitPriority } from './priorities';\nimport { addRegexToken, match1to2, match2 } from '../parse/regex';\nimport { addParseToken } from '../parse/token';\nimport { SECOND } from './constants';\n\n// FORMATTING\n\naddFormatToken('s', ['ss', 2], 0, 'second');\n\n// ALIASES\n\naddUnitAlias('second', 's');\n\n// PRIORITY\n\naddUnitPriority('second', 15);\n\n// PARSING\n\naddRegexToken('s',  match1to2);\naddRegexToken('ss', match1to2, match2);\naddParseToken(['s', 'ss'], SECOND);\n\n// MOMENTS\n\nexport var getSetSecond = makeGetSet('Seconds', false);\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/lib/units/timestamp.js",
    "content": "import { addFormatToken } from '../format/format';\nimport { addRegexToken, matchTimestamp, matchSigned } from '../parse/regex';\nimport { addParseToken } from '../parse/token';\nimport toInt from '../utils/to-int';\n\n// FORMATTING\n\naddFormatToken('X', 0, 0, 'unix');\naddFormatToken('x', 0, 0, 'valueOf');\n\n// PARSING\n\naddRegexToken('x', matchSigned);\naddRegexToken('X', matchTimestamp);\naddParseToken('X', function (input, array, config) {\n    config._d = new Date(parseFloat(input, 10) * 1000);\n});\naddParseToken('x', function (input, array, config) {\n    config._d = new Date(toInt(input));\n});\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/lib/units/timezone.js",
    "content": "import { addFormatToken } from '../format/format';\n\n// FORMATTING\n\naddFormatToken('z',  0, 0, 'zoneAbbr');\naddFormatToken('zz', 0, 0, 'zoneName');\n\n// MOMENTS\n\nexport function getZoneAbbr () {\n    return this._isUTC ? 'UTC' : '';\n}\n\nexport function getZoneName () {\n    return this._isUTC ? 'Coordinated Universal Time' : '';\n}\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/lib/units/units.js",
    "content": "// Side effect imports\nimport './day-of-month';\nimport './day-of-week';\nimport './day-of-year';\nimport './hour';\nimport './millisecond';\nimport './minute';\nimport './month';\nimport './offset';\nimport './quarter';\nimport './second';\nimport './timestamp';\nimport './timezone';\nimport './week-year';\nimport './week';\nimport './year';\n\nimport { normalizeUnits } from './aliases';\n\nexport { normalizeUnits };\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/lib/units/week-calendar-utils.js",
    "content": "import { daysInYear } from './year';\nimport { createLocal } from '../create/local';\nimport { createUTCDate } from '../create/date-from-array';\n\n// start-of-first-week - start-of-year\nfunction firstWeekOffset(year, dow, doy) {\n    var // first-week day -- which january is always in the first week (4 for iso, 1 for other)\n        fwd = 7 + dow - doy,\n        // first-week day local weekday -- which local weekday is fwd\n        fwdlw = (7 + createUTCDate(year, 0, fwd).getUTCDay() - dow) % 7;\n\n    return -fwdlw + fwd - 1;\n}\n\n// https://en.wikipedia.org/wiki/ISO_week_date#Calculating_a_date_given_the_year.2C_week_number_and_weekday\nexport function dayOfYearFromWeeks(year, week, weekday, dow, doy) {\n    var localWeekday = (7 + weekday - dow) % 7,\n        weekOffset = firstWeekOffset(year, dow, doy),\n        dayOfYear = 1 + 7 * (week - 1) + localWeekday + weekOffset,\n        resYear, resDayOfYear;\n\n    if (dayOfYear <= 0) {\n        resYear = year - 1;\n        resDayOfYear = daysInYear(resYear) + dayOfYear;\n    } else if (dayOfYear > daysInYear(year)) {\n        resYear = year + 1;\n        resDayOfYear = dayOfYear - daysInYear(year);\n    } else {\n        resYear = year;\n        resDayOfYear = dayOfYear;\n    }\n\n    return {\n        year: resYear,\n        dayOfYear: resDayOfYear\n    };\n}\n\nexport function weekOfYear(mom, dow, doy) {\n    var weekOffset = firstWeekOffset(mom.year(), dow, doy),\n        week = Math.floor((mom.dayOfYear() - weekOffset - 1) / 7) + 1,\n        resWeek, resYear;\n\n    if (week < 1) {\n        resYear = mom.year() - 1;\n        resWeek = week + weeksInYear(resYear, dow, doy);\n    } else if (week > weeksInYear(mom.year(), dow, doy)) {\n        resWeek = week - weeksInYear(mom.year(), dow, doy);\n        resYear = mom.year() + 1;\n    } else {\n        resYear = mom.year();\n        resWeek = week;\n    }\n\n    return {\n        week: resWeek,\n        year: resYear\n    };\n}\n\nexport function weeksInYear(year, dow, doy) {\n    var weekOffset = firstWeekOffset(year, dow, doy),\n        weekOffsetNext = firstWeekOffset(year + 1, dow, doy);\n    return (daysInYear(year) - weekOffset + weekOffsetNext) / 7;\n}\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/lib/units/week-year.js",
    "content": "import { addFormatToken } from '../format/format';\nimport { addUnitAlias } from './aliases';\nimport { addUnitPriority } from './priorities';\nimport { addRegexToken, match1to2, match1to4, match1to6, match2, match4, match6, matchSigned } from '../parse/regex';\nimport { addWeekParseToken } from '../parse/token';\nimport { weekOfYear, weeksInYear, dayOfYearFromWeeks } from './week-calendar-utils';\nimport toInt from '../utils/to-int';\nimport { hooks } from '../utils/hooks';\nimport { createLocal } from '../create/local';\nimport { createUTCDate } from '../create/date-from-array';\n\n// FORMATTING\n\naddFormatToken(0, ['gg', 2], 0, function () {\n    return this.weekYear() % 100;\n});\n\naddFormatToken(0, ['GG', 2], 0, function () {\n    return this.isoWeekYear() % 100;\n});\n\nfunction addWeekYearFormatToken (token, getter) {\n    addFormatToken(0, [token, token.length], 0, getter);\n}\n\naddWeekYearFormatToken('gggg',     'weekYear');\naddWeekYearFormatToken('ggggg',    'weekYear');\naddWeekYearFormatToken('GGGG',  'isoWeekYear');\naddWeekYearFormatToken('GGGGG', 'isoWeekYear');\n\n// ALIASES\n\naddUnitAlias('weekYear', 'gg');\naddUnitAlias('isoWeekYear', 'GG');\n\n// PRIORITY\n\naddUnitPriority('weekYear', 1);\naddUnitPriority('isoWeekYear', 1);\n\n\n// PARSING\n\naddRegexToken('G',      matchSigned);\naddRegexToken('g',      matchSigned);\naddRegexToken('GG',     match1to2, match2);\naddRegexToken('gg',     match1to2, match2);\naddRegexToken('GGGG',   match1to4, match4);\naddRegexToken('gggg',   match1to4, match4);\naddRegexToken('GGGGG',  match1to6, match6);\naddRegexToken('ggggg',  match1to6, match6);\n\naddWeekParseToken(['gggg', 'ggggg', 'GGGG', 'GGGGG'], function (input, week, config, token) {\n    week[token.substr(0, 2)] = toInt(input);\n});\n\naddWeekParseToken(['gg', 'GG'], function (input, week, config, token) {\n    week[token] = hooks.parseTwoDigitYear(input);\n});\n\n// MOMENTS\n\nexport function getSetWeekYear (input) {\n    return getSetWeekYearHelper.call(this,\n            input,\n            this.week(),\n            this.weekday(),\n            this.localeData()._week.dow,\n            this.localeData()._week.doy);\n}\n\nexport function getSetISOWeekYear (input) {\n    return getSetWeekYearHelper.call(this,\n            input, this.isoWeek(), this.isoWeekday(), 1, 4);\n}\n\nexport function getISOWeeksInYear () {\n    return weeksInYear(this.year(), 1, 4);\n}\n\nexport function getWeeksInYear () {\n    var weekInfo = this.localeData()._week;\n    return weeksInYear(this.year(), weekInfo.dow, weekInfo.doy);\n}\n\nfunction getSetWeekYearHelper(input, week, weekday, dow, doy) {\n    var weeksTarget;\n    if (input == null) {\n        return weekOfYear(this, dow, doy).year;\n    } else {\n        weeksTarget = weeksInYear(input, dow, doy);\n        if (week > weeksTarget) {\n            week = weeksTarget;\n        }\n        return setWeekAll.call(this, input, week, weekday, dow, doy);\n    }\n}\n\nfunction setWeekAll(weekYear, week, weekday, dow, doy) {\n    var dayOfYearData = dayOfYearFromWeeks(weekYear, week, weekday, dow, doy),\n        date = createUTCDate(dayOfYearData.year, 0, dayOfYearData.dayOfYear);\n\n    this.year(date.getUTCFullYear());\n    this.month(date.getUTCMonth());\n    this.date(date.getUTCDate());\n    return this;\n}\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/lib/units/week.js",
    "content": "import { addFormatToken } from '../format/format';\nimport { addUnitAlias } from './aliases';\nimport { addUnitPriority } from './priorities';\nimport { addRegexToken, match1to2, match2 } from '../parse/regex';\nimport { addWeekParseToken } from '../parse/token';\nimport toInt from '../utils/to-int';\nimport { createLocal } from '../create/local';\nimport { weekOfYear } from './week-calendar-utils';\n\n// FORMATTING\n\naddFormatToken('w', ['ww', 2], 'wo', 'week');\naddFormatToken('W', ['WW', 2], 'Wo', 'isoWeek');\n\n// ALIASES\n\naddUnitAlias('week', 'w');\naddUnitAlias('isoWeek', 'W');\n\n// PRIORITIES\n\naddUnitPriority('week', 5);\naddUnitPriority('isoWeek', 5);\n\n// PARSING\n\naddRegexToken('w',  match1to2);\naddRegexToken('ww', match1to2, match2);\naddRegexToken('W',  match1to2);\naddRegexToken('WW', match1to2, match2);\n\naddWeekParseToken(['w', 'ww', 'W', 'WW'], function (input, week, config, token) {\n    week[token.substr(0, 1)] = toInt(input);\n});\n\n// HELPERS\n\n// LOCALES\n\nexport function localeWeek (mom) {\n    return weekOfYear(mom, this._week.dow, this._week.doy).week;\n}\n\nexport var defaultLocaleWeek = {\n    dow : 0, // Sunday is the first day of the week.\n    doy : 6  // The week that contains Jan 1st is the first week of the year.\n};\n\nexport function localeFirstDayOfWeek () {\n    return this._week.dow;\n}\n\nexport function localeFirstDayOfYear () {\n    return this._week.doy;\n}\n\n// MOMENTS\n\nexport function getSetWeek (input) {\n    var week = this.localeData().week(this);\n    return input == null ? week : this.add((input - week) * 7, 'd');\n}\n\nexport function getSetISOWeek (input) {\n    var week = weekOfYear(this, 1, 4).week;\n    return input == null ? week : this.add((input - week) * 7, 'd');\n}\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/lib/units/year.js",
    "content": "import { makeGetSet } from '../moment/get-set';\nimport { addFormatToken } from '../format/format';\nimport { addUnitAlias } from './aliases';\nimport { addUnitPriority } from './priorities';\nimport { addRegexToken, match1to2, match1to4, match1to6, match2, match4, match6, matchSigned } from '../parse/regex';\nimport { addParseToken } from '../parse/token';\nimport { hooks } from '../utils/hooks';\nimport { YEAR } from './constants';\nimport toInt from '../utils/to-int';\n\n// FORMATTING\n\naddFormatToken('Y', 0, 0, function () {\n    var y = this.year();\n    return y <= 9999 ? '' + y : '+' + y;\n});\n\naddFormatToken(0, ['YY', 2], 0, function () {\n    return this.year() % 100;\n});\n\naddFormatToken(0, ['YYYY',   4],       0, 'year');\naddFormatToken(0, ['YYYYY',  5],       0, 'year');\naddFormatToken(0, ['YYYYYY', 6, true], 0, 'year');\n\n// ALIASES\n\naddUnitAlias('year', 'y');\n\n// PRIORITIES\n\naddUnitPriority('year', 1);\n\n// PARSING\n\naddRegexToken('Y',      matchSigned);\naddRegexToken('YY',     match1to2, match2);\naddRegexToken('YYYY',   match1to4, match4);\naddRegexToken('YYYYY',  match1to6, match6);\naddRegexToken('YYYYYY', match1to6, match6);\n\naddParseToken(['YYYYY', 'YYYYYY'], YEAR);\naddParseToken('YYYY', function (input, array) {\n    array[YEAR] = input.length === 2 ? hooks.parseTwoDigitYear(input) : toInt(input);\n});\naddParseToken('YY', function (input, array) {\n    array[YEAR] = hooks.parseTwoDigitYear(input);\n});\naddParseToken('Y', function (input, array) {\n    array[YEAR] = parseInt(input, 10);\n});\n\n// HELPERS\n\nexport function daysInYear(year) {\n    return isLeapYear(year) ? 366 : 365;\n}\n\nfunction isLeapYear(year) {\n    return (year % 4 === 0 && year % 100 !== 0) || year % 400 === 0;\n}\n\n// HOOKS\n\nhooks.parseTwoDigitYear = function (input) {\n    return toInt(input) + (toInt(input) > 68 ? 1900 : 2000);\n};\n\n// MOMENTS\n\nexport var getSetYear = makeGetSet('FullYear', true);\n\nexport function getIsLeapYear () {\n    return isLeapYear(this.year());\n}\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/lib/utils/abs-ceil.js",
    "content": "export default function absCeil (number) {\n    if (number < 0) {\n        return Math.floor(number);\n    } else {\n        return Math.ceil(number);\n    }\n}\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/lib/utils/abs-floor.js",
    "content": "export default function absFloor (number) {\n    if (number < 0) {\n        // -0 -> 0\n        return Math.ceil(number) || 0;\n    } else {\n        return Math.floor(number);\n    }\n}\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/lib/utils/abs-round.js",
    "content": "export default function absRound (number) {\n    if (number < 0) {\n        return Math.round(-1 * number) * -1;\n    } else {\n        return Math.round(number);\n    }\n}\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/lib/utils/compare-arrays.js",
    "content": "import toInt from './to-int';\n\n// compare two arrays, return the number of differences\nexport default function compareArrays(array1, array2, dontConvert) {\n    var len = Math.min(array1.length, array2.length),\n        lengthDiff = Math.abs(array1.length - array2.length),\n        diffs = 0,\n        i;\n    for (i = 0; i < len; i++) {\n        if ((dontConvert && array1[i] !== array2[i]) ||\n            (!dontConvert && toInt(array1[i]) !== toInt(array2[i]))) {\n            diffs++;\n        }\n    }\n    return diffs + lengthDiff;\n}\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/lib/utils/defaults.js",
    "content": "// Pick the first defined of two or three arguments.\nexport default function defaults(a, b, c) {\n    if (a != null) {\n        return a;\n    }\n    if (b != null) {\n        return b;\n    }\n    return c;\n}\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/lib/utils/deprecate.js",
    "content": "import extend from './extend';\nimport { hooks } from './hooks';\nimport isUndefined from './is-undefined';\n\nfunction warn(msg) {\n    if (hooks.suppressDeprecationWarnings === false &&\n            (typeof console !==  'undefined') && console.warn) {\n        console.warn('Deprecation warning: ' + msg);\n    }\n}\n\nexport function deprecate(msg, fn) {\n    var firstTime = true;\n\n    return extend(function () {\n        if (hooks.deprecationHandler != null) {\n            hooks.deprecationHandler(null, msg);\n        }\n        if (firstTime) {\n            var args = [];\n            var arg;\n            for (var i = 0; i < arguments.length; i++) {\n                arg = '';\n                if (typeof arguments[i] === 'object') {\n                    arg += '\\n[' + i + '] ';\n                    for (var key in arguments[0]) {\n                        arg += key + ': ' + arguments[0][key] + ', ';\n                    }\n                    arg = arg.slice(0, -2); // Remove trailing comma and space\n                } else {\n                    arg = arguments[i];\n                }\n                args.push(arg);\n            }\n            warn(msg + '\\nArguments: ' + Array.prototype.slice.call(args).join('') + '\\n' + (new Error()).stack);\n            firstTime = false;\n        }\n        return fn.apply(this, arguments);\n    }, fn);\n}\n\nvar deprecations = {};\n\nexport function deprecateSimple(name, msg) {\n    if (hooks.deprecationHandler != null) {\n        hooks.deprecationHandler(name, msg);\n    }\n    if (!deprecations[name]) {\n        warn(msg);\n        deprecations[name] = true;\n    }\n}\n\nhooks.suppressDeprecationWarnings = false;\nhooks.deprecationHandler = null;\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/lib/utils/extend.js",
    "content": "import hasOwnProp from './has-own-prop';\n\nexport default function extend(a, b) {\n    for (var i in b) {\n        if (hasOwnProp(b, i)) {\n            a[i] = b[i];\n        }\n    }\n\n    if (hasOwnProp(b, 'toString')) {\n        a.toString = b.toString;\n    }\n\n    if (hasOwnProp(b, 'valueOf')) {\n        a.valueOf = b.valueOf;\n    }\n\n    return a;\n}\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/lib/utils/has-own-prop.js",
    "content": "export default function hasOwnProp(a, b) {\n    return Object.prototype.hasOwnProperty.call(a, b);\n}\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/lib/utils/hooks.js",
    "content": "export { hooks, setHookCallback };\n\nvar hookCallback;\n\nfunction hooks () {\n    return hookCallback.apply(null, arguments);\n}\n\n// This is done to register the method called with moment()\n// without creating circular dependencies.\nfunction setHookCallback (callback) {\n    hookCallback = callback;\n}\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/lib/utils/index-of.js",
    "content": "var indexOf;\n\nif (Array.prototype.indexOf) {\n    indexOf = Array.prototype.indexOf;\n} else {\n    indexOf = function (o) {\n        // I know\n        var i;\n        for (i = 0; i < this.length; ++i) {\n            if (this[i] === o) {\n                return i;\n            }\n        }\n        return -1;\n    };\n}\n\nexport { indexOf as default };\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/lib/utils/is-array.js",
    "content": "export default function isArray(input) {\n    return input instanceof Array || Object.prototype.toString.call(input) === '[object Array]';\n}\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/lib/utils/is-date.js",
    "content": "export default function isDate(input) {\n    return input instanceof Date || Object.prototype.toString.call(input) === '[object Date]';\n}\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/lib/utils/is-function.js",
    "content": "export default function isFunction(input) {\n    return input instanceof Function || Object.prototype.toString.call(input) === '[object Function]';\n}\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/lib/utils/is-number.js",
    "content": "export default function isNumber(input) {\n    return typeof input === 'number' || Object.prototype.toString.call(input) === '[object Number]';\n}\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/lib/utils/is-object-empty.js",
    "content": "export default function isObjectEmpty(obj) {\n    var k;\n    for (k in obj) {\n        // even if its not own property I'd still call it non-empty\n        return false;\n    }\n    return true;\n}\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/lib/utils/is-object.js",
    "content": "export default function isObject(input) {\n    // IE8 will treat undefined and null as object if it wasn't for\n    // input != null\n    return input != null && Object.prototype.toString.call(input) === '[object Object]';\n}\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/lib/utils/is-undefined.js",
    "content": "export default function isUndefined(input) {\n    return input === void 0;\n}\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/lib/utils/keys.js",
    "content": "import hasOwnProp from './has-own-prop';\n\nvar keys;\n\nif (Object.keys) {\n    keys = Object.keys;\n} else {\n    keys = function (obj) {\n        var i, res = [];\n        for (i in obj) {\n            if (hasOwnProp(obj, i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    };\n}\n\nexport { keys as default };\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/lib/utils/map.js",
    "content": "export default function map(arr, fn) {\n    var res = [], i;\n    for (i = 0; i < arr.length; ++i) {\n        res.push(fn(arr[i], i));\n    }\n    return res;\n}\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/lib/utils/some.js",
    "content": "var some;\nif (Array.prototype.some) {\n    some = Array.prototype.some;\n} else {\n    some = function (fun) {\n        var t = Object(this);\n        var len = t.length >>> 0;\n\n        for (var i = 0; i < len; i++) {\n            if (i in t && fun.call(this, t[i], i, t)) {\n                return true;\n            }\n        }\n\n        return false;\n    };\n}\n\nexport { some as default };\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/lib/utils/to-int.js",
    "content": "import absFloor from './abs-floor';\n\nexport default function toInt(argumentForCoercion) {\n    var coercedNumber = +argumentForCoercion,\n        value = 0;\n\n    if (coercedNumber !== 0 && isFinite(coercedNumber)) {\n        value = absFloor(coercedNumber);\n    }\n\n    return value;\n}\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/lib/utils/zero-fill.js",
    "content": "export default function zeroFill(number, targetLength, forceSign) {\n    var absNumber = '' + Math.abs(number),\n        zerosToFill = targetLength - absNumber.length,\n        sign = number >= 0;\n    return (sign ? (forceSign ? '+' : '') : '-') +\n        Math.pow(10, Math.max(0, zerosToFill)).toString().substr(1) + absNumber;\n}\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/locale/af.js",
    "content": "//! moment.js locale configuration\n//! locale : Afrikaans [af]\n//! author : Werner Mollentze : https://github.com/wernerm\n\nimport moment from '../moment';\n\nexport default moment.defineLocale('af', {\n    months : 'Januarie_Februarie_Maart_April_Mei_Junie_Julie_Augustus_September_Oktober_November_Desember'.split('_'),\n    monthsShort : 'Jan_Feb_Mrt_Apr_Mei_Jun_Jul_Aug_Sep_Okt_Nov_Des'.split('_'),\n    weekdays : 'Sondag_Maandag_Dinsdag_Woensdag_Donderdag_Vrydag_Saterdag'.split('_'),\n    weekdaysShort : 'Son_Maa_Din_Woe_Don_Vry_Sat'.split('_'),\n    weekdaysMin : 'So_Ma_Di_Wo_Do_Vr_Sa'.split('_'),\n    meridiemParse: /vm|nm/i,\n    isPM : function (input) {\n        return /^nm$/i.test(input);\n    },\n    meridiem : function (hours, minutes, isLower) {\n        if (hours < 12) {\n            return isLower ? 'vm' : 'VM';\n        } else {\n            return isLower ? 'nm' : 'NM';\n        }\n    },\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY HH:mm',\n        LLLL : 'dddd, D MMMM YYYY HH:mm'\n    },\n    calendar : {\n        sameDay : '[Vandag om] LT',\n        nextDay : '[Môre om] LT',\n        nextWeek : 'dddd [om] LT',\n        lastDay : '[Gister om] LT',\n        lastWeek : '[Laas] dddd [om] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'oor %s',\n        past : '%s gelede',\n        s : '\\'n paar sekondes',\n        m : '\\'n minuut',\n        mm : '%d minute',\n        h : '\\'n uur',\n        hh : '%d ure',\n        d : '\\'n dag',\n        dd : '%d dae',\n        M : '\\'n maand',\n        MM : '%d maande',\n        y : '\\'n jaar',\n        yy : '%d jaar'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}(ste|de)/,\n    ordinal : function (number) {\n        return number + ((number === 1 || number === 8 || number >= 20) ? 'ste' : 'de'); // Thanks to Joris Röling : https://github.com/jjupiter\n    },\n    week : {\n        dow : 1, // Maandag is die eerste dag van die week.\n        doy : 4  // Die week wat die 4de Januarie bevat is die eerste week van die jaar.\n    }\n});\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/locale/ar-dz.js",
    "content": "//! moment.js locale configuration\n//! locale : Arabic (Algeria) [ar-dz]\n//! author : Noureddine LOUAHEDJ : https://github.com/noureddineme\n\nimport moment from '../moment';\n\nexport default moment.defineLocale('ar-dz', {\n    months : 'جانفي_فيفري_مارس_أفريل_ماي_جوان_جويلية_أوت_سبتمبر_أكتوبر_نوفمبر_ديسمبر'.split('_'),\n    monthsShort : 'جانفي_فيفري_مارس_أفريل_ماي_جوان_جويلية_أوت_سبتمبر_أكتوبر_نوفمبر_ديسمبر'.split('_'),\n    weekdays : 'الأحد_الإثنين_الثلاثاء_الأربعاء_الخميس_الجمعة_السبت'.split('_'),\n    weekdaysShort : 'احد_اثنين_ثلاثاء_اربعاء_خميس_جمعة_سبت'.split('_'),\n    weekdaysMin : 'أح_إث_ثلا_أر_خم_جم_سب'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY HH:mm',\n        LLLL : 'dddd D MMMM YYYY HH:mm'\n    },\n    calendar : {\n        sameDay: '[اليوم على الساعة] LT',\n        nextDay: '[غدا على الساعة] LT',\n        nextWeek: 'dddd [على الساعة] LT',\n        lastDay: '[أمس على الساعة] LT',\n        lastWeek: 'dddd [على الساعة] LT',\n        sameElse: 'L'\n    },\n    relativeTime : {\n        future : 'في %s',\n        past : 'منذ %s',\n        s : 'ثوان',\n        m : 'دقيقة',\n        mm : '%d دقائق',\n        h : 'ساعة',\n        hh : '%d ساعات',\n        d : 'يوم',\n        dd : '%d أيام',\n        M : 'شهر',\n        MM : '%d أشهر',\n        y : 'سنة',\n        yy : '%d سنوات'\n    },\n    week : {\n        dow : 0, // Sunday is the first day of the week.\n        doy : 4  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/locale/ar-kw.js",
    "content": "//! moment.js locale configuration\n//! locale : Arabic (Kuwait) [ar-kw]\n//! author : Nusret Parlak: https://github.com/nusretparlak\n\nimport moment from '../moment';\n\nexport default moment.defineLocale('ar-kw', {\n    months : 'يناير_فبراير_مارس_أبريل_ماي_يونيو_يوليوز_غشت_شتنبر_أكتوبر_نونبر_دجنبر'.split('_'),\n    monthsShort : 'يناير_فبراير_مارس_أبريل_ماي_يونيو_يوليوز_غشت_شتنبر_أكتوبر_نونبر_دجنبر'.split('_'),\n    weekdays : 'الأحد_الإتنين_الثلاثاء_الأربعاء_الخميس_الجمعة_السبت'.split('_'),\n    weekdaysShort : 'احد_اتنين_ثلاثاء_اربعاء_خميس_جمعة_سبت'.split('_'),\n    weekdaysMin : 'ح_ن_ث_ر_خ_ج_س'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY HH:mm',\n        LLLL : 'dddd D MMMM YYYY HH:mm'\n    },\n    calendar : {\n        sameDay: '[اليوم على الساعة] LT',\n        nextDay: '[غدا على الساعة] LT',\n        nextWeek: 'dddd [على الساعة] LT',\n        lastDay: '[أمس على الساعة] LT',\n        lastWeek: 'dddd [على الساعة] LT',\n        sameElse: 'L'\n    },\n    relativeTime : {\n        future : 'في %s',\n        past : 'منذ %s',\n        s : 'ثوان',\n        m : 'دقيقة',\n        mm : '%d دقائق',\n        h : 'ساعة',\n        hh : '%d ساعات',\n        d : 'يوم',\n        dd : '%d أيام',\n        M : 'شهر',\n        MM : '%d أشهر',\n        y : 'سنة',\n        yy : '%d سنوات'\n    },\n    week : {\n        dow : 0, // Sunday is the first day of the week.\n        doy : 12  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/locale/ar-ly.js",
    "content": "//! moment.js locale configuration\n//! locale : Arabic (Lybia) [ar-ly]\n//! author : Ali Hmer: https://github.com/kikoanis\n\nimport moment from '../moment';\n\nvar symbolMap = {\n    '1': '1',\n    '2': '2',\n    '3': '3',\n    '4': '4',\n    '5': '5',\n    '6': '6',\n    '7': '7',\n    '8': '8',\n    '9': '9',\n    '0': '0'\n}, pluralForm = function (n) {\n    return n === 0 ? 0 : n === 1 ? 1 : n === 2 ? 2 : n % 100 >= 3 && n % 100 <= 10 ? 3 : n % 100 >= 11 ? 4 : 5;\n}, plurals = {\n    s : ['أقل من ثانية', 'ثانية واحدة', ['ثانيتان', 'ثانيتين'], '%d ثوان', '%d ثانية', '%d ثانية'],\n    m : ['أقل من دقيقة', 'دقيقة واحدة', ['دقيقتان', 'دقيقتين'], '%d دقائق', '%d دقيقة', '%d دقيقة'],\n    h : ['أقل من ساعة', 'ساعة واحدة', ['ساعتان', 'ساعتين'], '%d ساعات', '%d ساعة', '%d ساعة'],\n    d : ['أقل من يوم', 'يوم واحد', ['يومان', 'يومين'], '%d أيام', '%d يومًا', '%d يوم'],\n    M : ['أقل من شهر', 'شهر واحد', ['شهران', 'شهرين'], '%d أشهر', '%d شهرا', '%d شهر'],\n    y : ['أقل من عام', 'عام واحد', ['عامان', 'عامين'], '%d أعوام', '%d عامًا', '%d عام']\n}, pluralize = function (u) {\n    return function (number, withoutSuffix, string, isFuture) {\n        var f = pluralForm(number),\n            str = plurals[u][pluralForm(number)];\n        if (f === 2) {\n            str = str[withoutSuffix ? 0 : 1];\n        }\n        return str.replace(/%d/i, number);\n    };\n}, months = [\n    'يناير',\n    'فبراير',\n    'مارس',\n    'أبريل',\n    'مايو',\n    'يونيو',\n    'يوليو',\n    'أغسطس',\n    'سبتمبر',\n    'أكتوبر',\n    'نوفمبر',\n    'ديسمبر'\n];\n\nexport default moment.defineLocale('ar-ly', {\n    months : months,\n    monthsShort : months,\n    weekdays : 'الأحد_الإثنين_الثلاثاء_الأربعاء_الخميس_الجمعة_السبت'.split('_'),\n    weekdaysShort : 'أحد_إثنين_ثلاثاء_أربعاء_خميس_جمعة_سبت'.split('_'),\n    weekdaysMin : 'ح_ن_ث_ر_خ_ج_س'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'D/\\u200FM/\\u200FYYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY HH:mm',\n        LLLL : 'dddd D MMMM YYYY HH:mm'\n    },\n    meridiemParse: /ص|م/,\n    isPM : function (input) {\n        return 'م' === input;\n    },\n    meridiem : function (hour, minute, isLower) {\n        if (hour < 12) {\n            return 'ص';\n        } else {\n            return 'م';\n        }\n    },\n    calendar : {\n        sameDay: '[اليوم عند الساعة] LT',\n        nextDay: '[غدًا عند الساعة] LT',\n        nextWeek: 'dddd [عند الساعة] LT',\n        lastDay: '[أمس عند الساعة] LT',\n        lastWeek: 'dddd [عند الساعة] LT',\n        sameElse: 'L'\n    },\n    relativeTime : {\n        future : 'بعد %s',\n        past : 'منذ %s',\n        s : pluralize('s'),\n        m : pluralize('m'),\n        mm : pluralize('m'),\n        h : pluralize('h'),\n        hh : pluralize('h'),\n        d : pluralize('d'),\n        dd : pluralize('d'),\n        M : pluralize('M'),\n        MM : pluralize('M'),\n        y : pluralize('y'),\n        yy : pluralize('y')\n    },\n    preparse: function (string) {\n        return string.replace(/\\u200f/g, '').replace(/،/g, ',');\n    },\n    postformat: function (string) {\n        return string.replace(/\\d/g, function (match) {\n            return symbolMap[match];\n        }).replace(/,/g, '،');\n    },\n    week : {\n        dow : 6, // Saturday is the first day of the week.\n        doy : 12  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/locale/ar-ma.js",
    "content": "//! moment.js locale configuration\n//! locale : Arabic (Morocco) [ar-ma]\n//! author : ElFadili Yassine : https://github.com/ElFadiliY\n//! author : Abdel Said : https://github.com/abdelsaid\n\nimport moment from '../moment';\n\nexport default moment.defineLocale('ar-ma', {\n    months : 'يناير_فبراير_مارس_أبريل_ماي_يونيو_يوليوز_غشت_شتنبر_أكتوبر_نونبر_دجنبر'.split('_'),\n    monthsShort : 'يناير_فبراير_مارس_أبريل_ماي_يونيو_يوليوز_غشت_شتنبر_أكتوبر_نونبر_دجنبر'.split('_'),\n    weekdays : 'الأحد_الإتنين_الثلاثاء_الأربعاء_الخميس_الجمعة_السبت'.split('_'),\n    weekdaysShort : 'احد_اتنين_ثلاثاء_اربعاء_خميس_جمعة_سبت'.split('_'),\n    weekdaysMin : 'ح_ن_ث_ر_خ_ج_س'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY HH:mm',\n        LLLL : 'dddd D MMMM YYYY HH:mm'\n    },\n    calendar : {\n        sameDay: '[اليوم على الساعة] LT',\n        nextDay: '[غدا على الساعة] LT',\n        nextWeek: 'dddd [على الساعة] LT',\n        lastDay: '[أمس على الساعة] LT',\n        lastWeek: 'dddd [على الساعة] LT',\n        sameElse: 'L'\n    },\n    relativeTime : {\n        future : 'في %s',\n        past : 'منذ %s',\n        s : 'ثوان',\n        m : 'دقيقة',\n        mm : '%d دقائق',\n        h : 'ساعة',\n        hh : '%d ساعات',\n        d : 'يوم',\n        dd : '%d أيام',\n        M : 'شهر',\n        MM : '%d أشهر',\n        y : 'سنة',\n        yy : '%d سنوات'\n    },\n    week : {\n        dow : 6, // Saturday is the first day of the week.\n        doy : 12  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/locale/ar-sa.js",
    "content": "//! moment.js locale configuration\n//! locale : Arabic (Saudi Arabia) [ar-sa]\n//! author : Suhail Alkowaileet : https://github.com/xsoh\n\nimport moment from '../moment';\n\nvar symbolMap = {\n    '1': '١',\n    '2': '٢',\n    '3': '٣',\n    '4': '٤',\n    '5': '٥',\n    '6': '٦',\n    '7': '٧',\n    '8': '٨',\n    '9': '٩',\n    '0': '٠'\n}, numberMap = {\n    '١': '1',\n    '٢': '2',\n    '٣': '3',\n    '٤': '4',\n    '٥': '5',\n    '٦': '6',\n    '٧': '7',\n    '٨': '8',\n    '٩': '9',\n    '٠': '0'\n};\n\nexport default moment.defineLocale('ar-sa', {\n    months : 'يناير_فبراير_مارس_أبريل_مايو_يونيو_يوليو_أغسطس_سبتمبر_أكتوبر_نوفمبر_ديسمبر'.split('_'),\n    monthsShort : 'يناير_فبراير_مارس_أبريل_مايو_يونيو_يوليو_أغسطس_سبتمبر_أكتوبر_نوفمبر_ديسمبر'.split('_'),\n    weekdays : 'الأحد_الإثنين_الثلاثاء_الأربعاء_الخميس_الجمعة_السبت'.split('_'),\n    weekdaysShort : 'أحد_إثنين_ثلاثاء_أربعاء_خميس_جمعة_سبت'.split('_'),\n    weekdaysMin : 'ح_ن_ث_ر_خ_ج_س'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY HH:mm',\n        LLLL : 'dddd D MMMM YYYY HH:mm'\n    },\n    meridiemParse: /ص|م/,\n    isPM : function (input) {\n        return 'م' === input;\n    },\n    meridiem : function (hour, minute, isLower) {\n        if (hour < 12) {\n            return 'ص';\n        } else {\n            return 'م';\n        }\n    },\n    calendar : {\n        sameDay: '[اليوم على الساعة] LT',\n        nextDay: '[غدا على الساعة] LT',\n        nextWeek: 'dddd [على الساعة] LT',\n        lastDay: '[أمس على الساعة] LT',\n        lastWeek: 'dddd [على الساعة] LT',\n        sameElse: 'L'\n    },\n    relativeTime : {\n        future : 'في %s',\n        past : 'منذ %s',\n        s : 'ثوان',\n        m : 'دقيقة',\n        mm : '%d دقائق',\n        h : 'ساعة',\n        hh : '%d ساعات',\n        d : 'يوم',\n        dd : '%d أيام',\n        M : 'شهر',\n        MM : '%d أشهر',\n        y : 'سنة',\n        yy : '%d سنوات'\n    },\n    preparse: function (string) {\n        return string.replace(/[١٢٣٤٥٦٧٨٩٠]/g, function (match) {\n            return numberMap[match];\n        }).replace(/،/g, ',');\n    },\n    postformat: function (string) {\n        return string.replace(/\\d/g, function (match) {\n            return symbolMap[match];\n        }).replace(/,/g, '،');\n    },\n    week : {\n        dow : 0, // Sunday is the first day of the week.\n        doy : 6  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/locale/ar-tn.js",
    "content": "//! moment.js locale configuration\n//! locale  :  Arabic (Tunisia) [ar-tn]\n//! author : Nader Toukabri : https://github.com/naderio\n\nimport moment from '../moment';\n\nexport default moment.defineLocale('ar-tn', {\n    months: 'جانفي_فيفري_مارس_أفريل_ماي_جوان_جويلية_أوت_سبتمبر_أكتوبر_نوفمبر_ديسمبر'.split('_'),\n    monthsShort: 'جانفي_فيفري_مارس_أفريل_ماي_جوان_جويلية_أوت_سبتمبر_أكتوبر_نوفمبر_ديسمبر'.split('_'),\n    weekdays: 'الأحد_الإثنين_الثلاثاء_الأربعاء_الخميس_الجمعة_السبت'.split('_'),\n    weekdaysShort: 'أحد_إثنين_ثلاثاء_أربعاء_خميس_جمعة_سبت'.split('_'),\n    weekdaysMin: 'ح_ن_ث_ر_خ_ج_س'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat: {\n        LT: 'HH:mm',\n        LTS: 'HH:mm:ss',\n        L: 'DD/MM/YYYY',\n        LL: 'D MMMM YYYY',\n        LLL: 'D MMMM YYYY HH:mm',\n        LLLL: 'dddd D MMMM YYYY HH:mm'\n    },\n    calendar: {\n        sameDay: '[اليوم على الساعة] LT',\n        nextDay: '[غدا على الساعة] LT',\n        nextWeek: 'dddd [على الساعة] LT',\n        lastDay: '[أمس على الساعة] LT',\n        lastWeek: 'dddd [على الساعة] LT',\n        sameElse: 'L'\n    },\n    relativeTime: {\n        future: 'في %s',\n        past: 'منذ %s',\n        s: 'ثوان',\n        m: 'دقيقة',\n        mm: '%d دقائق',\n        h: 'ساعة',\n        hh: '%d ساعات',\n        d: 'يوم',\n        dd: '%d أيام',\n        M: 'شهر',\n        MM: '%d أشهر',\n        y: 'سنة',\n        yy: '%d سنوات'\n    },\n    week: {\n        dow: 1, // Monday is the first day of the week.\n        doy: 4 // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/locale/ar.js",
    "content": "//! moment.js locale configuration\n//! locale : Arabic [ar]\n//! author : Abdel Said: https://github.com/abdelsaid\n//! author : Ahmed Elkhatib\n//! author : forabi https://github.com/forabi\n\nimport moment from '../moment';\n\nvar symbolMap = {\n    '1': '١',\n    '2': '٢',\n    '3': '٣',\n    '4': '٤',\n    '5': '٥',\n    '6': '٦',\n    '7': '٧',\n    '8': '٨',\n    '9': '٩',\n    '0': '٠'\n}, numberMap = {\n    '١': '1',\n    '٢': '2',\n    '٣': '3',\n    '٤': '4',\n    '٥': '5',\n    '٦': '6',\n    '٧': '7',\n    '٨': '8',\n    '٩': '9',\n    '٠': '0'\n}, pluralForm = function (n) {\n    return n === 0 ? 0 : n === 1 ? 1 : n === 2 ? 2 : n % 100 >= 3 && n % 100 <= 10 ? 3 : n % 100 >= 11 ? 4 : 5;\n}, plurals = {\n    s : ['أقل من ثانية', 'ثانية واحدة', ['ثانيتان', 'ثانيتين'], '%d ثوان', '%d ثانية', '%d ثانية'],\n    m : ['أقل من دقيقة', 'دقيقة واحدة', ['دقيقتان', 'دقيقتين'], '%d دقائق', '%d دقيقة', '%d دقيقة'],\n    h : ['أقل من ساعة', 'ساعة واحدة', ['ساعتان', 'ساعتين'], '%d ساعات', '%d ساعة', '%d ساعة'],\n    d : ['أقل من يوم', 'يوم واحد', ['يومان', 'يومين'], '%d أيام', '%d يومًا', '%d يوم'],\n    M : ['أقل من شهر', 'شهر واحد', ['شهران', 'شهرين'], '%d أشهر', '%d شهرا', '%d شهر'],\n    y : ['أقل من عام', 'عام واحد', ['عامان', 'عامين'], '%d أعوام', '%d عامًا', '%d عام']\n}, pluralize = function (u) {\n    return function (number, withoutSuffix, string, isFuture) {\n        var f = pluralForm(number),\n            str = plurals[u][pluralForm(number)];\n        if (f === 2) {\n            str = str[withoutSuffix ? 0 : 1];\n        }\n        return str.replace(/%d/i, number);\n    };\n}, months = [\n    'كانون الثاني يناير',\n    'شباط فبراير',\n    'آذار مارس',\n    'نيسان أبريل',\n    'أيار مايو',\n    'حزيران يونيو',\n    'تموز يوليو',\n    'آب أغسطس',\n    'أيلول سبتمبر',\n    'تشرين الأول أكتوبر',\n    'تشرين الثاني نوفمبر',\n    'كانون الأول ديسمبر'\n];\n\nexport default moment.defineLocale('ar', {\n    months : months,\n    monthsShort : months,\n    weekdays : 'الأحد_الإثنين_الثلاثاء_الأربعاء_الخميس_الجمعة_السبت'.split('_'),\n    weekdaysShort : 'أحد_إثنين_ثلاثاء_أربعاء_خميس_جمعة_سبت'.split('_'),\n    weekdaysMin : 'ح_ن_ث_ر_خ_ج_س'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'D/\\u200FM/\\u200FYYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY HH:mm',\n        LLLL : 'dddd D MMMM YYYY HH:mm'\n    },\n    meridiemParse: /ص|م/,\n    isPM : function (input) {\n        return 'م' === input;\n    },\n    meridiem : function (hour, minute, isLower) {\n        if (hour < 12) {\n            return 'ص';\n        } else {\n            return 'م';\n        }\n    },\n    calendar : {\n        sameDay: '[اليوم عند الساعة] LT',\n        nextDay: '[غدًا عند الساعة] LT',\n        nextWeek: 'dddd [عند الساعة] LT',\n        lastDay: '[أمس عند الساعة] LT',\n        lastWeek: 'dddd [عند الساعة] LT',\n        sameElse: 'L'\n    },\n    relativeTime : {\n        future : 'بعد %s',\n        past : 'منذ %s',\n        s : pluralize('s'),\n        m : pluralize('m'),\n        mm : pluralize('m'),\n        h : pluralize('h'),\n        hh : pluralize('h'),\n        d : pluralize('d'),\n        dd : pluralize('d'),\n        M : pluralize('M'),\n        MM : pluralize('M'),\n        y : pluralize('y'),\n        yy : pluralize('y')\n    },\n    preparse: function (string) {\n        return string.replace(/\\u200f/g, '').replace(/[١٢٣٤٥٦٧٨٩٠]/g, function (match) {\n            return numberMap[match];\n        }).replace(/،/g, ',');\n    },\n    postformat: function (string) {\n        return string.replace(/\\d/g, function (match) {\n            return symbolMap[match];\n        }).replace(/,/g, '،');\n    },\n    week : {\n        dow : 6, // Saturday is the first day of the week.\n        doy : 12  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/locale/az.js",
    "content": "//! moment.js locale configuration\n//! locale : Azerbaijani [az]\n//! author : topchiyev : https://github.com/topchiyev\n\nimport moment from '../moment';\n\nvar suffixes = {\n    1: '-inci',\n    5: '-inci',\n    8: '-inci',\n    70: '-inci',\n    80: '-inci',\n    2: '-nci',\n    7: '-nci',\n    20: '-nci',\n    50: '-nci',\n    3: '-üncü',\n    4: '-üncü',\n    100: '-üncü',\n    6: '-ncı',\n    9: '-uncu',\n    10: '-uncu',\n    30: '-uncu',\n    60: '-ıncı',\n    90: '-ıncı'\n};\n\nexport default moment.defineLocale('az', {\n    months : 'yanvar_fevral_mart_aprel_may_iyun_iyul_avqust_sentyabr_oktyabr_noyabr_dekabr'.split('_'),\n    monthsShort : 'yan_fev_mar_apr_may_iyn_iyl_avq_sen_okt_noy_dek'.split('_'),\n    weekdays : 'Bazar_Bazar ertəsi_Çərşənbə axşamı_Çərşənbə_Cümə axşamı_Cümə_Şənbə'.split('_'),\n    weekdaysShort : 'Baz_BzE_ÇAx_Çər_CAx_Cüm_Şən'.split('_'),\n    weekdaysMin : 'Bz_BE_ÇA_Çə_CA_Cü_Şə'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD.MM.YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY HH:mm',\n        LLLL : 'dddd, D MMMM YYYY HH:mm'\n    },\n    calendar : {\n        sameDay : '[bugün saat] LT',\n        nextDay : '[sabah saat] LT',\n        nextWeek : '[gələn həftə] dddd [saat] LT',\n        lastDay : '[dünən] LT',\n        lastWeek : '[keçən həftə] dddd [saat] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : '%s sonra',\n        past : '%s əvvəl',\n        s : 'birneçə saniyyə',\n        m : 'bir dəqiqə',\n        mm : '%d dəqiqə',\n        h : 'bir saat',\n        hh : '%d saat',\n        d : 'bir gün',\n        dd : '%d gün',\n        M : 'bir ay',\n        MM : '%d ay',\n        y : 'bir il',\n        yy : '%d il'\n    },\n    meridiemParse: /gecə|səhər|gündüz|axşam/,\n    isPM : function (input) {\n        return /^(gündüz|axşam)$/.test(input);\n    },\n    meridiem : function (hour, minute, isLower) {\n        if (hour < 4) {\n            return 'gecə';\n        } else if (hour < 12) {\n            return 'səhər';\n        } else if (hour < 17) {\n            return 'gündüz';\n        } else {\n            return 'axşam';\n        }\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}-(ıncı|inci|nci|üncü|ncı|uncu)/,\n    ordinal : function (number) {\n        if (number === 0) {  // special case for zero\n            return number + '-ıncı';\n        }\n        var a = number % 10,\n            b = number % 100 - a,\n            c = number >= 100 ? 100 : null;\n        return number + (suffixes[a] || suffixes[b] || suffixes[c]);\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 7  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/locale/be.js",
    "content": "//! moment.js locale configuration\n//! locale : Belarusian [be]\n//! author : Dmitry Demidov : https://github.com/demidov91\n//! author: Praleska: http://praleska.pro/\n//! Author : Menelion Elensúle : https://github.com/Oire\n\nimport moment from '../moment';\n\nfunction plural(word, num) {\n    var forms = word.split('_');\n    return num % 10 === 1 && num % 100 !== 11 ? forms[0] : (num % 10 >= 2 && num % 10 <= 4 && (num % 100 < 10 || num % 100 >= 20) ? forms[1] : forms[2]);\n}\nfunction relativeTimeWithPlural(number, withoutSuffix, key) {\n    var format = {\n        'mm': withoutSuffix ? 'хвіліна_хвіліны_хвілін' : 'хвіліну_хвіліны_хвілін',\n        'hh': withoutSuffix ? 'гадзіна_гадзіны_гадзін' : 'гадзіну_гадзіны_гадзін',\n        'dd': 'дзень_дні_дзён',\n        'MM': 'месяц_месяцы_месяцаў',\n        'yy': 'год_гады_гадоў'\n    };\n    if (key === 'm') {\n        return withoutSuffix ? 'хвіліна' : 'хвіліну';\n    }\n    else if (key === 'h') {\n        return withoutSuffix ? 'гадзіна' : 'гадзіну';\n    }\n    else {\n        return number + ' ' + plural(format[key], +number);\n    }\n}\n\nexport default moment.defineLocale('be', {\n    months : {\n        format: 'студзеня_лютага_сакавіка_красавіка_траўня_чэрвеня_ліпеня_жніўня_верасня_кастрычніка_лістапада_снежня'.split('_'),\n        standalone: 'студзень_люты_сакавік_красавік_травень_чэрвень_ліпень_жнівень_верасень_кастрычнік_лістапад_снежань'.split('_')\n    },\n    monthsShort : 'студ_лют_сак_крас_трав_чэрв_ліп_жнів_вер_каст_ліст_снеж'.split('_'),\n    weekdays : {\n        format: 'нядзелю_панядзелак_аўторак_сераду_чацвер_пятніцу_суботу'.split('_'),\n        standalone: 'нядзеля_панядзелак_аўторак_серада_чацвер_пятніца_субота'.split('_'),\n        isFormat: /\\[ ?[Вв] ?(?:мінулую|наступную)? ?\\] ?dddd/\n    },\n    weekdaysShort : 'нд_пн_ат_ср_чц_пт_сб'.split('_'),\n    weekdaysMin : 'нд_пн_ат_ср_чц_пт_сб'.split('_'),\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD.MM.YYYY',\n        LL : 'D MMMM YYYY г.',\n        LLL : 'D MMMM YYYY г., HH:mm',\n        LLLL : 'dddd, D MMMM YYYY г., HH:mm'\n    },\n    calendar : {\n        sameDay: '[Сёння ў] LT',\n        nextDay: '[Заўтра ў] LT',\n        lastDay: '[Учора ў] LT',\n        nextWeek: function () {\n            return '[У] dddd [ў] LT';\n        },\n        lastWeek: function () {\n            switch (this.day()) {\n                case 0:\n                case 3:\n                case 5:\n                case 6:\n                    return '[У мінулую] dddd [ў] LT';\n                case 1:\n                case 2:\n                case 4:\n                    return '[У мінулы] dddd [ў] LT';\n            }\n        },\n        sameElse: 'L'\n    },\n    relativeTime : {\n        future : 'праз %s',\n        past : '%s таму',\n        s : 'некалькі секунд',\n        m : relativeTimeWithPlural,\n        mm : relativeTimeWithPlural,\n        h : relativeTimeWithPlural,\n        hh : relativeTimeWithPlural,\n        d : 'дзень',\n        dd : relativeTimeWithPlural,\n        M : 'месяц',\n        MM : relativeTimeWithPlural,\n        y : 'год',\n        yy : relativeTimeWithPlural\n    },\n    meridiemParse: /ночы|раніцы|дня|вечара/,\n    isPM : function (input) {\n        return /^(дня|вечара)$/.test(input);\n    },\n    meridiem : function (hour, minute, isLower) {\n        if (hour < 4) {\n            return 'ночы';\n        } else if (hour < 12) {\n            return 'раніцы';\n        } else if (hour < 17) {\n            return 'дня';\n        } else {\n            return 'вечара';\n        }\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}-(і|ы|га)/,\n    ordinal: function (number, period) {\n        switch (period) {\n            case 'M':\n            case 'd':\n            case 'DDD':\n            case 'w':\n            case 'W':\n                return (number % 10 === 2 || number % 10 === 3) && (number % 100 !== 12 && number % 100 !== 13) ? number + '-і' : number + '-ы';\n            case 'D':\n                return number + '-га';\n            default:\n                return number;\n        }\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 7  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/locale/bg.js",
    "content": "//! moment.js locale configuration\n//! locale : Bulgarian [bg]\n//! author : Krasen Borisov : https://github.com/kraz\n\nimport moment from '../moment';\n\nexport default moment.defineLocale('bg', {\n    months : 'януари_февруари_март_април_май_юни_юли_август_септември_октомври_ноември_декември'.split('_'),\n    monthsShort : 'янр_фев_мар_апр_май_юни_юли_авг_сеп_окт_ное_дек'.split('_'),\n    weekdays : 'неделя_понеделник_вторник_сряда_четвъртък_петък_събота'.split('_'),\n    weekdaysShort : 'нед_пон_вто_сря_чет_пет_съб'.split('_'),\n    weekdaysMin : 'нд_пн_вт_ср_чт_пт_сб'.split('_'),\n    longDateFormat : {\n        LT : 'H:mm',\n        LTS : 'H:mm:ss',\n        L : 'D.MM.YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY H:mm',\n        LLLL : 'dddd, D MMMM YYYY H:mm'\n    },\n    calendar : {\n        sameDay : '[Днес в] LT',\n        nextDay : '[Утре в] LT',\n        nextWeek : 'dddd [в] LT',\n        lastDay : '[Вчера в] LT',\n        lastWeek : function () {\n            switch (this.day()) {\n                case 0:\n                case 3:\n                case 6:\n                    return '[В изминалата] dddd [в] LT';\n                case 1:\n                case 2:\n                case 4:\n                case 5:\n                    return '[В изминалия] dddd [в] LT';\n            }\n        },\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'след %s',\n        past : 'преди %s',\n        s : 'няколко секунди',\n        m : 'минута',\n        mm : '%d минути',\n        h : 'час',\n        hh : '%d часа',\n        d : 'ден',\n        dd : '%d дни',\n        M : 'месец',\n        MM : '%d месеца',\n        y : 'година',\n        yy : '%d години'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}-(ев|ен|ти|ви|ри|ми)/,\n    ordinal : function (number) {\n        var lastDigit = number % 10,\n            last2Digits = number % 100;\n        if (number === 0) {\n            return number + '-ев';\n        } else if (last2Digits === 0) {\n            return number + '-ен';\n        } else if (last2Digits > 10 && last2Digits < 20) {\n            return number + '-ти';\n        } else if (lastDigit === 1) {\n            return number + '-ви';\n        } else if (lastDigit === 2) {\n            return number + '-ри';\n        } else if (lastDigit === 7 || lastDigit === 8) {\n            return number + '-ми';\n        } else {\n            return number + '-ти';\n        }\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 7  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/locale/bn.js",
    "content": "//! moment.js locale configuration\n//! locale : Bengali [bn]\n//! author : Kaushik Gandhi : https://github.com/kaushikgandhi\n\nimport moment from '../moment';\n\nvar symbolMap = {\n    '1': '১',\n    '2': '২',\n    '3': '৩',\n    '4': '৪',\n    '5': '৫',\n    '6': '৬',\n    '7': '৭',\n    '8': '৮',\n    '9': '৯',\n    '0': '০'\n},\nnumberMap = {\n    '১': '1',\n    '২': '2',\n    '৩': '3',\n    '৪': '4',\n    '৫': '5',\n    '৬': '6',\n    '৭': '7',\n    '৮': '8',\n    '৯': '9',\n    '০': '0'\n};\n\nexport default moment.defineLocale('bn', {\n    months : 'জানুয়ারী_ফেব্রুয়ারি_মার্চ_এপ্রিল_মে_জুন_জুলাই_আগস্ট_সেপ্টেম্বর_অক্টোবর_নভেম্বর_ডিসেম্বর'.split('_'),\n    monthsShort : 'জানু_ফেব_মার্চ_এপ্র_মে_জুন_জুল_আগ_সেপ্ট_অক্টো_নভে_ডিসে'.split('_'),\n    weekdays : 'রবিবার_সোমবার_মঙ্গলবার_বুধবার_বৃহস্পতিবার_শুক্রবার_শনিবার'.split('_'),\n    weekdaysShort : 'রবি_সোম_মঙ্গল_বুধ_বৃহস্পতি_শুক্র_শনি'.split('_'),\n    weekdaysMin : 'রবি_সোম_মঙ্গ_বুধ_বৃহঃ_শুক্র_শনি'.split('_'),\n    longDateFormat : {\n        LT : 'A h:mm সময়',\n        LTS : 'A h:mm:ss সময়',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY, A h:mm সময়',\n        LLLL : 'dddd, D MMMM YYYY, A h:mm সময়'\n    },\n    calendar : {\n        sameDay : '[আজ] LT',\n        nextDay : '[আগামীকাল] LT',\n        nextWeek : 'dddd, LT',\n        lastDay : '[গতকাল] LT',\n        lastWeek : '[গত] dddd, LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : '%s পরে',\n        past : '%s আগে',\n        s : 'কয়েক সেকেন্ড',\n        m : 'এক মিনিট',\n        mm : '%d মিনিট',\n        h : 'এক ঘন্টা',\n        hh : '%d ঘন্টা',\n        d : 'এক দিন',\n        dd : '%d দিন',\n        M : 'এক মাস',\n        MM : '%d মাস',\n        y : 'এক বছর',\n        yy : '%d বছর'\n    },\n    preparse: function (string) {\n        return string.replace(/[১২৩৪৫৬৭৮৯০]/g, function (match) {\n            return numberMap[match];\n        });\n    },\n    postformat: function (string) {\n        return string.replace(/\\d/g, function (match) {\n            return symbolMap[match];\n        });\n    },\n    meridiemParse: /রাত|সকাল|দুপুর|বিকাল|রাত/,\n    meridiemHour : function (hour, meridiem) {\n        if (hour === 12) {\n            hour = 0;\n        }\n        if ((meridiem === 'রাত' && hour >= 4) ||\n                (meridiem === 'দুপুর' && hour < 5) ||\n                meridiem === 'বিকাল') {\n            return hour + 12;\n        } else {\n            return hour;\n        }\n    },\n    meridiem : function (hour, minute, isLower) {\n        if (hour < 4) {\n            return 'রাত';\n        } else if (hour < 10) {\n            return 'সকাল';\n        } else if (hour < 17) {\n            return 'দুপুর';\n        } else if (hour < 20) {\n            return 'বিকাল';\n        } else {\n            return 'রাত';\n        }\n    },\n    week : {\n        dow : 0, // Sunday is the first day of the week.\n        doy : 6  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/locale/bo.js",
    "content": "//! moment.js locale configuration\n//! locale : Tibetan [bo]\n//! author : Thupten N. Chakrishar : https://github.com/vajradog\n\nimport moment from '../moment';\n\nvar symbolMap = {\n    '1': '༡',\n    '2': '༢',\n    '3': '༣',\n    '4': '༤',\n    '5': '༥',\n    '6': '༦',\n    '7': '༧',\n    '8': '༨',\n    '9': '༩',\n    '0': '༠'\n},\nnumberMap = {\n    '༡': '1',\n    '༢': '2',\n    '༣': '3',\n    '༤': '4',\n    '༥': '5',\n    '༦': '6',\n    '༧': '7',\n    '༨': '8',\n    '༩': '9',\n    '༠': '0'\n};\n\nexport default moment.defineLocale('bo', {\n    months : 'ཟླ་བ་དང་པོ_ཟླ་བ་གཉིས་པ_ཟླ་བ་གསུམ་པ_ཟླ་བ་བཞི་པ_ཟླ་བ་ལྔ་པ_ཟླ་བ་དྲུག་པ_ཟླ་བ་བདུན་པ_ཟླ་བ་བརྒྱད་པ_ཟླ་བ་དགུ་པ_ཟླ་བ་བཅུ་པ_ཟླ་བ་བཅུ་གཅིག་པ_ཟླ་བ་བཅུ་གཉིས་པ'.split('_'),\n    monthsShort : 'ཟླ་བ་དང་པོ_ཟླ་བ་གཉིས་པ_ཟླ་བ་གསུམ་པ_ཟླ་བ་བཞི་པ_ཟླ་བ་ལྔ་པ_ཟླ་བ་དྲུག་པ_ཟླ་བ་བདུན་པ_ཟླ་བ་བརྒྱད་པ_ཟླ་བ་དགུ་པ_ཟླ་བ་བཅུ་པ_ཟླ་བ་བཅུ་གཅིག་པ_ཟླ་བ་བཅུ་གཉིས་པ'.split('_'),\n    weekdays : 'གཟའ་ཉི་མ་_གཟའ་ཟླ་བ་_གཟའ་མིག་དམར་_གཟའ་ལྷག་པ་_གཟའ་ཕུར་བུ_གཟའ་པ་སངས་_གཟའ་སྤེན་པ་'.split('_'),\n    weekdaysShort : 'ཉི་མ་_ཟླ་བ་_མིག་དམར་_ལྷག་པ་_ཕུར་བུ_པ་སངས་_སྤེན་པ་'.split('_'),\n    weekdaysMin : 'ཉི་མ་_ཟླ་བ་_མིག་དམར་_ལྷག་པ་_ཕུར་བུ_པ་སངས་_སྤེན་པ་'.split('_'),\n    longDateFormat : {\n        LT : 'A h:mm',\n        LTS : 'A h:mm:ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY, A h:mm',\n        LLLL : 'dddd, D MMMM YYYY, A h:mm'\n    },\n    calendar : {\n        sameDay : '[དི་རིང] LT',\n        nextDay : '[སང་ཉིན] LT',\n        nextWeek : '[བདུན་ཕྲག་རྗེས་མ], LT',\n        lastDay : '[ཁ་སང] LT',\n        lastWeek : '[བདུན་ཕྲག་མཐའ་མ] dddd, LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : '%s ལ་',\n        past : '%s སྔན་ལ',\n        s : 'ལམ་སང',\n        m : 'སྐར་མ་གཅིག',\n        mm : '%d སྐར་མ',\n        h : 'ཆུ་ཚོད་གཅིག',\n        hh : '%d ཆུ་ཚོད',\n        d : 'ཉིན་གཅིག',\n        dd : '%d ཉིན་',\n        M : 'ཟླ་བ་གཅིག',\n        MM : '%d ཟླ་བ',\n        y : 'ལོ་གཅིག',\n        yy : '%d ལོ'\n    },\n    preparse: function (string) {\n        return string.replace(/[༡༢༣༤༥༦༧༨༩༠]/g, function (match) {\n            return numberMap[match];\n        });\n    },\n    postformat: function (string) {\n        return string.replace(/\\d/g, function (match) {\n            return symbolMap[match];\n        });\n    },\n    meridiemParse: /མཚན་མོ|ཞོགས་ཀས|ཉིན་གུང|དགོང་དག|མཚན་མོ/,\n    meridiemHour : function (hour, meridiem) {\n        if (hour === 12) {\n            hour = 0;\n        }\n        if ((meridiem === 'མཚན་མོ' && hour >= 4) ||\n                (meridiem === 'ཉིན་གུང' && hour < 5) ||\n                meridiem === 'དགོང་དག') {\n            return hour + 12;\n        } else {\n            return hour;\n        }\n    },\n    meridiem : function (hour, minute, isLower) {\n        if (hour < 4) {\n            return 'མཚན་མོ';\n        } else if (hour < 10) {\n            return 'ཞོགས་ཀས';\n        } else if (hour < 17) {\n            return 'ཉིན་གུང';\n        } else if (hour < 20) {\n            return 'དགོང་དག';\n        } else {\n            return 'མཚན་མོ';\n        }\n    },\n    week : {\n        dow : 0, // Sunday is the first day of the week.\n        doy : 6  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/locale/br.js",
    "content": "//! moment.js locale configuration\n//! locale : Breton [br]\n//! author : Jean-Baptiste Le Duigou : https://github.com/jbleduigou\n\nimport moment from '../moment';\n\nfunction relativeTimeWithMutation(number, withoutSuffix, key) {\n    var format = {\n        'mm': 'munutenn',\n        'MM': 'miz',\n        'dd': 'devezh'\n    };\n    return number + ' ' + mutation(format[key], number);\n}\nfunction specialMutationForYears(number) {\n    switch (lastNumber(number)) {\n        case 1:\n        case 3:\n        case 4:\n        case 5:\n        case 9:\n            return number + ' bloaz';\n        default:\n            return number + ' vloaz';\n    }\n}\nfunction lastNumber(number) {\n    if (number > 9) {\n        return lastNumber(number % 10);\n    }\n    return number;\n}\nfunction mutation(text, number) {\n    if (number === 2) {\n        return softMutation(text);\n    }\n    return text;\n}\nfunction softMutation(text) {\n    var mutationTable = {\n        'm': 'v',\n        'b': 'v',\n        'd': 'z'\n    };\n    if (mutationTable[text.charAt(0)] === undefined) {\n        return text;\n    }\n    return mutationTable[text.charAt(0)] + text.substring(1);\n}\n\nexport default moment.defineLocale('br', {\n    months : 'Genver_C\\'hwevrer_Meurzh_Ebrel_Mae_Mezheven_Gouere_Eost_Gwengolo_Here_Du_Kerzu'.split('_'),\n    monthsShort : 'Gen_C\\'hwe_Meu_Ebr_Mae_Eve_Gou_Eos_Gwe_Her_Du_Ker'.split('_'),\n    weekdays : 'Sul_Lun_Meurzh_Merc\\'her_Yaou_Gwener_Sadorn'.split('_'),\n    weekdaysShort : 'Sul_Lun_Meu_Mer_Yao_Gwe_Sad'.split('_'),\n    weekdaysMin : 'Su_Lu_Me_Mer_Ya_Gw_Sa'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat : {\n        LT : 'h[e]mm A',\n        LTS : 'h[e]mm:ss A',\n        L : 'DD/MM/YYYY',\n        LL : 'D [a viz] MMMM YYYY',\n        LLL : 'D [a viz] MMMM YYYY h[e]mm A',\n        LLLL : 'dddd, D [a viz] MMMM YYYY h[e]mm A'\n    },\n    calendar : {\n        sameDay : '[Hiziv da] LT',\n        nextDay : '[Warc\\'hoazh da] LT',\n        nextWeek : 'dddd [da] LT',\n        lastDay : '[Dec\\'h da] LT',\n        lastWeek : 'dddd [paset da] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'a-benn %s',\n        past : '%s \\'zo',\n        s : 'un nebeud segondennoù',\n        m : 'ur vunutenn',\n        mm : relativeTimeWithMutation,\n        h : 'un eur',\n        hh : '%d eur',\n        d : 'un devezh',\n        dd : relativeTimeWithMutation,\n        M : 'ur miz',\n        MM : relativeTimeWithMutation,\n        y : 'ur bloaz',\n        yy : specialMutationForYears\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}(añ|vet)/,\n    ordinal : function (number) {\n        var output = (number === 1) ? 'añ' : 'vet';\n        return number + output;\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/locale/bs.js",
    "content": "//! moment.js locale configuration\n//! locale : Bosnian [bs]\n//! author : Nedim Cholich : https://github.com/frontyard\n//! based on (hr) translation by Bojan Marković\n\nimport moment from '../moment';\n\nfunction translate(number, withoutSuffix, key) {\n    var result = number + ' ';\n    switch (key) {\n        case 'm':\n            return withoutSuffix ? 'jedna minuta' : 'jedne minute';\n        case 'mm':\n            if (number === 1) {\n                result += 'minuta';\n            } else if (number === 2 || number === 3 || number === 4) {\n                result += 'minute';\n            } else {\n                result += 'minuta';\n            }\n            return result;\n        case 'h':\n            return withoutSuffix ? 'jedan sat' : 'jednog sata';\n        case 'hh':\n            if (number === 1) {\n                result += 'sat';\n            } else if (number === 2 || number === 3 || number === 4) {\n                result += 'sata';\n            } else {\n                result += 'sati';\n            }\n            return result;\n        case 'dd':\n            if (number === 1) {\n                result += 'dan';\n            } else {\n                result += 'dana';\n            }\n            return result;\n        case 'MM':\n            if (number === 1) {\n                result += 'mjesec';\n            } else if (number === 2 || number === 3 || number === 4) {\n                result += 'mjeseca';\n            } else {\n                result += 'mjeseci';\n            }\n            return result;\n        case 'yy':\n            if (number === 1) {\n                result += 'godina';\n            } else if (number === 2 || number === 3 || number === 4) {\n                result += 'godine';\n            } else {\n                result += 'godina';\n            }\n            return result;\n    }\n}\n\nexport default moment.defineLocale('bs', {\n    months : 'januar_februar_mart_april_maj_juni_juli_august_septembar_oktobar_novembar_decembar'.split('_'),\n    monthsShort : 'jan._feb._mar._apr._maj._jun._jul._aug._sep._okt._nov._dec.'.split('_'),\n    monthsParseExact: true,\n    weekdays : 'nedjelja_ponedjeljak_utorak_srijeda_četvrtak_petak_subota'.split('_'),\n    weekdaysShort : 'ned._pon._uto._sri._čet._pet._sub.'.split('_'),\n    weekdaysMin : 'ne_po_ut_sr_če_pe_su'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat : {\n        LT : 'H:mm',\n        LTS : 'H:mm:ss',\n        L : 'DD.MM.YYYY',\n        LL : 'D. MMMM YYYY',\n        LLL : 'D. MMMM YYYY H:mm',\n        LLLL : 'dddd, D. MMMM YYYY H:mm'\n    },\n    calendar : {\n        sameDay  : '[danas u] LT',\n        nextDay  : '[sutra u] LT',\n        nextWeek : function () {\n            switch (this.day()) {\n                case 0:\n                    return '[u] [nedjelju] [u] LT';\n                case 3:\n                    return '[u] [srijedu] [u] LT';\n                case 6:\n                    return '[u] [subotu] [u] LT';\n                case 1:\n                case 2:\n                case 4:\n                case 5:\n                    return '[u] dddd [u] LT';\n            }\n        },\n        lastDay  : '[jučer u] LT',\n        lastWeek : function () {\n            switch (this.day()) {\n                case 0:\n                case 3:\n                    return '[prošlu] dddd [u] LT';\n                case 6:\n                    return '[prošle] [subote] [u] LT';\n                case 1:\n                case 2:\n                case 4:\n                case 5:\n                    return '[prošli] dddd [u] LT';\n            }\n        },\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'za %s',\n        past   : 'prije %s',\n        s      : 'par sekundi',\n        m      : translate,\n        mm     : translate,\n        h      : translate,\n        hh     : translate,\n        d      : 'dan',\n        dd     : translate,\n        M      : 'mjesec',\n        MM     : translate,\n        y      : 'godinu',\n        yy     : translate\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}\\./,\n    ordinal : '%d.',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 7  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/locale/ca.js",
    "content": "//! moment.js locale configuration\n//! locale : Catalan [ca]\n//! author : Juan G. Hurtado : https://github.com/juanghurtado\n\nimport moment from '../moment';\n\nexport default moment.defineLocale('ca', {\n    months : {\n        standalone: 'gener_febrer_març_abril_maig_juny_juliol_agost_setembre_octubre_novembre_desembre'.split('_'),\n        format: 'de gener_de febrer_de març_d\\'abril_de maig_de juny_de juliol_d\\'agost_de setembre_d\\'octubre_de novembre_de desembre'.split('_'),\n        isFormat: /D[oD]?(\\s)+MMMM/\n    },\n    monthsShort : 'gen._febr._març_abr._maig_juny_jul._ag._set._oct._nov._des.'.split('_'),\n    monthsParseExact : true,\n    weekdays : 'diumenge_dilluns_dimarts_dimecres_dijous_divendres_dissabte'.split('_'),\n    weekdaysShort : 'dg._dl._dt._dc._dj._dv._ds.'.split('_'),\n    weekdaysMin : 'Dg_Dl_Dt_Dc_Dj_Dv_Ds'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat : {\n        LT : 'H:mm',\n        LTS : 'H:mm:ss',\n        L : 'DD/MM/YYYY',\n        LL : '[el] D MMMM [de] YYYY',\n        ll : 'D MMM YYYY',\n        LLL : '[el] D MMMM [de] YYYY [a les] H:mm',\n        lll : 'D MMM YYYY, H:mm',\n        LLLL : '[el] dddd D MMMM [de] YYYY [a les] H:mm',\n        llll : 'ddd D MMM YYYY, H:mm'\n    },\n    calendar : {\n        sameDay : function () {\n            return '[avui a ' + ((this.hours() !== 1) ? 'les' : 'la') + '] LT';\n        },\n        nextDay : function () {\n            return '[demà a ' + ((this.hours() !== 1) ? 'les' : 'la') + '] LT';\n        },\n        nextWeek : function () {\n            return 'dddd [a ' + ((this.hours() !== 1) ? 'les' : 'la') + '] LT';\n        },\n        lastDay : function () {\n            return '[ahir a ' + ((this.hours() !== 1) ? 'les' : 'la') + '] LT';\n        },\n        lastWeek : function () {\n            return '[el] dddd [passat a ' + ((this.hours() !== 1) ? 'les' : 'la') + '] LT';\n        },\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'd\\'aquí %s',\n        past : 'fa %s',\n        s : 'uns segons',\n        m : 'un minut',\n        mm : '%d minuts',\n        h : 'una hora',\n        hh : '%d hores',\n        d : 'un dia',\n        dd : '%d dies',\n        M : 'un mes',\n        MM : '%d mesos',\n        y : 'un any',\n        yy : '%d anys'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}(r|n|t|è|a)/,\n    ordinal : function (number, period) {\n        var output = (number === 1) ? 'r' :\n            (number === 2) ? 'n' :\n            (number === 3) ? 'r' :\n            (number === 4) ? 't' : 'è';\n        if (period === 'w' || period === 'W') {\n            output = 'a';\n        }\n        return number + output;\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/locale/cs.js",
    "content": "//! moment.js locale configuration\n//! locale : Czech [cs]\n//! author : petrbela : https://github.com/petrbela\n\nimport moment from '../moment';\n\nvar months = 'leden_únor_březen_duben_květen_červen_červenec_srpen_září_říjen_listopad_prosinec'.split('_'),\n    monthsShort = 'led_úno_bře_dub_kvě_čvn_čvc_srp_zář_říj_lis_pro'.split('_');\nfunction plural(n) {\n    return (n > 1) && (n < 5) && (~~(n / 10) !== 1);\n}\nfunction translate(number, withoutSuffix, key, isFuture) {\n    var result = number + ' ';\n    switch (key) {\n        case 's':  // a few seconds / in a few seconds / a few seconds ago\n            return (withoutSuffix || isFuture) ? 'pár sekund' : 'pár sekundami';\n        case 'm':  // a minute / in a minute / a minute ago\n            return withoutSuffix ? 'minuta' : (isFuture ? 'minutu' : 'minutou');\n        case 'mm': // 9 minutes / in 9 minutes / 9 minutes ago\n            if (withoutSuffix || isFuture) {\n                return result + (plural(number) ? 'minuty' : 'minut');\n            } else {\n                return result + 'minutami';\n            }\n            break;\n        case 'h':  // an hour / in an hour / an hour ago\n            return withoutSuffix ? 'hodina' : (isFuture ? 'hodinu' : 'hodinou');\n        case 'hh': // 9 hours / in 9 hours / 9 hours ago\n            if (withoutSuffix || isFuture) {\n                return result + (plural(number) ? 'hodiny' : 'hodin');\n            } else {\n                return result + 'hodinami';\n            }\n            break;\n        case 'd':  // a day / in a day / a day ago\n            return (withoutSuffix || isFuture) ? 'den' : 'dnem';\n        case 'dd': // 9 days / in 9 days / 9 days ago\n            if (withoutSuffix || isFuture) {\n                return result + (plural(number) ? 'dny' : 'dní');\n            } else {\n                return result + 'dny';\n            }\n            break;\n        case 'M':  // a month / in a month / a month ago\n            return (withoutSuffix || isFuture) ? 'měsíc' : 'měsícem';\n        case 'MM': // 9 months / in 9 months / 9 months ago\n            if (withoutSuffix || isFuture) {\n                return result + (plural(number) ? 'měsíce' : 'měsíců');\n            } else {\n                return result + 'měsíci';\n            }\n            break;\n        case 'y':  // a year / in a year / a year ago\n            return (withoutSuffix || isFuture) ? 'rok' : 'rokem';\n        case 'yy': // 9 years / in 9 years / 9 years ago\n            if (withoutSuffix || isFuture) {\n                return result + (plural(number) ? 'roky' : 'let');\n            } else {\n                return result + 'lety';\n            }\n            break;\n    }\n}\n\nexport default moment.defineLocale('cs', {\n    months : months,\n    monthsShort : monthsShort,\n    monthsParse : (function (months, monthsShort) {\n        var i, _monthsParse = [];\n        for (i = 0; i < 12; i++) {\n            // use custom parser to solve problem with July (červenec)\n            _monthsParse[i] = new RegExp('^' + months[i] + '$|^' + monthsShort[i] + '$', 'i');\n        }\n        return _monthsParse;\n    }(months, monthsShort)),\n    shortMonthsParse : (function (monthsShort) {\n        var i, _shortMonthsParse = [];\n        for (i = 0; i < 12; i++) {\n            _shortMonthsParse[i] = new RegExp('^' + monthsShort[i] + '$', 'i');\n        }\n        return _shortMonthsParse;\n    }(monthsShort)),\n    longMonthsParse : (function (months) {\n        var i, _longMonthsParse = [];\n        for (i = 0; i < 12; i++) {\n            _longMonthsParse[i] = new RegExp('^' + months[i] + '$', 'i');\n        }\n        return _longMonthsParse;\n    }(months)),\n    weekdays : 'neděle_pondělí_úterý_středa_čtvrtek_pátek_sobota'.split('_'),\n    weekdaysShort : 'ne_po_út_st_čt_pá_so'.split('_'),\n    weekdaysMin : 'ne_po_út_st_čt_pá_so'.split('_'),\n    longDateFormat : {\n        LT: 'H:mm',\n        LTS : 'H:mm:ss',\n        L : 'DD.MM.YYYY',\n        LL : 'D. MMMM YYYY',\n        LLL : 'D. MMMM YYYY H:mm',\n        LLLL : 'dddd D. MMMM YYYY H:mm',\n        l : 'D. M. YYYY'\n    },\n    calendar : {\n        sameDay: '[dnes v] LT',\n        nextDay: '[zítra v] LT',\n        nextWeek: function () {\n            switch (this.day()) {\n                case 0:\n                    return '[v neděli v] LT';\n                case 1:\n                case 2:\n                    return '[v] dddd [v] LT';\n                case 3:\n                    return '[ve středu v] LT';\n                case 4:\n                    return '[ve čtvrtek v] LT';\n                case 5:\n                    return '[v pátek v] LT';\n                case 6:\n                    return '[v sobotu v] LT';\n            }\n        },\n        lastDay: '[včera v] LT',\n        lastWeek: function () {\n            switch (this.day()) {\n                case 0:\n                    return '[minulou neděli v] LT';\n                case 1:\n                case 2:\n                    return '[minulé] dddd [v] LT';\n                case 3:\n                    return '[minulou středu v] LT';\n                case 4:\n                case 5:\n                    return '[minulý] dddd [v] LT';\n                case 6:\n                    return '[minulou sobotu v] LT';\n            }\n        },\n        sameElse: 'L'\n    },\n    relativeTime : {\n        future : 'za %s',\n        past : 'před %s',\n        s : translate,\n        m : translate,\n        mm : translate,\n        h : translate,\n        hh : translate,\n        d : translate,\n        dd : translate,\n        M : translate,\n        MM : translate,\n        y : translate,\n        yy : translate\n    },\n    dayOfMonthOrdinalParse : /\\d{1,2}\\./,\n    ordinal : '%d.',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/locale/cv.js",
    "content": "//! moment.js locale configuration\n//! locale : Chuvash [cv]\n//! author : Anatoly Mironov : https://github.com/mirontoli\n\nimport moment from '../moment';\n\nexport default moment.defineLocale('cv', {\n    months : 'кӑрлач_нарӑс_пуш_ака_май_ҫӗртме_утӑ_ҫурла_авӑн_юпа_чӳк_раштав'.split('_'),\n    monthsShort : 'кӑр_нар_пуш_ака_май_ҫӗр_утӑ_ҫур_авн_юпа_чӳк_раш'.split('_'),\n    weekdays : 'вырсарникун_тунтикун_ытларикун_юнкун_кӗҫнерникун_эрнекун_шӑматкун'.split('_'),\n    weekdaysShort : 'выр_тун_ытл_юн_кӗҫ_эрн_шӑм'.split('_'),\n    weekdaysMin : 'вр_тн_ыт_юн_кҫ_эр_шм'.split('_'),\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD-MM-YYYY',\n        LL : 'YYYY [ҫулхи] MMMM [уйӑхӗн] D[-мӗшӗ]',\n        LLL : 'YYYY [ҫулхи] MMMM [уйӑхӗн] D[-мӗшӗ], HH:mm',\n        LLLL : 'dddd, YYYY [ҫулхи] MMMM [уйӑхӗн] D[-мӗшӗ], HH:mm'\n    },\n    calendar : {\n        sameDay: '[Паян] LT [сехетре]',\n        nextDay: '[Ыран] LT [сехетре]',\n        lastDay: '[Ӗнер] LT [сехетре]',\n        nextWeek: '[Ҫитес] dddd LT [сехетре]',\n        lastWeek: '[Иртнӗ] dddd LT [сехетре]',\n        sameElse: 'L'\n    },\n    relativeTime : {\n        future : function (output) {\n            var affix = /сехет$/i.exec(output) ? 'рен' : /ҫул$/i.exec(output) ? 'тан' : 'ран';\n            return output + affix;\n        },\n        past : '%s каялла',\n        s : 'пӗр-ик ҫеккунт',\n        m : 'пӗр минут',\n        mm : '%d минут',\n        h : 'пӗр сехет',\n        hh : '%d сехет',\n        d : 'пӗр кун',\n        dd : '%d кун',\n        M : 'пӗр уйӑх',\n        MM : '%d уйӑх',\n        y : 'пӗр ҫул',\n        yy : '%d ҫул'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}-мӗш/,\n    ordinal : '%d-мӗш',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 7  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/locale/cy.js",
    "content": "//! moment.js locale configuration\n//! locale : Welsh [cy]\n//! author : Robert Allen : https://github.com/robgallen\n//! author : https://github.com/ryangreaves\n\nimport moment from '../moment';\n\nexport default moment.defineLocale('cy', {\n    months: 'Ionawr_Chwefror_Mawrth_Ebrill_Mai_Mehefin_Gorffennaf_Awst_Medi_Hydref_Tachwedd_Rhagfyr'.split('_'),\n    monthsShort: 'Ion_Chwe_Maw_Ebr_Mai_Meh_Gor_Aws_Med_Hyd_Tach_Rhag'.split('_'),\n    weekdays: 'Dydd Sul_Dydd Llun_Dydd Mawrth_Dydd Mercher_Dydd Iau_Dydd Gwener_Dydd Sadwrn'.split('_'),\n    weekdaysShort: 'Sul_Llun_Maw_Mer_Iau_Gwe_Sad'.split('_'),\n    weekdaysMin: 'Su_Ll_Ma_Me_Ia_Gw_Sa'.split('_'),\n    weekdaysParseExact : true,\n    // time formats are the same as en-gb\n    longDateFormat: {\n        LT: 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L: 'DD/MM/YYYY',\n        LL: 'D MMMM YYYY',\n        LLL: 'D MMMM YYYY HH:mm',\n        LLLL: 'dddd, D MMMM YYYY HH:mm'\n    },\n    calendar: {\n        sameDay: '[Heddiw am] LT',\n        nextDay: '[Yfory am] LT',\n        nextWeek: 'dddd [am] LT',\n        lastDay: '[Ddoe am] LT',\n        lastWeek: 'dddd [diwethaf am] LT',\n        sameElse: 'L'\n    },\n    relativeTime: {\n        future: 'mewn %s',\n        past: '%s yn ôl',\n        s: 'ychydig eiliadau',\n        m: 'munud',\n        mm: '%d munud',\n        h: 'awr',\n        hh: '%d awr',\n        d: 'diwrnod',\n        dd: '%d diwrnod',\n        M: 'mis',\n        MM: '%d mis',\n        y: 'blwyddyn',\n        yy: '%d flynedd'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}(fed|ain|af|il|ydd|ed|eg)/,\n    // traditional ordinal numbers above 31 are not commonly used in colloquial Welsh\n    ordinal: function (number) {\n        var b = number,\n            output = '',\n            lookup = [\n                '', 'af', 'il', 'ydd', 'ydd', 'ed', 'ed', 'ed', 'fed', 'fed', 'fed', // 1af to 10fed\n                'eg', 'fed', 'eg', 'eg', 'fed', 'eg', 'eg', 'fed', 'eg', 'fed' // 11eg to 20fed\n            ];\n        if (b > 20) {\n            if (b === 40 || b === 50 || b === 60 || b === 80 || b === 100) {\n                output = 'fed'; // not 30ain, 70ain or 90ain\n            } else {\n                output = 'ain';\n            }\n        } else if (b > 0) {\n            output = lookup[b];\n        }\n        return number + output;\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/locale/da.js",
    "content": "//! moment.js locale configuration\n//! locale : Danish [da]\n//! author : Ulrik Nielsen : https://github.com/mrbase\n\nimport moment from '../moment';\n\nexport default moment.defineLocale('da', {\n    months : 'januar_februar_marts_april_maj_juni_juli_august_september_oktober_november_december'.split('_'),\n    monthsShort : 'jan_feb_mar_apr_maj_jun_jul_aug_sep_okt_nov_dec'.split('_'),\n    weekdays : 'søndag_mandag_tirsdag_onsdag_torsdag_fredag_lørdag'.split('_'),\n    weekdaysShort : 'søn_man_tir_ons_tor_fre_lør'.split('_'),\n    weekdaysMin : 'sø_ma_ti_on_to_fr_lø'.split('_'),\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D. MMMM YYYY',\n        LLL : 'D. MMMM YYYY HH:mm',\n        LLLL : 'dddd [d.] D. MMMM YYYY [kl.] HH:mm'\n    },\n    calendar : {\n        sameDay : '[i dag kl.] LT',\n        nextDay : '[i morgen kl.] LT',\n        nextWeek : 'på dddd [kl.] LT',\n        lastDay : '[i går kl.] LT',\n        lastWeek : '[i] dddd[s kl.] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'om %s',\n        past : '%s siden',\n        s : 'få sekunder',\n        m : 'et minut',\n        mm : '%d minutter',\n        h : 'en time',\n        hh : '%d timer',\n        d : 'en dag',\n        dd : '%d dage',\n        M : 'en måned',\n        MM : '%d måneder',\n        y : 'et år',\n        yy : '%d år'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}\\./,\n    ordinal : '%d.',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/locale/de-at.js",
    "content": "//! moment.js locale configuration\n//! locale : German (Austria) [de-at]\n//! author : lluchs : https://github.com/lluchs\n//! author: Menelion Elensúle: https://github.com/Oire\n//! author : Martin Groller : https://github.com/MadMG\n//! author : Mikolaj Dadela : https://github.com/mik01aj\n\nimport moment from '../moment';\n\nfunction processRelativeTime(number, withoutSuffix, key, isFuture) {\n    var format = {\n        'm': ['eine Minute', 'einer Minute'],\n        'h': ['eine Stunde', 'einer Stunde'],\n        'd': ['ein Tag', 'einem Tag'],\n        'dd': [number + ' Tage', number + ' Tagen'],\n        'M': ['ein Monat', 'einem Monat'],\n        'MM': [number + ' Monate', number + ' Monaten'],\n        'y': ['ein Jahr', 'einem Jahr'],\n        'yy': [number + ' Jahre', number + ' Jahren']\n    };\n    return withoutSuffix ? format[key][0] : format[key][1];\n}\n\nexport default moment.defineLocale('de-at', {\n    months : 'Jänner_Februar_März_April_Mai_Juni_Juli_August_September_Oktober_November_Dezember'.split('_'),\n    monthsShort : 'Jän._Febr._Mrz._Apr._Mai_Jun._Jul._Aug._Sept._Okt._Nov._Dez.'.split('_'),\n    monthsParseExact : true,\n    weekdays : 'Sonntag_Montag_Dienstag_Mittwoch_Donnerstag_Freitag_Samstag'.split('_'),\n    weekdaysShort : 'So._Mo._Di._Mi._Do._Fr._Sa.'.split('_'),\n    weekdaysMin : 'So_Mo_Di_Mi_Do_Fr_Sa'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat : {\n        LT: 'HH:mm',\n        LTS: 'HH:mm:ss',\n        L : 'DD.MM.YYYY',\n        LL : 'D. MMMM YYYY',\n        LLL : 'D. MMMM YYYY HH:mm',\n        LLLL : 'dddd, D. MMMM YYYY HH:mm'\n    },\n    calendar : {\n        sameDay: '[heute um] LT [Uhr]',\n        sameElse: 'L',\n        nextDay: '[morgen um] LT [Uhr]',\n        nextWeek: 'dddd [um] LT [Uhr]',\n        lastDay: '[gestern um] LT [Uhr]',\n        lastWeek: '[letzten] dddd [um] LT [Uhr]'\n    },\n    relativeTime : {\n        future : 'in %s',\n        past : 'vor %s',\n        s : 'ein paar Sekunden',\n        m : processRelativeTime,\n        mm : '%d Minuten',\n        h : processRelativeTime,\n        hh : '%d Stunden',\n        d : processRelativeTime,\n        dd : processRelativeTime,\n        M : processRelativeTime,\n        MM : processRelativeTime,\n        y : processRelativeTime,\n        yy : processRelativeTime\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}\\./,\n    ordinal : '%d.',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/locale/de-ch.js",
    "content": "//! moment.js locale configuration\n//! locale : German (Switzerland) [de-ch]\n//! author : sschueller : https://github.com/sschueller\n\n// based on: https://www.bk.admin.ch/dokumentation/sprachen/04915/05016/index.html?lang=de#\n\nimport moment from '../moment';\n\nfunction processRelativeTime(number, withoutSuffix, key, isFuture) {\n    var format = {\n        'm': ['eine Minute', 'einer Minute'],\n        'h': ['eine Stunde', 'einer Stunde'],\n        'd': ['ein Tag', 'einem Tag'],\n        'dd': [number + ' Tage', number + ' Tagen'],\n        'M': ['ein Monat', 'einem Monat'],\n        'MM': [number + ' Monate', number + ' Monaten'],\n        'y': ['ein Jahr', 'einem Jahr'],\n        'yy': [number + ' Jahre', number + ' Jahren']\n    };\n    return withoutSuffix ? format[key][0] : format[key][1];\n}\n\nexport default moment.defineLocale('de-ch', {\n    months : 'Januar_Februar_März_April_Mai_Juni_Juli_August_September_Oktober_November_Dezember'.split('_'),\n    monthsShort : 'Jan._Febr._März_April_Mai_Juni_Juli_Aug._Sept._Okt._Nov._Dez.'.split('_'),\n    monthsParseExact : true,\n    weekdays : 'Sonntag_Montag_Dienstag_Mittwoch_Donnerstag_Freitag_Samstag'.split('_'),\n    weekdaysShort : 'So_Mo_Di_Mi_Do_Fr_Sa'.split('_'),\n    weekdaysMin : 'So_Mo_Di_Mi_Do_Fr_Sa'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat : {\n        LT: 'HH.mm',\n        LTS: 'HH.mm.ss',\n        L : 'DD.MM.YYYY',\n        LL : 'D. MMMM YYYY',\n        LLL : 'D. MMMM YYYY HH.mm',\n        LLLL : 'dddd, D. MMMM YYYY HH.mm'\n    },\n    calendar : {\n        sameDay: '[heute um] LT [Uhr]',\n        sameElse: 'L',\n        nextDay: '[morgen um] LT [Uhr]',\n        nextWeek: 'dddd [um] LT [Uhr]',\n        lastDay: '[gestern um] LT [Uhr]',\n        lastWeek: '[letzten] dddd [um] LT [Uhr]'\n    },\n    relativeTime : {\n        future : 'in %s',\n        past : 'vor %s',\n        s : 'ein paar Sekunden',\n        m : processRelativeTime,\n        mm : '%d Minuten',\n        h : processRelativeTime,\n        hh : '%d Stunden',\n        d : processRelativeTime,\n        dd : processRelativeTime,\n        M : processRelativeTime,\n        MM : processRelativeTime,\n        y : processRelativeTime,\n        yy : processRelativeTime\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}\\./,\n    ordinal : '%d.',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/locale/de.js",
    "content": "//! moment.js locale configuration\n//! locale : German [de]\n//! author : lluchs : https://github.com/lluchs\n//! author: Menelion Elensúle: https://github.com/Oire\n//! author : Mikolaj Dadela : https://github.com/mik01aj\n\nimport moment from '../moment';\n\nfunction processRelativeTime(number, withoutSuffix, key, isFuture) {\n    var format = {\n        'm': ['eine Minute', 'einer Minute'],\n        'h': ['eine Stunde', 'einer Stunde'],\n        'd': ['ein Tag', 'einem Tag'],\n        'dd': [number + ' Tage', number + ' Tagen'],\n        'M': ['ein Monat', 'einem Monat'],\n        'MM': [number + ' Monate', number + ' Monaten'],\n        'y': ['ein Jahr', 'einem Jahr'],\n        'yy': [number + ' Jahre', number + ' Jahren']\n    };\n    return withoutSuffix ? format[key][0] : format[key][1];\n}\n\nexport default moment.defineLocale('de', {\n    months : 'Januar_Februar_März_April_Mai_Juni_Juli_August_September_Oktober_November_Dezember'.split('_'),\n    monthsShort : 'Jan._Febr._Mrz._Apr._Mai_Jun._Jul._Aug._Sept._Okt._Nov._Dez.'.split('_'),\n    monthsParseExact : true,\n    weekdays : 'Sonntag_Montag_Dienstag_Mittwoch_Donnerstag_Freitag_Samstag'.split('_'),\n    weekdaysShort : 'So._Mo._Di._Mi._Do._Fr._Sa.'.split('_'),\n    weekdaysMin : 'So_Mo_Di_Mi_Do_Fr_Sa'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat : {\n        LT: 'HH:mm',\n        LTS: 'HH:mm:ss',\n        L : 'DD.MM.YYYY',\n        LL : 'D. MMMM YYYY',\n        LLL : 'D. MMMM YYYY HH:mm',\n        LLLL : 'dddd, D. MMMM YYYY HH:mm'\n    },\n    calendar : {\n        sameDay: '[heute um] LT [Uhr]',\n        sameElse: 'L',\n        nextDay: '[morgen um] LT [Uhr]',\n        nextWeek: 'dddd [um] LT [Uhr]',\n        lastDay: '[gestern um] LT [Uhr]',\n        lastWeek: '[letzten] dddd [um] LT [Uhr]'\n    },\n    relativeTime : {\n        future : 'in %s',\n        past : 'vor %s',\n        s : 'ein paar Sekunden',\n        m : processRelativeTime,\n        mm : '%d Minuten',\n        h : processRelativeTime,\n        hh : '%d Stunden',\n        d : processRelativeTime,\n        dd : processRelativeTime,\n        M : processRelativeTime,\n        MM : processRelativeTime,\n        y : processRelativeTime,\n        yy : processRelativeTime\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}\\./,\n    ordinal : '%d.',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/locale/dv.js",
    "content": "//! moment.js locale configuration\n//! locale : Maldivian [dv]\n//! author : Jawish Hameed : https://github.com/jawish\n\nimport moment from '../moment';\n\nvar months = [\n    'ޖެނުއަރީ',\n    'ފެބްރުއަރީ',\n    'މާރިޗު',\n    'އޭޕްރީލު',\n    'މޭ',\n    'ޖޫން',\n    'ޖުލައި',\n    'އޯގަސްޓު',\n    'ސެޕްޓެމްބަރު',\n    'އޮކްޓޯބަރު',\n    'ނޮވެމްބަރު',\n    'ޑިސެމްބަރު'\n], weekdays = [\n    'އާދިއްތަ',\n    'ހޯމަ',\n    'އަންގާރަ',\n    'ބުދަ',\n    'ބުރާސްފަތި',\n    'ހުކުރު',\n    'ހޮނިހިރު'\n];\n\nexport default moment.defineLocale('dv', {\n    months : months,\n    monthsShort : months,\n    weekdays : weekdays,\n    weekdaysShort : weekdays,\n    weekdaysMin : 'އާދި_ހޯމަ_އަން_ބުދަ_ބުރާ_ހުކު_ހޮނި'.split('_'),\n    longDateFormat : {\n\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'D/M/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY HH:mm',\n        LLLL : 'dddd D MMMM YYYY HH:mm'\n    },\n    meridiemParse: /މކ|މފ/,\n    isPM : function (input) {\n        return 'މފ' === input;\n    },\n    meridiem : function (hour, minute, isLower) {\n        if (hour < 12) {\n            return 'މކ';\n        } else {\n            return 'މފ';\n        }\n    },\n    calendar : {\n        sameDay : '[މިއަދު] LT',\n        nextDay : '[މާދަމާ] LT',\n        nextWeek : 'dddd LT',\n        lastDay : '[އިއްޔެ] LT',\n        lastWeek : '[ފާއިތުވި] dddd LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'ތެރޭގައި %s',\n        past : 'ކުރިން %s',\n        s : 'ސިކުންތުކޮޅެއް',\n        m : 'މިނިޓެއް',\n        mm : 'މިނިޓު %d',\n        h : 'ގަޑިއިރެއް',\n        hh : 'ގަޑިއިރު %d',\n        d : 'ދުވަހެއް',\n        dd : 'ދުވަސް %d',\n        M : 'މަހެއް',\n        MM : 'މަސް %d',\n        y : 'އަހަރެއް',\n        yy : 'އަހަރު %d'\n    },\n    preparse: function (string) {\n        return string.replace(/،/g, ',');\n    },\n    postformat: function (string) {\n        return string.replace(/,/g, '،');\n    },\n    week : {\n        dow : 7,  // Sunday is the first day of the week.\n        doy : 12  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/locale/el.js",
    "content": "//! moment.js locale configuration\n//! locale : Greek [el]\n//! author : Aggelos Karalias : https://github.com/mehiel\n\nimport moment from '../moment';\nimport isFunction from '../lib/utils/is-function';\n\nexport default moment.defineLocale('el', {\n    monthsNominativeEl : 'Ιανουάριος_Φεβρουάριος_Μάρτιος_Απρίλιος_Μάιος_Ιούνιος_Ιούλιος_Αύγουστος_Σεπτέμβριος_Οκτώβριος_Νοέμβριος_Δεκέμβριος'.split('_'),\n    monthsGenitiveEl : 'Ιανουαρίου_Φεβρουαρίου_Μαρτίου_Απριλίου_Μαΐου_Ιουνίου_Ιουλίου_Αυγούστου_Σεπτεμβρίου_Οκτωβρίου_Νοεμβρίου_Δεκεμβρίου'.split('_'),\n    months : function (momentToFormat, format) {\n        if (!momentToFormat) {\n            return this._monthsNominativeEl;\n        } else if (/D/.test(format.substring(0, format.indexOf('MMMM')))) { // if there is a day number before 'MMMM'\n            return this._monthsGenitiveEl[momentToFormat.month()];\n        } else {\n            return this._monthsNominativeEl[momentToFormat.month()];\n        }\n    },\n    monthsShort : 'Ιαν_Φεβ_Μαρ_Απρ_Μαϊ_Ιουν_Ιουλ_Αυγ_Σεπ_Οκτ_Νοε_Δεκ'.split('_'),\n    weekdays : 'Κυριακή_Δευτέρα_Τρίτη_Τετάρτη_Πέμπτη_Παρασκευή_Σάββατο'.split('_'),\n    weekdaysShort : 'Κυρ_Δευ_Τρι_Τετ_Πεμ_Παρ_Σαβ'.split('_'),\n    weekdaysMin : 'Κυ_Δε_Τρ_Τε_Πε_Πα_Σα'.split('_'),\n    meridiem : function (hours, minutes, isLower) {\n        if (hours > 11) {\n            return isLower ? 'μμ' : 'ΜΜ';\n        } else {\n            return isLower ? 'πμ' : 'ΠΜ';\n        }\n    },\n    isPM : function (input) {\n        return ((input + '').toLowerCase()[0] === 'μ');\n    },\n    meridiemParse : /[ΠΜ]\\.?Μ?\\.?/i,\n    longDateFormat : {\n        LT : 'h:mm A',\n        LTS : 'h:mm:ss A',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY h:mm A',\n        LLLL : 'dddd, D MMMM YYYY h:mm A'\n    },\n    calendarEl : {\n        sameDay : '[Σήμερα {}] LT',\n        nextDay : '[Αύριο {}] LT',\n        nextWeek : 'dddd [{}] LT',\n        lastDay : '[Χθες {}] LT',\n        lastWeek : function () {\n            switch (this.day()) {\n                case 6:\n                    return '[το προηγούμενο] dddd [{}] LT';\n                default:\n                    return '[την προηγούμενη] dddd [{}] LT';\n            }\n        },\n        sameElse : 'L'\n    },\n    calendar : function (key, mom) {\n        var output = this._calendarEl[key],\n            hours = mom && mom.hours();\n        if (isFunction(output)) {\n            output = output.apply(mom);\n        }\n        return output.replace('{}', (hours % 12 === 1 ? 'στη' : 'στις'));\n    },\n    relativeTime : {\n        future : 'σε %s',\n        past : '%s πριν',\n        s : 'λίγα δευτερόλεπτα',\n        m : 'ένα λεπτό',\n        mm : '%d λεπτά',\n        h : 'μία ώρα',\n        hh : '%d ώρες',\n        d : 'μία μέρα',\n        dd : '%d μέρες',\n        M : 'ένας μήνας',\n        MM : '%d μήνες',\n        y : 'ένας χρόνος',\n        yy : '%d χρόνια'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}η/,\n    ordinal: '%dη',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4st is the first week of the year.\n    }\n});\n\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/locale/en-au.js",
    "content": "//! moment.js locale configuration\n//! locale : English (Australia) [en-au]\n//! author : Jared Morse : https://github.com/jarcoal\n\nimport moment from '../moment';\n\nexport default moment.defineLocale('en-au', {\n    months : 'January_February_March_April_May_June_July_August_September_October_November_December'.split('_'),\n    monthsShort : 'Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec'.split('_'),\n    weekdays : 'Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday'.split('_'),\n    weekdaysShort : 'Sun_Mon_Tue_Wed_Thu_Fri_Sat'.split('_'),\n    weekdaysMin : 'Su_Mo_Tu_We_Th_Fr_Sa'.split('_'),\n    longDateFormat : {\n        LT : 'h:mm A',\n        LTS : 'h:mm:ss A',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY h:mm A',\n        LLLL : 'dddd, D MMMM YYYY h:mm A'\n    },\n    calendar : {\n        sameDay : '[Today at] LT',\n        nextDay : '[Tomorrow at] LT',\n        nextWeek : 'dddd [at] LT',\n        lastDay : '[Yesterday at] LT',\n        lastWeek : '[Last] dddd [at] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'in %s',\n        past : '%s ago',\n        s : 'a few seconds',\n        m : 'a minute',\n        mm : '%d minutes',\n        h : 'an hour',\n        hh : '%d hours',\n        d : 'a day',\n        dd : '%d days',\n        M : 'a month',\n        MM : '%d months',\n        y : 'a year',\n        yy : '%d years'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}(st|nd|rd|th)/,\n    ordinal : function (number) {\n        var b = number % 10,\n            output = (~~(number % 100 / 10) === 1) ? 'th' :\n            (b === 1) ? 'st' :\n            (b === 2) ? 'nd' :\n            (b === 3) ? 'rd' : 'th';\n        return number + output;\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/locale/en-ca.js",
    "content": "//! moment.js locale configuration\n//! locale : English (Canada) [en-ca]\n//! author : Jonathan Abourbih : https://github.com/jonbca\n\nimport moment from '../moment';\n\nexport default moment.defineLocale('en-ca', {\n    months : 'January_February_March_April_May_June_July_August_September_October_November_December'.split('_'),\n    monthsShort : 'Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec'.split('_'),\n    weekdays : 'Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday'.split('_'),\n    weekdaysShort : 'Sun_Mon_Tue_Wed_Thu_Fri_Sat'.split('_'),\n    weekdaysMin : 'Su_Mo_Tu_We_Th_Fr_Sa'.split('_'),\n    longDateFormat : {\n        LT : 'h:mm A',\n        LTS : 'h:mm:ss A',\n        L : 'YYYY-MM-DD',\n        LL : 'MMMM D, YYYY',\n        LLL : 'MMMM D, YYYY h:mm A',\n        LLLL : 'dddd, MMMM D, YYYY h:mm A'\n    },\n    calendar : {\n        sameDay : '[Today at] LT',\n        nextDay : '[Tomorrow at] LT',\n        nextWeek : 'dddd [at] LT',\n        lastDay : '[Yesterday at] LT',\n        lastWeek : '[Last] dddd [at] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'in %s',\n        past : '%s ago',\n        s : 'a few seconds',\n        m : 'a minute',\n        mm : '%d minutes',\n        h : 'an hour',\n        hh : '%d hours',\n        d : 'a day',\n        dd : '%d days',\n        M : 'a month',\n        MM : '%d months',\n        y : 'a year',\n        yy : '%d years'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}(st|nd|rd|th)/,\n    ordinal : function (number) {\n        var b = number % 10,\n            output = (~~(number % 100 / 10) === 1) ? 'th' :\n            (b === 1) ? 'st' :\n            (b === 2) ? 'nd' :\n            (b === 3) ? 'rd' : 'th';\n        return number + output;\n    }\n});\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/locale/en-gb.js",
    "content": "//! moment.js locale configuration\n//! locale : English (United Kingdom) [en-gb]\n//! author : Chris Gedrim : https://github.com/chrisgedrim\n\nimport moment from '../moment';\n\nexport default moment.defineLocale('en-gb', {\n    months : 'January_February_March_April_May_June_July_August_September_October_November_December'.split('_'),\n    monthsShort : 'Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec'.split('_'),\n    weekdays : 'Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday'.split('_'),\n    weekdaysShort : 'Sun_Mon_Tue_Wed_Thu_Fri_Sat'.split('_'),\n    weekdaysMin : 'Su_Mo_Tu_We_Th_Fr_Sa'.split('_'),\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY HH:mm',\n        LLLL : 'dddd, D MMMM YYYY HH:mm'\n    },\n    calendar : {\n        sameDay : '[Today at] LT',\n        nextDay : '[Tomorrow at] LT',\n        nextWeek : 'dddd [at] LT',\n        lastDay : '[Yesterday at] LT',\n        lastWeek : '[Last] dddd [at] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'in %s',\n        past : '%s ago',\n        s : 'a few seconds',\n        m : 'a minute',\n        mm : '%d minutes',\n        h : 'an hour',\n        hh : '%d hours',\n        d : 'a day',\n        dd : '%d days',\n        M : 'a month',\n        MM : '%d months',\n        y : 'a year',\n        yy : '%d years'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}(st|nd|rd|th)/,\n    ordinal : function (number) {\n        var b = number % 10,\n            output = (~~(number % 100 / 10) === 1) ? 'th' :\n            (b === 1) ? 'st' :\n            (b === 2) ? 'nd' :\n            (b === 3) ? 'rd' : 'th';\n        return number + output;\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/locale/en-ie.js",
    "content": "//! moment.js locale configuration\n//! locale : English (Ireland) [en-ie]\n//! author : Chris Cartlidge : https://github.com/chriscartlidge\n\nimport moment from '../moment';\n\nexport default moment.defineLocale('en-ie', {\n    months : 'January_February_March_April_May_June_July_August_September_October_November_December'.split('_'),\n    monthsShort : 'Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec'.split('_'),\n    weekdays : 'Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday'.split('_'),\n    weekdaysShort : 'Sun_Mon_Tue_Wed_Thu_Fri_Sat'.split('_'),\n    weekdaysMin : 'Su_Mo_Tu_We_Th_Fr_Sa'.split('_'),\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD-MM-YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY HH:mm',\n        LLLL : 'dddd D MMMM YYYY HH:mm'\n    },\n    calendar : {\n        sameDay : '[Today at] LT',\n        nextDay : '[Tomorrow at] LT',\n        nextWeek : 'dddd [at] LT',\n        lastDay : '[Yesterday at] LT',\n        lastWeek : '[Last] dddd [at] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'in %s',\n        past : '%s ago',\n        s : 'a few seconds',\n        m : 'a minute',\n        mm : '%d minutes',\n        h : 'an hour',\n        hh : '%d hours',\n        d : 'a day',\n        dd : '%d days',\n        M : 'a month',\n        MM : '%d months',\n        y : 'a year',\n        yy : '%d years'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}(st|nd|rd|th)/,\n    ordinal : function (number) {\n        var b = number % 10,\n            output = (~~(number % 100 / 10) === 1) ? 'th' :\n            (b === 1) ? 'st' :\n            (b === 2) ? 'nd' :\n            (b === 3) ? 'rd' : 'th';\n        return number + output;\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/locale/en-nz.js",
    "content": "//! moment.js locale configuration\n//! locale : English (New Zealand) [en-nz]\n//! author : Luke McGregor : https://github.com/lukemcgregor\n\nimport moment from '../moment';\n\nexport default moment.defineLocale('en-nz', {\n    months : 'January_February_March_April_May_June_July_August_September_October_November_December'.split('_'),\n    monthsShort : 'Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec'.split('_'),\n    weekdays : 'Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday'.split('_'),\n    weekdaysShort : 'Sun_Mon_Tue_Wed_Thu_Fri_Sat'.split('_'),\n    weekdaysMin : 'Su_Mo_Tu_We_Th_Fr_Sa'.split('_'),\n    longDateFormat : {\n        LT : 'h:mm A',\n        LTS : 'h:mm:ss A',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY h:mm A',\n        LLLL : 'dddd, D MMMM YYYY h:mm A'\n    },\n    calendar : {\n        sameDay : '[Today at] LT',\n        nextDay : '[Tomorrow at] LT',\n        nextWeek : 'dddd [at] LT',\n        lastDay : '[Yesterday at] LT',\n        lastWeek : '[Last] dddd [at] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'in %s',\n        past : '%s ago',\n        s : 'a few seconds',\n        m : 'a minute',\n        mm : '%d minutes',\n        h : 'an hour',\n        hh : '%d hours',\n        d : 'a day',\n        dd : '%d days',\n        M : 'a month',\n        MM : '%d months',\n        y : 'a year',\n        yy : '%d years'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}(st|nd|rd|th)/,\n    ordinal : function (number) {\n        var b = number % 10,\n            output = (~~(number % 100 / 10) === 1) ? 'th' :\n            (b === 1) ? 'st' :\n            (b === 2) ? 'nd' :\n            (b === 3) ? 'rd' : 'th';\n        return number + output;\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/locale/eo.js",
    "content": "//! moment.js locale configuration\n//! locale : Esperanto [eo]\n//! author : Colin Dean : https://github.com/colindean\n//! author : Mia Nordentoft Imperatori : https://github.com/miestasmia\n//! comment : miestasmia corrected the translation by colindean\n\nimport moment from '../moment';\n\nexport default moment.defineLocale('eo', {\n    months : 'januaro_februaro_marto_aprilo_majo_junio_julio_aŭgusto_septembro_oktobro_novembro_decembro'.split('_'),\n    monthsShort : 'jan_feb_mar_apr_maj_jun_jul_aŭg_sep_okt_nov_dec'.split('_'),\n    weekdays : 'dimanĉo_lundo_mardo_merkredo_ĵaŭdo_vendredo_sabato'.split('_'),\n    weekdaysShort : 'dim_lun_mard_merk_ĵaŭ_ven_sab'.split('_'),\n    weekdaysMin : 'di_lu_ma_me_ĵa_ve_sa'.split('_'),\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'YYYY-MM-DD',\n        LL : 'D[-a de] MMMM, YYYY',\n        LLL : 'D[-a de] MMMM, YYYY HH:mm',\n        LLLL : 'dddd, [la] D[-a de] MMMM, YYYY HH:mm'\n    },\n    meridiemParse: /[ap]\\.t\\.m/i,\n    isPM: function (input) {\n        return input.charAt(0).toLowerCase() === 'p';\n    },\n    meridiem : function (hours, minutes, isLower) {\n        if (hours > 11) {\n            return isLower ? 'p.t.m.' : 'P.T.M.';\n        } else {\n            return isLower ? 'a.t.m.' : 'A.T.M.';\n        }\n    },\n    calendar : {\n        sameDay : '[Hodiaŭ je] LT',\n        nextDay : '[Morgaŭ je] LT',\n        nextWeek : 'dddd [je] LT',\n        lastDay : '[Hieraŭ je] LT',\n        lastWeek : '[pasinta] dddd [je] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'post %s',\n        past : 'antaŭ %s',\n        s : 'sekundoj',\n        m : 'minuto',\n        mm : '%d minutoj',\n        h : 'horo',\n        hh : '%d horoj',\n        d : 'tago',//ne 'diurno', ĉar estas uzita por proksimumo\n        dd : '%d tagoj',\n        M : 'monato',\n        MM : '%d monatoj',\n        y : 'jaro',\n        yy : '%d jaroj'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}a/,\n    ordinal : '%da',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 7  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/locale/es-do.js",
    "content": "//! moment.js locale configuration\n//! locale : Spanish (Dominican Republic) [es-do]\n\nimport moment from '../moment';\n\nvar monthsShortDot = 'ene._feb._mar._abr._may._jun._jul._ago._sep._oct._nov._dic.'.split('_'),\n    monthsShort = 'ene_feb_mar_abr_may_jun_jul_ago_sep_oct_nov_dic'.split('_');\n\nexport default moment.defineLocale('es-do', {\n    months : 'enero_febrero_marzo_abril_mayo_junio_julio_agosto_septiembre_octubre_noviembre_diciembre'.split('_'),\n    monthsShort : function (m, format) {\n        if (!m) {\n            return monthsShortDot;\n        } else if (/-MMM-/.test(format)) {\n            return monthsShort[m.month()];\n        } else {\n            return monthsShortDot[m.month()];\n        }\n    },\n    monthsParseExact : true,\n    weekdays : 'domingo_lunes_martes_miércoles_jueves_viernes_sábado'.split('_'),\n    weekdaysShort : 'dom._lun._mar._mié._jue._vie._sáb.'.split('_'),\n    weekdaysMin : 'do_lu_ma_mi_ju_vi_sá'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat : {\n        LT : 'h:mm A',\n        LTS : 'h:mm:ss A',\n        L : 'DD/MM/YYYY',\n        LL : 'D [de] MMMM [de] YYYY',\n        LLL : 'D [de] MMMM [de] YYYY h:mm A',\n        LLLL : 'dddd, D [de] MMMM [de] YYYY h:mm A'\n    },\n    calendar : {\n        sameDay : function () {\n            return '[hoy a la' + ((this.hours() !== 1) ? 's' : '') + '] LT';\n        },\n        nextDay : function () {\n            return '[mañana a la' + ((this.hours() !== 1) ? 's' : '') + '] LT';\n        },\n        nextWeek : function () {\n            return 'dddd [a la' + ((this.hours() !== 1) ? 's' : '') + '] LT';\n        },\n        lastDay : function () {\n            return '[ayer a la' + ((this.hours() !== 1) ? 's' : '') + '] LT';\n        },\n        lastWeek : function () {\n            return '[el] dddd [pasado a la' + ((this.hours() !== 1) ? 's' : '') + '] LT';\n        },\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'en %s',\n        past : 'hace %s',\n        s : 'unos segundos',\n        m : 'un minuto',\n        mm : '%d minutos',\n        h : 'una hora',\n        hh : '%d horas',\n        d : 'un día',\n        dd : '%d días',\n        M : 'un mes',\n        MM : '%d meses',\n        y : 'un año',\n        yy : '%d años'\n    },\n    dayOfMonthOrdinalParse : /\\d{1,2}º/,\n    ordinal : '%dº',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/locale/es.js",
    "content": "//! moment.js locale configuration\n//! locale : Spanish [es]\n//! author : Julio Napurí : https://github.com/julionc\n\nimport moment from '../moment';\n\nvar monthsShortDot = 'ene._feb._mar._abr._may._jun._jul._ago._sep._oct._nov._dic.'.split('_'),\n    monthsShort = 'ene_feb_mar_abr_may_jun_jul_ago_sep_oct_nov_dic'.split('_');\n\nexport default moment.defineLocale('es', {\n    months : 'enero_febrero_marzo_abril_mayo_junio_julio_agosto_septiembre_octubre_noviembre_diciembre'.split('_'),\n    monthsShort : function (m, format) {\n        if (!m) {\n            return monthsShortDot;\n        } else if (/-MMM-/.test(format)) {\n            return monthsShort[m.month()];\n        } else {\n            return monthsShortDot[m.month()];\n        }\n    },\n    monthsParseExact : true,\n    weekdays : 'domingo_lunes_martes_miércoles_jueves_viernes_sábado'.split('_'),\n    weekdaysShort : 'dom._lun._mar._mié._jue._vie._sáb.'.split('_'),\n    weekdaysMin : 'do_lu_ma_mi_ju_vi_sá'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat : {\n        LT : 'H:mm',\n        LTS : 'H:mm:ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D [de] MMMM [de] YYYY',\n        LLL : 'D [de] MMMM [de] YYYY H:mm',\n        LLLL : 'dddd, D [de] MMMM [de] YYYY H:mm'\n    },\n    calendar : {\n        sameDay : function () {\n            return '[hoy a la' + ((this.hours() !== 1) ? 's' : '') + '] LT';\n        },\n        nextDay : function () {\n            return '[mañana a la' + ((this.hours() !== 1) ? 's' : '') + '] LT';\n        },\n        nextWeek : function () {\n            return 'dddd [a la' + ((this.hours() !== 1) ? 's' : '') + '] LT';\n        },\n        lastDay : function () {\n            return '[ayer a la' + ((this.hours() !== 1) ? 's' : '') + '] LT';\n        },\n        lastWeek : function () {\n            return '[el] dddd [pasado a la' + ((this.hours() !== 1) ? 's' : '') + '] LT';\n        },\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'en %s',\n        past : 'hace %s',\n        s : 'unos segundos',\n        m : 'un minuto',\n        mm : '%d minutos',\n        h : 'una hora',\n        hh : '%d horas',\n        d : 'un día',\n        dd : '%d días',\n        M : 'un mes',\n        MM : '%d meses',\n        y : 'un año',\n        yy : '%d años'\n    },\n    dayOfMonthOrdinalParse : /\\d{1,2}º/,\n    ordinal : '%dº',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/locale/et.js",
    "content": "//! moment.js locale configuration\n//! locale : Estonian [et]\n//! author : Henry Kehlmann : https://github.com/madhenry\n//! improvements : Illimar Tambek : https://github.com/ragulka\n\nimport moment from '../moment';\n\nfunction processRelativeTime(number, withoutSuffix, key, isFuture) {\n    var format = {\n        's' : ['mõne sekundi', 'mõni sekund', 'paar sekundit'],\n        'm' : ['ühe minuti', 'üks minut'],\n        'mm': [number + ' minuti', number + ' minutit'],\n        'h' : ['ühe tunni', 'tund aega', 'üks tund'],\n        'hh': [number + ' tunni', number + ' tundi'],\n        'd' : ['ühe päeva', 'üks päev'],\n        'M' : ['kuu aja', 'kuu aega', 'üks kuu'],\n        'MM': [number + ' kuu', number + ' kuud'],\n        'y' : ['ühe aasta', 'aasta', 'üks aasta'],\n        'yy': [number + ' aasta', number + ' aastat']\n    };\n    if (withoutSuffix) {\n        return format[key][2] ? format[key][2] : format[key][1];\n    }\n    return isFuture ? format[key][0] : format[key][1];\n}\n\nexport default moment.defineLocale('et', {\n    months        : 'jaanuar_veebruar_märts_aprill_mai_juuni_juuli_august_september_oktoober_november_detsember'.split('_'),\n    monthsShort   : 'jaan_veebr_märts_apr_mai_juuni_juuli_aug_sept_okt_nov_dets'.split('_'),\n    weekdays      : 'pühapäev_esmaspäev_teisipäev_kolmapäev_neljapäev_reede_laupäev'.split('_'),\n    weekdaysShort : 'P_E_T_K_N_R_L'.split('_'),\n    weekdaysMin   : 'P_E_T_K_N_R_L'.split('_'),\n    longDateFormat : {\n        LT   : 'H:mm',\n        LTS : 'H:mm:ss',\n        L    : 'DD.MM.YYYY',\n        LL   : 'D. MMMM YYYY',\n        LLL  : 'D. MMMM YYYY H:mm',\n        LLLL : 'dddd, D. MMMM YYYY H:mm'\n    },\n    calendar : {\n        sameDay  : '[Täna,] LT',\n        nextDay  : '[Homme,] LT',\n        nextWeek : '[Järgmine] dddd LT',\n        lastDay  : '[Eile,] LT',\n        lastWeek : '[Eelmine] dddd LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : '%s pärast',\n        past   : '%s tagasi',\n        s      : processRelativeTime,\n        m      : processRelativeTime,\n        mm     : processRelativeTime,\n        h      : processRelativeTime,\n        hh     : processRelativeTime,\n        d      : processRelativeTime,\n        dd     : '%d päeva',\n        M      : processRelativeTime,\n        MM     : processRelativeTime,\n        y      : processRelativeTime,\n        yy     : processRelativeTime\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}\\./,\n    ordinal : '%d.',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/locale/eu.js",
    "content": "//! moment.js locale configuration\n//! locale : Basque [eu]\n//! author : Eneko Illarramendi : https://github.com/eillarra\n\nimport moment from '../moment';\n\nexport default moment.defineLocale('eu', {\n    months : 'urtarrila_otsaila_martxoa_apirila_maiatza_ekaina_uztaila_abuztua_iraila_urria_azaroa_abendua'.split('_'),\n    monthsShort : 'urt._ots._mar._api._mai._eka._uzt._abu._ira._urr._aza._abe.'.split('_'),\n    monthsParseExact : true,\n    weekdays : 'igandea_astelehena_asteartea_asteazkena_osteguna_ostirala_larunbata'.split('_'),\n    weekdaysShort : 'ig._al._ar._az._og._ol._lr.'.split('_'),\n    weekdaysMin : 'ig_al_ar_az_og_ol_lr'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'YYYY-MM-DD',\n        LL : 'YYYY[ko] MMMM[ren] D[a]',\n        LLL : 'YYYY[ko] MMMM[ren] D[a] HH:mm',\n        LLLL : 'dddd, YYYY[ko] MMMM[ren] D[a] HH:mm',\n        l : 'YYYY-M-D',\n        ll : 'YYYY[ko] MMM D[a]',\n        lll : 'YYYY[ko] MMM D[a] HH:mm',\n        llll : 'ddd, YYYY[ko] MMM D[a] HH:mm'\n    },\n    calendar : {\n        sameDay : '[gaur] LT[etan]',\n        nextDay : '[bihar] LT[etan]',\n        nextWeek : 'dddd LT[etan]',\n        lastDay : '[atzo] LT[etan]',\n        lastWeek : '[aurreko] dddd LT[etan]',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : '%s barru',\n        past : 'duela %s',\n        s : 'segundo batzuk',\n        m : 'minutu bat',\n        mm : '%d minutu',\n        h : 'ordu bat',\n        hh : '%d ordu',\n        d : 'egun bat',\n        dd : '%d egun',\n        M : 'hilabete bat',\n        MM : '%d hilabete',\n        y : 'urte bat',\n        yy : '%d urte'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}\\./,\n    ordinal : '%d.',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 7  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/locale/fa.js",
    "content": "//! moment.js locale configuration\n//! locale : Persian [fa]\n//! author : Ebrahim Byagowi : https://github.com/ebraminio\n\nimport moment from '../moment';\n\nvar symbolMap = {\n    '1': '۱',\n    '2': '۲',\n    '3': '۳',\n    '4': '۴',\n    '5': '۵',\n    '6': '۶',\n    '7': '۷',\n    '8': '۸',\n    '9': '۹',\n    '0': '۰'\n}, numberMap = {\n    '۱': '1',\n    '۲': '2',\n    '۳': '3',\n    '۴': '4',\n    '۵': '5',\n    '۶': '6',\n    '۷': '7',\n    '۸': '8',\n    '۹': '9',\n    '۰': '0'\n};\n\nexport default moment.defineLocale('fa', {\n    months : 'ژانویه_فوریه_مارس_آوریل_مه_ژوئن_ژوئیه_اوت_سپتامبر_اکتبر_نوامبر_دسامبر'.split('_'),\n    monthsShort : 'ژانویه_فوریه_مارس_آوریل_مه_ژوئن_ژوئیه_اوت_سپتامبر_اکتبر_نوامبر_دسامبر'.split('_'),\n    weekdays : 'یک\\u200cشنبه_دوشنبه_سه\\u200cشنبه_چهارشنبه_پنج\\u200cشنبه_جمعه_شنبه'.split('_'),\n    weekdaysShort : 'یک\\u200cشنبه_دوشنبه_سه\\u200cشنبه_چهارشنبه_پنج\\u200cشنبه_جمعه_شنبه'.split('_'),\n    weekdaysMin : 'ی_د_س_چ_پ_ج_ش'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY HH:mm',\n        LLLL : 'dddd, D MMMM YYYY HH:mm'\n    },\n    meridiemParse: /قبل از ظهر|بعد از ظهر/,\n    isPM: function (input) {\n        return /بعد از ظهر/.test(input);\n    },\n    meridiem : function (hour, minute, isLower) {\n        if (hour < 12) {\n            return 'قبل از ظهر';\n        } else {\n            return 'بعد از ظهر';\n        }\n    },\n    calendar : {\n        sameDay : '[امروز ساعت] LT',\n        nextDay : '[فردا ساعت] LT',\n        nextWeek : 'dddd [ساعت] LT',\n        lastDay : '[دیروز ساعت] LT',\n        lastWeek : 'dddd [پیش] [ساعت] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'در %s',\n        past : '%s پیش',\n        s : 'چند ثانیه',\n        m : 'یک دقیقه',\n        mm : '%d دقیقه',\n        h : 'یک ساعت',\n        hh : '%d ساعت',\n        d : 'یک روز',\n        dd : '%d روز',\n        M : 'یک ماه',\n        MM : '%d ماه',\n        y : 'یک سال',\n        yy : '%d سال'\n    },\n    preparse: function (string) {\n        return string.replace(/[۰-۹]/g, function (match) {\n            return numberMap[match];\n        }).replace(/،/g, ',');\n    },\n    postformat: function (string) {\n        return string.replace(/\\d/g, function (match) {\n            return symbolMap[match];\n        }).replace(/,/g, '،');\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}م/,\n    ordinal : '%dم',\n    week : {\n        dow : 6, // Saturday is the first day of the week.\n        doy : 12 // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/locale/fi.js",
    "content": "//! moment.js locale configuration\n//! locale : Finnish [fi]\n//! author : Tarmo Aidantausta : https://github.com/bleadof\n\nimport moment from '../moment';\n\nvar numbersPast = 'nolla yksi kaksi kolme neljä viisi kuusi seitsemän kahdeksan yhdeksän'.split(' '),\n    numbersFuture = [\n        'nolla', 'yhden', 'kahden', 'kolmen', 'neljän', 'viiden', 'kuuden',\n        numbersPast[7], numbersPast[8], numbersPast[9]\n    ];\nfunction translate(number, withoutSuffix, key, isFuture) {\n    var result = '';\n    switch (key) {\n        case 's':\n            return isFuture ? 'muutaman sekunnin' : 'muutama sekunti';\n        case 'm':\n            return isFuture ? 'minuutin' : 'minuutti';\n        case 'mm':\n            result = isFuture ? 'minuutin' : 'minuuttia';\n            break;\n        case 'h':\n            return isFuture ? 'tunnin' : 'tunti';\n        case 'hh':\n            result = isFuture ? 'tunnin' : 'tuntia';\n            break;\n        case 'd':\n            return isFuture ? 'päivän' : 'päivä';\n        case 'dd':\n            result = isFuture ? 'päivän' : 'päivää';\n            break;\n        case 'M':\n            return isFuture ? 'kuukauden' : 'kuukausi';\n        case 'MM':\n            result = isFuture ? 'kuukauden' : 'kuukautta';\n            break;\n        case 'y':\n            return isFuture ? 'vuoden' : 'vuosi';\n        case 'yy':\n            result = isFuture ? 'vuoden' : 'vuotta';\n            break;\n    }\n    result = verbalNumber(number, isFuture) + ' ' + result;\n    return result;\n}\nfunction verbalNumber(number, isFuture) {\n    return number < 10 ? (isFuture ? numbersFuture[number] : numbersPast[number]) : number;\n}\n\nexport default moment.defineLocale('fi', {\n    months : 'tammikuu_helmikuu_maaliskuu_huhtikuu_toukokuu_kesäkuu_heinäkuu_elokuu_syyskuu_lokakuu_marraskuu_joulukuu'.split('_'),\n    monthsShort : 'tammi_helmi_maalis_huhti_touko_kesä_heinä_elo_syys_loka_marras_joulu'.split('_'),\n    weekdays : 'sunnuntai_maanantai_tiistai_keskiviikko_torstai_perjantai_lauantai'.split('_'),\n    weekdaysShort : 'su_ma_ti_ke_to_pe_la'.split('_'),\n    weekdaysMin : 'su_ma_ti_ke_to_pe_la'.split('_'),\n    longDateFormat : {\n        LT : 'HH.mm',\n        LTS : 'HH.mm.ss',\n        L : 'DD.MM.YYYY',\n        LL : 'Do MMMM[ta] YYYY',\n        LLL : 'Do MMMM[ta] YYYY, [klo] HH.mm',\n        LLLL : 'dddd, Do MMMM[ta] YYYY, [klo] HH.mm',\n        l : 'D.M.YYYY',\n        ll : 'Do MMM YYYY',\n        lll : 'Do MMM YYYY, [klo] HH.mm',\n        llll : 'ddd, Do MMM YYYY, [klo] HH.mm'\n    },\n    calendar : {\n        sameDay : '[tänään] [klo] LT',\n        nextDay : '[huomenna] [klo] LT',\n        nextWeek : 'dddd [klo] LT',\n        lastDay : '[eilen] [klo] LT',\n        lastWeek : '[viime] dddd[na] [klo] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : '%s päästä',\n        past : '%s sitten',\n        s : translate,\n        m : translate,\n        mm : translate,\n        h : translate,\n        hh : translate,\n        d : translate,\n        dd : translate,\n        M : translate,\n        MM : translate,\n        y : translate,\n        yy : translate\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}\\./,\n    ordinal : '%d.',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/locale/fo.js",
    "content": "//! moment.js locale configuration\n//! locale : Faroese [fo]\n//! author : Ragnar Johannesen : https://github.com/ragnar123\n\nimport moment from '../moment';\n\nexport default moment.defineLocale('fo', {\n    months : 'januar_februar_mars_apríl_mai_juni_juli_august_september_oktober_november_desember'.split('_'),\n    monthsShort : 'jan_feb_mar_apr_mai_jun_jul_aug_sep_okt_nov_des'.split('_'),\n    weekdays : 'sunnudagur_mánadagur_týsdagur_mikudagur_hósdagur_fríggjadagur_leygardagur'.split('_'),\n    weekdaysShort : 'sun_mán_týs_mik_hós_frí_ley'.split('_'),\n    weekdaysMin : 'su_má_tý_mi_hó_fr_le'.split('_'),\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY HH:mm',\n        LLLL : 'dddd D. MMMM, YYYY HH:mm'\n    },\n    calendar : {\n        sameDay : '[Í dag kl.] LT',\n        nextDay : '[Í morgin kl.] LT',\n        nextWeek : 'dddd [kl.] LT',\n        lastDay : '[Í gjár kl.] LT',\n        lastWeek : '[síðstu] dddd [kl] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'um %s',\n        past : '%s síðani',\n        s : 'fá sekund',\n        m : 'ein minutt',\n        mm : '%d minuttir',\n        h : 'ein tími',\n        hh : '%d tímar',\n        d : 'ein dagur',\n        dd : '%d dagar',\n        M : 'ein mánaði',\n        MM : '%d mánaðir',\n        y : 'eitt ár',\n        yy : '%d ár'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}\\./,\n    ordinal : '%d.',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/locale/fr-ca.js",
    "content": "//! moment.js locale configuration\n//! locale : French (Canada) [fr-ca]\n//! author : Jonathan Abourbih : https://github.com/jonbca\n\nimport moment from '../moment';\n\nexport default moment.defineLocale('fr-ca', {\n    months : 'janvier_février_mars_avril_mai_juin_juillet_août_septembre_octobre_novembre_décembre'.split('_'),\n    monthsShort : 'janv._févr._mars_avr._mai_juin_juil._août_sept._oct._nov._déc.'.split('_'),\n    monthsParseExact : true,\n    weekdays : 'dimanche_lundi_mardi_mercredi_jeudi_vendredi_samedi'.split('_'),\n    weekdaysShort : 'dim._lun._mar._mer._jeu._ven._sam.'.split('_'),\n    weekdaysMin : 'Di_Lu_Ma_Me_Je_Ve_Sa'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'YYYY-MM-DD',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY HH:mm',\n        LLLL : 'dddd D MMMM YYYY HH:mm'\n    },\n    calendar : {\n        sameDay : '[Aujourd’hui à] LT',\n        nextDay : '[Demain à] LT',\n        nextWeek : 'dddd [à] LT',\n        lastDay : '[Hier à] LT',\n        lastWeek : 'dddd [dernier à] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'dans %s',\n        past : 'il y a %s',\n        s : 'quelques secondes',\n        m : 'une minute',\n        mm : '%d minutes',\n        h : 'une heure',\n        hh : '%d heures',\n        d : 'un jour',\n        dd : '%d jours',\n        M : 'un mois',\n        MM : '%d mois',\n        y : 'un an',\n        yy : '%d ans'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}(er|e)/,\n    ordinal : function (number, period) {\n        switch (period) {\n            // Words with masculine grammatical gender: mois, trimestre, jour\n            default:\n            case 'M':\n            case 'Q':\n            case 'D':\n            case 'DDD':\n            case 'd':\n                return number + (number === 1 ? 'er' : 'e');\n\n            // Words with feminine grammatical gender: semaine\n            case 'w':\n            case 'W':\n                return number + (number === 1 ? 're' : 'e');\n        }\n    }\n});\n\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/locale/fr-ch.js",
    "content": "//! moment.js locale configuration\n//! locale : French (Switzerland) [fr-ch]\n//! author : Gaspard Bucher : https://github.com/gaspard\n\nimport moment from '../moment';\n\nexport default moment.defineLocale('fr-ch', {\n    months : 'janvier_février_mars_avril_mai_juin_juillet_août_septembre_octobre_novembre_décembre'.split('_'),\n    monthsShort : 'janv._févr._mars_avr._mai_juin_juil._août_sept._oct._nov._déc.'.split('_'),\n    monthsParseExact : true,\n    weekdays : 'dimanche_lundi_mardi_mercredi_jeudi_vendredi_samedi'.split('_'),\n    weekdaysShort : 'dim._lun._mar._mer._jeu._ven._sam.'.split('_'),\n    weekdaysMin : 'Di_Lu_Ma_Me_Je_Ve_Sa'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD.MM.YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY HH:mm',\n        LLLL : 'dddd D MMMM YYYY HH:mm'\n    },\n    calendar : {\n        sameDay : '[Aujourd’hui à] LT',\n        nextDay : '[Demain à] LT',\n        nextWeek : 'dddd [à] LT',\n        lastDay : '[Hier à] LT',\n        lastWeek : 'dddd [dernier à] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'dans %s',\n        past : 'il y a %s',\n        s : 'quelques secondes',\n        m : 'une minute',\n        mm : '%d minutes',\n        h : 'une heure',\n        hh : '%d heures',\n        d : 'un jour',\n        dd : '%d jours',\n        M : 'un mois',\n        MM : '%d mois',\n        y : 'un an',\n        yy : '%d ans'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}(er|e)/,\n    ordinal : function (number, period) {\n        switch (period) {\n            // Words with masculine grammatical gender: mois, trimestre, jour\n            default:\n            case 'M':\n            case 'Q':\n            case 'D':\n            case 'DDD':\n            case 'd':\n                return number + (number === 1 ? 'er' : 'e');\n\n            // Words with feminine grammatical gender: semaine\n            case 'w':\n            case 'W':\n                return number + (number === 1 ? 're' : 'e');\n        }\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/locale/fr.js",
    "content": "//! moment.js locale configuration\n//! locale : French [fr]\n//! author : John Fischer : https://github.com/jfroffice\n\nimport moment from '../moment';\n\nexport default moment.defineLocale('fr', {\n    months : 'janvier_février_mars_avril_mai_juin_juillet_août_septembre_octobre_novembre_décembre'.split('_'),\n    monthsShort : 'janv._févr._mars_avr._mai_juin_juil._août_sept._oct._nov._déc.'.split('_'),\n    monthsParseExact : true,\n    weekdays : 'dimanche_lundi_mardi_mercredi_jeudi_vendredi_samedi'.split('_'),\n    weekdaysShort : 'dim._lun._mar._mer._jeu._ven._sam.'.split('_'),\n    weekdaysMin : 'Di_Lu_Ma_Me_Je_Ve_Sa'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY HH:mm',\n        LLLL : 'dddd D MMMM YYYY HH:mm'\n    },\n    calendar : {\n        sameDay : '[Aujourd’hui à] LT',\n        nextDay : '[Demain à] LT',\n        nextWeek : 'dddd [à] LT',\n        lastDay : '[Hier à] LT',\n        lastWeek : 'dddd [dernier à] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'dans %s',\n        past : 'il y a %s',\n        s : 'quelques secondes',\n        m : 'une minute',\n        mm : '%d minutes',\n        h : 'une heure',\n        hh : '%d heures',\n        d : 'un jour',\n        dd : '%d jours',\n        M : 'un mois',\n        MM : '%d mois',\n        y : 'un an',\n        yy : '%d ans'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}(er|)/,\n    ordinal : function (number, period) {\n        switch (period) {\n            // TODO: Return 'e' when day of month > 1. Move this case inside\n            // block for masculine words below.\n            // See https://github.com/moment/moment/issues/3375\n            case 'D':\n                return number + (number === 1 ? 'er' : '');\n\n            // Words with masculine grammatical gender: mois, trimestre, jour\n            default:\n            case 'M':\n            case 'Q':\n            case 'DDD':\n            case 'd':\n                return number + (number === 1 ? 'er' : 'e');\n\n            // Words with feminine grammatical gender: semaine\n            case 'w':\n            case 'W':\n                return number + (number === 1 ? 're' : 'e');\n        }\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/locale/fy.js",
    "content": "//! moment.js locale configuration\n//! locale : Frisian [fy]\n//! author : Robin van der Vliet : https://github.com/robin0van0der0v\n\nimport moment from '../moment';\n\nvar monthsShortWithDots = 'jan._feb._mrt._apr._mai_jun._jul._aug._sep._okt._nov._des.'.split('_'),\n    monthsShortWithoutDots = 'jan_feb_mrt_apr_mai_jun_jul_aug_sep_okt_nov_des'.split('_');\n\nexport default moment.defineLocale('fy', {\n    months : 'jannewaris_febrewaris_maart_april_maaie_juny_july_augustus_septimber_oktober_novimber_desimber'.split('_'),\n    monthsShort : function (m, format) {\n        if (!m) {\n            return monthsShortWithDots;\n        } else if (/-MMM-/.test(format)) {\n            return monthsShortWithoutDots[m.month()];\n        } else {\n            return monthsShortWithDots[m.month()];\n        }\n    },\n    monthsParseExact : true,\n    weekdays : 'snein_moandei_tiisdei_woansdei_tongersdei_freed_sneon'.split('_'),\n    weekdaysShort : 'si._mo._ti._wo._to._fr._so.'.split('_'),\n    weekdaysMin : 'Si_Mo_Ti_Wo_To_Fr_So'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD-MM-YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY HH:mm',\n        LLLL : 'dddd D MMMM YYYY HH:mm'\n    },\n    calendar : {\n        sameDay: '[hjoed om] LT',\n        nextDay: '[moarn om] LT',\n        nextWeek: 'dddd [om] LT',\n        lastDay: '[juster om] LT',\n        lastWeek: '[ôfrûne] dddd [om] LT',\n        sameElse: 'L'\n    },\n    relativeTime : {\n        future : 'oer %s',\n        past : '%s lyn',\n        s : 'in pear sekonden',\n        m : 'ien minút',\n        mm : '%d minuten',\n        h : 'ien oere',\n        hh : '%d oeren',\n        d : 'ien dei',\n        dd : '%d dagen',\n        M : 'ien moanne',\n        MM : '%d moannen',\n        y : 'ien jier',\n        yy : '%d jierren'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}(ste|de)/,\n    ordinal : function (number) {\n        return number + ((number === 1 || number === 8 || number >= 20) ? 'ste' : 'de');\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/locale/gd.js",
    "content": "//! moment.js locale configuration\n//! locale : Scottish Gaelic [gd]\n//! author : Jon Ashdown : https://github.com/jonashdown\n\nimport moment from '../moment';\n\nvar months = [\n    'Am Faoilleach', 'An Gearran', 'Am Màrt', 'An Giblean', 'An Cèitean', 'An t-Ògmhios', 'An t-Iuchar', 'An Lùnastal', 'An t-Sultain', 'An Dàmhair', 'An t-Samhain', 'An Dùbhlachd'\n];\n\nvar monthsShort = ['Faoi', 'Gear', 'Màrt', 'Gibl', 'Cèit', 'Ògmh', 'Iuch', 'Lùn', 'Sult', 'Dàmh', 'Samh', 'Dùbh'];\n\nvar weekdays = ['Didòmhnaich', 'Diluain', 'Dimàirt', 'Diciadain', 'Diardaoin', 'Dihaoine', 'Disathairne'];\n\nvar weekdaysShort = ['Did', 'Dil', 'Dim', 'Dic', 'Dia', 'Dih', 'Dis'];\n\nvar weekdaysMin = ['Dò', 'Lu', 'Mà', 'Ci', 'Ar', 'Ha', 'Sa'];\n\nexport default moment.defineLocale('gd', {\n    months : months,\n    monthsShort : monthsShort,\n    monthsParseExact : true,\n    weekdays : weekdays,\n    weekdaysShort : weekdaysShort,\n    weekdaysMin : weekdaysMin,\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY HH:mm',\n        LLLL : 'dddd, D MMMM YYYY HH:mm'\n    },\n    calendar : {\n        sameDay : '[An-diugh aig] LT',\n        nextDay : '[A-màireach aig] LT',\n        nextWeek : 'dddd [aig] LT',\n        lastDay : '[An-dè aig] LT',\n        lastWeek : 'dddd [seo chaidh] [aig] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'ann an %s',\n        past : 'bho chionn %s',\n        s : 'beagan diogan',\n        m : 'mionaid',\n        mm : '%d mionaidean',\n        h : 'uair',\n        hh : '%d uairean',\n        d : 'latha',\n        dd : '%d latha',\n        M : 'mìos',\n        MM : '%d mìosan',\n        y : 'bliadhna',\n        yy : '%d bliadhna'\n    },\n    dayOfMonthOrdinalParse : /\\d{1,2}(d|na|mh)/,\n    ordinal : function (number) {\n        var output = number === 1 ? 'd' : number % 10 === 2 ? 'na' : 'mh';\n        return number + output;\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/locale/gl.js",
    "content": "//! moment.js locale configuration\n//! locale : Galician [gl]\n//! author : Juan G. Hurtado : https://github.com/juanghurtado\n\nimport moment from '../moment';\n\nexport default moment.defineLocale('gl', {\n    months : 'xaneiro_febreiro_marzo_abril_maio_xuño_xullo_agosto_setembro_outubro_novembro_decembro'.split('_'),\n    monthsShort : 'xan._feb._mar._abr._mai._xuñ._xul._ago._set._out._nov._dec.'.split('_'),\n    monthsParseExact: true,\n    weekdays : 'domingo_luns_martes_mércores_xoves_venres_sábado'.split('_'),\n    weekdaysShort : 'dom._lun._mar._mér._xov._ven._sáb.'.split('_'),\n    weekdaysMin : 'do_lu_ma_mé_xo_ve_sá'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat : {\n        LT : 'H:mm',\n        LTS : 'H:mm:ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D [de] MMMM [de] YYYY',\n        LLL : 'D [de] MMMM [de] YYYY H:mm',\n        LLLL : 'dddd, D [de] MMMM [de] YYYY H:mm'\n    },\n    calendar : {\n        sameDay : function () {\n            return '[hoxe ' + ((this.hours() !== 1) ? 'ás' : 'á') + '] LT';\n        },\n        nextDay : function () {\n            return '[mañá ' + ((this.hours() !== 1) ? 'ás' : 'á') + '] LT';\n        },\n        nextWeek : function () {\n            return 'dddd [' + ((this.hours() !== 1) ? 'ás' : 'a') + '] LT';\n        },\n        lastDay : function () {\n            return '[onte ' + ((this.hours() !== 1) ? 'á' : 'a') + '] LT';\n        },\n        lastWeek : function () {\n            return '[o] dddd [pasado ' + ((this.hours() !== 1) ? 'ás' : 'a') + '] LT';\n        },\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : function (str) {\n            if (str.indexOf('un') === 0) {\n                return 'n' + str;\n            }\n            return 'en ' + str;\n        },\n        past : 'hai %s',\n        s : 'uns segundos',\n        m : 'un minuto',\n        mm : '%d minutos',\n        h : 'unha hora',\n        hh : '%d horas',\n        d : 'un día',\n        dd : '%d días',\n        M : 'un mes',\n        MM : '%d meses',\n        y : 'un ano',\n        yy : '%d anos'\n    },\n    dayOfMonthOrdinalParse : /\\d{1,2}º/,\n    ordinal : '%dº',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/locale/gom-latn.js",
    "content": "//! moment.js locale configuration\n//! locale : Konkani Latin script [gom-latn]\n//! author : The Discoverer : https://github.com/WikiDiscoverer\n\nimport moment from '../moment';\n\nfunction processRelativeTime(number, withoutSuffix, key, isFuture) {\n    var format = {\n        's': ['thodde secondanim', 'thodde second'],\n        'm': ['eka mintan', 'ek minute'],\n        'mm': [number + ' mintanim', number + ' mintam'],\n        'h': ['eka horan', 'ek hor'],\n        'hh': [number + ' horanim', number + ' hor'],\n        'd': ['eka disan', 'ek dis'],\n        'dd': [number + ' disanim', number + ' dis'],\n        'M': ['eka mhoinean', 'ek mhoino'],\n        'MM': [number + ' mhoineanim', number + ' mhoine'],\n        'y': ['eka vorsan', 'ek voros'],\n        'yy': [number + ' vorsanim', number + ' vorsam']\n    };\n    return withoutSuffix ? format[key][0] : format[key][1];\n}\n\nexport default moment.defineLocale('gom-latn', {\n    months : 'Janer_Febrer_Mars_Abril_Mai_Jun_Julai_Agost_Setembr_Otubr_Novembr_Dezembr'.split('_'),\n    monthsShort : 'Jan._Feb._Mars_Abr._Mai_Jun_Jul._Ago._Set._Otu._Nov._Dez.'.split('_'),\n    monthsParseExact : true,\n    weekdays : 'Aitar_Somar_Mongllar_Budvar_Brestar_Sukrar_Son\\'var'.split('_'),\n    weekdaysShort : 'Ait._Som._Mon._Bud._Bre._Suk._Son.'.split('_'),\n    weekdaysMin : 'Ai_Sm_Mo_Bu_Br_Su_Sn'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat : {\n        LT : 'A h:mm [vazta]',\n        LTS : 'A h:mm:ss [vazta]',\n        L : 'DD-MM-YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY A h:mm [vazta]',\n        LLLL : 'dddd, MMMM[achea] Do, YYYY, A h:mm [vazta]',\n        llll: 'ddd, D MMM YYYY, A h:mm [vazta]'\n    },\n    calendar : {\n        sameDay: '[Aiz] LT',\n        nextDay: '[Faleam] LT',\n        nextWeek: '[Ieta to] dddd[,] LT',\n        lastDay: '[Kal] LT',\n        lastWeek: '[Fatlo] dddd[,] LT',\n        sameElse: 'L'\n    },\n    relativeTime : {\n        future : '%s',\n        past : '%s adim',\n        s : processRelativeTime,\n        m : processRelativeTime,\n        mm : processRelativeTime,\n        h : processRelativeTime,\n        hh : processRelativeTime,\n        d : processRelativeTime,\n        dd : processRelativeTime,\n        M : processRelativeTime,\n        MM : processRelativeTime,\n        y : processRelativeTime,\n        yy : processRelativeTime\n    },\n    dayOfMonthOrdinalParse : /\\d{1,2}(er)/,\n    ordinal : function (number, period) {\n        switch (period) {\n            // the ordinal 'er' only applies to day of the month\n            case 'D':\n                return number + 'er';\n            default:\n            case 'M':\n            case 'Q':\n            case 'DDD':\n            case 'd':\n            case 'w':\n            case 'W':\n                return number;\n        }\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    },\n    meridiemParse: /rati|sokalli|donparam|sanje/,\n    meridiemHour : function (hour, meridiem) {\n        if (hour === 12) {\n            hour = 0;\n        }\n        if (meridiem === 'rati') {\n            return hour < 4 ? hour : hour + 12;\n        } else if (meridiem === 'sokalli') {\n            return hour;\n        } else if (meridiem === 'donparam') {\n            return hour > 12 ? hour : hour + 12;\n        } else if (meridiem === 'sanje') {\n            return hour + 12;\n        }\n    },\n    meridiem : function (hour, minute, isLower) {\n        if (hour < 4) {\n            return 'rati';\n        } else if (hour < 12) {\n            return 'sokalli';\n        } else if (hour < 16) {\n            return 'donparam';\n        } else if (hour < 20) {\n            return 'sanje';\n        } else {\n            return 'rati';\n        }\n    }\n});\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/locale/he.js",
    "content": "//! moment.js locale configuration\n//! locale : Hebrew [he]\n//! author : Tomer Cohen : https://github.com/tomer\n//! author : Moshe Simantov : https://github.com/DevelopmentIL\n//! author : Tal Ater : https://github.com/TalAter\n\nimport moment from '../moment';\n\nexport default moment.defineLocale('he', {\n    months : 'ינואר_פברואר_מרץ_אפריל_מאי_יוני_יולי_אוגוסט_ספטמבר_אוקטובר_נובמבר_דצמבר'.split('_'),\n    monthsShort : 'ינו׳_פבר׳_מרץ_אפר׳_מאי_יוני_יולי_אוג׳_ספט׳_אוק׳_נוב׳_דצמ׳'.split('_'),\n    weekdays : 'ראשון_שני_שלישי_רביעי_חמישי_שישי_שבת'.split('_'),\n    weekdaysShort : 'א׳_ב׳_ג׳_ד׳_ה׳_ו׳_ש׳'.split('_'),\n    weekdaysMin : 'א_ב_ג_ד_ה_ו_ש'.split('_'),\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D [ב]MMMM YYYY',\n        LLL : 'D [ב]MMMM YYYY HH:mm',\n        LLLL : 'dddd, D [ב]MMMM YYYY HH:mm',\n        l : 'D/M/YYYY',\n        ll : 'D MMM YYYY',\n        lll : 'D MMM YYYY HH:mm',\n        llll : 'ddd, D MMM YYYY HH:mm'\n    },\n    calendar : {\n        sameDay : '[היום ב־]LT',\n        nextDay : '[מחר ב־]LT',\n        nextWeek : 'dddd [בשעה] LT',\n        lastDay : '[אתמול ב־]LT',\n        lastWeek : '[ביום] dddd [האחרון בשעה] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'בעוד %s',\n        past : 'לפני %s',\n        s : 'מספר שניות',\n        m : 'דקה',\n        mm : '%d דקות',\n        h : 'שעה',\n        hh : function (number) {\n            if (number === 2) {\n                return 'שעתיים';\n            }\n            return number + ' שעות';\n        },\n        d : 'יום',\n        dd : function (number) {\n            if (number === 2) {\n                return 'יומיים';\n            }\n            return number + ' ימים';\n        },\n        M : 'חודש',\n        MM : function (number) {\n            if (number === 2) {\n                return 'חודשיים';\n            }\n            return number + ' חודשים';\n        },\n        y : 'שנה',\n        yy : function (number) {\n            if (number === 2) {\n                return 'שנתיים';\n            } else if (number % 10 === 0 && number !== 10) {\n                return number + ' שנה';\n            }\n            return number + ' שנים';\n        }\n    },\n    meridiemParse: /אחה\"צ|לפנה\"צ|אחרי הצהריים|לפני הצהריים|לפנות בוקר|בבוקר|בערב/i,\n    isPM : function (input) {\n        return /^(אחה\"צ|אחרי הצהריים|בערב)$/.test(input);\n    },\n    meridiem : function (hour, minute, isLower) {\n        if (hour < 5) {\n            return 'לפנות בוקר';\n        } else if (hour < 10) {\n            return 'בבוקר';\n        } else if (hour < 12) {\n            return isLower ? 'לפנה\"צ' : 'לפני הצהריים';\n        } else if (hour < 18) {\n            return isLower ? 'אחה\"צ' : 'אחרי הצהריים';\n        } else {\n            return 'בערב';\n        }\n    }\n});\n\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/locale/hi.js",
    "content": "//! moment.js locale configuration\n//! locale : Hindi [hi]\n//! author : Mayank Singhal : https://github.com/mayanksinghal\n\nimport moment from '../moment';\n\nvar symbolMap = {\n    '1': '१',\n    '2': '२',\n    '3': '३',\n    '4': '४',\n    '5': '५',\n    '6': '६',\n    '7': '७',\n    '8': '८',\n    '9': '९',\n    '0': '०'\n},\nnumberMap = {\n    '१': '1',\n    '२': '2',\n    '३': '3',\n    '४': '4',\n    '५': '5',\n    '६': '6',\n    '७': '7',\n    '८': '8',\n    '९': '9',\n    '०': '0'\n};\n\nexport default moment.defineLocale('hi', {\n    months : 'जनवरी_फ़रवरी_मार्च_अप्रैल_मई_जून_जुलाई_अगस्त_सितम्बर_अक्टूबर_नवम्बर_दिसम्बर'.split('_'),\n    monthsShort : 'जन._फ़र._मार्च_अप्रै._मई_जून_जुल._अग._सित._अक्टू._नव._दिस.'.split('_'),\n    monthsParseExact: true,\n    weekdays : 'रविवार_सोमवार_मंगलवार_बुधवार_गुरूवार_शुक्रवार_शनिवार'.split('_'),\n    weekdaysShort : 'रवि_सोम_मंगल_बुध_गुरू_शुक्र_शनि'.split('_'),\n    weekdaysMin : 'र_सो_मं_बु_गु_शु_श'.split('_'),\n    longDateFormat : {\n        LT : 'A h:mm बजे',\n        LTS : 'A h:mm:ss बजे',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY, A h:mm बजे',\n        LLLL : 'dddd, D MMMM YYYY, A h:mm बजे'\n    },\n    calendar : {\n        sameDay : '[आज] LT',\n        nextDay : '[कल] LT',\n        nextWeek : 'dddd, LT',\n        lastDay : '[कल] LT',\n        lastWeek : '[पिछले] dddd, LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : '%s में',\n        past : '%s पहले',\n        s : 'कुछ ही क्षण',\n        m : 'एक मिनट',\n        mm : '%d मिनट',\n        h : 'एक घंटा',\n        hh : '%d घंटे',\n        d : 'एक दिन',\n        dd : '%d दिन',\n        M : 'एक महीने',\n        MM : '%d महीने',\n        y : 'एक वर्ष',\n        yy : '%d वर्ष'\n    },\n    preparse: function (string) {\n        return string.replace(/[१२३४५६७८९०]/g, function (match) {\n            return numberMap[match];\n        });\n    },\n    postformat: function (string) {\n        return string.replace(/\\d/g, function (match) {\n            return symbolMap[match];\n        });\n    },\n    // Hindi notation for meridiems are quite fuzzy in practice. While there exists\n    // a rigid notion of a 'Pahar' it is not used as rigidly in modern Hindi.\n    meridiemParse: /रात|सुबह|दोपहर|शाम/,\n    meridiemHour : function (hour, meridiem) {\n        if (hour === 12) {\n            hour = 0;\n        }\n        if (meridiem === 'रात') {\n            return hour < 4 ? hour : hour + 12;\n        } else if (meridiem === 'सुबह') {\n            return hour;\n        } else if (meridiem === 'दोपहर') {\n            return hour >= 10 ? hour : hour + 12;\n        } else if (meridiem === 'शाम') {\n            return hour + 12;\n        }\n    },\n    meridiem : function (hour, minute, isLower) {\n        if (hour < 4) {\n            return 'रात';\n        } else if (hour < 10) {\n            return 'सुबह';\n        } else if (hour < 17) {\n            return 'दोपहर';\n        } else if (hour < 20) {\n            return 'शाम';\n        } else {\n            return 'रात';\n        }\n    },\n    week : {\n        dow : 0, // Sunday is the first day of the week.\n        doy : 6  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/locale/hr.js",
    "content": "//! moment.js locale configuration\n//! locale : Croatian [hr]\n//! author : Bojan Marković : https://github.com/bmarkovic\n\nimport moment from '../moment';\n\nfunction translate(number, withoutSuffix, key) {\n    var result = number + ' ';\n    switch (key) {\n        case 'm':\n            return withoutSuffix ? 'jedna minuta' : 'jedne minute';\n        case 'mm':\n            if (number === 1) {\n                result += 'minuta';\n            } else if (number === 2 || number === 3 || number === 4) {\n                result += 'minute';\n            } else {\n                result += 'minuta';\n            }\n            return result;\n        case 'h':\n            return withoutSuffix ? 'jedan sat' : 'jednog sata';\n        case 'hh':\n            if (number === 1) {\n                result += 'sat';\n            } else if (number === 2 || number === 3 || number === 4) {\n                result += 'sata';\n            } else {\n                result += 'sati';\n            }\n            return result;\n        case 'dd':\n            if (number === 1) {\n                result += 'dan';\n            } else {\n                result += 'dana';\n            }\n            return result;\n        case 'MM':\n            if (number === 1) {\n                result += 'mjesec';\n            } else if (number === 2 || number === 3 || number === 4) {\n                result += 'mjeseca';\n            } else {\n                result += 'mjeseci';\n            }\n            return result;\n        case 'yy':\n            if (number === 1) {\n                result += 'godina';\n            } else if (number === 2 || number === 3 || number === 4) {\n                result += 'godine';\n            } else {\n                result += 'godina';\n            }\n            return result;\n    }\n}\n\nexport default moment.defineLocale('hr', {\n    months : {\n        format: 'siječnja_veljače_ožujka_travnja_svibnja_lipnja_srpnja_kolovoza_rujna_listopada_studenoga_prosinca'.split('_'),\n        standalone: 'siječanj_veljača_ožujak_travanj_svibanj_lipanj_srpanj_kolovoz_rujan_listopad_studeni_prosinac'.split('_')\n    },\n    monthsShort : 'sij._velj._ožu._tra._svi._lip._srp._kol._ruj._lis._stu._pro.'.split('_'),\n    monthsParseExact: true,\n    weekdays : 'nedjelja_ponedjeljak_utorak_srijeda_četvrtak_petak_subota'.split('_'),\n    weekdaysShort : 'ned._pon._uto._sri._čet._pet._sub.'.split('_'),\n    weekdaysMin : 'ne_po_ut_sr_če_pe_su'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat : {\n        LT : 'H:mm',\n        LTS : 'H:mm:ss',\n        L : 'DD.MM.YYYY',\n        LL : 'D. MMMM YYYY',\n        LLL : 'D. MMMM YYYY H:mm',\n        LLLL : 'dddd, D. MMMM YYYY H:mm'\n    },\n    calendar : {\n        sameDay  : '[danas u] LT',\n        nextDay  : '[sutra u] LT',\n        nextWeek : function () {\n            switch (this.day()) {\n                case 0:\n                    return '[u] [nedjelju] [u] LT';\n                case 3:\n                    return '[u] [srijedu] [u] LT';\n                case 6:\n                    return '[u] [subotu] [u] LT';\n                case 1:\n                case 2:\n                case 4:\n                case 5:\n                    return '[u] dddd [u] LT';\n            }\n        },\n        lastDay  : '[jučer u] LT',\n        lastWeek : function () {\n            switch (this.day()) {\n                case 0:\n                case 3:\n                    return '[prošlu] dddd [u] LT';\n                case 6:\n                    return '[prošle] [subote] [u] LT';\n                case 1:\n                case 2:\n                case 4:\n                case 5:\n                    return '[prošli] dddd [u] LT';\n            }\n        },\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'za %s',\n        past   : 'prije %s',\n        s      : 'par sekundi',\n        m      : translate,\n        mm     : translate,\n        h      : translate,\n        hh     : translate,\n        d      : 'dan',\n        dd     : translate,\n        M      : 'mjesec',\n        MM     : translate,\n        y      : 'godinu',\n        yy     : translate\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}\\./,\n    ordinal : '%d.',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 7  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/locale/hu.js",
    "content": "//! moment.js locale configuration\n//! locale : Hungarian [hu]\n//! author : Adam Brunner : https://github.com/adambrunner\n\nimport moment from '../moment';\n\nvar weekEndings = 'vasárnap hétfőn kedden szerdán csütörtökön pénteken szombaton'.split(' ');\nfunction translate(number, withoutSuffix, key, isFuture) {\n    var num = number,\n        suffix;\n    switch (key) {\n        case 's':\n            return (isFuture || withoutSuffix) ? 'néhány másodperc' : 'néhány másodperce';\n        case 'm':\n            return 'egy' + (isFuture || withoutSuffix ? ' perc' : ' perce');\n        case 'mm':\n            return num + (isFuture || withoutSuffix ? ' perc' : ' perce');\n        case 'h':\n            return 'egy' + (isFuture || withoutSuffix ? ' óra' : ' órája');\n        case 'hh':\n            return num + (isFuture || withoutSuffix ? ' óra' : ' órája');\n        case 'd':\n            return 'egy' + (isFuture || withoutSuffix ? ' nap' : ' napja');\n        case 'dd':\n            return num + (isFuture || withoutSuffix ? ' nap' : ' napja');\n        case 'M':\n            return 'egy' + (isFuture || withoutSuffix ? ' hónap' : ' hónapja');\n        case 'MM':\n            return num + (isFuture || withoutSuffix ? ' hónap' : ' hónapja');\n        case 'y':\n            return 'egy' + (isFuture || withoutSuffix ? ' év' : ' éve');\n        case 'yy':\n            return num + (isFuture || withoutSuffix ? ' év' : ' éve');\n    }\n    return '';\n}\nfunction week(isFuture) {\n    return (isFuture ? '' : '[múlt] ') + '[' + weekEndings[this.day()] + '] LT[-kor]';\n}\n\nexport default moment.defineLocale('hu', {\n    months : 'január_február_március_április_május_június_július_augusztus_szeptember_október_november_december'.split('_'),\n    monthsShort : 'jan_feb_márc_ápr_máj_jún_júl_aug_szept_okt_nov_dec'.split('_'),\n    weekdays : 'vasárnap_hétfő_kedd_szerda_csütörtök_péntek_szombat'.split('_'),\n    weekdaysShort : 'vas_hét_kedd_sze_csüt_pén_szo'.split('_'),\n    weekdaysMin : 'v_h_k_sze_cs_p_szo'.split('_'),\n    longDateFormat : {\n        LT : 'H:mm',\n        LTS : 'H:mm:ss',\n        L : 'YYYY.MM.DD.',\n        LL : 'YYYY. MMMM D.',\n        LLL : 'YYYY. MMMM D. H:mm',\n        LLLL : 'YYYY. MMMM D., dddd H:mm'\n    },\n    meridiemParse: /de|du/i,\n    isPM: function (input) {\n        return input.charAt(1).toLowerCase() === 'u';\n    },\n    meridiem : function (hours, minutes, isLower) {\n        if (hours < 12) {\n            return isLower === true ? 'de' : 'DE';\n        } else {\n            return isLower === true ? 'du' : 'DU';\n        }\n    },\n    calendar : {\n        sameDay : '[ma] LT[-kor]',\n        nextDay : '[holnap] LT[-kor]',\n        nextWeek : function () {\n            return week.call(this, true);\n        },\n        lastDay : '[tegnap] LT[-kor]',\n        lastWeek : function () {\n            return week.call(this, false);\n        },\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : '%s múlva',\n        past : '%s',\n        s : translate,\n        m : translate,\n        mm : translate,\n        h : translate,\n        hh : translate,\n        d : translate,\n        dd : translate,\n        M : translate,\n        MM : translate,\n        y : translate,\n        yy : translate\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}\\./,\n    ordinal : '%d.',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/locale/hy-am.js",
    "content": "//! moment.js locale configuration\n//! locale : Armenian [hy-am]\n//! author : Armendarabyan : https://github.com/armendarabyan\n\nimport moment from '../moment';\n\nexport default moment.defineLocale('hy-am', {\n    months : {\n        format: 'հունվարի_փետրվարի_մարտի_ապրիլի_մայիսի_հունիսի_հուլիսի_օգոստոսի_սեպտեմբերի_հոկտեմբերի_նոյեմբերի_դեկտեմբերի'.split('_'),\n        standalone: 'հունվար_փետրվար_մարտ_ապրիլ_մայիս_հունիս_հուլիս_օգոստոս_սեպտեմբեր_հոկտեմբեր_նոյեմբեր_դեկտեմբեր'.split('_')\n    },\n    monthsShort : 'հնվ_փտր_մրտ_ապր_մյս_հնս_հլս_օգս_սպտ_հկտ_նմբ_դկտ'.split('_'),\n    weekdays : 'կիրակի_երկուշաբթի_երեքշաբթի_չորեքշաբթի_հինգշաբթի_ուրբաթ_շաբաթ'.split('_'),\n    weekdaysShort : 'կրկ_երկ_երք_չրք_հնգ_ուրբ_շբթ'.split('_'),\n    weekdaysMin : 'կրկ_երկ_երք_չրք_հնգ_ուրբ_շբթ'.split('_'),\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD.MM.YYYY',\n        LL : 'D MMMM YYYY թ.',\n        LLL : 'D MMMM YYYY թ., HH:mm',\n        LLLL : 'dddd, D MMMM YYYY թ., HH:mm'\n    },\n    calendar : {\n        sameDay: '[այսօր] LT',\n        nextDay: '[վաղը] LT',\n        lastDay: '[երեկ] LT',\n        nextWeek: function () {\n            return 'dddd [օրը ժամը] LT';\n        },\n        lastWeek: function () {\n            return '[անցած] dddd [օրը ժամը] LT';\n        },\n        sameElse: 'L'\n    },\n    relativeTime : {\n        future : '%s հետո',\n        past : '%s առաջ',\n        s : 'մի քանի վայրկյան',\n        m : 'րոպե',\n        mm : '%d րոպե',\n        h : 'ժամ',\n        hh : '%d ժամ',\n        d : 'օր',\n        dd : '%d օր',\n        M : 'ամիս',\n        MM : '%d ամիս',\n        y : 'տարի',\n        yy : '%d տարի'\n    },\n    meridiemParse: /գիշերվա|առավոտվա|ցերեկվա|երեկոյան/,\n    isPM: function (input) {\n        return /^(ցերեկվա|երեկոյան)$/.test(input);\n    },\n    meridiem : function (hour) {\n        if (hour < 4) {\n            return 'գիշերվա';\n        } else if (hour < 12) {\n            return 'առավոտվա';\n        } else if (hour < 17) {\n            return 'ցերեկվա';\n        } else {\n            return 'երեկոյան';\n        }\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}|\\d{1,2}-(ին|րդ)/,\n    ordinal: function (number, period) {\n        switch (period) {\n            case 'DDD':\n            case 'w':\n            case 'W':\n            case 'DDDo':\n                if (number === 1) {\n                    return number + '-ին';\n                }\n                return number + '-րդ';\n            default:\n                return number;\n        }\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 7  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/locale/id.js",
    "content": "//! moment.js locale configuration\n//! locale : Indonesian [id]\n//! author : Mohammad Satrio Utomo : https://github.com/tyok\n//! reference: http://id.wikisource.org/wiki/Pedoman_Umum_Ejaan_Bahasa_Indonesia_yang_Disempurnakan\n\nimport moment from '../moment';\n\nexport default moment.defineLocale('id', {\n    months : 'Januari_Februari_Maret_April_Mei_Juni_Juli_Agustus_September_Oktober_November_Desember'.split('_'),\n    monthsShort : 'Jan_Feb_Mar_Apr_Mei_Jun_Jul_Ags_Sep_Okt_Nov_Des'.split('_'),\n    weekdays : 'Minggu_Senin_Selasa_Rabu_Kamis_Jumat_Sabtu'.split('_'),\n    weekdaysShort : 'Min_Sen_Sel_Rab_Kam_Jum_Sab'.split('_'),\n    weekdaysMin : 'Mg_Sn_Sl_Rb_Km_Jm_Sb'.split('_'),\n    longDateFormat : {\n        LT : 'HH.mm',\n        LTS : 'HH.mm.ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY [pukul] HH.mm',\n        LLLL : 'dddd, D MMMM YYYY [pukul] HH.mm'\n    },\n    meridiemParse: /pagi|siang|sore|malam/,\n    meridiemHour : function (hour, meridiem) {\n        if (hour === 12) {\n            hour = 0;\n        }\n        if (meridiem === 'pagi') {\n            return hour;\n        } else if (meridiem === 'siang') {\n            return hour >= 11 ? hour : hour + 12;\n        } else if (meridiem === 'sore' || meridiem === 'malam') {\n            return hour + 12;\n        }\n    },\n    meridiem : function (hours, minutes, isLower) {\n        if (hours < 11) {\n            return 'pagi';\n        } else if (hours < 15) {\n            return 'siang';\n        } else if (hours < 19) {\n            return 'sore';\n        } else {\n            return 'malam';\n        }\n    },\n    calendar : {\n        sameDay : '[Hari ini pukul] LT',\n        nextDay : '[Besok pukul] LT',\n        nextWeek : 'dddd [pukul] LT',\n        lastDay : '[Kemarin pukul] LT',\n        lastWeek : 'dddd [lalu pukul] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'dalam %s',\n        past : '%s yang lalu',\n        s : 'beberapa detik',\n        m : 'semenit',\n        mm : '%d menit',\n        h : 'sejam',\n        hh : '%d jam',\n        d : 'sehari',\n        dd : '%d hari',\n        M : 'sebulan',\n        MM : '%d bulan',\n        y : 'setahun',\n        yy : '%d tahun'\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 7  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/locale/is.js",
    "content": "//! moment.js locale configuration\n//! locale : Icelandic [is]\n//! author : Hinrik Örn Sigurðsson : https://github.com/hinrik\n\nimport moment from '../moment';\n\nfunction plural(n) {\n    if (n % 100 === 11) {\n        return true;\n    } else if (n % 10 === 1) {\n        return false;\n    }\n    return true;\n}\nfunction translate(number, withoutSuffix, key, isFuture) {\n    var result = number + ' ';\n    switch (key) {\n        case 's':\n            return withoutSuffix || isFuture ? 'nokkrar sekúndur' : 'nokkrum sekúndum';\n        case 'm':\n            return withoutSuffix ? 'mínúta' : 'mínútu';\n        case 'mm':\n            if (plural(number)) {\n                return result + (withoutSuffix || isFuture ? 'mínútur' : 'mínútum');\n            } else if (withoutSuffix) {\n                return result + 'mínúta';\n            }\n            return result + 'mínútu';\n        case 'hh':\n            if (plural(number)) {\n                return result + (withoutSuffix || isFuture ? 'klukkustundir' : 'klukkustundum');\n            }\n            return result + 'klukkustund';\n        case 'd':\n            if (withoutSuffix) {\n                return 'dagur';\n            }\n            return isFuture ? 'dag' : 'degi';\n        case 'dd':\n            if (plural(number)) {\n                if (withoutSuffix) {\n                    return result + 'dagar';\n                }\n                return result + (isFuture ? 'daga' : 'dögum');\n            } else if (withoutSuffix) {\n                return result + 'dagur';\n            }\n            return result + (isFuture ? 'dag' : 'degi');\n        case 'M':\n            if (withoutSuffix) {\n                return 'mánuður';\n            }\n            return isFuture ? 'mánuð' : 'mánuði';\n        case 'MM':\n            if (plural(number)) {\n                if (withoutSuffix) {\n                    return result + 'mánuðir';\n                }\n                return result + (isFuture ? 'mánuði' : 'mánuðum');\n            } else if (withoutSuffix) {\n                return result + 'mánuður';\n            }\n            return result + (isFuture ? 'mánuð' : 'mánuði');\n        case 'y':\n            return withoutSuffix || isFuture ? 'ár' : 'ári';\n        case 'yy':\n            if (plural(number)) {\n                return result + (withoutSuffix || isFuture ? 'ár' : 'árum');\n            }\n            return result + (withoutSuffix || isFuture ? 'ár' : 'ári');\n    }\n}\n\nexport default moment.defineLocale('is', {\n    months : 'janúar_febrúar_mars_apríl_maí_júní_júlí_ágúst_september_október_nóvember_desember'.split('_'),\n    monthsShort : 'jan_feb_mar_apr_maí_jún_júl_ágú_sep_okt_nóv_des'.split('_'),\n    weekdays : 'sunnudagur_mánudagur_þriðjudagur_miðvikudagur_fimmtudagur_föstudagur_laugardagur'.split('_'),\n    weekdaysShort : 'sun_mán_þri_mið_fim_fös_lau'.split('_'),\n    weekdaysMin : 'Su_Má_Þr_Mi_Fi_Fö_La'.split('_'),\n    longDateFormat : {\n        LT : 'H:mm',\n        LTS : 'H:mm:ss',\n        L : 'DD.MM.YYYY',\n        LL : 'D. MMMM YYYY',\n        LLL : 'D. MMMM YYYY [kl.] H:mm',\n        LLLL : 'dddd, D. MMMM YYYY [kl.] H:mm'\n    },\n    calendar : {\n        sameDay : '[í dag kl.] LT',\n        nextDay : '[á morgun kl.] LT',\n        nextWeek : 'dddd [kl.] LT',\n        lastDay : '[í gær kl.] LT',\n        lastWeek : '[síðasta] dddd [kl.] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'eftir %s',\n        past : 'fyrir %s síðan',\n        s : translate,\n        m : translate,\n        mm : translate,\n        h : 'klukkustund',\n        hh : translate,\n        d : translate,\n        dd : translate,\n        M : translate,\n        MM : translate,\n        y : translate,\n        yy : translate\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}\\./,\n    ordinal : '%d.',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/locale/it.js",
    "content": "//! moment.js locale configuration\n//! locale : Italian [it]\n//! author : Lorenzo : https://github.com/aliem\n//! author: Mattia Larentis: https://github.com/nostalgiaz\n\nimport moment from '../moment';\n\nexport default moment.defineLocale('it', {\n    months : 'gennaio_febbraio_marzo_aprile_maggio_giugno_luglio_agosto_settembre_ottobre_novembre_dicembre'.split('_'),\n    monthsShort : 'gen_feb_mar_apr_mag_giu_lug_ago_set_ott_nov_dic'.split('_'),\n    weekdays : 'domenica_lunedì_martedì_mercoledì_giovedì_venerdì_sabato'.split('_'),\n    weekdaysShort : 'dom_lun_mar_mer_gio_ven_sab'.split('_'),\n    weekdaysMin : 'do_lu_ma_me_gi_ve_sa'.split('_'),\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY HH:mm',\n        LLLL : 'dddd, D MMMM YYYY HH:mm'\n    },\n    calendar : {\n        sameDay: '[Oggi alle] LT',\n        nextDay: '[Domani alle] LT',\n        nextWeek: 'dddd [alle] LT',\n        lastDay: '[Ieri alle] LT',\n        lastWeek: function () {\n            switch (this.day()) {\n                case 0:\n                    return '[la scorsa] dddd [alle] LT';\n                default:\n                    return '[lo scorso] dddd [alle] LT';\n            }\n        },\n        sameElse: 'L'\n    },\n    relativeTime : {\n        future : function (s) {\n            return ((/^[0-9].+$/).test(s) ? 'tra' : 'in') + ' ' + s;\n        },\n        past : '%s fa',\n        s : 'alcuni secondi',\n        m : 'un minuto',\n        mm : '%d minuti',\n        h : 'un\\'ora',\n        hh : '%d ore',\n        d : 'un giorno',\n        dd : '%d giorni',\n        M : 'un mese',\n        MM : '%d mesi',\n        y : 'un anno',\n        yy : '%d anni'\n    },\n    dayOfMonthOrdinalParse : /\\d{1,2}º/,\n    ordinal: '%dº',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/locale/ja.js",
    "content": "//! moment.js locale configuration\n//! locale : Japanese [ja]\n//! author : LI Long : https://github.com/baryon\n\nimport moment from '../moment';\n\nexport default moment.defineLocale('ja', {\n    months : '1月_2月_3月_4月_5月_6月_7月_8月_9月_10月_11月_12月'.split('_'),\n    monthsShort : '1月_2月_3月_4月_5月_6月_7月_8月_9月_10月_11月_12月'.split('_'),\n    weekdays : '日曜日_月曜日_火曜日_水曜日_木曜日_金曜日_土曜日'.split('_'),\n    weekdaysShort : '日_月_火_水_木_金_土'.split('_'),\n    weekdaysMin : '日_月_火_水_木_金_土'.split('_'),\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'YYYY/MM/DD',\n        LL : 'YYYY年M月D日',\n        LLL : 'YYYY年M月D日 HH:mm',\n        LLLL : 'YYYY年M月D日 HH:mm dddd',\n        l : 'YYYY/MM/DD',\n        ll : 'YYYY年M月D日',\n        lll : 'YYYY年M月D日 HH:mm',\n        llll : 'YYYY年M月D日 HH:mm dddd'\n    },\n    meridiemParse: /午前|午後/i,\n    isPM : function (input) {\n        return input === '午後';\n    },\n    meridiem : function (hour, minute, isLower) {\n        if (hour < 12) {\n            return '午前';\n        } else {\n            return '午後';\n        }\n    },\n    calendar : {\n        sameDay : '[今日] LT',\n        nextDay : '[明日] LT',\n        nextWeek : '[来週]dddd LT',\n        lastDay : '[昨日] LT',\n        lastWeek : '[前週]dddd LT',\n        sameElse : 'L'\n    },\n    dayOfMonthOrdinalParse : /\\d{1,2}日/,\n    ordinal : function (number, period) {\n        switch (period) {\n            case 'd':\n            case 'D':\n            case 'DDD':\n                return number + '日';\n            default:\n                return number;\n        }\n    },\n    relativeTime : {\n        future : '%s後',\n        past : '%s前',\n        s : '数秒',\n        m : '1分',\n        mm : '%d分',\n        h : '1時間',\n        hh : '%d時間',\n        d : '1日',\n        dd : '%d日',\n        M : '1ヶ月',\n        MM : '%dヶ月',\n        y : '1年',\n        yy : '%d年'\n    }\n});\n\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/locale/jv.js",
    "content": "//! moment.js locale configuration\n//! locale : Javanese [jv]\n//! author : Rony Lantip : https://github.com/lantip\n//! reference: http://jv.wikipedia.org/wiki/Basa_Jawa\n\nimport moment from '../moment';\n\nexport default moment.defineLocale('jv', {\n    months : 'Januari_Februari_Maret_April_Mei_Juni_Juli_Agustus_September_Oktober_Nopember_Desember'.split('_'),\n    monthsShort : 'Jan_Feb_Mar_Apr_Mei_Jun_Jul_Ags_Sep_Okt_Nop_Des'.split('_'),\n    weekdays : 'Minggu_Senen_Seloso_Rebu_Kemis_Jemuwah_Septu'.split('_'),\n    weekdaysShort : 'Min_Sen_Sel_Reb_Kem_Jem_Sep'.split('_'),\n    weekdaysMin : 'Mg_Sn_Sl_Rb_Km_Jm_Sp'.split('_'),\n    longDateFormat : {\n        LT : 'HH.mm',\n        LTS : 'HH.mm.ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY [pukul] HH.mm',\n        LLLL : 'dddd, D MMMM YYYY [pukul] HH.mm'\n    },\n    meridiemParse: /enjing|siyang|sonten|ndalu/,\n    meridiemHour : function (hour, meridiem) {\n        if (hour === 12) {\n            hour = 0;\n        }\n        if (meridiem === 'enjing') {\n            return hour;\n        } else if (meridiem === 'siyang') {\n            return hour >= 11 ? hour : hour + 12;\n        } else if (meridiem === 'sonten' || meridiem === 'ndalu') {\n            return hour + 12;\n        }\n    },\n    meridiem : function (hours, minutes, isLower) {\n        if (hours < 11) {\n            return 'enjing';\n        } else if (hours < 15) {\n            return 'siyang';\n        } else if (hours < 19) {\n            return 'sonten';\n        } else {\n            return 'ndalu';\n        }\n    },\n    calendar : {\n        sameDay : '[Dinten puniko pukul] LT',\n        nextDay : '[Mbenjang pukul] LT',\n        nextWeek : 'dddd [pukul] LT',\n        lastDay : '[Kala wingi pukul] LT',\n        lastWeek : 'dddd [kepengker pukul] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'wonten ing %s',\n        past : '%s ingkang kepengker',\n        s : 'sawetawis detik',\n        m : 'setunggal menit',\n        mm : '%d menit',\n        h : 'setunggal jam',\n        hh : '%d jam',\n        d : 'sedinten',\n        dd : '%d dinten',\n        M : 'sewulan',\n        MM : '%d wulan',\n        y : 'setaun',\n        yy : '%d taun'\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 7  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/locale/ka.js",
    "content": "//! moment.js locale configuration\n//! locale : Georgian [ka]\n//! author : Irakli Janiashvili : https://github.com/irakli-janiashvili\n\nimport moment from '../moment';\n\nexport default moment.defineLocale('ka', {\n    months : {\n        standalone: 'იანვარი_თებერვალი_მარტი_აპრილი_მაისი_ივნისი_ივლისი_აგვისტო_სექტემბერი_ოქტომბერი_ნოემბერი_დეკემბერი'.split('_'),\n        format: 'იანვარს_თებერვალს_მარტს_აპრილის_მაისს_ივნისს_ივლისს_აგვისტს_სექტემბერს_ოქტომბერს_ნოემბერს_დეკემბერს'.split('_')\n    },\n    monthsShort : 'იან_თებ_მარ_აპრ_მაი_ივნ_ივლ_აგვ_სექ_ოქტ_ნოე_დეკ'.split('_'),\n    weekdays : {\n        standalone: 'კვირა_ორშაბათი_სამშაბათი_ოთხშაბათი_ხუთშაბათი_პარასკევი_შაბათი'.split('_'),\n        format: 'კვირას_ორშაბათს_სამშაბათს_ოთხშაბათს_ხუთშაბათს_პარასკევს_შაბათს'.split('_'),\n        isFormat: /(წინა|შემდეგ)/\n    },\n    weekdaysShort : 'კვი_ორშ_სამ_ოთხ_ხუთ_პარ_შაბ'.split('_'),\n    weekdaysMin : 'კვ_ორ_სა_ოთ_ხუ_პა_შა'.split('_'),\n    longDateFormat : {\n        LT : 'h:mm A',\n        LTS : 'h:mm:ss A',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY h:mm A',\n        LLLL : 'dddd, D MMMM YYYY h:mm A'\n    },\n    calendar : {\n        sameDay : '[დღეს] LT[-ზე]',\n        nextDay : '[ხვალ] LT[-ზე]',\n        lastDay : '[გუშინ] LT[-ზე]',\n        nextWeek : '[შემდეგ] dddd LT[-ზე]',\n        lastWeek : '[წინა] dddd LT-ზე',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : function (s) {\n            return (/(წამი|წუთი|საათი|წელი)/).test(s) ?\n                s.replace(/ი$/, 'ში') :\n                s + 'ში';\n        },\n        past : function (s) {\n            if ((/(წამი|წუთი|საათი|დღე|თვე)/).test(s)) {\n                return s.replace(/(ი|ე)$/, 'ის უკან');\n            }\n            if ((/წელი/).test(s)) {\n                return s.replace(/წელი$/, 'წლის უკან');\n            }\n        },\n        s : 'რამდენიმე წამი',\n        m : 'წუთი',\n        mm : '%d წუთი',\n        h : 'საათი',\n        hh : '%d საათი',\n        d : 'დღე',\n        dd : '%d დღე',\n        M : 'თვე',\n        MM : '%d თვე',\n        y : 'წელი',\n        yy : '%d წელი'\n    },\n    dayOfMonthOrdinalParse: /0|1-ლი|მე-\\d{1,2}|\\d{1,2}-ე/,\n    ordinal : function (number) {\n        if (number === 0) {\n            return number;\n        }\n        if (number === 1) {\n            return number + '-ლი';\n        }\n        if ((number < 20) || (number <= 100 && (number % 20 === 0)) || (number % 100 === 0)) {\n            return 'მე-' + number;\n        }\n        return number + '-ე';\n    },\n    week : {\n        dow : 1,\n        doy : 7\n    }\n});\n\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/locale/kk.js",
    "content": "//! moment.js locale configuration\n//! locale : Kazakh [kk]\n//! authors : Nurlan Rakhimzhanov : https://github.com/nurlan\n\nimport moment from '../moment';\n\nvar suffixes = {\n    0: '-ші',\n    1: '-ші',\n    2: '-ші',\n    3: '-ші',\n    4: '-ші',\n    5: '-ші',\n    6: '-шы',\n    7: '-ші',\n    8: '-ші',\n    9: '-шы',\n    10: '-шы',\n    20: '-шы',\n    30: '-шы',\n    40: '-шы',\n    50: '-ші',\n    60: '-шы',\n    70: '-ші',\n    80: '-ші',\n    90: '-шы',\n    100: '-ші'\n};\n\nexport default moment.defineLocale('kk', {\n    months : 'қаңтар_ақпан_наурыз_сәуір_мамыр_маусым_шілде_тамыз_қыркүйек_қазан_қараша_желтоқсан'.split('_'),\n    monthsShort : 'қаң_ақп_нау_сәу_мам_мау_шіл_там_қыр_қаз_қар_жел'.split('_'),\n    weekdays : 'жексенбі_дүйсенбі_сейсенбі_сәрсенбі_бейсенбі_жұма_сенбі'.split('_'),\n    weekdaysShort : 'жек_дүй_сей_сәр_бей_жұм_сен'.split('_'),\n    weekdaysMin : 'жк_дй_сй_ср_бй_жм_сн'.split('_'),\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD.MM.YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY HH:mm',\n        LLLL : 'dddd, D MMMM YYYY HH:mm'\n    },\n    calendar : {\n        sameDay : '[Бүгін сағат] LT',\n        nextDay : '[Ертең сағат] LT',\n        nextWeek : 'dddd [сағат] LT',\n        lastDay : '[Кеше сағат] LT',\n        lastWeek : '[Өткен аптаның] dddd [сағат] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : '%s ішінде',\n        past : '%s бұрын',\n        s : 'бірнеше секунд',\n        m : 'бір минут',\n        mm : '%d минут',\n        h : 'бір сағат',\n        hh : '%d сағат',\n        d : 'бір күн',\n        dd : '%d күн',\n        M : 'бір ай',\n        MM : '%d ай',\n        y : 'бір жыл',\n        yy : '%d жыл'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}-(ші|шы)/,\n    ordinal : function (number) {\n        var a = number % 10,\n            b = number >= 100 ? 100 : null;\n        return number + (suffixes[number] || suffixes[a] || suffixes[b]);\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 7  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/locale/km.js",
    "content": "//! moment.js locale configuration\n//! locale : Cambodian [km]\n//! author : Kruy Vanna : https://github.com/kruyvanna\n\nimport moment from '../moment';\n\nexport default moment.defineLocale('km', {\n    months: 'មករា_កុម្ភៈ_មីនា_មេសា_ឧសភា_មិថុនា_កក្កដា_សីហា_កញ្ញា_តុលា_វិច្ឆិកា_ធ្នូ'.split('_'),\n    monthsShort: 'មករា_កុម្ភៈ_មីនា_មេសា_ឧសភា_មិថុនា_កក្កដា_សីហា_កញ្ញា_តុលា_វិច្ឆិកា_ធ្នូ'.split('_'),\n    weekdays: 'អាទិត្យ_ច័ន្ទ_អង្គារ_ពុធ_ព្រហស្បតិ៍_សុក្រ_សៅរ៍'.split('_'),\n    weekdaysShort: 'អាទិត្យ_ច័ន្ទ_អង្គារ_ពុធ_ព្រហស្បតិ៍_សុក្រ_សៅរ៍'.split('_'),\n    weekdaysMin: 'អាទិត្យ_ច័ន្ទ_អង្គារ_ពុធ_ព្រហស្បតិ៍_សុក្រ_សៅរ៍'.split('_'),\n    longDateFormat: {\n        LT: 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L: 'DD/MM/YYYY',\n        LL: 'D MMMM YYYY',\n        LLL: 'D MMMM YYYY HH:mm',\n        LLLL: 'dddd, D MMMM YYYY HH:mm'\n    },\n    calendar: {\n        sameDay: '[ថ្ងៃនេះ ម៉ោង] LT',\n        nextDay: '[ស្អែក ម៉ោង] LT',\n        nextWeek: 'dddd [ម៉ោង] LT',\n        lastDay: '[ម្សិលមិញ ម៉ោង] LT',\n        lastWeek: 'dddd [សប្តាហ៍មុន] [ម៉ោង] LT',\n        sameElse: 'L'\n    },\n    relativeTime: {\n        future: '%sទៀត',\n        past: '%sមុន',\n        s: 'ប៉ុន្មានវិនាទី',\n        m: 'មួយនាទី',\n        mm: '%d នាទី',\n        h: 'មួយម៉ោង',\n        hh: '%d ម៉ោង',\n        d: 'មួយថ្ងៃ',\n        dd: '%d ថ្ងៃ',\n        M: 'មួយខែ',\n        MM: '%d ខែ',\n        y: 'មួយឆ្នាំ',\n        yy: '%d ឆ្នាំ'\n    },\n    week: {\n        dow: 1, // Monday is the first day of the week.\n        doy: 4 // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/locale/kn.js",
    "content": "//! moment.js locale configuration\n//! locale : Kannada [kn]\n//! author : Rajeev Naik : https://github.com/rajeevnaikte\n\nimport moment from '../moment';\n\nvar symbolMap = {\n    '1': '೧',\n    '2': '೨',\n    '3': '೩',\n    '4': '೪',\n    '5': '೫',\n    '6': '೬',\n    '7': '೭',\n    '8': '೮',\n    '9': '೯',\n    '0': '೦'\n},\nnumberMap = {\n    '೧': '1',\n    '೨': '2',\n    '೩': '3',\n    '೪': '4',\n    '೫': '5',\n    '೬': '6',\n    '೭': '7',\n    '೮': '8',\n    '೯': '9',\n    '೦': '0'\n};\n\nexport default moment.defineLocale('kn', {\n    months : 'ಜನವರಿ_ಫೆಬ್ರವರಿ_ಮಾರ್ಚ್_ಏಪ್ರಿಲ್_ಮೇ_ಜೂನ್_ಜುಲೈ_ಆಗಸ್ಟ್_ಸೆಪ್ಟೆಂಬರ್_ಅಕ್ಟೋಬರ್_ನವೆಂಬರ್_ಡಿಸೆಂಬರ್'.split('_'),\n    monthsShort : 'ಜನ_ಫೆಬ್ರ_ಮಾರ್ಚ್_ಏಪ್ರಿಲ್_ಮೇ_ಜೂನ್_ಜುಲೈ_ಆಗಸ್ಟ್_ಸೆಪ್ಟೆಂಬ_ಅಕ್ಟೋಬ_ನವೆಂಬ_ಡಿಸೆಂಬ'.split('_'),\n    monthsParseExact: true,\n    weekdays : 'ಭಾನುವಾರ_ಸೋಮವಾರ_ಮಂಗಳವಾರ_ಬುಧವಾರ_ಗುರುವಾರ_ಶುಕ್ರವಾರ_ಶನಿವಾರ'.split('_'),\n    weekdaysShort : 'ಭಾನು_ಸೋಮ_ಮಂಗಳ_ಬುಧ_ಗುರು_ಶುಕ್ರ_ಶನಿ'.split('_'),\n    weekdaysMin : 'ಭಾ_ಸೋ_ಮಂ_ಬು_ಗು_ಶು_ಶ'.split('_'),\n    longDateFormat : {\n        LT : 'A h:mm',\n        LTS : 'A h:mm:ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY, A h:mm',\n        LLLL : 'dddd, D MMMM YYYY, A h:mm'\n    },\n    calendar : {\n        sameDay : '[ಇಂದು] LT',\n        nextDay : '[ನಾಳೆ] LT',\n        nextWeek : 'dddd, LT',\n        lastDay : '[ನಿನ್ನೆ] LT',\n        lastWeek : '[ಕೊನೆಯ] dddd, LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : '%s ನಂತರ',\n        past : '%s ಹಿಂದೆ',\n        s : 'ಕೆಲವು ಕ್ಷಣಗಳು',\n        m : 'ಒಂದು ನಿಮಿಷ',\n        mm : '%d ನಿಮಿಷ',\n        h : 'ಒಂದು ಗಂಟೆ',\n        hh : '%d ಗಂಟೆ',\n        d : 'ಒಂದು ದಿನ',\n        dd : '%d ದಿನ',\n        M : 'ಒಂದು ತಿಂಗಳು',\n        MM : '%d ತಿಂಗಳು',\n        y : 'ಒಂದು ವರ್ಷ',\n        yy : '%d ವರ್ಷ'\n    },\n    preparse: function (string) {\n        return string.replace(/[೧೨೩೪೫೬೭೮೯೦]/g, function (match) {\n            return numberMap[match];\n        });\n    },\n    postformat: function (string) {\n        return string.replace(/\\d/g, function (match) {\n            return symbolMap[match];\n        });\n    },\n    meridiemParse: /ರಾತ್ರಿ|ಬೆಳಿಗ್ಗೆ|ಮಧ್ಯಾಹ್ನ|ಸಂಜೆ/,\n    meridiemHour : function (hour, meridiem) {\n        if (hour === 12) {\n            hour = 0;\n        }\n        if (meridiem === 'ರಾತ್ರಿ') {\n            return hour < 4 ? hour : hour + 12;\n        } else if (meridiem === 'ಬೆಳಿಗ್ಗೆ') {\n            return hour;\n        } else if (meridiem === 'ಮಧ್ಯಾಹ್ನ') {\n            return hour >= 10 ? hour : hour + 12;\n        } else if (meridiem === 'ಸಂಜೆ') {\n            return hour + 12;\n        }\n    },\n    meridiem : function (hour, minute, isLower) {\n        if (hour < 4) {\n            return 'ರಾತ್ರಿ';\n        } else if (hour < 10) {\n            return 'ಬೆಳಿಗ್ಗೆ';\n        } else if (hour < 17) {\n            return 'ಮಧ್ಯಾಹ್ನ';\n        } else if (hour < 20) {\n            return 'ಸಂಜೆ';\n        } else {\n            return 'ರಾತ್ರಿ';\n        }\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}(ನೇ)/,\n    ordinal : function (number) {\n        return number + 'ನೇ';\n    },\n    week : {\n        dow : 0, // Sunday is the first day of the week.\n        doy : 6  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/locale/ko.js",
    "content": "//! moment.js locale configuration\n//! locale : Korean [ko]\n//! author : Kyungwook, Park : https://github.com/kyungw00k\n//! author : Jeeeyul Lee <jeeeyul@gmail.com>\n\nimport moment from '../moment';\n\nexport default moment.defineLocale('ko', {\n    months : '1월_2월_3월_4월_5월_6월_7월_8월_9월_10월_11월_12월'.split('_'),\n    monthsShort : '1월_2월_3월_4월_5월_6월_7월_8월_9월_10월_11월_12월'.split('_'),\n    weekdays : '일요일_월요일_화요일_수요일_목요일_금요일_토요일'.split('_'),\n    weekdaysShort : '일_월_화_수_목_금_토'.split('_'),\n    weekdaysMin : '일_월_화_수_목_금_토'.split('_'),\n    longDateFormat : {\n        LT : 'A h:mm',\n        LTS : 'A h:mm:ss',\n        L : 'YYYY.MM.DD',\n        LL : 'YYYY년 MMMM D일',\n        LLL : 'YYYY년 MMMM D일 A h:mm',\n        LLLL : 'YYYY년 MMMM D일 dddd A h:mm',\n        l : 'YYYY.MM.DD',\n        ll : 'YYYY년 MMMM D일',\n        lll : 'YYYY년 MMMM D일 A h:mm',\n        llll : 'YYYY년 MMMM D일 dddd A h:mm'\n    },\n    calendar : {\n        sameDay : '오늘 LT',\n        nextDay : '내일 LT',\n        nextWeek : 'dddd LT',\n        lastDay : '어제 LT',\n        lastWeek : '지난주 dddd LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : '%s 후',\n        past : '%s 전',\n        s : '몇 초',\n        ss : '%d초',\n        m : '1분',\n        mm : '%d분',\n        h : '한 시간',\n        hh : '%d시간',\n        d : '하루',\n        dd : '%d일',\n        M : '한 달',\n        MM : '%d달',\n        y : '일 년',\n        yy : '%d년'\n    },\n    dayOfMonthOrdinalParse : /\\d{1,2}일/,\n    ordinal : '%d일',\n    meridiemParse : /오전|오후/,\n    isPM : function (token) {\n        return token === '오후';\n    },\n    meridiem : function (hour, minute, isUpper) {\n        return hour < 12 ? '오전' : '오후';\n    }\n});\n\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/locale/ky.js",
    "content": "//! moment.js locale configuration\n//! locale : Kyrgyz [ky]\n//! author : Chyngyz Arystan uulu : https://github.com/chyngyz\n\n\nimport moment from '../moment';\n\nvar suffixes = {\n    0: '-чү',\n    1: '-чи',\n    2: '-чи',\n    3: '-чү',\n    4: '-чү',\n    5: '-чи',\n    6: '-чы',\n    7: '-чи',\n    8: '-чи',\n    9: '-чу',\n    10: '-чу',\n    20: '-чы',\n    30: '-чу',\n    40: '-чы',\n    50: '-чү',\n    60: '-чы',\n    70: '-чи',\n    80: '-чи',\n    90: '-чу',\n    100: '-чү'\n};\n\nexport default moment.defineLocale('ky', {\n    months : 'январь_февраль_март_апрель_май_июнь_июль_август_сентябрь_октябрь_ноябрь_декабрь'.split('_'),\n    monthsShort : 'янв_фев_март_апр_май_июнь_июль_авг_сен_окт_ноя_дек'.split('_'),\n    weekdays : 'Жекшемби_Дүйшөмбү_Шейшемби_Шаршемби_Бейшемби_Жума_Ишемби'.split('_'),\n    weekdaysShort : 'Жек_Дүй_Шей_Шар_Бей_Жум_Ише'.split('_'),\n    weekdaysMin : 'Жк_Дй_Шй_Шр_Бй_Жм_Иш'.split('_'),\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD.MM.YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY HH:mm',\n        LLLL : 'dddd, D MMMM YYYY HH:mm'\n    },\n    calendar : {\n        sameDay : '[Бүгүн саат] LT',\n        nextDay : '[Эртең саат] LT',\n        nextWeek : 'dddd [саат] LT',\n        lastDay : '[Кече саат] LT',\n        lastWeek : '[Өткен аптанын] dddd [күнү] [саат] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : '%s ичинде',\n        past : '%s мурун',\n        s : 'бирнече секунд',\n        m : 'бир мүнөт',\n        mm : '%d мүнөт',\n        h : 'бир саат',\n        hh : '%d саат',\n        d : 'бир күн',\n        dd : '%d күн',\n        M : 'бир ай',\n        MM : '%d ай',\n        y : 'бир жыл',\n        yy : '%d жыл'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}-(чи|чы|чү|чу)/,\n    ordinal : function (number) {\n        var a = number % 10,\n            b = number >= 100 ? 100 : null;\n        return number + (suffixes[number] || suffixes[a] || suffixes[b]);\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 7  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/locale/lb.js",
    "content": "//! moment.js locale configuration\n//! locale : Luxembourgish [lb]\n//! author : mweimerskirch : https://github.com/mweimerskirch\n//! author : David Raison : https://github.com/kwisatz\n\nimport moment from '../moment';\n\nfunction processRelativeTime(number, withoutSuffix, key, isFuture) {\n    var format = {\n        'm': ['eng Minutt', 'enger Minutt'],\n        'h': ['eng Stonn', 'enger Stonn'],\n        'd': ['een Dag', 'engem Dag'],\n        'M': ['ee Mount', 'engem Mount'],\n        'y': ['ee Joer', 'engem Joer']\n    };\n    return withoutSuffix ? format[key][0] : format[key][1];\n}\nfunction processFutureTime(string) {\n    var number = string.substr(0, string.indexOf(' '));\n    if (eifelerRegelAppliesToNumber(number)) {\n        return 'a ' + string;\n    }\n    return 'an ' + string;\n}\nfunction processPastTime(string) {\n    var number = string.substr(0, string.indexOf(' '));\n    if (eifelerRegelAppliesToNumber(number)) {\n        return 'viru ' + string;\n    }\n    return 'virun ' + string;\n}\n/**\n * Returns true if the word before the given number loses the '-n' ending.\n * e.g. 'an 10 Deeg' but 'a 5 Deeg'\n *\n * @param number {integer}\n * @returns {boolean}\n */\nfunction eifelerRegelAppliesToNumber(number) {\n    number = parseInt(number, 10);\n    if (isNaN(number)) {\n        return false;\n    }\n    if (number < 0) {\n        // Negative Number --> always true\n        return true;\n    } else if (number < 10) {\n        // Only 1 digit\n        if (4 <= number && number <= 7) {\n            return true;\n        }\n        return false;\n    } else if (number < 100) {\n        // 2 digits\n        var lastDigit = number % 10, firstDigit = number / 10;\n        if (lastDigit === 0) {\n            return eifelerRegelAppliesToNumber(firstDigit);\n        }\n        return eifelerRegelAppliesToNumber(lastDigit);\n    } else if (number < 10000) {\n        // 3 or 4 digits --> recursively check first digit\n        while (number >= 10) {\n            number = number / 10;\n        }\n        return eifelerRegelAppliesToNumber(number);\n    } else {\n        // Anything larger than 4 digits: recursively check first n-3 digits\n        number = number / 1000;\n        return eifelerRegelAppliesToNumber(number);\n    }\n}\n\nexport default moment.defineLocale('lb', {\n    months: 'Januar_Februar_Mäerz_Abrëll_Mee_Juni_Juli_August_September_Oktober_November_Dezember'.split('_'),\n    monthsShort: 'Jan._Febr._Mrz._Abr._Mee_Jun._Jul._Aug._Sept._Okt._Nov._Dez.'.split('_'),\n    monthsParseExact : true,\n    weekdays: 'Sonndeg_Méindeg_Dënschdeg_Mëttwoch_Donneschdeg_Freideg_Samschdeg'.split('_'),\n    weekdaysShort: 'So._Mé._Dë._Më._Do._Fr._Sa.'.split('_'),\n    weekdaysMin: 'So_Mé_Dë_Më_Do_Fr_Sa'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat: {\n        LT: 'H:mm [Auer]',\n        LTS: 'H:mm:ss [Auer]',\n        L: 'DD.MM.YYYY',\n        LL: 'D. MMMM YYYY',\n        LLL: 'D. MMMM YYYY H:mm [Auer]',\n        LLLL: 'dddd, D. MMMM YYYY H:mm [Auer]'\n    },\n    calendar: {\n        sameDay: '[Haut um] LT',\n        sameElse: 'L',\n        nextDay: '[Muer um] LT',\n        nextWeek: 'dddd [um] LT',\n        lastDay: '[Gëschter um] LT',\n        lastWeek: function () {\n            // Different date string for 'Dënschdeg' (Tuesday) and 'Donneschdeg' (Thursday) due to phonological rule\n            switch (this.day()) {\n                case 2:\n                case 4:\n                    return '[Leschten] dddd [um] LT';\n                default:\n                    return '[Leschte] dddd [um] LT';\n            }\n        }\n    },\n    relativeTime : {\n        future : processFutureTime,\n        past : processPastTime,\n        s : 'e puer Sekonnen',\n        m : processRelativeTime,\n        mm : '%d Minutten',\n        h : processRelativeTime,\n        hh : '%d Stonnen',\n        d : processRelativeTime,\n        dd : '%d Deeg',\n        M : processRelativeTime,\n        MM : '%d Méint',\n        y : processRelativeTime,\n        yy : '%d Joer'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}\\./,\n    ordinal: '%d.',\n    week: {\n        dow: 1, // Monday is the first day of the week.\n        doy: 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/locale/lo.js",
    "content": "//! moment.js locale configuration\n//! locale : Lao [lo]\n//! author : Ryan Hart : https://github.com/ryanhart2\n\nimport moment from '../moment';\n\nexport default moment.defineLocale('lo', {\n    months : 'ມັງກອນ_ກຸມພາ_ມີນາ_ເມສາ_ພຶດສະພາ_ມິຖຸນາ_ກໍລະກົດ_ສິງຫາ_ກັນຍາ_ຕຸລາ_ພະຈິກ_ທັນວາ'.split('_'),\n    monthsShort : 'ມັງກອນ_ກຸມພາ_ມີນາ_ເມສາ_ພຶດສະພາ_ມິຖຸນາ_ກໍລະກົດ_ສິງຫາ_ກັນຍາ_ຕຸລາ_ພະຈິກ_ທັນວາ'.split('_'),\n    weekdays : 'ອາທິດ_ຈັນ_ອັງຄານ_ພຸດ_ພະຫັດ_ສຸກ_ເສົາ'.split('_'),\n    weekdaysShort : 'ທິດ_ຈັນ_ອັງຄານ_ພຸດ_ພະຫັດ_ສຸກ_ເສົາ'.split('_'),\n    weekdaysMin : 'ທ_ຈ_ອຄ_ພ_ພຫ_ສກ_ສ'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY HH:mm',\n        LLLL : 'ວັນdddd D MMMM YYYY HH:mm'\n    },\n    meridiemParse: /ຕອນເຊົ້າ|ຕອນແລງ/,\n    isPM: function (input) {\n        return input === 'ຕອນແລງ';\n    },\n    meridiem : function (hour, minute, isLower) {\n        if (hour < 12) {\n            return 'ຕອນເຊົ້າ';\n        } else {\n            return 'ຕອນແລງ';\n        }\n    },\n    calendar : {\n        sameDay : '[ມື້ນີ້ເວລາ] LT',\n        nextDay : '[ມື້ອື່ນເວລາ] LT',\n        nextWeek : '[ວັນ]dddd[ໜ້າເວລາ] LT',\n        lastDay : '[ມື້ວານນີ້ເວລາ] LT',\n        lastWeek : '[ວັນ]dddd[ແລ້ວນີ້ເວລາ] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'ອີກ %s',\n        past : '%sຜ່ານມາ',\n        s : 'ບໍ່ເທົ່າໃດວິນາທີ',\n        m : '1 ນາທີ',\n        mm : '%d ນາທີ',\n        h : '1 ຊົ່ວໂມງ',\n        hh : '%d ຊົ່ວໂມງ',\n        d : '1 ມື້',\n        dd : '%d ມື້',\n        M : '1 ເດືອນ',\n        MM : '%d ເດືອນ',\n        y : '1 ປີ',\n        yy : '%d ປີ'\n    },\n    dayOfMonthOrdinalParse: /(ທີ່)\\d{1,2}/,\n    ordinal : function (number) {\n        return 'ທີ່' + number;\n    }\n});\n\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/locale/lt.js",
    "content": "//! moment.js locale configuration\n//! locale : Lithuanian [lt]\n//! author : Mindaugas Mozūras : https://github.com/mmozuras\n\nimport moment from '../moment';\n\nvar units = {\n    'm' : 'minutė_minutės_minutę',\n    'mm': 'minutės_minučių_minutes',\n    'h' : 'valanda_valandos_valandą',\n    'hh': 'valandos_valandų_valandas',\n    'd' : 'diena_dienos_dieną',\n    'dd': 'dienos_dienų_dienas',\n    'M' : 'mėnuo_mėnesio_mėnesį',\n    'MM': 'mėnesiai_mėnesių_mėnesius',\n    'y' : 'metai_metų_metus',\n    'yy': 'metai_metų_metus'\n};\nfunction translateSeconds(number, withoutSuffix, key, isFuture) {\n    if (withoutSuffix) {\n        return 'kelios sekundės';\n    } else {\n        return isFuture ? 'kelių sekundžių' : 'kelias sekundes';\n    }\n}\nfunction translateSingular(number, withoutSuffix, key, isFuture) {\n    return withoutSuffix ? forms(key)[0] : (isFuture ? forms(key)[1] : forms(key)[2]);\n}\nfunction special(number) {\n    return number % 10 === 0 || (number > 10 && number < 20);\n}\nfunction forms(key) {\n    return units[key].split('_');\n}\nfunction translate(number, withoutSuffix, key, isFuture) {\n    var result = number + ' ';\n    if (number === 1) {\n        return result + translateSingular(number, withoutSuffix, key[0], isFuture);\n    } else if (withoutSuffix) {\n        return result + (special(number) ? forms(key)[1] : forms(key)[0]);\n    } else {\n        if (isFuture) {\n            return result + forms(key)[1];\n        } else {\n            return result + (special(number) ? forms(key)[1] : forms(key)[2]);\n        }\n    }\n}\nexport default moment.defineLocale('lt', {\n    months : {\n        format: 'sausio_vasario_kovo_balandžio_gegužės_birželio_liepos_rugpjūčio_rugsėjo_spalio_lapkričio_gruodžio'.split('_'),\n        standalone: 'sausis_vasaris_kovas_balandis_gegužė_birželis_liepa_rugpjūtis_rugsėjis_spalis_lapkritis_gruodis'.split('_'),\n        isFormat: /D[oD]?(\\[[^\\[\\]]*\\]|\\s)+MMMM?|MMMM?(\\[[^\\[\\]]*\\]|\\s)+D[oD]?/\n    },\n    monthsShort : 'sau_vas_kov_bal_geg_bir_lie_rgp_rgs_spa_lap_grd'.split('_'),\n    weekdays : {\n        format: 'sekmadienį_pirmadienį_antradienį_trečiadienį_ketvirtadienį_penktadienį_šeštadienį'.split('_'),\n        standalone: 'sekmadienis_pirmadienis_antradienis_trečiadienis_ketvirtadienis_penktadienis_šeštadienis'.split('_'),\n        isFormat: /dddd HH:mm/\n    },\n    weekdaysShort : 'Sek_Pir_Ant_Tre_Ket_Pen_Šeš'.split('_'),\n    weekdaysMin : 'S_P_A_T_K_Pn_Š'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'YYYY-MM-DD',\n        LL : 'YYYY [m.] MMMM D [d.]',\n        LLL : 'YYYY [m.] MMMM D [d.], HH:mm [val.]',\n        LLLL : 'YYYY [m.] MMMM D [d.], dddd, HH:mm [val.]',\n        l : 'YYYY-MM-DD',\n        ll : 'YYYY [m.] MMMM D [d.]',\n        lll : 'YYYY [m.] MMMM D [d.], HH:mm [val.]',\n        llll : 'YYYY [m.] MMMM D [d.], ddd, HH:mm [val.]'\n    },\n    calendar : {\n        sameDay : '[Šiandien] LT',\n        nextDay : '[Rytoj] LT',\n        nextWeek : 'dddd LT',\n        lastDay : '[Vakar] LT',\n        lastWeek : '[Praėjusį] dddd LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'po %s',\n        past : 'prieš %s',\n        s : translateSeconds,\n        m : translateSingular,\n        mm : translate,\n        h : translateSingular,\n        hh : translate,\n        d : translateSingular,\n        dd : translate,\n        M : translateSingular,\n        MM : translate,\n        y : translateSingular,\n        yy : translate\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}-oji/,\n    ordinal : function (number) {\n        return number + '-oji';\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/locale/lv.js",
    "content": "//! moment.js locale configuration\n//! locale : Latvian [lv]\n//! author : Kristaps Karlsons : https://github.com/skakri\n//! author : Jānis Elmeris : https://github.com/JanisE\n\nimport moment from '../moment';\n\nvar units = {\n    'm': 'minūtes_minūtēm_minūte_minūtes'.split('_'),\n    'mm': 'minūtes_minūtēm_minūte_minūtes'.split('_'),\n    'h': 'stundas_stundām_stunda_stundas'.split('_'),\n    'hh': 'stundas_stundām_stunda_stundas'.split('_'),\n    'd': 'dienas_dienām_diena_dienas'.split('_'),\n    'dd': 'dienas_dienām_diena_dienas'.split('_'),\n    'M': 'mēneša_mēnešiem_mēnesis_mēneši'.split('_'),\n    'MM': 'mēneša_mēnešiem_mēnesis_mēneši'.split('_'),\n    'y': 'gada_gadiem_gads_gadi'.split('_'),\n    'yy': 'gada_gadiem_gads_gadi'.split('_')\n};\n/**\n * @param withoutSuffix boolean true = a length of time; false = before/after a period of time.\n */\nfunction format(forms, number, withoutSuffix) {\n    if (withoutSuffix) {\n        // E.g. \"21 minūte\", \"3 minūtes\".\n        return number % 10 === 1 && number % 100 !== 11 ? forms[2] : forms[3];\n    } else {\n        // E.g. \"21 minūtes\" as in \"pēc 21 minūtes\".\n        // E.g. \"3 minūtēm\" as in \"pēc 3 minūtēm\".\n        return number % 10 === 1 && number % 100 !== 11 ? forms[0] : forms[1];\n    }\n}\nfunction relativeTimeWithPlural(number, withoutSuffix, key) {\n    return number + ' ' + format(units[key], number, withoutSuffix);\n}\nfunction relativeTimeWithSingular(number, withoutSuffix, key) {\n    return format(units[key], number, withoutSuffix);\n}\nfunction relativeSeconds(number, withoutSuffix) {\n    return withoutSuffix ? 'dažas sekundes' : 'dažām sekundēm';\n}\n\nexport default moment.defineLocale('lv', {\n    months : 'janvāris_februāris_marts_aprīlis_maijs_jūnijs_jūlijs_augusts_septembris_oktobris_novembris_decembris'.split('_'),\n    monthsShort : 'jan_feb_mar_apr_mai_jūn_jūl_aug_sep_okt_nov_dec'.split('_'),\n    weekdays : 'svētdiena_pirmdiena_otrdiena_trešdiena_ceturtdiena_piektdiena_sestdiena'.split('_'),\n    weekdaysShort : 'Sv_P_O_T_C_Pk_S'.split('_'),\n    weekdaysMin : 'Sv_P_O_T_C_Pk_S'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD.MM.YYYY.',\n        LL : 'YYYY. [gada] D. MMMM',\n        LLL : 'YYYY. [gada] D. MMMM, HH:mm',\n        LLLL : 'YYYY. [gada] D. MMMM, dddd, HH:mm'\n    },\n    calendar : {\n        sameDay : '[Šodien pulksten] LT',\n        nextDay : '[Rīt pulksten] LT',\n        nextWeek : 'dddd [pulksten] LT',\n        lastDay : '[Vakar pulksten] LT',\n        lastWeek : '[Pagājušā] dddd [pulksten] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'pēc %s',\n        past : 'pirms %s',\n        s : relativeSeconds,\n        m : relativeTimeWithSingular,\n        mm : relativeTimeWithPlural,\n        h : relativeTimeWithSingular,\n        hh : relativeTimeWithPlural,\n        d : relativeTimeWithSingular,\n        dd : relativeTimeWithPlural,\n        M : relativeTimeWithSingular,\n        MM : relativeTimeWithPlural,\n        y : relativeTimeWithSingular,\n        yy : relativeTimeWithPlural\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}\\./,\n    ordinal : '%d.',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/locale/me.js",
    "content": "//! moment.js locale configuration\n//! locale : Montenegrin [me]\n//! author : Miodrag Nikač <miodrag@restartit.me> : https://github.com/miodragnikac\n\nimport moment from '../moment';\n\nvar translator = {\n    words: { //Different grammatical cases\n        m: ['jedan minut', 'jednog minuta'],\n        mm: ['minut', 'minuta', 'minuta'],\n        h: ['jedan sat', 'jednog sata'],\n        hh: ['sat', 'sata', 'sati'],\n        dd: ['dan', 'dana', 'dana'],\n        MM: ['mjesec', 'mjeseca', 'mjeseci'],\n        yy: ['godina', 'godine', 'godina']\n    },\n    correctGrammaticalCase: function (number, wordKey) {\n        return number === 1 ? wordKey[0] : (number >= 2 && number <= 4 ? wordKey[1] : wordKey[2]);\n    },\n    translate: function (number, withoutSuffix, key) {\n        var wordKey = translator.words[key];\n        if (key.length === 1) {\n            return withoutSuffix ? wordKey[0] : wordKey[1];\n        } else {\n            return number + ' ' + translator.correctGrammaticalCase(number, wordKey);\n        }\n    }\n};\n\nexport default moment.defineLocale('me', {\n    months: 'januar_februar_mart_april_maj_jun_jul_avgust_septembar_oktobar_novembar_decembar'.split('_'),\n    monthsShort: 'jan._feb._mar._apr._maj_jun_jul_avg._sep._okt._nov._dec.'.split('_'),\n    monthsParseExact : true,\n    weekdays: 'nedjelja_ponedjeljak_utorak_srijeda_četvrtak_petak_subota'.split('_'),\n    weekdaysShort: 'ned._pon._uto._sri._čet._pet._sub.'.split('_'),\n    weekdaysMin: 'ne_po_ut_sr_če_pe_su'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat: {\n        LT: 'H:mm',\n        LTS : 'H:mm:ss',\n        L: 'DD.MM.YYYY',\n        LL: 'D. MMMM YYYY',\n        LLL: 'D. MMMM YYYY H:mm',\n        LLLL: 'dddd, D. MMMM YYYY H:mm'\n    },\n    calendar: {\n        sameDay: '[danas u] LT',\n        nextDay: '[sjutra u] LT',\n\n        nextWeek: function () {\n            switch (this.day()) {\n                case 0:\n                    return '[u] [nedjelju] [u] LT';\n                case 3:\n                    return '[u] [srijedu] [u] LT';\n                case 6:\n                    return '[u] [subotu] [u] LT';\n                case 1:\n                case 2:\n                case 4:\n                case 5:\n                    return '[u] dddd [u] LT';\n            }\n        },\n        lastDay  : '[juče u] LT',\n        lastWeek : function () {\n            var lastWeekDays = [\n                '[prošle] [nedjelje] [u] LT',\n                '[prošlog] [ponedjeljka] [u] LT',\n                '[prošlog] [utorka] [u] LT',\n                '[prošle] [srijede] [u] LT',\n                '[prošlog] [četvrtka] [u] LT',\n                '[prošlog] [petka] [u] LT',\n                '[prošle] [subote] [u] LT'\n            ];\n            return lastWeekDays[this.day()];\n        },\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'za %s',\n        past   : 'prije %s',\n        s      : 'nekoliko sekundi',\n        m      : translator.translate,\n        mm     : translator.translate,\n        h      : translator.translate,\n        hh     : translator.translate,\n        d      : 'dan',\n        dd     : translator.translate,\n        M      : 'mjesec',\n        MM     : translator.translate,\n        y      : 'godinu',\n        yy     : translator.translate\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}\\./,\n    ordinal : '%d.',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 7  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/locale/mi.js",
    "content": "//! moment.js locale configuration\n//! locale : Maori [mi]\n//! author : John Corrigan <robbiecloset@gmail.com> : https://github.com/johnideal\n\nimport moment from '../moment';\n\nexport default moment.defineLocale('mi', {\n    months: 'Kohi-tāte_Hui-tanguru_Poutū-te-rangi_Paenga-whāwhā_Haratua_Pipiri_Hōngoingoi_Here-turi-kōkā_Mahuru_Whiringa-ā-nuku_Whiringa-ā-rangi_Hakihea'.split('_'),\n    monthsShort: 'Kohi_Hui_Pou_Pae_Hara_Pipi_Hōngoi_Here_Mahu_Whi-nu_Whi-ra_Haki'.split('_'),\n    monthsRegex: /(?:['a-z\\u0101\\u014D\\u016B]+\\-?){1,3}/i,\n    monthsStrictRegex: /(?:['a-z\\u0101\\u014D\\u016B]+\\-?){1,3}/i,\n    monthsShortRegex: /(?:['a-z\\u0101\\u014D\\u016B]+\\-?){1,3}/i,\n    monthsShortStrictRegex: /(?:['a-z\\u0101\\u014D\\u016B]+\\-?){1,2}/i,\n    weekdays: 'Rātapu_Mane_Tūrei_Wenerei_Tāite_Paraire_Hātarei'.split('_'),\n    weekdaysShort: 'Ta_Ma_Tū_We_Tāi_Pa_Hā'.split('_'),\n    weekdaysMin: 'Ta_Ma_Tū_We_Tāi_Pa_Hā'.split('_'),\n    longDateFormat: {\n        LT: 'HH:mm',\n        LTS: 'HH:mm:ss',\n        L: 'DD/MM/YYYY',\n        LL: 'D MMMM YYYY',\n        LLL: 'D MMMM YYYY [i] HH:mm',\n        LLLL: 'dddd, D MMMM YYYY [i] HH:mm'\n    },\n    calendar: {\n        sameDay: '[i teie mahana, i] LT',\n        nextDay: '[apopo i] LT',\n        nextWeek: 'dddd [i] LT',\n        lastDay: '[inanahi i] LT',\n        lastWeek: 'dddd [whakamutunga i] LT',\n        sameElse: 'L'\n    },\n    relativeTime: {\n        future: 'i roto i %s',\n        past: '%s i mua',\n        s: 'te hēkona ruarua',\n        m: 'he meneti',\n        mm: '%d meneti',\n        h: 'te haora',\n        hh: '%d haora',\n        d: 'he ra',\n        dd: '%d ra',\n        M: 'he marama',\n        MM: '%d marama',\n        y: 'he tau',\n        yy: '%d tau'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}º/,\n    ordinal: '%dº',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/locale/mk.js",
    "content": "//! moment.js locale configuration\n//! locale : Macedonian [mk]\n//! author : Borislav Mickov : https://github.com/B0k0\n\nimport moment from '../moment';\n\nexport default moment.defineLocale('mk', {\n    months : 'јануари_февруари_март_април_мај_јуни_јули_август_септември_октомври_ноември_декември'.split('_'),\n    monthsShort : 'јан_фев_мар_апр_мај_јун_јул_авг_сеп_окт_ное_дек'.split('_'),\n    weekdays : 'недела_понеделник_вторник_среда_четврток_петок_сабота'.split('_'),\n    weekdaysShort : 'нед_пон_вто_сре_чет_пет_саб'.split('_'),\n    weekdaysMin : 'нe_пo_вт_ср_че_пе_сa'.split('_'),\n    longDateFormat : {\n        LT : 'H:mm',\n        LTS : 'H:mm:ss',\n        L : 'D.MM.YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY H:mm',\n        LLLL : 'dddd, D MMMM YYYY H:mm'\n    },\n    calendar : {\n        sameDay : '[Денес во] LT',\n        nextDay : '[Утре во] LT',\n        nextWeek : '[Во] dddd [во] LT',\n        lastDay : '[Вчера во] LT',\n        lastWeek : function () {\n            switch (this.day()) {\n                case 0:\n                case 3:\n                case 6:\n                    return '[Изминатата] dddd [во] LT';\n                case 1:\n                case 2:\n                case 4:\n                case 5:\n                    return '[Изминатиот] dddd [во] LT';\n            }\n        },\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'после %s',\n        past : 'пред %s',\n        s : 'неколку секунди',\n        m : 'минута',\n        mm : '%d минути',\n        h : 'час',\n        hh : '%d часа',\n        d : 'ден',\n        dd : '%d дена',\n        M : 'месец',\n        MM : '%d месеци',\n        y : 'година',\n        yy : '%d години'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}-(ев|ен|ти|ви|ри|ми)/,\n    ordinal : function (number) {\n        var lastDigit = number % 10,\n            last2Digits = number % 100;\n        if (number === 0) {\n            return number + '-ев';\n        } else if (last2Digits === 0) {\n            return number + '-ен';\n        } else if (last2Digits > 10 && last2Digits < 20) {\n            return number + '-ти';\n        } else if (lastDigit === 1) {\n            return number + '-ви';\n        } else if (lastDigit === 2) {\n            return number + '-ри';\n        } else if (lastDigit === 7 || lastDigit === 8) {\n            return number + '-ми';\n        } else {\n            return number + '-ти';\n        }\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 7  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/locale/ml.js",
    "content": "//! moment.js locale configuration\n//! locale : Malayalam [ml]\n//! author : Floyd Pink : https://github.com/floydpink\n\nimport moment from '../moment';\n\nexport default moment.defineLocale('ml', {\n    months : 'ജനുവരി_ഫെബ്രുവരി_മാർച്ച്_ഏപ്രിൽ_മേയ്_ജൂൺ_ജൂലൈ_ഓഗസ്റ്റ്_സെപ്റ്റംബർ_ഒക്ടോബർ_നവംബർ_ഡിസംബർ'.split('_'),\n    monthsShort : 'ജനു._ഫെബ്രു._മാർ._ഏപ്രി._മേയ്_ജൂൺ_ജൂലൈ._ഓഗ._സെപ്റ്റ._ഒക്ടോ._നവം._ഡിസം.'.split('_'),\n    monthsParseExact : true,\n    weekdays : 'ഞായറാഴ്ച_തിങ്കളാഴ്ച_ചൊവ്വാഴ്ച_ബുധനാഴ്ച_വ്യാഴാഴ്ച_വെള്ളിയാഴ്ച_ശനിയാഴ്ച'.split('_'),\n    weekdaysShort : 'ഞായർ_തിങ്കൾ_ചൊവ്വ_ബുധൻ_വ്യാഴം_വെള്ളി_ശനി'.split('_'),\n    weekdaysMin : 'ഞാ_തി_ചൊ_ബു_വ്യാ_വെ_ശ'.split('_'),\n    longDateFormat : {\n        LT : 'A h:mm -നു',\n        LTS : 'A h:mm:ss -നു',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY, A h:mm -നു',\n        LLLL : 'dddd, D MMMM YYYY, A h:mm -നു'\n    },\n    calendar : {\n        sameDay : '[ഇന്ന്] LT',\n        nextDay : '[നാളെ] LT',\n        nextWeek : 'dddd, LT',\n        lastDay : '[ഇന്നലെ] LT',\n        lastWeek : '[കഴിഞ്ഞ] dddd, LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : '%s കഴിഞ്ഞ്',\n        past : '%s മുൻപ്',\n        s : 'അൽപ നിമിഷങ്ങൾ',\n        m : 'ഒരു മിനിറ്റ്',\n        mm : '%d മിനിറ്റ്',\n        h : 'ഒരു മണിക്കൂർ',\n        hh : '%d മണിക്കൂർ',\n        d : 'ഒരു ദിവസം',\n        dd : '%d ദിവസം',\n        M : 'ഒരു മാസം',\n        MM : '%d മാസം',\n        y : 'ഒരു വർഷം',\n        yy : '%d വർഷം'\n    },\n    meridiemParse: /രാത്രി|രാവിലെ|ഉച്ച കഴിഞ്ഞ്|വൈകുന്നേരം|രാത്രി/i,\n    meridiemHour : function (hour, meridiem) {\n        if (hour === 12) {\n            hour = 0;\n        }\n        if ((meridiem === 'രാത്രി' && hour >= 4) ||\n                meridiem === 'ഉച്ച കഴിഞ്ഞ്' ||\n                meridiem === 'വൈകുന്നേരം') {\n            return hour + 12;\n        } else {\n            return hour;\n        }\n    },\n    meridiem : function (hour, minute, isLower) {\n        if (hour < 4) {\n            return 'രാത്രി';\n        } else if (hour < 12) {\n            return 'രാവിലെ';\n        } else if (hour < 17) {\n            return 'ഉച്ച കഴിഞ്ഞ്';\n        } else if (hour < 20) {\n            return 'വൈകുന്നേരം';\n        } else {\n            return 'രാത്രി';\n        }\n    }\n});\n\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/locale/mr.js",
    "content": "//! moment.js locale configuration\n//! locale : Marathi [mr]\n//! author : Harshad Kale : https://github.com/kalehv\n//! author : Vivek Athalye : https://github.com/vnathalye\n\nimport moment from '../moment';\n\nvar symbolMap = {\n    '1': '१',\n    '2': '२',\n    '3': '३',\n    '4': '४',\n    '5': '५',\n    '6': '६',\n    '7': '७',\n    '8': '८',\n    '9': '९',\n    '0': '०'\n},\nnumberMap = {\n    '१': '1',\n    '२': '2',\n    '३': '3',\n    '४': '4',\n    '५': '5',\n    '६': '6',\n    '७': '7',\n    '८': '8',\n    '९': '9',\n    '०': '0'\n};\n\nfunction relativeTimeMr(number, withoutSuffix, string, isFuture)\n{\n    var output = '';\n    if (withoutSuffix) {\n        switch (string) {\n            case 's': output = 'काही सेकंद'; break;\n            case 'm': output = 'एक मिनिट'; break;\n            case 'mm': output = '%d मिनिटे'; break;\n            case 'h': output = 'एक तास'; break;\n            case 'hh': output = '%d तास'; break;\n            case 'd': output = 'एक दिवस'; break;\n            case 'dd': output = '%d दिवस'; break;\n            case 'M': output = 'एक महिना'; break;\n            case 'MM': output = '%d महिने'; break;\n            case 'y': output = 'एक वर्ष'; break;\n            case 'yy': output = '%d वर्षे'; break;\n        }\n    }\n    else {\n        switch (string) {\n            case 's': output = 'काही सेकंदां'; break;\n            case 'm': output = 'एका मिनिटा'; break;\n            case 'mm': output = '%d मिनिटां'; break;\n            case 'h': output = 'एका तासा'; break;\n            case 'hh': output = '%d तासां'; break;\n            case 'd': output = 'एका दिवसा'; break;\n            case 'dd': output = '%d दिवसां'; break;\n            case 'M': output = 'एका महिन्या'; break;\n            case 'MM': output = '%d महिन्यां'; break;\n            case 'y': output = 'एका वर्षा'; break;\n            case 'yy': output = '%d वर्षां'; break;\n        }\n    }\n    return output.replace(/%d/i, number);\n}\n\nexport default moment.defineLocale('mr', {\n    months : 'जानेवारी_फेब्रुवारी_मार्च_एप्रिल_मे_जून_जुलै_ऑगस्ट_सप्टेंबर_ऑक्टोबर_नोव्हेंबर_डिसेंबर'.split('_'),\n    monthsShort: 'जाने._फेब्रु._मार्च._एप्रि._मे._जून._जुलै._ऑग._सप्टें._ऑक्टो._नोव्हें._डिसें.'.split('_'),\n    monthsParseExact : true,\n    weekdays : 'रविवार_सोमवार_मंगळवार_बुधवार_गुरूवार_शुक्रवार_शनिवार'.split('_'),\n    weekdaysShort : 'रवि_सोम_मंगळ_बुध_गुरू_शुक्र_शनि'.split('_'),\n    weekdaysMin : 'र_सो_मं_बु_गु_शु_श'.split('_'),\n    longDateFormat : {\n        LT : 'A h:mm वाजता',\n        LTS : 'A h:mm:ss वाजता',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY, A h:mm वाजता',\n        LLLL : 'dddd, D MMMM YYYY, A h:mm वाजता'\n    },\n    calendar : {\n        sameDay : '[आज] LT',\n        nextDay : '[उद्या] LT',\n        nextWeek : 'dddd, LT',\n        lastDay : '[काल] LT',\n        lastWeek: '[मागील] dddd, LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future: '%sमध्ये',\n        past: '%sपूर्वी',\n        s: relativeTimeMr,\n        m: relativeTimeMr,\n        mm: relativeTimeMr,\n        h: relativeTimeMr,\n        hh: relativeTimeMr,\n        d: relativeTimeMr,\n        dd: relativeTimeMr,\n        M: relativeTimeMr,\n        MM: relativeTimeMr,\n        y: relativeTimeMr,\n        yy: relativeTimeMr\n    },\n    preparse: function (string) {\n        return string.replace(/[१२३४५६७८९०]/g, function (match) {\n            return numberMap[match];\n        });\n    },\n    postformat: function (string) {\n        return string.replace(/\\d/g, function (match) {\n            return symbolMap[match];\n        });\n    },\n    meridiemParse: /रात्री|सकाळी|दुपारी|सायंकाळी/,\n    meridiemHour : function (hour, meridiem) {\n        if (hour === 12) {\n            hour = 0;\n        }\n        if (meridiem === 'रात्री') {\n            return hour < 4 ? hour : hour + 12;\n        } else if (meridiem === 'सकाळी') {\n            return hour;\n        } else if (meridiem === 'दुपारी') {\n            return hour >= 10 ? hour : hour + 12;\n        } else if (meridiem === 'सायंकाळी') {\n            return hour + 12;\n        }\n    },\n    meridiem: function (hour, minute, isLower) {\n        if (hour < 4) {\n            return 'रात्री';\n        } else if (hour < 10) {\n            return 'सकाळी';\n        } else if (hour < 17) {\n            return 'दुपारी';\n        } else if (hour < 20) {\n            return 'सायंकाळी';\n        } else {\n            return 'रात्री';\n        }\n    },\n    week : {\n        dow : 0, // Sunday is the first day of the week.\n        doy : 6  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/locale/ms-my.js",
    "content": "//! moment.js locale configuration\n//! locale : Malay [ms-my]\n//! note : DEPRECATED, the correct one is [ms]\n//! author : Weldan Jamili : https://github.com/weldan\n\nimport moment from '../moment';\n\nexport default moment.defineLocale('ms-my', {\n    months : 'Januari_Februari_Mac_April_Mei_Jun_Julai_Ogos_September_Oktober_November_Disember'.split('_'),\n    monthsShort : 'Jan_Feb_Mac_Apr_Mei_Jun_Jul_Ogs_Sep_Okt_Nov_Dis'.split('_'),\n    weekdays : 'Ahad_Isnin_Selasa_Rabu_Khamis_Jumaat_Sabtu'.split('_'),\n    weekdaysShort : 'Ahd_Isn_Sel_Rab_Kha_Jum_Sab'.split('_'),\n    weekdaysMin : 'Ah_Is_Sl_Rb_Km_Jm_Sb'.split('_'),\n    longDateFormat : {\n        LT : 'HH.mm',\n        LTS : 'HH.mm.ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY [pukul] HH.mm',\n        LLLL : 'dddd, D MMMM YYYY [pukul] HH.mm'\n    },\n    meridiemParse: /pagi|tengahari|petang|malam/,\n    meridiemHour: function (hour, meridiem) {\n        if (hour === 12) {\n            hour = 0;\n        }\n        if (meridiem === 'pagi') {\n            return hour;\n        } else if (meridiem === 'tengahari') {\n            return hour >= 11 ? hour : hour + 12;\n        } else if (meridiem === 'petang' || meridiem === 'malam') {\n            return hour + 12;\n        }\n    },\n    meridiem : function (hours, minutes, isLower) {\n        if (hours < 11) {\n            return 'pagi';\n        } else if (hours < 15) {\n            return 'tengahari';\n        } else if (hours < 19) {\n            return 'petang';\n        } else {\n            return 'malam';\n        }\n    },\n    calendar : {\n        sameDay : '[Hari ini pukul] LT',\n        nextDay : '[Esok pukul] LT',\n        nextWeek : 'dddd [pukul] LT',\n        lastDay : '[Kelmarin pukul] LT',\n        lastWeek : 'dddd [lepas pukul] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'dalam %s',\n        past : '%s yang lepas',\n        s : 'beberapa saat',\n        m : 'seminit',\n        mm : '%d minit',\n        h : 'sejam',\n        hh : '%d jam',\n        d : 'sehari',\n        dd : '%d hari',\n        M : 'sebulan',\n        MM : '%d bulan',\n        y : 'setahun',\n        yy : '%d tahun'\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 7  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/locale/ms.js",
    "content": "//! moment.js locale configuration\n//! locale : Malay [ms]\n//! author : Weldan Jamili : https://github.com/weldan\n\nimport moment from '../moment';\n\nexport default moment.defineLocale('ms', {\n    months : 'Januari_Februari_Mac_April_Mei_Jun_Julai_Ogos_September_Oktober_November_Disember'.split('_'),\n    monthsShort : 'Jan_Feb_Mac_Apr_Mei_Jun_Jul_Ogs_Sep_Okt_Nov_Dis'.split('_'),\n    weekdays : 'Ahad_Isnin_Selasa_Rabu_Khamis_Jumaat_Sabtu'.split('_'),\n    weekdaysShort : 'Ahd_Isn_Sel_Rab_Kha_Jum_Sab'.split('_'),\n    weekdaysMin : 'Ah_Is_Sl_Rb_Km_Jm_Sb'.split('_'),\n    longDateFormat : {\n        LT : 'HH.mm',\n        LTS : 'HH.mm.ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY [pukul] HH.mm',\n        LLLL : 'dddd, D MMMM YYYY [pukul] HH.mm'\n    },\n    meridiemParse: /pagi|tengahari|petang|malam/,\n    meridiemHour: function (hour, meridiem) {\n        if (hour === 12) {\n            hour = 0;\n        }\n        if (meridiem === 'pagi') {\n            return hour;\n        } else if (meridiem === 'tengahari') {\n            return hour >= 11 ? hour : hour + 12;\n        } else if (meridiem === 'petang' || meridiem === 'malam') {\n            return hour + 12;\n        }\n    },\n    meridiem : function (hours, minutes, isLower) {\n        if (hours < 11) {\n            return 'pagi';\n        } else if (hours < 15) {\n            return 'tengahari';\n        } else if (hours < 19) {\n            return 'petang';\n        } else {\n            return 'malam';\n        }\n    },\n    calendar : {\n        sameDay : '[Hari ini pukul] LT',\n        nextDay : '[Esok pukul] LT',\n        nextWeek : 'dddd [pukul] LT',\n        lastDay : '[Kelmarin pukul] LT',\n        lastWeek : 'dddd [lepas pukul] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'dalam %s',\n        past : '%s yang lepas',\n        s : 'beberapa saat',\n        m : 'seminit',\n        mm : '%d minit',\n        h : 'sejam',\n        hh : '%d jam',\n        d : 'sehari',\n        dd : '%d hari',\n        M : 'sebulan',\n        MM : '%d bulan',\n        y : 'setahun',\n        yy : '%d tahun'\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 7  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/locale/my.js",
    "content": "//! moment.js locale configuration\n//! locale : Burmese [my]\n//! author : Squar team, mysquar.com\n//! author : David Rossellat : https://github.com/gholadr\n//! author : Tin Aung Lin : https://github.com/thanyawzinmin\n\nimport moment from '../moment';\n\nvar symbolMap = {\n    '1': '၁',\n    '2': '၂',\n    '3': '၃',\n    '4': '၄',\n    '5': '၅',\n    '6': '၆',\n    '7': '၇',\n    '8': '၈',\n    '9': '၉',\n    '0': '၀'\n}, numberMap = {\n    '၁': '1',\n    '၂': '2',\n    '၃': '3',\n    '၄': '4',\n    '၅': '5',\n    '၆': '6',\n    '၇': '7',\n    '၈': '8',\n    '၉': '9',\n    '၀': '0'\n};\n\nexport default moment.defineLocale('my', {\n    months: 'ဇန်နဝါရီ_ဖေဖော်ဝါရီ_မတ်_ဧပြီ_မေ_ဇွန်_ဇူလိုင်_သြဂုတ်_စက်တင်ဘာ_အောက်တိုဘာ_နိုဝင်ဘာ_ဒီဇင်ဘာ'.split('_'),\n    monthsShort: 'ဇန်_ဖေ_မတ်_ပြီ_မေ_ဇွန်_လိုင်_သြ_စက်_အောက်_နို_ဒီ'.split('_'),\n    weekdays: 'တနင်္ဂနွေ_တနင်္လာ_အင်္ဂါ_ဗုဒ္ဓဟူး_ကြာသပတေး_သောကြာ_စနေ'.split('_'),\n    weekdaysShort: 'နွေ_လာ_ဂါ_ဟူး_ကြာ_သော_နေ'.split('_'),\n    weekdaysMin: 'နွေ_လာ_ဂါ_ဟူး_ကြာ_သော_နေ'.split('_'),\n\n    longDateFormat: {\n        LT: 'HH:mm',\n        LTS: 'HH:mm:ss',\n        L: 'DD/MM/YYYY',\n        LL: 'D MMMM YYYY',\n        LLL: 'D MMMM YYYY HH:mm',\n        LLLL: 'dddd D MMMM YYYY HH:mm'\n    },\n    calendar: {\n        sameDay: '[ယနေ.] LT [မှာ]',\n        nextDay: '[မနက်ဖြန်] LT [မှာ]',\n        nextWeek: 'dddd LT [မှာ]',\n        lastDay: '[မနေ.က] LT [မှာ]',\n        lastWeek: '[ပြီးခဲ့သော] dddd LT [မှာ]',\n        sameElse: 'L'\n    },\n    relativeTime: {\n        future: 'လာမည့် %s မှာ',\n        past: 'လွန်ခဲ့သော %s က',\n        s: 'စက္ကန်.အနည်းငယ်',\n        m: 'တစ်မိနစ်',\n        mm: '%d မိနစ်',\n        h: 'တစ်နာရီ',\n        hh: '%d နာရီ',\n        d: 'တစ်ရက်',\n        dd: '%d ရက်',\n        M: 'တစ်လ',\n        MM: '%d လ',\n        y: 'တစ်နှစ်',\n        yy: '%d နှစ်'\n    },\n    preparse: function (string) {\n        return string.replace(/[၁၂၃၄၅၆၇၈၉၀]/g, function (match) {\n            return numberMap[match];\n        });\n    },\n    postformat: function (string) {\n        return string.replace(/\\d/g, function (match) {\n            return symbolMap[match];\n        });\n    },\n    week: {\n        dow: 1, // Monday is the first day of the week.\n        doy: 4 // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/locale/nb.js",
    "content": "//! moment.js locale configuration\n//! locale : Norwegian Bokmål [nb]\n//! authors : Espen Hovlandsdal : https://github.com/rexxars\n//!           Sigurd Gartmann : https://github.com/sigurdga\n\nimport moment from '../moment';\n\nexport default moment.defineLocale('nb', {\n    months : 'januar_februar_mars_april_mai_juni_juli_august_september_oktober_november_desember'.split('_'),\n    monthsShort : 'jan._feb._mars_april_mai_juni_juli_aug._sep._okt._nov._des.'.split('_'),\n    monthsParseExact : true,\n    weekdays : 'søndag_mandag_tirsdag_onsdag_torsdag_fredag_lørdag'.split('_'),\n    weekdaysShort : 'sø._ma._ti._on._to._fr._lø.'.split('_'),\n    weekdaysMin : 'sø_ma_ti_on_to_fr_lø'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD.MM.YYYY',\n        LL : 'D. MMMM YYYY',\n        LLL : 'D. MMMM YYYY [kl.] HH:mm',\n        LLLL : 'dddd D. MMMM YYYY [kl.] HH:mm'\n    },\n    calendar : {\n        sameDay: '[i dag kl.] LT',\n        nextDay: '[i morgen kl.] LT',\n        nextWeek: 'dddd [kl.] LT',\n        lastDay: '[i går kl.] LT',\n        lastWeek: '[forrige] dddd [kl.] LT',\n        sameElse: 'L'\n    },\n    relativeTime : {\n        future : 'om %s',\n        past : '%s siden',\n        s : 'noen sekunder',\n        m : 'ett minutt',\n        mm : '%d minutter',\n        h : 'en time',\n        hh : '%d timer',\n        d : 'en dag',\n        dd : '%d dager',\n        M : 'en måned',\n        MM : '%d måneder',\n        y : 'ett år',\n        yy : '%d år'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}\\./,\n    ordinal : '%d.',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/locale/ne.js",
    "content": "//! moment.js locale configuration\n//! locale : Nepalese [ne]\n//! author : suvash : https://github.com/suvash\n\nimport moment from '../moment';\n\nvar symbolMap = {\n    '1': '१',\n    '2': '२',\n    '3': '३',\n    '4': '४',\n    '5': '५',\n    '6': '६',\n    '7': '७',\n    '8': '८',\n    '9': '९',\n    '0': '०'\n},\nnumberMap = {\n    '१': '1',\n    '२': '2',\n    '३': '3',\n    '४': '4',\n    '५': '5',\n    '६': '6',\n    '७': '7',\n    '८': '8',\n    '९': '9',\n    '०': '0'\n};\n\nexport default moment.defineLocale('ne', {\n    months : 'जनवरी_फेब्रुवरी_मार्च_अप्रिल_मई_जुन_जुलाई_अगष्ट_सेप्टेम्बर_अक्टोबर_नोभेम्बर_डिसेम्बर'.split('_'),\n    monthsShort : 'जन._फेब्रु._मार्च_अप्रि._मई_जुन_जुलाई._अग._सेप्ट._अक्टो._नोभे._डिसे.'.split('_'),\n    monthsParseExact : true,\n    weekdays : 'आइतबार_सोमबार_मङ्गलबार_बुधबार_बिहिबार_शुक्रबार_शनिबार'.split('_'),\n    weekdaysShort : 'आइत._सोम._मङ्गल._बुध._बिहि._शुक्र._शनि.'.split('_'),\n    weekdaysMin : 'आ._सो._मं._बु._बि._शु._श.'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat : {\n        LT : 'Aको h:mm बजे',\n        LTS : 'Aको h:mm:ss बजे',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY, Aको h:mm बजे',\n        LLLL : 'dddd, D MMMM YYYY, Aको h:mm बजे'\n    },\n    preparse: function (string) {\n        return string.replace(/[१२३४५६७८९०]/g, function (match) {\n            return numberMap[match];\n        });\n    },\n    postformat: function (string) {\n        return string.replace(/\\d/g, function (match) {\n            return symbolMap[match];\n        });\n    },\n    meridiemParse: /राति|बिहान|दिउँसो|साँझ/,\n    meridiemHour : function (hour, meridiem) {\n        if (hour === 12) {\n            hour = 0;\n        }\n        if (meridiem === 'राति') {\n            return hour < 4 ? hour : hour + 12;\n        } else if (meridiem === 'बिहान') {\n            return hour;\n        } else if (meridiem === 'दिउँसो') {\n            return hour >= 10 ? hour : hour + 12;\n        } else if (meridiem === 'साँझ') {\n            return hour + 12;\n        }\n    },\n    meridiem : function (hour, minute, isLower) {\n        if (hour < 3) {\n            return 'राति';\n        } else if (hour < 12) {\n            return 'बिहान';\n        } else if (hour < 16) {\n            return 'दिउँसो';\n        } else if (hour < 20) {\n            return 'साँझ';\n        } else {\n            return 'राति';\n        }\n    },\n    calendar : {\n        sameDay : '[आज] LT',\n        nextDay : '[भोलि] LT',\n        nextWeek : '[आउँदो] dddd[,] LT',\n        lastDay : '[हिजो] LT',\n        lastWeek : '[गएको] dddd[,] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : '%sमा',\n        past : '%s अगाडि',\n        s : 'केही क्षण',\n        m : 'एक मिनेट',\n        mm : '%d मिनेट',\n        h : 'एक घण्टा',\n        hh : '%d घण्टा',\n        d : 'एक दिन',\n        dd : '%d दिन',\n        M : 'एक महिना',\n        MM : '%d महिना',\n        y : 'एक बर्ष',\n        yy : '%d बर्ष'\n    },\n    week : {\n        dow : 0, // Sunday is the first day of the week.\n        doy : 6  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/locale/nl-be.js",
    "content": "//! moment.js locale configuration\n//! locale : Dutch (Belgium) [nl-be]\n//! author : Joris Röling : https://github.com/jorisroling\n//! author : Jacob Middag : https://github.com/middagj\n\nimport moment from '../moment';\n\nvar monthsShortWithDots = 'jan._feb._mrt._apr._mei_jun._jul._aug._sep._okt._nov._dec.'.split('_'),\n    monthsShortWithoutDots = 'jan_feb_mrt_apr_mei_jun_jul_aug_sep_okt_nov_dec'.split('_');\n\nvar monthsParse = [/^jan/i, /^feb/i, /^maart|mrt.?$/i, /^apr/i, /^mei$/i, /^jun[i.]?$/i, /^jul[i.]?$/i, /^aug/i, /^sep/i, /^okt/i, /^nov/i, /^dec/i];\nvar monthsRegex = /^(januari|februari|maart|april|mei|april|ju[nl]i|augustus|september|oktober|november|december|jan\\.?|feb\\.?|mrt\\.?|apr\\.?|ju[nl]\\.?|aug\\.?|sep\\.?|okt\\.?|nov\\.?|dec\\.?)/i;\n\nexport default moment.defineLocale('nl-be', {\n    months : 'januari_februari_maart_april_mei_juni_juli_augustus_september_oktober_november_december'.split('_'),\n    monthsShort : function (m, format) {\n        if (!m) {\n            return monthsShortWithDots;\n        } else if (/-MMM-/.test(format)) {\n            return monthsShortWithoutDots[m.month()];\n        } else {\n            return monthsShortWithDots[m.month()];\n        }\n    },\n\n    monthsRegex: monthsRegex,\n    monthsShortRegex: monthsRegex,\n    monthsStrictRegex: /^(januari|februari|maart|mei|ju[nl]i|april|augustus|september|oktober|november|december)/i,\n    monthsShortStrictRegex: /^(jan\\.?|feb\\.?|mrt\\.?|apr\\.?|mei|ju[nl]\\.?|aug\\.?|sep\\.?|okt\\.?|nov\\.?|dec\\.?)/i,\n\n    monthsParse : monthsParse,\n    longMonthsParse : monthsParse,\n    shortMonthsParse : monthsParse,\n\n    weekdays : 'zondag_maandag_dinsdag_woensdag_donderdag_vrijdag_zaterdag'.split('_'),\n    weekdaysShort : 'zo._ma._di._wo._do._vr._za.'.split('_'),\n    weekdaysMin : 'Zo_Ma_Di_Wo_Do_Vr_Za'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY HH:mm',\n        LLLL : 'dddd D MMMM YYYY HH:mm'\n    },\n    calendar : {\n        sameDay: '[vandaag om] LT',\n        nextDay: '[morgen om] LT',\n        nextWeek: 'dddd [om] LT',\n        lastDay: '[gisteren om] LT',\n        lastWeek: '[afgelopen] dddd [om] LT',\n        sameElse: 'L'\n    },\n    relativeTime : {\n        future : 'over %s',\n        past : '%s geleden',\n        s : 'een paar seconden',\n        m : 'één minuut',\n        mm : '%d minuten',\n        h : 'één uur',\n        hh : '%d uur',\n        d : 'één dag',\n        dd : '%d dagen',\n        M : 'één maand',\n        MM : '%d maanden',\n        y : 'één jaar',\n        yy : '%d jaar'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}(ste|de)/,\n    ordinal : function (number) {\n        return number + ((number === 1 || number === 8 || number >= 20) ? 'ste' : 'de');\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/locale/nl.js",
    "content": "//! moment.js locale configuration\n//! locale : Dutch [nl]\n//! author : Joris Röling : https://github.com/jorisroling\n//! author : Jacob Middag : https://github.com/middagj\n\nimport moment from '../moment';\n\nvar monthsShortWithDots = 'jan._feb._mrt._apr._mei_jun._jul._aug._sep._okt._nov._dec.'.split('_'),\n    monthsShortWithoutDots = 'jan_feb_mrt_apr_mei_jun_jul_aug_sep_okt_nov_dec'.split('_');\n\nvar monthsParse = [/^jan/i, /^feb/i, /^maart|mrt.?$/i, /^apr/i, /^mei$/i, /^jun[i.]?$/i, /^jul[i.]?$/i, /^aug/i, /^sep/i, /^okt/i, /^nov/i, /^dec/i];\nvar monthsRegex = /^(januari|februari|maart|april|mei|april|ju[nl]i|augustus|september|oktober|november|december|jan\\.?|feb\\.?|mrt\\.?|apr\\.?|ju[nl]\\.?|aug\\.?|sep\\.?|okt\\.?|nov\\.?|dec\\.?)/i;\n\nexport default moment.defineLocale('nl', {\n    months : 'januari_februari_maart_april_mei_juni_juli_augustus_september_oktober_november_december'.split('_'),\n    monthsShort : function (m, format) {\n        if (!m) {\n            return monthsShortWithDots;\n        } else if (/-MMM-/.test(format)) {\n            return monthsShortWithoutDots[m.month()];\n        } else {\n            return monthsShortWithDots[m.month()];\n        }\n    },\n\n    monthsRegex: monthsRegex,\n    monthsShortRegex: monthsRegex,\n    monthsStrictRegex: /^(januari|februari|maart|mei|ju[nl]i|april|augustus|september|oktober|november|december)/i,\n    monthsShortStrictRegex: /^(jan\\.?|feb\\.?|mrt\\.?|apr\\.?|mei|ju[nl]\\.?|aug\\.?|sep\\.?|okt\\.?|nov\\.?|dec\\.?)/i,\n\n    monthsParse : monthsParse,\n    longMonthsParse : monthsParse,\n    shortMonthsParse : monthsParse,\n\n    weekdays : 'zondag_maandag_dinsdag_woensdag_donderdag_vrijdag_zaterdag'.split('_'),\n    weekdaysShort : 'zo._ma._di._wo._do._vr._za.'.split('_'),\n    weekdaysMin : 'Zo_Ma_Di_Wo_Do_Vr_Za'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD-MM-YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY HH:mm',\n        LLLL : 'dddd D MMMM YYYY HH:mm'\n    },\n    calendar : {\n        sameDay: '[vandaag om] LT',\n        nextDay: '[morgen om] LT',\n        nextWeek: 'dddd [om] LT',\n        lastDay: '[gisteren om] LT',\n        lastWeek: '[afgelopen] dddd [om] LT',\n        sameElse: 'L'\n    },\n    relativeTime : {\n        future : 'over %s',\n        past : '%s geleden',\n        s : 'een paar seconden',\n        m : 'één minuut',\n        mm : '%d minuten',\n        h : 'één uur',\n        hh : '%d uur',\n        d : 'één dag',\n        dd : '%d dagen',\n        M : 'één maand',\n        MM : '%d maanden',\n        y : 'één jaar',\n        yy : '%d jaar'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}(ste|de)/,\n    ordinal : function (number) {\n        return number + ((number === 1 || number === 8 || number >= 20) ? 'ste' : 'de');\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/locale/nn.js",
    "content": "//! moment.js locale configuration\n//! locale : Nynorsk [nn]\n//! author : https://github.com/mechuwind\n\nimport moment from '../moment';\n\nexport default moment.defineLocale('nn', {\n    months : 'januar_februar_mars_april_mai_juni_juli_august_september_oktober_november_desember'.split('_'),\n    monthsShort : 'jan_feb_mar_apr_mai_jun_jul_aug_sep_okt_nov_des'.split('_'),\n    weekdays : 'sundag_måndag_tysdag_onsdag_torsdag_fredag_laurdag'.split('_'),\n    weekdaysShort : 'sun_mån_tys_ons_tor_fre_lau'.split('_'),\n    weekdaysMin : 'su_må_ty_on_to_fr_lø'.split('_'),\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD.MM.YYYY',\n        LL : 'D. MMMM YYYY',\n        LLL : 'D. MMMM YYYY [kl.] H:mm',\n        LLLL : 'dddd D. MMMM YYYY [kl.] HH:mm'\n    },\n    calendar : {\n        sameDay: '[I dag klokka] LT',\n        nextDay: '[I morgon klokka] LT',\n        nextWeek: 'dddd [klokka] LT',\n        lastDay: '[I går klokka] LT',\n        lastWeek: '[Føregåande] dddd [klokka] LT',\n        sameElse: 'L'\n    },\n    relativeTime : {\n        future : 'om %s',\n        past : '%s sidan',\n        s : 'nokre sekund',\n        m : 'eit minutt',\n        mm : '%d minutt',\n        h : 'ein time',\n        hh : '%d timar',\n        d : 'ein dag',\n        dd : '%d dagar',\n        M : 'ein månad',\n        MM : '%d månader',\n        y : 'eit år',\n        yy : '%d år'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}\\./,\n    ordinal : '%d.',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/locale/pa-in.js",
    "content": "//! moment.js locale configuration\n//! locale : Punjabi (India) [pa-in]\n//! author : Harpreet Singh : https://github.com/harpreetkhalsagtbit\n\nimport moment from '../moment';\n\nvar symbolMap = {\n    '1': '੧',\n    '2': '੨',\n    '3': '੩',\n    '4': '੪',\n    '5': '੫',\n    '6': '੬',\n    '7': '੭',\n    '8': '੮',\n    '9': '੯',\n    '0': '੦'\n},\nnumberMap = {\n    '੧': '1',\n    '੨': '2',\n    '੩': '3',\n    '੪': '4',\n    '੫': '5',\n    '੬': '6',\n    '੭': '7',\n    '੮': '8',\n    '੯': '9',\n    '੦': '0'\n};\n\nexport default moment.defineLocale('pa-in', {\n    // There are months name as per Nanakshahi Calender but they are not used as rigidly in modern Punjabi.\n    months : 'ਜਨਵਰੀ_ਫ਼ਰਵਰੀ_ਮਾਰਚ_ਅਪ੍ਰੈਲ_ਮਈ_ਜੂਨ_ਜੁਲਾਈ_ਅਗਸਤ_ਸਤੰਬਰ_ਅਕਤੂਬਰ_ਨਵੰਬਰ_ਦਸੰਬਰ'.split('_'),\n    monthsShort : 'ਜਨਵਰੀ_ਫ਼ਰਵਰੀ_ਮਾਰਚ_ਅਪ੍ਰੈਲ_ਮਈ_ਜੂਨ_ਜੁਲਾਈ_ਅਗਸਤ_ਸਤੰਬਰ_ਅਕਤੂਬਰ_ਨਵੰਬਰ_ਦਸੰਬਰ'.split('_'),\n    weekdays : 'ਐਤਵਾਰ_ਸੋਮਵਾਰ_ਮੰਗਲਵਾਰ_ਬੁਧਵਾਰ_ਵੀਰਵਾਰ_ਸ਼ੁੱਕਰਵਾਰ_ਸ਼ਨੀਚਰਵਾਰ'.split('_'),\n    weekdaysShort : 'ਐਤ_ਸੋਮ_ਮੰਗਲ_ਬੁਧ_ਵੀਰ_ਸ਼ੁਕਰ_ਸ਼ਨੀ'.split('_'),\n    weekdaysMin : 'ਐਤ_ਸੋਮ_ਮੰਗਲ_ਬੁਧ_ਵੀਰ_ਸ਼ੁਕਰ_ਸ਼ਨੀ'.split('_'),\n    longDateFormat : {\n        LT : 'A h:mm ਵਜੇ',\n        LTS : 'A h:mm:ss ਵਜੇ',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY, A h:mm ਵਜੇ',\n        LLLL : 'dddd, D MMMM YYYY, A h:mm ਵਜੇ'\n    },\n    calendar : {\n        sameDay : '[ਅਜ] LT',\n        nextDay : '[ਕਲ] LT',\n        nextWeek : 'dddd, LT',\n        lastDay : '[ਕਲ] LT',\n        lastWeek : '[ਪਿਛਲੇ] dddd, LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : '%s ਵਿੱਚ',\n        past : '%s ਪਿਛਲੇ',\n        s : 'ਕੁਝ ਸਕਿੰਟ',\n        m : 'ਇਕ ਮਿੰਟ',\n        mm : '%d ਮਿੰਟ',\n        h : 'ਇੱਕ ਘੰਟਾ',\n        hh : '%d ਘੰਟੇ',\n        d : 'ਇੱਕ ਦਿਨ',\n        dd : '%d ਦਿਨ',\n        M : 'ਇੱਕ ਮਹੀਨਾ',\n        MM : '%d ਮਹੀਨੇ',\n        y : 'ਇੱਕ ਸਾਲ',\n        yy : '%d ਸਾਲ'\n    },\n    preparse: function (string) {\n        return string.replace(/[੧੨੩੪੫੬੭੮੯੦]/g, function (match) {\n            return numberMap[match];\n        });\n    },\n    postformat: function (string) {\n        return string.replace(/\\d/g, function (match) {\n            return symbolMap[match];\n        });\n    },\n    // Punjabi notation for meridiems are quite fuzzy in practice. While there exists\n    // a rigid notion of a 'Pahar' it is not used as rigidly in modern Punjabi.\n    meridiemParse: /ਰਾਤ|ਸਵੇਰ|ਦੁਪਹਿਰ|ਸ਼ਾਮ/,\n    meridiemHour : function (hour, meridiem) {\n        if (hour === 12) {\n            hour = 0;\n        }\n        if (meridiem === 'ਰਾਤ') {\n            return hour < 4 ? hour : hour + 12;\n        } else if (meridiem === 'ਸਵੇਰ') {\n            return hour;\n        } else if (meridiem === 'ਦੁਪਹਿਰ') {\n            return hour >= 10 ? hour : hour + 12;\n        } else if (meridiem === 'ਸ਼ਾਮ') {\n            return hour + 12;\n        }\n    },\n    meridiem : function (hour, minute, isLower) {\n        if (hour < 4) {\n            return 'ਰਾਤ';\n        } else if (hour < 10) {\n            return 'ਸਵੇਰ';\n        } else if (hour < 17) {\n            return 'ਦੁਪਹਿਰ';\n        } else if (hour < 20) {\n            return 'ਸ਼ਾਮ';\n        } else {\n            return 'ਰਾਤ';\n        }\n    },\n    week : {\n        dow : 0, // Sunday is the first day of the week.\n        doy : 6  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/locale/pl.js",
    "content": "//! moment.js locale configuration\n//! locale : Polish [pl]\n//! author : Rafal Hirsz : https://github.com/evoL\n\nimport moment from '../moment';\n\nvar monthsNominative = 'styczeń_luty_marzec_kwiecień_maj_czerwiec_lipiec_sierpień_wrzesień_październik_listopad_grudzień'.split('_'),\n    monthsSubjective = 'stycznia_lutego_marca_kwietnia_maja_czerwca_lipca_sierpnia_września_października_listopada_grudnia'.split('_');\nfunction plural(n) {\n    return (n % 10 < 5) && (n % 10 > 1) && ((~~(n / 10) % 10) !== 1);\n}\nfunction translate(number, withoutSuffix, key) {\n    var result = number + ' ';\n    switch (key) {\n        case 'm':\n            return withoutSuffix ? 'minuta' : 'minutę';\n        case 'mm':\n            return result + (plural(number) ? 'minuty' : 'minut');\n        case 'h':\n            return withoutSuffix  ? 'godzina'  : 'godzinę';\n        case 'hh':\n            return result + (plural(number) ? 'godziny' : 'godzin');\n        case 'MM':\n            return result + (plural(number) ? 'miesiące' : 'miesięcy');\n        case 'yy':\n            return result + (plural(number) ? 'lata' : 'lat');\n    }\n}\n\nexport default moment.defineLocale('pl', {\n    months : function (momentToFormat, format) {\n        if (!momentToFormat) {\n            return monthsNominative;\n        } else if (format === '') {\n            // Hack: if format empty we know this is used to generate\n            // RegExp by moment. Give then back both valid forms of months\n            // in RegExp ready format.\n            return '(' + monthsSubjective[momentToFormat.month()] + '|' + monthsNominative[momentToFormat.month()] + ')';\n        } else if (/D MMMM/.test(format)) {\n            return monthsSubjective[momentToFormat.month()];\n        } else {\n            return monthsNominative[momentToFormat.month()];\n        }\n    },\n    monthsShort : 'sty_lut_mar_kwi_maj_cze_lip_sie_wrz_paź_lis_gru'.split('_'),\n    weekdays : 'niedziela_poniedziałek_wtorek_środa_czwartek_piątek_sobota'.split('_'),\n    weekdaysShort : 'ndz_pon_wt_śr_czw_pt_sob'.split('_'),\n    weekdaysMin : 'Nd_Pn_Wt_Śr_Cz_Pt_So'.split('_'),\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD.MM.YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY HH:mm',\n        LLLL : 'dddd, D MMMM YYYY HH:mm'\n    },\n    calendar : {\n        sameDay: '[Dziś o] LT',\n        nextDay: '[Jutro o] LT',\n        nextWeek: '[W] dddd [o] LT',\n        lastDay: '[Wczoraj o] LT',\n        lastWeek: function () {\n            switch (this.day()) {\n                case 0:\n                    return '[W zeszłą niedzielę o] LT';\n                case 3:\n                    return '[W zeszłą środę o] LT';\n                case 6:\n                    return '[W zeszłą sobotę o] LT';\n                default:\n                    return '[W zeszły] dddd [o] LT';\n            }\n        },\n        sameElse: 'L'\n    },\n    relativeTime : {\n        future : 'za %s',\n        past : '%s temu',\n        s : 'kilka sekund',\n        m : translate,\n        mm : translate,\n        h : translate,\n        hh : translate,\n        d : '1 dzień',\n        dd : '%d dni',\n        M : 'miesiąc',\n        MM : translate,\n        y : 'rok',\n        yy : translate\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}\\./,\n    ordinal : '%d.',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/locale/pt-br.js",
    "content": "//! moment.js locale configuration\n//! locale : Portuguese (Brazil) [pt-br]\n//! author : Caio Ribeiro Pereira : https://github.com/caio-ribeiro-pereira\n\nimport moment from '../moment';\n\nexport default moment.defineLocale('pt-br', {\n    months : 'Janeiro_Fevereiro_Março_Abril_Maio_Junho_Julho_Agosto_Setembro_Outubro_Novembro_Dezembro'.split('_'),\n    monthsShort : 'Jan_Fev_Mar_Abr_Mai_Jun_Jul_Ago_Set_Out_Nov_Dez'.split('_'),\n    weekdays : 'Domingo_Segunda-feira_Terça-feira_Quarta-feira_Quinta-feira_Sexta-feira_Sábado'.split('_'),\n    weekdaysShort : 'Dom_Seg_Ter_Qua_Qui_Sex_Sáb'.split('_'),\n    weekdaysMin : 'Do_2ª_3ª_4ª_5ª_6ª_Sá'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D [de] MMMM [de] YYYY',\n        LLL : 'D [de] MMMM [de] YYYY [às] HH:mm',\n        LLLL : 'dddd, D [de] MMMM [de] YYYY [às] HH:mm'\n    },\n    calendar : {\n        sameDay: '[Hoje às] LT',\n        nextDay: '[Amanhã às] LT',\n        nextWeek: 'dddd [às] LT',\n        lastDay: '[Ontem às] LT',\n        lastWeek: function () {\n            return (this.day() === 0 || this.day() === 6) ?\n                '[Último] dddd [às] LT' : // Saturday + Sunday\n                '[Última] dddd [às] LT'; // Monday - Friday\n        },\n        sameElse: 'L'\n    },\n    relativeTime : {\n        future : 'em %s',\n        past : '%s atrás',\n        s : 'poucos segundos',\n        m : 'um minuto',\n        mm : '%d minutos',\n        h : 'uma hora',\n        hh : '%d horas',\n        d : 'um dia',\n        dd : '%d dias',\n        M : 'um mês',\n        MM : '%d meses',\n        y : 'um ano',\n        yy : '%d anos'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}º/,\n    ordinal : '%dº'\n});\n\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/locale/pt.js",
    "content": "//! moment.js locale configuration\n//! locale : Portuguese [pt]\n//! author : Jefferson : https://github.com/jalex79\n\nimport moment from '../moment';\n\nexport default moment.defineLocale('pt', {\n    months : 'Janeiro_Fevereiro_Março_Abril_Maio_Junho_Julho_Agosto_Setembro_Outubro_Novembro_Dezembro'.split('_'),\n    monthsShort : 'Jan_Fev_Mar_Abr_Mai_Jun_Jul_Ago_Set_Out_Nov_Dez'.split('_'),\n    weekdays : 'Domingo_Segunda-Feira_Terça-Feira_Quarta-Feira_Quinta-Feira_Sexta-Feira_Sábado'.split('_'),\n    weekdaysShort : 'Dom_Seg_Ter_Qua_Qui_Sex_Sáb'.split('_'),\n    weekdaysMin : 'Do_2ª_3ª_4ª_5ª_6ª_Sá'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D [de] MMMM [de] YYYY',\n        LLL : 'D [de] MMMM [de] YYYY HH:mm',\n        LLLL : 'dddd, D [de] MMMM [de] YYYY HH:mm'\n    },\n    calendar : {\n        sameDay: '[Hoje às] LT',\n        nextDay: '[Amanhã às] LT',\n        nextWeek: 'dddd [às] LT',\n        lastDay: '[Ontem às] LT',\n        lastWeek: function () {\n            return (this.day() === 0 || this.day() === 6) ?\n                '[Último] dddd [às] LT' : // Saturday + Sunday\n                '[Última] dddd [às] LT'; // Monday - Friday\n        },\n        sameElse: 'L'\n    },\n    relativeTime : {\n        future : 'em %s',\n        past : 'há %s',\n        s : 'segundos',\n        m : 'um minuto',\n        mm : '%d minutos',\n        h : 'uma hora',\n        hh : '%d horas',\n        d : 'um dia',\n        dd : '%d dias',\n        M : 'um mês',\n        MM : '%d meses',\n        y : 'um ano',\n        yy : '%d anos'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}º/,\n    ordinal : '%dº',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/locale/ro.js",
    "content": "//! moment.js locale configuration\n//! locale : Romanian [ro]\n//! author : Vlad Gurdiga : https://github.com/gurdiga\n//! author : Valentin Agachi : https://github.com/avaly\n\nimport moment from '../moment';\n\nfunction relativeTimeWithPlural(number, withoutSuffix, key) {\n    var format = {\n            'mm': 'minute',\n            'hh': 'ore',\n            'dd': 'zile',\n            'MM': 'luni',\n            'yy': 'ani'\n        },\n        separator = ' ';\n    if (number % 100 >= 20 || (number >= 100 && number % 100 === 0)) {\n        separator = ' de ';\n    }\n    return number + separator + format[key];\n}\n\nexport default moment.defineLocale('ro', {\n    months : 'ianuarie_februarie_martie_aprilie_mai_iunie_iulie_august_septembrie_octombrie_noiembrie_decembrie'.split('_'),\n    monthsShort : 'ian._febr._mart._apr._mai_iun._iul._aug._sept._oct._nov._dec.'.split('_'),\n    monthsParseExact: true,\n    weekdays : 'duminică_luni_marți_miercuri_joi_vineri_sâmbătă'.split('_'),\n    weekdaysShort : 'Dum_Lun_Mar_Mie_Joi_Vin_Sâm'.split('_'),\n    weekdaysMin : 'Du_Lu_Ma_Mi_Jo_Vi_Sâ'.split('_'),\n    longDateFormat : {\n        LT : 'H:mm',\n        LTS : 'H:mm:ss',\n        L : 'DD.MM.YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY H:mm',\n        LLLL : 'dddd, D MMMM YYYY H:mm'\n    },\n    calendar : {\n        sameDay: '[azi la] LT',\n        nextDay: '[mâine la] LT',\n        nextWeek: 'dddd [la] LT',\n        lastDay: '[ieri la] LT',\n        lastWeek: '[fosta] dddd [la] LT',\n        sameElse: 'L'\n    },\n    relativeTime : {\n        future : 'peste %s',\n        past : '%s în urmă',\n        s : 'câteva secunde',\n        m : 'un minut',\n        mm : relativeTimeWithPlural,\n        h : 'o oră',\n        hh : relativeTimeWithPlural,\n        d : 'o zi',\n        dd : relativeTimeWithPlural,\n        M : 'o lună',\n        MM : relativeTimeWithPlural,\n        y : 'un an',\n        yy : relativeTimeWithPlural\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 7  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/locale/ru.js",
    "content": "//! moment.js locale configuration\n//! locale : Russian [ru]\n//! author : Viktorminator : https://github.com/Viktorminator\n//! Author : Menelion Elensúle : https://github.com/Oire\n//! author : Коренберг Марк : https://github.com/socketpair\n\nimport moment from '../moment';\n\nfunction plural(word, num) {\n    var forms = word.split('_');\n    return num % 10 === 1 && num % 100 !== 11 ? forms[0] : (num % 10 >= 2 && num % 10 <= 4 && (num % 100 < 10 || num % 100 >= 20) ? forms[1] : forms[2]);\n}\nfunction relativeTimeWithPlural(number, withoutSuffix, key) {\n    var format = {\n        'mm': withoutSuffix ? 'минута_минуты_минут' : 'минуту_минуты_минут',\n        'hh': 'час_часа_часов',\n        'dd': 'день_дня_дней',\n        'MM': 'месяц_месяца_месяцев',\n        'yy': 'год_года_лет'\n    };\n    if (key === 'm') {\n        return withoutSuffix ? 'минута' : 'минуту';\n    }\n    else {\n        return number + ' ' + plural(format[key], +number);\n    }\n}\nvar monthsParse = [/^янв/i, /^фев/i, /^мар/i, /^апр/i, /^ма[йя]/i, /^июн/i, /^июл/i, /^авг/i, /^сен/i, /^окт/i, /^ноя/i, /^дек/i];\n\n// http://new.gramota.ru/spravka/rules/139-prop : § 103\n// Сокращения месяцев: http://new.gramota.ru/spravka/buro/search-answer?s=242637\n// CLDR data:          http://www.unicode.org/cldr/charts/28/summary/ru.html#1753\nexport default moment.defineLocale('ru', {\n    months : {\n        format: 'января_февраля_марта_апреля_мая_июня_июля_августа_сентября_октября_ноября_декабря'.split('_'),\n        standalone: 'январь_февраль_март_апрель_май_июнь_июль_август_сентябрь_октябрь_ноябрь_декабрь'.split('_')\n    },\n    monthsShort : {\n        // по CLDR именно \"июл.\" и \"июн.\", но какой смысл менять букву на точку ?\n        format: 'янв._февр._мар._апр._мая_июня_июля_авг._сент._окт._нояб._дек.'.split('_'),\n        standalone: 'янв._февр._март_апр._май_июнь_июль_авг._сент._окт._нояб._дек.'.split('_')\n    },\n    weekdays : {\n        standalone: 'воскресенье_понедельник_вторник_среда_четверг_пятница_суббота'.split('_'),\n        format: 'воскресенье_понедельник_вторник_среду_четверг_пятницу_субботу'.split('_'),\n        isFormat: /\\[ ?[Вв] ?(?:прошлую|следующую|эту)? ?\\] ?dddd/\n    },\n    weekdaysShort : 'вс_пн_вт_ср_чт_пт_сб'.split('_'),\n    weekdaysMin : 'вс_пн_вт_ср_чт_пт_сб'.split('_'),\n    monthsParse : monthsParse,\n    longMonthsParse : monthsParse,\n    shortMonthsParse : monthsParse,\n\n    // полные названия с падежами, по три буквы, для некоторых, по 4 буквы, сокращения с точкой и без точки\n    monthsRegex: /^(январ[ья]|янв\\.?|феврал[ья]|февр?\\.?|марта?|мар\\.?|апрел[ья]|апр\\.?|ма[йя]|июн[ья]|июн\\.?|июл[ья]|июл\\.?|августа?|авг\\.?|сентябр[ья]|сент?\\.?|октябр[ья]|окт\\.?|ноябр[ья]|нояб?\\.?|декабр[ья]|дек\\.?)/i,\n\n    // копия предыдущего\n    monthsShortRegex: /^(январ[ья]|янв\\.?|феврал[ья]|февр?\\.?|марта?|мар\\.?|апрел[ья]|апр\\.?|ма[йя]|июн[ья]|июн\\.?|июл[ья]|июл\\.?|августа?|авг\\.?|сентябр[ья]|сент?\\.?|октябр[ья]|окт\\.?|ноябр[ья]|нояб?\\.?|декабр[ья]|дек\\.?)/i,\n\n    // полные названия с падежами\n    monthsStrictRegex: /^(январ[яь]|феврал[яь]|марта?|апрел[яь]|ма[яй]|июн[яь]|июл[яь]|августа?|сентябр[яь]|октябр[яь]|ноябр[яь]|декабр[яь])/i,\n\n    // Выражение, которое соотвествует только сокращённым формам\n    monthsShortStrictRegex: /^(янв\\.|февр?\\.|мар[т.]|апр\\.|ма[яй]|июн[ья.]|июл[ья.]|авг\\.|сент?\\.|окт\\.|нояб?\\.|дек\\.)/i,\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD.MM.YYYY',\n        LL : 'D MMMM YYYY г.',\n        LLL : 'D MMMM YYYY г., HH:mm',\n        LLLL : 'dddd, D MMMM YYYY г., HH:mm'\n    },\n    calendar : {\n        sameDay: '[Сегодня в] LT',\n        nextDay: '[Завтра в] LT',\n        lastDay: '[Вчера в] LT',\n        nextWeek: function (now) {\n            if (now.week() !== this.week()) {\n                switch (this.day()) {\n                    case 0:\n                        return '[В следующее] dddd [в] LT';\n                    case 1:\n                    case 2:\n                    case 4:\n                        return '[В следующий] dddd [в] LT';\n                    case 3:\n                    case 5:\n                    case 6:\n                        return '[В следующую] dddd [в] LT';\n                }\n            } else {\n                if (this.day() === 2) {\n                    return '[Во] dddd [в] LT';\n                } else {\n                    return '[В] dddd [в] LT';\n                }\n            }\n        },\n        lastWeek: function (now) {\n            if (now.week() !== this.week()) {\n                switch (this.day()) {\n                    case 0:\n                        return '[В прошлое] dddd [в] LT';\n                    case 1:\n                    case 2:\n                    case 4:\n                        return '[В прошлый] dddd [в] LT';\n                    case 3:\n                    case 5:\n                    case 6:\n                        return '[В прошлую] dddd [в] LT';\n                }\n            } else {\n                if (this.day() === 2) {\n                    return '[Во] dddd [в] LT';\n                } else {\n                    return '[В] dddd [в] LT';\n                }\n            }\n        },\n        sameElse: 'L'\n    },\n    relativeTime : {\n        future : 'через %s',\n        past : '%s назад',\n        s : 'несколько секунд',\n        m : relativeTimeWithPlural,\n        mm : relativeTimeWithPlural,\n        h : 'час',\n        hh : relativeTimeWithPlural,\n        d : 'день',\n        dd : relativeTimeWithPlural,\n        M : 'месяц',\n        MM : relativeTimeWithPlural,\n        y : 'год',\n        yy : relativeTimeWithPlural\n    },\n    meridiemParse: /ночи|утра|дня|вечера/i,\n    isPM : function (input) {\n        return /^(дня|вечера)$/.test(input);\n    },\n    meridiem : function (hour, minute, isLower) {\n        if (hour < 4) {\n            return 'ночи';\n        } else if (hour < 12) {\n            return 'утра';\n        } else if (hour < 17) {\n            return 'дня';\n        } else {\n            return 'вечера';\n        }\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}-(й|го|я)/,\n    ordinal: function (number, period) {\n        switch (period) {\n            case 'M':\n            case 'd':\n            case 'DDD':\n                return number + '-й';\n            case 'D':\n                return number + '-го';\n            case 'w':\n            case 'W':\n                return number + '-я';\n            default:\n                return number;\n        }\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 7  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/locale/sd.js",
    "content": "//! moment.js locale configuration\n//! locale : Sindhi [sd]\n//! author : Narain Sagar : https://github.com/narainsagar\n\nimport moment from '../moment';\n\nvar months = [\n    'جنوري',\n    'فيبروري',\n    'مارچ',\n    'اپريل',\n    'مئي',\n    'جون',\n    'جولاءِ',\n    'آگسٽ',\n    'سيپٽمبر',\n    'آڪٽوبر',\n    'نومبر',\n    'ڊسمبر'\n];\nvar days = [\n    'آچر',\n    'سومر',\n    'اڱارو',\n    'اربع',\n    'خميس',\n    'جمع',\n    'ڇنڇر'\n];\n\nexport default moment.defineLocale('sd', {\n    months : months,\n    monthsShort : months,\n    weekdays : days,\n    weekdaysShort : days,\n    weekdaysMin : days,\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY HH:mm',\n        LLLL : 'dddd، D MMMM YYYY HH:mm'\n    },\n    meridiemParse: /صبح|شام/,\n    isPM : function (input) {\n        return 'شام' === input;\n    },\n    meridiem : function (hour, minute, isLower) {\n        if (hour < 12) {\n            return 'صبح';\n        }\n        return 'شام';\n    },\n    calendar : {\n        sameDay : '[اڄ] LT',\n        nextDay : '[سڀاڻي] LT',\n        nextWeek : 'dddd [اڳين هفتي تي] LT',\n        lastDay : '[ڪالهه] LT',\n        lastWeek : '[گزريل هفتي] dddd [تي] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : '%s پوء',\n        past : '%s اڳ',\n        s : 'چند سيڪنڊ',\n        m : 'هڪ منٽ',\n        mm : '%d منٽ',\n        h : 'هڪ ڪلاڪ',\n        hh : '%d ڪلاڪ',\n        d : 'هڪ ڏينهن',\n        dd : '%d ڏينهن',\n        M : 'هڪ مهينو',\n        MM : '%d مهينا',\n        y : 'هڪ سال',\n        yy : '%d سال'\n    },\n    preparse: function (string) {\n        return string.replace(/،/g, ',');\n    },\n    postformat: function (string) {\n        return string.replace(/,/g, '،');\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/locale/se.js",
    "content": "//! moment.js locale configuration\n//! locale : Northern Sami [se]\n//! authors : Bård Rolstad Henriksen : https://github.com/karamell\n\n\nimport moment from '../moment';\n\nexport default moment.defineLocale('se', {\n    months : 'ođđajagemánnu_guovvamánnu_njukčamánnu_cuoŋománnu_miessemánnu_geassemánnu_suoidnemánnu_borgemánnu_čakčamánnu_golggotmánnu_skábmamánnu_juovlamánnu'.split('_'),\n    monthsShort : 'ođđj_guov_njuk_cuo_mies_geas_suoi_borg_čakč_golg_skáb_juov'.split('_'),\n    weekdays : 'sotnabeaivi_vuossárga_maŋŋebárga_gaskavahkku_duorastat_bearjadat_lávvardat'.split('_'),\n    weekdaysShort : 'sotn_vuos_maŋ_gask_duor_bear_láv'.split('_'),\n    weekdaysMin : 's_v_m_g_d_b_L'.split('_'),\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD.MM.YYYY',\n        LL : 'MMMM D. [b.] YYYY',\n        LLL : 'MMMM D. [b.] YYYY [ti.] HH:mm',\n        LLLL : 'dddd, MMMM D. [b.] YYYY [ti.] HH:mm'\n    },\n    calendar : {\n        sameDay: '[otne ti] LT',\n        nextDay: '[ihttin ti] LT',\n        nextWeek: 'dddd [ti] LT',\n        lastDay: '[ikte ti] LT',\n        lastWeek: '[ovddit] dddd [ti] LT',\n        sameElse: 'L'\n    },\n    relativeTime : {\n        future : '%s geažes',\n        past : 'maŋit %s',\n        s : 'moadde sekunddat',\n        m : 'okta minuhta',\n        mm : '%d minuhtat',\n        h : 'okta diimmu',\n        hh : '%d diimmut',\n        d : 'okta beaivi',\n        dd : '%d beaivvit',\n        M : 'okta mánnu',\n        MM : '%d mánut',\n        y : 'okta jahki',\n        yy : '%d jagit'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}\\./,\n    ordinal : '%d.',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/locale/si.js",
    "content": "//! moment.js locale configuration\n//! locale : Sinhalese [si]\n//! author : Sampath Sitinamaluwa : https://github.com/sampathsris\n\nimport moment from '../moment';\n\n/*jshint -W100*/\nexport default moment.defineLocale('si', {\n    months : 'ජනවාරි_පෙබරවාරි_මාර්තු_අප්‍රේල්_මැයි_ජූනි_ජූලි_අගෝස්තු_සැප්තැම්බර්_ඔක්තෝබර්_නොවැම්බර්_දෙසැම්බර්'.split('_'),\n    monthsShort : 'ජන_පෙබ_මාර්_අප්_මැයි_ජූනි_ජූලි_අගෝ_සැප්_ඔක්_නොවැ_දෙසැ'.split('_'),\n    weekdays : 'ඉරිදා_සඳුදා_අඟහරුවාදා_බදාදා_බ්‍රහස්පතින්දා_සිකුරාදා_සෙනසුරාදා'.split('_'),\n    weekdaysShort : 'ඉරි_සඳු_අඟ_බදා_බ්‍රහ_සිකු_සෙන'.split('_'),\n    weekdaysMin : 'ඉ_ස_අ_බ_බ්‍ර_සි_සෙ'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat : {\n        LT : 'a h:mm',\n        LTS : 'a h:mm:ss',\n        L : 'YYYY/MM/DD',\n        LL : 'YYYY MMMM D',\n        LLL : 'YYYY MMMM D, a h:mm',\n        LLLL : 'YYYY MMMM D [වැනි] dddd, a h:mm:ss'\n    },\n    calendar : {\n        sameDay : '[අද] LT[ට]',\n        nextDay : '[හෙට] LT[ට]',\n        nextWeek : 'dddd LT[ට]',\n        lastDay : '[ඊයේ] LT[ට]',\n        lastWeek : '[පසුගිය] dddd LT[ට]',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : '%sකින්',\n        past : '%sකට පෙර',\n        s : 'තත්පර කිහිපය',\n        m : 'මිනිත්තුව',\n        mm : 'මිනිත්තු %d',\n        h : 'පැය',\n        hh : 'පැය %d',\n        d : 'දිනය',\n        dd : 'දින %d',\n        M : 'මාසය',\n        MM : 'මාස %d',\n        y : 'වසර',\n        yy : 'වසර %d'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2} වැනි/,\n    ordinal : function (number) {\n        return number + ' වැනි';\n    },\n    meridiemParse : /පෙර වරු|පස් වරු|පෙ.ව|ප.ව./,\n    isPM : function (input) {\n        return input === 'ප.ව.' || input === 'පස් වරු';\n    },\n    meridiem : function (hours, minutes, isLower) {\n        if (hours > 11) {\n            return isLower ? 'ප.ව.' : 'පස් වරු';\n        } else {\n            return isLower ? 'පෙ.ව.' : 'පෙර වරු';\n        }\n    }\n});\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/locale/sk.js",
    "content": "//! moment.js locale configuration\n//! locale : Slovak [sk]\n//! author : Martin Minka : https://github.com/k2s\n//! based on work of petrbela : https://github.com/petrbela\n\nimport moment from '../moment';\n\nvar months = 'január_február_marec_apríl_máj_jún_júl_august_september_október_november_december'.split('_'),\n    monthsShort = 'jan_feb_mar_apr_máj_jún_júl_aug_sep_okt_nov_dec'.split('_');\nfunction plural(n) {\n    return (n > 1) && (n < 5);\n}\nfunction translate(number, withoutSuffix, key, isFuture) {\n    var result = number + ' ';\n    switch (key) {\n        case 's':  // a few seconds / in a few seconds / a few seconds ago\n            return (withoutSuffix || isFuture) ? 'pár sekúnd' : 'pár sekundami';\n        case 'm':  // a minute / in a minute / a minute ago\n            return withoutSuffix ? 'minúta' : (isFuture ? 'minútu' : 'minútou');\n        case 'mm': // 9 minutes / in 9 minutes / 9 minutes ago\n            if (withoutSuffix || isFuture) {\n                return result + (plural(number) ? 'minúty' : 'minút');\n            } else {\n                return result + 'minútami';\n            }\n            break;\n        case 'h':  // an hour / in an hour / an hour ago\n            return withoutSuffix ? 'hodina' : (isFuture ? 'hodinu' : 'hodinou');\n        case 'hh': // 9 hours / in 9 hours / 9 hours ago\n            if (withoutSuffix || isFuture) {\n                return result + (plural(number) ? 'hodiny' : 'hodín');\n            } else {\n                return result + 'hodinami';\n            }\n            break;\n        case 'd':  // a day / in a day / a day ago\n            return (withoutSuffix || isFuture) ? 'deň' : 'dňom';\n        case 'dd': // 9 days / in 9 days / 9 days ago\n            if (withoutSuffix || isFuture) {\n                return result + (plural(number) ? 'dni' : 'dní');\n            } else {\n                return result + 'dňami';\n            }\n            break;\n        case 'M':  // a month / in a month / a month ago\n            return (withoutSuffix || isFuture) ? 'mesiac' : 'mesiacom';\n        case 'MM': // 9 months / in 9 months / 9 months ago\n            if (withoutSuffix || isFuture) {\n                return result + (plural(number) ? 'mesiace' : 'mesiacov');\n            } else {\n                return result + 'mesiacmi';\n            }\n            break;\n        case 'y':  // a year / in a year / a year ago\n            return (withoutSuffix || isFuture) ? 'rok' : 'rokom';\n        case 'yy': // 9 years / in 9 years / 9 years ago\n            if (withoutSuffix || isFuture) {\n                return result + (plural(number) ? 'roky' : 'rokov');\n            } else {\n                return result + 'rokmi';\n            }\n            break;\n    }\n}\n\nexport default moment.defineLocale('sk', {\n    months : months,\n    monthsShort : monthsShort,\n    weekdays : 'nedeľa_pondelok_utorok_streda_štvrtok_piatok_sobota'.split('_'),\n    weekdaysShort : 'ne_po_ut_st_št_pi_so'.split('_'),\n    weekdaysMin : 'ne_po_ut_st_št_pi_so'.split('_'),\n    longDateFormat : {\n        LT: 'H:mm',\n        LTS : 'H:mm:ss',\n        L : 'DD.MM.YYYY',\n        LL : 'D. MMMM YYYY',\n        LLL : 'D. MMMM YYYY H:mm',\n        LLLL : 'dddd D. MMMM YYYY H:mm'\n    },\n    calendar : {\n        sameDay: '[dnes o] LT',\n        nextDay: '[zajtra o] LT',\n        nextWeek: function () {\n            switch (this.day()) {\n                case 0:\n                    return '[v nedeľu o] LT';\n                case 1:\n                case 2:\n                    return '[v] dddd [o] LT';\n                case 3:\n                    return '[v stredu o] LT';\n                case 4:\n                    return '[vo štvrtok o] LT';\n                case 5:\n                    return '[v piatok o] LT';\n                case 6:\n                    return '[v sobotu o] LT';\n            }\n        },\n        lastDay: '[včera o] LT',\n        lastWeek: function () {\n            switch (this.day()) {\n                case 0:\n                    return '[minulú nedeľu o] LT';\n                case 1:\n                case 2:\n                    return '[minulý] dddd [o] LT';\n                case 3:\n                    return '[minulú stredu o] LT';\n                case 4:\n                case 5:\n                    return '[minulý] dddd [o] LT';\n                case 6:\n                    return '[minulú sobotu o] LT';\n            }\n        },\n        sameElse: 'L'\n    },\n    relativeTime : {\n        future : 'za %s',\n        past : 'pred %s',\n        s : translate,\n        m : translate,\n        mm : translate,\n        h : translate,\n        hh : translate,\n        d : translate,\n        dd : translate,\n        M : translate,\n        MM : translate,\n        y : translate,\n        yy : translate\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}\\./,\n    ordinal : '%d.',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/locale/sl.js",
    "content": "//! moment.js locale configuration\n//! locale : Slovenian [sl]\n//! author : Robert Sedovšek : https://github.com/sedovsek\n\nimport moment from '../moment';\n\nfunction processRelativeTime(number, withoutSuffix, key, isFuture) {\n    var result = number + ' ';\n    switch (key) {\n        case 's':\n            return withoutSuffix || isFuture ? 'nekaj sekund' : 'nekaj sekundami';\n        case 'm':\n            return withoutSuffix ? 'ena minuta' : 'eno minuto';\n        case 'mm':\n            if (number === 1) {\n                result += withoutSuffix ? 'minuta' : 'minuto';\n            } else if (number === 2) {\n                result += withoutSuffix || isFuture ? 'minuti' : 'minutama';\n            } else if (number < 5) {\n                result += withoutSuffix || isFuture ? 'minute' : 'minutami';\n            } else {\n                result += withoutSuffix || isFuture ? 'minut' : 'minutami';\n            }\n            return result;\n        case 'h':\n            return withoutSuffix ? 'ena ura' : 'eno uro';\n        case 'hh':\n            if (number === 1) {\n                result += withoutSuffix ? 'ura' : 'uro';\n            } else if (number === 2) {\n                result += withoutSuffix || isFuture ? 'uri' : 'urama';\n            } else if (number < 5) {\n                result += withoutSuffix || isFuture ? 'ure' : 'urami';\n            } else {\n                result += withoutSuffix || isFuture ? 'ur' : 'urami';\n            }\n            return result;\n        case 'd':\n            return withoutSuffix || isFuture ? 'en dan' : 'enim dnem';\n        case 'dd':\n            if (number === 1) {\n                result += withoutSuffix || isFuture ? 'dan' : 'dnem';\n            } else if (number === 2) {\n                result += withoutSuffix || isFuture ? 'dni' : 'dnevoma';\n            } else {\n                result += withoutSuffix || isFuture ? 'dni' : 'dnevi';\n            }\n            return result;\n        case 'M':\n            return withoutSuffix || isFuture ? 'en mesec' : 'enim mesecem';\n        case 'MM':\n            if (number === 1) {\n                result += withoutSuffix || isFuture ? 'mesec' : 'mesecem';\n            } else if (number === 2) {\n                result += withoutSuffix || isFuture ? 'meseca' : 'mesecema';\n            } else if (number < 5) {\n                result += withoutSuffix || isFuture ? 'mesece' : 'meseci';\n            } else {\n                result += withoutSuffix || isFuture ? 'mesecev' : 'meseci';\n            }\n            return result;\n        case 'y':\n            return withoutSuffix || isFuture ? 'eno leto' : 'enim letom';\n        case 'yy':\n            if (number === 1) {\n                result += withoutSuffix || isFuture ? 'leto' : 'letom';\n            } else if (number === 2) {\n                result += withoutSuffix || isFuture ? 'leti' : 'letoma';\n            } else if (number < 5) {\n                result += withoutSuffix || isFuture ? 'leta' : 'leti';\n            } else {\n                result += withoutSuffix || isFuture ? 'let' : 'leti';\n            }\n            return result;\n    }\n}\n\nexport default moment.defineLocale('sl', {\n    months : 'januar_februar_marec_april_maj_junij_julij_avgust_september_oktober_november_december'.split('_'),\n    monthsShort : 'jan._feb._mar._apr._maj._jun._jul._avg._sep._okt._nov._dec.'.split('_'),\n    monthsParseExact: true,\n    weekdays : 'nedelja_ponedeljek_torek_sreda_četrtek_petek_sobota'.split('_'),\n    weekdaysShort : 'ned._pon._tor._sre._čet._pet._sob.'.split('_'),\n    weekdaysMin : 'ne_po_to_sr_če_pe_so'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat : {\n        LT : 'H:mm',\n        LTS : 'H:mm:ss',\n        L : 'DD.MM.YYYY',\n        LL : 'D. MMMM YYYY',\n        LLL : 'D. MMMM YYYY H:mm',\n        LLLL : 'dddd, D. MMMM YYYY H:mm'\n    },\n    calendar : {\n        sameDay  : '[danes ob] LT',\n        nextDay  : '[jutri ob] LT',\n\n        nextWeek : function () {\n            switch (this.day()) {\n                case 0:\n                    return '[v] [nedeljo] [ob] LT';\n                case 3:\n                    return '[v] [sredo] [ob] LT';\n                case 6:\n                    return '[v] [soboto] [ob] LT';\n                case 1:\n                case 2:\n                case 4:\n                case 5:\n                    return '[v] dddd [ob] LT';\n            }\n        },\n        lastDay  : '[včeraj ob] LT',\n        lastWeek : function () {\n            switch (this.day()) {\n                case 0:\n                    return '[prejšnjo] [nedeljo] [ob] LT';\n                case 3:\n                    return '[prejšnjo] [sredo] [ob] LT';\n                case 6:\n                    return '[prejšnjo] [soboto] [ob] LT';\n                case 1:\n                case 2:\n                case 4:\n                case 5:\n                    return '[prejšnji] dddd [ob] LT';\n            }\n        },\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'čez %s',\n        past   : 'pred %s',\n        s      : processRelativeTime,\n        m      : processRelativeTime,\n        mm     : processRelativeTime,\n        h      : processRelativeTime,\n        hh     : processRelativeTime,\n        d      : processRelativeTime,\n        dd     : processRelativeTime,\n        M      : processRelativeTime,\n        MM     : processRelativeTime,\n        y      : processRelativeTime,\n        yy     : processRelativeTime\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}\\./,\n    ordinal : '%d.',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 7  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/locale/sq.js",
    "content": "//! moment.js locale configuration\n//! locale : Albanian [sq]\n//! author : Flakërim Ismani : https://github.com/flakerimi\n//! author : Menelion Elensúle : https://github.com/Oire\n//! author : Oerd Cukalla : https://github.com/oerd\n\nimport moment from '../moment';\n\nexport default moment.defineLocale('sq', {\n    months : 'Janar_Shkurt_Mars_Prill_Maj_Qershor_Korrik_Gusht_Shtator_Tetor_Nëntor_Dhjetor'.split('_'),\n    monthsShort : 'Jan_Shk_Mar_Pri_Maj_Qer_Kor_Gus_Sht_Tet_Nën_Dhj'.split('_'),\n    weekdays : 'E Diel_E Hënë_E Martë_E Mërkurë_E Enjte_E Premte_E Shtunë'.split('_'),\n    weekdaysShort : 'Die_Hën_Mar_Mër_Enj_Pre_Sht'.split('_'),\n    weekdaysMin : 'D_H_Ma_Më_E_P_Sh'.split('_'),\n    weekdaysParseExact : true,\n    meridiemParse: /PD|MD/,\n    isPM: function (input) {\n        return input.charAt(0) === 'M';\n    },\n    meridiem : function (hours, minutes, isLower) {\n        return hours < 12 ? 'PD' : 'MD';\n    },\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY HH:mm',\n        LLLL : 'dddd, D MMMM YYYY HH:mm'\n    },\n    calendar : {\n        sameDay : '[Sot në] LT',\n        nextDay : '[Nesër në] LT',\n        nextWeek : 'dddd [në] LT',\n        lastDay : '[Dje në] LT',\n        lastWeek : 'dddd [e kaluar në] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'në %s',\n        past : '%s më parë',\n        s : 'disa sekonda',\n        m : 'një minutë',\n        mm : '%d minuta',\n        h : 'një orë',\n        hh : '%d orë',\n        d : 'një ditë',\n        dd : '%d ditë',\n        M : 'një muaj',\n        MM : '%d muaj',\n        y : 'një vit',\n        yy : '%d vite'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}\\./,\n    ordinal : '%d.',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/locale/sr-cyrl.js",
    "content": "//! moment.js locale configuration\n//! locale : Serbian Cyrillic [sr-cyrl]\n//! author : Milan Janačković<milanjanackovic@gmail.com> : https://github.com/milan-j\n\nimport moment from '../moment';\n\nvar translator = {\n    words: { //Different grammatical cases\n        m: ['један минут', 'једне минуте'],\n        mm: ['минут', 'минуте', 'минута'],\n        h: ['један сат', 'једног сата'],\n        hh: ['сат', 'сата', 'сати'],\n        dd: ['дан', 'дана', 'дана'],\n        MM: ['месец', 'месеца', 'месеци'],\n        yy: ['година', 'године', 'година']\n    },\n    correctGrammaticalCase: function (number, wordKey) {\n        return number === 1 ? wordKey[0] : (number >= 2 && number <= 4 ? wordKey[1] : wordKey[2]);\n    },\n    translate: function (number, withoutSuffix, key) {\n        var wordKey = translator.words[key];\n        if (key.length === 1) {\n            return withoutSuffix ? wordKey[0] : wordKey[1];\n        } else {\n            return number + ' ' + translator.correctGrammaticalCase(number, wordKey);\n        }\n    }\n};\n\nexport default moment.defineLocale('sr-cyrl', {\n    months: 'јануар_фебруар_март_април_мај_јун_јул_август_септембар_октобар_новембар_децембар'.split('_'),\n    monthsShort: 'јан._феб._мар._апр._мај_јун_јул_авг._сеп._окт._нов._дец.'.split('_'),\n    monthsParseExact: true,\n    weekdays: 'недеља_понедељак_уторак_среда_четвртак_петак_субота'.split('_'),\n    weekdaysShort: 'нед._пон._уто._сре._чет._пет._суб.'.split('_'),\n    weekdaysMin: 'не_по_ут_ср_че_пе_су'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat: {\n        LT: 'H:mm',\n        LTS : 'H:mm:ss',\n        L: 'DD.MM.YYYY',\n        LL: 'D. MMMM YYYY',\n        LLL: 'D. MMMM YYYY H:mm',\n        LLLL: 'dddd, D. MMMM YYYY H:mm'\n    },\n    calendar: {\n        sameDay: '[данас у] LT',\n        nextDay: '[сутра у] LT',\n        nextWeek: function () {\n            switch (this.day()) {\n                case 0:\n                    return '[у] [недељу] [у] LT';\n                case 3:\n                    return '[у] [среду] [у] LT';\n                case 6:\n                    return '[у] [суботу] [у] LT';\n                case 1:\n                case 2:\n                case 4:\n                case 5:\n                    return '[у] dddd [у] LT';\n            }\n        },\n        lastDay  : '[јуче у] LT',\n        lastWeek : function () {\n            var lastWeekDays = [\n                '[прошле] [недеље] [у] LT',\n                '[прошлог] [понедељка] [у] LT',\n                '[прошлог] [уторка] [у] LT',\n                '[прошле] [среде] [у] LT',\n                '[прошлог] [четвртка] [у] LT',\n                '[прошлог] [петка] [у] LT',\n                '[прошле] [суботе] [у] LT'\n            ];\n            return lastWeekDays[this.day()];\n        },\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'за %s',\n        past   : 'пре %s',\n        s      : 'неколико секунди',\n        m      : translator.translate,\n        mm     : translator.translate,\n        h      : translator.translate,\n        hh     : translator.translate,\n        d      : 'дан',\n        dd     : translator.translate,\n        M      : 'месец',\n        MM     : translator.translate,\n        y      : 'годину',\n        yy     : translator.translate\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}\\./,\n    ordinal : '%d.',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 7  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/locale/sr.js",
    "content": "//! moment.js locale configuration\n//! locale : Serbian [sr]\n//! author : Milan Janačković<milanjanackovic@gmail.com> : https://github.com/milan-j\n\nimport moment from '../moment';\n\nvar translator = {\n    words: { //Different grammatical cases\n        m: ['jedan minut', 'jedne minute'],\n        mm: ['minut', 'minute', 'minuta'],\n        h: ['jedan sat', 'jednog sata'],\n        hh: ['sat', 'sata', 'sati'],\n        dd: ['dan', 'dana', 'dana'],\n        MM: ['mesec', 'meseca', 'meseci'],\n        yy: ['godina', 'godine', 'godina']\n    },\n    correctGrammaticalCase: function (number, wordKey) {\n        return number === 1 ? wordKey[0] : (number >= 2 && number <= 4 ? wordKey[1] : wordKey[2]);\n    },\n    translate: function (number, withoutSuffix, key) {\n        var wordKey = translator.words[key];\n        if (key.length === 1) {\n            return withoutSuffix ? wordKey[0] : wordKey[1];\n        } else {\n            return number + ' ' + translator.correctGrammaticalCase(number, wordKey);\n        }\n    }\n};\n\nexport default moment.defineLocale('sr', {\n    months: 'januar_februar_mart_april_maj_jun_jul_avgust_septembar_oktobar_novembar_decembar'.split('_'),\n    monthsShort: 'jan._feb._mar._apr._maj_jun_jul_avg._sep._okt._nov._dec.'.split('_'),\n    monthsParseExact: true,\n    weekdays: 'nedelja_ponedeljak_utorak_sreda_četvrtak_petak_subota'.split('_'),\n    weekdaysShort: 'ned._pon._uto._sre._čet._pet._sub.'.split('_'),\n    weekdaysMin: 'ne_po_ut_sr_če_pe_su'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat: {\n        LT: 'H:mm',\n        LTS : 'H:mm:ss',\n        L: 'DD.MM.YYYY',\n        LL: 'D. MMMM YYYY',\n        LLL: 'D. MMMM YYYY H:mm',\n        LLLL: 'dddd, D. MMMM YYYY H:mm'\n    },\n    calendar: {\n        sameDay: '[danas u] LT',\n        nextDay: '[sutra u] LT',\n        nextWeek: function () {\n            switch (this.day()) {\n                case 0:\n                    return '[u] [nedelju] [u] LT';\n                case 3:\n                    return '[u] [sredu] [u] LT';\n                case 6:\n                    return '[u] [subotu] [u] LT';\n                case 1:\n                case 2:\n                case 4:\n                case 5:\n                    return '[u] dddd [u] LT';\n            }\n        },\n        lastDay  : '[juče u] LT',\n        lastWeek : function () {\n            var lastWeekDays = [\n                '[prošle] [nedelje] [u] LT',\n                '[prošlog] [ponedeljka] [u] LT',\n                '[prošlog] [utorka] [u] LT',\n                '[prošle] [srede] [u] LT',\n                '[prošlog] [četvrtka] [u] LT',\n                '[prošlog] [petka] [u] LT',\n                '[prošle] [subote] [u] LT'\n            ];\n            return lastWeekDays[this.day()];\n        },\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'za %s',\n        past   : 'pre %s',\n        s      : 'nekoliko sekundi',\n        m      : translator.translate,\n        mm     : translator.translate,\n        h      : translator.translate,\n        hh     : translator.translate,\n        d      : 'dan',\n        dd     : translator.translate,\n        M      : 'mesec',\n        MM     : translator.translate,\n        y      : 'godinu',\n        yy     : translator.translate\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}\\./,\n    ordinal : '%d.',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 7  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/locale/ss.js",
    "content": "//! moment.js locale configuration\n//! locale : siSwati [ss]\n//! author : Nicolai Davies<mail@nicolai.io> : https://github.com/nicolaidavies\n\n\nimport moment from '../moment';\n\nexport default moment.defineLocale('ss', {\n    months : \"Bhimbidvwane_Indlovana_Indlov'lenkhulu_Mabasa_Inkhwekhweti_Inhlaba_Kholwane_Ingci_Inyoni_Imphala_Lweti_Ingongoni\".split('_'),\n    monthsShort : 'Bhi_Ina_Inu_Mab_Ink_Inh_Kho_Igc_Iny_Imp_Lwe_Igo'.split('_'),\n    weekdays : 'Lisontfo_Umsombuluko_Lesibili_Lesitsatfu_Lesine_Lesihlanu_Umgcibelo'.split('_'),\n    weekdaysShort : 'Lis_Umb_Lsb_Les_Lsi_Lsh_Umg'.split('_'),\n    weekdaysMin : 'Li_Us_Lb_Lt_Ls_Lh_Ug'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat : {\n        LT : 'h:mm A',\n        LTS : 'h:mm:ss A',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY h:mm A',\n        LLLL : 'dddd, D MMMM YYYY h:mm A'\n    },\n    calendar : {\n        sameDay : '[Namuhla nga] LT',\n        nextDay : '[Kusasa nga] LT',\n        nextWeek : 'dddd [nga] LT',\n        lastDay : '[Itolo nga] LT',\n        lastWeek : 'dddd [leliphelile] [nga] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'nga %s',\n        past : 'wenteka nga %s',\n        s : 'emizuzwana lomcane',\n        m : 'umzuzu',\n        mm : '%d emizuzu',\n        h : 'lihora',\n        hh : '%d emahora',\n        d : 'lilanga',\n        dd : '%d emalanga',\n        M : 'inyanga',\n        MM : '%d tinyanga',\n        y : 'umnyaka',\n        yy : '%d iminyaka'\n    },\n    meridiemParse: /ekuseni|emini|entsambama|ebusuku/,\n    meridiem : function (hours, minutes, isLower) {\n        if (hours < 11) {\n            return 'ekuseni';\n        } else if (hours < 15) {\n            return 'emini';\n        } else if (hours < 19) {\n            return 'entsambama';\n        } else {\n            return 'ebusuku';\n        }\n    },\n    meridiemHour : function (hour, meridiem) {\n        if (hour === 12) {\n            hour = 0;\n        }\n        if (meridiem === 'ekuseni') {\n            return hour;\n        } else if (meridiem === 'emini') {\n            return hour >= 11 ? hour : hour + 12;\n        } else if (meridiem === 'entsambama' || meridiem === 'ebusuku') {\n            if (hour === 0) {\n                return 0;\n            }\n            return hour + 12;\n        }\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}/,\n    ordinal : '%d',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/locale/sv.js",
    "content": "//! moment.js locale configuration\n//! locale : Swedish [sv]\n//! author : Jens Alm : https://github.com/ulmus\n\nimport moment from '../moment';\n\nexport default moment.defineLocale('sv', {\n    months : 'januari_februari_mars_april_maj_juni_juli_augusti_september_oktober_november_december'.split('_'),\n    monthsShort : 'jan_feb_mar_apr_maj_jun_jul_aug_sep_okt_nov_dec'.split('_'),\n    weekdays : 'söndag_måndag_tisdag_onsdag_torsdag_fredag_lördag'.split('_'),\n    weekdaysShort : 'sön_mån_tis_ons_tor_fre_lör'.split('_'),\n    weekdaysMin : 'sö_må_ti_on_to_fr_lö'.split('_'),\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'YYYY-MM-DD',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY [kl.] HH:mm',\n        LLLL : 'dddd D MMMM YYYY [kl.] HH:mm',\n        lll : 'D MMM YYYY HH:mm',\n        llll : 'ddd D MMM YYYY HH:mm'\n    },\n    calendar : {\n        sameDay: '[Idag] LT',\n        nextDay: '[Imorgon] LT',\n        lastDay: '[Igår] LT',\n        nextWeek: '[På] dddd LT',\n        lastWeek: '[I] dddd[s] LT',\n        sameElse: 'L'\n    },\n    relativeTime : {\n        future : 'om %s',\n        past : 'för %s sedan',\n        s : 'några sekunder',\n        m : 'en minut',\n        mm : '%d minuter',\n        h : 'en timme',\n        hh : '%d timmar',\n        d : 'en dag',\n        dd : '%d dagar',\n        M : 'en månad',\n        MM : '%d månader',\n        y : 'ett år',\n        yy : '%d år'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}(e|a)/,\n    ordinal : function (number) {\n        var b = number % 10,\n            output = (~~(number % 100 / 10) === 1) ? 'e' :\n            (b === 1) ? 'a' :\n            (b === 2) ? 'a' :\n            (b === 3) ? 'e' : 'e';\n        return number + output;\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/locale/sw.js",
    "content": "//! moment.js locale configuration\n//! locale : Swahili [sw]\n//! author : Fahad Kassim : https://github.com/fadsel\n\nimport moment from '../moment';\n\nexport default moment.defineLocale('sw', {\n    months : 'Januari_Februari_Machi_Aprili_Mei_Juni_Julai_Agosti_Septemba_Oktoba_Novemba_Desemba'.split('_'),\n    monthsShort : 'Jan_Feb_Mac_Apr_Mei_Jun_Jul_Ago_Sep_Okt_Nov_Des'.split('_'),\n    weekdays : 'Jumapili_Jumatatu_Jumanne_Jumatano_Alhamisi_Ijumaa_Jumamosi'.split('_'),\n    weekdaysShort : 'Jpl_Jtat_Jnne_Jtan_Alh_Ijm_Jmos'.split('_'),\n    weekdaysMin : 'J2_J3_J4_J5_Al_Ij_J1'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD.MM.YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY HH:mm',\n        LLLL : 'dddd, D MMMM YYYY HH:mm'\n    },\n    calendar : {\n        sameDay : '[leo saa] LT',\n        nextDay : '[kesho saa] LT',\n        nextWeek : '[wiki ijayo] dddd [saat] LT',\n        lastDay : '[jana] LT',\n        lastWeek : '[wiki iliyopita] dddd [saat] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : '%s baadaye',\n        past : 'tokea %s',\n        s : 'hivi punde',\n        m : 'dakika moja',\n        mm : 'dakika %d',\n        h : 'saa limoja',\n        hh : 'masaa %d',\n        d : 'siku moja',\n        dd : 'masiku %d',\n        M : 'mwezi mmoja',\n        MM : 'miezi %d',\n        y : 'mwaka mmoja',\n        yy : 'miaka %d'\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 7  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/locale/ta.js",
    "content": "//! moment.js locale configuration\n//! locale : Tamil [ta]\n//! author : Arjunkumar Krishnamoorthy : https://github.com/tk120404\n\nimport moment from '../moment';\n\nvar symbolMap = {\n    '1': '௧',\n    '2': '௨',\n    '3': '௩',\n    '4': '௪',\n    '5': '௫',\n    '6': '௬',\n    '7': '௭',\n    '8': '௮',\n    '9': '௯',\n    '0': '௦'\n}, numberMap = {\n    '௧': '1',\n    '௨': '2',\n    '௩': '3',\n    '௪': '4',\n    '௫': '5',\n    '௬': '6',\n    '௭': '7',\n    '௮': '8',\n    '௯': '9',\n    '௦': '0'\n};\n\nexport default moment.defineLocale('ta', {\n    months : 'ஜனவரி_பிப்ரவரி_மார்ச்_ஏப்ரல்_மே_ஜூன்_ஜூலை_ஆகஸ்ட்_செப்டெம்பர்_அக்டோபர்_நவம்பர்_டிசம்பர்'.split('_'),\n    monthsShort : 'ஜனவரி_பிப்ரவரி_மார்ச்_ஏப்ரல்_மே_ஜூன்_ஜூலை_ஆகஸ்ட்_செப்டெம்பர்_அக்டோபர்_நவம்பர்_டிசம்பர்'.split('_'),\n    weekdays : 'ஞாயிற்றுக்கிழமை_திங்கட்கிழமை_செவ்வாய்கிழமை_புதன்கிழமை_வியாழக்கிழமை_வெள்ளிக்கிழமை_சனிக்கிழமை'.split('_'),\n    weekdaysShort : 'ஞாயிறு_திங்கள்_செவ்வாய்_புதன்_வியாழன்_வெள்ளி_சனி'.split('_'),\n    weekdaysMin : 'ஞா_தி_செ_பு_வி_வெ_ச'.split('_'),\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY, HH:mm',\n        LLLL : 'dddd, D MMMM YYYY, HH:mm'\n    },\n    calendar : {\n        sameDay : '[இன்று] LT',\n        nextDay : '[நாளை] LT',\n        nextWeek : 'dddd, LT',\n        lastDay : '[நேற்று] LT',\n        lastWeek : '[கடந்த வாரம்] dddd, LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : '%s இல்',\n        past : '%s முன்',\n        s : 'ஒரு சில விநாடிகள்',\n        m : 'ஒரு நிமிடம்',\n        mm : '%d நிமிடங்கள்',\n        h : 'ஒரு மணி நேரம்',\n        hh : '%d மணி நேரம்',\n        d : 'ஒரு நாள்',\n        dd : '%d நாட்கள்',\n        M : 'ஒரு மாதம்',\n        MM : '%d மாதங்கள்',\n        y : 'ஒரு வருடம்',\n        yy : '%d ஆண்டுகள்'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}வது/,\n    ordinal : function (number) {\n        return number + 'வது';\n    },\n    preparse: function (string) {\n        return string.replace(/[௧௨௩௪௫௬௭௮௯௦]/g, function (match) {\n            return numberMap[match];\n        });\n    },\n    postformat: function (string) {\n        return string.replace(/\\d/g, function (match) {\n            return symbolMap[match];\n        });\n    },\n    // refer http://ta.wikipedia.org/s/1er1\n    meridiemParse: /யாமம்|வைகறை|காலை|நண்பகல்|எற்பாடு|மாலை/,\n    meridiem : function (hour, minute, isLower) {\n        if (hour < 2) {\n            return ' யாமம்';\n        } else if (hour < 6) {\n            return ' வைகறை';  // வைகறை\n        } else if (hour < 10) {\n            return ' காலை'; // காலை\n        } else if (hour < 14) {\n            return ' நண்பகல்'; // நண்பகல்\n        } else if (hour < 18) {\n            return ' எற்பாடு'; // எற்பாடு\n        } else if (hour < 22) {\n            return ' மாலை'; // மாலை\n        } else {\n            return ' யாமம்';\n        }\n    },\n    meridiemHour : function (hour, meridiem) {\n        if (hour === 12) {\n            hour = 0;\n        }\n        if (meridiem === 'யாமம்') {\n            return hour < 2 ? hour : hour + 12;\n        } else if (meridiem === 'வைகறை' || meridiem === 'காலை') {\n            return hour;\n        } else if (meridiem === 'நண்பகல்') {\n            return hour >= 10 ? hour : hour + 12;\n        } else {\n            return hour + 12;\n        }\n    },\n    week : {\n        dow : 0, // Sunday is the first day of the week.\n        doy : 6  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/locale/te.js",
    "content": "//! moment.js locale configuration\n//! locale : Telugu [te]\n//! author : Krishna Chaitanya Thota : https://github.com/kcthota\n\nimport moment from '../moment';\n\nexport default moment.defineLocale('te', {\n    months : 'జనవరి_ఫిబ్రవరి_మార్చి_ఏప్రిల్_మే_జూన్_జూలై_ఆగస్టు_సెప్టెంబర్_అక్టోబర్_నవంబర్_డిసెంబర్'.split('_'),\n    monthsShort : 'జన._ఫిబ్ర._మార్చి_ఏప్రి._మే_జూన్_జూలై_ఆగ._సెప్._అక్టో._నవ._డిసె.'.split('_'),\n    monthsParseExact : true,\n    weekdays : 'ఆదివారం_సోమవారం_మంగళవారం_బుధవారం_గురువారం_శుక్రవారం_శనివారం'.split('_'),\n    weekdaysShort : 'ఆది_సోమ_మంగళ_బుధ_గురు_శుక్ర_శని'.split('_'),\n    weekdaysMin : 'ఆ_సో_మం_బు_గు_శు_శ'.split('_'),\n    longDateFormat : {\n        LT : 'A h:mm',\n        LTS : 'A h:mm:ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY, A h:mm',\n        LLLL : 'dddd, D MMMM YYYY, A h:mm'\n    },\n    calendar : {\n        sameDay : '[నేడు] LT',\n        nextDay : '[రేపు] LT',\n        nextWeek : 'dddd, LT',\n        lastDay : '[నిన్న] LT',\n        lastWeek : '[గత] dddd, LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : '%s లో',\n        past : '%s క్రితం',\n        s : 'కొన్ని క్షణాలు',\n        m : 'ఒక నిమిషం',\n        mm : '%d నిమిషాలు',\n        h : 'ఒక గంట',\n        hh : '%d గంటలు',\n        d : 'ఒక రోజు',\n        dd : '%d రోజులు',\n        M : 'ఒక నెల',\n        MM : '%d నెలలు',\n        y : 'ఒక సంవత్సరం',\n        yy : '%d సంవత్సరాలు'\n    },\n    dayOfMonthOrdinalParse : /\\d{1,2}వ/,\n    ordinal : '%dవ',\n    meridiemParse: /రాత్రి|ఉదయం|మధ్యాహ్నం|సాయంత్రం/,\n    meridiemHour : function (hour, meridiem) {\n        if (hour === 12) {\n            hour = 0;\n        }\n        if (meridiem === 'రాత్రి') {\n            return hour < 4 ? hour : hour + 12;\n        } else if (meridiem === 'ఉదయం') {\n            return hour;\n        } else if (meridiem === 'మధ్యాహ్నం') {\n            return hour >= 10 ? hour : hour + 12;\n        } else if (meridiem === 'సాయంత్రం') {\n            return hour + 12;\n        }\n    },\n    meridiem : function (hour, minute, isLower) {\n        if (hour < 4) {\n            return 'రాత్రి';\n        } else if (hour < 10) {\n            return 'ఉదయం';\n        } else if (hour < 17) {\n            return 'మధ్యాహ్నం';\n        } else if (hour < 20) {\n            return 'సాయంత్రం';\n        } else {\n            return 'రాత్రి';\n        }\n    },\n    week : {\n        dow : 0, // Sunday is the first day of the week.\n        doy : 6  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/locale/tet.js",
    "content": "//! moment.js locale configuration\n//! locale : Tetun Dili (East Timor) [tet]\n//! author : Joshua Brooks : https://github.com/joshbrooks\n//! author : Onorio De J. Afonso : https://github.com/marobo\n\nimport moment from '../moment';\n\nexport default moment.defineLocale('tet', {\n    months : 'Janeiru_Fevereiru_Marsu_Abril_Maiu_Juniu_Juliu_Augustu_Setembru_Outubru_Novembru_Dezembru'.split('_'),\n    monthsShort : 'Jan_Fev_Mar_Abr_Mai_Jun_Jul_Aug_Set_Out_Nov_Dez'.split('_'),\n    weekdays : 'Domingu_Segunda_Tersa_Kuarta_Kinta_Sexta_Sabadu'.split('_'),\n    weekdaysShort : 'Dom_Seg_Ters_Kua_Kint_Sext_Sab'.split('_'),\n    weekdaysMin : 'Do_Seg_Te_Ku_Ki_Sex_Sa'.split('_'),\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY HH:mm',\n        LLLL : 'dddd, D MMMM YYYY HH:mm'\n    },\n    calendar : {\n        sameDay: '[Ohin iha] LT',\n        nextDay: '[Aban iha] LT',\n        nextWeek: 'dddd [iha] LT',\n        lastDay: '[Horiseik iha] LT',\n        lastWeek: 'dddd [semana kotuk] [iha] LT',\n        sameElse: 'L'\n    },\n    relativeTime : {\n        future : 'iha %s',\n        past : '%s liuba',\n        s : 'minutu balun',\n        m : 'minutu ida',\n        mm : 'minutus %d',\n        h : 'horas ida',\n        hh : 'horas %d',\n        d : 'loron ida',\n        dd : 'loron %d',\n        M : 'fulan ida',\n        MM : 'fulan %d',\n        y : 'tinan ida',\n        yy : 'tinan %d'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}(st|nd|rd|th)/,\n    ordinal : function (number) {\n        var b = number % 10,\n            output = (~~(number % 100 / 10) === 1) ? 'th' :\n            (b === 1) ? 'st' :\n            (b === 2) ? 'nd' :\n            (b === 3) ? 'rd' : 'th';\n        return number + output;\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/locale/th.js",
    "content": "//! moment.js locale configuration\n//! locale : Thai [th]\n//! author : Kridsada Thanabulpong : https://github.com/sirn\n\nimport moment from '../moment';\n\nexport default moment.defineLocale('th', {\n    months : 'มกราคม_กุมภาพันธ์_มีนาคม_เมษายน_พฤษภาคม_มิถุนายน_กรกฎาคม_สิงหาคม_กันยายน_ตุลาคม_พฤศจิกายน_ธันวาคม'.split('_'),\n    monthsShort : 'ม.ค._ก.พ._มี.ค._เม.ย._พ.ค._มิ.ย._ก.ค._ส.ค._ก.ย._ต.ค._พ.ย._ธ.ค.'.split('_'),\n    monthsParseExact: true,\n    weekdays : 'อาทิตย์_จันทร์_อังคาร_พุธ_พฤหัสบดี_ศุกร์_เสาร์'.split('_'),\n    weekdaysShort : 'อาทิตย์_จันทร์_อังคาร_พุธ_พฤหัส_ศุกร์_เสาร์'.split('_'), // yes, three characters difference\n    weekdaysMin : 'อา._จ._อ._พ._พฤ._ศ._ส.'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat : {\n        LT : 'H:mm',\n        LTS : 'H:mm:ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY เวลา H:mm',\n        LLLL : 'วันddddที่ D MMMM YYYY เวลา H:mm'\n    },\n    meridiemParse: /ก่อนเที่ยง|หลังเที่ยง/,\n    isPM: function (input) {\n        return input === 'หลังเที่ยง';\n    },\n    meridiem : function (hour, minute, isLower) {\n        if (hour < 12) {\n            return 'ก่อนเที่ยง';\n        } else {\n            return 'หลังเที่ยง';\n        }\n    },\n    calendar : {\n        sameDay : '[วันนี้ เวลา] LT',\n        nextDay : '[พรุ่งนี้ เวลา] LT',\n        nextWeek : 'dddd[หน้า เวลา] LT',\n        lastDay : '[เมื่อวานนี้ เวลา] LT',\n        lastWeek : '[วัน]dddd[ที่แล้ว เวลา] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'อีก %s',\n        past : '%sที่แล้ว',\n        s : 'ไม่กี่วินาที',\n        m : '1 นาที',\n        mm : '%d นาที',\n        h : '1 ชั่วโมง',\n        hh : '%d ชั่วโมง',\n        d : '1 วัน',\n        dd : '%d วัน',\n        M : '1 เดือน',\n        MM : '%d เดือน',\n        y : '1 ปี',\n        yy : '%d ปี'\n    }\n});\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/locale/tl-ph.js",
    "content": "//! moment.js locale configuration\n//! locale : Tagalog (Philippines) [tl-ph]\n//! author : Dan Hagman : https://github.com/hagmandan\n\nimport moment from '../moment';\n\nexport default moment.defineLocale('tl-ph', {\n    months : 'Enero_Pebrero_Marso_Abril_Mayo_Hunyo_Hulyo_Agosto_Setyembre_Oktubre_Nobyembre_Disyembre'.split('_'),\n    monthsShort : 'Ene_Peb_Mar_Abr_May_Hun_Hul_Ago_Set_Okt_Nob_Dis'.split('_'),\n    weekdays : 'Linggo_Lunes_Martes_Miyerkules_Huwebes_Biyernes_Sabado'.split('_'),\n    weekdaysShort : 'Lin_Lun_Mar_Miy_Huw_Biy_Sab'.split('_'),\n    weekdaysMin : 'Li_Lu_Ma_Mi_Hu_Bi_Sab'.split('_'),\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'MM/D/YYYY',\n        LL : 'MMMM D, YYYY',\n        LLL : 'MMMM D, YYYY HH:mm',\n        LLLL : 'dddd, MMMM DD, YYYY HH:mm'\n    },\n    calendar : {\n        sameDay: 'LT [ngayong araw]',\n        nextDay: '[Bukas ng] LT',\n        nextWeek: 'LT [sa susunod na] dddd',\n        lastDay: 'LT [kahapon]',\n        lastWeek: 'LT [noong nakaraang] dddd',\n        sameElse: 'L'\n    },\n    relativeTime : {\n        future : 'sa loob ng %s',\n        past : '%s ang nakalipas',\n        s : 'ilang segundo',\n        m : 'isang minuto',\n        mm : '%d minuto',\n        h : 'isang oras',\n        hh : '%d oras',\n        d : 'isang araw',\n        dd : '%d araw',\n        M : 'isang buwan',\n        MM : '%d buwan',\n        y : 'isang taon',\n        yy : '%d taon'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}/,\n    ordinal : function (number) {\n        return number;\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/locale/tlh.js",
    "content": "//! moment.js locale configuration\n//! locale : Klingon [tlh]\n//! author : Dominika Kruk : https://github.com/amaranthrose\n\nimport moment from '../moment';\n\nvar numbersNouns = 'pagh_wa’_cha’_wej_loS_vagh_jav_Soch_chorgh_Hut'.split('_');\n\nfunction translateFuture(output) {\n    var time = output;\n    time = (output.indexOf('jaj') !== -1) ?\n    time.slice(0, -3) + 'leS' :\n    (output.indexOf('jar') !== -1) ?\n    time.slice(0, -3) + 'waQ' :\n    (output.indexOf('DIS') !== -1) ?\n    time.slice(0, -3) + 'nem' :\n    time + ' pIq';\n    return time;\n}\n\nfunction translatePast(output) {\n    var time = output;\n    time = (output.indexOf('jaj') !== -1) ?\n    time.slice(0, -3) + 'Hu’' :\n    (output.indexOf('jar') !== -1) ?\n    time.slice(0, -3) + 'wen' :\n    (output.indexOf('DIS') !== -1) ?\n    time.slice(0, -3) + 'ben' :\n    time + ' ret';\n    return time;\n}\n\nfunction translate(number, withoutSuffix, string, isFuture) {\n    var numberNoun = numberAsNoun(number);\n    switch (string) {\n        case 'mm':\n            return numberNoun + ' tup';\n        case 'hh':\n            return numberNoun + ' rep';\n        case 'dd':\n            return numberNoun + ' jaj';\n        case 'MM':\n            return numberNoun + ' jar';\n        case 'yy':\n            return numberNoun + ' DIS';\n    }\n}\n\nfunction numberAsNoun(number) {\n    var hundred = Math.floor((number % 1000) / 100),\n    ten = Math.floor((number % 100) / 10),\n    one = number % 10,\n    word = '';\n    if (hundred > 0) {\n        word += numbersNouns[hundred] + 'vatlh';\n    }\n    if (ten > 0) {\n        word += ((word !== '') ? ' ' : '') + numbersNouns[ten] + 'maH';\n    }\n    if (one > 0) {\n        word += ((word !== '') ? ' ' : '') + numbersNouns[one];\n    }\n    return (word === '') ? 'pagh' : word;\n}\n\nexport default moment.defineLocale('tlh', {\n    months : 'tera’ jar wa’_tera’ jar cha’_tera’ jar wej_tera’ jar loS_tera’ jar vagh_tera’ jar jav_tera’ jar Soch_tera’ jar chorgh_tera’ jar Hut_tera’ jar wa’maH_tera’ jar wa’maH wa’_tera’ jar wa’maH cha’'.split('_'),\n    monthsShort : 'jar wa’_jar cha’_jar wej_jar loS_jar vagh_jar jav_jar Soch_jar chorgh_jar Hut_jar wa’maH_jar wa’maH wa’_jar wa’maH cha’'.split('_'),\n    monthsParseExact : true,\n    weekdays : 'lojmItjaj_DaSjaj_povjaj_ghItlhjaj_loghjaj_buqjaj_ghInjaj'.split('_'),\n    weekdaysShort : 'lojmItjaj_DaSjaj_povjaj_ghItlhjaj_loghjaj_buqjaj_ghInjaj'.split('_'),\n    weekdaysMin : 'lojmItjaj_DaSjaj_povjaj_ghItlhjaj_loghjaj_buqjaj_ghInjaj'.split('_'),\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD.MM.YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY HH:mm',\n        LLLL : 'dddd, D MMMM YYYY HH:mm'\n    },\n    calendar : {\n        sameDay: '[DaHjaj] LT',\n        nextDay: '[wa’leS] LT',\n        nextWeek: 'LLL',\n        lastDay: '[wa’Hu’] LT',\n        lastWeek: 'LLL',\n        sameElse: 'L'\n    },\n    relativeTime : {\n        future : translateFuture,\n        past : translatePast,\n        s : 'puS lup',\n        m : 'wa’ tup',\n        mm : translate,\n        h : 'wa’ rep',\n        hh : translate,\n        d : 'wa’ jaj',\n        dd : translate,\n        M : 'wa’ jar',\n        MM : translate,\n        y : 'wa’ DIS',\n        yy : translate\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}\\./,\n    ordinal : '%d.',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/locale/tr.js",
    "content": "//! moment.js locale configuration\n//! locale : Turkish [tr]\n//! authors : Erhan Gundogan : https://github.com/erhangundogan,\n//!           Burak Yiğit Kaya: https://github.com/BYK\n\nimport moment from '../moment';\n\nvar suffixes = {\n    1: '\\'inci',\n    5: '\\'inci',\n    8: '\\'inci',\n    70: '\\'inci',\n    80: '\\'inci',\n    2: '\\'nci',\n    7: '\\'nci',\n    20: '\\'nci',\n    50: '\\'nci',\n    3: '\\'üncü',\n    4: '\\'üncü',\n    100: '\\'üncü',\n    6: '\\'ncı',\n    9: '\\'uncu',\n    10: '\\'uncu',\n    30: '\\'uncu',\n    60: '\\'ıncı',\n    90: '\\'ıncı'\n};\n\nexport default moment.defineLocale('tr', {\n    months : 'Ocak_Şubat_Mart_Nisan_Mayıs_Haziran_Temmuz_Ağustos_Eylül_Ekim_Kasım_Aralık'.split('_'),\n    monthsShort : 'Oca_Şub_Mar_Nis_May_Haz_Tem_Ağu_Eyl_Eki_Kas_Ara'.split('_'),\n    weekdays : 'Pazar_Pazartesi_Salı_Çarşamba_Perşembe_Cuma_Cumartesi'.split('_'),\n    weekdaysShort : 'Paz_Pts_Sal_Çar_Per_Cum_Cts'.split('_'),\n    weekdaysMin : 'Pz_Pt_Sa_Ça_Pe_Cu_Ct'.split('_'),\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD.MM.YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY HH:mm',\n        LLLL : 'dddd, D MMMM YYYY HH:mm'\n    },\n    calendar : {\n        sameDay : '[bugün saat] LT',\n        nextDay : '[yarın saat] LT',\n        nextWeek : '[haftaya] dddd [saat] LT',\n        lastDay : '[dün] LT',\n        lastWeek : '[geçen hafta] dddd [saat] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : '%s sonra',\n        past : '%s önce',\n        s : 'birkaç saniye',\n        m : 'bir dakika',\n        mm : '%d dakika',\n        h : 'bir saat',\n        hh : '%d saat',\n        d : 'bir gün',\n        dd : '%d gün',\n        M : 'bir ay',\n        MM : '%d ay',\n        y : 'bir yıl',\n        yy : '%d yıl'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}'(inci|nci|üncü|ncı|uncu|ıncı)/,\n    ordinal : function (number) {\n        if (number === 0) {  // special case for zero\n            return number + '\\'ıncı';\n        }\n        var a = number % 10,\n            b = number % 100 - a,\n            c = number >= 100 ? 100 : null;\n        return number + (suffixes[a] || suffixes[b] || suffixes[c]);\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 7  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/locale/tzl.js",
    "content": "//! moment.js locale configuration\n//! locale : Talossan [tzl]\n//! author : Robin van der Vliet : https://github.com/robin0van0der0v\n//! author : Iustì Canun\n\nimport moment from '../moment';\n\n// After the year there should be a slash and the amount of years since December 26, 1979 in Roman numerals.\n// This is currently too difficult (maybe even impossible) to add.\nexport default moment.defineLocale('tzl', {\n    months : 'Januar_Fevraglh_Març_Avrïu_Mai_Gün_Julia_Guscht_Setemvar_Listopäts_Noemvar_Zecemvar'.split('_'),\n    monthsShort : 'Jan_Fev_Mar_Avr_Mai_Gün_Jul_Gus_Set_Lis_Noe_Zec'.split('_'),\n    weekdays : 'Súladi_Lúneçi_Maitzi_Márcuri_Xhúadi_Viénerçi_Sáturi'.split('_'),\n    weekdaysShort : 'Súl_Lún_Mai_Már_Xhú_Vié_Sát'.split('_'),\n    weekdaysMin : 'Sú_Lú_Ma_Má_Xh_Vi_Sá'.split('_'),\n    longDateFormat : {\n        LT : 'HH.mm',\n        LTS : 'HH.mm.ss',\n        L : 'DD.MM.YYYY',\n        LL : 'D. MMMM [dallas] YYYY',\n        LLL : 'D. MMMM [dallas] YYYY HH.mm',\n        LLLL : 'dddd, [li] D. MMMM [dallas] YYYY HH.mm'\n    },\n    meridiemParse: /d\\'o|d\\'a/i,\n    isPM : function (input) {\n        return 'd\\'o' === input.toLowerCase();\n    },\n    meridiem : function (hours, minutes, isLower) {\n        if (hours > 11) {\n            return isLower ? 'd\\'o' : 'D\\'O';\n        } else {\n            return isLower ? 'd\\'a' : 'D\\'A';\n        }\n    },\n    calendar : {\n        sameDay : '[oxhi à] LT',\n        nextDay : '[demà à] LT',\n        nextWeek : 'dddd [à] LT',\n        lastDay : '[ieiri à] LT',\n        lastWeek : '[sür el] dddd [lasteu à] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'osprei %s',\n        past : 'ja%s',\n        s : processRelativeTime,\n        m : processRelativeTime,\n        mm : processRelativeTime,\n        h : processRelativeTime,\n        hh : processRelativeTime,\n        d : processRelativeTime,\n        dd : processRelativeTime,\n        M : processRelativeTime,\n        MM : processRelativeTime,\n        y : processRelativeTime,\n        yy : processRelativeTime\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}\\./,\n    ordinal : '%d.',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\nfunction processRelativeTime(number, withoutSuffix, key, isFuture) {\n    var format = {\n        's': ['viensas secunds', '\\'iensas secunds'],\n        'm': ['\\'n míut', '\\'iens míut'],\n        'mm': [number + ' míuts', '' + number + ' míuts'],\n        'h': ['\\'n þora', '\\'iensa þora'],\n        'hh': [number + ' þoras', '' + number + ' þoras'],\n        'd': ['\\'n ziua', '\\'iensa ziua'],\n        'dd': [number + ' ziuas', '' + number + ' ziuas'],\n        'M': ['\\'n mes', '\\'iens mes'],\n        'MM': [number + ' mesen', '' + number + ' mesen'],\n        'y': ['\\'n ar', '\\'iens ar'],\n        'yy': [number + ' ars', '' + number + ' ars']\n    };\n    return isFuture ? format[key][0] : (withoutSuffix ? format[key][0] : format[key][1]);\n}\n\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/locale/tzm-latn.js",
    "content": "//! moment.js locale configuration\n//! locale : Central Atlas Tamazight Latin [tzm-latn]\n//! author : Abdel Said : https://github.com/abdelsaid\n\nimport moment from '../moment';\n\nexport default moment.defineLocale('tzm-latn', {\n    months : 'innayr_brˤayrˤ_marˤsˤ_ibrir_mayyw_ywnyw_ywlywz_ɣwšt_šwtanbir_ktˤwbrˤ_nwwanbir_dwjnbir'.split('_'),\n    monthsShort : 'innayr_brˤayrˤ_marˤsˤ_ibrir_mayyw_ywnyw_ywlywz_ɣwšt_šwtanbir_ktˤwbrˤ_nwwanbir_dwjnbir'.split('_'),\n    weekdays : 'asamas_aynas_asinas_akras_akwas_asimwas_asiḍyas'.split('_'),\n    weekdaysShort : 'asamas_aynas_asinas_akras_akwas_asimwas_asiḍyas'.split('_'),\n    weekdaysMin : 'asamas_aynas_asinas_akras_akwas_asimwas_asiḍyas'.split('_'),\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY HH:mm',\n        LLLL : 'dddd D MMMM YYYY HH:mm'\n    },\n    calendar : {\n        sameDay: '[asdkh g] LT',\n        nextDay: '[aska g] LT',\n        nextWeek: 'dddd [g] LT',\n        lastDay: '[assant g] LT',\n        lastWeek: 'dddd [g] LT',\n        sameElse: 'L'\n    },\n    relativeTime : {\n        future : 'dadkh s yan %s',\n        past : 'yan %s',\n        s : 'imik',\n        m : 'minuḍ',\n        mm : '%d minuḍ',\n        h : 'saɛa',\n        hh : '%d tassaɛin',\n        d : 'ass',\n        dd : '%d ossan',\n        M : 'ayowr',\n        MM : '%d iyyirn',\n        y : 'asgas',\n        yy : '%d isgasn'\n    },\n    week : {\n        dow : 6, // Saturday is the first day of the week.\n        doy : 12  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/locale/tzm.js",
    "content": "//! moment.js locale configuration\n//! locale : Central Atlas Tamazight [tzm]\n//! author : Abdel Said : https://github.com/abdelsaid\n\nimport moment from '../moment';\n\nexport default moment.defineLocale('tzm', {\n    months : 'ⵉⵏⵏⴰⵢⵔ_ⴱⵕⴰⵢⵕ_ⵎⴰⵕⵚ_ⵉⴱⵔⵉⵔ_ⵎⴰⵢⵢⵓ_ⵢⵓⵏⵢⵓ_ⵢⵓⵍⵢⵓⵣ_ⵖⵓⵛⵜ_ⵛⵓⵜⴰⵏⴱⵉⵔ_ⴽⵟⵓⴱⵕ_ⵏⵓⵡⴰⵏⴱⵉⵔ_ⴷⵓⵊⵏⴱⵉⵔ'.split('_'),\n    monthsShort : 'ⵉⵏⵏⴰⵢⵔ_ⴱⵕⴰⵢⵕ_ⵎⴰⵕⵚ_ⵉⴱⵔⵉⵔ_ⵎⴰⵢⵢⵓ_ⵢⵓⵏⵢⵓ_ⵢⵓⵍⵢⵓⵣ_ⵖⵓⵛⵜ_ⵛⵓⵜⴰⵏⴱⵉⵔ_ⴽⵟⵓⴱⵕ_ⵏⵓⵡⴰⵏⴱⵉⵔ_ⴷⵓⵊⵏⴱⵉⵔ'.split('_'),\n    weekdays : 'ⴰⵙⴰⵎⴰⵙ_ⴰⵢⵏⴰⵙ_ⴰⵙⵉⵏⴰⵙ_ⴰⴽⵔⴰⵙ_ⴰⴽⵡⴰⵙ_ⴰⵙⵉⵎⵡⴰⵙ_ⴰⵙⵉⴹⵢⴰⵙ'.split('_'),\n    weekdaysShort : 'ⴰⵙⴰⵎⴰⵙ_ⴰⵢⵏⴰⵙ_ⴰⵙⵉⵏⴰⵙ_ⴰⴽⵔⴰⵙ_ⴰⴽⵡⴰⵙ_ⴰⵙⵉⵎⵡⴰⵙ_ⴰⵙⵉⴹⵢⴰⵙ'.split('_'),\n    weekdaysMin : 'ⴰⵙⴰⵎⴰⵙ_ⴰⵢⵏⴰⵙ_ⴰⵙⵉⵏⴰⵙ_ⴰⴽⵔⴰⵙ_ⴰⴽⵡⴰⵙ_ⴰⵙⵉⵎⵡⴰⵙ_ⴰⵙⵉⴹⵢⴰⵙ'.split('_'),\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS: 'HH:mm:ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY HH:mm',\n        LLLL : 'dddd D MMMM YYYY HH:mm'\n    },\n    calendar : {\n        sameDay: '[ⴰⵙⴷⵅ ⴴ] LT',\n        nextDay: '[ⴰⵙⴽⴰ ⴴ] LT',\n        nextWeek: 'dddd [ⴴ] LT',\n        lastDay: '[ⴰⵚⴰⵏⵜ ⴴ] LT',\n        lastWeek: 'dddd [ⴴ] LT',\n        sameElse: 'L'\n    },\n    relativeTime : {\n        future : 'ⴷⴰⴷⵅ ⵙ ⵢⴰⵏ %s',\n        past : 'ⵢⴰⵏ %s',\n        s : 'ⵉⵎⵉⴽ',\n        m : 'ⵎⵉⵏⵓⴺ',\n        mm : '%d ⵎⵉⵏⵓⴺ',\n        h : 'ⵙⴰⵄⴰ',\n        hh : '%d ⵜⴰⵙⵙⴰⵄⵉⵏ',\n        d : 'ⴰⵙⵙ',\n        dd : '%d oⵙⵙⴰⵏ',\n        M : 'ⴰⵢoⵓⵔ',\n        MM : '%d ⵉⵢⵢⵉⵔⵏ',\n        y : 'ⴰⵙⴳⴰⵙ',\n        yy : '%d ⵉⵙⴳⴰⵙⵏ'\n    },\n    week : {\n        dow : 6, // Saturday is the first day of the week.\n        doy : 12  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/locale/uk.js",
    "content": "//! moment.js locale configuration\n//! locale : Ukrainian [uk]\n//! author : zemlanin : https://github.com/zemlanin\n//! Author : Menelion Elensúle : https://github.com/Oire\n\nimport moment from '../moment';\n\nfunction plural(word, num) {\n    var forms = word.split('_');\n    return num % 10 === 1 && num % 100 !== 11 ? forms[0] : (num % 10 >= 2 && num % 10 <= 4 && (num % 100 < 10 || num % 100 >= 20) ? forms[1] : forms[2]);\n}\nfunction relativeTimeWithPlural(number, withoutSuffix, key) {\n    var format = {\n        'mm': withoutSuffix ? 'хвилина_хвилини_хвилин' : 'хвилину_хвилини_хвилин',\n        'hh': withoutSuffix ? 'година_години_годин' : 'годину_години_годин',\n        'dd': 'день_дні_днів',\n        'MM': 'місяць_місяці_місяців',\n        'yy': 'рік_роки_років'\n    };\n    if (key === 'm') {\n        return withoutSuffix ? 'хвилина' : 'хвилину';\n    }\n    else if (key === 'h') {\n        return withoutSuffix ? 'година' : 'годину';\n    }\n    else {\n        return number + ' ' + plural(format[key], +number);\n    }\n}\nfunction weekdaysCaseReplace(m, format) {\n    var weekdays = {\n        'nominative': 'неділя_понеділок_вівторок_середа_четвер_п’ятниця_субота'.split('_'),\n        'accusative': 'неділю_понеділок_вівторок_середу_четвер_п’ятницю_суботу'.split('_'),\n        'genitive': 'неділі_понеділка_вівторка_середи_четверга_п’ятниці_суботи'.split('_')\n    };\n\n    if (!m) {\n        return weekdays['nominative'];\n    }\n\n    var nounCase = (/(\\[[ВвУу]\\]) ?dddd/).test(format) ?\n        'accusative' :\n        ((/\\[?(?:минулої|наступної)? ?\\] ?dddd/).test(format) ?\n            'genitive' :\n            'nominative');\n    return weekdays[nounCase][m.day()];\n}\nfunction processHoursFunction(str) {\n    return function () {\n        return str + 'о' + (this.hours() === 11 ? 'б' : '') + '] LT';\n    };\n}\n\nexport default moment.defineLocale('uk', {\n    months : {\n        'format': 'січня_лютого_березня_квітня_травня_червня_липня_серпня_вересня_жовтня_листопада_грудня'.split('_'),\n        'standalone': 'січень_лютий_березень_квітень_травень_червень_липень_серпень_вересень_жовтень_листопад_грудень'.split('_')\n    },\n    monthsShort : 'січ_лют_бер_квіт_трав_черв_лип_серп_вер_жовт_лист_груд'.split('_'),\n    weekdays : weekdaysCaseReplace,\n    weekdaysShort : 'нд_пн_вт_ср_чт_пт_сб'.split('_'),\n    weekdaysMin : 'нд_пн_вт_ср_чт_пт_сб'.split('_'),\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD.MM.YYYY',\n        LL : 'D MMMM YYYY р.',\n        LLL : 'D MMMM YYYY р., HH:mm',\n        LLLL : 'dddd, D MMMM YYYY р., HH:mm'\n    },\n    calendar : {\n        sameDay: processHoursFunction('[Сьогодні '),\n        nextDay: processHoursFunction('[Завтра '),\n        lastDay: processHoursFunction('[Вчора '),\n        nextWeek: processHoursFunction('[У] dddd ['),\n        lastWeek: function () {\n            switch (this.day()) {\n                case 0:\n                case 3:\n                case 5:\n                case 6:\n                    return processHoursFunction('[Минулої] dddd [').call(this);\n                case 1:\n                case 2:\n                case 4:\n                    return processHoursFunction('[Минулого] dddd [').call(this);\n            }\n        },\n        sameElse: 'L'\n    },\n    relativeTime : {\n        future : 'за %s',\n        past : '%s тому',\n        s : 'декілька секунд',\n        m : relativeTimeWithPlural,\n        mm : relativeTimeWithPlural,\n        h : 'годину',\n        hh : relativeTimeWithPlural,\n        d : 'день',\n        dd : relativeTimeWithPlural,\n        M : 'місяць',\n        MM : relativeTimeWithPlural,\n        y : 'рік',\n        yy : relativeTimeWithPlural\n    },\n    // M. E.: those two are virtually unused but a user might want to implement them for his/her website for some reason\n    meridiemParse: /ночі|ранку|дня|вечора/,\n    isPM: function (input) {\n        return /^(дня|вечора)$/.test(input);\n    },\n    meridiem : function (hour, minute, isLower) {\n        if (hour < 4) {\n            return 'ночі';\n        } else if (hour < 12) {\n            return 'ранку';\n        } else if (hour < 17) {\n            return 'дня';\n        } else {\n            return 'вечора';\n        }\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}-(й|го)/,\n    ordinal: function (number, period) {\n        switch (period) {\n            case 'M':\n            case 'd':\n            case 'DDD':\n            case 'w':\n            case 'W':\n                return number + '-й';\n            case 'D':\n                return number + '-го';\n            default:\n                return number;\n        }\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 7  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/locale/ur.js",
    "content": "//! moment.js locale configuration\n//! locale : Urdu [ur]\n//! author : Sawood Alam : https://github.com/ibnesayeed\n//! author : Zack : https://github.com/ZackVision\n\nimport moment from '../moment';\n\nvar months = [\n    'جنوری',\n    'فروری',\n    'مارچ',\n    'اپریل',\n    'مئی',\n    'جون',\n    'جولائی',\n    'اگست',\n    'ستمبر',\n    'اکتوبر',\n    'نومبر',\n    'دسمبر'\n];\nvar days = [\n    'اتوار',\n    'پیر',\n    'منگل',\n    'بدھ',\n    'جمعرات',\n    'جمعہ',\n    'ہفتہ'\n];\n\nexport default moment.defineLocale('ur', {\n    months : months,\n    monthsShort : months,\n    weekdays : days,\n    weekdaysShort : days,\n    weekdaysMin : days,\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY HH:mm',\n        LLLL : 'dddd، D MMMM YYYY HH:mm'\n    },\n    meridiemParse: /صبح|شام/,\n    isPM : function (input) {\n        return 'شام' === input;\n    },\n    meridiem : function (hour, minute, isLower) {\n        if (hour < 12) {\n            return 'صبح';\n        }\n        return 'شام';\n    },\n    calendar : {\n        sameDay : '[آج بوقت] LT',\n        nextDay : '[کل بوقت] LT',\n        nextWeek : 'dddd [بوقت] LT',\n        lastDay : '[گذشتہ روز بوقت] LT',\n        lastWeek : '[گذشتہ] dddd [بوقت] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : '%s بعد',\n        past : '%s قبل',\n        s : 'چند سیکنڈ',\n        m : 'ایک منٹ',\n        mm : '%d منٹ',\n        h : 'ایک گھنٹہ',\n        hh : '%d گھنٹے',\n        d : 'ایک دن',\n        dd : '%d دن',\n        M : 'ایک ماہ',\n        MM : '%d ماہ',\n        y : 'ایک سال',\n        yy : '%d سال'\n    },\n    preparse: function (string) {\n        return string.replace(/،/g, ',');\n    },\n    postformat: function (string) {\n        return string.replace(/,/g, '،');\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/locale/uz-latn.js",
    "content": "//! moment.js locale configuration\n//! locale : Uzbek Latin [uz-latn]\n//! author : Rasulbek Mirzayev : github.com/Rasulbeeek\n\nimport moment from '../moment';\n\nexport default moment.defineLocale('uz-latn', {\n    months : 'Yanvar_Fevral_Mart_Aprel_May_Iyun_Iyul_Avgust_Sentabr_Oktabr_Noyabr_Dekabr'.split('_'),\n    monthsShort : 'Yan_Fev_Mar_Apr_May_Iyun_Iyul_Avg_Sen_Okt_Noy_Dek'.split('_'),\n    weekdays : 'Yakshanba_Dushanba_Seshanba_Chorshanba_Payshanba_Juma_Shanba'.split('_'),\n    weekdaysShort : 'Yak_Dush_Sesh_Chor_Pay_Jum_Shan'.split('_'),\n    weekdaysMin : 'Ya_Du_Se_Cho_Pa_Ju_Sha'.split('_'),\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY HH:mm',\n        LLLL : 'D MMMM YYYY, dddd HH:mm'\n    },\n    calendar : {\n        sameDay : '[Bugun soat] LT [da]',\n        nextDay : '[Ertaga] LT [da]',\n        nextWeek : 'dddd [kuni soat] LT [da]',\n        lastDay : '[Kecha soat] LT [da]',\n        lastWeek : '[O\\'tgan] dddd [kuni soat] LT [da]',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'Yaqin %s ichida',\n        past : 'Bir necha %s oldin',\n        s : 'soniya',\n        m : 'bir daqiqa',\n        mm : '%d daqiqa',\n        h : 'bir soat',\n        hh : '%d soat',\n        d : 'bir kun',\n        dd : '%d kun',\n        M : 'bir oy',\n        MM : '%d oy',\n        y : 'bir yil',\n        yy : '%d yil'\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 7  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/locale/uz.js",
    "content": "//! moment.js locale configuration\n//! locale : Uzbek [uz]\n//! author : Sardor Muminov : https://github.com/muminoff\n\nimport moment from '../moment';\n\nexport default moment.defineLocale('uz', {\n    months : 'январ_феврал_март_апрел_май_июн_июл_август_сентябр_октябр_ноябр_декабр'.split('_'),\n    monthsShort : 'янв_фев_мар_апр_май_июн_июл_авг_сен_окт_ноя_дек'.split('_'),\n    weekdays : 'Якшанба_Душанба_Сешанба_Чоршанба_Пайшанба_Жума_Шанба'.split('_'),\n    weekdaysShort : 'Якш_Душ_Сеш_Чор_Пай_Жум_Шан'.split('_'),\n    weekdaysMin : 'Як_Ду_Се_Чо_Па_Жу_Ша'.split('_'),\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY HH:mm',\n        LLLL : 'D MMMM YYYY, dddd HH:mm'\n    },\n    calendar : {\n        sameDay : '[Бугун соат] LT [да]',\n        nextDay : '[Эртага] LT [да]',\n        nextWeek : 'dddd [куни соат] LT [да]',\n        lastDay : '[Кеча соат] LT [да]',\n        lastWeek : '[Утган] dddd [куни соат] LT [да]',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'Якин %s ичида',\n        past : 'Бир неча %s олдин',\n        s : 'фурсат',\n        m : 'бир дакика',\n        mm : '%d дакика',\n        h : 'бир соат',\n        hh : '%d соат',\n        d : 'бир кун',\n        dd : '%d кун',\n        M : 'бир ой',\n        MM : '%d ой',\n        y : 'бир йил',\n        yy : '%d йил'\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 7  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/locale/vi.js",
    "content": "//! moment.js locale configuration\n//! locale : Vietnamese [vi]\n//! author : Bang Nguyen : https://github.com/bangnk\n\nimport moment from '../moment';\n\nexport default moment.defineLocale('vi', {\n    months : 'tháng 1_tháng 2_tháng 3_tháng 4_tháng 5_tháng 6_tháng 7_tháng 8_tháng 9_tháng 10_tháng 11_tháng 12'.split('_'),\n    monthsShort : 'Th01_Th02_Th03_Th04_Th05_Th06_Th07_Th08_Th09_Th10_Th11_Th12'.split('_'),\n    monthsParseExact : true,\n    weekdays : 'chủ nhật_thứ hai_thứ ba_thứ tư_thứ năm_thứ sáu_thứ bảy'.split('_'),\n    weekdaysShort : 'CN_T2_T3_T4_T5_T6_T7'.split('_'),\n    weekdaysMin : 'CN_T2_T3_T4_T5_T6_T7'.split('_'),\n    weekdaysParseExact : true,\n    meridiemParse: /sa|ch/i,\n    isPM : function (input) {\n        return /^ch$/i.test(input);\n    },\n    meridiem : function (hours, minutes, isLower) {\n        if (hours < 12) {\n            return isLower ? 'sa' : 'SA';\n        } else {\n            return isLower ? 'ch' : 'CH';\n        }\n    },\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM [năm] YYYY',\n        LLL : 'D MMMM [năm] YYYY HH:mm',\n        LLLL : 'dddd, D MMMM [năm] YYYY HH:mm',\n        l : 'DD/M/YYYY',\n        ll : 'D MMM YYYY',\n        lll : 'D MMM YYYY HH:mm',\n        llll : 'ddd, D MMM YYYY HH:mm'\n    },\n    calendar : {\n        sameDay: '[Hôm nay lúc] LT',\n        nextDay: '[Ngày mai lúc] LT',\n        nextWeek: 'dddd [tuần tới lúc] LT',\n        lastDay: '[Hôm qua lúc] LT',\n        lastWeek: 'dddd [tuần rồi lúc] LT',\n        sameElse: 'L'\n    },\n    relativeTime : {\n        future : '%s tới',\n        past : '%s trước',\n        s : 'vài giây',\n        m : 'một phút',\n        mm : '%d phút',\n        h : 'một giờ',\n        hh : '%d giờ',\n        d : 'một ngày',\n        dd : '%d ngày',\n        M : 'một tháng',\n        MM : '%d tháng',\n        y : 'một năm',\n        yy : '%d năm'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}/,\n    ordinal : function (number) {\n        return number;\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/locale/x-pseudo.js",
    "content": "//! moment.js locale configuration\n//! locale : Pseudo [x-pseudo]\n//! author : Andrew Hood : https://github.com/andrewhood125\n\nimport moment from '../moment';\n\nexport default moment.defineLocale('x-pseudo', {\n    months : 'J~áñúá~rý_F~ébrú~árý_~Márc~h_Áp~ríl_~Máý_~Júñé~_Júl~ý_Áú~gúst~_Sép~témb~ér_Ó~ctób~ér_Ñ~óvém~bér_~Décé~mbér'.split('_'),\n    monthsShort : 'J~áñ_~Féb_~Már_~Ápr_~Máý_~Júñ_~Júl_~Áúg_~Sép_~Óct_~Ñóv_~Déc'.split('_'),\n    monthsParseExact : true,\n    weekdays : 'S~úñdá~ý_Mó~ñdáý~_Túé~sdáý~_Wéd~ñésd~áý_T~húrs~dáý_~Fríd~áý_S~átúr~dáý'.split('_'),\n    weekdaysShort : 'S~úñ_~Móñ_~Túé_~Wéd_~Thú_~Frí_~Sát'.split('_'),\n    weekdaysMin : 'S~ú_Mó~_Tú_~Wé_T~h_Fr~_Sá'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat : {\n        LT : 'HH:mm',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY HH:mm',\n        LLLL : 'dddd, D MMMM YYYY HH:mm'\n    },\n    calendar : {\n        sameDay : '[T~ódá~ý át] LT',\n        nextDay : '[T~ómó~rró~w át] LT',\n        nextWeek : 'dddd [át] LT',\n        lastDay : '[Ý~ést~érdá~ý át] LT',\n        lastWeek : '[L~ást] dddd [át] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'í~ñ %s',\n        past : '%s á~gó',\n        s : 'á ~féw ~sécó~ñds',\n        m : 'á ~míñ~úté',\n        mm : '%d m~íñú~tés',\n        h : 'á~ñ hó~úr',\n        hh : '%d h~óúrs',\n        d : 'á ~dáý',\n        dd : '%d d~áýs',\n        M : 'á ~móñ~th',\n        MM : '%d m~óñt~hs',\n        y : 'á ~ýéár',\n        yy : '%d ý~éárs'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}(th|st|nd|rd)/,\n    ordinal : function (number) {\n        var b = number % 10,\n            output = (~~(number % 100 / 10) === 1) ? 'th' :\n            (b === 1) ? 'st' :\n            (b === 2) ? 'nd' :\n            (b === 3) ? 'rd' : 'th';\n        return number + output;\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/locale/yo.js",
    "content": "//! moment.js locale configuration\n//! locale : Yoruba Nigeria [yo]\n//! author : Atolagbe Abisoye : https://github.com/andela-batolagbe\n\nimport moment from '../moment';\n\nexport default moment.defineLocale('yo', {\n    months : 'Sẹ́rẹ́_Èrèlè_Ẹrẹ̀nà_Ìgbé_Èbibi_Òkùdu_Agẹmo_Ògún_Owewe_Ọ̀wàrà_Bélú_Ọ̀pẹ̀̀'.split('_'),\n    monthsShort : 'Sẹ́r_Èrl_Ẹrn_Ìgb_Èbi_Òkù_Agẹ_Ògú_Owe_Ọ̀wà_Bél_Ọ̀pẹ̀̀'.split('_'),\n    weekdays : 'Àìkú_Ajé_Ìsẹ́gun_Ọjọ́rú_Ọjọ́bọ_Ẹtì_Àbámẹ́ta'.split('_'),\n    weekdaysShort : 'Àìk_Ajé_Ìsẹ́_Ọjr_Ọjb_Ẹtì_Àbá'.split('_'),\n    weekdaysMin : 'Àì_Aj_Ìs_Ọr_Ọb_Ẹt_Àb'.split('_'),\n    longDateFormat : {\n        LT : 'h:mm A',\n        LTS : 'h:mm:ss A',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY h:mm A',\n        LLLL : 'dddd, D MMMM YYYY h:mm A'\n    },\n    calendar : {\n        sameDay : '[Ònì ni] LT',\n        nextDay : '[Ọ̀la ni] LT',\n        nextWeek : 'dddd [Ọsẹ̀ tón\\'bọ] [ni] LT',\n        lastDay : '[Àna ni] LT',\n        lastWeek : 'dddd [Ọsẹ̀ tólọ́] [ni] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'ní %s',\n        past : '%s kọjá',\n        s : 'ìsẹjú aayá die',\n        m : 'ìsẹjú kan',\n        mm : 'ìsẹjú %d',\n        h : 'wákati kan',\n        hh : 'wákati %d',\n        d : 'ọjọ́ kan',\n        dd : 'ọjọ́ %d',\n        M : 'osù kan',\n        MM : 'osù %d',\n        y : 'ọdún kan',\n        yy : 'ọdún %d'\n    },\n    dayOfMonthOrdinalParse : /ọjọ́\\s\\d{1,2}/,\n    ordinal : 'ọjọ́ %d',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4 // The week that contains Jan 4th is the first week of the year.\n    }\n});\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/locale/zh-cn.js",
    "content": "//! moment.js locale configuration\n//! locale : Chinese (China) [zh-cn]\n//! author : suupic : https://github.com/suupic\n//! author : Zeno Zeng : https://github.com/zenozeng\n\nimport moment from '../moment';\n\nexport default moment.defineLocale('zh-cn', {\n    months : '一月_二月_三月_四月_五月_六月_七月_八月_九月_十月_十一月_十二月'.split('_'),\n    monthsShort : '1月_2月_3月_4月_5月_6月_7月_8月_9月_10月_11月_12月'.split('_'),\n    weekdays : '星期日_星期一_星期二_星期三_星期四_星期五_星期六'.split('_'),\n    weekdaysShort : '周日_周一_周二_周三_周四_周五_周六'.split('_'),\n    weekdaysMin : '日_一_二_三_四_五_六'.split('_'),\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'YYYY年MMMD日',\n        LL : 'YYYY年MMMD日',\n        LLL : 'YYYY年MMMD日Ah点mm分',\n        LLLL : 'YYYY年MMMD日ddddAh点mm分',\n        l : 'YYYY年MMMD日',\n        ll : 'YYYY年MMMD日',\n        lll : 'YYYY年MMMD日 HH:mm',\n        llll : 'YYYY年MMMD日dddd HH:mm'\n    },\n    meridiemParse: /凌晨|早上|上午|中午|下午|晚上/,\n    meridiemHour: function (hour, meridiem) {\n        if (hour === 12) {\n            hour = 0;\n        }\n        if (meridiem === '凌晨' || meridiem === '早上' ||\n                meridiem === '上午') {\n            return hour;\n        } else if (meridiem === '下午' || meridiem === '晚上') {\n            return hour + 12;\n        } else {\n            // '中午'\n            return hour >= 11 ? hour : hour + 12;\n        }\n    },\n    meridiem : function (hour, minute, isLower) {\n        var hm = hour * 100 + minute;\n        if (hm < 600) {\n            return '凌晨';\n        } else if (hm < 900) {\n            return '早上';\n        } else if (hm < 1130) {\n            return '上午';\n        } else if (hm < 1230) {\n            return '中午';\n        } else if (hm < 1800) {\n            return '下午';\n        } else {\n            return '晚上';\n        }\n    },\n    calendar : {\n        sameDay : '[今天]LT',\n        nextDay : '[明天]LT',\n        nextWeek : '[下]ddddLT',\n        lastDay : '[昨天]LT',\n        lastWeek : '[上]ddddLT',\n        sameElse : 'L'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}(日|月|周)/,\n    ordinal : function (number, period) {\n        switch (period) {\n            case 'd':\n            case 'D':\n            case 'DDD':\n                return number + '日';\n            case 'M':\n                return number + '月';\n            case 'w':\n            case 'W':\n                return number + '周';\n            default:\n                return number;\n        }\n    },\n    relativeTime : {\n        future : '%s内',\n        past : '%s前',\n        s : '几秒',\n        m : '1 分钟',\n        mm : '%d 分钟',\n        h : '1 小时',\n        hh : '%d 小时',\n        d : '1 天',\n        dd : '%d 天',\n        M : '1 个月',\n        MM : '%d 个月',\n        y : '1 年',\n        yy : '%d 年'\n    },\n    week : {\n        // GB/T 7408-1994《数据元和交换格式·信息交换·日期和时间表示法》与ISO 8601:1988等效\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/locale/zh-hk.js",
    "content": "//! moment.js locale configuration\n//! locale : Chinese (Hong Kong) [zh-hk]\n//! author : Ben : https://github.com/ben-lin\n//! author : Chris Lam : https://github.com/hehachris\n//! author : Konstantin : https://github.com/skfd\n\nimport moment from '../moment';\n\nexport default moment.defineLocale('zh-hk', {\n    months : '一月_二月_三月_四月_五月_六月_七月_八月_九月_十月_十一月_十二月'.split('_'),\n    monthsShort : '1月_2月_3月_4月_5月_6月_7月_8月_9月_10月_11月_12月'.split('_'),\n    weekdays : '星期日_星期一_星期二_星期三_星期四_星期五_星期六'.split('_'),\n    weekdaysShort : '週日_週一_週二_週三_週四_週五_週六'.split('_'),\n    weekdaysMin : '日_一_二_三_四_五_六'.split('_'),\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'YYYY年MMMD日',\n        LL : 'YYYY年MMMD日',\n        LLL : 'YYYY年MMMD日 HH:mm',\n        LLLL : 'YYYY年MMMD日dddd HH:mm',\n        l : 'YYYY年MMMD日',\n        ll : 'YYYY年MMMD日',\n        lll : 'YYYY年MMMD日 HH:mm',\n        llll : 'YYYY年MMMD日dddd HH:mm'\n    },\n    meridiemParse: /凌晨|早上|上午|中午|下午|晚上/,\n    meridiemHour : function (hour, meridiem) {\n        if (hour === 12) {\n            hour = 0;\n        }\n        if (meridiem === '凌晨' || meridiem === '早上' || meridiem === '上午') {\n            return hour;\n        } else if (meridiem === '中午') {\n            return hour >= 11 ? hour : hour + 12;\n        } else if (meridiem === '下午' || meridiem === '晚上') {\n            return hour + 12;\n        }\n    },\n    meridiem : function (hour, minute, isLower) {\n        var hm = hour * 100 + minute;\n        if (hm < 600) {\n            return '凌晨';\n        } else if (hm < 900) {\n            return '早上';\n        } else if (hm < 1130) {\n            return '上午';\n        } else if (hm < 1230) {\n            return '中午';\n        } else if (hm < 1800) {\n            return '下午';\n        } else {\n            return '晚上';\n        }\n    },\n    calendar : {\n        sameDay : '[今天]LT',\n        nextDay : '[明天]LT',\n        nextWeek : '[下]ddddLT',\n        lastDay : '[昨天]LT',\n        lastWeek : '[上]ddddLT',\n        sameElse : 'L'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}(日|月|週)/,\n    ordinal : function (number, period) {\n        switch (period) {\n            case 'd' :\n            case 'D' :\n            case 'DDD' :\n                return number + '日';\n            case 'M' :\n                return number + '月';\n            case 'w' :\n            case 'W' :\n                return number + '週';\n            default :\n                return number;\n        }\n    },\n    relativeTime : {\n        future : '%s內',\n        past : '%s前',\n        s : '幾秒',\n        m : '1 分鐘',\n        mm : '%d 分鐘',\n        h : '1 小時',\n        hh : '%d 小時',\n        d : '1 天',\n        dd : '%d 天',\n        M : '1 個月',\n        MM : '%d 個月',\n        y : '1 年',\n        yy : '%d 年'\n    }\n});\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/locale/zh-tw.js",
    "content": "//! moment.js locale configuration\n//! locale : Chinese (Taiwan) [zh-tw]\n//! author : Ben : https://github.com/ben-lin\n//! author : Chris Lam : https://github.com/hehachris\n\nimport moment from '../moment';\n\nexport default moment.defineLocale('zh-tw', {\n    months : '一月_二月_三月_四月_五月_六月_七月_八月_九月_十月_十一月_十二月'.split('_'),\n    monthsShort : '1月_2月_3月_4月_5月_6月_7月_8月_9月_10月_11月_12月'.split('_'),\n    weekdays : '星期日_星期一_星期二_星期三_星期四_星期五_星期六'.split('_'),\n    weekdaysShort : '週日_週一_週二_週三_週四_週五_週六'.split('_'),\n    weekdaysMin : '日_一_二_三_四_五_六'.split('_'),\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'YYYY年MMMD日',\n        LL : 'YYYY年MMMD日',\n        LLL : 'YYYY年MMMD日 HH:mm',\n        LLLL : 'YYYY年MMMD日dddd HH:mm',\n        l : 'YYYY年MMMD日',\n        ll : 'YYYY年MMMD日',\n        lll : 'YYYY年MMMD日 HH:mm',\n        llll : 'YYYY年MMMD日dddd HH:mm'\n    },\n    meridiemParse: /凌晨|早上|上午|中午|下午|晚上/,\n    meridiemHour : function (hour, meridiem) {\n        if (hour === 12) {\n            hour = 0;\n        }\n        if (meridiem === '凌晨' || meridiem === '早上' || meridiem === '上午') {\n            return hour;\n        } else if (meridiem === '中午') {\n            return hour >= 11 ? hour : hour + 12;\n        } else if (meridiem === '下午' || meridiem === '晚上') {\n            return hour + 12;\n        }\n    },\n    meridiem : function (hour, minute, isLower) {\n        var hm = hour * 100 + minute;\n        if (hm < 600) {\n            return '凌晨';\n        } else if (hm < 900) {\n            return '早上';\n        } else if (hm < 1130) {\n            return '上午';\n        } else if (hm < 1230) {\n            return '中午';\n        } else if (hm < 1800) {\n            return '下午';\n        } else {\n            return '晚上';\n        }\n    },\n    calendar : {\n        sameDay : '[今天]LT',\n        nextDay : '[明天]LT',\n        nextWeek : '[下]ddddLT',\n        lastDay : '[昨天]LT',\n        lastWeek : '[上]ddddLT',\n        sameElse : 'L'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}(日|月|週)/,\n    ordinal : function (number, period) {\n        switch (period) {\n            case 'd' :\n            case 'D' :\n            case 'DDD' :\n                return number + '日';\n            case 'M' :\n                return number + '月';\n            case 'w' :\n            case 'W' :\n                return number + '週';\n            default :\n                return number;\n        }\n    },\n    relativeTime : {\n        future : '%s內',\n        past : '%s前',\n        s : '幾秒',\n        m : '1 分鐘',\n        mm : '%d 分鐘',\n        h : '1 小時',\n        hh : '%d 小時',\n        d : '1 天',\n        dd : '%d 天',\n        M : '1 個月',\n        MM : '%d 個月',\n        y : '1 年',\n        yy : '%d 年'\n    }\n});\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/moment.js",
    "content": "//! moment.js\n//! version : 2.18.1\n//! authors : Tim Wood, Iskren Chernev, Moment.js contributors\n//! license : MIT\n//! momentjs.com\n\nimport { hooks as moment, setHookCallback } from './lib/utils/hooks';\n\nmoment.version = '2.18.1';\n\nimport {\n    min,\n    max,\n    now,\n    isMoment,\n    momentPrototype as fn,\n    createUTC       as utc,\n    createUnix      as unix,\n    createLocal     as local,\n    createInvalid   as invalid,\n    createInZone    as parseZone\n} from './lib/moment/moment';\n\nimport {\n    getCalendarFormat\n} from './lib/moment/calendar';\n\nimport {\n    defineLocale,\n    updateLocale,\n    getSetGlobalLocale as locale,\n    getLocale          as localeData,\n    listLocales        as locales,\n    listMonths         as months,\n    listMonthsShort    as monthsShort,\n    listWeekdays       as weekdays,\n    listWeekdaysMin    as weekdaysMin,\n    listWeekdaysShort  as weekdaysShort\n} from './lib/locale/locale';\n\nimport {\n    isDuration,\n    createDuration as duration,\n    getSetRelativeTimeRounding as relativeTimeRounding,\n    getSetRelativeTimeThreshold as relativeTimeThreshold\n} from './lib/duration/duration';\n\nimport { normalizeUnits } from './lib/units/units';\n\nimport isDate from './lib/utils/is-date';\n\nsetHookCallback(local);\n\nmoment.fn                    = fn;\nmoment.min                   = min;\nmoment.max                   = max;\nmoment.now                   = now;\nmoment.utc                   = utc;\nmoment.unix                  = unix;\nmoment.months                = months;\nmoment.isDate                = isDate;\nmoment.locale                = locale;\nmoment.invalid               = invalid;\nmoment.duration              = duration;\nmoment.isMoment              = isMoment;\nmoment.weekdays              = weekdays;\nmoment.parseZone             = parseZone;\nmoment.localeData            = localeData;\nmoment.isDuration            = isDuration;\nmoment.monthsShort           = monthsShort;\nmoment.weekdaysMin           = weekdaysMin;\nmoment.defineLocale          = defineLocale;\nmoment.updateLocale          = updateLocale;\nmoment.locales               = locales;\nmoment.weekdaysShort         = weekdaysShort;\nmoment.normalizeUnits        = normalizeUnits;\nmoment.relativeTimeRounding = relativeTimeRounding;\nmoment.relativeTimeThreshold = relativeTimeThreshold;\nmoment.calendarFormat        = getCalendarFormat;\nmoment.prototype             = fn;\n\nexport default moment;\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/test/helpers/common-locale.js",
    "content": "import { test, expect } from '../qunit';\nimport each from './each';\nimport objectKeys from './object-keys';\nimport moment from '../../moment';\nimport defaults from '../../lib/utils/defaults';\n\nexport function defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/test/helpers/deprecation-handler.js",
    "content": "import each from './each';\n\nexport function setupDeprecationHandler(test, moment, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment.suppressDeprecationWarnings;\n    moment.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nexport function teardownDeprecationHandler(test, moment, scope) {\n    moment.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/test/helpers/dst.js",
    "content": "import moment from '../../moment';\n\nexport function isNearSpringDST() {\n    return moment().subtract(1, 'day').utcOffset() !== moment().add(1, 'day').utcOffset();\n}\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/test/helpers/each.js",
    "content": "function each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nexport default each;\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/test/helpers/object-keys.js",
    "content": "export default function objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/test/locale/af.js",
    "content": "import {localeModule, test} from '../qunit';\nimport moment from '../../moment';\nlocaleModule('af');\n\ntest('parse', function (assert) {\n    var tests = 'Januarie Jan_Februarie Feb_Maart Mrt_April Apr_Mei Mei_Junie Jun_Julie Jul_Augustus Aug_September Sep_Oktober Okt_November Nov_Desember Des'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, MMMM Do YYYY, h:mm:ss a',      'Sondag, Februarie 14de 2010, 3:25:50 nm'],\n            ['ddd, hA',                            'Son, 3NM'],\n            ['M Mo MM MMMM MMM',                   '2 2de 02 Februarie Feb'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14de 14'],\n            ['d do dddd ddd dd',                   '0 0de Sondag Son So'],\n            ['DDD DDDo DDDD',                      '45 45ste 045'],\n            ['w wo ww',                            '6 6de 06'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'nm NM'],\n            ['[the] DDDo [day of the year]',       'the 45ste day of the year'],\n            ['LT',                                 '15:25'],\n            ['LTS',                                '15:25:50'],\n            ['L',                                  '14/02/2010'],\n            ['LL',                                 '14 Februarie 2010'],\n            ['LLL',                                '14 Februarie 2010 15:25'],\n            ['LLLL',                               'Sondag, 14 Februarie 2010 15:25'],\n            ['l',                                  '14/2/2010'],\n            ['ll',                                 '14 Feb 2010'],\n            ['lll',                                '14 Feb 2010 15:25'],\n            ['llll',                               'Son, 14 Feb 2010 15:25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1ste', '1ste');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2de', '2de');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3de', '3de');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4de', '4de');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5de', '5de');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6de', '6de');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7de', '7de');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8ste', '8ste');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9de', '9de');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10de', '10de');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11de', '11de');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12de', '12de');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13de', '13de');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14de', '14de');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15de', '15de');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16de', '16de');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17de', '17de');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18de', '18de');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19de', '19de');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20ste', '20ste');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21ste', '21ste');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22ste', '22ste');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23ste', '23ste');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24ste', '24ste');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25ste', '25ste');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26ste', '26ste');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27ste', '27ste');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28ste', '28ste');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29ste', '29ste');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30ste', '30ste');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31ste', '31ste');\n});\n\ntest('format month', function (assert) {\n    var expected = 'Januarie Jan_Februarie Feb_Maart Mrt_April Apr_Mei Mei_Junie Jun_Julie Jul_Augustus Aug_September Sep_Oktober Okt_November Nov_Desember Des'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'Sondag Son So_Maandag Maa Ma_Dinsdag Din Di_Woensdag Woe Wo_Donderdag Don Do_Vrydag Vry Vr_Saterdag Sat Sa'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  '\\'n paar sekondes', '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  '\\'n minuut',      '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  '\\'n minuut',      '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 minute',     '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 minute',    '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  '\\'n uur',       '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  '\\'n uur',       '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 ure',       '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 ure',       '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 ure',      '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  '\\'n dag',         '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  '\\'n dag',         '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 dae',        '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   '\\'n dag',         '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 dae',        '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 dae',       '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  '\\'n maand',       '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  '\\'n maand',       '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  '\\'n maand',       '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 maande',      '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 maande',      '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 maande',      '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   '\\'n maand',       '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 maande',      '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), '\\'n jaar',        '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 jaar',       '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   '\\'n jaar',        '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 jaar',       '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'oor \\'n paar sekondes',  'prefix');\n    assert.equal(moment(0).from(30000), '\\'n paar sekondes gelede', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), '\\'n paar sekondes gelede',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'oor \\'n paar sekondes', 'in a few seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), 'oor 5 dae', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'Vandag om 12:00',     'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'Vandag om 12:25',     'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'Vandag om 13:00',     'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'Môre om 12:00',       'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'Vandag om 11:00',     'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'Gister om 12:00',     'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('dddd [om] LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd [om] LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd [om] LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('[Laas] dddd [om] LT'),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[Laas] dddd [om] LT'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[Laas] dddd [om] LT'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2012, 0,  1]).format('w ww wo'), '52 52 52ste', 'Jan  1 2012 should be week 52');\n    assert.equal(moment([2012, 0,  2]).format('w ww wo'),   '1 01 1ste', 'Jan  2 2012 should be week 1');\n    assert.equal(moment([2012, 0,  8]).format('w ww wo'),   '1 01 1ste', 'Jan  8 2012 should be week 1');\n    assert.equal(moment([2012, 0,  9]).format('w ww wo'),    '2 02 2de', 'Jan  9 2012 should be week 2');\n    assert.equal(moment([2012, 0, 15]).format('w ww wo'),    '2 02 2de', 'Jan 15 2012 should be week 2');\n});\n\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/test/locale/ar-dz.js",
    "content": "import {localeModule, test} from '../qunit';\nimport moment from '../../moment';\nlocaleModule('ar-dz');\n\ntest('parse', function (assert) {\n    var tests = 'جانفي:جانفي_فيفري:فيفري_مارس:مارس_أفريل:أفريل_ماي:ماي_جوان:جوان_جويلية:جويلية_أوت:أوت_سبتمبر:سبتمبر_أكتوبر:أكتوبر_نوفمبر:نوفمبر_ديسمبر:ديسمبر'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(':');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, MMMM Do YYYY, h:mm:ss a',      'الأحد, فيفري 14 2010, 3:25:50 pm'],\n            ['ddd, hA',                            'احد, 3PM'],\n            ['M Mo MM MMMM MMM',                   '2 2 02 فيفري فيفري'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14 14'],\n            ['d do dddd ddd dd',                   '0 0 الأحد احد أح'],\n            ['DDD DDDo DDDD',                      '45 45 045'],\n            ['w wo ww',                            '7 7 07'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'pm PM'],\n            ['[the] DDDo [day of the year]',       'the 45 day of the year'],\n            ['LT',                                 '15:25'],\n            ['LTS',                                '15:25:50'],\n            ['L',                                  '14/02/2010'],\n            ['LL',                                 '14 فيفري 2010'],\n            ['LLL',                                '14 فيفري 2010 15:25'],\n            ['LLLL',                               'الأحد 14 فيفري 2010 15:25'],\n            ['l',                                  '14/2/2010'],\n            ['ll',                                 '14 فيفري 2010'],\n            ['lll',                                '14 فيفري 2010 15:25'],\n            ['llll',                               'احد 14 فيفري 2010 15:25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1', '1');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2', '2');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3', '3');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4', '4');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5', '5');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6', '6');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7', '7');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8', '8');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9', '9');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10', '10');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11', '11');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12', '12');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13', '13');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14', '14');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15', '15');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16', '16');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17', '17');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18', '18');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19', '19');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20', '20');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21', '21');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22', '22');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23', '23');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24', '24');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25', '25');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26', '26');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27', '27');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28', '28');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29', '29');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30', '30');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31', '31');\n});\n\ntest('format month', function (assert) {\n    var expected = 'جانفي جانفي_فيفري فيفري_مارس مارس_أفريل أفريل_ماي ماي_جوان جوان_جويلية جويلية_أوت أوت_سبتمبر سبتمبر_أكتوبر أكتوبر_نوفمبر نوفمبر_ديسمبر ديسمبر'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'الأحد احد أح_الإثنين اثنين إث_الثلاثاء ثلاثاء ثلا_الأربعاء اربعاء أر_الخميس خميس خم_الجمعة جمعة جم_السبت سبت سب'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'ثوان', '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'دقيقة',      '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'دقيقة',      '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 دقائق',     '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 دقائق',    '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'ساعة',       '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'ساعة',       '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 ساعات',       '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 ساعات',       '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 ساعات',      '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'يوم',         '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'يوم',         '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 أيام',        '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'يوم',         '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 أيام',        '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 أيام',       '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'شهر',       '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'شهر',       '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'شهر',       '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 أشهر',      '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 أشهر',      '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 أشهر',      '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'شهر',       '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 أشهر',      '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'سنة',        '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 سنوات',       '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'سنة',        '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 سنوات',       '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'في ثوان',  'prefix');\n    assert.equal(moment(0).from(30000), 'منذ ثوان', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'منذ ثوان',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'في ثوان', 'in a few seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), 'في 5 أيام', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'اليوم على الساعة 12:00',     'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'اليوم على الساعة 12:25',     'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'اليوم على الساعة 13:00',     'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'غدا على الساعة 12:00',      'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'اليوم على الساعة 11:00',     'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'أمس على الساعة 12:00',     'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('dddd [على الساعة] LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd [على الساعة] LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd [على الساعة] LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('dddd [على الساعة] LT'),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd [على الساعة] LT'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd [على الساعة] LT'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2016, 1, 4]).format('w ww wo'), '5 05 5', 'Feb 4 2016 should be week 5');\n    assert.equal(moment([2016,  0,  6]).format('w ww wo'), '1 01 1', 'Jan  6 2016 should be week 1');\n    assert.equal(moment([2016,  0,  7]).format('w ww wo'), '1 01 1', 'Jan  7 2016 should be week 1');\n    assert.equal(moment([2016,  0, 13]).format('w ww wo'), '2 02 2', 'Jan 13 2016 should be week 2');\n    assert.equal(moment([2016,  0, 14]).format('w ww wo'), '2 02 2', 'Jan 14 2016 should be week 2');\n});\n\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/test/locale/ar-kw.js",
    "content": "import {localeModule, test} from '../qunit';\nimport moment from '../../moment';\nlocaleModule('ar-kw');\n\ntest('parse', function (assert) {\n    var tests = 'يناير:يناير_فبراير:فبراير_مارس:مارس_أبريل:أبريل_ماي:ماي_يونيو:يونيو_يوليوز:يوليوز_غشت:غشت_شتنبر:شتنبر_أكتوبر:أكتوبر_نونبر:نونبر_دجنبر:دجنبر'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(':');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, MMMM Do YYYY, h:mm:ss a',      'الأحد, فبراير 14 2010, 3:25:50 pm'],\n            ['ddd, hA',                            'احد, 3PM'],\n            ['M Mo MM MMMM MMM',                   '2 2 02 فبراير فبراير'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14 14'],\n            ['d do dddd ddd dd',                   '0 0 الأحد احد ح'],\n            ['DDD DDDo DDDD',                      '45 45 045'],\n            ['w wo ww',                            '9 9 09'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'pm PM'],\n            ['[the] DDDo [day of the year]',       'the 45 day of the year'],\n            ['LT',                                 '15:25'],\n            ['LTS',                                '15:25:50'],\n            ['L',                                  '14/02/2010'],\n            ['LL',                                 '14 فبراير 2010'],\n            ['LLL',                                '14 فبراير 2010 15:25'],\n            ['LLLL',                               'الأحد 14 فبراير 2010 15:25'],\n            ['l',                                  '14/2/2010'],\n            ['ll',                                 '14 فبراير 2010'],\n            ['lll',                                '14 فبراير 2010 15:25'],\n            ['llll',                               'احد 14 فبراير 2010 15:25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1', '1');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2', '2');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3', '3');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4', '4');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5', '5');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6', '6');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7', '7');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8', '8');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9', '9');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10', '10');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11', '11');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12', '12');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13', '13');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14', '14');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15', '15');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16', '16');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17', '17');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18', '18');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19', '19');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20', '20');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21', '21');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22', '22');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23', '23');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24', '24');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25', '25');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26', '26');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27', '27');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28', '28');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29', '29');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30', '30');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31', '31');\n});\n\ntest('format month', function (assert) {\n    var expected = 'يناير يناير_فبراير فبراير_مارس مارس_أبريل أبريل_ماي ماي_يونيو يونيو_يوليوز يوليوز_غشت غشت_شتنبر شتنبر_أكتوبر أكتوبر_نونبر نونبر_دجنبر دجنبر'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'الأحد احد ح_الإتنين اتنين ن_الثلاثاء ثلاثاء ث_الأربعاء اربعاء ر_الخميس خميس خ_الجمعة جمعة ج_السبت سبت س'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'ثوان', '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'دقيقة',      '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'دقيقة',      '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 دقائق',     '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 دقائق',    '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'ساعة',       '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'ساعة',       '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 ساعات',       '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 ساعات',       '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 ساعات',      '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'يوم',         '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'يوم',         '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 أيام',        '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'يوم',         '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 أيام',        '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 أيام',       '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'شهر',       '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'شهر',       '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'شهر',       '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 أشهر',      '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 أشهر',      '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 أشهر',      '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'شهر',       '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 أشهر',      '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'سنة',        '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 سنوات',       '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'سنة',        '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 سنوات',       '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'في ثوان',  'prefix');\n    assert.equal(moment(0).from(30000), 'منذ ثوان', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'منذ ثوان',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'في ثوان', 'in a few seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), 'في 5 أيام', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'اليوم على الساعة 12:00',     'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'اليوم على الساعة 12:25',     'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'اليوم على الساعة 13:00',     'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'غدا على الساعة 12:00',      'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'اليوم على الساعة 11:00',     'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'أمس على الساعة 12:00',     'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('dddd [على الساعة] LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd [على الساعة] LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd [على الساعة] LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('dddd [على الساعة] LT'),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd [على الساعة] LT'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd [على الساعة] LT'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2011, 11, 31]).format('w ww wo'), '1 01 1', 'Dec 31 2011 should be week 1');\n    assert.equal(moment([2012,  0,  1]).format('w ww wo'), '2 02 2', 'Jan  1 2012 should be week 2');\n    assert.equal(moment([2012,  0,  8]).format('w ww wo'), '3 03 3', 'Jan  8 2012 should be week 3');\n    assert.equal(moment([2012,  0, 14]).format('w ww wo'), '3 03 3', 'Jan 14 2012 should be week 3');\n    assert.equal(moment([2012,  0, 15]).format('w ww wo'), '4 04 4', 'Jan 15 2012 should be week 4');\n});\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/test/locale/ar-ly.js",
    "content": "import {localeModule, test} from '../qunit';\nimport moment from '../../moment';\nlocaleModule('ar-ly');\n\nvar months = [\n    'يناير',\n    'فبراير',\n    'مارس',\n    'أبريل',\n    'مايو',\n    'يونيو',\n    'يوليو',\n    'أغسطس',\n    'سبتمبر',\n    'أكتوبر',\n    'نوفمبر',\n    'ديسمبر'\n];\n\ntest('parse', function (assert) {\n    var tests = months, i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1) + ' instead is month ' + moment(input, mmm).month());\n    }\n    for (i = 0; i < 12; i++) {\n        equalTest(tests[i], 'MMM', i);\n        equalTest(tests[i], 'MMM', i);\n        equalTest(tests[i], 'MMMM', i);\n        equalTest(tests[i], 'MMMM', i);\n        equalTest(tests[i].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, MMMM Do YYYY, h:mm:ss a',      'الأحد، فبراير 14 2010، 3:25:50 م'],\n            ['ddd, hA',                            'أحد، 3م'],\n            ['M Mo MM MMMM MMM',                   '2 2 02 فبراير فبراير'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14 14'],\n            ['d do dddd ddd dd',                   '0 0 الأحد أحد ح'],\n            ['DDD DDDo DDDD',                      '45 45 045'],\n            ['w wo ww',                            '8 8 08'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'م م'],\n            ['[the] DDDo [day of the year]',       'the 45 day of the year'],\n            ['LT',                                 '15:25'],\n            ['LTS',                                '15:25:50'],\n            ['L',                                  '14/\\u200f2/\\u200f2010'],\n            ['LL',                                 '14 فبراير 2010'],\n            ['LLL',                                '14 فبراير 2010 15:25'],\n            ['LLLL',                               'الأحد 14 فبراير 2010 15:25'],\n            ['l',                                  '14/\\u200f2/\\u200f2010'],\n            ['ll',                                 '14 فبراير 2010'],\n            ['lll',                                '14 فبراير 2010 15:25'],\n            ['llll',                               'أحد 14 فبراير 2010 15:25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1', '1');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2', '2');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3', '3');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4', '4');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5', '5');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6', '6');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7', '7');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8', '8');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9', '9');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10', '10');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11', '11');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12', '12');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13', '13');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14', '14');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15', '15');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16', '16');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17', '17');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18', '18');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19', '19');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20', '20');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21', '21');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22', '22');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23', '23');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24', '24');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25', '25');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26', '26');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27', '27');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28', '28');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29', '29');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30', '30');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31', '31');\n});\n\ntest('format month', function (assert) {\n    var expected = months, i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM'), expected[i], expected[i]);\n        assert.equal(moment([2011, i, 1]).format('MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'الأحد أحد ح_الإثنين إثنين ن_الثلاثاء ثلاثاء ث_الأربعاء أربعاء ر_الخميس خميس خ_الجمعة جمعة ج_السبت سبت س'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  '44 ثانية', '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'دقيقة واحدة',      '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'دقيقة واحدة',      '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  'دقيقتان',     '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 دقيقة',    '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'ساعة واحدة',       '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'ساعة واحدة',       '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  'ساعتان',       '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 ساعات',       '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 ساعة',      '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'يوم واحد',         '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'يوم واحد',         '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  'يومان',        '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'يوم واحد',         '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 أيام',        '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 يومًا',       '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'شهر واحد',       '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'شهر واحد',       '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'شهر واحد',       '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  'شهران',      '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  'شهران',      '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 أشهر',      '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'شهر واحد',       '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 أشهر',      '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'عام واحد',        '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), 'عامان',       '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'عام واحد',        '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 أعوام',       '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'بعد 30 ثانية',  'prefix');\n    assert.equal(moment(0).from(30000), 'منذ 30 ثانية', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'منذ ثانية واحدة',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'بعد 30 ثانية', 'in a few seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), 'بعد 5 أيام', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'اليوم عند الساعة 12:00',     'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'اليوم عند الساعة 12:25',     'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'اليوم عند الساعة 13:00',     'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'غدًا عند الساعة 12:00',      'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'اليوم عند الساعة 11:00',     'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'أمس عند الساعة 12:00',       'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('dddd [عند الساعة] LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd [عند الساعة] LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd [عند الساعة] LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('dddd [عند الساعة] LT'),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd [عند الساعة] LT'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd [عند الساعة] LT'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('weeks year starting wednesday custom', function (assert) {\n    assert.equal(moment('2003 1 6', 'gggg w d').format('YYYY-MM-DD'), '2002-12-28', 'Week 1 of 2003 should be Dec 28 2002');\n    assert.equal(moment('2003 1 0', 'gggg w e').format('YYYY-MM-DD'), '2002-12-28', 'Week 1 of 2003 should be Dec 28 2002');\n    assert.equal(moment('2003 1 6', 'gggg w d').format('gggg w d'), '2003 1 6', 'Saturday of week 1 of 2003 parsed should be formatted as 2003 1 6');\n    assert.equal(moment('2003 1 0', 'gggg w e').format('gggg w e'), '2003 1 0', '1st day of week 1 of 2003 parsed should be formatted as 2003 1 0');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2011, 11, 31]).format('w ww wo'), '1 01 1', 'Dec 31 2011 should be week 1');\n    assert.equal(moment([2012,  0,  6]).format('w ww wo'), '1 01 1', 'Jan  6 2012 should be week 1');\n    assert.equal(moment([2012,  0,  7]).format('w ww wo'), '2 02 2', 'Jan  7 2012 should be week 2');\n    assert.equal(moment([2012,  0, 13]).format('w ww wo'), '2 02 2', 'Jan 13 2012 should be week 2');\n    assert.equal(moment([2012,  0, 14]).format('w ww wo'), '3 03 3', 'Jan 14 2012 should be week 3');\n});\n\ntest('no leading zeros in long date formats', function (assert) {\n    var i, j, longDateStr, shortDateStr;\n    for (i = 1; i <= 9; ++i) {\n        for (j = 1; j <= 9; ++j) {\n            longDateStr = moment([2014, i, j]).format('L');\n            shortDateStr = moment([2014, i, j]).format('l');\n            assert.equal(longDateStr, shortDateStr, 'should not have leading zeros in month or day');\n        }\n    }\n});\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/test/locale/ar-ma.js",
    "content": "import {localeModule, test} from '../qunit';\nimport moment from '../../moment';\nlocaleModule('ar-ma');\n\ntest('parse', function (assert) {\n    var tests = 'يناير:يناير_فبراير:فبراير_مارس:مارس_أبريل:أبريل_ماي:ماي_يونيو:يونيو_يوليوز:يوليوز_غشت:غشت_شتنبر:شتنبر_أكتوبر:أكتوبر_نونبر:نونبر_دجنبر:دجنبر'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(':');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, MMMM Do YYYY, h:mm:ss a',      'الأحد, فبراير 14 2010, 3:25:50 pm'],\n            ['ddd, hA',                            'احد, 3PM'],\n            ['M Mo MM MMMM MMM',                   '2 2 02 فبراير فبراير'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14 14'],\n            ['d do dddd ddd dd',                   '0 0 الأحد احد ح'],\n            ['DDD DDDo DDDD',                      '45 45 045'],\n            ['w wo ww',                            '8 8 08'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'pm PM'],\n            ['[the] DDDo [day of the year]',       'the 45 day of the year'],\n            ['LT',                                 '15:25'],\n            ['LTS',                                '15:25:50'],\n            ['L',                                  '14/02/2010'],\n            ['LL',                                 '14 فبراير 2010'],\n            ['LLL',                                '14 فبراير 2010 15:25'],\n            ['LLLL',                               'الأحد 14 فبراير 2010 15:25'],\n            ['l',                                  '14/2/2010'],\n            ['ll',                                 '14 فبراير 2010'],\n            ['lll',                                '14 فبراير 2010 15:25'],\n            ['llll',                               'احد 14 فبراير 2010 15:25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1', '1');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2', '2');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3', '3');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4', '4');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5', '5');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6', '6');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7', '7');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8', '8');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9', '9');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10', '10');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11', '11');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12', '12');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13', '13');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14', '14');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15', '15');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16', '16');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17', '17');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18', '18');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19', '19');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20', '20');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21', '21');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22', '22');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23', '23');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24', '24');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25', '25');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26', '26');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27', '27');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28', '28');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29', '29');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30', '30');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31', '31');\n});\n\ntest('format month', function (assert) {\n    var expected = 'يناير يناير_فبراير فبراير_مارس مارس_أبريل أبريل_ماي ماي_يونيو يونيو_يوليوز يوليوز_غشت غشت_شتنبر شتنبر_أكتوبر أكتوبر_نونبر نونبر_دجنبر دجنبر'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'الأحد احد ح_الإتنين اتنين ن_الثلاثاء ثلاثاء ث_الأربعاء اربعاء ر_الخميس خميس خ_الجمعة جمعة ج_السبت سبت س'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'ثوان', '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'دقيقة',      '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'دقيقة',      '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 دقائق',     '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 دقائق',    '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'ساعة',       '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'ساعة',       '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 ساعات',       '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 ساعات',       '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 ساعات',      '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'يوم',         '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'يوم',         '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 أيام',        '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'يوم',         '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 أيام',        '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 أيام',       '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'شهر',       '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'شهر',       '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'شهر',       '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 أشهر',      '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 أشهر',      '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 أشهر',      '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'شهر',       '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 أشهر',      '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'سنة',        '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 سنوات',       '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'سنة',        '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 سنوات',       '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'في ثوان',  'prefix');\n    assert.equal(moment(0).from(30000), 'منذ ثوان', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'منذ ثوان',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'في ثوان', 'in a few seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), 'في 5 أيام', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'اليوم على الساعة 12:00',     'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'اليوم على الساعة 12:25',     'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'اليوم على الساعة 13:00',     'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'غدا على الساعة 12:00',      'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'اليوم على الساعة 11:00',     'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'أمس على الساعة 12:00',     'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('dddd [على الساعة] LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd [على الساعة] LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd [على الساعة] LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('dddd [على الساعة] LT'),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd [على الساعة] LT'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd [على الساعة] LT'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2011, 11, 31]).format('w ww wo'), '1 01 1', 'Dec 31 2011 should be week 1');\n    assert.equal(moment([2012,  0,  6]).format('w ww wo'), '1 01 1', 'Jan  6 2012 should be week 1');\n    assert.equal(moment([2012,  0,  7]).format('w ww wo'), '2 02 2', 'Jan  7 2012 should be week 2');\n    assert.equal(moment([2012,  0, 13]).format('w ww wo'), '2 02 2', 'Jan 13 2012 should be week 2');\n    assert.equal(moment([2012,  0, 14]).format('w ww wo'), '3 03 3', 'Jan 14 2012 should be week 3');\n});\n\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/test/locale/ar-sa.js",
    "content": "import {localeModule, test} from '../qunit';\nimport moment from '../../moment';\nlocaleModule('ar-sa');\n\ntest('parse', function (assert) {\n    var tests = 'يناير:يناير_فبراير:فبراير_مارس:مارس_أبريل:أبريل_مايو:مايو_يونيو:يونيو_يوليو:يوليو_أغسطس:أغسطس_سبتمبر:سبتمبر_أكتوبر:أكتوبر_نوفمبر:نوفمبر_ديسمبر:ديسمبر'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1) + ' instead is month ' + moment(input, mmm).month());\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(':');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, MMMM Do YYYY, h:mm:ss a',      'الأحد، فبراير ١٤ ٢٠١٠، ٣:٢٥:٥٠ م'],\n            ['ddd, hA',                            'أحد، ٣م'],\n            ['M Mo MM MMMM MMM',                   '٢ ٢ ٠٢ فبراير فبراير'],\n            ['YYYY YY',                            '٢٠١٠ ١٠'],\n            ['D Do DD',                            '١٤ ١٤ ١٤'],\n            ['d do dddd ddd dd',                   '٠ ٠ الأحد أحد ح'],\n            ['DDD DDDo DDDD',                      '٤٥ ٤٥ ٠٤٥'],\n            ['w wo ww',                            '٨ ٨ ٠٨'],\n            ['h hh',                               '٣ ٠٣'],\n            ['H HH',                               '١٥ ١٥'],\n            ['m mm',                               '٢٥ ٢٥'],\n            ['s ss',                               '٥٠ ٥٠'],\n            ['a A',                                'م م'],\n            ['[the] DDDo [day of the year]',       'the ٤٥ day of the year'],\n            ['LT',                                 '١٥:٢٥'],\n            ['LTS',                                '١٥:٢٥:٥٠'],\n            ['L',                                  '١٤/٠٢/٢٠١٠'],\n            ['LL',                                 '١٤ فبراير ٢٠١٠'],\n            ['LLL',                                '١٤ فبراير ٢٠١٠ ١٥:٢٥'],\n            ['LLLL',                               'الأحد ١٤ فبراير ٢٠١٠ ١٥:٢٥'],\n            ['l',                                  '١٤/٢/٢٠١٠'],\n            ['ll',                                 '١٤ فبراير ٢٠١٠'],\n            ['lll',                                '١٤ فبراير ٢٠١٠ ١٥:٢٥'],\n            ['llll',                               'أحد ١٤ فبراير ٢٠١٠ ١٥:٢٥']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '١', '1');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '٢', '2');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '٣', '3');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '٤', '4');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '٥', '5');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '٦', '6');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '٧', '7');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '٨', '8');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '٩', '9');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '١٠', '10');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '١١', '11');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '١٢', '12');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '١٣', '13');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '١٤', '14');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '١٥', '15');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '١٦', '16');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '١٧', '17');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '١٨', '18');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '١٩', '19');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '٢٠', '20');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '٢١', '21');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '٢٢', '22');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '٢٣', '23');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '٢٤', '24');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '٢٥', '25');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '٢٦', '26');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '٢٧', '27');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '٢٨', '28');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '٢٩', '29');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '٣٠', '30');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '٣١', '31');\n});\n\ntest('format month', function (assert) {\n    var expected = 'يناير يناير_فبراير فبراير_مارس مارس_أبريل أبريل_مايو مايو_يونيو يونيو_يوليو يوليو_أغسطس أغسطس_سبتمبر سبتمبر_أكتوبر أكتوبر_نوفمبر نوفمبر_ديسمبر ديسمبر'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'الأحد أحد ح_الإثنين إثنين ن_الثلاثاء ثلاثاء ث_الأربعاء أربعاء ر_الخميس خميس خ_الجمعة جمعة ج_السبت سبت س'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'ثوان', '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'دقيقة',      '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'دقيقة',      '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '٢ دقائق',     '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '٤٤ دقائق',    '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'ساعة',       '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'ساعة',       '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '٢ ساعات',       '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '٥ ساعات',       '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '٢١ ساعات',      '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'يوم',         '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'يوم',         '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '٢ أيام',        '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'يوم',         '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '٥ أيام',        '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '٢٥ أيام',       '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'شهر',       '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'شهر',       '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'شهر',       '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '٢ أشهر',      '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '٢ أشهر',      '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '٣ أشهر',      '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'شهر',       '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '٥ أشهر',      '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'سنة',        '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '٢ سنوات',       '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'سنة',        '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '٥ سنوات',       '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'في ثوان',  'prefix');\n    assert.equal(moment(0).from(30000), 'منذ ثوان', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'منذ ثوان',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'في ثوان', 'in a few seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), 'في ٥ أيام', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'اليوم على الساعة ١٢:٠٠',     'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'اليوم على الساعة ١٢:٢٥',     'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'اليوم على الساعة ١٣:٠٠',     'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'غدا على الساعة ١٢:٠٠',       'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'اليوم على الساعة ١١:٠٠',     'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'أمس على الساعة ١٢:٠٠',      'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('dddd [على الساعة] LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd [على الساعة] LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd [على الساعة] LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('dddd [على الساعة] LT'),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd [على الساعة] LT'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd [على الساعة] LT'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('weeks year starting wednesday custom', function (assert) {\n    assert.equal(moment('2003 1 6', 'gggg w d').format('YYYY-MM-DD'), '٢٠٠٣-٠١-٠٤', '2003 1 6 : gggg w d');\n    assert.equal(moment('2003 1 0', 'gggg w e').format('YYYY-MM-DD'), '٢٠٠٢-١٢-٢٩', '2003 1 0 : gggg w e');\n    assert.equal(moment('2003 1 6', 'gggg w d').format('gggg w d'), '٢٠٠٣ ١ ٦', '2003 1 6 : gggg w d');\n    assert.equal(moment('2003 1 0', 'gggg w e').format('gggg w e'), '٢٠٠٣ ١ ٠', '2003 1 0 : gggg w e');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2011, 11, 31]).format('w ww wo'), '٥٣ ٥٣ ٥٣', '2011 11 31');\n    assert.equal(moment([2012,  0,  6]).format('w ww wo'), '١ ٠١ ١', '2012 0 6');\n    assert.equal(moment([2012,  0,  7]).format('w ww wo'), '١ ٠١ ١', '2012 0 7');\n    assert.equal(moment([2012,  0, 13]).format('w ww wo'), '٢ ٠٢ ٢', '2012 0 13');\n    assert.equal(moment([2012,  0, 14]).format('w ww wo'), '٢ ٠٢ ٢', '2012 0 14');\n});\n\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/test/locale/ar-tn.js",
    "content": "import {localeModule, test} from '../qunit';\nimport moment from '../../moment';\nlocaleModule('ar-tn');\n\ntest('parse', function (assert) {\n    var tests = 'جانفي:جانفي_فيفري:فيفري_مارس:مارس_أفريل:أفريل_ماي:ماي_جوان:جوان_جويلية:جويلية_أوت:أوت_سبتمبر:سبتمبر_أكتوبر:أكتوبر_نوفمبر:نوفمبر_ديسمبر:ديسمبر'.split('_'),\n        i;\n\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(':');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, MMMM Do YYYY, h:mm:ss a', 'الأحد, فيفري 14 2010, 3:25:50 pm'],\n            ['ddd, hA', 'أحد, 3PM'],\n            ['M Mo MM MMMM MMM', '2 2 02 فيفري فيفري'],\n            ['YYYY YY', '2010 10'],\n            ['D Do DD', '14 14 14'],\n            ['d do dddd ddd dd', '0 0 الأحد أحد ح'],\n            ['DDD DDDo DDDD', '45 45 045'],\n            ['w wo ww', '6 6 06'],\n            ['h hh', '3 03'],\n            ['H HH', '15 15'],\n            ['m mm', '25 25'],\n            ['s ss', '50 50'],\n            ['a A', 'pm PM'],\n            ['[the] DDDo [day of the year]', 'the 45 day of the year'],\n            ['LT', '15:25'],\n            ['LTS', '15:25:50'],\n            ['L', '14/02/2010'],\n            ['LL', '14 فيفري 2010'],\n            ['LLL', '14 فيفري 2010 15:25'],\n            ['LLLL', 'الأحد 14 فيفري 2010 15:25'],\n            ['l', '14/2/2010'],\n            ['ll', '14 فيفري 2010'],\n            ['lll', '14 فيفري 2010 15:25'],\n            ['llll', 'أحد 14 فيفري 2010 15:25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1', '1');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2', '2');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3', '3');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4', '4');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5', '5');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6', '6');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7', '7');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8', '8');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9', '9');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10', '10');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11', '11');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12', '12');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13', '13');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14', '14');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15', '15');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16', '16');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17', '17');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18', '18');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19', '19');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20', '20');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21', '21');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22', '22');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23', '23');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24', '24');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25', '25');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26', '26');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27', '27');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28', '28');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29', '29');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30', '30');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31', '31');\n});\n\ntest('format month', function (assert) {\n    var expected = 'جانفي جانفي_فيفري فيفري_مارس مارس_أفريل أفريل_ماي ماي_جوان جوان_جويلية جويلية_أوت أوت_سبتمبر سبتمبر_أكتوبر أكتوبر_نوفمبر نوفمبر_ديسمبر ديسمبر'.split('_'),\n        i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'الأحد أحد ح_الإثنين إثنين ن_الثلاثاء ثلاثاء ث_الأربعاء أربعاء ر_الخميس خميس خ_الجمعة جمعة ج_السبت سبت س'.split('_'),\n        i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({\n        s: 44\n    }), true), 'ثوان', '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({\n        s: 45\n    }), true), 'دقيقة', '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({\n        s: 89\n    }), true), 'دقيقة', '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({\n        s: 90\n    }), true), '2 دقائق', '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({\n        m: 44\n    }), true), '44 دقائق', '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({\n        m: 45\n    }), true), 'ساعة', '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({\n        m: 89\n    }), true), 'ساعة', '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({\n        m: 90\n    }), true), '2 ساعات', '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({\n        h: 5\n    }), true), '5 ساعات', '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({\n        h: 21\n    }), true), '21 ساعات', '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({\n        h: 22\n    }), true), 'يوم', '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({\n        h: 35\n    }), true), 'يوم', '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({\n        h: 36\n    }), true), '2 أيام', '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({\n        d: 1\n    }), true), 'يوم', '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({\n        d: 5\n    }), true), '5 أيام', '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({\n        d: 25\n    }), true), '25 أيام', '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({\n        d: 26\n    }), true), 'شهر', '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({\n        d: 30\n    }), true), 'شهر', '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({\n        d: 43\n    }), true), 'شهر', '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({\n        d: 46\n    }), true), '2 أشهر', '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({\n        d: 74\n    }), true), '2 أشهر', '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({\n        d: 76\n    }), true), '3 أشهر', '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({\n        M: 1\n    }), true), 'شهر', '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({\n        M: 5\n    }), true), '5 أشهر', '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({\n        d: 345\n    }), true), 'سنة', '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({\n        d: 548\n    }), true), '2 سنوات', '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({\n        y: 1\n    }), true), 'سنة', '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({\n        y: 5\n    }), true), '5 سنوات', '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'في ثوان', 'prefix');\n    assert.equal(moment(0).from(30000), 'منذ ثوان', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'منذ ثوان', 'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({\n        s: 30\n    }).fromNow(), 'في ثوان', 'in a few seconds');\n    assert.equal(moment().add({\n        d: 5\n    }).fromNow(), 'في 5 أيام', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                  'اليوم على الساعة 12:00', 'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),     'اليوم على الساعة 12:25', 'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),      'اليوم على الساعة 13:00', 'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),      'غدا على الساعة 12:00',  'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(), 'اليوم على الساعة 11:00', 'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(), 'أمس على الساعة 12:00',  'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({\n            d: i\n        });\n        assert.equal(m.calendar(), m.format('dddd [على الساعة] LT'), 'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(), m.format('dddd [على الساعة] LT'), 'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(), m.format('dddd [على الساعة] LT'), 'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({\n            d: i\n        });\n        assert.equal(m.calendar(), m.format('dddd [على الساعة] LT'), 'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(), m.format('dddd [على الساعة] LT'), 'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(), m.format('dddd [على الساعة] LT'), 'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({\n            w: 1\n        }),\n        weeksFromNow = moment().add({\n            w: 1\n        });\n\n    assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '1 week ago');\n    assert.equal(weeksFromNow.calendar(), weeksFromNow.format('L'), 'in 1 week');\n\n    weeksAgo = moment().subtract({\n        w: 2\n    });\n    weeksFromNow = moment().add({\n        w: 2\n    });\n\n    assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(), weeksFromNow.format('L'), 'in 2 weeks');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2012, 0,  1]).format('w ww wo'), '52 52 52', 'Jan  1 2012 should be week 52');\n    assert.equal(moment([2012, 0,  2]).format('w ww wo'), '1 01 1', 'Jan  2 2012 should be week 1');\n    assert.equal(moment([2012, 0,  8]).format('w ww wo'), '1 01 1', 'Jan  8 2012 should be week 1');\n    assert.equal(moment([2012, 0,  9]).format('w ww wo'),   '2 02 2', 'Jan  9 2012 should be week 2');\n    assert.equal(moment([2012, 0, 15]).format('w ww wo'),   '2 02 2', 'Jan 15 2012 should be week 2');\n});\n\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/test/locale/ar.js",
    "content": "import {localeModule, test} from '../qunit';\nimport moment from '../../moment';\nlocaleModule('ar');\n\nvar months = [\n    'كانون الثاني يناير',\n    'شباط فبراير',\n    'آذار مارس',\n    'نيسان أبريل',\n    'أيار مايو',\n    'حزيران يونيو',\n    'تموز يوليو',\n    'آب أغسطس',\n    'أيلول سبتمبر',\n    'تشرين الأول أكتوبر',\n    'تشرين الثاني نوفمبر',\n    'كانون الأول ديسمبر'\n];\n\ntest('parse', function (assert) {\n    var tests = months, i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1) + ' instead is month ' + moment(input, mmm).month());\n    }\n    for (i = 0; i < 12; i++) {\n        equalTest(tests[i], 'MMM', i);\n        equalTest(tests[i], 'MMM', i);\n        equalTest(tests[i], 'MMMM', i);\n        equalTest(tests[i], 'MMMM', i);\n        equalTest(tests[i].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, MMMM Do YYYY, h:mm:ss a',      'الأحد، شباط فبراير ١٤ ٢٠١٠، ٣:٢٥:٥٠ م'],\n            ['ddd, hA',                            'أحد، ٣م'],\n            ['M Mo MM MMMM MMM',                   '٢ ٢ ٠٢ شباط فبراير شباط فبراير'],\n            ['YYYY YY',                            '٢٠١٠ ١٠'],\n            ['D Do DD',                            '١٤ ١٤ ١٤'],\n            ['d do dddd ddd dd',                   '٠ ٠ الأحد أحد ح'],\n            ['DDD DDDo DDDD',                      '٤٥ ٤٥ ٠٤٥'],\n            ['w wo ww',                            '٨ ٨ ٠٨'],\n            ['h hh',                               '٣ ٠٣'],\n            ['H HH',                               '١٥ ١٥'],\n            ['m mm',                               '٢٥ ٢٥'],\n            ['s ss',                               '٥٠ ٥٠'],\n            ['a A',                                'م م'],\n            ['[the] DDDo [day of the year]',       'the ٤٥ day of the year'],\n            ['LT',                                 '١٥:٢٥'],\n            ['LTS',                                '١٥:٢٥:٥٠'],\n            ['L',                                  '١٤/\\u200f٢/\\u200f٢٠١٠'],\n            ['LL',                                 '١٤ شباط فبراير ٢٠١٠'],\n            ['LLL',                                '١٤ شباط فبراير ٢٠١٠ ١٥:٢٥'],\n            ['LLLL',                               'الأحد ١٤ شباط فبراير ٢٠١٠ ١٥:٢٥'],\n            ['l',                                  '١٤/\\u200f٢/\\u200f٢٠١٠'],\n            ['ll',                                 '١٤ شباط فبراير ٢٠١٠'],\n            ['lll',                                '١٤ شباط فبراير ٢٠١٠ ١٥:٢٥'],\n            ['llll',                               'أحد ١٤ شباط فبراير ٢٠١٠ ١٥:٢٥']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '١', '1');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '٢', '2');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '٣', '3');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '٤', '4');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '٥', '5');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '٦', '6');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '٧', '7');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '٨', '8');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '٩', '9');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '١٠', '10');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '١١', '11');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '١٢', '12');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '١٣', '13');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '١٤', '14');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '١٥', '15');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '١٦', '16');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '١٧', '17');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '١٨', '18');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '١٩', '19');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '٢٠', '20');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '٢١', '21');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '٢٢', '22');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '٢٣', '23');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '٢٤', '24');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '٢٥', '25');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '٢٦', '26');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '٢٧', '27');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '٢٨', '28');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '٢٩', '29');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '٣٠', '30');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '٣١', '31');\n});\n\ntest('format month', function (assert) {\n    var expected = months, i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM'), expected[i], expected[i]);\n        assert.equal(moment([2011, i, 1]).format('MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'الأحد أحد ح_الإثنين إثنين ن_الثلاثاء ثلاثاء ث_الأربعاء أربعاء ر_الخميس خميس خ_الجمعة جمعة ج_السبت سبت س'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  '٤٤ ثانية', '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'دقيقة واحدة',      '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'دقيقة واحدة',      '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  'دقيقتان',     '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '٤٤ دقيقة',    '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'ساعة واحدة',       '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'ساعة واحدة',       '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  'ساعتان',       '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '٥ ساعات',       '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '٢١ ساعة',      '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'يوم واحد',         '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'يوم واحد',         '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  'يومان',        '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'يوم واحد',         '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '٥ أيام',        '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '٢٥ يومًا',       '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'شهر واحد',       '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'شهر واحد',       '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'شهر واحد',       '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  'شهران',      '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  'شهران',      '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '٣ أشهر',      '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'شهر واحد',       '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '٥ أشهر',      '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'عام واحد',        '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), 'عامان',       '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'عام واحد',        '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '٥ أعوام',       '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'بعد ٣٠ ثانية',  'prefix');\n    assert.equal(moment(0).from(30000), 'منذ ٣٠ ثانية', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'منذ ثانية واحدة',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'بعد ٣٠ ثانية', 'in a few seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), 'بعد ٥ أيام', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'اليوم عند الساعة ١٢:٠٠',     'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'اليوم عند الساعة ١٢:٢٥',     'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'اليوم عند الساعة ١٣:٠٠',     'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'غدًا عند الساعة ١٢:٠٠',      'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'اليوم عند الساعة ١١:٠٠',     'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'أمس عند الساعة ١٢:٠٠',       'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('dddd [عند الساعة] LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd [عند الساعة] LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd [عند الساعة] LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('dddd [عند الساعة] LT'),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd [عند الساعة] LT'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd [عند الساعة] LT'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('weeks year starting wednesday custom', function (assert) {\n    assert.equal(moment('2003 1 6', 'gggg w d').format('YYYY-MM-DD'), '٢٠٠٢-١٢-٢٨', 'Week 1 of 2003 should be Dec 28 2002');\n    assert.equal(moment('2003 1 0', 'gggg w e').format('YYYY-MM-DD'), '٢٠٠٢-١٢-٢٨', 'Week 1 of 2003 should be Dec 28 2002');\n    assert.equal(moment('2003 1 6', 'gggg w d').format('gggg w d'), '٢٠٠٣ ١ ٦', 'Saturday of week 1 of 2003 parsed should be formatted as 2003 1 6');\n    assert.equal(moment('2003 1 0', 'gggg w e').format('gggg w e'), '٢٠٠٣ ١ ٠', '1st day of week 1 of 2003 parsed should be formatted as 2003 1 0');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2011, 11, 31]).format('w ww wo'), '١ ٠١ ١', 'Dec 31 2011 should be week 1');\n    assert.equal(moment([2012,  0,  6]).format('w ww wo'), '١ ٠١ ١', 'Jan  6 2012 should be week 1');\n    assert.equal(moment([2012,  0,  7]).format('w ww wo'), '٢ ٠٢ ٢', 'Jan  7 2012 should be week 2');\n    assert.equal(moment([2012,  0, 13]).format('w ww wo'), '٢ ٠٢ ٢', 'Jan 13 2012 should be week 2');\n    assert.equal(moment([2012,  0, 14]).format('w ww wo'), '٣ ٠٣ ٣', 'Jan 14 2012 should be week 3');\n});\n\ntest('no leading zeros in long date formats', function (assert) {\n    var i, j, longDateStr, shortDateStr;\n    for (i = 1; i <= 9; ++i) {\n        for (j = 1; j <= 9; ++j) {\n            longDateStr = moment([2014, i, j]).format('L');\n            shortDateStr = moment([2014, i, j]).format('l');\n            assert.equal(longDateStr, shortDateStr, 'should not have leading zeros in month or day');\n        }\n    }\n});\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/test/locale/az.js",
    "content": "import {localeModule, test} from '../qunit';\nimport moment from '../../moment';\nlocaleModule('az');\n\ntest('parse', function (assert) {\n    var tests = 'yanvar yan_fevral fev_mart mar_Aprel apr_may may_iyun iyn_iyul iyl_Avqust avq_sentyabr sen_oktyabr okt_noyabr noy_dekabr dek'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, D MMMM YYYY, HH:mm:ss',        'Bazar, 14 fevral 2010, 15:25:50'],\n            ['ddd, A h',                           'Baz, gündüz 3'],\n            ['M Mo MM MMMM MMM',                   '2 2-nci 02 fevral fev'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14-üncü 14'],\n            ['d do dddd ddd dd',                   '0 0-ıncı Bazar Baz Bz'],\n            ['DDD DDDo DDDD',                      '45 45-inci 045'],\n            ['w wo ww',                            '7 7-nci 07'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'gündüz gündüz'],\n            ['[ilin] DDDo [günü]',                 'ilin 45-inci günü'],\n            ['LT',                                 '15:25'],\n            ['LTS',                                '15:25:50'],\n            ['L',                                  '14.02.2010'],\n            ['LL',                                 '14 fevral 2010'],\n            ['LLL',                                '14 fevral 2010 15:25'],\n            ['LLLL',                               'Bazar, 14 fevral 2010 15:25'],\n            ['l',                                  '14.2.2010'],\n            ['ll',                                 '14 fev 2010'],\n            ['lll',                                '14 fev 2010 15:25'],\n            ['llll',                               'Baz, 14 fev 2010 15:25']\n        ],\n        DDDo = [\n            [359, '360-ıncı'],\n            [199, '200-üncü'],\n            [149, '150-nci']\n        ],\n        dt = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        DDDoDt,\n        i;\n\n    for (i = 0; i < a.length; i++) {\n        assert.equal(dt.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n    for (i = 0; i < DDDo.length; i++) {\n        DDDoDt = moment([2010]);\n        assert.equal(DDDoDt.add(DDDo[i][0], 'days').format('DDDo'), DDDo[i][1], DDDo[i][0] + ' ---> ' + DDDo[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1-inci', '1st');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2-nci', '2nd');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3-üncü', '3rd');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4-üncü', '4th');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5-inci', '5th');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6-ncı', '6th');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7-nci', '7th');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8-inci', '8th');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9-uncu', '9th');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10-uncu', '10th');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11-inci', '11th');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12-nci', '12th');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13-üncü', '13th');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14-üncü', '14th');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15-inci', '15th');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16-ncı', '16th');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17-nci', '17th');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18-inci', '18th');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19-uncu', '19th');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20-nci', '20th');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21-inci', '21th');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22-nci', '22th');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23-üncü', '23th');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24-üncü', '24th');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25-inci', '25th');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26-ncı', '26th');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27-nci', '27th');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28-inci', '28th');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29-uncu', '29th');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30-uncu', '30th');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31-inci', '31st');\n});\n\ntest('format month', function (assert) {\n    var expected = 'yanvar yan_fevral fev_mart mar_aprel apr_may may_iyun iyn_iyul iyl_avqust avq_sentyabr sen_oktyabr okt_noyabr noy_dekabr dek'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'Bazar Baz Bz_Bazar ertəsi BzE BE_Çərşənbə axşamı ÇAx ÇA_Çərşənbə Çər Çə_Cümə axşamı CAx CA_Cümə Cüm Cü_Şənbə Şən Şə'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'birneçə saniyyə', '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'bir dəqiqə',      '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'bir dəqiqə',      '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 dəqiqə',     '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 dəqiqə',    '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'bir saat',       '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'bir saat',       '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 saat',       '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 saat',       '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 saat',      '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'bir gün',         '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'bir gün',         '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 gün',        '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'bir gün',         '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 gün',        '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 gün',       '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'bir ay',       '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'bir ay',       '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 ay',      '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 ay',      '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 ay',      '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'bir ay',       '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 ay',      '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'bir il',        '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 il',       '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'bir il',        '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 il',       '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'birneçə saniyyə sonra',  'prefix');\n    assert.equal(moment(0).from(30000), 'birneçə saniyyə əvvəl', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'birneçə saniyyə əvvəl',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'birneçə saniyyə sonra', 'in a few seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), '5 gün sonra', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'bugün saat 12:00',     'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'bugün saat 12:25',     'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'bugün saat 13:00',     'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'sabah saat 12:00',     'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'bugün saat 11:00',     'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'dünən 12:00',          'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('[gələn həftə] dddd [saat] LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[gələn həftə] dddd [saat] LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[gələn həftə] dddd [saat] LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('[keçən həftə] dddd [saat] LT'),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[keçən həftə] dddd [saat] LT'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[keçən həftə] dddd [saat] LT'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2011, 11, 26]).format('w ww wo'), '1 01 1-inci', 'Dec 26 2011 should be week 1');\n    assert.equal(moment([2012,  0,  1]).format('w ww wo'), '1 01 1-inci', 'Jan  1 2012 should be week 1');\n    assert.equal(moment([2012,  0,  2]).format('w ww wo'), '2 02 2-nci', 'Jan  2 2012 should be week 2');\n    assert.equal(moment([2012,  0,  8]).format('w ww wo'), '2 02 2-nci', 'Jan  8 2012 should be week 2');\n    assert.equal(moment([2012,  0,  9]).format('w ww wo'), '3 03 3-üncü', 'Jan  9 2012 should be week 3');\n});\n\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/test/locale/be.js",
    "content": "import {localeModule, test} from '../qunit';\nimport moment from '../../moment';\nlocaleModule('be');\n\ntest('parse', function (assert) {\n    var tests = 'студзень студ_люты лют_сакавік сак_красавік крас_травень трав_чэрвень чэрв_ліпень ліп_жнівень жнів_верасень вер_кастрычнік каст_лістапад ліст_снежань снеж'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, Do MMMM YYYY, HH:mm:ss',       'нядзеля, 14-га лютага 2010, 15:25:50'],\n            ['ddd, h A',                           'нд, 3 дня'],\n            ['M Mo MM MMMM MMM',                   '2 2-і 02 люты лют'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14-га 14'],\n            ['d do dddd ddd dd',                   '0 0-ы нядзеля нд нд'],\n            ['DDD DDDo DDDD',                      '45 45-ы 045'],\n            ['w wo ww',                            '7 7-ы 07'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'дня дня'],\n            ['DDDo [дзень года]',                   '45-ы дзень года'],\n            ['LT',                                 '15:25'],\n            ['LTS',                                '15:25:50'],\n            ['L',                                  '14.02.2010'],\n            ['LL',                                 '14 лютага 2010 г.'],\n            ['LLL',                                '14 лютага 2010 г., 15:25'],\n            ['LLLL',                               'нядзеля, 14 лютага 2010 г., 15:25'],\n            ['l',                                  '14.2.2010'],\n            ['ll',                                 '14 лют 2010 г.'],\n            ['lll',                                '14 лют 2010 г., 15:25'],\n            ['llll',                               'нд, 14 лют 2010 г., 15:25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format meridiem', function (assert) {\n    assert.equal(moment([2012, 11, 28, 0, 0]).format('A'), 'ночы', 'night');\n    assert.equal(moment([2012, 11, 28, 3, 59]).format('A'), 'ночы', 'night');\n    assert.equal(moment([2012, 11, 28, 4, 0]).format('A'), 'раніцы', 'morning');\n    assert.equal(moment([2012, 11, 28, 11, 59]).format('A'), 'раніцы', 'morning');\n    assert.equal(moment([2012, 11, 28, 12, 0]).format('A'), 'дня', 'afternoon');\n    assert.equal(moment([2012, 11, 28, 16, 59]).format('A'), 'дня', 'afternoon');\n    assert.equal(moment([2012, 11, 28, 17, 0]).format('A'), 'вечара', 'evening');\n    assert.equal(moment([2012, 11, 28, 23, 59]).format('A'), 'вечара', 'evening');\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1-ы', '1-ы');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2-і', '2-і');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3-і', '3-і');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4-ы', '4-ы');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5-ы', '5-ы');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6-ы', '6-ы');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7-ы', '7-ы');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8-ы', '8-ы');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9-ы', '9-ы');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10-ы', '10-ы');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11-ы', '11-ы');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12-ы', '12-ы');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13-ы', '13-ы');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14-ы', '14-ы');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15-ы', '15-ы');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16-ы', '16-ы');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17-ы', '17-ы');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18-ы', '18-ы');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19-ы', '19-ы');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20-ы', '20-ы');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21-ы', '21-ы');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22-і', '22-і');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23-і', '23-і');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24-ы', '24-ы');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25-ы', '25-ы');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26-ы', '26-ы');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27-ы', '27-ы');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28-ы', '28-ы');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29-ы', '29-ы');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30-ы', '30-ы');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31-ы', '31-ы');\n});\n\ntest('format month', function (assert) {\n    var expected = 'студзень студ_люты лют_сакавік сак_красавік крас_травень трав_чэрвень чэрв_ліпень ліп_жнівень жнів_верасень вер_кастрычнік каст_лістапад ліст_снежань снеж'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format month case', function (assert) {\n    var months = {\n        'nominative': 'студзень_люты_сакавік_красавік_травень_чэрвень_ліпень_жнівень_верасень_кастрычнік_лістапад_снежань'.split('_'),\n        'accusative': 'студзеня_лютага_сакавіка_красавіка_траўня_чэрвеня_ліпеня_жніўня_верасня_кастрычніка_лістапада_снежня'.split('_')\n    }, i;\n    for (i = 0; i < 12; i++) {\n        assert.equal(moment([2011, i, 1]).format('D MMMM'), '1 ' + months.accusative[i], '1 ' + months.accusative[i]);\n        assert.equal(moment([2011, i, 1]).format('MMMM'), months.nominative[i], '1 ' + months.nominative[i]);\n    }\n});\n\ntest('format month case with escaped symbols', function (assert) {\n    var months = {\n        'nominative': 'студзень_люты_сакавік_красавік_травень_чэрвень_ліпень_жнівень_верасень_кастрычнік_лістапад_снежань'.split('_'),\n        'accusative': 'студзеня_лютага_сакавіка_красавіка_траўня_чэрвеня_ліпеня_жніўня_верасня_кастрычніка_лістапада_снежня'.split('_')\n    }, i;\n    for (i = 0; i < 12; i++) {\n        assert.equal(moment([2013, i, 1]).format('D[] MMMM'), '1 ' + months.accusative[i], '1 ' + months.accusative[i]);\n        assert.equal(moment([2013, i, 1]).format('[<i>]D[</i>] [<b>]MMMM[</b>]'), '<i>1</i> <b>' + months.accusative[i] + '</b>', '1 <b>' + months.accusative[i] + '</b>');\n        assert.equal(moment([2013, i, 1]).format('D[-ы дзень] MMMM'), '1-ы дзень ' + months.accusative[i], '1-ы дзень ' + months.accusative[i]);\n        assert.equal(moment([2013, i, 1]).format('D, MMMM'), '1, ' + months.nominative[i], '1, ' + months.nominative[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'нядзеля нд нд_панядзелак пн пн_аўторак ат ат_серада ср ср_чацвер чц чц_пятніца пт пт_субота сб сб'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'некалькі секунд',    '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'хвіліна',   '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'хвіліна',   '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 хвіліны',  '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 31}), true),  '31 хвіліна',  '31 minutes = 31 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 хвіліны', '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'гадзіна',    '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'гадзіна',    '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 гадзіны',    '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 гадзін',    '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 гадзіна',   '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'дзень',      '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'дзень',      '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 дні',     '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'дзень',      '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 дзён',     '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 11}), true),  '11 дзён',     '11 days = 11 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 21}), true),  '21 дзень',     '21 days = 21 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 дзён',    '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'месяц',    '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'месяц',    '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'месяц',    '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 месяцы',   '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 месяцы',   '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 месяцы',   '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'месяц',    '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 месяцаў',   '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'год',     '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 гады',    '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'год',     '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 гадоў',    '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'праз некалькі секунд', 'prefix');\n    assert.equal(moment(0).from(30000), 'некалькі секунд таму', 'suffix');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'праз некалькі секунд', 'in a few seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), 'праз 5 дзён', 'in 5 days');\n    assert.equal(moment().add({m: 31}).fromNow(), 'праз 31 хвіліну', 'in 31 minutes = in 31 minutes');\n    assert.equal(moment().subtract({m: 31}).fromNow(), '31 хвіліну таму', '31 minutes ago = 31 minutes ago');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'Сёння ў 12:00',     'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'Сёння ў 12:25',     'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'Сёння ў 13:00',     'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'Заўтра ў 12:00',    'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'Сёння ў 11:00',     'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'Учора ў 12:00',     'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    function makeFormat(d) {\n        return '[У] dddd [ў] LT';\n    }\n\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format(makeFormat(m)),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format(makeFormat(m)),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format(makeFormat(m)),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n\n    function makeFormat(d) {\n        switch (d.day()) {\n            case 0:\n            case 3:\n            case 5:\n            case 6:\n                return '[У мінулую] dddd [ў] LT';\n            case 1:\n            case 2:\n            case 4:\n                return '[У мінулы] dddd [ў] LT';\n        }\n    }\n\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format(makeFormat(m)),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format(makeFormat(m)),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format(makeFormat(m)),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2011, 11, 26]).format('w ww wo'), '1 01 1-ы', 'Dec 26 2011 should be week 1');\n    assert.equal(moment([2012,  0,  1]).format('w ww wo'), '1 01 1-ы', 'Jan  1 2012 should be week 1');\n    assert.equal(moment([2012,  0,  2]).format('w ww wo'), '2 02 2-і', 'Jan  2 2012 should be week 2');\n    assert.equal(moment([2012,  0,  8]).format('w ww wo'), '2 02 2-і', 'Jan  8 2012 should be week 2');\n    assert.equal(moment([2012,  0,  9]).format('w ww wo'), '3 03 3-і', 'Jan  9 2012 should be week 3');\n});\n\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/test/locale/bg.js",
    "content": "import {localeModule, test} from '../qunit';\nimport moment from '../../moment';\nlocaleModule('bg');\n\ntest('parse', function (assert) {\n    var tests = 'януари янр_февруари фев_март мар_април апр_май май_юни юни_юли юли_август авг_септември сеп_октомври окт_ноември ное_декември дек'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, MMMM Do YYYY, H:mm:ss',        'неделя, февруари 14-ти 2010, 15:25:50'],\n            ['ddd, hA',                            'нед, 3PM'],\n            ['M Mo MM MMMM MMM',                   '2 2-ри 02 февруари фев'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14-ти 14'],\n            ['d do dddd ddd dd',                   '0 0-ев неделя нед нд'],\n            ['DDD DDDo DDDD',                      '45 45-ти 045'],\n            ['w wo ww',                            '7 7-ми 07'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'pm PM'],\n            ['[the] DDDo [day of the year]',       'the 45-ти day of the year'],\n            ['LT',                                 '15:25'],\n            ['LTS',                                '15:25:50'],\n            ['L',                                  '14.02.2010'],\n            ['LL',                                 '14 февруари 2010'],\n            ['LLL',                                '14 февруари 2010 15:25'],\n            ['LLLL',                               'неделя, 14 февруари 2010 15:25'],\n            ['l',                                  '14.2.2010'],\n            ['ll',                                 '14 фев 2010'],\n            ['lll',                                '14 фев 2010 15:25'],\n            ['llll',                               'нед, 14 фев 2010 15:25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1-ви', '1-ви');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2-ри', '2-ри');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3-ти', '3-ти');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4-ти', '4-ти');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5-ти', '5-ти');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6-ти', '6-ти');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7-ми', '7-ми');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8-ми', '8-ми');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9-ти', '9-ти');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10-ти', '10-ти');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11-ти', '11-ти');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12-ти', '12-ти');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13-ти', '13-ти');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14-ти', '14-ти');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15-ти', '15-ти');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16-ти', '16-ти');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17-ти', '17-ти');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18-ти', '18-ти');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19-ти', '19-ти');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20-ти', '20-ти');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21-ви', '21-ви');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22-ри', '22-ри');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23-ти', '23-ти');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24-ти', '24-ти');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25-ти', '25-ти');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26-ти', '26-ти');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27-ми', '27-ми');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28-ми', '28-ми');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29-ти', '29-ти');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30-ти', '30-ти');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31-ви', '31-ви');\n});\n\ntest('format month', function (assert) {\n    var expected = 'януари янр_февруари фев_март мар_април апр_май май_юни юни_юли юли_август авг_септември сеп_октомври окт_ноември ное_декември дек'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'неделя нед нд_понеделник пон пн_вторник вто вт_сряда сря ср_четвъртък чет чт_петък пет пт_събота съб сб'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'няколко секунди', '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'минута',          '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'минута',          '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 минути',        '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 минути',       '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'час',             '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'час',             '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 часа',          '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 часа',          '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 часа',         '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'ден',             '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'ден',             '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 дни',           '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'ден',             '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 дни',           '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 дни',          '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'месец',           '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'месец',           '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'месец',           '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 месеца',        '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 месеца',        '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 месеца',        '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'месец',           '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 месеца',        '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'година',          '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 години',        '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'година',          '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 години',        '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'след няколко секунди',  'prefix');\n    assert.equal(moment(0).from(30000), 'преди няколко секунди', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'преди няколко секунди',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'след няколко секунди', 'in a few seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), 'след 5 дни', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'Днес в 12:00',  'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'Днес в 12:25',  'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'Днес в 13:00',  'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'Утре в 12:00',  'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'Днес в 11:00',  'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'Вчера в 12:00', 'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('dddd [в] LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd [в] LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd [в] LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n\n    function makeFormat(d) {\n        switch (d.day()) {\n            case 0:\n            case 3:\n            case 6:\n                return '[В изминалата] dddd [в] LT';\n            case 1:\n            case 2:\n            case 4:\n            case 5:\n                return '[В изминалия] dddd [в] LT';\n        }\n    }\n\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format(makeFormat(m)),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format(makeFormat(m)),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format(makeFormat(m)),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2011, 11, 26]).format('w ww wo'), '1 01 1-ви', 'Dec 26 2011 should be week 1');\n    assert.equal(moment([2012,  0,  1]).format('w ww wo'), '1 01 1-ви', 'Jan  1 2012 should be week 1');\n    assert.equal(moment([2012,  0,  2]).format('w ww wo'), '2 02 2-ри', 'Jan  2 2012 should be week 2');\n    assert.equal(moment([2012,  0,  8]).format('w ww wo'), '2 02 2-ри', 'Jan  8 2012 should be week 2');\n    assert.equal(moment([2012,  0,  9]).format('w ww wo'), '3 03 3-ти', 'Jan  9 2012 should be week 3');\n});\n\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/test/locale/bn.js",
    "content": "import {localeModule, test} from '../qunit';\nimport moment from '../../moment';\nlocaleModule('bn');\n\ntest('parse', function (assert) {\n    var tests = 'জানুয়ারী জানু_ফেব্রুয়ারি ফেব_মার্চ মার্চ_এপ্রিল এপ্র_মে মে_জুন জুন_জুলাই জুল_আগস্ট আগ_সেপ্টেম্বর সেপ্ট_অক্টোবর অক্টো_নভেম্বর নভে_ডিসেম্বর ডিসে'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, Do MMMM YYYY, a h:mm:ss সময়',  'রবিবার, ১৪ ফেব্রুয়ারি ২০১০, দুপুর ৩:২৫:৫০ সময়'],\n            ['ddd, a h সময়',                       'রবি, দুপুর ৩ সময়'],\n            ['M Mo MM MMMM MMM',                   '২ ২ ০২ ফেব্রুয়ারি ফেব'],\n            ['YYYY YY',                            '২০১০ ১০'],\n            ['D Do DD',                            '১৪ ১৪ ১৪'],\n            ['d do dddd ddd dd',                   '০ ০ রবিবার রবি রবি'],\n            ['DDD DDDo DDDD',                      '৪৫ ৪৫ ০৪৫'],\n            ['w wo ww',                            '৮ ৮ ০৮'],\n            ['h hh',                               '৩ ০৩'],\n            ['H HH',                               '১৫ ১৫'],\n            ['m mm',                               '২৫ ২৫'],\n            ['s ss',                               '৫০ ৫০'],\n            ['a A',                                'দুপুর দুপুর'],\n            ['LT',                                 'দুপুর ৩:২৫ সময়'],\n            ['LTS',                                'দুপুর ৩:২৫:৫০ সময়'],\n            ['L',                                  '১৪/০২/২০১০'],\n            ['LL',                                 '১৪ ফেব্রুয়ারি ২০১০'],\n            ['LLL',                                '১৪ ফেব্রুয়ারি ২০১০, দুপুর ৩:২৫ সময়'],\n            ['LLLL',                               'রবিবার, ১৪ ফেব্রুয়ারি ২০১০, দুপুর ৩:২৫ সময়'],\n            ['l',                                  '১৪/২/২০১০'],\n            ['ll',                                 '১৪ ফেব ২০১০'],\n            ['lll',                                '১৪ ফেব ২০১০, দুপুর ৩:২৫ সময়'],\n            ['llll',                               'রবি, ১৪ ফেব ২০১০, দুপুর ৩:২৫ সময়']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '১', '১');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '২', '২');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '৩', '৩');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '৪', '৪');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '৫', '৫');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '৬', '৬');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '৭', '৭');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '৮', '৮');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '৯', '৯');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '১০', '১০');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '১১', '১১');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '১২', '১২');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '১৩', '১৩');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '১৪', '১৪');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '১৫', '১৫');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '১৬', '১৬');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '১৭', '১৭');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '১৮', '১৮');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '১৯', '১৯');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '২০', '২০');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '২১', '২১');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '২২', '২২');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '২৩', '২৩');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '২৪', '২৪');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '২৫', '২৫');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '২৬', '২৬');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '২৭', '২৭');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '২৮', '२৮');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '২৯', '২৯');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '৩০', '৩০');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '৩১', '৩১');\n});\n\ntest('format month', function (assert) {\n    var expected = 'জানুয়ারী জানু_ফেব্রুয়ারি ফেব_মার্চ মার্চ_এপ্রিল এপ্র_মে মে_জুন জুন_জুলাই জুল_আগস্ট আগ_সেপ্টেম্বর সেপ্ট_অক্টোবর অক্টো_নভেম্বর নভে_ডিসেম্বর ডিসে'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'রবিবার রবি রবি_সোমবার সোম সোম_মঙ্গলবার মঙ্গল মঙ্গ_বুধবার বুধ বুধ_বৃহস্পতিবার বৃহস্পতি বৃহঃ_শুক্রবার শুক্র শুক্র_শনিবার শনি শনি'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'কয়েক সেকেন্ড', '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'এক মিনিট',      '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'এক মিনিট',      '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '২ মিনিট',     '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '৪৪ মিনিট',    '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'এক ঘন্টা',       '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'এক ঘন্টা',       '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '২ ঘন্টা',       '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '৫ ঘন্টা',       '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '২১ ঘন্টা',      '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'এক দিন',         '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'এক দিন',         '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '২ দিন',        '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'এক দিন',         '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '৫ দিন',        '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '২৫ দিন',       '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'এক মাস',       '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'এক মাস',       '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '২ মাস',      '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '২ মাস',      '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '৩ মাস',      '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'এক মাস',       '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '৫ মাস',      '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'এক বছর',        '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '২ বছর',       '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'এক বছর',        '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '৫ বছর',       '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'কয়েক সেকেন্ড পরে',  'prefix');\n    assert.equal(moment(0).from(30000), 'কয়েক সেকেন্ড আগে', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'কয়েক সেকেন্ড আগে',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'কয়েক সেকেন্ড পরে', 'কয়েক সেকেন্ড পরে');\n    assert.equal(moment().add({d: 5}).fromNow(), '৫ দিন পরে', '৫ দিন পরে');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'আজ দুপুর ১২:০০ সময়',       'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'আজ দুপুর ১২:২৫ সময়',       'Now plus 25 min');\n    assert.equal(moment(a).add({h: 3}).calendar(),       'আজ দুপুর ৩:০০ সময়',        'Now plus 3 hours');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'আগামীকাল দুপুর ১২:০০ সময়', 'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'আজ দুপুর ১১:০০ সময়',       'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'গতকাল দুপুর ১২:০০ সময়',    'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('dddd[,] LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd[,] LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd[,] LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('[গত] dddd[,] LT'),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[গত] dddd[,] LT'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[গত] dddd[,] LT'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('meridiem', function (assert) {\n    assert.equal(moment([2011, 2, 23,  2, 30]).format('a'), 'রাত', 'before dawn');\n    assert.equal(moment([2011, 2, 23,  9, 30]).format('a'), 'সকাল', 'morning');\n    assert.equal(moment([2011, 2, 23, 14, 30]).format('a'), 'দুপুর', 'during day');\n    assert.equal(moment([2011, 2, 23, 17, 30]).format('a'), 'বিকাল', 'evening');\n    assert.equal(moment([2011, 2, 23, 19, 30]).format('a'), 'বিকাল', 'late evening');\n    assert.equal(moment([2011, 2, 23, 21, 20]).format('a'), 'রাত', 'night');\n\n    assert.equal(moment([2011, 2, 23,  2, 30]).format('A'), 'রাত', 'before dawn');\n    assert.equal(moment([2011, 2, 23,  9, 30]).format('A'), 'সকাল', 'morning');\n    assert.equal(moment([2011, 2, 23, 14, 30]).format('A'), 'দুপুর', ' during day');\n    assert.equal(moment([2011, 2, 23, 17, 30]).format('A'), 'বিকাল', 'evening');\n    assert.equal(moment([2011, 2, 23, 19, 30]).format('A'), 'বিকাল', 'late evening');\n    assert.equal(moment([2011, 2, 23, 21, 20]).format('A'), 'রাত', 'night');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2012, 0,  1]).format('w ww wo'), '১ ০১ ১', 'Jan  1 2012 should be week 1');\n    assert.equal(moment([2012, 0,  7]).format('w ww wo'), '১ ০১ ১', 'Jan  7 2012 should be week 1');\n    assert.equal(moment([2012, 0,  8]).format('w ww wo'), '২ ০২ ২', 'Jan  8 2012 should be week 2');\n    assert.equal(moment([2012, 0, 14]).format('w ww wo'), '২ ০২ ২', 'Jan 14 2012 should be week 2');\n    assert.equal(moment([2012, 0, 15]).format('w ww wo'), '৩ ০৩ ৩', 'Jan 15 2012 should be week 3');\n});\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/test/locale/bo.js",
    "content": "import {localeModule, test} from '../qunit';\nimport moment from '../../moment';\nlocaleModule('bo');\n\ntest('parse', function (assert) {\n    var tests = 'ཟླ་བ་དང་པོ ཟླ་བ་དང་པོ._ཟླ་བ་གཉིས་པ ཟླ་བ་གཉིས་པ_ཟླ་བ་གསུམ་པ ཟླ་བ་གསུམ་པ_ཟླ་བ་བཞི་པ ཟླ་བ་བཞི་པ_ཟླ་བ་ལྔ་པ ཟླ་བ་ལྔ་པ_ཟླ་བ་དྲུག་པ ཟླ་བ་དྲུག་པ_ཟླ་བ་བདུན་པ ཟླ་བ་བདུན་པ_ཟླ་བ་བརྒྱད་པ ཟླ་བ་བརྒྱད་པ_ཟླ་བ་དགུ་པ ཟླ་བ་དགུ་པ_ཟླ་བ་བཅུ་པ ཟླ་བ་བཅུ་པ_ཟླ་བ་བཅུ་གཅིག་པ ཟླ་བ་བཅུ་གཅིག་པ_ཟླ་བ་བཅུ་གཉིས་པ ཟླ་བ་བཅུ་གཉིས་པ'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, Do MMMM YYYY, a h:mm:ss ལ་',  'གཟའ་ཉི་མ་, ༡༤ ཟླ་བ་གཉིས་པ ༢༠༡༠, ཉིན་གུང ༣:༢༥:༥༠ ལ་'],\n            ['ddd, a h ལ་',                       'ཉི་མ་, ཉིན་གུང ༣ ལ་'],\n            ['M Mo MM MMMM MMM',                   '༢ ༢ ༠༢ ཟླ་བ་གཉིས་པ ཟླ་བ་གཉིས་པ'],\n            ['YYYY YY',                            '༢༠༡༠ ༡༠'],\n            ['D Do DD',                            '༡༤ ༡༤ ༡༤'],\n            ['d do dddd ddd dd',                   '༠ ༠ གཟའ་ཉི་མ་ ཉི་མ་ ཉི་མ་'],\n            ['DDD DDDo DDDD',                      '༤༥ ༤༥ ༠༤༥'],\n            ['w wo ww',                            '༨ ༨ ༠༨'],\n            ['h hh',                               '༣ ༠༣'],\n            ['H HH',                               '༡༥ ༡༥'],\n            ['m mm',                               '༢༥ ༢༥'],\n            ['s ss',                               '༥༠ ༥༠'],\n            ['a A',                                'ཉིན་གུང ཉིན་གུང'],\n            ['LT',                                 'ཉིན་གུང ༣:༢༥'],\n            ['LTS',                                'ཉིན་གུང ༣:༢༥:༥༠'],\n            ['L',                                  '༡༤/༠༢/༢༠༡༠'],\n            ['LL',                                 '༡༤ ཟླ་བ་གཉིས་པ ༢༠༡༠'],\n            ['LLL',                                '༡༤ ཟླ་བ་གཉིས་པ ༢༠༡༠, ཉིན་གུང ༣:༢༥'],\n            ['LLLL',                               'གཟའ་ཉི་མ་, ༡༤ ཟླ་བ་གཉིས་པ ༢༠༡༠, ཉིན་གུང ༣:༢༥'],\n            ['l',                                  '༡༤/༢/༢༠༡༠'],\n            ['ll',                                 '༡༤ ཟླ་བ་གཉིས་པ ༢༠༡༠'],\n            ['lll',                                '༡༤ ཟླ་བ་གཉིས་པ ༢༠༡༠, ཉིན་གུང ༣:༢༥'],\n            ['llll',                               'ཉི་མ་, ༡༤ ཟླ་བ་གཉིས་པ ༢༠༡༠, ཉིན་གུང ༣:༢༥']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '༡', '༡');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '༢', '༢');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '༣', '༣');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '༤', '༤');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '༥', '༥');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '༦', '༦');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '༧', '༧');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '༨', '༨');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '༩', '༩');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '༡༠', '༡༠');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '༡༡', '༡༡');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '༡༢', '༡༢');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '༡༣', '༡༣');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '༡༤', '༡༤');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '༡༥', '༡༥');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '༡༦', '༡༦');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '༡༧', '༡༧');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '༡༨', '༡༨');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '༡༩', '༡༩');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '༢༠', '༢༠');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '༢༡', '༢༡');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '༢༢', '༢༢');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '༢༣', '༢༣');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '༢༤', '༢༤');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '༢༥', '༢༥');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '༢༦', '༢༦');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '༢༧', '༢༧');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '༢༨', '༢༨');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '༢༩', '༢༩');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '༣༠', '༣༠');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '༣༡', '༣༡');\n});\n\ntest('format month', function (assert) {\n    var expected = 'ཟླ་བ་དང་པོ ཟླ་བ་དང་པོ_ཟླ་བ་གཉིས་པ ཟླ་བ་གཉིས་པ_ཟླ་བ་གསུམ་པ ཟླ་བ་གསུམ་པ_ཟླ་བ་བཞི་པ ཟླ་བ་བཞི་པ_ཟླ་བ་ལྔ་པ ཟླ་བ་ལྔ་པ_ཟླ་བ་དྲུག་པ ཟླ་བ་དྲུག་པ_ཟླ་བ་བདུན་པ ཟླ་བ་བདུན་པ_ཟླ་བ་བརྒྱད་པ ཟླ་བ་བརྒྱད་པ_ཟླ་བ་དགུ་པ ཟླ་བ་དགུ་པ_ཟླ་བ་བཅུ་པ ཟླ་བ་བཅུ་པ_ཟླ་བ་བཅུ་གཅིག་པ ཟླ་བ་བཅུ་གཅིག་པ_ཟླ་བ་བཅུ་གཉིས་པ ཟླ་བ་བཅུ་གཉིས་པ'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'གཟའ་ཉི་མ་ ཉི་མ་ ཉི་མ་_གཟའ་ཟླ་བ་ ཟླ་བ་ ཟླ་བ་_གཟའ་མིག་དམར་ མིག་དམར་ མིག་དམར་_གཟའ་ལྷག་པ་ ལྷག་པ་ ལྷག་པ་_གཟའ་ཕུར་བུ ཕུར་བུ ཕུར་བུ_གཟའ་པ་སངས་ པ་སངས་ པ་སངས་_གཟའ་སྤེན་པ་ སྤེན་པ་ སྤེན་པ་'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'ལམ་སང', '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'སྐར་མ་གཅིག',      '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'སྐར་མ་གཅིག',      '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '༢ སྐར་མ',     '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '༤༤ སྐར་མ',    '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'ཆུ་ཚོད་གཅིག',       '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'ཆུ་ཚོད་གཅིག',       '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '༢ ཆུ་ཚོད',       '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '༥ ཆུ་ཚོད',       '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '༢༡ ཆུ་ཚོད',      '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'ཉིན་གཅིག',         '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'ཉིན་གཅིག',         '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '༢ ཉིན་',        '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'ཉིན་གཅིག',         '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '༥ ཉིན་',        '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '༢༥ ཉིན་',       '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'ཟླ་བ་གཅིག',       '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'ཟླ་བ་གཅིག',       '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'ཟླ་བ་གཅིག',       '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '༢ ཟླ་བ',      '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '༢ ཟླ་བ',      '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '༣ ཟླ་བ',      '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'ཟླ་བ་གཅིག',       '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '༥ ཟླ་བ',      '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'ལོ་གཅིག',        '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '༢ ལོ',       '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'ལོ་གཅིག',        '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '༥ ལོ',       '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'ལམ་སང ལ་',  'prefix');\n    assert.equal(moment(0).from(30000), 'ལམ་སང སྔན་ལ', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'ལམ་སང སྔན་ལ',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'ལམ་སང ལ་', 'ལམ་སང ལ་');\n    assert.equal(moment().add({d: 5}).fromNow(), '༥ ཉིན་ ལ་', '༥ ཉིན་ ལ་');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'དི་རིང ཉིན་གུང ༡༢:༠༠',  'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'དི་རིང ཉིན་གུང ༡༢:༢༥',  'Now plus 25 min');\n    assert.equal(moment(a).add({h: 3}).calendar(),       'དི་རིང ཉིན་གུང ༣:༠༠',   'Now plus 3 hours');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'སང་ཉིན ཉིན་གུང ༡༢:༠༠',  'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'དི་རིང ཉིན་གུང ༡༡:༠༠',  'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'ཁ་སང ཉིན་གུང ༡༢:༠༠',    'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('[བདུན་ཕྲག་རྗེས་མ][,] LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[བདུན་ཕྲག་རྗེས་མ][,] LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[བདུན་ཕྲག་རྗེས་མ][,] LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('[བདུན་ཕྲག་མཐའ་མ] dddd[,] LT'),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[བདུན་ཕྲག་མཐའ་མ] dddd[,] LT'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[བདུན་ཕྲག་མཐའ་མ] dddd[,] LT'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('meridiem', function (assert) {\n    assert.equal(moment([2011, 2, 23,  2, 30]).format('a'), 'མཚན་མོ', 'before dawn');\n    assert.equal(moment([2011, 2, 23,  9, 30]).format('a'), 'ཞོགས་ཀས', 'morning');\n    assert.equal(moment([2011, 2, 23, 14, 30]).format('a'), 'ཉིན་གུང', 'during day');\n    assert.equal(moment([2011, 2, 23, 17, 30]).format('a'), 'དགོང་དག', 'evening');\n    assert.equal(moment([2011, 2, 23, 19, 30]).format('a'), 'དགོང་དག', 'late evening');\n    assert.equal(moment([2011, 2, 23, 21, 20]).format('a'), 'མཚན་མོ', 'night');\n\n    assert.equal(moment([2011, 2, 23,  2, 30]).format('A'), 'མཚན་མོ', 'before dawn');\n    assert.equal(moment([2011, 2, 23,  9, 30]).format('A'), 'ཞོགས་ཀས', 'morning');\n    assert.equal(moment([2011, 2, 23, 14, 30]).format('A'), 'ཉིན་གུང', ' during day');\n    assert.equal(moment([2011, 2, 23, 17, 30]).format('A'), 'དགོང་དག', 'evening');\n    assert.equal(moment([2011, 2, 23, 19, 30]).format('A'), 'དགོང་དག', 'late evening');\n    assert.equal(moment([2011, 2, 23, 21, 20]).format('A'), 'མཚན་མོ', 'night');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2012, 0,  1]).format('w ww wo'), '༡ ༠༡ ༡', 'Jan  1 2012 should be week 1');\n    assert.equal(moment([2012, 0,  7]).format('w ww wo'), '༡ ༠༡ ༡', 'Jan  7 2012 should be week 1');\n    assert.equal(moment([2012, 0,  8]).format('w ww wo'), '༢ ༠༢ ༢', 'Jan  8 2012 should be week 2');\n    assert.equal(moment([2012, 0, 14]).format('w ww wo'), '༢ ༠༢ ༢', 'Jan 14 2012 should be week 2');\n    assert.equal(moment([2012, 0, 15]).format('w ww wo'), '༣ ༠༣ ༣', 'Jan 15 2012 should be week 3');\n});\n\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/test/locale/br.js",
    "content": "import {localeModule, test} from '../qunit';\nimport moment from '../../moment';\nlocaleModule('br');\n\ntest('parse', function (assert) {\n    var tests = 'Genver Gen_C\\'hwevrer C\\'hwe_Meurzh Meu_Ebrel Ebr_Mae Mae_Mezheven Eve_Gouere Gou_Eost Eos_Gwengolo Gwe_Here Her_Du Du_Kerzu Ker'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    moment.locale('br');\n    var a = [\n            ['dddd, MMMM Do YYYY, h:mm:ss a',      'Sul, C\\'hwevrer 14vet 2010, 3:25:50 pm'],\n            ['ddd, h A',                            'Sul, 3 PM'],\n            ['M Mo MM MMMM MMM',                   '2 2vet 02 C\\'hwevrer C\\'hwe'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14vet 14'],\n            ['d do dddd ddd dd',                   '0 0vet Sul Sul Su'],\n            ['DDD DDDo DDDD',                      '45 45vet 045'],\n            ['w wo ww',                            '6 6vet 06'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['DDDo [devezh] [ar] [vloaz]',       '45vet devezh ar vloaz'],\n            ['L',                                  '14/02/2010'],\n            ['LL',                                 '14 a viz C\\'hwevrer 2010'],\n            ['LLL',                                '14 a viz C\\'hwevrer 2010 3e25 PM'],\n            ['LLLL',                               'Sul, 14 a viz C\\'hwevrer 2010 3e25 PM']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    moment.locale('br');\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1añ', '1añ');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2vet', '2vet');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3vet', '3vet');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4vet', '4vet');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5vet', '5vet');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6vet', '6vet');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7vet', '7vet');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8vet', '8vet');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9vet', '9vet');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10vet', '10vet');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11vet', '11vet');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12vet', '12vet');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13vet', '13vet');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14vet', '14vet');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15vet', '15vet');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16vet', '16vet');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17vet', '17vet');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18vet', '18vet');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19vet', '19vet');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20vet', '20vet');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21vet', '21vet');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22vet', '22vet');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23vet', '23vet');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24vet', '24vet');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25vet', '25vet');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26vet', '26vet');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27vet', '27vet');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28vet', '28vet');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29vet', '29vet');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30vet', '30vet');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31vet', '31vet');\n});\n\ntest('format month', function (assert) {\n    moment.locale('br');\n    var expected = 'Genver Gen_C\\'hwevrer C\\'hwe_Meurzh Meu_Ebrel Ebr_Mae Mae_Mezheven Eve_Gouere Gou_Eost Eos_Gwengolo Gwe_Here Her_Du Du_Kerzu Ker'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    moment.locale('br');\n    var expected = 'Sul Sul Su_Lun Lun Lu_Meurzh Meu Me_Merc\\'her Mer Mer_Yaou Yao Ya_Gwener Gwe Gw_Sadorn Sad Sa'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    moment.locale('br');\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'un nebeud segondennoù', '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'ur vunutenn',      '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'ur vunutenn',      '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 vunutenn',     '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 munutenn',    '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'un eur',       '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'un eur',       '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 eur',       '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 eur',       '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 eur',      '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'un devezh',         '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'un devezh',         '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 zevezh',        '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'un devezh',         '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 devezh',        '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 devezh',       '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'ur miz',       '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'ur miz',       '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'ur miz',       '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 viz',      '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 viz',      '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 miz',      '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'ur miz',       '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 miz',      '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'ur bloaz',        '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 vloaz',       '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'ur bloaz',        '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 bloaz',       '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    moment.locale('br');\n    assert.equal(moment(30000).from(0), 'a-benn un nebeud segondennoù',  'prefix');\n    assert.equal(moment(0).from(30000), 'un nebeud segondennoù \\'zo', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    moment.locale('br');\n    assert.equal(moment().fromNow(), 'un nebeud segondennoù \\'zo',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    moment.locale('br');\n    assert.equal(moment().add({s: 30}).fromNow(), 'a-benn un nebeud segondennoù', 'in a few seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), 'a-benn 5 devezh', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    moment.locale('br');\n\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'Hiziv da 12e00 PM',        'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'Hiziv da 12e25 PM',        'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'Hiziv da 1e00 PM',         'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'Warc\\'hoazh da 12e00 PM',  'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'Hiziv da 11e00 AM',        'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'Dec\\'h da 12e00 PM',       'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    moment.locale('br');\n\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('dddd [da] LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd [da] LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd [da] LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    moment.locale('br');\n\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('dddd [paset da] LT'),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd [paset da] LT'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd [paset da] LT'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    moment.locale('br');\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('special mutations for years', function (assert) {\n    moment.locale('br');\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true), 'ur bloaz', 'mutation 1 year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 2}), true), '2 vloaz', 'mutation 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 3}), true), '3 bloaz', 'mutation 3 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 4}), true), '4 bloaz', 'mutation 4 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true), '5 bloaz', 'mutation 5 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 9}), true), '9 bloaz', 'mutation 9 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 10}), true), '10 vloaz', 'mutation 10 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 21}), true), '21 bloaz', 'mutation 21 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 22}), true), '22 vloaz', 'mutation 22 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 133}), true), '133 bloaz', 'mutation 133 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 148}), true), '148 vloaz', 'mutation 148 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 261}), true), '261 bloaz', 'mutation 261 years');\n});\n\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/test/locale/bs.js",
    "content": "import {localeModule, test} from '../qunit';\nimport moment from '../../moment';\nlocaleModule('bs');\n\ntest('parse', function (assert) {\n    var tests = 'januar jan._februar feb._mart mar._april apr._maj maj._juni jun._juli jul._august aug._septembar sep._oktobar okt._novembar nov._decembar dec.'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1) + ' inp ' + mmm);\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, Do MMMM YYYY, h:mm:ss a',      'nedjelja, 14. februar 2010, 3:25:50 pm'],\n            ['ddd, hA',                            'ned., 3PM'],\n            ['M Mo MM MMMM MMM',                   '2 2. 02 februar feb.'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14. 14'],\n            ['d do dddd ddd dd',                   '0 0. nedjelja ned. ne'],\n            ['DDD DDDo DDDD',                      '45 45. 045'],\n            ['w wo ww',                            '7 7. 07'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'pm PM'],\n            ['[the] DDDo [day of the year]',       'the 45. day of the year'],\n            ['LTS',                                '15:25:50'],\n            ['L',                                  '14.02.2010'],\n            ['LL',                                 '14. februar 2010'],\n            ['LLL',                                '14. februar 2010 15:25'],\n            ['LLLL',                               'nedjelja, 14. februar 2010 15:25'],\n            ['l',                                  '14.2.2010'],\n            ['ll',                                 '14. feb. 2010'],\n            ['lll',                                '14. feb. 2010 15:25'],\n            ['llll',                               'ned., 14. feb. 2010 15:25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1.', '1.');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2.', '2.');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3.', '3.');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4.', '4.');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5.', '5.');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6.', '6.');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7.', '7.');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8.', '8.');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9.', '9.');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10.', '10.');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11.', '11.');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12.', '12.');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13.', '13.');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14.', '14.');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15.', '15.');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16.', '16.');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17.', '17.');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18.', '18.');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19.', '19.');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20.', '20.');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21.', '21.');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22.', '22.');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23.', '23.');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24.', '24.');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25.', '25.');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26.', '26.');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27.', '27.');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28.', '28.');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29.', '29.');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30.', '30.');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31.', '31.');\n});\n\ntest('format month', function (assert) {\n    var expected = 'januar jan._februar feb._mart mar._april apr._maj maj._juni jun._juli jul._august aug._septembar sep._oktobar okt._novembar nov._decembar dec.'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'nedjelja ned. ne_ponedjeljak pon. po_utorak uto. ut_srijeda sri. sr_četvrtak čet. če_petak pet. pe_subota sub. su'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'par sekundi', '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'jedna minuta',   '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'jedna minuta',   '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 minute',     '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 minuta',     '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'jedan sat',      '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'jedan sat',      '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 sata',        '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 sati',         '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 sati',        '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'dan',       '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'dan',       '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 dana',        '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'dan',       '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 dana',        '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 dana',       '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'mjesec',     '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'mjesec',     '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'mjesec',     '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 mjeseca',     '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 mjeseca',     '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 mjeseca',     '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'mjesec',     '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 mjeseci',    '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'godinu',     '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 godine',       '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'godinu',     '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 godina',        '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'za par sekundi',  'prefix');\n    assert.equal(moment(0).from(30000), 'prije par sekundi', 'prefix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'prije par sekundi',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'za par sekundi', 'in a few seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), 'za 5 dana', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'danas u 12:00',  'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'danas u 12:25',  'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'danas u 13:00',  'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'sutra u 12:00',  'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'danas u 11:00',  'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'jučer u 12:00',  'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n\n    function makeFormat(d) {\n        switch (d.day()) {\n            case 0:\n                return '[u] [nedjelju] [u] LT';\n            case 3:\n                return '[u] [srijedu] [u] LT';\n            case 6:\n                return '[u] [subotu] [u] LT';\n            case 1:\n            case 2:\n            case 4:\n            case 5:\n                return '[u] dddd [u] LT';\n        }\n    }\n\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format(makeFormat(m)),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format(makeFormat(m)),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format(makeFormat(m)),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n\n    function makeFormat(d) {\n        switch (d.day()) {\n            case 0:\n            case 3:\n                return '[prošlu] dddd [u] LT';\n            case 6:\n                return '[prošle] [subote] [u] LT';\n            case 1:\n            case 2:\n            case 4:\n            case 5:\n                return '[prošli] dddd [u] LT';\n        }\n    }\n\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format(makeFormat(m)),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format(makeFormat(m)),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format(makeFormat(m)),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2011, 11, 26]).format('w ww wo'), '1 01 1.', 'Dec 26 2011 should be week 1');\n    assert.equal(moment([2012,  0,  1]).format('w ww wo'), '1 01 1.', 'Jan  1 2012 should be week 1');\n    assert.equal(moment([2012,  0,  2]).format('w ww wo'), '2 02 2.', 'Jan  2 2012 should be week 2');\n    assert.equal(moment([2012,  0,  8]).format('w ww wo'), '2 02 2.', 'Jan  8 2012 should be week 2');\n    assert.equal(moment([2012,  0,  9]).format('w ww wo'), '3 03 3.', 'Jan  9 2012 should be week 3');\n});\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/test/locale/ca.js",
    "content": "import {localeModule, test} from '../qunit';\nimport moment from '../../moment';\nlocaleModule('ca');\n\ntest('parse', function (assert) {\n    var tests = 'gener gen._febrer febr._març març_abril abr._maig maig_juny juny_juliol jul._agost ag._setembre set._octubre oct._novembre nov._desembre des.'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, Do MMMM YYYY, h:mm:ss a',      'diumenge, 14è de febrer 2010, 3:25:50 pm'],\n            ['ddd, hA',                            'dg., 3PM'],\n            ['M Mo MM MMMM MMM',                   '2 2n 02 febrer febr.'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14è 14'],\n            ['d do dddd ddd dd',                   '0 0è diumenge dg. Dg'],\n            ['DDD DDDo DDDD',                      '45 45è 045'],\n            ['w wo ww',                            '6 6a 06'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'pm PM'],\n            ['[the] DDDo [day of the year]',       'the 45è day of the year'],\n            ['LTS',                                '15:25:50'],\n            ['L',                                  '14/02/2010'],\n            ['LL',                                 'el 14 de febrer de 2010'],\n            ['LLL',                                'el 14 de febrer de 2010 a les 15:25'],\n            ['LLLL',                               'el diumenge 14 de febrer de 2010 a les 15:25'],\n            ['l',                                  '14/2/2010'],\n            ['ll',                                 '14 febr. 2010'],\n            ['lll',                                '14 febr. 2010, 15:25'],\n            ['llll',                               'dg. 14 febr. 2010, 15:25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1r', '1r');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2n', '2n');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3r', '3r');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4t', '4t');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5è', '5è');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6è', '6è');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7è', '7è');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8è', '8è');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9è', '9è');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10è', '10è');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11è', '11è');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12è', '12è');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13è', '13è');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14è', '14è');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15è', '15è');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16è', '16è');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17è', '17è');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18è', '18è');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19è', '19è');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20è', '20è');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21è', '21è');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22è', '22è');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23è', '23è');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24è', '24è');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25è', '25è');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26è', '26è');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27è', '27è');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28è', '28è');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29è', '29è');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30è', '30è');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31è', '31è');\n});\n\ntest('format month', function (assert) {\n    var expected = 'gener gen._febrer febr._març març_abril abr._maig maig_juny juny_juliol jul._agost ag._setembre set._octubre oct._novembre nov._desembre des.'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'diumenge dg. Dg_dilluns dl. Dl_dimarts dt. Dt_dimecres dc. Dc_dijous dj. Dj_divendres dv. Dv_dissabte ds. Ds'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'uns segons', '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'un minut',      '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'un minut',      '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 minuts',     '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 minuts',    '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'una hora',       '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'una hora',       '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 hores',       '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 hores',       '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 hores',      '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'un dia',         '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'un dia',         '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 dies',        '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'un dia',         '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 dies',        '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 dies',       '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'un mes',       '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'un mes',       '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'un mes',       '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 mesos',      '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 mesos',      '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 mesos',      '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'un mes',       '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 mesos',      '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'un any',        '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 anys',       '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'un any',        '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 anys',       '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'd\\'aquí uns segons',  'prefix');\n    assert.equal(moment(0).from(30000), 'fa uns segons', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'fa uns segons',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'd\\'aquí uns segons', 'd\\'aquí uns segons');\n    assert.equal(moment().add({d: 5}).fromNow(), 'd\\'aquí 5 dies', 'd\\'aquí 5 dies');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                       'avui a les 12:00',     'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),          'avui a les 12:25',     'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),           'avui a les 13:00',     'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),           'demà a les 12:00',     'tomorrow at the same time');\n    assert.equal(moment(a).add({d: 1, h : -1}).calendar(),   'demà a les 11:00',     'tomorrow minus 1 hour');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),      'avui a les 11:00',     'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),      'ahir a les 12:00',     'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('dddd [a ' + ((m.hours() !== 1) ? 'les' : 'la') + '] LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd [a ' + ((m.hours() !== 1) ? 'les' : 'la') + '] LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd [a ' + ((m.hours() !== 1) ? 'les' : 'la') + '] LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('[el] dddd [passat a ' + ((m.hours() !== 1) ? 'les' : 'la') + '] LT'),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[el] dddd [passat a ' + ((m.hours() !== 1) ? 'les' : 'la') + '] LT'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[el] dddd [passat a ' + ((m.hours() !== 1) ? 'les' : 'la') + '] LT'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2012, 0,  1]).format('w ww wo'), '52 52 52a', 'Jan  1 2012 should be week 52');\n    assert.equal(moment([2012, 0,  2]).format('w ww wo'),   '1 01 1a', 'Jan  2 2012 should be week 1');\n    assert.equal(moment([2012, 0,  8]).format('w ww wo'),   '1 01 1a', 'Jan  8 2012 should be week 1');\n    assert.equal(moment([2012, 0,  9]).format('w ww wo'),   '2 02 2a', 'Jan  9 2012 should be week 2');\n    assert.equal(moment([2012, 0, 15]).format('w ww wo'),   '2 02 2a', 'Jan 15 2012 should be week 2');\n});\n\ntest('day and month', function (assert) {\n    assert.equal(moment([2012, 1, 15]).format('D MMMM'), '15 de febrer');\n    assert.equal(moment([2012, 9, 15]).format('D MMMM'), '15 d\\'octubre');\n    assert.equal(moment([2012, 9, 15]).format('MMMM, D'), 'octubre, 15');\n});\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/test/locale/cs.js",
    "content": "import {localeModule, test} from '../qunit';\nimport moment from '../../moment';\nlocaleModule('cs');\n\ntest('parse', function (assert) {\n    var tests = 'leden led_únor úno_březen bře_duben dub_květen kvě_červen čvn_červenec čvc_srpen srp_září zář_říjen říj_listopad lis_prosinec pro'.split('_'), i;\n    function equalTest(input, mmm, monthIndex) {\n        assert.equal(moment(input, mmm).month(), monthIndex, input + ' ' + mmm + ' should be month ' + (monthIndex + 1));\n    }\n    function equalTestStrict(input, mmm, monthIndex) {\n        assert.equal(moment(input, mmm, true).month(), monthIndex, input + ' ' + mmm + ' should be strict month ' + (monthIndex + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n\n        equalTestStrict(tests[i][1], 'MMM', i);\n        equalTestStrict(tests[i][0], 'MMMM', i);\n        equalTestStrict(tests[i][1].toLocaleLowerCase(), 'MMM', i);\n        equalTestStrict(tests[i][1].toLocaleUpperCase(), 'MMM', i);\n        equalTestStrict(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTestStrict(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, MMMM Do YYYY, h:mm:ss',  'neděle, únor 14. 2010, 3:25:50'],\n            ['ddd, h',                       'ne, 3'],\n            ['M Mo MM MMMM MMM',             '2 2. 02 únor úno'],\n            ['YYYY YY',                      '2010 10'],\n            ['D Do DD',                      '14 14. 14'],\n            ['d do dddd ddd dd',             '0 0. neděle ne ne'],\n            ['DDD DDDo DDDD',                '45 45. 045'],\n            ['w wo ww',                      '6 6. 06'],\n            ['h hh',                         '3 03'],\n            ['H HH',                         '15 15'],\n            ['m mm',                         '25 25'],\n            ['s ss',                         '50 50'],\n            ['a A',                          'pm PM'],\n            ['DDDo [den v roce]',            '45. den v roce'],\n            ['LTS',                          '15:25:50'],\n            ['L',                            '14.02.2010'],\n            ['LL',                           '14. únor 2010'],\n            ['LLL',                          '14. únor 2010 15:25'],\n            ['LLLL',                         'neděle 14. únor 2010 15:25'],\n            ['l',                            '14. 2. 2010'],\n            ['ll',                           '14. úno 2010'],\n            ['lll',                          '14. úno 2010 15:25'],\n            ['llll',                         'ne 14. úno 2010 15:25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1.', '1.');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2.', '2.');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3.', '3.');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4.', '4.');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5.', '5.');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6.', '6.');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7.', '7.');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8.', '8.');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9.', '9.');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10.', '10.');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11.', '11.');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12.', '12.');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13.', '13.');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14.', '14.');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15.', '15.');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16.', '16.');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17.', '17.');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18.', '18.');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19.', '19.');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20.', '20.');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21.', '21.');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22.', '22.');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23.', '23.');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24.', '24.');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25.', '25.');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26.', '26.');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27.', '27.');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28.', '28.');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29.', '29.');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30.', '30.');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31.', '31.');\n});\n\ntest('format month', function (assert) {\n    var expected = 'leden led_únor úno_březen bře_duben dub_květen kvě_červen čvn_červenec čvc_srpen srp_září zář_říjen říj_listopad lis_prosinec pro'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'neděle ne ne_pondělí po po_úterý út út_středa st st_čtvrtek čt čt_pátek pá pá_sobota so so'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'pár sekund',  '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'minuta',        '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'minuta',        '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 minuty',      '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 minut',     '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'hodina',       '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'hodina',       '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 hodiny',     '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 hodin',      '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 hodin',     '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'den',       '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'den',       '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 dny',         '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'den',       '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 dní',         '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 dní',        '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'měsíc',       '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'měsíc',       '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'měsíc',       '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 měsíce',    '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 měsíce',    '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 měsíce',    '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'měsíc',       '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 měsíců',    '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'rok',           '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 roky',        '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'rok',           '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 let',         '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'za pár sekund',  'prefix');\n    assert.equal(moment(0).from(30000), 'před pár sekundami', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'před pár sekundami',  'now from now should display as in the past');\n});\n\ntest('fromNow (future)', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'za pár sekund', 'in a few seconds');\n    assert.equal(moment().add({m: 1}).fromNow(), 'za minutu', 'in a minute');\n    assert.equal(moment().add({m: 3}).fromNow(), 'za 3 minuty', 'in 3 minutes');\n    assert.equal(moment().add({m: 10}).fromNow(), 'za 10 minut', 'in 10 minutes');\n    assert.equal(moment().add({h: 1}).fromNow(), 'za hodinu', 'in an hour');\n    assert.equal(moment().add({h: 3}).fromNow(), 'za 3 hodiny', 'in 3 hours');\n    assert.equal(moment().add({h: 10}).fromNow(), 'za 10 hodin', 'in 10 hours');\n    assert.equal(moment().add({d: 1}).fromNow(), 'za den', 'in a day');\n    assert.equal(moment().add({d: 3}).fromNow(), 'za 3 dny', 'in 3 days');\n    assert.equal(moment().add({d: 10}).fromNow(), 'za 10 dní', 'in 10 days');\n    assert.equal(moment().add({M: 1}).fromNow(), 'za měsíc', 'in a month');\n    assert.equal(moment().add({M: 3}).fromNow(), 'za 3 měsíce', 'in 3 months');\n    assert.equal(moment().add({M: 10}).fromNow(), 'za 10 měsíců', 'in 10 months');\n    assert.equal(moment().add({y: 1}).fromNow(), 'za rok', 'in a year');\n    assert.equal(moment().add({y: 3}).fromNow(), 'za 3 roky', 'in 3 years');\n    assert.equal(moment().add({y: 10}).fromNow(), 'za 10 let', 'in 10 years');\n});\n\ntest('fromNow (past)', function (assert) {\n    assert.equal(moment().subtract({s: 30}).fromNow(), 'před pár sekundami', 'a few seconds ago');\n    assert.equal(moment().subtract({m: 1}).fromNow(), 'před minutou', 'a minute ago');\n    assert.equal(moment().subtract({m: 3}).fromNow(), 'před 3 minutami', '3 minutes ago');\n    assert.equal(moment().subtract({m: 10}).fromNow(), 'před 10 minutami', '10 minutes ago');\n    assert.equal(moment().subtract({h: 1}).fromNow(), 'před hodinou', 'an hour ago');\n    assert.equal(moment().subtract({h: 3}).fromNow(), 'před 3 hodinami', '3 hours ago');\n    assert.equal(moment().subtract({h: 10}).fromNow(), 'před 10 hodinami', '10 hours ago');\n    assert.equal(moment().subtract({d: 1}).fromNow(), 'před dnem', 'a day ago');\n    assert.equal(moment().subtract({d: 3}).fromNow(), 'před 3 dny', '3 days ago');\n    assert.equal(moment().subtract({d: 10}).fromNow(), 'před 10 dny', '10 days ago');\n    assert.equal(moment().subtract({M: 1}).fromNow(), 'před měsícem', 'a month ago');\n    assert.equal(moment().subtract({M: 3}).fromNow(), 'před 3 měsíci', '3 months ago');\n    assert.equal(moment().subtract({M: 10}).fromNow(), 'před 10 měsíci', '10 months ago');\n    assert.equal(moment().subtract({y: 1}).fromNow(), 'před rokem', 'a year ago');\n    assert.equal(moment().subtract({y: 3}).fromNow(), 'před 3 lety', '3 years ago');\n    assert.equal(moment().subtract({y: 10}).fromNow(), 'před 10 lety', '10 years ago');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'dnes v 12:00',     'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'dnes v 12:25',     'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'dnes v 13:00',     'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'zítra v 12:00',    'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'dnes v 11:00',     'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'včera v 12:00',    'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m, nextDay;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        nextDay = '';\n        switch (m.day()) {\n            case 0:\n                nextDay = 'v neděli';\n                break;\n            case 1:\n                nextDay = 'v pondělí';\n                break;\n            case 2:\n                nextDay = 'v úterý';\n                break;\n            case 3:\n                nextDay = 've středu';\n                break;\n            case 4:\n                nextDay = 've čtvrtek';\n                break;\n            case 5:\n                nextDay = 'v pátek';\n                break;\n            case 6:\n                nextDay = 'v sobotu';\n                break;\n        }\n        assert.equal(m.calendar(),       m.format('[' + nextDay + '] [v] LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[' + nextDay + '] [v] LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[' + nextDay + '] [v] LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m, lastDay;\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        lastDay = '';\n        switch (m.day()) {\n            case 0:\n                lastDay = 'minulou neděli';\n                break;\n            case 1:\n                lastDay = 'minulé pondělí';\n                break;\n            case 2:\n                lastDay = 'minulé úterý';\n                break;\n            case 3:\n                lastDay = 'minulou středu';\n                break;\n            case 4:\n                lastDay = 'minulý čtvrtek';\n                break;\n            case 5:\n                lastDay = 'minulý pátek';\n                break;\n            case 6:\n                lastDay = 'minulou sobotu';\n                break;\n        }\n        assert.equal(m.calendar(),       m.format('[' + lastDay + '] [v] LT'),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[' + lastDay + '] [v] LT'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[' + lastDay + '] [v] LT'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('humanize duration', function (assert) {\n    assert.equal(moment.duration(1, 'minutes').humanize(), 'minuta', 'a minute (future)');\n    assert.equal(moment.duration(1, 'minutes').humanize(true), 'za minutu', 'in a minute');\n    assert.equal(moment.duration(-1, 'minutes').humanize(), 'minuta', 'a minute (past)');\n    assert.equal(moment.duration(-1, 'minutes').humanize(true), 'před minutou', 'a minute ago');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2012, 0,  1]).format('w ww wo'), '52 52 52.', 'Jan  1 2012 should be week 52');\n    assert.equal(moment([2012, 0,  2]).format('w ww wo'),   '1 01 1.', 'Jan  2 2012 should be week 1');\n    assert.equal(moment([2012, 0,  8]).format('w ww wo'),   '1 01 1.', 'Jan  8 2012 should be week 1');\n    assert.equal(moment([2012, 0,  9]).format('w ww wo'),   '2 02 2.', 'Jan  9 2012 should be week 2');\n    assert.equal(moment([2012, 0, 15]).format('w ww wo'),   '2 02 2.', 'Jan 15 2012 should be week 2');\n});\n\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/test/locale/cv.js",
    "content": "import {localeModule, test} from '../qunit';\nimport moment from '../../moment';\nlocaleModule('cv');\n\ntest('parse', function (assert) {\n    var tests = 'кӑрлач кӑр_нарӑс нар_пуш пуш_ака ака_май май_ҫӗртме ҫӗр_утӑ утӑ_ҫурла ҫур_авӑн авн_юпа юпа_чӳк чӳк_раштав раш'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, MMMM Do YYYY, h:mm:ss a',      'вырсарникун, нарӑс 14-мӗш 2010, 3:25:50 pm'],\n            ['ddd, hA',                            'выр, 3PM'],\n            ['M Mo MM MMMM MMM',                   '2 2-мӗш 02 нарӑс нар'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14-мӗш 14'],\n            ['d do dddd ddd dd',                   '0 0-мӗш вырсарникун выр вр'],\n            ['DDD DDDo DDDD',                      '45 45-мӗш 045'],\n            ['w wo ww',                            '7 7-мӗш 07'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'pm PM'],\n            ['Ҫулӑн DDDo кунӗ',                    'Ҫулӑн 45-мӗш кунӗ'],\n            ['LTS',                                '15:25:50'],\n            ['L',                                  '14-02-2010'],\n            ['LL',                                 '2010 ҫулхи нарӑс уйӑхӗн 14-мӗшӗ'],\n            ['LLL',                                '2010 ҫулхи нарӑс уйӑхӗн 14-мӗшӗ, 15:25'],\n            ['LLLL',                               'вырсарникун, 2010 ҫулхи нарӑс уйӑхӗн 14-мӗшӗ, 15:25'],\n            ['l',                                  '14-2-2010'],\n            ['ll',                                 '2010 ҫулхи нар уйӑхӗн 14-мӗшӗ'],\n            ['lll',                                '2010 ҫулхи нар уйӑхӗн 14-мӗшӗ, 15:25'],\n            ['llll',                               'выр, 2010 ҫулхи нар уйӑхӗн 14-мӗшӗ, 15:25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1-мӗш', '1-мӗш');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2-мӗш', '2-мӗш');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3-мӗш', '3-мӗш');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4-мӗш', '4-мӗш');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5-мӗш', '5-мӗш');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6-мӗш', '6-мӗш');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7-мӗш', '7-мӗш');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8-мӗш', '8-мӗш');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9-мӗш', '9-мӗш');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10-мӗш', '10-мӗш');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11-мӗш', '11-мӗш');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12-мӗш', '12-мӗш');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13-мӗш', '13-мӗш');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14-мӗш', '14-мӗш');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15-мӗш', '15-мӗш');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16-мӗш', '16-мӗш');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17-мӗш', '17-мӗш');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18-мӗш', '18-мӗш');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19-мӗш', '19-мӗш');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20-мӗш', '20-мӗш');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21-мӗш', '21-мӗш');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22-мӗш', '22-мӗш');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23-мӗш', '23-мӗш');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24-мӗш', '24-мӗш');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25-мӗш', '25-мӗш');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26-мӗш', '26-мӗш');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27-мӗш', '27-мӗш');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28-мӗш', '28-мӗш');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29-мӗш', '29-мӗш');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30-мӗш', '30-мӗш');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31-мӗш', '31-мӗш');\n});\n\ntest('format month', function (assert) {\n    var expected = 'кӑрлач кӑр_нарӑс нар_пуш пуш_ака ака_май май_ҫӗртме ҫӗр_утӑ утӑ_ҫурла ҫур_авӑн авн_юпа юпа_чӳк чӳк_раштав раш'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'вырсарникун выр вр_тунтикун тун тн_ытларикун ытл ыт_юнкун юн юн_кӗҫнерникун кӗҫ кҫ_эрнекун эрн эр_шӑматкун шӑм шм'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'пӗр-ик ҫеккунт', '44 sekunder = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'пӗр минут',      '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'пӗр минут',      '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 минут',     '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 минут',    '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'пӗр сехет',       '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'пӗр сехет',       '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 сехет',       '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 сехет',       '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 сехет',      '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'пӗр кун',         '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'пӗр кун',         '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 кун',        '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'пӗр кун',         '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 кун',        '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 кун',       '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'пӗр уйӑх',       '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'пӗр уйӑх',       '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'пӗр уйӑх',       '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 уйӑх',      '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 уйӑх',      '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 уйӑх',      '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'пӗр уйӑх',       '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 уйӑх',      '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'пӗр ҫул',        '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 ҫул',       '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'пӗр ҫул',        '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 ҫул',       '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'пӗр-ик ҫеккунтран',  'prefix');\n    assert.equal(moment(0).from(30000), 'пӗр-ик ҫеккунт каялла', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'пӗр-ик ҫеккунт каялла',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'пӗр-ик ҫеккунтран', 'in a few seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), '5 кунран', 'in 5 days');\n    assert.equal(moment().add({h: 2}).fromNow(), '2 сехетрен', 'in 2 hours, the right suffix!');\n    assert.equal(moment().add({y: 3}).fromNow(), '3 ҫултан', 'in 3 years, the right suffix!');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n    assert.equal(moment(a).calendar(),                   'Паян 12:00 сехетре',     'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'Паян 12:25 сехетре',     'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'Паян 13:00 сехетре',     'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'Ыран 12:00 сехетре',     'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'Паян 11:00 сехетре',     'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'Ӗнер 12:00 сехетре',     'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('[Ҫитес] dddd LT [сехетре]'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[Ҫитес] dddd LT [сехетре]'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[Ҫитес] dddd LT [сехетре]'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('[Иртнӗ] dddd LT [сехетре]'),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[Иртнӗ] dddd LT [сехетре]'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[Иртнӗ] dddd LT [сехетре]'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\n// Monday is the first day of the week.\n// The week that contains Jan 1st is the first week of the year.\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2011, 11, 26]).format('w ww wo'), '1 01 1-мӗш', 'Dec 26 2011 should be week 1');\n    assert.equal(moment([2012,  0,  1]).format('w ww wo'), '1 01 1-мӗш', 'Jan  1 2012 should be week 1');\n    assert.equal(moment([2012,  0,  2]).format('w ww wo'), '2 02 2-мӗш', 'Jan  2 2012 should be week 2');\n    assert.equal(moment([2012,  0,  8]).format('w ww wo'), '2 02 2-мӗш', 'Jan  8 2012 should be week 2');\n    assert.equal(moment([2012,  0,  9]).format('w ww wo'), '3 03 3-мӗш', 'Jan  9 2012 should be week 3');\n});\n\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/test/locale/cy.js",
    "content": "import {localeModule, test} from '../qunit';\nimport moment from '../../moment';\nlocaleModule('cy');\n\ntest('parse', function (assert) {\n    var tests = 'Ionawr Ion_Chwefror Chwe_Mawrth Maw_Ebrill Ebr_Mai Mai_Mehefin Meh_Gorffennaf Gor_Awst Aws_Medi Med_Hydref Hyd_Tachwedd Tach_Rhagfyr Rhag'.split('_'),\n        i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, MMMM Do YYYY, h:mm:ss a',      'Dydd Sul, Chwefror 14eg 2010, 3:25:50 pm'],\n            ['ddd, hA',                            'Sul, 3PM'],\n            ['M Mo MM MMMM MMM',                   '2 2il 02 Chwefror Chwe'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14eg 14'],\n            ['d do dddd ddd dd',                   '0 0 Dydd Sul Sul Su'],\n            ['DDD DDDo DDDD',                      '45 45ain 045'],\n            ['w wo ww',                            '6 6ed 06'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'pm PM'],\n            ['[the] DDDo [day of the year]',       'the 45ain day of the year'],\n            ['LTS',                                '15:25:50'],\n            ['L',                                  '14/02/2010'],\n            ['LL',                                 '14 Chwefror 2010'],\n            ['LLL',                                '14 Chwefror 2010 15:25'],\n            ['LLLL',                               'Dydd Sul, 14 Chwefror 2010 15:25'],\n            ['l',                                  '14/2/2010'],\n            ['ll',                                 '14 Chwe 2010'],\n            ['lll',                                '14 Chwe 2010 15:25'],\n            ['llll',                               'Sul, 14 Chwe 2010 15:25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1af', '1af');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2il', '2il');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3ydd', '3ydd');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4ydd', '4ydd');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5ed', '5ed');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6ed', '6ed');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7ed', '7ed');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8fed', '8fed');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9fed', '9fed');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10fed', '10fed');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11eg', '11eg');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12fed', '12fed');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13eg', '13eg');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14eg', '14eg');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15fed', '15fed');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16eg', '16eg');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17eg', '17eg');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18fed', '18fed');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19eg', '19eg');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20fed', '20fed');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21ain', '21ain');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22ain', '22ain');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23ain', '23ain');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24ain', '24ain');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25ain', '25ain');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26ain', '26ain');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27ain', '27ain');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28ain', '28ain');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29ain', '29ain');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30ain', '30ain');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31ain', '31ain');\n});\n\ntest('format month', function (assert) {\n    var expected = 'Ionawr Ion_Chwefror Chwe_Mawrth Maw_Ebrill Ebr_Mai Mai_Mehefin Meh_Gorffennaf Gor_Awst Aws_Medi Med_Hydref Hyd_Tachwedd Tach_Rhagfyr Rhag'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'Dydd Sul Sul Su_Dydd Llun Llun Ll_Dydd Mawrth Maw Ma_Dydd Mercher Mer Me_Dydd Iau Iau Ia_Dydd Gwener Gwe Gw_Dydd Sadwrn Sad Sa'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'ychydig eiliadau', '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'munud',   '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'munud',   '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 munud',  '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 munud', '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'awr',    '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'awr',    '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 awr',    '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 awr',    '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 awr',   '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'diwrnod',      '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'diwrnod',      '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 diwrnod',     '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'diwrnod',      '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 diwrnod',     '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 diwrnod',    '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'mis',    '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'mis',    '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'mis',    '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 mis',   '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 mis',   '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 mis',   '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'mis',    '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 mis',   '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'blwyddyn',     '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 flynedd',    '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'blwyddyn',     '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 flynedd',    '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'mewn ychydig eiliadau', 'prefix');\n    assert.equal(moment(0).from(30000), 'ychydig eiliadau yn ôl', 'suffix');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'mewn ychydig eiliadau', 'in a few seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), 'mewn 5 diwrnod', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'Heddiw am 12:00',    'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'Heddiw am 12:25',    'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'Heddiw am 13:00',    'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'Yfory am 12:00',     'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'Heddiw am 11:00',    'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'Ddoe am 12:00',      'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('dddd [am] LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd [am] LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd [am] LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('dddd [diwethaf am] LT'),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd [diwethaf am] LT'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd [diwethaf am] LT'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2012, 0,  1]).format('w ww wo'), '52 52 52ain', 'Jan  1 2012 should be week 52');\n    assert.equal(moment([2012, 0,  2]).format('w ww wo'), '1 01 1af', 'Jan  2 2012 should be week 1');\n    assert.equal(moment([2012, 0,  8]).format('w ww wo'), '1 01 1af', 'Jan  8 2012 should be week 1');\n    assert.equal(moment([2012, 0,  9]).format('w ww wo'),   '2 02 2il', 'Jan  9 2012 should be week 2');\n    assert.equal(moment([2012, 0, 15]).format('w ww wo'),   '2 02 2il', 'Jan 15 2012 should be week 2');\n});\n\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/test/locale/da.js",
    "content": "import {localeModule, test} from '../qunit';\nimport moment from '../../moment';\nlocaleModule('da');\n\ntest('parse', function (assert) {\n    var tests = 'januar jan_februar feb_marts mar_april apr_maj maj_juni jun_juli jul_august aug_september sep_oktober okt_november nov_december dec'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd [den] Do MMMM YYYY, h:mm:ss a', 'søndag den 14. februar 2010, 3:25:50 pm'],\n            ['ddd hA',                             'søn 3PM'],\n            ['M Mo MM MMMM MMM',                   '2 2. 02 februar feb'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14. 14'],\n            ['d do dddd ddd dd',                   '0 0. søndag søn sø'],\n            ['DDD DDDo DDDD',                      '45 45. 045'],\n            ['w wo ww',                            '6 6. 06'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'pm PM'],\n            ['[den] DDDo [dag på året]',           'den 45. dag på året'],\n            ['LTS',                                '15:25:50'],\n            ['L',                                  '14/02/2010'],\n            ['LL',                                 '14. februar 2010'],\n            ['LLL',                                '14. februar 2010 15:25'],\n            ['LLLL',                               'søndag d. 14. februar 2010 kl. 15:25'],\n            ['l',                                  '14/2/2010'],\n            ['ll',                                 '14. feb 2010'],\n            ['lll',                                '14. feb 2010 15:25'],\n            ['llll',                               'søn d. 14. feb 2010 kl. 15:25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1.', '1.');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2.', '2.');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3.', '3.');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4.', '4.');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5.', '5.');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6.', '6.');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7.', '7.');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8.', '8.');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9.', '9.');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10.', '10.');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11.', '11.');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12.', '12.');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13.', '13.');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14.', '14.');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15.', '15.');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16.', '16.');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17.', '17.');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18.', '18.');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19.', '19.');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20.', '20.');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21.', '21.');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22.', '22.');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23.', '23.');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24.', '24.');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25.', '25.');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26.', '26.');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27.', '27.');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28.', '28.');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29.', '29.');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30.', '30.');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31.', '31.');\n});\n\ntest('format month', function (assert) {\n    var expected = 'januar jan_februar feb_marts mar_april apr_maj maj_juni jun_juli jul_august aug_september sep_oktober okt_november nov_december dec'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'søndag søn sø_mandag man ma_tirsdag tir ti_onsdag ons on_torsdag tor to_fredag fre fr_lørdag lør lø'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'få sekunder', '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'et minut',    '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'et minut',    '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 minutter',  '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 minutter', '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'en time',     '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'en time',     '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 timer',     '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 timer',     '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 timer',    '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'en dag',      '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'en dag',      '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 dage',      '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'en dag',      '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 dage',      '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 dage',     '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'en måned',    '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'en måned',    '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'en måned',    '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 måneder',   '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 måneder',   '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 måneder',   '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'en måned',    '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 måneder',   '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'et år',       '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 år',        '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'et år',       '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 år',        '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'om få sekunder',  'prefix');\n    assert.equal(moment(0).from(30000), 'få sekunder siden', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'få sekunder siden',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'om få sekunder', 'in a few seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), 'om 5 dage', 'in 5 days');\n});\n\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'i dag kl. 12:00',    'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'i dag kl. 12:25',    'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'i dag kl. 13:00',    'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'i morgen kl. 12:00', 'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'i dag kl. 11:00',    'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'i går kl. 12:00',    'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('på dddd [kl.] LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('på dddd [kl.] LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('på dddd [kl.] LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('[i] dddd[s kl.] LT'),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[i] dddd[s kl.] LT'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[i] dddd[s kl.] LT'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2012, 0,  1]).format('w ww wo'), '52 52 52.', 'Jan  1 2012 should be week 52');\n    assert.equal(moment([2012, 0,  2]).format('w ww wo'),   '1 01 1.', 'Jan  2 2012 should be week 1');\n    assert.equal(moment([2012, 0,  8]).format('w ww wo'),   '1 01 1.', 'Jan  8 2012 should be week 1');\n    assert.equal(moment([2012, 0,  9]).format('w ww wo'),   '2 02 2.', 'Jan  9 2012 should be week 2');\n    assert.equal(moment([2012, 0, 15]).format('w ww wo'),   '2 02 2.', 'Jan 15 2012 should be week 2');\n});\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/test/locale/de-at.js",
    "content": "import {localeModule, test} from '../qunit';\nimport moment from '../../moment';\nlocaleModule('de-at');\n\ntest('parse', function (assert) {\n    var tests = 'Jänner Jän._Februar Febr._März Mrz._April Apr._Mai Mai_Juni Jun._Juli Jul._August Aug._September Sept._Oktober Okt._November Nov._Dezember Dez.'.split('_'), i;\n\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, Do MMMM YYYY, h:mm:ss a', 'Sonntag, 14. Februar 2010, 3:25:50 pm'],\n            ['ddd, hA', 'So., 3PM'],\n            ['M Mo MM MMMM MMM', '2 2. 02 Februar Febr.'],\n            ['YYYY YY', '2010 10'],\n            ['D Do DD', '14 14. 14'],\n            ['d do dddd ddd dd', '0 0. Sonntag So. So'],\n            ['DDD DDDo DDDD', '45 45. 045'],\n            ['w wo ww', '6 6. 06'],\n            ['h hh', '3 03'],\n            ['H HH', '15 15'],\n            ['m mm', '25 25'],\n            ['s ss', '50 50'],\n            ['a A', 'pm PM'],\n            ['[the] DDDo [day of the year]', 'the 45. day of the year'],\n            ['LTS', '15:25:50'],\n            ['L', '14.02.2010'],\n            ['LL', '14. Februar 2010'],\n            ['LLL', '14. Februar 2010 15:25'],\n            ['LLLL', 'Sonntag, 14. Februar 2010 15:25'],\n            ['l', '14.2.2010'],\n            ['ll', '14. Febr. 2010'],\n            ['lll', '14. Febr. 2010 15:25'],\n            ['llll', 'So., 14. Febr. 2010 15:25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1.', '1.');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2.', '2.');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3.', '3.');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4.', '4.');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5.', '5.');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6.', '6.');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7.', '7.');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8.', '8.');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9.', '9.');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10.', '10.');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11.', '11.');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12.', '12.');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13.', '13.');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14.', '14.');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15.', '15.');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16.', '16.');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17.', '17.');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18.', '18.');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19.', '19.');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20.', '20.');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21.', '21.');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22.', '22.');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23.', '23.');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24.', '24.');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25.', '25.');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26.', '26.');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27.', '27.');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28.', '28.');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29.', '29.');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30.', '30.');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31.', '31.');\n});\n\ntest('format month', function (assert) {\n    var expected = 'Jänner Jän._Februar Febr._März Mrz._April Apr._Mai Mai_Juni Jun._Juli Jul._August Aug._September Sept._Oktober Okt._November Nov._Dezember Dez.'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'Sonntag So. So_Montag Mo. Mo_Dienstag Di. Di_Mittwoch Mi. Mi_Donnerstag Do. Do_Freitag Fr. Fr_Samstag Sa. Sa'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true), 'ein paar Sekunden', '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true), 'eine Minute', '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true), 'eine Minute', '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true), '2 Minuten', '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true), '44 Minuten', '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true), 'eine Stunde', '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true), 'eine Stunde', '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true), '2 Stunden', '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true), '5 Stunden', '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true), '21 Stunden', '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true), 'ein Tag', '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true), 'ein Tag', '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true), '2 Tage', '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true), 'ein Tag', '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true), '5 Tage', '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true), '25 Tage', '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true), 'ein Monat', '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true), 'ein Monat', '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true), '2 Monate', '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true), '2 Monate', '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true), '3 Monate', '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true), 'ein Monat', '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true), '5 Monate', '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'ein Jahr', '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 Jahre', '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true), 'ein Jahr', '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true), '5 Jahre', '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'in ein paar Sekunden', 'prefix');\n    assert.equal(moment(0).from(30000), 'vor ein paar Sekunden', 'suffix');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'in ein paar Sekunden', 'in a few seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), 'in 5 Tagen', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                  'heute um 12:00 Uhr',   'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),     'heute um 12:25 Uhr',   'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),      'heute um 13:00 Uhr',   'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),      'morgen um 12:00 Uhr',  'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(), 'heute um 11:00 Uhr',   'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(), 'gestern um 12:00 Uhr', 'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(), m.format('dddd [um] LT [Uhr]'), 'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(), m.format('dddd [um] LT [Uhr]'), 'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(), m.format('dddd [um] LT [Uhr]'), 'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(), m.format('[letzten] dddd [um] LT [Uhr]'), 'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(), m.format('[letzten] dddd [um] LT [Uhr]'), 'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(), m.format('[letzten] dddd [um] LT [Uhr]'), 'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '1 week ago');\n    assert.equal(weeksFromNow.calendar(), weeksFromNow.format('L'), 'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(), weeksFromNow.format('L'), 'in 2 weeks');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2012, 0, 1]).format('w ww wo'), '52 52 52.', 'Jan  1 2012 should be week 52');\n    assert.equal(moment([2012, 0, 2]).format('w ww wo'), '1 01 1.', 'Jan  2 2012 should be week 1');\n    assert.equal(moment([2012, 0, 8]).format('w ww wo'), '1 01 1.', 'Jan  8 2012 should be week 1');\n    assert.equal(moment([2012, 0, 9]).format('w ww wo'), '2 02 2.', 'Jan  9 2012 should be week 2');\n    assert.equal(moment([2012, 0, 15]).format('w ww wo'), '2 02 2.', 'Jan 15 2012 should be week 2');\n});\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/test/locale/de-ch.js",
    "content": "import {localeModule, test} from '../qunit';\nimport moment from '../../moment';\nlocaleModule('de-ch');\n\ntest('parse', function (assert) {\n    var tests = 'Januar Jan._Februar Febr._März März_April April_Mai Mai_Juni Juni_Juli Juli_August Aug._September Sept._Oktober Okt._November Nov._Dezember Dez.'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, Do MMMM YYYY, h.mm.ss a',      'Sonntag, 14. Februar 2010, 3.25.50 pm'],\n            ['ddd, hA',                            'So, 3PM'],\n            ['M Mo MM MMMM MMM',                   '2 2. 02 Februar Febr.'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14. 14'],\n            ['d do dddd ddd dd',                   '0 0. Sonntag So So'],\n            ['DDD DDDo DDDD',                      '45 45. 045'],\n            ['w wo ww',                            '6 6. 06'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'pm PM'],\n            ['[the] DDDo [day of the year]',       'the 45. day of the year'],\n            ['LTS',                                '15.25.50'],\n            ['L',                                  '14.02.2010'],\n            ['LL',                                 '14. Februar 2010'],\n            ['LLL',                                '14. Februar 2010 15.25'],\n            ['LLLL',                               'Sonntag, 14. Februar 2010 15.25'],\n            ['l',                                  '14.2.2010'],\n            ['ll',                                 '14. Febr. 2010'],\n            ['lll',                                '14. Febr. 2010 15.25'],\n            ['llll',                               'So, 14. Febr. 2010 15.25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1.', '1.');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2.', '2.');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3.', '3.');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4.', '4.');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5.', '5.');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6.', '6.');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7.', '7.');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8.', '8.');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9.', '9.');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10.', '10.');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11.', '11.');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12.', '12.');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13.', '13.');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14.', '14.');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15.', '15.');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16.', '16.');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17.', '17.');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18.', '18.');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19.', '19.');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20.', '20.');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21.', '21.');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22.', '22.');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23.', '23.');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24.', '24.');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25.', '25.');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26.', '26.');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27.', '27.');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28.', '28.');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29.', '29.');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30.', '30.');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31.', '31.');\n});\n\ntest('format month', function (assert) {\n    var expected = 'Januar Jan._Februar Febr._März März_April April_Mai Mai_Juni Juni_Juli Juli_August Aug._September Sept._Oktober Okt._November Nov._Dezember Dez.'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'Sonntag So So_Montag Mo Mo_Dienstag Di Di_Mittwoch Mi Mi_Donnerstag Do Do_Freitag Fr Fr_Samstag Sa Sa'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'ein paar Sekunden',  '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'eine Minute',       '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'eine Minute',       '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 Minuten',          '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 Minuten',         '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'eine Stunde',       '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'eine Stunde',       '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 Stunden',          '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 Stunden',          '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 Stunden',         '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'ein Tag',          '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'ein Tag',          '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 Tage',            '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'ein Tag',          '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 Tage',            '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 Tage',           '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'ein Monat',        '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'ein Monat',        '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'ein Monat',        '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 Monate',          '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 Monate',          '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 Monate',          '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'ein Monat',        '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 Monate',          '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'ein Jahr',         '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 Jahre',           '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'ein Jahr',         '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 Jahre',           '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'in ein paar Sekunden', 'prefix');\n    assert.equal(moment(0).from(30000), 'vor ein paar Sekunden', 'suffix');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'in ein paar Sekunden', 'in a few seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), 'in 5 Tagen', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'heute um 12.00 Uhr',   'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'heute um 12.25 Uhr',   'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'heute um 13.00 Uhr',   'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'morgen um 12.00 Uhr',  'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'heute um 11.00 Uhr',   'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'gestern um 12.00 Uhr', 'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('dddd [um] LT [Uhr]'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd [um] LT [Uhr]'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd [um] LT [Uhr]'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('[letzten] dddd [um] LT [Uhr]'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[letzten] dddd [um] LT [Uhr]'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[letzten] dddd [um] LT [Uhr]'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2012, 0,  1]).format('w ww wo'), '52 52 52.', 'Jan  1 2012 should be week 52');\n    assert.equal(moment([2012, 0,  2]).format('w ww wo'),   '1 01 1.', 'Jan  2 2012 should be week 1');\n    assert.equal(moment([2012, 0,  8]).format('w ww wo'),   '1 01 1.', 'Jan  8 2012 should be week 1');\n    assert.equal(moment([2012, 0,  9]).format('w ww wo'),   '2 02 2.', 'Jan  9 2012 should be week 2');\n    assert.equal(moment([2012, 0, 15]).format('w ww wo'),   '2 02 2.', 'Jan 15 2012 should be week 2');\n});\n\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/test/locale/de.js",
    "content": "import {localeModule, test} from '../qunit';\nimport moment from '../../moment';\nlocaleModule('de');\n\ntest('parse', function (assert) {\n    var tests = 'Januar Jan._Februar Febr._März Mrz._April Apr._Mai Mai_Juni Jun._Juli Jul._August Aug._September Sept._Oktober Okt._November Nov._Dezember Dez.'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, Do MMMM YYYY, h:mm:ss a',      'Sonntag, 14. Februar 2010, 3:25:50 pm'],\n            ['ddd, hA',                            'So., 3PM'],\n            ['M Mo MM MMMM MMM',                   '2 2. 02 Februar Febr.'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14. 14'],\n            ['d do dddd ddd dd',                   '0 0. Sonntag So. So'],\n            ['DDD DDDo DDDD',                      '45 45. 045'],\n            ['w wo ww',                            '6 6. 06'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'pm PM'],\n            ['[the] DDDo [day of the year]',       'the 45. day of the year'],\n            ['LTS',                                '15:25:50'],\n            ['L',                                  '14.02.2010'],\n            ['LL',                                 '14. Februar 2010'],\n            ['LLL',                                '14. Februar 2010 15:25'],\n            ['LLLL',                               'Sonntag, 14. Februar 2010 15:25'],\n            ['l',                                  '14.2.2010'],\n            ['ll',                                 '14. Febr. 2010'],\n            ['lll',                                '14. Febr. 2010 15:25'],\n            ['llll',                               'So., 14. Febr. 2010 15:25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1.', '1.');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2.', '2.');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3.', '3.');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4.', '4.');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5.', '5.');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6.', '6.');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7.', '7.');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8.', '8.');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9.', '9.');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10.', '10.');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11.', '11.');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12.', '12.');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13.', '13.');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14.', '14.');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15.', '15.');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16.', '16.');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17.', '17.');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18.', '18.');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19.', '19.');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20.', '20.');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21.', '21.');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22.', '22.');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23.', '23.');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24.', '24.');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25.', '25.');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26.', '26.');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27.', '27.');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28.', '28.');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29.', '29.');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30.', '30.');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31.', '31.');\n});\n\ntest('format month', function (assert) {\n    var expected = 'Januar Jan._Februar Febr._März Mrz._April Apr._Mai Mai_Juni Jun._Juli Jul._August Aug._September Sept._Oktober Okt._November Nov._Dezember Dez.'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'Sonntag So. So_Montag Mo. Mo_Dienstag Di. Di_Mittwoch Mi. Mi_Donnerstag Do. Do_Freitag Fr. Fr_Samstag Sa. Sa'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'ein paar Sekunden',  '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'eine Minute',       '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'eine Minute',       '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 Minuten',          '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 Minuten',         '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'eine Stunde',       '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'eine Stunde',       '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 Stunden',          '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 Stunden',          '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 Stunden',         '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'ein Tag',          '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'ein Tag',          '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 Tage',            '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'ein Tag',          '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 Tage',            '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 Tage',           '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'ein Monat',        '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'ein Monat',        '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'ein Monat',        '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 Monate',          '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 Monate',          '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 Monate',          '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'ein Monat',        '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 Monate',          '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'ein Jahr',         '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 Jahre',           '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'ein Jahr',         '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 Jahre',           '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'in ein paar Sekunden', 'prefix');\n    assert.equal(moment(0).from(30000), 'vor ein paar Sekunden', 'suffix');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'in ein paar Sekunden', 'in a few seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), 'in 5 Tagen', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'heute um 12:00 Uhr',   'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'heute um 12:25 Uhr',   'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'heute um 13:00 Uhr',   'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'morgen um 12:00 Uhr',  'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'heute um 11:00 Uhr',   'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'gestern um 12:00 Uhr', 'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('dddd [um] LT [Uhr]'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd [um] LT [Uhr]'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd [um] LT [Uhr]'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('[letzten] dddd [um] LT [Uhr]'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[letzten] dddd [um] LT [Uhr]'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[letzten] dddd [um] LT [Uhr]'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2012, 0,  1]).format('w ww wo'), '52 52 52.', 'Jan  1 2012 should be week 52');\n    assert.equal(moment([2012, 0,  2]).format('w ww wo'),   '1 01 1.', 'Jan  2 2012 should be week 1');\n    assert.equal(moment([2012, 0,  8]).format('w ww wo'),   '1 01 1.', 'Jan  8 2012 should be week 1');\n    assert.equal(moment([2012, 0,  9]).format('w ww wo'),   '2 02 2.', 'Jan  9 2012 should be week 2');\n    assert.equal(moment([2012, 0, 15]).format('w ww wo'),   '2 02 2.', 'Jan 15 2012 should be week 2');\n});\n\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/test/locale/dv.js",
    "content": "import {localeModule, test} from '../qunit';\nimport moment from '../../moment';\nlocaleModule('dv');\n\ntest('parse', function (assert) {\n    var i,\n        tests = [\n            'ޖެނުއަރީ',\n            'ފެބްރުއަރީ',\n            'މާރިޗު',\n            'އޭޕްރީލު',\n            'މޭ',\n            'ޖޫން',\n            'ޖުލައި',\n            'އޯގަސްޓު',\n            'ސެޕްޓެމްބަރު',\n            'އޮކްޓޯބަރު',\n            'ނޮވެމްބަރު',\n            'ޑިސެމްބަރު'\n        ];\n\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n\n    for (i = 0; i < 12; i++) {\n        equalTest(tests[i], 'MMM', i);\n        equalTest(tests[i], 'MMMM', i);\n        equalTest(tests[i].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, MMMM Do YYYY, h:mm:ss a',      'އާދިއްތަ، ފެބްރުއަރީ 14 2010، 3:25:50 މފ'],\n            ['ddd, hA',                            'އާދިއްތަ، 3މފ'],\n            ['M Mo MM MMMM MMM',                   '2 2 02 ފެބްރުއަރީ ފެބްރުއަރީ'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14 14'],\n            ['d do dddd ddd dd',                   '0 0 އާދިއްތަ އާދިއްތަ އާދި'],\n            ['DDD DDDo DDDD',                      '45 45 045'],\n            ['w wo ww',                            '8 8 08'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'މފ މފ'],\n            ['LTS',                                '15:25:50'],\n            ['L',                                  '14/2/2010'],\n            ['LL',                                 '14 ފެބްރުއަރީ 2010'],\n            ['LLL',                                '14 ފެބްރުއަރީ 2010 15:25'],\n            ['LLLL',                               'އާދިއްތަ 14 ފެބްރުއަރީ 2010 15:25'],\n            ['l',                                  '14/2/2010'],\n            ['ll',                                 '14 ފެބްރުއަރީ 2010'],\n            ['lll',                                '14 ފެބްރުއަރީ 2010 15:25'],\n            ['llll',                               'އާދިއްތަ 14 ފެބްރުއަރީ 2010 15:25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format month', function (assert) {\n    var i,\n        expected = [\n            'ޖެނުއަރީ',\n            'ފެބްރުއަރީ',\n            'މާރިޗު',\n            'އޭޕްރީލު',\n            'މޭ',\n            'ޖޫން',\n            'ޖުލައި',\n            'އޯގަސްޓު',\n            'ސެޕްޓެމްބަރު',\n            'އޮކްޓޯބަރު',\n            'ނޮވެމްބަރު',\n            'ޑިސެމްބަރު'\n        ];\n\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM'), expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var i,\n        expected = [\n            'އާދިއްތަ',\n            'ހޯމަ',\n            'އަންގާރަ',\n            'ބުދަ',\n            'ބުރާސްފަތި',\n            'ހުކުރު',\n            'ހޮނިހިރު'\n        ];\n\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd'), expected[i]);\n    }\n});\n\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'ސިކުންތުކޮޅެއް',  '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'މިނިޓެއް',        '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'މިނިޓެއް',        '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  'މިނިޓު 2',        '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  'މިނިޓު 44',       '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'ގަޑިއިރެއް',      '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'ގަޑިއިރެއް',      '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  'ގަޑިއިރު 2',      '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   'ގަޑިއިރު 5',      '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  'ގަޑިއިރު 21',     '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'ދުވަހެއް',        '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'ދުވަހެއް',        '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  'ދުވަސް 2',        '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'ދުވަހެއް',        '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   'ދުވަސް 5',        '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  'ދުވަސް 25',       '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'މަހެއް',          '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'މަހެއް',          '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'މަހެއް',          '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  'މަސް 2',          '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  'މަސް 2',          '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  'މަސް 3',          '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'މަހެއް',          '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   'މަސް 5',          '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'އަހަރެއް',        '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), 'އަހަރު 2',        '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'އަހަރެއް',        '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   'އަހަރު 5',        '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'ތެރޭގައި ސިކުންތުކޮޅެއް', 'prefix');\n    assert.equal(moment(0).from(30000), 'ކުރިން ސިކުންތުކޮޅެއް', 'suffix');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'ތެރޭގައި ސިކުންތުކޮޅެއް', 'in a few seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), 'ތެރޭގައި ދުވަސް 5', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'މިއަދު 12:00',  'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'މިއަދު 12:25',  'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'މިއަދު 13:00',  'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'މާދަމާ 12:00',  'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'މިއަދު 11:00',  'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'އިއްޔެ 12:00',  'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('dddd LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('[ފާއިތުވި] dddd LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[ފާއިތުވި] dddd LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[ފާއިތުވި] dddd LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2012, 0,  1]).format('w ww wo'),   '1 01 1', 'Jan  1 2012 should be week 1');\n    assert.equal(moment([2012, 0,  2]).format('w ww wo'),   '1 01 1', 'Jan  2 2012 should be week 1');\n    assert.equal(moment([2012, 0,  8]).format('w ww wo'),   '2 02 2', 'Jan  8 2012 should be week 2');\n    assert.equal(moment([2012, 0,  9]).format('w ww wo'),   '2 02 2', 'Jan  9 2012 should be week 2');\n    assert.equal(moment([2012, 0, 15]).format('w ww wo'),   '3 03 3', 'Jan 15 2012 should be week 3');\n});\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/test/locale/el.js",
    "content": "import {localeModule, test} from '../qunit';\nimport moment from '../../moment';\nlocaleModule('el');\n\ntest('parse', function (assert) {\n    var i,\n        tests = 'Ιανουάριος Ιαν_Φεβρουάριος Φεβ_Μάρτιος Μαρ_Απρίλιος Απρ_Μάιος Μαϊ_Ιούνιος Ιουν_Ιούλιος Ιουλ_Αύγουστος Αυγ_Σεπτέμβριος Σεπ_Οκτώβριος Οκτ_Νοέμβριος Νοε_Δεκέμβριος Δεκ'.split('_');\n\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('parse meridiem', function (assert) {\n    var i,\n        b = moment(),\n        meridiemTests = [\n            // h a patterns, expected hours, isValid\n            ['10 πμ',   10, true],\n            ['10 μμ',   22, true],\n            ['10 π.μ.', 10, true],\n            ['10 μ.μ.', 22, true],\n            ['10 π',    10, true],\n            ['10 μ',    22, true],\n            ['10 ΠΜ',   10, true],\n            ['10 ΜΜ',   22, true],\n            ['10 Π.Μ.', 10, true],\n            ['10 Μ.Μ.', 22, true],\n            ['10 Π',    10, true],\n            ['10 Μ',    22, true],\n            ['10 am',   10, false],\n            ['10 pm',   10, false]\n        ],\n        parsed;\n\n    // test that a formatted moment including meridiem string can be parsed back to the same moment\n    assert.ok(b.isSame(moment(b.format('h:mm:ss a'), 'h:mm:ss a', 'el', true), 'seconds'), b.format('h:mm:ss a') + ' should be equal to ' + moment(b.format('h:mm:ss a'), 'h:mm:ss a', 'el', true).format('h:mm:ss a'));\n\n    // test that a formatted moment having a meridiem string can be parsed with strict flag\n    assert.ok(moment(b.format('h:mm:ss a'), 'h:mm:ss a', 'el', true).isValid(), b.format('h:mm:ss a') + ' should be parsed as valid');\n\n    for (i = 0; i < meridiemTests.length; i++) {\n        parsed = moment(meridiemTests[i][0], 'h a', 'el', true);\n        assert.equal(parsed.isValid(), meridiemTests[i][2], 'validity for ' + meridiemTests[i][0]);\n        if (parsed.isValid()) {\n            assert.equal(parsed.hours(), meridiemTests[i][1], 'hours for ' + meridiemTests[i][0]);\n        }\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, MMMM Do YYYY, h:mm:ss a',      'Κυριακή, Φεβρουάριος 14η 2010, 3:25:50 μμ'],\n            ['dddd, D MMMM YYYY, h:mm:ss a',       'Κυριακή, 14 Φεβρουαρίου 2010, 3:25:50 μμ'],\n            ['ddd, hA',                            'Κυρ, 3ΜΜ'],\n            ['dddd, MMMM YYYY',                    'Κυριακή, Φεβρουάριος 2010'],\n            ['M Mo MM MMMM MMM',                   '2 2η 02 Φεβρουάριος Φεβ'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14η 14'],\n            ['d do dddd ddd dd',                   '0 0η Κυριακή Κυρ Κυ'],\n            ['DDD DDDo DDDD',                      '45 45η 045'],\n            ['w wo ww',                            '6 6η 06'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'μμ ΜΜ'],\n            ['[the] DDDo [day of the year]',       'the 45η day of the year'],\n            ['LTS',                                '3:25:50 ΜΜ'],\n            ['L',                                  '14/02/2010'],\n            ['LL',                                 '14 Φεβρουαρίου 2010'],\n            ['LLL',                                '14 Φεβρουαρίου 2010 3:25 ΜΜ'],\n            ['LLLL',                               'Κυριακή, 14 Φεβρουαρίου 2010 3:25 ΜΜ'],\n            ['l',                                  '14/2/2010'],\n            ['ll',                                 '14 Φεβ 2010'],\n            ['lll',                                '14 Φεβ 2010 3:25 ΜΜ'],\n            ['llll',                               'Κυρ, 14 Φεβ 2010 3:25 ΜΜ']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1η', '1η');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2η', '2η');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3η', '3η');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4η', '4η');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5η', '5η');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6η', '6η');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7η', '7η');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8η', '8η');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9η', '9η');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10η', '10η');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11η', '11η');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12η', '12η');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13η', '13η');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14η', '14η');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15η', '15η');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16η', '16η');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17η', '17η');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18η', '18η');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19η', '19η');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20η', '20η');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21η', '21η');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22η', '22η');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23η', '23η');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24η', '24η');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25η', '25η');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26η', '26η');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27η', '27η');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28η', '28η');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29η', '29η');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30η', '30η');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31η', '31η');\n});\n\ntest('format month', function (assert) {\n    var i,\n        expected = 'Ιανουάριος Ιαν_Φεβρουάριος Φεβ_Μάρτιος Μαρ_Απρίλιος Απρ_Μάιος Μαϊ_Ιούνιος Ιουν_Ιούλιος Ιουλ_Αύγουστος Αυγ_Σεπτέμβριος Σεπ_Οκτώβριος Οκτ_Νοέμβριος Νοε_Δεκέμβριος Δεκ'.split('_');\n\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var i,\n        expected = 'Κυριακή Κυρ Κυ_Δευτέρα Δευ Δε_Τρίτη Τρι Τρ_Τετάρτη Τετ Τε_Πέμπτη Πεμ Πε_Παρασκευή Παρ Πα_Σάββατο Σαβ Σα'.split('_');\n\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'λίγα δευτερόλεπτα',   '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'ένα λεπτό',           '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'ένα λεπτό',           '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 λεπτά',             '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 λεπτά',            '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'μία ώρα',             '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'μία ώρα',             '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 ώρες',              '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 ώρες',              '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 ώρες',             '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'μία μέρα',            '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'μία μέρα',            '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 μέρες',             '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'μία μέρα',            '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 μέρες',             '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 μέρες',            '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'ένας μήνας',          '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'ένας μήνας',          '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'ένας μήνας',          '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 μήνες',             '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 μήνες',             '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 μήνες',             '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'ένας μήνας',          '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 μήνες',             '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'ένας χρόνος',         '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 χρόνια',            '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'ένας χρόνος',         '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 χρόνια',            '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'σε λίγα δευτερόλεπτα',  'prefix');\n    assert.equal(moment(0).from(30000), 'λίγα δευτερόλεπτα πριν', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'λίγα δευτερόλεπτα πριν',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'σε λίγα δευτερόλεπτα', 'in a few seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), 'σε 5 μέρες', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'Σήμερα στις 12:00 ΜΜ',     'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'Σήμερα στις 12:25 ΜΜ',     'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'Σήμερα στη 1:00 ΜΜ',      'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'Αύριο στις 12:00 ΜΜ',      'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'Σήμερα στις 11:00 ΠΜ',      'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'Χθες στις 12:00 ΜΜ',       'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('dddd [' + (m.hours() % 12 === 1 ? 'στη' : 'στις') + '] LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd [στις] LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd [στις] LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m, dayString;\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        dayString = m.day() === 6 ? '[το προηγούμενο Σάββατο]' : '[την προηγούμενη] dddd';\n        assert.equal(m.calendar(),       m.format(dayString + ' [' + (m.hours() % 12 === 1 ? 'στη' : 'στις') + '] LT'),  'Today - ' + i + ' days current time');\n        m.hours(1).minutes(30).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format(dayString + ' [στη] LT'),  'Today - ' + i + ' days one o clock');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format(dayString + ' [στις] LT'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format(dayString + ' [στις] LT'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('weeks year starting sunday format', function (assert) {\n    assert.equal(moment([2012, 0,  1]).format('w ww wo'), '52 52 52η', 'Jan  1 2012 should be week 52');\n    assert.equal(moment([2012, 0,  7]).format('w ww wo'),   '1 01 1η', 'Jan  7 2012 should be week 1');\n    assert.equal(moment([2012, 0,  8]).format('w ww wo'),   '1 01 1η', 'Jan  8 2012 should be week 1');\n    assert.equal(moment([2012, 0, 14]).format('w ww wo'),   '2 02 2η', 'Jan 14 2012 should be week 2');\n    assert.equal(moment([2012, 0, 15]).format('w ww wo'),   '2 02 2η', 'Jan 15 2012 should be week 2');\n});\n\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/test/locale/en-au.js",
    "content": "import {localeModule, test} from '../qunit';\nimport moment from '../../moment';\nlocaleModule('en-au');\n\ntest('parse', function (assert) {\n    var tests = 'January Jan_February Feb_March Mar_April Apr_May May_June Jun_July Jul_August Aug_September Sep_October Oct_November Nov_December Dec'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, MMMM Do YYYY, h:mm:ss a',      'Sunday, February 14th 2010, 3:25:50 pm'],\n            ['ddd, hA',                            'Sun, 3PM'],\n            ['M Mo MM MMMM MMM',                   '2 2nd 02 February Feb'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14th 14'],\n            ['d do dddd ddd dd',                   '0 0th Sunday Sun Su'],\n            ['DDD DDDo DDDD',                      '45 45th 045'],\n            ['w wo ww',                            '6 6th 06'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'pm PM'],\n            ['[the] DDDo [day of the year]',       'the 45th day of the year'],\n            ['LTS',                                '3:25:50 PM'],\n            ['L',                                  '14/02/2010'],\n            ['LL',                                 '14 February 2010'],\n            ['LLL',                                '14 February 2010 3:25 PM'],\n            ['LLLL',                               'Sunday, 14 February 2010 3:25 PM'],\n            ['l',                                  '14/2/2010'],\n            ['ll',                                 '14 Feb 2010'],\n            ['lll',                                '14 Feb 2010 3:25 PM'],\n            ['llll',                               'Sun, 14 Feb 2010 3:25 PM']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1st', '1st');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2nd', '2nd');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3rd', '3rd');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4th', '4th');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5th', '5th');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6th', '6th');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7th', '7th');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8th', '8th');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9th', '9th');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10th', '10th');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11th', '11th');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12th', '12th');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13th', '13th');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14th', '14th');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15th', '15th');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16th', '16th');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17th', '17th');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18th', '18th');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19th', '19th');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20th', '20th');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21st', '21st');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22nd', '22nd');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23rd', '23rd');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24th', '24th');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25th', '25th');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26th', '26th');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27th', '27th');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28th', '28th');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29th', '29th');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30th', '30th');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31st', '31st');\n});\n\ntest('format month', function (assert) {\n    var expected = 'January Jan_February Feb_March Mar_April Apr_May May_June Jun_July Jul_August Aug_September Sep_October Oct_November Nov_December Dec'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'Sunday Sun Su_Monday Mon Mo_Tuesday Tue Tu_Wednesday Wed We_Thursday Thu Th_Friday Fri Fr_Saturday Sat Sa'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'a few seconds', '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'a minute',      '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'a minute',      '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 minutes',     '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 minutes',    '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'an hour',       '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'an hour',       '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 hours',       '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 hours',       '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 hours',      '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'a day',         '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'a day',         '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 days',        '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'a day',         '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 days',        '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 days',       '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'a month',       '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'a month',       '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'a month',       '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 months',      '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 months',      '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 months',      '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'a month',       '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 months',      '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'a year',        '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 years',       '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'a year',        '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 years',       '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'in a few seconds',  'prefix');\n    assert.equal(moment(0).from(30000), 'a few seconds ago', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'a few seconds ago',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'in a few seconds', 'in a few seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), 'in 5 days', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'Today at 12:00 PM',     'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'Today at 12:25 PM',     'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'Today at 1:00 PM',      'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'Tomorrow at 12:00 PM',  'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'Today at 11:00 AM',     'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'Yesterday at 12:00 PM', 'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('dddd [at] LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd [at] LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd [at] LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('[Last] dddd [at] LT'),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[Last] dddd [at] LT'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[Last] dddd [at] LT'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2012, 0,  1]).format('w ww wo'), '52 52 52nd', 'Jan  1 2012 should be week 52');\n    assert.equal(moment([2012, 0,  2]).format('w ww wo'),   '1 01 1st', 'Jan  2 2012 should be week 1');\n    assert.equal(moment([2012, 0,  8]).format('w ww wo'),   '1 01 1st', 'Jan  8 2012 should be week 1');\n    assert.equal(moment([2012, 0,  9]).format('w ww wo'),   '2 02 2nd', 'Jan  9 2012 should be week 2');\n    assert.equal(moment([2012, 0, 15]).format('w ww wo'),   '2 02 2nd', 'Jan 15 2012 should be week 2');\n});\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/test/locale/en-ca.js",
    "content": "import {localeModule, test} from '../qunit';\nimport moment from '../../moment';\nlocaleModule('en-ca');\n\ntest('parse', function (assert) {\n    var i,\n        tests = 'January Jan_February Feb_March Mar_April Apr_May May_June Jun_July Jul_August Aug_September Sep_October Oct_November Nov_December Dec'.split('_');\n\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, MMMM Do YYYY, h:mm:ss a',      'Sunday, February 14th 2010, 3:25:50 pm'],\n            ['ddd, hA',                            'Sun, 3PM'],\n            ['M Mo MM MMMM MMM',                   '2 2nd 02 February Feb'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14th 14'],\n            ['d do dddd ddd dd',                   '0 0th Sunday Sun Su'],\n            ['DDD DDDo DDDD',                      '45 45th 045'],\n            ['w wo ww',                            '8 8th 08'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'pm PM'],\n            ['[the] DDDo [day of the year]',       'the 45th day of the year'],\n            ['L',                                  '2010-02-14'],\n            ['LTS',                                '3:25:50 PM'],\n            ['LL',                                 'February 14, 2010'],\n            ['LLL',                                'February 14, 2010 3:25 PM'],\n            ['LLLL',                               'Sunday, February 14, 2010 3:25 PM'],\n            ['l',                                  '2010-2-14'],\n            ['ll',                                 'Feb 14, 2010'],\n            ['lll',                                'Feb 14, 2010 3:25 PM'],\n            ['llll',                               'Sun, Feb 14, 2010 3:25 PM']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1st', '1st');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2nd', '2nd');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3rd', '3rd');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4th', '4th');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5th', '5th');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6th', '6th');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7th', '7th');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8th', '8th');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9th', '9th');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10th', '10th');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11th', '11th');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12th', '12th');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13th', '13th');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14th', '14th');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15th', '15th');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16th', '16th');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17th', '17th');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18th', '18th');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19th', '19th');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20th', '20th');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21st', '21st');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22nd', '22nd');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23rd', '23rd');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24th', '24th');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25th', '25th');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26th', '26th');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27th', '27th');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28th', '28th');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29th', '29th');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30th', '30th');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31st', '31st');\n});\n\ntest('format month', function (assert) {\n    var i,\n        expected = 'January Jan_February Feb_March Mar_April Apr_May May_June Jun_July Jul_August Aug_September Sep_October Oct_November Nov_December Dec'.split('_');\n\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var i,\n        expected = 'Sunday Sun Su_Monday Mon Mo_Tuesday Tue Tu_Wednesday Wed We_Thursday Thu Th_Friday Fri Fr_Saturday Sat Sa'.split('_');\n\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'a few seconds', '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'a minute',      '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'a minute',      '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 minutes',     '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 minutes',    '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'an hour',       '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'an hour',       '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 hours',       '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 hours',       '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 hours',      '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'a day',         '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'a day',         '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 days',        '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'a day',         '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 days',        '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 days',       '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'a month',       '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'a month',       '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'a month',       '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 months',      '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 months',      '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 months',      '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'a month',       '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 months',      '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'a year',        '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 years',       '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'a year',        '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 years',       '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'in a few seconds',  'prefix');\n    assert.equal(moment(0).from(30000), 'a few seconds ago', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'a few seconds ago',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'in a few seconds', 'in a few seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), 'in 5 days', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'Today at 12:00 PM',     'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'Today at 12:25 PM',     'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'Today at 1:00 PM',      'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'Tomorrow at 12:00 PM',  'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'Today at 11:00 AM',     'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'Yesterday at 12:00 PM', 'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('dddd [at] LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd [at] LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd [at] LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('[Last] dddd [at] LT'),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[Last] dddd [at] LT'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[Last] dddd [at] LT'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('weeks year starting sunday format', function (assert) {\n    assert.equal(moment([2012, 0,  1]).format('w ww wo'), '1 01 1st', 'Jan  1 2012 should be week 1');\n    assert.equal(moment([2012, 0,  7]).format('w ww wo'), '1 01 1st', 'Jan  7 2012 should be week 1');\n    assert.equal(moment([2012, 0,  8]).format('w ww wo'), '2 02 2nd', 'Jan  8 2012 should be week 2');\n    assert.equal(moment([2012, 0, 14]).format('w ww wo'), '2 02 2nd', 'Jan 14 2012 should be week 2');\n    assert.equal(moment([2012, 0, 15]).format('w ww wo'), '3 03 3rd', 'Jan 15 2012 should be week 3');\n});\n\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/test/locale/en-gb.js",
    "content": "import {localeModule, test} from '../qunit';\nimport moment from '../../moment';\nlocaleModule('en-gb');\n\ntest('parse', function (assert) {\n    var tests = 'January Jan_February Feb_March Mar_April Apr_May May_June Jun_July Jul_August Aug_September Sep_October Oct_November Nov_December Dec'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, MMMM Do YYYY, h:mm:ss a',      'Sunday, February 14th 2010, 3:25:50 pm'],\n            ['ddd, hA',                            'Sun, 3PM'],\n            ['M Mo MM MMMM MMM',                   '2 2nd 02 February Feb'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14th 14'],\n            ['d do dddd ddd dd',                   '0 0th Sunday Sun Su'],\n            ['DDD DDDo DDDD',                      '45 45th 045'],\n            ['w wo ww',                            '6 6th 06'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'pm PM'],\n            ['[the] DDDo [day of the year]',       'the 45th day of the year'],\n            ['LTS',                                '15:25:50'],\n            ['L',                                  '14/02/2010'],\n            ['LL',                                 '14 February 2010'],\n            ['LLL',                                '14 February 2010 15:25'],\n            ['LLLL',                               'Sunday, 14 February 2010 15:25'],\n            ['l',                                  '14/2/2010'],\n            ['ll',                                 '14 Feb 2010'],\n            ['lll',                                '14 Feb 2010 15:25'],\n            ['llll',                               'Sun, 14 Feb 2010 15:25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1st', '1st');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2nd', '2nd');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3rd', '3rd');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4th', '4th');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5th', '5th');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6th', '6th');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7th', '7th');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8th', '8th');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9th', '9th');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10th', '10th');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11th', '11th');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12th', '12th');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13th', '13th');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14th', '14th');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15th', '15th');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16th', '16th');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17th', '17th');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18th', '18th');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19th', '19th');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20th', '20th');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21st', '21st');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22nd', '22nd');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23rd', '23rd');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24th', '24th');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25th', '25th');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26th', '26th');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27th', '27th');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28th', '28th');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29th', '29th');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30th', '30th');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31st', '31st');\n});\n\ntest('format month', function (assert) {\n    var expected = 'January Jan_February Feb_March Mar_April Apr_May May_June Jun_July Jul_August Aug_September Sep_October Oct_November Nov_December Dec'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'Sunday Sun Su_Monday Mon Mo_Tuesday Tue Tu_Wednesday Wed We_Thursday Thu Th_Friday Fri Fr_Saturday Sat Sa'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'a few seconds', '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'a minute',      '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'a minute',      '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 minutes',     '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 minutes',    '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'an hour',       '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'an hour',       '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 hours',       '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 hours',       '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 hours',      '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'a day',         '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'a day',         '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 days',        '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'a day',         '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 days',        '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 days',       '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'a month',       '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'a month',       '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'a month',       '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 months',      '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 months',      '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 months',      '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'a month',       '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 months',      '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'a year',        '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 years',       '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'a year',        '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 years',       '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'in a few seconds',  'prefix');\n    assert.equal(moment(0).from(30000), 'a few seconds ago', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'a few seconds ago',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'in a few seconds', 'in a few seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), 'in 5 days', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'Today at 12:00',      'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'Today at 12:25',      'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'Today at 13:00',      'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'Tomorrow at 12:00',   'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'Today at 11:00',      'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'Yesterday at 12:00',  'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('dddd [at] LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd [at] LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd [at] LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('[Last] dddd [at] LT'),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[Last] dddd [at] LT'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[Last] dddd [at] LT'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2012, 0,  1]).format('w ww wo'), '52 52 52nd', 'Jan  1 2012 should be week 52');\n    assert.equal(moment([2012, 0,  2]).format('w ww wo'),   '1 01 1st', 'Jan  2 2012 should be week 1');\n    assert.equal(moment([2012, 0,  8]).format('w ww wo'),   '1 01 1st', 'Jan  8 2012 should be week 1');\n    assert.equal(moment([2012, 0,  9]).format('w ww wo'),   '2 02 2nd', 'Jan  9 2012 should be week 2');\n    assert.equal(moment([2012, 0, 15]).format('w ww wo'),   '2 02 2nd', 'Jan 15 2012 should be week 2');\n});\n\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/test/locale/en-ie.js",
    "content": "import {localeModule, test} from '../qunit';\nimport moment from '../../moment';\nlocaleModule('en-ie');\n\ntest('parse', function (assert) {\n    var tests = 'January Jan_February Feb_March Mar_April Apr_May May_June Jun_July Jul_August Aug_September Sep_October Oct_November Nov_December Dec'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, MMMM Do YYYY, h:mm:ss a',      'Sunday, February 14th 2010, 3:25:50 pm'],\n            ['ddd, hA',                            'Sun, 3PM'],\n            ['M Mo MM MMMM MMM',                   '2 2nd 02 February Feb'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14th 14'],\n            ['d do dddd ddd dd',                   '0 0th Sunday Sun Su'],\n            ['DDD DDDo DDDD',                      '45 45th 045'],\n            ['w wo ww',                            '6 6th 06'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'pm PM'],\n            ['[the] DDDo [day of the year]',       'the 45th day of the year'],\n            ['LTS',                                '15:25:50'],\n            ['L',                                  '14-02-2010'],\n            ['LL',                                 '14 February 2010'],\n            ['LLL',                                '14 February 2010 15:25'],\n            ['LLLL',                               'Sunday 14 February 2010 15:25'],\n            ['l',                                  '14-2-2010'],\n            ['ll',                                 '14 Feb 2010'],\n            ['lll',                                '14 Feb 2010 15:25'],\n            ['llll',                               'Sun 14 Feb 2010 15:25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1st', '1st');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2nd', '2nd');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3rd', '3rd');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4th', '4th');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5th', '5th');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6th', '6th');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7th', '7th');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8th', '8th');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9th', '9th');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10th', '10th');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11th', '11th');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12th', '12th');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13th', '13th');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14th', '14th');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15th', '15th');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16th', '16th');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17th', '17th');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18th', '18th');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19th', '19th');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20th', '20th');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21st', '21st');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22nd', '22nd');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23rd', '23rd');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24th', '24th');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25th', '25th');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26th', '26th');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27th', '27th');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28th', '28th');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29th', '29th');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30th', '30th');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31st', '31st');\n});\n\ntest('format month', function (assert) {\n    var expected = 'January Jan_February Feb_March Mar_April Apr_May May_June Jun_July Jul_August Aug_September Sep_October Oct_November Nov_December Dec'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'Sunday Sun Su_Monday Mon Mo_Tuesday Tue Tu_Wednesday Wed We_Thursday Thu Th_Friday Fri Fr_Saturday Sat Sa'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'a few seconds', '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'a minute',      '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'a minute',      '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 minutes',     '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 minutes',    '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'an hour',       '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'an hour',       '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 hours',       '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 hours',       '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 hours',      '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'a day',         '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'a day',         '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 days',        '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'a day',         '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 days',        '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 days',       '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'a month',       '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'a month',       '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'a month',       '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 months',      '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 months',      '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 months',      '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'a month',       '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 months',      '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'a year',        '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 years',       '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'a year',        '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 years',       '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'in a few seconds',  'prefix');\n    assert.equal(moment(0).from(30000), 'a few seconds ago', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'a few seconds ago',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'in a few seconds', 'in a few seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), 'in 5 days', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'Today at 12:00',      'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'Today at 12:25',      'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'Today at 13:00',      'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'Tomorrow at 12:00',   'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'Today at 11:00',      'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'Yesterday at 12:00',  'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('dddd [at] LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd [at] LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd [at] LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('[Last] dddd [at] LT'),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[Last] dddd [at] LT'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[Last] dddd [at] LT'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2012, 0,  1]).format('w ww wo'), '52 52 52nd', 'Jan  1 2012 should be week 52');\n    assert.equal(moment([2012, 0,  2]).format('w ww wo'),   '1 01 1st', 'Jan  2 2012 should be week 1');\n    assert.equal(moment([2012, 0,  8]).format('w ww wo'),   '1 01 1st', 'Jan  8 2012 should be week 1');\n    assert.equal(moment([2012, 0,  9]).format('w ww wo'),   '2 02 2nd', 'Jan  9 2012 should be week 2');\n    assert.equal(moment([2012, 0, 15]).format('w ww wo'),   '2 02 2nd', 'Jan 15 2012 should be week 2');\n});\n\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/test/locale/en-nz.js",
    "content": "import {localeModule, test} from '../qunit';\nimport moment from '../../moment';\nlocaleModule('en-nz');\n\ntest('parse', function (assert) {\n    var tests = 'January Jan_February Feb_March Mar_April Apr_May May_June Jun_July Jul_August Aug_September Sep_October Oct_November Nov_December Dec'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, MMMM Do YYYY, h:mm:ss a',      'Sunday, February 14th 2010, 3:25:50 pm'],\n            ['ddd, hA',                            'Sun, 3PM'],\n            ['M Mo MM MMMM MMM',                   '2 2nd 02 February Feb'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14th 14'],\n            ['d do dddd ddd dd',                   '0 0th Sunday Sun Su'],\n            ['DDD DDDo DDDD',                      '45 45th 045'],\n            ['w wo ww',                            '6 6th 06'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'pm PM'],\n            ['[the] DDDo [day of the year]',       'the 45th day of the year'],\n            ['LTS',                                '3:25:50 PM'],\n            ['L',                                  '14/02/2010'],\n            ['LL',                                 '14 February 2010'],\n            ['LLL',                                '14 February 2010 3:25 PM'],\n            ['LLLL',                               'Sunday, 14 February 2010 3:25 PM'],\n            ['l',                                  '14/2/2010'],\n            ['ll',                                 '14 Feb 2010'],\n            ['lll',                                '14 Feb 2010 3:25 PM'],\n            ['llll',                               'Sun, 14 Feb 2010 3:25 PM']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1st', '1st');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2nd', '2nd');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3rd', '3rd');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4th', '4th');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5th', '5th');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6th', '6th');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7th', '7th');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8th', '8th');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9th', '9th');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10th', '10th');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11th', '11th');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12th', '12th');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13th', '13th');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14th', '14th');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15th', '15th');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16th', '16th');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17th', '17th');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18th', '18th');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19th', '19th');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20th', '20th');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21st', '21st');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22nd', '22nd');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23rd', '23rd');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24th', '24th');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25th', '25th');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26th', '26th');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27th', '27th');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28th', '28th');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29th', '29th');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30th', '30th');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31st', '31st');\n});\n\ntest('format month', function (assert) {\n    var expected = 'January Jan_February Feb_March Mar_April Apr_May May_June Jun_July Jul_August Aug_September Sep_October Oct_November Nov_December Dec'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'Sunday Sun Su_Monday Mon Mo_Tuesday Tue Tu_Wednesday Wed We_Thursday Thu Th_Friday Fri Fr_Saturday Sat Sa'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'a few seconds', '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'a minute',      '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'a minute',      '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 minutes',     '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 minutes',    '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'an hour',       '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'an hour',       '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 hours',       '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 hours',       '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 hours',      '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'a day',         '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'a day',         '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 days',        '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'a day',         '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 days',        '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 days',       '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'a month',       '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'a month',       '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'a month',       '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 months',      '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 months',      '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 months',      '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'a month',       '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 months',      '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'a year',        '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 years',       '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'a year',        '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 years',       '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'in a few seconds',  'prefix');\n    assert.equal(moment(0).from(30000), 'a few seconds ago', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'a few seconds ago',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'in a few seconds', 'in a few seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), 'in 5 days', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'Today at 12:00 PM',     'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'Today at 12:25 PM',     'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'Today at 1:00 PM',      'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'Tomorrow at 12:00 PM',  'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'Today at 11:00 AM',     'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'Yesterday at 12:00 PM', 'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('dddd [at] LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd [at] LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd [at] LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('[Last] dddd [at] LT'),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[Last] dddd [at] LT'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[Last] dddd [at] LT'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2012, 0,  1]).format('w ww wo'), '52 52 52nd', 'Jan  1 2012 should be week 52');\n    assert.equal(moment([2012, 0,  2]).format('w ww wo'),   '1 01 1st', 'Jan  2 2012 should be week 1');\n    assert.equal(moment([2012, 0,  8]).format('w ww wo'),   '1 01 1st', 'Jan  8 2012 should be week 1');\n    assert.equal(moment([2012, 0,  9]).format('w ww wo'),   '2 02 2nd', 'Jan  9 2012 should be week 2');\n    assert.equal(moment([2012, 0, 15]).format('w ww wo'),   '2 02 2nd', 'Jan 15 2012 should be week 2');\n});\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/test/locale/en.js",
    "content": "import {localeModule, test} from '../qunit';\nimport moment from '../../moment';\nlocaleModule('en');\n\ntest('parse', function (assert) {\n    var i,\n        tests = 'January Jan_February Feb_March Mar_April Apr_May May_June Jun_July Jul_August Aug_September Sep_October Oct_November Nov_December Dec'.split('_');\n\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, MMMM Do YYYY, h:mm:ss a',      'Sunday, February 14th 2010, 3:25:50 pm'],\n            ['ddd, hA',                            'Sun, 3PM'],\n            ['M Mo MM MMMM MMM',                   '2 2nd 02 February Feb'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14th 14'],\n            ['d do dddd ddd dd',                   '0 0th Sunday Sun Su'],\n            ['DDD DDDo DDDD',                      '45 45th 045'],\n            ['w wo ww',                            '8 8th 08'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'pm PM'],\n            ['[the] DDDo [day of the year]',       'the 45th day of the year'],\n            ['LTS',                                '3:25:50 PM'],\n            ['L',                                  '02/14/2010'],\n            ['LL',                                 'February 14, 2010'],\n            ['LLL',                                'February 14, 2010 3:25 PM'],\n            ['LLLL',                               'Sunday, February 14, 2010 3:25 PM'],\n            ['l',                                  '2/14/2010'],\n            ['ll',                                 'Feb 14, 2010'],\n            ['lll',                                'Feb 14, 2010 3:25 PM'],\n            ['llll',                               'Sun, Feb 14, 2010 3:25 PM']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1st', '1st');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2nd', '2nd');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3rd', '3rd');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4th', '4th');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5th', '5th');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6th', '6th');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7th', '7th');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8th', '8th');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9th', '9th');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10th', '10th');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11th', '11th');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12th', '12th');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13th', '13th');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14th', '14th');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15th', '15th');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16th', '16th');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17th', '17th');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18th', '18th');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19th', '19th');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20th', '20th');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21st', '21st');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22nd', '22nd');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23rd', '23rd');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24th', '24th');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25th', '25th');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26th', '26th');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27th', '27th');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28th', '28th');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29th', '29th');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30th', '30th');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31st', '31st');\n});\n\ntest('format month', function (assert) {\n    var i,\n        expected = 'January Jan_February Feb_March Mar_April Apr_May May_June Jun_July Jul_August Aug_September Sep_October Oct_November Nov_December Dec'.split('_');\n\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var i,\n        expected = 'Sunday Sun Su_Monday Mon Mo_Tuesday Tue Tu_Wednesday Wed We_Thursday Thu Th_Friday Fri Fr_Saturday Sat Sa'.split('_');\n\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'a few seconds', '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'a minute',      '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'a minute',      '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 minutes',     '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 minutes',    '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'an hour',       '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'an hour',       '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 hours',       '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 hours',       '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 hours',      '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'a day',         '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'a day',         '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 days',        '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'a day',         '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 days',        '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 days',       '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'a month',       '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'a month',       '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'a month',       '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 months',      '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 months',      '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 months',      '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'a month',       '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 months',      '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'a year',        '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 years',       '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'a year',        '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 years',       '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'in a few seconds',  'prefix');\n    assert.equal(moment(0).from(30000), 'a few seconds ago', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'a few seconds ago',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'in a few seconds', 'in a few seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), 'in 5 days', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'Today at 12:00 PM',     'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'Today at 12:25 PM',     'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'Today at 1:00 PM',      'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'Tomorrow at 12:00 PM',  'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'Today at 11:00 AM',     'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'Yesterday at 12:00 PM', 'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('dddd [at] LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd [at] LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd [at] LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('[Last] dddd [at] LT'),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[Last] dddd [at] LT'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[Last] dddd [at] LT'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('weeks year starting sunday format', function (assert) {\n    assert.equal(moment([2012, 0,  1]).format('w ww wo'), '1 01 1st', 'Jan  1 2012 should be week 1');\n    assert.equal(moment([2012, 0,  7]).format('w ww wo'), '1 01 1st', 'Jan  7 2012 should be week 1');\n    assert.equal(moment([2012, 0,  8]).format('w ww wo'), '2 02 2nd', 'Jan  8 2012 should be week 2');\n    assert.equal(moment([2012, 0, 14]).format('w ww wo'), '2 02 2nd', 'Jan 14 2012 should be week 2');\n    assert.equal(moment([2012, 0, 15]).format('w ww wo'), '3 03 3rd', 'Jan 15 2012 should be week 3');\n});\n\ntest('weekdays strict parsing', function (assert) {\n    var m = moment('2015-01-01T12', moment.ISO_8601, true),\n        enLocale = moment.localeData('en');\n\n    for (var i = 0; i < 7; ++i) {\n        assert.equal(moment(enLocale.weekdays(m.day(i), ''), 'dddd', true).isValid(), true, 'parse weekday ' + i);\n        assert.equal(moment(enLocale.weekdaysShort(m.day(i), ''), 'ddd', true).isValid(), true, 'parse short weekday ' + i);\n        assert.equal(moment(enLocale.weekdaysMin(m.day(i), ''), 'dd', true).isValid(), true, 'parse min weekday ' + i);\n\n        // negative tests\n        assert.equal(moment(enLocale.weekdaysMin(m.day(i), ''), 'ddd', true).isValid(), false, 'parse short weekday ' + i);\n        assert.equal(moment(enLocale.weekdaysShort(m.day(i), ''), 'dd', true).isValid(), false, 'parse min weekday ' + i);\n    }\n});\n\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/test/locale/eo.js",
    "content": "import {localeModule, test} from '../qunit';\nimport moment from '../../moment';\nlocaleModule('eo');\n\ntest('parse', function (assert) {\n    var tests = 'januaro jan_februaro feb_marto mar_aprilo apr_majo maj_junio jun_julio jul_aŭgusto aŭg_septembro sep_oktobro okt_novembro nov_decembro dec'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, MMMM Do YYYY, h:mm:ss a',      'dimanĉo, februaro 14a 2010, 3:25:50 p.t.m.'],\n            ['ddd, hA',                            'dim, 3P.T.M.'],\n            ['M Mo MM MMMM MMM',                   '2 2a 02 februaro feb'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14a 14'],\n            ['d do dddd ddd dd',                   '0 0a dimanĉo dim di'],\n            ['DDD DDDo DDDD',                      '45 45a 045'],\n            ['w wo ww',                            '7 7a 07'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'p.t.m. P.T.M.'],\n            ['[la] DDDo [tago] [de] [la] [jaro]',  'la 45a tago de la jaro'],\n            ['LTS',                                '15:25:50'],\n            ['L',                                  '2010-02-14'],\n            ['LL',                                 '14-a de februaro, 2010'],\n            ['LLL',                                '14-a de februaro, 2010 15:25'],\n            ['LLLL',                               'dimanĉo, la 14-a de februaro, 2010 15:25'],\n            ['l',                                  '2010-2-14'],\n            ['ll',                                 '14-a de feb, 2010'],\n            ['lll',                                '14-a de feb, 2010 15:25'],\n            ['llll',                               'dim, la 14-a de feb, 2010 15:25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1a', '1a');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2a', '2a');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3a', '3a');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4a', '4a');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5a', '5a');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6a', '6a');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7a', '7a');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8a', '8a');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9a', '9a');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10a', '10a');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11a', '11a');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12a', '12a');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13a', '13a');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14a', '14a');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15a', '15a');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16a', '16a');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17a', '17a');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18a', '18a');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19a', '19a');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20a', '20a');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21a', '21a');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22a', '22a');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23a', '23a');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24a', '24a');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25a', '25a');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26a', '26a');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27a', '27a');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28a', '28a');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29a', '29a');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30a', '30a');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31a', '31a');\n});\n\ntest('format month', function (assert) {\n    var expected = 'januaro jan_februaro feb_marto mar_aprilo apr_majo maj_junio jun_julio jul_aŭgusto aŭg_septembro sep_oktobro okt_novembro nov_decembro dec'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'dimanĉo dim di_lundo lun lu_mardo mard ma_merkredo merk me_ĵaŭdo ĵaŭ ĵa_vendredo ven ve_sabato sab sa'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'sekundoj', '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'minuto',      '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'minuto',      '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 minutoj',     '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 minutoj',    '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'horo',       '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'horo',       '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 horoj',       '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 horoj',       '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 horoj',      '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'tago',         '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'tago',         '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 tagoj',        '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'tago',         '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 tagoj',        '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 tagoj',       '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'monato',       '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'monato',       '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'monato',       '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 monatoj',      '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 monatoj',      '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 monatoj',      '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'monato',       '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 monatoj',      '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'jaro',        '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 jaroj',       '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'jaro',        '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 jaroj',       '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'post sekundoj',  'post prefix');\n    assert.equal(moment(0).from(30000), 'antaŭ sekundoj', 'antaŭ prefix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'antaŭ sekundoj',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'post sekundoj', 'post sekundoj');\n    assert.equal(moment().add({d: 5}).fromNow(), 'post 5 tagoj', 'post 5 tagoj');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'Hodiaŭ je 12:00',     'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'Hodiaŭ je 12:25',     'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'Hodiaŭ je 13:00',     'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'Morgaŭ je 12:00',     'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'Hodiaŭ je 11:00',     'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'Hieraŭ je 12:00',     'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('dddd [je] LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd [je] LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd [je] LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('[pasinta] dddd [je] LT'),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[pasinta] dddd [je] LT'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[pasinta] dddd [je] LT'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2011, 11, 26]).format('w ww wo'), '1 01 1a', 'Dec 26 2011 should be week 1');\n    assert.equal(moment([2012,  0,  1]).format('w ww wo'), '1 01 1a', 'Jan  1 2012 should be week 1');\n    assert.equal(moment([2012,  0,  2]).format('w ww wo'), '2 02 2a', 'Jan  2 2012 should be week 2');\n    assert.equal(moment([2012,  0,  8]).format('w ww wo'), '2 02 2a', 'Jan  8 2012 should be week 2');\n    assert.equal(moment([2012,  0,  9]).format('w ww wo'), '3 03 3a', 'Jan  9 2012 should be week 3');\n});\n\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/test/locale/es-do.js",
    "content": "import {localeModule, test} from '../qunit';\nimport moment from '../../moment';\nlocaleModule('es-do');\n\ntest('parse', function (assert) {\n    var tests = 'enero ene._febrero feb._marzo mar._abril abr._mayo may._junio jun._julio jul._agosto ago._septiembre sep._octubre oct._noviembre nov._diciembre dic.'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, MMMM Do YYYY, h:mm:ss a',      'domingo, febrero 14º 2010, 3:25:50 pm'],\n            ['ddd, hA',                            'dom., 3PM'],\n            ['M Mo MM MMMM MMM',                   '2 2º 02 febrero feb.'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14º 14'],\n            ['d do dddd ddd dd',                   '0 0º domingo dom. do'],\n            ['DDD DDDo DDDD',                      '45 45º 045'],\n            ['w wo ww',                            '6 6º 06'],\n            ['YYYY-MMM-DD',                        '2010-feb-14'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'pm PM'],\n            ['[the] DDDo [day of the year]',       'the 45º day of the year'],\n            ['LTS',                                '3:25:50 PM'],\n            ['L',                                  '14/02/2010'],\n            ['LL',                                 '14 de febrero de 2010'],\n            ['LLL',                                '14 de febrero de 2010 3:25 PM'],\n            ['LLLL',                               'domingo, 14 de febrero de 2010 3:25 PM'],\n            ['l',                                  '14/2/2010'],\n            ['ll',                                 '14 de feb. de 2010'],\n            ['lll',                                '14 de feb. de 2010 3:25 PM'],\n            ['llll',                               'dom., 14 de feb. de 2010 3:25 PM']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1º', '1º');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2º', '2º');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3º', '3º');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4º', '4º');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5º', '5º');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6º', '6º');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7º', '7º');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8º', '8º');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9º', '9º');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10º', '10º');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11º', '11º');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12º', '12º');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13º', '13º');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14º', '14º');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15º', '15º');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16º', '16º');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17º', '17º');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18º', '18º');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19º', '19º');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20º', '20º');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21º', '21º');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22º', '22º');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23º', '23º');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24º', '24º');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25º', '25º');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26º', '26º');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27º', '27º');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28º', '28º');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29º', '29º');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30º', '30º');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31º', '31º');\n});\n\ntest('format month', function (assert) {\n    var expected = 'enero ene._febrero feb._marzo mar._abril abr._mayo may._junio jun._julio jul._agosto ago._septiembre sep._octubre oct._noviembre nov._diciembre dic.'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'domingo dom. do_lunes lun. lu_martes mar. ma_miércoles mié. mi_jueves jue. ju_viernes vie. vi_sábado sáb. sá'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'unos segundos', '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'un minuto',      '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'un minuto',      '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 minutos',     '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 minutos',    '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'una hora',       '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'una hora',       '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 horas',       '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 horas',       '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 horas',      '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'un día',         '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'un día',         '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 días',        '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'un día',         '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 días',        '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 días',       '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'un mes',       '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'un mes',       '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'un mes',       '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 meses',      '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 meses',      '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 meses',      '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'un mes',       '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 meses',      '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'un año',        '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 años',       '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'un año',        '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 años',       '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'en unos segundos',  'prefix');\n    assert.equal(moment(0).from(30000), 'hace unos segundos', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'hace unos segundos',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'en unos segundos', 'en unos segundos');\n    assert.equal(moment().add({d: 5}).fromNow(), 'en 5 días', 'en 5 días');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                       'hoy a las 12:00 PM',     'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),          'hoy a las 12:25 PM',     'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),           'hoy a las 1:00 PM',     'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),           'mañana a las 12:00 PM',  'tomorrow at the same time');\n    assert.equal(moment(a).add({d: 1, h : -1}).calendar(),   'mañana a las 11:00 AM',   'tomorrow minus 1 hour');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),      'hoy a las 11:00 AM',     'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),      'ayer a las 12:00 PM',    'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('dddd [a la' + ((m.hours() !== 1) ? 's' : '') + '] LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd [a la' + ((m.hours() !== 1) ? 's' : '') + '] LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd [a la' + ((m.hours() !== 1) ? 's' : '') + '] LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('[el] dddd [pasado a la' + ((m.hours() !== 1) ? 's' : '') + '] LT'),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[el] dddd [pasado a la' + ((m.hours() !== 1) ? 's' : '') + '] LT'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[el] dddd [pasado a la' + ((m.hours() !== 1) ? 's' : '') + '] LT'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2012, 0,  1]).format('w ww wo'), '52 52 52º', 'Jan  1 2012 should be week 52');\n    assert.equal(moment([2012, 0,  2]).format('w ww wo'),   '1 01 1º', 'Jan  2 2012 should be week 1');\n    assert.equal(moment([2012, 0,  8]).format('w ww wo'),   '1 01 1º', 'Jan  8 2012 should be week 1');\n    assert.equal(moment([2012, 0,  9]).format('w ww wo'),   '2 02 2º', 'Jan  9 2012 should be week 2');\n    assert.equal(moment([2012, 0, 15]).format('w ww wo'),   '2 02 2º', 'Jan 15 2012 should be week 2');\n});\n\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/test/locale/es.js",
    "content": "import {localeModule, test} from '../qunit';\nimport moment from '../../moment';\nlocaleModule('es');\n\ntest('parse', function (assert) {\n    var tests = 'enero ene._febrero feb._marzo mar._abril abr._mayo may._junio jun._julio jul._agosto ago._septiembre sep._octubre oct._noviembre nov._diciembre dic.'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, MMMM Do YYYY, h:mm:ss a',      'domingo, febrero 14º 2010, 3:25:50 pm'],\n            ['ddd, hA',                            'dom., 3PM'],\n            ['M Mo MM MMMM MMM',                   '2 2º 02 febrero feb.'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14º 14'],\n            ['d do dddd ddd dd',                   '0 0º domingo dom. do'],\n            ['DDD DDDo DDDD',                      '45 45º 045'],\n            ['w wo ww',                            '6 6º 06'],\n            ['YYYY-MMM-DD',                        '2010-feb-14'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'pm PM'],\n            ['[the] DDDo [day of the year]',       'the 45º day of the year'],\n            ['LTS',                                '15:25:50'],\n            ['L',                                  '14/02/2010'],\n            ['LL',                                 '14 de febrero de 2010'],\n            ['LLL',                                '14 de febrero de 2010 15:25'],\n            ['LLLL',                               'domingo, 14 de febrero de 2010 15:25'],\n            ['l',                                  '14/2/2010'],\n            ['ll',                                 '14 de feb. de 2010'],\n            ['lll',                                '14 de feb. de 2010 15:25'],\n            ['llll',                               'dom., 14 de feb. de 2010 15:25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1º', '1º');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2º', '2º');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3º', '3º');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4º', '4º');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5º', '5º');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6º', '6º');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7º', '7º');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8º', '8º');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9º', '9º');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10º', '10º');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11º', '11º');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12º', '12º');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13º', '13º');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14º', '14º');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15º', '15º');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16º', '16º');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17º', '17º');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18º', '18º');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19º', '19º');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20º', '20º');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21º', '21º');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22º', '22º');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23º', '23º');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24º', '24º');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25º', '25º');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26º', '26º');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27º', '27º');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28º', '28º');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29º', '29º');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30º', '30º');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31º', '31º');\n});\n\ntest('format month', function (assert) {\n    var expected = 'enero ene._febrero feb._marzo mar._abril abr._mayo may._junio jun._julio jul._agosto ago._septiembre sep._octubre oct._noviembre nov._diciembre dic.'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'domingo dom. do_lunes lun. lu_martes mar. ma_miércoles mié. mi_jueves jue. ju_viernes vie. vi_sábado sáb. sá'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'unos segundos', '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'un minuto',      '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'un minuto',      '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 minutos',     '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 minutos',    '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'una hora',       '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'una hora',       '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 horas',       '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 horas',       '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 horas',      '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'un día',         '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'un día',         '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 días',        '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'un día',         '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 días',        '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 días',       '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'un mes',       '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'un mes',       '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'un mes',       '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 meses',      '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 meses',      '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 meses',      '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'un mes',       '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 meses',      '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'un año',        '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 años',       '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'un año',        '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 años',       '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'en unos segundos',  'prefix');\n    assert.equal(moment(0).from(30000), 'hace unos segundos', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'hace unos segundos',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'en unos segundos', 'en unos segundos');\n    assert.equal(moment().add({d: 5}).fromNow(), 'en 5 días', 'en 5 días');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                       'hoy a las 12:00',     'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),          'hoy a las 12:25',     'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),           'hoy a las 13:00',     'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),           'mañana a las 12:00',  'tomorrow at the same time');\n    assert.equal(moment(a).add({d: 1, h : -1}).calendar(),   'mañana a las 11:00',   'tomorrow minus 1 hour');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),      'hoy a las 11:00',     'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),      'ayer a las 12:00',    'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('dddd [a la' + ((m.hours() !== 1) ? 's' : '') + '] LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd [a la' + ((m.hours() !== 1) ? 's' : '') + '] LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd [a la' + ((m.hours() !== 1) ? 's' : '') + '] LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('[el] dddd [pasado a la' + ((m.hours() !== 1) ? 's' : '') + '] LT'),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[el] dddd [pasado a la' + ((m.hours() !== 1) ? 's' : '') + '] LT'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[el] dddd [pasado a la' + ((m.hours() !== 1) ? 's' : '') + '] LT'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2012, 0,  1]).format('w ww wo'), '52 52 52º', 'Jan  1 2012 should be week 52');\n    assert.equal(moment([2012, 0,  2]).format('w ww wo'),   '1 01 1º', 'Jan  2 2012 should be week 1');\n    assert.equal(moment([2012, 0,  8]).format('w ww wo'),   '1 01 1º', 'Jan  8 2012 should be week 1');\n    assert.equal(moment([2012, 0,  9]).format('w ww wo'),   '2 02 2º', 'Jan  9 2012 should be week 2');\n    assert.equal(moment([2012, 0, 15]).format('w ww wo'),   '2 02 2º', 'Jan 15 2012 should be week 2');\n});\n\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/test/locale/et.js",
    "content": "import {localeModule, test} from '../qunit';\nimport moment from '../../moment';\nlocaleModule('et');\n\ntest('parse', function (assert) {\n    var tests = 'jaanuar jaan_veebruar veebr_märts märts_aprill apr_mai mai_juuni juuni_juuli juuli_august aug_september sept_oktoober okt_november nov_detsember dets'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' peaks olema kuu ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, Do MMMM YYYY, H:mm:ss',      'pühapäev, 14. veebruar 2010, 15:25:50'],\n            ['ddd, h',                           'P, 3'],\n            ['M Mo MM MMMM MMM',                 '2 2. 02 veebruar veebr'],\n            ['YYYY YY',                          '2010 10'],\n            ['D Do DD',                          '14 14. 14'],\n            ['d do dddd ddd dd',                 '0 0. pühapäev P P'],\n            ['DDD DDDo DDDD',                    '45 45. 045'],\n            ['w wo ww',                          '6 6. 06'],\n            ['h hh',                             '3 03'],\n            ['H HH',                             '15 15'],\n            ['m mm',                             '25 25'],\n            ['s ss',                             '50 50'],\n            ['a A',                              'pm PM'],\n            ['[aasta] DDDo [päev]',              'aasta 45. päev'],\n            ['LTS',                              '15:25:50'],\n            ['L',                                '14.02.2010'],\n            ['LL',                               '14. veebruar 2010'],\n            ['LLL',                              '14. veebruar 2010 15:25'],\n            ['LLLL',                             'pühapäev, 14. veebruar 2010 15:25'],\n            ['l',                                '14.2.2010'],\n            ['ll',                               '14. veebr 2010'],\n            ['lll',                              '14. veebr 2010 15:25'],\n            ['llll',                             'P, 14. veebr 2010 15:25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1.', '1.');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2.', '2.');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3.', '3.');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4.', '4.');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5.', '5.');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6.', '6.');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7.', '7.');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8.', '8.');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9.', '9.');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10.', '10.');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11.', '11.');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12.', '12.');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13.', '13.');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14.', '14.');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15.', '15.');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16.', '16.');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17.', '17.');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18.', '18.');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19.', '19.');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20.', '20.');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21.', '21.');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22.', '22.');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23.', '23.');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24.', '24.');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25.', '25.');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26.', '26.');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27.', '27.');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28.', '28.');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29.', '29.');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30.', '30.');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31.', '31.');\n});\n\ntest('format month', function (assert) {\n    var expected = 'jaanuar jaan_veebruar veebr_märts märts_aprill apr_mai mai_juuni juuni_juuli juuli_august aug_september sept_oktoober okt_november nov_detsember dets'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'pühapäev P P_esmaspäev E E_teisipäev T T_kolmapäev K K_neljapäev N N_reede R R_laupäev L L'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'paar sekundit',  '44 seconds = paar sekundit');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'üks minut',      '45 seconds = üks minut');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'üks minut',      '89 seconds = üks minut');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 minutit',      '90 seconds = 2 minutit');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 minutit',     '44 minutes = 44 minutit');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'üks tund',       '45 minutes = tund aega');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'üks tund',       '89 minutes = üks tund');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 tundi',        '90 minutes = 2 tundi');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 tundi',        '5 hours = 5 tundi');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 tundi',       '21 hours = 21 tundi');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'üks päev',       '22 hours = üks päev');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'üks päev',       '35 hours = üks päev');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 päeva',        '36 hours = 2 päeva');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'üks päev',       '1 day = üks päev');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 päeva',        '5 days = 5 päeva');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 päeva',       '25 days = 25 päeva');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'üks kuu',        '26 days = üks kuu');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'üks kuu',        '30 days = üks kuu');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'üks kuu',        '43 days = üks kuu');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 kuud',         '46 days = 2 kuud');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 kuud',         '75 days = 2 kuud');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 kuud',         '76 days = 3 kuud');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'üks kuu',        '1 month = üks kuu');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 kuud',         '5 months = 5 kuud');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'üks aasta',      '345 days = üks aasta');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 aastat',       '548 days = 2 aastat');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'üks aasta',      '1 year = üks aasta');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 aastat',       '5 years = 5 aastat');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'mõne sekundi pärast',  'prefix');\n    assert.equal(moment(0).from(30000), 'mõni sekund tagasi', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'mõni sekund tagasi',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'mõne sekundi pärast', 'in a few seconds');\n    assert.equal(moment().subtract({s: 30}).fromNow(), 'mõni sekund tagasi', 'a few seconds ago');\n\n    assert.equal(moment().add({m: 1}).fromNow(), 'ühe minuti pärast', 'in a minute');\n    assert.equal(moment().subtract({m: 1}).fromNow(), 'üks minut tagasi', 'a minute ago');\n\n    assert.equal(moment().add({m: 5}).fromNow(), '5 minuti pärast', 'in 5 minutes');\n    assert.equal(moment().subtract({m: 5}).fromNow(), '5 minutit tagasi', '5 minutes ago');\n\n    assert.equal(moment().add({d: 1}).fromNow(), 'ühe päeva pärast', 'in one day');\n    assert.equal(moment().subtract({d: 1}).fromNow(), 'üks päev tagasi', 'one day ago');\n\n    assert.equal(moment().add({d: 5}).fromNow(), '5 päeva pärast', 'in 5 days');\n    assert.equal(moment().subtract({d: 5}).fromNow(), '5 päeva tagasi', '5 days ago');\n\n    assert.equal(moment().add({M: 1}).fromNow(), 'kuu aja pärast', 'in a month');\n    assert.equal(moment().subtract({M: 1}).fromNow(), 'kuu aega tagasi', 'a month ago');\n\n    assert.equal(moment().add({M: 5}).fromNow(), '5 kuu pärast', 'in 5 months');\n    assert.equal(moment().subtract({M: 5}).fromNow(), '5 kuud tagasi', '5 months ago');\n\n    assert.equal(moment().add({y: 1}).fromNow(), 'ühe aasta pärast', 'in a year');\n    assert.equal(moment().subtract({y: 1}).fromNow(), 'aasta tagasi', 'a year ago');\n\n    assert.equal(moment().add({y: 5}).fromNow(), '5 aasta pärast', 'in 5 years');\n    assert.equal(moment().subtract({y: 5}).fromNow(), '5 aastat tagasi', '5 years ago');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'Täna, 12:00',     'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'Täna, 12:25',     'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'Täna, 13:00',     'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'Homme, 12:00',    'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'Täna, 11:00',     'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'Eile, 12:00',     'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('[Järgmine] dddd LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[Järgmine] dddd LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[Järgmine] dddd LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('[Eelmine] dddd LT'),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[Eelmine] dddd LT'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[Eelmine] dddd LT'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 nädal tagasi');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  '1 nädala pärast');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 nädalat tagasi');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  '2 nädala pärast');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2012, 0,  1]).format('w ww wo'), '52 52 52.', 'Jan  1 2012 should be week 52');\n    assert.equal(moment([2012, 0,  2]).format('w ww wo'),   '1 01 1.', 'Jan  2 2012 should be week 1');\n    assert.equal(moment([2012, 0,  8]).format('w ww wo'),   '1 01 1.', 'Jan  8 2012 should be week 1');\n    assert.equal(moment([2012, 0,  9]).format('w ww wo'),   '2 02 2.', 'Jan  9 2012 should be week 2');\n    assert.equal(moment([2012, 0, 15]).format('w ww wo'),   '2 02 2.', 'Jan 15 2012 should be week 2');\n});\n\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/test/locale/eu.js",
    "content": "import {localeModule, test} from '../qunit';\nimport moment from '../../moment';\nlocaleModule('eu');\n\ntest('parse', function (assert) {\n    var tests = 'urtarrila urt._otsaila ots._martxoa mar._apirila api._maiatza mai._ekaina eka._uztaila uzt._abuztua abu._iraila ira._urria urr._azaroa aza._abendua abe.'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, MMMM Do YYYY, h:mm:ss a',      'igandea, otsaila 14. 2010, 3:25:50 pm'],\n            ['ddd, hA',                            'ig., 3PM'],\n            ['M Mo MM MMMM MMM',                   '2 2. 02 otsaila ots.'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14. 14'],\n            ['d do dddd ddd dd',                   '0 0. igandea ig. ig'],\n            ['DDD DDDo DDDD',                      '45 45. 045'],\n            ['w wo ww',                            '7 7. 07'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'pm PM'],\n            ['[the] DDDo [day of the year]',       'the 45. day of the year'],\n            ['LTS',                                '15:25:50'],\n            ['L',                                  '2010-02-14'],\n            ['LL',                                 '2010ko otsailaren 14a'],\n            ['LLL',                                '2010ko otsailaren 14a 15:25'],\n            ['LLLL',                               'igandea, 2010ko otsailaren 14a 15:25'],\n            ['l',                                  '2010-2-14'],\n            ['ll',                                 '2010ko ots. 14a'],\n            ['lll',                                '2010ko ots. 14a 15:25'],\n            ['llll',                               'ig., 2010ko ots. 14a 15:25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1.', '1.');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2.', '2.');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3.', '3.');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4.', '4.');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5.', '5.');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6.', '6.');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7.', '7.');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8.', '8.');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9.', '9.');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10.', '10.');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11.', '11.');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12.', '12.');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13.', '13.');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14.', '14.');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15.', '15.');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16.', '16.');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17.', '17.');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18.', '18.');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19.', '19.');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20.', '20.');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21.', '21.');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22.', '22.');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23.', '23.');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24.', '24.');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25.', '25.');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26.', '26.');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27.', '27.');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28.', '28.');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29.', '29.');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30.', '30.');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31.', '31.');\n});\n\ntest('format month', function (assert) {\n    var expected = 'urtarrila urt._otsaila ots._martxoa mar._apirila api._maiatza mai._ekaina eka._uztaila uzt._abuztua abu._iraila ira._urria urr._azaroa aza._abendua abe.'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'igandea ig. ig_astelehena al. al_asteartea ar. ar_asteazkena az. az_osteguna og. og_ostirala ol. ol_larunbata lr. lr'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'segundo batzuk', '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'minutu bat',     '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'minutu bat',     '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 minutu',       '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 minutu',      '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'ordu bat',       '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'ordu bat',       '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 ordu',         '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 ordu',         '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 ordu',        '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'egun bat',       '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'egun bat',       '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 egun',         '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'egun bat',       '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 egun',         '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 egun',        '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'hilabete bat',   '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'hilabete bat',   '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'hilabete bat',   '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 hilabete',     '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 hilabete',     '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 hilabete',     '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'hilabete bat',   '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 hilabete',     '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'urte bat',       '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 urte',         '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'urte bat',       '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 urte',         '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'segundo batzuk barru',  'prefix');\n    assert.equal(moment(0).from(30000), 'duela segundo batzuk', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'duela segundo batzuk',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'segundo batzuk barru', 'in seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), '5 egun barru', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'gaur 12:00etan',  'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'gaur 12:25etan',  'now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'gaur 13:00etan',  'now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'bihar 12:00etan', 'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'gaur 11:00etan',  'now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'atzo 12:00etan',  'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('dddd LT[etan]'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd LT[etan]'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd LT[etan]'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('[aurreko] dddd LT[etan]'),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[aurreko] dddd LT[etan]'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[aurreko] dddd LT[etan]'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2011, 11, 26]).format('w ww wo'), '1 01 1.', 'Dec 26 2011 should be week 1');\n    assert.equal(moment([2012,  0,  1]).format('w ww wo'), '1 01 1.', 'Jan  1 2012 should be week 1');\n    assert.equal(moment([2012,  0,  2]).format('w ww wo'), '2 02 2.', 'Jan  2 2012 should be week 2');\n    assert.equal(moment([2012,  0,  8]).format('w ww wo'), '2 02 2.', 'Jan  8 2012 should be week 2');\n    assert.equal(moment([2012,  0,  9]).format('w ww wo'), '3 03 3.', 'Jan  9 2012 should be week 3');\n});\n\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/test/locale/fa.js",
    "content": "import {localeModule, test} from '../qunit';\nimport moment from '../../moment';\nlocaleModule('fa');\n\ntest('parse', function (assert) {\n    var tests = 'ژانویه_فوریه_مارس_آوریل_مه_ژوئن_ژوئیه_اوت_سپتامبر_اکتبر_نوامبر_دسامبر'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1) + ' instead is month ' + moment(input, mmm).month());\n    }\n    for (i = 0; i < 12; i++) {\n        equalTest(tests[i], 'MMM', i);\n        equalTest(tests[i], 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, MMMM Do YYYY, h:mm:ss a',      'یک\\u200cشنبه، فوریه ۱۴م ۲۰۱۰، ۳:۲۵:۵۰ بعد از ظهر'],\n            ['ddd, hA',                            'یک\\u200cشنبه، ۳بعد از ظهر'],\n            ['M Mo MM MMMM MMM',                   '۲ ۲م ۰۲ فوریه فوریه'],\n            ['YYYY YY',                            '۲۰۱۰ ۱۰'],\n            ['D Do DD',                            '۱۴ ۱۴م ۱۴'],\n            ['d do dddd ddd dd',                   '۰ ۰م یک\\u200cشنبه یک\\u200cشنبه ی'],\n            ['DDD DDDo DDDD',                      '۴۵ ۴۵م ۰۴۵'],\n            ['w wo ww',                            '۸ ۸م ۰۸'],\n            ['h hh',                               '۳ ۰۳'],\n            ['H HH',                               '۱۵ ۱۵'],\n            ['m mm',                               '۲۵ ۲۵'],\n            ['s ss',                               '۵۰ ۵۰'],\n            ['a A',                                'بعد از ظهر بعد از ظهر'],\n            ['DDDo [روز سال]',             '۴۵م روز سال'],\n            ['LTS',                                '۱۵:۲۵:۵۰'],\n            ['L',                                  '۱۴/۰۲/۲۰۱۰'],\n            ['LL',                                 '۱۴ فوریه ۲۰۱۰'],\n            ['LLL',                                '۱۴ فوریه ۲۰۱۰ ۱۵:۲۵'],\n            ['LLLL',                               'یک\\u200cشنبه، ۱۴ فوریه ۲۰۱۰ ۱۵:۲۵'],\n            ['l',                                  '۱۴/۲/۲۰۱۰'],\n            ['ll',                                 '۱۴ فوریه ۲۰۱۰'],\n            ['lll',                                '۱۴ فوریه ۲۰۱۰ ۱۵:۲۵'],\n            ['llll',                               'یک\\u200cشنبه، ۱۴ فوریه ۲۰۱۰ ۱۵:۲۵']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '۱م', '1');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '۲م', '2');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '۳م', '3');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '۴م', '4');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '۵م', '5');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '۶م', '6');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '۷م', '7');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '۸م', '8');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '۹م', '9');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '۱۰م', '10');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '۱۱م', '11');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '۱۲م', '12');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '۱۳م', '13');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '۱۴م', '14');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '۱۵م', '15');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '۱۶م', '16');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '۱۷م', '17');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '۱۸م', '18');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '۱۹م', '19');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '۲۰م', '20');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '۲۱م', '21');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '۲۲م', '22');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '۲۳م', '23');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '۲۴م', '24');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '۲۵م', '25');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '۲۶م', '26');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '۲۷م', '27');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '۲۸م', '28');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '۲۹م', '29');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '۳۰م', '30');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '۳۱م', '31');\n});\n\ntest('format month', function (assert) {\n    var expected = 'ژانویه ژانویه_فوریه فوریه_مارس مارس_آوریل آوریل_مه مه_ژوئن ژوئن_ژوئیه ژوئیه_اوت اوت_سپتامبر سپتامبر_اکتبر اکتبر_نوامبر نوامبر_دسامبر دسامبر'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'یک\\u200cشنبه یک\\u200cشنبه ی_دوشنبه دوشنبه د_سه\\u200cشنبه سه\\u200cشنبه س_چهارشنبه چهارشنبه چ_پنج\\u200cشنبه پنج\\u200cشنبه پ_جمعه جمعه ج_شنبه شنبه ش'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'چند ثانیه', '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'یک دقیقه',       '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'یک دقیقه',       '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '۲ دقیقه',     '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '۴۴ دقیقه',    '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'یک ساعت',     '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'یک ساعت',     '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '۲ ساعت',      '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '۵ ساعت',      '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '۲۱ ساعت',     '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'یک روز',      '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'یک روز',      '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '۲ روز',       '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'یک روز',      '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '۵ روز',       '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '۲۵ روز',      '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'یک ماه',      '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'یک ماه',      '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'یک ماه',      '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '۲ ماه',       '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '۲ ماه',       '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '۳ ماه',       '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'یک ماه',      '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '۵ ماه',       '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'یک سال',      '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '۲ سال',       '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'یک سال',      '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '۵ سال',       '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'در چند ثانیه', 'prefix');\n    assert.equal(moment(0).from(30000), 'چند ثانیه پیش', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'چند ثانیه پیش',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'در چند ثانیه', 'in a few seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), 'در ۵ روز', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'امروز ساعت ۱۲:۰۰', 'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'امروز ساعت ۱۲:۲۵', 'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'امروز ساعت ۱۳:۰۰', 'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'فردا ساعت ۱۲:۰۰', 'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'امروز ساعت ۱۱:۰۰', 'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'دیروز ساعت ۱۲:۰۰', 'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('dddd [ساعت] LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd [ساعت] LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd [ساعت] LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('dddd [پیش ساعت] LT'),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd [پیش ساعت] LT'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd [پیش ساعت] LT'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2011, 11, 31]).format('w ww wo'), '۱ ۰۱ ۱م', 'Dec 31 2011 should be week 1');\n    assert.equal(moment([2012,  0,  6]).format('w ww wo'), '۱ ۰۱ ۱م', 'Jan  6 2012 should be week 1');\n    assert.equal(moment([2012,  0,  7]).format('w ww wo'), '۲ ۰۲ ۲م', 'Jan  7 2012 should be week 2');\n    assert.equal(moment([2012,  0, 13]).format('w ww wo'), '۲ ۰۲ ۲م', 'Jan 13 2012 should be week 2');\n    assert.equal(moment([2012,  0, 14]).format('w ww wo'), '۳ ۰۳ ۳م', 'Jan 14 2012 should be week 3');\n});\n\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/test/locale/fi.js",
    "content": "import {localeModule, test} from '../qunit';\nimport moment from '../../moment';\nlocaleModule('fi');\n\ntest('parse', function (assert) {\n    var tests = 'tammikuu tammi_helmikuu helmi_maaliskuu maalis_huhtikuu huhti_toukokuu touko_kesäkuu kesä_heinäkuu heinä_elokuu elo_syyskuu syys_lokakuu loka_marraskuu marras_joulukuu joulu'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, MMMM Do YYYY, h:mm:ss a',      'sunnuntai, helmikuu 14. 2010, 3:25:50 pm'],\n            ['ddd, hA',                            'su, 3PM'],\n            ['M Mo MM MMMM MMM',                   '2 2. 02 helmikuu helmi'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14. 14'],\n            ['d do dddd ddd dd',                   '0 0. sunnuntai su su'],\n            ['DDD DDDo DDDD',                      '45 45. 045'],\n            ['w wo ww',                            '6 6. 06'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'pm PM'],\n            ['[vuoden] DDDo [päivä]',              'vuoden 45. päivä'],\n            ['LTS',                                '15.25.50'],\n            ['L',                                  '14.02.2010'],\n            ['LL',                                 '14. helmikuuta 2010'],\n            ['LLL',                                '14. helmikuuta 2010, klo 15.25'],\n            ['LLLL',                               'sunnuntai, 14. helmikuuta 2010, klo 15.25'],\n            ['l',                                  '14.2.2010'],\n            ['ll',                                 '14. helmi 2010'],\n            ['lll',                                '14. helmi 2010, klo 15.25'],\n            ['llll',                               'su, 14. helmi 2010, klo 15.25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1.', '1st');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2.', '2nd');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3.', '3rd');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4.', '4th');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5.', '5th');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6.', '6th');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7.', '7th');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8.', '8th');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9.', '9th');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10.', '10th');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11.', '11th');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12.', '12th');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13.', '13th');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14.', '14th');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15.', '15th');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16.', '16th');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17.', '17th');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18.', '18th');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19.', '19th');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20.', '20th');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21.', '21st');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22.', '22nd');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23.', '23rd');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24.', '24th');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25.', '25th');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26.', '26th');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27.', '27th');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28.', '28th');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29.', '29th');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30.', '30th');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31.', '31st');\n});\n\ntest('format month', function (assert) {\n    var expected = 'tammikuu tammi_helmikuu helmi_maaliskuu maalis_huhtikuu huhti_toukokuu touko_kesäkuu kesä_heinäkuu heinä_elokuu elo_syyskuu syys_lokakuu loka_marraskuu marras_joulukuu joulu'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'sunnuntai su su_maanantai ma ma_tiistai ti ti_keskiviikko ke ke_torstai to to_perjantai pe pe_lauantai la la'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'muutama sekunti', '44 seconds = few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'minuutti',      '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'minuutti',      '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  'kaksi minuuttia',     '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 minuuttia',    '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'tunti',       '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'tunti',       '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  'kaksi tuntia',       '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   'viisi tuntia',       '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 tuntia',      '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'päivä',         '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'päivä',         '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  'kaksi päivää',        '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'päivä',         '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   'viisi päivää',        '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 päivää',       '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'kuukausi',       '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'kuukausi',       '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'kuukausi',       '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  'kaksi kuukautta',      '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  'kaksi kuukautta',      '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  'kolme kuukautta',      '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'kuukausi',       '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   'viisi kuukautta',      '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'vuosi',        '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), 'kaksi vuotta',       '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'vuosi',        '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   'viisi vuotta',       '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'muutaman sekunnin päästä',  'prefix');\n    assert.equal(moment(0).from(30000), 'muutama sekunti sitten', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'muutama sekunti sitten',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'muutaman sekunnin päästä', 'in a few seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), 'viiden päivän päästä', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'tänään klo 12.00',    'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'tänään klo 12.25',    'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'tänään klo 13.00',    'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'huomenna klo 12.00',  'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'tänään klo 11.00',    'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'eilen klo 12.00',     'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('dddd [klo] LT'),  'today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd [klo] LT'),  'today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd [klo] LT'),  'today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('[viime] dddd[na] [klo] LT'),  'today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[viime] dddd[na] [klo] LT'),  'today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[viime] dddd[na] [klo] LT'),  'today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  'yksi viikko sitten');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'yhden viikon päästä');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  'kaksi viikkoa sitten');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'kaden viikon päästä');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2012, 0,  1]).format('w ww wo'), '52 52 52.', 'Jan  1 2012 should be week 52');\n    assert.equal(moment([2012, 0,  2]).format('w ww wo'),   '1 01 1.', 'Jan  2 2012 should be week 1');\n    assert.equal(moment([2012, 0,  8]).format('w ww wo'),   '1 01 1.', 'Jan  8 2012 should be week 1');\n    assert.equal(moment([2012, 0,  9]).format('w ww wo'),   '2 02 2.', 'Jan  9 2012 should be week 2');\n    assert.equal(moment([2012, 0, 15]).format('w ww wo'),   '2 02 2.', 'Jan 15 2012 should be week 2');\n});\n\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/test/locale/fo.js",
    "content": "import {localeModule, test} from '../qunit';\nimport moment from '../../moment';\nlocaleModule('fo');\n\ntest('parse', function (assert) {\n    var tests = 'januar jan_februar feb_mars mar_apríl apr_mai mai_juni jun_juli jul_august aug_september sep_oktober okt_november nov_desember des'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd [tann] Do MMMM YYYY, h:mm:ss a', 'sunnudagur tann 14. februar 2010, 3:25:50 pm'],\n            ['ddd hA',                             'sun 3PM'],\n            ['M Mo MM MMMM MMM',                   '2 2. 02 februar feb'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14. 14'],\n            ['d do dddd ddd dd',                   '0 0. sunnudagur sun su'],\n            ['DDD DDDo DDDD',                      '45 45. 045'],\n            ['w wo ww',                            '6 6. 06'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'pm PM'],\n            ['[tann] DDDo [dagin á árinum]',       'tann 45. dagin á árinum'],\n            ['LTS',                                '15:25:50'],\n            ['L',                                  '14/02/2010'],\n            ['LL',                                 '14 februar 2010'],\n            ['LLL',                                '14 februar 2010 15:25'],\n            ['LLLL',                               'sunnudagur 14. februar, 2010 15:25'],\n            ['l',                                  '14/2/2010'],\n            ['ll',                                 '14 feb 2010'],\n            ['lll',                                '14 feb 2010 15:25'],\n            ['llll',                               'sun 14. feb, 2010 15:25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1.', '1.');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2.', '2.');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3.', '3.');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4.', '4.');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5.', '5.');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6.', '6.');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7.', '7.');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8.', '8.');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9.', '9.');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10.', '10.');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11.', '11.');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12.', '12.');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13.', '13.');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14.', '14.');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15.', '15.');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16.', '16.');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17.', '17.');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18.', '18.');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19.', '19.');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20.', '20.');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21.', '21.');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22.', '22.');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23.', '23.');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24.', '24.');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25.', '25.');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26.', '26.');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27.', '27.');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28.', '28.');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29.', '29.');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30.', '30.');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31.', '31.');\n});\n\ntest('format month', function (assert) {\n    var expected = 'januar jan_februar feb_mars mar_apríl apr_mai mai_juni jun_juli jul_august aug_september sep_oktober okt_november nov_desember des'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'sunnudagur sun su_mánadagur mán má_týsdagur týs tý_mikudagur mik mi_hósdagur hós hó_fríggjadagur frí fr_leygardagur ley le'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'fá sekund', '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'ein minutt',    '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'ein minutt',    '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 minuttir',  '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 minuttir', '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'ein tími',     '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'ein tími',     '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 tímar',     '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 tímar',     '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 tímar',    '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'ein dagur',      '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'ein dagur',      '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 dagar',      '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'ein dagur',      '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 dagar',      '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 dagar',     '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'ein mánaði',    '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'ein mánaði',    '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'ein mánaði',    '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 mánaðir',   '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 mánaðir',   '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 mánaðir',   '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'ein mánaði',    '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 mánaðir',   '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'eitt ár',       '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 ár',        '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'eitt ár',       '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 ár',        '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'um fá sekund',  'prefix');\n    assert.equal(moment(0).from(30000), 'fá sekund síðani', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'fá sekund síðani',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'um fá sekund', 'in a few seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), 'um 5 dagar', 'in 5 days');\n});\n\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'Í dag kl. 12:00',    'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'Í dag kl. 12:25',    'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'Í dag kl. 13:00',    'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'Í morgin kl. 12:00', 'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'Í dag kl. 11:00',    'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'Í gjár kl. 12:00',   'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('dddd [kl.] LT'),  'today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd [kl.] LT'),  'today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd [kl.] LT'),  'today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('[síðstu] dddd [kl] LT'),  'today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[síðstu] dddd [kl] LT'),  'today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[síðstu] dddd [kl] LT'),  'today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  'yksi viikko sitten');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'yhden viikon päästä');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  'kaksi viikkoa sitten');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'kaden viikon päästä');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2012, 0,  1]).format('w ww wo'), '52 52 52.', 'Jan  1 2012 should be week 52');\n    assert.equal(moment([2012, 0,  2]).format('w ww wo'),   '1 01 1.', 'Jan  2 2012 should be week 1');\n    assert.equal(moment([2012, 0,  8]).format('w ww wo'),   '1 01 1.', 'Jan  8 2012 should be week 1');\n    assert.equal(moment([2012, 0,  9]).format('w ww wo'),   '2 02 2.', 'Jan  9 2012 should be week 2');\n    assert.equal(moment([2012, 0, 15]).format('w ww wo'),   '2 02 2.', 'Jan 15 2012 should be week 2');\n});\n\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/test/locale/fr-ca.js",
    "content": "import {localeModule, test} from '../qunit';\nimport moment from '../../moment';\nlocaleModule('fr-ca');\n\ntest('parse', function (assert) {\n    var i,\n        tests = 'janvier janv._février févr._mars mars_avril avr._mai mai_juin juin_juillet juil._août août_septembre sept._octobre oct._novembre nov._décembre déc.'.split('_');\n\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, MMMM Do YYYY, h:mm:ss a', 'dimanche, février 14e 2010, 3:25:50 pm'],\n            ['ddd, hA',                       'dim., 3PM'],\n            ['M Mo MM MMMM MMM',              '2 2e 02 février févr.'],\n            ['YYYY YY',                       '2010 10'],\n            ['D Do DD',                       '14 14e 14'],\n            ['d do dddd ddd dd',              '0 0e dimanche dim. Di'],\n            ['DDD DDDo DDDD',                 '45 45e 045'],\n            ['w wo ww',                       '8 8e 08'],\n            ['h hh',                          '3 03'],\n            ['H HH',                          '15 15'],\n            ['m mm',                          '25 25'],\n            ['s ss',                          '50 50'],\n            ['a A',                           'pm PM'],\n            ['[le] Do [jour du mois]',        'le 14e jour du mois'],\n            ['[le] DDDo [jour de l’année]',   'le 45e jour de l’année'],\n            ['LTS',                           '15:25:50'],\n            ['L',                             '2010-02-14'],\n            ['LL',                            '14 février 2010'],\n            ['LLL',                           '14 février 2010 15:25'],\n            ['LLLL',                          'dimanche 14 février 2010 15:25'],\n            ['l',                             '2010-2-14'],\n            ['ll',                            '14 févr. 2010'],\n            ['lll',                           '14 févr. 2010 15:25'],\n            ['llll',                          'dim. 14 févr. 2010 15:25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2017, 0, 1]).format('Mo'),     '1er',     '1er');\n    assert.equal(moment([2017, 1, 1]).format('Mo'),     '2e',      '2e');\n\n    assert.equal(moment([2017, 0, 1]).format('Qo'),     '1er',     '1er');\n    assert.equal(moment([2017, 3, 1]).format('Qo'),     '2e',      '2e');\n\n    assert.equal(moment([2017, 0, 1]).format('Do'),     '1er',     '1er');\n    assert.equal(moment([2017, 0, 2]).format('Do'),     '2e',      '2e');\n\n    assert.equal(moment([2011, 0, 1]).format('DDDo'),   '1er',     '1er');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'),   '2e',      '2e');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'),   '3e',      '3e');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'),   '4e',      '4e');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'),   '5e',      '5e');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'),   '6e',      '6e');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'),   '7e',      '7e');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'),   '8e',      '8e');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'),   '9e',      '9e');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'),  '10e',     '10e');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'),  '11e',     '11e');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'),  '12e',     '12e');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'),  '13e',     '13e');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'),  '14e',     '14e');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'),  '15e',     '15e');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'),  '16e',     '16e');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'),  '17e',     '17e');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'),  '18e',     '18e');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'),  '19e',     '19e');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'),  '20e',     '20e');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'),  '21e',     '21e');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'),  '22e',     '22e');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'),  '23e',     '23e');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'),  '24e',     '24e');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'),  '25e',     '25e');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'),  '26e',     '26e');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'),  '27e',     '27e');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'),  '28e',     '28e');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'),  '29e',     '29e');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'),  '30e',     '30e');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'),  '31e',     '31e');\n\n    assert.equal(moment([2017, 0, 1]).format('do'),     '0e',      '0e');\n    assert.equal(moment([2017, 0, 2]).format('do'),     '1er',     '1er');\n\n    assert.equal(moment([2017, 0, 4]).format('wo Wo'),  '1re 1re', '1re 1re');\n    assert.equal(moment([2017, 0, 11]).format('wo Wo'), '2e 2e',   '2e 2e');\n});\n\ntest('format month', function (assert) {\n    var i,\n        expected = 'janvier janv._février févr._mars mars_avril avr._mai mai_juin juin_juillet juil._août août_septembre sept._octobre oct._novembre nov._décembre déc.'.split('_');\n\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var i,\n        expected = 'dimanche dim. Di_lundi lun. Lu_mardi mar. Ma_mercredi mer. Me_jeudi jeu. Je_vendredi ven. Ve_samedi sam. Sa'.split('_');\n\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'quelques secondes', '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'une minute',        '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'une minute',        '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 minutes',         '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 minutes',        '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'une heure',         '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'une heure',         '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 heures',          '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 heures',          '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 heures',         '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'un jour',           '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'un jour',           '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 jours',           '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'un jour',           '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 jours',           '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 jours',          '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'un mois',           '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'un mois',           '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'un mois',           '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 mois',            '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 mois',            '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 mois',            '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'un mois',           '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 mois',            '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'un an',             '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 ans',             '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'un an',             '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 ans',             '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'dans quelques secondes',   'prefix');\n    assert.equal(moment(0).from(30000), 'il y a quelques secondes', 'suffix');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'dans quelques secondes', 'in a few seconds');\n    assert.equal(moment().add({d: 5}).fromNow(),  'dans 5 jours',           'in 5 days');\n});\n\ntest('same day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                  'Aujourd’hui à 12:00', 'Today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),     'Aujourd’hui à 12:25', 'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),      'Aujourd’hui à 13:00', 'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),      'Demain à 12:00',      'Tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(), 'Aujourd’hui à 11:00', 'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(), 'Hier à 12:00',        'Yesterday at the same time');\n});\n\ntest('same next week', function (assert) {\n    var i, m;\n\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(), m.format('dddd [à] LT'), 'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(), m.format('dddd [à] LT'), 'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(), m.format('dddd [à] LT'), 'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('same last week', function (assert) {\n    var i, m;\n\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(), m.format('dddd [dernier à] LT'), 'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(), m.format('dddd [dernier à] LT'), 'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(), m.format('dddd [dernier à] LT'), 'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('same all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),     weeksAgo.format('L'),     '1 week ago');\n    assert.equal(weeksFromNow.calendar(), weeksFromNow.format('L'), 'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),     weeksAgo.format('L'),     '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(), weeksFromNow.format('L'), 'in 2 weeks');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2012, 0,  1]).format('w ww wo'), '1 01 1re', 'Jan  1 2012 should be week 1');\n    assert.equal(moment([2012, 0,  7]).format('w ww wo'), '1 01 1re', 'Jan  7 2012 should be week 1');\n    assert.equal(moment([2012, 0,  8]).format('w ww wo'), '2 02 2e',  'Jan  8 2012 should be week 2');\n    assert.equal(moment([2012, 0, 14]).format('w ww wo'), '2 02 2e',  'Jan 14 2012 should be week 2');\n    assert.equal(moment([2012, 0, 15]).format('w ww wo'), '3 03 3e',  'Jan 15 2012 should be week 3');\n});\n\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/test/locale/fr-ch.js",
    "content": "import {localeModule, test} from '../qunit';\nimport moment from '../../moment';\nlocaleModule('fr-ch');\n\ntest('parse', function (assert) {\n    var i,\n        tests = 'janvier janv._février févr._mars mars_avril avr._mai mai_juin juin_juillet juil._août août_septembre sept._octobre oct._novembre nov._décembre déc.'.split('_');\n\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, MMMM Do YYYY, h:mm:ss a', 'dimanche, février 14e 2010, 3:25:50 pm'],\n            ['ddd, hA',                       'dim., 3PM'],\n            ['M Mo MM MMMM MMM',              '2 2e 02 février févr.'],\n            ['YYYY YY',                       '2010 10'],\n            ['D Do DD',                       '14 14e 14'],\n            ['d do dddd ddd dd',              '0 0e dimanche dim. Di'],\n            ['DDD DDDo DDDD',                 '45 45e 045'],\n            ['w wo ww',                       '6 6e 06'],\n            ['h hh',                          '3 03'],\n            ['H HH',                          '15 15'],\n            ['m mm',                          '25 25'],\n            ['s ss',                          '50 50'],\n            ['a A',                           'pm PM'],\n            ['[le] Do [jour du mois]',        'le 14e jour du mois'],\n            ['[le] DDDo [jour de l’année]',   'le 45e jour de l’année'],\n            ['LTS',                           '15:25:50'],\n            ['L',                             '14.02.2010'],\n            ['LL',                            '14 février 2010'],\n            ['LLL',                           '14 février 2010 15:25'],\n            ['LLLL',                          'dimanche 14 février 2010 15:25'],\n            ['l',                             '14.2.2010'],\n            ['ll',                            '14 févr. 2010'],\n            ['lll',                           '14 févr. 2010 15:25'],\n            ['llll',                          'dim. 14 févr. 2010 15:25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2017, 0, 1]).format('Mo'),     '1er',     '1er');\n    assert.equal(moment([2017, 1, 1]).format('Mo'),     '2e',      '2e');\n\n    assert.equal(moment([2017, 0, 1]).format('Qo'),     '1er',     '1er');\n    assert.equal(moment([2017, 3, 1]).format('Qo'),     '2e',      '2e');\n\n    assert.equal(moment([2017, 0, 1]).format('Do'),     '1er',     '1er');\n    assert.equal(moment([2017, 0, 2]).format('Do'),     '2e',      '2e');\n\n    assert.equal(moment([2011, 0, 1]).format('DDDo'),   '1er',     '1er');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'),   '2e',      '2e');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'),   '3e',      '3e');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'),   '4e',      '4e');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'),   '5e',      '5e');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'),   '6e',      '6e');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'),   '7e',      '7e');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'),   '8e',      '8e');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'),   '9e',      '9e');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'),  '10e',     '10e');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'),  '11e',     '11e');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'),  '12e',     '12e');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'),  '13e',     '13e');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'),  '14e',     '14e');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'),  '15e',     '15e');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'),  '16e',     '16e');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'),  '17e',     '17e');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'),  '18e',     '18e');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'),  '19e',     '19e');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'),  '20e',     '20e');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'),  '21e',     '21e');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'),  '22e',     '22e');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'),  '23e',     '23e');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'),  '24e',     '24e');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'),  '25e',     '25e');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'),  '26e',     '26e');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'),  '27e',     '27e');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'),  '28e',     '28e');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'),  '29e',     '29e');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'),  '30e',     '30e');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'),  '31e',     '31e');\n\n    assert.equal(moment([2017, 0, 1]).format('do'),     '0e',      '0e');\n    assert.equal(moment([2017, 0, 2]).format('do'),     '1er',     '1er');\n\n    assert.equal(moment([2017, 0, 4]).format('wo Wo'),  '1re 1re', '1re 1re');\n    assert.equal(moment([2017, 0, 11]).format('wo Wo'), '2e 2e',   '2e 2e');\n});\n\ntest('format month', function (assert) {\n    var i,\n        expected = 'janvier janv._février févr._mars mars_avril avr._mai mai_juin juin_juillet juil._août août_septembre sept._octobre oct._novembre nov._décembre déc.'.split('_');\n\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var i,\n        expected = 'dimanche dim. Di_lundi lun. Lu_mardi mar. Ma_mercredi mer. Me_jeudi jeu. Je_vendredi ven. Ve_samedi sam. Sa'.split('_');\n\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'quelques secondes', '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'une minute',        '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'une minute',        '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 minutes',         '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 minutes',        '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'une heure',         '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'une heure',         '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 heures',          '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 heures',          '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 heures',         '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'un jour',           '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'un jour',           '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 jours',           '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'un jour',           '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 jours',           '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 jours',          '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'un mois',           '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'un mois',           '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'un mois',           '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 mois',            '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 mois',            '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 mois',            '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'un mois',           '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 mois',            '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'un an',             '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 ans',             '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'un an',             '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 ans',             '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'dans quelques secondes',   'prefix');\n    assert.equal(moment(0).from(30000), 'il y a quelques secondes', 'suffix');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'dans quelques secondes', 'in a few seconds');\n    assert.equal(moment().add({d: 5}).fromNow(),  'dans 5 jours',           'in 5 days');\n});\n\ntest('same day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                  'Aujourd’hui à 12:00', 'Today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),     'Aujourd’hui à 12:25', 'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),      'Aujourd’hui à 13:00', 'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),      'Demain à 12:00',      'Tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(), 'Aujourd’hui à 11:00', 'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(), 'Hier à 12:00',        'Yesterday at the same time');\n});\n\ntest('same next week', function (assert) {\n    var i, m;\n\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(), m.format('dddd [à] LT'), 'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(), m.format('dddd [à] LT'), 'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(), m.format('dddd [à] LT'), 'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('same last week', function (assert) {\n    var i, m;\n\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(), m.format('dddd [dernier à] LT'), 'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(), m.format('dddd [dernier à] LT'), 'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(), m.format('dddd [dernier à] LT'), 'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('same all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),     weeksAgo.format('L'),     '1 week ago');\n    assert.equal(weeksFromNow.calendar(), weeksFromNow.format('L'), 'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),     weeksAgo.format('L'),     '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(), weeksFromNow.format('L'), 'in 2 weeks');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2012, 0,  1]).format('w ww wo'), '52 52 52e', 'Jan  1 2012 should be week 52');\n    assert.equal(moment([2012, 0,  2]).format('w ww wo'), '1 01 1re',  'Jan  2 2012 should be week 1');\n    assert.equal(moment([2012, 0,  8]).format('w ww wo'), '1 01 1re',  'Jan  8 2012 should be week 1');\n    assert.equal(moment([2012, 0,  9]).format('w ww wo'), '2 02 2e',   'Jan  9 2012 should be week 2');\n    assert.equal(moment([2012, 0, 15]).format('w ww wo'), '2 02 2e',   'Jan 15 2012 should be week 2');\n});\n\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/test/locale/fr.js",
    "content": "import {localeModule, test} from '../qunit';\nimport moment from '../../moment';\nlocaleModule('fr');\n\ntest('parse', function (assert) {\n    var i,\n        tests = 'janvier janv._février févr._mars mars_avril avr._mai mai_juin juin_juillet juil._août août_septembre sept._octobre oct._novembre nov._décembre déc.'.split('_');\n\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, MMMM Do YYYY, h:mm:ss a', 'dimanche, février 14 2010, 3:25:50 pm'],\n            ['ddd, hA',                       'dim., 3PM'],\n            ['M Mo MM MMMM MMM',              '2 2e 02 février févr.'],\n            ['YYYY YY',                       '2010 10'],\n            ['D Do DD',                       '14 14 14'],\n            ['d do dddd ddd dd',              '0 0e dimanche dim. Di'],\n            ['DDD DDDo DDDD',                 '45 45e 045'],\n            ['w wo ww',                       '6 6e 06'],\n            ['h hh',                          '3 03'],\n            ['H HH',                          '15 15'],\n            ['m mm',                          '25 25'],\n            ['s ss',                          '50 50'],\n            ['a A',                           'pm PM'],\n            ['[le] Do [jour du mois]',        'le 14 jour du mois'],\n            ['[le] DDDo [jour de l’année]',   'le 45e jour de l’année'],\n            ['LTS',                           '15:25:50'],\n            ['L',                             '14/02/2010'],\n            ['LL',                            '14 février 2010'],\n            ['LLL',                           '14 février 2010 15:25'],\n            ['LLLL',                          'dimanche 14 février 2010 15:25'],\n            ['l',                             '14/2/2010'],\n            ['ll',                            '14 févr. 2010'],\n            ['lll',                           '14 févr. 2010 15:25'],\n            ['llll',                          'dim. 14 févr. 2010 15:25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2017, 0, 1]).format('Mo'),     '1er',     '1er');\n    assert.equal(moment([2017, 1, 1]).format('Mo'),     '2e',      '2e');\n\n    assert.equal(moment([2017, 0, 1]).format('Qo'),     '1er',     '1er');\n    assert.equal(moment([2017, 3, 1]).format('Qo'),     '2e',      '2e');\n\n    assert.equal(moment([2017, 0, 1]).format('Do'),     '1er',     '1er');\n    assert.equal(moment([2017, 0, 2]).format('Do'),     '2',       '2');\n\n    assert.equal(moment([2011, 0, 1]).format('DDDo'),   '1er',     '1er');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'),   '2e',      '2e');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'),   '3e',      '3e');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'),   '4e',      '4e');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'),   '5e',      '5e');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'),   '6e',      '6e');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'),   '7e',      '7e');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'),   '8e',      '8e');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'),   '9e',      '9e');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'),  '10e',     '10e');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'),  '11e',     '11e');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'),  '12e',     '12e');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'),  '13e',     '13e');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'),  '14e',     '14e');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'),  '15e',     '15e');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'),  '16e',     '16e');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'),  '17e',     '17e');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'),  '18e',     '18e');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'),  '19e',     '19e');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'),  '20e',     '20e');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'),  '21e',     '21e');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'),  '22e',     '22e');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'),  '23e',     '23e');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'),  '24e',     '24e');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'),  '25e',     '25e');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'),  '26e',     '26e');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'),  '27e',     '27e');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'),  '28e',     '28e');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'),  '29e',     '29e');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'),  '30e',     '30e');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'),  '31e',     '31e');\n\n    assert.equal(moment([2017, 0, 1]).format('do'),     '0e',      '0e');\n    assert.equal(moment([2017, 0, 2]).format('do'),     '1er',     '1er');\n\n    assert.equal(moment([2017, 0, 4]).format('wo Wo'),  '1re 1re', '1re 1re');\n    assert.equal(moment([2017, 0, 11]).format('wo Wo'), '2e 2e',   '2e 2e');\n});\n\ntest('format month', function (assert) {\n    var i,\n        expected = 'janvier janv._février févr._mars mars_avril avr._mai mai_juin juin_juillet juil._août août_septembre sept._octobre oct._novembre nov._décembre déc.'.split('_');\n\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var i,\n        expected = 'dimanche dim. Di_lundi lun. Lu_mardi mar. Ma_mercredi mer. Me_jeudi jeu. Je_vendredi ven. Ve_samedi sam. Sa'.split('_');\n\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'quelques secondes', '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'une minute',        '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'une minute',        '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 minutes',         '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 minutes',        '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'une heure',         '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'une heure',         '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 heures',          '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 heures',          '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 heures',         '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'un jour',           '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'un jour',           '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 jours',           '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'un jour',           '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 jours',           '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 jours',          '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'un mois',           '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'un mois',           '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'un mois',           '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 mois',            '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 mois',            '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 mois',            '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'un mois',           '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 mois',            '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'un an',             '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 ans',             '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'un an',             '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 ans',             '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'dans quelques secondes',   'prefix');\n    assert.equal(moment(0).from(30000), 'il y a quelques secondes', 'suffix');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'dans quelques secondes', 'in a few seconds');\n    assert.equal(moment().add({d: 5}).fromNow(),  'dans 5 jours',           'in 5 days');\n});\n\ntest('same day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                  'Aujourd’hui à 12:00', 'Today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),     'Aujourd’hui à 12:25', 'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),      'Aujourd’hui à 13:00', 'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),      'Demain à 12:00',      'Tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(), 'Aujourd’hui à 11:00', 'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(), 'Hier à 12:00',        'Yesterday at the same time');\n});\n\ntest('same next week', function (assert) {\n    var i, m;\n\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(), m.format('dddd [à] LT'), 'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(), m.format('dddd [à] LT'), 'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(), m.format('dddd [à] LT'), 'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('same last week', function (assert) {\n    var i, m;\n\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(), m.format('dddd [dernier à] LT'), 'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(), m.format('dddd [dernier à] LT'), 'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(), m.format('dddd [dernier à] LT'), 'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('same all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),     weeksAgo.format('L'),     '1 week ago');\n    assert.equal(weeksFromNow.calendar(), weeksFromNow.format('L'), 'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),     weeksAgo.format('L'),     '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(), weeksFromNow.format('L'), 'in 2 weeks');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2012, 0,  1]).format('w ww wo'), '52 52 52e', 'Jan  1 2012 should be week 52');\n    assert.equal(moment([2012, 0,  2]).format('w ww wo'), '1 01 1re',  'Jan  2 2012 should be week 1');\n    assert.equal(moment([2012, 0,  8]).format('w ww wo'), '1 01 1re',  'Jan  8 2012 should be week 1');\n    assert.equal(moment([2012, 0,  9]).format('w ww wo'), '2 02 2e',   'Jan  9 2012 should be week 2');\n    assert.equal(moment([2012, 0, 15]).format('w ww wo'), '2 02 2e',   'Jan 15 2012 should be week 2');\n});\n\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/test/locale/fy.js",
    "content": "import {localeModule, test} from '../qunit';\nimport moment from '../../moment';\nlocaleModule('fy');\n\ntest('parse', function (assert) {\n    var tests = 'jannewaris jan._febrewaris feb._maart mrt._april apr._maaie mai._juny jun._july jul._augustus aug._septimber sep._oktober okt._novimber nov._desimber des.'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, MMMM Do YYYY, HH:mm:ss',       'snein, febrewaris 14de 2010, 15:25:50'],\n            ['ddd, HH',                            'si., 15'],\n            ['M Mo MM MMMM MMM',                   '2 2de 02 febrewaris feb.'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14de 14'],\n            ['d do dddd ddd dd',                   '0 0de snein si. Si'],\n            ['DDD DDDo DDDD',                      '45 45ste 045'],\n            ['w wo ww',                            '6 6de 06'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'pm PM'],\n            ['[the] DDDo [day of the year]',       'the 45ste day of the year'],\n            ['LTS',                                '15:25:50'],\n            ['L',                                  '14-02-2010'],\n            ['LL',                                 '14 febrewaris 2010'],\n            ['LLL',                                '14 febrewaris 2010 15:25'],\n            ['LLLL',                               'snein 14 febrewaris 2010 15:25'],\n            ['l',                                  '14-2-2010'],\n            ['ll',                                 '14 feb. 2010'],\n            ['lll',                                '14 feb. 2010 15:25'],\n            ['llll',                               'si. 14 feb. 2010 15:25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1ste', '1ste');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2de', '2de');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3de', '3de');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4de', '4de');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5de', '5de');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6de', '6de');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7de', '7de');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8ste', '8ste');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9de', '9de');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10de', '10de');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11de', '11de');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12de', '12de');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13de', '13de');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14de', '14de');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15de', '15de');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16de', '16de');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17de', '17de');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18de', '18de');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19de', '19de');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20ste', '20ste');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21ste', '21ste');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22ste', '22ste');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23ste', '23ste');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24ste', '24ste');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25ste', '25ste');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26ste', '26ste');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27ste', '27ste');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28ste', '28ste');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29ste', '29ste');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30ste', '30ste');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31ste', '31ste');\n});\n\ntest('format month', function (assert) {\n    var expected = 'jannewaris jan._febrewaris feb._maart mrt._april apr._maaie mai_juny jun._july jul._augustus aug._septimber sep._oktober okt._novimber nov._desimber des.'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'snein si. Si_moandei mo. Mo_tiisdei ti. Ti_woansdei wo. Wo_tongersdei to. To_freed fr. Fr_sneon so. So'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'in pear sekonden', '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'ien minút',      '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'ien minút',      '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 minuten',     '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 minuten',    '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'ien oere',       '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'ien oere',       '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 oeren',       '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 oeren',       '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 oeren',      '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'ien dei',         '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'ien dei',         '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 dagen',        '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'ien dei',         '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 dagen',        '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 dagen',       '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'ien moanne',       '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'ien moanne',       '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'ien moanne',       '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 moannen',      '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 moannen',      '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 moannen',      '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'ien moanne',       '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 moannen',      '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'ien jier',        '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 jierren',       '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'ien jier',        '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 jierren',       '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'oer in pear sekonden',  'prefix');\n    assert.equal(moment(0).from(30000), 'in pear sekonden lyn', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'in pear sekonden lyn',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'oer in pear sekonden', 'in a few seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), 'oer 5 dagen', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'hjoed om 12:00',     'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'hjoed om 12:25',     'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'hjoed om 13:00',     'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'moarn om 12:00',     'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'hjoed om 11:00',     'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'juster om 12:00',    'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('dddd [om] LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd [om] LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd [om] LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('[ôfrûne] dddd [om] LT'),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[ôfrûne] dddd [om] LT'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[ôfrûne] dddd [om] LT'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('month abbreviation', function (assert) {\n    assert.equal(moment([2012, 5, 23]).format('D-MMM-YYYY'), '23-jun-2012', 'format month abbreviation surrounded by dashes should not include a dot');\n    assert.equal(moment([2012, 5, 23]).format('D MMM YYYY'), '23 jun. 2012', 'format month abbreviation not surrounded by dashes should include a dot');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2012, 0,  1]).format('w ww wo'), '52 52 52ste', 'Jan  1 2012 should be week 52');\n    assert.equal(moment([2012, 0,  2]).format('w ww wo'),   '1 01 1ste', 'Jan  2 2012 should be week 1');\n    assert.equal(moment([2012, 0,  8]).format('w ww wo'),   '1 01 1ste', 'Jan  8 2012 should be week 1');\n    assert.equal(moment([2012, 0,  9]).format('w ww wo'),    '2 02 2de', 'Jan  9 2012 should be week 2');\n    assert.equal(moment([2012, 0, 15]).format('w ww wo'),    '2 02 2de', 'Jan 15 2012 should be week 2');\n});\n\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/test/locale/gd.js",
    "content": "import {localeModule, test} from '../qunit';\nimport moment from '../../moment';\nlocaleModule('gd');\n\nvar months = [\n    'Am Faoilleach,Faoi',\n    'An Gearran,Gear',\n    'Am Màrt,Màrt',\n    'An Giblean,Gibl',\n    'An Cèitean,Cèit',\n    'An t-Ògmhios,Ògmh',\n    'An t-Iuchar,Iuch',\n    'An Lùnastal,Lùn',\n    'An t-Sultain,Sult',\n    'An Dàmhair,Dàmh',\n    'An t-Samhain,Samh',\n    'An Dùbhlachd,Dùbh'\n];\n\ntest('parse', function (assert) {\n    function equalTest(monthName, monthFormat, monthNum) {\n        assert.equal(moment(monthName, monthFormat).month(), monthNum, monthName + ' should be month ' + (monthNum + 1));\n    }\n\n    for (var i = 0; i < 12; i++) {\n        var testMonth = months[i].split(',');\n        equalTest(testMonth[0], 'MMM', i);\n        equalTest(testMonth[1], 'MMM', i);\n        equalTest(testMonth[0], 'MMMM', i);\n        equalTest(testMonth[1], 'MMMM', i);\n        equalTest(testMonth[0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(testMonth[1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(testMonth[0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(testMonth[1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n        ['dddd, MMMM Do YYYY, h:mm:ss a', 'Didòmhnaich, An Gearran 14mh 2010, 3:25:50 pm'],\n        ['ddd, hA', 'Did, 3PM'],\n        ['M Mo MM MMMM MMM', '2 2na 02 An Gearran Gear'],\n        ['YYYY YY', '2010 10'],\n        ['D Do DD', '14 14mh 14'],\n        ['d do dddd ddd dd', '0 0mh Didòmhnaich Did Dò'],\n        ['DDD DDDo DDDD', '45 45mh 045'],\n        ['w wo ww', '6 6mh 06'],\n        ['h hh', '3 03'],\n        ['H HH', '15 15'],\n        ['m mm', '25 25'],\n        ['s ss', '50 50'],\n        ['a A', 'pm PM'],\n        ['[an] DDDo [latha den bhliadhna]', 'an 45mh latha den bhliadhna'],\n        ['LTS', '15:25:50'],\n        ['L', '14/02/2010'],\n        ['LL', '14 An Gearran 2010'],\n        ['LLL', '14 An Gearran 2010 15:25'],\n        ['LLLL', 'Didòmhnaich, 14 An Gearran 2010 15:25'],\n        ['l', '14/2/2010'],\n        ['ll', '14 Gear 2010'],\n        ['lll', '14 Gear 2010 15:25'],\n        ['llll', 'Did, 14 Gear 2010 15:25']\n    ],\n    b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n    i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1d', '1d');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2na', '2na');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3mh', '3mh');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4mh', '4mh');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5mh', '5mh');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6mh', '6mh');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7mh', '7mh');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8mh', '8mh');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9mh', '9mh');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10mh', '10mh');\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11mh', '11mh');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12na', '12na');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13mh', '13mh');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14mh', '14mh');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15mh', '15mh');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16mh', '16mh');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17mh', '17mh');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18mh', '18mh');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19mh', '19mh');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20mh', '20mh');\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21mh', '21mh');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22na', '22na');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23mh', '23mh');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24mh', '24mh');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25mh', '25mh');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26mh', '26mh');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27mh', '27mh');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28mh', '28mh');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29mh', '29mh');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30mh', '30mh');\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31mh', '31mh');\n});\n\ntest('format month', function (assert) {\n    var expected = months;\n    for (var i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM,MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = ['Didòmhnaich Did Dò', 'Diluain Dil Lu', 'Dimàirt Dim Mà', 'Diciadain Dic Ci', 'Diardaoin Dia Ar', 'Dihaoine Dih Ha', 'Disathairne Dis Sa'];\n    for (var i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true), 'beagan diogan', '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true), 'mionaid', '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true), 'mionaid', '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true), '2 mionaidean', '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true), '44 mionaidean', '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true), 'uair', '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true), 'uair', '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true), '2 uairean', '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true), '5 uairean', '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true), '21 uairean', '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true), 'latha', '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true), 'latha', '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true), '2 latha', '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true), 'latha', '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true), '5 latha', '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true), '25 latha', '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true), 'mìos', '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true), 'mìos', '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true), 'mìos', '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true), '2 mìosan', '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true), '2 mìosan', '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true), '3 mìosan', '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true), 'mìos', '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true), '5 mìosan', '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'bliadhna', '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 bliadhna', '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true), 'bliadhna', '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true), '5 bliadhna', '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'ann an beagan diogan', 'prefix');\n    assert.equal(moment(0).from(30000), 'bho chionn beagan diogan', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'bho chionn beagan diogan', 'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'ann an beagan diogan', 'in a few seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), 'ann an 5 latha', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                  'An-diugh aig 12:00',   'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),     'An-diugh aig 12:25',   'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),      'An-diugh aig 13:00',   'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),      'A-màireach aig 12:00', 'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(), 'An-diugh aig 11:00',   'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(), 'An-dè aig 12:00',      'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(), m.format('dddd [aig] LT'), 'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(), m.format('dddd [aig] LT'), 'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(), m.format('dddd [aig] LT'), 'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(), m.format('dddd [seo chaidh] [aig] LT'), 'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(), m.format('dddd [seo chaidh] [aig] LT'), 'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(), m.format('dddd [seo chaidh] [aig] LT'), 'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n       weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '1 week ago');\n    assert.equal(weeksFromNow.calendar(), weeksFromNow.format('L'), 'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(), weeksFromNow.format('L'), 'in 2 weeks');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2012, 0, 1]).format('w ww wo'), '52 52 52na', 'Faoi  1 2012 should be week 52');\n    assert.equal(moment([2012, 0, 2]).format('w ww wo'), '1 01 1d', 'Faoi  2 2012 should be week 1');\n    assert.equal(moment([2012, 0, 8]).format('w ww wo'), '1 01 1d', 'Faoi  8 2012 should be week 1');\n    assert.equal(moment([2012, 0, 9]).format('w ww wo'), '2 02 2na', 'Faoi  9 2012 should be week 2');\n    assert.equal(moment([2012, 0, 15]).format('w ww wo'), '2 02 2na', 'Faoi 15 2012 should be week 2');\n});\n\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/test/locale/gl.js",
    "content": "import {localeModule, test} from '../qunit';\nimport moment from '../../moment';\nlocaleModule('gl');\n\ntest('parse', function (assert) {\n    var tests = 'xaneiro xan._febreiro feb._marzo mar._abril abr._maio mai._xuño xuñ._xullo xul._agosto ago._setembro set._outubro out._novembro nov._decembro dec.'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, MMMM Do YYYY, h:mm:ss a',      'domingo, febreiro 14º 2010, 3:25:50 pm'],\n            ['ddd, hA',                            'dom., 3PM'],\n            ['M Mo MM MMMM MMM',                   '2 2º 02 febreiro feb.'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14º 14'],\n            ['d do dddd ddd dd',                   '0 0º domingo dom. do'],\n            ['DDD DDDo DDDD',                      '45 45º 045'],\n            ['w wo ww',                            '6 6º 06'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'pm PM'],\n            ['[the] DDDo [day of the year]',       'the 45º day of the year'],\n            ['LTS',                                '15:25:50'],\n            ['L',                                  '14/02/2010'],\n            ['LL',                                 '14 de febreiro de 2010'],\n            ['LLL',                                '14 de febreiro de 2010 15:25'],\n            ['LLLL',                               'domingo, 14 de febreiro de 2010 15:25'],\n            ['l',                                  '14/2/2010'],\n            ['ll',                                 '14 de feb. de 2010'],\n            ['lll',                                '14 de feb. de 2010 15:25'],\n            ['llll',                               'dom., 14 de feb. de 2010 15:25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1º', '1º');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2º', '2º');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3º', '3º');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4º', '4º');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5º', '5º');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6º', '6º');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7º', '7º');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8º', '8º');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9º', '9º');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10º', '10º');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11º', '11º');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12º', '12º');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13º', '13º');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14º', '14º');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15º', '15º');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16º', '16º');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17º', '17º');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18º', '18º');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19º', '19º');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20º', '20º');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21º', '21º');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22º', '22º');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23º', '23º');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24º', '24º');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25º', '25º');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26º', '26º');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27º', '27º');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28º', '28º');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29º', '29º');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30º', '30º');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31º', '31º');\n});\n\ntest('format month', function (assert) {\n    var expected = 'xaneiro xan._febreiro feb._marzo mar._abril abr._maio mai._xuño xuñ._xullo xul._agosto ago._setembro set._outubro out._novembro nov._decembro dec.'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'domingo dom. do_luns lun. lu_martes mar. ma_mércores mér. mé_xoves xov. xo_venres ven. ve_sábado sáb. sá'.split('_'),\n    i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'uns segundos', '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'un minuto',      '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'un minuto',      '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 minutos',     '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 minutos',    '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'unha hora',       '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'unha hora',       '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 horas',       '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 horas',       '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 horas',      '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'un día',         '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'un día',         '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 días',        '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'un día',         '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 días',        '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 días',       '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'un mes',       '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'un mes',       '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'un mes',       '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 meses',      '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 meses',      '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 meses',      '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'un mes',       '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 meses',      '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'un ano',        '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 anos',       '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'un ano',        '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 anos',       '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'nuns segundos',  'prefix');\n    assert.equal(moment(0).from(30000), 'hai uns segundos', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'hai uns segundos',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'nuns segundos', 'nuns segundos');\n    assert.equal(moment().add({d: 5}).fromNow(), 'en 5 días', 'en 5 días');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                       'hoxe ás 12:00',  'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),          'hoxe ás 12:25',  'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),           'hoxe ás 13:00',  'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),           'mañá ás 12:00',  'tomorrow at the same time');\n    assert.equal(moment(a).add({d: 1, h : -1}).calendar(),   'mañá ás 11:00',   'tomorrow minus 1 hour');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),      'hoxe ás 11:00',   'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),      'onte á 12:00',   'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('dddd [' + ((m.hours() !== 1) ? 'ás' : 'a') + '] LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd [' + ((m.hours() !== 1) ? 'ás' : 'a') + '] LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd [' + ((m.hours() !== 1) ? 'ás' : 'a') + '] LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('[o] dddd [pasado ' + ((m.hours() !== 1) ? 'ás' : 'a') + '] LT'),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[o] dddd [pasado ' + ((m.hours() !== 1) ? 'ás' : 'a') + '] LT'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[o] dddd [pasado ' + ((m.hours() !== 1) ? 'ás' : 'a') + '] LT'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('regression tests', function (assert) {\n    var lastWeek = moment().subtract({d: 4}).hours(1);\n    assert.equal(lastWeek.calendar(), lastWeek.format('[o] dddd [pasado a] LT'), '1 o\\'clock bug');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2012, 0,  1]).format('w ww wo'), '52 52 52º', 'Jan  1 2012 should be week 52');\n    assert.equal(moment([2012, 0,  2]).format('w ww wo'),   '1 01 1º', 'Jan  2 2012 should be week 1');\n    assert.equal(moment([2012, 0,  8]).format('w ww wo'),   '1 01 1º', 'Jan  8 2012 should be week 1');\n    assert.equal(moment([2012, 0,  9]).format('w ww wo'),   '2 02 2º', 'Jan  9 2012 should be week 2');\n    assert.equal(moment([2012, 0, 15]).format('w ww wo'),   '2 02 2º', 'Jan 15 2012 should be week 2');\n});\n\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/test/locale/gom-latn.js",
    "content": "import {localeModule, test} from '../qunit';\nimport moment from '../../moment';\nlocaleModule('gom-latn');\n\ntest('parse', function (assert) {\n    var i,\n        tests = 'Janer Jan._Febrer Feb._Mars Mars_Abril Abr._Mai Mai_Jun Jun_Julai Jul._Agost Ago._Setembr Set._Otubr Otu._Novembr Nov._Dezembr Dez.'.split('_');\n\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, MMMM Do YYYY, h:mm:ss a',      'Aitar, Febrer 14er 2010, 3:25:50 donparam'],\n            ['ddd, hA',                            'Ait., 3donparam'],\n            ['M Mo MM MMMM MMM',                   '2 2 02 Febrer Feb.'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14er 14'],\n            ['d do dddd ddd dd',                   '0 0 Aitar Ait. Ai'],\n            ['DDD DDDo DDDD',                      '45 45 045'],\n            ['w wo ww',                            '6 6 06'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'donparam donparam'],\n            ['[the] DDDo [day of the year]',       'the 45 day of the year'],\n            ['LTS',                                'donparam 3:25:50 vazta'],\n            ['L',                                  '14-02-2010'],\n            ['LL',                                 '14 Febrer 2010'],\n            ['LLL',                                '14 Febrer 2010 donparam 3:25 vazta'],\n            ['LLLL',                               'Aitar, Febrerachea 14er, 2010, donparam 3:25 vazta'],\n            ['l',                                  '14-2-2010'],\n            ['ll',                                 '14 Feb. 2010'],\n            ['lll',                                '14 Feb. 2010 donparam 3:25 vazta'],\n            ['llll',                               'Ait., 14 Feb. 2010, donparam 3:25 vazta']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1', '1');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2', '2');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3', '3');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4', '4');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5', '5');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6', '6');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7', '7');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8', '8');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9', '9');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10', '10');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11', '11');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12', '12');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13', '13');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14', '14');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15', '15');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16', '16');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17', '17');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18', '18');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19', '19');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20', '20');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21', '21');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22', '22');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23', '23');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24', '24');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25', '25');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26', '26');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27', '27');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28', '28');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29', '29');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30', '30');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31', '31');\n});\n\ntest('format month', function (assert) {\n    var i,\n        expected = 'Janer Jan._Febrer Feb._Mars Mars_Abril Abr._Mai Mai_Jun Jun_Julai Jul._Agost Ago._Setembr Set._Otubr Otu._Novembr Nov._Dezembr Dez.'.split('_');\n\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var i,\n        expected = 'Aitar Ait. Ai_Somar Som. Sm_Mongllar Mon. Mo_Budvar Bud. Bu_Brestar Bre. Br_Sukrar Suk. Su_Son\\'var Son. Sn'.split('_');\n\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'thodde secondanim', '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'eka mintan',      '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'eka mintan',      '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 mintanim',     '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 mintanim',    '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'eka horan',       '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'eka horan',       '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 horanim',       '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 horanim',       '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 horanim',      '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'eka disan',         '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'eka disan',         '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 disanim',        '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'eka disan',         '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 disanim',        '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 disanim',       '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'eka mhoinean',       '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'eka mhoinean',       '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'eka mhoinean',       '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 mhoineanim',      '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 mhoineanim',      '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 mhoineanim',      '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'eka mhoinean',       '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 mhoineanim',      '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'eka vorsan',        '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 vorsanim',       '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'eka vorsan',        '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 vorsanim',       '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'thodde second',  'prefix');\n    assert.equal(moment(0).from(30000), 'thodde second adim', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'thodde second adim',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'thodde second', 'in a few seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), '5 dis', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'Aiz donparam 12:00 vazta',     'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'Aiz donparam 12:25 vazta',     'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'Aiz donparam 1:00 vazta',      'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'Faleam donparam 12:00 vazta',  'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'Aiz sokalli 11:00 vazta',     'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'Kal donparam 12:00 vazta', 'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('[Ieta to] dddd[,] LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[Ieta to] dddd[,] LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[Ieta to] dddd[,] LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('[Fatlo] dddd[,] LT'),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[Fatlo] dddd[,] LT'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[Fatlo] dddd[,] LT'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('weeks year starting sunday format', function (assert) {\n    assert.equal(moment([2012, 0,  1]).format('w ww wo'), '52 52 52', 'Jan  1 2012 should be week 52');\n    assert.equal(moment([2012, 0,  2]).format('w ww wo'), '1 01 1', 'Jan  2 2012 should be week 1');\n    assert.equal(moment([2012, 0,  8]).format('w ww wo'), '1 01 1', 'Jan  8 2012 should be week 1');\n    assert.equal(moment([2012, 0, 14]).format('w ww wo'), '2 02 2', 'Jan 14 2012 should be week 2');\n    assert.equal(moment([2012, 0, 15]).format('w ww wo'), '2 02 2', 'Jan 15 2012 should be week 2');\n});\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/test/locale/he.js",
    "content": "import {localeModule, test} from '../qunit';\nimport moment from '../../moment';\nlocaleModule('he');\n\ntest('parse', function (assert) {\n    var tests = 'ינואר ינו׳_פברואר פבר׳_מרץ מרץ_אפריל אפר׳_מאי מאי_יוני יוני_יולי יולי_אוגוסט אוג׳_ספטמבר ספט׳_אוקטובר אוק׳_נובמבר נוב׳_דצמבר דצמ׳'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, MMMM Do YYYY, h:mm:ss a',      'ראשון, פברואר 14 2010, 3:25:50 אחה\"צ'],\n            ['ddd, h A',                           'א׳, 3 אחרי הצהריים'],\n            ['M Mo MM MMMM MMM',                   '2 2 02 פברואר פבר׳'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14 14'],\n            ['d do dddd ddd dd',                   '0 0 ראשון א׳ א'],\n            ['DDD DDDo DDDD',                      '45 45 045'],\n            ['w wo ww',                            '8 8 08'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'אחה\"צ אחרי הצהריים'],\n            ['[the] DDDo [day of the year]',       'the 45 day of the year'],\n            ['LTS',                                '15:25:50'],\n            ['L',                                  '14/02/2010'],\n            ['LL',                                 '14 בפברואר 2010'],\n            ['LLL',                                '14 בפברואר 2010 15:25'],\n            ['LLLL',                               'ראשון, 14 בפברואר 2010 15:25'],\n            ['l',                                  '14/2/2010'],\n            ['ll',                                 '14 פבר׳ 2010'],\n            ['lll',                                '14 פבר׳ 2010 15:25'],\n            ['llll',                               'א׳, 14 פבר׳ 2010 15:25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format month', function (assert) {\n    var expected = 'ינואר ינו׳_פברואר פבר׳_מרץ מרץ_אפריל אפר׳_מאי מאי_יוני יוני_יולי יולי_אוגוסט אוג׳_ספטמבר ספט׳_אוקטובר אוק׳_נובמבר נוב׳_דצמבר דצמ׳'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'ראשון א׳ א|שני ב׳ ב|שלישי ג׳ ג|רביעי ד׳ ד|חמישי ה׳ ה|שישי ו׳ ו|שבת ש׳ ש'.split('|'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'מספר שניות', '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'דקה',      '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'דקה',      '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 דקות',     '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 דקות',    '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'שעה',       '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'שעה',       '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  'שעתיים',       '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 שעות',       '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 שעות',      '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'יום',         '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'יום',         '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  'יומיים',        '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'יום',         '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 ימים',        '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 ימים',       '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'חודש',       '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'חודש',       '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'חודש',       '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  'חודשיים',      '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  'חודשיים',      '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 חודשים',      '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'חודש',       '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 חודשים',      '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'שנה',        '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), 'שנתיים',       '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 3699}), true), '10 שנים',        '345 days = 10 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 7340}), true), '20 שנה',       '548 days = 20 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'שנה',        '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 שנים',       '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'בעוד מספר שניות',  'prefix');\n    assert.equal(moment(0).from(30000), 'לפני מספר שניות', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'לפני מספר שניות',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'בעוד מספר שניות', 'in a few seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), 'בעוד 5 ימים', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'היום ב־12:00',   'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'היום ב־12:25',   'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'היום ב־13:00',   'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'מחר ב־12:00',   'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'היום ב־11:00',   'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'אתמול ב־12:00',  'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('dddd [בשעה] LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd [בשעה] LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd [בשעה] LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('[ביום] dddd [האחרון בשעה] LT'),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[ביום] dddd [האחרון בשעה] LT'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[ביום] dddd [האחרון בשעה] LT'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('weeks year starting sunday format', function (assert) {\n    assert.equal(moment([2012, 0,  1]).format('w ww wo'), '1 01 1', 'Jan  1 2012 should be week 1');\n    assert.equal(moment([2012, 0,  7]).format('w ww wo'), '1 01 1', 'Jan  7 2012 should be week 1');\n    assert.equal(moment([2012, 0,  8]).format('w ww wo'), '2 02 2', 'Jan  8 2012 should be week 2');\n    assert.equal(moment([2012, 0, 14]).format('w ww wo'), '2 02 2', 'Jan 14 2012 should be week 2');\n    assert.equal(moment([2012, 0, 15]).format('w ww wo'), '3 03 3', 'Jan 15 2012 should be week 3');\n});\n\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/test/locale/hi.js",
    "content": "import {localeModule, test} from '../qunit';\nimport moment from '../../moment';\nlocaleModule('hi');\n\ntest('parse', function (assert) {\n    var tests = 'जनवरी जन._फ़रवरी फ़र._मार्च मार्च_अप्रैल अप्रै._मई मई_जून जून_जुलाई जुल._अगस्त अग._सितम्बर सित._अक्टूबर अक्टू._नवम्बर नव._दिसम्बर दिस.'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, Do MMMM YYYY, a h:mm:ss बजे',  'रविवार, १४ फ़रवरी २०१०, दोपहर ३:२५:५० बजे'],\n            ['ddd, a h बजे',                       'रवि, दोपहर ३ बजे'],\n            ['M Mo MM MMMM MMM',                   '२ २ ०२ फ़रवरी फ़र.'],\n            ['YYYY YY',                            '२०१० १०'],\n            ['D Do DD',                            '१४ १४ १४'],\n            ['d do dddd ddd dd',                   '० ० रविवार रवि र'],\n            ['DDD DDDo DDDD',                      '४५ ४५ ०४५'],\n            ['w wo ww',                            '८ ८ ०८'],\n            ['h hh',                               '३ ०३'],\n            ['H HH',                               '१५ १५'],\n            ['m mm',                               '२५ २५'],\n            ['s ss',                               '५० ५०'],\n            ['a A',                                'दोपहर दोपहर'],\n            ['LTS',                                'दोपहर ३:२५:५० बजे'],\n            ['L',                                  '१४/०२/२०१०'],\n            ['LL',                                 '१४ फ़रवरी २०१०'],\n            ['LLL',                                '१४ फ़रवरी २०१०, दोपहर ३:२५ बजे'],\n            ['LLLL',                               'रविवार, १४ फ़रवरी २०१०, दोपहर ३:२५ बजे'],\n            ['l',                                  '१४/२/२०१०'],\n            ['ll',                                 '१४ फ़र. २०१०'],\n            ['lll',                                '१४ फ़र. २०१०, दोपहर ३:२५ बजे'],\n            ['llll',                               'रवि, १४ फ़र. २०१०, दोपहर ३:२५ बजे']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '१', '१');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '२', '२');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '३', '३');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '४', '४');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '५', '५');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '६', '६');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '७', '७');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '८', '८');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '९', '९');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '१०', '१०');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '११', '११');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '१२', '१२');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '१३', '१३');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '१४', '१४');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '१५', '१५');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '१६', '१६');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '१७', '१७');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '१८', '१८');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '१९', '१९');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '२०', '२०');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '२१', '२१');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '२२', '२२');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '२३', '२३');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '२४', '२४');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '२५', '२५');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '२६', '२६');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '२७', '२७');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '२८', '२८');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '२९', '२९');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '३०', '३०');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '३१', '३१');\n});\n\ntest('format month', function (assert) {\n    var expected = 'जनवरी जन._फ़रवरी फ़र._मार्च मार्च_अप्रैल अप्रै._मई मई_जून जून_जुलाई जुल._अगस्त अग._सितम्बर सित._अक्टूबर अक्टू._नवम्बर नव._दिसम्बर दिस.'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'रविवार रवि र_सोमवार सोम सो_मंगलवार मंगल मं_बुधवार बुध बु_गुरूवार गुरू गु_शुक्रवार शुक्र शु_शनिवार शनि श'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'कुछ ही क्षण', '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'एक मिनट',      '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'एक मिनट',      '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '२ मिनट',     '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '४४ मिनट',    '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'एक घंटा',       '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'एक घंटा',       '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '२ घंटे',       '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '५ घंटे',       '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '२१ घंटे',      '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'एक दिन',         '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'एक दिन',         '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '२ दिन',        '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'एक दिन',         '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '५ दिन',        '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '२५ दिन',       '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'एक महीने',       '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'एक महीने',       '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'एक महीने',       '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '२ महीने',      '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '२ महीने',      '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '३ महीने',      '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'एक महीने',       '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '५ महीने',      '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'एक वर्ष',        '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '२ वर्ष',       '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'एक वर्ष',        '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '५ वर्ष',       '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'कुछ ही क्षण में',  'prefix');\n    assert.equal(moment(0).from(30000), 'कुछ ही क्षण पहले', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'कुछ ही क्षण पहले',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'कुछ ही क्षण में', 'कुछ ही क्षण में');\n    assert.equal(moment().add({d: 5}).fromNow(), '५ दिन में', '५ दिन में');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'आज दोपहर १२:०० बजे',    'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'आज दोपहर १२:२५ बजे',    'Now plus 25 min');\n    assert.equal(moment(a).add({h: 3}).calendar(),       'आज दोपहर ३:०० बजे',     'Now plus 3 hours');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'कल दोपहर १२:०० बजे',    'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'आज दोपहर ११:०० बजे',    'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'कल दोपहर १२:०० बजे',    'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('dddd[,] LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd[,] LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd[,] LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('[पिछले] dddd[,] LT'),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[पिछले] dddd[,] LT'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[पिछले] dddd[,] LT'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('meridiem', function (assert) {\n    assert.equal(moment([2011, 2, 23,  2, 30]).format('a'), 'रात', 'before dawn');\n    assert.equal(moment([2011, 2, 23,  9, 30]).format('a'), 'सुबह', 'morning');\n    assert.equal(moment([2011, 2, 23, 14, 30]).format('a'), 'दोपहर', 'during day');\n    assert.equal(moment([2011, 2, 23, 17, 30]).format('a'), 'शाम', 'evening');\n    assert.equal(moment([2011, 2, 23, 19, 30]).format('a'), 'शाम', 'late evening');\n    assert.equal(moment([2011, 2, 23, 21, 20]).format('a'), 'रात', 'night');\n\n    assert.equal(moment([2011, 2, 23,  2, 30]).format('A'), 'रात', 'before dawn');\n    assert.equal(moment([2011, 2, 23,  9, 30]).format('A'), 'सुबह', 'morning');\n    assert.equal(moment([2011, 2, 23, 14, 30]).format('A'), 'दोपहर', ' during day');\n    assert.equal(moment([2011, 2, 23, 17, 30]).format('A'), 'शाम', 'evening');\n    assert.equal(moment([2011, 2, 23, 19, 30]).format('A'), 'शाम', 'late evening');\n    assert.equal(moment([2011, 2, 23, 21, 20]).format('A'), 'रात', 'night');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2012, 0,  1]).format('w ww wo'), '१ ०१ १', 'Jan  1 2012 should be week 1');\n    assert.equal(moment([2012, 0,  7]).format('w ww wo'), '१ ०१ १', 'Jan  7 2012 should be week 1');\n    assert.equal(moment([2012, 0,  8]).format('w ww wo'), '२ ०२ २', 'Jan  8 2012 should be week 2');\n    assert.equal(moment([2012, 0, 14]).format('w ww wo'), '२ ०२ २', 'Jan 14 2012 should be week 2');\n    assert.equal(moment([2012, 0, 15]).format('w ww wo'), '३ ०३ ३', 'Jan 15 2012 should be week 3');\n});\n\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/test/locale/hr.js",
    "content": "import {localeModule, test} from '../qunit';\nimport moment from '../../moment';\nlocaleModule('hr');\n\ntest('parse', function (assert) {\n    var tests = 'siječanj sij._veljača velj._ožujak ožu._travanj tra._svibanj svi._lipanj lip._srpanj srp._kolovoz kol._rujan ruj._listopad lis._studeni stu._prosinac pro.'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, Do MMMM YYYY, h:mm:ss a',      'nedjelja, 14. veljače 2010, 3:25:50 pm'],\n            ['ddd, hA',                            'ned., 3PM'],\n            ['M Mo MM MMMM MMM',                   '2 2. 02 veljača velj.'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14. 14'],\n            ['d do dddd ddd dd',                   '0 0. nedjelja ned. ne'],\n            ['DDD DDDo DDDD',                      '45 45. 045'],\n            ['w wo ww',                            '7 7. 07'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'pm PM'],\n            ['[the] DDDo [day of the year]',       'the 45. day of the year'],\n            ['LTS',                                '15:25:50'],\n            ['L',                                  '14.02.2010'],\n            ['LL',                                 '14. veljača 2010'],\n            ['LLL',                                '14. veljača 2010 15:25'],\n            ['LLLL',                               'nedjelja, 14. veljača 2010 15:25'],\n            ['l',                                  '14.2.2010'],\n            ['ll',                                 '14. velj. 2010'],\n            ['lll',                                '14. velj. 2010 15:25'],\n            ['llll',                               'ned., 14. velj. 2010 15:25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1.', '1.');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2.', '2.');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3.', '3.');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4.', '4.');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5.', '5.');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6.', '6.');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7.', '7.');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8.', '8.');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9.', '9.');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10.', '10.');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11.', '11.');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12.', '12.');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13.', '13.');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14.', '14.');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15.', '15.');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16.', '16.');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17.', '17.');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18.', '18.');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19.', '19.');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20.', '20.');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21.', '21.');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22.', '22.');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23.', '23.');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24.', '24.');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25.', '25.');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26.', '26.');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27.', '27.');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28.', '28.');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29.', '29.');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30.', '30.');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31.', '31.');\n});\n\ntest('format month', function (assert) {\n    var expected = 'siječanj sij._veljača velj._ožujak ožu._travanj tra._svibanj svi._lipanj lip._srpanj srp._kolovoz kol._rujan ruj._listopad lis._studeni stu._prosinac pro.'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'nedjelja ned. ne_ponedjeljak pon. po_utorak uto. ut_srijeda sri. sr_četvrtak čet. če_petak pet. pe_subota sub. su'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'par sekundi', '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'jedna minuta',   '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'jedna minuta',   '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 minute',     '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 minuta',     '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'jedan sat',      '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'jedan sat',      '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 sata',        '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 sati',         '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 sati',        '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'dan',       '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'dan',       '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 dana',        '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'dan',       '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 dana',        '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 dana',       '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'mjesec',     '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'mjesec',     '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'mjesec',     '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 mjeseca',     '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 mjeseca',     '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 mjeseca',     '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'mjesec',     '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 mjeseci',    '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'godinu',     '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 godine',       '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'godinu',     '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 godina',        '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'za par sekundi',  'prefix');\n    assert.equal(moment(0).from(30000), 'prije par sekundi', 'prefix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'prije par sekundi',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'za par sekundi', 'in a few seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), 'za 5 dana', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'danas u 12:00',  'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'danas u 12:25',  'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'danas u 13:00',  'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'sutra u 12:00',  'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'danas u 11:00',  'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'jučer u 12:00',  'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n\n    function makeFormat(d) {\n        switch (d.day()) {\n            case 0:\n                return '[u] [nedjelju] [u] LT';\n            case 3:\n                return '[u] [srijedu] [u] LT';\n            case 6:\n                return '[u] [subotu] [u] LT';\n            case 1:\n            case 2:\n            case 4:\n            case 5:\n                return '[u] dddd [u] LT';\n        }\n    }\n\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format(makeFormat(m)),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format(makeFormat(m)),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format(makeFormat(m)),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n\n    function makeFormat(d) {\n        switch (d.day()) {\n            case 0:\n            case 3:\n                return '[prošlu] dddd [u] LT';\n            case 6:\n                return '[prošle] [subote] [u] LT';\n            case 1:\n            case 2:\n            case 4:\n            case 5:\n                return '[prošli] dddd [u] LT';\n        }\n    }\n\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format(makeFormat(m)),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format(makeFormat(m)),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format(makeFormat(m)),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2011, 11, 26]).format('w ww wo'), '1 01 1.', 'Dec 26 2011 should be week 1');\n    assert.equal(moment([2012,  0,  1]).format('w ww wo'), '1 01 1.', 'Jan  1 2012 should be week 1');\n    assert.equal(moment([2012,  0,  2]).format('w ww wo'), '2 02 2.', 'Jan  2 2012 should be week 2');\n    assert.equal(moment([2012,  0,  8]).format('w ww wo'), '2 02 2.', 'Jan  8 2012 should be week 2');\n    assert.equal(moment([2012,  0,  9]).format('w ww wo'), '3 03 3.', 'Jan  9 2012 should be week 3');\n});\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/test/locale/hu.js",
    "content": "import {localeModule, test} from '../qunit';\nimport moment from '../../moment';\nlocaleModule('hu');\n\ntest('parse', function (assert) {\n    var tests = 'január jan_február feb_március márc_április ápr_május máj_június jún_július júl_augusztus aug_szeptember szept_október okt_november nov_december dec'.split('_'),\n        i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, MMMM Do YYYY, HH:mm:ss',      'vasárnap, február 14. 2010, 15:25:50'],\n            ['ddd, HH',                            'vas, 15'],\n            ['M Mo MM MMMM MMM',                   '2 2. 02 február feb'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14. 14'],\n            ['d do dddd ddd dd',                   '0 0. vasárnap vas v'],\n            ['DDD DDDo DDDD',                      '45 45. 045'],\n            ['w wo ww',                            '6 6. 06'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['[az év] DDDo [napja]',               'az év 45. napja'],\n            ['LTS',                                '15:25:50'],\n            ['L',                                  '2010.02.14.'],\n            ['LL',                                 '2010. február 14.'],\n            ['LLL',                                '2010. február 14. 15:25'],\n            ['LLLL',                               '2010. február 14., vasárnap 15:25'],\n            ['l',                                  '2010.2.14.'],\n            ['ll',                                 '2010. feb 14.'],\n            ['lll',                                '2010. feb 14. 15:25'],\n            ['llll',                               '2010. feb 14., vas 15:25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('meridiem', function (assert) {\n    assert.equal(moment([2011, 2, 23,  0,  0]).format('a'), 'de', 'am');\n    assert.equal(moment([2011, 2, 23, 11, 59]).format('a'), 'de', 'am');\n    assert.equal(moment([2011, 2, 23, 12,  0]).format('a'), 'du', 'pm');\n    assert.equal(moment([2011, 2, 23, 23, 59]).format('a'), 'du', 'pm');\n\n    assert.equal(moment([2011, 2, 23,  0,  0]).format('A'), 'DE', 'AM');\n    assert.equal(moment([2011, 2, 23, 11, 59]).format('A'), 'DE', 'AM');\n    assert.equal(moment([2011, 2, 23, 12,  0]).format('A'), 'DU', 'PM');\n    assert.equal(moment([2011, 2, 23, 23, 59]).format('A'), 'DU', 'PM');\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1.', '1.');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2.', '2.');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3.', '3.');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4.', '4.');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5.', '5.');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6.', '6.');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7.', '7.');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8.', '8.');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9.', '9.');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10.', '10.');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11.', '11.');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12.', '12.');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13.', '13.');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14.', '14.');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15.', '15.');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16.', '16.');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17.', '17.');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18.', '18.');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19.', '19.');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20.', '20.');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21.', '21.');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22.', '22.');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23.', '23.');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24.', '24.');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25.', '25.');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26.', '26.');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27.', '27.');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28.', '28.');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29.', '29.');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30.', '30.');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31.', '31.');\n});\n\ntest('format month', function (assert) {\n    var expected = 'január jan_február feb_március márc_április ápr_május máj_június jún_július júl_augusztus aug_szeptember szept_október okt_november nov_december dec'.split('_'),\n        i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'vasárnap vas_hétfő hét_kedd kedd_szerda sze_csütörtök csüt_péntek pén_szombat szo'.split('_'),\n        i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'néhány másodperc', '44 másodperc = néhány másodperc');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'egy perc',         '45 másodperc = egy perc');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'egy perc',         '89 másodperc = egy perc');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 perc',           '90 másodperc = 2 perc');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 perc',          '44 perc = 44 perc');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'egy óra',          '45 perc = egy óra');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'egy óra',          '89 perc = egy óra');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 óra',            '90 perc = 2 óra');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 óra',            '5 óra = 5 óra');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 óra',           '21 óra = 21 óra');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'egy nap',          '22 óra = egy nap');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'egy nap',          '35 óra = egy nap');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 nap',            '36 óra = 2 nap');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'egy nap',          '1 nap = egy nap');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 nap',            '5 nap = 5 nap');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 nap',           '25 nap = 25 nap');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'egy hónap',        '26 nap = egy hónap');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'egy hónap',        '30 nap = egy hónap');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'egy hónap',        '45 nap = egy hónap');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 hónap',          '46 nap = 2 hónap');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 hónap',          '75 nap = 2 hónap');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 hónap',          '76 nap = 3 hónap');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'egy hónap',        '1 hónap = egy hónap');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 hónap',          '5 hónap = 5 hónap');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'egy év',           '345 nap = egy év');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 év',             '548 nap = 2 év');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'egy év',           '1 év = egy év');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 év',             '5 év = 5 év');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'néhány másodperc múlva',  'prefix');\n    assert.equal(moment(0).from(30000), 'néhány másodperce', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'néhány másodperce',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'néhány másodperc múlva', 'néhány másodperc múlva');\n    assert.equal(moment().add({d: 5}).fromNow(), '5 nap múlva', '5 nap múlva');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'ma 12:00-kor',     'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'ma 12:25-kor',     'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'ma 13:00-kor',     'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'holnap 12:00-kor', 'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'ma 11:00-kor',     'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'tegnap 12:00-kor', 'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m, days = 'vasárnap_hétfőn_kedden_szerdán_csütörtökön_pénteken_szombaton'.split('_');\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('[' + days[m.day()] + '] LT[-kor]'),  'today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[' + days[m.day()] + '] LT[-kor]'),  'today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[' + days[m.day()] + '] LT[-kor]'),  'today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m, days = 'vasárnap_hétfőn_kedden_szerdán_csütörtökön_pénteken_szombaton'.split('_');\n\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('[múlt ' + days[m.day()] + '] LT[-kor]'),  'today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[múlt ' + days[m.day()] + '] LT[-kor]'),  'today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[múlt ' + days[m.day()] + '] LT[-kor]'),  'today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  'egy héte');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'egy hét múlva');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 hete');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  '2 hét múlva');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2011, 11, 26]).format('w ww wo'), '52 52 52.', 'Dec 26 2011 should be week 52');\n    assert.equal(moment([2012,  0,  1]).format('w ww wo'), '52 52 52.', 'Jan  1 2012 should be week 52');\n    assert.equal(moment([2012,  0,  2]).format('w ww wo'), '1 01 1.', 'Jan  2 2012 should be week 1');\n    assert.equal(moment([2012,  0,  8]).format('w ww wo'), '1 01 1.', 'Jan  8 2012 should be week 1');\n    assert.equal(moment([2012,  0,  9]).format('w ww wo'), '2 02 2.', 'Jan  9 2012 should be week 2');\n});\n\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/test/locale/hy-am.js",
    "content": "import {localeModule, test} from '../qunit';\nimport moment from '../../moment';\nlocaleModule('hy-am');\n\ntest('parse', function (assert) {\n    var tests = 'հունվար հնվ_փետրվար փտր_մարտ մրտ_ապրիլ ապր_մայիս մյս_հունիս հնս_հուլիս հլս_օգոստոս օգս_սեպտեմբեր սպտ_հոկտեմբեր հկտ_նոյեմբեր նմբ_դեկտեմբեր դկտ'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('parse exceptional case', function (assert) {\n    assert.equal(moment('11 մայիսի 1989', ['DD MMMM YYYY']).format('DD-MM-YYYY'), '11-05-1989');\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, Do MMMM YYYY, HH:mm:ss',       'կիրակի, 14 փետրվարի 2010, 15:25:50'],\n            ['ddd, h A',                           'կրկ, 3 ցերեկվա'],\n            ['M Mo MM MMMM MMM',                   '2 2 02 փետրվար փտր'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14 14'],\n            ['d do dddd ddd dd',                   '0 0 կիրակի կրկ կրկ'],\n            ['DDD DDDo DDDD',                      '45 45-րդ 045'],\n            ['w wo ww',                            '7 7-րդ 07'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'ցերեկվա ցերեկվա'],\n            ['[տարվա] DDDo [օրը]',                 'տարվա 45-րդ օրը'],\n            ['LTS',                                '15:25:50'],\n            ['L',                                  '14.02.2010'],\n            ['LL',                                 '14 փետրվարի 2010 թ.'],\n            ['LLL',                                '14 փետրվարի 2010 թ., 15:25'],\n            ['LLLL',                               'կիրակի, 14 փետրվարի 2010 թ., 15:25'],\n            ['l',                                  '14.2.2010'],\n            ['ll',                                 '14 փտր 2010 թ.'],\n            ['lll',                                '14 փտր 2010 թ., 15:25'],\n            ['llll',                               'կրկ, 14 փտր 2010 թ., 15:25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format meridiem', function (assert) {\n    assert.equal(moment([2012, 11, 28, 0, 0]).format('A'), 'գիշերվա', 'night');\n    assert.equal(moment([2012, 11, 28, 3, 59]).format('A'), 'գիշերվա', 'night');\n    assert.equal(moment([2012, 11, 28, 4, 0]).format('A'), 'առավոտվա', 'morning');\n    assert.equal(moment([2012, 11, 28, 11, 59]).format('A'), 'առավոտվա', 'morning');\n    assert.equal(moment([2012, 11, 28, 12, 0]).format('A'), 'ցերեկվա', 'afternoon');\n    assert.equal(moment([2012, 11, 28, 16, 59]).format('A'), 'ցերեկվա', 'afternoon');\n    assert.equal(moment([2012, 11, 28, 17, 0]).format('A'), 'երեկոյան', 'evening');\n    assert.equal(moment([2012, 11, 28, 23, 59]).format('A'), 'երեկոյան', 'evening');\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1-ին', '1-ին');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2-րդ', '2-րդ');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3-րդ', '3-րդ');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4-րդ', '4-րդ');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5-րդ', '5-րդ');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6-րդ', '6-րդ');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7-րդ', '7-րդ');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8-րդ', '8-րդ');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9-րդ', '9-րդ');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10-րդ', '10-րդ');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11-րդ', '11-րդ');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12-րդ', '12-րդ');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13-րդ', '13-րդ');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14-րդ', '14-րդ');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15-րդ', '15-րդ');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16-րդ', '16-րդ');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17-րդ', '17-րդ');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18-րդ', '18-րդ');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19-րդ', '19-րդ');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20-րդ', '20-րդ');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21-րդ', '21-րդ');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22-րդ', '22-րդ');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23-րդ', '23-րդ');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24-րդ', '24-րդ');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25-րդ', '25-րդ');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26-րդ', '26-րդ');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27-րդ', '27-րդ');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28-րդ', '28-րդ');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29-րդ', '29-րդ');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30-րդ', '30-րդ');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31-րդ', '31-րդ');\n});\n\ntest('format month', function (assert) {\n    var expected = 'հունվար հնվ_փետրվար փտր_մարտ մրտ_ապրիլ ապր_մայիս մյս_հունիս հնս_հուլիս հլս_օգոստոս օգս_սեպտեմբեր սպտ_հոկտեմբեր հկտ_նոյեմբեր նմբ_դեկտեմբեր դկտ'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format month case', function (assert) {\n    var months = {\n        'nominative': 'հունվար_փետրվար_մարտ_ապրիլ_մայիս_հունիս_հուլիս_օգոստոս_սեպտեմբեր_հոկտեմբեր_նոյեմբեր_դեկտեմբեր'.split('_'),\n        'accusative': 'հունվարի_փետրվարի_մարտի_ապրիլի_մայիսի_հունիսի_հուլիսի_օգոստոսի_սեպտեմբերի_հոկտեմբերի_նոյեմբերի_դեկտեմբերի'.split('_')\n    }, i;\n    for (i = 0; i < 12; i++) {\n        assert.equal(moment([2011, i, 1]).format('D MMMM'), '1 ' + months.accusative[i], '1 ' + months.accusative[i]);\n        assert.equal(moment([2011, i, 1]).format('MMMM'), months.nominative[i], '1 ' + months.nominative[i]);\n    }\n});\n\ntest('format month short case', function (assert) {\n    var monthsShort = {\n        'nominative': 'հնվ_փտր_մրտ_ապր_մյս_հնս_հլս_օգս_սպտ_հկտ_նմբ_դկտ'.split('_'),\n        'accusative': 'հնվ_փտր_մրտ_ապր_մյս_հնս_հլս_օգս_սպտ_հկտ_նմբ_դկտ'.split('_')\n    }, i;\n    for (i = 0; i < 12; i++) {\n        assert.equal(moment([2011, i, 1]).format('D MMM'), '1 ' + monthsShort.accusative[i], '1 ' + monthsShort.accusative[i]);\n        assert.equal(moment([2011, i, 1]).format('MMM'), monthsShort.nominative[i], '1 ' + monthsShort.nominative[i]);\n    }\n});\n\ntest('format month case with escaped symbols', function (assert) {\n    var months = {\n        'nominative': 'հունվար_փետրվար_մարտ_ապրիլ_մայիս_հունիս_հուլիս_օգոստոս_սեպտեմբեր_հոկտեմբեր_նոյեմբեր_դեկտեմբեր'.split('_'),\n        'accusative': 'հունվարի_փետրվարի_մարտի_ապրիլի_մայիսի_հունիսի_հուլիսի_օգոստոսի_սեպտեմբերի_հոկտեմբերի_նոյեմբերի_դեկտեմբերի'.split('_')\n    }, i;\n    for (i = 0; i < 12; i++) {\n        assert.equal(moment([2013, i, 1]).format('D[] MMMM'), '1 ' + months.accusative[i], '1 ' + months.accusative[i]);\n        assert.equal(moment([2013, i, 1]).format('[<i>]D[</i>] [<b>]MMMM[</b>]'), '<i>1</i> <b>' + months.accusative[i] + '</b>', '1 <b>' + months.accusative[i] + '</b>');\n        assert.equal(moment([2013, i, 1]).format('D[-ին օրը] MMMM'), '1-ին օրը ' + months.accusative[i], '1-ին օրը ' + months.accusative[i]);\n        assert.equal(moment([2013, i, 1]).format('D, MMMM'), '1, ' + months.nominative[i], '1, ' + months.nominative[i]);\n    }\n});\n\ntest('format month short case with escaped symbols', function (assert) {\n    var monthsShort = {\n        'nominative': 'հնվ_փտր_մրտ_ապր_մյս_հնս_հլս_օգս_սպտ_հկտ_նմբ_դկտ'.split('_'),\n        'accusative': 'հնվ_փտր_մրտ_ապր_մյս_հնս_հլս_օգս_սպտ_հկտ_նմբ_դկտ'.split('_')\n    }, i;\n    for (i = 0; i < 12; i++) {\n        assert.equal(moment([2013, i, 1]).format('D[] MMM'), '1 ' + monthsShort.accusative[i], '1 ' + monthsShort.accusative[i]);\n        assert.equal(moment([2013, i, 1]).format('[<i>]D[</i>] [<b>]MMM[</b>]'), '<i>1</i> <b>' + monthsShort.accusative[i] + '</b>', '1 <b>' + monthsShort.accusative[i] + '</b>');\n        assert.equal(moment([2013, i, 1]).format('D[-ին օրը] MMM'), '1-ին օրը ' + monthsShort.accusative[i], '1-ին օրը ' + monthsShort.accusative[i]);\n        assert.equal(moment([2013, i, 1]).format('D, MMM'), '1, ' + monthsShort.nominative[i], '1, ' + monthsShort.nominative[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'կիրակի կրկ կրկ_երկուշաբթի երկ երկ_երեքշաբթի երք երք_չորեքշաբթի չրք չրք_հինգշաբթի հնգ հնգ_ուրբաթ ուրբ ուրբ_շաբաթ շբթ շբթ'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'մի քանի վայրկյան',    '44 seconds = seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'րոպե',   '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'րոպե',   '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 րոպե',  '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 րոպե', '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'ժամ',    '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'ժամ',    '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 ժամ',    '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 ժամ',    '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 ժամ',   '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'օր',      '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'օր',      '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 օր',     '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'օր',      '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 օր',     '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 11}), true),  '11 օր',     '11 days = 11 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 21}), true),  '21 օր',     '21 days = 21 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 օր',    '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'ամիս',    '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'ամիս',    '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'ամիս',    '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 ամիս',   '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 ամիս',   '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 ամիս',   '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'ամիս',    '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 ամիս',   '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'տարի',     '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 տարի',    '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'տարի',     '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 տարի',    '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'մի քանի վայրկյան հետո', 'prefix');\n    assert.equal(moment(0).from(30000), 'մի քանի վայրկյան առաջ', 'suffix');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'մի քանի վայրկյան հետո', 'in seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), '5 օր հետո', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'այսօր 12:00',   'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'այսօր 12:25',   'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'այսօր 13:00',   'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'վաղը 12:00',    'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'այսօր 11:00',   'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'երեկ 12:00',    'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    function makeFormat(d) {\n        return 'dddd [օրը ժամը] LT';\n    }\n\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format(makeFormat(m)),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format(makeFormat(m)),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format(makeFormat(m)),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n\n    function makeFormat(d) {\n        return '[անցած] dddd [օրը ժամը] LT';\n    }\n\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format(makeFormat(m)),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format(makeFormat(m)),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format(makeFormat(m)),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2011, 11, 26]).format('w ww wo'), '1 01 1-ին', 'Dec 26 2011 should be week 1');\n    assert.equal(moment([2012,  0,  1]).format('w ww wo'), '1 01 1-ին', 'Jan  1 2012 should be week 1');\n    assert.equal(moment([2012,  0,  2]).format('w ww wo'), '2 02 2-րդ', 'Jan  2 2012 should be week 2');\n    assert.equal(moment([2012,  0,  8]).format('w ww wo'), '2 02 2-րդ', 'Jan  8 2012 should be week 2');\n    assert.equal(moment([2012,  0,  9]).format('w ww wo'), '3 03 3-րդ', 'Jan  9 2012 should be week 3');\n});\n\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/test/locale/id.js",
    "content": "import {localeModule, test} from '../qunit';\nimport moment from '../../moment';\nlocaleModule('id');\n\ntest('parse', function (assert) {\n    var tests = 'Januari Jan_Februari Feb_Maret Mar_April Apr_Mei Mei_Juni Jun_Juli Jul_Agustus Ags_September Sep_Oktober Okt_November Nov_Desember Des'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, MMMM Do YYYY, h:mm:ss a',      'Minggu, Februari 14 2010, 3:25:50 sore'],\n            ['ddd, hA',                            'Min, 3sore'],\n            ['M Mo MM MMMM MMM',                   '2 2 02 Februari Feb'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14 14'],\n            ['d do dddd ddd dd',                   '0 0 Minggu Min Mg'],\n            ['DDD DDDo DDDD',                      '45 45 045'],\n            ['w wo ww',                            '7 7 07'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'sore sore'],\n            ['[the] DDDo [day of the year]',       'the 45 day of the year'],\n            ['LTS',                                '15.25.50'],\n            ['L',                                  '14/02/2010'],\n            ['LL',                                 '14 Februari 2010'],\n            ['LLL',                                '14 Februari 2010 pukul 15.25'],\n            ['LLLL',                               'Minggu, 14 Februari 2010 pukul 15.25'],\n            ['l',                                  '14/2/2010'],\n            ['ll',                                 '14 Feb 2010'],\n            ['lll',                                '14 Feb 2010 pukul 15.25'],\n            ['llll',                               'Min, 14 Feb 2010 pukul 15.25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format month', function (assert) {\n    var expected = 'Januari Jan_Februari Feb_Maret Mar_April Apr_Mei Mei_Juni Jun_Juli Jul_Agustus Ags_September Sep_Oktober Okt_November Nov_Desember Des'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'Minggu Min Mg_Senin Sen Sn_Selasa Sel Sl_Rabu Rab Rb_Kamis Kam Km_Jumat Jum Jm_Sabtu Sab Sb'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'beberapa detik', '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'semenit',      '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'semenit',      '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 menit',     '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 menit',    '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'sejam',       '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'sejam',       '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 jam',       '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 jam',       '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 jam',      '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'sehari',         '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'sehari',         '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 hari',        '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'sehari',         '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 hari',        '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 hari',       '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'sebulan',       '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'sebulan',       '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'sebulan',       '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 bulan',      '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 bulan',      '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 bulan',      '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'sebulan',       '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 bulan',      '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'setahun',        '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 tahun',       '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'setahun',        '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 tahun',       '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'dalam beberapa detik',  'prefix');\n    assert.equal(moment(0).from(30000), 'beberapa detik yang lalu', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'beberapa detik yang lalu',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'dalam beberapa detik', 'in a few seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), 'dalam 5 hari', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'Hari ini pukul 12.00', 'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'Hari ini pukul 12.25', 'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'Hari ini pukul 13.00', 'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'Besok pukul 12.00',    'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'Hari ini pukul 11.00', 'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'Kemarin pukul 12.00',  'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('dddd [pukul] LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd [pukul] LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd [pukul] LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('dddd [lalu pukul] LT'),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd [lalu pukul] LT'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd [lalu pukul] LT'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2011, 11, 26]).format('w ww wo'), '1 01 1', 'Dec 26 2011 should be week 1');\n    assert.equal(moment([2012,  0,  1]).format('w ww wo'), '1 01 1', 'Jan  1 2012 should be week 1');\n    assert.equal(moment([2012,  0,  2]).format('w ww wo'), '2 02 2', 'Jan  2 2012 should be week 2');\n    assert.equal(moment([2012,  0,  8]).format('w ww wo'), '2 02 2', 'Jan  8 2012 should be week 2');\n    assert.equal(moment([2012,  0,  9]).format('w ww wo'), '3 03 3', 'Jan  9 2012 should be week 3');\n});\n\n\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/test/locale/is.js",
    "content": "import {localeModule, test} from '../qunit';\nimport moment from '../../moment';\nlocaleModule('is');\n\ntest('parse', function (assert) {\n    var tests = 'janúar jan_febrúar feb_mars mar_apríl apr_maí maí_júní jún_júlí júl_ágúst ágú_september sep_október okt_nóvember nóv_desember des'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, Do MMMM YYYY, h:mm:ss a',      'sunnudagur, 14. febrúar 2010, 3:25:50 pm'],\n            ['ddd, hA',                            'sun, 3PM'],\n            ['M Mo MM MMMM MMM',                   '2 2. 02 febrúar feb'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14. 14'],\n            ['d do dddd ddd dd',                   '0 0. sunnudagur sun Su'],\n            ['DDD DDDo DDDD',                      '45 45. 045'],\n            ['w wo ww',                            '6 6. 06'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'pm PM'],\n            ['[the] DDDo [day of the year]',       'the 45. day of the year'],\n            ['LTS',                                '15:25:50'],\n            ['L',                                  '14.02.2010'],\n            ['LL',                                 '14. febrúar 2010'],\n            ['LLL',                                '14. febrúar 2010 kl. 15:25'],\n            ['LLLL',                               'sunnudagur, 14. febrúar 2010 kl. 15:25'],\n            ['l',                                  '14.2.2010'],\n            ['ll',                                 '14. feb 2010'],\n            ['lll',                                '14. feb 2010 kl. 15:25'],\n            ['llll',                               'sun, 14. feb 2010 kl. 15:25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1.', '1.');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2.', '2.');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3.', '3.');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4.', '4.');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5.', '5.');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6.', '6.');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7.', '7.');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8.', '8.');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9.', '9.');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10.', '10.');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11.', '11.');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12.', '12.');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13.', '13.');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14.', '14.');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15.', '15.');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16.', '16.');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17.', '17.');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18.', '18.');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19.', '19.');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20.', '20.');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21.', '21.');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22.', '22.');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23.', '23.');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24.', '24.');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25.', '25.');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26.', '26.');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27.', '27.');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28.', '28.');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29.', '29.');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30.', '30.');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31.', '31.');\n});\n\ntest('format month', function (assert) {\n    var expected = 'janúar jan_febrúar feb_mars mar_apríl apr_maí maí_júní jún_júlí júl_ágúst ágú_september sep_október okt_nóvember nóv_desember des'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'sunnudagur sun Su_mánudagur mán Má_þriðjudagur þri Þr_miðvikudagur mið Mi_fimmtudagur fim Fi_föstudagur fös Fö_laugardagur lau La'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'nokkrar sekúndur', '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'mínúta',      '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'mínúta',      '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 mínútur',     '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 mínútur',    '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 21}), true),  '21 mínúta',    '21 minutes = 21 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'klukkustund',       '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'klukkustund',       '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 klukkustundir',       '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 klukkustundir',       '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 klukkustund',      '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'dagur',         '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'dagur',         '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 dagar',        '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'dagur',         '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 dagar',        '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 dagar',       '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 11}), true),  '11 dagar',       '11 days = 11 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 21}), true),  '21 dagur',       '21 days = 21 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'mánuður',       '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'mánuður',       '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'mánuður',       '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 mánuðir',      '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 mánuðir',      '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 mánuðir',      '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'mánuður',       '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 mánuðir',      '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'ár',        '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 ár',       '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'ár',        '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 ár',       '5 years = 5 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 21}), true),  '21 ár',       '21 years = 21 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'eftir nokkrar sekúndur',  'prefix');\n    assert.equal(moment(0).from(30000), 'fyrir nokkrum sekúndum síðan', 'suffix');\n    assert.equal(moment().subtract({m: 1}).fromNow(), 'fyrir mínútu síðan', 'a minute ago');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'fyrir nokkrum sekúndum síðan',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'eftir nokkrar sekúndur', 'in a few seconds');\n    assert.equal(moment().add({m: 1}).fromNow(), 'eftir mínútu', 'in a minute');\n    assert.equal(moment().add({d: 5}).fromNow(), 'eftir 5 daga', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'í dag kl. 12:00',     'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'í dag kl. 12:25',     'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'í dag kl. 13:00',     'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'á morgun kl. 12:00',  'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'í dag kl. 11:00',     'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'í gær kl. 12:00',     'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('dddd [kl.] LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd [kl.] LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd [kl.] LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('[síðasta] dddd [kl.] LT'),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[síðasta] dddd [kl.] LT'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[síðasta] dddd [kl.] LT'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2012, 0,  1]).format('w ww wo'), '52 52 52.', 'Jan  1 2012 should be week 52');\n    assert.equal(moment([2012, 0,  2]).format('w ww wo'),  '1 01 1.', 'Jan  2 2012 should be week 1');\n    assert.equal(moment([2012, 0,  8]).format('w ww wo'),  '1 01 1.', 'Jan  8 2012 should be week 1');\n    assert.equal(moment([2012, 0,  9]).format('w ww wo'),  '2 02 2.', 'Jan  9 2012 should be week 2');\n    assert.equal(moment([2012, 0, 15]).format('w ww wo'),  '2 02 2.', 'Jan 15 2012 should be week 2');\n});\n\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/test/locale/it.js",
    "content": "import {localeModule, test} from '../qunit';\nimport moment from '../../moment';\nlocaleModule('it');\n\ntest('parse', function (assert) {\n    var tests = 'gennaio gen_febbraio feb_marzo mar_aprile apr_maggio mag_giugno giu_luglio lug_agosto ago_settembre set_ottobre ott_novembre nov_dicembre dic'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, MMMM Do YYYY, h:mm:ss a',      'domenica, febbraio 14º 2010, 3:25:50 pm'],\n            ['ddd, hA',                            'dom, 3PM'],\n            ['M Mo MM MMMM MMM',                   '2 2º 02 febbraio feb'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14º 14'],\n            ['d do dddd ddd dd',                   '0 0º domenica dom do'],\n            ['DDD DDDo DDDD',                      '45 45º 045'],\n            ['w wo ww',                            '6 6º 06'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'pm PM'],\n            ['[the] DDDo [day of the year]',       'the 45º day of the year'],\n            ['LTS',                                '15:25:50'],\n            ['L',                                  '14/02/2010'],\n            ['LL',                                 '14 febbraio 2010'],\n            ['LLL',                                '14 febbraio 2010 15:25'],\n            ['LLLL',                               'domenica, 14 febbraio 2010 15:25'],\n            ['l',                                  '14/2/2010'],\n            ['ll',                                 '14 feb 2010'],\n            ['lll',                                '14 feb 2010 15:25'],\n            ['llll',                               'dom, 14 feb 2010 15:25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1º', '1º');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2º', '2º');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3º', '3º');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4º', '4º');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5º', '5º');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6º', '6º');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7º', '7º');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8º', '8º');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9º', '9º');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10º', '10º');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11º', '11º');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12º', '12º');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13º', '13º');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14º', '14º');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15º', '15º');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16º', '16º');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17º', '17º');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18º', '18º');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19º', '19º');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20º', '20º');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21º', '21º');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22º', '22º');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23º', '23º');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24º', '24º');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25º', '25º');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26º', '26º');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27º', '27º');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28º', '28º');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29º', '29º');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30º', '30º');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31º', '31º');\n});\n\ntest('format month', function (assert) {\n    var expected = 'gennaio gen_febbraio feb_marzo mar_aprile apr_maggio mag_giugno giu_luglio lug_agosto ago_settembre set_ottobre ott_novembre nov_dicembre dic'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'domenica dom do_lunedì lun lu_martedì mar ma_mercoledì mer me_giovedì gio gi_venerdì ven ve_sabato sab sa'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'alcuni secondi', '44 seconds = seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'un minuto',      '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'un minuto',      '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 minuti',       '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 minuti',      '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'un\\'ora',        '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'un\\'ora',        '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 ore',          '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 ore',          '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 ore',         '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'un giorno',      '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'un giorno',      '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 giorni',       '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'un giorno',      '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 giorni',       '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 giorni',      '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'un mese',        '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'un mese',        '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'un mese',        '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 mesi',         '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 mesi',         '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 mesi',         '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'un mese',        '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 mesi',         '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'un anno',        '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 anni',         '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'un anno',        '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 anni',         '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'in alcuni secondi', 'prefix');\n    assert.equal(moment(0).from(30000), 'alcuni secondi fa', 'suffix');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'in alcuni secondi', 'in seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), 'tra 5 giorni', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'Oggi alle 12:00',     'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'Oggi alle 12:25',     'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'Oggi alle 13:00',     'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'Domani alle 12:00',   'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'Oggi alle 11:00',     'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'Ieri alle 12:00',     'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('dddd [alle] LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd [alle] LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd [alle] LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m, weekday, datestring;\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        // Different date string\n        weekday = parseInt(m.format('d'), 10);\n        datestring = (weekday === 0) ? '[la scorsa] dddd [alle] LT' : '[lo scorso] dddd [alle] LT';\n        assert.equal(m.calendar(), m.format(datestring), 'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(), m.format(datestring), 'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(), m.format(datestring), 'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2012, 0,  1]).format('w ww wo'), '52 52 52º', 'Jan  1 2012 should be week 52');\n    assert.equal(moment([2012, 0,  2]).format('w ww wo'),  '1 01 1º', 'Jan  2 2012 should be week 1');\n    assert.equal(moment([2012, 0,  8]).format('w ww wo'),  '1 01 1º', 'Jan  8 2012 should be week 1');\n    assert.equal(moment([2012, 0,  9]).format('w ww wo'),  '2 02 2º', 'Jan  9 2012 should be week 2');\n    assert.equal(moment([2012, 0, 15]).format('w ww wo'),  '2 02 2º', 'Jan 15 2012 should be week 2');\n});\n\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/test/locale/ja.js",
    "content": "import {localeModule, test} from '../qunit';\nimport moment from '../../moment';\nlocaleModule('ja');\n\ntest('parse', function (assert) {\n    var tests = '1月 1月_2月 2月_3月 3月_4月 4月_5月 5月_6月 6月_7月 7月_8月 8月_9月 9月_10月 10月_11月 11月_12月 12月'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, MMMM Do YYYY, a h:mm:ss',      '日曜日, 2月 14日 2010, 午後 3:25:50'],\n            ['ddd, Ah',                            '日, 午後3'],\n            ['M Mo MM MMMM MMM',                   '2 2 02 2月 2月'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14日 14'],\n            ['d do dddd ddd dd',                   '0 0日 日曜日 日 日'],\n            ['DDD DDDo DDDD',                      '45 45日 045'],\n            ['w wo ww',                            '8 8 08'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                '午後 午後'],\n            ['[the] DDDo [day of the year]',       'the 45日 day of the year'],\n            ['LTS',                                '15:25:50'],\n            ['L',                                  '2010/02/14'],\n            ['LL',                                 '2010年2月14日'],\n            ['LLL',                                '2010年2月14日 15:25'],\n            ['LLLL',                               '2010年2月14日 15:25 日曜日'],\n            ['l',                                  '2010/02/14'],\n            ['ll',                                 '2010年2月14日'],\n            ['lll',                                '2010年2月14日 15:25'],\n            ['llll',                               '2010年2月14日 15:25 日曜日']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format month', function (assert) {\n    var expected = '1月 1月_2月 2月_3月 3月_4月 4月_5月 5月_6月 6月_7月 7月_8月 8月_9月 9月_10月 10月_11月 11月_12月 12月'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = '日曜日 日 日_月曜日 月 月_火曜日 火 火_水曜日 水 水_木曜日 木 木_金曜日 金 金_土曜日 土 土'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  '数秒',   '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  '1分', '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  '1分', '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2分',  '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44分', '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  '1時間', '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  '1時間', '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2時間',  '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5時間',  '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21時間', '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  '1日',   '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  '1日',   '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2日',   '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   '1日',   '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5日',   '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25日',  '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  '1ヶ月', '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  '1ヶ月', '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  '1ヶ月', '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2ヶ月',  '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2ヶ月',  '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3ヶ月',  '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   '1ヶ月', '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5ヶ月',  '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), '1年',   '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2年',   '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   '1年',   '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5年',   '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), '数秒後',  'prefix');\n    assert.equal(moment(0).from(30000), '数秒前', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), '数秒前',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), '数秒後', 'in a few seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), '5日後', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   '今日 12:00', 'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      '今日 12:25', 'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       '今日 13:00', 'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       '明日 12:00', 'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  '今日 11:00', 'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  '昨日 12:00', 'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('[来週]dddd LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[来週]dddd LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[来週]dddd LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('[前週]dddd LT'),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[前週]dddd LT'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[前週]dddd LT'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),      '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),      '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('weeks year starting sunday format', function (assert) {\n    assert.equal(moment([2012, 0,  1]).format('w ww wo'), '1 01 1', 'Jan  1 2012 should be week 1');\n    assert.equal(moment([2012, 0,  7]).format('w ww wo'), '1 01 1', 'Jan  7 2012 should be week 1');\n    assert.equal(moment([2012, 0,  8]).format('w ww wo'), '2 02 2', 'Jan  8 2012 should be week 2');\n    assert.equal(moment([2012, 0, 14]).format('w ww wo'), '2 02 2', 'Jan 14 2012 should be week 2');\n    assert.equal(moment([2012, 0, 15]).format('w ww wo'), '3 03 3', 'Jan 15 2012 should be week 3');\n});\n\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/test/locale/jv.js",
    "content": "import {localeModule, test} from '../qunit';\nimport moment from '../../moment';\nlocaleModule('jv');\n\ntest('parse', function (assert) {\n    var tests = 'Januari Jan_Februari Feb_Maret Mar_April Apr_Mei Mei_Juni Jun_Juli Jul_Agustus Ags_September Sep_Oktober Okt_Nopember Nop_Desember Des'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, MMMM Do YYYY, h:mm:ss a',      'Minggu, Februari 14 2010, 3:25:50 sonten'],\n            ['ddd, hA',                            'Min, 3sonten'],\n            ['M Mo MM MMMM MMM',                   '2 2 02 Februari Feb'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14 14'],\n            ['d do dddd ddd dd',                   '0 0 Minggu Min Mg'],\n            ['DDD DDDo DDDD',                      '45 45 045'],\n            ['w wo ww',                            '7 7 07'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'sonten sonten'],\n            ['[the] DDDo [day of the year]',       'the 45 day of the year'],\n            ['LTS',                                '15.25.50'],\n            ['L',                                  '14/02/2010'],\n            ['LL',                                 '14 Februari 2010'],\n            ['LLL',                                '14 Februari 2010 pukul 15.25'],\n            ['LLLL',                               'Minggu, 14 Februari 2010 pukul 15.25'],\n            ['l',                                  '14/2/2010'],\n            ['ll',                                 '14 Feb 2010'],\n            ['lll',                                '14 Feb 2010 pukul 15.25'],\n            ['llll',                               'Min, 14 Feb 2010 pukul 15.25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format month', function (assert) {\n    var expected = 'Januari Jan_Februari Feb_Maret Mar_April Apr_Mei Mei_Juni Jun_Juli Jul_Agustus Ags_September Sep_Oktober Okt_Nopember Nop_Desember Des'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'Minggu Min Mg_Senen Sen Sn_Seloso Sel Sl_Rebu Reb Rb_Kemis Kem Km_Jemuwah Jem Jm_Septu Sep Sp'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'sawetawis detik', '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'setunggal menit',      '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'setunggal menit',      '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 menit',     '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 menit',    '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'setunggal jam',       '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'setunggal jam',       '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 jam',       '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 jam',       '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 jam',      '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'sedinten',         '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'sedinten',         '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 dinten',        '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'sedinten',         '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 dinten',        '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 dinten',       '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'sewulan',       '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'sewulan',       '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'sewulan',       '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 wulan',      '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 wulan',      '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 wulan',      '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'sewulan',       '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 wulan',      '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'setaun',        '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 taun',       '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'setaun',        '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 taun',       '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'wonten ing sawetawis detik',  'prefix');\n    assert.equal(moment(0).from(30000), 'sawetawis detik ingkang kepengker', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'sawetawis detik ingkang kepengker',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'wonten ing sawetawis detik', 'in a few seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), 'wonten ing 5 dinten', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'Dinten puniko pukul 12.00', 'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'Dinten puniko pukul 12.25', 'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'Dinten puniko pukul 13.00', 'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'Mbenjang pukul 12.00',      'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'Dinten puniko pukul 11.00', 'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'Kala wingi pukul 12.00',    'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('dddd [pukul] LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd [pukul] LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd [pukul] LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('dddd [kepengker pukul] LT'),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd [kepengker pukul] LT'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd [kepengker pukul] LT'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\n// Monday is the first day of the week.\n// The week that contains Jan 1st is the first week of the year.\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2011, 11, 26]).format('w ww wo'), '1 01 1', 'Dec 26 2011 should be week 1');\n    assert.equal(moment([2012,  0,  1]).format('w ww wo'), '1 01 1', 'Jan  1 2012 should be week 1');\n    assert.equal(moment([2012,  0,  2]).format('w ww wo'), '2 02 2', 'Jan  2 2012 should be week 2');\n    assert.equal(moment([2012,  0,  8]).format('w ww wo'), '2 02 2', 'Jan  8 2012 should be week 2');\n    assert.equal(moment([2012,  0,  9]).format('w ww wo'), '3 03 3', 'Jan  9 2012 should be week 3');\n});\n\n\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/test/locale/ka.js",
    "content": "import {localeModule, test} from '../qunit';\nimport moment from '../../moment';\nlocaleModule('ka');\n\ntest('parse', function (assert) {\n    var i,\n        tests = 'იანვარი იან_თებერვალი თებ_მარტი მარ_აპრილი აპრ_მაისი მაი_ივნისი ივნ_ივლისი ივლ_აგვისტო აგვ_სექტემბერი სექ_ოქტომბერი ოქტ_ნოემბერი ნოე_დეკემბერი დეკ'.split('_');\n\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' უნდა იყოს თვე ' + (i + 1));\n    }\n\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, MMMM Do YYYY, h:mm:ss a', 'კვირა, თებერვალი მე-14 2010, 3:25:50 pm'],\n            ['ddd, hA',                       'კვი, 3PM'],\n            ['M Mo MM MMMM MMM',              '2 მე-2 02 თებერვალი თებ'],\n            ['YYYY YY',                       '2010 10'],\n            ['D Do DD',                       '14 მე-14 14'],\n            ['d do dddd ddd dd',              '0 0 კვირა კვი კვ'],\n            ['DDD DDDo DDDD',                 '45 45-ე 045'],\n            ['w wo ww',                       '7 მე-7 07'],\n            ['h hh',                          '3 03'],\n            ['H HH',                          '15 15'],\n            ['m mm',                          '25 25'],\n            ['s ss',                          '50 50'],\n            ['a A',                           'pm PM'],\n            ['წლის DDDo დღე',                 'წლის 45-ე დღე'],\n            ['LTS',                           '3:25:50 PM'],\n            ['L',                             '14/02/2010'],\n            ['LL',                            '14 თებერვალს 2010'],\n            ['LLL',                           '14 თებერვალს 2010 3:25 PM'],\n            ['LLLL',                          'კვირა, 14 თებერვალს 2010 3:25 PM'],\n            ['l',                             '14/2/2010'],\n            ['ll',                            '14 თებ 2010'],\n            ['lll',                           '14 თებ 2010 3:25 PM'],\n            ['llll',                          'კვი, 14 თებ 2010 3:25 PM']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'),  '1-ლი',  '1-ლი');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'),  'მე-2',  'მე-2');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'),  'მე-3',  'მე-3');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'),  'მე-4',  'მე-4');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'),  'მე-5',  'მე-5');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'),  'მე-6',  'მე-6');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'),  'მე-7',  'მე-7');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'),  'მე-8',  'მე-8');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'),  'მე-9',  'მე-9');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), 'მე-10', 'მე-10');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), 'მე-11', 'მე-11');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), 'მე-12', 'მე-12');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), 'მე-13', 'მე-13');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), 'მე-14', 'მე-14');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), 'მე-15', 'მე-15');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), 'მე-16', 'მე-16');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), 'მე-17', 'მე-17');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), 'მე-18', 'მე-18');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), 'მე-19', 'მე-19');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), 'მე-20', 'მე-20');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21-ე', '21-ე');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22-ე', '22-ე');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23-ე', '23-ე');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24-ე', '24-ე');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25-ე', '25-ე');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26-ე', '26-ე');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27-ე', '27-ე');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28-ე', '28-ე');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29-ე', '29-ე');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30-ე', '30-ე');\n\n    assert.equal(moment('2011 40', 'YYYY DDD').format('DDDo'),  'მე-40',  'მე-40');\n    assert.equal(moment('2011 50', 'YYYY DDD').format('DDDo'),  '50-ე',   '50-ე');\n    assert.equal(moment('2011 60', 'YYYY DDD').format('DDDo'),  'მე-60',  'მე-60');\n    assert.equal(moment('2011 100', 'YYYY DDD').format('DDDo'), 'მე-100', 'მე-100');\n    assert.equal(moment('2011 101', 'YYYY DDD').format('DDDo'), '101-ე',  '101-ე');\n});\n\ntest('format month', function (assert) {\n    var i,\n        expected = 'იანვარი იან_თებერვალი თებ_მარტი მარ_აპრილი აპრ_მაისი მაი_ივნისი ივნ_ივლისი ივლ_აგვისტო აგვ_სექტემბერი სექ_ოქტომბერი ოქტ_ნოემბერი ნოე_დეკემბერი დეკ'.split('_');\n\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var i,\n        expected = 'კვირა კვი კვ_ორშაბათი ორშ ორ_სამშაბათი სამ სა_ოთხშაბათი ოთხ ოთ_ხუთშაბათი ხუთ ხუ_პარასკევი პარ პა_შაბათი შაბ შა'.split('_');\n\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}),  true), 'რამდენიმე წამი', '44 წამი  = რამდენიმე წამი');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}),  true), 'წუთი',           '45 წამი  = წუთი');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}),  true), 'წუთი',           '89 წამი  = წუთი');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}),  true), '2 წუთი',         '90 წამი  = 2 წუთი');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}),  true), '44 წუთი',        '44 წამი  = 44 წუთი');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}),  true), 'საათი',          '45 წამი  = საათი');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}),  true), 'საათი',          '89 წამი  = საათი');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}),  true), '2 საათი',        '90 წამი  = 2 საათი');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}),   true), '5 საათი',        '5 საათი  = 5 საათი');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}),  true), '21 საათი',       '21 საათი = 21 საათი');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}),  true), 'დღე',            '22 საათი = დღე');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}),  true), 'დღე',            '35 საათი = დღე');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}),  true), '2 დღე',          '36 საათი = 2 დღე');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}),   true), 'დღე',            '1 დღე    = დღე');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}),   true), '5 დღე',          '5 დღე    = 5 დღე');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}),  true), '25 დღე',         '25 დღე   = 25 დღე');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}),  true), 'თვე',            '26 დღე   = თვე');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}),  true), 'თვე',            '30 დღე   = თვე');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}),  true), 'თვე',            '45 დღე   = თვე');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}),  true), '2 თვე',          '46 დღე   = 2 თვე');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}),  true), '2 თვე',          '75 დღე   = 2 თვე');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}),  true), '3 თვე',          '76 დღე   = 3 თვე');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}),   true), 'თვე',            '1 თვე    = თვე');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}),   true), '5 თვე',          '5 თვე    = 5 თვე');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'წელი',           '345 დღე  = წელი');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 წელი',         '548 დღე  = 2 წელი');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}),   true), 'წელი',           '1 წელი   = წელი');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}),   true), '5 წელი',         '5 წელი   = 5 წელი');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'რამდენიმე წამში',     'ში სუფიქსი');\n    assert.equal(moment(0).from(30000), 'რამდენიმე წამის უკან', 'უკან სუფიქსი');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'რამდენიმე წამის უკან', 'უნდა აჩვენოს როგორც წარსული');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'რამდენიმე წამში', 'რამდენიმე წამში');\n    assert.equal(moment().add({d: 5}).fromNow(), '5 დღეში', '5 დღეში');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'დღეს 12:00 PM-ზე',  'დღეს ამავე დროს');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'დღეს 12:25 PM-ზე',  'ახლანდელ დროს დამატებული 25 წუთი');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'დღეს 1:00 PM-ზე',   'ახლანდელ დროს დამატებული 1 საათი');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'ხვალ 12:00 PM-ზე',  'ხვალ ამავე დროს');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'დღეს 11:00 AM-ზე',  'ახლანდელ დროს გამოკლებული 1 საათი');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'გუშინ 12:00 PM-ზე', 'გუშინ ამავე დროს');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('[შემდეგ] dddd LT[-ზე]'),  'დღეს + ' + i + ' დღე ახლანდელ დროს');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[შემდეგ] dddd LT[-ზე]'),  'დღეს + ' + i + ' დღე დღის დასაწყისში');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[შემდეგ] dddd LT[-ზე]'),  'დღეს + ' + i + ' დღე დღის დასასრულს');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('[წინა] dddd LT[-ზე]'),  'დღეს - ' + i + ' დღე ახლანდელ დროს');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[წინა] dddd LT[-ზე]'),  'დღეს - ' + i + ' დღე დღის დასაწყისში');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[წინა] dddd LT[-ზე]'),  'დღეს - ' + i + ' დღე დღის დასასრულს');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 კვირის უკან');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  '1 კვირაში');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 კვირის წინ');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  '2 კვირაში');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2011, 11, 26]).format('w ww wo'), '1 01 1-ლი', 'დეკ 26 2011 უნდა იყოს კვირა 1');\n    assert.equal(moment([2012,  0,  1]).format('w ww wo'), '1 01 1-ლი', 'იან  1 2012 უნდა იყოს კვირა 1');\n    assert.equal(moment([2012,  0,  2]).format('w ww wo'), '2 02 მე-2', 'იან  2 2012 უნდა იყოს კვირა 2');\n    assert.equal(moment([2012,  0,  8]).format('w ww wo'), '2 02 მე-2', 'იან  8 2012 უნდა იყოს კვირა 2');\n    assert.equal(moment([2012,  0,  9]).format('w ww wo'), '3 03 მე-3', 'იან  9 2012 უნდა იყოს კვირა 3');\n});\n\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/test/locale/kk.js",
    "content": "import {localeModule, test} from '../qunit';\nimport moment from '../../moment';\nlocaleModule('kk');\n\ntest('parse', function (assert) {\n    var tests = 'қаңтар қаң_ақпан ақп_наурыз нау_сәуір сәу_мамыр мам_маусым мау_шілде шіл_тамыз там_қыркүйек қыр_қазан қаз_қараша қар_желтоқсан жел'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, Do MMMM YYYY, HH:mm:ss',       'жексенбі, 14-ші ақпан 2010, 15:25:50'],\n            ['ddd, hA',                            'жек, 3PM'],\n            ['M Mo MM MMMM MMM',                   '2 2-ші 02 ақпан ақп'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14-ші 14'],\n            ['d do dddd ddd dd',                   '0 0-ші жексенбі жек жк'],\n            ['DDD DDDo DDDD',                      '45 45-ші 045'],\n            ['w wo ww',                            '7 7-ші 07'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'pm PM'],\n            ['[жылдың] DDDo [күні]',               'жылдың 45-ші күні'],\n            ['LTS',                                '15:25:50'],\n            ['L',                                  '14.02.2010'],\n            ['LL',                                 '14 ақпан 2010'],\n            ['LLL',                                '14 ақпан 2010 15:25'],\n            ['LLLL',                               'жексенбі, 14 ақпан 2010 15:25'],\n            ['l',                                  '14.2.2010'],\n            ['ll',                                 '14 ақп 2010'],\n            ['lll',                                '14 ақп 2010 15:25'],\n            ['llll',                               'жек, 14 ақп 2010 15:25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1-ші', '1st');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2-ші', '2nd');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3-ші', '3rd');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4-ші', '4th');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5-ші', '5th');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6-шы', '6th');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7-ші', '7th');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8-ші', '8th');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9-шы', '9th');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10-шы', '10th');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11-ші', '11th');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12-ші', '12th');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13-ші', '13th');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14-ші', '14th');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15-ші', '15th');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16-шы', '16th');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17-ші', '17th');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18-ші', '18th');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19-шы', '19th');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20-шы', '20th');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21-ші', '21st');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22-ші', '22nd');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23-ші', '23rd');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24-ші', '24th');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25-ші', '25th');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26-шы', '26th');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27-ші', '27th');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28-ші', '28th');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29-шы', '29th');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30-шы', '30th');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31-ші', '31st');\n});\n\ntest('format month', function (assert) {\n    var expected = 'қаңтар қаң_ақпан ақп_наурыз нау_сәуір сәу_мамыр мам_маусым мау_шілде шіл_тамыз там_қыркүйек қыр_қазан қаз_қараша қар_желтоқсан жел'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'жексенбі жек жк_дүйсенбі дүй дй_сейсенбі сей сй_сәрсенбі сәр ср_бейсенбі бей бй_жұма жұм жм_сенбі сен сн'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'бірнеше секунд', '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'бір минут',      '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'бір минут',      '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 минут',     '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 минут',    '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'бір сағат',       '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'бір сағат',       '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 сағат',       '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 сағат',       '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 сағат',      '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'бір күн',         '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'бір күн',         '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 күн',        '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'бір күн',         '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 күн',        '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 күн',       '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'бір ай',       '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'бір ай',       '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'бір ай',       '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 ай',      '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 ай',      '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 ай',      '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'бір ай',       '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 ай',      '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'бір жыл',        '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 жыл',       '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'бір жыл',        '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 жыл',       '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'бірнеше секунд ішінде',  'prefix');\n    assert.equal(moment(0).from(30000), 'бірнеше секунд бұрын', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'бірнеше секунд бұрын',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'бірнеше секунд ішінде', 'in a few seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), '5 күн ішінде', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'Бүгін сағат 12:00',  'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'Бүгін сағат 12:25',  'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'Бүгін сағат 13:00',  'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'Ертең сағат 12:00',  'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'Бүгін сағат 11:00',  'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'Кеше сағат 12:00',   'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('dddd [сағат] LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd [сағат] LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd [сағат] LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('[Өткен аптаның] dddd [сағат] LT'),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[Өткен аптаның] dddd [сағат] LT'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[Өткен аптаның] dddd [сағат] LT'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2012, 0,  1]).format('w ww wo'),   '1 01 1-ші', 'Jan  1 2012 should be week 1');\n    assert.equal(moment([2012, 0,  2]).format('w ww wo'),   '2 02 2-ші', 'Jan  2 2012 should be week 2');\n    assert.equal(moment([2012, 0,  8]).format('w ww wo'),   '2 02 2-ші', 'Jan  8 2012 should be week 2');\n    assert.equal(moment([2012, 0,  9]).format('w ww wo'),   '3 03 3-ші', 'Jan  9 2012 should be week 3');\n    assert.equal(moment([2012, 0, 15]).format('w ww wo'),   '3 03 3-ші', 'Jan 15 2012 should be week 3');\n});\n\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/test/locale/km.js",
    "content": "import {localeModule, test} from '../qunit';\nimport moment from '../../moment';\nlocaleModule('km');\n\ntest('parse', function (assert) {\n    var tests = 'មករា មករា_កុម្ភៈ កុម្ភៈ_មីនា មីនា_មេសា មេសា_ឧសភា ឧសភា_មិថុនា មិថុនា_កក្កដា កក្កដា_សីហា សីហា_កញ្ញា កញ្ញា_តុលា តុលា_វិច្ឆិកា វិច្ឆិកា_ធ្នូ ធ្នូ'.split('_'),\n        i;\n\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, MMMM Do YYYY, h:mm:ss a', 'អាទិត្យ, កុម្ភៈ 14 2010, 3:25:50 pm'],\n            ['ddd, hA', 'អាទិត្យ, 3PM'],\n            ['M Mo MM MMMM MMM', '2 2 02 កុម្ភៈ កុម្ភៈ'],\n            ['YYYY YY', '2010 10'],\n            ['D Do DD', '14 14 14'],\n            ['d do dddd ddd dd', '0 0 អាទិត្យ អាទិត្យ អាទិត្យ'],\n            ['DDD DDDo DDDD', '45 45 045'],\n            ['w wo ww', '6 6 06'],\n            ['h hh', '3 03'],\n            ['H HH', '15 15'],\n            ['m mm', '25 25'],\n            ['s ss', '50 50'],\n            ['a A', 'pm PM'],\n            ['[the] DDDo [day of the year]', 'the 45 day of the year'],\n            ['LTS', '15:25:50'],\n            ['L', '14/02/2010'],\n            ['LL', '14 កុម្ភៈ 2010'],\n            ['LLL', '14 កុម្ភៈ 2010 15:25'],\n            ['LLLL', 'អាទិត្យ, 14 កុម្ភៈ 2010 15:25'],\n            ['l', '14/2/2010'],\n            ['ll', '14 កុម្ភៈ 2010'],\n            ['lll', '14 កុម្ភៈ 2010 15:25'],\n            ['llll', 'អាទិត្យ, 14 កុម្ភៈ 2010 15:25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1', '1st');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2', '2nd');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3', '3rd');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4', '4th');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5', '5th');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6', '6th');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7', '7th');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8', '8th');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9', '9th');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10', '10th');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11', '11th');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12', '12th');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13', '13th');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14', '14th');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15', '15th');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16', '16th');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17', '17th');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18', '18th');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19', '19th');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20', '20th');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21', '21st');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22', '22nd');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23', '23rd');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24', '24th');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25', '25th');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26', '26th');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27', '27th');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28', '28th');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29', '29th');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30', '30th');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31', '31st');\n});\n\ntest('format month', function (assert) {\n    var expected = 'មករា មករា_កុម្ភៈ កុម្ភៈ_មីនា មីនា_មេសា មេសា_ឧសភា ឧសភា_មិថុនា មិថុនា_កក្កដា កក្កដា_សីហា សីហា_កញ្ញា កញ្ញា_តុលា តុលា_វិច្ឆិកា វិច្ឆិកា_ធ្នូ ធ្នូ'.split('_'),\n        i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'អាទិត្យ អាទិត្យ អាទិត្យ_ច័ន្ទ ច័ន្ទ ច័ន្ទ_អង្គារ អង្គារ អង្គារ_ពុធ ពុធ ពុធ_ព្រហស្បតិ៍ ព្រហស្បតិ៍ ព្រហស្បតិ៍_សុក្រ សុក្រ សុក្រ_សៅរ៍ សៅរ៍ សៅរ៍'.split('_'),\n        i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true), 'ប៉ុន្មានវិនាទី', '44 seconds = ប៉ុន្មានវិនាទី');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true), 'មួយនាទី', '45 seconds = មួយនាទី');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true), 'មួយនាទី', '89 seconds = មួយនាទី');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true), '2 នាទី', '90 seconds = 2 នាទី');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true), '44 នាទី', '44 minutes = 44 នាទី');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true), 'មួយម៉ោង', '45 minutes = មួយម៉ោង');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true), 'មួយម៉ោង', '89 minutes = មួយម៉ោង');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true), '2 ម៉ោង', '90 minutes = 2 ម៉ោង');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true), '5 ម៉ោង', '5 hours = 5 ម៉ោង');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true), '21 ម៉ោង', '21 hours = 21 ម៉ោង');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true), 'មួយថ្ងៃ', '22 hours = មួយថ្ងៃ');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true), 'មួយថ្ងៃ', '35 hours = មួយថ្ងៃ');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true), '2 ថ្ងៃ', '36 hours = 2 ថ្ងៃ');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true), 'មួយថ្ងៃ', '1 day = មួយថ្ងៃ');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true), '5 ថ្ងៃ', '5 days = 5 ថ្ងៃ');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true), '25 ថ្ងៃ', '25 days = 25 ថ្ងៃ');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true), 'មួយខែ', '26 days = មួយខែ');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true), 'មួយខែ', '30 days = មួយខែ');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true), 'មួយខែ', '43 days = មួយខែ');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true), '2 ខែ', '46 days = 2 ខែ');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true), '2 ខែ', '75 days = 2 ខែ');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true), '3 ខែ', '76 days = 3 ខែ');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true), 'មួយខែ', '1 month = មួយខែ');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true), '5 ខែ', '5 months = 5 ខែ');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'មួយឆ្នាំ', '345 days = មួយឆ្នាំ');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 ឆ្នាំ', '548 days = 2 ឆ្នាំ');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true), 'មួយឆ្នាំ', '1 year = មួយឆ្នាំ');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true), '5 ឆ្នាំ', '5 years = 5 ឆ្នាំ');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'ប៉ុន្មានវិនាទីទៀត', 'prefix');\n    assert.equal(moment(0).from(30000), 'ប៉ុន្មានវិនាទីមុន', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'ប៉ុន្មានវិនាទីមុន', 'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({\n        s: 30\n    }).fromNow(), 'ប៉ុន្មានវិនាទីទៀត', 'in a few seconds');\n    assert.equal(moment().add({\n        d: 5\n    }).fromNow(), '5 ថ្ងៃទៀត', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                  'ថ្ងៃនេះ ម៉ោង 12:00',  'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),     'ថ្ងៃនេះ ម៉ោង 12:25',  'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),      'ថ្ងៃនេះ ម៉ោង 13:00',  'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),      'ស្អែក ម៉ោង 12:00',    'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(), 'ថ្ងៃនេះ ម៉ោង 11:00',  'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(), 'ម្សិលមិញ ម៉ោង 12:00', 'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({\n            d: i\n        });\n        assert.equal(m.calendar(), m.format('dddd [ម៉ោង] LT'), 'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(), m.format('dddd [ម៉ោង] LT'), 'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(), m.format('dddd [ម៉ោង] LT'), 'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({\n            d: i\n        });\n        assert.equal(m.calendar(), m.format('dddd [សប្តាហ៍មុន] [ម៉ោង] LT'), 'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(), m.format('dddd [សប្តាហ៍មុន] [ម៉ោង] LT'), 'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(), m.format('dddd [សប្តាហ៍មុន] [ម៉ោង] LT'), 'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({\n            w: 1\n        }),\n        weeksFromNow = moment().add({\n            w: 1\n        });\n\n    assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '1 week ago');\n    assert.equal(weeksFromNow.calendar(), weeksFromNow.format('L'), 'in 1 week');\n\n    weeksAgo = moment().subtract({\n        w: 2\n    });\n    weeksFromNow = moment().add({\n        w: 2\n    });\n\n    assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(), weeksFromNow.format('L'), 'in 2 weeks');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2012, 0, 1]).format('w ww wo'), '52 52 52', 'Jan  1 2012 should be week 52');\n    assert.equal(moment([2012, 0, 2]).format('w ww wo'), '1 01 1', 'Jan  2 2012 should be week 1');\n    assert.equal(moment([2012, 0, 8]).format('w ww wo'), '1 01 1', 'Jan  8 2012 should be week 1');\n    assert.equal(moment([2012, 0, 9]).format('w ww wo'), '2 02 2', 'Jan  9 2012 should be week 2');\n    assert.equal(moment([2012, 0, 15]).format('w ww wo'), '2 02 2', 'Jan 15 2012 should be week 2');\n});\n\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/test/locale/kn.js",
    "content": "import {localeModule, test} from '../qunit';\nimport moment from '../../moment';\nlocaleModule('kn');\n\ntest('parse', function (assert) {\n    var tests = 'ಜನವರಿ ಜನ_ಫೆಬ್ರವರಿ ಫೆಬ್ರ_ಮಾರ್ಚ್ ಮಾರ್ಚ್_ಏಪ್ರಿಲ್ ಏಪ್ರಿಲ್_ಮೇ ಮೇ_ಜೂನ್ ಜೂನ್_ಜುಲೈ ಜುಲೈ_ಆಗಸ್ಟ್ ಆಗಸ್ಟ್_ಸೆಪ್ಟೆಂಬರ್ ಸೆಪ್ಟೆಂಬ_ಅಕ್ಟೋಬರ್ ಅಕ್ಟೋಬ_ನವೆಂಬರ್ ನವೆಂಬ_ಡಿಸೆಂಬರ್ ಡಿಸೆಂಬ'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, Do MMMM YYYY, a h:mm:ss',      'ಭಾನುವಾರ, ೧೪ನೇ ಫೆಬ್ರವರಿ ೨೦೧೦, ಮಧ್ಯಾಹ್ನ ೩:೨೫:೫೦'],\n            ['ddd, a h ಗಂಟೆ',                      'ಭಾನು, ಮಧ್ಯಾಹ್ನ ೩ ಗಂಟೆ'],\n            ['M Mo MM MMMM MMM',                   '೨ ೨ನೇ ೦೨ ಫೆಬ್ರವರಿ ಫೆಬ್ರ'],\n            ['YYYY YY',                            '೨೦೧೦ ೧೦'],\n            ['D Do DD',                            '೧೪ ೧೪ನೇ ೧೪'],\n            ['d do dddd ddd dd',                   '೦ ೦ನೇ ಭಾನುವಾರ ಭಾನು ಭಾ'],\n            ['DDD DDDo DDDD',                      '೪೫ ೪೫ನೇ ೦೪೫'],\n            ['w wo ww',                            '೮ ೮ನೇ ೦೮'],\n            ['h hh',                               '೩ ೦೩'],\n            ['H HH',                               '೧೫ ೧೫'],\n            ['m mm',                               '೨೫ ೨೫'],\n            ['s ss',                               '೫೦ ೫೦'],\n            ['a A',                                'ಮಧ್ಯಾಹ್ನ ಮಧ್ಯಾಹ್ನ'],\n            ['LTS',                                'ಮಧ್ಯಾಹ್ನ ೩:೨೫:೫೦'],\n            ['L',                                  '೧೪/೦೨/೨೦೧೦'],\n            ['LL',                                 '೧೪ ಫೆಬ್ರವರಿ ೨೦೧೦'],\n            ['LLL',                                '೧೪ ಫೆಬ್ರವರಿ ೨೦೧೦, ಮಧ್ಯಾಹ್ನ ೩:೨೫'],\n            ['LLLL',                               'ಭಾನುವಾರ, ೧೪ ಫೆಬ್ರವರಿ ೨೦೧೦, ಮಧ್ಯಾಹ್ನ ೩:೨೫'],\n            ['l',                                  '೧೪/೨/೨೦೧೦'],\n            ['ll',                                 '೧೪ ಫೆಬ್ರ ೨೦೧೦'],\n            ['lll',                                '೧೪ ಫೆಬ್ರ ೨೦೧೦, ಮಧ್ಯಾಹ್ನ ೩:೨೫'],\n            ['llll',                               'ಭಾನು, ೧೪ ಫೆಬ್ರ ೨೦೧೦, ಮಧ್ಯಾಹ್ನ ೩:೨೫']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '೧ನೇ', '೧ನೇ');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '೨ನೇ', '೨ನೇ');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '೩ನೇ', '೩ನೇ');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '೪ನೇ', '೪ನೇ');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '೫ನೇ', '೫ನೇ');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '೬ನೇ', '೬ನೇ');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '೭ನೇ', '೭ನೇ');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '೮ನೇ', '೮ನೇ');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '೯ನೇ', '೯ನೇ');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '೧೦ನೇ', '೧೦ನೇ');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '೧೧ನೇ', '೧೧ನೇ');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '೧೨ನೇ', '೧೨ನೇ');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '೧೩ನೇ', '೧೩ನೇ');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '೧೪ನೇ', '೧೪ನೇ');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '೧೫ನೇ', '೧೫ನೇ');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '೧೬ನೇ', '೧೬ನೇ');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '೧೭ನೇ', '೧೭ನೇ');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '೧೮ನೇ', '೧೮ನೇ');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '೧೯ನೇ', '೧೯ನೇ');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '೨೦ನೇ', '೨೦ನೇ');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '೨೧ನೇ', '೨೧ನೇ');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '೨೨ನೇ', '೨೨ನೇ');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '೨೩ನೇ', '೨೩ನೇ');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '೨೪ನೇ', '೨೪ನೇ');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '೨೫ನೇ', '೨೫ನೇ');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '೨೬ನೇ', '೨೬ನೇ');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '೨೭ನೇ', '೨೭ನೇ');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '೨೮ನೇ', '೨೮ನೇ');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '೨೯ನೇ', '೨೯ನೇ');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '೩೦ನೇ', '೩೦ನೇ');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '೩೧ನೇ', '೩೧ನೇ');\n});\n\ntest('format month', function (assert) {\n    var expected = 'ಜನವರಿ ಜನ_ಫೆಬ್ರವರಿ ಫೆಬ್ರ_ಮಾರ್ಚ್ ಮಾರ್ಚ್_ಏಪ್ರಿಲ್ ಏಪ್ರಿಲ್_ಮೇ ಮೇ_ಜೂನ್ ಜೂನ್_ಜುಲೈ ಜುಲೈ_ಆಗಸ್ಟ್ ಆಗಸ್ಟ್_ಸೆಪ್ಟೆಂಬರ್ ಸೆಪ್ಟೆಂಬ_ಅಕ್ಟೋಬರ್ ಅಕ್ಟೋಬ_ನವೆಂಬರ್ ನವೆಂಬ_ಡಿಸೆಂಬರ್ ಡಿಸೆಂಬ'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'ಭಾನುವಾರ ಭಾನು ಭಾ_ಸೋಮವಾರ ಸೋಮ ಸೋ_ಮಂಗಳವಾರ ಮಂಗಳ ಮಂ_ಬುಧವಾರ ಬುಧ ಬು_ಗುರುವಾರ ಗುರು ಗು_ಶುಕ್ರವಾರ ಶುಕ್ರ ಶು_ಶನಿವಾರ ಶನಿ ಶ'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'ಕೆಲವು ಕ್ಷಣಗಳು', '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'ಒಂದು ನಿಮಿಷ',      '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'ಒಂದು ನಿಮಿಷ',      '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '೨ ನಿಮಿಷ',     '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '೪೪ ನಿಮಿಷ',    '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'ಒಂದು ಗಂಟೆ',       '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'ಒಂದು ಗಂಟೆ',       '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '೨ ಗಂಟೆ',       '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '೫ ಗಂಟೆ',       '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '೨೧ ಗಂಟೆ',      '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'ಒಂದು ದಿನ',         '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'ಒಂದು ದಿನ',         '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '೨ ದಿನ',        '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'ಒಂದು ದಿನ',         '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '೫ ದಿನ',        '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '೨೫ ದಿನ',       '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'ಒಂದು ತಿಂಗಳು',       '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'ಒಂದು ತಿಂಗಳು',       '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'ಒಂದು ತಿಂಗಳು',       '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '೨ ತಿಂಗಳು',      '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '೨ ತಿಂಗಳು',      '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '೩ ತಿಂಗಳು',      '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'ಒಂದು ತಿಂಗಳು',       '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '೫ ತಿಂಗಳು',      '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'ಒಂದು ವರ್ಷ',        '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '೨ ವರ್ಷ',       '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'ಒಂದು ವರ್ಷ',        '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '೫ ವರ್ಷ',       '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'ಕೆಲವು ಕ್ಷಣಗಳು ನಂತರ',  'prefix');\n    assert.equal(moment(0).from(30000), 'ಕೆಲವು ಕ್ಷಣಗಳು ಹಿಂದೆ', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'ಕೆಲವು ಕ್ಷಣಗಳು ಹಿಂದೆ',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'ಕೆಲವು ಕ್ಷಣಗಳು ನಂತರ', 'ಕೆಲವು ಕ್ಷಣಗಳು ನಂತರ');\n    assert.equal(moment().add({d: 5}).fromNow(), '೫ ದಿನ ನಂತರ', '೫ ದಿನ ನಂತರ');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'ಇಂದು ಮಧ್ಯಾಹ್ನ ೧೨:೦೦',    'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'ಇಂದು ಮಧ್ಯಾಹ್ನ ೧೨:೨೫',    'Now plus 25 min');\n    assert.equal(moment(a).add({h: 3}).calendar(),       'ಇಂದು ಮಧ್ಯಾಹ್ನ ೩:೦೦',     'Now plus 3 hours');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'ನಾಳೆ ಮಧ್ಯಾಹ್ನ ೧೨:೦೦',    'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'ಇಂದು ಮಧ್ಯಾಹ್ನ ೧೧:೦೦',    'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'ನಿನ್ನೆ ಮಧ್ಯಾಹ್ನ ೧೨:೦೦',    'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('dddd[,] LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd[,] LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd[,] LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('[ಕೊನೆಯ] dddd[,] LT'),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[ಕೊನೆಯ] dddd[,] LT'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[ಕೊನೆಯ] dddd[,] LT'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('meridiem', function (assert) {\n    assert.equal(moment([2011, 2, 23,  2, 30]).format('a'), 'ರಾತ್ರಿ', 'before dawn');\n    assert.equal(moment([2011, 2, 23,  9, 30]).format('a'), 'ಬೆಳಿಗ್ಗೆ', 'morning');\n    assert.equal(moment([2011, 2, 23, 14, 30]).format('a'), 'ಮಧ್ಯಾಹ್ನ', 'during day');\n    assert.equal(moment([2011, 2, 23, 17, 30]).format('a'), 'ಸಂಜೆ', 'evening');\n    assert.equal(moment([2011, 2, 23, 19, 30]).format('a'), 'ಸಂಜೆ', 'late evening');\n    assert.equal(moment([2011, 2, 23, 21, 20]).format('a'), 'ರಾತ್ರಿ', 'night');\n\n    assert.equal(moment([2011, 2, 23,  2, 30]).format('A'), 'ರಾತ್ರಿ', 'before dawn');\n    assert.equal(moment([2011, 2, 23,  9, 30]).format('A'), 'ಬೆಳಿಗ್ಗೆ', 'morning');\n    assert.equal(moment([2011, 2, 23, 14, 30]).format('A'), 'ಮಧ್ಯಾಹ್ನ', ' during day');\n    assert.equal(moment([2011, 2, 23, 17, 30]).format('A'), 'ಸಂಜೆ', 'evening');\n    assert.equal(moment([2011, 2, 23, 19, 30]).format('A'), 'ಸಂಜೆ', 'late evening');\n    assert.equal(moment([2011, 2, 23, 21, 20]).format('A'), 'ರಾತ್ರಿ', 'night');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2012, 0,  1]).format('w ww wo'), '೧ ೦೧ ೧ನೇ', 'Jan  1 2012 should be week 1');\n    assert.equal(moment([2012, 0,  7]).format('w ww wo'), '೧ ೦೧ ೧ನೇ', 'Jan  7 2012 should be week 1');\n    assert.equal(moment([2012, 0,  8]).format('w ww wo'), '೨ ೦೨ ೨ನೇ', 'Jan  8 2012 should be week 2');\n    assert.equal(moment([2012, 0, 14]).format('w ww wo'), '೨ ೦೨ ೨ನೇ', 'Jan 14 2012 should be week 2');\n    assert.equal(moment([2012, 0, 15]).format('w ww wo'), '೩ ೦೩ ೩ನೇ', 'Jan 15 2012 should be week 3');\n});\n\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/test/locale/ko.js",
    "content": "import {localeModule, test} from '../qunit';\nimport moment from '../../moment';\nlocaleModule('ko');\n\ntest('parse', function (assert) {\n    var tests = '1월 1월_2월 2월_3월 3월_4월 4월_5월 5월_6월 6월_7월 7월_8월 8월_9월 9월_10월 10월_11월 11월_12월 12월'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('parse meridiem', function (assert) {\n    var elements = [{\n        expression : '1981년 9월 8일 오후 2시 30분',\n        inputFormat : 'YYYY[년] M[월] D[일] A h[시] m[분]',\n        outputFormat : 'A',\n        expected : '오후'\n    }, {\n        expression : '1981년 9월 8일 오전 2시 30분',\n        inputFormat : 'YYYY[년] M[월] D[일] A h[시] m[분]',\n        outputFormat : 'A h시',\n        expected : '오전 2시'\n    }, {\n        expression : '14시 30분',\n        inputFormat : 'H[시] m[분]',\n        outputFormat : 'A',\n        expected : '오후'\n    }, {\n        expression : '오후 4시',\n        inputFormat : 'A h[시]',\n        outputFormat : 'H',\n        expected : '16'\n    }], i, l, it, actual;\n\n    for (i = 0, l = elements.length; i < l; ++i) {\n        it = elements[i];\n        actual = moment(it.expression, it.inputFormat).format(it.outputFormat);\n\n        assert.equal(\n            actual,\n            it.expected,\n            '\\'' + it.outputFormat + '\\' of \\'' + it.expression + '\\' must be \\'' + it.expected + '\\' but was \\'' + actual + '\\'.'\n        );\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['YYYY년 MMMM Do dddd a h:mm:ss',      '2010년 2월 14일 일요일 오후 3:25:50'],\n            ['ddd A h',                            '일 오후 3'],\n            ['M Mo MM MMMM MMM',                   '2 2일 02 2월 2월'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14일 14'],\n            ['d do dddd ddd dd',                   '0 0일 일요일 일 일'],\n            ['DDD DDDo DDDD',                      '45 45일 045'],\n            ['w wo ww',                            '8 8일 08'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                '오후 오후'],\n            ['일년 중 DDDo째 되는 날',                 '일년 중 45일째 되는 날'],\n            ['LTS',                                '오후 3:25:50'],\n            ['L',                                  '2010.02.14'],\n            ['LL',                                 '2010년 2월 14일'],\n            ['LLL',                                '2010년 2월 14일 오후 3:25'],\n            ['LLLL',                               '2010년 2월 14일 일요일 오후 3:25'],\n            ['l',                                  '2010.02.14'],\n            ['ll',                                 '2010년 2월 14일'],\n            ['lll',                                '2010년 2월 14일 오후 3:25'],\n            ['llll',                               '2010년 2월 14일 일요일 오후 3:25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1일', '1일');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2일', '2일');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3일', '3일');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4일', '4일');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5일', '5일');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6일', '6일');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7일', '7일');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8일', '8일');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9일', '9일');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10일', '10일');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11일', '11일');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12일', '12일');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13일', '13일');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14일', '14일');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15일', '15일');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16일', '16일');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17일', '17일');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18일', '18일');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19일', '19일');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20일', '20일');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21일', '21일');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22일', '22일');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23일', '23일');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24일', '24일');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25일', '25일');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26일', '26일');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27일', '27일');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28일', '28일');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29일', '29일');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30일', '30일');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31일', '31일');\n});\n\ntest('format month', function (assert) {\n    var expected = '1월 1월_2월 2월_3월 3월_4월 4월_5월 5월_6월 6월_7월 7월_8월 8월_9월 9월_10월 10월_11월 11월_12월 12월'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = '일요일 일 일_월요일 월 월_화요일 화 화_수요일 수 수_목요일 목 목_금요일 금 금_토요일 토 토'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  '몇 초', '44초 = 몇 초');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  '1분',      '45초 = 1분');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  '1분',      '89초 = 1분');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2분',     '90초 = 2분');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44분',    '44분 = 44분');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  '한 시간',       '45분 = 한 시간');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  '한 시간',       '89분 = 한 시간');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2시간',       '90분 = 2시간');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5시간',       '5시간 = 5시간');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21시간',      '21시간 = 21시간');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  '하루',         '22시간 = 하루');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  '하루',         '35시간 = 하루');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2일',        '36시간 = 2일');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   '하루',         '하루 = 하루');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5일',        '5일 = 5일');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25일',       '25일 = 25일');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  '한 달',       '26일 = 한 달');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  '한 달',       '30일 = 한 달');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  '한 달',       '45일 = 한 달');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2달',      '46일 = 2달');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2달',      '75일 = 2달');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3달',      '76일 = 3달');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   '한 달',       '1달 = 한 달');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5달',      '5달 = 5달');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), '일 년',        '345일 = 일 년');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2년',       '548일 = 2년');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   '일 년',        '일 년 = 일 년');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5년',       '5년 = 5년');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), '몇 초 후',  'prefix');\n    assert.equal(moment(0).from(30000), '몇 초 전', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), '몇 초 전',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), '몇 초 후', 'in a few seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), '5일 후', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   '오늘 오후 12:00', 'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      '오늘 오후 12:25', 'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       '오늘 오후 1:00',  'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       '내일 오후 12:00', 'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  '오늘 오전 11:00', 'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  '어제 오후 12:00', 'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('dddd LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('지난주 dddd LT'),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('지난주 dddd LT'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('지난주 dddd LT'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('weeks year starting sunday format', function (assert) {\n    assert.equal(moment([2012, 0,  1]).format('w ww wo'), '1 01 1일', 'Jan  1 2012 should be week 1');\n    assert.equal(moment([2012, 0,  7]).format('w ww wo'), '1 01 1일', 'Jan  7 2012 should be week 1');\n    assert.equal(moment([2012, 0,  8]).format('w ww wo'), '2 02 2일', 'Jan  8 2012 should be week 2');\n    assert.equal(moment([2012, 0, 14]).format('w ww wo'), '2 02 2일', 'Jan 14 2012 should be week 2');\n    assert.equal(moment([2012, 0, 15]).format('w ww wo'), '3 03 3일', 'Jan 15 2012 should be week 3');\n});\n\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/test/locale/ky.js",
    "content": "import {localeModule, test} from '../qunit';\nimport moment from '../../moment';\nlocaleModule('ky');\n\ntest('parse', function (assert) {\n    var tests = 'январь янв_февраль фев_март март_апрель апр_май май_июнь июнь_июль июль_август авг_сентябрь сен_октябрь окт_ноябрь ноя_декабрь дек'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, Do MMMM YYYY, HH:mm:ss',       'Жекшемби, 14-чү февраль 2010, 15:25:50'],\n            ['ddd, hA',                            'Жек, 3PM'],\n            ['M Mo MM MMMM MMM',                   '2 2-чи 02 февраль фев'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14-чү 14'],\n            ['d do dddd ddd dd',                   '0 0-чү Жекшемби Жек Жк'],\n            ['DDD DDDo DDDD',                      '45 45-чи 045'],\n            ['w wo ww',                            '7 7-чи 07'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'pm PM'],\n            ['[жылдын] DDDo [күнү]',               'жылдын 45-чи күнү'],\n            ['LTS',                                '15:25:50'],\n            ['L',                                  '14.02.2010'],\n            ['LL',                                 '14 февраль 2010'],\n            ['LLL',                                '14 февраль 2010 15:25'],\n            ['LLLL',                               'Жекшемби, 14 февраль 2010 15:25'],\n            ['l',                                  '14.2.2010'],\n            ['ll',                                 '14 фев 2010'],\n            ['lll',                                '14 фев 2010 15:25'],\n            ['llll',                               'Жек, 14 фев 2010 15:25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1-чи', '1st');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2-чи', '2nd');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3-чү', '3rd');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4-чү', '4th');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5-чи', '5th');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6-чы', '6th');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7-чи', '7th');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8-чи', '8th');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9-чу', '9th');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10-чу', '10th');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11-чи', '11th');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12-чи', '12th');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13-чү', '13th');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14-чү', '14th');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15-чи', '15th');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16-чы', '16th');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17-чи', '17th');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18-чи', '18th');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19-чу', '19th');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20-чы', '20th');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21-чи', '21st');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22-чи', '22nd');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23-чү', '23rd');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24-чү', '24th');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25-чи', '25th');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26-чы', '26th');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27-чи', '27th');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28-чи', '28th');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29-чу', '29th');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30-чу', '30th');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31-чи', '31st');\n});\n\ntest('format month', function (assert) {\n    var expected = 'январь янв_февраль фев_март март_апрель апр_май май_июнь июнь_июль июль_август авг_сентябрь сен_октябрь окт_ноябрь ноя_декабрь дек'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'Жекшемби Жек Жк_Дүйшөмбү Дүй Дй_Шейшемби Шей Шй_Шаршемби Шар Шр_Бейшемби Бей Бй_Жума Жум Жм_Ишемби Ише Иш'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'бирнече секунд', '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'бир мүнөт',      '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'бир мүнөт',      '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 мүнөт',     '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 мүнөт',    '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'бир саат',       '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'бир саат',       '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 саат',       '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 саат',       '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 саат',      '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'бир күн',         '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'бир күн',         '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 күн',        '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'бир күн',         '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 күн',        '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 күн',       '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'бир ай',       '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'бир ай',       '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'бир ай',       '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 ай',      '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 ай',      '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 ай',      '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'бир ай',       '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 ай',      '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'бир жыл',        '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 жыл',       '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'бир жыл',        '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 жыл',       '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'бирнече секунд ичинде',  'prefix');\n    assert.equal(moment(0).from(30000), 'бирнече секунд мурун', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'бирнече секунд мурун',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'бирнече секунд ичинде', 'in a few seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), '5 күн ичинде', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'Бүгүн саат 12:00',  'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'Бүгүн саат 12:25',  'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'Бүгүн саат 13:00',  'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'Эртең саат 12:00',  'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'Бүгүн саат 11:00',  'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'Кече саат 12:00',   'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('dddd [саат] LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd [саат] LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd [саат] LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('[Өткен аптанын] dddd [күнү] [саат] LT'),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[Өткен аптанын] dddd [күнү] [саат] LT'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[Өткен аптанын] dddd [күнү] [саат] LT'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2012, 0,  1]).format('w ww wo'),   '1 01 1-чи', 'Jan  1 2012 should be week 1');\n    assert.equal(moment([2012, 0,  2]).format('w ww wo'),   '2 02 2-чи', 'Jan  2 2012 should be week 2');\n    assert.equal(moment([2012, 0,  8]).format('w ww wo'),   '2 02 2-чи', 'Jan  8 2012 should be week 2');\n    assert.equal(moment([2012, 0,  9]).format('w ww wo'),   '3 03 3-чү', 'Jan  9 2012 should be week 3');\n    assert.equal(moment([2012, 0, 15]).format('w ww wo'),   '3 03 3-чү', 'Jan 15 2012 should be week 3');\n});\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/test/locale/lb.js",
    "content": "import {localeModule, test} from '../qunit';\nimport moment from '../../moment';\nlocaleModule('lb');\n\ntest('parse', function (assert) {\n    var tests = 'Januar Jan._Februar Febr._Mäerz Mrz._Abrëll Abr._Mee Mee_Juni Jun._Juli Jul._August Aug._September Sept._Oktober Okt._November Nov._Dezember Dez.'.split('_'), i;\n\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, Do MMMM YYYY, HH:mm:ss', 'Sonndeg, 14. Februar 2010, 15:25:50'],\n            ['ddd, HH:mm', 'So., 15:25'],\n            ['M Mo MM MMMM MMM', '2 2. 02 Februar Febr.'],\n            ['YYYY YY', '2010 10'],\n            ['D Do DD', '14 14. 14'],\n            ['d do dddd ddd dd', '0 0. Sonndeg So. So'],\n            ['DDD DDDo DDDD', '45 45. 045'],\n            ['w wo ww', '6 6. 06'],\n            ['h hh', '3 03'],\n            ['H HH', '15 15'],\n            ['m mm', '25 25'],\n            ['s ss', '50 50'],\n            ['a A', 'pm PM'],\n            ['[the] DDDo [day of the year]', 'the 45. day of the year'],\n            ['LTS', '15:25:50 Auer'],\n            ['L', '14.02.2010'],\n            ['LL', '14. Februar 2010'],\n            ['LLL', '14. Februar 2010 15:25 Auer'],\n            ['LLLL', 'Sonndeg, 14. Februar 2010 15:25 Auer'],\n            ['l', '14.2.2010'],\n            ['ll', '14. Febr. 2010'],\n            ['lll', '14. Febr. 2010 15:25 Auer'],\n            ['llll', 'So., 14. Febr. 2010 15:25 Auer']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format month', function (assert) {\n    var expected = 'Januar Jan._Februar Febr._Mäerz Mrz._Abrëll Abr._Mee Mee_Juni Jun._Juli Jul._August Aug._September Sept._Oktober Okt._November Nov._Dezember Dez.'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'Sonndeg So. So_Méindeg Mé. Mé_Dënschdeg Dë. Dë_Mëttwoch Më. Më_Donneschdeg Do. Do_Freideg Fr. Fr_Samschdeg Sa. Sa'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true), 'e puer Sekonnen', '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true), 'eng Minutt', '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true), 'eng Minutt', '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true), '2 Minutten', '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true), '44 Minutten', '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true), 'eng Stonn', '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true), 'eng Stonn', '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true), '2 Stonnen', '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true), '5 Stonnen', '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true), '21 Stonnen', '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true), 'een Dag', '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true), 'een Dag', '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true), '2 Deeg', '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true), 'een Dag', '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true), '5 Deeg', '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true), '25 Deeg', '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true), 'ee Mount', '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true), 'ee Mount', '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true), 'ee Mount', '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true), '2 Méint', '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true), '2 Méint', '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true), '3 Méint', '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true), 'ee Mount', '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true), '5 Méint', '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'ee Joer', '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 Joer', '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true), 'ee Joer', '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true), '5 Joer', '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'an e puer Sekonnen', 'prefix');\n    assert.equal(moment(0).from(30000), 'virun e puer Sekonnen', 'suffix');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'an e puer Sekonnen', 'in a few seconds');\n    assert.equal(moment().add({d: 1}).fromNow(), 'an engem Dag', 'in one day');\n    assert.equal(moment().add({d: 2}).fromNow(), 'an 2 Deeg', 'in 2 days');\n    assert.equal(moment().add({d: 3}).fromNow(), 'an 3 Deeg', 'in 3 days');\n    assert.equal(moment().add({d: 4}).fromNow(), 'a 4 Deeg', 'in 4 days');\n    assert.equal(moment().add({d: 5}).fromNow(), 'a 5 Deeg', 'in 5 days');\n    assert.equal(moment().add({d: 6}).fromNow(), 'a 6 Deeg', 'in 6 days');\n    assert.equal(moment().add({d: 7}).fromNow(), 'a 7 Deeg', 'in 7 days');\n    assert.equal(moment().add({d: 8}).fromNow(), 'an 8 Deeg', 'in 8 days');\n    assert.equal(moment().add({d: 9}).fromNow(), 'an 9 Deeg', 'in 9 days');\n    assert.equal(moment().add({d: 10}).fromNow(), 'an 10 Deeg', 'in 10 days');\n    assert.equal(moment().add({y: 100}).fromNow(), 'an 100 Joer', 'in 100 years');\n    assert.equal(moment().add({y: 400}).fromNow(), 'a 400 Joer', 'in 400 years');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'Haut um 12:00 Auer',     'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'Haut um 12:25 Auer',     'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'Haut um 13:00 Auer',     'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'Muer um 12:00 Auer',     'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'Haut um 11:00 Auer',     'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'Gëschter um 12:00 Auer', 'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('dddd [um] LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd [um] LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd [um] LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m, weekday, datestring;\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n\n        // Different date string for 'Dënschdeg' (Tuesday) and 'Donneschdeg' (Thursday)\n        weekday = parseInt(m.format('d'), 10);\n        datestring = (weekday === 2 || weekday === 4 ? '[Leschten] dddd [um] LT' : '[Leschte] dddd [um] LT');\n\n        assert.equal(m.calendar(), m.format(datestring), 'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(), m.format(datestring), 'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(), m.format(datestring), 'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('weeks year starting sunday format', function (assert) {\n    assert.equal(moment([2012, 0,  1]).format('w ww wo'), '52 52 52.', 'Jan  1 2012 should be week 52');\n    assert.equal(moment([2012, 0,  7]).format('w ww wo'), '1 01 1.',   'Jan  7 2012 should be week 1');\n    assert.equal(moment([2012, 0,  8]).format('w ww wo'), '1 01 1.',   'Jan  8 2012 should be week 1');\n    assert.equal(moment([2012, 0, 14]).format('w ww wo'), '2 02 2.',   'Jan 14 2012 should be week 2');\n    assert.equal(moment([2012, 0, 15]).format('w ww wo'), '2 02 2.',   'Jan 15 2012 should be week 2');\n});\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/test/locale/lo.js",
    "content": "import {localeModule, test} from '../qunit';\nimport moment from '../../moment';\nlocaleModule('lo');\n\ntest('parse', function (assert) {\n    var tests = 'ມັງກອນ ມັງກອນ_ກຸມພາ ກຸມພາ_ມີນາ ມີນາ_ເມສາ ເມສາ_ພຶດສະພາ ພຶດສະພາ_ມິຖຸນາ ມິຖຸນາ_ກໍລະກົດ ກໍລະກົດ_ສິງຫາ ສິງຫາ_ກັນຍາ ກັນຍາ_ຕຸລາ ຕຸລາ_ພະຈິກ ພະຈິກ_ທັນວາ ທັນວາ'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, MMMM Do YYYY, h:mm:ss a',      'ອາທິດ, ກຸມພາ ທີ່14 2010, 3:25:50 ຕອນແລງ'],\n            ['ddd, hA',                            'ທິດ, 3ຕອນແລງ'],\n            ['M Mo MM MMMM MMM',                   '2 ທີ່2 02 ກຸມພາ ກຸມພາ'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 ທີ່14 14'],\n            ['d do dddd ddd dd',                   '0 ທີ່0 ອາທິດ ທິດ ທ'],\n            ['DDD DDDo DDDD',                      '45 ທີ່45 045'],\n            ['w wo ww',                            '8 ທີ່8 08'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'ຕອນແລງ ຕອນແລງ'],\n            ['[ວັນ]DDDo [ຂອງປີ]',                   'ວັນທີ່45 ຂອງປີ'],\n            ['LTS',                                '15:25:50'],\n            ['L',                                  '14/02/2010'],\n            ['LL',                                 '14 ກຸມພາ 2010'],\n            ['LLL',                                '14 ກຸມພາ 2010 15:25'],\n            ['LLLL',                               'ວັນອາທິດ 14 ກຸມພາ 2010 15:25'],\n            ['l',                                  '14/2/2010'],\n            ['ll',                                 '14 ກຸມພາ 2010'],\n            ['lll',                                '14 ກຸມພາ 2010 15:25'],\n            ['llll',                               'ວັນທິດ 14 ກຸມພາ 2010 15:25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), 'ທີ່1', 'ທີ່1');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), 'ທີ່2', 'ທີ່2');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), 'ທີ່3', 'ທີ່3');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), 'ທີ່4', 'ທີ່4');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), 'ທີ່5', 'ທີ່5');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), 'ທີ່6', 'ທີ່6');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), 'ທີ່7', 'ທີ່7');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), 'ທີ່8', 'ທີ່8');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), 'ທີ່9', 'ທີ່9');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), 'ທີ່10', 'ທີ່10');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), 'ທີ່11', 'ທີ່11');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), 'ທີ່12', 'ທີ່12');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), 'ທີ່13', 'ທີ່13');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), 'ທີ່14', 'ທີ່14');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), 'ທີ່15', 'ທີ່15');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), 'ທີ່16', 'ທີ່16');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), 'ທີ່17', 'ທີ່17');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), 'ທີ່18', 'ທີ່18');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), 'ທີ່19', 'ທີ່19');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), 'ທີ່20', 'ທີ່20');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), 'ທີ່21', 'ທີ່21');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), 'ທີ່22', 'ທີ່22');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), 'ທີ່23', 'ທີ່23');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), 'ທີ່24', 'ທີ່24');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), 'ທີ່25', 'ທີ່25');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), 'ທີ່26', 'ທີ່26');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), 'ທີ່27', 'ທີ່27');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), 'ທີ່28', 'ທີ່28');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), 'ທີ່29', 'ທີ່29');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), 'ທີ່30', 'ທີ່30');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), 'ທີ່31', 'ທີ່31');\n});\n\ntest('format month', function (assert) {\n    var expected = 'ມັງກອນ ມັງກອນ_ກຸມພາ ກຸມພາ_ມີນາ ມີນາ_ເມສາ ເມສາ_ພຶດສະພາ ພຶດສະພາ_ມິຖຸນາ ມິຖຸນາ_ກໍລະກົດ ກໍລະກົດ_ສິງຫາ ສິງຫາ_ກັນຍາ ກັນຍາ_ຕຸລາ ຕຸລາ_ພະຈິກ ພະຈິກ_ທັນວາ ທັນວາ'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'ອາທິດ ທິດ ທ_ຈັນ ຈັນ ຈ_ອັງຄານ ອັງຄານ ອຄ_ພຸດ ພຸດ ພ_ພະຫັດ ພະຫັດ ພຫ_ສຸກ ສຸກ ສກ_ເສົາ ເສົາ ສ'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'ບໍ່ເທົ່າໃດວິນາທີ', '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  '1 ນາທີ',      '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  '1 ນາທີ',      '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 ນາທີ',     '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 ນາທີ',    '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  '1 ຊົ່ວໂມງ',       '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  '1 ຊົ່ວໂມງ',       '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 ຊົ່ວໂມງ',       '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 ຊົ່ວໂມງ',       '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 ຊົ່ວໂມງ',      '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  '1 ມື້',         '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  '1 ມື້',         '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 ມື້',        '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   '1 ມື້',         '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 ມື້',        '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 ມື້',       '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  '1 ເດືອນ',       '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  '1 ເດືອນ',       '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  '1 ເດືອນ',       '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 ເດືອນ',      '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 ເດືອນ',      '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 ເດືອນ',      '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   '1 ເດືອນ',       '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 ເດືອນ',      '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), '1 ປີ',        '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 ປີ',       '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   '1 ປີ',        '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 ປີ',       '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'ອີກ ບໍ່ເທົ່າໃດວິນາທີ',  'prefix');\n    assert.equal(moment(0).from(30000), 'ບໍ່ເທົ່າໃດວິນາທີຜ່ານມາ', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'ບໍ່ເທົ່າໃດວິນາທີຜ່ານມາ',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'ອີກ ບໍ່ເທົ່າໃດວິນາທີ', 'in a few seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), 'ອີກ 5 ມື້', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'ມື້ນີ້ເວລາ 12:00',    'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'ມື້ນີ້ເວລາ 12:25',    'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'ມື້ນີ້ເວລາ 13:00',    'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'ມື້ອື່ນເວລາ 12:00',   'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'ມື້ນີ້ເວລາ 11:00',    'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'ມື້ວານນີ້ເວລາ 12:00',  'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('[ວັນ]dddd[ໜ້າເວລາ] LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[ວັນ]dddd[ໜ້າເວລາ] LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[ວັນ]dddd[ໜ້າເວລາ] LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('[ວັນ]dddd[ແລ້ວນີ້ເວລາ] LT'),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[ວັນ]dddd[ແລ້ວນີ້ເວລາ] LT'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[ວັນ]dddd[ແລ້ວນີ້ເວລາ] LT'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('weeks year starting sunday format', function (assert) {\n    assert.equal(moment([2012, 0,  1]).format('w ww wo'), '1 01 ທີ່1', 'Jan  1 2012 should be week 1');\n    assert.equal(moment([2012, 0,  7]).format('w ww wo'), '1 01 ທີ່1', 'Jan  7 2012 should be week 1');\n    assert.equal(moment([2012, 0,  8]).format('w ww wo'), '2 02 ທີ່2', 'Jan  8 2012 should be week 2');\n    assert.equal(moment([2012, 0, 14]).format('w ww wo'), '2 02 ທີ່2', 'Jan 14 2012 should be week 2');\n    assert.equal(moment([2012, 0, 15]).format('w ww wo'), '3 03 ທີ່3', 'Jan 15 2012 should be week 3');\n});\n\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/test/locale/lt.js",
    "content": "import {localeModule, test} from '../qunit';\nimport moment from '../../moment';\nlocaleModule('lt');\n\ntest('parse', function (assert) {\n    var tests = 'sausis sau_vasaris vas_kovas kov_balandis bal_gegužė geg_birželis bir_liepa lie_rugpjūtis rgp_rugsėjis rgs_spalis spa_lapkritis lap_gruodis grd'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, Do MMMM YYYY, h:mm:ss a',      'sekmadienis, 14-oji vasario 2010, 3:25:50 pm'],\n            ['ddd, hA',                            'Sek, 3PM'],\n            ['M Mo MM MMMM MMM',                   '2 2-oji 02 vasaris vas'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14-oji 14'],\n            ['d do dddd ddd dd',                   '0 0-oji sekmadienis Sek S'],\n            ['DDD DDDo DDDD',                      '45 45-oji 045'],\n            ['w wo ww',                            '6 6-oji 06'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'pm PM'],\n            ['DDDo [metų diena]',                  '45-oji metų diena'],\n            ['LTS',                                '15:25:50'],\n            ['L',                                  '2010-02-14'],\n            ['LL',                                 '2010 m. vasario 14 d.'],\n            ['LLL',                                '2010 m. vasario 14 d., 15:25 val.'],\n            ['LLLL',                               '2010 m. vasario 14 d., sekmadienis, 15:25 val.'],\n            ['l',                                  '2010-02-14'],\n            ['ll',                                 '2010 m. vasario 14 d.'],\n            ['lll',                                '2010 m. vasario 14 d., 15:25 val.'],\n            ['llll',                               '2010 m. vasario 14 d., Sek, 15:25 val.']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1-oji', '1-oji');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2-oji', '2-oji');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3-oji', '3-oji');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4-oji', '4-oji');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5-oji', '5-oji');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6-oji', '6-oji');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7-oji', '7-oji');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8-oji', '8-oji');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9-oji', '9-oji');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10-oji', '10-oji');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11-oji', '11-oji');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12-oji', '12-oji');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13-oji', '13-oji');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14-oji', '14-oji');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15-oji', '15-oji');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16-oji', '16-oji');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17-oji', '17-oji');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18-oji', '18-oji');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19-oji', '19-oji');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20-oji', '20-oji');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21-oji', '21-oji');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22-oji', '22-oji');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23-oji', '23-oji');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24-oji', '24-oji');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25-oji', '25-oji');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26-oji', '26-oji');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27-oji', '27-oji');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28-oji', '28-oji');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29-oji', '29-oji');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30-oji', '30-oji');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31-oji', '31-oji');\n});\n\ntest('format month', function (assert) {\n    var expected = 'sausis sau_vasaris vas_kovas kov_balandis bal_gegužė geg_birželis bir_liepa lie_rugpjūtis rgp_rugsėjis rgs_spalis spa_lapkritis lap_gruodis grd'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'sekmadienis Sek S_pirmadienis Pir P_antradienis Ant A_trečiadienis Tre T_ketvirtadienis Ket K_penktadienis Pen Pn_šeštadienis Šeš Š'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('format week on US calendar', function (assert) {\n    // Tests, whether the weekday names are correct, even if the week does not start on Monday\n    moment.updateLocale('lt', {week: {dow: 0, doy: 6}});\n    var expected = 'sekmadienis Sek S_pirmadienis Pir P_antradienis Ant A_trečiadienis Tre T_ketvirtadienis Ket K_penktadienis Pen Pn_šeštadienis Šeš Š'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n    moment.updateLocale('lt', null);\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'kelios sekundės', '44 seconds = seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'minutė',          '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'minutė',          '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 minutės',       '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 10}), true),  '10 minučių',       '10 minutes = 10 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 11}), true),  '11 minučių',       '11 minutes = 11 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 19}), true),  '19 minučių',       '19 minutes = 19 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 20}), true),  '20 minučių',       '20 minutes = 20 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 minutės',      '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'valanda',         '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'valanda',         '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 valandos',      '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 valandos',      '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 10}), true),  '10 valandų',      '10 hours = 10 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 valandos',     '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'diena',           '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'diena',           '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 dienos',        '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'diena',           '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 dienos',        '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 10}), true),  '10 dienų',        '10 days = 10 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 dienos',       '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'mėnuo',           '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'mėnuo',           '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'mėnuo',           '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 mėnesiai',      '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 mėnesiai',      '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 mėnesiai',      '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'mėnuo',           '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 mėnesiai',      '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 10}), true),  '10 mėnesių',      '10 months = 10 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'metai',           '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 metai',         '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'metai',           '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 metai',         '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'po kelių sekundžių',  'prefix');\n    assert.equal(moment(0).from(30000), 'prieš kelias sekundes', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'prieš kelias sekundes',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'po kelių sekundžių', 'in seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), 'po 5 dienų', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'Šiandien 12:00',  'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'Šiandien 12:25',  'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'Šiandien 13:00',  'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'Rytoj 12:00',     'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'Šiandien 11:00',  'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'Vakar 12:00',     'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('dddd LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('[Praėjusį] dddd LT'),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[Praėjusį] dddd LT'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[Praėjusį] dddd LT'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2012, 0,  1]).format('w ww wo'), '52 52 52-oji', 'Jan  1 2012 should be week 52');\n    assert.equal(moment([2012, 0,  2]).format('w ww wo'),  '1 01 1-oji', 'Jan  2 2012 should be week 1');\n    assert.equal(moment([2012, 0,  8]).format('w ww wo'),  '1 01 1-oji', 'Jan  8 2012 should be week 1');\n    assert.equal(moment([2012, 0,  9]).format('w ww wo'),  '2 02 2-oji', 'Jan  9 2012 should be week 2');\n    assert.equal(moment([2012, 0, 15]).format('w ww wo'),  '2 02 2-oji', 'Jan 15 2012 should be week 2');\n});\n\ntest('month cases', function (assert) {\n    assert.equal(moment([2015, 4, 1]).format('LL'), '2015 m. gegužės 1 d.', 'uses format instead of standalone form');\n});\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/test/locale/lv.js",
    "content": "import {localeModule, test} from '../qunit';\nimport moment from '../../moment';\nlocaleModule('lv');\n\ntest('parse', function (assert) {\n    var tests = 'janvāris jan_februāris feb_marts mar_aprīlis apr_maijs mai_jūnijs jūn_jūlijs jūl_augusts aug_septembris sep_oktobris okt_novembris nov_decembris dec'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, Do MMMM YYYY, h:mm:ss a',      'svētdiena, 14. februāris 2010, 3:25:50 pm'],\n            ['ddd, hA',                            'Sv, 3PM'],\n            ['M Mo MM MMMM MMM',                   '2 2. 02 februāris feb'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14. 14'],\n            ['d do dddd ddd dd',                   '0 0. svētdiena Sv Sv'],\n            ['DDD DDDo DDDD',                      '45 45. 045'],\n            ['w wo ww',                            '6 6. 06'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'pm PM'],\n            ['[the] DDDo [day of the year]',       'the 45. day of the year'],\n            ['LTS',                                '15:25:50'],\n            ['L',                                  '14.02.2010.'],\n            ['LL',                                 '2010. gada 14. februāris'],\n            ['LLL',                                '2010. gada 14. februāris, 15:25'],\n            ['LLLL',                               '2010. gada 14. februāris, svētdiena, 15:25'],\n            ['l',                                  '14.2.2010.'],\n            ['ll',                                 '2010. gada 14. feb'],\n            ['lll',                                '2010. gada 14. feb, 15:25'],\n            ['llll',                               '2010. gada 14. feb, Sv, 15:25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1.', '1.');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2.', '2.');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3.', '3.');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4.', '4.');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5.', '5.');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6.', '6.');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7.', '7.');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8.', '8.');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9.', '9.');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10.', '10.');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11.', '11.');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12.', '12.');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13.', '13.');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14.', '14.');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15.', '15.');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16.', '16.');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17.', '17.');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18.', '18.');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19.', '19.');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20.', '20.');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21.', '21.');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22.', '22.');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23.', '23.');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24.', '24.');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25.', '25.');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26.', '26.');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27.', '27.');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28.', '28.');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29.', '29.');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30.', '30.');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31.', '31.');\n});\n\ntest('format month', function (assert) {\n    var expected = 'janvāris jan_februāris feb_marts mar_aprīlis apr_maijs mai_jūnijs jūn_jūlijs jūl_augusts aug_septembris sep_oktobris okt_novembris nov_decembris dec'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'svētdiena Sv Sv_pirmdiena P P_otrdiena O O_trešdiena T T_ceturtdiena C C_piektdiena Pk Pk_sestdiena S S'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\n// Includes testing the cases of withoutSuffix = true and false.\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),   'dažas sekundes',       '44 seconds = seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), false),  'pirms dažām sekundēm', '44 seconds with suffix = seconds ago');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),   'minūte',               '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), false),  'pirms minūtes',        '45 seconds with suffix = a minute ago');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),   'minūte',               '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: -89}), false), 'pēc minūtes',          '89 seconds with suffix/prefix = in a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),   '2 minūtes',            '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), false),  'pirms 2 minūtēm',      '90 seconds with suffix = 2 minutes ago');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),   '44 minūtes',           '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), false),  'pirms 44 minūtēm',     '44 minutes with suffix = 44 minutes ago');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),   'stunda',               '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), false),  'pirms stundas',        '45 minutes with suffix = an hour ago');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),   'stunda',               '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),   '2 stundas',            '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: -90}), false), 'pēc 2 stundām',        '90 minutes with suffix = in 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),    '5 stundas',            '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), false),   'pirms 5 stundām',      '5 hours with suffix = 5 hours ago');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),   '21 stunda',            '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), false),  'pirms 21 stundas',     '21 hours with suffix = 21 hours ago');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),   'diena',                '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), false),  'pirms dienas',         '22 hours with suffix = a day ago');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),   'diena',                '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),   '2 dienas',             '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), false),  'pirms 2 dienām',       '36 hours with suffix = 2 days ago');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),    'diena',                '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),    '5 dienas',             '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), false),   'pirms 5 dienām',       '5 days with suffix = 5 days ago');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),   '25 dienas',            '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), false),  'pirms 25 dienām',      '25 days with suffix = 25 days ago');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),   'mēnesis',              '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), false),  'pirms mēneša',         '26 days with suffix = a month ago');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),   'mēnesis',              '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),   'mēnesis',              '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),   '2 mēneši',             '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), false),  'pirms 2 mēnešiem',     '46 days with suffix = 2 months ago');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),   '2 mēneši',             '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),   '3 mēneši',             '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), false),  'pirms 3 mēnešiem',     '76 days with suffix = 3 months ago');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),    'mēnesis',              '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),    '5 mēneši',             '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), false),   'pirms 5 mēnešiem',     '5 months with suffix = 5 months ago');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true),  'gads',                 '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), false), 'pirms gada',           '345 days with suffix = a year ago');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true),  '2 gadi',               '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), false), 'pirms 2 gadiem',       '548 days with suffix = 2 years ago');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),    'gads',                 '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),    '5 gadi',               '5 years = 5 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), false),   'pirms 5 gadiem',       '5 years with suffix = 5 years ago');\n\n    // test that numbers ending with 1 are singular except for when they end with 11 in which case they are plural\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 11}), true),   '11 gadi',              '11 years = 11 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 21}), true),   '21 gads',              '21 year = 21 year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 211}), true),  '211 gadi',             '211 years = 211 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 221}), false), 'pirms 221 gada',       '221 year with suffix = 221 years ago');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'pēc dažām sekundēm',  'prefix');\n    assert.equal(moment(0).from(30000), 'pirms dažām sekundēm', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'pirms dažām sekundēm',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'pēc dažām sekundēm', 'in seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), 'pēc 5 dienām', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'Šodien pulksten 12:00',  'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'Šodien pulksten 12:25',  'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'Šodien pulksten 13:00',  'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'Rīt pulksten 12:00',     'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'Šodien pulksten 11:00',  'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'Vakar pulksten 12:00',   'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('dddd [pulksten] LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd [pulksten] LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd [pulksten] LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('[Pagājušā] dddd [pulksten] LT'),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[Pagājušā] dddd [pulksten] LT'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[Pagājušā] dddd [pulksten] LT'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2012, 0,  1]).format('w ww wo'), '52 52 52.', 'Jan  1 2012 should be week 52');\n    assert.equal(moment([2012, 0,  2]).format('w ww wo'),  '1 01 1.', 'Jan  2 2012 should be week 1');\n    assert.equal(moment([2012, 0,  8]).format('w ww wo'),  '1 01 1.', 'Jan  8 2012 should be week 1');\n    assert.equal(moment([2012, 0,  9]).format('w ww wo'),  '2 02 2.', 'Jan  9 2012 should be week 2');\n    assert.equal(moment([2012, 0, 15]).format('w ww wo'),  '2 02 2.', 'Jan 15 2012 should be week 2');\n});\n\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/test/locale/me.js",
    "content": "import {localeModule, test} from '../qunit';\nimport moment from '../../moment';\nlocaleModule('me');\n\ntest('parse', function (assert) {\n    var tests = 'januar jan._februar feb._mart mar._april apr._maj maj_jun jun_jul jul_avgust avg._septembar sep._oktobar okt._novembar nov._decembar dec.'.split('_'),\n        i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, Do MMMM YYYY, h:mm:ss a',      'nedjelja, 14. februar 2010, 3:25:50 pm'],\n            ['ddd, hA',                            'ned., 3PM'],\n            ['M Mo MM MMMM MMM',                   '2 2. 02 februar feb.'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14. 14'],\n            ['d do dddd ddd dd',                   '0 0. nedjelja ned. ne'],\n            ['DDD DDDo DDDD',                      '45 45. 045'],\n            ['w wo ww',                            '7 7. 07'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'pm PM'],\n            ['[the] DDDo [day of the year]',       'the 45. day of the year'],\n            ['LTS',                                '15:25:50'],\n            ['L',                                  '14.02.2010'],\n            ['LL',                                 '14. februar 2010'],\n            ['LLL',                                '14. februar 2010 15:25'],\n            ['LLLL',                               'nedjelja, 14. februar 2010 15:25'],\n            ['l',                                  '14.2.2010'],\n            ['ll',                                 '14. feb. 2010'],\n            ['lll',                                '14. feb. 2010 15:25'],\n            ['llll',                               'ned., 14. feb. 2010 15:25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1.', '1.');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2.', '2.');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3.', '3.');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4.', '4.');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5.', '5.');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6.', '6.');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7.', '7.');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8.', '8.');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9.', '9.');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10.', '10.');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11.', '11.');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12.', '12.');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13.', '13.');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14.', '14.');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15.', '15.');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16.', '16.');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17.', '17.');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18.', '18.');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19.', '19.');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20.', '20.');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21.', '21.');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22.', '22.');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23.', '23.');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24.', '24.');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25.', '25.');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26.', '26.');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27.', '27.');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28.', '28.');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29.', '29.');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30.', '30.');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31.', '31.');\n});\n\ntest('format month', function (assert) {\n    var expected = 'januar jan._februar feb._mart mar._april apr._maj maj_jun jun_jul jul_avgust avg._septembar sep._oktobar okt._novembar nov._decembar dec.'.split('_'),\n        i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'nedjelja ned. ne_ponedjeljak pon. po_utorak uto. ut_srijeda sri. sr_četvrtak čet. če_petak pet. pe_subota sub. su'.split('_'),\n        i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'nekoliko sekundi', '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'jedan minut',   '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'jedan minut',   '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 minuta',     '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 minuta',     '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'jedan sat',      '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'jedan sat',      '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 sata',        '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 sati',         '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 sati',        '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'dan',       '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'dan',       '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 dana',        '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'dan',       '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 dana',        '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 dana',       '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'mjesec',     '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'mjesec',     '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'mjesec',     '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 mjeseca',     '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 mjeseca',     '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 mjeseca',     '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'mjesec',     '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 mjeseci',    '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'godinu',     '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 godine',       '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'godinu',     '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 godina',        '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'za nekoliko sekundi',  'prefix');\n    assert.equal(moment(0).from(30000), 'prije nekoliko sekundi', 'prefix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'prije nekoliko sekundi',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'za nekoliko sekundi', 'in a few seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), 'za 5 dana', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'danas u 12:00',  'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'danas u 12:25',  'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'danas u 13:00',  'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'sjutra u 12:00', 'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'danas u 11:00',  'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'juče u 12:00',   'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n\n    function makeFormat(d) {\n        switch (d.day()) {\n            case 0:\n                return '[u] [nedjelju] [u] LT';\n            case 3:\n                return '[u] [srijedu] [u] LT';\n            case 6:\n                return '[u] [subotu] [u] LT';\n            case 1:\n            case 2:\n            case 4:\n            case 5:\n                return '[u] dddd [u] LT';\n        }\n    }\n\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format(makeFormat(m)),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format(makeFormat(m)),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format(makeFormat(m)),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n\n    function makeFormat(d) {\n        var lastWeekDay = [\n                '[prošle] [nedjelje] [u] LT',\n                '[prošlog] [ponedjeljka] [u] LT',\n                '[prošlog] [utorka] [u] LT',\n                '[prošle] [srijede] [u] LT',\n                '[prošlog] [četvrtka] [u] LT',\n                '[prošlog] [petka] [u] LT',\n                '[prošle] [subote] [u] LT'\n            ];\n\n        return lastWeekDay[d.day()];\n    }\n\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format(makeFormat(m)),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format(makeFormat(m)),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format(makeFormat(m)),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\n// Monday is the first day of the week.\n// The week that contains Jan 1st is the first week of the year.\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2011, 11, 26]).format('w ww wo'), '1 01 1.', 'Dec 26 2011 should be week 1');\n    assert.equal(moment([2012,  0,  1]).format('w ww wo'), '1 01 1.', 'Jan  1 2012 should be week 1');\n    assert.equal(moment([2012,  0,  2]).format('w ww wo'), '2 02 2.', 'Jan  2 2012 should be week 2');\n    assert.equal(moment([2012,  0,  8]).format('w ww wo'), '2 02 2.', 'Jan  8 2012 should be week 2');\n    assert.equal(moment([2012,  0,  9]).format('w ww wo'), '3 03 3.', 'Jan  9 2012 should be week 3');\n});\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/test/locale/mi.js",
    "content": "import {localeModule, test} from '../qunit';\nimport moment from '../../moment';\nlocaleModule('mi');\n\ntest('parse', function (assert) {\n    var tests = 'Kohi-tāte Kohi_Hui-tanguru Hui_Poutū-te-rangi Pou_Paenga-whāwhā Pae_Haratua Hara_Pipiri Pipi_Hōngoingoi Hōngoi_Here-turi-kōkā Here_Mahuru Mahu_Whiringa-ā-nuku Whi-nu_Whiringa-ā-rangi Whi-ra_Hakihea Haki'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, MMMM Do YYYY, h:mm:ss a',      'Rātapu, Hui-tanguru 14º 2010, 3:25:50 pm'],\n            ['ddd, hA',                            'Ta, 3PM'],\n            ['M Mo MM MMMM MMM',                   '2 2º 02 Hui-tanguru Hui'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14º 14'],\n            ['d do dddd ddd dd',                   '0 0º Rātapu Ta Ta'],\n            ['DDD DDDo DDDD',                      '45 45º 045'],\n            ['w wo ww',                            '6 6º 06'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'pm PM'],\n            ['[the] DDDo [day of the year]',       'the 45º day of the year'],\n            ['LTS',                                '15:25:50'],\n            ['L',                                  '14/02/2010'],\n            ['LL',                                 '14 Hui-tanguru 2010'],\n            ['LLL',                                '14 Hui-tanguru 2010 i 15:25'],\n            ['LLLL',                               'Rātapu, 14 Hui-tanguru 2010 i 15:25'],\n            ['l',                                  '14/2/2010'],\n            ['ll',                                 '14 Hui 2010'],\n            ['lll',                                '14 Hui 2010 i 15:25'],\n            ['llll',                               'Ta, 14 Hui 2010 i 15:25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1º', '1º');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2º', '2º');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3º', '3º');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4º', '4º');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5º', '5º');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6º', '6º');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7º', '7º');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8º', '8º');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9º', '9º');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10º', '10º');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11º', '11º');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12º', '12º');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13º', '13º');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14º', '14º');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15º', '15º');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16º', '16º');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17º', '17º');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18º', '18º');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19º', '19º');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20º', '20º');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21º', '21º');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22º', '22º');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23º', '23º');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24º', '24º');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25º', '25º');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26º', '26º');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27º', '27º');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28º', '28º');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29º', '29º');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30º', '30º');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31º', '31º');\n});\n\ntest('format month', function (assert) {\n    var expected = 'Kohi-tāte Kohi_Hui-tanguru Hui_Poutū-te-rangi Pou_Paenga-whāwhā Pae_Haratua Hara_Pipiri Pipi_Hōngoingoi Hōngoi_Here-turi-kōkā Here_Mahuru Mahu_Whiringa-ā-nuku Whi-nu_Whiringa-ā-rangi Whi-ra_Hakihea Haki'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'Rātapu Ta Ta_Mane Ma Ma_Tūrei Tū Tū_Wenerei We We_Tāite Tāi Tāi_Paraire Pa Pa_Hātarei Hā Hā'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'te hēkona ruarua', '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'he meneti',        '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'he meneti',        '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 meneti',         '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 meneti',        '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'te haora',         '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'te haora',         '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 haora',          '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 haora',          '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 haora',         '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'he ra',            '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'he ra',            '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 ra',             '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'he ra',            '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 ra',             '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 ra',            '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'he marama',        '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'he marama',        '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'he marama',        '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 marama',         '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 marama',         '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 marama',         '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'he marama',         '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 marama',         '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'he tau',           '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 tau',            '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'he tau',           '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 tau',            '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'i roto i te hēkona ruarua',  'prefix');\n    assert.equal(moment(0).from(30000), 'te hēkona ruarua i mua', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'te hēkona ruarua i mua',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'i roto i te hēkona ruarua', 'in a few seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), 'i roto i 5 ra', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'i teie mahana, i 12:00', 'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'i teie mahana, i 12:25', 'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'i teie mahana, i 13:00', 'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'apopo i 12:00',       'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'i teie mahana, i 11:00', 'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'inanahi i 12:00',     'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('dddd [i] LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd [i] LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd [i] LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('dddd [whakamutunga i] LT'), 'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd [whakamutunga i] LT'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd [whakamutunga i] LT'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2012, 0,  1]).format('w ww wo'), '52 52 52º', 'Jan  1 2012 should be week 52');\n    assert.equal(moment([2012, 0,  2]).format('w ww wo'),   '1 01 1º', 'Jan  2 2012 should be week 1');\n    assert.equal(moment([2012, 0,  8]).format('w ww wo'),   '1 01 1º', 'Jan  8 2012 should be week 1');\n    assert.equal(moment([2012, 0,  9]).format('w ww wo'),   '2 02 2º', 'Jan  9 2012 should be week 2');\n    assert.equal(moment([2012, 0, 15]).format('w ww wo'),   '2 02 2º', 'Jan 15 2012 should be week 2');\n});\n\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/test/locale/mk.js",
    "content": "import {localeModule, test} from '../qunit';\nimport moment from '../../moment';\nlocaleModule('mk');\n\ntest('parse', function (assert) {\n    var tests = 'јануари јан_февруари фев_март мар_април апр_мај мај_јуни јун_јули јул_август авг_септември сеп_октомври окт_ноември ное_декември дек'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, MMMM Do YYYY, H:mm:ss',        'недела, февруари 14-ти 2010, 15:25:50'],\n            ['ddd, hA',                            'нед, 3PM'],\n            ['M Mo MM MMMM MMM',                   '2 2-ри 02 февруари фев'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14-ти 14'],\n            ['d do dddd ddd dd',                   '0 0-ев недела нед нe'],\n            ['DDD DDDo DDDD',                      '45 45-ти 045'],\n            ['w wo ww',                            '7 7-ми 07'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'pm PM'],\n            ['[the] DDDo [day of the year]',       'the 45-ти day of the year'],\n            ['LTS',                                '15:25:50'],\n            ['L',                                  '14.02.2010'],\n            ['LL',                                 '14 февруари 2010'],\n            ['LLL',                                '14 февруари 2010 15:25'],\n            ['LLLL',                               'недела, 14 февруари 2010 15:25'],\n            ['l',                                  '14.2.2010'],\n            ['ll',                                 '14 фев 2010'],\n            ['lll',                                '14 фев 2010 15:25'],\n            ['llll',                               'нед, 14 фев 2010 15:25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1-ви', '1-ви');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2-ри', '2-ри');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3-ти', '3-ти');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4-ти', '4-ти');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5-ти', '5-ти');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6-ти', '6-ти');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7-ми', '7-ми');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8-ми', '8-ми');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9-ти', '9-ти');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10-ти', '10-ти');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11-ти', '11-ти');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12-ти', '12-ти');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13-ти', '13-ти');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14-ти', '14-ти');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15-ти', '15-ти');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16-ти', '16-ти');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17-ти', '17-ти');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18-ти', '18-ти');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19-ти', '19-ти');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20-ти', '20-ти');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21-ви', '21-ви');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22-ри', '22-ри');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23-ти', '23-ти');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24-ти', '24-ти');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25-ти', '25-ти');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26-ти', '26-ти');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27-ми', '27-ми');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28-ми', '28-ми');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29-ти', '29-ти');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30-ти', '30-ти');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31-ви', '31-ви');\n});\n\ntest('format month', function (assert) {\n    var expected = 'јануари јан_февруари фев_март мар_април апр_мај мај_јуни јун_јули јул_август авг_септември сеп_октомври окт_ноември ное_декември дек'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'недела нед нe_понеделник пон пo_вторник вто вт_среда сре ср_четврток чет че_петок пет пе_сабота саб сa'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'неколку секунди', '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'минута',          '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'минута',          '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 минути',        '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 минути',       '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'час',             '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'час',             '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 часа',          '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 часа',          '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 часа',         '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'ден',             '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'ден',             '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 дена',          '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'ден',             '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 дена',          '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 дена',         '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'месец',           '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'месец',           '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'месец',           '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 месеци',        '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 месеци',        '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 месеци',        '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'месец',           '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 месеци',        '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'година',          '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 години',        '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'година',          '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 години',        '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'после неколку секунди', 'prefix');\n    assert.equal(moment(0).from(30000), 'пред неколку секунди',  'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'пред неколку секунди',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'после неколку секунди', 'in a few seconds');\n    assert.equal(moment().add({d: 5}).fromNow(),  'после 5 дена', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'Денес во 12:00',  'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'Денес во 12:25',  'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'Денес во 13:00',  'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'Утре во 12:00',   'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'Денес во 11:00',  'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'Вчера во 12:00',  'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('[Во] dddd [во] LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[Во] dddd [во] LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[Во] dddd [во] LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n\n    function makeFormat(d) {\n        switch (d.day()) {\n            case 0:\n            case 3:\n            case 6:\n                return '[Изминатата] dddd [во] LT';\n            case 1:\n            case 2:\n            case 4:\n            case 5:\n                return '[Изминатиот] dddd [во] LT';\n        }\n    }\n\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format(makeFormat(m)),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format(makeFormat(m)),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format(makeFormat(m)),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2011, 11, 26]).format('w ww wo'), '1 01 1-ви', 'Dec 26 2011 should be week 1');\n    assert.equal(moment([2012,  0,  1]).format('w ww wo'), '1 01 1-ви', 'Jan  1 2012 should be week 1');\n    assert.equal(moment([2012,  0,  2]).format('w ww wo'), '2 02 2-ри', 'Jan  2 2012 should be week 2');\n    assert.equal(moment([2012,  0,  8]).format('w ww wo'), '2 02 2-ри', 'Jan  8 2012 should be week 2');\n    assert.equal(moment([2012,  0,  9]).format('w ww wo'), '3 03 3-ти', 'Jan  9 2012 should be week 3');\n});\n\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/test/locale/ml.js",
    "content": "import {localeModule, test} from '../qunit';\nimport moment from '../../moment';\nlocaleModule('ml');\n\ntest('parse', function (assert) {\n    var tests = 'ജനുവരി ജനു._ഫെബ്രുവരി ഫെബ്രു._മാർച്ച് മാർ._ഏപ്രിൽ ഏപ്രി._മേയ് മേയ്_ജൂൺ ജൂൺ_ജൂലൈ ജൂലൈ._ഓഗസ്റ്റ് ഓഗ._സെപ്റ്റംബർ സെപ്റ്റ._ഒക്ടോബർ ഒക്ടോ._നവംബർ നവം._ഡിസംബർ ഡിസം.'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, Do MMMM YYYY, a h:mm:ss -നു',  'ഞായറാഴ്ച, 14 ഫെബ്രുവരി 2010, ഉച്ച കഴിഞ്ഞ് 3:25:50 -നു'],\n            ['ddd, a h -നു',                       'ഞായർ, ഉച്ച കഴിഞ്ഞ് 3 -നു'],\n            ['M Mo MM MMMM MMM',                   '2 2 02 ഫെബ്രുവരി ഫെബ്രു.'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14 14'],\n            ['d do dddd ddd dd',                   '0 0 ഞായറാഴ്ച ഞായർ ഞാ'],\n            ['DDD DDDo DDDD',                      '45 45 045'],\n            ['w wo ww',                            '8 8 08'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'ഉച്ച കഴിഞ്ഞ് ഉച്ച കഴിഞ്ഞ്'],\n            ['LTS',                                'ഉച്ച കഴിഞ്ഞ് 3:25:50 -നു'],\n            ['L',                                  '14/02/2010'],\n            ['LL',                                 '14 ഫെബ്രുവരി 2010'],\n            ['LLL',                                '14 ഫെബ്രുവരി 2010, ഉച്ച കഴിഞ്ഞ് 3:25 -നു'],\n            ['LLLL',                               'ഞായറാഴ്ച, 14 ഫെബ്രുവരി 2010, ഉച്ച കഴിഞ്ഞ് 3:25 -നു'],\n            ['l',                                  '14/2/2010'],\n            ['ll',                                 '14 ഫെബ്രു. 2010'],\n            ['lll',                                '14 ഫെബ്രു. 2010, ഉച്ച കഴിഞ്ഞ് 3:25 -നു'],\n            ['llll',                               'ഞായർ, 14 ഫെബ്രു. 2010, ഉച്ച കഴിഞ്ഞ് 3:25 -നു']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1', '1');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2', '2');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3', '3');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4', '4');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5', '5');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6', '6');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7', '7');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8', '8');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9', '9');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10', '10');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11', '11');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12', '12');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13', '13');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14', '14');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15', '15');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16', '16');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17', '17');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18', '18');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19', '19');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20', '20');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21', '21');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22', '22');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23', '23');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24', '24');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25', '25');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26', '26');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27', '27');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28', '28');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29', '29');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30', '30');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31', '31');\n});\n\ntest('format month', function (assert) {\n    var expected = 'ജനുവരി ജനു._ഫെബ്രുവരി ഫെബ്രു._മാർച്ച് മാർ._ഏപ്രിൽ ഏപ്രി._മേയ് മേയ്_ജൂൺ ജൂൺ_ജൂലൈ ജൂലൈ._ഓഗസ്റ്റ് ഓഗ._സെപ്റ്റംബർ സെപ്റ്റ._ഒക്ടോബർ ഒക്ടോ._നവംബർ നവം._ഡിസംബർ ഡിസം.'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'ഞായറാഴ്ച ഞായർ ഞാ_തിങ്കളാഴ്ച തിങ്കൾ തി_ചൊവ്വാഴ്ച ചൊവ്വ ചൊ_ബുധനാഴ്ച ബുധൻ ബു_വ്യാഴാഴ്ച വ്യാഴം വ്യാ_വെള്ളിയാഴ്ച വെള്ളി വെ_ശനിയാഴ്ച ശനി ശ'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'അൽപ നിമിഷങ്ങൾ', '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'ഒരു മിനിറ്റ്',      '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'ഒരു മിനിറ്റ്',      '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 മിനിറ്റ്',     '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 മിനിറ്റ്',    '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'ഒരു മണിക്കൂർ',       '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'ഒരു മണിക്കൂർ',       '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 മണിക്കൂർ',       '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 മണിക്കൂർ',       '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 മണിക്കൂർ',      '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'ഒരു ദിവസം',         '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'ഒരു ദിവസം',         '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 ദിവസം',        '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'ഒരു ദിവസം',         '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 ദിവസം',        '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 ദിവസം',       '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'ഒരു മാസം',       '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'ഒരു മാസം',       '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'ഒരു മാസം',       '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 മാസം',      '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 മാസം',      '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 മാസം',      '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'ഒരു മാസം',       '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 മാസം',      '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'ഒരു വർഷം',        '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 വർഷം',       '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'ഒരു വർഷം',        '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 വർഷം',       '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'അൽപ നിമിഷങ്ങൾ കഴിഞ്ഞ്',  'prefix');\n    assert.equal(moment(0).from(30000), 'അൽപ നിമിഷങ്ങൾ മുൻപ്', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'അൽപ നിമിഷങ്ങൾ മുൻപ്',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'അൽപ നിമിഷങ്ങൾ കഴിഞ്ഞ്', 'അൽപ നിമിഷങ്ങൾ കഴിഞ്ഞ്');\n    assert.equal(moment().add({d: 5}).fromNow(), '5 ദിവസം കഴിഞ്ഞ്', '5 ദിവസം കഴിഞ്ഞ്');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'ഇന്ന് ഉച്ച കഴിഞ്ഞ് 12:00 -നു',   'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'ഇന്ന് ഉച്ച കഴിഞ്ഞ് 12:25 -നു',   'Now plus 25 min');\n    assert.equal(moment(a).add({h: 3}).calendar(),       'ഇന്ന് ഉച്ച കഴിഞ്ഞ് 3:00 -നു',    'Now plus 3 hours');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'നാളെ ഉച്ച കഴിഞ്ഞ് 12:00 -നു',    'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'ഇന്ന് രാവിലെ 11:00 -നു',         'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'ഇന്നലെ ഉച്ച കഴിഞ്ഞ് 12:00 -നു',  'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('dddd[,] LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd[,] LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd[,] LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('[കഴിഞ്ഞ] dddd[,] LT'),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[കഴിഞ്ഞ] dddd[,] LT'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[കഴിഞ്ഞ] dddd[,] LT'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('meridiem', function (assert) {\n    assert.equal(moment([2011, 2, 23,  2, 30]).format('a'), 'രാത്രി', 'before dawn');\n    assert.equal(moment([2011, 2, 23,  9, 30]).format('a'), 'രാവിലെ', 'morning');\n    assert.equal(moment([2011, 2, 23, 14, 30]).format('a'), 'ഉച്ച കഴിഞ്ഞ്', 'during day');\n    assert.equal(moment([2011, 2, 23, 17, 30]).format('a'), 'വൈകുന്നേരം', 'evening');\n    assert.equal(moment([2011, 2, 23, 19, 30]).format('a'), 'വൈകുന്നേരം', 'late evening');\n    assert.equal(moment([2011, 2, 23, 21, 20]).format('a'), 'രാത്രി', 'night');\n\n    assert.equal(moment([2011, 2, 23,  2, 30]).format('A'), 'രാത്രി', 'before dawn');\n    assert.equal(moment([2011, 2, 23,  9, 30]).format('A'), 'രാവിലെ', 'morning');\n    assert.equal(moment([2011, 2, 23, 14, 30]).format('A'), 'ഉച്ച കഴിഞ്ഞ്', ' during day');\n    assert.equal(moment([2011, 2, 23, 17, 30]).format('A'), 'വൈകുന്നേരം', 'evening');\n    assert.equal(moment([2011, 2, 23, 19, 30]).format('A'), 'വൈകുന്നേരം', 'late evening');\n    assert.equal(moment([2011, 2, 23, 21, 20]).format('A'), 'രാത്രി', 'night');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2012, 0,  1]).format('w ww wo'), '1 01 1', 'Jan  1 2012 should be week 1');\n    assert.equal(moment([2012, 0,  7]).format('w ww wo'), '1 01 1', 'Jan  7 2012 should be week 1');\n    assert.equal(moment([2012, 0,  8]).format('w ww wo'), '2 02 2', 'Jan  8 2012 should be week 2');\n    assert.equal(moment([2012, 0, 14]).format('w ww wo'), '2 02 2', 'Jan 14 2012 should be week 2');\n    assert.equal(moment([2012, 0, 15]).format('w ww wo'), '3 03 3', 'Jan 15 2012 should be week 3');\n});\n\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/test/locale/mr.js",
    "content": "import {localeModule, test} from '../qunit';\nimport moment from '../../moment';\nlocaleModule('mr');\n\ntest('parse', function (assert) {\n    var tests = 'जानेवारी जाने._फेब्रुवारी फेब्रु._मार्च मार्च._एप्रिल एप्रि._मे मे._जून जून._जुलै जुलै._ऑगस्ट ऑग._सप्टेंबर सप्टें._ऑक्टोबर ऑक्टो._नोव्हेंबर नोव्हें._डिसेंबर डिसें.'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, Do MMMM YYYY, a h:mm:ss वाजता', 'रविवार, १४ फेब्रुवारी २०१०, दुपारी ३:२५:५० वाजता'],\n            ['ddd, a h वाजता',                       'रवि, दुपारी ३ वाजता'],\n            ['M Mo MM MMMM MMM',                   '२ २ ०२ फेब्रुवारी फेब्रु.'],\n            ['YYYY YY',                            '२०१० १०'],\n            ['D Do DD',                            '१४ १४ १४'],\n            ['d do dddd ddd dd',                   '० ० रविवार रवि र'],\n            ['DDD DDDo DDDD',                      '४५ ४५ ०४५'],\n            ['w wo ww',                            '८ ८ ०८'],\n            ['h hh',                               '३ ०३'],\n            ['H HH',                               '१५ १५'],\n            ['m mm',                               '२५ २५'],\n            ['s ss',                               '५० ५०'],\n            ['a A',                                'दुपारी दुपारी'],\n            ['LTS',                                'दुपारी ३:२५:५० वाजता'],\n            ['L',                                  '१४/०२/२०१०'],\n            ['LL',                                 '१४ फेब्रुवारी २०१०'],\n            ['LLL',                                '१४ फेब्रुवारी २०१०, दुपारी ३:२५ वाजता'],\n            ['LLLL',                               'रविवार, १४ फेब्रुवारी २०१०, दुपारी ३:२५ वाजता'],\n            ['l',                                  '१४/२/२०१०'],\n            ['ll',                                 '१४ फेब्रु. २०१०'],\n            ['lll',                                '१४ फेब्रु. २०१०, दुपारी ३:२५ वाजता'],\n            ['llll',                               'रवि, १४ फेब्रु. २०१०, दुपारी ३:२५ वाजता']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '१', '१');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '२', '२');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '३', '३');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '४', '४');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '५', '५');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '६', '६');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '७', '७');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '८', '८');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '९', '९');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '१०', '१०');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '११', '११');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '१२', '१२');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '१३', '१३');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '१४', '१४');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '१५', '१५');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '१६', '१६');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '१७', '१७');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '१८', '१८');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '१९', '१९');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '२०', '२०');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '२१', '२१');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '२२', '२२');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '२३', '२३');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '२४', '२४');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '२५', '२५');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '२६', '२६');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '२७', '२७');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '२८', '२८');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '२९', '२९');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '३०', '३०');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '३१', '३१');\n});\n\ntest('format month', function (assert) {\n    var expected = 'जानेवारी जाने._फेब्रुवारी फेब्रु._मार्च मार्च._एप्रिल एप्रि._मे मे._जून जून._जुलै जुलै._ऑगस्ट ऑग._सप्टेंबर सप्टें._ऑक्टोबर ऑक्टो._नोव्हेंबर नोव्हें._डिसेंबर डिसें.'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'रविवार रवि र_सोमवार सोम सो_मंगळवार मंगळ मं_बुधवार बुध बु_गुरूवार गुरू गु_शुक्रवार शुक्र शु_शनिवार शनि श'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'काही सेकंद', '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'एक मिनिट',      '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'एक मिनिट',      '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '२ मिनिटे',     '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true), '४४ मिनिटे', '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'एक तास',       '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'एक तास',       '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '२ तास',       '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '५ तास',       '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '२१ तास',      '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'एक दिवस',         '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'एक दिवस',         '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '२ दिवस',        '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'एक दिवस',         '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '५ दिवस',        '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '२५ दिवस',       '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true), 'एक महिना', '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true), 'एक महिना', '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true), 'एक महिना', '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true), '२ महिने', '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true), '२ महिने', '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true), '३ महिने', '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true), 'एक महिना', '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true), '५ महिने', '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'एक वर्ष',        '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '२ वर्षे',       '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'एक वर्ष',        '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true), '५ वर्षे', '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'काही सेकंदांमध्ये', 'prefix');\n    assert.equal(moment(0).from(30000), 'काही सेकंदांपूर्वी', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'काही सेकंदांपूर्वी',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'काही सेकंदांमध्ये', 'in a few seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), '५ दिवसांमध्ये', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'आज दुपारी १२:०० वाजता',    'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'आज दुपारी १२:२५ वाजता',    'Now plus 25 min');\n    assert.equal(moment(a).add({h: 3}).calendar(),       'आज दुपारी ३:०० वाजता',     'Now plus 3 hours');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'उद्या दुपारी १२:०० वाजता', 'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'आज दुपारी ११:०० वाजता',    'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'काल दुपारी १२:०० वाजता',   'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('dddd[,] LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd[,] LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd[,] LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(), m.format('[मागील] dddd[,] LT'), 'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(), m.format('[मागील] dddd[,] LT'), 'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(), m.format('[मागील] dddd[,] LT'), 'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('meridiem', function (assert) {\n    assert.equal(moment([2011, 2, 23,  2, 30]).format('a'), 'रात्री', 'before dawn');\n    assert.equal(moment([2011, 2, 23,  9, 30]).format('a'), 'सकाळी', 'morning');\n    assert.equal(moment([2011, 2, 23, 14, 30]).format('a'), 'दुपारी', 'during day');\n    assert.equal(moment([2011, 2, 23, 17, 30]).format('a'), 'सायंकाळी', 'evening');\n    assert.equal(moment([2011, 2, 23, 19, 30]).format('a'), 'सायंकाळी', 'late evening');\n    assert.equal(moment([2011, 2, 23, 21, 20]).format('a'), 'रात्री', 'night');\n\n    assert.equal(moment([2011, 2, 23,  2, 30]).format('A'), 'रात्री', 'before dawn');\n    assert.equal(moment([2011, 2, 23,  9, 30]).format('A'), 'सकाळी', 'morning');\n    assert.equal(moment([2011, 2, 23, 14, 30]).format('A'), 'दुपारी', ' during day');\n    assert.equal(moment([2011, 2, 23, 17, 30]).format('A'), 'सायंकाळी', 'evening');\n    assert.equal(moment([2011, 2, 23, 19, 30]).format('A'), 'सायंकाळी', 'late evening');\n    assert.equal(moment([2011, 2, 23, 21, 20]).format('A'), 'रात्री', 'night');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2012, 0,  1]).format('w ww wo'), '१ ०१ १', 'Jan  1 2012 should be week 1');\n    assert.equal(moment([2012, 0,  7]).format('w ww wo'), '१ ०१ १', 'Jan  7 2012 should be week 1');\n    assert.equal(moment([2012, 0,  8]).format('w ww wo'), '२ ०२ २', 'Jan  8 2012 should be week 2');\n    assert.equal(moment([2012, 0, 14]).format('w ww wo'), '२ ०२ २', 'Jan 14 2012 should be week 2');\n    assert.equal(moment([2012, 0, 15]).format('w ww wo'), '३ ०३ ३', 'Jan 15 2012 should be week 3');\n});\n\n\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/test/locale/ms-my.js",
    "content": "import {localeModule, test} from '../qunit';\nimport moment from '../../moment';\nlocaleModule('ms-my');\n\ntest('parse', function (assert) {\n    var i,\n        tests = 'Januari Jan_Februari Feb_Mac Mac_April Apr_Mei Mei_Jun Jun_Julai Jul_Ogos Ogs_September Sep_Oktober Okt_November Nov_Disember Dis'.split('_');\n\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' sepatutnya bulan ' + (i + 1));\n    }\n\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, MMMM Do YYYY, h:mm:ss a',      'Ahad, Februari 14 2010, 3:25:50 petang'],\n            ['ddd, hA',                            'Ahd, 3petang'],\n            ['M Mo MM MMMM MMM',                   '2 2 02 Februari Feb'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14 14'],\n            ['d do dddd ddd dd',                   '0 0 Ahad Ahd Ah'],\n            ['DDD DDDo DDDD',                      '45 45 045'],\n            ['w wo ww',                            '7 7 07'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'petang petang'],\n            ['[hari] [ke] DDDo [tahun] ini', 'hari ke 45 tahun ini'],\n            ['LTS',                                '15.25.50'],\n            ['L',                                  '14/02/2010'],\n            ['LL',                                 '14 Februari 2010'],\n            ['LLL',                                '14 Februari 2010 pukul 15.25'],\n            ['LLLL',                               'Ahad, 14 Februari 2010 pukul 15.25'],\n            ['l',                                  '14/2/2010'],\n            ['ll',                                 '14 Feb 2010'],\n            ['lll',                                '14 Feb 2010 pukul 15.25'],\n            ['llll',                               'Ahd, 14 Feb 2010 pukul 15.25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1', '1');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2', '2');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3', '3');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4', '4');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5', '5');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6', '6');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7', '7');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8', '8');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9', '9');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10', '10');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11', '11');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12', '12');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13', '13');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14', '14');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15', '15');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16', '16');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17', '17');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18', '18');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19', '19');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20', '20');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21', '21');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22', '22');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23', '23');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24', '24');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25', '25');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26', '26');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27', '27');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28', '28');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29', '29');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30', '30');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31', '31');\n});\n\ntest('format month', function (assert) {\n    var i,\n        expected = 'Januari Jan_Februari Feb_Mac Mac_April Apr_Mei Mei_Jun Jun_Julai Jul_Ogos Ogs_September Sep_Oktober Okt_November Nov_Disember Dis'.split('_');\n\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var i,\n        expected = 'Ahad Ahd Ah_Isnin Isn Is_Selasa Sel Sl_Rabu Rab Rb_Khamis Kha Km_Jumaat Jum Jm_Sabtu Sab Sb'.split('_');\n\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'beberapa saat', '44 saat = beberapa saat');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'seminit',      '45 saat = seminit');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'seminit',      '89 saat = seminit');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 minit',     '90 saat = 2 minit');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 minit',    '44 minit = 44 minit');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'sejam',       '45 minit = sejam');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'sejam',       '89 minit = sejam');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 jam',       '90 minit = 2 jam');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 jam',       '5 jam = 5 jam');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 jam',      '21 jam = 21 jam');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'sehari',         '22 jam = sehari');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'sehari',         '35 jam = sehari');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 hari',        '36 jam = 2 hari');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'sehari',         '1 hari = sehari');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 hari',        '5 hari = 5 hari');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 hari',       '25 hari = 25 hari');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'sebulan',       '26 hari = sebulan');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'sebulan',       '30 hari = sebulan');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'sebulan',       '45 hari = sebulan');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 bulan',      '46 hari = 2 bulan');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 bulan',      '75 hari = 2 bulan');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 bulan',      '76 hari = 3 bulan');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'sebulan',       '1 bulan = sebulan');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 bulan',      '5 bulan = 5 bulan');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'setahun',        '345 hari = setahun');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 tahun',       '548 hari = 2 tahun');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'setahun',        '1 tahun = setahun');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 tahun',       '5 tahun = 5 tahun');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'dalam beberapa saat',  'prefix');\n    assert.equal(moment(0).from(30000), 'beberapa saat yang lepas', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'beberapa saat yang lepas',  'waktu sekarang dari sekarang sepatutnya menunjukkan sebagai telah lepas');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'dalam beberapa saat', 'dalam beberapa saat');\n    assert.equal(moment().add({d: 5}).fromNow(), 'dalam 5 hari', 'dalam 5 hari');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'Hari ini pukul 12.00',  'hari ini pada waktu yang sama');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'Hari ini pukul 12.25',  'Sekarang tambah 25 minit');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'Hari ini pukul 13.00',  'Sekarang tambah 1 jam');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'Esok pukul 12.00',      'esok pada waktu yang sama');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'Hari ini pukul 11.00',  'Sekarang tolak 1 jam');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'Kelmarin pukul 12.00',  'kelmarin pada waktu yang sama');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('dddd [pukul] LT'),  'Hari ini + ' + i + ' hari waktu sekarang');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd [pukul] LT'),  'Hari ini + ' + i + ' hari permulaan hari');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd [pukul] LT'),  'Hari ini + ' + i + ' hari tamat hari');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('dddd [lepas] [pukul] LT'),  'Hari ini - ' + i + ' hari waktu sekarang');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd [lepas] [pukul] LT'),  'Hari ini - ' + i + ' hari permulaan hari');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd [lepas] [pukul] LT'),  'Hari ini - ' + i + ' hari tamat hari');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 minggu lepas');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'dalam 1 minggu');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 minggu lepas');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'dalam 2 minggu');\n});\n\ntest('weeks year starting sunday format', function (assert) {\n    assert.equal(moment([2012, 0,  1]).format('w ww wo'), '1 01 1', 'Jan  1 2012 sepatutnya minggu 1');\n    assert.equal(moment([2012, 0,  7]).format('w ww wo'), '2 02 2', 'Jan  7 2012 sepatutnya minggu 2');\n    assert.equal(moment([2012, 0,  8]).format('w ww wo'), '2 02 2', 'Jan  8 2012 sepatutnya minggu 2');\n    assert.equal(moment([2012, 0, 14]).format('w ww wo'), '3 03 3', 'Jan 14 2012 sepatutnya minggu 3');\n    assert.equal(moment([2012, 0, 15]).format('w ww wo'), '3 03 3', 'Jan 15 2012 sepatutnya minggu 3');\n});\n\n\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/test/locale/ms.js",
    "content": "import {localeModule, test} from '../qunit';\nimport moment from '../../moment';\nlocaleModule('ms');\n\ntest('parse', function (assert) {\n    var i,\n        tests = 'Januari Jan_Februari Feb_Mac Mac_April Apr_Mei Mei_Jun Jun_Julai Jul_Ogos Ogs_September Sep_Oktober Okt_November Nov_Disember Dis'.split('_');\n\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' sepatutnya bulan ' + (i + 1));\n    }\n\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, MMMM Do YYYY, h:mm:ss a',      'Ahad, Februari 14 2010, 3:25:50 petang'],\n            ['ddd, hA',                            'Ahd, 3petang'],\n            ['M Mo MM MMMM MMM',                   '2 2 02 Februari Feb'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14 14'],\n            ['d do dddd ddd dd',                   '0 0 Ahad Ahd Ah'],\n            ['DDD DDDo DDDD',                      '45 45 045'],\n            ['w wo ww',                            '7 7 07'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'petang petang'],\n            ['[hari] [ke] DDDo [tahun] ini', 'hari ke 45 tahun ini'],\n            ['LTS',                                '15.25.50'],\n            ['L',                                  '14/02/2010'],\n            ['LL',                                 '14 Februari 2010'],\n            ['LLL',                                '14 Februari 2010 pukul 15.25'],\n            ['LLLL',                               'Ahad, 14 Februari 2010 pukul 15.25'],\n            ['l',                                  '14/2/2010'],\n            ['ll',                                 '14 Feb 2010'],\n            ['lll',                                '14 Feb 2010 pukul 15.25'],\n            ['llll',                               'Ahd, 14 Feb 2010 pukul 15.25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1', '1');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2', '2');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3', '3');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4', '4');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5', '5');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6', '6');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7', '7');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8', '8');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9', '9');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10', '10');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11', '11');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12', '12');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13', '13');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14', '14');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15', '15');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16', '16');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17', '17');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18', '18');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19', '19');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20', '20');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21', '21');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22', '22');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23', '23');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24', '24');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25', '25');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26', '26');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27', '27');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28', '28');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29', '29');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30', '30');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31', '31');\n});\n\ntest('format month', function (assert) {\n    var i,\n        expected = 'Januari Jan_Februari Feb_Mac Mac_April Apr_Mei Mei_Jun Jun_Julai Jul_Ogos Ogs_September Sep_Oktober Okt_November Nov_Disember Dis'.split('_');\n\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var i,\n        expected = 'Ahad Ahd Ah_Isnin Isn Is_Selasa Sel Sl_Rabu Rab Rb_Khamis Kha Km_Jumaat Jum Jm_Sabtu Sab Sb'.split('_');\n\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'beberapa saat', '44 saat = beberapa saat');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'seminit',      '45 saat = seminit');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'seminit',      '89 saat = seminit');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 minit',     '90 saat = 2 minit');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 minit',    '44 minit = 44 minit');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'sejam',       '45 minit = sejam');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'sejam',       '89 minit = sejam');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 jam',       '90 minit = 2 jam');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 jam',       '5 jam = 5 jam');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 jam',      '21 jam = 21 jam');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'sehari',         '22 jam = sehari');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'sehari',         '35 jam = sehari');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 hari',        '36 jam = 2 hari');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'sehari',         '1 hari = sehari');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 hari',        '5 hari = 5 hari');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 hari',       '25 hari = 25 hari');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'sebulan',       '26 hari = sebulan');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'sebulan',       '30 hari = sebulan');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'sebulan',       '45 hari = sebulan');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 bulan',      '46 hari = 2 bulan');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 bulan',      '75 hari = 2 bulan');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 bulan',      '76 hari = 3 bulan');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'sebulan',       '1 bulan = sebulan');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 bulan',      '5 bulan = 5 bulan');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'setahun',        '345 hari = setahun');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 tahun',       '548 hari = 2 tahun');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'setahun',        '1 tahun = setahun');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 tahun',       '5 tahun = 5 tahun');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'dalam beberapa saat',  'prefix');\n    assert.equal(moment(0).from(30000), 'beberapa saat yang lepas', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'beberapa saat yang lepas',  'waktu sekarang dari sekarang sepatutnya menunjukkan sebagai telah lepas');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'dalam beberapa saat', 'dalam beberapa saat');\n    assert.equal(moment().add({d: 5}).fromNow(), 'dalam 5 hari', 'dalam 5 hari');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'Hari ini pukul 12.00',  'hari ini pada waktu yang sama');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'Hari ini pukul 12.25',  'Sekarang tambah 25 minit');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'Hari ini pukul 13.00',  'Sekarang tambah 1 jam');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'Esok pukul 12.00',      'esok pada waktu yang sama');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'Hari ini pukul 11.00',  'Sekarang tolak 1 jam');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'Kelmarin pukul 12.00',  'kelmarin pada waktu yang sama');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('dddd [pukul] LT'),  'Hari ini + ' + i + ' hari waktu sekarang');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd [pukul] LT'),  'Hari ini + ' + i + ' hari permulaan hari');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd [pukul] LT'),  'Hari ini + ' + i + ' hari tamat hari');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('dddd [lepas] [pukul] LT'),  'Hari ini - ' + i + ' hari waktu sekarang');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd [lepas] [pukul] LT'),  'Hari ini - ' + i + ' hari permulaan hari');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd [lepas] [pukul] LT'),  'Hari ini - ' + i + ' hari tamat hari');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 minggu lepas');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'dalam 1 minggu');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 minggu lepas');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'dalam 2 minggu');\n});\n\ntest('weeks year starting sunday format', function (assert) {\n    assert.equal(moment([2012, 0,  1]).format('w ww wo'), '1 01 1', 'Jan  1 2012 sepatutnya minggu 1');\n    assert.equal(moment([2012, 0,  7]).format('w ww wo'), '2 02 2', 'Jan  7 2012 sepatutnya minggu 2');\n    assert.equal(moment([2012, 0,  8]).format('w ww wo'), '2 02 2', 'Jan  8 2012 sepatutnya minggu 2');\n    assert.equal(moment([2012, 0, 14]).format('w ww wo'), '3 03 3', 'Jan 14 2012 sepatutnya minggu 3');\n    assert.equal(moment([2012, 0, 15]).format('w ww wo'), '3 03 3', 'Jan 15 2012 sepatutnya minggu 3');\n});\n\n\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/test/locale/my.js",
    "content": "import {localeModule, test} from '../qunit';\nimport moment from '../../moment';\nlocaleModule('my');\n\ntest('parse', function (assert) {\n    var tests = 'ဇန်နဝါရီ ဇန်_ဖေဖော်ဝါရီ ဖေ_မတ် မတ်_ဧပြီ ပြီ_မေ မေ_ဇွန် ဇွန်_ဇူလိုင် လိုင်_သြဂုတ် သြ_စက်တင်ဘာ စက်_အောက်တိုဘာ အောက်_နိုဝင်ဘာ နို_ဒီဇင်ဘာ ဒီ'.split('_'),\n        i;\n\n    function equalTest (input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, MMMM Do YYYY, h:mm:ss a', 'တနင်္ဂနွေ, ဖေဖော်ဝါရီ ၁၄ ၂၀၁၀, ၃:၂၅:၅၀ pm'],\n            ['ddd, hA', 'နွေ, ၃PM'],\n            ['M Mo MM MMMM MMM', '၂ ၂ ၀၂ ဖေဖော်ဝါရီ ဖေ'],\n            ['YYYY YY', '၂၀၁၀ ၁၀'],\n            ['D Do DD', '၁၄ ၁၄ ၁၄'],\n            ['d do dddd ddd dd', '၀ ၀ တနင်္ဂနွေ နွေ နွေ'],\n            ['DDD DDDo DDDD', '၄၅ ၄၅ ၀၄၅'],\n            ['w wo ww', '၆ ၆ ၀၆'],\n            ['h hh', '၃ ၀၃'],\n            ['H HH', '၁၅ ၁၅'],\n            ['m mm', '၂၅ ၂၅'],\n            ['s ss', '၅၀ ၅၀'],\n            ['a A', 'pm PM'],\n            ['[နှစ်၏] DDDo [ရက်မြောက်]', 'နှစ်၏ ၄၅ ရက်မြောက်'],\n            ['LTS', '၁၅:၂၅:၅၀'],\n            ['L', '၁၄/၀၂/၂၀၁၀'],\n            ['LL', '၁၄ ဖေဖော်ဝါရီ ၂၀၁၀'],\n            ['LLL', '၁၄ ဖေဖော်ဝါရီ ၂၀၁၀ ၁၅:၂၅'],\n            ['LLLL', 'တနင်္ဂနွေ ၁၄ ဖေဖော်ဝါရီ ၂၀၁၀ ၁၅:၂၅'],\n            ['l', '၁၄/၂/၂၀၁၀'],\n            ['ll', '၁၄ ဖေ ၂၀၁၀'],\n            ['lll', '၁၄ ဖေ ၂၀၁၀ ၁၅:၂၅'],\n            ['llll', 'နွေ ၁၄ ဖေ ၂၀၁၀ ၁၅:၂၅']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '၁', '၁');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '၂', '၂');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '၃', '၃');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '၄', '၄');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '၅', '၅');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '၆', '၆');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '၇', '၇');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '၈', '၈');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '၉', '၉');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '၁၀', '၁၀');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '၁၁', '၁၁');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '၁၂', '၁၂');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '၁၃', '၁၃');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '၁၄', '၁၄');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '၁၅', '၁၅');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '၁၆', '၁၆');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '၁၇', '၁၇');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '၁၈', '၁၈');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '၁၉', '၁၉');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '၂၀', '၂၀');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '၂၁', '၂၁');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '၂၂', '၂၂');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '၂၃', '၂၃');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '၂၄', '၂၄');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '၂၅', '၂၅');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '၂၆', '၂၆');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '၂၇', '၂၇');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '၂၈', '၂၈');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '၂၉', '၂၉');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '၃၀', '၃၀');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '၃၁', '၃၁');\n});\n\ntest('format month', function (assert) {\n    var expected = 'ဇန်နဝါရီ ဇန်_ဖေဖော်ဝါရီ ဖေ_မတ် မတ်_ဧပြီ ပြီ_မေ မေ_ဇွန် ဇွန်_ဇူလိုင် လိုင်_သြဂုတ် သြ_စက်တင်ဘာ စက်_အောက်တိုဘာ အောက်_နိုဝင်ဘာ နို_ဒီဇင်ဘာ ဒီ'.split('_'),\n        i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'တနင်္ဂနွေ နွေ နွေ_တနင်္လာ လာ လာ_အင်္ဂါ ဂါ ဂါ_ဗုဒ္ဓဟူး ဟူး ဟူး_ကြာသပတေး ကြာ ကြာ_သောကြာ သော သော_စနေ နေ နေ'.split('_'),\n        i;\n\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({\n        s: 44\n    }), true), 'စက္ကန်.အနည်းငယ်', '၄၄ စက္ကန်. = စက္ကန်.အနည်းငယ်');\n    assert.equal(start.from(moment([2007, 1, 28]).add({\n        s: 45\n    }), true), 'တစ်မိနစ်', '၄၅ စက္ကန်. = တစ်မိနစ်');\n    assert.equal(start.from(moment([2007, 1, 28]).add({\n        s: 89\n    }), true), 'တစ်မိနစ်', '၈၉ စက္ကန်. = တစ်မိနစ်');\n    assert.equal(start.from(moment([2007, 1, 28]).add({\n        s: 90\n    }), true), '၂ မိနစ်', '၉၀ စက္ကန်. =  ၂ မိနစ်');\n    assert.equal(start.from(moment([2007, 1, 28]).add({\n        m: 44\n    }), true), '၄၄ မိနစ်', '၄၄ မိနစ် = ၄၄ မိနစ်');\n    assert.equal(start.from(moment([2007, 1, 28]).add({\n        m: 45\n    }), true), 'တစ်နာရီ', '၄၅ မိနစ် = ၁ နာရီ');\n    assert.equal(start.from(moment([2007, 1, 28]).add({\n        m: 89\n    }), true), 'တစ်နာရီ', '၈၉ မိနစ် = တစ်နာရီ');\n    assert.equal(start.from(moment([2007, 1, 28]).add({\n        m: 90\n    }), true), '၂ နာရီ', 'မိနစ် ၉၀= ၂ နာရီ');\n    assert.equal(start.from(moment([2007, 1, 28]).add({\n        h: 5\n    }), true), '၅ နာရီ', '၅ နာရီ= ၅ နာရီ');\n    assert.equal(start.from(moment([2007, 1, 28]).add({\n        h: 21\n    }), true), '၂၁ နာရီ', '၂၁ နာရီ =၂၁ နာရီ');\n    assert.equal(start.from(moment([2007, 1, 28]).add({\n        h: 22\n    }), true), 'တစ်ရက်', '၂၂ နာရီ =တစ်ရက်');\n    assert.equal(start.from(moment([2007, 1, 28]).add({\n        h: 35\n    }), true), 'တစ်ရက်', '၃၅ နာရီ =တစ်ရက်');\n    assert.equal(start.from(moment([2007, 1, 28]).add({\n        h: 36\n    }), true), '၂ ရက်', '၃၆ နာရီ = ၂ ရက်');\n    assert.equal(start.from(moment([2007, 1, 28]).add({\n        d: 1\n    }), true), 'တစ်ရက်', '၁ ရက်= တစ်ရက်');\n    assert.equal(start.from(moment([2007, 1, 28]).add({\n        d: 5\n    }), true), '၅ ရက်', '၅ ရက် = ၅ ရက်');\n    assert.equal(start.from(moment([2007, 1, 28]).add({\n        d: 25\n    }), true), '၂၅ ရက်', '၂၅ ရက်= ၂၅ ရက်');\n    assert.equal(start.from(moment([2007, 1, 28]).add({\n        d: 26\n    }), true), 'တစ်လ', '၂၆ ရက် = တစ်လ');\n    assert.equal(start.from(moment([2007, 1, 28]).add({\n        d: 30\n    }), true), 'တစ်လ', 'ရက် ၃၀ = တစ်လ');\n    assert.equal(start.from(moment([2007, 1, 28]).add({\n        d: 43\n    }), true), 'တစ်လ', '၄၃ ရက် = တစ်လ');\n    assert.equal(start.from(moment([2007, 1, 28]).add({\n        d: 46\n    }), true), '၂ လ', '၄၆ ရက် = ၂ လ');\n    assert.equal(start.from(moment([2007, 1, 28]).add({\n        d: 74\n    }), true), '၂ လ', '၇၅ ရက်= ၂ လ');\n    assert.equal(start.from(moment([2007, 1, 28]).add({\n        d: 76\n    }), true), '၃ လ', '၇၆ ရက် = ၃ လ');\n    assert.equal(start.from(moment([2007, 1, 28]).add({\n        M: 1\n    }), true), 'တစ်လ', '၁ လ = တစ်လ');\n    assert.equal(start.from(moment([2007, 1, 28]).add({\n        M: 5\n    }), true), '၅ လ', '၅ လ = ၅ လ');\n    assert.equal(start.from(moment([2007, 1, 28]).add({\n        d: 345\n    }), true), 'တစ်နှစ်', '၃၄၅ ရက် = တစ်နှစ်');\n    assert.equal(start.from(moment([2007, 1, 28]).add({\n        d: 548\n    }), true), '၂ နှစ်', '၅၄၈ ရက် = ၂ နှစ်');\n    assert.equal(start.from(moment([2007, 1, 28]).add({\n        y: 1\n    }), true), 'တစ်နှစ်', '၁ နှစ် = တစ်နှစ်');\n    assert.equal(start.from(moment([2007, 1, 28]).add({\n        y: 5\n    }), true), '၅ နှစ်', '၅ နှစ် = ၅ နှစ်');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'လာမည့် စက္ကန်.အနည်းငယ် မှာ', 'prefix');\n    assert.equal(moment(0).from(30000), 'လွန်ခဲ့သော စက္ကန်.အနည်းငယ် က', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'လွန်ခဲ့သော စက္ကန်.အနည်းငယ် က', 'ယခုမှစပြီး အတိတ်တွင်ဖော်ပြသလိုဖော်ပြမည်');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({\n        s: 30\n    }).fromNow(), 'လာမည့် စက္ကန်.အနည်းငယ် မှာ', 'လာမည့် စက္ကန်.အနည်းငယ် မှာ');\n    assert.equal(moment().add({\n        d: 5\n    }).fromNow(), 'လာမည့် ၅ ရက် မှာ', 'လာမည့် ၅ ရက် မှာ');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                  'ယနေ. ၁၂:၀၀ မှာ',      'ယနေ. ဒီအချိန်');\n    assert.equal(moment(a).add({m: 25}).calendar(),     'ယနေ. ၁၂:၂၅ မှာ',      'ယခုမှ ၂၅ မိနစ်ပေါင်းထည့်');\n    assert.equal(moment(a).add({h: 1}).calendar(),      'ယနေ. ၁၃:၀၀ မှာ',      'ယခုမှ ၁ နာရီပေါင်းထည့်');\n    assert.equal(moment(a).add({d: 1}).calendar(),      'မနက်ဖြန် ၁၂:၀၀ မှာ',  'မနက်ဖြန် ဒီအချိန်');\n    assert.equal(moment(a).subtract({h: 1}).calendar(), 'ယနေ. ၁၁:၀၀ မှာ',      'ယခုမှ ၁ နာရီနှုတ်');\n    assert.equal(moment(a).subtract({d: 1}).calendar(), 'မနေ.က ၁၂:၀၀ မှာ',     'မနေ.က ဒီအချိန်');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({\n            d: i\n        });\n        assert.equal(m.calendar(), m.format('dddd LT [မှာ]'), 'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(), m.format('dddd LT [မှာ]'), 'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(), m.format('dddd LT [မှာ]'), 'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({\n            d: i\n        });\n        assert.equal(m.calendar(), m.format('[ပြီးခဲ့သော] dddd LT [မှာ]'), 'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(), m.format('[ပြီးခဲ့သော] dddd LT [မှာ]'), 'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(), m.format('[ပြီးခဲ့သော] dddd LT [မှာ]'), 'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({\n            w: 1\n        }),\n        weeksFromNow = moment().add({\n            w: 1\n        });\n\n    assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), 'လွန်ခဲ့သော ၁ ပတ်က');\n    assert.equal(weeksFromNow.calendar(), weeksFromNow.format('L'), '၁ ပတ်အတွင်း');\n\n    weeksAgo = moment().subtract({\n        w: 2\n    });\n    weeksFromNow = moment().add({\n        w: 2\n    });\n\n    assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '၂ ပတ် အရင်က');\n    assert.equal(weeksFromNow.calendar(), weeksFromNow.format('L'), '၂ ပတ် အတွင်း');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2012, 0, 1]).format('w ww wo'), '၅၂ ၅၂ ၅၂', 'Jan  1 2012 should be week 52');\n    assert.equal(moment([2012, 0, 2]).format('w ww wo'), '၁ ၀၁ ၁', 'Jan  2 2012 should be week 1');\n    assert.equal(moment([2012, 0, 8]).format('w ww wo'), '၁ ၀၁ ၁', 'Jan  8 2012 should be week 1');\n    assert.equal(moment([2012, 0, 9]).format('w ww wo'), '၂ ၀၂ ၂', 'Jan  9 2012 should be week 2');\n    assert.equal(moment([2012, 0, 15]).format('w ww wo'), '၂ ၀၂ ၂', 'Jan 15 2012 should be week 2');\n});\n\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/test/locale/nb.js",
    "content": "import {localeModule, test} from '../qunit';\nimport moment from '../../moment';\nlocaleModule('nb');\n\ntest('parse', function (assert) {\n    var tests = 'januar jan._februar feb._mars mars_april april_mai mai_juni juni_juli juli_august aug._september sep._oktober okt._november nov._desember des.'.split('_'),\n        i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, MMMM Do YYYY, h:mm:ss a',      'søndag, februar 14. 2010, 3:25:50 pm'],\n            ['ddd, hA',                            'sø., 3PM'],\n            ['M Mo MM MMMM MMM',                   '2 2. 02 februar feb.'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14. 14'],\n            ['d do dddd ddd dd',                   '0 0. søndag sø. sø'],\n            ['DDD DDDo DDDD',                      '45 45. 045'],\n            ['w wo ww',                            '6 6. 06'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'pm PM'],\n            ['[den] DDDo [dagen i året]',          'den 45. dagen i året'],\n            ['LTS',                                '15:25:50'],\n            ['L',                                  '14.02.2010'],\n            ['LL',                                 '14. februar 2010'],\n            ['LLL',                                '14. februar 2010 kl. 15:25'],\n            ['LLLL',                               'søndag 14. februar 2010 kl. 15:25'],\n            ['l',                                  '14.2.2010'],\n            ['ll',                                 '14. feb. 2010'],\n            ['lll',                                '14. feb. 2010 kl. 15:25'],\n            ['llll',                               'sø. 14. feb. 2010 kl. 15:25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1.', '1.');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2.', '2.');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3.', '3.');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4.', '4.');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5.', '5.');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6.', '6.');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7.', '7.');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8.', '8.');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9.', '9.');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10.', '10.');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11.', '11.');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12.', '12.');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13.', '13.');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14.', '14.');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15.', '15.');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16.', '16.');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17.', '17.');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18.', '18.');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19.', '19.');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20.', '20.');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21.', '21.');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22.', '22.');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23.', '23.');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24.', '24.');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25.', '25.');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26.', '26.');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27.', '27.');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28.', '28.');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29.', '29.');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30.', '30.');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31.', '31.');\n});\n\ntest('format month', function (assert) {\n    var expected = 'januar jan._februar feb._mars mars_april april_mai mai_juni juni_juli juli_august aug._september sep._oktober okt._november nov._desember des.'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'søndag sø. sø_mandag ma. ma_tirsdag ti. ti_onsdag on. on_torsdag to. to_fredag fr. fr_lørdag lø. lø'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'noen sekunder', '44 sekunder = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'ett minutt',      '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'ett minutt',      '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 minutter',     '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 minutter',    '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'en time',       '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'en time',       '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 timer',       '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 timer',       '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 timer',      '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'en dag',         '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'en dag',         '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 dager',        '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'en dag',         '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 dager',        '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 dager',       '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'en måned',       '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'en måned',       '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'en måned',       '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 måneder',      '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 måneder',      '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 måneder',      '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'en måned',       '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 måneder',      '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'ett år',        '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 år',       '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'ett år',        '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 år',       '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'om noen sekunder',  'prefix');\n    assert.equal(moment(0).from(30000), 'noen sekunder siden', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'noen sekunder siden',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'om noen sekunder', 'in a few seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), 'om 5 dager', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'i dag kl. 12:00',     'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'i dag kl. 12:25',     'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'i dag kl. 13:00',     'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'i morgen kl. 12:00',  'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'i dag kl. 11:00',     'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'i går kl. 12:00',     'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('dddd [kl.] LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd [kl.] LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd [kl.] LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('[forrige] dddd [kl.] LT'),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[forrige] dddd [kl.] LT'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[forrige] dddd [kl.] LT'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2012, 0,  1]).format('w ww wo'), '52 52 52.', 'Jan  1 2012 should be week 52');\n    assert.equal(moment([2012, 0,  2]).format('w ww wo'),  '1 01 1.', 'Jan  2 2012 should be week 1');\n    assert.equal(moment([2012, 0,  8]).format('w ww wo'),  '1 01 1.', 'Jan  8 2012 should be week 1');\n    assert.equal(moment([2012, 0,  9]).format('w ww wo'),  '2 02 2.', 'Jan  9 2012 should be week 2');\n    assert.equal(moment([2012, 0, 15]).format('w ww wo'),  '2 02 2.', 'Jan 15 2012 should be week 2');\n});\n\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/test/locale/ne.js",
    "content": "import {localeModule, test} from '../qunit';\nimport moment from '../../moment';\nlocaleModule('ne');\n\ntest('parse', function (assert) {\n    var tests = 'जनवरी जन._फेब्रुवरी फेब्रु._मार्च मार्च_अप्रिल अप्रि._मई मई_जुन जुन_जुलाई जुलाई._अगष्ट अग._सेप्टेम्बर सेप्ट._अक्टोबर अक्टो._नोभेम्बर नोभे._डिसेम्बर डिसे.'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, Do MMMM YYYY, aको h:mm:ss बजे',      'आइतबार, १४ फेब्रुवरी २०१०, दिउँसोको ३:२५:५० बजे'],\n            ['ddd, aको h बजे',                                                'आइत., दिउँसोको ३ बजे'],\n            ['M Mo MM MMMM MMM',                   '२ २ ०२ फेब्रुवरी फेब्रु.'],\n            ['YYYY YY',                            '२०१० १०'],\n            ['D Do DD',                            '१४ १४ १४'],\n            ['d do dddd ddd dd',                   '० ० आइतबार आइत. आ.'],\n            ['DDD DDDo DDDD',                      '४५ ४५ ०४५'],\n            ['w wo ww',                            '८ ८ ०८'],\n            ['h hh',                               '३ ०३'],\n            ['H HH',                               '१५ १५'],\n            ['m mm',                               '२५ २५'],\n            ['s ss',                               '५० ५०'],\n            ['a A',                                'दिउँसो दिउँसो'],\n            ['LTS',                                'दिउँसोको ३:२५:५० बजे'],\n            ['L',                                  '१४/०२/२०१०'],\n            ['LL',                                 '१४ फेब्रुवरी २०१०'],\n            ['LLL',                                '१४ फेब्रुवरी २०१०, दिउँसोको ३:२५ बजे'],\n            ['LLLL',                               'आइतबार, १४ फेब्रुवरी २०१०, दिउँसोको ३:२५ बजे'],\n            ['l',                                  '१४/२/२०१०'],\n            ['ll',                                 '१४ फेब्रु. २०१०'],\n            ['lll',                                '१४ फेब्रु. २०१०, दिउँसोको ३:२५ बजे'],\n            ['llll',                               'आइत., १४ फेब्रु. २०१०, दिउँसोको ३:२५ बजे']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '१', '१');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '२', '२');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '३', '३');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '४', '४');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '५', '५');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '६', '६');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '७', '७');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '८', '८');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '९', '९');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '१०', '१०');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '११', '११');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '१२', '१२');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '१३', '१३');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '१४', '१४');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '१५', '१५');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '१६', '१६');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '१७', '१७');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '१८', '१८');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '१९', '१९');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '२०', '२०');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '२१', '२१');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '२२', '२२');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '२३', '२३');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '२४', '२४');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '२५', '२५');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '२६', '२६');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '२७', '२७');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '२८', '२८');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '२९', '२९');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '३०', '३०');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '३१', '३१');\n});\n\ntest('format month', function (assert) {\n    var expected = 'जनवरी जन._फेब्रुवरी फेब्रु._मार्च मार्च_अप्रिल अप्रि._मई मई_जुन जुन_जुलाई जुलाई._अगष्ट अग._सेप्टेम्बर सेप्ट._अक्टोबर अक्टो._नोभेम्बर नोभे._डिसेम्बर डिसे.'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'आइतबार आइत. आ._सोमबार सोम. सो._मङ्गलबार मङ्गल. मं._बुधबार बुध. बु._बिहिबार बिहि. बि._शुक्रबार शुक्र. शु._शनिबार शनि. श.'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'केही क्षण', '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'एक मिनेट',      '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'एक मिनेट',      '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '२ मिनेट',     '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '४४ मिनेट',    '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'एक घण्टा',       '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'एक घण्टा',       '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '२ घण्टा',       '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '५ घण्टा',       '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '२१ घण्टा',      '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'एक दिन',         '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'एक दिन',         '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '२ दिन',        '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'एक दिन',         '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '५ दिन',        '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '२५ दिन',       '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'एक महिना',       '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'एक महिना',       '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'एक महिना',       '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '२ महिना',      '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '२ महिना',      '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '३ महिना',      '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'एक महिना',       '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '५ महिना',      '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'एक बर्ष',        '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '२ बर्ष',       '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'एक बर्ष',        '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '५ बर्ष',       '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'केही क्षणमा',  'prefix');\n    assert.equal(moment(0).from(30000), 'केही क्षण अगाडि', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'केही क्षण अगाडि',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'केही क्षणमा', 'केही क्षणमा');\n    assert.equal(moment().add({d: 5}).fromNow(), '५ दिनमा', '५ दिनमा');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'आज दिउँसोको १२:०० बजे',    'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'आज दिउँसोको १२:२५ बजे',    'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'आज दिउँसोको १:०० बजे',     'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'भोलि दिउँसोको १२:०० बजे',  'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'आज बिहानको ११:०० बजे',     'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'हिजो दिउँसोको १२:०० बजे',  'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('[आउँदो] dddd[,] LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[आउँदो] dddd[,] LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[आउँदो] dddd[,] LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('[गएको] dddd[,] LT'),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[गएको] dddd[,] LT'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[गएको] dddd[,] LT'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('meridiem', function (assert) {\n    assert.equal(moment([2011, 2, 23,  2, 30]).format('a'), 'राति', 'before dawn');\n    assert.equal(moment([2011, 2, 23,  9, 30]).format('a'), 'बिहान', 'morning');\n    assert.equal(moment([2011, 2, 23, 14, 30]).format('a'), 'दिउँसो', 'during day');\n    assert.equal(moment([2011, 2, 23, 17, 30]).format('a'), 'साँझ', 'evening');\n    assert.equal(moment([2011, 2, 23, 19, 30]).format('a'), 'साँझ', 'late evening');\n    assert.equal(moment([2011, 2, 23, 21, 20]).format('a'), 'राति', 'night');\n\n    assert.equal(moment([2011, 2, 23,  2, 30]).format('A'), 'राति', 'before dawn');\n    assert.equal(moment([2011, 2, 23,  9, 30]).format('A'), 'बिहान', 'morning');\n    assert.equal(moment([2011, 2, 23, 14, 30]).format('A'), 'दिउँसो', 'during day');\n    assert.equal(moment([2011, 2, 23, 17, 30]).format('A'), 'साँझ', 'evening');\n    assert.equal(moment([2011, 2, 23, 19, 30]).format('A'), 'साँझ', 'late evening');\n    assert.equal(moment([2011, 2, 23, 21, 20]).format('A'), 'राति', 'night');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2011, 11, 26]).format('w ww wo'), '५३ ५३ ५३', 'Dec 26 2011 should be week 53');\n    assert.equal(moment([2012,  0,  1]).format('w ww wo'), '१ ०१ १', 'Jan  1 2012 should be week 1');\n    assert.equal(moment([2012,  0,  2]).format('w ww wo'), '१ ०१ १', 'Jan  2 2012 should be week 1');\n    assert.equal(moment([2012,  0,  8]).format('w ww wo'), '२ ०२ २', 'Jan  8 2012 should be week 2');\n    assert.equal(moment([2012,  0,  9]).format('w ww wo'), '२ ०२ २', 'Jan  9 2012 should be week 2');\n});\n\n\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/test/locale/nl-be.js",
    "content": "import {localeModule, test} from '../qunit';\nimport moment from '../../moment';\nlocaleModule('nl-be');\n\ntest('parse', function (assert) {\n    var tests = 'januari jan._februari feb._maart mrt._april apr._mei mei._juni jun._juli jul._augustus aug._september sep._oktober okt._november nov._december dec.'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, MMMM Do YYYY, HH:mm:ss',       'zondag, februari 14de 2010, 15:25:50'],\n            ['ddd, HH',                            'zo., 15'],\n            ['M Mo MM MMMM MMM',                   '2 2de 02 februari feb.'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14de 14'],\n            ['d do dddd ddd dd',                   '0 0de zondag zo. Zo'],\n            ['DDD DDDo DDDD',                      '45 45ste 045'],\n            ['w wo ww',                            '6 6de 06'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'pm PM'],\n            ['[the] DDDo [day of the year]',       'the 45ste day of the year'],\n            ['LTS',                                '15:25:50'],\n            ['L',                                  '14/02/2010'],\n            ['LL',                                 '14 februari 2010'],\n            ['LLL',                                '14 februari 2010 15:25'],\n            ['LLLL',                               'zondag 14 februari 2010 15:25'],\n            ['l',                                  '14/2/2010'],\n            ['ll',                                 '14 feb. 2010'],\n            ['lll',                                '14 feb. 2010 15:25'],\n            ['llll',                               'zo. 14 feb. 2010 15:25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1ste', '1ste');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2de', '2de');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3de', '3de');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4de', '4de');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5de', '5de');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6de', '6de');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7de', '7de');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8ste', '8ste');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9de', '9de');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10de', '10de');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11de', '11de');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12de', '12de');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13de', '13de');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14de', '14de');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15de', '15de');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16de', '16de');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17de', '17de');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18de', '18de');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19de', '19de');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20ste', '20ste');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21ste', '21ste');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22ste', '22ste');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23ste', '23ste');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24ste', '24ste');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25ste', '25ste');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26ste', '26ste');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27ste', '27ste');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28ste', '28ste');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29ste', '29ste');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30ste', '30ste');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31ste', '31ste');\n});\n\ntest('format month', function (assert) {\n    var expected = 'januari jan._februari feb._maart mrt._april apr._mei mei_juni jun._juli jul._augustus aug._september sep._oktober okt._november nov._december dec.'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'zondag zo. Zo_maandag ma. Ma_dinsdag di. Di_woensdag wo. Wo_donderdag do. Do_vrijdag vr. Vr_zaterdag za. Za'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'een paar seconden', '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'één minuut',      '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'één minuut',      '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 minuten',     '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 minuten',    '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'één uur',       '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'één uur',       '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 uur',       '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 uur',       '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 uur',      '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'één dag',         '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'één dag',         '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 dagen',        '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'één dag',         '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 dagen',        '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 dagen',       '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'één maand',       '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'één maand',       '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'één maand',       '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 maanden',      '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 maanden',      '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 maanden',      '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'één maand',       '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 maanden',      '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'één jaar',        '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 jaar',       '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'één jaar',        '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 jaar',       '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'over een paar seconden',  'prefix');\n    assert.equal(moment(0).from(30000), 'een paar seconden geleden', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'een paar seconden geleden',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'over een paar seconden', 'in a few seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), 'over 5 dagen', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'vandaag om 12:00',   'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'vandaag om 12:25',   'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'vandaag om 13:00',   'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'morgen om 12:00',    'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'vandaag om 11:00',   'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'gisteren om 12:00',  'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('dddd [om] LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd [om] LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd [om] LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('[afgelopen] dddd [om] LT'),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[afgelopen] dddd [om] LT'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[afgelopen] dddd [om] LT'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('month abbreviation', function (assert) {\n    assert.equal(moment([2012, 5, 23]).format('D-MMM-YYYY'), '23-jun-2012', 'format month abbreviation surrounded by dashes should not include a dot');\n    assert.equal(moment([2012, 5, 23]).unix(), moment('23-jun-2012', 'D-MMM-YYYY').unix(), 'parse month abbreviation surrounded by dashes without dot');\n    assert.equal(moment([2012, 5, 23]).format('D MMM YYYY'), '23 jun. 2012', 'format month abbreviation not surrounded by dashes should include a dot');\n    assert.equal(moment([2012, 5, 23]).unix(), moment('23 jun. 2012', 'D MMM YYYY').unix(), 'parse month abbreviation not surrounded by dashes with dot');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2012, 0,  1]).format('w ww wo'), '52 52 52ste', 'Jan  1 2012 should be week 52');\n    assert.equal(moment([2012, 0,  2]).format('w ww wo'),   '1 01 1ste', 'Jan  2 2012 should be week 1');\n    assert.equal(moment([2012, 0,  8]).format('w ww wo'),   '1 01 1ste', 'Jan  8 2012 should be week 1');\n    assert.equal(moment([2012, 0,  9]).format('w ww wo'),    '2 02 2de', 'Jan  9 2012 should be week 2');\n    assert.equal(moment([2012, 0, 15]).format('w ww wo'),    '2 02 2de', 'Jan 15 2012 should be week 2');\n});\n\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/test/locale/nl.js",
    "content": "import {localeModule, test} from '../qunit';\nimport moment from '../../moment';\nlocaleModule('nl');\n\ntest('parse', function (assert) {\n    var tests = 'januari jan._februari feb._maart mrt._april apr._mei mei._juni jun._juli jul._augustus aug._september sep._oktober okt._november nov._december dec.'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, MMMM Do YYYY, HH:mm:ss',       'zondag, februari 14de 2010, 15:25:50'],\n            ['ddd, HH',                            'zo., 15'],\n            ['M Mo MM MMMM MMM',                   '2 2de 02 februari feb.'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14de 14'],\n            ['d do dddd ddd dd',                   '0 0de zondag zo. Zo'],\n            ['DDD DDDo DDDD',                      '45 45ste 045'],\n            ['w wo ww',                            '6 6de 06'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'pm PM'],\n            ['[the] DDDo [day of the year]',       'the 45ste day of the year'],\n            ['LTS',                                '15:25:50'],\n            ['L',                                  '14-02-2010'],\n            ['LL',                                 '14 februari 2010'],\n            ['LLL',                                '14 februari 2010 15:25'],\n            ['LLLL',                               'zondag 14 februari 2010 15:25'],\n            ['l',                                  '14-2-2010'],\n            ['ll',                                 '14 feb. 2010'],\n            ['lll',                                '14 feb. 2010 15:25'],\n            ['llll',                               'zo. 14 feb. 2010 15:25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1ste', '1ste');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2de', '2de');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3de', '3de');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4de', '4de');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5de', '5de');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6de', '6de');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7de', '7de');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8ste', '8ste');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9de', '9de');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10de', '10de');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11de', '11de');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12de', '12de');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13de', '13de');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14de', '14de');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15de', '15de');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16de', '16de');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17de', '17de');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18de', '18de');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19de', '19de');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20ste', '20ste');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21ste', '21ste');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22ste', '22ste');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23ste', '23ste');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24ste', '24ste');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25ste', '25ste');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26ste', '26ste');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27ste', '27ste');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28ste', '28ste');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29ste', '29ste');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30ste', '30ste');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31ste', '31ste');\n});\n\ntest('format month', function (assert) {\n    var expected = 'januari jan._februari feb._maart mrt._april apr._mei mei_juni jun._juli jul._augustus aug._september sep._oktober okt._november nov._december dec.'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'zondag zo. Zo_maandag ma. Ma_dinsdag di. Di_woensdag wo. Wo_donderdag do. Do_vrijdag vr. Vr_zaterdag za. Za'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'een paar seconden', '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'één minuut',      '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'één minuut',      '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 minuten',     '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 minuten',    '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'één uur',       '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'één uur',       '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 uur',       '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 uur',       '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 uur',      '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'één dag',         '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'één dag',         '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 dagen',        '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'één dag',         '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 dagen',        '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 dagen',       '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'één maand',       '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'één maand',       '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'één maand',       '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 maanden',      '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 maanden',      '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 maanden',      '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'één maand',       '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 maanden',      '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'één jaar',        '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 jaar',       '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'één jaar',        '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 jaar',       '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'over een paar seconden',  'prefix');\n    assert.equal(moment(0).from(30000), 'een paar seconden geleden', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'een paar seconden geleden',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'over een paar seconden', 'in a few seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), 'over 5 dagen', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'vandaag om 12:00',   'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'vandaag om 12:25',   'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'vandaag om 13:00',   'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'morgen om 12:00',    'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'vandaag om 11:00',   'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'gisteren om 12:00',  'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('dddd [om] LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd [om] LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd [om] LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('[afgelopen] dddd [om] LT'),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[afgelopen] dddd [om] LT'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[afgelopen] dddd [om] LT'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('month abbreviation', function (assert) {\n    assert.equal(moment([2012, 5, 23]).format('D-MMM-YYYY'), '23-jun-2012', 'format month abbreviation surrounded by dashes should not include a dot');\n    assert.equal(moment([2012, 5, 23]).unix(), moment('23-jun-2012', 'D-MMM-YYYY').unix(), 'parse month abbreviation surrounded by dashes without dot');\n    assert.equal(moment([2012, 5, 23]).format('D MMM YYYY'), '23 jun. 2012', 'format month abbreviation not surrounded by dashes should include a dot');\n    assert.equal(moment([2012, 5, 23]).unix(), moment('23 jun. 2012', 'D MMM YYYY').unix(), 'parse month abbreviation not surrounded by dashes with dot');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2012, 0,  1]).format('w ww wo'), '52 52 52ste', 'Jan  1 2012 should be week 52');\n    assert.equal(moment([2012, 0,  2]).format('w ww wo'),   '1 01 1ste', 'Jan  2 2012 should be week 1');\n    assert.equal(moment([2012, 0,  8]).format('w ww wo'),   '1 01 1ste', 'Jan  8 2012 should be week 1');\n    assert.equal(moment([2012, 0,  9]).format('w ww wo'),    '2 02 2de', 'Jan  9 2012 should be week 2');\n    assert.equal(moment([2012, 0, 15]).format('w ww wo'),    '2 02 2de', 'Jan 15 2012 should be week 2');\n});\n\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/test/locale/nn.js",
    "content": "import {localeModule, test} from '../qunit';\nimport moment from '../../moment';\nlocaleModule('nn');\n\ntest('parse', function (assert) {\n    var tests = 'januar jan_februar feb_mars mar_april apr_mai mai_juni jun_juli jul_august aug_september sep_oktober okt_november nov_desember des'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, MMMM Do YYYY, h:mm:ss a',      'sundag, februar 14. 2010, 3:25:50 pm'],\n            ['ddd, hA',                            'sun, 3PM'],\n            ['M Mo MM MMMM MMM',                   '2 2. 02 februar feb'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14. 14'],\n            ['d do dddd ddd dd',                   '0 0. sundag sun su'],\n            ['DDD DDDo DDDD',                      '45 45. 045'],\n            ['w wo ww',                            '6 6. 06'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'pm PM'],\n            ['[the] DDDo [day of the year]',       'the 45. day of the year'],\n            ['LTS',                                '15:25:50'],\n            ['L',                                  '14.02.2010'],\n            ['LL',                                 '14. februar 2010'],\n            ['LLL',                                '14. februar 2010 kl. 15:25'],\n            ['LLLL',                               'sundag 14. februar 2010 kl. 15:25'],\n            ['l',                                  '14.2.2010'],\n            ['ll',                                 '14. feb 2010'],\n            ['lll',                                '14. feb 2010 kl. 15:25'],\n            ['llll',                               'sun 14. feb 2010 kl. 15:25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1.', '1.');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2.', '2.');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3.', '3.');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4.', '4.');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5.', '5.');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6.', '6.');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7.', '7.');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8.', '8.');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9.', '9.');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10.', '10.');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11.', '11.');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12.', '12.');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13.', '13.');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14.', '14.');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15.', '15.');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16.', '16.');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17.', '17.');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18.', '18.');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19.', '19.');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20.', '20.');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21.', '21.');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22.', '22.');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23.', '23.');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24.', '24.');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25.', '25.');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26.', '26.');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27.', '27.');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28.', '28.');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29.', '29.');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30.', '30.');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31.', '31.');\n});\n\ntest('format month', function (assert) {\n    var expected = 'januar jan_februar feb_mars mar_april apr_mai mai_juni jun_juli jul_august aug_september sep_oktober okt_november nov_desember des'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'sundag sun su_måndag mån må_tysdag tys ty_onsdag ons on_torsdag tor to_fredag fre fr_laurdag lau lø'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'nokre sekund', '44 sekunder = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'eit minutt',   '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'eit minutt',   '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 minutt',     '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 minutt',    '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'ein time',     '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'ein time',     '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 timar',      '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 timar',      '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 timar',     '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'ein dag',      '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'ein dag',      '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 dagar',      '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'ein dag',      '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 dagar',      '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 dagar',     '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'ein månad',    '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'ein månad',    '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'ein månad',    '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 månader',    '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 månader',    '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 månader',    '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'ein månad',    '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 månader',    '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'eit år',       '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 år',         '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'eit år',       '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 år',         '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'om nokre sekund',  'prefix');\n    assert.equal(moment(0).from(30000), 'nokre sekund sidan', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'nokre sekund sidan',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'om nokre sekund', 'in a few seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), 'om 5 dagar', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'I dag klokka 12:00',     'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'I dag klokka 12:25',     'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'I dag klokka 13:00',     'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'I morgon klokka 12:00',  'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'I dag klokka 11:00',     'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'I går klokka 12:00',     'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('dddd [klokka] LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd [klokka] LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd [klokka] LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('[Føregåande] dddd [klokka] LT'),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[Føregåande] dddd [klokka] LT'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[Føregåande] dddd [klokka] LT'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2012, 0,  1]).format('w ww wo'), '52 52 52.', 'Jan  1 2012 should be week 52');\n    assert.equal(moment([2012, 0,  2]).format('w ww wo'),   '1 01 1.', 'Jan  2 2012 should be week 1');\n    assert.equal(moment([2012, 0,  8]).format('w ww wo'),   '1 01 1.', 'Jan  8 2012 should be week 1');\n    assert.equal(moment([2012, 0,  9]).format('w ww wo'),   '2 02 2.', 'Jan  9 2012 should be week 2');\n    assert.equal(moment([2012, 0, 15]).format('w ww wo'),   '2 02 2.', 'Jan 15 2012 should be week 2');\n});\n\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/test/locale/pa-in.js",
    "content": "import {localeModule, test} from '../qunit';\nimport moment from '../../moment';\nlocaleModule('pa-in');\n\ntest('parse', function (assert) {\n    var tests = 'ਜਨਵਰੀ ਜਨਵਰੀ_ਫ਼ਰਵਰੀ ਫ਼ਰਵਰੀ_ਮਾਰਚ ਮਾਰਚ_ਅਪ੍ਰੈਲ ਅਪ੍ਰੈਲ_ਮਈ ਮਈ_ਜੂਨ ਜੂਨ_ਜੁਲਾਈ ਜੁਲਾਈ_ਅਗਸਤ ਅਗਸਤ_ਸਤੰਬਰ ਸਤੰਬਰ_ਅਕਤੂਬਰ ਅਕਤੂਬਰ_ਨਵੰਬਰ ਨਵੰਬਰ_ਦਸੰਬਰ ਦਸੰਬਰ'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, Do MMMM YYYY, a h:mm:ss ਵਜੇ',  'ਐਤਵਾਰ, ੧੪ ਫ਼ਰਵਰੀ ੨੦੧੦, ਦੁਪਹਿਰ ੩:੨੫:੫੦ ਵਜੇ'],\n            ['ddd, a h ਵਜੇ',                       'ਐਤ, ਦੁਪਹਿਰ ੩ ਵਜੇ'],\n            ['M Mo MM MMMM MMM',                   '੨ ੨ ੦੨ ਫ਼ਰਵਰੀ ਫ਼ਰਵਰੀ'],\n            ['YYYY YY',                            '੨੦੧੦ ੧੦'],\n            ['D Do DD',                            '੧੪ ੧੪ ੧੪'],\n            ['d do dddd ddd dd',                   '੦ ੦ ਐਤਵਾਰ ਐਤ ਐਤ'],\n            ['DDD DDDo DDDD',                      '੪੫ ੪੫ ੦੪੫'],\n            ['w wo ww',                            '੮ ੮ ੦੮'],\n            ['h hh',                               '੩ ੦੩'],\n            ['H HH',                               '੧੫ ੧੫'],\n            ['m mm',                               '੨੫ ੨੫'],\n            ['s ss',                               '੫੦ ੫੦'],\n            ['a A',                                'ਦੁਪਹਿਰ ਦੁਪਹਿਰ'],\n            ['LTS',                                'ਦੁਪਹਿਰ ੩:੨੫:੫੦ ਵਜੇ'],\n            ['L',                                  '੧੪/੦੨/੨੦੧੦'],\n            ['LL',                                 '੧੪ ਫ਼ਰਵਰੀ ੨੦੧੦'],\n            ['LLL',                                '੧੪ ਫ਼ਰਵਰੀ ੨੦੧੦, ਦੁਪਹਿਰ ੩:੨੫ ਵਜੇ'],\n            ['LLLL',                               'ਐਤਵਾਰ, ੧੪ ਫ਼ਰਵਰੀ ੨੦੧੦, ਦੁਪਹਿਰ ੩:੨੫ ਵਜੇ'],\n            ['l',                                  '੧੪/੨/੨੦੧੦'],\n            ['ll',                                 '੧੪ ਫ਼ਰਵਰੀ ੨੦੧੦'],\n            ['lll',                                '੧੪ ਫ਼ਰਵਰੀ ੨੦੧੦, ਦੁਪਹਿਰ ੩:੨੫ ਵਜੇ'],\n            ['llll',                               'ਐਤ, ੧੪ ਫ਼ਰਵਰੀ ੨੦੧੦, ਦੁਪਹਿਰ ੩:੨੫ ਵਜੇ']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '੧', '੧');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '੨', '੨');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '੩', '੩');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '੪', '੪');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '੫', '੫');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '੬', '੬');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '੭', '੭');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '੮', '੮');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '੯', '੯');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '੧੦', '੧੦');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '੧੧', '੧੧');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '੧੨', '੧੨');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '੧੩', '੧੩');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '੧੪', '੧੪');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '੧੫', '੧੫');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '੧੬', '੧੬');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '੧੭', '੧੭');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '੧੮', '੧੮');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '੧੯', '੧੯');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '੨੦', '੨੦');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '੨੧', '੨੧');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '੨੨', '੨੨');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '੨੩', '੨੩');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '੨੪', '੨੪');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '੨੫', '੨੫');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '੨੬', '੨੬');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '੨੭', '੨੭');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '੨੮', '੨੮');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '੨੯', '੨੯');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '੩੦', '੩੦');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '੩੧', '੩੧');\n});\n\ntest('format month', function (assert) {\n    var expected = 'ਜਨਵਰੀ ਜਨਵਰੀ_ਫ਼ਰਵਰੀ ਫ਼ਰਵਰੀ_ਮਾਰਚ ਮਾਰਚ_ਅਪ੍ਰੈਲ ਅਪ੍ਰੈਲ_ਮਈ ਮਈ_ਜੂਨ ਜੂਨ_ਜੁਲਾਈ ਜੁਲਾਈ_ਅਗਸਤ ਅਗਸਤ_ਸਤੰਬਰ ਸਤੰਬਰ_ਅਕਤੂਬਰ ਅਕਤੂਬਰ_ਨਵੰਬਰ ਨਵੰਬਰ_ਦਸੰਬਰ ਦਸੰਬਰ'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'ਐਤਵਾਰ ਐਤ ਐਤ_ਸੋਮਵਾਰ ਸੋਮ ਸੋਮ_ਮੰਗਲਵਾਰ ਮੰਗਲ ਮੰਗਲ_ਬੁਧਵਾਰ ਬੁਧ ਬੁਧ_ਵੀਰਵਾਰ ਵੀਰ ਵੀਰ_ਸ਼ੁੱਕਰਵਾਰ ਸ਼ੁਕਰ ਸ਼ੁਕਰ_ਸ਼ਨੀਚਰਵਾਰ ਸ਼ਨੀ ਸ਼ਨੀ'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'ਕੁਝ ਸਕਿੰਟ', '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'ਇਕ ਮਿੰਟ',      '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'ਇਕ ਮਿੰਟ',      '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '੨ ਮਿੰਟ',     '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '੪੪ ਮਿੰਟ',    '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'ਇੱਕ ਘੰਟਾ',       '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'ਇੱਕ ਘੰਟਾ',       '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '੨ ਘੰਟੇ',       '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '੫ ਘੰਟੇ',       '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '੨੧ ਘੰਟੇ',      '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'ਇੱਕ ਦਿਨ',         '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'ਇੱਕ ਦਿਨ',         '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '੨ ਦਿਨ',        '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'ਇੱਕ ਦਿਨ',         '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '੫ ਦਿਨ',        '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '੨੫ ਦਿਨ',       '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'ਇੱਕ ਮਹੀਨਾ',       '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'ਇੱਕ ਮਹੀਨਾ',       '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'ਇੱਕ ਮਹੀਨਾ',       '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '੨ ਮਹੀਨੇ',      '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '੨ ਮਹੀਨੇ',      '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '੩ ਮਹੀਨੇ',      '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'ਇੱਕ ਮਹੀਨਾ',       '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '੫ ਮਹੀਨੇ',      '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'ਇੱਕ ਸਾਲ',        '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '੨ ਸਾਲ',       '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'ਇੱਕ ਸਾਲ',        '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '੫ ਸਾਲ',       '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'ਕੁਝ ਸਕਿੰਟ ਵਿੱਚ',  'prefix');\n    assert.equal(moment(0).from(30000), 'ਕੁਝ ਸਕਿੰਟ ਪਿਛਲੇ', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'ਕੁਝ ਸਕਿੰਟ ਪਿਛਲੇ',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'ਕੁਝ ਸਕਿੰਟ ਵਿੱਚ', 'ਕੁਝ ਸਕਿੰਟ ਵਿੱਚ');\n    assert.equal(moment().add({d: 5}).fromNow(), '੫ ਦਿਨ ਵਿੱਚ', '੫ ਦਿਨ ਵਿੱਚ');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'ਅਜ ਦੁਪਹਿਰ ੧੨:੦੦ ਵਜੇ',  'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'ਅਜ ਦੁਪਹਿਰ ੧੨:੨੫ ਵਜੇ',  'Now plus 25 min');\n    assert.equal(moment(a).add({h: 3}).calendar(),       'ਅਜ ਦੁਪਹਿਰ ੩:੦੦ ਵਜੇ',   'Now plus 3 hours');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'ਕਲ ਦੁਪਹਿਰ ੧੨:੦੦ ਵਜੇ',  'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'ਅਜ ਦੁਪਹਿਰ ੧੧:੦੦ ਵਜੇ',  'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'ਕਲ ਦੁਪਹਿਰ ੧੨:੦੦ ਵਜੇ',  'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('dddd[,] LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd[,] LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd[,] LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('[ਪਿਛਲੇ] dddd[,] LT'),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[ਪਿਛਲੇ] dddd[,] LT'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[ਪਿਛਲੇ] dddd[,] LT'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('meridiem invariant', function (assert) {\n    assert.equal(moment([2011, 2, 23,  2, 30]).format('a'), 'ਰਾਤ', 'before dawn');\n    assert.equal(moment([2011, 2, 23,  9, 30]).format('a'), 'ਸਵੇਰ', 'morning');\n    assert.equal(moment([2011, 2, 23, 14, 30]).format('a'), 'ਦੁਪਹਿਰ', 'during day');\n    assert.equal(moment([2011, 2, 23, 17, 30]).format('a'), 'ਸ਼ਾਮ', 'evening');\n    assert.equal(moment([2011, 2, 23, 19, 30]).format('a'), 'ਸ਼ਾਮ', 'late evening');\n    assert.equal(moment([2011, 2, 23, 21, 20]).format('a'), 'ਰਾਤ', 'night');\n\n    assert.equal(moment([2011, 2, 23,  2, 30]).format('A'), 'ਰਾਤ', 'before dawn');\n    assert.equal(moment([2011, 2, 23,  9, 30]).format('A'), 'ਸਵੇਰ', 'morning');\n    assert.equal(moment([2011, 2, 23, 14, 30]).format('A'), 'ਦੁਪਹਿਰ', ' during day');\n    assert.equal(moment([2011, 2, 23, 17, 30]).format('A'), 'ਸ਼ਾਮ', 'evening');\n    assert.equal(moment([2011, 2, 23, 19, 30]).format('A'), 'ਸ਼ਾਮ', 'late evening');\n    assert.equal(moment([2011, 2, 23, 21, 20]).format('A'), 'ਰਾਤ', 'night');\n});\n\ntest('weeks year starting sunday', function (assert) {\n    assert.equal(moment([2012, 0,  1]).week(), 1, 'Jan  1 2012 should be week 1');\n    assert.equal(moment([2012, 0,  7]).week(), 1, 'Jan  7 2012 should be week 1');\n    assert.equal(moment([2012, 0,  8]).week(), 2, 'Jan  8 2012 should be week 2');\n    assert.equal(moment([2012, 0, 14]).week(), 2, 'Jan 14 2012 should be week 2');\n    assert.equal(moment([2012, 0, 15]).week(), 3, 'Jan 15 2012 should be week 3');\n});\n\ntest('weeks year starting monday', function (assert) {\n    assert.equal(moment([2006, 11, 31]).week(), 1, 'Dec 31 2006 should be week 1');\n    assert.equal(moment([2007,  0,  1]).week(), 1, 'Jan  1 2007 should be week 1');\n    assert.equal(moment([2007,  0,  6]).week(), 1, 'Jan  6 2007 should be week 1');\n    assert.equal(moment([2007,  0,  7]).week(), 2, 'Jan  7 2007 should be week 2');\n    assert.equal(moment([2007,  0, 13]).week(), 2, 'Jan 13 2007 should be week 2');\n    assert.equal(moment([2007,  0, 14]).week(), 3, 'Jan 14 2007 should be week 3');\n});\n\ntest('weeks year starting tuesday', function (assert) {\n    assert.equal(moment([2007, 11, 29]).week(), 52, 'Dec 29 2007 should be week 52');\n    assert.equal(moment([2008,  0,  1]).week(), 1, 'Jan  1 2008 should be week 1');\n    assert.equal(moment([2008,  0,  5]).week(), 1, 'Jan  5 2008 should be week 1');\n    assert.equal(moment([2008,  0,  6]).week(), 2, 'Jan  6 2008 should be week 2');\n    assert.equal(moment([2008,  0, 12]).week(), 2, 'Jan 12 2008 should be week 2');\n    assert.equal(moment([2008,  0, 13]).week(), 3, 'Jan 13 2008 should be week 3');\n});\n\ntest('weeks year starting wednesday', function (assert) {\n    assert.equal(moment([2002, 11, 29]).week(), 1, 'Dec 29 2002 should be week 1');\n    assert.equal(moment([2003,  0,  1]).week(), 1, 'Jan  1 2003 should be week 1');\n    assert.equal(moment([2003,  0,  4]).week(), 1, 'Jan  4 2003 should be week 1');\n    assert.equal(moment([2003,  0,  5]).week(), 2, 'Jan  5 2003 should be week 2');\n    assert.equal(moment([2003,  0, 11]).week(), 2, 'Jan 11 2003 should be week 2');\n    assert.equal(moment([2003,  0, 12]).week(), 3, 'Jan 12 2003 should be week 3');\n});\n\ntest('weeks year starting thursday', function (assert) {\n    assert.equal(moment([2008, 11, 28]).week(), 1, 'Dec 28 2008 should be week 1');\n    assert.equal(moment([2009,  0,  1]).week(), 1, 'Jan  1 2009 should be week 1');\n    assert.equal(moment([2009,  0,  3]).week(), 1, 'Jan  3 2009 should be week 1');\n    assert.equal(moment([2009,  0,  4]).week(), 2, 'Jan  4 2009 should be week 2');\n    assert.equal(moment([2009,  0, 10]).week(), 2, 'Jan 10 2009 should be week 2');\n    assert.equal(moment([2009,  0, 11]).week(), 3, 'Jan 11 2009 should be week 3');\n});\n\ntest('weeks year starting friday', function (assert) {\n    assert.equal(moment([2009, 11, 27]).week(), 1, 'Dec 27 2009 should be week 1');\n    assert.equal(moment([2010,  0,  1]).week(), 1, 'Jan  1 2010 should be week 1');\n    assert.equal(moment([2010,  0,  2]).week(), 1, 'Jan  2 2010 should be week 1');\n    assert.equal(moment([2010,  0,  3]).week(), 2, 'Jan  3 2010 should be week 2');\n    assert.equal(moment([2010,  0,  9]).week(), 2, 'Jan  9 2010 should be week 2');\n    assert.equal(moment([2010,  0, 10]).week(), 3, 'Jan 10 2010 should be week 3');\n});\n\ntest('weeks year starting saturday', function (assert) {\n    assert.equal(moment([2010, 11, 26]).week(), 1, 'Dec 26 2010 should be week 1');\n    assert.equal(moment([2011,  0,  1]).week(), 1, 'Jan  1 2011 should be week 1');\n    assert.equal(moment([2011,  0,  2]).week(), 2, 'Jan  2 2011 should be week 2');\n    assert.equal(moment([2011,  0,  8]).week(), 2, 'Jan  8 2011 should be week 2');\n    assert.equal(moment([2011,  0,  9]).week(), 3, 'Jan  9 2011 should be week 3');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2012, 0,  1]).format('w ww wo'), '੧ ੦੧ ੧', 'Jan  1 2012 should be week 1');\n    assert.equal(moment([2012, 0,  7]).format('w ww wo'), '੧ ੦੧ ੧', 'Jan  7 2012 should be week 1');\n    assert.equal(moment([2012, 0,  8]).format('w ww wo'), '੨ ੦੨ ੨', 'Jan  8 2012 should be week 2');\n    assert.equal(moment([2012, 0, 14]).format('w ww wo'), '੨ ੦੨ ੨', 'Jan 14 2012 should be week 2');\n    assert.equal(moment([2012, 0, 15]).format('w ww wo'), '੩ ੦੩ ੩', 'Jan 15 2012 should be week 3');\n});\n\ntest('lenient day of month ordinal parsing', function (assert) {\n    var i, ordinalStr, testMoment;\n    for (i = 1; i <= 31; ++i) {\n        ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n        testMoment = moment(ordinalStr, 'YYYY MM Do');\n        assert.equal(testMoment.year(), 2014,\n                'lenient day of month ordinal parsing ' + i + ' year check');\n        assert.equal(testMoment.month(), 0,\n                'lenient day of month ordinal parsing ' + i + ' month check');\n        assert.equal(testMoment.date(), i,\n                'lenient day of month ordinal parsing ' + i + ' date check');\n    }\n});\n\ntest('lenient day of month ordinal parsing of number', function (assert) {\n    var i, testMoment;\n    for (i = 1; i <= 31; ++i) {\n        testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n        assert.equal(testMoment.year(), 2014,\n                'lenient day of month ordinal parsing of number ' + i + ' year check');\n        assert.equal(testMoment.month(), 0,\n                'lenient day of month ordinal parsing of number ' + i + ' month check');\n        assert.equal(testMoment.date(), i,\n                'lenient day of month ordinal parsing of number ' + i + ' date check');\n    }\n});\n\ntest('strict day of month ordinal parsing', function (assert) {\n    var i, ordinalStr, testMoment;\n    for (i = 1; i <= 31; ++i) {\n        ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n        testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n        assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n    }\n});\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/test/locale/pl.js",
    "content": "import {localeModule, test} from '../qunit';\nimport moment from '../../moment';\nlocaleModule('pl');\n\ntest('parse', function (assert) {\n    var tests = 'styczeń stycznia sty_luty lutego lut_marzec marca mar_kwiecień kwietnia kwi_maj maja maj_czerwiec czerwca cze_lipiec lipca lip_sierpień sierpnia sie_wrzesień września wrz_październik października paź_listopad listopada lis_grudzień grudnia gru'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][2], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][2], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][2].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][2].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('parse strict', function (assert) {\n    var tests = 'styczeń stycznia sty_luty lutego lut_marzec marca mar_kwiecień kwietnia kwi_maj maja maj_czerwiec czerwca cze_lipiec lipca lip_sierpień sierpnia sie_wrzesień września wrz_październik października paź_listopad listopada lis_grudzień grudnia gru'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm, true).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][2], 'MMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][2].toLocaleLowerCase(), 'MMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][2].toLocaleUpperCase(), 'MMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, MMMM Do YYYY, h:mm:ss a',      'niedziela, luty 14. 2010, 3:25:50 pm'],\n            ['ddd, hA',                            'ndz, 3PM'],\n            ['M Mo MM MMMM MMM',                   '2 2. 02 luty lut'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14. 14'],\n            ['d do dddd ddd dd',                   '0 0. niedziela ndz Nd'],\n            ['DDD DDDo DDDD',                      '45 45. 045'],\n            ['w wo ww',                            '6 6. 06'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'pm PM'],\n            ['[the] DDDo [day of the year]',       'the 45. day of the year'],\n            ['LTS',                                '15:25:50'],\n            ['L',                                  '14.02.2010'],\n            ['LL',                                 '14 lutego 2010'],\n            ['LLL',                                '14 lutego 2010 15:25'],\n            ['LLLL',                               'niedziela, 14 lutego 2010 15:25'],\n            ['l',                                  '14.2.2010'],\n            ['ll',                                 '14 lut 2010'],\n            ['lll',                                '14 lut 2010 15:25'],\n            ['llll',                               'ndz, 14 lut 2010 15:25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1.', '1.');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2.', '2.');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3.', '3.');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4.', '4.');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5.', '5.');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6.', '6.');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7.', '7.');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8.', '8.');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9.', '9.');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10.', '10.');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11.', '11.');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12.', '12.');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13.', '13.');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14.', '14.');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15.', '15.');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16.', '16.');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17.', '17.');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18.', '18.');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19.', '19.');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20.', '20.');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21.', '21.');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22.', '22.');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23.', '23.');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24.', '24.');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25.', '25.');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26.', '26.');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27.', '27.');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28.', '28.');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29.', '29.');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30.', '30.');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31.', '31.');\n});\n\ntest('format month', function (assert) {\n    var expected = 'styczeń sty_luty lut_marzec mar_kwiecień kwi_maj maj_czerwiec cze_lipiec lip_sierpień sie_wrzesień wrz_październik paź_listopad lis_grudzień gru'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'niedziela ndz Nd_poniedziałek pon Pn_wtorek wt Wt_środa śr Śr_czwartek czw Cz_piątek pt Pt_sobota sob So'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'kilka sekund',  '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'minuta',        '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'minuta',        '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 minuty',      '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 minuty',     '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'godzina',       '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'godzina',       '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 godziny',     '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 godzin',      '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 godzin',     '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  '1 dzień',       '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  '1 dzień',       '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 dni',         '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   '1 dzień',       '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 dni',         '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 dni',        '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'miesiąc',       '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'miesiąc',       '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'miesiąc',       '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 miesiące',    '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 miesiące',    '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 miesiące',    '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'miesiąc',       '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 miesięcy',    '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'rok',           '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 lata',        '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'rok',           '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 lat',         '5 years = 5 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 112}), true), '112 lat',       '112 years = 112 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 122}), true), '122 lata',      '122 years = 122 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 213}), true), '213 lat',       '213 years = 213 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 223}), true), '223 lata',      '223 years = 223 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'za kilka sekund',  'prefix');\n    assert.equal(moment(0).from(30000), 'kilka sekund temu', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'kilka sekund temu',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'za kilka sekund', 'in a few seconds');\n    assert.equal(moment().add({h: 1}).fromNow(), 'za godzinę', 'in an hour');\n    assert.equal(moment().add({d: 5}).fromNow(), 'za 5 dni', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'Dziś o 12:00',    'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'Dziś o 12:25',    'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'Dziś o 13:00',    'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'Jutro o 12:00',   'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'Dziś o 11:00',    'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'Wczoraj o 12:00', 'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('[W] dddd [o] LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[W] dddd [o] LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[W] dddd [o] LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n\n    function makeFormat(d) {\n        switch (d.day()) {\n            case 0:\n                return '[W zeszłą niedzielę o] LT';\n            case 3:\n                return '[W zeszłą środę o] LT';\n            case 6:\n                return '[W zeszłą sobotę o] LT';\n            default:\n                return '[W zeszły] dddd [o] LT';\n        }\n    }\n\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(), m.format(makeFormat(m)), 'Today - ' + i + ' days current time');\n\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(), m.format(makeFormat(m)), 'Today - ' + i + ' days beginning of day');\n\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(), m.format(makeFormat(m)), 'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2012, 0,  1]).format('w ww wo'), '52 52 52.', 'Jan  1 2012 should be week 52');\n    assert.equal(moment([2012, 0,  2]).format('w ww wo'),   '1 01 1.', 'Jan  2 2012 should be week 1');\n    assert.equal(moment([2012, 0,  8]).format('w ww wo'),   '1 01 1.', 'Jan  8 2012 should be week 1');\n    assert.equal(moment([2012, 0,  9]).format('w ww wo'),   '2 02 2.', 'Jan  9 2012 should be week 2');\n    assert.equal(moment([2012, 0, 15]).format('w ww wo'),   '2 02 2.', 'Jan 15 2012 should be week 2');\n});\n\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/test/locale/pt-br.js",
    "content": "import {localeModule, test} from '../qunit';\nimport moment from '../../moment';\nlocaleModule('pt-br');\n\ntest('parse', function (assert) {\n    var tests = 'janeiro jan_fevereiro fev_março mar_abril abr_maio mai_junho jun_julho jul_agosto ago_setembro set_outubro out_novembro nov_dezembro dez'.split('_'), i;\n\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, MMMM Do YYYY, h:mm:ss a',      'Domingo, Fevereiro 14º 2010, 3:25:50 pm'],\n            ['ddd, hA',                            'Dom, 3PM'],\n            ['M Mo MM MMMM MMM',                   '2 2º 02 Fevereiro Fev'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14º 14'],\n            ['d do dddd ddd',                      '0 0º Domingo Dom'],\n            ['DDD DDDo DDDD',                      '45 45º 045'],\n            ['w wo ww',                            '8 8º 08'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'pm PM'],\n            ['[the] DDDo [day of the year]',       'the 45º day of the year'],\n            ['LTS',                                '15:25:50'],\n            ['L',                                  '14/02/2010'],\n            ['LL',                                 '14 de Fevereiro de 2010'],\n            ['LLL',                                '14 de Fevereiro de 2010 às 15:25'],\n            ['LLLL',                               'Domingo, 14 de Fevereiro de 2010 às 15:25'],\n            ['l',                                  '14/2/2010'],\n            ['ll',                                 '14 de Fev de 2010'],\n            ['lll',                                '14 de Fev de 2010 às 15:25'],\n            ['llll',                               'Dom, 14 de Fev de 2010 às 15:25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1º', '1º');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2º', '2º');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3º', '3º');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4º', '4º');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5º', '5º');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6º', '6º');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7º', '7º');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8º', '8º');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9º', '9º');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10º', '10º');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11º', '11º');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12º', '12º');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13º', '13º');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14º', '14º');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15º', '15º');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16º', '16º');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17º', '17º');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18º', '18º');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19º', '19º');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20º', '20º');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21º', '21º');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22º', '22º');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23º', '23º');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24º', '24º');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25º', '25º');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26º', '26º');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27º', '27º');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28º', '28º');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29º', '29º');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30º', '30º');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31º', '31º');\n});\n\ntest('format month', function (assert) {\n    var expected = 'Janeiro Jan_Fevereiro Fev_Março Mar_Abril Abr_Maio Mai_Junho Jun_Julho Jul_Agosto Ago_Setembro Set_Outubro Out_Novembro Nov_Dezembro Dez'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'Domingo Dom Do_Segunda-feira Seg 2ª_Terça-feira Ter 3ª_Quarta-feira Qua 4ª_Quinta-feira Qui 5ª_Sexta-feira Sex 6ª_Sábado Sáb Sá'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'poucos segundos', '44 seconds = seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'um minuto',   '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'um minuto',   '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 minutos',  '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 minutos', '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'uma hora',    '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'uma hora',    '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 horas',    '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 horas',    '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 horas',   '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'um dia',      '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'um dia',      '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 dias',     '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'um dia',      '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 dias',     '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 dias',    '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'um mês',    '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'um mês',    '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'um mês',    '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 meses',   '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 meses',   '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 meses',   '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'um mês',    '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 meses',   '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'um ano',     '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 anos',    '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'um ano',     '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 anos',    '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'em poucos segundos', 'prefix');\n    assert.equal(moment(0).from(30000), 'poucos segundos atrás', 'suffix');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'em poucos segundos', 'in seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), 'em 5 dias', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'Hoje às 12:00',    'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'Hoje às 12:25',    'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'Hoje às 13:00',    'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'Amanhã às 12:00',  'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'Hoje às 11:00',    'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'Ontem às 12:00',   'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('dddd [às] LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd [às] LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd [às] LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format((m.day() === 0 || m.day() === 6) ? '[Último] dddd [às] LT' : '[Última] dddd [às] LT'),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format((m.day() === 0 || m.day() === 6) ? '[Último] dddd [às] LT' : '[Última] dddd [às] LT'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format((m.day() === 0 || m.day() === 6) ? '[Último] dddd [às] LT' : '[Última] dddd [às] LT'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('weeks year starting sunday format', function (assert) {\n    assert.equal(moment([2012, 0,  1]).format('w ww wo'), '1 01 1º', 'Jan  1 2012 should be week 1');\n    assert.equal(moment([2012, 0,  7]).format('w ww wo'), '1 01 1º', 'Jan  7 2012 should be week 1');\n    assert.equal(moment([2012, 0,  8]).format('w ww wo'), '2 02 2º', 'Jan  8 2012 should be week 2');\n    assert.equal(moment([2012, 0, 14]).format('w ww wo'), '2 02 2º', 'Jan 14 2012 should be week 2');\n    assert.equal(moment([2012, 0, 15]).format('w ww wo'), '3 03 3º', 'Jan 15 2012 should be week 3');\n});\n\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/test/locale/pt.js",
    "content": "import {localeModule, test} from '../qunit';\nimport moment from '../../moment';\nlocaleModule('pt');\n\ntest('parse', function (assert) {\n    var tests = 'Janeiro Jan_Fevereiro Fev_Março Mar_Abril Abr_Maio Mai_Junho Jun_Julho Jul_Agosto Ago_Setembro Set_Outubro Out_Novembro Nov_Dezembro Dez'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, MMMM Do YYYY, h:mm:ss a',      'Domingo, Fevereiro 14º 2010, 3:25:50 pm'],\n            ['ddd, hA',                            'Dom, 3PM'],\n            ['M Mo MM MMMM MMM',                   '2 2º 02 Fevereiro Fev'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14º 14'],\n            ['d do dddd ddd',                      '0 0º Domingo Dom'],\n            ['DDD DDDo DDDD',                      '45 45º 045'],\n            ['w wo ww',                            '6 6º 06'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'pm PM'],\n            ['[the] DDDo [day of the year]',       'the 45º day of the year'],\n            ['LTS',                                '15:25:50'],\n            ['L',                                  '14/02/2010'],\n            ['LL',                                 '14 de Fevereiro de 2010'],\n            ['LLL',                                '14 de Fevereiro de 2010 15:25'],\n            ['LLLL',                               'Domingo, 14 de Fevereiro de 2010 15:25'],\n            ['l',                                  '14/2/2010'],\n            ['ll',                                 '14 de Fev de 2010'],\n            ['lll',                                '14 de Fev de 2010 15:25'],\n            ['llll',                               'Dom, 14 de Fev de 2010 15:25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1º', '1º');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2º', '2º');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3º', '3º');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4º', '4º');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5º', '5º');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6º', '6º');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7º', '7º');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8º', '8º');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9º', '9º');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10º', '10º');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11º', '11º');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12º', '12º');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13º', '13º');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14º', '14º');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15º', '15º');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16º', '16º');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17º', '17º');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18º', '18º');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19º', '19º');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20º', '20º');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21º', '21º');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22º', '22º');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23º', '23º');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24º', '24º');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25º', '25º');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26º', '26º');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27º', '27º');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28º', '28º');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29º', '29º');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30º', '30º');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31º', '31º');\n});\n\ntest('format month', function (assert) {\n    var expected = 'Janeiro Jan_Fevereiro Fev_Março Mar_Abril Abr_Maio Mai_Junho Jun_Julho Jul_Agosto Ago_Setembro Set_Outubro Out_Novembro Nov_Dezembro Dez'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'Domingo Dom Do_Segunda-Feira Seg 2ª_Terça-Feira Ter 3ª_Quarta-Feira Qua 4ª_Quinta-Feira Qui 5ª_Sexta-Feira Sex 6ª_Sábado Sáb Sá'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'segundos',    '44 seconds = seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'um minuto',   '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'um minuto',   '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 minutos',  '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 minutos', '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'uma hora',    '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'uma hora',    '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 horas',    '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 horas',    '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 horas',   '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'um dia',      '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'um dia',      '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 dias',     '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'um dia',      '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 dias',     '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 dias',    '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'um mês',    '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'um mês',    '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'um mês',    '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 meses',   '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 meses',   '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 meses',   '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'um mês',    '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 meses',   '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'um ano',     '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 anos',    '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'um ano',     '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 anos',    '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'em segundos', 'prefix');\n    assert.equal(moment(0).from(30000), 'há segundos', 'suffix');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'em segundos', 'in seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), 'em 5 dias', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'Hoje às 12:00',    'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'Hoje às 12:25',    'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'Hoje às 13:00',    'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'Amanhã às 12:00',  'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'Hoje às 11:00',    'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'Ontem às 12:00',   'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('dddd [às] LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd [às] LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd [às] LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format((m.day() === 0 || m.day() === 6) ? '[Último] dddd [às] LT' : '[Última] dddd [às] LT'),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format((m.day() === 0 || m.day() === 6) ? '[Último] dddd [às] LT' : '[Última] dddd [às] LT'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format((m.day() === 0 || m.day() === 6) ? '[Último] dddd [às] LT' : '[Última] dddd [às] LT'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2012, 0,  1]).format('w ww wo'), '52 52 52º', 'Jan  1 2012 should be week 52');\n    assert.equal(moment([2012, 0,  2]).format('w ww wo'),  '1 01 1º', 'Jan  2 2012 should be week 1');\n    assert.equal(moment([2012, 0,  8]).format('w ww wo'),  '1 01 1º', 'Jan  8 2012 should be week 1');\n    assert.equal(moment([2012, 0,  9]).format('w ww wo'),  '2 02 2º', 'Jan  9 2012 should be week 2');\n    assert.equal(moment([2012, 0, 15]).format('w ww wo'),  '2 02 2º', 'Jan 15 2012 should be week 2');\n});\n\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/test/locale/ro.js",
    "content": "import {localeModule, test} from '../qunit';\nimport moment from '../../moment';\nlocaleModule('ro');\n\ntest('parse', function (assert) {\n    var tests = 'ianuarie ian._februarie febr._martie mart._aprilie apr._mai mai_iunie iun._iulie iul._august aug._septembrie sept._octombrie oct._noiembrie nov._decembrie dec.'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, MMMM Do YYYY, h:mm:ss A',  'duminică, februarie 14 2010, 3:25:50 PM'],\n            ['ddd, hA',                        'Dum, 3PM'],\n            ['M Mo MM MMMM MMM',               '2 2 02 februarie febr.'],\n            ['YYYY YY',                        '2010 10'],\n            ['D Do DD',                        '14 14 14'],\n            ['d do dddd ddd dd',               '0 0 duminică Dum Du'],\n            ['DDD DDDo DDDD',                  '45 45 045'],\n            ['w wo ww',                        '7 7 07'],\n            ['h hh',                           '3 03'],\n            ['H HH',                           '15 15'],\n            ['m mm',                           '25 25'],\n            ['s ss',                           '50 50'],\n            ['a A',                            'pm PM'],\n            ['[a] DDDo[a zi a anului]',        'a 45a zi a anului'],\n            ['LTS',                            '15:25:50'],\n            ['L',                              '14.02.2010'],\n            ['LL',                             '14 februarie 2010'],\n            ['LLL',                            '14 februarie 2010 15:25'],\n            ['LLLL',                           'duminică, 14 februarie 2010 15:25'],\n            ['l',                              '14.2.2010'],\n            ['ll',                             '14 febr. 2010'],\n            ['lll',                            '14 febr. 2010 15:25'],\n            ['llll',                           'Dum, 14 febr. 2010 15:25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1', '1');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2', '2');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3', '3');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4', '4');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5', '5');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6', '6');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7', '7');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8', '8');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9', '9');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10', '10');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11', '11');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12', '12');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13', '13');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14', '14');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15', '15');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16', '16');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17', '17');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18', '18');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19', '19');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20', '20');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21', '21');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22', '22');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23', '23');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24', '24');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25', '25');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26', '26');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27', '27');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28', '28');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29', '29');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30', '30');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31', '31');\n});\n\ntest('format month', function (assert) {\n    var expected = 'ianuarie ian._februarie febr._martie mart._aprilie apr._mai mai_iunie iun._iulie iul._august aug._septembrie sept._octombrie oct._noiembrie nov._decembrie dec.'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'duminică Dum Du_luni Lun Lu_marți Mar Ma_miercuri Mie Mi_joi Joi Jo_vineri Vin Vi_sâmbătă Sâm Sâ'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'câteva secunde', '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'un minut',       '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'un minut',       '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 minute',       '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 de minute',   '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'o oră',          '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'o oră',          '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 ore',          '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 ore',          '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 de ore',      '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'o zi',           '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'o zi',           '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 zile',         '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'o zi',           '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 zile',         '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 de zile',     '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'o lună',         '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'o lună',         '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'o lună',         '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 luni',         '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 luni',         '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 luni',         '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'o lună',         '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 luni',         '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'un an',          '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 ani',          '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'un an',          '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 ani',          '5 years = 5 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 19}), true),   '19 ani',        '19 years = 19 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 20}), true),   '20 de ani',     '20 years = 20 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 100}), true),   '100 de ani',   '100 years = 100 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 101}), true),   '101 ani',      '101 years = 101 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 119}), true),   '119 ani',      '119 years = 119 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 120}), true),   '120 de ani',   '120 years = 120 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 219}), true),   '219 ani',      '219 years = 219 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 220}), true),   '220 de ani',   '220 years = 220 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'peste câteva secunde',   'prefix');\n    assert.equal(moment(0).from(30000), 'câteva secunde în urmă', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'câteva secunde în urmă',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'peste câteva secunde', 'in a few seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), 'peste 5 zile', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'azi la 12:00',     'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'azi la 12:25',     'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'azi la 13:00',     'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'mâine la 12:00',   'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'azi la 11:00',     'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'ieri la 12:00',    'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('dddd [la] LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd [la] LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd [la] LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('[fosta] dddd [la] LT'),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[fosta] dddd [la] LT'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[fosta] dddd [la] LT'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2011, 11, 26]).format('w ww wo'), '1 01 1', 'Dec 26 2011 should be week 1');\n    assert.equal(moment([2012,  0,  1]).format('w ww wo'), '1 01 1', 'Jan  1 2012 should be week 1');\n    assert.equal(moment([2012,  0,  2]).format('w ww wo'), '2 02 2', 'Jan  2 2012 should be week 2');\n    assert.equal(moment([2012,  0,  8]).format('w ww wo'), '2 02 2', 'Jan  8 2012 should be week 2');\n    assert.equal(moment([2012,  0,  9]).format('w ww wo'), '3 03 3', 'Jan  9 2012 should be week 3');\n});\n\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/test/locale/ru.js",
    "content": "import {localeModule, test} from '../qunit';\nimport moment from '../../moment';\nlocaleModule('ru');\n\ntest('parse', function (assert) {\n    var tests = 'январь янв._февраль февр._март март_апрель апр._май май_июнь июнь_июль июль_август авг._сентябрь сент._октябрь окт._ноябрь нояб._декабрь дек.'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    function equalTestStrict(input, mmm, monthIndex) {\n        assert.equal(moment(input, mmm, true).month(), monthIndex, input + ' ' + mmm + ' should be strict month ' + (monthIndex + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n\n        equalTestStrict(tests[i][1], 'MMM', i);\n        equalTestStrict(tests[i][0], 'MMMM', i);\n        equalTestStrict(tests[i][1].toLocaleLowerCase(), 'MMM', i);\n        equalTestStrict(tests[i][1].toLocaleUpperCase(), 'MMM', i);\n        equalTestStrict(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTestStrict(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('parse exceptional case', function (assert) {\n    assert.equal(moment('11 Мая 1989', ['DD MMMM YYYY']).format('DD-MM-YYYY'), '11-05-1989');\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, Do MMMM YYYY, HH:mm:ss',       'воскресенье, 14-го февраля 2010, 15:25:50'],\n            ['ddd, h A',                           'вс, 3 дня'],\n            ['M Mo MM MMMM MMM',                   '2 2-й 02 февраль февр.'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14-го 14'],\n            ['d do dddd ddd dd',                   '0 0-й воскресенье вс вс'],\n            ['DDD DDDo DDDD',                      '45 45-й 045'],\n            ['w wo ww',                            '7 7-я 07'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'дня дня'],\n            ['DDDo [день года]',                   '45-й день года'],\n            ['LTS',                                '15:25:50'],\n            ['L',                                  '14.02.2010'],\n            ['LL',                                 '14 февраля 2010 г.'],\n            ['LLL',                                '14 февраля 2010 г., 15:25'],\n            ['LLLL',                               'воскресенье, 14 февраля 2010 г., 15:25'],\n            ['l',                                  '14.2.2010'],\n            ['ll',                                 '14 февр. 2010 г.'],\n            ['lll',                                '14 февр. 2010 г., 15:25'],\n            ['llll',                               'вс, 14 февр. 2010 г., 15:25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format meridiem', function (assert) {\n    assert.equal(moment([2012, 11, 28, 0, 0]).format('A'), 'ночи', 'night');\n    assert.equal(moment([2012, 11, 28, 3, 59]).format('A'), 'ночи', 'night');\n    assert.equal(moment([2012, 11, 28, 4, 0]).format('A'), 'утра', 'morning');\n    assert.equal(moment([2012, 11, 28, 11, 59]).format('A'), 'утра', 'morning');\n    assert.equal(moment([2012, 11, 28, 12, 0]).format('A'), 'дня', 'afternoon');\n    assert.equal(moment([2012, 11, 28, 16, 59]).format('A'), 'дня', 'afternoon');\n    assert.equal(moment([2012, 11, 28, 17, 0]).format('A'), 'вечера', 'evening');\n    assert.equal(moment([2012, 11, 28, 23, 59]).format('A'), 'вечера', 'evening');\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1-й', '1-й');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2-й', '2-й');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3-й', '3-й');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4-й', '4-й');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5-й', '5-й');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6-й', '6-й');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7-й', '7-й');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8-й', '8-й');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9-й', '9-й');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10-й', '10-й');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11-й', '11-й');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12-й', '12-й');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13-й', '13-й');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14-й', '14-й');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15-й', '15-й');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16-й', '16-й');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17-й', '17-й');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18-й', '18-й');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19-й', '19-й');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20-й', '20-й');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21-й', '21-й');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22-й', '22-й');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23-й', '23-й');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24-й', '24-й');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25-й', '25-й');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26-й', '26-й');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27-й', '27-й');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28-й', '28-й');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29-й', '29-й');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30-й', '30-й');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31-й', '31-й');\n});\n\ntest('format month', function (assert) {\n    var expected = 'январь янв._февраль февр._март март_апрель апр._май май_июнь июнь_июль июль_август авг._сентябрь сент._октябрь окт._ноябрь нояб._декабрь дек.'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format month case', function (assert) {\n    var months = {\n        'nominative': 'январь_февраль_март_апрель_май_июнь_июль_август_сентябрь_октябрь_ноябрь_декабрь'.split('_'),\n        'accusative': 'января_февраля_марта_апреля_мая_июня_июля_августа_сентября_октября_ноября_декабря'.split('_')\n    }, i;\n    for (i = 0; i < 12; i++) {\n        assert.equal(moment([2011, i, 1]).format('D MMMM'), '1 ' + months.accusative[i], '1 ' + months.accusative[i]);\n        assert.equal(moment([2011, i, 1]).format('MMMM'), months.nominative[i], '1 ' + months.nominative[i]);\n    }\n});\n\ntest('format month short case', function (assert) {\n    var monthsShort = {\n        'nominative': 'янв._февр._март_апр._май_июнь_июль_авг._сент._окт._нояб._дек.'.split('_'),\n        'accusative': 'янв._февр._мар._апр._мая_июня_июля_авг._сент._окт._нояб._дек.'.split('_')\n    }, i;\n    for (i = 0; i < 12; i++) {\n        assert.equal(moment([2011, i, 1]).format('D MMM'), '1 ' + monthsShort.accusative[i], '1 ' + monthsShort.accusative[i]);\n        assert.equal(moment([2011, i, 1]).format('MMM'), monthsShort.nominative[i], '1 ' + monthsShort.nominative[i]);\n    }\n});\n\ntest('format month case with escaped symbols', function (assert) {\n    var months = {\n        'nominative': 'январь_февраль_март_апрель_май_июнь_июль_август_сентябрь_октябрь_ноябрь_декабрь'.split('_'),\n        'accusative': 'января_февраля_марта_апреля_мая_июня_июля_августа_сентября_октября_ноября_декабря'.split('_')\n    }, i;\n    for (i = 0; i < 12; i++) {\n        assert.equal(moment([2013, i, 1]).format('D[] MMMM'), '1 ' + months.accusative[i], '1 ' + months.accusative[i]);\n        assert.equal(moment([2013, i, 1]).format('[<i>]D[</i>] [<b>]MMMM[</b>]'), '<i>1</i> <b>' + months.accusative[i] + '</b>', '1 <b>' + months.accusative[i] + '</b>');\n        assert.equal(moment([2013, i, 1]).format('D[-й день] MMMM'), '1-й день ' + months.accusative[i], '1-й день ' + months.accusative[i]);\n        assert.equal(moment([2013, i, 1]).format('D, MMMM'), '1, ' + months.nominative[i], '1, ' + months.nominative[i]);\n    }\n});\n\ntest('format month short case with escaped symbols', function (assert) {\n    var monthsShort = {\n        'nominative': 'янв._февр._март_апр._май_июнь_июль_авг._сент._окт._нояб._дек.'.split('_'),\n        'accusative': 'янв._февр._мар._апр._мая_июня_июля_авг._сент._окт._нояб._дек.'.split('_')\n    }, i;\n    for (i = 0; i < 12; i++) {\n        assert.equal(moment([2013, i, 1]).format('D[] MMM'), '1 ' + monthsShort.accusative[i], '1 ' + monthsShort.accusative[i]);\n        assert.equal(moment([2013, i, 1]).format('[<i>]D[</i>] [<b>]MMM[</b>]'), '<i>1</i> <b>' + monthsShort.accusative[i] + '</b>', '1 <b>' + monthsShort.accusative[i] + '</b>');\n        assert.equal(moment([2013, i, 1]).format('D[-й день] MMM'), '1-й день ' + monthsShort.accusative[i], '1-й день ' + monthsShort.accusative[i]);\n        assert.equal(moment([2013, i, 1]).format('D, MMM'), '1, ' + monthsShort.nominative[i], '1, ' + monthsShort.nominative[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'воскресенье вс вс_понедельник пн пн_вторник вт вт_среда ср ср_четверг чт чт_пятница пт пт_суббота сб сб'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'несколько секунд',    '44 seconds = seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'минута',   '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'минута',   '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 минуты',  '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 31}), true),  '31 минута',  '31 minutes = 31 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 минуты', '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'час',    '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'час',    '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 часа',    '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 часов',    '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 час',   '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'день',      '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'день',      '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 дня',     '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'день',      '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 дней',     '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 11}), true),  '11 дней',     '11 days = 11 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 21}), true),  '21 день',     '21 days = 21 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 дней',    '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'месяц',    '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'месяц',    '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'месяц',    '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 месяца',   '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 месяца',   '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 месяца',   '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'месяц',    '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 месяцев',   '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'год',     '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 года',    '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'год',     '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 лет',    '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'через несколько секунд', 'prefix');\n    assert.equal(moment(0).from(30000), 'несколько секунд назад', 'suffix');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'через несколько секунд', 'in seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), 'через 5 дней', 'in 5 days');\n    assert.equal(moment().add({m: 31}).fromNow(), 'через 31 минуту', 'in 31 minutes = in 31 minutes');\n    assert.equal(moment().subtract({m: 31}).fromNow(), '31 минуту назад', '31 minutes ago = 31 minutes ago');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'Сегодня в 12:00',     'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'Сегодня в 12:25',     'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'Сегодня в 13:00',     'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'Завтра в 12:00',      'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'Сегодня в 11:00',     'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'Вчера в 12:00',       'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m, now;\n\n    function makeFormatNext(d) {\n        switch (d.day()) {\n            case 0:\n                return '[В следующее] dddd [в] LT';\n            case 1:\n            case 2:\n            case 4:\n                return '[В следующий] dddd [в] LT';\n            case 3:\n            case 5:\n            case 6:\n                return '[В следующую] dddd [в] LT';\n        }\n    }\n\n    function makeFormatThis(d) {\n        if (d.day() === 2) {\n            return '[Во] dddd [в] LT';\n        }\n        else {\n            return '[В] dddd [в] LT';\n        }\n    }\n\n    now = moment().startOf('week');\n    for (i = 2; i < 7; i++) {\n        m = moment(now).add({d: i});\n        assert.equal(m.calendar(now),       m.format(makeFormatThis(m)),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(now),       m.format(makeFormatThis(m)),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(now),       m.format(makeFormatThis(m)),  'Today + ' + i + ' days end of day');\n    }\n\n    now = moment().endOf('week');\n    for (i = 2; i < 7; i++) {\n        m = moment(now).add({d: i});\n        assert.equal(m.calendar(now),       m.format(makeFormatNext(m)),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(now),       m.format(makeFormatNext(m)),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(now),       m.format(makeFormatNext(m)),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m, now;\n\n    function makeFormatLast(d) {\n        switch (d.day()) {\n            case 0:\n                return '[В прошлое] dddd [в] LT';\n            case 1:\n            case 2:\n            case 4:\n                return '[В прошлый] dddd [в] LT';\n            case 3:\n            case 5:\n            case 6:\n                return '[В прошлую] dddd [в] LT';\n        }\n    }\n\n    function makeFormatThis(d) {\n        if (d.day() === 2) {\n            return '[Во] dddd [в] LT';\n        }\n        else {\n            return '[В] dddd [в] LT';\n        }\n    }\n\n    now = moment().startOf('week');\n    for (i = 2; i < 7; i++) {\n        m = moment(now).subtract({d: i});\n        assert.equal(m.calendar(now),       m.format(makeFormatLast(m)),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(now),       m.format(makeFormatLast(m)),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(now),       m.format(makeFormatLast(m)),  'Today - ' + i + ' days end of day');\n    }\n\n    now = moment().endOf('week');\n    for (i = 2; i < 7; i++) {\n        m = moment(now).subtract({d: i});\n        assert.equal(m.calendar(now),       m.format(makeFormatThis(m)),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(now),       m.format(makeFormatThis(m)),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(now),       m.format(makeFormatThis(m)),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2011, 11, 26]).format('w ww wo'), '1 01 1-я', 'Dec 26 2011 should be week 1');\n    assert.equal(moment([2012,  0,  1]).format('w ww wo'), '1 01 1-я', 'Jan  1 2012 should be week 1');\n    assert.equal(moment([2012,  0,  2]).format('w ww wo'), '2 02 2-я', 'Jan  2 2012 should be week 2');\n    assert.equal(moment([2012,  0,  8]).format('w ww wo'), '2 02 2-я', 'Jan  8 2012 should be week 2');\n    assert.equal(moment([2012,  0,  9]).format('w ww wo'), '3 03 3-я', 'Jan  9 2012 should be week 3');\n});\n\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/test/locale/sd.js",
    "content": "import {localeModule, test} from '../qunit';\nimport moment from '../../moment';\nlocaleModule('sd');\n\nvar months = [\n    'جنوري',\n    'فيبروري',\n    'مارچ',\n    'اپريل',\n    'مئي',\n    'جون',\n    'جولاءِ',\n    'آگسٽ',\n    'سيپٽمبر',\n    'آڪٽوبر',\n    'نومبر',\n    'ڊسمبر'\n];\nvar days = [\n    'آچر',\n    'سومر',\n    'اڱارو',\n    'اربع',\n    'خميس',\n    'جمع',\n    'ڇنڇر'\n];\n\ntest('parse', function (assert) {\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (var i = 0; i < 12; i++) {\n        equalTest(months[i], 'MMM', i);\n        equalTest(months[i], 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, MMMM Do YYYY, h:mm:ss a',      'آچر، فيبروري 14 2010، 3:25:50 شام'],\n            ['ddd, hA',                            'آچر، 3شام'],\n            ['M Mo MM MMMM MMM',                   '2 2 02 فيبروري فيبروري'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14 14'],\n            ['d do dddd ddd dd',                   '0 0 آچر آچر آچر'],\n            ['DDD DDDo DDDD',                      '45 45 045'],\n            ['w wo ww',                            '6 6 06'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'شام شام'],\n            ['[سال جو] DDDo[ڏينهن]',       'سال جو 45ڏينهن'],\n            ['LTS',                                '15:25:50'],\n            ['L',                                  '14/02/2010'],\n            ['LL',                                 '14 فيبروري 2010'],\n            ['LLL',                                '14 فيبروري 2010 15:25'],\n            ['LLLL',                               'آچر، 14 فيبروري 2010 15:25'],\n            ['l',                                  '14/2/2010'],\n            ['ll',                                 '14 فيبروري 2010'],\n            ['lll',                                '14 فيبروري 2010 15:25'],\n            ['llll',                               'آچر، 14 فيبروري 2010 15:25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1', '1');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2', '2');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3', '3');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4', '4');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5', '5');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6', '6');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7', '7');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8', '8');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9', '9');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10', '10');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11', '11');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12', '12');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13', '13');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14', '14');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15', '15');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16', '16');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17', '17');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18', '18');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19', '19');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20', '20');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21', '21');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22', '22');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23', '23');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24', '24');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25', '25');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26', '26');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27', '27');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28', '28');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29', '29');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30', '30');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31', '31');\n});\n\ntest('format month', function (assert) {\n    for (var i = 0; i < months.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), months[i] + ' ' + months[i], months[i] + ' ' + months[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    for (var i = 0; i < days.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), days[i] + ' ' + days[i] + ' ' + days[i], days[i] + ' ' + days[i] + ' ' + days[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'چند سيڪنڊ', '44 seconds = چند سيڪنڊ');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'هڪ منٽ',      '45 seconds = هڪ منٽ');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'هڪ منٽ',      '89 seconds = هڪ منٽ');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 منٽ',     '90 seconds = 2 منٽ');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 منٽ',    '44 minutes = 44 منٽ');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'هڪ ڪلاڪ',       '45 minutes = هڪ ڪلاڪ');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'هڪ ڪلاڪ',       '89 minutes = هڪ ڪلاڪ');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 ڪلاڪ',       '90 minutes = 2 ڪلاڪ');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 ڪلاڪ',       '5 hours = 5 ڪلاڪ');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 ڪلاڪ',      '21 hours = 21 ڪلاڪ');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'هڪ ڏينهن',         '22 hours = هڪ ڏينهن');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'هڪ ڏينهن',         '35 hours = هڪ ڏينهن');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 ڏينهن',        '36 hours = 2 ڏينهن');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'هڪ ڏينهن',         '1 day = هڪ ڏينهن');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 ڏينهن',        '5 days = 5 ڏينهن');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 ڏينهن',       '25 days = 25 ڏينهن');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'هڪ مهينو',       '26 days = هڪ مهينو');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'هڪ مهينو',       '30 days = هڪ مهينو');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'هڪ مهينو',       '43 days = هڪ مهينو');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 مهينا',      '46 days = 2 مهينا');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 مهينا',      '75 days = 2 مهينا');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 مهينا',      '76 days = 3 مهينا');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'هڪ مهينو',       '1 month = هڪ مهينو');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 مهينا',      '5 months = 5 مهينا');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'هڪ سال',        '345 days = هڪ سال');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 سال',       '548 days = 2 سال');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'هڪ سال',        '1 year = هڪ سال');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 سال',       '5 years = 5 سال');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'چند سيڪنڊ پوء',  'prefix');\n    assert.equal(moment(0).from(30000), 'چند سيڪنڊ اڳ', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'چند سيڪنڊ اڳ',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'چند سيڪنڊ پوء', 'in a few seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), '5 ڏينهن پوء', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'اڄ 12:00',      'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'اڄ 12:25',      'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'اڄ 13:00',      'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'سڀاڻي 12:00',   'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'اڄ 11:00',      'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'ڪالهه 12:00',  'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('dddd [اڳين هفتي تي] LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd [اڳين هفتي تي] LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd [اڳين هفتي تي] LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('[گزريل هفتي] dddd [تي] LT'),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[گزريل هفتي] dddd [تي] LT'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[گزريل هفتي] dddd [تي] LT'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2012, 0,  1]).format('w ww wo'), '52 52 52', 'Jan  1 2012 should be week 52');\n    assert.equal(moment([2012, 0,  2]).format('w ww wo'),   '1 01 1', 'Jan  2 2012 should be week 1');\n    assert.equal(moment([2012, 0,  8]).format('w ww wo'),   '1 01 1', 'Jan  8 2012 should be week 1');\n    assert.equal(moment([2012, 0,  9]).format('w ww wo'),   '2 02 2', 'Jan  9 2012 should be week 2');\n    assert.equal(moment([2012, 0, 15]).format('w ww wo'),   '2 02 2', 'Jan 15 2012 should be week 2');\n});\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/test/locale/se.js",
    "content": "import {localeModule, test} from '../qunit';\nimport moment from '../../moment';\nlocaleModule('se');\n\ntest('parse', function (assert) {\n    var i,\n        tests = 'ođđajagemánnu ođđj_guovvamánnu guov_njukčamánnu njuk_cuoŋománnu cuo_miessemánnu mies_geassemánnu geas_suoidnemánnu suoi_borgemánnu borg_čakčamánnu čakč_golggotmánnu golg_skábmamánnu skáb_juovlamánnu juov'.split('_');\n\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, MMMM Do YYYY, h:mm:ss a',      'sotnabeaivi, guovvamánnu 14. 2010, 3:25:50 pm'],\n            ['ddd, hA',                            'sotn, 3PM'],\n            ['M Mo MM MMMM MMM',                   '2 2. 02 guovvamánnu guov'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14. 14'],\n            ['d do dddd ddd dd',                   '0 0. sotnabeaivi sotn s'],\n            ['DDD DDDo DDDD',                      '45 45. 045'],\n            ['w wo ww',                            '6 6. 06'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'pm PM'],\n            ['[jagi] DDDo [beaivi]',               'jagi 45. beaivi'],\n            ['LTS',                                '15:25:50'],\n            ['L',                                  '14.02.2010'],\n            ['LL',                                 'guovvamánnu 14. b. 2010'],\n            ['LLL',                                'guovvamánnu 14. b. 2010 ti. 15:25'],\n            ['LLLL',                               'sotnabeaivi, guovvamánnu 14. b. 2010 ti. 15:25'],\n            ['l',                                  '14.2.2010'],\n            ['ll',                                 'guov 14. b. 2010'],\n            ['lll',                                'guov 14. b. 2010 ti. 15:25'],\n            ['llll',                               'sotn, guov 14. b. 2010 ti. 15:25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1.', '1.');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2.', '2.');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3.', '3.');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4.', '4.');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5.', '5.');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6.', '6.');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7.', '7.');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8.', '8.');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9.', '9.');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10.', '10.');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11.', '11.');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12.', '12.');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13.', '13.');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14.', '14.');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15.', '15.');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16.', '16.');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17.', '17.');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18.', '18.');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19.', '19.');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20.', '20.');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21.', '21.');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22.', '22.');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23.', '23.');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24.', '24.');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25.', '25.');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26.', '26.');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27.', '27.');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28.', '28.');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29.', '29.');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30.', '30.');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31.', '31.');\n});\n\ntest('format month', function (assert) {\n    var i,\n        expected = 'ođđajagemánnu ođđj_guovvamánnu guov_njukčamánnu njuk_cuoŋománnu cuo_miessemánnu mies_geassemánnu geas_suoidnemánnu suoi_borgemánnu borg_čakčamánnu čakč_golggotmánnu golg_skábmamánnu skáb_juovlamánnu juov'.split('_');\n\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var i,\n        expected = 'sotnabeaivi sotn s_vuossárga vuos v_maŋŋebárga maŋ m_gaskavahkku gask g_duorastat duor d_bearjadat bear b_lávvardat láv L'.split('_');\n\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'moadde sekunddat', '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'okta minuhta',  '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'okta minuhta',  '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 minuhtat',    '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 minuhtat',   '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'okta diimmu',   '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'okta diimmu',   '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 diimmut',     '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 diimmut',     '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 diimmut',    '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'okta beaivi',   '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'okta beaivi',   '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 beaivvit',    '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'okta beaivi',   '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 beaivvit',    '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 beaivvit',   '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'okta mánnu',    '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'okta mánnu',    '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'okta mánnu',    '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 mánut',       '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 mánut',       '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 mánut',       '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'okta mánnu',    '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 mánut',       '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'okta jahki',    '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 jagit',       '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'okta jahki',    '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 jagit',       '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'moadde sekunddat geažes',  'prefix');\n    assert.equal(moment(0).from(30000), 'maŋit moadde sekunddat', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'maŋit moadde sekunddat',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'moadde sekunddat geažes', 'in a few seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), '5 beaivvit geažes', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'otne ti 12:00',     'Today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'otne ti 12:25',     'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'otne ti 13:00',     'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'ihttin ti 12:00',   'Tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'otne ti 11:00',     'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'ikte ti 12:00',     'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('dddd [ti] LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd [ti] LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd [ti] LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('[ovddit] dddd [ti] LT'),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[ovddit] dddd [ti] LT'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[ovddit] dddd [ti] LT'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2012, 0,  1]).format('w ww wo'), '52 52 52.', 'Jan  1 2012 should be week 52');\n    assert.equal(moment([2012, 0,  2]).format('w ww wo'),  '1 01 1.', 'Jan  2 2012 should be week 1');\n    assert.equal(moment([2012, 0,  8]).format('w ww wo'),  '1 01 1.', 'Jan  8 2012 should be week 1');\n    assert.equal(moment([2012, 0,  9]).format('w ww wo'),  '2 02 2.', 'Jan  9 2012 should be week 2');\n    assert.equal(moment([2012, 0, 15]).format('w ww wo'),  '2 02 2.', 'Jan 15 2012 should be week 2');\n});\n\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/test/locale/si.js",
    "content": "import {localeModule, test} from '../qunit';\nimport moment from '../../moment';\nlocaleModule('si');\n\n/*jshint -W100*/\ntest('parse', function (assert) {\n    var tests = 'ජනවාරි ජන_පෙබරවාරි පෙබ_මාර්තු මාර්_අප්‍රේල් අප්_මැයි මැයි_ජූනි ජූනි_ජූලි ජූලි_අගෝස්තු අගෝ_සැප්තැම්බර් සැප්_ඔක්තෝබර් ඔක්_නොවැම්බර් නොවැ_දෙසැම්බර් දෙසැ'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['YYYY MMMM Do dddd, a h:mm:ss',       '2010 පෙබරවාරි 14 වැනි ඉරිදා, ප.ව. 3:25:50'],\n            ['YYYY MMMM Do dddd, a h:mm:ss',       '2010 පෙබරවාරි 14 වැනි ඉරිදා, ප.ව. 3:25:50'],\n            ['ddd, A h',                            'ඉරි, පස් වරු 3'],\n            ['M Mo MM MMMM MMM',                   '2 2 වැනි 02 පෙබරවාරි පෙබ'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14 වැනි 14'],\n            ['d do dddd ddd dd',                   '0 0 වැනි ඉරිදා ඉරි ඉ'],\n            ['DDD DDDo DDDD',                      '45 45 වැනි 045'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'ප.ව. පස් වරු'],\n            ['[වසරේ] DDDo [දිනය]',                      'වසරේ 45 වැනි දිනය'],\n            ['LTS',                                'ප.ව. 3:25:50'],\n            ['LT',                                 'ප.ව. 3:25'],\n            ['L',                                  '2010/02/14'],\n            ['LL',                                 '2010 පෙබරවාරි 14'],\n            ['LLL',                                '2010 පෙබරවාරි 14, ප.ව. 3:25'],\n            ['LLLL',                               '2010 පෙබරවාරි 14 වැනි ඉරිදා, ප.ව. 3:25:50'],\n            ['l',                                  '2010/2/14'],\n            ['ll',                                 '2010 පෙබ 14'],\n            ['lll',                                '2010 පෙබ 14, ප.ව. 3:25'],\n            ['llll',                               '2010 පෙබ 14 වැනි ඉරි, ප.ව. 3:25:50']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1 වැනි', '1 වැනි');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2 වැනි', '2 වැනි');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3 වැනි', '3 වැනි');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4 වැනි', '4 වැනි');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5 වැනි', '5 වැනි');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6 වැනි', '6 වැනි');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7 වැනි', '7 වැනි');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8 වැනි', '8 වැනි');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9 වැනි', '9 වැනි');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10 වැනි', '10 වැනි');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11 වැනි', '11 වැනි');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12 වැනි', '12 වැනි');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13 වැනි', '13 වැනි');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14 වැනි', '14 වැනි');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15 වැනි', '15 වැනි');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16 වැනි', '16 වැනි');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17 වැනි', '17 වැනි');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18 වැනි', '18 වැනි');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19 වැනි', '19 වැනි');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20 වැනි', '20 වැනි');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21 වැනි', '21 වැනි');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22 වැනි', '22 වැනි');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23 වැනි', '23 වැනි');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24 වැනි', '24 වැනි');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25 වැනි', '25 වැනි');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26 වැනි', '26 වැනි');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27 වැනි', '27 වැනි');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28 වැනි', '28 වැනි');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29 වැනි', '29 වැනි');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30 වැනි', '30 වැනි');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31 වැනි', '31 වැනි');\n});\n\ntest('format month', function (assert) {\n    var expected = 'ජනවාරි ජන_පෙබරවාරි පෙබ_මාර්තු මාර්_අප්‍රේල් අප්_මැයි මැයි_ජූනි ජූනි_ජූලි ජූලි_අගෝස්තු අගෝ_සැප්තැම්බර් සැප්_ඔක්තෝබර් ඔක්_නොවැම්බර් නොවැ_දෙසැම්බර් දෙසැ'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'ඉරිදා ඉරි ඉ_සඳුදා සඳු ස_අඟහරුවාදා අඟ අ_බදාදා බදා බ_බ්‍රහස්පතින්දා බ්‍රහ බ්‍ර_සිකුරාදා සිකු සි_සෙනසුරාදා සෙන සෙ'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'තත්පර කිහිපය', '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'මිනිත්තුව',      '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'මිනිත්තුව',      '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  'මිනිත්තු 2',     '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  'මිනිත්තු 44',    '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'පැය',       '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'පැය',       '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  'පැය 2',       '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   'පැය 5',       '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  'පැය 21',      '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'දිනය',         '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'දිනය',         '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  'දින 2',        '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'දිනය',         '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   'දින 5',        '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  'දින 25',       '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'මාසය',       '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'මාසය',       '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'මාසය',       '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  'මාස 2',      '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  'මාස 2',      '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  'මාස 3',      '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'මාසය',       '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   'මාස 5',      '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'වසර',        '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), 'වසර 2',       '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'වසර',        '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   'වසර 5',       '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'තත්පර කිහිපයකින්',  'prefix');\n    assert.equal(moment(0).from(30000), 'තත්පර කිහිපයකට පෙර', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'තත්පර කිහිපයකට පෙර',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'තත්පර කිහිපයකින්', 'in a few seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), 'දින 5කින්', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'අද ප.ව. 12:00ට',     'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'අද ප.ව. 12:25ට',     'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'අද ප.ව. 1:00ට',      'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'හෙට ප.ව. 12:00ට',   'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'අද පෙ.ව. 11:00ට',    'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'ඊයේ ප.ව. 12:00ට',   'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('dddd LT[ට]'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd LT[ට]'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd LT[ට]'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('[පසුගිය] dddd LT[ට]'),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[පසුගිය] dddd LT[ට]'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[පසුගිය] dddd LT[ට]'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/test/locale/sk.js",
    "content": "import {localeModule, test} from '../qunit';\nimport moment from '../../moment';\nlocaleModule('sk');\n\ntest('parse', function (assert) {\n    var tests = 'január jan._február feb._marec mar._apríl apr._máj máj_jún jún._júl júl._august aug._september sep._október okt._november nov._december dec.'.split('_'), i;\n    function equalTest(input, mmm, monthIndex) {\n        assert.equal(moment(input, mmm).month(), monthIndex, input + ' should be month ' + (monthIndex + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, MMMM Do YYYY, h:mm:ss',  'nedeľa, február 14. 2010, 3:25:50'],\n            ['ddd, h',                       'ne, 3'],\n            ['M Mo MM MMMM MMM',             '2 2. 02 február feb'],\n            ['YYYY YY',                      '2010 10'],\n            ['D Do DD',                      '14 14. 14'],\n            ['d do dddd ddd dd',             '0 0. nedeľa ne ne'],\n            ['DDD DDDo DDDD',                '45 45. 045'],\n            ['w wo ww',                      '6 6. 06'],\n            ['h hh',                         '3 03'],\n            ['H HH',                         '15 15'],\n            ['m mm',                         '25 25'],\n            ['s ss',                         '50 50'],\n            ['a A',                          'pm PM'],\n            ['DDDo [deň v roku]',            '45. deň v roku'],\n            ['LTS',                          '15:25:50'],\n            ['L',                            '14.02.2010'],\n            ['LL',                           '14. február 2010'],\n            ['LLL',                          '14. február 2010 15:25'],\n            ['LLLL',                         'nedeľa 14. február 2010 15:25'],\n            ['l',                            '14.2.2010'],\n            ['ll',                           '14. feb 2010'],\n            ['lll',                          '14. feb 2010 15:25'],\n            ['llll',                         'ne 14. feb 2010 15:25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1.', '1.');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2.', '2.');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3.', '3.');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4.', '4.');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5.', '5.');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6.', '6.');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7.', '7.');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8.', '8.');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9.', '9.');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10.', '10.');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11.', '11.');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12.', '12.');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13.', '13.');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14.', '14.');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15.', '15.');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16.', '16.');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17.', '17.');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18.', '18.');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19.', '19.');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20.', '20.');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21.', '21.');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22.', '22.');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23.', '23.');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24.', '24.');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25.', '25.');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26.', '26.');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27.', '27.');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28.', '28.');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29.', '29.');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30.', '30.');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31.', '31.');\n});\n\ntest('format month', function (assert) {\n    var expected = 'január jan_február feb_marec mar_apríl apr_máj máj_jún jún_júl júl_august aug_september sep_október okt_november nov_december dec'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'nedeľa ne ne_pondelok po po_utorok ut ut_streda st st_štvrtok št št_piatok pi pi_sobota so so'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'pár sekúnd',  '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'minúta',        '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'minúta',        '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 minúty',      '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 minút',     '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'hodina',       '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'hodina',       '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 hodiny',     '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 hodín',      '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 hodín',     '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'deň',       '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'deň',       '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 dni',         '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'deň',       '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 dní',         '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 dní',        '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'mesiac',       '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'mesiac',       '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'mesiac',       '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 mesiace',    '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 mesiace',    '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 mesiace',    '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'mesiac',       '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 mesiacov',    '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'rok',           '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 roky',        '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'rok',           '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 rokov',         '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'za pár sekúnd',  'prefix');\n    assert.equal(moment(0).from(30000), 'pred pár sekundami', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'pred pár sekundami',  'now from now should display as in the past');\n});\n\ntest('fromNow (future)', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'za pár sekúnd', 'in a few seconds');\n    assert.equal(moment().add({m: 1}).fromNow(), 'za minútu', 'in a minute');\n    assert.equal(moment().add({m: 3}).fromNow(), 'za 3 minúty', 'in 3 minutes');\n    assert.equal(moment().add({m: 10}).fromNow(), 'za 10 minút', 'in 10 minutes');\n    assert.equal(moment().add({h: 1}).fromNow(), 'za hodinu', 'in an hour');\n    assert.equal(moment().add({h: 3}).fromNow(), 'za 3 hodiny', 'in 3 hours');\n    assert.equal(moment().add({h: 10}).fromNow(), 'za 10 hodín', 'in 10 hours');\n    assert.equal(moment().add({d: 1}).fromNow(), 'za deň', 'in a day');\n    assert.equal(moment().add({d: 3}).fromNow(), 'za 3 dni', 'in 3 days');\n    assert.equal(moment().add({d: 10}).fromNow(), 'za 10 dní', 'in 10 days');\n    assert.equal(moment().add({M: 1}).fromNow(), 'za mesiac', 'in a month');\n    assert.equal(moment().add({M: 3}).fromNow(), 'za 3 mesiace', 'in 3 months');\n    assert.equal(moment().add({M: 10}).fromNow(), 'za 10 mesiacov', 'in 10 months');\n    assert.equal(moment().add({y: 1}).fromNow(), 'za rok', 'in a year');\n    assert.equal(moment().add({y: 3}).fromNow(), 'za 3 roky', 'in 3 years');\n    assert.equal(moment().add({y: 10}).fromNow(), 'za 10 rokov', 'in 10 years');\n});\n\ntest('fromNow (past)', function (assert) {\n    assert.equal(moment().subtract({s: 30}).fromNow(), 'pred pár sekundami', 'a few seconds ago');\n    assert.equal(moment().subtract({m: 1}).fromNow(), 'pred minútou', 'a minute ago');\n    assert.equal(moment().subtract({m: 3}).fromNow(), 'pred 3 minútami', '3 minutes ago');\n    assert.equal(moment().subtract({m: 10}).fromNow(), 'pred 10 minútami', '10 minutes ago');\n    assert.equal(moment().subtract({h: 1}).fromNow(), 'pred hodinou', 'an hour ago');\n    assert.equal(moment().subtract({h: 3}).fromNow(), 'pred 3 hodinami', '3 hours ago');\n    assert.equal(moment().subtract({h: 10}).fromNow(), 'pred 10 hodinami', '10 hours ago');\n    assert.equal(moment().subtract({d: 1}).fromNow(), 'pred dňom', 'a day ago');\n    assert.equal(moment().subtract({d: 3}).fromNow(), 'pred 3 dňami', '3 days ago');\n    assert.equal(moment().subtract({d: 10}).fromNow(), 'pred 10 dňami', '10 days ago');\n    assert.equal(moment().subtract({M: 1}).fromNow(), 'pred mesiacom', 'a month ago');\n    assert.equal(moment().subtract({M: 3}).fromNow(), 'pred 3 mesiacmi', '3 months ago');\n    assert.equal(moment().subtract({M: 10}).fromNow(), 'pred 10 mesiacmi', '10 months ago');\n    assert.equal(moment().subtract({y: 1}).fromNow(), 'pred rokom', 'a year ago');\n    assert.equal(moment().subtract({y: 3}).fromNow(), 'pred 3 rokmi', '3 years ago');\n    assert.equal(moment().subtract({y: 10}).fromNow(), 'pred 10 rokmi', '10 years ago');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'dnes o 12:00',     'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'dnes o 12:25',     'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'dnes o 13:00',     'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'zajtra o 12:00',   'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'dnes o 11:00',     'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'včera o 12:00',    'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m, nextDay;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        nextDay = '';\n        switch (m.day()) {\n            case 0:\n                nextDay = 'v nedeľu';\n                break;\n            case 1:\n                nextDay = 'v pondelok';\n                break;\n            case 2:\n                nextDay = 'v utorok';\n                break;\n            case 3:\n                nextDay = 'v stredu';\n                break;\n            case 4:\n                nextDay = 'vo štvrtok';\n                break;\n            case 5:\n                nextDay = 'v piatok';\n                break;\n            case 6:\n                nextDay = 'v sobotu';\n                break;\n        }\n        assert.equal(m.calendar(),       m.format('[' + nextDay + '] [o] LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[' + nextDay + '] [o] LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[' + nextDay + '] [o] LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m, lastDay;\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        lastDay = '';\n        switch (m.day()) {\n            case 0:\n                lastDay = 'minulú nedeľu';\n                break;\n            case 1:\n                lastDay = 'minulý pondelok';\n                break;\n            case 2:\n                lastDay = 'minulý utorok';\n                break;\n            case 3:\n                lastDay = 'minulú stredu';\n                break;\n            case 4:\n                lastDay = 'minulý štvrtok';\n                break;\n            case 5:\n                lastDay = 'minulý piatok';\n                break;\n            case 6:\n                lastDay = 'minulú sobotu';\n                break;\n        }\n        assert.equal(m.calendar(),       m.format('[' + lastDay + '] [o] LT'),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[' + lastDay + '] [o] LT'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[' + lastDay + '] [o] LT'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('humanize duration', function (assert) {\n    assert.equal(moment.duration(1, 'minutes').humanize(), 'minúta', 'a minute (future)');\n    assert.equal(moment.duration(1, 'minutes').humanize(true), 'za minútu', 'in a minute');\n    assert.equal(moment.duration(-1, 'minutes').humanize(), 'minúta', 'a minute (past)');\n    assert.equal(moment.duration(-1, 'minutes').humanize(true), 'pred minútou', 'a minute ago');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2012, 0,  1]).format('w ww wo'), '52 52 52.', 'Jan  1 2012 should be week 52');\n    assert.equal(moment([2012, 0,  2]).format('w ww wo'),   '1 01 1.', 'Jan  2 2012 should be week 1');\n    assert.equal(moment([2012, 0,  8]).format('w ww wo'),   '1 01 1.', 'Jan  8 2012 should be week 1');\n    assert.equal(moment([2012, 0,  9]).format('w ww wo'),   '2 02 2.', 'Jan  9 2012 should be week 2');\n    assert.equal(moment([2012, 0, 15]).format('w ww wo'),   '2 02 2.', 'Jan 15 2012 should be week 2');\n});\n\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/test/locale/sl.js",
    "content": "import {localeModule, test} from '../qunit';\nimport moment from '../../moment';\nlocaleModule('sl');\n\ntest('parse', function (assert) {\n    var tests = 'januar jan._februar feb._marec mar._april apr._maj maj_junij jun._julij jul._avgust avg._september sep._oktober okt._november nov._december dec.'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, Do MMMM YYYY, h:mm:ss a',      'nedelja, 14. februar 2010, 3:25:50 pm'],\n            ['ddd, hA',                            'ned., 3PM'],\n            ['M Mo MM MMMM MMM',                   '2 2. 02 februar feb.'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14. 14'],\n            ['d do dddd ddd dd',                   '0 0. nedelja ned. ne'],\n            ['DDD DDDo DDDD',                      '45 45. 045'],\n            ['w wo ww',                            '7 7. 07'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'pm PM'],\n            ['[the] DDDo [day of the year]',       'the 45. day of the year'],\n            ['LTS',                                '15:25:50'],\n            ['L',                                  '14.02.2010'],\n            ['LL',                                 '14. februar 2010'],\n            ['LLL',                                '14. februar 2010 15:25'],\n            ['LLLL',                               'nedelja, 14. februar 2010 15:25'],\n            ['l',                                  '14.2.2010'],\n            ['ll',                                 '14. feb. 2010'],\n            ['lll',                                '14. feb. 2010 15:25'],\n            ['llll',                               'ned., 14. feb. 2010 15:25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1.', '1.');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2.', '2.');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3.', '3.');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4.', '4.');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5.', '5.');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6.', '6.');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7.', '7.');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8.', '8.');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9.', '9.');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10.', '10.');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11.', '11.');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12.', '12.');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13.', '13.');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14.', '14.');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15.', '15.');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16.', '16.');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17.', '17.');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18.', '18.');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19.', '19.');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20.', '20.');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21.', '21.');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22.', '22.');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23.', '23.');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24.', '24.');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25.', '25.');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26.', '26.');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27.', '27.');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28.', '28.');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29.', '29.');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30.', '30.');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31.', '31.');\n});\n\ntest('format month', function (assert) {\n    var expected = 'januar jan._februar feb._marec mar._april apr._maj maj._junij jun._julij jul._avgust avg._september sep._oktober okt._november nov._december dec.'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'nedelja ned. ne_ponedeljek pon. po_torek tor. to_sreda sre. sr_četrtek čet. če_petek pet. pe_sobota sob. so'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'nekaj sekund', '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'ena minuta',   '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'ena minuta',   '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 minuti',     '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 minut',     '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'ena ura',      '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'ena ura',      '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 uri',        '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 ur',         '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 ur',        '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'en dan',       '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'en dan',       '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 dni',        '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'en dan',       '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 dni',        '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 dni',       '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'en mesec',     '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'en mesec',     '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'en mesec',     '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 meseca',     '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 meseca',     '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 mesece',     '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'en mesec',     '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 mesecev',    '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'eno leto',     '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 leti',       '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'eno leto',     '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 let',        '5 years = 5 years');\n\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 1}), true),  'ena minuta', 'a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 2}), true),  '2 minuti',   '2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 3}), true),  '3 minute',   '3 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 4}), true),  '4 minute',   '4 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 5}), true),  '5 minut',    '5 minutes');\n\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 1}), true),  'ena ura', 'an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 2}), true),  '2 uri',   '2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 3}), true),  '3 ure',   '3 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 4}), true),  '4 ure',   '4 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),  '5 ur',    '5 hours');\n\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),  'en dan', 'a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 2}), true),  '2 dni',  '2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 3}), true),  '3 dni',  '3 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 4}), true),  '4 dni',  '4 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),  '5 dni',  '5 days');\n\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),  'en mesec',  'a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 2}), true),  '2 meseca',  '2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 3}), true),  '3 mesece',  '3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 4}), true),  '4 mesece',  '4 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),  '5 mesecev', '5 months');\n\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),  'eno leto', 'a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 2}), true),  '2 leti',   '2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 3}), true),  '3 leta',   '3 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 4}), true),  '4 leta',   '4 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),  '5 let',    '5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'čez nekaj sekund',  'prefix');\n    assert.equal(moment(0).from(30000), 'pred nekaj sekundami', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'pred nekaj sekundami',  'now from now should display as in the past');\n});\n\ntest('fromNow (future)', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'čez nekaj sekund', 'in a few seconds');\n    assert.equal(moment().add({m: 1}).fromNow(),  'čez eno minuto', 'in a minute');\n    assert.equal(moment().add({m: 2}).fromNow(),  'čez 2 minuti',   'in 2 minutes');\n    assert.equal(moment().add({m: 3}).fromNow(),  'čez 3 minute',   'in 3 minutes');\n    assert.equal(moment().add({m: 4}).fromNow(),  'čez 4 minute',   'in 4 minutes');\n    assert.equal(moment().add({m: 5}).fromNow(),  'čez 5 minut',    'in 5 minutes');\n\n    assert.equal(moment().add({h: 1}).fromNow(),  'čez eno uro', 'in an hour');\n    assert.equal(moment().add({h: 2}).fromNow(),  'čez 2 uri',   'in 2 hours');\n    assert.equal(moment().add({h: 3}).fromNow(),  'čez 3 ure',   'in 3 hours');\n    assert.equal(moment().add({h: 4}).fromNow(),  'čez 4 ure',   'in 4 hours');\n    assert.equal(moment().add({h: 5}).fromNow(),  'čez 5 ur',    'in 5 hours');\n\n    assert.equal(moment().add({d: 1}).fromNow(),  'čez en dan', 'in a day');\n    assert.equal(moment().add({d: 2}).fromNow(),  'čez 2 dni',  'in 2 days');\n    assert.equal(moment().add({d: 3}).fromNow(),  'čez 3 dni',  'in 3 days');\n    assert.equal(moment().add({d: 4}).fromNow(),  'čez 4 dni',  'in 4 days');\n    assert.equal(moment().add({d: 5}).fromNow(),  'čez 5 dni',  'in 5 days');\n\n    assert.equal(moment().add({M: 1}).fromNow(),  'čez en mesec',  'in a month');\n    assert.equal(moment().add({M: 2}).fromNow(),  'čez 2 meseca',  'in 2 months');\n    assert.equal(moment().add({M: 3}).fromNow(),  'čez 3 mesece',  'in 3 months');\n    assert.equal(moment().add({M: 4}).fromNow(),  'čez 4 mesece',  'in 4 months');\n    assert.equal(moment().add({M: 5}).fromNow(),  'čez 5 mesecev', 'in 5 months');\n\n    assert.equal(moment().add({y: 1}).fromNow(),  'čez eno leto', 'in a year');\n    assert.equal(moment().add({y: 2}).fromNow(),  'čez 2 leti',   'in 2 years');\n    assert.equal(moment().add({y: 3}).fromNow(),  'čez 3 leta',   'in 3 years');\n    assert.equal(moment().add({y: 4}).fromNow(),  'čez 4 leta',   'in 4 years');\n    assert.equal(moment().add({y: 5}).fromNow(),  'čez 5 let',    'in 5 years');\n\n    assert.equal(moment().subtract({s: 30}).fromNow(), 'pred nekaj sekundami', 'a few seconds ago');\n\n    assert.equal(moment().subtract({m: 1}).fromNow(),  'pred eno minuto', 'a minute ago');\n    assert.equal(moment().subtract({m: 2}).fromNow(),  'pred 2 minutama', '2 minutes ago');\n    assert.equal(moment().subtract({m: 3}).fromNow(),  'pred 3 minutami', '3 minutes ago');\n    assert.equal(moment().subtract({m: 4}).fromNow(),  'pred 4 minutami', '4 minutes ago');\n    assert.equal(moment().subtract({m: 5}).fromNow(),  'pred 5 minutami', '5 minutes ago');\n\n    assert.equal(moment().subtract({h: 1}).fromNow(),  'pred eno uro', 'an hour ago');\n    assert.equal(moment().subtract({h: 2}).fromNow(),  'pred 2 urama', '2 hours ago');\n    assert.equal(moment().subtract({h: 3}).fromNow(),  'pred 3 urami', '3 hours ago');\n    assert.equal(moment().subtract({h: 4}).fromNow(),  'pred 4 urami', '4 hours ago');\n    assert.equal(moment().subtract({h: 5}).fromNow(),  'pred 5 urami', '5 hours ago');\n\n    assert.equal(moment().subtract({d: 1}).fromNow(),  'pred enim dnem', 'a day ago');\n    assert.equal(moment().subtract({d: 2}).fromNow(),  'pred 2 dnevoma', '2 days ago');\n    assert.equal(moment().subtract({d: 3}).fromNow(),  'pred 3 dnevi',   '3 days ago');\n    assert.equal(moment().subtract({d: 4}).fromNow(),  'pred 4 dnevi',   '4 days ago');\n    assert.equal(moment().subtract({d: 5}).fromNow(),  'pred 5 dnevi',   '5 days ago');\n\n    assert.equal(moment().subtract({M: 1}).fromNow(),  'pred enim mesecem', 'a month ago');\n    assert.equal(moment().subtract({M: 2}).fromNow(),  'pred 2 mesecema',   '2 months ago');\n    assert.equal(moment().subtract({M: 3}).fromNow(),  'pred 3 meseci',     '3 months ago');\n    assert.equal(moment().subtract({M: 4}).fromNow(),  'pred 4 meseci',     '4 months ago');\n    assert.equal(moment().subtract({M: 5}).fromNow(),  'pred 5 meseci',     '5 months ago');\n\n    assert.equal(moment().subtract({y: 1}).fromNow(),  'pred enim letom', 'a year ago');\n    assert.equal(moment().subtract({y: 2}).fromNow(),  'pred 2 letoma',   '2 years ago');\n    assert.equal(moment().subtract({y: 3}).fromNow(),  'pred 3 leti',     '3 years ago');\n    assert.equal(moment().subtract({y: 4}).fromNow(),  'pred 4 leti',     '4 years ago');\n    assert.equal(moment().subtract({y: 5}).fromNow(),  'pred 5 leti',     '5 years ago');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'danes ob 12:00',  'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'danes ob 12:25',  'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'danes ob 13:00',  'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'jutri ob 12:00',  'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'danes ob 11:00',  'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'včeraj ob 12:00', 'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n\n    function makeFormat(d) {\n        switch (d.day()) {\n            case 0:\n                return '[v] [nedeljo] [ob] LT';\n            case 3:\n                return '[v] [sredo] [ob] LT';\n            case 6:\n                return '[v] [soboto] [ob] LT';\n            case 1:\n            case 2:\n            case 4:\n            case 5:\n                return '[v] dddd [ob] LT';\n        }\n    }\n\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format(makeFormat(m)),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format(makeFormat(m)),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format(makeFormat(m)),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n\n    function makeFormat(d) {\n        switch (d.day()) {\n            case 0:\n                return '[prejšnjo] [nedeljo] [ob] LT';\n            case 3:\n                return '[prejšnjo] [sredo] [ob] LT';\n            case 6:\n                return '[prejšnjo] [soboto] [ob] LT';\n            case 1:\n            case 2:\n            case 4:\n            case 5:\n                return '[prejšnji] dddd [ob] LT';\n        }\n    }\n\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format(makeFormat(m)),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format(makeFormat(m)),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format(makeFormat(m)),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2011, 11, 26]).format('w ww wo'), '1 01 1.', 'Dec 26 2011 should be week 1');\n    assert.equal(moment([2012,  0,  1]).format('w ww wo'), '1 01 1.', 'Jan  1 2012 should be week 1');\n    assert.equal(moment([2012,  0,  2]).format('w ww wo'), '2 02 2.', 'Jan  2 2012 should be week 2');\n    assert.equal(moment([2012,  0,  8]).format('w ww wo'), '2 02 2.', 'Jan  8 2012 should be week 2');\n    assert.equal(moment([2012,  0,  9]).format('w ww wo'), '3 03 3.', 'Jan  9 2012 should be week 3');\n});\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/test/locale/sq.js",
    "content": "import {localeModule, test} from '../qunit';\nimport moment from '../../moment';\nlocaleModule('sq');\n\ntest('parse', function (assert) {\n    var i,\n        tests = 'Janar Jan_Shkurt Shk_Mars Mar_Prill Pri_Maj Maj_Qershor Qer_Korrik Kor_Gusht Gus_Shtator Sht_Tetor Tet_Nëntor Nën_Dhjetor Dhj'.split('_');\n\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, MMMM Do YYYY, HH:mm:ss',       'E Diel, Shkurt 14. 2010, 15:25:50'],\n            ['ddd, HH',                            'Die, 15'],\n            ['M Mo MM MMMM MMM',                   '2 2. 02 Shkurt Shk'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14. 14'],\n            ['d do dddd ddd dd',                   '0 0. E Diel Die D'],\n            ['DDD DDDo DDDD',                      '45 45. 045'],\n            ['w wo ww',                            '6 6. 06'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'MD MD'],\n            ['[the] DDDo [day of the year]',       'the 45. day of the year'],\n            ['LTS',                                '15:25:50'],\n            ['L',                                  '14/02/2010'],\n            ['LL',                                 '14 Shkurt 2010'],\n            ['LLL',                                '14 Shkurt 2010 15:25'],\n            ['LLLL',                               'E Diel, 14 Shkurt 2010 15:25'],\n            ['l',                                  '14/2/2010'],\n            ['ll',                                 '14 Shk 2010'],\n            ['lll',                                '14 Shk 2010 15:25'],\n            ['llll',                               'Die, 14 Shk 2010 15:25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('meridiem', function (assert) {\n    assert.equal(moment([2011, 2, 23,  0, 0]).format('A'), 'PD', 'before dawn');\n    assert.equal(moment([2011, 2, 23, 12, 0]).format('A'), 'MD', 'noon');\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1.', '1.');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2.', '2.');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3.', '3.');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4.', '4.');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5.', '5.');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6.', '6.');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7.', '7.');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8.', '8.');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9.', '9.');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10.', '10.');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11.', '11.');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12.', '12.');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13.', '13.');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14.', '14.');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15.', '15.');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16.', '16.');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17.', '17.');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18.', '18.');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19.', '19.');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20.', '20.');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21.', '21.');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22.', '22.');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23.', '23.');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24.', '24.');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25.', '25.');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26.', '26.');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27.', '27.');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28.', '28.');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29.', '29.');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30.', '30.');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31.', '31.');\n});\n\ntest('format month', function (assert) {\n    var i,\n        expected = 'Janar Jan_Shkurt Shk_Mars Mar_Prill Pri_Maj Maj_Qershor Qer_Korrik Kor_Gusht Gus_Shtator Sht_Tetor Tet_Nëntor Nën_Dhjetor Dhj'.split('_');\n\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var i,\n        expected = 'E Diel Die D_E Hënë Hën H_E Martë Mar Ma_E Mërkurë Mër Më_E Enjte Enj E_E Premte Pre P_E Shtunë Sht Sh'.split('_');\n\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'disa sekonda', '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'një minutë',      '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'një minutë',      '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 minuta',     '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 minuta',    '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'një orë',       '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'një orë',       '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 orë',       '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 orë',       '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 orë',      '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'një ditë',         '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'një ditë',         '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 ditë',        '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'një ditë',         '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 ditë',        '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 ditë',       '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'një muaj',       '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'një muaj',       '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'një muaj',       '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 muaj',      '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 muaj',      '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 muaj',      '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'një muaj',       '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 muaj',      '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'një vit',        '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 vite',       '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'një vit',        '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 vite',       '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'në disa sekonda',  'prefix');\n    assert.equal(moment(0).from(30000), 'disa sekonda më parë', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'disa sekonda më parë',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'në disa sekonda', 'in a few seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), 'në 5 ditë', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'Sot në 12:00',   'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'Sot në 12:25',   'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'Sot në 13:00',   'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'Nesër në 12:00', 'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'Sot në 11:00',   'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'Dje në 12:00',   'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('dddd [në] LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd [në] LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd [në] LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('dddd [e kaluar në] LT'),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd [e kaluar në] LT'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd [e kaluar në] LT'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2012, 0,  1]).format('w ww wo'), '52 52 52.', 'Jan  1 2012 should be week 52');\n    assert.equal(moment([2012, 0,  2]).format('w ww wo'),   '1 01 1.', 'Jan  2 2012 should be week 1');\n    assert.equal(moment([2012, 0,  8]).format('w ww wo'),   '1 01 1.', 'Jan  8 2012 should be week 1');\n    assert.equal(moment([2012, 0,  9]).format('w ww wo'),   '2 02 2.', 'Jan  9 2012 should be week 2');\n    assert.equal(moment([2012, 0, 15]).format('w ww wo'),   '2 02 2.', 'Jan 15 2012 should be week 2');\n});\n\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/test/locale/sr-cyrl.js",
    "content": "import {localeModule, test} from '../qunit';\nimport moment from '../../moment';\nlocaleModule('sr-cyrl');\n\ntest('parse', function (assert) {\n    var tests = 'јануар јан._фебруар феб._март мар._април апр._мај мај_јун јун_јул јул_август авг._септембар сеп._октобар окт._новембар нов._децембар дец.'.split('_'),\n        i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, Do MMMM YYYY, h:mm:ss a',      'недеља, 14. фебруар 2010, 3:25:50 pm'],\n            ['ddd, hA',                            'нед., 3PM'],\n            ['M Mo MM MMMM MMM',                   '2 2. 02 фебруар феб.'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14. 14'],\n            ['d do dddd ddd dd',                   '0 0. недеља нед. не'],\n            ['DDD DDDo DDDD',                      '45 45. 045'],\n            ['w wo ww',                            '7 7. 07'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'pm PM'],\n            ['[the] DDDo [day of the year]',       'the 45. day of the year'],\n            ['LTS',                                '15:25:50'],\n            ['L',                                  '14.02.2010'],\n            ['LL',                                 '14. фебруар 2010'],\n            ['LLL',                                '14. фебруар 2010 15:25'],\n            ['LLLL',                               'недеља, 14. фебруар 2010 15:25'],\n            ['l',                                  '14.2.2010'],\n            ['ll',                                 '14. феб. 2010'],\n            ['lll',                                '14. феб. 2010 15:25'],\n            ['llll',                               'нед., 14. феб. 2010 15:25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1.', '1.');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2.', '2.');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3.', '3.');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4.', '4.');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5.', '5.');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6.', '6.');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7.', '7.');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8.', '8.');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9.', '9.');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10.', '10.');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11.', '11.');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12.', '12.');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13.', '13.');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14.', '14.');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15.', '15.');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16.', '16.');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17.', '17.');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18.', '18.');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19.', '19.');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20.', '20.');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21.', '21.');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22.', '22.');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23.', '23.');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24.', '24.');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25.', '25.');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26.', '26.');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27.', '27.');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28.', '28.');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29.', '29.');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30.', '30.');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31.', '31.');\n});\n\ntest('format month', function (assert) {\n    var expected = 'јануар јан._фебруар феб._март мар._април апр._мај мај_јун јун_јул јул_август авг._септембар сеп._октобар окт._новембар нов._децембар дец.'.split('_'),\n        i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'недеља нед. не_понедељак пон. по_уторак уто. ут_среда сре. ср_четвртак чет. че_петак пет. пе_субота суб. су'.split('_'),\n        i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'неколико секунди', '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'један минут',   '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'један минут',   '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 минуте',     '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 минута',     '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'један сат',      '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'један сат',      '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 сата',        '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 сати',         '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 сати',        '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'дан',       '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'дан',       '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 дана',        '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'дан',       '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 дана',        '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 дана',       '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'месец',     '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'месец',     '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'месец',     '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 месеца',     '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 месеца',     '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 месеца',     '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'месец',     '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 месеци',    '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'годину',     '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 године',       '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'годину',     '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 година',        '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'за неколико секунди',  'prefix');\n    assert.equal(moment(0).from(30000), 'пре неколико секунди', 'prefix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'пре неколико секунди',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'за неколико секунди', 'in a few seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), 'за 5 дана', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'данас у 12:00',  'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'данас у 12:25',  'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'данас у 13:00',  'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'сутра у 12:00',  'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'данас у 11:00',  'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'јуче у 12:00',   'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n\n    function makeFormat(d) {\n        switch (d.day()) {\n            case 0:\n                return '[у] [недељу] [у] LT';\n            case 3:\n                return '[у] [среду] [у] LT';\n            case 6:\n                return '[у] [суботу] [у] LT';\n            case 1:\n            case 2:\n            case 4:\n            case 5:\n                return '[у] dddd [у] LT';\n        }\n    }\n\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format(makeFormat(m)),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format(makeFormat(m)),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format(makeFormat(m)),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n\n    function makeFormat(d) {\n        var lastWeekDay = [\n                '[прошле] [недеље] [у] LT',\n                '[прошлог] [понедељка] [у] LT',\n                '[прошлог] [уторка] [у] LT',\n                '[прошле] [среде] [у] LT',\n                '[прошлог] [четвртка] [у] LT',\n                '[прошлог] [петка] [у] LT',\n                '[прошле] [суботе] [у] LT'\n            ];\n\n        return lastWeekDay[d.day()];\n    }\n\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format(makeFormat(m)),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format(makeFormat(m)),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format(makeFormat(m)),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2011, 11, 26]).format('w ww wo'), '1 01 1.', 'Dec 26 2011 should be week 1');\n    assert.equal(moment([2012,  0,  1]).format('w ww wo'), '1 01 1.', 'Jan  1 2012 should be week 1');\n    assert.equal(moment([2012,  0,  2]).format('w ww wo'), '2 02 2.', 'Jan  2 2012 should be week 2');\n    assert.equal(moment([2012,  0,  8]).format('w ww wo'), '2 02 2.', 'Jan  8 2012 should be week 2');\n    assert.equal(moment([2012,  0,  9]).format('w ww wo'), '3 03 3.', 'Jan  9 2012 should be week 3');\n});\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/test/locale/sr.js",
    "content": "import {localeModule, test} from '../qunit';\nimport moment from '../../moment';\nlocaleModule('sr');\n\ntest('parse', function (assert) {\n    var tests = 'januar jan._februar feb._mart mar._april apr._maj maj_jun jun_jul jul_avgust avg._septembar sep._oktobar okt._novembar nov._decembar dec.'.split('_'),\n        i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, Do MMMM YYYY, h:mm:ss a',      'nedelja, 14. februar 2010, 3:25:50 pm'],\n            ['ddd, hA',                            'ned., 3PM'],\n            ['M Mo MM MMMM MMM',                   '2 2. 02 februar feb.'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14. 14'],\n            ['d do dddd ddd dd',                   '0 0. nedelja ned. ne'],\n            ['DDD DDDo DDDD',                      '45 45. 045'],\n            ['w wo ww',                            '7 7. 07'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'pm PM'],\n            ['[the] DDDo [day of the year]',       'the 45. day of the year'],\n            ['LTS',                                '15:25:50'],\n            ['L',                                  '14.02.2010'],\n            ['LL',                                 '14. februar 2010'],\n            ['LLL',                                '14. februar 2010 15:25'],\n            ['LLLL',                               'nedelja, 14. februar 2010 15:25'],\n            ['l',                                  '14.2.2010'],\n            ['ll',                                 '14. feb. 2010'],\n            ['lll',                                '14. feb. 2010 15:25'],\n            ['llll',                               'ned., 14. feb. 2010 15:25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1.', '1.');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2.', '2.');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3.', '3.');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4.', '4.');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5.', '5.');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6.', '6.');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7.', '7.');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8.', '8.');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9.', '9.');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10.', '10.');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11.', '11.');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12.', '12.');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13.', '13.');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14.', '14.');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15.', '15.');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16.', '16.');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17.', '17.');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18.', '18.');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19.', '19.');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20.', '20.');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21.', '21.');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22.', '22.');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23.', '23.');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24.', '24.');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25.', '25.');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26.', '26.');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27.', '27.');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28.', '28.');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29.', '29.');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30.', '30.');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31.', '31.');\n});\n\ntest('format month', function (assert) {\n    var expected = 'januar jan._februar feb._mart mar._april apr._maj maj_jun jun_jul jul_avgust avg._septembar sep._oktobar okt._novembar nov._decembar dec.'.split('_'),\n        i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'nedelja ned. ne_ponedeljak pon. po_utorak uto. ut_sreda sre. sr_četvrtak čet. če_petak pet. pe_subota sub. su'.split('_'),\n        i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'nekoliko sekundi', '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'jedan minut',   '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'jedan minut',   '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 minute',     '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 minuta',     '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'jedan sat',      '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'jedan sat',      '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 sata',        '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 sati',         '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 sati',        '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'dan',       '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'dan',       '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 dana',        '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'dan',       '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 dana',        '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 dana',       '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'mesec',     '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'mesec',     '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'mesec',     '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 meseca',     '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 meseca',     '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 meseca',     '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'mesec',     '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 meseci',    '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'godinu',     '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 godine',       '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'godinu',     '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 godina',        '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'za nekoliko sekundi',  'prefix');\n    assert.equal(moment(0).from(30000), 'pre nekoliko sekundi', 'prefix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'pre nekoliko sekundi',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'za nekoliko sekundi', 'in a few seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), 'za 5 dana', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'danas u 12:00',  'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'danas u 12:25',  'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'danas u 13:00',  'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'sutra u 12:00',  'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'danas u 11:00',  'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'juče u 12:00',   'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n\n    function makeFormat(d) {\n        switch (d.day()) {\n            case 0:\n                return '[u] [nedelju] [u] LT';\n            case 3:\n                return '[u] [sredu] [u] LT';\n            case 6:\n                return '[u] [subotu] [u] LT';\n            case 1:\n            case 2:\n            case 4:\n            case 5:\n                return '[u] dddd [u] LT';\n        }\n    }\n\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format(makeFormat(m)),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format(makeFormat(m)),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format(makeFormat(m)),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n\n    function makeFormat(d) {\n        var lastWeekDay = [\n                '[prošle] [nedelje] [u] LT',\n                '[prošlog] [ponedeljka] [u] LT',\n                '[prošlog] [utorka] [u] LT',\n                '[prošle] [srede] [u] LT',\n                '[prošlog] [četvrtka] [u] LT',\n                '[prošlog] [petka] [u] LT',\n                '[prošle] [subote] [u] LT'\n            ];\n\n        return lastWeekDay[d.day()];\n    }\n\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format(makeFormat(m)),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format(makeFormat(m)),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format(makeFormat(m)),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2011, 11, 26]).format('w ww wo'), '1 01 1.', 'Dec 26 2011 should be week 1');\n    assert.equal(moment([2012,  0,  1]).format('w ww wo'), '1 01 1.', 'Jan  1 2012 should be week 1');\n    assert.equal(moment([2012,  0,  2]).format('w ww wo'), '2 02 2.', 'Jan  2 2012 should be week 2');\n    assert.equal(moment([2012,  0,  8]).format('w ww wo'), '2 02 2.', 'Jan  8 2012 should be week 2');\n    assert.equal(moment([2012,  0,  9]).format('w ww wo'), '3 03 3.', 'Jan  9 2012 should be week 3');\n});\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/test/locale/ss.js",
    "content": "import {localeModule, test} from '../qunit';\nimport moment from '../../moment';\nlocaleModule('ss');\n\ntest('parse', function (assert) {\n    var tests = \"Bhimbidvwane Bhi_Indlovana Ina_Indlov'lenkhulu Inu_Mabasa Mab_Inkhwekhweti Ink_Inhlaba Inh_Kholwane Kho_Ingci Igc_Inyoni Iny_Imphala Imp_Lweti lwe_Ingongoni Igo\".split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('parse meridiem', function (assert) {\n    var i,\n        b = moment(),\n        meridiemTests = [\n            // h a patterns, expected hours, isValid\n            ['10 ekuseni',   10, true],\n            ['11 emini',   11, true],\n            ['3 entsambama',   15, true],\n            ['4 entsambama',   16, true],\n            ['6 entsambama',   18, true],\n            ['7 ebusuku',   19, true],\n            ['12 ebusuku',   0, true],\n            ['10 am',   10, false],\n            ['10 pm',   10, false]\n        ],\n        parsed;\n\n    // test that a formatted moment including meridiem string can be parsed back to the same moment\n    assert.ok(b.isSame(moment(b.format('h:mm:ss a'), 'h:mm:ss a', 'ss', true), 'seconds'), b.format('h:mm:ss a') + ' should be equal to ' + moment(b.format('h:mm:ss a'), 'h:mm:ss a', 'ss', true).format('h:mm:ss a'));\n\n    // test that a formatted moment having a meridiem string can be parsed with strict flag\n    assert.ok(moment(b.format('h:mm:ss a'), 'h:mm:ss a', 'ss', true).isValid(), b.format('h:mm:ss a') + ' should be parsed as valid');\n\n    for (i = 0; i < meridiemTests.length; i++) {\n        parsed = moment(meridiemTests[i][0], 'h a', 'ss', true);\n        assert.equal(parsed.isValid(), meridiemTests[i][2], 'validity for ' + meridiemTests[i][0]);\n        if (parsed.isValid()) {\n            assert.equal(parsed.hours(), meridiemTests[i][1], 'hours for ' + meridiemTests[i][0]);\n        }\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, MMMM Do YYYY, h:mm:ss a',      'Lisontfo, Indlovana 14 2010, 3:25:50 entsambama'],\n            ['ddd, h A',                            'Lis, 3 entsambama'],\n            ['M Mo MM MMMM MMM',                   '2 2 02 Indlovana Ina'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14 14'],\n            ['d do dddd ddd dd',                   '0 0 Lisontfo Lis Li'],\n            ['DDD DDDo DDDD',                      '45 45 045'],\n            ['w wo ww',                            '6 6 06'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'entsambama entsambama'],\n            ['[Lilanga] DDDo [lilanga lelinyaka]', 'Lilanga 45 lilanga lelinyaka'],\n            ['LTS',                                '3:25:50 entsambama'],\n            ['L',                                  '14/02/2010'],\n            ['LL',                                 '14 Indlovana 2010'],\n            ['LLL',                                '14 Indlovana 2010 3:25 entsambama'],\n            ['LLLL',                               'Lisontfo, 14 Indlovana 2010 3:25 entsambama'],\n            ['l',                                  '14/2/2010'],\n            ['ll',                                 '14 Ina 2010'],\n            ['lll',                                '14 Ina 2010 3:25 entsambama'],\n            ['llll',                               'Lis, 14 Ina 2010 3:25 entsambama']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1', '1');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2', '2');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3', '3');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4', '4');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5', '5');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6', '6');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7', '7');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8', '8');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9', '9');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10', '10');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11', '11');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12', '12');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13', '13');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14', '14');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15', '15');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16', '16');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17', '17');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18', '18');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19', '19');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20', '20');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21', '21');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22', '22');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23', '23');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24', '24');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25', '25');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26', '26');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27', '27');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28', '28');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29', '29');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30', '30');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31', '31');\n});\n\ntest('format month', function (assert) {\n    var expected = \"Bhimbidvwane Bhi_Indlovana Ina_Indlov'lenkhulu Inu_Mabasa Mab_Inkhwekhweti Ink_Inhlaba Inh_Kholwane Kho_Ingci Igc_Inyoni Iny_Imphala Imp_Lweti Lwe_Ingongoni Igo\".split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'Lisontfo Lis Li_Umsombuluko Umb Us_Lesibili Lsb Lb_Lesitsatfu Les Lt_Lesine Lsi Ls_Lesihlanu Lsh Lh_Umgcibelo Umg Ug'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'emizuzwana lomcane', '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'umzuzu',      '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'umzuzu',      '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 emizuzu',     '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 emizuzu',    '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'lihora',       '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'lihora',       '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 emahora',       '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 emahora',       '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 emahora',      '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'lilanga',         '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'lilanga',         '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 emalanga',        '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'lilanga',         '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 emalanga',        '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 emalanga',       '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'inyanga',       '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'inyanga',       '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'inyanga',       '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 tinyanga',      '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 tinyanga',      '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 tinyanga',      '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'inyanga',       '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 tinyanga',      '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'umnyaka',        '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 iminyaka',       '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'umnyaka',        '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 iminyaka',       '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'nga emizuzwana lomcane',  'prefix');\n    assert.equal(moment(0).from(30000), 'wenteka nga emizuzwana lomcane', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'wenteka nga emizuzwana lomcane',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'nga emizuzwana lomcane', 'in a few seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), 'nga 5 emalanga', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'Namuhla nga 12:00 emini',      'Today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'Namuhla nga 12:25 emini',      'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'Namuhla nga 1:00 emini',      'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'Kusasa nga 12:00 emini',   'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'Namuhla nga 11:00 emini',      'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'Itolo nga 12:00 emini',  'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('dddd [nga] LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd [nga] LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd [nga] LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('dddd [leliphelile] [nga] LT'),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd [leliphelile] [nga] LT'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd [leliphelile] [nga] LT'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2012, 0,  1]).format('w ww wo'), '52 52 52', 'Jan  1 2012 should be week 52');\n    assert.equal(moment([2012, 0,  2]).format('w ww wo'),   '1 01 1', 'Jan  4 2012 should be week 1');\n    assert.equal(moment([2012, 0,  8]).format('w ww wo'),   '1 01 1', 'Jan  8 2012 should be week 1');\n    assert.equal(moment([2012, 0,  9]).format('w ww wo'),   '2 02 2', 'Jan  9 2012 should be week 2');\n    assert.equal(moment([2012, 0, 15]).format('w ww wo'),   '2 02 2', 'Jan 15 2012 should be week 2');\n});\n\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/test/locale/sv.js",
    "content": "import {localeModule, test} from '../qunit';\nimport moment from '../../moment';\nlocaleModule('sv');\n\ntest('parse', function (assert) {\n    var tests = 'januari jan_februari feb_mars mar_april apr_maj maj_juni jun_juli jul_augusti aug_september sep_oktober okt_november nov_december dec'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, MMMM Do YYYY, h:mm:ss a',      'söndag, februari 14e 2010, 3:25:50 pm'],\n            ['ddd, hA',                            'sön, 3PM'],\n            ['M Mo MM MMMM MMM',                   '2 2a 02 februari feb'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14e 14'],\n            ['d do dddd ddd dd',                   '0 0e söndag sön sö'],\n            ['DDD DDDo DDDD',                      '45 45e 045'],\n            ['w wo ww',                            '6 6e 06'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'pm PM'],\n            ['[the] DDDo [day of the year]',       'the 45e day of the year'],\n            ['LTS',                                '15:25:50'],\n            ['L',                                  '2010-02-14'],\n            ['LL',                                 '14 februari 2010'],\n            ['LLL',                                '14 februari 2010 kl. 15:25'],\n            ['LLLL',                               'söndag 14 februari 2010 kl. 15:25'],\n            ['l',                                  '2010-2-14'],\n            ['ll',                                 '14 feb 2010'],\n            ['lll',                                '14 feb 2010 15:25'],\n            ['llll',                               'sön 14 feb 2010 15:25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1a', '1a');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2a', '2a');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3e', '3e');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4e', '4e');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5e', '5e');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6e', '6e');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7e', '7e');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8e', '8e');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9e', '9e');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10e', '10e');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11e', '11e');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12e', '12e');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13e', '13e');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14e', '14e');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15e', '15e');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16e', '16e');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17e', '17e');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18e', '18e');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19e', '19e');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20e', '20e');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21a', '21a');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22a', '22a');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23e', '23e');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24e', '24e');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25e', '25e');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26e', '26e');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27e', '27e');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28e', '28e');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29e', '29e');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30e', '30e');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31a', '31a');\n});\n\ntest('format month', function (assert) {\n    var expected = 'januari jan_februari feb_mars mar_april apr_maj maj_juni jun_juli jul_augusti aug_september sep_oktober okt_november nov_december dec'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'söndag sön sö_måndag mån må_tisdag tis ti_onsdag ons on_torsdag tor to_fredag fre fr_lördag lör lö'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'några sekunder', '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'en minut',      '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'en minut',      '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 minuter',     '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 minuter',    '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'en timme',       '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'en timme',       '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 timmar',       '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 timmar',       '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 timmar',      '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'en dag',         '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'en dag',         '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 dagar',        '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'en dag',         '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 dagar',        '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 dagar',       '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'en månad',       '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'en månad',       '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'en månad',       '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 månader',      '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 månader',      '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 månader',      '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'en månad',       '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 månader',      '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'ett år',        '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 år',       '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'ett år',        '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 år',       '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'om några sekunder',  'prefix');\n    assert.equal(moment(0).from(30000), 'för några sekunder sedan', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'för några sekunder sedan',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'om några sekunder', 'in a few seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), 'om 5 dagar', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'Idag 12:00',     'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'Idag 12:25',     'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'Idag 13:00',     'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'Imorgon 12:00',  'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'Idag 11:00',     'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'Igår 12:00',     'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('[På] dddd LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[På] dddd LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[På] dddd LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('[I] dddd[s] LT'),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[I] dddd[s] LT'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[I] dddd[s] LT'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2012, 0,  1]).format('w ww wo'), '52 52 52a', 'Jan  1 2012 should be week 52');\n    assert.equal(moment([2012, 0,  2]).format('w ww wo'),   '1 01 1a', 'Jan  2 2012 should be week 1');\n    assert.equal(moment([2012, 0,  8]).format('w ww wo'),   '1 01 1a', 'Jan  8 2012 should be week 1');\n    assert.equal(moment([2012, 0,  9]).format('w ww wo'),   '2 02 2a', 'Jan  9 2012 should be week 2');\n    assert.equal(moment([2012, 0, 15]).format('w ww wo'),   '2 02 2a', 'Jan 15 2012 should be week 2');\n});\n\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/test/locale/sw.js",
    "content": "import {localeModule, test} from '../qunit';\nimport moment from '../../moment';\nlocaleModule('sw');\n\ntest('parse', function (assert) {\n    var tests = 'Januari Jan_Februari Feb_Machi Mac_Aprili Apr_Mei Mei_Juni Jun_Julai Jul_Agosti Ago_Septemba Sep_Oktoba Okt_Novemba Nov_Desemba Des'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, MMMM Do YYYY, h:mm:ss a',      'Jumapili, Februari 14 2010, 3:25:50 pm'],\n            ['ddd, hA',                            'Jpl, 3PM'],\n            ['M Mo MM MMMM MMM',                   '2 2 02 Februari Feb'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14 14'],\n            ['d do dddd ddd dd',                   '0 0 Jumapili Jpl J2'],\n            ['DDD DDDo DDDD',                      '45 45 045'],\n            ['w wo ww',                            '7 7 07'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'pm PM'],\n            ['[siku] DDDo [ya mwaka]',             'siku 45 ya mwaka'],\n            ['LTS',                                '15:25:50'],\n            ['L',                                  '14.02.2010'],\n            ['LL',                                 '14 Februari 2010'],\n            ['LLL',                                '14 Februari 2010 15:25'],\n            ['LLLL',                               'Jumapili, 14 Februari 2010 15:25'],\n            ['l',                                  '14.2.2010'],\n            ['ll',                                 '14 Feb 2010'],\n            ['lll',                                '14 Feb 2010 15:25'],\n            ['llll',                               'Jpl, 14 Feb 2010 15:25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1', '1');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2', '2');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3', '3');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4', '4');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5', '5');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6', '6');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7', '7');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8', '8');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9', '9');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10', '10');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11', '11');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12', '12');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13', '13');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14', '14');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15', '15');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16', '16');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17', '17');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18', '18');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19', '19');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20', '20');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21', '21');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22', '22');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23', '23');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24', '24');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25', '25');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26', '26');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27', '27');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28', '28');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29', '29');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30', '30');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31', '31');\n});\n\ntest('format month', function (assert) {\n    var expected = 'Januari Jan_Februari Feb_Machi Mac_Aprili Apr_Mei Mei_Juni Jun_Julai Jul_Agosti Ago_Septemba Sep_Oktoba Okt_Novemba Nov_Desemba Des'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'Jumapili Jpl J2_Jumatatu Jtat J3_Jumanne Jnne J4_Jumatano Jtan J5_Alhamisi Alh Al_Ijumaa Ijm Ij_Jumamosi Jmos J1'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'hivi punde',   '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'dakika moja',  '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'dakika moja',  '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  'dakika 2',     '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  'dakika 44',    '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'saa limoja',   '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'saa limoja',   '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  'masaa 2',      '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   'masaa 5',      '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  'masaa 21',     '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'siku moja',    '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'siku moja',    '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  'masiku 2',     '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'siku moja',    '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   'masiku 5',     '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  'masiku 25',    '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'mwezi mmoja',  '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'mwezi mmoja',  '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'mwezi mmoja',  '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  'miezi 2',      '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  'miezi 2',      '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  'miezi 3',      '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'mwezi mmoja',  '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   'miezi 5',      '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'mwaka mmoja',  '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), 'miaka 2',      '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'mwaka mmoja',  '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   'miaka 5',      '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'hivi punde baadaye',  'prefix');\n    assert.equal(moment(0).from(30000), 'tokea hivi punde', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'tokea hivi punde',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'hivi punde baadaye', 'in a few seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), 'masiku 5 baadaye', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n    assert.equal(moment(a).calendar(),                   'leo saa 12:00',      'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'leo saa 12:25',      'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'leo saa 13:00',      'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'kesho saa 12:00',    'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'leo saa 11:00',      'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'jana 12:00',         'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('[wiki ijayo] dddd [saat] LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[wiki ijayo] dddd [saat] LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[wiki ijayo] dddd [saat] LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('[wiki iliyopita] dddd [saat] LT'),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[wiki iliyopita] dddd [saat] LT'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[wiki iliyopita] dddd [saat] LT'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),      '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('weeks year starting sunday format', function (assert) {\n    assert.equal(moment([2011, 11, 26]).format('w ww wo'), '1 01 1', 'Dec 26 2011 should be week 1');\n    assert.equal(moment([2012,  0,  1]).format('w ww wo'), '1 01 1', 'Jan  1 2012 should be week 1');\n    assert.equal(moment([2012,  0,  2]).format('w ww wo'), '2 02 2', 'Jan  2 2012 should be week 2');\n    assert.equal(moment([2012,  0,  8]).format('w ww wo'), '2 02 2', 'Jan  8 2012 should be week 2');\n    assert.equal(moment([2012,  0,  9]).format('w ww wo'), '3 03 3', 'Jan  9 2012 should be week 3');\n});\n\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/test/locale/ta.js",
    "content": "import {localeModule, test} from '../qunit';\nimport moment from '../../moment';\nlocaleModule('ta');\n\ntest('parse', function (assert) {\n    var tests = 'ஜனவரி ஜனவரி_பிப்ரவரி பிப்ரவரி_மார்ச் மார்ச்_ஏப்ரல் ஏப்ரல்_மே மே_ஜூன் ஜூன்_ஜூலை ஜூலை_ஆகஸ்ட் ஆகஸ்ட்_செப்டெம்பர் செப்டெம்பர்_அக்டோபர் அக்டோபர்_நவம்பர் நவம்பர்_டிசம்பர் டிசம்பர்'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, MMMM Do YYYY, h:mm:ss a', 'ஞாயிற்றுக்கிழமை, பிப்ரவரி ௧௪வது ௨௦௧௦, ௩:௨௫:௫௦  எற்பாடு'],\n            ['ddd, hA',                       'ஞாயிறு, ௩ எற்பாடு'],\n            ['M Mo MM MMMM MMM',              '௨ ௨வது ௦௨ பிப்ரவரி பிப்ரவரி'],\n            ['YYYY YY',                       '௨௦௧௦ ௧௦'],\n            ['D Do DD',                       '௧௪ ௧௪வது ௧௪'],\n            ['d do dddd ddd dd',              '௦ ௦வது ஞாயிற்றுக்கிழமை ஞாயிறு ஞா'],\n            ['DDD DDDo DDDD',                 '௪௫ ௪௫வது ௦௪௫'],\n            ['w wo ww',                       '௮ ௮வது ௦௮'],\n            ['h hh',                          '௩ ௦௩'],\n            ['H HH',                          '௧௫ ௧௫'],\n            ['m mm',                          '௨௫ ௨௫'],\n            ['s ss',                          '௫௦ ௫௦'],\n            ['a A',                           ' எற்பாடு  எற்பாடு'],\n            ['[ஆண்டின்] DDDo  [நாள்]', 'ஆண்டின் ௪௫வது  நாள்'],\n            ['LTS',                           '௧௫:௨௫:௫௦'],\n            ['L',                             '௧௪/௦௨/௨௦௧௦'],\n            ['LL',                            '௧௪ பிப்ரவரி ௨௦௧௦'],\n            ['LLL',                           '௧௪ பிப்ரவரி ௨௦௧௦, ௧௫:௨௫'],\n            ['LLLL',                          'ஞாயிற்றுக்கிழமை, ௧௪ பிப்ரவரி ௨௦௧௦, ௧௫:௨௫'],\n            ['l',                             '௧௪/௨/௨௦௧௦'],\n            ['ll',                            '௧௪ பிப்ரவரி ௨௦௧௦'],\n            ['lll',                           '௧௪ பிப்ரவரி ௨௦௧௦, ௧௫:௨௫'],\n            ['llll',                          'ஞாயிறு, ௧௪ பிப்ரவரி ௨௦௧௦, ௧௫:௨௫']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '௧வது', '௧வது');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '௨வது', '௨வது');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '௩வது', '௩வது');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '௪வது', '௪வது');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '௫வது', '௫வது');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '௬வது', '௬வது');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '௭வது', '௭வது');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '௮வது', '௮வது');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '௯வது', '௯வது');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '௧௦வது', '௧௦வது');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '௧௧வது', '௧௧வது');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '௧௨வது', '௧௨வது');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '௧௩வது', '௧௩வது');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '௧௪வது', '௧௪வது');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '௧௫வது', '௧௫வது');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '௧௬வது', '௧௬வது');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '௧௭வது', '௧௭வது');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '௧௮வது', '௧௮வது');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '௧௯வது', '௧௯வது');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '௨௦வது', '௨௦வது');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '௨௧வது', '௨௧வது');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '௨௨வது', '௨௨வது');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '௨௩வது', '௨௩வது');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '௨௪வது', '௨௪வது');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '௨௫வது', '௨௫வது');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '௨௬வது', '௨௬வது');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '௨௭வது', '௨௭வது');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '௨௮வது', '௨௮வது');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '௨௯வது', '௨௯வது');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '௩௦வது', '௩௦வது');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '௩௧வது', '௩௧வது');\n});\n\ntest('format month', function (assert) {\n    var expected = 'ஜனவரி ஜனவரி_பிப்ரவரி பிப்ரவரி_மார்ச் மார்ச்_ஏப்ரல் ஏப்ரல்_மே மே_ஜூன் ஜூன்_ஜூலை ஜூலை_ஆகஸ்ட் ஆகஸ்ட்_செப்டெம்பர் செப்டெம்பர்_அக்டோபர் அக்டோபர்_நவம்பர் நவம்பர்_டிசம்பர் டிசம்பர்'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'ஞாயிற்றுக்கிழமை ஞாயிறு ஞா_திங்கட்கிழமை திங்கள் தி_செவ்வாய்கிழமை செவ்வாய் செ_புதன்கிழமை புதன் பு_வியாழக்கிழமை வியாழன் வி_வெள்ளிக்கிழமை வெள்ளி வெ_சனிக்கிழமை சனி ச'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'ஒரு சில விநாடிகள்', '44 விநாடிகள் = ஒரு சில விநாடிகள்');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'ஒரு நிமிடம்',      '45 விநாடிகள் = ஒரு நிமிடம்');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'ஒரு நிமிடம்',      '89 விநாடிகள் = ஒரு நிமிடம்');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '௨ நிமிடங்கள்',     '90 விநாடிகள் = ௨ நிமிடங்கள்');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '௪௪ நிமிடங்கள்',    '44 நிமிடங்கள் = 44 நிமிடங்கள்');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'ஒரு மணி நேரம்',       '45 நிமிடங்கள் = ஒரு மணி நேரம்');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'ஒரு மணி நேரம்',       '89 நிமிடங்கள் = ஒரு மணி நேரம்');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '௨ மணி நேரம்',       '90 நிமிடங்கள் = ௨ மணி நேரம்');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '௫ மணி நேரம்',       '5 மணி நேரம் = 5 மணி நேரம்');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '௨௧ மணி நேரம்',      '௨௧ மணி நேரம் = ௨௧ மணி நேரம்');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'ஒரு நாள்',         '௨௨ மணி நேரம் = ஒரு நாள்');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'ஒரு நாள்',         '௩5 மணி நேரம் = ஒரு நாள்');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '௨ நாட்கள்',        '௩6 மணி நேரம் = ௨ days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'ஒரு நாள்',         '௧ நாள் = ஒரு நாள்');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '௫ நாட்கள்',        '5 நாட்கள் = 5 நாட்கள்');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '௨௫ நாட்கள்',       '௨5 நாட்கள் = ௨5 நாட்கள்');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'ஒரு மாதம்',       '௨6 நாட்கள் = ஒரு மாதம்');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'ஒரு மாதம்',       '௩0 நாட்கள் = ஒரு மாதம்');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'ஒரு மாதம்',       '45 நாட்கள் = ஒரு மாதம்');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '௨ மாதங்கள்',      '46 நாட்கள் = ௨ மாதங்கள்');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '௨ மாதங்கள்',      '75 நாட்கள் = ௨ மாதங்கள்');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '௩ மாதங்கள்',      '76 நாட்கள் = ௩ மாதங்கள்');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'ஒரு மாதம்',       '௧ மாதம் = ஒரு மாதம்');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '௫ மாதங்கள்',      '5 மாதங்கள் = 5 மாதங்கள்');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'ஒரு வருடம்',        '௩45 நாட்கள் = ஒரு வருடம்');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '௨ ஆண்டுகள்',       '548 நாட்கள் = ௨ ஆண்டுகள்');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'ஒரு வருடம்',        '௧ வருடம் = ஒரு வருடம்');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '௫ ஆண்டுகள்',       '5 ஆண்டுகள் = 5 ஆண்டுகள்');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'ஒரு சில விநாடிகள் இல்',  'prefix');\n    assert.equal(moment(0).from(30000), 'ஒரு சில விநாடிகள் முன்', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'ஒரு சில விநாடிகள் முன்',  'இப்போது இருந்து கடந்த காலத்தில் காட்ட வேண்டும்');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'ஒரு சில விநாடிகள் இல்', 'ஒரு சில விநாடிகள் இல்');\n    assert.equal(moment().add({d: 5}).fromNow(), '௫ நாட்கள் இல்', '5 நாட்கள் இல்');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'இன்று ௧௨:௦௦',   'இன்று  12:00');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'இன்று ௧௨:௨௫',   'இன்று  12:25');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'இன்று ௧௩:௦௦',   'இன்று  13:00');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'நாளை ௧௨:௦௦',    'நாளை  12:00');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'இன்று ௧௧:௦௦',   'இன்று  11:00');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'நேற்று ௧௨:௦௦',  'நேற்று  12:00');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('dddd, LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd, LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd, LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('[கடந்த வாரம்] dddd, LT'),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[கடந்த வாரம்] dddd, LT'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[கடந்த வாரம்] dddd, LT'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('meridiem', function (assert) {\n    assert.equal(moment([2011, 2, 23,  0, 30]).format('a'), ' யாமம்', '(after) midnight');\n    assert.equal(moment([2011, 2, 23,  2, 30]).format('a'), ' வைகறை', 'before dawn');\n    assert.equal(moment([2011, 2, 23,  9, 30]).format('a'), ' காலை', 'morning');\n    assert.equal(moment([2011, 2, 23, 14, 30]).format('a'), ' எற்பாடு', 'during day');\n    assert.equal(moment([2011, 2, 23, 17, 30]).format('a'), ' எற்பாடு', 'evening');\n    assert.equal(moment([2011, 2, 23, 19, 30]).format('a'), ' மாலை', 'late evening');\n    assert.equal(moment([2011, 2, 23, 23, 30]).format('a'), ' யாமம்', '(before) midnight');\n});\n\n\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/test/locale/te.js",
    "content": "import {localeModule, test} from '../qunit';\nimport moment from '../../moment';\nlocaleModule('te');\n\ntest('parse', function (assert) {\n    var tests = 'జనవరి జన._ఫిబ్రవరి ఫిబ్ర._మార్చి మార్చి_ఏప్రిల్ ఏప్రి._మే మే_జూన్ జూన్_జూలై జూలై_ఆగస్టు ఆగ._సెప్టెంబర్ సెప్._అక్టోబర్ అక్టో._నవంబర్ నవ._డిసెంబర్ డిసె.'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, Do తేదీ MMMM YYYY, a h:mm:ss',  'ఆదివారం, 14వ తేదీ ఫిబ్రవరి 2010, మధ్యాహ్నం 3:25:50'],\n            ['ddd, a h గంటలు',                 'ఆది, మధ్యాహ్నం 3 గంటలు'],\n            ['M Mo నెల MM MMMM MMM',                   '2 2వ నెల 02 ఫిబ్రవరి ఫిబ్ర.'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14వ 14'],\n            ['d do dddd ddd dd',                   '0 0వ ఆదివారం ఆది ఆ'],\n            ['DDD DDDo DDDD',                      '45 45వ 045'],\n            ['w wo ww',                            '8 8వ 08'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'మధ్యాహ్నం మధ్యాహ్నం'],\n            ['LTS',                                'మధ్యాహ్నం 3:25:50'],\n            ['L',                                  '14/02/2010'],\n            ['LL',                                 '14 ఫిబ్రవరి 2010'],\n            ['LLL',                                '14 ఫిబ్రవరి 2010, మధ్యాహ్నం 3:25'],\n            ['LLLL',                               'ఆదివారం, 14 ఫిబ్రవరి 2010, మధ్యాహ్నం 3:25'],\n            ['l',                                  '14/2/2010'],\n            ['ll',                                 '14 ఫిబ్ర. 2010'],\n            ['lll',                                '14 ఫిబ్ర. 2010, మధ్యాహ్నం 3:25'],\n            ['llll',                               'ఆది, 14 ఫిబ్ర. 2010, మధ్యాహ్నం 3:25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1వ', '1వ');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2వ', '2వ');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3వ', '3వ');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4వ', '4వ');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5వ', '5వ');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6వ', '6వ');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7వ', '7వ');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8వ', '8వ');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9వ', '9వ');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10వ', '10వ');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11వ', '11వ');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12వ', '12వ');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13వ', '13వ');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14వ', '14వ');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15వ', '15వ');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16వ', '16వ');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17వ', '17వ');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18వ', '18వ');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19వ', '19వ');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20వ', '20వ');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21వ', '21వ');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22వ', '22వ');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23వ', '23వ');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24వ', '24వ');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25వ', '25వ');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26వ', '26వ');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27వ', '27వ');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28వ', '28వ');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29వ', '29వ');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30వ', '30వ');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31వ', '31వ');\n});\n\ntest('format month', function (assert) {\n    var expected = 'జనవరి జన._ఫిబ్రవరి ఫిబ్ర._మార్చి మార్చి_ఏప్రిల్ ఏప్రి._మే మే_జూన్ జూన్_జూలై జూలై_ఆగస్టు ఆగ._సెప్టెంబర్ సెప్._అక్టోబర్ అక్టో._నవంబర్ నవ._డిసెంబర్ డిసె.'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'ఆదివారం ఆది ఆ_సోమవారం సోమ సో_మంగళవారం మంగళ మం_బుధవారం బుధ బు_గురువారం గురు గు_శుక్రవారం శుక్ర శు_శనివారం శని శ'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'కొన్ని క్షణాలు', '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'ఒక నిమిషం',      '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'ఒక నిమిషం',      '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 నిమిషాలు',     '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 నిమిషాలు',    '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'ఒక గంట',       '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'ఒక గంట',       '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 గంటలు',       '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 గంటలు',       '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 గంటలు',      '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'ఒక రోజు',         '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'ఒక రోజు',         '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 రోజులు',        '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'ఒక రోజు',         '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 రోజులు',        '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 రోజులు',       '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'ఒక నెల',       '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'ఒక నెల',       '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'ఒక నెల',       '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 నెలలు',      '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 నెలలు',      '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 నెలలు',      '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'ఒక నెల',       '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 నెలలు',      '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'ఒక సంవత్సరం',        '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 సంవత్సరాలు',       '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'ఒక సంవత్సరం',        '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 సంవత్సరాలు',       '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'కొన్ని క్షణాలు లో',  'prefix');\n    assert.equal(moment(0).from(30000), 'కొన్ని క్షణాలు క్రితం', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'కొన్ని క్షణాలు క్రితం',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'కొన్ని క్షణాలు లో', 'కొన్ని క్షణాలు లో');\n    assert.equal(moment().add({d: 5}).fromNow(), '5 రోజులు లో', '5 రోజులు లో');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'నేడు మధ్యాహ్నం 12:00',   'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'నేడు మధ్యాహ్నం 12:25',   'Now plus 25 min');\n    assert.equal(moment(a).add({h: 3}).calendar(),       'నేడు మధ్యాహ్నం 3:00',    'Now plus 3 hours');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'రేపు మధ్యాహ్నం 12:00',   'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'నేడు మధ్యాహ్నం 11:00',   'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'నిన్న మధ్యాహ్నం 12:00',  'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('dddd[,] LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd[,] LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd[,] LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('[గత] dddd[,] LT'),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[గత] dddd[,] LT'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[గత] dddd[,] LT'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('meridiem', function (assert) {\n    assert.equal(moment([2011, 2, 23,  2, 30]).format('a'), 'రాత్రి', 'before dawn');\n    assert.equal(moment([2011, 2, 23,  9, 30]).format('a'), 'ఉదయం', 'morning');\n    assert.equal(moment([2011, 2, 23, 14, 30]).format('a'), 'మధ్యాహ్నం', 'during day');\n    assert.equal(moment([2011, 2, 23, 17, 30]).format('a'), 'సాయంత్రం', 'evening');\n    assert.equal(moment([2011, 2, 23, 19, 30]).format('a'), 'సాయంత్రం', 'late evening');\n    assert.equal(moment([2011, 2, 23, 21, 20]).format('a'), 'రాత్రి', 'night');\n\n    assert.equal(moment([2011, 2, 23,  2, 30]).format('A'), 'రాత్రి', 'before dawn');\n    assert.equal(moment([2011, 2, 23,  9, 30]).format('A'), 'ఉదయం', 'morning');\n    assert.equal(moment([2011, 2, 23, 14, 30]).format('A'), 'మధ్యాహ్నం', ' during day');\n    assert.equal(moment([2011, 2, 23, 17, 30]).format('A'), 'సాయంత్రం', 'evening');\n    assert.equal(moment([2011, 2, 23, 19, 30]).format('A'), 'సాయంత్రం', 'late evening');\n    assert.equal(moment([2011, 2, 23, 21, 20]).format('A'), 'రాత్రి', 'night');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2012, 0,  1]).format('w ww wo'), '1 01 1వ', 'Jan  1 2012 should be week 1');\n    assert.equal(moment([2012, 0,  7]).format('w ww wo'), '1 01 1వ', 'Jan  7 2012 should be week 1');\n    assert.equal(moment([2012, 0,  8]).format('w ww wo'), '2 02 2వ', 'Jan  8 2012 should be week 2');\n    assert.equal(moment([2012, 0, 14]).format('w ww wo'), '2 02 2వ', 'Jan 14 2012 should be week 2');\n    assert.equal(moment([2012, 0, 15]).format('w ww wo'), '3 03 3వ', 'Jan 15 2012 should be week 3');\n});\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/test/locale/tet.js",
    "content": "import {localeModule, test} from '../qunit';\nimport moment from '../../moment';\nlocaleModule('tet');\n\ntest('parse', function (assert) {\n    var tests = 'Janeiru Jan_Fevereiru Fev_Marsu Mar_Abril Abr_Maiu Mai_Juniu Jun_Juliu Jul_Augustu Aug_Setembru Set_Outubru Out_Novembru Nov_Dezembru Dez'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, MMMM Do YYYY, h:mm:ss a',      'Domingu, Fevereiru 14th 2010, 3:25:50 pm'],\n            ['ddd, hA',                            'Dom, 3PM'],\n            ['M Mo MM MMMM MMM',                   '2 2nd 02 Fevereiru Fev'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14th 14'],\n            ['d do dddd ddd dd',                   '0 0th Domingu Dom Do'],\n            ['DDD DDDo DDDD',                      '45 45th 045'],\n            ['w wo ww',                            '6 6th 06'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'pm PM'],\n            ['[the] DDDo [day of the year]',       'the 45th day of the year'],\n            ['LTS',                                '15:25:50'],\n            ['L',                                  '14/02/2010'],\n            ['LL',                                 '14 Fevereiru 2010'],\n            ['LLL',                                '14 Fevereiru 2010 15:25'],\n            ['LLLL',                               'Domingu, 14 Fevereiru 2010 15:25'],\n            ['l',                                  '14/2/2010'],\n            ['ll',                                 '14 Fev 2010'],\n            ['lll',                                '14 Fev 2010 15:25'],\n            ['llll',                               'Dom, 14 Fev 2010 15:25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1st', '1st');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2nd', '2nd');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3rd', '3rd');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4th', '4th');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5th', '5th');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6th', '6th');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7th', '7th');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8th', '8th');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9th', '9th');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10th', '10th');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11th', '11th');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12th', '12th');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13th', '13th');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14th', '14th');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15th', '15th');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16th', '16th');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17th', '17th');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18th', '18th');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19th', '19th');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20th', '20th');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21st', '21st');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22nd', '22nd');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23rd', '23rd');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24th', '24th');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25th', '25th');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26th', '26th');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27th', '27th');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28th', '28th');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29th', '29th');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30th', '30th');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31st', '31st');\n});\n\ntest('format month', function (assert) {\n    var expected = 'Janeiru Jan_Fevereiru Fev_Marsu Mar_Abril Abr_Maiu Mai_Juniu Jun_Juliu Jul_Augustu Aug_Setembru Set_Outubru Out_Novembru Nov_Dezembru Dez'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'Domingu Dom Do_Segunda Seg Seg_Tersa Ters Te_Kuarta Kua Ku_Kinta Kint Ki_Sexta Sext Sex_Sabadu Sab Sa'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'minutu balun', '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'minutu ida',      '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'minutu ida',      '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  'minutus 2',     '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  'minutus 44',    '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'horas ida',       '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'horas ida',       '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  'horas 2',       '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   'horas 5',       '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  'horas 21',      '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'loron ida',         '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'loron ida',         '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  'loron 2',        '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'loron ida',         '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   'loron 5',        '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  'loron 25',       '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'fulan ida',       '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'fulan ida',       '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'fulan ida',       '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  'fulan 2',      '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  'fulan 2',      '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  'fulan 3',      '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'fulan ida',       '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   'fulan 5',      '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'tinan ida',        '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), 'tinan 2',       '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'tinan ida',        '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   'tinan 5',       '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'iha minutu balun',  'prefix');\n    assert.equal(moment(0).from(30000), 'minutu balun liuba', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'minutu balun liuba',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'iha minutu balun', 'in a few seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), 'iha loron 5', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'Ohin iha 12:00',      'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'Ohin iha 12:25',      'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'Ohin iha 13:00',      'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'Aban iha 12:00',   'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'Ohin iha 11:00',      'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'Horiseik iha 12:00',  'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('dddd [iha] LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd [iha] LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd [iha] LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('dddd [semana kotuk] [iha] LT'),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd [semana kotuk] [iha] LT'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd [semana kotuk] [iha] LT'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2012, 0,  1]).format('w ww wo'), '52 52 52nd', 'Jan  1 2012 should be week 52');\n    assert.equal(moment([2012, 0,  2]).format('w ww wo'),   '1 01 1st', 'Jan  2 2012 should be week 1');\n    assert.equal(moment([2012, 0,  8]).format('w ww wo'),   '1 01 1st', 'Jan  8 2012 should be week 1');\n    assert.equal(moment([2012, 0,  9]).format('w ww wo'),   '2 02 2nd', 'Jan  9 2012 should be week 2');\n    assert.equal(moment([2012, 0, 15]).format('w ww wo'),   '2 02 2nd', 'Jan 15 2012 should be week 2');\n});\n\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/test/locale/th.js",
    "content": "import {localeModule, test} from '../qunit';\nimport moment from '../../moment';\nlocaleModule('th');\n\ntest('parse', function (assert) {\n    var tests = 'มกราคม ม.ค._กุมภาพันธ์ ก.พ._มีนาคม มี.ค._เมษายน เม.ย._พฤษภาคม พ.ค._มิถุนายน มิ.ย._กรกฎาคม ก.ค._สิงหาคม ส.ค._กันยายน ก.ย._ตุลาคม ต.ค._พฤศจิกายน พ.ย._ธันวาคม ธ.ค.'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, Do MMMM YYYY, h:mm:ss a',      'อาทิตย์, 14 กุมภาพันธ์ 2010, 3:25:50 หลังเที่ยง'],\n            ['ddd, h A',                           'อาทิตย์, 3 หลังเที่ยง'],\n            ['M Mo MM MMMM MMM',                   '2 2 02 กุมภาพันธ์ ก.พ.'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14 14'],\n            ['d do dddd ddd dd',                   '0 0 อาทิตย์ อาทิตย์ อา.'],\n            ['DDD DDDo DDDD',                      '45 45 045'],\n            ['w wo ww',                            '8 8 08'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'หลังเที่ยง หลังเที่ยง'],\n            ['[the] DDDo [day of the year]',       'the 45 day of the year'],\n            ['LTS',                                '15:25:50'],\n            ['L',                                  '14/02/2010'],\n            ['LL',                                 '14 กุมภาพันธ์ 2010'],\n            ['LLL',                                '14 กุมภาพันธ์ 2010 เวลา 15:25'],\n            ['LLLL',                               'วันอาทิตย์ที่ 14 กุมภาพันธ์ 2010 เวลา 15:25'],\n            ['l',                                  '14/2/2010'],\n            ['ll',                                 '14 ก.พ. 2010'],\n            ['lll',                                '14 ก.พ. 2010 เวลา 15:25'],\n            ['llll',                               'วันอาทิตย์ที่ 14 ก.พ. 2010 เวลา 15:25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format month', function (assert) {\n    var expected = 'มกราคม ม.ค._กุมภาพันธ์ ก.พ._มีนาคม มี.ค._เมษายน เม.ย._พฤษภาคม พ.ค._มิถุนายน มิ.ย._กรกฎาคม ก.ค._สิงหาคม ส.ค._กันยายน ก.ย._ตุลาคม ต.ค._พฤศจิกายน พ.ย._ธันวาคม ธ.ค.'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'อาทิตย์ อาทิตย์ อา._จันทร์ จันทร์ จ._อังคาร อังคาร อ._พุธ พุธ พ._พฤหัสบดี พฤหัส พฤ._ศุกร์ ศุกร์ ศ._เสาร์ เสาร์ ส.'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'ไม่กี่วินาที',   '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  '1 นาที', '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  '1 นาที', '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 นาที',  '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 นาที', '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  '1 ชั่วโมง', '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  '1 ชั่วโมง', '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 ชั่วโมง',  '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 ชั่วโมง',  '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 ชั่วโมง', '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  '1 วัน',   '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  '1 วัน',   '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 วัน',   '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   '1 วัน',   '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 วัน',   '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 วัน',  '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  '1 เดือน', '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  '1 เดือน', '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  '1 เดือน', '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 เดือน',  '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 เดือน',  '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 เดือน',  '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   '1 เดือน', '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 เดือน',  '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), '1 ปี',   '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 ปี',   '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   '1 ปี',   '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 ปี',   '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'อีก ไม่กี่วินาที',  'prefix');\n    assert.equal(moment(0).from(30000), 'ไม่กี่วินาทีที่แล้ว', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'ไม่กี่วินาทีที่แล้ว',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'อีก ไม่กี่วินาที', 'in a few seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), 'อีก 5 วัน', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'วันนี้ เวลา 12:00',      'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'วันนี้ เวลา 12:25',     'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'วันนี้ เวลา 13:00',      'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'พรุ่งนี้ เวลา 12:00',    'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'วันนี้ เวลา 11:00',      'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'เมื่อวานนี้ เวลา 12:00', 'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('dddd[หน้า เวลา] LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd[หน้า เวลา] LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd[หน้า เวลา] LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('[วัน]dddd[ที่แล้ว เวลา] LT'),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[วัน]dddd[ที่แล้ว เวลา] LT'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[วัน]dddd[ที่แล้ว เวลา] LT'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),      '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),      '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('weeks year starting sunday format', function (assert) {\n    assert.equal(moment([2012, 0,  1]).format('w ww wo'), '1 01 1', 'Jan  1 2012 should be week 1');\n    assert.equal(moment([2012, 0,  7]).format('w ww wo'), '1 01 1', 'Jan  7 2012 should be week 1');\n    assert.equal(moment([2012, 0,  8]).format('w ww wo'), '2 02 2', 'Jan  8 2012 should be week 2');\n    assert.equal(moment([2012, 0, 14]).format('w ww wo'), '2 02 2', 'Jan 14 2012 should be week 2');\n    assert.equal(moment([2012, 0, 15]).format('w ww wo'), '3 03 3', 'Jan 15 2012 should be week 3');\n});\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/test/locale/tl-ph.js",
    "content": "import {localeModule, test} from '../qunit';\nimport moment from '../../moment';\nlocaleModule('tl-ph');\n\ntest('parse', function (assert) {\n    var tests = 'Enero Ene_Pebrero Peb_Marso Mar_Abril Abr_Mayo May_Hunyo Hun_Hulyo Hul_Agosto Ago_Setyembre Set_Oktubre Okt_Nobyembre Nob_Disyembre Dis'.split('_'),\n        i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, MMMM Do YYYY, h:mm:ss a',      'Linggo, Pebrero 14 2010, 3:25:50 pm'],\n            ['ddd, hA',                            'Lin, 3PM'],\n            ['M Mo MM MMMM MMM',                   '2 2 02 Pebrero Peb'],\n            ['YYYY YY',                             '2010 10'],\n            ['D Do DD',                            '14 14 14'],\n            ['d do dddd ddd dd',                   '0 0 Linggo Lin Li'],\n            ['DDD DDDo DDDD',                      '45 45 045'],\n            ['w wo ww',                            '6 6 06'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'pm PM'],\n            ['[the] DDDo [day of the year]',       'the 45 day of the year'],\n            ['LTS',                                '15:25:50'],\n            ['L',                                  '02/14/2010'],\n            ['LL',                                 'Pebrero 14, 2010'],\n            ['LLL',                                'Pebrero 14, 2010 15:25'],\n            ['LLLL',                               'Linggo, Pebrero 14, 2010 15:25'],\n            ['l',                                  '2/14/2010'],\n            ['ll',                                 'Peb 14, 2010'],\n            ['lll',                                'Peb 14, 2010 15:25'],\n            ['llll',                               'Lin, Peb 14, 2010 15:25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1', '1');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2', '2');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3', '3');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4', '4');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5', '5');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6', '6');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7', '7');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8', '8');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9', '9');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10', '10');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11', '11');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12', '12');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13', '13');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14', '14');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15', '15');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16', '16');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17', '17');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18', '18');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19', '19');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20', '20');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21', '21');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22', '22');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23', '23');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24', '24');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25', '25');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26', '26');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27', '27');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28', '28');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29', '29');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30', '30');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31', '31');\n});\n\ntest('format month', function (assert) {\n    var expected = 'Enero Ene_Pebrero Peb_Marso Mar_Abril Abr_Mayo May_Hunyo Hun_Hulyo Hul_Agosto Ago_Setyembre Set_Oktubre Okt_Nobyembre Nob_Disyembre Dis'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'Linggo Lin Li_Lunes Lun Lu_Martes Mar Ma_Miyerkules Miy Mi_Huwebes Huw Hu_Biyernes Biy Bi_Sabado Sab Sab'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'ilang segundo', '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'isang minuto',   '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'isang minuto',   '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 minuto',  '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 minuto', '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'isang oras',    '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'isang oras',    '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 oras',    '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 oras',    '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 oras',   '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'isang araw',      '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'isang araw',      '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 araw',     '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'isang araw',      '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 araw',     '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 araw',    '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'isang buwan',    '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'isang buwan',    '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'isang buwan',    '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 buwan',   '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 buwan',   '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 buwan',   '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'isang buwan',    '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 buwan',   '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'isang taon',     '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 taon',    '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'isang taon',     '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 taon',    '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'sa loob ng ilang segundo', 'prefix');\n    assert.equal(moment(0).from(30000), 'ilang segundo ang nakalipas', 'suffix');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'sa loob ng ilang segundo', 'in a few seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), 'sa loob ng 5 araw', 'in 5 days');\n});\n\ntest('same day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   '12:00 ngayong araw',    'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      '12:25 ngayong araw',    'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       '13:00 ngayong araw',    'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'Bukas ng 12:00',     'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  '11:00 ngayong araw',    'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  '12:00 kahapon',   'yesterday at the same time');\n});\n\ntest('same next week', function (assert) {\n    var i, m;\n\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('LT [sa susunod na] dddd'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('LT [sa susunod na] dddd'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('LT [sa susunod na] dddd'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('same last week', function (assert) {\n    var i, m;\n\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('LT [noong nakaraang] dddd'),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('LT [noong nakaraang] dddd'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('LT [noong nakaraang] dddd'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('same all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2012, 0,  1]).format('w ww wo'), '52 52 52', 'Jan  1 2012 should be week 52');\n    assert.equal(moment([2012, 0,  2]).format('w ww wo'), '1 01 1', 'Jan  2 2012 should be week 1');\n    assert.equal(moment([2012, 0,  8]).format('w ww wo'), '1 01 1', 'Jan  8 2012 should be week 1');\n    assert.equal(moment([2012, 0,  9]).format('w ww wo'),   '2 02 2', 'Jan  9 2012 should be week 2');\n    assert.equal(moment([2012, 0, 15]).format('w ww wo'),   '2 02 2', 'Jan 15 2012 should be week 2');\n});\n\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/test/locale/tlh.js",
    "content": "import {localeModule, test} from '../qunit';\nimport moment from '../../moment';\nlocaleModule('tlh');\n\n//Current parsing method doesn't allow parsing correctly months 10, 11 and 12.\n/*\n * test('parse', function (assert) {\n    var tests = 'tera’ jar wa’.jar wa’_tera’ jar cha’.jar cha’_tera’ jar wej.jar wej_tera’ jar loS.jar loS_tera’ jar vagh.jar vagh_tera’ jar jav.jar jav_tera’ jar Soch.jar Soch_tera’ jar chorgh.jar chorgh_tera’ jar Hut.jar Hut_tera’ jar wa’maH.jar wa’maH_tera’ jar wa’maH wa’.jar wa’maH wa’_tera’ jar wa’maH cha’.jar wa’maH cha’'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split('.');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n*/\ntest('format', function (assert) {\n    var a = [\n            ['dddd, MMMM Do YYYY, h:mm:ss a',      'lojmItjaj, tera’ jar cha’ 14. 2010, 3:25:50 pm'],\n            ['ddd, hA',                            'lojmItjaj, 3PM'],\n            ['M Mo MM MMMM MMM',                   '2 2. 02 tera’ jar cha’ jar cha’'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14. 14'],\n            ['d do dddd ddd dd',                   '0 0. lojmItjaj lojmItjaj lojmItjaj'],\n            ['DDD DDDo DDDD',                      '45 45. 045'],\n            ['w wo ww',                            '6 6. 06'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'pm PM'],\n            ['[DIS jaj] DDDo',                     'DIS jaj 45.'],\n            ['LTS',                                '15:25:50'],\n            ['L',                                  '14.02.2010'],\n            ['LL',                                 '14 tera’ jar cha’ 2010'],\n            ['LLL',                                '14 tera’ jar cha’ 2010 15:25'],\n            ['LLLL',                               'lojmItjaj, 14 tera’ jar cha’ 2010 15:25'],\n            ['l',                                  '14.2.2010'],\n            ['ll',                                 '14 jar cha’ 2010'],\n            ['lll',                                '14 jar cha’ 2010 15:25'],\n            ['llll',                               'lojmItjaj, 14 jar cha’ 2010 15:25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1.', '1.');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2.', '2.');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3.', '3.');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4.', '4.');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5.', '5.');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6.', '6.');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7.', '7.');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8.', '8.');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9.', '9.');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10.', '10.');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11.', '11.');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12.', '12.');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13.', '13.');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14.', '14.');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15.', '15.');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16.', '16.');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17.', '17.');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18.', '18.');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19.', '19.');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20.', '20.');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21.', '21.');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22.', '22.');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23.', '23.');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24.', '24.');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25.', '25.');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26.', '26.');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27.', '27.');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28.', '28.');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29.', '29.');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30.', '30.');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31.', '31.');\n});\n\ntest('format month', function (assert) {\n    var expected = 'tera’ jar wa’ jar wa’_tera’ jar cha’ jar cha’_tera’ jar wej jar wej_tera’ jar loS jar loS_tera’ jar vagh jar vagh_tera’ jar jav jar jav_tera’ jar Soch jar Soch_tera’ jar chorgh jar chorgh_tera’ jar Hut jar Hut_tera’ jar wa’maH jar wa’maH_tera’ jar wa’maH wa’ jar wa’maH wa’_tera’ jar wa’maH cha’ jar wa’maH cha’'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'lojmItjaj lojmItjaj lojmItjaj_DaSjaj DaSjaj DaSjaj_povjaj povjaj povjaj_ghItlhjaj ghItlhjaj ghItlhjaj_loghjaj loghjaj loghjaj_buqjaj buqjaj buqjaj_ghInjaj ghInjaj ghInjaj'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'puS lup',  '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'wa’ tup',        '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'wa’ tup',        '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  'cha’ tup',      '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  'loSmaH loS tup',     '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'wa’ rep',       '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'wa’ rep',       '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  'cha’ rep',     '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   'vagh rep',      '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  'cha’maH wa’ rep',     '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'wa’ jaj',       '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'wa’ jaj',       '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  'cha’ jaj',         '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'wa’ jaj',       '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   'vagh jaj',         '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  'cha’maH vagh jaj',        '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'wa’ jar',       '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'wa’ jar',       '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'wa’ jar',       '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  'cha’ jar',    '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  'cha’ jar',    '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  'wej jar',    '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'wa’ jar',       '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   'vagh jar',    '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'wa’ DIS',           '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), 'cha’ DIS',        '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'wa’ DIS',           '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   'vagh DIS',         '5 years = 5 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 112}), true), 'wa’vatlh wa’maH cha’ DIS',       '112 years = 112 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 122}), true), 'wa’vatlh cha’maH cha’ DIS',      '122 years = 122 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 213}), true), 'cha’vatlh wa’maH wej DIS',       '213 years = 213 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 223}), true), 'cha’vatlh cha’maH wej DIS',      '223 years = 223 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'puS lup pIq',  'suffix');\n    assert.equal(moment(0).from(30000), 'puS lup ret', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'puS lup ret',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'puS lup pIq', 'in a few seconds');\n    assert.equal(moment().add({h: 1}).fromNow(), 'wa’ rep pIq', 'in an hour');\n    assert.equal(moment().add({d: 5}).fromNow(), 'vagh leS', 'in 5 days');\n    assert.equal(moment().add({M: 2}).fromNow(), 'cha’ waQ', 'in 2 months');\n    assert.equal(moment().add({y: 1}).fromNow(), 'wa’ nem', 'in a year');\n    assert.equal(moment().add({s: -30}).fromNow(), 'puS lup ret', 'a few seconds ago');\n    assert.equal(moment().add({h: -1}).fromNow(), 'wa’ rep ret', 'an hour ago');\n    assert.equal(moment().add({d: -5}).fromNow(), 'vagh Hu’', '5 days ago');\n    assert.equal(moment().add({M: -2}).fromNow(), 'cha’ wen', '2 months ago');\n    assert.equal(moment().add({y: -1}).fromNow(), 'wa’ ben', 'a year ago');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'DaHjaj 12:00',     'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'DaHjaj 12:25',     'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'DaHjaj 13:00',     'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'wa’leS 12:00',     'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'DaHjaj 11:00',     'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'wa’Hu’ 12:00',     'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('LLL'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('LLL'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('LLL'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(), m.format('LLL'), 'Today - ' + i + ' days current time');\n\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(), m.format('LLL'), 'Today - ' + i + ' days beginning of day');\n\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(), m.format('LLL'), 'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2012, 0,  1]).format('w ww wo'), '52 52 52.', 'Jan  1 2012 should be week 52');\n    assert.equal(moment([2012, 0,  2]).format('w ww wo'),   '1 01 1.', 'Jan  2 2012 should be week 1');\n    assert.equal(moment([2012, 0,  8]).format('w ww wo'),   '1 01 1.', 'Jan  8 2012 should be week 1');\n    assert.equal(moment([2012, 0,  9]).format('w ww wo'),   '2 02 2.', 'Jan  9 2012 should be week 2');\n    assert.equal(moment([2012, 0, 15]).format('w ww wo'),   '2 02 2.', 'Jan 15 2012 should be week 2');\n});\n\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/test/locale/tr.js",
    "content": "import {localeModule, test} from '../qunit';\nimport moment from '../../moment';\nlocaleModule('tr');\n\ntest('parse', function (assert) {\n    var tests = 'Ocak Oca_Şubat Şub_Mart Mar_Nisan Nis_Mayıs May_Haziran Haz_Temmuz Tem_Ağustos Ağu_Eylül Eyl_Ekim Eki_Kasım Kas_Aralık Ara'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, MMMM Do YYYY, h:mm:ss a',      'Pazar, Şubat 14\\'üncü 2010, 3:25:50 pm'],\n            ['ddd, hA',                            'Paz, 3PM'],\n            ['M Mo MM MMMM MMM',                   '2 2\\'nci 02 Şubat Şub'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14\\'üncü 14'],\n            ['d do dddd ddd dd',                   '0 0\\'ıncı Pazar Paz Pz'],\n            ['DDD DDDo DDDD',                      '45 45\\'inci 045'],\n            ['w wo ww',                            '7 7\\'nci 07'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'pm PM'],\n            ['[yılın] DDDo [günü]',                'yılın 45\\'inci günü'],\n            ['LTS',                                '15:25:50'],\n            ['L',                                  '14.02.2010'],\n            ['LL',                                 '14 Şubat 2010'],\n            ['LLL',                                '14 Şubat 2010 15:25'],\n            ['LLLL',                               'Pazar, 14 Şubat 2010 15:25'],\n            ['l',                                  '14.2.2010'],\n            ['ll',                                 '14 Şub 2010'],\n            ['lll',                                '14 Şub 2010 15:25'],\n            ['llll',                               'Paz, 14 Şub 2010 15:25']\n        ],\n        DDDo = [\n            [359, '360\\'ıncı'],\n            [199, '200\\'üncü'],\n            [149, '150\\'nci']\n        ],\n        dt = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        DDDoDt,\n        i;\n\n    for (i = 0; i < a.length; i++) {\n        assert.equal(dt.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n    for (i = 0; i < DDDo.length; i++) {\n        DDDoDt = moment([2010]);\n        assert.equal(DDDoDt.add(DDDo[i][0], 'days').format('DDDo'), DDDo[i][1], DDDo[i][0] + ' ---> ' + DDDo[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1\\'inci', '1st');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2\\'nci', '2nd');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3\\'üncü', '3rd');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4\\'üncü', '4th');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5\\'inci', '5th');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6\\'ncı', '6th');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7\\'nci', '7th');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8\\'inci', '8th');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9\\'uncu', '9th');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10\\'uncu', '10th');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11\\'inci', '11th');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12\\'nci', '12th');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13\\'üncü', '13th');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14\\'üncü', '14th');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15\\'inci', '15th');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16\\'ncı', '16th');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17\\'nci', '17th');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18\\'inci', '18th');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19\\'uncu', '19th');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20\\'nci', '20th');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21\\'inci', '21th');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22\\'nci', '22th');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23\\'üncü', '23th');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24\\'üncü', '24th');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25\\'inci', '25th');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26\\'ncı', '26th');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27\\'nci', '27th');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28\\'inci', '28th');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29\\'uncu', '29th');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30\\'uncu', '30th');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31\\'inci', '31st');\n});\n\ntest('format month', function (assert) {\n    var expected = 'Ocak Oca_Şubat Şub_Mart Mar_Nisan Nis_Mayıs May_Haziran Haz_Temmuz Tem_Ağustos Ağu_Eylül Eyl_Ekim Eki_Kasım Kas_Aralık Ara'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'Pazar Paz Pz_Pazartesi Pts Pt_Salı Sal Sa_Çarşamba Çar Ça_Perşembe Per Pe_Cuma Cum Cu_Cumartesi Cts Ct'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'birkaç saniye', '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'bir dakika',      '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'bir dakika',      '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 dakika',     '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 dakika',    '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'bir saat',       '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'bir saat',       '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 saat',       '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 saat',       '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 saat',      '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'bir gün',         '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'bir gün',         '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 gün',        '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'bir gün',         '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 gün',        '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 gün',       '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'bir ay',       '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'bir ay',       '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'bir ay',       '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 ay',      '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 ay',      '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 ay',      '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'bir ay',       '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 ay',      '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'bir yıl',        '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 yıl',       '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'bir yıl',        '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 yıl',       '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'birkaç saniye sonra',  'prefix');\n    assert.equal(moment(0).from(30000), 'birkaç saniye önce', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'birkaç saniye önce',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'birkaç saniye sonra', 'in a few seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), '5 gün sonra', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'bugün saat 12:00',     'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'bugün saat 12:25',     'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'bugün saat 13:00',     'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'yarın saat 12:00',     'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'bugün saat 11:00',     'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'dün 12:00',            'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('[haftaya] dddd [saat] LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[haftaya] dddd [saat] LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[haftaya] dddd [saat] LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('[geçen hafta] dddd [saat] LT'),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[geçen hafta] dddd [saat] LT'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[geçen hafta] dddd [saat] LT'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2011, 11, 26]).format('w ww wo'), '1 01 1\\'inci', 'Dec 26 2011 should be week 1');\n    assert.equal(moment([2012,  0,  1]).format('w ww wo'), '1 01 1\\'inci', 'Jan  1 2012 should be week 1');\n    assert.equal(moment([2012,  0,  2]).format('w ww wo'), '2 02 2\\'nci', 'Jan  2 2012 should be week 2');\n    assert.equal(moment([2012,  0,  8]).format('w ww wo'), '2 02 2\\'nci', 'Jan  8 2012 should be week 2');\n    assert.equal(moment([2012,  0,  9]).format('w ww wo'), '3 03 3\\'üncü', 'Jan  9 2012 should be week 3');\n});\n\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/test/locale/tzl.js",
    "content": "import {localeModule, test} from '../qunit';\nimport moment from '../../moment';\nlocaleModule('tzl');\n\ntest('parse', function (assert) {\n    var tests = 'Januar Jan_Fevraglh Fev_Març Mar_Avrïu Avr_Mai Mai_Gün Gün_Julia Jul_Guscht Gus_Setemvar Set_Listopäts Lis_Noemvar Noe_Zecemvar Zec'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, MMMM Do YYYY, h.mm.ss a',      'Súladi, Fevraglh 14. 2010, 3.25.50 d\\'o'],\n            ['ddd, hA',                            'Súl, 3D\\'O'],\n            ['M Mo MM MMMM MMM',                   '2 2. 02 Fevraglh Fev'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14. 14'],\n            ['d do dddd ddd dd',                   '0 0. Súladi Súl Sú'],\n            ['DDD DDDo DDDD',                      '45 45. 045'],\n            ['w wo ww',                            '6 6. 06'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'd\\'o D\\'O'],\n            ['[the] DDDo [day of the year]',       'the 45. day of the year'],\n            ['LTS',                                '15.25.50'],\n            ['L',                                  '14.02.2010'],\n            ['LL',                                 '14. Fevraglh dallas 2010'],\n            ['LLL',                                '14. Fevraglh dallas 2010 15.25'],\n            ['LLLL',                               'Súladi, li 14. Fevraglh dallas 2010 15.25'],\n            ['l',                                  '14.2.2010'],\n            ['ll',                                 '14. Fev dallas 2010'],\n            ['lll',                                '14. Fev dallas 2010 15.25'],\n            ['llll',                               'Súl, li 14. Fev dallas 2010 15.25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1.', '1.');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2.', '2.');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3.', '3.');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4.', '4.');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5.', '5.');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6.', '6.');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7.', '7.');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8.', '8.');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9.', '9.');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10.', '10.');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11.', '11.');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12.', '12.');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13.', '13.');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14.', '14.');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15.', '15.');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16.', '16.');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17.', '17.');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18.', '18.');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19.', '19.');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20.', '20.');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21.', '21.');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22.', '22.');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23.', '23.');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24.', '24.');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25.', '25.');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26.', '26.');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27.', '27.');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28.', '28.');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29.', '29.');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30.', '30.');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31.', '31.');\n});\n\ntest('format month', function (assert) {\n    var expected = 'Januar Jan_Fevraglh Fev_Març Mar_Avrïu Avr_Mai Mai_Gün Gün_Julia Jul_Guscht Gus_Setemvar Set_Listopäts Lis_Noemvar Noe_Zecemvar Zec'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'Súladi Súl Sú_Lúneçi Lún Lú_Maitzi Mai Ma_Márcuri Már Má_Xhúadi Xhú Xh_Viénerçi Vié Vi_Sáturi Sát Sá'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'viensas secunds', '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  '\\'n míut',      '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  '\\'n míut',      '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 míuts',     '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 míuts',    '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  '\\'n þora',       '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  '\\'n þora',       '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 þoras',       '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 þoras',       '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 þoras',      '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  '\\'n ziua',         '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  '\\'n ziua',         '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 ziuas',        '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   '\\'n ziua',         '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 ziuas',        '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 ziuas',       '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  '\\'n mes',       '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  '\\'n mes',       '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  '\\'n mes',       '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 mesen',      '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 mesen',      '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 mesen',      '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   '\\'n mes',       '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 mesen',      '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), '\\'n ar',        '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 ars',       '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   '\\'n ar',        '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 ars',       '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'osprei viensas secunds',  'prefix');\n    assert.equal(moment(0).from(30000), 'ja\\'iensas secunds', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'ja\\'iensas secunds',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'osprei viensas secunds', 'in a few seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), 'osprei 5 ziuas', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'oxhi à 12.00',      'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'oxhi à 12.25',      'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'oxhi à 13.00',      'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'demà à 12.00',      'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'oxhi à 11.00',      'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'ieiri à 12.00',     'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('dddd [à] LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd [à] LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd [à] LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('[sür el] dddd [lasteu à] LT'),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[sür el] dddd [lasteu à] LT'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[sür el] dddd [lasteu à] LT'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\n// Monday is the first day of the week.\n// The week that contains Jan 4th is the first week of the year.\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2012, 0,  1]).format('w ww wo'), '52 52 52.', 'Jan  1 2012 should be week 52');\n    assert.equal(moment([2012, 0,  2]).format('w ww wo'),   '1 01 1.', 'Jan  2 2012 should be week 1');\n    assert.equal(moment([2012, 0,  8]).format('w ww wo'),   '1 01 1.', 'Jan  8 2012 should be week 1');\n    assert.equal(moment([2012, 0,  9]).format('w ww wo'),   '2 02 2.', 'Jan  9 2012 should be week 2');\n    assert.equal(moment([2012, 0, 15]).format('w ww wo'),   '2 02 2.', 'Jan 15 2012 should be week 2');\n});\n\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/test/locale/tzm-latn.js",
    "content": "import {localeModule, test} from '../qunit';\nimport moment from '../../moment';\nlocaleModule('tzm-latn');\n\ntest('parse', function (assert) {\n    var tests = 'innayr innayr_brˤayrˤ brˤayrˤ_marˤsˤ marˤsˤ_ibrir ibrir_mayyw mayyw_ywnyw ywnyw_ywlywz ywlywz_ɣwšt ɣwšt_šwtanbir šwtanbir_ktˤwbrˤ ktˤwbrˤ_nwwanbir nwwanbir_dwjnbir dwjnbir'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, MMMM Do YYYY, h:mm:ss a',      'asamas, brˤayrˤ 14 2010, 3:25:50 pm'],\n            ['ddd, hA',                            'asamas, 3PM'],\n            ['M Mo MM MMMM MMM',                   '2 2 02 brˤayrˤ brˤayrˤ'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14 14'],\n            ['d do dddd ddd dd',                   '0 0 asamas asamas asamas'],\n            ['DDD DDDo DDDD',                      '45 45 045'],\n            ['w wo ww',                            '8 8 08'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'pm PM'],\n            ['[the] DDDo [day of the year]',       'the 45 day of the year'],\n            ['LTS',                                '15:25:50'],\n            ['L',                                  '14/02/2010'],\n            ['LL',                                 '14 brˤayrˤ 2010'],\n            ['LLL',                                '14 brˤayrˤ 2010 15:25'],\n            ['LLLL',                               'asamas 14 brˤayrˤ 2010 15:25'],\n            ['l',                                  '14/2/2010'],\n            ['ll',                                 '14 brˤayrˤ 2010'],\n            ['lll',                                '14 brˤayrˤ 2010 15:25'],\n            ['llll',                               'asamas 14 brˤayrˤ 2010 15:25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1', '1');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2', '2');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3', '3');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4', '4');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5', '5');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6', '6');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7', '7');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8', '8');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9', '9');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10', '10');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11', '11');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12', '12');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13', '13');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14', '14');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15', '15');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16', '16');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17', '17');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18', '18');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19', '19');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20', '20');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21', '21');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22', '22');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23', '23');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24', '24');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25', '25');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26', '26');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27', '27');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28', '28');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29', '29');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30', '30');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31', '31');\n});\n\ntest('format month', function (assert) {\n    var expected = 'innayr innayr_brˤayrˤ brˤayrˤ_marˤsˤ marˤsˤ_ibrir ibrir_mayyw mayyw_ywnyw ywnyw_ywlywz ywlywz_ɣwšt ɣwšt_šwtanbir šwtanbir_ktˤwbrˤ ktˤwbrˤ_nwwanbir nwwanbir_dwjnbir dwjnbir'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'asamas asamas asamas_aynas aynas aynas_asinas asinas asinas_akras akras akras_akwas akwas akwas_asimwas asimwas asimwas_asiḍyas asiḍyas asiḍyas'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'imik', '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'minuḍ',      '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'minuḍ',      '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 minuḍ',     '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 minuḍ',    '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'saɛa',       '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'saɛa',       '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 tassaɛin',       '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 tassaɛin',       '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 tassaɛin',      '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'ass',         '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'ass',         '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 ossan',        '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'ass',         '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 ossan',        '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 ossan',       '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'ayowr',       '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'ayowr',       '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'ayowr',       '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 iyyirn',      '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 iyyirn',      '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 iyyirn',      '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'ayowr',       '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 iyyirn',      '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'asgas',        '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 isgasn',       '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'asgas',        '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 isgasn',       '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'dadkh s yan imik',  'prefix');\n    assert.equal(moment(0).from(30000), 'yan imik', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'yan imik',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'dadkh s yan imik', 'in a few seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), 'dadkh s yan 5 ossan', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'asdkh g 12:00',   'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'asdkh g 12:25',   'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'asdkh g 13:00',   'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'aska g 12:00',    'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'asdkh g 11:00',   'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'assant g 12:00',  'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('dddd [g] LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd [g] LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd [g] LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('dddd [g] LT'),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd [g] LT'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd [g] LT'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2011, 11, 31]).format('w ww wo'), '1 01 1', 'Dec 31 2011 should be week 1');\n    assert.equal(moment([2012,  0,  6]).format('w ww wo'), '1 01 1', 'Jan  6 2012 should be week 1');\n    assert.equal(moment([2012,  0,  7]).format('w ww wo'), '2 02 2', 'Jan  7 2012 should be week 2');\n    assert.equal(moment([2012,  0, 13]).format('w ww wo'), '2 02 2', 'Jan 13 2012 should be week 2');\n    assert.equal(moment([2012,  0, 14]).format('w ww wo'), '3 03 3', 'Jan 14 2012 should be week 3');\n});\n\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/test/locale/tzm.js",
    "content": "import {localeModule, test} from '../qunit';\nimport moment from '../../moment';\nlocaleModule('tzm');\n\ntest('parse', function (assert) {\n    var tests = 'ⵉⵏⵏⴰⵢⵔ ⵉⵏⵏⴰⵢⵔ_ⴱⵕⴰⵢⵕ ⴱⵕⴰⵢⵕ_ⵎⴰⵕⵚ ⵎⴰⵕⵚ_ⵉⴱⵔⵉⵔ ⵉⴱⵔⵉⵔ_ⵎⴰⵢⵢⵓ ⵎⴰⵢⵢⵓ_ⵢⵓⵏⵢⵓ ⵢⵓⵏⵢⵓ_ⵢⵓⵍⵢⵓⵣ ⵢⵓⵍⵢⵓⵣ_ⵖⵓⵛⵜ ⵖⵓⵛⵜ_ⵛⵓⵜⴰⵏⴱⵉⵔ ⵛⵓⵜⴰⵏⴱⵉⵔ_ⴽⵟⵓⴱⵕ ⴽⵟⵓⴱⵕ_ⵏⵓⵡⴰⵏⴱⵉⵔ ⵏⵓⵡⴰⵏⴱⵉⵔ_ⴷⵓⵊⵏⴱⵉⵔ ⴷⵓⵊⵏⴱⵉⵔ'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, MMMM Do YYYY, h:mm:ss a',      'ⴰⵙⴰⵎⴰⵙ, ⴱⵕⴰⵢⵕ 14 2010, 3:25:50 pm'],\n            ['ddd, hA',                            'ⴰⵙⴰⵎⴰⵙ, 3PM'],\n            ['M Mo MM MMMM MMM',                   '2 2 02 ⴱⵕⴰⵢⵕ ⴱⵕⴰⵢⵕ'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14 14'],\n            ['d do dddd ddd dd',                   '0 0 ⴰⵙⴰⵎⴰⵙ ⴰⵙⴰⵎⴰⵙ ⴰⵙⴰⵎⴰⵙ'],\n            ['DDD DDDo DDDD',                      '45 45 045'],\n            ['w wo ww',                            '8 8 08'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'pm PM'],\n            ['[the] DDDo [day of the year]',       'the 45 day of the year'],\n            ['LTS',                                '15:25:50'],\n            ['L',                                  '14/02/2010'],\n            ['LL',                                 '14 ⴱⵕⴰⵢⵕ 2010'],\n            ['LLL',                                '14 ⴱⵕⴰⵢⵕ 2010 15:25'],\n            ['LLLL',                               'ⴰⵙⴰⵎⴰⵙ 14 ⴱⵕⴰⵢⵕ 2010 15:25'],\n            ['l',                                  '14/2/2010'],\n            ['ll',                                 '14 ⴱⵕⴰⵢⵕ 2010'],\n            ['lll',                                '14 ⴱⵕⴰⵢⵕ 2010 15:25'],\n            ['llll',                               'ⴰⵙⴰⵎⴰⵙ 14 ⴱⵕⴰⵢⵕ 2010 15:25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1', '1');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2', '2');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3', '3');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4', '4');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5', '5');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6', '6');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7', '7');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8', '8');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9', '9');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10', '10');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11', '11');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12', '12');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13', '13');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14', '14');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15', '15');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16', '16');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17', '17');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18', '18');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19', '19');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20', '20');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21', '21');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22', '22');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23', '23');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24', '24');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25', '25');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26', '26');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27', '27');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28', '28');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29', '29');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30', '30');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31', '31');\n});\n\ntest('format month', function (assert) {\n    var expected = 'ⵉⵏⵏⴰⵢⵔ ⵉⵏⵏⴰⵢⵔ_ⴱⵕⴰⵢⵕ ⴱⵕⴰⵢⵕ_ⵎⴰⵕⵚ ⵎⴰⵕⵚ_ⵉⴱⵔⵉⵔ ⵉⴱⵔⵉⵔ_ⵎⴰⵢⵢⵓ ⵎⴰⵢⵢⵓ_ⵢⵓⵏⵢⵓ ⵢⵓⵏⵢⵓ_ⵢⵓⵍⵢⵓⵣ ⵢⵓⵍⵢⵓⵣ_ⵖⵓⵛⵜ ⵖⵓⵛⵜ_ⵛⵓⵜⴰⵏⴱⵉⵔ ⵛⵓⵜⴰⵏⴱⵉⵔ_ⴽⵟⵓⴱⵕ ⴽⵟⵓⴱⵕ_ⵏⵓⵡⴰⵏⴱⵉⵔ ⵏⵓⵡⴰⵏⴱⵉⵔ_ⴷⵓⵊⵏⴱⵉⵔ ⴷⵓⵊⵏⴱⵉⵔ'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'ⴰⵙⴰⵎⴰⵙ ⴰⵙⴰⵎⴰⵙ ⴰⵙⴰⵎⴰⵙ_ⴰⵢⵏⴰⵙ ⴰⵢⵏⴰⵙ ⴰⵢⵏⴰⵙ_ⴰⵙⵉⵏⴰⵙ ⴰⵙⵉⵏⴰⵙ ⴰⵙⵉⵏⴰⵙ_ⴰⴽⵔⴰⵙ ⴰⴽⵔⴰⵙ ⴰⴽⵔⴰⵙ_ⴰⴽⵡⴰⵙ ⴰⴽⵡⴰⵙ ⴰⴽⵡⴰⵙ_ⴰⵙⵉⵎⵡⴰⵙ ⴰⵙⵉⵎⵡⴰⵙ ⴰⵙⵉⵎⵡⴰⵙ_ⴰⵙⵉⴹⵢⴰⵙ ⴰⵙⵉⴹⵢⴰⵙ ⴰⵙⵉⴹⵢⴰⵙ'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'ⵉⵎⵉⴽ', '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'ⵎⵉⵏⵓⴺ',      '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'ⵎⵉⵏⵓⴺ',      '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 ⵎⵉⵏⵓⴺ',     '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 ⵎⵉⵏⵓⴺ',    '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'ⵙⴰⵄⴰ',       '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'ⵙⴰⵄⴰ',       '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 ⵜⴰⵙⵙⴰⵄⵉⵏ',       '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 ⵜⴰⵙⵙⴰⵄⵉⵏ',       '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 ⵜⴰⵙⵙⴰⵄⵉⵏ',      '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'ⴰⵙⵙ',         '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'ⴰⵙⵙ',         '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 oⵙⵙⴰⵏ',        '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'ⴰⵙⵙ',         '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 oⵙⵙⴰⵏ',        '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 oⵙⵙⴰⵏ',       '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'ⴰⵢoⵓⵔ',       '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'ⴰⵢoⵓⵔ',       '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'ⴰⵢoⵓⵔ',       '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 ⵉⵢⵢⵉⵔⵏ',      '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 ⵉⵢⵢⵉⵔⵏ',      '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 ⵉⵢⵢⵉⵔⵏ',      '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'ⴰⵢoⵓⵔ',       '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 ⵉⵢⵢⵉⵔⵏ',      '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'ⴰⵙⴳⴰⵙ',        '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 ⵉⵙⴳⴰⵙⵏ',       '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'ⴰⵙⴳⴰⵙ',        '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 ⵉⵙⴳⴰⵙⵏ',       '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'ⴷⴰⴷⵅ ⵙ ⵢⴰⵏ ⵉⵎⵉⴽ',  'prefix');\n    assert.equal(moment(0).from(30000), 'ⵢⴰⵏ ⵉⵎⵉⴽ', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'ⵢⴰⵏ ⵉⵎⵉⴽ',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'ⴷⴰⴷⵅ ⵙ ⵢⴰⵏ ⵉⵎⵉⴽ', 'in a few seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), 'ⴷⴰⴷⵅ ⵙ ⵢⴰⵏ 5 oⵙⵙⴰⵏ', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'ⴰⵙⴷⵅ ⴴ 12:00',  'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'ⴰⵙⴷⵅ ⴴ 12:25',  'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'ⴰⵙⴷⵅ ⴴ 13:00',  'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'ⴰⵙⴽⴰ ⴴ 12:00',  'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'ⴰⵙⴷⵅ ⴴ 11:00',  'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'ⴰⵚⴰⵏⵜ ⴴ 12:00',  'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('dddd [ⴴ] LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd [ⴴ] LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd [ⴴ] LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('dddd [ⴴ] LT'),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd [ⴴ] LT'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd [ⴴ] LT'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2011, 11, 31]).format('w ww wo'), '1 01 1', 'Dec 31 2011 should be week 1');\n    assert.equal(moment([2012,  0,  6]).format('w ww wo'), '1 01 1', 'Jan  6 2012 should be week 1');\n    assert.equal(moment([2012,  0,  7]).format('w ww wo'), '2 02 2', 'Jan  7 2012 should be week 2');\n    assert.equal(moment([2012,  0, 13]).format('w ww wo'), '2 02 2', 'Jan 13 2012 should be week 2');\n    assert.equal(moment([2012,  0, 14]).format('w ww wo'), '3 03 3', 'Jan 14 2012 should be week 3');\n});\n\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/test/locale/uk.js",
    "content": "import {localeModule, test} from '../qunit';\nimport moment from '../../moment';\nlocaleModule('uk');\n\ntest('parse', function (assert) {\n    var tests = 'січень січ_лютий лют_березень бер_квітень квіт_травень трав_червень черв_липень лип_серпень серп_вересень вер_жовтень жовт_листопад лист_грудень груд'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, Do MMMM YYYY, HH:mm:ss',       'неділя, 14-го лютого 2010, 15:25:50'],\n            ['ddd, h A',                           'нд, 3 дня'],\n            ['M Mo MM MMMM MMM',                   '2 2-й 02 лютий лют'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14-го 14'],\n            ['d do dddd ddd dd',                   '0 0-й неділя нд нд'],\n            ['DDD DDDo DDDD',                      '45 45-й 045'],\n            ['w wo ww',                            '7 7-й 07'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'дня дня'],\n            ['DDDo [день року]',                  '45-й день року'],\n            ['LTS',                                '15:25:50'],\n            ['L',                                  '14.02.2010'],\n            ['LL',                                 '14 лютого 2010 р.'],\n            ['LLL',                                '14 лютого 2010 р., 15:25'],\n            ['LLLL',                               'неділя, 14 лютого 2010 р., 15:25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format meridiem', function (assert) {\n    assert.equal(moment([2012, 11, 28, 0, 0]).format('A'), 'ночі', 'night');\n    assert.equal(moment([2012, 11, 28, 3, 59]).format('A'), 'ночі', 'night');\n    assert.equal(moment([2012, 11, 28, 4, 0]).format('A'), 'ранку', 'morning');\n    assert.equal(moment([2012, 11, 28, 11, 59]).format('A'), 'ранку', 'morning');\n    assert.equal(moment([2012, 11, 28, 12, 0]).format('A'), 'дня', 'afternoon');\n    assert.equal(moment([2012, 11, 28, 16, 59]).format('A'), 'дня', 'afternoon');\n    assert.equal(moment([2012, 11, 28, 17, 0]).format('A'), 'вечора', 'evening');\n    assert.equal(moment([2012, 11, 28, 23, 59]).format('A'), 'вечора', 'evening');\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1-й', '1-й');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2-й', '2-й');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3-й', '3-й');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4-й', '4-й');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5-й', '5-й');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6-й', '6-й');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7-й', '7-й');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8-й', '8-й');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9-й', '9-й');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10-й', '10-й');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11-й', '11-й');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12-й', '12-й');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13-й', '13-й');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14-й', '14-й');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15-й', '15-й');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16-й', '16-й');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17-й', '17-й');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18-й', '18-й');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19-й', '19-й');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20-й', '20-й');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21-й', '21-й');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22-й', '22-й');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23-й', '23-й');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24-й', '24-й');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25-й', '25-й');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26-й', '26-й');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27-й', '27-й');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28-й', '28-й');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29-й', '29-й');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30-й', '30-й');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31-й', '31-й');\n});\n\ntest('format month', function (assert) {\n    var expected = 'січень січ_лютий лют_березень бер_квітень квіт_травень трав_червень черв_липень лип_серпень серп_вересень вер_жовтень жовт_листопад лист_грудень груд'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format month case', function (assert) {\n    var months = {\n        'nominative': 'січень_лютий_березень_квітень_травень_червень_липень_серпень_вересень_жовтень_листопад_грудень'.split('_'),\n        'accusative': 'січня_лютого_березня_квітня_травня_червня_липня_серпня_вересня_жовтня_листопада_грудня'.split('_')\n    }, i;\n    for (i = 0; i < 12; i++) {\n        assert.equal(moment([2011, i, 1]).format('D MMMM'), '1 ' + months.accusative[i], '1 ' + months.accusative[i]);\n        assert.equal(moment([2011, i, 1]).format('MMMM'), months.nominative[i], '1 ' + months.nominative[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'неділя нд нд_понеділок пн пн_вівторок вт вт_середа ср ср_четвер чт чт_п’ятниця пт пт_субота сб сб'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'декілька секунд',    '44 seconds = seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'хвилина',   '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'хвилина',   '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 хвилини',  '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 хвилини', '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'годину',    '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'годину',    '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 години',    '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 годин',    '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 година',   '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'день',      '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'день',      '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 дні',     '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'день',      '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 днів',     '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 11}), true),  '11 днів',     '11 days = 11 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 21}), true),  '21 день',     '21 days = 21 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 днів',    '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'місяць',    '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'місяць',    '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'місяць',    '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 місяці',   '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 місяці',   '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 місяці',   '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'місяць',    '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 місяців',   '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'рік',     '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 роки',    '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'рік',     '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 років',    '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'за декілька секунд', 'prefix');\n    assert.equal(moment(0).from(30000), 'декілька секунд тому', 'suffix');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'за декілька секунд', 'in seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), 'за 5 днів', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'Сьогодні о 12:00',   'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'Сьогодні о 12:25',   'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'Сьогодні о 13:00',   'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'Завтра о 12:00',     'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 2}).calendar(),  'Сьогодні о 10:00',   'Now minus 2 hours');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'Вчора о 12:00',      'yesterday at the same time');\n    // A special case for Ukrainian since 11 hours have different preposition\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'Сьогодні об 11:00',  'same day at 11 o\\'clock');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('[У] dddd [о' + (m.hours() === 11 ? 'б' : '') + '] LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[У] dddd [о] LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[У] dddd [о] LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n\n    function makeFormat(d) {\n        switch (d.day()) {\n            case 0:\n            case 3:\n            case 5:\n            case 6:\n                return '[Минулої] dddd [о' + (d.hours() === 11 ? 'б' : '') + '] LT';\n            case 1:\n            case 2:\n            case 4:\n                return '[Минулого] dddd [о' + (d.hours() === 11 ? 'б' : '') + '] LT';\n        }\n    }\n\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format(makeFormat(m)),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format(makeFormat(m)),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format(makeFormat(m)),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2011, 11, 26]).format('w ww wo'), '1 01 1-й', 'Dec 26 2011 should be week 1');\n    assert.equal(moment([2012,  0,  1]).format('w ww wo'), '1 01 1-й', 'Jan  1 2012 should be week 1');\n    assert.equal(moment([2012,  0,  2]).format('w ww wo'), '2 02 2-й', 'Jan  2 2012 should be week 2');\n    assert.equal(moment([2012,  0,  8]).format('w ww wo'), '2 02 2-й', 'Jan  8 2012 should be week 2');\n    assert.equal(moment([2012,  0,  9]).format('w ww wo'), '3 03 3-й', 'Jan  9 2012 should be week 3');\n});\n\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/test/locale/ur.js",
    "content": "import {localeModule, test} from '../qunit';\nimport moment from '../../moment';\nlocaleModule('ur');\n\nvar months = [\n    'جنوری',\n    'فروری',\n    'مارچ',\n    'اپریل',\n    'مئی',\n    'جون',\n    'جولائی',\n    'اگست',\n    'ستمبر',\n    'اکتوبر',\n    'نومبر',\n    'دسمبر'\n];\nvar days = [\n    'اتوار',\n    'پیر',\n    'منگل',\n    'بدھ',\n    'جمعرات',\n    'جمعہ',\n    'ہفتہ'\n];\n\ntest('parse', function (assert) {\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (var i = 0; i < 12; i++) {\n        equalTest(months[i], 'MMM', i);\n        equalTest(months[i], 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, MMMM Do YYYY, h:mm:ss a',      'اتوار، فروری 14 2010، 3:25:50 شام'],\n            ['ddd, hA',                            'اتوار، 3شام'],\n            ['M Mo MM MMMM MMM',                   '2 2 02 فروری فروری'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14 14'],\n            ['d do dddd ddd dd',                   '0 0 اتوار اتوار اتوار'],\n            ['DDD DDDo DDDD',                      '45 45 045'],\n            ['w wo ww',                            '6 6 06'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'شام شام'],\n            ['[سال کا] DDDo[واں دن]',       'سال کا 45واں دن'],\n            ['LTS',                                '15:25:50'],\n            ['L',                                  '14/02/2010'],\n            ['LL',                                 '14 فروری 2010'],\n            ['LLL',                                '14 فروری 2010 15:25'],\n            ['LLLL',                               'اتوار، 14 فروری 2010 15:25'],\n            ['l',                                  '14/2/2010'],\n            ['ll',                                 '14 فروری 2010'],\n            ['lll',                                '14 فروری 2010 15:25'],\n            ['llll',                               'اتوار، 14 فروری 2010 15:25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1', '1');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2', '2');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3', '3');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4', '4');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5', '5');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6', '6');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7', '7');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8', '8');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9', '9');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10', '10');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11', '11');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12', '12');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13', '13');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14', '14');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15', '15');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16', '16');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17', '17');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18', '18');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19', '19');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20', '20');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21', '21');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22', '22');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23', '23');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24', '24');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25', '25');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26', '26');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27', '27');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28', '28');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29', '29');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30', '30');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31', '31');\n});\n\ntest('format month', function (assert) {\n    for (var i = 0; i < months.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), months[i] + ' ' + months[i], months[i] + ' ' + months[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    for (var i = 0; i < days.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), days[i] + ' ' + days[i] + ' ' + days[i], days[i] + ' ' + days[i] + ' ' + days[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'چند سیکنڈ', '44 seconds = چند سیکنڈ');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'ایک منٹ',      '45 seconds = ایک منٹ');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'ایک منٹ',      '89 seconds = ایک منٹ');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 منٹ',     '90 seconds = 2 منٹ');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 منٹ',    '44 minutes = 44 منٹ');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'ایک گھنٹہ',       '45 minutes = ایک گھنٹہ');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'ایک گھنٹہ',       '89 minutes = ایک گھنٹہ');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 گھنٹے',       '90 minutes = 2 گھنٹے');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 گھنٹے',       '5 hours = 5 گھنٹے');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 گھنٹے',      '21 hours = 21 گھنٹے');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'ایک دن',         '22 hours = ایک دن');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'ایک دن',         '35 hours = ایک دن');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 دن',        '36 hours = 2 دن');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'ایک دن',         '1 day = ایک دن');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 دن',        '5 days = 5 دن');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 دن',       '25 days = 25 دن');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'ایک ماہ',       '26 days = ایک ماہ');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'ایک ماہ',       '30 days = ایک ماہ');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'ایک ماہ',       '43 days = ایک ماہ');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 ماہ',      '46 days = 2 ماہ');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 ماہ',      '75 days = 2 ماہ');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 ماہ',      '76 days = 3 ماہ');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'ایک ماہ',       '1 month = ایک ماہ');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 ماہ',      '5 months = 5 ماہ');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'ایک سال',        '345 days = ایک سال');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 سال',       '548 days = 2 سال');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'ایک سال',        '1 year = ایک سال');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 سال',       '5 years = 5 سال');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'چند سیکنڈ بعد',  'prefix');\n    assert.equal(moment(0).from(30000), 'چند سیکنڈ قبل', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'چند سیکنڈ قبل',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'چند سیکنڈ بعد', 'in a few seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), '5 دن بعد', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'آج بوقت 12:00',      'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'آج بوقت 12:25',      'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'آج بوقت 13:00',      'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'کل بوقت 12:00',   'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'آج بوقت 11:00',      'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'گذشتہ روز بوقت 12:00',  'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('dddd [بوقت] LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd [بوقت] LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd [بوقت] LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('[گذشتہ] dddd [بوقت] LT'),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[گذشتہ] dddd [بوقت] LT'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[گذشتہ] dddd [بوقت] LT'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2012, 0,  1]).format('w ww wo'), '52 52 52', 'Jan  1 2012 should be week 52');\n    assert.equal(moment([2012, 0,  2]).format('w ww wo'),   '1 01 1', 'Jan  2 2012 should be week 1');\n    assert.equal(moment([2012, 0,  8]).format('w ww wo'),   '1 01 1', 'Jan  8 2012 should be week 1');\n    assert.equal(moment([2012, 0,  9]).format('w ww wo'),   '2 02 2', 'Jan  9 2012 should be week 2');\n    assert.equal(moment([2012, 0, 15]).format('w ww wo'),   '2 02 2', 'Jan 15 2012 should be week 2');\n});\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/test/locale/uz-latn.js",
    "content": "import {localeModule, test} from '../qunit';\nimport moment from '../../moment';\nlocaleModule('uz-latn');\n\ntest('parse', function (assert) {\n    var tests = 'Yanvar Yan_Fevral Fev_Mart Mar_Aprel Apr_May May_Iyun Iyun_Iyul Iyul_Avgust Avg_Sentabr Sen_Oktabr Okt_Noyabr Noy_Dekabr Dek'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, Do-MMMM YYYY, h:mm:ss',        'Yakshanba, 14-Fevral 2010, 3:25:50'],\n            ['ddd, h:mm',                          'Yak, 3:25'],\n            ['M Mo MM MMMM MMM',                   '2 2 02 Fevral Fev'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14 14'],\n            ['d do dddd ddd dd',                   '0 0 Yakshanba Yak Ya'],\n            ['DDD DDDo DDDD',                      '45 45 045'],\n            ['w wo ww',                            '7 7 07'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'pm PM'],\n            ['[yilning] DDDo-[kuni]',             'yilning 45-kuni'],\n            ['LTS',                                '15:25:50'],\n            ['L',                                  '14/02/2010'],\n            ['LL',                                 '14 Fevral 2010'],\n            ['LLL',                                '14 Fevral 2010 15:25'],\n            ['LLLL',                               '14 Fevral 2010, Yakshanba 15:25'],\n            ['l',                                  '14/2/2010'],\n            ['ll',                                 '14 Fev 2010'],\n            ['lll',                                '14 Fev 2010 15:25'],\n            ['llll',                               '14 Fev 2010, Yak 15:25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2016, 0, 1]).format('DDDo'), '1', '1');\n    assert.equal(moment([2016, 0, 2]).format('DDDo'), '2', '2');\n    assert.equal(moment([2016, 0, 3]).format('DDDo'), '3', '3');\n    assert.equal(moment([2016, 0, 4]).format('DDDo'), '4', '4');\n    assert.equal(moment([2016, 0, 5]).format('DDDo'), '5', '5');\n    assert.equal(moment([2016, 0, 6]).format('DDDo'), '6', '6');\n    assert.equal(moment([2016, 0, 7]).format('DDDo'), '7', '7');\n    assert.equal(moment([2016, 0, 8]).format('DDDo'), '8', '8');\n    assert.equal(moment([2016, 0, 9]).format('DDDo'), '9', '9');\n    assert.equal(moment([2016, 0, 10]).format('DDDo'), '10', '10');\n\n    assert.equal(moment([2016, 0, 11]).format('DDDo'), '11', '11');\n    assert.equal(moment([2016, 0, 12]).format('DDDo'), '12', '12');\n    assert.equal(moment([2016, 0, 13]).format('DDDo'), '13', '13');\n    assert.equal(moment([2016, 0, 14]).format('DDDo'), '14', '14');\n    assert.equal(moment([2016, 0, 15]).format('DDDo'), '15', '15');\n    assert.equal(moment([2016, 0, 16]).format('DDDo'), '16', '16');\n    assert.equal(moment([2016, 0, 17]).format('DDDo'), '17', '17');\n    assert.equal(moment([2016, 0, 18]).format('DDDo'), '18', '18');\n    assert.equal(moment([2016, 0, 19]).format('DDDo'), '19', '19');\n    assert.equal(moment([2016, 0, 20]).format('DDDo'), '20', '20');\n\n    assert.equal(moment([2016, 0, 21]).format('DDDo'), '21', '21');\n    assert.equal(moment([2016, 0, 22]).format('DDDo'), '22', '22');\n    assert.equal(moment([2016, 0, 23]).format('DDDo'), '23', '23');\n    assert.equal(moment([2016, 0, 24]).format('DDDo'), '24', '24');\n    assert.equal(moment([2016, 0, 25]).format('DDDo'), '25', '25');\n    assert.equal(moment([2016, 0, 26]).format('DDDo'), '26', '26');\n    assert.equal(moment([2016, 0, 27]).format('DDDo'), '27', '27');\n    assert.equal(moment([2016, 0, 28]).format('DDDo'), '28', '28');\n    assert.equal(moment([2016, 0, 29]).format('DDDo'), '29', '29');\n    assert.equal(moment([2016, 0, 30]).format('DDDo'), '30', '30');\n\n    assert.equal(moment([2016, 0, 31]).format('DDDo'), '31', '31');\n});\n\ntest('format month', function (assert) {\n    var expected = 'Yanvar Yan_Fevral Fev_Mart Mar_Aprel Apr_May May_Iyun Iyun_Iyul Iyul_Avgust Avg_Sentabr Sen_Oktabr Okt_Noyabr Noy_Dekabr Dek'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2016, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'Yakshanba Yak Ya_Dushanba Dush Du_Seshanba Sesh Se_Chorshanba Chor Cho_Payshanba Pay Pa_Juma Jum Ju_Shanba Shan Sha'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2016, 0, 3 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2017, 1, 28]);\n    assert.equal(start.from(moment([2017, 1, 28]).add({s: 44}), true),  'soniya', '44 soniya = soniya');\n    assert.equal(start.from(moment([2017, 1, 28]).add({s: 45}), true),  'bir daqiqa',      '45 soniya = bir daqiqa');\n    assert.equal(start.from(moment([2017, 1, 28]).add({s: 89}), true),  'bir daqiqa',      '89 soniya = bir daqiqa');\n    assert.equal(start.from(moment([2017, 1, 28]).add({s: 90}), true),  '2 daqiqa',     '90 soniya = 2 daqiqa');\n    assert.equal(start.from(moment([2017, 1, 28]).add({m: 44}), true),  '44 daqiqa',    '44 daqiqa = 44 daqiqa');\n    assert.equal(start.from(moment([2017, 1, 28]).add({m: 45}), true),  'bir soat',       '45 minut = bir soat');\n    assert.equal(start.from(moment([2017, 1, 28]).add({m: 89}), true),  'bir soat',       '89 minut = bir soat');\n    assert.equal(start.from(moment([2017, 1, 28]).add({m: 90}), true),  '2 soat',       '90 minut = 2 soat');\n    assert.equal(start.from(moment([2017, 1, 28]).add({h: 5}), true),   '5 soat',       '5 soat = 5 soat');\n    assert.equal(start.from(moment([2017, 1, 28]).add({h: 21}), true),  '21 soat',      '21 soat = 21 soat');\n    assert.equal(start.from(moment([2017, 1, 28]).add({h: 22}), true),  'bir kun',         '22 soat = bir kun');\n    assert.equal(start.from(moment([2017, 1, 28]).add({h: 35}), true),  'bir kun',         '35 soat = bir kun');\n    assert.equal(start.from(moment([2017, 1, 28]).add({h: 36}), true),  '2 kun',        '36 soat = 2 kun');\n    assert.equal(start.from(moment([2017, 1, 28]).add({d: 1}), true),   'bir kun',         '1 kun = 1 kun');\n    assert.equal(start.from(moment([2017, 1, 28]).add({d: 5}), true),   '5 kun',        '5 kun = 5 kun');\n    assert.equal(start.from(moment([2017, 1, 28]).add({d: 25}), true),  '25 kun',       '25 kun = 25 kun');\n    assert.equal(start.from(moment([2017, 1, 28]).add({d: 26}), true),  'bir oy',       '26 kun = bir oy');\n    assert.equal(start.from(moment([2017, 1, 28]).add({d: 30}), true),  'bir oy',       '30 kun = bir oy');\n    assert.equal(start.from(moment([2017, 1, 28]).add({d: 43}), true),  'bir oy',       '45 kun = bir oy');\n    assert.equal(start.from(moment([2017, 1, 28]).add({d: 46}), true),  '2 oy',      '46 kun = 2 oy');\n    assert.equal(start.from(moment([2017, 1, 28]).add({d: 74}), true),  '2 oy',      '75 kun = 2 oy');\n    assert.equal(start.from(moment([2017, 1, 28]).add({d: 76}), true),  '3 oy',      '76 kun = 3 oy');\n    assert.equal(start.from(moment([2017, 1, 28]).add({M: 1}), true),   'bir oy',       'bir oy = bir oy');\n    assert.equal(start.from(moment([2017, 1, 28]).add({M: 5}), true),   '5 oy',      '5 oy = 5 oy');\n    assert.equal(start.from(moment([2017, 1, 28]).add({d: 345}), true), 'bir yil',        '345 kun = bir yil');\n    assert.equal(start.from(moment([2017, 1, 28]).add({d: 548}), true), '2 yil',       '548 kun = 2 yil');\n    assert.equal(start.from(moment([2017, 1, 28]).add({y: 1}), true),   'bir yil',        '1 yil = bir yil');\n    assert.equal(start.from(moment([2017, 1, 28]).add({y: 5}), true),   '5 yil',       '5 yil = 5 yil');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'Yaqin soniya ichida',  'prefix');\n    assert.equal(moment(0).from(30000), 'Bir necha soniya oldin', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'Bir necha soniya oldin',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'Yaqin soniya ichida', 'in a few seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), 'Yaqin 5 kun ichida', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'Bugun soat 12:00 da',  'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'Bugun soat 12:25 da',  'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'Bugun soat 13:00 da',  'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'Ertaga 12:00 da',      'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'Bugun soat 11:00 da',  'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'Kecha soat 12:00 da',   'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('dddd [kuni soat] LT [da]'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd [kuni soat] LT [da]'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd [kuni soat] LT [da]'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('[O\\'tgan] dddd [kuni soat] LT [da]'),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[O\\'tgan] dddd [kuni soat] LT [da]'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[O\\'tgan] dddd [kuni soat] LT [da]'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2012, 0,  1]).format('w ww wo'), '1 01 1', 'Jan  1 2012 should be week 52');\n    assert.equal(moment([2012, 0,  2]).format('w ww wo'),   '2 02 2', 'Jan  2 2012 should be week 1');\n    assert.equal(moment([2012, 0,  8]).format('w ww wo'),   '2 02 2', 'Jan  8 2012 should be week 1');\n    assert.equal(moment([2012, 0,  9]).format('w ww wo'),   '3 03 3', 'Jan  9 2012 should be week 2');\n    assert.equal(moment([2012, 0, 15]).format('w ww wo'),   '3 03 3', 'Jan 15 2012 should be week 2');\n});\n\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/test/locale/uz.js",
    "content": "import {localeModule, test} from '../qunit';\nimport moment from '../../moment';\nlocaleModule('uz');\n\ntest('parse', function (assert) {\n    var tests = 'январ янв_феврал фев_март мар_апрел апр_май май_июн июн_июл июл_август авг_сентябр сен_октябр окт_ноябр ноя_декабр дек'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, Do-MMMM YYYY, h:mm:ss',        'Якшанба, 14-феврал 2010, 3:25:50'],\n            ['ddd, h:mm',                          'Якш, 3:25'],\n            ['M Mo MM MMMM MMM',                   '2 2 02 феврал фев'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14 14'],\n            ['d do dddd ddd dd',                   '0 0 Якшанба Якш Як'],\n            ['DDD DDDo DDDD',                      '45 45 045'],\n            ['w wo ww',                            '7 7 07'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'pm PM'],\n            ['[йилнинг] DDDo-[куни]',             'йилнинг 45-куни'],\n            ['LTS',                                '15:25:50'],\n            ['L',                                  '14/02/2010'],\n            ['LL',                                 '14 феврал 2010'],\n            ['LLL',                                '14 феврал 2010 15:25'],\n            ['LLLL',                               '14 феврал 2010, Якшанба 15:25'],\n            ['l',                                  '14/2/2010'],\n            ['ll',                                 '14 фев 2010'],\n            ['lll',                                '14 фев 2010 15:25'],\n            ['llll',                               '14 фев 2010, Якш 15:25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1', '1');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2', '2');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3', '3');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4', '4');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5', '5');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6', '6');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7', '7');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8', '8');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9', '9');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10', '10');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11', '11');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12', '12');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13', '13');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14', '14');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15', '15');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16', '16');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17', '17');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18', '18');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19', '19');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20', '20');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21', '21');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22', '22');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23', '23');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24', '24');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25', '25');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26', '26');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27', '27');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28', '28');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29', '29');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30', '30');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31', '31');\n});\n\ntest('format month', function (assert) {\n    var expected = 'январ янв_феврал фев_март мар_апрел апр_май май_июн июн_июл июл_август авг_сентябр сен_октябр окт_ноябр ноя_декабр дек'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'Якшанба Якш Як_Душанба Душ Ду_Сешанба Сеш Се_Чоршанба Чор Чо_Пайшанба Пай Па_Жума Жум Жу_Шанба Шан Ша'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'фурсат', '44 секунд = фурсат');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'бир дакика',      '45 секунд = бир дакика');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'бир дакика',      '89 секунд = бир дакика');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 дакика',     '90 секунд = 2 дакика');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 дакика',    '44 дакика = 44 дакика');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'бир соат',       '45 минут = бир соат');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'бир соат',       '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 соат',       '90 минут = 2 соат');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 соат',       '5 соат = 5 соат');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 соат',      '21 соат = 21 соат');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'бир кун',         '22 соат = бир кун');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'бир кун',         '35 соат = бир кун');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 кун',        '36 соат = 2 кун');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'бир кун',         '1 кун = 1 кун');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 кун',        '5 кун = 5 кун');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 кун',       '25 кун = 25 кун');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'бир ой',       '26 кун = бир ой');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'бир ой',       '30 кун = бир ой');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'бир ой',       '45 кун = бир ой');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 ой',      '46 кун = 2 ой');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 ой',      '75 кун = 2 ой');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 ой',      '76 кун = 3 ой');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'бир ой',       'бир ой = бир ой');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 ой',      '5 ой = 5 ой');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'бир йил',        '345 кун = бир йил');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 йил',       '548 кун = 2 йил');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'бир йил',        '1 йил = бир йил');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 йил',       '5 йил = 5 йил');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'Якин фурсат ичида',  'prefix');\n    assert.equal(moment(0).from(30000), 'Бир неча фурсат олдин', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'Бир неча фурсат олдин',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'Якин фурсат ичида', 'in a few seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), 'Якин 5 кун ичида', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'Бугун соат 12:00 да',  'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'Бугун соат 12:25 да',  'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'Бугун соат 13:00 да',  'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'Эртага 12:00 да',      'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'Бугун соат 11:00 да',  'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'Кеча соат 12:00 да',   'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('dddd [куни соат] LT [да]'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd [куни соат] LT [да]'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd [куни соат] LT [да]'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('[Утган] dddd [куни соат] LT [да]'),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[Утган] dddd [куни соат] LT [да]'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[Утган] dddd [куни соат] LT [да]'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2012, 0,  1]).format('w ww wo'), '1 01 1', 'Jan  1 2012 should be week 52');\n    assert.equal(moment([2012, 0,  2]).format('w ww wo'),   '2 02 2', 'Jan  2 2012 should be week 1');\n    assert.equal(moment([2012, 0,  8]).format('w ww wo'),   '2 02 2', 'Jan  8 2012 should be week 1');\n    assert.equal(moment([2012, 0,  9]).format('w ww wo'),   '3 03 3', 'Jan  9 2012 should be week 2');\n    assert.equal(moment([2012, 0, 15]).format('w ww wo'),   '3 03 3', 'Jan 15 2012 should be week 2');\n});\n\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/test/locale/vi.js",
    "content": "import {localeModule, test} from '../qunit';\nimport moment from '../../moment';\nlocaleModule('vi');\n\ntest('parse', function (assert) {\n    var i,\n        tests = 'tháng 1,Th01_tháng 2,Th02_tháng 3,Th03_tháng 4,Th04_tháng 5,Th05_tháng 6,Th06_tháng 7,Th07_tháng 8,Th08_tháng 9,Th09_tháng 10,Th10_tháng 11,Th11_tháng 12,Th12'.split('_');\n\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + i);\n    }\n\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(',');\n        equalTest(tests[i][0], '[tháng] M', i);\n        equalTest(tests[i][1], '[Th]M', i);\n        equalTest(tests[i][0], '[tháng] MM', i);\n        equalTest(tests[i][1], '[Th]MM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), '[THÁNG] M', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), '[TH]M', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), '[THÁNG] MM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), '[TH]MM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, MMMM Do YYYY, h:mm:ss a',      'chủ nhật, tháng 2 14 2010, 3:25:50 ch'],\n            ['ddd, hA',                            'CN, 3CH'],\n            ['M Mo MM MMMM MMM',                   '2 2 02 tháng 2 Th02'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14 14'],\n            ['d do dddd ddd dd',                   '0 0 chủ nhật CN CN'],\n            ['DDD DDDo DDDD',                      '45 45 045'],\n            ['w wo ww',                            '6 6 06'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'ch CH'],\n            ['[ngày thứ] DDDo [của năm]',          'ngày thứ 45 của năm'],\n            ['LTS',                                '15:25:50'],\n            ['L',                                  '14/02/2010'],\n            ['LL',                                 '14 tháng 2 năm 2010'],\n            ['LLL',                                '14 tháng 2 năm 2010 15:25'],\n            ['LLLL',                               'chủ nhật, 14 tháng 2 năm 2010 15:25'],\n            ['l',                                  '14/2/2010'],\n            ['ll',                                 '14 Th02 2010'],\n            ['lll',                                '14 Th02 2010 15:25'],\n            ['llll',                               'CN, 14 Th02 2010 15:25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1', '1');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2', '2');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3', '3');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4', '4');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5', '5');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6', '6');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7', '7');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8', '8');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9', '9');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10', '10');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11', '11');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12', '12');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13', '13');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14', '14');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15', '15');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16', '16');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17', '17');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18', '18');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19', '19');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20', '20');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21', '21');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22', '22');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23', '23');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24', '24');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25', '25');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26', '26');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27', '27');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28', '28');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29', '29');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30', '30');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31', '31');\n});\n\ntest('format month', function (assert) {\n    var i,\n        expected = 'tháng 1,Th01_tháng 2,Th02_tháng 3,Th03_tháng 4,Th04_tháng 5,Th05_tháng 6,Th06_tháng 7,Th07_tháng 8,Th08_tháng 9,Th09_tháng 10,Th10_tháng 11,Th11_tháng 12,Th12'.split('_');\n\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM,MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var i,\n        expected = 'chủ nhật CN CN_thứ hai T2 T2_thứ ba T3 T3_thứ tư T4 T4_thứ năm T5 T5_thứ sáu T6 T6_thứ bảy T7 T7'.split('_');\n\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'vài giây', '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'một phút',      '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'một phút',      '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 phút',     '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 phút',    '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'một giờ',       '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'một giờ',       '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 giờ',       '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 giờ',       '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 giờ',      '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'một ngày',         '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'một ngày',         '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 ngày',        '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'một ngày',         '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 ngày',        '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 ngày',       '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'một tháng',       '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'một tháng',       '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'một tháng',       '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 tháng',      '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 tháng',      '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 tháng',      '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'một tháng',       '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 tháng',      '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'một năm',        '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 năm',       '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'một năm',        '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 năm',       '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'vài giây tới',  'prefix');\n    assert.equal(moment(0).from(30000), 'vài giây trước', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'vài giây trước',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'vài giây tới', 'in a few seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), '5 ngày tới', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'Hôm nay lúc 12:00',   'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'Hôm nay lúc 12:25',   'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'Hôm nay lúc 13:00',   'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'Ngày mai lúc 12:00',  'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'Hôm nay lúc 11:00',   'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'Hôm qua lúc 12:00',   'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('dddd [tuần tới lúc] LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd [tuần tới lúc] LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd [tuần tới lúc] LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('dddd [tuần rồi lúc] LT'),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd [tuần rồi lúc] LT'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd [tuần rồi lúc] LT'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2012, 0,  1]).format('w ww wo'), '52 52 52', 'Jan  1 2012 should be week 52');\n    assert.equal(moment([2012, 0,  2]).format('w ww wo'),   '1 01 1', 'Jan  2 2012 should be week 1');\n    assert.equal(moment([2012, 0,  8]).format('w ww wo'),   '1 01 1', 'Jan  8 2012 should be week 1');\n    assert.equal(moment([2012, 0,  9]).format('w ww wo'),   '2 02 2', 'Jan  9 2012 should be week 2');\n    assert.equal(moment([2012, 0, 15]).format('w ww wo'),   '2 02 2', 'Jan 15 2012 should be week 2');\n});\n\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/test/locale/x-pseudo.js",
    "content": "import {localeModule, test} from '../qunit';\nimport moment from '../../moment';\nlocaleModule('x-pseudo');\n\ntest('parse', function (assert) {\n    var tests = 'J~áñúá~rý J~áñ_F~ébrú~árý ~Féb_~Márc~h ~Már_Áp~ríl ~Ápr_~Máý ~Máý_~Júñé~ ~Júñ_Júl~ý ~Júl_Áú~gúst~ ~Áúg_Sép~témb~ér ~Sép_Ó~ctób~ér ~Óct_Ñ~óvém~bér ~Ñóv_~Décé~mbér ~Déc'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, MMMM Do YYYY, h:mm:ss a',      'S~úñdá~ý, F~ébrú~árý 14th 2010, 3:25:50 pm'],\n            ['ddd, hA',                            'S~úñ, 3PM'],\n            ['M Mo MM MMMM MMM',                   '2 2nd 02 F~ébrú~árý ~Féb'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14th 14'],\n            ['d do dddd ddd dd',                   '0 0th S~úñdá~ý S~úñ S~ú'],\n            ['DDD DDDo DDDD',                      '45 45th 045'],\n            ['w wo ww',                            '6 6th 06'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'pm PM'],\n            ['[the] DDDo [day of the year]',       'the 45th day of the year'],\n            ['LT',                                 '15:25'],\n            ['L',                                  '14/02/2010'],\n            ['LL',                                 '14 F~ébrú~árý 2010'],\n            ['LLL',                                '14 F~ébrú~árý 2010 15:25'],\n            ['LLLL',                               'S~úñdá~ý, 14 F~ébrú~árý 2010 15:25'],\n            ['l',                                  '14/2/2010'],\n            ['ll',                                 '14 ~Féb 2010'],\n            ['lll',                                '14 ~Féb 2010 15:25'],\n            ['llll',                               'S~úñ, 14 ~Féb 2010 15:25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1st', '1st');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2nd', '2nd');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3rd', '3rd');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4th', '4th');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5th', '5th');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6th', '6th');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7th', '7th');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8th', '8th');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9th', '9th');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10th', '10th');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11th', '11th');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12th', '12th');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13th', '13th');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14th', '14th');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15th', '15th');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16th', '16th');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17th', '17th');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18th', '18th');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19th', '19th');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20th', '20th');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21st', '21st');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22nd', '22nd');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23rd', '23rd');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24th', '24th');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25th', '25th');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26th', '26th');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27th', '27th');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28th', '28th');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29th', '29th');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30th', '30th');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31st', '31st');\n});\n\ntest('format month', function (assert) {\n    var expected = 'J~áñúá~rý J~áñ_F~ébrú~árý ~Féb_~Márc~h ~Már_Áp~ríl ~Ápr_~Máý ~Máý_~Júñé~ ~Júñ_Júl~ý ~Júl_Áú~gúst~ ~Áúg_Sép~témb~ér ~Sép_Ó~ctób~ér ~Óct_Ñ~óvém~bér ~Ñóv_~Décé~mbér ~Déc'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'S~úñdá~ý S~úñ S~ú_Mó~ñdáý~ ~Móñ Mó~_Túé~sdáý~ ~Túé Tú_Wéd~ñésd~áý ~Wéd ~Wé_T~húrs~dáý ~Thú T~h_~Fríd~áý ~Frí Fr~_S~átúr~dáý ~Sát Sá'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'á ~féw ~sécó~ñds', '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'á ~míñ~úté',      '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'á ~míñ~úté',      '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 m~íñú~tés',     '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 m~íñú~tés',    '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'á~ñ hó~úr',       '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'á~ñ hó~úr',       '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 h~óúrs',       '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 h~óúrs',       '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 h~óúrs',      '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'á ~dáý',         '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'á ~dáý',         '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 d~áýs',        '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'á ~dáý',         '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 d~áýs',        '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 d~áýs',       '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'á ~móñ~th',       '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'á ~móñ~th',       '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'á ~móñ~th',       '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 m~óñt~hs',      '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 m~óñt~hs',      '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 m~óñt~hs',      '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'á ~móñ~th',       '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 m~óñt~hs',      '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'á ~ýéár',        '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 ý~éárs',       '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'á ~ýéár',        '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 ý~éárs',       '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'í~ñ á ~féw ~sécó~ñds',  'prefix');\n    assert.equal(moment(0).from(30000), 'á ~féw ~sécó~ñds á~gó', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'á ~féw ~sécó~ñds á~gó',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'í~ñ á ~féw ~sécó~ñds', 'in a few seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), 'í~ñ 5 d~áýs', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(2).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                     'T~ódá~ý át 02:00',      'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'T~ódá~ý át 02:25',      'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'T~ódá~ý át 03:00',      'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'T~ómó~rró~w át 02:00',   'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'T~ódá~ý át 01:00',      'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'Ý~ést~érdá~ý át 02:00',  'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('dddd [át] LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd [át] LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd [át] LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('[L~ást] dddd [át] LT'),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[L~ást] dddd [át] LT'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[L~ást] dddd [át] LT'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2012, 0,  1]).format('w ww wo'), '52 52 52nd', 'Jan  1 2012 should be week 52');\n    assert.equal(moment([2012, 0,  2]).format('w ww wo'),   '1 01 1st', 'Jan  2 2012 should be week 1');\n    assert.equal(moment([2012, 0,  8]).format('w ww wo'),   '1 01 1st', 'Jan  8 2012 should be week 1');\n    assert.equal(moment([2012, 0,  9]).format('w ww wo'),   '2 02 2nd', 'Jan  9 2012 should be week 2');\n    assert.equal(moment([2012, 0, 15]).format('w ww wo'),   '2 02 2nd', 'Jan 15 2012 should be week 2');\n});\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/test/locale/yo.js",
    "content": "import { localeModule, test } from '../qunit';\nimport moment from '../../moment';\nlocaleModule('yo');\n\ntest('parse', function (assert) {\n    var tests = 'Sẹ́rẹ́ Sẹ́r_Èrèlè Èrl_Ẹrẹ̀nà Ẹrn_Ìgbé Ìgb_Èbibi Èbi_Òkùdu Òkù_Agẹmo Agẹ_Ògún Ògú_Owewe Owe_Ọ̀wàrà Ọ̀wà_Bélú Bél_Ọ̀pẹ̀̀ Ọ̀pẹ̀̀'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, MMMM Do YYYY, h:mm:ss a', 'Àìkú, Èrèlè ọjọ́ 14 2010, 3:25:50 pm'],\n            ['ddd, hA', 'Àìk, 3PM'],\n            ['M Mo MM MMMM MMM', '2 ọjọ́ 2 02 Èrèlè Èrl'],\n            ['YYYY YY', '2010 10'],\n            ['D Do DD', '14 ọjọ́ 14 14'],\n            ['d do dddd ddd dd', '0 ọjọ́ 0 Àìkú Àìk Àì'],\n            ['DDD DDDo DDDD', '45 ọjọ́ 45 045'],\n            ['w wo ww', '6 ọjọ́ 6 06'],\n            ['h hh', '3 03'],\n            ['H HH', '15 15'],\n            ['m mm', '25 25'],\n            ['s ss', '50 50'],\n            ['a A', 'pm PM'],\n            ['[the] DDDo [day of the year]', 'the ọjọ́ 45 day of the year'],\n            ['LTS', '3:25:50 PM'],\n            ['L', '14/02/2010'],\n            ['LL', '14 Èrèlè 2010'],\n            ['LLL', '14 Èrèlè 2010 3:25 PM'],\n            ['LLLL', 'Àìkú, 14 Èrèlè 2010 3:25 PM'],\n            ['l', '14/2/2010'],\n            ['ll', '14 Èrl 2010'],\n            ['lll', '14 Èrl 2010 3:25 PM'],\n            ['llll', 'Àìk, 14 Èrl 2010 3:25 PM']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), 'ọjọ́ 1', 'ọjọ́ 1');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), 'ọjọ́ 2', 'ọjọ́ 2');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), 'ọjọ́ 3', 'ọjọ́ 3');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), 'ọjọ́ 4', 'ọjọ́ 4');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), 'ọjọ́ 5', 'ọjọ́ 5');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), 'ọjọ́ 6', 'ọjọ́ 6');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), 'ọjọ́ 7', 'ọjọ́ 7');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), 'ọjọ́ 8', 'ọjọ́ 8');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), 'ọjọ́ 9', 'ọjọ́ 9');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), 'ọjọ́ 10', 'ọjọ́ 10');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), 'ọjọ́ 11', 'ọjọ́ 11');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), 'ọjọ́ 12', 'ọjọ́ 12');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), 'ọjọ́ 13', 'ọjọ́ 13');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), 'ọjọ́ 14', 'ọjọ́ 14');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), 'ọjọ́ 15', 'ọjọ́ 15');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), 'ọjọ́ 16', 'ọjọ́ 16');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), 'ọjọ́ 17', 'ọjọ́ 17');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), 'ọjọ́ 18', 'ọjọ́ 18');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), 'ọjọ́ 19', 'ọjọ́ 19');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), 'ọjọ́ 20', 'ọjọ́ 20');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), 'ọjọ́ 21', 'ọjọ́ 21');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), 'ọjọ́ 22', 'ọjọ́ 22');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), 'ọjọ́ 23', 'ọjọ́ 23');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), 'ọjọ́ 24', 'ọjọ́ 24');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), 'ọjọ́ 25', 'ọjọ́ 25');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), 'ọjọ́ 26', 'ọjọ́ 26');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), 'ọjọ́ 27', 'ọjọ́ 27');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), 'ọjọ́ 28', 'ọjọ́ 28');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), 'ọjọ́ 29', 'ọjọ́ 29');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), 'ọjọ́ 30', 'ọjọ́ 30');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), 'ọjọ́ 31', 'ọjọ́ 31');\n});\n\ntest('format month', function (assert) {\n    var expected = 'Sẹ́rẹ́ Sẹ́r_Èrèlè Èrl_Ẹrẹ̀nà Ẹrn_Ìgbé Ìgb_Èbibi Èbi_Òkùdu Òkù_Agẹmo Agẹ_Ògún Ògú_Owewe Owe_Ọ̀wàrà Ọ̀wà_Bélú Bél_Ọ̀pẹ̀̀ Ọ̀pẹ̀̀'.split('_'),\n        i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'Àìkú Àìk Àì_Ajé Ajé Aj_Ìsẹ́gun Ìsẹ́ Ìs_Ọjọ́rú Ọjr Ọr_Ọjọ́bọ Ọjb Ọb_Ẹtì Ẹtì Ẹt_Àbámẹ́ta Àbá Àb'.split('_'),\n        i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'ìsẹjú aayá die', '44 seconds = ìsẹjú aayá die');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'ìsẹjú kan',      '45 seconds = ìsẹjú kan');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'ìsẹjú kan',      '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  'ìsẹjú 2',        '90 seconds = ìsẹjú 2');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  'ìsẹjú 44',       'ìsẹjú 44 = ìsẹjú 44');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'wákati kan',     'ìsẹjú 45 = wákati kan');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'wákati kan',     'ìsẹjú 89 = wákati kan');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  'wákati 2',       'ìsẹjú 90 = wákati 2');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   'wákati 5',       'wákati 5 = wákati 5');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  'wákati 21',      'wákati 21 = wákati 21');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'ọjọ́ kan',        '22 wákati = ọjọ́ kan');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'ọjọ́ kan',        '35 wákati = ọjọ́ kan');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  'ọjọ́ 2',          'wákati 36 = ọjọ́ 2');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'ọjọ́ kan',        '1  = ọjọ́ kan');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   'ọjọ́ 5',          'ọjọ́ 5 = ọjọ́  5');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  'ọjọ́ 25',         'ọjọ́ 25 = ọjọ́ 25');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'osù kan',        'ọjọ́ 26 = osù kan');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'osù kan',        'ọjọ́ 30 = osù kan');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'osù kan',        'ọjọ́ 43 = osù kan');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  'osù 2',          'ọjọ́ 46 = osù 2');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  'osù 2',          'ọjọ́ 75 = osù 2');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  'osù 3',          'ọjọ́ 76 = osù 3');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'osù kan',        'osù 1 = osù kan');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   'osù 5',          'osù 5 = osù 5');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'ọdún kan',       'ọjọ 345 = ọdún kan');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), 'ọdún 2',         'ọjọ 548 = ọdún 2');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'ọdún kan',       'ọdún 1 = ọdún kan');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   'ọdún 5',         'ọdún 5 = ọdún 5');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'ní ìsẹjú aayá die', 'prefix');\n    assert.equal(moment(0).from(30000), 'ìsẹjú aayá die kọjá', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'ìsẹjú aayá die kọjá', 'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'ní ìsẹjú aayá die', 'ní ìsẹjú aayá die');\n    assert.equal(moment().add({d: 5}).fromNow(), 'ní ọjọ́ 5', 'ní ọjọ́ 5');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                     'Ònì ni 12:00 PM',   'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'Ònì ni 12:25 PM',   'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'Ònì ni 1:00 PM',    'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'Ọ̀la ni 12:00 PM',   'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'Ònì ni 11:00 AM',   'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'Àna ni 12:00 PM',   'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(), m.format('dddd [Ọsẹ̀ tón\\'bọ] [ni] LT'), 'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(), m.format('dddd [Ọsẹ̀ tón\\'bọ] [ni] LT'), 'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(), m.format('dddd [Ọsẹ̀ tón\\'bọ] [ni] LT'), 'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(), m.format('dddd [Ọsẹ̀ tólọ́] [ni] LT'), 'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(), m.format('dddd [Ọsẹ̀ tólọ́] [ni] LT'), 'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(), m.format('dddd [Ọsẹ̀ tólọ́] [ni] LT'), 'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '1 week ago');\n    assert.equal(weeksFromNow.calendar(), weeksFromNow.format('L'), 'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(), weeksFromNow.format('L'), 'in 2 weeks');\n});\n\ntest('weeks year starting sunday format', function (assert) {\n    assert.equal(moment([2012, 0,  1]).format('w ww wo'), '52 52 ọjọ́ 52', 'Jan  1 2012 should be week 52');\n    assert.equal(moment([2012, 0,  2]).format('w ww wo'),   '1 01 ọjọ́ 1', 'Jan  2 2012 should be week 1');\n    assert.equal(moment([2012, 0,  8]).format('w ww wo'),   '1 01 ọjọ́ 1', 'Jan  8 2012 should be week 1');\n    assert.equal(moment([2012, 0,  9]).format('w ww wo'),   '2 02 ọjọ́ 2', 'Jan  9 2012 should be week 2');\n    assert.equal(moment([2012, 0, 15]).format('w ww wo'),   '2 02 ọjọ́ 2', 'Jan 15 2012 should be week 2');\n});\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/test/locale/zh-cn.js",
    "content": "import {localeModule, test} from '../qunit';\nimport moment from '../../moment';\nlocaleModule('zh-cn');\n\ntest('parse', function (assert) {\n    var tests = '一月 1月_二月 2月_三月 3月_四月 4月_五月 5月_六月 6月_七月 7月_八月 8月_九月 9月_十月 10月_十一月 11月_十二月 12月'.split('_'), i;\n\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, MMMM Do YYYY, a h:mm:ss',      '星期日, 二月 14日 2010, 下午 3:25:50'],\n            ['ddd, Ah',                            '周日, 下午3'],\n            ['M Mo MM MMMM MMM',                   '2 2月 02 二月 2月'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14日 14'],\n            ['d do dddd ddd dd',                   '0 0日 星期日 周日 日'],\n            ['DDD DDDo DDDD',                      '45 45日 045'],\n            ['w wo ww',                            '6 6周 06'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                '下午 下午'],\n            ['[这年的第] DDDo',                    '这年的第 45日'],\n            ['LTS',                                '15:25:50'],\n            ['L',                                  '2010年2月14日'],\n            ['LL',                                 '2010年2月14日'],\n            ['LLL',                                '2010年2月14日下午3点25分'],\n            ['LLLL',                               '2010年2月14日星期日下午3点25分'],\n            ['l',                                  '2010年2月14日'],\n            ['ll',                                 '2010年2月14日'],\n            ['lll',                                '2010年2月14日 15:25'],\n            ['llll',                               '2010年2月14日星期日 15:25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format month', function (assert) {\n    var expected = '一月 1月_二月 2月_三月 3月_四月 4月_五月 5月_六月 6月_七月 7月_八月 8月_九月 9月_十月 10月_十一月 11月_十二月 12月'.split('_'), i;\n\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = '星期日 周日 日_星期一 周一 一_星期二 周二 二_星期三 周三 三_星期四 周四 四_星期五 周五 五_星期六 周六 六'.split('_'), i;\n\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  '几秒',   '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  '1 分钟', '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  '1 分钟', '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 分钟',  '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 分钟', '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  '1 小时', '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  '1 小时', '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 小时',  '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 小时',  '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 小时', '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  '1 天',   '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  '1 天',   '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 天',   '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   '1 天',   '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 天',   '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 天',  '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  '1 个月', '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  '1 个月', '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  '1 个月', '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 个月',  '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 个月',  '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 个月',  '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   '1 个月', '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 个月',  '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), '1 年',   '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 年',   '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   '1 年',   '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 年',   '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), '几秒内',  'prefix');\n    assert.equal(moment(0).from(30000), '几秒前', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), '几秒前',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), '几秒内', 'in a few seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), '5 天内', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   '今天12:00', 'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      '今天12:25', 'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       '今天13:00', 'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       '明天12:00', 'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  '今天11:00', 'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  '昨天12:00', 'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('[下]ddddLT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[下]ddddLT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[下]ddddLT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('[上]ddddLT'),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[上]ddddLT'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[上]ddddLT'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),      '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),      '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('meridiem', function (assert) {\n    assert.equal(moment([2011, 2, 23,  0, 0]).format('A'), '凌晨', 'before dawn');\n    assert.equal(moment([2011, 2, 23,  6, 0]).format('A'), '早上', 'morning');\n    assert.equal(moment([2011, 2, 23,  9, 0]).format('A'), '上午', 'before noon');\n    assert.equal(moment([2011, 2, 23, 12, 0]).format('A'), '中午', 'noon');\n    assert.equal(moment([2011, 2, 23, 13, 0]).format('A'), '下午', 'afternoon');\n    assert.equal(moment([2011, 2, 23, 18, 0]).format('A'), '晚上', 'night');\n});\n\ntest('weeks year starting sunday format', function (assert) {\n    assert.equal(moment([2012, 0,  1]).format('w ww wo'), '52 52 52周', 'Jan  1 2012 应该是第52周');\n    assert.equal(moment([2012, 0,  7]).format('w ww wo'), '1 01 1周', 'Jan  7 2012 应该是第 1周');\n    assert.equal(moment([2012, 0, 14]).format('w ww wo'), '2 02 2周', 'Jan 14 2012 应该是第 2周');\n});\n\n\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/test/locale/zh-hk.js",
    "content": "import {localeModule, test} from '../qunit';\nimport moment from '../../moment';\nlocaleModule('zh-hk');\n\ntest('parse', function (assert) {\n    var tests = '一月 1月_二月 2月_三月 3月_四月 4月_五月 5月_六月 6月_七月 7月_八月 8月_九月 9月_十月 10月_十一月 11月_十二月 12月'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, MMMM Do YYYY, a h:mm:ss',      '星期日, 二月 14日 2010, 下午 3:25:50'],\n            ['ddd, Ah',                            '週日, 下午3'],\n            ['M Mo MM MMMM MMM',                   '2 2月 02 二月 2月'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14日 14'],\n            ['d do dddd ddd dd',                   '0 0日 星期日 週日 日'],\n            ['DDD DDDo DDDD',                      '45 45日 045'],\n            ['w wo ww',                            '8 8週 08'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                '下午 下午'],\n            ['[這年的第] DDDo',                    '這年的第 45日'],\n            ['LTS',                                '15:25:50'],\n            ['L',                                  '2010年2月14日'],\n            ['LL',                                 '2010年2月14日'],\n            ['LLL',                                '2010年2月14日 15:25'],\n            ['LLLL',                               '2010年2月14日星期日 15:25'],\n            ['l',                                  '2010年2月14日'],\n            ['ll',                                 '2010年2月14日'],\n            ['lll',                                '2010年2月14日 15:25'],\n            ['llll',                               '2010年2月14日星期日 15:25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format month', function (assert) {\n    var expected = '一月 1月_二月 2月_三月 3月_四月 4月_五月 5月_六月 6月_七月 7月_八月 8月_九月 9月_十月 10月_十一月 11月_十二月 12月'.split('_'), i;\n\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = '星期日 週日 日_星期一 週一 一_星期二 週二 二_星期三 週三 三_星期四 週四 四_星期五 週五 五_星期六 週六 六'.split('_'), i;\n\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  '幾秒',   '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  '1 分鐘', '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  '1 分鐘', '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 分鐘',  '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 分鐘', '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  '1 小時', '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  '1 小時', '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 小時',  '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 小時',  '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 小時', '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  '1 天',   '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  '1 天',   '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 天',   '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   '1 天',   '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 天',   '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 天',  '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  '1 個月', '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  '1 個月', '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  '1 個月', '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 個月',  '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 個月',  '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 個月',  '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   '1 個月', '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 個月',  '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), '1 年',   '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 年',   '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   '1 年',   '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 年',   '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), '幾秒內',  'prefix');\n    assert.equal(moment(0).from(30000), '幾秒前', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), '幾秒前',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), '幾秒內', 'in a few seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), '5 天內', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   '今天12:00', 'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      '今天12:25', 'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       '今天13:00', 'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       '明天12:00', 'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  '今天11:00', 'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  '昨天12:00', 'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('[下]ddddLT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[下]ddddLT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[下]ddddLT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('[上]ddddLT'),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[上]ddddLT'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[上]ddddLT'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),      '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),      '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('meridiem', function (assert) {\n    assert.equal(moment([2011, 2, 23,  0, 0]).format('a'), '凌晨', 'before dawn');\n    assert.equal(moment([2011, 2, 23,  6, 0]).format('a'), '早上', 'morning');\n    assert.equal(moment([2011, 2, 23,  9, 0]).format('a'), '上午', 'before noon');\n    assert.equal(moment([2011, 2, 23, 12, 0]).format('a'), '中午', 'noon');\n    assert.equal(moment([2011, 2, 23, 13, 0]).format('a'), '下午', 'after noon');\n    assert.equal(moment([2011, 2, 23, 18, 0]).format('a'), '晚上', 'night');\n\n    assert.equal(moment([2011, 2, 23,  0, 0]).format('A'), '凌晨', 'before dawn');\n    assert.equal(moment([2011, 2, 23,  6, 0]).format('A'), '早上', 'morning');\n    assert.equal(moment([2011, 2, 23,  9, 0]).format('A'), '上午', 'before noon');\n    assert.equal(moment([2011, 2, 23, 12, 0]).format('A'), '中午', 'noon');\n    assert.equal(moment([2011, 2, 23, 13, 0]).format('A'), '下午', 'afternoon');\n    assert.equal(moment([2011, 2, 23, 18, 0]).format('A'), '晚上', 'night');\n});\n\ntest('weeks year starting sunday format', function (assert) {\n    assert.equal(moment([2012, 0,  1]).format('w ww wo'), '1 01 1週', 'Jan  1 2012 應該是第 1週');\n    assert.equal(moment([2012, 0,  7]).format('w ww wo'), '1 01 1週', 'Jan  7 2012 應該是第 1週');\n    assert.equal(moment([2012, 0,  8]).format('w ww wo'), '2 02 2週', 'Jan  8 2012 應該是第 2週');\n    assert.equal(moment([2012, 0, 14]).format('w ww wo'), '2 02 2週', 'Jan 14 2012 應該是第 2週');\n    assert.equal(moment([2012, 0, 15]).format('w ww wo'), '3 03 3週', 'Jan 15 2012 應該是第 3週');\n});\n\n\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/test/locale/zh-tw.js",
    "content": "import {localeModule, test} from '../qunit';\nimport moment from '../../moment';\nlocaleModule('zh-tw');\n\ntest('parse', function (assert) {\n    var tests = '一月 1月_二月 2月_三月 3月_四月 4月_五月 5月_六月 6月_七月 7月_八月 8月_九月 9月_十月 10月_十一月 11月_十二月 12月'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, MMMM Do YYYY, a h:mm:ss',      '星期日, 二月 14日 2010, 下午 3:25:50'],\n            ['ddd, Ah',                            '週日, 下午3'],\n            ['M Mo MM MMMM MMM',                   '2 2月 02 二月 2月'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14日 14'],\n            ['d do dddd ddd dd',                   '0 0日 星期日 週日 日'],\n            ['DDD DDDo DDDD',                      '45 45日 045'],\n            ['w wo ww',                            '8 8週 08'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                '下午 下午'],\n            ['[這年的第] DDDo',                    '這年的第 45日'],\n            ['LTS',                                '15:25:50'],\n            ['L',                                  '2010年2月14日'],\n            ['LL',                                 '2010年2月14日'],\n            ['LLL',                                '2010年2月14日 15:25'],\n            ['LLLL',                               '2010年2月14日星期日 15:25'],\n            ['l',                                  '2010年2月14日'],\n            ['ll',                                 '2010年2月14日'],\n            ['lll',                                '2010年2月14日 15:25'],\n            ['llll',                               '2010年2月14日星期日 15:25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format month', function (assert) {\n    var expected = '一月 1月_二月 2月_三月 3月_四月 4月_五月 5月_六月 6月_七月 7月_八月 8月_九月 9月_十月 10月_十一月 11月_十二月 12月'.split('_'), i;\n\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = '星期日 週日 日_星期一 週一 一_星期二 週二 二_星期三 週三 三_星期四 週四 四_星期五 週五 五_星期六 週六 六'.split('_'), i;\n\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  '幾秒',   '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  '1 分鐘', '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  '1 分鐘', '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 分鐘',  '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 分鐘', '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  '1 小時', '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  '1 小時', '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 小時',  '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 小時',  '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 小時', '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  '1 天',   '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  '1 天',   '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 天',   '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   '1 天',   '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 天',   '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 天',  '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  '1 個月', '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  '1 個月', '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  '1 個月', '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 個月',  '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 個月',  '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 個月',  '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   '1 個月', '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 個月',  '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), '1 年',   '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 年',   '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   '1 年',   '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 年',   '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), '幾秒內',  'prefix');\n    assert.equal(moment(0).from(30000), '幾秒前', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), '幾秒前',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), '幾秒內', 'in a few seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), '5 天內', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   '今天12:00', 'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      '今天12:25', 'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       '今天13:00', 'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       '明天12:00', 'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  '今天11:00', 'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  '昨天12:00', 'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('[下]ddddLT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[下]ddddLT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[下]ddddLT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('[上]ddddLT'),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[上]ddddLT'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[上]ddddLT'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),      '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),      '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('meridiem', function (assert) {\n    assert.equal(moment([2011, 2, 23,  0, 0]).format('a'), '凌晨', 'before dawn');\n    assert.equal(moment([2011, 2, 23,  6, 0]).format('a'), '早上', 'morning');\n    assert.equal(moment([2011, 2, 23,  9, 0]).format('a'), '上午', 'before noon');\n    assert.equal(moment([2011, 2, 23, 12, 0]).format('a'), '中午', 'noon');\n    assert.equal(moment([2011, 2, 23, 13, 0]).format('a'), '下午', 'after noon');\n    assert.equal(moment([2011, 2, 23, 18, 0]).format('a'), '晚上', 'night');\n\n    assert.equal(moment([2011, 2, 23,  0, 0]).format('A'), '凌晨', 'before dawn');\n    assert.equal(moment([2011, 2, 23,  6, 0]).format('A'), '早上', 'morning');\n    assert.equal(moment([2011, 2, 23,  9, 0]).format('A'), '上午', 'before noon');\n    assert.equal(moment([2011, 2, 23, 12, 0]).format('A'), '中午', 'noon');\n    assert.equal(moment([2011, 2, 23, 13, 0]).format('A'), '下午', 'afternoon');\n    assert.equal(moment([2011, 2, 23, 18, 0]).format('A'), '晚上', 'night');\n});\n\ntest('weeks year starting sunday format', function (assert) {\n    assert.equal(moment([2012, 0,  1]).format('w ww wo'), '1 01 1週', 'Jan  1 2012 應該是第 1週');\n    assert.equal(moment([2012, 0,  7]).format('w ww wo'), '1 01 1週', 'Jan  7 2012 應該是第 1週');\n    assert.equal(moment([2012, 0,  8]).format('w ww wo'), '2 02 2週', 'Jan  8 2012 應該是第 2週');\n    assert.equal(moment([2012, 0, 14]).format('w ww wo'), '2 02 2週', 'Jan 14 2012 應該是第 2週');\n    assert.equal(moment([2012, 0, 15]).format('w ww wo'), '3 03 3週', 'Jan 15 2012 應該是第 3週');\n});\n\n\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/test/moment/add_subtract.js",
    "content": "import { module, test, expect } from '../qunit';\nimport moment from '../../moment';\n\nmodule('add and subtract');\n\ntest('add short reverse args', function (assert) {\n    var a = moment(), b, c, d;\n    a.year(2011);\n    a.month(9);\n    a.date(12);\n    a.hours(6);\n    a.minutes(7);\n    a.seconds(8);\n    a.milliseconds(500);\n\n    assert.equal(a.add({ms: 50}).milliseconds(), 550, 'Add milliseconds');\n    assert.equal(a.add({s: 1}).seconds(), 9, 'Add seconds');\n    assert.equal(a.add({m: 1}).minutes(), 8, 'Add minutes');\n    assert.equal(a.add({h: 1}).hours(), 7, 'Add hours');\n    assert.equal(a.add({d: 1}).date(), 13, 'Add date');\n    assert.equal(a.add({w: 1}).date(), 20, 'Add week');\n    assert.equal(a.add({M: 1}).month(), 10, 'Add month');\n    assert.equal(a.add({y: 1}).year(), 2012, 'Add year');\n    assert.equal(a.add({Q: 1}).month(), 1, 'Add quarter');\n\n    b = moment([2010, 0, 31]).add({M: 1});\n    c = moment([2010, 1, 28]).subtract({M: 1});\n    d = moment([2010, 1, 28]).subtract({Q: 1});\n\n    assert.equal(b.month(), 1, 'add month, jan 31st to feb 28th');\n    assert.equal(b.date(), 28, 'add month, jan 31st to feb 28th');\n    assert.equal(c.month(), 0, 'subtract month, feb 28th to jan 28th');\n    assert.equal(c.date(), 28, 'subtract month, feb 28th to jan 28th');\n    assert.equal(d.month(), 10, 'subtract quarter, feb 28th 2010 to nov 28th 2009');\n    assert.equal(d.date(), 28, 'subtract quarter, feb 28th 2010 to nov 28th 2009');\n    assert.equal(d.year(), 2009, 'subtract quarter, feb 28th 2010 to nov 28th 2009');\n});\n\ntest('add long reverse args', function (assert) {\n    var a = moment();\n    a.year(2011);\n    a.month(9);\n    a.date(12);\n    a.hours(6);\n    a.minutes(7);\n    a.seconds(8);\n    a.milliseconds(500);\n\n    assert.equal(a.add({milliseconds: 50}).milliseconds(), 550, 'Add milliseconds');\n    assert.equal(a.add({seconds: 1}).seconds(), 9, 'Add seconds');\n    assert.equal(a.add({minutes: 1}).minutes(), 8, 'Add minutes');\n    assert.equal(a.add({hours: 1}).hours(), 7, 'Add hours');\n    assert.equal(a.add({days: 1}).date(), 13, 'Add date');\n    assert.equal(a.add({weeks: 1}).date(), 20, 'Add week');\n    assert.equal(a.add({months: 1}).month(), 10, 'Add month');\n    assert.equal(a.add({years: 1}).year(), 2012, 'Add year');\n    assert.equal(a.add({quarters: 1}).month(), 1, 'Add quarter');\n});\n\ntest('add long singular reverse args', function (assert) {\n    var a = moment();\n    a.year(2011);\n    a.month(9);\n    a.date(12);\n    a.hours(6);\n    a.minutes(7);\n    a.seconds(8);\n    a.milliseconds(500);\n\n    assert.equal(a.add({millisecond: 50}).milliseconds(), 550, 'Add milliseconds');\n    assert.equal(a.add({second: 1}).seconds(), 9, 'Add seconds');\n    assert.equal(a.add({minute: 1}).minutes(), 8, 'Add minutes');\n    assert.equal(a.add({hour: 1}).hours(), 7, 'Add hours');\n    assert.equal(a.add({day: 1}).date(), 13, 'Add date');\n    assert.equal(a.add({week: 1}).date(), 20, 'Add week');\n    assert.equal(a.add({month: 1}).month(), 10, 'Add month');\n    assert.equal(a.add({year: 1}).year(), 2012, 'Add year');\n    assert.equal(a.add({quarter: 1}).month(), 1, 'Add quarter');\n});\n\ntest('add string long reverse args', function (assert) {\n    var a = moment(), b;\n\n    test.expectedDeprecations('moment().add(period, number)');\n\n    a.year(2011);\n    a.month(9);\n    a.date(12);\n    a.hours(6);\n    a.minutes(7);\n    a.seconds(8);\n    a.milliseconds(500);\n\n    b = a.clone();\n\n    assert.equal(a.add('millisecond', 50).milliseconds(), 550, 'Add milliseconds');\n    assert.equal(a.add('second', 1).seconds(), 9, 'Add seconds');\n    assert.equal(a.add('minute', 1).minutes(), 8, 'Add minutes');\n    assert.equal(a.add('hour', 1).hours(), 7, 'Add hours');\n    assert.equal(a.add('day', 1).date(), 13, 'Add date');\n    assert.equal(a.add('week', 1).date(), 20, 'Add week');\n    assert.equal(a.add('month', 1).month(), 10, 'Add month');\n    assert.equal(a.add('year', 1).year(), 2012, 'Add year');\n    assert.equal(b.add('day', '01').date(), 13, 'Add date');\n    assert.equal(a.add('quarter', 1).month(), 1, 'Add quarter');\n});\n\ntest('add string long singular reverse args', function (assert) {\n    var a = moment(), b;\n\n    test.expectedDeprecations('moment().add(period, number)');\n\n    a.year(2011);\n    a.month(9);\n    a.date(12);\n    a.hours(6);\n    a.minutes(7);\n    a.seconds(8);\n    a.milliseconds(500);\n\n    b = a.clone();\n\n    assert.equal(a.add('milliseconds', 50).milliseconds(), 550, 'Add milliseconds');\n    assert.equal(a.add('seconds', 1).seconds(), 9, 'Add seconds');\n    assert.equal(a.add('minutes', 1).minutes(), 8, 'Add minutes');\n    assert.equal(a.add('hours', 1).hours(), 7, 'Add hours');\n    assert.equal(a.add('days', 1).date(), 13, 'Add date');\n    assert.equal(a.add('weeks', 1).date(), 20, 'Add week');\n    assert.equal(a.add('months', 1).month(), 10, 'Add month');\n    assert.equal(a.add('years', 1).year(), 2012, 'Add year');\n    assert.equal(b.add('days', '01').date(), 13, 'Add date');\n    assert.equal(a.add('quarters', 1).month(), 1, 'Add quarter');\n});\n\ntest('add string short reverse args', function (assert) {\n    var a = moment();\n    test.expectedDeprecations('moment().add(period, number)');\n\n    a.year(2011);\n    a.month(9);\n    a.date(12);\n    a.hours(6);\n    a.minutes(7);\n    a.seconds(8);\n    a.milliseconds(500);\n\n    assert.equal(a.add('ms', 50).milliseconds(), 550, 'Add milliseconds');\n    assert.equal(a.add('s', 1).seconds(), 9, 'Add seconds');\n    assert.equal(a.add('m', 1).minutes(), 8, 'Add minutes');\n    assert.equal(a.add('h', 1).hours(), 7, 'Add hours');\n    assert.equal(a.add('d', 1).date(), 13, 'Add date');\n    assert.equal(a.add('w', 1).date(), 20, 'Add week');\n    assert.equal(a.add('M', 1).month(), 10, 'Add month');\n    assert.equal(a.add('y', 1).year(), 2012, 'Add year');\n    assert.equal(a.add('Q', 1).month(), 1, 'Add quarter');\n});\n\ntest('add string long', function (assert) {\n    var a = moment();\n    a.year(2011);\n    a.month(9);\n    a.date(12);\n    a.hours(6);\n    a.minutes(7);\n    a.seconds(8);\n    a.milliseconds(500);\n\n    assert.equal(a.add(50, 'millisecond').milliseconds(), 550, 'Add milliseconds');\n    assert.equal(a.add(1, 'second').seconds(), 9, 'Add seconds');\n    assert.equal(a.add(1, 'minute').minutes(), 8, 'Add minutes');\n    assert.equal(a.add(1, 'hour').hours(), 7, 'Add hours');\n    assert.equal(a.add(1, 'day').date(), 13, 'Add date');\n    assert.equal(a.add(1, 'week').date(), 20, 'Add week');\n    assert.equal(a.add(1, 'month').month(), 10, 'Add month');\n    assert.equal(a.add(1, 'year').year(), 2012, 'Add year');\n    assert.equal(a.add(1, 'quarter').month(), 1, 'Add quarter');\n});\n\ntest('add string long singular', function (assert) {\n    var a = moment();\n    a.year(2011);\n    a.month(9);\n    a.date(12);\n    a.hours(6);\n    a.minutes(7);\n    a.seconds(8);\n    a.milliseconds(500);\n\n    assert.equal(a.add(50, 'milliseconds').milliseconds(), 550, 'Add milliseconds');\n    assert.equal(a.add(1, 'seconds').seconds(), 9, 'Add seconds');\n    assert.equal(a.add(1, 'minutes').minutes(), 8, 'Add minutes');\n    assert.equal(a.add(1, 'hours').hours(), 7, 'Add hours');\n    assert.equal(a.add(1, 'days').date(), 13, 'Add date');\n    assert.equal(a.add(1, 'weeks').date(), 20, 'Add week');\n    assert.equal(a.add(1, 'months').month(), 10, 'Add month');\n    assert.equal(a.add(1, 'years').year(), 2012, 'Add year');\n    assert.equal(a.add(1, 'quarters').month(), 1, 'Add quarter');\n});\n\ntest('add string short', function (assert) {\n    var a = moment();\n    a.year(2011);\n    a.month(9);\n    a.date(12);\n    a.hours(6);\n    a.minutes(7);\n    a.seconds(8);\n    a.milliseconds(500);\n\n    assert.equal(a.add(50, 'ms').milliseconds(), 550, 'Add milliseconds');\n    assert.equal(a.add(1, 's').seconds(), 9, 'Add seconds');\n    assert.equal(a.add(1, 'm').minutes(), 8, 'Add minutes');\n    assert.equal(a.add(1, 'h').hours(), 7, 'Add hours');\n    assert.equal(a.add(1, 'd').date(), 13, 'Add date');\n    assert.equal(a.add(1, 'w').date(), 20, 'Add week');\n    assert.equal(a.add(1, 'M').month(), 10, 'Add month');\n    assert.equal(a.add(1, 'y').year(), 2012, 'Add year');\n    assert.equal(a.add(1, 'Q').month(), 1, 'Add quarter');\n});\n\ntest('add strings string short reversed', function (assert) {\n    var a = moment();\n    test.expectedDeprecations('moment().add(period, number)');\n\n    a.year(2011);\n    a.month(9);\n    a.date(12);\n    a.hours(6);\n    a.minutes(7);\n    a.seconds(8);\n    a.milliseconds(500);\n\n    assert.equal(a.add('ms', '50').milliseconds(), 550, 'Add milliseconds');\n    assert.equal(a.add('s', '1').seconds(), 9, 'Add seconds');\n    assert.equal(a.add('m', '1').minutes(), 8, 'Add minutes');\n    assert.equal(a.add('h', '1').hours(), 7, 'Add hours');\n    assert.equal(a.add('d', '1').date(), 13, 'Add date');\n    assert.equal(a.add('w', '1').date(), 20, 'Add week');\n    assert.equal(a.add('M', '1').month(), 10, 'Add month');\n    assert.equal(a.add('y', '1').year(), 2012, 'Add year');\n    assert.equal(a.add('Q', '1').month(), 1, 'Add quarter');\n});\n\ntest('subtract strings string short reversed', function (assert) {\n    var a = moment();\n    test.expectedDeprecations('moment().subtract(period, number)');\n\n    a.year(2011);\n    a.month(9);\n    a.date(12);\n    a.hours(6);\n    a.minutes(7);\n    a.seconds(8);\n    a.milliseconds(500);\n\n    assert.equal(a.subtract('ms', '50').milliseconds(), 450, 'Subtract milliseconds');\n    assert.equal(a.subtract('s', '1').seconds(), 7, 'Subtract seconds');\n    assert.equal(a.subtract('m', '1').minutes(), 6, 'Subtract minutes');\n    assert.equal(a.subtract('h', '1').hours(), 5, 'Subtract hours');\n    assert.equal(a.subtract('d', '1').date(), 11, 'Subtract date');\n    assert.equal(a.subtract('w', '1').date(), 4, 'Subtract week');\n    assert.equal(a.subtract('M', '1').month(), 8, 'Subtract month');\n    assert.equal(a.subtract('y', '1').year(), 2010, 'Subtract year');\n    assert.equal(a.subtract('Q', '1').month(), 5, 'Subtract quarter');\n});\n\ntest('add strings string short', function (assert) {\n    var a = moment();\n    a.year(2011);\n    a.month(9);\n    a.date(12);\n    a.hours(6);\n    a.minutes(7);\n    a.seconds(8);\n    a.milliseconds(500);\n\n    assert.equal(a.add('50', 'ms').milliseconds(), 550, 'Add milliseconds');\n    assert.equal(a.add('1', 's').seconds(), 9, 'Add seconds');\n    assert.equal(a.add('1', 'm').minutes(), 8, 'Add minutes');\n    assert.equal(a.add('1', 'h').hours(), 7, 'Add hours');\n    assert.equal(a.add('1', 'd').date(), 13, 'Add date');\n    assert.equal(a.add('1', 'w').date(), 20, 'Add week');\n    assert.equal(a.add('1', 'M').month(), 10, 'Add month');\n    assert.equal(a.add('1', 'y').year(), 2012, 'Add year');\n    assert.equal(a.add('1', 'Q').month(), 1, 'Add quarter');\n});\n\ntest('add no string with milliseconds default', function (assert) {\n    var a = moment();\n    a.year(2011);\n    a.month(9);\n    a.date(12);\n    a.hours(6);\n    a.minutes(7);\n    a.seconds(8);\n    a.milliseconds(500);\n\n    assert.equal(a.add(50).milliseconds(), 550, 'Add milliseconds');\n});\n\ntest('subtract strings string short', function (assert) {\n    var a = moment();\n    a.year(2011);\n    a.month(9);\n    a.date(12);\n    a.hours(6);\n    a.minutes(7);\n    a.seconds(8);\n    a.milliseconds(500);\n\n    assert.equal(a.subtract('50', 'ms').milliseconds(), 450, 'Subtract milliseconds');\n    assert.equal(a.subtract('1', 's').seconds(), 7, 'Subtract seconds');\n    assert.equal(a.subtract('1', 'm').minutes(), 6, 'Subtract minutes');\n    assert.equal(a.subtract('1', 'h').hours(), 5, 'Subtract hours');\n    assert.equal(a.subtract('1', 'd').date(), 11, 'Subtract date');\n    assert.equal(a.subtract('1', 'w').date(), 4, 'Subtract week');\n    assert.equal(a.subtract('1', 'M').month(), 8, 'Subtract month');\n    assert.equal(a.subtract('1', 'y').year(), 2010, 'Subtract year');\n    assert.equal(a.subtract('1', 'Q').month(), 5, 'Subtract quarter');\n});\n\ntest('add across DST', function (assert) {\n    // Detect Safari bug and bail. Hours on 13th March 2011 are shifted\n    // with 1 ahead.\n    if (new Date(2011, 2, 13, 5, 0, 0).getHours() !== 5) {\n        expect(0);\n        return;\n    }\n\n    var a = moment(new Date(2011, 2, 12, 5, 0, 0)),\n        b = moment(new Date(2011, 2, 12, 5, 0, 0)),\n        c = moment(new Date(2011, 2, 12, 5, 0, 0)),\n        d = moment(new Date(2011, 2, 12, 5, 0, 0)),\n        e = moment(new Date(2011, 2, 12, 5, 0, 0));\n    a.add(1, 'days');\n    b.add(24, 'hours');\n    c.add(1, 'months');\n    e.add(1, 'quarter');\n\n    assert.equal(a.hours(), 5, 'adding days over DST difference should result in the same hour');\n    if (b.isDST() && !d.isDST()) {\n        assert.equal(b.hours(), 6, 'adding hours over DST difference should result in a different hour');\n    } else if (!b.isDST() && d.isDST()) {\n        assert.equal(b.hours(), 4, 'adding hours over DST difference should result in a different hour');\n    } else {\n        assert.equal(b.hours(), 5, 'adding hours over DST difference should result in a same hour if the timezone does not have daylight savings time');\n    }\n    assert.equal(c.hours(), 5, 'adding months over DST difference should result in the same hour');\n    assert.equal(e.hours(), 5, 'adding quarters over DST difference should result in the same hour');\n});\n\ntest('add decimal values of days and months', function (assert) {\n    assert.equal(moment([2016,3,3]).add(1.5, 'days').date(), 5, 'adding 1.5 days is rounded to adding 2 day');\n    assert.equal(moment([2016,3,3]).add(-1.5, 'days').date(), 1, 'adding -1.5 days is rounded to adding -2 day');\n    assert.equal(moment([2016,3,1]).add(-1.5, 'days').date(), 30, 'adding -1.5 days on first of month wraps around');\n    assert.equal(moment([2016,3,3]).add(1.5, 'months').month(), 5, 'adding 1.5 months adds 2 months');\n    assert.equal(moment([2016,3,3]).add(-1.5, 'months').month(), 1, 'adding -1.5 months adds -2 months');\n    assert.equal(moment([2016,0,3]).add(-1.5, 'months').month(), 10, 'adding -1.5 months at start of year wraps back');\n    assert.equal(moment([2016,3,3]).subtract(1.5, 'days').date(),1, 'subtract 1.5 days is rounded to subtract 2 day');\n    assert.equal(moment([2016,3,2]).subtract(1.5, 'days').date(), 31, 'subtract 1.5 days subtracts 2 days');\n    assert.equal(moment([2016,1,1]).subtract(1.1, 'days').date(), 31, 'subtract 1.1 days wraps to previous month');\n    assert.equal(moment([2016,3,3]).subtract(-1.5, 'days').date(), 5, 'subtract -1.5 days is rounded to subtract -2 day');\n    assert.equal(moment([2016,3,30]).subtract(-1.5, 'days').date(), 2, 'subtract -1.5 days on last of month wraps around');\n    assert.equal(moment([2016,3,3]).subtract(1.5, 'months').month(), 1, 'subtract 1.5 months subtract 2 months');\n    assert.equal(moment([2016,3,3]).subtract(-1.5, 'months').month(), 5, 'subtract -1.5 months subtract -2 month');\n    assert.equal(moment([2016,11,31]).subtract(-1.5, 'months').month(),1, 'subtract -1.5 months at end of year wraps back');\n    assert.equal(moment([2016, 0,1]).add(1.5, 'years').format('YYYY-MM-DD'), '2017-07-01', 'add 1.5 years adds 1 year six months');\n    assert.equal(moment([2016, 0,1]).add(1.6, 'years').format('YYYY-MM-DD'), '2017-08-01', 'add 1.6 years becomes 1.6*12 = 19.2, round, 19 months');\n    assert.equal(moment([2016,0,1]).add(1.1, 'quarters').format('YYYY-MM-DD'), '2016-04-01', 'add 1.1 quarters 1.1*3=3.3, round, 3 months');\n});\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/test/moment/calendar.js",
    "content": "// These tests are for locale independent features\n// locale dependent tests would be in locale test folder\nimport { module, test } from '../qunit';\nimport moment from '../../moment';\n\nmodule('calendar');\n\ntest('passing a function', function (assert) {\n    var a  = moment().hours(13).minutes(0).seconds(0);\n    assert.equal(moment(a).calendar(null, {\n        'sameDay': function () {\n            return 'h:mmA';\n        }\n    }), '1:00PM', 'should equate');\n});\n\ntest('extending calendar options', function (assert) {\n    var calendarFormat = moment.calendarFormat;\n\n    moment.calendarFormat = function (myMoment, now) {\n        var diff = myMoment.diff(now, 'days', true);\n        var nextMonth = now.clone().add(1, 'month');\n\n        var retVal =  diff < -6 ? 'sameElse' :\n            diff < -1 ? 'lastWeek' :\n            diff < 0 ? 'lastDay' :\n            diff < 1 ? 'sameDay' :\n            diff < 2 ? 'nextDay' :\n            diff < 7 ? 'nextWeek' :\n            (myMoment.month() === now.month() && myMoment.year() === now.year()) ? 'thisMonth' :\n            (nextMonth.month() === myMoment.month() && nextMonth.year() === myMoment.year()) ? 'nextMonth' : 'sameElse';\n        return retVal;\n    };\n\n    moment.updateLocale('en', {\n        calendar : {\n                sameDay : '[Today at] LT',\n                nextDay : '[Tomorrow at] LT',\n                nextWeek : 'dddd [at] LT',\n                lastDay : '[Yesterday at] LT',\n                lastWeek : '[Last] dddd [at] LT',\n                thisMonth : '[This month on the] Do',\n                nextMonth : '[Next month on the] Do',\n                sameElse : 'L'\n            }\n    });\n    var a = moment('2016-01-01').add(28, 'days');\n    var b = moment('2016-01-01').add(1, 'month');\n    try {\n        assert.equal(a.calendar('2016-01-01'), 'This month on the 29th', 'Ad hoc calendar format for this month');\n        assert.equal(b.calendar('2016-01-01'), 'Next month on the 1st', 'Ad hoc calendar format for next month');\n        assert.equal(a.locale('fr').calendar('2016-01-01'), a.locale('fr').format('L'), 'French falls back to default because thisMonth is not defined in that locale');\n    } finally {\n        moment.calendarFormat = calendarFormat;\n        moment.updateLocale('en', null);\n    }\n});\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/test/moment/create.js",
    "content": "import { module, test } from '../qunit';\nimport moment from '../../moment';\n\nmodule('create');\n\ntest('array', function (assert) {\n    assert.ok(moment([2010]).toDate() instanceof Date, '[2010]');\n    assert.ok(moment([2010, 1]).toDate() instanceof Date, '[2010, 1]');\n    assert.ok(moment([2010, 1, 12]).toDate() instanceof Date, '[2010, 1, 12]');\n    assert.ok(moment([2010, 1, 12, 1]).toDate() instanceof Date, '[2010, 1, 12, 1]');\n    assert.ok(moment([2010, 1, 12, 1, 1]).toDate() instanceof Date, '[2010, 1, 12, 1, 1]');\n    assert.ok(moment([2010, 1, 12, 1, 1, 1]).toDate() instanceof Date, '[2010, 1, 12, 1, 1, 1]');\n    assert.ok(moment([2010, 1, 12, 1, 1, 1, 1]).toDate() instanceof Date, '[2010, 1, 12, 1, 1, 1, 1]');\n    assert.equal(+moment(new Date(2010, 1, 14, 15, 25, 50, 125)), +moment([2010, 1, 14, 15, 25, 50, 125]), 'constructing with array === constructing with new Date()');\n});\n\ntest('array with invalid arguments', function (assert) {\n    assert.ok(!moment([2010, null, null]).isValid(), '[2010, null, null]');\n    assert.ok(!moment([1945, null, null]).isValid(), '[1945, null, null] (pre-1970)');\n});\n\ntest('array copying', function (assert) {\n    var importantArray = [2009, 11];\n    moment(importantArray);\n    assert.deepEqual(importantArray, [2009, 11], 'initializer should not mutate the original array');\n});\n\ntest('object', function (assert) {\n    var fmt = 'YYYY-MM-DD HH:mm:ss.SSS',\n        tests = [\n            [{year: 2010}, '2010-01-01 00:00:00.000'],\n            [{year: 2010, month: 1}, '2010-02-01 00:00:00.000'],\n            [{year: 2010, month: 1, day: 12}, '2010-02-12 00:00:00.000'],\n            [{year: 2010, month: 1, date: 12}, '2010-02-12 00:00:00.000'],\n            [{year: 2010, month: 1, day: 12, hours: 1}, '2010-02-12 01:00:00.000'],\n            [{year: 2010, month: 1, date: 12, hours: 1}, '2010-02-12 01:00:00.000'],\n            [{year: 2010, month: 1, day: 12, hours: 1, minutes: 1}, '2010-02-12 01:01:00.000'],\n            [{year: 2010, month: 1, date: 12, hours: 1, minutes: 1}, '2010-02-12 01:01:00.000'],\n            [{year: 2010, month: 1, day: 12, hours: 1, minutes: 1, seconds: 1}, '2010-02-12 01:01:01.000'],\n            [{year: 2010, month: 1, day: 12, hours: 1, minutes: 1, seconds: 1, milliseconds: 1}, '2010-02-12 01:01:01.001'],\n            [{years: 2010, months: 1, days: 14, hours: 15, minutes: 25, seconds: 50, milliseconds: 125}, '2010-02-14 15:25:50.125'],\n            [{year: 2010, month: 1, day: 14, hour: 15, minute: 25, second: 50, millisecond: 125}, '2010-02-14 15:25:50.125'],\n            [{y: 2010, M: 1, d: 14, h: 15, m: 25, s: 50, ms: 125}, '2010-02-14 15:25:50.125']\n        ], i;\n    for (i = 0; i < tests.length; ++i) {\n        assert.equal(moment(tests[i][0]).format(fmt), tests[i][1]);\n    }\n});\n\ntest('multi format array copying', function (assert) {\n    var importantArray = ['MM/DD/YYYY', 'YYYY-MM-DD', 'MM-DD-YYYY'];\n    moment('1999-02-13', importantArray);\n    assert.deepEqual(importantArray, ['MM/DD/YYYY', 'YYYY-MM-DD', 'MM-DD-YYYY'], 'initializer should not mutate the original array');\n});\n\ntest('number', function (assert) {\n    assert.ok(moment(1000).toDate() instanceof Date, '1000');\n    assert.equal(moment(1000).valueOf(), 1000, 'asserting valueOf');\n    assert.equal(moment.utc(1000).valueOf(), 1000, 'asserting valueOf');\n});\n\ntest('unix', function (assert) {\n    assert.equal(moment.unix(1).valueOf(), 1000, '1 unix timestamp == 1000 Date.valueOf');\n    assert.equal(moment(1000).unix(), 1, '1000 Date.valueOf == 1 unix timestamp');\n    assert.equal(moment.unix(1000).valueOf(), 1000000, '1000 unix timestamp == 1000000 Date.valueOf');\n    assert.equal(moment(1500).unix(), 1, '1500 Date.valueOf == 1 unix timestamp');\n    assert.equal(moment(1900).unix(), 1, '1900 Date.valueOf == 1 unix timestamp');\n    assert.equal(moment(2100).unix(), 2, '2100 Date.valueOf == 2 unix timestamp');\n    assert.equal(moment(1333129333524).unix(), 1333129333, '1333129333524 Date.valueOf == 1333129333 unix timestamp');\n    assert.equal(moment(1333129333524000).unix(), 1333129333524, '1333129333524000 Date.valueOf == 1333129333524 unix timestamp');\n});\n\ntest('date', function (assert) {\n    assert.ok(moment(new Date()).toDate() instanceof Date, 'new Date()');\n    assert.equal(moment(new Date(2016,0,1), 'YYYY-MM-DD').format('YYYY-MM-DD'), '2016-01-01', 'If date is provided, format string is ignored');\n});\n\ntest('date with a format as an array', function (assert) {\n    var tests = [\n        new Date(2016, 9, 27),\n        new Date(2016, 9, 28),\n        new Date(2016, 9, 29),\n        new Date(2016, 9, 30),\n        new Date(2016, 9, 31)\n    ], i;\n\n    for (i = 0; i < tests.length; i++) {\n        assert.equal(moment(tests[i]).format(), moment(tests[i], ['MM/DD/YYYY'], false).format(), 'Passing date with a format array should still return the correct date');\n    }\n});\n\ntest('date mutation', function (assert) {\n    var a = new Date();\n    assert.ok(moment(a).toDate() !== a, 'the date moment uses should not be the date passed in');\n});\n\ntest('moment', function (assert) {\n    assert.ok(moment(moment()).toDate() instanceof Date, 'moment(moment())');\n    assert.ok(moment(moment(moment())).toDate() instanceof Date, 'moment(moment(moment()))');\n});\n\ntest('cloning moment should only copy own properties', function (assert) {\n    assert.ok(!moment().clone().hasOwnProperty('month'), 'Should not clone prototype methods');\n});\n\ntest('cloning moment works with weird clones', function (assert) {\n    var extend = function (a, b) {\n        var i;\n        for (i in b) {\n            a[i] = b[i];\n        }\n        return a;\n    },\n    now = moment(),\n    nowu = moment.utc();\n\n    assert.equal(+extend({}, now).clone(), +now, 'cloning extend-ed now is now');\n    assert.equal(+extend({}, nowu).clone(), +nowu, 'cloning extend-ed utc now is utc now');\n});\n\ntest('cloning respects moment.momentProperties', function (assert) {\n    var m = moment();\n\n    assert.equal(m.clone()._special, undefined, 'cloning ignores extra properties');\n    m._special = 'bacon';\n    moment.momentProperties.push('_special');\n    assert.equal(m.clone()._special, 'bacon', 'cloning respects momentProperties');\n    moment.momentProperties.pop();\n});\n\ntest('undefined', function (assert) {\n    assert.ok(moment().toDate() instanceof Date, 'undefined');\n});\n\ntest('iso with bad input', function (assert) {\n    assert.ok(!moment('a', moment.ISO_8601).isValid(), 'iso parsing with invalid string');\n    assert.ok(!moment('a', moment.ISO_8601, true).isValid(), 'iso parsing with invalid string, strict');\n});\n\ntest('iso format 24hrs', function (assert) {\n    assert.equal(moment('2014-01-01T24:00:00.000').format('YYYY-MM-DD[T]HH:mm:ss.SSS'),\n            '2014-01-02T00:00:00.000', 'iso format with 24:00 localtime');\n    assert.equal(moment.utc('2014-01-01T24:00:00.000').format('YYYY-MM-DD[T]HH:mm:ss.SSS'),\n            '2014-01-02T00:00:00.000', 'iso format with 24:00 utc');\n});\n\ntest('string without format - json', function (assert) {\n    assert.equal(moment('Date(1325132654000)').valueOf(), 1325132654000, 'Date(1325132654000)');\n    assert.equal(moment('Date(-1325132654000)').valueOf(), -1325132654000, 'Date(-1325132654000)');\n    assert.equal(moment('/Date(1325132654000)/').valueOf(), 1325132654000, '/Date(1325132654000)/');\n    assert.equal(moment('/Date(1325132654000+0700)/').valueOf(), 1325132654000, '/Date(1325132654000+0700)/');\n    assert.equal(moment('/Date(1325132654000-0700)/').valueOf(), 1325132654000, '/Date(1325132654000-0700)/');\n});\n\ntest('string with format dropped am/pm bug', function (assert) {\n    moment.locale('en');\n\n    assert.equal(moment('05/1/2012 12:25:00', 'MM/DD/YYYY h:m:s a').format('MM/DD/YYYY'), '05/01/2012', 'should not break if am/pm is left off from the parsing tokens');\n    assert.equal(moment('05/1/2012 12:25:00 am', 'MM/DD/YYYY h:m:s a').format('MM/DD/YYYY'), '05/01/2012', 'should not break if am/pm is left off from the parsing tokens');\n    assert.equal(moment('05/1/2012 12:25:00 pm', 'MM/DD/YYYY h:m:s a').format('MM/DD/YYYY'), '05/01/2012', 'should not break if am/pm is left off from the parsing tokens');\n\n    assert.ok(moment('05/1/2012 12:25:00', 'MM/DD/YYYY h:m:s a').isValid());\n    assert.ok(moment('05/1/2012 12:25:00 am', 'MM/DD/YYYY h:m:s a').isValid());\n    assert.ok(moment('05/1/2012 12:25:00 pm', 'MM/DD/YYYY h:m:s a').isValid());\n});\n\ntest('empty string with formats', function (assert) {\n    assert.equal(moment('', 'MM').format('YYYY-MM-DD HH:mm:ss'), 'Invalid date');\n    assert.equal(moment(' ', 'MM').format('YYYY-MM-DD HH:mm:ss'), 'Invalid date');\n    assert.equal(moment(' ', 'DD').format('YYYY-MM-DD HH:mm:ss'), 'Invalid date');\n    assert.equal(moment(' ', ['MM', 'DD']).format('YYYY-MM-DD HH:mm:ss'), 'Invalid date');\n\n    assert.ok(!moment('', 'MM').isValid());\n    assert.ok(!moment(' ', 'MM').isValid());\n    assert.ok(!moment(' ', 'DD').isValid());\n    assert.ok(!moment(' ', ['MM', 'DD']).isValid());\n});\n\ntest('undefined argument with formats', function (assert) {\n    assert.equal(moment(undefined, 'MM').format('YYYY-MM-DD HH:mm:ss'), 'Invalid date');\n    assert.equal(moment(undefined, 'DD').format('YYYY-MM-DD HH:mm:ss'), 'Invalid date');\n    assert.equal(moment(undefined, ['MM', 'DD']).format('YYYY-MM-DD HH:mm:ss'), 'Invalid date');\n\n    assert.ok(!moment(undefined, 'MM').isValid());\n    assert.ok(!moment(undefined, 'MM').isValid());\n    assert.ok(!moment(undefined, 'DD').isValid());\n    assert.ok(!moment(undefined, ['MM', 'DD']).isValid());\n});\n\ntest('defaulting to current date', function (assert) {\n    var now = moment();\n    assert.equal(moment('12:13:14', 'hh:mm:ss').format('YYYY-MM-DD hh:mm:ss'),\n                 now.clone().hour(12).minute(13).second(14).format('YYYY-MM-DD hh:mm:ss'),\n                 'given only time default to current date');\n    assert.equal(moment('05', 'DD').format('YYYY-MM-DD'),\n                 now.clone().date(5).format('YYYY-MM-DD'),\n                 'given day of month default to current month, year');\n    assert.equal(moment('05', 'MM').format('YYYY-MM-DD'),\n                 now.clone().month(4).date(1).format('YYYY-MM-DD'),\n                 'given month default to current year');\n    assert.equal(moment('1996', 'YYYY').format('YYYY-MM-DD'),\n                 now.clone().year(1996).month(0).date(1).format('YYYY-MM-DD'),\n                 'given year do not default');\n});\n\ntest('matching am/pm', function (assert) {\n    assert.equal(moment('2012-09-03T03:00PM',   'YYYY-MM-DDThh:mmA').format('YYYY-MM-DDThh:mmA'), '2012-09-03T03:00PM', 'am/pm should parse correctly for PM');\n    assert.equal(moment('2012-09-03T03:00P.M.', 'YYYY-MM-DDThh:mmA').format('YYYY-MM-DDThh:mmA'), '2012-09-03T03:00PM', 'am/pm should parse correctly for P.M.');\n    assert.equal(moment('2012-09-03T03:00P',    'YYYY-MM-DDThh:mmA').format('YYYY-MM-DDThh:mmA'), '2012-09-03T03:00PM', 'am/pm should parse correctly for P');\n    assert.equal(moment('2012-09-03T03:00pm',   'YYYY-MM-DDThh:mmA').format('YYYY-MM-DDThh:mmA'), '2012-09-03T03:00PM', 'am/pm should parse correctly for pm');\n    assert.equal(moment('2012-09-03T03:00p.m.', 'YYYY-MM-DDThh:mmA').format('YYYY-MM-DDThh:mmA'), '2012-09-03T03:00PM', 'am/pm should parse correctly for p.m.');\n    assert.equal(moment('2012-09-03T03:00p',    'YYYY-MM-DDThh:mmA').format('YYYY-MM-DDThh:mmA'), '2012-09-03T03:00PM', 'am/pm should parse correctly for p');\n\n    assert.equal(moment('2012-09-03T03:00AM',   'YYYY-MM-DDThh:mmA').format('YYYY-MM-DDThh:mmA'), '2012-09-03T03:00AM', 'am/pm should parse correctly for AM');\n    assert.equal(moment('2012-09-03T03:00A.M.', 'YYYY-MM-DDThh:mmA').format('YYYY-MM-DDThh:mmA'), '2012-09-03T03:00AM', 'am/pm should parse correctly for A.M.');\n    assert.equal(moment('2012-09-03T03:00A',    'YYYY-MM-DDThh:mmA').format('YYYY-MM-DDThh:mmA'), '2012-09-03T03:00AM', 'am/pm should parse correctly for A');\n    assert.equal(moment('2012-09-03T03:00am',   'YYYY-MM-DDThh:mmA').format('YYYY-MM-DDThh:mmA'), '2012-09-03T03:00AM', 'am/pm should parse correctly for am');\n    assert.equal(moment('2012-09-03T03:00a.m.', 'YYYY-MM-DDThh:mmA').format('YYYY-MM-DDThh:mmA'), '2012-09-03T03:00AM', 'am/pm should parse correctly for a.m.');\n    assert.equal(moment('2012-09-03T03:00a',    'YYYY-MM-DDThh:mmA').format('YYYY-MM-DDThh:mmA'), '2012-09-03T03:00AM', 'am/pm should parse correctly for a');\n\n    assert.equal(moment('5:00p.m.March 4 2012', 'h:mmAMMMM D YYYY').format('YYYY-MM-DDThh:mmA'), '2012-03-04T05:00PM', 'am/pm should parse correctly before month names');\n});\n\ntest('string with format', function (assert) {\n    moment.locale('en');\n    var a = [\n        ['YYYY-Q',              '2014-4'],\n        ['MM-DD-YYYY',          '12-02-1999'],\n        ['DD-MM-YYYY',          '12-02-1999'],\n        ['DD/MM/YYYY',          '12/02/1999'],\n        ['DD_MM_YYYY',          '12_02_1999'],\n        ['DD:MM:YYYY',          '12:02:1999'],\n        ['D-M-YY',              '2-2-99'],\n        ['YY',                  '99'],\n        ['DDD-YYYY',            '300-1999'],\n        ['DD-MM-YYYY h:m:s',    '12-02-1999 2:45:10'],\n        ['DD-MM-YYYY h:m:s a',  '12-02-1999 2:45:10 am'],\n        ['DD-MM-YYYY h:m:s a',  '12-02-1999 2:45:10 pm'],\n        ['h:mm a',              '12:00 pm'],\n        ['h:mm a',              '12:30 pm'],\n        ['h:mm a',              '12:00 am'],\n        ['h:mm a',              '12:30 am'],\n        ['HH:mm',               '12:00'],\n        ['kk:mm',               '12:00'],\n        ['YYYY-MM-DDTHH:mm:ss', '2011-11-11T11:11:11'],\n        ['MM-DD-YYYY [M]',      '12-02-1999 M'],\n        ['ddd MMM DD HH:mm:ss YYYY', 'Tue Apr 07 22:52:51 2009'],\n        ['HH:mm:ss',            '12:00:00'],\n        ['HH:mm:ss',            '12:30:00'],\n        ['HH:mm:ss',            '00:00:00'],\n        ['HH:mm:ss S',          '00:30:00 1'],\n        ['HH:mm:ss SS',         '00:30:00 12'],\n        ['HH:mm:ss SSS',        '00:30:00 123'],\n        ['HH:mm:ss S',          '00:30:00 7'],\n        ['HH:mm:ss SS',         '00:30:00 78'],\n        ['HH:mm:ss SSS',        '00:30:00 789'],\n        ['kk:mm:ss',            '12:00:00'],\n        ['kk:mm:ss',            '12:30:00'],\n        ['kk:mm:ss',            '24:00:00'],\n        ['kk:mm:ss S',          '24:30:00 1'],\n        ['kk:mm:ss SS',         '24:30:00 12'],\n        ['kk:mm:ss SSS',        '24:30:00 123'],\n        ['kk:mm:ss S',          '24:30:00 7'],\n        ['kk:mm:ss SS',         '24:30:00 78'],\n        ['kk:mm:ss SSS',        '24:30:00 789'],\n        ['X',                   '1234567890'],\n        ['x',                   '1234567890123'],\n        ['LT',                  '12:30 AM'],\n        ['LTS',                 '12:30:29 AM'],\n        ['L',                   '09/02/1999'],\n        ['l',                   '9/2/1999'],\n        ['LL',                  'September 2, 1999'],\n        ['ll',                  'Sep 2, 1999'],\n        ['LLL',                 'September 2, 1999 12:30 AM'],\n        ['lll',                 'Sep 2, 1999 12:30 AM'],\n        ['LLLL',                'Thursday, September 2, 1999 12:30 AM'],\n        ['llll',                'Thu, Sep 2, 1999 12:30 AM']\n    ],\n    m,\n    i;\n\n    for (i = 0; i < a.length; i++) {\n        m = moment(a[i][1], a[i][0]);\n        assert.ok(m.isValid());\n        assert.equal(m.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('2 digit year with YYYY format', function (assert) {\n    assert.equal(moment('9/2/99', 'D/M/YYYY').format('DD/MM/YYYY'), '09/02/1999', 'D/M/YYYY ---> 9/2/99');\n    assert.equal(moment('9/2/1999', 'D/M/YYYY').format('DD/MM/YYYY'), '09/02/1999', 'D/M/YYYY ---> 9/2/1999');\n    assert.equal(moment('9/2/68', 'D/M/YYYY').format('DD/MM/YYYY'), '09/02/2068', 'D/M/YYYY ---> 9/2/68');\n    assert.equal(moment('9/2/69', 'D/M/YYYY').format('DD/MM/YYYY'), '09/02/1969', 'D/M/YYYY ---> 9/2/69');\n});\n\ntest('unix timestamp format', function (assert) {\n    var formats = ['X', 'X.S', 'X.SS', 'X.SSS'], i, format;\n\n    for (i = 0; i < formats.length; i++) {\n        format = formats[i];\n        assert.equal(moment('1234567890',     format).valueOf(), 1234567890 * 1000,       format + ' matches timestamp without milliseconds');\n        assert.equal(moment('1234567890.1',   format).valueOf(), 1234567890 * 1000 + 100, format + ' matches timestamp with deciseconds');\n        assert.equal(moment('1234567890.12',  format).valueOf(), 1234567890 * 1000 + 120, format + ' matches timestamp with centiseconds');\n        assert.equal(moment('1234567890.123', format).valueOf(), 1234567890 * 1000 + 123, format + ' matches timestamp with milliseconds');\n    }\n});\n\ntest('unix offset milliseconds', function (assert) {\n    assert.equal(moment('1234567890123', 'x').valueOf(), 1234567890123, 'x matches unix offset in milliseconds');\n});\n\ntest('milliseconds format', function (assert) {\n    assert.equal(moment('1', 'S').get('ms'), 100, 'deciseconds');\n    // assert.equal(moment('10', 'S', true).isValid(), false, 'deciseconds with two digits');\n    // assert.equal(moment('1', 'SS', true).isValid(), false, 'centiseconds with one digits');\n    assert.equal(moment('12', 'SS').get('ms'), 120, 'centiseconds');\n    // assert.equal(moment('123', 'SS', true).isValid(), false, 'centiseconds with three digits');\n    assert.equal(moment('123', 'SSS').get('ms'), 123, 'milliseconds');\n    assert.equal(moment('1234', 'SSSS').get('ms'), 123, 'milliseconds with SSSS');\n    assert.equal(moment('123456789101112', 'SSSS').get('ms'), 123, 'milliseconds with SSSS');\n});\n\ntest('string with format no separators', function (assert) {\n    moment.locale('en');\n    var a = [\n        ['MMDDYYYY',          '12021999'],\n        ['DDMMYYYY',          '12021999'],\n        ['YYYYMMDD',          '19991202'],\n        ['DDMMMYYYY',         '10Sep2001']\n    ], i;\n\n    for (i = 0; i < a.length; i++) {\n        assert.equal(moment(a[i][1], a[i][0]).format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('string with format (timezone)', function (assert) {\n    assert.equal(moment('5 -0700', 'H ZZ').toDate().getUTCHours(), 12, 'parse hours \\'5 -0700\\' ---> \\'H ZZ\\'');\n    assert.equal(moment('5 -07:00', 'H Z').toDate().getUTCHours(), 12, 'parse hours \\'5 -07:00\\' ---> \\'H Z\\'');\n    assert.equal(moment('5 -0730', 'H ZZ').toDate().getUTCMinutes(), 30, 'parse hours \\'5 -0730\\' ---> \\'H ZZ\\'');\n    assert.equal(moment('5 -07:30', 'H Z').toDate().getUTCMinutes(), 30, 'parse hours \\'5 -07:0\\' ---> \\'H Z\\'');\n    assert.equal(moment('5 +0100', 'H ZZ').toDate().getUTCHours(), 4, 'parse hours \\'5 +0100\\' ---> \\'H ZZ\\'');\n    assert.equal(moment('5 +01:00', 'H Z').toDate().getUTCHours(), 4, 'parse hours \\'5 +01:00\\' ---> \\'H Z\\'');\n    assert.equal(moment('5 +0130', 'H ZZ').toDate().getUTCMinutes(), 30, 'parse hours \\'5 +0130\\' ---> \\'H ZZ\\'');\n    assert.equal(moment('5 +01:30', 'H Z').toDate().getUTCMinutes(), 30, 'parse hours \\'5 +01:30\\' ---> \\'H Z\\'');\n});\n\ntest('string with format (timezone offset)', function (assert) {\n    var a, b, c, d, e, f;\n    a = new Date(Date.UTC(2011, 0, 1, 1));\n    b = moment('2011 1 1 0 -01:00', 'YYYY MM DD HH Z');\n    assert.equal(a.getHours(), b.hours(), 'date created with utc == parsed string with timezone offset');\n    assert.equal(+a, +b, 'date created with utc == parsed string with timezone offset');\n    c = moment('2011 2 1 10 -05:00', 'YYYY MM DD HH Z');\n    d = moment('2011 2 1 8 -07:00', 'YYYY MM DD HH Z');\n    assert.equal(c.hours(), d.hours(), '10 am central time == 8 am pacific time');\n    e = moment.utc('Fri, 20 Jul 2012 17:15:00', 'ddd, DD MMM YYYY HH:mm:ss');\n    f = moment.utc('Fri, 20 Jul 2012 10:15:00 -0700', 'ddd, DD MMM YYYY HH:mm:ss ZZ');\n    assert.equal(e.hours(), f.hours(), 'parse timezone offset in utc');\n});\n\ntest('string with timezone around start of year', function (assert) {\n    assert.equal(moment('2000-01-01T00:00:00.000+01:00').toISOString(), '1999-12-31T23:00:00.000Z', '+1:00 around 2000');\n    assert.equal(moment('2000-01-01T00:00:00.000-01:00').toISOString(), '2000-01-01T01:00:00.000Z', '-1:00 around 2000');\n    assert.equal(moment('1970-01-01T00:00:00.000+01:00').toISOString(), '1969-12-31T23:00:00.000Z', '+1:00 around 1970');\n    assert.equal(moment('1970-01-01T00:00:00.000-01:00').toISOString(), '1970-01-01T01:00:00.000Z', '-1:00 around 1970');\n    assert.equal(moment('1200-01-01T00:00:00.000+01:00').toISOString(), '1199-12-31T23:00:00.000Z', '+1:00 around 1200');\n    assert.equal(moment('1200-01-01T00:00:00.000-01:00').toISOString(), '1200-01-01T01:00:00.000Z', '-1:00 around 1200');\n});\n\ntest('string with array of formats', function (assert) {\n    var thursdayForCurrentWeek = moment()\n      .day(4)\n      .format('YYYY MM DD');\n\n    assert.equal(moment('11-02-1999', ['MM-DD-YYYY', 'DD-MM-YYYY']).format('MM DD YYYY'), '11 02 1999', 'switching month and day');\n    assert.equal(moment('02-11-1999', ['MM/DD/YYYY', 'YYYY MM DD', 'MM-DD-YYYY']).format('MM DD YYYY'), '02 11 1999', 'year last');\n    assert.equal(moment('1999-02-11', ['MM/DD/YYYY', 'YYYY MM DD', 'MM-DD-YYYY']).format('MM DD YYYY'), '02 11 1999', 'year first');\n\n    assert.equal(moment('02-11-1999', ['MM/DD/YYYY', 'YYYY MM DD']).format('MM DD YYYY'), '02 11 1999', 'year last');\n    assert.equal(moment('1999-02-11', ['MM/DD/YYYY', 'YYYY MM DD']).format('MM DD YYYY'), '02 11 1999', 'year first');\n    assert.equal(moment('02-11-1999', ['YYYY MM DD', 'MM/DD/YYYY']).format('MM DD YYYY'), '02 11 1999', 'year last');\n    assert.equal(moment('1999-02-11', ['YYYY MM DD', 'MM/DD/YYYY']).format('MM DD YYYY'), '02 11 1999', 'year first');\n\n    assert.equal(moment('13-11-1999', ['MM/DD/YYYY', 'DD/MM/YYYY']).format('MM DD YYYY'), '11 13 1999', 'second must be month');\n    assert.equal(moment('11-13-1999', ['MM/DD/YYYY', 'DD/MM/YYYY']).format('MM DD YYYY'), '11 13 1999', 'first must be month');\n    assert.equal(moment('01-02-2000', ['MM/DD/YYYY', 'DD/MM/YYYY']).format('MM DD YYYY'), '01 02 2000', 'either can be a month, month first format');\n    assert.equal(moment('02-01-2000', ['DD/MM/YYYY', 'MM/DD/YYYY']).format('MM DD YYYY'), '01 02 2000', 'either can be a month, day first format');\n\n    assert.equal(moment('11-02-10', ['MM/DD/YY', 'YY MM DD', 'DD-MM-YY']).format('MM DD YYYY'), '02 11 2010', 'all unparsed substrings have influence on format penalty');\n    assert.equal(moment('11-02-10', ['MM-DD-YY HH:mm', 'YY MM DD']).format('MM DD YYYY'), '02 10 2011', 'prefer formats without extra tokens');\n    assert.equal(moment('11-02-10 junk', ['MM-DD-YY', 'YY.MM.DD [junk]']).format('MM DD YYYY'), '02 10 2011', 'prefer formats that dont result in extra characters');\n    assert.equal(moment('11-22-10', ['YY-MM-DD', 'YY-DD-MM']).format('MM DD YYYY'), '10 22 2011', 'prefer valid results');\n\n    assert.equal(moment('gibberish', ['YY-MM-DD', 'YY-DD-MM']).format('MM DD YYYY'), 'Invalid date', 'doest throw for invalid strings');\n    assert.equal(moment('gibberish', []).format('MM DD YYYY'), 'Invalid date', 'doest throw for an empty array');\n\n    // https://github.com/moment/moment/issues/1143\n    assert.equal(moment(\n        'System Administrator and Database Assistant (7/1/2011), System Administrator and Database Assistant (7/1/2011), Database Coordinator (7/1/2011), Vice President (7/1/2011), System Administrator and Database Assistant (5/31/2012), Database Coordinator (7/1/2012), System Administrator and Database Assistant (7/1/2013)',\n        ['MM/DD/YYYY', 'MM-DD-YYYY', 'YYYY-MM-DD', 'YYYY-MM-DDTHH:mm:ssZ'])\n        .format('YYYY-MM-DD'), '2011-07-01', 'Works for long strings');\n\n    assert.equal(moment('11-02-10', ['MM.DD.YY', 'DD-MM-YY']).format('MM DD YYYY'), '02 11 2010', 'escape RegExp special characters on comparing');\n\n    assert.equal(moment('13-10-98', ['DD MM YY', 'DD MM YYYY'])._f, 'DD MM YY', 'use two digit year');\n    assert.equal(moment('13-10-1998', ['DD MM YY', 'DD MM YYYY'])._f, 'DD MM YYYY', 'use four digit year');\n\n    assert.equal(moment('01', ['MM', 'DD'])._f, 'MM', 'Should use first valid format');\n\n    assert.equal(moment('Thursday 8:30pm', ['dddd h:mma']).format('YYYY MM DD dddd h:mma'), thursdayForCurrentWeek + ' Thursday 8:30pm', 'Default to current week');\n});\n\ntest('string with array of formats + ISO', function (assert) {\n    assert.equal(moment('1994', [moment.ISO_8601, 'MM', 'HH:mm', 'YYYY']).year(), 1994, 'iso: assert parse YYYY');\n    assert.equal(moment('17:15', [moment.ISO_8601, 'MM', 'HH:mm', 'YYYY']).hour(), 17, 'iso: assert parse HH:mm (1)');\n    assert.equal(moment('24:15', [moment.ISO_8601, 'MM', 'kk:mm', 'YYYY']).hour(), 0, 'iso: assert parse kk:mm');\n    assert.equal(moment('17:15', [moment.ISO_8601, 'MM', 'HH:mm', 'YYYY']).minutes(), 15, 'iso: assert parse HH:mm (2)');\n    assert.equal(moment('06', [moment.ISO_8601, 'MM', 'HH:mm', 'YYYY']).month(), 6 - 1, 'iso: assert parse MM');\n    assert.equal(moment('2012-06-01', [moment.ISO_8601, 'MM', 'HH:mm', 'YYYY']).parsingFlags().iso, true, 'iso: assert parse iso');\n    assert.equal(moment('2014-05-05', [moment.ISO_8601, 'YYYY-MM-DD']).parsingFlags().iso, true, 'iso: edge case array precedence iso');\n    assert.equal(moment('2014-05-05', ['YYYY-MM-DD', moment.ISO_8601]).parsingFlags().iso, false, 'iso: edge case array precedence not iso');\n});\n\ntest('string with format - years', function (assert) {\n    assert.equal(moment('67', 'YY').format('YYYY'), '2067', '67 > 2067');\n    assert.equal(moment('68', 'YY').format('YYYY'), '2068', '68 > 2068');\n    assert.equal(moment('69', 'YY').format('YYYY'), '1969', '69 > 1969');\n    assert.equal(moment('70', 'YY').format('YYYY'), '1970', '70 > 1970');\n});\n\ntest('implicit cloning', function (assert) {\n    var momentA = moment([2011, 10, 10]),\n    momentB = moment(momentA);\n    momentA.month(5);\n    assert.equal(momentB.month(), 10, 'Calling moment() on a moment will create a clone');\n    assert.equal(momentA.month(), 5, 'Calling moment() on a moment will create a clone');\n});\n\ntest('explicit cloning', function (assert) {\n    var momentA = moment([2011, 10, 10]),\n    momentB = momentA.clone();\n    momentA.month(5);\n    assert.equal(momentB.month(), 10, 'Calling moment() on a moment will create a clone');\n    assert.equal(momentA.month(), 5, 'Calling moment() on a moment will create a clone');\n});\n\ntest('cloning carrying over utc mode', function (assert) {\n    assert.equal(moment().local().clone()._isUTC, false, 'An explicit cloned local moment should have _isUTC == false');\n    assert.equal(moment().utc().clone()._isUTC, true, 'An cloned utc moment should have _isUTC == true');\n    assert.equal(moment().clone()._isUTC, false, 'An explicit cloned local moment should have _isUTC == false');\n    assert.equal(moment.utc().clone()._isUTC, true, 'An explicit cloned utc moment should have _isUTC == true');\n    assert.equal(moment(moment().local())._isUTC, false, 'An implicit cloned local moment should have _isUTC == false');\n    assert.equal(moment(moment().utc())._isUTC, true, 'An implicit cloned utc moment should have _isUTC == true');\n    assert.equal(moment(moment())._isUTC, false, 'An implicit cloned local moment should have _isUTC == false');\n    assert.equal(moment(moment.utc())._isUTC, true, 'An implicit cloned utc moment should have _isUTC == true');\n});\n\ntest('parsing RFC 2822', function (assert) {\n    var testCases = {\n        'clean RFC2822 datetime with all options': 'Tue, 01 Nov 2016 01:23:45 UT',\n        'clean RFC2822 datetime without comma': 'Tue 01 Nov 2016 02:23:45 GMT',\n        'clean RFC2822 datetime without seconds': 'Tue, 01 Nov 2016 03:23 +0000',\n        'clean RFC2822 datetime without century': 'Tue, 01 Nov 16 04:23:45 Z',\n        'clean RFC2822 datetime without day': '01 Nov 2016 05:23:45 z',\n        'clean RFC2822 datetime with single-digit day-of-month': 'Tue, 1 Nov 2016 06:23:45 GMT',\n        'RFC2822 datetime with CFWSs': '(Init Comment) Tue,\\n 1 Nov              2016 (Split\\n Comment)  07:23:45 +0000 (GMT)'\n    };\n    var testCase;\n\n    for (testCase in testCases) {\n        var testResult = moment(testCases[testCase], moment.RFC_2822, true);\n        assert.ok(testResult.isValid(), testResult);\n        assert.ok(testResult.parsingFlags().rfc2822, testResult + ' - rfc2822 parsingFlag');\n    }\n});\n\ntest('non RFC 2822 strings', function (assert) {\n    var testCases = {\n        'RFC2822 datetime with all options but invalid day delimiter': 'Tue. 01 Nov 2016 01:23:45 GMT',\n        'RFC2822 datetime with mismatching Day (week v date)': 'Mon, 01 Nov 2016 01:23:45 GMT'\n    };\n    var testCase;\n\n    for (testCase in testCases) {\n        var testResult = moment(testCases[testCase], moment.RFC_2822, true);\n        assert.ok(!testResult.isValid(), testResult);\n        assert.ok(!testResult.parsingFlags().rfc2822, testResult + ' - rfc2822 parsingFlag');\n    }\n});\n\ntest('parsing iso', function (assert) {\n    var offset = moment([2011, 9, 8]).utcOffset(),\n    pad = function (input) {\n        if (input < 10) {\n            return '0' + input;\n        }\n        return '' + input;\n    },\n    hourOffset = (offset > 0 ? Math.floor(offset / 60) : Math.ceil(offset / 60)),\n    minOffset = offset - (hourOffset * 60),\n    tz = (offset >= 0) ?\n        '+' + pad(hourOffset) + ':' + pad(minOffset) :\n        '-' + pad(-hourOffset) + ':' + pad(-minOffset),\n    tz2 = tz.replace(':', ''),\n    tz3 = tz2.slice(0, 3),\n    //Tz3 removes minutes digit so will break the tests when parsed if they all use the same minutes digit\n    minutesForTz3 = pad((4 + minOffset) % 60),\n    minute = pad(4 + minOffset),\n\n    formats = [\n        ['2011-10-08',                    '2011-10-08T00:00:00.000' + tz],\n        ['2011-10-08T18',                 '2011-10-08T18:00:00.000' + tz],\n        ['2011-10-08T18:04',              '2011-10-08T18:04:00.000' + tz],\n        ['2011-10-08T18:04:20',           '2011-10-08T18:04:20.000' + tz],\n        ['2011-10-08T18:04' + tz,         '2011-10-08T18:04:00.000' + tz],\n        ['2011-10-08T18:04:20' + tz,      '2011-10-08T18:04:20.000' + tz],\n        ['2011-10-08T18:04' + tz2,        '2011-10-08T18:04:00.000' + tz],\n        ['2011-10-08T18:04:20' + tz2,     '2011-10-08T18:04:20.000' + tz],\n        ['2011-10-08T18:04' + tz3,        '2011-10-08T18:' + minutesForTz3 + ':00.000' + tz],\n        ['2011-10-08T18:04:20' + tz3,     '2011-10-08T18:' + minutesForTz3 + ':20.000' + tz],\n        ['2011-10-08T18:04:20.1' + tz2,   '2011-10-08T18:04:20.100' + tz],\n        ['2011-10-08T18:04:20.11' + tz2,  '2011-10-08T18:04:20.110' + tz],\n        ['2011-10-08T18:04:20.111' + tz2, '2011-10-08T18:04:20.111' + tz],\n        ['2011-10-08 18',                 '2011-10-08T18:00:00.000' + tz],\n        ['2011-10-08 18:04',              '2011-10-08T18:04:00.000' + tz],\n        ['2011-10-08 18:04:20',           '2011-10-08T18:04:20.000' + tz],\n        ['2011-10-08 18:04' + tz,         '2011-10-08T18:04:00.000' + tz],\n        ['2011-10-08 18:04:20' + tz,      '2011-10-08T18:04:20.000' + tz],\n        ['2011-10-08 18:04' + tz2,        '2011-10-08T18:04:00.000' + tz],\n        ['2011-10-08 18:04:20' + tz2,     '2011-10-08T18:04:20.000' + tz],\n        ['2011-10-08 18:04' + tz3,        '2011-10-08T18:' + minutesForTz3 + ':00.000' + tz],\n        ['2011-10-08 18:04:20' + tz3,     '2011-10-08T18:' + minutesForTz3 + ':20.000' + tz],\n        ['2011-10-08 18:04:20.1' + tz2,   '2011-10-08T18:04:20.100' + tz],\n        ['2011-10-08 18:04:20.11' + tz2,  '2011-10-08T18:04:20.110' + tz],\n        ['2011-10-08 18:04:20.111' + tz2, '2011-10-08T18:04:20.111' + tz],\n        ['2011-W40',                      '2011-10-03T00:00:00.000' + tz],\n        ['2011-W40-6',                    '2011-10-08T00:00:00.000' + tz],\n        ['2011-W40-6T18',                 '2011-10-08T18:00:00.000' + tz],\n        ['2011-W40-6T18:04',              '2011-10-08T18:04:00.000' + tz],\n        ['2011-W40-6T18:04:20',           '2011-10-08T18:04:20.000' + tz],\n        ['2011-W40-6T18:04' + tz,         '2011-10-08T18:04:00.000' + tz],\n        ['2011-W40-6T18:04:20' + tz,      '2011-10-08T18:04:20.000' + tz],\n        ['2011-W40-6T18:04' + tz2,        '2011-10-08T18:04:00.000' + tz],\n        ['2011-W40-6T18:04:20' + tz2,     '2011-10-08T18:04:20.000' + tz],\n        ['2011-W40-6T18:04' + tz3,        '2011-10-08T18:' + minutesForTz3 + ':00.000' + tz],\n        ['2011-W40-6T18:04:20' + tz3,     '2011-10-08T18:' + minutesForTz3 + ':20.000' + tz],\n        ['2011-W40-6T18:04:20.1' + tz2,   '2011-10-08T18:04:20.100' + tz],\n        ['2011-W40-6T18:04:20.11' + tz2,  '2011-10-08T18:04:20.110' + tz],\n        ['2011-W40-6T18:04:20.111' + tz2, '2011-10-08T18:04:20.111' + tz],\n        ['2011-W40-6 18',                 '2011-10-08T18:00:00.000' + tz],\n        ['2011-W40-6 18:04',              '2011-10-08T18:04:00.000' + tz],\n        ['2011-W40-6 18:04:20',           '2011-10-08T18:04:20.000' + tz],\n        ['2011-W40-6 18:04' + tz,         '2011-10-08T18:04:00.000' + tz],\n        ['2011-W40-6 18:04:20' + tz,      '2011-10-08T18:04:20.000' + tz],\n        ['2011-W40-6 18:04' + tz2,        '2011-10-08T18:04:00.000' + tz],\n        ['2011-W40-6 18:04:20' + tz2,     '2011-10-08T18:04:20.000' + tz],\n        ['2011-W40-6 18:04' + tz3,        '2011-10-08T18:' + minutesForTz3 + ':00.000' + tz],\n        ['2011-W40-6 18:04:20' + tz3,     '2011-10-08T18:' + minutesForTz3 + ':20.000' + tz],\n        ['2011-W40-6 18:04:20.1' + tz2,   '2011-10-08T18:04:20.100' + tz],\n        ['2011-W40-6 18:04:20.11' + tz2,  '2011-10-08T18:04:20.110' + tz],\n        ['2011-W40-6 18:04:20.111' + tz2, '2011-10-08T18:04:20.111' + tz],\n        ['2011-281',                      '2011-10-08T00:00:00.000' + tz],\n        ['2011-281T18',                   '2011-10-08T18:00:00.000' + tz],\n        ['2011-281T18:04',                '2011-10-08T18:04:00.000' + tz],\n        ['2011-281T18:04:20',             '2011-10-08T18:04:20.000' + tz],\n        ['2011-281T18:04' + tz,           '2011-10-08T18:04:00.000' + tz],\n        ['2011-281T18:04:20' + tz,        '2011-10-08T18:04:20.000' + tz],\n        ['2011-281T18:04' + tz2,          '2011-10-08T18:04:00.000' + tz],\n        ['2011-281T18:04:20' + tz2,       '2011-10-08T18:04:20.000' + tz],\n        ['2011-281T18:04' + tz3,          '2011-10-08T18:' + minutesForTz3 + ':00.000' + tz],\n        ['2011-281T18:04:20' + tz3,       '2011-10-08T18:' + minutesForTz3 + ':20.000' + tz],\n        ['2011-281T18:04:20.1' + tz2,     '2011-10-08T18:04:20.100' + tz],\n        ['2011-281T18:04:20.11' + tz2,    '2011-10-08T18:04:20.110' + tz],\n        ['2011-281T18:04:20.111' + tz2,   '2011-10-08T18:04:20.111' + tz],\n        ['2011-281 18',                   '2011-10-08T18:00:00.000' + tz],\n        ['2011-281 18:04',                '2011-10-08T18:04:00.000' + tz],\n        ['2011-281 18:04:20',             '2011-10-08T18:04:20.000' + tz],\n        ['2011-281 18:04' + tz,           '2011-10-08T18:04:00.000' + tz],\n        ['2011-281 18:04:20' + tz,        '2011-10-08T18:04:20.000' + tz],\n        ['2011-281 18:04' + tz2,          '2011-10-08T18:04:00.000' + tz],\n        ['2011-281 18:04:20' + tz2,       '2011-10-08T18:04:20.000' + tz],\n        ['2011-281 18:04' + tz3,          '2011-10-08T18:' + minutesForTz3 + ':00.000' + tz],\n        ['2011-281 18:04:20' + tz3,       '2011-10-08T18:' + minutesForTz3 + ':20.000' + tz],\n        ['2011-281 18:04:20.1' + tz2,     '2011-10-08T18:04:20.100' + tz],\n        ['2011-281 18:04:20.11' + tz2,    '2011-10-08T18:04:20.110' + tz],\n        ['2011-281 18:04:20.111' + tz2,   '2011-10-08T18:04:20.111' + tz],\n        ['20111008T18',                   '2011-10-08T18:00:00.000' + tz],\n        ['20111008T1804',                 '2011-10-08T18:04:00.000' + tz],\n        ['20111008T180420',               '2011-10-08T18:04:20.000' + tz],\n        ['20111008T1804' + tz,            '2011-10-08T18:04:00.000' + tz],\n        ['20111008T180420' + tz,          '2011-10-08T18:04:20.000' + tz],\n        ['20111008T1804' + tz2,           '2011-10-08T18:04:00.000' + tz],\n        ['20111008T180420' + tz2,         '2011-10-08T18:04:20.000' + tz],\n        ['20111008T1804' + tz3,           '2011-10-08T18:' + minutesForTz3 + ':00.000' + tz],\n        ['20111008T180420' + tz3,         '2011-10-08T18:' + minutesForTz3 + ':20.000' + tz],\n        ['20111008T180420,1' + tz2,       '2011-10-08T18:04:20.100' + tz],\n        ['20111008T180420,11' + tz2,      '2011-10-08T18:04:20.110' + tz],\n        ['20111008T180420,111' + tz2,     '2011-10-08T18:04:20.111' + tz],\n        ['20111008 18',                   '2011-10-08T18:00:00.000' + tz],\n        ['20111008 1804',                 '2011-10-08T18:04:00.000' + tz],\n        ['20111008 180420',               '2011-10-08T18:04:20.000' + tz],\n        ['20111008 1804' + tz,            '2011-10-08T18:04:00.000' + tz],\n        ['20111008 180420' + tz,          '2011-10-08T18:04:20.000' + tz],\n        ['20111008 1804' + tz2,           '2011-10-08T18:04:00.000' + tz],\n        ['20111008 180420' + tz2,         '2011-10-08T18:04:20.000' + tz],\n        ['20111008 1804' + tz3,           '2011-10-08T18:' + minutesForTz3 + ':00.000' + tz],\n        ['20111008 180420' + tz3,         '2011-10-08T18:' + minutesForTz3 + ':20.000' + tz],\n        ['20111008 180420,1' + tz2,       '2011-10-08T18:04:20.100' + tz],\n        ['20111008 180420,11' + tz2,      '2011-10-08T18:04:20.110' + tz],\n        ['20111008 180420,111' + tz2,     '2011-10-08T18:04:20.111' + tz],\n        ['2011W40',                       '2011-10-03T00:00:00.000' + tz],\n        ['2011W406',                      '2011-10-08T00:00:00.000' + tz],\n        ['2011W406T18',                   '2011-10-08T18:00:00.000' + tz],\n        ['2011W406T1804',                 '2011-10-08T18:04:00.000' + tz],\n        ['2011W406T180420',               '2011-10-08T18:04:20.000' + tz],\n        ['2011W406 1804' + tz2,           '2011-10-08T18:04:00.000' + tz],\n        ['2011W406T1804' + tz,            '2011-10-08T18:04:00.000' + tz],\n        ['2011W406T180420' + tz,          '2011-10-08T18:04:20.000' + tz],\n        ['2011W406T1804' + tz2,           '2011-10-08T18:04:00.000' + tz],\n        ['2011W406T180420' + tz2,         '2011-10-08T18:04:20.000' + tz],\n        ['2011W406T1804' + tz3,           '2011-10-08T18:' + minutesForTz3 + ':00.000' + tz],\n        ['2011W406T180420' + tz3,         '2011-10-08T18:' + minutesForTz3 + ':20.000' + tz],\n        ['2011W406T180420,1' + tz2,       '2011-10-08T18:04:20.100' + tz],\n        ['2011W406T180420,11' + tz2,      '2011-10-08T18:04:20.110' + tz],\n        ['2011W406T180420,111' + tz2,     '2011-10-08T18:04:20.111' + tz],\n        ['2011W406 18',                   '2011-10-08T18:00:00.000' + tz],\n        ['2011W406 1804',                 '2011-10-08T18:04:00.000' + tz],\n        ['2011W406 180420',               '2011-10-08T18:04:20.000' + tz],\n        ['2011W406 1804' + tz,            '2011-10-08T18:04:00.000' + tz],\n        ['2011W406 180420' + tz,          '2011-10-08T18:04:20.000' + tz],\n        ['2011W406 180420' + tz2,         '2011-10-08T18:04:20.000' + tz],\n        ['2011W406 1804' + tz3,           '2011-10-08T18:' + minutesForTz3 + ':00.000' + tz],\n        ['2011W406 180420' + tz3,         '2011-10-08T18:' + minutesForTz3 + ':20.000' + tz],\n        ['2011W406 180420,1' + tz2,       '2011-10-08T18:04:20.100' + tz],\n        ['2011W406 180420,11' + tz2,      '2011-10-08T18:04:20.110' + tz],\n        ['2011W406 180420,111' + tz2,     '2011-10-08T18:04:20.111' + tz],\n        ['2011281',                       '2011-10-08T00:00:00.000' + tz],\n        ['2011281T18',                    '2011-10-08T18:00:00.000' + tz],\n        ['2011281T1804',                  '2011-10-08T18:04:00.000' + tz],\n        ['2011281T180420',                '2011-10-08T18:04:20.000' + tz],\n        ['2011281T1804' + tz,             '2011-10-08T18:04:00.000' + tz],\n        ['2011281T180420' + tz,           '2011-10-08T18:04:20.000' + tz],\n        ['2011281T1804' + tz2,            '2011-10-08T18:04:00.000' + tz],\n        ['2011281T180420' + tz2,          '2011-10-08T18:04:20.000' + tz],\n        ['2011281T1804' + tz3,            '2011-10-08T18:' + minutesForTz3 + ':00.000' + tz],\n        ['2011281T180420' + tz3,          '2011-10-08T18:' + minutesForTz3 + ':20.000' + tz],\n        ['2011281T180420,1' + tz2,        '2011-10-08T18:04:20.100' + tz],\n        ['2011281T180420,11' + tz2,       '2011-10-08T18:04:20.110' + tz],\n        ['2011281T180420,111' + tz2,      '2011-10-08T18:04:20.111' + tz],\n        ['2011281 18',                    '2011-10-08T18:00:00.000' + tz],\n        ['2011281 1804',                  '2011-10-08T18:04:00.000' + tz],\n        ['2011281 180420',                '2011-10-08T18:04:20.000' + tz],\n        ['2011281 1804' + tz,             '2011-10-08T18:04:00.000' + tz],\n        ['2011281 180420' + tz,           '2011-10-08T18:04:20.000' + tz],\n        ['2011281 1804' + tz2,            '2011-10-08T18:04:00.000' + tz],\n        ['2011281 180420' + tz2,          '2011-10-08T18:04:20.000' + tz],\n        ['2011281 1804' + tz3,            '2011-10-08T18:' + minutesForTz3 + ':00.000' + tz],\n        ['2011281 180420' + tz3,          '2011-10-08T18:' + minutesForTz3 + ':20.000' + tz],\n        ['2011281 180420,1' + tz2,        '2011-10-08T18:04:20.100' + tz],\n        ['2011281 180420,11' + tz2,       '2011-10-08T18:04:20.110' + tz],\n        ['2011281 180420,111' + tz2,      '2011-10-08T18:04:20.111' + tz]\n    ], i;\n    for (i = 0; i < formats.length; i++) {\n        assert.equal(moment(formats[i][0]).format('YYYY-MM-DDTHH:mm:ss.SSSZ'),\n                formats[i][1], 'moment should be able to parse ISO ' + formats[i][0]);\n        assert.equal(moment(formats[i][0], moment.ISO_8601).format('YYYY-MM-DDTHH:mm:ss.SSSZ'),\n                formats[i][1], 'moment should be able to parse specified ISO ' + formats[i][0]);\n        assert.equal(moment(formats[i][0], moment.ISO_8601, true).format('YYYY-MM-DDTHH:mm:ss.SSSZ'),\n                formats[i][1], 'moment should be able to parse specified strict ISO ' + formats[i][0]);\n    }\n});\n\ntest('non iso 8601 strings', function (assert) {\n    assert.ok(!moment('2015-10T10:15', moment.ISO_8601, true).isValid(), 'incomplete date with time');\n    assert.ok(!moment('2015-W10T10:15', moment.ISO_8601, true).isValid(), 'incomplete week date with time');\n    assert.ok(!moment('201510', moment.ISO_8601, true).isValid(), 'basic YYYYMM is not allowed');\n    assert.ok(!moment('2015W10T1015', moment.ISO_8601, true).isValid(), 'incomplete week date with time (basic)');\n    assert.ok(!moment('2015-10-08T1015', moment.ISO_8601, true).isValid(), 'mixing extended and basic format');\n    assert.ok(!moment('20151008T10:15', moment.ISO_8601, true).isValid(), 'mixing basic and extended format');\n    assert.ok(!moment('2015-10-1', moment.ISO_8601, true).isValid(), 'missing zero padding for day');\n});\n\ntest('parsing iso week year/week/weekday', function (assert) {\n    assert.equal(moment.utc('2007-W01').format(), '2007-01-01T00:00:00Z', '2008 week 1 (1st Jan Mon)');\n    assert.equal(moment.utc('2008-W01').format(), '2007-12-31T00:00:00Z', '2008 week 1 (1st Jan Tue)');\n    assert.equal(moment.utc('2003-W01').format(), '2002-12-30T00:00:00Z', '2008 week 1 (1st Jan Wed)');\n    assert.equal(moment.utc('2009-W01').format(), '2008-12-29T00:00:00Z', '2009 week 1 (1st Jan Thu)');\n    assert.equal(moment.utc('2010-W01').format(), '2010-01-04T00:00:00Z', '2010 week 1 (1st Jan Fri)');\n    assert.equal(moment.utc('2011-W01').format(), '2011-01-03T00:00:00Z', '2011 week 1 (1st Jan Sat)');\n    assert.equal(moment.utc('2012-W01').format(), '2012-01-02T00:00:00Z', '2012 week 1 (1st Jan Sun)');\n});\n\ntest('parsing week year/week/weekday (dow 1, doy 4)', function (assert) {\n    moment.locale('dow:1,doy:4', {week: {dow: 1, doy: 4}});\n\n    assert.equal(moment.utc('2007-01', 'gggg-ww').format(), '2007-01-01T00:00:00Z', '2007 week 1 (1st Jan Mon)');\n    assert.equal(moment.utc('2008-01', 'gggg-ww').format(), '2007-12-31T00:00:00Z', '2008 week 1 (1st Jan Tue)');\n    assert.equal(moment.utc('2003-01', 'gggg-ww').format(), '2002-12-30T00:00:00Z', '2003 week 1 (1st Jan Wed)');\n    assert.equal(moment.utc('2009-01', 'gggg-ww').format(), '2008-12-29T00:00:00Z', '2009 week 1 (1st Jan Thu)');\n    assert.equal(moment.utc('2010-01', 'gggg-ww').format(), '2010-01-04T00:00:00Z', '2010 week 1 (1st Jan Fri)');\n    assert.equal(moment.utc('2011-01', 'gggg-ww').format(), '2011-01-03T00:00:00Z', '2011 week 1 (1st Jan Sat)');\n    assert.equal(moment.utc('2012-01', 'gggg-ww').format(), '2012-01-02T00:00:00Z', '2012 week 1 (1st Jan Sun)');\n\n    moment.defineLocale('dow:1,doy:4', null);\n});\n\ntest('parsing week year/week/weekday (dow 1, doy 7)', function (assert) {\n    moment.locale('dow:1,doy:7', {week: {dow: 1, doy: 7}});\n\n    assert.equal(moment.utc('2007-01', 'gggg-ww').format(), '2007-01-01T00:00:00Z', '2007 week 1 (1st Jan Mon)');\n    assert.equal(moment.utc('2008-01', 'gggg-ww').format(), '2007-12-31T00:00:00Z', '2008 week 1 (1st Jan Tue)');\n    assert.equal(moment.utc('2003-01', 'gggg-ww').format(), '2002-12-30T00:00:00Z', '2003 week 1 (1st Jan Wed)');\n    assert.equal(moment.utc('2009-01', 'gggg-ww').format(), '2008-12-29T00:00:00Z', '2009 week 1 (1st Jan Thu)');\n    assert.equal(moment.utc('2010-01', 'gggg-ww').format(), '2009-12-28T00:00:00Z', '2010 week 1 (1st Jan Fri)');\n    assert.equal(moment.utc('2011-01', 'gggg-ww').format(), '2010-12-27T00:00:00Z', '2011 week 1 (1st Jan Sat)');\n    assert.equal(moment.utc('2012-01', 'gggg-ww').format(), '2011-12-26T00:00:00Z', '2012 week 1 (1st Jan Sun)');\n    moment.defineLocale('dow:1,doy:7', null);\n});\n\ntest('parsing week year/week/weekday (dow 0, doy 6)', function (assert) {\n    moment.locale('dow:0,doy:6', {week: {dow: 0, doy: 6}});\n\n    assert.equal(moment.utc('2007-01', 'gggg-ww').format(), '2006-12-31T00:00:00Z', '2007 week 1 (1st Jan Mon)');\n    assert.equal(moment.utc('2008-01', 'gggg-ww').format(), '2007-12-30T00:00:00Z', '2008 week 1 (1st Jan Tue)');\n    assert.equal(moment.utc('2003-01', 'gggg-ww').format(), '2002-12-29T00:00:00Z', '2003 week 1 (1st Jan Wed)');\n    assert.equal(moment.utc('2009-01', 'gggg-ww').format(), '2008-12-28T00:00:00Z', '2009 week 1 (1st Jan Thu)');\n    assert.equal(moment.utc('2010-01', 'gggg-ww').format(), '2009-12-27T00:00:00Z', '2010 week 1 (1st Jan Fri)');\n    assert.equal(moment.utc('2011-01', 'gggg-ww').format(), '2010-12-26T00:00:00Z', '2011 week 1 (1st Jan Sat)');\n    assert.equal(moment.utc('2012-01', 'gggg-ww').format(), '2012-01-01T00:00:00Z', '2012 week 1 (1st Jan Sun)');\n    moment.defineLocale('dow:0,doy:6', null);\n});\n\ntest('parsing week year/week/weekday (dow 6, doy 12)', function (assert) {\n    moment.locale('dow:6,doy:12', {week: {dow: 6, doy: 12}});\n\n    assert.equal(moment.utc('2007-01', 'gggg-ww').format(), '2006-12-30T00:00:00Z', '2007 week 1 (1st Jan Mon)');\n    assert.equal(moment.utc('2008-01', 'gggg-ww').format(), '2007-12-29T00:00:00Z', '2008 week 1 (1st Jan Tue)');\n    assert.equal(moment.utc('2003-01', 'gggg-ww').format(), '2002-12-28T00:00:00Z', '2003 week 1 (1st Jan Wed)');\n    assert.equal(moment.utc('2009-01', 'gggg-ww').format(), '2008-12-27T00:00:00Z', '2009 week 1 (1st Jan Thu)');\n    assert.equal(moment.utc('2010-01', 'gggg-ww').format(), '2009-12-26T00:00:00Z', '2010 week 1 (1st Jan Fri)');\n    assert.equal(moment.utc('2011-01', 'gggg-ww').format(), '2011-01-01T00:00:00Z', '2011 week 1 (1st Jan Sat)');\n    assert.equal(moment.utc('2012-01', 'gggg-ww').format(), '2011-12-31T00:00:00Z', '2012 week 1 (1st Jan Sun)');\n    moment.defineLocale('dow:6,doy:12', null);\n});\n\ntest('parsing ISO with Z', function (assert) {\n    var i, mom, formats = [\n        ['2011-10-08T18:04',             '2011-10-08T18:04:00.000'],\n        ['2011-10-08T18:04:20',          '2011-10-08T18:04:20.000'],\n        ['2011-10-08T18:04:20.1',        '2011-10-08T18:04:20.100'],\n        ['2011-10-08T18:04:20.11',       '2011-10-08T18:04:20.110'],\n        ['2011-10-08T18:04:20.111',      '2011-10-08T18:04:20.111'],\n        ['2011-W40-6T18',                '2011-10-08T18:00:00.000'],\n        ['2011-W40-6T18:04',             '2011-10-08T18:04:00.000'],\n        ['2011-W40-6T18:04:20',          '2011-10-08T18:04:20.000'],\n        ['2011-W40-6T18:04:20.1',        '2011-10-08T18:04:20.100'],\n        ['2011-W40-6T18:04:20.11',       '2011-10-08T18:04:20.110'],\n        ['2011-W40-6T18:04:20.111',      '2011-10-08T18:04:20.111'],\n        ['2011-281T18',                  '2011-10-08T18:00:00.000'],\n        ['2011-281T18:04',               '2011-10-08T18:04:00.000'],\n        ['2011-281T18:04:20',            '2011-10-08T18:04:20.000'],\n        ['2011-281T18:04:20',            '2011-10-08T18:04:20.000'],\n        ['2011-281T18:04:20.1',          '2011-10-08T18:04:20.100'],\n        ['2011-281T18:04:20.11',         '2011-10-08T18:04:20.110'],\n        ['2011-281T18:04:20.111',        '2011-10-08T18:04:20.111']\n    ];\n\n    for (i = 0; i < formats.length; i++) {\n        mom = moment(formats[i][0] + 'Z').utc();\n        assert.equal(mom.format('YYYY-MM-DDTHH:mm:ss.SSS'), formats[i][1], 'moment should be able to parse ISO in UTC ' + formats[i][0] + 'Z');\n\n        mom = moment(formats[i][0] + ' Z').utc();\n        assert.equal(mom.format('YYYY-MM-DDTHH:mm:ss.SSS'), formats[i][1], 'moment should be able to parse ISO in UTC ' + formats[i][0] + ' Z');\n    }\n});\n\ntest('parsing iso with T', function (assert) {\n    assert.equal(moment('2011-10-08T18')._f, 'YYYY-MM-DDTHH', 'should include \\'T\\' in the format');\n    assert.equal(moment('2011-10-08T18:20')._f, 'YYYY-MM-DDTHH:mm', 'should include \\'T\\' in the format');\n    assert.equal(moment('2011-10-08T18:20:13')._f, 'YYYY-MM-DDTHH:mm:ss', 'should include \\'T\\' in the format');\n    assert.equal(moment('2011-10-08T18:20:13.321')._f, 'YYYY-MM-DDTHH:mm:ss.SSSS', 'should include \\'T\\' in the format');\n\n    assert.equal(moment('2011-10-08 18')._f, 'YYYY-MM-DD HH', 'should not include \\'T\\' in the format');\n    assert.equal(moment('2011-10-08 18:20')._f, 'YYYY-MM-DD HH:mm', 'should not include \\'T\\' in the format');\n    assert.equal(moment('2011-10-08 18:20:13')._f, 'YYYY-MM-DD HH:mm:ss', 'should not include \\'T\\' in the format');\n    assert.equal(moment('2011-10-08 18:20:13.321')._f, 'YYYY-MM-DD HH:mm:ss.SSSS', 'should not include \\'T\\' in the format');\n});\n\ntest('parsing iso Z timezone', function (assert) {\n    var i,\n    formats = [\n        ['2011-10-08T18:04Z',             '2011-10-08T18:04:00.000+00:00'],\n        ['2011-10-08T18:04:20Z',          '2011-10-08T18:04:20.000+00:00'],\n        ['2011-10-08T18:04:20.111Z',      '2011-10-08T18:04:20.111+00:00']\n    ];\n    for (i = 0; i < formats.length; i++) {\n        assert.equal(moment.utc(formats[i][0]).format('YYYY-MM-DDTHH:mm:ss.SSSZ'), formats[i][1], 'moment should be able to parse ISO ' + formats[i][0]);\n    }\n});\n\ntest('parsing iso Z timezone into local', function (assert) {\n    var m = moment('2011-10-08T18:04:20.111Z');\n\n    assert.equal(m.utc().format('YYYY-MM-DDTHH:mm:ss.SSS'), '2011-10-08T18:04:20.111', 'moment should be able to parse ISO 2011-10-08T18:04:20.111Z');\n});\n\ntest('parsing iso with more subsecond precision digits', function (assert) {\n    assert.equal(moment.utc('2013-07-31T22:00:00.0000000Z').format(), '2013-07-31T22:00:00Z', 'more than 3 subsecond digits');\n});\n\ntest('null or empty', function (assert) {\n    assert.equal(moment('').isValid(), false, 'moment(\\'\\') is not valid');\n    assert.equal(moment(null).isValid(), false, 'moment(null) is not valid');\n    assert.equal(moment(null, 'YYYY-MM-DD').isValid(), false, 'moment(\\'\\', \\'format\\') is not valid');\n    assert.equal(moment('', 'YYYY-MM-DD').isValid(), false, 'moment(\\'\\', \\'format\\') is not valid');\n    assert.equal(moment.utc('').isValid(), false, 'moment.utc(\\'\\') is not valid');\n    assert.equal(moment.utc(null).isValid(), false, 'moment.utc(null) is not valid');\n    assert.equal(moment.utc(null, 'YYYY-MM-DD').isValid(), false, 'moment.utc(null) is not valid');\n    assert.equal(moment.utc('', 'YYYY-MM-DD').isValid(), false, 'moment.utc(\\'\\', \\'YYYY-MM-DD\\') is not valid');\n});\n\ntest('first century', function (assert) {\n    assert.equal(moment([0, 0, 1]).format('YYYY-MM-DD'), '0000-01-01', 'Year AD 0');\n    assert.equal(moment([99, 0, 1]).format('YYYY-MM-DD'), '0099-01-01', 'Year AD 99');\n    assert.equal(moment([999, 0, 1]).format('YYYY-MM-DD'), '0999-01-01', 'Year AD 999');\n    assert.equal(moment('0 1 1', 'YYYY MM DD').format('YYYY-MM-DD'), '0000-01-01', 'Year AD 0');\n    assert.equal(moment('999 1 1', 'YYYY MM DD').format('YYYY-MM-DD'), '0999-01-01', 'Year AD 999');\n    assert.equal(moment('0 1 1', 'YYYYY MM DD').format('YYYYY-MM-DD'), '00000-01-01', 'Year AD 0');\n    assert.equal(moment('99 1 1', 'YYYYY MM DD').format('YYYYY-MM-DD'), '00099-01-01', 'Year AD 99');\n    assert.equal(moment('999 1 1', 'YYYYY MM DD').format('YYYYY-MM-DD'), '00999-01-01', 'Year AD 999');\n});\n\ntest('six digit years', function (assert) {\n    assert.equal(moment([-270000, 0, 1]).format('YYYYY-MM-DD'), '-270000-01-01', 'format BC 270,001');\n    assert.equal(moment([270000, 0, 1]).format('YYYYY-MM-DD'), '270000-01-01', 'format AD 270,000');\n    assert.equal(moment('-270000-01-01', 'YYYYY-MM-DD').toDate().getFullYear(), -270000, 'parse BC 270,001');\n    assert.equal(moment('270000-01-01',  'YYYYY-MM-DD').toDate().getFullYear(), 270000, 'parse AD 270,000');\n    assert.equal(moment('+270000-01-01', 'YYYYY-MM-DD').toDate().getFullYear(), 270000, 'parse AD +270,000');\n    assert.equal(moment.utc('-270000-01-01', 'YYYYY-MM-DD').toDate().getUTCFullYear(), -270000, 'parse utc BC 270,001');\n    assert.equal(moment.utc('270000-01-01',  'YYYYY-MM-DD').toDate().getUTCFullYear(), 270000, 'parse utc AD 270,000');\n    assert.equal(moment.utc('+270000-01-01', 'YYYYY-MM-DD').toDate().getUTCFullYear(), 270000, 'parse utc AD +270,000');\n});\n\ntest('negative four digit years', function (assert) {\n    assert.equal(moment('-1000-01-01', 'YYYYY-MM-DD').toDate().getFullYear(), -1000, 'parse BC 1,001');\n    assert.equal(moment.utc('-1000-01-01', 'YYYYY-MM-DD').toDate().getUTCFullYear(), -1000, 'parse utc BC 1,001');\n});\n\ntest('strict parsing', function (assert) {\n    assert.equal(moment('2014-', 'YYYY-Q', true).isValid(), false, 'fail missing quarter');\n\n    assert.equal(moment('2012-05', 'YYYY-MM', true).format('YYYY-MM'), '2012-05', 'parse correct string');\n    assert.equal(moment(' 2012-05', 'YYYY-MM', true).isValid(), false, 'fail on extra whitespace');\n    assert.equal(moment('foo 2012-05', '[foo] YYYY-MM', true).format('YYYY-MM'), '2012-05', 'handle fixed text');\n    assert.equal(moment('2012 05', 'YYYY-MM', true).isValid(), false, 'fail on different separator');\n    assert.equal(moment('2012 05', 'YYYY MM DD', true).isValid(), false, 'fail on too many tokens');\n\n    assert.equal(moment('05 30 2010', ['DD MM YYYY', 'MM DD YYYY'], true).format('MM DD YYYY'), '05 30 2010', 'array with bad date');\n    assert.equal(moment('05 30 2010', ['', 'MM DD YYYY'], true).format('MM DD YYYY'), '05 30 2010', 'array with invalid format');\n    assert.equal(moment('05 30 2010', [' DD MM YYYY', 'MM DD YYYY'], true).format('MM DD YYYY'), '05 30 2010', 'array with non-matching format');\n\n    assert.equal(moment('2010.*...', 'YYYY.*', true).isValid(), false, 'invalid format with regex chars');\n    assert.equal(moment('2010.*', 'YYYY.*', true).year(), 2010, 'valid format with regex chars');\n    assert.equal(moment('.*2010.*', '.*YYYY.*', true).year(), 2010, 'valid format with regex chars on both sides');\n\n    //strict tokens\n    assert.equal(moment('-5-05-25', 'YYYY-MM-DD', true).isValid(), false, 'invalid negative year');\n    assert.equal(moment('2-05-25', 'YYYY-MM-DD', true).isValid(), false, 'invalid one-digit year');\n    assert.equal(moment('20-05-25', 'YYYY-MM-DD', true).isValid(), false, 'invalid two-digit year');\n    assert.equal(moment('201-05-25', 'YYYY-MM-DD', true).isValid(), false, 'invalid three-digit year');\n    assert.equal(moment('2010-05-25', 'YYYY-MM-DD', true).isValid(), true, 'valid four-digit year');\n    assert.equal(moment('22010-05-25', 'YYYY-MM-DD', true).isValid(), false, 'invalid five-digit year');\n\n    assert.equal(moment('12-05-25', 'YY-MM-DD', true).isValid(), true, 'valid two-digit year');\n    assert.equal(moment('2012-05-25', 'YY-MM-DD', true).isValid(), false, 'invalid four-digit year');\n\n    assert.equal(moment('-5-05-25', 'Y-MM-DD', true).isValid(), true, 'valid negative year');\n    assert.equal(moment('2-05-25', 'Y-MM-DD', true).isValid(), true, 'valid one-digit year');\n    assert.equal(moment('20-05-25', 'Y-MM-DD', true).isValid(), true, 'valid two-digit year');\n    assert.equal(moment('201-05-25', 'Y-MM-DD', true).isValid(), true, 'valid three-digit year');\n\n    assert.equal(moment('2012-5-25', 'YYYY-M-DD', true).isValid(), true, 'valid one-digit month');\n    assert.equal(moment('2012-5-25', 'YYYY-MM-DD', true).isValid(), false, 'invalid one-digit month');\n    assert.equal(moment('2012-05-25', 'YYYY-M-DD', true).isValid(), true, 'valid one-digit month');\n    assert.equal(moment('2012-05-25', 'YYYY-MM-DD', true).isValid(), true, 'valid one-digit month');\n\n    assert.equal(moment('2012-05-2', 'YYYY-MM-D', true).isValid(), true, 'valid one-digit day');\n    assert.equal(moment('2012-05-2', 'YYYY-MM-DD', true).isValid(), false, 'invalid one-digit day');\n    assert.equal(moment('2012-05-02', 'YYYY-MM-D', true).isValid(), true, 'valid two-digit day');\n    assert.equal(moment('2012-05-02', 'YYYY-MM-DD', true).isValid(), true, 'valid two-digit day');\n\n    assert.equal(moment('+002012-05-25', 'YYYYY-MM-DD', true).isValid(), true, 'valid six-digit year');\n    assert.equal(moment('+2012-05-25', 'YYYYY-MM-DD', true).isValid(), false, 'invalid four-digit year');\n\n    //thse are kinda pointless, but they should work as expected\n    assert.equal(moment('1', 'S', true).isValid(), true, 'valid one-digit milisecond');\n    assert.equal(moment('12', 'S', true).isValid(), false, 'invalid two-digit milisecond');\n    assert.equal(moment('123', 'S', true).isValid(), false, 'invalid three-digit milisecond');\n\n    assert.equal(moment('1', 'SS', true).isValid(), false, 'invalid one-digit milisecond');\n    assert.equal(moment('12', 'SS', true).isValid(), true, 'valid two-digit milisecond');\n    assert.equal(moment('123', 'SS', true).isValid(), false, 'invalid three-digit milisecond');\n\n    assert.equal(moment('1', 'SSS', true).isValid(), false, 'invalid one-digit milisecond');\n    assert.equal(moment('12', 'SSS', true).isValid(), false, 'invalid two-digit milisecond');\n    assert.equal(moment('123', 'SSS', true).isValid(), true, 'valid three-digit milisecond');\n\n    // strict parsing respects month length\n    assert.ok(moment('1 January 2000', 'D MMMM YYYY', true).isValid(), 'capital long-month + MMMM');\n    assert.ok(!moment('1 January 2000', 'D MMM YYYY', true).isValid(), 'capital long-month + MMM');\n    assert.ok(!moment('1 Jan 2000', 'D MMMM YYYY', true).isValid(), 'capital short-month + MMMM');\n    assert.ok(moment('1 Jan 2000', 'D MMM YYYY', true).isValid(), 'capital short-month + MMM');\n    assert.ok(moment('1 january 2000', 'D MMMM YYYY', true).isValid(), 'lower long-month + MMMM');\n    assert.ok(!moment('1 january 2000', 'D MMM YYYY', true).isValid(), 'lower long-month + MMM');\n    assert.ok(!moment('1 jan 2000', 'D MMMM YYYY', true).isValid(), 'lower short-month + MMMM');\n    assert.ok(moment('1 jan 2000', 'D MMM YYYY', true).isValid(), 'lower short-month + MMM');\n});\n\ntest('parsing into a locale', function (assert) {\n    moment.defineLocale('parselocale', {\n        months : 'one_two_three_four_five_six_seven_eight_nine_ten_eleven_twelve'.split('_'),\n        monthsShort : 'one_two_three_four_five_six_seven_eight_nine_ten_eleven_twelve'.split('_')\n    });\n\n    moment.locale('en');\n\n    assert.equal(moment('2012 seven', 'YYYY MMM', 'parselocale').month(), 6, 'should be able to parse in a specific locale');\n\n    moment.locale('parselocale');\n\n    assert.equal(moment('2012 july', 'YYYY MMM', 'en').month(), 6, 'should be able to parse in a specific locale');\n\n    moment.defineLocale('parselocale', null);\n});\n\nfunction getVerifier(test) {\n    return function (input, format, expected, description, asymetrical) {\n        var m = moment(input, format);\n        test.equal(m.format('YYYY MM DD'), expected, 'compare: ' + description);\n\n        //test round trip\n        if (!asymetrical) {\n            test.equal(m.format(format), input, 'round trip: ' + description);\n        }\n    };\n}\n\ntest('parsing week and weekday information', function (assert) {\n    var ver = getVerifier(assert);\n    var currentWeekOfYear = moment().weeks();\n    var expectedDate2012 = moment([2012, 0, 1])\n      .day(0)\n      .add((currentWeekOfYear - 1), 'weeks')\n      .format('YYYY MM DD');\n    var expectedDate1999 = moment([1999, 0, 1])\n      .day(0)\n      .add((currentWeekOfYear - 1), 'weeks')\n      .format('YYYY MM DD');\n\n    // year\n    ver('12', 'gg', expectedDate2012, 'week-year two digits');\n    ver('2012', 'gggg', expectedDate2012, 'week-year four digits');\n    ver('99', 'gg', expectedDate1999, 'week-year two digits previous year');\n    ver('1999', 'gggg', expectedDate1999, 'week-year four digits previous year');\n\n    ver('99', 'GG', '1999 01 04', 'iso week-year two digits');\n    ver('1999', 'GGGG', '1999 01 04', 'iso week-year four digits');\n\n    ver('13', 'GG', '2012 12 31', 'iso week-year two digits previous year');\n    ver('2013', 'GGGG', '2012 12 31', 'iso week-year four digits previous year');\n\n    // year + week\n    ver('1999 37', 'gggg w', '1999 09 05', 'week');\n    ver('1999 37', 'gggg ww', '1999 09 05', 'week double');\n    ver('1999 37', 'GGGG W', '1999 09 13', 'iso week');\n    ver('1999 37', 'GGGG WW', '1999 09 13', 'iso week double');\n\n    ver('1999 37 4', 'GGGG WW E', '1999 09 16', 'iso day');\n    ver('1999 37 04', 'GGGG WW E', '1999 09 16', 'iso day wide', true);\n\n    ver('1999 37 4', 'gggg ww e', '1999 09 09', 'day');\n    ver('1999 37 04', 'gggg ww e', '1999 09 09', 'day wide', true);\n\n    // year + week + day\n    ver('1999 37 4', 'gggg ww d', '1999 09 09', 'd');\n    ver('1999 37 Th', 'gggg ww dd', '1999 09 09', 'dd');\n    ver('1999 37 Thu', 'gggg ww ddd', '1999 09 09', 'ddd');\n    ver('1999 37 Thursday', 'gggg ww dddd', '1999 09 09', 'dddd');\n\n    // lower-order only\n    assert.equal(moment('22', 'ww').week(), 22, 'week sets the week by itself');\n    assert.equal(moment('22', 'ww').weekYear(), moment().weekYear(), 'week keeps this year');\n    assert.equal(moment('2012 22', 'YYYY ww').weekYear(), 2012, 'week keeps parsed year');\n\n    assert.equal(moment('22', 'WW').isoWeek(), 22, 'iso week sets the week by itself');\n    assert.equal(moment('2012 22', 'YYYY WW').weekYear(), 2012, 'iso week keeps parsed year');\n    assert.equal(moment('22', 'WW').isoWeekYear(), moment().isoWeekYear(), 'iso week keeps this year');\n\n    // order\n    ver('6 2013 2', 'e gggg w', '2013 01 12', 'order doesn\\'t matter');\n    ver('6 2013 2', 'E GGGG W', '2013 01 12', 'iso order doesn\\'t matter');\n\n    //can parse other stuff too\n    assert.equal(moment('1999-W37-4 3:30', 'GGGG-[W]WW-E HH:mm').format('YYYY MM DD HH:mm'), '1999 09 16 03:30', 'parsing weeks and hours');\n\n    // In safari, all years before 1300 are shifted back with one day.\n    // http://stackoverflow.com/questions/20768975/safari-subtracts-1-day-from-dates-before-1300\n    if (new Date('1300-01-01').getUTCFullYear() === 1300) {\n        // Years less than 100\n        ver('0098-06', 'GGGG-WW', '0098 02 03', 'small years work', true);\n    }\n});\n\ntest('parsing localized weekdays', function (assert) {\n    var ver = getVerifier(assert);\n    try {\n        moment.locale('dow:1,doy:4', {\n            weekdays : 'dimanche_lundi_mardi_mercredi_jeudi_vendredi_samedi'.split('_'),\n            weekdaysShort : 'dim._lun._mar._mer._jeu._ven._sam.'.split('_'),\n            weekdaysMin : 'Di_Lu_Ma_Me_Je_Ve_Sa'.split('_'),\n            week: {dow: 1, doy: 4}\n        });\n        ver('1999 37 4', 'GGGG WW E', '1999 09 16', 'iso ignores locale');\n        ver('1999 37 7', 'GGGG WW E', '1999 09 19', 'iso ignores locale');\n\n        ver('1999 37 0', 'gggg ww e', '1999 09 13', 'localized e uses local doy and dow: 0 = monday');\n        ver('1999 37 4', 'gggg ww e', '1999 09 17', 'localized e uses local doy and dow: 4 = friday');\n\n        ver('1999 37 1', 'gggg ww d', '1999 09 13', 'localized d uses 0-indexed days: 1 = monday');\n        ver('1999 37 Lu', 'gggg ww dd', '1999 09 13', 'localized d uses 0-indexed days: Mo');\n        ver('1999 37 lun.', 'gggg ww ddd', '1999 09 13', 'localized d uses 0-indexed days: Mon');\n        ver('1999 37 lundi', 'gggg ww dddd', '1999 09 13', 'localized d uses 0-indexed days: Monday');\n        ver('1999 37 4', 'gggg ww d', '1999 09 16', 'localized d uses 0-indexed days: 4');\n\n        //sunday goes at the end of the week\n        ver('1999 37 0', 'gggg ww d', '1999 09 19', 'localized d uses 0-indexed days: 0 = sund');\n        ver('1999 37 Di', 'gggg ww dd', '1999 09 19', 'localized d uses 0-indexed days: 0 = sund');\n    }\n    finally {\n        moment.defineLocale('dow:1,doy:4', null);\n        moment.locale('en');\n    }\n});\n\ntest('parsing with customized two-digit year', function (assert) {\n    var original = moment.parseTwoDigitYear;\n    try {\n        assert.equal(moment('68', 'YY').year(), 2068);\n        assert.equal(moment('69', 'YY').year(), 1969);\n        moment.parseTwoDigitYear = function (input) {\n            return +input + (+input > 30 ? 1900 : 2000);\n        };\n        assert.equal(moment('68', 'YY').year(), 1968);\n        assert.equal(moment('67', 'YY').year(), 1967);\n        assert.equal(moment('31', 'YY').year(), 1931);\n        assert.equal(moment('30', 'YY').year(), 2030);\n    }\n    finally {\n        moment.parseTwoDigitYear = original;\n    }\n});\n\ntest('array with strings', function (assert) {\n    assert.equal(moment(['2014', '7', '31']).isValid(), true, 'string array + isValid');\n});\n\ntest('object with strings', function (assert) {\n    assert.equal(moment({year: '2014', month: '7', day: '31'}).isValid(), true, 'string object + isValid');\n});\n\ntest('utc with array of formats', function (assert) {\n    assert.equal(moment.utc('2014-01-01', ['YYYY-MM-DD', 'YYYY-MM']).format(), '2014-01-01T00:00:00Z', 'moment.utc works with array of formats');\n});\n\ntest('parsing invalid string weekdays', function (assert) {\n    assert.equal(false, moment('a', 'dd').isValid(),\n            'dd with invalid weekday, non-strict');\n    assert.equal(false, moment('a', 'dd', true).isValid(),\n            'dd with invalid weekday, strict');\n    assert.equal(false, moment('a', 'ddd').isValid(),\n            'ddd with invalid weekday, non-strict');\n    assert.equal(false, moment('a', 'ddd', true).isValid(),\n            'ddd with invalid weekday, strict');\n    assert.equal(false, moment('a', 'dddd').isValid(),\n            'dddd with invalid weekday, non-strict');\n    assert.equal(false, moment('a', 'dddd', true).isValid(),\n            'dddd with invalid weekday, strict');\n});\n\ntest('milliseconds', function (assert) {\n    assert.equal(moment('1', 'S').millisecond(), 100);\n    assert.equal(moment('12', 'SS').millisecond(), 120);\n    assert.equal(moment('123', 'SSS').millisecond(), 123);\n    assert.equal(moment('1234', 'SSSS').millisecond(), 123);\n    assert.equal(moment('12345', 'SSSSS').millisecond(), 123);\n    assert.equal(moment('123456', 'SSSSSS').millisecond(), 123);\n    assert.equal(moment('1234567', 'SSSSSSS').millisecond(), 123);\n    assert.equal(moment('12345678', 'SSSSSSSS').millisecond(), 123);\n    assert.equal(moment('123456789', 'SSSSSSSSS').millisecond(), 123);\n});\n\ntest('hmm', function (assert) {\n    assert.equal(moment('123', 'hmm', true).format('HH:mm:ss'), '01:23:00', '123 with hmm');\n    assert.equal(moment('123a', 'hmmA', true).format('HH:mm:ss'), '01:23:00', '123a with hmmA');\n    assert.equal(moment('123p', 'hmmA', true).format('HH:mm:ss'), '13:23:00', '123p with hmmA');\n\n    assert.equal(moment('1234', 'hmm', true).format('HH:mm:ss'), '12:34:00', '1234 with hmm');\n    assert.equal(moment('1234a', 'hmmA', true).format('HH:mm:ss'), '00:34:00', '1234a with hmmA');\n    assert.equal(moment('1234p', 'hmmA', true).format('HH:mm:ss'), '12:34:00', '1234p with hmmA');\n\n    assert.equal(moment('12345', 'hmmss', true).format('HH:mm:ss'), '01:23:45', '12345 with hmmss');\n    assert.equal(moment('12345a', 'hmmssA', true).format('HH:mm:ss'), '01:23:45', '12345a with hmmssA');\n    assert.equal(moment('12345p', 'hmmssA', true).format('HH:mm:ss'), '13:23:45', '12345p with hmmssA');\n    assert.equal(moment('112345', 'hmmss', true).format('HH:mm:ss'), '11:23:45', '112345 with hmmss');\n    assert.equal(moment('112345a', 'hmmssA', true).format('HH:mm:ss'), '11:23:45', '112345a with hmmssA');\n    assert.equal(moment('112345p', 'hmmssA', true).format('HH:mm:ss'), '23:23:45', '112345p with hmmssA');\n\n    assert.equal(moment('023', 'Hmm', true).format('HH:mm:ss'), '00:23:00', '023 with Hmm');\n    assert.equal(moment('123', 'Hmm', true).format('HH:mm:ss'), '01:23:00', '123 with Hmm');\n    assert.equal(moment('1234', 'Hmm', true).format('HH:mm:ss'), '12:34:00', '1234 with Hmm');\n    assert.equal(moment('1534', 'Hmm', true).format('HH:mm:ss'), '15:34:00', '1234 with Hmm');\n    assert.equal(moment('12345', 'Hmmss', true).format('HH:mm:ss'), '01:23:45', '12345 with Hmmss');\n    assert.equal(moment('112345', 'Hmmss', true).format('HH:mm:ss'), '11:23:45', '112345 with Hmmss');\n    assert.equal(moment('172345', 'Hmmss', true).format('HH:mm:ss'), '17:23:45', '112345 with Hmmss');\n});\n\ntest('Y token', function (assert) {\n    assert.equal(moment('1-1-2010', 'M-D-Y', true).year(), 2010, 'parsing Y');\n});\n\ntest('parsing flags retain parsed date parts', function (assert) {\n    var a = moment('10 p', 'hh:mm a');\n    assert.equal(a.parsingFlags().parsedDateParts[3], 10, 'parsed 10 as the hour');\n    assert.equal(a.parsingFlags().parsedDateParts[0], undefined, 'year was not parsed');\n    assert.equal(a.parsingFlags().meridiem, 'p', 'meridiem flag was added');\n    var b = moment('10:30', ['MMDDYY', 'HH:mm']);\n    assert.equal(b.parsingFlags().parsedDateParts[3], 10, 'multiple format parshing matched hour');\n    assert.equal(b.parsingFlags().parsedDateParts[0], undefined, 'array is properly copied, no residual data from first token parse');\n});\n\ntest('parsing only meridiem results in invalid date', function (assert) {\n    assert.ok(!moment('alkj', 'hh:mm a').isValid(), 'because an a token is used, a meridiem will be parsed but nothing else was so invalid');\n    assert.ok(moment('02:30 p more extra stuff', 'hh:mm a').isValid(), 'because other tokens were parsed, date is valid');\n    assert.ok(moment('1/1/2016 extra data', ['a', 'M/D/YYYY']).isValid(), 'took second format, does not pick up on meridiem parsed from first format (good copy)');\n});\n\ntest('invalid dates return invalid for methods that access the _d prop', function (assert) {\n    var momentAsDate = moment(['2015', '12', '1']).toDate();\n    assert.ok(momentAsDate instanceof Date, 'toDate returns a Date object');\n    assert.ok(isNaN(momentAsDate.getTime()), 'toDate returns an invalid Date invalid');\n});\n\ntest('k, kk', function (assert) {\n    for (var i = -1; i <= 24; i++) {\n        var kVal = i + ':15:59';\n        var kkVal = (i < 10 ? '0' : '') + i + ':15:59';\n        if (i !== 24) {\n            assert.ok(moment(kVal, 'k:mm:ss').isSame(moment(kVal, 'H:mm:ss')), kVal + ' k parsing');\n            assert.ok(moment(kkVal, 'kk:mm:ss').isSame(moment(kkVal, 'HH:mm:ss')), kkVal + ' kk parsing');\n        } else {\n            assert.equal(moment(kVal, 'k:mm:ss').format('k:mm:ss'), kVal, kVal + ' k parsing');\n            assert.equal(moment(kkVal, 'kk:mm:ss').format('kk:mm:ss'), kkVal, kkVal + ' skk parsing');\n        }\n    }\n});\n\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/test/moment/creation-data.js",
    "content": "import { module, test } from '../qunit';\nimport moment from '../../moment';\n\nmodule('creation data');\n\ntest('valid date', function (assert) {\n    var dat = moment('1992-10-22');\n    var orig = dat.creationData();\n\n    assert.equal(dat.isValid(), true, '1992-10-22 is valid');\n    assert.equal(orig.input, '1992-10-22', 'original input is not correct.');\n    assert.equal(orig.format, 'YYYY-MM-DD', 'original format is defined.');\n    assert.equal(orig.locale._abbr, 'en', 'default locale is en');\n    assert.equal(orig.isUTC, false, 'not a UTC date');\n});\n\ntest('valid date at fr locale', function (assert) {\n    var dat = moment('1992-10-22', 'YYYY-MM-DD', 'fr');\n    var orig = dat.creationData();\n\n    assert.equal(orig.locale._abbr, 'fr', 'locale is fr');\n});\n\ntest('valid date with formats', function (assert) {\n    var dat = moment('29-06-1995', ['MM-DD-YYYY', 'DD-MM', 'DD-MM-YYYY']);\n    var orig = dat.creationData();\n\n    assert.equal(orig.format, 'DD-MM-YYYY', 'DD-MM-YYYY format is defined.');\n});\n\ntest('strict', function (assert) {\n    assert.ok(moment('2015-01-02', 'YYYY-MM-DD', true).creationData().strict, 'strict is true');\n    assert.ok(!moment('2015-01-02', 'YYYY-MM-DD').creationData().strict, 'strict is true');\n});\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/test/moment/days_in_month.js",
    "content": "import { module, test } from '../qunit';\nimport moment from '../../moment';\nimport each from '../helpers/each';\n\nmodule('days in month');\n\ntest('days in month', function (assert) {\n    each([31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31], function (days, i) {\n        var firstDay = moment([2012, i]),\n            lastDay  = moment([2012, i, days]);\n        assert.equal(firstDay.daysInMonth(), days, firstDay.format('L') + ' should have ' + days + ' days.');\n        assert.equal(lastDay.daysInMonth(), days, lastDay.format('L') + ' should have ' + days + ' days.');\n    });\n});\n\ntest('days in month leap years', function (assert) {\n    assert.equal(moment([2010, 1]).daysInMonth(), 28, 'Feb 2010 should have 28 days');\n    assert.equal(moment([2100, 1]).daysInMonth(), 28, 'Feb 2100 should have 28 days');\n    assert.equal(moment([2008, 1]).daysInMonth(), 29, 'Feb 2008 should have 29 days');\n    assert.equal(moment([2000, 1]).daysInMonth(), 29, 'Feb 2000 should have 29 days');\n});\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/test/moment/days_in_year.js",
    "content": "import { module, test } from '../qunit';\nimport moment from '../../moment';\n\nmodule('days in year');\n\n// https://github.com/moment/moment/issues/3717\ntest('YYYYDDD should not parse DDD=000', function (assert) {\n    assert.equal(moment(7000000, moment.ISO_8601, true).isValid(), false);\n    assert.equal(moment('7000000', moment.ISO_8601, true).isValid(), false);\n    assert.equal(moment(7000000, moment.ISO_8601, false).isValid(), false);\n});\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/test/moment/deprecate.js",
    "content": "import { module, test, expect } from '../qunit';\nimport { deprecate } from '../../lib/utils/deprecate';\nimport moment from '../../moment';\n\nmodule('deprecate');\n\ntest('deprecate', function (assert) {\n    // NOTE: hooks inside deprecate.js and moment are different, so this is can\n    // not be test.expectedDeprecations(...)\n    var fn = function () {};\n    var deprecatedFn = deprecate('testing deprecation', fn);\n    deprecatedFn();\n\n    expect(0);\n});\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/test/moment/diff.js",
    "content": "import { module, test } from '../qunit';\nimport moment from '../../moment';\n\nfunction equal(assert, a, b, message) {\n    assert.ok(Math.abs(a - b) < 0.00000001, '(' + a + ' === ' + b + ') ' + message);\n}\n\nfunction dstForYear(year) {\n    var start = moment([year]),\n        end = moment([year + 1]),\n        current = start.clone(),\n        last;\n\n    while (current < end) {\n        last = current.clone();\n        current.add(24, 'hour');\n        if (last.utcOffset() !== current.utcOffset()) {\n            end = current.clone();\n            current = last.clone();\n            break;\n        }\n    }\n\n    while (current < end) {\n        last = current.clone();\n        current.add(1, 'hour');\n        if (last.utcOffset() !== current.utcOffset()) {\n            return {\n                moment : last,\n                diff : -(current.utcOffset() - last.utcOffset()) / 60\n            };\n        }\n    }\n}\n\nmodule('diff');\n\ntest('diff', function (assert) {\n    assert.equal(moment(1000).diff(0), 1000, '1 second - 0 = 1000');\n    assert.equal(moment(1000).diff(500), 500, '1 second - 0.5 seconds = 500');\n    assert.equal(moment(0).diff(1000), -1000, '0 - 1 second = -1000');\n    assert.equal(moment(new Date(1000)).diff(1000), 0, '1 second - 1 second = 0');\n    var oneHourDate = new Date(2015, 5, 21),\n    nowDate = new Date(+oneHourDate);\n    oneHourDate.setHours(oneHourDate.getHours() + 1);\n    assert.equal(moment(oneHourDate).diff(nowDate), 60 * 60 * 1000, '1 hour from now = 3600000');\n});\n\ntest('diff key after', function (assert) {\n    assert.equal(moment([2010]).diff([2011], 'years'), -1, 'year diff');\n    assert.equal(moment([2010]).diff([2010, 2], 'months'), -2, 'month diff');\n    assert.equal(moment([2010]).diff([2010, 0, 7], 'weeks'), 0, 'week diff');\n    assert.equal(moment([2010]).diff([2010, 0, 8], 'weeks'), -1, 'week diff');\n    assert.equal(moment([2010]).diff([2010, 0, 21], 'weeks'), -2, 'week diff');\n    assert.equal(moment([2010]).diff([2010, 0, 22], 'weeks'), -3, 'week diff');\n    assert.equal(moment([2010]).diff([2010, 0, 4], 'days'), -3, 'day diff');\n    assert.equal(moment([2010]).diff([2010, 0, 1, 4], 'hours'), -4, 'hour diff');\n    assert.equal(moment([2010]).diff([2010, 0, 1, 0, 5], 'minutes'), -5, 'minute diff');\n    assert.equal(moment([2010]).diff([2010, 0, 1, 0, 0, 6], 'seconds'), -6, 'second diff');\n});\n\ntest('diff key before', function (assert) {\n    assert.equal(moment([2011]).diff([2010], 'years'), 1, 'year diff');\n    assert.equal(moment([2010, 2]).diff([2010], 'months'), 2, 'month diff');\n    assert.equal(moment([2010, 0, 4]).diff([2010], 'days'), 3, 'day diff');\n    assert.equal(moment([2010, 0, 7]).diff([2010], 'weeks'), 0, 'week diff');\n    assert.equal(moment([2010, 0, 8]).diff([2010], 'weeks'), 1, 'week diff');\n    assert.equal(moment([2010, 0, 21]).diff([2010], 'weeks'), 2, 'week diff');\n    assert.equal(moment([2010, 0, 22]).diff([2010], 'weeks'), 3, 'week diff');\n    assert.equal(moment([2010, 0, 1, 4]).diff([2010], 'hours'), 4, 'hour diff');\n    assert.equal(moment([2010, 0, 1, 0, 5]).diff([2010], 'minutes'), 5, 'minute diff');\n    assert.equal(moment([2010, 0, 1, 0, 0, 6]).diff([2010], 'seconds'), 6, 'second diff');\n});\n\ntest('diff key before singular', function (assert) {\n    assert.equal(moment([2011]).diff([2010], 'year'), 1, 'year diff singular');\n    assert.equal(moment([2010, 2]).diff([2010], 'month'), 2, 'month diff singular');\n    assert.equal(moment([2010, 0, 4]).diff([2010], 'day'), 3, 'day diff singular');\n    assert.equal(moment([2010, 0, 7]).diff([2010], 'week'), 0, 'week diff singular');\n    assert.equal(moment([2010, 0, 8]).diff([2010], 'week'), 1, 'week diff singular');\n    assert.equal(moment([2010, 0, 21]).diff([2010], 'week'), 2, 'week diff singular');\n    assert.equal(moment([2010, 0, 22]).diff([2010], 'week'), 3, 'week diff singular');\n    assert.equal(moment([2010, 0, 1, 4]).diff([2010], 'hour'), 4, 'hour diff singular');\n    assert.equal(moment([2010, 0, 1, 0, 5]).diff([2010], 'minute'), 5, 'minute diff singular');\n    assert.equal(moment([2010, 0, 1, 0, 0, 6]).diff([2010], 'second'), 6, 'second diff singular');\n});\n\ntest('diff key before abbreviated', function (assert) {\n    assert.equal(moment([2011]).diff([2010], 'y'), 1, 'year diff abbreviated');\n    assert.equal(moment([2010, 2]).diff([2010], 'M'), 2, 'month diff abbreviated');\n    assert.equal(moment([2010, 0, 4]).diff([2010], 'd'), 3, 'day diff abbreviated');\n    assert.equal(moment([2010, 0, 7]).diff([2010], 'w'), 0, 'week diff abbreviated');\n    assert.equal(moment([2010, 0, 8]).diff([2010], 'w'), 1, 'week diff abbreviated');\n    assert.equal(moment([2010, 0, 21]).diff([2010], 'w'), 2, 'week diff abbreviated');\n    assert.equal(moment([2010, 0, 22]).diff([2010], 'w'), 3, 'week diff abbreviated');\n    assert.equal(moment([2010, 0, 1, 4]).diff([2010], 'h'), 4, 'hour diff abbreviated');\n    assert.equal(moment([2010, 0, 1, 0, 5]).diff([2010], 'm'), 5, 'minute diff abbreviated');\n    assert.equal(moment([2010, 0, 1, 0, 0, 6]).diff([2010], 's'), 6, 'second diff abbreviated');\n});\n\ntest('diff month', function (assert) {\n    assert.equal(moment([2011, 0, 31]).diff([2011, 2, 1], 'months'), -1, 'month diff');\n});\n\ntest('diff across DST', function (assert) {\n    var dst = dstForYear(2012), a, b, daysInMonth;\n    if (!dst) {\n        assert.equal(42, 42, 'at least one assertion');\n        return;\n    }\n\n    a = dst.moment;\n    b = a.clone().utc().add(12, 'hours').local();\n    daysInMonth = (a.daysInMonth() + b.daysInMonth()) / 2;\n    assert.equal(b.diff(a, 'milliseconds', true), 12 * 60 * 60 * 1000,\n            'ms diff across DST');\n    assert.equal(b.diff(a, 'seconds', true), 12 * 60 * 60,\n            'second diff across DST');\n    assert.equal(b.diff(a, 'minutes', true), 12 * 60,\n            'minute diff across DST');\n    assert.equal(b.diff(a, 'hours', true), 12,\n            'hour diff across DST');\n    assert.equal(b.diff(a, 'days', true), (12 - dst.diff) / 24,\n            'day diff across DST');\n    equal(assert, b.diff(a, 'weeks', true),  (12 - dst.diff) / 24 / 7,\n            'week diff across DST');\n    assert.ok(0.95 / (2 * 31) < b.diff(a, 'months', true),\n            'month diff across DST, lower bound');\n    assert.ok(b.diff(a, 'month', true) < 1.05 / (2 * 28),\n            'month diff across DST, upper bound');\n    assert.ok(0.95 / (2 * 31 * 12) < b.diff(a, 'years', true),\n            'year diff across DST, lower bound');\n    assert.ok(b.diff(a, 'year', true) < 1.05 / (2 * 28 * 12),\n            'year diff across DST, upper bound');\n\n    a = dst.moment;\n    b = a.clone().utc().add(12 + dst.diff, 'hours').local();\n    daysInMonth = (a.daysInMonth() + b.daysInMonth()) / 2;\n\n    assert.equal(b.diff(a, 'milliseconds', true),\n            (12 + dst.diff) * 60 * 60 * 1000,\n            'ms diff across DST');\n    assert.equal(b.diff(a, 'seconds', true),  (12 + dst.diff) * 60 * 60,\n            'second diff across DST');\n    assert.equal(b.diff(a, 'minutes', true),  (12 + dst.diff) * 60,\n            'minute diff across DST');\n    assert.equal(b.diff(a, 'hours', true),  (12 + dst.diff),\n            'hour diff across DST');\n    assert.equal(b.diff(a, 'days', true),  12 / 24, 'day diff across DST');\n    equal(assert, b.diff(a, 'weeks', true),  12 / 24 / 7,\n            'week diff across DST');\n    assert.ok(0.95 / (2 * 31) < b.diff(a, 'months', true),\n            'month diff across DST, lower bound');\n    assert.ok(b.diff(a, 'month', true) < 1.05 / (2 * 28),\n            'month diff across DST, upper bound');\n    assert.ok(0.95 / (2 * 31 * 12) < b.diff(a, 'years', true),\n            'year diff across DST, lower bound');\n    assert.ok(b.diff(a, 'year', true) < 1.05 / (2 * 28 * 12),\n            'year diff across DST, upper bound');\n});\n\ntest('diff overflow', function (assert) {\n    assert.equal(moment([2011]).diff([2010], 'months'), 12, 'month diff');\n    assert.equal(moment([2010, 0, 2]).diff([2010], 'hours'), 24, 'hour diff');\n    assert.equal(moment([2010, 0, 1, 2]).diff([2010], 'minutes'), 120, 'minute diff');\n    assert.equal(moment([2010, 0, 1, 0, 4]).diff([2010], 'seconds'), 240, 'second diff');\n});\n\ntest('diff between utc and local', function (assert) {\n    if (moment([2012]).utcOffset() === moment([2011]).utcOffset()) {\n        // Russia's utc offset on 1st of Jan 2012 vs 2011 is different\n        assert.equal(moment([2012]).utc().diff([2011], 'years'), 1, 'year diff');\n    }\n    assert.equal(moment([2010, 2, 2]).utc().diff([2010, 0, 2], 'months'), 2, 'month diff');\n    assert.equal(moment([2010, 0, 4]).utc().diff([2010], 'days'), 3, 'day diff');\n    assert.equal(moment([2010, 0, 22]).utc().diff([2010], 'weeks'), 3, 'week diff');\n    assert.equal(moment([2010, 0, 1, 4]).utc().diff([2010], 'hours'), 4, 'hour diff');\n    assert.equal(moment([2010, 0, 1, 0, 5]).utc().diff([2010], 'minutes'), 5, 'minute diff');\n    assert.equal(moment([2010, 0, 1, 0, 0, 6]).utc().diff([2010], 'seconds'), 6, 'second diff');\n});\n\ntest('diff floored', function (assert) {\n    assert.equal(moment([2010, 0, 1, 23]).diff([2010], 'day'), 0, '23 hours = 0 days');\n    assert.equal(moment([2010, 0, 1, 23, 59]).diff([2010], 'day'), 0, '23:59 hours = 0 days');\n    assert.equal(moment([2010, 0, 1, 24]).diff([2010], 'day'), 1, '24 hours = 1 day');\n    assert.equal(moment([2010, 0, 2]).diff([2011, 0, 1], 'year'), 0, 'year rounded down');\n    assert.equal(moment([2011, 0, 1]).diff([2010, 0, 2], 'year'), 0, 'year rounded down');\n    assert.equal(moment([2010, 0, 2]).diff([2011, 0, 2], 'year'), -1, 'year rounded down');\n    assert.equal(moment([2011, 0, 2]).diff([2010, 0, 2], 'year'), 1, 'year rounded down');\n});\n\ntest('year diffs include dates', function (assert) {\n    assert.ok(moment([2012, 1, 19]).diff(moment([2002, 1, 20]), 'years', true) < 10, 'year diff should include date of month');\n});\n\ntest('month diffs', function (assert) {\n    // due to floating point math errors, these tests just need to be accurate within 0.00000001\n    assert.equal(moment([2012, 0, 1]).diff([2012, 1, 1], 'months', true), -1, 'Jan 1 to Feb 1 should be 1 month');\n    equal(assert, moment([2012, 0, 1]).diff([2012, 0, 1, 12], 'months', true), -0.5 / 31, 'Jan 1 to Jan 1 noon should be 0.5 / 31 months');\n    assert.equal(moment([2012, 0, 15]).diff([2012, 1, 15], 'months', true), -1, 'Jan 15 to Feb 15 should be 1 month');\n    assert.equal(moment([2012, 0, 28]).diff([2012, 1, 28], 'months', true), -1, 'Jan 28 to Feb 28 should be 1 month');\n    assert.ok(moment([2012, 0, 31]).diff([2012, 1, 29], 'months', true), -1, 'Jan 31 to Feb 29 should be 1 month');\n    assert.ok(-1 > moment([2012, 0, 31]).diff([2012, 2, 1], 'months', true), 'Jan 31 to Mar 1 should be more than 1 month');\n    assert.ok(-30 / 28 < moment([2012, 0, 31]).diff([2012, 2, 1], 'months', true), 'Jan 31 to Mar 1 should be less than 1 month and 1 day');\n    equal(assert, moment([2012, 0, 1]).diff([2012, 0, 31], 'months', true), -(30 / 31), 'Jan 1 to Jan 31 should be 30 / 31 months');\n    assert.ok(0 < moment('2014-02-01').diff(moment('2014-01-31'), 'months', true), 'jan-31 to feb-1 diff is positive');\n});\n\ntest('exact month diffs', function (assert) {\n    // generate all pairs of months and compute month diff, with fixed day\n    // of month = 15.\n\n    var m1, m2;\n    for (m1 = 0; m1 < 12; ++m1) {\n        for (m2 = m1; m2 < 12; ++m2) {\n            assert.equal(moment([2013, m2, 15]).diff(moment([2013, m1, 15]), 'months', true), m2 - m1,\n                         'month diff from 2013-' + m1 + '-15 to 2013-' + m2 + '-15');\n        }\n    }\n});\n\ntest('year diffs', function (assert) {\n    // due to floating point math errors, these tests just need to be accurate within 0.00000001\n    equal(assert, moment([2012, 0, 1]).diff([2013, 0, 1], 'years', true), -1, 'Jan 1 2012 to Jan 1 2013 should be 1 year');\n    equal(assert, moment([2012, 1, 28]).diff([2013, 1, 28], 'years', true), -1, 'Feb 28 2012 to Feb 28 2013 should be 1 year');\n    equal(assert, moment([2012, 2, 1]).diff([2013, 2, 1], 'years', true), -1, 'Mar 1 2012 to Mar 1 2013 should be 1 year');\n    equal(assert, moment([2012, 11, 1]).diff([2013, 11, 1], 'years', true), -1, 'Dec 1 2012 to Dec 1 2013 should be 1 year');\n    equal(assert, moment([2012, 11, 31]).diff([2013, 11, 31], 'years', true), -1, 'Dec 31 2012 to Dec 31 2013 should be 1 year');\n    equal(assert, moment([2012, 0, 1]).diff([2013, 6, 1], 'years', true), -1.5, 'Jan 1 2012 to Jul 1 2013 should be 1.5 years');\n    equal(assert, moment([2012, 0, 31]).diff([2013, 6, 31], 'years', true), -1.5, 'Jan 31 2012 to Jul 31 2013 should be 1.5 years');\n    equal(assert, moment([2012, 0, 1]).diff([2013, 0, 1, 12], 'years', true), -1 - (0.5 / 31) / 12, 'Jan 1 2012 to Jan 1 2013 noon should be 1+(0.5 / 31) / 12 years');\n    equal(assert, moment([2012, 0, 1]).diff([2013, 6, 1, 12], 'years', true), -1.5 - (0.5 / 31) / 12, 'Jan 1 2012 to Jul 1 2013 noon should be 1.5+(0.5 / 31) / 12 years');\n    equal(assert, moment([2012, 1, 29]).diff([2013, 1, 28], 'years', true), -1, 'Feb 29 2012 to Feb 28 2013 should be 1-(1 / 28.5) / 12 years');\n});\n\ntest('negative zero', function (assert) {\n    function isNegative (n) {\n        return (1 / n) < 0;\n    }\n    assert.ok(!isNegative(moment([2012, 0, 1]).diff(moment([2012, 0, 1]), 'months')), 'month diff on same date is zero, not -0');\n    assert.ok(!isNegative(moment([2012, 0, 1]).diff(moment([2012, 0, 1]), 'years')), 'year diff on same date is zero, not -0');\n    assert.ok(!isNegative(moment([2012, 0, 1]).diff(moment([2012, 0, 1]), 'quarters')), 'quarter diff on same date is zero, not -0');\n    assert.ok(!isNegative(moment([2012, 0, 1]).diff(moment([2012, 0, 1, 1]), 'days')), 'days diff on same date is zero, not -0');\n    assert.ok(!isNegative(moment([2012, 0, 1]).diff(moment([2012, 0, 1, 0, 1]), 'hours')), 'hour diff on same hour is zero, not -0');\n    assert.ok(!isNegative(moment([2012, 0, 1]).diff(moment([2012, 0, 1, 0, 0, 1]), 'minutes')), 'minute diff on same minute is zero, not -0');\n    assert.ok(!isNegative(moment([2012, 0, 1]).diff(moment([2012, 0, 1, 0, 0, 0, 1]), 'seconds')), 'second diff on same second is zero, not -0');\n});\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/test/moment/duration.js",
    "content": "import { module, test } from '../qunit';\nimport moment from '../../moment';\n\nmodule('duration');\n\ntest('object instantiation', function (assert) {\n    var d = moment.duration({\n        years: 2,\n        months: 3,\n        weeks: 2,\n        days: 1,\n        hours: 8,\n        minutes: 9,\n        seconds: 20,\n        milliseconds: 12\n    });\n\n    assert.equal(d.years(),        2,  'years');\n    assert.equal(d.months(),       3,  'months');\n    assert.equal(d.weeks(),        2,  'weeks');\n    assert.equal(d.days(),         15, 'days'); // two weeks + 1 day\n    assert.equal(d.hours(),        8,  'hours');\n    assert.equal(d.minutes(),      9,  'minutes');\n    assert.equal(d.seconds(),      20, 'seconds');\n    assert.equal(d.milliseconds(), 12, 'milliseconds');\n});\n\ntest('object instantiation with strings', function (assert) {\n    var d = moment.duration({\n        years: '2',\n        months: '3',\n        weeks: '2',\n        days: '1',\n        hours: '8',\n        minutes: '9',\n        seconds: '20',\n        milliseconds: '12'\n    });\n\n    assert.equal(d.years(),        2,  'years');\n    assert.equal(d.months(),       3,  'months');\n    assert.equal(d.weeks(),        2,  'weeks');\n    assert.equal(d.days(),         15, 'days'); // two weeks + 1 day\n    assert.equal(d.hours(),        8,  'hours');\n    assert.equal(d.minutes(),      9,  'minutes');\n    assert.equal(d.seconds(),      20, 'seconds');\n    assert.equal(d.milliseconds(), 12, 'milliseconds');\n});\n\ntest('milliseconds instantiation', function (assert) {\n    assert.equal(moment.duration(72).milliseconds(), 72, 'milliseconds');\n    assert.equal(moment.duration(72).humanize(), 'a few seconds', 'Duration should be valid');\n});\n\ntest('undefined instantiation', function (assert) {\n    assert.equal(moment.duration(undefined).milliseconds(), 0, 'milliseconds');\n    assert.equal(moment.duration(undefined).isValid(), true, '_isValid');\n    assert.equal(moment.duration(undefined).humanize(), 'a few seconds', 'Duration should be valid');\n});\n\ntest('null instantiation', function (assert) {\n    assert.equal(moment.duration(null).milliseconds(), 0, 'milliseconds');\n    assert.equal(moment.duration(null).isValid(), true, '_isValid');\n    assert.equal(moment.duration(null).humanize(), 'a few seconds', 'Duration should be valid');\n});\n\ntest('NaN instantiation', function (assert) {\n    assert.ok(isNaN(moment.duration(NaN).milliseconds()), 'milliseconds should be NaN');\n    assert.equal(moment.duration(NaN).isValid(), false, '_isValid');\n    assert.equal(moment.duration(NaN).humanize(), 'Invalid date', 'Duration should be invalid');\n});\n\ntest('instantiation by type', function (assert) {\n    assert.equal(moment.duration(1, 'years').years(),                 1, 'years');\n    assert.equal(moment.duration(1, 'y').years(),                     1, 'y');\n    assert.equal(moment.duration(2, 'months').months(),               2, 'months');\n    assert.equal(moment.duration(2, 'M').months(),                    2, 'M');\n    assert.equal(moment.duration(3, 'weeks').weeks(),                 3, 'weeks');\n    assert.equal(moment.duration(3, 'w').weeks(),                     3, 'weeks');\n    assert.equal(moment.duration(4, 'days').days(),                   4, 'days');\n    assert.equal(moment.duration(4, 'd').days(),                      4, 'd');\n    assert.equal(moment.duration(5, 'hours').hours(),                 5, 'hours');\n    assert.equal(moment.duration(5, 'h').hours(),                     5, 'h');\n    assert.equal(moment.duration(6, 'minutes').minutes(),             6, 'minutes');\n    assert.equal(moment.duration(6, 'm').minutes(),                   6, 'm');\n    assert.equal(moment.duration(7, 'seconds').seconds(),             7, 'seconds');\n    assert.equal(moment.duration(7, 's').seconds(),                   7, 's');\n    assert.equal(moment.duration(8, 'milliseconds').milliseconds(),   8, 'milliseconds');\n    assert.equal(moment.duration(8, 'ms').milliseconds(),             8, 'ms');\n});\n\ntest('shortcuts', function (assert) {\n    assert.equal(moment.duration({y: 1}).years(),         1, 'years = y');\n    assert.equal(moment.duration({M: 2}).months(),        2, 'months = M');\n    assert.equal(moment.duration({w: 3}).weeks(),         3, 'weeks = w');\n    assert.equal(moment.duration({d: 4}).days(),          4, 'days = d');\n    assert.equal(moment.duration({h: 5}).hours(),         5, 'hours = h');\n    assert.equal(moment.duration({m: 6}).minutes(),       6, 'minutes = m');\n    assert.equal(moment.duration({s: 7}).seconds(),       7, 'seconds = s');\n    assert.equal(moment.duration({ms: 8}).milliseconds(), 8, 'milliseconds = ms');\n});\n\ntest('generic getter', function (assert) {\n    assert.equal(moment.duration(1, 'years').get('years'),                1, 'years');\n    assert.equal(moment.duration(1, 'years').get('year'),                 1, 'years = year');\n    assert.equal(moment.duration(1, 'years').get('y'),                    1, 'years = y');\n    assert.equal(moment.duration(2, 'months').get('months'),              2, 'months');\n    assert.equal(moment.duration(2, 'months').get('month'),               2, 'months = month');\n    assert.equal(moment.duration(2, 'months').get('M'),                   2, 'months = M');\n    assert.equal(moment.duration(3, 'weeks').get('weeks'),                3, 'weeks');\n    assert.equal(moment.duration(3, 'weeks').get('week'),                 3, 'weeks = week');\n    assert.equal(moment.duration(3, 'weeks').get('w'),                    3, 'weeks = w');\n    assert.equal(moment.duration(4, 'days').get('days'),                  4, 'days');\n    assert.equal(moment.duration(4, 'days').get('day'),                   4, 'days = day');\n    assert.equal(moment.duration(4, 'days').get('d'),                     4, 'days = d');\n    assert.equal(moment.duration(5, 'hours').get('hours'),                5, 'hours');\n    assert.equal(moment.duration(5, 'hours').get('hour'),                 5, 'hours = hour');\n    assert.equal(moment.duration(5, 'hours').get('h'),                    5, 'hours = h');\n    assert.equal(moment.duration(6, 'minutes').get('minutes'),            6, 'minutes');\n    assert.equal(moment.duration(6, 'minutes').get('minute'),             6, 'minutes = minute');\n    assert.equal(moment.duration(6, 'minutes').get('m'),                  6, 'minutes = m');\n    assert.equal(moment.duration(7, 'seconds').get('seconds'),            7, 'seconds');\n    assert.equal(moment.duration(7, 'seconds').get('second'),             7, 'seconds = second');\n    assert.equal(moment.duration(7, 'seconds').get('s'),                  7, 'seconds = s');\n    assert.equal(moment.duration(8, 'milliseconds').get('milliseconds'),  8, 'milliseconds');\n    assert.equal(moment.duration(8, 'milliseconds').get('millisecond'),   8, 'milliseconds = millisecond');\n    assert.equal(moment.duration(8, 'milliseconds').get('ms'),            8, 'milliseconds = ms');\n});\n\ntest('instantiation from another duration', function (assert) {\n    var simple = moment.duration(1234),\n        lengthy = moment.duration(60 * 60 * 24 * 360 * 1e3),\n        complicated = moment.duration({\n            years: 2,\n            months: 3,\n            weeks: 4,\n            days: 1,\n            hours: 8,\n            minutes: 9,\n            seconds: 20,\n            milliseconds: 12\n        }),\n        modified = moment.duration(1, 'day').add(moment.duration(1, 'day'));\n\n    assert.deepEqual(moment.duration(simple), simple, 'simple clones are equal');\n    assert.deepEqual(moment.duration(lengthy), lengthy, 'lengthy clones are equal');\n    assert.deepEqual(moment.duration(complicated), complicated, 'complicated clones are equal');\n    assert.deepEqual(moment.duration(modified), modified, 'cloning modified duration works');\n});\n\ntest('instantiation from 24-hour time zero', function (assert) {\n    assert.equal(moment.duration('00:00').years(), 0, '0 years');\n    assert.equal(moment.duration('00:00').days(), 0, '0 days');\n    assert.equal(moment.duration('00:00').hours(), 0, '0 hours');\n    assert.equal(moment.duration('00:00').minutes(), 0, '0 minutes');\n    assert.equal(moment.duration('00:00').seconds(), 0, '0 seconds');\n    assert.equal(moment.duration('00:00').milliseconds(), 0, '0 milliseconds');\n});\n\ntest('instantiation from 24-hour time <24 hours', function (assert) {\n    assert.equal(moment.duration('06:45').years(), 0, '0 years');\n    assert.equal(moment.duration('06:45').days(), 0, '0 days');\n    assert.equal(moment.duration('06:45').hours(), 6, '6 hours');\n    assert.equal(moment.duration('06:45').minutes(), 45, '45 minutes');\n    assert.equal(moment.duration('06:45').seconds(), 0, '0 seconds');\n    assert.equal(moment.duration('06:45').milliseconds(), 0, '0 milliseconds');\n});\n\ntest('instantiation from 24-hour time >24 hours', function (assert) {\n    assert.equal(moment.duration('26:45').years(), 0, '0 years');\n    assert.equal(moment.duration('26:45').days(), 1, '0 days');\n    assert.equal(moment.duration('26:45').hours(), 2, '2 hours');\n    assert.equal(moment.duration('26:45').minutes(), 45, '45 minutes');\n    assert.equal(moment.duration('26:45').seconds(), 0, '0 seconds');\n    assert.equal(moment.duration('26:45').milliseconds(), 0, '0 milliseconds');\n});\n\ntest('instatiation from serialized C# TimeSpan zero', function (assert) {\n    assert.equal(moment.duration('00:00:00').years(), 0, '0 years');\n    assert.equal(moment.duration('00:00:00').days(), 0, '0 days');\n    assert.equal(moment.duration('00:00:00').hours(), 0, '0 hours');\n    assert.equal(moment.duration('00:00:00').minutes(), 0, '0 minutes');\n    assert.equal(moment.duration('00:00:00').seconds(), 0, '0 seconds');\n    assert.equal(moment.duration('00:00:00').milliseconds(), 0, '0 milliseconds');\n});\n\ntest('instatiation from serialized C# TimeSpan with days', function (assert) {\n    assert.equal(moment.duration('1.02:03:04.9999999').years(), 0, '0 years');\n    assert.equal(moment.duration('1.02:03:04.9999999').days(), 1, '1 day');\n    assert.equal(moment.duration('1.02:03:04.9999999').hours(), 2, '2 hours');\n    assert.equal(moment.duration('1.02:03:04.9999999').minutes(), 3, '3 minutes');\n    assert.equal(moment.duration('1.02:03:04.9999999').seconds(), 5, '5 seconds');\n    assert.equal(moment.duration('1.02:03:04.9999999').milliseconds(), 0, '0 milliseconds');\n\n    assert.equal(moment.duration('1 02:03:04.9999999').years(), 0, '0 years');\n    assert.equal(moment.duration('1 02:03:04.9999999').days(), 1, '1 day');\n    assert.equal(moment.duration('1 02:03:04.9999999').hours(), 2, '2 hours');\n    assert.equal(moment.duration('1 02:03:04.9999999').minutes(), 3, '3 minutes');\n    assert.equal(moment.duration('1 02:03:04.9999999').seconds(), 5, '5 seconds');\n    assert.equal(moment.duration('1 02:03:04.9999999').milliseconds(), 0, '0 milliseconds');\n});\n\ntest('instatiation from serialized C# TimeSpan without days', function (assert) {\n    assert.equal(moment.duration('01:02:03.9999999').years(), 0, '0 years');\n    assert.equal(moment.duration('01:02:03.9999999').days(), 0, '0 days');\n    assert.equal(moment.duration('01:02:03.9999999').hours(), 1, '1 hour');\n    assert.equal(moment.duration('01:02:03.9999999').minutes(), 2, '2 minutes');\n    assert.equal(moment.duration('01:02:03.9999999').seconds(), 4, '4 seconds');\n    assert.equal(moment.duration('01:02:03.9999999').milliseconds(), 0, '0 milliseconds');\n\n    assert.equal(moment.duration('23:59:59.9999999').days(), 1, '1 days');\n    assert.equal(moment.duration('23:59:59.9999999').hours(), 0, '0 hours');\n    assert.equal(moment.duration('23:59:59.9999999').minutes(), 0, '0 minutes');\n    assert.equal(moment.duration('23:59:59.9999999').seconds(), 0, '0 seconds');\n    assert.equal(moment.duration('23:59:59.9999999').milliseconds(), 0, '0 milliseconds');\n\n    assert.equal(moment.duration('500:59:59.8888888').days(), 20, '500 hours overflows to 20 days');\n    assert.equal(moment.duration('500:59:59.8888888').hours(), 20, '500 hours overflows to 20 hours');\n});\n\ntest('instatiation from serialized C# TimeSpan without days or milliseconds', function (assert) {\n    assert.equal(moment.duration('01:02:03').years(), 0, '0 years');\n    assert.equal(moment.duration('01:02:03').days(), 0, '0 days');\n    assert.equal(moment.duration('01:02:03').hours(), 1, '1 hour');\n    assert.equal(moment.duration('01:02:03').minutes(), 2, '2 minutes');\n    assert.equal(moment.duration('01:02:03').seconds(), 3, '3 seconds');\n    assert.equal(moment.duration('01:02:03').milliseconds(), 0, '0 milliseconds');\n});\n\ntest('instatiation from serialized C# TimeSpan without milliseconds', function (assert) {\n    assert.equal(moment.duration('1.02:03:04').years(), 0, '0 years');\n    assert.equal(moment.duration('1.02:03:04').days(), 1, '1 day');\n    assert.equal(moment.duration('1.02:03:04').hours(), 2, '2 hours');\n    assert.equal(moment.duration('1.02:03:04').minutes(), 3, '3 minutes');\n    assert.equal(moment.duration('1.02:03:04').seconds(), 4, '4 seconds');\n    assert.equal(moment.duration('1.02:03:04').milliseconds(), 0, '0 milliseconds');\n});\n\ntest('instantiation from serialized C# TimeSpan with low millisecond precision', function (assert) {\n    assert.equal(moment.duration('00:00:15.72').years(), 0, '0 years');\n    assert.equal(moment.duration('00:00:15.72').days(), 0, '0 days');\n    assert.equal(moment.duration('00:00:15.72').hours(), 0, '0 hours');\n    assert.equal(moment.duration('00:00:15.72').minutes(), 0, '0 minutes');\n    assert.equal(moment.duration('00:00:15.72').seconds(), 15, '15 seconds');\n    assert.equal(moment.duration('00:00:15.72').milliseconds(), 720, '720 milliseconds');\n\n    assert.equal(moment.duration('00:00:15.7').milliseconds(), 700, '700 milliseconds');\n\n    assert.equal(moment.duration('00:00:15.').milliseconds(), 0, '0 milliseconds');\n});\n\ntest('instantiation from serialized C# TimeSpan with high millisecond precision', function (assert) {\n    assert.equal(moment.duration('00:00:15.7200000').seconds(), 15, '15 seconds');\n    assert.equal(moment.duration('00:00:15.7200000').milliseconds(), 720, '720 milliseconds');\n\n    assert.equal(moment.duration('00:00:15.7209999').seconds(), 15, '15 seconds');\n    assert.equal(moment.duration('00:00:15.7209999').milliseconds(), 721, '721 milliseconds');\n\n    assert.equal(moment.duration('00:00:15.7205000').seconds(), 15, '15 seconds');\n    assert.equal(moment.duration('00:00:15.7205000').milliseconds(), 721, '721 milliseconds');\n\n    assert.equal(moment.duration('-00:00:15.7205000').seconds(), -15, '15 seconds');\n    assert.equal(moment.duration('-00:00:15.7205000').milliseconds(), -721, '721 milliseconds');\n});\n\ntest('instatiation from serialized C# TimeSpan maxValue', function (assert) {\n    var d = moment.duration('10675199.02:48:05.4775807');\n\n    assert.equal(d.years(), 29227, '29227 years');\n    assert.equal(d.months(), 8, '8 months');\n    assert.equal(d.days(), 12, '12 day');  // if you have to change this value -- just do it\n\n    assert.equal(d.hours(), 2, '2 hours');\n    assert.equal(d.minutes(), 48, '48 minutes');\n    assert.equal(d.seconds(), 5, '5 seconds');\n    assert.equal(d.milliseconds(), 478, '478 milliseconds');\n});\n\ntest('instatiation from serialized C# TimeSpan minValue', function (assert) {\n    var d = moment.duration('-10675199.02:48:05.4775808');\n\n    assert.equal(d.years(), -29227, '29653 years');\n    assert.equal(d.months(), -8, '8 day');\n    assert.equal(d.days(), -12, '12 day');  // if you have to change this value -- just do it\n\n    assert.equal(d.hours(), -2, '2 hours');\n    assert.equal(d.minutes(), -48, '48 minutes');\n    assert.equal(d.seconds(), -5, '5 seconds');\n    assert.equal(d.milliseconds(), -478, '478 milliseconds');\n});\n\ntest('instantiation from ISO 8601 duration', function (assert) {\n    assert.equal(moment.duration('P1Y2M3DT4H5M6S').asSeconds(), moment.duration({y: 1, M: 2, d: 3, h: 4, m: 5, s: 6}).asSeconds(), 'all fields');\n    assert.equal(moment.duration('P3W3D').asSeconds(), moment.duration({w: 3, d: 3}).asSeconds(), 'week and day fields');\n    assert.equal(moment.duration('P1M').asSeconds(), moment.duration({M: 1}).asSeconds(), 'single month field');\n    assert.equal(moment.duration('PT1M').asSeconds(), moment.duration({m: 1}).asSeconds(), 'single minute field');\n    assert.equal(moment.duration('P1MT2H').asSeconds(), moment.duration({M: 1, h: 2}).asSeconds(), 'random fields missing');\n    assert.equal(moment.duration('-P60D').asSeconds(), moment.duration({d: -60}).asSeconds(), 'negative days');\n    assert.equal(moment.duration('PT0.5S').asSeconds(), moment.duration({s: 0.5}).asSeconds(), 'fractional seconds');\n    assert.equal(moment.duration('PT0,5S').asSeconds(), moment.duration({s: 0.5}).asSeconds(), 'fractional seconds (comma)');\n});\n\ntest('serialization to ISO 8601 duration strings', function (assert) {\n    assert.equal(moment.duration({y: 1, M: 2, d: 3, h: 4, m: 5, s: 6}).toISOString(), 'P1Y2M3DT4H5M6S', 'all fields');\n    assert.equal(moment.duration({M: -1}).toISOString(), '-P1M', 'one month ago');\n    assert.equal(moment.duration({m: -1}).toISOString(), '-PT1M', 'one minute ago');\n    assert.equal(moment.duration({s: -0.5}).toISOString(), '-PT0.5S', 'one half second ago');\n    assert.equal(moment.duration({y: -1, M: 1}).toISOString(), '-P11M', 'a month after a year ago');\n    assert.equal(moment.duration({}).toISOString(), 'P0D', 'zero duration');\n    assert.equal(moment.duration({M: 16, d:40, s: 86465}).toISOString(), 'P1Y4M40DT24H1M5S', 'all fields');\n});\n\ntest('toString acts as toISOString', function (assert) {\n    assert.equal(moment.duration({y: 1, M: 2, d: 3, h: 4, m: 5, s: 6}).toString(), 'P1Y2M3DT4H5M6S', 'all fields');\n    assert.equal(moment.duration({M: -1}).toString(), '-P1M', 'one month ago');\n    assert.equal(moment.duration({m: -1}).toString(), '-PT1M', 'one minute ago');\n    assert.equal(moment.duration({s: -0.5}).toString(), '-PT0.5S', 'one half second ago');\n    assert.equal(moment.duration({y: -1, M: 1}).toString(), '-P11M', 'a month after a year ago');\n    assert.equal(moment.duration({}).toString(), 'P0D', 'zero duration');\n    assert.equal(moment.duration({M: 16, d:40, s: 86465}).toString(), 'P1Y4M40DT24H1M5S', 'all fields');\n});\n\ntest('toIsoString deprecation', function (assert) {\n    test.expectedDeprecations('toIsoString()');\n\n    assert.equal(moment.duration({}).toIsoString(), moment.duration({}).toISOString(), 'toIsoString delegates to toISOString');\n});\n\ntest('`isodate` (python) test cases', function (assert) {\n    assert.equal(moment.duration('P18Y9M4DT11H9M8S').asSeconds(), moment.duration({y: 18, M: 9, d: 4, h: 11, m: 9, s: 8}).asSeconds(), 'python isodate 1');\n    assert.equal(moment.duration('P2W').asSeconds(), moment.duration({w: 2}).asSeconds(), 'python isodate 2');\n    assert.equal(moment.duration('P3Y6M4DT12H30M5S').asSeconds(), moment.duration({y: 3, M: 6, d: 4, h: 12, m: 30, s: 5}).asSeconds(), 'python isodate 3');\n    assert.equal(moment.duration('P23DT23H').asSeconds(), moment.duration({d: 23, h: 23}).asSeconds(), 'python isodate 4');\n    assert.equal(moment.duration('P4Y').asSeconds(), moment.duration({y: 4}).asSeconds(), 'python isodate 5');\n    assert.equal(moment.duration('P1M').asSeconds(), moment.duration({M: 1}).asSeconds(), 'python isodate 6');\n    assert.equal(moment.duration('PT1M').asSeconds(), moment.duration({m: 1}).asSeconds(), 'python isodate 7');\n    assert.equal(moment.duration('P0.5Y').asSeconds(), moment.duration({y: 0.5}).asSeconds(), 'python isodate 8');\n    assert.equal(moment.duration('PT36H').asSeconds(), moment.duration({h: 36}).asSeconds(), 'python isodate 9');\n    assert.equal(moment.duration('P1DT12H').asSeconds(), moment.duration({d: 1, h: 12}).asSeconds(), 'python isodate 10');\n    assert.equal(moment.duration('-P2W').asSeconds(), moment.duration({w: -2}).asSeconds(), 'python isodate 11');\n    assert.equal(moment.duration('-P2.2W').asSeconds(), moment.duration({w: -2.2}).asSeconds(), 'python isodate 12');\n    assert.equal(moment.duration('P1DT2H3M4S').asSeconds(), moment.duration({d: 1, h: 2, m: 3, s: 4}).asSeconds(), 'python isodate 13');\n    assert.equal(moment.duration('P1DT2H3M').asSeconds(), moment.duration({d: 1, h: 2, m: 3}).asSeconds(), 'python isodate 14');\n    assert.equal(moment.duration('P1DT2H').asSeconds(), moment.duration({d: 1, h: 2}).asSeconds(), 'python isodate 15');\n    assert.equal(moment.duration('PT2H').asSeconds(), moment.duration({h: 2}).asSeconds(), 'python isodate 16');\n    assert.equal(moment.duration('PT2.3H').asSeconds(), moment.duration({h: 2.3}).asSeconds(), 'python isodate 17');\n    assert.equal(moment.duration('PT2H3M4S').asSeconds(), moment.duration({h: 2, m: 3, s: 4}).asSeconds(), 'python isodate 18');\n    assert.equal(moment.duration('PT3M4S').asSeconds(), moment.duration({m: 3, s: 4}).asSeconds(), 'python isodate 19');\n    assert.equal(moment.duration('PT22S').asSeconds(), moment.duration({s: 22}).asSeconds(), 'python isodate 20');\n    assert.equal(moment.duration('PT22.22S').asSeconds(), moment.duration({s: 22.22}).asSeconds(), 'python isodate 21');\n    assert.equal(moment.duration('-P2Y').asSeconds(), moment.duration({y: -2}).asSeconds(), 'python isodate 22');\n    assert.equal(moment.duration('-P3Y6M4DT12H30M5S').asSeconds(), moment.duration({y: -3, M: -6, d: -4, h: -12, m: -30, s: -5}).asSeconds(), 'python isodate 23');\n    assert.equal(moment.duration('-P1DT2H3M4S').asSeconds(), moment.duration({d: -1, h: -2, m: -3, s: -4}).asSeconds(), 'python isodate 24');\n    assert.equal(moment.duration('PT-6H3M').asSeconds(), moment.duration({h: -6, m: 3}).asSeconds(), 'python isodate 25');\n    assert.equal(moment.duration('-PT-6H3M').asSeconds(), moment.duration({h: 6, m: -3}).asSeconds(), 'python isodate 26');\n    assert.equal(moment.duration('-P-3Y-6M-4DT-12H-30M-5S').asSeconds(), moment.duration({y: 3, M: 6, d: 4, h: 12, m: 30, s: 5}).asSeconds(), 'python isodate 27');\n    assert.equal(moment.duration('P-3Y-6M-4DT-12H-30M-5S').asSeconds(), moment.duration({y: -3, M: -6, d: -4, h: -12, m: -30, s: -5}).asSeconds(), 'python isodate 28');\n    assert.equal(moment.duration('-P-2W').asSeconds(), moment.duration({w: 2}).asSeconds(), 'python isodate 29');\n    assert.equal(moment.duration('P-2W').asSeconds(), moment.duration({w: -2}).asSeconds(), 'python isodate 30');\n});\n\ntest('ISO 8601 misuse cases', function (assert) {\n    assert.equal(moment.duration('P').asSeconds(), 0, 'lonely P');\n    assert.equal(moment.duration('PT').asSeconds(), 0, 'just P and T');\n    assert.equal(moment.duration('P1H').asSeconds(), 0, 'missing T');\n    assert.equal(moment.duration('P1D1Y').asSeconds(), 0, 'out of order');\n    assert.equal(moment.duration('PT.5S').asSeconds(), 0.5, 'accept no leading zero for decimal');\n    assert.equal(moment.duration('PT1,S').asSeconds(), 1, 'accept trailing decimal separator');\n    assert.equal(moment.duration('PT1M0,,5S').asSeconds(), 60, 'extra decimal separators are ignored as 0');\n});\n\ntest('humanize', function (assert) {\n    moment.locale('en');\n    assert.equal(moment.duration({seconds: 44}).humanize(),  'a few seconds', '44 seconds = a few seconds');\n    assert.equal(moment.duration({seconds: 45}).humanize(),  'a minute',      '45 seconds = a minute');\n    assert.equal(moment.duration({seconds: 89}).humanize(),  'a minute',      '89 seconds = a minute');\n    assert.equal(moment.duration({seconds: 90}).humanize(),  '2 minutes',     '90 seconds = 2 minutes');\n    assert.equal(moment.duration({minutes: 44}).humanize(),  '44 minutes',    '44 minutes = 44 minutes');\n    assert.equal(moment.duration({minutes: 45}).humanize(),  'an hour',       '45 minutes = an hour');\n    assert.equal(moment.duration({minutes: 89}).humanize(),  'an hour',       '89 minutes = an hour');\n    assert.equal(moment.duration({minutes: 90}).humanize(),  '2 hours',       '90 minutes = 2 hours');\n    assert.equal(moment.duration({hours: 5}).humanize(),     '5 hours',       '5 hours = 5 hours');\n    assert.equal(moment.duration({hours: 21}).humanize(),    '21 hours',      '21 hours = 21 hours');\n    assert.equal(moment.duration({hours: 22}).humanize(),    'a day',         '22 hours = a day');\n    assert.equal(moment.duration({hours: 35}).humanize(),    'a day',         '35 hours = a day');\n    assert.equal(moment.duration({hours: 36}).humanize(),    '2 days',        '36 hours = 2 days');\n    assert.equal(moment.duration({days: 1}).humanize(),      'a day',         '1 day = a day');\n    assert.equal(moment.duration({days: 5}).humanize(),      '5 days',        '5 days = 5 days');\n    assert.equal(moment.duration({weeks: 1}).humanize(),     '7 days',        '1 week = 7 days');\n    assert.equal(moment.duration({days: 25}).humanize(),     '25 days',       '25 days = 25 days');\n    assert.equal(moment.duration({days: 26}).humanize(),     'a month',       '26 days = a month');\n    assert.equal(moment.duration({days: 30}).humanize(),     'a month',       '30 days = a month');\n    assert.equal(moment.duration({days: 45}).humanize(),     'a month',       '45 days = a month');\n    assert.equal(moment.duration({days: 46}).humanize(),     '2 months',      '46 days = 2 months');\n    assert.equal(moment.duration({days: 74}).humanize(),     '2 months',      '74 days = 2 months');\n    assert.equal(moment.duration({days: 77}).humanize(),     '3 months',      '77 days = 3 months');\n    assert.equal(moment.duration({months: 1}).humanize(),    'a month',       '1 month = a month');\n    assert.equal(moment.duration({months: 5}).humanize(),    '5 months',      '5 months = 5 months');\n    assert.equal(moment.duration({days: 344}).humanize(),    'a year',        '344 days = a year');\n    assert.equal(moment.duration({days: 345}).humanize(),    'a year',        '345 days = a year');\n    assert.equal(moment.duration({days: 547}).humanize(),    'a year',        '547 days = a year');\n    assert.equal(moment.duration({days: 548}).humanize(),    '2 years',       '548 days = 2 years');\n    assert.equal(moment.duration({years: 1}).humanize(),     'a year',        '1 year = a year');\n    assert.equal(moment.duration({years: 5}).humanize(),     '5 years',       '5 years = 5 years');\n    assert.equal(moment.duration(7200000).humanize(),        '2 hours',       '7200000 = 2 minutes');\n});\n\ntest('humanize duration with suffix', function (assert) {\n    moment.locale('en');\n    assert.equal(moment.duration({seconds:  44}).humanize(true),  'in a few seconds', '44 seconds = a few seconds');\n    assert.equal(moment.duration({seconds: -44}).humanize(true),  'a few seconds ago', '44 seconds = a few seconds');\n});\n\ntest('bubble value up', function (assert) {\n    assert.equal(moment.duration({milliseconds: 61001}).milliseconds(), 1, '61001 milliseconds has 1 millisecond left over');\n    assert.equal(moment.duration({milliseconds: 61001}).seconds(),      1, '61001 milliseconds has 1 second left over');\n    assert.equal(moment.duration({milliseconds: 61001}).minutes(),      1, '61001 milliseconds has 1 minute left over');\n\n    assert.equal(moment.duration({minutes: 350}).minutes(), 50, '350 minutes has 50 minutes left over');\n    assert.equal(moment.duration({minutes: 350}).hours(),   5,  '350 minutes has 5 hours left over');\n});\n\ntest('clipping', function (assert) {\n    assert.equal(moment.duration({months: 11}).months(), 11, '11 months is 11 months');\n    assert.equal(moment.duration({months: 11}).years(),  0,  '11 months makes no year');\n    assert.equal(moment.duration({months: 12}).months(), 0,  '12 months is 0 months left over');\n    assert.equal(moment.duration({months: 12}).years(),  1,  '12 months makes 1 year');\n    assert.equal(moment.duration({months: 13}).months(), 1,  '13 months is 1 month left over');\n    assert.equal(moment.duration({months: 13}).years(),  1,  '13 months makes 1 year');\n\n    assert.equal(moment.duration({days: 30}).days(),   30, '30 days is 30 days');\n    assert.equal(moment.duration({days: 30}).months(), 0,  '30 days makes no month');\n    assert.equal(moment.duration({days: 31}).days(),   0,  '31 days is 0 days left over');\n    assert.equal(moment.duration({days: 31}).months(), 1,  '31 days is a month');\n    assert.equal(moment.duration({days: 32}).days(),   1,  '32 days is 1 day left over');\n    assert.equal(moment.duration({days: 32}).months(), 1,  '32 days is a month');\n\n    assert.equal(moment.duration({hours: 23}).hours(), 23, '23 hours is 23 hours');\n    assert.equal(moment.duration({hours: 23}).days(),  0,  '23 hours makes no day');\n    assert.equal(moment.duration({hours: 24}).hours(), 0,  '24 hours is 0 hours left over');\n    assert.equal(moment.duration({hours: 24}).days(),  1,  '24 hours makes 1 day');\n    assert.equal(moment.duration({hours: 25}).hours(), 1,  '25 hours is 1 hour left over');\n    assert.equal(moment.duration({hours: 25}).days(),  1,  '25 hours makes 1 day');\n});\n\ntest('bubbling consistency', function (assert) {\n    var days = 0, months = 0, newDays, newMonths, totalDays, d;\n    for (totalDays = 1; totalDays <= 500; ++totalDays) {\n        d = moment.duration(totalDays, 'days');\n        newDays = d.days();\n        newMonths = d.months() + d.years() * 12;\n        assert.ok(\n                (months === newMonths && days + 1 === newDays) ||\n                (months + 1 === newMonths && newDays === 0),\n                'consistent total days ' + totalDays +\n                ' was ' + months + ' ' + days +\n                ' now ' + newMonths + ' ' + newDays);\n        days = newDays;\n        months = newMonths;\n    }\n});\n\ntest('effective equivalency', function (assert) {\n    assert.deepEqual(moment.duration({seconds: 1})._data,  moment.duration({milliseconds: 1000})._data, '1 second is the same as 1000 milliseconds');\n    assert.deepEqual(moment.duration({seconds: 60})._data, moment.duration({minutes: 1})._data,         '1 minute is the same as 60 seconds');\n    assert.deepEqual(moment.duration({minutes: 60})._data, moment.duration({hours: 1})._data,           '1 hour is the same as 60 minutes');\n    assert.deepEqual(moment.duration({hours: 24})._data,   moment.duration({days: 1})._data,            '1 day is the same as 24 hours');\n    assert.deepEqual(moment.duration({days: 7})._data,     moment.duration({weeks: 1})._data,           '1 week is the same as 7 days');\n    assert.deepEqual(moment.duration({days: 31})._data,    moment.duration({months: 1})._data,          '1 month is the same as 30 days');\n    assert.deepEqual(moment.duration({months: 12})._data,  moment.duration({years: 1})._data,           '1 years is the same as 12 months');\n});\n\ntest('asGetters', function (assert) {\n    // 400 years have exactly 146097 days\n\n    // years\n    assert.equal(moment.duration(1, 'year').asYears(),            1,           '1 year as years');\n    assert.equal(moment.duration(1, 'year').asMonths(),           12,          '1 year as months');\n    assert.equal(moment.duration(400, 'year').asMonths(),         4800,        '400 years as months');\n    assert.equal(moment.duration(1, 'year').asWeeks().toFixed(3), 52.143,      '1 year as weeks');\n    assert.equal(moment.duration(1, 'year').asDays(),             365,         '1 year as days');\n    assert.equal(moment.duration(2, 'year').asDays(),             730,         '2 years as days');\n    assert.equal(moment.duration(3, 'year').asDays(),             1096,        '3 years as days');\n    assert.equal(moment.duration(4, 'year').asDays(),             1461,        '4 years as days');\n    assert.equal(moment.duration(400, 'year').asDays(),           146097,      '400 years as days');\n    assert.equal(moment.duration(1, 'year').asHours(),            8760,        '1 year as hours');\n    assert.equal(moment.duration(1, 'year').asMinutes(),          525600,      '1 year as minutes');\n    assert.equal(moment.duration(1, 'year').asSeconds(),          31536000,    '1 year as seconds');\n    assert.equal(moment.duration(1, 'year').asMilliseconds(),     31536000000, '1 year as milliseconds');\n\n    // months\n    assert.equal(moment.duration(1, 'month').asYears().toFixed(4), 0.0833,     '1 month as years');\n    assert.equal(moment.duration(1, 'month').asMonths(),           1,          '1 month as months');\n    assert.equal(moment.duration(1, 'month').asWeeks().toFixed(3), 4.286,      '1 month as weeks');\n    assert.equal(moment.duration(1, 'month').asDays(),             30,         '1 month as days');\n    assert.equal(moment.duration(2, 'month').asDays(),             61,         '2 months as days');\n    assert.equal(moment.duration(3, 'month').asDays(),             91,         '3 months as days');\n    assert.equal(moment.duration(4, 'month').asDays(),             122,        '4 months as days');\n    assert.equal(moment.duration(5, 'month').asDays(),             152,        '5 months as days');\n    assert.equal(moment.duration(6, 'month').asDays(),             183,        '6 months as days');\n    assert.equal(moment.duration(7, 'month').asDays(),             213,        '7 months as days');\n    assert.equal(moment.duration(8, 'month').asDays(),             243,        '8 months as days');\n    assert.equal(moment.duration(9, 'month').asDays(),             274,        '9 months as days');\n    assert.equal(moment.duration(10, 'month').asDays(),            304,        '10 months as days');\n    assert.equal(moment.duration(11, 'month').asDays(),            335,        '11 months as days');\n    assert.equal(moment.duration(12, 'month').asDays(),            365,        '12 months as days');\n    assert.equal(moment.duration(24, 'month').asDays(),            730,        '24 months as days');\n    assert.equal(moment.duration(36, 'month').asDays(),            1096,       '36 months as days');\n    assert.equal(moment.duration(48, 'month').asDays(),            1461,       '48 months as days');\n    assert.equal(moment.duration(4800, 'month').asDays(),          146097,     '4800 months as days');\n    assert.equal(moment.duration(1, 'month').asHours(),            720,        '1 month as hours');\n    assert.equal(moment.duration(1, 'month').asMinutes(),          43200,      '1 month as minutes');\n    assert.equal(moment.duration(1, 'month').asSeconds(),          2592000,    '1 month as seconds');\n    assert.equal(moment.duration(1, 'month').asMilliseconds(),     2592000000, '1 month as milliseconds');\n\n    // weeks\n    assert.equal(moment.duration(1, 'week').asYears().toFixed(4),  0.0192,    '1 week as years');\n    assert.equal(moment.duration(1, 'week').asMonths().toFixed(3), 0.230,     '1 week as months');\n    assert.equal(moment.duration(1, 'week').asWeeks(),             1,         '1 week as weeks');\n    assert.equal(moment.duration(1, 'week').asDays(),              7,         '1 week as days');\n    assert.equal(moment.duration(1, 'week').asHours(),             168,       '1 week as hours');\n    assert.equal(moment.duration(1, 'week').asMinutes(),           10080,     '1 week as minutes');\n    assert.equal(moment.duration(1, 'week').asSeconds(),           604800,    '1 week as seconds');\n    assert.equal(moment.duration(1, 'week').asMilliseconds(),      604800000, '1 week as milliseconds');\n\n    // days\n    assert.equal(moment.duration(1, 'day').asYears().toFixed(4),  0.0027,   '1 day as years');\n    assert.equal(moment.duration(1, 'day').asMonths().toFixed(3), 0.033,    '1 day as months');\n    assert.equal(moment.duration(1, 'day').asWeeks().toFixed(3),  0.143,    '1 day as weeks');\n    assert.equal(moment.duration(1, 'day').asDays(),              1,        '1 day as days');\n    assert.equal(moment.duration(1, 'day').asHours(),             24,       '1 day as hours');\n    assert.equal(moment.duration(1, 'day').asMinutes(),           1440,     '1 day as minutes');\n    assert.equal(moment.duration(1, 'day').asSeconds(),           86400,    '1 day as seconds');\n    assert.equal(moment.duration(1, 'day').asMilliseconds(),      86400000, '1 day as milliseconds');\n\n    // hours\n    assert.equal(moment.duration(1, 'hour').asYears().toFixed(6),  0.000114, '1 hour as years');\n    assert.equal(moment.duration(1, 'hour').asMonths().toFixed(5), 0.00137,  '1 hour as months');\n    assert.equal(moment.duration(1, 'hour').asWeeks().toFixed(5),  0.00595,  '1 hour as weeks');\n    assert.equal(moment.duration(1, 'hour').asDays().toFixed(4),   0.0417,   '1 hour as days');\n    assert.equal(moment.duration(1, 'hour').asHours(),             1,        '1 hour as hours');\n    assert.equal(moment.duration(1, 'hour').asMinutes(),           60,       '1 hour as minutes');\n    assert.equal(moment.duration(1, 'hour').asSeconds(),           3600,     '1 hour as seconds');\n    assert.equal(moment.duration(1, 'hour').asMilliseconds(),      3600000,  '1 hour as milliseconds');\n\n    // minutes\n    assert.equal(moment.duration(1, 'minute').asYears().toFixed(8),  0.00000190, '1 minute as years');\n    assert.equal(moment.duration(1, 'minute').asMonths().toFixed(7), 0.0000228,  '1 minute as months');\n    assert.equal(moment.duration(1, 'minute').asWeeks().toFixed(7),  0.0000992,  '1 minute as weeks');\n    assert.equal(moment.duration(1, 'minute').asDays().toFixed(6),   0.000694,   '1 minute as days');\n    assert.equal(moment.duration(1, 'minute').asHours().toFixed(4),  0.0167,     '1 minute as hours');\n    assert.equal(moment.duration(1, 'minute').asMinutes(),           1,          '1 minute as minutes');\n    assert.equal(moment.duration(1, 'minute').asSeconds(),           60,         '1 minute as seconds');\n    assert.equal(moment.duration(1, 'minute').asMilliseconds(),      60000,      '1 minute as milliseconds');\n\n    // seconds\n    assert.equal(moment.duration(1, 'second').asYears().toFixed(10),  0.0000000317, '1 second as years');\n    assert.equal(moment.duration(1, 'second').asMonths().toFixed(9),  0.000000380,  '1 second as months');\n    assert.equal(moment.duration(1, 'second').asWeeks().toFixed(8),   0.00000165,   '1 second as weeks');\n    assert.equal(moment.duration(1, 'second').asDays().toFixed(7),    0.0000116,    '1 second as days');\n    assert.equal(moment.duration(1, 'second').asHours().toFixed(6),   0.000278,     '1 second as hours');\n    assert.equal(moment.duration(1, 'second').asMinutes().toFixed(4), 0.0167,       '1 second as minutes');\n    assert.equal(moment.duration(1, 'second').asSeconds(),            1,            '1 second as seconds');\n    assert.equal(moment.duration(1, 'second').asMilliseconds(),       1000,         '1 second as milliseconds');\n\n    // milliseconds\n    assert.equal(moment.duration(1, 'millisecond').asYears().toFixed(13),  0.0000000000317, '1 millisecond as years');\n    assert.equal(moment.duration(1, 'millisecond').asMonths().toFixed(12), 0.000000000380,  '1 millisecond as months');\n    assert.equal(moment.duration(1, 'millisecond').asWeeks().toFixed(11),  0.00000000165,   '1 millisecond as weeks');\n    assert.equal(moment.duration(1, 'millisecond').asDays().toFixed(10),   0.0000000116,    '1 millisecond as days');\n    assert.equal(moment.duration(1, 'millisecond').asHours().toFixed(9),   0.000000278,     '1 millisecond as hours');\n    assert.equal(moment.duration(1, 'millisecond').asMinutes().toFixed(7), 0.0000167,       '1 millisecond as minutes');\n    assert.equal(moment.duration(1, 'millisecond').asSeconds(),            0.001,           '1 millisecond as seconds');\n    assert.equal(moment.duration(1, 'millisecond').asMilliseconds(),       1,               '1 millisecond as milliseconds');\n});\n\ntest('as getters for small units', function (assert) {\n    var dS = moment.duration(1, 'milliseconds'),\n        ds = moment.duration(3, 'seconds'),\n        dm = moment.duration(13, 'minutes');\n\n    // Tests for issue #1867.\n    // Floating point errors for small duration units were introduced in version 2.8.0.\n    assert.equal(dS.as('milliseconds'), 1, 'as(\"milliseconds\")');\n    assert.equal(dS.asMilliseconds(),   1, 'asMilliseconds()');\n    assert.equal(ds.as('seconds'),      3, 'as(\"seconds\")');\n    assert.equal(ds.asSeconds(),        3, 'asSeconds()');\n    assert.equal(dm.as('minutes'),      13, 'as(\"minutes\")');\n    assert.equal(dm.asMinutes(),        13, 'asMinutes()');\n});\n\ntest('minutes getter for floating point hours', function (assert) {\n    // Tests for issue #2978.\n    // For certain floating point hours, .minutes() getter produced incorrect values due to the rounding errors\n    assert.equal(moment.duration(2.3, 'h').minutes(), 18, 'minutes()');\n    assert.equal(moment.duration(4.1, 'h').minutes(), 6, 'minutes()');\n});\n\ntest('isDuration', function (assert) {\n    assert.ok(moment.isDuration(moment.duration(12345678)), 'correctly says true');\n    assert.ok(!moment.isDuration(moment()), 'moment object is not a duration');\n    assert.ok(!moment.isDuration({milliseconds: 1}), 'plain object is not a duration');\n});\n\ntest('add', function (assert) {\n    var d = moment.duration({months: 4, weeks: 3, days: 2});\n    // for some reason, d._data._months does not get updated; use d._months instead.\n    assert.equal(d.add(1, 'month')._months, 5, 'Add months');\n    assert.equal(d.add(5, 'days')._days, 28, 'Add days');\n    assert.equal(d.add(10000)._milliseconds, 10000, 'Add milliseconds');\n    assert.equal(d.add({h: 23, m: 59})._milliseconds, 23 * 60 * 60 * 1000 + 59 * 60 * 1000 + 10000, 'Add hour:minute');\n});\n\ntest('add and bubble', function (assert) {\n    var d;\n\n    assert.equal(moment.duration(1, 'second').add(1000, 'milliseconds').seconds(), 2, 'Adding milliseconds should bubble up to seconds');\n    assert.equal(moment.duration(1, 'minute').add(60, 'second').minutes(), 2, 'Adding seconds should bubble up to minutes');\n    assert.equal(moment.duration(1, 'hour').add(60, 'minutes').hours(), 2, 'Adding minutes should bubble up to hours');\n    assert.equal(moment.duration(1, 'day').add(24, 'hours').days(), 2, 'Adding hours should bubble up to days');\n\n    d = moment.duration(-1, 'day').add(1, 'hour');\n    assert.equal(d.hours(), -23, '-1 day + 1 hour == -23 hour (component)');\n    assert.equal(d.asHours(), -23, '-1 day + 1 hour == -23 hours');\n\n    d = moment.duration(-1, 'year').add(1, 'day');\n    assert.equal(d.days(), -30, '- 1 year + 1 day == -30 days (component)');\n    assert.equal(d.months(), -11, '- 1 year + 1 day == -11 months (component)');\n    assert.equal(d.years(), 0, '- 1 year + 1 day == 0 years (component)');\n    assert.equal(d.asDays(), -364, '- 1 year + 1 day == -364 days');\n\n    d = moment.duration(-1, 'year').add(1, 'hour');\n    assert.equal(d.hours(), -23, '- 1 year + 1 hour == -23 hours (component)');\n    assert.equal(d.days(), -30, '- 1 year + 1 hour == -30 days (component)');\n    assert.equal(d.months(), -11, '- 1 year + 1 hour == -11 months (component)');\n    assert.equal(d.years(), 0, '- 1 year + 1 hour == 0 years (component)');\n});\n\ntest('subtract and bubble', function (assert) {\n    var d;\n\n    assert.equal(moment.duration(2, 'second').subtract(1000, 'milliseconds').seconds(), 1, 'Subtracting milliseconds should bubble up to seconds');\n    assert.equal(moment.duration(2, 'minute').subtract(60, 'second').minutes(), 1, 'Subtracting seconds should bubble up to minutes');\n    assert.equal(moment.duration(2, 'hour').subtract(60, 'minutes').hours(), 1, 'Subtracting minutes should bubble up to hours');\n    assert.equal(moment.duration(2, 'day').subtract(24, 'hours').days(), 1, 'Subtracting hours should bubble up to days');\n\n    d = moment.duration(1, 'day').subtract(1, 'hour');\n    assert.equal(d.hours(), 23, '1 day - 1 hour == 23 hour (component)');\n    assert.equal(d.asHours(), 23, '1 day - 1 hour == 23 hours');\n\n    d = moment.duration(1, 'year').subtract(1, 'day');\n    assert.equal(d.days(), 30, '1 year - 1 day == 30 days (component)');\n    assert.equal(d.months(), 11, '1 year - 1 day == 11 months (component)');\n    assert.equal(d.years(), 0, '1 year - 1 day == 0 years (component)');\n    assert.equal(d.asDays(), 364, '1 year - 1 day == 364 days');\n\n    d = moment.duration(1, 'year').subtract(1, 'hour');\n    assert.equal(d.hours(), 23, '1 year - 1 hour == 23 hours (component)');\n    assert.equal(d.days(), 30, '1 year - 1 hour == 30 days (component)');\n    assert.equal(d.months(), 11, '1 year - 1 hour == 11 months (component)');\n    assert.equal(d.years(), 0, '1 year - 1 hour == 0 years (component)');\n});\n\ntest('subtract', function (assert) {\n    var d = moment.duration({months: 2, weeks: 2, days: 0, hours: 5});\n    // for some reason, d._data._months does not get updated; use d._months instead.\n    assert.equal(d.subtract(1, 'months')._months, 1, 'Subtract months');\n    assert.equal(d.subtract(14, 'days')._days, 0, 'Subtract days');\n    assert.equal(d.subtract(10000)._milliseconds, 5 * 60 * 60 * 1000 - 10000, 'Subtract milliseconds');\n    assert.equal(d.subtract({h: 1, m: 59})._milliseconds, 3 * 60 * 60 * 1000 + 1 * 60 * 1000 - 10000, 'Subtract hour:minute');\n});\n\ntest('JSON.stringify duration', function (assert) {\n    var d = moment.duration(1024, 'h');\n\n    assert.equal(JSON.stringify(d), '\"' + d.toISOString() + '\"', 'JSON.stringify on duration should return ISO string');\n});\n\ntest('duration plugins', function (assert) {\n    var durationObject = moment.duration();\n    moment.duration.fn.foo = function (arg) {\n        assert.equal(this, durationObject);\n        assert.equal(arg, 5);\n    };\n    durationObject.foo(5);\n});\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/test/moment/duration_from_moments.js",
    "content": "import { module, test } from '../qunit';\nimport moment from '../../moment';\n\nmodule('duration from moments');\n\ntest('pure year diff', function (assert) {\n    var m1 = moment('2012-01-01T00:00:00.000Z'),\n        m2 = moment('2013-01-01T00:00:00.000Z');\n\n    assert.equal(moment.duration({from: m1, to: m2}).as('years'), 1, 'year moment difference');\n    assert.equal(moment.duration({from: m2, to: m1}).as('years'), -1, 'negative year moment difference');\n});\n\ntest('month and day diff', function (assert) {\n    var m1 = moment('2012-01-15T00:00:00.000Z'),\n        m2 = moment('2012-02-17T00:00:00.000Z'),\n        d = moment.duration({from: m1, to: m2});\n\n    assert.equal(d.get('days'), 2);\n    assert.equal(d.get('months'), 1);\n});\n\ntest('day diff, separate months', function (assert) {\n    var m1 = moment('2012-01-15T00:00:00.000Z'),\n        m2 = moment('2012-02-13T00:00:00.000Z'),\n        d = moment.duration({from: m1, to: m2});\n\n    assert.equal(d.as('days'), 29);\n});\n\ntest('hour diff', function (assert) {\n    var m1 = moment('2012-01-15T17:00:00.000Z'),\n        m2 = moment('2012-01-16T03:00:00.000Z'),\n        d = moment.duration({from: m1, to: m2});\n\n    assert.equal(d.as('hours'), 10);\n});\n\ntest('minute diff', function (assert) {\n    var m1 = moment('2012-01-15T17:45:00.000Z'),\n        m2 = moment('2012-01-16T03:15:00.000Z'),\n        d = moment.duration({from: m1, to: m2});\n\n    assert.equal(d.as('hours'), 9.5);\n});\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/test/moment/duration_invalid.js",
    "content": "import { module, test } from '../qunit';\nimport moment from '../../moment';\n\nmodule('invalid');\n\ntest('invalid duration', function (assert) {\n    var m = moment.duration.invalid(); // should be invalid\n    assert.equal(m.isValid(), false);\n    assert.ok(isNaN(m.valueOf()));\n});\n\ntest('valid duration', function (assert) {\n    var m = moment.duration({d: null}); // should be valid, for now\n    assert.equal(m.isValid(), true);\n    assert.equal(m.valueOf(), 0);\n});\n\ntest('invalid duration - only smallest unit can have decimal', function (assert) {\n    var m = moment.duration({'days': 3.5, 'hours': 1.1}); // should be invalid\n    assert.equal(m.isValid(), false);\n    assert.ok(isNaN(m.valueOf())); // .valueOf() returns NaN for invalid durations\n});\n\ntest('valid duration - smallest unit can have decimal', function (assert) {\n    var m = moment.duration({'days': 3, 'hours': 1.1}); // should be valid\n    assert.equal(m.isValid(), true);\n    assert.equal(m.asHours(), 73.1);\n});\n\ntest('invalid duration with two arguments', function (assert) {\n    var m = moment.duration(NaN, 'days');\n    assert.equal(m.isValid(), false);\n    assert.ok(isNaN(m.valueOf()));\n});\n\ntest('invalid duration operations', function (assert) {\n    var invalids = [\n            moment.duration(NaN),\n            moment.duration(NaN, 'days'),\n            moment.duration.invalid()\n        ],\n        i,\n        invalid,\n        valid = moment.duration();\n\n    for (i = 0; i < invalids.length; ++i) {\n        invalid = invalids[i];\n\n        assert.ok(!invalid.add(5, 'hours').isValid(), 'invalid.add is invalid; i=' + i);\n        assert.ok(!invalid.subtract(30, 'days').isValid(), 'invalid.subtract is invalid; i=' + i);\n        assert.ok(!invalid.abs().isValid(), 'invalid.abs is invalid; i=' + i);\n        assert.ok(isNaN(invalid.as('years')), 'invalid.as is NaN; i=' + i);\n        assert.ok(isNaN(invalid.asMilliseconds()), 'invalid.asMilliseconds is NaN; i=' + i);\n        assert.ok(isNaN(invalid.asSeconds()), 'invalid.asSeconds is NaN; i=' + i);\n        assert.ok(isNaN(invalid.asMinutes()), 'invalid.asMinutes is NaN; i=' + i);\n        assert.ok(isNaN(invalid.asHours()), 'invalid.asHours is NaN; i=' + i);\n        assert.ok(isNaN(invalid.asDays()), 'invalid.asDays is NaN; i=' + i);\n        assert.ok(isNaN(invalid.asWeeks()), 'invalid.asWeeks is NaN; i=' + i);\n        assert.ok(isNaN(invalid.asMonths()), 'invalid.asMonths is NaN; i=' + i);\n        assert.ok(isNaN(invalid.asYears()), 'invalid.asYears is NaN; i=' + i);\n        assert.ok(isNaN(invalid.valueOf()), 'invalid.valueOf is NaN; i=' + i);\n        assert.ok(isNaN(invalid.get('hours')), 'invalid.get is NaN; i=' + i);\n\n        assert.ok(isNaN(invalid.milliseconds()), 'invalid.milliseconds is NaN; i=' + i);\n        assert.ok(isNaN(invalid.seconds()), 'invalid.seconds is NaN; i=' + i);\n        assert.ok(isNaN(invalid.minutes()), 'invalid.minutes is NaN; i=' + i);\n        assert.ok(isNaN(invalid.hours()), 'invalid.hours is NaN; i=' + i);\n        assert.ok(isNaN(invalid.days()), 'invalid.days is NaN; i=' + i);\n        assert.ok(isNaN(invalid.weeks()), 'invalid.weeks is NaN; i=' + i);\n        assert.ok(isNaN(invalid.months()), 'invalid.months is NaN; i=' + i);\n        assert.ok(isNaN(invalid.years()), 'invalid.years is NaN; i=' + i);\n\n        assert.equal(invalid.humanize(),\n                     invalid.localeData().invalidDate(),\n                     'invalid.humanize is localized invalid duration string; i=' + i);\n        assert.equal(invalid.toISOString(),\n                     invalid.localeData().invalidDate(),\n                     'invalid.toISOString is localized invalid duration string; i=' + i);\n        assert.equal(invalid.toString(),\n                     invalid.localeData().invalidDate(),\n                     'invalid.toString is localized invalid duration string; i=' + i);\n        assert.equal(invalid.toJSON(), invalid.localeData().invalidDate(), 'invalid.toJSON is null; i=' + i);\n        assert.equal(invalid.locale(), 'en', 'invalid.locale; i=' + i);\n        assert.equal(invalid.localeData()._abbr, 'en', 'invalid.localeData()._abbr; i=' + i);\n    }\n});\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/test/moment/format.js",
    "content": "import { module, test } from '../qunit';\nimport each from '../helpers/each';\nimport moment from '../../moment';\n\nmodule('format');\n\ntest('format YY', function (assert) {\n    var b = moment(new Date(2009, 1, 14, 15, 25, 50, 125));\n    assert.equal(b.format('YY'), '09', 'YY ---> 09');\n});\n\ntest('format escape brackets', function (assert) {\n    moment.locale('en');\n\n    var b = moment(new Date(2009, 1, 14, 15, 25, 50, 125));\n    assert.equal(b.format('[day]'), 'day', 'Single bracket');\n    assert.equal(b.format('[day] YY [YY]'), 'day 09 YY', 'Double bracket');\n    assert.equal(b.format('[YY'), '[09', 'Un-ended bracket');\n    assert.equal(b.format('[[YY]]'), '[YY]', 'Double nested brackets');\n    assert.equal(b.format('[[]'), '[', 'Escape open bracket');\n    assert.equal(b.format('[Last]'), 'Last', 'localized tokens');\n    assert.equal(b.format('[L] L'), 'L 02/14/2009', 'localized tokens with escaped localized tokens');\n    assert.equal(b.format('[L LL LLL LLLL aLa]'), 'L LL LLL LLLL aLa', 'localized tokens with escaped localized tokens');\n    assert.equal(b.format('[LLL] LLL'), 'LLL February 14, 2009 3:25 PM', 'localized tokens with escaped localized tokens (recursion)');\n    assert.equal(b.format('YYYY[\\n]DD[\\n]'), '2009\\n14\\n', 'Newlines');\n});\n\ntest('handle negative years', function (assert) {\n    moment.locale('en');\n    assert.equal(moment.utc().year(-1).format('YY'), '-01', 'YY with negative year');\n    assert.equal(moment.utc().year(-1).format('YYYY'), '-0001', 'YYYY with negative year');\n    assert.equal(moment.utc().year(-12).format('YY'), '-12', 'YY with negative year');\n    assert.equal(moment.utc().year(-12).format('YYYY'), '-0012', 'YYYY with negative year');\n    assert.equal(moment.utc().year(-123).format('YY'), '-23', 'YY with negative year');\n    assert.equal(moment.utc().year(-123).format('YYYY'), '-0123', 'YYYY with negative year');\n    assert.equal(moment.utc().year(-1234).format('YY'), '-34', 'YY with negative year');\n    assert.equal(moment.utc().year(-1234).format('YYYY'), '-1234', 'YYYY with negative year');\n    assert.equal(moment.utc().year(-12345).format('YY'), '-45', 'YY with negative year');\n    assert.equal(moment.utc().year(-12345).format('YYYY'), '-12345', 'YYYY with negative year');\n});\n\ntest('format milliseconds', function (assert) {\n    var b = moment(new Date(2009, 1, 14, 15, 25, 50, 123));\n    assert.equal(b.format('S'), '1', 'Deciseconds');\n    assert.equal(b.format('SS'), '12', 'Centiseconds');\n    assert.equal(b.format('SSS'), '123', 'Milliseconds');\n    b.milliseconds(789);\n    assert.equal(b.format('S'), '7', 'Deciseconds');\n    assert.equal(b.format('SS'), '78', 'Centiseconds');\n    assert.equal(b.format('SSS'), '789', 'Milliseconds');\n});\n\ntest('format timezone', function (assert) {\n    var b = moment(new Date(2010, 1, 14, 15, 25, 50, 125));\n    assert.ok(b.format('Z').match(/^[\\+\\-]\\d\\d:\\d\\d$/), b.format('Z') + ' should be something like \\'+07:30\\'');\n    assert.ok(b.format('ZZ').match(/^[\\+\\-]\\d{4}$/), b.format('ZZ') + ' should be something like \\'+0700\\'');\n});\n\ntest('format multiple with utc offset', function (assert) {\n    var b = moment('2012-10-08 -1200', ['YYYY-MM-DD HH:mm ZZ', 'YYYY-MM-DD ZZ', 'YYYY-MM-DD']);\n    assert.equal(b.format('YYYY-MM'), '2012-10', 'Parsing multiple formats should not crash with different sized formats');\n});\n\ntest('isDST', function (assert) {\n    var janOffset = new Date(2011, 0, 1).getTimezoneOffset(),\n        julOffset = new Date(2011, 6, 1).getTimezoneOffset(),\n        janIsDst = janOffset < julOffset,\n        julIsDst = julOffset < janOffset,\n        jan1 = moment([2011]),\n        jul1 = moment([2011, 6]);\n\n    if (janIsDst && julIsDst) {\n        assert.ok(0, 'January and July cannot both be in DST');\n        assert.ok(0, 'January and July cannot both be in DST');\n    } else if (janIsDst) {\n        assert.ok(jan1.isDST(), 'January 1 is DST');\n        assert.ok(!jul1.isDST(), 'July 1 is not DST');\n    } else if (julIsDst) {\n        assert.ok(!jan1.isDST(), 'January 1 is not DST');\n        assert.ok(jul1.isDST(), 'July 1 is DST');\n    } else {\n        assert.ok(!jan1.isDST(), 'January 1 is not DST');\n        assert.ok(!jul1.isDST(), 'July 1 is not DST');\n    }\n});\n\ntest('unix timestamp', function (assert) {\n    var m = moment('1234567890.123', 'X');\n    assert.equal(m.format('X'), '1234567890', 'unix timestamp without milliseconds');\n    assert.equal(m.format('X.S'), '1234567890.1', 'unix timestamp with deciseconds');\n    assert.equal(m.format('X.SS'), '1234567890.12', 'unix timestamp with centiseconds');\n    assert.equal(m.format('X.SSS'), '1234567890.123', 'unix timestamp with milliseconds');\n\n    m = moment(1234567890.123, 'X');\n    assert.equal(m.format('X'), '1234567890', 'unix timestamp as integer');\n});\n\ntest('unix offset milliseconds', function (assert) {\n    var m = moment('1234567890123', 'x');\n    assert.equal(m.format('x'), '1234567890123', 'unix offset in milliseconds');\n\n    m = moment(1234567890123, 'x');\n    assert.equal(m.format('x'), '1234567890123', 'unix offset in milliseconds as integer');\n});\n\ntest('utcOffset sanity checks', function (assert) {\n    assert.equal(moment().utcOffset() % 15, 0,\n            'utc offset should be a multiple of 15 (was ' + moment().utcOffset() + ')');\n\n    assert.equal(moment().utcOffset(), -(new Date()).getTimezoneOffset(),\n        'utcOffset should return the opposite of getTimezoneOffset');\n});\n\ntest('default format', function (assert) {\n    var isoRegex = /\\d{4}.\\d\\d.\\d\\dT\\d\\d.\\d\\d.\\d\\d[\\+\\-]\\d\\d:\\d\\d/;\n    assert.ok(isoRegex.exec(moment().format()), 'default format (' + moment().format() + ') should match ISO');\n});\n\ntest('default UTC format', function (assert) {\n    var isoRegex = /\\d{4}.\\d\\d.\\d\\dT\\d\\d.\\d\\d.\\d\\dZ/;\n    assert.ok(isoRegex.exec(moment.utc().format()), 'default UTC format (' + moment.utc().format() + ') should match ISO');\n});\n\ntest('toJSON', function (assert) {\n    var supportsJson = typeof JSON !== 'undefined' && JSON.stringify && JSON.stringify.call,\n        date = moment('2012-10-09T21:30:40.678+0100');\n\n    assert.equal(date.toJSON(), '2012-10-09T20:30:40.678Z', 'should output ISO8601 on moment.fn.toJSON');\n\n    if (supportsJson) {\n        assert.equal(JSON.stringify({\n            date : date\n        }), '{\"date\":\"2012-10-09T20:30:40.678Z\"}', 'should output ISO8601 on JSON.stringify');\n    }\n});\n\ntest('toISOString', function (assert) {\n    var date = moment.utc('2012-10-09T20:30:40.678');\n\n    assert.equal(date.toISOString(), '2012-10-09T20:30:40.678Z', 'should output ISO8601 on moment.fn.toISOString');\n\n    // big years\n    date = moment.utc('+020123-10-09T20:30:40.678');\n    assert.equal(date.toISOString(), '+020123-10-09T20:30:40.678Z', 'ISO8601 format on big positive year');\n    // negative years\n    date = moment.utc('-000001-10-09T20:30:40.678');\n    assert.equal(date.toISOString(), '-000001-10-09T20:30:40.678Z', 'ISO8601 format on negative year');\n    // big negative years\n    date = moment.utc('-020123-10-09T20:30:40.678');\n    assert.equal(date.toISOString(), '-020123-10-09T20:30:40.678Z', 'ISO8601 format on big negative year');\n\n    //invalid dates\n    date = moment.utc('2017-12-32');\n    assert.equal(date.toISOString(), null, 'An invalid date to iso string is null');\n});\n\n// See https://nodejs.org/dist/latest/docs/api/util.html#util_custom_inspect_function_on_objects\ntest('inspect', function (assert) {\n    function roundtrip(m) {\n        /*jshint evil:true */\n        return (new Function('moment', 'return ' + m.inspect()))(moment);\n    }\n    function testInspect(date, string) {\n        var inspected = date.inspect();\n        assert.equal(inspected, string);\n        assert.ok(date.isSame(roundtrip(date)), 'Tried to parse ' + inspected);\n    }\n\n    testInspect(\n        moment('2012-10-09T20:30:40.678'),\n        'moment(\"2012-10-09T20:30:40.678\")'\n    );\n    testInspect(\n        moment('+020123-10-09T20:30:40.678'),\n        'moment(\"+020123-10-09T20:30:40.678\")'\n    );\n    testInspect(\n        moment.utc('2012-10-09T20:30:40.678'),\n        'moment.utc(\"2012-10-09T20:30:40.678+00:00\")'\n    );\n    testInspect(\n        moment.utc('+020123-10-09T20:30:40.678'),\n        'moment.utc(\"+020123-10-09T20:30:40.678+00:00\")'\n    );\n    testInspect(\n        moment.utc('+020123-10-09T20:30:40.678+01:00'),\n        'moment.utc(\"+020123-10-09T19:30:40.678+00:00\")'\n    );\n    testInspect(\n        moment.parseZone('2016-06-11T17:30:40.678+0430'),\n        'moment.parseZone(\"2016-06-11T17:30:40.678+04:30\")'\n    );\n    testInspect(\n        moment.parseZone('+112016-06-11T17:30:40.678+0430'),\n        'moment.parseZone(\"+112016-06-11T17:30:40.678+04:30\")'\n    );\n\n    assert.equal(\n        moment(new Date('nope')).inspect(),\n        'moment.invalid(/* Invalid Date */)'\n    );\n    assert.equal(\n        moment('blah', 'YYYY').inspect(),\n        'moment.invalid(/* blah */)'\n    );\n});\n\ntest('long years', function (assert) {\n    assert.equal(moment.utc().year(2).format('YYYYYY'), '+000002', 'small year with YYYYYY');\n    assert.equal(moment.utc().year(2012).format('YYYYYY'), '+002012', 'regular year with YYYYYY');\n    assert.equal(moment.utc().year(20123).format('YYYYYY'), '+020123', 'big year with YYYYYY');\n\n    assert.equal(moment.utc().year(-1).format('YYYYYY'), '-000001', 'small negative year with YYYYYY');\n    assert.equal(moment.utc().year(-2012).format('YYYYYY'), '-002012', 'negative year with YYYYYY');\n    assert.equal(moment.utc().year(-20123).format('YYYYYY'), '-020123', 'big negative year with YYYYYY');\n});\n\ntest('toISOString() when 0 year', function (assert) {\n    // https://github.com/moment/moment/issues/3765\n    var date = moment('0000-01-01T21:00:00.000Z');\n    assert.equal(date.toISOString(), '0000-01-01T21:00:00.000Z');\n    assert.equal(date.toDate().toISOString(), '0000-01-01T21:00:00.000Z');\n});\n\ntest('iso week formats', function (assert) {\n    // https://en.wikipedia.org/wiki/ISO_week_date\n    var cases = {\n        '2005-01-02': '2004-53',\n        '2005-12-31': '2005-52',\n        '2007-01-01': '2007-01',\n        '2007-12-30': '2007-52',\n        '2007-12-31': '2008-01',\n        '2008-01-01': '2008-01',\n        '2008-12-28': '2008-52',\n        '2008-12-29': '2009-01',\n        '2008-12-30': '2009-01',\n        '2008-12-31': '2009-01',\n        '2009-01-01': '2009-01',\n        '2009-12-31': '2009-53',\n        '2010-01-01': '2009-53',\n        '2010-01-02': '2009-53',\n        '2010-01-03': '2009-53',\n        '404-12-31': '0404-53',\n        '405-12-31': '0405-52'\n    }, i, isoWeek, formatted2, formatted1;\n\n    for (i in cases) {\n        isoWeek = cases[i].split('-').pop();\n        formatted2 = moment(i, 'YYYY-MM-DD').format('WW');\n        assert.equal(isoWeek, formatted2, i + ': WW should be ' + isoWeek + ', but ' + formatted2);\n        isoWeek = isoWeek.replace(/^0+/, '');\n        formatted1 = moment(i, 'YYYY-MM-DD').format('W');\n        assert.equal(isoWeek, formatted1, i + ': W should be ' + isoWeek + ', but ' + formatted1);\n    }\n});\n\ntest('iso week year formats', function (assert) {\n    // https://en.wikipedia.org/wiki/ISO_week_date\n    var cases = {\n        '2005-01-02': '2004-53',\n        '2005-12-31': '2005-52',\n        '2007-01-01': '2007-01',\n        '2007-12-30': '2007-52',\n        '2007-12-31': '2008-01',\n        '2008-01-01': '2008-01',\n        '2008-12-28': '2008-52',\n        '2008-12-29': '2009-01',\n        '2008-12-30': '2009-01',\n        '2008-12-31': '2009-01',\n        '2009-01-01': '2009-01',\n        '2009-12-31': '2009-53',\n        '2010-01-01': '2009-53',\n        '2010-01-02': '2009-53',\n        '2010-01-03': '2009-53',\n        '404-12-31': '0404-53',\n        '405-12-31': '0405-52'\n    }, i, isoWeekYear, formatted5, formatted4, formatted2;\n\n    for (i in cases) {\n        isoWeekYear = cases[i].split('-')[0];\n        formatted5 = moment(i, 'YYYY-MM-DD').format('GGGGG');\n        assert.equal('0' + isoWeekYear, formatted5, i + ': GGGGG should be ' + isoWeekYear + ', but ' + formatted5);\n        formatted4 = moment(i, 'YYYY-MM-DD').format('GGGG');\n        assert.equal(isoWeekYear, formatted4, i + ': GGGG should be ' + isoWeekYear + ', but ' + formatted4);\n        formatted2 = moment(i, 'YYYY-MM-DD').format('GG');\n        assert.equal(isoWeekYear.slice(2, 4), formatted2, i + ': GG should be ' + isoWeekYear + ', but ' + formatted2);\n    }\n});\n\ntest('week year formats', function (assert) {\n    // https://en.wikipedia.org/wiki/ISO_week_date\n    var cases = {\n        '2005-01-02': '2004-53',\n        '2005-12-31': '2005-52',\n        '2007-01-01': '2007-01',\n        '2007-12-30': '2007-52',\n        '2007-12-31': '2008-01',\n        '2008-01-01': '2008-01',\n        '2008-12-28': '2008-52',\n        '2008-12-29': '2009-01',\n        '2008-12-30': '2009-01',\n        '2008-12-31': '2009-01',\n        '2009-01-01': '2009-01',\n        '2009-12-31': '2009-53',\n        '2010-01-01': '2009-53',\n        '2010-01-02': '2009-53',\n        '2010-01-03': '2009-53',\n        '404-12-31': '0404-53',\n        '405-12-31': '0405-52'\n    }, i, isoWeekYear, formatted5, formatted4, formatted2;\n\n    moment.defineLocale('dow:1,doy:4', {week: {dow: 1, doy: 4}});\n\n    for (i in cases) {\n        isoWeekYear = cases[i].split('-')[0];\n        formatted5 = moment(i, 'YYYY-MM-DD').format('ggggg');\n        assert.equal('0' + isoWeekYear, formatted5, i + ': ggggg should be ' + isoWeekYear + ', but ' + formatted5);\n        formatted4 = moment(i, 'YYYY-MM-DD').format('gggg');\n        assert.equal(isoWeekYear, formatted4, i + ': gggg should be ' + isoWeekYear + ', but ' + formatted4);\n        formatted2 = moment(i, 'YYYY-MM-DD').format('gg');\n        assert.equal(isoWeekYear.slice(2, 4), formatted2, i + ': gg should be ' + isoWeekYear + ', but ' + formatted2);\n    }\n    moment.defineLocale('dow:1,doy:4', null);\n});\n\ntest('iso weekday formats', function (assert) {\n    assert.equal(moment([1985, 1,  4]).format('E'), '1', 'Feb  4 1985 is Monday    -- 1st day');\n    assert.equal(moment([2029, 8, 18]).format('E'), '2', 'Sep 18 2029 is Tuesday   -- 2nd day');\n    assert.equal(moment([2013, 3, 24]).format('E'), '3', 'Apr 24 2013 is Wednesday -- 3rd day');\n    assert.equal(moment([2015, 2,  5]).format('E'), '4', 'Mar  5 2015 is Thursday  -- 4th day');\n    assert.equal(moment([1970, 0,  2]).format('E'), '5', 'Jan  2 1970 is Friday    -- 5th day');\n    assert.equal(moment([2001, 4, 12]).format('E'), '6', 'May 12 2001 is Saturday  -- 6th day');\n    assert.equal(moment([2000, 0,  2]).format('E'), '7', 'Jan  2 2000 is Sunday    -- 7th day');\n});\n\ntest('weekday formats', function (assert) {\n    moment.defineLocale('dow: 3,doy: 5', {week: {dow: 3, doy: 5}});\n    assert.equal(moment([1985, 1,  6]).format('e'), '0', 'Feb  6 1985 is Wednesday -- 0th day');\n    assert.equal(moment([2029, 8, 20]).format('e'), '1', 'Sep 20 2029 is Thursday  -- 1st day');\n    assert.equal(moment([2013, 3, 26]).format('e'), '2', 'Apr 26 2013 is Friday    -- 2nd day');\n    assert.equal(moment([2015, 2,  7]).format('e'), '3', 'Mar  7 2015 is Saturday  -- 3nd day');\n    assert.equal(moment([1970, 0,  4]).format('e'), '4', 'Jan  4 1970 is Sunday    -- 4th day');\n    assert.equal(moment([2001, 4, 14]).format('e'), '5', 'May 14 2001 is Monday    -- 5th day');\n    assert.equal(moment([2000, 0,  4]).format('e'), '6', 'Jan  4 2000 is Tuesday   -- 6th day');\n    moment.defineLocale('dow: 3,doy: 5', null);\n});\n\ntest('toString is just human readable format', function (assert) {\n    var b = moment(new Date(2009, 1, 5, 15, 25, 50, 125));\n    assert.equal(b.toString(), b.format('ddd MMM DD YYYY HH:mm:ss [GMT]ZZ'));\n});\n\ntest('toJSON skips postformat', function (assert) {\n    moment.defineLocale('postformat', {\n        postformat: function (s) {\n            s.replace(/./g, 'X');\n        }\n    });\n    assert.equal(moment.utc([2000, 0, 1]).toJSON(), '2000-01-01T00:00:00.000Z', 'toJSON doesn\\'t postformat');\n    moment.defineLocale('postformat', null);\n});\n\ntest('calendar day timezone', function (assert) {\n    moment.locale('en');\n    var zones = [60, -60, 90, -90, 360, -360, 720, -720],\n        b = moment().utc().startOf('day').subtract({m : 1}),\n        c = moment().local().startOf('day').subtract({m : 1}),\n        d = moment().local().startOf('day').subtract({d : 2}),\n        i, z, a;\n\n    for (i = 0; i < zones.length; ++i) {\n        z = zones[i];\n        a = moment().utcOffset(z).startOf('day').subtract({m: 1});\n        assert.equal(moment(a).utcOffset(z).calendar(), 'Yesterday at 11:59 PM',\n                     'Yesterday at 11:59 PM, not Today, or the wrong time, tz = ' + z);\n    }\n\n    assert.equal(moment(b).utc().calendar(), 'Yesterday at 11:59 PM', 'Yesterday at 11:59 PM, not Today, or the wrong time');\n    assert.equal(moment(c).local().calendar(), 'Yesterday at 11:59 PM', 'Yesterday at 11:59 PM, not Today, or the wrong time');\n    assert.equal(moment(c).local().calendar(d), 'Tomorrow at 11:59 PM', 'Tomorrow at 11:59 PM, not Yesterday, or the wrong time');\n});\n\ntest('calendar with custom formats', function (assert) {\n    assert.equal(moment().calendar(null, {sameDay: '[Today]'}), 'Today', 'Today');\n    assert.equal(moment().add(1, 'days').calendar(null, {nextDay: '[Tomorrow]'}), 'Tomorrow', 'Tomorrow');\n    assert.equal(moment([1985, 1, 4]).calendar(null, {sameElse: 'YYYY-MM-DD'}), '1985-02-04', 'Else');\n});\n\ntest('invalid', function (assert) {\n    assert.equal(moment.invalid().format(), 'Invalid date');\n    assert.equal(moment.invalid().format('YYYY-MM-DD'), 'Invalid date');\n});\n\ntest('quarter formats', function (assert) {\n    assert.equal(moment([1985, 1,  4]).format('Q'), '1', 'Feb  4 1985 is Q1');\n    assert.equal(moment([2029, 8, 18]).format('Q'), '3', 'Sep 18 2029 is Q3');\n    assert.equal(moment([2013, 3, 24]).format('Q'), '2', 'Apr 24 2013 is Q2');\n    assert.equal(moment([2015, 2,  5]).format('Q'), '1', 'Mar  5 2015 is Q1');\n    assert.equal(moment([1970, 0,  2]).format('Q'), '1', 'Jan  2 1970 is Q1');\n    assert.equal(moment([2001, 11, 12]).format('Q'), '4', 'Dec 12 2001 is Q4');\n    assert.equal(moment([2000, 0,  2]).format('[Q]Q-YYYY'), 'Q1-2000', 'Jan  2 2000 is Q1');\n});\n\ntest('quarter ordinal formats', function (assert) {\n    assert.equal(moment([1985, 1, 4]).format('Qo'), '1st', 'Feb 4 1985 is 1st quarter');\n    assert.equal(moment([2029, 8, 18]).format('Qo'), '3rd', 'Sep 18 2029 is 3rd quarter');\n    assert.equal(moment([2013, 3, 24]).format('Qo'), '2nd', 'Apr 24 2013 is 2nd quarter');\n    assert.equal(moment([2015, 2,  5]).format('Qo'), '1st', 'Mar  5 2015 is 1st quarter');\n    assert.equal(moment([1970, 0,  2]).format('Qo'), '1st', 'Jan  2 1970 is 1st quarter');\n    assert.equal(moment([2001, 11, 12]).format('Qo'), '4th', 'Dec 12 2001 is 4th quarter');\n    assert.equal(moment([2000, 0,  2]).format('Qo [quarter] YYYY'), '1st quarter 2000', 'Jan  2 2000 is 1st quarter');\n});\n\n// test('full expanded format is returned from abbreviated formats', function (assert) {\n//     function objectKeys(obj) {\n//         if (Object.keys) {\n//             return Object.keys(obj);\n//         } else {\n//             // IE8\n//             var res = [], i;\n//             for (i in obj) {\n//                 if (obj.hasOwnProperty(i)) {\n//                     res.push(i);\n//                 }\n//             }\n//             return res;\n//         }\n//     }\n\n//     var locales =\n//         'ar-sa ar-tn ar az be bg bn bo br bs ca cs cv cy da de-at de dv el ' +\n//         'en-au en-ca en-gb en-ie en-nz eo es et eu fa fi fo fr-ca fr-ch fr fy ' +\n//         'gd gl he hi hr hu hy-am id is it ja jv ka kk km ko lb lo lt lv me mk ml ' +\n//         'mr ms-my ms my nb ne nl nn pl pt-br pt ro ru se si sk sl sq sr-cyrl ' +\n//         'sr sv sw ta te th tl-ph tlh tr tzl tzm-latn tzm uk uz vi zh-cn zh-tw';\n\n//     each(locales.split(' '), function (locale) {\n//         var data, tokens;\n//         data = moment().locale(locale).localeData()._longDateFormat;\n//         tokens = objectKeys(data);\n//         each(tokens, function (token) {\n//             // Check each format string to make sure it does not contain any\n//             // tokens that need to be expanded.\n//             each(tokens, function (i) {\n//                 // strip escaped sequences\n//                 var format = data[i].replace(/(\\[[^\\]]*\\])/g, '');\n//                 assert.equal(false, !!~format.indexOf(token), 'locale ' + locale + ' contains ' + token + ' in ' + i);\n//             });\n//         });\n//     });\n// });\n\ntest('milliseconds', function (assert) {\n    var m = moment('123', 'SSS');\n\n    assert.equal(m.format('S'), '1');\n    assert.equal(m.format('SS'), '12');\n    assert.equal(m.format('SSS'), '123');\n    assert.equal(m.format('SSSS'), '1230');\n    assert.equal(m.format('SSSSS'), '12300');\n    assert.equal(m.format('SSSSSS'), '123000');\n    assert.equal(m.format('SSSSSSS'), '1230000');\n    assert.equal(m.format('SSSSSSSS'), '12300000');\n    assert.equal(m.format('SSSSSSSSS'), '123000000');\n});\n\ntest('hmm and hmmss', function (assert) {\n    assert.equal(moment('12:34:56', 'HH:mm:ss').format('hmm'), '1234');\n    assert.equal(moment('01:34:56', 'HH:mm:ss').format('hmm'), '134');\n    assert.equal(moment('13:34:56', 'HH:mm:ss').format('hmm'), '134');\n\n    assert.equal(moment('12:34:56', 'HH:mm:ss').format('hmmss'), '123456');\n    assert.equal(moment('01:34:56', 'HH:mm:ss').format('hmmss'), '13456');\n    assert.equal(moment('13:34:56', 'HH:mm:ss').format('hmmss'), '13456');\n});\n\ntest('Hmm and Hmmss', function (assert) {\n    assert.equal(moment('12:34:56', 'HH:mm:ss').format('Hmm'), '1234');\n    assert.equal(moment('01:34:56', 'HH:mm:ss').format('Hmm'), '134');\n    assert.equal(moment('13:34:56', 'HH:mm:ss').format('Hmm'), '1334');\n\n    assert.equal(moment('12:34:56', 'HH:mm:ss').format('Hmmss'), '123456');\n    assert.equal(moment('01:34:56', 'HH:mm:ss').format('Hmmss'), '13456');\n    assert.equal(moment('08:34:56', 'HH:mm:ss').format('Hmmss'), '83456');\n    assert.equal(moment('18:34:56', 'HH:mm:ss').format('Hmmss'), '183456');\n});\n\ntest('k and kk', function (assert) {\n    assert.equal(moment('01:23:45', 'HH:mm:ss').format('k'), '1');\n    assert.equal(moment('12:34:56', 'HH:mm:ss').format('k'), '12');\n    assert.equal(moment('01:23:45', 'HH:mm:ss').format('kk'), '01');\n    assert.equal(moment('12:34:56', 'HH:mm:ss').format('kk'), '12');\n    assert.equal(moment('00:34:56', 'HH:mm:ss').format('kk'), '24');\n    assert.equal(moment('00:00:00', 'HH:mm:ss').format('kk'), '24');\n});\n\ntest('Y token', function (assert) {\n    assert.equal(moment('2010-01-01', 'YYYY-MM-DD', true).format('Y'), '2010', 'format 2010 with Y');\n    assert.equal(moment('-123-01-01', 'Y-MM-DD', true).format('Y'), '-123', 'format -123 with Y');\n    assert.equal(moment('12345-01-01', 'Y-MM-DD', true).format('Y'), '+12345', 'format 12345 with Y');\n    assert.equal(moment('0-01-01', 'Y-MM-DD', true).format('Y'), '0', 'format 0 with Y');\n    assert.equal(moment('1-01-01', 'Y-MM-DD', true).format('Y'), '1', 'format 1 with Y');\n    assert.equal(moment('9999-01-01', 'Y-MM-DD', true).format('Y'), '9999', 'format 9999 with Y');\n    assert.equal(moment('10000-01-01', 'Y-MM-DD', true).format('Y'), '+10000', 'format 10000 with Y');\n});\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/test/moment/from_to.js",
    "content": "import { module, test } from '../qunit';\nimport moment from '../../moment';\n\nmodule('from_to');\n\ntest('from', function (assert) {\n    var start = moment();\n    moment.locale('en');\n    assert.equal(start.from(start.clone().add(5, 'seconds')),  'a few seconds ago', '5 seconds = a few seconds ago');\n    assert.equal(start.from(start.clone().add(1, 'minute')),  'a minute ago', '1 minute = a minute ago');\n    assert.equal(start.from(start.clone().add(5, 'minutes')),  '5 minutes ago', '5 minutes = 5 minutes ago');\n\n    assert.equal(start.from(start.clone().subtract(5, 'seconds')),  'in a few seconds', '5 seconds = in a few seconds');\n    assert.equal(start.from(start.clone().subtract(1, 'minute')),  'in a minute', '1 minute = in a minute');\n    assert.equal(start.from(start.clone().subtract(5, 'minutes')),  'in 5 minutes', '5 minutes = in 5 minutes');\n});\n\ntest('from with absolute duration', function (assert) {\n    var start = moment();\n    moment.locale('en');\n    assert.equal(start.from(start.clone().add(5, 'seconds'), true),  'a few seconds', '5 seconds = a few seconds');\n    assert.equal(start.from(start.clone().add(1, 'minute'), true),  'a minute', '1 minute = a minute');\n    assert.equal(start.from(start.clone().add(5, 'minutes'), true),  '5 minutes', '5 minutes = 5 minutes');\n\n    assert.equal(start.from(start.clone().subtract(5, 'seconds'), true),  'a few seconds', '5 seconds = a few seconds');\n    assert.equal(start.from(start.clone().subtract(1, 'minute'), true),  'a minute', '1 minute = a minute');\n    assert.equal(start.from(start.clone().subtract(5, 'minutes'), true),  '5 minutes', '5 minutes = 5 minutes');\n});\n\ntest('to', function (assert) {\n    var start = moment();\n    moment.locale('en');\n    assert.equal(start.to(start.clone().subtract(5, 'seconds')),  'a few seconds ago', '5 seconds = a few seconds ago');\n    assert.equal(start.to(start.clone().subtract(1, 'minute')),  'a minute ago', '1 minute = a minute ago');\n    assert.equal(start.to(start.clone().subtract(5, 'minutes')),  '5 minutes ago', '5 minutes = 5 minutes ago');\n\n    assert.equal(start.to(start.clone().add(5, 'seconds')),  'in a few seconds', '5 seconds = in a few seconds');\n    assert.equal(start.to(start.clone().add(1, 'minute')),  'in a minute', '1 minute = in a minute');\n    assert.equal(start.to(start.clone().add(5, 'minutes')),  'in 5 minutes', '5 minutes = in 5 minutes');\n});\n\ntest('to with absolute duration', function (assert) {\n    var start = moment();\n    moment.locale('en');\n    assert.equal(start.to(start.clone().add(5, 'seconds'), true),  'a few seconds', '5 seconds = a few seconds');\n    assert.equal(start.to(start.clone().add(1, 'minute'), true),  'a minute', '1 minute = a minute');\n    assert.equal(start.to(start.clone().add(5, 'minutes'), true),  '5 minutes', '5 minutes = 5 minutes');\n\n    assert.equal(start.to(start.clone().subtract(5, 'seconds'), true),  'a few seconds', '5 seconds = a few seconds');\n    assert.equal(start.to(start.clone().subtract(1, 'minute'), true),  'a minute', '1 minute = a minute');\n    assert.equal(start.to(start.clone().subtract(5, 'minutes'), true),  '5 minutes', '5 minutes = 5 minutes');\n});\n\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/test/moment/getters_setters.js",
    "content": "import { module, test } from '../qunit';\nimport moment from '../../moment';\n\nmodule('getters and setters');\n\ntest('getters', function (assert) {\n    var a = moment([2011, 9, 12, 6, 7, 8, 9]);\n    assert.equal(a.year(), 2011, 'year');\n    assert.equal(a.month(), 9, 'month');\n    assert.equal(a.date(), 12, 'date');\n    assert.equal(a.day(), 3, 'day');\n    assert.equal(a.hours(), 6, 'hour');\n    assert.equal(a.minutes(), 7, 'minute');\n    assert.equal(a.seconds(), 8, 'second');\n    assert.equal(a.milliseconds(), 9, 'milliseconds');\n});\n\ntest('getters programmatic', function (assert) {\n    var a = moment([2011, 9, 12, 6, 7, 8, 9]);\n    assert.equal(a.get('year'), 2011, 'year');\n    assert.equal(a.get('month'), 9, 'month');\n    assert.equal(a.get('date'), 12, 'date');\n    assert.equal(a.get('day'), 3, 'day');\n    assert.equal(a.get('hour'), 6, 'hour');\n    assert.equal(a.get('minute'), 7, 'minute');\n    assert.equal(a.get('second'), 8, 'second');\n    assert.equal(a.get('milliseconds'), 9, 'milliseconds');\n\n    //actual getters tested elsewhere\n    assert.equal(a.get('weekday'), a.weekday(), 'weekday');\n    assert.equal(a.get('isoWeekday'), a.isoWeekday(), 'isoWeekday');\n    assert.equal(a.get('week'), a.week(), 'week');\n    assert.equal(a.get('isoWeek'), a.isoWeek(), 'isoWeek');\n    assert.equal(a.get('dayOfYear'), a.dayOfYear(), 'dayOfYear');\n\n    //getter no longer sets values when passed an object\n    assert.equal(moment([2016,0,1]).get({year:2015}).year(), 2016, 'getter no longer sets values when passed an object');\n});\n\ntest('setters plural', function (assert) {\n    var a = moment();\n    test.expectedDeprecations('years accessor', 'months accessor', 'dates accessor');\n\n    a.years(2011);\n    a.months(9);\n    a.dates(12);\n    a.hours(6);\n    a.minutes(7);\n    a.seconds(8);\n    a.milliseconds(9);\n    assert.equal(a.years(), 2011, 'years');\n    assert.equal(a.months(), 9, 'months');\n    assert.equal(a.dates(), 12, 'dates');\n    assert.equal(a.days(), 3, 'days');\n    assert.equal(a.hours(), 6, 'hours');\n    assert.equal(a.minutes(), 7, 'minutes');\n    assert.equal(a.seconds(), 8, 'seconds');\n    assert.equal(a.milliseconds(), 9, 'milliseconds');\n});\n\ntest('setters singular', function (assert) {\n    var a = moment();\n    a.year(2011);\n    a.month(9);\n    a.date(12);\n    a.hour(6);\n    a.minute(7);\n    a.second(8);\n    a.millisecond(9);\n    assert.equal(a.year(), 2011, 'year');\n    assert.equal(a.month(), 9, 'month');\n    assert.equal(a.date(), 12, 'date');\n    assert.equal(a.day(), 3, 'day');\n    assert.equal(a.hour(), 6, 'hour');\n    assert.equal(a.minute(), 7, 'minute');\n    assert.equal(a.second(), 8, 'second');\n    assert.equal(a.millisecond(), 9, 'milliseconds');\n});\n\ntest('setters', function (assert) {\n    var a = moment();\n    a.year(2011);\n    a.month(9);\n    a.date(12);\n    a.hours(6);\n    a.minutes(7);\n    a.seconds(8);\n    a.milliseconds(9);\n    assert.equal(a.year(), 2011, 'year');\n    assert.equal(a.month(), 9, 'month');\n    assert.equal(a.date(), 12, 'date');\n    assert.equal(a.day(), 3, 'day');\n    assert.equal(a.hours(), 6, 'hour');\n    assert.equal(a.minutes(), 7, 'minute');\n    assert.equal(a.seconds(), 8, 'second');\n    assert.equal(a.milliseconds(), 9, 'milliseconds');\n\n    // Test month() behavior. See https://github.com/timrwood/moment/pull/822\n    a = moment('20130531', 'YYYYMMDD');\n    a.month(3);\n    assert.equal(a.month(), 3, 'month edge case');\n});\n\ntest('setter programmatic', function (assert) {\n    var a = moment();\n    a.set('year', 2011);\n    a.set('month', 9);\n    a.set('date', 12);\n    a.set('hours', 6);\n    a.set('minutes', 7);\n    a.set('seconds', 8);\n    a.set('milliseconds', 9);\n    assert.equal(a.year(), 2011, 'year');\n    assert.equal(a.month(), 9, 'month');\n    assert.equal(a.date(), 12, 'date');\n    assert.equal(a.day(), 3, 'day');\n    assert.equal(a.hours(), 6, 'hour');\n    assert.equal(a.minutes(), 7, 'minute');\n    assert.equal(a.seconds(), 8, 'second');\n    assert.equal(a.milliseconds(), 9, 'milliseconds');\n\n    // Test month() behavior. See https://github.com/timrwood/moment/pull/822\n    a = moment('20130531', 'YYYYMMDD');\n    a.month(3);\n    assert.equal(a.month(), 3, 'month edge case');\n});\n\ntest('setters programatic with weeks', function (assert) {\n    var a = moment();\n    a.set('weekYear', 2001);\n    a.set('week', 49);\n    a.set('day', 4);\n\n    assert.equal(a.weekYear(), 2001, 'weekYear');\n    assert.equal(a.week(), 49, 'week');\n    assert.equal(a.day(), 4, 'day');\n\n    a.set('weekday', 1);\n    assert.equal(a.weekday(), 1, 'weekday');\n});\n\ntest('setters programatic with weeks ISO', function (assert) {\n    var a = moment();\n    a.set('isoWeekYear', 2001);\n    a.set('isoWeek', 49);\n    a.set('isoWeekday', 4);\n\n    assert.equal(a.isoWeekYear(), 2001, 'isoWeekYear');\n    assert.equal(a.isoWeek(), 49, 'isoWeek');\n    assert.equal(a.isoWeekday(), 4, 'isoWeekday');\n});\n\ntest('setters strings', function (assert) {\n    var a = moment([2012]).locale('en');\n    assert.equal(a.clone().day(0).day('Wednesday').day(), 3, 'day full name');\n    assert.equal(a.clone().day(0).day('Wed').day(), 3, 'day short name');\n    assert.equal(a.clone().day(0).day('We').day(), 3, 'day minimal name');\n    assert.equal(a.clone().day(0).day('invalid').day(), 0, 'invalid day name');\n    assert.equal(a.clone().month(0).month('April').month(), 3, 'month full name');\n    assert.equal(a.clone().month(0).month('Apr').month(), 3, 'month short name');\n    assert.equal(a.clone().month(0).month('invalid').month(), 0, 'invalid month name');\n});\n\ntest('setters - falsey values', function (assert) {\n    var a = moment();\n    // ensure minutes wasn't coincidentally 0 already\n    a.minutes(1);\n    a.minutes(0);\n    assert.equal(a.minutes(), 0, 'falsey value');\n});\n\ntest('chaining setters', function (assert) {\n    var a = moment();\n    a.year(2011)\n     .month(9)\n     .date(12)\n     .hours(6)\n     .minutes(7)\n     .seconds(8);\n    assert.equal(a.year(), 2011, 'year');\n    assert.equal(a.month(), 9, 'month');\n    assert.equal(a.date(), 12, 'date');\n    assert.equal(a.day(), 3, 'day');\n    assert.equal(a.hours(), 6, 'hour');\n    assert.equal(a.minutes(), 7, 'minute');\n    assert.equal(a.seconds(), 8, 'second');\n});\n\ntest('setter with multiple unit values', function (assert) {\n    var a = moment();\n    a.set({\n        year: 2011,\n        month: 9,\n        date: 12,\n        hours: 6,\n        minutes: 7,\n        seconds: 8,\n        milliseconds: 9\n    });\n    assert.equal(a.year(), 2011, 'year');\n    assert.equal(a.month(), 9, 'month');\n    assert.equal(a.date(), 12, 'date');\n    assert.equal(a.day(), 3, 'day');\n    assert.equal(a.hours(), 6, 'hour');\n    assert.equal(a.minutes(), 7, 'minute');\n    assert.equal(a.seconds(), 8, 'second');\n    assert.equal(a.milliseconds(), 9, 'milliseconds');\n\n    var c = moment([2016,0,1]);\n    assert.equal(c.set({weekYear: 2016}).weekYear(), 2016, 'week year correctly sets with object syntax');\n    assert.equal(c.set({quarter: 3}).quarter(), 3, 'quarter sets correctly with object syntax');\n});\n\ntest('day setter', function (assert) {\n    var a = moment([2011, 0, 15]);\n    assert.equal(moment(a).day(0).date(), 9, 'set from saturday to sunday');\n    assert.equal(moment(a).day(6).date(), 15, 'set from saturday to saturday');\n    assert.equal(moment(a).day(3).date(), 12, 'set from saturday to wednesday');\n\n    a = moment([2011, 0, 9]);\n    assert.equal(moment(a).day(0).date(), 9, 'set from sunday to sunday');\n    assert.equal(moment(a).day(6).date(), 15, 'set from sunday to saturday');\n    assert.equal(moment(a).day(3).date(), 12, 'set from sunday to wednesday');\n\n    a = moment([2011, 0, 12]);\n    assert.equal(moment(a).day(0).date(), 9, 'set from wednesday to sunday');\n    assert.equal(moment(a).day(6).date(), 15, 'set from wednesday to saturday');\n    assert.equal(moment(a).day(3).date(), 12, 'set from wednesday to wednesday');\n\n    assert.equal(moment(a).day(-7).date(), 2, 'set from wednesday to last sunday');\n    assert.equal(moment(a).day(-1).date(), 8, 'set from wednesday to last saturday');\n    assert.equal(moment(a).day(-4).date(), 5, 'set from wednesday to last wednesday');\n\n    assert.equal(moment(a).day(7).date(), 16, 'set from wednesday to next sunday');\n    assert.equal(moment(a).day(13).date(), 22, 'set from wednesday to next saturday');\n    assert.equal(moment(a).day(10).date(), 19, 'set from wednesday to next wednesday');\n\n    assert.equal(moment(a).day(14).date(), 23, 'set from wednesday to second next sunday');\n    assert.equal(moment(a).day(20).date(), 29, 'set from wednesday to second next saturday');\n    assert.equal(moment(a).day(17).date(), 26, 'set from wednesday to second next wednesday');\n});\n\ntest('object set ordering', function (assert) {\n    var a = moment([2016,3,30]);\n    assert.equal(a.set({date:31, month:4}).date(), 31, 'setter order automatically arranged by size');\n    var b = moment([2015,1,28]);\n    assert.equal(b.set({date:29, year: 2016}).format('YYYY-MM-DD'), '2016-02-29', 'year is prioritized over date');\n    //check a nonexistent time in US isn't set\n    var c = moment([2016,2,13]);\n    c.set({\n        hour:2,\n        minutes:30,\n        date: 14\n    });\n    assert.equal(c.format('YYYY-MM-DDTHH:mm'), '2016-03-14T02:30', 'setting hours, minutes date puts date first allowing time set to work');\n});\n\ntest('string setters', function (assert) {\n    var a = moment();\n    a.year('2011');\n    a.month('9');\n    a.date('12');\n    a.hours('6');\n    a.minutes('7');\n    a.seconds('8');\n    a.milliseconds('9');\n    assert.equal(a.year(), 2011, 'year');\n    assert.equal(a.month(), 9, 'month');\n    assert.equal(a.date(), 12, 'date');\n    assert.equal(a.day(), 3, 'day');\n    assert.equal(a.hours(), 6, 'hour');\n    assert.equal(a.minutes(), 7, 'minute');\n    assert.equal(a.seconds(), 8, 'second');\n    assert.equal(a.milliseconds(), 9, 'milliseconds');\n});\n\ntest('setters across DST +1', function (assert) {\n    var oldUpdateOffset = moment.updateOffset,\n        // Based on a real story somewhere in America/Los_Angeles\n        dstAt = moment('2014-03-09T02:00:00-08:00').parseZone(),\n        m;\n\n    moment.updateOffset = function (mom, keepTime) {\n        if (mom.isBefore(dstAt)) {\n            mom.utcOffset(-8, keepTime);\n        } else {\n            mom.utcOffset(-7, keepTime);\n        }\n    };\n\n    m = moment('2014-03-15T00:00:00-07:00').parseZone();\n    m.year(2013);\n    assert.equal(m.format(), '2013-03-15T00:00:00-08:00', 'year across +1');\n\n    m = moment('2014-03-15T00:00:00-07:00').parseZone();\n    m.month(0);\n    assert.equal(m.format(), '2014-01-15T00:00:00-08:00', 'month across +1');\n\n    m = moment('2014-03-15T00:00:00-07:00').parseZone();\n    m.date(1);\n    assert.equal(m.format(), '2014-03-01T00:00:00-08:00', 'date across +1');\n\n    m = moment('2014-03-09T03:05:00-07:00').parseZone();\n    m.hour(0);\n    assert.equal(m.format(), '2014-03-09T00:05:00-08:00', 'hour across +1');\n\n    moment.updateOffset = oldUpdateOffset;\n});\n\ntest('setters across DST -1', function (assert) {\n    var oldUpdateOffset = moment.updateOffset,\n        // Based on a real story somewhere in America/Los_Angeles\n        dstAt = moment('2014-11-02T02:00:00-07:00').parseZone(),\n        m;\n\n    moment.updateOffset = function (mom, keepTime) {\n        if (mom.isBefore(dstAt)) {\n            mom.utcOffset(-7, keepTime);\n        } else {\n            mom.utcOffset(-8, keepTime);\n        }\n    };\n\n    m = moment('2014-11-15T00:00:00-08:00').parseZone();\n    m.year(2013);\n    assert.equal(m.format(), '2013-11-15T00:00:00-07:00', 'year across -1');\n\n    m = moment('2014-11-15T00:00:00-08:00').parseZone();\n    m.month(0);\n    assert.equal(m.format(), '2014-01-15T00:00:00-07:00', 'month across -1');\n\n    m = moment('2014-11-15T00:00:00-08:00').parseZone();\n    m.date(1);\n    assert.equal(m.format(), '2014-11-01T00:00:00-07:00', 'date across -1');\n\n    m = moment('2014-11-02T03:30:00-08:00').parseZone();\n    m.hour(0);\n    assert.equal(m.format(), '2014-11-02T00:30:00-07:00', 'hour across -1');\n\n    moment.updateOffset = oldUpdateOffset;\n});\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/test/moment/instanceof.js",
    "content": "import { module, test } from '../qunit';\nimport moment from '../../moment';\n\nmodule('instanceof');\n\ntest('instanceof', function (assert) {\n    var mm = moment([2010, 0, 1]);\n\n    var extend = function (a, b) {\n        var i;\n        for (i in b) {\n            a[i] = b[i];\n        }\n        return a;\n    };\n\n    assert.equal(moment() instanceof moment, true, 'simple moment object');\n    assert.equal(extend({}, moment()) instanceof moment, false, 'extended moment object');\n    assert.equal(moment(null) instanceof moment, true, 'invalid moment object');\n\n    assert.equal(new Date() instanceof moment, false, 'date object is not moment object');\n    assert.equal(Object instanceof moment, false, 'Object is not moment object');\n    assert.equal('foo' instanceof moment, false, 'string is not moment object');\n    assert.equal(1 instanceof moment, false, 'number is not moment object');\n    assert.equal(NaN instanceof moment, false, 'NaN is not moment object');\n    assert.equal(null instanceof moment, false, 'null is not moment object');\n    assert.equal(undefined instanceof moment, false, 'undefined is not moment object');\n});\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/test/moment/invalid.js",
    "content": "import { module, test } from '../qunit';\nimport moment from '../../moment';\n\nmodule('invalid');\n\ntest('invalid', function (assert) {\n    var m = moment.invalid();\n    assert.equal(m.isValid(), false);\n    assert.equal(m.parsingFlags().userInvalidated, true);\n    assert.ok(isNaN(m.valueOf()));\n});\n\ntest('invalid with existing flag', function (assert) {\n    var m = moment.invalid({invalidMonth : 'whatchamacallit'});\n    assert.equal(m.isValid(), false);\n    assert.equal(m.parsingFlags().userInvalidated, false);\n    assert.equal(m.parsingFlags().invalidMonth, 'whatchamacallit');\n    assert.ok(isNaN(m.valueOf()));\n});\n\ntest('invalid with custom flag', function (assert) {\n    var m = moment.invalid({tooBusyWith : 'reiculating splines'});\n    assert.equal(m.isValid(), false);\n    assert.equal(m.parsingFlags().userInvalidated, false);\n    assert.equal(m.parsingFlags().tooBusyWith, 'reiculating splines');\n    assert.ok(isNaN(m.valueOf()));\n});\n\ntest('invalid operations', function (assert) {\n    var invalids = [\n            moment.invalid(),\n            moment('xyz', 'l'),\n            moment('2015-01-35', 'YYYY-MM-DD'),\n            moment('2015-01-25 a', 'YYYY-MM-DD', true)\n        ],\n        i,\n        invalid,\n        valid = moment();\n\n    test.expectedDeprecations('moment().min', 'moment().max', 'isDSTShifted');\n\n    for (i = 0; i < invalids.length; ++i) {\n        invalid = invalids[i];\n\n        assert.ok(!invalid.clone().add(5, 'hours').isValid(), 'invalid.add is invalid');\n        assert.equal(invalid.calendar(), 'Invalid date', 'invalid.calendar is \\'Invalid date\\'');\n        assert.ok(!invalid.clone().isValid(), 'invalid.clone is invalid');\n        assert.ok(isNaN(invalid.diff(valid)), 'invalid.diff(valid) is NaN');\n        assert.ok(isNaN(valid.diff(invalid)), 'valid.diff(invalid) is NaN');\n        assert.ok(isNaN(invalid.diff(invalid)), 'invalid.diff(invalid) is NaN');\n        assert.ok(!invalid.clone().endOf('month').isValid(), 'invalid.endOf is invalid');\n        assert.equal(invalid.format(), 'Invalid date', 'invalid.format is \\'Invalid date\\'');\n        assert.equal(invalid.from(), 'Invalid date');\n        assert.equal(invalid.from(valid), 'Invalid date');\n        assert.equal(valid.from(invalid), 'Invalid date');\n        assert.equal(invalid.fromNow(), 'Invalid date');\n        assert.equal(invalid.to(), 'Invalid date');\n        assert.equal(invalid.to(valid), 'Invalid date');\n        assert.equal(valid.to(invalid), 'Invalid date');\n        assert.equal(invalid.toNow(), 'Invalid date');\n        assert.ok(isNaN(invalid.get('year')), 'invalid.get is NaN');\n        // TODO invalidAt\n        assert.ok(!invalid.isAfter(valid));\n        assert.ok(!valid.isAfter(invalid));\n        assert.ok(!invalid.isAfter(invalid));\n        assert.ok(!invalid.isBefore(valid));\n        assert.ok(!valid.isBefore(invalid));\n        assert.ok(!invalid.isBefore(invalid));\n        assert.ok(!invalid.isBetween(valid, valid));\n        assert.ok(!valid.isBetween(invalid, valid));\n        assert.ok(!valid.isBetween(valid, invalid));\n        assert.ok(!invalid.isSame(invalid));\n        assert.ok(!invalid.isSame(valid));\n        assert.ok(!valid.isSame(invalid));\n        assert.ok(!invalid.isValid());\n        assert.equal(invalid.locale(), 'en');\n        assert.equal(invalid.localeData()._abbr, 'en');\n        assert.ok(!invalid.clone().max(valid).isValid());\n        assert.ok(!valid.clone().max(invalid).isValid());\n        assert.ok(!invalid.clone().max(invalid).isValid());\n        assert.ok(!invalid.clone().min(valid).isValid());\n        assert.ok(!valid.clone().min(invalid).isValid());\n        assert.ok(!invalid.clone().min(invalid).isValid());\n        assert.ok(!moment.min(invalid, valid).isValid());\n        assert.ok(!moment.min(valid, invalid).isValid());\n        assert.ok(!moment.max(invalid, valid).isValid());\n        assert.ok(!moment.max(valid, invalid).isValid());\n        assert.ok(!invalid.clone().set('year', 2005).isValid());\n        assert.ok(!invalid.clone().startOf('month').isValid());\n\n        assert.ok(!invalid.clone().subtract(5, 'days').isValid());\n        assert.deepEqual(invalid.toArray(), [NaN, NaN, NaN, NaN, NaN, NaN, NaN]);\n        assert.deepEqual(invalid.toObject(), {\n            years: NaN,\n            months: NaN,\n            date: NaN,\n            hours: NaN,\n            minutes: NaN,\n            seconds: NaN,\n            milliseconds: NaN\n        });\n        assert.ok(moment.isDate(invalid.toDate()));\n        assert.ok(isNaN(invalid.toDate().valueOf()));\n        assert.equal(invalid.toJSON(), null);\n        assert.equal(invalid.toString(), 'Invalid date');\n        assert.ok(isNaN(invalid.unix()));\n        assert.ok(isNaN(invalid.valueOf()));\n\n        assert.ok(isNaN(invalid.year()));\n        assert.ok(isNaN(invalid.weekYear()));\n        assert.ok(isNaN(invalid.isoWeekYear()));\n        assert.ok(isNaN(invalid.quarter()));\n        assert.ok(isNaN(invalid.quarters()));\n        assert.ok(isNaN(invalid.month()));\n        assert.ok(isNaN(invalid.daysInMonth()));\n        assert.ok(isNaN(invalid.week()));\n        assert.ok(isNaN(invalid.weeks()));\n        assert.ok(isNaN(invalid.isoWeek()));\n        assert.ok(isNaN(invalid.isoWeeks()));\n        assert.ok(isNaN(invalid.weeksInYear()));\n        assert.ok(isNaN(invalid.isoWeeksInYear()));\n        assert.ok(isNaN(invalid.date()));\n        assert.ok(isNaN(invalid.day()));\n        assert.ok(isNaN(invalid.days()));\n        assert.ok(isNaN(invalid.weekday()));\n        assert.ok(isNaN(invalid.isoWeekday()));\n        assert.ok(isNaN(invalid.dayOfYear()));\n        assert.ok(isNaN(invalid.hour()));\n        assert.ok(isNaN(invalid.hours()));\n        assert.ok(isNaN(invalid.minute()));\n        assert.ok(isNaN(invalid.minutes()));\n        assert.ok(isNaN(invalid.second()));\n        assert.ok(isNaN(invalid.seconds()));\n        assert.ok(isNaN(invalid.millisecond()));\n        assert.ok(isNaN(invalid.milliseconds()));\n        assert.ok(isNaN(invalid.utcOffset()));\n\n        assert.ok(!invalid.clone().year(2001).isValid());\n        assert.ok(!invalid.clone().weekYear(2001).isValid());\n        assert.ok(!invalid.clone().isoWeekYear(2001).isValid());\n        assert.ok(!invalid.clone().quarter(1).isValid());\n        assert.ok(!invalid.clone().quarters(1).isValid());\n        assert.ok(!invalid.clone().month(1).isValid());\n        assert.ok(!invalid.clone().week(1).isValid());\n        assert.ok(!invalid.clone().weeks(1).isValid());\n        assert.ok(!invalid.clone().isoWeek(1).isValid());\n        assert.ok(!invalid.clone().isoWeeks(1).isValid());\n        assert.ok(!invalid.clone().date(1).isValid());\n        assert.ok(!invalid.clone().day(1).isValid());\n        assert.ok(!invalid.clone().days(1).isValid());\n        assert.ok(!invalid.clone().weekday(1).isValid());\n        assert.ok(!invalid.clone().isoWeekday(1).isValid());\n        assert.ok(!invalid.clone().dayOfYear(1).isValid());\n        assert.ok(!invalid.clone().hour(1).isValid());\n        assert.ok(!invalid.clone().hours(1).isValid());\n        assert.ok(!invalid.clone().minute(1).isValid());\n        assert.ok(!invalid.clone().minutes(1).isValid());\n        assert.ok(!invalid.clone().second(1).isValid());\n        assert.ok(!invalid.clone().seconds(1).isValid());\n        assert.ok(!invalid.clone().millisecond(1).isValid());\n        assert.ok(!invalid.clone().milliseconds(1).isValid());\n        assert.ok(!invalid.clone().utcOffset(1).isValid());\n\n        assert.ok(!invalid.clone().utc().isValid());\n        assert.ok(!invalid.clone().local().isValid());\n        assert.ok(!invalid.clone().parseZone('05:30').isValid());\n        assert.ok(!invalid.hasAlignedHourOffset());\n        assert.ok(!invalid.isDST());\n        assert.ok(!invalid.isDSTShifted());\n        assert.ok(!invalid.isLocal());\n        assert.ok(!invalid.isUtcOffset());\n        assert.ok(!invalid.isUtc());\n        assert.ok(!invalid.isUTC());\n\n        assert.ok(!invalid.isLeapYear());\n\n        assert.equal(moment.duration({from: invalid, to: valid}).asMilliseconds(), 0);\n        assert.equal(moment.duration({from: valid, to: invalid}).asMilliseconds(), 0);\n        assert.equal(moment.duration({from: invalid, to: invalid}).asMilliseconds(), 0);\n    }\n});\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/test/moment/is_after.js",
    "content": "import { module, test } from '../qunit';\nimport moment from '../../moment';\n\nmodule('is after');\n\ntest('is after without units', function (assert) {\n    var m = moment(new Date(2011, 3, 2, 3, 4, 5, 10)), mCopy = moment(m);\n    assert.equal(m.isAfter(moment(new Date(2012, 3, 2, 3, 5, 5, 10))), false, 'year is later');\n    assert.equal(m.isAfter(moment(new Date(2010, 3, 2, 3, 3, 5, 10))), true, 'year is earlier');\n    assert.equal(m.isAfter(moment(new Date(2011, 4, 2, 3, 4, 5, 10))), false, 'month is later');\n    assert.equal(m.isAfter(moment(new Date(2011, 2, 2, 3, 4, 5, 10))), true, 'month is earlier');\n    assert.equal(m.isAfter(moment(new Date(2011, 3, 3, 3, 4, 5, 10))), false, 'day is later');\n    assert.equal(m.isAfter(moment(new Date(2011, 3, 1, 3, 4, 5, 10))), true, 'day is earlier');\n    assert.equal(m.isAfter(moment(new Date(2011, 3, 2, 4, 4, 5, 10))), false, 'hour is later');\n    assert.equal(m.isAfter(moment(new Date(2011, 3, 2, 2, 4, 5, 10))), true, 'hour is earlier');\n    assert.equal(m.isAfter(moment(new Date(2011, 3, 2, 3, 5, 5, 10))), false, 'minute is later');\n    assert.equal(m.isAfter(moment(new Date(2011, 3, 2, 3, 3, 5, 10))), true, 'minute is earlier');\n    assert.equal(m.isAfter(moment(new Date(2011, 3, 2, 3, 4, 6, 10))), false, 'second is later');\n    assert.equal(m.isAfter(moment(new Date(2011, 3, 2, 3, 4, 4, 11))), true, 'second is earlier');\n    assert.equal(m.isAfter(moment(new Date(2011, 3, 2, 3, 4, 5, 10))), false, 'millisecond match');\n    assert.equal(m.isAfter(moment(new Date(2011, 3, 2, 3, 4, 5, 11))), false, 'millisecond is later');\n    assert.equal(m.isAfter(moment(new Date(2011, 3, 2, 3, 4, 5, 9))), true, 'millisecond is earlier');\n    assert.equal(m.isAfter(m), false, 'moments are not after themselves');\n    assert.equal(+m, +mCopy, 'isAfter second should not change moment');\n});\n\ntest('is after year', function (assert) {\n    var m = moment(new Date(2011, 1, 2, 3, 4, 5, 6)), mCopy = moment(m);\n    assert.equal(m.isAfter(moment(new Date(2011, 5, 6, 7, 8, 9, 10)), 'year'), false, 'year match');\n    assert.equal(m.isAfter(moment(new Date(2010, 5, 6, 7, 8, 9, 10)), 'years'), true, 'plural should work');\n    assert.equal(m.isAfter(moment(new Date(2013, 5, 6, 7, 8, 9, 10)), 'year'), false, 'year is later');\n    assert.equal(m.isAfter(moment(new Date(2010, 5, 6, 7, 8, 9, 10)), 'year'), true, 'year is earlier');\n    assert.equal(m.isAfter(moment(new Date(2011, 0, 1, 0, 0, 0, 0)), 'year'), false, 'exact start of year');\n    assert.equal(m.isAfter(moment(new Date(2011, 11, 31, 23, 59, 59, 999)), 'year'), false, 'exact end of year');\n    assert.equal(m.isAfter(moment(new Date(2012, 0, 1, 0, 0, 0, 0)), 'year'), false, 'start of next year');\n    assert.equal(m.isAfter(moment(new Date(2010, 11, 31, 23, 59, 59, 999)), 'year'), true, 'end of previous year');\n    assert.equal(m.isAfter(moment(new Date(1980, 11, 31, 23, 59, 59, 999)), 'year'), true, 'end of year far before');\n    assert.equal(m.isAfter(m, 'year'), false, 'same moments are not after the same year');\n    assert.equal(+m, +mCopy, 'isAfter year should not change moment');\n});\n\ntest('is after month', function (assert) {\n    var m = moment(new Date(2011, 2, 3, 4, 5, 6, 7)), mCopy = moment(m);\n    assert.equal(m.isAfter(moment(new Date(2011, 2, 6, 7, 8, 9, 10)), 'month'), false, 'month match');\n    assert.equal(m.isAfter(moment(new Date(2010, 2, 6, 7, 8, 9, 10)), 'months'), true, 'plural should work');\n    assert.equal(m.isAfter(moment(new Date(2012, 2, 6, 7, 8, 9, 10)), 'month'), false, 'year is later');\n    assert.equal(m.isAfter(moment(new Date(2010, 2, 6, 7, 8, 9, 10)), 'month'), true, 'year is earlier');\n    assert.equal(m.isAfter(moment(new Date(2011, 5, 6, 7, 8, 9, 10)), 'month'), false, 'month is later');\n    assert.equal(m.isAfter(moment(new Date(2011, 1, 6, 7, 8, 9, 10)), 'month'), true, 'month is earlier');\n    assert.equal(m.isAfter(moment(new Date(2011, 2, 1, 0, 0, 0, 0)), 'month'), false, 'exact start of month');\n    assert.equal(m.isAfter(moment(new Date(2011, 2, 31, 23, 59, 59, 999)), 'month'), false, 'exact end of month');\n    assert.equal(m.isAfter(moment(new Date(2011, 3, 1, 0, 0, 0, 0)), 'month'), false, 'start of next month');\n    assert.equal(m.isAfter(moment(new Date(2011, 1, 27, 23, 59, 59, 999)), 'month'), true, 'end of previous month');\n    assert.equal(m.isAfter(moment(new Date(2010, 12, 31, 23, 59, 59, 999)), 'month'), true, 'later month but earlier year');\n    assert.equal(m.isAfter(m, 'month'), false, 'same moments are not after the same month');\n    assert.equal(+m, +mCopy, 'isAfter month should not change moment');\n});\n\ntest('is after day', function (assert) {\n    var m = moment(new Date(2011, 3, 2, 3, 4, 5, 6)), mCopy = moment(m);\n    assert.equal(m.isAfter(moment(new Date(2011, 3, 2, 7, 8, 9, 10)), 'day'), false, 'day match');\n    assert.equal(m.isAfter(moment(new Date(2010, 3, 2, 7, 8, 9, 10)), 'days'), true, 'plural should work');\n    assert.equal(m.isAfter(moment(new Date(2012, 3, 2, 7, 8, 9, 10)), 'day'), false, 'year is later');\n    assert.equal(m.isAfter(moment(new Date(2010, 3, 2, 7, 8, 9, 10)), 'day'), true, 'year is earlier');\n    assert.equal(m.isAfter(moment(new Date(2011, 4, 2, 7, 8, 9, 10)), 'day'), false, 'month is later');\n    assert.equal(m.isAfter(moment(new Date(2011, 2, 2, 7, 8, 9, 10)), 'day'), true, 'month is earlier');\n    assert.equal(m.isAfter(moment(new Date(2011, 3, 3, 7, 8, 9, 10)), 'day'), false, 'day is later');\n    assert.equal(m.isAfter(moment(new Date(2011, 3, 1, 7, 8, 9, 10)), 'day'), true, 'day is earlier');\n    assert.equal(m.isAfter(moment(new Date(2011, 3, 2, 0, 0, 0, 0)), 'day'), false, 'exact start of day');\n    assert.equal(m.isAfter(moment(new Date(2011, 3, 2, 23, 59, 59, 999)), 'day'), false, 'exact end of day');\n    assert.equal(m.isAfter(moment(new Date(2011, 3, 3, 0, 0, 0, 0)), 'day'), false, 'start of next day');\n    assert.equal(m.isAfter(moment(new Date(2011, 3, 1, 23, 59, 59, 999)), 'day'), true, 'end of previous day');\n    assert.equal(m.isAfter(moment(new Date(2010, 3, 10, 0, 0, 0, 0)), 'day'), true, 'later day but earlier year');\n    assert.equal(m.isAfter(m, 'day'), false, 'same moments are not after the same day');\n    assert.equal(+m, +mCopy, 'isAfter day should not change moment');\n});\n\ntest('is after hour', function (assert) {\n    var m = moment(new Date(2011, 3, 2, 3, 4, 5, 6)), mCopy = moment(m);\n    assert.equal(m.isAfter(moment(new Date(2011, 3, 2, 3, 8, 9, 10)), 'hour'), false, 'hour match');\n    assert.equal(m.isAfter(moment(new Date(2010, 3, 2, 3, 8, 9, 10)), 'hours'), true, 'plural should work');\n    assert.equal(m.isAfter(moment(new Date(2012, 3, 2, 3, 8, 9, 10)), 'hour'), false, 'year is later');\n    assert.equal(m.isAfter(moment(new Date(2010, 3, 2, 3, 8, 9, 10)), 'hour'), true, 'year is earlier');\n    assert.equal(m.isAfter(moment(new Date(2011, 4, 2, 3, 8, 9, 10)), 'hour'), false, 'month is later');\n    assert.equal(m.isAfter(moment(new Date(2011, 1, 2, 3, 8, 9, 10)), 'hour'), true, 'month is earlier');\n    assert.equal(m.isAfter(moment(new Date(2011, 3, 3, 3, 8, 9, 10)), 'hour'), false, 'day is later');\n    assert.equal(m.isAfter(moment(new Date(2011, 3, 1, 3, 8, 9, 10)), 'hour'), true, 'day is earlier');\n    assert.equal(m.isAfter(moment(new Date(2011, 3, 2, 4, 8, 9, 10)), 'hour'), false, 'hour is later');\n    assert.equal(m.isAfter(moment(new Date(2011, 3, 2, 3, 8, 9, 10)), 'hour'), false, 'hour is earlier');\n    assert.equal(m.isAfter(moment(new Date(2011, 3, 2, 3, 0, 0, 0)), 'hour'), false, 'exact start of hour');\n    assert.equal(m.isAfter(moment(new Date(2011, 3, 2, 3, 59, 59, 999)), 'hour'), false, 'exact end of hour');\n    assert.equal(m.isAfter(moment(new Date(2011, 3, 2, 4, 0, 0, 0)), 'hour'), false, 'start of next hour');\n    assert.equal(m.isAfter(moment(new Date(2011, 3, 2, 2, 59, 59, 999)), 'hour'), true, 'end of previous hour');\n    assert.equal(m.isAfter(m, 'hour'), false, 'same moments are not after the same hour');\n    assert.equal(+m, +mCopy, 'isAfter hour should not change moment');\n});\n\ntest('is after minute', function (assert) {\n    var m = moment(new Date(2011, 3, 2, 3, 4, 5, 6)), mCopy = moment(m);\n    assert.equal(m.isAfter(moment(new Date(2011, 3, 2, 3, 4, 9, 10)), 'minute'), false, 'minute match');\n    assert.equal(m.isAfter(moment(new Date(2010, 3, 2, 3, 4, 9, 10)), 'minutes'), true, 'plural should work');\n    assert.equal(m.isAfter(moment(new Date(2012, 3, 2, 3, 4, 9, 10)), 'minute'), false, 'year is later');\n    assert.equal(m.isAfter(moment(new Date(2010, 3, 2, 3, 4, 9, 10)), 'minute'), true, 'year is earlier');\n    assert.equal(m.isAfter(moment(new Date(2011, 4, 2, 3, 4, 9, 10)), 'minute'), false, 'month is later');\n    assert.equal(m.isAfter(moment(new Date(2011, 2, 2, 3, 4, 9, 10)), 'minute'), true, 'month is earlier');\n    assert.equal(m.isAfter(moment(new Date(2011, 3, 3, 3, 4, 9, 10)), 'minute'), false, 'day is later');\n    assert.equal(m.isAfter(moment(new Date(2011, 3, 1, 3, 4, 9, 10)), 'minute'), true, 'day is earlier');\n    assert.equal(m.isAfter(moment(new Date(2011, 3, 2, 4, 4, 9, 10)), 'minute'), false, 'hour is later');\n    assert.equal(m.isAfter(moment(new Date(2011, 3, 2, 2, 4, 9, 10)), 'minute'), true, 'hour is earler');\n    assert.equal(m.isAfter(moment(new Date(2011, 3, 2, 3, 5, 9, 10)), 'minute'), false, 'minute is later');\n    assert.equal(m.isAfter(moment(new Date(2011, 3, 2, 3, 3, 9, 10)), 'minute'), true, 'minute is earlier');\n    assert.equal(m.isAfter(moment(new Date(2011, 3, 2, 3, 4, 0, 0)), 'minute'), false, 'exact start of minute');\n    assert.equal(m.isAfter(moment(new Date(2011, 3, 2, 3, 4, 59, 999)), 'minute'), false, 'exact end of minute');\n    assert.equal(m.isAfter(moment(new Date(2011, 3, 2, 3, 5, 0, 0)), 'minute'), false, 'start of next minute');\n    assert.equal(m.isAfter(moment(new Date(2011, 3, 2, 3, 3, 59, 999)), 'minute'), true, 'end of previous minute');\n    assert.equal(m.isAfter(m, 'minute'), false, 'same moments are not after the same minute');\n    assert.equal(+m, +mCopy, 'isAfter minute should not change moment');\n});\n\ntest('is after second', function (assert) {\n    var m = moment(new Date(2011, 3, 2, 3, 4, 5, 10)), mCopy = moment(m);\n    assert.equal(m.isAfter(moment(new Date(2011, 3, 2, 3, 4, 5, 10)), 'second'), false, 'second match');\n    assert.equal(m.isAfter(moment(new Date(2010, 3, 2, 3, 4, 5, 10)), 'seconds'), true, 'plural should work');\n    assert.equal(m.isAfter(moment(new Date(2012, 3, 2, 3, 4, 5, 10)), 'second'), false, 'year is later');\n    assert.equal(m.isAfter(moment(new Date(2010, 3, 2, 3, 4, 5, 10)), 'second'), true, 'year is earlier');\n    assert.equal(m.isAfter(moment(new Date(2011, 4, 2, 3, 4, 5, 10)), 'second'), false, 'month is later');\n    assert.equal(m.isAfter(moment(new Date(2011, 2, 2, 3, 4, 5, 10)), 'second'), true, 'month is earlier');\n    assert.equal(m.isAfter(moment(new Date(2011, 3, 3, 3, 4, 5, 10)), 'second'), false, 'day is later');\n    assert.equal(m.isAfter(moment(new Date(2011, 3, 1, 1, 4, 5, 10)), 'second'), true, 'day is earlier');\n    assert.equal(m.isAfter(moment(new Date(2011, 3, 2, 4, 4, 5, 10)), 'second'), false, 'hour is later');\n    assert.equal(m.isAfter(moment(new Date(2011, 3, 1, 4, 1, 5, 10)), 'second'), true, 'hour is earlier');\n    assert.equal(m.isAfter(moment(new Date(2011, 3, 2, 3, 5, 5, 10)), 'second'), false, 'minute is later');\n    assert.equal(m.isAfter(moment(new Date(2011, 3, 2, 3, 3, 5, 10)), 'second'), true, 'minute is earlier');\n    assert.equal(m.isAfter(moment(new Date(2011, 3, 2, 3, 4, 6, 10)), 'second'), false, 'second is later');\n    assert.equal(m.isAfter(moment(new Date(2011, 3, 2, 3, 4, 4, 5)), 'second'), true, 'second is earlier');\n    assert.equal(m.isAfter(moment(new Date(2011, 3, 2, 3, 4, 5, 0)), 'second'), false, 'exact start of second');\n    assert.equal(m.isAfter(moment(new Date(2011, 3, 2, 3, 4, 5, 999)), 'second'), false, 'exact end of second');\n    assert.equal(m.isAfter(moment(new Date(2011, 3, 2, 3, 4, 6, 0)), 'second'), false, 'start of next second');\n    assert.equal(m.isAfter(moment(new Date(2011, 3, 2, 3, 4, 4, 999)), 'second'), true, 'end of previous second');\n    assert.equal(m.isAfter(m, 'second'), false, 'same moments are not after the same second');\n    assert.equal(+m, +mCopy, 'isAfter second should not change moment');\n});\n\ntest('is after millisecond', function (assert) {\n    var m = moment(new Date(2011, 3, 2, 3, 4, 5, 10)), mCopy = moment(m);\n    assert.equal(m.isAfter(moment(new Date(2011, 3, 2, 3, 4, 5, 10)), 'millisecond'), false, 'millisecond match');\n    assert.equal(m.isAfter(moment(new Date(2010, 3, 2, 3, 4, 5, 10)), 'milliseconds'), true, 'plural should work');\n    assert.equal(m.isAfter(moment(new Date(2012, 3, 2, 3, 4, 5, 10)), 'millisecond'), false, 'year is later');\n    assert.equal(m.isAfter(moment(new Date(2010, 3, 2, 3, 4, 5, 10)), 'millisecond'), true, 'year is earlier');\n    assert.equal(m.isAfter(moment(new Date(2011, 4, 2, 3, 4, 5, 10)), 'millisecond'), false, 'month is later');\n    assert.equal(m.isAfter(moment(new Date(2011, 2, 2, 3, 4, 5, 10)), 'millisecond'), true, 'month is earlier');\n    assert.equal(m.isAfter(moment(new Date(2011, 3, 3, 3, 4, 5, 10)), 'millisecond'), false, 'day is later');\n    assert.equal(m.isAfter(moment(new Date(2011, 3, 1, 1, 4, 5, 10)), 'millisecond'), true, 'day is earlier');\n    assert.equal(m.isAfter(moment(new Date(2011, 3, 2, 4, 4, 5, 10)), 'millisecond'), false, 'hour is later');\n    assert.equal(m.isAfter(moment(new Date(2011, 3, 1, 4, 1, 5, 10)), 'millisecond'), true, 'hour is earlier');\n    assert.equal(m.isAfter(moment(new Date(2011, 3, 2, 3, 5, 5, 10)), 'millisecond'), false, 'minute is later');\n    assert.equal(m.isAfter(moment(new Date(2011, 3, 2, 3, 3, 5, 10)), 'millisecond'), true, 'minute is earlier');\n    assert.equal(m.isAfter(moment(new Date(2011, 3, 2, 3, 4, 6, 10)), 'millisecond'), false, 'second is later');\n    assert.equal(m.isAfter(moment(new Date(2011, 3, 2, 3, 4, 4, 5)), 'millisecond'), true, 'second is earlier');\n    assert.equal(m.isAfter(moment(new Date(2011, 3, 2, 3, 4, 6, 11)), 'millisecond'), false, 'millisecond is later');\n    assert.equal(m.isAfter(moment(new Date(2011, 3, 2, 3, 4, 4, 9)), 'millisecond'), true, 'millisecond is earlier');\n    assert.equal(m.isAfter(m, 'millisecond'), false, 'same moments are not after the same millisecond');\n    assert.equal(+m, +mCopy, 'isAfter millisecond should not change moment');\n});\n\ntest('is after invalid', function (assert) {\n    var m = moment(), invalid = moment.invalid();\n    assert.equal(m.isAfter(invalid), false, 'valid moment is not after invalid moment');\n    assert.equal(invalid.isAfter(m), false, 'invalid moment is not after valid moment');\n    assert.equal(m.isAfter(invalid, 'year'), false, 'invalid moment year');\n    assert.equal(m.isAfter(invalid, 'month'), false, 'invalid moment month');\n    assert.equal(m.isAfter(invalid, 'day'), false, 'invalid moment day');\n    assert.equal(m.isAfter(invalid, 'hour'), false, 'invalid moment hour');\n    assert.equal(m.isAfter(invalid, 'minute'), false, 'invalid moment minute');\n    assert.equal(m.isAfter(invalid, 'second'), false, 'invalid moment second');\n    assert.equal(m.isAfter(invalid, 'milliseconds'), false, 'invalid moment milliseconds');\n});\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/test/moment/is_array.js",
    "content": "import { module, test } from '../qunit';\nimport isArray from '../../lib/utils/is-array.js';\n\n\ntest('isArray recognizes Array objects', function (assert) {\n    assert.ok(isArray([1,2,3]), 'array args');\n    assert.ok(isArray([]), 'empty array');\n    assert.ok(isArray(new Array(1,2,3)), 'array constructor');\n});\n\ntest('isArray rejects non-Array objects', function (assert) {\n    assert.ok(!isArray(), 'nothing');\n    assert.ok(!isArray(undefined), 'undefined');\n    assert.ok(!isArray(null), 'null');\n    assert.ok(!isArray(123), 'number');\n    assert.ok(!isArray('[1,2,3]'), 'string');\n    assert.ok(!isArray(new Date()), 'date');\n    assert.ok(!isArray({a:1,b:2}), 'object');\n});\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/test/moment/is_before.js",
    "content": "import { module, test } from '../qunit';\nimport moment from '../../moment';\n\nmodule('is before');\n\ntest('is after without units', function (assert) {\n    var m = moment(new Date(2011, 3, 2, 3, 4, 5, 10)), mCopy = moment(m);\n    assert.equal(m.isBefore(moment(new Date(2012, 3, 2, 3, 5, 5, 10))), true, 'year is later');\n    assert.equal(m.isBefore(moment(new Date(2010, 3, 2, 3, 3, 5, 10))), false, 'year is earlier');\n    assert.equal(m.isBefore(moment(new Date(2011, 4, 2, 3, 4, 5, 10))), true, 'month is later');\n    assert.equal(m.isBefore(moment(new Date(2011, 2, 2, 3, 4, 5, 10))), false, 'month is earlier');\n    assert.equal(m.isBefore(moment(new Date(2011, 3, 3, 3, 4, 5, 10))), true, 'day is later');\n    assert.equal(m.isBefore(moment(new Date(2011, 3, 1, 3, 4, 5, 10))), false, 'day is earlier');\n    assert.equal(m.isBefore(moment(new Date(2011, 3, 2, 4, 4, 5, 10))), true, 'hour is later');\n    assert.equal(m.isBefore(moment(new Date(2011, 3, 2, 2, 4, 5, 10))), false, 'hour is earlier');\n    assert.equal(m.isBefore(moment(new Date(2011, 3, 2, 3, 5, 5, 10))), true, 'minute is later');\n    assert.equal(m.isBefore(moment(new Date(2011, 3, 2, 3, 3, 5, 10))), false, 'minute is earlier');\n    assert.equal(m.isBefore(moment(new Date(2011, 3, 2, 3, 4, 6, 10))), true, 'second is later');\n    assert.equal(m.isBefore(moment(new Date(2011, 3, 2, 3, 4, 4, 11))), false, 'second is earlier');\n    assert.equal(m.isBefore(moment(new Date(2011, 3, 2, 3, 4, 5, 10))), false, 'millisecond match');\n    assert.equal(m.isBefore(moment(new Date(2011, 3, 2, 3, 4, 5, 11))), true, 'millisecond is later');\n    assert.equal(m.isBefore(moment(new Date(2011, 3, 2, 3, 4, 5, 9))), false, 'millisecond is earlier');\n    assert.equal(m.isBefore(m), false, 'moments are not before themselves');\n    assert.equal(+m, +mCopy, 'isBefore second should not change moment');\n});\n\ntest('is before year', function (assert) {\n    var m = moment(new Date(2011, 1, 2, 3, 4, 5, 6)), mCopy = moment(m);\n    assert.equal(m.isBefore(moment(new Date(2011, 5, 6, 7, 8, 9, 10)), 'year'), false, 'year match');\n    assert.equal(m.isBefore(moment(new Date(2012, 5, 6, 7, 8, 9, 10)), 'years'), true, 'plural should work');\n    assert.equal(m.isBefore(moment(new Date(2013, 5, 6, 7, 8, 9, 10)), 'year'), true, 'year is later');\n    assert.equal(m.isBefore(moment(new Date(2010, 5, 6, 7, 8, 9, 10)), 'year'), false, 'year is earlier');\n    assert.equal(m.isBefore(moment(new Date(2011, 0, 1, 0, 0, 0, 0)), 'year'), false, 'exact start of year');\n    assert.equal(m.isBefore(moment(new Date(2011, 11, 31, 23, 59, 59, 999)), 'year'), false, 'exact end of year');\n    assert.equal(m.isBefore(moment(new Date(2012, 0, 1, 0, 0, 0, 0)), 'year'), true, 'start of next year');\n    assert.equal(m.isBefore(moment(new Date(2010, 11, 31, 23, 59, 59, 999)), 'year'), false, 'end of previous year');\n    assert.equal(m.isBefore(moment(new Date(1980, 11, 31, 23, 59, 59, 999)), 'year'), false, 'end of year far before');\n    assert.equal(m.isBefore(m, 'year'), false, 'same moments are not before the same year');\n    assert.equal(+m, +mCopy, 'isBefore year should not change moment');\n});\n\ntest('is before month', function (assert) {\n    var m = moment(new Date(2011, 2, 3, 4, 5, 6, 7)), mCopy = moment(m);\n    assert.equal(m.isBefore(moment(new Date(2011, 2, 6, 7, 8, 9, 10)), 'month'), false, 'month match');\n    assert.equal(m.isBefore(moment(new Date(2012, 2, 6, 7, 8, 9, 10)), 'months'), true, 'plural should work');\n    assert.equal(m.isBefore(moment(new Date(2012, 2, 6, 7, 8, 9, 10)), 'month'), true, 'year is later');\n    assert.equal(m.isBefore(moment(new Date(2010, 2, 6, 7, 8, 9, 10)), 'month'), false, 'year is earlier');\n    assert.equal(m.isBefore(moment(new Date(2011, 5, 6, 7, 8, 9, 10)), 'month'), true, 'month is later');\n    assert.equal(m.isBefore(moment(new Date(2011, 1, 6, 7, 8, 9, 10)), 'month'), false, 'month is earlier');\n    assert.equal(m.isBefore(moment(new Date(2011, 2, 1, 0, 0, 0, 0)), 'month'), false, 'exact start of month');\n    assert.equal(m.isBefore(moment(new Date(2011, 2, 31, 23, 59, 59, 999)), 'month'), false, 'exact end of month');\n    assert.equal(m.isBefore(moment(new Date(2011, 3, 1, 0, 0, 0, 0)), 'month'), true, 'start of next month');\n    assert.equal(m.isBefore(moment(new Date(2011, 1, 27, 23, 59, 59, 999)), 'month'), false, 'end of previous month');\n    assert.equal(m.isBefore(moment(new Date(2010, 12, 31, 23, 59, 59, 999)), 'month'), false, 'later month but earlier year');\n    assert.equal(m.isBefore(m, 'month'), false, 'same moments are not before the same month');\n    assert.equal(+m, +mCopy, 'isBefore month should not change moment');\n});\n\ntest('is before day', function (assert) {\n    var m = moment(new Date(2011, 3, 2, 3, 4, 5, 6)), mCopy = moment(m);\n    assert.equal(m.isBefore(moment(new Date(2011, 3, 2, 7, 8, 9, 10)), 'day'), false, 'day match');\n    assert.equal(m.isBefore(moment(new Date(2012, 3, 2, 7, 8, 9, 10)), 'days'), true, 'plural should work');\n    assert.equal(m.isBefore(moment(new Date(2012, 3, 2, 7, 8, 9, 10)), 'day'), true, 'year is later');\n    assert.equal(m.isBefore(moment(new Date(2010, 3, 2, 7, 8, 9, 10)), 'day'), false, 'year is earlier');\n    assert.equal(m.isBefore(moment(new Date(2011, 4, 2, 7, 8, 9, 10)), 'day'), true, 'month is later');\n    assert.equal(m.isBefore(moment(new Date(2011, 2, 2, 7, 8, 9, 10)), 'day'), false, 'month is earlier');\n    assert.equal(m.isBefore(moment(new Date(2011, 3, 3, 7, 8, 9, 10)), 'day'), true, 'day is later');\n    assert.equal(m.isBefore(moment(new Date(2011, 3, 1, 7, 8, 9, 10)), 'day'), false, 'day is earlier');\n    assert.equal(m.isBefore(moment(new Date(2011, 3, 2, 0, 0, 0, 0)), 'day'), false, 'exact start of day');\n    assert.equal(m.isBefore(moment(new Date(2011, 3, 2, 23, 59, 59, 999)), 'day'), false, 'exact end of day');\n    assert.equal(m.isBefore(moment(new Date(2011, 3, 3, 0, 0, 0, 0)), 'day'), true, 'start of next day');\n    assert.equal(m.isBefore(moment(new Date(2011, 3, 1, 23, 59, 59, 999)), 'day'), false, 'end of previous day');\n    assert.equal(m.isBefore(moment(new Date(2010, 3, 10, 0, 0, 0, 0)), 'day'), false, 'later day but earlier year');\n    assert.equal(m.isBefore(m, 'day'), false, 'same moments are not before the same day');\n    assert.equal(+m, +mCopy, 'isBefore day should not change moment');\n});\n\ntest('is before hour', function (assert) {\n    var m = moment(new Date(2011, 3, 2, 3, 4, 5, 6)), mCopy = moment(m);\n    assert.equal(m.isBefore(moment(new Date(2011, 3, 2, 3, 8, 9, 10)), 'hour'), false, 'hour match');\n    assert.equal(m.isBefore(moment(new Date(2012, 3, 2, 3, 8, 9, 10)), 'hours'), true, 'plural should work');\n    assert.equal(m.isBefore(moment(new Date(2012, 3, 2, 3, 8, 9, 10)), 'hour'), true, 'year is later');\n    assert.equal(m.isBefore(moment(new Date(2010, 3, 2, 3, 8, 9, 10)), 'hour'), false, 'year is earlier');\n    assert.equal(m.isBefore(moment(new Date(2011, 4, 2, 3, 8, 9, 10)), 'hour'), true, 'month is later');\n    assert.equal(m.isBefore(moment(new Date(2011, 1, 2, 3, 8, 9, 10)), 'hour'), false, 'month is earlier');\n    assert.equal(m.isBefore(moment(new Date(2011, 3, 3, 3, 8, 9, 10)), 'hour'), true, 'day is later');\n    assert.equal(m.isBefore(moment(new Date(2011, 3, 1, 3, 8, 9, 10)), 'hour'), false, 'day is earlier');\n    assert.equal(m.isBefore(moment(new Date(2011, 3, 2, 4, 8, 9, 10)), 'hour'), true, 'hour is later');\n    assert.equal(m.isBefore(moment(new Date(2011, 3, 2, 3, 8, 9, 10)), 'hour'), false, 'hour is earlier');\n    assert.equal(m.isBefore(moment(new Date(2011, 3, 2, 3, 0, 0, 0)), 'hour'), false, 'exact start of hour');\n    assert.equal(m.isBefore(moment(new Date(2011, 3, 2, 3, 59, 59, 999)), 'hour'), false, 'exact end of hour');\n    assert.equal(m.isBefore(moment(new Date(2011, 3, 2, 4, 0, 0, 0)), 'hour'), true, 'start of next hour');\n    assert.equal(m.isBefore(moment(new Date(2011, 3, 2, 2, 59, 59, 999)), 'hour'), false, 'end of previous hour');\n    assert.equal(m.isBefore(m, 'hour'), false, 'same moments are not before the same hour');\n    assert.equal(+m, +mCopy, 'isBefore hour should not change moment');\n});\n\ntest('is before minute', function (assert) {\n    var m = moment(new Date(2011, 3, 2, 3, 4, 5, 6)), mCopy = moment(m);\n    assert.equal(m.isBefore(moment(new Date(2011, 3, 2, 3, 4, 9, 10)), 'minute'), false, 'minute match');\n    assert.equal(m.isBefore(moment(new Date(2012, 3, 2, 3, 4, 9, 10)), 'minutes'), true, 'plural should work');\n    assert.equal(m.isBefore(moment(new Date(2012, 3, 2, 3, 4, 9, 10)), 'minute'), true, 'year is later');\n    assert.equal(m.isBefore(moment(new Date(2010, 3, 2, 3, 4, 9, 10)), 'minute'), false, 'year is earlier');\n    assert.equal(m.isBefore(moment(new Date(2011, 4, 2, 3, 4, 9, 10)), 'minute'), true, 'month is later');\n    assert.equal(m.isBefore(moment(new Date(2011, 2, 2, 3, 4, 9, 10)), 'minute'), false, 'month is earlier');\n    assert.equal(m.isBefore(moment(new Date(2011, 3, 3, 3, 4, 9, 10)), 'minute'), true, 'day is later');\n    assert.equal(m.isBefore(moment(new Date(2011, 3, 1, 3, 4, 9, 10)), 'minute'), false, 'day is earlier');\n    assert.equal(m.isBefore(moment(new Date(2011, 3, 2, 4, 4, 9, 10)), 'minute'), true, 'hour is later');\n    assert.equal(m.isBefore(moment(new Date(2011, 3, 2, 2, 4, 9, 10)), 'minute'), false, 'hour is earler');\n    assert.equal(m.isBefore(moment(new Date(2011, 3, 2, 3, 5, 9, 10)), 'minute'), true, 'minute is later');\n    assert.equal(m.isBefore(moment(new Date(2011, 3, 2, 3, 3, 9, 10)), 'minute'), false, 'minute is earlier');\n    assert.equal(m.isBefore(moment(new Date(2011, 3, 2, 3, 4, 0, 0)), 'minute'), false, 'exact start of minute');\n    assert.equal(m.isBefore(moment(new Date(2011, 3, 2, 3, 4, 59, 999)), 'minute'), false, 'exact end of minute');\n    assert.equal(m.isBefore(moment(new Date(2011, 3, 2, 3, 5, 0, 0)), 'minute'), true, 'start of next minute');\n    assert.equal(m.isBefore(moment(new Date(2011, 3, 2, 3, 3, 59, 999)), 'minute'), false, 'end of previous minute');\n    assert.equal(m.isBefore(m, 'minute'), false, 'same moments are not before the same minute');\n    assert.equal(+m, +mCopy, 'isBefore minute should not change moment');\n});\n\ntest('is before second', function (assert) {\n    var m = moment(new Date(2011, 3, 2, 3, 4, 5, 10)), mCopy = moment(m);\n    assert.equal(m.isBefore(moment(new Date(2011, 3, 2, 3, 4, 5, 10)), 'second'), false, 'second match');\n    assert.equal(m.isBefore(moment(new Date(2012, 3, 2, 3, 4, 5, 10)), 'seconds'), true, 'plural should work');\n    assert.equal(m.isBefore(moment(new Date(2012, 3, 2, 3, 4, 5, 10)), 'second'), true, 'year is later');\n    assert.equal(m.isBefore(moment(new Date(2010, 3, 2, 3, 4, 5, 10)), 'second'), false, 'year is earlier');\n    assert.equal(m.isBefore(moment(new Date(2011, 4, 2, 3, 4, 5, 10)), 'second'), true, 'month is later');\n    assert.equal(m.isBefore(moment(new Date(2011, 2, 2, 3, 4, 5, 10)), 'second'), false, 'month is earlier');\n    assert.equal(m.isBefore(moment(new Date(2011, 3, 3, 3, 4, 5, 10)), 'second'), true, 'day is later');\n    assert.equal(m.isBefore(moment(new Date(2011, 3, 1, 1, 4, 5, 10)), 'second'), false, 'day is earlier');\n    assert.equal(m.isBefore(moment(new Date(2011, 3, 2, 4, 4, 5, 10)), 'second'), true, 'hour is later');\n    assert.equal(m.isBefore(moment(new Date(2011, 3, 1, 4, 1, 5, 10)), 'second'), false, 'hour is earlier');\n    assert.equal(m.isBefore(moment(new Date(2011, 3, 2, 3, 5, 5, 10)), 'second'), true, 'minute is later');\n    assert.equal(m.isBefore(moment(new Date(2011, 3, 2, 3, 3, 5, 10)), 'second'), false, 'minute is earlier');\n    assert.equal(m.isBefore(moment(new Date(2011, 3, 2, 3, 4, 6, 10)), 'second'), true, 'second is later');\n    assert.equal(m.isBefore(moment(new Date(2011, 3, 2, 3, 4, 4, 5)), 'second'), false, 'second is earlier');\n    assert.equal(m.isBefore(moment(new Date(2011, 3, 2, 3, 4, 5, 0)), 'second'), false, 'exact start of second');\n    assert.equal(m.isBefore(moment(new Date(2011, 3, 2, 3, 4, 5, 999)), 'second'), false, 'exact end of second');\n    assert.equal(m.isBefore(moment(new Date(2011, 3, 2, 3, 4, 6, 0)), 'second'), true, 'start of next second');\n    assert.equal(m.isBefore(moment(new Date(2011, 3, 2, 3, 4, 4, 999)), 'second'), false, 'end of previous second');\n    assert.equal(m.isBefore(m, 'second'), false, 'same moments are not before the same second');\n    assert.equal(+m, +mCopy, 'isBefore second should not change moment');\n});\n\ntest('is before millisecond', function (assert) {\n    var m = moment(new Date(2011, 3, 2, 3, 4, 5, 10)), mCopy = moment(m);\n    assert.equal(m.isBefore(moment(new Date(2011, 3, 2, 3, 4, 5, 10)), 'millisecond'), false, 'millisecond match');\n    assert.equal(m.isBefore(moment(new Date(2010, 3, 2, 3, 4, 5, 10)), 'milliseconds'), false, 'plural should work');\n    assert.equal(m.isBefore(moment(new Date(2012, 3, 2, 3, 4, 5, 10)), 'millisecond'), true, 'year is later');\n    assert.equal(m.isBefore(moment(new Date(2010, 3, 2, 3, 4, 5, 10)), 'millisecond'), false, 'year is earlier');\n    assert.equal(m.isBefore(moment(new Date(2011, 4, 2, 3, 4, 5, 10)), 'millisecond'), true, 'month is later');\n    assert.equal(m.isBefore(moment(new Date(2011, 2, 2, 3, 4, 5, 10)), 'millisecond'), false, 'month is earlier');\n    assert.equal(m.isBefore(moment(new Date(2011, 3, 3, 3, 4, 5, 10)), 'millisecond'), true, 'day is later');\n    assert.equal(m.isBefore(moment(new Date(2011, 3, 1, 1, 4, 5, 10)), 'millisecond'), false, 'day is earlier');\n    assert.equal(m.isBefore(moment(new Date(2011, 3, 2, 4, 4, 5, 10)), 'millisecond'), true, 'hour is later');\n    assert.equal(m.isBefore(moment(new Date(2011, 3, 1, 4, 1, 5, 10)), 'millisecond'), false, 'hour is earlier');\n    assert.equal(m.isBefore(moment(new Date(2011, 3, 2, 3, 5, 5, 10)), 'millisecond'), true, 'minute is later');\n    assert.equal(m.isBefore(moment(new Date(2011, 3, 2, 3, 3, 5, 10)), 'millisecond'), false, 'minute is earlier');\n    assert.equal(m.isBefore(moment(new Date(2011, 3, 2, 3, 4, 6, 10)), 'millisecond'), true, 'second is later');\n    assert.equal(m.isBefore(moment(new Date(2011, 3, 2, 3, 4, 4, 5)), 'millisecond'), false, 'second is earlier');\n    assert.equal(m.isBefore(moment(new Date(2011, 3, 2, 3, 4, 6, 11)), 'millisecond'), true, 'millisecond is later');\n    assert.equal(m.isBefore(moment(new Date(2011, 3, 2, 3, 4, 4, 9)), 'millisecond'), false, 'millisecond is earlier');\n    assert.equal(m.isBefore(m, 'millisecond'), false, 'same moments are not before the same millisecond');\n    assert.equal(+m, +mCopy, 'isBefore millisecond should not change moment');\n});\n\ntest('is before invalid', function (assert) {\n    var m = moment(), invalid = moment.invalid();\n    assert.equal(m.isBefore(invalid), false, 'valid moment is not before invalid moment');\n    assert.equal(invalid.isBefore(m), false, 'invalid moment is not before valid moment');\n    assert.equal(m.isBefore(invalid, 'year'), false, 'invalid moment year');\n    assert.equal(m.isBefore(invalid, 'month'), false, 'invalid moment month');\n    assert.equal(m.isBefore(invalid, 'day'), false, 'invalid moment day');\n    assert.equal(m.isBefore(invalid, 'hour'), false, 'invalid moment hour');\n    assert.equal(m.isBefore(invalid, 'minute'), false, 'invalid moment minute');\n    assert.equal(m.isBefore(invalid, 'second'), false, 'invalid moment second');\n    assert.equal(m.isBefore(invalid, 'milliseconds'), false, 'invalid moment milliseconds');\n});\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/test/moment/is_between.js",
    "content": "import { module, test } from '../qunit';\nimport moment from '../../moment';\n\nmodule('is between');\n\ntest('is between without units', function (assert) {\n    var m = moment(new Date(2011, 3, 2, 3, 4, 5, 10)), mCopy = moment(m);\n    assert.equal(m.isBetween(\n                moment(new Date(2009, 3, 2, 3, 4, 5, 10)),\n                moment(new Date(2011, 3, 2, 3, 4, 5, 10))), false, 'year is later');\n    assert.equal(m.isBetween(\n                moment(new Date(2011, 3, 2, 3, 4, 5, 10)),\n                moment(new Date(2013, 3, 2, 3, 4, 5, 10))), false, 'year is earlier');\n    assert.equal(m.isBetween(\n                moment(new Date(2010, 3, 2, 3, 4, 5, 10)),\n                moment(new Date(2012, 3, 2, 3, 4, 5, 10))), true, 'year is between');\n    assert.equal(m.isBetween(\n                moment(new Date(2011, 1, 2, 3, 4, 5, 10)),\n                moment(new Date(2011, 3, 2, 3, 4, 5, 10))), false, 'month is later');\n    assert.equal(m.isBetween(\n                moment(new Date(2011, 3, 2, 3, 4, 5, 10)),\n                moment(new Date(2011, 5, 2, 3, 4, 5, 10))), false, 'month is earlier');\n    assert.equal(m.isBetween(\n                moment(new Date(2011, 2, 2, 3, 4, 5, 10)),\n                moment(new Date(2011, 4, 2, 3, 4, 5, 10))), true, 'month is between');\n    assert.equal(m.isBetween(\n                moment(new Date(2011, 3, 1, 3, 4, 5, 10)),\n                moment(new Date(2011, 3, 2, 3, 4, 5, 10))), false, 'day is later');\n    assert.equal(m.isBetween(\n                moment(new Date(2011, 3, 2, 3, 4, 5, 10)),\n                moment(new Date(2011, 3, 4, 3, 4, 5, 10))), false, 'day is earlier');\n    assert.equal(m.isBetween(\n                moment(new Date(2011, 3, 1, 3, 4, 5, 10)),\n                moment(new Date(2011, 3, 3, 3, 4, 5, 10))), true, 'day is between');\n    assert.equal(m.isBetween(\n                moment(new Date(2011, 3, 2, 1, 4, 5, 10)),\n                moment(new Date(2011, 3, 2, 3, 4, 5, 10))), false, 'hour is later');\n    assert.equal(m.isBetween(\n                moment(new Date(2011, 3, 2, 3, 4, 5, 10)),\n                moment(new Date(2011, 3, 2, 5, 4, 5, 10))), false, 'hour is earlier');\n    assert.equal(m.isBetween(\n                moment(new Date(2011, 3, 2, 2, 4, 5, 10)),\n                moment(new Date(2011, 3, 2, 4, 4, 5, 10))), true, 'hour is between');\n    assert.equal(m.isBetween(\n                moment(new Date(2011, 3, 2, 3, 4, 5, 10)),\n                moment(new Date(2011, 3, 2, 3, 6, 5, 10))), false, 'minute is later');\n    assert.equal(m.isBetween(\n                moment(new Date(2011, 3, 2, 3, 2, 5, 10)),\n                moment(new Date(2011, 3, 2, 3, 4, 5, 10))), false, 'minute is earlier');\n    assert.equal(m.isBetween(\n                moment(new Date(2011, 3, 2, 3, 3, 5, 10)),\n                moment(new Date(2011, 3, 2, 3, 5, 5, 10))), true, 'minute is between');\n    assert.equal(m.isBetween(\n                moment(new Date(2011, 3, 2, 3, 4, 5, 10)),\n                moment(new Date(2011, 3, 2, 3, 4, 7, 10))), false, 'second is later');\n    assert.equal(m.isBetween(\n                moment(new Date(2011, 3, 2, 3, 4, 3, 10)),\n                moment(new Date(2011, 3, 2, 3, 4, 5, 10))), false, 'second is earlier');\n    assert.equal(m.isBetween(\n                moment(new Date(2011, 3, 2, 3, 4, 4, 10)),\n                moment(new Date(2011, 3, 2, 3, 4, 6, 10))), true, 'second is between');\n    assert.equal(m.isBetween(\n                moment(new Date(2011, 3, 2, 3, 4, 5, 10)),\n                moment(new Date(2011, 3, 2, 3, 4, 5, 12))), false, 'millisecond is later');\n    assert.equal(m.isBetween(\n                moment(new Date(2011, 3, 2, 3, 4, 5, 8)),\n                moment(new Date(2011, 3, 2, 3, 4, 5, 10))), false, 'millisecond is earlier');\n    assert.equal(m.isBetween(\n                moment(new Date(2011, 3, 2, 3, 4, 5, 9)),\n                moment(new Date(2011, 3, 2, 3, 4, 5, 11))), true, 'millisecond is between');\n    assert.equal(m.isBetween(m, m), false, 'moments are not between themselves');\n    assert.equal(+m, +mCopy, 'isBetween second should not change moment');\n});\n\ntest('is between without units inclusivity', function (assert) {\n    var m = moment(new Date(2011, 3, 2, 3, 4, 5, 10)), mCopy = moment(m);\n    assert.equal(m.isBetween(\n        moment(new Date(2011, 3, 2, 3, 4, 5, 10)),\n        moment(new Date(2012, 3, 2, 3, 4, 5, 10)), null, '()'), false, 'start and end are excluded, start is equal to moment');\n    assert.equal(m.isBetween(\n        moment(new Date(2010, 3, 2, 3, 4, 5, 10)),\n        moment(new Date(2011, 3, 2, 3, 4, 5, 10)), null, '()'), false, 'start and end are excluded, end is equal to moment');\n    assert.equal(m.isBetween(\n        moment(new Date(2010, 3, 2, 3, 4, 5, 10)),\n        moment(new Date(2012, 3, 2, 3, 4, 5, 10)), null, '()'), true, 'start and end are excluded, is between');\n    assert.equal(m.isBetween(\n        moment(new Date(2009, 3, 2, 3, 4, 5, 10)),\n        moment(new Date(2010, 3, 2, 3, 4, 5, 10)), null, '()'), false, 'start and end are excluded, is not between');\n    assert.equal(m.isBetween(\n        moment(new Date(2011, 3, 2, 3, 4, 5, 10)),\n        moment(new Date(2011, 3, 2, 3, 4, 5, 10)), null, '()'), false, 'start and end are excluded, should fail on same start/end date.');\n\n    assert.equal(m.isBetween(\n        moment(new Date(2011, 3, 2, 3, 4, 5, 10)),\n        moment(new Date(2012, 3, 2, 3, 4, 5, 10)), null, '(]'), false, 'start is excluded and end is included should fail on same start date');\n    assert.equal(m.isBetween(\n        moment(new Date(2010, 3, 2, 3, 4, 5, 10)),\n        moment(new Date(2011, 3, 2, 3, 4, 5, 10)), null, '(]'), true, 'start is excluded and end is included should succeed on end date');\n    assert.equal(m.isBetween(\n        moment(new Date(2010, 3, 2, 3, 4, 5, 10)),\n        moment(new Date(2012, 3, 2, 3, 4, 5, 10)), null, '(]'), true, 'start is excluded and end is included, is between');\n    assert.equal(m.isBetween(\n        moment(new Date(2009, 3, 2, 3, 4, 5, 10)),\n        moment(new Date(2010, 3, 2, 3, 4, 5, 10)), null, '(]'), false, 'start is excluded and end is included, is not between');\n    assert.equal(m.isBetween(\n        moment(new Date(2011, 3, 2, 3, 4, 5, 10)),\n        moment(new Date(2011, 3, 2, 3, 4, 5, 10)), null, '(]'), false, 'start is excluded and end is included, should fail on same start/end date.');\n\n    assert.equal(m.isBetween(\n        moment(new Date(2011, 3, 2, 3, 4, 5, 10)),\n        moment(new Date(2012, 3, 2, 3, 4, 5, 10)), null, '[)'), true, 'start is included and end is excluded should succeed on same start date');\n    assert.equal(m.isBetween(\n        moment(new Date(2010, 3, 2, 3, 4, 5, 10)),\n        moment(new Date(2011, 3, 2, 3, 4, 5, 10)), null, '[)'), false, 'start is included and end is excluded should fail on same end date');\n    assert.equal(m.isBetween(\n        moment(new Date(2010, 3, 2, 3, 4, 5, 10)),\n        moment(new Date(2012, 3, 2, 3, 4, 5, 10)), null, '[)'), true, 'start is included and end is excluded, is between');\n    assert.equal(m.isBetween(\n        moment(new Date(2009, 3, 2, 3, 4, 5, 10)),\n        moment(new Date(2010, 3, 2, 3, 4, 5, 10)), null, '[)'), false, 'start is included and end is excluded, is not between');\n    assert.equal(m.isBetween(\n        moment(new Date(2011, 3, 2, 3, 4, 5, 10)),\n        moment(new Date(2011, 3, 2, 3, 4, 5, 10)), null, '[)'), false, 'start is included and end is excluded, should fail on same end and start date');\n\n    assert.equal(m.isBetween(\n        moment(new Date(2011, 3, 2, 3, 4, 5, 10)),\n        moment(new Date(2012, 3, 2, 3, 4, 5, 10)), null, '[]'), true, 'start and end inclusive should succeed on same start date');\n    assert.equal(m.isBetween(\n        moment(new Date(2010, 3, 2, 3, 4, 5, 10)),\n        moment(new Date(2011, 3, 2, 3, 4, 5, 10)), null, '[]'), true, 'start and end inclusive should succeed on same end date');\n    assert.equal(m.isBetween(\n        moment(new Date(2010, 3, 2, 3, 4, 5, 10)),\n        moment(new Date(2012, 3, 2, 3, 4, 5, 10)), null, '[]'), true, 'start and end inclusive, is between');\n    assert.equal(m.isBetween(\n        moment(new Date(2009, 3, 2, 3, 4, 5, 10)),\n        moment(new Date(2010, 3, 2, 3, 4, 5, 10)), null, '[]'), false, 'start and end inclusive, is not between');\n    assert.equal(m.isBetween(\n        moment(new Date(2011, 3, 2, 3, 4, 5, 10)),\n        moment(new Date(2011, 3, 2, 3, 4, 5, 10)), null, '[]'), true, 'start and end inclusive, should handle same end and start date');\n});\n\ntest('is between milliseconds inclusivity', function (assert) {\n    var m = moment(new Date(2011, 3, 2, 3, 4, 5, 10)), mCopy = moment(m);\n    assert.equal(m.isBetween(\n        moment(new Date(2010, 3, 2, 3, 4, 5, 10)),\n        moment(new Date(2012, 3, 2, 3, 4, 5, 10)), 'milliseconds'), true, 'options, no inclusive');\n    assert.equal(m.isBetween(\n        moment(new Date(2011, 3, 2, 3, 4, 5, 10)),\n        moment(new Date(2012, 3, 2, 3, 4, 5, 10)), 'milliseconds', '()'), false, 'start and end are excluded, start is equal to moment');\n    assert.equal(m.isBetween(\n        moment(new Date(2010, 3, 2, 3, 4, 5, 10)),\n        moment(new Date(2011, 3, 2, 3, 4, 5, 10)), 'milliseconds', '()'), false, 'start and end are excluded, end is equal to moment');\n    assert.equal(m.isBetween(\n        moment(new Date(2010, 3, 2, 3, 4, 5, 10)),\n        moment(new Date(2012, 3, 2, 3, 4, 5, 10)), 'milliseconds', '()'), true, 'start and end are excluded, is between');\n    assert.equal(m.isBetween(\n        moment(new Date(2009, 3, 2, 3, 4, 5, 10)),\n        moment(new Date(2010, 3, 2, 3, 4, 5, 10)), 'milliseconds', '()'), false, 'start and end are excluded, is not between');\n    assert.equal(m.isBetween(\n        moment(new Date(2011, 3, 2, 3, 4, 5, 10)),\n        moment(new Date(2011, 3, 2, 3, 4, 5, 10)), 'milliseconds', '()'), false, 'start and end are excluded, should fail on same start/end date.');\n\n    assert.equal(m.isBetween(\n        moment(new Date(2011, 3, 2, 3, 4, 5, 10)),\n        moment(new Date(2012, 3, 2, 3, 4, 5, 10)), 'milliseconds', '(]'), false, 'start is excluded and end is included should fail on same start date');\n    assert.equal(m.isBetween(\n        moment(new Date(2010, 3, 2, 3, 4, 5, 10)),\n        moment(new Date(2011, 3, 2, 3, 4, 5, 10)), 'milliseconds', '(]'), true, 'start is excluded and end is included should succeed on end date');\n    assert.equal(m.isBetween(\n        moment(new Date(2010, 3, 2, 3, 4, 5, 10)),\n        moment(new Date(2012, 3, 2, 3, 4, 5, 10)), 'milliseconds', '(]'), true, 'start is excluded and end is included, is between');\n    assert.equal(m.isBetween(\n        moment(new Date(2009, 3, 2, 3, 4, 5, 10)),\n        moment(new Date(2010, 3, 2, 3, 4, 5, 10)), 'milliseconds', '(]'), false, 'start is excluded and end is included, is not between');\n    assert.equal(m.isBetween(\n        moment(new Date(2011, 3, 2, 3, 4, 5, 10)),\n        moment(new Date(2011, 3, 2, 3, 4, 5, 10)), 'milliseconds', '(]'), false, 'start is excluded and end is included, should fail on same start/end date.');\n\n    assert.equal(m.isBetween(\n        moment(new Date(2011, 3, 2, 3, 4, 5, 10)),\n        moment(new Date(2012, 3, 2, 3, 4, 5, 10)), 'milliseconds', '[)'), true, 'start is included and end is excluded should succeed on same start date');\n    assert.equal(m.isBetween(\n        moment(new Date(2010, 3, 2, 3, 4, 5, 10)),\n        moment(new Date(2011, 3, 2, 3, 4, 5, 10)), 'milliseconds', '[)'), false, 'start is included and end is excluded should fail on same end date');\n    assert.equal(m.isBetween(\n        moment(new Date(2010, 3, 2, 3, 4, 5, 10)),\n        moment(new Date(2012, 3, 2, 3, 4, 5, 10)), 'milliseconds', '[)'), true, 'start is included and end is excluded, is between');\n    assert.equal(m.isBetween(\n        moment(new Date(2009, 3, 2, 3, 4, 5, 10)),\n        moment(new Date(2010, 3, 2, 3, 4, 5, 10)), 'milliseconds', '[)'), false, 'start is included and end is excluded, is not between');\n    assert.equal(m.isBetween(\n        moment(new Date(2011, 3, 2, 3, 4, 5, 10)),\n        moment(new Date(2011, 3, 2, 3, 4, 5, 10)), 'milliseconds', '[)'), false, 'start is included and end is excluded, should fail on same end and start date');\n\n    assert.equal(m.isBetween(\n        moment(new Date(2011, 3, 2, 3, 4, 5, 10)),\n        moment(new Date(2012, 3, 2, 3, 4, 5, 10)), 'milliseconds', '[]'), true, 'start and end inclusive should succeed on same start date');\n    assert.equal(m.isBetween(\n        moment(new Date(2010, 3, 2, 3, 4, 5, 10)),\n        moment(new Date(2011, 3, 2, 3, 4, 5, 10)), 'milliseconds', '[]'), true, 'start and end inclusive should succeed on same end date');\n    assert.equal(m.isBetween(\n        moment(new Date(2010, 3, 2, 3, 4, 5, 10)),\n        moment(new Date(2012, 3, 2, 3, 4, 5, 10)), 'milliseconds', '[]'), true, 'start and end inclusive, is between');\n    assert.equal(m.isBetween(\n        moment(new Date(2009, 3, 2, 3, 4, 5, 10)),\n        moment(new Date(2010, 3, 2, 3, 4, 5, 10)), 'milliseconds', '[]'), false, 'start and end inclusive, is not between');\n    assert.equal(m.isBetween(\n        moment(new Date(2011, 3, 2, 3, 4, 5, 10)),\n        moment(new Date(2011, 3, 2, 3, 4, 5, 10)), 'milliseconds', '[]'), true, 'start and end inclusive, should handle same end and start date');\n});\n\ntest('is between year', function (assert) {\n    var m = moment(new Date(2011, 1, 2, 3, 4, 5, 6)), mCopy = moment(m);\n    assert.equal(m.isBetween(\n                moment(new Date(2011, 5, 6, 7, 8, 9, 10)),\n                moment(new Date(2011, 5, 6, 7, 8, 9, 10)), 'year'), false, 'year match');\n    assert.equal(m.isBetween(\n                moment(new Date(2010, 5, 6, 7, 8, 9, 10)),\n                moment(new Date(2012, 5, 6, 7, 8, 9, 10)), 'years'), true, 'plural should work');\n    assert.equal(m.isBetween(\n                moment(new Date(2010, 5, 6, 7, 8, 9, 10)),\n                moment(new Date(2012, 5, 6, 7, 8, 9, 10)), 'year'), true, 'year is between');\n    assert.equal(m.isBetween(\n                moment(new Date(2011, 5, 6, 7, 8, 9, 10)),\n                moment(new Date(2013, 5, 6, 7, 8, 9, 10)), 'year'), false, 'year is earlier');\n    assert.equal(m.isBetween(\n                moment(new Date(2010, 5, 6, 7, 8, 9, 10)),\n                moment(new Date(2011, 5, 6, 7, 8, 9, 10)), 'year'), false, 'year is later');\n    assert.equal(m.isBetween(m, 'year'), false, 'same moments are not between the same year');\n    assert.equal(+m, +mCopy, 'isBetween year should not change moment');\n});\n\ntest('is between month', function (assert) {\n    var m = moment(new Date(2011, 1, 2, 3, 4, 5, 6)), mCopy = moment(m);\n    assert.equal(m.isBetween(\n                moment(new Date(2011, 1, 6, 7, 8, 9, 10)),\n                moment(new Date(2011, 1, 6, 7, 8, 9, 10)), 'month'), false, 'month match');\n    assert.equal(m.isBetween(\n                moment(new Date(2011, 0, 6, 7, 8, 9, 10)),\n                moment(new Date(2011, 2, 6, 7, 8, 9, 10)), 'months'), true, 'plural should work');\n    assert.equal(m.isBetween(\n                moment(new Date(2011, 0, 31, 23, 59, 59, 999)),\n                moment(new Date(2011, 2, 1, 0, 0, 0, 0)), 'month'), true, 'month is between');\n    assert.equal(m.isBetween(\n                moment(new Date(2011, 1, 6, 7, 8, 9, 10)),\n                moment(new Date(2011, 2, 6, 7, 8, 9, 10)), 'month'), false, 'month is earlier');\n    assert.equal(m.isBetween(\n                moment(new Date(2011, 11, 6, 7, 8, 9, 10)),\n                moment(new Date(2011, 1, 6, 7, 8, 9, 10)), 'month'), false, 'month is later');\n    assert.equal(m.isBetween(m, 'month'), false, 'same moments are not between the same month');\n    assert.equal(+m, +mCopy, 'isBetween month should not change moment');\n});\n\ntest('is between day', function (assert) {\n    var m = moment(new Date(2011, 1, 2, 3, 4, 5, 6)), mCopy = moment(m);\n    assert.equal(m.isBetween(\n                moment(new Date(2011, 1, 2, 7, 8, 9, 10)),\n                moment(new Date(2011, 1, 2, 7, 8, 9, 10)), 'day'), false, 'day match');\n    assert.equal(m.isBetween(\n                moment(new Date(2011, 1, 1, 7, 8, 9, 10)),\n                moment(new Date(2011, 1, 3, 7, 8, 9, 10)), 'days'), true, 'plural should work');\n    assert.equal(m.isBetween(\n                moment(new Date(2011, 1, 1, 7, 8, 9, 10)),\n                moment(new Date(2011, 1, 3, 7, 8, 9, 10)), 'day'), true, 'day is between');\n    assert.equal(m.isBetween(\n                moment(new Date(2011, 1, 2, 7, 8, 9, 10)),\n                moment(new Date(2011, 1, 4, 7, 8, 9, 10)), 'day'), false, 'day is earlier');\n    assert.equal(m.isBetween(\n                moment(new Date(2011, 1, 1, 7, 8, 9, 10)),\n                moment(new Date(2011, 1, 2, 7, 8, 9, 10)), 'day'), false, 'day is later');\n    assert.equal(m.isBetween(m, 'day'), false, 'same moments are not between the same day');\n    assert.equal(+m, +mCopy, 'isBetween day should not change moment');\n});\n\ntest('is between hour', function (assert) {\n    var m = moment(new Date(2011, 1, 2, 3, 4, 5, 6)), mCopy = moment(m);\n    assert.equal(m.isBetween(\n                moment(new Date(2011, 1, 2, 3, 5, 9, 10)),\n                moment(new Date(2011, 1, 2, 3, 9, 9, 10)), 'hour'), false, 'hour match');\n    assert.equal(m.isBetween(\n                moment(new Date(2011, 1, 2, 1, 59, 59, 999)),\n                moment(new Date(2011, 1, 2, 4, 0, 0, 0)), 'hours'), true, 'plural should work');\n    assert.equal(m.isBetween(\n                moment(new Date(2011, 1, 2, 2, 59, 59, 999)),\n                moment(new Date(2011, 1, 2, 4, 0, 0, 0)), 'hour'), true, 'hour is between');\n    assert.equal(m.isBetween(\n                moment(new Date(2011, 1, 2, 7, 8, 9, 10)),\n                moment(new Date(2011, 1, 2, 7, 8, 9, 10)), 'hour'), false, 'hour is earlier');\n    assert.equal(m.isBetween(\n                moment(new Date(2011, 1, 2, 7, 8, 9, 10)),\n                moment(new Date(2011, 1, 2, 7, 8, 9, 10)), 'hour'), false, 'hour is later');\n    assert.equal(m.isBetween(m, 'hour'), false, 'same moments are not between the same hour');\n    assert.equal(+m, +mCopy, 'isBetween hour should not change moment');\n});\n\ntest('is between minute', function (assert) {\n    var m = moment(new Date(2011, 1, 2, 3, 4, 5, 6)), mCopy = moment(m);\n    assert.equal(m.isBetween(\n                moment(new Date(2011, 1, 2, 3, 4, 9, 10)),\n                moment(new Date(2011, 1, 2, 3, 4, 9, 10)), 'minute'), false, 'minute match');\n    assert.equal(m.isBetween(\n                moment(new Date(2011, 1, 2, 3, 3, 9, 10)),\n                moment(new Date(2011, 1, 2, 3, 5, 9, 10)), 'minutes'), true, 'plural should work');\n    assert.equal(m.isBetween(\n                moment(new Date(2011, 1, 2, 3, 3, 59, 999)),\n                moment(new Date(2011, 1, 2, 3, 5, 0, 0)), 'minute'), true, 'minute is between');\n    assert.equal(m.isBetween(\n                moment(new Date(2011, 1, 2, 3, 5, 0, 0)),\n                moment(new Date(2011, 1, 2, 3, 8, 9, 10)), 'minute'), false, 'minute is earlier');\n    assert.equal(m.isBetween(\n                moment(new Date(2011, 1, 2, 3, 2, 9, 10)),\n                moment(new Date(2011, 1, 2, 3, 3, 59, 999)), 'minute'), false, 'minute is later');\n    assert.equal(m.isBetween(m, 'minute'), false, 'same moments are not between the same minute');\n    assert.equal(+m, +mCopy, 'isBetween minute should not change moment');\n});\n\ntest('is between second', function (assert) {\n    var m = moment(new Date(2011, 1, 2, 3, 4, 5, 6)), mCopy = moment(m);\n    assert.equal(m.isBetween(\n                moment(new Date(2011, 1, 2, 3, 4, 5, 10)),\n                moment(new Date(2011, 1, 2, 3, 4, 5, 10)), 'second'), false, 'second match');\n    assert.equal(m.isBetween(\n                moment(new Date(2011, 1, 2, 3, 4, 4, 10)),\n                moment(new Date(2011, 1, 2, 3, 4, 6, 10)), 'seconds'), true, 'plural should work');\n    assert.equal(m.isBetween(\n                moment(new Date(2011, 1, 2, 3, 4, 4, 999)),\n                moment(new Date(2011, 1, 2, 3, 4, 6, 0)), 'second'), true, 'second is between');\n    assert.equal(m.isBetween(\n                moment(new Date(2011, 1, 2, 3, 4, 6, 0)),\n                moment(new Date(2011, 1, 2, 3, 4, 7, 10)), 'second'), false, 'second is earlier');\n    assert.equal(m.isBetween(\n                moment(new Date(2011, 1, 2, 3, 4, 3, 10)),\n                moment(new Date(2011, 1, 2, 3, 4, 4, 999)), 'second'), false, 'second is later');\n    assert.equal(m.isBetween(m, 'second'), false, 'same moments are not between the same second');\n    assert.equal(+m, +mCopy, 'isBetween second should not change moment');\n});\n\ntest('is between millisecond', function (assert) {\n    var m = moment(new Date(2011, 1, 2, 3, 4, 5, 6)), mCopy = moment(m);\n    assert.equal(m.isBetween(\n                moment(new Date(2011, 1, 2, 3, 4, 5, 6)),\n                moment(new Date(2011, 1, 2, 3, 4, 5, 6)), 'millisecond'), false, 'millisecond match');\n    assert.equal(m.isBetween(\n                moment(new Date(2011, 1, 2, 3, 4, 5, 5)),\n                moment(new Date(2011, 1, 2, 3, 4, 5, 7)), 'milliseconds'), true, 'plural should work');\n    assert.equal(m.isBetween(\n                moment(new Date(2011, 1, 2, 3, 4, 5, 5)),\n                moment(new Date(2011, 1, 2, 3, 4, 5, 7)), 'millisecond'), true, 'millisecond is between');\n    assert.equal(m.isBetween(\n                moment(new Date(2011, 1, 2, 3, 4, 5, 7)),\n                moment(new Date(2011, 1, 2, 3, 4, 5, 10)), 'millisecond'), false, 'millisecond is earlier');\n    assert.equal(m.isBetween(\n                moment(new Date(2011, 1, 2, 3, 4, 5, 4)),\n                moment(new Date(2011, 1, 2, 3, 4, 5, 6)), 'millisecond'), false, 'millisecond is later');\n    assert.equal(m.isBetween(m, 'millisecond'), false, 'same moments are not between the same millisecond');\n    assert.equal(+m, +mCopy, 'isBetween millisecond should not change moment');\n});\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/test/moment/is_date.js",
    "content": "import { module, test } from '../qunit';\nimport moment from '../../moment';\n\nmodule('is date');\n\ntest('isDate recognizes Date objects', function (assert) {\n    assert.ok(moment.isDate(new Date()), 'no args (now)');\n    assert.ok(moment.isDate(new Date([2014, 2, 15])), 'array args');\n    assert.ok(moment.isDate(new Date('2014-03-15')), 'string args');\n    assert.ok(moment.isDate(new Date('does NOT look like a date')), 'invalid date');\n});\n\ntest('isDate rejects non-Date objects', function (assert) {\n    assert.ok(!moment.isDate(), 'nothing');\n    assert.ok(!moment.isDate(undefined), 'undefined');\n    assert.ok(!moment.isDate(null), 'string args');\n    assert.ok(!moment.isDate(42), 'number');\n    assert.ok(!moment.isDate('2014-03-15'), 'string');\n    assert.ok(!moment.isDate([2014, 2, 15]), 'array');\n    assert.ok(!moment.isDate({year: 2014, month: 2, day: 15}), 'object');\n    assert.ok(!moment.isDate({\n        toString: function () {\n            return '[object Date]';\n        }\n    }), 'lying object');\n});\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/test/moment/is_moment.js",
    "content": "import { module, test } from '../qunit';\nimport moment from '../../moment';\n\nmodule('is moment');\n\ntest('is moment object', function (assert) {\n    var MyObj = function () {},\n        extend = function (a, b) {\n            var i;\n            for (i in b) {\n                a[i] = b[i];\n            }\n            return a;\n        };\n    MyObj.prototype.toDate = function () {\n        return new Date();\n    };\n\n    assert.ok(moment.isMoment(moment()), 'simple moment object');\n    assert.ok(moment.isMoment(moment(null)), 'invalid moment object');\n    assert.ok(moment.isMoment(extend({}, moment())), 'externally cloned moments are moments');\n    assert.ok(moment.isMoment(extend({}, moment.utc())), 'externally cloned utc moments are moments');\n\n    assert.ok(!moment.isMoment(new MyObj()), 'myObj is not moment object');\n    assert.ok(!moment.isMoment(moment), 'moment function is not moment object');\n    assert.ok(!moment.isMoment(new Date()), 'date object is not moment object');\n    assert.ok(!moment.isMoment(Object), 'Object is not moment object');\n    assert.ok(!moment.isMoment('foo'), 'string is not moment object');\n    assert.ok(!moment.isMoment(1), 'number is not moment object');\n    assert.ok(!moment.isMoment(NaN), 'NaN is not moment object');\n    assert.ok(!moment.isMoment(null), 'null is not moment object');\n    assert.ok(!moment.isMoment(undefined), 'undefined is not moment object');\n});\n\ntest('is moment with hacked hasOwnProperty', function (assert) {\n    var obj = {};\n    // HACK to suppress jshint warning about bad property name\n    obj['hasOwnMoney'.replace('Money', 'Property')] = function () {\n        return true;\n    };\n\n    assert.ok(!moment.isMoment(obj), 'isMoment works even if passed object has a wrong hasOwnProperty implementation (ie8)');\n});\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/test/moment/is_number.js",
    "content": "import { module, test } from '../qunit';\nimport isNumber from '../../lib/utils/is-number.js';\n\n\ntest('isNumber recognizes numbers', function (assert) {\n    assert.ok(isNumber(1), 'simple integer');\n    assert.ok(isNumber(0), 'simple number');\n    assert.ok(isNumber(-0), 'silly number');\n    assert.ok(isNumber(1010010293029), 'large number');\n    assert.ok(isNumber(Infinity), 'largest number');\n    assert.ok(isNumber(-Infinity), 'smallest number');\n    assert.ok(isNumber(NaN), 'not number');\n    assert.ok(isNumber(1.100393830000), 'decimal numbers');\n    assert.ok(isNumber(Math.LN2), 'natural log of two');\n    assert.ok(isNumber(Math.PI), 'delicious number');\n    assert.ok(isNumber(5e10), 'scientifically notated number');\n    assert.ok(isNumber(new Number(1)), 'number primitive wrapped in an object'); // jshint ignore:line\n});\n\ntest('isNumber rejects non-numbers', function (assert) {\n    assert.ok(!isNumber(), 'nothing');\n    assert.ok(!isNumber(undefined), 'undefined');\n    assert.ok(!isNumber(null), 'null');\n    assert.ok(!isNumber([1]), 'array');\n    assert.ok(!isNumber('[1,2,3]'), 'string');\n    assert.ok(!isNumber(new Date()), 'date');\n    assert.ok(!isNumber({a:1,b:2}), 'object');\n});\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/test/moment/is_same.js",
    "content": "import { module, test } from '../qunit';\nimport moment from '../../moment';\n\nmodule('is same');\n\ntest('is same without units', function (assert) {\n    var m = moment(new Date(2011, 3, 2, 3, 4, 5, 10)), mCopy = moment(m);\n    assert.equal(m.isSame(moment(new Date(2012, 3, 2, 3, 5, 5, 10))), false, 'year is later');\n    assert.equal(m.isSame(moment(new Date(2010, 3, 2, 3, 3, 5, 10))), false, 'year is earlier');\n    assert.equal(m.isSame(moment(new Date(2011, 4, 2, 3, 4, 5, 10))), false, 'month is later');\n    assert.equal(m.isSame(moment(new Date(2011, 2, 2, 3, 4, 5, 10))), false, 'month is earlier');\n    assert.equal(m.isSame(moment(new Date(2011, 3, 3, 3, 4, 5, 10))), false, 'day is later');\n    assert.equal(m.isSame(moment(new Date(2011, 3, 1, 3, 4, 5, 10))), false, 'day is earlier');\n    assert.equal(m.isSame(moment(new Date(2011, 3, 2, 4, 4, 5, 10))), false, 'hour is later');\n    assert.equal(m.isSame(moment(new Date(2011, 3, 2, 2, 4, 5, 10))), false, 'hour is earlier');\n    assert.equal(m.isSame(moment(new Date(2011, 3, 2, 3, 5, 5, 10))), false, 'minute is later');\n    assert.equal(m.isSame(moment(new Date(2011, 3, 2, 3, 3, 5, 10))), false, 'minute is earlier');\n    assert.equal(m.isSame(moment(new Date(2011, 3, 2, 3, 4, 6, 10))), false, 'second is later');\n    assert.equal(m.isSame(moment(new Date(2011, 3, 2, 3, 4, 4, 11))), false, 'second is earlier');\n    assert.equal(m.isSame(moment(new Date(2011, 3, 2, 3, 4, 5, 10))), true, 'millisecond match');\n    assert.equal(m.isSame(moment(new Date(2011, 3, 2, 3, 4, 5, 11))), false, 'millisecond is later');\n    assert.equal(m.isSame(moment(new Date(2011, 3, 2, 3, 4, 5, 9))), false, 'millisecond is earlier');\n    assert.equal(m.isSame(m), true, 'moments are the same as themselves');\n    assert.equal(+m, +mCopy, 'isSame second should not change moment');\n});\n\ntest('is same year', function (assert) {\n    var m = moment(new Date(2011, 1, 2, 3, 4, 5, 6)), mCopy = moment(m);\n    assert.equal(m.isSame(moment(new Date(2011, 5, 6, 7, 8, 9, 10)), 'year'), true, 'year match');\n    assert.equal(m.isSame(moment(new Date(2011, 5, 6, 7, 8, 9, 10)), 'years'), true, 'plural should work');\n    assert.equal(m.isSame(moment(new Date(2012, 5, 6, 7, 8, 9, 10)), 'year'), false, 'year mismatch');\n    assert.equal(m.isSame(moment(new Date(2011, 0, 1, 0, 0, 0, 0)), 'year'), true, 'exact start of year');\n    assert.equal(m.isSame(moment(new Date(2011, 11, 31, 23, 59, 59, 999)), 'year'), true, 'exact end of year');\n    assert.equal(m.isSame(moment(new Date(2012, 0, 1, 0, 0, 0, 0)), 'year'), false, 'start of next year');\n    assert.equal(m.isSame(moment(new Date(2010, 11, 31, 23, 59, 59, 999)), 'year'), false, 'end of previous year');\n    assert.equal(m.isSame(m, 'year'), true, 'same moments are in the same year');\n    assert.equal(+m, +mCopy, 'isSame year should not change moment');\n});\n\ntest('is same month', function (assert) {\n    var m = moment(new Date(2011, 2, 3, 4, 5, 6, 7)), mCopy = moment(m);\n    assert.equal(m.isSame(moment(new Date(2011, 2, 6, 7, 8, 9, 10)), 'month'), true, 'month match');\n    assert.equal(m.isSame(moment(new Date(2011, 2, 6, 7, 8, 9, 10)), 'months'), true, 'plural should work');\n    assert.equal(m.isSame(moment(new Date(2012, 2, 6, 7, 8, 9, 10)), 'month'), false, 'year mismatch');\n    assert.equal(m.isSame(moment(new Date(2011, 5, 6, 7, 8, 9, 10)), 'month'), false, 'month mismatch');\n    assert.equal(m.isSame(moment(new Date(2011, 2, 1, 0, 0, 0, 0)), 'month'), true, 'exact start of month');\n    assert.equal(m.isSame(moment(new Date(2011, 2, 31, 23, 59, 59, 999)), 'month'), true, 'exact end of month');\n    assert.equal(m.isSame(moment(new Date(2011, 3, 1, 0, 0, 0, 0)), 'month'), false, 'start of next month');\n    assert.equal(m.isSame(moment(new Date(2011, 1, 27, 23, 59, 59, 999)), 'month'), false, 'end of previous month');\n    assert.equal(m.isSame(m, 'month'), true, 'same moments are in the same month');\n    assert.equal(+m, +mCopy, 'isSame month should not change moment');\n});\n\ntest('is same day', function (assert) {\n    var m = moment(new Date(2011, 1, 2, 3, 4, 5, 6)), mCopy = moment(m);\n    assert.equal(m.isSame(moment(new Date(2011, 1, 2, 7, 8, 9, 10)), 'day'), true, 'day match');\n    assert.equal(m.isSame(moment(new Date(2011, 1, 2, 7, 8, 9, 10)), 'days'), true, 'plural should work');\n    assert.equal(m.isSame(moment(new Date(2012, 1, 2, 7, 8, 9, 10)), 'day'), false, 'year mismatch');\n    assert.equal(m.isSame(moment(new Date(2011, 2, 2, 7, 8, 9, 10)), 'day'), false, 'month mismatch');\n    assert.equal(m.isSame(moment(new Date(2011, 1, 3, 7, 8, 9, 10)), 'day'), false, 'day mismatch');\n    assert.equal(m.isSame(moment(new Date(2011, 1, 2, 0, 0, 0, 0)), 'day'), true, 'exact start of day');\n    assert.equal(m.isSame(moment(new Date(2011, 1, 2, 23, 59, 59, 999)), 'day'), true, 'exact end of day');\n    assert.equal(m.isSame(moment(new Date(2011, 1, 3, 0, 0, 0, 0)), 'day'), false, 'start of next day');\n    assert.equal(m.isSame(moment(new Date(2011, 1, 1, 23, 59, 59, 999)), 'day'), false, 'end of previous day');\n    assert.equal(m.isSame(m, 'day'), true, 'same moments are in the same day');\n    assert.equal(+m, +mCopy, 'isSame day should not change moment');\n});\n\ntest('is same hour', function (assert) {\n    var m = moment(new Date(2011, 1, 2, 3, 4, 5, 6)), mCopy = moment(m);\n    assert.equal(m.isSame(moment(new Date(2011, 1, 2, 3, 8, 9, 10)), 'hour'), true, 'hour match');\n    assert.equal(m.isSame(moment(new Date(2011, 1, 2, 3, 8, 9, 10)), 'hours'), true, 'plural should work');\n    assert.equal(m.isSame(moment(new Date(2012, 1, 2, 3, 8, 9, 10)), 'hour'), false, 'year mismatch');\n    assert.equal(m.isSame(moment(new Date(2011, 2, 2, 3, 8, 9, 10)), 'hour'), false, 'month mismatch');\n    assert.equal(m.isSame(moment(new Date(2011, 1, 3, 3, 8, 9, 10)), 'hour'), false, 'day mismatch');\n    assert.equal(m.isSame(moment(new Date(2011, 1, 2, 4, 8, 9, 10)), 'hour'), false, 'hour mismatch');\n    assert.equal(m.isSame(moment(new Date(2011, 1, 2, 3, 0, 0, 0)), 'hour'), true, 'exact start of hour');\n    assert.equal(m.isSame(moment(new Date(2011, 1, 2, 3, 59, 59, 999)), 'hour'), true, 'exact end of hour');\n    assert.equal(m.isSame(moment(new Date(2011, 1, 2, 4, 0, 0, 0)), 'hour'), false, 'start of next hour');\n    assert.equal(m.isSame(moment(new Date(2011, 1, 2, 2, 59, 59, 999)), 'hour'), false, 'end of previous hour');\n    assert.equal(m.isSame(m, 'hour'), true, 'same moments are in the same hour');\n    assert.equal(+m, +mCopy, 'isSame hour should not change moment');\n});\n\ntest('is same minute', function (assert) {\n    var m = moment(new Date(2011, 1, 2, 3, 4, 5, 6)), mCopy = moment(m);\n    assert.equal(m.isSame(moment(new Date(2011, 1, 2, 3, 4, 9, 10)), 'minute'), true, 'minute match');\n    assert.equal(m.isSame(moment(new Date(2011, 1, 2, 3, 4, 9, 10)), 'minutes'), true, 'plural should work');\n    assert.equal(m.isSame(moment(new Date(2012, 1, 2, 3, 4, 9, 10)), 'minute'), false, 'year mismatch');\n    assert.equal(m.isSame(moment(new Date(2011, 2, 2, 3, 4, 9, 10)), 'minute'), false, 'month mismatch');\n    assert.equal(m.isSame(moment(new Date(2011, 1, 3, 3, 4, 9, 10)), 'minute'), false, 'day mismatch');\n    assert.equal(m.isSame(moment(new Date(2011, 1, 2, 4, 4, 9, 10)), 'minute'), false, 'hour mismatch');\n    assert.equal(m.isSame(moment(new Date(2011, 1, 2, 3, 5, 9, 10)), 'minute'), false, 'minute mismatch');\n    assert.equal(m.isSame(moment(new Date(2011, 1, 2, 3, 4, 0, 0)), 'minute'), true, 'exact start of minute');\n    assert.equal(m.isSame(moment(new Date(2011, 1, 2, 3, 4, 59, 999)), 'minute'), true, 'exact end of minute');\n    assert.equal(m.isSame(moment(new Date(2011, 1, 2, 3, 5, 0, 0)), 'minute'), false, 'start of next minute');\n    assert.equal(m.isSame(moment(new Date(2011, 1, 2, 3, 3, 59, 999)), 'minute'), false, 'end of previous minute');\n    assert.equal(m.isSame(m, 'minute'), true, 'same moments are in the same minute');\n    assert.equal(+m, +mCopy, 'isSame minute should not change moment');\n});\n\ntest('is same second', function (assert) {\n    var m = moment(new Date(2011, 1, 2, 3, 4, 5, 6)), mCopy = moment(m);\n    assert.equal(m.isSame(moment(new Date(2011, 1, 2, 3, 4, 5, 10)), 'second'), true, 'second match');\n    assert.equal(m.isSame(moment(new Date(2011, 1, 2, 3, 4, 5, 10)), 'seconds'), true, 'plural should work');\n    assert.equal(m.isSame(moment(new Date(2012, 1, 2, 3, 4, 5, 10)), 'second'), false, 'year mismatch');\n    assert.equal(m.isSame(moment(new Date(2011, 2, 2, 3, 4, 5, 10)), 'second'), false, 'month mismatch');\n    assert.equal(m.isSame(moment(new Date(2011, 1, 3, 3, 4, 5, 10)), 'second'), false, 'day mismatch');\n    assert.equal(m.isSame(moment(new Date(2011, 1, 2, 4, 4, 5, 10)), 'second'), false, 'hour mismatch');\n    assert.equal(m.isSame(moment(new Date(2011, 1, 2, 3, 5, 5, 10)), 'second'), false, 'minute mismatch');\n    assert.equal(m.isSame(moment(new Date(2011, 1, 2, 3, 4, 6, 10)), 'second'), false, 'second mismatch');\n    assert.equal(m.isSame(moment(new Date(2011, 1, 2, 3, 4, 5, 0)), 'second'), true, 'exact start of second');\n    assert.equal(m.isSame(moment(new Date(2011, 1, 2, 3, 4, 5, 999)), 'second'), true, 'exact end of second');\n    assert.equal(m.isSame(moment(new Date(2011, 1, 2, 3, 4, 6, 0)), 'second'), false, 'start of next second');\n    assert.equal(m.isSame(moment(new Date(2011, 1, 2, 3, 4, 4, 999)), 'second'), false, 'end of previous second');\n    assert.equal(m.isSame(m, 'second'), true, 'same moments are in the same second');\n    assert.equal(+m, +mCopy, 'isSame second should not change moment');\n});\n\ntest('is same millisecond', function (assert) {\n    var m = moment(new Date(2011, 3, 2, 3, 4, 5, 10)), mCopy = moment(m);\n    assert.equal(m.isSame(moment(new Date(2011, 3, 2, 3, 4, 5, 10)), 'millisecond'), true, 'millisecond match');\n    assert.equal(m.isSame(moment(new Date(2011, 3, 2, 3, 4, 5, 10)), 'milliseconds'), true, 'plural should work');\n    assert.equal(m.isSame(moment(new Date(2012, 3, 2, 3, 4, 5, 10)), 'millisecond'), false, 'year is later');\n    assert.equal(m.isSame(moment(new Date(2010, 3, 2, 3, 4, 5, 10)), 'millisecond'), false, 'year is earlier');\n    assert.equal(m.isSame(moment(new Date(2011, 4, 2, 3, 4, 5, 10)), 'millisecond'), false, 'month is later');\n    assert.equal(m.isSame(moment(new Date(2011, 2, 2, 3, 4, 5, 10)), 'millisecond'), false, 'month is earlier');\n    assert.equal(m.isSame(moment(new Date(2011, 3, 3, 3, 4, 5, 10)), 'millisecond'), false, 'day is later');\n    assert.equal(m.isSame(moment(new Date(2011, 3, 1, 1, 4, 5, 10)), 'millisecond'), false, 'day is earlier');\n    assert.equal(m.isSame(moment(new Date(2011, 3, 2, 4, 4, 5, 10)), 'millisecond'), false, 'hour is later');\n    assert.equal(m.isSame(moment(new Date(2011, 3, 1, 4, 1, 5, 10)), 'millisecond'), false, 'hour is earlier');\n    assert.equal(m.isSame(moment(new Date(2011, 3, 2, 3, 5, 5, 10)), 'millisecond'), false, 'minute is later');\n    assert.equal(m.isSame(moment(new Date(2011, 3, 2, 3, 3, 5, 10)), 'millisecond'), false, 'minute is earlier');\n    assert.equal(m.isSame(moment(new Date(2011, 3, 2, 3, 4, 6, 10)), 'millisecond'), false, 'second is later');\n    assert.equal(m.isSame(moment(new Date(2011, 3, 2, 3, 4, 4, 5)), 'millisecond'), false, 'second is earlier');\n    assert.equal(m.isSame(moment(new Date(2011, 3, 2, 3, 4, 6, 11)), 'millisecond'), false, 'millisecond is later');\n    assert.equal(m.isSame(moment(new Date(2011, 3, 2, 3, 4, 4, 9)), 'millisecond'), false, 'millisecond is earlier');\n    assert.equal(m.isSame(m, 'millisecond'), true, 'same moments are in the same millisecond');\n    assert.equal(+m, +mCopy, 'isSame millisecond should not change moment');\n});\n\ntest('is same with utc offset moments', function (assert) {\n    assert.ok(moment.parseZone('2013-02-01T00:00:00-05:00').isSame(moment('2013-02-01'), 'year'), 'zoned vs local moment');\n    assert.ok(moment('2013-02-01').isSame(moment('2013-02-01').utcOffset('-05:00'), 'year'), 'local vs zoned moment');\n    assert.ok(moment.parseZone('2013-02-01T00:00:00-05:00').isSame(moment.parseZone('2013-02-01T00:00:00-06:30'), 'year'),\n            'zoned vs (differently) zoned moment');\n});\n\ntest('is same with invalid moments', function (assert) {\n    assert.equal(moment.invalid().isSame(moment.invalid()), false, 'invalid moments are not considered equal');\n});\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/test/moment/is_same_or_after.js",
    "content": "import { module, test } from '../qunit';\nimport moment from '../../moment';\n\nmodule('is same or after');\n\ntest('is same or after without units', function (assert) {\n    var m = moment(new Date(2011, 3, 2, 3, 4, 5, 10)), mCopy = moment(m);\n    assert.equal(m.isSameOrAfter(moment(new Date(2012, 3, 2, 3, 5, 5, 10))), false, 'year is later');\n    assert.equal(m.isSameOrAfter(moment(new Date(2010, 3, 2, 3, 3, 5, 10))), true, 'year is earlier');\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 4, 2, 3, 4, 5, 10))), false, 'month is later');\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 2, 2, 3, 4, 5, 10))), true, 'month is earlier');\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 3, 3, 3, 4, 5, 10))), false, 'day is later');\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 3, 1, 3, 4, 5, 10))), true, 'day is earlier');\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 3, 2, 4, 4, 5, 10))), false, 'hour is later');\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 3, 2, 2, 4, 5, 10))), true, 'hour is earlier');\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 3, 2, 3, 5, 5, 10))), false, 'minute is later');\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 3, 2, 3, 3, 5, 10))), true, 'minute is earlier');\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 3, 2, 3, 4, 6, 10))), false, 'second is later');\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 3, 2, 3, 4, 4, 11))), true, 'second is earlier');\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 3, 2, 3, 4, 5, 10))), true, 'millisecond match');\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 3, 2, 3, 4, 5, 11))), false, 'millisecond is later');\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 3, 2, 3, 4, 5, 9))), true, 'millisecond is earlier');\n    assert.equal(m.isSameOrAfter(m), true, 'moments are the same as themselves');\n    assert.equal(+m, +mCopy, 'isSameOrAfter second should not change moment');\n});\n\ntest('is same or after year', function (assert) {\n    var m = moment(new Date(2011, 1, 2, 3, 4, 5, 6)), mCopy = moment(m);\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 5, 6, 7, 8, 9, 10)), 'year'), true, 'year match');\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 5, 6, 7, 8, 9, 10)), 'years'), true, 'plural should work');\n    assert.equal(m.isSameOrAfter(moment(new Date(2012, 5, 6, 7, 8, 9, 10)), 'year'), false, 'year is later');\n    assert.equal(m.isSameOrAfter(moment(new Date(2010, 5, 6, 7, 8, 9, 10)), 'year'), true, 'year is earlier');\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 0, 1, 0, 0, 0, 0)), 'year'), true, 'exact start of year');\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 11, 31, 23, 59, 59, 999)), 'year'), true, 'exact end of year');\n    assert.equal(m.isSameOrAfter(moment(new Date(2012, 0, 1, 0, 0, 0, 0)), 'year'), false, 'start of next year');\n    assert.equal(m.isSameOrAfter(moment(new Date(2010, 11, 31, 23, 59, 59, 999)), 'year'), true, 'end of previous year');\n    assert.equal(m.isSameOrAfter(m, 'year'), true, 'same moments are in the same year');\n    assert.equal(+m, +mCopy, 'isSameOrAfter year should not change moment');\n});\n\ntest('is same or after month', function (assert) {\n    var m = moment(new Date(2011, 2, 3, 4, 5, 6, 7)), mCopy = moment(m);\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 2, 6, 7, 8, 9, 10)), 'month'), true, 'month match');\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 2, 6, 7, 8, 9, 10)), 'months'), true, 'plural should work');\n    assert.equal(m.isSameOrAfter(moment(new Date(2012, 2, 6, 7, 8, 9, 10)), 'month'), false, 'year is later');\n    assert.equal(m.isSameOrAfter(moment(new Date(2010, 2, 6, 7, 8, 9, 10)), 'month'), true, 'year is earlier');\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 5, 6, 7, 8, 9, 10)), 'month'), false, 'month is later');\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 1, 6, 7, 8, 9, 10)), 'month'), true, 'month is earlier');\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 2, 1, 0, 0, 0, 0)), 'month'), true, 'exact start of month');\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 2, 31, 23, 59, 59, 999)), 'month'), true, 'exact end of month');\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 3, 1, 0, 0, 0, 0)), 'month'), false, 'start of next month');\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 1, 27, 23, 59, 59, 999)), 'month'), true, 'end of previous month');\n    assert.equal(m.isSameOrAfter(m, 'month'), true, 'same moments are in the same month');\n    assert.equal(+m, +mCopy, 'isSameOrAfter month should not change moment');\n});\n\ntest('is same or after day', function (assert) {\n    var m = moment(new Date(2011, 1, 2, 3, 4, 5, 6)), mCopy = moment(m);\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 1, 2, 7, 8, 9, 10)), 'day'), true, 'day match');\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 1, 2, 7, 8, 9, 10)), 'days'), true, 'plural should work');\n    assert.equal(m.isSameOrAfter(moment(new Date(2012, 1, 2, 7, 8, 9, 10)), 'day'), false, 'year is later');\n    assert.equal(m.isSameOrAfter(moment(new Date(2010, 1, 2, 7, 8, 9, 10)), 'day'), true, 'year is earlier');\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 2, 2, 7, 8, 9, 10)), 'day'), false, 'month is later');\n    assert.equal(m.isSameOrAfter(moment(new Date(2010, 12, 2, 7, 8, 9, 10)), 'day'), true, 'month is earlier');\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 1, 3, 7, 8, 9, 10)), 'day'), false, 'day is later');\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 1, 1, 7, 8, 9, 10)), 'day'), true, 'day is earlier');\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 1, 2, 0, 0, 0, 0)), 'day'), true, 'exact start of day');\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 1, 2, 23, 59, 59, 999)), 'day'), true, 'exact end of day');\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 1, 3, 0, 0, 0, 0)), 'day'), false, 'start of next day');\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 1, 1, 23, 59, 59, 999)), 'day'), true, 'end of previous day');\n    assert.equal(m.isSameOrAfter(m, 'day'), true, 'same moments are in the same day');\n    assert.equal(+m, +mCopy, 'isSameOrAfter day should not change moment');\n});\n\ntest('is same or after hour', function (assert) {\n    var m = moment(new Date(2011, 1, 2, 3, 4, 5, 6)), mCopy = moment(m);\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 1, 2, 3, 8, 9, 10)), 'hour'), true, 'hour match');\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 1, 2, 3, 8, 9, 10)), 'hours'), true, 'plural should work');\n    assert.equal(m.isSameOrAfter(moment(new Date(2012, 1, 2, 3, 8, 9, 10)), 'hour'), false, 'year is later');\n    assert.equal(m.isSameOrAfter(moment(new Date(2010, 1, 2, 3, 8, 9, 10)), 'hour'), true, 'year is earlier');\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 2, 2, 3, 8, 9, 10)), 'hour'), false, 'month is later');\n    assert.equal(m.isSameOrAfter(moment(new Date(2010, 12, 2, 3, 8, 9, 10)), 'hour'), true, 'month is earlier');\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 1, 3, 3, 8, 9, 10)), 'hour'), false, 'day is later');\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 1, 1, 3, 8, 9, 10)), 'hour'), true, 'day is earlier');\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 1, 2, 4, 8, 9, 10)), 'hour'), false, 'hour is later');\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 1, 2, 2, 8, 9, 10)), 'hour'), true, 'hour is earlier');\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 1, 2, 3, 0, 0, 0)), 'hour'), true, 'exact start of hour');\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 1, 2, 3, 59, 59, 999)), 'hour'), true, 'exact end of hour');\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 1, 2, 4, 0, 0, 0)), 'hour'), false, 'start of next hour');\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 1, 2, 2, 59, 59, 999)), 'hour'), true, 'end of previous hour');\n    assert.equal(m.isSameOrAfter(m, 'hour'), true, 'same moments are in the same hour');\n    assert.equal(+m, +mCopy, 'isSameOrAfter hour should not change moment');\n});\n\ntest('is same or after minute', function (assert) {\n    var m = moment(new Date(2011, 1, 2, 3, 4, 5, 6)), mCopy = moment(m);\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 1, 2, 3, 4, 9, 10)), 'minute'), true, 'minute match');\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 1, 2, 3, 4, 9, 10)), 'minutes'), true, 'plural should work');\n    assert.equal(m.isSameOrAfter(moment(new Date(2012, 1, 2, 3, 4, 9, 10)), 'minute'), false, 'year is later');\n    assert.equal(m.isSameOrAfter(moment(new Date(2010, 1, 2, 3, 4, 9, 10)), 'minute'), true, 'year is earlier');\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 2, 2, 3, 4, 9, 10)), 'minute'), false, 'month is later');\n    assert.equal(m.isSameOrAfter(moment(new Date(2010, 12, 2, 3, 4, 9, 10)), 'minute'), true, 'month is earlier');\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 1, 3, 3, 4, 9, 10)), 'minute'), false, 'day is later');\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 1, 1, 3, 4, 9, 10)), 'minute'), true, 'day is earlier');\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 1, 2, 4, 4, 9, 10)), 'minute'), false, 'hour is later');\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 1, 2, 2, 4, 9, 10)), 'minute'), true, 'hour is earlier');\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 1, 2, 3, 5, 9, 10)), 'minute'), false, 'minute is later');\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 1, 2, 3, 3, 9, 10)), 'minute'), true, 'minute is earlier');\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 1, 2, 3, 4, 0, 0)), 'minute'), true, 'exact start of minute');\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 1, 2, 3, 4, 59, 999)), 'minute'), true, 'exact end of minute');\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 1, 2, 3, 5, 0, 0)), 'minute'), false, 'start of next minute');\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 1, 2, 3, 3, 59, 999)), 'minute'), true, 'end of previous minute');\n    assert.equal(m.isSameOrAfter(m, 'minute'), true, 'same moments are in the same minute');\n    assert.equal(+m, +mCopy, 'isSameOrAfter minute should not change moment');\n});\n\ntest('is same or after second', function (assert) {\n    var m = moment(new Date(2011, 1, 2, 3, 4, 5, 6)), mCopy = moment(m);\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 1, 2, 3, 4, 5, 10)), 'second'), true, 'second match');\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 1, 2, 3, 4, 5, 10)), 'seconds'), true, 'plural should work');\n    assert.equal(m.isSameOrAfter(moment(new Date(2012, 1, 2, 3, 4, 5, 10)), 'second'), false, 'year is later');\n    assert.equal(m.isSameOrAfter(moment(new Date(2010, 1, 2, 3, 4, 5, 10)), 'second'), true, 'year is earlier');\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 2, 2, 3, 4, 5, 10)), 'second'), false, 'month is later');\n    assert.equal(m.isSameOrAfter(moment(new Date(2010, 12, 2, 3, 4, 5, 10)), 'second'), true, 'month is earlier');\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 1, 3, 3, 4, 5, 10)), 'second'), false, 'day is later');\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 1, 1, 3, 4, 5, 10)), 'second'), true, 'day is earlier');\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 1, 2, 4, 4, 5, 10)), 'second'), false, 'hour is later');\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 1, 2, 2, 4, 5, 10)), 'second'), true, 'hour is earlier');\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 1, 2, 3, 5, 5, 10)), 'second'), false, 'minute is later');\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 1, 2, 3, 3, 5, 10)), 'second'), true, 'minute is earlier');\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 1, 2, 3, 4, 6, 10)), 'second'), false, 'second is later');\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 1, 2, 3, 4, 4, 10)), 'second'), true, 'second is earlier');\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 1, 2, 3, 4, 5, 0)), 'second'), true, 'exact start of second');\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 1, 2, 3, 4, 5, 999)), 'second'), true, 'exact end of second');\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 1, 2, 3, 4, 6, 0)), 'second'), false, 'start of next second');\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 1, 2, 3, 4, 4, 999)), 'second'), true, 'end of previous second');\n    assert.equal(m.isSameOrAfter(m, 'second'), true, 'same moments are in the same second');\n    assert.equal(+m, +mCopy, 'isSameOrAfter second should not change moment');\n});\n\ntest('is same or after millisecond', function (assert) {\n    var m = moment(new Date(2011, 3, 2, 3, 4, 5, 10)), mCopy = moment(m);\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 3, 2, 3, 4, 5, 10)), 'millisecond'), true, 'millisecond match');\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 3, 2, 3, 4, 5, 10)), 'milliseconds'), true, 'plural should work');\n    assert.equal(m.isSameOrAfter(moment(new Date(2012, 3, 2, 3, 4, 5, 10)), 'millisecond'), false, 'year is later');\n    assert.equal(m.isSameOrAfter(moment(new Date(2010, 3, 2, 3, 4, 5, 10)), 'millisecond'), true, 'year is earlier');\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 4, 2, 3, 4, 5, 10)), 'millisecond'), false, 'month is later');\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 2, 2, 3, 4, 5, 10)), 'millisecond'), true, 'month is earlier');\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 3, 3, 3, 4, 5, 10)), 'millisecond'), false, 'day is later');\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 3, 1, 1, 4, 5, 10)), 'millisecond'), true, 'day is earlier');\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 3, 2, 4, 4, 5, 10)), 'millisecond'), false, 'hour is later');\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 3, 1, 4, 1, 5, 10)), 'millisecond'), true, 'hour is earlier');\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 3, 2, 3, 5, 5, 10)), 'millisecond'), false, 'minute is later');\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 3, 2, 3, 3, 5, 10)), 'millisecond'), true, 'minute is earlier');\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 3, 2, 3, 4, 6, 10)), 'millisecond'), false, 'second is later');\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 3, 2, 3, 4, 4, 5)), 'millisecond'), true, 'second is earlier');\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 3, 2, 3, 4, 6, 11)), 'millisecond'), false, 'millisecond is later');\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 3, 2, 3, 4, 4, 9)), 'millisecond'), true, 'millisecond is earlier');\n    assert.equal(m.isSameOrAfter(m, 'millisecond'), true, 'same moments are in the same millisecond');\n    assert.equal(+m, +mCopy, 'isSameOrAfter millisecond should not change moment');\n});\n\ntest('is same or after with utc offset moments', function (assert) {\n    assert.ok(moment.parseZone('2013-02-01T00:00:00-05:00').isSameOrAfter(moment('2013-02-01'), 'year'), 'zoned vs local moment');\n    assert.ok(moment('2013-02-01').isSameOrAfter(moment('2013-02-01').utcOffset('-05:00'), 'year'), 'local vs zoned moment');\n    assert.ok(moment.parseZone('2013-02-01T00:00:00-05:00').isSameOrAfter(moment.parseZone('2013-02-01T00:00:00-06:30'), 'year'),\n            'zoned vs (differently) zoned moment');\n});\n\ntest('is same or after with invalid moments', function (assert) {\n    var m = moment(), invalid = moment.invalid();\n    assert.equal(invalid.isSameOrAfter(invalid), false, 'invalid moments are not considered equal');\n    assert.equal(m.isSameOrAfter(invalid), false, 'valid moment is not after invalid moment');\n    assert.equal(invalid.isSameOrAfter(m), false, 'invalid moment is not after valid moment');\n    assert.equal(m.isSameOrAfter(invalid, 'year'), false, 'invalid moment year');\n    assert.equal(m.isSameOrAfter(invalid, 'month'), false, 'invalid moment month');\n    assert.equal(m.isSameOrAfter(invalid, 'day'), false, 'invalid moment day');\n    assert.equal(m.isSameOrAfter(invalid, 'hour'), false, 'invalid moment hour');\n    assert.equal(m.isSameOrAfter(invalid, 'minute'), false, 'invalid moment minute');\n    assert.equal(m.isSameOrAfter(invalid, 'second'), false, 'invalid moment second');\n    assert.equal(m.isSameOrAfter(invalid, 'milliseconds'), false, 'invalid moment milliseconds');\n});\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/test/moment/is_same_or_before.js",
    "content": "import { module, test } from '../qunit';\nimport moment from '../../moment';\n\nmodule('is same or before');\n\ntest('is same or before without units', function (assert) {\n    var m = moment(new Date(2011, 3, 2, 3, 4, 5, 10)), mCopy = moment(m);\n    assert.equal(m.isSameOrBefore(moment(new Date(2012, 3, 2, 3, 5, 5, 10))), true, 'year is later');\n    assert.equal(m.isSameOrBefore(moment(new Date(2010, 3, 2, 3, 3, 5, 10))), false, 'year is earlier');\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 4, 2, 3, 4, 5, 10))), true, 'month is later');\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 2, 2, 3, 4, 5, 10))), false, 'month is earlier');\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 3, 3, 3, 4, 5, 10))), true, 'day is later');\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 3, 1, 3, 4, 5, 10))), false, 'day is earlier');\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 3, 2, 4, 4, 5, 10))), true, 'hour is later');\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 3, 2, 2, 4, 5, 10))), false, 'hour is earlier');\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 3, 2, 3, 5, 5, 10))), true, 'minute is later');\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 3, 2, 3, 3, 5, 10))), false, 'minute is earlier');\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 3, 2, 3, 4, 6, 10))), true, 'second is later');\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 3, 2, 3, 4, 4, 11))), false, 'second is earlier');\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 3, 2, 3, 4, 5, 10))), true, 'millisecond match');\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 3, 2, 3, 4, 5, 11))), true, 'millisecond is later');\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 3, 2, 3, 4, 5, 9))), false, 'millisecond is earlier');\n    assert.equal(m.isSameOrBefore(m), true, 'moments are the same as themselves');\n    assert.equal(+m, +mCopy, 'isSameOrBefore second should not change moment');\n});\n\ntest('is same or before year', function (assert) {\n    var m = moment(new Date(2011, 1, 2, 3, 4, 5, 6)), mCopy = moment(m);\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 5, 6, 7, 8, 9, 10)), 'year'), true, 'year match');\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 5, 6, 7, 8, 9, 10)), 'years'), true, 'plural should work');\n    assert.equal(m.isSameOrBefore(moment(new Date(2012, 5, 6, 7, 8, 9, 10)), 'year'), true, 'year is later');\n    assert.equal(m.isSameOrBefore(moment(new Date(2010, 5, 6, 7, 8, 9, 10)), 'year'), false, 'year is earlier');\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 0, 1, 0, 0, 0, 0)), 'year'), true, 'exact start of year');\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 11, 31, 23, 59, 59, 999)), 'year'), true, 'exact end of year');\n    assert.equal(m.isSameOrBefore(moment(new Date(2012, 0, 1, 0, 0, 0, 0)), 'year'), true, 'start of next year');\n    assert.equal(m.isSameOrBefore(moment(new Date(2010, 11, 31, 23, 59, 59, 999)), 'year'), false, 'end of previous year');\n    assert.equal(m.isSameOrBefore(m, 'year'), true, 'same moments are in the same year');\n    assert.equal(+m, +mCopy, 'isSameOrBefore year should not change moment');\n});\n\ntest('is same or before month', function (assert) {\n    var m = moment(new Date(2011, 2, 3, 4, 5, 6, 7)), mCopy = moment(m);\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 2, 6, 7, 8, 9, 10)), 'month'), true, 'month match');\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 2, 6, 7, 8, 9, 10)), 'months'), true, 'plural should work');\n    assert.equal(m.isSameOrBefore(moment(new Date(2012, 2, 6, 7, 8, 9, 10)), 'month'), true, 'year is later');\n    assert.equal(m.isSameOrBefore(moment(new Date(2010, 2, 6, 7, 8, 9, 10)), 'month'), false, 'year is earlier');\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 5, 6, 7, 8, 9, 10)), 'month'), true, 'month is later');\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 1, 6, 7, 8, 9, 10)), 'month'), false, 'month is earlier');\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 2, 1, 0, 0, 0, 0)), 'month'), true, 'exact start of month');\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 2, 31, 23, 59, 59, 999)), 'month'), true, 'exact end of month');\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 3, 1, 0, 0, 0, 0)), 'month'), true, 'start of next month');\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 1, 27, 23, 59, 59, 999)), 'month'), false, 'end of previous month');\n    assert.equal(m.isSameOrBefore(m, 'month'), true, 'same moments are in the same month');\n    assert.equal(+m, +mCopy, 'isSameOrBefore month should not change moment');\n});\n\ntest('is same or before day', function (assert) {\n    var m = moment(new Date(2011, 1, 2, 3, 4, 5, 6)), mCopy = moment(m);\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 1, 2, 7, 8, 9, 10)), 'day'), true, 'day match');\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 1, 2, 7, 8, 9, 10)), 'days'), true, 'plural should work');\n    assert.equal(m.isSameOrBefore(moment(new Date(2012, 1, 2, 7, 8, 9, 10)), 'day'), true, 'year is later');\n    assert.equal(m.isSameOrBefore(moment(new Date(2010, 1, 2, 7, 8, 9, 10)), 'day'), false, 'year is earlier');\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 2, 2, 7, 8, 9, 10)), 'day'), true, 'month is later');\n    assert.equal(m.isSameOrBefore(moment(new Date(2010, 12, 2, 7, 8, 9, 10)), 'day'), false, 'month is earlier');\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 1, 3, 7, 8, 9, 10)), 'day'), true, 'day is later');\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 1, 1, 7, 8, 9, 10)), 'day'), false, 'day is earlier');\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 1, 2, 0, 0, 0, 0)), 'day'), true, 'exact start of day');\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 1, 2, 23, 59, 59, 999)), 'day'), true, 'exact end of day');\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 1, 3, 0, 0, 0, 0)), 'day'), true, 'start of next day');\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 1, 1, 23, 59, 59, 999)), 'day'), false, 'end of previous day');\n    assert.equal(m.isSameOrBefore(m, 'day'), true, 'same moments are in the same day');\n    assert.equal(+m, +mCopy, 'isSameOrBefore day should not change moment');\n});\n\ntest('is same or before hour', function (assert) {\n    var m = moment(new Date(2011, 1, 2, 3, 4, 5, 6)), mCopy = moment(m);\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 1, 2, 3, 8, 9, 10)), 'hour'), true, 'hour match');\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 1, 2, 3, 8, 9, 10)), 'hours'), true, 'plural should work');\n    assert.equal(m.isSameOrBefore(moment(new Date(2012, 1, 2, 3, 8, 9, 10)), 'hour'), true, 'year is later');\n    assert.equal(m.isSameOrBefore(moment(new Date(2010, 1, 2, 3, 8, 9, 10)), 'hour'), false, 'year is earlier');\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 2, 2, 3, 8, 9, 10)), 'hour'), true, 'month is later');\n    assert.equal(m.isSameOrBefore(moment(new Date(2010, 12, 2, 3, 8, 9, 10)), 'hour'), false, 'month is earlier');\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 1, 3, 3, 8, 9, 10)), 'hour'), true, 'day is later');\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 1, 1, 3, 8, 9, 10)), 'hour'), false, 'day is earlier');\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 1, 2, 4, 8, 9, 10)), 'hour'), true, 'hour is later');\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 1, 2, 2, 8, 9, 10)), 'hour'), false, 'hour is earlier');\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 1, 2, 3, 0, 0, 0)), 'hour'), true, 'exact start of hour');\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 1, 2, 3, 59, 59, 999)), 'hour'), true, 'exact end of hour');\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 1, 2, 4, 0, 0, 0)), 'hour'), true, 'start of next hour');\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 1, 2, 2, 59, 59, 999)), 'hour'), false, 'end of previous hour');\n    assert.equal(m.isSameOrBefore(m, 'hour'), true, 'same moments are in the same hour');\n    assert.equal(+m, +mCopy, 'isSameOrBefore hour should not change moment');\n});\n\ntest('is same or before minute', function (assert) {\n    var m = moment(new Date(2011, 1, 2, 3, 4, 5, 6)), mCopy = moment(m);\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 1, 2, 3, 4, 9, 10)), 'minute'), true, 'minute match');\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 1, 2, 3, 4, 9, 10)), 'minutes'), true, 'plural should work');\n    assert.equal(m.isSameOrBefore(moment(new Date(2012, 1, 2, 3, 4, 9, 10)), 'minute'), true, 'year is later');\n    assert.equal(m.isSameOrBefore(moment(new Date(2010, 1, 2, 3, 4, 9, 10)), 'minute'), false, 'year is earlier');\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 2, 2, 3, 4, 9, 10)), 'minute'), true, 'month is later');\n    assert.equal(m.isSameOrBefore(moment(new Date(2010, 12, 2, 3, 4, 9, 10)), 'minute'), false, 'month is earlier');\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 1, 3, 3, 4, 9, 10)), 'minute'), true, 'day is later');\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 1, 1, 3, 4, 9, 10)), 'minute'), false, 'day is earlier');\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 1, 2, 4, 4, 9, 10)), 'minute'), true, 'hour is later');\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 1, 2, 2, 4, 9, 10)), 'minute'), false, 'hour is earlier');\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 1, 2, 3, 5, 9, 10)), 'minute'), true, 'minute is later');\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 1, 2, 3, 3, 9, 10)), 'minute'), false, 'minute is earlier');\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 1, 2, 3, 4, 0, 0)), 'minute'), true, 'exact start of minute');\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 1, 2, 3, 4, 59, 999)), 'minute'), true, 'exact end of minute');\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 1, 2, 3, 5, 0, 0)), 'minute'), true, 'start of next minute');\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 1, 2, 3, 3, 59, 999)), 'minute'), false, 'end of previous minute');\n    assert.equal(m.isSameOrBefore(m, 'minute'), true, 'same moments are in the same minute');\n    assert.equal(+m, +mCopy, 'isSameOrBefore minute should not change moment');\n});\n\ntest('is same or before second', function (assert) {\n    var m = moment(new Date(2011, 1, 2, 3, 4, 5, 6)), mCopy = moment(m);\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 1, 2, 3, 4, 5, 10)), 'second'), true, 'second match');\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 1, 2, 3, 4, 5, 10)), 'seconds'), true, 'plural should work');\n    assert.equal(m.isSameOrBefore(moment(new Date(2012, 1, 2, 3, 4, 5, 10)), 'second'), true, 'year is later');\n    assert.equal(m.isSameOrBefore(moment(new Date(2010, 1, 2, 3, 4, 5, 10)), 'second'), false, 'year is earlier');\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 2, 2, 3, 4, 5, 10)), 'second'), true, 'month is later');\n    assert.equal(m.isSameOrBefore(moment(new Date(2010, 12, 2, 3, 4, 5, 10)), 'second'), false, 'month is earlier');\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 1, 3, 3, 4, 5, 10)), 'second'), true, 'day is later');\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 1, 1, 3, 4, 5, 10)), 'second'), false, 'day is earlier');\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 1, 2, 4, 4, 5, 10)), 'second'), true, 'hour is later');\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 1, 2, 2, 4, 5, 10)), 'second'), false, 'hour is earlier');\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 1, 2, 3, 5, 5, 10)), 'second'), true, 'minute is later');\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 1, 2, 3, 3, 5, 10)), 'second'), false, 'minute is earlier');\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 1, 2, 3, 4, 6, 10)), 'second'), true, 'second is later');\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 1, 2, 3, 4, 4, 10)), 'second'), false, 'second is earlier');\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 1, 2, 3, 4, 5, 0)), 'second'), true, 'exact start of second');\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 1, 2, 3, 4, 5, 999)), 'second'), true, 'exact end of second');\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 1, 2, 3, 4, 6, 0)), 'second'), true, 'start of next second');\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 1, 2, 3, 4, 4, 999)), 'second'), false, 'end of previous second');\n    assert.equal(m.isSameOrBefore(m, 'second'), true, 'same moments are in the same second');\n    assert.equal(+m, +mCopy, 'isSameOrBefore second should not change moment');\n});\n\ntest('is same or before millisecond', function (assert) {\n    var m = moment(new Date(2011, 3, 2, 3, 4, 5, 10)), mCopy = moment(m);\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 3, 2, 3, 4, 5, 10)), 'millisecond'), true, 'millisecond match');\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 3, 2, 3, 4, 5, 10)), 'milliseconds'), true, 'plural should work');\n    assert.equal(m.isSameOrBefore(moment(new Date(2012, 3, 2, 3, 4, 5, 10)), 'millisecond'), true, 'year is later');\n    assert.equal(m.isSameOrBefore(moment(new Date(2010, 3, 2, 3, 4, 5, 10)), 'millisecond'), false, 'year is earlier');\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 4, 2, 3, 4, 5, 10)), 'millisecond'), true, 'month is later');\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 2, 2, 3, 4, 5, 10)), 'millisecond'), false, 'month is earlier');\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 3, 3, 3, 4, 5, 10)), 'millisecond'), true, 'day is later');\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 3, 1, 1, 4, 5, 10)), 'millisecond'), false, 'day is earlier');\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 3, 2, 4, 4, 5, 10)), 'millisecond'), true, 'hour is later');\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 3, 1, 4, 1, 5, 10)), 'millisecond'), false, 'hour is earlier');\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 3, 2, 3, 5, 5, 10)), 'millisecond'), true, 'minute is later');\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 3, 2, 3, 3, 5, 10)), 'millisecond'), false, 'minute is earlier');\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 3, 2, 3, 4, 6, 10)), 'millisecond'), true, 'second is later');\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 3, 2, 3, 4, 4, 5)), 'millisecond'), false, 'second is earlier');\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 3, 2, 3, 4, 6, 11)), 'millisecond'), true, 'millisecond is later');\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 3, 2, 3, 4, 4, 9)), 'millisecond'), false, 'millisecond is earlier');\n    assert.equal(m.isSameOrBefore(m, 'millisecond'), true, 'same moments are in the same millisecond');\n    assert.equal(+m, +mCopy, 'isSameOrBefore millisecond should not change moment');\n});\n\ntest('is same with utc offset moments', function (assert) {\n    assert.ok(moment.parseZone('2013-02-01T00:00:00-05:00').isSameOrBefore(moment('2013-02-01'), 'year'), 'zoned vs local moment');\n    assert.ok(moment('2013-02-01').isSameOrBefore(moment('2013-02-01').utcOffset('-05:00'), 'year'), 'local vs zoned moment');\n    assert.ok(\n      moment.parseZone('2013-02-01T00:00:00-05:00').isSameOrBefore(moment.parseZone('2013-02-01T00:00:00-06:30'), 'year'),\n      'zoned vs (differently) zoned moment'\n    );\n});\n\ntest('is same with invalid moments', function (assert) {\n    var m = moment(), invalid = moment.invalid();\n    assert.equal(invalid.isSameOrBefore(invalid), false, 'invalid moments are not considered equal');\n    assert.equal(m.isSameOrBefore(invalid), false, 'valid moment is not before invalid moment');\n    assert.equal(invalid.isSameOrBefore(m), false, 'invalid moment is not before valid moment');\n    assert.equal(m.isSameOrBefore(invalid, 'year'), false, 'invalid moment year');\n    assert.equal(m.isSameOrBefore(invalid, 'month'), false, 'invalid moment month');\n    assert.equal(m.isSameOrBefore(invalid, 'day'), false, 'invalid moment day');\n    assert.equal(m.isSameOrBefore(invalid, 'hour'), false, 'invalid moment hour');\n    assert.equal(m.isSameOrBefore(invalid, 'minute'), false, 'invalid moment minute');\n    assert.equal(m.isSameOrBefore(invalid, 'second'), false, 'invalid moment second');\n    assert.equal(m.isSameOrBefore(invalid, 'milliseconds'), false, 'invalid moment milliseconds');\n});\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/test/moment/is_valid.js",
    "content": "import { module, test } from '../qunit';\nimport moment from '../../moment';\n\nmodule('is valid');\n\ntest('array bad month', function (assert) {\n    assert.equal(moment([2010, -1]).isValid(), false, 'month -1 invalid');\n    assert.equal(moment([2100, 12]).isValid(), false, 'month 12 invalid');\n});\n\ntest('array good month', function (assert) {\n    for (var i = 0; i < 12; i++) {\n        assert.equal(moment([2010, i]).isValid(), true, 'month ' + i);\n        assert.equal(moment.utc([2010, i]).isValid(), true, 'month ' + i);\n    }\n});\n\ntest('array bad date', function (assert) {\n    var tests = [\n        moment([2010, 0, 0]),\n        moment([2100, 0, 32]),\n        moment.utc([2010, 0, 0]),\n        moment.utc([2100, 0, 32])\n    ],\n    i, m;\n\n    for (i in tests) {\n        m = tests[i];\n        assert.equal(m.isValid(), false);\n    }\n});\n\ntest('h/hh with hour > 12', function (assert) {\n    assert.ok(moment('06/20/2014 11:51 PM', 'MM/DD/YYYY hh:mm A', true).isValid(), '11 for hh');\n    assert.ok(moment('06/20/2014 11:51 AM', 'MM/DD/YYYY hh:mm A', true).isValid(), '11 for hh');\n    assert.ok(moment('06/20/2014 23:51 PM', 'MM/DD/YYYY hh:mm A').isValid(), 'non-strict validity 23 for hh');\n    assert.ok(moment('06/20/2014 23:51 PM', 'MM/DD/YYYY hh:mm A').parsingFlags().bigHour, 'non-strict bigHour 23 for hh');\n    assert.ok(!moment('06/20/2014 23:51 PM', 'MM/DD/YYYY hh:mm A', true).isValid(), 'validity 23 for hh');\n    assert.ok(moment('06/20/2014 23:51 PM', 'MM/DD/YYYY hh:mm A', true).parsingFlags().bigHour, 'bigHour 23 for hh');\n});\n\ntest('array bad date leap year', function (assert) {\n    assert.equal(moment([2010, 1, 29]).isValid(), false, '2010 feb 29');\n    assert.equal(moment([2100, 1, 29]).isValid(), false, '2100 feb 29');\n    assert.equal(moment([2008, 1, 30]).isValid(), false, '2008 feb 30');\n    assert.equal(moment([2000, 1, 30]).isValid(), false, '2000 feb 30');\n\n    assert.equal(moment.utc([2010, 1, 29]).isValid(), false, 'utc 2010 feb 29');\n    assert.equal(moment.utc([2100, 1, 29]).isValid(), false, 'utc 2100 feb 29');\n    assert.equal(moment.utc([2008, 1, 30]).isValid(), false, 'utc 2008 feb 30');\n    assert.equal(moment.utc([2000, 1, 30]).isValid(), false, 'utc 2000 feb 30');\n});\n\ntest('string + formats bad date', function (assert) {\n    assert.equal(moment('2020-00-00', []).isValid(), false, 'invalid on empty array');\n    assert.equal(moment('2020-00-00', ['YYYY-MM-DD', 'DD-MM-YYYY']).isValid(), false, 'invalid on all in array');\n    assert.equal(moment('2020-00-00', ['DD-MM-YYYY', 'YYYY-MM-DD']).isValid(), false, 'invalid on all in array');\n    assert.equal(moment('2020-01-01', ['YYYY-MM-DD', 'DD-MM-YYYY']).isValid(), true, 'valid on first');\n    assert.equal(moment('2020-01-01', ['DD-MM-YYYY', 'YYYY-MM-DD']).isValid(), true, 'valid on last');\n    assert.equal(moment('2020-01-01', ['YYYY-MM-DD', 'YYYY-DD-MM']).isValid(), true, 'valid on both');\n    assert.equal(moment('2020-13-01', ['YYYY-MM-DD', 'YYYY-DD-MM']).isValid(), true, 'valid on last');\n\n    assert.equal(moment('12-13-2012', ['DD-MM-YYYY', 'YYYY-MM-DD']).isValid(), false, 'month rollover');\n    assert.equal(moment('12-13-2012', ['DD-MM-YYYY', 'DD-MM-YYYY']).isValid(), false, 'month rollover');\n    assert.equal(moment('38-12-2012', ['DD-MM-YYYY']).isValid(), false, 'day rollover');\n});\n\ntest('string nonsensical with format', function (assert) {\n    assert.equal(moment('fail', 'MM-DD-YYYY').isValid(), false, 'string \\'fail\\' with format \\'MM-DD-YYYY\\'');\n    assert.equal(moment('xx-xx-2001', 'DD-MM-YYY').isValid(), true, 'string \\'xx-xx-2001\\' with format \\'MM-DD-YYYY\\'');\n});\n\ntest('string with bad month name', function (assert) {\n    assert.equal(moment('01-Nam-2012', 'DD-MMM-YYYY').isValid(), false, '\\'Nam\\' is an invalid month');\n    assert.equal(moment('01-Aug-2012', 'DD-MMM-YYYY').isValid(), true, '\\'Aug\\' is a valid month');\n});\n\ntest('string with spaceless format', function (assert) {\n    assert.equal(moment('10Sep2001', 'DDMMMYYYY').isValid(), true, 'Parsing 10Sep2001 should result in a valid date');\n});\n\ntest('invalid string iso 8601', function (assert) {\n    var tests = [\n        '2010-00-00',\n        '2010-01-00',\n        '2010-01-40',\n        '2010-01-01T24:01',  // 24:00:00 is actually valid\n        '2010-01-01T23:60',\n        '2010-01-01T23:59:60'\n    ], i;\n\n    for (i = 0; i < tests.length; i++) {\n        assert.equal(moment(tests[i], moment.ISO_8601).isValid(), false, tests[i] + ' should be invalid');\n        assert.equal(moment.utc(tests[i], moment.ISO_8601).isValid(), false, tests[i] + ' should be invalid');\n    }\n});\n\ntest('invalid string iso 8601 + timezone', function (assert) {\n    var tests = [\n        '2010-00-00T+00:00',\n        '2010-01-00T+00:00',\n        '2010-01-40T+00:00',\n        '2010-01-40T24:01+00:00',\n        '2010-01-40T23:60+00:00',\n        '2010-01-40T23:59:60+00:00',\n        '2010-01-40T23:59:59.9999+00:00',\n        '2010-01-40T23:59:59,9999+00:00'\n    ], i;\n\n    for (i = 0; i < tests.length; i++) {\n        assert.equal(moment(tests[i], moment.ISO_8601).isValid(), false, tests[i] + ' should be invalid');\n        assert.equal(moment.utc(tests[i], moment.ISO_8601).isValid(), false, tests[i] + ' should be invalid');\n    }\n});\n\ntest('valid string iso 8601 - not strict', function (assert) {\n    var tests = [\n        '2010-01-30 00:00:00,000Z',\n        '20100101',\n        '20100130',\n        '20100130T23+00:00',\n        '20100130T2359+0000',\n        '20100130T235959+0000',\n        '20100130T235959,999+0000',\n        '20100130T235959,999-0700',\n        '20100130T000000,000+0700',\n        '20100130 000000,000Z'\n    ];\n\n    for (var i = 0; i < tests.length; i++) {\n        assert.equal(moment(tests[i]).isValid(), true, tests[i] + ' should be valid in normal');\n        assert.equal(moment.utc(tests[i]).isValid(), true, tests[i] + ' should be valid in normal');\n    }\n});\n\ntest('valid string iso 8601 + timezone', function (assert) {\n    var tests = [\n        '2010-01-01',\n        '2010-01-30',\n        '2010-01-30T23+00:00',\n        '2010-01-30T23:59+00:00',\n        '2010-01-30T23:59:59+00:00',\n        '2010-01-30T23:59:59.999+00:00',\n        '2010-01-30T23:59:59.999-07:00',\n        '2010-01-30T00:00:00.000+07:00',\n        '2010-01-30T23:59:59.999-07',\n        '2010-01-30T00:00:00.000+07',\n        '2010-01-30 00:00:00.000Z'\n    ], i;\n\n    for (i = 0; i < tests.length; i++) {\n        assert.equal(moment(tests[i]).isValid(), true, tests[i] + ' should be valid in normal');\n        assert.equal(moment.utc(tests[i]).isValid(), true, tests[i] + ' should be valid in normal');\n        assert.equal(moment(tests[i], moment.ISO_8601, true).isValid(), true, tests[i] + ' should be valid in strict');\n        assert.equal(moment.utc(tests[i], moment.ISO_8601, true).isValid(), true, tests[i] + ' should be valid in strict');\n    }\n});\n\ntest('invalidAt', function (assert) {\n    assert.equal(moment([2000, 12]).invalidAt(), 1, 'month 12 is invalid: 0-11');\n    assert.equal(moment([2000, 1, 30]).invalidAt(), 2, '30 is not a valid february day');\n    assert.equal(moment([2000, 1, 29, 25]).invalidAt(), 3, '25 is invalid hour');\n    assert.equal(moment([2000, 1, 29, 24,  1]).invalidAt(), 3, '24:01 is invalid hour');\n    assert.equal(moment([2000, 1, 29, 23, 60]).invalidAt(), 4, '60 is invalid minute');\n    assert.equal(moment([2000, 1, 29, 23, 59, 60]).invalidAt(), 5, '60 is invalid second');\n    assert.equal(moment([2000, 1, 29, 23, 59, 59, 1000]).invalidAt(), 6, '1000 is invalid millisecond');\n    assert.equal(moment([2000, 1, 29, 23, 59, 59, 999]).invalidAt(), -1, '-1 if everything is fine');\n});\n\ntest('valid Unix timestamp', function (assert) {\n    assert.equal(moment(1371065286, 'X').isValid(), true, 'number integer');\n    assert.equal(moment(1379066897.0, 'X').isValid(), true, 'number whole 1dp');\n    assert.equal(moment(1379066897.7, 'X').isValid(), true, 'number 1dp');\n    assert.equal(moment(1379066897.00, 'X').isValid(), true, 'number whole 2dp');\n    assert.equal(moment(1379066897.07, 'X').isValid(), true, 'number 2dp');\n    assert.equal(moment(1379066897.17, 'X').isValid(), true, 'number 2dp');\n    assert.equal(moment(1379066897.000, 'X').isValid(), true, 'number whole 3dp');\n    assert.equal(moment(1379066897.007, 'X').isValid(), true, 'number 3dp');\n    assert.equal(moment(1379066897.017, 'X').isValid(), true, 'number 3dp');\n    assert.equal(moment(1379066897.157, 'X').isValid(), true, 'number 3dp');\n    assert.equal(moment('1371065286', 'X').isValid(), true, 'string integer');\n    assert.equal(moment('1379066897.', 'X').isValid(), true, 'string trailing .');\n    assert.equal(moment('1379066897.0', 'X').isValid(), true, 'string whole 1dp');\n    assert.equal(moment('1379066897.7', 'X').isValid(), true, 'string 1dp');\n    assert.equal(moment('1379066897.00', 'X').isValid(), true, 'string whole 2dp');\n    assert.equal(moment('1379066897.07', 'X').isValid(), true, 'string 2dp');\n    assert.equal(moment('1379066897.17', 'X').isValid(), true, 'string 2dp');\n    assert.equal(moment('1379066897.000', 'X').isValid(), true, 'string whole 3dp');\n    assert.equal(moment('1379066897.007', 'X').isValid(), true, 'string 3dp');\n    assert.equal(moment('1379066897.017', 'X').isValid(), true, 'string 3dp');\n    assert.equal(moment('1379066897.157', 'X').isValid(), true, 'string 3dp');\n});\n\ntest('invalid Unix timestamp', function (assert) {\n    assert.equal(moment(undefined, 'X').isValid(), false, 'undefined');\n    assert.equal(moment('undefined', 'X').isValid(), false, 'string undefined');\n    try {\n        assert.equal(moment(null, 'X').isValid(), false, 'null');\n    } catch (e) {\n        assert.ok(true, 'null');\n    }\n\n    assert.equal(moment('null', 'X').isValid(), false, 'string null');\n    assert.equal(moment([], 'X').isValid(), false, 'array');\n    assert.equal(moment('{}', 'X').isValid(), false, 'object');\n    try {\n        assert.equal(moment('', 'X').isValid(), false, 'string empty');\n    } catch (e) {\n        assert.ok(true, 'string empty');\n    }\n\n    assert.equal(moment(' ', 'X').isValid(), false, 'string space');\n});\n\ntest('valid Unix offset milliseconds', function (assert) {\n    assert.equal(moment(1234567890123, 'x').isValid(), true, 'number integer');\n    assert.equal(moment('1234567890123', 'x').isValid(), true, 'string integer');\n});\n\ntest('invalid Unix offset milliseconds', function (assert) {\n    assert.equal(moment(undefined, 'x').isValid(), false, 'undefined');\n    assert.equal(moment('undefined', 'x').isValid(), false, 'string undefined');\n    try {\n        assert.equal(moment(null, 'x').isValid(), false, 'null');\n    } catch (e) {\n        assert.ok(true, 'null');\n    }\n\n    assert.equal(moment('null', 'x').isValid(), false, 'string null');\n    assert.equal(moment([], 'x').isValid(), false, 'array');\n    assert.equal(moment('{}', 'x').isValid(), false, 'object');\n    try {\n        assert.equal(moment('', 'x').isValid(), false, 'string empty');\n    } catch (e) {\n        assert.ok(true, 'string empty');\n    }\n\n    assert.equal(moment(' ', 'x').isValid(), false, 'string space');\n});\n\ntest('empty', function (assert) {\n    assert.equal(moment(null).isValid(), false, 'null');\n    assert.equal(moment('').isValid(), false, 'empty string');\n    assert.equal(moment(null, 'YYYY').isValid(), false, 'format + null');\n    assert.equal(moment('', 'YYYY').isValid(), false, 'format + empty string');\n    assert.equal(moment(' ', 'YYYY').isValid(), false, 'format + empty when trimmed');\n});\n\ntest('days of the year', function (assert) {\n    assert.equal(moment('2010 300', 'YYYY DDDD').isValid(), true, 'day 300 of year valid');\n    assert.equal(moment('2010 365', 'YYYY DDDD').isValid(), true, 'day 365 of year valid');\n    assert.equal(moment('2010 366', 'YYYY DDDD').isValid(), false, 'day 366 of year invalid');\n    assert.equal(moment('2012 365', 'YYYY DDDD').isValid(), true, 'day 365 of leap year valid');\n    assert.equal(moment('2012 366', 'YYYY DDDD').isValid(), true, 'day 366 of leap year valid');\n    assert.equal(moment('2012 367', 'YYYY DDDD').isValid(), false, 'day 367 of leap year invalid');\n});\n\ntest('24:00:00.000 is valid', function (assert) {\n    assert.equal(moment('2014-01-01 24', 'YYYY-MM-DD HH').isValid(), true, '24 is valid');\n    assert.equal(moment('2014-01-01 24:00', 'YYYY-MM-DD HH:mm').isValid(), true, '24:00 is valid');\n    assert.equal(moment('2014-01-01 24:01', 'YYYY-MM-DD HH:mm').isValid(), false, '24:01 is not valid');\n});\n\ntest('oddball permissiveness', function (assert) {\n    // https://github.com/moment/moment/issues/1128\n    assert.ok(moment('2010-10-3199', ['MM/DD/YYYY', 'MM-DD-YYYY', 'YYYY-MM-DD']).isValid());\n\n    // https://github.com/moment/moment/issues/1122\n    assert.ok(moment('3:25', ['h:mma', 'hh:mma', 'H:mm', 'HH:mm']).isValid());\n});\n\ntest('0 hour is invalid in strict', function (assert) {\n    assert.equal(moment('00:01', 'hh:mm', true).isValid(), false, '00 hour is invalid in strict');\n    assert.equal(moment('00:01', 'hh:mm').isValid(), true, '00 hour is valid in normal');\n    assert.equal(moment('0:01', 'h:mm', true).isValid(), false, '0 hour is invalid in strict');\n    assert.equal(moment('0:01', 'h:mm').isValid(), true, '0 hour is valid in normal');\n});\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/test/moment/leapyear.js",
    "content": "import { module, test } from '../qunit';\nimport moment from '../../moment';\n\nmodule('leap year');\n\ntest('leap year', function (assert) {\n    assert.equal(moment([2010, 0, 1]).isLeapYear(), false, '2010');\n    assert.equal(moment([2100, 0, 1]).isLeapYear(), false, '2100');\n    assert.equal(moment([2008, 0, 1]).isLeapYear(), true, '2008');\n    assert.equal(moment([2000, 0, 1]).isLeapYear(), true, '2000');\n});\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/test/moment/listers.js",
    "content": "import { module, test } from '../qunit';\nimport moment from '../../moment';\n\nmodule('listers');\n\ntest('default', function (assert) {\n    assert.deepEqual(moment.months(), ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December']);\n    assert.deepEqual(moment.monthsShort(), ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']);\n    assert.deepEqual(moment.weekdays(), ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday']);\n    assert.deepEqual(moment.weekdaysShort(), ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat']);\n    assert.deepEqual(moment.weekdaysMin(), ['Su', 'Mo', 'Tu', 'We', 'Th', 'Fr', 'Sa']);\n});\n\ntest('index', function (assert) {\n    assert.equal(moment.months(0), 'January');\n    assert.equal(moment.months(2), 'March');\n    assert.equal(moment.monthsShort(0), 'Jan');\n    assert.equal(moment.monthsShort(2), 'Mar');\n    assert.equal(moment.weekdays(0), 'Sunday');\n    assert.equal(moment.weekdays(2), 'Tuesday');\n    assert.equal(moment.weekdaysShort(0), 'Sun');\n    assert.equal(moment.weekdaysShort(2), 'Tue');\n    assert.equal(moment.weekdaysMin(0), 'Su');\n    assert.equal(moment.weekdaysMin(2), 'Tu');\n});\n\ntest('localized', function (assert) {\n    var months = 'one_two_three_four_five_six_seven_eight_nine_ten_eleven_twelve'.split('_'),\n        monthsShort = 'on_tw_th_fo_fi_si_se_ei_ni_te_el_tw'.split('_'),\n        weekdays = 'one_two_three_four_five_six_seven'.split('_'),\n        weekdaysShort = 'on_tw_th_fo_fi_si_se'.split('_'),\n        weekdaysMin = '1_2_3_4_5_6_7'.split('_'),\n        weekdaysLocale = 'four_five_six_seven_one_two_three'.split('_'),\n        weekdaysShortLocale = 'fo_fi_si_se_on_tw_th'.split('_'),\n        weekdaysMinLocale = '4_5_6_7_1_2_3'.split('_'),\n        week = {\n            dow : 3,\n            doy : 6\n        };\n\n    moment.locale('numerologists', {\n        months : months,\n        monthsShort : monthsShort,\n        weekdays : weekdays,\n        weekdaysShort: weekdaysShort,\n        weekdaysMin: weekdaysMin,\n        week : week\n    });\n\n    assert.deepEqual(moment.months(), months);\n    assert.deepEqual(moment.monthsShort(), monthsShort);\n    assert.deepEqual(moment.weekdays(), weekdays);\n    assert.deepEqual(moment.weekdaysShort(), weekdaysShort);\n    assert.deepEqual(moment.weekdaysMin(), weekdaysMin);\n\n    assert.equal(moment.months(0), 'one');\n    assert.equal(moment.monthsShort(0), 'on');\n    assert.equal(moment.weekdays(0), 'one');\n    assert.equal(moment.weekdaysShort(0), 'on');\n    assert.equal(moment.weekdaysMin(0), '1');\n\n    assert.equal(moment.months(2), 'three');\n    assert.equal(moment.monthsShort(2), 'th');\n    assert.equal(moment.weekdays(2), 'three');\n    assert.equal(moment.weekdaysShort(2), 'th');\n    assert.equal(moment.weekdaysMin(2), '3');\n\n    assert.deepEqual(moment.weekdays(true), weekdaysLocale);\n    assert.deepEqual(moment.weekdaysShort(true), weekdaysShortLocale);\n    assert.deepEqual(moment.weekdaysMin(true), weekdaysMinLocale);\n\n    assert.equal(moment.weekdays(true, 0), 'four');\n    assert.equal(moment.weekdaysShort(true, 0), 'fo');\n    assert.equal(moment.weekdaysMin(true, 0), '4');\n\n    assert.equal(moment.weekdays(false, 2), 'three');\n    assert.equal(moment.weekdaysShort(false, 2), 'th');\n    assert.equal(moment.weekdaysMin(false, 2), '3');\n});\n\ntest('with functions', function (assert) {\n    var monthsShort = 'one_two_three_four_five_six_seven_eight_nine_ten_eleven_twelve'.split('_'),\n        monthsShortWeird = 'onesy_twosy_threesy_foursy_fivesy_sixsy_sevensy_eightsy_ninesy_tensy_elevensy_twelvesy'.split('_');\n\n    moment.locale('difficult', {\n\n        monthsShort: function (m, format) {\n            var arr = format.match(/-MMM-/) ? monthsShortWeird : monthsShort;\n            return arr[m.month()];\n        }\n    });\n\n    assert.deepEqual(moment.monthsShort(), monthsShort);\n    assert.deepEqual(moment.monthsShort('MMM'), monthsShort);\n    assert.deepEqual(moment.monthsShort('-MMM-'), monthsShortWeird);\n\n    assert.deepEqual(moment.monthsShort('MMM', 2), 'three');\n    assert.deepEqual(moment.monthsShort('-MMM-', 2), 'threesy');\n    assert.deepEqual(moment.monthsShort(2), 'three');\n});\n\ntest('with locale data', function (assert) {\n    var months = 'one_two_three_four_five_six_seven_eight_nine_ten_eleven_twelve'.split('_'),\n        monthsShort = 'on_tw_th_fo_fi_si_se_ei_ni_te_el_tw'.split('_'),\n        weekdays = 'one_two_three_four_five_six_seven'.split('_'),\n        weekdaysShort = 'on_tw_th_fo_fi_si_se'.split('_'),\n        weekdaysMin = '1_2_3_4_5_6_7'.split('_'),\n        weekdaysLocale = 'four_five_six_seven_one_two_three'.split('_'),\n        weekdaysShortLocale = 'fo_fi_si_se_on_tw_th'.split('_'),\n        weekdaysMinLocale = '4_5_6_7_1_2_3'.split('_'),\n        week = {\n            dow : 3,\n            doy : 6\n        };\n\n    var customLocale = moment.localeData('numerologists');\n\n    assert.deepEqual(customLocale.months(), months);\n    assert.deepEqual(customLocale.monthsShort(), monthsShort);\n    assert.deepEqual(customLocale.weekdays(), weekdays);\n    assert.deepEqual(customLocale.weekdaysShort(), weekdaysShort);\n    assert.deepEqual(customLocale.weekdaysMin(), weekdaysMin);\n});\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/test/moment/locale.js",
    "content": "import { module, test } from '../qunit';\nimport moment from '../../moment';\nimport each from '../helpers/each';\nimport indexOf from '../../lib/utils/index-of';\n\nmodule('locale', {\n    setup : function () {\n        // TODO: Remove once locales are switched to ES6\n        each([{\n            name: 'en-gb',\n            data: {}\n        }, {\n            name: 'en-ca',\n            data: {}\n        }, {\n            name: 'es',\n            data: {\n                relativeTime: {past: 'hace %s', s: 'unos segundos', d: 'un día'},\n                months: 'enero_febrero_marzo_abril_mayo_junio_julio_agosto_septiembre_octubre_noviembre_diciembre'.split('_')\n            }\n        }, {\n            name: 'fr',\n            data: {}\n        }, {\n            name: 'fr-ca',\n            data: {}\n        }, {\n            name: 'it',\n            data: {}\n        }, {\n            name: 'zh-cn',\n            data: {\n                months: '一月_二月_三月_四月_五月_六月_七月_八月_九月_十月_十一月_十二月'.split('_')\n            }\n        }], function (locale) {\n            if (moment.locale(locale.name) !== locale.name) {\n                moment.defineLocale(locale.name, locale.data);\n            }\n        });\n        moment.locale('en');\n    }\n});\n\ntest('library getters and setters', function (assert) {\n    var r = moment.locale('en');\n\n    assert.equal(r, 'en', 'locale should return en by default');\n    assert.equal(moment.locale(), 'en', 'locale should return en by default');\n\n    moment.locale('fr');\n    assert.equal(moment.locale(), 'fr', 'locale should return the changed locale');\n\n    moment.locale('en-gb');\n    assert.equal(moment.locale(), 'en-gb', 'locale should return the changed locale');\n\n    moment.locale('en');\n    assert.equal(moment.locale(), 'en', 'locale should reset');\n\n    moment.locale('does-not-exist');\n    assert.equal(moment.locale(), 'en', 'locale should reset');\n\n    moment.locale('EN');\n    assert.equal(moment.locale(), 'en', 'Normalize locale key case');\n\n    moment.locale('EN_gb');\n    assert.equal(moment.locale(), 'en-gb', 'Normalize locale key underscore');\n});\n\ntest('library setter array of locales', function (assert) {\n    assert.equal(moment.locale(['non-existent', 'fr', 'also-non-existent']), 'fr', 'passing an array uses the first valid locale');\n    assert.equal(moment.locale(['es', 'fr', 'also-non-existent']), 'es', 'passing an array uses the first valid locale');\n});\n\ntest('library setter locale substrings', function (assert) {\n    assert.equal(moment.locale('fr-crap'), 'fr', 'use substrings');\n    assert.equal(moment.locale('fr-does-not-exist'), 'fr', 'uses deep substrings');\n    assert.equal(moment.locale('fr-CA-does-not-exist'), 'fr-ca', 'uses deepest substring');\n});\n\ntest('library getter locale array and substrings', function (assert) {\n    assert.equal(moment.locale(['en-CH', 'fr']), 'en', 'prefer root locale to shallower ones');\n    assert.equal(moment.locale(['en-gb-leeds', 'en-CA']), 'en-gb', 'prefer root locale to shallower ones');\n    assert.equal(moment.locale(['en-fake', 'en-CA']), 'en-ca', 'prefer alternatives with shared roots');\n    assert.equal(moment.locale(['en-fake', 'en-fake2', 'en-ca']), 'en-ca', 'prefer alternatives with shared roots');\n    assert.equal(moment.locale(['fake-CA', 'fake-MX', 'fr']), 'fr', 'always find something if possible');\n    assert.equal(moment.locale(['fake-CA', 'fake-MX', 'fr']), 'fr', 'always find something if possible');\n    assert.equal(moment.locale(['fake-CA', 'fake-MX', 'fr-fake-fake-fake']), 'fr', 'always find something if possible');\n    assert.equal(moment.locale(['en', 'en-CA']), 'en', 'prefer earlier if it works');\n});\n\ntest('library ensure inheritance', function (assert) {\n    moment.locale('made-up', {\n        // I put them out of order\n        months : 'February_March_April_May_June_July_August_September_October_November_December_January'.split('_')\n        // the rest of the properties should be inherited.\n    });\n\n    assert.equal(moment([2012, 5, 6]).format('MMMM'), 'July', 'Override some of the configs');\n    assert.equal(moment([2012, 5, 6]).format('MMM'), 'Jun', 'But not all of them');\n});\n\ntest('library ensure inheritance LT L LL LLL LLLL', function (assert) {\n    var locale = 'test-inherit-lt';\n\n    moment.defineLocale(locale, {\n        longDateFormat : {\n            LT : '-[LT]-',\n            L : '-[L]-',\n            LL : '-[LL]-',\n            LLL : '-[LLL]-',\n            LLLL : '-[LLLL]-'\n        },\n        calendar : {\n            sameDay : '[sameDay] LT',\n            nextDay : '[nextDay] L',\n            nextWeek : '[nextWeek] LL',\n            lastDay : '[lastDay] LLL',\n            lastWeek : '[lastWeek] LLLL',\n            sameElse : 'L'\n        }\n    });\n\n    moment.locale('es');\n\n    assert.equal(moment().locale(locale).calendar(), 'sameDay -LT-', 'Should use instance locale in LT formatting');\n    assert.equal(moment().add(1, 'days').locale(locale).calendar(), 'nextDay -L-', 'Should use instance locale in L formatting');\n    assert.equal(moment().add(-1, 'days').locale(locale).calendar(), 'lastDay -LLL-', 'Should use instance locale in LL formatting');\n    assert.equal(moment().add(4, 'days').locale(locale).calendar(), 'nextWeek -LL-', 'Should use instance locale in LLL formatting');\n    assert.equal(moment().add(-4, 'days').locale(locale).calendar(), 'lastWeek -LLLL-', 'Should use instance locale in LLLL formatting');\n});\n\ntest('library localeData', function (assert) {\n    moment.locale('en');\n\n    var jan = moment([2000, 0]);\n\n    assert.equal(moment.localeData().months(jan), 'January', 'no arguments returns global');\n    assert.equal(moment.localeData('zh-cn').months(jan), '一月', 'a string returns the locale based on key');\n    assert.equal(moment.localeData(moment().locale('es')).months(jan), 'enero', 'if you pass in a moment it uses the moment\\'s locale');\n});\n\ntest('library deprecations', function (assert) {\n    test.expectedDeprecations('moment.lang');\n    moment.lang('dude', {months: ['Movember']});\n    assert.equal(moment.locale(), 'dude', 'setting the lang sets the locale');\n    assert.equal(moment.lang(), moment.locale());\n    assert.equal(moment.langData(), moment.localeData(), 'langData is localeData');\n    moment.defineLocale('dude', null);\n});\n\ntest('defineLocale', function (assert) {\n    moment.locale('en');\n    moment.defineLocale('dude', {months: ['Movember']});\n    assert.equal(moment().locale(), 'dude', 'defineLocale also sets it');\n    assert.equal(moment().locale('dude').locale(), 'dude', 'defineLocale defines a locale');\n    moment.defineLocale('dude', null);\n});\n\ntest('locales', function (assert) {\n    moment.defineLocale('dude', {months: ['Movember']});\n    assert.equal(true, !!~indexOf.call(moment.locales(), 'dude'), 'locales returns an array of defined locales');\n    assert.equal(true, !!~indexOf.call(moment.locales(), 'en'), 'locales should always include english');\n    moment.defineLocale('dude', null);\n});\n\ntest('library convenience', function (assert) {\n    moment.locale('something', {week: {dow: 3}});\n    moment.locale('something');\n    assert.equal(moment.locale(), 'something', 'locale can be used to create the locale too');\n    moment.defineLocale('something', null);\n});\n\ntest('firstDayOfWeek firstDayOfYear locale getters', function (assert) {\n    moment.locale('something', {week: {dow: 3, doy: 4}});\n    moment.locale('something');\n    assert.equal(moment.localeData().firstDayOfWeek(), 3, 'firstDayOfWeek');\n    assert.equal(moment.localeData().firstDayOfYear(), 4, 'firstDayOfYear');\n    moment.defineLocale('something', null);\n});\n\ntest('instance locale method', function (assert) {\n    moment.locale('en');\n\n    assert.equal(moment([2012, 5, 6]).format('MMMM'), 'June', 'Normally default to global');\n    assert.equal(moment([2012, 5, 6]).locale('es').format('MMMM'), 'junio', 'Use the instance specific locale');\n    assert.equal(moment([2012, 5, 6]).format('MMMM'), 'June', 'Using an instance specific locale does not affect other moments');\n});\n\ntest('instance locale method with array', function (assert) {\n    var m = moment().locale(['non-existent', 'fr', 'also-non-existent']);\n    assert.equal(m.locale(), 'fr', 'passing an array uses the first valid locale');\n    m = moment().locale(['es', 'fr', 'also-non-existent']);\n    assert.equal(m.locale(), 'es', 'passing an array uses the first valid locale');\n});\n\ntest('instance getter locale substrings', function (assert) {\n    var m = moment();\n\n    m.locale('fr-crap');\n    assert.equal(m.locale(), 'fr', 'use substrings');\n\n    m.locale('fr-does-not-exist');\n    assert.equal(m.locale(), 'fr', 'uses deep substrings');\n});\n\ntest('instance locale persists with manipulation', function (assert) {\n    moment.locale('en');\n\n    assert.equal(moment([2012, 5, 6]).locale('es').add({days: 1}).format('MMMM'), 'junio', 'With addition');\n    assert.equal(moment([2012, 5, 6]).locale('es').day(0).format('MMMM'), 'junio', 'With day getter');\n    assert.equal(moment([2012, 5, 6]).locale('es').endOf('day').format('MMMM'), 'junio', 'With endOf');\n});\n\ntest('instance locale persists with cloning', function (assert) {\n    moment.locale('en');\n\n    var a = moment([2012, 5, 6]).locale('es'),\n        b = a.clone(),\n        c = moment(a);\n\n    assert.equal(b.format('MMMM'), 'junio', 'using moment.fn.clone()');\n    assert.equal(b.format('MMMM'), 'junio', 'using moment()');\n});\n\ntest('duration locale method', function (assert) {\n    moment.locale('en');\n\n    assert.equal(moment.duration({seconds:  44}).humanize(), 'a few seconds', 'Normally default to global');\n    assert.equal(moment.duration({seconds:  44}).locale('es').humanize(), 'unos segundos', 'Use the instance specific locale');\n    assert.equal(moment.duration({seconds:  44}).humanize(), 'a few seconds', 'Using an instance specific locale does not affect other durations');\n});\n\ntest('duration locale persists with cloning', function (assert) {\n    moment.locale('en');\n\n    var a = moment.duration({seconds:  44}).locale('es'),\n        b = moment.duration(a);\n\n    assert.equal(b.humanize(), 'unos segundos', 'using moment.duration()');\n});\n\ntest('changing the global locale doesn\\'t affect existing duration instances', function (assert) {\n    var mom = moment.duration();\n    moment.locale('fr');\n    assert.equal('en', mom.locale());\n});\n\ntest('duration deprecations', function (assert) {\n    test.expectedDeprecations('moment().lang()');\n    assert.equal(moment.duration().lang(), moment.duration().localeData(), 'duration.lang is the same as duration.localeData');\n});\n\ntest('from and fromNow with invalid date', function (assert) {\n    assert.equal(moment(NaN).from(), 'Invalid date', 'moment.from with invalid moment');\n    assert.equal(moment(NaN).fromNow(), 'Invalid date', 'moment.fromNow with invalid moment');\n});\n\ntest('from relative time future', function (assert) {\n    var start = moment([2007, 1, 28]);\n\n    assert.equal(start.from(moment([2007, 1, 28]).subtract({s: 44})),  'in a few seconds', '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).subtract({s: 45})),  'in a minute',      '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).subtract({s: 89})),  'in a minute',      '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).subtract({s: 90})),  'in 2 minutes',     '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).subtract({m: 44})),  'in 44 minutes',    '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).subtract({m: 45})),  'in an hour',       '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).subtract({m: 89})),  'in an hour',       '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).subtract({m: 90})),  'in 2 hours',       '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).subtract({h: 5})),   'in 5 hours',       '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).subtract({h: 21})),  'in 21 hours',      '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).subtract({h: 22})),  'in a day',         '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).subtract({h: 35})),  'in a day',         '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).subtract({h: 36})),  'in 2 days',        '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).subtract({d: 1})),   'in a day',         '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).subtract({d: 5})),   'in 5 days',        '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).subtract({d: 25})),  'in 25 days',       '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).subtract({d: 26})),  'in a month',       '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).subtract({d: 30})),  'in a month',       '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).subtract({d: 45})),  'in a month',       '45 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).subtract({d: 47})),  'in 2 months',      '47 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).subtract({d: 74})),  'in 2 months',      '74 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).subtract({d: 78})),  'in 3 months',      '78 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).subtract({M: 1})),   'in a month',       '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).subtract({M: 5})),   'in 5 months',      '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).subtract({d: 315})), 'in 10 months',     '315 days = 10 months');\n    assert.equal(start.from(moment([2007, 1, 28]).subtract({d: 344})), 'in a year',        '344 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).subtract({d: 345})), 'in a year',        '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).subtract({d: 548})), 'in 2 years',       '548 days = in 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).subtract({y: 1})),   'in a year',        '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).subtract({y: 5})),   'in 5 years',       '5 years = 5 years');\n});\n\ntest('from relative time past', function (assert) {\n    var start = moment([2007, 1, 28]);\n\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44})),  'a few seconds ago', '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45})),  'a minute ago',      '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89})),  'a minute ago',      '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90})),  '2 minutes ago',     '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44})),  '44 minutes ago',    '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45})),  'an hour ago',       '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89})),  'an hour ago',       '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90})),  '2 hours ago',       '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5})),   '5 hours ago',       '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21})),  '21 hours ago',      '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22})),  'a day ago',         '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35})),  'a day ago',         '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36})),  '2 days ago',        '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1})),   'a day ago',         '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5})),   '5 days ago',        '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25})),  '25 days ago',       '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26})),  'a month ago',       '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30})),  'a month ago',       '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43})),  'a month ago',       '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46})),  '2 months ago',      '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74})),  '2 months ago',      '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76})),  '3 months ago',      '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1})),   'a month ago',       '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5})),   '5 months ago',      '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 315})), '10 months ago',     '315 days = 10 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 344})), 'a year ago',        '344 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345})), 'a year ago',        '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548})), '2 years ago',       '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1})),   'a year ago',        '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5})),   '5 years ago',       '5 years = 5 years');\n});\n\ntest('instance locale used with from', function (assert) {\n    moment.locale('en');\n\n    var a = moment([2012, 5, 6]).locale('es'),\n        b = moment([2012, 5, 7]);\n\n    assert.equal(a.from(b), 'hace un día', 'preserve locale of first moment');\n    assert.equal(b.from(a), 'in a day', 'do not preserve locale of second moment');\n});\n\ntest('instance localeData', function (assert) {\n    moment.defineLocale('dude', {week: {dow: 3}});\n    assert.equal(moment().locale('dude').localeData()._week.dow, 3);\n    moment.defineLocale('dude', null);\n});\n\ntest('month name callback function', function (assert) {\n    function fakeReplace(m, format) {\n        if (/test/.test(format)) {\n            return 'test';\n        }\n        if (m.date() === 1) {\n            return 'date';\n        }\n        return 'default';\n    }\n\n    moment.locale('made-up-2', {\n        months : fakeReplace,\n        monthsShort : fakeReplace,\n        weekdays : fakeReplace,\n        weekdaysShort : fakeReplace,\n        weekdaysMin : fakeReplace\n    });\n\n    assert.equal(moment().format('[test] dd ddd dddd MMM MMMM'), 'test test test test test test', 'format month name function should be able to access the format string');\n    assert.equal(moment([2011, 0, 1]).format('dd ddd dddd MMM MMMM'), 'date date date date date', 'format month name function should be able to access the moment object');\n    assert.equal(moment([2011, 0, 2]).format('dd ddd dddd MMM MMMM'), 'default default default default default', 'format month name function should be able to access the moment object');\n});\n\ntest('changing parts of a locale config', function (assert) {\n    test.expectedDeprecations('defineLocaleOverride');\n\n    moment.locale('partial-lang', {\n        months : 'a b c d e f g h i j k l'.split(' ')\n    });\n\n    assert.equal(moment([2011, 0, 1]).format('MMMM'), 'a', 'should be able to set locale values when creating the localeuage');\n\n    moment.locale('partial-lang', {\n        monthsShort : 'A B C D E F G H I J K L'.split(' ')\n    });\n\n    assert.equal(moment([2011, 0, 1]).format('MMMM MMM'), 'a A', 'should be able to set locale values after creating the localeuage');\n\n    moment.defineLocale('partial-lang', null);\n});\n\ntest('start/endOf week feature for first-day-is-monday locales', function (assert) {\n    moment.locale('monday-lang', {\n        week : {\n            dow : 1 // Monday is the first day of the week\n        }\n    });\n\n    moment.locale('monday-lang');\n    assert.equal(moment([2013, 0, 1]).startOf('week').day(), 1, 'for locale monday-lang first day of the week should be monday');\n    assert.equal(moment([2013, 0, 1]).endOf('week').day(), 0, 'for locale monday-lang last day of the week should be sunday');\n    moment.defineLocale('monday-lang', null);\n});\n\ntest('meridiem parsing', function (assert) {\n    moment.locale('meridiem-parsing', {\n        meridiemParse : /[bd]/i,\n        isPM : function (input) {\n            return input === 'b';\n        }\n    });\n\n    moment.locale('meridiem-parsing');\n    assert.equal(moment('2012-01-01 3b', 'YYYY-MM-DD ha').hour(), 15, 'Custom parsing of meridiem should work');\n    assert.equal(moment('2012-01-01 3d', 'YYYY-MM-DD ha').hour(), 3, 'Custom parsing of meridiem should work');\n    moment.defineLocale('meridiem-parsing', null);\n});\n\ntest('invalid date formatting', function (assert) {\n    moment.locale('has-invalid', {\n        invalidDate: 'KHAAAAAAAAAAAN!'\n    });\n\n    assert.equal(moment.invalid().format(), 'KHAAAAAAAAAAAN!');\n    assert.equal(moment.invalid().format('YYYY-MM-DD'), 'KHAAAAAAAAAAAN!');\n    moment.defineLocale('has-invalid', null);\n});\n\ntest('return locale name', function (assert) {\n    var registered = moment.locale('return-this', {});\n\n    assert.equal(registered, 'return-this', 'returns the locale configured');\n    moment.locale('return-this', null);\n});\n\ntest('changing the global locale doesn\\'t affect existing instances', function (assert) {\n    var mom = moment();\n    moment.locale('fr');\n    assert.equal('en', mom.locale());\n});\n\ntest('setting a language on instance returns the original moment for chaining', function (assert) {\n    test.expectedDeprecations('moment().lang()');\n    var mom = moment();\n\n    assert.equal(mom.lang('fr'), mom, 'setting the language (lang) returns the original moment for chaining');\n    assert.equal(mom.locale('it'), mom, 'setting the language (locale) returns the original moment for chaining');\n});\n\ntest('lang(key) changes the language of the instance', function (assert) {\n    test.expectedDeprecations('moment().lang()');\n    var m = moment().month(0);\n    m.lang('fr');\n    assert.equal(m.locale(), 'fr', 'm.lang(key) changes instance locale');\n});\n\ntest('moment#locale(false) resets to global locale', function (assert) {\n    var m = moment();\n\n    moment.locale('fr');\n    m.locale('it');\n\n    assert.equal(moment.locale(), 'fr', 'global locale is it');\n    assert.equal(m.locale(), 'it', 'instance locale is it');\n    m.locale(false);\n    assert.equal(m.locale(), 'fr', 'instance locale reset to global locale');\n});\n\ntest('moment().locale with missing key doesn\\'t change locale', function (assert) {\n    assert.equal(moment().locale('boo').localeData(), moment.localeData(),\n            'preserve global locale in case of bad locale id');\n});\n\ntest('moment().lang with missing key doesn\\'t change locale', function (assert) {\n    test.expectedDeprecations('moment().lang()');\n    assert.equal(moment().lang('boo').localeData(), moment.localeData(),\n            'preserve global locale in case of bad locale id');\n});\n\n\n// TODO: Enable this after fixing pl months parse hack hack\n// test('monthsParseExact', function (assert) {\n//     var locale = 'test-months-parse-exact';\n\n//     moment.defineLocale(locale, {\n//         monthsParseExact: true,\n//         months: 'A_AA_AAA_B_B B_BB  B_C_C-C_C,C2C_D_D+D_D`D*D'.split('_'),\n//         monthsShort: 'E_EE_EEE_F_FF_FFF_G_GG_GGG_H_HH_HHH'.split('_')\n//     });\n\n//     assert.equal(moment('A', 'MMMM', true).month(), 0, 'parse long month 0 with MMMM');\n//     assert.equal(moment('AA', 'MMMM', true).month(), 1, 'parse long month 1 with MMMM');\n//     assert.equal(moment('AAA', 'MMMM', true).month(), 2, 'parse long month 2 with MMMM');\n//     assert.equal(moment('B B', 'MMMM', true).month(), 4, 'parse long month 4 with MMMM');\n//     assert.equal(moment('BB  B', 'MMMM', true).month(), 5, 'parse long month 5 with MMMM');\n//     assert.equal(moment('C-C', 'MMMM', true).month(), 7, 'parse long month 7 with MMMM');\n//     assert.equal(moment('C,C2C', 'MMMM', true).month(), 8, 'parse long month 8 with MMMM');\n//     assert.equal(moment('D+D', 'MMMM', true).month(), 10, 'parse long month 10 with MMMM');\n//     assert.equal(moment('D`D*D', 'MMMM', true).month(), 11, 'parse long month 11 with MMMM');\n\n//     assert.equal(moment('E', 'MMM', true).month(), 0, 'parse long month 0 with MMM');\n//     assert.equal(moment('EE', 'MMM', true).month(), 1, 'parse long month 1 with MMM');\n//     assert.equal(moment('EEE', 'MMM', true).month(), 2, 'parse long month 2 with MMM');\n\n//     assert.equal(moment('A', 'MMM').month(), 0, 'non-strict parse long month 0 with MMM');\n//     assert.equal(moment('AA', 'MMM').month(), 1, 'non-strict parse long month 1 with MMM');\n//     assert.equal(moment('AAA', 'MMM').month(), 2, 'non-strict parse long month 2 with MMM');\n//     assert.equal(moment('E', 'MMMM').month(), 0, 'non-strict parse short month 0 with MMMM');\n//     assert.equal(moment('EE', 'MMMM').month(), 1, 'non-strict parse short month 1 with MMMM');\n//     assert.equal(moment('EEE', 'MMMM').month(), 2, 'non-strict parse short month 2 with MMMM');\n// });\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/test/moment/locale_inheritance.js",
    "content": "import { module, test } from '../qunit';\nimport moment from '../../moment';\n\nmodule('locale inheritance');\n\ntest('calendar', function (assert) {\n    moment.defineLocale('base-cal', {\n        calendar : {\n            sameDay: '[Today at] HH:mm',\n            nextDay: '[Tomorrow at] HH:mm',\n            nextWeek: '[Next week at] HH:mm',\n            lastDay: '[Yesterday at] HH:mm',\n            lastWeek: '[Last week at] HH:mm',\n            sameElse: '[whatever]'\n        }\n    });\n    moment.defineLocale('child-cal', {\n        parentLocale: 'base-cal',\n        calendar: {\n            sameDay: '[Today] HH:mm',\n            nextDay: '[Tomorrow] HH:mm',\n            nextWeek: '[Next week] HH:mm'\n        }\n    });\n\n    moment.locale('child-cal');\n    var anchor = moment.utc('2015-05-05T12:00:00', moment.ISO_8601);\n    assert.equal(anchor.clone().add(3, 'hours').calendar(anchor), 'Today 15:00', 'today uses child version');\n    assert.equal(anchor.clone().add(1, 'day').calendar(anchor), 'Tomorrow 12:00', 'tomorrow uses child version');\n    assert.equal(anchor.clone().add(3, 'days').calendar(anchor), 'Next week 12:00', 'next week uses child version');\n\n    assert.equal(anchor.clone().subtract(1, 'day').calendar(anchor), 'Yesterday at 12:00', 'yesterday uses parent version');\n    assert.equal(anchor.clone().subtract(3, 'days').calendar(anchor), 'Last week at 12:00', 'last week uses parent version');\n    assert.equal(anchor.clone().subtract(7, 'days').calendar(anchor), 'whatever', 'sameElse uses parent version -');\n    assert.equal(anchor.clone().add(7, 'days').calendar(anchor), 'whatever', 'sameElse uses parent version +');\n});\n\ntest('missing', function (assert) {\n    moment.defineLocale('base-cal-2', {\n        calendar: {\n            sameDay: '[Today at] HH:mm',\n            nextDay: '[Tomorrow at] HH:mm',\n            nextWeek: '[Next week at] HH:mm',\n            lastDay: '[Yesterday at] HH:mm',\n            lastWeek: '[Last week at] HH:mm',\n            sameElse: '[whatever]'\n        }\n    });\n    moment.defineLocale('child-cal-2', {\n        parentLocale: 'base-cal-2'\n    });\n    moment.locale('child-cal-2');\n    var anchor = moment.utc('2015-05-05T12:00:00', moment.ISO_8601);\n    assert.equal(anchor.clone().add(3, 'hours').calendar(anchor), 'Today at 15:00', 'today uses parent version');\n    assert.equal(anchor.clone().add(1, 'day').calendar(anchor), 'Tomorrow at 12:00', 'tomorrow uses parent version');\n    assert.equal(anchor.clone().add(3, 'days').calendar(anchor), 'Next week at 12:00', 'next week uses parent version');\n    assert.equal(anchor.clone().subtract(1, 'day').calendar(anchor), 'Yesterday at 12:00', 'yesterday uses parent version');\n    assert.equal(anchor.clone().subtract(3, 'days').calendar(anchor), 'Last week at 12:00', 'last week uses parent version');\n    assert.equal(anchor.clone().subtract(7, 'days').calendar(anchor), 'whatever', 'sameElse uses parent version -');\n    assert.equal(anchor.clone().add(7, 'days').calendar(anchor), 'whatever', 'sameElse uses parent version +');\n});\n\n// Test function vs obj both directions\n\ntest('long date format', function (assert) {\n    moment.defineLocale('base-ldf', {\n        longDateFormat : {\n            LTS  : 'h:mm:ss A',\n            LT   : 'h:mm A',\n            L    : 'MM/DD/YYYY',\n            LL   : 'MMMM D, YYYY',\n            LLL  : 'MMMM D, YYYY h:mm A',\n            LLLL : 'dddd, MMMM D, YYYY h:mm A'\n        }\n    });\n    moment.defineLocale('child-ldf', {\n        parentLocale: 'base-ldf',\n        longDateFormat: {\n            LLL  : '[child] MMMM D, YYYY h:mm A',\n            LLLL : '[child] dddd, MMMM D, YYYY h:mm A'\n        }\n    });\n\n    moment.locale('child-ldf');\n    var anchor = moment.utc('2015-09-06T12:34:56', moment.ISO_8601);\n    assert.equal(anchor.format('LTS'), '12:34:56 PM', 'LTS uses base');\n    assert.equal(anchor.format('LT'), '12:34 PM', 'LT uses base');\n    assert.equal(anchor.format('L'), '09/06/2015', 'L uses base');\n    assert.equal(anchor.format('l'), '9/6/2015', 'l uses base');\n    assert.equal(anchor.format('LL'), 'September 6, 2015', 'LL uses base');\n    assert.equal(anchor.format('ll'), 'Sep 6, 2015', 'll uses base');\n    assert.equal(anchor.format('LLL'), 'child September 6, 2015 12:34 PM', 'LLL uses child');\n    assert.equal(anchor.format('lll'), 'child Sep 6, 2015 12:34 PM', 'lll uses child');\n    assert.equal(anchor.format('LLLL'), 'child Sunday, September 6, 2015 12:34 PM', 'LLLL uses child');\n    assert.equal(anchor.format('llll'), 'child Sun, Sep 6, 2015 12:34 PM', 'llll uses child');\n});\n\ntest('ordinal', function (assert) {\n    moment.defineLocale('base-ordinal-1', {\n        ordinal : '%dx'\n    });\n    moment.defineLocale('child-ordinal-1', {\n        parentLocale: 'base-ordinal-1',\n        ordinal : '%dy'\n    });\n\n    assert.equal(moment.utc('2015-02-03', moment.ISO_8601).format('Do'), '3y', 'ordinal uses child string');\n\n    moment.defineLocale('base-ordinal-2', {\n        ordinal : '%dx'\n    });\n    moment.defineLocale('child-ordinal-2', {\n        parentLocale: 'base-ordinal-2',\n        ordinal : function (num) {\n            return num + 'y';\n        }\n    });\n\n    assert.equal(moment.utc('2015-02-03', moment.ISO_8601).format('Do'), '3y', 'ordinal uses child function');\n\n    moment.defineLocale('base-ordinal-3', {\n        ordinal : function (num) {\n            return num + 'x';\n        }\n    });\n    moment.defineLocale('child-ordinal-3', {\n        parentLocale: 'base-ordinal-3',\n        ordinal : '%dy'\n    });\n\n    assert.equal(moment.utc('2015-02-03', moment.ISO_8601).format('Do'), '3y', 'ordinal uses child string (overwrite parent function)');\n});\n\ntest('ordinal parse', function (assert) {\n    moment.defineLocale('base-ordinal-parse-1', {\n        dayOfMonthOrdinalParse : /\\d{1,2}x/\n    });\n    moment.defineLocale('child-ordinal-parse-1', {\n        parentLocale: 'base-ordinal-parse-1',\n        dayOfMonthOrdinalParse : /\\d{1,2}y/\n    });\n\n    assert.ok(moment.utc('2015-01-1y', 'YYYY-MM-Do', true).isValid(), 'ordinal parse uses child');\n\n    moment.defineLocale('base-ordinal-parse-2', {\n        dayOfMonthOrdinalParse : /\\d{1,2}x/\n    });\n    moment.defineLocale('child-ordinal-parse-2', {\n        parentLocale: 'base-ordinal-parse-2',\n        dayOfMonthOrdinalParse : /\\d{1,2}/\n    });\n\n    assert.ok(moment.utc('2015-01-1', 'YYYY-MM-Do', true).isValid(), 'ordinal parse uses child (default)');\n});\n\ntest('months', function (assert) {\n    moment.defineLocale('base-months', {\n        months : 'One_Two_Three_Four_Five_Six_Seven_Eight_Nine_Ten_Eleven_Twelve'.split('_')\n    });\n    moment.defineLocale('child-months', {\n        parentLocale: 'base-months',\n        months : 'First_Second_Third_Fourth_Fifth_Sixth_Seventh_Eighth_Ninth_Tenth_Eleventh_Twelveth '.split('_')\n    });\n    assert.ok(moment.utc('2015-01-01', 'YYYY-MM-DD').format('MMMM'), 'First', 'months uses child');\n});\n\ntest('define child locale before parent', function (assert) {\n    moment.defineLocale('months-x', null);\n    moment.defineLocale('base-months-x', null);\n\n    moment.defineLocale('months-x', {\n        parentLocale: 'base-months-x',\n        months : 'First_Second_Third_Fourth_Fifth_Sixth_Seventh_Eighth_Ninth_Tenth_Eleventh_Twelveth '.split('_')\n    });\n    assert.equal(moment.locale(), 'en', 'failed to set a locale requiring missing parent');\n    moment.defineLocale('base-months-x', {\n        months : 'One_Two_Three_Four_Five_Six_Seven_Eight_Nine_Ten_Eleven_Twelve'.split('_')\n    });\n    assert.equal(moment.locale(), 'base-months-x', 'defineLocale should also set the locale (regardless of child locales)');\n\n    assert.equal(moment().locale('months-x').month(0).format('MMMM'), 'First', 'loading child before parent locale works');\n});\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/test/moment/locale_update.js",
    "content": "import { module, test } from '../qunit';\nimport moment from '../../moment';\n\nmodule('locale update');\n\ntest('calendar', function (assert) {\n    moment.defineLocale('cal', null);\n    moment.defineLocale('cal', {\n        calendar : {\n            sameDay: '[Today at] HH:mm',\n            nextDay: '[Tomorrow at] HH:mm',\n            nextWeek: '[Next week at] HH:mm',\n            lastDay: '[Yesterday at] HH:mm',\n            lastWeek: '[Last week at] HH:mm',\n            sameElse: '[whatever]'\n        }\n    });\n    moment.updateLocale('cal', {\n        calendar: {\n            sameDay: '[Today] HH:mm',\n            nextDay: '[Tomorrow] HH:mm',\n            nextWeek: '[Next week] HH:mm'\n        }\n    });\n\n    moment.locale('cal');\n    var anchor = moment.utc('2015-05-05T12:00:00', moment.ISO_8601);\n    assert.equal(anchor.clone().add(3, 'hours').calendar(anchor), 'Today 15:00', 'today uses child version');\n    assert.equal(anchor.clone().add(1, 'day').calendar(anchor), 'Tomorrow 12:00', 'tomorrow uses child version');\n    assert.equal(anchor.clone().add(3, 'days').calendar(anchor), 'Next week 12:00', 'next week uses child version');\n\n    assert.equal(anchor.clone().subtract(1, 'day').calendar(anchor), 'Yesterday at 12:00', 'yesterday uses parent version');\n    assert.equal(anchor.clone().subtract(3, 'days').calendar(anchor), 'Last week at 12:00', 'last week uses parent version');\n    assert.equal(anchor.clone().subtract(7, 'days').calendar(anchor), 'whatever', 'sameElse uses parent version -');\n    assert.equal(anchor.clone().add(7, 'days').calendar(anchor), 'whatever', 'sameElse uses parent version +');\n});\n\ntest('missing', function (assert) {\n    moment.defineLocale('cal-2', null);\n    moment.defineLocale('cal-2', {\n        calendar: {\n            sameDay: '[Today at] HH:mm',\n            nextDay: '[Tomorrow at] HH:mm',\n            nextWeek: '[Next week at] HH:mm',\n            lastDay: '[Yesterday at] HH:mm',\n            lastWeek: '[Last week at] HH:mm',\n            sameElse: '[whatever]'\n        }\n    });\n    moment.updateLocale('cal-2', {\n    });\n    moment.locale('cal-2');\n    var anchor = moment.utc('2015-05-05T12:00:00', moment.ISO_8601);\n    assert.equal(anchor.clone().add(3, 'hours').calendar(anchor), 'Today at 15:00', 'today uses parent version');\n    assert.equal(anchor.clone().add(1, 'day').calendar(anchor), 'Tomorrow at 12:00', 'tomorrow uses parent version');\n    assert.equal(anchor.clone().add(3, 'days').calendar(anchor), 'Next week at 12:00', 'next week uses parent version');\n    assert.equal(anchor.clone().subtract(1, 'day').calendar(anchor), 'Yesterday at 12:00', 'yesterday uses parent version');\n    assert.equal(anchor.clone().subtract(3, 'days').calendar(anchor), 'Last week at 12:00', 'last week uses parent version');\n    assert.equal(anchor.clone().subtract(7, 'days').calendar(anchor), 'whatever', 'sameElse uses parent version -');\n    assert.equal(anchor.clone().add(7, 'days').calendar(anchor), 'whatever', 'sameElse uses parent version +');\n});\n\n// Test function vs obj both directions\n\ntest('long date format', function (assert) {\n    moment.defineLocale('ldf', null);\n    moment.defineLocale('ldf', {\n        longDateFormat : {\n            LTS  : 'h:mm:ss A',\n            LT   : 'h:mm A',\n            L    : 'MM/DD/YYYY',\n            LL   : 'MMMM D, YYYY',\n            LLL  : 'MMMM D, YYYY h:mm A',\n            LLLL : 'dddd, MMMM D, YYYY h:mm A'\n        }\n    });\n    moment.updateLocale('ldf', {\n        longDateFormat: {\n            LLL  : '[child] MMMM D, YYYY h:mm A',\n            LLLL : '[child] dddd, MMMM D, YYYY h:mm A'\n        }\n    });\n\n    moment.locale('ldf');\n    var anchor = moment.utc('2015-09-06T12:34:56', moment.ISO_8601);\n    assert.equal(anchor.format('LTS'), '12:34:56 PM', 'LTS uses base');\n    assert.equal(anchor.format('LT'), '12:34 PM', 'LT uses base');\n    assert.equal(anchor.format('L'), '09/06/2015', 'L uses base');\n    assert.equal(anchor.format('l'), '9/6/2015', 'l uses base');\n    assert.equal(anchor.format('LL'), 'September 6, 2015', 'LL uses base');\n    assert.equal(anchor.format('ll'), 'Sep 6, 2015', 'll uses base');\n    assert.equal(anchor.format('LLL'), 'child September 6, 2015 12:34 PM', 'LLL uses child');\n    assert.equal(anchor.format('lll'), 'child Sep 6, 2015 12:34 PM', 'lll uses child');\n    assert.equal(anchor.format('LLLL'), 'child Sunday, September 6, 2015 12:34 PM', 'LLLL uses child');\n    assert.equal(anchor.format('llll'), 'child Sun, Sep 6, 2015 12:34 PM', 'llll uses child');\n});\n\ntest('ordinal', function (assert) {\n    moment.defineLocale('ordinal-1', null);\n    moment.defineLocale('ordinal-1', {\n        ordinal : '%dx'\n    });\n    moment.updateLocale('ordinal-1', {\n        ordinal : '%dy'\n    });\n\n    assert.equal(moment.utc('2015-02-03', moment.ISO_8601).format('Do'), '3y', 'ordinal uses child string');\n\n    moment.defineLocale('ordinal-2', null);\n    moment.defineLocale('ordinal-2', {\n        ordinal : '%dx'\n    });\n    moment.updateLocale('ordinal-2', {\n        ordinal : function (num) {\n            return num + 'y';\n        }\n    });\n\n    assert.equal(moment.utc('2015-02-03', moment.ISO_8601).format('Do'), '3y', 'ordinal uses child function');\n\n    moment.defineLocale('ordinal-3', null);\n    moment.defineLocale('ordinal-3', {\n        ordinal : function (num) {\n            return num + 'x';\n        }\n    });\n    moment.updateLocale('ordinal-3', {\n        ordinal : '%dy'\n    });\n\n    assert.equal(moment.utc('2015-02-03', moment.ISO_8601).format('Do'), '3y', 'ordinal uses child string (overwrite parent function)');\n});\n\ntest('ordinal parse', function (assert) {\n    moment.defineLocale('ordinal-parse-1', null);\n    moment.defineLocale('ordinal-parse-1', {\n        dayOfMonthOrdinalParse : /\\d{1,2}x/\n    });\n    moment.updateLocale('ordinal-parse-1', {\n        dayOfMonthOrdinalParse : /\\d{1,2}y/\n    });\n\n    assert.ok(moment.utc('2015-01-1y', 'YYYY-MM-Do', true).isValid(), 'ordinal parse uses child');\n\n    moment.defineLocale('ordinal-parse-2', null);\n    moment.defineLocale('ordinal-parse-2', {\n        dayOfMonthOrdinalParse : /\\d{1,2}x/\n    });\n    moment.updateLocale('ordinal-parse-2', {\n        dayOfMonthOrdinalParse : /\\d{1,2}/\n    });\n\n    assert.ok(moment.utc('2015-01-1', 'YYYY-MM-Do', true).isValid(), 'ordinal parse uses child (default)');\n});\n\ntest('months', function (assert) {\n    moment.defineLocale('months', null);\n    moment.defineLocale('months', {\n        months : 'One_Two_Three_Four_Five_Six_Seven_Eight_Nine_Ten_Eleven_Twelve'.split('_')\n    });\n    moment.updateLocale('months', {\n        parentLocale: 'base-months',\n        months : 'First_Second_Third_Fourth_Fifth_Sixth_Seventh_Eighth_Ninth_Tenth_Eleventh_Twelveth '.split('_')\n    });\n    assert.ok(moment.utc('2015-01-01', 'YYYY-MM-DD').format('MMMM'), 'First', 'months uses child');\n});\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/test/moment/min_max.js",
    "content": "import { module, test } from '../qunit';\nimport moment from '../../moment';\n\nmodule('min max');\n\ntest('min', function (assert) {\n    var now = moment(),\n        future = now.clone().add(1, 'month'),\n        past = now.clone().subtract(1, 'month'),\n        invalid = moment.invalid();\n\n    assert.equal(moment.min(now, future, past), past, 'min(now, future, past)');\n    assert.equal(moment.min(future, now, past), past, 'min(future, now, past)');\n    assert.equal(moment.min(future, past, now), past, 'min(future, past, now)');\n    assert.equal(moment.min(past, future, now), past, 'min(past, future, now)');\n    assert.equal(moment.min(now, past), past, 'min(now, past)');\n    assert.equal(moment.min(past, now), past, 'min(past, now)');\n    assert.equal(moment.min(now), now, 'min(now, past)');\n\n    assert.equal(moment.min([now, future, past]), past, 'min([now, future, past])');\n    assert.equal(moment.min([now, past]), past, 'min(now, past)');\n    assert.equal(moment.min([now]), now, 'min(now)');\n\n    assert.equal(moment.min([now, invalid]), invalid, 'min(now, invalid)');\n    assert.equal(moment.min([invalid, now]), invalid, 'min(invalid, now)');\n});\n\ntest('max', function (assert) {\n    var now = moment(),\n        future = now.clone().add(1, 'month'),\n        past = now.clone().subtract(1, 'month'),\n        invalid = moment.invalid();\n\n    assert.equal(moment.max(now, future, past), future, 'max(now, future, past)');\n    assert.equal(moment.max(future, now, past), future, 'max(future, now, past)');\n    assert.equal(moment.max(future, past, now), future, 'max(future, past, now)');\n    assert.equal(moment.max(past, future, now), future, 'max(past, future, now)');\n    assert.equal(moment.max(now, past), now, 'max(now, past)');\n    assert.equal(moment.max(past, now), now, 'max(past, now)');\n    assert.equal(moment.max(now), now, 'max(now, past)');\n\n    assert.equal(moment.max([now, future, past]), future, 'max([now, future, past])');\n    assert.equal(moment.max([now, past]), now, 'max(now, past)');\n    assert.equal(moment.max([now]), now, 'max(now)');\n\n    assert.equal(moment.max([now, invalid]), invalid, 'max(now, invalid)');\n    assert.equal(moment.max([invalid, now]), invalid, 'max(invalid, now)');\n});\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/test/moment/mutable.js",
    "content": "import { module, test } from '../qunit';\nimport moment from '../../moment';\n\nmodule('mutable');\n\ntest('manipulation methods', function (assert) {\n    var m = moment();\n\n    assert.equal(m, m.year(2011), 'year() should be mutable');\n    assert.equal(m, m.month(1), 'month() should be mutable');\n    assert.equal(m, m.hours(7), 'hours() should be mutable');\n    assert.equal(m, m.minutes(33), 'minutes() should be mutable');\n    assert.equal(m, m.seconds(44), 'seconds() should be mutable');\n    assert.equal(m, m.milliseconds(55), 'milliseconds() should be mutable');\n    assert.equal(m, m.day(2), 'day() should be mutable');\n    assert.equal(m, m.startOf('week'), 'startOf() should be mutable');\n    assert.equal(m, m.add(1, 'days'), 'add() should be mutable');\n    assert.equal(m, m.subtract(2, 'years'), 'subtract() should be mutable');\n    assert.equal(m, m.local(), 'local() should be mutable');\n    assert.equal(m, m.utc(), 'utc() should be mutable');\n});\n\ntest('non mutable methods', function (assert) {\n    var m = moment();\n    assert.notEqual(m, m.clone(), 'clone() should not be mutable');\n});\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/test/moment/normalize_units.js",
    "content": "import { module, test } from '../qunit';\nimport moment from '../../moment';\n\nmodule('normalize units');\n\ntest('normalize units', function (assert) {\n    var fullKeys = ['year', 'quarter', 'month', 'isoWeek', 'week', 'day', 'hour', 'minute', 'second', 'millisecond', 'date', 'dayOfYear', 'weekday', 'isoWeekday', 'weekYear', 'isoWeekYear'],\n        aliases = ['y', 'Q', 'M', 'W', 'w', 'd', 'h', 'm', 's', 'ms', 'D', 'DDD', 'e', 'E', 'gg', 'GG'],\n        length = fullKeys.length,\n        fullKey,\n        fullKeyCaps,\n        fullKeyPlural,\n        fullKeyCapsPlural,\n        fullKeyLower,\n        alias,\n        index;\n\n    for (index = 0; index < length; index += 1) {\n        fullKey = fullKeys[index];\n        fullKeyCaps = fullKey.toUpperCase();\n        fullKeyLower = fullKey.toLowerCase();\n        fullKeyPlural = fullKey + 's';\n        fullKeyCapsPlural = fullKeyCaps + 's';\n        alias = aliases[index];\n        assert.equal(moment.normalizeUnits(fullKey), fullKey, 'Testing full key ' + fullKey);\n        assert.equal(moment.normalizeUnits(fullKeyCaps), fullKey, 'Testing full key capitalised ' + fullKey);\n        assert.equal(moment.normalizeUnits(fullKeyPlural), fullKey, 'Testing full key plural ' + fullKey);\n        assert.equal(moment.normalizeUnits(fullKeyCapsPlural), fullKey, 'Testing full key capitalised and plural ' + fullKey);\n        assert.equal(moment.normalizeUnits(alias), fullKey, 'Testing alias ' + fullKey);\n    }\n});\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/test/moment/now.js",
    "content": "import { module, test, expect } from '../qunit';\nimport moment from '../../moment';\n\nmodule('now');\n\ntest('now', function (assert) {\n    var startOfTest = new Date().valueOf(),\n        momentNowTime = moment.now(),\n        afterMomentCreationTime = new Date().valueOf();\n\n    assert.ok(startOfTest <= momentNowTime, 'moment now() time should be now, not in the past');\n    assert.ok(momentNowTime <= afterMomentCreationTime, 'moment now() time should be now, not in the future');\n});\n\ntest('now - Date mocked', function (assert) {\n    // We need to test mocking the global Date object, so disable 'Read Only' jshint check\n    /* jshint -W020 */\n    var RealDate = Date,\n        customTimeMs = moment('2015-01-01T01:30:00.000Z').valueOf();\n\n    function MockDate() {\n        return new RealDate(customTimeMs);\n    }\n\n    MockDate.now = function () {\n        return new MockDate().valueOf();\n    };\n\n    MockDate.prototype = RealDate.prototype;\n\n    Date = MockDate;\n\n    try {\n        assert.equal(moment().valueOf(), customTimeMs, 'moment now() time should use the global Date object');\n    } finally {\n        Date = RealDate;\n    }\n});\n\ntest('now - custom value', function (assert) {\n    var customTimeStr = '2015-01-01T01:30:00.000Z',\n        customTime = moment(customTimeStr, moment.ISO_8601).valueOf(),\n        oldFn = moment.now;\n\n    moment.now = function () {\n        return customTime;\n    };\n\n    try {\n        assert.equal(moment().toISOString(), customTimeStr, 'moment() constructor should use the function defined by moment.now, but it did not');\n        assert.equal(moment.utc().toISOString(), customTimeStr, 'moment() constructor should use the function defined by moment.now, but it did not');\n    } finally {\n        moment.now = oldFn;\n    }\n});\n\ntest('empty object, empty array', function (assert) {\n    function assertIsNow(gen, msg) {\n        var before = +(new Date()),\n            mid = gen(),\n            after = +(new Date());\n        assert.ok(before <= +mid && +mid <= after, 'should be now : ' + msg);\n    }\n    assertIsNow(function () {\n        return moment();\n    }, 'moment()');\n    assertIsNow(function () {\n        return moment([]);\n    }, 'moment([])');\n    assertIsNow(function () {\n        return moment({});\n    }, 'moment({})');\n    assertIsNow(function () {\n        return moment.utc();\n    }, 'moment.utc()');\n    assertIsNow(function () {\n        return moment.utc([]);\n    }, 'moment.utc([])');\n    assertIsNow(function () {\n        return moment.utc({});\n    }, 'moment.utc({})');\n});\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/test/moment/parsing_flags.js",
    "content": "import { module, test } from '../qunit';\nimport moment from '../../moment';\n\nmodule('parsing flags');\n\nfunction flags () {\n    return moment.apply(null, arguments).parsingFlags();\n}\n\ntest('overflow with array', function (assert) {\n    //months\n    assert.equal(flags([2010, 0]).overflow, -1, 'month 0 valid');\n    assert.equal(flags([2010, 1]).overflow, -1, 'month 1 valid');\n    assert.equal(flags([2010, -1]).overflow, 1, 'month -1 invalid');\n    assert.equal(flags([2100, 12]).overflow, 1, 'month 12 invalid');\n\n    //days\n    assert.equal(flags([2010, 1, 16]).overflow, -1, 'date valid');\n    assert.equal(flags([2010, 1, -1]).overflow, 2, 'date -1 invalid');\n    assert.equal(flags([2010, 1, 0]).overflow, 2, 'date 0 invalid');\n    assert.equal(flags([2010, 1, 32]).overflow, 2, 'date 32 invalid');\n    assert.equal(flags([2012, 1, 29]).overflow, -1, 'date leap year valid');\n    assert.equal(flags([2010, 1, 29]).overflow, 2, 'date leap year invalid');\n\n    //hours\n    assert.equal(flags([2010, 1, 1, 8]).overflow, -1, 'hour valid');\n    assert.equal(flags([2010, 1, 1, 0]).overflow, -1, 'hour 0 valid');\n    assert.equal(flags([2010, 1, 1, -1]).overflow, 3, 'hour -1 invalid');\n    assert.equal(flags([2010, 1, 1, 25]).overflow, 3, 'hour 25 invalid');\n    assert.equal(flags([2010, 1, 1, 24, 1]).overflow, 3, 'hour 24:01 invalid');\n\n    //minutes\n    assert.equal(flags([2010, 1, 1, 8, 15]).overflow, -1, 'minute valid');\n    assert.equal(flags([2010, 1, 1, 8, 0]).overflow, -1, 'minute 0 valid');\n    assert.equal(flags([2010, 1, 1, 8, -1]).overflow, 4, 'minute -1 invalid');\n    assert.equal(flags([2010, 1, 1, 8, 60]).overflow, 4, 'minute 60 invalid');\n\n    //seconds\n    assert.equal(flags([2010, 1, 1, 8, 15, 12]).overflow, -1, 'second valid');\n    assert.equal(flags([2010, 1, 1, 8, 15, 0]).overflow, -1, 'second 0 valid');\n    assert.equal(flags([2010, 1, 1, 8, 15, -1]).overflow, 5, 'second -1 invalid');\n    assert.equal(flags([2010, 1, 1, 8, 15, 60]).overflow, 5, 'second 60 invalid');\n\n    //milliseconds\n    assert.equal(flags([2010, 1, 1, 8, 15, 12, 345]).overflow, -1, 'millisecond valid');\n    assert.equal(flags([2010, 1, 1, 8, 15, 12, 0]).overflow, -1, 'millisecond 0 valid');\n    assert.equal(flags([2010, 1, 1, 8, 15, 12, -1]).overflow, 6, 'millisecond -1 invalid');\n    assert.equal(flags([2010, 1, 1, 8, 15, 12, 1000]).overflow, 6, 'millisecond 1000 invalid');\n\n    // 24 hrs\n    assert.equal(flags([2010, 1, 1, 24, 0, 0, 0]).overflow, -1, '24:00:00.000 is fine');\n    assert.equal(flags([2010, 1, 1, 24, 1, 0, 0]).overflow, 3, '24:01:00.000 is wrong hour');\n    assert.equal(flags([2010, 1, 1, 24, 0, 1, 0]).overflow, 3, '24:00:01.000 is wrong hour');\n    assert.equal(flags([2010, 1, 1, 24, 0, 0, 1]).overflow, 3, '24:00:00.001 is wrong hour');\n});\n\ntest('overflow without format', function (assert) {\n    //months\n    assert.equal(flags('2001-01', 'YYYY-MM').overflow, -1, 'month 1 valid');\n    assert.equal(flags('2001-12', 'YYYY-MM').overflow, -1, 'month 12 valid');\n    assert.equal(flags('2001-13', 'YYYY-MM').overflow, 1, 'month 13 invalid');\n\n    //days\n    assert.equal(flags('2010-01-16', 'YYYY-MM-DD').overflow, -1, 'date 16 valid');\n    assert.equal(flags('2010-01-0',  'YYYY-MM-DD').overflow, 2, 'date 0 invalid');\n    assert.equal(flags('2010-01-32', 'YYYY-MM-DD').overflow, 2, 'date 32 invalid');\n    assert.equal(flags('2012-02-29', 'YYYY-MM-DD').overflow, -1, 'date leap year valid');\n    assert.equal(flags('2010-02-29', 'YYYY-MM-DD').overflow, 2, 'date leap year invalid');\n\n    //days of the year\n    assert.equal(flags('2010 300', 'YYYY DDDD').overflow, -1, 'day 300 of year valid');\n    assert.equal(flags('2010 365', 'YYYY DDDD').overflow, -1, 'day 365 of year valid');\n    assert.equal(flags('2010 366', 'YYYY DDDD').overflow, 2, 'day 366 of year invalid');\n    assert.equal(flags('2012 366', 'YYYY DDDD').overflow, -1, 'day 366 of leap year valid');\n    assert.equal(flags('2012 367', 'YYYY DDDD').overflow, 2, 'day 367 of leap year invalid');\n\n    //hours\n    assert.equal(flags('08', 'HH').overflow, -1, 'hour valid');\n    assert.equal(flags('00', 'HH').overflow, -1, 'hour 0 valid');\n    assert.equal(flags('25', 'HH').overflow, 3, 'hour 25 invalid');\n    assert.equal(flags('24:01', 'HH:mm').overflow, 3, 'hour 24:01 invalid');\n\n    //minutes\n    assert.equal(flags('08:15', 'HH:mm').overflow, -1, 'minute valid');\n    assert.equal(flags('08:00', 'HH:mm').overflow, -1, 'minute 0 valid');\n    assert.equal(flags('08:60', 'HH:mm').overflow, 4, 'minute 60 invalid');\n\n    //seconds\n    assert.equal(flags('08:15:12', 'HH:mm:ss').overflow, -1, 'second valid');\n    assert.equal(flags('08:15:00', 'HH:mm:ss').overflow, -1, 'second 0 valid');\n    assert.equal(flags('08:15:60', 'HH:mm:ss').overflow, 5, 'second 60 invalid');\n\n    //milliseconds\n    assert.equal(flags('08:15:12:345', 'HH:mm:ss:SSSS').overflow, -1, 'millisecond valid');\n    assert.equal(flags('08:15:12:000', 'HH:mm:ss:SSSS').overflow, -1, 'millisecond 0 valid');\n\n    //this is OK because we don't match the last digit, so it's 100 ms\n    assert.equal(flags('08:15:12:1000', 'HH:mm:ss:SSSS').overflow, -1, 'millisecond 1000 actually valid');\n});\n\ntest('extra tokens', function (assert) {\n    assert.deepEqual(flags('1982-05-25', 'YYYY-MM-DD').unusedTokens, [], 'nothing extra');\n    assert.deepEqual(flags('1982-05', 'YYYY-MM-DD').unusedTokens, ['DD'], 'extra formatting token');\n    assert.deepEqual(flags('1982', 'YYYY-MM-DD').unusedTokens, ['MM', 'DD'], 'multiple extra formatting tokens');\n    assert.deepEqual(flags('1982-05', 'YYYY-MM-').unusedTokens, [], 'extra non-formatting token');\n    assert.deepEqual(flags('1982-05-', 'YYYY-MM-DD').unusedTokens, ['DD'], 'non-extra non-formatting token');\n    assert.deepEqual(flags('1982 05 1982', 'YYYY-MM-DD').unusedTokens, [], 'different non-formatting token');\n});\n\ntest('extra tokens strict', function (assert) {\n    assert.deepEqual(flags('1982-05-25', 'YYYY-MM-DD', true).unusedTokens, [], 'nothing extra');\n    assert.deepEqual(flags('1982-05', 'YYYY-MM-DD', true).unusedTokens, ['-', 'DD'], 'extra formatting token');\n    assert.deepEqual(flags('1982', 'YYYY-MM-DD', true).unusedTokens, ['-', 'MM', '-', 'DD'], 'multiple extra formatting tokens');\n    assert.deepEqual(flags('1982-05', 'YYYY-MM-', true).unusedTokens, ['-'], 'extra non-formatting token');\n    assert.deepEqual(flags('1982-05-', 'YYYY-MM-DD', true).unusedTokens, ['DD'], 'non-extra non-formatting token');\n    assert.deepEqual(flags('1982 05 1982', 'YYYY-MM-DD', true).unusedTokens, ['-', '-'], 'different non-formatting token');\n});\n\ntest('unused input', function (assert) {\n    assert.deepEqual(flags('1982-05-25', 'YYYY-MM-DD').unusedInput, [], 'normal input');\n    assert.deepEqual(flags('1982-05-25 this is more stuff', 'YYYY-MM-DD').unusedInput, [' this is more stuff'], 'trailing nonsense');\n    assert.deepEqual(flags('1982-05-25 09:30', 'YYYY-MM-DD').unusedInput, [' 09:30'], ['trailing legit-looking input']);\n    assert.deepEqual(flags('1982-05-25 some junk', 'YYYY-MM-DD [some junk]').unusedInput, [], 'junk that actually gets matched');\n    assert.deepEqual(flags('stuff at beginning 1982-05-25', 'YYYY-MM-DD').unusedInput, ['stuff at beginning '], 'leading junk');\n    assert.deepEqual(flags('junk 1982 more junk 05 yet more junk25', 'YYYY-MM-DD').unusedInput, ['junk ', ' more junk ', ' yet more junk'], 'interstitial junk');\n});\n\ntest('unused input strict', function (assert) {\n    assert.deepEqual(flags('1982-05-25', 'YYYY-MM-DD', true).unusedInput, [], 'normal input');\n    assert.deepEqual(flags('1982-05-25 this is more stuff', 'YYYY-MM-DD', true).unusedInput, [' this is more stuff'], 'trailing nonsense');\n    assert.deepEqual(flags('1982-05-25 09:30', 'YYYY-MM-DD', true).unusedInput, [' 09:30'], ['trailing legit-looking input']);\n    assert.deepEqual(flags('1982-05-25 some junk', 'YYYY-MM-DD [some junk]', true).unusedInput, [], 'junk that actually gets matched');\n    assert.deepEqual(flags('stuff at beginning 1982-05-25', 'YYYY-MM-DD', true).unusedInput, ['stuff at beginning '], 'leading junk');\n    assert.deepEqual(flags('junk 1982 more junk 05 yet more junk25', 'YYYY-MM-DD', true).unusedInput, ['junk ', ' more junk ', ' yet more junk'], 'interstitial junk');\n});\n\ntest('chars left over', function (assert) {\n    assert.equal(flags('1982-05-25', 'YYYY-MM-DD').charsLeftOver, 0, 'normal input');\n    assert.equal(flags('1982-05-25 this is more stuff', 'YYYY-MM-DD').charsLeftOver, ' this is more stuff'.length, 'trailing nonsense');\n    assert.equal(flags('1982-05-25 09:30', 'YYYY-MM-DD').charsLeftOver, ' 09:30'.length, 'trailing legit-looking input');\n    assert.equal(flags('stuff at beginning 1982-05-25', 'YYYY-MM-DD').charsLeftOver, 'stuff at beginning '.length, 'leading junk');\n    assert.equal(flags('1982 junk 05 more junk25', 'YYYY-MM-DD').charsLeftOver, [' junk ', ' more junk'].join('').length, 'interstitial junk');\n    assert.equal(flags('stuff at beginning 1982 junk 05 more junk25', 'YYYY-MM-DD').charsLeftOver, ['stuff at beginning ', ' junk ', ' more junk'].join('').length, 'leading and interstitial junk');\n});\n\ntest('empty', function (assert) {\n    assert.equal(flags('1982-05-25', 'YYYY-MM-DD').empty, false, 'normal input');\n    assert.equal(flags('nothing here', 'YYYY-MM-DD').empty, true, 'pure garbage');\n    assert.equal(flags('junk but has the number 2000 in it', 'YYYY-MM-DD').empty, false, 'only mostly garbage');\n    assert.equal(flags('', 'YYYY-MM-DD').empty, true, 'empty string');\n    assert.equal(flags('', 'YYYY-MM-DD').empty, true, 'blank string');\n});\n\ntest('null', function (assert) {\n    assert.equal(flags('1982-05-25', 'YYYY-MM-DD').nullInput, false, 'normal input');\n    assert.equal(flags(null).nullInput, true, 'just null');\n    assert.equal(flags(null, 'YYYY-MM-DD').nullInput, true, 'null with format');\n});\n\ntest('invalid month', function (assert) {\n    assert.equal(flags('1982 May', 'YYYY MMMM').invalidMonth, null, 'normal input');\n    assert.equal(flags('1982 Laser', 'YYYY MMMM').invalidMonth, 'Laser', 'bad month name');\n});\n\ntest('empty format array', function (assert) {\n    assert.equal(flags('1982 May', ['YYYY MMM']).invalidFormat, false, 'empty format array');\n    assert.equal(flags('1982 May', []).invalidFormat, true, 'empty format array');\n});\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/test/moment/preparse_postformat.js",
    "content": "import { module, test } from '../qunit';\nimport moment from '../../moment';\n\nvar symbolMap = {\n        '1': '!',\n        '2': '@',\n        '3': '#',\n        '4': '$',\n        '5': '%',\n        '6': '^',\n        '7': '&',\n        '8': '*',\n        '9': '(',\n        '0': ')'\n    },\n    numberMap = {\n        '!': '1',\n        '@': '2',\n        '#': '3',\n        '$': '4',\n        '%': '5',\n        '^': '6',\n        '&': '7',\n        '*': '8',\n        '(': '9',\n        ')': '0'\n    };\n\nmodule('preparse and postformat', {\n    setup: function () {\n        moment.locale('symbol', {\n            preparse: function (string) {\n                return string.replace(/[!@#$%\\^&*()]/g, function (match) {\n                    return numberMap[match];\n                });\n            },\n\n            postformat: function (string) {\n                return string.replace(/\\d/g, function (match) {\n                    return symbolMap[match];\n                });\n            }\n        });\n    },\n    teardown: function () {\n        moment.defineLocale('symbol', null);\n    }\n});\n\ntest('transform', function (assert) {\n    assert.equal(moment.utc('@)!@-)*-@&', 'YYYY-MM-DD').unix(), 1346025600, 'preparse string + format');\n    assert.equal(moment.utc('@)!@-)*-@&').unix(), 1346025600, 'preparse ISO8601 string');\n    assert.equal(moment.unix(1346025600).utc().format('YYYY-MM-DD'), '@)!@-)*-@&', 'postformat');\n});\n\ntest('transform from', function (assert) {\n    var start = moment([2007, 1, 28]);\n\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true), '@ minutes', 'postformat should work on moment.fn.from');\n    assert.equal(moment().add(6, 'd').fromNow(true), '^ days', 'postformat should work on moment.fn.fromNow');\n    assert.equal(moment.duration(10, 'h').humanize(), '!) hours', 'postformat should work on moment.duration.fn.humanize');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'Today at !@:)) PM',     'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'Today at !@:@% PM',     'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'Today at !:)) PM',      'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'Tomorrow at !@:)) PM',  'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'Today at !!:)) AM',     'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'Yesterday at !@:)) PM', 'yesterday at the same time');\n});\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/test/moment/quarter.js",
    "content": "import { module, test } from '../qunit';\nimport moment from '../../moment';\n\nmodule('quarter');\n\ntest('library quarter getter', function (assert) {\n    assert.equal(moment([1985,  1,  4]).quarter(), 1, 'Feb  4 1985 is Q1');\n    assert.equal(moment([2029,  8, 18]).quarter(), 3, 'Sep 18 2029 is Q3');\n    assert.equal(moment([2013,  3, 24]).quarter(), 2, 'Apr 24 2013 is Q2');\n    assert.equal(moment([2015,  2,  5]).quarter(), 1, 'Mar  5 2015 is Q1');\n    assert.equal(moment([1970,  0,  2]).quarter(), 1, 'Jan  2 1970 is Q1');\n    assert.equal(moment([2001, 11, 12]).quarter(), 4, 'Dec 12 2001 is Q4');\n    assert.equal(moment([2000,  0,  2]).quarter(), 1, 'Jan  2 2000 is Q1');\n});\n\ntest('quarter setter singular', function (assert) {\n    var m = moment([2014, 4, 11]);\n    assert.equal(m.quarter(2).month(), 4, 'set same quarter');\n    assert.equal(m.quarter(3).month(), 7, 'set 3rd quarter');\n    assert.equal(m.quarter(1).month(), 1, 'set 1st quarter');\n    assert.equal(m.quarter(4).month(), 10, 'set 4th quarter');\n});\n\ntest('quarter setter plural', function (assert) {\n    var m = moment([2014, 4, 11]);\n    assert.equal(m.quarters(2).month(), 4, 'set same quarter');\n    assert.equal(m.quarters(3).month(), 7, 'set 3rd quarter');\n    assert.equal(m.quarters(1).month(), 1, 'set 1st quarter');\n    assert.equal(m.quarters(4).month(), 10, 'set 4th quarter');\n});\n\ntest('quarter setter programmatic', function (assert) {\n    var m = moment([2014, 4, 11]);\n    assert.equal(m.set('quarter', 2).month(), 4, 'set same quarter');\n    assert.equal(m.set('quarter', 3).month(), 7, 'set 3rd quarter');\n    assert.equal(m.set('quarter', 1).month(), 1, 'set 1st quarter');\n    assert.equal(m.set('quarter', 4).month(), 10, 'set 4th quarter');\n});\n\ntest('quarter setter programmatic plural', function (assert) {\n    var m = moment([2014, 4, 11]);\n    assert.equal(m.set('quarters', 2).month(), 4, 'set same quarter');\n    assert.equal(m.set('quarters', 3).month(), 7, 'set 3rd quarter');\n    assert.equal(m.set('quarters', 1).month(), 1, 'set 1st quarter');\n    assert.equal(m.set('quarters', 4).month(), 10, 'set 4th quarter');\n});\n\ntest('quarter setter programmatic abbr', function (assert) {\n    var m = moment([2014, 4, 11]);\n    assert.equal(m.set('Q', 2).month(), 4, 'set same quarter');\n    assert.equal(m.set('Q', 3).month(), 7, 'set 3rd quarter');\n    assert.equal(m.set('Q', 1).month(), 1, 'set 1st quarter');\n    assert.equal(m.set('Q', 4).month(), 10, 'set 4th quarter');\n});\n\ntest('quarter setter only month changes', function (assert) {\n    var m = moment([2014, 4, 11, 1, 2, 3, 4]).quarter(4);\n    assert.equal(m.year(), 2014, 'keep year');\n    assert.equal(m.month(), 10, 'set month');\n    assert.equal(m.date(), 11, 'keep date');\n    assert.equal(m.hour(), 1, 'keep hour');\n    assert.equal(m.minute(), 2, 'keep minutes');\n    assert.equal(m.second(), 3, 'keep seconds');\n    assert.equal(m.millisecond(), 4, 'keep milliseconds');\n});\n\ntest('quarter setter bubble to next year', function (assert) {\n    var m = moment([2014, 4, 11, 1, 2, 3, 4]).quarter(7);\n    assert.equal(m.year(), 2015, 'year bubbled');\n    assert.equal(m.month(), 7, 'set month');\n    assert.equal(m.date(), 11, 'keep date');\n    assert.equal(m.hour(), 1, 'keep hour');\n    assert.equal(m.minute(), 2, 'keep minutes');\n    assert.equal(m.second(), 3, 'keep seconds');\n    assert.equal(m.millisecond(), 4, 'keep milliseconds');\n});\n\ntest('quarter diff', function (assert) {\n    assert.equal(moment('2014-01-01').diff(moment('2014-04-01'), 'quarter'),\n            -1, 'diff -1 quarter');\n    assert.equal(moment('2014-04-01').diff(moment('2014-01-01'), 'quarter'),\n            1, 'diff 1 quarter');\n    assert.equal(moment('2014-05-01').diff(moment('2014-01-01'), 'quarter'),\n            1, 'diff 1 quarter');\n    assert.ok(Math.abs((4 / 3) - moment('2014-05-01').diff(\n                    moment('2014-01-01'), 'quarter', true)) < 0.00001,\n            'diff 1 1/3 quarter');\n    assert.equal(moment('2015-01-01').diff(moment('2014-01-01'), 'quarter'),\n            4, 'diff 4 quarters');\n});\n\ntest('quarter setter bubble to previous year', function (assert) {\n    var m = moment([2014, 4, 11, 1, 2, 3, 4]).quarter(-3);\n    assert.equal(m.year(), 2013, 'year bubbled');\n    assert.equal(m.month(), 1, 'set month');\n    assert.equal(m.date(), 11, 'keep date');\n    assert.equal(m.hour(), 1, 'keep hour');\n    assert.equal(m.minute(), 2, 'keep minutes');\n    assert.equal(m.second(), 3, 'keep seconds');\n    assert.equal(m.millisecond(), 4, 'keep milliseconds');\n});\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/test/moment/relative_time.js",
    "content": "import { module, test } from '../qunit';\nimport moment from '../../moment';\n\nmodule('relative time');\n\ntest('default thresholds fromNow', function (assert) {\n    var a = moment();\n\n    // Seconds to minutes threshold\n    a.subtract(44, 'seconds');\n    assert.equal(a.fromNow(), 'a few seconds ago', 'Below default seconds to minutes threshold');\n    a.subtract(1, 'seconds');\n    assert.equal(a.fromNow(), 'a minute ago', 'Above default seconds to minutes threshold');\n\n    // Minutes to hours threshold\n    a = moment();\n    a.subtract(44, 'minutes');\n    assert.equal(a.fromNow(), '44 minutes ago', 'Below default minute to hour threshold');\n    a.subtract(1, 'minutes');\n    assert.equal(a.fromNow(), 'an hour ago', 'Above default minute to hour threshold');\n\n    // Hours to days threshold\n    a = moment();\n    a.subtract(21, 'hours');\n    assert.equal(a.fromNow(), '21 hours ago', 'Below default hours to day threshold');\n    a.subtract(1, 'hours');\n    assert.equal(a.fromNow(), 'a day ago', 'Above default hours to day threshold');\n\n    // Days to month threshold\n    a = moment();\n    a.subtract(25, 'days');\n    assert.equal(a.fromNow(), '25 days ago', 'Below default days to month (singular) threshold');\n    a.subtract(1, 'days');\n    assert.equal(a.fromNow(), 'a month ago', 'Above default days to month (singular) threshold');\n\n    // months to year threshold\n    a = moment();\n    a.subtract(10, 'months');\n    assert.equal(a.fromNow(), '10 months ago', 'Below default days to years threshold');\n    a.subtract(1, 'month');\n    assert.equal(a.fromNow(), 'a year ago', 'Above default days to years threshold');\n});\n\ntest('default thresholds toNow', function (assert) {\n    var a = moment();\n\n    // Seconds to minutes threshold\n    a.subtract(44, 'seconds');\n    assert.equal(a.toNow(), 'in a few seconds', 'Below default seconds to minutes threshold');\n    a.subtract(1, 'seconds');\n    assert.equal(a.toNow(), 'in a minute', 'Above default seconds to minutes threshold');\n\n    // Minutes to hours threshold\n    a = moment();\n    a.subtract(44, 'minutes');\n    assert.equal(a.toNow(), 'in 44 minutes', 'Below default minute to hour threshold');\n    a.subtract(1, 'minutes');\n    assert.equal(a.toNow(), 'in an hour', 'Above default minute to hour threshold');\n\n    // Hours to days threshold\n    a = moment();\n    a.subtract(21, 'hours');\n    assert.equal(a.toNow(), 'in 21 hours', 'Below default hours to day threshold');\n    a.subtract(1, 'hours');\n    assert.equal(a.toNow(), 'in a day', 'Above default hours to day threshold');\n\n    // Days to month threshold\n    a = moment();\n    a.subtract(25, 'days');\n    assert.equal(a.toNow(), 'in 25 days', 'Below default days to month (singular) threshold');\n    a.subtract(1, 'days');\n    assert.equal(a.toNow(), 'in a month', 'Above default days to month (singular) threshold');\n\n    // months to year threshold\n    a = moment();\n    a.subtract(10, 'months');\n    assert.equal(a.toNow(), 'in 10 months', 'Below default days to years threshold');\n    a.subtract(1, 'month');\n    assert.equal(a.toNow(), 'in a year', 'Above default days to years threshold');\n});\n\ntest('custom thresholds', function (assert) {\n    var a;\n\n    // Seconds to minute threshold, under 30\n    moment.relativeTimeThreshold('s', 25);\n\n    a = moment();\n    a.subtract(24, 'seconds');\n    assert.equal(a.fromNow(), 'a few seconds ago', 'Below custom seconds to minute threshold, s < 30');\n    a.subtract(1, 'seconds');\n    assert.equal(a.fromNow(), 'a minute ago', 'Above custom seconds to minute threshold, s < 30');\n\n    // Seconds to minutes threshold\n    moment.relativeTimeThreshold('s', 55);\n\n    a = moment();\n    a.subtract(54, 'seconds');\n    assert.equal(a.fromNow(), 'a few seconds ago', 'Below custom seconds to minutes threshold');\n    a.subtract(1, 'seconds');\n    assert.equal(a.fromNow(), 'a minute ago', 'Above custom seconds to minutes threshold');\n\n    moment.relativeTimeThreshold('s', 45);\n\n    // A few seconds to seconds threshold\n    moment.relativeTimeThreshold('ss', 3);\n\n    a = moment();\n    a.subtract(3, 'seconds');\n    assert.equal(a.fromNow(), 'a few seconds ago', 'Below custom a few seconds to seconds threshold');\n    a.subtract(1, 'seconds');\n    assert.equal(a.fromNow(), '4 seconds ago', 'Above custom a few seconds to seconds threshold');\n\n    moment.relativeTimeThreshold('ss', 44);\n\n    // Minutes to hours threshold\n    moment.relativeTimeThreshold('m', 55);\n    a = moment();\n    a.subtract(54, 'minutes');\n    assert.equal(a.fromNow(), '54 minutes ago', 'Below custom minutes to hours threshold');\n    a.subtract(1, 'minutes');\n    assert.equal(a.fromNow(), 'an hour ago', 'Above custom minutes to hours threshold');\n    moment.relativeTimeThreshold('m', 45);\n\n    // Hours to days threshold\n    moment.relativeTimeThreshold('h', 24);\n    a = moment();\n    a.subtract(23, 'hours');\n    assert.equal(a.fromNow(), '23 hours ago', 'Below custom hours to days threshold');\n    a.subtract(1, 'hours');\n    assert.equal(a.fromNow(), 'a day ago', 'Above custom hours to days threshold');\n    moment.relativeTimeThreshold('h', 22);\n\n    // Days to month threshold\n    moment.relativeTimeThreshold('d', 28);\n    a = moment();\n    a.subtract(27, 'days');\n    assert.equal(a.fromNow(), '27 days ago', 'Below custom days to month (singular) threshold');\n    a.subtract(1, 'days');\n    assert.equal(a.fromNow(), 'a month ago', 'Above custom days to month (singular) threshold');\n    moment.relativeTimeThreshold('d', 26);\n\n    // months to years threshold\n    moment.relativeTimeThreshold('M', 9);\n    a = moment();\n    a.subtract(8, 'months');\n    assert.equal(a.fromNow(), '8 months ago', 'Below custom days to years threshold');\n    a.subtract(1, 'months');\n    assert.equal(a.fromNow(), 'a year ago', 'Above custom days to years threshold');\n    moment.relativeTimeThreshold('M', 11);\n});\n\ntest('custom rounding', function (assert) {\n    var roundingDefault = moment.relativeTimeRounding();\n\n    // Round relative time evaluation down\n    moment.relativeTimeRounding(Math.floor);\n\n    moment.relativeTimeThreshold('s', 60);\n    moment.relativeTimeThreshold('m', 60);\n    moment.relativeTimeThreshold('h', 24);\n    moment.relativeTimeThreshold('d', 27);\n    moment.relativeTimeThreshold('M', 12);\n\n    var a = moment.utc();\n    a.subtract({minutes: 59, seconds: 59});\n    assert.equal(a.toNow(), 'in 59 minutes', 'Round down towards the nearest minute');\n\n    a = moment.utc();\n    a.subtract({hours: 23, minutes: 59, seconds: 59});\n    assert.equal(a.toNow(), 'in 23 hours', 'Round down towards the nearest hour');\n\n    a = moment.utc();\n    a.subtract({days: 26, hours: 23, minutes: 59});\n    assert.equal(a.toNow(), 'in 26 days', 'Round down towards the nearest day (just under)');\n\n    a = moment.utc();\n    a.subtract({days: 27});\n    assert.equal(a.toNow(), 'in a month', 'Round down towards the nearest day (just over)');\n\n    a = moment.utc();\n    a.subtract({days: 364});\n    assert.equal(a.toNow(), 'in 11 months', 'Round down towards the nearest month');\n\n    a = moment.utc();\n    a.subtract({years: 1, days: 364});\n    assert.equal(a.toNow(), 'in a year', 'Round down towards the nearest year');\n\n    // Do not round relative time evaluation\n    var retainValue = function (value) {\n        return value.toFixed(3);\n    };\n    moment.relativeTimeRounding(retainValue);\n\n    a = moment.utc();\n    a.subtract({hours: 39});\n    assert.equal(a.toNow(), 'in 1.625 days', 'Round down towards the nearest year');\n\n    // Restore defaults\n    moment.relativeTimeThreshold('s', 45);\n    moment.relativeTimeThreshold('m', 45);\n    moment.relativeTimeThreshold('h', 22);\n    moment.relativeTimeThreshold('d', 26);\n    moment.relativeTimeThreshold('M', 11);\n    moment.relativeTimeRounding(roundingDefault);\n});\n\ntest('retrieve rounding settings', function (assert) {\n    moment.relativeTimeRounding(Math.round);\n    var roundingFunction = moment.relativeTimeRounding();\n\n    assert.equal(roundingFunction, Math.round, 'Can retrieve rounding setting');\n});\n\ntest('retrieve threshold settings', function (assert) {\n    moment.relativeTimeThreshold('m', 45);\n    var minuteThreshold = moment.relativeTimeThreshold('m');\n\n    assert.equal(minuteThreshold, 45, 'Can retrieve minute setting');\n});\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/test/moment/start_end_of.js",
    "content": "import { module, test } from '../qunit';\nimport moment from '../../moment';\n\nmodule('start and end of units');\n\ntest('start of year', function (assert) {\n    var m = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).startOf('year'),\n        ms = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).startOf('years'),\n        ma = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).startOf('y');\n    assert.equal(+m, +ms, 'Plural or singular should work');\n    assert.equal(+m, +ma, 'Full or abbreviated should work');\n    assert.equal(m.year(), 2011, 'keep the year');\n    assert.equal(m.month(), 0, 'strip out the month');\n    assert.equal(m.date(), 1, 'strip out the day');\n    assert.equal(m.hours(), 0, 'strip out the hours');\n    assert.equal(m.minutes(), 0, 'strip out the minutes');\n    assert.equal(m.seconds(), 0, 'strip out the seconds');\n    assert.equal(m.milliseconds(), 0, 'strip out the milliseconds');\n});\n\ntest('end of year', function (assert) {\n    var m = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).endOf('year'),\n        ms = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).endOf('years'),\n        ma = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).endOf('y');\n    assert.equal(+m, +ms, 'Plural or singular should work');\n    assert.equal(+m, +ma, 'Full or abbreviated should work');\n    assert.equal(m.year(), 2011, 'keep the year');\n    assert.equal(m.month(), 11, 'set the month');\n    assert.equal(m.date(), 31, 'set the day');\n    assert.equal(m.hours(), 23, 'set the hours');\n    assert.equal(m.minutes(), 59, 'set the minutes');\n    assert.equal(m.seconds(), 59, 'set the seconds');\n    assert.equal(m.milliseconds(), 999, 'set the seconds');\n});\n\ntest('start of quarter', function (assert) {\n    var m = moment(new Date(2011, 4, 2, 3, 4, 5, 6)).startOf('quarter'),\n        ms = moment(new Date(2011, 4, 2, 3, 4, 5, 6)).startOf('quarters'),\n        ma = moment(new Date(2011, 4, 2, 3, 4, 5, 6)).startOf('Q');\n    assert.equal(+m, +ms, 'Plural or singular should work');\n    assert.equal(+m, +ma, 'Full or abbreviated should work');\n    assert.equal(m.year(), 2011, 'keep the year');\n    assert.equal(m.quarter(), 2, 'keep the quarter');\n    assert.equal(m.month(), 3, 'strip out the month');\n    assert.equal(m.date(), 1, 'strip out the day');\n    assert.equal(m.hours(), 0, 'strip out the hours');\n    assert.equal(m.minutes(), 0, 'strip out the minutes');\n    assert.equal(m.seconds(), 0, 'strip out the seconds');\n    assert.equal(m.milliseconds(), 0, 'strip out the milliseconds');\n});\n\ntest('end of quarter', function (assert) {\n    var m = moment(new Date(2011, 4, 2, 3, 4, 5, 6)).endOf('quarter'),\n        ms = moment(new Date(2011, 4, 2, 3, 4, 5, 6)).endOf('quarters'),\n        ma = moment(new Date(2011, 4, 2, 3, 4, 5, 6)).endOf('Q');\n    assert.equal(+m, +ms, 'Plural or singular should work');\n    assert.equal(+m, +ma, 'Full or abbreviated should work');\n    assert.equal(m.year(), 2011, 'keep the year');\n    assert.equal(m.quarter(), 2, 'keep the quarter');\n    assert.equal(m.month(), 5, 'set the month');\n    assert.equal(m.date(), 30, 'set the day');\n    assert.equal(m.hours(), 23, 'set the hours');\n    assert.equal(m.minutes(), 59, 'set the minutes');\n    assert.equal(m.seconds(), 59, 'set the seconds');\n    assert.equal(m.milliseconds(), 999, 'set the seconds');\n});\n\ntest('start of month', function (assert) {\n    var m = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).startOf('month'),\n        ms = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).startOf('months'),\n        ma = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).startOf('M');\n    assert.equal(+m, +ms, 'Plural or singular should work');\n    assert.equal(+m, +ma, 'Full or abbreviated should work');\n    assert.equal(m.year(), 2011, 'keep the year');\n    assert.equal(m.month(), 1, 'keep the month');\n    assert.equal(m.date(), 1, 'strip out the day');\n    assert.equal(m.hours(), 0, 'strip out the hours');\n    assert.equal(m.minutes(), 0, 'strip out the minutes');\n    assert.equal(m.seconds(), 0, 'strip out the seconds');\n    assert.equal(m.milliseconds(), 0, 'strip out the milliseconds');\n});\n\ntest('end of month', function (assert) {\n    var m = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).endOf('month'),\n        ms = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).endOf('months'),\n        ma = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).endOf('M');\n    assert.equal(+m, +ms, 'Plural or singular should work');\n    assert.equal(+m, +ma, 'Full or abbreviated should work');\n    assert.equal(m.year(), 2011, 'keep the year');\n    assert.equal(m.month(), 1, 'keep the month');\n    assert.equal(m.date(), 28, 'set the day');\n    assert.equal(m.hours(), 23, 'set the hours');\n    assert.equal(m.minutes(), 59, 'set the minutes');\n    assert.equal(m.seconds(), 59, 'set the seconds');\n    assert.equal(m.milliseconds(), 999, 'set the seconds');\n});\n\ntest('start of week', function (assert) {\n    var m = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).startOf('week'),\n        ms = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).startOf('weeks'),\n        ma = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).startOf('w');\n    assert.equal(+m, +ms, 'Plural or singular should work');\n    assert.equal(+m, +ma, 'Full or abbreviated should work');\n    assert.equal(m.year(), 2011, 'keep the year');\n    assert.equal(m.month(), 0, 'rolls back to January');\n    assert.equal(m.day(), 0, 'set day of week');\n    assert.equal(m.date(), 30, 'set correct date');\n    assert.equal(m.hours(), 0, 'strip out the hours');\n    assert.equal(m.minutes(), 0, 'strip out the minutes');\n    assert.equal(m.seconds(), 0, 'strip out the seconds');\n    assert.equal(m.milliseconds(), 0, 'strip out the milliseconds');\n});\n\ntest('end of week', function (assert) {\n    var m = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).endOf('week'),\n        ms = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).endOf('weeks'),\n        ma = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).endOf('weeks');\n    assert.equal(+m, +ms, 'Plural or singular should work');\n    assert.equal(+m, +ma, 'Full or abbreviated should work');\n    assert.equal(m.year(), 2011, 'keep the year');\n    assert.equal(m.month(), 1, 'keep the month');\n    assert.equal(m.day(), 6, 'set the day of the week');\n    assert.equal(m.date(), 5, 'set the day');\n    assert.equal(m.hours(), 23, 'set the hours');\n    assert.equal(m.minutes(), 59, 'set the minutes');\n    assert.equal(m.seconds(), 59, 'set the seconds');\n    assert.equal(m.milliseconds(), 999, 'set the seconds');\n});\n\ntest('start of iso-week', function (assert) {\n    var m = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).startOf('isoWeek'),\n        ms = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).startOf('isoWeeks'),\n        ma = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).startOf('W');\n    assert.equal(+m, +ms, 'Plural or singular should work');\n    assert.equal(+m, +ma, 'Full or abbreviated should work');\n    assert.equal(m.year(), 2011, 'keep the year');\n    assert.equal(m.month(), 0, 'rollback to January');\n    assert.equal(m.isoWeekday(), 1, 'set day of iso-week');\n    assert.equal(m.date(), 31, 'set correct date');\n    assert.equal(m.hours(), 0, 'strip out the hours');\n    assert.equal(m.minutes(), 0, 'strip out the minutes');\n    assert.equal(m.seconds(), 0, 'strip out the seconds');\n    assert.equal(m.milliseconds(), 0, 'strip out the milliseconds');\n});\n\ntest('end of iso-week', function (assert) {\n    var m = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).endOf('isoWeek'),\n        ms = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).endOf('isoWeeks'),\n        ma = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).endOf('W');\n    assert.equal(+m, +ms, 'Plural or singular should work');\n    assert.equal(+m, +ma, 'Full or abbreviated should work');\n    assert.equal(m.year(), 2011, 'keep the year');\n    assert.equal(m.month(), 1, 'keep the month');\n    assert.equal(m.isoWeekday(), 7, 'set the day of the week');\n    assert.equal(m.date(), 6, 'set the day');\n    assert.equal(m.hours(), 23, 'set the hours');\n    assert.equal(m.minutes(), 59, 'set the minutes');\n    assert.equal(m.seconds(), 59, 'set the seconds');\n    assert.equal(m.milliseconds(), 999, 'set the seconds');\n});\n\ntest('start of day', function (assert) {\n    var m = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).startOf('day'),\n        ms = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).startOf('days'),\n        ma = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).startOf('d');\n    assert.equal(+m, +ms, 'Plural or singular should work');\n    assert.equal(+m, +ma, 'Full or abbreviated should work');\n    assert.equal(m.year(), 2011, 'keep the year');\n    assert.equal(m.month(), 1, 'keep the month');\n    assert.equal(m.date(), 2, 'keep the day');\n    assert.equal(m.hours(), 0, 'strip out the hours');\n    assert.equal(m.minutes(), 0, 'strip out the minutes');\n    assert.equal(m.seconds(), 0, 'strip out the seconds');\n    assert.equal(m.milliseconds(), 0, 'strip out the milliseconds');\n});\n\ntest('end of day', function (assert) {\n    var m = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).endOf('day'),\n        ms = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).endOf('days'),\n        ma = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).endOf('d');\n    assert.equal(+m, +ms, 'Plural or singular should work');\n    assert.equal(+m, +ma, 'Full or abbreviated should work');\n    assert.equal(m.year(), 2011, 'keep the year');\n    assert.equal(m.month(), 1, 'keep the month');\n    assert.equal(m.date(), 2, 'keep the day');\n    assert.equal(m.hours(), 23, 'set the hours');\n    assert.equal(m.minutes(), 59, 'set the minutes');\n    assert.equal(m.seconds(), 59, 'set the seconds');\n    assert.equal(m.milliseconds(), 999, 'set the seconds');\n});\n\ntest('start of date', function (assert) {\n    var m = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).startOf('date'),\n        ms = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).startOf('dates');\n\n    assert.equal(+m, +ms, 'Plural or singular should work');\n    assert.equal(m.year(), 2011, 'keep the year');\n    assert.equal(m.month(), 1, 'keep the month');\n    assert.equal(m.date(), 2, 'keep the day');\n    assert.equal(m.hours(), 0, 'strip out the hours');\n    assert.equal(m.minutes(), 0, 'strip out the minutes');\n    assert.equal(m.seconds(), 0, 'strip out the seconds');\n    assert.equal(m.milliseconds(), 0, 'strip out the milliseconds');\n});\n\ntest('end of date', function (assert) {\n    var m = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).endOf('date'),\n        ms = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).endOf('dates');\n\n    assert.equal(+m, +ms, 'Plural or singular should work');\n    assert.equal(m.year(), 2011, 'keep the year');\n    assert.equal(m.month(), 1, 'keep the month');\n    assert.equal(m.date(), 2, 'keep the day');\n    assert.equal(m.hours(), 23, 'set the hours');\n    assert.equal(m.minutes(), 59, 'set the minutes');\n    assert.equal(m.seconds(), 59, 'set the seconds');\n    assert.equal(m.milliseconds(), 999, 'set the seconds');\n});\n\n\ntest('start of hour', function (assert) {\n    var m = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).startOf('hour'),\n        ms = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).startOf('hours'),\n        ma = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).startOf('h');\n    assert.equal(+m, +ms, 'Plural or singular should work');\n    assert.equal(+m, +ma, 'Full or abbreviated should work');\n    assert.equal(m.year(), 2011, 'keep the year');\n    assert.equal(m.month(), 1, 'keep the month');\n    assert.equal(m.date(), 2, 'keep the day');\n    assert.equal(m.hours(), 3, 'keep the hours');\n    assert.equal(m.minutes(), 0, 'strip out the minutes');\n    assert.equal(m.seconds(), 0, 'strip out the seconds');\n    assert.equal(m.milliseconds(), 0, 'strip out the milliseconds');\n});\n\ntest('end of hour', function (assert) {\n    var m = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).endOf('hour'),\n        ms = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).endOf('hours'),\n        ma = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).endOf('h');\n    assert.equal(+m, +ms, 'Plural or singular should work');\n    assert.equal(+m, +ma, 'Full or abbreviated should work');\n    assert.equal(m.year(), 2011, 'keep the year');\n    assert.equal(m.month(), 1, 'keep the month');\n    assert.equal(m.date(), 2, 'keep the day');\n    assert.equal(m.hours(), 3, 'keep the hours');\n    assert.equal(m.minutes(), 59, 'set the minutes');\n    assert.equal(m.seconds(), 59, 'set the seconds');\n    assert.equal(m.milliseconds(), 999, 'set the seconds');\n});\n\ntest('start of minute', function (assert) {\n    var m = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).startOf('minute'),\n        ms = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).startOf('minutes'),\n        ma = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).startOf('m');\n    assert.equal(+m, +ms, 'Plural or singular should work');\n    assert.equal(+m, +ma, 'Full or abbreviated should work');\n    assert.equal(m.year(), 2011, 'keep the year');\n    assert.equal(m.month(), 1, 'keep the month');\n    assert.equal(m.date(), 2, 'keep the day');\n    assert.equal(m.hours(), 3, 'keep the hours');\n    assert.equal(m.minutes(), 4, 'keep the minutes');\n    assert.equal(m.seconds(), 0, 'strip out the seconds');\n    assert.equal(m.milliseconds(), 0, 'strip out the milliseconds');\n});\n\ntest('end of minute', function (assert) {\n    var m = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).endOf('minute'),\n        ms = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).endOf('minutes'),\n        ma = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).endOf('m');\n    assert.equal(+m, +ms, 'Plural or singular should work');\n    assert.equal(+m, +ma, 'Full or abbreviated should work');\n    assert.equal(m.year(), 2011, 'keep the year');\n    assert.equal(m.month(), 1, 'keep the month');\n    assert.equal(m.date(), 2, 'keep the day');\n    assert.equal(m.hours(), 3, 'keep the hours');\n    assert.equal(m.minutes(), 4, 'keep the minutes');\n    assert.equal(m.seconds(), 59, 'set the seconds');\n    assert.equal(m.milliseconds(), 999, 'set the seconds');\n});\n\ntest('start of second', function (assert) {\n    var m = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).startOf('second'),\n        ms = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).startOf('seconds'),\n        ma = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).startOf('s');\n    assert.equal(+m, +ms, 'Plural or singular should work');\n    assert.equal(+m, +ma, 'Full or abbreviated should work');\n    assert.equal(m.year(), 2011, 'keep the year');\n    assert.equal(m.month(), 1, 'keep the month');\n    assert.equal(m.date(), 2, 'keep the day');\n    assert.equal(m.hours(), 3, 'keep the hours');\n    assert.equal(m.minutes(), 4, 'keep the minutes');\n    assert.equal(m.seconds(), 5, 'keep the the seconds');\n    assert.equal(m.milliseconds(), 0, 'strip out the milliseconds');\n});\n\ntest('end of second', function (assert) {\n    var m = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).endOf('second'),\n        ms = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).endOf('seconds'),\n        ma = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).endOf('s');\n    assert.equal(+m, +ms, 'Plural or singular should work');\n    assert.equal(+m, +ma, 'Full or abbreviated should work');\n    assert.equal(m.year(), 2011, 'keep the year');\n    assert.equal(m.month(), 1, 'keep the month');\n    assert.equal(m.date(), 2, 'keep the day');\n    assert.equal(m.hours(), 3, 'keep the hours');\n    assert.equal(m.minutes(), 4, 'keep the minutes');\n    assert.equal(m.seconds(), 5, 'keep the seconds');\n    assert.equal(m.milliseconds(), 999, 'set the seconds');\n});\n\ntest('startOf across DST +1', function (assert) {\n    var oldUpdateOffset = moment.updateOffset,\n        // Based on a real story somewhere in America/Los_Angeles\n        dstAt = moment('2014-03-09T02:00:00-08:00').parseZone(),\n        m;\n\n    moment.updateOffset = function (mom, keepTime) {\n        if (mom.isBefore(dstAt)) {\n            mom.utcOffset(-8, keepTime);\n        } else {\n            mom.utcOffset(-7, keepTime);\n        }\n    };\n\n    m = moment('2014-03-15T00:00:00-07:00').parseZone();\n    m.startOf('y');\n    assert.equal(m.format(), '2014-01-01T00:00:00-08:00', 'startOf(\\'year\\') across +1');\n\n    m = moment('2014-03-15T00:00:00-07:00').parseZone();\n    m.startOf('M');\n    assert.equal(m.format(), '2014-03-01T00:00:00-08:00', 'startOf(\\'month\\') across +1');\n\n    m = moment('2014-03-09T09:00:00-07:00').parseZone();\n    m.startOf('d');\n    assert.equal(m.format(), '2014-03-09T00:00:00-08:00', 'startOf(\\'day\\') across +1');\n\n    m = moment('2014-03-09T03:05:00-07:00').parseZone();\n    m.startOf('h');\n    assert.equal(m.format(), '2014-03-09T03:00:00-07:00', 'startOf(\\'hour\\') after +1');\n\n    m = moment('2014-03-09T01:35:00-08:00').parseZone();\n    m.startOf('h');\n    assert.equal(m.format(), '2014-03-09T01:00:00-08:00', 'startOf(\\'hour\\') before +1');\n\n    // There is no such time as 2:30-7 to try startOf('hour') across that\n\n    moment.updateOffset = oldUpdateOffset;\n});\n\ntest('startOf across DST -1', function (assert) {\n    var oldUpdateOffset = moment.updateOffset,\n        // Based on a real story somewhere in America/Los_Angeles\n        dstAt = moment('2014-11-02T02:00:00-07:00').parseZone(),\n        m;\n\n    moment.updateOffset = function (mom, keepTime) {\n        if (mom.isBefore(dstAt)) {\n            mom.utcOffset(-7, keepTime);\n        } else {\n            mom.utcOffset(-8, keepTime);\n        }\n    };\n\n    m = moment('2014-11-15T00:00:00-08:00').parseZone();\n    m.startOf('y');\n    assert.equal(m.format(), '2014-01-01T00:00:00-07:00', 'startOf(\\'year\\') across -1');\n\n    m = moment('2014-11-15T00:00:00-08:00').parseZone();\n    m.startOf('M');\n    assert.equal(m.format(), '2014-11-01T00:00:00-07:00', 'startOf(\\'month\\') across -1');\n\n    m = moment('2014-11-02T09:00:00-08:00').parseZone();\n    m.startOf('d');\n    assert.equal(m.format(), '2014-11-02T00:00:00-07:00', 'startOf(\\'day\\') across -1');\n\n    // note that utc offset is -8\n    m = moment('2014-11-02T01:30:00-08:00').parseZone();\n    m.startOf('h');\n    assert.equal(m.format(), '2014-11-02T01:00:00-08:00', 'startOf(\\'hour\\') after +1');\n\n    // note that utc offset is -7\n    m = moment('2014-11-02T01:30:00-07:00').parseZone();\n    m.startOf('h');\n    assert.equal(m.format(), '2014-11-02T01:00:00-07:00', 'startOf(\\'hour\\') before +1');\n\n    moment.updateOffset = oldUpdateOffset;\n});\n\ntest('endOf millisecond and no-arg', function (assert) {\n    var m = moment();\n    assert.equal(+m, +m.clone().endOf(), 'endOf without argument should change time');\n    assert.equal(+m, +m.clone().endOf('ms'), 'endOf with ms argument should change time');\n    assert.equal(+m, +m.clone().endOf('millisecond'), 'endOf with millisecond argument should change time');\n    assert.equal(+m, +m.clone().endOf('milliseconds'), 'endOf with milliseconds argument should change time');\n});\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/test/moment/string_prototype.js",
    "content": "import { module, test } from '../qunit';\nimport moment from '../../moment';\n\nmodule('string prototype');\n\ntest('string prototype overrides call', function (assert) {\n    var prior = String.prototype.call, b;\n    String.prototype.call = function () {\n        return null;\n    };\n\n    b = moment(new Date(2011, 7, 28, 15, 25, 50, 125));\n    assert.equal(b.format('MMMM Do YYYY, h:mm a'), 'August 28th 2011, 3:25 pm');\n\n    String.prototype.call = prior;\n});\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/test/moment/to_type.js",
    "content": "import { module, test, expect } from '../qunit';\nimport moment from '../../moment';\n\nmodule('to type');\n\ntest('toObject', function (assert) {\n    var expected = {\n        years:2010,\n        months:3,\n        date:5,\n        hours:15,\n        minutes:10,\n        seconds:3,\n        milliseconds:123\n    };\n    assert.deepEqual(moment(expected).toObject(), expected, 'toObject invalid');\n});\n\ntest('toArray', function (assert) {\n    var expected = [2014, 11, 26, 11, 46, 58, 17];\n    assert.deepEqual(moment(expected).toArray(), expected, 'toArray invalid');\n});\n\ntest('toDate returns a copy of the internal date', function (assert) {\n    var m = moment();\n    var d = m.toDate();\n    m.year(0);\n    assert.notEqual(d, m.toDate());\n});\n\ntest('toJSON', function (assert) {\n    if (Date.prototype.toISOString) {\n        var expected = new Date().toISOString();\n        assert.deepEqual(moment(expected).toJSON(), expected, 'toJSON invalid');\n    } else {\n        // IE8\n        expect(0);\n    }\n});\n\ntest('toJSON works when moment is frozen', function (assert) {\n    if (Date.prototype.toISOString) {\n        var expected = new Date().toISOString();\n        var m = moment(expected);\n        if (Object.freeze != null) {\n            Object.freeze(m);\n        }\n        assert.deepEqual(m.toJSON(), expected, 'toJSON when frozen invalid');\n    } else {\n        // IE8\n        expect(0);\n    }\n});\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/test/moment/utc.js",
    "content": "import { module, test } from '../qunit';\nimport moment from '../../moment';\n\nmodule('utc');\n\ntest('utc and local', function (assert) {\n    var m = moment(Date.UTC(2011, 1, 2, 3, 4, 5, 6)), offset, expected;\n    m.utc();\n    // utc\n    assert.equal(m.date(), 2, 'the day should be correct for utc');\n    assert.equal(m.day(), 3, 'the date should be correct for utc');\n    assert.equal(m.hours(), 3, 'the hours should be correct for utc');\n\n    // local\n    m.local();\n    if (m.utcOffset() < -180) {\n        assert.equal(m.date(), 1, 'the date should be correct for local');\n        assert.equal(m.day(), 2, 'the day should be correct for local');\n    } else {\n        assert.equal(m.date(), 2, 'the date should be correct for local');\n        assert.equal(m.day(), 3, 'the day should be correct for local');\n    }\n    offset = Math.floor(m.utcOffset() / 60);\n    expected = (24 + 3 + offset) % 24;\n    assert.equal(m.hours(), expected, 'the hours (' + m.hours() + ') should be correct for local');\n    assert.equal(moment().utc().utcOffset(), 0, 'timezone in utc should always be zero');\n});\n\ntest('creating with utc and no arguments', function (assert) {\n    var startOfTest = new Date().valueOf(),\n        momentDefaultUtcTime = moment.utc().valueOf(),\n        afterMomentCreationTime = new Date().valueOf();\n\n    assert.ok(startOfTest <= momentDefaultUtcTime, 'moment UTC default time should be now, not in the past');\n    assert.ok(momentDefaultUtcTime <= afterMomentCreationTime, 'moment UTC default time should be now, not in the future');\n});\n\ntest('creating with utc and a date parameter array', function (assert) {\n    var m = moment.utc([2011, 1, 2, 3, 4, 5, 6]);\n    assert.equal(m.date(), 2, 'the day should be correct for utc array');\n    assert.equal(m.hours(), 3, 'the hours should be correct for utc array');\n\n    m = moment.utc('2011-02-02 3:04:05', 'YYYY-MM-DD HH:mm:ss');\n    assert.equal(m.date(), 2, 'the day should be correct for utc parsing format');\n    assert.equal(m.hours(), 3, 'the hours should be correct for utc parsing format');\n\n    m = moment.utc('2011-02-02T03:04:05+00:00');\n    assert.equal(m.date(), 2, 'the day should be correct for utc parsing iso');\n    assert.equal(m.hours(), 3, 'the hours should be correct for utc parsing iso');\n});\n\ntest('creating with utc without timezone', function (assert) {\n    var m = moment.utc('2012-01-02T08:20:00');\n    assert.equal(m.date(), 2, 'the day should be correct for utc parse without timezone');\n    assert.equal(m.hours(), 8, 'the hours should be correct for utc parse without timezone');\n\n    m = moment.utc('2012-01-02T08:20:00+09:00');\n    assert.equal(m.date(), 1, 'the day should be correct for utc parse with timezone');\n    assert.equal(m.hours(), 23, 'the hours should be correct for utc parse with timezone');\n});\n\ntest('cloning with utc offset', function (assert) {\n    var m = moment.utc('2012-01-02T08:20:00');\n    assert.equal(moment.utc(m)._isUTC, true, 'the local offset should be converted to UTC');\n    assert.equal(moment.utc(m.clone().utc())._isUTC, true, 'the local offset should stay in UTC');\n\n    m.utcOffset(120);\n    assert.equal(moment.utc(m)._isUTC, true, 'the explicit utc offset should stay in UTC');\n    assert.equal(moment.utc(m).utcOffset(), 0, 'the explicit utc offset should have an offset of 0');\n});\n\ntest('weekday with utc', function (assert) {\n    assert.equal(\n        moment('2013-09-15T00:00:00Z').utc().weekday(), // first minute of the day\n        moment('2013-09-15T23:59:00Z').utc().weekday(), // last minute of the day\n        'a UTC-moment\\'s .weekday() should not be affected by the local timezone'\n    );\n});\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/test/moment/utc_offset.js",
    "content": "import { module, test } from '../qunit';\nimport moment from '../../moment';\n\nmodule('utc offset');\n\ntest('setter / getter blackbox', function (assert) {\n    var m = moment([2010]);\n\n    assert.equal(m.clone().utcOffset(0).utcOffset(), 0, 'utcOffset 0');\n\n    assert.equal(m.clone().utcOffset(1).utcOffset(), 60, 'utcOffset 1 is 60');\n    assert.equal(m.clone().utcOffset(60).utcOffset(), 60, 'utcOffset 60');\n    assert.equal(m.clone().utcOffset('+01:00').utcOffset(), 60, 'utcOffset +01:00 is 60');\n    assert.equal(m.clone().utcOffset('+0100').utcOffset(), 60, 'utcOffset +0100 is 60');\n\n    assert.equal(m.clone().utcOffset(-1).utcOffset(), -60, 'utcOffset -1 is -60');\n    assert.equal(m.clone().utcOffset(-60).utcOffset(), -60, 'utcOffset -60');\n    assert.equal(m.clone().utcOffset('-01:00').utcOffset(), -60, 'utcOffset -01:00 is -60');\n    assert.equal(m.clone().utcOffset('-0100').utcOffset(), -60, 'utcOffset -0100 is -60');\n\n    assert.equal(m.clone().utcOffset(1.5).utcOffset(), 90, 'utcOffset 1.5 is 90');\n    assert.equal(m.clone().utcOffset(90).utcOffset(), 90, 'utcOffset 1.5 is 90');\n    assert.equal(m.clone().utcOffset('+01:30').utcOffset(), 90, 'utcOffset +01:30 is 90');\n    assert.equal(m.clone().utcOffset('+0130').utcOffset(), 90, 'utcOffset +0130 is 90');\n\n    assert.equal(m.clone().utcOffset(-1.5).utcOffset(), -90, 'utcOffset -1.5');\n    assert.equal(m.clone().utcOffset(-90).utcOffset(), -90, 'utcOffset -90');\n    assert.equal(m.clone().utcOffset('-01:30').utcOffset(), -90, 'utcOffset +01:30 is 90');\n    assert.equal(m.clone().utcOffset('-0130').utcOffset(), -90, 'utcOffset +0130 is 90');\n    assert.equal(m.clone().utcOffset('+00:10').utcOffset(), 10, 'utcOffset +00:10 is 10');\n    assert.equal(m.clone().utcOffset('-00:10').utcOffset(), -10, 'utcOffset +00:10 is 10');\n    assert.equal(m.clone().utcOffset('+0010').utcOffset(), 10, 'utcOffset +0010 is 10');\n    assert.equal(m.clone().utcOffset('-0010').utcOffset(), -10, 'utcOffset +0010 is 10');\n});\n\ntest('utcOffset shorthand hours -> minutes', function (assert) {\n    var i;\n    for (i = -15; i <= 15; ++i) {\n        assert.equal(moment().utcOffset(i).utcOffset(), i * 60,\n                '' + i + ' -> ' + i * 60);\n    }\n    assert.equal(moment().utcOffset(-16).utcOffset(), -16, '-16 -> -16');\n    assert.equal(moment().utcOffset(16).utcOffset(), 16, '16 -> 16');\n});\n\ntest('isLocal, isUtc, isUtcOffset', function (assert) {\n    assert.ok(moment().isLocal(), 'moment() creates objects in local time');\n    assert.ok(!moment.utc().isLocal(), 'moment.utc creates objects NOT in local time');\n    assert.ok(moment.utc().local().isLocal(), 'moment.fn.local() converts to local time');\n    assert.ok(!moment().utcOffset(5).isLocal(), 'moment.fn.utcOffset(N) puts objects NOT in local time');\n    assert.ok(moment().utcOffset(5).local().isLocal(), 'moment.fn.local() converts to local time');\n\n    assert.ok(moment.utc().isUtc(), 'moment.utc() creates objects in utc time');\n    assert.ok(moment().utcOffset(0).isUtc(), 'utcOffset(0) is equivalent to utc mode');\n    assert.ok(!moment().utcOffset(1).isUtc(), 'utcOffset(1) is NOT equivalent to utc mode');\n\n    assert.ok(!moment().isUtcOffset(), 'moment() creates objects NOT in utc-offset mode');\n    assert.ok(moment.utc().isUtcOffset(), 'moment.utc() creates objects in utc-offset mode');\n    assert.ok(moment().utcOffset(3).isUtcOffset(), 'utcOffset(N != 0) creates objects in utc-offset mode');\n    assert.ok(moment().utcOffset(0).isUtcOffset(), 'utcOffset(0) creates objects in utc-offset mode');\n});\n\ntest('isUTC', function (assert) {\n    assert.ok(moment.utc().isUTC(), 'moment.utc() creates objects in utc time');\n    assert.ok(moment().utcOffset(0).isUTC(), 'utcOffset(0) is equivalent to utc mode');\n    assert.ok(!moment().utcOffset(1).isUTC(), 'utcOffset(1) is NOT equivalent to utc mode');\n});\n\ntest('change hours when changing the utc offset', function (assert) {\n    var m = moment.utc([2000, 0, 1, 6]);\n    assert.equal(m.hour(), 6, 'UTC 6AM should be 6AM at +0000');\n\n    // sanity check\n    m.utcOffset(0);\n    assert.equal(m.hour(), 6, 'UTC 6AM should be 6AM at +0000');\n\n    m.utcOffset(-60);\n    assert.equal(m.hour(), 5, 'UTC 6AM should be 5AM at -0100');\n\n    m.utcOffset(60);\n    assert.equal(m.hour(), 7, 'UTC 6AM should be 7AM at +0100');\n});\n\ntest('change minutes when changing the utc offset', function (assert) {\n    var m = moment.utc([2000, 0, 1, 6, 31]);\n\n    m.utcOffset(0);\n    assert.equal(m.format('HH:mm'), '06:31', 'UTC 6:31AM should be 6:31AM at +0000');\n\n    m.utcOffset(-30);\n    assert.equal(m.format('HH:mm'), '06:01', 'UTC 6:31AM should be 6:01AM at -0030');\n\n    m.utcOffset(30);\n    assert.equal(m.format('HH:mm'), '07:01', 'UTC 6:31AM should be 7:01AM at +0030');\n\n    m.utcOffset(-1380);\n    assert.equal(m.format('HH:mm'), '07:31', 'UTC 6:31AM should be 7:31AM at +1380');\n});\n\ntest('distance from the unix epoch', function (assert) {\n    var zoneA = moment(),\n        zoneB = moment(zoneA),\n        zoneC = moment(zoneA),\n        zoneD = moment(zoneA),\n        zoneE = moment(zoneA);\n\n    zoneB.utc();\n    assert.equal(+zoneA, +zoneB, 'moment should equal moment.utc');\n\n    zoneC.utcOffset(60);\n    assert.equal(+zoneA, +zoneC, 'moment should equal moment.utcOffset(60)');\n\n    zoneD.utcOffset(-480);\n    assert.equal(+zoneA, +zoneD,\n            'moment should equal moment.utcOffset(-480)');\n\n    zoneE.utcOffset(-1000);\n    assert.equal(+zoneA, +zoneE,\n            'moment should equal moment.utcOffset(-1000)');\n});\n\ntest('update offset after changing any values', function (assert) {\n    var oldOffset = moment.updateOffset,\n        m = moment.utc([2000, 6, 1]);\n\n    moment.updateOffset = function (mom, keepTime) {\n        if (mom.__doChange) {\n            if (+mom > 962409600000) {\n                mom.utcOffset(-120, keepTime);\n            } else {\n                mom.utcOffset(-60, keepTime);\n            }\n        }\n    };\n\n    assert.equal(m.format('ZZ'), '+0000', 'should be at +0000');\n    assert.equal(m.format('HH:mm'), '00:00', 'should start 12AM at +0000 timezone');\n\n    m.__doChange = true;\n    m.add(1, 'h');\n\n    assert.equal(m.format('ZZ'), '-0200', 'should be at -0200');\n    assert.equal(m.format('HH:mm'), '23:00', '1AM at +0000 should be 11PM at -0200 timezone');\n\n    m.subtract(1, 'h');\n\n    assert.equal(m.format('ZZ'), '-0100', 'should be at -0100');\n    assert.equal(m.format('HH:mm'), '23:00', '12AM at +0000 should be 11PM at -0100 timezone');\n\n    moment.updateOffset = oldOffset;\n});\n\n//////////////////\ntest('getters and setters', function (assert) {\n    var a = moment([2011, 5, 20]);\n\n    assert.equal(a.clone().utcOffset(-120).year(2012).year(), 2012, 'should get and set year correctly');\n    assert.equal(a.clone().utcOffset(-120).month(1).month(), 1, 'should get and set month correctly');\n    assert.equal(a.clone().utcOffset(-120).date(2).date(), 2, 'should get and set date correctly');\n    assert.equal(a.clone().utcOffset(-120).day(1).day(), 1, 'should get and set day correctly');\n    assert.equal(a.clone().utcOffset(-120).hour(1).hour(), 1, 'should get and set hour correctly');\n    assert.equal(a.clone().utcOffset(-120).minute(1).minute(), 1, 'should get and set minute correctly');\n});\n\ntest('getters', function (assert) {\n    var a = moment.utc([2012, 0, 1, 0, 0, 0]);\n\n    assert.equal(a.clone().utcOffset(-120).year(),  2011, 'should get year correctly');\n    assert.equal(a.clone().utcOffset(-120).month(),   11, 'should get month correctly');\n    assert.equal(a.clone().utcOffset(-120).date(),    31, 'should get date correctly');\n    assert.equal(a.clone().utcOffset(-120).hour(),    22, 'should get hour correctly');\n    assert.equal(a.clone().utcOffset(-120).minute(),   0, 'should get minute correctly');\n\n    assert.equal(a.clone().utcOffset(120).year(),  2012, 'should get year correctly');\n    assert.equal(a.clone().utcOffset(120).month(),    0, 'should get month correctly');\n    assert.equal(a.clone().utcOffset(120).date(),     1, 'should get date correctly');\n    assert.equal(a.clone().utcOffset(120).hour(),     2, 'should get hour correctly');\n    assert.equal(a.clone().utcOffset(120).minute(),   0, 'should get minute correctly');\n\n    assert.equal(a.clone().utcOffset(90).year(),  2012, 'should get year correctly');\n    assert.equal(a.clone().utcOffset(90).month(),    0, 'should get month correctly');\n    assert.equal(a.clone().utcOffset(90).date(),     1, 'should get date correctly');\n    assert.equal(a.clone().utcOffset(90).hour(),     1, 'should get hour correctly');\n    assert.equal(a.clone().utcOffset(90).minute(),  30, 'should get minute correctly');\n});\n\ntest('from', function (assert) {\n    var zoneA = moment(),\n        zoneB = moment(zoneA).utcOffset(-720),\n        zoneC = moment(zoneA).utcOffset(-360),\n        zoneD = moment(zoneA).utcOffset(690),\n        other = moment(zoneA).add(35, 'm');\n\n    assert.equal(zoneA.from(other), zoneB.from(other), 'moment#from should be the same in all zones');\n    assert.equal(zoneA.from(other), zoneC.from(other), 'moment#from should be the same in all zones');\n    assert.equal(zoneA.from(other), zoneD.from(other), 'moment#from should be the same in all zones');\n});\n\ntest('diff', function (assert) {\n    var zoneA = moment(),\n        zoneB = moment(zoneA).utcOffset(-720),\n        zoneC = moment(zoneA).utcOffset(-360),\n        zoneD = moment(zoneA).utcOffset(690),\n        other = moment(zoneA).add(35, 'm');\n\n    assert.equal(zoneA.diff(other), zoneB.diff(other), 'moment#diff should be the same in all zones');\n    assert.equal(zoneA.diff(other), zoneC.diff(other), 'moment#diff should be the same in all zones');\n    assert.equal(zoneA.diff(other), zoneD.diff(other), 'moment#diff should be the same in all zones');\n\n    assert.equal(zoneA.diff(other, 'minute', true), zoneB.diff(other, 'minute', true), 'moment#diff should be the same in all zones');\n    assert.equal(zoneA.diff(other, 'minute', true), zoneC.diff(other, 'minute', true), 'moment#diff should be the same in all zones');\n    assert.equal(zoneA.diff(other, 'minute', true), zoneD.diff(other, 'minute', true), 'moment#diff should be the same in all zones');\n\n    assert.equal(zoneA.diff(other, 'hour', true), zoneB.diff(other, 'hour', true), 'moment#diff should be the same in all zones');\n    assert.equal(zoneA.diff(other, 'hour', true), zoneC.diff(other, 'hour', true), 'moment#diff should be the same in all zones');\n    assert.equal(zoneA.diff(other, 'hour', true), zoneD.diff(other, 'hour', true), 'moment#diff should be the same in all zones');\n});\n\ntest('unix offset and timestamp', function (assert) {\n    var zoneA = moment(),\n        zoneB = moment(zoneA).utcOffset(-720),\n        zoneC = moment(zoneA).utcOffset(-360),\n        zoneD = moment(zoneA).utcOffset(690);\n\n    assert.equal(zoneA.unix(), zoneB.unix(), 'moment#unix should be the same in all zones');\n    assert.equal(zoneA.unix(), zoneC.unix(), 'moment#unix should be the same in all zones');\n    assert.equal(zoneA.unix(), zoneD.unix(), 'moment#unix should be the same in all zones');\n\n    assert.equal(+zoneA, +zoneB, 'moment#valueOf should be the same in all zones');\n    assert.equal(+zoneA, +zoneC, 'moment#valueOf should be the same in all zones');\n    assert.equal(+zoneA, +zoneD, 'moment#valueOf should be the same in all zones');\n});\n\ntest('cloning', function (assert) {\n    assert.equal(moment().utcOffset(-120).clone().utcOffset(), -120,\n            'explicit cloning should retain the offset');\n    assert.equal(moment().utcOffset(120).clone().utcOffset(), 120,\n            'explicit cloning should retain the offset');\n    assert.equal(moment(moment().utcOffset(-120)).utcOffset(), -120,\n            'implicit cloning should retain the offset');\n    assert.equal(moment(moment().utcOffset(120)).utcOffset(), 120,\n            'implicit cloning should retain the offset');\n});\n\ntest('start of / end of', function (assert) {\n    var a = moment.utc([2010, 1, 2, 0, 0, 0]).utcOffset(-450);\n\n    assert.equal(a.clone().startOf('day').hour(), 0,\n            'start of day should work on moments with utc offset');\n    assert.equal(a.clone().startOf('day').minute(), 0,\n            'start of day should work on moments with utc offset');\n    assert.equal(a.clone().startOf('hour').minute(), 0,\n            'start of hour should work on moments with utc offset');\n\n    assert.equal(a.clone().endOf('day').hour(), 23,\n            'end of day should work on moments with utc offset');\n    assert.equal(a.clone().endOf('day').minute(), 59,\n            'end of day should work on moments with utc offset');\n    assert.equal(a.clone().endOf('hour').minute(), 59,\n            'end of hour should work on moments with utc offset');\n});\n\ntest('reset offset with moment#utc', function (assert) {\n    var a = moment.utc([2012]).utcOffset(-480);\n\n    assert.equal(a.clone().hour(),      16, 'different utc offset should have different hour');\n    assert.equal(a.clone().utc().hour(), 0, 'calling moment#utc should reset the offset');\n});\n\ntest('reset offset with moment#local', function (assert) {\n    var a = moment([2012]).utcOffset(-480);\n\n    assert.equal(a.clone().local().hour(), 0, 'calling moment#local should reset the offset');\n});\n\ntest('toDate', function (assert) {\n    var zoneA = new Date(),\n        zoneB = moment(zoneA).utcOffset(-720).toDate(),\n        zoneC = moment(zoneA).utcOffset(-360).toDate(),\n        zoneD = moment(zoneA).utcOffset(690).toDate();\n\n    assert.equal(+zoneA, +zoneB, 'moment#toDate should output a date with the right unix timestamp');\n    assert.equal(+zoneA, +zoneC, 'moment#toDate should output a date with the right unix timestamp');\n    assert.equal(+zoneA, +zoneD, 'moment#toDate should output a date with the right unix timestamp');\n});\n\ntest('same / before / after', function (assert) {\n    var zoneA = moment().utc(),\n        zoneB = moment(zoneA).utcOffset(-120),\n        zoneC = moment(zoneA).utcOffset(120);\n\n    assert.ok(zoneA.isSame(zoneB), 'two moments with different offsets should be the same');\n    assert.ok(zoneA.isSame(zoneC), 'two moments with different offsets should be the same');\n\n    assert.ok(zoneA.isSame(zoneB, 'hour'), 'two moments with different offsets should be the same hour');\n    assert.ok(zoneA.isSame(zoneC, 'hour'), 'two moments with different offsets should be the same hour');\n\n    zoneA.add(1, 'hour');\n\n    assert.ok(zoneA.isAfter(zoneB), 'isAfter should work with two moments with different offsets');\n    assert.ok(zoneA.isAfter(zoneC), 'isAfter should work with two moments with different offsets');\n\n    assert.ok(zoneA.isAfter(zoneB, 'hour'), 'isAfter:hour should work with two moments with different offsets');\n    assert.ok(zoneA.isAfter(zoneC, 'hour'), 'isAfter:hour should work with two moments with different offsets');\n\n    zoneA.subtract(2, 'hour');\n\n    assert.ok(zoneA.isBefore(zoneB), 'isBefore should work with two moments with different offsets');\n    assert.ok(zoneA.isBefore(zoneC), 'isBefore should work with two moments with different offsets');\n\n    assert.ok(zoneA.isBefore(zoneB, 'hour'), 'isBefore:hour should work with two moments with different offsets');\n    assert.ok(zoneA.isBefore(zoneC, 'hour'), 'isBefore:hour should work with two moments with different offsets');\n});\n\ntest('add / subtract over dst', function (assert) {\n    var oldOffset = moment.updateOffset,\n        m = moment.utc([2000, 2, 31, 3]);\n\n    moment.updateOffset = function (mom, keepTime) {\n        if (mom.clone().utc().month() > 2) {\n            mom.utcOffset(60, keepTime);\n        } else {\n            mom.utcOffset(0, keepTime);\n        }\n    };\n\n    assert.equal(m.hour(), 3, 'should start at 00:00');\n\n    m.add(24, 'hour');\n\n    assert.equal(m.hour(), 4, 'adding 24 hours should disregard dst');\n\n    m.subtract(24, 'hour');\n\n    assert.equal(m.hour(), 3, 'subtracting 24 hours should disregard dst');\n\n    m.add(1, 'day');\n\n    assert.equal(m.hour(), 3, 'adding 1 day should have the same hour');\n\n    m.subtract(1, 'day');\n\n    assert.equal(m.hour(), 3, 'subtracting 1 day should have the same hour');\n\n    m.add(1, 'month');\n\n    assert.equal(m.hour(), 3, 'adding 1 month should have the same hour');\n\n    m.subtract(1, 'month');\n\n    assert.equal(m.hour(), 3, 'subtracting 1 month should have the same hour');\n\n    moment.updateOffset = oldOffset;\n});\n\ntest('isDST', function (assert) {\n    var oldOffset = moment.updateOffset;\n\n    moment.updateOffset = function (mom, keepTime) {\n        if (mom.month() > 2 && mom.month() < 9) {\n            mom.utcOffset(60, keepTime);\n        } else {\n            mom.utcOffset(0, keepTime);\n        }\n    };\n\n    assert.ok(!moment().month(0).isDST(),  'Jan should not be summer dst');\n    assert.ok(moment().month(6).isDST(),   'Jul should be summer dst');\n    assert.ok(!moment().month(11).isDST(), 'Dec should not be summer dst');\n\n    moment.updateOffset = function (mom) {\n        if (mom.month() > 2 && mom.month() < 9) {\n            mom.utcOffset(0);\n        } else {\n            mom.utcOffset(60);\n        }\n    };\n\n    assert.ok(moment().month(0).isDST(),  'Jan should be winter dst');\n    assert.ok(!moment().month(6).isDST(), 'Jul should not be winter dst');\n    assert.ok(moment().month(11).isDST(), 'Dec should be winter dst');\n\n    moment.updateOffset = oldOffset;\n});\n\ntest('zone names', function (assert) {\n    assert.equal(moment().zoneAbbr(),   '', 'Local zone abbr should be empty');\n    assert.equal(moment().format('z'),  '', 'Local zone formatted abbr should be empty');\n    assert.equal(moment().zoneName(),   '', 'Local zone name should be empty');\n    assert.equal(moment().format('zz'), '', 'Local zone formatted name should be empty');\n\n    assert.equal(moment.utc().zoneAbbr(),   'UTC', 'UTC zone abbr should be UTC');\n    assert.equal(moment.utc().format('z'),  'UTC', 'UTC zone formatted abbr should be UTC');\n    assert.equal(moment.utc().zoneName(),   'Coordinated Universal Time', 'UTC zone abbr should be Coordinated Universal Time');\n    assert.equal(moment.utc().format('zz'), 'Coordinated Universal Time', 'UTC zone formatted abbr should be Coordinated Universal Time');\n});\n\ntest('hours alignment with UTC', function (assert) {\n    assert.equal(moment().utcOffset(-120).hasAlignedHourOffset(), true);\n    assert.equal(moment().utcOffset(180).hasAlignedHourOffset(), true);\n    assert.equal(moment().utcOffset(-90).hasAlignedHourOffset(), false);\n    assert.equal(moment().utcOffset(90).hasAlignedHourOffset(), false);\n});\n\ntest('hours alignment with other zone', function (assert) {\n    var m = moment().utcOffset(-120);\n\n    assert.equal(m.hasAlignedHourOffset(moment().utcOffset(-180)), true);\n    assert.equal(m.hasAlignedHourOffset(moment().utcOffset(180)), true);\n    assert.equal(m.hasAlignedHourOffset(moment().utcOffset(-90)), false);\n    assert.equal(m.hasAlignedHourOffset(moment().utcOffset(90)), false);\n\n    m = moment().utcOffset(-90);\n\n    assert.equal(m.hasAlignedHourOffset(moment().utcOffset(-180)), false);\n    assert.equal(m.hasAlignedHourOffset(moment().utcOffset(180)), false);\n    assert.equal(m.hasAlignedHourOffset(moment().utcOffset(-30)), true);\n    assert.equal(m.hasAlignedHourOffset(moment().utcOffset(30)), true);\n\n    m = moment().utcOffset(60);\n\n    assert.equal(m.hasAlignedHourOffset(moment().utcOffset(-180)), true);\n    assert.equal(m.hasAlignedHourOffset(moment().utcOffset(180)), true);\n    assert.equal(m.hasAlignedHourOffset(moment().utcOffset(-90)), false);\n    assert.equal(m.hasAlignedHourOffset(moment().utcOffset(90)), false);\n\n    m = moment().utcOffset(-25);\n\n    assert.equal(m.hasAlignedHourOffset(moment().utcOffset(35)), true);\n    assert.equal(m.hasAlignedHourOffset(moment().utcOffset(-85)), true);\n\n    assert.equal(m.hasAlignedHourOffset(moment().utcOffset(-35)), false);\n    assert.equal(m.hasAlignedHourOffset(moment().utcOffset(85)), false);\n});\n\ntest('parse zone', function (assert) {\n    var m = moment('2013-01-01T00:00:00-13:00').parseZone();\n    assert.equal(m.utcOffset(), -13 * 60);\n    assert.equal(m.hours(), 0);\n});\n\ntest('parse UTC zone', function (assert) {\n    var m = moment('2013-01-01T05:00:00+00:00').parseZone();\n    assert.equal(m.utcOffset(), 0);\n    assert.equal(m.hours(), 5);\n});\n\ntest('parse zone static', function (assert) {\n    var m = moment.parseZone('2013-01-01T00:00:00-13:00');\n    assert.equal(m.utcOffset(), -13 * 60);\n    assert.equal(m.hours(), 0);\n});\n\ntest('parse zone with more arguments', function (assert) {\n    var m;\n    m = moment.parseZone('2013 01 01 05 -13:00', 'YYYY MM DD HH ZZ');\n    assert.equal(m.format(), '2013-01-01T05:00:00-13:00', 'accept input and format');\n    m = moment.parseZone('2013-01-01-13:00', 'YYYY MM DD ZZ', true);\n    assert.equal(m.isValid(), false, 'accept input, format and strict flag');\n    m = moment.parseZone('2013-01-01-13:00', ['DD MM YYYY ZZ', 'YYYY MM DD ZZ']);\n    assert.equal(m.format(), '2013-01-01T00:00:00-13:00', 'accept input and array of formats');\n});\n\ntest('parse zone with a timezone from the format string', function (assert) {\n    var m = moment('11-12-2013 -0400 +1100', 'DD-MM-YYYY ZZ #####').parseZone();\n\n    assert.equal(m.utcOffset(), -4 * 60);\n});\n\ntest('parse zone without a timezone included in the format string', function (assert) {\n    var m = moment('11-12-2013 -0400 +1100', 'DD-MM-YYYY').parseZone();\n\n    assert.equal(m.utcOffset(), 11 * 60);\n});\n\ntest('timezone format', function (assert) {\n    assert.equal(moment().utcOffset(60).format('ZZ'), '+0100', '-60 -> +0100');\n    assert.equal(moment().utcOffset(90).format('ZZ'), '+0130', '-90 -> +0130');\n    assert.equal(moment().utcOffset(120).format('ZZ'), '+0200', '-120 -> +0200');\n\n    assert.equal(moment().utcOffset(-60).format('ZZ'), '-0100', '+60 -> -0100');\n    assert.equal(moment().utcOffset(-90).format('ZZ'), '-0130', '+90 -> -0130');\n    assert.equal(moment().utcOffset(-120).format('ZZ'), '-0200', '+120 -> -0200');\n});\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/test/moment/week_year.js",
    "content": "import { module, test } from '../qunit';\nimport moment from '../../moment';\n\nmodule('week year');\n\ntest('iso week year', function (assert) {\n    // Some examples taken from https://en.wikipedia.org/wiki/ISO_week\n    assert.equal(moment([2005, 0, 1]).isoWeekYear(), 2004);\n    assert.equal(moment([2005, 0, 2]).isoWeekYear(), 2004);\n    assert.equal(moment([2005, 0, 3]).isoWeekYear(), 2005);\n    assert.equal(moment([2005, 11, 31]).isoWeekYear(), 2005);\n    assert.equal(moment([2006, 0, 1]).isoWeekYear(), 2005);\n    assert.equal(moment([2006, 0, 2]).isoWeekYear(), 2006);\n    assert.equal(moment([2007, 0, 1]).isoWeekYear(), 2007);\n    assert.equal(moment([2007, 11, 30]).isoWeekYear(), 2007);\n    assert.equal(moment([2007, 11, 31]).isoWeekYear(), 2008);\n    assert.equal(moment([2008, 0, 1]).isoWeekYear(), 2008);\n    assert.equal(moment([2008, 11, 28]).isoWeekYear(), 2008);\n    assert.equal(moment([2008, 11, 29]).isoWeekYear(), 2009);\n    assert.equal(moment([2008, 11, 30]).isoWeekYear(), 2009);\n    assert.equal(moment([2008, 11, 31]).isoWeekYear(), 2009);\n    assert.equal(moment([2009, 0, 1]).isoWeekYear(), 2009);\n    assert.equal(moment([2010, 0, 1]).isoWeekYear(), 2009);\n    assert.equal(moment([2010, 0, 2]).isoWeekYear(), 2009);\n    assert.equal(moment([2010, 0, 3]).isoWeekYear(), 2009);\n    assert.equal(moment([2010, 0, 4]).isoWeekYear(), 2010);\n});\n\ntest('week year', function (assert) {\n    // Some examples taken from https://en.wikipedia.org/wiki/ISO_week\n    moment.locale('dow: 1,doy: 4', {week: {dow: 1, doy: 4}}); // like iso\n    assert.equal(moment([2005, 0, 1]).weekYear(), 2004);\n    assert.equal(moment([2005, 0, 2]).weekYear(), 2004);\n    assert.equal(moment([2005, 0, 3]).weekYear(), 2005);\n    assert.equal(moment([2005, 11, 31]).weekYear(), 2005);\n    assert.equal(moment([2006, 0, 1]).weekYear(), 2005);\n    assert.equal(moment([2006, 0, 2]).weekYear(), 2006);\n    assert.equal(moment([2007, 0, 1]).weekYear(), 2007);\n    assert.equal(moment([2007, 11, 30]).weekYear(), 2007);\n    assert.equal(moment([2007, 11, 31]).weekYear(), 2008);\n    assert.equal(moment([2008, 0, 1]).weekYear(), 2008);\n    assert.equal(moment([2008, 11, 28]).weekYear(), 2008);\n    assert.equal(moment([2008, 11, 29]).weekYear(), 2009);\n    assert.equal(moment([2008, 11, 30]).weekYear(), 2009);\n    assert.equal(moment([2008, 11, 31]).weekYear(), 2009);\n    assert.equal(moment([2009, 0, 1]).weekYear(), 2009);\n    assert.equal(moment([2010, 0, 1]).weekYear(), 2009);\n    assert.equal(moment([2010, 0, 2]).weekYear(), 2009);\n    assert.equal(moment([2010, 0, 3]).weekYear(), 2009);\n    assert.equal(moment([2010, 0, 4]).weekYear(), 2010);\n\n    moment.locale('dow: 1,doy: 7', {week: {dow: 1, doy: 7}});\n    assert.equal(moment([2004, 11, 26]).weekYear(), 2004);\n    assert.equal(moment([2004, 11, 27]).weekYear(), 2005);\n    assert.equal(moment([2005, 11, 25]).weekYear(), 2005);\n    assert.equal(moment([2005, 11, 26]).weekYear(), 2006);\n    assert.equal(moment([2006, 11, 31]).weekYear(), 2006);\n    assert.equal(moment([2007,  0,  1]).weekYear(), 2007);\n    assert.equal(moment([2007, 11, 30]).weekYear(), 2007);\n    assert.equal(moment([2007, 11, 31]).weekYear(), 2008);\n    assert.equal(moment([2008, 11, 28]).weekYear(), 2008);\n    assert.equal(moment([2008, 11, 29]).weekYear(), 2009);\n    assert.equal(moment([2009, 11, 27]).weekYear(), 2009);\n    assert.equal(moment([2009, 11, 28]).weekYear(), 2010);\n});\n\n// Verifies that the week number, week day computation is correct for all dow, doy combinations\ntest('week year roundtrip', function (assert) {\n    var dow, doy, wd, m, localeName;\n    for (dow = 0; dow < 7; ++dow) {\n        for (doy = dow; doy < dow + 7; ++doy) {\n            for (wd = 0; wd < 7; ++wd) {\n                localeName = 'dow: ' + dow + ', doy: ' + doy;\n                moment.locale(localeName, {week: {dow: dow, doy: doy}});\n                // We use the 10th week as the 1st one can spill to the previous year\n                m = moment('2015 10 ' + wd, 'gggg w d', true);\n                assert.equal(m.format('gggg w d'), '2015 10 ' + wd, 'dow: ' + dow + ' doy: ' + doy + ' wd: ' + wd);\n                m = moment('2015 10 ' + wd, 'gggg w e', true);\n                assert.equal(m.format('gggg w e'), '2015 10 ' + wd, 'dow: ' + dow + ' doy: ' + doy + ' wd: ' + wd);\n                moment.defineLocale(localeName, null);\n            }\n        }\n    }\n});\n\ntest('week numbers 2012/2013', function (assert) {\n    moment.locale('dow: 6, doy: 12', {week: {dow: 6, doy: 12}});\n    assert.equal(52, moment('2012-12-28', 'YYYY-MM-DD').week(), '2012-12-28 is week 52'); // 51 -- should be 52?\n    assert.equal(1, moment('2012-12-29', 'YYYY-MM-DD').week(), '2012-12-29 is week 1'); // 52 -- should be 1\n    assert.equal(1, moment('2013-01-01', 'YYYY-MM-DD').week(), '2013-01-01 is week 1'); // 52 -- should be 1\n    assert.equal(2, moment('2013-01-08', 'YYYY-MM-DD').week(), '2013-01-08 is week 2'); // 53 -- should be 2\n    assert.equal(2, moment('2013-01-11', 'YYYY-MM-DD').week(), '2013-01-11 is week 2'); // 53 -- should be 2\n    assert.equal(3, moment('2013-01-12', 'YYYY-MM-DD').week(), '2013-01-12 is week 3'); // 1 -- should be 3\n    assert.equal(52, moment('2012-01-01', 'YYYY-MM-DD').weeksInYear(), 'weeks in 2012 are 52'); // 52\n    moment.defineLocale('dow: 6, doy: 12', null);\n});\n\ntest('weeks numbers dow:1 doy:4', function (assert) {\n    moment.locale('dow: 1, doy: 4', {week: {dow: 1, doy: 4}});\n    assert.equal(moment([2012, 0, 1]).week(), 52, 'Jan  1 2012 should be week 52');\n    assert.equal(moment([2012, 0, 2]).week(),  1, 'Jan  2 2012 should be week 1');\n    assert.equal(moment([2012, 0, 8]).week(),  1, 'Jan  8 2012 should be week 1');\n    assert.equal(moment([2012, 0, 9]).week(),  2, 'Jan  9 2012 should be week 2');\n    assert.equal(moment([2012, 0, 15]).week(), 2, 'Jan 15 2012 should be week 2');\n    assert.equal(moment([2007, 0, 1]).week(),  1, 'Jan  1 2007 should be week 1');\n    assert.equal(moment([2007, 0, 7]).week(),  1, 'Jan  7 2007 should be week 1');\n    assert.equal(moment([2007, 0, 8]).week(),  2, 'Jan  8 2007 should be week 2');\n    assert.equal(moment([2007, 0, 14]).week(), 2, 'Jan 14 2007 should be week 2');\n    assert.equal(moment([2007, 0, 15]).week(), 3, 'Jan 15 2007 should be week 3');\n    assert.equal(moment([2007, 11, 31]).week(), 1, 'Dec 31 2007 should be week 1');\n    assert.equal(moment([2008,  0,  1]).week(), 1, 'Jan  1 2008 should be week 1');\n    assert.equal(moment([2008,  0,  6]).week(), 1, 'Jan  6 2008 should be week 1');\n    assert.equal(moment([2008,  0,  7]).week(), 2, 'Jan  7 2008 should be week 2');\n    assert.equal(moment([2008,  0, 13]).week(), 2, 'Jan 13 2008 should be week 2');\n    assert.equal(moment([2008,  0, 14]).week(), 3, 'Jan 14 2008 should be week 3');\n    assert.equal(moment([2002, 11, 30]).week(), 1, 'Dec 30 2002 should be week 1');\n    assert.equal(moment([2003,  0,  1]).week(), 1, 'Jan  1 2003 should be week 1');\n    assert.equal(moment([2003,  0,  5]).week(), 1, 'Jan  5 2003 should be week 1');\n    assert.equal(moment([2003,  0,  6]).week(), 2, 'Jan  6 2003 should be week 2');\n    assert.equal(moment([2003,  0, 12]).week(), 2, 'Jan 12 2003 should be week 2');\n    assert.equal(moment([2003,  0, 13]).week(), 3, 'Jan 13 2003 should be week 3');\n    assert.equal(moment([2008, 11, 29]).week(), 1, 'Dec 29 2008 should be week 1');\n    assert.equal(moment([2009,  0,  1]).week(), 1, 'Jan  1 2009 should be week 1');\n    assert.equal(moment([2009,  0,  4]).week(), 1, 'Jan  4 2009 should be week 1');\n    assert.equal(moment([2009,  0,  5]).week(), 2, 'Jan  5 2009 should be week 2');\n    assert.equal(moment([2009,  0, 11]).week(), 2, 'Jan 11 2009 should be week 2');\n    assert.equal(moment([2009,  0, 13]).week(), 3, 'Jan 12 2009 should be week 3');\n    assert.equal(moment([2009, 11, 28]).week(), 53, 'Dec 28 2009 should be week 53');\n    assert.equal(moment([2010,  0,  1]).week(), 53, 'Jan  1 2010 should be week 53');\n    assert.equal(moment([2010,  0,  3]).week(), 53, 'Jan  3 2010 should be week 53');\n    assert.equal(moment([2010,  0,  4]).week(),  1, 'Jan  4 2010 should be week 1');\n    assert.equal(moment([2010,  0, 10]).week(),  1, 'Jan 10 2010 should be week 1');\n    assert.equal(moment([2010,  0, 11]).week(),  2, 'Jan 11 2010 should be week 2');\n    assert.equal(moment([2010, 11, 27]).week(), 52, 'Dec 27 2010 should be week 52');\n    assert.equal(moment([2011,  0,  1]).week(), 52, 'Jan  1 2011 should be week 52');\n    assert.equal(moment([2011,  0,  2]).week(), 52, 'Jan  2 2011 should be week 52');\n    assert.equal(moment([2011,  0,  3]).week(),  1, 'Jan  3 2011 should be week 1');\n    assert.equal(moment([2011,  0,  9]).week(),  1, 'Jan  9 2011 should be week 1');\n    assert.equal(moment([2011,  0, 10]).week(),  2, 'Jan 10 2011 should be week 2');\n    moment.defineLocale('dow: 1, doy: 4', null);\n});\n\ntest('weeks numbers dow:6 doy:12', function (assert) {\n    moment.locale('dow: 6, doy: 12', {week: {dow: 6, doy: 12}});\n    assert.equal(moment([2011, 11, 31]).week(), 1, 'Dec 31 2011 should be week 1');\n    assert.equal(moment([2012,  0,  6]).week(), 1, 'Jan  6 2012 should be week 1');\n    assert.equal(moment([2012,  0,  7]).week(), 2, 'Jan  7 2012 should be week 2');\n    assert.equal(moment([2012,  0, 13]).week(), 2, 'Jan 13 2012 should be week 2');\n    assert.equal(moment([2012,  0, 14]).week(), 3, 'Jan 14 2012 should be week 3');\n    assert.equal(moment([2006, 11, 30]).week(), 1, 'Dec 30 2006 should be week 1');\n    assert.equal(moment([2007,  0,  5]).week(), 1, 'Jan  5 2007 should be week 1');\n    assert.equal(moment([2007,  0,  6]).week(), 2, 'Jan  6 2007 should be week 2');\n    assert.equal(moment([2007,  0, 12]).week(), 2, 'Jan 12 2007 should be week 2');\n    assert.equal(moment([2007,  0, 13]).week(), 3, 'Jan 13 2007 should be week 3');\n    assert.equal(moment([2007, 11, 29]).week(), 1, 'Dec 29 2007 should be week 1');\n    assert.equal(moment([2008,  0,  1]).week(), 1, 'Jan  1 2008 should be week 1');\n    assert.equal(moment([2008,  0,  4]).week(), 1, 'Jan  4 2008 should be week 1');\n    assert.equal(moment([2008,  0,  5]).week(), 2, 'Jan  5 2008 should be week 2');\n    assert.equal(moment([2008,  0, 11]).week(), 2, 'Jan 11 2008 should be week 2');\n    assert.equal(moment([2008,  0, 12]).week(), 3, 'Jan 12 2008 should be week 3');\n    assert.equal(moment([2002, 11, 28]).week(), 1, 'Dec 28 2002 should be week 1');\n    assert.equal(moment([2003,  0,  1]).week(), 1, 'Jan  1 2003 should be week 1');\n    assert.equal(moment([2003,  0,  3]).week(), 1, 'Jan  3 2003 should be week 1');\n    assert.equal(moment([2003,  0,  4]).week(), 2, 'Jan  4 2003 should be week 2');\n    assert.equal(moment([2003,  0, 10]).week(), 2, 'Jan 10 2003 should be week 2');\n    assert.equal(moment([2003,  0, 11]).week(), 3, 'Jan 11 2003 should be week 3');\n    assert.equal(moment([2008, 11, 27]).week(), 1, 'Dec 27 2008 should be week 1');\n    assert.equal(moment([2009,  0,  1]).week(), 1, 'Jan  1 2009 should be week 1');\n    assert.equal(moment([2009,  0,  2]).week(), 1, 'Jan  2 2009 should be week 1');\n    assert.equal(moment([2009,  0,  3]).week(), 2, 'Jan  3 2009 should be week 2');\n    assert.equal(moment([2009,  0,  9]).week(), 2, 'Jan  9 2009 should be week 2');\n    assert.equal(moment([2009,  0, 10]).week(), 3, 'Jan 10 2009 should be week 3');\n    assert.equal(moment([2009, 11, 26]).week(), 1, 'Dec 26 2009 should be week 1');\n    assert.equal(moment([2010,  0,  1]).week(), 1, 'Jan  1 2010 should be week 1');\n    assert.equal(moment([2010,  0,  2]).week(), 2, 'Jan  2 2010 should be week 2');\n    assert.equal(moment([2010,  0,  8]).week(), 2, 'Jan  8 2010 should be week 2');\n    assert.equal(moment([2010,  0,  9]).week(), 3, 'Jan  9 2010 should be week 3');\n    assert.equal(moment([2011, 0,  1]).week(), 1, 'Jan  1 2011 should be week 1');\n    assert.equal(moment([2011, 0,  7]).week(), 1, 'Jan  7 2011 should be week 1');\n    assert.equal(moment([2011, 0,  8]).week(), 2, 'Jan  8 2011 should be week 2');\n    assert.equal(moment([2011, 0, 14]).week(), 2, 'Jan 14 2011 should be week 2');\n    assert.equal(moment([2011, 0, 15]).week(), 3, 'Jan 15 2011 should be week 3');\n    moment.defineLocale('dow: 6, doy: 12', null);\n});\n\ntest('weeks numbers dow:1 doy:7', function (assert) {\n    moment.locale('dow: 1, doy: 7', {week: {dow: 1, doy: 7}});\n    assert.equal(moment([2011, 11, 26]).week(), 1, 'Dec 26 2011 should be week 1');\n    assert.equal(moment([2012,  0,  1]).week(), 1, 'Jan  1 2012 should be week 1');\n    assert.equal(moment([2012,  0,  2]).week(), 2, 'Jan  2 2012 should be week 2');\n    assert.equal(moment([2012,  0,  8]).week(), 2, 'Jan  8 2012 should be week 2');\n    assert.equal(moment([2012,  0,  9]).week(), 3, 'Jan  9 2012 should be week 3');\n    assert.equal(moment([2007, 0, 1]).week(),  1, 'Jan  1 2007 should be week 1');\n    assert.equal(moment([2007, 0, 7]).week(),  1, 'Jan  7 2007 should be week 1');\n    assert.equal(moment([2007, 0, 8]).week(),  2, 'Jan  8 2007 should be week 2');\n    assert.equal(moment([2007, 0, 14]).week(), 2, 'Jan 14 2007 should be week 2');\n    assert.equal(moment([2007, 0, 15]).week(), 3, 'Jan 15 2007 should be week 3');\n    assert.equal(moment([2007, 11, 31]).week(), 1, 'Dec 31 2007 should be week 1');\n    assert.equal(moment([2008,  0,  1]).week(), 1, 'Jan  1 2008 should be week 1');\n    assert.equal(moment([2008,  0,  6]).week(), 1, 'Jan  6 2008 should be week 1');\n    assert.equal(moment([2008,  0,  7]).week(), 2, 'Jan  7 2008 should be week 2');\n    assert.equal(moment([2008,  0, 13]).week(), 2, 'Jan 13 2008 should be week 2');\n    assert.equal(moment([2008,  0, 14]).week(), 3, 'Jan 14 2008 should be week 3');\n    assert.equal(moment([2002, 11, 30]).week(), 1, 'Dec 30 2002 should be week 1');\n    assert.equal(moment([2003,  0,  1]).week(), 1, 'Jan  1 2003 should be week 1');\n    assert.equal(moment([2003,  0,  5]).week(), 1, 'Jan  5 2003 should be week 1');\n    assert.equal(moment([2003,  0,  6]).week(), 2, 'Jan  6 2003 should be week 2');\n    assert.equal(moment([2003,  0, 12]).week(), 2, 'Jan 12 2003 should be week 2');\n    assert.equal(moment([2003,  0, 13]).week(), 3, 'Jan 13 2003 should be week 3');\n    assert.equal(moment([2008, 11, 29]).week(), 1, 'Dec 29 2008 should be week 1');\n    assert.equal(moment([2009,  0,  1]).week(), 1, 'Jan  1 2009 should be week 1');\n    assert.equal(moment([2009,  0,  4]).week(), 1, 'Jan  4 2009 should be week 1');\n    assert.equal(moment([2009,  0,  5]).week(), 2, 'Jan  5 2009 should be week 2');\n    assert.equal(moment([2009,  0, 11]).week(), 2, 'Jan 11 2009 should be week 2');\n    assert.equal(moment([2009,  0, 12]).week(), 3, 'Jan 12 2009 should be week 3');\n    assert.equal(moment([2009, 11, 28]).week(), 1, 'Dec 28 2009 should be week 1');\n    assert.equal(moment([2010,  0,  1]).week(), 1, 'Jan  1 2010 should be week 1');\n    assert.equal(moment([2010,  0,  3]).week(), 1, 'Jan  3 2010 should be week 1');\n    assert.equal(moment([2010,  0,  4]).week(), 2, 'Jan  4 2010 should be week 2');\n    assert.equal(moment([2010,  0, 10]).week(), 2, 'Jan 10 2010 should be week 2');\n    assert.equal(moment([2010,  0, 11]).week(), 3, 'Jan 11 2010 should be week 3');\n    assert.equal(moment([2010, 11, 27]).week(), 1, 'Dec 27 2010 should be week 1');\n    assert.equal(moment([2011,  0,  1]).week(), 1, 'Jan  1 2011 should be week 1');\n    assert.equal(moment([2011,  0,  2]).week(), 1, 'Jan  2 2011 should be week 1');\n    assert.equal(moment([2011,  0,  3]).week(), 2, 'Jan  3 2011 should be week 2');\n    assert.equal(moment([2011,  0,  9]).week(), 2, 'Jan  9 2011 should be week 2');\n    assert.equal(moment([2011,  0, 10]).week(), 3, 'Jan 10 2011 should be week 3');\n    moment.defineLocale('dow: 1, doy: 7', null);\n});\n\ntest('weeks numbers dow:0 doy:6', function (assert) {\n    moment.locale('dow: 0, doy: 6', {week: {dow: 0, doy: 6}});\n    assert.equal(moment([2012, 0,  1]).week(), 1, 'Jan  1 2012 should be week 1');\n    assert.equal(moment([2012, 0,  7]).week(), 1, 'Jan  7 2012 should be week 1');\n    assert.equal(moment([2012, 0,  8]).week(), 2, 'Jan  8 2012 should be week 2');\n    assert.equal(moment([2012, 0, 14]).week(), 2, 'Jan 14 2012 should be week 2');\n    assert.equal(moment([2012, 0, 15]).week(), 3, 'Jan 15 2012 should be week 3');\n    assert.equal(moment([2006, 11, 31]).week(), 1, 'Dec 31 2006 should be week 1');\n    assert.equal(moment([2007,  0,  1]).week(), 1, 'Jan  1 2007 should be week 1');\n    assert.equal(moment([2007,  0,  6]).week(), 1, 'Jan  6 2007 should be week 1');\n    assert.equal(moment([2007,  0,  7]).week(), 2, 'Jan  7 2007 should be week 2');\n    assert.equal(moment([2007,  0, 13]).week(), 2, 'Jan 13 2007 should be week 2');\n    assert.equal(moment([2007,  0, 14]).week(), 3, 'Jan 14 2007 should be week 3');\n    assert.equal(moment([2007, 11, 29]).week(), 52, 'Dec 29 2007 should be week 52');\n    assert.equal(moment([2008,  0,  1]).week(), 1, 'Jan  1 2008 should be week 1');\n    assert.equal(moment([2008,  0,  5]).week(), 1, 'Jan  5 2008 should be week 1');\n    assert.equal(moment([2008,  0,  6]).week(), 2, 'Jan  6 2008 should be week 2');\n    assert.equal(moment([2008,  0, 12]).week(), 2, 'Jan 12 2008 should be week 2');\n    assert.equal(moment([2008,  0, 13]).week(), 3, 'Jan 13 2008 should be week 3');\n    assert.equal(moment([2002, 11, 29]).week(), 1, 'Dec 29 2002 should be week 1');\n    assert.equal(moment([2003,  0,  1]).week(), 1, 'Jan  1 2003 should be week 1');\n    assert.equal(moment([2003,  0,  4]).week(), 1, 'Jan  4 2003 should be week 1');\n    assert.equal(moment([2003,  0,  5]).week(), 2, 'Jan  5 2003 should be week 2');\n    assert.equal(moment([2003,  0, 11]).week(), 2, 'Jan 11 2003 should be week 2');\n    assert.equal(moment([2003,  0, 12]).week(), 3, 'Jan 12 2003 should be week 3');\n    assert.equal(moment([2008, 11, 28]).week(), 1, 'Dec 28 2008 should be week 1');\n    assert.equal(moment([2009,  0,  1]).week(), 1, 'Jan  1 2009 should be week 1');\n    assert.equal(moment([2009,  0,  3]).week(), 1, 'Jan  3 2009 should be week 1');\n    assert.equal(moment([2009,  0,  4]).week(), 2, 'Jan  4 2009 should be week 2');\n    assert.equal(moment([2009,  0, 10]).week(), 2, 'Jan 10 2009 should be week 2');\n    assert.equal(moment([2009,  0, 11]).week(), 3, 'Jan 11 2009 should be week 3');\n    assert.equal(moment([2009, 11, 27]).week(), 1, 'Dec 27 2009 should be week 1');\n    assert.equal(moment([2010,  0,  1]).week(), 1, 'Jan  1 2010 should be week 1');\n    assert.equal(moment([2010,  0,  2]).week(), 1, 'Jan  2 2010 should be week 1');\n    assert.equal(moment([2010,  0,  3]).week(), 2, 'Jan  3 2010 should be week 2');\n    assert.equal(moment([2010,  0,  9]).week(), 2, 'Jan  9 2010 should be week 2');\n    assert.equal(moment([2010,  0, 10]).week(), 3, 'Jan 10 2010 should be week 3');\n    assert.equal(moment([2010, 11, 26]).week(), 1, 'Dec 26 2010 should be week 1');\n    assert.equal(moment([2011,  0,  1]).week(), 1, 'Jan  1 2011 should be week 1');\n    assert.equal(moment([2011,  0,  2]).week(), 2, 'Jan  2 2011 should be week 2');\n    assert.equal(moment([2011,  0,  8]).week(), 2, 'Jan  8 2011 should be week 2');\n    assert.equal(moment([2011,  0,  9]).week(), 3, 'Jan  9 2011 should be week 3');\n    moment.defineLocale('dow: 0, doy: 6', null);\n});\n\ntest('week year overflows', function (assert) {\n    assert.equal('2005-01-01', moment.utc('2004-W53-6', moment.ISO_8601, true).format('YYYY-MM-DD'), '2004-W53-6 is 1st Jan 2005');\n    assert.equal('2007-12-31', moment.utc('2008-W01-1', moment.ISO_8601, true).format('YYYY-MM-DD'), '2008-W01-1 is 31st Dec 2007');\n});\n\ntest('weeks overflow', function (assert) {\n    assert.equal(7, moment.utc('2004-W54-1', moment.ISO_8601, true).parsingFlags().overflow, '2004 has only 53 weeks');\n    assert.equal(7, moment.utc('2004-W00-1', moment.ISO_8601, true).parsingFlags().overflow, 'there is no 0th week');\n});\n\ntest('weekday overflow', function (assert) {\n    assert.equal(8, moment.utc('2004-W30-0', moment.ISO_8601, true).parsingFlags().overflow, 'there is no 0 iso weekday');\n    assert.equal(8, moment.utc('2004-W30-8', moment.ISO_8601, true).parsingFlags().overflow, 'there is no 8 iso weekday');\n    assert.equal(8, moment.utc('2004-w30-7', 'gggg-[w]ww-e', true).parsingFlags().overflow, 'there is no 7 \\'e\\' weekday');\n    assert.equal(8, moment.utc('2004-w30-7', 'gggg-[w]ww-d', true).parsingFlags().overflow, 'there is no 7 \\'d\\' weekday');\n});\n\ntest('week year setter works', function (assert) {\n    for (var year = 2000; year <= 2020; year += 1) {\n        assert.equal(moment.utc('2012-12-31T00:00:00.000Z').isoWeekYear(year).isoWeekYear(), year, 'setting iso-week-year to ' + year);\n        assert.equal(moment.utc('2012-12-31T00:00:00.000Z').weekYear(year).weekYear(), year, 'setting week-year to ' + year);\n    }\n\n    assert.equal(moment.utc('2004-W53-1', moment.ISO_8601, true).isoWeekYear(2013).format('GGGG-[W]WW-E'), '2013-W52-1', '2004-W53-1 to 2013');\n    assert.equal(moment.utc('2004-W53-1', moment.ISO_8601, true).isoWeekYear(2020).format('GGGG-[W]WW-E'), '2020-W53-1', '2004-W53-1 to 2020');\n    assert.equal(moment.utc('2005-W52-1', moment.ISO_8601, true).isoWeekYear(2004).format('GGGG-[W]WW-E'), '2004-W52-1', '2005-W52-1 to 2004');\n    assert.equal(moment.utc('2013-W30-4', moment.ISO_8601, true).isoWeekYear(2015).format('GGGG-[W]WW-E'), '2015-W30-4', '2013-W30-4 to 2015');\n\n    assert.equal(moment.utc('2005-w53-0', 'gggg-[w]ww-e', true).weekYear(2013).format('gggg-[w]ww-e'), '2013-w52-0', '2005-w53-0 to 2013');\n    assert.equal(moment.utc('2005-w53-0', 'gggg-[w]ww-e', true).weekYear(2016).format('gggg-[w]ww-e'), '2016-w53-0', '2005-w53-0 to 2016');\n    assert.equal(moment.utc('2004-w52-0', 'gggg-[w]ww-e', true).weekYear(2005).format('gggg-[w]ww-e'), '2005-w52-0', '2004-w52-0 to 2005');\n    assert.equal(moment.utc('2013-w30-4', 'gggg-[w]ww-e', true).weekYear(2015).format('gggg-[w]ww-e'), '2015-w30-4', '2013-w30-4 to 2015');\n});\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/test/moment/weekday.js",
    "content": "import { module, test } from '../qunit';\nimport moment from '../../moment';\n\nmodule('week day');\n\ntest('iso weekday', function (assert) {\n    var i;\n\n    for (i = 0; i < 7; ++i) {\n        moment.locale('dow:' + i + ',doy: 6', {week: {dow: i, doy: 6}});\n        assert.equal(moment([1985, 1,  4]).isoWeekday(), 1, 'Feb  4 1985 is Monday    -- 1st day');\n        assert.equal(moment([2029, 8, 18]).isoWeekday(), 2, 'Sep 18 2029 is Tuesday   -- 2nd day');\n        assert.equal(moment([2013, 3, 24]).isoWeekday(), 3, 'Apr 24 2013 is Wednesday -- 3rd day');\n        assert.equal(moment([2015, 2,  5]).isoWeekday(), 4, 'Mar  5 2015 is Thursday  -- 4th day');\n        assert.equal(moment([1970, 0,  2]).isoWeekday(), 5, 'Jan  2 1970 is Friday    -- 5th day');\n        assert.equal(moment([2001, 4, 12]).isoWeekday(), 6, 'May 12 2001 is Saturday  -- 6th day');\n        assert.equal(moment([2000, 0,  2]).isoWeekday(), 7, 'Jan  2 2000 is Sunday    -- 7th day');\n    }\n});\n\ntest('iso weekday setter', function (assert) {\n    var a = moment([2011, 0, 10]);\n    assert.equal(moment(a).isoWeekday(1).date(),  10, 'set from mon to mon');\n    assert.equal(moment(a).isoWeekday(4).date(),  13, 'set from mon to thu');\n    assert.equal(moment(a).isoWeekday(7).date(),  16, 'set from mon to sun');\n    assert.equal(moment(a).isoWeekday(-6).date(),  3, 'set from mon to last mon');\n    assert.equal(moment(a).isoWeekday(-3).date(),  6, 'set from mon to last thu');\n    assert.equal(moment(a).isoWeekday(0).date(),   9, 'set from mon to last sun');\n    assert.equal(moment(a).isoWeekday(8).date(),  17, 'set from mon to next mon');\n    assert.equal(moment(a).isoWeekday(11).date(), 20, 'set from mon to next thu');\n    assert.equal(moment(a).isoWeekday(14).date(), 23, 'set from mon to next sun');\n\n    a = moment([2011, 0, 13]);\n    assert.equal(moment(a).isoWeekday(1).date(), 10, 'set from thu to mon');\n    assert.equal(moment(a).isoWeekday(4).date(), 13, 'set from thu to thu');\n    assert.equal(moment(a).isoWeekday(7).date(), 16, 'set from thu to sun');\n    assert.equal(moment(a).isoWeekday(-6).date(),  3, 'set from thu to last mon');\n    assert.equal(moment(a).isoWeekday(-3).date(),  6, 'set from thu to last thu');\n    assert.equal(moment(a).isoWeekday(0).date(),   9, 'set from thu to last sun');\n    assert.equal(moment(a).isoWeekday(8).date(),  17, 'set from thu to next mon');\n    assert.equal(moment(a).isoWeekday(11).date(), 20, 'set from thu to next thu');\n    assert.equal(moment(a).isoWeekday(14).date(), 23, 'set from thu to next sun');\n\n    a = moment([2011, 0, 16]);\n    assert.equal(moment(a).isoWeekday(1).date(), 10, 'set from sun to mon');\n    assert.equal(moment(a).isoWeekday(4).date(), 13, 'set from sun to thu');\n    assert.equal(moment(a).isoWeekday(7).date(), 16, 'set from sun to sun');\n    assert.equal(moment(a).isoWeekday(-6).date(),  3, 'set from sun to last mon');\n    assert.equal(moment(a).isoWeekday(-3).date(),  6, 'set from sun to last thu');\n    assert.equal(moment(a).isoWeekday(0).date(),   9, 'set from sun to last sun');\n    assert.equal(moment(a).isoWeekday(8).date(),  17, 'set from sun to next mon');\n    assert.equal(moment(a).isoWeekday(11).date(), 20, 'set from sun to next thu');\n    assert.equal(moment(a).isoWeekday(14).date(), 23, 'set from sun to next sun');\n});\n\ntest('iso weekday setter with day name', function (assert) {\n    moment.locale('en');\n\n    var a = moment([2011, 0, 10]);\n    assert.equal(moment(a).isoWeekday('Monday').date(),   10, 'set from mon to mon');\n    assert.equal(moment(a).isoWeekday('Thursday').date(), 13, 'set from mon to thu');\n    assert.equal(moment(a).isoWeekday('Sunday').date(),   16, 'set from mon to sun');\n\n    a = moment([2011, 0, 13]);\n    assert.equal(moment(a).isoWeekday('Monday').date(),   10, 'set from thu to mon');\n    assert.equal(moment(a).isoWeekday('Thursday').date(), 13, 'set from thu to thu');\n    assert.equal(moment(a).isoWeekday('Sunday').date(),   16, 'set from thu to sun');\n\n    a = moment([2011, 0, 16]);\n    assert.equal(moment(a).isoWeekday('Monday').date(),   10, 'set from sun to mon');\n    assert.equal(moment(a).isoWeekday('Thursday').date(), 13, 'set from sun to thu');\n    assert.equal(moment(a).isoWeekday('Sunday').date(),   16, 'set from sun to sun');\n});\n\ntest('weekday first day of week Sunday (dow 0)', function (assert) {\n    moment.locale('dow: 0,doy: 6', {week: {dow: 0, doy: 6}});\n    assert.equal(moment([1985, 1,  3]).weekday(), 0, 'Feb  3 1985 is Sunday    -- 0th day');\n    assert.equal(moment([2029, 8, 17]).weekday(), 1, 'Sep 17 2029 is Monday    -- 1st day');\n    assert.equal(moment([2013, 3, 23]).weekday(), 2, 'Apr 23 2013 is Tuesday   -- 2nd day');\n    assert.equal(moment([2015, 2,  4]).weekday(), 3, 'Mar  4 2015 is Wednesday -- 3nd day');\n    assert.equal(moment([1970, 0,  1]).weekday(), 4, 'Jan  1 1970 is Thursday  -- 4th day');\n    assert.equal(moment([2001, 4, 11]).weekday(), 5, 'May 11 2001 is Friday    -- 5th day');\n    assert.equal(moment([2000, 0,  1]).weekday(), 6, 'Jan  1 2000 is Saturday  -- 6th day');\n});\n\ntest('weekday first day of week Monday (dow 1)', function (assert) {\n    moment.locale('dow: 1,doy: 6', {week: {dow: 1, doy: 6}});\n    assert.equal(moment([1985, 1,  4]).weekday(), 0, 'Feb  4 1985 is Monday    -- 0th day');\n    assert.equal(moment([2029, 8, 18]).weekday(), 1, 'Sep 18 2029 is Tuesday   -- 1st day');\n    assert.equal(moment([2013, 3, 24]).weekday(), 2, 'Apr 24 2013 is Wednesday -- 2nd day');\n    assert.equal(moment([2015, 2,  5]).weekday(), 3, 'Mar  5 2015 is Thursday  -- 3nd day');\n    assert.equal(moment([1970, 0,  2]).weekday(), 4, 'Jan  2 1970 is Friday    -- 4th day');\n    assert.equal(moment([2001, 4, 12]).weekday(), 5, 'May 12 2001 is Saturday  -- 5th day');\n    assert.equal(moment([2000, 0,  2]).weekday(), 6, 'Jan  2 2000 is Sunday    -- 6th day');\n});\n\ntest('weekday first day of week Tuesday (dow 2)', function (assert) {\n    moment.locale('dow: 2,doy: 6', {week: {dow: 2, doy: 6}});\n    assert.equal(moment([1985, 1,  5]).weekday(), 0, 'Feb  5 1985 is Tuesday   -- 0th day');\n    assert.equal(moment([2029, 8, 19]).weekday(), 1, 'Sep 19 2029 is Wednesday -- 1st day');\n    assert.equal(moment([2013, 3, 25]).weekday(), 2, 'Apr 25 2013 is Thursday  -- 2nd day');\n    assert.equal(moment([2015, 2,  6]).weekday(), 3, 'Mar  6 2015 is Friday    -- 3nd day');\n    assert.equal(moment([1970, 0,  3]).weekday(), 4, 'Jan  3 1970 is Staturday -- 4th day');\n    assert.equal(moment([2001, 4, 13]).weekday(), 5, 'May 13 2001 is Sunday    -- 5th day');\n    assert.equal(moment([2000, 0,  3]).weekday(), 6, 'Jan  3 2000 is Monday    -- 6th day');\n});\n\ntest('weekday first day of week Wednesday (dow 3)', function (assert) {\n    moment.locale('dow: 3,doy: 6', {week: {dow: 3, doy: 6}});\n    assert.equal(moment([1985, 1,  6]).weekday(), 0, 'Feb  6 1985 is Wednesday -- 0th day');\n    assert.equal(moment([2029, 8, 20]).weekday(), 1, 'Sep 20 2029 is Thursday  -- 1st day');\n    assert.equal(moment([2013, 3, 26]).weekday(), 2, 'Apr 26 2013 is Friday    -- 2nd day');\n    assert.equal(moment([2015, 2,  7]).weekday(), 3, 'Mar  7 2015 is Saturday  -- 3nd day');\n    assert.equal(moment([1970, 0,  4]).weekday(), 4, 'Jan  4 1970 is Sunday    -- 4th day');\n    assert.equal(moment([2001, 4, 14]).weekday(), 5, 'May 14 2001 is Monday    -- 5th day');\n    assert.equal(moment([2000, 0,  4]).weekday(), 6, 'Jan  4 2000 is Tuesday   -- 6th day');\n    moment.locale('dow:3,doy:6', null);\n});\n\ntest('weekday first day of week Thursday (dow 4)', function (assert) {\n    moment.locale('dow: 4,doy: 6', {week: {dow: 4, doy: 6}});\n    assert.equal(moment([1985, 1,  7]).weekday(), 0, 'Feb  7 1985 is Thursday  -- 0th day');\n    assert.equal(moment([2029, 8, 21]).weekday(), 1, 'Sep 21 2029 is Friday    -- 1st day');\n    assert.equal(moment([2013, 3, 27]).weekday(), 2, 'Apr 27 2013 is Saturday  -- 2nd day');\n    assert.equal(moment([2015, 2,  8]).weekday(), 3, 'Mar  8 2015 is Sunday    -- 3nd day');\n    assert.equal(moment([1970, 0,  5]).weekday(), 4, 'Jan  5 1970 is Monday    -- 4th day');\n    assert.equal(moment([2001, 4, 15]).weekday(), 5, 'May 15 2001 is Tuesday   -- 5th day');\n    assert.equal(moment([2000, 0,  5]).weekday(), 6, 'Jan  5 2000 is Wednesday -- 6th day');\n});\n\ntest('weekday first day of week Friday (dow 5)', function (assert) {\n    moment.locale('dow: 5,doy: 6', {week: {dow: 5, doy: 6}});\n    assert.equal(moment([1985, 1,  8]).weekday(), 0, 'Feb  8 1985 is Friday    -- 0th day');\n    assert.equal(moment([2029, 8, 22]).weekday(), 1, 'Sep 22 2029 is Staturday -- 1st day');\n    assert.equal(moment([2013, 3, 28]).weekday(), 2, 'Apr 28 2013 is Sunday    -- 2nd day');\n    assert.equal(moment([2015, 2,  9]).weekday(), 3, 'Mar  9 2015 is Monday    -- 3nd day');\n    assert.equal(moment([1970, 0,  6]).weekday(), 4, 'Jan  6 1970 is Tuesday   -- 4th day');\n    assert.equal(moment([2001, 4, 16]).weekday(), 5, 'May 16 2001 is Wednesday -- 5th day');\n    assert.equal(moment([2000, 0,  6]).weekday(), 6, 'Jan  6 2000 is Thursday  -- 6th day');\n});\n\ntest('weekday first day of week Saturday (dow 6)', function (assert) {\n    moment.locale('dow: 6,doy: 6', {week: {dow: 6, doy: 6}});\n    assert.equal(moment([1985, 1,  9]).weekday(), 0, 'Feb  9 1985 is Staturday -- 0th day');\n    assert.equal(moment([2029, 8, 23]).weekday(), 1, 'Sep 23 2029 is Sunday    -- 1st day');\n    assert.equal(moment([2013, 3, 29]).weekday(), 2, 'Apr 29 2013 is Monday    -- 2nd day');\n    assert.equal(moment([2015, 2, 10]).weekday(), 3, 'Mar 10 2015 is Tuesday   -- 3nd day');\n    assert.equal(moment([1970, 0,  7]).weekday(), 4, 'Jan  7 1970 is Wednesday -- 4th day');\n    assert.equal(moment([2001, 4, 17]).weekday(), 5, 'May 17 2001 is Thursday  -- 5th day');\n    assert.equal(moment([2000, 0,  7]).weekday(), 6, 'Jan  7 2000 is Friday    -- 6th day');\n});\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/test/moment/weeks.js",
    "content": "import { module, test } from '../qunit';\nimport moment from '../../moment';\n\nmodule('weeks');\n\ntest('day of year', function (assert) {\n    assert.equal(moment([2000,  0,  1]).dayOfYear(),   1, 'Jan  1 2000 should be day 1 of the year');\n    assert.equal(moment([2000,  1, 28]).dayOfYear(),  59, 'Feb 28 2000 should be day 59 of the year');\n    assert.equal(moment([2000,  1, 29]).dayOfYear(),  60, 'Feb 28 2000 should be day 60 of the year');\n    assert.equal(moment([2000, 11, 31]).dayOfYear(), 366, 'Dec 31 2000 should be day 366 of the year');\n    assert.equal(moment([2001,  0,  1]).dayOfYear(),   1, 'Jan  1 2001 should be day 1 of the year');\n    assert.equal(moment([2001,  1, 28]).dayOfYear(),  59, 'Feb 28 2001 should be day 59 of the year');\n    assert.equal(moment([2001,  2,  1]).dayOfYear(),  60, 'Mar  1 2001 should be day 60 of the year');\n    assert.equal(moment([2001, 11, 31]).dayOfYear(), 365, 'Dec 31 2001 should be day 365 of the year');\n});\n\ntest('day of year setters', function (assert) {\n    assert.equal(moment([2000,  0,  1]).dayOfYear(200).dayOfYear(), 200, 'Setting Jan  1 2000 day of the year to 200 should work');\n    assert.equal(moment([2000,  1, 28]).dayOfYear(200).dayOfYear(), 200, 'Setting Feb 28 2000 day of the year to 200 should work');\n    assert.equal(moment([2000,  1, 29]).dayOfYear(200).dayOfYear(), 200, 'Setting Feb 28 2000 day of the year to 200 should work');\n    assert.equal(moment([2000, 11, 31]).dayOfYear(200).dayOfYear(), 200, 'Setting Dec 31 2000 day of the year to 200 should work');\n    assert.equal(moment().dayOfYear(1).dayOfYear(),   1, 'Setting day of the year to 1 should work');\n    assert.equal(moment().dayOfYear(59).dayOfYear(),  59, 'Setting day of the year to 59 should work');\n    assert.equal(moment().dayOfYear(60).dayOfYear(),  60, 'Setting day of the year to 60 should work');\n    assert.equal(moment().dayOfYear(365).dayOfYear(), 365, 'Setting day of the year to 365 should work');\n});\n\ntest('iso weeks year starting sunday', function (assert) {\n    assert.equal(moment([2012, 0, 1]).isoWeek(), 52, 'Jan  1 2012 should be iso week 52');\n    assert.equal(moment([2012, 0, 2]).isoWeek(),  1, 'Jan  2 2012 should be iso week 1');\n    assert.equal(moment([2012, 0, 8]).isoWeek(),  1, 'Jan  8 2012 should be iso week 1');\n    assert.equal(moment([2012, 0, 9]).isoWeek(),  2, 'Jan  9 2012 should be iso week 2');\n    assert.equal(moment([2012, 0, 15]).isoWeek(), 2, 'Jan 15 2012 should be iso week 2');\n});\n\ntest('iso weeks year starting monday', function (assert) {\n    assert.equal(moment([2007, 0, 1]).isoWeek(),  1, 'Jan  1 2007 should be iso week 1');\n    assert.equal(moment([2007, 0, 7]).isoWeek(),  1, 'Jan  7 2007 should be iso week 1');\n    assert.equal(moment([2007, 0, 8]).isoWeek(),  2, 'Jan  8 2007 should be iso week 2');\n    assert.equal(moment([2007, 0, 14]).isoWeek(), 2, 'Jan 14 2007 should be iso week 2');\n    assert.equal(moment([2007, 0, 15]).isoWeek(), 3, 'Jan 15 2007 should be iso week 3');\n});\n\ntest('iso weeks year starting tuesday', function (assert) {\n    assert.equal(moment([2007, 11, 31]).isoWeek(), 1, 'Dec 31 2007 should be iso week 1');\n    assert.equal(moment([2008,  0,  1]).isoWeek(), 1, 'Jan  1 2008 should be iso week 1');\n    assert.equal(moment([2008,  0,  6]).isoWeek(), 1, 'Jan  6 2008 should be iso week 1');\n    assert.equal(moment([2008,  0,  7]).isoWeek(), 2, 'Jan  7 2008 should be iso week 2');\n    assert.equal(moment([2008,  0, 13]).isoWeek(), 2, 'Jan 13 2008 should be iso week 2');\n    assert.equal(moment([2008,  0, 14]).isoWeek(), 3, 'Jan 14 2008 should be iso week 3');\n});\n\ntest('iso weeks year starting wednesday', function (assert) {\n    assert.equal(moment([2002, 11, 30]).isoWeek(), 1, 'Dec 30 2002 should be iso week 1');\n    assert.equal(moment([2003,  0,  1]).isoWeek(), 1, 'Jan  1 2003 should be iso week 1');\n    assert.equal(moment([2003,  0,  5]).isoWeek(), 1, 'Jan  5 2003 should be iso week 1');\n    assert.equal(moment([2003,  0,  6]).isoWeek(), 2, 'Jan  6 2003 should be iso week 2');\n    assert.equal(moment([2003,  0, 12]).isoWeek(), 2, 'Jan 12 2003 should be iso week 2');\n    assert.equal(moment([2003,  0, 13]).isoWeek(), 3, 'Jan 13 2003 should be iso week 3');\n});\n\ntest('iso weeks year starting thursday', function (assert) {\n    assert.equal(moment([2008, 11, 29]).isoWeek(), 1, 'Dec 29 2008 should be iso week 1');\n    assert.equal(moment([2009,  0,  1]).isoWeek(), 1, 'Jan  1 2009 should be iso week 1');\n    assert.equal(moment([2009,  0,  4]).isoWeek(), 1, 'Jan  4 2009 should be iso week 1');\n    assert.equal(moment([2009,  0,  5]).isoWeek(), 2, 'Jan  5 2009 should be iso week 2');\n    assert.equal(moment([2009,  0, 11]).isoWeek(), 2, 'Jan 11 2009 should be iso week 2');\n    assert.equal(moment([2009,  0, 13]).isoWeek(), 3, 'Jan 12 2009 should be iso week 3');\n});\n\ntest('iso weeks year starting friday', function (assert) {\n    assert.equal(moment([2009, 11, 28]).isoWeek(), 53, 'Dec 28 2009 should be iso week 53');\n    assert.equal(moment([2010,  0,  1]).isoWeek(), 53, 'Jan  1 2010 should be iso week 53');\n    assert.equal(moment([2010,  0,  3]).isoWeek(), 53, 'Jan  3 2010 should be iso week 53');\n    assert.equal(moment([2010,  0,  4]).isoWeek(),  1, 'Jan  4 2010 should be iso week 1');\n    assert.equal(moment([2010,  0, 10]).isoWeek(),  1, 'Jan 10 2010 should be iso week 1');\n    assert.equal(moment([2010,  0, 11]).isoWeek(),  2, 'Jan 11 2010 should be iso week 2');\n});\n\ntest('iso weeks year starting saturday', function (assert) {\n    assert.equal(moment([2010, 11, 27]).isoWeek(), 52, 'Dec 27 2010 should be iso week 52');\n    assert.equal(moment([2011,  0,  1]).isoWeek(), 52, 'Jan  1 2011 should be iso week 52');\n    assert.equal(moment([2011,  0,  2]).isoWeek(), 52, 'Jan  2 2011 should be iso week 52');\n    assert.equal(moment([2011,  0,  3]).isoWeek(),  1, 'Jan  3 2011 should be iso week 1');\n    assert.equal(moment([2011,  0,  9]).isoWeek(),  1, 'Jan  9 2011 should be iso week 1');\n    assert.equal(moment([2011,  0, 10]).isoWeek(),  2, 'Jan 10 2011 should be iso week 2');\n});\n\ntest('iso weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2012, 0,  1]).format('W WW Wo'), '52 52 52nd', 'Jan  1 2012 should be iso week 52');\n    assert.equal(moment([2012, 0,  2]).format('W WW Wo'),   '1 01 1st', 'Jan  2 2012 should be iso week 1');\n    assert.equal(moment([2012, 0,  8]).format('W WW Wo'),   '1 01 1st', 'Jan  8 2012 should be iso week 1');\n    assert.equal(moment([2012, 0,  9]).format('W WW Wo'),   '2 02 2nd', 'Jan  9 2012 should be iso week 2');\n    assert.equal(moment([2012, 0, 15]).format('W WW Wo'),   '2 02 2nd', 'Jan 15 2012 should be iso week 2');\n});\n\ntest('weeks plural year starting sunday', function (assert) {\n    assert.equal(moment([2012, 0,  1]).weeks(), 1, 'Jan  1 2012 should be week 1');\n    assert.equal(moment([2012, 0,  7]).weeks(), 1, 'Jan  7 2012 should be week 1');\n    assert.equal(moment([2012, 0,  8]).weeks(), 2, 'Jan  8 2012 should be week 2');\n    assert.equal(moment([2012, 0, 14]).weeks(), 2, 'Jan 14 2012 should be week 2');\n    assert.equal(moment([2012, 0, 15]).weeks(), 3, 'Jan 15 2012 should be week 3');\n});\n\ntest('iso weeks plural year starting sunday', function (assert) {\n    assert.equal(moment([2012, 0, 1]).isoWeeks(), 52, 'Jan  1 2012 should be iso week 52');\n    assert.equal(moment([2012, 0, 2]).isoWeeks(),  1, 'Jan  2 2012 should be iso week 1');\n    assert.equal(moment([2012, 0, 8]).isoWeeks(),  1, 'Jan  8 2012 should be iso week 1');\n    assert.equal(moment([2012, 0, 9]).isoWeeks(),  2, 'Jan  9 2012 should be iso week 2');\n    assert.equal(moment([2012, 0, 15]).isoWeeks(), 2, 'Jan 15 2012 should be iso week 2');\n});\n\ntest('weeks setter', function (assert) {\n    assert.equal(moment([2012, 0,  1]).week(30).week(), 30, 'Setting Jan 1 2012 to week 30 should work');\n    assert.equal(moment([2012, 0,  7]).week(30).week(), 30, 'Setting Jan 7 2012 to week 30 should work');\n    assert.equal(moment([2012, 0,  8]).week(30).week(), 30, 'Setting Jan 8 2012 to week 30 should work');\n    assert.equal(moment([2012, 0, 14]).week(30).week(), 30, 'Setting Jan 14 2012 to week 30 should work');\n    assert.equal(moment([2012, 0, 15]).week(30).week(), 30, 'Setting Jan 15 2012 to week 30 should work');\n});\n\ntest('iso weeks setter', function (assert) {\n    assert.equal(moment([2012, 0,  1]).isoWeeks(25).isoWeeks(), 25, 'Setting Jan  1 2012 to week 25 should work');\n    assert.equal(moment([2012, 0,  2]).isoWeeks(24).isoWeeks(), 24, 'Setting Jan  2 2012 to week 24 should work');\n    assert.equal(moment([2012, 0,  8]).isoWeeks(23).isoWeeks(), 23, 'Setting Jan  8 2012 to week 23 should work');\n    assert.equal(moment([2012, 0,  9]).isoWeeks(22).isoWeeks(), 22, 'Setting Jan  9 2012 to week 22 should work');\n    assert.equal(moment([2012, 0, 15]).isoWeeks(21).isoWeeks(), 21, 'Setting Jan 15 2012 to week 21 should work');\n});\n\ntest('iso weeks setter day of year', function (assert) {\n    assert.equal(moment([2012, 0,  1]).isoWeek(1).dayOfYear(), 9, 'Setting Jan  1 2012 to week 1 should be day of year 8');\n    assert.equal(moment([2012, 0,  1]).isoWeek(1).year(),   2011, 'Setting Jan  1 2012 to week 1 should be year 2011');\n    assert.equal(moment([2012, 0,  2]).isoWeek(1).dayOfYear(), 2, 'Setting Jan  2 2012 to week 1 should be day of year 2');\n    assert.equal(moment([2012, 0,  8]).isoWeek(1).dayOfYear(), 8, 'Setting Jan  8 2012 to week 1 should be day of year 8');\n    assert.equal(moment([2012, 0,  9]).isoWeek(1).dayOfYear(), 2, 'Setting Jan  9 2012 to week 1 should be day of year 2');\n    assert.equal(moment([2012, 0, 15]).isoWeek(1).dayOfYear(), 8, 'Setting Jan 15 2012 to week 1 should be day of year 8');\n});\n\ntest('years with iso week 53', function (assert) {\n    // Based on a table taken from https://en.wikipedia.org/wiki/ISO_week_date\n    // (as downloaded on 2014-01-06) listing the 71 years in a 400-year cycle\n    // that have 53 weeks; in this case reflecting the 2000 based cycle\n    assert.equal(moment([2004, 11, 31]).isoWeek(), 53, 'Dec 31 2004 should be iso week 53');\n    assert.equal(moment([2009, 11, 31]).isoWeek(), 53, 'Dec 31 2009 should be iso week 53');\n    assert.equal(moment([2015, 11, 31]).isoWeek(), 53, 'Dec 31 2015 should be iso week 53');\n    assert.equal(moment([2020, 11, 31]).isoWeek(), 53, 'Dec 31 2020 should be iso week 53');\n    assert.equal(moment([2026, 11, 31]).isoWeek(), 53, 'Dec 31 2026 should be iso week 53');\n    assert.equal(moment([2032, 11, 31]).isoWeek(), 53, 'Dec 31 2032 should be iso week 53');\n    assert.equal(moment([2037, 11, 31]).isoWeek(), 53, 'Dec 31 2037 should be iso week 53');\n    assert.equal(moment([2043, 11, 31]).isoWeek(), 53, 'Dec 31 2043 should be iso week 53');\n    assert.equal(moment([2048, 11, 31]).isoWeek(), 53, 'Dec 31 2048 should be iso week 53');\n    assert.equal(moment([2054, 11, 31]).isoWeek(), 53, 'Dec 31 2054 should be iso week 53');\n    assert.equal(moment([2060, 11, 31]).isoWeek(), 53, 'Dec 31 2060 should be iso week 53');\n    assert.equal(moment([2065, 11, 31]).isoWeek(), 53, 'Dec 31 2065 should be iso week 53');\n    assert.equal(moment([2071, 11, 31]).isoWeek(), 53, 'Dec 31 2071 should be iso week 53');\n    assert.equal(moment([2076, 11, 31]).isoWeek(), 53, 'Dec 31 2076 should be iso week 53');\n    assert.equal(moment([2082, 11, 31]).isoWeek(), 53, 'Dec 31 2082 should be iso week 53');\n    assert.equal(moment([2088, 11, 31]).isoWeek(), 53, 'Dec 31 2088 should be iso week 53');\n    assert.equal(moment([2093, 11, 31]).isoWeek(), 53, 'Dec 31 2093 should be iso week 53');\n    assert.equal(moment([2099, 11, 31]).isoWeek(), 53, 'Dec 31 2099 should be iso week 53');\n    assert.equal(moment([2105, 11, 31]).isoWeek(), 53, 'Dec 31 2105 should be iso week 53');\n    assert.equal(moment([2111, 11, 31]).isoWeek(), 53, 'Dec 31 2111 should be iso week 53');\n    assert.equal(moment([2116, 11, 31]).isoWeek(), 53, 'Dec 31 2116 should be iso week 53');\n    assert.equal(moment([2122, 11, 31]).isoWeek(), 53, 'Dec 31 2122 should be iso week 53');\n    assert.equal(moment([2128, 11, 31]).isoWeek(), 53, 'Dec 31 2128 should be iso week 53');\n    assert.equal(moment([2133, 11, 31]).isoWeek(), 53, 'Dec 31 2133 should be iso week 53');\n    assert.equal(moment([2139, 11, 31]).isoWeek(), 53, 'Dec 31 2139 should be iso week 53');\n    assert.equal(moment([2144, 11, 31]).isoWeek(), 53, 'Dec 31 2144 should be iso week 53');\n    assert.equal(moment([2150, 11, 31]).isoWeek(), 53, 'Dec 31 2150 should be iso week 53');\n    assert.equal(moment([2156, 11, 31]).isoWeek(), 53, 'Dec 31 2156 should be iso week 53');\n    assert.equal(moment([2161, 11, 31]).isoWeek(), 53, 'Dec 31 2161 should be iso week 53');\n    assert.equal(moment([2167, 11, 31]).isoWeek(), 53, 'Dec 31 2167 should be iso week 53');\n    assert.equal(moment([2172, 11, 31]).isoWeek(), 53, 'Dec 31 2172 should be iso week 53');\n    assert.equal(moment([2178, 11, 31]).isoWeek(), 53, 'Dec 31 2178 should be iso week 53');\n    assert.equal(moment([2184, 11, 31]).isoWeek(), 53, 'Dec 31 2184 should be iso week 53');\n    assert.equal(moment([2189, 11, 31]).isoWeek(), 53, 'Dec 31 2189 should be iso week 53');\n    assert.equal(moment([2195, 11, 31]).isoWeek(), 53, 'Dec 31 2195 should be iso week 53');\n    assert.equal(moment([2201, 11, 31]).isoWeek(), 53, 'Dec 31 2201 should be iso week 53');\n    assert.equal(moment([2207, 11, 31]).isoWeek(), 53, 'Dec 31 2207 should be iso week 53');\n    assert.equal(moment([2212, 11, 31]).isoWeek(), 53, 'Dec 31 2212 should be iso week 53');\n    assert.equal(moment([2218, 11, 31]).isoWeek(), 53, 'Dec 31 2218 should be iso week 53');\n    assert.equal(moment([2224, 11, 31]).isoWeek(), 53, 'Dec 31 2224 should be iso week 53');\n    assert.equal(moment([2229, 11, 31]).isoWeek(), 53, 'Dec 31 2229 should be iso week 53');\n    assert.equal(moment([2235, 11, 31]).isoWeek(), 53, 'Dec 31 2235 should be iso week 53');\n    assert.equal(moment([2240, 11, 31]).isoWeek(), 53, 'Dec 31 2240 should be iso week 53');\n    assert.equal(moment([2246, 11, 31]).isoWeek(), 53, 'Dec 31 2246 should be iso week 53');\n    assert.equal(moment([2252, 11, 31]).isoWeek(), 53, 'Dec 31 2252 should be iso week 53');\n    assert.equal(moment([2257, 11, 31]).isoWeek(), 53, 'Dec 31 2257 should be iso week 53');\n    assert.equal(moment([2263, 11, 31]).isoWeek(), 53, 'Dec 31 2263 should be iso week 53');\n    assert.equal(moment([2268, 11, 31]).isoWeek(), 53, 'Dec 31 2268 should be iso week 53');\n    assert.equal(moment([2274, 11, 31]).isoWeek(), 53, 'Dec 31 2274 should be iso week 53');\n    assert.equal(moment([2280, 11, 31]).isoWeek(), 53, 'Dec 31 2280 should be iso week 53');\n    assert.equal(moment([2285, 11, 31]).isoWeek(), 53, 'Dec 31 2285 should be iso week 53');\n    assert.equal(moment([2291, 11, 31]).isoWeek(), 53, 'Dec 31 2291 should be iso week 53');\n    assert.equal(moment([2296, 11, 31]).isoWeek(), 53, 'Dec 31 2296 should be iso week 53');\n    assert.equal(moment([2303, 11, 31]).isoWeek(), 53, 'Dec 31 2303 should be iso week 53');\n    assert.equal(moment([2308, 11, 31]).isoWeek(), 53, 'Dec 31 2308 should be iso week 53');\n    assert.equal(moment([2314, 11, 31]).isoWeek(), 53, 'Dec 31 2314 should be iso week 53');\n    assert.equal(moment([2320, 11, 31]).isoWeek(), 53, 'Dec 31 2320 should be iso week 53');\n    assert.equal(moment([2325, 11, 31]).isoWeek(), 53, 'Dec 31 2325 should be iso week 53');\n    assert.equal(moment([2331, 11, 31]).isoWeek(), 53, 'Dec 31 2331 should be iso week 53');\n    assert.equal(moment([2336, 11, 31]).isoWeek(), 53, 'Dec 31 2336 should be iso week 53');\n    assert.equal(moment([2342, 11, 31]).isoWeek(), 53, 'Dec 31 2342 should be iso week 53');\n    assert.equal(moment([2348, 11, 31]).isoWeek(), 53, 'Dec 31 2348 should be iso week 53');\n    assert.equal(moment([2353, 11, 31]).isoWeek(), 53, 'Dec 31 2353 should be iso week 53');\n    assert.equal(moment([2359, 11, 31]).isoWeek(), 53, 'Dec 31 2359 should be iso week 53');\n    assert.equal(moment([2364, 11, 31]).isoWeek(), 53, 'Dec 31 2364 should be iso week 53');\n    assert.equal(moment([2370, 11, 31]).isoWeek(), 53, 'Dec 31 2370 should be iso week 53');\n    assert.equal(moment([2376, 11, 31]).isoWeek(), 53, 'Dec 31 2376 should be iso week 53');\n    assert.equal(moment([2381, 11, 31]).isoWeek(), 53, 'Dec 31 2381 should be iso week 53');\n    assert.equal(moment([2387, 11, 31]).isoWeek(), 53, 'Dec 31 2387 should be iso week 53');\n    assert.equal(moment([2392, 11, 31]).isoWeek(), 53, 'Dec 31 2392 should be iso week 53');\n    assert.equal(moment([2398, 11, 31]).isoWeek(), 53, 'Dec 31 2398 should be iso week 53');\n});\n\ntest('count years with iso week 53', function (assert) {\n    // Based on https://en.wikipedia.org/wiki/ISO_week_date (as seen on 2014-01-06)\n    // stating that there are 71 years in a 400-year cycle that have 53 weeks;\n    // in this case reflecting the 2000 based cycle\n    var count = 0, i;\n    for (i = 0; i < 400; i++) {\n        count += (moment([2000 + i, 11, 31]).isoWeek() === 53) ? 1 : 0;\n    }\n    assert.equal(count, 71, 'Should have 71 years in 400-year cycle with iso week 53');\n});\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/test/moment/weeks_in_year.js",
    "content": "import { module, test } from '../qunit';\nimport moment from '../../moment';\n\nmodule('weeks in year');\n\ntest('isoWeeksInYear', function (assert) {\n    assert.equal(moment([2004]).isoWeeksInYear(), 53, '2004 has 53 iso weeks');\n    assert.equal(moment([2005]).isoWeeksInYear(), 52, '2005 has 53 iso weeks');\n    assert.equal(moment([2006]).isoWeeksInYear(), 52, '2006 has 53 iso weeks');\n    assert.equal(moment([2007]).isoWeeksInYear(), 52, '2007 has 52 iso weeks');\n    assert.equal(moment([2008]).isoWeeksInYear(), 52, '2008 has 53 iso weeks');\n    assert.equal(moment([2009]).isoWeeksInYear(), 53, '2009 has 53 iso weeks');\n    assert.equal(moment([2010]).isoWeeksInYear(), 52, '2010 has 52 iso weeks');\n    assert.equal(moment([2011]).isoWeeksInYear(), 52, '2011 has 52 iso weeks');\n    assert.equal(moment([2012]).isoWeeksInYear(), 52, '2012 has 52 iso weeks');\n    assert.equal(moment([2013]).isoWeeksInYear(), 52, '2013 has 52 iso weeks');\n    assert.equal(moment([2014]).isoWeeksInYear(), 52, '2014 has 52 iso weeks');\n    assert.equal(moment([2015]).isoWeeksInYear(), 53, '2015 has 53 iso weeks');\n});\n\ntest('weeksInYear doy/dow = 1/4', function (assert) {\n    moment.locale('1/4', {week: {dow: 1, doy: 4}});\n\n    assert.equal(moment([2004]).weeksInYear(), 53, '2004 has 53 weeks');\n    assert.equal(moment([2005]).weeksInYear(), 52, '2005 has 53 weeks');\n    assert.equal(moment([2006]).weeksInYear(), 52, '2006 has 53 weeks');\n    assert.equal(moment([2007]).weeksInYear(), 52, '2007 has 52 weeks');\n    assert.equal(moment([2008]).weeksInYear(), 52, '2008 has 53 weeks');\n    assert.equal(moment([2009]).weeksInYear(), 53, '2009 has 53 weeks');\n    assert.equal(moment([2010]).weeksInYear(), 52, '2010 has 52 weeks');\n    assert.equal(moment([2011]).weeksInYear(), 52, '2011 has 52 weeks');\n    assert.equal(moment([2012]).weeksInYear(), 52, '2012 has 52 weeks');\n    assert.equal(moment([2013]).weeksInYear(), 52, '2013 has 52 weeks');\n    assert.equal(moment([2014]).weeksInYear(), 52, '2014 has 52 weeks');\n    assert.equal(moment([2015]).weeksInYear(), 53, '2015 has 53 weeks');\n});\n\ntest('weeksInYear doy/dow = 6/12', function (assert) {\n    moment.locale('6/12', {week: {dow: 6, doy: 12}});\n\n    assert.equal(moment([2004]).weeksInYear(), 53, '2004 has 53 weeks');\n    assert.equal(moment([2005]).weeksInYear(), 52, '2005 has 53 weeks');\n    assert.equal(moment([2006]).weeksInYear(), 52, '2006 has 53 weeks');\n    assert.equal(moment([2007]).weeksInYear(), 52, '2007 has 52 weeks');\n    assert.equal(moment([2008]).weeksInYear(), 52, '2008 has 53 weeks');\n    assert.equal(moment([2009]).weeksInYear(), 52, '2009 has 53 weeks');\n    assert.equal(moment([2010]).weeksInYear(), 53, '2010 has 52 weeks');\n    assert.equal(moment([2011]).weeksInYear(), 52, '2011 has 52 weeks');\n    assert.equal(moment([2012]).weeksInYear(), 52, '2012 has 52 weeks');\n    assert.equal(moment([2013]).weeksInYear(), 52, '2013 has 52 weeks');\n    assert.equal(moment([2014]).weeksInYear(), 52, '2014 has 52 weeks');\n    assert.equal(moment([2015]).weeksInYear(), 52, '2015 has 53 weeks');\n});\n\ntest('weeksInYear doy/dow = 1/7', function (assert) {\n    moment.locale('1/7', {week: {dow: 1, doy: 7}});\n\n    assert.equal(moment([2004]).weeksInYear(), 52, '2004 has 53 weeks');\n    assert.equal(moment([2005]).weeksInYear(), 52, '2005 has 53 weeks');\n    assert.equal(moment([2006]).weeksInYear(), 53, '2006 has 53 weeks');\n    assert.equal(moment([2007]).weeksInYear(), 52, '2007 has 52 weeks');\n    assert.equal(moment([2008]).weeksInYear(), 52, '2008 has 53 weeks');\n    assert.equal(moment([2009]).weeksInYear(), 52, '2009 has 53 weeks');\n    assert.equal(moment([2010]).weeksInYear(), 52, '2010 has 52 weeks');\n    assert.equal(moment([2011]).weeksInYear(), 52, '2011 has 52 weeks');\n    assert.equal(moment([2012]).weeksInYear(), 53, '2012 has 52 weeks');\n    assert.equal(moment([2013]).weeksInYear(), 52, '2013 has 52 weeks');\n    assert.equal(moment([2014]).weeksInYear(), 52, '2014 has 52 weeks');\n    assert.equal(moment([2015]).weeksInYear(), 52, '2015 has 53 weeks');\n});\n\ntest('weeksInYear doy/dow = 0/6', function (assert) {\n    moment.locale('0/6', {week: {dow: 0, doy: 6}});\n\n    assert.equal(moment([2004]).weeksInYear(), 52, '2004 has 53 weeks');\n    assert.equal(moment([2005]).weeksInYear(), 53, '2005 has 53 weeks');\n    assert.equal(moment([2006]).weeksInYear(), 52, '2006 has 53 weeks');\n    assert.equal(moment([2007]).weeksInYear(), 52, '2007 has 52 weeks');\n    assert.equal(moment([2008]).weeksInYear(), 52, '2008 has 53 weeks');\n    assert.equal(moment([2009]).weeksInYear(), 52, '2009 has 53 weeks');\n    assert.equal(moment([2010]).weeksInYear(), 52, '2010 has 52 weeks');\n    assert.equal(moment([2011]).weeksInYear(), 53, '2011 has 52 weeks');\n    assert.equal(moment([2012]).weeksInYear(), 52, '2012 has 52 weeks');\n    assert.equal(moment([2013]).weeksInYear(), 52, '2013 has 52 weeks');\n    assert.equal(moment([2014]).weeksInYear(), 52, '2014 has 52 weeks');\n    assert.equal(moment([2015]).weeksInYear(), 52, '2015 has 53 weeks');\n});\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/test/moment/zone_switching.js",
    "content": "import { module, test, expect } from '../qunit';\nimport moment from '../../moment';\nimport { isNearSpringDST } from '../helpers/dst';\n\nmodule('zone switching');\n\ntest('local to utc, keepLocalTime = true', function (assert) {\n    var m = moment(),\n        fmt = 'YYYY-DD-MM HH:mm:ss';\n    assert.equal(m.clone().utc(true).format(fmt), m.format(fmt), 'local to utc failed to keep local time');\n});\n\ntest('local to utc, keepLocalTime = false', function (assert) {\n    var m = moment();\n    assert.equal(m.clone().utc().valueOf(), m.valueOf(), 'local to utc failed to keep utc time (implicit)');\n    assert.equal(m.clone().utc(false).valueOf(), m.valueOf(), 'local to utc failed to keep utc time (explicit)');\n});\n\ntest('local to zone, keepLocalTime = true', function (assert) {\n    test.expectedDeprecations('moment().zone');\n    var m = moment(),\n        fmt = 'YYYY-DD-MM HH:mm:ss',\n        z;\n\n    // Apparently there is -12:00 and +14:00\n    // https://en.wikipedia.org/wiki/UTC+14:00\n    // https://en.wikipedia.org/wiki/UTC-12:00\n    for (z = -12; z <= 14; ++z) {\n        assert.equal(m.clone().zone(z * 60, true).format(fmt), m.format(fmt),\n                'local to zone(' + z + ':00) failed to keep local time');\n    }\n});\n\ntest('local to zone, keepLocalTime = false', function (assert) {\n    test.expectedDeprecations('moment().zone');\n    var m = moment(),\n        z;\n\n    // Apparently there is -12:00 and +14:00\n    // https://en.wikipedia.org/wiki/UTC+14:00\n    // https://en.wikipedia.org/wiki/UTC-12:00\n    for (z = -12; z <= 14; ++z) {\n        assert.equal(m.clone().zone(z * 60).valueOf(), m.valueOf(),\n                'local to zone(' + z + ':00) failed to keep utc time (implicit)');\n        assert.equal(m.clone().zone(z * 60, false).valueOf(), m.valueOf(),\n                'local to zone(' + z + ':00) failed to keep utc time (explicit)');\n    }\n});\n\ntest('utc to local, keepLocalTime = true', function (assert) {\n    // Don't test near the spring DST transition\n    if (isNearSpringDST()) {\n        expect(0);\n        return;\n    }\n\n    var um = moment.utc(),\n        fmt = 'YYYY-DD-MM HH:mm:ss';\n\n    assert.equal(um.clone().local(true).format(fmt), um.format(fmt), 'utc to local failed to keep local time');\n});\n\ntest('utc to local, keepLocalTime = false', function (assert) {\n    var um = moment.utc();\n    assert.equal(um.clone().local().valueOf(), um.valueOf(), 'utc to local failed to keep utc time (implicit)');\n    assert.equal(um.clone().local(false).valueOf(), um.valueOf(), 'utc to local failed to keep utc time (explicit)');\n});\n\ntest('zone to local, keepLocalTime = true', function (assert) {\n    // Don't test near the spring DST transition\n    if (isNearSpringDST()) {\n        expect(0);\n        return;\n    }\n\n    test.expectedDeprecations('moment().zone');\n\n    var m = moment(),\n        fmt = 'YYYY-DD-MM HH:mm:ss',\n        z;\n\n    // Apparently there is -12:00 and +14:00\n    // https://en.wikipedia.org/wiki/UTC+14:00\n    // https://en.wikipedia.org/wiki/UTC-12:00\n    for (z = -12; z <= 14; ++z) {\n        m.zone(z * 60);\n\n        assert.equal(m.clone().local(true).format(fmt), m.format(fmt),\n                'zone(' + z + ':00) to local failed to keep local time');\n    }\n});\n\ntest('zone to local, keepLocalTime = false', function (assert) {\n    test.expectedDeprecations('moment().zone');\n    var m = moment(),\n        z;\n\n    // Apparently there is -12:00 and +14:00\n    // https://en.wikipedia.org/wiki/UTC+14:00\n    // https://en.wikipedia.org/wiki/UTC-12:00\n    for (z = -12; z <= 14; ++z) {\n        m.zone(z * 60);\n\n        assert.equal(m.clone().local(false).valueOf(), m.valueOf(),\n                'zone(' + z + ':00) to local failed to keep utc time (explicit)');\n        assert.equal(m.clone().local().valueOf(), m.valueOf(),\n                'zone(' + z + ':00) to local failed to keep utc time (implicit)');\n    }\n});\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/test/moment/zones.js",
    "content": "import { module, test } from '../qunit';\nimport moment from '../../moment';\n\nmodule('zones', {\n    'setup': function () {\n        test.expectedDeprecations('moment().zone');\n    }\n});\n\ntest('set zone', function (assert) {\n    var zone = moment();\n\n    zone.zone(0);\n    assert.equal(zone.zone(), 0, 'should be able to set the zone to 0');\n\n    zone.zone(60);\n    assert.equal(zone.zone(), 60, 'should be able to set the zone to 60');\n\n    zone.zone(-60);\n    assert.equal(zone.zone(), -60, 'should be able to set the zone to -60');\n});\n\ntest('set zone shorthand', function (assert) {\n    var zone = moment();\n\n    zone.zone(1);\n    assert.equal(zone.zone(), 60, 'setting the zone to 1 should imply hours and convert to 60');\n\n    zone.zone(-1);\n    assert.equal(zone.zone(), -60, 'setting the zone to -1 should imply hours and convert to -60');\n\n    zone.zone(15);\n    assert.equal(zone.zone(), 900, 'setting the zone to 15 should imply hours and convert to 900');\n\n    zone.zone(-15);\n    assert.equal(zone.zone(), -900, 'setting the zone to -15 should imply hours and convert to -900');\n\n    zone.zone(16);\n    assert.equal(zone.zone(), 16, 'setting the zone to 16 should imply minutes');\n\n    zone.zone(-16);\n    assert.equal(zone.zone(), -16, 'setting the zone to -16 should imply minutes');\n});\n\ntest('set zone with string', function (assert) {\n    var zone = moment();\n\n    zone.zone('+00:00');\n    assert.equal(zone.zone(), 0, 'set the zone with a timezone string');\n\n    zone.zone('2013-03-07T07:00:00-08:00');\n    assert.equal(zone.zone(), 480, 'set the zone with a string that does not begin with the timezone');\n\n    zone.zone('2013-03-07T07:00:00+0100');\n    assert.equal(zone.zone(), -60, 'set the zone with a string that uses the +0000 syntax');\n\n    zone.zone('2013-03-07T07:00:00+02');\n    assert.equal(zone.zone(), -120, 'set the zone with a string that uses the +00 syntax');\n\n    zone.zone('03-07-2013T07:00:00-08:00');\n    assert.equal(zone.zone(), 480, 'set the zone with a string with a non-ISO 8601 date');\n});\n\ntest('change hours when changing the zone', function (assert) {\n    var zone = moment.utc([2000, 0, 1, 6]);\n\n    zone.zone(0);\n    assert.equal(zone.hour(), 6, 'UTC 6AM should be 6AM at +0000');\n\n    zone.zone(60);\n    assert.equal(zone.hour(), 5, 'UTC 6AM should be 5AM at -0100');\n\n    zone.zone(-60);\n    assert.equal(zone.hour(), 7, 'UTC 6AM should be 7AM at +0100');\n});\n\ntest('change minutes when changing the zone', function (assert) {\n    var zone = moment.utc([2000, 0, 1, 6, 31]);\n\n    zone.zone(0);\n    assert.equal(zone.format('HH:mm'), '06:31', 'UTC 6:31AM should be 6:31AM at +0000');\n\n    zone.zone(30);\n    assert.equal(zone.format('HH:mm'), '06:01', 'UTC 6:31AM should be 6:01AM at -0030');\n\n    zone.zone(-30);\n    assert.equal(zone.format('HH:mm'), '07:01', 'UTC 6:31AM should be 7:01AM at +0030');\n\n    zone.zone(1380);\n    assert.equal(zone.format('HH:mm'), '07:31', 'UTC 6:31AM should be 7:31AM at +1380');\n});\n\ntest('distance from the unix epoch', function (assert) {\n    var zoneA = moment(),\n        zoneB = moment(zoneA),\n        zoneC = moment(zoneA),\n        zoneD = moment(zoneA),\n        zoneE = moment(zoneA);\n\n    zoneB.utc();\n    assert.equal(+zoneA, +zoneB, 'moment should equal moment.utc');\n\n    zoneC.zone(-60);\n    assert.equal(+zoneA, +zoneC, 'moment should equal moment.zone(-60)');\n\n    zoneD.zone(480);\n    assert.equal(+zoneA, +zoneD, 'moment should equal moment.zone(480)');\n\n    zoneE.zone(1000);\n    assert.equal(+zoneA, +zoneE, 'moment should equal moment.zone(1000)');\n});\n\ntest('update offset after changing any values', function (assert) {\n    var oldOffset = moment.updateOffset,\n        m = moment.utc([2000, 6, 1]);\n\n    moment.updateOffset = function (mom, keepTime) {\n        if (mom.__doChange) {\n            if (+mom > 962409600000) {\n                mom.zone(120, keepTime);\n            } else {\n                mom.zone(60, keepTime);\n            }\n        }\n    };\n\n    assert.equal(m.format('ZZ'), '+0000', 'should be at +0000');\n    assert.equal(m.format('HH:mm'), '00:00', 'should start 12AM at +0000 timezone');\n\n    m.__doChange = true;\n    m.add(1, 'h');\n\n    assert.equal(m.format('ZZ'), '-0200', 'should be at -0200');\n    assert.equal(m.format('HH:mm'), '23:00', '1AM at +0000 should be 11PM at -0200 timezone');\n\n    m.subtract(1, 'h');\n\n    assert.equal(m.format('ZZ'), '-0100', 'should be at -0100');\n    assert.equal(m.format('HH:mm'), '23:00', '12AM at +0000 should be 11PM at -0100 timezone');\n\n    moment.updateOffset = oldOffset;\n});\n\ntest('getters and setters', function (assert) {\n    var a = moment([2011, 5, 20]);\n\n    assert.equal(a.clone().zone(120).year(2012).year(), 2012, 'should get and set year correctly');\n    assert.equal(a.clone().zone(120).month(1).month(), 1, 'should get and set month correctly');\n    assert.equal(a.clone().zone(120).date(2).date(), 2, 'should get and set date correctly');\n    assert.equal(a.clone().zone(120).day(1).day(), 1, 'should get and set day correctly');\n    assert.equal(a.clone().zone(120).hour(1).hour(), 1, 'should get and set hour correctly');\n    assert.equal(a.clone().zone(120).minute(1).minute(), 1, 'should get and set minute correctly');\n});\n\ntest('getters', function (assert) {\n    var a = moment.utc([2012, 0, 1, 0, 0, 0]);\n\n    assert.equal(a.clone().zone(120).year(),  2011, 'should get year correctly');\n    assert.equal(a.clone().zone(120).month(),   11, 'should get month correctly');\n    assert.equal(a.clone().zone(120).date(),    31, 'should get date correctly');\n    assert.equal(a.clone().zone(120).hour(),    22, 'should get hour correctly');\n    assert.equal(a.clone().zone(120).minute(),   0, 'should get minute correctly');\n\n    assert.equal(a.clone().zone(-120).year(),  2012, 'should get year correctly');\n    assert.equal(a.clone().zone(-120).month(),    0, 'should get month correctly');\n    assert.equal(a.clone().zone(-120).date(),     1, 'should get date correctly');\n    assert.equal(a.clone().zone(-120).hour(),     2, 'should get hour correctly');\n    assert.equal(a.clone().zone(-120).minute(),   0, 'should get minute correctly');\n\n    assert.equal(a.clone().zone(-90).year(),  2012, 'should get year correctly');\n    assert.equal(a.clone().zone(-90).month(),    0, 'should get month correctly');\n    assert.equal(a.clone().zone(-90).date(),     1, 'should get date correctly');\n    assert.equal(a.clone().zone(-90).hour(),     1, 'should get hour correctly');\n    assert.equal(a.clone().zone(-90).minute(),  30, 'should get minute correctly');\n});\n\ntest('from', function (assert) {\n    var zoneA = moment(),\n        zoneB = moment(zoneA).zone(720),\n        zoneC = moment(zoneA).zone(360),\n        zoneD = moment(zoneA).zone(-690),\n        other = moment(zoneA).add(35, 'm');\n\n    assert.equal(zoneA.from(other), zoneB.from(other), 'moment#from should be the same in all zones');\n    assert.equal(zoneA.from(other), zoneC.from(other), 'moment#from should be the same in all zones');\n    assert.equal(zoneA.from(other), zoneD.from(other), 'moment#from should be the same in all zones');\n});\n\ntest('diff', function (assert) {\n    var zoneA = moment(),\n        zoneB = moment(zoneA).zone(720),\n        zoneC = moment(zoneA).zone(360),\n        zoneD = moment(zoneA).zone(-690),\n        other = moment(zoneA).add(35, 'm');\n\n    assert.equal(zoneA.diff(other), zoneB.diff(other), 'moment#diff should be the same in all zones');\n    assert.equal(zoneA.diff(other), zoneC.diff(other), 'moment#diff should be the same in all zones');\n    assert.equal(zoneA.diff(other), zoneD.diff(other), 'moment#diff should be the same in all zones');\n\n    assert.equal(zoneA.diff(other, 'minute', true), zoneB.diff(other, 'minute', true), 'moment#diff should be the same in all zones');\n    assert.equal(zoneA.diff(other, 'minute', true), zoneC.diff(other, 'minute', true), 'moment#diff should be the same in all zones');\n    assert.equal(zoneA.diff(other, 'minute', true), zoneD.diff(other, 'minute', true), 'moment#diff should be the same in all zones');\n\n    assert.equal(zoneA.diff(other, 'hour', true), zoneB.diff(other, 'hour', true), 'moment#diff should be the same in all zones');\n    assert.equal(zoneA.diff(other, 'hour', true), zoneC.diff(other, 'hour', true), 'moment#diff should be the same in all zones');\n    assert.equal(zoneA.diff(other, 'hour', true), zoneD.diff(other, 'hour', true), 'moment#diff should be the same in all zones');\n});\n\ntest('unix offset and timestamp', function (assert) {\n    var zoneA = moment(),\n        zoneB = moment(zoneA).zone(720),\n        zoneC = moment(zoneA).zone(360),\n        zoneD = moment(zoneA).zone(-690);\n\n    assert.equal(zoneA.unix(), zoneB.unix(), 'moment#unix should be the same in all zones');\n    assert.equal(zoneA.unix(), zoneC.unix(), 'moment#unix should be the same in all zones');\n    assert.equal(zoneA.unix(), zoneD.unix(), 'moment#unix should be the same in all zones');\n\n    assert.equal(+zoneA, +zoneB, 'moment#valueOf should be the same in all zones');\n    assert.equal(+zoneA, +zoneC, 'moment#valueOf should be the same in all zones');\n    assert.equal(+zoneA, +zoneD, 'moment#valueOf should be the same in all zones');\n});\n\ntest('cloning', function (assert) {\n    assert.equal(moment().zone(120).clone().zone(),   120, 'explicit cloning should retain the zone');\n    assert.equal(moment().zone(-120).clone().zone(), -120, 'explicit cloning should retain the zone');\n    assert.equal(moment(moment().zone(120)).zone(),   120, 'implicit cloning should retain the zone');\n    assert.equal(moment(moment().zone(-120)).zone(), -120, 'implicit cloning should retain the zone');\n});\n\ntest('start of / end of', function (assert) {\n    var a = moment.utc([2010, 1, 2, 0, 0, 0]).zone(450);\n\n    assert.equal(a.clone().startOf('day').hour(), 0, 'start of day should work on moments with a zone');\n    assert.equal(a.clone().startOf('day').minute(), 0, 'start of day should work on moments with a zone');\n    assert.equal(a.clone().startOf('hour').minute(), 0, 'start of hour should work on moments with a zone');\n\n    assert.equal(a.clone().endOf('day').hour(), 23, 'end of day should work on moments with a zone');\n    assert.equal(a.clone().endOf('day').minute(), 59, 'end of day should work on moments with a zone');\n    assert.equal(a.clone().endOf('hour').minute(), 59, 'end of hour should work on moments with a zone');\n});\n\ntest('reset zone with moment#utc', function (assert) {\n    var a = moment.utc([2012]).zone(480);\n\n    assert.equal(a.clone().hour(),      16, 'different zone should have different hour');\n    assert.equal(a.clone().utc().hour(), 0, 'calling moment#utc should reset the offset');\n});\n\ntest('reset zone with moment#local', function (assert) {\n    var a = moment([2012]).zone(480);\n\n    assert.equal(a.clone().local().hour(), 0, 'calling moment#local should reset the offset');\n});\n\ntest('toDate', function (assert) {\n    var zoneA = new Date(),\n        zoneB = moment(zoneA).zone(720).toDate(),\n        zoneC = moment(zoneA).zone(360).toDate(),\n        zoneD = moment(zoneA).zone(-690).toDate();\n\n    assert.equal(+zoneA, +zoneB, 'moment#toDate should output a date with the right unix timestamp');\n    assert.equal(+zoneA, +zoneC, 'moment#toDate should output a date with the right unix timestamp');\n    assert.equal(+zoneA, +zoneD, 'moment#toDate should output a date with the right unix timestamp');\n});\n\ntest('same / before / after', function (assert) {\n    var zoneA = moment().utc(),\n        zoneB = moment(zoneA).zone(120),\n        zoneC = moment(zoneA).zone(-120);\n\n    assert.ok(zoneA.isSame(zoneB), 'two moments with different offsets should be the same');\n    assert.ok(zoneA.isSame(zoneC), 'two moments with different offsets should be the same');\n\n    assert.ok(zoneA.isSame(zoneB, 'hour'), 'two moments with different offsets should be the same hour');\n    assert.ok(zoneA.isSame(zoneC, 'hour'), 'two moments with different offsets should be the same hour');\n\n    zoneA.add(1, 'hour');\n\n    assert.ok(zoneA.isAfter(zoneB), 'isAfter should work with two moments with different offsets');\n    assert.ok(zoneA.isAfter(zoneC), 'isAfter should work with two moments with different offsets');\n\n    assert.ok(zoneA.isAfter(zoneB, 'hour'), 'isAfter:hour should work with two moments with different offsets');\n    assert.ok(zoneA.isAfter(zoneC, 'hour'), 'isAfter:hour should work with two moments with different offsets');\n\n    zoneA.subtract(2, 'hour');\n\n    assert.ok(zoneA.isBefore(zoneB), 'isBefore should work with two moments with different offsets');\n    assert.ok(zoneA.isBefore(zoneC), 'isBefore should work with two moments with different offsets');\n\n    assert.ok(zoneA.isBefore(zoneB, 'hour'), 'isBefore:hour should work with two moments with different offsets');\n    assert.ok(zoneA.isBefore(zoneC, 'hour'), 'isBefore:hour should work with two moments with different offsets');\n});\n\ntest('add / subtract over dst', function (assert) {\n    var oldOffset = moment.updateOffset,\n        m = moment.utc([2000, 2, 31, 3]);\n\n    moment.updateOffset = function (mom, keepTime) {\n        if (mom.clone().utc().month() > 2) {\n            mom.zone(-60, keepTime);\n        } else {\n            mom.zone(0, keepTime);\n        }\n    };\n\n    assert.equal(m.hour(), 3, 'should start at 00:00');\n\n    m.add(24, 'hour');\n\n    assert.equal(m.hour(), 4, 'adding 24 hours should disregard dst');\n\n    m.subtract(24, 'hour');\n\n    assert.equal(m.hour(), 3, 'subtracting 24 hours should disregard dst');\n\n    m.add(1, 'day');\n\n    assert.equal(m.hour(), 3, 'adding 1 day should have the same hour');\n\n    m.subtract(1, 'day');\n\n    assert.equal(m.hour(), 3, 'subtracting 1 day should have the same hour');\n\n    m.add(1, 'month');\n\n    assert.equal(m.hour(), 3, 'adding 1 month should have the same hour');\n\n    m.subtract(1, 'month');\n\n    assert.equal(m.hour(), 3, 'subtracting 1 month should have the same hour');\n\n    moment.updateOffset = oldOffset;\n});\n\ntest('isDST', function (assert) {\n    var oldOffset = moment.updateOffset;\n\n    moment.updateOffset = function (mom, keepTime) {\n        if (mom.month() > 2 && mom.month() < 9) {\n            mom.zone(-60, keepTime);\n        } else {\n            mom.zone(0, keepTime);\n        }\n    };\n\n    assert.ok(!moment().month(0).isDST(),  'Jan should not be summer dst');\n    assert.ok(moment().month(6).isDST(),   'Jul should be summer dst');\n    assert.ok(!moment().month(11).isDST(), 'Dec should not be summer dst');\n\n    moment.updateOffset = function (mom) {\n        if (mom.month() > 2 && mom.month() < 9) {\n            mom.zone(0);\n        } else {\n            mom.zone(-60);\n        }\n    };\n\n    assert.ok(moment().month(0).isDST(),  'Jan should be winter dst');\n    assert.ok(!moment().month(6).isDST(), 'Jul should not be winter dst');\n    assert.ok(moment().month(11).isDST(), 'Dec should be winter dst');\n\n    moment.updateOffset = oldOffset;\n});\n\ntest('zone names', function (assert) {\n    test.expectedDeprecations();\n    assert.equal(moment().zoneAbbr(),   '', 'Local zone abbr should be empty');\n    assert.equal(moment().format('z'),  '', 'Local zone formatted abbr should be empty');\n    assert.equal(moment().zoneName(),   '', 'Local zone name should be empty');\n    assert.equal(moment().format('zz'), '', 'Local zone formatted name should be empty');\n\n    assert.equal(moment.utc().zoneAbbr(),   'UTC', 'UTC zone abbr should be UTC');\n    assert.equal(moment.utc().format('z'),  'UTC', 'UTC zone formatted abbr should be UTC');\n    assert.equal(moment.utc().zoneName(),   'Coordinated Universal Time', 'UTC zone abbr should be Coordinated Universal Time');\n    assert.equal(moment.utc().format('zz'), 'Coordinated Universal Time', 'UTC zone formatted abbr should be Coordinated Universal Time');\n});\n\ntest('hours alignment with UTC', function (assert) {\n    assert.equal(moment().zone(120).hasAlignedHourOffset(), true);\n    assert.equal(moment().zone(-180).hasAlignedHourOffset(), true);\n    assert.equal(moment().zone(90).hasAlignedHourOffset(), false);\n    assert.equal(moment().zone(-90).hasAlignedHourOffset(), false);\n});\n\ntest('hours alignment with other zone', function (assert) {\n    var m = moment().zone(120);\n\n    assert.equal(m.hasAlignedHourOffset(moment().zone(180)), true);\n    assert.equal(m.hasAlignedHourOffset(moment().zone(-180)), true);\n    assert.equal(m.hasAlignedHourOffset(moment().zone(90)), false);\n    assert.equal(m.hasAlignedHourOffset(moment().zone(-90)), false);\n\n    m = moment().zone(90);\n\n    assert.equal(m.hasAlignedHourOffset(moment().zone(180)), false);\n    assert.equal(m.hasAlignedHourOffset(moment().zone(-180)), false);\n    assert.equal(m.hasAlignedHourOffset(moment().zone(30)), true);\n    assert.equal(m.hasAlignedHourOffset(moment().zone(-30)), true);\n\n    m = moment().zone(-60);\n\n    assert.equal(m.hasAlignedHourOffset(moment().zone(180)), true);\n    assert.equal(m.hasAlignedHourOffset(moment().zone(-180)), true);\n    assert.equal(m.hasAlignedHourOffset(moment().zone(90)), false);\n    assert.equal(m.hasAlignedHourOffset(moment().zone(-90)), false);\n\n    m = moment().zone(25);\n\n    assert.equal(m.hasAlignedHourOffset(moment().zone(-35)), true);\n    assert.equal(m.hasAlignedHourOffset(moment().zone(85)), true);\n\n    assert.equal(m.hasAlignedHourOffset(moment().zone(35)), false);\n    assert.equal(m.hasAlignedHourOffset(moment().zone(-85)), false);\n});\n\ntest('parse zone', function (assert) {\n    var m = moment('2013-01-01T00:00:00-13:00').parseZone();\n    assert.equal(m.zone(), 13 * 60);\n    assert.equal(m.hours(), 0);\n});\n\ntest('parse zone static', function (assert) {\n    var m = moment.parseZone('2013-01-01T00:00:00-13:00');\n    assert.equal(m.zone(), 13 * 60);\n    assert.equal(m.hours(), 0);\n});\n\ntest('parse zone with more arguments', function (assert) {\n    test.expectedDeprecations();\n    var m;\n    m = moment.parseZone('2013 01 01 05 -13:00', 'YYYY MM DD HH ZZ');\n    assert.equal(m.format(), '2013-01-01T05:00:00-13:00', 'accept input and format');\n    m = moment.parseZone('2013-01-01-13:00', 'YYYY MM DD ZZ', true);\n    assert.equal(m.isValid(), false, 'accept input, format and strict flag');\n    m = moment.parseZone('2013-01-01-13:00', ['DD MM YYYY ZZ', 'YYYY MM DD ZZ']);\n    assert.equal(m.format(), '2013-01-01T00:00:00-13:00', 'accept input and array of formats');\n});\n\ntest('parse zone with a timezone from the format string', function (assert) {\n    var m = moment('11-12-2013 -0400 +1100', 'DD-MM-YYYY ZZ #####').parseZone();\n\n    assert.equal(m.zone(), 4 * 60);\n});\n\ntest('parse zone without a timezone included in the format string', function (assert) {\n    var m = moment('11-12-2013 -0400 +1100', 'DD-MM-YYYY').parseZone();\n\n    assert.equal(m.zone(), -11 * 60);\n});\n\ntest('timezone format', function (assert) {\n    assert.equal(moment().zone(-60).format('ZZ'), '+0100', '-60 -> +0100');\n    assert.equal(moment().zone(-90).format('ZZ'), '+0130', '-90 -> +0130');\n    assert.equal(moment().zone(-120).format('ZZ'), '+0200', '-120 -> +0200');\n\n    assert.equal(moment().zone(+60).format('ZZ'), '-0100', '+60 -> -0100');\n    assert.equal(moment().zone(+90).format('ZZ'), '-0130', '+90 -> -0130');\n    assert.equal(moment().zone(+120).format('ZZ'), '-0200', '+120 -> -0200');\n});\n\ntest('parse zone without a timezone', function (assert) {\n    test.expectedDeprecations();\n    var m1 = moment.parseZone('2016-02-01T00:00:00');\n    var m2 = moment.parseZone('2016-02-01T00:00:00Z');\n    var m3 = moment.parseZone('2016-02-01T00:00:00+00:00'); //Someone might argue this is not necessary, you could even argue that is wrong being here.\n    var m4 = moment.parseZone('2016-02-01T00:00:00+0000'); //Someone might argue this is not necessary, you could even argue that is wrong being here.\n    assert.equal(\n        m1.format('M D YYYY HH:mm:ss ZZ'),\n        '2 1 2016 00:00:00 +0000',\n        'Not providing a timezone should keep the time and change the zone to 0'\n    );\n    assert.equal(\n        m2.format('M D YYYY HH:mm:ss ZZ'),\n        '2 1 2016 00:00:00 +0000',\n        'Not providing a timezone should keep the time and change the zone to 0'\n    );\n    assert.equal(\n        m3.format('M D YYYY HH:mm:ss ZZ'),\n        '2 1 2016 00:00:00 +0000',\n        'Not providing a timezone should keep the time and change the zone to 0'\n    );\n    assert.equal(\n        m4.format('M D YYYY HH:mm:ss ZZ'),\n        '2 1 2016 00:00:00 +0000',\n        'Not providing a timezone should keep the time and change the zone to 0'\n    );\n});\n\ntest('parse zone with a minutes unit abs less than 16 should retain minutes', function (assert) {\n    //ensure when minutes are explicitly parsed, they are retained\n    //instead of converted to hours, even if less than 16\n    var n = moment.parseZone('2013-01-01T00:00:00-00:15');\n    assert.equal(n.utcOffset(), -15);\n    assert.equal(n.zone(), 15);\n    assert.equal(n.hour(), 0);\n    var o = moment.parseZone('2013-01-01T00:00:00+00:15');\n    assert.equal(o.utcOffset(), 15);\n    assert.equal(o.zone(), -15);\n    assert.equal(o.hour(), 0);\n});\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/src/test/qunit.js",
    "content": "/*global QUnit:false*/\n\nimport moment from '../moment';\nimport { defineCommonLocaleTests } from './helpers/common-locale';\nimport { setupDeprecationHandler, teardownDeprecationHandler } from './helpers/deprecation-handler';\n\nexport var test = QUnit.test;\n\nexport var expect = QUnit.expect;\n\nexport function module (name, lifecycle) {\n    QUnit.module(name, {\n        setup : function () {\n            moment.locale('en');\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'core');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            teardownDeprecationHandler(test, moment, 'core');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n}\n\nexport function localeModule (name, lifecycle) {\n    QUnit.module('locale:' + name, {\n        setup : function () {\n            moment.locale(name);\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            moment.locale('en');\n            teardownDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n    defineCommonLocaleTests(name, -1, -1);\n}\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/tasks/bump_version.js",
    "content": "module.exports = function (grunt) {\n    grunt.registerTask('bump_version', function (version) {\n        if (!version || version.split('.').length !== 3) {\n            grunt.fail.fatal('malformed version. Use\\n\\n    grunt bump_version:1.2.3');\n        }\n\n        grunt.config('string-replace.moment-js', {\n            files: {'src/moment.js': 'src/moment.js'},\n            options: {\n                replacements: [\n                    {\n                        pattern:     /\\/\\/! version : .*/,\n                        replacement: '//! version : ' + version\n                    }, {\n                        pattern:     /moment\\.version = '.*'/,\n                        replacement: \"moment.version = '\" + version + \"'\"\n                    }\n                ]\n            }\n        });\n\n        grunt.config('string-replace.package-json', {\n            files: {'package.json': 'package.json'},\n            options: {\n                replacements: [\n                    {\n                        pattern:     /\"version\": .*/,\n                        replacement: '\"version\": \"' + version + '\",'\n                    }\n                ]\n            }\n        });\n\n        grunt.config('string-replace.component-json', {\n            files: {'component.json': 'component.json'},\n            options: {\n                replacements: [\n                    {\n                        pattern:     /\"version\": .*/,\n                        replacement: '\"version\": \"' + version + '\",'\n                    }\n                ]\n            }\n        });\n\n        grunt.config('string-replace.moment-js-nuspec', {\n            files: {'Moment.js.nuspec': 'Moment.js.nuspec'},\n            options: {\n                replacements: [\n                    {\n                        pattern:     /<version>.*<\\/version>/,\n                        replacement: '<version>' + version + '</version>'\n                    }\n                ]\n            }\n        });\n\n        grunt.config('string-replace.meteor-package-js', {\n            files: {'meteor/package.js': 'meteor/package.js'},\n            options: {\n                replacements: [\n                    {\n                        pattern:     /version: .*/,\n                        replacement: 'version: \\'' + version + '\\','\n                    }\n                ]\n            }\n        });\n\n        grunt.task.run([\n            'string-replace:moment-js',\n            'string-replace:package-json',\n            'string-replace:component-json',\n            'string-replace:moment-js-nuspec',\n            'string-replace:meteor-package-js'\n        ]);\n    });\n};\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/tasks/check_sauce_creds.js",
    "content": "module.exports = function (grunt) {\n    // Pull requests do not have secure variables enabled for security reasons.\n    // Use this task before launching travis-sauce-browser task, so it would\n    // exit early and won't try connecting to SauceLabs without credentials.\n    grunt.registerTask('check-sauce-creds', function () {\n        if (process.env.SAUCE_USERNAME === undefined) {\n            grunt.log.writeln('No sauce credentials found');\n            grunt.task.clearQueue();\n        } else {\n            grunt.log.writeln('Sauce credentials found');\n        }\n    });\n};\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/tasks/component.js",
    "content": "module.exports = function (grunt) {\n    grunt.registerTask('component', function () {\n        var config = JSON.parse(grunt.file.read('component.json'));\n\n        config.files = grunt.file.expand('locale/*.js');\n        config.files.unshift('moment.js');\n\n        grunt.file.write('component.json', JSON.stringify(config, true, 2) + '\\n');\n    });\n};\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/tasks/nuget.js",
    "content": "module.exports = function (grunt) {\n    // To set up on mac:\n    // * brew install nuget # this fetches mono\n    // * go to nuget.org, login, click on username (top right), copy api-key\n    //   from the bottom\n    // * grunt nugetkey --key=XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX\n    // * grunt nuget-publish\n    //\n    //\n    // If this fails you might need to follow:\n    //\n    // http://stackoverflow.com/questions/15181888/nuget-on-linux-error-getting-response-stream\n    //\n    // $ sudo mozroots --import --machine --sync\n    // $ sudo certmgr -ssl -m https://go.microsoft.com\n    // $ sudo certmgr -ssl -m https://nugetgallery.blob.core.windows.net\n    // $ sudo certmgr -ssl -m https://nuget.org\n\n    grunt.config('nugetpack', {\n        dist: {\n            src: 'Moment.js.nuspec',\n            dest: './'\n        }\n    });\n    grunt.registerTask('nugetkey_pre', function () {\n        grunt.option('key', process.env.NUGET_KEY);\n        grunt.option('source', 'https://www.nuget.org/api/v2/package');\n    });\n    grunt.registerTask('nugetkey_post', function () {\n        grunt.option('key', null);\n        grunt.option('source', null);\n    });\n    grunt.config('nugetpush', {\n        dist: {\n            src: 'Moment.js.*.nupkg'\n        }\n    });\n    grunt.config('clean.nuget', {\n        src: 'Moment.js.*.nupkg'\n    });\n\n    grunt.registerTask('nuget-publish', [\n        'nugetpack', 'nugetkey_pre', 'nugetkey', 'nugetkey_post', 'nugetpush', 'clean:nuget'\n    ]);\n};\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/tasks/qtest.js",
    "content": "module.exports = function (grunt) {\n    grunt.task.registerTask('qtest', 'run tests locally', function () {\n        var done = this.async();\n\n        var testrunner = require('qunit');\n\n        testrunner.options.log.assertions = false;\n        testrunner.options.log.tests = false;\n        testrunner.options.log.summary = false;\n        testrunner.options.log.testing = false;\n        testrunner.options.maxBlockDuration = 120000;\n\n        var tests;\n\n        if (grunt.option('only') != null) {\n            tests = grunt.file.expand.apply(null, grunt.option('only').split(',').map(function (file) {\n                if (file === 'moment') {\n                    return 'build/umd/test/moment/*.js';\n                } else if (file === 'locale') {\n                    return 'build/umd/test/locale/*.js';\n                } else {\n                    return 'build/umd/test/' + file + '.js';\n                }\n            }));\n        } else {\n            tests = grunt.file.expand('build/umd/test/moment/*.js',\n                'build/umd/test/locale/*.js');\n        }\n\n        testrunner.run({\n            code: 'build/umd/moment.js',\n            tests: tests\n        }, function (err, report) {\n            if (err) {\n                console.log('woot', err, report);\n                done(err);\n                return;\n            }\n            err = null;\n            if (report.failed !== 0) {\n                err = new Error(report.failed + ' tests failed');\n            }\n            done(err);\n        });\n    });\n};\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/tasks/transpile.js",
    "content": "module.exports = function (grunt) {\n    // var esperanto = require('esperanto');\n    var rollup = require('rollup').rollup;\n    // var babel = require('rollup-plugin-babel');\n    var path = require('path');\n    var Promise = require('es6-promise').Promise;\n    var TMP_DIR = 'build/tmp';\n\n    function moveComments(code, moveType) {\n        var comments = [], rest = [], skipId = -1;\n        code.split('\\n').forEach(function (line, i) {\n            var isComment = false;\n            if (line.trim().slice(0, 3) === '//!') {\n                isComment = true;\n            }\n            if (isComment && moveType === 'main-only') {\n                if (i === skipId + 1 ||\n                        line.trim() === '//! moment.js locale configuration') {\n                    skipId = i;\n                    // continue to next line\n                    return;\n                }\n            }\n\n            if (isComment) {\n                comments.push(line.trim());\n            } else {\n                rest.push(line);\n            }\n        });\n\n        return comments.concat([''], rest).join('\\n');\n    }\n\n    var headerCache = {};\n    function getHeaderByFile(headerFile) {\n        if (headerFile === 'none') {\n            return '';\n        }\n        if (!(headerFile in headerCache)) {\n            headerCache[headerFile] = grunt.file.read(headerFile);\n        }\n        return headerCache[headerFile];\n    }\n\n    function rollupBundle(opts) {\n        // entry, umdName, skipMoment\n\n        var rollupOpts = {\n            entry: opts.entry,\n            plugins: [\n                // babel({})\n            ]\n        }, bundleOpts = {\n            format: 'umd',\n            moduleName: opts.umdName != null ? opts.umdName : 'not_used'\n        };\n\n        if (opts.skipMoment) {\n            // And this is what people call progress?\n            rollupOpts.external = [\n                './moment',\n                '../moment',\n                '../../moment',\n                path.resolve('src/moment'),\n                path.resolve('build/tmp/moment')\n            ];\n            bundleOpts.globals = {};\n            bundleOpts.globals[path.resolve('src/moment')] = 'moment';\n            bundleOpts.globals[path.resolve('build/tmp/moment')] = 'moment';\n        }\n\n        return rollup(rollupOpts).then(function (bundle) {\n            var result = bundle.generate(bundleOpts);\n            return result.code;\n        });\n    }\n\n    function transpile(opts) {\n        // base, entry, skipMoment, headerFile, skipLines, target\n        var umdName = opts.headerFile != null && opts.headerFile !== 'none' ? 'not_used' : opts.umdName,\n            headerFile = opts.headerFile ? opts.headerFile : 'templates/default.js',\n            header = getHeaderByFile(headerFile),\n            skipLines = opts.skipLines != null ? opts.skipLines : 5;\n\n        return rollupBundle({\n            entry: path.join(opts.base, opts.entry),\n            skipMoment: opts.skipMoment != null ? opts.skipMoment : false,\n            umdName: umdName\n        }).then(function (code) {\n            var fixed = header + code.split('\\n').slice(skipLines).join('\\n');\n            if (opts.moveComments) {\n                fixed = moveComments(fixed, opts.moveComments);\n            }\n            grunt.file.write(opts.target, fixed);\n        });\n    }\n\n    function transpileMany(opts) {\n        var batchSize = 50,\n            promise = Promise.resolve(null),\n            files = grunt.file.expand({cwd: opts.base}, opts.pattern),\n            i,\n            transpileOne = function (i) {\n                promise = promise.then(function () {\n                    return Promise.all(files.slice(i, i + batchSize).map(function (file) {\n                        return transpile({\n                            base: opts.base,\n                            entry: file,\n                            headerFile: opts.headerFile,\n                            skipMoment: opts.skipMoment,\n                            skipLines: opts.skipLines,\n                            moveComments: opts.moveComments,\n                            target: path.join(opts.targetDir, file)\n                        });\n                    }));\n                });\n            };\n\n        for (i = 0; i < files.length; i += batchSize) {\n            transpileOne(i);\n        }\n\n        return promise;\n    }\n\n    function prepareTemp(base) {\n        var files = grunt.file.expand({cwd: base}, '**/*.js'),\n            tmpDir = TMP_DIR;\n        if (grunt.file.exists(tmpDir)) {\n            return;\n        }\n        files.forEach(function (file) {\n            grunt.file.copy(path.join(base, file), path.join(tmpDir, file));\n        });\n    }\n\n    function transpileCode(opts) {\n        var entry = opts.entry || path.basename(opts.target);\n        prepareTemp(opts.base);\n        grunt.file.write(path.join(TMP_DIR, entry), opts.code);\n        return transpile({\n            base: TMP_DIR,\n            entry: entry,\n            umdName: opts.umdName || 'not_used',\n            headerFile: opts.headerFile,\n            skipLines: opts.skipLines,\n            moveComments: opts.moveComments,\n            target: opts.target,\n            skipMoment: opts.skipMoment\n        });\n    }\n\n    function generateLocales(target, localeFiles, opts) {\n        var files = localeFiles,\n            code = [\n                'import moment from \"./moment\";',\n                'export default moment;'\n            ].concat(files.map(function (file) {\n                var identifier = path.basename(file, '.js').replace('-', '_');\n                return 'import ' + identifier + ' from \"./' + file + '\";';\n            })).concat([\n                // Reset the language back to 'en', because every defineLocale\n                // also sets it.\n                'moment.locale(\\'en\\');'\n            ]).join('\\n');\n        return transpileCode({\n            base: 'src',\n            code: code,\n            target: target,\n            skipMoment: opts.skipMoment,\n            headerFile: opts.skipMoment === true ? 'templates/locale-header.js' : 'templates/default.js',\n            skipLines: opts.skipMoment === true ? 7 : 5\n        });\n    }\n\n    grunt.task.registerTask('transpile-raw', 'convert es6 to umd', function () {\n        var done = this.async();\n\n        transpile({\n            base: 'src',\n            entry: 'moment.js',\n            umdName: 'moment',\n            target: 'build/umd/moment.js',\n            skipLines: 5,\n            moveComments: true\n        }).then(function () {\n            grunt.log.ok('build/umd/moment.js');\n        }).then(function () {\n            return transpileMany({\n                base: 'src',\n                pattern: 'locale/*.js',\n                headerFile: 'templates/locale-header.js',\n                skipLines: 7,\n                moveComments: true,\n                targetDir: 'build/umd',\n                skipMoment: true\n            });\n        }).then(function () {\n            grunt.log.ok('build/umd/locale/*.js');\n        }).then(function () {\n            return transpileMany({\n                base: 'src',\n                pattern: 'test/moment/*.js',\n                headerFile: 'templates/test-header.js',\n                skipLines: 7,\n                moveComments: true,\n                targetDir: 'build/umd',\n                skipMoment: true\n            });\n        }).then(function () {\n            grunt.log.ok('build/umd/test/moment/*.js');\n        }).then(function () {\n            return transpileMany({\n                base: 'src',\n                pattern: 'test/locale/*.js',\n                headerFile: 'templates/test-header.js',\n                skipLines: 7,\n                moveComments: true,\n                targetDir: 'build/umd',\n                skipMoment: true\n            });\n        }).then(function () {\n            grunt.log.ok('build/umd/test/locale/*.js');\n        }).then(function () {\n            return generateLocales(\n                'build/umd/min/locales.js',\n                grunt.file.expand({cwd: 'src'}, 'locale/*.js'),\n                {skipMoment: true}\n            );\n        }).then(function () {\n            grunt.log.ok('build/umd/min/locales.js');\n        }).then(function () {\n            return generateLocales(\n                'build/umd/min/moment-with-locales.js',\n                grunt.file.expand({cwd: 'src'}, 'locale/*.js'),\n                {skipMoment: false}\n            );\n        }).then(function () {\n            grunt.log.ok('build/umd/min/moment-with-locales.js');\n        }).then(done, function (e) {\n            grunt.log.error('error transpiling', e);\n            done(e);\n        });\n    });\n\n    grunt.task.registerTask('transpile-custom-raw',\n            'build just custom language bundles',\n            function (locales) {\n        var done = this.async();\n\n        var localeFiles = locales.split(',').map(function (locale) {\n            var file = grunt.file.expand({cwd: 'src'}, 'locale/' + locale + '.js');\n            if (file.length !== 1) {\n                // we failed to find a locale\n                done(new Error('could not find locale: ' + locale));\n                done = null;\n            } else {\n                return file[0];\n            }\n        });\n\n        // There was an issue with a locale\n        if (done == null) {\n            return;\n        }\n\n        return generateLocales(\n            'build/umd/min/locales.custom.js',\n            localeFiles,\n            {skipMoment: true}\n        ).then(function () {\n            grunt.log.ok('build/umd/min/locales.custom.js');\n        }).then(function () {\n            return generateLocales(\n                'build/umd/min/moment-with-locales.custom.js',\n                localeFiles,\n                {skipMoment: false});\n        }).then(function () {\n            grunt.log.ok('build/umd/min/moment-with-locales.custom.js');\n        }).then(function () {\n            var moment = require('../build/umd/min/moment-with-locales.custom.js');\n            if (moment.locales().filter(function (locale) {\n                return locale !== 'en';\n            }).length !== localeFiles.length) {\n                throw new Error(\n                    'You probably specified locales requiring ' +\n                    'parent locale, but didn\\'t specify parent');\n            }\n        }).then(done, function (e) {\n            grunt.log.error('error transpiling-custom', e);\n            done(e);\n        });\n    });\n\n    grunt.config('clean.build', [\n        'build'\n    ]);\n\n    grunt.config('concat.tests', {\n        src: 'build/umd/test/**/*.js',\n        dest: 'build/umd/min/tests.js'\n    });\n\n    grunt.task.registerTask('transpile',\n            'builds all es5 files, optinally creating custom locales',\n            function (locales) {\n        var tasks = [\n            'clean:build',\n            'transpile-raw',\n            'concat:tests'\n        ];\n\n        if (locales) {\n            tasks.push('transpile-custom-raw:' + locales);\n        }\n\n        grunt.task.run(tasks);\n    });\n};\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/tasks/update_index.js",
    "content": "module.exports = function (grunt) {\n    grunt.config('copy.index-files', {\n        expand: true,\n        cwd: 'build/umd/',\n        src: [\n            'moment.js',\n            'locale/*.js',\n            'min/locales.js',\n            'min/moment-with-locales.js',\n            'min/tests.js'\n        ],\n        dest: '.'\n    });\n\n    grunt.registerTask('update-index', ['copy:index-files']);\n};\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/templates/default.js",
    "content": ";(function (global, factory) {\n    typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :\n    typeof define === 'function' && define.amd ? define(factory) :\n    global.moment = factory()\n}(this, (function () { 'use strict';\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/templates/locale-header.js",
    "content": ";(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/templates/test-header.js",
    "content": ";(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/typing-tests/moment-tests.ts",
    "content": "/// <reference path=\"../moment.d.ts\" />\nimport moment = require('../moment');\n\nmoment().add('hours', 1).fromNow();\n\nvar day = new Date(2011, 9, 16);\nvar dayWrapper = moment(day);\nvar otherDay = moment(new Date(2020, 3, 7));\n\nvar day1 = moment(1318781876406);\nvar day2 = moment.unix(1318781876);\nvar day3 = moment(\"Dec 25, 1995\");\nvar day4 = moment(\"12-25-1995\", \"MM-DD-YYYY\");\nvar day5 = moment(\"12-25-1995\", [\"MM-DD-YYYY\", \"YYYY-MM-DD\"]);\nvar day6 = moment(\"05-06-1995\", [\"MM-DD-YYYY\", \"DD-MM-YYYY\"]);\nvar now = moment();\nvar day7 = moment([2010, 1, 14, 15, 25, 50, 125]);\nvar day8 = moment([2010]);\nvar day9 = moment([2010, 6]);\nvar day10 = moment([2010, 6, 10]);\nvar array = [2010, 1, 14, 15, 25, 50, 125];\nvar day11 = moment(Date.UTC.apply({}, array));\nvar day12 = moment.unix(1318781876);\n\n// TODO: reenable in 2.0\n// moment(null);\nmoment(undefined);\nmoment({ years: 2010, months: 3, days: 5, hours: 15, minutes: 10, seconds: 3, milliseconds: 123 });\nmoment(\"20140101\", \"YYYYMMDD\", true);\nmoment(\"20140101\", \"YYYYMMDD\", \"en\");\nmoment(\"20140101\", \"YYYYMMDD\", \"en\", true);\nmoment(\"20140101\", [\"YYYYMMDD\"], true);\nmoment(\"20140101\", [\"YYYYMMDD\"], \"en\");\nmoment(\"20140101\", [\"YYYYMMDD\"], \"en\", true);\n\nmoment(day.toISOString(), moment.ISO_8601);\nmoment(day.toISOString(), moment.ISO_8601, true);\nmoment(day.toISOString(), moment.ISO_8601, \"en\", true);\nmoment(day.toISOString(), [moment.ISO_8601]);\nmoment(day.toISOString(), [moment.ISO_8601], true);\nmoment(day.toISOString(), [moment.ISO_8601], \"en\", true);\n\nvar a = moment([2012]);\nvar b = moment(a);\na.year(2000);\nb.year(); // 2012\n\nmoment.utc();\nmoment.utc(12345);\nmoment.utc([12, 34, 56]);\nmoment.utc({ years: 2010, months: 3, days: 5, hours: 15, minutes: 10, seconds: 3, milliseconds: 123 });\nmoment.utc(\"1-2-3\");\nmoment.utc(\"1-2-3\", \"3-2-1\");\nmoment.utc(\"1-2-3\", \"3-2-1\", true);\nmoment.utc(\"1-2-3\", \"3-2-1\", \"en\");\nmoment.utc(\"1-2-3\", \"3-2-1\", \"en\", true);\nmoment.utc(\"01-01-2014\", [\"DD-MM-YYYY\", \"MM-DD-YYYY\"]);\nmoment.utc(\"01-01-2014\", [\"DD-MM-YYYY\", \"MM-DD-YYYY\"], true);\nmoment.utc(\"01-01-2014\", [\"DD-MM-YYYY\", \"MM-DD-YYYY\"], \"en\");\nmoment.utc(\"01-01-2014\", [\"DD-MM-YYYY\", \"MM-DD-YYYY\"], \"en\", true);\n\nvar a2 = moment.utc([2011, 0, 1, 8]);\na.hours();\na.local();\na.hours();\n\nmoment(\"2011-10-10\", \"YYYY-MM-DD\").isValid();\nmoment(\"2011-10-50\", \"YYYY-MM-DD\").isValid();\nmoment(\"2011-10-10T10:20:90\").isValid();\nmoment([2011, 0, 1]).isValid();\nmoment([2011, 0, 50]).isValid();\nmoment(\"not a date\").isValid();\n\nmoment().add('days', 7).subtract('months', 1).year(2009).hours(0).minutes(0).seconds(0);\n\nmoment().add('days', 7);\nmoment().add('days', 7).add('months', 1);\nmoment().add({days:7,months:1});\nmoment().add('milliseconds', 1000000);\nmoment().add('days', 360);\nmoment([2010, 0, 31]);\nmoment([2010, 0, 31]).add('months', 1);\nvar m = moment(new Date(2011, 2, 12, 5, 0, 0));\nm.hours();\nm.add('days', 1).hours();\nvar m2 = moment(new Date(2011, 2, 12, 5, 0, 0));\nm2.hours();\nm2.add('hours', 24).hours();\nvar duration = moment.duration({'days': 1});\nmoment([2012, 0, 31]).add(duration);\n\nmoment().add('seconds', 1);\nmoment().add(1, 'seconds');\n\nmoment().add('1', 'seconds');\n\nmoment().subtract('days', 7);\n\nmoment().seconds(30);\nmoment().minutes(30);\n\nmoment().hours(12);\nmoment().date(5);\nmoment().day(5);\nmoment().day(\"Sunday\");\nmoment().month(5);\nmoment().month(\"January\");\nmoment().year(1984);\nmoment().startOf('year');\nmoment().month(0).date(1).hours(0).minutes(0).seconds(0).milliseconds(0);\nmoment().startOf('hour');\nmoment().minutes(0).seconds(0).milliseconds(0);\nmoment().weekday();\nmoment().weekday(0);\nmoment().isoWeekday(1);\nmoment().isoWeekday();\nmoment().weekYear(2);\nmoment().weekYear();\nmoment().isoWeekYear(3);\nmoment().isoWeekYear();\nmoment().week();\nmoment().week(45);\nmoment().weeks();\nmoment().weeks(45);\nmoment().isoWeek();\nmoment().isoWeek(45);\nmoment().isoWeeks();\nmoment().isoWeeks(45);\nmoment().dayOfYear();\nmoment().dayOfYear(45);\n\nmoment().set('year', 2013);\nmoment().set('month', 3);  // April\nmoment().set('date', 1);\nmoment().set('hour', 13);\nmoment().set('minute', 20);\nmoment().set('second', 30);\nmoment().set('millisecond', 123);\nmoment().set({'year': 2013, 'month': 3});\n\nvar getMilliseconds: number = moment().milliseconds();\nvar getSeconds: number = moment().seconds();\nvar getMinutes: number = moment().minutes();\nvar getHours: number = moment().hours();\nvar getDate: number = moment().date();\nvar getDay: number = moment().day();\nvar getMonth: number = moment().month();\nvar getQuater: number = moment().quarter();\nvar getYear: number = moment().year();\n\nmoment().hours(0).minutes(0).seconds(0).milliseconds(0);\n\nvar a3 = moment([2011, 0, 1, 8]);\na3.hours();\na3.utc();\na3.hours();\n\nvar a4 = moment([2010, 1, 14, 15, 25, 50, 125]);\na4.format(\"dddd, MMMM Do YYYY, h:mm:ss a\");\na4.format(\"ddd, hA\");\n\nmoment().format('\\\\L');\nmoment().format('[today] DDDD');\n\nvar a5 = moment([2007, 0, 29]);\nvar b5 = moment([2007, 0, 28]);\na5.from(b5);\n\nvar a6 = moment([2007, 0, 29]);\nvar b6 = moment([2007, 0, 28]);\na6.from(b6);\na6.from([2007, 0, 28]);\na6.from(new Date(2007, 0, 28));\na6.from(\"1-28-2007\");\n\nvar a7 = moment();\nvar b7 = moment(\"10-10-1900\", \"MM-DD-YYYY\");\na7.from(b7);\n\nvar start = moment([2007, 0, 5]);\nvar end = moment([2007, 0, 10]);\nstart.from(end);\nstart.from(end, true);\n\nmoment([2007, 0, 29]).fromNow();\nmoment([2007, 0, 29]).fromNow();\nmoment([2007, 0, 29]).fromNow(true);\n\nvar a8 = moment([2007, 0, 29]);\nvar b8 = moment([2007, 0, 28]);\na8.diff(b8) ;\na8.diff(b8, 'days');\na8.diff(b8, 'years')\na8.diff(b8, 'years', true);\n\nmoment([2007, 0, 29]).toDate();\nmoment([2007, 1, 23]).toISOString();\nmoment(1318874398806).valueOf();\nmoment(1318874398806).unix();\nmoment([2000]).isLeapYear();\nmoment().zone();\nmoment().utcOffset();\nmoment(\"2012-2\", \"YYYY-MM\").daysInMonth();\nmoment([2011, 2, 12]).isDST();\n\nmoment.isMoment(new Date());\nmoment.isMoment(moment());\n\nmoment.isDate(new Date());\nmoment.isDate(/regexp/);\n\nmoment.isDuration(new Date());\nmoment.isDuration(moment.duration());\n\nmoment().isBetween(moment(), moment());\nmoment().isBetween(new Date(), new Date());\nmoment().isBetween([1,1,2000], [1,1,2001], \"year\");\n\nmoment.localeData('fr');\nmoment(1316116057189).fromNow();\n\nmoment.localeData('en');\nvar globalLang = moment();\nvar localLang = moment();\nlocalLang.localeData();\nlocalLang.format('LLLL');\nglobalLang.format('LLLL');\n\n// TODO: reenable in 2.0\n// moment.duration(null);\nmoment.duration(undefined);\nmoment.duration(100);\nmoment.duration(2, 'seconds');\nmoment.duration({\n    seconds: 2,\n    minutes: 2,\n    hours: 2,\n    days: 2,\n    weeks: 2,\n    months: 2,\n    years: 2\n});\nmoment.duration({\n    s: 2,\n    m: 2,\n    h: 2,\n    d: 2,\n    w: 2,\n    M: 2,\n    y: 2,\n});\nmoment.duration(1, \"minutes\").humanize();\nmoment.duration(500).milliseconds();\nmoment.duration(500).asMilliseconds();\nmoment.duration(500).seconds();\nmoment.duration(500).asSeconds();\nmoment.duration().minutes();\nmoment.duration().asMinutes();\nmoment.duration().toISOString();\nmoment.duration().toJSON();\n\nvar adur = moment.duration(3, 'd');\nvar bdur = moment.duration(2, 'd');\nadur.subtract(bdur).days();\nadur.subtract(1).days();\nadur.subtract(1, 'd').days();\n\n// Selecting a language\nmoment.locale();\nmoment.locale('en');\nmoment.locale(['en', 'fr']);\n\n// TODO: Reenable in 2.0\n// moment.defineLocale('en', null);\n// moment.updateLocale('en', null);\n// moment.locale('en', null);\n\n// Defining a custom language:\nmoment.locale('en', {\n    months: [\"January\", \"February\", \"March\", \"April\", \"May\", \"June\", \"July\", \"August\", \"September\", \"October\", \"November\", \"December\"],\n    monthsShort: [\"Jan\", \"Feb\", \"Mar\", \"Apr\", \"May\", \"Jun\", \"Jul\", \"Aug\", \"Sep\", \"Oct\", \"Nov\", \"Dec\"],\n    weekdays: [\"Sunday\", \"Monday\", \"Tuesday\", \"Wednesday\", \"Thursday\", \"Friday\", \"Saturday\"],\n    weekdaysShort: [\"Sun\", \"Mon\", \"Tue\", \"Wed\", \"Thu\", \"Fri\", \"Sat\"],\n    weekdaysMin: [\"Su\", \"Mo\", \"Tu\", \"We\", \"Th\", \"Fr\", \"Sa\"],\n    longDateFormat: {\n        LTS: \"h:mm:ss A\",\n        LT: \"h:mm A\",\n        L: \"MM/DD/YYYY\",\n        LL: \"MMMM D YYYY\",\n        LLL: \"MMMM D YYYY LT\",\n        LLLL: \"dddd, MMMM D YYYY LT\"\n    },\n    relativeTime: {\n        future: \"in %s\",\n        past: \"%s ago\",\n        s: \"seconds\",\n        m: \"a minute\",\n        mm: \"%d minutes\",\n        h: \"an hour\",\n        hh: \"%d hours\",\n        d: \"a day\",\n        dd: \"%d days\",\n        M: \"a month\",\n        MM: \"%d months\",\n        y: \"a year\",\n        yy: \"%d years\"\n    },\n    meridiem: function (hour, minute, isLower) {\n        if (hour < 9) {\n            return \"??\";\n        } else if (hour < 11 && minute < 30) {\n            return \"??\";\n        } else if (hour < 13 && minute < 30) {\n            return \"??\";\n        } else if (hour < 18) {\n            return \"??\";\n        } else {\n            return \"??\";\n        }\n    },\n    calendar: {\n        lastDay: '[Yesterday at] LT',\n        sameDay: '[Today at] LT',\n        nextDay: '[Tomorrow at] LT',\n        lastWeek: '[last] dddd [at] LT',\n        nextWeek: 'dddd [at] LT',\n        sameElse: 'L'\n    },\n    ordinal: function (number) {\n        var b = number % 10;\n        return (~~(number % 100 / 10) === 1) ? 'th' :\n            (b === 1) ? 'st' :\n            (b === 2) ? 'nd' :\n            (b === 3) ? 'rd' : 'th';\n    },\n    week: {\n        dow: 1,\n        doy: 4\n    }\n});\n\nmoment.locale('en', {\n    months : [\n        \"January\", \"February\", \"March\", \"April\", \"May\", \"June\", \"July\",\n        \"August\", \"September\", \"October\", \"November\", \"December\"\n    ]\n});\n\nmoment.locale('en', {\n    months : function (momentToFormat: moment.Moment, format: string) {\n        // momentToFormat is the moment currently being formatted\n        // format is the formatting string\n        if (/^MMMM/.test(format)) { // if the format starts with 'MMMM'\n            return this.nominative[momentToFormat.month()];\n        } else {\n            return this.subjective[momentToFormat.month()];\n        }\n    }\n});\n\nmoment.locale('en', {\n    monthsShort : [\n        \"Jan\", \"Feb\", \"Mar\", \"Apr\", \"May\", \"Jun\",\n        \"Jul\", \"Aug\", \"Sep\", \"Oct\", \"Nov\", \"Dec\"\n    ]\n});\n\nmoment.locale('en', {\n    monthsShort : function (momentToFormat: moment.Moment, format: string) {\n        if (/^MMMM/.test(format)) {\n            return this.nominative[momentToFormat.month()];\n        } else {\n            return this.subjective[momentToFormat.month()];\n        }\n    }\n});\n\nmoment.locale('en', {\n    weekdays : [\n        \"Sunday\", \"Monday\", \"Tuesday\", \"Wednesday\", \"Thursday\", \"Friday\", \"Saturday\"\n    ]\n});\n\nmoment.locale('en', {\n    weekdays : function (momentToFormat: moment.Moment) {\n        return this.weekdays[momentToFormat.day()];\n    }\n});\n\nmoment.locale('en', {\n    weekdaysShort : [\"Sun\", \"Mon\", \"Tue\", \"Wed\", \"Thu\", \"Fri\", \"Sat\"]\n});\n\nmoment.locale('en', {\n    weekdaysShort : function (momentToFormat: moment.Moment) {\n        return this.weekdaysShort[momentToFormat.day()];\n    }\n});\n\nmoment.locale('en', {\n    weekdaysMin : [\"Su\", \"Mo\", \"Tu\", \"We\", \"Th\", \"Fr\", \"Sa\"]\n});\n\nmoment.locale('en', {\n    weekdaysMin : function (momentToFormat: moment.Moment) {\n        return this.weekdaysMin[momentToFormat.day()];\n    }\n});\n\nmoment.locale('en', {\n    longDateFormat : {\n        LTS: \"h:mm:ss A\",\n        LT: \"h:mm A\",\n        L: \"MM/DD/YYYY\",\n        l: \"M/D/YYYY\",\n        LL: \"MMMM Do YYYY\",\n        ll: \"MMM D YYYY\",\n        LLL: \"MMMM Do YYYY LT\",\n        lll: \"MMM D YYYY LT\",\n        LLLL: \"dddd, MMMM Do YYYY LT\",\n        llll: \"ddd, MMM D YYYY LT\"\n    }\n});\n\nmoment.locale('en', {\n    longDateFormat : {\n        LTS: \"h:mm A\",\n        LT: \"h:mm A\",\n        L: \"MM/DD/YYYY\",\n        LL: \"MMMM Do YYYY\",\n        LLL: \"MMMM Do YYYY LT\",\n        LLLL: \"dddd, MMMM Do YYYY LT\"\n    }\n});\n\nmoment.locale('en', {\n    relativeTime : {\n        future: \"in %s\",\n        past:   \"%s ago\",\n        s:  \"seconds\",\n        m:  \"a minute\",\n        mm: \"%d minutes\",\n        h:  \"an hour\",\n        hh: \"%d hours\",\n        d:  \"a day\",\n        dd: \"%d days\",\n        M:  \"a month\",\n        MM: \"%d months\",\n        y:  \"a year\",\n        yy: \"%d years\"\n    }\n});\n\nmoment.locale('en', {\n    meridiem : function (hour, minute, isLowercase) {\n        if (hour < 9) {\n            return \"早上\";\n        } else if (hour < 11 && minute < 30) {\n            return \"上午\";\n        } else if (hour < 13 && minute < 30) {\n            return \"中午\";\n        } else if (hour < 18) {\n            return \"下午\";\n        } else {\n            return \"晚上\";\n        }\n    }\n});\n\nmoment.locale('en', {\n    calendar : {\n        lastDay : '[Yesterday at] LT',\n        sameDay : '[Today at] LT',\n        nextDay : function () {\n          return '[hoy a la' + ((this.hours() !== 1) ? 's' : '') + '] LT';\n        },\n        lastWeek : '[last] dddd [at] LT',\n        nextWeek : 'dddd [at] LT',\n        sameElse : 'L'\n    }\n});\n\nmoment.locale('en', {\n    ordinal : function (number) {\n        var b = number % 10;\n        var output = (~~ (number % 100 / 10) === 1) ? 'th' :\n            (b === 1) ? 'st' :\n            (b === 2) ? 'nd' :\n            (b === 3) ? 'rd' : 'th';\n        return number + output;\n    }\n});\n\nconsole.log(moment.version);\n\nmoment.defaultFormat = 'YYYY-MM-DD HH:mm';\n"
  },
  {
    "path": "app_backend/static/plugin/moment-2.18.1/typing-tests/tsconfig.json",
    "content": "{\n  \"compileOnSave\": false,\n  \"compilerOptions\": {\n    \"module\": \"commonjs\",\n    \"noEmit\": true,\n    \"noImplicitAny\": true\n  },\n  \"files\": [\n    \"../moment.d.ts\",\n    \"./moment-tests.ts\"\n  ]\n}\n"
  },
  {
    "path": "app_backend/static/robots.txt",
    "content": "User-agent: *\nDisallow: /\n"
  },
  {
    "path": "app_backend/tasks/README.md",
    "content": "## 订单匹配，短信通知\n\n## 定时对账，账目统计\n\n## 定时统计，定时导出\n\n## 操作日志\n"
  },
  {
    "path": "app_backend/tasks/__init__.py",
    "content": "#!/usr/bin/env python\n# encoding: utf-8\n\n\"\"\"\n@author: zhanghe\n@software: PyCharm\n@file: __init__.py.py\n@time: 2017/4/20 下午5:00\n\"\"\"\n\n\ndef func():\n    pass\n\n\nclass Main(object):\n    def __init__(self):\n        pass\n\n\nif __name__ == '__main__':\n    pass\n"
  },
  {
    "path": "app_backend/tasks/run_stats.py",
    "content": "#!/usr/bin/env python\n# encoding: utf-8\n\n\"\"\"\n@author: zhanghe\n@software: PyCharm\n@file: run_stats.py\n@time: 2017/6/12 下午5:37\n\"\"\"\n\n\ndef func():\n    pass\n\n\nclass Main(object):\n    def __init__(self):\n        pass\n\n\nif __name__ == '__main__':\n    pass\n"
  },
  {
    "path": "app_backend/tasks/run_task.py",
    "content": "#!/usr/bin/env python\n# encoding: utf-8\n\n\"\"\"\n@author: zhanghe\n@software: PyCharm\n@file: run_task.py\n@time: 2017/6/30 下午3:37\n\"\"\"\n\n\ndef func():\n    pass\n\n\nclass Main(object):\n    def __init__(self):\n        pass\n\n\nif __name__ == '__main__':\n    pass\n"
  },
  {
    "path": "app_backend/templates/404.html",
    "content": "{% extends \"layout.html\" %}\n\n{% block content %}\n<div class=\"container-fluid\">\n    <div class=\"col-md-8 col-sm-offset-2 text-center\">\n        <h2 class=\"sub-header\">404</h2>\n    </div>\n</div>\n{% endblock %}"
  },
  {
    "path": "app_backend/templates/500.html",
    "content": "{% extends \"layout.html\" %}\n\n{% block content %}\n<div class=\"container-fluid\">\n    <div class=\"col-md-8 col-sm-offset-2 text-center\">\n        <h2 class=\"sub-header\">500</h2>\n    </div>\n</div>\n{% endblock %}"
  },
  {
    "path": "app_backend/templates/_left.html",
    "content": "<div class=\"navbar-default sidebar\" role=\"navigation\">\n    <div class=\"sidebar-nav navbar-collapse\">\n        <ul class=\"nav\" id=\"side-menu\">\n            <li class=\"sidebar-search\">\n                <div class=\"input-group custom-search-form\">\n                    <input type=\"text\" class=\"form-control\" placeholder=\"Search...\">\n                    <span class=\"input-group-btn\">\n                        <button class=\"btn btn-default\" type=\"button\">\n                            <i class=\"fa fa-search\"></i>\n                        </button>\n                    </span>\n                </div>\n                <!-- /input-group -->\n            </li>\n            <li>\n                <a href=\"/\"><i class=\"fa fa-dashboard fa-fw\"></i> 后台首页</a>\n            </li>\n\n            <li class=\"active\">\n                <a id=\"menu-user\" href=\"#\"><i class=\"fa fa-table fa-fw\"></i> 会员管理<span class=\"fa arrow\"></span></a>\n                <ul class=\"nav nav-second-level\">\n                    <li>\n                        <a href=\"{{ url_for('user.lists') }}\">会员列表</a>\n                    </li>\n{#                    <li>#}\n{#                        <a href=\"{{ url_for('user.add') }}\">会员添加</a>#}\n{#                    </li>#}\n                    <li>\n                        <a href=\"{{ url_for('user.relationship') }}\">会员关系</a>\n                    </li>\n                </ul>\n                <!-- /.nav-second-level -->\n            </li>\n            <li{% if 'active' in request.path %} class=\"active\"{% endif %}>\n                <a id=\"menu-active\" href=\"#\"><i class=\"fa fa-users fa-fw\"></i> 激活管理<span class=\"fa arrow\"></span></a>\n                <ul class=\"nav nav-second-level\">\n                    <li>\n                        <a href=\"{{ url_for('active.lists') }}\">激活列表</a>\n                    </li>\n                    <li>\n                        <a href=\"{{ url_for('active.add') }}\">赠送激活码</a>\n                    </li>\n                </ul>\n            </li>\n            <li{% if 'scheduling' in request.path %} class=\"active\"{% endif %}>\n                <a id=\"menu-scheduling\" href=\"#\"><i class=\"fa fa-money fa-fw\"></i> 排单管理<span class=\"fa arrow\"></span></a>\n                <ul class=\"nav nav-second-level\">\n                    <li>\n                        <a href=\"{{ url_for('scheduling.lists') }}\">排单币表</a>\n                    </li>\n                    <li>\n                        <a href=\"{{ url_for('scheduling.add') }}\">发送排单币</a>\n                    </li>\n                </ul>\n            </li>\n\n            <li>\n                <a id=\"menu-order\" href=\"#\"><i class=\"fa fa-edit fa-fw\"></i> 订单管理<span class=\"fa arrow\"></span></a>\n                <ul class=\"nav nav-second-level\">\n                    <li>\n                        <a href=\"{{ url_for('order.lists', status_rec=0) }}\">订单列表 - 进行中</a>\n                    </li>\n                    <li>\n                        <a href=\"{{ url_for('order.lists', status_rec=1) }}\">订单列表 - 已完成</a>\n                    </li>\n                    <li>\n                        <a href=\"{{ url_for('apply_put.lists') }}\">投资申请列表</a>\n                    </li>\n                    <li>\n                        <a href=\"{{ url_for('apply_get.lists') }}\">提现申请列表</a>\n                    </li>\n                    <li>\n                        <a href=\"{{ url_for('apply_put.add') }}\">添加投资申请</a>\n                    </li>\n                    <li>\n                        <a href=\"{{ url_for('apply_get.add') }}\">添加提现申请</a>\n                    </li>\n                </ul>\n                <!-- /.nav-second-level -->\n            </li>\n            <li>\n                <a id=\"menu-message\" href=\"#\"><i class=\"fa fa-files-o fa-fw\"></i> 留言管理<span class=\"fa arrow\"></span></a>\n                <ul class=\"nav nav-second-level\">\n                    <li>\n                        <a href=\"{{ url_for('message.lists') }}\">留言列表</a>\n                    </li>\n                    <li>\n                        <a href=\"{{ url_for('complaint.lists') }}\">投诉列表</a>\n                    </li>\n                </ul>\n                <!-- /.nav-second-level -->\n            </li>\n            <li{% if 'settings' in request.path %} class=\"active\"{% endif %}>\n                <a id=\"menu-settings\" href=\"#\"><i class=\"fa fa-sitemap fa-fw\"></i> 系统配置<span class=\"fa arrow\"></span></a>\n                <ul class=\"nav nav-second-level\">\n                    <li>\n                        <a href=\"{{ url_for('settings.switch') }}\">开关配置</a>\n                    </li>\n                    <li>\n                        <a href=\"{{ url_for('settings.user') }}\">会员配置</a>\n                    </li>\n                    <li>\n                        <a href=\"{{ url_for('settings.order') }}\">订单配置</a>\n                    </li>\n                    <li>\n                        <a href=\"{{ url_for('settings.apply_put') }}\">投资配置</a>\n                    </li>\n                    <li>\n                        <a href=\"{{ url_for('settings.apply_get') }}\">提现配置</a>\n                    </li>\n                    <li>\n                        <a href=\"{{ url_for('settings.interest') }}\">利息配置</a>\n                    </li>\n                </ul>\n                <!-- /.nav-second-level -->\n            </li>\n            <li{% if 'admin' in request.path %} class=\"active\"{% endif %}>\n                <a id=\"menu-admin\" href=\"#\"><i class=\"fa fa-files-o fa-fw\"></i> 权限管理<span class=\"fa arrow\"></span></a>\n                <ul class=\"nav nav-second-level\">\n                    <li>\n                        <a href=\"{{ url_for('admin.lists') }}\"{% if url_for('admin.lists') == request.path %} class=\"active\"{% endif %}>后台成员</a>\n                    </li>\n                    <li>\n                        <a href=\"{{ url_for('admin.add') }}\"{% if url_for('admin.add') == request.path %} class=\"active\"{% endif %}>添加成员</a>\n                    </li>\n                    <li>\n                        <a href=\"{{ url_for('admin.role') }}\"{% if url_for('admin.role') == request.path %} class=\"active\"{% endif %}>角色管理</a>\n                    </li>\n                </ul>\n                <!-- /.nav-second-level -->\n            </li>\n            <li{% if 'stats' in request.path %} class=\"active\"{% endif %}>\n                <a id=\"menu-stats\" href=\"#\"><i class=\"fa fa-bar-chart-o fa-fw\"></i> 运营统计<span class=\"fa arrow\"></span></a>\n                <ul class=\"nav nav-second-level\">\n                    <li>\n                        <a href=\"{{ url_for('stats.user') }}\"{% if url_for('stats.user') == request.path %} class=\"active\"{% endif %}>用户统计</a>\n                    </li>\n                    <li>\n                        <a href=\"{{ url_for('stats.apply_put') }}\"{% if url_for('stats.apply_put') == request.path %} class=\"active\"{% endif %}>投资统计</a>\n                    </li>\n                    <li>\n                        <a href=\"{{ url_for('stats.apply_get') }}\"{% if url_for('stats.apply_get') == request.path %} class=\"active\"{% endif %}>提现统计</a>\n                    </li>\n                    <li>\n                        <a href=\"{{ url_for('stats.order') }}\"{% if url_for('stats.order') == request.path %} class=\"active\"{% endif %}>订单统计</a>\n                    </li>\n                    <li>\n                        <a href=\"{{ url_for('wallet.stats') }}\">钱包统计</a>\n                    </li>\n                    <li>\n                        <a href=\"{{ url_for('score.stats') }}\">积分统计</a>\n                    </li>\n                </ul>\n                <!-- /.nav-second-level -->\n            </li>\n        </ul>\n    </div>\n    <!-- /.sidebar-collapse -->\n</div>\n"
  },
  {
    "path": "app_backend/templates/_top.html",
    "content": "<div class=\"navbar-header\">\n    <button type=\"button\" class=\"navbar-toggle\" data-toggle=\"collapse\" data-target=\".navbar-collapse\">\n        <span class=\"sr-only\">Toggle navigation</span>\n        <span class=\"icon-bar\"></span>\n        <span class=\"icon-bar\"></span>\n        <span class=\"icon-bar\"></span>\n    </button>\n    <a class=\"navbar-brand\" href=\"/\">后台管理</a>\n</div>\n<!-- /.navbar-header -->\n\n<ul class=\"nav navbar-top-links navbar-right\">\n    <!-- /.dropdown -->\n    <li class=\"dropdown\">\n        <a class=\"dropdown-toggle\" data-toggle=\"dropdown\" href=\"#\">\n            <i class=\"fa fa-user fa-fw\"></i> {{ current_user.username }} [{{ current_user.role_id | role_admin }}] <i class=\"fa fa-caret-down\"></i>\n        </a>\n        <ul class=\"dropdown-menu dropdown-user\">\n            <li><a href=\"{{ url_for('admin.profile') }}\"><i class=\"fa fa-user fa-fw\"></i> 个人中心</a>\n            </li>\n            <li class=\"divider\"></li>\n            <li><a href=\"{{ url_for('logout') }}\"><i class=\"fa fa-sign-out fa-fw\"></i> 退出登录</a>\n            </li>\n        </ul>\n        <!-- /.dropdown-user -->\n    </li>\n    <!-- /.dropdown -->\n</ul>"
  },
  {
    "path": "app_backend/templates/active/add.html",
    "content": "<!-- extend from base layout -->\n{% extends \"layout.html\" %}\n\n{% block content %}\n    <div class=\"container\">\n    <ol class=\"breadcrumb\">\n        <li><a href=\"/\">首页</a></li>\n        <li class=\"active\">激活中心</li>\n        <li class=\"active\">赠送激活</li>\n    </ol>\n    <form class=\"form-horizontal\" method=\"post\" action=\"\">\n        {{ form.csrf_token }}\n        <div class=\"form-group{% if form.user_id.errors %} has-error{% endif %}\">\n            {{ form.user_id.label(class=\"col-sm-2 control-label\") }}\n            <div class=\"col-sm-10\">\n                {{ form.user_id(class=\"form-control\", placeholder=\"填写赠送用户ID\") }}\n                {% for error in form.user_id.errors %}\n                    <span class=\"help-block\">{{ error }}</span>\n                {% endfor %}\n            </div>\n        </div>\n        <div class=\"form-group{% if form.amount.errors %} has-error{% endif %}\">\n            {{ form.amount.label(class=\"col-sm-2 control-label\") }}\n            <div class=\"col-sm-10\">\n                {{ form.amount(class=\"form-control\", placeholder=\"填写赠送数量\", type=\"number\", min=\"1\") }}\n                {% for error in form.amount.errors %}\n                    <span class=\"help-block\">{{ error }}</span>\n                {% endfor %}\n                <span class=\"help-block\">赠送数量必须为整数 [当前剩余激活码数量：{{ form.user_id.data | user_active }}]</span>\n            </div>\n        </div>\n        <div class=\"form-group\">\n            <div class=\"col-sm-offset-2 col-sm-10\">\n                <button type=\"submit\" class=\"btn btn-success btn-load\" data-loading-text=\"赠送中\">赠送</button>\n                <button type=\"reset\" class=\"btn btn-default\">重新填写</button>\n                <button class=\"btn btn-default\" onclick=\"history.back();\">返回</button>\n            </div>\n        </div>\n    </form>\n    </div>\n{% endblock %}\n"
  },
  {
    "path": "app_backend/templates/active/list.html",
    "content": "<!-- extend from base layout -->\n{% extends \"layout.html\" %}\n\n{% block extra_css %}\n\n{% endblock %}\n\n{% block content %}\n    <div class=\"container\">\n    <!-- header -->\n    <nav class=\"sub-header row container-fluid\">\n        <ol class=\"breadcrumb\">\n            <li><a href=\"/\">首页</a></li>\n            <li><a href=\"javascript:void(0);\" onclick=\"$('#menu-active').trigger('click');\">激活管理</a></li>\n            <li class=\"active\">激活列表</li>\n        </ol>\n        <div class=\"btn-group pull-right\" role=\"group\" aria-label=\"...\">\n            {% if not request.query_string %}\n            <a type=\"button\" class=\"btn btn-default active\">系统赠送</a>\n            <a type=\"button\" class=\"btn btn-default\" href=\"{{ url_for('active.lists', active_list_type=2) }}\">会员转赠</a>\n            <a type=\"button\" class=\"btn btn-default\" href=\"{{ url_for('active.lists', active_list_type=3) }}\">上游激活</a>\n            <a type=\"button\" class=\"btn btn-default\" href=\"{{ url_for('active.lists', active_list_type=4) }}\">自行激活</a>\n            {% elif request.query_string==\"active_list_type=2\" %}\n            <a type=\"button\" class=\"btn btn-default\" href=\"{{ url_for('active.lists') }}\">系统赠送</a>\n            <a type=\"button\" class=\"btn btn-default active\">会员转赠</a>\n            <a type=\"button\" class=\"btn btn-default\" href=\"{{ url_for('active.lists', active_list_type=3) }}\">上游激活</a>\n            <a type=\"button\" class=\"btn btn-default\" href=\"{{ url_for('active.lists', active_list_type=4) }}\">自行激活</a>\n            {% elif request.query_string==\"active_list_type=3\" %}\n            <a type=\"button\" class=\"btn btn-default\" href=\"{{ url_for('active.lists') }}\">系统赠送</a>\n            <a type=\"button\" class=\"btn btn-default\" href=\"{{ url_for('active.lists', active_list_type=2) }}\">会员转赠</a>\n            <a type=\"button\" class=\"btn btn-default active\">上游激活</a>\n            <a type=\"button\" class=\"btn btn-default\" href=\"{{ url_for('active.lists', active_list_type=4) }}\">自行激活</a>\n            {% elif request.query_string==\"active_list_type=4\" %}\n            <a type=\"button\" class=\"btn btn-default\" href=\"{{ url_for('active.lists') }}\">系统赠送</a>\n            <a type=\"button\" class=\"btn btn-default\" href=\"{{ url_for('active.lists', active_list_type=2) }}\">会员转赠</a>\n            <a type=\"button\" class=\"btn btn-default\" href=\"{{ url_for('active.lists', active_list_type=3) }}\">上游激活</a>\n            <a type=\"button\" class=\"btn btn-default active\">自行激活</a>\n            {% endif %}\n        </div>\n    </nav>\n\n    <hr/>\n    <!-- content -->\n    <div class=\"table-responsive\">\n        {# <table class=\"table table-striped\"> #}\n        <table class=\"table table-hover\">\n            <thead>\n            <tr>\n                <th>激活明细ID</th>\n                <th>赠送用户</th>\n                <th>接收用户</th>\n                <th>类型</th>\n                <th>数量</th>\n                <th>时间</th>\n            </tr>\n            </thead>\n            <tbody>\n            {% for active, user_profile_put, user_profile_get in pagination.items %}\n            <tr class=\"text-muted\">\n                <td>{{ active.id }}</td>\n                <td>{{ user_profile_put.nickname | default('系统赠送') }} [{{ active.user_id }}]</td>\n                <td>{{ user_profile_get.nickname }} [{{ active.sc_id }}]</td>\n                <td>{{ active.type | type_active }}</td>\n                <td>{{ active.amount }}</td>\n                <td>{{ moment(active.create_time).format('YYYY-MM-DD HH:mm:ss') }}</td>\n            </tr>\n            {% endfor %}\n            </tbody>\n        </table>\n        {# 翻页 #}\n        {% from \"macros.html\" import render_pagination %}\n        {{ render_pagination(pagination, 'active.lists') }}\n    </div>\n    </div>\n{% endblock %}\n\n{% block extra_js %}\n\n{% endblock %}\n"
  },
  {
    "path": "app_backend/templates/admin/add.html",
    "content": "{% extends \"layout.html\" %}\n\n{% block content %}\n<div class=\"container-fluid\">\n    <ol class=\"breadcrumb\">\n        <li><a href=\"/\">后台管理</a></li>\n        <li><a href=\"javascript:void(0);\" onclick=\"$('#menu-admin').trigger('click');\">权限管理</a></li>\n        <li class=\"active\">添加成员</li>\n    </ol>\n    {# 表单 #}\n    <form class=\"form-horizontal\" method=\"post\" action=\"\">\n        {{ form.csrf_token }}\n        {# 标签导航 #}\n\n        <div class=\"form-group{% if form.username.errors %} has-error{% endif %}\">\n            {{ form.username.label(class=\"col-sm-2 control-label\") }}\n            <div class=\"col-sm-10\">\n                {{ form.username(class=\"form-control\", placeholder=\"管理账号\", minlength=\"2\", maxlength=\"20\") }}\n                {% for error in form.username.errors %}\n                    <span class=\"help-block\">{{ error }}</span>\n                {% endfor %}\n            </div>\n        </div>\n        <div class=\"form-group{% if form.password.errors %} has-error{% endif %}\">\n            {{ form.password.label(class=\"col-sm-2 control-label\") }}\n            <div class=\"col-sm-10\">\n                {{ form.password(class=\"form-control\", placeholder=\"登录密码[6-20位]\", minlength=\"6\", maxlength=\"20\") }}\n                {% for error in form.password.errors %}\n                    <span class=\"help-block\">{{ error }}</span>\n                {% endfor %}\n            </div>\n        </div>\n        <div class=\"form-group{% if form.area_id.errors %} has-error{% endif %}\">\n            {{ form.area_id.label(class=\"col-sm-2 control-label\") }}\n            <div class=\"col-sm-10\">\n                {{ form.area_id(data_header=\"选择手机区号\") }}\n                {% for error in form.area_id.errors %}\n                    <span class=\"help-block\">{{ error }}</span>\n                {% endfor %}\n            </div>\n        </div>\n        <div class=\"form-group{% if form.phone.errors %} has-error{% endif %}\">\n            {{ form.phone.label(class=\"col-sm-2 control-label\") }}\n            <div class=\"col-sm-10\">\n                {{ form.phone(class=\"form-control\", placeholder=\"手机号码\", type=\"tel\", maxlength=11) }}\n                {% for error in form.phone.errors %}\n                    <span class=\"help-block\">{{ error }}</span>\n                {% endfor %}\n            </div>\n        </div>\n        <div class=\"form-group{% if form.role_id.errors %} has-error{% endif %}\">\n            {{ form.role_id.label(class=\"col-sm-2 control-label\") }}\n            <div class=\"col-sm-10\">\n                {{ form.role_id(class=\"form-control\", placeholder=\"管理角色\", data_width=\"fit\", data_header=\"选择角色\") }}\n                {% for error in form.role_id.errors %}\n                    <span class=\"help-block\">{{ error }}</span>\n                {% endfor %}\n            </div>\n        </div>\n        <div class=\"form-group\">\n            <div class=\"col-sm-offset-2 col-sm-10\">\n                <button type=\"submit\" class=\"btn btn-default btn-load\" data-loading-text=\"添加中\">添加</button>\n                <button type=\"reset\" class=\"btn btn-default\">重新填写</button>\n            </div>\n        </div>\n    </form>\n\n\n    </div>\n\n{% endblock %}\n\n{% block extra_js %}\n<script>\n    // 初始化赋值\n    var area_id = $('#area_id');\n    area_id.selectpicker('val', '{{ form.area_id.data }}');\n    // 处理选项修改\n    area_id.on('changed.bs.select', function (event, clickedIndex, newValue, oldValue) {\n        // console.log($('#area_id').val());\n        // console.log(event);\n        // console.log(clickedIndex);\n        // console.log(newValue);\n        // console.log(oldValue);\n    });\n\n    // 初始化赋值\n    var role_id = $('#role_id');\n    role_id.selectpicker('val', '{{ form.role_id.data }}');\n    // 处理选项修改\n    role_id.on('changed.bs.select', function (event, clickedIndex, newValue, oldValue) {\n        // console.log($('#role_id').val());\n        // console.log(event);\n        // console.log(clickedIndex);\n        // console.log(newValue);\n        // console.log(oldValue);\n    });\n</script>\n{% endblock %}\n"
  },
  {
    "path": "app_backend/templates/admin/edit.html",
    "content": "{% extends \"layout.html\" %}\n\n{% block content %}\n<div class=\"container-fluid\">\n    <ol class=\"breadcrumb\">\n        <li><a href=\"/\">后台管理</a></li>\n        <li><a href=\"javascript:void(0);\" onclick=\"$('#menu-admin').trigger('click');\">权限管理</a></li>\n        <li class=\"active\">编辑成员</li>\n    </ol>\n\n    {# 表单 #}\n    <form class=\"form-horizontal\" method=\"post\" action=\"\">\n        {{ form.csrf_token }}\n        {# 标签导航 #}\n\n        <div class=\"form-group{% if form.username.errors %} has-error{% endif %}\">\n            {{ form.username.label(class=\"col-sm-2 control-label\") }}\n            <div class=\"col-sm-10\">\n                {{ form.username(class=\"form-control\", placeholder=\"管理账号\", minlength=\"2\", maxlength=\"20\") }}\n                {% for error in form.username.errors %}\n                    <span class=\"help-block\">{{ error }}</span>\n                {% endfor %}\n            </div>\n        </div>\n        <div class=\"form-group{% if form.password.errors %} has-error{% endif %}\">\n            {{ form.password.label(class=\"col-sm-2 control-label\") }}\n            <div class=\"col-sm-10\">\n                {{ form.password(class=\"form-control\", placeholder=\"登录密码[6-20位]，若无需更改，请留空\", maxlength=\"20\") }}\n                {% for error in form.password.errors %}\n                    <span class=\"help-block\">{{ error }}</span>\n                {% endfor %}\n            </div>\n        </div>\n        <div class=\"form-group{% if form.area_id.errors %} has-error{% endif %}\">\n            {{ form.area_id.label(class=\"col-sm-2 control-label\") }}\n            <div class=\"col-sm-10\">\n                {{ form.area_id(data_header=\"选择手机区号\") }}\n                {% for error in form.area_id.errors %}\n                    <span class=\"help-block\">{{ error }}</span>\n                {% endfor %}\n            </div>\n        </div>\n        <div class=\"form-group{% if form.phone.errors %} has-error{% endif %}\">\n            {{ form.phone.label(class=\"col-sm-2 control-label\") }}\n            <div class=\"col-sm-10\">\n                {{ form.phone(class=\"form-control\", placeholder=\"手机号码\", type=\"tel\", maxlength=11) }}\n                {% for error in form.phone.errors %}\n                    <span class=\"help-block\">{{ error }}</span>\n                {% endfor %}\n            </div>\n        </div>\n        <div class=\"form-group{% if form.role_id.errors %} has-error{% endif %}\">\n            {{ form.role_id.label(class=\"col-sm-2 control-label\") }}\n            <div class=\"col-sm-10\">\n                {{ form.role_id(class=\"form-control\", placeholder=\"管理角色\", data_width=\"fit\", data_header=\"选择角色\") }}\n                {% for error in form.role_id.errors %}\n                    <span class=\"help-block\">{{ error }}</span>\n                {% endfor %}\n            </div>\n        </div>\n        <div class=\"form-group{% if form.create_time.errors %} has-error{% endif %}\">\n            {{ form.create_time.label(class=\"col-sm-2 control-label\") }}\n            <div class=\"col-sm-10\">\n                <div class=\"form-control\">\n                    {{ moment(form.create_time.data).format('YYYY-MM-DD HH:mm:ss') }}\n                </div>\n                {% for error in form.create_time.errors %}\n                    <span class=\"help-block\">{{ error }}</span>\n                {% endfor %}\n            </div>\n        </div>\n        <div class=\"form-group{% if form.update_time.errors %} has-error{% endif %}\">\n            {{ form.update_time.label(class=\"col-sm-2 control-label\") }}\n            <div class=\"col-sm-10\">\n                <div class=\"form-control\">\n                    {{ moment(form.update_time.data).format('YYYY-MM-DD HH:mm:ss') }}\n                </div>\n                {% for error in form.update_time.errors %}\n                    <span class=\"help-block\">{{ error }}</span>\n                {% endfor %}\n            </div>\n        </div>\n        <div class=\"form-group\">\n            <div class=\"col-sm-offset-2 col-sm-10\">\n                <button type=\"submit\" class=\"btn btn-success btn-load\" data-loading-text=\"编辑中\">编辑</button>\n                <button type=\"reset\" class=\"btn btn-default\">重新填写</button>\n            </div>\n        </div>\n    </form>\n\n</div>\n\n{% endblock %}\n\n{% block extra_js %}\n<script>\n    // 初始化赋值\n    var area_id = $('#area_id');\n    area_id.selectpicker('val', '{{ form.area_id.data }}');\n    // 处理选项修改\n    area_id.on('changed.bs.select', function (event, clickedIndex, newValue, oldValue) {\n        // console.log($('#area_id').val());\n        // console.log(event);\n        // console.log(clickedIndex);\n        // console.log(newValue);\n        // console.log(oldValue);\n    });\n\n    // 初始化赋值\n    var role_id = $('#role_id');\n    role_id.selectpicker('val', '{{ form.role_id.data }}');\n    // 处理选项修改\n    role_id.on('changed.bs.select', function (event, clickedIndex, newValue, oldValue) {\n        // console.log($('#role_id').val());\n        // console.log(event);\n        // console.log(clickedIndex);\n        // console.log(newValue);\n        // console.log(oldValue);\n    });\n</script>\n{% endblock %}\n"
  },
  {
    "path": "app_backend/templates/admin/list.html",
    "content": "{% extends \"layout.html\" %}\n\n{% block content %}\n<div class=\"container-fluid\">\n    <ol class=\"breadcrumb\">\n        <li><a href=\"/\">后台管理</a></li>\n        <li><a href=\"javascript:void(0);\" onclick=\"$('#menu-admin').trigger('click');\">权限管理</a></li>\n        <li class=\"active\">后台成员</li>\n    </ol>\n\n    <div class=\"table-responsive\">\n        {# <table class=\"table table-striped\"> #}\n        <table class=\"table table-hover\">\n            <thead>\n            <tr>\n                <th>id</th>\n                <th>管理账号</th>\n{#                <th>area_id</th>#}\n                <th>手机区号</th>\n                <th>手机号码</th>\n                <th>角色</th>\n                <th>删除状态</th>\n                <th>登录时间</th>\n                <th>登录IP</th>\n                <th>创建时间</th>\n                <th>更新时间</th>\n                <th>操作</th>\n            </tr>\n            </thead>\n            <tbody>\n            {% for admin in pagination.items %}\n            <tr class=\"text-muted\">\n                <td>{{ admin.id }}</td>\n                <td>{{ admin.username }}</td>\n{#                <td>{{ admin.area_id }}</td>#}\n                <td>{{ admin.area_code }}</td>\n                <td>{{ admin.phone }}</td>\n                <td>{{ admin.role_id | role_admin }}</td>\n                <td>{{ admin.status_delete | status_delete }}</td>\n                <td>{% if admin.login_time %}{{ moment(admin.login_time).format('YYYY-MM-DD HH:mm:ss') }}{% endif %}</td>\n                <td>{% if admin.login_ip %}{{ admin.login_ip }}{% endif %}</td>\n                <td>{{ moment(admin.create_time).format('YYYY-MM-DD HH:mm:ss') }}</td>\n                <td>{{ moment(admin.update_time).format('YYYY-MM-DD HH:mm:ss') }}</td>\n                <td>\n                    <a href=\"{{ url_for('admin.edit', admin_id=admin.id, next=request.path) }}\" rel=\"tooltip\" title=\"编辑\"><span class=\"glyphicon glyphicon-pencil\"></span></a>\n                    <a href=\"javascript:void(0);\" onclick=\"admin_delete({{ admin.id }});\" rel=\"tooltip\" title=\"删除\"><span class=\"glyphicon glyphicon-trash\"></span></a>\n                </td>\n            </tr>\n            {% endfor %}\n            </tbody>\n        </table>\n        {# 翻页 #}\n        {% from \"macros.html\" import render_pagination %}\n        {{ render_pagination(pagination, 'admin.lists') }}\n    </div>\n</div>\n\n{% endblock %}\n\n{% block extra_js %}\n<script>\n// 成员删除\nfunction admin_delete(admin_uid){\n    if(confirm(\"删除数据不能恢复，是否确认删除?\"))\n    {\n        // console.log(admin_uid);\n        $.getJSON('{{ url_for('admin.ajax_delete') }}',\n        {\n            admin_uid: admin_uid\n        }, function (result) {\n            if(result.hasOwnProperty('error')){\n                alert(result.error);\n            }else {\n                alert(result.success);\n                window.location.reload();\n            }\n        });\n        return false;\n    }\n}\n</script>\n{% endblock %}\n"
  },
  {
    "path": "app_backend/templates/admin/profile.html",
    "content": "{% extends \"layout.html\" %}\n\n{% block content %}\n<div class=\"container-fluid\">\n    <ol class=\"breadcrumb\">\n        <li><a href=\"/\">后台管理</a></li>\n        <li><a href=\"javascript:void(0);\" onclick=\"$('#menu-admin').trigger('click');\">运营管理</a></li>\n        <li class=\"active\">个人中心</li>\n    </ol>\n    {# 表单 #}\n    <form class=\"form-horizontal\" method=\"post\" action=\"\">\n        {{ form.csrf_token }}\n        {# 标签导航 #}\n\n        <div class=\"form-group{% if form.username.errors %} has-error{% endif %}\">\n            {{ form.username.label(class=\"col-sm-2 control-label\") }}\n            <div class=\"col-sm-10\">\n                {{ form.username(class=\"form-control\", placeholder=\"管理账号\", minlength=\"2\", maxlength=\"20\") }}\n                {% for error in form.username.errors %}\n                    <span class=\"help-block\">{{ error }}</span>\n                {% endfor %}\n            </div>\n        </div>\n        <div class=\"form-group{% if form.password.errors %} has-error{% endif %}\">\n            {{ form.password.label(class=\"col-sm-2 control-label\") }}\n            <div class=\"col-sm-10\">\n                {{ form.password(class=\"form-control\", placeholder=\"登录密码[6-20位]，若无需更改，请留空\", maxlength=\"20\") }}\n                {% for error in form.password.errors %}\n                    <span class=\"help-block\">{{ error }}</span>\n                {% endfor %}\n            </div>\n        </div>\n        <div class=\"form-group{% if form.area_id.errors %} has-error{% endif %}\">\n            {{ form.area_id.label(class=\"col-sm-2 control-label\") }}\n            <div class=\"col-sm-10\">\n                {{ form.area_id(data_header=\"选择手机区号\") }}\n                {% for error in form.area_id.errors %}\n                    <span class=\"help-block\">{{ error }}</span>\n                {% endfor %}\n            </div>\n        </div>\n        <div class=\"form-group{% if form.phone.errors %} has-error{% endif %}\">\n            {{ form.phone.label(class=\"col-sm-2 control-label\") }}\n            <div class=\"col-sm-10\">\n                {{ form.phone(class=\"form-control\", placeholder=\"手机号码\", type=\"tel\", maxlength=11) }}\n                {% for error in form.phone.errors %}\n                    <span class=\"help-block\">{{ error }}</span>\n                {% endfor %}\n            </div>\n        </div>\n        <div class=\"form-group{% if form.role_id.errors %} has-error{% endif %}\">\n            {{ form.role_id.label(class=\"col-sm-2 control-label\") }}\n            <div class=\"col-sm-10\">\n                {{ form.role_id(class=\"form-control\", placeholder=\"管理角色\", data_width=\"fit\", data_header=\"选择角色\") }}\n                {% for error in form.role_id.errors %}\n                    <span class=\"help-block\">{{ error }}</span>\n                {% endfor %}\n            </div>\n        </div>\n        <div class=\"form-group{% if form.create_time.errors %} has-error{% endif %}\">\n            {{ form.create_time.label(class=\"col-sm-2 control-label\") }}\n            <div class=\"col-sm-10\">\n                <div class=\"form-control\">\n                    {{ moment(form.create_time.data).format('YYYY-MM-DD HH:mm:ss') }}\n                </div>\n                {% for error in form.create_time.errors %}\n                    <span class=\"help-block\">{{ error }}</span>\n                {% endfor %}\n            </div>\n        </div>\n        <div class=\"form-group{% if form.update_time.errors %} has-error{% endif %}\">\n            {{ form.update_time.label(class=\"col-sm-2 control-label\") }}\n            <div class=\"col-sm-10\">\n                <div class=\"form-control\">\n                    {{ moment(form.update_time.data).format('YYYY-MM-DD HH:mm:ss') }}\n                </div>\n                {% for error in form.update_time.errors %}\n                    <span class=\"help-block\">{{ error }}</span>\n                {% endfor %}\n            </div>\n        </div>\n        <div class=\"form-group\">\n            <div class=\"col-sm-offset-2 col-sm-10\">\n                <button type=\"submit\" class=\"btn btn-success btn-load\" data-loading-text=\"编辑中\">编辑</button>\n                <button type=\"reset\" class=\"btn btn-default\">重新填写</button>\n            </div>\n        </div>\n    </form>\n\n</div>\n\n{% endblock %}\n\n{% block extra_js %}\n<script>\n    // 初始化赋值\n    var area_id = $('#area_id');\n    area_id.selectpicker('val', '{{ form.area_id.data }}');\n    // 处理选项修改\n    area_id.on('changed.bs.select', function (event, clickedIndex, newValue, oldValue) {\n        // console.log($('#area_id').val());\n        // console.log(event);\n        // console.log(clickedIndex);\n        // console.log(newValue);\n        // console.log(oldValue);\n    });\n\n    // 初始化赋值\n    var role_id = $('#role_id');\n    role_id.selectpicker('val', '{{ form.role_id.data }}');\n    // 处理选项修改\n    role_id.on('changed.bs.select', function (event, clickedIndex, newValue, oldValue) {\n        // console.log($('#role_id').val());\n        // console.log(event);\n        // console.log(clickedIndex);\n        // console.log(newValue);\n        // console.log(oldValue);\n    });\n</script>\n{% endblock %}\n"
  },
  {
    "path": "app_backend/templates/admin/role.html",
    "content": "{% extends \"layout.html\" %}\n\n{% block content %}\n<div class=\"container-fluid\">\n    <ol class=\"breadcrumb\">\n        <li><a href=\"/\">后台管理</a></li>\n        <li><a href=\"javascript:void(0);\" onclick=\"$('#menu-settings').trigger('click');\">权限管理</a></li>\n        <li class=\"active\">角色管理</li>\n    </ol>\n\n    {# 表单 #}\n    <form class=\"form-horizontal\" method=\"post\" action=\"\">\n        {{ form.csrf_token }}\n        <p></p>\n        <div class=\"form-group{% if form.role_id.errors %} has-error{% endif %}\">\n            {{ form.role_id.label(class=\"col-sm-2 control-label\") }}\n            <div class=\"col-sm-10\">\n                {{ form.role_id(class=\"form-control\", placeholder=\"管理角色\", data_width=\"fit\", data_header=\"选择角色\") }}\n                {% for error in form.role_id.errors %}\n                    <span class=\"help-block\">{{ error }}</span>\n                {% endfor %}\n            </div>\n        </div>\n        <div class=\"form-group{% if form.module.errors %} has-error{% endif %}\">\n            {{ form.module.label(class=\"col-sm-2 control-label\") }}\n            <div class=\"col-sm-10\">\n                {{ form.module(class=\"form-control\", placeholder=\"权限模块\", maxlength=\"256\") }}\n                {% for error in form.module.errors %}\n                    <span class=\"help-block\">{{ error }}</span>\n                {% endfor %}\n                <span class=\"help-block\">模块名称：会员,订单,留言,系统,权限,统计(半角逗号分隔)</span>\n            </div>\n        </div>\n        <div class=\"form-group{% if form.note.errors %} has-error{% endif %}\">\n            {{ form.note.label(class=\"col-sm-2 control-label\") }}\n            <div class=\"col-sm-10\">\n                {{ form.note(class=\"form-control\", placeholder=\"权限备注\", maxlength=\"256\") }}\n                {% for error in form.note.errors %}\n                    <span class=\"help-block\">{{ error }}</span>\n                {% endfor %}\n            </div>\n        </div>\n\n        <div class=\"form-group\">\n            <div class=\"col-sm-offset-2 col-sm-10\">\n                <button type=\"submit\" class=\"btn btn-success btn-load\" data-loading-text=\"保存中\">保存</button>\n                <button type=\"reset\" class=\"btn btn-default\">重新填写</button>\n            </div>\n        </div>\n    </form>\n\n</div>\n\n{% endblock %}\n\n{% block extra_js %}\n<script>\n    // 初始化赋值\n    var role_id = $('#role_id');\n    role_id.selectpicker('val', '{{ form.role_id.data }}');\n    // 处理选项修改\n    role_id.on('changed.bs.select', function (event, clickedIndex, newValue, oldValue) {\n        // console.log($('#role_id').val());\n        window.location.href = '{{ url_for('admin.role') }}' + '?role_id=' + $('#role_id').val();\n        // console.log(event);\n        // console.log(clickedIndex);\n        // console.log(newValue);\n        // console.log(oldValue);\n    });\n</script>\n{% endblock %}\n\n"
  },
  {
    "path": "app_backend/templates/apply_get/add.html",
    "content": "{% extends \"layout.html\" %}\n\n{% block content %}\n<div class=\"container-fluid\">\n    <ol class=\"breadcrumb\">\n        <li><a href=\"/\">后台管理</a></li>\n        <li><a href=\"javascript:void(0);\" onclick=\"$('#menu-order').trigger('click');\">订单管理</a></li>\n        <li class=\"active\">添加提现申请</li>\n    </ol>\n    <h2 class=\"sub-header\">Apply Get Add!</h2>\n\n\n</div>\n\n{% endblock %}"
  },
  {
    "path": "app_backend/templates/apply_get/info.html",
    "content": "<!-- extend from base layout -->\n{% extends \"layout.html\" %}\n\n{% block extra_css %}\n\n{% endblock %}\n\n{% block content %}\n    <div class=\"container-fluid\">\n    <ol class=\"breadcrumb\">\n        <li><a href=\"/\">后台管理</a></li>\n        <li><a href=\"javascript:void(0);\" onclick=\"$('#menu-order').trigger('click');\">订单管理</a></li>\n        <li class=\"active\">提现匹配</li>\n    </ol>\n{#    <h2 class=\"sub-header\">Apply Get Matcher!</h2>#}\n    <section id=\"apply_put_info\">\n        <div class=\"panel panel-default\">\n        <div class=\"panel-heading\">\n            <strong class=\"panel-title\">提现申请详情\n                {% if apply_get_info.money_apply > apply_get_info.money_order %}\n                <i>[ 待匹配金额：{{ apply_get_info.money_apply - apply_get_info.money_order }} ]</i>\n                {% endif %}\n            <span class=\"glyphicon glyphicon-cog pull-right\"></span>\n            </strong>\n        </div>\n        <table class=\"table\">\n            <thead>\n                <tr>\n                    <th>提现ID</th>\n                    <th>用户ID</th>\n                    <th>用户名称</th>\n                    <th>申请类型</th>\n                    <th>申请金额</th>\n                    <th>订单金额</th>\n                    <th>申请状态</th>\n                    <th>订单状态</th>\n                    <th>删除状态</th>\n                    <th>申请时间</th>\n                    <th>是否允许拆分</th>\n                </tr>\n            </thead>\n            <tbody>\n                <tr>\n                    <td>{{ apply_get_info.id }}</td>\n                    <td>{{ apply_get_info.user_id }}</td>\n                    <td>{{ apply_get_info.user_id | nickname }}</td>\n                    <td>{{ apply_get_info.type_apply | type_apply }}</td>\n                    <td>{{ apply_get_info.money_apply }}</td>\n                    <td>{{ apply_get_info.money_order }}</td>\n                    <td>{{ apply_get_info.status_apply | status_apply }}</td>\n                    <td>{{ apply_get_info.status_order | status_order }}</td>\n                    <td>{{ apply_get_info.status_delete | status_delete }}</td>\n                    <td>{{ moment(apply_get_info.create_time).format('YYYY-MM-DD HH:mm:ss') }}</td>\n                    <td>\n                        <label><input title=\"选择\" type=\"checkbox\" id=\"apply_get_accept_split\" value=\"1\" /> 允许拆分</label>\n                    </td>\n                </tr>\n            </tbody>\n        </table>\n        </div>\n    </section>\n    {% if apply_get_info.status_order > STATUS_ORDER_HANDING | int %}\n    <section id=\"apply_match_get_info\">\n        <div class=\"panel panel-default\">\n        <div class=\"panel-heading\">\n            <strong class=\"panel-title\">匹配订单列表\n            <span class=\"glyphicon glyphicon-cog pull-right\"></span>\n            </strong>\n        </div>\n        <table class=\"table table-hover table-responsive\">\n            <thead>\n                <tr>\n                    <th>订单ID</th>\n                    <th>用户ID</th>\n                    <th>用户名称</th>\n                    <th>订单类型</th>\n                    <th>订单金额</th>\n                    <th>审核状态</th>\n                    <th>支付状态</th>\n                    <th>收款状态</th>\n                    <th>删除状态</th>\n                    <th>订单时间</th>\n                </tr>\n            </thead>\n            <tbody>\n                {% for order_info, apply_put_info in apply_put_list %}\n                <tr>\n                    <td>{{ order_info.id }}</td>\n                    <td>{{ order_info.apply_put_uid }}</td>\n                    <td>{{ order_info.apply_put_uid | nickname }}</td>\n                    <td>{{ order_info.type | type_order }}</td>\n                    <td>{{ order_info.money }}</td>\n                    <td>{{ order_info.status_audit | status_audit }}</td>\n                    <td>{{ order_info.status_pay | status_pay }}</td>\n                    <td>{{ order_info.status_rec | status_rec }}</td>\n                    <td>{{ order_info.status_delete | status_delete }}</td>\n                    <td>{{ moment(order_info.create_time).format('YYYY-MM-DD HH:mm:ss') }}</td>\n                </tr>\n                {% endfor %}\n            </tbody>\n        </table>\n        </div>\n    </section>\n    {% endif %}\n\n    {% if apply_get_info.status_order < STATUS_ORDER_COMPLETED | int %}\n    <section id=\"apply_get_list\">\n        <div class=\"panel panel-default\">\n        <div class=\"panel-heading\">\n            <strong class=\"panel-title\">投资申请列表\n            <span class=\"glyphicon glyphicon-cog pull-right\"></span>\n            </strong>\n        </div>\n        <div class=\"panel-body\">\n        <form class=\"form-inline\">\n{#            <div class=\"form-group{% if form.apply_get_id.errors %} has-error{% endif %}\">#}\n{#                {{ form.apply_get_id.label(class=\"sr-only\") }}#}\n{#                {{ form.apply_get_id(class=\"form-control\", placeholder=\"Apply Get Id\") }}#}\n{#                {% for error in form.apply_get_id.errors %}#}\n{#                    <span class=\"help-block\">{{ error }}</span>#}\n{#                {% endfor %}#}\n{#            </div>#}\n{#            <div class=\"form-group{% if form.user_id.errors %} has-error{% endif %}\">#}\n{#                {{ form.user_id.label(class=\"sr-only\") }}#}\n{#                {{ form.user_id(class=\"form-control\", placeholder=\"User Id\") }}#}\n{#                {% for error in form.user_id.errors %}#}\n{#                    <span class=\"help-block\">{{ error }}</span>#}\n{#                {% endfor %}#}\n{#            </div>#}\n{#            <div class=\"form-group{% if form.type_apply.errors %} has-error{% endif %}\">#}\n{#                {{ form.type_apply.label(class=\"sr-only\") }}#}\n{#                {{ form.type_apply(class=\"form-control\", placeholder=\"申请类型\", data_width=\"fit\", data_header=\"选择类型\") }}#}\n{#                {% for error in form.type_apply.errors %}#}\n{#                    <span class=\"help-block\">{{ error }}</span>#}\n{#                {% endfor %}#}\n{#            </div>#}\n            <div class=\"form-group{% if form.min_money.errors %} has-error{% endif %}\">\n                {{ form.min_money.label(class=\"\") }}\n                {{ form.min_money(class=\"form-control\", placeholder=\"min money\", type=\"number\", min=\"100\", max=\"100000\", step=\"100\") }}\n                {% for error in form.min_money.errors %}\n                    <span class=\"help-block\">{{ error }}</span>\n                {% endfor %}\n            </div>\n            <div class=\"form-group{% if form.max_money.errors %} has-error{% endif %}\">\n                {{ form.max_money.label(class=\"\") }}\n                {{ form.max_money(class=\"form-control\", placeholder=\"max money\", type=\"number\", min=\"100\", max=\"100000\", step=\"100\") }}\n                {% for error in form.max_money.errors %}\n                    <span class=\"help-block\">{{ error }}</span>\n                {% endfor %}\n            </div>\n            <div class=\"form-group{% if form.start_time.errors %} has-error{% endif %}\">\n                {{ form.start_time.label(class=\"\") }}\n                {{ form.start_time(class=\"form-control\", placeholder=\"start_time\", type='date') }}\n                {% for error in form.start_time.errors %}\n                    <span class=\"help-block\">{{ error }}</span>\n                {% endfor %}\n            </div>\n            <div class=\"form-group{% if form.end_time.errors %} has-error{% endif %}\">\n                {{ form.end_time.label(class=\"\") }}\n                {{ form.end_time(class=\"form-control\", placeholder=\"end_time\", type='date') }}\n                {% for error in form.end_time.errors %}\n                    <span class=\"help-block\">{{ error }}</span>\n                {% endfor %}\n            </div>\n\n            <button type=\"submit\" class=\"btn btn-primary\" name=\"op\" value=\"0\">Search</button>\n        </form>\n\n\n        <hr/>\n        <form onsubmit=\"apply_get_match(this)\">\n        <input type=\"hidden\" name=\"apply_get_id\" value=\"{{ apply_get_info.id }}\">\n        <input type=\"hidden\" id=\"accept_split\" name=\"accept_split\" value=\"\">\n        <div class=\"container-fluid\">\n            <div class=\"btn-group pull-right\" role=\"group\" aria-label=\"...\">\n                <button type=\"button\" class=\"btn btn-default\">金额:<i id=\"amount-money\">0</i></button>\n                <button type=\"submit\" class=\"btn btn-success btn-load\" data-loading-text=\"匹配中\" autocomplete=\"off\" id=\"match-submit\">匹配</button>\n            </div>\n        </div>\n\n        <div class=\"table-responsive\">\n            {# <table class=\"table table-striped\"> #}\n            <table class=\"table table-hover\">\n                <thead>\n                <tr>\n                    <th>提现ID</th>\n                    <th>用户ID</th>\n                    <th>用户名称</th>\n                    <th>申请类型</th>\n                    <th>申请金额</th>\n                    <th>申请状态</th>\n                    <th>订单状态</th>\n                    <th>删除状态</th>\n                    <th>申请时间</th>\n                    <th>操作</th>\n                </tr>\n                </thead>\n                <tbody>\n                {% for apply_put, user_profile in pagination.items %}\n                <tr class=\"text-muted apply_put_check_tr\">\n                    <td>{{ apply_put.id }}</td>\n                    <td>{{ apply_put.user_id }}</td>\n                    <td>{{ user_profile.nickname }}</td>\n                    <td>{{ apply_put.type_apply | type_apply }}</td>\n                    <td>{{ apply_put.money_apply }}</td>\n                    <td>{{ apply_put.status_apply | status_apply }}</td>\n                    <td>{{ apply_put.status_order | status_order }}</td>\n                    <td>{{ apply_put.status_delete | status_delete }}</td>\n                    <td>{{ moment(apply_put.create_time).format('YYYY-MM-DD HH:mm:ss') }}</td>\n                    <td>\n                        <label><input title=\"选择\" type=\"checkbox\" class=\"apply_put_check\" name=\"apply_put_id\" id=\"{{ apply_put.money_apply }}\" value=\"{{ apply_put.id }}\" /> 选择</label>\n                    </td>\n                </tr>\n                {% endfor %}\n                </tbody>\n            </table>\n            {# 翻页 #}\n            {% from \"macros.html\" import render_pagination %}\n            {{ render_pagination(pagination, 'user.lists') }}\n        </div>\n        </form>\n        </div>\n        </div>\n    </section>\n    {% endif %}\n\n    </div>\n{% endblock %}\n\n{% block extra_js %}\n<script>\n    // 初始化赋值\n    var type_apply = $('#type_apply');\n    type_apply.selectpicker('val', '{{ form.type_apply.data }}');\n    // 处理选项修改\n    type_apply.on('changed.bs.select', function (event, clickedIndex, newValue, oldValue) {\n        // console.log($('#status_lock').val());\n        // console.log(event);\n        // console.log(clickedIndex);\n        // console.log(newValue);\n        // console.log(oldValue);\n    });\n\n    // 提现匹配\n    function apply_get_match(form) {\n        //console.log($(form).serialize());\n        $.ajax({\n            url: \"{{ url_for('apply_get.ajax_match') }}\",\n            type: 'POST',\n            data: $(form).serialize(),\n            dataType: 'json',\n            success: function (result) {\n                // console.log(result);\n                if(result.hasOwnProperty('error')){\n                    alert(result.error);\n                }else {\n                    alert(result.success);\n                }\n            }\n        });\n        //$(form).button('reset');  // 重置表单 恢复保存按钮\n        // todo 更新 tr 数据(blog_id)\n        return false;\n    }\n    // 计算金额\n    $(function(){\n        //数据行单击选中\n{#        $('.apply_put_check_tr').click(function () {#}\n{#            //console.log($(this).children(\"td\").children(\"input.apply_put_check\"));#}\n{#            $(this).children(\"td\").children(\"input.apply_put_check\").trigger(\"click\");#}\n{#        });#}\n        //选中状态变化同步更新选中金额\n        $('.apply_put_check').change(function () {\n            var sum=0;\n            $(\"input.apply_put_check:checkbox:checked\").each(function(){\n                sum+= parseInt(this.id);\n            });\n            $('#amount-money').html(sum);\n        });\n        //选中允许拆分\n        $('#apply_get_accept_split').change(function () {\n            //console.log($(this).prop(\"checked\"));\n            if($(this).prop(\"checked\") == true){\n                $('#accept_split').val('1');\n            }else {\n                $('#accept_split').val('');\n            }\n        });\n    });\n</script>\n{% endblock %}\n"
  },
  {
    "path": "app_backend/templates/apply_get/list.html",
    "content": "<!-- extend from base layout -->\n{% extends \"layout.html\" %}\n\n{% block extra_css %}\n\n{% endblock %}\n\n{% block content %}\n    <div class=\"container-fluid\">\n    <ol class=\"breadcrumb\">\n        <li><a href=\"/\">后台管理</a></li>\n        <li><a href=\"javascript:void(0);\" onclick=\"$('#menu-order').trigger('click');\">订单管理</a></li>\n        <li class=\"active\">提现列表</li>\n    </ol>\n\n    <form class=\"form-inline\">\n        <div class=\"form-group{% if form.apply_get_id.errors %} has-error{% endif %}\">\n            {{ form.apply_get_id.label(class=\"sr-only\") }}\n            {{ form.apply_get_id(class=\"form-control\", placeholder=\"提现申请ID\") }}\n            {% for error in form.apply_get_id.errors %}\n                <span class=\"help-block\">{{ error }}</span>\n            {% endfor %}\n        </div>\n        <div class=\"form-group{% if form.user_id.errors %} has-error{% endif %}\">\n            {{ form.user_id.label(class=\"sr-only\") }}\n            {{ form.user_id(class=\"form-control\", placeholder=\"用户ID\") }}\n            {% for error in form.user_id.errors %}\n                <span class=\"help-block\">{{ error }}</span>\n            {% endfor %}\n        </div>\n        <div class=\"form-group{% if form.type_apply.errors %} has-error{% endif %}\">\n            {{ form.type_apply.label(class=\"sr-only\") }}\n            {{ form.type_apply(class=\"form-control\", placeholder=\"申请类型\", data_width=\"fit\", data_header=\"选择类型\") }}\n            {% for error in form.type_apply.errors %}\n                <span class=\"help-block\">{{ error }}</span>\n            {% endfor %}\n        </div>\n        <div class=\"form-group{% if form.status_order.errors %} has-error{% endif %}\">\n            {{ form.status_order.label(class=\"sr-only\") }}\n            {{ form.status_order(class=\"form-control\", placeholder=\"订单状态\", data_width=\"fit\", data_header=\"选择状态\") }}\n            {% for error in form.status_order.errors %}\n                <span class=\"help-block\">{{ error }}</span>\n            {% endfor %}\n        </div>\n        <div class=\"form-group{% if form.status_delete.errors %} has-error{% endif %}\">\n            {{ form.status_delete.label(class=\"sr-only\") }}\n            {{ form.status_delete(class=\"form-control\", placeholder=\"删除状态\", data_width=\"fit\", data_header=\"选择状态\") }}\n            {% for error in form.status_delete.errors %}\n                <span class=\"help-block\">{{ error }}</span>\n            {% endfor %}\n        </div>\n        <div class=\"form-group{% if form.start_time.errors %} has-error{% endif %}\">\n            {{ form.start_time.label(class=\"sr-only\") }}\n            {{ form.start_time(class=\"form-control\", placeholder=\"start_time\", type='date') }}\n            {% for error in form.start_time.errors %}\n                <span class=\"help-block\">{{ error }}</span>\n            {% endfor %}\n        </div>\n        <div class=\"form-group{% if form.end_time.errors %} has-error{% endif %}\">\n            {{ form.end_time.label(class=\"sr-only\") }}\n            {{ form.end_time(class=\"form-control\", placeholder=\"end_time\", type='date') }}\n            {% for error in form.end_time.errors %}\n                <span class=\"help-block\">{{ error }}</span>\n            {% endfor %}\n        </div>\n\n        <button type=\"submit\" class=\"btn btn-primary\" name=\"op\" value=\"0\">Search</button>\n        <button type=\"submit\" class=\"btn btn-primary\" name=\"op\" value=\"1\">Export</button>\n    </form>\n\n    <hr/>\n\n    <div class=\"table-responsive\">\n        {# <table class=\"table table-striped\"> #}\n        <table class=\"table table-hover\">\n            <thead>\n            <tr>\n                <th>ID</th>\n                <th>用户ID</th>\n                <th>用户名称</th>\n                <th>申请类型</th>\n                <th>申请金额</th>\n                <th>订单金额</th>\n                <th>申请状态</th>\n                <th>订单状态</th>\n                <th>删除状态</th>\n                <th>申请时间</th>\n                <th>操作</th>\n            </tr>\n            </thead>\n            <tbody>\n            {% for apply_get, user_profile in pagination.items %}\n            <tr class=\"text-muted\">\n                <td>{{ apply_get.id }}</td>\n                <td>{{ apply_get.user_id }}</td>\n                <td>{{ user_profile.nickname }}</td>\n                <td>{{ apply_get.type_apply | type_apply }}</td>\n                <td>{{ apply_get.money_apply }}</td>\n                <td>{{ apply_get.money_order }}</td>\n                <td>{{ apply_get.status_apply | status_apply }}</td>\n                <td>{{ apply_get.status_order | status_order }}</td>\n                <td>{{ apply_get.status_delete | status_delete }}</td>\n                <td>{{ moment(apply_get.create_time).format('YYYY-MM-DD HH:mm:ss') }}</td>\n                <td>\n                    <a href=\"{{ url_for('apply_get.info', apply_get_id=apply_get.id) }}\" rel=\"tooltip\" title=\"匹配\"><span class=\"glyphicon glyphicon-retweet\"></span></a>\n                    <a href=\"javascript:void(0);\" onclick=\"apply_get_delete({{ apply_get.id }});\" rel=\"tooltip\" title=\"删除\"><span class=\"glyphicon glyphicon-trash\"></span></a>\n                </td>\n            </tr>\n            {% endfor %}\n            </tbody>\n        </table>\n        {# 翻页 #}\n        {% from \"macros.html\" import render_pagination %}\n        {{ render_pagination(pagination, 'apply_get.lists') }}\n    </div>\n    </div>\n{% endblock %}\n\n{% block extra_js %}\n<script>\n    // 初始化赋值\n    var type_apply = $('#type_apply');\n    type_apply.selectpicker('val', '{{ form.type_apply.data }}');\n    // 处理选项修改\n    type_apply.on('changed.bs.select', function (event, clickedIndex, newValue, oldValue) {\n        // console.log($('#type_apply').val());\n        // console.log(event);\n        // console.log(clickedIndex);\n        // console.log(newValue);\n        // console.log(oldValue);\n    });\n\n    var status_order = $('#status_order');\n    status_order.selectpicker('val', '{{ form.status_order.data }}');\n    // 处理选项修改\n    status_order.on('changed.bs.select', function (event, clickedIndex, newValue, oldValue) {\n        // console.log($('#status_order').val());\n        // console.log(event);\n        // console.log(clickedIndex);\n        // console.log(newValue);\n        // console.log(oldValue);\n    });\n\n    var status_delete = $('#status_delete');\n    status_delete.selectpicker('val', '{{ form.status_delete.data }}');\n    // 处理选项修改\n    status_delete.on('changed.bs.select', function (event, clickedIndex, newValue, oldValue) {\n        // console.log($('#status_delete').val());\n        // console.log(event);\n        // console.log(clickedIndex);\n        // console.log(newValue);\n        // console.log(oldValue);\n    });\n\n    // 提现删除\n    function apply_get_delete(apply_get_id){\n        if(confirm(\"删除数据不能恢复，是否确认删除?\"))\n        {\n            // console.log(apply_get_id);\n            $.getJSON('{{ url_for('apply_get.ajax_delete') }}',\n            {\n                apply_get_id: apply_get_id\n            }, function (result) {\n                if(result.hasOwnProperty('error')){\n                    alert(result.error);\n                }else {\n                    alert(result.success);\n                    window.location.reload();\n                }\n            });\n            return false;\n        }\n    }\n</script>\n{% endblock %}\n"
  },
  {
    "path": "app_backend/templates/apply_get/stats.html",
    "content": "{% extends \"layout.html\" %}\n\n{% block content %}\n<div class=\"container-fluid\">\n    <ol class=\"breadcrumb\">\n        <li><a href=\"/\">后台管理</a></li>\n        <li><a href=\"javascript:void(0);\" onclick=\"$('#menu-stats').trigger('click');\">运营统计</a></li>\n        <li class=\"active\">提现统计</li>\n    </ol>\n    <h2 class=\"sub-header\">Apply Get Stats!</h2>\n\n\n</div>\n\n{% endblock %}"
  },
  {
    "path": "app_backend/templates/apply_put/add.html",
    "content": "{% extends \"layout.html\" %}\n\n{% block content %}\n<div class=\"container-fluid\">\n    <ol class=\"breadcrumb\">\n        <li><a href=\"/\">后台管理</a></li>\n        <li><a href=\"javascript:void(0);\" onclick=\"$('#menu-order').trigger('click');\">订单管理</a></li>\n        <li class=\"active\">添加投资申请</li>\n    </ol>\n    <h2 class=\"sub-header\">Apply Put Add!</h2>\n\n\n</div>\n\n{% endblock %}"
  },
  {
    "path": "app_backend/templates/apply_put/info.html",
    "content": "<!-- extend from base layout -->\n{% extends \"layout.html\" %}\n\n{% block extra_css %}\n\n{% endblock %}\n\n{% block content %}\n    <div class=\"container-fluid\">\n    <ol class=\"breadcrumb\">\n        <li><a href=\"/\">后台管理</a></li>\n        <li><a href=\"javascript:void(0);\" onclick=\"$('#menu-order').trigger('click');\">订单管理</a></li>\n        <li class=\"active\">投资匹配</li>\n    </ol>\n{#    <h2 class=\"sub-header\">Apply Put Matcher!</h2>#}\n    <section id=\"apply_put_info\">\n        <div class=\"panel panel-default\">\n        <div class=\"panel-heading\">\n            <strong class=\"panel-title\">投资申请详情\n            {% if apply_put_info.money_apply > apply_put_info.money_order %}\n            <i>[ 待匹配金额：{{ apply_put_info.money_apply - apply_put_info.money_order }} ]</i>\n            {% endif %}\n            <span class=\"glyphicon glyphicon-cog pull-right\"></span>\n            </strong>\n        </div>\n        <table class=\"table\">\n            <thead>\n                <tr>\n                    <th>投资ID</th>\n                    <th>用户ID</th>\n                    <th>用户名称</th>\n                    <th>申请类型</th>\n                    <th>申请金额</th>\n                    <th>订单金额</th>\n                    <th>申请状态</th>\n                    <th>订单状态</th>\n                    <th>删除状态</th>\n                    <th>申请时间</th>\n                    <th>是否允许拆分</th>\n                </tr>\n            </thead>\n            <tbody>\n                <tr>\n                    <td>{{ apply_put_info.id }}</td>\n                    <td>{{ apply_put_info.user_id }}</td>\n                    <td>{{ apply_put_info.user_id | nickname }}</td>\n                    <td>{{ apply_put_info.type_apply | type_apply }}</td>\n                    <td>{{ apply_put_info.money_apply }}</td>\n                    <td>{{ apply_put_info.money_order }}</td>\n                    <td>{{ apply_put_info.status_apply | status_apply }}</td>\n                    <td>{{ apply_put_info.status_order | status_order }}</td>\n                    <td>{{ apply_put_info.status_delete | status_delete }}</td>\n                    <td>{{ moment(apply_put_info.create_time).format('YYYY-MM-DD HH:mm:ss') }}</td>\n                    <td>\n                        <label><input title=\"选择\" type=\"checkbox\" id=\"apply_put_accept_split\" value=\"1\" /> 允许拆分</label>\n                    </td>\n                </tr>\n            </tbody>\n        </table>\n        </div>\n    </section>\n    {% if apply_put_info.status_order > STATUS_ORDER_HANDING | int %}\n    <section id=\"apply_match_get_info\">\n        <div class=\"panel panel-default\">\n        <div class=\"panel-heading\">\n            <strong class=\"panel-title\">匹配订单列表\n            <span class=\"glyphicon glyphicon-cog pull-right\"></span>\n            </strong>\n        </div>\n        <table class=\"table table-hover table-responsive\">\n            <thead>\n                <tr>\n                    <th>订单ID</th>\n                    <th>用户ID</th>\n                    <th>用户名称</th>\n                    <th>订单类型</th>\n                    <th>订单金额</th>\n                    <th>审核状态</th>\n                    <th>支付状态</th>\n                    <th>收款状态</th>\n                    <th>删除状态</th>\n                    <th>订单时间</th>\n                </tr>\n            </thead>\n            <tbody>\n                {% for order_info, apply_get_info in apply_get_list %}\n                <tr>\n                    <td>{{ order_info.id }}</td>\n                    <td>{{ order_info.apply_get_uid }}</td>\n                    <td>{{ order_info.apply_get_uid | nickname }}</td>\n                    <td>{{ order_info.type | type_order }}</td>\n                    <td>{{ order_info.money }}</td>\n                    <td>{{ order_info.status_audit | status_audit }}</td>\n                    <td>{{ order_info.status_pay | status_pay }}</td>\n                    <td>{{ order_info.status_rec | status_rec }}</td>\n                    <td>{{ order_info.status_delete | status_delete }}</td>\n                    <td>{{ moment(order_info.create_time).format('YYYY-MM-DD HH:mm:ss') }}</td>\n                </tr>\n                {% endfor %}\n            </tbody>\n        </table>\n        </div>\n    </section>\n    {% endif %}\n\n    {% if apply_put_info.status_order < STATUS_ORDER_COMPLETED | int %}\n    <section id=\"apply_get_list\">\n        <div class=\"panel panel-default\">\n        <div class=\"panel-heading\">\n            <strong class=\"panel-title\">提现申请列表\n            <span class=\"glyphicon glyphicon-cog pull-right\"></span>\n            </strong>\n        </div>\n        <div class=\"panel-body\">\n        <form class=\"form-inline\">\n{#            <div class=\"form-group{% if form.apply_get_id.errors %} has-error{% endif %}\">#}\n{#                {{ form.apply_get_id.label(class=\"sr-only\") }}#}\n{#                {{ form.apply_get_id(class=\"form-control\", placeholder=\"Apply Get Id\") }}#}\n{#                {% for error in form.apply_get_id.errors %}#}\n{#                    <span class=\"help-block\">{{ error }}</span>#}\n{#                {% endfor %}#}\n{#            </div>#}\n{#            <div class=\"form-group{% if form.user_id.errors %} has-error{% endif %}\">#}\n{#                {{ form.user_id.label(class=\"sr-only\") }}#}\n{#                {{ form.user_id(class=\"form-control\", placeholder=\"User Id\") }}#}\n{#                {% for error in form.user_id.errors %}#}\n{#                    <span class=\"help-block\">{{ error }}</span>#}\n{#                {% endfor %}#}\n{#            </div>#}\n{#            <div class=\"form-group{% if form.type_apply.errors %} has-error{% endif %}\">#}\n{#                {{ form.type_apply.label(class=\"sr-only\") }}#}\n{#                {{ form.type_apply(class=\"form-control\", placeholder=\"申请类型\", data_width=\"fit\", data_header=\"选择类型\") }}#}\n{#                {% for error in form.type_apply.errors %}#}\n{#                    <span class=\"help-block\">{{ error }}</span>#}\n{#                {% endfor %}#}\n{#            </div>#}\n            <div class=\"form-group{% if form.min_money.errors %} has-error{% endif %}\">\n                {{ form.min_money.label(class=\"\") }}\n                {{ form.min_money(class=\"form-control\", placeholder=\"min money\", type=\"number\", min=\"100\", max=\"100000\", step=\"100\") }}\n                {% for error in form.min_money.errors %}\n                    <span class=\"help-block\">{{ error }}</span>\n                {% endfor %}\n            </div>\n            <div class=\"form-group{% if form.max_money.errors %} has-error{% endif %}\">\n                {{ form.max_money.label(class=\"\") }}\n                {{ form.max_money(class=\"form-control\", placeholder=\"max money\", type=\"number\", min=\"100\", max=\"100000\", step=\"100\") }}\n                {% for error in form.max_money.errors %}\n                    <span class=\"help-block\">{{ error }}</span>\n                {% endfor %}\n            </div>\n            <div class=\"form-group{% if form.start_time.errors %} has-error{% endif %}\">\n                {{ form.start_time.label(class=\"\") }}\n                {{ form.start_time(class=\"form-control\", placeholder=\"start_time\", type='date') }}\n                {% for error in form.start_time.errors %}\n                    <span class=\"help-block\">{{ error }}</span>\n                {% endfor %}\n            </div>\n            <div class=\"form-group{% if form.end_time.errors %} has-error{% endif %}\">\n                {{ form.end_time.label(class=\"\") }}\n                {{ form.end_time(class=\"form-control\", placeholder=\"end_time\", type='date') }}\n                {% for error in form.end_time.errors %}\n                    <span class=\"help-block\">{{ error }}</span>\n                {% endfor %}\n            </div>\n\n            <button type=\"submit\" class=\"btn btn-primary\" name=\"op\" value=\"0\">Search</button>\n        </form>\n\n\n        <hr/>\n        <form onsubmit=\"apply_put_match(this)\">\n        <input type=\"hidden\" name=\"apply_put_id\" value=\"{{ apply_put_info.id }}\">\n        <input type=\"hidden\" id=\"accept_split\" name=\"accept_split\" value=\"\">\n        <div class=\"container-fluid\">\n            <div class=\"btn-group pull-right\" role=\"group\" aria-label=\"...\">\n                <button type=\"button\" class=\"btn btn-default\">金额:<i id=\"amount-money\">0</i></button>\n                <button type=\"submit\" class=\"btn btn-success btn-load\" data-loading-text=\"匹配中\" autocomplete=\"off\" id=\"match-submit\">匹配</button>\n            </div>\n        </div>\n\n        <div class=\"table-responsive\">\n            {# <table class=\"table table-striped\"> #}\n            <table class=\"table table-hover\">\n                <thead>\n                <tr>\n                    <th>提现ID</th>\n                    <th>用户ID</th>\n                    <th>用户名称</th>\n                    <th>申请类型</th>\n                    <th>申请金额</th>\n                    <th>申请状态</th>\n                    <th>订单状态</th>\n                    <th>删除状态</th>\n                    <th>申请时间</th>\n                    <th>操作</th>\n                </tr>\n                </thead>\n                <tbody>\n                {% for apply_get, user_profile in pagination.items %}\n                <tr class=\"text-muted\">\n                    <td>{{ apply_get.id }}</td>\n                    <td>{{ apply_get.user_id }}</td>\n                    <td>{{ user_profile.nickname }}</td>\n                    <td>{{ apply_get.type_apply | type_apply }}</td>\n                    <td>{{ apply_get.money_apply }}</td>\n                    <td>{{ apply_get.status_apply | status_apply }}</td>\n                    <td>{{ apply_get.status_order | status_order }}</td>\n                    <td>{{ apply_get.status_delete | status_delete }}</td>\n                    <td>{{ moment(apply_get.create_time).format('YYYY-MM-DD HH:mm:ss') }}</td>\n                    <td>\n                        <label><input title=\"选择\" type=\"checkbox\" class=\"apply_get_check\" name=\"apply_get_id\" id=\"{{ apply_get.money_apply }}\" value=\"{{ apply_get.id }}\" /> 选择</label>\n                    </td>\n                </tr>\n                {% endfor %}\n                </tbody>\n            </table>\n            {# 翻页 #}\n            {% from \"macros.html\" import render_pagination %}\n            {{ render_pagination(pagination, 'user.lists') }}\n        </div>\n        </form>\n        </div>\n        </div>\n    </section>\n    {% endif %}\n\n    </div>\n{% endblock %}\n\n{% block extra_js %}\n<script>\n    // 初始化赋值\n    var type_apply = $('#type_apply');\n    type_apply.selectpicker('val', '{{ form.type_apply.data }}');\n    // 处理选项修改\n    type_apply.on('changed.bs.select', function (event, clickedIndex, newValue, oldValue) {\n        // console.log($('#status_lock').val());\n        // console.log(event);\n        // console.log(clickedIndex);\n        // console.log(newValue);\n        // console.log(oldValue);\n    });\n\n    // 投资匹配\n    function apply_put_match(form) {\n        //console.log($(form).serialize());\n        $.ajax({\n            url: \"{{ url_for('apply_put.ajax_match') }}\",\n            type: 'POST',\n            data: $(form).serialize(),\n            dataType: 'json',\n            success: function (result) {\n                // console.log(result);\n                if(result.hasOwnProperty('error')){\n                    alert(result.error);\n                }else {\n                    alert(result.success);\n                }\n            }\n        });\n        //$(form).button('reset');  // 重置表单 恢复保存按钮\n        // todo 更新 tr 数据(blog_id)\n        return false;\n    }\n    // 计算金额\n    $(function(){\n        //选中状态变化同步更新选中金额\n        $('.apply_get_check').change(function () {\n            var sum=0;\n            $(\"input.apply_get_check:checkbox:checked\").each(function(){\n                sum+= parseInt(this.id);\n            });\n            $('#amount-money').html(sum);\n        });\n        //选中允许拆分\n        $('#apply_put_accept_split').change(function () {\n            //console.log($(this).prop(\"checked\"));\n            if($(this).prop(\"checked\") == true){\n                $('#accept_split').val('1');\n            }else {\n                $('#accept_split').val('');\n            }\n        });\n    });\n</script>\n{% endblock %}\n"
  },
  {
    "path": "app_backend/templates/apply_put/list.html",
    "content": "<!-- extend from base layout -->\n{% extends \"layout.html\" %}\n\n{% block extra_css %}\n\n{% endblock %}\n\n{% block content %}\n    <div class=\"container-fluid\">\n    <ol class=\"breadcrumb\">\n        <li><a href=\"/\">后台管理</a></li>\n        <li><a href=\"javascript:void(0);\" onclick=\"$('#menu-order').trigger('click');\">订单管理</a></li>\n        <li class=\"active\">投资列表</li>\n    </ol>\n\n    <form class=\"form-inline\">\n        <div class=\"form-group{% if form.apply_put_id.errors %} has-error{% endif %}\">\n            {{ form.apply_put_id.label(class=\"sr-only\") }}\n            {{ form.apply_put_id(class=\"form-control\", placeholder=\"投资申请ID\") }}\n            {% for error in form.apply_put_id.errors %}\n                <span class=\"help-block\">{{ error }}</span>\n            {% endfor %}\n        </div>\n        <div class=\"form-group{% if form.user_id.errors %} has-error{% endif %}\">\n            {{ form.user_id.label(class=\"sr-only\") }}\n            {{ form.user_id(class=\"form-control\", placeholder=\"用户ID\") }}\n            {% for error in form.user_id.errors %}\n                <span class=\"help-block\">{{ error }}</span>\n            {% endfor %}\n        </div>\n        <div class=\"form-group{% if form.type_apply.errors %} has-error{% endif %}\">\n            {{ form.type_apply.label(class=\"sr-only\") }}\n            {{ form.type_apply(class=\"form-control\", placeholder=\"申请类型\", data_width=\"fit\", data_header=\"选择类型\") }}\n            {% for error in form.type_apply.errors %}\n                <span class=\"help-block\">{{ error }}</span>\n            {% endfor %}\n        </div>\n        <div class=\"form-group{% if form.status_order.errors %} has-error{% endif %}\">\n            {{ form.status_order.label(class=\"sr-only\") }}\n            {{ form.status_order(class=\"form-control\", placeholder=\"订单状态\", data_width=\"fit\", data_header=\"选择状态\") }}\n            {% for error in form.status_order.errors %}\n                <span class=\"help-block\">{{ error }}</span>\n            {% endfor %}\n        </div>\n        <div class=\"form-group{% if form.status_delete.errors %} has-error{% endif %}\">\n            {{ form.status_delete.label(class=\"sr-only\") }}\n            {{ form.status_delete(class=\"form-control\", placeholder=\"删除状态\", data_width=\"fit\", data_header=\"选择状态\") }}\n            {% for error in form.status_delete.errors %}\n                <span class=\"help-block\">{{ error }}</span>\n            {% endfor %}\n        </div>\n        <div class=\"form-group{% if form.start_time.errors %} has-error{% endif %}\">\n            {{ form.start_time.label(class=\"sr-only\") }}\n            {{ form.start_time(class=\"form-control\", placeholder=\"start_time\", type='date') }}\n            {% for error in form.start_time.errors %}\n                <span class=\"help-block\">{{ error }}</span>\n            {% endfor %}\n        </div>\n        <div class=\"form-group{% if form.end_time.errors %} has-error{% endif %}\">\n            {{ form.end_time.label(class=\"sr-only\") }}\n            {{ form.end_time(class=\"form-control\", placeholder=\"end_time\", type='date') }}\n            {% for error in form.end_time.errors %}\n                <span class=\"help-block\">{{ error }}</span>\n            {% endfor %}\n        </div>\n\n        <button type=\"submit\" class=\"btn btn-primary\" name=\"op\" value=\"0\">Search</button>\n        <button type=\"submit\" class=\"btn btn-primary\" name=\"op\" value=\"1\">Export</button>\n    </form>\n\n    <hr/>\n\n    <div class=\"table-responsive\">\n        {# <table class=\"table table-striped\"> #}\n        <table class=\"table table-hover\">\n            <thead>\n            <tr>\n                <th>ID</th>\n                <th>用户ID</th>\n                <th>用户名称</th>\n                <th>申请类型</th>\n                <th>申请金额</th>\n                <th>订单金额</th>\n                <th>申请状态</th>\n                <th>订单状态</th>\n                <th>删除状态</th>\n                <th>申请时间</th>\n                <th>操作</th>\n            </tr>\n            </thead>\n            <tbody>\n            {% for apply_put, user_profile in pagination.items %}\n            <tr class=\"text-muted\">\n                <td>{{ apply_put.id }}</td>\n                <td>{{ apply_put.user_id }}</td>\n                <td>{{ user_profile.nickname }}</td>\n                <td>{{ apply_put.type_apply | type_apply }}</td>\n                <td>{{ apply_put.money_apply }}</td>\n                <td>{{ apply_put.money_order }}</td>\n                <td>{{ apply_put.status_apply | status_apply }}</td>\n                <td>{{ apply_put.status_order | status_order }}</td>\n                <td>{{ apply_put.status_delete | status_delete }}</td>\n                <td>{{ moment(apply_put.create_time).format('YYYY-MM-DD HH:mm:ss') }}</td>\n                <td>\n                    <a href=\"{{ url_for('apply_put.info', apply_put_id=apply_put.id) }}\" rel=\"tooltip\" title=\"匹配\"><span class=\"glyphicon glyphicon-retweet\"></span></a>\n                    <a href=\"javascript:void(0);\" onclick=\"apply_put_delete({{ apply_put.id }});\" rel=\"tooltip\" title=\"删除\"><span class=\"glyphicon glyphicon-trash\"></span></a>\n                </td>\n            </tr>\n            {% endfor %}\n            </tbody>\n        </table>\n        {# 翻页 #}\n        {% from \"macros.html\" import render_pagination %}\n        {{ render_pagination(pagination, 'apply_put.lists') }}\n    </div>\n    </div>\n{% endblock %}\n\n{% block extra_js %}\n<script>\n    // 初始化赋值\n    var type_apply = $('#type_apply');\n    type_apply.selectpicker('val', '{{ form.type_apply.data }}');\n    // 处理选项修改\n    type_apply.on('changed.bs.select', function (event, clickedIndex, newValue, oldValue) {\n        // console.log($('#type_apply').val());\n        // console.log(event);\n        // console.log(clickedIndex);\n        // console.log(newValue);\n        // console.log(oldValue);\n    });\n\n    var status_order = $('#status_order');\n    status_order.selectpicker('val', '{{ form.status_order.data }}');\n    // 处理选项修改\n    status_order.on('changed.bs.select', function (event, clickedIndex, newValue, oldValue) {\n        // console.log($('#status_order').val());\n        // console.log(event);\n        // console.log(clickedIndex);\n        // console.log(newValue);\n        // console.log(oldValue);\n    });\n\n    var status_delete = $('#status_delete');\n    status_delete.selectpicker('val', '{{ form.status_delete.data }}');\n    // 处理选项修改\n    status_delete.on('changed.bs.select', function (event, clickedIndex, newValue, oldValue) {\n        // console.log($('#status_delete').val());\n        // console.log(event);\n        // console.log(clickedIndex);\n        // console.log(newValue);\n        // console.log(oldValue);\n    });\n\n    // 投资删除\n    function apply_put_delete(apply_put_id){\n        if(confirm(\"删除数据不能恢复，是否确认删除?\"))\n        {\n            // console.log(apply_put_id);\n            $.getJSON('{{ url_for('apply_put.ajax_delete') }}',\n            {\n                apply_put_id: apply_put_id\n            }, function (result) {\n                if(result.hasOwnProperty('error')){\n                    alert(result.error);\n                }else {\n                    alert(result.success);\n                    window.location.reload();\n                }\n            });\n            return false;\n        }\n    }\n</script>\n{% endblock %}\n"
  },
  {
    "path": "app_backend/templates/apply_put/stats.html",
    "content": "{% extends \"layout.html\" %}\n\n{% block content %}\n<div class=\"container-fluid\">\n    <ol class=\"breadcrumb\">\n        <li><a href=\"/\">后台管理</a></li>\n        <li><a href=\"javascript:void(0);\" onclick=\"$('#menu-stats').trigger('click');\">运营统计</a></li>\n        <li class=\"active\">投资统计</li>\n    </ol>\n    <h2 class=\"sub-header\">Apply Put Stats!</h2>\n\n\n</div>\n\n{% endblock %}"
  },
  {
    "path": "app_backend/templates/auth/email.html",
    "content": "{% extends \"layout.html\" %}\n\n{% block content %}\n    <div class=\"container-fluid\">\n    <h1>Sign In</h1>\n    <form class=\"form-horizontal\" method=\"post\" action=\"\">\n        {{ form.csrf_token }}\n\n        {# 标签导航 #}\n        <div class=\"form-group\">\n            <ul class=\"nav nav-tabs\">  {# 填充整个导航条：nav-justified #}\n                <li role=\"presentation\"><a href=\"{{ url_for('auth.index') }}\">Index</a></li>\n                <li role=\"presentation\"><a href=\"{{ url_for('auth.phone') }}\">Phone</a></li>\n                <li role=\"presentation\" class=\"active\"><a href=\"{{ url_for('auth.email') }}\">Email</a></li>\n            </ul>\n        </div>\n        <div class=\"form-group{% if form.email.errors %} has-error{% endif %}\">\n            {{ form.email.label(class=\"col-sm-2 control-label\") }}\n            <div class=\"col-sm-10\">\n                {{ form.email(class=\"form-control\", placeholder=\"Account(email)\", value=\"test@gmail.com\") }}\n                {% for error in form.email.errors %}\n                    <span class=\"help-block\">{{ error }}</span>\n                {% endfor %}\n            </div>\n        </div>\n        <div class=\"form-group{% if form.password.errors %} has-error{% endif %}\">\n            {{ form.password.label(class=\"col-sm-2 control-label\") }}\n            <div class=\"col-sm-10\">\n                {{ form.password(class=\"form-control\", placeholder=\"Password\", value=\"123456\") }}\n                {% for error in form.password.errors %}\n                    <span class=\"help-block\">{{ error }}</span>\n                {% endfor %}\n            </div>\n        </div>\n        <div class=\"form-group{% if form.remember.errors %} has-error{% endif %}\">\n            <div class=\"col-sm-offset-2 col-sm-10\">\n                <div class=\"checkbox\">\n                    <label>\n                        {{ form.remember }} Remember Me\n                    </label>\n                </div>\n            </div>\n        </div>\n        <div class=\"form-group\">\n            <div class=\"col-sm-offset-2 col-sm-10\">\n                <button type=\"submit\" class=\"btn btn-default btn-load\" data-loading-text=\"Sign in...\" autocomplete=\"off\">Sign in</button> <a href=\"#\">Lost password?</a>\n            </div>\n        </div>\n    </form>\n    <hr/>\n    <a type=\"button\" href=\"{{ url_for('auth.login_qq') }}\">QQ</a>\n    <a type=\"button\" href=\"{{ url_for('auth.login_weibo') }}\">WeiBo</a>\n    <a type=\"button\" href=\"{{ url_for('auth.login_github') }}\">GitHub</a>\n    </div>\n{% endblock %}"
  },
  {
    "path": "app_backend/templates/auth/index.html",
    "content": "{% extends \"layout.html\" %}\n\n{% block content %}\n    <div class=\"container-fluid\">\n    <h1>Sign In</h1>\n    <form class=\"form-horizontal\" method=\"post\" action=\"\">\n        {{ form.csrf_token }}\n\n        {# 标签导航 #}\n        <div class=\"form-group\">\n            <ul class=\"nav nav-tabs\">  {# 填充整个导航条：nav-justified #}\n                <li role=\"presentation\" class=\"active\"><a href=\"{{ url_for('auth.index') }}\">Index</a></li>\n                <li role=\"presentation\"><a href=\"{{ url_for('auth.phone') }}\">Phone</a></li>\n                <li role=\"presentation\"><a href=\"{{ url_for('auth.email') }}\">Email</a></li>\n            </ul>\n        </div>\n        <div class=\"form-group{% if form.account.errors %} has-error{% endif %}\">\n            {{ form.account.label(class=\"col-sm-2 control-label\") }}\n            <div class=\"col-sm-10\">\n                {{ form.account(class=\"form-control\", placeholder=\"Account\") }}\n                {% for error in form.account.errors %}\n                    <span class=\"help-block\">{{ error }}</span>\n                {% endfor %}\n            </div>\n        </div>\n        <div class=\"form-group{% if form.password.errors %} has-error{% endif %}\">\n            {{ form.password.label(class=\"col-sm-2 control-label\") }}\n            <div class=\"col-sm-10\">\n                {{ form.password(class=\"form-control\", placeholder=\"Password\", value=\"123456\") }}\n                {% for error in form.password.errors %}\n                    <span class=\"help-block\">{{ error }}</span>\n                {% endfor %}\n            </div>\n        </div>\n        <div class=\"form-group{% if form.remember.errors %} has-error{% endif %}\">\n            <div class=\"col-sm-offset-2 col-sm-10\">\n                <div class=\"checkbox\">\n                    <label>\n                        {{ form.remember }} Remember Me\n                    </label>\n                </div>\n            </div>\n        </div>\n        <div class=\"form-group\">\n            <div class=\"col-sm-offset-2 col-sm-10\">\n                <button type=\"submit\" class=\"btn btn-default btn-load\" data-loading-text=\"Sign in...\" autocomplete=\"off\">Sign in</button> <a href=\"#\">Lost password?</a>\n            </div>\n        </div>\n    </form>\n    <hr/>\n    <a type=\"button\" href=\"{{ url_for('auth.login_qq') }}\">QQ</a>\n    <a type=\"button\" href=\"{{ url_for('auth.login_weibo') }}\">WeiBo</a>\n    <a type=\"button\" href=\"{{ url_for('auth.login_github') }}\">GitHub</a>\n    </div>\n{% endblock %}"
  },
  {
    "path": "app_backend/templates/auth/phone.html",
    "content": "{% extends \"layout.html\" %}\n\n{% block content %}\n    <div class=\"container-fluid\">\n    <h1>Sign In</h1>\n    <form class=\"form-horizontal\" method=\"post\" action=\"\">\n        {{ form.csrf_token }}\n\n        {# 标签导航 #}\n        <div class=\"form-group\">\n            <ul class=\"nav nav-tabs\">  {# 填充整个导航条：nav-justified #}\n                <li role=\"presentation\"><a href=\"{{ url_for('auth.index') }}\">Index</a></li>\n                <li role=\"presentation\" class=\"active\"><a href=\"{{ url_for('auth.phone') }}\">Phone</a></li>\n                <li role=\"presentation\"><a href=\"{{ url_for('auth.email') }}\">Email</a></li>\n            </ul>\n        </div>\n        <div class=\"form-group{% if form.phone.errors %} has-error{% endif %}\">\n            {{ form.phone.label(class=\"col-sm-2 control-label\") }}\n            <div class=\"col-sm-10\">\n                {{ form.phone(class=\"form-control\", placeholder=\"Phone\") }}\n                {% for error in form.phone.errors %}\n                    <span class=\"help-block\">{{ error }}</span>\n                {% endfor %}\n            </div>\n        </div>\n        <div class=\"form-group{% if form.password.errors %} has-error{% endif %}\">\n            {{ form.password.label(class=\"col-sm-2 control-label\") }}\n            <div class=\"col-sm-10\">\n                {{ form.password(class=\"form-control\", placeholder=\"Password\", value=\"123456\") }}\n                {% for error in form.password.errors %}\n                    <span class=\"help-block\">{{ error }}</span>\n                {% endfor %}\n            </div>\n        </div>\n        <div class=\"form-group{% if form.remember.errors %} has-error{% endif %}\">\n            <div class=\"col-sm-offset-2 col-sm-10\">\n                <div class=\"checkbox\">\n                    <label>\n                        {{ form.remember }} Remember Me\n                    </label>\n                </div>\n            </div>\n        </div>\n        <div class=\"form-group\">\n            <div class=\"col-sm-offset-2 col-sm-10\">\n                <button type=\"submit\" class=\"btn btn-default btn-load\" data-loading-text=\"Sign in...\" autocomplete=\"off\">Sign in</button> <a href=\"#\">Lost password?</a>\n            </div>\n        </div>\n    </form>\n    <hr/>\n    <a type=\"button\" href=\"{{ url_for('auth.login_qq') }}\">QQ</a>\n    <a type=\"button\" href=\"{{ url_for('auth.login_weibo') }}\">WeiBo</a>\n    <a type=\"button\" href=\"{{ url_for('auth.login_github') }}\">GitHub</a>\n    </div>\n{% endblock %}"
  },
  {
    "path": "app_backend/templates/complaint/list.html",
    "content": "{% extends \"layout.html\" %}\n\n{% block content %}\n<div class=\"container-fluid\">\n    <nav class=\"sub-header row container-fluid\">\n        <ol class=\"breadcrumb\">\n            <li><a href=\"/\">后台管理</a></li>\n            <li><a href=\"javascript:void(0);\" onclick=\"$('#menu-message').trigger('click');\">留言管理</a></li>\n            <li class=\"active\">投诉列表</li>\n        </ol>\n        <div class=\"btn-group pull-right\" role=\"group\" aria-label=\"...\">\n        {% if request.query_string == 'status_reply=1' %}\n            <a type=\"button\" class=\"btn btn-default\" href=\"{{ url_for('complaint.lists') }}\">未处理</a>\n            <a type=\"button\" class=\"btn btn-default active\">已处理</a>\n        {% else %}\n            <a type=\"button\" class=\"btn btn-default active\">未处理</a>\n            <a type=\"button\" class=\"btn btn-default\" href=\"{{ url_for('complaint.lists', status_reply=1) }}\">已处理</a>\n        {% endif %}\n        </div>\n    </nav>\n\n{#    <h2 class=\"sub-header\">Complaint List!</h2>#}\n    <!-- content -->\n    <div class=\"table-responsive\">\n        {# <table class=\"table table-striped\"> #}\n        <table class=\"table table-hover\">\n            <thead>\n            <tr>\n                <th>投诉明细ID</th>\n                <th>投诉用户</th>\n                <th>被投诉用户</th>\n                <th>投诉内容</th>\n                <th>投诉时间</th>\n                {% if request.query_string == 'status_reply=1' %}\n                <th>回复内容</th>\n                <th>回复时间</th>\n                {% else %}\n                <th>操作</th>\n                {% endif %}\n            </tr>\n            </thead>\n            <tbody>\n            {% for complaint, user_profile_put, user_profile_get in pagination.items %}\n            <tr class=\"text-muted\">\n                <td>{{ complaint.id }}</td>\n                <td>{{ user_profile_put.nickname | default('系统消息') }} [{{ user_profile_put.user_id }}]</td>\n                <td>{{ user_profile_get.nickname }} [{{ user_profile_get.user_id }}]</td>\n                <td>{{ complaint.content }}</td>\n                <td>{{ moment(complaint.create_time).format('YYYY-MM-DD HH:mm:ss') }}</td>\n                {% if request.query_string == 'status_reply=1' %}\n                <td>{{ complaint.content_reply }}</td>\n                <td>{{ moment(complaint.reply_time).format('YYYY-MM-DD HH:mm:ss') }}</td>\n                {% else %}\n                <td>\n                    <a href=\"javascript:void(0);\" onclick=\"complaint_delete({{ complaint.id }});\" rel=\"tooltip\" title=\"删除\"><span class=\"glyphicon glyphicon-trash\"></span></a>\n                    <a href=\"{{ url_for('complaint.reply', complaint_id=complaint.id) }}\" rel=\"tooltip\" title=\"回复\"><span class=\"glyphicon glyphicon-comment\"></span></a>\n                </td>\n                {% endif %}\n            </tr>\n            {% endfor %}\n            </tbody>\n        </table>\n        {# 翻页 #}\n        {% from \"macros.html\" import render_pagination %}\n        {{ render_pagination(pagination, 'complaint.lists') }}\n    </div>\n\n</div>\n\n{% endblock %}\n\n{% block extra_js %}\n<script>\n    // 投诉删除\n    function complaint_delete(msg_id){\n        if(confirm(\"删除数据不能恢复，是否确认删除?\"))\n        {\n            // console.log(user_id);\n            $.getJSON('{{ url_for('complaint.ajax_delete') }}',\n            {\n                msg_id: msg_id\n            }, function (result) {\n                if(result.hasOwnProperty('error')){\n                    alert(result.error);\n                }else {\n                    alert(result.success);\n                    window.location.reload();\n                }\n            });\n            return false;\n        }\n    }\n</script>\n{% endblock %}"
  },
  {
    "path": "app_backend/templates/complaint/reply.html",
    "content": "{% extends \"layout.html\" %}\n\n{% block content %}\n<div class=\"container-fluid\">\n    <nav class=\"sub-header row container-fluid\">\n        <ol class=\"breadcrumb\">\n            <li><a href=\"/\">后台管理</a></li>\n            <li><a href=\"javascript:void(0);\" onclick=\"$('#menu-message').trigger('click');\">留言管理</a></li>\n            <li class=\"active\">投诉处理</li>\n        </ol>\n    </nav>\n\n{#    <h2 class=\"sub-header\">Complaint List!</h2>#}\n    <!-- content -->\n    <div class=\"table-responsive col-lg-12 col-md-12\">\n        <form class=\"form-horizontal\" method=\"post\" action=\"\">\n            {{ form.csrf_token }}\n            <div class=\"form-group{% if form.send_user_id.errors %} has-error{% endif %}\">\n                {{ form.send_user_id.label(class=\"col-sm-2 control-label\") }}\n                <div class=\"col-sm-10\">\n                    <div class=\"form-control\">{{ form.send_user_id.data | nickname }}</div>\n                </div>\n            </div>\n            <div class=\"form-group{% if form.receive_user_id.errors %} has-error{% endif %}\">\n                {{ form.receive_user_id.label(class=\"col-sm-2 control-label\") }}\n                <div class=\"col-sm-10\">\n                    <div class=\"form-control\">{{ form.receive_user_id.data | nickname }}</div>\n                </div>\n            </div>\n\n            <div class=\"form-group{% if form.content.errors %} has-error{% endif %}\">\n                {{ form.content.label(class=\"col-sm-2 control-label\") }}\n                <div class=\"col-sm-10\">\n                    {{ form.content(class=\"form-control\", placeholder=\"投诉内容\", rows=\"6\") }}\n                    {% for error in form.content.errors %}\n                        <span class=\"help-block\">{{ error }}</span>\n                    {% endfor %}\n                </div>\n            </div>\n            <div class=\"form-group{% if form.content_reply.errors %} has-error{% endif %}\">\n                {{ form.content_reply.label(class=\"col-sm-2 control-label\") }}\n                <div class=\"col-sm-10\">\n                    {{ form.content_reply(class=\"form-control\", placeholder=\"回复内容\", rows=\"6\") }}\n                    {% for error in form.content_reply.errors %}\n                        <span class=\"help-block\">{{ error }}</span>\n                    {% endfor %}\n                </div>\n            </div>\n            <div class=\"form-group\">\n                <div class=\"col-sm-offset-2 col-sm-10\">\n                    <button type=\"submit\" class=\"btn btn-success btn-load\" data-loading-text=\"回复中\">回复</button>\n                    <button type=\"reset\" class=\"btn btn-default\">重新填写</button>\n                    <button class=\"btn btn-default\" onclick=\"history.back();\">返回</button>\n                </div>\n            </div>\n        </form>\n    </div>\n\n\n</div>\n\n{% endblock %}\n\n{% block extra_js %}\n\n{% endblock %}"
  },
  {
    "path": "app_backend/templates/index.html",
    "content": "{% extends \"layout.html\" %}\n\n{% block content %}\n<div class=\"container-fluid\">\n    <ol class=\"breadcrumb\">\n        <li><a href=\"/\">后台管理</a></li>\n        <li class=\"active\">后台首页</li>\n    </ol>\n    <div class=\"col-md-8 col-sm-offset-2 text-center\">\n        <h2 class=\"sub-header\">Welcome!</h2>\n        <div id=\"current_time\">{{ moment().format('dddd, YYYY年MM月DD日, a hh:mm:ss') }}</div>\n    </div>\n</div>\n{% endblock %}\n\n{% block extra_js %}\n<script>\n// 当前时间同步刷新\nvar update_time;\n(update_time = function () {\n    $('#current_time').html(moment().format('dddd, YYYY年MM月DD日, a hh:mm:ss'));\n})();\nsetInterval(update_time, 1000);\n</script>\n{% endblock %}"
  },
  {
    "path": "app_backend/templates/index_.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n\n<head>\n\n    <meta charset=\"utf-8\">\n    <meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\">\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">\n    <meta name=\"description\" content=\"\">\n    <meta name=\"author\" content=\"\">\n\n    <title>后台管理</title>\n\n    <!-- Bootstrap Core CSS -->\n    <link href=\"../static/css/bootstrap.min.css\" rel=\"stylesheet\">\n\n    <!-- MetisMenu CSS -->\n    <link href=\"../vendor/metisMenu/metisMenu.min.css\" rel=\"stylesheet\">\n\n    <!-- Custom CSS -->\n    <link href=\"../dist/css/sb-admin-2.css\" rel=\"stylesheet\">\n\n    <!-- Custom Fonts -->\n    <link href=\"../vendor/font-awesome/css/font-awesome.min.css\" rel=\"stylesheet\" type=\"text/css\">\n\n    <!-- HTML5 Shim and Respond.js IE8 support of HTML5 elements and media queries -->\n    <!-- WARNING: Respond.js doesn't work if you view the page via file:// -->\n    <!--[if lt IE 9]>\n        <script src=\"https://oss.maxcdn.com/libs/html5shiv/3.7.0/html5shiv.js\"></script>\n        <script src=\"https://oss.maxcdn.com/libs/respond.js/1.4.2/respond.min.js\"></script>\n    <![endif]-->\n\n</head>\n\n<body>\n\n    <div id=\"wrapper\">\n\n        <!-- Navigation -->\n        <nav class=\"navbar navbar-default navbar-static-top\" role=\"navigation\" style=\"margin-bottom: 0\">\n            <div class=\"navbar-header\">\n                <button type=\"button\" class=\"navbar-toggle\" data-toggle=\"collapse\" data-target=\".navbar-collapse\">\n                    <span class=\"sr-only\">Toggle navigation</span>\n                    <span class=\"icon-bar\"></span>\n                    <span class=\"icon-bar\"></span>\n                    <span class=\"icon-bar\"></span>\n                </button>\n                <a class=\"navbar-brand\" href=\"index.html\">后台管理</a>\n            </div>\n            <!-- /.navbar-header -->\n\n            <ul class=\"nav navbar-top-links navbar-right\">\n                <li class=\"dropdown\">\n                    <a class=\"dropdown-toggle\" data-toggle=\"dropdown\" href=\"#\">\n                        <i class=\"fa fa-envelope fa-fw\"></i> <i class=\"fa fa-caret-down\"></i>\n                    </a>\n                    <ul class=\"dropdown-menu dropdown-messages\">\n                        <li>\n                            <a href=\"#\">\n                                <div>\n                                    <strong>John Smith</strong>\n                                    <span class=\"pull-right text-muted\">\n                                        <em>Yesterday</em>\n                                    </span>\n                                </div>\n                                <div>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque eleifend...</div>\n                            </a>\n                        </li>\n                        <li class=\"divider\"></li>\n                        <li>\n                            <a href=\"#\">\n                                <div>\n                                    <strong>John Smith</strong>\n                                    <span class=\"pull-right text-muted\">\n                                        <em>Yesterday</em>\n                                    </span>\n                                </div>\n                                <div>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque eleifend...</div>\n                            </a>\n                        </li>\n                        <li class=\"divider\"></li>\n                        <li>\n                            <a href=\"#\">\n                                <div>\n                                    <strong>John Smith</strong>\n                                    <span class=\"pull-right text-muted\">\n                                        <em>Yesterday</em>\n                                    </span>\n                                </div>\n                                <div>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque eleifend...</div>\n                            </a>\n                        </li>\n                        <li class=\"divider\"></li>\n                        <li>\n                            <a class=\"text-center\" href=\"#\">\n                                <strong>Read All Messages</strong>\n                                <i class=\"fa fa-angle-right\"></i>\n                            </a>\n                        </li>\n                    </ul>\n                    <!-- /.dropdown-messages -->\n                </li>\n                <!-- /.dropdown -->\n                <li class=\"dropdown\">\n                    <a class=\"dropdown-toggle\" data-toggle=\"dropdown\" href=\"#\">\n                        <i class=\"fa fa-tasks fa-fw\"></i> <i class=\"fa fa-caret-down\"></i>\n                    </a>\n                    <ul class=\"dropdown-menu dropdown-tasks\">\n                        <li>\n                            <a href=\"#\">\n                                <div>\n                                    <p>\n                                        <strong>Task 1</strong>\n                                        <span class=\"pull-right text-muted\">40% Complete</span>\n                                    </p>\n                                    <div class=\"progress progress-striped active\">\n                                        <div class=\"progress-bar progress-bar-success\" role=\"progressbar\" aria-valuenow=\"40\" aria-valuemin=\"0\" aria-valuemax=\"100\" style=\"width: 40%\">\n                                            <span class=\"sr-only\">40% Complete (success)</span>\n                                        </div>\n                                    </div>\n                                </div>\n                            </a>\n                        </li>\n                        <li class=\"divider\"></li>\n                        <li>\n                            <a href=\"#\">\n                                <div>\n                                    <p>\n                                        <strong>Task 2</strong>\n                                        <span class=\"pull-right text-muted\">20% Complete</span>\n                                    </p>\n                                    <div class=\"progress progress-striped active\">\n                                        <div class=\"progress-bar progress-bar-info\" role=\"progressbar\" aria-valuenow=\"20\" aria-valuemin=\"0\" aria-valuemax=\"100\" style=\"width: 20%\">\n                                            <span class=\"sr-only\">20% Complete</span>\n                                        </div>\n                                    </div>\n                                </div>\n                            </a>\n                        </li>\n                        <li class=\"divider\"></li>\n                        <li>\n                            <a href=\"#\">\n                                <div>\n                                    <p>\n                                        <strong>Task 3</strong>\n                                        <span class=\"pull-right text-muted\">60% Complete</span>\n                                    </p>\n                                    <div class=\"progress progress-striped active\">\n                                        <div class=\"progress-bar progress-bar-warning\" role=\"progressbar\" aria-valuenow=\"60\" aria-valuemin=\"0\" aria-valuemax=\"100\" style=\"width: 60%\">\n                                            <span class=\"sr-only\">60% Complete (warning)</span>\n                                        </div>\n                                    </div>\n                                </div>\n                            </a>\n                        </li>\n                        <li class=\"divider\"></li>\n                        <li>\n                            <a href=\"#\">\n                                <div>\n                                    <p>\n                                        <strong>Task 4</strong>\n                                        <span class=\"pull-right text-muted\">80% Complete</span>\n                                    </p>\n                                    <div class=\"progress progress-striped active\">\n                                        <div class=\"progress-bar progress-bar-danger\" role=\"progressbar\" aria-valuenow=\"80\" aria-valuemin=\"0\" aria-valuemax=\"100\" style=\"width: 80%\">\n                                            <span class=\"sr-only\">80% Complete (danger)</span>\n                                        </div>\n                                    </div>\n                                </div>\n                            </a>\n                        </li>\n                        <li class=\"divider\"></li>\n                        <li>\n                            <a class=\"text-center\" href=\"#\">\n                                <strong>See All Tasks</strong>\n                                <i class=\"fa fa-angle-right\"></i>\n                            </a>\n                        </li>\n                    </ul>\n                    <!-- /.dropdown-tasks -->\n                </li>\n                <!-- /.dropdown -->\n                <li class=\"dropdown\">\n                    <a class=\"dropdown-toggle\" data-toggle=\"dropdown\" href=\"#\">\n                        <i class=\"fa fa-bell fa-fw\"></i> <i class=\"fa fa-caret-down\"></i>\n                    </a>\n                    <ul class=\"dropdown-menu dropdown-alerts\">\n                        <li>\n                            <a href=\"#\">\n                                <div>\n                                    <i class=\"fa fa-comment fa-fw\"></i> New Comment\n                                    <span class=\"pull-right text-muted small\">4 minutes ago</span>\n                                </div>\n                            </a>\n                        </li>\n                        <li class=\"divider\"></li>\n                        <li>\n                            <a href=\"#\">\n                                <div>\n                                    <i class=\"fa fa-twitter fa-fw\"></i> 3 New Followers\n                                    <span class=\"pull-right text-muted small\">12 minutes ago</span>\n                                </div>\n                            </a>\n                        </li>\n                        <li class=\"divider\"></li>\n                        <li>\n                            <a href=\"#\">\n                                <div>\n                                    <i class=\"fa fa-envelope fa-fw\"></i> Message Sent\n                                    <span class=\"pull-right text-muted small\">4 minutes ago</span>\n                                </div>\n                            </a>\n                        </li>\n                        <li class=\"divider\"></li>\n                        <li>\n                            <a href=\"#\">\n                                <div>\n                                    <i class=\"fa fa-tasks fa-fw\"></i> New Task\n                                    <span class=\"pull-right text-muted small\">4 minutes ago</span>\n                                </div>\n                            </a>\n                        </li>\n                        <li class=\"divider\"></li>\n                        <li>\n                            <a href=\"#\">\n                                <div>\n                                    <i class=\"fa fa-upload fa-fw\"></i> Server Rebooted\n                                    <span class=\"pull-right text-muted small\">4 minutes ago</span>\n                                </div>\n                            </a>\n                        </li>\n                        <li class=\"divider\"></li>\n                        <li>\n                            <a class=\"text-center\" href=\"#\">\n                                <strong>See All Alerts</strong>\n                                <i class=\"fa fa-angle-right\"></i>\n                            </a>\n                        </li>\n                    </ul>\n                    <!-- /.dropdown-alerts -->\n                </li>\n                <!-- /.dropdown -->\n                <li class=\"dropdown\">\n                    <a class=\"dropdown-toggle\" data-toggle=\"dropdown\" href=\"#\">\n                        <i class=\"fa fa-user fa-fw\"></i> <i class=\"fa fa-caret-down\"></i>\n                    </a>\n                    <ul class=\"dropdown-menu dropdown-user\">\n                        <li><a href=\"#\"><i class=\"fa fa-user fa-fw\"></i> User Profile</a>\n                        </li>\n                        <li><a href=\"#\"><i class=\"fa fa-gear fa-fw\"></i> Settings</a>\n                        </li>\n                        <li class=\"divider\"></li>\n                        <li><a href=\"login.html\"><i class=\"fa fa-sign-out fa-fw\"></i> Logout</a>\n                        </li>\n                    </ul>\n                    <!-- /.dropdown-user -->\n                </li>\n                <!-- /.dropdown -->\n            </ul>\n            <!-- /.navbar-top-links -->\n\n            <div class=\"navbar-default sidebar\" role=\"navigation\">\n                <div class=\"sidebar-nav navbar-collapse\">\n                    <ul class=\"nav\" id=\"side-menu\">\n                        <li class=\"sidebar-search\">\n                            <div class=\"input-group custom-search-form\">\n                                <input type=\"text\" class=\"form-control\" placeholder=\"Search...\">\n                                <span class=\"input-group-btn\">\n                                    <button class=\"btn btn-default\" type=\"button\">\n                                        <i class=\"fa fa-search\"></i>\n                                    </button>\n                                </span>\n                            </div>\n                            <!-- /input-group -->\n                        </li>\n                        <li>\n                            <a href=\"index.html\"><i class=\"fa fa-dashboard fa-fw\"></i> 后台首页</a>\n                        </li>\n                        <li>\n                            <a href=\"#\"><i class=\"fa fa-bar-chart-o fa-fw\"></i> 会员管理<span class=\"fa arrow\"></span></a>\n                            <ul class=\"nav nav-second-level\">\n                                <li>\n                                    <a href=\"flot.html\">会员列表</a>\n                                </li>\n                                <li>\n                                    <a href=\"flot.html\">会员添加</a>\n                                </li>\n                                <li>\n                                    <a href=\"morris.html\">会员关系</a>\n                                </li>\n                            </ul>\n                            <!-- /.nav-second-level -->\n                        </li>\n                        <li>\n                            <a href=\"tables.html\"><i class=\"fa fa-table fa-fw\"></i> 金币管理</a>\n                        </li>\n                        <li>\n                            <a href=\"forms.html\"><i class=\"fa fa-edit fa-fw\"></i> Forms</a>\n                        </li>\n                        <li>\n                            <a href=\"#\"><i class=\"fa fa-wrench fa-fw\"></i> 订单管理<span class=\"fa arrow\"></span></a>\n                            <ul class=\"nav nav-second-level\">\n                                <li>\n                                    <a href=\"panels-wells.html\">订单列表</a>\n                                </li>\n                                <li>\n                                    <a href=\"buttons.html\">订单列表</a>\n                                </li>\n                                <li>\n                                    <a href=\"notifications.html\">提供申请列表</a>\n                                </li>\n                                <li>\n                                    <a href=\"typography.html\">获得申请列表</a>\n                                </li>\n                                <li>\n                                    <a href=\"icons.html\">添加提供申请</a>\n                                </li>\n                                <li>\n                                    <a href=\"grid.html\">添加获得申请</a>\n                                </li>\n                            </ul>\n                            <!-- /.nav-second-level -->\n                        </li>\n                        <li>\n                            <a href=\"#\"><i class=\"fa fa-sitemap fa-fw\"></i> 系统设置<span class=\"fa arrow\"></span></a>\n                            <ul class=\"nav nav-second-level\">\n                                <li>\n                                    <a href=\"#\">会员设置</a>\n                                </li>\n                                <li>\n                                    <a href=\"#\">订单设置</a>\n                                </li>\n                                <li>\n                                    <a href=\"#\">利息设置 <span class=\"fa arrow\"></span></a>\n                                    <ul class=\"nav nav-third-level\">\n                                        <li>\n                                            <a href=\"#\">提前打款</a>\n                                        </li>\n                                        <li>\n                                            <a href=\"#\">延迟打款</a>\n                                        </li>\n                                        <li>\n                                            <a href=\"#\">提前收货</a>\n                                        </li>\n                                        <li>\n                                            <a href=\"#\">延迟收货</a>\n                                        </li>\n                                    </ul>\n                                    <!-- /.nav-third-level -->\n                                </li>\n                            </ul>\n                            <!-- /.nav-second-level -->\n                        </li>\n                        <li class=\"active\">\n                            <a href=\"#\"><i class=\"fa fa-files-o fa-fw\"></i> 留言管理<span class=\"fa arrow\"></span></a>\n                            <ul class=\"nav nav-second-level\">\n                                <li>\n                                    <a class=\"active\" href=\"blank.html\">留言列表</a>\n                                </li>\n                                <li>\n                                    <a href=\"login.html\">投诉列表</a>\n                                </li>\n                            </ul>\n                            <!-- /.nav-second-level -->\n                        </li>\n                    </ul>\n                </div>\n                <!-- /.sidebar-collapse -->\n            </div>\n            <!-- /.navbar-static-side -->\n        </nav>\n\n        <!-- Page Content -->\n        <div id=\"page-wrapper\">\n            <div class=\"container-fluid\">\n                <div class=\"row\">\n                    <div class=\"col-lg-12\">\n                        <h1 class=\"page-header\">Blank</h1>\n                    </div>\n                    <!-- /.col-lg-12 -->\n                </div>\n                <!-- /.row -->\n            </div>\n            <!-- /.container-fluid -->\n        </div>\n        <!-- /#page-wrapper -->\n\n    </div>\n    <!-- /#wrapper -->\n\n    <!-- jQuery -->\n    <script src=\"../static/js/jquery-1.11.3.min.js\"></script>\n\n    <!-- Bootstrap Core JavaScript -->\n    <script src=\"../vendor/bootstrap/js/bootstrap.min.js\"></script>\n\n    <!-- Metis Menu Plugin JavaScript -->\n    <script src=\"../vendor/metisMenu/metisMenu.min.js\"></script>\n\n    <!-- Custom Theme JavaScript -->\n    <script src=\"../dist/js/sb-admin-2.js\"></script>\n\n</body>\n\n</html>\n"
  },
  {
    "path": "app_backend/templates/layout.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n\n<head>\n    <meta charset=\"utf-8\">\n    <meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\">\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">\n    <meta name=\"keywords\" content=\"\">\n    <meta name=\"description\" content=\"\">\n    <meta name=\"author\" content=\"\">\n    {# <link rel=\"icon\" href=\"{{ url_for('static', _external=True, filename='img/favicon.ico') }}\"> #}\n    <link rel=\"shortcut icon\" href=\"{{ url_for('static', filename='img/favicon.ico') }}\">\n    <title>{% if title %}{{ title }} - {% endif %}后台管理</title>\n    <!-- Bootstrap -->\n    <link href=\"{{ url_for('static', filename='css/bootstrap.min.css') }}\" rel=\"stylesheet\">\n    <link href=\"{{ url_for('static', filename='css/bootstrap-theme.min.css') }}\" rel=\"stylesheet\">\n    <!-- Plugin -->\n    <link href=\"{{ url_for('static', filename='plugin/metisMenu/metisMenu.min.css') }}\" rel=\"stylesheet\">\n    <link href=\"{{ url_for('static', filename='plugin/font-awesome/css/font-awesome.min.css') }}\" rel=\"stylesheet\">\n    <link href=\"{{ url_for('static', filename='css/bootstrap-select.min.css') }}\" rel=\"stylesheet\">\n    <!-- Custom -->\n    <link href=\"{{ url_for('static', filename='css/sb-admin-2.min.css') }}\" rel=\"stylesheet\">\n    <link href=\"{{ url_for('static', filename='css/custom.css', v='1.4.69') }}\" rel=\"stylesheet\">\n    {% block extra_css %}{% endblock %}\n    <!-- HTML5 shim and Respond.js for IE8 support of HTML5 elements and media queries -->\n    <!-- WARNING: Respond.js doesn't work if you view the page via file:// -->\n    <!--[if lt IE 9]>\n      <script src=\"https://oss.maxcdn.com/html5shiv/3.7.3/html5shiv.min.js\"></script>\n      <script src=\"https://oss.maxcdn.com/respond/1.4.2/respond.min.js\"></script>\n    <![endif]-->\n\n</head>\n\n<body>\n\n    <div id=\"wrapper\">\n\n        <!-- Navigation -->\n        <nav class=\"navbar navbar-default navbar-static-top\" role=\"navigation\" style=\"margin-bottom: 0\">\n            <!-- 头部导航 -->\n            {% include \"_top.html\" %}\n            <!-- 左侧导航 -->\n            {% include \"_left.html\" %}\n        </nav>\n\n        <!-- Page Content -->\n        <div id=\"page-wrapper\">\n            <div class=\"container\">\n            {# 闪现消息 success info warning danger #}\n            {% with messages = get_flashed_messages(with_categories=true) %}\n            {% if messages %}\n            {% for category, message in messages %}\n                <div class=\"alert alert-{{ category }}\" role=\"alert\">\n                    <button type=\"button\" class=\"close\" data-dismiss=\"alert\" aria-hidden=\"true\">&times;</button>\n                    {{ message }}\n                </div>\n            {% endfor %}\n            {% endif %}\n            {% endwith %}\n            </div>\n            {% block content %}{% endblock %}\n            <!-- /.container-fluid -->\n        </div>\n        <!-- /#page-wrapper -->\n\n    </div>\n    <!-- /#wrapper -->\n\n    <!-- jQuery -->\n    <script src=\"{{ url_for('static', filename='js/jquery-1.11.3.min.js') }}\"></script>\n\n    <!-- Bootstrap Core JavaScript -->\n    <script src=\"{{ url_for('static', filename='js/bootstrap.min.js') }}\"></script>\n\n    <!-- Metis Menu Plugin JavaScript -->\n    <script src=\"{{ url_for('static', filename='plugin/metisMenu/metisMenu.min.js') }}\"></script>\n    <script src=\"{{ url_for('static', filename='js/bootstrap-select.min.js') }}\"></script>\n\n    <!-- Chart Plugin JavaScript -->\n    <script src=\"{{ url_for('static', filename='plugin/Chart.js-2.6.0/dist/Chart.min.js') }}\"></script>\n\n    <!-- Custom Theme JavaScript -->\n    <script src=\"{{ url_for('static', filename='js/sb-admin-2.js') }}\"></script>\n    <script src=\"{{ url_for('static', filename='js/custom.js', v='1.4.74') }}\"></script>\n\n    <script src=\"{{ url_for('static', filename='plugin/moment-2.18.1/min/moment-with-locales.min.js') }}\"></script>\n    <script>\n        moment.locale('zh-cn');\n        function flask_moment_render(elem) {\n            $(elem).text(eval('moment(\"' + $(elem).data('timestamp') + '\").' + $(elem).data('format') + ';'));\n            $(elem).removeClass('flask-moment').show();\n        }\n        function flask_moment_render_all() {\n            $('.flask-moment').each(function () {\n                flask_moment_render(this);\n                if ($(this).data('refresh')) {\n                    (function (elem, interval) {\n                        setInterval(function () {\n                            flask_moment_render(elem)\n                        }, interval);\n                    })(this, $(this).data('refresh'));\n                }\n            })\n        }\n        $(document).ready(function () {\n            flask_moment_render_all();\n        });\n    </script>\n\n    {% block extra_js %}{% endblock %}\n</body>\n\n</html>\n"
  },
  {
    "path": "app_backend/templates/login.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n\n<head>\n    <meta charset=\"utf-8\">\n    <meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\">\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">\n    <meta name=\"keywords\" content=\"\">\n    <meta name=\"description\" content=\"\">\n    <meta name=\"author\" content=\"\">\n    {# <link rel=\"icon\" href=\"{{ url_for('static', _external=True, filename='img/favicon.ico') }}\"> #}\n    <link rel=\"shortcut icon\" href=\"{{ url_for('static', filename='img/favicon.ico') }}\">\n    <title>后台登录 - 后台管理</title>\n    <!-- Bootstrap -->\n    <link href=\"{{ url_for('static', filename='css/bootstrap.min.css') }}\" rel=\"stylesheet\">\n    <!-- Plugin -->\n    <link href=\"{{ url_for('static', filename='plugin/metisMenu/metisMenu.min.css') }}\" rel=\"stylesheet\">\n    <link href=\"{{ url_for('static', filename='plugin/font-awesome/css/font-awesome.min.css') }}\" rel=\"stylesheet\">\n    <link href=\"{{ url_for('static', filename='css/bootstrap-select.min.css') }}\" rel=\"stylesheet\">\n    <!-- Custom -->\n    <link href=\"{{ url_for('static', filename='css/sb-admin-2.min.css') }}\" rel=\"stylesheet\">\n    {% block extra_css %}{% endblock %}\n    <!-- HTML5 shim and Respond.js for IE8 support of HTML5 elements and media queries -->\n    <!-- WARNING: Respond.js doesn't work if you view the page via file:// -->\n    <!--[if lt IE 9]>\n      <script src=\"https://oss.maxcdn.com/html5shiv/3.7.3/html5shiv.min.js\"></script>\n      <script src=\"https://oss.maxcdn.com/respond/1.4.2/respond.min.js\"></script>\n    <![endif]-->\n\n</head>\n\n<body>\n    <div class=\"container\">\n    {# 闪现消息 success info warning danger #}\n    {% with messages = get_flashed_messages(with_categories=true) %}\n    {% if messages %}\n    {% for category, message in messages %}\n        <div class=\"alert alert-{{ category }}\" role=\"alert\">\n            <button type=\"button\" class=\"close\" data-dismiss=\"alert\" aria-hidden=\"true\">&times;</button>\n            {{ message }}\n        </div>\n    {% endfor %}\n    {% endif %}\n    {% endwith %}\n    </div>\n\n    <div class=\"container\">\n        <div class=\"row\">\n            <div class=\"col-md-4 col-md-offset-4\">\n                <div class=\"login-panel panel panel-default\">\n                    <div class=\"panel-heading\">\n                        <h3 class=\"panel-title\">后台登录</h3>\n                    </div>\n                    <div class=\"panel-body\">\n                        <form class=\"form-horizontal\" method=\"post\" action=\"\">\n                            {{ form.csrf_token }}\n\n                            <div class=\"form-group{% if form.account.errors %} has-error{% endif %}\">\n                                <div class=\"col-sm-12\">\n                                    {{ form.account(class=\"form-control\", placeholder=\"登录账号\") }}\n                                    {% for error in form.account.errors %}\n                                        <span class=\"help-block\">{{ error }}</span>\n                                    {% endfor %}\n                                </div>\n                            </div>\n                            <div class=\"form-group{% if form.password.errors %} has-error{% endif %}\">\n                                <div class=\"col-sm-12\">\n                                    {{ form.password(class=\"form-control\", placeholder=\"登录密码\") }}\n                                    {% for error in form.password.errors %}\n                                        <span class=\"help-block\">{{ error }}</span>\n                                    {% endfor %}\n                                </div>\n                            </div>\n                            <div class=\"form-group{% if form.sms.errors %} has-error{% endif %}\">\n                                <div class=\"col-sm-12\">\n                                    <div class=\"input-group\">\n                                        {{ form.sms(class=\"form-control\", placeholder=\"短信验证码\", maxlength=6) }}\n                                        <span class=\"input-group-btn\">\n                                            <button id=\"get_sms_btn\" class=\"btn btn-default\" type=\"button\">\n                                                <span class=\"glyphicon glyphicon-envelope\"></span> <i>发送短信</i>\n                                            </button>\n                                        </span>\n                                    </div>\n                                    {% for error in form.sms.errors %}\n                                        <span class=\"help-block\">{{ error }}</span>\n                                    {% endfor %}\n                                </div>\n                            </div>\n                            <div class=\"form-group{% if form.remember.errors %} has-error{% endif %}\">\n                                <div class=\"col-sm-12\">\n                                    <div class=\"checkbox\">\n                                        <label>\n                                            {{ form.remember }} 记住登录状态\n                                        </label>\n                                    </div>\n                                </div>\n                            </div>\n                            <div class=\"form-group\">\n                                <div class=\"col-sm-12\">\n                                    <button type=\"submit\" class=\"btn btn-success btn-load btn-block\" data-loading-text=\"登录中\" autocomplete=\"off\">登录</button>\n                                </div>\n                            </div>\n                        </form>\n                    </div>\n                    <div class=\"panel-footer text-center\"><i id=\"current_time\">{{ moment().format('dddd, MMMM Do YYYY, h:mm:ss a') }}</i></div>\n                </div>\n            </div>\n        </div>\n    </div>\n\n    <!-- /#wrapper -->\n\n    <!-- jQuery -->\n    <script src=\"{{ url_for('static', filename='js/jquery-1.11.3.min.js') }}\"></script>\n\n    <!-- Bootstrap Core JavaScript -->\n    <script src=\"{{ url_for('static', filename='js/bootstrap.min.js') }}\"></script>\n\n    {{ moment.include_moment() }}\n\n    {{ moment.lang('zh-cn') }}\n\n    <!-- Metis Menu Plugin JavaScript -->\n    <script src=\"{{ url_for('static', filename='plugin/metisMenu/metisMenu.min.js') }}\"></script>\n\n    <!-- Custom Theme JavaScript -->\n    <script src=\"{{ url_for('static', filename='js/sb-admin-2.js') }}\"></script>\n    <script src=\"{{ url_for('static', filename='js/custom.js', v='1.4.74') }}\"></script>\n\n    <script>\n        // 倒计时\n        var countdown=60;\n        function set_time(val) {\n            if (countdown == 0) {\n                val.removeAttr(\"disabled\");\n                val.find(\"i\").first().html(\"发送短信\");\n                countdown = 60;\n                return;\n            } else {\n                val.attr(\"disabled\", true);\n                val.find(\"i\").first().html(\"重新发送(\" + countdown + \")\");\n                countdown--;\n            }\n            setTimeout(function () {\n                set_time(val)\n            }, 1000)\n        }\n\n        // 当前时间同步刷新\n        var update_time;\n        (update_time = function () {\n            $('#current_time').html(moment().format('dddd, MMMM Do YYYY, h:mm:ss a'));\n        })();\n        setInterval(update_time, 1000);\n\n        // 点击发送手机验证码到手机 - ajax\n        $('#get_sms_btn').click(function () {\n            var cur_obj = $(this);\n            var account = $('#account');\n            // 校验手机号码，图形验证码\n            if(!account.val()){\n                account.focus();\n                return;\n            }\n            // 获取短信验证码\n            $.getJSON('{{ url_for('ajax_get_sms_code') }}',\n                {\n                    account: account.val()\n                }, function (data) {\n                    var result = data.result;  // true/false\n                    if(result==false){\n                        //console.log(result);\n                        alert(data.msg);\n                        account.focus();\n                        return false;\n                    }else {\n                        $('#sms').focus();\n                        set_time(cur_obj);\n                    }\n                }\n            );\n        });\n    </script>\n\n</body>\n\n</html>\n"
  },
  {
    "path": "app_backend/templates/macros.html",
    "content": "{% macro render_pagination(pagination, endpoint) %}\n    {% if pagination.pages > 0 %}\n    <nav class=\"text-center\">\n        <ul class=\"pagination\">\n            <li>\n                {% if pagination.has_prev %}\n                    <a href=\"{{ url_for(endpoint, page=pagination.prev_num, **request.args) }}\" aria-label=\"Previous\">\n                {% else %}\n                    <a href=\"javascript:void(0);\" aria-label=\"Previous\">\n                {% endif %}\n                <span aria-hidden=\"true\">&laquo;</span>\n                </a>\n            </li>\n            {% for page in pagination.iter_pages() %}\n                {% if page %}\n                    {% if page == pagination.page %}\n                        <li class=\"active\">\n                            {% else %}\n                        <li>\n                    {% endif %}\n                <a href=\"{{ url_for(endpoint, page=page, **request.args) }}\">{{ page }}</a>\n                </li>\n                {% endif %}\n            {% endfor %}\n            <li>\n                {% if pagination.has_next %}\n                    <a href=\"{{ url_for(endpoint, page=pagination.next_num, **request.args) }}\" aria-label=\"Next\">\n                {% else %}\n                    <a href=\"javascript:void(0);\" aria-label=\"Next\">\n                {% endif %}\n                <span aria-hidden=\"true\">&raquo;</span>\n                </a>\n            </li>\n        </ul>\n    </nav>\n    {% else %}\n    <section id=\"nothing\">\n        <div class=\"well well-large text-center\">\n            记录为空\n        </div>\n    </section>\n    {% endif %}\n{% endmacro %}\n\n\n{% macro render_nav(title) %}\n    {#    <nav class=\"navbar navbar-default\">#}\n    <nav class=\"navbar navbar-default navbar-fixed-top\">\n        <div class=\"container\">\n            <div class=\"navbar-header\">\n                <button type=\"button\" class=\"navbar-toggle collapsed\" data-toggle=\"collapse\" data-target=\"#navbar\"\n                        aria-expanded=\"false\">\n                    <span class=\"sr-only\">Toggle navigation</span>\n                    <span class=\"icon-bar\"></span>\n                    <span class=\"icon-bar\"></span>\n                    <span class=\"icon-bar\"></span>\n                </button>\n                <span class=\"navbar-brand\" href=\"{{ url_for('index') }}\">Flask Project</span>\n            </div>\n            <div id=\"navbar\" class=\"navbar-collapse collapse\">\n                <ul class=\"nav navbar-nav\">\n                    <li{% if title == 'home' %} class=\"active\"{% endif %}><a href=\"{{ url_for('index') }}\"><span\n                            class=\"glyphicon glyphicon-home\"></span> Home</a></li>\n                    <li{% if title == 'about' %} class=\"active\"{% endif %}><a href=\"{{ url_for('about') }}\"><span\n                            class=\"glyphicon glyphicon-list\"></span> About</a></li>\n                    <li{% if title == 'contact' %} class=\"active\"{% endif %}><a href=\"{{ url_for('contact') }}\"><span\n                            class=\"glyphicon glyphicon-envelope\"></span> Contact</a></li>\n                    <li class=\"dropdown\">\n                        <a href=\"#\" class=\"dropdown-toggle\" data-toggle=\"dropdown\" role=\"button\" aria-haspopup=\"true\"\n                           aria-expanded=\"false\"><span class=\"glyphicon glyphicon-book\"></span> Blog List <span\n                                class=\"caret\"></span></a>\n                        <ul class=\"dropdown-menu\">\n                            {% if title == 'blog_list' %}\n                                <li class=\"dropdown-header\">Blog List</li>{% else %}\n                                <li><a href=\"{{ url_for('blog.index') }}\">Blog List</a></li>{% endif %}\n                            {% if title == 'blog_new' %}\n                                <li class=\"dropdown-header\">Blog New</li>{% else %}\n                                <li><a href=\"{{ url_for('blog.new') }}\">Blog New</a></li>{% endif %}\n                            {% if title == 'blog_hot' %}\n                                <li class=\"dropdown-header\">Blog Hot</li>{% else %}\n                                <li><a href=\"{{ url_for('blog.hot') }}\">Blog Hot</a></li>{% endif %}\n                        </ul>\n                    </li>\n                </ul>\n                <form class=\"navbar-form navbar-left\" role=\"search\" action=\"{{ url_for('search') }}\">\n                    <div class=\"input-group\">\n                        <input type=\"text\" class=\"form-control\" placeholder=\"Search for...\" speech x-webkit-speech\n                               onwebkitspeechchange=\"$(this).cloest('form').submit()\">\n                        <span class=\"input-group-btn\">\n                            <button class=\"btn btn-default\" type=\"submit\"><span class=\"glyphicon glyphicon-search\"></span></button>\n                        </span>\n                    </div>\n                </form>\n                <ul class=\"nav navbar-nav navbar-right\">\n                    {% if current_user and current_user.is_authenticated %}\n                        <li class=\"dropdown\">\n                            <a href=\"#\" class=\"dropdown-toggle\" data-toggle=\"dropdown\" role=\"button\"\n                               aria-haspopup=\"true\"\n                               aria-expanded=\"false\"><span\n                                    class=\"glyphicon glyphicon-user\"></span> {{ current_user.nickname }}<span\n                                    class=\"caret\"></span></a>\n                            <ul class=\"dropdown-menu\">\n                                <li><a href=\"{{ url_for('blog.add') }}\"><span class=\"glyphicon glyphicon-edit\"></span>\n                                    Add Blog</a></li>\n                                <li><a href=\"{{ url_for('user.setting') }}\"><span class=\"glyphicon glyphicon-cog\"></span>\n                                    Setting</a></li>\n                                <li role=\"separator\" class=\"divider\"></li>\n                                <li><a href=\"{{ url_for('auth.logout') }}\"><span class=\"glyphicon glyphicon-log-out\"></span>\n                                    Logout</a></li>\n                            </ul>\n                        </li>\n                    {% else %}\n                        <li{% if title == 'reg' %} class=\"active\"{% endif %}><a href=\"{{ url_for('reg.index') }}\"><span\n                                class=\"glyphicon glyphicon-list-alt\"></span> Register</a></li>\n                        <li{% if title == 'login' %} class=\"active\"{% endif %}><a href=\"{{ url_for('auth.index') }}\"><span\n                                class=\"glyphicon glyphicon-log-in\"></span> Login</a></li>\n                    {% endif %}\n                </ul>\n            </div><!--/.nav-collapse -->\n        </div>\n    </nav>\n{% endmacro %}\n\n\n{% macro render_ground(title) %}\n    {#    <nav class=\"navbar navbar-default\">#}\n    <nav class=\"page-menu navbar-default\" id=\"menu\">\n        <div class=\"container\">\n            <div class=\"navbar-header\">\n            </div>\n            <div class=\"collapse in\" aria-expanded=\"true\">\n                <ul class=\"nav navbar-nav\">\n                    <li{% if title == 'home' %} class=\"active\"{% endif %}><a href=\"{{ url_for('index') }}\"><span\n                            class=\"glyphicon glyphicon-home\"></span> Home</a></li>\n                    <li{% if title == 'about' %} class=\"active\"{% endif %}><a href=\"{{ url_for('about') }}\"><span\n                            class=\"glyphicon glyphicon-list\"></span> About</a></li>\n                    <li{% if title == 'contact' %} class=\"active\"{% endif %}><a href=\"{{ url_for('contact') }}\"><span\n                            class=\"glyphicon glyphicon-envelope\"></span> Contact</a></li>\n                    <li class=\"dropdown\">\n                        <a href=\"#\" class=\"dropdown-toggle\" data-toggle=\"dropdown\" role=\"button\" aria-haspopup=\"true\"\n                           aria-expanded=\"false\"><span class=\"glyphicon glyphicon-book\"></span> Blog List <span\n                                class=\"caret\"></span></a>\n                        <ul class=\"dropdown-menu\">\n                            {% if title == 'blog_list' %}\n                                <li class=\"dropdown-header\">Blog List</li>{% else %}\n                                <li><a href=\"{{ url_for('blog.index') }}\">Blog List</a></li>{% endif %}\n                            {% if title == 'blog_new' %}\n                                <li class=\"dropdown-header\">Blog New</li>{% else %}\n                                <li><a href=\"{{ url_for('blog.new') }}\">Blog New</a></li>{% endif %}\n                            {% if title == 'blog_hot' %}\n                                <li class=\"dropdown-header\">Blog Hot</li>{% else %}\n                                <li><a href=\"{{ url_for('blog.hot') }}\">Blog Hot</a></li>{% endif %}\n                        </ul>\n                    </li>\n                </ul>\n                <form class=\"navbar-form navbar-left\" role=\"search\" action=\"{{ url_for('search') }}\">\n                    <div class=\"input-group\">\n                        <input type=\"text\" class=\"form-control\" placeholder=\"Search for...\" speech x-webkit-speech\n                               onwebkitspeechchange=\"$(this).cloest('form').submit()\">\n                        <span class=\"input-group-btn\">\n                            <button class=\"btn btn-default\" type=\"submit\"><span class=\"glyphicon glyphicon-search\"></span></button>\n                        </span>\n                    </div>\n                </form>\n                <ul class=\"nav navbar-nav navbar-right\">\n                    {% if current_user and current_user.is_authenticated %}\n                        <li class=\"dropdown\">\n                            <a href=\"#\" class=\"dropdown-toggle\" data-toggle=\"dropdown\" role=\"button\"\n                               aria-haspopup=\"true\"\n                               aria-expanded=\"false\"><span\n                                    class=\"glyphicon glyphicon-user\"></span> {{ current_user.nickname }}<span\n                                    class=\"caret\"></span></a>\n                            <ul class=\"dropdown-menu\">\n                                <li><a href=\"{{ url_for('blog.add') }}\"><span class=\"glyphicon glyphicon-edit\"></span>\n                                    Add Blog</a></li>\n                                <li><a href=\"{{ url_for('user.setting') }}\"><span class=\"glyphicon glyphicon-cog\"></span>\n                                    Setting</a></li>\n                                <li role=\"separator\" class=\"divider\"></li>\n                                <li><a href=\"{{ url_for('auth.logout') }}\"><span class=\"glyphicon glyphicon-log-out\"></span>\n                                    Logout</a></li>\n                            </ul>\n                        </li>\n                    {% else %}\n                        <li{% if title == 'reg' %} class=\"active\"{% endif %}><a href=\"{{ url_for('reg.index') }}\"><span\n                                class=\"glyphicon glyphicon-list-alt\"></span> Register</a></li>\n                        <li{% if title == 'login' %} class=\"active\"{% endif %}><a href=\"{{ url_for('auth.index') }}\"><span\n                                class=\"glyphicon glyphicon-log-in\"></span> Login</a></li>\n                    {% endif %}\n                </ul>\n            </div><!--/.nav-collapse -->\n        </div>\n    </nav>\n{% endmacro %}\n"
  },
  {
    "path": "app_backend/templates/main.html",
    "content": "<div class=\"row\">\n    <div class=\"col-lg-12\">\n        <h1 class=\"page-header\">Blank</h1>\n    </div>\n    <!-- /.col-lg-12 -->\n</div>\n<!-- /.row -->\n"
  },
  {
    "path": "app_backend/templates/message/list.html",
    "content": "{% extends \"layout.html\" %}\n\n{% block content %}\n<div class=\"container-fluid\">\n    <ol class=\"breadcrumb\">\n        <li><a href=\"/\">后台管理</a></li>\n        <li><a href=\"javascript:void(0);\" onclick=\"$('#menu-message').trigger('click');\">留言管理</a></li>\n        <li class=\"active\">留言列表</li>\n    </ol>\n\n    <!-- content -->\n    <div class=\"table-responsive\">\n        {# <table class=\"table table-striped\"> #}\n        <table class=\"table table-hover\">\n            <thead>\n            <tr>\n                <th>消息明细ID</th>\n                <th>发送用户</th>\n                <th>接收用户</th>\n                <th>消息</th>\n                <th>时间</th>\n                <th>操作</th>\n            </tr>\n            </thead>\n            <tbody>\n            {% for msg, user_profile_put, user_profile_get in pagination.items %}\n            <tr class=\"text-muted\">\n                <td>{{ msg.id }}</td>\n                <td>{{ user_profile_put.nickname | default('系统消息') }} [{{ user_profile_put.user_id }}]</td>\n                <td>{{ user_profile_get.nickname }} [{{ user_profile_get.user_id }}]</td>\n                <td>{{ msg.content }}</td>\n                <td>{{ moment(msg.create_time).format('YYYY-MM-DD HH:mm:ss') }}</td>\n                <td>\n                    <a href=\"javascript:void(0);\" onclick=\"msg_delete({{ msg.id }});\" rel=\"tooltip\" title=\"删除\"><span class=\"glyphicon glyphicon-trash\"></span></a>\n                </td>\n            </tr>\n            {% endfor %}\n            </tbody>\n        </table>\n        {# 翻页 #}\n        {% from \"macros.html\" import render_pagination %}\n        {{ render_pagination(pagination, 'message.lists') }}\n    </div>\n\n\n</div>\n\n{% endblock %}\n\n{% block extra_js %}\n<script>\n    // 留言删除\n    function msg_delete(msg_id){\n        if(confirm(\"删除数据不能恢复，是否确认删除?\"))\n        {\n            // console.log(user_id);\n            $.getJSON('{{ url_for('message.ajax_delete') }}',\n            {\n                msg_id: msg_id\n            }, function (result) {\n                if(result.hasOwnProperty('error')){\n                    alert(result.error);\n                }else {\n                    alert(result.success);\n                    window.location.reload();\n                }\n            });\n            return false;\n        }\n    }\n</script>\n{% endblock %}"
  },
  {
    "path": "app_backend/templates/order/list.html",
    "content": "<!-- extend from base layout -->\n{% extends \"layout.html\" %}\n\n{% block extra_css %}\n\n{% endblock %}\n\n{% block content %}\n    <div class=\"container-fluid\">\n    <ol class=\"breadcrumb\">\n        <li><a href=\"/\">后台管理</a></li>\n        <li><a href=\"javascript:void(0);\" onclick=\"$('#menu-order').trigger('click');\">订单管理</a></li>\n        <li class=\"active\">订单列表</li>\n    </ol>\n\n    <form class=\"form-inline\">\n        <div class=\"form-group{% if form.order_id.errors %} has-error{% endif %}\">\n            {{ form.order_id.label(class=\"sr-only\") }}\n            {{ form.order_id(class=\"form-control\", placeholder=\"订单ID\") }}\n            {% for error in form.order_id.errors %}\n                <span class=\"help-block\">{{ error }}</span>\n            {% endfor %}\n        </div>\n        <div class=\"form-group{% if form.apply_put_id.errors %} has-error{% endif %}\">\n            {{ form.apply_put_id.label(class=\"sr-only\") }}\n            {{ form.apply_put_id(class=\"form-control\", placeholder=\"申请投资ID\") }}\n            {% for error in form.apply_put_id.errors %}\n                <span class=\"help-block\">{{ error }}</span>\n            {% endfor %}\n        </div>\n        <div class=\"form-group{% if form.apply_get_id.errors %} has-error{% endif %}\">\n            {{ form.apply_get_id.label(class=\"sr-only\") }}\n            {{ form.apply_get_id(class=\"form-control\", placeholder=\"申请提现ID\") }}\n            {% for error in form.apply_get_id.errors %}\n                <span class=\"help-block\">{{ error }}</span>\n            {% endfor %}\n        </div>\n        <div class=\"form-group{% if form.apply_put_uid.errors %} has-error{% endif %}\">\n            {{ form.apply_put_uid.label(class=\"sr-only\") }}\n            {{ form.apply_put_uid(class=\"form-control\", placeholder=\"申请投资UID\") }}\n            {% for error in form.apply_put_uid.errors %}\n                <span class=\"help-block\">{{ error }}</span>\n            {% endfor %}\n        </div>\n        <div class=\"form-group{% if form.apply_get_uid.errors %} has-error{% endif %}\">\n            {{ form.apply_get_uid.label(class=\"sr-only\") }}\n            {{ form.apply_get_uid(class=\"form-control\", placeholder=\"申请提现UID\") }}\n            {% for error in form.apply_get_uid.errors %}\n                <span class=\"help-block\">{{ error }}</span>\n            {% endfor %}\n        </div>\n        <div class=\"form-group{% if form.status_audit.errors %} has-error{% endif %}\">\n            {{ form.status_audit.label(class=\"sr-only\") }}\n            {{ form.status_audit(class=\"form-control\", placeholder=\"审核状态\", data_width=\"fit\", data_header=\"选择状态\") }}\n            {% for error in form.status_audit.errors %}\n                <span class=\"help-block\">{{ error }}</span>\n            {% endfor %}\n        </div>\n        <div class=\"form-group{% if form.status_pay.errors %} has-error{% endif %}\">\n            {{ form.status_pay.label(class=\"sr-only\") }}\n            {{ form.status_pay(class=\"form-control\", placeholder=\"支付状态\", data_width=\"fit\", data_header=\"选择状态\") }}\n            {% for error in form.status_pay.errors %}\n                <span class=\"help-block\">{{ error }}</span>\n            {% endfor %}\n        </div>\n        <div class=\"form-group{% if form.status_rec.errors %} has-error{% endif %}\">\n            {{ form.status_rec.label(class=\"sr-only\") }}\n            {{ form.status_rec(class=\"form-control\", placeholder=\"收款状态\", data_width=\"fit\", data_header=\"选择状态\") }}\n            {% for error in form.status_rec.errors %}\n                <span class=\"help-block\">{{ error }}</span>\n            {% endfor %}\n        </div>\n        <div class=\"form-group{% if form.start_time.errors %} has-error{% endif %}\">\n            {{ form.start_time.label(class=\"sr-only\") }}\n            {{ form.start_time(class=\"form-control\", placeholder=\"start_time\", type='date') }}\n            {% for error in form.start_time.errors %}\n                <span class=\"help-block\">{{ error }}</span>\n            {% endfor %}\n        </div>\n        <div class=\"form-group{% if form.end_time.errors %} has-error{% endif %}\">\n            {{ form.end_time.label(class=\"sr-only\") }}\n            {{ form.end_time(class=\"form-control\", placeholder=\"end_time\", type='date') }}\n            {% for error in form.end_time.errors %}\n                <span class=\"help-block\">{{ error }}</span>\n            {% endfor %}\n        </div>\n\n        <button type=\"submit\" class=\"btn btn-primary\" name=\"op\" value=\"0\">Search</button>\n        <button type=\"submit\" class=\"btn btn-primary\" name=\"op\" value=\"1\">Export</button>\n    </form>\n\n    <hr/>\n\n    <div class=\"table-responsive\">\n        {# <table class=\"table table-striped\"> #}\n        <table class=\"table table-hover\">\n            <thead>\n            <tr>\n                <th>订单ID</th>\n                <th>投资ID</th>\n                <th>提现ID</th>\n                <th>投资用户</th>\n                <th>提现用户</th>\n                <th>订单金额</th>\n                <th>认证状态</th>\n                <th>支付状态</th>\n                <th>确认状态</th>\n                <th>匹配时间</th>\n                <th>操作</th>\n            </tr>\n            </thead>\n            <tbody>\n            {% for order, user_profile_put, user_profile_get in pagination.items %}\n            <tr class=\"text-muted\">\n                <td>{{ order.id }}</td>\n                <td>{{ order.apply_put_id }}</td>\n                <td>{{ order.apply_get_id }}</td>\n                <td>{{ user_profile_put.nickname }} [{{ order.apply_put_uid }}]</td>\n                <td>{{ user_profile_get.nickname }} [{{ order.apply_get_uid }}]</td>\n                <td>{{ order.money }}</td>\n                <td>{{ order.status_audit | status_audit }}</td>\n                <td>{{ order.status_pay | status_pay }}</td>\n                <td>{{ order.status_rec | status_rec }}</td>\n                <td>{{ moment(order.create_time).format('YYYY-MM-DD HH:mm:ss') }}</td>\n                <td>\n                    <a href=\"javascript:void(0);\" onclick=\"order_audit({{ order.id }});\" rel=\"tooltip\" title=\"审核\"><span class=\"glyphicon glyphicon-check\"></span></a>\n                    <a href=\"javascript:void(0);\" onclick=\"order_delete({{ order.id }});\" rel=\"tooltip\" title=\"删除\"><span class=\"glyphicon glyphicon-trash\"></span></a>\n                </td>\n            </tr>\n            {% endfor %}\n            </tbody>\n        </table>\n        {# 翻页 #}\n        {% from \"macros.html\" import render_pagination %}\n        {{ render_pagination(pagination, 'order.lists') }}\n    </div>\n    </div>\n{% endblock %}\n\n{% block extra_js %}\n<script>\n    // 初始化赋值\n    var status_audit = $('#status_audit');\n    status_audit.selectpicker('val', '{{ form.status_audit.data }}');\n    // 处理选项修改\n    status_audit.on('changed.bs.select', function (event, clickedIndex, newValue, oldValue) {\n        // console.log($('#status_audit').val());\n        // console.log(event);\n        // console.log(clickedIndex);\n        // console.log(newValue);\n        // console.log(oldValue);\n    });\n\n    var status_pay = $('#status_pay');\n    status_pay.selectpicker('val', '{{ form.status_pay.data }}');\n    // 处理选项修改\n    status_pay.on('changed.bs.select', function (event, clickedIndex, newValue, oldValue) {\n        // console.log($('#status_pay').val());\n        // console.log(event);\n        // console.log(clickedIndex);\n        // console.log(newValue);\n        // console.log(oldValue);\n    });\n\n    var status_rec = $('#status_rec');\n    status_rec.selectpicker('val', '{{ form.status_rec.data }}');\n    // 处理选项修改\n    status_rec.on('changed.bs.select', function (event, clickedIndex, newValue, oldValue) {\n        // console.log($('#status_rec').val());\n        // console.log(event);\n        // console.log(clickedIndex);\n        // console.log(newValue);\n        // console.log(oldValue);\n    });\n\n    // 订单审核\n    function order_audit(order_id){\n        if(confirm(\"是否确认审核通过?\"))\n        {\n            // console.log(order_id);\n            $.getJSON('{{ url_for('order.ajax_audit') }}',\n            {\n                order_id: order_id\n            }, function (result) {\n                if(result.hasOwnProperty('error')){\n                    alert(result.error);\n                }else {\n                    alert(result.success);\n                    window.location.reload();\n                }\n            });\n            return false;\n        }\n    }\n\n    // 订单删除\n    function order_delete(order_id){\n        if(confirm(\"删除数据不能恢复，是否确认删除?\"))\n        {\n            // console.log(order_id);\n            $.getJSON('{{ url_for('order.ajax_delete') }}',\n            {\n                order_id: order_id\n            }, function (result) {\n                if(result.hasOwnProperty('error')){\n                    alert(result.error);\n                }else {\n                    alert(result.success);\n                    window.location.reload();\n                }\n            });\n            return false;\n        }\n    }\n</script>\n{% endblock %}\n"
  },
  {
    "path": "app_backend/templates/order/stats.html",
    "content": "{% extends \"layout.html\" %}\n\n{% block content %}\n<div class=\"container-fluid\">\n    <ol class=\"breadcrumb\">\n        <li><a href=\"/\">后台管理</a></li>\n        <li><a href=\"javascript:void(0);\" onclick=\"$('#menu-stats').trigger('click');\">运营统计</a></li>\n        <li class=\"active\">订单统计</li>\n    </ol>\n    <h2 class=\"sub-header\">Order Stats!</h2>\n\n\n</div>\n\n{% endblock %}"
  },
  {
    "path": "app_backend/templates/scheduling/add.html",
    "content": "<!-- extend from base layout -->\n{% extends \"layout.html\" %}\n\n{% block content %}\n    <div class=\"container\">\n    <ol class=\"breadcrumb\">\n        <li><a href=\"/\">首页</a></li>\n        <li class=\"active\">发送排单币</li>\n    </ol>\n    <form class=\"form-horizontal\" method=\"post\" action=\"\">\n        {{ form.csrf_token }}\n        <div class=\"form-group{% if form.user_id.errors %} has-error{% endif %}\">\n            {{ form.user_id.label(class=\"col-sm-2 control-label\") }}\n            <div class=\"col-sm-10\">\n                {{ form.user_id(class=\"form-control\", placeholder=\"填写用户ID\") }}\n                {% for error in form.user_id.errors %}\n                    <span class=\"help-block\">{{ error }}</span>\n                {% endfor %}\n            </div>\n        </div>\n        <div class=\"form-group{% if form.amount.errors %} has-error{% endif %}\">\n            {{ form.amount.label(class=\"col-sm-2 control-label\") }}\n            <div class=\"col-sm-10\">\n                {{ form.amount(class=\"form-control\", placeholder=\"填写发送数量\", type=\"number\", min=\"1\") }}\n                {% for error in form.amount.errors %}\n                    <span class=\"help-block\">{{ error }}</span>\n                {% endfor %}\n                <span class=\"help-block\">发送数量必须为整数 [当前剩余排单数量：{{ form.user_id.data | scheduling_amount }}]</span>\n            </div>\n        </div>\n        <div class=\"form-group\">\n            <div class=\"col-sm-offset-2 col-sm-10\">\n                <button type=\"submit\" class=\"btn btn-success btn-load\" data-loading-text=\"发送中\">发送</button>\n                <button type=\"reset\" class=\"btn btn-default\">重新填写</button>\n                <button class=\"btn btn-default\" onclick=\"history.back();\">返回</button>\n            </div>\n        </div>\n    </form>\n    </div>\n{% endblock %}\n"
  },
  {
    "path": "app_backend/templates/scheduling/list.html",
    "content": "<!-- extend from base layout -->\n{% extends \"layout.html\" %}\n\n{% block extra_css %}\n\n{% endblock %}\n\n{% block content %}\n    <div class=\"container\">\n    <!-- header -->\n    <nav class=\"sub-header row container-fluid\">\n        <ol class=\"breadcrumb\">\n            <li><a href=\"/\">首页</a></li>\n            <li class=\"active\">排单列表</li>\n        </ol>\n        <div class=\"btn-group pull-right\" role=\"group\" aria-label=\"...\">\n            {% if not request.query_string %}\n            <a type=\"button\" class=\"btn btn-default active\">全部</a>\n            <a type=\"button\" class=\"btn btn-default\" href=\"{{ url_for('scheduling.lists', scheduling_list=1) }}\">用户排单</a>\n            <a type=\"button\" class=\"btn btn-default\" href=\"{{ url_for('scheduling.lists', scheduling_list=2) }}\">系统发送</a>\n            {% elif request.query_string==\"scheduling_list=1\" %}\n            <a type=\"button\" class=\"btn btn-default\" href=\"{{ url_for('scheduling.lists') }}\">全部</a>\n            <a type=\"button\" class=\"btn btn-default active\">用户排单</a>\n            <a type=\"button\" class=\"btn btn-default\" href=\"{{ url_for('scheduling.lists', scheduling_list=2) }}\">系统发送</a>\n            {% elif request.query_string==\"scheduling_list=2\" %}\n            <a type=\"button\" class=\"btn btn-default\" href=\"{{ url_for('scheduling.lists') }}\">全部</a>\n            <a type=\"button\" class=\"btn btn-default\" href=\"{{ url_for('scheduling.lists', scheduling_list=1) }}\">用户排单</a>\n            <a type=\"button\" class=\"btn btn-default active\">系统发送</a>\n            {% endif %}\n        </div>\n    </nav>\n\n\n    <hr/>\n    <!-- content -->\n    <div class=\"table-responsive\">\n        {# <table class=\"table table-striped\"> #}\n        <table class=\"table table-hover\">\n            <thead>\n            <tr>\n                <th>排单明细ID</th>\n                <th>用户</th>\n                <th>类型</th>\n                <th>数量</th>\n                <th>时间</th>\n            </tr>\n            </thead>\n            <tbody>\n            {% for scheduling, user_profile_put, user_profile_get in pagination.items %}\n            <tr class=\"text-muted\">\n                <td>{{ scheduling.id }}</td>\n                <td>{{ user_profile_get.nickname }} [{{ scheduling.sc_id }}]</td>\n                <td>{{ scheduling.type | type_scheduling }}</td>\n                <td>{{ scheduling.amount }}</td>\n                <td>{{ moment(scheduling.create_time).format('YYYY-MM-DD HH:mm:ss') }}</td>\n            </tr>\n            {% endfor %}\n            </tbody>\n        </table>\n        {# 翻页 #}\n        {% from \"macros.html\" import render_pagination %}\n        {{ render_pagination(pagination, 'scheduling.lists') }}\n    </div>\n    </div>\n{% endblock %}\n\n{% block extra_js %}\n\n{% endblock %}\n"
  },
  {
    "path": "app_backend/templates/score/list.html",
    "content": "<!-- extend from base layout -->\n{% extends \"layout.html\" %}\n\n{% block extra_css %}\n\n{% endblock %}\n\n{% block content %}\n    <div class=\"container-fluid\">\n    <h2 class=\"sub-header\">Apply Get List!</h2>\n\n    <form class=\"form-inline\">\n        <div class=\"form-group{% if form.apply_get_id.errors %} has-error{% endif %}\">\n            {{ form.apply_get_id.label(class=\"sr-only\") }}\n            {{ form.apply_get_id(class=\"form-control\", placeholder=\"Apply Get Id\") }}\n            {% for error in form.apply_get_id.errors %}\n                <span class=\"help-block\">{{ error }}</span>\n            {% endfor %}\n        </div>\n        <div class=\"form-group{% if form.user_id.errors %} has-error{% endif %}\">\n            {{ form.user_id.label(class=\"sr-only\") }}\n            {{ form.user_id(class=\"form-control\", placeholder=\"User Id\") }}\n            {% for error in form.user_id.errors %}\n                <span class=\"help-block\">{{ error }}</span>\n            {% endfor %}\n        </div>\n        <div class=\"form-group{% if form.type_apply.errors %} has-error{% endif %}\">\n            {{ form.type_apply.label(class=\"sr-only\") }}\n            {{ form.type_apply(class=\"form-control\", placeholder=\"申请类型\", data_width=\"fit\", data_header=\"选择类型\") }}\n            {% for error in form.type_apply.errors %}\n                <span class=\"help-block\">{{ error }}</span>\n            {% endfor %}\n        </div>\n        <div class=\"form-group{% if form.start_time.errors %} has-error{% endif %}\">\n            {{ form.start_time.label(class=\"sr-only\") }}\n            {{ form.start_time(class=\"form-control\", placeholder=\"start_time\", type='date') }}\n            {% for error in form.start_time.errors %}\n                <span class=\"help-block\">{{ error }}</span>\n            {% endfor %}\n        </div>\n        <div class=\"form-group{% if form.end_time.errors %} has-error{% endif %}\">\n            {{ form.end_time.label(class=\"sr-only\") }}\n            {{ form.end_time(class=\"form-control\", placeholder=\"end_time\", type='date') }}\n            {% for error in form.end_time.errors %}\n                <span class=\"help-block\">{{ error }}</span>\n            {% endfor %}\n        </div>\n\n        <button type=\"submit\" class=\"btn btn-primary\" name=\"op\" value=\"0\">Search</button>\n        <button type=\"submit\" class=\"btn btn-primary\" name=\"op\" value=\"1\">Export</button>\n    </form>\n\n    <hr/>\n\n    <div class=\"table-responsive\">\n        {# <table class=\"table table-striped\"> #}\n        <table class=\"table table-hover\">\n            <thead>\n            <tr>\n                <th>id</th>\n                <th>user_id</th>\n                <th>type_apply</th>\n                <th>money_apply</th>\n                <th>status_apply</th>\n                <th>status_order</th>\n                <th>status_delete</th>\n                <th>create_time</th>\n                <th>action</th>\n            </tr>\n            </thead>\n            <tbody>\n            {% for apply_get in pagination.items %}\n            <tr class=\"text-muted\">\n                <td>{{ apply_get.id }}</td>\n                <td>{{ apply_get.user_id }}</td>\n                <td>{{ apply_get.type_apply }}</td>\n                <td>{{ apply_get.money_apply }}</td>\n                <td>{{ apply_get.status_apply }}</td>\n                <td>{{ apply_get.status_order }}</td>\n                <td>{{ apply_get.status_delete }}</td>\n                <td>{{ moment(apply_get.create_time).format('YYYY-MM-DD HH:mm:ss') }}</td>\n                <td>\n                    <a href=\"javascript:void(0);\" onclick=\"apply_get_delete({{ apply_get.id }});\" rel=\"tooltip\" title=\"删除\"><span class=\"glyphicon glyphicon-trash\"></span></a>\n                </td>\n            </tr>\n            {% endfor %}\n            </tbody>\n        </table>\n        {# 翻页 #}\n        {% from \"macros.html\" import render_pagination %}\n        {{ render_pagination(pagination, 'user.lists') }}\n    </div>\n    </div>\n{% endblock %}\n\n{% block extra_js %}\n<script>\n    // 初始化赋值\n    var type_apply = $('#type_apply');\n    type_apply.selectpicker('val', '{{ form.type_apply.data }}');\n    // 处理选项修改\n    type_apply.on('changed.bs.select', function (event, clickedIndex, newValue, oldValue) {\n        // console.log($('#status_lock').val());\n        // console.log(event);\n        // console.log(clickedIndex);\n        // console.log(newValue);\n        // console.log(oldValue);\n    });\n    function apply_get_delete(apply_get_id){\n        if(confirm(\"删除数据不能恢复，是否确认删除?\"))\n        {\n            // console.log(user_id);\n            $.getJSON('{{ url_for('apply_get.delete') }}',\n            {\n                apply_get_id: apply_get_id\n            }, function (data) {\n                var result = data.result;  // true/false\n                // console.log(result==true);\n                if(result==true){\n                    window.location.reload();\n                }\n            });\n            return false;\n        }\n    }\n</script>\n{% endblock %}\n"
  },
  {
    "path": "app_backend/templates/score/stats.html",
    "content": "{% extends \"layout.html\" %}\n\n{% block content %}\n<div class=\"container-fluid\">\n    <ol class=\"breadcrumb\">\n        <li><a href=\"/\">后台管理</a></li>\n        <li><a href=\"javascript:void(0);\" onclick=\"$('#menu-stats').trigger('click');\">运营统计</a></li>\n        <li class=\"active\">积分统计</li>\n    </ol>\n    <h2 class=\"sub-header\">Score Stats!</h2>\n\n\n</div>\n\n{% endblock %}"
  },
  {
    "path": "app_backend/templates/settings/apply_get.html",
    "content": "{% extends \"layout.html\" %}\n\n{% block content %}\n<div class=\"container-fluid\">\n    <ol class=\"breadcrumb\">\n        <li><a href=\"/\">后台管理</a></li>\n        <li><a href=\"javascript:void(0);\" onclick=\"$('#menu-settings').trigger('click');\">系统配置</a></li>\n        <li class=\"active\">提现配置</li>\n    </ol>\n{#    <h2 class=\"sub-header\">Order Setting!</h2>#}\n    {# 表单 #}\n    <form class=\"form-horizontal\" method=\"post\" action=\"\">\n        {{ form.csrf_token }}\n        <p></p>\n        <blockquote>\n            <p class=\"text-muted\">单次提现限制</p>\n        </blockquote>\n        <div class=\"form-group{% if form.APPLY_GET_MIN_EACH.errors %} has-error{% endif %}\">\n            {{ form.APPLY_GET_MIN_EACH.label(class=\"col-sm-2 control-label\") }}\n            <div class=\"col-sm-10\">\n                {{ form.APPLY_GET_MIN_EACH(class=\"form-control\", placeholder=\"单次提现最小金额 [单位：元]\", type=\"number\") }}\n                {% for error in form.APPLY_GET_MIN_EACH.errors %}\n                    <span class=\"help-block\">{{ error }}</span>\n                {% endfor %}\n            </div>\n        </div>\n        <div class=\"form-group{% if form.APPLY_GET_MAX_EACH.errors %} has-error{% endif %}\">\n            {{ form.APPLY_GET_MAX_EACH.label(class=\"col-sm-2 control-label\") }}\n            <div class=\"col-sm-10\">\n                {{ form.APPLY_GET_MAX_EACH(class=\"form-control\", placeholder=\"单次提现最大金额 [单位：元]\", type=\"number\") }}\n                {% for error in form.APPLY_GET_MAX_EACH.errors %}\n                    <span class=\"help-block\">{{ error }}</span>\n                {% endfor %}\n            </div>\n        </div>\n        <div class=\"form-group{% if form.APPLY_GET_STEP.errors %} has-error{% endif %}\">\n            {{ form.APPLY_GET_STEP.label(class=\"col-sm-2 control-label\") }}\n            <div class=\"col-sm-10\">\n                {{ form.APPLY_GET_STEP(class=\"form-control\", placeholder=\"提现金额调整基数 [单位：元]\", type=\"number\") }}\n                {% for error in form.APPLY_GET_STEP.errors %}\n                    <span class=\"help-block\">{{ error }}</span>\n                {% endfor %}\n            </div>\n        </div>\n        <hr>\n        <blockquote>\n            <p class=\"text-muted\">单个用户提现限制</p>\n        </blockquote>\n        <div class=\"form-group{% if form.APPLY_GET_USER_MAX_AMOUNT.errors %} has-error{% endif %}\">\n            {{ form.APPLY_GET_USER_MAX_AMOUNT.label(class=\"col-sm-2 control-label\") }}\n            <div class=\"col-sm-10\">\n                {{ form.APPLY_GET_USER_MAX_AMOUNT(class=\"form-control\", placeholder=\"单个用户提现最大交易中金额 [单位：元]\", type=\"number\") }}\n                {% for error in form.APPLY_GET_USER_MAX_AMOUNT.errors %}\n                    <span class=\"help-block\">{{ error }}</span>\n                {% endfor %}\n            </div>\n        </div>\n        <div class=\"form-group{% if form.APPLY_GET_USER_MAX_COUNT.errors %} has-error{% endif %}\">\n            {{ form.APPLY_GET_USER_MAX_COUNT.label(class=\"col-sm-2 control-label\") }}\n            <div class=\"col-sm-10\">\n                {{ form.APPLY_GET_USER_MAX_COUNT(class=\"form-control\", placeholder=\"单个用户提现最大交易中单数(0 表示不限制)\", type=\"number\") }}\n                {% for error in form.APPLY_GET_USER_MAX_COUNT.errors %}\n                    <span class=\"help-block\">{{ error }}</span>\n                {% endfor %}\n            </div>\n        </div>\n        <hr>\n        <blockquote>\n            <p class=\"text-muted\">每日提现限制</p>\n        </blockquote>\n\n        <div class=\"form-group{% if form.APPLY_GET_MAX_AMOUNT_DAILY.errors %} has-error{% endif %}\">\n            {{ form.APPLY_GET_MAX_AMOUNT_DAILY.label(class=\"col-sm-2 control-label\") }}\n            <div class=\"col-sm-10\">\n                {{ form.APPLY_GET_MAX_AMOUNT_DAILY(class=\"form-control\", placeholder=\"每日提现最大金额 [单位：元]\", type=\"number\") }}\n                {% for error in form.APPLY_GET_MAX_AMOUNT_DAILY.errors %}\n                    <span class=\"help-block\">{{ error }}</span>\n                {% endfor %}\n            </div>\n        </div>\n        <div class=\"form-group{% if form.APPLY_GET_MAX_COUNT_DAILY.errors %} has-error{% endif %}\">\n            {{ form.APPLY_GET_MAX_COUNT_DAILY.label(class=\"col-sm-2 control-label\") }}\n            <div class=\"col-sm-10\">\n                {{ form.APPLY_GET_MAX_COUNT_DAILY(class=\"form-control\", placeholder=\"每日提现最大单数\", type=\"number\") }}\n                {% for error in form.APPLY_GET_MAX_COUNT_DAILY.errors %}\n                    <span class=\"help-block\">{{ error }}</span>\n                {% endfor %}\n            </div>\n        </div>\n        <hr>\n        <blockquote>\n            <p class=\"text-muted\">每月提现限制</p>\n        </blockquote>\n\n        <div class=\"form-group{% if form.APPLY_GET_MAX_AMOUNT_MONTHLY.errors %} has-error{% endif %}\">\n            {{ form.APPLY_GET_MAX_AMOUNT_MONTHLY.label(class=\"col-sm-2 control-label\") }}\n            <div class=\"col-sm-10\">\n                {{ form.APPLY_GET_MAX_AMOUNT_MONTHLY(class=\"form-control\", placeholder=\"每月提现最大金额 [单位：元]\", type=\"number\") }}\n                {% for error in form.APPLY_GET_MAX_AMOUNT_MONTHLY.errors %}\n                    <span class=\"help-block\">{{ error }}</span>\n                {% endfor %}\n            </div>\n        </div>\n        <div class=\"form-group{% if form.APPLY_GET_MAX_COUNT_MONTHLY.errors %} has-error{% endif %}\">\n            {{ form.APPLY_GET_MAX_COUNT_MONTHLY.label(class=\"col-sm-2 control-label\") }}\n            <div class=\"col-sm-10\">\n                {{ form.APPLY_GET_MAX_COUNT_MONTHLY(class=\"form-control\", placeholder=\"每月提现最大单数\", type=\"number\") }}\n                {% for error in form.APPLY_GET_MAX_COUNT_MONTHLY.errors %}\n                    <span class=\"help-block\">{{ error }}</span>\n                {% endfor %}\n            </div>\n        </div>\n        <hr>\n        <blockquote>\n            <p class=\"text-muted\">提现时间配置</p>\n        </blockquote>\n\n        <div class=\"form-group{% if form.APPLY_GET_TIME_START.errors %} has-error{% endif %}\">\n            {{ form.APPLY_GET_TIME_START.label(class=\"col-sm-2 control-label\") }}\n            <div class=\"col-sm-10\">\n                {{ form.APPLY_GET_TIME_START(class=\"form-control\", placeholder=\"每天提现申请开始时间 [00:00:00-23:59:59]\") }}\n                {% for error in form.APPLY_GET_TIME_START.errors %}\n                    <span class=\"help-block\">{{ error }}</span>\n                {% endfor %}\n            </div>\n        </div>\n        <div class=\"form-group{% if form.APPLY_GET_TIME_END.errors %} has-error{% endif %}\">\n            {{ form.APPLY_GET_TIME_END.label(class=\"col-sm-2 control-label\") }}\n            <div class=\"col-sm-10\">\n                {{ form.APPLY_GET_TIME_END(class=\"form-control\", placeholder=\"每天提现申请结束时间 [00:00:00-23:59:59]\") }}\n                {% for error in form.APPLY_GET_TIME_END.errors %}\n                    <span class=\"help-block\">{{ error }}</span>\n                {% endfor %}\n            </div>\n        </div>\n\n        <div class=\"form-group\">\n            <div class=\"col-sm-offset-2 col-sm-10\">\n                <button type=\"submit\" class=\"btn btn-success btn-load\" data-loading-text=\"保存中\">保存</button>\n                <button type=\"reset\" class=\"btn btn-default\">重新填写</button>\n            </div>\n        </div>\n    </form>\n\n</div>\n\n{% endblock %}"
  },
  {
    "path": "app_backend/templates/settings/apply_put.html",
    "content": "{% extends \"layout.html\" %}\n\n{% block content %}\n<div class=\"container-fluid\">\n    <ol class=\"breadcrumb\">\n        <li><a href=\"/\">后台管理</a></li>\n        <li><a href=\"javascript:void(0);\" onclick=\"$('#menu-settings').trigger('click');\">系统配置</a></li>\n        <li class=\"active\">投资配置</li>\n    </ol>\n{#    <h2 class=\"sub-header\">Order Setting!</h2>#}\n    {# 表单 #}\n    <form class=\"form-horizontal\" method=\"post\" action=\"\">\n        {{ form.csrf_token }}\n        <p></p>\n        <blockquote>\n            <p class=\"text-muted\">单次投资限制</p>\n        </blockquote>\n        <div class=\"form-group{% if form.APPLY_PUT_MIN_EACH.errors %} has-error{% endif %}\">\n            {{ form.APPLY_PUT_MIN_EACH.label(class=\"col-sm-2 control-label\") }}\n            <div class=\"col-sm-10\">\n                {{ form.APPLY_PUT_MIN_EACH(class=\"form-control\", placeholder=\"单次投资最小金额 [单位：元]\", type=\"number\") }}\n                {% for error in form.APPLY_PUT_MIN_EACH.errors %}\n                    <span class=\"help-block\">{{ error }}</span>\n                {% endfor %}\n            </div>\n        </div>\n        <div class=\"form-group{% if form.APPLY_PUT_MAX_EACH.errors %} has-error{% endif %}\">\n            {{ form.APPLY_PUT_MAX_EACH.label(class=\"col-sm-2 control-label\") }}\n            <div class=\"col-sm-10\">\n                {{ form.APPLY_PUT_MAX_EACH(class=\"form-control\", placeholder=\"单次投资最大金额 [单位：元]\", type=\"number\") }}\n                {% for error in form.APPLY_PUT_MAX_EACH.errors %}\n                    <span class=\"help-block\">{{ error }}</span>\n                {% endfor %}\n            </div>\n        </div>\n        <div class=\"form-group{% if form.APPLY_PUT_STEP.errors %} has-error{% endif %}\">\n            {{ form.APPLY_PUT_STEP.label(class=\"col-sm-2 control-label\") }}\n            <div class=\"col-sm-10\">\n                {{ form.APPLY_PUT_STEP(class=\"form-control\", placeholder=\"投资金额调整基数 [单位：元]\", type=\"number\") }}\n                {% for error in form.APPLY_PUT_STEP.errors %}\n                    <span class=\"help-block\">{{ error }}</span>\n                {% endfor %}\n            </div>\n        </div>\n        <hr>\n        <blockquote>\n            <p class=\"text-muted\">单个用户投资限制</p>\n        </blockquote>\n        <div class=\"form-group{% if form.APPLY_PUT_USER_MAX_AMOUNT.errors %} has-error{% endif %}\">\n            {{ form.APPLY_PUT_USER_MAX_AMOUNT.label(class=\"col-sm-2 control-label\") }}\n            <div class=\"col-sm-10\">\n                {{ form.APPLY_PUT_USER_MAX_AMOUNT(class=\"form-control\", placeholder=\"单个用户投资最大交易中金额 [单位：元]\", type=\"number\") }}\n                {% for error in form.APPLY_PUT_USER_MAX_AMOUNT.errors %}\n                    <span class=\"help-block\">{{ error }}</span>\n                {% endfor %}\n            </div>\n        </div>\n        <div class=\"form-group{% if form.APPLY_PUT_USER_MAX_COUNT.errors %} has-error{% endif %}\">\n            {{ form.APPLY_PUT_USER_MAX_COUNT.label(class=\"col-sm-2 control-label\") }}\n            <div class=\"col-sm-10\">\n                {{ form.APPLY_PUT_USER_MAX_COUNT(class=\"form-control\", placeholder=\"单个用户投资最大交易中单数(0 表示不限制)\", type=\"number\") }}\n                {% for error in form.APPLY_PUT_USER_MAX_COUNT.errors %}\n                    <span class=\"help-block\">{{ error }}</span>\n                {% endfor %}\n            </div>\n        </div>\n        <hr>\n        <blockquote>\n            <p class=\"text-muted\">每日投资限制</p>\n        </blockquote>\n\n        <div class=\"form-group{% if form.APPLY_PUT_MAX_AMOUNT_DAILY.errors %} has-error{% endif %}\">\n            {{ form.APPLY_PUT_MAX_AMOUNT_DAILY.label(class=\"col-sm-2 control-label\") }}\n            <div class=\"col-sm-10\">\n                {{ form.APPLY_PUT_MAX_AMOUNT_DAILY(class=\"form-control\", placeholder=\"每日投资最大金额 [单位：元]\", type=\"number\") }}\n                {% for error in form.APPLY_PUT_MAX_AMOUNT_DAILY.errors %}\n                    <span class=\"help-block\">{{ error }}</span>\n                {% endfor %}\n            </div>\n        </div>\n        <div class=\"form-group{% if form.APPLY_PUT_MAX_COUNT_DAILY.errors %} has-error{% endif %}\">\n            {{ form.APPLY_PUT_MAX_COUNT_DAILY.label(class=\"col-sm-2 control-label\") }}\n            <div class=\"col-sm-10\">\n                {{ form.APPLY_PUT_MAX_COUNT_DAILY(class=\"form-control\", placeholder=\"每日投资最大单数\", type=\"number\") }}\n                {% for error in form.APPLY_PUT_MAX_COUNT_DAILY.errors %}\n                    <span class=\"help-block\">{{ error }}</span>\n                {% endfor %}\n            </div>\n        </div>\n        <hr>\n        <blockquote>\n            <p class=\"text-muted\">每月投资限制</p>\n        </blockquote>\n\n        <div class=\"form-group{% if form.APPLY_PUT_MAX_AMOUNT_MONTHLY.errors %} has-error{% endif %}\">\n            {{ form.APPLY_PUT_MAX_AMOUNT_MONTHLY.label(class=\"col-sm-2 control-label\") }}\n            <div class=\"col-sm-10\">\n                {{ form.APPLY_PUT_MAX_AMOUNT_MONTHLY(class=\"form-control\", placeholder=\"每月投资最大金额 [单位：元]\", type=\"number\") }}\n                {% for error in form.APPLY_PUT_MAX_AMOUNT_MONTHLY.errors %}\n                    <span class=\"help-block\">{{ error }}</span>\n                {% endfor %}\n            </div>\n        </div>\n        <div class=\"form-group{% if form.APPLY_PUT_MAX_COUNT_MONTHLY.errors %} has-error{% endif %}\">\n            {{ form.APPLY_PUT_MAX_COUNT_MONTHLY.label(class=\"col-sm-2 control-label\") }}\n            <div class=\"col-sm-10\">\n                {{ form.APPLY_PUT_MAX_COUNT_MONTHLY(class=\"form-control\", placeholder=\"每月投资最大单数\", type=\"number\") }}\n                {% for error in form.APPLY_PUT_MAX_COUNT_MONTHLY.errors %}\n                    <span class=\"help-block\">{{ error }}</span>\n                {% endfor %}\n            </div>\n        </div>\n        <hr>\n        <blockquote>\n            <p class=\"text-muted\">投资时间配置</p>\n        </blockquote>\n\n        <div class=\"form-group{% if form.APPLY_PUT_TIME_START.errors %} has-error{% endif %}\">\n            {{ form.APPLY_PUT_TIME_START.label(class=\"col-sm-2 control-label\") }}\n            <div class=\"col-sm-10\">\n                {{ form.APPLY_PUT_TIME_START(class=\"form-control\", placeholder=\"每天投资申请开始时间 [00:00:00-23:59:59]\") }}\n                {% for error in form.APPLY_PUT_TIME_START.errors %}\n                    <span class=\"help-block\">{{ error }}</span>\n                {% endfor %}\n            </div>\n        </div>\n        <div class=\"form-group{% if form.APPLY_PUT_TIME_END.errors %} has-error{% endif %}\">\n            {{ form.APPLY_PUT_TIME_END.label(class=\"col-sm-2 control-label\") }}\n            <div class=\"col-sm-10\">\n                {{ form.APPLY_PUT_TIME_END(class=\"form-control\", placeholder=\"每天投资申请结束时间 [00:00:00-23:59:59]\") }}\n                {% for error in form.APPLY_PUT_TIME_END.errors %}\n                    <span class=\"help-block\">{{ error }}</span>\n                {% endfor %}\n            </div>\n        </div>\n\n        <div class=\"form-group\">\n            <div class=\"col-sm-offset-2 col-sm-10\">\n                <button type=\"submit\" class=\"btn btn-success btn-load\" data-loading-text=\"保存中\">保存</button>\n                <button type=\"reset\" class=\"btn btn-default\">重新填写</button>\n            </div>\n        </div>\n    </form>\n\n</div>\n\n{% endblock %}"
  },
  {
    "path": "app_backend/templates/settings/bonus.html",
    "content": "{% extends \"layout.html\" %}\n\n{% block content %}\n<div class=\"container-fluid\">\n    <ol class=\"breadcrumb\">\n        <li><a href=\"/\">后台管理</a></li>\n        <li><a href=\"javascript:void(0);\" onclick=\"$('#menu-settings').trigger('click');\">系统配置</a></li>\n        <li class=\"active\">奖金配置</li>\n    </ol>\n    <h2 class=\"sub-header\">Bonus Setting!</h2>\n\n\n</div>\n\n{% endblock %}"
  },
  {
    "path": "app_backend/templates/settings/interest.html",
    "content": "{% extends \"layout.html\" %}\n\n{% block content %}\n<div class=\"container-fluid\">\n    <ol class=\"breadcrumb\">\n        <li><a href=\"/\">后台管理</a></li>\n        <li><a href=\"javascript:void(0);\" onclick=\"$('#menu-settings').trigger('click');\">系统配置</a></li>\n        <li class=\"active\"><a href=\"#\" onclick=\"$('#menu-settings-interest').trigger('click');\">利息配置</a></li>\n    </ol>\n{#    <h2 class=\"sub-header\">Interest Setting!</h2>#}\n    {# 表单 #}\n    <form class=\"form-horizontal\" method=\"post\" action=\"\">\n        {{ form.csrf_token }}\n        <p></p>\n\n        <blockquote>\n            <p class=\"text-muted\">利息配置</p>\n        </blockquote>\n        <div class=\"form-group{% if form.INTEREST_PUT.errors %} has-error{% endif %}\">\n            {{ form.INTEREST_PUT.label(class=\"col-sm-2 control-label\") }}\n            <div class=\"col-sm-10\">\n                {{ form.INTEREST_PUT(class=\"form-control\", placeholder=\"投资利息（日息） [范围：0-1]\") }}\n                {% for error in form.INTEREST_PUT.errors %}\n                    <span class=\"help-block\">{{ error }}</span>\n                {% endfor %}\n            </div>\n        </div>\n        <hr>\n        <blockquote>\n            <p class=\"text-muted\">支付奖惩配置</p>\n        </blockquote>\n        <div class=\"form-group{% if form.INTEREST_PAY_AHEAD.errors %} has-error{% endif %}\">\n            {{ form.INTEREST_PAY_AHEAD.label(class=\"col-sm-2 control-label\") }}\n            <div class=\"col-sm-10\">\n                {{ form.INTEREST_PAY_AHEAD(class=\"form-control\", placeholder=\"提前支付奖金比例 [范围：0-1]\") }}\n                {% for error in form.INTEREST_PAY_AHEAD.errors %}\n                    <span class=\"help-block\">{{ error }}</span>\n                {% endfor %}\n            </div>\n        </div>\n        <div class=\"form-group{% if form.INTEREST_PAY_DELAY.errors %} has-error{% endif %}\">\n            {{ form.INTEREST_PAY_DELAY.label(class=\"col-sm-2 control-label\") }}\n            <div class=\"col-sm-10\">\n                {{ form.INTEREST_PAY_DELAY(class=\"form-control\", placeholder=\"延迟支付罚金比例 [范围：0-1]\") }}\n                {% for error in form.INTEREST_PAY_DELAY.errors %}\n                    <span class=\"help-block\">{{ error }}</span>\n                {% endfor %}\n            </div>\n        </div>\n        <div class=\"form-group{% if form.DIFF_TIME_PAY_AHEAD.errors %} has-error{% endif %}\">\n            {{ form.DIFF_TIME_PAY_AHEAD.label(class=\"col-sm-2 control-label\") }}\n            <div class=\"col-sm-10\">\n                {{ form.DIFF_TIME_PAY_AHEAD(class=\"form-control\", placeholder=\"提前支付奖金时间 [单位：秒]\", type=\"number\") }}\n                {% for error in form.DIFF_TIME_PAY_AHEAD.errors %}\n                    <span class=\"help-block\">{{ error }}</span>\n                {% endfor %}\n            </div>\n        </div>\n        <div class=\"form-group{% if form.DIFF_TIME_PAY_DELAY.errors %} has-error{% endif %}\">\n            {{ form.DIFF_TIME_PAY_DELAY.label(class=\"col-sm-2 control-label\") }}\n            <div class=\"col-sm-10\">\n                {{ form.DIFF_TIME_PAY_DELAY(class=\"form-control\", placeholder=\"延迟支付罚金时间 [单位：秒]\", type=\"number\") }}\n                {% for error in form.DIFF_TIME_PAY_DELAY.errors %}\n                    <span class=\"help-block\">{{ error }}</span>\n                {% endfor %}\n            </div>\n        </div>\n        <hr>\n        <blockquote>\n            <p class=\"text-muted\">确认奖惩配置</p>\n        </blockquote>\n        <div class=\"form-group{% if form.INTEREST_REC_AHEAD.errors %} has-error{% endif %}\">\n            {{ form.INTEREST_REC_AHEAD.label(class=\"col-sm-2 control-label\") }}\n            <div class=\"col-sm-10\">\n                {{ form.INTEREST_REC_AHEAD(class=\"form-control\", placeholder=\"提前确认奖金比例 [范围：0-1]\") }}\n                {% for error in form.INTEREST_REC_AHEAD.errors %}\n                    <span class=\"help-block\">{{ error }}</span>\n                {% endfor %}\n            </div>\n        </div>\n        <div class=\"form-group{% if form.INTEREST_REC_DELAY.errors %} has-error{% endif %}\">\n            {{ form.INTEREST_REC_DELAY.label(class=\"col-sm-2 control-label\") }}\n            <div class=\"col-sm-10\">\n                {{ form.INTEREST_REC_DELAY(class=\"form-control\", placeholder=\"延迟确认罚金比例 [范围：0-1]\") }}\n                {% for error in form.INTEREST_REC_DELAY.errors %}\n                    <span class=\"help-block\">{{ error }}</span>\n                {% endfor %}\n            </div>\n        </div>\n        <div class=\"form-group{% if form.DIFF_TIME_REC_AHEAD.errors %} has-error{% endif %}\">\n            {{ form.DIFF_TIME_REC_AHEAD.label(class=\"col-sm-2 control-label\") }}\n            <div class=\"col-sm-10\">\n                {{ form.DIFF_TIME_REC_AHEAD(class=\"form-control\", placeholder=\"提前确认奖金时间 [单位：秒]\", type=\"number\") }}\n                {% for error in form.DIFF_TIME_REC_AHEAD.errors %}\n                    <span class=\"help-block\">{{ error }}</span>\n                {% endfor %}\n            </div>\n        </div>\n        <div class=\"form-group{% if form.DIFF_TIME_REC_DELAY.errors %} has-error{% endif %}\">\n            {{ form.DIFF_TIME_REC_DELAY.label(class=\"col-sm-2 control-label\") }}\n            <div class=\"col-sm-10\">\n                {{ form.DIFF_TIME_REC_DELAY(class=\"form-control\", placeholder=\"延迟确认罚金时间 [单位：秒]\", type=\"number\") }}\n                {% for error in form.DIFF_TIME_REC_DELAY.errors %}\n                    <span class=\"help-block\">{{ error }}</span>\n                {% endfor %}\n            </div>\n        </div>\n\n        <div class=\"form-group\">\n            <div class=\"col-sm-offset-2 col-sm-10\">\n                <button type=\"submit\" class=\"btn btn-success btn-load\" data-loading-text=\"保存中\">保存</button>\n                <button type=\"reset\" class=\"btn btn-default\">重新填写</button>\n            </div>\n        </div>\n    </form>\n\n</div>\n\n{% endblock %}"
  },
  {
    "path": "app_backend/templates/settings/order.html",
    "content": "{% extends \"layout.html\" %}\n\n{% block content %}\n<div class=\"container-fluid\">\n    <ol class=\"breadcrumb\">\n        <li><a href=\"/\">后台管理</a></li>\n        <li><a href=\"javascript:void(0);\" onclick=\"$('#menu-settings').trigger('click');\">系统配置</a></li>\n        <li class=\"active\">订单配置</li>\n    </ol>\n{#    <h2 class=\"sub-header\">Order Setting!</h2>#}\n    {# 表单 #}\n    <form class=\"form-horizontal\" method=\"post\" action=\"\">\n        {{ form.csrf_token }}\n        <p></p>\n\n        <blockquote>\n            <p class=\"text-muted\">订单限制</p>\n        </blockquote>\n        <div class=\"form-group{% if form.ORDER_MAX_AMOUNT.errors %} has-error{% endif %}\">\n            {{ form.ORDER_MAX_AMOUNT.label(class=\"col-sm-2 control-label\") }}\n            <div class=\"col-sm-10\">\n                {{ form.ORDER_MAX_AMOUNT(class=\"form-control\", placeholder=\"订单最大金额 [单位：元]\", type=\"number\") }}\n                {% for error in form.ORDER_MAX_AMOUNT.errors %}\n                    <span class=\"help-block\">{{ error }}</span>\n                {% endfor %}\n            </div>\n        </div>\n        <div class=\"form-group{% if form.ORDER_MAX_COUNT.errors %} has-error{% endif %}\">\n            {{ form.ORDER_MAX_COUNT.label(class=\"col-sm-2 control-label\") }}\n            <div class=\"col-sm-10\">\n                {{ form.ORDER_MAX_COUNT(class=\"form-control\", placeholder=\"订单最大数量 [单位：个]\", type=\"number\") }}\n                {% for error in form.ORDER_MAX_COUNT.errors %}\n                    <span class=\"help-block\">{{ error }}</span>\n                {% endfor %}\n            </div>\n        </div>\n        <hr>\n        <blockquote>\n            <p class=\"text-muted\">推广奖励</p>\n        </blockquote>\n\n        <div class=\"form-group{% if form.BONUS_DIRECT.errors %} has-error{% endif %}\">\n            {{ form.BONUS_DIRECT.label(class=\"col-sm-2 control-label\") }}\n            <div class=\"col-sm-10\">\n                {{ form.BONUS_DIRECT(class=\"form-control\", placeholder=\"直接推荐奖励 [范围：0-1]\") }}\n                {% for error in form.BONUS_DIRECT.errors %}\n                    <span class=\"help-block\">{{ error }}</span>\n                {% endfor %}\n            </div>\n        </div>\n        <div class=\"form-group{% if form.BONUS_LEVEL_FIRST.errors %} has-error{% endif %}\">\n            {{ form.BONUS_LEVEL_FIRST.label(class=\"col-sm-2 control-label\") }}\n            <div class=\"col-sm-10\">\n                {{ form.BONUS_LEVEL_FIRST(class=\"form-control\", placeholder=\"一级推荐奖励 [范围：0-1]\") }}\n                {% for error in form.BONUS_LEVEL_FIRST.errors %}\n                    <span class=\"help-block\">{{ error }}</span>\n                {% endfor %}\n            </div>\n        </div>\n        <div class=\"form-group{% if form.BONUS_LEVEL_SECOND.errors %} has-error{% endif %}\">\n            {{ form.BONUS_LEVEL_SECOND.label(class=\"col-sm-2 control-label\") }}\n            <div class=\"col-sm-10\">\n                {{ form.BONUS_LEVEL_SECOND(class=\"form-control\", placeholder=\"二级推荐奖励 [范围：0-1]\") }}\n                {% for error in form.BONUS_LEVEL_SECOND.errors %}\n                    <span class=\"help-block\">{{ error }}</span>\n                {% endfor %}\n            </div>\n        </div>\n        <div class=\"form-group{% if form.BONUS_LEVEL_THIRD.errors %} has-error{% endif %}\">\n            {{ form.BONUS_LEVEL_THIRD.label(class=\"col-sm-2 control-label\") }}\n            <div class=\"col-sm-10\">\n                {{ form.BONUS_LEVEL_THIRD(class=\"form-control\", placeholder=\"三级推荐奖励 [范围：0-1]\") }}\n                {% for error in form.BONUS_LEVEL_THIRD.errors %}\n                    <span class=\"help-block\">{{ error }}</span>\n                {% endfor %}\n            </div>\n        </div>\n\n        <div class=\"form-group\">\n            <div class=\"col-sm-offset-2 col-sm-10\">\n                <button type=\"submit\" class=\"btn btn-success btn-load\" data-loading-text=\"保存中\">保存</button>\n                <button type=\"reset\" class=\"btn btn-default\">重新填写</button>\n            </div>\n        </div>\n    </form>\n\n</div>\n\n{% endblock %}"
  },
  {
    "path": "app_backend/templates/settings/score.html",
    "content": "{% extends \"layout.html\" %}\n\n{% block content %}\n<div class=\"container-fluid\">\n    <ol class=\"breadcrumb\">\n        <li><a href=\"/\">后台管理</a></li>\n        <li><a href=\"javascript:void(0);\" onclick=\"$('#menu-settings').trigger('click');\">系统配置</a></li>\n        <li class=\"active\">积分配置</li>\n    </ol>\n    <h2 class=\"sub-header\">Score Setting!</h2>\n\n\n</div>\n\n{% endblock %}"
  },
  {
    "path": "app_backend/templates/settings/switch.html",
    "content": "{% extends \"layout.html\" %}\n\n{% block content %}\n<div class=\"container-fluid\">\n    <ol class=\"breadcrumb\">\n        <li><a href=\"/\">后台管理</a></li>\n        <li><a href=\"javascript:void(0);\" onclick=\"$('#menu-settings').trigger('click');\">系统配置</a></li>\n        <li class=\"active\">开关配置</li>\n    </ol>\n    <div class=\"btn-group pull-right\" role=\"group\" aria-label=\"...\">\n        <a type=\"button\" class=\"btn btn-warning\" href=\"javascript:void(0);\" onclick=\"ajax_clean()\">还原所有配置</a>\n    </div>\n    {# 表单 #}\n    <form class=\"form-horizontal\" method=\"post\" action=\"\">\n        {{ form.csrf_token }}\n        <p></p>\n        <blockquote>\n            <p class=\"text-muted\">导出配置</p>\n        </blockquote>\n        <div class=\"form-group{% if form.SWITCH_EXPORT.errors %} has-error{% endif %}\">\n            {{ form.SWITCH_EXPORT.label(class=\"col-sm-2 control-label\") }}\n            <div class=\"col-sm-10\">\n                {{ form.SWITCH_EXPORT() }}\n                {% for error in form.SWITCH_EXPORT.errors %}\n                    <span class=\"help-block\">{{ error }}</span>\n                {% endfor %}\n            </div>\n        </div>\n        <hr>\n        <blockquote>\n            <p class=\"text-muted\">注册配置</p>\n        </blockquote>\n        <div class=\"form-group{% if form.SWITCH_REG_ACCOUNT.errors %} has-error{% endif %}\">\n            {{ form.SWITCH_REG_ACCOUNT.label(class=\"col-sm-2 control-label\") }}\n            <div class=\"col-sm-10\">\n                {{ form.SWITCH_REG_ACCOUNT() }}\n                {% for error in form.SWITCH_REG_ACCOUNT.errors %}\n                    <span class=\"help-block\">{{ error }}</span>\n                {% endfor %}\n            </div>\n        </div>\n        <div class=\"form-group{% if form.SWITCH_REG_PHONE.errors %} has-error{% endif %}\">\n            {{ form.SWITCH_REG_PHONE.label(class=\"col-sm-2 control-label\") }}\n            <div class=\"col-sm-10\">\n                {{ form.SWITCH_REG_PHONE() }}\n                {% for error in form.SWITCH_REG_PHONE.errors %}\n                    <span class=\"help-block\">{{ error }}</span>\n                {% endfor %}\n            </div>\n        </div>\n        <div class=\"form-group{% if form.SWITCH_REG_EMAIL.errors %} has-error{% endif %}\">\n            {{ form.SWITCH_REG_EMAIL.label(class=\"col-sm-2 control-label\") }}\n            <div class=\"col-sm-10\">\n                {{ form.SWITCH_REG_EMAIL() }}\n                {% for error in form.SWITCH_REG_EMAIL.errors %}\n                    <span class=\"help-block\">{{ error }}</span>\n                {% endfor %}\n            </div>\n        </div>\n        <div class=\"form-group{% if form.SWITCH_REG_THREE_PART.errors %} has-error{% endif %}\">\n            {{ form.SWITCH_REG_THREE_PART.label(class=\"col-sm-2 control-label\") }}\n            <div class=\"col-sm-10\">\n                {{ form.SWITCH_REG_THREE_PART() }}\n                {% for error in form.SWITCH_REG_THREE_PART.errors %}\n                    <span class=\"help-block\">{{ error }}</span>\n                {% endfor %}\n            </div>\n        </div>\n        <hr>\n        <blockquote>\n            <p class=\"text-muted\">登录配置</p>\n        </blockquote>\n        <div class=\"form-group{% if form.SWITCH_LOGIN_ACCOUNT.errors %} has-error{% endif %}\">\n            {{ form.SWITCH_LOGIN_ACCOUNT.label(class=\"col-sm-2 control-label\") }}\n            <div class=\"col-sm-10\">\n                {{ form.SWITCH_LOGIN_ACCOUNT() }}\n                {% for error in form.SWITCH_LOGIN_ACCOUNT.errors %}\n                    <span class=\"help-block\">{{ error }}</span>\n                {% endfor %}\n            </div>\n        </div>\n        <div class=\"form-group{% if form.SWITCH_LOGIN_PHONE.errors %} has-error{% endif %}\">\n            {{ form.SWITCH_LOGIN_PHONE.label(class=\"col-sm-2 control-label\") }}\n            <div class=\"col-sm-10\">\n                {{ form.SWITCH_LOGIN_PHONE() }}\n                {% for error in form.SWITCH_LOGIN_PHONE.errors %}\n                    <span class=\"help-block\">{{ error }}</span>\n                {% endfor %}\n            </div>\n        </div>\n        <div class=\"form-group{% if form.SWITCH_LOGIN_EMAIL.errors %} has-error{% endif %}\">\n            {{ form.SWITCH_LOGIN_EMAIL.label(class=\"col-sm-2 control-label\") }}\n            <div class=\"col-sm-10\">\n                {{ form.SWITCH_LOGIN_EMAIL() }}\n                {% for error in form.SWITCH_LOGIN_EMAIL.errors %}\n                    <span class=\"help-block\">{{ error }}</span>\n                {% endfor %}\n            </div>\n        </div>\n        <div class=\"form-group{% if form.SWITCH_LOGIN_THREE_PART.errors %} has-error{% endif %}\">\n            {{ form.SWITCH_LOGIN_THREE_PART.label(class=\"col-sm-2 control-label\") }}\n            <div class=\"col-sm-10\">\n                {{ form.SWITCH_LOGIN_THREE_PART() }}\n                {% for error in form.SWITCH_LOGIN_THREE_PART.errors %}\n                    <span class=\"help-block\">{{ error }}</span>\n                {% endfor %}\n            </div>\n        </div>\n\n        <div class=\"form-group\">\n            <div class=\"col-sm-offset-2 col-sm-10\">\n                <button type=\"submit\" class=\"btn btn-success btn-load\" data-loading-text=\"保存中\">保存</button>\n                <button type=\"reset\" class=\"btn btn-default\">重新填写</button>\n            </div>\n        </div>\n    </form>\n\n</div>\n\n{% endblock %}\n\n{% block extra_js %}\n<script>\n    // 清除所有配置\n    function ajax_clean(){\n        if(confirm(\"是否确认还原所有配置?\"))\n        {\n            // console.log(order_id);\n            $.getJSON('{{ url_for('settings.ajax_clean') }}',\n            {\n            }, function (result) {\n                if(result.hasOwnProperty('error')){\n                    alert(result.error);\n                }else {\n                    alert(result.success);\n                    window.location.reload();\n                }\n            });\n            return false;\n        }\n    }\n</script>\n{% endblock %}"
  },
  {
    "path": "app_backend/templates/settings/user.html",
    "content": "{% extends \"layout.html\" %}\n\n{% block content %}\n<div class=\"container-fluid\">\n    <ol class=\"breadcrumb\">\n        <li><a href=\"/\">后台管理</a></li>\n        <li><a href=\"javascript:void(0);\" onclick=\"$('#menu-settings').trigger('click');\">系统配置</a></li>\n        <li class=\"active\">会员配置</li>\n    </ol>\n    <blockquote>\n        <p class=\"text-muted\">会员冻结条件配置</p>\n    </blockquote>\n    {# 表单 #}\n    <form class=\"form-horizontal\" method=\"post\" action=\"\">\n        {{ form.csrf_token }}\n        <p></p>\n        <div class=\"form-group{% if form.LOCK_REG_NOT_ACTIVE_TTL.errors %} has-error{% endif %}\">\n            {{ form.LOCK_REG_NOT_ACTIVE_TTL.label(class=\"col-sm-2 control-label\") }}\n            <div class=\"col-sm-10\">\n                {{ form.LOCK_REG_NOT_ACTIVE_TTL(class=\"form-control\", placeholder=\"注册未激活时间 [单位：秒]\") }}\n                {% for error in form.LOCK_REG_NOT_ACTIVE_TTL.errors %}\n                    <span class=\"help-block\">{{ error }}</span>\n                {% endfor %}\n            </div>\n        </div>\n        <div class=\"form-group{% if form.LOCK_ACTIVE_NOT_PUT_TTL.errors %} has-error{% endif %}\">\n            {{ form.LOCK_ACTIVE_NOT_PUT_TTL.label(class=\"col-sm-2 control-label\") }}\n            <div class=\"col-sm-10\">\n                {{ form.LOCK_ACTIVE_NOT_PUT_TTL(class=\"form-control\", placeholder=\"激活未排单时间 [单位：秒]\") }}\n                {% for error in form.LOCK_ACTIVE_NOT_PUT_TTL.errors %}\n                    <span class=\"help-block\">{{ error }}</span>\n                {% endfor %}\n            </div>\n        </div>\n        <div class=\"form-group{% if form.LOCK_ORDER_NOT_PAY_TTL.errors %} has-error{% endif %}\">\n            {{ form.LOCK_ORDER_NOT_PAY_TTL.label(class=\"col-sm-2 control-label\") }}\n            <div class=\"col-sm-10\">\n                {{ form.LOCK_ORDER_NOT_PAY_TTL(class=\"form-control\", placeholder=\"匹配未付款时间 [单位：秒]\") }}\n                {% for error in form.LOCK_ORDER_NOT_PAY_TTL.errors %}\n                    <span class=\"help-block\">{{ error }}</span>\n                {% endfor %}\n            </div>\n        </div>\n        <div class=\"form-group{% if form.LOCK_PAY_NOT_REC_TTL.errors %} has-error{% endif %}\">\n            {{ form.LOCK_PAY_NOT_REC_TTL.label(class=\"col-sm-2 control-label\") }}\n            <div class=\"col-sm-10\">\n                {{ form.LOCK_PAY_NOT_REC_TTL(class=\"form-control\", placeholder=\"收款未确认时间 [单位：秒]\") }}\n                {% for error in form.LOCK_PAY_NOT_REC_TTL.errors %}\n                    <span class=\"help-block\">{{ error }}</span>\n                {% endfor %}\n            </div>\n        </div>\n\n        <div class=\"form-group\">\n            <div class=\"col-sm-offset-2 col-sm-10\">\n                <button type=\"submit\" class=\"btn btn-success btn-load\" data-loading-text=\"保存中\">保存</button>\n                <button type=\"reset\" class=\"btn btn-default\">重新填写</button>\n            </div>\n        </div>\n    </form>\n\n</div>\n\n{% endblock %}\n"
  },
  {
    "path": "app_backend/templates/settings/wallet.html",
    "content": "{% extends \"layout.html\" %}\n\n{% block content %}\n\n\n{% endblock %}"
  },
  {
    "path": "app_backend/templates/stats/apply_get.html",
    "content": "{% extends \"layout.html\" %}\n\n{% block content %}\n<div class=\"container-fluid\">\n    <ol class=\"breadcrumb\">\n        <li><a href=\"/\">后台管理</a></li>\n        <li><a href=\"javascript:void(0);\" onclick=\"$('#menu-stats').trigger('click');\">运营统计</a></li>\n        <li class=\"active\">提现统计</li>\n    </ol>\n{#    <h2 class=\"sub-header\">User Stats!</h2>#}\n    <p class=\"btn-group pull-right\" role=\"group\" aria-label=\"...\">\n    {% if not request.query_string or request.query_string == 'time_based=hour' %}\n        <a type=\"button\" class=\"btn btn-default active\">时</a>\n        <a type=\"button\" class=\"btn btn-default\" href=\"{{ url_for('stats.apply_get', time_based='date') }}\">日</a>\n        <a type=\"button\" class=\"btn btn-default\" href=\"{{ url_for('stats.apply_get', time_based='month') }}\">月</a>\n    {% elif request.query_string == 'time_based=date' %}\n        <a type=\"button\" class=\"btn btn-default\" href=\"{{ url_for('stats.apply_get', time_based='hour') }}\">时</a>\n        <a type=\"button\" class=\"btn btn-default active\">日</a>\n        <a type=\"button\" class=\"btn btn-default\" href=\"{{ url_for('stats.apply_get', time_based='month') }}\">月</a>\n    {% elif request.query_string == 'time_based=month' %}\n        <a type=\"button\" class=\"btn btn-default\" href=\"{{ url_for('stats.apply_get', time_based='hour') }}\">时</a>\n        <a type=\"button\" class=\"btn btn-default\" href=\"{{ url_for('stats.apply_get', time_based='date') }}\">日</a>\n        <a type=\"button\" class=\"btn btn-default active\">月</a>\n    {% endif %}\n    </p>\n\n    <div class=\"row\">\n        <div class=\"col-lg-12 col-md-12\">\n            <section id=\"chart_line_graphs\">\n                <div class=\"panel panel-default\">\n                    <div class=\"panel-heading\">\n                        <strong class=\"panel-title\">\n                            <span class=\"glyphicon glyphicon-signal\"></span> 提现统计\n                            <span class=\"glyphicon glyphicon-refresh pull-right\"></span>\n                        </strong>\n                    </div>\n                    <div class=\"panel-body\">\n                        <canvas id=\"chart_line_canvas\"></canvas>\n                    </div>\n                    <div class=\"panel-footer text-center text-muted\">\n                        <i id=\"current_time\">{{ moment().format('dddd, YYYY-MM-DD, h:mm:ss a') }}</i>\n                    </div>\n                </div>\n            </section>\n        </div>\n    </div>\n</div>\n\n{% endblock %}\n\n\n{% block extra_js %}\n<script>\n    $(function () {\n        // 配置图表选项\n        var options = {\n            responsive: true,\n            tooltips: {\n                intersect: false,\n                mode: 'index',\n                bodySpacing: 4\n            },\n            legend: {\n                position: 'bottom'\n            },\n            title: {\n                display: true,\n                text: '提现统计'\n            },\n            scales: {\n                yAxes: [{\n                    ticks: {\n                        beginAtZero: true\n                    }\n                }]\n            }\n        };\n\n        // 获取Line图标数据\n        $.getJSON('{{ url_for('apply_get.ajax_stats') }}',\n            {\n                time_based: '{{ time_based }}'\n            },\n            function (data) {\n                /* 创建Line图表 */\n                var ctx = $(\"#chart_line_canvas\").get(0).getContext(\"2d\");\n                var myLineChart = new Chart(ctx, {\n                    type: 'line',\n                    data: data,\n                    options: options\n                });\n                // console.log(myLineChart);\n            }\n        );\n    });\n\n    // 当前时间同步刷新\n    var update_time;\n    (update_time = function () {\n        $('#current_time').html(moment().format('dddd, YYYY-MM-DD, h:mm:ss a'));\n    })();\n    setInterval(update_time, 1000);\n</script>\n{% endblock %}\n"
  },
  {
    "path": "app_backend/templates/stats/apply_put.html",
    "content": "{% extends \"layout.html\" %}\n\n{% block content %}\n<div class=\"container-fluid\">\n    <ol class=\"breadcrumb\">\n        <li><a href=\"/\">后台管理</a></li>\n        <li><a href=\"javascript:void(0);\" onclick=\"$('#menu-stats').trigger('click');\">运营统计</a></li>\n        <li class=\"active\">投资统计</li>\n    </ol>\n{#    <h2 class=\"sub-header\">User Stats!</h2>#}\n    <p class=\"btn-group pull-right\" role=\"group\" aria-label=\"...\">\n    {% if not request.query_string or request.query_string == 'time_based=hour' %}\n        <a type=\"button\" class=\"btn btn-default active\">时</a>\n        <a type=\"button\" class=\"btn btn-default\" href=\"{{ url_for('stats.apply_put', time_based='date') }}\">日</a>\n        <a type=\"button\" class=\"btn btn-default\" href=\"{{ url_for('stats.apply_put', time_based='month') }}\">月</a>\n    {% elif request.query_string == 'time_based=date' %}\n        <a type=\"button\" class=\"btn btn-default\" href=\"{{ url_for('stats.apply_put', time_based='hour') }}\">时</a>\n        <a type=\"button\" class=\"btn btn-default active\">日</a>\n        <a type=\"button\" class=\"btn btn-default\" href=\"{{ url_for('stats.apply_put', time_based='month') }}\">月</a>\n    {% elif request.query_string == 'time_based=month' %}\n        <a type=\"button\" class=\"btn btn-default\" href=\"{{ url_for('stats.apply_put', time_based='hour') }}\">时</a>\n        <a type=\"button\" class=\"btn btn-default\" href=\"{{ url_for('stats.apply_put', time_based='date') }}\">日</a>\n        <a type=\"button\" class=\"btn btn-default active\">月</a>\n    {% endif %}\n    </p>\n\n    <div class=\"row\">\n        <div class=\"col-lg-12 col-md-12\">\n            <section id=\"chart_line_graphs\">\n                <div class=\"panel panel-default\">\n                    <div class=\"panel-heading\">\n                        <strong class=\"panel-title\">\n                            <span class=\"glyphicon glyphicon-signal\"></span> 投资统计\n                            <span class=\"glyphicon glyphicon-refresh pull-right\"></span>\n                        </strong>\n                    </div>\n                    <div class=\"panel-body\">\n                        <canvas id=\"chart_line_canvas\"></canvas>\n                    </div>\n                    <div class=\"panel-footer text-center text-muted\">\n                        <i id=\"current_time\">{{ moment().format('dddd, YYYY-MM-DD, h:mm:ss a') }}</i>\n                    </div>\n                </div>\n            </section>\n        </div>\n    </div>\n</div>\n\n{% endblock %}\n\n\n{% block extra_js %}\n<script>\n    $(function () {\n        // 配置图表选项\n        var options = {\n            responsive: true,\n            tooltips: {\n                intersect: false,\n                mode: 'index',\n                bodySpacing: 4\n            },\n            legend: {\n                position: 'bottom'\n            },\n            title: {\n                display: true,\n                text: '投资统计'\n            },\n            scales: {\n                yAxes: [{\n                    ticks: {\n                        beginAtZero: true\n                    }\n                }]\n            }\n        };\n\n        // 获取Line图标数据\n        $.getJSON('{{ url_for('apply_put.ajax_stats') }}',\n            {\n                time_based: '{{ time_based }}'\n            },\n            function (data) {\n                /* 创建Line图表 */\n                var ctx = $(\"#chart_line_canvas\").get(0).getContext(\"2d\");\n                var myLineChart = new Chart(ctx, {\n                    type: 'line',\n                    data: data,\n                    options: options\n                });\n                // console.log(myLineChart);\n            }\n        );\n    });\n\n    // 当前时间同步刷新\n    var update_time;\n    (update_time = function () {\n        $('#current_time').html(moment().format('dddd, YYYY-MM-DD, h:mm:ss a'));\n    })();\n    setInterval(update_time, 1000);\n</script>\n{% endblock %}\n"
  },
  {
    "path": "app_backend/templates/stats/order.html",
    "content": "{% extends \"layout.html\" %}\n\n{% block content %}\n<div class=\"container-fluid\">\n    <ol class=\"breadcrumb\">\n        <li><a href=\"/\">后台管理</a></li>\n        <li><a href=\"javascript:void(0);\" onclick=\"$('#menu-stats').trigger('click');\">运营统计</a></li>\n        <li class=\"active\">订单统计</li>\n    </ol>\n{#    <h2 class=\"sub-header\">User Stats!</h2>#}\n    <p class=\"btn-group pull-right\" role=\"group\" aria-label=\"...\">\n    {% if not request.query_string or request.query_string == 'time_based=hour' %}\n        <a type=\"button\" class=\"btn btn-default active\">时</a>\n        <a type=\"button\" class=\"btn btn-default\" href=\"{{ url_for('stats.order', time_based='date') }}\">日</a>\n        <a type=\"button\" class=\"btn btn-default\" href=\"{{ url_for('stats.order', time_based='month') }}\">月</a>\n    {% elif request.query_string == 'time_based=date' %}\n        <a type=\"button\" class=\"btn btn-default\" href=\"{{ url_for('stats.order', time_based='hour') }}\">时</a>\n        <a type=\"button\" class=\"btn btn-default active\">日</a>\n        <a type=\"button\" class=\"btn btn-default\" href=\"{{ url_for('stats.order', time_based='month') }}\">月</a>\n    {% elif request.query_string == 'time_based=month' %}\n        <a type=\"button\" class=\"btn btn-default\" href=\"{{ url_for('stats.order', time_based='hour') }}\">时</a>\n        <a type=\"button\" class=\"btn btn-default\" href=\"{{ url_for('stats.order', time_based='date') }}\">日</a>\n        <a type=\"button\" class=\"btn btn-default active\">月</a>\n    {% endif %}\n    </p>\n\n    <div class=\"row\">\n        <div class=\"col-lg-12 col-md-12\">\n            <section id=\"chart_line_graphs\">\n                <div class=\"panel panel-default\">\n                    <div class=\"panel-heading\">\n                        <strong class=\"panel-title\">\n                            <span class=\"glyphicon glyphicon-signal\"></span> 订单统计\n                            <span class=\"glyphicon glyphicon-refresh pull-right\"></span>\n                        </strong>\n                    </div>\n                    <div class=\"panel-body\">\n                        <canvas id=\"chart_line_canvas\"></canvas>\n                    </div>\n                    <div class=\"panel-footer text-center text-muted\">\n                        <i id=\"current_time\">{{ moment().format('dddd, YYYY-MM-DD, h:mm:ss a') }}</i>\n                    </div>\n                </div>\n            </section>\n        </div>\n    </div>\n</div>\n\n{% endblock %}\n\n\n{% block extra_js %}\n<script>\n    $(function () {\n        // 配置图表选项\n        var options = {\n            responsive: true,\n            tooltips: {\n                intersect: false,\n                mode: 'index',\n                bodySpacing: 4\n            },\n            legend: {\n                position: 'bottom'\n            },\n            title: {\n                display: true,\n                text: '订单统计 - 订单金额'\n            },\n            scales: {\n                yAxes: [{\n                    ticks: {\n                        beginAtZero: true\n                    }\n                }]\n            }\n        };\n\n        // 获取Line图标数据\n        $.getJSON('{{ url_for('order.ajax_stats') }}',\n            {\n                time_based: '{{ time_based }}'\n            },\n            function (data) {\n                /* 创建Line图表 */\n                var ctx = $(\"#chart_line_canvas\").get(0).getContext(\"2d\");\n                var myLineChart = new Chart(ctx, {\n                    type: 'line',\n                    data: data,\n                    options: options\n                });\n                // console.log(myLineChart);\n            }\n        );\n    });\n\n    // 当前时间同步刷新\n    var update_time;\n    (update_time = function () {\n        $('#current_time').html(moment().format('dddd, YYYY-MM-DD, h:mm:ss a'));\n    })();\n    setInterval(update_time, 1000);\n</script>\n{% endblock %}\n"
  },
  {
    "path": "app_backend/templates/stats/user.html",
    "content": "{% extends \"layout.html\" %}\n\n{% block content %}\n<div class=\"container-fluid\">\n    <ol class=\"breadcrumb\">\n        <li><a href=\"/\">后台管理</a></li>\n        <li><a href=\"javascript:void(0);\" onclick=\"$('#menu-stats').trigger('click');\">运营统计</a></li>\n        <li class=\"active\">用户统计</li>\n    </ol>\n{#    <h2 class=\"sub-header\">User Stats!</h2>#}\n    <p class=\"btn-group pull-right\" role=\"group\" aria-label=\"...\">\n    {% if not request.query_string or request.query_string == 'time_based=hour' %}\n        <a type=\"button\" class=\"btn btn-default active\">时</a>\n        <a type=\"button\" class=\"btn btn-default\" href=\"{{ url_for('stats.user', time_based='date') }}\">日</a>\n        <a type=\"button\" class=\"btn btn-default\" href=\"{{ url_for('stats.user', time_based='month') }}\">月</a>\n    {% elif request.query_string == 'time_based=date' %}\n        <a type=\"button\" class=\"btn btn-default\" href=\"{{ url_for('stats.user', time_based='hour') }}\">时</a>\n        <a type=\"button\" class=\"btn btn-default active\">日</a>\n        <a type=\"button\" class=\"btn btn-default\" href=\"{{ url_for('stats.user', time_based='month') }}\">月</a>\n    {% elif request.query_string == 'time_based=month' %}\n        <a type=\"button\" class=\"btn btn-default\" href=\"{{ url_for('stats.user', time_based='hour') }}\">时</a>\n        <a type=\"button\" class=\"btn btn-default\" href=\"{{ url_for('stats.user', time_based='date') }}\">日</a>\n        <a type=\"button\" class=\"btn btn-default active\">月</a>\n    {% endif %}\n    </p>\n\n    <div class=\"row\">\n        <div class=\"col-lg-12 col-md-12\">\n            <section id=\"chart_line_graphs\">\n                <div class=\"panel panel-default\">\n                    <div class=\"panel-heading\">\n                        <strong class=\"panel-title\">\n                            <span class=\"glyphicon glyphicon-signal\"></span> 用户统计\n                            <span class=\"glyphicon glyphicon-refresh pull-right\"></span>\n                        </strong>\n                    </div>\n                    <div class=\"panel-body\">\n                        <canvas id=\"chart_line_canvas\"></canvas>\n                    </div>\n                    <div class=\"panel-footer text-center text-muted\">\n                        <i id=\"current_time\">{{ moment().format('dddd, YYYY-MM-DD, h:mm:ss a') }}</i>\n                    </div>\n                </div>\n            </section>\n        </div>\n    </div>\n</div>\n\n{% endblock %}\n\n\n{% block extra_js %}\n<script>\n    $(function () {\n        // 配置图表选项\n        var options = {\n            responsive: true,\n            tooltips: {\n                intersect: false,\n                mode: 'index',\n                bodySpacing: 4\n            },\n            legend: {\n                position: 'bottom'\n            },\n            title: {\n                display: true,\n                text: '用户统计 - 注册激活'\n            },\n            scales: {\n                yAxes: [{\n                    ticks: {\n                        beginAtZero: true\n                    }\n                }]\n            }\n        };\n\n        // 获取Line图标数据\n        $.getJSON('{{ url_for('user.ajax_stats') }}',\n            {\n                time_based: '{{ time_based }}'\n            },\n            function (data) {\n                /* 创建Line图表 */\n                var ctx = $(\"#chart_line_canvas\").get(0).getContext(\"2d\");\n                var myLineChart = new Chart(ctx, {\n                    type: 'line',\n                    data: data,\n                    options: options\n                });\n                // console.log(myLineChart);\n            }\n        );\n    });\n\n    // 当前时间同步刷新\n    var update_time;\n    (update_time = function () {\n        $('#current_time').html(moment().format('dddd, YYYY-MM-DD, h:mm:ss a'));\n    })();\n    setInterval(update_time, 1000);\n</script>\n{% endblock %}\n"
  },
  {
    "path": "app_backend/templates/user/_give_active.html",
    "content": "<div class=\"modal fade\" id=\"give_active\" tabindex=\"-1\" role=\"dialog\" aria-labelledby=\"myModalLabel\">\n    <div class=\"modal-dialog\" role=\"document\">\n        <div class=\"modal-content\">\n            <div class=\"modal-header\">\n                <button type=\"button\" class=\"close\" data-dismiss=\"modal\" aria-label=\"Close\"><span\n                        aria-hidden=\"true\">&times;</span></button>\n                <h4 class=\"modal-title\" id=\"myModalLabel\">赠送激活码</h4>\n            </div>\n            <div class=\"modal-body\">\n                {# 表单 #}\n                <form class=\"form-horizontal\" method=\"post\" action=\"\">\n                    {{ form.csrf_token }}\n{#                    {{ form.user_id() }}#}\n{#                    <p></p>#}\n                    <div class=\"form-group\">\n                        <label class=\"col-sm-2 control-label\" for=\"nickname\">用户名称</label>\n                        <div class=\"col-sm-10\">\n                            <input class=\"form-control\" disabled=\"disabled\" id=\"nickname\" name=\"nickname\" placeholder=\"用户名称\" type=\"text\" value=\"Admin\">\n                        </div>\n                    </div>\n                    <div class=\"form-group\">\n                        <label class=\"col-sm-2 control-label\" for=\"amount\">赠送数量</label>\n                        <div class=\"col-sm-10\">\n                            <input class=\"form-control\" id=\"amount\" min=\"1\" name=\"amount\" placeholder=\"填写赠送数量\" type=\"number\" value=\"1\">\n                            <span class=\"help-block\">赠送数量必须为整数 [当前剩余激活码数量：5]</span>\n                        </div>\n                    </div>\n\n                </form>\n            </div>\n            <div class=\"modal-footer\">\n                <button type=\"button\" class=\"btn btn-default\" data-dismiss=\"modal\">关闭</button>\n                <button type=\"button\" class=\"btn btn-primary\" >赠送</button>\n            </div>\n        </div>\n    </div>\n</div>"
  },
  {
    "path": "app_backend/templates/user/_team_tree.html",
    "content": "<li class=\"list-unstyled\">\n{% for (user_id, nickname, type_level_code), value in team_tree.items() recursive %}\n    {% if loop.first %}\n        <ul>\n    {% endif %}\n        <li class=\"list-unstyled\">\n            <a href=\"javascript:void(0);\">{{ nickname }} [{{ user_id }}] [{{ type_level_code | type_level }}]</a>\n        </li>\n    {% if value %}\n        {{ loop(value.items()) }}\n    {% endif %}\n    {% if loop.last %}\n        </ul>\n    {% endif %}\n{% endfor %}\n</li>"
  },
  {
    "path": "app_backend/templates/user/add.html",
    "content": "{% extends \"layout.html\" %}\n\n{% block content %}\n<div class=\"container-fluid\">\n    <ol class=\"breadcrumb\">\n        <li><a href=\"/\">后台管理</a></li>\n        <li><a href=\"javascript:void(0);\" onclick=\"$('#menu-user').trigger('click');\">会员管理</a></li>\n        <li class=\"active\">会员添加</li>\n    </ol>\n    <h2 class=\"sub-header\">User Add!</h2>\n\n\n</div>\n\n{% endblock %}"
  },
  {
    "path": "app_backend/templates/user/auth.html",
    "content": "{% extends \"layout.html\" %}\n\n{% block content %}\n    <div class=\"container-fluid\">\n    <ol class=\"breadcrumb\">\n        <li><a href=\"/\">后台管理</a></li>\n        <li><a href=\"javascript:void(0);\" onclick=\"$('#menu-user').trigger('click');\">会员管理</a></li>\n        <li class=\"active\">认证信息</li>\n    </ol>\n\n    {# 表单 #}\n    <form class=\"form-horizontal\" method=\"post\" action=\"\">\n        {{ form.csrf_token }}\n        {{ form.id() }}\n        {{ form.user_id() }}\n        {# 标签导航 #}\n        <ul class=\"nav nav-tabs\">  {# 填充整个导航条：nav-justified #}\n            <li role=\"presentation\" class=\"active\"><a href=\"{{ url_for('user.auth', user_id=form.user_id.data) }}\">登录信息</a></li>\n            <li role=\"presentation\"><a href=\"{{ url_for('user.bank', user_id=form.user_id.data) }}\">银行信息</a></li>\n            <li role=\"presentation\"><a href=\"{{ url_for('user.profile', user_id=form.user_id.data) }}\">基本信息</a></li>\n        </ul>\n        <p></p>\n\n        <div class=\"form-group{% if form.auth_key.errors %} has-error{% endif %}\">\n            {{ form.auth_key.label(class=\"col-sm-2 control-label\") }}\n            <div class=\"col-sm-10\">\n                {{ form.auth_key(class=\"form-control\", placeholder=\"登录账号[2-20位]\", minlength=\"2\", maxlength=\"20\") }}\n                {% for error in form.auth_key.errors %}\n                    <span class=\"help-block\">{{ error }}</span>\n                {% endfor %}\n            </div>\n        </div>\n        <div class=\"form-group{% if form.auth_secret.errors %} has-error{% endif %}\">\n            {{ form.auth_secret.label(class=\"col-sm-2 control-label\") }}\n            <div class=\"col-sm-10\">\n                {{ form.auth_secret(class=\"form-control\", placeholder=\"登录密码[6-20位]，若无需更改，请留空\", maxlength=\"20\") }}\n                {% for error in form.auth_secret.errors %}\n                    <span class=\"help-block\">{{ error }}</span>\n                {% endfor %}\n            </div>\n        </div>\n        <div class=\"form-group{% if form.status_verified.errors %} has-error{% endif %}\">\n            {{ form.status_verified.label(class=\"col-sm-2 control-label\") }}\n            <div class=\"col-sm-10\">\n                {{ form.status_verified() }}\n                {% for error in form.status_verified.errors %}\n                    <span class=\"help-block\">{{ error }}</span>\n                {% endfor %}\n            </div>\n        </div>\n        <div class=\"form-group{% if form.create_time.errors %} has-error{% endif %}\">\n            {{ form.create_time.label(class=\"col-sm-2 control-label\") }}\n            <div class=\"col-sm-10\">\n                <div class=\"form-control\">\n                    {{ moment(form.create_time.data).format('YYYY-MM-DD HH:mm:ss') }}\n                </div>\n                {% for error in form.create_time.errors %}\n                    <span class=\"help-block\">{{ error }}</span>\n                {% endfor %}\n            </div>\n        </div>\n        <div class=\"form-group{% if form.update_time.errors %} has-error{% endif %}\">\n            {{ form.update_time.label(class=\"col-sm-2 control-label\") }}\n            <div class=\"col-sm-10\">\n                <div class=\"form-control\">\n                    {{ moment(form.update_time.data).format('YYYY-MM-DD HH:mm:ss') }}\n                </div>\n                {% for error in form.update_time.errors %}\n                    <span class=\"help-block\">{{ error }}</span>\n                {% endfor %}\n            </div>\n        </div>\n        <div class=\"form-group\">\n            <div class=\"col-sm-offset-2 col-sm-10\">\n                <button type=\"submit\" class=\"btn btn-success btn-load\" data-loading-text=\"保存中\">保存</button>\n                <button type=\"reset\" class=\"btn btn-default\">重新填写</button>\n            </div>\n        </div>\n    </form>\n\n\n    </div>\n\n{% endblock %}\n\n{% block extra_js %}\n\n{% endblock %}\n"
  },
  {
    "path": "app_backend/templates/user/bank.html",
    "content": "{% extends \"layout.html\" %}\n\n{% block content %}\n    <div class=\"container-fluid\">\n    <ol class=\"breadcrumb\">\n        <li><a href=\"/\">后台管理</a></li>\n        <li><a href=\"javascript:void(0);\" onclick=\"$('#menu-user').trigger('click');\">会员管理</a></li>\n        <li class=\"active\">银行信息</li>\n    </ol>\n\n    {# 表单 #}\n    <form class=\"form-horizontal\" method=\"post\" action=\"\">\n        {{ form.csrf_token }}\n        {{ form.user_id() }}\n        {# 标签导航 #}\n        <ul class=\"nav nav-tabs\">  {# 填充整个导航条：nav-justified #}\n            <li role=\"presentation\"><a href=\"{{ url_for('user.auth', user_id=form.user_id.data) }}\">登录信息</a></li>\n            <li role=\"presentation\" class=\"active\"><a href=\"{{ url_for('user.bank', user_id=form.user_id.data) }}\">银行信息</a></li>\n            <li role=\"presentation\"><a href=\"{{ url_for('user.profile', user_id=form.user_id.data) }}\">基本信息</a></li>\n        </ul>\n        <p></p>\n        <div class=\"form-group{% if form.account_name.errors %} has-error{% endif %}\">\n            {{ form.account_name.label(class=\"col-sm-2 control-label\") }}\n            <div class=\"col-sm-10\">\n                {{ form.account_name(class=\"form-control\", placeholder=\"账户姓名\") }}\n                {% for error in form.account_name.errors %}\n                    <span class=\"help-block\">{{ error }}</span>\n                {% endfor %}\n            </div>\n        </div>\n        <div class=\"form-group{% if form.bank_name.errors %} has-error{% endif %}\">\n            {{ form.bank_name.label(class=\"col-sm-2 control-label\") }}\n            <div class=\"col-sm-10\">\n                {{ form.bank_name(class=\"form-control\", placeholder=\"银行名称\") }}\n                {% for error in form.bank_name.errors %}\n                    <span class=\"help-block\">{{ error }}</span>\n                {% endfor %}\n            </div>\n        </div>\n        <div class=\"form-group{% if form.bank_address.errors %} has-error{% endif %}\">\n            {{ form.bank_address.label(class=\"col-sm-2 control-label\") }}\n            <div class=\"col-sm-10\">\n                {{ form.bank_address(class=\"form-control\", placeholder=\"支行名称\") }}\n                {% for error in form.bank_address.errors %}\n                    <span class=\"help-block\">{{ error }}</span>\n                {% endfor %}\n            </div>\n        </div>\n        <div class=\"form-group{% if form.bank_account.errors %} has-error{% endif %}\">\n            {{ form.bank_account.label(class=\"col-sm-2 control-label\") }}\n            <div class=\"col-sm-10\">\n                {{ form.bank_account(class=\"form-control\", placeholder=\"银行卡号\") }}\n                {% for error in form.bank_account.errors %}\n                    <span class=\"help-block\">{{ error }}</span>\n                {% endfor %}\n            </div>\n        </div>\n        <div class=\"form-group{% if form.status_verified.errors %} has-error{% endif %}\">\n            {{ form.status_verified.label(class=\"col-sm-2 control-label\") }}\n            <div class=\"col-sm-10\">\n                {{ form.status_verified() }}\n                {% for error in form.status_verified.errors %}\n                    <span class=\"help-block\">{{ error }}</span>\n                {% endfor %}\n            </div>\n        </div>\n        <div class=\"form-group{% if form.create_time.errors %} has-error{% endif %}\">\n            {{ form.create_time.label(class=\"col-sm-2 control-label\") }}\n            <div class=\"col-sm-10\">\n                <div class=\"form-control\">\n                    {{ moment(form.create_time.data).format('YYYY-MM-DD HH:mm:ss') }}\n                </div>\n                {% for error in form.create_time.errors %}\n                    <span class=\"help-block\">{{ error }}</span>\n                {% endfor %}\n            </div>\n        </div>\n        <div class=\"form-group{% if form.update_time.errors %} has-error{% endif %}\">\n            {{ form.update_time.label(class=\"col-sm-2 control-label\") }}\n            <div class=\"col-sm-10\">\n                <div class=\"form-control\">\n                    {{ moment(form.update_time.data).format('YYYY-MM-DD HH:mm:ss') }}\n                </div>\n                {% for error in form.update_time.errors %}\n                    <span class=\"help-block\">{{ error }}</span>\n                {% endfor %}\n            </div>\n        </div>\n        <div class=\"form-group\">\n            <div class=\"col-sm-offset-2 col-sm-10\">\n                <button type=\"submit\" class=\"btn btn-success btn-load\" data-loading-text=\"保存中\">保存</button>\n                <button type=\"reset\" class=\"btn btn-default\">重新填写</button>\n            </div>\n        </div>\n    </form>\n\n\n    </div>\n\n{% endblock %}\n\n{% block extra_js %}\n\n{% endblock %}\n"
  },
  {
    "path": "app_backend/templates/user/config.html",
    "content": "<!-- extend from base layout -->\n{% extends \"layout.html\" %}\n\n{% block content %}\n    <div class=\"container\">\n    <ol class=\"breadcrumb\">\n        <li><a href=\"/\">首页</a></li>\n        <li><a href=\"javascript:void(0);\" onclick=\"$('#menu-user').trigger('click');\">会员管理</a></li>\n        <li class=\"active\">用户配置</li>\n    </ol>\n    <form class=\"form-horizontal\" method=\"post\" action=\"\">\n        {{ form.csrf_token }}\n        <div class=\"form-group{% if form.user_id.errors %} has-error{% endif %}\">\n            {{ form.user_id.label(class=\"col-sm-2 control-label\") }}\n            <div class=\"col-sm-10\">\n                <div class=\"form-control\">{{ form.user_id.data | nickname }}</div>\n                {% for error in form.user_id.errors %}\n                    <span class=\"help-block\">{{ error }}</span>\n                {% endfor %}\n            </div>\n        </div>\n        <div class=\"form-group{% if form.team_bonus.errors %} has-error{% endif %}\">\n            {{ form.team_bonus.label(class=\"col-sm-2 control-label\") }}\n            <div class=\"col-sm-10\">\n                {{ form.team_bonus(class=\"form-control\", placeholder=\"填写奖金配置\") }}\n                {% for error in form.team_bonus.errors %}\n                    <span class=\"help-block\">{{ error }}</span>\n                {% endfor %}\n                <span class=\"help-block\">小数表示，半角逗号分隔；如为空，则按全局配置执行</span>\n                <span class=\"help-block\">例如：0.05,0.05,0.03（一级,二级,三级） 暂时最多支持3级</span>\n            </div>\n        </div>\n        <div class=\"form-group\">\n            <div class=\"col-sm-offset-2 col-sm-10\">\n                <button type=\"submit\" class=\"btn btn-success btn-load\" data-loading-text=\"配置中\">配置</button>\n                <button type=\"reset\" class=\"btn btn-default\">重新填写</button>\n                <button class=\"btn btn-default\" onclick=\"history.back();\">返回</button>\n            </div>\n        </div>\n    </form>\n    </div>\n{% endblock %}\n"
  },
  {
    "path": "app_backend/templates/user/list.html",
    "content": "<!-- extend from base layout -->\n{% extends \"layout.html\" %}\n\n{% block extra_css %}\n\n{% endblock %}\n\n{% block content %}\n    <div class=\"container-fluid\">\n    <ol class=\"breadcrumb\">\n        <li><a href=\"/\">后台管理</a></li>\n        <li><a href=\"javascript:void(0);\" onclick=\"$('#menu-user').trigger('click');\">会员管理</a></li>\n        <li class=\"active\">会员列表</li>\n    </ol>\n\n    <form class=\"form-inline\">\n        <div class=\"form-group{% if form.user_id.errors %} has-error{% endif %}\">\n            {{ form.user_id.label(class=\"sr-only\") }}\n            {{ form.user_id(class=\"form-control\", placeholder=\"用户ID\") }}\n            {% for error in form.user_id.errors %}\n                <span class=\"help-block\">{{ error }}</span>\n            {% endfor %}\n        </div>\n        <div class=\"form-group{% if form.user_name.errors %} has-error{% endif %}\">\n            {{ form.user_name.label(class=\"sr-only\") }}\n            {{ form.user_name(class=\"form-control\", placeholder=\"用户名称\") }}\n            {% for error in form.user_name.errors %}\n                <span class=\"help-block\">{{ error }}</span>\n            {% endfor %}\n        </div>\n        <div class=\"form-group{% if form.start_time.errors %} has-error{% endif %}\">\n            {{ form.start_time.label(class=\"sr-only\") }}\n            {{ form.start_time(class=\"form-control\", placeholder=\"start_time\", type='date') }}\n            {% for error in form.start_time.errors %}\n                <span class=\"help-block\">{{ error }}</span>\n            {% endfor %}\n        </div>\n        <div class=\"form-group{% if form.end_time.errors %} has-error{% endif %}\">\n            {{ form.end_time.label(class=\"sr-only\") }}\n            {{ form.end_time(class=\"form-control\", placeholder=\"end_time\", type='date') }}\n            {% for error in form.end_time.errors %}\n                <span class=\"help-block\">{{ error }}</span>\n            {% endfor %}\n        </div>\n        <div class=\"form-group{% if form.status_active.errors %} has-error{% endif %}\">\n            {{ form.status_active.label(class=\"sr-only\") }}\n            {{ form.status_active(class=\"form-control\", placeholder=\"激活状态\", data_width=\"fit\", data_header=\"选择状态\") }}\n            {% for error in form.status_active.errors %}\n                <span class=\"help-block\">{{ error }}</span>\n            {% endfor %}\n        </div>\n        <div class=\"form-group{% if form.status_lock.errors %} has-error{% endif %}\">\n            {{ form.status_lock.label(class=\"sr-only\") }}\n            {{ form.status_lock(class=\"form-control\", placeholder=\"锁定状态\", data_width=\"fit\", data_header=\"选择状态\") }}\n            {% for error in form.status_lock.errors %}\n                <span class=\"help-block\">{{ error }}</span>\n            {% endfor %}\n        </div>\n        <button type=\"submit\" class=\"btn btn-primary\" name=\"op\" value=\"0\">Search</button>\n        <button type=\"submit\" class=\"btn btn-primary\" name=\"op\" value=\"1\">Export</button>\n    </form>\n\n    <hr/>\n\n    <div class=\"table-responsive\">\n        {# <table class=\"table table-striped\"> #}\n        <table class=\"table table-hover\">\n            <thead>\n            <tr>\n                <th>用户ID</th>\n                <th>用户名称</th>\n                <th>等级</th>\n                <th>手机号码</th>\n                <th>推荐人</th>\n                <th>钱包余额</th>\n                <th>数字货币</th>\n{#                <th>积分</th>#}\n                <th>奖金</th>\n                <th>排单币</th>\n                <th>激活状态</th>\n                <th>锁定状态</th>\n                <th>创建时间</th>\n                <th>操作</th>\n            </tr>\n            </thead>\n            <tbody>\n            {% for (user, user_profile_c, user_profile_p, wallet, bit_coin, score, bonus, scheduling) in pagination.items %}\n            <tr class=\"text-muted\">\n                <td>{{ user.id }}</td>\n                <td><a href=\"{{ url_for('user.admin_login', user_id=user.id) }}\" rel=\"tooltip\" title=\"登录\" target=\"_blank\">{{ user_profile_c.nickname }}</a></td>\n                <td>{{ user_profile_c.type_level | type_level }}</td>\n                <td>{{ user_profile_c.phone }}</td>\n                {% if user_profile_p %}\n                <td><a href=\"{{ url_for('user.admin_login', user_id=user_profile_p.user_id) }}\" rel=\"tooltip\" title=\"登录\" target=\"_blank\">{{ user_profile_p.nickname }}</a></td>\n                {% else %}\n                <td></td>\n                {% endif %}\n                <td>{{ wallet.amount_current | default('0') }}</td>\n                <td>{{ bit_coin.amount | default('0') }}</td>\n{#                <td>{{ score.amount | default('0') }}</td>#}\n                <td>{{ bonus.amount | default('0') }}</td>\n                <td>{{ scheduling.amount | default('0') }}</td>\n                <td>{{ user.status_active | status_active }}</td>\n                <td>{{ user.status_lock | status_lock }}</td>\n                <td>{{ moment(user.create_time).format('YYYY-MM-DD HH:mm:ss') }}</td>\n                <td>\n                    <a href=\"{{ url_for('active.add', user_id=user.id, next=request.path) }}\" rel=\"tooltip\" title=\"激活码\">\n                        <span class=\"glyphicon glyphicon-qrcode\"></span>\n                    </a>\n                    <a href=\"{{ url_for('scheduling.add', user_id=user.id, next=request.path) }}\" rel=\"tooltip\" title=\"排单币\">\n                        <span class=\"glyphicon glyphicon-euro\"></span>\n                    </a>\n                    <a href=\"{{ url_for('user.profile', user_id=user.id, next=request.path) }}\" rel=\"tooltip\" title=\"编辑\">\n                        <span class=\"glyphicon glyphicon-pencil\"></span>\n                    </a>\n                    <a href=\"{{ url_for('user.config', user_id=user.id, next=request.path) }}\" rel=\"tooltip\" title=\"配置\">\n                        <span class=\"glyphicon glyphicon-cog\"></span>\n                    </a>\n                    {% if user.status_lock == STATUS_LOCK_OK | int %}\n                    <a href=\"javascript:void(0);\" onclick=\"user_unlock({{ user.id }});\" rel=\"tooltip\" title=\"解锁\">\n                        <span class=\"fa fa-unlock-alt\"></span>\n                    </a>\n                    {% else %}\n                    <a href=\"javascript:void(0);\" onclick=\"user_lock({{ user.id }});\" rel=\"tooltip\" title=\"锁定\">\n                        <span class=\"glyphicon glyphicon-lock\"></span>\n                    </a>\n                    {% endif %}\n                    <a href=\"javascript:void(0);\" onclick=\"user_delete({{ user.id }});\" rel=\"tooltip\" title=\"删除\">\n                        <span class=\"glyphicon glyphicon-trash\"></span>\n                    </a>\n                </td>\n            </tr>\n            {% endfor %}\n            </tbody>\n        </table>\n        {# 翻页 #}\n        {% from \"macros.html\" import render_pagination %}\n        {{ render_pagination(pagination, 'user.lists') }}\n\n    </div>\n    </div>\n{% endblock %}\n\n{% block extra_js %}\n<script>\n    // 初始化赋值\n    var status_active = $('#status_active');\n    status_active.selectpicker('val', '{{ form.status_active.data }}');\n    // 处理选项修改\n    status_active.on('changed.bs.select', function (event, clickedIndex, newValue, oldValue) {\n        // console.log($('#status_active').val());\n        // console.log(event);\n        // console.log(clickedIndex);\n        // console.log(newValue);\n        // console.log(oldValue);\n    });\n\n    var status_lock = $('#status_lock');\n    status_lock.selectpicker('val', '{{ form.status_lock.data }}');\n    // 处理选项修改\n    status_lock.on('changed.bs.select', function (event, clickedIndex, newValue, oldValue) {\n        // console.log($('#status_lock').val());\n        // console.log(event);\n        // console.log(clickedIndex);\n        // console.log(newValue);\n        // console.log(oldValue);\n    });\n\n    // 用户锁定\n    function user_lock(user_id){\n        if(confirm(\"用户锁定操作，是否确认?\"))\n        {\n            // console.log(user_id);\n            $.getJSON('{{ url_for('user.ajax_lock') }}',\n            {\n                user_id: user_id\n            }, function (result) {\n                if(result.hasOwnProperty('error')){\n                    alert(result.error);\n                }else {\n                    alert(result.success);\n                    window.location.reload();\n                }\n            });\n            return false;\n        }\n    }\n\n    // 用户解锁\n    function user_unlock(user_id){\n        if(confirm(\"用户解锁操作，是否确认?\"))\n        {\n            // console.log(user_id);\n            $.getJSON('{{ url_for('user.ajax_unlock') }}',\n            {\n                user_id: user_id\n            }, function (result) {\n                if(result.hasOwnProperty('error')){\n                    alert(result.error);\n                }else {\n                    alert(result.success);\n                    window.location.reload();\n                }\n            });\n            return false;\n        }\n    }\n\n    // 用户删除\n    function user_delete(user_id){\n        if(confirm(\"删除数据不能恢复，是否确认删除?\"))\n        {\n            // console.log(user_id);\n            $.getJSON('{{ url_for('user.ajax_delete') }}',\n            {\n                user_id: user_id\n            }, function (result) {\n                if(result.hasOwnProperty('error')){\n                    alert(result.error);\n                }else {\n                    alert(result.success);\n                    window.location.reload();\n                }\n            });\n            return false;\n        }\n    }\n</script>\n{% endblock %}\n"
  },
  {
    "path": "app_backend/templates/user/profile.html",
    "content": "{% extends \"layout.html\" %}\n\n{% block content %}\n    <div class=\"container-fluid\">\n    <ol class=\"breadcrumb\">\n        <li><a href=\"/\">后台管理</a></li>\n        <li><a href=\"javascript:void(0);\" onclick=\"$('#menu-user').trigger('click');\">会员管理</a></li>\n        <li class=\"active\">会员信息</li>\n    </ol>\n\n    {# 表单 #}\n    <form class=\"form-horizontal\" method=\"post\" action=\"\">\n        {{ form.csrf_token }}\n        {{ form.user_id() }}\n        {# 标签导航 #}\n        <ul class=\"nav nav-tabs\">  {# 填充整个导航条：nav-justified #}\n            <li role=\"presentation\"><a href=\"{{ url_for('user.auth', user_id=form.user_id.data) }}\">登录信息</a></li>\n            <li role=\"presentation\"><a href=\"{{ url_for('user.bank', user_id=form.user_id.data) }}\">银行信息</a></li>\n            <li role=\"presentation\" class=\"active\"><a href=\"{{ url_for('user.profile', user_id=form.user_id.data) }}\">基本信息</a></li>\n        </ul>\n        <p></p>\n        <div class=\"form-group{% if form.user_pid.errors %} has-error{% endif %}\">\n            {{ form.user_pid.label(class=\"col-sm-2 control-label\") }}\n            <div class=\"col-sm-10\">\n                {{ form.user_pid(class=\"form-control\", placeholder=\"Pid\") }}\n                {% for error in form.user_pid.errors %}\n                    <span class=\"help-block\">{{ error }}</span>\n                {% endfor %}\n                <span class=\"help-block\">推荐人名称：{{ form.user_pid.data | nickname }}</span>\n            </div>\n        </div>\n        <div class=\"form-group{% if form.nickname.errors %} has-error{% endif %}\">\n            {{ form.nickname.label(class=\"col-sm-2 control-label\") }}\n            <div class=\"col-sm-10\">\n                {{ form.nickname(class=\"form-control\", placeholder=\"用户名称\", disabled=\"disabled\") }}\n                {% for error in form.nickname.errors %}\n                    <span class=\"help-block\">{{ error }}</span>\n                {% endfor %}\n            </div>\n        </div>\n        <div class=\"form-group{% if form.email.errors %} has-error{% endif %}\">\n            {{ form.email.label(class=\"col-sm-2 control-label\") }}\n            <div class=\"col-sm-10\">\n                {{ form.email(class=\"form-control\", placeholder=\"电子邮箱\") }}\n                {% for error in form.email.errors %}\n                    <span class=\"help-block\">{{ error }}</span>\n                {% endfor %}\n            </div>\n        </div>\n        <div class=\"form-group{% if form.area_id.errors %} has-error{% endif %}\">\n            {{ form.area_id.label(class=\"col-sm-2 control-label\") }}\n            <div class=\"col-sm-10\">\n                {{ form.area_id(data_header=\"选择手机区号\") }}\n                {% for error in form.area_id.errors %}\n                    <span class=\"help-block\">{{ error }}</span>\n                {% endfor %}\n            </div>\n        </div>\n        <div class=\"form-group{% if form.phone.errors %} has-error{% endif %}\">\n            {{ form.phone.label(class=\"col-sm-2 control-label\") }}\n            <div class=\"col-sm-10\">\n                {{ form.phone(class=\"form-control\", placeholder=\"手机号码\", type=\"tel\", maxlength=11) }}\n                {% for error in form.phone.errors %}\n                    <span class=\"help-block\">{{ error }}</span>\n                {% endfor %}\n            </div>\n        </div>\n        <div class=\"form-group{% if form.birthday.errors %} has-error{% endif %}\">\n            {{ form.birthday.label(class=\"col-sm-2 control-label\") }}\n            <div class=\"col-sm-10\">\n                {{ form.birthday(class=\"form-control\", placeholder=\"Birthday\", type=\"date\") }}\n                {% for error in form.birthday.errors %}\n                    <span class=\"help-block\">{{ error }}</span>\n                {% endfor %}\n            </div>\n        </div>\n        <div class=\"form-group{% if form.real_name.errors %} has-error{% endif %}\">\n                    {{ form.real_name.label(class=\"col-sm-2 control-label\") }}\n                    <div class=\"col-sm-10\">\n                        {{ form.real_name(class=\"form-control\", placeholder=\"真实姓名\") }}\n                        {% for error in form.real_name.errors %}\n                            <span class=\"help-block\">{{ error }}</span>\n                        {% endfor %}\n                    </div>\n                </div>\n        <div class=\"form-group{% if form.id_card.errors %} has-error{% endif %}\">\n            {{ form.id_card.label(class=\"col-sm-2 control-label\") }}\n            <div class=\"col-sm-10\">\n                {{ form.id_card(class=\"form-control\", placeholder=\"身份证号\", maxlength=18) }}\n                {% for error in form.id_card.errors %}\n                    <span class=\"help-block\">{{ error }}</span>\n                {% endfor %}\n            </div>\n        </div>\n        <div class=\"form-group{% if form.create_time.errors %} has-error{% endif %}\">\n            {{ form.create_time.label(class=\"col-sm-2 control-label\") }}\n            <div class=\"col-sm-10\">\n                <div class=\"form-control\">\n                    {{ moment(form.create_time.data).format('YYYY-MM-DD HH:mm:ss') }}\n                </div>\n                {% for error in form.create_time.errors %}\n                    <span class=\"help-block\">{{ error }}</span>\n                {% endfor %}\n            </div>\n        </div>\n        <div class=\"form-group{% if form.update_time.errors %} has-error{% endif %}\">\n            {{ form.update_time.label(class=\"col-sm-2 control-label\") }}\n            <div class=\"col-sm-10\">\n                <div class=\"form-control\">\n                    {{ moment(form.update_time.data).format('YYYY-MM-DD HH:mm:ss') }}\n                </div>\n                {% for error in form.update_time.errors %}\n                    <span class=\"help-block\">{{ error }}</span>\n                {% endfor %}\n            </div>\n        </div>\n        <div class=\"form-group\">\n            <div class=\"col-sm-offset-2 col-sm-10\">\n                <button type=\"submit\" class=\"btn btn-success btn-load\" data-loading-text=\"保存中\">保存</button>\n                <button type=\"reset\" class=\"btn btn-default\">重新填写</button>\n            </div>\n        </div>\n    </form>\n\n\n    </div>\n\n{% endblock %}\n\n{% block extra_js %}\n<script>\n    // 初始化赋值\n    var area_id = $('#area_id');\n    area_id.selectpicker('val', '{{ form.area_id.data }}');\n    // 处理选项修改\n    area_id.on('changed.bs.select', function (event, clickedIndex, newValue, oldValue) {\n        // console.log($('#area_id').val());\n        // console.log(event);\n        // console.log(clickedIndex);\n        // console.log(newValue);\n        // console.log(oldValue);\n    });\n</script>\n{% endblock %}\n"
  },
  {
    "path": "app_backend/templates/user/relationship.html",
    "content": "{% extends \"layout.html\" %}\n\n{% block extra_css %}\n    <style>\n        .node circle {\n            fill: #999;\n        }\n        .node text {\n            font: 10px sans-serif;\n        }\n        .node--internal circle {\n            fill: #555;\n        }\n        .node--internal text {\n            text-shadow: 0 1px 0 #fff, 0 -1px 0 #fff, 1px 0 0 #fff, -1px 0 0 #fff;\n        }\n        .link {\n            fill: none;\n            stroke: #555;\n            stroke-opacity: 0.4;\n            stroke-width: 1.5;\n        }\n    </style>\n{% endblock %}\n\n{% block content %}\n    <div class=\"container-fluid\">\n        <ol class=\"breadcrumb\">\n            <li><a href=\"/\">后台管理</a></li>\n            <li><a href=\"javascript:void(0);\" onclick=\"$('#menu-user').trigger('click');\">会员管理</a></li>\n            <li class=\"active\">会员关系</li>\n        </ol>\n\n        <form class=\"form-inline\">\n            <div class=\"form-group{% if form.user_id.errors %} has-error{% endif %}\">\n                {{ form.user_id.label(class=\"sr-only\") }}\n                {{ form.user_id(class=\"form-control\", placeholder=\"用户ID\") }}\n                {% for error in form.user_id.errors %}\n                    <span class=\"help-block\">{{ error }}</span>\n                {% endfor %}\n            </div>\n            <div class=\"form-group{% if form.user_name.errors %} has-error{% endif %}\">\n                {{ form.user_name.label(class=\"sr-only\") }}\n                {{ form.user_name(class=\"form-control\", placeholder=\"用户名称\") }}\n                {% for error in form.user_name.errors %}\n                    <span class=\"help-block\">{{ error }}</span>\n                {% endfor %}\n            </div>\n            <button type=\"submit\" class=\"btn btn-primary\" name=\"op\" value=\"0\">Search</button>\n        </form>\n\n        <hr/>\n\n        {% include 'user/_team_tree.html' %}\n\n{#        <svg width=\"960\" height=\"1060\"></svg>#}\n    </div>\n\n{% endblock %}\n\n{% block extra_js %}\n    <script src=\"{{ url_for('static', filename='plugin/d3/d3.min.js') }}\"></script>\n    <script>\n\n        var svg = d3.select(\"svg\"),\n                width = +svg.attr(\"width\"),\n                height = +svg.attr(\"height\"),\n                g = svg.append(\"g\").attr(\"transform\", \"translate(\" + (width / 2 + 40) + \",\" + (height / 2 + 90) + \")\");\n\n        var stratify = d3.stratify()\n                .parentId(function (d) {\n                    return d.id.substring(0, d.id.lastIndexOf(\".\"));\n                });\n\n        var tree = d3.tree()\n                .size([2 * Math.PI, 500])\n                .separation(function (a, b) {\n                    return (a.parent == b.parent ? 1 : 2) / a.depth;\n                });\n\n        d3.csv('{{ url_for('static', filename='csv/flare.csv') }}', function (error, data) {\n            if (error) throw error;\n\n            var root = tree(stratify(data));\n\n            var link = g.selectAll(\".link\")\n                    .data(root.links())\n                    .enter().append(\"path\")\n                    .attr(\"class\", \"link\")\n                    .attr(\"d\", d3.linkRadial()\n                            .angle(function (d) {\n                                return d.x;\n                            })\n                            .radius(function (d) {\n                                return d.y;\n                            }));\n\n            var node = g.selectAll(\".node\")\n                    .data(root.descendants())\n                    .enter().append(\"g\")\n                    .attr(\"class\", function (d) {\n                        return \"node\" + (d.children ? \" node--internal\" : \" node--leaf\");\n                    })\n                    .attr(\"transform\", function (d) {\n                        return \"translate(\" + radialPoint(d.x, d.y) + \")\";\n                    });\n\n            node.append(\"circle\")\n                    .attr(\"r\", 2.5);\n\n            node.append(\"text\")\n                    .attr(\"dy\", \"0.31em\")\n                    .attr(\"x\", function (d) {\n                        return d.x < Math.PI === !d.children ? 6 : -6;\n                    })\n                    .attr(\"text-anchor\", function (d) {\n                        return d.x < Math.PI === !d.children ? \"start\" : \"end\";\n                    })\n                    .attr(\"transform\", function (d) {\n                        return \"rotate(\" + (d.x < Math.PI ? d.x - Math.PI / 2 : d.x + Math.PI / 2) * 180 / Math.PI + \")\";\n                    })\n                    .text(function (d) {\n                        return d.id.substring(d.id.lastIndexOf(\".\") + 1);\n                    });\n        });\n\n        function radialPoint(x, y) {\n            return [(y = +y) * Math.cos(x -= Math.PI / 2), y * Math.sin(x)];\n        }\n\n    </script>\n{% endblock %}\n"
  },
  {
    "path": "app_backend/templates/user/stats.html",
    "content": "{% extends \"layout.html\" %}\n\n{% block content %}\n<div class=\"container-fluid\">\n    <ol class=\"breadcrumb\">\n        <li><a href=\"/\">后台管理</a></li>\n        <li><a href=\"javascript:void(0);\" onclick=\"$('#menu-stats').trigger('click');\">运营统计</a></li>\n        <li class=\"active\">用户统计</li>\n    </ol>\n    <h2 class=\"sub-header\">User Stats!</h2>\n\n\n</div>\n\n{% endblock %}"
  },
  {
    "path": "app_backend/templates/wallet/list.html",
    "content": "<!-- extend from base layout -->\n{% extends \"layout.html\" %}\n\n{% block extra_css %}\n\n{% endblock %}\n\n{% block content %}\n    <div class=\"container-fluid\">\n    <h2 class=\"sub-header\">Apply Get List!</h2>\n\n    <form class=\"form-inline\">\n        <div class=\"form-group{% if form.apply_get_id.errors %} has-error{% endif %}\">\n            {{ form.apply_get_id.label(class=\"sr-only\") }}\n            {{ form.apply_get_id(class=\"form-control\", placeholder=\"Apply Get Id\") }}\n            {% for error in form.apply_get_id.errors %}\n                <span class=\"help-block\">{{ error }}</span>\n            {% endfor %}\n        </div>\n        <div class=\"form-group{% if form.user_id.errors %} has-error{% endif %}\">\n            {{ form.user_id.label(class=\"sr-only\") }}\n            {{ form.user_id(class=\"form-control\", placeholder=\"User Id\") }}\n            {% for error in form.user_id.errors %}\n                <span class=\"help-block\">{{ error }}</span>\n            {% endfor %}\n        </div>\n        <div class=\"form-group{% if form.type_apply.errors %} has-error{% endif %}\">\n            {{ form.type_apply.label(class=\"sr-only\") }}\n            {{ form.type_apply(class=\"form-control\", placeholder=\"申请类型\", data_width=\"fit\", data_header=\"选择类型\") }}\n            {% for error in form.type_apply.errors %}\n                <span class=\"help-block\">{{ error }}</span>\n            {% endfor %}\n        </div>\n        <div class=\"form-group{% if form.start_time.errors %} has-error{% endif %}\">\n            {{ form.start_time.label(class=\"sr-only\") }}\n            {{ form.start_time(class=\"form-control\", placeholder=\"start_time\", type='date') }}\n            {% for error in form.start_time.errors %}\n                <span class=\"help-block\">{{ error }}</span>\n            {% endfor %}\n        </div>\n        <div class=\"form-group{% if form.end_time.errors %} has-error{% endif %}\">\n            {{ form.end_time.label(class=\"sr-only\") }}\n            {{ form.end_time(class=\"form-control\", placeholder=\"end_time\", type='date') }}\n            {% for error in form.end_time.errors %}\n                <span class=\"help-block\">{{ error }}</span>\n            {% endfor %}\n        </div>\n\n        <button type=\"submit\" class=\"btn btn-primary\" name=\"op\" value=\"0\">Search</button>\n        <button type=\"submit\" class=\"btn btn-primary\" name=\"op\" value=\"1\">Export</button>\n    </form>\n\n    <hr/>\n\n    <div class=\"table-responsive\">\n        {# <table class=\"table table-striped\"> #}\n        <table class=\"table table-hover\">\n            <thead>\n            <tr>\n                <th>id</th>\n                <th>user_id</th>\n                <th>type_apply</th>\n                <th>money_apply</th>\n                <th>status_apply</th>\n                <th>status_order</th>\n                <th>status_delete</th>\n                <th>create_time</th>\n                <th>action</th>\n            </tr>\n            </thead>\n            <tbody>\n            {% for apply_get in pagination.items %}\n            <tr class=\"text-muted\">\n                <td>{{ apply_get.id }}</td>\n                <td>{{ apply_get.user_id }}</td>\n                <td>{{ apply_get.type_apply }}</td>\n                <td>{{ apply_get.money_apply }}</td>\n                <td>{{ apply_get.status_apply }}</td>\n                <td>{{ apply_get.status_order }}</td>\n                <td>{{ apply_get.status_delete }}</td>\n                <td>{{ moment(apply_get.create_time).format('YYYY-MM-DD HH:mm:ss') }}</td>\n                <td>\n                    <a href=\"javascript:void(0);\" onclick=\"apply_get_delete({{ apply_get.id }});\" rel=\"tooltip\" title=\"删除\"><span class=\"glyphicon glyphicon-trash\"></span></a>\n                </td>\n            </tr>\n            {% endfor %}\n            </tbody>\n        </table>\n        {# 翻页 #}\n        {% from \"macros.html\" import render_pagination %}\n        {{ render_pagination(pagination, 'user.lists') }}\n    </div>\n    </div>\n{% endblock %}\n\n{% block extra_js %}\n<script>\n    // 初始化赋值\n    var type_apply = $('#type_apply');\n    type_apply.selectpicker('val', '{{ form.type_apply.data }}');\n    // 处理选项修改\n    type_apply.on('changed.bs.select', function (event, clickedIndex, newValue, oldValue) {\n        // console.log($('#status_lock').val());\n        // console.log(event);\n        // console.log(clickedIndex);\n        // console.log(newValue);\n        // console.log(oldValue);\n    });\n    function apply_get_delete(apply_get_id){\n        if(confirm(\"删除数据不能恢复，是否确认删除?\"))\n        {\n            // console.log(user_id);\n            $.getJSON('{{ url_for('apply_get.delete') }}',\n            {\n                apply_get_id: apply_get_id\n            }, function (data) {\n                var result = data.result;  // true/false\n                // console.log(result==true);\n                if(result==true){\n                    window.location.reload();\n                }\n            });\n            return false;\n        }\n    }\n</script>\n{% endblock %}\n"
  },
  {
    "path": "app_backend/templates/wallet/stats.html",
    "content": "{% extends \"layout.html\" %}\n\n{% block content %}\n<div class=\"container-fluid\">\n    <ol class=\"breadcrumb\">\n        <li><a href=\"/\">后台管理</a></li>\n        <li><a href=\"javascript:void(0);\" onclick=\"$('#menu-stats').trigger('click');\">运营统计</a></li>\n        <li class=\"active\">钱包统计</li>\n    </ol>\n    <h2 class=\"sub-header\">Wallet Stats!</h2>\n\n\n</div>\n\n{% endblock %}"
  },
  {
    "path": "app_backend/tests/__init__.py",
    "content": "#!/usr/bin/env python\n# encoding: utf-8\n\n\"\"\"\n@author: zhanghe\n@software: PyCharm\n@file: __init__.py\n@time: 2017/6/17 下午3:29\n\"\"\"\n\n\ndef func():\n    pass\n\n\nclass Main(object):\n    def __init__(self):\n        pass\n\n\nif __name__ == '__main__':\n    pass\n"
  },
  {
    "path": "app_backend/tests/test_user_profile.py",
    "content": "#!/usr/bin/env python\n# encoding: utf-8\n\n\"\"\"\n@user: zhanghe\n@software: PyCharm\n@file: user_profile.py\n@time: 17-4-29 下午16:36\n\"\"\"\n\n\nfrom collections import Iterable\nimport json\nfrom app_backend.api.user_profile import get_team_tree_recursion\n\n\nteam_tree = get_team_tree_recursion(1)\nprint dict(team_tree)\n\n\nif __name__ == '__main__':\n    pass\n"
  },
  {
    "path": "app_backend/tools/__init__.py",
    "content": "#!/usr/bin/env python\n# encoding: utf-8\n\n\"\"\"\n@author: zhanghe\n@software: PyCharm\n@file: __init__.py\n@time: 16-2-22 下午11:05\n\"\"\"\n"
  },
  {
    "path": "app_backend/tools/config_manage.py",
    "content": "#!/usr/bin/env python\n# encoding: utf-8\n\n\"\"\"\n@author: zhanghe\n@software: PyCharm\n@file: config_manage.py\n@time: 2017/6/4 上午11:00\n\"\"\"\n\n\nimport redis\nimport json\nimport time\nfrom app_frontend import app\nredis_client = redis.Redis(**app.config['REDIS'])\n\n\ndef get_conf(conf_name):\n    \"\"\"\n    获取配置\n    :param conf_name:\n    :return:\n    \"\"\"\n    conf_key = 'conf:%s' % conf_name\n    conf_value = redis_client.get(conf_key)\n    res = conf_value or app.config.get(conf_name)\n    return str(res)\n\n\ndef set_conf(conf_name, conf_value):\n    \"\"\"\n    设置配置\n    :param conf_name:\n    :param conf_value:\n    :return:\n    \"\"\"\n    conf_key = 'conf:%s' % conf_name\n    return redis_client.set(conf_key, conf_value)\n\n\ndef clean_conf():\n    \"\"\"\n    清除配置\n    :return:\n    \"\"\"\n    conf_key = 'conf:*'\n    conf_keys = redis_client.keys(conf_key)\n    return redis_client.delete(*conf_keys)\n\n\nif __name__ == '__main__':\n    print get_conf('INTEREST_PUT'), type(get_conf('INTEREST_PUT'))\n    # print set_conf('APPLY_PUT_MIN_EACH', 4000)\n    print clean_conf()\n"
  },
  {
    "path": "app_backend/tools/db.py",
    "content": "#!/usr/bin/env python\n# encoding: utf-8\n\n\"\"\"\n@author: zhanghe\n@software: PyCharm\n@file: tools.py\n@time: 16-1-25 下午8:39\n\"\"\"\n\n# todo get_rows order_by\n# todo insert ignore\n\n\nfrom app_backend.database import db\nfrom sqlalchemy.inspection import inspect\n\n\ndef get_row_by_id(model_name, pk_id):\n    \"\"\"\n    通过 id 获取信息\n    :param model_name:\n    :param pk_id:\n    :return: None/object\n    \"\"\"\n    try:\n        row = db.session.query(model_name).get(pk_id)\n        db.session.commit()\n        return row\n    except Exception as e:\n        db.session.rollback()\n        raise e\n\n\ndef get_rows_by_ids(model_name, pk_ids):\n    \"\"\"\n    通过一组 ids 获取信息列表\n    :param model_name:\n    :param pk_ids:\n    :return: list\n    \"\"\"\n    try:\n        model_pk = inspect(model_name).primary_key[0]\n        rows = db.session.query(model_name).filter(model_pk.in_(pk_ids)).all()\n        db.session.commit()\n        return rows\n    except Exception as e:\n        db.session.rollback()\n        raise e\n\n\ndef get_limit_rows_by_last_id(model_name, last_pk_id, limit_num, *args, **kwargs):\n    \"\"\"\n    通过最后一个主键 id 获取最新信息列表\n    适用场景：\n    1、动态加载\n    2、快速定位\n    :param model_name:\n    :param last_pk_id:\n    :param limit_num:\n    :param args:\n    :param kwargs:\n    :return: list\n    \"\"\"\n    try:\n        model_pk = inspect(model_name).primary_key[0]\n        rows = db.session.query(model_name).filter(model_pk > last_pk_id, *args).filter_by(**kwargs).limit(limit_num).all()\n        db.session.commit()\n        return rows\n    except Exception as e:\n        db.session.rollback()\n        raise e\n\n\ndef get_row(model_name, *args, **kwargs):\n    \"\"\"\n    获取信息\n    Usage:\n        # 方式一\n        get_row(User, User.id > 1)\n        # 方式二\n        test_condition = {\n            'name': \"Larry\"\n        }\n        get_row(User, **test_condition)\n    :param model_name:\n    :param args:\n    :param kwargs:\n    :return: None/object\n    \"\"\"\n    try:\n        row = db.session.query(model_name).filter(*args).filter_by(**kwargs).first()\n        db.session.commit()\n        return row\n    except Exception as e:\n        db.session.rollback()\n        raise e\n\n\ndef get_lists(model_name, *args, **kwargs):\n    \"\"\"\n    获取列表信息\n    Usage:\n        # 方式一\n        get_lists(User, User.id > 1)\n        # 方式二\n        test_condition = {\n            'name': \"Larry\"\n        }\n        get_lists(User, **test_condition)\n    :param model_name:\n    :param args:\n    :param kwargs:\n    :return: None/list\n    \"\"\"\n    try:\n        lists = db.session.query(model_name).filter(*args).filter_by(**kwargs).all()\n        db.session.commit()\n        return lists\n    except Exception as e:\n        db.session.rollback()\n        raise e\n\n\ndef count(model_name, *args, **kwargs):\n    \"\"\"\n    计数\n    Usage:\n        # 方式一\n        count(User, User.id > 1)\n        # 方式二\n        test_condition = {\n            'name': \"Larry\"\n        }\n        count(User, **test_condition)\n    :param model_name:\n    :param args:\n    :param kwargs:\n    :return: 0/Number（int）\n    \"\"\"\n    try:\n        result_count = db.session.query(model_name).filter(*args).filter_by(**kwargs).count()\n        db.session.commit()\n        return result_count\n    except Exception as e:\n        db.session.rollback()\n        raise e\n\n\ndef add(model_name, data):\n    \"\"\"\n    添加信息\n    :param model_name:\n    :param data:\n    :return: None/Value of model_obj.PK\n    \"\"\"\n    model_obj = model_name(**data)\n    try:\n        db.session.add(model_obj)\n        db.session.commit()\n        return inspect(model_obj).identity[0]\n    except Exception as e:\n        db.session.rollback()\n        raise e\n\n\ndef edit(model_name, pk_id, data):\n    \"\"\"\n    修改信息\n    :param model_name:\n    :param pk_id:\n    :param data:\n    :return: Number of affected rows (Example: 0/1)\n    \"\"\"\n    model_pk = inspect(model_name).primary_key[0]\n    try:\n        model_obj = db.session.query(model_name).filter(model_pk == pk_id)\n        result = model_obj.update(data)\n        db.session.commit()\n        return result\n    except Exception as e:\n        db.session.rollback()\n        raise e\n\n\ndef merge(model_name, data):\n    \"\"\"\n    覆盖信息(没有新增，存在更新)\n    数据中必须带主键字段\n    :param model_name:\n    :param data:\n    :return: Value of PK\n    \"\"\"\n    model_obj = model_name(**data)\n    try:\n        r = db.session.merge(model_obj)\n        db.session.commit()\n        return inspect(r).identity[0]\n    except Exception as e:\n        db.session.rollback()\n        raise e\n\n\ndef increase(model_name, pk_id, field, num=1, **kwargs):\n    \"\"\"\n    字段自增\n    :param model_name:\n    :param pk_id:\n    :param field:\n    :param num:\n    :param kwargs:\n    :return: Number of affected rows (Example: 0/1)\n    \"\"\"\n    model_pk = inspect(model_name).primary_key[0]\n    try:\n        model_obj = db.session.query(model_name).filter(model_pk == pk_id)\n        value = getattr(model_name, field) + num\n        data = {\n            field: value\n        }\n        data.update(**kwargs)  # 更新扩展字段\n        result = model_obj.update(data)\n        db.session.commit()\n        return result\n    except Exception as e:\n        db.session.rollback()\n        raise e\n\n\ndef delete(model_name, pk_id):\n    \"\"\"\n    删除信息\n    :param model_name:\n    :param pk_id:\n    :return: Number of affected rows (Example: 0/1)\n    \"\"\"\n    model_pk = inspect(model_name).primary_key[0]\n    try:\n        model_obj = db.session.query(model_name).filter(model_pk == pk_id)\n        result = model_obj.delete()\n        db.session.commit()\n        return result\n    except Exception as e:\n        db.session.rollback()\n        raise e\n\n\ndef get_rows(model_name, page=1, per_page=10, *args, **kwargs):\n    \"\"\"\n    获取信息列表（分页）\n    Usage:\n        items: 信息列表\n        has_next: 如果本页之后还有超过一个分页，则返回True\n        has_prev: 如果本页之前还有超过一个分页，则返回True\n        next_num: 返回下一页的页码\n        prev_num: 返回上一页的页码\n        iter_pages(): 页码列表\n        iter_pages(left_edge=2, left_current=2, right_current=5, right_edge=2) 页码列表默认参数\n    :param model_name:\n    :param page:\n    :param per_page:\n    :param args:\n    :param kwargs:\n    :return: None/object\n    \"\"\"\n    try:\n        rows = model_name.query. \\\n            filter(*args). \\\n            filter_by(**kwargs). \\\n            order_by(inspect(model_name).primary_key[0].desc()). \\\n            paginate(page, per_page, False)\n        db.session.commit()\n        return rows\n    except Exception as e:\n        db.session.rollback()\n        raise e\n\n\ndef insert_rows(model_name, data_list):\n    \"\"\"\n    批量插入数据（遇到主键/唯一索引重复，忽略报错，继续执行下一条插入任务）\n    注意：\n    Warning: Duplicate entry\n    警告有可能会提示：\n    UnicodeEncodeError: 'ascii' codec can't encode characters in position 17-20: ordinal not in range(128)\n    处理：\n    import sys\n\n    reload(sys)\n    sys.setdefaultencoding('utf8')\n\n    sql 语句大小限制\n    show VARIABLES like '%max_allowed_packet%';\n    参考：http://dev.mysql.com/doc/refman/5.7/en/packet-too-large.html\n\n    :param model_name:\n    :param data_list:\n    :return:\n    \"\"\"\n    try:\n        result = db.session.execute(model_name.__table__.insert().prefix_with('IGNORE'), data_list)\n        db.session.commit()\n        return result.rowcount\n    except Exception as e:\n        db.session.rollback()\n        raise e\n\n\ndef update_rows(model_name, data, *args, **kwargs):\n    \"\"\"\n    批量修改数据\n    :param model_name:\n    :param data:\n    :param args:\n    :param kwargs:\n    :return:\n    \"\"\"\n    try:\n        model_obj = db.session.query(model_name).filter(*args).filter_by(**kwargs)\n        result = model_obj.update(data, synchronize_session=False)\n        db.session.commit()\n        return result\n    except Exception as e:\n        db.session.rollback()\n        raise e\n\n\ndef update_rows_by_ids(model_name, pk_ids, data):\n    \"\"\"\n    根据一组主键id 批量修改数据\n    \"\"\"\n    model_pk = inspect(model_name).primary_key[0]\n    try:\n        model_obj = db.session.query(model_name).filter(model_pk.in_(pk_ids))\n        result = model_obj.update(data, synchronize_session=False)\n        db.session.commit()\n        return result\n    except Exception as e:\n        db.session.rollback()\n        raise e\n\n\ndef test_user():\n    \"\"\"\n    测试 User\n    :return:\n    \"\"\"\n    from app.models import User\n    print '\\n测试增删改查'\n    # 测试获取\n    row = get_row_by_id(User, 1)\n    print row\n    if row:\n        print row.id, row.email, row.nickname\n    # 测试添加\n    user_info = {\n        'email': 'admin@gmail.com',\n        # 'password': '123456',\n        'nickname': 'Admin',\n    }\n    # 测试计数\n    result_count = count(User, User.id > 1, **{'id': 2})\n    print result_count\n\n    result = add(User, user_info)\n    print result\n    # # 测试修改\n    # result = edit(User, 2, {'nickname': 'Emma'})\n    # print result\n    # # 测试删除\n    # result = delete(User, 2)\n    # print result\n    #\n    print '\\n测试单条信息'\n    test_condition = {\n        'nickname': \"Larry\"\n    }\n    row = get_row(User, **test_condition)\n    print row\n    if row:\n        print row.id, row.email, row.nickname\n    row = get_row(User, User.id > 0, id=3)\n    print row\n    if row:\n        print row.id, row.email, row.nickname\n\n\ndef test_blog():\n    \"\"\"\n    测试 Blog\n    :return:\n    \"\"\"\n    from app.models import Blog\n    print '测试通过上一次id获取列表信息'\n    rows = get_limit_rows_by_last_id(Blog, 1, 4, Blog.id > 2, **{'id': 7})\n    if rows:\n        for item in rows:\n            print item.id, item.author, item.title, item.pub_date\n\n    print '测试列表信息'\n    rows = get_rows(Blog, 1, 10, Blog.id > 0, Blog.id < 9, **{'id': 7})\n    if rows:\n        for item in rows.items:\n            print item.id, item.author, item.title, item.pub_date\n\n\ndef test_transaction():\n    \"\"\"\n    测试事务\n    \"\"\"\n    from app.models import User\n    from datetime import datetime\n    print '\\n测试事务'\n\n    try:\n        current_time = datetime.utcnow()\n        user_info_01 = {\n            'nickname': 'rose',\n            'avatar_url': '',\n            'email': 'rose@gmail.com',\n            'phone': '13818731111',\n            'create_time': current_time,\n            'update_time': current_time,\n            'last_ip': '0.0.0.0'\n        }\n        model_obj_01 = User(**user_info_01)\n        db.session.add(model_obj_01)\n        db.session.flush()\n        print inspect(model_obj_01).identity[0]\n\n        user_info_02 = {\n            'nickname': 'pit',\n            'avatar_url': '',\n            'email': 'pit@gmail.com',\n            'phone': '13818730000',\n            'create_time': current_time,\n            'update_time': current_time,\n            'last_ip': '0.0.0.0'\n        }\n        model_obj_02 = User(**user_info_02)\n        db.session.add(model_obj_02)\n        db.session.flush()\n        print inspect(model_obj_02).identity[0]\n\n    except Exception as e:\n        db.session.rollback()\n        raise e\n\n\ndef test_label():\n    \"\"\"\n    测试字符串截取和别名\n    SqLite substr\n    MySql left\n    :return:\n    \"\"\"\n    from app.models import User\n    from sqlalchemy import func\n    rows = db.session.query(User.id, func.substr(User.nickname, 2).label('nickname_new'),\n                            User.create_time).filter().order_by(User.nickname, User.create_time.desc()).all()\n    for row in rows:\n        print row.id, row.nickname_new, row.create_time\n\n\ndef test_join():\n    from app_backend.models import User, UserProfile\n    # rows = db.session.query(User, UserProfile).outerjoin(UserProfile, User.id == UserProfile.user_id).order_by(User.id.desc()).all()\n    # for row in rows:\n    #     print row[0].__dict__, row[1].__dict__\n    # paginate = User.query.join(UserProfile, User.id == UserProfile.user_id).add_columns(User.id, UserProfile.nickname).order_by(User.id.desc()).paginate(1, 10, False)\n    paginate = User.query.join(UserProfile, User.id == UserProfile.user_id).add_entity(UserProfile).order_by(User.id.desc()).paginate(1, 10, False)\n    print paginate.items\n    for (a, b) in paginate.items:\n        print a.id, b.user_id\n\n\nif __name__ == '__main__':\n    # test_user()\n    # test_blog()\n    # test_transaction()\n    # test_label()\n    test_join()\n"
  },
  {
    "path": "app_backend/tools/db_test.py",
    "content": "#!/usr/bin/env python\n# encoding: utf-8\n\n\"\"\"\n@author: zhanghe\n@software: PyCharm\n@file: db_test.py\n@time: 16-3-25 下午11:35\n\"\"\"\n\n\nimport unittest\nfrom app_backend.tools.system import get_memory_usage\nfrom config import BASE_DIR\nimport os\n\n\nclass TestDB(unittest.TestCase):\n    \"\"\"\n    数据库操作测试用例\n    \"\"\"\n    def setUp(self):\n        \"\"\"\n        测试前准备环境的搭建\n        \"\"\"\n        # 备份数据\n        cmd = os.path.join(BASE_DIR, 'etc/db_dump.sh')\n        os.system(cmd)\n        # 准备测试数据\n        cmd = os.path.join(BASE_DIR, 'etc/db_init.sh')\n        os.system(cmd)\n        print\n        pass\n\n    def test_get_row_by_id(self):\n        \"\"\"\n        测试 通过主键获取信息\n        \"\"\"\n        print self.test_get_row_by_id.__doc__.strip()\n        from app.tools.db import get_row_by_id\n        from app.models import User\n        # 测试有记录的场景\n        row = get_row_by_id(User, 1)\n        assert row.id == 1\n        assert row.email == 'admin@gmail.com'\n        assert row.nickname == 'Admin'\n        # 测试无记录的场景\n        row = get_row_by_id(User, 100)\n        assert row is None\n\n    def test_get_rows_by_ids(self):\n        \"\"\"\n        测试 通过主键列表获取信息列表\n        \"\"\"\n        print self.test_get_rows_by_ids.__doc__.strip()\n        from app.tools.db import get_rows_by_ids\n        from app.models import User\n        # # 测试有记录的场景\n        rows = get_rows_by_ids(User, [1, 2, 3])\n        assert len(rows) == 3\n        assert rows[0].id == 1\n        assert rows[0].email == 'admin@gmail.com'\n        assert rows[0].nickname == 'Admin'\n        # 测试无记录的场景\n        rows = get_rows_by_ids(User, [100])\n        assert rows == []\n\n    def test_get_row(self):\n        \"\"\"\n        测试 获取信息\n        \"\"\"\n        print self.test_get_row.__doc__.strip()\n        from app.tools.db import get_row\n        from app.models import User\n        # 测试有记录的场景一\n        row = get_row(User, User.id > 1)\n        assert row.id == 2\n        assert row.email == 'guest@gmail.com'\n        assert row.nickname == 'Guest'\n        # 测试有记录的场景二\n        row = get_row(User, nickname='Guest')\n        assert row.id == 2\n        assert row.email == 'guest@gmail.com'\n        assert row.nickname == 'Guest'\n        # 测试有记录的场景三\n        row = get_row(User, **{'nickname': 'Guest'})\n        assert row.id == 2\n        assert row.email == 'guest@gmail.com'\n        assert row.nickname == 'Guest'\n        # 测试无记录的场景\n        row = get_row(User, User.id == 100)\n        assert row is None\n\n    def test_count(self):\n        \"\"\"\n        测试 计数\n        \"\"\"\n        print self.test_count.__doc__.strip()\n        from app.tools.db import count\n        from app.models import User\n        # 测试带查询条件并结果大于0的场景\n        rows_count = count(User, User.id > 0, User.id < 100)\n        assert rows_count == 3\n        # 测试带查询条件并结果等于0的场景\n        rows_count = count(User, User.id > 100)\n        assert rows_count == 0\n        # 测试无查询条件并结果大于0的场景\n        rows_count = count(User)\n        assert rows_count == 3\n\n    def test_add(self):\n        \"\"\"\n        测试 添加信息\n        \"\"\"\n        print self.test_add.__doc__.strip()\n        from app.tools.db import add\n        from app.models import User\n        # 测试正确的场景\n        user_info = {\n            'email': 'bob@gmail.com',\n            'password': '123456',\n            'nickname': 'Bob',\n        }\n        result = add(User, user_info)\n        assert result == 4\n        # 测试错误的场景\n        user_info = {\n            'email': 'error@gmail.com',\n            'password': '123456',\n            # 'nickname': 'Error',\n        }\n        try:\n            result = add(User, user_info)\n        except Exception as e:\n            assert e.message == '(sqlite3.IntegrityError) NOT NULL constraint failed: user.nickname'\n        assert result == 4\n\n    def tearDown(self):\n        \"\"\"\n        测试后环境的还原\n        \"\"\"\n        # 恢复数据\n        cmd = os.path.join(BASE_DIR, 'etc/db_restore.sh')\n        os.system(cmd)\n        # 获取内存消耗\n        get_memory_usage()\n        pass\n\n\nif __name__ == '__main__':\n    unittest.main()\n\n\n\"\"\"\nTesting started at 上午12:59 ...\n\n测试 添加信息\n[pid:24399]内存使用28.22M\n\n测试 计数\n[pid:24399]内存使用28.63M\n\n测试 获取信息\n[pid:24399]内存使用28.69M\n\n测试 通过主键获取信息\n[pid:24399]内存使用28.69M\n\n测试 通过主键列表获取信息列表\n[pid:24399]内存使用28.72M\n\nProcess finished with exit code 0\n\"\"\""
  },
  {
    "path": "app_backend/tools/decorators.py",
    "content": "#!/usr/bin/env python\n# encoding: utf-8\n\n\"\"\"\n@author: zhanghe\n@software: PyCharm\n@file: decorators.py\n@time: 16-3-11 下午3:08\n\"\"\"\n\n\nfrom threading import Thread\n\n\ndef async(f):\n    \"\"\"\n    基于线程的异步调用装饰器\n    :param f:\n    :return:\n    \"\"\"\n    def wrapper(*args, **kwargs):\n        thr = Thread(target=f, args=args, kwargs=kwargs)\n        thr.start()\n    return wrapper\n"
  },
  {
    "path": "app_backend/tools/file.py",
    "content": "#!/usr/bin/env python\n# encoding: utf-8\n\n\"\"\"\n@author: zhanghe\n@software: PyCharm\n@file: file.py\n@time: 16-3-29 下午2:21\n\"\"\"\n\n\nimport os\nimport glob\n\n\ndef read_files(file_dir='*', suffix='*'):\n    \"\"\"\n    读取目录下指定文件\n    :param file_dir:\n    :param suffix:\n    :return:\n    \"\"\"\n    try:\n        for file_name in glob.glob(r'%s*.%s' % (file_dir, suffix)):\n            if os.path.isfile(file_name):\n                print file_name, os.path.abspath(file_name)\n    except OSError:\n        print u'读取文件失败'\n    except Exception, e:\n        print e.message\n\n\nif __name__ == '__main__':\n    read_files()\n"
  },
  {
    "path": "app_backend/tools/send_sms.py",
    "content": "#!/usr/bin/env python\n# encoding: utf-8\n\n\"\"\"\n@author: zhanghe\n@software: PyCharm\n@file: send_sms.py\n@time: 2017/4/5 下午1:47\n\"\"\"\n\n\nfrom sshtunnel import SSHTunnelForwarder\nfrom sqlalchemy.orm import sessionmaker\nfrom sqlalchemy import create_engine\nfrom app_backend.lib.sms_chuanglan_iso import SmsChuangLanIsoApi\nimport time\nfrom config import current_config\n\nSSH_CONFIG = current_config.SSH_CONFIG\nSMS = current_config.SMS\n\n\n# 隧道配置\nSSH_IP = SSH_CONFIG['IP']\nSSH_PORT = SSH_CONFIG['PORT']\nSSH_USERNAME = SSH_CONFIG['USERNAME']\nSSH_PASSWORD = SSH_CONFIG['PASSWORD']\n\n# DB配置\nDB_MYSQL = SSH_CONFIG['DB_MYSQL']\n\n\n# 短信接口配置\nUN = SMS['UN']           # 创蓝账号\nPW = SMS['PW']           # 创蓝密码\n\n\ndef get_server_tunnel():\n    \"\"\"\n    获取连接隧道\n    :return:\n    \"\"\"\n    server_tunnel = SSHTunnelForwarder(\n        (SSH_IP, SSH_PORT),\n        ssh_password=SSH_PASSWORD,\n        ssh_username=SSH_USERNAME,\n        remote_bind_address=(DB_MYSQL['host'], DB_MYSQL['port']))\n    return server_tunnel\n\n\ndef get_db_session(server_tunnel=None):\n    \"\"\"\n    获取db_session\n    :param server_tunnel:\n    :return:\n    \"\"\"\n    if server_tunnel:\n        local_port = str(server_tunnel.local_bind_port)\n\n        sqlalchemy_database_uri_mysql = \\\n            'mysql+mysqldb://%s:%s@%s:%s/%s?charset=utf8' % \\\n            (DB_MYSQL['user'], DB_MYSQL['passwd'], DB_MYSQL['host'], local_port, DB_MYSQL['db'])\n    else:\n        sqlalchemy_database_uri_mysql = \\\n            'mysql+mysqldb://%s:%s@%s:%s/%s?charset=utf8' % \\\n            (DB_MYSQL['user'], DB_MYSQL['passwd'], DB_MYSQL['host'], DB_MYSQL['port'], DB_MYSQL['db'])\n    engine = create_engine(sqlalchemy_database_uri_mysql)\n\n    # connect to DB\n    DB_Session = sessionmaker(autocommit=True, autoflush=True, bind=engine)\n    session = DB_Session()\n    return session\n\n\ndef run_send_sms(server_tunnel=None):\n    \"\"\"\n    短信发送\n    :return:\n    \"\"\"\n    if server_tunnel and not server_tunnel.is_active:\n        server.start()  # start ssh sever\n        print 'Server reconnected via SSH'\n    session = get_db_session(server_tunnel)\n    print 'Database session created'\n\n    sms_client = SmsChuangLanIsoApi(UN, PW)\n\n    # test data retrieval\n    while 1:\n        sql_fetch = \"SELECT * FROM ot_sms WHERE sent_st=0 limit 100\"\n        sql_edit = 'UPDATE ot_sms SET sent_st=:sent_st WHERE id=:id;'\n        rows = session.execute(sql_fetch).fetchall()\n        for row in rows:\n            # 处理中\n            session.execute(sql_edit, {'id': row['id'], 'sent_st': 1})\n            # 发送信息\n            print time.strftime('%Y-%m-%d %H:%M:%S'), row['mobile'], row['msg']\n\n            result = sms_client.send_international('86%s' % row['mobile'], row['msg'])\n            print result\n            if result['success']:\n                print session.execute(sql_edit, {'id': row['id'], 'sent_st': 2}).rowcount\n            else:\n                print session.execute(sql_edit, {'id': row['id'], 'sent_st': 3}).rowcount\n    # server.stop()  # stop ssh sever\n\n\nif __name__ == '__main__':\n    # 隧道模式\n    server = get_server_tunnel()\n    server.start()\n    run_send_sms(server)\n    server.stop()\n    # 普通模式\n    run_send_sms()\n\n\n\"\"\"\n✗ pip install sshtunnel\n✗ pip install MySQL-python\n✗ pip install schedule\n\"\"\""
  },
  {
    "path": "app_backend/tools/session_manage.py",
    "content": "#!/usr/bin/env python\n# encoding: utf-8\n\n\"\"\"\n@author: zhanghe\n@software: PyCharm\n@file: session_manage.py\n@time: 2017/4/9 上午11:16\n\"\"\"\n\n\nimport redis\nimport json\nfrom config import REDIS\n\n\nredis_client = redis.Redis(**REDIS)\n\n\ndef get_session(session_id):\n    session_key = 'session:%s' % session_id\n    print json.loads(redis_client.get(session_key))\n\n\nif __name__ == '__main__':\n    get_session('f093df3e-5f8b-432a-ab56-99e3975225f4')\n"
  },
  {
    "path": "app_backend/tools/stat.py",
    "content": "#!/usr/bin/env python\n# encoding: utf-8\n\n\"\"\"\n@author: zhanghe\n@software: PyCharm\n@file: stat.py\n@time: 16-2-22 下午11:08\n\"\"\"\n\n\nfrom app_backend.api.blog import get_blog_counter, set_blog_counter, add_blog_stat_item, get_blog_container_status\nfrom app_backend.api.user import add_user_stat_item\n\n# 定义支持的统计类型\nstat_type_list = [\n    'favor',  # 支持数\n    'decry',  # 反对数\n    'follow',  # 关注数\n    'fans',  # 粉丝数\n    'view',  # 点击数\n    'collect',  # 收藏数\n    'flag'  # 举报数\n]\n\n\ndef set_blog_stat(stat_type, uid, item_id, num=1):\n    \"\"\"\n    设置 blog 统计\n    :param stat_type:\n    :param uid:\n    :param item_id:\n    :param num:\n    :return:\n    \"\"\"\n    blog_status = add_blog_stat_item(stat_type, item_id, uid)  # 更新blog容器\n    user_status = add_user_stat_item(stat_type, uid, item_id)  # 更新user容器\n    if blog_status == 1 and user_status == 1:\n        count = set_blog_counter(item_id, stat_type, num)  # 更新计数器\n    else:\n        # 如果已经更新容器，计数器不需更新\n        count = get_blog_counter(item_id)\n    status = get_blog_container_status(item_id, uid)\n    result = {\n        'count': count,\n        'status': status\n    }\n    return result\n\n\nif __name__ == '__main__':\n    pass\n"
  },
  {
    "path": "app_backend/tools/system.py",
    "content": "#!/usr/bin/env python\n# encoding: utf-8\n\n\"\"\"\n@author: zhanghe\n@software: PyCharm\n@file: system.py\n@time: 16-4-17 下午11:59\n\"\"\"\n\n\nimport os\n\n\ndef get_memory_usage():\n    \"\"\"\n    获取当前进程内存使用情况(单位M)\n    \"\"\"\n    # 获取当前脚本的进程ID\n    pid = os.getpid()\n    # 获取当前脚本占用的内存\n    cmd = 'ps -p %s -o rss=' % pid\n    output = os.popen(cmd)\n    result = output.read()\n    if result == '':\n        memory_usage_value = 0\n    else:\n        memory_usage_value = int(result.strip())\n    memory_usage_format = memory_usage_value / 1024.0\n    print '[pid:%s]内存使用%.2fM' % (pid, memory_usage_format)\n\n\nif __name__ == '__main__':\n    get_memory_usage()\n"
  },
  {
    "path": "app_backend/tools/url.py",
    "content": "#!/usr/bin/env python\n# encoding: utf-8\n\n\"\"\"\n@author: zhanghe\n@software: PyCharm\n@file: url.py\n@time: 16-3-25 下午3:19\n\"\"\"\n\n\nfrom urlparse import urlparse\n\n\ndef secure_url(url, netloc='', default_url='/'):\n    \"\"\"\n    获取安全 url\n    不带域名的链接，不需指定 netloc 参数\n    有域名的链接，需要指定 netloc 为授权的域名（不带协议）\n    :param url:\n    :param netloc:\n    :param default_url:\n    :return:\n    \"\"\"\n    parse_result = urlparse(url)\n    if parse_result.netloc in ['', netloc]:\n        return url\n    return default_url\n\n\ndef test():\n    \"\"\"\n    测试获取安全url\n    :return:\n    \"\"\"\n    url = '%2Fblog%2Flist%2F'\n    print secure_url(url)\n\n\nif __name__ == '__main__':\n    test()\n"
  },
  {
    "path": "app_backend/vendor/bootstrap/css/bootstrap.css",
    "content": "/*!\n * Bootstrap v3.3.7 (http://getbootstrap.com)\n * Copyright 2011-2016 Twitter, Inc.\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)\n */\n/*! normalize.css v3.0.3 | MIT License | github.com/necolas/normalize.css */\nhtml {\n  font-family: sans-serif;\n  -webkit-text-size-adjust: 100%;\n      -ms-text-size-adjust: 100%;\n}\nbody {\n  margin: 0;\n}\narticle,\naside,\ndetails,\nfigcaption,\nfigure,\nfooter,\nheader,\nhgroup,\nmain,\nmenu,\nnav,\nsection,\nsummary {\n  display: block;\n}\naudio,\ncanvas,\nprogress,\nvideo {\n  display: inline-block;\n  vertical-align: baseline;\n}\naudio:not([controls]) {\n  display: none;\n  height: 0;\n}\n[hidden],\ntemplate {\n  display: none;\n}\na {\n  background-color: transparent;\n}\na:active,\na:hover {\n  outline: 0;\n}\nabbr[title] {\n  border-bottom: 1px dotted;\n}\nb,\nstrong {\n  font-weight: bold;\n}\ndfn {\n  font-style: italic;\n}\nh1 {\n  margin: .67em 0;\n  font-size: 2em;\n}\nmark {\n  color: #000;\n  background: #ff0;\n}\nsmall {\n  font-size: 80%;\n}\nsub,\nsup {\n  position: relative;\n  font-size: 75%;\n  line-height: 0;\n  vertical-align: baseline;\n}\nsup {\n  top: -.5em;\n}\nsub {\n  bottom: -.25em;\n}\nimg {\n  border: 0;\n}\nsvg:not(:root) {\n  overflow: hidden;\n}\nfigure {\n  margin: 1em 40px;\n}\nhr {\n  height: 0;\n  -webkit-box-sizing: content-box;\n     -moz-box-sizing: content-box;\n          box-sizing: content-box;\n}\npre {\n  overflow: auto;\n}\ncode,\nkbd,\npre,\nsamp {\n  font-family: monospace, monospace;\n  font-size: 1em;\n}\nbutton,\ninput,\noptgroup,\nselect,\ntextarea {\n  margin: 0;\n  font: inherit;\n  color: inherit;\n}\nbutton {\n  overflow: visible;\n}\nbutton,\nselect {\n  text-transform: none;\n}\nbutton,\nhtml input[type=\"button\"],\ninput[type=\"reset\"],\ninput[type=\"submit\"] {\n  -webkit-appearance: button;\n  cursor: pointer;\n}\nbutton[disabled],\nhtml input[disabled] {\n  cursor: default;\n}\nbutton::-moz-focus-inner,\ninput::-moz-focus-inner {\n  padding: 0;\n  border: 0;\n}\ninput {\n  line-height: normal;\n}\ninput[type=\"checkbox\"],\ninput[type=\"radio\"] {\n  -webkit-box-sizing: border-box;\n     -moz-box-sizing: border-box;\n          box-sizing: border-box;\n  padding: 0;\n}\ninput[type=\"number\"]::-webkit-inner-spin-button,\ninput[type=\"number\"]::-webkit-outer-spin-button {\n  height: auto;\n}\ninput[type=\"search\"] {\n  -webkit-box-sizing: content-box;\n     -moz-box-sizing: content-box;\n          box-sizing: content-box;\n  -webkit-appearance: textfield;\n}\ninput[type=\"search\"]::-webkit-search-cancel-button,\ninput[type=\"search\"]::-webkit-search-decoration {\n  -webkit-appearance: none;\n}\nfieldset {\n  padding: .35em .625em .75em;\n  margin: 0 2px;\n  border: 1px solid #c0c0c0;\n}\nlegend {\n  padding: 0;\n  border: 0;\n}\ntextarea {\n  overflow: auto;\n}\noptgroup {\n  font-weight: bold;\n}\ntable {\n  border-spacing: 0;\n  border-collapse: collapse;\n}\ntd,\nth {\n  padding: 0;\n}\n/*! Source: https://github.com/h5bp/html5-boilerplate/blob/master/src/css/main.css */\n@media print {\n  *,\n  *:before,\n  *:after {\n    color: #000 !important;\n    text-shadow: none !important;\n    background: transparent !important;\n    -webkit-box-shadow: none !important;\n            box-shadow: none !important;\n  }\n  a,\n  a:visited {\n    text-decoration: underline;\n  }\n  a[href]:after {\n    content: \" (\" attr(href) \")\";\n  }\n  abbr[title]:after {\n    content: \" (\" attr(title) \")\";\n  }\n  a[href^=\"#\"]:after,\n  a[href^=\"javascript:\"]:after {\n    content: \"\";\n  }\n  pre,\n  blockquote {\n    border: 1px solid #999;\n\n    page-break-inside: avoid;\n  }\n  thead {\n    display: table-header-group;\n  }\n  tr,\n  img {\n    page-break-inside: avoid;\n  }\n  img {\n    max-width: 100% !important;\n  }\n  p,\n  h2,\n  h3 {\n    orphans: 3;\n    widows: 3;\n  }\n  h2,\n  h3 {\n    page-break-after: avoid;\n  }\n  .navbar {\n    display: none;\n  }\n  .btn > .caret,\n  .dropup > .btn > .caret {\n    border-top-color: #000 !important;\n  }\n  .label {\n    border: 1px solid #000;\n  }\n  .table {\n    border-collapse: collapse !important;\n  }\n  .table td,\n  .table th {\n    background-color: #fff !important;\n  }\n  .table-bordered th,\n  .table-bordered td {\n    border: 1px solid #ddd !important;\n  }\n}\n@font-face {\n  font-family: 'Glyphicons Halflings';\n\n  src: url('../fonts/glyphicons-halflings-regular.eot');\n  src: url('../fonts/glyphicons-halflings-regular.eot?#iefix') format('embedded-opentype'), url('../fonts/glyphicons-halflings-regular.woff2') format('woff2'), url('../fonts/glyphicons-halflings-regular.woff') format('woff'), url('../fonts/glyphicons-halflings-regular.ttf') format('truetype'), url('../fonts/glyphicons-halflings-regular.svg#glyphicons_halflingsregular') format('svg');\n}\n.glyphicon {\n  position: relative;\n  top: 1px;\n  display: inline-block;\n  font-family: 'Glyphicons Halflings';\n  font-style: normal;\n  font-weight: normal;\n  line-height: 1;\n\n  -webkit-font-smoothing: antialiased;\n  -moz-osx-font-smoothing: grayscale;\n}\n.glyphicon-asterisk:before {\n  content: \"\\002a\";\n}\n.glyphicon-plus:before {\n  content: \"\\002b\";\n}\n.glyphicon-euro:before,\n.glyphicon-eur:before {\n  content: \"\\20ac\";\n}\n.glyphicon-minus:before {\n  content: \"\\2212\";\n}\n.glyphicon-cloud:before {\n  content: \"\\2601\";\n}\n.glyphicon-envelope:before {\n  content: \"\\2709\";\n}\n.glyphicon-pencil:before {\n  content: \"\\270f\";\n}\n.glyphicon-glass:before {\n  content: \"\\e001\";\n}\n.glyphicon-music:before {\n  content: \"\\e002\";\n}\n.glyphicon-search:before {\n  content: \"\\e003\";\n}\n.glyphicon-heart:before {\n  content: \"\\e005\";\n}\n.glyphicon-star:before {\n  content: \"\\e006\";\n}\n.glyphicon-star-empty:before {\n  content: \"\\e007\";\n}\n.glyphicon-user:before {\n  content: \"\\e008\";\n}\n.glyphicon-film:before {\n  content: \"\\e009\";\n}\n.glyphicon-th-large:before {\n  content: \"\\e010\";\n}\n.glyphicon-th:before {\n  content: \"\\e011\";\n}\n.glyphicon-th-list:before {\n  content: \"\\e012\";\n}\n.glyphicon-ok:before {\n  content: \"\\e013\";\n}\n.glyphicon-remove:before {\n  content: \"\\e014\";\n}\n.glyphicon-zoom-in:before {\n  content: \"\\e015\";\n}\n.glyphicon-zoom-out:before {\n  content: \"\\e016\";\n}\n.glyphicon-off:before {\n  content: \"\\e017\";\n}\n.glyphicon-signal:before {\n  content: \"\\e018\";\n}\n.glyphicon-cog:before {\n  content: \"\\e019\";\n}\n.glyphicon-trash:before {\n  content: \"\\e020\";\n}\n.glyphicon-home:before {\n  content: \"\\e021\";\n}\n.glyphicon-file:before {\n  content: \"\\e022\";\n}\n.glyphicon-time:before {\n  content: \"\\e023\";\n}\n.glyphicon-road:before {\n  content: \"\\e024\";\n}\n.glyphicon-download-alt:before {\n  content: \"\\e025\";\n}\n.glyphicon-download:before {\n  content: \"\\e026\";\n}\n.glyphicon-upload:before {\n  content: \"\\e027\";\n}\n.glyphicon-inbox:before {\n  content: \"\\e028\";\n}\n.glyphicon-play-circle:before {\n  content: \"\\e029\";\n}\n.glyphicon-repeat:before {\n  content: \"\\e030\";\n}\n.glyphicon-refresh:before {\n  content: \"\\e031\";\n}\n.glyphicon-list-alt:before {\n  content: \"\\e032\";\n}\n.glyphicon-lock:before {\n  content: \"\\e033\";\n}\n.glyphicon-flag:before {\n  content: \"\\e034\";\n}\n.glyphicon-headphones:before {\n  content: \"\\e035\";\n}\n.glyphicon-volume-off:before {\n  content: \"\\e036\";\n}\n.glyphicon-volume-down:before {\n  content: \"\\e037\";\n}\n.glyphicon-volume-up:before {\n  content: \"\\e038\";\n}\n.glyphicon-qrcode:before {\n  content: \"\\e039\";\n}\n.glyphicon-barcode:before {\n  content: \"\\e040\";\n}\n.glyphicon-tag:before {\n  content: \"\\e041\";\n}\n.glyphicon-tags:before {\n  content: \"\\e042\";\n}\n.glyphicon-book:before {\n  content: \"\\e043\";\n}\n.glyphicon-bookmark:before {\n  content: \"\\e044\";\n}\n.glyphicon-print:before {\n  content: \"\\e045\";\n}\n.glyphicon-camera:before {\n  content: \"\\e046\";\n}\n.glyphicon-font:before {\n  content: \"\\e047\";\n}\n.glyphicon-bold:before {\n  content: \"\\e048\";\n}\n.glyphicon-italic:before {\n  content: \"\\e049\";\n}\n.glyphicon-text-height:before {\n  content: \"\\e050\";\n}\n.glyphicon-text-width:before {\n  content: \"\\e051\";\n}\n.glyphicon-align-left:before {\n  content: \"\\e052\";\n}\n.glyphicon-align-center:before {\n  content: \"\\e053\";\n}\n.glyphicon-align-right:before {\n  content: \"\\e054\";\n}\n.glyphicon-align-justify:before {\n  content: \"\\e055\";\n}\n.glyphicon-list:before {\n  content: \"\\e056\";\n}\n.glyphicon-indent-left:before {\n  content: \"\\e057\";\n}\n.glyphicon-indent-right:before {\n  content: \"\\e058\";\n}\n.glyphicon-facetime-video:before {\n  content: \"\\e059\";\n}\n.glyphicon-picture:before {\n  content: \"\\e060\";\n}\n.glyphicon-map-marker:before {\n  content: \"\\e062\";\n}\n.glyphicon-adjust:before {\n  content: \"\\e063\";\n}\n.glyphicon-tint:before {\n  content: \"\\e064\";\n}\n.glyphicon-edit:before {\n  content: \"\\e065\";\n}\n.glyphicon-share:before {\n  content: \"\\e066\";\n}\n.glyphicon-check:before {\n  content: \"\\e067\";\n}\n.glyphicon-move:before {\n  content: \"\\e068\";\n}\n.glyphicon-step-backward:before {\n  content: \"\\e069\";\n}\n.glyphicon-fast-backward:before {\n  content: \"\\e070\";\n}\n.glyphicon-backward:before {\n  content: \"\\e071\";\n}\n.glyphicon-play:before {\n  content: \"\\e072\";\n}\n.glyphicon-pause:before {\n  content: \"\\e073\";\n}\n.glyphicon-stop:before {\n  content: \"\\e074\";\n}\n.glyphicon-forward:before {\n  content: \"\\e075\";\n}\n.glyphicon-fast-forward:before {\n  content: \"\\e076\";\n}\n.glyphicon-step-forward:before {\n  content: \"\\e077\";\n}\n.glyphicon-eject:before {\n  content: \"\\e078\";\n}\n.glyphicon-chevron-left:before {\n  content: \"\\e079\";\n}\n.glyphicon-chevron-right:before {\n  content: \"\\e080\";\n}\n.glyphicon-plus-sign:before {\n  content: \"\\e081\";\n}\n.glyphicon-minus-sign:before {\n  content: \"\\e082\";\n}\n.glyphicon-remove-sign:before {\n  content: \"\\e083\";\n}\n.glyphicon-ok-sign:before {\n  content: \"\\e084\";\n}\n.glyphicon-question-sign:before {\n  content: \"\\e085\";\n}\n.glyphicon-info-sign:before {\n  content: \"\\e086\";\n}\n.glyphicon-screenshot:before {\n  content: \"\\e087\";\n}\n.glyphicon-remove-circle:before {\n  content: \"\\e088\";\n}\n.glyphicon-ok-circle:before {\n  content: \"\\e089\";\n}\n.glyphicon-ban-circle:before {\n  content: \"\\e090\";\n}\n.glyphicon-arrow-left:before {\n  content: \"\\e091\";\n}\n.glyphicon-arrow-right:before {\n  content: \"\\e092\";\n}\n.glyphicon-arrow-up:before {\n  content: \"\\e093\";\n}\n.glyphicon-arrow-down:before {\n  content: \"\\e094\";\n}\n.glyphicon-share-alt:before {\n  content: \"\\e095\";\n}\n.glyphicon-resize-full:before {\n  content: \"\\e096\";\n}\n.glyphicon-resize-small:before {\n  content: \"\\e097\";\n}\n.glyphicon-exclamation-sign:before {\n  content: \"\\e101\";\n}\n.glyphicon-gift:before {\n  content: \"\\e102\";\n}\n.glyphicon-leaf:before {\n  content: \"\\e103\";\n}\n.glyphicon-fire:before {\n  content: \"\\e104\";\n}\n.glyphicon-eye-open:before {\n  content: \"\\e105\";\n}\n.glyphicon-eye-close:before {\n  content: \"\\e106\";\n}\n.glyphicon-warning-sign:before {\n  content: \"\\e107\";\n}\n.glyphicon-plane:before {\n  content: \"\\e108\";\n}\n.glyphicon-calendar:before {\n  content: \"\\e109\";\n}\n.glyphicon-random:before {\n  content: \"\\e110\";\n}\n.glyphicon-comment:before {\n  content: \"\\e111\";\n}\n.glyphicon-magnet:before {\n  content: \"\\e112\";\n}\n.glyphicon-chevron-up:before {\n  content: \"\\e113\";\n}\n.glyphicon-chevron-down:before {\n  content: \"\\e114\";\n}\n.glyphicon-retweet:before {\n  content: \"\\e115\";\n}\n.glyphicon-shopping-cart:before {\n  content: \"\\e116\";\n}\n.glyphicon-folder-close:before {\n  content: \"\\e117\";\n}\n.glyphicon-folder-open:before {\n  content: \"\\e118\";\n}\n.glyphicon-resize-vertical:before {\n  content: \"\\e119\";\n}\n.glyphicon-resize-horizontal:before {\n  content: \"\\e120\";\n}\n.glyphicon-hdd:before {\n  content: \"\\e121\";\n}\n.glyphicon-bullhorn:before {\n  content: \"\\e122\";\n}\n.glyphicon-bell:before {\n  content: \"\\e123\";\n}\n.glyphicon-certificate:before {\n  content: \"\\e124\";\n}\n.glyphicon-thumbs-up:before {\n  content: \"\\e125\";\n}\n.glyphicon-thumbs-down:before {\n  content: \"\\e126\";\n}\n.glyphicon-hand-right:before {\n  content: \"\\e127\";\n}\n.glyphicon-hand-left:before {\n  content: \"\\e128\";\n}\n.glyphicon-hand-up:before {\n  content: \"\\e129\";\n}\n.glyphicon-hand-down:before {\n  content: \"\\e130\";\n}\n.glyphicon-circle-arrow-right:before {\n  content: \"\\e131\";\n}\n.glyphicon-circle-arrow-left:before {\n  content: \"\\e132\";\n}\n.glyphicon-circle-arrow-up:before {\n  content: \"\\e133\";\n}\n.glyphicon-circle-arrow-down:before {\n  content: \"\\e134\";\n}\n.glyphicon-globe:before {\n  content: \"\\e135\";\n}\n.glyphicon-wrench:before {\n  content: \"\\e136\";\n}\n.glyphicon-tasks:before {\n  content: \"\\e137\";\n}\n.glyphicon-filter:before {\n  content: \"\\e138\";\n}\n.glyphicon-briefcase:before {\n  content: \"\\e139\";\n}\n.glyphicon-fullscreen:before {\n  content: \"\\e140\";\n}\n.glyphicon-dashboard:before {\n  content: \"\\e141\";\n}\n.glyphicon-paperclip:before {\n  content: \"\\e142\";\n}\n.glyphicon-heart-empty:before {\n  content: \"\\e143\";\n}\n.glyphicon-link:before {\n  content: \"\\e144\";\n}\n.glyphicon-phone:before {\n  content: \"\\e145\";\n}\n.glyphicon-pushpin:before {\n  content: \"\\e146\";\n}\n.glyphicon-usd:before {\n  content: \"\\e148\";\n}\n.glyphicon-gbp:before {\n  content: \"\\e149\";\n}\n.glyphicon-sort:before {\n  content: \"\\e150\";\n}\n.glyphicon-sort-by-alphabet:before {\n  content: \"\\e151\";\n}\n.glyphicon-sort-by-alphabet-alt:before {\n  content: \"\\e152\";\n}\n.glyphicon-sort-by-order:before {\n  content: \"\\e153\";\n}\n.glyphicon-sort-by-order-alt:before {\n  content: \"\\e154\";\n}\n.glyphicon-sort-by-attributes:before {\n  content: \"\\e155\";\n}\n.glyphicon-sort-by-attributes-alt:before {\n  content: \"\\e156\";\n}\n.glyphicon-unchecked:before {\n  content: \"\\e157\";\n}\n.glyphicon-expand:before {\n  content: \"\\e158\";\n}\n.glyphicon-collapse-down:before {\n  content: \"\\e159\";\n}\n.glyphicon-collapse-up:before {\n  content: \"\\e160\";\n}\n.glyphicon-log-in:before {\n  content: \"\\e161\";\n}\n.glyphicon-flash:before {\n  content: \"\\e162\";\n}\n.glyphicon-log-out:before {\n  content: \"\\e163\";\n}\n.glyphicon-new-window:before {\n  content: \"\\e164\";\n}\n.glyphicon-record:before {\n  content: \"\\e165\";\n}\n.glyphicon-save:before {\n  content: \"\\e166\";\n}\n.glyphicon-open:before {\n  content: \"\\e167\";\n}\n.glyphicon-saved:before {\n  content: \"\\e168\";\n}\n.glyphicon-import:before {\n  content: \"\\e169\";\n}\n.glyphicon-export:before {\n  content: \"\\e170\";\n}\n.glyphicon-send:before {\n  content: \"\\e171\";\n}\n.glyphicon-floppy-disk:before {\n  content: \"\\e172\";\n}\n.glyphicon-floppy-saved:before {\n  content: \"\\e173\";\n}\n.glyphicon-floppy-remove:before {\n  content: \"\\e174\";\n}\n.glyphicon-floppy-save:before {\n  content: \"\\e175\";\n}\n.glyphicon-floppy-open:before {\n  content: \"\\e176\";\n}\n.glyphicon-credit-card:before {\n  content: \"\\e177\";\n}\n.glyphicon-transfer:before {\n  content: \"\\e178\";\n}\n.glyphicon-cutlery:before {\n  content: \"\\e179\";\n}\n.glyphicon-header:before {\n  content: \"\\e180\";\n}\n.glyphicon-compressed:before {\n  content: \"\\e181\";\n}\n.glyphicon-earphone:before {\n  content: \"\\e182\";\n}\n.glyphicon-phone-alt:before {\n  content: \"\\e183\";\n}\n.glyphicon-tower:before {\n  content: \"\\e184\";\n}\n.glyphicon-stats:before {\n  content: \"\\e185\";\n}\n.glyphicon-sd-video:before {\n  content: \"\\e186\";\n}\n.glyphicon-hd-video:before {\n  content: \"\\e187\";\n}\n.glyphicon-subtitles:before {\n  content: \"\\e188\";\n}\n.glyphicon-sound-stereo:before {\n  content: \"\\e189\";\n}\n.glyphicon-sound-dolby:before {\n  content: \"\\e190\";\n}\n.glyphicon-sound-5-1:before {\n  content: \"\\e191\";\n}\n.glyphicon-sound-6-1:before {\n  content: \"\\e192\";\n}\n.glyphicon-sound-7-1:before {\n  content: \"\\e193\";\n}\n.glyphicon-copyright-mark:before {\n  content: \"\\e194\";\n}\n.glyphicon-registration-mark:before {\n  content: \"\\e195\";\n}\n.glyphicon-cloud-download:before {\n  content: \"\\e197\";\n}\n.glyphicon-cloud-upload:before {\n  content: \"\\e198\";\n}\n.glyphicon-tree-conifer:before {\n  content: \"\\e199\";\n}\n.glyphicon-tree-deciduous:before {\n  content: \"\\e200\";\n}\n.glyphicon-cd:before {\n  content: \"\\e201\";\n}\n.glyphicon-save-file:before {\n  content: \"\\e202\";\n}\n.glyphicon-open-file:before {\n  content: \"\\e203\";\n}\n.glyphicon-level-up:before {\n  content: \"\\e204\";\n}\n.glyphicon-copy:before {\n  content: \"\\e205\";\n}\n.glyphicon-paste:before {\n  content: \"\\e206\";\n}\n.glyphicon-alert:before {\n  content: \"\\e209\";\n}\n.glyphicon-equalizer:before {\n  content: \"\\e210\";\n}\n.glyphicon-king:before {\n  content: \"\\e211\";\n}\n.glyphicon-queen:before {\n  content: \"\\e212\";\n}\n.glyphicon-pawn:before {\n  content: \"\\e213\";\n}\n.glyphicon-bishop:before {\n  content: \"\\e214\";\n}\n.glyphicon-knight:before {\n  content: \"\\e215\";\n}\n.glyphicon-baby-formula:before {\n  content: \"\\e216\";\n}\n.glyphicon-tent:before {\n  content: \"\\26fa\";\n}\n.glyphicon-blackboard:before {\n  content: \"\\e218\";\n}\n.glyphicon-bed:before {\n  content: \"\\e219\";\n}\n.glyphicon-apple:before {\n  content: \"\\f8ff\";\n}\n.glyphicon-erase:before {\n  content: \"\\e221\";\n}\n.glyphicon-hourglass:before {\n  content: \"\\231b\";\n}\n.glyphicon-lamp:before {\n  content: \"\\e223\";\n}\n.glyphicon-duplicate:before {\n  content: \"\\e224\";\n}\n.glyphicon-piggy-bank:before {\n  content: \"\\e225\";\n}\n.glyphicon-scissors:before {\n  content: \"\\e226\";\n}\n.glyphicon-bitcoin:before {\n  content: \"\\e227\";\n}\n.glyphicon-btc:before {\n  content: \"\\e227\";\n}\n.glyphicon-xbt:before {\n  content: \"\\e227\";\n}\n.glyphicon-yen:before {\n  content: \"\\00a5\";\n}\n.glyphicon-jpy:before {\n  content: \"\\00a5\";\n}\n.glyphicon-ruble:before {\n  content: \"\\20bd\";\n}\n.glyphicon-rub:before {\n  content: \"\\20bd\";\n}\n.glyphicon-scale:before {\n  content: \"\\e230\";\n}\n.glyphicon-ice-lolly:before {\n  content: \"\\e231\";\n}\n.glyphicon-ice-lolly-tasted:before {\n  content: \"\\e232\";\n}\n.glyphicon-education:before {\n  content: \"\\e233\";\n}\n.glyphicon-option-horizontal:before {\n  content: \"\\e234\";\n}\n.glyphicon-option-vertical:before {\n  content: \"\\e235\";\n}\n.glyphicon-menu-hamburger:before {\n  content: \"\\e236\";\n}\n.glyphicon-modal-window:before {\n  content: \"\\e237\";\n}\n.glyphicon-oil:before {\n  content: \"\\e238\";\n}\n.glyphicon-grain:before {\n  content: \"\\e239\";\n}\n.glyphicon-sunglasses:before {\n  content: \"\\e240\";\n}\n.glyphicon-text-size:before {\n  content: \"\\e241\";\n}\n.glyphicon-text-color:before {\n  content: \"\\e242\";\n}\n.glyphicon-text-background:before {\n  content: \"\\e243\";\n}\n.glyphicon-object-align-top:before {\n  content: \"\\e244\";\n}\n.glyphicon-object-align-bottom:before {\n  content: \"\\e245\";\n}\n.glyphicon-object-align-horizontal:before {\n  content: \"\\e246\";\n}\n.glyphicon-object-align-left:before {\n  content: \"\\e247\";\n}\n.glyphicon-object-align-vertical:before {\n  content: \"\\e248\";\n}\n.glyphicon-object-align-right:before {\n  content: \"\\e249\";\n}\n.glyphicon-triangle-right:before {\n  content: \"\\e250\";\n}\n.glyphicon-triangle-left:before {\n  content: \"\\e251\";\n}\n.glyphicon-triangle-bottom:before {\n  content: \"\\e252\";\n}\n.glyphicon-triangle-top:before {\n  content: \"\\e253\";\n}\n.glyphicon-console:before {\n  content: \"\\e254\";\n}\n.glyphicon-superscript:before {\n  content: \"\\e255\";\n}\n.glyphicon-subscript:before {\n  content: \"\\e256\";\n}\n.glyphicon-menu-left:before {\n  content: \"\\e257\";\n}\n.glyphicon-menu-right:before {\n  content: \"\\e258\";\n}\n.glyphicon-menu-down:before {\n  content: \"\\e259\";\n}\n.glyphicon-menu-up:before {\n  content: \"\\e260\";\n}\n* {\n  -webkit-box-sizing: border-box;\n     -moz-box-sizing: border-box;\n          box-sizing: border-box;\n}\n*:before,\n*:after {\n  -webkit-box-sizing: border-box;\n     -moz-box-sizing: border-box;\n          box-sizing: border-box;\n}\nhtml {\n  font-size: 10px;\n\n  -webkit-tap-highlight-color: rgba(0, 0, 0, 0);\n}\nbody {\n  font-family: \"Helvetica Neue\", Helvetica, Arial, sans-serif;\n  font-size: 14px;\n  line-height: 1.42857143;\n  color: #333;\n  background-color: #fff;\n}\ninput,\nbutton,\nselect,\ntextarea {\n  font-family: inherit;\n  font-size: inherit;\n  line-height: inherit;\n}\na {\n  color: #337ab7;\n  text-decoration: none;\n}\na:hover,\na:focus {\n  color: #23527c;\n  text-decoration: underline;\n}\na:focus {\n  outline: 5px auto -webkit-focus-ring-color;\n  outline-offset: -2px;\n}\nfigure {\n  margin: 0;\n}\nimg {\n  vertical-align: middle;\n}\n.img-responsive,\n.thumbnail > img,\n.thumbnail a > img,\n.carousel-inner > .item > img,\n.carousel-inner > .item > a > img {\n  display: block;\n  max-width: 100%;\n  height: auto;\n}\n.img-rounded {\n  border-radius: 6px;\n}\n.img-thumbnail {\n  display: inline-block;\n  max-width: 100%;\n  height: auto;\n  padding: 4px;\n  line-height: 1.42857143;\n  background-color: #fff;\n  border: 1px solid #ddd;\n  border-radius: 4px;\n  -webkit-transition: all .2s ease-in-out;\n       -o-transition: all .2s ease-in-out;\n          transition: all .2s ease-in-out;\n}\n.img-circle {\n  border-radius: 50%;\n}\nhr {\n  margin-top: 20px;\n  margin-bottom: 20px;\n  border: 0;\n  border-top: 1px solid #eee;\n}\n.sr-only {\n  position: absolute;\n  width: 1px;\n  height: 1px;\n  padding: 0;\n  margin: -1px;\n  overflow: hidden;\n  clip: rect(0, 0, 0, 0);\n  border: 0;\n}\n.sr-only-focusable:active,\n.sr-only-focusable:focus {\n  position: static;\n  width: auto;\n  height: auto;\n  margin: 0;\n  overflow: visible;\n  clip: auto;\n}\n[role=\"button\"] {\n  cursor: pointer;\n}\nh1,\nh2,\nh3,\nh4,\nh5,\nh6,\n.h1,\n.h2,\n.h3,\n.h4,\n.h5,\n.h6 {\n  font-family: inherit;\n  font-weight: 500;\n  line-height: 1.1;\n  color: inherit;\n}\nh1 small,\nh2 small,\nh3 small,\nh4 small,\nh5 small,\nh6 small,\n.h1 small,\n.h2 small,\n.h3 small,\n.h4 small,\n.h5 small,\n.h6 small,\nh1 .small,\nh2 .small,\nh3 .small,\nh4 .small,\nh5 .small,\nh6 .small,\n.h1 .small,\n.h2 .small,\n.h3 .small,\n.h4 .small,\n.h5 .small,\n.h6 .small {\n  font-weight: normal;\n  line-height: 1;\n  color: #777;\n}\nh1,\n.h1,\nh2,\n.h2,\nh3,\n.h3 {\n  margin-top: 20px;\n  margin-bottom: 10px;\n}\nh1 small,\n.h1 small,\nh2 small,\n.h2 small,\nh3 small,\n.h3 small,\nh1 .small,\n.h1 .small,\nh2 .small,\n.h2 .small,\nh3 .small,\n.h3 .small {\n  font-size: 65%;\n}\nh4,\n.h4,\nh5,\n.h5,\nh6,\n.h6 {\n  margin-top: 10px;\n  margin-bottom: 10px;\n}\nh4 small,\n.h4 small,\nh5 small,\n.h5 small,\nh6 small,\n.h6 small,\nh4 .small,\n.h4 .small,\nh5 .small,\n.h5 .small,\nh6 .small,\n.h6 .small {\n  font-size: 75%;\n}\nh1,\n.h1 {\n  font-size: 36px;\n}\nh2,\n.h2 {\n  font-size: 30px;\n}\nh3,\n.h3 {\n  font-size: 24px;\n}\nh4,\n.h4 {\n  font-size: 18px;\n}\nh5,\n.h5 {\n  font-size: 14px;\n}\nh6,\n.h6 {\n  font-size: 12px;\n}\np {\n  margin: 0 0 10px;\n}\n.lead {\n  margin-bottom: 20px;\n  font-size: 16px;\n  font-weight: 300;\n  line-height: 1.4;\n}\n@media (min-width: 768px) {\n  .lead {\n    font-size: 21px;\n  }\n}\nsmall,\n.small {\n  font-size: 85%;\n}\nmark,\n.mark {\n  padding: .2em;\n  background-color: #fcf8e3;\n}\n.text-left {\n  text-align: left;\n}\n.text-right {\n  text-align: right;\n}\n.text-center {\n  text-align: center;\n}\n.text-justify {\n  text-align: justify;\n}\n.text-nowrap {\n  white-space: nowrap;\n}\n.text-lowercase {\n  text-transform: lowercase;\n}\n.text-uppercase {\n  text-transform: uppercase;\n}\n.text-capitalize {\n  text-transform: capitalize;\n}\n.text-muted {\n  color: #777;\n}\n.text-primary {\n  color: #337ab7;\n}\na.text-primary:hover,\na.text-primary:focus {\n  color: #286090;\n}\n.text-success {\n  color: #3c763d;\n}\na.text-success:hover,\na.text-success:focus {\n  color: #2b542c;\n}\n.text-info {\n  color: #31708f;\n}\na.text-info:hover,\na.text-info:focus {\n  color: #245269;\n}\n.text-warning {\n  color: #8a6d3b;\n}\na.text-warning:hover,\na.text-warning:focus {\n  color: #66512c;\n}\n.text-danger {\n  color: #a94442;\n}\na.text-danger:hover,\na.text-danger:focus {\n  color: #843534;\n}\n.bg-primary {\n  color: #fff;\n  background-color: #337ab7;\n}\na.bg-primary:hover,\na.bg-primary:focus {\n  background-color: #286090;\n}\n.bg-success {\n  background-color: #dff0d8;\n}\na.bg-success:hover,\na.bg-success:focus {\n  background-color: #c1e2b3;\n}\n.bg-info {\n  background-color: #d9edf7;\n}\na.bg-info:hover,\na.bg-info:focus {\n  background-color: #afd9ee;\n}\n.bg-warning {\n  background-color: #fcf8e3;\n}\na.bg-warning:hover,\na.bg-warning:focus {\n  background-color: #f7ecb5;\n}\n.bg-danger {\n  background-color: #f2dede;\n}\na.bg-danger:hover,\na.bg-danger:focus {\n  background-color: #e4b9b9;\n}\n.page-header {\n  padding-bottom: 9px;\n  margin: 40px 0 20px;\n  border-bottom: 1px solid #eee;\n}\nul,\nol {\n  margin-top: 0;\n  margin-bottom: 10px;\n}\nul ul,\nol ul,\nul ol,\nol ol {\n  margin-bottom: 0;\n}\n.list-unstyled {\n  padding-left: 0;\n  list-style: none;\n}\n.list-inline {\n  padding-left: 0;\n  margin-left: -5px;\n  list-style: none;\n}\n.list-inline > li {\n  display: inline-block;\n  padding-right: 5px;\n  padding-left: 5px;\n}\ndl {\n  margin-top: 0;\n  margin-bottom: 20px;\n}\ndt,\ndd {\n  line-height: 1.42857143;\n}\ndt {\n  font-weight: bold;\n}\ndd {\n  margin-left: 0;\n}\n@media (min-width: 768px) {\n  .dl-horizontal dt {\n    float: left;\n    width: 160px;\n    overflow: hidden;\n    clear: left;\n    text-align: right;\n    text-overflow: ellipsis;\n    white-space: nowrap;\n  }\n  .dl-horizontal dd {\n    margin-left: 180px;\n  }\n}\nabbr[title],\nabbr[data-original-title] {\n  cursor: help;\n  border-bottom: 1px dotted #777;\n}\n.initialism {\n  font-size: 90%;\n  text-transform: uppercase;\n}\nblockquote {\n  padding: 10px 20px;\n  margin: 0 0 20px;\n  font-size: 17.5px;\n  border-left: 5px solid #eee;\n}\nblockquote p:last-child,\nblockquote ul:last-child,\nblockquote ol:last-child {\n  margin-bottom: 0;\n}\nblockquote footer,\nblockquote small,\nblockquote .small {\n  display: block;\n  font-size: 80%;\n  line-height: 1.42857143;\n  color: #777;\n}\nblockquote footer:before,\nblockquote small:before,\nblockquote .small:before {\n  content: '\\2014 \\00A0';\n}\n.blockquote-reverse,\nblockquote.pull-right {\n  padding-right: 15px;\n  padding-left: 0;\n  text-align: right;\n  border-right: 5px solid #eee;\n  border-left: 0;\n}\n.blockquote-reverse footer:before,\nblockquote.pull-right footer:before,\n.blockquote-reverse small:before,\nblockquote.pull-right small:before,\n.blockquote-reverse .small:before,\nblockquote.pull-right .small:before {\n  content: '';\n}\n.blockquote-reverse footer:after,\nblockquote.pull-right footer:after,\n.blockquote-reverse small:after,\nblockquote.pull-right small:after,\n.blockquote-reverse .small:after,\nblockquote.pull-right .small:after {\n  content: '\\00A0 \\2014';\n}\naddress {\n  margin-bottom: 20px;\n  font-style: normal;\n  line-height: 1.42857143;\n}\ncode,\nkbd,\npre,\nsamp {\n  font-family: Menlo, Monaco, Consolas, \"Courier New\", monospace;\n}\ncode {\n  padding: 2px 4px;\n  font-size: 90%;\n  color: #c7254e;\n  background-color: #f9f2f4;\n  border-radius: 4px;\n}\nkbd {\n  padding: 2px 4px;\n  font-size: 90%;\n  color: #fff;\n  background-color: #333;\n  border-radius: 3px;\n  -webkit-box-shadow: inset 0 -1px 0 rgba(0, 0, 0, .25);\n          box-shadow: inset 0 -1px 0 rgba(0, 0, 0, .25);\n}\nkbd kbd {\n  padding: 0;\n  font-size: 100%;\n  font-weight: bold;\n  -webkit-box-shadow: none;\n          box-shadow: none;\n}\npre {\n  display: block;\n  padding: 9.5px;\n  margin: 0 0 10px;\n  font-size: 13px;\n  line-height: 1.42857143;\n  color: #333;\n  word-break: break-all;\n  word-wrap: break-word;\n  background-color: #f5f5f5;\n  border: 1px solid #ccc;\n  border-radius: 4px;\n}\npre code {\n  padding: 0;\n  font-size: inherit;\n  color: inherit;\n  white-space: pre-wrap;\n  background-color: transparent;\n  border-radius: 0;\n}\n.pre-scrollable {\n  max-height: 340px;\n  overflow-y: scroll;\n}\n.container {\n  padding-right: 15px;\n  padding-left: 15px;\n  margin-right: auto;\n  margin-left: auto;\n}\n@media (min-width: 768px) {\n  .container {\n    width: 750px;\n  }\n}\n@media (min-width: 992px) {\n  .container {\n    width: 970px;\n  }\n}\n@media (min-width: 1200px) {\n  .container {\n    width: 1170px;\n  }\n}\n.container-fluid {\n  padding-right: 15px;\n  padding-left: 15px;\n  margin-right: auto;\n  margin-left: auto;\n}\n.row {\n  margin-right: -15px;\n  margin-left: -15px;\n}\n.col-xs-1, .col-sm-1, .col-md-1, .col-lg-1, .col-xs-2, .col-sm-2, .col-md-2, .col-lg-2, .col-xs-3, .col-sm-3, .col-md-3, .col-lg-3, .col-xs-4, .col-sm-4, .col-md-4, .col-lg-4, .col-xs-5, .col-sm-5, .col-md-5, .col-lg-5, .col-xs-6, .col-sm-6, .col-md-6, .col-lg-6, .col-xs-7, .col-sm-7, .col-md-7, .col-lg-7, .col-xs-8, .col-sm-8, .col-md-8, .col-lg-8, .col-xs-9, .col-sm-9, .col-md-9, .col-lg-9, .col-xs-10, .col-sm-10, .col-md-10, .col-lg-10, .col-xs-11, .col-sm-11, .col-md-11, .col-lg-11, .col-xs-12, .col-sm-12, .col-md-12, .col-lg-12 {\n  position: relative;\n  min-height: 1px;\n  padding-right: 15px;\n  padding-left: 15px;\n}\n.col-xs-1, .col-xs-2, .col-xs-3, .col-xs-4, .col-xs-5, .col-xs-6, .col-xs-7, .col-xs-8, .col-xs-9, .col-xs-10, .col-xs-11, .col-xs-12 {\n  float: left;\n}\n.col-xs-12 {\n  width: 100%;\n}\n.col-xs-11 {\n  width: 91.66666667%;\n}\n.col-xs-10 {\n  width: 83.33333333%;\n}\n.col-xs-9 {\n  width: 75%;\n}\n.col-xs-8 {\n  width: 66.66666667%;\n}\n.col-xs-7 {\n  width: 58.33333333%;\n}\n.col-xs-6 {\n  width: 50%;\n}\n.col-xs-5 {\n  width: 41.66666667%;\n}\n.col-xs-4 {\n  width: 33.33333333%;\n}\n.col-xs-3 {\n  width: 25%;\n}\n.col-xs-2 {\n  width: 16.66666667%;\n}\n.col-xs-1 {\n  width: 8.33333333%;\n}\n.col-xs-pull-12 {\n  right: 100%;\n}\n.col-xs-pull-11 {\n  right: 91.66666667%;\n}\n.col-xs-pull-10 {\n  right: 83.33333333%;\n}\n.col-xs-pull-9 {\n  right: 75%;\n}\n.col-xs-pull-8 {\n  right: 66.66666667%;\n}\n.col-xs-pull-7 {\n  right: 58.33333333%;\n}\n.col-xs-pull-6 {\n  right: 50%;\n}\n.col-xs-pull-5 {\n  right: 41.66666667%;\n}\n.col-xs-pull-4 {\n  right: 33.33333333%;\n}\n.col-xs-pull-3 {\n  right: 25%;\n}\n.col-xs-pull-2 {\n  right: 16.66666667%;\n}\n.col-xs-pull-1 {\n  right: 8.33333333%;\n}\n.col-xs-pull-0 {\n  right: auto;\n}\n.col-xs-push-12 {\n  left: 100%;\n}\n.col-xs-push-11 {\n  left: 91.66666667%;\n}\n.col-xs-push-10 {\n  left: 83.33333333%;\n}\n.col-xs-push-9 {\n  left: 75%;\n}\n.col-xs-push-8 {\n  left: 66.66666667%;\n}\n.col-xs-push-7 {\n  left: 58.33333333%;\n}\n.col-xs-push-6 {\n  left: 50%;\n}\n.col-xs-push-5 {\n  left: 41.66666667%;\n}\n.col-xs-push-4 {\n  left: 33.33333333%;\n}\n.col-xs-push-3 {\n  left: 25%;\n}\n.col-xs-push-2 {\n  left: 16.66666667%;\n}\n.col-xs-push-1 {\n  left: 8.33333333%;\n}\n.col-xs-push-0 {\n  left: auto;\n}\n.col-xs-offset-12 {\n  margin-left: 100%;\n}\n.col-xs-offset-11 {\n  margin-left: 91.66666667%;\n}\n.col-xs-offset-10 {\n  margin-left: 83.33333333%;\n}\n.col-xs-offset-9 {\n  margin-left: 75%;\n}\n.col-xs-offset-8 {\n  margin-left: 66.66666667%;\n}\n.col-xs-offset-7 {\n  margin-left: 58.33333333%;\n}\n.col-xs-offset-6 {\n  margin-left: 50%;\n}\n.col-xs-offset-5 {\n  margin-left: 41.66666667%;\n}\n.col-xs-offset-4 {\n  margin-left: 33.33333333%;\n}\n.col-xs-offset-3 {\n  margin-left: 25%;\n}\n.col-xs-offset-2 {\n  margin-left: 16.66666667%;\n}\n.col-xs-offset-1 {\n  margin-left: 8.33333333%;\n}\n.col-xs-offset-0 {\n  margin-left: 0;\n}\n@media (min-width: 768px) {\n  .col-sm-1, .col-sm-2, .col-sm-3, .col-sm-4, .col-sm-5, .col-sm-6, .col-sm-7, .col-sm-8, .col-sm-9, .col-sm-10, .col-sm-11, .col-sm-12 {\n    float: left;\n  }\n  .col-sm-12 {\n    width: 100%;\n  }\n  .col-sm-11 {\n    width: 91.66666667%;\n  }\n  .col-sm-10 {\n    width: 83.33333333%;\n  }\n  .col-sm-9 {\n    width: 75%;\n  }\n  .col-sm-8 {\n    width: 66.66666667%;\n  }\n  .col-sm-7 {\n    width: 58.33333333%;\n  }\n  .col-sm-6 {\n    width: 50%;\n  }\n  .col-sm-5 {\n    width: 41.66666667%;\n  }\n  .col-sm-4 {\n    width: 33.33333333%;\n  }\n  .col-sm-3 {\n    width: 25%;\n  }\n  .col-sm-2 {\n    width: 16.66666667%;\n  }\n  .col-sm-1 {\n    width: 8.33333333%;\n  }\n  .col-sm-pull-12 {\n    right: 100%;\n  }\n  .col-sm-pull-11 {\n    right: 91.66666667%;\n  }\n  .col-sm-pull-10 {\n    right: 83.33333333%;\n  }\n  .col-sm-pull-9 {\n    right: 75%;\n  }\n  .col-sm-pull-8 {\n    right: 66.66666667%;\n  }\n  .col-sm-pull-7 {\n    right: 58.33333333%;\n  }\n  .col-sm-pull-6 {\n    right: 50%;\n  }\n  .col-sm-pull-5 {\n    right: 41.66666667%;\n  }\n  .col-sm-pull-4 {\n    right: 33.33333333%;\n  }\n  .col-sm-pull-3 {\n    right: 25%;\n  }\n  .col-sm-pull-2 {\n    right: 16.66666667%;\n  }\n  .col-sm-pull-1 {\n    right: 8.33333333%;\n  }\n  .col-sm-pull-0 {\n    right: auto;\n  }\n  .col-sm-push-12 {\n    left: 100%;\n  }\n  .col-sm-push-11 {\n    left: 91.66666667%;\n  }\n  .col-sm-push-10 {\n    left: 83.33333333%;\n  }\n  .col-sm-push-9 {\n    left: 75%;\n  }\n  .col-sm-push-8 {\n    left: 66.66666667%;\n  }\n  .col-sm-push-7 {\n    left: 58.33333333%;\n  }\n  .col-sm-push-6 {\n    left: 50%;\n  }\n  .col-sm-push-5 {\n    left: 41.66666667%;\n  }\n  .col-sm-push-4 {\n    left: 33.33333333%;\n  }\n  .col-sm-push-3 {\n    left: 25%;\n  }\n  .col-sm-push-2 {\n    left: 16.66666667%;\n  }\n  .col-sm-push-1 {\n    left: 8.33333333%;\n  }\n  .col-sm-push-0 {\n    left: auto;\n  }\n  .col-sm-offset-12 {\n    margin-left: 100%;\n  }\n  .col-sm-offset-11 {\n    margin-left: 91.66666667%;\n  }\n  .col-sm-offset-10 {\n    margin-left: 83.33333333%;\n  }\n  .col-sm-offset-9 {\n    margin-left: 75%;\n  }\n  .col-sm-offset-8 {\n    margin-left: 66.66666667%;\n  }\n  .col-sm-offset-7 {\n    margin-left: 58.33333333%;\n  }\n  .col-sm-offset-6 {\n    margin-left: 50%;\n  }\n  .col-sm-offset-5 {\n    margin-left: 41.66666667%;\n  }\n  .col-sm-offset-4 {\n    margin-left: 33.33333333%;\n  }\n  .col-sm-offset-3 {\n    margin-left: 25%;\n  }\n  .col-sm-offset-2 {\n    margin-left: 16.66666667%;\n  }\n  .col-sm-offset-1 {\n    margin-left: 8.33333333%;\n  }\n  .col-sm-offset-0 {\n    margin-left: 0;\n  }\n}\n@media (min-width: 992px) {\n  .col-md-1, .col-md-2, .col-md-3, .col-md-4, .col-md-5, .col-md-6, .col-md-7, .col-md-8, .col-md-9, .col-md-10, .col-md-11, .col-md-12 {\n    float: left;\n  }\n  .col-md-12 {\n    width: 100%;\n  }\n  .col-md-11 {\n    width: 91.66666667%;\n  }\n  .col-md-10 {\n    width: 83.33333333%;\n  }\n  .col-md-9 {\n    width: 75%;\n  }\n  .col-md-8 {\n    width: 66.66666667%;\n  }\n  .col-md-7 {\n    width: 58.33333333%;\n  }\n  .col-md-6 {\n    width: 50%;\n  }\n  .col-md-5 {\n    width: 41.66666667%;\n  }\n  .col-md-4 {\n    width: 33.33333333%;\n  }\n  .col-md-3 {\n    width: 25%;\n  }\n  .col-md-2 {\n    width: 16.66666667%;\n  }\n  .col-md-1 {\n    width: 8.33333333%;\n  }\n  .col-md-pull-12 {\n    right: 100%;\n  }\n  .col-md-pull-11 {\n    right: 91.66666667%;\n  }\n  .col-md-pull-10 {\n    right: 83.33333333%;\n  }\n  .col-md-pull-9 {\n    right: 75%;\n  }\n  .col-md-pull-8 {\n    right: 66.66666667%;\n  }\n  .col-md-pull-7 {\n    right: 58.33333333%;\n  }\n  .col-md-pull-6 {\n    right: 50%;\n  }\n  .col-md-pull-5 {\n    right: 41.66666667%;\n  }\n  .col-md-pull-4 {\n    right: 33.33333333%;\n  }\n  .col-md-pull-3 {\n    right: 25%;\n  }\n  .col-md-pull-2 {\n    right: 16.66666667%;\n  }\n  .col-md-pull-1 {\n    right: 8.33333333%;\n  }\n  .col-md-pull-0 {\n    right: auto;\n  }\n  .col-md-push-12 {\n    left: 100%;\n  }\n  .col-md-push-11 {\n    left: 91.66666667%;\n  }\n  .col-md-push-10 {\n    left: 83.33333333%;\n  }\n  .col-md-push-9 {\n    left: 75%;\n  }\n  .col-md-push-8 {\n    left: 66.66666667%;\n  }\n  .col-md-push-7 {\n    left: 58.33333333%;\n  }\n  .col-md-push-6 {\n    left: 50%;\n  }\n  .col-md-push-5 {\n    left: 41.66666667%;\n  }\n  .col-md-push-4 {\n    left: 33.33333333%;\n  }\n  .col-md-push-3 {\n    left: 25%;\n  }\n  .col-md-push-2 {\n    left: 16.66666667%;\n  }\n  .col-md-push-1 {\n    left: 8.33333333%;\n  }\n  .col-md-push-0 {\n    left: auto;\n  }\n  .col-md-offset-12 {\n    margin-left: 100%;\n  }\n  .col-md-offset-11 {\n    margin-left: 91.66666667%;\n  }\n  .col-md-offset-10 {\n    margin-left: 83.33333333%;\n  }\n  .col-md-offset-9 {\n    margin-left: 75%;\n  }\n  .col-md-offset-8 {\n    margin-left: 66.66666667%;\n  }\n  .col-md-offset-7 {\n    margin-left: 58.33333333%;\n  }\n  .col-md-offset-6 {\n    margin-left: 50%;\n  }\n  .col-md-offset-5 {\n    margin-left: 41.66666667%;\n  }\n  .col-md-offset-4 {\n    margin-left: 33.33333333%;\n  }\n  .col-md-offset-3 {\n    margin-left: 25%;\n  }\n  .col-md-offset-2 {\n    margin-left: 16.66666667%;\n  }\n  .col-md-offset-1 {\n    margin-left: 8.33333333%;\n  }\n  .col-md-offset-0 {\n    margin-left: 0;\n  }\n}\n@media (min-width: 1200px) {\n  .col-lg-1, .col-lg-2, .col-lg-3, .col-lg-4, .col-lg-5, .col-lg-6, .col-lg-7, .col-lg-8, .col-lg-9, .col-lg-10, .col-lg-11, .col-lg-12 {\n    float: left;\n  }\n  .col-lg-12 {\n    width: 100%;\n  }\n  .col-lg-11 {\n    width: 91.66666667%;\n  }\n  .col-lg-10 {\n    width: 83.33333333%;\n  }\n  .col-lg-9 {\n    width: 75%;\n  }\n  .col-lg-8 {\n    width: 66.66666667%;\n  }\n  .col-lg-7 {\n    width: 58.33333333%;\n  }\n  .col-lg-6 {\n    width: 50%;\n  }\n  .col-lg-5 {\n    width: 41.66666667%;\n  }\n  .col-lg-4 {\n    width: 33.33333333%;\n  }\n  .col-lg-3 {\n    width: 25%;\n  }\n  .col-lg-2 {\n    width: 16.66666667%;\n  }\n  .col-lg-1 {\n    width: 8.33333333%;\n  }\n  .col-lg-pull-12 {\n    right: 100%;\n  }\n  .col-lg-pull-11 {\n    right: 91.66666667%;\n  }\n  .col-lg-pull-10 {\n    right: 83.33333333%;\n  }\n  .col-lg-pull-9 {\n    right: 75%;\n  }\n  .col-lg-pull-8 {\n    right: 66.66666667%;\n  }\n  .col-lg-pull-7 {\n    right: 58.33333333%;\n  }\n  .col-lg-pull-6 {\n    right: 50%;\n  }\n  .col-lg-pull-5 {\n    right: 41.66666667%;\n  }\n  .col-lg-pull-4 {\n    right: 33.33333333%;\n  }\n  .col-lg-pull-3 {\n    right: 25%;\n  }\n  .col-lg-pull-2 {\n    right: 16.66666667%;\n  }\n  .col-lg-pull-1 {\n    right: 8.33333333%;\n  }\n  .col-lg-pull-0 {\n    right: auto;\n  }\n  .col-lg-push-12 {\n    left: 100%;\n  }\n  .col-lg-push-11 {\n    left: 91.66666667%;\n  }\n  .col-lg-push-10 {\n    left: 83.33333333%;\n  }\n  .col-lg-push-9 {\n    left: 75%;\n  }\n  .col-lg-push-8 {\n    left: 66.66666667%;\n  }\n  .col-lg-push-7 {\n    left: 58.33333333%;\n  }\n  .col-lg-push-6 {\n    left: 50%;\n  }\n  .col-lg-push-5 {\n    left: 41.66666667%;\n  }\n  .col-lg-push-4 {\n    left: 33.33333333%;\n  }\n  .col-lg-push-3 {\n    left: 25%;\n  }\n  .col-lg-push-2 {\n    left: 16.66666667%;\n  }\n  .col-lg-push-1 {\n    left: 8.33333333%;\n  }\n  .col-lg-push-0 {\n    left: auto;\n  }\n  .col-lg-offset-12 {\n    margin-left: 100%;\n  }\n  .col-lg-offset-11 {\n    margin-left: 91.66666667%;\n  }\n  .col-lg-offset-10 {\n    margin-left: 83.33333333%;\n  }\n  .col-lg-offset-9 {\n    margin-left: 75%;\n  }\n  .col-lg-offset-8 {\n    margin-left: 66.66666667%;\n  }\n  .col-lg-offset-7 {\n    margin-left: 58.33333333%;\n  }\n  .col-lg-offset-6 {\n    margin-left: 50%;\n  }\n  .col-lg-offset-5 {\n    margin-left: 41.66666667%;\n  }\n  .col-lg-offset-4 {\n    margin-left: 33.33333333%;\n  }\n  .col-lg-offset-3 {\n    margin-left: 25%;\n  }\n  .col-lg-offset-2 {\n    margin-left: 16.66666667%;\n  }\n  .col-lg-offset-1 {\n    margin-left: 8.33333333%;\n  }\n  .col-lg-offset-0 {\n    margin-left: 0;\n  }\n}\ntable {\n  background-color: transparent;\n}\ncaption {\n  padding-top: 8px;\n  padding-bottom: 8px;\n  color: #777;\n  text-align: left;\n}\nth {\n  text-align: left;\n}\n.table {\n  width: 100%;\n  max-width: 100%;\n  margin-bottom: 20px;\n}\n.table > thead > tr > th,\n.table > tbody > tr > th,\n.table > tfoot > tr > th,\n.table > thead > tr > td,\n.table > tbody > tr > td,\n.table > tfoot > tr > td {\n  padding: 8px;\n  line-height: 1.42857143;\n  vertical-align: top;\n  border-top: 1px solid #ddd;\n}\n.table > thead > tr > th {\n  vertical-align: bottom;\n  border-bottom: 2px solid #ddd;\n}\n.table > caption + thead > tr:first-child > th,\n.table > colgroup + thead > tr:first-child > th,\n.table > thead:first-child > tr:first-child > th,\n.table > caption + thead > tr:first-child > td,\n.table > colgroup + thead > tr:first-child > td,\n.table > thead:first-child > tr:first-child > td {\n  border-top: 0;\n}\n.table > tbody + tbody {\n  border-top: 2px solid #ddd;\n}\n.table .table {\n  background-color: #fff;\n}\n.table-condensed > thead > tr > th,\n.table-condensed > tbody > tr > th,\n.table-condensed > tfoot > tr > th,\n.table-condensed > thead > tr > td,\n.table-condensed > tbody > tr > td,\n.table-condensed > tfoot > tr > td {\n  padding: 5px;\n}\n.table-bordered {\n  border: 1px solid #ddd;\n}\n.table-bordered > thead > tr > th,\n.table-bordered > tbody > tr > th,\n.table-bordered > tfoot > tr > th,\n.table-bordered > thead > tr > td,\n.table-bordered > tbody > tr > td,\n.table-bordered > tfoot > tr > td {\n  border: 1px solid #ddd;\n}\n.table-bordered > thead > tr > th,\n.table-bordered > thead > tr > td {\n  border-bottom-width: 2px;\n}\n.table-striped > tbody > tr:nth-of-type(odd) {\n  background-color: #f9f9f9;\n}\n.table-hover > tbody > tr:hover {\n  background-color: #f5f5f5;\n}\ntable col[class*=\"col-\"] {\n  position: static;\n  display: table-column;\n  float: none;\n}\ntable td[class*=\"col-\"],\ntable th[class*=\"col-\"] {\n  position: static;\n  display: table-cell;\n  float: none;\n}\n.table > thead > tr > td.active,\n.table > tbody > tr > td.active,\n.table > tfoot > tr > td.active,\n.table > thead > tr > th.active,\n.table > tbody > tr > th.active,\n.table > tfoot > tr > th.active,\n.table > thead > tr.active > td,\n.table > tbody > tr.active > td,\n.table > tfoot > tr.active > td,\n.table > thead > tr.active > th,\n.table > tbody > tr.active > th,\n.table > tfoot > tr.active > th {\n  background-color: #f5f5f5;\n}\n.table-hover > tbody > tr > td.active:hover,\n.table-hover > tbody > tr > th.active:hover,\n.table-hover > tbody > tr.active:hover > td,\n.table-hover > tbody > tr:hover > .active,\n.table-hover > tbody > tr.active:hover > th {\n  background-color: #e8e8e8;\n}\n.table > thead > tr > td.success,\n.table > tbody > tr > td.success,\n.table > tfoot > tr > td.success,\n.table > thead > tr > th.success,\n.table > tbody > tr > th.success,\n.table > tfoot > tr > th.success,\n.table > thead > tr.success > td,\n.table > tbody > tr.success > td,\n.table > tfoot > tr.success > td,\n.table > thead > tr.success > th,\n.table > tbody > tr.success > th,\n.table > tfoot > tr.success > th {\n  background-color: #dff0d8;\n}\n.table-hover > tbody > tr > td.success:hover,\n.table-hover > tbody > tr > th.success:hover,\n.table-hover > tbody > tr.success:hover > td,\n.table-hover > tbody > tr:hover > .success,\n.table-hover > tbody > tr.success:hover > th {\n  background-color: #d0e9c6;\n}\n.table > thead > tr > td.info,\n.table > tbody > tr > td.info,\n.table > tfoot > tr > td.info,\n.table > thead > tr > th.info,\n.table > tbody > tr > th.info,\n.table > tfoot > tr > th.info,\n.table > thead > tr.info > td,\n.table > tbody > tr.info > td,\n.table > tfoot > tr.info > td,\n.table > thead > tr.info > th,\n.table > tbody > tr.info > th,\n.table > tfoot > tr.info > th {\n  background-color: #d9edf7;\n}\n.table-hover > tbody > tr > td.info:hover,\n.table-hover > tbody > tr > th.info:hover,\n.table-hover > tbody > tr.info:hover > td,\n.table-hover > tbody > tr:hover > .info,\n.table-hover > tbody > tr.info:hover > th {\n  background-color: #c4e3f3;\n}\n.table > thead > tr > td.warning,\n.table > tbody > tr > td.warning,\n.table > tfoot > tr > td.warning,\n.table > thead > tr > th.warning,\n.table > tbody > tr > th.warning,\n.table > tfoot > tr > th.warning,\n.table > thead > tr.warning > td,\n.table > tbody > tr.warning > td,\n.table > tfoot > tr.warning > td,\n.table > thead > tr.warning > th,\n.table > tbody > tr.warning > th,\n.table > tfoot > tr.warning > th {\n  background-color: #fcf8e3;\n}\n.table-hover > tbody > tr > td.warning:hover,\n.table-hover > tbody > tr > th.warning:hover,\n.table-hover > tbody > tr.warning:hover > td,\n.table-hover > tbody > tr:hover > .warning,\n.table-hover > tbody > tr.warning:hover > th {\n  background-color: #faf2cc;\n}\n.table > thead > tr > td.danger,\n.table > tbody > tr > td.danger,\n.table > tfoot > tr > td.danger,\n.table > thead > tr > th.danger,\n.table > tbody > tr > th.danger,\n.table > tfoot > tr > th.danger,\n.table > thead > tr.danger > td,\n.table > tbody > tr.danger > td,\n.table > tfoot > tr.danger > td,\n.table > thead > tr.danger > th,\n.table > tbody > tr.danger > th,\n.table > tfoot > tr.danger > th {\n  background-color: #f2dede;\n}\n.table-hover > tbody > tr > td.danger:hover,\n.table-hover > tbody > tr > th.danger:hover,\n.table-hover > tbody > tr.danger:hover > td,\n.table-hover > tbody > tr:hover > .danger,\n.table-hover > tbody > tr.danger:hover > th {\n  background-color: #ebcccc;\n}\n.table-responsive {\n  min-height: .01%;\n  overflow-x: auto;\n}\n@media screen and (max-width: 767px) {\n  .table-responsive {\n    width: 100%;\n    margin-bottom: 15px;\n    overflow-y: hidden;\n    -ms-overflow-style: -ms-autohiding-scrollbar;\n    border: 1px solid #ddd;\n  }\n  .table-responsive > .table {\n    margin-bottom: 0;\n  }\n  .table-responsive > .table > thead > tr > th,\n  .table-responsive > .table > tbody > tr > th,\n  .table-responsive > .table > tfoot > tr > th,\n  .table-responsive > .table > thead > tr > td,\n  .table-responsive > .table > tbody > tr > td,\n  .table-responsive > .table > tfoot > tr > td {\n    white-space: nowrap;\n  }\n  .table-responsive > .table-bordered {\n    border: 0;\n  }\n  .table-responsive > .table-bordered > thead > tr > th:first-child,\n  .table-responsive > .table-bordered > tbody > tr > th:first-child,\n  .table-responsive > .table-bordered > tfoot > tr > th:first-child,\n  .table-responsive > .table-bordered > thead > tr > td:first-child,\n  .table-responsive > .table-bordered > tbody > tr > td:first-child,\n  .table-responsive > .table-bordered > tfoot > tr > td:first-child {\n    border-left: 0;\n  }\n  .table-responsive > .table-bordered > thead > tr > th:last-child,\n  .table-responsive > .table-bordered > tbody > tr > th:last-child,\n  .table-responsive > .table-bordered > tfoot > tr > th:last-child,\n  .table-responsive > .table-bordered > thead > tr > td:last-child,\n  .table-responsive > .table-bordered > tbody > tr > td:last-child,\n  .table-responsive > .table-bordered > tfoot > tr > td:last-child {\n    border-right: 0;\n  }\n  .table-responsive > .table-bordered > tbody > tr:last-child > th,\n  .table-responsive > .table-bordered > tfoot > tr:last-child > th,\n  .table-responsive > .table-bordered > tbody > tr:last-child > td,\n  .table-responsive > .table-bordered > tfoot > tr:last-child > td {\n    border-bottom: 0;\n  }\n}\nfieldset {\n  min-width: 0;\n  padding: 0;\n  margin: 0;\n  border: 0;\n}\nlegend {\n  display: block;\n  width: 100%;\n  padding: 0;\n  margin-bottom: 20px;\n  font-size: 21px;\n  line-height: inherit;\n  color: #333;\n  border: 0;\n  border-bottom: 1px solid #e5e5e5;\n}\nlabel {\n  display: inline-block;\n  max-width: 100%;\n  margin-bottom: 5px;\n  font-weight: bold;\n}\ninput[type=\"search\"] {\n  -webkit-box-sizing: border-box;\n     -moz-box-sizing: border-box;\n          box-sizing: border-box;\n}\ninput[type=\"radio\"],\ninput[type=\"checkbox\"] {\n  margin: 4px 0 0;\n  margin-top: 1px \\9;\n  line-height: normal;\n}\ninput[type=\"file\"] {\n  display: block;\n}\ninput[type=\"range\"] {\n  display: block;\n  width: 100%;\n}\nselect[multiple],\nselect[size] {\n  height: auto;\n}\ninput[type=\"file\"]:focus,\ninput[type=\"radio\"]:focus,\ninput[type=\"checkbox\"]:focus {\n  outline: 5px auto -webkit-focus-ring-color;\n  outline-offset: -2px;\n}\noutput {\n  display: block;\n  padding-top: 7px;\n  font-size: 14px;\n  line-height: 1.42857143;\n  color: #555;\n}\n.form-control {\n  display: block;\n  width: 100%;\n  height: 34px;\n  padding: 6px 12px;\n  font-size: 14px;\n  line-height: 1.42857143;\n  color: #555;\n  background-color: #fff;\n  background-image: none;\n  border: 1px solid #ccc;\n  border-radius: 4px;\n  -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075);\n          box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075);\n  -webkit-transition: border-color ease-in-out .15s, -webkit-box-shadow ease-in-out .15s;\n       -o-transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s;\n          transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s;\n}\n.form-control:focus {\n  border-color: #66afe9;\n  outline: 0;\n  -webkit-box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(102, 175, 233, .6);\n          box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(102, 175, 233, .6);\n}\n.form-control::-moz-placeholder {\n  color: #999;\n  opacity: 1;\n}\n.form-control:-ms-input-placeholder {\n  color: #999;\n}\n.form-control::-webkit-input-placeholder {\n  color: #999;\n}\n.form-control::-ms-expand {\n  background-color: transparent;\n  border: 0;\n}\n.form-control[disabled],\n.form-control[readonly],\nfieldset[disabled] .form-control {\n  background-color: #eee;\n  opacity: 1;\n}\n.form-control[disabled],\nfieldset[disabled] .form-control {\n  cursor: not-allowed;\n}\ntextarea.form-control {\n  height: auto;\n}\ninput[type=\"search\"] {\n  -webkit-appearance: none;\n}\n@media screen and (-webkit-min-device-pixel-ratio: 0) {\n  input[type=\"date\"].form-control,\n  input[type=\"time\"].form-control,\n  input[type=\"datetime-local\"].form-control,\n  input[type=\"month\"].form-control {\n    line-height: 34px;\n  }\n  input[type=\"date\"].input-sm,\n  input[type=\"time\"].input-sm,\n  input[type=\"datetime-local\"].input-sm,\n  input[type=\"month\"].input-sm,\n  .input-group-sm input[type=\"date\"],\n  .input-group-sm input[type=\"time\"],\n  .input-group-sm input[type=\"datetime-local\"],\n  .input-group-sm input[type=\"month\"] {\n    line-height: 30px;\n  }\n  input[type=\"date\"].input-lg,\n  input[type=\"time\"].input-lg,\n  input[type=\"datetime-local\"].input-lg,\n  input[type=\"month\"].input-lg,\n  .input-group-lg input[type=\"date\"],\n  .input-group-lg input[type=\"time\"],\n  .input-group-lg input[type=\"datetime-local\"],\n  .input-group-lg input[type=\"month\"] {\n    line-height: 46px;\n  }\n}\n.form-group {\n  margin-bottom: 15px;\n}\n.radio,\n.checkbox {\n  position: relative;\n  display: block;\n  margin-top: 10px;\n  margin-bottom: 10px;\n}\n.radio label,\n.checkbox label {\n  min-height: 20px;\n  padding-left: 20px;\n  margin-bottom: 0;\n  font-weight: normal;\n  cursor: pointer;\n}\n.radio input[type=\"radio\"],\n.radio-inline input[type=\"radio\"],\n.checkbox input[type=\"checkbox\"],\n.checkbox-inline input[type=\"checkbox\"] {\n  position: absolute;\n  margin-top: 4px \\9;\n  margin-left: -20px;\n}\n.radio + .radio,\n.checkbox + .checkbox {\n  margin-top: -5px;\n}\n.radio-inline,\n.checkbox-inline {\n  position: relative;\n  display: inline-block;\n  padding-left: 20px;\n  margin-bottom: 0;\n  font-weight: normal;\n  vertical-align: middle;\n  cursor: pointer;\n}\n.radio-inline + .radio-inline,\n.checkbox-inline + .checkbox-inline {\n  margin-top: 0;\n  margin-left: 10px;\n}\ninput[type=\"radio\"][disabled],\ninput[type=\"checkbox\"][disabled],\ninput[type=\"radio\"].disabled,\ninput[type=\"checkbox\"].disabled,\nfieldset[disabled] input[type=\"radio\"],\nfieldset[disabled] input[type=\"checkbox\"] {\n  cursor: not-allowed;\n}\n.radio-inline.disabled,\n.checkbox-inline.disabled,\nfieldset[disabled] .radio-inline,\nfieldset[disabled] .checkbox-inline {\n  cursor: not-allowed;\n}\n.radio.disabled label,\n.checkbox.disabled label,\nfieldset[disabled] .radio label,\nfieldset[disabled] .checkbox label {\n  cursor: not-allowed;\n}\n.form-control-static {\n  min-height: 34px;\n  padding-top: 7px;\n  padding-bottom: 7px;\n  margin-bottom: 0;\n}\n.form-control-static.input-lg,\n.form-control-static.input-sm {\n  padding-right: 0;\n  padding-left: 0;\n}\n.input-sm {\n  height: 30px;\n  padding: 5px 10px;\n  font-size: 12px;\n  line-height: 1.5;\n  border-radius: 3px;\n}\nselect.input-sm {\n  height: 30px;\n  line-height: 30px;\n}\ntextarea.input-sm,\nselect[multiple].input-sm {\n  height: auto;\n}\n.form-group-sm .form-control {\n  height: 30px;\n  padding: 5px 10px;\n  font-size: 12px;\n  line-height: 1.5;\n  border-radius: 3px;\n}\n.form-group-sm select.form-control {\n  height: 30px;\n  line-height: 30px;\n}\n.form-group-sm textarea.form-control,\n.form-group-sm select[multiple].form-control {\n  height: auto;\n}\n.form-group-sm .form-control-static {\n  height: 30px;\n  min-height: 32px;\n  padding: 6px 10px;\n  font-size: 12px;\n  line-height: 1.5;\n}\n.input-lg {\n  height: 46px;\n  padding: 10px 16px;\n  font-size: 18px;\n  line-height: 1.3333333;\n  border-radius: 6px;\n}\nselect.input-lg {\n  height: 46px;\n  line-height: 46px;\n}\ntextarea.input-lg,\nselect[multiple].input-lg {\n  height: auto;\n}\n.form-group-lg .form-control {\n  height: 46px;\n  padding: 10px 16px;\n  font-size: 18px;\n  line-height: 1.3333333;\n  border-radius: 6px;\n}\n.form-group-lg select.form-control {\n  height: 46px;\n  line-height: 46px;\n}\n.form-group-lg textarea.form-control,\n.form-group-lg select[multiple].form-control {\n  height: auto;\n}\n.form-group-lg .form-control-static {\n  height: 46px;\n  min-height: 38px;\n  padding: 11px 16px;\n  font-size: 18px;\n  line-height: 1.3333333;\n}\n.has-feedback {\n  position: relative;\n}\n.has-feedback .form-control {\n  padding-right: 42.5px;\n}\n.form-control-feedback {\n  position: absolute;\n  top: 0;\n  right: 0;\n  z-index: 2;\n  display: block;\n  width: 34px;\n  height: 34px;\n  line-height: 34px;\n  text-align: center;\n  pointer-events: none;\n}\n.input-lg + .form-control-feedback,\n.input-group-lg + .form-control-feedback,\n.form-group-lg .form-control + .form-control-feedback {\n  width: 46px;\n  height: 46px;\n  line-height: 46px;\n}\n.input-sm + .form-control-feedback,\n.input-group-sm + .form-control-feedback,\n.form-group-sm .form-control + .form-control-feedback {\n  width: 30px;\n  height: 30px;\n  line-height: 30px;\n}\n.has-success .help-block,\n.has-success .control-label,\n.has-success .radio,\n.has-success .checkbox,\n.has-success .radio-inline,\n.has-success .checkbox-inline,\n.has-success.radio label,\n.has-success.checkbox label,\n.has-success.radio-inline label,\n.has-success.checkbox-inline label {\n  color: #3c763d;\n}\n.has-success .form-control {\n  border-color: #3c763d;\n  -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075);\n          box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075);\n}\n.has-success .form-control:focus {\n  border-color: #2b542c;\n  -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 6px #67b168;\n          box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 6px #67b168;\n}\n.has-success .input-group-addon {\n  color: #3c763d;\n  background-color: #dff0d8;\n  border-color: #3c763d;\n}\n.has-success .form-control-feedback {\n  color: #3c763d;\n}\n.has-warning .help-block,\n.has-warning .control-label,\n.has-warning .radio,\n.has-warning .checkbox,\n.has-warning .radio-inline,\n.has-warning .checkbox-inline,\n.has-warning.radio label,\n.has-warning.checkbox label,\n.has-warning.radio-inline label,\n.has-warning.checkbox-inline label {\n  color: #8a6d3b;\n}\n.has-warning .form-control {\n  border-color: #8a6d3b;\n  -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075);\n          box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075);\n}\n.has-warning .form-control:focus {\n  border-color: #66512c;\n  -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 6px #c0a16b;\n          box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 6px #c0a16b;\n}\n.has-warning .input-group-addon {\n  color: #8a6d3b;\n  background-color: #fcf8e3;\n  border-color: #8a6d3b;\n}\n.has-warning .form-control-feedback {\n  color: #8a6d3b;\n}\n.has-error .help-block,\n.has-error .control-label,\n.has-error .radio,\n.has-error .checkbox,\n.has-error .radio-inline,\n.has-error .checkbox-inline,\n.has-error.radio label,\n.has-error.checkbox label,\n.has-error.radio-inline label,\n.has-error.checkbox-inline label {\n  color: #a94442;\n}\n.has-error .form-control {\n  border-color: #a94442;\n  -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075);\n          box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075);\n}\n.has-error .form-control:focus {\n  border-color: #843534;\n  -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 6px #ce8483;\n          box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 6px #ce8483;\n}\n.has-error .input-group-addon {\n  color: #a94442;\n  background-color: #f2dede;\n  border-color: #a94442;\n}\n.has-error .form-control-feedback {\n  color: #a94442;\n}\n.has-feedback label ~ .form-control-feedback {\n  top: 25px;\n}\n.has-feedback label.sr-only ~ .form-control-feedback {\n  top: 0;\n}\n.help-block {\n  display: block;\n  margin-top: 5px;\n  margin-bottom: 10px;\n  color: #737373;\n}\n@media (min-width: 768px) {\n  .form-inline .form-group {\n    display: inline-block;\n    margin-bottom: 0;\n    vertical-align: middle;\n  }\n  .form-inline .form-control {\n    display: inline-block;\n    width: auto;\n    vertical-align: middle;\n  }\n  .form-inline .form-control-static {\n    display: inline-block;\n  }\n  .form-inline .input-group {\n    display: inline-table;\n    vertical-align: middle;\n  }\n  .form-inline .input-group .input-group-addon,\n  .form-inline .input-group .input-group-btn,\n  .form-inline .input-group .form-control {\n    width: auto;\n  }\n  .form-inline .input-group > .form-control {\n    width: 100%;\n  }\n  .form-inline .control-label {\n    margin-bottom: 0;\n    vertical-align: middle;\n  }\n  .form-inline .radio,\n  .form-inline .checkbox {\n    display: inline-block;\n    margin-top: 0;\n    margin-bottom: 0;\n    vertical-align: middle;\n  }\n  .form-inline .radio label,\n  .form-inline .checkbox label {\n    padding-left: 0;\n  }\n  .form-inline .radio input[type=\"radio\"],\n  .form-inline .checkbox input[type=\"checkbox\"] {\n    position: relative;\n    margin-left: 0;\n  }\n  .form-inline .has-feedback .form-control-feedback {\n    top: 0;\n  }\n}\n.form-horizontal .radio,\n.form-horizontal .checkbox,\n.form-horizontal .radio-inline,\n.form-horizontal .checkbox-inline {\n  padding-top: 7px;\n  margin-top: 0;\n  margin-bottom: 0;\n}\n.form-horizontal .radio,\n.form-horizontal .checkbox {\n  min-height: 27px;\n}\n.form-horizontal .form-group {\n  margin-right: -15px;\n  margin-left: -15px;\n}\n@media (min-width: 768px) {\n  .form-horizontal .control-label {\n    padding-top: 7px;\n    margin-bottom: 0;\n    text-align: right;\n  }\n}\n.form-horizontal .has-feedback .form-control-feedback {\n  right: 15px;\n}\n@media (min-width: 768px) {\n  .form-horizontal .form-group-lg .control-label {\n    padding-top: 11px;\n    font-size: 18px;\n  }\n}\n@media (min-width: 768px) {\n  .form-horizontal .form-group-sm .control-label {\n    padding-top: 6px;\n    font-size: 12px;\n  }\n}\n.btn {\n  display: inline-block;\n  padding: 6px 12px;\n  margin-bottom: 0;\n  font-size: 14px;\n  font-weight: normal;\n  line-height: 1.42857143;\n  text-align: center;\n  white-space: nowrap;\n  vertical-align: middle;\n  -ms-touch-action: manipulation;\n      touch-action: manipulation;\n  cursor: pointer;\n  -webkit-user-select: none;\n     -moz-user-select: none;\n      -ms-user-select: none;\n          user-select: none;\n  background-image: none;\n  border: 1px solid transparent;\n  border-radius: 4px;\n}\n.btn:focus,\n.btn:active:focus,\n.btn.active:focus,\n.btn.focus,\n.btn:active.focus,\n.btn.active.focus {\n  outline: 5px auto -webkit-focus-ring-color;\n  outline-offset: -2px;\n}\n.btn:hover,\n.btn:focus,\n.btn.focus {\n  color: #333;\n  text-decoration: none;\n}\n.btn:active,\n.btn.active {\n  background-image: none;\n  outline: 0;\n  -webkit-box-shadow: inset 0 3px 5px rgba(0, 0, 0, .125);\n          box-shadow: inset 0 3px 5px rgba(0, 0, 0, .125);\n}\n.btn.disabled,\n.btn[disabled],\nfieldset[disabled] .btn {\n  cursor: not-allowed;\n  filter: alpha(opacity=65);\n  -webkit-box-shadow: none;\n          box-shadow: none;\n  opacity: .65;\n}\na.btn.disabled,\nfieldset[disabled] a.btn {\n  pointer-events: none;\n}\n.btn-default {\n  color: #333;\n  background-color: #fff;\n  border-color: #ccc;\n}\n.btn-default:focus,\n.btn-default.focus {\n  color: #333;\n  background-color: #e6e6e6;\n  border-color: #8c8c8c;\n}\n.btn-default:hover {\n  color: #333;\n  background-color: #e6e6e6;\n  border-color: #adadad;\n}\n.btn-default:active,\n.btn-default.active,\n.open > .dropdown-toggle.btn-default {\n  color: #333;\n  background-color: #e6e6e6;\n  border-color: #adadad;\n}\n.btn-default:active:hover,\n.btn-default.active:hover,\n.open > .dropdown-toggle.btn-default:hover,\n.btn-default:active:focus,\n.btn-default.active:focus,\n.open > .dropdown-toggle.btn-default:focus,\n.btn-default:active.focus,\n.btn-default.active.focus,\n.open > .dropdown-toggle.btn-default.focus {\n  color: #333;\n  background-color: #d4d4d4;\n  border-color: #8c8c8c;\n}\n.btn-default:active,\n.btn-default.active,\n.open > .dropdown-toggle.btn-default {\n  background-image: none;\n}\n.btn-default.disabled:hover,\n.btn-default[disabled]:hover,\nfieldset[disabled] .btn-default:hover,\n.btn-default.disabled:focus,\n.btn-default[disabled]:focus,\nfieldset[disabled] .btn-default:focus,\n.btn-default.disabled.focus,\n.btn-default[disabled].focus,\nfieldset[disabled] .btn-default.focus {\n  background-color: #fff;\n  border-color: #ccc;\n}\n.btn-default .badge {\n  color: #fff;\n  background-color: #333;\n}\n.btn-primary {\n  color: #fff;\n  background-color: #337ab7;\n  border-color: #2e6da4;\n}\n.btn-primary:focus,\n.btn-primary.focus {\n  color: #fff;\n  background-color: #286090;\n  border-color: #122b40;\n}\n.btn-primary:hover {\n  color: #fff;\n  background-color: #286090;\n  border-color: #204d74;\n}\n.btn-primary:active,\n.btn-primary.active,\n.open > .dropdown-toggle.btn-primary {\n  color: #fff;\n  background-color: #286090;\n  border-color: #204d74;\n}\n.btn-primary:active:hover,\n.btn-primary.active:hover,\n.open > .dropdown-toggle.btn-primary:hover,\n.btn-primary:active:focus,\n.btn-primary.active:focus,\n.open > .dropdown-toggle.btn-primary:focus,\n.btn-primary:active.focus,\n.btn-primary.active.focus,\n.open > .dropdown-toggle.btn-primary.focus {\n  color: #fff;\n  background-color: #204d74;\n  border-color: #122b40;\n}\n.btn-primary:active,\n.btn-primary.active,\n.open > .dropdown-toggle.btn-primary {\n  background-image: none;\n}\n.btn-primary.disabled:hover,\n.btn-primary[disabled]:hover,\nfieldset[disabled] .btn-primary:hover,\n.btn-primary.disabled:focus,\n.btn-primary[disabled]:focus,\nfieldset[disabled] .btn-primary:focus,\n.btn-primary.disabled.focus,\n.btn-primary[disabled].focus,\nfieldset[disabled] .btn-primary.focus {\n  background-color: #337ab7;\n  border-color: #2e6da4;\n}\n.btn-primary .badge {\n  color: #337ab7;\n  background-color: #fff;\n}\n.btn-success {\n  color: #fff;\n  background-color: #5cb85c;\n  border-color: #4cae4c;\n}\n.btn-success:focus,\n.btn-success.focus {\n  color: #fff;\n  background-color: #449d44;\n  border-color: #255625;\n}\n.btn-success:hover {\n  color: #fff;\n  background-color: #449d44;\n  border-color: #398439;\n}\n.btn-success:active,\n.btn-success.active,\n.open > .dropdown-toggle.btn-success {\n  color: #fff;\n  background-color: #449d44;\n  border-color: #398439;\n}\n.btn-success:active:hover,\n.btn-success.active:hover,\n.open > .dropdown-toggle.btn-success:hover,\n.btn-success:active:focus,\n.btn-success.active:focus,\n.open > .dropdown-toggle.btn-success:focus,\n.btn-success:active.focus,\n.btn-success.active.focus,\n.open > .dropdown-toggle.btn-success.focus {\n  color: #fff;\n  background-color: #398439;\n  border-color: #255625;\n}\n.btn-success:active,\n.btn-success.active,\n.open > .dropdown-toggle.btn-success {\n  background-image: none;\n}\n.btn-success.disabled:hover,\n.btn-success[disabled]:hover,\nfieldset[disabled] .btn-success:hover,\n.btn-success.disabled:focus,\n.btn-success[disabled]:focus,\nfieldset[disabled] .btn-success:focus,\n.btn-success.disabled.focus,\n.btn-success[disabled].focus,\nfieldset[disabled] .btn-success.focus {\n  background-color: #5cb85c;\n  border-color: #4cae4c;\n}\n.btn-success .badge {\n  color: #5cb85c;\n  background-color: #fff;\n}\n.btn-info {\n  color: #fff;\n  background-color: #5bc0de;\n  border-color: #46b8da;\n}\n.btn-info:focus,\n.btn-info.focus {\n  color: #fff;\n  background-color: #31b0d5;\n  border-color: #1b6d85;\n}\n.btn-info:hover {\n  color: #fff;\n  background-color: #31b0d5;\n  border-color: #269abc;\n}\n.btn-info:active,\n.btn-info.active,\n.open > .dropdown-toggle.btn-info {\n  color: #fff;\n  background-color: #31b0d5;\n  border-color: #269abc;\n}\n.btn-info:active:hover,\n.btn-info.active:hover,\n.open > .dropdown-toggle.btn-info:hover,\n.btn-info:active:focus,\n.btn-info.active:focus,\n.open > .dropdown-toggle.btn-info:focus,\n.btn-info:active.focus,\n.btn-info.active.focus,\n.open > .dropdown-toggle.btn-info.focus {\n  color: #fff;\n  background-color: #269abc;\n  border-color: #1b6d85;\n}\n.btn-info:active,\n.btn-info.active,\n.open > .dropdown-toggle.btn-info {\n  background-image: none;\n}\n.btn-info.disabled:hover,\n.btn-info[disabled]:hover,\nfieldset[disabled] .btn-info:hover,\n.btn-info.disabled:focus,\n.btn-info[disabled]:focus,\nfieldset[disabled] .btn-info:focus,\n.btn-info.disabled.focus,\n.btn-info[disabled].focus,\nfieldset[disabled] .btn-info.focus {\n  background-color: #5bc0de;\n  border-color: #46b8da;\n}\n.btn-info .badge {\n  color: #5bc0de;\n  background-color: #fff;\n}\n.btn-warning {\n  color: #fff;\n  background-color: #f0ad4e;\n  border-color: #eea236;\n}\n.btn-warning:focus,\n.btn-warning.focus {\n  color: #fff;\n  background-color: #ec971f;\n  border-color: #985f0d;\n}\n.btn-warning:hover {\n  color: #fff;\n  background-color: #ec971f;\n  border-color: #d58512;\n}\n.btn-warning:active,\n.btn-warning.active,\n.open > .dropdown-toggle.btn-warning {\n  color: #fff;\n  background-color: #ec971f;\n  border-color: #d58512;\n}\n.btn-warning:active:hover,\n.btn-warning.active:hover,\n.open > .dropdown-toggle.btn-warning:hover,\n.btn-warning:active:focus,\n.btn-warning.active:focus,\n.open > .dropdown-toggle.btn-warning:focus,\n.btn-warning:active.focus,\n.btn-warning.active.focus,\n.open > .dropdown-toggle.btn-warning.focus {\n  color: #fff;\n  background-color: #d58512;\n  border-color: #985f0d;\n}\n.btn-warning:active,\n.btn-warning.active,\n.open > .dropdown-toggle.btn-warning {\n  background-image: none;\n}\n.btn-warning.disabled:hover,\n.btn-warning[disabled]:hover,\nfieldset[disabled] .btn-warning:hover,\n.btn-warning.disabled:focus,\n.btn-warning[disabled]:focus,\nfieldset[disabled] .btn-warning:focus,\n.btn-warning.disabled.focus,\n.btn-warning[disabled].focus,\nfieldset[disabled] .btn-warning.focus {\n  background-color: #f0ad4e;\n  border-color: #eea236;\n}\n.btn-warning .badge {\n  color: #f0ad4e;\n  background-color: #fff;\n}\n.btn-danger {\n  color: #fff;\n  background-color: #d9534f;\n  border-color: #d43f3a;\n}\n.btn-danger:focus,\n.btn-danger.focus {\n  color: #fff;\n  background-color: #c9302c;\n  border-color: #761c19;\n}\n.btn-danger:hover {\n  color: #fff;\n  background-color: #c9302c;\n  border-color: #ac2925;\n}\n.btn-danger:active,\n.btn-danger.active,\n.open > .dropdown-toggle.btn-danger {\n  color: #fff;\n  background-color: #c9302c;\n  border-color: #ac2925;\n}\n.btn-danger:active:hover,\n.btn-danger.active:hover,\n.open > .dropdown-toggle.btn-danger:hover,\n.btn-danger:active:focus,\n.btn-danger.active:focus,\n.open > .dropdown-toggle.btn-danger:focus,\n.btn-danger:active.focus,\n.btn-danger.active.focus,\n.open > .dropdown-toggle.btn-danger.focus {\n  color: #fff;\n  background-color: #ac2925;\n  border-color: #761c19;\n}\n.btn-danger:active,\n.btn-danger.active,\n.open > .dropdown-toggle.btn-danger {\n  background-image: none;\n}\n.btn-danger.disabled:hover,\n.btn-danger[disabled]:hover,\nfieldset[disabled] .btn-danger:hover,\n.btn-danger.disabled:focus,\n.btn-danger[disabled]:focus,\nfieldset[disabled] .btn-danger:focus,\n.btn-danger.disabled.focus,\n.btn-danger[disabled].focus,\nfieldset[disabled] .btn-danger.focus {\n  background-color: #d9534f;\n  border-color: #d43f3a;\n}\n.btn-danger .badge {\n  color: #d9534f;\n  background-color: #fff;\n}\n.btn-link {\n  font-weight: normal;\n  color: #337ab7;\n  border-radius: 0;\n}\n.btn-link,\n.btn-link:active,\n.btn-link.active,\n.btn-link[disabled],\nfieldset[disabled] .btn-link {\n  background-color: transparent;\n  -webkit-box-shadow: none;\n          box-shadow: none;\n}\n.btn-link,\n.btn-link:hover,\n.btn-link:focus,\n.btn-link:active {\n  border-color: transparent;\n}\n.btn-link:hover,\n.btn-link:focus {\n  color: #23527c;\n  text-decoration: underline;\n  background-color: transparent;\n}\n.btn-link[disabled]:hover,\nfieldset[disabled] .btn-link:hover,\n.btn-link[disabled]:focus,\nfieldset[disabled] .btn-link:focus {\n  color: #777;\n  text-decoration: none;\n}\n.btn-lg,\n.btn-group-lg > .btn {\n  padding: 10px 16px;\n  font-size: 18px;\n  line-height: 1.3333333;\n  border-radius: 6px;\n}\n.btn-sm,\n.btn-group-sm > .btn {\n  padding: 5px 10px;\n  font-size: 12px;\n  line-height: 1.5;\n  border-radius: 3px;\n}\n.btn-xs,\n.btn-group-xs > .btn {\n  padding: 1px 5px;\n  font-size: 12px;\n  line-height: 1.5;\n  border-radius: 3px;\n}\n.btn-block {\n  display: block;\n  width: 100%;\n}\n.btn-block + .btn-block {\n  margin-top: 5px;\n}\ninput[type=\"submit\"].btn-block,\ninput[type=\"reset\"].btn-block,\ninput[type=\"button\"].btn-block {\n  width: 100%;\n}\n.fade {\n  opacity: 0;\n  -webkit-transition: opacity .15s linear;\n       -o-transition: opacity .15s linear;\n          transition: opacity .15s linear;\n}\n.fade.in {\n  opacity: 1;\n}\n.collapse {\n  display: none;\n}\n.collapse.in {\n  display: block;\n}\ntr.collapse.in {\n  display: table-row;\n}\ntbody.collapse.in {\n  display: table-row-group;\n}\n.collapsing {\n  position: relative;\n  height: 0;\n  overflow: hidden;\n  -webkit-transition-timing-function: ease;\n       -o-transition-timing-function: ease;\n          transition-timing-function: ease;\n  -webkit-transition-duration: .35s;\n       -o-transition-duration: .35s;\n          transition-duration: .35s;\n  -webkit-transition-property: height, visibility;\n       -o-transition-property: height, visibility;\n          transition-property: height, visibility;\n}\n.caret {\n  display: inline-block;\n  width: 0;\n  height: 0;\n  margin-left: 2px;\n  vertical-align: middle;\n  border-top: 4px dashed;\n  border-top: 4px solid \\9;\n  border-right: 4px solid transparent;\n  border-left: 4px solid transparent;\n}\n.dropup,\n.dropdown {\n  position: relative;\n}\n.dropdown-toggle:focus {\n  outline: 0;\n}\n.dropdown-menu {\n  position: absolute;\n  top: 100%;\n  left: 0;\n  z-index: 1000;\n  display: none;\n  float: left;\n  min-width: 160px;\n  padding: 5px 0;\n  margin: 2px 0 0;\n  font-size: 14px;\n  text-align: left;\n  list-style: none;\n  background-color: #fff;\n  -webkit-background-clip: padding-box;\n          background-clip: padding-box;\n  border: 1px solid #ccc;\n  border: 1px solid rgba(0, 0, 0, .15);\n  border-radius: 4px;\n  -webkit-box-shadow: 0 6px 12px rgba(0, 0, 0, .175);\n          box-shadow: 0 6px 12px rgba(0, 0, 0, .175);\n}\n.dropdown-menu.pull-right {\n  right: 0;\n  left: auto;\n}\n.dropdown-menu .divider {\n  height: 1px;\n  margin: 9px 0;\n  overflow: hidden;\n  background-color: #e5e5e5;\n}\n.dropdown-menu > li > a {\n  display: block;\n  padding: 3px 20px;\n  clear: both;\n  font-weight: normal;\n  line-height: 1.42857143;\n  color: #333;\n  white-space: nowrap;\n}\n.dropdown-menu > li > a:hover,\n.dropdown-menu > li > a:focus {\n  color: #262626;\n  text-decoration: none;\n  background-color: #f5f5f5;\n}\n.dropdown-menu > .active > a,\n.dropdown-menu > .active > a:hover,\n.dropdown-menu > .active > a:focus {\n  color: #fff;\n  text-decoration: none;\n  background-color: #337ab7;\n  outline: 0;\n}\n.dropdown-menu > .disabled > a,\n.dropdown-menu > .disabled > a:hover,\n.dropdown-menu > .disabled > a:focus {\n  color: #777;\n}\n.dropdown-menu > .disabled > a:hover,\n.dropdown-menu > .disabled > a:focus {\n  text-decoration: none;\n  cursor: not-allowed;\n  background-color: transparent;\n  background-image: none;\n  filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);\n}\n.open > .dropdown-menu {\n  display: block;\n}\n.open > a {\n  outline: 0;\n}\n.dropdown-menu-right {\n  right: 0;\n  left: auto;\n}\n.dropdown-menu-left {\n  right: auto;\n  left: 0;\n}\n.dropdown-header {\n  display: block;\n  padding: 3px 20px;\n  font-size: 12px;\n  line-height: 1.42857143;\n  color: #777;\n  white-space: nowrap;\n}\n.dropdown-backdrop {\n  position: fixed;\n  top: 0;\n  right: 0;\n  bottom: 0;\n  left: 0;\n  z-index: 990;\n}\n.pull-right > .dropdown-menu {\n  right: 0;\n  left: auto;\n}\n.dropup .caret,\n.navbar-fixed-bottom .dropdown .caret {\n  content: \"\";\n  border-top: 0;\n  border-bottom: 4px dashed;\n  border-bottom: 4px solid \\9;\n}\n.dropup .dropdown-menu,\n.navbar-fixed-bottom .dropdown .dropdown-menu {\n  top: auto;\n  bottom: 100%;\n  margin-bottom: 2px;\n}\n@media (min-width: 768px) {\n  .navbar-right .dropdown-menu {\n    right: 0;\n    left: auto;\n  }\n  .navbar-right .dropdown-menu-left {\n    right: auto;\n    left: 0;\n  }\n}\n.btn-group,\n.btn-group-vertical {\n  position: relative;\n  display: inline-block;\n  vertical-align: middle;\n}\n.btn-group > .btn,\n.btn-group-vertical > .btn {\n  position: relative;\n  float: left;\n}\n.btn-group > .btn:hover,\n.btn-group-vertical > .btn:hover,\n.btn-group > .btn:focus,\n.btn-group-vertical > .btn:focus,\n.btn-group > .btn:active,\n.btn-group-vertical > .btn:active,\n.btn-group > .btn.active,\n.btn-group-vertical > .btn.active {\n  z-index: 2;\n}\n.btn-group .btn + .btn,\n.btn-group .btn + .btn-group,\n.btn-group .btn-group + .btn,\n.btn-group .btn-group + .btn-group {\n  margin-left: -1px;\n}\n.btn-toolbar {\n  margin-left: -5px;\n}\n.btn-toolbar .btn,\n.btn-toolbar .btn-group,\n.btn-toolbar .input-group {\n  float: left;\n}\n.btn-toolbar > .btn,\n.btn-toolbar > .btn-group,\n.btn-toolbar > .input-group {\n  margin-left: 5px;\n}\n.btn-group > .btn:not(:first-child):not(:last-child):not(.dropdown-toggle) {\n  border-radius: 0;\n}\n.btn-group > .btn:first-child {\n  margin-left: 0;\n}\n.btn-group > .btn:first-child:not(:last-child):not(.dropdown-toggle) {\n  border-top-right-radius: 0;\n  border-bottom-right-radius: 0;\n}\n.btn-group > .btn:last-child:not(:first-child),\n.btn-group > .dropdown-toggle:not(:first-child) {\n  border-top-left-radius: 0;\n  border-bottom-left-radius: 0;\n}\n.btn-group > .btn-group {\n  float: left;\n}\n.btn-group > .btn-group:not(:first-child):not(:last-child) > .btn {\n  border-radius: 0;\n}\n.btn-group > .btn-group:first-child:not(:last-child) > .btn:last-child,\n.btn-group > .btn-group:first-child:not(:last-child) > .dropdown-toggle {\n  border-top-right-radius: 0;\n  border-bottom-right-radius: 0;\n}\n.btn-group > .btn-group:last-child:not(:first-child) > .btn:first-child {\n  border-top-left-radius: 0;\n  border-bottom-left-radius: 0;\n}\n.btn-group .dropdown-toggle:active,\n.btn-group.open .dropdown-toggle {\n  outline: 0;\n}\n.btn-group > .btn + .dropdown-toggle {\n  padding-right: 8px;\n  padding-left: 8px;\n}\n.btn-group > .btn-lg + .dropdown-toggle {\n  padding-right: 12px;\n  padding-left: 12px;\n}\n.btn-group.open .dropdown-toggle {\n  -webkit-box-shadow: inset 0 3px 5px rgba(0, 0, 0, .125);\n          box-shadow: inset 0 3px 5px rgba(0, 0, 0, .125);\n}\n.btn-group.open .dropdown-toggle.btn-link {\n  -webkit-box-shadow: none;\n          box-shadow: none;\n}\n.btn .caret {\n  margin-left: 0;\n}\n.btn-lg .caret {\n  border-width: 5px 5px 0;\n  border-bottom-width: 0;\n}\n.dropup .btn-lg .caret {\n  border-width: 0 5px 5px;\n}\n.btn-group-vertical > .btn,\n.btn-group-vertical > .btn-group,\n.btn-group-vertical > .btn-group > .btn {\n  display: block;\n  float: none;\n  width: 100%;\n  max-width: 100%;\n}\n.btn-group-vertical > .btn-group > .btn {\n  float: none;\n}\n.btn-group-vertical > .btn + .btn,\n.btn-group-vertical > .btn + .btn-group,\n.btn-group-vertical > .btn-group + .btn,\n.btn-group-vertical > .btn-group + .btn-group {\n  margin-top: -1px;\n  margin-left: 0;\n}\n.btn-group-vertical > .btn:not(:first-child):not(:last-child) {\n  border-radius: 0;\n}\n.btn-group-vertical > .btn:first-child:not(:last-child) {\n  border-top-left-radius: 4px;\n  border-top-right-radius: 4px;\n  border-bottom-right-radius: 0;\n  border-bottom-left-radius: 0;\n}\n.btn-group-vertical > .btn:last-child:not(:first-child) {\n  border-top-left-radius: 0;\n  border-top-right-radius: 0;\n  border-bottom-right-radius: 4px;\n  border-bottom-left-radius: 4px;\n}\n.btn-group-vertical > .btn-group:not(:first-child):not(:last-child) > .btn {\n  border-radius: 0;\n}\n.btn-group-vertical > .btn-group:first-child:not(:last-child) > .btn:last-child,\n.btn-group-vertical > .btn-group:first-child:not(:last-child) > .dropdown-toggle {\n  border-bottom-right-radius: 0;\n  border-bottom-left-radius: 0;\n}\n.btn-group-vertical > .btn-group:last-child:not(:first-child) > .btn:first-child {\n  border-top-left-radius: 0;\n  border-top-right-radius: 0;\n}\n.btn-group-justified {\n  display: table;\n  width: 100%;\n  table-layout: fixed;\n  border-collapse: separate;\n}\n.btn-group-justified > .btn,\n.btn-group-justified > .btn-group {\n  display: table-cell;\n  float: none;\n  width: 1%;\n}\n.btn-group-justified > .btn-group .btn {\n  width: 100%;\n}\n.btn-group-justified > .btn-group .dropdown-menu {\n  left: auto;\n}\n[data-toggle=\"buttons\"] > .btn input[type=\"radio\"],\n[data-toggle=\"buttons\"] > .btn-group > .btn input[type=\"radio\"],\n[data-toggle=\"buttons\"] > .btn input[type=\"checkbox\"],\n[data-toggle=\"buttons\"] > .btn-group > .btn input[type=\"checkbox\"] {\n  position: absolute;\n  clip: rect(0, 0, 0, 0);\n  pointer-events: none;\n}\n.input-group {\n  position: relative;\n  display: table;\n  border-collapse: separate;\n}\n.input-group[class*=\"col-\"] {\n  float: none;\n  padding-right: 0;\n  padding-left: 0;\n}\n.input-group .form-control {\n  position: relative;\n  z-index: 2;\n  float: left;\n  width: 100%;\n  margin-bottom: 0;\n}\n.input-group .form-control:focus {\n  z-index: 3;\n}\n.input-group-lg > .form-control,\n.input-group-lg > .input-group-addon,\n.input-group-lg > .input-group-btn > .btn {\n  height: 46px;\n  padding: 10px 16px;\n  font-size: 18px;\n  line-height: 1.3333333;\n  border-radius: 6px;\n}\nselect.input-group-lg > .form-control,\nselect.input-group-lg > .input-group-addon,\nselect.input-group-lg > .input-group-btn > .btn {\n  height: 46px;\n  line-height: 46px;\n}\ntextarea.input-group-lg > .form-control,\ntextarea.input-group-lg > .input-group-addon,\ntextarea.input-group-lg > .input-group-btn > .btn,\nselect[multiple].input-group-lg > .form-control,\nselect[multiple].input-group-lg > .input-group-addon,\nselect[multiple].input-group-lg > .input-group-btn > .btn {\n  height: auto;\n}\n.input-group-sm > .form-control,\n.input-group-sm > .input-group-addon,\n.input-group-sm > .input-group-btn > .btn {\n  height: 30px;\n  padding: 5px 10px;\n  font-size: 12px;\n  line-height: 1.5;\n  border-radius: 3px;\n}\nselect.input-group-sm > .form-control,\nselect.input-group-sm > .input-group-addon,\nselect.input-group-sm > .input-group-btn > .btn {\n  height: 30px;\n  line-height: 30px;\n}\ntextarea.input-group-sm > .form-control,\ntextarea.input-group-sm > .input-group-addon,\ntextarea.input-group-sm > .input-group-btn > .btn,\nselect[multiple].input-group-sm > .form-control,\nselect[multiple].input-group-sm > .input-group-addon,\nselect[multiple].input-group-sm > .input-group-btn > .btn {\n  height: auto;\n}\n.input-group-addon,\n.input-group-btn,\n.input-group .form-control {\n  display: table-cell;\n}\n.input-group-addon:not(:first-child):not(:last-child),\n.input-group-btn:not(:first-child):not(:last-child),\n.input-group .form-control:not(:first-child):not(:last-child) {\n  border-radius: 0;\n}\n.input-group-addon,\n.input-group-btn {\n  width: 1%;\n  white-space: nowrap;\n  vertical-align: middle;\n}\n.input-group-addon {\n  padding: 6px 12px;\n  font-size: 14px;\n  font-weight: normal;\n  line-height: 1;\n  color: #555;\n  text-align: center;\n  background-color: #eee;\n  border: 1px solid #ccc;\n  border-radius: 4px;\n}\n.input-group-addon.input-sm {\n  padding: 5px 10px;\n  font-size: 12px;\n  border-radius: 3px;\n}\n.input-group-addon.input-lg {\n  padding: 10px 16px;\n  font-size: 18px;\n  border-radius: 6px;\n}\n.input-group-addon input[type=\"radio\"],\n.input-group-addon input[type=\"checkbox\"] {\n  margin-top: 0;\n}\n.input-group .form-control:first-child,\n.input-group-addon:first-child,\n.input-group-btn:first-child > .btn,\n.input-group-btn:first-child > .btn-group > .btn,\n.input-group-btn:first-child > .dropdown-toggle,\n.input-group-btn:last-child > .btn:not(:last-child):not(.dropdown-toggle),\n.input-group-btn:last-child > .btn-group:not(:last-child) > .btn {\n  border-top-right-radius: 0;\n  border-bottom-right-radius: 0;\n}\n.input-group-addon:first-child {\n  border-right: 0;\n}\n.input-group .form-control:last-child,\n.input-group-addon:last-child,\n.input-group-btn:last-child > .btn,\n.input-group-btn:last-child > .btn-group > .btn,\n.input-group-btn:last-child > .dropdown-toggle,\n.input-group-btn:first-child > .btn:not(:first-child),\n.input-group-btn:first-child > .btn-group:not(:first-child) > .btn {\n  border-top-left-radius: 0;\n  border-bottom-left-radius: 0;\n}\n.input-group-addon:last-child {\n  border-left: 0;\n}\n.input-group-btn {\n  position: relative;\n  font-size: 0;\n  white-space: nowrap;\n}\n.input-group-btn > .btn {\n  position: relative;\n}\n.input-group-btn > .btn + .btn {\n  margin-left: -1px;\n}\n.input-group-btn > .btn:hover,\n.input-group-btn > .btn:focus,\n.input-group-btn > .btn:active {\n  z-index: 2;\n}\n.input-group-btn:first-child > .btn,\n.input-group-btn:first-child > .btn-group {\n  margin-right: -1px;\n}\n.input-group-btn:last-child > .btn,\n.input-group-btn:last-child > .btn-group {\n  z-index: 2;\n  margin-left: -1px;\n}\n.nav {\n  padding-left: 0;\n  margin-bottom: 0;\n  list-style: none;\n}\n.nav > li {\n  position: relative;\n  display: block;\n}\n.nav > li > a {\n  position: relative;\n  display: block;\n  padding: 10px 15px;\n}\n.nav > li > a:hover,\n.nav > li > a:focus {\n  text-decoration: none;\n  background-color: #eee;\n}\n.nav > li.disabled > a {\n  color: #777;\n}\n.nav > li.disabled > a:hover,\n.nav > li.disabled > a:focus {\n  color: #777;\n  text-decoration: none;\n  cursor: not-allowed;\n  background-color: transparent;\n}\n.nav .open > a,\n.nav .open > a:hover,\n.nav .open > a:focus {\n  background-color: #eee;\n  border-color: #337ab7;\n}\n.nav .nav-divider {\n  height: 1px;\n  margin: 9px 0;\n  overflow: hidden;\n  background-color: #e5e5e5;\n}\n.nav > li > a > img {\n  max-width: none;\n}\n.nav-tabs {\n  border-bottom: 1px solid #ddd;\n}\n.nav-tabs > li {\n  float: left;\n  margin-bottom: -1px;\n}\n.nav-tabs > li > a {\n  margin-right: 2px;\n  line-height: 1.42857143;\n  border: 1px solid transparent;\n  border-radius: 4px 4px 0 0;\n}\n.nav-tabs > li > a:hover {\n  border-color: #eee #eee #ddd;\n}\n.nav-tabs > li.active > a,\n.nav-tabs > li.active > a:hover,\n.nav-tabs > li.active > a:focus {\n  color: #555;\n  cursor: default;\n  background-color: #fff;\n  border: 1px solid #ddd;\n  border-bottom-color: transparent;\n}\n.nav-tabs.nav-justified {\n  width: 100%;\n  border-bottom: 0;\n}\n.nav-tabs.nav-justified > li {\n  float: none;\n}\n.nav-tabs.nav-justified > li > a {\n  margin-bottom: 5px;\n  text-align: center;\n}\n.nav-tabs.nav-justified > .dropdown .dropdown-menu {\n  top: auto;\n  left: auto;\n}\n@media (min-width: 768px) {\n  .nav-tabs.nav-justified > li {\n    display: table-cell;\n    width: 1%;\n  }\n  .nav-tabs.nav-justified > li > a {\n    margin-bottom: 0;\n  }\n}\n.nav-tabs.nav-justified > li > a {\n  margin-right: 0;\n  border-radius: 4px;\n}\n.nav-tabs.nav-justified > .active > a,\n.nav-tabs.nav-justified > .active > a:hover,\n.nav-tabs.nav-justified > .active > a:focus {\n  border: 1px solid #ddd;\n}\n@media (min-width: 768px) {\n  .nav-tabs.nav-justified > li > a {\n    border-bottom: 1px solid #ddd;\n    border-radius: 4px 4px 0 0;\n  }\n  .nav-tabs.nav-justified > .active > a,\n  .nav-tabs.nav-justified > .active > a:hover,\n  .nav-tabs.nav-justified > .active > a:focus {\n    border-bottom-color: #fff;\n  }\n}\n.nav-pills > li {\n  float: left;\n}\n.nav-pills > li > a {\n  border-radius: 4px;\n}\n.nav-pills > li + li {\n  margin-left: 2px;\n}\n.nav-pills > li.active > a,\n.nav-pills > li.active > a:hover,\n.nav-pills > li.active > a:focus {\n  color: #fff;\n  background-color: #337ab7;\n}\n.nav-stacked > li {\n  float: none;\n}\n.nav-stacked > li + li {\n  margin-top: 2px;\n  margin-left: 0;\n}\n.nav-justified {\n  width: 100%;\n}\n.nav-justified > li {\n  float: none;\n}\n.nav-justified > li > a {\n  margin-bottom: 5px;\n  text-align: center;\n}\n.nav-justified > .dropdown .dropdown-menu {\n  top: auto;\n  left: auto;\n}\n@media (min-width: 768px) {\n  .nav-justified > li {\n    display: table-cell;\n    width: 1%;\n  }\n  .nav-justified > li > a {\n    margin-bottom: 0;\n  }\n}\n.nav-tabs-justified {\n  border-bottom: 0;\n}\n.nav-tabs-justified > li > a {\n  margin-right: 0;\n  border-radius: 4px;\n}\n.nav-tabs-justified > .active > a,\n.nav-tabs-justified > .active > a:hover,\n.nav-tabs-justified > .active > a:focus {\n  border: 1px solid #ddd;\n}\n@media (min-width: 768px) {\n  .nav-tabs-justified > li > a {\n    border-bottom: 1px solid #ddd;\n    border-radius: 4px 4px 0 0;\n  }\n  .nav-tabs-justified > .active > a,\n  .nav-tabs-justified > .active > a:hover,\n  .nav-tabs-justified > .active > a:focus {\n    border-bottom-color: #fff;\n  }\n}\n.tab-content > .tab-pane {\n  display: none;\n}\n.tab-content > .active {\n  display: block;\n}\n.nav-tabs .dropdown-menu {\n  margin-top: -1px;\n  border-top-left-radius: 0;\n  border-top-right-radius: 0;\n}\n.navbar {\n  position: relative;\n  min-height: 50px;\n  margin-bottom: 20px;\n  border: 1px solid transparent;\n}\n@media (min-width: 768px) {\n  .navbar {\n    border-radius: 4px;\n  }\n}\n@media (min-width: 768px) {\n  .navbar-header {\n    float: left;\n  }\n}\n.navbar-collapse {\n  padding-right: 15px;\n  padding-left: 15px;\n  overflow-x: visible;\n  -webkit-overflow-scrolling: touch;\n  border-top: 1px solid transparent;\n  -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, .1);\n          box-shadow: inset 0 1px 0 rgba(255, 255, 255, .1);\n}\n.navbar-collapse.in {\n  overflow-y: auto;\n}\n@media (min-width: 768px) {\n  .navbar-collapse {\n    width: auto;\n    border-top: 0;\n    -webkit-box-shadow: none;\n            box-shadow: none;\n  }\n  .navbar-collapse.collapse {\n    display: block !important;\n    height: auto !important;\n    padding-bottom: 0;\n    overflow: visible !important;\n  }\n  .navbar-collapse.in {\n    overflow-y: visible;\n  }\n  .navbar-fixed-top .navbar-collapse,\n  .navbar-static-top .navbar-collapse,\n  .navbar-fixed-bottom .navbar-collapse {\n    padding-right: 0;\n    padding-left: 0;\n  }\n}\n.navbar-fixed-top .navbar-collapse,\n.navbar-fixed-bottom .navbar-collapse {\n  max-height: 340px;\n}\n@media (max-device-width: 480px) and (orientation: landscape) {\n  .navbar-fixed-top .navbar-collapse,\n  .navbar-fixed-bottom .navbar-collapse {\n    max-height: 200px;\n  }\n}\n.container > .navbar-header,\n.container-fluid > .navbar-header,\n.container > .navbar-collapse,\n.container-fluid > .navbar-collapse {\n  margin-right: -15px;\n  margin-left: -15px;\n}\n@media (min-width: 768px) {\n  .container > .navbar-header,\n  .container-fluid > .navbar-header,\n  .container > .navbar-collapse,\n  .container-fluid > .navbar-collapse {\n    margin-right: 0;\n    margin-left: 0;\n  }\n}\n.navbar-static-top {\n  z-index: 1000;\n  border-width: 0 0 1px;\n}\n@media (min-width: 768px) {\n  .navbar-static-top {\n    border-radius: 0;\n  }\n}\n.navbar-fixed-top,\n.navbar-fixed-bottom {\n  position: fixed;\n  right: 0;\n  left: 0;\n  z-index: 1030;\n}\n@media (min-width: 768px) {\n  .navbar-fixed-top,\n  .navbar-fixed-bottom {\n    border-radius: 0;\n  }\n}\n.navbar-fixed-top {\n  top: 0;\n  border-width: 0 0 1px;\n}\n.navbar-fixed-bottom {\n  bottom: 0;\n  margin-bottom: 0;\n  border-width: 1px 0 0;\n}\n.navbar-brand {\n  float: left;\n  height: 50px;\n  padding: 15px 15px;\n  font-size: 18px;\n  line-height: 20px;\n}\n.navbar-brand:hover,\n.navbar-brand:focus {\n  text-decoration: none;\n}\n.navbar-brand > img {\n  display: block;\n}\n@media (min-width: 768px) {\n  .navbar > .container .navbar-brand,\n  .navbar > .container-fluid .navbar-brand {\n    margin-left: -15px;\n  }\n}\n.navbar-toggle {\n  position: relative;\n  float: right;\n  padding: 9px 10px;\n  margin-top: 8px;\n  margin-right: 15px;\n  margin-bottom: 8px;\n  background-color: transparent;\n  background-image: none;\n  border: 1px solid transparent;\n  border-radius: 4px;\n}\n.navbar-toggle:focus {\n  outline: 0;\n}\n.navbar-toggle .icon-bar {\n  display: block;\n  width: 22px;\n  height: 2px;\n  border-radius: 1px;\n}\n.navbar-toggle .icon-bar + .icon-bar {\n  margin-top: 4px;\n}\n@media (min-width: 768px) {\n  .navbar-toggle {\n    display: none;\n  }\n}\n.navbar-nav {\n  margin: 7.5px -15px;\n}\n.navbar-nav > li > a {\n  padding-top: 10px;\n  padding-bottom: 10px;\n  line-height: 20px;\n}\n@media (max-width: 767px) {\n  .navbar-nav .open .dropdown-menu {\n    position: static;\n    float: none;\n    width: auto;\n    margin-top: 0;\n    background-color: transparent;\n    border: 0;\n    -webkit-box-shadow: none;\n            box-shadow: none;\n  }\n  .navbar-nav .open .dropdown-menu > li > a,\n  .navbar-nav .open .dropdown-menu .dropdown-header {\n    padding: 5px 15px 5px 25px;\n  }\n  .navbar-nav .open .dropdown-menu > li > a {\n    line-height: 20px;\n  }\n  .navbar-nav .open .dropdown-menu > li > a:hover,\n  .navbar-nav .open .dropdown-menu > li > a:focus {\n    background-image: none;\n  }\n}\n@media (min-width: 768px) {\n  .navbar-nav {\n    float: left;\n    margin: 0;\n  }\n  .navbar-nav > li {\n    float: left;\n  }\n  .navbar-nav > li > a {\n    padding-top: 15px;\n    padding-bottom: 15px;\n  }\n}\n.navbar-form {\n  padding: 10px 15px;\n  margin-top: 8px;\n  margin-right: -15px;\n  margin-bottom: 8px;\n  margin-left: -15px;\n  border-top: 1px solid transparent;\n  border-bottom: 1px solid transparent;\n  -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, .1), 0 1px 0 rgba(255, 255, 255, .1);\n          box-shadow: inset 0 1px 0 rgba(255, 255, 255, .1), 0 1px 0 rgba(255, 255, 255, .1);\n}\n@media (min-width: 768px) {\n  .navbar-form .form-group {\n    display: inline-block;\n    margin-bottom: 0;\n    vertical-align: middle;\n  }\n  .navbar-form .form-control {\n    display: inline-block;\n    width: auto;\n    vertical-align: middle;\n  }\n  .navbar-form .form-control-static {\n    display: inline-block;\n  }\n  .navbar-form .input-group {\n    display: inline-table;\n    vertical-align: middle;\n  }\n  .navbar-form .input-group .input-group-addon,\n  .navbar-form .input-group .input-group-btn,\n  .navbar-form .input-group .form-control {\n    width: auto;\n  }\n  .navbar-form .input-group > .form-control {\n    width: 100%;\n  }\n  .navbar-form .control-label {\n    margin-bottom: 0;\n    vertical-align: middle;\n  }\n  .navbar-form .radio,\n  .navbar-form .checkbox {\n    display: inline-block;\n    margin-top: 0;\n    margin-bottom: 0;\n    vertical-align: middle;\n  }\n  .navbar-form .radio label,\n  .navbar-form .checkbox label {\n    padding-left: 0;\n  }\n  .navbar-form .radio input[type=\"radio\"],\n  .navbar-form .checkbox input[type=\"checkbox\"] {\n    position: relative;\n    margin-left: 0;\n  }\n  .navbar-form .has-feedback .form-control-feedback {\n    top: 0;\n  }\n}\n@media (max-width: 767px) {\n  .navbar-form .form-group {\n    margin-bottom: 5px;\n  }\n  .navbar-form .form-group:last-child {\n    margin-bottom: 0;\n  }\n}\n@media (min-width: 768px) {\n  .navbar-form {\n    width: auto;\n    padding-top: 0;\n    padding-bottom: 0;\n    margin-right: 0;\n    margin-left: 0;\n    border: 0;\n    -webkit-box-shadow: none;\n            box-shadow: none;\n  }\n}\n.navbar-nav > li > .dropdown-menu {\n  margin-top: 0;\n  border-top-left-radius: 0;\n  border-top-right-radius: 0;\n}\n.navbar-fixed-bottom .navbar-nav > li > .dropdown-menu {\n  margin-bottom: 0;\n  border-top-left-radius: 4px;\n  border-top-right-radius: 4px;\n  border-bottom-right-radius: 0;\n  border-bottom-left-radius: 0;\n}\n.navbar-btn {\n  margin-top: 8px;\n  margin-bottom: 8px;\n}\n.navbar-btn.btn-sm {\n  margin-top: 10px;\n  margin-bottom: 10px;\n}\n.navbar-btn.btn-xs {\n  margin-top: 14px;\n  margin-bottom: 14px;\n}\n.navbar-text {\n  margin-top: 15px;\n  margin-bottom: 15px;\n}\n@media (min-width: 768px) {\n  .navbar-text {\n    float: left;\n    margin-right: 15px;\n    margin-left: 15px;\n  }\n}\n@media (min-width: 768px) {\n  .navbar-left {\n    float: left !important;\n  }\n  .navbar-right {\n    float: right !important;\n    margin-right: -15px;\n  }\n  .navbar-right ~ .navbar-right {\n    margin-right: 0;\n  }\n}\n.navbar-default {\n  background-color: #f8f8f8;\n  border-color: #e7e7e7;\n}\n.navbar-default .navbar-brand {\n  color: #777;\n}\n.navbar-default .navbar-brand:hover,\n.navbar-default .navbar-brand:focus {\n  color: #5e5e5e;\n  background-color: transparent;\n}\n.navbar-default .navbar-text {\n  color: #777;\n}\n.navbar-default .navbar-nav > li > a {\n  color: #777;\n}\n.navbar-default .navbar-nav > li > a:hover,\n.navbar-default .navbar-nav > li > a:focus {\n  color: #333;\n  background-color: transparent;\n}\n.navbar-default .navbar-nav > .active > a,\n.navbar-default .navbar-nav > .active > a:hover,\n.navbar-default .navbar-nav > .active > a:focus {\n  color: #555;\n  background-color: #e7e7e7;\n}\n.navbar-default .navbar-nav > .disabled > a,\n.navbar-default .navbar-nav > .disabled > a:hover,\n.navbar-default .navbar-nav > .disabled > a:focus {\n  color: #ccc;\n  background-color: transparent;\n}\n.navbar-default .navbar-toggle {\n  border-color: #ddd;\n}\n.navbar-default .navbar-toggle:hover,\n.navbar-default .navbar-toggle:focus {\n  background-color: #ddd;\n}\n.navbar-default .navbar-toggle .icon-bar {\n  background-color: #888;\n}\n.navbar-default .navbar-collapse,\n.navbar-default .navbar-form {\n  border-color: #e7e7e7;\n}\n.navbar-default .navbar-nav > .open > a,\n.navbar-default .navbar-nav > .open > a:hover,\n.navbar-default .navbar-nav > .open > a:focus {\n  color: #555;\n  background-color: #e7e7e7;\n}\n@media (max-width: 767px) {\n  .navbar-default .navbar-nav .open .dropdown-menu > li > a {\n    color: #777;\n  }\n  .navbar-default .navbar-nav .open .dropdown-menu > li > a:hover,\n  .navbar-default .navbar-nav .open .dropdown-menu > li > a:focus {\n    color: #333;\n    background-color: transparent;\n  }\n  .navbar-default .navbar-nav .open .dropdown-menu > .active > a,\n  .navbar-default .navbar-nav .open .dropdown-menu > .active > a:hover,\n  .navbar-default .navbar-nav .open .dropdown-menu > .active > a:focus {\n    color: #555;\n    background-color: #e7e7e7;\n  }\n  .navbar-default .navbar-nav .open .dropdown-menu > .disabled > a,\n  .navbar-default .navbar-nav .open .dropdown-menu > .disabled > a:hover,\n  .navbar-default .navbar-nav .open .dropdown-menu > .disabled > a:focus {\n    color: #ccc;\n    background-color: transparent;\n  }\n}\n.navbar-default .navbar-link {\n  color: #777;\n}\n.navbar-default .navbar-link:hover {\n  color: #333;\n}\n.navbar-default .btn-link {\n  color: #777;\n}\n.navbar-default .btn-link:hover,\n.navbar-default .btn-link:focus {\n  color: #333;\n}\n.navbar-default .btn-link[disabled]:hover,\nfieldset[disabled] .navbar-default .btn-link:hover,\n.navbar-default .btn-link[disabled]:focus,\nfieldset[disabled] .navbar-default .btn-link:focus {\n  color: #ccc;\n}\n.navbar-inverse {\n  background-color: #222;\n  border-color: #080808;\n}\n.navbar-inverse .navbar-brand {\n  color: #9d9d9d;\n}\n.navbar-inverse .navbar-brand:hover,\n.navbar-inverse .navbar-brand:focus {\n  color: #fff;\n  background-color: transparent;\n}\n.navbar-inverse .navbar-text {\n  color: #9d9d9d;\n}\n.navbar-inverse .navbar-nav > li > a {\n  color: #9d9d9d;\n}\n.navbar-inverse .navbar-nav > li > a:hover,\n.navbar-inverse .navbar-nav > li > a:focus {\n  color: #fff;\n  background-color: transparent;\n}\n.navbar-inverse .navbar-nav > .active > a,\n.navbar-inverse .navbar-nav > .active > a:hover,\n.navbar-inverse .navbar-nav > .active > a:focus {\n  color: #fff;\n  background-color: #080808;\n}\n.navbar-inverse .navbar-nav > .disabled > a,\n.navbar-inverse .navbar-nav > .disabled > a:hover,\n.navbar-inverse .navbar-nav > .disabled > a:focus {\n  color: #444;\n  background-color: transparent;\n}\n.navbar-inverse .navbar-toggle {\n  border-color: #333;\n}\n.navbar-inverse .navbar-toggle:hover,\n.navbar-inverse .navbar-toggle:focus {\n  background-color: #333;\n}\n.navbar-inverse .navbar-toggle .icon-bar {\n  background-color: #fff;\n}\n.navbar-inverse .navbar-collapse,\n.navbar-inverse .navbar-form {\n  border-color: #101010;\n}\n.navbar-inverse .navbar-nav > .open > a,\n.navbar-inverse .navbar-nav > .open > a:hover,\n.navbar-inverse .navbar-nav > .open > a:focus {\n  color: #fff;\n  background-color: #080808;\n}\n@media (max-width: 767px) {\n  .navbar-inverse .navbar-nav .open .dropdown-menu > .dropdown-header {\n    border-color: #080808;\n  }\n  .navbar-inverse .navbar-nav .open .dropdown-menu .divider {\n    background-color: #080808;\n  }\n  .navbar-inverse .navbar-nav .open .dropdown-menu > li > a {\n    color: #9d9d9d;\n  }\n  .navbar-inverse .navbar-nav .open .dropdown-menu > li > a:hover,\n  .navbar-inverse .navbar-nav .open .dropdown-menu > li > a:focus {\n    color: #fff;\n    background-color: transparent;\n  }\n  .navbar-inverse .navbar-nav .open .dropdown-menu > .active > a,\n  .navbar-inverse .navbar-nav .open .dropdown-menu > .active > a:hover,\n  .navbar-inverse .navbar-nav .open .dropdown-menu > .active > a:focus {\n    color: #fff;\n    background-color: #080808;\n  }\n  .navbar-inverse .navbar-nav .open .dropdown-menu > .disabled > a,\n  .navbar-inverse .navbar-nav .open .dropdown-menu > .disabled > a:hover,\n  .navbar-inverse .navbar-nav .open .dropdown-menu > .disabled > a:focus {\n    color: #444;\n    background-color: transparent;\n  }\n}\n.navbar-inverse .navbar-link {\n  color: #9d9d9d;\n}\n.navbar-inverse .navbar-link:hover {\n  color: #fff;\n}\n.navbar-inverse .btn-link {\n  color: #9d9d9d;\n}\n.navbar-inverse .btn-link:hover,\n.navbar-inverse .btn-link:focus {\n  color: #fff;\n}\n.navbar-inverse .btn-link[disabled]:hover,\nfieldset[disabled] .navbar-inverse .btn-link:hover,\n.navbar-inverse .btn-link[disabled]:focus,\nfieldset[disabled] .navbar-inverse .btn-link:focus {\n  color: #444;\n}\n.breadcrumb {\n  padding: 8px 15px;\n  margin-bottom: 20px;\n  list-style: none;\n  background-color: #f5f5f5;\n  border-radius: 4px;\n}\n.breadcrumb > li {\n  display: inline-block;\n}\n.breadcrumb > li + li:before {\n  padding: 0 5px;\n  color: #ccc;\n  content: \"/\\00a0\";\n}\n.breadcrumb > .active {\n  color: #777;\n}\n.pagination {\n  display: inline-block;\n  padding-left: 0;\n  margin: 20px 0;\n  border-radius: 4px;\n}\n.pagination > li {\n  display: inline;\n}\n.pagination > li > a,\n.pagination > li > span {\n  position: relative;\n  float: left;\n  padding: 6px 12px;\n  margin-left: -1px;\n  line-height: 1.42857143;\n  color: #337ab7;\n  text-decoration: none;\n  background-color: #fff;\n  border: 1px solid #ddd;\n}\n.pagination > li:first-child > a,\n.pagination > li:first-child > span {\n  margin-left: 0;\n  border-top-left-radius: 4px;\n  border-bottom-left-radius: 4px;\n}\n.pagination > li:last-child > a,\n.pagination > li:last-child > span {\n  border-top-right-radius: 4px;\n  border-bottom-right-radius: 4px;\n}\n.pagination > li > a:hover,\n.pagination > li > span:hover,\n.pagination > li > a:focus,\n.pagination > li > span:focus {\n  z-index: 2;\n  color: #23527c;\n  background-color: #eee;\n  border-color: #ddd;\n}\n.pagination > .active > a,\n.pagination > .active > span,\n.pagination > .active > a:hover,\n.pagination > .active > span:hover,\n.pagination > .active > a:focus,\n.pagination > .active > span:focus {\n  z-index: 3;\n  color: #fff;\n  cursor: default;\n  background-color: #337ab7;\n  border-color: #337ab7;\n}\n.pagination > .disabled > span,\n.pagination > .disabled > span:hover,\n.pagination > .disabled > span:focus,\n.pagination > .disabled > a,\n.pagination > .disabled > a:hover,\n.pagination > .disabled > a:focus {\n  color: #777;\n  cursor: not-allowed;\n  background-color: #fff;\n  border-color: #ddd;\n}\n.pagination-lg > li > a,\n.pagination-lg > li > span {\n  padding: 10px 16px;\n  font-size: 18px;\n  line-height: 1.3333333;\n}\n.pagination-lg > li:first-child > a,\n.pagination-lg > li:first-child > span {\n  border-top-left-radius: 6px;\n  border-bottom-left-radius: 6px;\n}\n.pagination-lg > li:last-child > a,\n.pagination-lg > li:last-child > span {\n  border-top-right-radius: 6px;\n  border-bottom-right-radius: 6px;\n}\n.pagination-sm > li > a,\n.pagination-sm > li > span {\n  padding: 5px 10px;\n  font-size: 12px;\n  line-height: 1.5;\n}\n.pagination-sm > li:first-child > a,\n.pagination-sm > li:first-child > span {\n  border-top-left-radius: 3px;\n  border-bottom-left-radius: 3px;\n}\n.pagination-sm > li:last-child > a,\n.pagination-sm > li:last-child > span {\n  border-top-right-radius: 3px;\n  border-bottom-right-radius: 3px;\n}\n.pager {\n  padding-left: 0;\n  margin: 20px 0;\n  text-align: center;\n  list-style: none;\n}\n.pager li {\n  display: inline;\n}\n.pager li > a,\n.pager li > span {\n  display: inline-block;\n  padding: 5px 14px;\n  background-color: #fff;\n  border: 1px solid #ddd;\n  border-radius: 15px;\n}\n.pager li > a:hover,\n.pager li > a:focus {\n  text-decoration: none;\n  background-color: #eee;\n}\n.pager .next > a,\n.pager .next > span {\n  float: right;\n}\n.pager .previous > a,\n.pager .previous > span {\n  float: left;\n}\n.pager .disabled > a,\n.pager .disabled > a:hover,\n.pager .disabled > a:focus,\n.pager .disabled > span {\n  color: #777;\n  cursor: not-allowed;\n  background-color: #fff;\n}\n.label {\n  display: inline;\n  padding: .2em .6em .3em;\n  font-size: 75%;\n  font-weight: bold;\n  line-height: 1;\n  color: #fff;\n  text-align: center;\n  white-space: nowrap;\n  vertical-align: baseline;\n  border-radius: .25em;\n}\na.label:hover,\na.label:focus {\n  color: #fff;\n  text-decoration: none;\n  cursor: pointer;\n}\n.label:empty {\n  display: none;\n}\n.btn .label {\n  position: relative;\n  top: -1px;\n}\n.label-default {\n  background-color: #777;\n}\n.label-default[href]:hover,\n.label-default[href]:focus {\n  background-color: #5e5e5e;\n}\n.label-primary {\n  background-color: #337ab7;\n}\n.label-primary[href]:hover,\n.label-primary[href]:focus {\n  background-color: #286090;\n}\n.label-success {\n  background-color: #5cb85c;\n}\n.label-success[href]:hover,\n.label-success[href]:focus {\n  background-color: #449d44;\n}\n.label-info {\n  background-color: #5bc0de;\n}\n.label-info[href]:hover,\n.label-info[href]:focus {\n  background-color: #31b0d5;\n}\n.label-warning {\n  background-color: #f0ad4e;\n}\n.label-warning[href]:hover,\n.label-warning[href]:focus {\n  background-color: #ec971f;\n}\n.label-danger {\n  background-color: #d9534f;\n}\n.label-danger[href]:hover,\n.label-danger[href]:focus {\n  background-color: #c9302c;\n}\n.badge {\n  display: inline-block;\n  min-width: 10px;\n  padding: 3px 7px;\n  font-size: 12px;\n  font-weight: bold;\n  line-height: 1;\n  color: #fff;\n  text-align: center;\n  white-space: nowrap;\n  vertical-align: middle;\n  background-color: #777;\n  border-radius: 10px;\n}\n.badge:empty {\n  display: none;\n}\n.btn .badge {\n  position: relative;\n  top: -1px;\n}\n.btn-xs .badge,\n.btn-group-xs > .btn .badge {\n  top: 0;\n  padding: 1px 5px;\n}\na.badge:hover,\na.badge:focus {\n  color: #fff;\n  text-decoration: none;\n  cursor: pointer;\n}\n.list-group-item.active > .badge,\n.nav-pills > .active > a > .badge {\n  color: #337ab7;\n  background-color: #fff;\n}\n.list-group-item > .badge {\n  float: right;\n}\n.list-group-item > .badge + .badge {\n  margin-right: 5px;\n}\n.nav-pills > li > a > .badge {\n  margin-left: 3px;\n}\n.jumbotron {\n  padding-top: 30px;\n  padding-bottom: 30px;\n  margin-bottom: 30px;\n  color: inherit;\n  background-color: #eee;\n}\n.jumbotron h1,\n.jumbotron .h1 {\n  color: inherit;\n}\n.jumbotron p {\n  margin-bottom: 15px;\n  font-size: 21px;\n  font-weight: 200;\n}\n.jumbotron > hr {\n  border-top-color: #d5d5d5;\n}\n.container .jumbotron,\n.container-fluid .jumbotron {\n  padding-right: 15px;\n  padding-left: 15px;\n  border-radius: 6px;\n}\n.jumbotron .container {\n  max-width: 100%;\n}\n@media screen and (min-width: 768px) {\n  .jumbotron {\n    padding-top: 48px;\n    padding-bottom: 48px;\n  }\n  .container .jumbotron,\n  .container-fluid .jumbotron {\n    padding-right: 60px;\n    padding-left: 60px;\n  }\n  .jumbotron h1,\n  .jumbotron .h1 {\n    font-size: 63px;\n  }\n}\n.thumbnail {\n  display: block;\n  padding: 4px;\n  margin-bottom: 20px;\n  line-height: 1.42857143;\n  background-color: #fff;\n  border: 1px solid #ddd;\n  border-radius: 4px;\n  -webkit-transition: border .2s ease-in-out;\n       -o-transition: border .2s ease-in-out;\n          transition: border .2s ease-in-out;\n}\n.thumbnail > img,\n.thumbnail a > img {\n  margin-right: auto;\n  margin-left: auto;\n}\na.thumbnail:hover,\na.thumbnail:focus,\na.thumbnail.active {\n  border-color: #337ab7;\n}\n.thumbnail .caption {\n  padding: 9px;\n  color: #333;\n}\n.alert {\n  padding: 15px;\n  margin-bottom: 20px;\n  border: 1px solid transparent;\n  border-radius: 4px;\n}\n.alert h4 {\n  margin-top: 0;\n  color: inherit;\n}\n.alert .alert-link {\n  font-weight: bold;\n}\n.alert > p,\n.alert > ul {\n  margin-bottom: 0;\n}\n.alert > p + p {\n  margin-top: 5px;\n}\n.alert-dismissable,\n.alert-dismissible {\n  padding-right: 35px;\n}\n.alert-dismissable .close,\n.alert-dismissible .close {\n  position: relative;\n  top: -2px;\n  right: -21px;\n  color: inherit;\n}\n.alert-success {\n  color: #3c763d;\n  background-color: #dff0d8;\n  border-color: #d6e9c6;\n}\n.alert-success hr {\n  border-top-color: #c9e2b3;\n}\n.alert-success .alert-link {\n  color: #2b542c;\n}\n.alert-info {\n  color: #31708f;\n  background-color: #d9edf7;\n  border-color: #bce8f1;\n}\n.alert-info hr {\n  border-top-color: #a6e1ec;\n}\n.alert-info .alert-link {\n  color: #245269;\n}\n.alert-warning {\n  color: #8a6d3b;\n  background-color: #fcf8e3;\n  border-color: #faebcc;\n}\n.alert-warning hr {\n  border-top-color: #f7e1b5;\n}\n.alert-warning .alert-link {\n  color: #66512c;\n}\n.alert-danger {\n  color: #a94442;\n  background-color: #f2dede;\n  border-color: #ebccd1;\n}\n.alert-danger hr {\n  border-top-color: #e4b9c0;\n}\n.alert-danger .alert-link {\n  color: #843534;\n}\n@-webkit-keyframes progress-bar-stripes {\n  from {\n    background-position: 40px 0;\n  }\n  to {\n    background-position: 0 0;\n  }\n}\n@-o-keyframes progress-bar-stripes {\n  from {\n    background-position: 40px 0;\n  }\n  to {\n    background-position: 0 0;\n  }\n}\n@keyframes progress-bar-stripes {\n  from {\n    background-position: 40px 0;\n  }\n  to {\n    background-position: 0 0;\n  }\n}\n.progress {\n  height: 20px;\n  margin-bottom: 20px;\n  overflow: hidden;\n  background-color: #f5f5f5;\n  border-radius: 4px;\n  -webkit-box-shadow: inset 0 1px 2px rgba(0, 0, 0, .1);\n          box-shadow: inset 0 1px 2px rgba(0, 0, 0, .1);\n}\n.progress-bar {\n  float: left;\n  width: 0;\n  height: 100%;\n  font-size: 12px;\n  line-height: 20px;\n  color: #fff;\n  text-align: center;\n  background-color: #337ab7;\n  -webkit-box-shadow: inset 0 -1px 0 rgba(0, 0, 0, .15);\n          box-shadow: inset 0 -1px 0 rgba(0, 0, 0, .15);\n  -webkit-transition: width .6s ease;\n       -o-transition: width .6s ease;\n          transition: width .6s ease;\n}\n.progress-striped .progress-bar,\n.progress-bar-striped {\n  background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);\n  background-image:      -o-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);\n  background-image:         linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);\n  -webkit-background-size: 40px 40px;\n          background-size: 40px 40px;\n}\n.progress.active .progress-bar,\n.progress-bar.active {\n  -webkit-animation: progress-bar-stripes 2s linear infinite;\n       -o-animation: progress-bar-stripes 2s linear infinite;\n          animation: progress-bar-stripes 2s linear infinite;\n}\n.progress-bar-success {\n  background-color: #5cb85c;\n}\n.progress-striped .progress-bar-success {\n  background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);\n  background-image:      -o-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);\n  background-image:         linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);\n}\n.progress-bar-info {\n  background-color: #5bc0de;\n}\n.progress-striped .progress-bar-info {\n  background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);\n  background-image:      -o-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);\n  background-image:         linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);\n}\n.progress-bar-warning {\n  background-color: #f0ad4e;\n}\n.progress-striped .progress-bar-warning {\n  background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);\n  background-image:      -o-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);\n  background-image:         linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);\n}\n.progress-bar-danger {\n  background-color: #d9534f;\n}\n.progress-striped .progress-bar-danger {\n  background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);\n  background-image:      -o-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);\n  background-image:         linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);\n}\n.media {\n  margin-top: 15px;\n}\n.media:first-child {\n  margin-top: 0;\n}\n.media,\n.media-body {\n  overflow: hidden;\n  zoom: 1;\n}\n.media-body {\n  width: 10000px;\n}\n.media-object {\n  display: block;\n}\n.media-object.img-thumbnail {\n  max-width: none;\n}\n.media-right,\n.media > .pull-right {\n  padding-left: 10px;\n}\n.media-left,\n.media > .pull-left {\n  padding-right: 10px;\n}\n.media-left,\n.media-right,\n.media-body {\n  display: table-cell;\n  vertical-align: top;\n}\n.media-middle {\n  vertical-align: middle;\n}\n.media-bottom {\n  vertical-align: bottom;\n}\n.media-heading {\n  margin-top: 0;\n  margin-bottom: 5px;\n}\n.media-list {\n  padding-left: 0;\n  list-style: none;\n}\n.list-group {\n  padding-left: 0;\n  margin-bottom: 20px;\n}\n.list-group-item {\n  position: relative;\n  display: block;\n  padding: 10px 15px;\n  margin-bottom: -1px;\n  background-color: #fff;\n  border: 1px solid #ddd;\n}\n.list-group-item:first-child {\n  border-top-left-radius: 4px;\n  border-top-right-radius: 4px;\n}\n.list-group-item:last-child {\n  margin-bottom: 0;\n  border-bottom-right-radius: 4px;\n  border-bottom-left-radius: 4px;\n}\na.list-group-item,\nbutton.list-group-item {\n  color: #555;\n}\na.list-group-item .list-group-item-heading,\nbutton.list-group-item .list-group-item-heading {\n  color: #333;\n}\na.list-group-item:hover,\nbutton.list-group-item:hover,\na.list-group-item:focus,\nbutton.list-group-item:focus {\n  color: #555;\n  text-decoration: none;\n  background-color: #f5f5f5;\n}\nbutton.list-group-item {\n  width: 100%;\n  text-align: left;\n}\n.list-group-item.disabled,\n.list-group-item.disabled:hover,\n.list-group-item.disabled:focus {\n  color: #777;\n  cursor: not-allowed;\n  background-color: #eee;\n}\n.list-group-item.disabled .list-group-item-heading,\n.list-group-item.disabled:hover .list-group-item-heading,\n.list-group-item.disabled:focus .list-group-item-heading {\n  color: inherit;\n}\n.list-group-item.disabled .list-group-item-text,\n.list-group-item.disabled:hover .list-group-item-text,\n.list-group-item.disabled:focus .list-group-item-text {\n  color: #777;\n}\n.list-group-item.active,\n.list-group-item.active:hover,\n.list-group-item.active:focus {\n  z-index: 2;\n  color: #fff;\n  background-color: #337ab7;\n  border-color: #337ab7;\n}\n.list-group-item.active .list-group-item-heading,\n.list-group-item.active:hover .list-group-item-heading,\n.list-group-item.active:focus .list-group-item-heading,\n.list-group-item.active .list-group-item-heading > small,\n.list-group-item.active:hover .list-group-item-heading > small,\n.list-group-item.active:focus .list-group-item-heading > small,\n.list-group-item.active .list-group-item-heading > .small,\n.list-group-item.active:hover .list-group-item-heading > .small,\n.list-group-item.active:focus .list-group-item-heading > .small {\n  color: inherit;\n}\n.list-group-item.active .list-group-item-text,\n.list-group-item.active:hover .list-group-item-text,\n.list-group-item.active:focus .list-group-item-text {\n  color: #c7ddef;\n}\n.list-group-item-success {\n  color: #3c763d;\n  background-color: #dff0d8;\n}\na.list-group-item-success,\nbutton.list-group-item-success {\n  color: #3c763d;\n}\na.list-group-item-success .list-group-item-heading,\nbutton.list-group-item-success .list-group-item-heading {\n  color: inherit;\n}\na.list-group-item-success:hover,\nbutton.list-group-item-success:hover,\na.list-group-item-success:focus,\nbutton.list-group-item-success:focus {\n  color: #3c763d;\n  background-color: #d0e9c6;\n}\na.list-group-item-success.active,\nbutton.list-group-item-success.active,\na.list-group-item-success.active:hover,\nbutton.list-group-item-success.active:hover,\na.list-group-item-success.active:focus,\nbutton.list-group-item-success.active:focus {\n  color: #fff;\n  background-color: #3c763d;\n  border-color: #3c763d;\n}\n.list-group-item-info {\n  color: #31708f;\n  background-color: #d9edf7;\n}\na.list-group-item-info,\nbutton.list-group-item-info {\n  color: #31708f;\n}\na.list-group-item-info .list-group-item-heading,\nbutton.list-group-item-info .list-group-item-heading {\n  color: inherit;\n}\na.list-group-item-info:hover,\nbutton.list-group-item-info:hover,\na.list-group-item-info:focus,\nbutton.list-group-item-info:focus {\n  color: #31708f;\n  background-color: #c4e3f3;\n}\na.list-group-item-info.active,\nbutton.list-group-item-info.active,\na.list-group-item-info.active:hover,\nbutton.list-group-item-info.active:hover,\na.list-group-item-info.active:focus,\nbutton.list-group-item-info.active:focus {\n  color: #fff;\n  background-color: #31708f;\n  border-color: #31708f;\n}\n.list-group-item-warning {\n  color: #8a6d3b;\n  background-color: #fcf8e3;\n}\na.list-group-item-warning,\nbutton.list-group-item-warning {\n  color: #8a6d3b;\n}\na.list-group-item-warning .list-group-item-heading,\nbutton.list-group-item-warning .list-group-item-heading {\n  color: inherit;\n}\na.list-group-item-warning:hover,\nbutton.list-group-item-warning:hover,\na.list-group-item-warning:focus,\nbutton.list-group-item-warning:focus {\n  color: #8a6d3b;\n  background-color: #faf2cc;\n}\na.list-group-item-warning.active,\nbutton.list-group-item-warning.active,\na.list-group-item-warning.active:hover,\nbutton.list-group-item-warning.active:hover,\na.list-group-item-warning.active:focus,\nbutton.list-group-item-warning.active:focus {\n  color: #fff;\n  background-color: #8a6d3b;\n  border-color: #8a6d3b;\n}\n.list-group-item-danger {\n  color: #a94442;\n  background-color: #f2dede;\n}\na.list-group-item-danger,\nbutton.list-group-item-danger {\n  color: #a94442;\n}\na.list-group-item-danger .list-group-item-heading,\nbutton.list-group-item-danger .list-group-item-heading {\n  color: inherit;\n}\na.list-group-item-danger:hover,\nbutton.list-group-item-danger:hover,\na.list-group-item-danger:focus,\nbutton.list-group-item-danger:focus {\n  color: #a94442;\n  background-color: #ebcccc;\n}\na.list-group-item-danger.active,\nbutton.list-group-item-danger.active,\na.list-group-item-danger.active:hover,\nbutton.list-group-item-danger.active:hover,\na.list-group-item-danger.active:focus,\nbutton.list-group-item-danger.active:focus {\n  color: #fff;\n  background-color: #a94442;\n  border-color: #a94442;\n}\n.list-group-item-heading {\n  margin-top: 0;\n  margin-bottom: 5px;\n}\n.list-group-item-text {\n  margin-bottom: 0;\n  line-height: 1.3;\n}\n.panel {\n  margin-bottom: 20px;\n  background-color: #fff;\n  border: 1px solid transparent;\n  border-radius: 4px;\n  -webkit-box-shadow: 0 1px 1px rgba(0, 0, 0, .05);\n          box-shadow: 0 1px 1px rgba(0, 0, 0, .05);\n}\n.panel-body {\n  padding: 15px;\n}\n.panel-heading {\n  padding: 10px 15px;\n  border-bottom: 1px solid transparent;\n  border-top-left-radius: 3px;\n  border-top-right-radius: 3px;\n}\n.panel-heading > .dropdown .dropdown-toggle {\n  color: inherit;\n}\n.panel-title {\n  margin-top: 0;\n  margin-bottom: 0;\n  font-size: 16px;\n  color: inherit;\n}\n.panel-title > a,\n.panel-title > small,\n.panel-title > .small,\n.panel-title > small > a,\n.panel-title > .small > a {\n  color: inherit;\n}\n.panel-footer {\n  padding: 10px 15px;\n  background-color: #f5f5f5;\n  border-top: 1px solid #ddd;\n  border-bottom-right-radius: 3px;\n  border-bottom-left-radius: 3px;\n}\n.panel > .list-group,\n.panel > .panel-collapse > .list-group {\n  margin-bottom: 0;\n}\n.panel > .list-group .list-group-item,\n.panel > .panel-collapse > .list-group .list-group-item {\n  border-width: 1px 0;\n  border-radius: 0;\n}\n.panel > .list-group:first-child .list-group-item:first-child,\n.panel > .panel-collapse > .list-group:first-child .list-group-item:first-child {\n  border-top: 0;\n  border-top-left-radius: 3px;\n  border-top-right-radius: 3px;\n}\n.panel > .list-group:last-child .list-group-item:last-child,\n.panel > .panel-collapse > .list-group:last-child .list-group-item:last-child {\n  border-bottom: 0;\n  border-bottom-right-radius: 3px;\n  border-bottom-left-radius: 3px;\n}\n.panel > .panel-heading + .panel-collapse > .list-group .list-group-item:first-child {\n  border-top-left-radius: 0;\n  border-top-right-radius: 0;\n}\n.panel-heading + .list-group .list-group-item:first-child {\n  border-top-width: 0;\n}\n.list-group + .panel-footer {\n  border-top-width: 0;\n}\n.panel > .table,\n.panel > .table-responsive > .table,\n.panel > .panel-collapse > .table {\n  margin-bottom: 0;\n}\n.panel > .table caption,\n.panel > .table-responsive > .table caption,\n.panel > .panel-collapse > .table caption {\n  padding-right: 15px;\n  padding-left: 15px;\n}\n.panel > .table:first-child,\n.panel > .table-responsive:first-child > .table:first-child {\n  border-top-left-radius: 3px;\n  border-top-right-radius: 3px;\n}\n.panel > .table:first-child > thead:first-child > tr:first-child,\n.panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child,\n.panel > .table:first-child > tbody:first-child > tr:first-child,\n.panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child {\n  border-top-left-radius: 3px;\n  border-top-right-radius: 3px;\n}\n.panel > .table:first-child > thead:first-child > tr:first-child td:first-child,\n.panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child td:first-child,\n.panel > .table:first-child > tbody:first-child > tr:first-child td:first-child,\n.panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child td:first-child,\n.panel > .table:first-child > thead:first-child > tr:first-child th:first-child,\n.panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child th:first-child,\n.panel > .table:first-child > tbody:first-child > tr:first-child th:first-child,\n.panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child th:first-child {\n  border-top-left-radius: 3px;\n}\n.panel > .table:first-child > thead:first-child > tr:first-child td:last-child,\n.panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child td:last-child,\n.panel > .table:first-child > tbody:first-child > tr:first-child td:last-child,\n.panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child td:last-child,\n.panel > .table:first-child > thead:first-child > tr:first-child th:last-child,\n.panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child th:last-child,\n.panel > .table:first-child > tbody:first-child > tr:first-child th:last-child,\n.panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child th:last-child {\n  border-top-right-radius: 3px;\n}\n.panel > .table:last-child,\n.panel > .table-responsive:last-child > .table:last-child {\n  border-bottom-right-radius: 3px;\n  border-bottom-left-radius: 3px;\n}\n.panel > .table:last-child > tbody:last-child > tr:last-child,\n.panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child,\n.panel > .table:last-child > tfoot:last-child > tr:last-child,\n.panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child {\n  border-bottom-right-radius: 3px;\n  border-bottom-left-radius: 3px;\n}\n.panel > .table:last-child > tbody:last-child > tr:last-child td:first-child,\n.panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child td:first-child,\n.panel > .table:last-child > tfoot:last-child > tr:last-child td:first-child,\n.panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child td:first-child,\n.panel > .table:last-child > tbody:last-child > tr:last-child th:first-child,\n.panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child th:first-child,\n.panel > .table:last-child > tfoot:last-child > tr:last-child th:first-child,\n.panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child th:first-child {\n  border-bottom-left-radius: 3px;\n}\n.panel > .table:last-child > tbody:last-child > tr:last-child td:last-child,\n.panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child td:last-child,\n.panel > .table:last-child > tfoot:last-child > tr:last-child td:last-child,\n.panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child td:last-child,\n.panel > .table:last-child > tbody:last-child > tr:last-child th:last-child,\n.panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child th:last-child,\n.panel > .table:last-child > tfoot:last-child > tr:last-child th:last-child,\n.panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child th:last-child {\n  border-bottom-right-radius: 3px;\n}\n.panel > .panel-body + .table,\n.panel > .panel-body + .table-responsive,\n.panel > .table + .panel-body,\n.panel > .table-responsive + .panel-body {\n  border-top: 1px solid #ddd;\n}\n.panel > .table > tbody:first-child > tr:first-child th,\n.panel > .table > tbody:first-child > tr:first-child td {\n  border-top: 0;\n}\n.panel > .table-bordered,\n.panel > .table-responsive > .table-bordered {\n  border: 0;\n}\n.panel > .table-bordered > thead > tr > th:first-child,\n.panel > .table-responsive > .table-bordered > thead > tr > th:first-child,\n.panel > .table-bordered > tbody > tr > th:first-child,\n.panel > .table-responsive > .table-bordered > tbody > tr > th:first-child,\n.panel > .table-bordered > tfoot > tr > th:first-child,\n.panel > .table-responsive > .table-bordered > tfoot > tr > th:first-child,\n.panel > .table-bordered > thead > tr > td:first-child,\n.panel > .table-responsive > .table-bordered > thead > tr > td:first-child,\n.panel > .table-bordered > tbody > tr > td:first-child,\n.panel > .table-responsive > .table-bordered > tbody > tr > td:first-child,\n.panel > .table-bordered > tfoot > tr > td:first-child,\n.panel > .table-responsive > .table-bordered > tfoot > tr > td:first-child {\n  border-left: 0;\n}\n.panel > .table-bordered > thead > tr > th:last-child,\n.panel > .table-responsive > .table-bordered > thead > tr > th:last-child,\n.panel > .table-bordered > tbody > tr > th:last-child,\n.panel > .table-responsive > .table-bordered > tbody > tr > th:last-child,\n.panel > .table-bordered > tfoot > tr > th:last-child,\n.panel > .table-responsive > .table-bordered > tfoot > tr > th:last-child,\n.panel > .table-bordered > thead > tr > td:last-child,\n.panel > .table-responsive > .table-bordered > thead > tr > td:last-child,\n.panel > .table-bordered > tbody > tr > td:last-child,\n.panel > .table-responsive > .table-bordered > tbody > tr > td:last-child,\n.panel > .table-bordered > tfoot > tr > td:last-child,\n.panel > .table-responsive > .table-bordered > tfoot > tr > td:last-child {\n  border-right: 0;\n}\n.panel > .table-bordered > thead > tr:first-child > td,\n.panel > .table-responsive > .table-bordered > thead > tr:first-child > td,\n.panel > .table-bordered > tbody > tr:first-child > td,\n.panel > .table-responsive > .table-bordered > tbody > tr:first-child > td,\n.panel > .table-bordered > thead > tr:first-child > th,\n.panel > .table-responsive > .table-bordered > thead > tr:first-child > th,\n.panel > .table-bordered > tbody > tr:first-child > th,\n.panel > .table-responsive > .table-bordered > tbody > tr:first-child > th {\n  border-bottom: 0;\n}\n.panel > .table-bordered > tbody > tr:last-child > td,\n.panel > .table-responsive > .table-bordered > tbody > tr:last-child > td,\n.panel > .table-bordered > tfoot > tr:last-child > td,\n.panel > .table-responsive > .table-bordered > tfoot > tr:last-child > td,\n.panel > .table-bordered > tbody > tr:last-child > th,\n.panel > .table-responsive > .table-bordered > tbody > tr:last-child > th,\n.panel > .table-bordered > tfoot > tr:last-child > th,\n.panel > .table-responsive > .table-bordered > tfoot > tr:last-child > th {\n  border-bottom: 0;\n}\n.panel > .table-responsive {\n  margin-bottom: 0;\n  border: 0;\n}\n.panel-group {\n  margin-bottom: 20px;\n}\n.panel-group .panel {\n  margin-bottom: 0;\n  border-radius: 4px;\n}\n.panel-group .panel + .panel {\n  margin-top: 5px;\n}\n.panel-group .panel-heading {\n  border-bottom: 0;\n}\n.panel-group .panel-heading + .panel-collapse > .panel-body,\n.panel-group .panel-heading + .panel-collapse > .list-group {\n  border-top: 1px solid #ddd;\n}\n.panel-group .panel-footer {\n  border-top: 0;\n}\n.panel-group .panel-footer + .panel-collapse .panel-body {\n  border-bottom: 1px solid #ddd;\n}\n.panel-default {\n  border-color: #ddd;\n}\n.panel-default > .panel-heading {\n  color: #333;\n  background-color: #f5f5f5;\n  border-color: #ddd;\n}\n.panel-default > .panel-heading + .panel-collapse > .panel-body {\n  border-top-color: #ddd;\n}\n.panel-default > .panel-heading .badge {\n  color: #f5f5f5;\n  background-color: #333;\n}\n.panel-default > .panel-footer + .panel-collapse > .panel-body {\n  border-bottom-color: #ddd;\n}\n.panel-primary {\n  border-color: #337ab7;\n}\n.panel-primary > .panel-heading {\n  color: #fff;\n  background-color: #337ab7;\n  border-color: #337ab7;\n}\n.panel-primary > .panel-heading + .panel-collapse > .panel-body {\n  border-top-color: #337ab7;\n}\n.panel-primary > .panel-heading .badge {\n  color: #337ab7;\n  background-color: #fff;\n}\n.panel-primary > .panel-footer + .panel-collapse > .panel-body {\n  border-bottom-color: #337ab7;\n}\n.panel-success {\n  border-color: #d6e9c6;\n}\n.panel-success > .panel-heading {\n  color: #3c763d;\n  background-color: #dff0d8;\n  border-color: #d6e9c6;\n}\n.panel-success > .panel-heading + .panel-collapse > .panel-body {\n  border-top-color: #d6e9c6;\n}\n.panel-success > .panel-heading .badge {\n  color: #dff0d8;\n  background-color: #3c763d;\n}\n.panel-success > .panel-footer + .panel-collapse > .panel-body {\n  border-bottom-color: #d6e9c6;\n}\n.panel-info {\n  border-color: #bce8f1;\n}\n.panel-info > .panel-heading {\n  color: #31708f;\n  background-color: #d9edf7;\n  border-color: #bce8f1;\n}\n.panel-info > .panel-heading + .panel-collapse > .panel-body {\n  border-top-color: #bce8f1;\n}\n.panel-info > .panel-heading .badge {\n  color: #d9edf7;\n  background-color: #31708f;\n}\n.panel-info > .panel-footer + .panel-collapse > .panel-body {\n  border-bottom-color: #bce8f1;\n}\n.panel-warning {\n  border-color: #faebcc;\n}\n.panel-warning > .panel-heading {\n  color: #8a6d3b;\n  background-color: #fcf8e3;\n  border-color: #faebcc;\n}\n.panel-warning > .panel-heading + .panel-collapse > .panel-body {\n  border-top-color: #faebcc;\n}\n.panel-warning > .panel-heading .badge {\n  color: #fcf8e3;\n  background-color: #8a6d3b;\n}\n.panel-warning > .panel-footer + .panel-collapse > .panel-body {\n  border-bottom-color: #faebcc;\n}\n.panel-danger {\n  border-color: #ebccd1;\n}\n.panel-danger > .panel-heading {\n  color: #a94442;\n  background-color: #f2dede;\n  border-color: #ebccd1;\n}\n.panel-danger > .panel-heading + .panel-collapse > .panel-body {\n  border-top-color: #ebccd1;\n}\n.panel-danger > .panel-heading .badge {\n  color: #f2dede;\n  background-color: #a94442;\n}\n.panel-danger > .panel-footer + .panel-collapse > .panel-body {\n  border-bottom-color: #ebccd1;\n}\n.embed-responsive {\n  position: relative;\n  display: block;\n  height: 0;\n  padding: 0;\n  overflow: hidden;\n}\n.embed-responsive .embed-responsive-item,\n.embed-responsive iframe,\n.embed-responsive embed,\n.embed-responsive object,\n.embed-responsive video {\n  position: absolute;\n  top: 0;\n  bottom: 0;\n  left: 0;\n  width: 100%;\n  height: 100%;\n  border: 0;\n}\n.embed-responsive-16by9 {\n  padding-bottom: 56.25%;\n}\n.embed-responsive-4by3 {\n  padding-bottom: 75%;\n}\n.well {\n  min-height: 20px;\n  padding: 19px;\n  margin-bottom: 20px;\n  background-color: #f5f5f5;\n  border: 1px solid #e3e3e3;\n  border-radius: 4px;\n  -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .05);\n          box-shadow: inset 0 1px 1px rgba(0, 0, 0, .05);\n}\n.well blockquote {\n  border-color: #ddd;\n  border-color: rgba(0, 0, 0, .15);\n}\n.well-lg {\n  padding: 24px;\n  border-radius: 6px;\n}\n.well-sm {\n  padding: 9px;\n  border-radius: 3px;\n}\n.close {\n  float: right;\n  font-size: 21px;\n  font-weight: bold;\n  line-height: 1;\n  color: #000;\n  text-shadow: 0 1px 0 #fff;\n  filter: alpha(opacity=20);\n  opacity: .2;\n}\n.close:hover,\n.close:focus {\n  color: #000;\n  text-decoration: none;\n  cursor: pointer;\n  filter: alpha(opacity=50);\n  opacity: .5;\n}\nbutton.close {\n  -webkit-appearance: none;\n  padding: 0;\n  cursor: pointer;\n  background: transparent;\n  border: 0;\n}\n.modal-open {\n  overflow: hidden;\n}\n.modal {\n  position: fixed;\n  top: 0;\n  right: 0;\n  bottom: 0;\n  left: 0;\n  z-index: 1050;\n  display: none;\n  overflow: hidden;\n  -webkit-overflow-scrolling: touch;\n  outline: 0;\n}\n.modal.fade .modal-dialog {\n  -webkit-transition: -webkit-transform .3s ease-out;\n       -o-transition:      -o-transform .3s ease-out;\n          transition:         transform .3s ease-out;\n  -webkit-transform: translate(0, -25%);\n      -ms-transform: translate(0, -25%);\n       -o-transform: translate(0, -25%);\n          transform: translate(0, -25%);\n}\n.modal.in .modal-dialog {\n  -webkit-transform: translate(0, 0);\n      -ms-transform: translate(0, 0);\n       -o-transform: translate(0, 0);\n          transform: translate(0, 0);\n}\n.modal-open .modal {\n  overflow-x: hidden;\n  overflow-y: auto;\n}\n.modal-dialog {\n  position: relative;\n  width: auto;\n  margin: 10px;\n}\n.modal-content {\n  position: relative;\n  background-color: #fff;\n  -webkit-background-clip: padding-box;\n          background-clip: padding-box;\n  border: 1px solid #999;\n  border: 1px solid rgba(0, 0, 0, .2);\n  border-radius: 6px;\n  outline: 0;\n  -webkit-box-shadow: 0 3px 9px rgba(0, 0, 0, .5);\n          box-shadow: 0 3px 9px rgba(0, 0, 0, .5);\n}\n.modal-backdrop {\n  position: fixed;\n  top: 0;\n  right: 0;\n  bottom: 0;\n  left: 0;\n  z-index: 1040;\n  background-color: #000;\n}\n.modal-backdrop.fade {\n  filter: alpha(opacity=0);\n  opacity: 0;\n}\n.modal-backdrop.in {\n  filter: alpha(opacity=50);\n  opacity: .5;\n}\n.modal-header {\n  padding: 15px;\n  border-bottom: 1px solid #e5e5e5;\n}\n.modal-header .close {\n  margin-top: -2px;\n}\n.modal-title {\n  margin: 0;\n  line-height: 1.42857143;\n}\n.modal-body {\n  position: relative;\n  padding: 15px;\n}\n.modal-footer {\n  padding: 15px;\n  text-align: right;\n  border-top: 1px solid #e5e5e5;\n}\n.modal-footer .btn + .btn {\n  margin-bottom: 0;\n  margin-left: 5px;\n}\n.modal-footer .btn-group .btn + .btn {\n  margin-left: -1px;\n}\n.modal-footer .btn-block + .btn-block {\n  margin-left: 0;\n}\n.modal-scrollbar-measure {\n  position: absolute;\n  top: -9999px;\n  width: 50px;\n  height: 50px;\n  overflow: scroll;\n}\n@media (min-width: 768px) {\n  .modal-dialog {\n    width: 600px;\n    margin: 30px auto;\n  }\n  .modal-content {\n    -webkit-box-shadow: 0 5px 15px rgba(0, 0, 0, .5);\n            box-shadow: 0 5px 15px rgba(0, 0, 0, .5);\n  }\n  .modal-sm {\n    width: 300px;\n  }\n}\n@media (min-width: 992px) {\n  .modal-lg {\n    width: 900px;\n  }\n}\n.tooltip {\n  position: absolute;\n  z-index: 1070;\n  display: block;\n  font-family: \"Helvetica Neue\", Helvetica, Arial, sans-serif;\n  font-size: 12px;\n  font-style: normal;\n  font-weight: normal;\n  line-height: 1.42857143;\n  text-align: left;\n  text-align: start;\n  text-decoration: none;\n  text-shadow: none;\n  text-transform: none;\n  letter-spacing: normal;\n  word-break: normal;\n  word-spacing: normal;\n  word-wrap: normal;\n  white-space: normal;\n  filter: alpha(opacity=0);\n  opacity: 0;\n\n  line-break: auto;\n}\n.tooltip.in {\n  filter: alpha(opacity=90);\n  opacity: .9;\n}\n.tooltip.top {\n  padding: 5px 0;\n  margin-top: -3px;\n}\n.tooltip.right {\n  padding: 0 5px;\n  margin-left: 3px;\n}\n.tooltip.bottom {\n  padding: 5px 0;\n  margin-top: 3px;\n}\n.tooltip.left {\n  padding: 0 5px;\n  margin-left: -3px;\n}\n.tooltip-inner {\n  max-width: 200px;\n  padding: 3px 8px;\n  color: #fff;\n  text-align: center;\n  background-color: #000;\n  border-radius: 4px;\n}\n.tooltip-arrow {\n  position: absolute;\n  width: 0;\n  height: 0;\n  border-color: transparent;\n  border-style: solid;\n}\n.tooltip.top .tooltip-arrow {\n  bottom: 0;\n  left: 50%;\n  margin-left: -5px;\n  border-width: 5px 5px 0;\n  border-top-color: #000;\n}\n.tooltip.top-left .tooltip-arrow {\n  right: 5px;\n  bottom: 0;\n  margin-bottom: -5px;\n  border-width: 5px 5px 0;\n  border-top-color: #000;\n}\n.tooltip.top-right .tooltip-arrow {\n  bottom: 0;\n  left: 5px;\n  margin-bottom: -5px;\n  border-width: 5px 5px 0;\n  border-top-color: #000;\n}\n.tooltip.right .tooltip-arrow {\n  top: 50%;\n  left: 0;\n  margin-top: -5px;\n  border-width: 5px 5px 5px 0;\n  border-right-color: #000;\n}\n.tooltip.left .tooltip-arrow {\n  top: 50%;\n  right: 0;\n  margin-top: -5px;\n  border-width: 5px 0 5px 5px;\n  border-left-color: #000;\n}\n.tooltip.bottom .tooltip-arrow {\n  top: 0;\n  left: 50%;\n  margin-left: -5px;\n  border-width: 0 5px 5px;\n  border-bottom-color: #000;\n}\n.tooltip.bottom-left .tooltip-arrow {\n  top: 0;\n  right: 5px;\n  margin-top: -5px;\n  border-width: 0 5px 5px;\n  border-bottom-color: #000;\n}\n.tooltip.bottom-right .tooltip-arrow {\n  top: 0;\n  left: 5px;\n  margin-top: -5px;\n  border-width: 0 5px 5px;\n  border-bottom-color: #000;\n}\n.popover {\n  position: absolute;\n  top: 0;\n  left: 0;\n  z-index: 1060;\n  display: none;\n  max-width: 276px;\n  padding: 1px;\n  font-family: \"Helvetica Neue\", Helvetica, Arial, sans-serif;\n  font-size: 14px;\n  font-style: normal;\n  font-weight: normal;\n  line-height: 1.42857143;\n  text-align: left;\n  text-align: start;\n  text-decoration: none;\n  text-shadow: none;\n  text-transform: none;\n  letter-spacing: normal;\n  word-break: normal;\n  word-spacing: normal;\n  word-wrap: normal;\n  white-space: normal;\n  background-color: #fff;\n  -webkit-background-clip: padding-box;\n          background-clip: padding-box;\n  border: 1px solid #ccc;\n  border: 1px solid rgba(0, 0, 0, .2);\n  border-radius: 6px;\n  -webkit-box-shadow: 0 5px 10px rgba(0, 0, 0, .2);\n          box-shadow: 0 5px 10px rgba(0, 0, 0, .2);\n\n  line-break: auto;\n}\n.popover.top {\n  margin-top: -10px;\n}\n.popover.right {\n  margin-left: 10px;\n}\n.popover.bottom {\n  margin-top: 10px;\n}\n.popover.left {\n  margin-left: -10px;\n}\n.popover-title {\n  padding: 8px 14px;\n  margin: 0;\n  font-size: 14px;\n  background-color: #f7f7f7;\n  border-bottom: 1px solid #ebebeb;\n  border-radius: 5px 5px 0 0;\n}\n.popover-content {\n  padding: 9px 14px;\n}\n.popover > .arrow,\n.popover > .arrow:after {\n  position: absolute;\n  display: block;\n  width: 0;\n  height: 0;\n  border-color: transparent;\n  border-style: solid;\n}\n.popover > .arrow {\n  border-width: 11px;\n}\n.popover > .arrow:after {\n  content: \"\";\n  border-width: 10px;\n}\n.popover.top > .arrow {\n  bottom: -11px;\n  left: 50%;\n  margin-left: -11px;\n  border-top-color: #999;\n  border-top-color: rgba(0, 0, 0, .25);\n  border-bottom-width: 0;\n}\n.popover.top > .arrow:after {\n  bottom: 1px;\n  margin-left: -10px;\n  content: \" \";\n  border-top-color: #fff;\n  border-bottom-width: 0;\n}\n.popover.right > .arrow {\n  top: 50%;\n  left: -11px;\n  margin-top: -11px;\n  border-right-color: #999;\n  border-right-color: rgba(0, 0, 0, .25);\n  border-left-width: 0;\n}\n.popover.right > .arrow:after {\n  bottom: -10px;\n  left: 1px;\n  content: \" \";\n  border-right-color: #fff;\n  border-left-width: 0;\n}\n.popover.bottom > .arrow {\n  top: -11px;\n  left: 50%;\n  margin-left: -11px;\n  border-top-width: 0;\n  border-bottom-color: #999;\n  border-bottom-color: rgba(0, 0, 0, .25);\n}\n.popover.bottom > .arrow:after {\n  top: 1px;\n  margin-left: -10px;\n  content: \" \";\n  border-top-width: 0;\n  border-bottom-color: #fff;\n}\n.popover.left > .arrow {\n  top: 50%;\n  right: -11px;\n  margin-top: -11px;\n  border-right-width: 0;\n  border-left-color: #999;\n  border-left-color: rgba(0, 0, 0, .25);\n}\n.popover.left > .arrow:after {\n  right: 1px;\n  bottom: -10px;\n  content: \" \";\n  border-right-width: 0;\n  border-left-color: #fff;\n}\n.carousel {\n  position: relative;\n}\n.carousel-inner {\n  position: relative;\n  width: 100%;\n  overflow: hidden;\n}\n.carousel-inner > .item {\n  position: relative;\n  display: none;\n  -webkit-transition: .6s ease-in-out left;\n       -o-transition: .6s ease-in-out left;\n          transition: .6s ease-in-out left;\n}\n.carousel-inner > .item > img,\n.carousel-inner > .item > a > img {\n  line-height: 1;\n}\n@media all and (transform-3d), (-webkit-transform-3d) {\n  .carousel-inner > .item {\n    -webkit-transition: -webkit-transform .6s ease-in-out;\n         -o-transition:      -o-transform .6s ease-in-out;\n            transition:         transform .6s ease-in-out;\n\n    -webkit-backface-visibility: hidden;\n            backface-visibility: hidden;\n    -webkit-perspective: 1000px;\n            perspective: 1000px;\n  }\n  .carousel-inner > .item.next,\n  .carousel-inner > .item.active.right {\n    left: 0;\n    -webkit-transform: translate3d(100%, 0, 0);\n            transform: translate3d(100%, 0, 0);\n  }\n  .carousel-inner > .item.prev,\n  .carousel-inner > .item.active.left {\n    left: 0;\n    -webkit-transform: translate3d(-100%, 0, 0);\n            transform: translate3d(-100%, 0, 0);\n  }\n  .carousel-inner > .item.next.left,\n  .carousel-inner > .item.prev.right,\n  .carousel-inner > .item.active {\n    left: 0;\n    -webkit-transform: translate3d(0, 0, 0);\n            transform: translate3d(0, 0, 0);\n  }\n}\n.carousel-inner > .active,\n.carousel-inner > .next,\n.carousel-inner > .prev {\n  display: block;\n}\n.carousel-inner > .active {\n  left: 0;\n}\n.carousel-inner > .next,\n.carousel-inner > .prev {\n  position: absolute;\n  top: 0;\n  width: 100%;\n}\n.carousel-inner > .next {\n  left: 100%;\n}\n.carousel-inner > .prev {\n  left: -100%;\n}\n.carousel-inner > .next.left,\n.carousel-inner > .prev.right {\n  left: 0;\n}\n.carousel-inner > .active.left {\n  left: -100%;\n}\n.carousel-inner > .active.right {\n  left: 100%;\n}\n.carousel-control {\n  position: absolute;\n  top: 0;\n  bottom: 0;\n  left: 0;\n  width: 15%;\n  font-size: 20px;\n  color: #fff;\n  text-align: center;\n  text-shadow: 0 1px 2px rgba(0, 0, 0, .6);\n  background-color: rgba(0, 0, 0, 0);\n  filter: alpha(opacity=50);\n  opacity: .5;\n}\n.carousel-control.left {\n  background-image: -webkit-linear-gradient(left, rgba(0, 0, 0, .5) 0%, rgba(0, 0, 0, .0001) 100%);\n  background-image:      -o-linear-gradient(left, rgba(0, 0, 0, .5) 0%, rgba(0, 0, 0, .0001) 100%);\n  background-image: -webkit-gradient(linear, left top, right top, from(rgba(0, 0, 0, .5)), to(rgba(0, 0, 0, .0001)));\n  background-image:         linear-gradient(to right, rgba(0, 0, 0, .5) 0%, rgba(0, 0, 0, .0001) 100%);\n  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#80000000', endColorstr='#00000000', GradientType=1);\n  background-repeat: repeat-x;\n}\n.carousel-control.right {\n  right: 0;\n  left: auto;\n  background-image: -webkit-linear-gradient(left, rgba(0, 0, 0, .0001) 0%, rgba(0, 0, 0, .5) 100%);\n  background-image:      -o-linear-gradient(left, rgba(0, 0, 0, .0001) 0%, rgba(0, 0, 0, .5) 100%);\n  background-image: -webkit-gradient(linear, left top, right top, from(rgba(0, 0, 0, .0001)), to(rgba(0, 0, 0, .5)));\n  background-image:         linear-gradient(to right, rgba(0, 0, 0, .0001) 0%, rgba(0, 0, 0, .5) 100%);\n  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#00000000', endColorstr='#80000000', GradientType=1);\n  background-repeat: repeat-x;\n}\n.carousel-control:hover,\n.carousel-control:focus {\n  color: #fff;\n  text-decoration: none;\n  filter: alpha(opacity=90);\n  outline: 0;\n  opacity: .9;\n}\n.carousel-control .icon-prev,\n.carousel-control .icon-next,\n.carousel-control .glyphicon-chevron-left,\n.carousel-control .glyphicon-chevron-right {\n  position: absolute;\n  top: 50%;\n  z-index: 5;\n  display: inline-block;\n  margin-top: -10px;\n}\n.carousel-control .icon-prev,\n.carousel-control .glyphicon-chevron-left {\n  left: 50%;\n  margin-left: -10px;\n}\n.carousel-control .icon-next,\n.carousel-control .glyphicon-chevron-right {\n  right: 50%;\n  margin-right: -10px;\n}\n.carousel-control .icon-prev,\n.carousel-control .icon-next {\n  width: 20px;\n  height: 20px;\n  font-family: serif;\n  line-height: 1;\n}\n.carousel-control .icon-prev:before {\n  content: '\\2039';\n}\n.carousel-control .icon-next:before {\n  content: '\\203a';\n}\n.carousel-indicators {\n  position: absolute;\n  bottom: 10px;\n  left: 50%;\n  z-index: 15;\n  width: 60%;\n  padding-left: 0;\n  margin-left: -30%;\n  text-align: center;\n  list-style: none;\n}\n.carousel-indicators li {\n  display: inline-block;\n  width: 10px;\n  height: 10px;\n  margin: 1px;\n  text-indent: -999px;\n  cursor: pointer;\n  background-color: #000 \\9;\n  background-color: rgba(0, 0, 0, 0);\n  border: 1px solid #fff;\n  border-radius: 10px;\n}\n.carousel-indicators .active {\n  width: 12px;\n  height: 12px;\n  margin: 0;\n  background-color: #fff;\n}\n.carousel-caption {\n  position: absolute;\n  right: 15%;\n  bottom: 20px;\n  left: 15%;\n  z-index: 10;\n  padding-top: 20px;\n  padding-bottom: 20px;\n  color: #fff;\n  text-align: center;\n  text-shadow: 0 1px 2px rgba(0, 0, 0, .6);\n}\n.carousel-caption .btn {\n  text-shadow: none;\n}\n@media screen and (min-width: 768px) {\n  .carousel-control .glyphicon-chevron-left,\n  .carousel-control .glyphicon-chevron-right,\n  .carousel-control .icon-prev,\n  .carousel-control .icon-next {\n    width: 30px;\n    height: 30px;\n    margin-top: -10px;\n    font-size: 30px;\n  }\n  .carousel-control .glyphicon-chevron-left,\n  .carousel-control .icon-prev {\n    margin-left: -10px;\n  }\n  .carousel-control .glyphicon-chevron-right,\n  .carousel-control .icon-next {\n    margin-right: -10px;\n  }\n  .carousel-caption {\n    right: 20%;\n    left: 20%;\n    padding-bottom: 30px;\n  }\n  .carousel-indicators {\n    bottom: 20px;\n  }\n}\n.clearfix:before,\n.clearfix:after,\n.dl-horizontal dd:before,\n.dl-horizontal dd:after,\n.container:before,\n.container:after,\n.container-fluid:before,\n.container-fluid:after,\n.row:before,\n.row:after,\n.form-horizontal .form-group:before,\n.form-horizontal .form-group:after,\n.btn-toolbar:before,\n.btn-toolbar:after,\n.btn-group-vertical > .btn-group:before,\n.btn-group-vertical > .btn-group:after,\n.nav:before,\n.nav:after,\n.navbar:before,\n.navbar:after,\n.navbar-header:before,\n.navbar-header:after,\n.navbar-collapse:before,\n.navbar-collapse:after,\n.pager:before,\n.pager:after,\n.panel-body:before,\n.panel-body:after,\n.modal-header:before,\n.modal-header:after,\n.modal-footer:before,\n.modal-footer:after {\n  display: table;\n  content: \" \";\n}\n.clearfix:after,\n.dl-horizontal dd:after,\n.container:after,\n.container-fluid:after,\n.row:after,\n.form-horizontal .form-group:after,\n.btn-toolbar:after,\n.btn-group-vertical > .btn-group:after,\n.nav:after,\n.navbar:after,\n.navbar-header:after,\n.navbar-collapse:after,\n.pager:after,\n.panel-body:after,\n.modal-header:after,\n.modal-footer:after {\n  clear: both;\n}\n.center-block {\n  display: block;\n  margin-right: auto;\n  margin-left: auto;\n}\n.pull-right {\n  float: right !important;\n}\n.pull-left {\n  float: left !important;\n}\n.hide {\n  display: none !important;\n}\n.show {\n  display: block !important;\n}\n.invisible {\n  visibility: hidden;\n}\n.text-hide {\n  font: 0/0 a;\n  color: transparent;\n  text-shadow: none;\n  background-color: transparent;\n  border: 0;\n}\n.hidden {\n  display: none !important;\n}\n.affix {\n  position: fixed;\n}\n@-ms-viewport {\n  width: device-width;\n}\n.visible-xs,\n.visible-sm,\n.visible-md,\n.visible-lg {\n  display: none !important;\n}\n.visible-xs-block,\n.visible-xs-inline,\n.visible-xs-inline-block,\n.visible-sm-block,\n.visible-sm-inline,\n.visible-sm-inline-block,\n.visible-md-block,\n.visible-md-inline,\n.visible-md-inline-block,\n.visible-lg-block,\n.visible-lg-inline,\n.visible-lg-inline-block {\n  display: none !important;\n}\n@media (max-width: 767px) {\n  .visible-xs {\n    display: block !important;\n  }\n  table.visible-xs {\n    display: table !important;\n  }\n  tr.visible-xs {\n    display: table-row !important;\n  }\n  th.visible-xs,\n  td.visible-xs {\n    display: table-cell !important;\n  }\n}\n@media (max-width: 767px) {\n  .visible-xs-block {\n    display: block !important;\n  }\n}\n@media (max-width: 767px) {\n  .visible-xs-inline {\n    display: inline !important;\n  }\n}\n@media (max-width: 767px) {\n  .visible-xs-inline-block {\n    display: inline-block !important;\n  }\n}\n@media (min-width: 768px) and (max-width: 991px) {\n  .visible-sm {\n    display: block !important;\n  }\n  table.visible-sm {\n    display: table !important;\n  }\n  tr.visible-sm {\n    display: table-row !important;\n  }\n  th.visible-sm,\n  td.visible-sm {\n    display: table-cell !important;\n  }\n}\n@media (min-width: 768px) and (max-width: 991px) {\n  .visible-sm-block {\n    display: block !important;\n  }\n}\n@media (min-width: 768px) and (max-width: 991px) {\n  .visible-sm-inline {\n    display: inline !important;\n  }\n}\n@media (min-width: 768px) and (max-width: 991px) {\n  .visible-sm-inline-block {\n    display: inline-block !important;\n  }\n}\n@media (min-width: 992px) and (max-width: 1199px) {\n  .visible-md {\n    display: block !important;\n  }\n  table.visible-md {\n    display: table !important;\n  }\n  tr.visible-md {\n    display: table-row !important;\n  }\n  th.visible-md,\n  td.visible-md {\n    display: table-cell !important;\n  }\n}\n@media (min-width: 992px) and (max-width: 1199px) {\n  .visible-md-block {\n    display: block !important;\n  }\n}\n@media (min-width: 992px) and (max-width: 1199px) {\n  .visible-md-inline {\n    display: inline !important;\n  }\n}\n@media (min-width: 992px) and (max-width: 1199px) {\n  .visible-md-inline-block {\n    display: inline-block !important;\n  }\n}\n@media (min-width: 1200px) {\n  .visible-lg {\n    display: block !important;\n  }\n  table.visible-lg {\n    display: table !important;\n  }\n  tr.visible-lg {\n    display: table-row !important;\n  }\n  th.visible-lg,\n  td.visible-lg {\n    display: table-cell !important;\n  }\n}\n@media (min-width: 1200px) {\n  .visible-lg-block {\n    display: block !important;\n  }\n}\n@media (min-width: 1200px) {\n  .visible-lg-inline {\n    display: inline !important;\n  }\n}\n@media (min-width: 1200px) {\n  .visible-lg-inline-block {\n    display: inline-block !important;\n  }\n}\n@media (max-width: 767px) {\n  .hidden-xs {\n    display: none !important;\n  }\n}\n@media (min-width: 768px) and (max-width: 991px) {\n  .hidden-sm {\n    display: none !important;\n  }\n}\n@media (min-width: 992px) and (max-width: 1199px) {\n  .hidden-md {\n    display: none !important;\n  }\n}\n@media (min-width: 1200px) {\n  .hidden-lg {\n    display: none !important;\n  }\n}\n.visible-print {\n  display: none !important;\n}\n@media print {\n  .visible-print {\n    display: block !important;\n  }\n  table.visible-print {\n    display: table !important;\n  }\n  tr.visible-print {\n    display: table-row !important;\n  }\n  th.visible-print,\n  td.visible-print {\n    display: table-cell !important;\n  }\n}\n.visible-print-block {\n  display: none !important;\n}\n@media print {\n  .visible-print-block {\n    display: block !important;\n  }\n}\n.visible-print-inline {\n  display: none !important;\n}\n@media print {\n  .visible-print-inline {\n    display: inline !important;\n  }\n}\n.visible-print-inline-block {\n  display: none !important;\n}\n@media print {\n  .visible-print-inline-block {\n    display: inline-block !important;\n  }\n}\n@media print {\n  .hidden-print {\n    display: none !important;\n  }\n}\n/*# sourceMappingURL=bootstrap.css.map */\n"
  },
  {
    "path": "app_backend/vendor/bootstrap/js/bootstrap.js",
    "content": "/*!\n * Bootstrap v3.3.7 (http://getbootstrap.com)\n * Copyright 2011-2016 Twitter, Inc.\n * Licensed under the MIT license\n */\n\nif (typeof jQuery === 'undefined') {\n  throw new Error('Bootstrap\\'s JavaScript requires jQuery')\n}\n\n+function ($) {\n  'use strict';\n  var version = $.fn.jquery.split(' ')[0].split('.')\n  if ((version[0] < 2 && version[1] < 9) || (version[0] == 1 && version[1] == 9 && version[2] < 1) || (version[0] > 3)) {\n    throw new Error('Bootstrap\\'s JavaScript requires jQuery version 1.9.1 or higher, but lower than version 4')\n  }\n}(jQuery);\n\n/* ========================================================================\n * Bootstrap: transition.js v3.3.7\n * http://getbootstrap.com/javascript/#transitions\n * ========================================================================\n * Copyright 2011-2016 Twitter, Inc.\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)\n * ======================================================================== */\n\n\n+function ($) {\n  'use strict';\n\n  // CSS TRANSITION SUPPORT (Shoutout: http://www.modernizr.com/)\n  // ============================================================\n\n  function transitionEnd() {\n    var el = document.createElement('bootstrap')\n\n    var transEndEventNames = {\n      WebkitTransition : 'webkitTransitionEnd',\n      MozTransition    : 'transitionend',\n      OTransition      : 'oTransitionEnd otransitionend',\n      transition       : 'transitionend'\n    }\n\n    for (var name in transEndEventNames) {\n      if (el.style[name] !== undefined) {\n        return { end: transEndEventNames[name] }\n      }\n    }\n\n    return false // explicit for ie8 (  ._.)\n  }\n\n  // http://blog.alexmaccaw.com/css-transitions\n  $.fn.emulateTransitionEnd = function (duration) {\n    var called = false\n    var $el = this\n    $(this).one('bsTransitionEnd', function () { called = true })\n    var callback = function () { if (!called) $($el).trigger($.support.transition.end) }\n    setTimeout(callback, duration)\n    return this\n  }\n\n  $(function () {\n    $.support.transition = transitionEnd()\n\n    if (!$.support.transition) return\n\n    $.event.special.bsTransitionEnd = {\n      bindType: $.support.transition.end,\n      delegateType: $.support.transition.end,\n      handle: function (e) {\n        if ($(e.target).is(this)) return e.handleObj.handler.apply(this, arguments)\n      }\n    }\n  })\n\n}(jQuery);\n\n/* ========================================================================\n * Bootstrap: alert.js v3.3.7\n * http://getbootstrap.com/javascript/#alerts\n * ========================================================================\n * Copyright 2011-2016 Twitter, Inc.\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)\n * ======================================================================== */\n\n\n+function ($) {\n  'use strict';\n\n  // ALERT CLASS DEFINITION\n  // ======================\n\n  var dismiss = '[data-dismiss=\"alert\"]'\n  var Alert   = function (el) {\n    $(el).on('click', dismiss, this.close)\n  }\n\n  Alert.VERSION = '3.3.7'\n\n  Alert.TRANSITION_DURATION = 150\n\n  Alert.prototype.close = function (e) {\n    var $this    = $(this)\n    var selector = $this.attr('data-target')\n\n    if (!selector) {\n      selector = $this.attr('href')\n      selector = selector && selector.replace(/.*(?=#[^\\s]*$)/, '') // strip for ie7\n    }\n\n    var $parent = $(selector === '#' ? [] : selector)\n\n    if (e) e.preventDefault()\n\n    if (!$parent.length) {\n      $parent = $this.closest('.alert')\n    }\n\n    $parent.trigger(e = $.Event('close.bs.alert'))\n\n    if (e.isDefaultPrevented()) return\n\n    $parent.removeClass('in')\n\n    function removeElement() {\n      // detach from parent, fire event then clean up data\n      $parent.detach().trigger('closed.bs.alert').remove()\n    }\n\n    $.support.transition && $parent.hasClass('fade') ?\n      $parent\n        .one('bsTransitionEnd', removeElement)\n        .emulateTransitionEnd(Alert.TRANSITION_DURATION) :\n      removeElement()\n  }\n\n\n  // ALERT PLUGIN DEFINITION\n  // =======================\n\n  function Plugin(option) {\n    return this.each(function () {\n      var $this = $(this)\n      var data  = $this.data('bs.alert')\n\n      if (!data) $this.data('bs.alert', (data = new Alert(this)))\n      if (typeof option == 'string') data[option].call($this)\n    })\n  }\n\n  var old = $.fn.alert\n\n  $.fn.alert             = Plugin\n  $.fn.alert.Constructor = Alert\n\n\n  // ALERT NO CONFLICT\n  // =================\n\n  $.fn.alert.noConflict = function () {\n    $.fn.alert = old\n    return this\n  }\n\n\n  // ALERT DATA-API\n  // ==============\n\n  $(document).on('click.bs.alert.data-api', dismiss, Alert.prototype.close)\n\n}(jQuery);\n\n/* ========================================================================\n * Bootstrap: button.js v3.3.7\n * http://getbootstrap.com/javascript/#buttons\n * ========================================================================\n * Copyright 2011-2016 Twitter, Inc.\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)\n * ======================================================================== */\n\n\n+function ($) {\n  'use strict';\n\n  // BUTTON PUBLIC CLASS DEFINITION\n  // ==============================\n\n  var Button = function (element, options) {\n    this.$element  = $(element)\n    this.options   = $.extend({}, Button.DEFAULTS, options)\n    this.isLoading = false\n  }\n\n  Button.VERSION  = '3.3.7'\n\n  Button.DEFAULTS = {\n    loadingText: 'loading...'\n  }\n\n  Button.prototype.setState = function (state) {\n    var d    = 'disabled'\n    var $el  = this.$element\n    var val  = $el.is('input') ? 'val' : 'html'\n    var data = $el.data()\n\n    state += 'Text'\n\n    if (data.resetText == null) $el.data('resetText', $el[val]())\n\n    // push to event loop to allow forms to submit\n    setTimeout($.proxy(function () {\n      $el[val](data[state] == null ? this.options[state] : data[state])\n\n      if (state == 'loadingText') {\n        this.isLoading = true\n        $el.addClass(d).attr(d, d).prop(d, true)\n      } else if (this.isLoading) {\n        this.isLoading = false\n        $el.removeClass(d).removeAttr(d).prop(d, false)\n      }\n    }, this), 0)\n  }\n\n  Button.prototype.toggle = function () {\n    var changed = true\n    var $parent = this.$element.closest('[data-toggle=\"buttons\"]')\n\n    if ($parent.length) {\n      var $input = this.$element.find('input')\n      if ($input.prop('type') == 'radio') {\n        if ($input.prop('checked')) changed = false\n        $parent.find('.active').removeClass('active')\n        this.$element.addClass('active')\n      } else if ($input.prop('type') == 'checkbox') {\n        if (($input.prop('checked')) !== this.$element.hasClass('active')) changed = false\n        this.$element.toggleClass('active')\n      }\n      $input.prop('checked', this.$element.hasClass('active'))\n      if (changed) $input.trigger('change')\n    } else {\n      this.$element.attr('aria-pressed', !this.$element.hasClass('active'))\n      this.$element.toggleClass('active')\n    }\n  }\n\n\n  // BUTTON PLUGIN DEFINITION\n  // ========================\n\n  function Plugin(option) {\n    return this.each(function () {\n      var $this   = $(this)\n      var data    = $this.data('bs.button')\n      var options = typeof option == 'object' && option\n\n      if (!data) $this.data('bs.button', (data = new Button(this, options)))\n\n      if (option == 'toggle') data.toggle()\n      else if (option) data.setState(option)\n    })\n  }\n\n  var old = $.fn.button\n\n  $.fn.button             = Plugin\n  $.fn.button.Constructor = Button\n\n\n  // BUTTON NO CONFLICT\n  // ==================\n\n  $.fn.button.noConflict = function () {\n    $.fn.button = old\n    return this\n  }\n\n\n  // BUTTON DATA-API\n  // ===============\n\n  $(document)\n    .on('click.bs.button.data-api', '[data-toggle^=\"button\"]', function (e) {\n      var $btn = $(e.target).closest('.btn')\n      Plugin.call($btn, 'toggle')\n      if (!($(e.target).is('input[type=\"radio\"], input[type=\"checkbox\"]'))) {\n        // Prevent double click on radios, and the double selections (so cancellation) on checkboxes\n        e.preventDefault()\n        // The target component still receive the focus\n        if ($btn.is('input,button')) $btn.trigger('focus')\n        else $btn.find('input:visible,button:visible').first().trigger('focus')\n      }\n    })\n    .on('focus.bs.button.data-api blur.bs.button.data-api', '[data-toggle^=\"button\"]', function (e) {\n      $(e.target).closest('.btn').toggleClass('focus', /^focus(in)?$/.test(e.type))\n    })\n\n}(jQuery);\n\n/* ========================================================================\n * Bootstrap: carousel.js v3.3.7\n * http://getbootstrap.com/javascript/#carousel\n * ========================================================================\n * Copyright 2011-2016 Twitter, Inc.\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)\n * ======================================================================== */\n\n\n+function ($) {\n  'use strict';\n\n  // CAROUSEL CLASS DEFINITION\n  // =========================\n\n  var Carousel = function (element, options) {\n    this.$element    = $(element)\n    this.$indicators = this.$element.find('.carousel-indicators')\n    this.options     = options\n    this.paused      = null\n    this.sliding     = null\n    this.interval    = null\n    this.$active     = null\n    this.$items      = null\n\n    this.options.keyboard && this.$element.on('keydown.bs.carousel', $.proxy(this.keydown, this))\n\n    this.options.pause == 'hover' && !('ontouchstart' in document.documentElement) && this.$element\n      .on('mouseenter.bs.carousel', $.proxy(this.pause, this))\n      .on('mouseleave.bs.carousel', $.proxy(this.cycle, this))\n  }\n\n  Carousel.VERSION  = '3.3.7'\n\n  Carousel.TRANSITION_DURATION = 600\n\n  Carousel.DEFAULTS = {\n    interval: 5000,\n    pause: 'hover',\n    wrap: true,\n    keyboard: true\n  }\n\n  Carousel.prototype.keydown = function (e) {\n    if (/input|textarea/i.test(e.target.tagName)) return\n    switch (e.which) {\n      case 37: this.prev(); break\n      case 39: this.next(); break\n      default: return\n    }\n\n    e.preventDefault()\n  }\n\n  Carousel.prototype.cycle = function (e) {\n    e || (this.paused = false)\n\n    this.interval && clearInterval(this.interval)\n\n    this.options.interval\n      && !this.paused\n      && (this.interval = setInterval($.proxy(this.next, this), this.options.interval))\n\n    return this\n  }\n\n  Carousel.prototype.getItemIndex = function (item) {\n    this.$items = item.parent().children('.item')\n    return this.$items.index(item || this.$active)\n  }\n\n  Carousel.prototype.getItemForDirection = function (direction, active) {\n    var activeIndex = this.getItemIndex(active)\n    var willWrap = (direction == 'prev' && activeIndex === 0)\n                || (direction == 'next' && activeIndex == (this.$items.length - 1))\n    if (willWrap && !this.options.wrap) return active\n    var delta = direction == 'prev' ? -1 : 1\n    var itemIndex = (activeIndex + delta) % this.$items.length\n    return this.$items.eq(itemIndex)\n  }\n\n  Carousel.prototype.to = function (pos) {\n    var that        = this\n    var activeIndex = this.getItemIndex(this.$active = this.$element.find('.item.active'))\n\n    if (pos > (this.$items.length - 1) || pos < 0) return\n\n    if (this.sliding)       return this.$element.one('slid.bs.carousel', function () { that.to(pos) }) // yes, \"slid\"\n    if (activeIndex == pos) return this.pause().cycle()\n\n    return this.slide(pos > activeIndex ? 'next' : 'prev', this.$items.eq(pos))\n  }\n\n  Carousel.prototype.pause = function (e) {\n    e || (this.paused = true)\n\n    if (this.$element.find('.next, .prev').length && $.support.transition) {\n      this.$element.trigger($.support.transition.end)\n      this.cycle(true)\n    }\n\n    this.interval = clearInterval(this.interval)\n\n    return this\n  }\n\n  Carousel.prototype.next = function () {\n    if (this.sliding) return\n    return this.slide('next')\n  }\n\n  Carousel.prototype.prev = function () {\n    if (this.sliding) return\n    return this.slide('prev')\n  }\n\n  Carousel.prototype.slide = function (type, next) {\n    var $active   = this.$element.find('.item.active')\n    var $next     = next || this.getItemForDirection(type, $active)\n    var isCycling = this.interval\n    var direction = type == 'next' ? 'left' : 'right'\n    var that      = this\n\n    if ($next.hasClass('active')) return (this.sliding = false)\n\n    var relatedTarget = $next[0]\n    var slideEvent = $.Event('slide.bs.carousel', {\n      relatedTarget: relatedTarget,\n      direction: direction\n    })\n    this.$element.trigger(slideEvent)\n    if (slideEvent.isDefaultPrevented()) return\n\n    this.sliding = true\n\n    isCycling && this.pause()\n\n    if (this.$indicators.length) {\n      this.$indicators.find('.active').removeClass('active')\n      var $nextIndicator = $(this.$indicators.children()[this.getItemIndex($next)])\n      $nextIndicator && $nextIndicator.addClass('active')\n    }\n\n    var slidEvent = $.Event('slid.bs.carousel', { relatedTarget: relatedTarget, direction: direction }) // yes, \"slid\"\n    if ($.support.transition && this.$element.hasClass('slide')) {\n      $next.addClass(type)\n      $next[0].offsetWidth // force reflow\n      $active.addClass(direction)\n      $next.addClass(direction)\n      $active\n        .one('bsTransitionEnd', function () {\n          $next.removeClass([type, direction].join(' ')).addClass('active')\n          $active.removeClass(['active', direction].join(' '))\n          that.sliding = false\n          setTimeout(function () {\n            that.$element.trigger(slidEvent)\n          }, 0)\n        })\n        .emulateTransitionEnd(Carousel.TRANSITION_DURATION)\n    } else {\n      $active.removeClass('active')\n      $next.addClass('active')\n      this.sliding = false\n      this.$element.trigger(slidEvent)\n    }\n\n    isCycling && this.cycle()\n\n    return this\n  }\n\n\n  // CAROUSEL PLUGIN DEFINITION\n  // ==========================\n\n  function Plugin(option) {\n    return this.each(function () {\n      var $this   = $(this)\n      var data    = $this.data('bs.carousel')\n      var options = $.extend({}, Carousel.DEFAULTS, $this.data(), typeof option == 'object' && option)\n      var action  = typeof option == 'string' ? option : options.slide\n\n      if (!data) $this.data('bs.carousel', (data = new Carousel(this, options)))\n      if (typeof option == 'number') data.to(option)\n      else if (action) data[action]()\n      else if (options.interval) data.pause().cycle()\n    })\n  }\n\n  var old = $.fn.carousel\n\n  $.fn.carousel             = Plugin\n  $.fn.carousel.Constructor = Carousel\n\n\n  // CAROUSEL NO CONFLICT\n  // ====================\n\n  $.fn.carousel.noConflict = function () {\n    $.fn.carousel = old\n    return this\n  }\n\n\n  // CAROUSEL DATA-API\n  // =================\n\n  var clickHandler = function (e) {\n    var href\n    var $this   = $(this)\n    var $target = $($this.attr('data-target') || (href = $this.attr('href')) && href.replace(/.*(?=#[^\\s]+$)/, '')) // strip for ie7\n    if (!$target.hasClass('carousel')) return\n    var options = $.extend({}, $target.data(), $this.data())\n    var slideIndex = $this.attr('data-slide-to')\n    if (slideIndex) options.interval = false\n\n    Plugin.call($target, options)\n\n    if (slideIndex) {\n      $target.data('bs.carousel').to(slideIndex)\n    }\n\n    e.preventDefault()\n  }\n\n  $(document)\n    .on('click.bs.carousel.data-api', '[data-slide]', clickHandler)\n    .on('click.bs.carousel.data-api', '[data-slide-to]', clickHandler)\n\n  $(window).on('load', function () {\n    $('[data-ride=\"carousel\"]').each(function () {\n      var $carousel = $(this)\n      Plugin.call($carousel, $carousel.data())\n    })\n  })\n\n}(jQuery);\n\n/* ========================================================================\n * Bootstrap: collapse.js v3.3.7\n * http://getbootstrap.com/javascript/#collapse\n * ========================================================================\n * Copyright 2011-2016 Twitter, Inc.\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)\n * ======================================================================== */\n\n/* jshint latedef: false */\n\n+function ($) {\n  'use strict';\n\n  // COLLAPSE PUBLIC CLASS DEFINITION\n  // ================================\n\n  var Collapse = function (element, options) {\n    this.$element      = $(element)\n    this.options       = $.extend({}, Collapse.DEFAULTS, options)\n    this.$trigger      = $('[data-toggle=\"collapse\"][href=\"#' + element.id + '\"],' +\n                           '[data-toggle=\"collapse\"][data-target=\"#' + element.id + '\"]')\n    this.transitioning = null\n\n    if (this.options.parent) {\n      this.$parent = this.getParent()\n    } else {\n      this.addAriaAndCollapsedClass(this.$element, this.$trigger)\n    }\n\n    if (this.options.toggle) this.toggle()\n  }\n\n  Collapse.VERSION  = '3.3.7'\n\n  Collapse.TRANSITION_DURATION = 350\n\n  Collapse.DEFAULTS = {\n    toggle: true\n  }\n\n  Collapse.prototype.dimension = function () {\n    var hasWidth = this.$element.hasClass('width')\n    return hasWidth ? 'width' : 'height'\n  }\n\n  Collapse.prototype.show = function () {\n    if (this.transitioning || this.$element.hasClass('in')) return\n\n    var activesData\n    var actives = this.$parent && this.$parent.children('.panel').children('.in, .collapsing')\n\n    if (actives && actives.length) {\n      activesData = actives.data('bs.collapse')\n      if (activesData && activesData.transitioning) return\n    }\n\n    var startEvent = $.Event('show.bs.collapse')\n    this.$element.trigger(startEvent)\n    if (startEvent.isDefaultPrevented()) return\n\n    if (actives && actives.length) {\n      Plugin.call(actives, 'hide')\n      activesData || actives.data('bs.collapse', null)\n    }\n\n    var dimension = this.dimension()\n\n    this.$element\n      .removeClass('collapse')\n      .addClass('collapsing')[dimension](0)\n      .attr('aria-expanded', true)\n\n    this.$trigger\n      .removeClass('collapsed')\n      .attr('aria-expanded', true)\n\n    this.transitioning = 1\n\n    var complete = function () {\n      this.$element\n        .removeClass('collapsing')\n        .addClass('collapse in')[dimension]('')\n      this.transitioning = 0\n      this.$element\n        .trigger('shown.bs.collapse')\n    }\n\n    if (!$.support.transition) return complete.call(this)\n\n    var scrollSize = $.camelCase(['scroll', dimension].join('-'))\n\n    this.$element\n      .one('bsTransitionEnd', $.proxy(complete, this))\n      .emulateTransitionEnd(Collapse.TRANSITION_DURATION)[dimension](this.$element[0][scrollSize])\n  }\n\n  Collapse.prototype.hide = function () {\n    if (this.transitioning || !this.$element.hasClass('in')) return\n\n    var startEvent = $.Event('hide.bs.collapse')\n    this.$element.trigger(startEvent)\n    if (startEvent.isDefaultPrevented()) return\n\n    var dimension = this.dimension()\n\n    this.$element[dimension](this.$element[dimension]())[0].offsetHeight\n\n    this.$element\n      .addClass('collapsing')\n      .removeClass('collapse in')\n      .attr('aria-expanded', false)\n\n    this.$trigger\n      .addClass('collapsed')\n      .attr('aria-expanded', false)\n\n    this.transitioning = 1\n\n    var complete = function () {\n      this.transitioning = 0\n      this.$element\n        .removeClass('collapsing')\n        .addClass('collapse')\n        .trigger('hidden.bs.collapse')\n    }\n\n    if (!$.support.transition) return complete.call(this)\n\n    this.$element\n      [dimension](0)\n      .one('bsTransitionEnd', $.proxy(complete, this))\n      .emulateTransitionEnd(Collapse.TRANSITION_DURATION)\n  }\n\n  Collapse.prototype.toggle = function () {\n    this[this.$element.hasClass('in') ? 'hide' : 'show']()\n  }\n\n  Collapse.prototype.getParent = function () {\n    return $(this.options.parent)\n      .find('[data-toggle=\"collapse\"][data-parent=\"' + this.options.parent + '\"]')\n      .each($.proxy(function (i, element) {\n        var $element = $(element)\n        this.addAriaAndCollapsedClass(getTargetFromTrigger($element), $element)\n      }, this))\n      .end()\n  }\n\n  Collapse.prototype.addAriaAndCollapsedClass = function ($element, $trigger) {\n    var isOpen = $element.hasClass('in')\n\n    $element.attr('aria-expanded', isOpen)\n    $trigger\n      .toggleClass('collapsed', !isOpen)\n      .attr('aria-expanded', isOpen)\n  }\n\n  function getTargetFromTrigger($trigger) {\n    var href\n    var target = $trigger.attr('data-target')\n      || (href = $trigger.attr('href')) && href.replace(/.*(?=#[^\\s]+$)/, '') // strip for ie7\n\n    return $(target)\n  }\n\n\n  // COLLAPSE PLUGIN DEFINITION\n  // ==========================\n\n  function Plugin(option) {\n    return this.each(function () {\n      var $this   = $(this)\n      var data    = $this.data('bs.collapse')\n      var options = $.extend({}, Collapse.DEFAULTS, $this.data(), typeof option == 'object' && option)\n\n      if (!data && options.toggle && /show|hide/.test(option)) options.toggle = false\n      if (!data) $this.data('bs.collapse', (data = new Collapse(this, options)))\n      if (typeof option == 'string') data[option]()\n    })\n  }\n\n  var old = $.fn.collapse\n\n  $.fn.collapse             = Plugin\n  $.fn.collapse.Constructor = Collapse\n\n\n  // COLLAPSE NO CONFLICT\n  // ====================\n\n  $.fn.collapse.noConflict = function () {\n    $.fn.collapse = old\n    return this\n  }\n\n\n  // COLLAPSE DATA-API\n  // =================\n\n  $(document).on('click.bs.collapse.data-api', '[data-toggle=\"collapse\"]', function (e) {\n    var $this   = $(this)\n\n    if (!$this.attr('data-target')) e.preventDefault()\n\n    var $target = getTargetFromTrigger($this)\n    var data    = $target.data('bs.collapse')\n    var option  = data ? 'toggle' : $this.data()\n\n    Plugin.call($target, option)\n  })\n\n}(jQuery);\n\n/* ========================================================================\n * Bootstrap: dropdown.js v3.3.7\n * http://getbootstrap.com/javascript/#dropdowns\n * ========================================================================\n * Copyright 2011-2016 Twitter, Inc.\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)\n * ======================================================================== */\n\n\n+function ($) {\n  'use strict';\n\n  // DROPDOWN CLASS DEFINITION\n  // =========================\n\n  var backdrop = '.dropdown-backdrop'\n  var toggle   = '[data-toggle=\"dropdown\"]'\n  var Dropdown = function (element) {\n    $(element).on('click.bs.dropdown', this.toggle)\n  }\n\n  Dropdown.VERSION = '3.3.7'\n\n  function getParent($this) {\n    var selector = $this.attr('data-target')\n\n    if (!selector) {\n      selector = $this.attr('href')\n      selector = selector && /#[A-Za-z]/.test(selector) && selector.replace(/.*(?=#[^\\s]*$)/, '') // strip for ie7\n    }\n\n    var $parent = selector && $(selector)\n\n    return $parent && $parent.length ? $parent : $this.parent()\n  }\n\n  function clearMenus(e) {\n    if (e && e.which === 3) return\n    $(backdrop).remove()\n    $(toggle).each(function () {\n      var $this         = $(this)\n      var $parent       = getParent($this)\n      var relatedTarget = { relatedTarget: this }\n\n      if (!$parent.hasClass('open')) return\n\n      if (e && e.type == 'click' && /input|textarea/i.test(e.target.tagName) && $.contains($parent[0], e.target)) return\n\n      $parent.trigger(e = $.Event('hide.bs.dropdown', relatedTarget))\n\n      if (e.isDefaultPrevented()) return\n\n      $this.attr('aria-expanded', 'false')\n      $parent.removeClass('open').trigger($.Event('hidden.bs.dropdown', relatedTarget))\n    })\n  }\n\n  Dropdown.prototype.toggle = function (e) {\n    var $this = $(this)\n\n    if ($this.is('.disabled, :disabled')) return\n\n    var $parent  = getParent($this)\n    var isActive = $parent.hasClass('open')\n\n    clearMenus()\n\n    if (!isActive) {\n      if ('ontouchstart' in document.documentElement && !$parent.closest('.navbar-nav').length) {\n        // if mobile we use a backdrop because click events don't delegate\n        $(document.createElement('div'))\n          .addClass('dropdown-backdrop')\n          .insertAfter($(this))\n          .on('click', clearMenus)\n      }\n\n      var relatedTarget = { relatedTarget: this }\n      $parent.trigger(e = $.Event('show.bs.dropdown', relatedTarget))\n\n      if (e.isDefaultPrevented()) return\n\n      $this\n        .trigger('focus')\n        .attr('aria-expanded', 'true')\n\n      $parent\n        .toggleClass('open')\n        .trigger($.Event('shown.bs.dropdown', relatedTarget))\n    }\n\n    return false\n  }\n\n  Dropdown.prototype.keydown = function (e) {\n    if (!/(38|40|27|32)/.test(e.which) || /input|textarea/i.test(e.target.tagName)) return\n\n    var $this = $(this)\n\n    e.preventDefault()\n    e.stopPropagation()\n\n    if ($this.is('.disabled, :disabled')) return\n\n    var $parent  = getParent($this)\n    var isActive = $parent.hasClass('open')\n\n    if (!isActive && e.which != 27 || isActive && e.which == 27) {\n      if (e.which == 27) $parent.find(toggle).trigger('focus')\n      return $this.trigger('click')\n    }\n\n    var desc = ' li:not(.disabled):visible a'\n    var $items = $parent.find('.dropdown-menu' + desc)\n\n    if (!$items.length) return\n\n    var index = $items.index(e.target)\n\n    if (e.which == 38 && index > 0)                 index--         // up\n    if (e.which == 40 && index < $items.length - 1) index++         // down\n    if (!~index)                                    index = 0\n\n    $items.eq(index).trigger('focus')\n  }\n\n\n  // DROPDOWN PLUGIN DEFINITION\n  // ==========================\n\n  function Plugin(option) {\n    return this.each(function () {\n      var $this = $(this)\n      var data  = $this.data('bs.dropdown')\n\n      if (!data) $this.data('bs.dropdown', (data = new Dropdown(this)))\n      if (typeof option == 'string') data[option].call($this)\n    })\n  }\n\n  var old = $.fn.dropdown\n\n  $.fn.dropdown             = Plugin\n  $.fn.dropdown.Constructor = Dropdown\n\n\n  // DROPDOWN NO CONFLICT\n  // ====================\n\n  $.fn.dropdown.noConflict = function () {\n    $.fn.dropdown = old\n    return this\n  }\n\n\n  // APPLY TO STANDARD DROPDOWN ELEMENTS\n  // ===================================\n\n  $(document)\n    .on('click.bs.dropdown.data-api', clearMenus)\n    .on('click.bs.dropdown.data-api', '.dropdown form', function (e) { e.stopPropagation() })\n    .on('click.bs.dropdown.data-api', toggle, Dropdown.prototype.toggle)\n    .on('keydown.bs.dropdown.data-api', toggle, Dropdown.prototype.keydown)\n    .on('keydown.bs.dropdown.data-api', '.dropdown-menu', Dropdown.prototype.keydown)\n\n}(jQuery);\n\n/* ========================================================================\n * Bootstrap: modal.js v3.3.7\n * http://getbootstrap.com/javascript/#modals\n * ========================================================================\n * Copyright 2011-2016 Twitter, Inc.\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)\n * ======================================================================== */\n\n\n+function ($) {\n  'use strict';\n\n  // MODAL CLASS DEFINITION\n  // ======================\n\n  var Modal = function (element, options) {\n    this.options             = options\n    this.$body               = $(document.body)\n    this.$element            = $(element)\n    this.$dialog             = this.$element.find('.modal-dialog')\n    this.$backdrop           = null\n    this.isShown             = null\n    this.originalBodyPad     = null\n    this.scrollbarWidth      = 0\n    this.ignoreBackdropClick = false\n\n    if (this.options.remote) {\n      this.$element\n        .find('.modal-content')\n        .load(this.options.remote, $.proxy(function () {\n          this.$element.trigger('loaded.bs.modal')\n        }, this))\n    }\n  }\n\n  Modal.VERSION  = '3.3.7'\n\n  Modal.TRANSITION_DURATION = 300\n  Modal.BACKDROP_TRANSITION_DURATION = 150\n\n  Modal.DEFAULTS = {\n    backdrop: true,\n    keyboard: true,\n    show: true\n  }\n\n  Modal.prototype.toggle = function (_relatedTarget) {\n    return this.isShown ? this.hide() : this.show(_relatedTarget)\n  }\n\n  Modal.prototype.show = function (_relatedTarget) {\n    var that = this\n    var e    = $.Event('show.bs.modal', { relatedTarget: _relatedTarget })\n\n    this.$element.trigger(e)\n\n    if (this.isShown || e.isDefaultPrevented()) return\n\n    this.isShown = true\n\n    this.checkScrollbar()\n    this.setScrollbar()\n    this.$body.addClass('modal-open')\n\n    this.escape()\n    this.resize()\n\n    this.$element.on('click.dismiss.bs.modal', '[data-dismiss=\"modal\"]', $.proxy(this.hide, this))\n\n    this.$dialog.on('mousedown.dismiss.bs.modal', function () {\n      that.$element.one('mouseup.dismiss.bs.modal', function (e) {\n        if ($(e.target).is(that.$element)) that.ignoreBackdropClick = true\n      })\n    })\n\n    this.backdrop(function () {\n      var transition = $.support.transition && that.$element.hasClass('fade')\n\n      if (!that.$element.parent().length) {\n        that.$element.appendTo(that.$body) // don't move modals dom position\n      }\n\n      that.$element\n        .show()\n        .scrollTop(0)\n\n      that.adjustDialog()\n\n      if (transition) {\n        that.$element[0].offsetWidth // force reflow\n      }\n\n      that.$element.addClass('in')\n\n      that.enforceFocus()\n\n      var e = $.Event('shown.bs.modal', { relatedTarget: _relatedTarget })\n\n      transition ?\n        that.$dialog // wait for modal to slide in\n          .one('bsTransitionEnd', function () {\n            that.$element.trigger('focus').trigger(e)\n          })\n          .emulateTransitionEnd(Modal.TRANSITION_DURATION) :\n        that.$element.trigger('focus').trigger(e)\n    })\n  }\n\n  Modal.prototype.hide = function (e) {\n    if (e) e.preventDefault()\n\n    e = $.Event('hide.bs.modal')\n\n    this.$element.trigger(e)\n\n    if (!this.isShown || e.isDefaultPrevented()) return\n\n    this.isShown = false\n\n    this.escape()\n    this.resize()\n\n    $(document).off('focusin.bs.modal')\n\n    this.$element\n      .removeClass('in')\n      .off('click.dismiss.bs.modal')\n      .off('mouseup.dismiss.bs.modal')\n\n    this.$dialog.off('mousedown.dismiss.bs.modal')\n\n    $.support.transition && this.$element.hasClass('fade') ?\n      this.$element\n        .one('bsTransitionEnd', $.proxy(this.hideModal, this))\n        .emulateTransitionEnd(Modal.TRANSITION_DURATION) :\n      this.hideModal()\n  }\n\n  Modal.prototype.enforceFocus = function () {\n    $(document)\n      .off('focusin.bs.modal') // guard against infinite focus loop\n      .on('focusin.bs.modal', $.proxy(function (e) {\n        if (document !== e.target &&\n            this.$element[0] !== e.target &&\n            !this.$element.has(e.target).length) {\n          this.$element.trigger('focus')\n        }\n      }, this))\n  }\n\n  Modal.prototype.escape = function () {\n    if (this.isShown && this.options.keyboard) {\n      this.$element.on('keydown.dismiss.bs.modal', $.proxy(function (e) {\n        e.which == 27 && this.hide()\n      }, this))\n    } else if (!this.isShown) {\n      this.$element.off('keydown.dismiss.bs.modal')\n    }\n  }\n\n  Modal.prototype.resize = function () {\n    if (this.isShown) {\n      $(window).on('resize.bs.modal', $.proxy(this.handleUpdate, this))\n    } else {\n      $(window).off('resize.bs.modal')\n    }\n  }\n\n  Modal.prototype.hideModal = function () {\n    var that = this\n    this.$element.hide()\n    this.backdrop(function () {\n      that.$body.removeClass('modal-open')\n      that.resetAdjustments()\n      that.resetScrollbar()\n      that.$element.trigger('hidden.bs.modal')\n    })\n  }\n\n  Modal.prototype.removeBackdrop = function () {\n    this.$backdrop && this.$backdrop.remove()\n    this.$backdrop = null\n  }\n\n  Modal.prototype.backdrop = function (callback) {\n    var that = this\n    var animate = this.$element.hasClass('fade') ? 'fade' : ''\n\n    if (this.isShown && this.options.backdrop) {\n      var doAnimate = $.support.transition && animate\n\n      this.$backdrop = $(document.createElement('div'))\n        .addClass('modal-backdrop ' + animate)\n        .appendTo(this.$body)\n\n      this.$element.on('click.dismiss.bs.modal', $.proxy(function (e) {\n        if (this.ignoreBackdropClick) {\n          this.ignoreBackdropClick = false\n          return\n        }\n        if (e.target !== e.currentTarget) return\n        this.options.backdrop == 'static'\n          ? this.$element[0].focus()\n          : this.hide()\n      }, this))\n\n      if (doAnimate) this.$backdrop[0].offsetWidth // force reflow\n\n      this.$backdrop.addClass('in')\n\n      if (!callback) return\n\n      doAnimate ?\n        this.$backdrop\n          .one('bsTransitionEnd', callback)\n          .emulateTransitionEnd(Modal.BACKDROP_TRANSITION_DURATION) :\n        callback()\n\n    } else if (!this.isShown && this.$backdrop) {\n      this.$backdrop.removeClass('in')\n\n      var callbackRemove = function () {\n        that.removeBackdrop()\n        callback && callback()\n      }\n      $.support.transition && this.$element.hasClass('fade') ?\n        this.$backdrop\n          .one('bsTransitionEnd', callbackRemove)\n          .emulateTransitionEnd(Modal.BACKDROP_TRANSITION_DURATION) :\n        callbackRemove()\n\n    } else if (callback) {\n      callback()\n    }\n  }\n\n  // these following methods are used to handle overflowing modals\n\n  Modal.prototype.handleUpdate = function () {\n    this.adjustDialog()\n  }\n\n  Modal.prototype.adjustDialog = function () {\n    var modalIsOverflowing = this.$element[0].scrollHeight > document.documentElement.clientHeight\n\n    this.$element.css({\n      paddingLeft:  !this.bodyIsOverflowing && modalIsOverflowing ? this.scrollbarWidth : '',\n      paddingRight: this.bodyIsOverflowing && !modalIsOverflowing ? this.scrollbarWidth : ''\n    })\n  }\n\n  Modal.prototype.resetAdjustments = function () {\n    this.$element.css({\n      paddingLeft: '',\n      paddingRight: ''\n    })\n  }\n\n  Modal.prototype.checkScrollbar = function () {\n    var fullWindowWidth = window.innerWidth\n    if (!fullWindowWidth) { // workaround for missing window.innerWidth in IE8\n      var documentElementRect = document.documentElement.getBoundingClientRect()\n      fullWindowWidth = documentElementRect.right - Math.abs(documentElementRect.left)\n    }\n    this.bodyIsOverflowing = document.body.clientWidth < fullWindowWidth\n    this.scrollbarWidth = this.measureScrollbar()\n  }\n\n  Modal.prototype.setScrollbar = function () {\n    var bodyPad = parseInt((this.$body.css('padding-right') || 0), 10)\n    this.originalBodyPad = document.body.style.paddingRight || ''\n    if (this.bodyIsOverflowing) this.$body.css('padding-right', bodyPad + this.scrollbarWidth)\n  }\n\n  Modal.prototype.resetScrollbar = function () {\n    this.$body.css('padding-right', this.originalBodyPad)\n  }\n\n  Modal.prototype.measureScrollbar = function () { // thx walsh\n    var scrollDiv = document.createElement('div')\n    scrollDiv.className = 'modal-scrollbar-measure'\n    this.$body.append(scrollDiv)\n    var scrollbarWidth = scrollDiv.offsetWidth - scrollDiv.clientWidth\n    this.$body[0].removeChild(scrollDiv)\n    return scrollbarWidth\n  }\n\n\n  // MODAL PLUGIN DEFINITION\n  // =======================\n\n  function Plugin(option, _relatedTarget) {\n    return this.each(function () {\n      var $this   = $(this)\n      var data    = $this.data('bs.modal')\n      var options = $.extend({}, Modal.DEFAULTS, $this.data(), typeof option == 'object' && option)\n\n      if (!data) $this.data('bs.modal', (data = new Modal(this, options)))\n      if (typeof option == 'string') data[option](_relatedTarget)\n      else if (options.show) data.show(_relatedTarget)\n    })\n  }\n\n  var old = $.fn.modal\n\n  $.fn.modal             = Plugin\n  $.fn.modal.Constructor = Modal\n\n\n  // MODAL NO CONFLICT\n  // =================\n\n  $.fn.modal.noConflict = function () {\n    $.fn.modal = old\n    return this\n  }\n\n\n  // MODAL DATA-API\n  // ==============\n\n  $(document).on('click.bs.modal.data-api', '[data-toggle=\"modal\"]', function (e) {\n    var $this   = $(this)\n    var href    = $this.attr('href')\n    var $target = $($this.attr('data-target') || (href && href.replace(/.*(?=#[^\\s]+$)/, ''))) // strip for ie7\n    var option  = $target.data('bs.modal') ? 'toggle' : $.extend({ remote: !/#/.test(href) && href }, $target.data(), $this.data())\n\n    if ($this.is('a')) e.preventDefault()\n\n    $target.one('show.bs.modal', function (showEvent) {\n      if (showEvent.isDefaultPrevented()) return // only register focus restorer if modal will actually get shown\n      $target.one('hidden.bs.modal', function () {\n        $this.is(':visible') && $this.trigger('focus')\n      })\n    })\n    Plugin.call($target, option, this)\n  })\n\n}(jQuery);\n\n/* ========================================================================\n * Bootstrap: tooltip.js v3.3.7\n * http://getbootstrap.com/javascript/#tooltip\n * Inspired by the original jQuery.tipsy by Jason Frame\n * ========================================================================\n * Copyright 2011-2016 Twitter, Inc.\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)\n * ======================================================================== */\n\n\n+function ($) {\n  'use strict';\n\n  // TOOLTIP PUBLIC CLASS DEFINITION\n  // ===============================\n\n  var Tooltip = function (element, options) {\n    this.type       = null\n    this.options    = null\n    this.enabled    = null\n    this.timeout    = null\n    this.hoverState = null\n    this.$element   = null\n    this.inState    = null\n\n    this.init('tooltip', element, options)\n  }\n\n  Tooltip.VERSION  = '3.3.7'\n\n  Tooltip.TRANSITION_DURATION = 150\n\n  Tooltip.DEFAULTS = {\n    animation: true,\n    placement: 'top',\n    selector: false,\n    template: '<div class=\"tooltip\" role=\"tooltip\"><div class=\"tooltip-arrow\"></div><div class=\"tooltip-inner\"></div></div>',\n    trigger: 'hover focus',\n    title: '',\n    delay: 0,\n    html: false,\n    container: false,\n    viewport: {\n      selector: 'body',\n      padding: 0\n    }\n  }\n\n  Tooltip.prototype.init = function (type, element, options) {\n    this.enabled   = true\n    this.type      = type\n    this.$element  = $(element)\n    this.options   = this.getOptions(options)\n    this.$viewport = this.options.viewport && $($.isFunction(this.options.viewport) ? this.options.viewport.call(this, this.$element) : (this.options.viewport.selector || this.options.viewport))\n    this.inState   = { click: false, hover: false, focus: false }\n\n    if (this.$element[0] instanceof document.constructor && !this.options.selector) {\n      throw new Error('`selector` option must be specified when initializing ' + this.type + ' on the window.document object!')\n    }\n\n    var triggers = this.options.trigger.split(' ')\n\n    for (var i = triggers.length; i--;) {\n      var trigger = triggers[i]\n\n      if (trigger == 'click') {\n        this.$element.on('click.' + this.type, this.options.selector, $.proxy(this.toggle, this))\n      } else if (trigger != 'manual') {\n        var eventIn  = trigger == 'hover' ? 'mouseenter' : 'focusin'\n        var eventOut = trigger == 'hover' ? 'mouseleave' : 'focusout'\n\n        this.$element.on(eventIn  + '.' + this.type, this.options.selector, $.proxy(this.enter, this))\n        this.$element.on(eventOut + '.' + this.type, this.options.selector, $.proxy(this.leave, this))\n      }\n    }\n\n    this.options.selector ?\n      (this._options = $.extend({}, this.options, { trigger: 'manual', selector: '' })) :\n      this.fixTitle()\n  }\n\n  Tooltip.prototype.getDefaults = function () {\n    return Tooltip.DEFAULTS\n  }\n\n  Tooltip.prototype.getOptions = function (options) {\n    options = $.extend({}, this.getDefaults(), this.$element.data(), options)\n\n    if (options.delay && typeof options.delay == 'number') {\n      options.delay = {\n        show: options.delay,\n        hide: options.delay\n      }\n    }\n\n    return options\n  }\n\n  Tooltip.prototype.getDelegateOptions = function () {\n    var options  = {}\n    var defaults = this.getDefaults()\n\n    this._options && $.each(this._options, function (key, value) {\n      if (defaults[key] != value) options[key] = value\n    })\n\n    return options\n  }\n\n  Tooltip.prototype.enter = function (obj) {\n    var self = obj instanceof this.constructor ?\n      obj : $(obj.currentTarget).data('bs.' + this.type)\n\n    if (!self) {\n      self = new this.constructor(obj.currentTarget, this.getDelegateOptions())\n      $(obj.currentTarget).data('bs.' + this.type, self)\n    }\n\n    if (obj instanceof $.Event) {\n      self.inState[obj.type == 'focusin' ? 'focus' : 'hover'] = true\n    }\n\n    if (self.tip().hasClass('in') || self.hoverState == 'in') {\n      self.hoverState = 'in'\n      return\n    }\n\n    clearTimeout(self.timeout)\n\n    self.hoverState = 'in'\n\n    if (!self.options.delay || !self.options.delay.show) return self.show()\n\n    self.timeout = setTimeout(function () {\n      if (self.hoverState == 'in') self.show()\n    }, self.options.delay.show)\n  }\n\n  Tooltip.prototype.isInStateTrue = function () {\n    for (var key in this.inState) {\n      if (this.inState[key]) return true\n    }\n\n    return false\n  }\n\n  Tooltip.prototype.leave = function (obj) {\n    var self = obj instanceof this.constructor ?\n      obj : $(obj.currentTarget).data('bs.' + this.type)\n\n    if (!self) {\n      self = new this.constructor(obj.currentTarget, this.getDelegateOptions())\n      $(obj.currentTarget).data('bs.' + this.type, self)\n    }\n\n    if (obj instanceof $.Event) {\n      self.inState[obj.type == 'focusout' ? 'focus' : 'hover'] = false\n    }\n\n    if (self.isInStateTrue()) return\n\n    clearTimeout(self.timeout)\n\n    self.hoverState = 'out'\n\n    if (!self.options.delay || !self.options.delay.hide) return self.hide()\n\n    self.timeout = setTimeout(function () {\n      if (self.hoverState == 'out') self.hide()\n    }, self.options.delay.hide)\n  }\n\n  Tooltip.prototype.show = function () {\n    var e = $.Event('show.bs.' + this.type)\n\n    if (this.hasContent() && this.enabled) {\n      this.$element.trigger(e)\n\n      var inDom = $.contains(this.$element[0].ownerDocument.documentElement, this.$element[0])\n      if (e.isDefaultPrevented() || !inDom) return\n      var that = this\n\n      var $tip = this.tip()\n\n      var tipId = this.getUID(this.type)\n\n      this.setContent()\n      $tip.attr('id', tipId)\n      this.$element.attr('aria-describedby', tipId)\n\n      if (this.options.animation) $tip.addClass('fade')\n\n      var placement = typeof this.options.placement == 'function' ?\n        this.options.placement.call(this, $tip[0], this.$element[0]) :\n        this.options.placement\n\n      var autoToken = /\\s?auto?\\s?/i\n      var autoPlace = autoToken.test(placement)\n      if (autoPlace) placement = placement.replace(autoToken, '') || 'top'\n\n      $tip\n        .detach()\n        .css({ top: 0, left: 0, display: 'block' })\n        .addClass(placement)\n        .data('bs.' + this.type, this)\n\n      this.options.container ? $tip.appendTo(this.options.container) : $tip.insertAfter(this.$element)\n      this.$element.trigger('inserted.bs.' + this.type)\n\n      var pos          = this.getPosition()\n      var actualWidth  = $tip[0].offsetWidth\n      var actualHeight = $tip[0].offsetHeight\n\n      if (autoPlace) {\n        var orgPlacement = placement\n        var viewportDim = this.getPosition(this.$viewport)\n\n        placement = placement == 'bottom' && pos.bottom + actualHeight > viewportDim.bottom ? 'top'    :\n                    placement == 'top'    && pos.top    - actualHeight < viewportDim.top    ? 'bottom' :\n                    placement == 'right'  && pos.right  + actualWidth  > viewportDim.width  ? 'left'   :\n                    placement == 'left'   && pos.left   - actualWidth  < viewportDim.left   ? 'right'  :\n                    placement\n\n        $tip\n          .removeClass(orgPlacement)\n          .addClass(placement)\n      }\n\n      var calculatedOffset = this.getCalculatedOffset(placement, pos, actualWidth, actualHeight)\n\n      this.applyPlacement(calculatedOffset, placement)\n\n      var complete = function () {\n        var prevHoverState = that.hoverState\n        that.$element.trigger('shown.bs.' + that.type)\n        that.hoverState = null\n\n        if (prevHoverState == 'out') that.leave(that)\n      }\n\n      $.support.transition && this.$tip.hasClass('fade') ?\n        $tip\n          .one('bsTransitionEnd', complete)\n          .emulateTransitionEnd(Tooltip.TRANSITION_DURATION) :\n        complete()\n    }\n  }\n\n  Tooltip.prototype.applyPlacement = function (offset, placement) {\n    var $tip   = this.tip()\n    var width  = $tip[0].offsetWidth\n    var height = $tip[0].offsetHeight\n\n    // manually read margins because getBoundingClientRect includes difference\n    var marginTop = parseInt($tip.css('margin-top'), 10)\n    var marginLeft = parseInt($tip.css('margin-left'), 10)\n\n    // we must check for NaN for ie 8/9\n    if (isNaN(marginTop))  marginTop  = 0\n    if (isNaN(marginLeft)) marginLeft = 0\n\n    offset.top  += marginTop\n    offset.left += marginLeft\n\n    // $.fn.offset doesn't round pixel values\n    // so we use setOffset directly with our own function B-0\n    $.offset.setOffset($tip[0], $.extend({\n      using: function (props) {\n        $tip.css({\n          top: Math.round(props.top),\n          left: Math.round(props.left)\n        })\n      }\n    }, offset), 0)\n\n    $tip.addClass('in')\n\n    // check to see if placing tip in new offset caused the tip to resize itself\n    var actualWidth  = $tip[0].offsetWidth\n    var actualHeight = $tip[0].offsetHeight\n\n    if (placement == 'top' && actualHeight != height) {\n      offset.top = offset.top + height - actualHeight\n    }\n\n    var delta = this.getViewportAdjustedDelta(placement, offset, actualWidth, actualHeight)\n\n    if (delta.left) offset.left += delta.left\n    else offset.top += delta.top\n\n    var isVertical          = /top|bottom/.test(placement)\n    var arrowDelta          = isVertical ? delta.left * 2 - width + actualWidth : delta.top * 2 - height + actualHeight\n    var arrowOffsetPosition = isVertical ? 'offsetWidth' : 'offsetHeight'\n\n    $tip.offset(offset)\n    this.replaceArrow(arrowDelta, $tip[0][arrowOffsetPosition], isVertical)\n  }\n\n  Tooltip.prototype.replaceArrow = function (delta, dimension, isVertical) {\n    this.arrow()\n      .css(isVertical ? 'left' : 'top', 50 * (1 - delta / dimension) + '%')\n      .css(isVertical ? 'top' : 'left', '')\n  }\n\n  Tooltip.prototype.setContent = function () {\n    var $tip  = this.tip()\n    var title = this.getTitle()\n\n    $tip.find('.tooltip-inner')[this.options.html ? 'html' : 'text'](title)\n    $tip.removeClass('fade in top bottom left right')\n  }\n\n  Tooltip.prototype.hide = function (callback) {\n    var that = this\n    var $tip = $(this.$tip)\n    var e    = $.Event('hide.bs.' + this.type)\n\n    function complete() {\n      if (that.hoverState != 'in') $tip.detach()\n      if (that.$element) { // TODO: Check whether guarding this code with this `if` is really necessary.\n        that.$element\n          .removeAttr('aria-describedby')\n          .trigger('hidden.bs.' + that.type)\n      }\n      callback && callback()\n    }\n\n    this.$element.trigger(e)\n\n    if (e.isDefaultPrevented()) return\n\n    $tip.removeClass('in')\n\n    $.support.transition && $tip.hasClass('fade') ?\n      $tip\n        .one('bsTransitionEnd', complete)\n        .emulateTransitionEnd(Tooltip.TRANSITION_DURATION) :\n      complete()\n\n    this.hoverState = null\n\n    return this\n  }\n\n  Tooltip.prototype.fixTitle = function () {\n    var $e = this.$element\n    if ($e.attr('title') || typeof $e.attr('data-original-title') != 'string') {\n      $e.attr('data-original-title', $e.attr('title') || '').attr('title', '')\n    }\n  }\n\n  Tooltip.prototype.hasContent = function () {\n    return this.getTitle()\n  }\n\n  Tooltip.prototype.getPosition = function ($element) {\n    $element   = $element || this.$element\n\n    var el     = $element[0]\n    var isBody = el.tagName == 'BODY'\n\n    var elRect    = el.getBoundingClientRect()\n    if (elRect.width == null) {\n      // width and height are missing in IE8, so compute them manually; see https://github.com/twbs/bootstrap/issues/14093\n      elRect = $.extend({}, elRect, { width: elRect.right - elRect.left, height: elRect.bottom - elRect.top })\n    }\n    var isSvg = window.SVGElement && el instanceof window.SVGElement\n    // Avoid using $.offset() on SVGs since it gives incorrect results in jQuery 3.\n    // See https://github.com/twbs/bootstrap/issues/20280\n    var elOffset  = isBody ? { top: 0, left: 0 } : (isSvg ? null : $element.offset())\n    var scroll    = { scroll: isBody ? document.documentElement.scrollTop || document.body.scrollTop : $element.scrollTop() }\n    var outerDims = isBody ? { width: $(window).width(), height: $(window).height() } : null\n\n    return $.extend({}, elRect, scroll, outerDims, elOffset)\n  }\n\n  Tooltip.prototype.getCalculatedOffset = function (placement, pos, actualWidth, actualHeight) {\n    return placement == 'bottom' ? { top: pos.top + pos.height,   left: pos.left + pos.width / 2 - actualWidth / 2 } :\n           placement == 'top'    ? { top: pos.top - actualHeight, left: pos.left + pos.width / 2 - actualWidth / 2 } :\n           placement == 'left'   ? { top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left - actualWidth } :\n        /* placement == 'right' */ { top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left + pos.width }\n\n  }\n\n  Tooltip.prototype.getViewportAdjustedDelta = function (placement, pos, actualWidth, actualHeight) {\n    var delta = { top: 0, left: 0 }\n    if (!this.$viewport) return delta\n\n    var viewportPadding = this.options.viewport && this.options.viewport.padding || 0\n    var viewportDimensions = this.getPosition(this.$viewport)\n\n    if (/right|left/.test(placement)) {\n      var topEdgeOffset    = pos.top - viewportPadding - viewportDimensions.scroll\n      var bottomEdgeOffset = pos.top + viewportPadding - viewportDimensions.scroll + actualHeight\n      if (topEdgeOffset < viewportDimensions.top) { // top overflow\n        delta.top = viewportDimensions.top - topEdgeOffset\n      } else if (bottomEdgeOffset > viewportDimensions.top + viewportDimensions.height) { // bottom overflow\n        delta.top = viewportDimensions.top + viewportDimensions.height - bottomEdgeOffset\n      }\n    } else {\n      var leftEdgeOffset  = pos.left - viewportPadding\n      var rightEdgeOffset = pos.left + viewportPadding + actualWidth\n      if (leftEdgeOffset < viewportDimensions.left) { // left overflow\n        delta.left = viewportDimensions.left - leftEdgeOffset\n      } else if (rightEdgeOffset > viewportDimensions.right) { // right overflow\n        delta.left = viewportDimensions.left + viewportDimensions.width - rightEdgeOffset\n      }\n    }\n\n    return delta\n  }\n\n  Tooltip.prototype.getTitle = function () {\n    var title\n    var $e = this.$element\n    var o  = this.options\n\n    title = $e.attr('data-original-title')\n      || (typeof o.title == 'function' ? o.title.call($e[0]) :  o.title)\n\n    return title\n  }\n\n  Tooltip.prototype.getUID = function (prefix) {\n    do prefix += ~~(Math.random() * 1000000)\n    while (document.getElementById(prefix))\n    return prefix\n  }\n\n  Tooltip.prototype.tip = function () {\n    if (!this.$tip) {\n      this.$tip = $(this.options.template)\n      if (this.$tip.length != 1) {\n        throw new Error(this.type + ' `template` option must consist of exactly 1 top-level element!')\n      }\n    }\n    return this.$tip\n  }\n\n  Tooltip.prototype.arrow = function () {\n    return (this.$arrow = this.$arrow || this.tip().find('.tooltip-arrow'))\n  }\n\n  Tooltip.prototype.enable = function () {\n    this.enabled = true\n  }\n\n  Tooltip.prototype.disable = function () {\n    this.enabled = false\n  }\n\n  Tooltip.prototype.toggleEnabled = function () {\n    this.enabled = !this.enabled\n  }\n\n  Tooltip.prototype.toggle = function (e) {\n    var self = this\n    if (e) {\n      self = $(e.currentTarget).data('bs.' + this.type)\n      if (!self) {\n        self = new this.constructor(e.currentTarget, this.getDelegateOptions())\n        $(e.currentTarget).data('bs.' + this.type, self)\n      }\n    }\n\n    if (e) {\n      self.inState.click = !self.inState.click\n      if (self.isInStateTrue()) self.enter(self)\n      else self.leave(self)\n    } else {\n      self.tip().hasClass('in') ? self.leave(self) : self.enter(self)\n    }\n  }\n\n  Tooltip.prototype.destroy = function () {\n    var that = this\n    clearTimeout(this.timeout)\n    this.hide(function () {\n      that.$element.off('.' + that.type).removeData('bs.' + that.type)\n      if (that.$tip) {\n        that.$tip.detach()\n      }\n      that.$tip = null\n      that.$arrow = null\n      that.$viewport = null\n      that.$element = null\n    })\n  }\n\n\n  // TOOLTIP PLUGIN DEFINITION\n  // =========================\n\n  function Plugin(option) {\n    return this.each(function () {\n      var $this   = $(this)\n      var data    = $this.data('bs.tooltip')\n      var options = typeof option == 'object' && option\n\n      if (!data && /destroy|hide/.test(option)) return\n      if (!data) $this.data('bs.tooltip', (data = new Tooltip(this, options)))\n      if (typeof option == 'string') data[option]()\n    })\n  }\n\n  var old = $.fn.tooltip\n\n  $.fn.tooltip             = Plugin\n  $.fn.tooltip.Constructor = Tooltip\n\n\n  // TOOLTIP NO CONFLICT\n  // ===================\n\n  $.fn.tooltip.noConflict = function () {\n    $.fn.tooltip = old\n    return this\n  }\n\n}(jQuery);\n\n/* ========================================================================\n * Bootstrap: popover.js v3.3.7\n * http://getbootstrap.com/javascript/#popovers\n * ========================================================================\n * Copyright 2011-2016 Twitter, Inc.\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)\n * ======================================================================== */\n\n\n+function ($) {\n  'use strict';\n\n  // POPOVER PUBLIC CLASS DEFINITION\n  // ===============================\n\n  var Popover = function (element, options) {\n    this.init('popover', element, options)\n  }\n\n  if (!$.fn.tooltip) throw new Error('Popover requires tooltip.js')\n\n  Popover.VERSION  = '3.3.7'\n\n  Popover.DEFAULTS = $.extend({}, $.fn.tooltip.Constructor.DEFAULTS, {\n    placement: 'right',\n    trigger: 'click',\n    content: '',\n    template: '<div class=\"popover\" role=\"tooltip\"><div class=\"arrow\"></div><h3 class=\"popover-title\"></h3><div class=\"popover-content\"></div></div>'\n  })\n\n\n  // NOTE: POPOVER EXTENDS tooltip.js\n  // ================================\n\n  Popover.prototype = $.extend({}, $.fn.tooltip.Constructor.prototype)\n\n  Popover.prototype.constructor = Popover\n\n  Popover.prototype.getDefaults = function () {\n    return Popover.DEFAULTS\n  }\n\n  Popover.prototype.setContent = function () {\n    var $tip    = this.tip()\n    var title   = this.getTitle()\n    var content = this.getContent()\n\n    $tip.find('.popover-title')[this.options.html ? 'html' : 'text'](title)\n    $tip.find('.popover-content').children().detach().end()[ // we use append for html objects to maintain js events\n      this.options.html ? (typeof content == 'string' ? 'html' : 'append') : 'text'\n    ](content)\n\n    $tip.removeClass('fade top bottom left right in')\n\n    // IE8 doesn't accept hiding via the `:empty` pseudo selector, we have to do\n    // this manually by checking the contents.\n    if (!$tip.find('.popover-title').html()) $tip.find('.popover-title').hide()\n  }\n\n  Popover.prototype.hasContent = function () {\n    return this.getTitle() || this.getContent()\n  }\n\n  Popover.prototype.getContent = function () {\n    var $e = this.$element\n    var o  = this.options\n\n    return $e.attr('data-content')\n      || (typeof o.content == 'function' ?\n            o.content.call($e[0]) :\n            o.content)\n  }\n\n  Popover.prototype.arrow = function () {\n    return (this.$arrow = this.$arrow || this.tip().find('.arrow'))\n  }\n\n\n  // POPOVER PLUGIN DEFINITION\n  // =========================\n\n  function Plugin(option) {\n    return this.each(function () {\n      var $this   = $(this)\n      var data    = $this.data('bs.popover')\n      var options = typeof option == 'object' && option\n\n      if (!data && /destroy|hide/.test(option)) return\n      if (!data) $this.data('bs.popover', (data = new Popover(this, options)))\n      if (typeof option == 'string') data[option]()\n    })\n  }\n\n  var old = $.fn.popover\n\n  $.fn.popover             = Plugin\n  $.fn.popover.Constructor = Popover\n\n\n  // POPOVER NO CONFLICT\n  // ===================\n\n  $.fn.popover.noConflict = function () {\n    $.fn.popover = old\n    return this\n  }\n\n}(jQuery);\n\n/* ========================================================================\n * Bootstrap: scrollspy.js v3.3.7\n * http://getbootstrap.com/javascript/#scrollspy\n * ========================================================================\n * Copyright 2011-2016 Twitter, Inc.\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)\n * ======================================================================== */\n\n\n+function ($) {\n  'use strict';\n\n  // SCROLLSPY CLASS DEFINITION\n  // ==========================\n\n  function ScrollSpy(element, options) {\n    this.$body          = $(document.body)\n    this.$scrollElement = $(element).is(document.body) ? $(window) : $(element)\n    this.options        = $.extend({}, ScrollSpy.DEFAULTS, options)\n    this.selector       = (this.options.target || '') + ' .nav li > a'\n    this.offsets        = []\n    this.targets        = []\n    this.activeTarget   = null\n    this.scrollHeight   = 0\n\n    this.$scrollElement.on('scroll.bs.scrollspy', $.proxy(this.process, this))\n    this.refresh()\n    this.process()\n  }\n\n  ScrollSpy.VERSION  = '3.3.7'\n\n  ScrollSpy.DEFAULTS = {\n    offset: 10\n  }\n\n  ScrollSpy.prototype.getScrollHeight = function () {\n    return this.$scrollElement[0].scrollHeight || Math.max(this.$body[0].scrollHeight, document.documentElement.scrollHeight)\n  }\n\n  ScrollSpy.prototype.refresh = function () {\n    var that          = this\n    var offsetMethod  = 'offset'\n    var offsetBase    = 0\n\n    this.offsets      = []\n    this.targets      = []\n    this.scrollHeight = this.getScrollHeight()\n\n    if (!$.isWindow(this.$scrollElement[0])) {\n      offsetMethod = 'position'\n      offsetBase   = this.$scrollElement.scrollTop()\n    }\n\n    this.$body\n      .find(this.selector)\n      .map(function () {\n        var $el   = $(this)\n        var href  = $el.data('target') || $el.attr('href')\n        var $href = /^#./.test(href) && $(href)\n\n        return ($href\n          && $href.length\n          && $href.is(':visible')\n          && [[$href[offsetMethod]().top + offsetBase, href]]) || null\n      })\n      .sort(function (a, b) { return a[0] - b[0] })\n      .each(function () {\n        that.offsets.push(this[0])\n        that.targets.push(this[1])\n      })\n  }\n\n  ScrollSpy.prototype.process = function () {\n    var scrollTop    = this.$scrollElement.scrollTop() + this.options.offset\n    var scrollHeight = this.getScrollHeight()\n    var maxScroll    = this.options.offset + scrollHeight - this.$scrollElement.height()\n    var offsets      = this.offsets\n    var targets      = this.targets\n    var activeTarget = this.activeTarget\n    var i\n\n    if (this.scrollHeight != scrollHeight) {\n      this.refresh()\n    }\n\n    if (scrollTop >= maxScroll) {\n      return activeTarget != (i = targets[targets.length - 1]) && this.activate(i)\n    }\n\n    if (activeTarget && scrollTop < offsets[0]) {\n      this.activeTarget = null\n      return this.clear()\n    }\n\n    for (i = offsets.length; i--;) {\n      activeTarget != targets[i]\n        && scrollTop >= offsets[i]\n        && (offsets[i + 1] === undefined || scrollTop < offsets[i + 1])\n        && this.activate(targets[i])\n    }\n  }\n\n  ScrollSpy.prototype.activate = function (target) {\n    this.activeTarget = target\n\n    this.clear()\n\n    var selector = this.selector +\n      '[data-target=\"' + target + '\"],' +\n      this.selector + '[href=\"' + target + '\"]'\n\n    var active = $(selector)\n      .parents('li')\n      .addClass('active')\n\n    if (active.parent('.dropdown-menu').length) {\n      active = active\n        .closest('li.dropdown')\n        .addClass('active')\n    }\n\n    active.trigger('activate.bs.scrollspy')\n  }\n\n  ScrollSpy.prototype.clear = function () {\n    $(this.selector)\n      .parentsUntil(this.options.target, '.active')\n      .removeClass('active')\n  }\n\n\n  // SCROLLSPY PLUGIN DEFINITION\n  // ===========================\n\n  function Plugin(option) {\n    return this.each(function () {\n      var $this   = $(this)\n      var data    = $this.data('bs.scrollspy')\n      var options = typeof option == 'object' && option\n\n      if (!data) $this.data('bs.scrollspy', (data = new ScrollSpy(this, options)))\n      if (typeof option == 'string') data[option]()\n    })\n  }\n\n  var old = $.fn.scrollspy\n\n  $.fn.scrollspy             = Plugin\n  $.fn.scrollspy.Constructor = ScrollSpy\n\n\n  // SCROLLSPY NO CONFLICT\n  // =====================\n\n  $.fn.scrollspy.noConflict = function () {\n    $.fn.scrollspy = old\n    return this\n  }\n\n\n  // SCROLLSPY DATA-API\n  // ==================\n\n  $(window).on('load.bs.scrollspy.data-api', function () {\n    $('[data-spy=\"scroll\"]').each(function () {\n      var $spy = $(this)\n      Plugin.call($spy, $spy.data())\n    })\n  })\n\n}(jQuery);\n\n/* ========================================================================\n * Bootstrap: tab.js v3.3.7\n * http://getbootstrap.com/javascript/#tabs\n * ========================================================================\n * Copyright 2011-2016 Twitter, Inc.\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)\n * ======================================================================== */\n\n\n+function ($) {\n  'use strict';\n\n  // TAB CLASS DEFINITION\n  // ====================\n\n  var Tab = function (element) {\n    // jscs:disable requireDollarBeforejQueryAssignment\n    this.element = $(element)\n    // jscs:enable requireDollarBeforejQueryAssignment\n  }\n\n  Tab.VERSION = '3.3.7'\n\n  Tab.TRANSITION_DURATION = 150\n\n  Tab.prototype.show = function () {\n    var $this    = this.element\n    var $ul      = $this.closest('ul:not(.dropdown-menu)')\n    var selector = $this.data('target')\n\n    if (!selector) {\n      selector = $this.attr('href')\n      selector = selector && selector.replace(/.*(?=#[^\\s]*$)/, '') // strip for ie7\n    }\n\n    if ($this.parent('li').hasClass('active')) return\n\n    var $previous = $ul.find('.active:last a')\n    var hideEvent = $.Event('hide.bs.tab', {\n      relatedTarget: $this[0]\n    })\n    var showEvent = $.Event('show.bs.tab', {\n      relatedTarget: $previous[0]\n    })\n\n    $previous.trigger(hideEvent)\n    $this.trigger(showEvent)\n\n    if (showEvent.isDefaultPrevented() || hideEvent.isDefaultPrevented()) return\n\n    var $target = $(selector)\n\n    this.activate($this.closest('li'), $ul)\n    this.activate($target, $target.parent(), function () {\n      $previous.trigger({\n        type: 'hidden.bs.tab',\n        relatedTarget: $this[0]\n      })\n      $this.trigger({\n        type: 'shown.bs.tab',\n        relatedTarget: $previous[0]\n      })\n    })\n  }\n\n  Tab.prototype.activate = function (element, container, callback) {\n    var $active    = container.find('> .active')\n    var transition = callback\n      && $.support.transition\n      && ($active.length && $active.hasClass('fade') || !!container.find('> .fade').length)\n\n    function next() {\n      $active\n        .removeClass('active')\n        .find('> .dropdown-menu > .active')\n          .removeClass('active')\n        .end()\n        .find('[data-toggle=\"tab\"]')\n          .attr('aria-expanded', false)\n\n      element\n        .addClass('active')\n        .find('[data-toggle=\"tab\"]')\n          .attr('aria-expanded', true)\n\n      if (transition) {\n        element[0].offsetWidth // reflow for transition\n        element.addClass('in')\n      } else {\n        element.removeClass('fade')\n      }\n\n      if (element.parent('.dropdown-menu').length) {\n        element\n          .closest('li.dropdown')\n            .addClass('active')\n          .end()\n          .find('[data-toggle=\"tab\"]')\n            .attr('aria-expanded', true)\n      }\n\n      callback && callback()\n    }\n\n    $active.length && transition ?\n      $active\n        .one('bsTransitionEnd', next)\n        .emulateTransitionEnd(Tab.TRANSITION_DURATION) :\n      next()\n\n    $active.removeClass('in')\n  }\n\n\n  // TAB PLUGIN DEFINITION\n  // =====================\n\n  function Plugin(option) {\n    return this.each(function () {\n      var $this = $(this)\n      var data  = $this.data('bs.tab')\n\n      if (!data) $this.data('bs.tab', (data = new Tab(this)))\n      if (typeof option == 'string') data[option]()\n    })\n  }\n\n  var old = $.fn.tab\n\n  $.fn.tab             = Plugin\n  $.fn.tab.Constructor = Tab\n\n\n  // TAB NO CONFLICT\n  // ===============\n\n  $.fn.tab.noConflict = function () {\n    $.fn.tab = old\n    return this\n  }\n\n\n  // TAB DATA-API\n  // ============\n\n  var clickHandler = function (e) {\n    e.preventDefault()\n    Plugin.call($(this), 'show')\n  }\n\n  $(document)\n    .on('click.bs.tab.data-api', '[data-toggle=\"tab\"]', clickHandler)\n    .on('click.bs.tab.data-api', '[data-toggle=\"pill\"]', clickHandler)\n\n}(jQuery);\n\n/* ========================================================================\n * Bootstrap: affix.js v3.3.7\n * http://getbootstrap.com/javascript/#affix\n * ========================================================================\n * Copyright 2011-2016 Twitter, Inc.\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)\n * ======================================================================== */\n\n\n+function ($) {\n  'use strict';\n\n  // AFFIX CLASS DEFINITION\n  // ======================\n\n  var Affix = function (element, options) {\n    this.options = $.extend({}, Affix.DEFAULTS, options)\n\n    this.$target = $(this.options.target)\n      .on('scroll.bs.affix.data-api', $.proxy(this.checkPosition, this))\n      .on('click.bs.affix.data-api',  $.proxy(this.checkPositionWithEventLoop, this))\n\n    this.$element     = $(element)\n    this.affixed      = null\n    this.unpin        = null\n    this.pinnedOffset = null\n\n    this.checkPosition()\n  }\n\n  Affix.VERSION  = '3.3.7'\n\n  Affix.RESET    = 'affix affix-top affix-bottom'\n\n  Affix.DEFAULTS = {\n    offset: 0,\n    target: window\n  }\n\n  Affix.prototype.getState = function (scrollHeight, height, offsetTop, offsetBottom) {\n    var scrollTop    = this.$target.scrollTop()\n    var position     = this.$element.offset()\n    var targetHeight = this.$target.height()\n\n    if (offsetTop != null && this.affixed == 'top') return scrollTop < offsetTop ? 'top' : false\n\n    if (this.affixed == 'bottom') {\n      if (offsetTop != null) return (scrollTop + this.unpin <= position.top) ? false : 'bottom'\n      return (scrollTop + targetHeight <= scrollHeight - offsetBottom) ? false : 'bottom'\n    }\n\n    var initializing   = this.affixed == null\n    var colliderTop    = initializing ? scrollTop : position.top\n    var colliderHeight = initializing ? targetHeight : height\n\n    if (offsetTop != null && scrollTop <= offsetTop) return 'top'\n    if (offsetBottom != null && (colliderTop + colliderHeight >= scrollHeight - offsetBottom)) return 'bottom'\n\n    return false\n  }\n\n  Affix.prototype.getPinnedOffset = function () {\n    if (this.pinnedOffset) return this.pinnedOffset\n    this.$element.removeClass(Affix.RESET).addClass('affix')\n    var scrollTop = this.$target.scrollTop()\n    var position  = this.$element.offset()\n    return (this.pinnedOffset = position.top - scrollTop)\n  }\n\n  Affix.prototype.checkPositionWithEventLoop = function () {\n    setTimeout($.proxy(this.checkPosition, this), 1)\n  }\n\n  Affix.prototype.checkPosition = function () {\n    if (!this.$element.is(':visible')) return\n\n    var height       = this.$element.height()\n    var offset       = this.options.offset\n    var offsetTop    = offset.top\n    var offsetBottom = offset.bottom\n    var scrollHeight = Math.max($(document).height(), $(document.body).height())\n\n    if (typeof offset != 'object')         offsetBottom = offsetTop = offset\n    if (typeof offsetTop == 'function')    offsetTop    = offset.top(this.$element)\n    if (typeof offsetBottom == 'function') offsetBottom = offset.bottom(this.$element)\n\n    var affix = this.getState(scrollHeight, height, offsetTop, offsetBottom)\n\n    if (this.affixed != affix) {\n      if (this.unpin != null) this.$element.css('top', '')\n\n      var affixType = 'affix' + (affix ? '-' + affix : '')\n      var e         = $.Event(affixType + '.bs.affix')\n\n      this.$element.trigger(e)\n\n      if (e.isDefaultPrevented()) return\n\n      this.affixed = affix\n      this.unpin = affix == 'bottom' ? this.getPinnedOffset() : null\n\n      this.$element\n        .removeClass(Affix.RESET)\n        .addClass(affixType)\n        .trigger(affixType.replace('affix', 'affixed') + '.bs.affix')\n    }\n\n    if (affix == 'bottom') {\n      this.$element.offset({\n        top: scrollHeight - height - offsetBottom\n      })\n    }\n  }\n\n\n  // AFFIX PLUGIN DEFINITION\n  // =======================\n\n  function Plugin(option) {\n    return this.each(function () {\n      var $this   = $(this)\n      var data    = $this.data('bs.affix')\n      var options = typeof option == 'object' && option\n\n      if (!data) $this.data('bs.affix', (data = new Affix(this, options)))\n      if (typeof option == 'string') data[option]()\n    })\n  }\n\n  var old = $.fn.affix\n\n  $.fn.affix             = Plugin\n  $.fn.affix.Constructor = Affix\n\n\n  // AFFIX NO CONFLICT\n  // =================\n\n  $.fn.affix.noConflict = function () {\n    $.fn.affix = old\n    return this\n  }\n\n\n  // AFFIX DATA-API\n  // ==============\n\n  $(window).on('load', function () {\n    $('[data-spy=\"affix\"]').each(function () {\n      var $spy = $(this)\n      var data = $spy.data()\n\n      data.offset = data.offset || {}\n\n      if (data.offsetBottom != null) data.offset.bottom = data.offsetBottom\n      if (data.offsetTop    != null) data.offset.top    = data.offsetTop\n\n      Plugin.call($spy, data)\n    })\n  })\n\n}(jQuery);\n"
  },
  {
    "path": "app_backend/vendor/bootstrap-social/bootstrap-social.css",
    "content": "/*\n * Social Buttons for Bootstrap\n *\n * Copyright 2013-2014 Panayiotis Lipiridis\n * Licensed under the MIT License\n *\n * https://github.com/lipis/bootstrap-social\n */\n\n.btn-social{position:relative;padding-left:44px;text-align:left;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.btn-social>:first-child{position:absolute;left:0;top:0;bottom:0;width:32px;line-height:34px;font-size:1.6em;text-align:center;border-right:1px solid rgba(0,0,0,0.2)}\n.btn-social.btn-lg{padding-left:61px}.btn-social.btn-lg :first-child{line-height:45px;width:45px;font-size:1.8em}\n.btn-social.btn-sm{padding-left:38px}.btn-social.btn-sm :first-child{line-height:28px;width:28px;font-size:1.4em}\n.btn-social.btn-xs{padding-left:30px}.btn-social.btn-xs :first-child{line-height:20px;width:20px;font-size:1.2em}\n.btn-social-icon{position:relative;padding-left:44px;text-align:left;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;height:34px;width:34px;padding:0}.btn-social-icon>:first-child{position:absolute;left:0;top:0;bottom:0;width:32px;line-height:34px;font-size:1.6em;text-align:center;border-right:1px solid rgba(0,0,0,0.2)}\n.btn-social-icon.btn-lg{padding-left:61px}.btn-social-icon.btn-lg :first-child{line-height:45px;width:45px;font-size:1.8em}\n.btn-social-icon.btn-sm{padding-left:38px}.btn-social-icon.btn-sm :first-child{line-height:28px;width:28px;font-size:1.4em}\n.btn-social-icon.btn-xs{padding-left:30px}.btn-social-icon.btn-xs :first-child{line-height:20px;width:20px;font-size:1.2em}\n.btn-social-icon :first-child{border:none;text-align:center;width:100% !important}\n.btn-social-icon.btn-lg{height:45px;width:45px;padding-left:0;padding-right:0}\n.btn-social-icon.btn-sm{height:30px;width:30px;padding-left:0;padding-right:0}\n.btn-social-icon.btn-xs{height:22px;width:22px;padding-left:0;padding-right:0}\n.btn-adn{color:#fff;background-color:#d87a68;border-color:rgba(0,0,0,0.2)}.btn-adn:hover,.btn-adn:focus,.btn-adn:active,.btn-adn.active,.open>.dropdown-toggle.btn-adn{color:#fff;background-color:#ce563f;border-color:rgba(0,0,0,0.2)}\n.btn-adn:active,.btn-adn.active,.open>.dropdown-toggle.btn-adn{background-image:none}\n.btn-adn.disabled,.btn-adn[disabled],fieldset[disabled] .btn-adn,.btn-adn.disabled:hover,.btn-adn[disabled]:hover,fieldset[disabled] .btn-adn:hover,.btn-adn.disabled:focus,.btn-adn[disabled]:focus,fieldset[disabled] .btn-adn:focus,.btn-adn.disabled:active,.btn-adn[disabled]:active,fieldset[disabled] .btn-adn:active,.btn-adn.disabled.active,.btn-adn[disabled].active,fieldset[disabled] .btn-adn.active{background-color:#d87a68;border-color:rgba(0,0,0,0.2)}\n.btn-adn .badge{color:#d87a68;background-color:#fff}\n.btn-bitbucket{color:#fff;background-color:#205081;border-color:rgba(0,0,0,0.2)}.btn-bitbucket:hover,.btn-bitbucket:focus,.btn-bitbucket:active,.btn-bitbucket.active,.open>.dropdown-toggle.btn-bitbucket{color:#fff;background-color:#163758;border-color:rgba(0,0,0,0.2)}\n.btn-bitbucket:active,.btn-bitbucket.active,.open>.dropdown-toggle.btn-bitbucket{background-image:none}\n.btn-bitbucket.disabled,.btn-bitbucket[disabled],fieldset[disabled] .btn-bitbucket,.btn-bitbucket.disabled:hover,.btn-bitbucket[disabled]:hover,fieldset[disabled] .btn-bitbucket:hover,.btn-bitbucket.disabled:focus,.btn-bitbucket[disabled]:focus,fieldset[disabled] .btn-bitbucket:focus,.btn-bitbucket.disabled:active,.btn-bitbucket[disabled]:active,fieldset[disabled] .btn-bitbucket:active,.btn-bitbucket.disabled.active,.btn-bitbucket[disabled].active,fieldset[disabled] .btn-bitbucket.active{background-color:#205081;border-color:rgba(0,0,0,0.2)}\n.btn-bitbucket .badge{color:#205081;background-color:#fff}\n.btn-dropbox{color:#fff;background-color:#1087dd;border-color:rgba(0,0,0,0.2)}.btn-dropbox:hover,.btn-dropbox:focus,.btn-dropbox:active,.btn-dropbox.active,.open>.dropdown-toggle.btn-dropbox{color:#fff;background-color:#0d6aad;border-color:rgba(0,0,0,0.2)}\n.btn-dropbox:active,.btn-dropbox.active,.open>.dropdown-toggle.btn-dropbox{background-image:none}\n.btn-dropbox.disabled,.btn-dropbox[disabled],fieldset[disabled] .btn-dropbox,.btn-dropbox.disabled:hover,.btn-dropbox[disabled]:hover,fieldset[disabled] .btn-dropbox:hover,.btn-dropbox.disabled:focus,.btn-dropbox[disabled]:focus,fieldset[disabled] .btn-dropbox:focus,.btn-dropbox.disabled:active,.btn-dropbox[disabled]:active,fieldset[disabled] .btn-dropbox:active,.btn-dropbox.disabled.active,.btn-dropbox[disabled].active,fieldset[disabled] .btn-dropbox.active{background-color:#1087dd;border-color:rgba(0,0,0,0.2)}\n.btn-dropbox .badge{color:#1087dd;background-color:#fff}\n.btn-facebook{color:#fff;background-color:#3b5998;border-color:rgba(0,0,0,0.2)}.btn-facebook:hover,.btn-facebook:focus,.btn-facebook:active,.btn-facebook.active,.open>.dropdown-toggle.btn-facebook{color:#fff;background-color:#2d4373;border-color:rgba(0,0,0,0.2)}\n.btn-facebook:active,.btn-facebook.active,.open>.dropdown-toggle.btn-facebook{background-image:none}\n.btn-facebook.disabled,.btn-facebook[disabled],fieldset[disabled] .btn-facebook,.btn-facebook.disabled:hover,.btn-facebook[disabled]:hover,fieldset[disabled] .btn-facebook:hover,.btn-facebook.disabled:focus,.btn-facebook[disabled]:focus,fieldset[disabled] .btn-facebook:focus,.btn-facebook.disabled:active,.btn-facebook[disabled]:active,fieldset[disabled] .btn-facebook:active,.btn-facebook.disabled.active,.btn-facebook[disabled].active,fieldset[disabled] .btn-facebook.active{background-color:#3b5998;border-color:rgba(0,0,0,0.2)}\n.btn-facebook .badge{color:#3b5998;background-color:#fff}\n.btn-flickr{color:#fff;background-color:#ff0084;border-color:rgba(0,0,0,0.2)}.btn-flickr:hover,.btn-flickr:focus,.btn-flickr:active,.btn-flickr.active,.open>.dropdown-toggle.btn-flickr{color:#fff;background-color:#cc006a;border-color:rgba(0,0,0,0.2)}\n.btn-flickr:active,.btn-flickr.active,.open>.dropdown-toggle.btn-flickr{background-image:none}\n.btn-flickr.disabled,.btn-flickr[disabled],fieldset[disabled] .btn-flickr,.btn-flickr.disabled:hover,.btn-flickr[disabled]:hover,fieldset[disabled] .btn-flickr:hover,.btn-flickr.disabled:focus,.btn-flickr[disabled]:focus,fieldset[disabled] .btn-flickr:focus,.btn-flickr.disabled:active,.btn-flickr[disabled]:active,fieldset[disabled] .btn-flickr:active,.btn-flickr.disabled.active,.btn-flickr[disabled].active,fieldset[disabled] .btn-flickr.active{background-color:#ff0084;border-color:rgba(0,0,0,0.2)}\n.btn-flickr .badge{color:#ff0084;background-color:#fff}\n.btn-foursquare{color:#fff;background-color:#f94877;border-color:rgba(0,0,0,0.2)}.btn-foursquare:hover,.btn-foursquare:focus,.btn-foursquare:active,.btn-foursquare.active,.open>.dropdown-toggle.btn-foursquare{color:#fff;background-color:#f71752;border-color:rgba(0,0,0,0.2)}\n.btn-foursquare:active,.btn-foursquare.active,.open>.dropdown-toggle.btn-foursquare{background-image:none}\n.btn-foursquare.disabled,.btn-foursquare[disabled],fieldset[disabled] .btn-foursquare,.btn-foursquare.disabled:hover,.btn-foursquare[disabled]:hover,fieldset[disabled] .btn-foursquare:hover,.btn-foursquare.disabled:focus,.btn-foursquare[disabled]:focus,fieldset[disabled] .btn-foursquare:focus,.btn-foursquare.disabled:active,.btn-foursquare[disabled]:active,fieldset[disabled] .btn-foursquare:active,.btn-foursquare.disabled.active,.btn-foursquare[disabled].active,fieldset[disabled] .btn-foursquare.active{background-color:#f94877;border-color:rgba(0,0,0,0.2)}\n.btn-foursquare .badge{color:#f94877;background-color:#fff}\n.btn-github{color:#fff;background-color:#444;border-color:rgba(0,0,0,0.2)}.btn-github:hover,.btn-github:focus,.btn-github:active,.btn-github.active,.open>.dropdown-toggle.btn-github{color:#fff;background-color:#2b2b2b;border-color:rgba(0,0,0,0.2)}\n.btn-github:active,.btn-github.active,.open>.dropdown-toggle.btn-github{background-image:none}\n.btn-github.disabled,.btn-github[disabled],fieldset[disabled] .btn-github,.btn-github.disabled:hover,.btn-github[disabled]:hover,fieldset[disabled] .btn-github:hover,.btn-github.disabled:focus,.btn-github[disabled]:focus,fieldset[disabled] .btn-github:focus,.btn-github.disabled:active,.btn-github[disabled]:active,fieldset[disabled] .btn-github:active,.btn-github.disabled.active,.btn-github[disabled].active,fieldset[disabled] .btn-github.active{background-color:#444;border-color:rgba(0,0,0,0.2)}\n.btn-github .badge{color:#444;background-color:#fff}\n.btn-google-plus{color:#fff;background-color:#dd4b39;border-color:rgba(0,0,0,0.2)}.btn-google-plus:hover,.btn-google-plus:focus,.btn-google-plus:active,.btn-google-plus.active,.open>.dropdown-toggle.btn-google-plus{color:#fff;background-color:#c23321;border-color:rgba(0,0,0,0.2)}\n.btn-google-plus:active,.btn-google-plus.active,.open>.dropdown-toggle.btn-google-plus{background-image:none}\n.btn-google-plus.disabled,.btn-google-plus[disabled],fieldset[disabled] .btn-google-plus,.btn-google-plus.disabled:hover,.btn-google-plus[disabled]:hover,fieldset[disabled] .btn-google-plus:hover,.btn-google-plus.disabled:focus,.btn-google-plus[disabled]:focus,fieldset[disabled] .btn-google-plus:focus,.btn-google-plus.disabled:active,.btn-google-plus[disabled]:active,fieldset[disabled] .btn-google-plus:active,.btn-google-plus.disabled.active,.btn-google-plus[disabled].active,fieldset[disabled] .btn-google-plus.active{background-color:#dd4b39;border-color:rgba(0,0,0,0.2)}\n.btn-google-plus .badge{color:#dd4b39;background-color:#fff}\n.btn-instagram{color:#fff;background-color:#3f729b;border-color:rgba(0,0,0,0.2)}.btn-instagram:hover,.btn-instagram:focus,.btn-instagram:active,.btn-instagram.active,.open>.dropdown-toggle.btn-instagram{color:#fff;background-color:#305777;border-color:rgba(0,0,0,0.2)}\n.btn-instagram:active,.btn-instagram.active,.open>.dropdown-toggle.btn-instagram{background-image:none}\n.btn-instagram.disabled,.btn-instagram[disabled],fieldset[disabled] .btn-instagram,.btn-instagram.disabled:hover,.btn-instagram[disabled]:hover,fieldset[disabled] .btn-instagram:hover,.btn-instagram.disabled:focus,.btn-instagram[disabled]:focus,fieldset[disabled] .btn-instagram:focus,.btn-instagram.disabled:active,.btn-instagram[disabled]:active,fieldset[disabled] .btn-instagram:active,.btn-instagram.disabled.active,.btn-instagram[disabled].active,fieldset[disabled] .btn-instagram.active{background-color:#3f729b;border-color:rgba(0,0,0,0.2)}\n.btn-instagram .badge{color:#3f729b;background-color:#fff}\n.btn-linkedin{color:#fff;background-color:#007bb6;border-color:rgba(0,0,0,0.2)}.btn-linkedin:hover,.btn-linkedin:focus,.btn-linkedin:active,.btn-linkedin.active,.open>.dropdown-toggle.btn-linkedin{color:#fff;background-color:#005983;border-color:rgba(0,0,0,0.2)}\n.btn-linkedin:active,.btn-linkedin.active,.open>.dropdown-toggle.btn-linkedin{background-image:none}\n.btn-linkedin.disabled,.btn-linkedin[disabled],fieldset[disabled] .btn-linkedin,.btn-linkedin.disabled:hover,.btn-linkedin[disabled]:hover,fieldset[disabled] .btn-linkedin:hover,.btn-linkedin.disabled:focus,.btn-linkedin[disabled]:focus,fieldset[disabled] .btn-linkedin:focus,.btn-linkedin.disabled:active,.btn-linkedin[disabled]:active,fieldset[disabled] .btn-linkedin:active,.btn-linkedin.disabled.active,.btn-linkedin[disabled].active,fieldset[disabled] .btn-linkedin.active{background-color:#007bb6;border-color:rgba(0,0,0,0.2)}\n.btn-linkedin .badge{color:#007bb6;background-color:#fff}\n.btn-microsoft{color:#fff;background-color:#2672ec;border-color:rgba(0,0,0,0.2)}.btn-microsoft:hover,.btn-microsoft:focus,.btn-microsoft:active,.btn-microsoft.active,.open>.dropdown-toggle.btn-microsoft{color:#fff;background-color:#125acd;border-color:rgba(0,0,0,0.2)}\n.btn-microsoft:active,.btn-microsoft.active,.open>.dropdown-toggle.btn-microsoft{background-image:none}\n.btn-microsoft.disabled,.btn-microsoft[disabled],fieldset[disabled] .btn-microsoft,.btn-microsoft.disabled:hover,.btn-microsoft[disabled]:hover,fieldset[disabled] .btn-microsoft:hover,.btn-microsoft.disabled:focus,.btn-microsoft[disabled]:focus,fieldset[disabled] .btn-microsoft:focus,.btn-microsoft.disabled:active,.btn-microsoft[disabled]:active,fieldset[disabled] .btn-microsoft:active,.btn-microsoft.disabled.active,.btn-microsoft[disabled].active,fieldset[disabled] .btn-microsoft.active{background-color:#2672ec;border-color:rgba(0,0,0,0.2)}\n.btn-microsoft .badge{color:#2672ec;background-color:#fff}\n.btn-openid{color:#fff;background-color:#f7931e;border-color:rgba(0,0,0,0.2)}.btn-openid:hover,.btn-openid:focus,.btn-openid:active,.btn-openid.active,.open>.dropdown-toggle.btn-openid{color:#fff;background-color:#da7908;border-color:rgba(0,0,0,0.2)}\n.btn-openid:active,.btn-openid.active,.open>.dropdown-toggle.btn-openid{background-image:none}\n.btn-openid.disabled,.btn-openid[disabled],fieldset[disabled] .btn-openid,.btn-openid.disabled:hover,.btn-openid[disabled]:hover,fieldset[disabled] .btn-openid:hover,.btn-openid.disabled:focus,.btn-openid[disabled]:focus,fieldset[disabled] .btn-openid:focus,.btn-openid.disabled:active,.btn-openid[disabled]:active,fieldset[disabled] .btn-openid:active,.btn-openid.disabled.active,.btn-openid[disabled].active,fieldset[disabled] .btn-openid.active{background-color:#f7931e;border-color:rgba(0,0,0,0.2)}\n.btn-openid .badge{color:#f7931e;background-color:#fff}\n.btn-pinterest{color:#fff;background-color:#cb2027;border-color:rgba(0,0,0,0.2)}.btn-pinterest:hover,.btn-pinterest:focus,.btn-pinterest:active,.btn-pinterest.active,.open>.dropdown-toggle.btn-pinterest{color:#fff;background-color:#9f191f;border-color:rgba(0,0,0,0.2)}\n.btn-pinterest:active,.btn-pinterest.active,.open>.dropdown-toggle.btn-pinterest{background-image:none}\n.btn-pinterest.disabled,.btn-pinterest[disabled],fieldset[disabled] .btn-pinterest,.btn-pinterest.disabled:hover,.btn-pinterest[disabled]:hover,fieldset[disabled] .btn-pinterest:hover,.btn-pinterest.disabled:focus,.btn-pinterest[disabled]:focus,fieldset[disabled] .btn-pinterest:focus,.btn-pinterest.disabled:active,.btn-pinterest[disabled]:active,fieldset[disabled] .btn-pinterest:active,.btn-pinterest.disabled.active,.btn-pinterest[disabled].active,fieldset[disabled] .btn-pinterest.active{background-color:#cb2027;border-color:rgba(0,0,0,0.2)}\n.btn-pinterest .badge{color:#cb2027;background-color:#fff}\n.btn-reddit{color:#000;background-color:#eff7ff;border-color:rgba(0,0,0,0.2)}.btn-reddit:hover,.btn-reddit:focus,.btn-reddit:active,.btn-reddit.active,.open>.dropdown-toggle.btn-reddit{color:#000;background-color:#bcddff;border-color:rgba(0,0,0,0.2)}\n.btn-reddit:active,.btn-reddit.active,.open>.dropdown-toggle.btn-reddit{background-image:none}\n.btn-reddit.disabled,.btn-reddit[disabled],fieldset[disabled] .btn-reddit,.btn-reddit.disabled:hover,.btn-reddit[disabled]:hover,fieldset[disabled] .btn-reddit:hover,.btn-reddit.disabled:focus,.btn-reddit[disabled]:focus,fieldset[disabled] .btn-reddit:focus,.btn-reddit.disabled:active,.btn-reddit[disabled]:active,fieldset[disabled] .btn-reddit:active,.btn-reddit.disabled.active,.btn-reddit[disabled].active,fieldset[disabled] .btn-reddit.active{background-color:#eff7ff;border-color:rgba(0,0,0,0.2)}\n.btn-reddit .badge{color:#eff7ff;background-color:#000}\n.btn-soundcloud{color:#fff;background-color:#f50;border-color:rgba(0,0,0,0.2)}.btn-soundcloud:hover,.btn-soundcloud:focus,.btn-soundcloud:active,.btn-soundcloud.active,.open>.dropdown-toggle.btn-soundcloud{color:#fff;background-color:#c40;border-color:rgba(0,0,0,0.2)}\n.btn-soundcloud:active,.btn-soundcloud.active,.open>.dropdown-toggle.btn-soundcloud{background-image:none}\n.btn-soundcloud.disabled,.btn-soundcloud[disabled],fieldset[disabled] .btn-soundcloud,.btn-soundcloud.disabled:hover,.btn-soundcloud[disabled]:hover,fieldset[disabled] .btn-soundcloud:hover,.btn-soundcloud.disabled:focus,.btn-soundcloud[disabled]:focus,fieldset[disabled] .btn-soundcloud:focus,.btn-soundcloud.disabled:active,.btn-soundcloud[disabled]:active,fieldset[disabled] .btn-soundcloud:active,.btn-soundcloud.disabled.active,.btn-soundcloud[disabled].active,fieldset[disabled] .btn-soundcloud.active{background-color:#f50;border-color:rgba(0,0,0,0.2)}\n.btn-soundcloud .badge{color:#f50;background-color:#fff}\n.btn-tumblr{color:#fff;background-color:#2c4762;border-color:rgba(0,0,0,0.2)}.btn-tumblr:hover,.btn-tumblr:focus,.btn-tumblr:active,.btn-tumblr.active,.open>.dropdown-toggle.btn-tumblr{color:#fff;background-color:#1c2d3f;border-color:rgba(0,0,0,0.2)}\n.btn-tumblr:active,.btn-tumblr.active,.open>.dropdown-toggle.btn-tumblr{background-image:none}\n.btn-tumblr.disabled,.btn-tumblr[disabled],fieldset[disabled] .btn-tumblr,.btn-tumblr.disabled:hover,.btn-tumblr[disabled]:hover,fieldset[disabled] .btn-tumblr:hover,.btn-tumblr.disabled:focus,.btn-tumblr[disabled]:focus,fieldset[disabled] .btn-tumblr:focus,.btn-tumblr.disabled:active,.btn-tumblr[disabled]:active,fieldset[disabled] .btn-tumblr:active,.btn-tumblr.disabled.active,.btn-tumblr[disabled].active,fieldset[disabled] .btn-tumblr.active{background-color:#2c4762;border-color:rgba(0,0,0,0.2)}\n.btn-tumblr .badge{color:#2c4762;background-color:#fff}\n.btn-twitter{color:#fff;background-color:#55acee;border-color:rgba(0,0,0,0.2)}.btn-twitter:hover,.btn-twitter:focus,.btn-twitter:active,.btn-twitter.active,.open>.dropdown-toggle.btn-twitter{color:#fff;background-color:#2795e9;border-color:rgba(0,0,0,0.2)}\n.btn-twitter:active,.btn-twitter.active,.open>.dropdown-toggle.btn-twitter{background-image:none}\n.btn-twitter.disabled,.btn-twitter[disabled],fieldset[disabled] .btn-twitter,.btn-twitter.disabled:hover,.btn-twitter[disabled]:hover,fieldset[disabled] .btn-twitter:hover,.btn-twitter.disabled:focus,.btn-twitter[disabled]:focus,fieldset[disabled] .btn-twitter:focus,.btn-twitter.disabled:active,.btn-twitter[disabled]:active,fieldset[disabled] .btn-twitter:active,.btn-twitter.disabled.active,.btn-twitter[disabled].active,fieldset[disabled] .btn-twitter.active{background-color:#55acee;border-color:rgba(0,0,0,0.2)}\n.btn-twitter .badge{color:#55acee;background-color:#fff}\n.btn-vimeo{color:#fff;background-color:#1ab7ea;border-color:rgba(0,0,0,0.2)}.btn-vimeo:hover,.btn-vimeo:focus,.btn-vimeo:active,.btn-vimeo.active,.open>.dropdown-toggle.btn-vimeo{color:#fff;background-color:#1295bf;border-color:rgba(0,0,0,0.2)}\n.btn-vimeo:active,.btn-vimeo.active,.open>.dropdown-toggle.btn-vimeo{background-image:none}\n.btn-vimeo.disabled,.btn-vimeo[disabled],fieldset[disabled] .btn-vimeo,.btn-vimeo.disabled:hover,.btn-vimeo[disabled]:hover,fieldset[disabled] .btn-vimeo:hover,.btn-vimeo.disabled:focus,.btn-vimeo[disabled]:focus,fieldset[disabled] .btn-vimeo:focus,.btn-vimeo.disabled:active,.btn-vimeo[disabled]:active,fieldset[disabled] .btn-vimeo:active,.btn-vimeo.disabled.active,.btn-vimeo[disabled].active,fieldset[disabled] .btn-vimeo.active{background-color:#1ab7ea;border-color:rgba(0,0,0,0.2)}\n.btn-vimeo .badge{color:#1ab7ea;background-color:#fff}\n.btn-vk{color:#fff;background-color:#587ea3;border-color:rgba(0,0,0,0.2)}.btn-vk:hover,.btn-vk:focus,.btn-vk:active,.btn-vk.active,.open>.dropdown-toggle.btn-vk{color:#fff;background-color:#466482;border-color:rgba(0,0,0,0.2)}\n.btn-vk:active,.btn-vk.active,.open>.dropdown-toggle.btn-vk{background-image:none}\n.btn-vk.disabled,.btn-vk[disabled],fieldset[disabled] .btn-vk,.btn-vk.disabled:hover,.btn-vk[disabled]:hover,fieldset[disabled] .btn-vk:hover,.btn-vk.disabled:focus,.btn-vk[disabled]:focus,fieldset[disabled] .btn-vk:focus,.btn-vk.disabled:active,.btn-vk[disabled]:active,fieldset[disabled] .btn-vk:active,.btn-vk.disabled.active,.btn-vk[disabled].active,fieldset[disabled] .btn-vk.active{background-color:#587ea3;border-color:rgba(0,0,0,0.2)}\n.btn-vk .badge{color:#587ea3;background-color:#fff}\n.btn-yahoo{color:#fff;background-color:#720e9e;border-color:rgba(0,0,0,0.2)}.btn-yahoo:hover,.btn-yahoo:focus,.btn-yahoo:active,.btn-yahoo.active,.open>.dropdown-toggle.btn-yahoo{color:#fff;background-color:#500a6f;border-color:rgba(0,0,0,0.2)}\n.btn-yahoo:active,.btn-yahoo.active,.open>.dropdown-toggle.btn-yahoo{background-image:none}\n.btn-yahoo.disabled,.btn-yahoo[disabled],fieldset[disabled] .btn-yahoo,.btn-yahoo.disabled:hover,.btn-yahoo[disabled]:hover,fieldset[disabled] .btn-yahoo:hover,.btn-yahoo.disabled:focus,.btn-yahoo[disabled]:focus,fieldset[disabled] .btn-yahoo:focus,.btn-yahoo.disabled:active,.btn-yahoo[disabled]:active,fieldset[disabled] .btn-yahoo:active,.btn-yahoo.disabled.active,.btn-yahoo[disabled].active,fieldset[disabled] .btn-yahoo.active{background-color:#720e9e;border-color:rgba(0,0,0,0.2)}\n.btn-yahoo .badge{color:#720e9e;background-color:#fff}\n"
  },
  {
    "path": "app_backend/vendor/bootstrap-social/bootstrap-social.less",
    "content": "/*\n * Social Buttons for Bootstrap\n *\n * Copyright 2013-2014 Panayiotis Lipiridis\n * Licensed under the MIT License\n *\n * https://github.com/lipis/bootstrap-social\n */\n\n@bs-height-base: (@line-height-computed + @padding-base-vertical * 2);\n@bs-height-lg:   (floor(@font-size-large * @line-height-base) + @padding-large-vertical * 2);\n@bs-height-sm:   (floor(@font-size-small * 1.5) + @padding-small-vertical * 2);\n@bs-height-xs:   (floor(@font-size-small * 1.2) + @padding-small-vertical + 1);\n\n.btn-social {\n  position: relative;\n  padding-left: (@bs-height-base + @padding-base-horizontal);\n  text-align: left;\n  white-space: nowrap;\n  overflow: hidden;\n  text-overflow: ellipsis;\n  > :first-child {\n    position: absolute;\n    left: 0;\n    top: 0;\n    bottom: 0;\n    width: @bs-height-base;\n    line-height: (@bs-height-base + 2);\n    font-size: 1.6em;\n    text-align: center;\n    border-right: 1px solid rgba(0, 0, 0, 0.2);\n  }\n  &.btn-lg {\n    padding-left: (@bs-height-lg + @padding-large-horizontal);\n    :first-child {\n      line-height: @bs-height-lg;\n      width: @bs-height-lg;\n      font-size: 1.8em;\n    }\n  }\n  &.btn-sm {\n    padding-left: (@bs-height-sm + @padding-small-horizontal);\n    :first-child {\n      line-height: @bs-height-sm;\n      width: @bs-height-sm;\n      font-size: 1.4em;\n    }\n  }\n  &.btn-xs {\n    padding-left: (@bs-height-xs + @padding-small-horizontal);\n    :first-child {\n      line-height: @bs-height-xs;\n      width: @bs-height-xs;\n      font-size: 1.2em;\n    }\n  }\n}\n\n.btn-social-icon {\n  .btn-social;\n  height: (@bs-height-base + 2);\n  width: (@bs-height-base + 2);\n  padding: 0;\n  :first-child {\n    border: none;\n    text-align: center;\n    width: 100%!important;\n  }\n  &.btn-lg {\n    height: @bs-height-lg;\n    width: @bs-height-lg;\n    padding-left: 0;\n    padding-right: 0;\n  }\n  &.btn-sm {\n    height: (@bs-height-sm + 2);\n    width: (@bs-height-sm + 2);\n    padding-left: 0;\n    padding-right: 0;\n  }\n  &.btn-xs {\n    height: (@bs-height-xs + 2);\n    width: (@bs-height-xs + 2);\n    padding-left: 0;\n    padding-right: 0;\n  }\n}\n\n.btn-social(@color-bg, @color: #fff) {\n  background-color: @color-bg;\n  .button-variant(@color, @color-bg, rgba(0,0,0,.2));\n}\n\n\n.btn-adn           { .btn-social(#d87a68); }\n.btn-bitbucket     { .btn-social(#205081); }\n.btn-dropbox       { .btn-social(#1087dd); }\n.btn-facebook      { .btn-social(#3b5998); }\n.btn-flickr        { .btn-social(#ff0084); }\n.btn-foursquare    { .btn-social(#f94877); }\n.btn-github        { .btn-social(#444444); }\n.btn-google-plus   { .btn-social(#dd4b39); }\n.btn-instagram     { .btn-social(#3f729b); }\n.btn-linkedin      { .btn-social(#007bb6); }\n.btn-microsoft     { .btn-social(#2672ec); }\n.btn-openid        { .btn-social(#f7931e); }\n.btn-pinterest     { .btn-social(#cb2027); }\n.btn-reddit        { .btn-social(#eff7ff, #000); }\n.btn-soundcloud    { .btn-social(#ff5500); }\n.btn-tumblr        { .btn-social(#2c4762); }\n.btn-twitter       { .btn-social(#55acee); }\n.btn-vimeo         { .btn-social(#1ab7ea); }\n.btn-vk            { .btn-social(#587ea3); }\n.btn-yahoo         { .btn-social(#720e9e); }\n"
  },
  {
    "path": "app_backend/vendor/bootstrap-social/bootstrap-social.scss",
    "content": "/*\n * Social Buttons for Bootstrap\n *\n * Copyright 2013-2014 Panayiotis Lipiridis\n * Licensed under the MIT License\n *\n * https://github.com/lipis/bootstrap-social\n */\n\n$bs-height-base: ($line-height-computed + $padding-base-vertical * 2);\n$bs-height-lg:   (floor($font-size-large * $line-height-base) + $padding-large-vertical * 2);\n$bs-height-sm:   (floor($font-size-small * 1.5) + $padding-small-vertical * 2);\n$bs-height-xs:   (floor($font-size-small * 1.2) + $padding-small-vertical + 1);\n\n.btn-social {\n  position: relative;\n  padding-left: ($bs-height-base + $padding-base-horizontal);\n  text-align: left;\n  white-space: nowrap;\n  overflow: hidden;\n  text-overflow: ellipsis;\n  > :first-child {\n    position: absolute;\n    left: 0;\n    top: 0;\n    bottom: 0;\n    width: $bs-height-base;\n    line-height: ($bs-height-base + 2);\n    font-size: 1.6em;\n    text-align: center;\n    border-right: 1px solid rgba(0, 0, 0, 0.2);\n  }\n  &.btn-lg {\n    padding-left: ($bs-height-lg + $padding-large-horizontal);\n    :first-child {\n      line-height: $bs-height-lg;\n      width: $bs-height-lg;\n      font-size: 1.8em;\n    }\n  }\n  &.btn-sm {\n    padding-left: ($bs-height-sm + $padding-small-horizontal);\n    :first-child {\n      line-height: $bs-height-sm;\n      width: $bs-height-sm;\n      font-size: 1.4em;\n    }\n  }\n  &.btn-xs {\n    padding-left: ($bs-height-xs + $padding-small-horizontal);\n    :first-child {\n      line-height: $bs-height-xs;\n      width: $bs-height-xs;\n      font-size: 1.2em;\n    }\n  }\n}\n\n.btn-social-icon {\n  @extend .btn-social;\n  height: ($bs-height-base + 2);\n  width: ($bs-height-base + 2);\n  padding: 0;\n  :first-child {\n    border: none;\n    text-align: center;\n    width: 100%!important;\n  }\n  &.btn-lg {\n    height: $bs-height-lg;\n    width: $bs-height-lg;\n    padding-left: 0;\n    padding-right: 0;\n  }\n  &.btn-sm {\n    height: ($bs-height-sm + 2);\n    width: ($bs-height-sm + 2);\n    padding-left: 0;\n    padding-right: 0;\n  }\n  &.btn-xs {\n    height: ($bs-height-xs + 2);\n    width: ($bs-height-xs + 2);\n    padding-left: 0;\n    padding-right: 0;\n  }\n}\n\n@mixin btn-social($color-bg, $color: #fff) {\n  background-color: $color-bg;\n  @include button-variant($color, $color-bg, rgba(0,0,0,.2));\n}\n\n\n.btn-adn           { @include btn-social(#d87a68); }\n.btn-bitbucket     { @include btn-social(#205081); }\n.btn-dropbox       { @include btn-social(#1087dd); }\n.btn-facebook      { @include btn-social(#3b5998); }\n.btn-flickr        { @include btn-social(#ff0084); }\n.btn-foursquare    { @include btn-social(#f94877); }\n.btn-github        { @include btn-social(#444444); }\n.btn-google-plus   { @include btn-social(#dd4b39); }\n.btn-instagram     { @include btn-social(#3f729b); }\n.btn-linkedin      { @include btn-social(#007bb6); }\n.btn-microsoft     { @include btn-social(#2672ec); }\n.btn-openid        { @include btn-social(#f7931e); }\n.btn-pinterest     { @include btn-social(#cb2027); }\n.btn-reddit        { @include btn-social(#eff7ff, #000); }\n.btn-soundcloud    { @include btn-social(#ff5500); }\n.btn-tumblr        { @include btn-social(#2c4762); }\n.btn-twitter       { @include btn-social(#55acee); }\n.btn-vimeo         { @include btn-social(#1ab7ea); }\n.btn-vk            { @include btn-social(#587ea3); }\n.btn-yahoo         { @include btn-social(#720e9e); }\n"
  },
  {
    "path": "app_backend/vendor/datatables/css/dataTables.bootstrap.css",
    "content": "table.dataTable {\n  clear: both;\n  margin-top: 6px !important;\n  margin-bottom: 6px !important;\n  max-width: none !important;\n  border-collapse: separate !important;\n}\ntable.dataTable td,\ntable.dataTable th {\n  -webkit-box-sizing: content-box;\n  -moz-box-sizing: content-box;\n  box-sizing: content-box;\n}\ntable.dataTable td.dataTables_empty,\ntable.dataTable th.dataTables_empty {\n  text-align: center;\n}\ntable.dataTable.nowrap th,\ntable.dataTable.nowrap td {\n  white-space: nowrap;\n}\n\ndiv.dataTables_wrapper div.dataTables_length label {\n  font-weight: normal;\n  text-align: left;\n  white-space: nowrap;\n}\ndiv.dataTables_wrapper div.dataTables_length select {\n  width: 75px;\n  display: inline-block;\n}\ndiv.dataTables_wrapper div.dataTables_filter {\n  text-align: right;\n}\ndiv.dataTables_wrapper div.dataTables_filter label {\n  font-weight: normal;\n  white-space: nowrap;\n  text-align: left;\n}\ndiv.dataTables_wrapper div.dataTables_filter input {\n  margin-left: 0.5em;\n  display: inline-block;\n  width: auto;\n}\ndiv.dataTables_wrapper div.dataTables_info {\n  padding-top: 8px;\n  white-space: nowrap;\n}\ndiv.dataTables_wrapper div.dataTables_paginate {\n  margin: 0;\n  white-space: nowrap;\n  text-align: right;\n}\ndiv.dataTables_wrapper div.dataTables_paginate ul.pagination {\n  margin: 2px 0;\n  white-space: nowrap;\n}\ndiv.dataTables_wrapper div.dataTables_processing {\n  position: absolute;\n  top: 50%;\n  left: 50%;\n  width: 200px;\n  margin-left: -100px;\n  margin-top: -26px;\n  text-align: center;\n  padding: 1em 0;\n}\n\ntable.dataTable thead > tr > th.sorting_asc, table.dataTable thead > tr > th.sorting_desc, table.dataTable thead > tr > th.sorting,\ntable.dataTable thead > tr > td.sorting_asc,\ntable.dataTable thead > tr > td.sorting_desc,\ntable.dataTable thead > tr > td.sorting {\n  padding-right: 30px;\n}\ntable.dataTable thead > tr > th:active,\ntable.dataTable thead > tr > td:active {\n  outline: none;\n}\ntable.dataTable thead .sorting,\ntable.dataTable thead .sorting_asc,\ntable.dataTable thead .sorting_desc,\ntable.dataTable thead .sorting_asc_disabled,\ntable.dataTable thead .sorting_desc_disabled {\n  cursor: pointer;\n  position: relative;\n}\ntable.dataTable thead .sorting:after,\ntable.dataTable thead .sorting_asc:after,\ntable.dataTable thead .sorting_desc:after,\ntable.dataTable thead .sorting_asc_disabled:after,\ntable.dataTable thead .sorting_desc_disabled:after {\n  position: absolute;\n  bottom: 8px;\n  right: 8px;\n  display: block;\n  font-family: 'Glyphicons Halflings';\n  opacity: 0.5;\n}\ntable.dataTable thead .sorting:after {\n  opacity: 0.2;\n  content: \"\\e150\";\n  /* sort */\n}\ntable.dataTable thead .sorting_asc:after {\n  content: \"\\e155\";\n  /* sort-by-attributes */\n}\ntable.dataTable thead .sorting_desc:after {\n  content: \"\\e156\";\n  /* sort-by-attributes-alt */\n}\ntable.dataTable thead .sorting_asc_disabled:after,\ntable.dataTable thead .sorting_desc_disabled:after {\n  color: #eee;\n}\n\ndiv.dataTables_scrollHead table.dataTable {\n  margin-bottom: 0 !important;\n}\n\ndiv.dataTables_scrollBody table {\n  border-top: none;\n  margin-top: 0 !important;\n  margin-bottom: 0 !important;\n}\ndiv.dataTables_scrollBody table thead .sorting:after,\ndiv.dataTables_scrollBody table thead .sorting_asc:after,\ndiv.dataTables_scrollBody table thead .sorting_desc:after {\n  display: none;\n}\ndiv.dataTables_scrollBody table tbody tr:first-child th,\ndiv.dataTables_scrollBody table tbody tr:first-child td {\n  border-top: none;\n}\n\ndiv.dataTables_scrollFoot table {\n  margin-top: 0 !important;\n  border-top: none;\n}\n\n@media screen and (max-width: 767px) {\n  div.dataTables_wrapper div.dataTables_length,\n  div.dataTables_wrapper div.dataTables_filter,\n  div.dataTables_wrapper div.dataTables_info,\n  div.dataTables_wrapper div.dataTables_paginate {\n    text-align: center;\n  }\n}\ntable.dataTable.table-condensed > thead > tr > th {\n  padding-right: 20px;\n}\ntable.dataTable.table-condensed .sorting:after,\ntable.dataTable.table-condensed .sorting_asc:after,\ntable.dataTable.table-condensed .sorting_desc:after {\n  top: 6px;\n  right: 6px;\n}\n\ntable.table-bordered.dataTable th,\ntable.table-bordered.dataTable td {\n  border-left-width: 0;\n}\ntable.table-bordered.dataTable th:last-child, table.table-bordered.dataTable th:last-child,\ntable.table-bordered.dataTable td:last-child,\ntable.table-bordered.dataTable td:last-child {\n  border-right-width: 0;\n}\ntable.table-bordered.dataTable tbody th,\ntable.table-bordered.dataTable tbody td {\n  border-bottom-width: 0;\n}\n\ndiv.dataTables_scrollHead table.table-bordered {\n  border-bottom-width: 0;\n}\n\ndiv.table-responsive > div.dataTables_wrapper > div.row {\n  margin: 0;\n}\ndiv.table-responsive > div.dataTables_wrapper > div.row > div[class^=\"col-\"]:first-child {\n  padding-left: 0;\n}\ndiv.table-responsive > div.dataTables_wrapper > div.row > div[class^=\"col-\"]:last-child {\n  padding-right: 0;\n}\n"
  },
  {
    "path": "app_backend/vendor/datatables/css/dataTables.bootstrap4.css",
    "content": "table.dataTable {\n  clear: both;\n  margin-top: 6px !important;\n  margin-bottom: 6px !important;\n  max-width: none !important;\n  border-collapse: separate !important;\n}\ntable.dataTable td,\ntable.dataTable th {\n  -webkit-box-sizing: content-box;\n  box-sizing: content-box;\n}\ntable.dataTable td.dataTables_empty,\ntable.dataTable th.dataTables_empty {\n  text-align: center;\n}\ntable.dataTable.nowrap th,\ntable.dataTable.nowrap td {\n  white-space: nowrap;\n}\n\ndiv.dataTables_wrapper div.dataTables_length label {\n  font-weight: normal;\n  text-align: left;\n  white-space: nowrap;\n}\ndiv.dataTables_wrapper div.dataTables_length select {\n  width: 75px;\n  display: inline-block;\n}\ndiv.dataTables_wrapper div.dataTables_filter {\n  text-align: right;\n}\ndiv.dataTables_wrapper div.dataTables_filter label {\n  font-weight: normal;\n  white-space: nowrap;\n  text-align: left;\n}\ndiv.dataTables_wrapper div.dataTables_filter input {\n  margin-left: 0.5em;\n  display: inline-block;\n  width: auto;\n}\ndiv.dataTables_wrapper div.dataTables_info {\n  padding-top: 0.85em;\n  white-space: nowrap;\n}\ndiv.dataTables_wrapper div.dataTables_paginate {\n  margin: 0;\n  white-space: nowrap;\n  text-align: right;\n}\ndiv.dataTables_wrapper div.dataTables_paginate ul.pagination {\n  margin: 2px 0;\n  white-space: nowrap;\n}\ndiv.dataTables_wrapper div.dataTables_processing {\n  position: absolute;\n  top: 50%;\n  left: 50%;\n  width: 200px;\n  margin-left: -100px;\n  margin-top: -26px;\n  text-align: center;\n  padding: 1em 0;\n}\n\ntable.dataTable thead > tr > th.sorting_asc, table.dataTable thead > tr > th.sorting_desc, table.dataTable thead > tr > th.sorting,\ntable.dataTable thead > tr > td.sorting_asc,\ntable.dataTable thead > tr > td.sorting_desc,\ntable.dataTable thead > tr > td.sorting {\n  padding-right: 30px;\n}\ntable.dataTable thead > tr > th:active,\ntable.dataTable thead > tr > td:active {\n  outline: none;\n}\ntable.dataTable thead .sorting,\ntable.dataTable thead .sorting_asc,\ntable.dataTable thead .sorting_desc,\ntable.dataTable thead .sorting_asc_disabled,\ntable.dataTable thead .sorting_desc_disabled {\n  cursor: pointer;\n  position: relative;\n}\ntable.dataTable thead .sorting:before, table.dataTable thead .sorting:after,\ntable.dataTable thead .sorting_asc:before,\ntable.dataTable thead .sorting_asc:after,\ntable.dataTable thead .sorting_desc:before,\ntable.dataTable thead .sorting_desc:after,\ntable.dataTable thead .sorting_asc_disabled:before,\ntable.dataTable thead .sorting_asc_disabled:after,\ntable.dataTable thead .sorting_desc_disabled:before,\ntable.dataTable thead .sorting_desc_disabled:after {\n  position: absolute;\n  bottom: 0.9em;\n  display: block;\n  opacity: 0.3;\n}\ntable.dataTable thead .sorting:before,\ntable.dataTable thead .sorting_asc:before,\ntable.dataTable thead .sorting_desc:before,\ntable.dataTable thead .sorting_asc_disabled:before,\ntable.dataTable thead .sorting_desc_disabled:before {\n  right: 1em;\n  content: \"\\2191\";\n}\ntable.dataTable thead .sorting:after,\ntable.dataTable thead .sorting_asc:after,\ntable.dataTable thead .sorting_desc:after,\ntable.dataTable thead .sorting_asc_disabled:after,\ntable.dataTable thead .sorting_desc_disabled:after {\n  right: 0.5em;\n  content: \"\\2193\";\n}\ntable.dataTable thead .sorting_asc:before,\ntable.dataTable thead .sorting_desc:after {\n  opacity: 1;\n}\ntable.dataTable thead .sorting_asc_disabled:before,\ntable.dataTable thead .sorting_desc_disabled:after {\n  opacity: 0;\n}\n\ndiv.dataTables_scrollHead table.dataTable {\n  margin-bottom: 0 !important;\n}\n\ndiv.dataTables_scrollBody table {\n  border-top: none;\n  margin-top: 0 !important;\n  margin-bottom: 0 !important;\n}\ndiv.dataTables_scrollBody table thead .sorting:after,\ndiv.dataTables_scrollBody table thead .sorting_asc:after,\ndiv.dataTables_scrollBody table thead .sorting_desc:after {\n  display: none;\n}\ndiv.dataTables_scrollBody table tbody tr:first-child th,\ndiv.dataTables_scrollBody table tbody tr:first-child td {\n  border-top: none;\n}\n\ndiv.dataTables_scrollFoot table {\n  margin-top: 0 !important;\n  border-top: none;\n}\n\n@media screen and (max-width: 767px) {\n  div.dataTables_wrapper div.dataTables_length,\n  div.dataTables_wrapper div.dataTables_filter,\n  div.dataTables_wrapper div.dataTables_info,\n  div.dataTables_wrapper div.dataTables_paginate {\n    text-align: center;\n  }\n}\ntable.dataTable.table-condensed > thead > tr > th {\n  padding-right: 20px;\n}\ntable.dataTable.table-condensed .sorting:after,\ntable.dataTable.table-condensed .sorting_asc:after,\ntable.dataTable.table-condensed .sorting_desc:after {\n  top: 6px;\n  right: 6px;\n}\n\ntable.table-bordered.dataTable th,\ntable.table-bordered.dataTable td {\n  border-left-width: 0;\n}\ntable.table-bordered.dataTable th:last-child, table.table-bordered.dataTable th:last-child,\ntable.table-bordered.dataTable td:last-child,\ntable.table-bordered.dataTable td:last-child {\n  border-right-width: 0;\n}\ntable.table-bordered.dataTable tbody th,\ntable.table-bordered.dataTable tbody td {\n  border-bottom-width: 0;\n}\n\ndiv.dataTables_scrollHead table.table-bordered {\n  border-bottom-width: 0;\n}\n\ndiv.table-responsive > div.dataTables_wrapper > div.row {\n  margin: 0;\n}\ndiv.table-responsive > div.dataTables_wrapper > div.row > div[class^=\"col-\"]:first-child {\n  padding-left: 0;\n}\ndiv.table-responsive > div.dataTables_wrapper > div.row > div[class^=\"col-\"]:last-child {\n  padding-right: 0;\n}\n"
  },
  {
    "path": "app_backend/vendor/datatables/css/dataTables.foundation.css",
    "content": "table.dataTable {\n  clear: both;\n  margin: 0.5em 0 !important;\n  max-width: none !important;\n  width: 100%;\n}\ntable.dataTable td,\ntable.dataTable th {\n  -webkit-box-sizing: content-box;\n  box-sizing: content-box;\n}\ntable.dataTable td.dataTables_empty,\ntable.dataTable th.dataTables_empty {\n  text-align: center;\n}\ntable.dataTable.nowrap th, table.dataTable.nowrap td {\n  white-space: nowrap;\n}\n\ndiv.dataTables_wrapper {\n  position: relative;\n}\ndiv.dataTables_wrapper div.dataTables_length label {\n  float: left;\n  text-align: left;\n  margin-bottom: 0;\n}\ndiv.dataTables_wrapper div.dataTables_length select {\n  width: 75px;\n  margin-bottom: 0;\n}\ndiv.dataTables_wrapper div.dataTables_filter label {\n  float: right;\n  margin-bottom: 0;\n}\ndiv.dataTables_wrapper div.dataTables_filter input {\n  display: inline-block !important;\n  width: auto !important;\n  margin-bottom: 0;\n  margin-left: 0.5em;\n}\ndiv.dataTables_wrapper div.dataTables_info {\n  padding-top: 2px;\n}\ndiv.dataTables_wrapper div.dataTables_paginate {\n  float: right;\n  margin: 0;\n}\ndiv.dataTables_wrapper div.dataTables_processing {\n  position: absolute;\n  top: 50%;\n  left: 50%;\n  width: 200px;\n  margin-left: -100px;\n  margin-top: -26px;\n  text-align: center;\n  padding: 1rem 0;\n}\n\ntable.dataTable thead > tr > th.sorting_asc, table.dataTable thead > tr > th.sorting_desc, table.dataTable thead > tr > th.sorting,\ntable.dataTable thead > tr > td.sorting_asc,\ntable.dataTable thead > tr > td.sorting_desc,\ntable.dataTable thead > tr > td.sorting {\n  padding-right: 1.5rem;\n}\ntable.dataTable thead > tr > th:active,\ntable.dataTable thead > tr > td:active {\n  outline: none;\n}\ntable.dataTable thead .sorting,\ntable.dataTable thead .sorting_asc,\ntable.dataTable thead .sorting_desc {\n  cursor: pointer;\n}\ntable.dataTable thead .sorting,\ntable.dataTable thead .sorting_asc,\ntable.dataTable thead .sorting_desc,\ntable.dataTable thead .sorting_asc_disabled,\ntable.dataTable thead .sorting_desc_disabled {\n  background-repeat: no-repeat;\n  background-position: center right;\n}\ntable.dataTable thead .sorting {\n  background-image: url(\"../images/sort_both.png\");\n}\ntable.dataTable thead .sorting_asc {\n  background-image: url(\"../images/sort_asc.png\");\n}\ntable.dataTable thead .sorting_desc {\n  background-image: url(\"../images/sort_desc.png\");\n}\ntable.dataTable thead .sorting_asc_disabled {\n  background-image: url(\"../images/sort_asc_disabled.png\");\n}\ntable.dataTable thead .sorting_desc_disabled {\n  background-image: url(\"../images/sort_desc_disabled.png\");\n}\n\ndiv.dataTables_scrollHead table {\n  margin-bottom: 0 !important;\n}\n\ndiv.dataTables_scrollBody table {\n  border-top: none;\n  margin-top: 0 !important;\n  margin-bottom: 0 !important;\n}\ndiv.dataTables_scrollBody table tbody tr:first-child th,\ndiv.dataTables_scrollBody table tbody tr:first-child td {\n  border-top: none;\n}\n\ndiv.dataTables_scrollFoot table {\n  margin-top: 0 !important;\n  border-top: none;\n}\n"
  },
  {
    "path": "app_backend/vendor/datatables/css/dataTables.jqueryui.css",
    "content": "/*\n * Table styles\n */\ntable.dataTable {\n  width: 100%;\n  margin: 0 auto;\n  clear: both;\n  border-collapse: separate;\n  border-spacing: 0;\n  /*\n   * Header and footer styles\n   */\n  /*\n   * Body styles\n   */\n}\ntable.dataTable thead th,\ntable.dataTable tfoot th {\n  font-weight: bold;\n}\ntable.dataTable thead th,\ntable.dataTable thead td {\n  padding: 10px 18px;\n}\ntable.dataTable thead th:active,\ntable.dataTable thead td:active {\n  outline: none;\n}\ntable.dataTable tfoot th,\ntable.dataTable tfoot td {\n  padding: 10px 18px 6px 18px;\n}\ntable.dataTable tbody tr {\n  background-color: #ffffff;\n}\ntable.dataTable tbody tr.selected {\n  background-color: #B0BED9;\n}\ntable.dataTable tbody th,\ntable.dataTable tbody td {\n  padding: 8px 10px;\n}\ntable.dataTable.row-border tbody th, table.dataTable.row-border tbody td, table.dataTable.display tbody th, table.dataTable.display tbody td {\n  border-top: 1px solid #ddd;\n}\ntable.dataTable.row-border tbody tr:first-child th,\ntable.dataTable.row-border tbody tr:first-child td, table.dataTable.display tbody tr:first-child th,\ntable.dataTable.display tbody tr:first-child td {\n  border-top: none;\n}\ntable.dataTable.cell-border tbody th, table.dataTable.cell-border tbody td {\n  border-top: 1px solid #ddd;\n  border-right: 1px solid #ddd;\n}\ntable.dataTable.cell-border tbody tr th:first-child,\ntable.dataTable.cell-border tbody tr td:first-child {\n  border-left: 1px solid #ddd;\n}\ntable.dataTable.cell-border tbody tr:first-child th,\ntable.dataTable.cell-border tbody tr:first-child td {\n  border-top: none;\n}\ntable.dataTable.stripe tbody tr.odd, table.dataTable.display tbody tr.odd {\n  background-color: #f9f9f9;\n}\ntable.dataTable.stripe tbody tr.odd.selected, table.dataTable.display tbody tr.odd.selected {\n  background-color: #acbad4;\n}\ntable.dataTable.hover tbody tr:hover, table.dataTable.display tbody tr:hover {\n  background-color: #f6f6f6;\n}\ntable.dataTable.hover tbody tr:hover.selected, table.dataTable.display tbody tr:hover.selected {\n  background-color: #aab7d1;\n}\ntable.dataTable.order-column tbody tr > .sorting_1,\ntable.dataTable.order-column tbody tr > .sorting_2,\ntable.dataTable.order-column tbody tr > .sorting_3, table.dataTable.display tbody tr > .sorting_1,\ntable.dataTable.display tbody tr > .sorting_2,\ntable.dataTable.display tbody tr > .sorting_3 {\n  background-color: #fafafa;\n}\ntable.dataTable.order-column tbody tr.selected > .sorting_1,\ntable.dataTable.order-column tbody tr.selected > .sorting_2,\ntable.dataTable.order-column tbody tr.selected > .sorting_3, table.dataTable.display tbody tr.selected > .sorting_1,\ntable.dataTable.display tbody tr.selected > .sorting_2,\ntable.dataTable.display tbody tr.selected > .sorting_3 {\n  background-color: #acbad5;\n}\ntable.dataTable.display tbody tr.odd > .sorting_1, table.dataTable.order-column.stripe tbody tr.odd > .sorting_1 {\n  background-color: #f1f1f1;\n}\ntable.dataTable.display tbody tr.odd > .sorting_2, table.dataTable.order-column.stripe tbody tr.odd > .sorting_2 {\n  background-color: #f3f3f3;\n}\ntable.dataTable.display tbody tr.odd > .sorting_3, table.dataTable.order-column.stripe tbody tr.odd > .sorting_3 {\n  background-color: whitesmoke;\n}\ntable.dataTable.display tbody tr.odd.selected > .sorting_1, table.dataTable.order-column.stripe tbody tr.odd.selected > .sorting_1 {\n  background-color: #a6b4cd;\n}\ntable.dataTable.display tbody tr.odd.selected > .sorting_2, table.dataTable.order-column.stripe tbody tr.odd.selected > .sorting_2 {\n  background-color: #a8b5cf;\n}\ntable.dataTable.display tbody tr.odd.selected > .sorting_3, table.dataTable.order-column.stripe tbody tr.odd.selected > .sorting_3 {\n  background-color: #a9b7d1;\n}\ntable.dataTable.display tbody tr.even > .sorting_1, table.dataTable.order-column.stripe tbody tr.even > .sorting_1 {\n  background-color: #fafafa;\n}\ntable.dataTable.display tbody tr.even > .sorting_2, table.dataTable.order-column.stripe tbody tr.even > .sorting_2 {\n  background-color: #fcfcfc;\n}\ntable.dataTable.display tbody tr.even > .sorting_3, table.dataTable.order-column.stripe tbody tr.even > .sorting_3 {\n  background-color: #fefefe;\n}\ntable.dataTable.display tbody tr.even.selected > .sorting_1, table.dataTable.order-column.stripe tbody tr.even.selected > .sorting_1 {\n  background-color: #acbad5;\n}\ntable.dataTable.display tbody tr.even.selected > .sorting_2, table.dataTable.order-column.stripe tbody tr.even.selected > .sorting_2 {\n  background-color: #aebcd6;\n}\ntable.dataTable.display tbody tr.even.selected > .sorting_3, table.dataTable.order-column.stripe tbody tr.even.selected > .sorting_3 {\n  background-color: #afbdd8;\n}\ntable.dataTable.display tbody tr:hover > .sorting_1, table.dataTable.order-column.hover tbody tr:hover > .sorting_1 {\n  background-color: #eaeaea;\n}\ntable.dataTable.display tbody tr:hover > .sorting_2, table.dataTable.order-column.hover tbody tr:hover > .sorting_2 {\n  background-color: #ececec;\n}\ntable.dataTable.display tbody tr:hover > .sorting_3, table.dataTable.order-column.hover tbody tr:hover > .sorting_3 {\n  background-color: #efefef;\n}\ntable.dataTable.display tbody tr:hover.selected > .sorting_1, table.dataTable.order-column.hover tbody tr:hover.selected > .sorting_1 {\n  background-color: #a2aec7;\n}\ntable.dataTable.display tbody tr:hover.selected > .sorting_2, table.dataTable.order-column.hover tbody tr:hover.selected > .sorting_2 {\n  background-color: #a3b0c9;\n}\ntable.dataTable.display tbody tr:hover.selected > .sorting_3, table.dataTable.order-column.hover tbody tr:hover.selected > .sorting_3 {\n  background-color: #a5b2cb;\n}\ntable.dataTable.no-footer {\n  border-bottom: 1px solid #111;\n}\ntable.dataTable.nowrap th, table.dataTable.nowrap td {\n  white-space: nowrap;\n}\ntable.dataTable.compact thead th,\ntable.dataTable.compact thead td {\n  padding: 4px 17px 4px 4px;\n}\ntable.dataTable.compact tfoot th,\ntable.dataTable.compact tfoot td {\n  padding: 4px;\n}\ntable.dataTable.compact tbody th,\ntable.dataTable.compact tbody td {\n  padding: 4px;\n}\ntable.dataTable th.dt-left,\ntable.dataTable td.dt-left {\n  text-align: left;\n}\ntable.dataTable th.dt-center,\ntable.dataTable td.dt-center,\ntable.dataTable td.dataTables_empty {\n  text-align: center;\n}\ntable.dataTable th.dt-right,\ntable.dataTable td.dt-right {\n  text-align: right;\n}\ntable.dataTable th.dt-justify,\ntable.dataTable td.dt-justify {\n  text-align: justify;\n}\ntable.dataTable th.dt-nowrap,\ntable.dataTable td.dt-nowrap {\n  white-space: nowrap;\n}\ntable.dataTable thead th.dt-head-left,\ntable.dataTable thead td.dt-head-left,\ntable.dataTable tfoot th.dt-head-left,\ntable.dataTable tfoot td.dt-head-left {\n  text-align: left;\n}\ntable.dataTable thead th.dt-head-center,\ntable.dataTable thead td.dt-head-center,\ntable.dataTable tfoot th.dt-head-center,\ntable.dataTable tfoot td.dt-head-center {\n  text-align: center;\n}\ntable.dataTable thead th.dt-head-right,\ntable.dataTable thead td.dt-head-right,\ntable.dataTable tfoot th.dt-head-right,\ntable.dataTable tfoot td.dt-head-right {\n  text-align: right;\n}\ntable.dataTable thead th.dt-head-justify,\ntable.dataTable thead td.dt-head-justify,\ntable.dataTable tfoot th.dt-head-justify,\ntable.dataTable tfoot td.dt-head-justify {\n  text-align: justify;\n}\ntable.dataTable thead th.dt-head-nowrap,\ntable.dataTable thead td.dt-head-nowrap,\ntable.dataTable tfoot th.dt-head-nowrap,\ntable.dataTable tfoot td.dt-head-nowrap {\n  white-space: nowrap;\n}\ntable.dataTable tbody th.dt-body-left,\ntable.dataTable tbody td.dt-body-left {\n  text-align: left;\n}\ntable.dataTable tbody th.dt-body-center,\ntable.dataTable tbody td.dt-body-center {\n  text-align: center;\n}\ntable.dataTable tbody th.dt-body-right,\ntable.dataTable tbody td.dt-body-right {\n  text-align: right;\n}\ntable.dataTable tbody th.dt-body-justify,\ntable.dataTable tbody td.dt-body-justify {\n  text-align: justify;\n}\ntable.dataTable tbody th.dt-body-nowrap,\ntable.dataTable tbody td.dt-body-nowrap {\n  white-space: nowrap;\n}\n\ntable.dataTable,\ntable.dataTable th,\ntable.dataTable td {\n  -webkit-box-sizing: content-box;\n  box-sizing: content-box;\n}\n\n/*\n * Control feature layout\n */\n.dataTables_wrapper {\n  position: relative;\n  clear: both;\n  *zoom: 1;\n  zoom: 1;\n}\n.dataTables_wrapper .dataTables_length {\n  float: left;\n}\n.dataTables_wrapper .dataTables_filter {\n  float: right;\n  text-align: right;\n}\n.dataTables_wrapper .dataTables_filter input {\n  margin-left: 0.5em;\n}\n.dataTables_wrapper .dataTables_info {\n  clear: both;\n  float: left;\n  padding-top: 0.755em;\n}\n.dataTables_wrapper .dataTables_paginate {\n  float: right;\n  text-align: right;\n  padding-top: 0.25em;\n}\n.dataTables_wrapper .dataTables_paginate .paginate_button {\n  box-sizing: border-box;\n  display: inline-block;\n  min-width: 1.5em;\n  padding: 0.5em 1em;\n  margin-left: 2px;\n  text-align: center;\n  text-decoration: none !important;\n  cursor: pointer;\n  *cursor: hand;\n  color: #333 !important;\n  border: 1px solid transparent;\n  border-radius: 2px;\n}\n.dataTables_wrapper .dataTables_paginate .paginate_button.current, .dataTables_wrapper .dataTables_paginate .paginate_button.current:hover {\n  color: #333 !important;\n  border: 1px solid #979797;\n  background-color: white;\n  background: -webkit-gradient(linear, left top, left bottom, color-stop(0%, white), color-stop(100%, #dcdcdc));\n  /* Chrome,Safari4+ */\n  background: -webkit-linear-gradient(top, white 0%, #dcdcdc 100%);\n  /* Chrome10+,Safari5.1+ */\n  background: -moz-linear-gradient(top, white 0%, #dcdcdc 100%);\n  /* FF3.6+ */\n  background: -ms-linear-gradient(top, white 0%, #dcdcdc 100%);\n  /* IE10+ */\n  background: -o-linear-gradient(top, white 0%, #dcdcdc 100%);\n  /* Opera 11.10+ */\n  background: linear-gradient(to bottom, white 0%, #dcdcdc 100%);\n  /* W3C */\n}\n.dataTables_wrapper .dataTables_paginate .paginate_button.disabled, .dataTables_wrapper .dataTables_paginate .paginate_button.disabled:hover, .dataTables_wrapper .dataTables_paginate .paginate_button.disabled:active {\n  cursor: default;\n  color: #666 !important;\n  border: 1px solid transparent;\n  background: transparent;\n  box-shadow: none;\n}\n.dataTables_wrapper .dataTables_paginate .paginate_button:hover {\n  color: white !important;\n  border: 1px solid #111;\n  background-color: #585858;\n  background: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #585858), color-stop(100%, #111));\n  /* Chrome,Safari4+ */\n  background: -webkit-linear-gradient(top, #585858 0%, #111 100%);\n  /* Chrome10+,Safari5.1+ */\n  background: -moz-linear-gradient(top, #585858 0%, #111 100%);\n  /* FF3.6+ */\n  background: -ms-linear-gradient(top, #585858 0%, #111 100%);\n  /* IE10+ */\n  background: -o-linear-gradient(top, #585858 0%, #111 100%);\n  /* Opera 11.10+ */\n  background: linear-gradient(to bottom, #585858 0%, #111 100%);\n  /* W3C */\n}\n.dataTables_wrapper .dataTables_paginate .paginate_button:active {\n  outline: none;\n  background-color: #2b2b2b;\n  background: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #2b2b2b), color-stop(100%, #0c0c0c));\n  /* Chrome,Safari4+ */\n  background: -webkit-linear-gradient(top, #2b2b2b 0%, #0c0c0c 100%);\n  /* Chrome10+,Safari5.1+ */\n  background: -moz-linear-gradient(top, #2b2b2b 0%, #0c0c0c 100%);\n  /* FF3.6+ */\n  background: -ms-linear-gradient(top, #2b2b2b 0%, #0c0c0c 100%);\n  /* IE10+ */\n  background: -o-linear-gradient(top, #2b2b2b 0%, #0c0c0c 100%);\n  /* Opera 11.10+ */\n  background: linear-gradient(to bottom, #2b2b2b 0%, #0c0c0c 100%);\n  /* W3C */\n  box-shadow: inset 0 0 3px #111;\n}\n.dataTables_wrapper .dataTables_paginate .ellipsis {\n  padding: 0 1em;\n}\n.dataTables_wrapper .dataTables_processing {\n  position: absolute;\n  top: 50%;\n  left: 50%;\n  width: 100%;\n  height: 40px;\n  margin-left: -50%;\n  margin-top: -25px;\n  padding-top: 20px;\n  text-align: center;\n  font-size: 1.2em;\n  background-color: white;\n  background: -webkit-gradient(linear, left top, right top, color-stop(0%, rgba(255, 255, 255, 0)), color-stop(25%, rgba(255, 255, 255, 0.9)), color-stop(75%, rgba(255, 255, 255, 0.9)), color-stop(100%, rgba(255, 255, 255, 0)));\n  background: -webkit-linear-gradient(left, rgba(255, 255, 255, 0) 0%, rgba(255, 255, 255, 0.9) 25%, rgba(255, 255, 255, 0.9) 75%, rgba(255, 255, 255, 0) 100%);\n  background: -moz-linear-gradient(left, rgba(255, 255, 255, 0) 0%, rgba(255, 255, 255, 0.9) 25%, rgba(255, 255, 255, 0.9) 75%, rgba(255, 255, 255, 0) 100%);\n  background: -ms-linear-gradient(left, rgba(255, 255, 255, 0) 0%, rgba(255, 255, 255, 0.9) 25%, rgba(255, 255, 255, 0.9) 75%, rgba(255, 255, 255, 0) 100%);\n  background: -o-linear-gradient(left, rgba(255, 255, 255, 0) 0%, rgba(255, 255, 255, 0.9) 25%, rgba(255, 255, 255, 0.9) 75%, rgba(255, 255, 255, 0) 100%);\n  background: linear-gradient(to right, rgba(255, 255, 255, 0) 0%, rgba(255, 255, 255, 0.9) 25%, rgba(255, 255, 255, 0.9) 75%, rgba(255, 255, 255, 0) 100%);\n}\n.dataTables_wrapper .dataTables_length,\n.dataTables_wrapper .dataTables_filter,\n.dataTables_wrapper .dataTables_info,\n.dataTables_wrapper .dataTables_processing,\n.dataTables_wrapper .dataTables_paginate {\n  color: #333;\n}\n.dataTables_wrapper .dataTables_scroll {\n  clear: both;\n}\n.dataTables_wrapper .dataTables_scroll div.dataTables_scrollBody {\n  *margin-top: -1px;\n  -webkit-overflow-scrolling: touch;\n}\n.dataTables_wrapper .dataTables_scroll div.dataTables_scrollBody th, .dataTables_wrapper .dataTables_scroll div.dataTables_scrollBody td {\n  vertical-align: middle;\n}\n.dataTables_wrapper .dataTables_scroll div.dataTables_scrollBody th > div.dataTables_sizing,\n.dataTables_wrapper .dataTables_scroll div.dataTables_scrollBody td > div.dataTables_sizing {\n  height: 0;\n  overflow: hidden;\n  margin: 0 !important;\n  padding: 0 !important;\n}\n.dataTables_wrapper.no-footer .dataTables_scrollBody {\n  border-bottom: 1px solid #111;\n}\n.dataTables_wrapper.no-footer div.dataTables_scrollHead table,\n.dataTables_wrapper.no-footer div.dataTables_scrollBody table {\n  border-bottom: none;\n}\n.dataTables_wrapper:after {\n  visibility: hidden;\n  display: block;\n  content: \"\";\n  clear: both;\n  height: 0;\n}\n\n@media screen and (max-width: 767px) {\n  .dataTables_wrapper .dataTables_info,\n  .dataTables_wrapper .dataTables_paginate {\n    float: none;\n    text-align: center;\n  }\n  .dataTables_wrapper .dataTables_paginate {\n    margin-top: 0.5em;\n  }\n}\n@media screen and (max-width: 640px) {\n  .dataTables_wrapper .dataTables_length,\n  .dataTables_wrapper .dataTables_filter {\n    float: none;\n    text-align: center;\n  }\n  .dataTables_wrapper .dataTables_filter {\n    margin-top: 0.5em;\n  }\n}\ntable.dataTable thead th div.DataTables_sort_wrapper {\n  position: relative;\n}\ntable.dataTable thead th div.DataTables_sort_wrapper span {\n  position: absolute;\n  top: 50%;\n  margin-top: -8px;\n  right: -18px;\n}\ntable.dataTable thead th.ui-state-default,\ntable.dataTable tfoot th.ui-state-default {\n  border-left-width: 0;\n}\ntable.dataTable thead th.ui-state-default:first-child,\ntable.dataTable tfoot th.ui-state-default:first-child {\n  border-left-width: 1px;\n}\n\n/*\n * Control feature layout\n */\n.dataTables_wrapper .dataTables_paginate .fg-button {\n  box-sizing: border-box;\n  display: inline-block;\n  min-width: 1.5em;\n  padding: 0.5em;\n  margin-left: 2px;\n  text-align: center;\n  text-decoration: none !important;\n  cursor: pointer;\n  *cursor: hand;\n  border: 1px solid transparent;\n}\n.dataTables_wrapper .dataTables_paginate .fg-button:active {\n  outline: none;\n}\n.dataTables_wrapper .dataTables_paginate .fg-button:first-child {\n  border-top-left-radius: 3px;\n  border-bottom-left-radius: 3px;\n}\n.dataTables_wrapper .dataTables_paginate .fg-button:last-child {\n  border-top-right-radius: 3px;\n  border-bottom-right-radius: 3px;\n}\n.dataTables_wrapper .ui-widget-header {\n  font-weight: normal;\n}\n.dataTables_wrapper .ui-toolbar {\n  padding: 8px;\n}\n.dataTables_wrapper.no-footer .dataTables_scrollBody {\n  border-bottom: none;\n}\n.dataTables_wrapper .dataTables_length,\n.dataTables_wrapper .dataTables_filter,\n.dataTables_wrapper .dataTables_info,\n.dataTables_wrapper .dataTables_processing,\n.dataTables_wrapper .dataTables_paginate {\n  color: inherit;\n}\n"
  },
  {
    "path": "app_backend/vendor/datatables/css/dataTables.material.css",
    "content": "div.dataTables_wrapper div.dataTables_filter {\n  text-align: right;\n}\ndiv.dataTables_wrapper div.dataTables_filter input {\n  margin-left: 0.5em;\n}\ndiv.dataTables_wrapper div.dataTables_info {\n  padding-top: 10px;\n  white-space: nowrap;\n}\ndiv.dataTables_wrapper div.dataTables_processing {\n  position: absolute;\n  top: 50%;\n  left: 50%;\n  width: 200px;\n  margin-left: -100px;\n  text-align: center;\n}\ndiv.dataTables_wrapper div.dataTables_paginate {\n  text-align: right;\n}\ndiv.dataTables_wrapper div.mdl-grid.dt-table {\n  padding-top: 0;\n  padding-bottom: 0;\n}\ndiv.dataTables_wrapper div.mdl-grid.dt-table > div.mdl-cell {\n  margin-top: 0;\n  margin-bottom: 0;\n}\n\ntable.dataTable thead > tr > th.sorting_asc, table.dataTable thead > tr > th.sorting_desc, table.dataTable thead > tr > th.sorting,\ntable.dataTable thead > tr > td.sorting_asc,\ntable.dataTable thead > tr > td.sorting_desc,\ntable.dataTable thead > tr > td.sorting {\n  padding-right: 30px;\n}\ntable.dataTable thead > tr > th:active,\ntable.dataTable thead > tr > td:active {\n  outline: none;\n}\ntable.dataTable thead .sorting,\ntable.dataTable thead .sorting_asc,\ntable.dataTable thead .sorting_desc,\ntable.dataTable thead .sorting_asc_disabled,\ntable.dataTable thead .sorting_desc_disabled {\n  cursor: pointer;\n  position: relative;\n}\ntable.dataTable thead .sorting:before, table.dataTable thead .sorting:after,\ntable.dataTable thead .sorting_asc:before,\ntable.dataTable thead .sorting_asc:after,\ntable.dataTable thead .sorting_desc:before,\ntable.dataTable thead .sorting_desc:after,\ntable.dataTable thead .sorting_asc_disabled:before,\ntable.dataTable thead .sorting_asc_disabled:after,\ntable.dataTable thead .sorting_desc_disabled:before,\ntable.dataTable thead .sorting_desc_disabled:after {\n  position: absolute;\n  bottom: 11px;\n  display: block;\n  opacity: 0.3;\n  font-size: 1.3em;\n}\ntable.dataTable thead .sorting:before,\ntable.dataTable thead .sorting_asc:before,\ntable.dataTable thead .sorting_desc:before,\ntable.dataTable thead .sorting_asc_disabled:before,\ntable.dataTable thead .sorting_desc_disabled:before {\n  right: 1em;\n  content: \"\\2191\";\n}\ntable.dataTable thead .sorting:after,\ntable.dataTable thead .sorting_asc:after,\ntable.dataTable thead .sorting_desc:after,\ntable.dataTable thead .sorting_asc_disabled:after,\ntable.dataTable thead .sorting_desc_disabled:after {\n  right: 0.5em;\n  content: \"\\2193\";\n}\ntable.dataTable thead .sorting_asc:before,\ntable.dataTable thead .sorting_desc:after {\n  opacity: 1;\n}\ntable.dataTable thead .sorting_asc_disabled:before,\ntable.dataTable thead .sorting_desc_disabled:after {\n  opacity: 0;\n}\n"
  },
  {
    "path": "app_backend/vendor/datatables/css/dataTables.semanticui.css",
    "content": "/*\n * Styling for DataTables with Semantic UI\n */\ntable.dataTable.table {\n  margin: 0;\n}\ntable.dataTable.table thead th,\ntable.dataTable.table thead td {\n  position: relative;\n}\ntable.dataTable.table thead th.sorting, table.dataTable.table thead th.sorting_asc, table.dataTable.table thead th.sorting_desc,\ntable.dataTable.table thead td.sorting,\ntable.dataTable.table thead td.sorting_asc,\ntable.dataTable.table thead td.sorting_desc {\n  padding-right: 20px;\n}\ntable.dataTable.table thead th.sorting:after, table.dataTable.table thead th.sorting_asc:after, table.dataTable.table thead th.sorting_desc:after,\ntable.dataTable.table thead td.sorting:after,\ntable.dataTable.table thead td.sorting_asc:after,\ntable.dataTable.table thead td.sorting_desc:after {\n  position: absolute;\n  top: 12px;\n  right: 8px;\n  display: block;\n  font-family: Icons;\n}\ntable.dataTable.table thead th.sorting:after,\ntable.dataTable.table thead td.sorting:after {\n  content: \"\\f0dc\";\n  color: #ddd;\n  font-size: 0.8em;\n}\ntable.dataTable.table thead th.sorting_asc:after,\ntable.dataTable.table thead td.sorting_asc:after {\n  content: \"\\f0de\";\n}\ntable.dataTable.table thead th.sorting_desc:after,\ntable.dataTable.table thead td.sorting_desc:after {\n  content: \"\\f0dd\";\n}\ntable.dataTable.table td,\ntable.dataTable.table th {\n  -webkit-box-sizing: content-box;\n  -moz-box-sizing: content-box;\n  box-sizing: content-box;\n}\ntable.dataTable.table td.dataTables_empty,\ntable.dataTable.table th.dataTables_empty {\n  text-align: center;\n}\ntable.dataTable.table.nowrap th,\ntable.dataTable.table.nowrap td {\n  white-space: nowrap;\n}\n\ndiv.dataTables_wrapper div.dataTables_length select {\n  vertical-align: middle;\n  min-height: 2.7142em;\n}\ndiv.dataTables_wrapper div.dataTables_length .ui.selection.dropdown {\n  min-width: 0;\n}\ndiv.dataTables_wrapper div.dataTables_filter input {\n  margin-left: 0.5em;\n}\ndiv.dataTables_wrapper div.dataTables_info {\n  padding-top: 13px;\n  white-space: nowrap;\n}\ndiv.dataTables_wrapper div.dataTables_processing {\n  position: absolute;\n  top: 50%;\n  left: 50%;\n  width: 200px;\n  margin-left: -100px;\n  text-align: center;\n}\ndiv.dataTables_wrapper div.row.dt-table {\n  padding: 0;\n}\ndiv.dataTables_wrapper div.dataTables_scrollHead table.dataTable {\n  border-bottom-right-radius: 0;\n  border-bottom-left-radius: 0;\n  border-bottom: none;\n}\ndiv.dataTables_wrapper div.dataTables_scrollBody thead .sorting:after,\ndiv.dataTables_wrapper div.dataTables_scrollBody thead .sorting_asc:after,\ndiv.dataTables_wrapper div.dataTables_scrollBody thead .sorting_desc:after {\n  display: none;\n}\ndiv.dataTables_wrapper div.dataTables_scrollBody table.dataTable {\n  border-radius: 0;\n  border-top: none;\n  border-bottom-width: 0;\n}\ndiv.dataTables_wrapper div.dataTables_scrollBody table.dataTable.no-footer {\n  border-bottom-width: 1px;\n}\ndiv.dataTables_wrapper div.dataTables_scrollFoot table.dataTable {\n  border-top-right-radius: 0;\n  border-top-left-radius: 0;\n  border-top: none;\n}\n"
  },
  {
    "path": "app_backend/vendor/datatables/css/dataTables.uikit.css",
    "content": "table.dataTable {\n  clear: both;\n  margin-top: 6px !important;\n  margin-bottom: 6px !important;\n  max-width: none !important;\n}\ntable.dataTable td,\ntable.dataTable th {\n  -webkit-box-sizing: content-box;\n  box-sizing: content-box;\n}\ntable.dataTable td.dataTables_empty,\ntable.dataTable th.dataTables_empty {\n  text-align: center;\n}\ntable.dataTable.nowrap th,\ntable.dataTable.nowrap td {\n  white-space: nowrap;\n}\n\ndiv.dataTables_wrapper div.row.uk-grid.dt-merge-grid {\n  margin-top: 5px;\n}\ndiv.dataTables_wrapper div.dataTables_length label {\n  font-weight: normal;\n  text-align: left;\n  white-space: nowrap;\n}\ndiv.dataTables_wrapper div.dataTables_length select {\n  width: 75px;\n  display: inline-block;\n}\ndiv.dataTables_wrapper div.dataTables_filter {\n  text-align: right;\n}\ndiv.dataTables_wrapper div.dataTables_filter label {\n  font-weight: normal;\n  white-space: nowrap;\n  text-align: left;\n}\ndiv.dataTables_wrapper div.dataTables_filter input {\n  margin-left: 0.5em;\n  display: inline-block;\n  width: auto;\n}\ndiv.dataTables_wrapper div.dataTables_info {\n  padding-top: 8px;\n  white-space: nowrap;\n}\ndiv.dataTables_wrapper div.dataTables_paginate {\n  margin: 0;\n  white-space: nowrap;\n  text-align: right;\n}\ndiv.dataTables_wrapper div.dataTables_paginate ul.pagination {\n  margin: 2px 0;\n  white-space: nowrap;\n}\ndiv.dataTables_wrapper div.dataTables_processing {\n  position: absolute;\n  top: 50%;\n  left: 50%;\n  width: 200px;\n  margin-left: -100px;\n  margin-top: -26px;\n  text-align: center;\n  padding: 1em 0;\n}\n\ntable.dataTable thead > tr > th,\ntable.dataTable thead > tr > td {\n  position: relative;\n}\ntable.dataTable thead > tr > th.sorting_asc, table.dataTable thead > tr > th.sorting_desc, table.dataTable thead > tr > th.sorting,\ntable.dataTable thead > tr > td.sorting_asc,\ntable.dataTable thead > tr > td.sorting_desc,\ntable.dataTable thead > tr > td.sorting {\n  padding-right: 30px;\n}\ntable.dataTable thead > tr > th.sorting:after, table.dataTable thead > tr > th.sorting_asc:after, table.dataTable thead > tr > th.sorting_desc:after,\ntable.dataTable thead > tr > td.sorting:after,\ntable.dataTable thead > tr > td.sorting_asc:after,\ntable.dataTable thead > tr > td.sorting_desc:after {\n  position: absolute;\n  top: 7px;\n  right: 8px;\n  display: block;\n  font-family: 'FontAwesome';\n}\ntable.dataTable thead > tr > th.sorting:after,\ntable.dataTable thead > tr > td.sorting:after {\n  content: \"\\f0dc\";\n  color: #ddd;\n  font-size: 0.8em;\n  padding-top: 0.12em;\n}\ntable.dataTable thead > tr > th.sorting_asc:after,\ntable.dataTable thead > tr > td.sorting_asc:after {\n  content: \"\\f0de\";\n}\ntable.dataTable thead > tr > th.sorting_desc:after,\ntable.dataTable thead > tr > td.sorting_desc:after {\n  content: \"\\f0dd\";\n}\n\ndiv.dataTables_scrollHead table.dataTable {\n  margin-bottom: 0 !important;\n}\n\ndiv.dataTables_scrollBody table {\n  border-top: none;\n  margin-top: 0 !important;\n  margin-bottom: 0 !important;\n}\ndiv.dataTables_scrollBody table thead .sorting:after,\ndiv.dataTables_scrollBody table thead .sorting_asc:after,\ndiv.dataTables_scrollBody table thead .sorting_desc:after {\n  display: none;\n}\ndiv.dataTables_scrollBody table tbody tr:first-child th,\ndiv.dataTables_scrollBody table tbody tr:first-child td {\n  border-top: none;\n}\n\ndiv.dataTables_scrollFoot table {\n  margin-top: 0 !important;\n  border-top: none;\n}\n\n@media screen and (max-width: 767px) {\n  div.dataTables_wrapper div.dataTables_length,\n  div.dataTables_wrapper div.dataTables_filter,\n  div.dataTables_wrapper div.dataTables_info,\n  div.dataTables_wrapper div.dataTables_paginate {\n    text-align: center;\n  }\n}\ntable.dataTable.uk-table-condensed > thead > tr > th {\n  padding-right: 20px;\n}\ntable.dataTable.uk-table-condensed .sorting:after,\ntable.dataTable.uk-table-condensed .sorting_asc:after,\ntable.dataTable.uk-table-condensed .sorting_desc:after {\n  top: 6px;\n  right: 6px;\n}\n"
  },
  {
    "path": "app_backend/vendor/datatables/css/jquery.dataTables.css",
    "content": "/*\n * Table styles\n */\ntable.dataTable {\n  width: 100%;\n  margin: 0 auto;\n  clear: both;\n  border-collapse: separate;\n  border-spacing: 0;\n  /*\n   * Header and footer styles\n   */\n  /*\n   * Body styles\n   */\n}\ntable.dataTable thead th,\ntable.dataTable tfoot th {\n  font-weight: bold;\n}\ntable.dataTable thead th,\ntable.dataTable thead td {\n  padding: 10px 18px;\n  border-bottom: 1px solid #111;\n}\ntable.dataTable thead th:active,\ntable.dataTable thead td:active {\n  outline: none;\n}\ntable.dataTable tfoot th,\ntable.dataTable tfoot td {\n  padding: 10px 18px 6px 18px;\n  border-top: 1px solid #111;\n}\ntable.dataTable thead .sorting,\ntable.dataTable thead .sorting_asc,\ntable.dataTable thead .sorting_desc {\n  cursor: pointer;\n  *cursor: hand;\n}\ntable.dataTable thead .sorting,\ntable.dataTable thead .sorting_asc,\ntable.dataTable thead .sorting_desc,\ntable.dataTable thead .sorting_asc_disabled,\ntable.dataTable thead .sorting_desc_disabled {\n  background-repeat: no-repeat;\n  background-position: center right;\n}\ntable.dataTable thead .sorting {\n  background-image: url(\"../images/sort_both.png\");\n}\ntable.dataTable thead .sorting_asc {\n  background-image: url(\"../images/sort_asc.png\");\n}\ntable.dataTable thead .sorting_desc {\n  background-image: url(\"../images/sort_desc.png\");\n}\ntable.dataTable thead .sorting_asc_disabled {\n  background-image: url(\"../images/sort_asc_disabled.png\");\n}\ntable.dataTable thead .sorting_desc_disabled {\n  background-image: url(\"../images/sort_desc_disabled.png\");\n}\ntable.dataTable tbody tr {\n  background-color: #ffffff;\n}\ntable.dataTable tbody tr.selected {\n  background-color: #B0BED9;\n}\ntable.dataTable tbody th,\ntable.dataTable tbody td {\n  padding: 8px 10px;\n}\ntable.dataTable.row-border tbody th, table.dataTable.row-border tbody td, table.dataTable.display tbody th, table.dataTable.display tbody td {\n  border-top: 1px solid #ddd;\n}\ntable.dataTable.row-border tbody tr:first-child th,\ntable.dataTable.row-border tbody tr:first-child td, table.dataTable.display tbody tr:first-child th,\ntable.dataTable.display tbody tr:first-child td {\n  border-top: none;\n}\ntable.dataTable.cell-border tbody th, table.dataTable.cell-border tbody td {\n  border-top: 1px solid #ddd;\n  border-right: 1px solid #ddd;\n}\ntable.dataTable.cell-border tbody tr th:first-child,\ntable.dataTable.cell-border tbody tr td:first-child {\n  border-left: 1px solid #ddd;\n}\ntable.dataTable.cell-border tbody tr:first-child th,\ntable.dataTable.cell-border tbody tr:first-child td {\n  border-top: none;\n}\ntable.dataTable.stripe tbody tr.odd, table.dataTable.display tbody tr.odd {\n  background-color: #f9f9f9;\n}\ntable.dataTable.stripe tbody tr.odd.selected, table.dataTable.display tbody tr.odd.selected {\n  background-color: #acbad4;\n}\ntable.dataTable.hover tbody tr:hover, table.dataTable.display tbody tr:hover {\n  background-color: #f6f6f6;\n}\ntable.dataTable.hover tbody tr:hover.selected, table.dataTable.display tbody tr:hover.selected {\n  background-color: #aab7d1;\n}\ntable.dataTable.order-column tbody tr > .sorting_1,\ntable.dataTable.order-column tbody tr > .sorting_2,\ntable.dataTable.order-column tbody tr > .sorting_3, table.dataTable.display tbody tr > .sorting_1,\ntable.dataTable.display tbody tr > .sorting_2,\ntable.dataTable.display tbody tr > .sorting_3 {\n  background-color: #fafafa;\n}\ntable.dataTable.order-column tbody tr.selected > .sorting_1,\ntable.dataTable.order-column tbody tr.selected > .sorting_2,\ntable.dataTable.order-column tbody tr.selected > .sorting_3, table.dataTable.display tbody tr.selected > .sorting_1,\ntable.dataTable.display tbody tr.selected > .sorting_2,\ntable.dataTable.display tbody tr.selected > .sorting_3 {\n  background-color: #acbad5;\n}\ntable.dataTable.display tbody tr.odd > .sorting_1, table.dataTable.order-column.stripe tbody tr.odd > .sorting_1 {\n  background-color: #f1f1f1;\n}\ntable.dataTable.display tbody tr.odd > .sorting_2, table.dataTable.order-column.stripe tbody tr.odd > .sorting_2 {\n  background-color: #f3f3f3;\n}\ntable.dataTable.display tbody tr.odd > .sorting_3, table.dataTable.order-column.stripe tbody tr.odd > .sorting_3 {\n  background-color: whitesmoke;\n}\ntable.dataTable.display tbody tr.odd.selected > .sorting_1, table.dataTable.order-column.stripe tbody tr.odd.selected > .sorting_1 {\n  background-color: #a6b4cd;\n}\ntable.dataTable.display tbody tr.odd.selected > .sorting_2, table.dataTable.order-column.stripe tbody tr.odd.selected > .sorting_2 {\n  background-color: #a8b5cf;\n}\ntable.dataTable.display tbody tr.odd.selected > .sorting_3, table.dataTable.order-column.stripe tbody tr.odd.selected > .sorting_3 {\n  background-color: #a9b7d1;\n}\ntable.dataTable.display tbody tr.even > .sorting_1, table.dataTable.order-column.stripe tbody tr.even > .sorting_1 {\n  background-color: #fafafa;\n}\ntable.dataTable.display tbody tr.even > .sorting_2, table.dataTable.order-column.stripe tbody tr.even > .sorting_2 {\n  background-color: #fcfcfc;\n}\ntable.dataTable.display tbody tr.even > .sorting_3, table.dataTable.order-column.stripe tbody tr.even > .sorting_3 {\n  background-color: #fefefe;\n}\ntable.dataTable.display tbody tr.even.selected > .sorting_1, table.dataTable.order-column.stripe tbody tr.even.selected > .sorting_1 {\n  background-color: #acbad5;\n}\ntable.dataTable.display tbody tr.even.selected > .sorting_2, table.dataTable.order-column.stripe tbody tr.even.selected > .sorting_2 {\n  background-color: #aebcd6;\n}\ntable.dataTable.display tbody tr.even.selected > .sorting_3, table.dataTable.order-column.stripe tbody tr.even.selected > .sorting_3 {\n  background-color: #afbdd8;\n}\ntable.dataTable.display tbody tr:hover > .sorting_1, table.dataTable.order-column.hover tbody tr:hover > .sorting_1 {\n  background-color: #eaeaea;\n}\ntable.dataTable.display tbody tr:hover > .sorting_2, table.dataTable.order-column.hover tbody tr:hover > .sorting_2 {\n  background-color: #ececec;\n}\ntable.dataTable.display tbody tr:hover > .sorting_3, table.dataTable.order-column.hover tbody tr:hover > .sorting_3 {\n  background-color: #efefef;\n}\ntable.dataTable.display tbody tr:hover.selected > .sorting_1, table.dataTable.order-column.hover tbody tr:hover.selected > .sorting_1 {\n  background-color: #a2aec7;\n}\ntable.dataTable.display tbody tr:hover.selected > .sorting_2, table.dataTable.order-column.hover tbody tr:hover.selected > .sorting_2 {\n  background-color: #a3b0c9;\n}\ntable.dataTable.display tbody tr:hover.selected > .sorting_3, table.dataTable.order-column.hover tbody tr:hover.selected > .sorting_3 {\n  background-color: #a5b2cb;\n}\ntable.dataTable.no-footer {\n  border-bottom: 1px solid #111;\n}\ntable.dataTable.nowrap th, table.dataTable.nowrap td {\n  white-space: nowrap;\n}\ntable.dataTable.compact thead th,\ntable.dataTable.compact thead td {\n  padding: 4px 17px 4px 4px;\n}\ntable.dataTable.compact tfoot th,\ntable.dataTable.compact tfoot td {\n  padding: 4px;\n}\ntable.dataTable.compact tbody th,\ntable.dataTable.compact tbody td {\n  padding: 4px;\n}\ntable.dataTable th.dt-left,\ntable.dataTable td.dt-left {\n  text-align: left;\n}\ntable.dataTable th.dt-center,\ntable.dataTable td.dt-center,\ntable.dataTable td.dataTables_empty {\n  text-align: center;\n}\ntable.dataTable th.dt-right,\ntable.dataTable td.dt-right {\n  text-align: right;\n}\ntable.dataTable th.dt-justify,\ntable.dataTable td.dt-justify {\n  text-align: justify;\n}\ntable.dataTable th.dt-nowrap,\ntable.dataTable td.dt-nowrap {\n  white-space: nowrap;\n}\ntable.dataTable thead th.dt-head-left,\ntable.dataTable thead td.dt-head-left,\ntable.dataTable tfoot th.dt-head-left,\ntable.dataTable tfoot td.dt-head-left {\n  text-align: left;\n}\ntable.dataTable thead th.dt-head-center,\ntable.dataTable thead td.dt-head-center,\ntable.dataTable tfoot th.dt-head-center,\ntable.dataTable tfoot td.dt-head-center {\n  text-align: center;\n}\ntable.dataTable thead th.dt-head-right,\ntable.dataTable thead td.dt-head-right,\ntable.dataTable tfoot th.dt-head-right,\ntable.dataTable tfoot td.dt-head-right {\n  text-align: right;\n}\ntable.dataTable thead th.dt-head-justify,\ntable.dataTable thead td.dt-head-justify,\ntable.dataTable tfoot th.dt-head-justify,\ntable.dataTable tfoot td.dt-head-justify {\n  text-align: justify;\n}\ntable.dataTable thead th.dt-head-nowrap,\ntable.dataTable thead td.dt-head-nowrap,\ntable.dataTable tfoot th.dt-head-nowrap,\ntable.dataTable tfoot td.dt-head-nowrap {\n  white-space: nowrap;\n}\ntable.dataTable tbody th.dt-body-left,\ntable.dataTable tbody td.dt-body-left {\n  text-align: left;\n}\ntable.dataTable tbody th.dt-body-center,\ntable.dataTable tbody td.dt-body-center {\n  text-align: center;\n}\ntable.dataTable tbody th.dt-body-right,\ntable.dataTable tbody td.dt-body-right {\n  text-align: right;\n}\ntable.dataTable tbody th.dt-body-justify,\ntable.dataTable tbody td.dt-body-justify {\n  text-align: justify;\n}\ntable.dataTable tbody th.dt-body-nowrap,\ntable.dataTable tbody td.dt-body-nowrap {\n  white-space: nowrap;\n}\n\ntable.dataTable,\ntable.dataTable th,\ntable.dataTable td {\n  -webkit-box-sizing: content-box;\n  box-sizing: content-box;\n}\n\n/*\n * Control feature layout\n */\n.dataTables_wrapper {\n  position: relative;\n  clear: both;\n  *zoom: 1;\n  zoom: 1;\n}\n.dataTables_wrapper .dataTables_length {\n  float: left;\n}\n.dataTables_wrapper .dataTables_filter {\n  float: right;\n  text-align: right;\n}\n.dataTables_wrapper .dataTables_filter input {\n  margin-left: 0.5em;\n}\n.dataTables_wrapper .dataTables_info {\n  clear: both;\n  float: left;\n  padding-top: 0.755em;\n}\n.dataTables_wrapper .dataTables_paginate {\n  float: right;\n  text-align: right;\n  padding-top: 0.25em;\n}\n.dataTables_wrapper .dataTables_paginate .paginate_button {\n  box-sizing: border-box;\n  display: inline-block;\n  min-width: 1.5em;\n  padding: 0.5em 1em;\n  margin-left: 2px;\n  text-align: center;\n  text-decoration: none !important;\n  cursor: pointer;\n  *cursor: hand;\n  color: #333 !important;\n  border: 1px solid transparent;\n  border-radius: 2px;\n}\n.dataTables_wrapper .dataTables_paginate .paginate_button.current, .dataTables_wrapper .dataTables_paginate .paginate_button.current:hover {\n  color: #333 !important;\n  border: 1px solid #979797;\n  background-color: white;\n  background: -webkit-gradient(linear, left top, left bottom, color-stop(0%, white), color-stop(100%, #dcdcdc));\n  /* Chrome,Safari4+ */\n  background: -webkit-linear-gradient(top, white 0%, #dcdcdc 100%);\n  /* Chrome10+,Safari5.1+ */\n  background: -moz-linear-gradient(top, white 0%, #dcdcdc 100%);\n  /* FF3.6+ */\n  background: -ms-linear-gradient(top, white 0%, #dcdcdc 100%);\n  /* IE10+ */\n  background: -o-linear-gradient(top, white 0%, #dcdcdc 100%);\n  /* Opera 11.10+ */\n  background: linear-gradient(to bottom, white 0%, #dcdcdc 100%);\n  /* W3C */\n}\n.dataTables_wrapper .dataTables_paginate .paginate_button.disabled, .dataTables_wrapper .dataTables_paginate .paginate_button.disabled:hover, .dataTables_wrapper .dataTables_paginate .paginate_button.disabled:active {\n  cursor: default;\n  color: #666 !important;\n  border: 1px solid transparent;\n  background: transparent;\n  box-shadow: none;\n}\n.dataTables_wrapper .dataTables_paginate .paginate_button:hover {\n  color: white !important;\n  border: 1px solid #111;\n  background-color: #585858;\n  background: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #585858), color-stop(100%, #111));\n  /* Chrome,Safari4+ */\n  background: -webkit-linear-gradient(top, #585858 0%, #111 100%);\n  /* Chrome10+,Safari5.1+ */\n  background: -moz-linear-gradient(top, #585858 0%, #111 100%);\n  /* FF3.6+ */\n  background: -ms-linear-gradient(top, #585858 0%, #111 100%);\n  /* IE10+ */\n  background: -o-linear-gradient(top, #585858 0%, #111 100%);\n  /* Opera 11.10+ */\n  background: linear-gradient(to bottom, #585858 0%, #111 100%);\n  /* W3C */\n}\n.dataTables_wrapper .dataTables_paginate .paginate_button:active {\n  outline: none;\n  background-color: #2b2b2b;\n  background: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #2b2b2b), color-stop(100%, #0c0c0c));\n  /* Chrome,Safari4+ */\n  background: -webkit-linear-gradient(top, #2b2b2b 0%, #0c0c0c 100%);\n  /* Chrome10+,Safari5.1+ */\n  background: -moz-linear-gradient(top, #2b2b2b 0%, #0c0c0c 100%);\n  /* FF3.6+ */\n  background: -ms-linear-gradient(top, #2b2b2b 0%, #0c0c0c 100%);\n  /* IE10+ */\n  background: -o-linear-gradient(top, #2b2b2b 0%, #0c0c0c 100%);\n  /* Opera 11.10+ */\n  background: linear-gradient(to bottom, #2b2b2b 0%, #0c0c0c 100%);\n  /* W3C */\n  box-shadow: inset 0 0 3px #111;\n}\n.dataTables_wrapper .dataTables_paginate .ellipsis {\n  padding: 0 1em;\n}\n.dataTables_wrapper .dataTables_processing {\n  position: absolute;\n  top: 50%;\n  left: 50%;\n  width: 100%;\n  height: 40px;\n  margin-left: -50%;\n  margin-top: -25px;\n  padding-top: 20px;\n  text-align: center;\n  font-size: 1.2em;\n  background-color: white;\n  background: -webkit-gradient(linear, left top, right top, color-stop(0%, rgba(255, 255, 255, 0)), color-stop(25%, rgba(255, 255, 255, 0.9)), color-stop(75%, rgba(255, 255, 255, 0.9)), color-stop(100%, rgba(255, 255, 255, 0)));\n  background: -webkit-linear-gradient(left, rgba(255, 255, 255, 0) 0%, rgba(255, 255, 255, 0.9) 25%, rgba(255, 255, 255, 0.9) 75%, rgba(255, 255, 255, 0) 100%);\n  background: -moz-linear-gradient(left, rgba(255, 255, 255, 0) 0%, rgba(255, 255, 255, 0.9) 25%, rgba(255, 255, 255, 0.9) 75%, rgba(255, 255, 255, 0) 100%);\n  background: -ms-linear-gradient(left, rgba(255, 255, 255, 0) 0%, rgba(255, 255, 255, 0.9) 25%, rgba(255, 255, 255, 0.9) 75%, rgba(255, 255, 255, 0) 100%);\n  background: -o-linear-gradient(left, rgba(255, 255, 255, 0) 0%, rgba(255, 255, 255, 0.9) 25%, rgba(255, 255, 255, 0.9) 75%, rgba(255, 255, 255, 0) 100%);\n  background: linear-gradient(to right, rgba(255, 255, 255, 0) 0%, rgba(255, 255, 255, 0.9) 25%, rgba(255, 255, 255, 0.9) 75%, rgba(255, 255, 255, 0) 100%);\n}\n.dataTables_wrapper .dataTables_length,\n.dataTables_wrapper .dataTables_filter,\n.dataTables_wrapper .dataTables_info,\n.dataTables_wrapper .dataTables_processing,\n.dataTables_wrapper .dataTables_paginate {\n  color: #333;\n}\n.dataTables_wrapper .dataTables_scroll {\n  clear: both;\n}\n.dataTables_wrapper .dataTables_scroll div.dataTables_scrollBody {\n  *margin-top: -1px;\n  -webkit-overflow-scrolling: touch;\n}\n.dataTables_wrapper .dataTables_scroll div.dataTables_scrollBody th, .dataTables_wrapper .dataTables_scroll div.dataTables_scrollBody td {\n  vertical-align: middle;\n}\n.dataTables_wrapper .dataTables_scroll div.dataTables_scrollBody th > div.dataTables_sizing,\n.dataTables_wrapper .dataTables_scroll div.dataTables_scrollBody td > div.dataTables_sizing {\n  height: 0;\n  overflow: hidden;\n  margin: 0 !important;\n  padding: 0 !important;\n}\n.dataTables_wrapper.no-footer .dataTables_scrollBody {\n  border-bottom: 1px solid #111;\n}\n.dataTables_wrapper.no-footer div.dataTables_scrollHead table,\n.dataTables_wrapper.no-footer div.dataTables_scrollBody table {\n  border-bottom: none;\n}\n.dataTables_wrapper:after {\n  visibility: hidden;\n  display: block;\n  content: \"\";\n  clear: both;\n  height: 0;\n}\n\n@media screen and (max-width: 767px) {\n  .dataTables_wrapper .dataTables_info,\n  .dataTables_wrapper .dataTables_paginate {\n    float: none;\n    text-align: center;\n  }\n  .dataTables_wrapper .dataTables_paginate {\n    margin-top: 0.5em;\n  }\n}\n@media screen and (max-width: 640px) {\n  .dataTables_wrapper .dataTables_length,\n  .dataTables_wrapper .dataTables_filter {\n    float: none;\n    text-align: center;\n  }\n  .dataTables_wrapper .dataTables_filter {\n    margin-top: 0.5em;\n  }\n}\n"
  },
  {
    "path": "app_backend/vendor/datatables/css/jquery.dataTables_themeroller.css",
    "content": "/*\n * Table styles\n */\ntable.dataTable {\n  width: 100%;\n  margin: 0 auto;\n  clear: both;\n  border-collapse: separate;\n  border-spacing: 0;\n  /*\n   * Header and footer styles\n   */\n  /*\n   * Body styles\n   */\n}\ntable.dataTable thead th,\ntable.dataTable thead td,\ntable.dataTable tfoot th,\ntable.dataTable tfoot td {\n  padding: 4px 10px;\n}\ntable.dataTable thead th,\ntable.dataTable tfoot th {\n  font-weight: bold;\n}\ntable.dataTable thead th:active,\ntable.dataTable thead td:active {\n  outline: none;\n}\ntable.dataTable thead .sorting_asc,\ntable.dataTable thead .sorting_desc,\ntable.dataTable thead .sorting {\n  cursor: pointer;\n  *cursor: hand;\n}\ntable.dataTable thead th div.DataTables_sort_wrapper {\n  position: relative;\n  padding-right: 10px;\n}\ntable.dataTable thead th div.DataTables_sort_wrapper span {\n  position: absolute;\n  top: 50%;\n  margin-top: -8px;\n  right: -5px;\n}\ntable.dataTable thead th.ui-state-default {\n  border-right-width: 0;\n}\ntable.dataTable thead th.ui-state-default:last-child {\n  border-right-width: 1px;\n}\ntable.dataTable tbody tr {\n  background-color: #ffffff;\n}\ntable.dataTable tbody tr.selected {\n  background-color: #B0BED9;\n}\ntable.dataTable tbody th,\ntable.dataTable tbody td {\n  padding: 8px 10px;\n}\ntable.dataTable th.center,\ntable.dataTable td.center,\ntable.dataTable td.dataTables_empty {\n  text-align: center;\n}\ntable.dataTable th.right,\ntable.dataTable td.right {\n  text-align: right;\n}\ntable.dataTable.row-border tbody th, table.dataTable.row-border tbody td, table.dataTable.display tbody th, table.dataTable.display tbody td {\n  border-top: 1px solid #ddd;\n}\ntable.dataTable.row-border tbody tr:first-child th,\ntable.dataTable.row-border tbody tr:first-child td, table.dataTable.display tbody tr:first-child th,\ntable.dataTable.display tbody tr:first-child td {\n  border-top: none;\n}\ntable.dataTable.cell-border tbody th, table.dataTable.cell-border tbody td {\n  border-top: 1px solid #ddd;\n  border-right: 1px solid #ddd;\n}\ntable.dataTable.cell-border tbody tr th:first-child,\ntable.dataTable.cell-border tbody tr td:first-child {\n  border-left: 1px solid #ddd;\n}\ntable.dataTable.cell-border tbody tr:first-child th,\ntable.dataTable.cell-border tbody tr:first-child td {\n  border-top: none;\n}\ntable.dataTable.stripe tbody tr.odd, table.dataTable.display tbody tr.odd {\n  background-color: #f9f9f9;\n}\ntable.dataTable.stripe tbody tr.odd.selected, table.dataTable.display tbody tr.odd.selected {\n  background-color: #abb9d3;\n}\ntable.dataTable.hover tbody tr:hover,\ntable.dataTable.hover tbody tr.odd:hover,\ntable.dataTable.hover tbody tr.even:hover, table.dataTable.display tbody tr:hover,\ntable.dataTable.display tbody tr.odd:hover,\ntable.dataTable.display tbody tr.even:hover {\n  background-color: whitesmoke;\n}\ntable.dataTable.hover tbody tr:hover.selected,\ntable.dataTable.hover tbody tr.odd:hover.selected,\ntable.dataTable.hover tbody tr.even:hover.selected, table.dataTable.display tbody tr:hover.selected,\ntable.dataTable.display tbody tr.odd:hover.selected,\ntable.dataTable.display tbody tr.even:hover.selected {\n  background-color: #a9b7d1;\n}\ntable.dataTable.order-column tbody tr > .sorting_1,\ntable.dataTable.order-column tbody tr > .sorting_2,\ntable.dataTable.order-column tbody tr > .sorting_3, table.dataTable.display tbody tr > .sorting_1,\ntable.dataTable.display tbody tr > .sorting_2,\ntable.dataTable.display tbody tr > .sorting_3 {\n  background-color: #f9f9f9;\n}\ntable.dataTable.order-column tbody tr.selected > .sorting_1,\ntable.dataTable.order-column tbody tr.selected > .sorting_2,\ntable.dataTable.order-column tbody tr.selected > .sorting_3, table.dataTable.display tbody tr.selected > .sorting_1,\ntable.dataTable.display tbody tr.selected > .sorting_2,\ntable.dataTable.display tbody tr.selected > .sorting_3 {\n  background-color: #acbad4;\n}\ntable.dataTable.display tbody tr.odd > .sorting_1, table.dataTable.order-column.stripe tbody tr.odd > .sorting_1 {\n  background-color: #f1f1f1;\n}\ntable.dataTable.display tbody tr.odd > .sorting_2, table.dataTable.order-column.stripe tbody tr.odd > .sorting_2 {\n  background-color: #f3f3f3;\n}\ntable.dataTable.display tbody tr.odd > .sorting_3, table.dataTable.order-column.stripe tbody tr.odd > .sorting_3 {\n  background-color: whitesmoke;\n}\ntable.dataTable.display tbody tr.odd.selected > .sorting_1, table.dataTable.order-column.stripe tbody tr.odd.selected > .sorting_1 {\n  background-color: #a6b3cd;\n}\ntable.dataTable.display tbody tr.odd.selected > .sorting_2, table.dataTable.order-column.stripe tbody tr.odd.selected > .sorting_2 {\n  background-color: #a7b5ce;\n}\ntable.dataTable.display tbody tr.odd.selected > .sorting_3, table.dataTable.order-column.stripe tbody tr.odd.selected > .sorting_3 {\n  background-color: #a9b6d0;\n}\ntable.dataTable.display tbody tr.even > .sorting_1, table.dataTable.order-column.stripe tbody tr.even > .sorting_1 {\n  background-color: #f9f9f9;\n}\ntable.dataTable.display tbody tr.even > .sorting_2, table.dataTable.order-column.stripe tbody tr.even > .sorting_2 {\n  background-color: #fbfbfb;\n}\ntable.dataTable.display tbody tr.even > .sorting_3, table.dataTable.order-column.stripe tbody tr.even > .sorting_3 {\n  background-color: #fdfdfd;\n}\ntable.dataTable.display tbody tr.even.selected > .sorting_1, table.dataTable.order-column.stripe tbody tr.even.selected > .sorting_1 {\n  background-color: #acbad4;\n}\ntable.dataTable.display tbody tr.even.selected > .sorting_2, table.dataTable.order-column.stripe tbody tr.even.selected > .sorting_2 {\n  background-color: #adbbd6;\n}\ntable.dataTable.display tbody tr.even.selected > .sorting_3, table.dataTable.order-column.stripe tbody tr.even.selected > .sorting_3 {\n  background-color: #afbdd8;\n}\ntable.dataTable.display tbody tr:hover > .sorting_1,\ntable.dataTable.display tbody tr.odd:hover > .sorting_1,\ntable.dataTable.display tbody tr.even:hover > .sorting_1, table.dataTable.order-column.hover tbody tr:hover > .sorting_1,\ntable.dataTable.order-column.hover tbody tr.odd:hover > .sorting_1,\ntable.dataTable.order-column.hover tbody tr.even:hover > .sorting_1 {\n  background-color: #eaeaea;\n}\ntable.dataTable.display tbody tr:hover > .sorting_2,\ntable.dataTable.display tbody tr.odd:hover > .sorting_2,\ntable.dataTable.display tbody tr.even:hover > .sorting_2, table.dataTable.order-column.hover tbody tr:hover > .sorting_2,\ntable.dataTable.order-column.hover tbody tr.odd:hover > .sorting_2,\ntable.dataTable.order-column.hover tbody tr.even:hover > .sorting_2 {\n  background-color: #ebebeb;\n}\ntable.dataTable.display tbody tr:hover > .sorting_3,\ntable.dataTable.display tbody tr.odd:hover > .sorting_3,\ntable.dataTable.display tbody tr.even:hover > .sorting_3, table.dataTable.order-column.hover tbody tr:hover > .sorting_3,\ntable.dataTable.order-column.hover tbody tr.odd:hover > .sorting_3,\ntable.dataTable.order-column.hover tbody tr.even:hover > .sorting_3 {\n  background-color: #eeeeee;\n}\ntable.dataTable.display tbody tr:hover.selected > .sorting_1,\ntable.dataTable.display tbody tr.odd:hover.selected > .sorting_1,\ntable.dataTable.display tbody tr.even:hover.selected > .sorting_1, table.dataTable.order-column.hover tbody tr:hover.selected > .sorting_1,\ntable.dataTable.order-column.hover tbody tr.odd:hover.selected > .sorting_1,\ntable.dataTable.order-column.hover tbody tr.even:hover.selected > .sorting_1 {\n  background-color: #a1aec7;\n}\ntable.dataTable.display tbody tr:hover.selected > .sorting_2,\ntable.dataTable.display tbody tr.odd:hover.selected > .sorting_2,\ntable.dataTable.display tbody tr.even:hover.selected > .sorting_2, table.dataTable.order-column.hover tbody tr:hover.selected > .sorting_2,\ntable.dataTable.order-column.hover tbody tr.odd:hover.selected > .sorting_2,\ntable.dataTable.order-column.hover tbody tr.even:hover.selected > .sorting_2 {\n  background-color: #a2afc8;\n}\ntable.dataTable.display tbody tr:hover.selected > .sorting_3,\ntable.dataTable.display tbody tr.odd:hover.selected > .sorting_3,\ntable.dataTable.display tbody tr.even:hover.selected > .sorting_3, table.dataTable.order-column.hover tbody tr:hover.selected > .sorting_3,\ntable.dataTable.order-column.hover tbody tr.odd:hover.selected > .sorting_3,\ntable.dataTable.order-column.hover tbody tr.even:hover.selected > .sorting_3 {\n  background-color: #a4b2cb;\n}\ntable.dataTable.nowrap th, table.dataTable.nowrap td {\n  white-space: nowrap;\n}\ntable.dataTable.compact thead th,\ntable.dataTable.compact thead td {\n  padding: 5px 9px;\n}\ntable.dataTable.compact tfoot th,\ntable.dataTable.compact tfoot td {\n  padding: 5px 9px 3px 9px;\n}\ntable.dataTable.compact tbody th,\ntable.dataTable.compact tbody td {\n  padding: 4px 5px;\n}\ntable.dataTable th.dt-left,\ntable.dataTable td.dt-left {\n  text-align: left;\n}\ntable.dataTable th.dt-center,\ntable.dataTable td.dt-center,\ntable.dataTable td.dataTables_empty {\n  text-align: center;\n}\ntable.dataTable th.dt-right,\ntable.dataTable td.dt-right {\n  text-align: right;\n}\ntable.dataTable th.dt-justify,\ntable.dataTable td.dt-justify {\n  text-align: justify;\n}\ntable.dataTable th.dt-nowrap,\ntable.dataTable td.dt-nowrap {\n  white-space: nowrap;\n}\ntable.dataTable thead th.dt-head-left,\ntable.dataTable thead td.dt-head-left,\ntable.dataTable tfoot th.dt-head-left,\ntable.dataTable tfoot td.dt-head-left {\n  text-align: left;\n}\ntable.dataTable thead th.dt-head-center,\ntable.dataTable thead td.dt-head-center,\ntable.dataTable tfoot th.dt-head-center,\ntable.dataTable tfoot td.dt-head-center {\n  text-align: center;\n}\ntable.dataTable thead th.dt-head-right,\ntable.dataTable thead td.dt-head-right,\ntable.dataTable tfoot th.dt-head-right,\ntable.dataTable tfoot td.dt-head-right {\n  text-align: right;\n}\ntable.dataTable thead th.dt-head-justify,\ntable.dataTable thead td.dt-head-justify,\ntable.dataTable tfoot th.dt-head-justify,\ntable.dataTable tfoot td.dt-head-justify {\n  text-align: justify;\n}\ntable.dataTable thead th.dt-head-nowrap,\ntable.dataTable thead td.dt-head-nowrap,\ntable.dataTable tfoot th.dt-head-nowrap,\ntable.dataTable tfoot td.dt-head-nowrap {\n  white-space: nowrap;\n}\ntable.dataTable tbody th.dt-body-left,\ntable.dataTable tbody td.dt-body-left {\n  text-align: left;\n}\ntable.dataTable tbody th.dt-body-center,\ntable.dataTable tbody td.dt-body-center {\n  text-align: center;\n}\ntable.dataTable tbody th.dt-body-right,\ntable.dataTable tbody td.dt-body-right {\n  text-align: right;\n}\ntable.dataTable tbody th.dt-body-justify,\ntable.dataTable tbody td.dt-body-justify {\n  text-align: justify;\n}\ntable.dataTable tbody th.dt-body-nowrap,\ntable.dataTable tbody td.dt-body-nowrap {\n  white-space: nowrap;\n}\n\ntable.dataTable,\ntable.dataTable th,\ntable.dataTable td {\n  -webkit-box-sizing: content-box;\n  -moz-box-sizing: content-box;\n  box-sizing: content-box;\n}\n\n/*\n * Control feature layout\n */\n.dataTables_wrapper {\n  position: relative;\n  clear: both;\n  *zoom: 1;\n  zoom: 1;\n}\n.dataTables_wrapper .dataTables_length {\n  float: left;\n}\n.dataTables_wrapper .dataTables_filter {\n  float: right;\n  text-align: right;\n}\n.dataTables_wrapper .dataTables_filter input {\n  margin-left: 0.5em;\n}\n.dataTables_wrapper .dataTables_info {\n  clear: both;\n  float: left;\n  padding-top: 0.55em;\n}\n.dataTables_wrapper .dataTables_paginate {\n  float: right;\n  text-align: right;\n}\n.dataTables_wrapper .dataTables_paginate .fg-button {\n  box-sizing: border-box;\n  display: inline-block;\n  min-width: 1.5em;\n  padding: 0.5em;\n  margin-left: 2px;\n  text-align: center;\n  text-decoration: none !important;\n  cursor: pointer;\n  *cursor: hand;\n  color: #333 !important;\n  border: 1px solid transparent;\n}\n.dataTables_wrapper .dataTables_paginate .fg-button:active {\n  outline: none;\n}\n.dataTables_wrapper .dataTables_paginate .fg-button:first-child {\n  border-top-left-radius: 3px;\n  border-bottom-left-radius: 3px;\n}\n.dataTables_wrapper .dataTables_paginate .fg-button:last-child {\n  border-top-right-radius: 3px;\n  border-bottom-right-radius: 3px;\n}\n.dataTables_wrapper .dataTables_processing {\n  position: absolute;\n  top: 50%;\n  left: 50%;\n  width: 100%;\n  height: 40px;\n  margin-left: -50%;\n  margin-top: -25px;\n  padding-top: 20px;\n  text-align: center;\n  font-size: 1.2em;\n  background-color: white;\n  background: -webkit-gradient(linear, left top, right top, color-stop(0%, rgba(255, 255, 255, 0)), color-stop(25%, rgba(255, 255, 255, 0.9)), color-stop(75%, rgba(255, 255, 255, 0.9)), color-stop(100%, rgba(255, 255, 255, 0)));\n  /* Chrome,Safari4+ */\n  background: -webkit-linear-gradient(left, rgba(255, 255, 255, 0) 0%, rgba(255, 255, 255, 0.9) 25%, rgba(255, 255, 255, 0.9) 75%, rgba(255, 255, 255, 0) 100%);\n  /* Chrome10+,Safari5.1+ */\n  background: -moz-linear-gradient(left, rgba(255, 255, 255, 0) 0%, rgba(255, 255, 255, 0.9) 25%, rgba(255, 255, 255, 0.9) 75%, rgba(255, 255, 255, 0) 100%);\n  /* FF3.6+ */\n  background: -ms-linear-gradient(left, rgba(255, 255, 255, 0) 0%, rgba(255, 255, 255, 0.9) 25%, rgba(255, 255, 255, 0.9) 75%, rgba(255, 255, 255, 0) 100%);\n  /* IE10+ */\n  background: -o-linear-gradient(left, rgba(255, 255, 255, 0) 0%, rgba(255, 255, 255, 0.9) 25%, rgba(255, 255, 255, 0.9) 75%, rgba(255, 255, 255, 0) 100%);\n  /* Opera 11.10+ */\n  background: linear-gradient(to right, rgba(255, 255, 255, 0) 0%, rgba(255, 255, 255, 0.9) 25%, rgba(255, 255, 255, 0.9) 75%, rgba(255, 255, 255, 0) 100%);\n  /* W3C */\n}\n.dataTables_wrapper .dataTables_length,\n.dataTables_wrapper .dataTables_filter,\n.dataTables_wrapper .dataTables_info,\n.dataTables_wrapper .dataTables_processing,\n.dataTables_wrapper .dataTables_paginate {\n  color: #333;\n}\n.dataTables_wrapper .dataTables_scroll {\n  clear: both;\n}\n.dataTables_wrapper .dataTables_scrollBody {\n  *margin-top: -1px;\n  -webkit-overflow-scrolling: touch;\n}\n.dataTables_wrapper .ui-widget-header {\n  font-weight: normal;\n}\n.dataTables_wrapper .ui-toolbar {\n  padding: 8px;\n}\n.dataTables_wrapper:after {\n  visibility: hidden;\n  display: block;\n  content: \"\";\n  clear: both;\n  height: 0;\n}\n\n@media screen and (max-width: 767px) {\n  .dataTables_wrapper .dataTables_length,\n  .dataTables_wrapper .dataTables_filter,\n  .dataTables_wrapper .dataTables_info,\n  .dataTables_wrapper .dataTables_paginate {\n    float: none;\n    text-align: center;\n  }\n  .dataTables_wrapper .dataTables_filter,\n  .dataTables_wrapper .dataTables_paginate {\n    margin-top: 0.5em;\n  }\n}\n"
  },
  {
    "path": "app_backend/vendor/datatables/js/dataTables.bootstrap.js",
    "content": "/*! DataTables Bootstrap 3 integration\n * ©2011-2015 SpryMedia Ltd - datatables.net/license\n */\n\n/**\n * DataTables integration for Bootstrap 3. This requires Bootstrap 3 and\n * DataTables 1.10 or newer.\n *\n * This file sets the defaults and adds options to DataTables to style its\n * controls using Bootstrap. See http://datatables.net/manual/styling/bootstrap\n * for further information.\n */\n(function( factory ){\n\tif ( typeof define === 'function' && define.amd ) {\n\t\t// AMD\n\t\tdefine( ['jquery', 'datatables.net'], function ( $ ) {\n\t\t\treturn factory( $, window, document );\n\t\t} );\n\t}\n\telse if ( typeof exports === 'object' ) {\n\t\t// CommonJS\n\t\tmodule.exports = function (root, $) {\n\t\t\tif ( ! root ) {\n\t\t\t\troot = window;\n\t\t\t}\n\n\t\t\tif ( ! $ || ! $.fn.dataTable ) {\n\t\t\t\t// Require DataTables, which attaches to jQuery, including\n\t\t\t\t// jQuery if needed and have a $ property so we can access the\n\t\t\t\t// jQuery object that is used\n\t\t\t\t$ = require('datatables.net')(root, $).$;\n\t\t\t}\n\n\t\t\treturn factory( $, root, root.document );\n\t\t};\n\t}\n\telse {\n\t\t// Browser\n\t\tfactory( jQuery, window, document );\n\t}\n}(function( $, window, document, undefined ) {\n'use strict';\nvar DataTable = $.fn.dataTable;\n\n\n/* Set the defaults for DataTables initialisation */\n$.extend( true, DataTable.defaults, {\n\tdom:\n\t\t\"<'row'<'col-sm-6'l><'col-sm-6'f>>\" +\n\t\t\"<'row'<'col-sm-12'tr>>\" +\n\t\t\"<'row'<'col-sm-5'i><'col-sm-7'p>>\",\n\trenderer: 'bootstrap'\n} );\n\n\n/* Default class modification */\n$.extend( DataTable.ext.classes, {\n\tsWrapper:      \"dataTables_wrapper form-inline dt-bootstrap\",\n\tsFilterInput:  \"form-control input-sm\",\n\tsLengthSelect: \"form-control input-sm\",\n\tsProcessing:   \"dataTables_processing panel panel-default\"\n} );\n\n\n/* Bootstrap paging button renderer */\nDataTable.ext.renderer.pageButton.bootstrap = function ( settings, host, idx, buttons, page, pages ) {\n\tvar api     = new DataTable.Api( settings );\n\tvar classes = settings.oClasses;\n\tvar lang    = settings.oLanguage.oPaginate;\n\tvar aria = settings.oLanguage.oAria.paginate || {};\n\tvar btnDisplay, btnClass, counter=0;\n\n\tvar attach = function( container, buttons ) {\n\t\tvar i, ien, node, button;\n\t\tvar clickHandler = function ( e ) {\n\t\t\te.preventDefault();\n\t\t\tif ( !$(e.currentTarget).hasClass('disabled') && api.page() != e.data.action ) {\n\t\t\t\tapi.page( e.data.action ).draw( 'page' );\n\t\t\t}\n\t\t};\n\n\t\tfor ( i=0, ien=buttons.length ; i<ien ; i++ ) {\n\t\t\tbutton = buttons[i];\n\n\t\t\tif ( $.isArray( button ) ) {\n\t\t\t\tattach( container, button );\n\t\t\t}\n\t\t\telse {\n\t\t\t\tbtnDisplay = '';\n\t\t\t\tbtnClass = '';\n\n\t\t\t\tswitch ( button ) {\n\t\t\t\t\tcase 'ellipsis':\n\t\t\t\t\t\tbtnDisplay = '&#x2026;';\n\t\t\t\t\t\tbtnClass = 'disabled';\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'first':\n\t\t\t\t\t\tbtnDisplay = lang.sFirst;\n\t\t\t\t\t\tbtnClass = button + (page > 0 ?\n\t\t\t\t\t\t\t'' : ' disabled');\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'previous':\n\t\t\t\t\t\tbtnDisplay = lang.sPrevious;\n\t\t\t\t\t\tbtnClass = button + (page > 0 ?\n\t\t\t\t\t\t\t'' : ' disabled');\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'next':\n\t\t\t\t\t\tbtnDisplay = lang.sNext;\n\t\t\t\t\t\tbtnClass = button + (page < pages-1 ?\n\t\t\t\t\t\t\t'' : ' disabled');\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'last':\n\t\t\t\t\t\tbtnDisplay = lang.sLast;\n\t\t\t\t\t\tbtnClass = button + (page < pages-1 ?\n\t\t\t\t\t\t\t'' : ' disabled');\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tdefault:\n\t\t\t\t\t\tbtnDisplay = button + 1;\n\t\t\t\t\t\tbtnClass = page === button ?\n\t\t\t\t\t\t\t'active' : '';\n\t\t\t\t\t\tbreak;\n\t\t\t\t}\n\n\t\t\t\tif ( btnDisplay ) {\n\t\t\t\t\tnode = $('<li>', {\n\t\t\t\t\t\t\t'class': classes.sPageButton+' '+btnClass,\n\t\t\t\t\t\t\t'id': idx === 0 && typeof button === 'string' ?\n\t\t\t\t\t\t\t\tsettings.sTableId +'_'+ button :\n\t\t\t\t\t\t\t\tnull\n\t\t\t\t\t\t} )\n\t\t\t\t\t\t.append( $('<a>', {\n\t\t\t\t\t\t\t\t'href': '#',\n\t\t\t\t\t\t\t\t'aria-controls': settings.sTableId,\n\t\t\t\t\t\t\t\t'aria-label': aria[ button ],\n\t\t\t\t\t\t\t\t'data-dt-idx': counter,\n\t\t\t\t\t\t\t\t'tabindex': settings.iTabIndex\n\t\t\t\t\t\t\t} )\n\t\t\t\t\t\t\t.html( btnDisplay )\n\t\t\t\t\t\t)\n\t\t\t\t\t\t.appendTo( container );\n\n\t\t\t\t\tsettings.oApi._fnBindAction(\n\t\t\t\t\t\tnode, {action: button}, clickHandler\n\t\t\t\t\t);\n\n\t\t\t\t\tcounter++;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t};\n\n\t// IE9 throws an 'unknown error' if document.activeElement is used\n\t// inside an iframe or frame. \n\tvar activeEl;\n\n\ttry {\n\t\t// Because this approach is destroying and recreating the paging\n\t\t// elements, focus is lost on the select button which is bad for\n\t\t// accessibility. So we want to restore focus once the draw has\n\t\t// completed\n\t\tactiveEl = $(host).find(document.activeElement).data('dt-idx');\n\t}\n\tcatch (e) {}\n\n\tattach(\n\t\t$(host).empty().html('<ul class=\"pagination\"/>').children('ul'),\n\t\tbuttons\n\t);\n\n\tif ( activeEl ) {\n\t\t$(host).find( '[data-dt-idx='+activeEl+']' ).focus();\n\t}\n};\n\n\nreturn DataTable;\n}));"
  },
  {
    "path": "app_backend/vendor/datatables/js/dataTables.bootstrap4.js",
    "content": "/*! DataTables Bootstrap 3 integration\n * ©2011-2015 SpryMedia Ltd - datatables.net/license\n */\n\n/**\n * DataTables integration for Bootstrap 3. This requires Bootstrap 3 and\n * DataTables 1.10 or newer.\n *\n * This file sets the defaults and adds options to DataTables to style its\n * controls using Bootstrap. See http://datatables.net/manual/styling/bootstrap\n * for further information.\n */\n(function( factory ){\n\tif ( typeof define === 'function' && define.amd ) {\n\t\t// AMD\n\t\tdefine( ['jquery', 'datatables.net'], function ( $ ) {\n\t\t\treturn factory( $, window, document );\n\t\t} );\n\t}\n\telse if ( typeof exports === 'object' ) {\n\t\t// CommonJS\n\t\tmodule.exports = function (root, $) {\n\t\t\tif ( ! root ) {\n\t\t\t\troot = window;\n\t\t\t}\n\n\t\t\tif ( ! $ || ! $.fn.dataTable ) {\n\t\t\t\t// Require DataTables, which attaches to jQuery, including\n\t\t\t\t// jQuery if needed and have a $ property so we can access the\n\t\t\t\t// jQuery object that is used\n\t\t\t\t$ = require('datatables.net')(root, $).$;\n\t\t\t}\n\n\t\t\treturn factory( $, root, root.document );\n\t\t};\n\t}\n\telse {\n\t\t// Browser\n\t\tfactory( jQuery, window, document );\n\t}\n}(function( $, window, document, undefined ) {\n'use strict';\nvar DataTable = $.fn.dataTable;\n\n\n/* Set the defaults for DataTables initialisation */\n$.extend( true, DataTable.defaults, {\n\tdom:\n\t\t\"<'row'<'col-md-6'l><'col-md-6'f>>\" +\n\t\t\"<'row'<'col-md-12'tr>>\" +\n\t\t\"<'row'<'col-md-5'i><'col-md-7'p>>\",\n\trenderer: 'bootstrap'\n} );\n\n\n/* Default class modification */\n$.extend( DataTable.ext.classes, {\n\tsWrapper:      \"dataTables_wrapper form-inline dt-bootstrap4\",\n\tsFilterInput:  \"form-control input-sm\",\n\tsLengthSelect: \"form-control input-sm\",\n\tsProcessing:   \"dataTables_processing panel panel-default\",\n\tsPageButton:   \"paginate_button page-item\"\n} );\n\n\n/* Bootstrap paging button renderer */\nDataTable.ext.renderer.pageButton.bootstrap = function ( settings, host, idx, buttons, page, pages ) {\n\tvar api     = new DataTable.Api( settings );\n\tvar classes = settings.oClasses;\n\tvar lang    = settings.oLanguage.oPaginate;\n\tvar aria = settings.oLanguage.oAria.paginate || {};\n\tvar btnDisplay, btnClass, counter=0;\n\n\tvar attach = function( container, buttons ) {\n\t\tvar i, ien, node, button;\n\t\tvar clickHandler = function ( e ) {\n\t\t\te.preventDefault();\n\t\t\tif ( !$(e.currentTarget).hasClass('disabled') && api.page() != e.data.action ) {\n\t\t\t\tapi.page( e.data.action ).draw( 'page' );\n\t\t\t}\n\t\t};\n\n\t\tfor ( i=0, ien=buttons.length ; i<ien ; i++ ) {\n\t\t\tbutton = buttons[i];\n\n\t\t\tif ( $.isArray( button ) ) {\n\t\t\t\tattach( container, button );\n\t\t\t}\n\t\t\telse {\n\t\t\t\tbtnDisplay = '';\n\t\t\t\tbtnClass = '';\n\n\t\t\t\tswitch ( button ) {\n\t\t\t\t\tcase 'ellipsis':\n\t\t\t\t\t\tbtnDisplay = '&#x2026;';\n\t\t\t\t\t\tbtnClass = 'disabled';\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'first':\n\t\t\t\t\t\tbtnDisplay = lang.sFirst;\n\t\t\t\t\t\tbtnClass = button + (page > 0 ?\n\t\t\t\t\t\t\t'' : ' disabled');\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'previous':\n\t\t\t\t\t\tbtnDisplay = lang.sPrevious;\n\t\t\t\t\t\tbtnClass = button + (page > 0 ?\n\t\t\t\t\t\t\t'' : ' disabled');\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'next':\n\t\t\t\t\t\tbtnDisplay = lang.sNext;\n\t\t\t\t\t\tbtnClass = button + (page < pages-1 ?\n\t\t\t\t\t\t\t'' : ' disabled');\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'last':\n\t\t\t\t\t\tbtnDisplay = lang.sLast;\n\t\t\t\t\t\tbtnClass = button + (page < pages-1 ?\n\t\t\t\t\t\t\t'' : ' disabled');\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tdefault:\n\t\t\t\t\t\tbtnDisplay = button + 1;\n\t\t\t\t\t\tbtnClass = page === button ?\n\t\t\t\t\t\t\t'active' : '';\n\t\t\t\t\t\tbreak;\n\t\t\t\t}\n\n\t\t\t\tif ( btnDisplay ) {\n\t\t\t\t\tnode = $('<li>', {\n\t\t\t\t\t\t\t'class': classes.sPageButton+' '+btnClass,\n\t\t\t\t\t\t\t'id': idx === 0 && typeof button === 'string' ?\n\t\t\t\t\t\t\t\tsettings.sTableId +'_'+ button :\n\t\t\t\t\t\t\t\tnull\n\t\t\t\t\t\t} )\n\t\t\t\t\t\t.append( $('<a>', {\n\t\t\t\t\t\t\t\t'href': '#',\n\t\t\t\t\t\t\t\t'aria-controls': settings.sTableId,\n\t\t\t\t\t\t\t\t'aria-label': aria[ button ],\n\t\t\t\t\t\t\t\t'data-dt-idx': counter,\n\t\t\t\t\t\t\t\t'tabindex': settings.iTabIndex,\n\t\t\t\t\t\t\t\t'class': 'page-link'\n\t\t\t\t\t\t\t} )\n\t\t\t\t\t\t\t.html( btnDisplay )\n\t\t\t\t\t\t)\n\t\t\t\t\t\t.appendTo( container );\n\n\t\t\t\t\tsettings.oApi._fnBindAction(\n\t\t\t\t\t\tnode, {action: button}, clickHandler\n\t\t\t\t\t);\n\n\t\t\t\t\tcounter++;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t};\n\n\t// IE9 throws an 'unknown error' if document.activeElement is used\n\t// inside an iframe or frame. \n\tvar activeEl;\n\n\ttry {\n\t\t// Because this approach is destroying and recreating the paging\n\t\t// elements, focus is lost on the select button which is bad for\n\t\t// accessibility. So we want to restore focus once the draw has\n\t\t// completed\n\t\tactiveEl = $(host).find(document.activeElement).data('dt-idx');\n\t}\n\tcatch (e) {}\n\n\tattach(\n\t\t$(host).empty().html('<ul class=\"pagination\"/>').children('ul'),\n\t\tbuttons\n\t);\n\n\tif ( activeEl ) {\n\t\t$(host).find( '[data-dt-idx='+activeEl+']' ).focus();\n\t}\n};\n\n\nreturn DataTable;\n}));"
  },
  {
    "path": "app_backend/vendor/datatables/js/dataTables.foundation.js",
    "content": "/*! DataTables Foundation integration\n * ©2011-2015 SpryMedia Ltd - datatables.net/license\n */\n\n/**\n * DataTables integration for Foundation. This requires Foundation 5 and\n * DataTables 1.10 or newer.\n *\n * This file sets the defaults and adds options to DataTables to style its\n * controls using Foundation. See http://datatables.net/manual/styling/foundation\n * for further information.\n */\n(function( factory ){\n\tif ( typeof define === 'function' && define.amd ) {\n\t\t// AMD\n\t\tdefine( ['jquery', 'datatables.net'], function ( $ ) {\n\t\t\treturn factory( $, window, document );\n\t\t} );\n\t}\n\telse if ( typeof exports === 'object' ) {\n\t\t// CommonJS\n\t\tmodule.exports = function (root, $) {\n\t\t\tif ( ! root ) {\n\t\t\t\troot = window;\n\t\t\t}\n\n\t\t\tif ( ! $ || ! $.fn.dataTable ) {\n\t\t\t\t$ = require('datatables.net')(root, $).$;\n\t\t\t}\n\n\t\t\treturn factory( $, root, root.document );\n\t\t};\n\t}\n\telse {\n\t\t// Browser\n\t\tfactory( jQuery, window, document );\n\t}\n}(function( $, window, document, undefined ) {\n'use strict';\nvar DataTable = $.fn.dataTable;\n\n// Detect Foundation 5 / 6 as they have different element and class requirements\nvar meta = $('<meta class=\"foundation-mq\"/>').appendTo('head');\nDataTable.ext.foundationVersion = meta.css('font-family').match(/small|medium|large/) ? 6 : 5;\nmeta.remove();\n\n\n$.extend( DataTable.ext.classes, {\n\tsWrapper:    \"dataTables_wrapper dt-foundation\",\n\tsProcessing: \"dataTables_processing panel\"\n} );\n\n\n/* Set the defaults for DataTables initialisation */\n$.extend( true, DataTable.defaults, {\n\tdom:\n\t\t\"<'row'<'small-6 columns'l><'small-6 columns'f>r>\"+\n\t\t\"t\"+\n\t\t\"<'row'<'small-6 columns'i><'small-6 columns'p>>\",\n\trenderer: 'foundation'\n} );\n\n\n/* Page button renderer */\nDataTable.ext.renderer.pageButton.foundation = function ( settings, host, idx, buttons, page, pages ) {\n\tvar api = new DataTable.Api( settings );\n\tvar classes = settings.oClasses;\n\tvar lang = settings.oLanguage.oPaginate;\n\tvar aria = settings.oLanguage.oAria.paginate || {};\n\tvar btnDisplay, btnClass;\n\tvar tag;\n\tvar v5 = DataTable.ext.foundationVersion === 5;\n\n\tvar attach = function( container, buttons ) {\n\t\tvar i, ien, node, button;\n\t\tvar clickHandler = function ( e ) {\n\t\t\te.preventDefault();\n\t\t\tif ( !$(e.currentTarget).hasClass('unavailable') && api.page() != e.data.action ) {\n\t\t\t\tapi.page( e.data.action ).draw( 'page' );\n\t\t\t}\n\t\t};\n\n\t\tfor ( i=0, ien=buttons.length ; i<ien ; i++ ) {\n\t\t\tbutton = buttons[i];\n\n\t\t\tif ( $.isArray( button ) ) {\n\t\t\t\tattach( container, button );\n\t\t\t}\n\t\t\telse {\n\t\t\t\tbtnDisplay = '';\n\t\t\t\tbtnClass = '';\n\t\t\t\ttag = null;\n\n\t\t\t\tswitch ( button ) {\n\t\t\t\t\tcase 'ellipsis':\n\t\t\t\t\t\tbtnDisplay = '&#x2026;';\n\t\t\t\t\t\tbtnClass = 'unavailable disabled';\n\t\t\t\t\t\ttag = null;\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'first':\n\t\t\t\t\t\tbtnDisplay = lang.sFirst;\n\t\t\t\t\t\tbtnClass = button + (page > 0 ?\n\t\t\t\t\t\t\t'' : ' unavailable disabled');\n\t\t\t\t\t\ttag = page > 0 ? 'a' : null;\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'previous':\n\t\t\t\t\t\tbtnDisplay = lang.sPrevious;\n\t\t\t\t\t\tbtnClass = button + (page > 0 ?\n\t\t\t\t\t\t\t'' : ' unavailable disabled');\n\t\t\t\t\t\ttag = page > 0 ? 'a' : null;\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'next':\n\t\t\t\t\t\tbtnDisplay = lang.sNext;\n\t\t\t\t\t\tbtnClass = button + (page < pages-1 ?\n\t\t\t\t\t\t\t'' : ' unavailable disabled');\n\t\t\t\t\t\ttag = page < pages-1 ? 'a' : null;\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'last':\n\t\t\t\t\t\tbtnDisplay = lang.sLast;\n\t\t\t\t\t\tbtnClass = button + (page < pages-1 ?\n\t\t\t\t\t\t\t'' : ' unavailable disabled');\n\t\t\t\t\t\ttag = page < pages-1 ? 'a' : null;\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tdefault:\n\t\t\t\t\t\tbtnDisplay = button + 1;\n\t\t\t\t\t\tbtnClass = page === button ?\n\t\t\t\t\t\t\t'current' : '';\n\t\t\t\t\t\ttag = page === button ?\n\t\t\t\t\t\t\tnull : 'a';\n\t\t\t\t\t\tbreak;\n\t\t\t\t}\n\n\t\t\t\tif ( v5 ) {\n\t\t\t\t\ttag = 'a';\n\t\t\t\t}\n\n\t\t\t\tif ( btnDisplay ) {\n\t\t\t\t\tnode = $('<li>', {\n\t\t\t\t\t\t\t'class': classes.sPageButton+' '+btnClass,\n\t\t\t\t\t\t\t'aria-controls': settings.sTableId,\n\t\t\t\t\t\t\t'aria-label': aria[ button ],\n\t\t\t\t\t\t\t'tabindex': settings.iTabIndex,\n\t\t\t\t\t\t\t'id': idx === 0 && typeof button === 'string' ?\n\t\t\t\t\t\t\t\tsettings.sTableId +'_'+ button :\n\t\t\t\t\t\t\t\tnull\n\t\t\t\t\t\t} )\n\t\t\t\t\t\t.append( tag ?\n\t\t\t\t\t\t\t$('<'+tag+'/>', {'href': '#'} ).html( btnDisplay ) :\n\t\t\t\t\t\t\tbtnDisplay\n\t\t\t\t\t\t)\n\t\t\t\t\t\t.appendTo( container );\n\n\t\t\t\t\tsettings.oApi._fnBindAction(\n\t\t\t\t\t\tnode, {action: button}, clickHandler\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t};\n\n\tattach(\n\t\t$(host).empty().html('<ul class=\"pagination\"/>').children('ul'),\n\t\tbuttons\n\t);\n};\n\n\nreturn DataTable;\n}));\n"
  },
  {
    "path": "app_backend/vendor/datatables/js/dataTables.jqueryui.js",
    "content": "/*! DataTables jQuery UI integration\n * ©2011-2014 SpryMedia Ltd - datatables.net/license\n */\n\n/**\n * DataTables integration for jQuery UI. This requires jQuery UI and\n * DataTables 1.10 or newer.\n *\n * This file sets the defaults and adds options to DataTables to style its\n * controls using jQuery UI. See http://datatables.net/manual/styling/jqueryui\n * for further information.\n */\n(function( factory ){\n\tif ( typeof define === 'function' && define.amd ) {\n\t\t// AMD\n\t\tdefine( ['jquery', 'datatables.net'], function ( $ ) {\n\t\t\treturn factory( $, window, document );\n\t\t} );\n\t}\n\telse if ( typeof exports === 'object' ) {\n\t\t// CommonJS\n\t\tmodule.exports = function (root, $) {\n\t\t\tif ( ! root ) {\n\t\t\t\troot = window;\n\t\t\t}\n\n\t\t\tif ( ! $ || ! $.fn.dataTable ) {\n\t\t\t\t$ = require('datatables.net')(root, $).$;\n\t\t\t}\n\n\t\t\treturn factory( $, root, root.document );\n\t\t};\n\t}\n\telse {\n\t\t// Browser\n\t\tfactory( jQuery, window, document );\n\t}\n}(function( $, window, document, undefined ) {\n'use strict';\nvar DataTable = $.fn.dataTable;\n\n\nvar sort_prefix = 'css_right ui-icon ui-icon-';\nvar toolbar_prefix = 'fg-toolbar ui-toolbar ui-widget-header ui-helper-clearfix ui-corner-';\n\n/* Set the defaults for DataTables initialisation */\n$.extend( true, DataTable.defaults, {\n\tdom:\n\t\t'<\"'+toolbar_prefix+'tl ui-corner-tr\"lfr>'+\n\t\t't'+\n\t\t'<\"'+toolbar_prefix+'bl ui-corner-br\"ip>',\n\trenderer: 'jqueryui'\n} );\n\n\n$.extend( DataTable.ext.classes, {\n\t\"sWrapper\":            \"dataTables_wrapper dt-jqueryui\",\n\n\t/* Full numbers paging buttons */\n\t\"sPageButton\":         \"fg-button ui-button ui-state-default\",\n\t\"sPageButtonActive\":   \"ui-state-disabled\",\n\t\"sPageButtonDisabled\": \"ui-state-disabled\",\n\n\t/* Features */\n\t\"sPaging\": \"dataTables_paginate fg-buttonset ui-buttonset fg-buttonset-multi \"+\n\t\t\"ui-buttonset-multi paging_\", /* Note that the type is postfixed */\n\n\t/* Sorting */\n\t\"sSortAsc\":            \"ui-state-default sorting_asc\",\n\t\"sSortDesc\":           \"ui-state-default sorting_desc\",\n\t\"sSortable\":           \"ui-state-default sorting\",\n\t\"sSortableAsc\":        \"ui-state-default sorting_asc_disabled\",\n\t\"sSortableDesc\":       \"ui-state-default sorting_desc_disabled\",\n\t\"sSortableNone\":       \"ui-state-default sorting_disabled\",\n\t\"sSortIcon\":           \"DataTables_sort_icon\",\n\n\t/* Scrolling */\n\t\"sScrollHead\": \"dataTables_scrollHead \"+\"ui-state-default\",\n\t\"sScrollFoot\": \"dataTables_scrollFoot \"+\"ui-state-default\",\n\n\t/* Misc */\n\t\"sHeaderTH\":  \"ui-state-default\",\n\t\"sFooterTH\":  \"ui-state-default\"\n} );\n\n\nDataTable.ext.renderer.header.jqueryui = function ( settings, cell, column, classes ) {\n\t// Calculate what the unsorted class should be\n\tvar noSortAppliedClass = sort_prefix+'carat-2-n-s';\n\tvar asc = $.inArray('asc', column.asSorting) !== -1;\n\tvar desc = $.inArray('desc', column.asSorting) !== -1;\n\n\tif ( !column.bSortable || (!asc && !desc) ) {\n\t\tnoSortAppliedClass = '';\n\t}\n\telse if ( asc && !desc ) {\n\t\tnoSortAppliedClass = sort_prefix+'carat-1-n';\n\t}\n\telse if ( !asc && desc ) {\n\t\tnoSortAppliedClass = sort_prefix+'carat-1-s';\n\t}\n\n\t// Setup the DOM structure\n\t$('<div/>')\n\t\t.addClass( 'DataTables_sort_wrapper' )\n\t\t.append( cell.contents() )\n\t\t.append( $('<span/>')\n\t\t\t.addClass( classes.sSortIcon+' '+noSortAppliedClass )\n\t\t)\n\t\t.appendTo( cell );\n\n\t// Attach a sort listener to update on sort\n\t$(settings.nTable).on( 'order.dt', function ( e, ctx, sorting, columns ) {\n\t\tif ( settings !== ctx ) {\n\t\t\treturn;\n\t\t}\n\n\t\tvar colIdx = column.idx;\n\n\t\tcell\n\t\t\t.removeClass( classes.sSortAsc +\" \"+classes.sSortDesc )\n\t\t\t.addClass( columns[ colIdx ] == 'asc' ?\n\t\t\t\tclasses.sSortAsc : columns[ colIdx ] == 'desc' ?\n\t\t\t\t\tclasses.sSortDesc :\n\t\t\t\t\tcolumn.sSortingClass\n\t\t\t);\n\n\t\tcell\n\t\t\t.find( 'span.'+classes.sSortIcon )\n\t\t\t.removeClass(\n\t\t\t\tsort_prefix+'triangle-1-n' +\" \"+\n\t\t\t\tsort_prefix+'triangle-1-s' +\" \"+\n\t\t\t\tsort_prefix+'carat-2-n-s' +\" \"+\n\t\t\t\tsort_prefix+'carat-1-n' +\" \"+\n\t\t\t\tsort_prefix+'carat-1-s'\n\t\t\t)\n\t\t\t.addClass( columns[ colIdx ] == 'asc' ?\n\t\t\t\tsort_prefix+'triangle-1-n' : columns[ colIdx ] == 'desc' ?\n\t\t\t\t\tsort_prefix+'triangle-1-s' :\n\t\t\t\t\tnoSortAppliedClass\n\t\t\t);\n\t} );\n};\n\n\n/*\n * TableTools jQuery UI compatibility\n * Required TableTools 2.1+\n */\nif ( DataTable.TableTools ) {\n\t$.extend( true, DataTable.TableTools.classes, {\n\t\t\"container\": \"DTTT_container ui-buttonset ui-buttonset-multi\",\n\t\t\"buttons\": {\n\t\t\t\"normal\": \"DTTT_button ui-button ui-state-default\"\n\t\t},\n\t\t\"collection\": {\n\t\t\t\"container\": \"DTTT_collection ui-buttonset ui-buttonset-multi\"\n\t\t}\n\t} );\n}\n\n\nreturn DataTable;\n}));\n"
  },
  {
    "path": "app_backend/vendor/datatables/js/dataTables.material.js",
    "content": "/*! DataTables Bootstrap 3 integration\n * ©2011-2015 SpryMedia Ltd - datatables.net/license\n */\n\n/**\n * DataTables integration for Bootstrap 3. This requires Bootstrap 3 and\n * DataTables 1.10 or newer.\n *\n * This file sets the defaults and adds options to DataTables to style its\n * controls using Bootstrap. See http://datatables.net/manual/styling/bootstrap\n * for further information.\n */\n(function( factory ){\n\tif ( typeof define === 'function' && define.amd ) {\n\t\t// AMD\n\t\tdefine( ['jquery', 'datatables.net'], function ( $ ) {\n\t\t\treturn factory( $, window, document );\n\t\t} );\n\t}\n\telse if ( typeof exports === 'object' ) {\n\t\t// CommonJS\n\t\tmodule.exports = function (root, $) {\n\t\t\tif ( ! root ) {\n\t\t\t\troot = window;\n\t\t\t}\n\n\t\t\tif ( ! $ || ! $.fn.dataTable ) {\n\t\t\t\t// Require DataTables, which attaches to jQuery, including\n\t\t\t\t// jQuery if needed and have a $ property so we can access the\n\t\t\t\t// jQuery object that is used\n\t\t\t\t$ = require('datatables.net')(root, $).$;\n\t\t\t}\n\n\t\t\treturn factory( $, root, root.document );\n\t\t};\n\t}\n\telse {\n\t\t// Browser\n\t\tfactory( jQuery, window, document );\n\t}\n}(function( $, window, document, undefined ) {\n'use strict';\nvar DataTable = $.fn.dataTable;\n\n\n/* Set the defaults for DataTables initialisation */\n$.extend( true, DataTable.defaults, {\n\tdom:\n\t\t\"<'mdl-grid'\"+\n\t\t\t\"<'mdl-cell mdl-cell--6-col'l>\"+\n\t\t\t\"<'mdl-cell mdl-cell--6-col'f>\"+\n\t\t\">\"+\n\t\t\"<'mdl-grid dt-table'\"+\n\t\t\t\"<'mdl-cell mdl-cell--12-col'tr>\"+\n\t\t\">\"+\n\t\t\"<'mdl-grid'\"+\n\t\t\t\"<'mdl-cell mdl-cell--4-col'i>\"+\n\t\t\t\"<'mdl-cell mdl-cell--8-col'p>\"+\n\t\t\">\",\n\trenderer: 'material'\n} );\n\n\n/* Default class modification */\n$.extend( DataTable.ext.classes, {\n\tsWrapper:      \"dataTables_wrapper form-inline dt-material\",\n\tsFilterInput:  \"form-control input-sm\",\n\tsLengthSelect: \"form-control input-sm\",\n\tsProcessing:   \"dataTables_processing panel panel-default\"\n} );\n\n\n/* Bootstrap paging button renderer */\nDataTable.ext.renderer.pageButton.material = function ( settings, host, idx, buttons, page, pages ) {\n\tvar api     = new DataTable.Api( settings );\n\tvar classes = settings.oClasses;\n\tvar lang    = settings.oLanguage.oPaginate;\n\tvar aria = settings.oLanguage.oAria.paginate || {};\n\tvar btnDisplay, btnClass, counter=0;\n\n\tvar attach = function( container, buttons ) {\n\t\tvar i, ien, node, button, disabled, active;\n\t\tvar clickHandler = function ( e ) {\n\t\t\te.preventDefault();\n\t\t\tif ( !$(e.currentTarget).hasClass('disabled') && api.page() != e.data.action ) {\n\t\t\t\tapi.page( e.data.action ).draw( 'page' );\n\t\t\t}\n\t\t};\n\n\t\tfor ( i=0, ien=buttons.length ; i<ien ; i++ ) {\n\t\t\tbutton = buttons[i];\n\n\t\t\tif ( $.isArray( button ) ) {\n\t\t\t\tattach( container, button );\n\t\t\t}\n\t\t\telse {\n\t\t\t\tbtnDisplay = '';\n\t\t\t\tactive = false;\n\n\t\t\t\tswitch ( button ) {\n\t\t\t\t\tcase 'ellipsis':\n\t\t\t\t\t\tbtnDisplay = '&#x2026;';\n\t\t\t\t\t\tbtnClass = 'disabled';\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'first':\n\t\t\t\t\t\tbtnDisplay = lang.sFirst;\n\t\t\t\t\t\tbtnClass = button + (page > 0 ?\n\t\t\t\t\t\t\t'' : ' disabled');\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'previous':\n\t\t\t\t\t\tbtnDisplay = lang.sPrevious;\n\t\t\t\t\t\tbtnClass = button + (page > 0 ?\n\t\t\t\t\t\t\t'' : ' disabled');\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'next':\n\t\t\t\t\t\tbtnDisplay = lang.sNext;\n\t\t\t\t\t\tbtnClass = button + (page < pages-1 ?\n\t\t\t\t\t\t\t'' : ' disabled');\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'last':\n\t\t\t\t\t\tbtnDisplay = lang.sLast;\n\t\t\t\t\t\tbtnClass = button + (page < pages-1 ?\n\t\t\t\t\t\t\t'' : ' disabled');\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tdefault:\n\t\t\t\t\t\tbtnDisplay = button + 1;\n\t\t\t\t\t\tbtnClass = '';\n\t\t\t\t\t\tactive = page === button;\n\t\t\t\t\t\tbreak;\n\t\t\t\t}\n\n\t\t\t\tif ( active ) {\n\t\t\t\t\tbtnClass += ' mdl-button--raised mdl-button--colored';\n\t\t\t\t}\n\n\t\t\t\tif ( btnDisplay ) {\n\t\t\t\t\tnode = $('<button>', {\n\t\t\t\t\t\t\t'class': 'mdl-button '+btnClass,\n\t\t\t\t\t\t\t'id': idx === 0 && typeof button === 'string' ?\n\t\t\t\t\t\t\t\tsettings.sTableId +'_'+ button :\n\t\t\t\t\t\t\t\tnull,\n\t\t\t\t\t\t\t'aria-controls': settings.sTableId,\n\t\t\t\t\t\t\t'aria-label': aria[ button ],\n\t\t\t\t\t\t\t'data-dt-idx': counter,\n\t\t\t\t\t\t\t'tabindex': settings.iTabIndex,\n\t\t\t\t\t\t\t'disabled': btnClass.indexOf('disabled') !== -1\n\t\t\t\t\t\t} )\n\t\t\t\t\t\t.html( btnDisplay )\n\t\t\t\t\t\t.appendTo( container );\n\n\t\t\t\t\tsettings.oApi._fnBindAction(\n\t\t\t\t\t\tnode, {action: button}, clickHandler\n\t\t\t\t\t);\n\n\t\t\t\t\tcounter++;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t};\n\n\t// IE9 throws an 'unknown error' if document.activeElement is used\n\t// inside an iframe or frame. \n\tvar activeEl;\n\n\ttry {\n\t\t// Because this approach is destroying and recreating the paging\n\t\t// elements, focus is lost on the select button which is bad for\n\t\t// accessibility. So we want to restore focus once the draw has\n\t\t// completed\n\t\tactiveEl = $(host).find(document.activeElement).data('dt-idx');\n\t}\n\tcatch (e) {}\n\n\tattach(\n\t\t$(host).empty().html('<div class=\"pagination\"/>').children(),\n\t\tbuttons\n\t);\n\n\tif ( activeEl ) {\n\t\t$(host).find( '[data-dt-idx='+activeEl+']' ).focus();\n\t}\n};\n\n\nreturn DataTable;\n}));"
  },
  {
    "path": "app_backend/vendor/datatables/js/dataTables.semanticui.js",
    "content": "/*! DataTables Bootstrap 3 integration\n * ©2011-2015 SpryMedia Ltd - datatables.net/license\n */\n\n/**\n * DataTables integration for Bootstrap 3. This requires Bootstrap 3 and\n * DataTables 1.10 or newer.\n *\n * This file sets the defaults and adds options to DataTables to style its\n * controls using Bootstrap. See http://datatables.net/manual/styling/bootstrap\n * for further information.\n */\n(function( factory ){\n\tif ( typeof define === 'function' && define.amd ) {\n\t\t// AMD\n\t\tdefine( ['jquery', 'datatables.net'], function ( $ ) {\n\t\t\treturn factory( $, window, document );\n\t\t} );\n\t}\n\telse if ( typeof exports === 'object' ) {\n\t\t// CommonJS\n\t\tmodule.exports = function (root, $) {\n\t\t\tif ( ! root ) {\n\t\t\t\troot = window;\n\t\t\t}\n\n\t\t\tif ( ! $ || ! $.fn.dataTable ) {\n\t\t\t\t// Require DataTables, which attaches to jQuery, including\n\t\t\t\t// jQuery if needed and have a $ property so we can access the\n\t\t\t\t// jQuery object that is used\n\t\t\t\t$ = require('datatables.net')(root, $).$;\n\t\t\t}\n\n\t\t\treturn factory( $, root, root.document );\n\t\t};\n\t}\n\telse {\n\t\t// Browser\n\t\tfactory( jQuery, window, document );\n\t}\n}(function( $, window, document, undefined ) {\n'use strict';\nvar DataTable = $.fn.dataTable;\n\n\n/* Set the defaults for DataTables initialisation */\n$.extend( true, DataTable.defaults, {\n\tdom:\n\t\t\"<'ui grid'\"+\n\t\t\t\"<'row'\"+\n\t\t\t\t\"<'eight wide column'l>\"+\n\t\t\t\t\"<'right aligned eight wide column'f>\"+\n\t\t\t\">\"+\n\t\t\t\"<'row dt-table'\"+\n\t\t\t\t\"<'sixteen wide column'tr>\"+\n\t\t\t\">\"+\n\t\t\t\"<'row'\"+\n\t\t\t\t\"<'seven wide column'i>\"+\n\t\t\t\t\"<'right aligned nine wide column'p>\"+\n\t\t\t\">\"+\n\t\t\">\",\n\trenderer: 'semanticUI'\n} );\n\n\n/* Default class modification */\n$.extend( DataTable.ext.classes, {\n\tsWrapper:      \"dataTables_wrapper dt-semanticUI\",\n\tsFilter:       \"dataTables_filter ui input\",\n\tsProcessing:   \"dataTables_processing ui segment\",\n\tsPageButton:   \"paginate_button item\"\n} );\n\n\n/* Bootstrap paging button renderer */\nDataTable.ext.renderer.pageButton.semanticUI = function ( settings, host, idx, buttons, page, pages ) {\n\tvar api     = new DataTable.Api( settings );\n\tvar classes = settings.oClasses;\n\tvar lang    = settings.oLanguage.oPaginate;\n\tvar aria = settings.oLanguage.oAria.paginate || {};\n\tvar btnDisplay, btnClass, counter=0;\n\n\tvar attach = function( container, buttons ) {\n\t\tvar i, ien, node, button;\n\t\tvar clickHandler = function ( e ) {\n\t\t\te.preventDefault();\n\t\t\tif ( !$(e.currentTarget).hasClass('disabled') && api.page() != e.data.action ) {\n\t\t\t\tapi.page( e.data.action ).draw( 'page' );\n\t\t\t}\n\t\t};\n\n\t\tfor ( i=0, ien=buttons.length ; i<ien ; i++ ) {\n\t\t\tbutton = buttons[i];\n\n\t\t\tif ( $.isArray( button ) ) {\n\t\t\t\tattach( container, button );\n\t\t\t}\n\t\t\telse {\n\t\t\t\tbtnDisplay = '';\n\t\t\t\tbtnClass = '';\n\n\t\t\t\tswitch ( button ) {\n\t\t\t\t\tcase 'ellipsis':\n\t\t\t\t\t\tbtnDisplay = '&#x2026;';\n\t\t\t\t\t\tbtnClass = 'disabled';\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'first':\n\t\t\t\t\t\tbtnDisplay = lang.sFirst;\n\t\t\t\t\t\tbtnClass = button + (page > 0 ?\n\t\t\t\t\t\t\t'' : ' disabled');\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'previous':\n\t\t\t\t\t\tbtnDisplay = lang.sPrevious;\n\t\t\t\t\t\tbtnClass = button + (page > 0 ?\n\t\t\t\t\t\t\t'' : ' disabled');\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'next':\n\t\t\t\t\t\tbtnDisplay = lang.sNext;\n\t\t\t\t\t\tbtnClass = button + (page < pages-1 ?\n\t\t\t\t\t\t\t'' : ' disabled');\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'last':\n\t\t\t\t\t\tbtnDisplay = lang.sLast;\n\t\t\t\t\t\tbtnClass = button + (page < pages-1 ?\n\t\t\t\t\t\t\t'' : ' disabled');\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tdefault:\n\t\t\t\t\t\tbtnDisplay = button + 1;\n\t\t\t\t\t\tbtnClass = page === button ?\n\t\t\t\t\t\t\t'active' : '';\n\t\t\t\t\t\tbreak;\n\t\t\t\t}\n\n\t\t\t\tvar tag = btnClass.indexOf( 'disabled' ) === -1 ?\n\t\t\t\t\t'a' :\n\t\t\t\t\t'div';\n\n\t\t\t\tif ( btnDisplay ) {\n\t\t\t\t\tnode = $('<'+tag+'>', {\n\t\t\t\t\t\t\t'class': classes.sPageButton+' '+btnClass,\n\t\t\t\t\t\t\t'id': idx === 0 && typeof button === 'string' ?\n\t\t\t\t\t\t\t\tsettings.sTableId +'_'+ button :\n\t\t\t\t\t\t\t\tnull,\n\t\t\t\t\t\t\t'href': '#',\n\t\t\t\t\t\t\t'aria-controls': settings.sTableId,\n\t\t\t\t\t\t\t'aria-label': aria[ button ],\n\t\t\t\t\t\t\t'data-dt-idx': counter,\n\t\t\t\t\t\t\t'tabindex': settings.iTabIndex\n\t\t\t\t\t\t} )\n\t\t\t\t\t\t.html( btnDisplay )\n\t\t\t\t\t\t.appendTo( container );\n\n\t\t\t\t\tsettings.oApi._fnBindAction(\n\t\t\t\t\t\tnode, {action: button}, clickHandler\n\t\t\t\t\t);\n\n\t\t\t\t\tcounter++;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t};\n\n\t// IE9 throws an 'unknown error' if document.activeElement is used\n\t// inside an iframe or frame. \n\tvar activeEl;\n\n\ttry {\n\t\t// Because this approach is destroying and recreating the paging\n\t\t// elements, focus is lost on the select button which is bad for\n\t\t// accessibility. So we want to restore focus once the draw has\n\t\t// completed\n\t\tactiveEl = $(host).find(document.activeElement).data('dt-idx');\n\t}\n\tcatch (e) {}\n\n\tattach(\n\t\t$(host).empty().html('<div class=\"ui pagination menu\"/>').children(),\n\t\tbuttons\n\t);\n\n\tif ( activeEl ) {\n\t\t$(host).find( '[data-dt-idx='+activeEl+']' ).focus();\n\t}\n};\n\n\n// Javascript enhancements on table initialisation\n$(document).on( 'init.dt', function (e, ctx) {\n\tif ( e.namespace !== 'dt' ) {\n\t\treturn;\n\t}\n\n\t// Length menu drop down\n\tif ( $.fn.dropdown ) {\n\t\tvar api = new $.fn.dataTable.Api( ctx );\n\n\t\t$( 'div.dataTables_length select', api.table().container() ).dropdown();\n\t}\n} );\n\n\nreturn DataTable;\n}));"
  },
  {
    "path": "app_backend/vendor/datatables/js/dataTables.uikit.js",
    "content": "/*! DataTables UIkit 3 integration\n */\n\n/**\n * This is a tech preview of UIKit integration with DataTables.\n */\n(function( factory ){\n\tif ( typeof define === 'function' && define.amd ) {\n\t\t// AMD\n\t\tdefine( ['jquery', 'datatables.net'], function ( $ ) {\n\t\t\treturn factory( $, window, document );\n\t\t} );\n\t}\n\telse if ( typeof exports === 'object' ) {\n\t\t// CommonJS\n\t\tmodule.exports = function (root, $) {\n\t\t\tif ( ! root ) {\n\t\t\t\troot = window;\n\t\t\t}\n\n\t\t\tif ( ! $ || ! $.fn.dataTable ) {\n\t\t\t\t// Require DataTables, which attaches to jQuery, including\n\t\t\t\t// jQuery if needed and have a $ property so we can access the\n\t\t\t\t// jQuery object that is used\n\t\t\t\t$ = require('datatables.net')(root, $).$;\n\t\t\t}\n\n\t\t\treturn factory( $, root, root.document );\n\t\t};\n\t}\n\telse {\n\t\t// Browser\n\t\tfactory( jQuery, window, document );\n\t}\n}(function( $, window, document, undefined ) {\n'use strict';\nvar DataTable = $.fn.dataTable;\n\n\n/* Set the defaults for DataTables initialisation */\n$.extend( true, DataTable.defaults, {\n\tdom:\n\t\t\"<'row uk-grid'<'uk-width-1-2'l><'uk-width-1-2'f>>\" +\n\t\t\"<'row uk-grid dt-merge-grid'<'uk-width-1-1'tr>>\" +\n\t\t\"<'row uk-grid dt-merge-grid'<'uk-width-2-5'i><'uk-width-3-5'p>>\",\n\trenderer: 'uikit'\n} );\n\n\n/* Default class modification */\n$.extend( DataTable.ext.classes, {\n\tsWrapper:      \"dataTables_wrapper uk-form dt-uikit\",\n\tsFilterInput:  \"uk-form-small\",\n\tsLengthSelect: \"uk-form-small\",\n\tsProcessing:   \"dataTables_processing uk-panel\"\n} );\n\n\n/* UIkit paging button renderer */\nDataTable.ext.renderer.pageButton.uikit = function ( settings, host, idx, buttons, page, pages ) {\n\tvar api     = new DataTable.Api( settings );\n\tvar classes = settings.oClasses;\n\tvar lang    = settings.oLanguage.oPaginate;\n\tvar aria = settings.oLanguage.oAria.paginate || {};\n\tvar btnDisplay, btnClass, counter=0;\n\n\tvar attach = function( container, buttons ) {\n\t\tvar i, ien, node, button;\n\t\tvar clickHandler = function ( e ) {\n\t\t\te.preventDefault();\n\t\t\tif ( !$(e.currentTarget).hasClass('disabled') && api.page() != e.data.action ) {\n\t\t\t\tapi.page( e.data.action ).draw( 'page' );\n\t\t\t}\n\t\t};\n\n\t\tfor ( i=0, ien=buttons.length ; i<ien ; i++ ) {\n\t\t\tbutton = buttons[i];\n\n\t\t\tif ( $.isArray( button ) ) {\n\t\t\t\tattach( container, button );\n\t\t\t}\n\t\t\telse {\n\t\t\t\tbtnDisplay = '';\n\t\t\t\tbtnClass = '';\n\n\t\t\t\tswitch ( button ) {\n\t\t\t\t\tcase 'ellipsis':\n\t\t\t\t\t\tbtnDisplay = '<i class=\"uk-icon-ellipsis-h\"></i>';\n\t\t\t\t\t\tbtnClass = 'uk-disabled disabled';\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'first':\n\t\t\t\t\t\tbtnDisplay = '<i class=\"uk-icon-angle-double-left\"></i> ' + lang.sFirst;\n\t\t\t\t\t\tbtnClass = (page > 0 ?\n\t\t\t\t\t\t\t'' : ' uk-disabled disabled');\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'previous':\n\t\t\t\t\t\tbtnDisplay = '<i class=\"uk-icon-angle-left\"></i> ' + lang.sPrevious;\n\t\t\t\t\t\tbtnClass = (page > 0 ?\n\t\t\t\t\t\t\t'' : 'uk-disabled disabled');\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'next':\n\t\t\t\t\t\tbtnDisplay = lang.sNext + ' <i class=\"uk-icon-angle-right\"></i>';\n\t\t\t\t\t\tbtnClass = (page < pages-1 ?\n\t\t\t\t\t\t\t'' : 'uk-disabled disabled');\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'last':\n\t\t\t\t\t\tbtnDisplay = lang.sLast + ' <i class=\"uk-icon-angle-double-right\"></i>';\n\t\t\t\t\t\tbtnClass = (page < pages-1 ?\n\t\t\t\t\t\t\t'' : ' uk-disabled disabled');\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tdefault:\n\t\t\t\t\t\tbtnDisplay = button + 1;\n\t\t\t\t\t\tbtnClass = page === button ?\n\t\t\t\t\t\t\t'uk-active' : '';\n\t\t\t\t\t\tbreak;\n\t\t\t\t}\n\n\t\t\t\tif ( btnDisplay ) {\n\t\t\t\t\tnode = $('<li>', {\n\t\t\t\t\t\t\t'class': classes.sPageButton+' '+btnClass,\n\t\t\t\t\t\t\t'id': idx === 0 && typeof button === 'string' ?\n\t\t\t\t\t\t\t\tsettings.sTableId +'_'+ button :\n\t\t\t\t\t\t\t\tnull\n\t\t\t\t\t\t} )\n\t\t\t\t\t\t.append( $(( -1 != btnClass.indexOf('disabled') || -1 != btnClass.indexOf('active') ) ? '<span>' : '<a>', {\n\t\t\t\t\t\t\t\t'href': '#',\n\t\t\t\t\t\t\t\t'aria-controls': settings.sTableId,\n\t\t\t\t\t\t\t\t'aria-label': aria[ button ],\n\t\t\t\t\t\t\t\t'data-dt-idx': counter,\n\t\t\t\t\t\t\t\t'tabindex': settings.iTabIndex\n\t\t\t\t\t\t\t} )\n\t\t\t\t\t\t\t.html( btnDisplay )\n\t\t\t\t\t\t)\n\t\t\t\t\t\t.appendTo( container );\n\n\t\t\t\t\tsettings.oApi._fnBindAction(\n\t\t\t\t\t\tnode, {action: button}, clickHandler\n\t\t\t\t\t);\n\n\t\t\t\t\tcounter++;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t};\n\n\t// IE9 throws an 'unknown error' if document.activeElement is used\n\t// inside an iframe or frame. \n\tvar activeEl;\n\n\ttry {\n\t\t// Because this approach is destroying and recreating the paging\n\t\t// elements, focus is lost on the select button which is bad for\n\t\t// accessibility. So we want to restore focus once the draw has\n\t\t// completed\n\t\tactiveEl = $(host).find(document.activeElement).data('dt-idx');\n\t}\n\tcatch (e) {}\n\n\tattach(\n\t\t$(host).empty().html('<ul class=\"uk-pagination uk-pagination-right\"/>').children('ul'),\n\t\tbuttons\n\t);\n\n\tif ( activeEl ) {\n\t\t$(host).find( '[data-dt-idx='+activeEl+']' ).focus();\n\t}\n};\n\n\nreturn DataTable;\n}));"
  },
  {
    "path": "app_backend/vendor/datatables/js/jquery.dataTables.js",
    "content": "/*! DataTables 1.10.12\n * ©2008-2015 SpryMedia Ltd - datatables.net/license\n */\n\n/**\n * @summary     DataTables\n * @description Paginate, search and order HTML tables\n * @version     1.10.12\n * @file        jquery.dataTables.js\n * @author      SpryMedia Ltd (www.sprymedia.co.uk)\n * @contact     www.sprymedia.co.uk/contact\n * @copyright   Copyright 2008-2015 SpryMedia Ltd.\n *\n * This source file is free software, available under the following license:\n *   MIT license - http://datatables.net/license\n *\n * This source file is distributed in the hope that it will be useful, but\n * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY\n * or FITNESS FOR A PARTICULAR PURPOSE. See the license files for details.\n *\n * For details please refer to: http://www.datatables.net\n */\n\n/*jslint evil: true, undef: true, browser: true */\n/*globals $,require,jQuery,define,_selector_run,_selector_opts,_selector_first,_selector_row_indexes,_ext,_Api,_api_register,_api_registerPlural,_re_new_lines,_re_html,_re_formatted_numeric,_re_escape_regex,_empty,_intVal,_numToDecimal,_isNumber,_isHtml,_htmlNumeric,_pluck,_pluck_order,_range,_stripHtml,_unique,_fnBuildAjax,_fnAjaxUpdate,_fnAjaxParameters,_fnAjaxUpdateDraw,_fnAjaxDataSrc,_fnAddColumn,_fnColumnOptions,_fnAdjustColumnSizing,_fnVisibleToColumnIndex,_fnColumnIndexToVisible,_fnVisbleColumns,_fnGetColumns,_fnColumnTypes,_fnApplyColumnDefs,_fnHungarianMap,_fnCamelToHungarian,_fnLanguageCompat,_fnBrowserDetect,_fnAddData,_fnAddTr,_fnNodeToDataIndex,_fnNodeToColumnIndex,_fnGetCellData,_fnSetCellData,_fnSplitObjNotation,_fnGetObjectDataFn,_fnSetObjectDataFn,_fnGetDataMaster,_fnClearTable,_fnDeleteIndex,_fnInvalidate,_fnGetRowElements,_fnCreateTr,_fnBuildHead,_fnDrawHead,_fnDraw,_fnReDraw,_fnAddOptionsHtml,_fnDetectHeader,_fnGetUniqueThs,_fnFeatureHtmlFilter,_fnFilterComplete,_fnFilterCustom,_fnFilterColumn,_fnFilter,_fnFilterCreateSearch,_fnEscapeRegex,_fnFilterData,_fnFeatureHtmlInfo,_fnUpdateInfo,_fnInfoMacros,_fnInitialise,_fnInitComplete,_fnLengthChange,_fnFeatureHtmlLength,_fnFeatureHtmlPaginate,_fnPageChange,_fnFeatureHtmlProcessing,_fnProcessingDisplay,_fnFeatureHtmlTable,_fnScrollDraw,_fnApplyToChildren,_fnCalculateColumnWidths,_fnThrottle,_fnConvertToWidth,_fnGetWidestNode,_fnGetMaxLenString,_fnStringToCss,_fnSortFlatten,_fnSort,_fnSortAria,_fnSortListener,_fnSortAttachListener,_fnSortingClasses,_fnSortData,_fnSaveState,_fnLoadState,_fnSettingsFromNode,_fnLog,_fnMap,_fnBindAction,_fnCallbackReg,_fnCallbackFire,_fnLengthOverflow,_fnRenderer,_fnDataSource,_fnRowAttributes*/\n\n(function( factory ) {\n\t\"use strict\";\n\n\tif ( typeof define === 'function' && define.amd ) {\n\t\t// AMD\n\t\tdefine( ['jquery'], function ( $ ) {\n\t\t\treturn factory( $, window, document );\n\t\t} );\n\t}\n\telse if ( typeof exports === 'object' ) {\n\t\t// CommonJS\n\t\tmodule.exports = function (root, $) {\n\t\t\tif ( ! root ) {\n\t\t\t\t// CommonJS environments without a window global must pass a\n\t\t\t\t// root. This will give an error otherwise\n\t\t\t\troot = window;\n\t\t\t}\n\n\t\t\tif ( ! $ ) {\n\t\t\t\t$ = typeof window !== 'undefined' ? // jQuery's factory checks for a global window\n\t\t\t\t\trequire('jquery') :\n\t\t\t\t\trequire('jquery')( root );\n\t\t\t}\n\n\t\t\treturn factory( $, root, root.document );\n\t\t};\n\t}\n\telse {\n\t\t// Browser\n\t\tfactory( jQuery, window, document );\n\t}\n}\n(function( $, window, document, undefined ) {\n\t\"use strict\";\n\n\t/**\n\t * DataTables is a plug-in for the jQuery Javascript library. It is a highly\n\t * flexible tool, based upon the foundations of progressive enhancement,\n\t * which will add advanced interaction controls to any HTML table. For a\n\t * full list of features please refer to\n\t * [DataTables.net](href=\"http://datatables.net).\n\t *\n\t * Note that the `DataTable` object is not a global variable but is aliased\n\t * to `jQuery.fn.DataTable` and `jQuery.fn.dataTable` through which it may\n\t * be  accessed.\n\t *\n\t *  @class\n\t *  @param {object} [init={}] Configuration object for DataTables. Options\n\t *    are defined by {@link DataTable.defaults}\n\t *  @requires jQuery 1.7+\n\t *\n\t *  @example\n\t *    // Basic initialisation\n\t *    $(document).ready( function {\n\t *      $('#example').dataTable();\n\t *    } );\n\t *\n\t *  @example\n\t *    // Initialisation with configuration options - in this case, disable\n\t *    // pagination and sorting.\n\t *    $(document).ready( function {\n\t *      $('#example').dataTable( {\n\t *        \"paginate\": false,\n\t *        \"sort\": false\n\t *      } );\n\t *    } );\n\t */\n\tvar DataTable = function ( options )\n\t{\n\t\t/**\n\t\t * Perform a jQuery selector action on the table's TR elements (from the tbody) and\n\t\t * return the resulting jQuery object.\n\t\t *  @param {string|node|jQuery} sSelector jQuery selector or node collection to act on\n\t\t *  @param {object} [oOpts] Optional parameters for modifying the rows to be included\n\t\t *  @param {string} [oOpts.filter=none] Select TR elements that meet the current filter\n\t\t *    criterion (\"applied\") or all TR elements (i.e. no filter).\n\t\t *  @param {string} [oOpts.order=current] Order of the TR elements in the processed array.\n\t\t *    Can be either 'current', whereby the current sorting of the table is used, or\n\t\t *    'original' whereby the original order the data was read into the table is used.\n\t\t *  @param {string} [oOpts.page=all] Limit the selection to the currently displayed page\n\t\t *    (\"current\") or not (\"all\"). If 'current' is given, then order is assumed to be\n\t\t *    'current' and filter is 'applied', regardless of what they might be given as.\n\t\t *  @returns {object} jQuery object, filtered by the given selector.\n\t\t *  @dtopt API\n\t\t *  @deprecated Since v1.10\n\t\t *\n\t\t *  @example\n\t\t *    $(document).ready(function() {\n\t\t *      var oTable = $('#example').dataTable();\n\t\t *\n\t\t *      // Highlight every second row\n\t\t *      oTable.$('tr:odd').css('backgroundColor', 'blue');\n\t\t *    } );\n\t\t *\n\t\t *  @example\n\t\t *    $(document).ready(function() {\n\t\t *      var oTable = $('#example').dataTable();\n\t\t *\n\t\t *      // Filter to rows with 'Webkit' in them, add a background colour and then\n\t\t *      // remove the filter, thus highlighting the 'Webkit' rows only.\n\t\t *      oTable.fnFilter('Webkit');\n\t\t *      oTable.$('tr', {\"search\": \"applied\"}).css('backgroundColor', 'blue');\n\t\t *      oTable.fnFilter('');\n\t\t *    } );\n\t\t */\n\t\tthis.$ = function ( sSelector, oOpts )\n\t\t{\n\t\t\treturn this.api(true).$( sSelector, oOpts );\n\t\t};\n\t\t\n\t\t\n\t\t/**\n\t\t * Almost identical to $ in operation, but in this case returns the data for the matched\n\t\t * rows - as such, the jQuery selector used should match TR row nodes or TD/TH cell nodes\n\t\t * rather than any descendants, so the data can be obtained for the row/cell. If matching\n\t\t * rows are found, the data returned is the original data array/object that was used to\n\t\t * create the row (or a generated array if from a DOM source).\n\t\t *\n\t\t * This method is often useful in-combination with $ where both functions are given the\n\t\t * same parameters and the array indexes will match identically.\n\t\t *  @param {string|node|jQuery} sSelector jQuery selector or node collection to act on\n\t\t *  @param {object} [oOpts] Optional parameters for modifying the rows to be included\n\t\t *  @param {string} [oOpts.filter=none] Select elements that meet the current filter\n\t\t *    criterion (\"applied\") or all elements (i.e. no filter).\n\t\t *  @param {string} [oOpts.order=current] Order of the data in the processed array.\n\t\t *    Can be either 'current', whereby the current sorting of the table is used, or\n\t\t *    'original' whereby the original order the data was read into the table is used.\n\t\t *  @param {string} [oOpts.page=all] Limit the selection to the currently displayed page\n\t\t *    (\"current\") or not (\"all\"). If 'current' is given, then order is assumed to be\n\t\t *    'current' and filter is 'applied', regardless of what they might be given as.\n\t\t *  @returns {array} Data for the matched elements. If any elements, as a result of the\n\t\t *    selector, were not TR, TD or TH elements in the DataTable, they will have a null\n\t\t *    entry in the array.\n\t\t *  @dtopt API\n\t\t *  @deprecated Since v1.10\n\t\t *\n\t\t *  @example\n\t\t *    $(document).ready(function() {\n\t\t *      var oTable = $('#example').dataTable();\n\t\t *\n\t\t *      // Get the data from the first row in the table\n\t\t *      var data = oTable._('tr:first');\n\t\t *\n\t\t *      // Do something useful with the data\n\t\t *      alert( \"First cell is: \"+data[0] );\n\t\t *    } );\n\t\t *\n\t\t *  @example\n\t\t *    $(document).ready(function() {\n\t\t *      var oTable = $('#example').dataTable();\n\t\t *\n\t\t *      // Filter to 'Webkit' and get all data for\n\t\t *      oTable.fnFilter('Webkit');\n\t\t *      var data = oTable._('tr', {\"search\": \"applied\"});\n\t\t *\n\t\t *      // Do something with the data\n\t\t *      alert( data.length+\" rows matched the search\" );\n\t\t *    } );\n\t\t */\n\t\tthis._ = function ( sSelector, oOpts )\n\t\t{\n\t\t\treturn this.api(true).rows( sSelector, oOpts ).data();\n\t\t};\n\t\t\n\t\t\n\t\t/**\n\t\t * Create a DataTables Api instance, with the currently selected tables for\n\t\t * the Api's context.\n\t\t * @param {boolean} [traditional=false] Set the API instance's context to be\n\t\t *   only the table referred to by the `DataTable.ext.iApiIndex` option, as was\n\t\t *   used in the API presented by DataTables 1.9- (i.e. the traditional mode),\n\t\t *   or if all tables captured in the jQuery object should be used.\n\t\t * @return {DataTables.Api}\n\t\t */\n\t\tthis.api = function ( traditional )\n\t\t{\n\t\t\treturn traditional ?\n\t\t\t\tnew _Api(\n\t\t\t\t\t_fnSettingsFromNode( this[ _ext.iApiIndex ] )\n\t\t\t\t) :\n\t\t\t\tnew _Api( this );\n\t\t};\n\t\t\n\t\t\n\t\t/**\n\t\t * Add a single new row or multiple rows of data to the table. Please note\n\t\t * that this is suitable for client-side processing only - if you are using\n\t\t * server-side processing (i.e. \"bServerSide\": true), then to add data, you\n\t\t * must add it to the data source, i.e. the server-side, through an Ajax call.\n\t\t *  @param {array|object} data The data to be added to the table. This can be:\n\t\t *    <ul>\n\t\t *      <li>1D array of data - add a single row with the data provided</li>\n\t\t *      <li>2D array of arrays - add multiple rows in a single call</li>\n\t\t *      <li>object - data object when using <i>mData</i></li>\n\t\t *      <li>array of objects - multiple data objects when using <i>mData</i></li>\n\t\t *    </ul>\n\t\t *  @param {bool} [redraw=true] redraw the table or not\n\t\t *  @returns {array} An array of integers, representing the list of indexes in\n\t\t *    <i>aoData</i> ({@link DataTable.models.oSettings}) that have been added to\n\t\t *    the table.\n\t\t *  @dtopt API\n\t\t *  @deprecated Since v1.10\n\t\t *\n\t\t *  @example\n\t\t *    // Global var for counter\n\t\t *    var giCount = 2;\n\t\t *\n\t\t *    $(document).ready(function() {\n\t\t *      $('#example').dataTable();\n\t\t *    } );\n\t\t *\n\t\t *    function fnClickAddRow() {\n\t\t *      $('#example').dataTable().fnAddData( [\n\t\t *        giCount+\".1\",\n\t\t *        giCount+\".2\",\n\t\t *        giCount+\".3\",\n\t\t *        giCount+\".4\" ]\n\t\t *      );\n\t\t *\n\t\t *      giCount++;\n\t\t *    }\n\t\t */\n\t\tthis.fnAddData = function( data, redraw )\n\t\t{\n\t\t\tvar api = this.api( true );\n\t\t\n\t\t\t/* Check if we want to add multiple rows or not */\n\t\t\tvar rows = $.isArray(data) && ( $.isArray(data[0]) || $.isPlainObject(data[0]) ) ?\n\t\t\t\tapi.rows.add( data ) :\n\t\t\t\tapi.row.add( data );\n\t\t\n\t\t\tif ( redraw === undefined || redraw ) {\n\t\t\t\tapi.draw();\n\t\t\t}\n\t\t\n\t\t\treturn rows.flatten().toArray();\n\t\t};\n\t\t\n\t\t\n\t\t/**\n\t\t * This function will make DataTables recalculate the column sizes, based on the data\n\t\t * contained in the table and the sizes applied to the columns (in the DOM, CSS or\n\t\t * through the sWidth parameter). This can be useful when the width of the table's\n\t\t * parent element changes (for example a window resize).\n\t\t *  @param {boolean} [bRedraw=true] Redraw the table or not, you will typically want to\n\t\t *  @dtopt API\n\t\t *  @deprecated Since v1.10\n\t\t *\n\t\t *  @example\n\t\t *    $(document).ready(function() {\n\t\t *      var oTable = $('#example').dataTable( {\n\t\t *        \"sScrollY\": \"200px\",\n\t\t *        \"bPaginate\": false\n\t\t *      } );\n\t\t *\n\t\t *      $(window).bind('resize', function () {\n\t\t *        oTable.fnAdjustColumnSizing();\n\t\t *      } );\n\t\t *    } );\n\t\t */\n\t\tthis.fnAdjustColumnSizing = function ( bRedraw )\n\t\t{\n\t\t\tvar api = this.api( true ).columns.adjust();\n\t\t\tvar settings = api.settings()[0];\n\t\t\tvar scroll = settings.oScroll;\n\t\t\n\t\t\tif ( bRedraw === undefined || bRedraw ) {\n\t\t\t\tapi.draw( false );\n\t\t\t}\n\t\t\telse if ( scroll.sX !== \"\" || scroll.sY !== \"\" ) {\n\t\t\t\t/* If not redrawing, but scrolling, we want to apply the new column sizes anyway */\n\t\t\t\t_fnScrollDraw( settings );\n\t\t\t}\n\t\t};\n\t\t\n\t\t\n\t\t/**\n\t\t * Quickly and simply clear a table\n\t\t *  @param {bool} [bRedraw=true] redraw the table or not\n\t\t *  @dtopt API\n\t\t *  @deprecated Since v1.10\n\t\t *\n\t\t *  @example\n\t\t *    $(document).ready(function() {\n\t\t *      var oTable = $('#example').dataTable();\n\t\t *\n\t\t *      // Immediately 'nuke' the current rows (perhaps waiting for an Ajax callback...)\n\t\t *      oTable.fnClearTable();\n\t\t *    } );\n\t\t */\n\t\tthis.fnClearTable = function( bRedraw )\n\t\t{\n\t\t\tvar api = this.api( true ).clear();\n\t\t\n\t\t\tif ( bRedraw === undefined || bRedraw ) {\n\t\t\t\tapi.draw();\n\t\t\t}\n\t\t};\n\t\t\n\t\t\n\t\t/**\n\t\t * The exact opposite of 'opening' a row, this function will close any rows which\n\t\t * are currently 'open'.\n\t\t *  @param {node} nTr the table row to 'close'\n\t\t *  @returns {int} 0 on success, or 1 if failed (can't find the row)\n\t\t *  @dtopt API\n\t\t *  @deprecated Since v1.10\n\t\t *\n\t\t *  @example\n\t\t *    $(document).ready(function() {\n\t\t *      var oTable;\n\t\t *\n\t\t *      // 'open' an information row when a row is clicked on\n\t\t *      $('#example tbody tr').click( function () {\n\t\t *        if ( oTable.fnIsOpen(this) ) {\n\t\t *          oTable.fnClose( this );\n\t\t *        } else {\n\t\t *          oTable.fnOpen( this, \"Temporary row opened\", \"info_row\" );\n\t\t *        }\n\t\t *      } );\n\t\t *\n\t\t *      oTable = $('#example').dataTable();\n\t\t *    } );\n\t\t */\n\t\tthis.fnClose = function( nTr )\n\t\t{\n\t\t\tthis.api( true ).row( nTr ).child.hide();\n\t\t};\n\t\t\n\t\t\n\t\t/**\n\t\t * Remove a row for the table\n\t\t *  @param {mixed} target The index of the row from aoData to be deleted, or\n\t\t *    the TR element you want to delete\n\t\t *  @param {function|null} [callBack] Callback function\n\t\t *  @param {bool} [redraw=true] Redraw the table or not\n\t\t *  @returns {array} The row that was deleted\n\t\t *  @dtopt API\n\t\t *  @deprecated Since v1.10\n\t\t *\n\t\t *  @example\n\t\t *    $(document).ready(function() {\n\t\t *      var oTable = $('#example').dataTable();\n\t\t *\n\t\t *      // Immediately remove the first row\n\t\t *      oTable.fnDeleteRow( 0 );\n\t\t *    } );\n\t\t */\n\t\tthis.fnDeleteRow = function( target, callback, redraw )\n\t\t{\n\t\t\tvar api = this.api( true );\n\t\t\tvar rows = api.rows( target );\n\t\t\tvar settings = rows.settings()[0];\n\t\t\tvar data = settings.aoData[ rows[0][0] ];\n\t\t\n\t\t\trows.remove();\n\t\t\n\t\t\tif ( callback ) {\n\t\t\t\tcallback.call( this, settings, data );\n\t\t\t}\n\t\t\n\t\t\tif ( redraw === undefined || redraw ) {\n\t\t\t\tapi.draw();\n\t\t\t}\n\t\t\n\t\t\treturn data;\n\t\t};\n\t\t\n\t\t\n\t\t/**\n\t\t * Restore the table to it's original state in the DOM by removing all of DataTables\n\t\t * enhancements, alterations to the DOM structure of the table and event listeners.\n\t\t *  @param {boolean} [remove=false] Completely remove the table from the DOM\n\t\t *  @dtopt API\n\t\t *  @deprecated Since v1.10\n\t\t *\n\t\t *  @example\n\t\t *    $(document).ready(function() {\n\t\t *      // This example is fairly pointless in reality, but shows how fnDestroy can be used\n\t\t *      var oTable = $('#example').dataTable();\n\t\t *      oTable.fnDestroy();\n\t\t *    } );\n\t\t */\n\t\tthis.fnDestroy = function ( remove )\n\t\t{\n\t\t\tthis.api( true ).destroy( remove );\n\t\t};\n\t\t\n\t\t\n\t\t/**\n\t\t * Redraw the table\n\t\t *  @param {bool} [complete=true] Re-filter and resort (if enabled) the table before the draw.\n\t\t *  @dtopt API\n\t\t *  @deprecated Since v1.10\n\t\t *\n\t\t *  @example\n\t\t *    $(document).ready(function() {\n\t\t *      var oTable = $('#example').dataTable();\n\t\t *\n\t\t *      // Re-draw the table - you wouldn't want to do it here, but it's an example :-)\n\t\t *      oTable.fnDraw();\n\t\t *    } );\n\t\t */\n\t\tthis.fnDraw = function( complete )\n\t\t{\n\t\t\t// Note that this isn't an exact match to the old call to _fnDraw - it takes\n\t\t\t// into account the new data, but can hold position.\n\t\t\tthis.api( true ).draw( complete );\n\t\t};\n\t\t\n\t\t\n\t\t/**\n\t\t * Filter the input based on data\n\t\t *  @param {string} sInput String to filter the table on\n\t\t *  @param {int|null} [iColumn] Column to limit filtering to\n\t\t *  @param {bool} [bRegex=false] Treat as regular expression or not\n\t\t *  @param {bool} [bSmart=true] Perform smart filtering or not\n\t\t *  @param {bool} [bShowGlobal=true] Show the input global filter in it's input box(es)\n\t\t *  @param {bool} [bCaseInsensitive=true] Do case-insensitive matching (true) or not (false)\n\t\t *  @dtopt API\n\t\t *  @deprecated Since v1.10\n\t\t *\n\t\t *  @example\n\t\t *    $(document).ready(function() {\n\t\t *      var oTable = $('#example').dataTable();\n\t\t *\n\t\t *      // Sometime later - filter...\n\t\t *      oTable.fnFilter( 'test string' );\n\t\t *    } );\n\t\t */\n\t\tthis.fnFilter = function( sInput, iColumn, bRegex, bSmart, bShowGlobal, bCaseInsensitive )\n\t\t{\n\t\t\tvar api = this.api( true );\n\t\t\n\t\t\tif ( iColumn === null || iColumn === undefined ) {\n\t\t\t\tapi.search( sInput, bRegex, bSmart, bCaseInsensitive );\n\t\t\t}\n\t\t\telse {\n\t\t\t\tapi.column( iColumn ).search( sInput, bRegex, bSmart, bCaseInsensitive );\n\t\t\t}\n\t\t\n\t\t\tapi.draw();\n\t\t};\n\t\t\n\t\t\n\t\t/**\n\t\t * Get the data for the whole table, an individual row or an individual cell based on the\n\t\t * provided parameters.\n\t\t *  @param {int|node} [src] A TR row node, TD/TH cell node or an integer. If given as\n\t\t *    a TR node then the data source for the whole row will be returned. If given as a\n\t\t *    TD/TH cell node then iCol will be automatically calculated and the data for the\n\t\t *    cell returned. If given as an integer, then this is treated as the aoData internal\n\t\t *    data index for the row (see fnGetPosition) and the data for that row used.\n\t\t *  @param {int} [col] Optional column index that you want the data of.\n\t\t *  @returns {array|object|string} If mRow is undefined, then the data for all rows is\n\t\t *    returned. If mRow is defined, just data for that row, and is iCol is\n\t\t *    defined, only data for the designated cell is returned.\n\t\t *  @dtopt API\n\t\t *  @deprecated Since v1.10\n\t\t *\n\t\t *  @example\n\t\t *    // Row data\n\t\t *    $(document).ready(function() {\n\t\t *      oTable = $('#example').dataTable();\n\t\t *\n\t\t *      oTable.$('tr').click( function () {\n\t\t *        var data = oTable.fnGetData( this );\n\t\t *        // ... do something with the array / object of data for the row\n\t\t *      } );\n\t\t *    } );\n\t\t *\n\t\t *  @example\n\t\t *    // Individual cell data\n\t\t *    $(document).ready(function() {\n\t\t *      oTable = $('#example').dataTable();\n\t\t *\n\t\t *      oTable.$('td').click( function () {\n\t\t *        var sData = oTable.fnGetData( this );\n\t\t *        alert( 'The cell clicked on had the value of '+sData );\n\t\t *      } );\n\t\t *    } );\n\t\t */\n\t\tthis.fnGetData = function( src, col )\n\t\t{\n\t\t\tvar api = this.api( true );\n\t\t\n\t\t\tif ( src !== undefined ) {\n\t\t\t\tvar type = src.nodeName ? src.nodeName.toLowerCase() : '';\n\t\t\n\t\t\t\treturn col !== undefined || type == 'td' || type == 'th' ?\n\t\t\t\t\tapi.cell( src, col ).data() :\n\t\t\t\t\tapi.row( src ).data() || null;\n\t\t\t}\n\t\t\n\t\t\treturn api.data().toArray();\n\t\t};\n\t\t\n\t\t\n\t\t/**\n\t\t * Get an array of the TR nodes that are used in the table's body. Note that you will\n\t\t * typically want to use the '$' API method in preference to this as it is more\n\t\t * flexible.\n\t\t *  @param {int} [iRow] Optional row index for the TR element you want\n\t\t *  @returns {array|node} If iRow is undefined, returns an array of all TR elements\n\t\t *    in the table's body, or iRow is defined, just the TR element requested.\n\t\t *  @dtopt API\n\t\t *  @deprecated Since v1.10\n\t\t *\n\t\t *  @example\n\t\t *    $(document).ready(function() {\n\t\t *      var oTable = $('#example').dataTable();\n\t\t *\n\t\t *      // Get the nodes from the table\n\t\t *      var nNodes = oTable.fnGetNodes( );\n\t\t *    } );\n\t\t */\n\t\tthis.fnGetNodes = function( iRow )\n\t\t{\n\t\t\tvar api = this.api( true );\n\t\t\n\t\t\treturn iRow !== undefined ?\n\t\t\t\tapi.row( iRow ).node() :\n\t\t\t\tapi.rows().nodes().flatten().toArray();\n\t\t};\n\t\t\n\t\t\n\t\t/**\n\t\t * Get the array indexes of a particular cell from it's DOM element\n\t\t * and column index including hidden columns\n\t\t *  @param {node} node this can either be a TR, TD or TH in the table's body\n\t\t *  @returns {int} If nNode is given as a TR, then a single index is returned, or\n\t\t *    if given as a cell, an array of [row index, column index (visible),\n\t\t *    column index (all)] is given.\n\t\t *  @dtopt API\n\t\t *  @deprecated Since v1.10\n\t\t *\n\t\t *  @example\n\t\t *    $(document).ready(function() {\n\t\t *      $('#example tbody td').click( function () {\n\t\t *        // Get the position of the current data from the node\n\t\t *        var aPos = oTable.fnGetPosition( this );\n\t\t *\n\t\t *        // Get the data array for this row\n\t\t *        var aData = oTable.fnGetData( aPos[0] );\n\t\t *\n\t\t *        // Update the data array and return the value\n\t\t *        aData[ aPos[1] ] = 'clicked';\n\t\t *        this.innerHTML = 'clicked';\n\t\t *      } );\n\t\t *\n\t\t *      // Init DataTables\n\t\t *      oTable = $('#example').dataTable();\n\t\t *    } );\n\t\t */\n\t\tthis.fnGetPosition = function( node )\n\t\t{\n\t\t\tvar api = this.api( true );\n\t\t\tvar nodeName = node.nodeName.toUpperCase();\n\t\t\n\t\t\tif ( nodeName == 'TR' ) {\n\t\t\t\treturn api.row( node ).index();\n\t\t\t}\n\t\t\telse if ( nodeName == 'TD' || nodeName == 'TH' ) {\n\t\t\t\tvar cell = api.cell( node ).index();\n\t\t\n\t\t\t\treturn [\n\t\t\t\t\tcell.row,\n\t\t\t\t\tcell.columnVisible,\n\t\t\t\t\tcell.column\n\t\t\t\t];\n\t\t\t}\n\t\t\treturn null;\n\t\t};\n\t\t\n\t\t\n\t\t/**\n\t\t * Check to see if a row is 'open' or not.\n\t\t *  @param {node} nTr the table row to check\n\t\t *  @returns {boolean} true if the row is currently open, false otherwise\n\t\t *  @dtopt API\n\t\t *  @deprecated Since v1.10\n\t\t *\n\t\t *  @example\n\t\t *    $(document).ready(function() {\n\t\t *      var oTable;\n\t\t *\n\t\t *      // 'open' an information row when a row is clicked on\n\t\t *      $('#example tbody tr').click( function () {\n\t\t *        if ( oTable.fnIsOpen(this) ) {\n\t\t *          oTable.fnClose( this );\n\t\t *        } else {\n\t\t *          oTable.fnOpen( this, \"Temporary row opened\", \"info_row\" );\n\t\t *        }\n\t\t *      } );\n\t\t *\n\t\t *      oTable = $('#example').dataTable();\n\t\t *    } );\n\t\t */\n\t\tthis.fnIsOpen = function( nTr )\n\t\t{\n\t\t\treturn this.api( true ).row( nTr ).child.isShown();\n\t\t};\n\t\t\n\t\t\n\t\t/**\n\t\t * This function will place a new row directly after a row which is currently\n\t\t * on display on the page, with the HTML contents that is passed into the\n\t\t * function. This can be used, for example, to ask for confirmation that a\n\t\t * particular record should be deleted.\n\t\t *  @param {node} nTr The table row to 'open'\n\t\t *  @param {string|node|jQuery} mHtml The HTML to put into the row\n\t\t *  @param {string} sClass Class to give the new TD cell\n\t\t *  @returns {node} The row opened. Note that if the table row passed in as the\n\t\t *    first parameter, is not found in the table, this method will silently\n\t\t *    return.\n\t\t *  @dtopt API\n\t\t *  @deprecated Since v1.10\n\t\t *\n\t\t *  @example\n\t\t *    $(document).ready(function() {\n\t\t *      var oTable;\n\t\t *\n\t\t *      // 'open' an information row when a row is clicked on\n\t\t *      $('#example tbody tr').click( function () {\n\t\t *        if ( oTable.fnIsOpen(this) ) {\n\t\t *          oTable.fnClose( this );\n\t\t *        } else {\n\t\t *          oTable.fnOpen( this, \"Temporary row opened\", \"info_row\" );\n\t\t *        }\n\t\t *      } );\n\t\t *\n\t\t *      oTable = $('#example').dataTable();\n\t\t *    } );\n\t\t */\n\t\tthis.fnOpen = function( nTr, mHtml, sClass )\n\t\t{\n\t\t\treturn this.api( true )\n\t\t\t\t.row( nTr )\n\t\t\t\t.child( mHtml, sClass )\n\t\t\t\t.show()\n\t\t\t\t.child()[0];\n\t\t};\n\t\t\n\t\t\n\t\t/**\n\t\t * Change the pagination - provides the internal logic for pagination in a simple API\n\t\t * function. With this function you can have a DataTables table go to the next,\n\t\t * previous, first or last pages.\n\t\t *  @param {string|int} mAction Paging action to take: \"first\", \"previous\", \"next\" or \"last\"\n\t\t *    or page number to jump to (integer), note that page 0 is the first page.\n\t\t *  @param {bool} [bRedraw=true] Redraw the table or not\n\t\t *  @dtopt API\n\t\t *  @deprecated Since v1.10\n\t\t *\n\t\t *  @example\n\t\t *    $(document).ready(function() {\n\t\t *      var oTable = $('#example').dataTable();\n\t\t *      oTable.fnPageChange( 'next' );\n\t\t *    } );\n\t\t */\n\t\tthis.fnPageChange = function ( mAction, bRedraw )\n\t\t{\n\t\t\tvar api = this.api( true ).page( mAction );\n\t\t\n\t\t\tif ( bRedraw === undefined || bRedraw ) {\n\t\t\t\tapi.draw(false);\n\t\t\t}\n\t\t};\n\t\t\n\t\t\n\t\t/**\n\t\t * Show a particular column\n\t\t *  @param {int} iCol The column whose display should be changed\n\t\t *  @param {bool} bShow Show (true) or hide (false) the column\n\t\t *  @param {bool} [bRedraw=true] Redraw the table or not\n\t\t *  @dtopt API\n\t\t *  @deprecated Since v1.10\n\t\t *\n\t\t *  @example\n\t\t *    $(document).ready(function() {\n\t\t *      var oTable = $('#example').dataTable();\n\t\t *\n\t\t *      // Hide the second column after initialisation\n\t\t *      oTable.fnSetColumnVis( 1, false );\n\t\t *    } );\n\t\t */\n\t\tthis.fnSetColumnVis = function ( iCol, bShow, bRedraw )\n\t\t{\n\t\t\tvar api = this.api( true ).column( iCol ).visible( bShow );\n\t\t\n\t\t\tif ( bRedraw === undefined || bRedraw ) {\n\t\t\t\tapi.columns.adjust().draw();\n\t\t\t}\n\t\t};\n\t\t\n\t\t\n\t\t/**\n\t\t * Get the settings for a particular table for external manipulation\n\t\t *  @returns {object} DataTables settings object. See\n\t\t *    {@link DataTable.models.oSettings}\n\t\t *  @dtopt API\n\t\t *  @deprecated Since v1.10\n\t\t *\n\t\t *  @example\n\t\t *    $(document).ready(function() {\n\t\t *      var oTable = $('#example').dataTable();\n\t\t *      var oSettings = oTable.fnSettings();\n\t\t *\n\t\t *      // Show an example parameter from the settings\n\t\t *      alert( oSettings._iDisplayStart );\n\t\t *    } );\n\t\t */\n\t\tthis.fnSettings = function()\n\t\t{\n\t\t\treturn _fnSettingsFromNode( this[_ext.iApiIndex] );\n\t\t};\n\t\t\n\t\t\n\t\t/**\n\t\t * Sort the table by a particular column\n\t\t *  @param {int} iCol the data index to sort on. Note that this will not match the\n\t\t *    'display index' if you have hidden data entries\n\t\t *  @dtopt API\n\t\t *  @deprecated Since v1.10\n\t\t *\n\t\t *  @example\n\t\t *    $(document).ready(function() {\n\t\t *      var oTable = $('#example').dataTable();\n\t\t *\n\t\t *      // Sort immediately with columns 0 and 1\n\t\t *      oTable.fnSort( [ [0,'asc'], [1,'asc'] ] );\n\t\t *    } );\n\t\t */\n\t\tthis.fnSort = function( aaSort )\n\t\t{\n\t\t\tthis.api( true ).order( aaSort ).draw();\n\t\t};\n\t\t\n\t\t\n\t\t/**\n\t\t * Attach a sort listener to an element for a given column\n\t\t *  @param {node} nNode the element to attach the sort listener to\n\t\t *  @param {int} iColumn the column that a click on this node will sort on\n\t\t *  @param {function} [fnCallback] callback function when sort is run\n\t\t *  @dtopt API\n\t\t *  @deprecated Since v1.10\n\t\t *\n\t\t *  @example\n\t\t *    $(document).ready(function() {\n\t\t *      var oTable = $('#example').dataTable();\n\t\t *\n\t\t *      // Sort on column 1, when 'sorter' is clicked on\n\t\t *      oTable.fnSortListener( document.getElementById('sorter'), 1 );\n\t\t *    } );\n\t\t */\n\t\tthis.fnSortListener = function( nNode, iColumn, fnCallback )\n\t\t{\n\t\t\tthis.api( true ).order.listener( nNode, iColumn, fnCallback );\n\t\t};\n\t\t\n\t\t\n\t\t/**\n\t\t * Update a table cell or row - this method will accept either a single value to\n\t\t * update the cell with, an array of values with one element for each column or\n\t\t * an object in the same format as the original data source. The function is\n\t\t * self-referencing in order to make the multi column updates easier.\n\t\t *  @param {object|array|string} mData Data to update the cell/row with\n\t\t *  @param {node|int} mRow TR element you want to update or the aoData index\n\t\t *  @param {int} [iColumn] The column to update, give as null or undefined to\n\t\t *    update a whole row.\n\t\t *  @param {bool} [bRedraw=true] Redraw the table or not\n\t\t *  @param {bool} [bAction=true] Perform pre-draw actions or not\n\t\t *  @returns {int} 0 on success, 1 on error\n\t\t *  @dtopt API\n\t\t *  @deprecated Since v1.10\n\t\t *\n\t\t *  @example\n\t\t *    $(document).ready(function() {\n\t\t *      var oTable = $('#example').dataTable();\n\t\t *      oTable.fnUpdate( 'Example update', 0, 0 ); // Single cell\n\t\t *      oTable.fnUpdate( ['a', 'b', 'c', 'd', 'e'], $('tbody tr')[0] ); // Row\n\t\t *    } );\n\t\t */\n\t\tthis.fnUpdate = function( mData, mRow, iColumn, bRedraw, bAction )\n\t\t{\n\t\t\tvar api = this.api( true );\n\t\t\n\t\t\tif ( iColumn === undefined || iColumn === null ) {\n\t\t\t\tapi.row( mRow ).data( mData );\n\t\t\t}\n\t\t\telse {\n\t\t\t\tapi.cell( mRow, iColumn ).data( mData );\n\t\t\t}\n\t\t\n\t\t\tif ( bAction === undefined || bAction ) {\n\t\t\t\tapi.columns.adjust();\n\t\t\t}\n\t\t\n\t\t\tif ( bRedraw === undefined || bRedraw ) {\n\t\t\t\tapi.draw();\n\t\t\t}\n\t\t\treturn 0;\n\t\t};\n\t\t\n\t\t\n\t\t/**\n\t\t * Provide a common method for plug-ins to check the version of DataTables being used, in order\n\t\t * to ensure compatibility.\n\t\t *  @param {string} sVersion Version string to check for, in the format \"X.Y.Z\". Note that the\n\t\t *    formats \"X\" and \"X.Y\" are also acceptable.\n\t\t *  @returns {boolean} true if this version of DataTables is greater or equal to the required\n\t\t *    version, or false if this version of DataTales is not suitable\n\t\t *  @method\n\t\t *  @dtopt API\n\t\t *  @deprecated Since v1.10\n\t\t *\n\t\t *  @example\n\t\t *    $(document).ready(function() {\n\t\t *      var oTable = $('#example').dataTable();\n\t\t *      alert( oTable.fnVersionCheck( '1.9.0' ) );\n\t\t *    } );\n\t\t */\n\t\tthis.fnVersionCheck = _ext.fnVersionCheck;\n\t\t\n\n\t\tvar _that = this;\n\t\tvar emptyInit = options === undefined;\n\t\tvar len = this.length;\n\n\t\tif ( emptyInit ) {\n\t\t\toptions = {};\n\t\t}\n\n\t\tthis.oApi = this.internal = _ext.internal;\n\n\t\t// Extend with old style plug-in API methods\n\t\tfor ( var fn in DataTable.ext.internal ) {\n\t\t\tif ( fn ) {\n\t\t\t\tthis[fn] = _fnExternApiFunc(fn);\n\t\t\t}\n\t\t}\n\n\t\tthis.each(function() {\n\t\t\t// For each initialisation we want to give it a clean initialisation\n\t\t\t// object that can be bashed around\n\t\t\tvar o = {};\n\t\t\tvar oInit = len > 1 ? // optimisation for single table case\n\t\t\t\t_fnExtend( o, options, true ) :\n\t\t\t\toptions;\n\n\t\t\t/*global oInit,_that,emptyInit*/\n\t\t\tvar i=0, iLen, j, jLen, k, kLen;\n\t\t\tvar sId = this.getAttribute( 'id' );\n\t\t\tvar bInitHandedOff = false;\n\t\t\tvar defaults = DataTable.defaults;\n\t\t\tvar $this = $(this);\n\t\t\t\n\t\t\t\n\t\t\t/* Sanity check */\n\t\t\tif ( this.nodeName.toLowerCase() != 'table' )\n\t\t\t{\n\t\t\t\t_fnLog( null, 0, 'Non-table node initialisation ('+this.nodeName+')', 2 );\n\t\t\t\treturn;\n\t\t\t}\n\t\t\t\n\t\t\t/* Backwards compatibility for the defaults */\n\t\t\t_fnCompatOpts( defaults );\n\t\t\t_fnCompatCols( defaults.column );\n\t\t\t\n\t\t\t/* Convert the camel-case defaults to Hungarian */\n\t\t\t_fnCamelToHungarian( defaults, defaults, true );\n\t\t\t_fnCamelToHungarian( defaults.column, defaults.column, true );\n\t\t\t\n\t\t\t/* Setting up the initialisation object */\n\t\t\t_fnCamelToHungarian( defaults, $.extend( oInit, $this.data() ) );\n\t\t\t\n\t\t\t\n\t\t\t\n\t\t\t/* Check to see if we are re-initialising a table */\n\t\t\tvar allSettings = DataTable.settings;\n\t\t\tfor ( i=0, iLen=allSettings.length ; i<iLen ; i++ )\n\t\t\t{\n\t\t\t\tvar s = allSettings[i];\n\t\t\t\n\t\t\t\t/* Base check on table node */\n\t\t\t\tif ( s.nTable == this || s.nTHead.parentNode == this || (s.nTFoot && s.nTFoot.parentNode == this) )\n\t\t\t\t{\n\t\t\t\t\tvar bRetrieve = oInit.bRetrieve !== undefined ? oInit.bRetrieve : defaults.bRetrieve;\n\t\t\t\t\tvar bDestroy = oInit.bDestroy !== undefined ? oInit.bDestroy : defaults.bDestroy;\n\t\t\t\n\t\t\t\t\tif ( emptyInit || bRetrieve )\n\t\t\t\t\t{\n\t\t\t\t\t\treturn s.oInstance;\n\t\t\t\t\t}\n\t\t\t\t\telse if ( bDestroy )\n\t\t\t\t\t{\n\t\t\t\t\t\ts.oInstance.fnDestroy();\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\t_fnLog( s, 0, 'Cannot reinitialise DataTable', 3 );\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\n\t\t\t\t/* If the element we are initialising has the same ID as a table which was previously\n\t\t\t\t * initialised, but the table nodes don't match (from before) then we destroy the old\n\t\t\t\t * instance by simply deleting it. This is under the assumption that the table has been\n\t\t\t\t * destroyed by other methods. Anyone using non-id selectors will need to do this manually\n\t\t\t\t */\n\t\t\t\tif ( s.sTableId == this.id )\n\t\t\t\t{\n\t\t\t\t\tallSettings.splice( i, 1 );\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t\t\n\t\t\t/* Ensure the table has an ID - required for accessibility */\n\t\t\tif ( sId === null || sId === \"\" )\n\t\t\t{\n\t\t\t\tsId = \"DataTables_Table_\"+(DataTable.ext._unique++);\n\t\t\t\tthis.id = sId;\n\t\t\t}\n\t\t\t\n\t\t\t/* Create the settings object for this table and set some of the default parameters */\n\t\t\tvar oSettings = $.extend( true, {}, DataTable.models.oSettings, {\n\t\t\t\t\"sDestroyWidth\": $this[0].style.width,\n\t\t\t\t\"sInstance\":     sId,\n\t\t\t\t\"sTableId\":      sId\n\t\t\t} );\n\t\t\toSettings.nTable = this;\n\t\t\toSettings.oApi   = _that.internal;\n\t\t\toSettings.oInit  = oInit;\n\t\t\t\n\t\t\tallSettings.push( oSettings );\n\t\t\t\n\t\t\t// Need to add the instance after the instance after the settings object has been added\n\t\t\t// to the settings array, so we can self reference the table instance if more than one\n\t\t\toSettings.oInstance = (_that.length===1) ? _that : $this.dataTable();\n\t\t\t\n\t\t\t// Backwards compatibility, before we apply all the defaults\n\t\t\t_fnCompatOpts( oInit );\n\t\t\t\n\t\t\tif ( oInit.oLanguage )\n\t\t\t{\n\t\t\t\t_fnLanguageCompat( oInit.oLanguage );\n\t\t\t}\n\t\t\t\n\t\t\t// If the length menu is given, but the init display length is not, use the length menu\n\t\t\tif ( oInit.aLengthMenu && ! oInit.iDisplayLength )\n\t\t\t{\n\t\t\t\toInit.iDisplayLength = $.isArray( oInit.aLengthMenu[0] ) ?\n\t\t\t\t\toInit.aLengthMenu[0][0] : oInit.aLengthMenu[0];\n\t\t\t}\n\t\t\t\n\t\t\t// Apply the defaults and init options to make a single init object will all\n\t\t\t// options defined from defaults and instance options.\n\t\t\toInit = _fnExtend( $.extend( true, {}, defaults ), oInit );\n\t\t\t\n\t\t\t\n\t\t\t// Map the initialisation options onto the settings object\n\t\t\t_fnMap( oSettings.oFeatures, oInit, [\n\t\t\t\t\"bPaginate\",\n\t\t\t\t\"bLengthChange\",\n\t\t\t\t\"bFilter\",\n\t\t\t\t\"bSort\",\n\t\t\t\t\"bSortMulti\",\n\t\t\t\t\"bInfo\",\n\t\t\t\t\"bProcessing\",\n\t\t\t\t\"bAutoWidth\",\n\t\t\t\t\"bSortClasses\",\n\t\t\t\t\"bServerSide\",\n\t\t\t\t\"bDeferRender\"\n\t\t\t] );\n\t\t\t_fnMap( oSettings, oInit, [\n\t\t\t\t\"asStripeClasses\",\n\t\t\t\t\"ajax\",\n\t\t\t\t\"fnServerData\",\n\t\t\t\t\"fnFormatNumber\",\n\t\t\t\t\"sServerMethod\",\n\t\t\t\t\"aaSorting\",\n\t\t\t\t\"aaSortingFixed\",\n\t\t\t\t\"aLengthMenu\",\n\t\t\t\t\"sPaginationType\",\n\t\t\t\t\"sAjaxSource\",\n\t\t\t\t\"sAjaxDataProp\",\n\t\t\t\t\"iStateDuration\",\n\t\t\t\t\"sDom\",\n\t\t\t\t\"bSortCellsTop\",\n\t\t\t\t\"iTabIndex\",\n\t\t\t\t\"fnStateLoadCallback\",\n\t\t\t\t\"fnStateSaveCallback\",\n\t\t\t\t\"renderer\",\n\t\t\t\t\"searchDelay\",\n\t\t\t\t\"rowId\",\n\t\t\t\t[ \"iCookieDuration\", \"iStateDuration\" ], // backwards compat\n\t\t\t\t[ \"oSearch\", \"oPreviousSearch\" ],\n\t\t\t\t[ \"aoSearchCols\", \"aoPreSearchCols\" ],\n\t\t\t\t[ \"iDisplayLength\", \"_iDisplayLength\" ],\n\t\t\t\t[ \"bJQueryUI\", \"bJUI\" ]\n\t\t\t] );\n\t\t\t_fnMap( oSettings.oScroll, oInit, [\n\t\t\t\t[ \"sScrollX\", \"sX\" ],\n\t\t\t\t[ \"sScrollXInner\", \"sXInner\" ],\n\t\t\t\t[ \"sScrollY\", \"sY\" ],\n\t\t\t\t[ \"bScrollCollapse\", \"bCollapse\" ]\n\t\t\t] );\n\t\t\t_fnMap( oSettings.oLanguage, oInit, \"fnInfoCallback\" );\n\t\t\t\n\t\t\t/* Callback functions which are array driven */\n\t\t\t_fnCallbackReg( oSettings, 'aoDrawCallback',       oInit.fnDrawCallback,      'user' );\n\t\t\t_fnCallbackReg( oSettings, 'aoServerParams',       oInit.fnServerParams,      'user' );\n\t\t\t_fnCallbackReg( oSettings, 'aoStateSaveParams',    oInit.fnStateSaveParams,   'user' );\n\t\t\t_fnCallbackReg( oSettings, 'aoStateLoadParams',    oInit.fnStateLoadParams,   'user' );\n\t\t\t_fnCallbackReg( oSettings, 'aoStateLoaded',        oInit.fnStateLoaded,       'user' );\n\t\t\t_fnCallbackReg( oSettings, 'aoRowCallback',        oInit.fnRowCallback,       'user' );\n\t\t\t_fnCallbackReg( oSettings, 'aoRowCreatedCallback', oInit.fnCreatedRow,        'user' );\n\t\t\t_fnCallbackReg( oSettings, 'aoHeaderCallback',     oInit.fnHeaderCallback,    'user' );\n\t\t\t_fnCallbackReg( oSettings, 'aoFooterCallback',     oInit.fnFooterCallback,    'user' );\n\t\t\t_fnCallbackReg( oSettings, 'aoInitComplete',       oInit.fnInitComplete,      'user' );\n\t\t\t_fnCallbackReg( oSettings, 'aoPreDrawCallback',    oInit.fnPreDrawCallback,   'user' );\n\t\t\t\n\t\t\toSettings.rowIdFn = _fnGetObjectDataFn( oInit.rowId );\n\t\t\t\n\t\t\t/* Browser support detection */\n\t\t\t_fnBrowserDetect( oSettings );\n\t\t\t\n\t\t\tvar oClasses = oSettings.oClasses;\n\t\t\t\n\t\t\t// @todo Remove in 1.11\n\t\t\tif ( oInit.bJQueryUI )\n\t\t\t{\n\t\t\t\t/* Use the JUI classes object for display. You could clone the oStdClasses object if\n\t\t\t\t * you want to have multiple tables with multiple independent classes\n\t\t\t\t */\n\t\t\t\t$.extend( oClasses, DataTable.ext.oJUIClasses, oInit.oClasses );\n\t\t\t\n\t\t\t\tif ( oInit.sDom === defaults.sDom && defaults.sDom === \"lfrtip\" )\n\t\t\t\t{\n\t\t\t\t\t/* Set the DOM to use a layout suitable for jQuery UI's theming */\n\t\t\t\t\toSettings.sDom = '<\"H\"lfr>t<\"F\"ip>';\n\t\t\t\t}\n\t\t\t\n\t\t\t\tif ( ! oSettings.renderer ) {\n\t\t\t\t\toSettings.renderer = 'jqueryui';\n\t\t\t\t}\n\t\t\t\telse if ( $.isPlainObject( oSettings.renderer ) && ! oSettings.renderer.header ) {\n\t\t\t\t\toSettings.renderer.header = 'jqueryui';\n\t\t\t\t}\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\t$.extend( oClasses, DataTable.ext.classes, oInit.oClasses );\n\t\t\t}\n\t\t\t$this.addClass( oClasses.sTable );\n\t\t\t\n\t\t\t\n\t\t\tif ( oSettings.iInitDisplayStart === undefined )\n\t\t\t{\n\t\t\t\t/* Display start point, taking into account the save saving */\n\t\t\t\toSettings.iInitDisplayStart = oInit.iDisplayStart;\n\t\t\t\toSettings._iDisplayStart = oInit.iDisplayStart;\n\t\t\t}\n\t\t\t\n\t\t\tif ( oInit.iDeferLoading !== null )\n\t\t\t{\n\t\t\t\toSettings.bDeferLoading = true;\n\t\t\t\tvar tmp = $.isArray( oInit.iDeferLoading );\n\t\t\t\toSettings._iRecordsDisplay = tmp ? oInit.iDeferLoading[0] : oInit.iDeferLoading;\n\t\t\t\toSettings._iRecordsTotal = tmp ? oInit.iDeferLoading[1] : oInit.iDeferLoading;\n\t\t\t}\n\t\t\t\n\t\t\t/* Language definitions */\n\t\t\tvar oLanguage = oSettings.oLanguage;\n\t\t\t$.extend( true, oLanguage, oInit.oLanguage );\n\t\t\t\n\t\t\tif ( oLanguage.sUrl !== \"\" )\n\t\t\t{\n\t\t\t\t/* Get the language definitions from a file - because this Ajax call makes the language\n\t\t\t\t * get async to the remainder of this function we use bInitHandedOff to indicate that\n\t\t\t\t * _fnInitialise will be fired by the returned Ajax handler, rather than the constructor\n\t\t\t\t */\n\t\t\t\t$.ajax( {\n\t\t\t\t\tdataType: 'json',\n\t\t\t\t\turl: oLanguage.sUrl,\n\t\t\t\t\tsuccess: function ( json ) {\n\t\t\t\t\t\t_fnLanguageCompat( json );\n\t\t\t\t\t\t_fnCamelToHungarian( defaults.oLanguage, json );\n\t\t\t\t\t\t$.extend( true, oLanguage, json );\n\t\t\t\t\t\t_fnInitialise( oSettings );\n\t\t\t\t\t},\n\t\t\t\t\terror: function () {\n\t\t\t\t\t\t// Error occurred loading language file, continue on as best we can\n\t\t\t\t\t\t_fnInitialise( oSettings );\n\t\t\t\t\t}\n\t\t\t\t} );\n\t\t\t\tbInitHandedOff = true;\n\t\t\t}\n\t\t\t\n\t\t\t/*\n\t\t\t * Stripes\n\t\t\t */\n\t\t\tif ( oInit.asStripeClasses === null )\n\t\t\t{\n\t\t\t\toSettings.asStripeClasses =[\n\t\t\t\t\toClasses.sStripeOdd,\n\t\t\t\t\toClasses.sStripeEven\n\t\t\t\t];\n\t\t\t}\n\t\t\t\n\t\t\t/* Remove row stripe classes if they are already on the table row */\n\t\t\tvar stripeClasses = oSettings.asStripeClasses;\n\t\t\tvar rowOne = $this.children('tbody').find('tr').eq(0);\n\t\t\tif ( $.inArray( true, $.map( stripeClasses, function(el, i) {\n\t\t\t\treturn rowOne.hasClass(el);\n\t\t\t} ) ) !== -1 ) {\n\t\t\t\t$('tbody tr', this).removeClass( stripeClasses.join(' ') );\n\t\t\t\toSettings.asDestroyStripes = stripeClasses.slice();\n\t\t\t}\n\t\t\t\n\t\t\t/*\n\t\t\t * Columns\n\t\t\t * See if we should load columns automatically or use defined ones\n\t\t\t */\n\t\t\tvar anThs = [];\n\t\t\tvar aoColumnsInit;\n\t\t\tvar nThead = this.getElementsByTagName('thead');\n\t\t\tif ( nThead.length !== 0 )\n\t\t\t{\n\t\t\t\t_fnDetectHeader( oSettings.aoHeader, nThead[0] );\n\t\t\t\tanThs = _fnGetUniqueThs( oSettings );\n\t\t\t}\n\t\t\t\n\t\t\t/* If not given a column array, generate one with nulls */\n\t\t\tif ( oInit.aoColumns === null )\n\t\t\t{\n\t\t\t\taoColumnsInit = [];\n\t\t\t\tfor ( i=0, iLen=anThs.length ; i<iLen ; i++ )\n\t\t\t\t{\n\t\t\t\t\taoColumnsInit.push( null );\n\t\t\t\t}\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\taoColumnsInit = oInit.aoColumns;\n\t\t\t}\n\t\t\t\n\t\t\t/* Add the columns */\n\t\t\tfor ( i=0, iLen=aoColumnsInit.length ; i<iLen ; i++ )\n\t\t\t{\n\t\t\t\t_fnAddColumn( oSettings, anThs ? anThs[i] : null );\n\t\t\t}\n\t\t\t\n\t\t\t/* Apply the column definitions */\n\t\t\t_fnApplyColumnDefs( oSettings, oInit.aoColumnDefs, aoColumnsInit, function (iCol, oDef) {\n\t\t\t\t_fnColumnOptions( oSettings, iCol, oDef );\n\t\t\t} );\n\t\t\t\n\t\t\t/* HTML5 attribute detection - build an mData object automatically if the\n\t\t\t * attributes are found\n\t\t\t */\n\t\t\tif ( rowOne.length ) {\n\t\t\t\tvar a = function ( cell, name ) {\n\t\t\t\t\treturn cell.getAttribute( 'data-'+name ) !== null ? name : null;\n\t\t\t\t};\n\t\t\t\n\t\t\t\t$( rowOne[0] ).children('th, td').each( function (i, cell) {\n\t\t\t\t\tvar col = oSettings.aoColumns[i];\n\t\t\t\n\t\t\t\t\tif ( col.mData === i ) {\n\t\t\t\t\t\tvar sort = a( cell, 'sort' ) || a( cell, 'order' );\n\t\t\t\t\t\tvar filter = a( cell, 'filter' ) || a( cell, 'search' );\n\t\t\t\n\t\t\t\t\t\tif ( sort !== null || filter !== null ) {\n\t\t\t\t\t\t\tcol.mData = {\n\t\t\t\t\t\t\t\t_:      i+'.display',\n\t\t\t\t\t\t\t\tsort:   sort !== null   ? i+'.@data-'+sort   : undefined,\n\t\t\t\t\t\t\t\ttype:   sort !== null   ? i+'.@data-'+sort   : undefined,\n\t\t\t\t\t\t\t\tfilter: filter !== null ? i+'.@data-'+filter : undefined\n\t\t\t\t\t\t\t};\n\t\t\t\n\t\t\t\t\t\t\t_fnColumnOptions( oSettings, i );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t} );\n\t\t\t}\n\t\t\t\n\t\t\tvar features = oSettings.oFeatures;\n\t\t\t\n\t\t\t/* Must be done after everything which can be overridden by the state saving! */\n\t\t\tif ( oInit.bStateSave )\n\t\t\t{\n\t\t\t\tfeatures.bStateSave = true;\n\t\t\t\t_fnLoadState( oSettings, oInit );\n\t\t\t\t_fnCallbackReg( oSettings, 'aoDrawCallback', _fnSaveState, 'state_save' );\n\t\t\t}\n\t\t\t\n\t\t\t\n\t\t\t/*\n\t\t\t * Sorting\n\t\t\t * @todo For modularisation (1.11) this needs to do into a sort start up handler\n\t\t\t */\n\t\t\t\n\t\t\t// If aaSorting is not defined, then we use the first indicator in asSorting\n\t\t\t// in case that has been altered, so the default sort reflects that option\n\t\t\tif ( oInit.aaSorting === undefined )\n\t\t\t{\n\t\t\t\tvar sorting = oSettings.aaSorting;\n\t\t\t\tfor ( i=0, iLen=sorting.length ; i<iLen ; i++ )\n\t\t\t\t{\n\t\t\t\t\tsorting[i][1] = oSettings.aoColumns[ i ].asSorting[0];\n\t\t\t\t}\n\t\t\t}\n\t\t\t\n\t\t\t/* Do a first pass on the sorting classes (allows any size changes to be taken into\n\t\t\t * account, and also will apply sorting disabled classes if disabled\n\t\t\t */\n\t\t\t_fnSortingClasses( oSettings );\n\t\t\t\n\t\t\tif ( features.bSort )\n\t\t\t{\n\t\t\t\t_fnCallbackReg( oSettings, 'aoDrawCallback', function () {\n\t\t\t\t\tif ( oSettings.bSorted ) {\n\t\t\t\t\t\tvar aSort = _fnSortFlatten( oSettings );\n\t\t\t\t\t\tvar sortedColumns = {};\n\t\t\t\n\t\t\t\t\t\t$.each( aSort, function (i, val) {\n\t\t\t\t\t\t\tsortedColumns[ val.src ] = val.dir;\n\t\t\t\t\t\t} );\n\t\t\t\n\t\t\t\t\t\t_fnCallbackFire( oSettings, null, 'order', [oSettings, aSort, sortedColumns] );\n\t\t\t\t\t\t_fnSortAria( oSettings );\n\t\t\t\t\t}\n\t\t\t\t} );\n\t\t\t}\n\t\t\t\n\t\t\t_fnCallbackReg( oSettings, 'aoDrawCallback', function () {\n\t\t\t\tif ( oSettings.bSorted || _fnDataSource( oSettings ) === 'ssp' || features.bDeferRender ) {\n\t\t\t\t\t_fnSortingClasses( oSettings );\n\t\t\t\t}\n\t\t\t}, 'sc' );\n\t\t\t\n\t\t\t\n\t\t\t/*\n\t\t\t * Final init\n\t\t\t * Cache the header, body and footer as required, creating them if needed\n\t\t\t */\n\t\t\t\n\t\t\t// Work around for Webkit bug 83867 - store the caption-side before removing from doc\n\t\t\tvar captions = $this.children('caption').each( function () {\n\t\t\t\tthis._captionSide = $this.css('caption-side');\n\t\t\t} );\n\t\t\t\n\t\t\tvar thead = $this.children('thead');\n\t\t\tif ( thead.length === 0 )\n\t\t\t{\n\t\t\t\tthead = $('<thead/>').appendTo(this);\n\t\t\t}\n\t\t\toSettings.nTHead = thead[0];\n\t\t\t\n\t\t\tvar tbody = $this.children('tbody');\n\t\t\tif ( tbody.length === 0 )\n\t\t\t{\n\t\t\t\ttbody = $('<tbody/>').appendTo(this);\n\t\t\t}\n\t\t\toSettings.nTBody = tbody[0];\n\t\t\t\n\t\t\tvar tfoot = $this.children('tfoot');\n\t\t\tif ( tfoot.length === 0 && captions.length > 0 && (oSettings.oScroll.sX !== \"\" || oSettings.oScroll.sY !== \"\") )\n\t\t\t{\n\t\t\t\t// If we are a scrolling table, and no footer has been given, then we need to create\n\t\t\t\t// a tfoot element for the caption element to be appended to\n\t\t\t\ttfoot = $('<tfoot/>').appendTo(this);\n\t\t\t}\n\t\t\t\n\t\t\tif ( tfoot.length === 0 || tfoot.children().length === 0 ) {\n\t\t\t\t$this.addClass( oClasses.sNoFooter );\n\t\t\t}\n\t\t\telse if ( tfoot.length > 0 ) {\n\t\t\t\toSettings.nTFoot = tfoot[0];\n\t\t\t\t_fnDetectHeader( oSettings.aoFooter, oSettings.nTFoot );\n\t\t\t}\n\t\t\t\n\t\t\t/* Check if there is data passing into the constructor */\n\t\t\tif ( oInit.aaData )\n\t\t\t{\n\t\t\t\tfor ( i=0 ; i<oInit.aaData.length ; i++ )\n\t\t\t\t{\n\t\t\t\t\t_fnAddData( oSettings, oInit.aaData[ i ] );\n\t\t\t\t}\n\t\t\t}\n\t\t\telse if ( oSettings.bDeferLoading || _fnDataSource( oSettings ) == 'dom' )\n\t\t\t{\n\t\t\t\t/* Grab the data from the page - only do this when deferred loading or no Ajax\n\t\t\t\t * source since there is no point in reading the DOM data if we are then going\n\t\t\t\t * to replace it with Ajax data\n\t\t\t\t */\n\t\t\t\t_fnAddTr( oSettings, $(oSettings.nTBody).children('tr') );\n\t\t\t}\n\t\t\t\n\t\t\t/* Copy the data index array */\n\t\t\toSettings.aiDisplay = oSettings.aiDisplayMaster.slice();\n\t\t\t\n\t\t\t/* Initialisation complete - table can be drawn */\n\t\t\toSettings.bInitialised = true;\n\t\t\t\n\t\t\t/* Check if we need to initialise the table (it might not have been handed off to the\n\t\t\t * language processor)\n\t\t\t */\n\t\t\tif ( bInitHandedOff === false )\n\t\t\t{\n\t\t\t\t_fnInitialise( oSettings );\n\t\t\t}\n\t\t} );\n\t\t_that = null;\n\t\treturn this;\n\t};\n\n\t\n\t/*\n\t * It is useful to have variables which are scoped locally so only the\n\t * DataTables functions can access them and they don't leak into global space.\n\t * At the same time these functions are often useful over multiple files in the\n\t * core and API, so we list, or at least document, all variables which are used\n\t * by DataTables as private variables here. This also ensures that there is no\n\t * clashing of variable names and that they can easily referenced for reuse.\n\t */\n\t\n\t\n\t// Defined else where\n\t//  _selector_run\n\t//  _selector_opts\n\t//  _selector_first\n\t//  _selector_row_indexes\n\t\n\tvar _ext; // DataTable.ext\n\tvar _Api; // DataTable.Api\n\tvar _api_register; // DataTable.Api.register\n\tvar _api_registerPlural; // DataTable.Api.registerPlural\n\t\n\tvar _re_dic = {};\n\tvar _re_new_lines = /[\\r\\n]/g;\n\tvar _re_html = /<.*?>/g;\n\tvar _re_date_start = /^[\\w\\+\\-]/;\n\tvar _re_date_end = /[\\w\\+\\-]$/;\n\t\n\t// Escape regular expression special characters\n\tvar _re_escape_regex = new RegExp( '(\\\\' + [ '/', '.', '*', '+', '?', '|', '(', ')', '[', ']', '{', '}', '\\\\', '$', '^', '-' ].join('|\\\\') + ')', 'g' );\n\t\n\t// http://en.wikipedia.org/wiki/Foreign_exchange_market\n\t// - \\u20BD - Russian ruble.\n\t// - \\u20a9 - South Korean Won\n\t// - \\u20BA - Turkish Lira\n\t// - \\u20B9 - Indian Rupee\n\t// - R - Brazil (R$) and South Africa\n\t// - fr - Swiss Franc\n\t// - kr - Swedish krona, Norwegian krone and Danish krone\n\t// - \\u2009 is thin space and \\u202F is narrow no-break space, both used in many\n\t//   standards as thousands separators.\n\tvar _re_formatted_numeric = /[',$£€¥%\\u2009\\u202F\\u20BD\\u20a9\\u20BArfk]/gi;\n\t\n\t\n\tvar _empty = function ( d ) {\n\t\treturn !d || d === true || d === '-' ? true : false;\n\t};\n\t\n\t\n\tvar _intVal = function ( s ) {\n\t\tvar integer = parseInt( s, 10 );\n\t\treturn !isNaN(integer) && isFinite(s) ? integer : null;\n\t};\n\t\n\t// Convert from a formatted number with characters other than `.` as the\n\t// decimal place, to a Javascript number\n\tvar _numToDecimal = function ( num, decimalPoint ) {\n\t\t// Cache created regular expressions for speed as this function is called often\n\t\tif ( ! _re_dic[ decimalPoint ] ) {\n\t\t\t_re_dic[ decimalPoint ] = new RegExp( _fnEscapeRegex( decimalPoint ), 'g' );\n\t\t}\n\t\treturn typeof num === 'string' && decimalPoint !== '.' ?\n\t\t\tnum.replace( /\\./g, '' ).replace( _re_dic[ decimalPoint ], '.' ) :\n\t\t\tnum;\n\t};\n\t\n\t\n\tvar _isNumber = function ( d, decimalPoint, formatted ) {\n\t\tvar strType = typeof d === 'string';\n\t\n\t\t// If empty return immediately so there must be a number if it is a\n\t\t// formatted string (this stops the string \"k\", or \"kr\", etc being detected\n\t\t// as a formatted number for currency\n\t\tif ( _empty( d ) ) {\n\t\t\treturn true;\n\t\t}\n\t\n\t\tif ( decimalPoint && strType ) {\n\t\t\td = _numToDecimal( d, decimalPoint );\n\t\t}\n\t\n\t\tif ( formatted && strType ) {\n\t\t\td = d.replace( _re_formatted_numeric, '' );\n\t\t}\n\t\n\t\treturn !isNaN( parseFloat(d) ) && isFinite( d );\n\t};\n\t\n\t\n\t// A string without HTML in it can be considered to be HTML still\n\tvar _isHtml = function ( d ) {\n\t\treturn _empty( d ) || typeof d === 'string';\n\t};\n\t\n\t\n\tvar _htmlNumeric = function ( d, decimalPoint, formatted ) {\n\t\tif ( _empty( d ) ) {\n\t\t\treturn true;\n\t\t}\n\t\n\t\tvar html = _isHtml( d );\n\t\treturn ! html ?\n\t\t\tnull :\n\t\t\t_isNumber( _stripHtml( d ), decimalPoint, formatted ) ?\n\t\t\t\ttrue :\n\t\t\t\tnull;\n\t};\n\t\n\t\n\tvar _pluck = function ( a, prop, prop2 ) {\n\t\tvar out = [];\n\t\tvar i=0, ien=a.length;\n\t\n\t\t// Could have the test in the loop for slightly smaller code, but speed\n\t\t// is essential here\n\t\tif ( prop2 !== undefined ) {\n\t\t\tfor ( ; i<ien ; i++ ) {\n\t\t\t\tif ( a[i] && a[i][ prop ] ) {\n\t\t\t\t\tout.push( a[i][ prop ][ prop2 ] );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\telse {\n\t\t\tfor ( ; i<ien ; i++ ) {\n\t\t\t\tif ( a[i] ) {\n\t\t\t\t\tout.push( a[i][ prop ] );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\n\t\treturn out;\n\t};\n\t\n\t\n\t// Basically the same as _pluck, but rather than looping over `a` we use `order`\n\t// as the indexes to pick from `a`\n\tvar _pluck_order = function ( a, order, prop, prop2 )\n\t{\n\t\tvar out = [];\n\t\tvar i=0, ien=order.length;\n\t\n\t\t// Could have the test in the loop for slightly smaller code, but speed\n\t\t// is essential here\n\t\tif ( prop2 !== undefined ) {\n\t\t\tfor ( ; i<ien ; i++ ) {\n\t\t\t\tif ( a[ order[i] ][ prop ] ) {\n\t\t\t\t\tout.push( a[ order[i] ][ prop ][ prop2 ] );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\telse {\n\t\t\tfor ( ; i<ien ; i++ ) {\n\t\t\t\tout.push( a[ order[i] ][ prop ] );\n\t\t\t}\n\t\t}\n\t\n\t\treturn out;\n\t};\n\t\n\t\n\tvar _range = function ( len, start )\n\t{\n\t\tvar out = [];\n\t\tvar end;\n\t\n\t\tif ( start === undefined ) {\n\t\t\tstart = 0;\n\t\t\tend = len;\n\t\t}\n\t\telse {\n\t\t\tend = start;\n\t\t\tstart = len;\n\t\t}\n\t\n\t\tfor ( var i=start ; i<end ; i++ ) {\n\t\t\tout.push( i );\n\t\t}\n\t\n\t\treturn out;\n\t};\n\t\n\t\n\tvar _removeEmpty = function ( a )\n\t{\n\t\tvar out = [];\n\t\n\t\tfor ( var i=0, ien=a.length ; i<ien ; i++ ) {\n\t\t\tif ( a[i] ) { // careful - will remove all falsy values!\n\t\t\t\tout.push( a[i] );\n\t\t\t}\n\t\t}\n\t\n\t\treturn out;\n\t};\n\t\n\t\n\tvar _stripHtml = function ( d ) {\n\t\treturn d.replace( _re_html, '' );\n\t};\n\t\n\t\n\t/**\n\t * Find the unique elements in a source array.\n\t *\n\t * @param  {array} src Source array\n\t * @return {array} Array of unique items\n\t * @ignore\n\t */\n\tvar _unique = function ( src )\n\t{\n\t\t// A faster unique method is to use object keys to identify used values,\n\t\t// but this doesn't work with arrays or objects, which we must also\n\t\t// consider. See jsperf.com/compare-array-unique-versions/4 for more\n\t\t// information.\n\t\tvar\n\t\t\tout = [],\n\t\t\tval,\n\t\t\ti, ien=src.length,\n\t\t\tj, k=0;\n\t\n\t\tagain: for ( i=0 ; i<ien ; i++ ) {\n\t\t\tval = src[i];\n\t\n\t\t\tfor ( j=0 ; j<k ; j++ ) {\n\t\t\t\tif ( out[j] === val ) {\n\t\t\t\t\tcontinue again;\n\t\t\t\t}\n\t\t\t}\n\t\n\t\t\tout.push( val );\n\t\t\tk++;\n\t\t}\n\t\n\t\treturn out;\n\t};\n\t\n\t\n\t/**\n\t * DataTables utility methods\n\t * \n\t * This namespace provides helper methods that DataTables uses internally to\n\t * create a DataTable, but which are not exclusively used only for DataTables.\n\t * These methods can be used by extension authors to save the duplication of\n\t * code.\n\t *\n\t *  @namespace\n\t */\n\tDataTable.util = {\n\t\t/**\n\t\t * Throttle the calls to a function. Arguments and context are maintained\n\t\t * for the throttled function.\n\t\t *\n\t\t * @param {function} fn Function to be called\n\t\t * @param {integer} freq Call frequency in mS\n\t\t * @return {function} Wrapped function\n\t\t */\n\t\tthrottle: function ( fn, freq ) {\n\t\t\tvar\n\t\t\t\tfrequency = freq !== undefined ? freq : 200,\n\t\t\t\tlast,\n\t\t\t\ttimer;\n\t\n\t\t\treturn function () {\n\t\t\t\tvar\n\t\t\t\t\tthat = this,\n\t\t\t\t\tnow  = +new Date(),\n\t\t\t\t\targs = arguments;\n\t\n\t\t\t\tif ( last && now < last + frequency ) {\n\t\t\t\t\tclearTimeout( timer );\n\t\n\t\t\t\t\ttimer = setTimeout( function () {\n\t\t\t\t\t\tlast = undefined;\n\t\t\t\t\t\tfn.apply( that, args );\n\t\t\t\t\t}, frequency );\n\t\t\t\t}\n\t\t\t\telse {\n\t\t\t\t\tlast = now;\n\t\t\t\t\tfn.apply( that, args );\n\t\t\t\t}\n\t\t\t};\n\t\t},\n\t\n\t\n\t\t/**\n\t\t * Escape a string such that it can be used in a regular expression\n\t\t *\n\t\t *  @param {string} val string to escape\n\t\t *  @returns {string} escaped string\n\t\t */\n\t\tescapeRegex: function ( val ) {\n\t\t\treturn val.replace( _re_escape_regex, '\\\\$1' );\n\t\t}\n\t};\n\t\n\t\n\t\n\t/**\n\t * Create a mapping object that allows camel case parameters to be looked up\n\t * for their Hungarian counterparts. The mapping is stored in a private\n\t * parameter called `_hungarianMap` which can be accessed on the source object.\n\t *  @param {object} o\n\t *  @memberof DataTable#oApi\n\t */\n\tfunction _fnHungarianMap ( o )\n\t{\n\t\tvar\n\t\t\thungarian = 'a aa ai ao as b fn i m o s ',\n\t\t\tmatch,\n\t\t\tnewKey,\n\t\t\tmap = {};\n\t\n\t\t$.each( o, function (key, val) {\n\t\t\tmatch = key.match(/^([^A-Z]+?)([A-Z])/);\n\t\n\t\t\tif ( match && hungarian.indexOf(match[1]+' ') !== -1 )\n\t\t\t{\n\t\t\t\tnewKey = key.replace( match[0], match[2].toLowerCase() );\n\t\t\t\tmap[ newKey ] = key;\n\t\n\t\t\t\tif ( match[1] === 'o' )\n\t\t\t\t{\n\t\t\t\t\t_fnHungarianMap( o[key] );\n\t\t\t\t}\n\t\t\t}\n\t\t} );\n\t\n\t\to._hungarianMap = map;\n\t}\n\t\n\t\n\t/**\n\t * Convert from camel case parameters to Hungarian, based on a Hungarian map\n\t * created by _fnHungarianMap.\n\t *  @param {object} src The model object which holds all parameters that can be\n\t *    mapped.\n\t *  @param {object} user The object to convert from camel case to Hungarian.\n\t *  @param {boolean} force When set to `true`, properties which already have a\n\t *    Hungarian value in the `user` object will be overwritten. Otherwise they\n\t *    won't be.\n\t *  @memberof DataTable#oApi\n\t */\n\tfunction _fnCamelToHungarian ( src, user, force )\n\t{\n\t\tif ( ! src._hungarianMap ) {\n\t\t\t_fnHungarianMap( src );\n\t\t}\n\t\n\t\tvar hungarianKey;\n\t\n\t\t$.each( user, function (key, val) {\n\t\t\thungarianKey = src._hungarianMap[ key ];\n\t\n\t\t\tif ( hungarianKey !== undefined && (force || user[hungarianKey] === undefined) )\n\t\t\t{\n\t\t\t\t// For objects, we need to buzz down into the object to copy parameters\n\t\t\t\tif ( hungarianKey.charAt(0) === 'o' )\n\t\t\t\t{\n\t\t\t\t\t// Copy the camelCase options over to the hungarian\n\t\t\t\t\tif ( ! user[ hungarianKey ] ) {\n\t\t\t\t\t\tuser[ hungarianKey ] = {};\n\t\t\t\t\t}\n\t\t\t\t\t$.extend( true, user[hungarianKey], user[key] );\n\t\n\t\t\t\t\t_fnCamelToHungarian( src[hungarianKey], user[hungarianKey], force );\n\t\t\t\t}\n\t\t\t\telse {\n\t\t\t\t\tuser[hungarianKey] = user[ key ];\n\t\t\t\t}\n\t\t\t}\n\t\t} );\n\t}\n\t\n\t\n\t/**\n\t * Language compatibility - when certain options are given, and others aren't, we\n\t * need to duplicate the values over, in order to provide backwards compatibility\n\t * with older language files.\n\t *  @param {object} oSettings dataTables settings object\n\t *  @memberof DataTable#oApi\n\t */\n\tfunction _fnLanguageCompat( lang )\n\t{\n\t\tvar defaults = DataTable.defaults.oLanguage;\n\t\tvar zeroRecords = lang.sZeroRecords;\n\t\n\t\t/* Backwards compatibility - if there is no sEmptyTable given, then use the same as\n\t\t * sZeroRecords - assuming that is given.\n\t\t */\n\t\tif ( ! lang.sEmptyTable && zeroRecords &&\n\t\t\tdefaults.sEmptyTable === \"No data available in table\" )\n\t\t{\n\t\t\t_fnMap( lang, lang, 'sZeroRecords', 'sEmptyTable' );\n\t\t}\n\t\n\t\t/* Likewise with loading records */\n\t\tif ( ! lang.sLoadingRecords && zeroRecords &&\n\t\t\tdefaults.sLoadingRecords === \"Loading...\" )\n\t\t{\n\t\t\t_fnMap( lang, lang, 'sZeroRecords', 'sLoadingRecords' );\n\t\t}\n\t\n\t\t// Old parameter name of the thousands separator mapped onto the new\n\t\tif ( lang.sInfoThousands ) {\n\t\t\tlang.sThousands = lang.sInfoThousands;\n\t\t}\n\t\n\t\tvar decimal = lang.sDecimal;\n\t\tif ( decimal ) {\n\t\t\t_addNumericSort( decimal );\n\t\t}\n\t}\n\t\n\t\n\t/**\n\t * Map one parameter onto another\n\t *  @param {object} o Object to map\n\t *  @param {*} knew The new parameter name\n\t *  @param {*} old The old parameter name\n\t */\n\tvar _fnCompatMap = function ( o, knew, old ) {\n\t\tif ( o[ knew ] !== undefined ) {\n\t\t\to[ old ] = o[ knew ];\n\t\t}\n\t};\n\t\n\t\n\t/**\n\t * Provide backwards compatibility for the main DT options. Note that the new\n\t * options are mapped onto the old parameters, so this is an external interface\n\t * change only.\n\t *  @param {object} init Object to map\n\t */\n\tfunction _fnCompatOpts ( init )\n\t{\n\t\t_fnCompatMap( init, 'ordering',      'bSort' );\n\t\t_fnCompatMap( init, 'orderMulti',    'bSortMulti' );\n\t\t_fnCompatMap( init, 'orderClasses',  'bSortClasses' );\n\t\t_fnCompatMap( init, 'orderCellsTop', 'bSortCellsTop' );\n\t\t_fnCompatMap( init, 'order',         'aaSorting' );\n\t\t_fnCompatMap( init, 'orderFixed',    'aaSortingFixed' );\n\t\t_fnCompatMap( init, 'paging',        'bPaginate' );\n\t\t_fnCompatMap( init, 'pagingType',    'sPaginationType' );\n\t\t_fnCompatMap( init, 'pageLength',    'iDisplayLength' );\n\t\t_fnCompatMap( init, 'searching',     'bFilter' );\n\t\n\t\t// Boolean initialisation of x-scrolling\n\t\tif ( typeof init.sScrollX === 'boolean' ) {\n\t\t\tinit.sScrollX = init.sScrollX ? '100%' : '';\n\t\t}\n\t\tif ( typeof init.scrollX === 'boolean' ) {\n\t\t\tinit.scrollX = init.scrollX ? '100%' : '';\n\t\t}\n\t\n\t\t// Column search objects are in an array, so it needs to be converted\n\t\t// element by element\n\t\tvar searchCols = init.aoSearchCols;\n\t\n\t\tif ( searchCols ) {\n\t\t\tfor ( var i=0, ien=searchCols.length ; i<ien ; i++ ) {\n\t\t\t\tif ( searchCols[i] ) {\n\t\t\t\t\t_fnCamelToHungarian( DataTable.models.oSearch, searchCols[i] );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\t\n\t\n\t/**\n\t * Provide backwards compatibility for column options. Note that the new options\n\t * are mapped onto the old parameters, so this is an external interface change\n\t * only.\n\t *  @param {object} init Object to map\n\t */\n\tfunction _fnCompatCols ( init )\n\t{\n\t\t_fnCompatMap( init, 'orderable',     'bSortable' );\n\t\t_fnCompatMap( init, 'orderData',     'aDataSort' );\n\t\t_fnCompatMap( init, 'orderSequence', 'asSorting' );\n\t\t_fnCompatMap( init, 'orderDataType', 'sortDataType' );\n\t\n\t\t// orderData can be given as an integer\n\t\tvar dataSort = init.aDataSort;\n\t\tif ( dataSort && ! $.isArray( dataSort ) ) {\n\t\t\tinit.aDataSort = [ dataSort ];\n\t\t}\n\t}\n\t\n\t\n\t/**\n\t * Browser feature detection for capabilities, quirks\n\t *  @param {object} settings dataTables settings object\n\t *  @memberof DataTable#oApi\n\t */\n\tfunction _fnBrowserDetect( settings )\n\t{\n\t\t// We don't need to do this every time DataTables is constructed, the values\n\t\t// calculated are specific to the browser and OS configuration which we\n\t\t// don't expect to change between initialisations\n\t\tif ( ! DataTable.__browser ) {\n\t\t\tvar browser = {};\n\t\t\tDataTable.__browser = browser;\n\t\n\t\t\t// Scrolling feature / quirks detection\n\t\t\tvar n = $('<div/>')\n\t\t\t\t.css( {\n\t\t\t\t\tposition: 'fixed',\n\t\t\t\t\ttop: 0,\n\t\t\t\t\tleft: 0,\n\t\t\t\t\theight: 1,\n\t\t\t\t\twidth: 1,\n\t\t\t\t\toverflow: 'hidden'\n\t\t\t\t} )\n\t\t\t\t.append(\n\t\t\t\t\t$('<div/>')\n\t\t\t\t\t\t.css( {\n\t\t\t\t\t\t\tposition: 'absolute',\n\t\t\t\t\t\t\ttop: 1,\n\t\t\t\t\t\t\tleft: 1,\n\t\t\t\t\t\t\twidth: 100,\n\t\t\t\t\t\t\toverflow: 'scroll'\n\t\t\t\t\t\t} )\n\t\t\t\t\t\t.append(\n\t\t\t\t\t\t\t$('<div/>')\n\t\t\t\t\t\t\t\t.css( {\n\t\t\t\t\t\t\t\t\twidth: '100%',\n\t\t\t\t\t\t\t\t\theight: 10\n\t\t\t\t\t\t\t\t} )\n\t\t\t\t\t\t)\n\t\t\t\t)\n\t\t\t\t.appendTo( 'body' );\n\t\n\t\t\tvar outer = n.children();\n\t\t\tvar inner = outer.children();\n\t\n\t\t\t// Numbers below, in order, are:\n\t\t\t// inner.offsetWidth, inner.clientWidth, outer.offsetWidth, outer.clientWidth\n\t\t\t//\n\t\t\t// IE6 XP:                           100 100 100  83\n\t\t\t// IE7 Vista:                        100 100 100  83\n\t\t\t// IE 8+ Windows:                     83  83 100  83\n\t\t\t// Evergreen Windows:                 83  83 100  83\n\t\t\t// Evergreen Mac with scrollbars:     85  85 100  85\n\t\t\t// Evergreen Mac without scrollbars: 100 100 100 100\n\t\n\t\t\t// Get scrollbar width\n\t\t\tbrowser.barWidth = outer[0].offsetWidth - outer[0].clientWidth;\n\t\n\t\t\t// IE6/7 will oversize a width 100% element inside a scrolling element, to\n\t\t\t// include the width of the scrollbar, while other browsers ensure the inner\n\t\t\t// element is contained without forcing scrolling\n\t\t\tbrowser.bScrollOversize = inner[0].offsetWidth === 100 && outer[0].clientWidth !== 100;\n\t\n\t\t\t// In rtl text layout, some browsers (most, but not all) will place the\n\t\t\t// scrollbar on the left, rather than the right.\n\t\t\tbrowser.bScrollbarLeft = Math.round( inner.offset().left ) !== 1;\n\t\n\t\t\t// IE8- don't provide height and width for getBoundingClientRect\n\t\t\tbrowser.bBounding = n[0].getBoundingClientRect().width ? true : false;\n\t\n\t\t\tn.remove();\n\t\t}\n\t\n\t\t$.extend( settings.oBrowser, DataTable.__browser );\n\t\tsettings.oScroll.iBarWidth = DataTable.__browser.barWidth;\n\t}\n\t\n\t\n\t/**\n\t * Array.prototype reduce[Right] method, used for browsers which don't support\n\t * JS 1.6. Done this way to reduce code size, since we iterate either way\n\t *  @param {object} settings dataTables settings object\n\t *  @memberof DataTable#oApi\n\t */\n\tfunction _fnReduce ( that, fn, init, start, end, inc )\n\t{\n\t\tvar\n\t\t\ti = start,\n\t\t\tvalue,\n\t\t\tisSet = false;\n\t\n\t\tif ( init !== undefined ) {\n\t\t\tvalue = init;\n\t\t\tisSet = true;\n\t\t}\n\t\n\t\twhile ( i !== end ) {\n\t\t\tif ( ! that.hasOwnProperty(i) ) {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\n\t\t\tvalue = isSet ?\n\t\t\t\tfn( value, that[i], i, that ) :\n\t\t\t\tthat[i];\n\t\n\t\t\tisSet = true;\n\t\t\ti += inc;\n\t\t}\n\t\n\t\treturn value;\n\t}\n\t\n\t/**\n\t * Add a column to the list used for the table with default values\n\t *  @param {object} oSettings dataTables settings object\n\t *  @param {node} nTh The th element for this column\n\t *  @memberof DataTable#oApi\n\t */\n\tfunction _fnAddColumn( oSettings, nTh )\n\t{\n\t\t// Add column to aoColumns array\n\t\tvar oDefaults = DataTable.defaults.column;\n\t\tvar iCol = oSettings.aoColumns.length;\n\t\tvar oCol = $.extend( {}, DataTable.models.oColumn, oDefaults, {\n\t\t\t\"nTh\": nTh ? nTh : document.createElement('th'),\n\t\t\t\"sTitle\":    oDefaults.sTitle    ? oDefaults.sTitle    : nTh ? nTh.innerHTML : '',\n\t\t\t\"aDataSort\": oDefaults.aDataSort ? oDefaults.aDataSort : [iCol],\n\t\t\t\"mData\": oDefaults.mData ? oDefaults.mData : iCol,\n\t\t\tidx: iCol\n\t\t} );\n\t\toSettings.aoColumns.push( oCol );\n\t\n\t\t// Add search object for column specific search. Note that the `searchCols[ iCol ]`\n\t\t// passed into extend can be undefined. This allows the user to give a default\n\t\t// with only some of the parameters defined, and also not give a default\n\t\tvar searchCols = oSettings.aoPreSearchCols;\n\t\tsearchCols[ iCol ] = $.extend( {}, DataTable.models.oSearch, searchCols[ iCol ] );\n\t\n\t\t// Use the default column options function to initialise classes etc\n\t\t_fnColumnOptions( oSettings, iCol, $(nTh).data() );\n\t}\n\t\n\t\n\t/**\n\t * Apply options for a column\n\t *  @param {object} oSettings dataTables settings object\n\t *  @param {int} iCol column index to consider\n\t *  @param {object} oOptions object with sType, bVisible and bSearchable etc\n\t *  @memberof DataTable#oApi\n\t */\n\tfunction _fnColumnOptions( oSettings, iCol, oOptions )\n\t{\n\t\tvar oCol = oSettings.aoColumns[ iCol ];\n\t\tvar oClasses = oSettings.oClasses;\n\t\tvar th = $(oCol.nTh);\n\t\n\t\t// Try to get width information from the DOM. We can't get it from CSS\n\t\t// as we'd need to parse the CSS stylesheet. `width` option can override\n\t\tif ( ! oCol.sWidthOrig ) {\n\t\t\t// Width attribute\n\t\t\toCol.sWidthOrig = th.attr('width') || null;\n\t\n\t\t\t// Style attribute\n\t\t\tvar t = (th.attr('style') || '').match(/width:\\s*(\\d+[pxem%]+)/);\n\t\t\tif ( t ) {\n\t\t\t\toCol.sWidthOrig = t[1];\n\t\t\t}\n\t\t}\n\t\n\t\t/* User specified column options */\n\t\tif ( oOptions !== undefined && oOptions !== null )\n\t\t{\n\t\t\t// Backwards compatibility\n\t\t\t_fnCompatCols( oOptions );\n\t\n\t\t\t// Map camel case parameters to their Hungarian counterparts\n\t\t\t_fnCamelToHungarian( DataTable.defaults.column, oOptions );\n\t\n\t\t\t/* Backwards compatibility for mDataProp */\n\t\t\tif ( oOptions.mDataProp !== undefined && !oOptions.mData )\n\t\t\t{\n\t\t\t\toOptions.mData = oOptions.mDataProp;\n\t\t\t}\n\t\n\t\t\tif ( oOptions.sType )\n\t\t\t{\n\t\t\t\toCol._sManualType = oOptions.sType;\n\t\t\t}\n\t\n\t\t\t// `class` is a reserved word in Javascript, so we need to provide\n\t\t\t// the ability to use a valid name for the camel case input\n\t\t\tif ( oOptions.className && ! oOptions.sClass )\n\t\t\t{\n\t\t\t\toOptions.sClass = oOptions.className;\n\t\t\t}\n\t\n\t\t\t$.extend( oCol, oOptions );\n\t\t\t_fnMap( oCol, oOptions, \"sWidth\", \"sWidthOrig\" );\n\t\n\t\t\t/* iDataSort to be applied (backwards compatibility), but aDataSort will take\n\t\t\t * priority if defined\n\t\t\t */\n\t\t\tif ( oOptions.iDataSort !== undefined )\n\t\t\t{\n\t\t\t\toCol.aDataSort = [ oOptions.iDataSort ];\n\t\t\t}\n\t\t\t_fnMap( oCol, oOptions, \"aDataSort\" );\n\t\t}\n\t\n\t\t/* Cache the data get and set functions for speed */\n\t\tvar mDataSrc = oCol.mData;\n\t\tvar mData = _fnGetObjectDataFn( mDataSrc );\n\t\tvar mRender = oCol.mRender ? _fnGetObjectDataFn( oCol.mRender ) : null;\n\t\n\t\tvar attrTest = function( src ) {\n\t\t\treturn typeof src === 'string' && src.indexOf('@') !== -1;\n\t\t};\n\t\toCol._bAttrSrc = $.isPlainObject( mDataSrc ) && (\n\t\t\tattrTest(mDataSrc.sort) || attrTest(mDataSrc.type) || attrTest(mDataSrc.filter)\n\t\t);\n\t\toCol._setter = null;\n\t\n\t\toCol.fnGetData = function (rowData, type, meta) {\n\t\t\tvar innerData = mData( rowData, type, undefined, meta );\n\t\n\t\t\treturn mRender && type ?\n\t\t\t\tmRender( innerData, type, rowData, meta ) :\n\t\t\t\tinnerData;\n\t\t};\n\t\toCol.fnSetData = function ( rowData, val, meta ) {\n\t\t\treturn _fnSetObjectDataFn( mDataSrc )( rowData, val, meta );\n\t\t};\n\t\n\t\t// Indicate if DataTables should read DOM data as an object or array\n\t\t// Used in _fnGetRowElements\n\t\tif ( typeof mDataSrc !== 'number' ) {\n\t\t\toSettings._rowReadObject = true;\n\t\t}\n\t\n\t\t/* Feature sorting overrides column specific when off */\n\t\tif ( !oSettings.oFeatures.bSort )\n\t\t{\n\t\t\toCol.bSortable = false;\n\t\t\tth.addClass( oClasses.sSortableNone ); // Have to add class here as order event isn't called\n\t\t}\n\t\n\t\t/* Check that the class assignment is correct for sorting */\n\t\tvar bAsc = $.inArray('asc', oCol.asSorting) !== -1;\n\t\tvar bDesc = $.inArray('desc', oCol.asSorting) !== -1;\n\t\tif ( !oCol.bSortable || (!bAsc && !bDesc) )\n\t\t{\n\t\t\toCol.sSortingClass = oClasses.sSortableNone;\n\t\t\toCol.sSortingClassJUI = \"\";\n\t\t}\n\t\telse if ( bAsc && !bDesc )\n\t\t{\n\t\t\toCol.sSortingClass = oClasses.sSortableAsc;\n\t\t\toCol.sSortingClassJUI = oClasses.sSortJUIAscAllowed;\n\t\t}\n\t\telse if ( !bAsc && bDesc )\n\t\t{\n\t\t\toCol.sSortingClass = oClasses.sSortableDesc;\n\t\t\toCol.sSortingClassJUI = oClasses.sSortJUIDescAllowed;\n\t\t}\n\t\telse\n\t\t{\n\t\t\toCol.sSortingClass = oClasses.sSortable;\n\t\t\toCol.sSortingClassJUI = oClasses.sSortJUI;\n\t\t}\n\t}\n\t\n\t\n\t/**\n\t * Adjust the table column widths for new data. Note: you would probably want to\n\t * do a redraw after calling this function!\n\t *  @param {object} settings dataTables settings object\n\t *  @memberof DataTable#oApi\n\t */\n\tfunction _fnAdjustColumnSizing ( settings )\n\t{\n\t\t/* Not interested in doing column width calculation if auto-width is disabled */\n\t\tif ( settings.oFeatures.bAutoWidth !== false )\n\t\t{\n\t\t\tvar columns = settings.aoColumns;\n\t\n\t\t\t_fnCalculateColumnWidths( settings );\n\t\t\tfor ( var i=0 , iLen=columns.length ; i<iLen ; i++ )\n\t\t\t{\n\t\t\t\tcolumns[i].nTh.style.width = columns[i].sWidth;\n\t\t\t}\n\t\t}\n\t\n\t\tvar scroll = settings.oScroll;\n\t\tif ( scroll.sY !== '' || scroll.sX !== '')\n\t\t{\n\t\t\t_fnScrollDraw( settings );\n\t\t}\n\t\n\t\t_fnCallbackFire( settings, null, 'column-sizing', [settings] );\n\t}\n\t\n\t\n\t/**\n\t * Covert the index of a visible column to the index in the data array (take account\n\t * of hidden columns)\n\t *  @param {object} oSettings dataTables settings object\n\t *  @param {int} iMatch Visible column index to lookup\n\t *  @returns {int} i the data index\n\t *  @memberof DataTable#oApi\n\t */\n\tfunction _fnVisibleToColumnIndex( oSettings, iMatch )\n\t{\n\t\tvar aiVis = _fnGetColumns( oSettings, 'bVisible' );\n\t\n\t\treturn typeof aiVis[iMatch] === 'number' ?\n\t\t\taiVis[iMatch] :\n\t\t\tnull;\n\t}\n\t\n\t\n\t/**\n\t * Covert the index of an index in the data array and convert it to the visible\n\t *   column index (take account of hidden columns)\n\t *  @param {int} iMatch Column index to lookup\n\t *  @param {object} oSettings dataTables settings object\n\t *  @returns {int} i the data index\n\t *  @memberof DataTable#oApi\n\t */\n\tfunction _fnColumnIndexToVisible( oSettings, iMatch )\n\t{\n\t\tvar aiVis = _fnGetColumns( oSettings, 'bVisible' );\n\t\tvar iPos = $.inArray( iMatch, aiVis );\n\t\n\t\treturn iPos !== -1 ? iPos : null;\n\t}\n\t\n\t\n\t/**\n\t * Get the number of visible columns\n\t *  @param {object} oSettings dataTables settings object\n\t *  @returns {int} i the number of visible columns\n\t *  @memberof DataTable#oApi\n\t */\n\tfunction _fnVisbleColumns( oSettings )\n\t{\n\t\tvar vis = 0;\n\t\n\t\t// No reduce in IE8, use a loop for now\n\t\t$.each( oSettings.aoColumns, function ( i, col ) {\n\t\t\tif ( col.bVisible && $(col.nTh).css('display') !== 'none' ) {\n\t\t\t\tvis++;\n\t\t\t}\n\t\t} );\n\t\n\t\treturn vis;\n\t}\n\t\n\t\n\t/**\n\t * Get an array of column indexes that match a given property\n\t *  @param {object} oSettings dataTables settings object\n\t *  @param {string} sParam Parameter in aoColumns to look for - typically\n\t *    bVisible or bSearchable\n\t *  @returns {array} Array of indexes with matched properties\n\t *  @memberof DataTable#oApi\n\t */\n\tfunction _fnGetColumns( oSettings, sParam )\n\t{\n\t\tvar a = [];\n\t\n\t\t$.map( oSettings.aoColumns, function(val, i) {\n\t\t\tif ( val[sParam] ) {\n\t\t\t\ta.push( i );\n\t\t\t}\n\t\t} );\n\t\n\t\treturn a;\n\t}\n\t\n\t\n\t/**\n\t * Calculate the 'type' of a column\n\t *  @param {object} settings dataTables settings object\n\t *  @memberof DataTable#oApi\n\t */\n\tfunction _fnColumnTypes ( settings )\n\t{\n\t\tvar columns = settings.aoColumns;\n\t\tvar data = settings.aoData;\n\t\tvar types = DataTable.ext.type.detect;\n\t\tvar i, ien, j, jen, k, ken;\n\t\tvar col, cell, detectedType, cache;\n\t\n\t\t// For each column, spin over the \n\t\tfor ( i=0, ien=columns.length ; i<ien ; i++ ) {\n\t\t\tcol = columns[i];\n\t\t\tcache = [];\n\t\n\t\t\tif ( ! col.sType && col._sManualType ) {\n\t\t\t\tcol.sType = col._sManualType;\n\t\t\t}\n\t\t\telse if ( ! col.sType ) {\n\t\t\t\tfor ( j=0, jen=types.length ; j<jen ; j++ ) {\n\t\t\t\t\tfor ( k=0, ken=data.length ; k<ken ; k++ ) {\n\t\t\t\t\t\t// Use a cache array so we only need to get the type data\n\t\t\t\t\t\t// from the formatter once (when using multiple detectors)\n\t\t\t\t\t\tif ( cache[k] === undefined ) {\n\t\t\t\t\t\t\tcache[k] = _fnGetCellData( settings, k, i, 'type' );\n\t\t\t\t\t\t}\n\t\n\t\t\t\t\t\tdetectedType = types[j]( cache[k], settings );\n\t\n\t\t\t\t\t\t// If null, then this type can't apply to this column, so\n\t\t\t\t\t\t// rather than testing all cells, break out. There is an\n\t\t\t\t\t\t// exception for the last type which is `html`. We need to\n\t\t\t\t\t\t// scan all rows since it is possible to mix string and HTML\n\t\t\t\t\t\t// types\n\t\t\t\t\t\tif ( ! detectedType && j !== types.length-1 ) {\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\n\t\t\t\t\t\t// Only a single match is needed for html type since it is\n\t\t\t\t\t\t// bottom of the pile and very similar to string\n\t\t\t\t\t\tif ( detectedType === 'html' ) {\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\n\t\t\t\t\t// Type is valid for all data points in the column - use this\n\t\t\t\t\t// type\n\t\t\t\t\tif ( detectedType ) {\n\t\t\t\t\t\tcol.sType = detectedType;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\n\t\t\t\t// Fall back - if no type was detected, always use string\n\t\t\t\tif ( ! col.sType ) {\n\t\t\t\t\tcol.sType = 'string';\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\t\n\t\n\t/**\n\t * Take the column definitions and static columns arrays and calculate how\n\t * they relate to column indexes. The callback function will then apply the\n\t * definition found for a column to a suitable configuration object.\n\t *  @param {object} oSettings dataTables settings object\n\t *  @param {array} aoColDefs The aoColumnDefs array that is to be applied\n\t *  @param {array} aoCols The aoColumns array that defines columns individually\n\t *  @param {function} fn Callback function - takes two parameters, the calculated\n\t *    column index and the definition for that column.\n\t *  @memberof DataTable#oApi\n\t */\n\tfunction _fnApplyColumnDefs( oSettings, aoColDefs, aoCols, fn )\n\t{\n\t\tvar i, iLen, j, jLen, k, kLen, def;\n\t\tvar columns = oSettings.aoColumns;\n\t\n\t\t// Column definitions with aTargets\n\t\tif ( aoColDefs )\n\t\t{\n\t\t\t/* Loop over the definitions array - loop in reverse so first instance has priority */\n\t\t\tfor ( i=aoColDefs.length-1 ; i>=0 ; i-- )\n\t\t\t{\n\t\t\t\tdef = aoColDefs[i];\n\t\n\t\t\t\t/* Each definition can target multiple columns, as it is an array */\n\t\t\t\tvar aTargets = def.targets !== undefined ?\n\t\t\t\t\tdef.targets :\n\t\t\t\t\tdef.aTargets;\n\t\n\t\t\t\tif ( ! $.isArray( aTargets ) )\n\t\t\t\t{\n\t\t\t\t\taTargets = [ aTargets ];\n\t\t\t\t}\n\t\n\t\t\t\tfor ( j=0, jLen=aTargets.length ; j<jLen ; j++ )\n\t\t\t\t{\n\t\t\t\t\tif ( typeof aTargets[j] === 'number' && aTargets[j] >= 0 )\n\t\t\t\t\t{\n\t\t\t\t\t\t/* Add columns that we don't yet know about */\n\t\t\t\t\t\twhile( columns.length <= aTargets[j] )\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t_fnAddColumn( oSettings );\n\t\t\t\t\t\t}\n\t\n\t\t\t\t\t\t/* Integer, basic index */\n\t\t\t\t\t\tfn( aTargets[j], def );\n\t\t\t\t\t}\n\t\t\t\t\telse if ( typeof aTargets[j] === 'number' && aTargets[j] < 0 )\n\t\t\t\t\t{\n\t\t\t\t\t\t/* Negative integer, right to left column counting */\n\t\t\t\t\t\tfn( columns.length+aTargets[j], def );\n\t\t\t\t\t}\n\t\t\t\t\telse if ( typeof aTargets[j] === 'string' )\n\t\t\t\t\t{\n\t\t\t\t\t\t/* Class name matching on TH element */\n\t\t\t\t\t\tfor ( k=0, kLen=columns.length ; k<kLen ; k++ )\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tif ( aTargets[j] == \"_all\" ||\n\t\t\t\t\t\t\t     $(columns[k].nTh).hasClass( aTargets[j] ) )\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tfn( k, def );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\n\t\t// Statically defined columns array\n\t\tif ( aoCols )\n\t\t{\n\t\t\tfor ( i=0, iLen=aoCols.length ; i<iLen ; i++ )\n\t\t\t{\n\t\t\t\tfn( i, aoCols[i] );\n\t\t\t}\n\t\t}\n\t}\n\t\n\t/**\n\t * Add a data array to the table, creating DOM node etc. This is the parallel to\n\t * _fnGatherData, but for adding rows from a Javascript source, rather than a\n\t * DOM source.\n\t *  @param {object} oSettings dataTables settings object\n\t *  @param {array} aData data array to be added\n\t *  @param {node} [nTr] TR element to add to the table - optional. If not given,\n\t *    DataTables will create a row automatically\n\t *  @param {array} [anTds] Array of TD|TH elements for the row - must be given\n\t *    if nTr is.\n\t *  @returns {int} >=0 if successful (index of new aoData entry), -1 if failed\n\t *  @memberof DataTable#oApi\n\t */\n\tfunction _fnAddData ( oSettings, aDataIn, nTr, anTds )\n\t{\n\t\t/* Create the object for storing information about this new row */\n\t\tvar iRow = oSettings.aoData.length;\n\t\tvar oData = $.extend( true, {}, DataTable.models.oRow, {\n\t\t\tsrc: nTr ? 'dom' : 'data',\n\t\t\tidx: iRow\n\t\t} );\n\t\n\t\toData._aData = aDataIn;\n\t\toSettings.aoData.push( oData );\n\t\n\t\t/* Create the cells */\n\t\tvar nTd, sThisType;\n\t\tvar columns = oSettings.aoColumns;\n\t\n\t\t// Invalidate the column types as the new data needs to be revalidated\n\t\tfor ( var i=0, iLen=columns.length ; i<iLen ; i++ )\n\t\t{\n\t\t\tcolumns[i].sType = null;\n\t\t}\n\t\n\t\t/* Add to the display array */\n\t\toSettings.aiDisplayMaster.push( iRow );\n\t\n\t\tvar id = oSettings.rowIdFn( aDataIn );\n\t\tif ( id !== undefined ) {\n\t\t\toSettings.aIds[ id ] = oData;\n\t\t}\n\t\n\t\t/* Create the DOM information, or register it if already present */\n\t\tif ( nTr || ! oSettings.oFeatures.bDeferRender )\n\t\t{\n\t\t\t_fnCreateTr( oSettings, iRow, nTr, anTds );\n\t\t}\n\t\n\t\treturn iRow;\n\t}\n\t\n\t\n\t/**\n\t * Add one or more TR elements to the table. Generally we'd expect to\n\t * use this for reading data from a DOM sourced table, but it could be\n\t * used for an TR element. Note that if a TR is given, it is used (i.e.\n\t * it is not cloned).\n\t *  @param {object} settings dataTables settings object\n\t *  @param {array|node|jQuery} trs The TR element(s) to add to the table\n\t *  @returns {array} Array of indexes for the added rows\n\t *  @memberof DataTable#oApi\n\t */\n\tfunction _fnAddTr( settings, trs )\n\t{\n\t\tvar row;\n\t\n\t\t// Allow an individual node to be passed in\n\t\tif ( ! (trs instanceof $) ) {\n\t\t\ttrs = $(trs);\n\t\t}\n\t\n\t\treturn trs.map( function (i, el) {\n\t\t\trow = _fnGetRowElements( settings, el );\n\t\t\treturn _fnAddData( settings, row.data, el, row.cells );\n\t\t} );\n\t}\n\t\n\t\n\t/**\n\t * Take a TR element and convert it to an index in aoData\n\t *  @param {object} oSettings dataTables settings object\n\t *  @param {node} n the TR element to find\n\t *  @returns {int} index if the node is found, null if not\n\t *  @memberof DataTable#oApi\n\t */\n\tfunction _fnNodeToDataIndex( oSettings, n )\n\t{\n\t\treturn (n._DT_RowIndex!==undefined) ? n._DT_RowIndex : null;\n\t}\n\t\n\t\n\t/**\n\t * Take a TD element and convert it into a column data index (not the visible index)\n\t *  @param {object} oSettings dataTables settings object\n\t *  @param {int} iRow The row number the TD/TH can be found in\n\t *  @param {node} n The TD/TH element to find\n\t *  @returns {int} index if the node is found, -1 if not\n\t *  @memberof DataTable#oApi\n\t */\n\tfunction _fnNodeToColumnIndex( oSettings, iRow, n )\n\t{\n\t\treturn $.inArray( n, oSettings.aoData[ iRow ].anCells );\n\t}\n\t\n\t\n\t/**\n\t * Get the data for a given cell from the internal cache, taking into account data mapping\n\t *  @param {object} settings dataTables settings object\n\t *  @param {int} rowIdx aoData row id\n\t *  @param {int} colIdx Column index\n\t *  @param {string} type data get type ('display', 'type' 'filter' 'sort')\n\t *  @returns {*} Cell data\n\t *  @memberof DataTable#oApi\n\t */\n\tfunction _fnGetCellData( settings, rowIdx, colIdx, type )\n\t{\n\t\tvar draw           = settings.iDraw;\n\t\tvar col            = settings.aoColumns[colIdx];\n\t\tvar rowData        = settings.aoData[rowIdx]._aData;\n\t\tvar defaultContent = col.sDefaultContent;\n\t\tvar cellData       = col.fnGetData( rowData, type, {\n\t\t\tsettings: settings,\n\t\t\trow:      rowIdx,\n\t\t\tcol:      colIdx\n\t\t} );\n\t\n\t\tif ( cellData === undefined ) {\n\t\t\tif ( settings.iDrawError != draw && defaultContent === null ) {\n\t\t\t\t_fnLog( settings, 0, \"Requested unknown parameter \"+\n\t\t\t\t\t(typeof col.mData=='function' ? '{function}' : \"'\"+col.mData+\"'\")+\n\t\t\t\t\t\" for row \"+rowIdx+\", column \"+colIdx, 4 );\n\t\t\t\tsettings.iDrawError = draw;\n\t\t\t}\n\t\t\treturn defaultContent;\n\t\t}\n\t\n\t\t// When the data source is null and a specific data type is requested (i.e.\n\t\t// not the original data), we can use default column data\n\t\tif ( (cellData === rowData || cellData === null) && defaultContent !== null && type !== undefined ) {\n\t\t\tcellData = defaultContent;\n\t\t}\n\t\telse if ( typeof cellData === 'function' ) {\n\t\t\t// If the data source is a function, then we run it and use the return,\n\t\t\t// executing in the scope of the data object (for instances)\n\t\t\treturn cellData.call( rowData );\n\t\t}\n\t\n\t\tif ( cellData === null && type == 'display' ) {\n\t\t\treturn '';\n\t\t}\n\t\treturn cellData;\n\t}\n\t\n\t\n\t/**\n\t * Set the value for a specific cell, into the internal data cache\n\t *  @param {object} settings dataTables settings object\n\t *  @param {int} rowIdx aoData row id\n\t *  @param {int} colIdx Column index\n\t *  @param {*} val Value to set\n\t *  @memberof DataTable#oApi\n\t */\n\tfunction _fnSetCellData( settings, rowIdx, colIdx, val )\n\t{\n\t\tvar col     = settings.aoColumns[colIdx];\n\t\tvar rowData = settings.aoData[rowIdx]._aData;\n\t\n\t\tcol.fnSetData( rowData, val, {\n\t\t\tsettings: settings,\n\t\t\trow:      rowIdx,\n\t\t\tcol:      colIdx\n\t\t}  );\n\t}\n\t\n\t\n\t// Private variable that is used to match action syntax in the data property object\n\tvar __reArray = /\\[.*?\\]$/;\n\tvar __reFn = /\\(\\)$/;\n\t\n\t/**\n\t * Split string on periods, taking into account escaped periods\n\t * @param  {string} str String to split\n\t * @return {array} Split string\n\t */\n\tfunction _fnSplitObjNotation( str )\n\t{\n\t\treturn $.map( str.match(/(\\\\.|[^\\.])+/g) || [''], function ( s ) {\n\t\t\treturn s.replace(/\\\\./g, '.');\n\t\t} );\n\t}\n\t\n\t\n\t/**\n\t * Return a function that can be used to get data from a source object, taking\n\t * into account the ability to use nested objects as a source\n\t *  @param {string|int|function} mSource The data source for the object\n\t *  @returns {function} Data get function\n\t *  @memberof DataTable#oApi\n\t */\n\tfunction _fnGetObjectDataFn( mSource )\n\t{\n\t\tif ( $.isPlainObject( mSource ) )\n\t\t{\n\t\t\t/* Build an object of get functions, and wrap them in a single call */\n\t\t\tvar o = {};\n\t\t\t$.each( mSource, function (key, val) {\n\t\t\t\tif ( val ) {\n\t\t\t\t\to[key] = _fnGetObjectDataFn( val );\n\t\t\t\t}\n\t\t\t} );\n\t\n\t\t\treturn function (data, type, row, meta) {\n\t\t\t\tvar t = o[type] || o._;\n\t\t\t\treturn t !== undefined ?\n\t\t\t\t\tt(data, type, row, meta) :\n\t\t\t\t\tdata;\n\t\t\t};\n\t\t}\n\t\telse if ( mSource === null )\n\t\t{\n\t\t\t/* Give an empty string for rendering / sorting etc */\n\t\t\treturn function (data) { // type, row and meta also passed, but not used\n\t\t\t\treturn data;\n\t\t\t};\n\t\t}\n\t\telse if ( typeof mSource === 'function' )\n\t\t{\n\t\t\treturn function (data, type, row, meta) {\n\t\t\t\treturn mSource( data, type, row, meta );\n\t\t\t};\n\t\t}\n\t\telse if ( typeof mSource === 'string' && (mSource.indexOf('.') !== -1 ||\n\t\t\t      mSource.indexOf('[') !== -1 || mSource.indexOf('(') !== -1) )\n\t\t{\n\t\t\t/* If there is a . in the source string then the data source is in a\n\t\t\t * nested object so we loop over the data for each level to get the next\n\t\t\t * level down. On each loop we test for undefined, and if found immediately\n\t\t\t * return. This allows entire objects to be missing and sDefaultContent to\n\t\t\t * be used if defined, rather than throwing an error\n\t\t\t */\n\t\t\tvar fetchData = function (data, type, src) {\n\t\t\t\tvar arrayNotation, funcNotation, out, innerSrc;\n\t\n\t\t\t\tif ( src !== \"\" )\n\t\t\t\t{\n\t\t\t\t\tvar a = _fnSplitObjNotation( src );\n\t\n\t\t\t\t\tfor ( var i=0, iLen=a.length ; i<iLen ; i++ )\n\t\t\t\t\t{\n\t\t\t\t\t\t// Check if we are dealing with special notation\n\t\t\t\t\t\tarrayNotation = a[i].match(__reArray);\n\t\t\t\t\t\tfuncNotation = a[i].match(__reFn);\n\t\n\t\t\t\t\t\tif ( arrayNotation )\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t// Array notation\n\t\t\t\t\t\t\ta[i] = a[i].replace(__reArray, '');\n\t\n\t\t\t\t\t\t\t// Condition allows simply [] to be passed in\n\t\t\t\t\t\t\tif ( a[i] !== \"\" ) {\n\t\t\t\t\t\t\t\tdata = data[ a[i] ];\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tout = [];\n\t\n\t\t\t\t\t\t\t// Get the remainder of the nested object to get\n\t\t\t\t\t\t\ta.splice( 0, i+1 );\n\t\t\t\t\t\t\tinnerSrc = a.join('.');\n\t\n\t\t\t\t\t\t\t// Traverse each entry in the array getting the properties requested\n\t\t\t\t\t\t\tif ( $.isArray( data ) ) {\n\t\t\t\t\t\t\t\tfor ( var j=0, jLen=data.length ; j<jLen ; j++ ) {\n\t\t\t\t\t\t\t\t\tout.push( fetchData( data[j], type, innerSrc ) );\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\n\t\t\t\t\t\t\t// If a string is given in between the array notation indicators, that\n\t\t\t\t\t\t\t// is used to join the strings together, otherwise an array is returned\n\t\t\t\t\t\t\tvar join = arrayNotation[0].substring(1, arrayNotation[0].length-1);\n\t\t\t\t\t\t\tdata = (join===\"\") ? out : out.join(join);\n\t\n\t\t\t\t\t\t\t// The inner call to fetchData has already traversed through the remainder\n\t\t\t\t\t\t\t// of the source requested, so we exit from the loop\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse if ( funcNotation )\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t// Function call\n\t\t\t\t\t\t\ta[i] = a[i].replace(__reFn, '');\n\t\t\t\t\t\t\tdata = data[ a[i] ]();\n\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t}\n\t\n\t\t\t\t\t\tif ( data === null || data[ a[i] ] === undefined )\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\treturn undefined;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tdata = data[ a[i] ];\n\t\t\t\t\t}\n\t\t\t\t}\n\t\n\t\t\t\treturn data;\n\t\t\t};\n\t\n\t\t\treturn function (data, type) { // row and meta also passed, but not used\n\t\t\t\treturn fetchData( data, type, mSource );\n\t\t\t};\n\t\t}\n\t\telse\n\t\t{\n\t\t\t/* Array or flat object mapping */\n\t\t\treturn function (data, type) { // row and meta also passed, but not used\n\t\t\t\treturn data[mSource];\n\t\t\t};\n\t\t}\n\t}\n\t\n\t\n\t/**\n\t * Return a function that can be used to set data from a source object, taking\n\t * into account the ability to use nested objects as a source\n\t *  @param {string|int|function} mSource The data source for the object\n\t *  @returns {function} Data set function\n\t *  @memberof DataTable#oApi\n\t */\n\tfunction _fnSetObjectDataFn( mSource )\n\t{\n\t\tif ( $.isPlainObject( mSource ) )\n\t\t{\n\t\t\t/* Unlike get, only the underscore (global) option is used for for\n\t\t\t * setting data since we don't know the type here. This is why an object\n\t\t\t * option is not documented for `mData` (which is read/write), but it is\n\t\t\t * for `mRender` which is read only.\n\t\t\t */\n\t\t\treturn _fnSetObjectDataFn( mSource._ );\n\t\t}\n\t\telse if ( mSource === null )\n\t\t{\n\t\t\t/* Nothing to do when the data source is null */\n\t\t\treturn function () {};\n\t\t}\n\t\telse if ( typeof mSource === 'function' )\n\t\t{\n\t\t\treturn function (data, val, meta) {\n\t\t\t\tmSource( data, 'set', val, meta );\n\t\t\t};\n\t\t}\n\t\telse if ( typeof mSource === 'string' && (mSource.indexOf('.') !== -1 ||\n\t\t\t      mSource.indexOf('[') !== -1 || mSource.indexOf('(') !== -1) )\n\t\t{\n\t\t\t/* Like the get, we need to get data from a nested object */\n\t\t\tvar setData = function (data, val, src) {\n\t\t\t\tvar a = _fnSplitObjNotation( src ), b;\n\t\t\t\tvar aLast = a[a.length-1];\n\t\t\t\tvar arrayNotation, funcNotation, o, innerSrc;\n\t\n\t\t\t\tfor ( var i=0, iLen=a.length-1 ; i<iLen ; i++ )\n\t\t\t\t{\n\t\t\t\t\t// Check if we are dealing with an array notation request\n\t\t\t\t\tarrayNotation = a[i].match(__reArray);\n\t\t\t\t\tfuncNotation = a[i].match(__reFn);\n\t\n\t\t\t\t\tif ( arrayNotation )\n\t\t\t\t\t{\n\t\t\t\t\t\ta[i] = a[i].replace(__reArray, '');\n\t\t\t\t\t\tdata[ a[i] ] = [];\n\t\n\t\t\t\t\t\t// Get the remainder of the nested object to set so we can recurse\n\t\t\t\t\t\tb = a.slice();\n\t\t\t\t\t\tb.splice( 0, i+1 );\n\t\t\t\t\t\tinnerSrc = b.join('.');\n\t\n\t\t\t\t\t\t// Traverse each entry in the array setting the properties requested\n\t\t\t\t\t\tif ( $.isArray( val ) )\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tfor ( var j=0, jLen=val.length ; j<jLen ; j++ )\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\to = {};\n\t\t\t\t\t\t\t\tsetData( o, val[j], innerSrc );\n\t\t\t\t\t\t\t\tdata[ a[i] ].push( o );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t// We've been asked to save data to an array, but it\n\t\t\t\t\t\t\t// isn't array data to be saved. Best that can be done\n\t\t\t\t\t\t\t// is to just save the value.\n\t\t\t\t\t\t\tdata[ a[i] ] = val;\n\t\t\t\t\t\t}\n\t\n\t\t\t\t\t\t// The inner call to setData has already traversed through the remainder\n\t\t\t\t\t\t// of the source and has set the data, thus we can exit here\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\telse if ( funcNotation )\n\t\t\t\t\t{\n\t\t\t\t\t\t// Function call\n\t\t\t\t\t\ta[i] = a[i].replace(__reFn, '');\n\t\t\t\t\t\tdata = data[ a[i] ]( val );\n\t\t\t\t\t}\n\t\n\t\t\t\t\t// If the nested object doesn't currently exist - since we are\n\t\t\t\t\t// trying to set the value - create it\n\t\t\t\t\tif ( data[ a[i] ] === null || data[ a[i] ] === undefined )\n\t\t\t\t\t{\n\t\t\t\t\t\tdata[ a[i] ] = {};\n\t\t\t\t\t}\n\t\t\t\t\tdata = data[ a[i] ];\n\t\t\t\t}\n\t\n\t\t\t\t// Last item in the input - i.e, the actual set\n\t\t\t\tif ( aLast.match(__reFn ) )\n\t\t\t\t{\n\t\t\t\t\t// Function call\n\t\t\t\t\tdata = data[ aLast.replace(__reFn, '') ]( val );\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\t// If array notation is used, we just want to strip it and use the property name\n\t\t\t\t\t// and assign the value. If it isn't used, then we get the result we want anyway\n\t\t\t\t\tdata[ aLast.replace(__reArray, '') ] = val;\n\t\t\t\t}\n\t\t\t};\n\t\n\t\t\treturn function (data, val) { // meta is also passed in, but not used\n\t\t\t\treturn setData( data, val, mSource );\n\t\t\t};\n\t\t}\n\t\telse\n\t\t{\n\t\t\t/* Array or flat object mapping */\n\t\t\treturn function (data, val) { // meta is also passed in, but not used\n\t\t\t\tdata[mSource] = val;\n\t\t\t};\n\t\t}\n\t}\n\t\n\t\n\t/**\n\t * Return an array with the full table data\n\t *  @param {object} oSettings dataTables settings object\n\t *  @returns array {array} aData Master data array\n\t *  @memberof DataTable#oApi\n\t */\n\tfunction _fnGetDataMaster ( settings )\n\t{\n\t\treturn _pluck( settings.aoData, '_aData' );\n\t}\n\t\n\t\n\t/**\n\t * Nuke the table\n\t *  @param {object} oSettings dataTables settings object\n\t *  @memberof DataTable#oApi\n\t */\n\tfunction _fnClearTable( settings )\n\t{\n\t\tsettings.aoData.length = 0;\n\t\tsettings.aiDisplayMaster.length = 0;\n\t\tsettings.aiDisplay.length = 0;\n\t\tsettings.aIds = {};\n\t}\n\t\n\t\n\t /**\n\t * Take an array of integers (index array) and remove a target integer (value - not\n\t * the key!)\n\t *  @param {array} a Index array to target\n\t *  @param {int} iTarget value to find\n\t *  @memberof DataTable#oApi\n\t */\n\tfunction _fnDeleteIndex( a, iTarget, splice )\n\t{\n\t\tvar iTargetIndex = -1;\n\t\n\t\tfor ( var i=0, iLen=a.length ; i<iLen ; i++ )\n\t\t{\n\t\t\tif ( a[i] == iTarget )\n\t\t\t{\n\t\t\t\tiTargetIndex = i;\n\t\t\t}\n\t\t\telse if ( a[i] > iTarget )\n\t\t\t{\n\t\t\t\ta[i]--;\n\t\t\t}\n\t\t}\n\t\n\t\tif ( iTargetIndex != -1 && splice === undefined )\n\t\t{\n\t\t\ta.splice( iTargetIndex, 1 );\n\t\t}\n\t}\n\t\n\t\n\t/**\n\t * Mark cached data as invalid such that a re-read of the data will occur when\n\t * the cached data is next requested. Also update from the data source object.\n\t *\n\t * @param {object} settings DataTables settings object\n\t * @param {int}    rowIdx   Row index to invalidate\n\t * @param {string} [src]    Source to invalidate from: undefined, 'auto', 'dom'\n\t *     or 'data'\n\t * @param {int}    [colIdx] Column index to invalidate. If undefined the whole\n\t *     row will be invalidated\n\t * @memberof DataTable#oApi\n\t *\n\t * @todo For the modularisation of v1.11 this will need to become a callback, so\n\t *   the sort and filter methods can subscribe to it. That will required\n\t *   initialisation options for sorting, which is why it is not already baked in\n\t */\n\tfunction _fnInvalidate( settings, rowIdx, src, colIdx )\n\t{\n\t\tvar row = settings.aoData[ rowIdx ];\n\t\tvar i, ien;\n\t\tvar cellWrite = function ( cell, col ) {\n\t\t\t// This is very frustrating, but in IE if you just write directly\n\t\t\t// to innerHTML, and elements that are overwritten are GC'ed,\n\t\t\t// even if there is a reference to them elsewhere\n\t\t\twhile ( cell.childNodes.length ) {\n\t\t\t\tcell.removeChild( cell.firstChild );\n\t\t\t}\n\t\n\t\t\tcell.innerHTML = _fnGetCellData( settings, rowIdx, col, 'display' );\n\t\t};\n\t\n\t\t// Are we reading last data from DOM or the data object?\n\t\tif ( src === 'dom' || ((! src || src === 'auto') && row.src === 'dom') ) {\n\t\t\t// Read the data from the DOM\n\t\t\trow._aData = _fnGetRowElements(\n\t\t\t\t\tsettings, row, colIdx, colIdx === undefined ? undefined : row._aData\n\t\t\t\t)\n\t\t\t\t.data;\n\t\t}\n\t\telse {\n\t\t\t// Reading from data object, update the DOM\n\t\t\tvar cells = row.anCells;\n\t\n\t\t\tif ( cells ) {\n\t\t\t\tif ( colIdx !== undefined ) {\n\t\t\t\t\tcellWrite( cells[colIdx], colIdx );\n\t\t\t\t}\n\t\t\t\telse {\n\t\t\t\t\tfor ( i=0, ien=cells.length ; i<ien ; i++ ) {\n\t\t\t\t\t\tcellWrite( cells[i], i );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\n\t\t// For both row and cell invalidation, the cached data for sorting and\n\t\t// filtering is nulled out\n\t\trow._aSortData = null;\n\t\trow._aFilterData = null;\n\t\n\t\t// Invalidate the type for a specific column (if given) or all columns since\n\t\t// the data might have changed\n\t\tvar cols = settings.aoColumns;\n\t\tif ( colIdx !== undefined ) {\n\t\t\tcols[ colIdx ].sType = null;\n\t\t}\n\t\telse {\n\t\t\tfor ( i=0, ien=cols.length ; i<ien ; i++ ) {\n\t\t\t\tcols[i].sType = null;\n\t\t\t}\n\t\n\t\t\t// Update DataTables special `DT_*` attributes for the row\n\t\t\t_fnRowAttributes( settings, row );\n\t\t}\n\t}\n\t\n\t\n\t/**\n\t * Build a data source object from an HTML row, reading the contents of the\n\t * cells that are in the row.\n\t *\n\t * @param {object} settings DataTables settings object\n\t * @param {node|object} TR element from which to read data or existing row\n\t *   object from which to re-read the data from the cells\n\t * @param {int} [colIdx] Optional column index\n\t * @param {array|object} [d] Data source object. If `colIdx` is given then this\n\t *   parameter should also be given and will be used to write the data into.\n\t *   Only the column in question will be written\n\t * @returns {object} Object with two parameters: `data` the data read, in\n\t *   document order, and `cells` and array of nodes (they can be useful to the\n\t *   caller, so rather than needing a second traversal to get them, just return\n\t *   them from here).\n\t * @memberof DataTable#oApi\n\t */\n\tfunction _fnGetRowElements( settings, row, colIdx, d )\n\t{\n\t\tvar\n\t\t\ttds = [],\n\t\t\ttd = row.firstChild,\n\t\t\tname, col, o, i=0, contents,\n\t\t\tcolumns = settings.aoColumns,\n\t\t\tobjectRead = settings._rowReadObject;\n\t\n\t\t// Allow the data object to be passed in, or construct\n\t\td = d !== undefined ?\n\t\t\td :\n\t\t\tobjectRead ?\n\t\t\t\t{} :\n\t\t\t\t[];\n\t\n\t\tvar attr = function ( str, td  ) {\n\t\t\tif ( typeof str === 'string' ) {\n\t\t\t\tvar idx = str.indexOf('@');\n\t\n\t\t\t\tif ( idx !== -1 ) {\n\t\t\t\t\tvar attr = str.substring( idx+1 );\n\t\t\t\t\tvar setter = _fnSetObjectDataFn( str );\n\t\t\t\t\tsetter( d, td.getAttribute( attr ) );\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\t\n\t\t// Read data from a cell and store into the data object\n\t\tvar cellProcess = function ( cell ) {\n\t\t\tif ( colIdx === undefined || colIdx === i ) {\n\t\t\t\tcol = columns[i];\n\t\t\t\tcontents = $.trim(cell.innerHTML);\n\t\n\t\t\t\tif ( col && col._bAttrSrc ) {\n\t\t\t\t\tvar setter = _fnSetObjectDataFn( col.mData._ );\n\t\t\t\t\tsetter( d, contents );\n\t\n\t\t\t\t\tattr( col.mData.sort, cell );\n\t\t\t\t\tattr( col.mData.type, cell );\n\t\t\t\t\tattr( col.mData.filter, cell );\n\t\t\t\t}\n\t\t\t\telse {\n\t\t\t\t\t// Depending on the `data` option for the columns the data can\n\t\t\t\t\t// be read to either an object or an array.\n\t\t\t\t\tif ( objectRead ) {\n\t\t\t\t\t\tif ( ! col._setter ) {\n\t\t\t\t\t\t\t// Cache the setter function\n\t\t\t\t\t\t\tcol._setter = _fnSetObjectDataFn( col.mData );\n\t\t\t\t\t\t}\n\t\t\t\t\t\tcol._setter( d, contents );\n\t\t\t\t\t}\n\t\t\t\t\telse {\n\t\t\t\t\t\td[i] = contents;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\n\t\t\ti++;\n\t\t};\n\t\n\t\tif ( td ) {\n\t\t\t// `tr` element was passed in\n\t\t\twhile ( td ) {\n\t\t\t\tname = td.nodeName.toUpperCase();\n\t\n\t\t\t\tif ( name == \"TD\" || name == \"TH\" ) {\n\t\t\t\t\tcellProcess( td );\n\t\t\t\t\ttds.push( td );\n\t\t\t\t}\n\t\n\t\t\t\ttd = td.nextSibling;\n\t\t\t}\n\t\t}\n\t\telse {\n\t\t\t// Existing row object passed in\n\t\t\ttds = row.anCells;\n\t\n\t\t\tfor ( var j=0, jen=tds.length ; j<jen ; j++ ) {\n\t\t\t\tcellProcess( tds[j] );\n\t\t\t}\n\t\t}\n\t\n\t\t// Read the ID from the DOM if present\n\t\tvar rowNode = row.firstChild ? row : row.nTr;\n\t\n\t\tif ( rowNode ) {\n\t\t\tvar id = rowNode.getAttribute( 'id' );\n\t\n\t\t\tif ( id ) {\n\t\t\t\t_fnSetObjectDataFn( settings.rowId )( d, id );\n\t\t\t}\n\t\t}\n\t\n\t\treturn {\n\t\t\tdata: d,\n\t\t\tcells: tds\n\t\t};\n\t}\n\t/**\n\t * Create a new TR element (and it's TD children) for a row\n\t *  @param {object} oSettings dataTables settings object\n\t *  @param {int} iRow Row to consider\n\t *  @param {node} [nTrIn] TR element to add to the table - optional. If not given,\n\t *    DataTables will create a row automatically\n\t *  @param {array} [anTds] Array of TD|TH elements for the row - must be given\n\t *    if nTr is.\n\t *  @memberof DataTable#oApi\n\t */\n\tfunction _fnCreateTr ( oSettings, iRow, nTrIn, anTds )\n\t{\n\t\tvar\n\t\t\trow = oSettings.aoData[iRow],\n\t\t\trowData = row._aData,\n\t\t\tcells = [],\n\t\t\tnTr, nTd, oCol,\n\t\t\ti, iLen;\n\t\n\t\tif ( row.nTr === null )\n\t\t{\n\t\t\tnTr = nTrIn || document.createElement('tr');\n\t\n\t\t\trow.nTr = nTr;\n\t\t\trow.anCells = cells;\n\t\n\t\t\t/* Use a private property on the node to allow reserve mapping from the node\n\t\t\t * to the aoData array for fast look up\n\t\t\t */\n\t\t\tnTr._DT_RowIndex = iRow;\n\t\n\t\t\t/* Special parameters can be given by the data source to be used on the row */\n\t\t\t_fnRowAttributes( oSettings, row );\n\t\n\t\t\t/* Process each column */\n\t\t\tfor ( i=0, iLen=oSettings.aoColumns.length ; i<iLen ; i++ )\n\t\t\t{\n\t\t\t\toCol = oSettings.aoColumns[i];\n\t\n\t\t\t\tnTd = nTrIn ? anTds[i] : document.createElement( oCol.sCellType );\n\t\t\t\tnTd._DT_CellIndex = {\n\t\t\t\t\trow: iRow,\n\t\t\t\t\tcolumn: i\n\t\t\t\t};\n\t\t\t\t\n\t\t\t\tcells.push( nTd );\n\t\n\t\t\t\t// Need to create the HTML if new, or if a rendering function is defined\n\t\t\t\tif ( (!nTrIn || oCol.mRender || oCol.mData !== i) &&\n\t\t\t\t\t (!$.isPlainObject(oCol.mData) || oCol.mData._ !== i+'.display')\n\t\t\t\t) {\n\t\t\t\t\tnTd.innerHTML = _fnGetCellData( oSettings, iRow, i, 'display' );\n\t\t\t\t}\n\t\n\t\t\t\t/* Add user defined class */\n\t\t\t\tif ( oCol.sClass )\n\t\t\t\t{\n\t\t\t\t\tnTd.className += ' '+oCol.sClass;\n\t\t\t\t}\n\t\n\t\t\t\t// Visibility - add or remove as required\n\t\t\t\tif ( oCol.bVisible && ! nTrIn )\n\t\t\t\t{\n\t\t\t\t\tnTr.appendChild( nTd );\n\t\t\t\t}\n\t\t\t\telse if ( ! oCol.bVisible && nTrIn )\n\t\t\t\t{\n\t\t\t\t\tnTd.parentNode.removeChild( nTd );\n\t\t\t\t}\n\t\n\t\t\t\tif ( oCol.fnCreatedCell )\n\t\t\t\t{\n\t\t\t\t\toCol.fnCreatedCell.call( oSettings.oInstance,\n\t\t\t\t\t\tnTd, _fnGetCellData( oSettings, iRow, i ), rowData, iRow, i\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t}\n\t\n\t\t\t_fnCallbackFire( oSettings, 'aoRowCreatedCallback', null, [nTr, rowData, iRow] );\n\t\t}\n\t\n\t\t// Remove once webkit bug 131819 and Chromium bug 365619 have been resolved\n\t\t// and deployed\n\t\trow.nTr.setAttribute( 'role', 'row' );\n\t}\n\t\n\t\n\t/**\n\t * Add attributes to a row based on the special `DT_*` parameters in a data\n\t * source object.\n\t *  @param {object} settings DataTables settings object\n\t *  @param {object} DataTables row object for the row to be modified\n\t *  @memberof DataTable#oApi\n\t */\n\tfunction _fnRowAttributes( settings, row )\n\t{\n\t\tvar tr = row.nTr;\n\t\tvar data = row._aData;\n\t\n\t\tif ( tr ) {\n\t\t\tvar id = settings.rowIdFn( data );\n\t\n\t\t\tif ( id ) {\n\t\t\t\ttr.id = id;\n\t\t\t}\n\t\n\t\t\tif ( data.DT_RowClass ) {\n\t\t\t\t// Remove any classes added by DT_RowClass before\n\t\t\t\tvar a = data.DT_RowClass.split(' ');\n\t\t\t\trow.__rowc = row.__rowc ?\n\t\t\t\t\t_unique( row.__rowc.concat( a ) ) :\n\t\t\t\t\ta;\n\t\n\t\t\t\t$(tr)\n\t\t\t\t\t.removeClass( row.__rowc.join(' ') )\n\t\t\t\t\t.addClass( data.DT_RowClass );\n\t\t\t}\n\t\n\t\t\tif ( data.DT_RowAttr ) {\n\t\t\t\t$(tr).attr( data.DT_RowAttr );\n\t\t\t}\n\t\n\t\t\tif ( data.DT_RowData ) {\n\t\t\t\t$(tr).data( data.DT_RowData );\n\t\t\t}\n\t\t}\n\t}\n\t\n\t\n\t/**\n\t * Create the HTML header for the table\n\t *  @param {object} oSettings dataTables settings object\n\t *  @memberof DataTable#oApi\n\t */\n\tfunction _fnBuildHead( oSettings )\n\t{\n\t\tvar i, ien, cell, row, column;\n\t\tvar thead = oSettings.nTHead;\n\t\tvar tfoot = oSettings.nTFoot;\n\t\tvar createHeader = $('th, td', thead).length === 0;\n\t\tvar classes = oSettings.oClasses;\n\t\tvar columns = oSettings.aoColumns;\n\t\n\t\tif ( createHeader ) {\n\t\t\trow = $('<tr/>').appendTo( thead );\n\t\t}\n\t\n\t\tfor ( i=0, ien=columns.length ; i<ien ; i++ ) {\n\t\t\tcolumn = columns[i];\n\t\t\tcell = $( column.nTh ).addClass( column.sClass );\n\t\n\t\t\tif ( createHeader ) {\n\t\t\t\tcell.appendTo( row );\n\t\t\t}\n\t\n\t\t\t// 1.11 move into sorting\n\t\t\tif ( oSettings.oFeatures.bSort ) {\n\t\t\t\tcell.addClass( column.sSortingClass );\n\t\n\t\t\t\tif ( column.bSortable !== false ) {\n\t\t\t\t\tcell\n\t\t\t\t\t\t.attr( 'tabindex', oSettings.iTabIndex )\n\t\t\t\t\t\t.attr( 'aria-controls', oSettings.sTableId );\n\t\n\t\t\t\t\t_fnSortAttachListener( oSettings, column.nTh, i );\n\t\t\t\t}\n\t\t\t}\n\t\n\t\t\tif ( column.sTitle != cell[0].innerHTML ) {\n\t\t\t\tcell.html( column.sTitle );\n\t\t\t}\n\t\n\t\t\t_fnRenderer( oSettings, 'header' )(\n\t\t\t\toSettings, cell, column, classes\n\t\t\t);\n\t\t}\n\t\n\t\tif ( createHeader ) {\n\t\t\t_fnDetectHeader( oSettings.aoHeader, thead );\n\t\t}\n\t\t\n\t\t/* ARIA role for the rows */\n\t \t$(thead).find('>tr').attr('role', 'row');\n\t\n\t\t/* Deal with the footer - add classes if required */\n\t\t$(thead).find('>tr>th, >tr>td').addClass( classes.sHeaderTH );\n\t\t$(tfoot).find('>tr>th, >tr>td').addClass( classes.sFooterTH );\n\t\n\t\t// Cache the footer cells. Note that we only take the cells from the first\n\t\t// row in the footer. If there is more than one row the user wants to\n\t\t// interact with, they need to use the table().foot() method. Note also this\n\t\t// allows cells to be used for multiple columns using colspan\n\t\tif ( tfoot !== null ) {\n\t\t\tvar cells = oSettings.aoFooter[0];\n\t\n\t\t\tfor ( i=0, ien=cells.length ; i<ien ; i++ ) {\n\t\t\t\tcolumn = columns[i];\n\t\t\t\tcolumn.nTf = cells[i].cell;\n\t\n\t\t\t\tif ( column.sClass ) {\n\t\t\t\t\t$(column.nTf).addClass( column.sClass );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\t\n\t\n\t/**\n\t * Draw the header (or footer) element based on the column visibility states. The\n\t * methodology here is to use the layout array from _fnDetectHeader, modified for\n\t * the instantaneous column visibility, to construct the new layout. The grid is\n\t * traversed over cell at a time in a rows x columns grid fashion, although each\n\t * cell insert can cover multiple elements in the grid - which is tracks using the\n\t * aApplied array. Cell inserts in the grid will only occur where there isn't\n\t * already a cell in that position.\n\t *  @param {object} oSettings dataTables settings object\n\t *  @param array {objects} aoSource Layout array from _fnDetectHeader\n\t *  @param {boolean} [bIncludeHidden=false] If true then include the hidden columns in the calc,\n\t *  @memberof DataTable#oApi\n\t */\n\tfunction _fnDrawHead( oSettings, aoSource, bIncludeHidden )\n\t{\n\t\tvar i, iLen, j, jLen, k, kLen, n, nLocalTr;\n\t\tvar aoLocal = [];\n\t\tvar aApplied = [];\n\t\tvar iColumns = oSettings.aoColumns.length;\n\t\tvar iRowspan, iColspan;\n\t\n\t\tif ( ! aoSource )\n\t\t{\n\t\t\treturn;\n\t\t}\n\t\n\t\tif (  bIncludeHidden === undefined )\n\t\t{\n\t\t\tbIncludeHidden = false;\n\t\t}\n\t\n\t\t/* Make a copy of the master layout array, but without the visible columns in it */\n\t\tfor ( i=0, iLen=aoSource.length ; i<iLen ; i++ )\n\t\t{\n\t\t\taoLocal[i] = aoSource[i].slice();\n\t\t\taoLocal[i].nTr = aoSource[i].nTr;\n\t\n\t\t\t/* Remove any columns which are currently hidden */\n\t\t\tfor ( j=iColumns-1 ; j>=0 ; j-- )\n\t\t\t{\n\t\t\t\tif ( !oSettings.aoColumns[j].bVisible && !bIncludeHidden )\n\t\t\t\t{\n\t\t\t\t\taoLocal[i].splice( j, 1 );\n\t\t\t\t}\n\t\t\t}\n\t\n\t\t\t/* Prep the applied array - it needs an element for each row */\n\t\t\taApplied.push( [] );\n\t\t}\n\t\n\t\tfor ( i=0, iLen=aoLocal.length ; i<iLen ; i++ )\n\t\t{\n\t\t\tnLocalTr = aoLocal[i].nTr;\n\t\n\t\t\t/* All cells are going to be replaced, so empty out the row */\n\t\t\tif ( nLocalTr )\n\t\t\t{\n\t\t\t\twhile( (n = nLocalTr.firstChild) )\n\t\t\t\t{\n\t\t\t\t\tnLocalTr.removeChild( n );\n\t\t\t\t}\n\t\t\t}\n\t\n\t\t\tfor ( j=0, jLen=aoLocal[i].length ; j<jLen ; j++ )\n\t\t\t{\n\t\t\t\tiRowspan = 1;\n\t\t\t\tiColspan = 1;\n\t\n\t\t\t\t/* Check to see if there is already a cell (row/colspan) covering our target\n\t\t\t\t * insert point. If there is, then there is nothing to do.\n\t\t\t\t */\n\t\t\t\tif ( aApplied[i][j] === undefined )\n\t\t\t\t{\n\t\t\t\t\tnLocalTr.appendChild( aoLocal[i][j].cell );\n\t\t\t\t\taApplied[i][j] = 1;\n\t\n\t\t\t\t\t/* Expand the cell to cover as many rows as needed */\n\t\t\t\t\twhile ( aoLocal[i+iRowspan] !== undefined &&\n\t\t\t\t\t        aoLocal[i][j].cell == aoLocal[i+iRowspan][j].cell )\n\t\t\t\t\t{\n\t\t\t\t\t\taApplied[i+iRowspan][j] = 1;\n\t\t\t\t\t\tiRowspan++;\n\t\t\t\t\t}\n\t\n\t\t\t\t\t/* Expand the cell to cover as many columns as needed */\n\t\t\t\t\twhile ( aoLocal[i][j+iColspan] !== undefined &&\n\t\t\t\t\t        aoLocal[i][j].cell == aoLocal[i][j+iColspan].cell )\n\t\t\t\t\t{\n\t\t\t\t\t\t/* Must update the applied array over the rows for the columns */\n\t\t\t\t\t\tfor ( k=0 ; k<iRowspan ; k++ )\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\taApplied[i+k][j+iColspan] = 1;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tiColspan++;\n\t\t\t\t\t}\n\t\n\t\t\t\t\t/* Do the actual expansion in the DOM */\n\t\t\t\t\t$(aoLocal[i][j].cell)\n\t\t\t\t\t\t.attr('rowspan', iRowspan)\n\t\t\t\t\t\t.attr('colspan', iColspan);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\t\n\t\n\t/**\n\t * Insert the required TR nodes into the table for display\n\t *  @param {object} oSettings dataTables settings object\n\t *  @memberof DataTable#oApi\n\t */\n\tfunction _fnDraw( oSettings )\n\t{\n\t\t/* Provide a pre-callback function which can be used to cancel the draw is false is returned */\n\t\tvar aPreDraw = _fnCallbackFire( oSettings, 'aoPreDrawCallback', 'preDraw', [oSettings] );\n\t\tif ( $.inArray( false, aPreDraw ) !== -1 )\n\t\t{\n\t\t\t_fnProcessingDisplay( oSettings, false );\n\t\t\treturn;\n\t\t}\n\t\n\t\tvar i, iLen, n;\n\t\tvar anRows = [];\n\t\tvar iRowCount = 0;\n\t\tvar asStripeClasses = oSettings.asStripeClasses;\n\t\tvar iStripes = asStripeClasses.length;\n\t\tvar iOpenRows = oSettings.aoOpenRows.length;\n\t\tvar oLang = oSettings.oLanguage;\n\t\tvar iInitDisplayStart = oSettings.iInitDisplayStart;\n\t\tvar bServerSide = _fnDataSource( oSettings ) == 'ssp';\n\t\tvar aiDisplay = oSettings.aiDisplay;\n\t\n\t\toSettings.bDrawing = true;\n\t\n\t\t/* Check and see if we have an initial draw position from state saving */\n\t\tif ( iInitDisplayStart !== undefined && iInitDisplayStart !== -1 )\n\t\t{\n\t\t\toSettings._iDisplayStart = bServerSide ?\n\t\t\t\tiInitDisplayStart :\n\t\t\t\tiInitDisplayStart >= oSettings.fnRecordsDisplay() ?\n\t\t\t\t\t0 :\n\t\t\t\t\tiInitDisplayStart;\n\t\n\t\t\toSettings.iInitDisplayStart = -1;\n\t\t}\n\t\n\t\tvar iDisplayStart = oSettings._iDisplayStart;\n\t\tvar iDisplayEnd = oSettings.fnDisplayEnd();\n\t\n\t\t/* Server-side processing draw intercept */\n\t\tif ( oSettings.bDeferLoading )\n\t\t{\n\t\t\toSettings.bDeferLoading = false;\n\t\t\toSettings.iDraw++;\n\t\t\t_fnProcessingDisplay( oSettings, false );\n\t\t}\n\t\telse if ( !bServerSide )\n\t\t{\n\t\t\toSettings.iDraw++;\n\t\t}\n\t\telse if ( !oSettings.bDestroying && !_fnAjaxUpdate( oSettings ) )\n\t\t{\n\t\t\treturn;\n\t\t}\n\t\n\t\tif ( aiDisplay.length !== 0 )\n\t\t{\n\t\t\tvar iStart = bServerSide ? 0 : iDisplayStart;\n\t\t\tvar iEnd = bServerSide ? oSettings.aoData.length : iDisplayEnd;\n\t\n\t\t\tfor ( var j=iStart ; j<iEnd ; j++ )\n\t\t\t{\n\t\t\t\tvar iDataIndex = aiDisplay[j];\n\t\t\t\tvar aoData = oSettings.aoData[ iDataIndex ];\n\t\t\t\tif ( aoData.nTr === null )\n\t\t\t\t{\n\t\t\t\t\t_fnCreateTr( oSettings, iDataIndex );\n\t\t\t\t}\n\t\n\t\t\t\tvar nRow = aoData.nTr;\n\t\n\t\t\t\t/* Remove the old striping classes and then add the new one */\n\t\t\t\tif ( iStripes !== 0 )\n\t\t\t\t{\n\t\t\t\t\tvar sStripe = asStripeClasses[ iRowCount % iStripes ];\n\t\t\t\t\tif ( aoData._sRowStripe != sStripe )\n\t\t\t\t\t{\n\t\t\t\t\t\t$(nRow).removeClass( aoData._sRowStripe ).addClass( sStripe );\n\t\t\t\t\t\taoData._sRowStripe = sStripe;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\n\t\t\t\t// Row callback functions - might want to manipulate the row\n\t\t\t\t// iRowCount and j are not currently documented. Are they at all\n\t\t\t\t// useful?\n\t\t\t\t_fnCallbackFire( oSettings, 'aoRowCallback', null,\n\t\t\t\t\t[nRow, aoData._aData, iRowCount, j] );\n\t\n\t\t\t\tanRows.push( nRow );\n\t\t\t\tiRowCount++;\n\t\t\t}\n\t\t}\n\t\telse\n\t\t{\n\t\t\t/* Table is empty - create a row with an empty message in it */\n\t\t\tvar sZero = oLang.sZeroRecords;\n\t\t\tif ( oSettings.iDraw == 1 &&  _fnDataSource( oSettings ) == 'ajax' )\n\t\t\t{\n\t\t\t\tsZero = oLang.sLoadingRecords;\n\t\t\t}\n\t\t\telse if ( oLang.sEmptyTable && oSettings.fnRecordsTotal() === 0 )\n\t\t\t{\n\t\t\t\tsZero = oLang.sEmptyTable;\n\t\t\t}\n\t\n\t\t\tanRows[ 0 ] = $( '<tr/>', { 'class': iStripes ? asStripeClasses[0] : '' } )\n\t\t\t\t.append( $('<td />', {\n\t\t\t\t\t'valign':  'top',\n\t\t\t\t\t'colSpan': _fnVisbleColumns( oSettings ),\n\t\t\t\t\t'class':   oSettings.oClasses.sRowEmpty\n\t\t\t\t} ).html( sZero ) )[0];\n\t\t}\n\t\n\t\t/* Header and footer callbacks */\n\t\t_fnCallbackFire( oSettings, 'aoHeaderCallback', 'header', [ $(oSettings.nTHead).children('tr')[0],\n\t\t\t_fnGetDataMaster( oSettings ), iDisplayStart, iDisplayEnd, aiDisplay ] );\n\t\n\t\t_fnCallbackFire( oSettings, 'aoFooterCallback', 'footer', [ $(oSettings.nTFoot).children('tr')[0],\n\t\t\t_fnGetDataMaster( oSettings ), iDisplayStart, iDisplayEnd, aiDisplay ] );\n\t\n\t\tvar body = $(oSettings.nTBody);\n\t\n\t\tbody.children().detach();\n\t\tbody.append( $(anRows) );\n\t\n\t\t/* Call all required callback functions for the end of a draw */\n\t\t_fnCallbackFire( oSettings, 'aoDrawCallback', 'draw', [oSettings] );\n\t\n\t\t/* Draw is complete, sorting and filtering must be as well */\n\t\toSettings.bSorted = false;\n\t\toSettings.bFiltered = false;\n\t\toSettings.bDrawing = false;\n\t}\n\t\n\t\n\t/**\n\t * Redraw the table - taking account of the various features which are enabled\n\t *  @param {object} oSettings dataTables settings object\n\t *  @param {boolean} [holdPosition] Keep the current paging position. By default\n\t *    the paging is reset to the first page\n\t *  @memberof DataTable#oApi\n\t */\n\tfunction _fnReDraw( settings, holdPosition )\n\t{\n\t\tvar\n\t\t\tfeatures = settings.oFeatures,\n\t\t\tsort     = features.bSort,\n\t\t\tfilter   = features.bFilter;\n\t\n\t\tif ( sort ) {\n\t\t\t_fnSort( settings );\n\t\t}\n\t\n\t\tif ( filter ) {\n\t\t\t_fnFilterComplete( settings, settings.oPreviousSearch );\n\t\t}\n\t\telse {\n\t\t\t// No filtering, so we want to just use the display master\n\t\t\tsettings.aiDisplay = settings.aiDisplayMaster.slice();\n\t\t}\n\t\n\t\tif ( holdPosition !== true ) {\n\t\t\tsettings._iDisplayStart = 0;\n\t\t}\n\t\n\t\t// Let any modules know about the draw hold position state (used by\n\t\t// scrolling internally)\n\t\tsettings._drawHold = holdPosition;\n\t\n\t\t_fnDraw( settings );\n\t\n\t\tsettings._drawHold = false;\n\t}\n\t\n\t\n\t/**\n\t * Add the options to the page HTML for the table\n\t *  @param {object} oSettings dataTables settings object\n\t *  @memberof DataTable#oApi\n\t */\n\tfunction _fnAddOptionsHtml ( oSettings )\n\t{\n\t\tvar classes = oSettings.oClasses;\n\t\tvar table = $(oSettings.nTable);\n\t\tvar holding = $('<div/>').insertBefore( table ); // Holding element for speed\n\t\tvar features = oSettings.oFeatures;\n\t\n\t\t// All DataTables are wrapped in a div\n\t\tvar insert = $('<div/>', {\n\t\t\tid:      oSettings.sTableId+'_wrapper',\n\t\t\t'class': classes.sWrapper + (oSettings.nTFoot ? '' : ' '+classes.sNoFooter)\n\t\t} );\n\t\n\t\toSettings.nHolding = holding[0];\n\t\toSettings.nTableWrapper = insert[0];\n\t\toSettings.nTableReinsertBefore = oSettings.nTable.nextSibling;\n\t\n\t\t/* Loop over the user set positioning and place the elements as needed */\n\t\tvar aDom = oSettings.sDom.split('');\n\t\tvar featureNode, cOption, nNewNode, cNext, sAttr, j;\n\t\tfor ( var i=0 ; i<aDom.length ; i++ )\n\t\t{\n\t\t\tfeatureNode = null;\n\t\t\tcOption = aDom[i];\n\t\n\t\t\tif ( cOption == '<' )\n\t\t\t{\n\t\t\t\t/* New container div */\n\t\t\t\tnNewNode = $('<div/>')[0];\n\t\n\t\t\t\t/* Check to see if we should append an id and/or a class name to the container */\n\t\t\t\tcNext = aDom[i+1];\n\t\t\t\tif ( cNext == \"'\" || cNext == '\"' )\n\t\t\t\t{\n\t\t\t\t\tsAttr = \"\";\n\t\t\t\t\tj = 2;\n\t\t\t\t\twhile ( aDom[i+j] != cNext )\n\t\t\t\t\t{\n\t\t\t\t\t\tsAttr += aDom[i+j];\n\t\t\t\t\t\tj++;\n\t\t\t\t\t}\n\t\n\t\t\t\t\t/* Replace jQuery UI constants @todo depreciated */\n\t\t\t\t\tif ( sAttr == \"H\" )\n\t\t\t\t\t{\n\t\t\t\t\t\tsAttr = classes.sJUIHeader;\n\t\t\t\t\t}\n\t\t\t\t\telse if ( sAttr == \"F\" )\n\t\t\t\t\t{\n\t\t\t\t\t\tsAttr = classes.sJUIFooter;\n\t\t\t\t\t}\n\t\n\t\t\t\t\t/* The attribute can be in the format of \"#id.class\", \"#id\" or \"class\" This logic\n\t\t\t\t\t * breaks the string into parts and applies them as needed\n\t\t\t\t\t */\n\t\t\t\t\tif ( sAttr.indexOf('.') != -1 )\n\t\t\t\t\t{\n\t\t\t\t\t\tvar aSplit = sAttr.split('.');\n\t\t\t\t\t\tnNewNode.id = aSplit[0].substr(1, aSplit[0].length-1);\n\t\t\t\t\t\tnNewNode.className = aSplit[1];\n\t\t\t\t\t}\n\t\t\t\t\telse if ( sAttr.charAt(0) == \"#\" )\n\t\t\t\t\t{\n\t\t\t\t\t\tnNewNode.id = sAttr.substr(1, sAttr.length-1);\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\tnNewNode.className = sAttr;\n\t\t\t\t\t}\n\t\n\t\t\t\t\ti += j; /* Move along the position array */\n\t\t\t\t}\n\t\n\t\t\t\tinsert.append( nNewNode );\n\t\t\t\tinsert = $(nNewNode);\n\t\t\t}\n\t\t\telse if ( cOption == '>' )\n\t\t\t{\n\t\t\t\t/* End container div */\n\t\t\t\tinsert = insert.parent();\n\t\t\t}\n\t\t\t// @todo Move options into their own plugins?\n\t\t\telse if ( cOption == 'l' && features.bPaginate && features.bLengthChange )\n\t\t\t{\n\t\t\t\t/* Length */\n\t\t\t\tfeatureNode = _fnFeatureHtmlLength( oSettings );\n\t\t\t}\n\t\t\telse if ( cOption == 'f' && features.bFilter )\n\t\t\t{\n\t\t\t\t/* Filter */\n\t\t\t\tfeatureNode = _fnFeatureHtmlFilter( oSettings );\n\t\t\t}\n\t\t\telse if ( cOption == 'r' && features.bProcessing )\n\t\t\t{\n\t\t\t\t/* pRocessing */\n\t\t\t\tfeatureNode = _fnFeatureHtmlProcessing( oSettings );\n\t\t\t}\n\t\t\telse if ( cOption == 't' )\n\t\t\t{\n\t\t\t\t/* Table */\n\t\t\t\tfeatureNode = _fnFeatureHtmlTable( oSettings );\n\t\t\t}\n\t\t\telse if ( cOption ==  'i' && features.bInfo )\n\t\t\t{\n\t\t\t\t/* Info */\n\t\t\t\tfeatureNode = _fnFeatureHtmlInfo( oSettings );\n\t\t\t}\n\t\t\telse if ( cOption == 'p' && features.bPaginate )\n\t\t\t{\n\t\t\t\t/* Pagination */\n\t\t\t\tfeatureNode = _fnFeatureHtmlPaginate( oSettings );\n\t\t\t}\n\t\t\telse if ( DataTable.ext.feature.length !== 0 )\n\t\t\t{\n\t\t\t\t/* Plug-in features */\n\t\t\t\tvar aoFeatures = DataTable.ext.feature;\n\t\t\t\tfor ( var k=0, kLen=aoFeatures.length ; k<kLen ; k++ )\n\t\t\t\t{\n\t\t\t\t\tif ( cOption == aoFeatures[k].cFeature )\n\t\t\t\t\t{\n\t\t\t\t\t\tfeatureNode = aoFeatures[k].fnInit( oSettings );\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\n\t\t\t/* Add to the 2D features array */\n\t\t\tif ( featureNode )\n\t\t\t{\n\t\t\t\tvar aanFeatures = oSettings.aanFeatures;\n\t\n\t\t\t\tif ( ! aanFeatures[cOption] )\n\t\t\t\t{\n\t\t\t\t\taanFeatures[cOption] = [];\n\t\t\t\t}\n\t\n\t\t\t\taanFeatures[cOption].push( featureNode );\n\t\t\t\tinsert.append( featureNode );\n\t\t\t}\n\t\t}\n\t\n\t\t/* Built our DOM structure - replace the holding div with what we want */\n\t\tholding.replaceWith( insert );\n\t\toSettings.nHolding = null;\n\t}\n\t\n\t\n\t/**\n\t * Use the DOM source to create up an array of header cells. The idea here is to\n\t * create a layout grid (array) of rows x columns, which contains a reference\n\t * to the cell that that point in the grid (regardless of col/rowspan), such that\n\t * any column / row could be removed and the new grid constructed\n\t *  @param array {object} aLayout Array to store the calculated layout in\n\t *  @param {node} nThead The header/footer element for the table\n\t *  @memberof DataTable#oApi\n\t */\n\tfunction _fnDetectHeader ( aLayout, nThead )\n\t{\n\t\tvar nTrs = $(nThead).children('tr');\n\t\tvar nTr, nCell;\n\t\tvar i, k, l, iLen, jLen, iColShifted, iColumn, iColspan, iRowspan;\n\t\tvar bUnique;\n\t\tvar fnShiftCol = function ( a, i, j ) {\n\t\t\tvar k = a[i];\n\t                while ( k[j] ) {\n\t\t\t\tj++;\n\t\t\t}\n\t\t\treturn j;\n\t\t};\n\t\n\t\taLayout.splice( 0, aLayout.length );\n\t\n\t\t/* We know how many rows there are in the layout - so prep it */\n\t\tfor ( i=0, iLen=nTrs.length ; i<iLen ; i++ )\n\t\t{\n\t\t\taLayout.push( [] );\n\t\t}\n\t\n\t\t/* Calculate a layout array */\n\t\tfor ( i=0, iLen=nTrs.length ; i<iLen ; i++ )\n\t\t{\n\t\t\tnTr = nTrs[i];\n\t\t\tiColumn = 0;\n\t\n\t\t\t/* For every cell in the row... */\n\t\t\tnCell = nTr.firstChild;\n\t\t\twhile ( nCell ) {\n\t\t\t\tif ( nCell.nodeName.toUpperCase() == \"TD\" ||\n\t\t\t\t     nCell.nodeName.toUpperCase() == \"TH\" )\n\t\t\t\t{\n\t\t\t\t\t/* Get the col and rowspan attributes from the DOM and sanitise them */\n\t\t\t\t\tiColspan = nCell.getAttribute('colspan') * 1;\n\t\t\t\t\tiRowspan = nCell.getAttribute('rowspan') * 1;\n\t\t\t\t\tiColspan = (!iColspan || iColspan===0 || iColspan===1) ? 1 : iColspan;\n\t\t\t\t\tiRowspan = (!iRowspan || iRowspan===0 || iRowspan===1) ? 1 : iRowspan;\n\t\n\t\t\t\t\t/* There might be colspan cells already in this row, so shift our target\n\t\t\t\t\t * accordingly\n\t\t\t\t\t */\n\t\t\t\t\tiColShifted = fnShiftCol( aLayout, i, iColumn );\n\t\n\t\t\t\t\t/* Cache calculation for unique columns */\n\t\t\t\t\tbUnique = iColspan === 1 ? true : false;\n\t\n\t\t\t\t\t/* If there is col / rowspan, copy the information into the layout grid */\n\t\t\t\t\tfor ( l=0 ; l<iColspan ; l++ )\n\t\t\t\t\t{\n\t\t\t\t\t\tfor ( k=0 ; k<iRowspan ; k++ )\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\taLayout[i+k][iColShifted+l] = {\n\t\t\t\t\t\t\t\t\"cell\": nCell,\n\t\t\t\t\t\t\t\t\"unique\": bUnique\n\t\t\t\t\t\t\t};\n\t\t\t\t\t\t\taLayout[i+k].nTr = nTr;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tnCell = nCell.nextSibling;\n\t\t\t}\n\t\t}\n\t}\n\t\n\t\n\t/**\n\t * Get an array of unique th elements, one for each column\n\t *  @param {object} oSettings dataTables settings object\n\t *  @param {node} nHeader automatically detect the layout from this node - optional\n\t *  @param {array} aLayout thead/tfoot layout from _fnDetectHeader - optional\n\t *  @returns array {node} aReturn list of unique th's\n\t *  @memberof DataTable#oApi\n\t */\n\tfunction _fnGetUniqueThs ( oSettings, nHeader, aLayout )\n\t{\n\t\tvar aReturn = [];\n\t\tif ( !aLayout )\n\t\t{\n\t\t\taLayout = oSettings.aoHeader;\n\t\t\tif ( nHeader )\n\t\t\t{\n\t\t\t\taLayout = [];\n\t\t\t\t_fnDetectHeader( aLayout, nHeader );\n\t\t\t}\n\t\t}\n\t\n\t\tfor ( var i=0, iLen=aLayout.length ; i<iLen ; i++ )\n\t\t{\n\t\t\tfor ( var j=0, jLen=aLayout[i].length ; j<jLen ; j++ )\n\t\t\t{\n\t\t\t\tif ( aLayout[i][j].unique &&\n\t\t\t\t\t (!aReturn[j] || !oSettings.bSortCellsTop) )\n\t\t\t\t{\n\t\t\t\t\taReturn[j] = aLayout[i][j].cell;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\n\t\treturn aReturn;\n\t}\n\t\n\t/**\n\t * Create an Ajax call based on the table's settings, taking into account that\n\t * parameters can have multiple forms, and backwards compatibility.\n\t *\n\t * @param {object} oSettings dataTables settings object\n\t * @param {array} data Data to send to the server, required by\n\t *     DataTables - may be augmented by developer callbacks\n\t * @param {function} fn Callback function to run when data is obtained\n\t */\n\tfunction _fnBuildAjax( oSettings, data, fn )\n\t{\n\t\t// Compatibility with 1.9-, allow fnServerData and event to manipulate\n\t\t_fnCallbackFire( oSettings, 'aoServerParams', 'serverParams', [data] );\n\t\n\t\t// Convert to object based for 1.10+ if using the old array scheme which can\n\t\t// come from server-side processing or serverParams\n\t\tif ( data && $.isArray(data) ) {\n\t\t\tvar tmp = {};\n\t\t\tvar rbracket = /(.*?)\\[\\]$/;\n\t\n\t\t\t$.each( data, function (key, val) {\n\t\t\t\tvar match = val.name.match(rbracket);\n\t\n\t\t\t\tif ( match ) {\n\t\t\t\t\t// Support for arrays\n\t\t\t\t\tvar name = match[0];\n\t\n\t\t\t\t\tif ( ! tmp[ name ] ) {\n\t\t\t\t\t\ttmp[ name ] = [];\n\t\t\t\t\t}\n\t\t\t\t\ttmp[ name ].push( val.value );\n\t\t\t\t}\n\t\t\t\telse {\n\t\t\t\t\ttmp[val.name] = val.value;\n\t\t\t\t}\n\t\t\t} );\n\t\t\tdata = tmp;\n\t\t}\n\t\n\t\tvar ajaxData;\n\t\tvar ajax = oSettings.ajax;\n\t\tvar instance = oSettings.oInstance;\n\t\tvar callback = function ( json ) {\n\t\t\t_fnCallbackFire( oSettings, null, 'xhr', [oSettings, json, oSettings.jqXHR] );\n\t\t\tfn( json );\n\t\t};\n\t\n\t\tif ( $.isPlainObject( ajax ) && ajax.data )\n\t\t{\n\t\t\tajaxData = ajax.data;\n\t\n\t\t\tvar newData = $.isFunction( ajaxData ) ?\n\t\t\t\tajaxData( data, oSettings ) :  // fn can manipulate data or return\n\t\t\t\tajaxData;                      // an object object or array to merge\n\t\n\t\t\t// If the function returned something, use that alone\n\t\t\tdata = $.isFunction( ajaxData ) && newData ?\n\t\t\t\tnewData :\n\t\t\t\t$.extend( true, data, newData );\n\t\n\t\t\t// Remove the data property as we've resolved it already and don't want\n\t\t\t// jQuery to do it again (it is restored at the end of the function)\n\t\t\tdelete ajax.data;\n\t\t}\n\t\n\t\tvar baseAjax = {\n\t\t\t\"data\": data,\n\t\t\t\"success\": function (json) {\n\t\t\t\tvar error = json.error || json.sError;\n\t\t\t\tif ( error ) {\n\t\t\t\t\t_fnLog( oSettings, 0, error );\n\t\t\t\t}\n\t\n\t\t\t\toSettings.json = json;\n\t\t\t\tcallback( json );\n\t\t\t},\n\t\t\t\"dataType\": \"json\",\n\t\t\t\"cache\": false,\n\t\t\t\"type\": oSettings.sServerMethod,\n\t\t\t\"error\": function (xhr, error, thrown) {\n\t\t\t\tvar ret = _fnCallbackFire( oSettings, null, 'xhr', [oSettings, null, oSettings.jqXHR] );\n\t\n\t\t\t\tif ( $.inArray( true, ret ) === -1 ) {\n\t\t\t\t\tif ( error == \"parsererror\" ) {\n\t\t\t\t\t\t_fnLog( oSettings, 0, 'Invalid JSON response', 1 );\n\t\t\t\t\t}\n\t\t\t\t\telse if ( xhr.readyState === 4 ) {\n\t\t\t\t\t\t_fnLog( oSettings, 0, 'Ajax error', 7 );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\n\t\t\t\t_fnProcessingDisplay( oSettings, false );\n\t\t\t}\n\t\t};\n\t\n\t\t// Store the data submitted for the API\n\t\toSettings.oAjaxData = data;\n\t\n\t\t// Allow plug-ins and external processes to modify the data\n\t\t_fnCallbackFire( oSettings, null, 'preXhr', [oSettings, data] );\n\t\n\t\tif ( oSettings.fnServerData )\n\t\t{\n\t\t\t// DataTables 1.9- compatibility\n\t\t\toSettings.fnServerData.call( instance,\n\t\t\t\toSettings.sAjaxSource,\n\t\t\t\t$.map( data, function (val, key) { // Need to convert back to 1.9 trad format\n\t\t\t\t\treturn { name: key, value: val };\n\t\t\t\t} ),\n\t\t\t\tcallback,\n\t\t\t\toSettings\n\t\t\t);\n\t\t}\n\t\telse if ( oSettings.sAjaxSource || typeof ajax === 'string' )\n\t\t{\n\t\t\t// DataTables 1.9- compatibility\n\t\t\toSettings.jqXHR = $.ajax( $.extend( baseAjax, {\n\t\t\t\turl: ajax || oSettings.sAjaxSource\n\t\t\t} ) );\n\t\t}\n\t\telse if ( $.isFunction( ajax ) )\n\t\t{\n\t\t\t// Is a function - let the caller define what needs to be done\n\t\t\toSettings.jqXHR = ajax.call( instance, data, callback, oSettings );\n\t\t}\n\t\telse\n\t\t{\n\t\t\t// Object to extend the base settings\n\t\t\toSettings.jqXHR = $.ajax( $.extend( baseAjax, ajax ) );\n\t\n\t\t\t// Restore for next time around\n\t\t\tajax.data = ajaxData;\n\t\t}\n\t}\n\t\n\t\n\t/**\n\t * Update the table using an Ajax call\n\t *  @param {object} settings dataTables settings object\n\t *  @returns {boolean} Block the table drawing or not\n\t *  @memberof DataTable#oApi\n\t */\n\tfunction _fnAjaxUpdate( settings )\n\t{\n\t\tif ( settings.bAjaxDataGet ) {\n\t\t\tsettings.iDraw++;\n\t\t\t_fnProcessingDisplay( settings, true );\n\t\n\t\t\t_fnBuildAjax(\n\t\t\t\tsettings,\n\t\t\t\t_fnAjaxParameters( settings ),\n\t\t\t\tfunction(json) {\n\t\t\t\t\t_fnAjaxUpdateDraw( settings, json );\n\t\t\t\t}\n\t\t\t);\n\t\n\t\t\treturn false;\n\t\t}\n\t\treturn true;\n\t}\n\t\n\t\n\t/**\n\t * Build up the parameters in an object needed for a server-side processing\n\t * request. Note that this is basically done twice, is different ways - a modern\n\t * method which is used by default in DataTables 1.10 which uses objects and\n\t * arrays, or the 1.9- method with is name / value pairs. 1.9 method is used if\n\t * the sAjaxSource option is used in the initialisation, or the legacyAjax\n\t * option is set.\n\t *  @param {object} oSettings dataTables settings object\n\t *  @returns {bool} block the table drawing or not\n\t *  @memberof DataTable#oApi\n\t */\n\tfunction _fnAjaxParameters( settings )\n\t{\n\t\tvar\n\t\t\tcolumns = settings.aoColumns,\n\t\t\tcolumnCount = columns.length,\n\t\t\tfeatures = settings.oFeatures,\n\t\t\tpreSearch = settings.oPreviousSearch,\n\t\t\tpreColSearch = settings.aoPreSearchCols,\n\t\t\ti, data = [], dataProp, column, columnSearch,\n\t\t\tsort = _fnSortFlatten( settings ),\n\t\t\tdisplayStart = settings._iDisplayStart,\n\t\t\tdisplayLength = features.bPaginate !== false ?\n\t\t\t\tsettings._iDisplayLength :\n\t\t\t\t-1;\n\t\n\t\tvar param = function ( name, value ) {\n\t\t\tdata.push( { 'name': name, 'value': value } );\n\t\t};\n\t\n\t\t// DataTables 1.9- compatible method\n\t\tparam( 'sEcho',          settings.iDraw );\n\t\tparam( 'iColumns',       columnCount );\n\t\tparam( 'sColumns',       _pluck( columns, 'sName' ).join(',') );\n\t\tparam( 'iDisplayStart',  displayStart );\n\t\tparam( 'iDisplayLength', displayLength );\n\t\n\t\t// DataTables 1.10+ method\n\t\tvar d = {\n\t\t\tdraw:    settings.iDraw,\n\t\t\tcolumns: [],\n\t\t\torder:   [],\n\t\t\tstart:   displayStart,\n\t\t\tlength:  displayLength,\n\t\t\tsearch:  {\n\t\t\t\tvalue: preSearch.sSearch,\n\t\t\t\tregex: preSearch.bRegex\n\t\t\t}\n\t\t};\n\t\n\t\tfor ( i=0 ; i<columnCount ; i++ ) {\n\t\t\tcolumn = columns[i];\n\t\t\tcolumnSearch = preColSearch[i];\n\t\t\tdataProp = typeof column.mData==\"function\" ? 'function' : column.mData ;\n\t\n\t\t\td.columns.push( {\n\t\t\t\tdata:       dataProp,\n\t\t\t\tname:       column.sName,\n\t\t\t\tsearchable: column.bSearchable,\n\t\t\t\torderable:  column.bSortable,\n\t\t\t\tsearch:     {\n\t\t\t\t\tvalue: columnSearch.sSearch,\n\t\t\t\t\tregex: columnSearch.bRegex\n\t\t\t\t}\n\t\t\t} );\n\t\n\t\t\tparam( \"mDataProp_\"+i, dataProp );\n\t\n\t\t\tif ( features.bFilter ) {\n\t\t\t\tparam( 'sSearch_'+i,     columnSearch.sSearch );\n\t\t\t\tparam( 'bRegex_'+i,      columnSearch.bRegex );\n\t\t\t\tparam( 'bSearchable_'+i, column.bSearchable );\n\t\t\t}\n\t\n\t\t\tif ( features.bSort ) {\n\t\t\t\tparam( 'bSortable_'+i, column.bSortable );\n\t\t\t}\n\t\t}\n\t\n\t\tif ( features.bFilter ) {\n\t\t\tparam( 'sSearch', preSearch.sSearch );\n\t\t\tparam( 'bRegex', preSearch.bRegex );\n\t\t}\n\t\n\t\tif ( features.bSort ) {\n\t\t\t$.each( sort, function ( i, val ) {\n\t\t\t\td.order.push( { column: val.col, dir: val.dir } );\n\t\n\t\t\t\tparam( 'iSortCol_'+i, val.col );\n\t\t\t\tparam( 'sSortDir_'+i, val.dir );\n\t\t\t} );\n\t\n\t\t\tparam( 'iSortingCols', sort.length );\n\t\t}\n\t\n\t\t// If the legacy.ajax parameter is null, then we automatically decide which\n\t\t// form to use, based on sAjaxSource\n\t\tvar legacy = DataTable.ext.legacy.ajax;\n\t\tif ( legacy === null ) {\n\t\t\treturn settings.sAjaxSource ? data : d;\n\t\t}\n\t\n\t\t// Otherwise, if legacy has been specified then we use that to decide on the\n\t\t// form\n\t\treturn legacy ? data : d;\n\t}\n\t\n\t\n\t/**\n\t * Data the data from the server (nuking the old) and redraw the table\n\t *  @param {object} oSettings dataTables settings object\n\t *  @param {object} json json data return from the server.\n\t *  @param {string} json.sEcho Tracking flag for DataTables to match requests\n\t *  @param {int} json.iTotalRecords Number of records in the data set, not accounting for filtering\n\t *  @param {int} json.iTotalDisplayRecords Number of records in the data set, accounting for filtering\n\t *  @param {array} json.aaData The data to display on this page\n\t *  @param {string} [json.sColumns] Column ordering (sName, comma separated)\n\t *  @memberof DataTable#oApi\n\t */\n\tfunction _fnAjaxUpdateDraw ( settings, json )\n\t{\n\t\t// v1.10 uses camelCase variables, while 1.9 uses Hungarian notation.\n\t\t// Support both\n\t\tvar compat = function ( old, modern ) {\n\t\t\treturn json[old] !== undefined ? json[old] : json[modern];\n\t\t};\n\t\n\t\tvar data = _fnAjaxDataSrc( settings, json );\n\t\tvar draw            = compat( 'sEcho',                'draw' );\n\t\tvar recordsTotal    = compat( 'iTotalRecords',        'recordsTotal' );\n\t\tvar recordsFiltered = compat( 'iTotalDisplayRecords', 'recordsFiltered' );\n\t\n\t\tif ( draw ) {\n\t\t\t// Protect against out of sequence returns\n\t\t\tif ( draw*1 < settings.iDraw ) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tsettings.iDraw = draw * 1;\n\t\t}\n\t\n\t\t_fnClearTable( settings );\n\t\tsettings._iRecordsTotal   = parseInt(recordsTotal, 10);\n\t\tsettings._iRecordsDisplay = parseInt(recordsFiltered, 10);\n\t\n\t\tfor ( var i=0, ien=data.length ; i<ien ; i++ ) {\n\t\t\t_fnAddData( settings, data[i] );\n\t\t}\n\t\tsettings.aiDisplay = settings.aiDisplayMaster.slice();\n\t\n\t\tsettings.bAjaxDataGet = false;\n\t\t_fnDraw( settings );\n\t\n\t\tif ( ! settings._bInitComplete ) {\n\t\t\t_fnInitComplete( settings, json );\n\t\t}\n\t\n\t\tsettings.bAjaxDataGet = true;\n\t\t_fnProcessingDisplay( settings, false );\n\t}\n\t\n\t\n\t/**\n\t * Get the data from the JSON data source to use for drawing a table. Using\n\t * `_fnGetObjectDataFn` allows the data to be sourced from a property of the\n\t * source object, or from a processing function.\n\t *  @param {object} oSettings dataTables settings object\n\t *  @param  {object} json Data source object / array from the server\n\t *  @return {array} Array of data to use\n\t */\n\tfunction _fnAjaxDataSrc ( oSettings, json )\n\t{\n\t\tvar dataSrc = $.isPlainObject( oSettings.ajax ) && oSettings.ajax.dataSrc !== undefined ?\n\t\t\toSettings.ajax.dataSrc :\n\t\t\toSettings.sAjaxDataProp; // Compatibility with 1.9-.\n\t\n\t\t// Compatibility with 1.9-. In order to read from aaData, check if the\n\t\t// default has been changed, if not, check for aaData\n\t\tif ( dataSrc === 'data' ) {\n\t\t\treturn json.aaData || json[dataSrc];\n\t\t}\n\t\n\t\treturn dataSrc !== \"\" ?\n\t\t\t_fnGetObjectDataFn( dataSrc )( json ) :\n\t\t\tjson;\n\t}\n\t\n\t/**\n\t * Generate the node required for filtering text\n\t *  @returns {node} Filter control element\n\t *  @param {object} oSettings dataTables settings object\n\t *  @memberof DataTable#oApi\n\t */\n\tfunction _fnFeatureHtmlFilter ( settings )\n\t{\n\t\tvar classes = settings.oClasses;\n\t\tvar tableId = settings.sTableId;\n\t\tvar language = settings.oLanguage;\n\t\tvar previousSearch = settings.oPreviousSearch;\n\t\tvar features = settings.aanFeatures;\n\t\tvar input = '<input type=\"search\" class=\"'+classes.sFilterInput+'\"/>';\n\t\n\t\tvar str = language.sSearch;\n\t\tstr = str.match(/_INPUT_/) ?\n\t\t\tstr.replace('_INPUT_', input) :\n\t\t\tstr+input;\n\t\n\t\tvar filter = $('<div/>', {\n\t\t\t\t'id': ! features.f ? tableId+'_filter' : null,\n\t\t\t\t'class': classes.sFilter\n\t\t\t} )\n\t\t\t.append( $('<label/>' ).append( str ) );\n\t\n\t\tvar searchFn = function() {\n\t\t\t/* Update all other filter input elements for the new display */\n\t\t\tvar n = features.f;\n\t\t\tvar val = !this.value ? \"\" : this.value; // mental IE8 fix :-(\n\t\n\t\t\t/* Now do the filter */\n\t\t\tif ( val != previousSearch.sSearch ) {\n\t\t\t\t_fnFilterComplete( settings, {\n\t\t\t\t\t\"sSearch\": val,\n\t\t\t\t\t\"bRegex\": previousSearch.bRegex,\n\t\t\t\t\t\"bSmart\": previousSearch.bSmart ,\n\t\t\t\t\t\"bCaseInsensitive\": previousSearch.bCaseInsensitive\n\t\t\t\t} );\n\t\n\t\t\t\t// Need to redraw, without resorting\n\t\t\t\tsettings._iDisplayStart = 0;\n\t\t\t\t_fnDraw( settings );\n\t\t\t}\n\t\t};\n\t\n\t\tvar searchDelay = settings.searchDelay !== null ?\n\t\t\tsettings.searchDelay :\n\t\t\t_fnDataSource( settings ) === 'ssp' ?\n\t\t\t\t400 :\n\t\t\t\t0;\n\t\n\t\tvar jqFilter = $('input', filter)\n\t\t\t.val( previousSearch.sSearch )\n\t\t\t.attr( 'placeholder', language.sSearchPlaceholder )\n\t\t\t.bind(\n\t\t\t\t'keyup.DT search.DT input.DT paste.DT cut.DT',\n\t\t\t\tsearchDelay ?\n\t\t\t\t\t_fnThrottle( searchFn, searchDelay ) :\n\t\t\t\t\tsearchFn\n\t\t\t)\n\t\t\t.bind( 'keypress.DT', function(e) {\n\t\t\t\t/* Prevent form submission */\n\t\t\t\tif ( e.keyCode == 13 ) {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t} )\n\t\t\t.attr('aria-controls', tableId);\n\t\n\t\t// Update the input elements whenever the table is filtered\n\t\t$(settings.nTable).on( 'search.dt.DT', function ( ev, s ) {\n\t\t\tif ( settings === s ) {\n\t\t\t\t// IE9 throws an 'unknown error' if document.activeElement is used\n\t\t\t\t// inside an iframe or frame...\n\t\t\t\ttry {\n\t\t\t\t\tif ( jqFilter[0] !== document.activeElement ) {\n\t\t\t\t\t\tjqFilter.val( previousSearch.sSearch );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tcatch ( e ) {}\n\t\t\t}\n\t\t} );\n\t\n\t\treturn filter[0];\n\t}\n\t\n\t\n\t/**\n\t * Filter the table using both the global filter and column based filtering\n\t *  @param {object} oSettings dataTables settings object\n\t *  @param {object} oSearch search information\n\t *  @param {int} [iForce] force a research of the master array (1) or not (undefined or 0)\n\t *  @memberof DataTable#oApi\n\t */\n\tfunction _fnFilterComplete ( oSettings, oInput, iForce )\n\t{\n\t\tvar oPrevSearch = oSettings.oPreviousSearch;\n\t\tvar aoPrevSearch = oSettings.aoPreSearchCols;\n\t\tvar fnSaveFilter = function ( oFilter ) {\n\t\t\t/* Save the filtering values */\n\t\t\toPrevSearch.sSearch = oFilter.sSearch;\n\t\t\toPrevSearch.bRegex = oFilter.bRegex;\n\t\t\toPrevSearch.bSmart = oFilter.bSmart;\n\t\t\toPrevSearch.bCaseInsensitive = oFilter.bCaseInsensitive;\n\t\t};\n\t\tvar fnRegex = function ( o ) {\n\t\t\t// Backwards compatibility with the bEscapeRegex option\n\t\t\treturn o.bEscapeRegex !== undefined ? !o.bEscapeRegex : o.bRegex;\n\t\t};\n\t\n\t\t// Resolve any column types that are unknown due to addition or invalidation\n\t\t// @todo As per sort - can this be moved into an event handler?\n\t\t_fnColumnTypes( oSettings );\n\t\n\t\t/* In server-side processing all filtering is done by the server, so no point hanging around here */\n\t\tif ( _fnDataSource( oSettings ) != 'ssp' )\n\t\t{\n\t\t\t/* Global filter */\n\t\t\t_fnFilter( oSettings, oInput.sSearch, iForce, fnRegex(oInput), oInput.bSmart, oInput.bCaseInsensitive );\n\t\t\tfnSaveFilter( oInput );\n\t\n\t\t\t/* Now do the individual column filter */\n\t\t\tfor ( var i=0 ; i<aoPrevSearch.length ; i++ )\n\t\t\t{\n\t\t\t\t_fnFilterColumn( oSettings, aoPrevSearch[i].sSearch, i, fnRegex(aoPrevSearch[i]),\n\t\t\t\t\taoPrevSearch[i].bSmart, aoPrevSearch[i].bCaseInsensitive );\n\t\t\t}\n\t\n\t\t\t/* Custom filtering */\n\t\t\t_fnFilterCustom( oSettings );\n\t\t}\n\t\telse\n\t\t{\n\t\t\tfnSaveFilter( oInput );\n\t\t}\n\t\n\t\t/* Tell the draw function we have been filtering */\n\t\toSettings.bFiltered = true;\n\t\t_fnCallbackFire( oSettings, null, 'search', [oSettings] );\n\t}\n\t\n\t\n\t/**\n\t * Apply custom filtering functions\n\t *  @param {object} oSettings dataTables settings object\n\t *  @memberof DataTable#oApi\n\t */\n\tfunction _fnFilterCustom( settings )\n\t{\n\t\tvar filters = DataTable.ext.search;\n\t\tvar displayRows = settings.aiDisplay;\n\t\tvar row, rowIdx;\n\t\n\t\tfor ( var i=0, ien=filters.length ; i<ien ; i++ ) {\n\t\t\tvar rows = [];\n\t\n\t\t\t// Loop over each row and see if it should be included\n\t\t\tfor ( var j=0, jen=displayRows.length ; j<jen ; j++ ) {\n\t\t\t\trowIdx = displayRows[ j ];\n\t\t\t\trow = settings.aoData[ rowIdx ];\n\t\n\t\t\t\tif ( filters[i]( settings, row._aFilterData, rowIdx, row._aData, j ) ) {\n\t\t\t\t\trows.push( rowIdx );\n\t\t\t\t}\n\t\t\t}\n\t\n\t\t\t// So the array reference doesn't break set the results into the\n\t\t\t// existing array\n\t\t\tdisplayRows.length = 0;\n\t\t\t$.merge( displayRows, rows );\n\t\t}\n\t}\n\t\n\t\n\t/**\n\t * Filter the table on a per-column basis\n\t *  @param {object} oSettings dataTables settings object\n\t *  @param {string} sInput string to filter on\n\t *  @param {int} iColumn column to filter\n\t *  @param {bool} bRegex treat search string as a regular expression or not\n\t *  @param {bool} bSmart use smart filtering or not\n\t *  @param {bool} bCaseInsensitive Do case insenstive matching or not\n\t *  @memberof DataTable#oApi\n\t */\n\tfunction _fnFilterColumn ( settings, searchStr, colIdx, regex, smart, caseInsensitive )\n\t{\n\t\tif ( searchStr === '' ) {\n\t\t\treturn;\n\t\t}\n\t\n\t\tvar data;\n\t\tvar display = settings.aiDisplay;\n\t\tvar rpSearch = _fnFilterCreateSearch( searchStr, regex, smart, caseInsensitive );\n\t\n\t\tfor ( var i=display.length-1 ; i>=0 ; i-- ) {\n\t\t\tdata = settings.aoData[ display[i] ]._aFilterData[ colIdx ];\n\t\n\t\t\tif ( ! rpSearch.test( data ) ) {\n\t\t\t\tdisplay.splice( i, 1 );\n\t\t\t}\n\t\t}\n\t}\n\t\n\t\n\t/**\n\t * Filter the data table based on user input and draw the table\n\t *  @param {object} settings dataTables settings object\n\t *  @param {string} input string to filter on\n\t *  @param {int} force optional - force a research of the master array (1) or not (undefined or 0)\n\t *  @param {bool} regex treat as a regular expression or not\n\t *  @param {bool} smart perform smart filtering or not\n\t *  @param {bool} caseInsensitive Do case insenstive matching or not\n\t *  @memberof DataTable#oApi\n\t */\n\tfunction _fnFilter( settings, input, force, regex, smart, caseInsensitive )\n\t{\n\t\tvar rpSearch = _fnFilterCreateSearch( input, regex, smart, caseInsensitive );\n\t\tvar prevSearch = settings.oPreviousSearch.sSearch;\n\t\tvar displayMaster = settings.aiDisplayMaster;\n\t\tvar display, invalidated, i;\n\t\n\t\t// Need to take account of custom filtering functions - always filter\n\t\tif ( DataTable.ext.search.length !== 0 ) {\n\t\t\tforce = true;\n\t\t}\n\t\n\t\t// Check if any of the rows were invalidated\n\t\tinvalidated = _fnFilterData( settings );\n\t\n\t\t// If the input is blank - we just want the full data set\n\t\tif ( input.length <= 0 ) {\n\t\t\tsettings.aiDisplay = displayMaster.slice();\n\t\t}\n\t\telse {\n\t\t\t// New search - start from the master array\n\t\t\tif ( invalidated ||\n\t\t\t\t force ||\n\t\t\t\t prevSearch.length > input.length ||\n\t\t\t\t input.indexOf(prevSearch) !== 0 ||\n\t\t\t\t settings.bSorted // On resort, the display master needs to be\n\t\t\t\t                  // re-filtered since indexes will have changed\n\t\t\t) {\n\t\t\t\tsettings.aiDisplay = displayMaster.slice();\n\t\t\t}\n\t\n\t\t\t// Search the display array\n\t\t\tdisplay = settings.aiDisplay;\n\t\n\t\t\tfor ( i=display.length-1 ; i>=0 ; i-- ) {\n\t\t\t\tif ( ! rpSearch.test( settings.aoData[ display[i] ]._sFilterRow ) ) {\n\t\t\t\t\tdisplay.splice( i, 1 );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\t\n\t\n\t/**\n\t * Build a regular expression object suitable for searching a table\n\t *  @param {string} sSearch string to search for\n\t *  @param {bool} bRegex treat as a regular expression or not\n\t *  @param {bool} bSmart perform smart filtering or not\n\t *  @param {bool} bCaseInsensitive Do case insensitive matching or not\n\t *  @returns {RegExp} constructed object\n\t *  @memberof DataTable#oApi\n\t */\n\tfunction _fnFilterCreateSearch( search, regex, smart, caseInsensitive )\n\t{\n\t\tsearch = regex ?\n\t\t\tsearch :\n\t\t\t_fnEscapeRegex( search );\n\t\t\n\t\tif ( smart ) {\n\t\t\t/* For smart filtering we want to allow the search to work regardless of\n\t\t\t * word order. We also want double quoted text to be preserved, so word\n\t\t\t * order is important - a la google. So this is what we want to\n\t\t\t * generate:\n\t\t\t * \n\t\t\t * ^(?=.*?\\bone\\b)(?=.*?\\btwo three\\b)(?=.*?\\bfour\\b).*$\n\t\t\t */\n\t\t\tvar a = $.map( search.match( /\"[^\"]+\"|[^ ]+/g ) || [''], function ( word ) {\n\t\t\t\tif ( word.charAt(0) === '\"' ) {\n\t\t\t\t\tvar m = word.match( /^\"(.*)\"$/ );\n\t\t\t\t\tword = m ? m[1] : word;\n\t\t\t\t}\n\t\n\t\t\t\treturn word.replace('\"', '');\n\t\t\t} );\n\t\n\t\t\tsearch = '^(?=.*?'+a.join( ')(?=.*?' )+').*$';\n\t\t}\n\t\n\t\treturn new RegExp( search, caseInsensitive ? 'i' : '' );\n\t}\n\t\n\t\n\t/**\n\t * Escape a string such that it can be used in a regular expression\n\t *  @param {string} sVal string to escape\n\t *  @returns {string} escaped string\n\t *  @memberof DataTable#oApi\n\t */\n\tvar _fnEscapeRegex = DataTable.util.escapeRegex;\n\t\n\tvar __filter_div = $('<div>')[0];\n\tvar __filter_div_textContent = __filter_div.textContent !== undefined;\n\t\n\t// Update the filtering data for each row if needed (by invalidation or first run)\n\tfunction _fnFilterData ( settings )\n\t{\n\t\tvar columns = settings.aoColumns;\n\t\tvar column;\n\t\tvar i, j, ien, jen, filterData, cellData, row;\n\t\tvar fomatters = DataTable.ext.type.search;\n\t\tvar wasInvalidated = false;\n\t\n\t\tfor ( i=0, ien=settings.aoData.length ; i<ien ; i++ ) {\n\t\t\trow = settings.aoData[i];\n\t\n\t\t\tif ( ! row._aFilterData ) {\n\t\t\t\tfilterData = [];\n\t\n\t\t\t\tfor ( j=0, jen=columns.length ; j<jen ; j++ ) {\n\t\t\t\t\tcolumn = columns[j];\n\t\n\t\t\t\t\tif ( column.bSearchable ) {\n\t\t\t\t\t\tcellData = _fnGetCellData( settings, i, j, 'filter' );\n\t\n\t\t\t\t\t\tif ( fomatters[ column.sType ] ) {\n\t\t\t\t\t\t\tcellData = fomatters[ column.sType ]( cellData );\n\t\t\t\t\t\t}\n\t\n\t\t\t\t\t\t// Search in DataTables 1.10 is string based. In 1.11 this\n\t\t\t\t\t\t// should be altered to also allow strict type checking.\n\t\t\t\t\t\tif ( cellData === null ) {\n\t\t\t\t\t\t\tcellData = '';\n\t\t\t\t\t\t}\n\t\n\t\t\t\t\t\tif ( typeof cellData !== 'string' && cellData.toString ) {\n\t\t\t\t\t\t\tcellData = cellData.toString();\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\telse {\n\t\t\t\t\t\tcellData = '';\n\t\t\t\t\t}\n\t\n\t\t\t\t\t// If it looks like there is an HTML entity in the string,\n\t\t\t\t\t// attempt to decode it so sorting works as expected. Note that\n\t\t\t\t\t// we could use a single line of jQuery to do this, but the DOM\n\t\t\t\t\t// method used here is much faster http://jsperf.com/html-decode\n\t\t\t\t\tif ( cellData.indexOf && cellData.indexOf('&') !== -1 ) {\n\t\t\t\t\t\t__filter_div.innerHTML = cellData;\n\t\t\t\t\t\tcellData = __filter_div_textContent ?\n\t\t\t\t\t\t\t__filter_div.textContent :\n\t\t\t\t\t\t\t__filter_div.innerText;\n\t\t\t\t\t}\n\t\n\t\t\t\t\tif ( cellData.replace ) {\n\t\t\t\t\t\tcellData = cellData.replace(/[\\r\\n]/g, '');\n\t\t\t\t\t}\n\t\n\t\t\t\t\tfilterData.push( cellData );\n\t\t\t\t}\n\t\n\t\t\t\trow._aFilterData = filterData;\n\t\t\t\trow._sFilterRow = filterData.join('  ');\n\t\t\t\twasInvalidated = true;\n\t\t\t}\n\t\t}\n\t\n\t\treturn wasInvalidated;\n\t}\n\t\n\t\n\t/**\n\t * Convert from the internal Hungarian notation to camelCase for external\n\t * interaction\n\t *  @param {object} obj Object to convert\n\t *  @returns {object} Inverted object\n\t *  @memberof DataTable#oApi\n\t */\n\tfunction _fnSearchToCamel ( obj )\n\t{\n\t\treturn {\n\t\t\tsearch:          obj.sSearch,\n\t\t\tsmart:           obj.bSmart,\n\t\t\tregex:           obj.bRegex,\n\t\t\tcaseInsensitive: obj.bCaseInsensitive\n\t\t};\n\t}\n\t\n\t\n\t\n\t/**\n\t * Convert from camelCase notation to the internal Hungarian. We could use the\n\t * Hungarian convert function here, but this is cleaner\n\t *  @param {object} obj Object to convert\n\t *  @returns {object} Inverted object\n\t *  @memberof DataTable#oApi\n\t */\n\tfunction _fnSearchToHung ( obj )\n\t{\n\t\treturn {\n\t\t\tsSearch:          obj.search,\n\t\t\tbSmart:           obj.smart,\n\t\t\tbRegex:           obj.regex,\n\t\t\tbCaseInsensitive: obj.caseInsensitive\n\t\t};\n\t}\n\t\n\t/**\n\t * Generate the node required for the info display\n\t *  @param {object} oSettings dataTables settings object\n\t *  @returns {node} Information element\n\t *  @memberof DataTable#oApi\n\t */\n\tfunction _fnFeatureHtmlInfo ( settings )\n\t{\n\t\tvar\n\t\t\ttid = settings.sTableId,\n\t\t\tnodes = settings.aanFeatures.i,\n\t\t\tn = $('<div/>', {\n\t\t\t\t'class': settings.oClasses.sInfo,\n\t\t\t\t'id': ! nodes ? tid+'_info' : null\n\t\t\t} );\n\t\n\t\tif ( ! nodes ) {\n\t\t\t// Update display on each draw\n\t\t\tsettings.aoDrawCallback.push( {\n\t\t\t\t\"fn\": _fnUpdateInfo,\n\t\t\t\t\"sName\": \"information\"\n\t\t\t} );\n\t\n\t\t\tn\n\t\t\t\t.attr( 'role', 'status' )\n\t\t\t\t.attr( 'aria-live', 'polite' );\n\t\n\t\t\t// Table is described by our info div\n\t\t\t$(settings.nTable).attr( 'aria-describedby', tid+'_info' );\n\t\t}\n\t\n\t\treturn n[0];\n\t}\n\t\n\t\n\t/**\n\t * Update the information elements in the display\n\t *  @param {object} settings dataTables settings object\n\t *  @memberof DataTable#oApi\n\t */\n\tfunction _fnUpdateInfo ( settings )\n\t{\n\t\t/* Show information about the table */\n\t\tvar nodes = settings.aanFeatures.i;\n\t\tif ( nodes.length === 0 ) {\n\t\t\treturn;\n\t\t}\n\t\n\t\tvar\n\t\t\tlang  = settings.oLanguage,\n\t\t\tstart = settings._iDisplayStart+1,\n\t\t\tend   = settings.fnDisplayEnd(),\n\t\t\tmax   = settings.fnRecordsTotal(),\n\t\t\ttotal = settings.fnRecordsDisplay(),\n\t\t\tout   = total ?\n\t\t\t\tlang.sInfo :\n\t\t\t\tlang.sInfoEmpty;\n\t\n\t\tif ( total !== max ) {\n\t\t\t/* Record set after filtering */\n\t\t\tout += ' ' + lang.sInfoFiltered;\n\t\t}\n\t\n\t\t// Convert the macros\n\t\tout += lang.sInfoPostFix;\n\t\tout = _fnInfoMacros( settings, out );\n\t\n\t\tvar callback = lang.fnInfoCallback;\n\t\tif ( callback !== null ) {\n\t\t\tout = callback.call( settings.oInstance,\n\t\t\t\tsettings, start, end, max, total, out\n\t\t\t);\n\t\t}\n\t\n\t\t$(nodes).html( out );\n\t}\n\t\n\t\n\tfunction _fnInfoMacros ( settings, str )\n\t{\n\t\t// When infinite scrolling, we are always starting at 1. _iDisplayStart is used only\n\t\t// internally\n\t\tvar\n\t\t\tformatter  = settings.fnFormatNumber,\n\t\t\tstart      = settings._iDisplayStart+1,\n\t\t\tlen        = settings._iDisplayLength,\n\t\t\tvis        = settings.fnRecordsDisplay(),\n\t\t\tall        = len === -1;\n\t\n\t\treturn str.\n\t\t\treplace(/_START_/g, formatter.call( settings, start ) ).\n\t\t\treplace(/_END_/g,   formatter.call( settings, settings.fnDisplayEnd() ) ).\n\t\t\treplace(/_MAX_/g,   formatter.call( settings, settings.fnRecordsTotal() ) ).\n\t\t\treplace(/_TOTAL_/g, formatter.call( settings, vis ) ).\n\t\t\treplace(/_PAGE_/g,  formatter.call( settings, all ? 1 : Math.ceil( start / len ) ) ).\n\t\t\treplace(/_PAGES_/g, formatter.call( settings, all ? 1 : Math.ceil( vis / len ) ) );\n\t}\n\t\n\t\n\t\n\t/**\n\t * Draw the table for the first time, adding all required features\n\t *  @param {object} settings dataTables settings object\n\t *  @memberof DataTable#oApi\n\t */\n\tfunction _fnInitialise ( settings )\n\t{\n\t\tvar i, iLen, iAjaxStart=settings.iInitDisplayStart;\n\t\tvar columns = settings.aoColumns, column;\n\t\tvar features = settings.oFeatures;\n\t\tvar deferLoading = settings.bDeferLoading; // value modified by the draw\n\t\n\t\t/* Ensure that the table data is fully initialised */\n\t\tif ( ! settings.bInitialised ) {\n\t\t\tsetTimeout( function(){ _fnInitialise( settings ); }, 200 );\n\t\t\treturn;\n\t\t}\n\t\n\t\t/* Show the display HTML options */\n\t\t_fnAddOptionsHtml( settings );\n\t\n\t\t/* Build and draw the header / footer for the table */\n\t\t_fnBuildHead( settings );\n\t\t_fnDrawHead( settings, settings.aoHeader );\n\t\t_fnDrawHead( settings, settings.aoFooter );\n\t\n\t\t/* Okay to show that something is going on now */\n\t\t_fnProcessingDisplay( settings, true );\n\t\n\t\t/* Calculate sizes for columns */\n\t\tif ( features.bAutoWidth ) {\n\t\t\t_fnCalculateColumnWidths( settings );\n\t\t}\n\t\n\t\tfor ( i=0, iLen=columns.length ; i<iLen ; i++ ) {\n\t\t\tcolumn = columns[i];\n\t\n\t\t\tif ( column.sWidth ) {\n\t\t\t\tcolumn.nTh.style.width = _fnStringToCss( column.sWidth );\n\t\t\t}\n\t\t}\n\t\n\t\t_fnCallbackFire( settings, null, 'preInit', [settings] );\n\t\n\t\t// If there is default sorting required - let's do it. The sort function\n\t\t// will do the drawing for us. Otherwise we draw the table regardless of the\n\t\t// Ajax source - this allows the table to look initialised for Ajax sourcing\n\t\t// data (show 'loading' message possibly)\n\t\t_fnReDraw( settings );\n\t\n\t\t// Server-side processing init complete is done by _fnAjaxUpdateDraw\n\t\tvar dataSrc = _fnDataSource( settings );\n\t\tif ( dataSrc != 'ssp' || deferLoading ) {\n\t\t\t// if there is an ajax source load the data\n\t\t\tif ( dataSrc == 'ajax' ) {\n\t\t\t\t_fnBuildAjax( settings, [], function(json) {\n\t\t\t\t\tvar aData = _fnAjaxDataSrc( settings, json );\n\t\n\t\t\t\t\t// Got the data - add it to the table\n\t\t\t\t\tfor ( i=0 ; i<aData.length ; i++ ) {\n\t\t\t\t\t\t_fnAddData( settings, aData[i] );\n\t\t\t\t\t}\n\t\n\t\t\t\t\t// Reset the init display for cookie saving. We've already done\n\t\t\t\t\t// a filter, and therefore cleared it before. So we need to make\n\t\t\t\t\t// it appear 'fresh'\n\t\t\t\t\tsettings.iInitDisplayStart = iAjaxStart;\n\t\n\t\t\t\t\t_fnReDraw( settings );\n\t\n\t\t\t\t\t_fnProcessingDisplay( settings, false );\n\t\t\t\t\t_fnInitComplete( settings, json );\n\t\t\t\t}, settings );\n\t\t\t}\n\t\t\telse {\n\t\t\t\t_fnProcessingDisplay( settings, false );\n\t\t\t\t_fnInitComplete( settings );\n\t\t\t}\n\t\t}\n\t}\n\t\n\t\n\t/**\n\t * Draw the table for the first time, adding all required features\n\t *  @param {object} oSettings dataTables settings object\n\t *  @param {object} [json] JSON from the server that completed the table, if using Ajax source\n\t *    with client-side processing (optional)\n\t *  @memberof DataTable#oApi\n\t */\n\tfunction _fnInitComplete ( settings, json )\n\t{\n\t\tsettings._bInitComplete = true;\n\t\n\t\t// When data was added after the initialisation (data or Ajax) we need to\n\t\t// calculate the column sizing\n\t\tif ( json || settings.oInit.aaData ) {\n\t\t\t_fnAdjustColumnSizing( settings );\n\t\t}\n\t\n\t\t_fnCallbackFire( settings, null, 'plugin-init', [settings, json] );\n\t\t_fnCallbackFire( settings, 'aoInitComplete', 'init', [settings, json] );\n\t}\n\t\n\t\n\tfunction _fnLengthChange ( settings, val )\n\t{\n\t\tvar len = parseInt( val, 10 );\n\t\tsettings._iDisplayLength = len;\n\t\n\t\t_fnLengthOverflow( settings );\n\t\n\t\t// Fire length change event\n\t\t_fnCallbackFire( settings, null, 'length', [settings, len] );\n\t}\n\t\n\t\n\t/**\n\t * Generate the node required for user display length changing\n\t *  @param {object} settings dataTables settings object\n\t *  @returns {node} Display length feature node\n\t *  @memberof DataTable#oApi\n\t */\n\tfunction _fnFeatureHtmlLength ( settings )\n\t{\n\t\tvar\n\t\t\tclasses  = settings.oClasses,\n\t\t\ttableId  = settings.sTableId,\n\t\t\tmenu     = settings.aLengthMenu,\n\t\t\td2       = $.isArray( menu[0] ),\n\t\t\tlengths  = d2 ? menu[0] : menu,\n\t\t\tlanguage = d2 ? menu[1] : menu;\n\t\n\t\tvar select = $('<select/>', {\n\t\t\t'name':          tableId+'_length',\n\t\t\t'aria-controls': tableId,\n\t\t\t'class':         classes.sLengthSelect\n\t\t} );\n\t\n\t\tfor ( var i=0, ien=lengths.length ; i<ien ; i++ ) {\n\t\t\tselect[0][ i ] = new Option( language[i], lengths[i] );\n\t\t}\n\t\n\t\tvar div = $('<div><label/></div>').addClass( classes.sLength );\n\t\tif ( ! settings.aanFeatures.l ) {\n\t\t\tdiv[0].id = tableId+'_length';\n\t\t}\n\t\n\t\tdiv.children().append(\n\t\t\tsettings.oLanguage.sLengthMenu.replace( '_MENU_', select[0].outerHTML )\n\t\t);\n\t\n\t\t// Can't use `select` variable as user might provide their own and the\n\t\t// reference is broken by the use of outerHTML\n\t\t$('select', div)\n\t\t\t.val( settings._iDisplayLength )\n\t\t\t.bind( 'change.DT', function(e) {\n\t\t\t\t_fnLengthChange( settings, $(this).val() );\n\t\t\t\t_fnDraw( settings );\n\t\t\t} );\n\t\n\t\t// Update node value whenever anything changes the table's length\n\t\t$(settings.nTable).bind( 'length.dt.DT', function (e, s, len) {\n\t\t\tif ( settings === s ) {\n\t\t\t\t$('select', div).val( len );\n\t\t\t}\n\t\t} );\n\t\n\t\treturn div[0];\n\t}\n\t\n\t\n\t\n\t/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\n\t * Note that most of the paging logic is done in\n\t * DataTable.ext.pager\n\t */\n\t\n\t/**\n\t * Generate the node required for default pagination\n\t *  @param {object} oSettings dataTables settings object\n\t *  @returns {node} Pagination feature node\n\t *  @memberof DataTable#oApi\n\t */\n\tfunction _fnFeatureHtmlPaginate ( settings )\n\t{\n\t\tvar\n\t\t\ttype   = settings.sPaginationType,\n\t\t\tplugin = DataTable.ext.pager[ type ],\n\t\t\tmodern = typeof plugin === 'function',\n\t\t\tredraw = function( settings ) {\n\t\t\t\t_fnDraw( settings );\n\t\t\t},\n\t\t\tnode = $('<div/>').addClass( settings.oClasses.sPaging + type )[0],\n\t\t\tfeatures = settings.aanFeatures;\n\t\n\t\tif ( ! modern ) {\n\t\t\tplugin.fnInit( settings, node, redraw );\n\t\t}\n\t\n\t\t/* Add a draw callback for the pagination on first instance, to update the paging display */\n\t\tif ( ! features.p )\n\t\t{\n\t\t\tnode.id = settings.sTableId+'_paginate';\n\t\n\t\t\tsettings.aoDrawCallback.push( {\n\t\t\t\t\"fn\": function( settings ) {\n\t\t\t\t\tif ( modern ) {\n\t\t\t\t\t\tvar\n\t\t\t\t\t\t\tstart      = settings._iDisplayStart,\n\t\t\t\t\t\t\tlen        = settings._iDisplayLength,\n\t\t\t\t\t\t\tvisRecords = settings.fnRecordsDisplay(),\n\t\t\t\t\t\t\tall        = len === -1,\n\t\t\t\t\t\t\tpage = all ? 0 : Math.ceil( start / len ),\n\t\t\t\t\t\t\tpages = all ? 1 : Math.ceil( visRecords / len ),\n\t\t\t\t\t\t\tbuttons = plugin(page, pages),\n\t\t\t\t\t\t\ti, ien;\n\t\n\t\t\t\t\t\tfor ( i=0, ien=features.p.length ; i<ien ; i++ ) {\n\t\t\t\t\t\t\t_fnRenderer( settings, 'pageButton' )(\n\t\t\t\t\t\t\t\tsettings, features.p[i], i, buttons, page, pages\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\telse {\n\t\t\t\t\t\tplugin.fnUpdate( settings, redraw );\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t\t\"sName\": \"pagination\"\n\t\t\t} );\n\t\t}\n\t\n\t\treturn node;\n\t}\n\t\n\t\n\t/**\n\t * Alter the display settings to change the page\n\t *  @param {object} settings DataTables settings object\n\t *  @param {string|int} action Paging action to take: \"first\", \"previous\",\n\t *    \"next\" or \"last\" or page number to jump to (integer)\n\t *  @param [bool] redraw Automatically draw the update or not\n\t *  @returns {bool} true page has changed, false - no change\n\t *  @memberof DataTable#oApi\n\t */\n\tfunction _fnPageChange ( settings, action, redraw )\n\t{\n\t\tvar\n\t\t\tstart     = settings._iDisplayStart,\n\t\t\tlen       = settings._iDisplayLength,\n\t\t\trecords   = settings.fnRecordsDisplay();\n\t\n\t\tif ( records === 0 || len === -1 )\n\t\t{\n\t\t\tstart = 0;\n\t\t}\n\t\telse if ( typeof action === \"number\" )\n\t\t{\n\t\t\tstart = action * len;\n\t\n\t\t\tif ( start > records )\n\t\t\t{\n\t\t\t\tstart = 0;\n\t\t\t}\n\t\t}\n\t\telse if ( action == \"first\" )\n\t\t{\n\t\t\tstart = 0;\n\t\t}\n\t\telse if ( action == \"previous\" )\n\t\t{\n\t\t\tstart = len >= 0 ?\n\t\t\t\tstart - len :\n\t\t\t\t0;\n\t\n\t\t\tif ( start < 0 )\n\t\t\t{\n\t\t\t  start = 0;\n\t\t\t}\n\t\t}\n\t\telse if ( action == \"next\" )\n\t\t{\n\t\t\tif ( start + len < records )\n\t\t\t{\n\t\t\t\tstart += len;\n\t\t\t}\n\t\t}\n\t\telse if ( action == \"last\" )\n\t\t{\n\t\t\tstart = Math.floor( (records-1) / len) * len;\n\t\t}\n\t\telse\n\t\t{\n\t\t\t_fnLog( settings, 0, \"Unknown paging action: \"+action, 5 );\n\t\t}\n\t\n\t\tvar changed = settings._iDisplayStart !== start;\n\t\tsettings._iDisplayStart = start;\n\t\n\t\tif ( changed ) {\n\t\t\t_fnCallbackFire( settings, null, 'page', [settings] );\n\t\n\t\t\tif ( redraw ) {\n\t\t\t\t_fnDraw( settings );\n\t\t\t}\n\t\t}\n\t\n\t\treturn changed;\n\t}\n\t\n\t\n\t\n\t/**\n\t * Generate the node required for the processing node\n\t *  @param {object} settings dataTables settings object\n\t *  @returns {node} Processing element\n\t *  @memberof DataTable#oApi\n\t */\n\tfunction _fnFeatureHtmlProcessing ( settings )\n\t{\n\t\treturn $('<div/>', {\n\t\t\t\t'id': ! settings.aanFeatures.r ? settings.sTableId+'_processing' : null,\n\t\t\t\t'class': settings.oClasses.sProcessing\n\t\t\t} )\n\t\t\t.html( settings.oLanguage.sProcessing )\n\t\t\t.insertBefore( settings.nTable )[0];\n\t}\n\t\n\t\n\t/**\n\t * Display or hide the processing indicator\n\t *  @param {object} settings dataTables settings object\n\t *  @param {bool} show Show the processing indicator (true) or not (false)\n\t *  @memberof DataTable#oApi\n\t */\n\tfunction _fnProcessingDisplay ( settings, show )\n\t{\n\t\tif ( settings.oFeatures.bProcessing ) {\n\t\t\t$(settings.aanFeatures.r).css( 'display', show ? 'block' : 'none' );\n\t\t}\n\t\n\t\t_fnCallbackFire( settings, null, 'processing', [settings, show] );\n\t}\n\t\n\t/**\n\t * Add any control elements for the table - specifically scrolling\n\t *  @param {object} settings dataTables settings object\n\t *  @returns {node} Node to add to the DOM\n\t *  @memberof DataTable#oApi\n\t */\n\tfunction _fnFeatureHtmlTable ( settings )\n\t{\n\t\tvar table = $(settings.nTable);\n\t\n\t\t// Add the ARIA grid role to the table\n\t\ttable.attr( 'role', 'grid' );\n\t\n\t\t// Scrolling from here on in\n\t\tvar scroll = settings.oScroll;\n\t\n\t\tif ( scroll.sX === '' && scroll.sY === '' ) {\n\t\t\treturn settings.nTable;\n\t\t}\n\t\n\t\tvar scrollX = scroll.sX;\n\t\tvar scrollY = scroll.sY;\n\t\tvar classes = settings.oClasses;\n\t\tvar caption = table.children('caption');\n\t\tvar captionSide = caption.length ? caption[0]._captionSide : null;\n\t\tvar headerClone = $( table[0].cloneNode(false) );\n\t\tvar footerClone = $( table[0].cloneNode(false) );\n\t\tvar footer = table.children('tfoot');\n\t\tvar _div = '<div/>';\n\t\tvar size = function ( s ) {\n\t\t\treturn !s ? null : _fnStringToCss( s );\n\t\t};\n\t\n\t\tif ( ! footer.length ) {\n\t\t\tfooter = null;\n\t\t}\n\t\n\t\t/*\n\t\t * The HTML structure that we want to generate in this function is:\n\t\t *  div - scroller\n\t\t *    div - scroll head\n\t\t *      div - scroll head inner\n\t\t *        table - scroll head table\n\t\t *          thead - thead\n\t\t *    div - scroll body\n\t\t *      table - table (master table)\n\t\t *        thead - thead clone for sizing\n\t\t *        tbody - tbody\n\t\t *    div - scroll foot\n\t\t *      div - scroll foot inner\n\t\t *        table - scroll foot table\n\t\t *          tfoot - tfoot\n\t\t */\n\t\tvar scroller = $( _div, { 'class': classes.sScrollWrapper } )\n\t\t\t.append(\n\t\t\t\t$(_div, { 'class': classes.sScrollHead } )\n\t\t\t\t\t.css( {\n\t\t\t\t\t\toverflow: 'hidden',\n\t\t\t\t\t\tposition: 'relative',\n\t\t\t\t\t\tborder: 0,\n\t\t\t\t\t\twidth: scrollX ? size(scrollX) : '100%'\n\t\t\t\t\t} )\n\t\t\t\t\t.append(\n\t\t\t\t\t\t$(_div, { 'class': classes.sScrollHeadInner } )\n\t\t\t\t\t\t\t.css( {\n\t\t\t\t\t\t\t\t'box-sizing': 'content-box',\n\t\t\t\t\t\t\t\twidth: scroll.sXInner || '100%'\n\t\t\t\t\t\t\t} )\n\t\t\t\t\t\t\t.append(\n\t\t\t\t\t\t\t\theaderClone\n\t\t\t\t\t\t\t\t\t.removeAttr('id')\n\t\t\t\t\t\t\t\t\t.css( 'margin-left', 0 )\n\t\t\t\t\t\t\t\t\t.append( captionSide === 'top' ? caption : null )\n\t\t\t\t\t\t\t\t\t.append(\n\t\t\t\t\t\t\t\t\t\ttable.children('thead')\n\t\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t)\n\t\t\t\t\t)\n\t\t\t)\n\t\t\t.append(\n\t\t\t\t$(_div, { 'class': classes.sScrollBody } )\n\t\t\t\t\t.css( {\n\t\t\t\t\t\tposition: 'relative',\n\t\t\t\t\t\toverflow: 'auto',\n\t\t\t\t\t\twidth: size( scrollX )\n\t\t\t\t\t} )\n\t\t\t\t\t.append( table )\n\t\t\t);\n\t\n\t\tif ( footer ) {\n\t\t\tscroller.append(\n\t\t\t\t$(_div, { 'class': classes.sScrollFoot } )\n\t\t\t\t\t.css( {\n\t\t\t\t\t\toverflow: 'hidden',\n\t\t\t\t\t\tborder: 0,\n\t\t\t\t\t\twidth: scrollX ? size(scrollX) : '100%'\n\t\t\t\t\t} )\n\t\t\t\t\t.append(\n\t\t\t\t\t\t$(_div, { 'class': classes.sScrollFootInner } )\n\t\t\t\t\t\t\t.append(\n\t\t\t\t\t\t\t\tfooterClone\n\t\t\t\t\t\t\t\t\t.removeAttr('id')\n\t\t\t\t\t\t\t\t\t.css( 'margin-left', 0 )\n\t\t\t\t\t\t\t\t\t.append( captionSide === 'bottom' ? caption : null )\n\t\t\t\t\t\t\t\t\t.append(\n\t\t\t\t\t\t\t\t\t\ttable.children('tfoot')\n\t\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t)\n\t\t\t\t\t)\n\t\t\t);\n\t\t}\n\t\n\t\tvar children = scroller.children();\n\t\tvar scrollHead = children[0];\n\t\tvar scrollBody = children[1];\n\t\tvar scrollFoot = footer ? children[2] : null;\n\t\n\t\t// When the body is scrolled, then we also want to scroll the headers\n\t\tif ( scrollX ) {\n\t\t\t$(scrollBody).on( 'scroll.DT', function (e) {\n\t\t\t\tvar scrollLeft = this.scrollLeft;\n\t\n\t\t\t\tscrollHead.scrollLeft = scrollLeft;\n\t\n\t\t\t\tif ( footer ) {\n\t\t\t\t\tscrollFoot.scrollLeft = scrollLeft;\n\t\t\t\t}\n\t\t\t} );\n\t\t}\n\t\n\t\t$(scrollBody).css(\n\t\t\tscrollY && scroll.bCollapse ? 'max-height' : 'height', \n\t\t\tscrollY\n\t\t);\n\t\n\t\tsettings.nScrollHead = scrollHead;\n\t\tsettings.nScrollBody = scrollBody;\n\t\tsettings.nScrollFoot = scrollFoot;\n\t\n\t\t// On redraw - align columns\n\t\tsettings.aoDrawCallback.push( {\n\t\t\t\"fn\": _fnScrollDraw,\n\t\t\t\"sName\": \"scrolling\"\n\t\t} );\n\t\n\t\treturn scroller[0];\n\t}\n\t\n\t\n\t\n\t/**\n\t * Update the header, footer and body tables for resizing - i.e. column\n\t * alignment.\n\t *\n\t * Welcome to the most horrible function DataTables. The process that this\n\t * function follows is basically:\n\t *   1. Re-create the table inside the scrolling div\n\t *   2. Take live measurements from the DOM\n\t *   3. Apply the measurements to align the columns\n\t *   4. Clean up\n\t *\n\t *  @param {object} settings dataTables settings object\n\t *  @memberof DataTable#oApi\n\t */\n\tfunction _fnScrollDraw ( settings )\n\t{\n\t\t// Given that this is such a monster function, a lot of variables are use\n\t\t// to try and keep the minimised size as small as possible\n\t\tvar\n\t\t\tscroll         = settings.oScroll,\n\t\t\tscrollX        = scroll.sX,\n\t\t\tscrollXInner   = scroll.sXInner,\n\t\t\tscrollY        = scroll.sY,\n\t\t\tbarWidth       = scroll.iBarWidth,\n\t\t\tdivHeader      = $(settings.nScrollHead),\n\t\t\tdivHeaderStyle = divHeader[0].style,\n\t\t\tdivHeaderInner = divHeader.children('div'),\n\t\t\tdivHeaderInnerStyle = divHeaderInner[0].style,\n\t\t\tdivHeaderTable = divHeaderInner.children('table'),\n\t\t\tdivBodyEl      = settings.nScrollBody,\n\t\t\tdivBody        = $(divBodyEl),\n\t\t\tdivBodyStyle   = divBodyEl.style,\n\t\t\tdivFooter      = $(settings.nScrollFoot),\n\t\t\tdivFooterInner = divFooter.children('div'),\n\t\t\tdivFooterTable = divFooterInner.children('table'),\n\t\t\theader         = $(settings.nTHead),\n\t\t\ttable          = $(settings.nTable),\n\t\t\ttableEl        = table[0],\n\t\t\ttableStyle     = tableEl.style,\n\t\t\tfooter         = settings.nTFoot ? $(settings.nTFoot) : null,\n\t\t\tbrowser        = settings.oBrowser,\n\t\t\tie67           = browser.bScrollOversize,\n\t\t\tdtHeaderCells  = _pluck( settings.aoColumns, 'nTh' ),\n\t\t\theaderTrgEls, footerTrgEls,\n\t\t\theaderSrcEls, footerSrcEls,\n\t\t\theaderCopy, footerCopy,\n\t\t\theaderWidths=[], footerWidths=[],\n\t\t\theaderContent=[], footerContent=[],\n\t\t\tidx, correction, sanityWidth,\n\t\t\tzeroOut = function(nSizer) {\n\t\t\t\tvar style = nSizer.style;\n\t\t\t\tstyle.paddingTop = \"0\";\n\t\t\t\tstyle.paddingBottom = \"0\";\n\t\t\t\tstyle.borderTopWidth = \"0\";\n\t\t\t\tstyle.borderBottomWidth = \"0\";\n\t\t\t\tstyle.height = 0;\n\t\t\t};\n\t\n\t\t// If the scrollbar visibility has changed from the last draw, we need to\n\t\t// adjust the column sizes as the table width will have changed to account\n\t\t// for the scrollbar\n\t\tvar scrollBarVis = divBodyEl.scrollHeight > divBodyEl.clientHeight;\n\t\t\n\t\tif ( settings.scrollBarVis !== scrollBarVis && settings.scrollBarVis !== undefined ) {\n\t\t\tsettings.scrollBarVis = scrollBarVis;\n\t\t\t_fnAdjustColumnSizing( settings );\n\t\t\treturn; // adjust column sizing will call this function again\n\t\t}\n\t\telse {\n\t\t\tsettings.scrollBarVis = scrollBarVis;\n\t\t}\n\t\n\t\t/*\n\t\t * 1. Re-create the table inside the scrolling div\n\t\t */\n\t\n\t\t// Remove the old minimised thead and tfoot elements in the inner table\n\t\ttable.children('thead, tfoot').remove();\n\t\n\t\tif ( footer ) {\n\t\t\tfooterCopy = footer.clone().prependTo( table );\n\t\t\tfooterTrgEls = footer.find('tr'); // the original tfoot is in its own table and must be sized\n\t\t\tfooterSrcEls = footerCopy.find('tr');\n\t\t}\n\t\n\t\t// Clone the current header and footer elements and then place it into the inner table\n\t\theaderCopy = header.clone().prependTo( table );\n\t\theaderTrgEls = header.find('tr'); // original header is in its own table\n\t\theaderSrcEls = headerCopy.find('tr');\n\t\theaderCopy.find('th, td').removeAttr('tabindex');\n\t\n\t\n\t\t/*\n\t\t * 2. Take live measurements from the DOM - do not alter the DOM itself!\n\t\t */\n\t\n\t\t// Remove old sizing and apply the calculated column widths\n\t\t// Get the unique column headers in the newly created (cloned) header. We want to apply the\n\t\t// calculated sizes to this header\n\t\tif ( ! scrollX )\n\t\t{\n\t\t\tdivBodyStyle.width = '100%';\n\t\t\tdivHeader[0].style.width = '100%';\n\t\t}\n\t\n\t\t$.each( _fnGetUniqueThs( settings, headerCopy ), function ( i, el ) {\n\t\t\tidx = _fnVisibleToColumnIndex( settings, i );\n\t\t\tel.style.width = settings.aoColumns[idx].sWidth;\n\t\t} );\n\t\n\t\tif ( footer ) {\n\t\t\t_fnApplyToChildren( function(n) {\n\t\t\t\tn.style.width = \"\";\n\t\t\t}, footerSrcEls );\n\t\t}\n\t\n\t\t// Size the table as a whole\n\t\tsanityWidth = table.outerWidth();\n\t\tif ( scrollX === \"\" ) {\n\t\t\t// No x scrolling\n\t\t\ttableStyle.width = \"100%\";\n\t\n\t\t\t// IE7 will make the width of the table when 100% include the scrollbar\n\t\t\t// - which is shouldn't. When there is a scrollbar we need to take this\n\t\t\t// into account.\n\t\t\tif ( ie67 && (table.find('tbody').height() > divBodyEl.offsetHeight ||\n\t\t\t\tdivBody.css('overflow-y') == \"scroll\")\n\t\t\t) {\n\t\t\t\ttableStyle.width = _fnStringToCss( table.outerWidth() - barWidth);\n\t\t\t}\n\t\n\t\t\t// Recalculate the sanity width\n\t\t\tsanityWidth = table.outerWidth();\n\t\t}\n\t\telse if ( scrollXInner !== \"\" ) {\n\t\t\t// legacy x scroll inner has been given - use it\n\t\t\ttableStyle.width = _fnStringToCss(scrollXInner);\n\t\n\t\t\t// Recalculate the sanity width\n\t\t\tsanityWidth = table.outerWidth();\n\t\t}\n\t\n\t\t// Hidden header should have zero height, so remove padding and borders. Then\n\t\t// set the width based on the real headers\n\t\n\t\t// Apply all styles in one pass\n\t\t_fnApplyToChildren( zeroOut, headerSrcEls );\n\t\n\t\t// Read all widths in next pass\n\t\t_fnApplyToChildren( function(nSizer) {\n\t\t\theaderContent.push( nSizer.innerHTML );\n\t\t\theaderWidths.push( _fnStringToCss( $(nSizer).css('width') ) );\n\t\t}, headerSrcEls );\n\t\n\t\t// Apply all widths in final pass\n\t\t_fnApplyToChildren( function(nToSize, i) {\n\t\t\t// Only apply widths to the DataTables detected header cells - this\n\t\t\t// prevents complex headers from having contradictory sizes applied\n\t\t\tif ( $.inArray( nToSize, dtHeaderCells ) !== -1 ) {\n\t\t\t\tnToSize.style.width = headerWidths[i];\n\t\t\t}\n\t\t}, headerTrgEls );\n\t\n\t\t$(headerSrcEls).height(0);\n\t\n\t\t/* Same again with the footer if we have one */\n\t\tif ( footer )\n\t\t{\n\t\t\t_fnApplyToChildren( zeroOut, footerSrcEls );\n\t\n\t\t\t_fnApplyToChildren( function(nSizer) {\n\t\t\t\tfooterContent.push( nSizer.innerHTML );\n\t\t\t\tfooterWidths.push( _fnStringToCss( $(nSizer).css('width') ) );\n\t\t\t}, footerSrcEls );\n\t\n\t\t\t_fnApplyToChildren( function(nToSize, i) {\n\t\t\t\tnToSize.style.width = footerWidths[i];\n\t\t\t}, footerTrgEls );\n\t\n\t\t\t$(footerSrcEls).height(0);\n\t\t}\n\t\n\t\n\t\t/*\n\t\t * 3. Apply the measurements\n\t\t */\n\t\n\t\t// \"Hide\" the header and footer that we used for the sizing. We need to keep\n\t\t// the content of the cell so that the width applied to the header and body\n\t\t// both match, but we want to hide it completely. We want to also fix their\n\t\t// width to what they currently are\n\t\t_fnApplyToChildren( function(nSizer, i) {\n\t\t\tnSizer.innerHTML = '<div class=\"dataTables_sizing\" style=\"height:0;overflow:hidden;\">'+headerContent[i]+'</div>';\n\t\t\tnSizer.style.width = headerWidths[i];\n\t\t}, headerSrcEls );\n\t\n\t\tif ( footer )\n\t\t{\n\t\t\t_fnApplyToChildren( function(nSizer, i) {\n\t\t\t\tnSizer.innerHTML = '<div class=\"dataTables_sizing\" style=\"height:0;overflow:hidden;\">'+footerContent[i]+'</div>';\n\t\t\t\tnSizer.style.width = footerWidths[i];\n\t\t\t}, footerSrcEls );\n\t\t}\n\t\n\t\t// Sanity check that the table is of a sensible width. If not then we are going to get\n\t\t// misalignment - try to prevent this by not allowing the table to shrink below its min width\n\t\tif ( table.outerWidth() < sanityWidth )\n\t\t{\n\t\t\t// The min width depends upon if we have a vertical scrollbar visible or not */\n\t\t\tcorrection = ((divBodyEl.scrollHeight > divBodyEl.offsetHeight ||\n\t\t\t\tdivBody.css('overflow-y') == \"scroll\")) ?\n\t\t\t\t\tsanityWidth+barWidth :\n\t\t\t\t\tsanityWidth;\n\t\n\t\t\t// IE6/7 are a law unto themselves...\n\t\t\tif ( ie67 && (divBodyEl.scrollHeight >\n\t\t\t\tdivBodyEl.offsetHeight || divBody.css('overflow-y') == \"scroll\")\n\t\t\t) {\n\t\t\t\ttableStyle.width = _fnStringToCss( correction-barWidth );\n\t\t\t}\n\t\n\t\t\t// And give the user a warning that we've stopped the table getting too small\n\t\t\tif ( scrollX === \"\" || scrollXInner !== \"\" ) {\n\t\t\t\t_fnLog( settings, 1, 'Possible column misalignment', 6 );\n\t\t\t}\n\t\t}\n\t\telse\n\t\t{\n\t\t\tcorrection = '100%';\n\t\t}\n\t\n\t\t// Apply to the container elements\n\t\tdivBodyStyle.width = _fnStringToCss( correction );\n\t\tdivHeaderStyle.width = _fnStringToCss( correction );\n\t\n\t\tif ( footer ) {\n\t\t\tsettings.nScrollFoot.style.width = _fnStringToCss( correction );\n\t\t}\n\t\n\t\n\t\t/*\n\t\t * 4. Clean up\n\t\t */\n\t\tif ( ! scrollY ) {\n\t\t\t/* IE7< puts a vertical scrollbar in place (when it shouldn't be) due to subtracting\n\t\t\t * the scrollbar height from the visible display, rather than adding it on. We need to\n\t\t\t * set the height in order to sort this. Don't want to do it in any other browsers.\n\t\t\t */\n\t\t\tif ( ie67 ) {\n\t\t\t\tdivBodyStyle.height = _fnStringToCss( tableEl.offsetHeight+barWidth );\n\t\t\t}\n\t\t}\n\t\n\t\t/* Finally set the width's of the header and footer tables */\n\t\tvar iOuterWidth = table.outerWidth();\n\t\tdivHeaderTable[0].style.width = _fnStringToCss( iOuterWidth );\n\t\tdivHeaderInnerStyle.width = _fnStringToCss( iOuterWidth );\n\t\n\t\t// Figure out if there are scrollbar present - if so then we need a the header and footer to\n\t\t// provide a bit more space to allow \"overflow\" scrolling (i.e. past the scrollbar)\n\t\tvar bScrolling = table.height() > divBodyEl.clientHeight || divBody.css('overflow-y') == \"scroll\";\n\t\tvar padding = 'padding' + (browser.bScrollbarLeft ? 'Left' : 'Right' );\n\t\tdivHeaderInnerStyle[ padding ] = bScrolling ? barWidth+\"px\" : \"0px\";\n\t\n\t\tif ( footer ) {\n\t\t\tdivFooterTable[0].style.width = _fnStringToCss( iOuterWidth );\n\t\t\tdivFooterInner[0].style.width = _fnStringToCss( iOuterWidth );\n\t\t\tdivFooterInner[0].style[padding] = bScrolling ? barWidth+\"px\" : \"0px\";\n\t\t}\n\t\n\t\t// Correct DOM ordering for colgroup - comes before the thead\n\t\ttable.children('colgroup').insertBefore( table.children('thead') );\n\t\n\t\t/* Adjust the position of the header in case we loose the y-scrollbar */\n\t\tdivBody.scroll();\n\t\n\t\t// If sorting or filtering has occurred, jump the scrolling back to the top\n\t\t// only if we aren't holding the position\n\t\tif ( (settings.bSorted || settings.bFiltered) && ! settings._drawHold ) {\n\t\t\tdivBodyEl.scrollTop = 0;\n\t\t}\n\t}\n\t\n\t\n\t\n\t/**\n\t * Apply a given function to the display child nodes of an element array (typically\n\t * TD children of TR rows\n\t *  @param {function} fn Method to apply to the objects\n\t *  @param array {nodes} an1 List of elements to look through for display children\n\t *  @param array {nodes} an2 Another list (identical structure to the first) - optional\n\t *  @memberof DataTable#oApi\n\t */\n\tfunction _fnApplyToChildren( fn, an1, an2 )\n\t{\n\t\tvar index=0, i=0, iLen=an1.length;\n\t\tvar nNode1, nNode2;\n\t\n\t\twhile ( i < iLen ) {\n\t\t\tnNode1 = an1[i].firstChild;\n\t\t\tnNode2 = an2 ? an2[i].firstChild : null;\n\t\n\t\t\twhile ( nNode1 ) {\n\t\t\t\tif ( nNode1.nodeType === 1 ) {\n\t\t\t\t\tif ( an2 ) {\n\t\t\t\t\t\tfn( nNode1, nNode2, index );\n\t\t\t\t\t}\n\t\t\t\t\telse {\n\t\t\t\t\t\tfn( nNode1, index );\n\t\t\t\t\t}\n\t\n\t\t\t\t\tindex++;\n\t\t\t\t}\n\t\n\t\t\t\tnNode1 = nNode1.nextSibling;\n\t\t\t\tnNode2 = an2 ? nNode2.nextSibling : null;\n\t\t\t}\n\t\n\t\t\ti++;\n\t\t}\n\t}\n\t\n\t\n\t\n\tvar __re_html_remove = /<.*?>/g;\n\t\n\t\n\t/**\n\t * Calculate the width of columns for the table\n\t *  @param {object} oSettings dataTables settings object\n\t *  @memberof DataTable#oApi\n\t */\n\tfunction _fnCalculateColumnWidths ( oSettings )\n\t{\n\t\tvar\n\t\t\ttable = oSettings.nTable,\n\t\t\tcolumns = oSettings.aoColumns,\n\t\t\tscroll = oSettings.oScroll,\n\t\t\tscrollY = scroll.sY,\n\t\t\tscrollX = scroll.sX,\n\t\t\tscrollXInner = scroll.sXInner,\n\t\t\tcolumnCount = columns.length,\n\t\t\tvisibleColumns = _fnGetColumns( oSettings, 'bVisible' ),\n\t\t\theaderCells = $('th', oSettings.nTHead),\n\t\t\ttableWidthAttr = table.getAttribute('width'), // from DOM element\n\t\t\ttableContainer = table.parentNode,\n\t\t\tuserInputs = false,\n\t\t\ti, column, columnIdx, width, outerWidth,\n\t\t\tbrowser = oSettings.oBrowser,\n\t\t\tie67 = browser.bScrollOversize;\n\t\n\t\tvar styleWidth = table.style.width;\n\t\tif ( styleWidth && styleWidth.indexOf('%') !== -1 ) {\n\t\t\ttableWidthAttr = styleWidth;\n\t\t}\n\t\n\t\t/* Convert any user input sizes into pixel sizes */\n\t\tfor ( i=0 ; i<visibleColumns.length ; i++ ) {\n\t\t\tcolumn = columns[ visibleColumns[i] ];\n\t\n\t\t\tif ( column.sWidth !== null ) {\n\t\t\t\tcolumn.sWidth = _fnConvertToWidth( column.sWidthOrig, tableContainer );\n\t\n\t\t\t\tuserInputs = true;\n\t\t\t}\n\t\t}\n\t\n\t\t/* If the number of columns in the DOM equals the number that we have to\n\t\t * process in DataTables, then we can use the offsets that are created by\n\t\t * the web- browser. No custom sizes can be set in order for this to happen,\n\t\t * nor scrolling used\n\t\t */\n\t\tif ( ie67 || ! userInputs && ! scrollX && ! scrollY &&\n\t\t     columnCount == _fnVisbleColumns( oSettings ) &&\n\t\t     columnCount == headerCells.length\n\t\t) {\n\t\t\tfor ( i=0 ; i<columnCount ; i++ ) {\n\t\t\t\tvar colIdx = _fnVisibleToColumnIndex( oSettings, i );\n\t\n\t\t\t\tif ( colIdx !== null ) {\n\t\t\t\t\tcolumns[ colIdx ].sWidth = _fnStringToCss( headerCells.eq(i).width() );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\telse\n\t\t{\n\t\t\t// Otherwise construct a single row, worst case, table with the widest\n\t\t\t// node in the data, assign any user defined widths, then insert it into\n\t\t\t// the DOM and allow the browser to do all the hard work of calculating\n\t\t\t// table widths\n\t\t\tvar tmpTable = $(table).clone() // don't use cloneNode - IE8 will remove events on the main table\n\t\t\t\t.css( 'visibility', 'hidden' )\n\t\t\t\t.removeAttr( 'id' );\n\t\n\t\t\t// Clean up the table body\n\t\t\ttmpTable.find('tbody tr').remove();\n\t\t\tvar tr = $('<tr/>').appendTo( tmpTable.find('tbody') );\n\t\n\t\t\t// Clone the table header and footer - we can't use the header / footer\n\t\t\t// from the cloned table, since if scrolling is active, the table's\n\t\t\t// real header and footer are contained in different table tags\n\t\t\ttmpTable.find('thead, tfoot').remove();\n\t\t\ttmpTable\n\t\t\t\t.append( $(oSettings.nTHead).clone() )\n\t\t\t\t.append( $(oSettings.nTFoot).clone() );\n\t\n\t\t\t// Remove any assigned widths from the footer (from scrolling)\n\t\t\ttmpTable.find('tfoot th, tfoot td').css('width', '');\n\t\n\t\t\t// Apply custom sizing to the cloned header\n\t\t\theaderCells = _fnGetUniqueThs( oSettings, tmpTable.find('thead')[0] );\n\t\n\t\t\tfor ( i=0 ; i<visibleColumns.length ; i++ ) {\n\t\t\t\tcolumn = columns[ visibleColumns[i] ];\n\t\n\t\t\t\theaderCells[i].style.width = column.sWidthOrig !== null && column.sWidthOrig !== '' ?\n\t\t\t\t\t_fnStringToCss( column.sWidthOrig ) :\n\t\t\t\t\t'';\n\t\n\t\t\t\t// For scrollX we need to force the column width otherwise the\n\t\t\t\t// browser will collapse it. If this width is smaller than the\n\t\t\t\t// width the column requires, then it will have no effect\n\t\t\t\tif ( column.sWidthOrig && scrollX ) {\n\t\t\t\t\t$( headerCells[i] ).append( $('<div/>').css( {\n\t\t\t\t\t\twidth: column.sWidthOrig,\n\t\t\t\t\t\tmargin: 0,\n\t\t\t\t\t\tpadding: 0,\n\t\t\t\t\t\tborder: 0,\n\t\t\t\t\t\theight: 1\n\t\t\t\t\t} ) );\n\t\t\t\t}\n\t\t\t}\n\t\n\t\t\t// Find the widest cell for each column and put it into the table\n\t\t\tif ( oSettings.aoData.length ) {\n\t\t\t\tfor ( i=0 ; i<visibleColumns.length ; i++ ) {\n\t\t\t\t\tcolumnIdx = visibleColumns[i];\n\t\t\t\t\tcolumn = columns[ columnIdx ];\n\t\n\t\t\t\t\t$( _fnGetWidestNode( oSettings, columnIdx ) )\n\t\t\t\t\t\t.clone( false )\n\t\t\t\t\t\t.append( column.sContentPadding )\n\t\t\t\t\t\t.appendTo( tr );\n\t\t\t\t}\n\t\t\t}\n\t\n\t\t\t// Tidy the temporary table - remove name attributes so there aren't\n\t\t\t// duplicated in the dom (radio elements for example)\n\t\t\t$('[name]', tmpTable).removeAttr('name');\n\t\n\t\t\t// Table has been built, attach to the document so we can work with it.\n\t\t\t// A holding element is used, positioned at the top of the container\n\t\t\t// with minimal height, so it has no effect on if the container scrolls\n\t\t\t// or not. Otherwise it might trigger scrolling when it actually isn't\n\t\t\t// needed\n\t\t\tvar holder = $('<div/>').css( scrollX || scrollY ?\n\t\t\t\t\t{\n\t\t\t\t\t\tposition: 'absolute',\n\t\t\t\t\t\ttop: 0,\n\t\t\t\t\t\tleft: 0,\n\t\t\t\t\t\theight: 1,\n\t\t\t\t\t\tright: 0,\n\t\t\t\t\t\toverflow: 'hidden'\n\t\t\t\t\t} :\n\t\t\t\t\t{}\n\t\t\t\t)\n\t\t\t\t.append( tmpTable )\n\t\t\t\t.appendTo( tableContainer );\n\t\n\t\t\t// When scrolling (X or Y) we want to set the width of the table as \n\t\t\t// appropriate. However, when not scrolling leave the table width as it\n\t\t\t// is. This results in slightly different, but I think correct behaviour\n\t\t\tif ( scrollX && scrollXInner ) {\n\t\t\t\ttmpTable.width( scrollXInner );\n\t\t\t}\n\t\t\telse if ( scrollX ) {\n\t\t\t\ttmpTable.css( 'width', 'auto' );\n\t\t\t\ttmpTable.removeAttr('width');\n\t\n\t\t\t\t// If there is no width attribute or style, then allow the table to\n\t\t\t\t// collapse\n\t\t\t\tif ( tmpTable.width() < tableContainer.clientWidth && tableWidthAttr ) {\n\t\t\t\t\ttmpTable.width( tableContainer.clientWidth );\n\t\t\t\t}\n\t\t\t}\n\t\t\telse if ( scrollY ) {\n\t\t\t\ttmpTable.width( tableContainer.clientWidth );\n\t\t\t}\n\t\t\telse if ( tableWidthAttr ) {\n\t\t\t\ttmpTable.width( tableWidthAttr );\n\t\t\t}\n\t\n\t\t\t// Get the width of each column in the constructed table - we need to\n\t\t\t// know the inner width (so it can be assigned to the other table's\n\t\t\t// cells) and the outer width so we can calculate the full width of the\n\t\t\t// table. This is safe since DataTables requires a unique cell for each\n\t\t\t// column, but if ever a header can span multiple columns, this will\n\t\t\t// need to be modified.\n\t\t\tvar total = 0;\n\t\t\tfor ( i=0 ; i<visibleColumns.length ; i++ ) {\n\t\t\t\tvar cell = $(headerCells[i]);\n\t\t\t\tvar border = cell.outerWidth() - cell.width();\n\t\n\t\t\t\t// Use getBounding... where possible (not IE8-) because it can give\n\t\t\t\t// sub-pixel accuracy, which we then want to round up!\n\t\t\t\tvar bounding = browser.bBounding ?\n\t\t\t\t\tMath.ceil( headerCells[i].getBoundingClientRect().width ) :\n\t\t\t\t\tcell.outerWidth();\n\t\n\t\t\t\t// Total is tracked to remove any sub-pixel errors as the outerWidth\n\t\t\t\t// of the table might not equal the total given here (IE!).\n\t\t\t\ttotal += bounding;\n\t\n\t\t\t\t// Width for each column to use\n\t\t\t\tcolumns[ visibleColumns[i] ].sWidth = _fnStringToCss( bounding - border );\n\t\t\t}\n\t\n\t\t\ttable.style.width = _fnStringToCss( total );\n\t\n\t\t\t// Finished with the table - ditch it\n\t\t\tholder.remove();\n\t\t}\n\t\n\t\t// If there is a width attr, we want to attach an event listener which\n\t\t// allows the table sizing to automatically adjust when the window is\n\t\t// resized. Use the width attr rather than CSS, since we can't know if the\n\t\t// CSS is a relative value or absolute - DOM read is always px.\n\t\tif ( tableWidthAttr ) {\n\t\t\ttable.style.width = _fnStringToCss( tableWidthAttr );\n\t\t}\n\t\n\t\tif ( (tableWidthAttr || scrollX) && ! oSettings._reszEvt ) {\n\t\t\tvar bindResize = function () {\n\t\t\t\t$(window).bind('resize.DT-'+oSettings.sInstance, _fnThrottle( function () {\n\t\t\t\t\t_fnAdjustColumnSizing( oSettings );\n\t\t\t\t} ) );\n\t\t\t};\n\t\n\t\t\t// IE6/7 will crash if we bind a resize event handler on page load.\n\t\t\t// To be removed in 1.11 which drops IE6/7 support\n\t\t\tif ( ie67 ) {\n\t\t\t\tsetTimeout( bindResize, 1000 );\n\t\t\t}\n\t\t\telse {\n\t\t\t\tbindResize();\n\t\t\t}\n\t\n\t\t\toSettings._reszEvt = true;\n\t\t}\n\t}\n\t\n\t\n\t/**\n\t * Throttle the calls to a function. Arguments and context are maintained for\n\t * the throttled function\n\t *  @param {function} fn Function to be called\n\t *  @param {int} [freq=200] call frequency in mS\n\t *  @returns {function} wrapped function\n\t *  @memberof DataTable#oApi\n\t */\n\tvar _fnThrottle = DataTable.util.throttle;\n\t\n\t\n\t/**\n\t * Convert a CSS unit width to pixels (e.g. 2em)\n\t *  @param {string} width width to be converted\n\t *  @param {node} parent parent to get the with for (required for relative widths) - optional\n\t *  @returns {int} width in pixels\n\t *  @memberof DataTable#oApi\n\t */\n\tfunction _fnConvertToWidth ( width, parent )\n\t{\n\t\tif ( ! width ) {\n\t\t\treturn 0;\n\t\t}\n\t\n\t\tvar n = $('<div/>')\n\t\t\t.css( 'width', _fnStringToCss( width ) )\n\t\t\t.appendTo( parent || document.body );\n\t\n\t\tvar val = n[0].offsetWidth;\n\t\tn.remove();\n\t\n\t\treturn val;\n\t}\n\t\n\t\n\t/**\n\t * Get the widest node\n\t *  @param {object} settings dataTables settings object\n\t *  @param {int} colIdx column of interest\n\t *  @returns {node} widest table node\n\t *  @memberof DataTable#oApi\n\t */\n\tfunction _fnGetWidestNode( settings, colIdx )\n\t{\n\t\tvar idx = _fnGetMaxLenString( settings, colIdx );\n\t\tif ( idx < 0 ) {\n\t\t\treturn null;\n\t\t}\n\t\n\t\tvar data = settings.aoData[ idx ];\n\t\treturn ! data.nTr ? // Might not have been created when deferred rendering\n\t\t\t$('<td/>').html( _fnGetCellData( settings, idx, colIdx, 'display' ) )[0] :\n\t\t\tdata.anCells[ colIdx ];\n\t}\n\t\n\t\n\t/**\n\t * Get the maximum strlen for each data column\n\t *  @param {object} settings dataTables settings object\n\t *  @param {int} colIdx column of interest\n\t *  @returns {string} max string length for each column\n\t *  @memberof DataTable#oApi\n\t */\n\tfunction _fnGetMaxLenString( settings, colIdx )\n\t{\n\t\tvar s, max=-1, maxIdx = -1;\n\t\n\t\tfor ( var i=0, ien=settings.aoData.length ; i<ien ; i++ ) {\n\t\t\ts = _fnGetCellData( settings, i, colIdx, 'display' )+'';\n\t\t\ts = s.replace( __re_html_remove, '' );\n\t\t\ts = s.replace( /&nbsp;/g, ' ' );\n\t\n\t\t\tif ( s.length > max ) {\n\t\t\t\tmax = s.length;\n\t\t\t\tmaxIdx = i;\n\t\t\t}\n\t\t}\n\t\n\t\treturn maxIdx;\n\t}\n\t\n\t\n\t/**\n\t * Append a CSS unit (only if required) to a string\n\t *  @param {string} value to css-ify\n\t *  @returns {string} value with css unit\n\t *  @memberof DataTable#oApi\n\t */\n\tfunction _fnStringToCss( s )\n\t{\n\t\tif ( s === null ) {\n\t\t\treturn '0px';\n\t\t}\n\t\n\t\tif ( typeof s == 'number' ) {\n\t\t\treturn s < 0 ?\n\t\t\t\t'0px' :\n\t\t\t\ts+'px';\n\t\t}\n\t\n\t\t// Check it has a unit character already\n\t\treturn s.match(/\\d$/) ?\n\t\t\ts+'px' :\n\t\t\ts;\n\t}\n\t\n\t\n\t\n\tfunction _fnSortFlatten ( settings )\n\t{\n\t\tvar\n\t\t\ti, iLen, k, kLen,\n\t\t\taSort = [],\n\t\t\taiOrig = [],\n\t\t\taoColumns = settings.aoColumns,\n\t\t\taDataSort, iCol, sType, srcCol,\n\t\t\tfixed = settings.aaSortingFixed,\n\t\t\tfixedObj = $.isPlainObject( fixed ),\n\t\t\tnestedSort = [],\n\t\t\tadd = function ( a ) {\n\t\t\t\tif ( a.length && ! $.isArray( a[0] ) ) {\n\t\t\t\t\t// 1D array\n\t\t\t\t\tnestedSort.push( a );\n\t\t\t\t}\n\t\t\t\telse {\n\t\t\t\t\t// 2D array\n\t\t\t\t\t$.merge( nestedSort, a );\n\t\t\t\t}\n\t\t\t};\n\t\n\t\t// Build the sort array, with pre-fix and post-fix options if they have been\n\t\t// specified\n\t\tif ( $.isArray( fixed ) ) {\n\t\t\tadd( fixed );\n\t\t}\n\t\n\t\tif ( fixedObj && fixed.pre ) {\n\t\t\tadd( fixed.pre );\n\t\t}\n\t\n\t\tadd( settings.aaSorting );\n\t\n\t\tif (fixedObj && fixed.post ) {\n\t\t\tadd( fixed.post );\n\t\t}\n\t\n\t\tfor ( i=0 ; i<nestedSort.length ; i++ )\n\t\t{\n\t\t\tsrcCol = nestedSort[i][0];\n\t\t\taDataSort = aoColumns[ srcCol ].aDataSort;\n\t\n\t\t\tfor ( k=0, kLen=aDataSort.length ; k<kLen ; k++ )\n\t\t\t{\n\t\t\t\tiCol = aDataSort[k];\n\t\t\t\tsType = aoColumns[ iCol ].sType || 'string';\n\t\n\t\t\t\tif ( nestedSort[i]._idx === undefined ) {\n\t\t\t\t\tnestedSort[i]._idx = $.inArray( nestedSort[i][1], aoColumns[iCol].asSorting );\n\t\t\t\t}\n\t\n\t\t\t\taSort.push( {\n\t\t\t\t\tsrc:       srcCol,\n\t\t\t\t\tcol:       iCol,\n\t\t\t\t\tdir:       nestedSort[i][1],\n\t\t\t\t\tindex:     nestedSort[i]._idx,\n\t\t\t\t\ttype:      sType,\n\t\t\t\t\tformatter: DataTable.ext.type.order[ sType+\"-pre\" ]\n\t\t\t\t} );\n\t\t\t}\n\t\t}\n\t\n\t\treturn aSort;\n\t}\n\t\n\t/**\n\t * Change the order of the table\n\t *  @param {object} oSettings dataTables settings object\n\t *  @memberof DataTable#oApi\n\t *  @todo This really needs split up!\n\t */\n\tfunction _fnSort ( oSettings )\n\t{\n\t\tvar\n\t\t\ti, ien, iLen, j, jLen, k, kLen,\n\t\t\tsDataType, nTh,\n\t\t\taiOrig = [],\n\t\t\toExtSort = DataTable.ext.type.order,\n\t\t\taoData = oSettings.aoData,\n\t\t\taoColumns = oSettings.aoColumns,\n\t\t\taDataSort, data, iCol, sType, oSort,\n\t\t\tformatters = 0,\n\t\t\tsortCol,\n\t\t\tdisplayMaster = oSettings.aiDisplayMaster,\n\t\t\taSort;\n\t\n\t\t// Resolve any column types that are unknown due to addition or invalidation\n\t\t// @todo Can this be moved into a 'data-ready' handler which is called when\n\t\t//   data is going to be used in the table?\n\t\t_fnColumnTypes( oSettings );\n\t\n\t\taSort = _fnSortFlatten( oSettings );\n\t\n\t\tfor ( i=0, ien=aSort.length ; i<ien ; i++ ) {\n\t\t\tsortCol = aSort[i];\n\t\n\t\t\t// Track if we can use the fast sort algorithm\n\t\t\tif ( sortCol.formatter ) {\n\t\t\t\tformatters++;\n\t\t\t}\n\t\n\t\t\t// Load the data needed for the sort, for each cell\n\t\t\t_fnSortData( oSettings, sortCol.col );\n\t\t}\n\t\n\t\t/* No sorting required if server-side or no sorting array */\n\t\tif ( _fnDataSource( oSettings ) != 'ssp' && aSort.length !== 0 )\n\t\t{\n\t\t\t// Create a value - key array of the current row positions such that we can use their\n\t\t\t// current position during the sort, if values match, in order to perform stable sorting\n\t\t\tfor ( i=0, iLen=displayMaster.length ; i<iLen ; i++ ) {\n\t\t\t\taiOrig[ displayMaster[i] ] = i;\n\t\t\t}\n\t\n\t\t\t/* Do the sort - here we want multi-column sorting based on a given data source (column)\n\t\t\t * and sorting function (from oSort) in a certain direction. It's reasonably complex to\n\t\t\t * follow on it's own, but this is what we want (example two column sorting):\n\t\t\t *  fnLocalSorting = function(a,b){\n\t\t\t *    var iTest;\n\t\t\t *    iTest = oSort['string-asc']('data11', 'data12');\n\t\t\t *      if (iTest !== 0)\n\t\t\t *        return iTest;\n\t\t\t *    iTest = oSort['numeric-desc']('data21', 'data22');\n\t\t\t *    if (iTest !== 0)\n\t\t\t *      return iTest;\n\t\t\t *    return oSort['numeric-asc']( aiOrig[a], aiOrig[b] );\n\t\t\t *  }\n\t\t\t * Basically we have a test for each sorting column, if the data in that column is equal,\n\t\t\t * test the next column. If all columns match, then we use a numeric sort on the row\n\t\t\t * positions in the original data array to provide a stable sort.\n\t\t\t *\n\t\t\t * Note - I know it seems excessive to have two sorting methods, but the first is around\n\t\t\t * 15% faster, so the second is only maintained for backwards compatibility with sorting\n\t\t\t * methods which do not have a pre-sort formatting function.\n\t\t\t */\n\t\t\tif ( formatters === aSort.length ) {\n\t\t\t\t// All sort types have formatting functions\n\t\t\t\tdisplayMaster.sort( function ( a, b ) {\n\t\t\t\t\tvar\n\t\t\t\t\t\tx, y, k, test, sort,\n\t\t\t\t\t\tlen=aSort.length,\n\t\t\t\t\t\tdataA = aoData[a]._aSortData,\n\t\t\t\t\t\tdataB = aoData[b]._aSortData;\n\t\n\t\t\t\t\tfor ( k=0 ; k<len ; k++ ) {\n\t\t\t\t\t\tsort = aSort[k];\n\t\n\t\t\t\t\t\tx = dataA[ sort.col ];\n\t\t\t\t\t\ty = dataB[ sort.col ];\n\t\n\t\t\t\t\t\ttest = x<y ? -1 : x>y ? 1 : 0;\n\t\t\t\t\t\tif ( test !== 0 ) {\n\t\t\t\t\t\t\treturn sort.dir === 'asc' ? test : -test;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\n\t\t\t\t\tx = aiOrig[a];\n\t\t\t\t\ty = aiOrig[b];\n\t\t\t\t\treturn x<y ? -1 : x>y ? 1 : 0;\n\t\t\t\t} );\n\t\t\t}\n\t\t\telse {\n\t\t\t\t// Depreciated - remove in 1.11 (providing a plug-in option)\n\t\t\t\t// Not all sort types have formatting methods, so we have to call their sorting\n\t\t\t\t// methods.\n\t\t\t\tdisplayMaster.sort( function ( a, b ) {\n\t\t\t\t\tvar\n\t\t\t\t\t\tx, y, k, l, test, sort, fn,\n\t\t\t\t\t\tlen=aSort.length,\n\t\t\t\t\t\tdataA = aoData[a]._aSortData,\n\t\t\t\t\t\tdataB = aoData[b]._aSortData;\n\t\n\t\t\t\t\tfor ( k=0 ; k<len ; k++ ) {\n\t\t\t\t\t\tsort = aSort[k];\n\t\n\t\t\t\t\t\tx = dataA[ sort.col ];\n\t\t\t\t\t\ty = dataB[ sort.col ];\n\t\n\t\t\t\t\t\tfn = oExtSort[ sort.type+\"-\"+sort.dir ] || oExtSort[ \"string-\"+sort.dir ];\n\t\t\t\t\t\ttest = fn( x, y );\n\t\t\t\t\t\tif ( test !== 0 ) {\n\t\t\t\t\t\t\treturn test;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\n\t\t\t\t\tx = aiOrig[a];\n\t\t\t\t\ty = aiOrig[b];\n\t\t\t\t\treturn x<y ? -1 : x>y ? 1 : 0;\n\t\t\t\t} );\n\t\t\t}\n\t\t}\n\t\n\t\t/* Tell the draw function that we have sorted the data */\n\t\toSettings.bSorted = true;\n\t}\n\t\n\t\n\tfunction _fnSortAria ( settings )\n\t{\n\t\tvar label;\n\t\tvar nextSort;\n\t\tvar columns = settings.aoColumns;\n\t\tvar aSort = _fnSortFlatten( settings );\n\t\tvar oAria = settings.oLanguage.oAria;\n\t\n\t\t// ARIA attributes - need to loop all columns, to update all (removing old\n\t\t// attributes as needed)\n\t\tfor ( var i=0, iLen=columns.length ; i<iLen ; i++ )\n\t\t{\n\t\t\tvar col = columns[i];\n\t\t\tvar asSorting = col.asSorting;\n\t\t\tvar sTitle = col.sTitle.replace( /<.*?>/g, \"\" );\n\t\t\tvar th = col.nTh;\n\t\n\t\t\t// IE7 is throwing an error when setting these properties with jQuery's\n\t\t\t// attr() and removeAttr() methods...\n\t\t\tth.removeAttribute('aria-sort');\n\t\n\t\t\t/* In ARIA only the first sorting column can be marked as sorting - no multi-sort option */\n\t\t\tif ( col.bSortable ) {\n\t\t\t\tif ( aSort.length > 0 && aSort[0].col == i ) {\n\t\t\t\t\tth.setAttribute('aria-sort', aSort[0].dir==\"asc\" ? \"ascending\" : \"descending\" );\n\t\t\t\t\tnextSort = asSorting[ aSort[0].index+1 ] || asSorting[0];\n\t\t\t\t}\n\t\t\t\telse {\n\t\t\t\t\tnextSort = asSorting[0];\n\t\t\t\t}\n\t\n\t\t\t\tlabel = sTitle + ( nextSort === \"asc\" ?\n\t\t\t\t\toAria.sSortAscending :\n\t\t\t\t\toAria.sSortDescending\n\t\t\t\t);\n\t\t\t}\n\t\t\telse {\n\t\t\t\tlabel = sTitle;\n\t\t\t}\n\t\n\t\t\tth.setAttribute('aria-label', label);\n\t\t}\n\t}\n\t\n\t\n\t/**\n\t * Function to run on user sort request\n\t *  @param {object} settings dataTables settings object\n\t *  @param {node} attachTo node to attach the handler to\n\t *  @param {int} colIdx column sorting index\n\t *  @param {boolean} [append=false] Append the requested sort to the existing\n\t *    sort if true (i.e. multi-column sort)\n\t *  @param {function} [callback] callback function\n\t *  @memberof DataTable#oApi\n\t */\n\tfunction _fnSortListener ( settings, colIdx, append, callback )\n\t{\n\t\tvar col = settings.aoColumns[ colIdx ];\n\t\tvar sorting = settings.aaSorting;\n\t\tvar asSorting = col.asSorting;\n\t\tvar nextSortIdx;\n\t\tvar next = function ( a, overflow ) {\n\t\t\tvar idx = a._idx;\n\t\t\tif ( idx === undefined ) {\n\t\t\t\tidx = $.inArray( a[1], asSorting );\n\t\t\t}\n\t\n\t\t\treturn idx+1 < asSorting.length ?\n\t\t\t\tidx+1 :\n\t\t\t\toverflow ?\n\t\t\t\t\tnull :\n\t\t\t\t\t0;\n\t\t};\n\t\n\t\t// Convert to 2D array if needed\n\t\tif ( typeof sorting[0] === 'number' ) {\n\t\t\tsorting = settings.aaSorting = [ sorting ];\n\t\t}\n\t\n\t\t// If appending the sort then we are multi-column sorting\n\t\tif ( append && settings.oFeatures.bSortMulti ) {\n\t\t\t// Are we already doing some kind of sort on this column?\n\t\t\tvar sortIdx = $.inArray( colIdx, _pluck(sorting, '0') );\n\t\n\t\t\tif ( sortIdx !== -1 ) {\n\t\t\t\t// Yes, modify the sort\n\t\t\t\tnextSortIdx = next( sorting[sortIdx], true );\n\t\n\t\t\t\tif ( nextSortIdx === null && sorting.length === 1 ) {\n\t\t\t\t\tnextSortIdx = 0; // can't remove sorting completely\n\t\t\t\t}\n\t\n\t\t\t\tif ( nextSortIdx === null ) {\n\t\t\t\t\tsorting.splice( sortIdx, 1 );\n\t\t\t\t}\n\t\t\t\telse {\n\t\t\t\t\tsorting[sortIdx][1] = asSorting[ nextSortIdx ];\n\t\t\t\t\tsorting[sortIdx]._idx = nextSortIdx;\n\t\t\t\t}\n\t\t\t}\n\t\t\telse {\n\t\t\t\t// No sort on this column yet\n\t\t\t\tsorting.push( [ colIdx, asSorting[0], 0 ] );\n\t\t\t\tsorting[sorting.length-1]._idx = 0;\n\t\t\t}\n\t\t}\n\t\telse if ( sorting.length && sorting[0][0] == colIdx ) {\n\t\t\t// Single column - already sorting on this column, modify the sort\n\t\t\tnextSortIdx = next( sorting[0] );\n\t\n\t\t\tsorting.length = 1;\n\t\t\tsorting[0][1] = asSorting[ nextSortIdx ];\n\t\t\tsorting[0]._idx = nextSortIdx;\n\t\t}\n\t\telse {\n\t\t\t// Single column - sort only on this column\n\t\t\tsorting.length = 0;\n\t\t\tsorting.push( [ colIdx, asSorting[0] ] );\n\t\t\tsorting[0]._idx = 0;\n\t\t}\n\t\n\t\t// Run the sort by calling a full redraw\n\t\t_fnReDraw( settings );\n\t\n\t\t// callback used for async user interaction\n\t\tif ( typeof callback == 'function' ) {\n\t\t\tcallback( settings );\n\t\t}\n\t}\n\t\n\t\n\t/**\n\t * Attach a sort handler (click) to a node\n\t *  @param {object} settings dataTables settings object\n\t *  @param {node} attachTo node to attach the handler to\n\t *  @param {int} colIdx column sorting index\n\t *  @param {function} [callback] callback function\n\t *  @memberof DataTable#oApi\n\t */\n\tfunction _fnSortAttachListener ( settings, attachTo, colIdx, callback )\n\t{\n\t\tvar col = settings.aoColumns[ colIdx ];\n\t\n\t\t_fnBindAction( attachTo, {}, function (e) {\n\t\t\t/* If the column is not sortable - don't to anything */\n\t\t\tif ( col.bSortable === false ) {\n\t\t\t\treturn;\n\t\t\t}\n\t\n\t\t\t// If processing is enabled use a timeout to allow the processing\n\t\t\t// display to be shown - otherwise to it synchronously\n\t\t\tif ( settings.oFeatures.bProcessing ) {\n\t\t\t\t_fnProcessingDisplay( settings, true );\n\t\n\t\t\t\tsetTimeout( function() {\n\t\t\t\t\t_fnSortListener( settings, colIdx, e.shiftKey, callback );\n\t\n\t\t\t\t\t// In server-side processing, the draw callback will remove the\n\t\t\t\t\t// processing display\n\t\t\t\t\tif ( _fnDataSource( settings ) !== 'ssp' ) {\n\t\t\t\t\t\t_fnProcessingDisplay( settings, false );\n\t\t\t\t\t}\n\t\t\t\t}, 0 );\n\t\t\t}\n\t\t\telse {\n\t\t\t\t_fnSortListener( settings, colIdx, e.shiftKey, callback );\n\t\t\t}\n\t\t} );\n\t}\n\t\n\t\n\t/**\n\t * Set the sorting classes on table's body, Note: it is safe to call this function\n\t * when bSort and bSortClasses are false\n\t *  @param {object} oSettings dataTables settings object\n\t *  @memberof DataTable#oApi\n\t */\n\tfunction _fnSortingClasses( settings )\n\t{\n\t\tvar oldSort = settings.aLastSort;\n\t\tvar sortClass = settings.oClasses.sSortColumn;\n\t\tvar sort = _fnSortFlatten( settings );\n\t\tvar features = settings.oFeatures;\n\t\tvar i, ien, colIdx;\n\t\n\t\tif ( features.bSort && features.bSortClasses ) {\n\t\t\t// Remove old sorting classes\n\t\t\tfor ( i=0, ien=oldSort.length ; i<ien ; i++ ) {\n\t\t\t\tcolIdx = oldSort[i].src;\n\t\n\t\t\t\t// Remove column sorting\n\t\t\t\t$( _pluck( settings.aoData, 'anCells', colIdx ) )\n\t\t\t\t\t.removeClass( sortClass + (i<2 ? i+1 : 3) );\n\t\t\t}\n\t\n\t\t\t// Add new column sorting\n\t\t\tfor ( i=0, ien=sort.length ; i<ien ; i++ ) {\n\t\t\t\tcolIdx = sort[i].src;\n\t\n\t\t\t\t$( _pluck( settings.aoData, 'anCells', colIdx ) )\n\t\t\t\t\t.addClass( sortClass + (i<2 ? i+1 : 3) );\n\t\t\t}\n\t\t}\n\t\n\t\tsettings.aLastSort = sort;\n\t}\n\t\n\t\n\t// Get the data to sort a column, be it from cache, fresh (populating the\n\t// cache), or from a sort formatter\n\tfunction _fnSortData( settings, idx )\n\t{\n\t\t// Custom sorting function - provided by the sort data type\n\t\tvar column = settings.aoColumns[ idx ];\n\t\tvar customSort = DataTable.ext.order[ column.sSortDataType ];\n\t\tvar customData;\n\t\n\t\tif ( customSort ) {\n\t\t\tcustomData = customSort.call( settings.oInstance, settings, idx,\n\t\t\t\t_fnColumnIndexToVisible( settings, idx )\n\t\t\t);\n\t\t}\n\t\n\t\t// Use / populate cache\n\t\tvar row, cellData;\n\t\tvar formatter = DataTable.ext.type.order[ column.sType+\"-pre\" ];\n\t\n\t\tfor ( var i=0, ien=settings.aoData.length ; i<ien ; i++ ) {\n\t\t\trow = settings.aoData[i];\n\t\n\t\t\tif ( ! row._aSortData ) {\n\t\t\t\trow._aSortData = [];\n\t\t\t}\n\t\n\t\t\tif ( ! row._aSortData[idx] || customSort ) {\n\t\t\t\tcellData = customSort ?\n\t\t\t\t\tcustomData[i] : // If there was a custom sort function, use data from there\n\t\t\t\t\t_fnGetCellData( settings, i, idx, 'sort' );\n\t\n\t\t\t\trow._aSortData[ idx ] = formatter ?\n\t\t\t\t\tformatter( cellData ) :\n\t\t\t\t\tcellData;\n\t\t\t}\n\t\t}\n\t}\n\t\n\t\n\t\n\t/**\n\t * Save the state of a table\n\t *  @param {object} oSettings dataTables settings object\n\t *  @memberof DataTable#oApi\n\t */\n\tfunction _fnSaveState ( settings )\n\t{\n\t\tif ( !settings.oFeatures.bStateSave || settings.bDestroying )\n\t\t{\n\t\t\treturn;\n\t\t}\n\t\n\t\t/* Store the interesting variables */\n\t\tvar state = {\n\t\t\ttime:    +new Date(),\n\t\t\tstart:   settings._iDisplayStart,\n\t\t\tlength:  settings._iDisplayLength,\n\t\t\torder:   $.extend( true, [], settings.aaSorting ),\n\t\t\tsearch:  _fnSearchToCamel( settings.oPreviousSearch ),\n\t\t\tcolumns: $.map( settings.aoColumns, function ( col, i ) {\n\t\t\t\treturn {\n\t\t\t\t\tvisible: col.bVisible,\n\t\t\t\t\tsearch: _fnSearchToCamel( settings.aoPreSearchCols[i] )\n\t\t\t\t};\n\t\t\t} )\n\t\t};\n\t\n\t\t_fnCallbackFire( settings, \"aoStateSaveParams\", 'stateSaveParams', [settings, state] );\n\t\n\t\tsettings.oSavedState = state;\n\t\tsettings.fnStateSaveCallback.call( settings.oInstance, settings, state );\n\t}\n\t\n\t\n\t/**\n\t * Attempt to load a saved table state\n\t *  @param {object} oSettings dataTables settings object\n\t *  @param {object} oInit DataTables init object so we can override settings\n\t *  @memberof DataTable#oApi\n\t */\n\tfunction _fnLoadState ( settings, oInit )\n\t{\n\t\tvar i, ien;\n\t\tvar columns = settings.aoColumns;\n\t\n\t\tif ( ! settings.oFeatures.bStateSave ) {\n\t\t\treturn;\n\t\t}\n\t\n\t\tvar state = settings.fnStateLoadCallback.call( settings.oInstance, settings );\n\t\tif ( ! state || ! state.time ) {\n\t\t\treturn;\n\t\t}\n\t\n\t\t/* Allow custom and plug-in manipulation functions to alter the saved data set and\n\t\t * cancelling of loading by returning false\n\t\t */\n\t\tvar abStateLoad = _fnCallbackFire( settings, 'aoStateLoadParams', 'stateLoadParams', [settings, state] );\n\t\tif ( $.inArray( false, abStateLoad ) !== -1 ) {\n\t\t\treturn;\n\t\t}\n\t\n\t\t/* Reject old data */\n\t\tvar duration = settings.iStateDuration;\n\t\tif ( duration > 0 && state.time < +new Date() - (duration*1000) ) {\n\t\t\treturn;\n\t\t}\n\t\n\t\t// Number of columns have changed - all bets are off, no restore of settings\n\t\tif ( columns.length !== state.columns.length ) {\n\t\t\treturn;\n\t\t}\n\t\n\t\t// Store the saved state so it might be accessed at any time\n\t\tsettings.oLoadedState = $.extend( true, {}, state );\n\t\n\t\t// Restore key features - todo - for 1.11 this needs to be done by\n\t\t// subscribed events\n\t\tif ( state.start !== undefined ) {\n\t\t\tsettings._iDisplayStart    = state.start;\n\t\t\tsettings.iInitDisplayStart = state.start;\n\t\t}\n\t\tif ( state.length !== undefined ) {\n\t\t\tsettings._iDisplayLength   = state.length;\n\t\t}\n\t\n\t\t// Order\n\t\tif ( state.order !== undefined ) {\n\t\t\tsettings.aaSorting = [];\n\t\t\t$.each( state.order, function ( i, col ) {\n\t\t\t\tsettings.aaSorting.push( col[0] >= columns.length ?\n\t\t\t\t\t[ 0, col[1] ] :\n\t\t\t\t\tcol\n\t\t\t\t);\n\t\t\t} );\n\t\t}\n\t\n\t\t// Search\n\t\tif ( state.search !== undefined ) {\n\t\t\t$.extend( settings.oPreviousSearch, _fnSearchToHung( state.search ) );\n\t\t}\n\t\n\t\t// Columns\n\t\tfor ( i=0, ien=state.columns.length ; i<ien ; i++ ) {\n\t\t\tvar col = state.columns[i];\n\t\n\t\t\t// Visibility\n\t\t\tif ( col.visible !== undefined ) {\n\t\t\t\tcolumns[i].bVisible = col.visible;\n\t\t\t}\n\t\n\t\t\t// Search\n\t\t\tif ( col.search !== undefined ) {\n\t\t\t\t$.extend( settings.aoPreSearchCols[i], _fnSearchToHung( col.search ) );\n\t\t\t}\n\t\t}\n\t\n\t\t_fnCallbackFire( settings, 'aoStateLoaded', 'stateLoaded', [settings, state] );\n\t}\n\t\n\t\n\t/**\n\t * Return the settings object for a particular table\n\t *  @param {node} table table we are using as a dataTable\n\t *  @returns {object} Settings object - or null if not found\n\t *  @memberof DataTable#oApi\n\t */\n\tfunction _fnSettingsFromNode ( table )\n\t{\n\t\tvar settings = DataTable.settings;\n\t\tvar idx = $.inArray( table, _pluck( settings, 'nTable' ) );\n\t\n\t\treturn idx !== -1 ?\n\t\t\tsettings[ idx ] :\n\t\t\tnull;\n\t}\n\t\n\t\n\t/**\n\t * Log an error message\n\t *  @param {object} settings dataTables settings object\n\t *  @param {int} level log error messages, or display them to the user\n\t *  @param {string} msg error message\n\t *  @param {int} tn Technical note id to get more information about the error.\n\t *  @memberof DataTable#oApi\n\t */\n\tfunction _fnLog( settings, level, msg, tn )\n\t{\n\t\tmsg = 'DataTables warning: '+\n\t\t\t(settings ? 'table id='+settings.sTableId+' - ' : '')+msg;\n\t\n\t\tif ( tn ) {\n\t\t\tmsg += '. For more information about this error, please see '+\n\t\t\t'http://datatables.net/tn/'+tn;\n\t\t}\n\t\n\t\tif ( ! level  ) {\n\t\t\t// Backwards compatibility pre 1.10\n\t\t\tvar ext = DataTable.ext;\n\t\t\tvar type = ext.sErrMode || ext.errMode;\n\t\n\t\t\tif ( settings ) {\n\t\t\t\t_fnCallbackFire( settings, null, 'error', [ settings, tn, msg ] );\n\t\t\t}\n\t\n\t\t\tif ( type == 'alert' ) {\n\t\t\t\talert( msg );\n\t\t\t}\n\t\t\telse if ( type == 'throw' ) {\n\t\t\t\tthrow new Error(msg);\n\t\t\t}\n\t\t\telse if ( typeof type == 'function' ) {\n\t\t\t\ttype( settings, tn, msg );\n\t\t\t}\n\t\t}\n\t\telse if ( window.console && console.log ) {\n\t\t\tconsole.log( msg );\n\t\t}\n\t}\n\t\n\t\n\t/**\n\t * See if a property is defined on one object, if so assign it to the other object\n\t *  @param {object} ret target object\n\t *  @param {object} src source object\n\t *  @param {string} name property\n\t *  @param {string} [mappedName] name to map too - optional, name used if not given\n\t *  @memberof DataTable#oApi\n\t */\n\tfunction _fnMap( ret, src, name, mappedName )\n\t{\n\t\tif ( $.isArray( name ) ) {\n\t\t\t$.each( name, function (i, val) {\n\t\t\t\tif ( $.isArray( val ) ) {\n\t\t\t\t\t_fnMap( ret, src, val[0], val[1] );\n\t\t\t\t}\n\t\t\t\telse {\n\t\t\t\t\t_fnMap( ret, src, val );\n\t\t\t\t}\n\t\t\t} );\n\t\n\t\t\treturn;\n\t\t}\n\t\n\t\tif ( mappedName === undefined ) {\n\t\t\tmappedName = name;\n\t\t}\n\t\n\t\tif ( src[name] !== undefined ) {\n\t\t\tret[mappedName] = src[name];\n\t\t}\n\t}\n\t\n\t\n\t/**\n\t * Extend objects - very similar to jQuery.extend, but deep copy objects, and\n\t * shallow copy arrays. The reason we need to do this, is that we don't want to\n\t * deep copy array init values (such as aaSorting) since the dev wouldn't be\n\t * able to override them, but we do want to deep copy arrays.\n\t *  @param {object} out Object to extend\n\t *  @param {object} extender Object from which the properties will be applied to\n\t *      out\n\t *  @param {boolean} breakRefs If true, then arrays will be sliced to take an\n\t *      independent copy with the exception of the `data` or `aaData` parameters\n\t *      if they are present. This is so you can pass in a collection to\n\t *      DataTables and have that used as your data source without breaking the\n\t *      references\n\t *  @returns {object} out Reference, just for convenience - out === the return.\n\t *  @memberof DataTable#oApi\n\t *  @todo This doesn't take account of arrays inside the deep copied objects.\n\t */\n\tfunction _fnExtend( out, extender, breakRefs )\n\t{\n\t\tvar val;\n\t\n\t\tfor ( var prop in extender ) {\n\t\t\tif ( extender.hasOwnProperty(prop) ) {\n\t\t\t\tval = extender[prop];\n\t\n\t\t\t\tif ( $.isPlainObject( val ) ) {\n\t\t\t\t\tif ( ! $.isPlainObject( out[prop] ) ) {\n\t\t\t\t\t\tout[prop] = {};\n\t\t\t\t\t}\n\t\t\t\t\t$.extend( true, out[prop], val );\n\t\t\t\t}\n\t\t\t\telse if ( breakRefs && prop !== 'data' && prop !== 'aaData' && $.isArray(val) ) {\n\t\t\t\t\tout[prop] = val.slice();\n\t\t\t\t}\n\t\t\t\telse {\n\t\t\t\t\tout[prop] = val;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\n\t\treturn out;\n\t}\n\t\n\t\n\t/**\n\t * Bind an event handers to allow a click or return key to activate the callback.\n\t * This is good for accessibility since a return on the keyboard will have the\n\t * same effect as a click, if the element has focus.\n\t *  @param {element} n Element to bind the action to\n\t *  @param {object} oData Data object to pass to the triggered function\n\t *  @param {function} fn Callback function for when the event is triggered\n\t *  @memberof DataTable#oApi\n\t */\n\tfunction _fnBindAction( n, oData, fn )\n\t{\n\t\t$(n)\n\t\t\t.bind( 'click.DT', oData, function (e) {\n\t\t\t\t\tn.blur(); // Remove focus outline for mouse users\n\t\t\t\t\tfn(e);\n\t\t\t\t} )\n\t\t\t.bind( 'keypress.DT', oData, function (e){\n\t\t\t\t\tif ( e.which === 13 ) {\n\t\t\t\t\t\te.preventDefault();\n\t\t\t\t\t\tfn(e);\n\t\t\t\t\t}\n\t\t\t\t} )\n\t\t\t.bind( 'selectstart.DT', function () {\n\t\t\t\t\t/* Take the brutal approach to cancelling text selection */\n\t\t\t\t\treturn false;\n\t\t\t\t} );\n\t}\n\t\n\t\n\t/**\n\t * Register a callback function. Easily allows a callback function to be added to\n\t * an array store of callback functions that can then all be called together.\n\t *  @param {object} oSettings dataTables settings object\n\t *  @param {string} sStore Name of the array storage for the callbacks in oSettings\n\t *  @param {function} fn Function to be called back\n\t *  @param {string} sName Identifying name for the callback (i.e. a label)\n\t *  @memberof DataTable#oApi\n\t */\n\tfunction _fnCallbackReg( oSettings, sStore, fn, sName )\n\t{\n\t\tif ( fn )\n\t\t{\n\t\t\toSettings[sStore].push( {\n\t\t\t\t\"fn\": fn,\n\t\t\t\t\"sName\": sName\n\t\t\t} );\n\t\t}\n\t}\n\t\n\t\n\t/**\n\t * Fire callback functions and trigger events. Note that the loop over the\n\t * callback array store is done backwards! Further note that you do not want to\n\t * fire off triggers in time sensitive applications (for example cell creation)\n\t * as its slow.\n\t *  @param {object} settings dataTables settings object\n\t *  @param {string} callbackArr Name of the array storage for the callbacks in\n\t *      oSettings\n\t *  @param {string} eventName Name of the jQuery custom event to trigger. If\n\t *      null no trigger is fired\n\t *  @param {array} args Array of arguments to pass to the callback function /\n\t *      trigger\n\t *  @memberof DataTable#oApi\n\t */\n\tfunction _fnCallbackFire( settings, callbackArr, eventName, args )\n\t{\n\t\tvar ret = [];\n\t\n\t\tif ( callbackArr ) {\n\t\t\tret = $.map( settings[callbackArr].slice().reverse(), function (val, i) {\n\t\t\t\treturn val.fn.apply( settings.oInstance, args );\n\t\t\t} );\n\t\t}\n\t\n\t\tif ( eventName !== null ) {\n\t\t\tvar e = $.Event( eventName+'.dt' );\n\t\n\t\t\t$(settings.nTable).trigger( e, args );\n\t\n\t\t\tret.push( e.result );\n\t\t}\n\t\n\t\treturn ret;\n\t}\n\t\n\t\n\tfunction _fnLengthOverflow ( settings )\n\t{\n\t\tvar\n\t\t\tstart = settings._iDisplayStart,\n\t\t\tend = settings.fnDisplayEnd(),\n\t\t\tlen = settings._iDisplayLength;\n\t\n\t\t/* If we have space to show extra rows (backing up from the end point - then do so */\n\t\tif ( start >= end )\n\t\t{\n\t\t\tstart = end - len;\n\t\t}\n\t\n\t\t// Keep the start record on the current page\n\t\tstart -= (start % len);\n\t\n\t\tif ( len === -1 || start < 0 )\n\t\t{\n\t\t\tstart = 0;\n\t\t}\n\t\n\t\tsettings._iDisplayStart = start;\n\t}\n\t\n\t\n\tfunction _fnRenderer( settings, type )\n\t{\n\t\tvar renderer = settings.renderer;\n\t\tvar host = DataTable.ext.renderer[type];\n\t\n\t\tif ( $.isPlainObject( renderer ) && renderer[type] ) {\n\t\t\t// Specific renderer for this type. If available use it, otherwise use\n\t\t\t// the default.\n\t\t\treturn host[renderer[type]] || host._;\n\t\t}\n\t\telse if ( typeof renderer === 'string' ) {\n\t\t\t// Common renderer - if there is one available for this type use it,\n\t\t\t// otherwise use the default\n\t\t\treturn host[renderer] || host._;\n\t\t}\n\t\n\t\t// Use the default\n\t\treturn host._;\n\t}\n\t\n\t\n\t/**\n\t * Detect the data source being used for the table. Used to simplify the code\n\t * a little (ajax) and to make it compress a little smaller.\n\t *\n\t *  @param {object} settings dataTables settings object\n\t *  @returns {string} Data source\n\t *  @memberof DataTable#oApi\n\t */\n\tfunction _fnDataSource ( settings )\n\t{\n\t\tif ( settings.oFeatures.bServerSide ) {\n\t\t\treturn 'ssp';\n\t\t}\n\t\telse if ( settings.ajax || settings.sAjaxSource ) {\n\t\t\treturn 'ajax';\n\t\t}\n\t\treturn 'dom';\n\t}\n\t\n\n\t\n\t\n\t/**\n\t * Computed structure of the DataTables API, defined by the options passed to\n\t * `DataTable.Api.register()` when building the API.\n\t *\n\t * The structure is built in order to speed creation and extension of the Api\n\t * objects since the extensions are effectively pre-parsed.\n\t *\n\t * The array is an array of objects with the following structure, where this\n\t * base array represents the Api prototype base:\n\t *\n\t *     [\n\t *       {\n\t *         name:      'data'                -- string   - Property name\n\t *         val:       function () {},       -- function - Api method (or undefined if just an object\n\t *         methodExt: [ ... ],              -- array    - Array of Api object definitions to extend the method result\n\t *         propExt:   [ ... ]               -- array    - Array of Api object definitions to extend the property\n\t *       },\n\t *       {\n\t *         name:     'row'\n\t *         val:       {},\n\t *         methodExt: [ ... ],\n\t *         propExt:   [\n\t *           {\n\t *             name:      'data'\n\t *             val:       function () {},\n\t *             methodExt: [ ... ],\n\t *             propExt:   [ ... ]\n\t *           },\n\t *           ...\n\t *         ]\n\t *       }\n\t *     ]\n\t *\n\t * @type {Array}\n\t * @ignore\n\t */\n\tvar __apiStruct = [];\n\t\n\t\n\t/**\n\t * `Array.prototype` reference.\n\t *\n\t * @type object\n\t * @ignore\n\t */\n\tvar __arrayProto = Array.prototype;\n\t\n\t\n\t/**\n\t * Abstraction for `context` parameter of the `Api` constructor to allow it to\n\t * take several different forms for ease of use.\n\t *\n\t * Each of the input parameter types will be converted to a DataTables settings\n\t * object where possible.\n\t *\n\t * @param  {string|node|jQuery|object} mixed DataTable identifier. Can be one\n\t *   of:\n\t *\n\t *   * `string` - jQuery selector. Any DataTables' matching the given selector\n\t *     with be found and used.\n\t *   * `node` - `TABLE` node which has already been formed into a DataTable.\n\t *   * `jQuery` - A jQuery object of `TABLE` nodes.\n\t *   * `object` - DataTables settings object\n\t *   * `DataTables.Api` - API instance\n\t * @return {array|null} Matching DataTables settings objects. `null` or\n\t *   `undefined` is returned if no matching DataTable is found.\n\t * @ignore\n\t */\n\tvar _toSettings = function ( mixed )\n\t{\n\t\tvar idx, jq;\n\t\tvar settings = DataTable.settings;\n\t\tvar tables = $.map( settings, function (el, i) {\n\t\t\treturn el.nTable;\n\t\t} );\n\t\n\t\tif ( ! mixed ) {\n\t\t\treturn [];\n\t\t}\n\t\telse if ( mixed.nTable && mixed.oApi ) {\n\t\t\t// DataTables settings object\n\t\t\treturn [ mixed ];\n\t\t}\n\t\telse if ( mixed.nodeName && mixed.nodeName.toLowerCase() === 'table' ) {\n\t\t\t// Table node\n\t\t\tidx = $.inArray( mixed, tables );\n\t\t\treturn idx !== -1 ? [ settings[idx] ] : null;\n\t\t}\n\t\telse if ( mixed && typeof mixed.settings === 'function' ) {\n\t\t\treturn mixed.settings().toArray();\n\t\t}\n\t\telse if ( typeof mixed === 'string' ) {\n\t\t\t// jQuery selector\n\t\t\tjq = $(mixed);\n\t\t}\n\t\telse if ( mixed instanceof $ ) {\n\t\t\t// jQuery object (also DataTables instance)\n\t\t\tjq = mixed;\n\t\t}\n\t\n\t\tif ( jq ) {\n\t\t\treturn jq.map( function(i) {\n\t\t\t\tidx = $.inArray( this, tables );\n\t\t\t\treturn idx !== -1 ? settings[idx] : null;\n\t\t\t} ).toArray();\n\t\t}\n\t};\n\t\n\t\n\t/**\n\t * DataTables API class - used to control and interface with  one or more\n\t * DataTables enhanced tables.\n\t *\n\t * The API class is heavily based on jQuery, presenting a chainable interface\n\t * that you can use to interact with tables. Each instance of the API class has\n\t * a \"context\" - i.e. the tables that it will operate on. This could be a single\n\t * table, all tables on a page or a sub-set thereof.\n\t *\n\t * Additionally the API is designed to allow you to easily work with the data in\n\t * the tables, retrieving and manipulating it as required. This is done by\n\t * presenting the API class as an array like interface. The contents of the\n\t * array depend upon the actions requested by each method (for example\n\t * `rows().nodes()` will return an array of nodes, while `rows().data()` will\n\t * return an array of objects or arrays depending upon your table's\n\t * configuration). The API object has a number of array like methods (`push`,\n\t * `pop`, `reverse` etc) as well as additional helper methods (`each`, `pluck`,\n\t * `unique` etc) to assist your working with the data held in a table.\n\t *\n\t * Most methods (those which return an Api instance) are chainable, which means\n\t * the return from a method call also has all of the methods available that the\n\t * top level object had. For example, these two calls are equivalent:\n\t *\n\t *     // Not chained\n\t *     api.row.add( {...} );\n\t *     api.draw();\n\t *\n\t *     // Chained\n\t *     api.row.add( {...} ).draw();\n\t *\n\t * @class DataTable.Api\n\t * @param {array|object|string|jQuery} context DataTable identifier. This is\n\t *   used to define which DataTables enhanced tables this API will operate on.\n\t *   Can be one of:\n\t *\n\t *   * `string` - jQuery selector. Any DataTables' matching the given selector\n\t *     with be found and used.\n\t *   * `node` - `TABLE` node which has already been formed into a DataTable.\n\t *   * `jQuery` - A jQuery object of `TABLE` nodes.\n\t *   * `object` - DataTables settings object\n\t * @param {array} [data] Data to initialise the Api instance with.\n\t *\n\t * @example\n\t *   // Direct initialisation during DataTables construction\n\t *   var api = $('#example').DataTable();\n\t *\n\t * @example\n\t *   // Initialisation using a DataTables jQuery object\n\t *   var api = $('#example').dataTable().api();\n\t *\n\t * @example\n\t *   // Initialisation as a constructor\n\t *   var api = new $.fn.DataTable.Api( 'table.dataTable' );\n\t */\n\t_Api = function ( context, data )\n\t{\n\t\tif ( ! (this instanceof _Api) ) {\n\t\t\treturn new _Api( context, data );\n\t\t}\n\t\n\t\tvar settings = [];\n\t\tvar ctxSettings = function ( o ) {\n\t\t\tvar a = _toSettings( o );\n\t\t\tif ( a ) {\n\t\t\t\tsettings = settings.concat( a );\n\t\t\t}\n\t\t};\n\t\n\t\tif ( $.isArray( context ) ) {\n\t\t\tfor ( var i=0, ien=context.length ; i<ien ; i++ ) {\n\t\t\t\tctxSettings( context[i] );\n\t\t\t}\n\t\t}\n\t\telse {\n\t\t\tctxSettings( context );\n\t\t}\n\t\n\t\t// Remove duplicates\n\t\tthis.context = _unique( settings );\n\t\n\t\t// Initial data\n\t\tif ( data ) {\n\t\t\t$.merge( this, data );\n\t\t}\n\t\n\t\t// selector\n\t\tthis.selector = {\n\t\t\trows: null,\n\t\t\tcols: null,\n\t\t\topts: null\n\t\t};\n\t\n\t\t_Api.extend( this, this, __apiStruct );\n\t};\n\t\n\tDataTable.Api = _Api;\n\t\n\t// Don't destroy the existing prototype, just extend it. Required for jQuery 2's\n\t// isPlainObject.\n\t$.extend( _Api.prototype, {\n\t\tany: function ()\n\t\t{\n\t\t\treturn this.count() !== 0;\n\t\t},\n\t\n\t\n\t\tconcat:  __arrayProto.concat,\n\t\n\t\n\t\tcontext: [], // array of table settings objects\n\t\n\t\n\t\tcount: function ()\n\t\t{\n\t\t\treturn this.flatten().length;\n\t\t},\n\t\n\t\n\t\teach: function ( fn )\n\t\t{\n\t\t\tfor ( var i=0, ien=this.length ; i<ien; i++ ) {\n\t\t\t\tfn.call( this, this[i], i, this );\n\t\t\t}\n\t\n\t\t\treturn this;\n\t\t},\n\t\n\t\n\t\teq: function ( idx )\n\t\t{\n\t\t\tvar ctx = this.context;\n\t\n\t\t\treturn ctx.length > idx ?\n\t\t\t\tnew _Api( ctx[idx], this[idx] ) :\n\t\t\t\tnull;\n\t\t},\n\t\n\t\n\t\tfilter: function ( fn )\n\t\t{\n\t\t\tvar a = [];\n\t\n\t\t\tif ( __arrayProto.filter ) {\n\t\t\t\ta = __arrayProto.filter.call( this, fn, this );\n\t\t\t}\n\t\t\telse {\n\t\t\t\t// Compatibility for browsers without EMCA-252-5 (JS 1.6)\n\t\t\t\tfor ( var i=0, ien=this.length ; i<ien ; i++ ) {\n\t\t\t\t\tif ( fn.call( this, this[i], i, this ) ) {\n\t\t\t\t\t\ta.push( this[i] );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\n\t\t\treturn new _Api( this.context, a );\n\t\t},\n\t\n\t\n\t\tflatten: function ()\n\t\t{\n\t\t\tvar a = [];\n\t\t\treturn new _Api( this.context, a.concat.apply( a, this.toArray() ) );\n\t\t},\n\t\n\t\n\t\tjoin:    __arrayProto.join,\n\t\n\t\n\t\tindexOf: __arrayProto.indexOf || function (obj, start)\n\t\t{\n\t\t\tfor ( var i=(start || 0), ien=this.length ; i<ien ; i++ ) {\n\t\t\t\tif ( this[i] === obj ) {\n\t\t\t\t\treturn i;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn -1;\n\t\t},\n\t\n\t\titerator: function ( flatten, type, fn, alwaysNew ) {\n\t\t\tvar\n\t\t\t\ta = [], ret,\n\t\t\t\ti, ien, j, jen,\n\t\t\t\tcontext = this.context,\n\t\t\t\trows, items, item,\n\t\t\t\tselector = this.selector;\n\t\n\t\t\t// Argument shifting\n\t\t\tif ( typeof flatten === 'string' ) {\n\t\t\t\talwaysNew = fn;\n\t\t\t\tfn = type;\n\t\t\t\ttype = flatten;\n\t\t\t\tflatten = false;\n\t\t\t}\n\t\n\t\t\tfor ( i=0, ien=context.length ; i<ien ; i++ ) {\n\t\t\t\tvar apiInst = new _Api( context[i] );\n\t\n\t\t\t\tif ( type === 'table' ) {\n\t\t\t\t\tret = fn.call( apiInst, context[i], i );\n\t\n\t\t\t\t\tif ( ret !== undefined ) {\n\t\t\t\t\t\ta.push( ret );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\telse if ( type === 'columns' || type === 'rows' ) {\n\t\t\t\t\t// this has same length as context - one entry for each table\n\t\t\t\t\tret = fn.call( apiInst, context[i], this[i], i );\n\t\n\t\t\t\t\tif ( ret !== undefined ) {\n\t\t\t\t\t\ta.push( ret );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\telse if ( type === 'column' || type === 'column-rows' || type === 'row' || type === 'cell' ) {\n\t\t\t\t\t// columns and rows share the same structure.\n\t\t\t\t\t// 'this' is an array of column indexes for each context\n\t\t\t\t\titems = this[i];\n\t\n\t\t\t\t\tif ( type === 'column-rows' ) {\n\t\t\t\t\t\trows = _selector_row_indexes( context[i], selector.opts );\n\t\t\t\t\t}\n\t\n\t\t\t\t\tfor ( j=0, jen=items.length ; j<jen ; j++ ) {\n\t\t\t\t\t\titem = items[j];\n\t\n\t\t\t\t\t\tif ( type === 'cell' ) {\n\t\t\t\t\t\t\tret = fn.call( apiInst, context[i], item.row, item.column, i, j );\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse {\n\t\t\t\t\t\t\tret = fn.call( apiInst, context[i], item, i, j, rows );\n\t\t\t\t\t\t}\n\t\n\t\t\t\t\t\tif ( ret !== undefined ) {\n\t\t\t\t\t\t\ta.push( ret );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\n\t\t\tif ( a.length || alwaysNew ) {\n\t\t\t\tvar api = new _Api( context, flatten ? a.concat.apply( [], a ) : a );\n\t\t\t\tvar apiSelector = api.selector;\n\t\t\t\tapiSelector.rows = selector.rows;\n\t\t\t\tapiSelector.cols = selector.cols;\n\t\t\t\tapiSelector.opts = selector.opts;\n\t\t\t\treturn api;\n\t\t\t}\n\t\t\treturn this;\n\t\t},\n\t\n\t\n\t\tlastIndexOf: __arrayProto.lastIndexOf || function (obj, start)\n\t\t{\n\t\t\t// Bit cheeky...\n\t\t\treturn this.indexOf.apply( this.toArray.reverse(), arguments );\n\t\t},\n\t\n\t\n\t\tlength:  0,\n\t\n\t\n\t\tmap: function ( fn )\n\t\t{\n\t\t\tvar a = [];\n\t\n\t\t\tif ( __arrayProto.map ) {\n\t\t\t\ta = __arrayProto.map.call( this, fn, this );\n\t\t\t}\n\t\t\telse {\n\t\t\t\t// Compatibility for browsers without EMCA-252-5 (JS 1.6)\n\t\t\t\tfor ( var i=0, ien=this.length ; i<ien ; i++ ) {\n\t\t\t\t\ta.push( fn.call( this, this[i], i ) );\n\t\t\t\t}\n\t\t\t}\n\t\n\t\t\treturn new _Api( this.context, a );\n\t\t},\n\t\n\t\n\t\tpluck: function ( prop )\n\t\t{\n\t\t\treturn this.map( function ( el ) {\n\t\t\t\treturn el[ prop ];\n\t\t\t} );\n\t\t},\n\t\n\t\tpop:     __arrayProto.pop,\n\t\n\t\n\t\tpush:    __arrayProto.push,\n\t\n\t\n\t\t// Does not return an API instance\n\t\treduce: __arrayProto.reduce || function ( fn, init )\n\t\t{\n\t\t\treturn _fnReduce( this, fn, init, 0, this.length, 1 );\n\t\t},\n\t\n\t\n\t\treduceRight: __arrayProto.reduceRight || function ( fn, init )\n\t\t{\n\t\t\treturn _fnReduce( this, fn, init, this.length-1, -1, -1 );\n\t\t},\n\t\n\t\n\t\treverse: __arrayProto.reverse,\n\t\n\t\n\t\t// Object with rows, columns and opts\n\t\tselector: null,\n\t\n\t\n\t\tshift:   __arrayProto.shift,\n\t\n\t\n\t\tsort:    __arrayProto.sort, // ? name - order?\n\t\n\t\n\t\tsplice:  __arrayProto.splice,\n\t\n\t\n\t\ttoArray: function ()\n\t\t{\n\t\t\treturn __arrayProto.slice.call( this );\n\t\t},\n\t\n\t\n\t\tto$: function ()\n\t\t{\n\t\t\treturn $( this );\n\t\t},\n\t\n\t\n\t\ttoJQuery: function ()\n\t\t{\n\t\t\treturn $( this );\n\t\t},\n\t\n\t\n\t\tunique: function ()\n\t\t{\n\t\t\treturn new _Api( this.context, _unique(this) );\n\t\t},\n\t\n\t\n\t\tunshift: __arrayProto.unshift\n\t} );\n\t\n\t\n\t_Api.extend = function ( scope, obj, ext )\n\t{\n\t\t// Only extend API instances and static properties of the API\n\t\tif ( ! ext.length || ! obj || ( ! (obj instanceof _Api) && ! obj.__dt_wrapper ) ) {\n\t\t\treturn;\n\t\t}\n\t\n\t\tvar\n\t\t\ti, ien,\n\t\t\tj, jen,\n\t\t\tstruct, inner,\n\t\t\tmethodScoping = function ( scope, fn, struc ) {\n\t\t\t\treturn function () {\n\t\t\t\t\tvar ret = fn.apply( scope, arguments );\n\t\n\t\t\t\t\t// Method extension\n\t\t\t\t\t_Api.extend( ret, ret, struc.methodExt );\n\t\t\t\t\treturn ret;\n\t\t\t\t};\n\t\t\t};\n\t\n\t\tfor ( i=0, ien=ext.length ; i<ien ; i++ ) {\n\t\t\tstruct = ext[i];\n\t\n\t\t\t// Value\n\t\t\tobj[ struct.name ] = typeof struct.val === 'function' ?\n\t\t\t\tmethodScoping( scope, struct.val, struct ) :\n\t\t\t\t$.isPlainObject( struct.val ) ?\n\t\t\t\t\t{} :\n\t\t\t\t\tstruct.val;\n\t\n\t\t\tobj[ struct.name ].__dt_wrapper = true;\n\t\n\t\t\t// Property extension\n\t\t\t_Api.extend( scope, obj[ struct.name ], struct.propExt );\n\t\t}\n\t};\n\t\n\t\n\t// @todo - Is there need for an augment function?\n\t// _Api.augment = function ( inst, name )\n\t// {\n\t// \t// Find src object in the structure from the name\n\t// \tvar parts = name.split('.');\n\t\n\t// \t_Api.extend( inst, obj );\n\t// };\n\t\n\t\n\t//     [\n\t//       {\n\t//         name:      'data'                -- string   - Property name\n\t//         val:       function () {},       -- function - Api method (or undefined if just an object\n\t//         methodExt: [ ... ],              -- array    - Array of Api object definitions to extend the method result\n\t//         propExt:   [ ... ]               -- array    - Array of Api object definitions to extend the property\n\t//       },\n\t//       {\n\t//         name:     'row'\n\t//         val:       {},\n\t//         methodExt: [ ... ],\n\t//         propExt:   [\n\t//           {\n\t//             name:      'data'\n\t//             val:       function () {},\n\t//             methodExt: [ ... ],\n\t//             propExt:   [ ... ]\n\t//           },\n\t//           ...\n\t//         ]\n\t//       }\n\t//     ]\n\t\n\t_Api.register = _api_register = function ( name, val )\n\t{\n\t\tif ( $.isArray( name ) ) {\n\t\t\tfor ( var j=0, jen=name.length ; j<jen ; j++ ) {\n\t\t\t\t_Api.register( name[j], val );\n\t\t\t}\n\t\t\treturn;\n\t\t}\n\t\n\t\tvar\n\t\t\ti, ien,\n\t\t\their = name.split('.'),\n\t\t\tstruct = __apiStruct,\n\t\t\tkey, method;\n\t\n\t\tvar find = function ( src, name ) {\n\t\t\tfor ( var i=0, ien=src.length ; i<ien ; i++ ) {\n\t\t\t\tif ( src[i].name === name ) {\n\t\t\t\t\treturn src[i];\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn null;\n\t\t};\n\t\n\t\tfor ( i=0, ien=heir.length ; i<ien ; i++ ) {\n\t\t\tmethod = heir[i].indexOf('()') !== -1;\n\t\t\tkey = method ?\n\t\t\t\their[i].replace('()', '') :\n\t\t\t\their[i];\n\t\n\t\t\tvar src = find( struct, key );\n\t\t\tif ( ! src ) {\n\t\t\t\tsrc = {\n\t\t\t\t\tname:      key,\n\t\t\t\t\tval:       {},\n\t\t\t\t\tmethodExt: [],\n\t\t\t\t\tpropExt:   []\n\t\t\t\t};\n\t\t\t\tstruct.push( src );\n\t\t\t}\n\t\n\t\t\tif ( i === ien-1 ) {\n\t\t\t\tsrc.val = val;\n\t\t\t}\n\t\t\telse {\n\t\t\t\tstruct = method ?\n\t\t\t\t\tsrc.methodExt :\n\t\t\t\t\tsrc.propExt;\n\t\t\t}\n\t\t}\n\t};\n\t\n\t\n\t_Api.registerPlural = _api_registerPlural = function ( pluralName, singularName, val ) {\n\t\t_Api.register( pluralName, val );\n\t\n\t\t_Api.register( singularName, function () {\n\t\t\tvar ret = val.apply( this, arguments );\n\t\n\t\t\tif ( ret === this ) {\n\t\t\t\t// Returned item is the API instance that was passed in, return it\n\t\t\t\treturn this;\n\t\t\t}\n\t\t\telse if ( ret instanceof _Api ) {\n\t\t\t\t// New API instance returned, want the value from the first item\n\t\t\t\t// in the returned array for the singular result.\n\t\t\t\treturn ret.length ?\n\t\t\t\t\t$.isArray( ret[0] ) ?\n\t\t\t\t\t\tnew _Api( ret.context, ret[0] ) : // Array results are 'enhanced'\n\t\t\t\t\t\tret[0] :\n\t\t\t\t\tundefined;\n\t\t\t}\n\t\n\t\t\t// Non-API return - just fire it back\n\t\t\treturn ret;\n\t\t} );\n\t};\n\t\n\t\n\t/**\n\t * Selector for HTML tables. Apply the given selector to the give array of\n\t * DataTables settings objects.\n\t *\n\t * @param {string|integer} [selector] jQuery selector string or integer\n\t * @param  {array} Array of DataTables settings objects to be filtered\n\t * @return {array}\n\t * @ignore\n\t */\n\tvar __table_selector = function ( selector, a )\n\t{\n\t\t// Integer is used to pick out a table by index\n\t\tif ( typeof selector === 'number' ) {\n\t\t\treturn [ a[ selector ] ];\n\t\t}\n\t\n\t\t// Perform a jQuery selector on the table nodes\n\t\tvar nodes = $.map( a, function (el, i) {\n\t\t\treturn el.nTable;\n\t\t} );\n\t\n\t\treturn $(nodes)\n\t\t\t.filter( selector )\n\t\t\t.map( function (i) {\n\t\t\t\t// Need to translate back from the table node to the settings\n\t\t\t\tvar idx = $.inArray( this, nodes );\n\t\t\t\treturn a[ idx ];\n\t\t\t} )\n\t\t\t.toArray();\n\t};\n\t\n\t\n\t\n\t/**\n\t * Context selector for the API's context (i.e. the tables the API instance\n\t * refers to.\n\t *\n\t * @name    DataTable.Api#tables\n\t * @param {string|integer} [selector] Selector to pick which tables the iterator\n\t *   should operate on. If not given, all tables in the current context are\n\t *   used. This can be given as a jQuery selector (for example `':gt(0)'`) to\n\t *   select multiple tables or as an integer to select a single table.\n\t * @returns {DataTable.Api} Returns a new API instance if a selector is given.\n\t */\n\t_api_register( 'tables()', function ( selector ) {\n\t\t// A new instance is created if there was a selector specified\n\t\treturn selector ?\n\t\t\tnew _Api( __table_selector( selector, this.context ) ) :\n\t\t\tthis;\n\t} );\n\t\n\t\n\t_api_register( 'table()', function ( selector ) {\n\t\tvar tables = this.tables( selector );\n\t\tvar ctx = tables.context;\n\t\n\t\t// Truncate to the first matched table\n\t\treturn ctx.length ?\n\t\t\tnew _Api( ctx[0] ) :\n\t\t\ttables;\n\t} );\n\t\n\t\n\t_api_registerPlural( 'tables().nodes()', 'table().node()' , function () {\n\t\treturn this.iterator( 'table', function ( ctx ) {\n\t\t\treturn ctx.nTable;\n\t\t}, 1 );\n\t} );\n\t\n\t\n\t_api_registerPlural( 'tables().body()', 'table().body()' , function () {\n\t\treturn this.iterator( 'table', function ( ctx ) {\n\t\t\treturn ctx.nTBody;\n\t\t}, 1 );\n\t} );\n\t\n\t\n\t_api_registerPlural( 'tables().header()', 'table().header()' , function () {\n\t\treturn this.iterator( 'table', function ( ctx ) {\n\t\t\treturn ctx.nTHead;\n\t\t}, 1 );\n\t} );\n\t\n\t\n\t_api_registerPlural( 'tables().footer()', 'table().footer()' , function () {\n\t\treturn this.iterator( 'table', function ( ctx ) {\n\t\t\treturn ctx.nTFoot;\n\t\t}, 1 );\n\t} );\n\t\n\t\n\t_api_registerPlural( 'tables().containers()', 'table().container()' , function () {\n\t\treturn this.iterator( 'table', function ( ctx ) {\n\t\t\treturn ctx.nTableWrapper;\n\t\t}, 1 );\n\t} );\n\t\n\t\n\t\n\t/**\n\t * Redraw the tables in the current context.\n\t */\n\t_api_register( 'draw()', function ( paging ) {\n\t\treturn this.iterator( 'table', function ( settings ) {\n\t\t\tif ( paging === 'page' ) {\n\t\t\t\t_fnDraw( settings );\n\t\t\t}\n\t\t\telse {\n\t\t\t\tif ( typeof paging === 'string' ) {\n\t\t\t\t\tpaging = paging === 'full-hold' ?\n\t\t\t\t\t\tfalse :\n\t\t\t\t\t\ttrue;\n\t\t\t\t}\n\t\n\t\t\t\t_fnReDraw( settings, paging===false );\n\t\t\t}\n\t\t} );\n\t} );\n\t\n\t\n\t\n\t/**\n\t * Get the current page index.\n\t *\n\t * @return {integer} Current page index (zero based)\n\t *//**\n\t * Set the current page.\n\t *\n\t * Note that if you attempt to show a page which does not exist, DataTables will\n\t * not throw an error, but rather reset the paging.\n\t *\n\t * @param {integer|string} action The paging action to take. This can be one of:\n\t *  * `integer` - The page index to jump to\n\t *  * `string` - An action to take:\n\t *    * `first` - Jump to first page.\n\t *    * `next` - Jump to the next page\n\t *    * `previous` - Jump to previous page\n\t *    * `last` - Jump to the last page.\n\t * @returns {DataTables.Api} this\n\t */\n\t_api_register( 'page()', function ( action ) {\n\t\tif ( action === undefined ) {\n\t\t\treturn this.page.info().page; // not an expensive call\n\t\t}\n\t\n\t\t// else, have an action to take on all tables\n\t\treturn this.iterator( 'table', function ( settings ) {\n\t\t\t_fnPageChange( settings, action );\n\t\t} );\n\t} );\n\t\n\t\n\t/**\n\t * Paging information for the first table in the current context.\n\t *\n\t * If you require paging information for another table, use the `table()` method\n\t * with a suitable selector.\n\t *\n\t * @return {object} Object with the following properties set:\n\t *  * `page` - Current page index (zero based - i.e. the first page is `0`)\n\t *  * `pages` - Total number of pages\n\t *  * `start` - Display index for the first record shown on the current page\n\t *  * `end` - Display index for the last record shown on the current page\n\t *  * `length` - Display length (number of records). Note that generally `start\n\t *    + length = end`, but this is not always true, for example if there are\n\t *    only 2 records to show on the final page, with a length of 10.\n\t *  * `recordsTotal` - Full data set length\n\t *  * `recordsDisplay` - Data set length once the current filtering criterion\n\t *    are applied.\n\t */\n\t_api_register( 'page.info()', function ( action ) {\n\t\tif ( this.context.length === 0 ) {\n\t\t\treturn undefined;\n\t\t}\n\t\n\t\tvar\n\t\t\tsettings   = this.context[0],\n\t\t\tstart      = settings._iDisplayStart,\n\t\t\tlen        = settings.oFeatures.bPaginate ? settings._iDisplayLength : -1,\n\t\t\tvisRecords = settings.fnRecordsDisplay(),\n\t\t\tall        = len === -1;\n\t\n\t\treturn {\n\t\t\t\"page\":           all ? 0 : Math.floor( start / len ),\n\t\t\t\"pages\":          all ? 1 : Math.ceil( visRecords / len ),\n\t\t\t\"start\":          start,\n\t\t\t\"end\":            settings.fnDisplayEnd(),\n\t\t\t\"length\":         len,\n\t\t\t\"recordsTotal\":   settings.fnRecordsTotal(),\n\t\t\t\"recordsDisplay\": visRecords,\n\t\t\t\"serverSide\":     _fnDataSource( settings ) === 'ssp'\n\t\t};\n\t} );\n\t\n\t\n\t/**\n\t * Get the current page length.\n\t *\n\t * @return {integer} Current page length. Note `-1` indicates that all records\n\t *   are to be shown.\n\t *//**\n\t * Set the current page length.\n\t *\n\t * @param {integer} Page length to set. Use `-1` to show all records.\n\t * @returns {DataTables.Api} this\n\t */\n\t_api_register( 'page.len()', function ( len ) {\n\t\t// Note that we can't call this function 'length()' because `length`\n\t\t// is a Javascript property of functions which defines how many arguments\n\t\t// the function expects.\n\t\tif ( len === undefined ) {\n\t\t\treturn this.context.length !== 0 ?\n\t\t\t\tthis.context[0]._iDisplayLength :\n\t\t\t\tundefined;\n\t\t}\n\t\n\t\t// else, set the page length\n\t\treturn this.iterator( 'table', function ( settings ) {\n\t\t\t_fnLengthChange( settings, len );\n\t\t} );\n\t} );\n\t\n\t\n\t\n\tvar __reload = function ( settings, holdPosition, callback ) {\n\t\t// Use the draw event to trigger a callback\n\t\tif ( callback ) {\n\t\t\tvar api = new _Api( settings );\n\t\n\t\t\tapi.one( 'draw', function () {\n\t\t\t\tcallback( api.ajax.json() );\n\t\t\t} );\n\t\t}\n\t\n\t\tif ( _fnDataSource( settings ) == 'ssp' ) {\n\t\t\t_fnReDraw( settings, holdPosition );\n\t\t}\n\t\telse {\n\t\t\t_fnProcessingDisplay( settings, true );\n\t\n\t\t\t// Cancel an existing request\n\t\t\tvar xhr = settings.jqXHR;\n\t\t\tif ( xhr && xhr.readyState !== 4 ) {\n\t\t\t\txhr.abort();\n\t\t\t}\n\t\n\t\t\t// Trigger xhr\n\t\t\t_fnBuildAjax( settings, [], function( json ) {\n\t\t\t\t_fnClearTable( settings );\n\t\n\t\t\t\tvar data = _fnAjaxDataSrc( settings, json );\n\t\t\t\tfor ( var i=0, ien=data.length ; i<ien ; i++ ) {\n\t\t\t\t\t_fnAddData( settings, data[i] );\n\t\t\t\t}\n\t\n\t\t\t\t_fnReDraw( settings, holdPosition );\n\t\t\t\t_fnProcessingDisplay( settings, false );\n\t\t\t} );\n\t\t}\n\t};\n\t\n\t\n\t/**\n\t * Get the JSON response from the last Ajax request that DataTables made to the\n\t * server. Note that this returns the JSON from the first table in the current\n\t * context.\n\t *\n\t * @return {object} JSON received from the server.\n\t */\n\t_api_register( 'ajax.json()', function () {\n\t\tvar ctx = this.context;\n\t\n\t\tif ( ctx.length > 0 ) {\n\t\t\treturn ctx[0].json;\n\t\t}\n\t\n\t\t// else return undefined;\n\t} );\n\t\n\t\n\t/**\n\t * Get the data submitted in the last Ajax request\n\t */\n\t_api_register( 'ajax.params()', function () {\n\t\tvar ctx = this.context;\n\t\n\t\tif ( ctx.length > 0 ) {\n\t\t\treturn ctx[0].oAjaxData;\n\t\t}\n\t\n\t\t// else return undefined;\n\t} );\n\t\n\t\n\t/**\n\t * Reload tables from the Ajax data source. Note that this function will\n\t * automatically re-draw the table when the remote data has been loaded.\n\t *\n\t * @param {boolean} [reset=true] Reset (default) or hold the current paging\n\t *   position. A full re-sort and re-filter is performed when this method is\n\t *   called, which is why the pagination reset is the default action.\n\t * @returns {DataTables.Api} this\n\t */\n\t_api_register( 'ajax.reload()', function ( callback, resetPaging ) {\n\t\treturn this.iterator( 'table', function (settings) {\n\t\t\t__reload( settings, resetPaging===false, callback );\n\t\t} );\n\t} );\n\t\n\t\n\t/**\n\t * Get the current Ajax URL. Note that this returns the URL from the first\n\t * table in the current context.\n\t *\n\t * @return {string} Current Ajax source URL\n\t *//**\n\t * Set the Ajax URL. Note that this will set the URL for all tables in the\n\t * current context.\n\t *\n\t * @param {string} url URL to set.\n\t * @returns {DataTables.Api} this\n\t */\n\t_api_register( 'ajax.url()', function ( url ) {\n\t\tvar ctx = this.context;\n\t\n\t\tif ( url === undefined ) {\n\t\t\t// get\n\t\t\tif ( ctx.length === 0 ) {\n\t\t\t\treturn undefined;\n\t\t\t}\n\t\t\tctx = ctx[0];\n\t\n\t\t\treturn ctx.ajax ?\n\t\t\t\t$.isPlainObject( ctx.ajax ) ?\n\t\t\t\t\tctx.ajax.url :\n\t\t\t\t\tctx.ajax :\n\t\t\t\tctx.sAjaxSource;\n\t\t}\n\t\n\t\t// set\n\t\treturn this.iterator( 'table', function ( settings ) {\n\t\t\tif ( $.isPlainObject( settings.ajax ) ) {\n\t\t\t\tsettings.ajax.url = url;\n\t\t\t}\n\t\t\telse {\n\t\t\t\tsettings.ajax = url;\n\t\t\t}\n\t\t\t// No need to consider sAjaxSource here since DataTables gives priority\n\t\t\t// to `ajax` over `sAjaxSource`. So setting `ajax` here, renders any\n\t\t\t// value of `sAjaxSource` redundant.\n\t\t} );\n\t} );\n\t\n\t\n\t/**\n\t * Load data from the newly set Ajax URL. Note that this method is only\n\t * available when `ajax.url()` is used to set a URL. Additionally, this method\n\t * has the same effect as calling `ajax.reload()` but is provided for\n\t * convenience when setting a new URL. Like `ajax.reload()` it will\n\t * automatically redraw the table once the remote data has been loaded.\n\t *\n\t * @returns {DataTables.Api} this\n\t */\n\t_api_register( 'ajax.url().load()', function ( callback, resetPaging ) {\n\t\t// Same as a reload, but makes sense to present it for easy access after a\n\t\t// url change\n\t\treturn this.iterator( 'table', function ( ctx ) {\n\t\t\t__reload( ctx, resetPaging===false, callback );\n\t\t} );\n\t} );\n\t\n\t\n\t\n\t\n\tvar _selector_run = function ( type, selector, selectFn, settings, opts )\n\t{\n\t\tvar\n\t\t\tout = [], res,\n\t\t\ta, i, ien, j, jen,\n\t\t\tselectorType = typeof selector;\n\t\n\t\t// Can't just check for isArray here, as an API or jQuery instance might be\n\t\t// given with their array like look\n\t\tif ( ! selector || selectorType === 'string' || selectorType === 'function' || selector.length === undefined ) {\n\t\t\tselector = [ selector ];\n\t\t}\n\t\n\t\tfor ( i=0, ien=selector.length ; i<ien ; i++ ) {\n\t\t\ta = selector[i] && selector[i].split ?\n\t\t\t\tselector[i].split(',') :\n\t\t\t\t[ selector[i] ];\n\t\n\t\t\tfor ( j=0, jen=a.length ; j<jen ; j++ ) {\n\t\t\t\tres = selectFn( typeof a[j] === 'string' ? $.trim(a[j]) : a[j] );\n\t\n\t\t\t\tif ( res && res.length ) {\n\t\t\t\t\tout = out.concat( res );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\n\t\t// selector extensions\n\t\tvar ext = _ext.selector[ type ];\n\t\tif ( ext.length ) {\n\t\t\tfor ( i=0, ien=ext.length ; i<ien ; i++ ) {\n\t\t\t\tout = ext[i]( settings, opts, out );\n\t\t\t}\n\t\t}\n\t\n\t\treturn _unique( out );\n\t};\n\t\n\t\n\tvar _selector_opts = function ( opts )\n\t{\n\t\tif ( ! opts ) {\n\t\t\topts = {};\n\t\t}\n\t\n\t\t// Backwards compatibility for 1.9- which used the terminology filter rather\n\t\t// than search\n\t\tif ( opts.filter && opts.search === undefined ) {\n\t\t\topts.search = opts.filter;\n\t\t}\n\t\n\t\treturn $.extend( {\n\t\t\tsearch: 'none',\n\t\t\torder: 'current',\n\t\t\tpage: 'all'\n\t\t}, opts );\n\t};\n\t\n\t\n\tvar _selector_first = function ( inst )\n\t{\n\t\t// Reduce the API instance to the first item found\n\t\tfor ( var i=0, ien=inst.length ; i<ien ; i++ ) {\n\t\t\tif ( inst[i].length > 0 ) {\n\t\t\t\t// Assign the first element to the first item in the instance\n\t\t\t\t// and truncate the instance and context\n\t\t\t\tinst[0] = inst[i];\n\t\t\t\tinst[0].length = 1;\n\t\t\t\tinst.length = 1;\n\t\t\t\tinst.context = [ inst.context[i] ];\n\t\n\t\t\t\treturn inst;\n\t\t\t}\n\t\t}\n\t\n\t\t// Not found - return an empty instance\n\t\tinst.length = 0;\n\t\treturn inst;\n\t};\n\t\n\t\n\tvar _selector_row_indexes = function ( settings, opts )\n\t{\n\t\tvar\n\t\t\ti, ien, tmp, a=[],\n\t\t\tdisplayFiltered = settings.aiDisplay,\n\t\t\tdisplayMaster = settings.aiDisplayMaster;\n\t\n\t\tvar\n\t\t\tsearch = opts.search,  // none, applied, removed\n\t\t\torder  = opts.order,   // applied, current, index (original - compatibility with 1.9)\n\t\t\tpage   = opts.page;    // all, current\n\t\n\t\tif ( _fnDataSource( settings ) == 'ssp' ) {\n\t\t\t// In server-side processing mode, most options are irrelevant since\n\t\t\t// rows not shown don't exist and the index order is the applied order\n\t\t\t// Removed is a special case - for consistency just return an empty\n\t\t\t// array\n\t\t\treturn search === 'removed' ?\n\t\t\t\t[] :\n\t\t\t\t_range( 0, displayMaster.length );\n\t\t}\n\t\telse if ( page == 'current' ) {\n\t\t\t// Current page implies that order=current and fitler=applied, since it is\n\t\t\t// fairly senseless otherwise, regardless of what order and search actually\n\t\t\t// are\n\t\t\tfor ( i=settings._iDisplayStart, ien=settings.fnDisplayEnd() ; i<ien ; i++ ) {\n\t\t\t\ta.push( displayFiltered[i] );\n\t\t\t}\n\t\t}\n\t\telse if ( order == 'current' || order == 'applied' ) {\n\t\t\ta = search == 'none' ?\n\t\t\t\tdisplayMaster.slice() :                      // no search\n\t\t\t\tsearch == 'applied' ?\n\t\t\t\t\tdisplayFiltered.slice() :                // applied search\n\t\t\t\t\t$.map( displayMaster, function (el, i) { // removed search\n\t\t\t\t\t\treturn $.inArray( el, displayFiltered ) === -1 ? el : null;\n\t\t\t\t\t} );\n\t\t}\n\t\telse if ( order == 'index' || order == 'original' ) {\n\t\t\tfor ( i=0, ien=settings.aoData.length ; i<ien ; i++ ) {\n\t\t\t\tif ( search == 'none' ) {\n\t\t\t\t\ta.push( i );\n\t\t\t\t}\n\t\t\t\telse { // applied | removed\n\t\t\t\t\ttmp = $.inArray( i, displayFiltered );\n\t\n\t\t\t\t\tif ((tmp === -1 && search == 'removed') ||\n\t\t\t\t\t\t(tmp >= 0   && search == 'applied') )\n\t\t\t\t\t{\n\t\t\t\t\t\ta.push( i );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\n\t\treturn a;\n\t};\n\t\n\t\n\t/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\n\t * Rows\n\t *\n\t * {}          - no selector - use all available rows\n\t * {integer}   - row aoData index\n\t * {node}      - TR node\n\t * {string}    - jQuery selector to apply to the TR elements\n\t * {array}     - jQuery array of nodes, or simply an array of TR nodes\n\t *\n\t */\n\t\n\t\n\tvar __row_selector = function ( settings, selector, opts )\n\t{\n\t\tvar run = function ( sel ) {\n\t\t\tvar selInt = _intVal( sel );\n\t\t\tvar i, ien;\n\t\n\t\t\t// Short cut - selector is a number and no options provided (default is\n\t\t\t// all records, so no need to check if the index is in there, since it\n\t\t\t// must be - dev error if the index doesn't exist).\n\t\t\tif ( selInt !== null && ! opts ) {\n\t\t\t\treturn [ selInt ];\n\t\t\t}\n\t\n\t\t\tvar rows = _selector_row_indexes( settings, opts );\n\t\n\t\t\tif ( selInt !== null && $.inArray( selInt, rows ) !== -1 ) {\n\t\t\t\t// Selector - integer\n\t\t\t\treturn [ selInt ];\n\t\t\t}\n\t\t\telse if ( ! sel ) {\n\t\t\t\t// Selector - none\n\t\t\t\treturn rows;\n\t\t\t}\n\t\n\t\t\t// Selector - function\n\t\t\tif ( typeof sel === 'function' ) {\n\t\t\t\treturn $.map( rows, function (idx) {\n\t\t\t\t\tvar row = settings.aoData[ idx ];\n\t\t\t\t\treturn sel( idx, row._aData, row.nTr ) ? idx : null;\n\t\t\t\t} );\n\t\t\t}\n\t\n\t\t\t// Get nodes in the order from the `rows` array with null values removed\n\t\t\tvar nodes = _removeEmpty(\n\t\t\t\t_pluck_order( settings.aoData, rows, 'nTr' )\n\t\t\t);\n\t\n\t\t\t// Selector - node\n\t\t\tif ( sel.nodeName ) {\n\t\t\t\tif ( sel._DT_RowIndex !== undefined ) {\n\t\t\t\t\treturn [ sel._DT_RowIndex ]; // Property added by DT for fast lookup\n\t\t\t\t}\n\t\t\t\telse if ( sel._DT_CellIndex ) {\n\t\t\t\t\treturn [ sel._DT_CellIndex.row ];\n\t\t\t\t}\n\t\t\t\telse {\n\t\t\t\t\tvar host = $(sel).closest('*[data-dt-row]');\n\t\t\t\t\treturn host.length ?\n\t\t\t\t\t\t[ host.data('dt-row') ] :\n\t\t\t\t\t\t[];\n\t\t\t\t}\n\t\t\t}\n\t\n\t\t\t// ID selector. Want to always be able to select rows by id, regardless\n\t\t\t// of if the tr element has been created or not, so can't rely upon\n\t\t\t// jQuery here - hence a custom implementation. This does not match\n\t\t\t// Sizzle's fast selector or HTML4 - in HTML5 the ID can be anything,\n\t\t\t// but to select it using a CSS selector engine (like Sizzle or\n\t\t\t// querySelect) it would need to need to be escaped for some characters.\n\t\t\t// DataTables simplifies this for row selectors since you can select\n\t\t\t// only a row. A # indicates an id any anything that follows is the id -\n\t\t\t// unescaped.\n\t\t\tif ( typeof sel === 'string' && sel.charAt(0) === '#' ) {\n\t\t\t\t// get row index from id\n\t\t\t\tvar rowObj = settings.aIds[ sel.replace( /^#/, '' ) ];\n\t\t\t\tif ( rowObj !== undefined ) {\n\t\t\t\t\treturn [ rowObj.idx ];\n\t\t\t\t}\n\t\n\t\t\t\t// need to fall through to jQuery in case there is DOM id that\n\t\t\t\t// matches\n\t\t\t}\n\t\n\t\t\t// Selector - jQuery selector string, array of nodes or jQuery object/\n\t\t\t// As jQuery's .filter() allows jQuery objects to be passed in filter,\n\t\t\t// it also allows arrays, so this will cope with all three options\n\t\t\treturn $(nodes)\n\t\t\t\t.filter( sel )\n\t\t\t\t.map( function () {\n\t\t\t\t\treturn this._DT_RowIndex;\n\t\t\t\t} )\n\t\t\t\t.toArray();\n\t\t};\n\t\n\t\treturn _selector_run( 'row', selector, run, settings, opts );\n\t};\n\t\n\t\n\t_api_register( 'rows()', function ( selector, opts ) {\n\t\t// argument shifting\n\t\tif ( selector === undefined ) {\n\t\t\tselector = '';\n\t\t}\n\t\telse if ( $.isPlainObject( selector ) ) {\n\t\t\topts = selector;\n\t\t\tselector = '';\n\t\t}\n\t\n\t\topts = _selector_opts( opts );\n\t\n\t\tvar inst = this.iterator( 'table', function ( settings ) {\n\t\t\treturn __row_selector( settings, selector, opts );\n\t\t}, 1 );\n\t\n\t\t// Want argument shifting here and in __row_selector?\n\t\tinst.selector.rows = selector;\n\t\tinst.selector.opts = opts;\n\t\n\t\treturn inst;\n\t} );\n\t\n\t_api_register( 'rows().nodes()', function () {\n\t\treturn this.iterator( 'row', function ( settings, row ) {\n\t\t\treturn settings.aoData[ row ].nTr || undefined;\n\t\t}, 1 );\n\t} );\n\t\n\t_api_register( 'rows().data()', function () {\n\t\treturn this.iterator( true, 'rows', function ( settings, rows ) {\n\t\t\treturn _pluck_order( settings.aoData, rows, '_aData' );\n\t\t}, 1 );\n\t} );\n\t\n\t_api_registerPlural( 'rows().cache()', 'row().cache()', function ( type ) {\n\t\treturn this.iterator( 'row', function ( settings, row ) {\n\t\t\tvar r = settings.aoData[ row ];\n\t\t\treturn type === 'search' ? r._aFilterData : r._aSortData;\n\t\t}, 1 );\n\t} );\n\t\n\t_api_registerPlural( 'rows().invalidate()', 'row().invalidate()', function ( src ) {\n\t\treturn this.iterator( 'row', function ( settings, row ) {\n\t\t\t_fnInvalidate( settings, row, src );\n\t\t} );\n\t} );\n\t\n\t_api_registerPlural( 'rows().indexes()', 'row().index()', function () {\n\t\treturn this.iterator( 'row', function ( settings, row ) {\n\t\t\treturn row;\n\t\t}, 1 );\n\t} );\n\t\n\t_api_registerPlural( 'rows().ids()', 'row().id()', function ( hash ) {\n\t\tvar a = [];\n\t\tvar context = this.context;\n\t\n\t\t// `iterator` will drop undefined values, but in this case we want them\n\t\tfor ( var i=0, ien=context.length ; i<ien ; i++ ) {\n\t\t\tfor ( var j=0, jen=this[i].length ; j<jen ; j++ ) {\n\t\t\t\tvar id = context[i].rowIdFn( context[i].aoData[ this[i][j] ]._aData );\n\t\t\t\ta.push( (hash === true ? '#' : '' )+ id );\n\t\t\t}\n\t\t}\n\t\n\t\treturn new _Api( context, a );\n\t} );\n\t\n\t_api_registerPlural( 'rows().remove()', 'row().remove()', function () {\n\t\tvar that = this;\n\t\n\t\tthis.iterator( 'row', function ( settings, row, thatIdx ) {\n\t\t\tvar data = settings.aoData;\n\t\t\tvar rowData = data[ row ];\n\t\t\tvar i, ien, j, jen;\n\t\t\tvar loopRow, loopCells;\n\t\n\t\t\tdata.splice( row, 1 );\n\t\n\t\t\t// Update the cached indexes\n\t\t\tfor ( i=0, ien=data.length ; i<ien ; i++ ) {\n\t\t\t\tloopRow = data[i];\n\t\t\t\tloopCells = loopRow.anCells;\n\t\n\t\t\t\t// Rows\n\t\t\t\tif ( loopRow.nTr !== null ) {\n\t\t\t\t\tloopRow.nTr._DT_RowIndex = i;\n\t\t\t\t}\n\t\n\t\t\t\t// Cells\n\t\t\t\tif ( loopCells !== null ) {\n\t\t\t\t\tfor ( j=0, jen=loopCells.length ; j<jen ; j++ ) {\n\t\t\t\t\t\tloopCells[j]._DT_CellIndex.row = i;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\n\t\t\t// Delete from the display arrays\n\t\t\t_fnDeleteIndex( settings.aiDisplayMaster, row );\n\t\t\t_fnDeleteIndex( settings.aiDisplay, row );\n\t\t\t_fnDeleteIndex( that[ thatIdx ], row, false ); // maintain local indexes\n\t\n\t\t\t// Check for an 'overflow' they case for displaying the table\n\t\t\t_fnLengthOverflow( settings );\n\t\n\t\t\t// Remove the row's ID reference if there is one\n\t\t\tvar id = settings.rowIdFn( rowData._aData );\n\t\t\tif ( id !== undefined ) {\n\t\t\t\tdelete settings.aIds[ id ];\n\t\t\t}\n\t\t} );\n\t\n\t\tthis.iterator( 'table', function ( settings ) {\n\t\t\tfor ( var i=0, ien=settings.aoData.length ; i<ien ; i++ ) {\n\t\t\t\tsettings.aoData[i].idx = i;\n\t\t\t}\n\t\t} );\n\t\n\t\treturn this;\n\t} );\n\t\n\t\n\t_api_register( 'rows.add()', function ( rows ) {\n\t\tvar newRows = this.iterator( 'table', function ( settings ) {\n\t\t\t\tvar row, i, ien;\n\t\t\t\tvar out = [];\n\t\n\t\t\t\tfor ( i=0, ien=rows.length ; i<ien ; i++ ) {\n\t\t\t\t\trow = rows[i];\n\t\n\t\t\t\t\tif ( row.nodeName && row.nodeName.toUpperCase() === 'TR' ) {\n\t\t\t\t\t\tout.push( _fnAddTr( settings, row )[0] );\n\t\t\t\t\t}\n\t\t\t\t\telse {\n\t\t\t\t\t\tout.push( _fnAddData( settings, row ) );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\n\t\t\t\treturn out;\n\t\t\t}, 1 );\n\t\n\t\t// Return an Api.rows() extended instance, so rows().nodes() etc can be used\n\t\tvar modRows = this.rows( -1 );\n\t\tmodRows.pop();\n\t\t$.merge( modRows, newRows );\n\t\n\t\treturn modRows;\n\t} );\n\t\n\t\n\t\n\t\n\t\n\t/**\n\t *\n\t */\n\t_api_register( 'row()', function ( selector, opts ) {\n\t\treturn _selector_first( this.rows( selector, opts ) );\n\t} );\n\t\n\t\n\t_api_register( 'row().data()', function ( data ) {\n\t\tvar ctx = this.context;\n\t\n\t\tif ( data === undefined ) {\n\t\t\t// Get\n\t\t\treturn ctx.length && this.length ?\n\t\t\t\tctx[0].aoData[ this[0] ]._aData :\n\t\t\t\tundefined;\n\t\t}\n\t\n\t\t// Set\n\t\tctx[0].aoData[ this[0] ]._aData = data;\n\t\n\t\t// Automatically invalidate\n\t\t_fnInvalidate( ctx[0], this[0], 'data' );\n\t\n\t\treturn this;\n\t} );\n\t\n\t\n\t_api_register( 'row().node()', function () {\n\t\tvar ctx = this.context;\n\t\n\t\treturn ctx.length && this.length ?\n\t\t\tctx[0].aoData[ this[0] ].nTr || null :\n\t\t\tnull;\n\t} );\n\t\n\t\n\t_api_register( 'row.add()', function ( row ) {\n\t\t// Allow a jQuery object to be passed in - only a single row is added from\n\t\t// it though - the first element in the set\n\t\tif ( row instanceof $ && row.length ) {\n\t\t\trow = row[0];\n\t\t}\n\t\n\t\tvar rows = this.iterator( 'table', function ( settings ) {\n\t\t\tif ( row.nodeName && row.nodeName.toUpperCase() === 'TR' ) {\n\t\t\t\treturn _fnAddTr( settings, row )[0];\n\t\t\t}\n\t\t\treturn _fnAddData( settings, row );\n\t\t} );\n\t\n\t\t// Return an Api.rows() extended instance, with the newly added row selected\n\t\treturn this.row( rows[0] );\n\t} );\n\t\n\t\n\t\n\tvar __details_add = function ( ctx, row, data, klass )\n\t{\n\t\t// Convert to array of TR elements\n\t\tvar rows = [];\n\t\tvar addRow = function ( r, k ) {\n\t\t\t// Recursion to allow for arrays of jQuery objects\n\t\t\tif ( $.isArray( r ) || r instanceof $ ) {\n\t\t\t\tfor ( var i=0, ien=r.length ; i<ien ; i++ ) {\n\t\t\t\t\taddRow( r[i], k );\n\t\t\t\t}\n\t\t\t\treturn;\n\t\t\t}\n\t\n\t\t\t// If we get a TR element, then just add it directly - up to the dev\n\t\t\t// to add the correct number of columns etc\n\t\t\tif ( r.nodeName && r.nodeName.toLowerCase() === 'tr' ) {\n\t\t\t\trows.push( r );\n\t\t\t}\n\t\t\telse {\n\t\t\t\t// Otherwise create a row with a wrapper\n\t\t\t\tvar created = $('<tr><td/></tr>').addClass( k );\n\t\t\t\t$('td', created)\n\t\t\t\t\t.addClass( k )\n\t\t\t\t\t.html( r )\n\t\t\t\t\t[0].colSpan = _fnVisbleColumns( ctx );\n\t\n\t\t\t\trows.push( created[0] );\n\t\t\t}\n\t\t};\n\t\n\t\taddRow( data, klass );\n\t\n\t\tif ( row._details ) {\n\t\t\trow._details.remove();\n\t\t}\n\t\n\t\trow._details = $(rows);\n\t\n\t\t// If the children were already shown, that state should be retained\n\t\tif ( row._detailsShow ) {\n\t\t\trow._details.insertAfter( row.nTr );\n\t\t}\n\t};\n\t\n\t\n\tvar __details_remove = function ( api, idx )\n\t{\n\t\tvar ctx = api.context;\n\t\n\t\tif ( ctx.length ) {\n\t\t\tvar row = ctx[0].aoData[ idx !== undefined ? idx : api[0] ];\n\t\n\t\t\tif ( row && row._details ) {\n\t\t\t\trow._details.remove();\n\t\n\t\t\t\trow._detailsShow = undefined;\n\t\t\t\trow._details = undefined;\n\t\t\t}\n\t\t}\n\t};\n\t\n\t\n\tvar __details_display = function ( api, show ) {\n\t\tvar ctx = api.context;\n\t\n\t\tif ( ctx.length && api.length ) {\n\t\t\tvar row = ctx[0].aoData[ api[0] ];\n\t\n\t\t\tif ( row._details ) {\n\t\t\t\trow._detailsShow = show;\n\t\n\t\t\t\tif ( show ) {\n\t\t\t\t\trow._details.insertAfter( row.nTr );\n\t\t\t\t}\n\t\t\t\telse {\n\t\t\t\t\trow._details.detach();\n\t\t\t\t}\n\t\n\t\t\t\t__details_events( ctx[0] );\n\t\t\t}\n\t\t}\n\t};\n\t\n\t\n\tvar __details_events = function ( settings )\n\t{\n\t\tvar api = new _Api( settings );\n\t\tvar namespace = '.dt.DT_details';\n\t\tvar drawEvent = 'draw'+namespace;\n\t\tvar colvisEvent = 'column-visibility'+namespace;\n\t\tvar destroyEvent = 'destroy'+namespace;\n\t\tvar data = settings.aoData;\n\t\n\t\tapi.off( drawEvent +' '+ colvisEvent +' '+ destroyEvent );\n\t\n\t\tif ( _pluck( data, '_details' ).length > 0 ) {\n\t\t\t// On each draw, insert the required elements into the document\n\t\t\tapi.on( drawEvent, function ( e, ctx ) {\n\t\t\t\tif ( settings !== ctx ) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\n\t\t\t\tapi.rows( {page:'current'} ).eq(0).each( function (idx) {\n\t\t\t\t\t// Internal data grab\n\t\t\t\t\tvar row = data[ idx ];\n\t\n\t\t\t\t\tif ( row._detailsShow ) {\n\t\t\t\t\t\trow._details.insertAfter( row.nTr );\n\t\t\t\t\t}\n\t\t\t\t} );\n\t\t\t} );\n\t\n\t\t\t// Column visibility change - update the colspan\n\t\t\tapi.on( colvisEvent, function ( e, ctx, idx, vis ) {\n\t\t\t\tif ( settings !== ctx ) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\n\t\t\t\t// Update the colspan for the details rows (note, only if it already has\n\t\t\t\t// a colspan)\n\t\t\t\tvar row, visible = _fnVisbleColumns( ctx );\n\t\n\t\t\t\tfor ( var i=0, ien=data.length ; i<ien ; i++ ) {\n\t\t\t\t\trow = data[i];\n\t\n\t\t\t\t\tif ( row._details ) {\n\t\t\t\t\t\trow._details.children('td[colspan]').attr('colspan', visible );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} );\n\t\n\t\t\t// Table destroyed - nuke any child rows\n\t\t\tapi.on( destroyEvent, function ( e, ctx ) {\n\t\t\t\tif ( settings !== ctx ) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\n\t\t\t\tfor ( var i=0, ien=data.length ; i<ien ; i++ ) {\n\t\t\t\t\tif ( data[i]._details ) {\n\t\t\t\t\t\t__details_remove( api, i );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} );\n\t\t}\n\t};\n\t\n\t// Strings for the method names to help minification\n\tvar _emp = '';\n\tvar _child_obj = _emp+'row().child';\n\tvar _child_mth = _child_obj+'()';\n\t\n\t// data can be:\n\t//  tr\n\t//  string\n\t//  jQuery or array of any of the above\n\t_api_register( _child_mth, function ( data, klass ) {\n\t\tvar ctx = this.context;\n\t\n\t\tif ( data === undefined ) {\n\t\t\t// get\n\t\t\treturn ctx.length && this.length ?\n\t\t\t\tctx[0].aoData[ this[0] ]._details :\n\t\t\t\tundefined;\n\t\t}\n\t\telse if ( data === true ) {\n\t\t\t// show\n\t\t\tthis.child.show();\n\t\t}\n\t\telse if ( data === false ) {\n\t\t\t// remove\n\t\t\t__details_remove( this );\n\t\t}\n\t\telse if ( ctx.length && this.length ) {\n\t\t\t// set\n\t\t\t__details_add( ctx[0], ctx[0].aoData[ this[0] ], data, klass );\n\t\t}\n\t\n\t\treturn this;\n\t} );\n\t\n\t\n\t_api_register( [\n\t\t_child_obj+'.show()',\n\t\t_child_mth+'.show()' // only when `child()` was called with parameters (without\n\t], function ( show ) {   // it returns an object and this method is not executed)\n\t\t__details_display( this, true );\n\t\treturn this;\n\t} );\n\t\n\t\n\t_api_register( [\n\t\t_child_obj+'.hide()',\n\t\t_child_mth+'.hide()' // only when `child()` was called with parameters (without\n\t], function () {         // it returns an object and this method is not executed)\n\t\t__details_display( this, false );\n\t\treturn this;\n\t} );\n\t\n\t\n\t_api_register( [\n\t\t_child_obj+'.remove()',\n\t\t_child_mth+'.remove()' // only when `child()` was called with parameters (without\n\t], function () {           // it returns an object and this method is not executed)\n\t\t__details_remove( this );\n\t\treturn this;\n\t} );\n\t\n\t\n\t_api_register( _child_obj+'.isShown()', function () {\n\t\tvar ctx = this.context;\n\t\n\t\tif ( ctx.length && this.length ) {\n\t\t\t// _detailsShown as false or undefined will fall through to return false\n\t\t\treturn ctx[0].aoData[ this[0] ]._detailsShow || false;\n\t\t}\n\t\treturn false;\n\t} );\n\t\n\t\n\t\n\t/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\n\t * Columns\n\t *\n\t * {integer}           - column index (>=0 count from left, <0 count from right)\n\t * \"{integer}:visIdx\"  - visible column index (i.e. translate to column index)  (>=0 count from left, <0 count from right)\n\t * \"{integer}:visible\" - alias for {integer}:visIdx  (>=0 count from left, <0 count from right)\n\t * \"{string}:name\"     - column name\n\t * \"{string}\"          - jQuery selector on column header nodes\n\t *\n\t */\n\t\n\t// can be an array of these items, comma separated list, or an array of comma\n\t// separated lists\n\t\n\tvar __re_column_selector = /^(.+):(name|visIdx|visible)$/;\n\t\n\t\n\t// r1 and r2 are redundant - but it means that the parameters match for the\n\t// iterator callback in columns().data()\n\tvar __columnData = function ( settings, column, r1, r2, rows ) {\n\t\tvar a = [];\n\t\tfor ( var row=0, ien=rows.length ; row<ien ; row++ ) {\n\t\t\ta.push( _fnGetCellData( settings, rows[row], column ) );\n\t\t}\n\t\treturn a;\n\t};\n\t\n\t\n\tvar __column_selector = function ( settings, selector, opts )\n\t{\n\t\tvar\n\t\t\tcolumns = settings.aoColumns,\n\t\t\tnames = _pluck( columns, 'sName' ),\n\t\t\tnodes = _pluck( columns, 'nTh' );\n\t\n\t\tvar run = function ( s ) {\n\t\t\tvar selInt = _intVal( s );\n\t\n\t\t\t// Selector - all\n\t\t\tif ( s === '' ) {\n\t\t\t\treturn _range( columns.length );\n\t\t\t}\n\t\n\t\t\t// Selector - index\n\t\t\tif ( selInt !== null ) {\n\t\t\t\treturn [ selInt >= 0 ?\n\t\t\t\t\tselInt : // Count from left\n\t\t\t\t\tcolumns.length + selInt // Count from right (+ because its a negative value)\n\t\t\t\t];\n\t\t\t}\n\t\n\t\t\t// Selector = function\n\t\t\tif ( typeof s === 'function' ) {\n\t\t\t\tvar rows = _selector_row_indexes( settings, opts );\n\t\n\t\t\t\treturn $.map( columns, function (col, idx) {\n\t\t\t\t\treturn s(\n\t\t\t\t\t\t\tidx,\n\t\t\t\t\t\t\t__columnData( settings, idx, 0, 0, rows ),\n\t\t\t\t\t\t\tnodes[ idx ]\n\t\t\t\t\t\t) ? idx : null;\n\t\t\t\t} );\n\t\t\t}\n\t\n\t\t\t// jQuery or string selector\n\t\t\tvar match = typeof s === 'string' ?\n\t\t\t\ts.match( __re_column_selector ) :\n\t\t\t\t'';\n\t\n\t\t\tif ( match ) {\n\t\t\t\tswitch( match[2] ) {\n\t\t\t\t\tcase 'visIdx':\n\t\t\t\t\tcase 'visible':\n\t\t\t\t\t\tvar idx = parseInt( match[1], 10 );\n\t\t\t\t\t\t// Visible index given, convert to column index\n\t\t\t\t\t\tif ( idx < 0 ) {\n\t\t\t\t\t\t\t// Counting from the right\n\t\t\t\t\t\t\tvar visColumns = $.map( columns, function (col,i) {\n\t\t\t\t\t\t\t\treturn col.bVisible ? i : null;\n\t\t\t\t\t\t\t} );\n\t\t\t\t\t\t\treturn [ visColumns[ visColumns.length + idx ] ];\n\t\t\t\t\t\t}\n\t\t\t\t\t\t// Counting from the left\n\t\t\t\t\t\treturn [ _fnVisibleToColumnIndex( settings, idx ) ];\n\t\n\t\t\t\t\tcase 'name':\n\t\t\t\t\t\t// match by name. `names` is column index complete and in order\n\t\t\t\t\t\treturn $.map( names, function (name, i) {\n\t\t\t\t\t\t\treturn name === match[1] ? i : null;\n\t\t\t\t\t\t} );\n\t\n\t\t\t\t\tdefault:\n\t\t\t\t\t\treturn [];\n\t\t\t\t}\n\t\t\t}\n\t\n\t\t\t// Cell in the table body\n\t\t\tif ( s.nodeName && s._DT_CellIndex ) {\n\t\t\t\treturn [ s._DT_CellIndex.column ];\n\t\t\t}\n\t\n\t\t\t// jQuery selector on the TH elements for the columns\n\t\t\tvar jqResult = $( nodes )\n\t\t\t\t.filter( s )\n\t\t\t\t.map( function () {\n\t\t\t\t\treturn $.inArray( this, nodes ); // `nodes` is column index complete and in order\n\t\t\t\t} )\n\t\t\t\t.toArray();\n\t\n\t\t\tif ( jqResult.length || ! s.nodeName ) {\n\t\t\t\treturn jqResult;\n\t\t\t}\n\t\n\t\t\t// Otherwise a node which might have a `dt-column` data attribute, or be\n\t\t\t// a child or such an element\n\t\t\tvar host = $(s).closest('*[data-dt-column]');\n\t\t\treturn host.length ?\n\t\t\t\t[ host.data('dt-column') ] :\n\t\t\t\t[];\n\t\t};\n\t\n\t\treturn _selector_run( 'column', selector, run, settings, opts );\n\t};\n\t\n\t\n\tvar __setColumnVis = function ( settings, column, vis ) {\n\t\tvar\n\t\t\tcols = settings.aoColumns,\n\t\t\tcol  = cols[ column ],\n\t\t\tdata = settings.aoData,\n\t\t\trow, cells, i, ien, tr;\n\t\n\t\t// Get\n\t\tif ( vis === undefined ) {\n\t\t\treturn col.bVisible;\n\t\t}\n\t\n\t\t// Set\n\t\t// No change\n\t\tif ( col.bVisible === vis ) {\n\t\t\treturn;\n\t\t}\n\t\n\t\tif ( vis ) {\n\t\t\t// Insert column\n\t\t\t// Need to decide if we should use appendChild or insertBefore\n\t\t\tvar insertBefore = $.inArray( true, _pluck(cols, 'bVisible'), column+1 );\n\t\n\t\t\tfor ( i=0, ien=data.length ; i<ien ; i++ ) {\n\t\t\t\ttr = data[i].nTr;\n\t\t\t\tcells = data[i].anCells;\n\t\n\t\t\t\tif ( tr ) {\n\t\t\t\t\t// insertBefore can act like appendChild if 2nd arg is null\n\t\t\t\t\ttr.insertBefore( cells[ column ], cells[ insertBefore ] || null );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\telse {\n\t\t\t// Remove column\n\t\t\t$( _pluck( settings.aoData, 'anCells', column ) ).detach();\n\t\t}\n\t\n\t\t// Common actions\n\t\tcol.bVisible = vis;\n\t\t_fnDrawHead( settings, settings.aoHeader );\n\t\t_fnDrawHead( settings, settings.aoFooter );\n\t\n\t\t_fnSaveState( settings );\n\t};\n\t\n\t\n\t_api_register( 'columns()', function ( selector, opts ) {\n\t\t// argument shifting\n\t\tif ( selector === undefined ) {\n\t\t\tselector = '';\n\t\t}\n\t\telse if ( $.isPlainObject( selector ) ) {\n\t\t\topts = selector;\n\t\t\tselector = '';\n\t\t}\n\t\n\t\topts = _selector_opts( opts );\n\t\n\t\tvar inst = this.iterator( 'table', function ( settings ) {\n\t\t\treturn __column_selector( settings, selector, opts );\n\t\t}, 1 );\n\t\n\t\t// Want argument shifting here and in _row_selector?\n\t\tinst.selector.cols = selector;\n\t\tinst.selector.opts = opts;\n\t\n\t\treturn inst;\n\t} );\n\t\n\t_api_registerPlural( 'columns().header()', 'column().header()', function ( selector, opts ) {\n\t\treturn this.iterator( 'column', function ( settings, column ) {\n\t\t\treturn settings.aoColumns[column].nTh;\n\t\t}, 1 );\n\t} );\n\t\n\t_api_registerPlural( 'columns().footer()', 'column().footer()', function ( selector, opts ) {\n\t\treturn this.iterator( 'column', function ( settings, column ) {\n\t\t\treturn settings.aoColumns[column].nTf;\n\t\t}, 1 );\n\t} );\n\t\n\t_api_registerPlural( 'columns().data()', 'column().data()', function () {\n\t\treturn this.iterator( 'column-rows', __columnData, 1 );\n\t} );\n\t\n\t_api_registerPlural( 'columns().dataSrc()', 'column().dataSrc()', function () {\n\t\treturn this.iterator( 'column', function ( settings, column ) {\n\t\t\treturn settings.aoColumns[column].mData;\n\t\t}, 1 );\n\t} );\n\t\n\t_api_registerPlural( 'columns().cache()', 'column().cache()', function ( type ) {\n\t\treturn this.iterator( 'column-rows', function ( settings, column, i, j, rows ) {\n\t\t\treturn _pluck_order( settings.aoData, rows,\n\t\t\t\ttype === 'search' ? '_aFilterData' : '_aSortData', column\n\t\t\t);\n\t\t}, 1 );\n\t} );\n\t\n\t_api_registerPlural( 'columns().nodes()', 'column().nodes()', function () {\n\t\treturn this.iterator( 'column-rows', function ( settings, column, i, j, rows ) {\n\t\t\treturn _pluck_order( settings.aoData, rows, 'anCells', column ) ;\n\t\t}, 1 );\n\t} );\n\t\n\t_api_registerPlural( 'columns().visible()', 'column().visible()', function ( vis, calc ) {\n\t\tvar ret = this.iterator( 'column', function ( settings, column ) {\n\t\t\tif ( vis === undefined ) {\n\t\t\t\treturn settings.aoColumns[ column ].bVisible;\n\t\t\t} // else\n\t\t\t__setColumnVis( settings, column, vis );\n\t\t} );\n\t\n\t\t// Group the column visibility changes\n\t\tif ( vis !== undefined ) {\n\t\t\t// Second loop once the first is done for events\n\t\t\tthis.iterator( 'column', function ( settings, column ) {\n\t\t\t\t_fnCallbackFire( settings, null, 'column-visibility', [settings, column, vis, calc] );\n\t\t\t} );\n\t\n\t\t\tif ( calc === undefined || calc ) {\n\t\t\t\tthis.columns.adjust();\n\t\t\t}\n\t\t}\n\t\n\t\treturn ret;\n\t} );\n\t\n\t_api_registerPlural( 'columns().indexes()', 'column().index()', function ( type ) {\n\t\treturn this.iterator( 'column', function ( settings, column ) {\n\t\t\treturn type === 'visible' ?\n\t\t\t\t_fnColumnIndexToVisible( settings, column ) :\n\t\t\t\tcolumn;\n\t\t}, 1 );\n\t} );\n\t\n\t_api_register( 'columns.adjust()', function () {\n\t\treturn this.iterator( 'table', function ( settings ) {\n\t\t\t_fnAdjustColumnSizing( settings );\n\t\t}, 1 );\n\t} );\n\t\n\t_api_register( 'column.index()', function ( type, idx ) {\n\t\tif ( this.context.length !== 0 ) {\n\t\t\tvar ctx = this.context[0];\n\t\n\t\t\tif ( type === 'fromVisible' || type === 'toData' ) {\n\t\t\t\treturn _fnVisibleToColumnIndex( ctx, idx );\n\t\t\t}\n\t\t\telse if ( type === 'fromData' || type === 'toVisible' ) {\n\t\t\t\treturn _fnColumnIndexToVisible( ctx, idx );\n\t\t\t}\n\t\t}\n\t} );\n\t\n\t_api_register( 'column()', function ( selector, opts ) {\n\t\treturn _selector_first( this.columns( selector, opts ) );\n\t} );\n\t\n\t\n\t\n\tvar __cell_selector = function ( settings, selector, opts )\n\t{\n\t\tvar data = settings.aoData;\n\t\tvar rows = _selector_row_indexes( settings, opts );\n\t\tvar cells = _removeEmpty( _pluck_order( data, rows, 'anCells' ) );\n\t\tvar allCells = $( [].concat.apply([], cells) );\n\t\tvar row;\n\t\tvar columns = settings.aoColumns.length;\n\t\tvar a, i, ien, j, o, host;\n\t\n\t\tvar run = function ( s ) {\n\t\t\tvar fnSelector = typeof s === 'function';\n\t\n\t\t\tif ( s === null || s === undefined || fnSelector ) {\n\t\t\t\t// All cells and function selectors\n\t\t\t\ta = [];\n\t\n\t\t\t\tfor ( i=0, ien=rows.length ; i<ien ; i++ ) {\n\t\t\t\t\trow = rows[i];\n\t\n\t\t\t\t\tfor ( j=0 ; j<columns ; j++ ) {\n\t\t\t\t\t\to = {\n\t\t\t\t\t\t\trow: row,\n\t\t\t\t\t\t\tcolumn: j\n\t\t\t\t\t\t};\n\t\n\t\t\t\t\t\tif ( fnSelector ) {\n\t\t\t\t\t\t\t// Selector - function\n\t\t\t\t\t\t\thost = data[ row ];\n\t\n\t\t\t\t\t\t\tif ( s( o, _fnGetCellData(settings, row, j), host.anCells ? host.anCells[j] : null ) ) {\n\t\t\t\t\t\t\t\ta.push( o );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse {\n\t\t\t\t\t\t\t// Selector - all\n\t\t\t\t\t\t\ta.push( o );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\n\t\t\t\treturn a;\n\t\t\t}\n\t\t\t\n\t\t\t// Selector - index\n\t\t\tif ( $.isPlainObject( s ) ) {\n\t\t\t\treturn [s];\n\t\t\t}\n\t\n\t\t\t// Selector - jQuery filtered cells\n\t\t\tvar jqResult = allCells\n\t\t\t\t.filter( s )\n\t\t\t\t.map( function (i, el) {\n\t\t\t\t\treturn { // use a new object, in case someone changes the values\n\t\t\t\t\t\trow:    el._DT_CellIndex.row,\n\t\t\t\t\t\tcolumn: el._DT_CellIndex.column\n\t \t\t\t\t};\n\t\t\t\t} )\n\t\t\t\t.toArray();\n\t\n\t\t\tif ( jqResult.length || ! s.nodeName ) {\n\t\t\t\treturn jqResult;\n\t\t\t}\n\t\n\t\t\t// Otherwise the selector is a node, and there is one last option - the\n\t\t\t// element might be a child of an element which has dt-row and dt-column\n\t\t\t// data attributes\n\t\t\thost = $(s).closest('*[data-dt-row]');\n\t\t\treturn host.length ?\n\t\t\t\t[ {\n\t\t\t\t\trow: host.data('dt-row'),\n\t\t\t\t\tcolumn: host.data('dt-column')\n\t\t\t\t} ] :\n\t\t\t\t[];\n\t\t};\n\t\n\t\treturn _selector_run( 'cell', selector, run, settings, opts );\n\t};\n\t\n\t\n\t\n\t\n\t_api_register( 'cells()', function ( rowSelector, columnSelector, opts ) {\n\t\t// Argument shifting\n\t\tif ( $.isPlainObject( rowSelector ) ) {\n\t\t\t// Indexes\n\t\t\tif ( rowSelector.row === undefined ) {\n\t\t\t\t// Selector options in first parameter\n\t\t\t\topts = rowSelector;\n\t\t\t\trowSelector = null;\n\t\t\t}\n\t\t\telse {\n\t\t\t\t// Cell index objects in first parameter\n\t\t\t\topts = columnSelector;\n\t\t\t\tcolumnSelector = null;\n\t\t\t}\n\t\t}\n\t\tif ( $.isPlainObject( columnSelector ) ) {\n\t\t\topts = columnSelector;\n\t\t\tcolumnSelector = null;\n\t\t}\n\t\n\t\t// Cell selector\n\t\tif ( columnSelector === null || columnSelector === undefined ) {\n\t\t\treturn this.iterator( 'table', function ( settings ) {\n\t\t\t\treturn __cell_selector( settings, rowSelector, _selector_opts( opts ) );\n\t\t\t} );\n\t\t}\n\t\n\t\t// Row + column selector\n\t\tvar columns = this.columns( columnSelector, opts );\n\t\tvar rows = this.rows( rowSelector, opts );\n\t\tvar a, i, ien, j, jen;\n\t\n\t\tvar cells = this.iterator( 'table', function ( settings, idx ) {\n\t\t\ta = [];\n\t\n\t\t\tfor ( i=0, ien=rows[idx].length ; i<ien ; i++ ) {\n\t\t\t\tfor ( j=0, jen=columns[idx].length ; j<jen ; j++ ) {\n\t\t\t\t\ta.push( {\n\t\t\t\t\t\trow:    rows[idx][i],\n\t\t\t\t\t\tcolumn: columns[idx][j]\n\t\t\t\t\t} );\n\t\t\t\t}\n\t\t\t}\n\t\n\t\t\treturn a;\n\t\t}, 1 );\n\t\n\t\t$.extend( cells.selector, {\n\t\t\tcols: columnSelector,\n\t\t\trows: rowSelector,\n\t\t\topts: opts\n\t\t} );\n\t\n\t\treturn cells;\n\t} );\n\t\n\t\n\t_api_registerPlural( 'cells().nodes()', 'cell().node()', function () {\n\t\treturn this.iterator( 'cell', function ( settings, row, column ) {\n\t\t\tvar data = settings.aoData[ row ];\n\t\n\t\t\treturn data && data.anCells ?\n\t\t\t\tdata.anCells[ column ] :\n\t\t\t\tundefined;\n\t\t}, 1 );\n\t} );\n\t\n\t\n\t_api_register( 'cells().data()', function () {\n\t\treturn this.iterator( 'cell', function ( settings, row, column ) {\n\t\t\treturn _fnGetCellData( settings, row, column );\n\t\t}, 1 );\n\t} );\n\t\n\t\n\t_api_registerPlural( 'cells().cache()', 'cell().cache()', function ( type ) {\n\t\ttype = type === 'search' ? '_aFilterData' : '_aSortData';\n\t\n\t\treturn this.iterator( 'cell', function ( settings, row, column ) {\n\t\t\treturn settings.aoData[ row ][ type ][ column ];\n\t\t}, 1 );\n\t} );\n\t\n\t\n\t_api_registerPlural( 'cells().render()', 'cell().render()', function ( type ) {\n\t\treturn this.iterator( 'cell', function ( settings, row, column ) {\n\t\t\treturn _fnGetCellData( settings, row, column, type );\n\t\t}, 1 );\n\t} );\n\t\n\t\n\t_api_registerPlural( 'cells().indexes()', 'cell().index()', function () {\n\t\treturn this.iterator( 'cell', function ( settings, row, column ) {\n\t\t\treturn {\n\t\t\t\trow: row,\n\t\t\t\tcolumn: column,\n\t\t\t\tcolumnVisible: _fnColumnIndexToVisible( settings, column )\n\t\t\t};\n\t\t}, 1 );\n\t} );\n\t\n\t\n\t_api_registerPlural( 'cells().invalidate()', 'cell().invalidate()', function ( src ) {\n\t\treturn this.iterator( 'cell', function ( settings, row, column ) {\n\t\t\t_fnInvalidate( settings, row, src, column );\n\t\t} );\n\t} );\n\t\n\t\n\t\n\t_api_register( 'cell()', function ( rowSelector, columnSelector, opts ) {\n\t\treturn _selector_first( this.cells( rowSelector, columnSelector, opts ) );\n\t} );\n\t\n\t\n\t_api_register( 'cell().data()', function ( data ) {\n\t\tvar ctx = this.context;\n\t\tvar cell = this[0];\n\t\n\t\tif ( data === undefined ) {\n\t\t\t// Get\n\t\t\treturn ctx.length && cell.length ?\n\t\t\t\t_fnGetCellData( ctx[0], cell[0].row, cell[0].column ) :\n\t\t\t\tundefined;\n\t\t}\n\t\n\t\t// Set\n\t\t_fnSetCellData( ctx[0], cell[0].row, cell[0].column, data );\n\t\t_fnInvalidate( ctx[0], cell[0].row, 'data', cell[0].column );\n\t\n\t\treturn this;\n\t} );\n\t\n\t\n\t\n\t/**\n\t * Get current ordering (sorting) that has been applied to the table.\n\t *\n\t * @returns {array} 2D array containing the sorting information for the first\n\t *   table in the current context. Each element in the parent array represents\n\t *   a column being sorted upon (i.e. multi-sorting with two columns would have\n\t *   2 inner arrays). The inner arrays may have 2 or 3 elements. The first is\n\t *   the column index that the sorting condition applies to, the second is the\n\t *   direction of the sort (`desc` or `asc`) and, optionally, the third is the\n\t *   index of the sorting order from the `column.sorting` initialisation array.\n\t *//**\n\t * Set the ordering for the table.\n\t *\n\t * @param {integer} order Column index to sort upon.\n\t * @param {string} direction Direction of the sort to be applied (`asc` or `desc`)\n\t * @returns {DataTables.Api} this\n\t *//**\n\t * Set the ordering for the table.\n\t *\n\t * @param {array} order 1D array of sorting information to be applied.\n\t * @param {array} [...] Optional additional sorting conditions\n\t * @returns {DataTables.Api} this\n\t *//**\n\t * Set the ordering for the table.\n\t *\n\t * @param {array} order 2D array of sorting information to be applied.\n\t * @returns {DataTables.Api} this\n\t */\n\t_api_register( 'order()', function ( order, dir ) {\n\t\tvar ctx = this.context;\n\t\n\t\tif ( order === undefined ) {\n\t\t\t// get\n\t\t\treturn ctx.length !== 0 ?\n\t\t\t\tctx[0].aaSorting :\n\t\t\t\tundefined;\n\t\t}\n\t\n\t\t// set\n\t\tif ( typeof order === 'number' ) {\n\t\t\t// Simple column / direction passed in\n\t\t\torder = [ [ order, dir ] ];\n\t\t}\n\t\telse if ( order.length && ! $.isArray( order[0] ) ) {\n\t\t\t// Arguments passed in (list of 1D arrays)\n\t\t\torder = Array.prototype.slice.call( arguments );\n\t\t}\n\t\t// otherwise a 2D array was passed in\n\t\n\t\treturn this.iterator( 'table', function ( settings ) {\n\t\t\tsettings.aaSorting = order.slice();\n\t\t} );\n\t} );\n\t\n\t\n\t/**\n\t * Attach a sort listener to an element for a given column\n\t *\n\t * @param {node|jQuery|string} node Identifier for the element(s) to attach the\n\t *   listener to. This can take the form of a single DOM node, a jQuery\n\t *   collection of nodes or a jQuery selector which will identify the node(s).\n\t * @param {integer} column the column that a click on this node will sort on\n\t * @param {function} [callback] callback function when sort is run\n\t * @returns {DataTables.Api} this\n\t */\n\t_api_register( 'order.listener()', function ( node, column, callback ) {\n\t\treturn this.iterator( 'table', function ( settings ) {\n\t\t\t_fnSortAttachListener( settings, node, column, callback );\n\t\t} );\n\t} );\n\t\n\t\n\t_api_register( 'order.fixed()', function ( set ) {\n\t\tif ( ! set ) {\n\t\t\tvar ctx = this.context;\n\t\t\tvar fixed = ctx.length ?\n\t\t\t\tctx[0].aaSortingFixed :\n\t\t\t\tundefined;\n\t\n\t\t\treturn $.isArray( fixed ) ?\n\t\t\t\t{ pre: fixed } :\n\t\t\t\tfixed;\n\t\t}\n\t\n\t\treturn this.iterator( 'table', function ( settings ) {\n\t\t\tsettings.aaSortingFixed = $.extend( true, {}, set );\n\t\t} );\n\t} );\n\t\n\t\n\t// Order by the selected column(s)\n\t_api_register( [\n\t\t'columns().order()',\n\t\t'column().order()'\n\t], function ( dir ) {\n\t\tvar that = this;\n\t\n\t\treturn this.iterator( 'table', function ( settings, i ) {\n\t\t\tvar sort = [];\n\t\n\t\t\t$.each( that[i], function (j, col) {\n\t\t\t\tsort.push( [ col, dir ] );\n\t\t\t} );\n\t\n\t\t\tsettings.aaSorting = sort;\n\t\t} );\n\t} );\n\t\n\t\n\t\n\t_api_register( 'search()', function ( input, regex, smart, caseInsen ) {\n\t\tvar ctx = this.context;\n\t\n\t\tif ( input === undefined ) {\n\t\t\t// get\n\t\t\treturn ctx.length !== 0 ?\n\t\t\t\tctx[0].oPreviousSearch.sSearch :\n\t\t\t\tundefined;\n\t\t}\n\t\n\t\t// set\n\t\treturn this.iterator( 'table', function ( settings ) {\n\t\t\tif ( ! settings.oFeatures.bFilter ) {\n\t\t\t\treturn;\n\t\t\t}\n\t\n\t\t\t_fnFilterComplete( settings, $.extend( {}, settings.oPreviousSearch, {\n\t\t\t\t\"sSearch\": input+\"\",\n\t\t\t\t\"bRegex\":  regex === null ? false : regex,\n\t\t\t\t\"bSmart\":  smart === null ? true  : smart,\n\t\t\t\t\"bCaseInsensitive\": caseInsen === null ? true : caseInsen\n\t\t\t} ), 1 );\n\t\t} );\n\t} );\n\t\n\t\n\t_api_registerPlural(\n\t\t'columns().search()',\n\t\t'column().search()',\n\t\tfunction ( input, regex, smart, caseInsen ) {\n\t\t\treturn this.iterator( 'column', function ( settings, column ) {\n\t\t\t\tvar preSearch = settings.aoPreSearchCols;\n\t\n\t\t\t\tif ( input === undefined ) {\n\t\t\t\t\t// get\n\t\t\t\t\treturn preSearch[ column ].sSearch;\n\t\t\t\t}\n\t\n\t\t\t\t// set\n\t\t\t\tif ( ! settings.oFeatures.bFilter ) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\n\t\t\t\t$.extend( preSearch[ column ], {\n\t\t\t\t\t\"sSearch\": input+\"\",\n\t\t\t\t\t\"bRegex\":  regex === null ? false : regex,\n\t\t\t\t\t\"bSmart\":  smart === null ? true  : smart,\n\t\t\t\t\t\"bCaseInsensitive\": caseInsen === null ? true : caseInsen\n\t\t\t\t} );\n\t\n\t\t\t\t_fnFilterComplete( settings, settings.oPreviousSearch, 1 );\n\t\t\t} );\n\t\t}\n\t);\n\t\n\t/*\n\t * State API methods\n\t */\n\t\n\t_api_register( 'state()', function () {\n\t\treturn this.context.length ?\n\t\t\tthis.context[0].oSavedState :\n\t\t\tnull;\n\t} );\n\t\n\t\n\t_api_register( 'state.clear()', function () {\n\t\treturn this.iterator( 'table', function ( settings ) {\n\t\t\t// Save an empty object\n\t\t\tsettings.fnStateSaveCallback.call( settings.oInstance, settings, {} );\n\t\t} );\n\t} );\n\t\n\t\n\t_api_register( 'state.loaded()', function () {\n\t\treturn this.context.length ?\n\t\t\tthis.context[0].oLoadedState :\n\t\t\tnull;\n\t} );\n\t\n\t\n\t_api_register( 'state.save()', function () {\n\t\treturn this.iterator( 'table', function ( settings ) {\n\t\t\t_fnSaveState( settings );\n\t\t} );\n\t} );\n\t\n\t\n\t\n\t/**\n\t * Provide a common method for plug-ins to check the version of DataTables being\n\t * used, in order to ensure compatibility.\n\t *\n\t *  @param {string} version Version string to check for, in the format \"X.Y.Z\".\n\t *    Note that the formats \"X\" and \"X.Y\" are also acceptable.\n\t *  @returns {boolean} true if this version of DataTables is greater or equal to\n\t *    the required version, or false if this version of DataTales is not\n\t *    suitable\n\t *  @static\n\t *  @dtopt API-Static\n\t *\n\t *  @example\n\t *    alert( $.fn.dataTable.versionCheck( '1.9.0' ) );\n\t */\n\tDataTable.versionCheck = DataTable.fnVersionCheck = function( version )\n\t{\n\t\tvar aThis = DataTable.version.split('.');\n\t\tvar aThat = version.split('.');\n\t\tvar iThis, iThat;\n\t\n\t\tfor ( var i=0, iLen=aThat.length ; i<iLen ; i++ ) {\n\t\t\tiThis = parseInt( aThis[i], 10 ) || 0;\n\t\t\tiThat = parseInt( aThat[i], 10 ) || 0;\n\t\n\t\t\t// Parts are the same, keep comparing\n\t\t\tif (iThis === iThat) {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\n\t\t\t// Parts are different, return immediately\n\t\t\treturn iThis > iThat;\n\t\t}\n\t\n\t\treturn true;\n\t};\n\t\n\t\n\t/**\n\t * Check if a `<table>` node is a DataTable table already or not.\n\t *\n\t *  @param {node|jquery|string} table Table node, jQuery object or jQuery\n\t *      selector for the table to test. Note that if more than more than one\n\t *      table is passed on, only the first will be checked\n\t *  @returns {boolean} true the table given is a DataTable, or false otherwise\n\t *  @static\n\t *  @dtopt API-Static\n\t *\n\t *  @example\n\t *    if ( ! $.fn.DataTable.isDataTable( '#example' ) ) {\n\t *      $('#example').dataTable();\n\t *    }\n\t */\n\tDataTable.isDataTable = DataTable.fnIsDataTable = function ( table )\n\t{\n\t\tvar t = $(table).get(0);\n\t\tvar is = false;\n\t\n\t\t$.each( DataTable.settings, function (i, o) {\n\t\t\tvar head = o.nScrollHead ? $('table', o.nScrollHead)[0] : null;\n\t\t\tvar foot = o.nScrollFoot ? $('table', o.nScrollFoot)[0] : null;\n\t\n\t\t\tif ( o.nTable === t || head === t || foot === t ) {\n\t\t\t\tis = true;\n\t\t\t}\n\t\t} );\n\t\n\t\treturn is;\n\t};\n\t\n\t\n\t/**\n\t * Get all DataTable tables that have been initialised - optionally you can\n\t * select to get only currently visible tables.\n\t *\n\t *  @param {boolean} [visible=false] Flag to indicate if you want all (default)\n\t *    or visible tables only.\n\t *  @returns {array} Array of `table` nodes (not DataTable instances) which are\n\t *    DataTables\n\t *  @static\n\t *  @dtopt API-Static\n\t *\n\t *  @example\n\t *    $.each( $.fn.dataTable.tables(true), function () {\n\t *      $(table).DataTable().columns.adjust();\n\t *    } );\n\t */\n\tDataTable.tables = DataTable.fnTables = function ( visible )\n\t{\n\t\tvar api = false;\n\t\n\t\tif ( $.isPlainObject( visible ) ) {\n\t\t\tapi = visible.api;\n\t\t\tvisible = visible.visible;\n\t\t}\n\t\n\t\tvar a = $.map( DataTable.settings, function (o) {\n\t\t\tif ( !visible || (visible && $(o.nTable).is(':visible')) ) {\n\t\t\t\treturn o.nTable;\n\t\t\t}\n\t\t} );\n\t\n\t\treturn api ?\n\t\t\tnew _Api( a ) :\n\t\t\ta;\n\t};\n\t\n\t\n\t/**\n\t * Convert from camel case parameters to Hungarian notation. This is made public\n\t * for the extensions to provide the same ability as DataTables core to accept\n\t * either the 1.9 style Hungarian notation, or the 1.10+ style camelCase\n\t * parameters.\n\t *\n\t *  @param {object} src The model object which holds all parameters that can be\n\t *    mapped.\n\t *  @param {object} user The object to convert from camel case to Hungarian.\n\t *  @param {boolean} force When set to `true`, properties which already have a\n\t *    Hungarian value in the `user` object will be overwritten. Otherwise they\n\t *    won't be.\n\t */\n\tDataTable.camelToHungarian = _fnCamelToHungarian;\n\t\n\t\n\t\n\t/**\n\t *\n\t */\n\t_api_register( '$()', function ( selector, opts ) {\n\t\tvar\n\t\t\trows   = this.rows( opts ).nodes(), // Get all rows\n\t\t\tjqRows = $(rows);\n\t\n\t\treturn $( [].concat(\n\t\t\tjqRows.filter( selector ).toArray(),\n\t\t\tjqRows.find( selector ).toArray()\n\t\t) );\n\t} );\n\t\n\t\n\t// jQuery functions to operate on the tables\n\t$.each( [ 'on', 'one', 'off' ], function (i, key) {\n\t\t_api_register( key+'()', function ( /* event, handler */ ) {\n\t\t\tvar args = Array.prototype.slice.call(arguments);\n\t\n\t\t\t// Add the `dt` namespace automatically if it isn't already present\n\t\t\tif ( ! args[0].match(/\\.dt\\b/) ) {\n\t\t\t\targs[0] += '.dt';\n\t\t\t}\n\t\n\t\t\tvar inst = $( this.tables().nodes() );\n\t\t\tinst[key].apply( inst, args );\n\t\t\treturn this;\n\t\t} );\n\t} );\n\t\n\t\n\t_api_register( 'clear()', function () {\n\t\treturn this.iterator( 'table', function ( settings ) {\n\t\t\t_fnClearTable( settings );\n\t\t} );\n\t} );\n\t\n\t\n\t_api_register( 'settings()', function () {\n\t\treturn new _Api( this.context, this.context );\n\t} );\n\t\n\t\n\t_api_register( 'init()', function () {\n\t\tvar ctx = this.context;\n\t\treturn ctx.length ? ctx[0].oInit : null;\n\t} );\n\t\n\t\n\t_api_register( 'data()', function () {\n\t\treturn this.iterator( 'table', function ( settings ) {\n\t\t\treturn _pluck( settings.aoData, '_aData' );\n\t\t} ).flatten();\n\t} );\n\t\n\t\n\t_api_register( 'destroy()', function ( remove ) {\n\t\tremove = remove || false;\n\t\n\t\treturn this.iterator( 'table', function ( settings ) {\n\t\t\tvar orig      = settings.nTableWrapper.parentNode;\n\t\t\tvar classes   = settings.oClasses;\n\t\t\tvar table     = settings.nTable;\n\t\t\tvar tbody     = settings.nTBody;\n\t\t\tvar thead     = settings.nTHead;\n\t\t\tvar tfoot     = settings.nTFoot;\n\t\t\tvar jqTable   = $(table);\n\t\t\tvar jqTbody   = $(tbody);\n\t\t\tvar jqWrapper = $(settings.nTableWrapper);\n\t\t\tvar rows      = $.map( settings.aoData, function (r) { return r.nTr; } );\n\t\t\tvar i, ien;\n\t\n\t\t\t// Flag to note that the table is currently being destroyed - no action\n\t\t\t// should be taken\n\t\t\tsettings.bDestroying = true;\n\t\n\t\t\t// Fire off the destroy callbacks for plug-ins etc\n\t\t\t_fnCallbackFire( settings, \"aoDestroyCallback\", \"destroy\", [settings] );\n\t\n\t\t\t// If not being removed from the document, make all columns visible\n\t\t\tif ( ! remove ) {\n\t\t\t\tnew _Api( settings ).columns().visible( true );\n\t\t\t}\n\t\n\t\t\t// Blitz all `DT` namespaced events (these are internal events, the\n\t\t\t// lowercase, `dt` events are user subscribed and they are responsible\n\t\t\t// for removing them\n\t\t\tjqWrapper.unbind('.DT').find(':not(tbody *)').unbind('.DT');\n\t\t\t$(window).unbind('.DT-'+settings.sInstance);\n\t\n\t\t\t// When scrolling we had to break the table up - restore it\n\t\t\tif ( table != thead.parentNode ) {\n\t\t\t\tjqTable.children('thead').detach();\n\t\t\t\tjqTable.append( thead );\n\t\t\t}\n\t\n\t\t\tif ( tfoot && table != tfoot.parentNode ) {\n\t\t\t\tjqTable.children('tfoot').detach();\n\t\t\t\tjqTable.append( tfoot );\n\t\t\t}\n\t\n\t\t\tsettings.aaSorting = [];\n\t\t\tsettings.aaSortingFixed = [];\n\t\t\t_fnSortingClasses( settings );\n\t\n\t\t\t$( rows ).removeClass( settings.asStripeClasses.join(' ') );\n\t\n\t\t\t$('th, td', thead).removeClass( classes.sSortable+' '+\n\t\t\t\tclasses.sSortableAsc+' '+classes.sSortableDesc+' '+classes.sSortableNone\n\t\t\t);\n\t\n\t\t\tif ( settings.bJUI ) {\n\t\t\t\t$('th span.'+classes.sSortIcon+ ', td span.'+classes.sSortIcon, thead).detach();\n\t\t\t\t$('th, td', thead).each( function () {\n\t\t\t\t\tvar wrapper = $('div.'+classes.sSortJUIWrapper, this);\n\t\t\t\t\t$(this).append( wrapper.contents() );\n\t\t\t\t\twrapper.detach();\n\t\t\t\t} );\n\t\t\t}\n\t\n\t\t\t// Add the TR elements back into the table in their original order\n\t\t\tjqTbody.children().detach();\n\t\t\tjqTbody.append( rows );\n\t\n\t\t\t// Remove the DataTables generated nodes, events and classes\n\t\t\tvar removedMethod = remove ? 'remove' : 'detach';\n\t\t\tjqTable[ removedMethod ]();\n\t\t\tjqWrapper[ removedMethod ]();\n\t\n\t\t\t// If we need to reattach the table to the document\n\t\t\tif ( ! remove && orig ) {\n\t\t\t\t// insertBefore acts like appendChild if !arg[1]\n\t\t\t\torig.insertBefore( table, settings.nTableReinsertBefore );\n\t\n\t\t\t\t// Restore the width of the original table - was read from the style property,\n\t\t\t\t// so we can restore directly to that\n\t\t\t\tjqTable\n\t\t\t\t\t.css( 'width', settings.sDestroyWidth )\n\t\t\t\t\t.removeClass( classes.sTable );\n\t\n\t\t\t\t// If the were originally stripe classes - then we add them back here.\n\t\t\t\t// Note this is not fool proof (for example if not all rows had stripe\n\t\t\t\t// classes - but it's a good effort without getting carried away\n\t\t\t\tien = settings.asDestroyStripes.length;\n\t\n\t\t\t\tif ( ien ) {\n\t\t\t\t\tjqTbody.children().each( function (i) {\n\t\t\t\t\t\t$(this).addClass( settings.asDestroyStripes[i % ien] );\n\t\t\t\t\t} );\n\t\t\t\t}\n\t\t\t}\n\t\n\t\t\t/* Remove the settings object from the settings array */\n\t\t\tvar idx = $.inArray( settings, DataTable.settings );\n\t\t\tif ( idx !== -1 ) {\n\t\t\t\tDataTable.settings.splice( idx, 1 );\n\t\t\t}\n\t\t} );\n\t} );\n\t\n\t\n\t// Add the `every()` method for rows, columns and cells in a compact form\n\t$.each( [ 'column', 'row', 'cell' ], function ( i, type ) {\n\t\t_api_register( type+'s().every()', function ( fn ) {\n\t\t\tvar opts = this.selector.opts;\n\t\t\tvar api = this;\n\t\n\t\t\treturn this.iterator( type, function ( settings, arg1, arg2, arg3, arg4 ) {\n\t\t\t\t// Rows and columns:\n\t\t\t\t//  arg1 - index\n\t\t\t\t//  arg2 - table counter\n\t\t\t\t//  arg3 - loop counter\n\t\t\t\t//  arg4 - undefined\n\t\t\t\t// Cells:\n\t\t\t\t//  arg1 - row index\n\t\t\t\t//  arg2 - column index\n\t\t\t\t//  arg3 - table counter\n\t\t\t\t//  arg4 - loop counter\n\t\t\t\tfn.call(\n\t\t\t\t\tapi[ type ](\n\t\t\t\t\t\targ1,\n\t\t\t\t\t\ttype==='cell' ? arg2 : opts,\n\t\t\t\t\t\ttype==='cell' ? opts : undefined\n\t\t\t\t\t),\n\t\t\t\t\targ1, arg2, arg3, arg4\n\t\t\t\t);\n\t\t\t} );\n\t\t} );\n\t} );\n\t\n\t\n\t// i18n method for extensions to be able to use the language object from the\n\t// DataTable\n\t_api_register( 'i18n()', function ( token, def, plural ) {\n\t\tvar ctx = this.context[0];\n\t\tvar resolved = _fnGetObjectDataFn( token )( ctx.oLanguage );\n\t\n\t\tif ( resolved === undefined ) {\n\t\t\tresolved = def;\n\t\t}\n\t\n\t\tif ( plural !== undefined && $.isPlainObject( resolved ) ) {\n\t\t\tresolved = resolved[ plural ] !== undefined ?\n\t\t\t\tresolved[ plural ] :\n\t\t\t\tresolved._;\n\t\t}\n\t\n\t\treturn resolved.replace( '%d', plural ); // nb: plural might be undefined,\n\t} );\n\n\t/**\n\t * Version string for plug-ins to check compatibility. Allowed format is\n\t * `a.b.c-d` where: a:int, b:int, c:int, d:string(dev|beta|alpha). `d` is used\n\t * only for non-release builds. See http://semver.org/ for more information.\n\t *  @member\n\t *  @type string\n\t *  @default Version number\n\t */\n\tDataTable.version = \"1.10.12\";\n\n\t/**\n\t * Private data store, containing all of the settings objects that are\n\t * created for the tables on a given page.\n\t *\n\t * Note that the `DataTable.settings` object is aliased to\n\t * `jQuery.fn.dataTableExt` through which it may be accessed and\n\t * manipulated, or `jQuery.fn.dataTable.settings`.\n\t *  @member\n\t *  @type array\n\t *  @default []\n\t *  @private\n\t */\n\tDataTable.settings = [];\n\n\t/**\n\t * Object models container, for the various models that DataTables has\n\t * available to it. These models define the objects that are used to hold\n\t * the active state and configuration of the table.\n\t *  @namespace\n\t */\n\tDataTable.models = {};\n\t\n\t\n\t\n\t/**\n\t * Template object for the way in which DataTables holds information about\n\t * search information for the global filter and individual column filters.\n\t *  @namespace\n\t */\n\tDataTable.models.oSearch = {\n\t\t/**\n\t\t * Flag to indicate if the filtering should be case insensitive or not\n\t\t *  @type boolean\n\t\t *  @default true\n\t\t */\n\t\t\"bCaseInsensitive\": true,\n\t\n\t\t/**\n\t\t * Applied search term\n\t\t *  @type string\n\t\t *  @default <i>Empty string</i>\n\t\t */\n\t\t\"sSearch\": \"\",\n\t\n\t\t/**\n\t\t * Flag to indicate if the search term should be interpreted as a\n\t\t * regular expression (true) or not (false) and therefore and special\n\t\t * regex characters escaped.\n\t\t *  @type boolean\n\t\t *  @default false\n\t\t */\n\t\t\"bRegex\": false,\n\t\n\t\t/**\n\t\t * Flag to indicate if DataTables is to use its smart filtering or not.\n\t\t *  @type boolean\n\t\t *  @default true\n\t\t */\n\t\t\"bSmart\": true\n\t};\n\t\n\t\n\t\n\t\n\t/**\n\t * Template object for the way in which DataTables holds information about\n\t * each individual row. This is the object format used for the settings\n\t * aoData array.\n\t *  @namespace\n\t */\n\tDataTable.models.oRow = {\n\t\t/**\n\t\t * TR element for the row\n\t\t *  @type node\n\t\t *  @default null\n\t\t */\n\t\t\"nTr\": null,\n\t\n\t\t/**\n\t\t * Array of TD elements for each row. This is null until the row has been\n\t\t * created.\n\t\t *  @type array nodes\n\t\t *  @default []\n\t\t */\n\t\t\"anCells\": null,\n\t\n\t\t/**\n\t\t * Data object from the original data source for the row. This is either\n\t\t * an array if using the traditional form of DataTables, or an object if\n\t\t * using mData options. The exact type will depend on the passed in\n\t\t * data from the data source, or will be an array if using DOM a data\n\t\t * source.\n\t\t *  @type array|object\n\t\t *  @default []\n\t\t */\n\t\t\"_aData\": [],\n\t\n\t\t/**\n\t\t * Sorting data cache - this array is ostensibly the same length as the\n\t\t * number of columns (although each index is generated only as it is\n\t\t * needed), and holds the data that is used for sorting each column in the\n\t\t * row. We do this cache generation at the start of the sort in order that\n\t\t * the formatting of the sort data need be done only once for each cell\n\t\t * per sort. This array should not be read from or written to by anything\n\t\t * other than the master sorting methods.\n\t\t *  @type array\n\t\t *  @default null\n\t\t *  @private\n\t\t */\n\t\t\"_aSortData\": null,\n\t\n\t\t/**\n\t\t * Per cell filtering data cache. As per the sort data cache, used to\n\t\t * increase the performance of the filtering in DataTables\n\t\t *  @type array\n\t\t *  @default null\n\t\t *  @private\n\t\t */\n\t\t\"_aFilterData\": null,\n\t\n\t\t/**\n\t\t * Filtering data cache. This is the same as the cell filtering cache, but\n\t\t * in this case a string rather than an array. This is easily computed with\n\t\t * a join on `_aFilterData`, but is provided as a cache so the join isn't\n\t\t * needed on every search (memory traded for performance)\n\t\t *  @type array\n\t\t *  @default null\n\t\t *  @private\n\t\t */\n\t\t\"_sFilterRow\": null,\n\t\n\t\t/**\n\t\t * Cache of the class name that DataTables has applied to the row, so we\n\t\t * can quickly look at this variable rather than needing to do a DOM check\n\t\t * on className for the nTr property.\n\t\t *  @type string\n\t\t *  @default <i>Empty string</i>\n\t\t *  @private\n\t\t */\n\t\t\"_sRowStripe\": \"\",\n\t\n\t\t/**\n\t\t * Denote if the original data source was from the DOM, or the data source\n\t\t * object. This is used for invalidating data, so DataTables can\n\t\t * automatically read data from the original source, unless uninstructed\n\t\t * otherwise.\n\t\t *  @type string\n\t\t *  @default null\n\t\t *  @private\n\t\t */\n\t\t\"src\": null,\n\t\n\t\t/**\n\t\t * Index in the aoData array. This saves an indexOf lookup when we have the\n\t\t * object, but want to know the index\n\t\t *  @type integer\n\t\t *  @default -1\n\t\t *  @private\n\t\t */\n\t\t\"idx\": -1\n\t};\n\t\n\t\n\t/**\n\t * Template object for the column information object in DataTables. This object\n\t * is held in the settings aoColumns array and contains all the information that\n\t * DataTables needs about each individual column.\n\t *\n\t * Note that this object is related to {@link DataTable.defaults.column}\n\t * but this one is the internal data store for DataTables's cache of columns.\n\t * It should NOT be manipulated outside of DataTables. Any configuration should\n\t * be done through the initialisation options.\n\t *  @namespace\n\t */\n\tDataTable.models.oColumn = {\n\t\t/**\n\t\t * Column index. This could be worked out on-the-fly with $.inArray, but it\n\t\t * is faster to just hold it as a variable\n\t\t *  @type integer\n\t\t *  @default null\n\t\t */\n\t\t\"idx\": null,\n\t\n\t\t/**\n\t\t * A list of the columns that sorting should occur on when this column\n\t\t * is sorted. That this property is an array allows multi-column sorting\n\t\t * to be defined for a column (for example first name / last name columns\n\t\t * would benefit from this). The values are integers pointing to the\n\t\t * columns to be sorted on (typically it will be a single integer pointing\n\t\t * at itself, but that doesn't need to be the case).\n\t\t *  @type array\n\t\t */\n\t\t\"aDataSort\": null,\n\t\n\t\t/**\n\t\t * Define the sorting directions that are applied to the column, in sequence\n\t\t * as the column is repeatedly sorted upon - i.e. the first value is used\n\t\t * as the sorting direction when the column if first sorted (clicked on).\n\t\t * Sort it again (click again) and it will move on to the next index.\n\t\t * Repeat until loop.\n\t\t *  @type array\n\t\t */\n\t\t\"asSorting\": null,\n\t\n\t\t/**\n\t\t * Flag to indicate if the column is searchable, and thus should be included\n\t\t * in the filtering or not.\n\t\t *  @type boolean\n\t\t */\n\t\t\"bSearchable\": null,\n\t\n\t\t/**\n\t\t * Flag to indicate if the column is sortable or not.\n\t\t *  @type boolean\n\t\t */\n\t\t\"bSortable\": null,\n\t\n\t\t/**\n\t\t * Flag to indicate if the column is currently visible in the table or not\n\t\t *  @type boolean\n\t\t */\n\t\t\"bVisible\": null,\n\t\n\t\t/**\n\t\t * Store for manual type assignment using the `column.type` option. This\n\t\t * is held in store so we can manipulate the column's `sType` property.\n\t\t *  @type string\n\t\t *  @default null\n\t\t *  @private\n\t\t */\n\t\t\"_sManualType\": null,\n\t\n\t\t/**\n\t\t * Flag to indicate if HTML5 data attributes should be used as the data\n\t\t * source for filtering or sorting. True is either are.\n\t\t *  @type boolean\n\t\t *  @default false\n\t\t *  @private\n\t\t */\n\t\t\"_bAttrSrc\": false,\n\t\n\t\t/**\n\t\t * Developer definable function that is called whenever a cell is created (Ajax source,\n\t\t * etc) or processed for input (DOM source). This can be used as a compliment to mRender\n\t\t * allowing you to modify the DOM element (add background colour for example) when the\n\t\t * element is available.\n\t\t *  @type function\n\t\t *  @param {element} nTd The TD node that has been created\n\t\t *  @param {*} sData The Data for the cell\n\t\t *  @param {array|object} oData The data for the whole row\n\t\t *  @param {int} iRow The row index for the aoData data store\n\t\t *  @default null\n\t\t */\n\t\t\"fnCreatedCell\": null,\n\t\n\t\t/**\n\t\t * Function to get data from a cell in a column. You should <b>never</b>\n\t\t * access data directly through _aData internally in DataTables - always use\n\t\t * the method attached to this property. It allows mData to function as\n\t\t * required. This function is automatically assigned by the column\n\t\t * initialisation method\n\t\t *  @type function\n\t\t *  @param {array|object} oData The data array/object for the array\n\t\t *    (i.e. aoData[]._aData)\n\t\t *  @param {string} sSpecific The specific data type you want to get -\n\t\t *    'display', 'type' 'filter' 'sort'\n\t\t *  @returns {*} The data for the cell from the given row's data\n\t\t *  @default null\n\t\t */\n\t\t\"fnGetData\": null,\n\t\n\t\t/**\n\t\t * Function to set data for a cell in the column. You should <b>never</b>\n\t\t * set the data directly to _aData internally in DataTables - always use\n\t\t * this method. It allows mData to function as required. This function\n\t\t * is automatically assigned by the column initialisation method\n\t\t *  @type function\n\t\t *  @param {array|object} oData The data array/object for the array\n\t\t *    (i.e. aoData[]._aData)\n\t\t *  @param {*} sValue Value to set\n\t\t *  @default null\n\t\t */\n\t\t\"fnSetData\": null,\n\t\n\t\t/**\n\t\t * Property to read the value for the cells in the column from the data\n\t\t * source array / object. If null, then the default content is used, if a\n\t\t * function is given then the return from the function is used.\n\t\t *  @type function|int|string|null\n\t\t *  @default null\n\t\t */\n\t\t\"mData\": null,\n\t\n\t\t/**\n\t\t * Partner property to mData which is used (only when defined) to get\n\t\t * the data - i.e. it is basically the same as mData, but without the\n\t\t * 'set' option, and also the data fed to it is the result from mData.\n\t\t * This is the rendering method to match the data method of mData.\n\t\t *  @type function|int|string|null\n\t\t *  @default null\n\t\t */\n\t\t\"mRender\": null,\n\t\n\t\t/**\n\t\t * Unique header TH/TD element for this column - this is what the sorting\n\t\t * listener is attached to (if sorting is enabled.)\n\t\t *  @type node\n\t\t *  @default null\n\t\t */\n\t\t\"nTh\": null,\n\t\n\t\t/**\n\t\t * Unique footer TH/TD element for this column (if there is one). Not used\n\t\t * in DataTables as such, but can be used for plug-ins to reference the\n\t\t * footer for each column.\n\t\t *  @type node\n\t\t *  @default null\n\t\t */\n\t\t\"nTf\": null,\n\t\n\t\t/**\n\t\t * The class to apply to all TD elements in the table's TBODY for the column\n\t\t *  @type string\n\t\t *  @default null\n\t\t */\n\t\t\"sClass\": null,\n\t\n\t\t/**\n\t\t * When DataTables calculates the column widths to assign to each column,\n\t\t * it finds the longest string in each column and then constructs a\n\t\t * temporary table and reads the widths from that. The problem with this\n\t\t * is that \"mmm\" is much wider then \"iiii\", but the latter is a longer\n\t\t * string - thus the calculation can go wrong (doing it properly and putting\n\t\t * it into an DOM object and measuring that is horribly(!) slow). Thus as\n\t\t * a \"work around\" we provide this option. It will append its value to the\n\t\t * text that is found to be the longest string for the column - i.e. padding.\n\t\t *  @type string\n\t\t */\n\t\t\"sContentPadding\": null,\n\t\n\t\t/**\n\t\t * Allows a default value to be given for a column's data, and will be used\n\t\t * whenever a null data source is encountered (this can be because mData\n\t\t * is set to null, or because the data source itself is null).\n\t\t *  @type string\n\t\t *  @default null\n\t\t */\n\t\t\"sDefaultContent\": null,\n\t\n\t\t/**\n\t\t * Name for the column, allowing reference to the column by name as well as\n\t\t * by index (needs a lookup to work by name).\n\t\t *  @type string\n\t\t */\n\t\t\"sName\": null,\n\t\n\t\t/**\n\t\t * Custom sorting data type - defines which of the available plug-ins in\n\t\t * afnSortData the custom sorting will use - if any is defined.\n\t\t *  @type string\n\t\t *  @default std\n\t\t */\n\t\t\"sSortDataType\": 'std',\n\t\n\t\t/**\n\t\t * Class to be applied to the header element when sorting on this column\n\t\t *  @type string\n\t\t *  @default null\n\t\t */\n\t\t\"sSortingClass\": null,\n\t\n\t\t/**\n\t\t * Class to be applied to the header element when sorting on this column -\n\t\t * when jQuery UI theming is used.\n\t\t *  @type string\n\t\t *  @default null\n\t\t */\n\t\t\"sSortingClassJUI\": null,\n\t\n\t\t/**\n\t\t * Title of the column - what is seen in the TH element (nTh).\n\t\t *  @type string\n\t\t */\n\t\t\"sTitle\": null,\n\t\n\t\t/**\n\t\t * Column sorting and filtering type\n\t\t *  @type string\n\t\t *  @default null\n\t\t */\n\t\t\"sType\": null,\n\t\n\t\t/**\n\t\t * Width of the column\n\t\t *  @type string\n\t\t *  @default null\n\t\t */\n\t\t\"sWidth\": null,\n\t\n\t\t/**\n\t\t * Width of the column when it was first \"encountered\"\n\t\t *  @type string\n\t\t *  @default null\n\t\t */\n\t\t\"sWidthOrig\": null\n\t};\n\t\n\t\n\t/*\n\t * Developer note: The properties of the object below are given in Hungarian\n\t * notation, that was used as the interface for DataTables prior to v1.10, however\n\t * from v1.10 onwards the primary interface is camel case. In order to avoid\n\t * breaking backwards compatibility utterly with this change, the Hungarian\n\t * version is still, internally the primary interface, but is is not documented\n\t * - hence the @name tags in each doc comment. This allows a Javascript function\n\t * to create a map from Hungarian notation to camel case (going the other direction\n\t * would require each property to be listed, which would at around 3K to the size\n\t * of DataTables, while this method is about a 0.5K hit.\n\t *\n\t * Ultimately this does pave the way for Hungarian notation to be dropped\n\t * completely, but that is a massive amount of work and will break current\n\t * installs (therefore is on-hold until v2).\n\t */\n\t\n\t/**\n\t * Initialisation options that can be given to DataTables at initialisation\n\t * time.\n\t *  @namespace\n\t */\n\tDataTable.defaults = {\n\t\t/**\n\t\t * An array of data to use for the table, passed in at initialisation which\n\t\t * will be used in preference to any data which is already in the DOM. This is\n\t\t * particularly useful for constructing tables purely in Javascript, for\n\t\t * example with a custom Ajax call.\n\t\t *  @type array\n\t\t *  @default null\n\t\t *\n\t\t *  @dtopt Option\n\t\t *  @name DataTable.defaults.data\n\t\t *\n\t\t *  @example\n\t\t *    // Using a 2D array data source\n\t\t *    $(document).ready( function () {\n\t\t *      $('#example').dataTable( {\n\t\t *        \"data\": [\n\t\t *          ['Trident', 'Internet Explorer 4.0', 'Win 95+', 4, 'X'],\n\t\t *          ['Trident', 'Internet Explorer 5.0', 'Win 95+', 5, 'C'],\n\t\t *        ],\n\t\t *        \"columns\": [\n\t\t *          { \"title\": \"Engine\" },\n\t\t *          { \"title\": \"Browser\" },\n\t\t *          { \"title\": \"Platform\" },\n\t\t *          { \"title\": \"Version\" },\n\t\t *          { \"title\": \"Grade\" }\n\t\t *        ]\n\t\t *      } );\n\t\t *    } );\n\t\t *\n\t\t *  @example\n\t\t *    // Using an array of objects as a data source (`data`)\n\t\t *    $(document).ready( function () {\n\t\t *      $('#example').dataTable( {\n\t\t *        \"data\": [\n\t\t *          {\n\t\t *            \"engine\":   \"Trident\",\n\t\t *            \"browser\":  \"Internet Explorer 4.0\",\n\t\t *            \"platform\": \"Win 95+\",\n\t\t *            \"version\":  4,\n\t\t *            \"grade\":    \"X\"\n\t\t *          },\n\t\t *          {\n\t\t *            \"engine\":   \"Trident\",\n\t\t *            \"browser\":  \"Internet Explorer 5.0\",\n\t\t *            \"platform\": \"Win 95+\",\n\t\t *            \"version\":  5,\n\t\t *            \"grade\":    \"C\"\n\t\t *          }\n\t\t *        ],\n\t\t *        \"columns\": [\n\t\t *          { \"title\": \"Engine\",   \"data\": \"engine\" },\n\t\t *          { \"title\": \"Browser\",  \"data\": \"browser\" },\n\t\t *          { \"title\": \"Platform\", \"data\": \"platform\" },\n\t\t *          { \"title\": \"Version\",  \"data\": \"version\" },\n\t\t *          { \"title\": \"Grade\",    \"data\": \"grade\" }\n\t\t *        ]\n\t\t *      } );\n\t\t *    } );\n\t\t */\n\t\t\"aaData\": null,\n\t\n\t\n\t\t/**\n\t\t * If ordering is enabled, then DataTables will perform a first pass sort on\n\t\t * initialisation. You can define which column(s) the sort is performed\n\t\t * upon, and the sorting direction, with this variable. The `sorting` array\n\t\t * should contain an array for each column to be sorted initially containing\n\t\t * the column's index and a direction string ('asc' or 'desc').\n\t\t *  @type array\n\t\t *  @default [[0,'asc']]\n\t\t *\n\t\t *  @dtopt Option\n\t\t *  @name DataTable.defaults.order\n\t\t *\n\t\t *  @example\n\t\t *    // Sort by 3rd column first, and then 4th column\n\t\t *    $(document).ready( function() {\n\t\t *      $('#example').dataTable( {\n\t\t *        \"order\": [[2,'asc'], [3,'desc']]\n\t\t *      } );\n\t\t *    } );\n\t\t *\n\t\t *    // No initial sorting\n\t\t *    $(document).ready( function() {\n\t\t *      $('#example').dataTable( {\n\t\t *        \"order\": []\n\t\t *      } );\n\t\t *    } );\n\t\t */\n\t\t\"aaSorting\": [[0,'asc']],\n\t\n\t\n\t\t/**\n\t\t * This parameter is basically identical to the `sorting` parameter, but\n\t\t * cannot be overridden by user interaction with the table. What this means\n\t\t * is that you could have a column (visible or hidden) which the sorting\n\t\t * will always be forced on first - any sorting after that (from the user)\n\t\t * will then be performed as required. This can be useful for grouping rows\n\t\t * together.\n\t\t *  @type array\n\t\t *  @default null\n\t\t *\n\t\t *  @dtopt Option\n\t\t *  @name DataTable.defaults.orderFixed\n\t\t *\n\t\t *  @example\n\t\t *    $(document).ready( function() {\n\t\t *      $('#example').dataTable( {\n\t\t *        \"orderFixed\": [[0,'asc']]\n\t\t *      } );\n\t\t *    } )\n\t\t */\n\t\t\"aaSortingFixed\": [],\n\t\n\t\n\t\t/**\n\t\t * DataTables can be instructed to load data to display in the table from a\n\t\t * Ajax source. This option defines how that Ajax call is made and where to.\n\t\t *\n\t\t * The `ajax` property has three different modes of operation, depending on\n\t\t * how it is defined. These are:\n\t\t *\n\t\t * * `string` - Set the URL from where the data should be loaded from.\n\t\t * * `object` - Define properties for `jQuery.ajax`.\n\t\t * * `function` - Custom data get function\n\t\t *\n\t\t * `string`\n\t\t * --------\n\t\t *\n\t\t * As a string, the `ajax` property simply defines the URL from which\n\t\t * DataTables will load data.\n\t\t *\n\t\t * `object`\n\t\t * --------\n\t\t *\n\t\t * As an object, the parameters in the object are passed to\n\t\t * [jQuery.ajax](http://api.jquery.com/jQuery.ajax/) allowing fine control\n\t\t * of the Ajax request. DataTables has a number of default parameters which\n\t\t * you can override using this option. Please refer to the jQuery\n\t\t * documentation for a full description of the options available, although\n\t\t * the following parameters provide additional options in DataTables or\n\t\t * require special consideration:\n\t\t *\n\t\t * * `data` - As with jQuery, `data` can be provided as an object, but it\n\t\t *   can also be used as a function to manipulate the data DataTables sends\n\t\t *   to the server. The function takes a single parameter, an object of\n\t\t *   parameters with the values that DataTables has readied for sending. An\n\t\t *   object may be returned which will be merged into the DataTables\n\t\t *   defaults, or you can add the items to the object that was passed in and\n\t\t *   not return anything from the function. This supersedes `fnServerParams`\n\t\t *   from DataTables 1.9-.\n\t\t *\n\t\t * * `dataSrc` - By default DataTables will look for the property `data` (or\n\t\t *   `aaData` for compatibility with DataTables 1.9-) when obtaining data\n\t\t *   from an Ajax source or for server-side processing - this parameter\n\t\t *   allows that property to be changed. You can use Javascript dotted\n\t\t *   object notation to get a data source for multiple levels of nesting, or\n\t\t *   it my be used as a function. As a function it takes a single parameter,\n\t\t *   the JSON returned from the server, which can be manipulated as\n\t\t *   required, with the returned value being that used by DataTables as the\n\t\t *   data source for the table. This supersedes `sAjaxDataProp` from\n\t\t *   DataTables 1.9-.\n\t\t *\n\t\t * * `success` - Should not be overridden it is used internally in\n\t\t *   DataTables. To manipulate / transform the data returned by the server\n\t\t *   use `ajax.dataSrc`, or use `ajax` as a function (see below).\n\t\t *\n\t\t * `function`\n\t\t * ----------\n\t\t *\n\t\t * As a function, making the Ajax call is left up to yourself allowing\n\t\t * complete control of the Ajax request. Indeed, if desired, a method other\n\t\t * than Ajax could be used to obtain the required data, such as Web storage\n\t\t * or an AIR database.\n\t\t *\n\t\t * The function is given four parameters and no return is required. The\n\t\t * parameters are:\n\t\t *\n\t\t * 1. _object_ - Data to send to the server\n\t\t * 2. _function_ - Callback function that must be executed when the required\n\t\t *    data has been obtained. That data should be passed into the callback\n\t\t *    as the only parameter\n\t\t * 3. _object_ - DataTables settings object for the table\n\t\t *\n\t\t * Note that this supersedes `fnServerData` from DataTables 1.9-.\n\t\t *\n\t\t *  @type string|object|function\n\t\t *  @default null\n\t\t *\n\t\t *  @dtopt Option\n\t\t *  @name DataTable.defaults.ajax\n\t\t *  @since 1.10.0\n\t\t *\n\t\t * @example\n\t\t *   // Get JSON data from a file via Ajax.\n\t\t *   // Note DataTables expects data in the form `{ data: [ ...data... ] }` by default).\n\t\t *   $('#example').dataTable( {\n\t\t *     \"ajax\": \"data.json\"\n\t\t *   } );\n\t\t *\n\t\t * @example\n\t\t *   // Get JSON data from a file via Ajax, using `dataSrc` to change\n\t\t *   // `data` to `tableData` (i.e. `{ tableData: [ ...data... ] }`)\n\t\t *   $('#example').dataTable( {\n\t\t *     \"ajax\": {\n\t\t *       \"url\": \"data.json\",\n\t\t *       \"dataSrc\": \"tableData\"\n\t\t *     }\n\t\t *   } );\n\t\t *\n\t\t * @example\n\t\t *   // Get JSON data from a file via Ajax, using `dataSrc` to read data\n\t\t *   // from a plain array rather than an array in an object\n\t\t *   $('#example').dataTable( {\n\t\t *     \"ajax\": {\n\t\t *       \"url\": \"data.json\",\n\t\t *       \"dataSrc\": \"\"\n\t\t *     }\n\t\t *   } );\n\t\t *\n\t\t * @example\n\t\t *   // Manipulate the data returned from the server - add a link to data\n\t\t *   // (note this can, should, be done using `render` for the column - this\n\t\t *   // is just a simple example of how the data can be manipulated).\n\t\t *   $('#example').dataTable( {\n\t\t *     \"ajax\": {\n\t\t *       \"url\": \"data.json\",\n\t\t *       \"dataSrc\": function ( json ) {\n\t\t *         for ( var i=0, ien=json.length ; i<ien ; i++ ) {\n\t\t *           json[i][0] = '<a href=\"/message/'+json[i][0]+'>View message</a>';\n\t\t *         }\n\t\t *         return json;\n\t\t *       }\n\t\t *     }\n\t\t *   } );\n\t\t *\n\t\t * @example\n\t\t *   // Add data to the request\n\t\t *   $('#example').dataTable( {\n\t\t *     \"ajax\": {\n\t\t *       \"url\": \"data.json\",\n\t\t *       \"data\": function ( d ) {\n\t\t *         return {\n\t\t *           \"extra_search\": $('#extra').val()\n\t\t *         };\n\t\t *       }\n\t\t *     }\n\t\t *   } );\n\t\t *\n\t\t * @example\n\t\t *   // Send request as POST\n\t\t *   $('#example').dataTable( {\n\t\t *     \"ajax\": {\n\t\t *       \"url\": \"data.json\",\n\t\t *       \"type\": \"POST\"\n\t\t *     }\n\t\t *   } );\n\t\t *\n\t\t * @example\n\t\t *   // Get the data from localStorage (could interface with a form for\n\t\t *   // adding, editing and removing rows).\n\t\t *   $('#example').dataTable( {\n\t\t *     \"ajax\": function (data, callback, settings) {\n\t\t *       callback(\n\t\t *         JSON.parse( localStorage.getItem('dataTablesData') )\n\t\t *       );\n\t\t *     }\n\t\t *   } );\n\t\t */\n\t\t\"ajax\": null,\n\t\n\t\n\t\t/**\n\t\t * This parameter allows you to readily specify the entries in the length drop\n\t\t * down menu that DataTables shows when pagination is enabled. It can be\n\t\t * either a 1D array of options which will be used for both the displayed\n\t\t * option and the value, or a 2D array which will use the array in the first\n\t\t * position as the value, and the array in the second position as the\n\t\t * displayed options (useful for language strings such as 'All').\n\t\t *\n\t\t * Note that the `pageLength` property will be automatically set to the\n\t\t * first value given in this array, unless `pageLength` is also provided.\n\t\t *  @type array\n\t\t *  @default [ 10, 25, 50, 100 ]\n\t\t *\n\t\t *  @dtopt Option\n\t\t *  @name DataTable.defaults.lengthMenu\n\t\t *\n\t\t *  @example\n\t\t *    $(document).ready( function() {\n\t\t *      $('#example').dataTable( {\n\t\t *        \"lengthMenu\": [[10, 25, 50, -1], [10, 25, 50, \"All\"]]\n\t\t *      } );\n\t\t *    } );\n\t\t */\n\t\t\"aLengthMenu\": [ 10, 25, 50, 100 ],\n\t\n\t\n\t\t/**\n\t\t * The `columns` option in the initialisation parameter allows you to define\n\t\t * details about the way individual columns behave. For a full list of\n\t\t * column options that can be set, please see\n\t\t * {@link DataTable.defaults.column}. Note that if you use `columns` to\n\t\t * define your columns, you must have an entry in the array for every single\n\t\t * column that you have in your table (these can be null if you don't which\n\t\t * to specify any options).\n\t\t *  @member\n\t\t *\n\t\t *  @name DataTable.defaults.column\n\t\t */\n\t\t\"aoColumns\": null,\n\t\n\t\t/**\n\t\t * Very similar to `columns`, `columnDefs` allows you to target a specific\n\t\t * column, multiple columns, or all columns, using the `targets` property of\n\t\t * each object in the array. This allows great flexibility when creating\n\t\t * tables, as the `columnDefs` arrays can be of any length, targeting the\n\t\t * columns you specifically want. `columnDefs` may use any of the column\n\t\t * options available: {@link DataTable.defaults.column}, but it _must_\n\t\t * have `targets` defined in each object in the array. Values in the `targets`\n\t\t * array may be:\n\t\t *   <ul>\n\t\t *     <li>a string - class name will be matched on the TH for the column</li>\n\t\t *     <li>0 or a positive integer - column index counting from the left</li>\n\t\t *     <li>a negative integer - column index counting from the right</li>\n\t\t *     <li>the string \"_all\" - all columns (i.e. assign a default)</li>\n\t\t *   </ul>\n\t\t *  @member\n\t\t *\n\t\t *  @name DataTable.defaults.columnDefs\n\t\t */\n\t\t\"aoColumnDefs\": null,\n\t\n\t\n\t\t/**\n\t\t * Basically the same as `search`, this parameter defines the individual column\n\t\t * filtering state at initialisation time. The array must be of the same size\n\t\t * as the number of columns, and each element be an object with the parameters\n\t\t * `search` and `escapeRegex` (the latter is optional). 'null' is also\n\t\t * accepted and the default will be used.\n\t\t *  @type array\n\t\t *  @default []\n\t\t *\n\t\t *  @dtopt Option\n\t\t *  @name DataTable.defaults.searchCols\n\t\t *\n\t\t *  @example\n\t\t *    $(document).ready( function() {\n\t\t *      $('#example').dataTable( {\n\t\t *        \"searchCols\": [\n\t\t *          null,\n\t\t *          { \"search\": \"My filter\" },\n\t\t *          null,\n\t\t *          { \"search\": \"^[0-9]\", \"escapeRegex\": false }\n\t\t *        ]\n\t\t *      } );\n\t\t *    } )\n\t\t */\n\t\t\"aoSearchCols\": [],\n\t\n\t\n\t\t/**\n\t\t * An array of CSS classes that should be applied to displayed rows. This\n\t\t * array may be of any length, and DataTables will apply each class\n\t\t * sequentially, looping when required.\n\t\t *  @type array\n\t\t *  @default null <i>Will take the values determined by the `oClasses.stripe*`\n\t\t *    options</i>\n\t\t *\n\t\t *  @dtopt Option\n\t\t *  @name DataTable.defaults.stripeClasses\n\t\t *\n\t\t *  @example\n\t\t *    $(document).ready( function() {\n\t\t *      $('#example').dataTable( {\n\t\t *        \"stripeClasses\": [ 'strip1', 'strip2', 'strip3' ]\n\t\t *      } );\n\t\t *    } )\n\t\t */\n\t\t\"asStripeClasses\": null,\n\t\n\t\n\t\t/**\n\t\t * Enable or disable automatic column width calculation. This can be disabled\n\t\t * as an optimisation (it takes some time to calculate the widths) if the\n\t\t * tables widths are passed in using `columns`.\n\t\t *  @type boolean\n\t\t *  @default true\n\t\t *\n\t\t *  @dtopt Features\n\t\t *  @name DataTable.defaults.autoWidth\n\t\t *\n\t\t *  @example\n\t\t *    $(document).ready( function () {\n\t\t *      $('#example').dataTable( {\n\t\t *        \"autoWidth\": false\n\t\t *      } );\n\t\t *    } );\n\t\t */\n\t\t\"bAutoWidth\": true,\n\t\n\t\n\t\t/**\n\t\t * Deferred rendering can provide DataTables with a huge speed boost when you\n\t\t * are using an Ajax or JS data source for the table. This option, when set to\n\t\t * true, will cause DataTables to defer the creation of the table elements for\n\t\t * each row until they are needed for a draw - saving a significant amount of\n\t\t * time.\n\t\t *  @type boolean\n\t\t *  @default false\n\t\t *\n\t\t *  @dtopt Features\n\t\t *  @name DataTable.defaults.deferRender\n\t\t *\n\t\t *  @example\n\t\t *    $(document).ready( function() {\n\t\t *      $('#example').dataTable( {\n\t\t *        \"ajax\": \"sources/arrays.txt\",\n\t\t *        \"deferRender\": true\n\t\t *      } );\n\t\t *    } );\n\t\t */\n\t\t\"bDeferRender\": false,\n\t\n\t\n\t\t/**\n\t\t * Replace a DataTable which matches the given selector and replace it with\n\t\t * one which has the properties of the new initialisation object passed. If no\n\t\t * table matches the selector, then the new DataTable will be constructed as\n\t\t * per normal.\n\t\t *  @type boolean\n\t\t *  @default false\n\t\t *\n\t\t *  @dtopt Options\n\t\t *  @name DataTable.defaults.destroy\n\t\t *\n\t\t *  @example\n\t\t *    $(document).ready( function() {\n\t\t *      $('#example').dataTable( {\n\t\t *        \"srollY\": \"200px\",\n\t\t *        \"paginate\": false\n\t\t *      } );\n\t\t *\n\t\t *      // Some time later....\n\t\t *      $('#example').dataTable( {\n\t\t *        \"filter\": false,\n\t\t *        \"destroy\": true\n\t\t *      } );\n\t\t *    } );\n\t\t */\n\t\t\"bDestroy\": false,\n\t\n\t\n\t\t/**\n\t\t * Enable or disable filtering of data. Filtering in DataTables is \"smart\" in\n\t\t * that it allows the end user to input multiple words (space separated) and\n\t\t * will match a row containing those words, even if not in the order that was\n\t\t * specified (this allow matching across multiple columns). Note that if you\n\t\t * wish to use filtering in DataTables this must remain 'true' - to remove the\n\t\t * default filtering input box and retain filtering abilities, please use\n\t\t * {@link DataTable.defaults.dom}.\n\t\t *  @type boolean\n\t\t *  @default true\n\t\t *\n\t\t *  @dtopt Features\n\t\t *  @name DataTable.defaults.searching\n\t\t *\n\t\t *  @example\n\t\t *    $(document).ready( function () {\n\t\t *      $('#example').dataTable( {\n\t\t *        \"searching\": false\n\t\t *      } );\n\t\t *    } );\n\t\t */\n\t\t\"bFilter\": true,\n\t\n\t\n\t\t/**\n\t\t * Enable or disable the table information display. This shows information\n\t\t * about the data that is currently visible on the page, including information\n\t\t * about filtered data if that action is being performed.\n\t\t *  @type boolean\n\t\t *  @default true\n\t\t *\n\t\t *  @dtopt Features\n\t\t *  @name DataTable.defaults.info\n\t\t *\n\t\t *  @example\n\t\t *    $(document).ready( function () {\n\t\t *      $('#example').dataTable( {\n\t\t *        \"info\": false\n\t\t *      } );\n\t\t *    } );\n\t\t */\n\t\t\"bInfo\": true,\n\t\n\t\n\t\t/**\n\t\t * Enable jQuery UI ThemeRoller support (required as ThemeRoller requires some\n\t\t * slightly different and additional mark-up from what DataTables has\n\t\t * traditionally used).\n\t\t *  @type boolean\n\t\t *  @default false\n\t\t *\n\t\t *  @dtopt Features\n\t\t *  @name DataTable.defaults.jQueryUI\n\t\t *\n\t\t *  @example\n\t\t *    $(document).ready( function() {\n\t\t *      $('#example').dataTable( {\n\t\t *        \"jQueryUI\": true\n\t\t *      } );\n\t\t *    } );\n\t\t */\n\t\t\"bJQueryUI\": false,\n\t\n\t\n\t\t/**\n\t\t * Allows the end user to select the size of a formatted page from a select\n\t\t * menu (sizes are 10, 25, 50 and 100). Requires pagination (`paginate`).\n\t\t *  @type boolean\n\t\t *  @default true\n\t\t *\n\t\t *  @dtopt Features\n\t\t *  @name DataTable.defaults.lengthChange\n\t\t *\n\t\t *  @example\n\t\t *    $(document).ready( function () {\n\t\t *      $('#example').dataTable( {\n\t\t *        \"lengthChange\": false\n\t\t *      } );\n\t\t *    } );\n\t\t */\n\t\t\"bLengthChange\": true,\n\t\n\t\n\t\t/**\n\t\t * Enable or disable pagination.\n\t\t *  @type boolean\n\t\t *  @default true\n\t\t *\n\t\t *  @dtopt Features\n\t\t *  @name DataTable.defaults.paging\n\t\t *\n\t\t *  @example\n\t\t *    $(document).ready( function () {\n\t\t *      $('#example').dataTable( {\n\t\t *        \"paging\": false\n\t\t *      } );\n\t\t *    } );\n\t\t */\n\t\t\"bPaginate\": true,\n\t\n\t\n\t\t/**\n\t\t * Enable or disable the display of a 'processing' indicator when the table is\n\t\t * being processed (e.g. a sort). This is particularly useful for tables with\n\t\t * large amounts of data where it can take a noticeable amount of time to sort\n\t\t * the entries.\n\t\t *  @type boolean\n\t\t *  @default false\n\t\t *\n\t\t *  @dtopt Features\n\t\t *  @name DataTable.defaults.processing\n\t\t *\n\t\t *  @example\n\t\t *    $(document).ready( function () {\n\t\t *      $('#example').dataTable( {\n\t\t *        \"processing\": true\n\t\t *      } );\n\t\t *    } );\n\t\t */\n\t\t\"bProcessing\": false,\n\t\n\t\n\t\t/**\n\t\t * Retrieve the DataTables object for the given selector. Note that if the\n\t\t * table has already been initialised, this parameter will cause DataTables\n\t\t * to simply return the object that has already been set up - it will not take\n\t\t * account of any changes you might have made to the initialisation object\n\t\t * passed to DataTables (setting this parameter to true is an acknowledgement\n\t\t * that you understand this). `destroy` can be used to reinitialise a table if\n\t\t * you need.\n\t\t *  @type boolean\n\t\t *  @default false\n\t\t *\n\t\t *  @dtopt Options\n\t\t *  @name DataTable.defaults.retrieve\n\t\t *\n\t\t *  @example\n\t\t *    $(document).ready( function() {\n\t\t *      initTable();\n\t\t *      tableActions();\n\t\t *    } );\n\t\t *\n\t\t *    function initTable ()\n\t\t *    {\n\t\t *      return $('#example').dataTable( {\n\t\t *        \"scrollY\": \"200px\",\n\t\t *        \"paginate\": false,\n\t\t *        \"retrieve\": true\n\t\t *      } );\n\t\t *    }\n\t\t *\n\t\t *    function tableActions ()\n\t\t *    {\n\t\t *      var table = initTable();\n\t\t *      // perform API operations with oTable\n\t\t *    }\n\t\t */\n\t\t\"bRetrieve\": false,\n\t\n\t\n\t\t/**\n\t\t * When vertical (y) scrolling is enabled, DataTables will force the height of\n\t\t * the table's viewport to the given height at all times (useful for layout).\n\t\t * However, this can look odd when filtering data down to a small data set,\n\t\t * and the footer is left \"floating\" further down. This parameter (when\n\t\t * enabled) will cause DataTables to collapse the table's viewport down when\n\t\t * the result set will fit within the given Y height.\n\t\t *  @type boolean\n\t\t *  @default false\n\t\t *\n\t\t *  @dtopt Options\n\t\t *  @name DataTable.defaults.scrollCollapse\n\t\t *\n\t\t *  @example\n\t\t *    $(document).ready( function() {\n\t\t *      $('#example').dataTable( {\n\t\t *        \"scrollY\": \"200\",\n\t\t *        \"scrollCollapse\": true\n\t\t *      } );\n\t\t *    } );\n\t\t */\n\t\t\"bScrollCollapse\": false,\n\t\n\t\n\t\t/**\n\t\t * Configure DataTables to use server-side processing. Note that the\n\t\t * `ajax` parameter must also be given in order to give DataTables a\n\t\t * source to obtain the required data for each draw.\n\t\t *  @type boolean\n\t\t *  @default false\n\t\t *\n\t\t *  @dtopt Features\n\t\t *  @dtopt Server-side\n\t\t *  @name DataTable.defaults.serverSide\n\t\t *\n\t\t *  @example\n\t\t *    $(document).ready( function () {\n\t\t *      $('#example').dataTable( {\n\t\t *        \"serverSide\": true,\n\t\t *        \"ajax\": \"xhr.php\"\n\t\t *      } );\n\t\t *    } );\n\t\t */\n\t\t\"bServerSide\": false,\n\t\n\t\n\t\t/**\n\t\t * Enable or disable sorting of columns. Sorting of individual columns can be\n\t\t * disabled by the `sortable` option for each column.\n\t\t *  @type boolean\n\t\t *  @default true\n\t\t *\n\t\t *  @dtopt Features\n\t\t *  @name DataTable.defaults.ordering\n\t\t *\n\t\t *  @example\n\t\t *    $(document).ready( function () {\n\t\t *      $('#example').dataTable( {\n\t\t *        \"ordering\": false\n\t\t *      } );\n\t\t *    } );\n\t\t */\n\t\t\"bSort\": true,\n\t\n\t\n\t\t/**\n\t\t * Enable or display DataTables' ability to sort multiple columns at the\n\t\t * same time (activated by shift-click by the user).\n\t\t *  @type boolean\n\t\t *  @default true\n\t\t *\n\t\t *  @dtopt Options\n\t\t *  @name DataTable.defaults.orderMulti\n\t\t *\n\t\t *  @example\n\t\t *    // Disable multiple column sorting ability\n\t\t *    $(document).ready( function () {\n\t\t *      $('#example').dataTable( {\n\t\t *        \"orderMulti\": false\n\t\t *      } );\n\t\t *    } );\n\t\t */\n\t\t\"bSortMulti\": true,\n\t\n\t\n\t\t/**\n\t\t * Allows control over whether DataTables should use the top (true) unique\n\t\t * cell that is found for a single column, or the bottom (false - default).\n\t\t * This is useful when using complex headers.\n\t\t *  @type boolean\n\t\t *  @default false\n\t\t *\n\t\t *  @dtopt Options\n\t\t *  @name DataTable.defaults.orderCellsTop\n\t\t *\n\t\t *  @example\n\t\t *    $(document).ready( function() {\n\t\t *      $('#example').dataTable( {\n\t\t *        \"orderCellsTop\": true\n\t\t *      } );\n\t\t *    } );\n\t\t */\n\t\t\"bSortCellsTop\": false,\n\t\n\t\n\t\t/**\n\t\t * Enable or disable the addition of the classes `sorting\\_1`, `sorting\\_2` and\n\t\t * `sorting\\_3` to the columns which are currently being sorted on. This is\n\t\t * presented as a feature switch as it can increase processing time (while\n\t\t * classes are removed and added) so for large data sets you might want to\n\t\t * turn this off.\n\t\t *  @type boolean\n\t\t *  @default true\n\t\t *\n\t\t *  @dtopt Features\n\t\t *  @name DataTable.defaults.orderClasses\n\t\t *\n\t\t *  @example\n\t\t *    $(document).ready( function () {\n\t\t *      $('#example').dataTable( {\n\t\t *        \"orderClasses\": false\n\t\t *      } );\n\t\t *    } );\n\t\t */\n\t\t\"bSortClasses\": true,\n\t\n\t\n\t\t/**\n\t\t * Enable or disable state saving. When enabled HTML5 `localStorage` will be\n\t\t * used to save table display information such as pagination information,\n\t\t * display length, filtering and sorting. As such when the end user reloads\n\t\t * the page the display display will match what thy had previously set up.\n\t\t *\n\t\t * Due to the use of `localStorage` the default state saving is not supported\n\t\t * in IE6 or 7. If state saving is required in those browsers, use\n\t\t * `stateSaveCallback` to provide a storage solution such as cookies.\n\t\t *  @type boolean\n\t\t *  @default false\n\t\t *\n\t\t *  @dtopt Features\n\t\t *  @name DataTable.defaults.stateSave\n\t\t *\n\t\t *  @example\n\t\t *    $(document).ready( function () {\n\t\t *      $('#example').dataTable( {\n\t\t *        \"stateSave\": true\n\t\t *      } );\n\t\t *    } );\n\t\t */\n\t\t\"bStateSave\": false,\n\t\n\t\n\t\t/**\n\t\t * This function is called when a TR element is created (and all TD child\n\t\t * elements have been inserted), or registered if using a DOM source, allowing\n\t\t * manipulation of the TR element (adding classes etc).\n\t\t *  @type function\n\t\t *  @param {node} row \"TR\" element for the current row\n\t\t *  @param {array} data Raw data array for this row\n\t\t *  @param {int} dataIndex The index of this row in the internal aoData array\n\t\t *\n\t\t *  @dtopt Callbacks\n\t\t *  @name DataTable.defaults.createdRow\n\t\t *\n\t\t *  @example\n\t\t *    $(document).ready( function() {\n\t\t *      $('#example').dataTable( {\n\t\t *        \"createdRow\": function( row, data, dataIndex ) {\n\t\t *          // Bold the grade for all 'A' grade browsers\n\t\t *          if ( data[4] == \"A\" )\n\t\t *          {\n\t\t *            $('td:eq(4)', row).html( '<b>A</b>' );\n\t\t *          }\n\t\t *        }\n\t\t *      } );\n\t\t *    } );\n\t\t */\n\t\t\"fnCreatedRow\": null,\n\t\n\t\n\t\t/**\n\t\t * This function is called on every 'draw' event, and allows you to\n\t\t * dynamically modify any aspect you want about the created DOM.\n\t\t *  @type function\n\t\t *  @param {object} settings DataTables settings object\n\t\t *\n\t\t *  @dtopt Callbacks\n\t\t *  @name DataTable.defaults.drawCallback\n\t\t *\n\t\t *  @example\n\t\t *    $(document).ready( function() {\n\t\t *      $('#example').dataTable( {\n\t\t *        \"drawCallback\": function( settings ) {\n\t\t *          alert( 'DataTables has redrawn the table' );\n\t\t *        }\n\t\t *      } );\n\t\t *    } );\n\t\t */\n\t\t\"fnDrawCallback\": null,\n\t\n\t\n\t\t/**\n\t\t * Identical to fnHeaderCallback() but for the table footer this function\n\t\t * allows you to modify the table footer on every 'draw' event.\n\t\t *  @type function\n\t\t *  @param {node} foot \"TR\" element for the footer\n\t\t *  @param {array} data Full table data (as derived from the original HTML)\n\t\t *  @param {int} start Index for the current display starting point in the\n\t\t *    display array\n\t\t *  @param {int} end Index for the current display ending point in the\n\t\t *    display array\n\t\t *  @param {array int} display Index array to translate the visual position\n\t\t *    to the full data array\n\t\t *\n\t\t *  @dtopt Callbacks\n\t\t *  @name DataTable.defaults.footerCallback\n\t\t *\n\t\t *  @example\n\t\t *    $(document).ready( function() {\n\t\t *      $('#example').dataTable( {\n\t\t *        \"footerCallback\": function( tfoot, data, start, end, display ) {\n\t\t *          tfoot.getElementsByTagName('th')[0].innerHTML = \"Starting index is \"+start;\n\t\t *        }\n\t\t *      } );\n\t\t *    } )\n\t\t */\n\t\t\"fnFooterCallback\": null,\n\t\n\t\n\t\t/**\n\t\t * When rendering large numbers in the information element for the table\n\t\t * (i.e. \"Showing 1 to 10 of 57 entries\") DataTables will render large numbers\n\t\t * to have a comma separator for the 'thousands' units (e.g. 1 million is\n\t\t * rendered as \"1,000,000\") to help readability for the end user. This\n\t\t * function will override the default method DataTables uses.\n\t\t *  @type function\n\t\t *  @member\n\t\t *  @param {int} toFormat number to be formatted\n\t\t *  @returns {string} formatted string for DataTables to show the number\n\t\t *\n\t\t *  @dtopt Callbacks\n\t\t *  @name DataTable.defaults.formatNumber\n\t\t *\n\t\t *  @example\n\t\t *    // Format a number using a single quote for the separator (note that\n\t\t *    // this can also be done with the language.thousands option)\n\t\t *    $(document).ready( function() {\n\t\t *      $('#example').dataTable( {\n\t\t *        \"formatNumber\": function ( toFormat ) {\n\t\t *          return toFormat.toString().replace(\n\t\t *            /\\B(?=(\\d{3})+(?!\\d))/g, \"'\"\n\t\t *          );\n\t\t *        };\n\t\t *      } );\n\t\t *    } );\n\t\t */\n\t\t\"fnFormatNumber\": function ( toFormat ) {\n\t\t\treturn toFormat.toString().replace(\n\t\t\t\t/\\B(?=(\\d{3})+(?!\\d))/g,\n\t\t\t\tthis.oLanguage.sThousands\n\t\t\t);\n\t\t},\n\t\n\t\n\t\t/**\n\t\t * This function is called on every 'draw' event, and allows you to\n\t\t * dynamically modify the header row. This can be used to calculate and\n\t\t * display useful information about the table.\n\t\t *  @type function\n\t\t *  @param {node} head \"TR\" element for the header\n\t\t *  @param {array} data Full table data (as derived from the original HTML)\n\t\t *  @param {int} start Index for the current display starting point in the\n\t\t *    display array\n\t\t *  @param {int} end Index for the current display ending point in the\n\t\t *    display array\n\t\t *  @param {array int} display Index array to translate the visual position\n\t\t *    to the full data array\n\t\t *\n\t\t *  @dtopt Callbacks\n\t\t *  @name DataTable.defaults.headerCallback\n\t\t *\n\t\t *  @example\n\t\t *    $(document).ready( function() {\n\t\t *      $('#example').dataTable( {\n\t\t *        \"fheaderCallback\": function( head, data, start, end, display ) {\n\t\t *          head.getElementsByTagName('th')[0].innerHTML = \"Displaying \"+(end-start)+\" records\";\n\t\t *        }\n\t\t *      } );\n\t\t *    } )\n\t\t */\n\t\t\"fnHeaderCallback\": null,\n\t\n\t\n\t\t/**\n\t\t * The information element can be used to convey information about the current\n\t\t * state of the table. Although the internationalisation options presented by\n\t\t * DataTables are quite capable of dealing with most customisations, there may\n\t\t * be times where you wish to customise the string further. This callback\n\t\t * allows you to do exactly that.\n\t\t *  @type function\n\t\t *  @param {object} oSettings DataTables settings object\n\t\t *  @param {int} start Starting position in data for the draw\n\t\t *  @param {int} end End position in data for the draw\n\t\t *  @param {int} max Total number of rows in the table (regardless of\n\t\t *    filtering)\n\t\t *  @param {int} total Total number of rows in the data set, after filtering\n\t\t *  @param {string} pre The string that DataTables has formatted using it's\n\t\t *    own rules\n\t\t *  @returns {string} The string to be displayed in the information element.\n\t\t *\n\t\t *  @dtopt Callbacks\n\t\t *  @name DataTable.defaults.infoCallback\n\t\t *\n\t\t *  @example\n\t\t *    $('#example').dataTable( {\n\t\t *      \"infoCallback\": function( settings, start, end, max, total, pre ) {\n\t\t *        return start +\" to \"+ end;\n\t\t *      }\n\t\t *    } );\n\t\t */\n\t\t\"fnInfoCallback\": null,\n\t\n\t\n\t\t/**\n\t\t * Called when the table has been initialised. Normally DataTables will\n\t\t * initialise sequentially and there will be no need for this function,\n\t\t * however, this does not hold true when using external language information\n\t\t * since that is obtained using an async XHR call.\n\t\t *  @type function\n\t\t *  @param {object} settings DataTables settings object\n\t\t *  @param {object} json The JSON object request from the server - only\n\t\t *    present if client-side Ajax sourced data is used\n\t\t *\n\t\t *  @dtopt Callbacks\n\t\t *  @name DataTable.defaults.initComplete\n\t\t *\n\t\t *  @example\n\t\t *    $(document).ready( function() {\n\t\t *      $('#example').dataTable( {\n\t\t *        \"initComplete\": function(settings, json) {\n\t\t *          alert( 'DataTables has finished its initialisation.' );\n\t\t *        }\n\t\t *      } );\n\t\t *    } )\n\t\t */\n\t\t\"fnInitComplete\": null,\n\t\n\t\n\t\t/**\n\t\t * Called at the very start of each table draw and can be used to cancel the\n\t\t * draw by returning false, any other return (including undefined) results in\n\t\t * the full draw occurring).\n\t\t *  @type function\n\t\t *  @param {object} settings DataTables settings object\n\t\t *  @returns {boolean} False will cancel the draw, anything else (including no\n\t\t *    return) will allow it to complete.\n\t\t *\n\t\t *  @dtopt Callbacks\n\t\t *  @name DataTable.defaults.preDrawCallback\n\t\t *\n\t\t *  @example\n\t\t *    $(document).ready( function() {\n\t\t *      $('#example').dataTable( {\n\t\t *        \"preDrawCallback\": function( settings ) {\n\t\t *          if ( $('#test').val() == 1 ) {\n\t\t *            return false;\n\t\t *          }\n\t\t *        }\n\t\t *      } );\n\t\t *    } );\n\t\t */\n\t\t\"fnPreDrawCallback\": null,\n\t\n\t\n\t\t/**\n\t\t * This function allows you to 'post process' each row after it have been\n\t\t * generated for each table draw, but before it is rendered on screen. This\n\t\t * function might be used for setting the row class name etc.\n\t\t *  @type function\n\t\t *  @param {node} row \"TR\" element for the current row\n\t\t *  @param {array} data Raw data array for this row\n\t\t *  @param {int} displayIndex The display index for the current table draw\n\t\t *  @param {int} displayIndexFull The index of the data in the full list of\n\t\t *    rows (after filtering)\n\t\t *\n\t\t *  @dtopt Callbacks\n\t\t *  @name DataTable.defaults.rowCallback\n\t\t *\n\t\t *  @example\n\t\t *    $(document).ready( function() {\n\t\t *      $('#example').dataTable( {\n\t\t *        \"rowCallback\": function( row, data, displayIndex, displayIndexFull ) {\n\t\t *          // Bold the grade for all 'A' grade browsers\n\t\t *          if ( data[4] == \"A\" ) {\n\t\t *            $('td:eq(4)', row).html( '<b>A</b>' );\n\t\t *          }\n\t\t *        }\n\t\t *      } );\n\t\t *    } );\n\t\t */\n\t\t\"fnRowCallback\": null,\n\t\n\t\n\t\t/**\n\t\t * __Deprecated__ The functionality provided by this parameter has now been\n\t\t * superseded by that provided through `ajax`, which should be used instead.\n\t\t *\n\t\t * This parameter allows you to override the default function which obtains\n\t\t * the data from the server so something more suitable for your application.\n\t\t * For example you could use POST data, or pull information from a Gears or\n\t\t * AIR database.\n\t\t *  @type function\n\t\t *  @member\n\t\t *  @param {string} source HTTP source to obtain the data from (`ajax`)\n\t\t *  @param {array} data A key/value pair object containing the data to send\n\t\t *    to the server\n\t\t *  @param {function} callback to be called on completion of the data get\n\t\t *    process that will draw the data on the page.\n\t\t *  @param {object} settings DataTables settings object\n\t\t *\n\t\t *  @dtopt Callbacks\n\t\t *  @dtopt Server-side\n\t\t *  @name DataTable.defaults.serverData\n\t\t *\n\t\t *  @deprecated 1.10. Please use `ajax` for this functionality now.\n\t\t */\n\t\t\"fnServerData\": null,\n\t\n\t\n\t\t/**\n\t\t * __Deprecated__ The functionality provided by this parameter has now been\n\t\t * superseded by that provided through `ajax`, which should be used instead.\n\t\t *\n\t\t *  It is often useful to send extra data to the server when making an Ajax\n\t\t * request - for example custom filtering information, and this callback\n\t\t * function makes it trivial to send extra information to the server. The\n\t\t * passed in parameter is the data set that has been constructed by\n\t\t * DataTables, and you can add to this or modify it as you require.\n\t\t *  @type function\n\t\t *  @param {array} data Data array (array of objects which are name/value\n\t\t *    pairs) that has been constructed by DataTables and will be sent to the\n\t\t *    server. In the case of Ajax sourced data with server-side processing\n\t\t *    this will be an empty array, for server-side processing there will be a\n\t\t *    significant number of parameters!\n\t\t *  @returns {undefined} Ensure that you modify the data array passed in,\n\t\t *    as this is passed by reference.\n\t\t *\n\t\t *  @dtopt Callbacks\n\t\t *  @dtopt Server-side\n\t\t *  @name DataTable.defaults.serverParams\n\t\t *\n\t\t *  @deprecated 1.10. Please use `ajax` for this functionality now.\n\t\t */\n\t\t\"fnServerParams\": null,\n\t\n\t\n\t\t/**\n\t\t * Load the table state. With this function you can define from where, and how, the\n\t\t * state of a table is loaded. By default DataTables will load from `localStorage`\n\t\t * but you might wish to use a server-side database or cookies.\n\t\t *  @type function\n\t\t *  @member\n\t\t *  @param {object} settings DataTables settings object\n\t\t *  @return {object} The DataTables state object to be loaded\n\t\t *\n\t\t *  @dtopt Callbacks\n\t\t *  @name DataTable.defaults.stateLoadCallback\n\t\t *\n\t\t *  @example\n\t\t *    $(document).ready( function() {\n\t\t *      $('#example').dataTable( {\n\t\t *        \"stateSave\": true,\n\t\t *        \"stateLoadCallback\": function (settings) {\n\t\t *          var o;\n\t\t *\n\t\t *          // Send an Ajax request to the server to get the data. Note that\n\t\t *          // this is a synchronous request.\n\t\t *          $.ajax( {\n\t\t *            \"url\": \"/state_load\",\n\t\t *            \"async\": false,\n\t\t *            \"dataType\": \"json\",\n\t\t *            \"success\": function (json) {\n\t\t *              o = json;\n\t\t *            }\n\t\t *          } );\n\t\t *\n\t\t *          return o;\n\t\t *        }\n\t\t *      } );\n\t\t *    } );\n\t\t */\n\t\t\"fnStateLoadCallback\": function ( settings ) {\n\t\t\ttry {\n\t\t\t\treturn JSON.parse(\n\t\t\t\t\t(settings.iStateDuration === -1 ? sessionStorage : localStorage).getItem(\n\t\t\t\t\t\t'DataTables_'+settings.sInstance+'_'+location.pathname\n\t\t\t\t\t)\n\t\t\t\t);\n\t\t\t} catch (e) {}\n\t\t},\n\t\n\t\n\t\t/**\n\t\t * Callback which allows modification of the saved state prior to loading that state.\n\t\t * This callback is called when the table is loading state from the stored data, but\n\t\t * prior to the settings object being modified by the saved state. Note that for\n\t\t * plug-in authors, you should use the `stateLoadParams` event to load parameters for\n\t\t * a plug-in.\n\t\t *  @type function\n\t\t *  @param {object} settings DataTables settings object\n\t\t *  @param {object} data The state object that is to be loaded\n\t\t *\n\t\t *  @dtopt Callbacks\n\t\t *  @name DataTable.defaults.stateLoadParams\n\t\t *\n\t\t *  @example\n\t\t *    // Remove a saved filter, so filtering is never loaded\n\t\t *    $(document).ready( function() {\n\t\t *      $('#example').dataTable( {\n\t\t *        \"stateSave\": true,\n\t\t *        \"stateLoadParams\": function (settings, data) {\n\t\t *          data.oSearch.sSearch = \"\";\n\t\t *        }\n\t\t *      } );\n\t\t *    } );\n\t\t *\n\t\t *  @example\n\t\t *    // Disallow state loading by returning false\n\t\t *    $(document).ready( function() {\n\t\t *      $('#example').dataTable( {\n\t\t *        \"stateSave\": true,\n\t\t *        \"stateLoadParams\": function (settings, data) {\n\t\t *          return false;\n\t\t *        }\n\t\t *      } );\n\t\t *    } );\n\t\t */\n\t\t\"fnStateLoadParams\": null,\n\t\n\t\n\t\t/**\n\t\t * Callback that is called when the state has been loaded from the state saving method\n\t\t * and the DataTables settings object has been modified as a result of the loaded state.\n\t\t *  @type function\n\t\t *  @param {object} settings DataTables settings object\n\t\t *  @param {object} data The state object that was loaded\n\t\t *\n\t\t *  @dtopt Callbacks\n\t\t *  @name DataTable.defaults.stateLoaded\n\t\t *\n\t\t *  @example\n\t\t *    // Show an alert with the filtering value that was saved\n\t\t *    $(document).ready( function() {\n\t\t *      $('#example').dataTable( {\n\t\t *        \"stateSave\": true,\n\t\t *        \"stateLoaded\": function (settings, data) {\n\t\t *          alert( 'Saved filter was: '+data.oSearch.sSearch );\n\t\t *        }\n\t\t *      } );\n\t\t *    } );\n\t\t */\n\t\t\"fnStateLoaded\": null,\n\t\n\t\n\t\t/**\n\t\t * Save the table state. This function allows you to define where and how the state\n\t\t * information for the table is stored By default DataTables will use `localStorage`\n\t\t * but you might wish to use a server-side database or cookies.\n\t\t *  @type function\n\t\t *  @member\n\t\t *  @param {object} settings DataTables settings object\n\t\t *  @param {object} data The state object to be saved\n\t\t *\n\t\t *  @dtopt Callbacks\n\t\t *  @name DataTable.defaults.stateSaveCallback\n\t\t *\n\t\t *  @example\n\t\t *    $(document).ready( function() {\n\t\t *      $('#example').dataTable( {\n\t\t *        \"stateSave\": true,\n\t\t *        \"stateSaveCallback\": function (settings, data) {\n\t\t *          // Send an Ajax request to the server with the state object\n\t\t *          $.ajax( {\n\t\t *            \"url\": \"/state_save\",\n\t\t *            \"data\": data,\n\t\t *            \"dataType\": \"json\",\n\t\t *            \"method\": \"POST\"\n\t\t *            \"success\": function () {}\n\t\t *          } );\n\t\t *        }\n\t\t *      } );\n\t\t *    } );\n\t\t */\n\t\t\"fnStateSaveCallback\": function ( settings, data ) {\n\t\t\ttry {\n\t\t\t\t(settings.iStateDuration === -1 ? sessionStorage : localStorage).setItem(\n\t\t\t\t\t'DataTables_'+settings.sInstance+'_'+location.pathname,\n\t\t\t\t\tJSON.stringify( data )\n\t\t\t\t);\n\t\t\t} catch (e) {}\n\t\t},\n\t\n\t\n\t\t/**\n\t\t * Callback which allows modification of the state to be saved. Called when the table\n\t\t * has changed state a new state save is required. This method allows modification of\n\t\t * the state saving object prior to actually doing the save, including addition or\n\t\t * other state properties or modification. Note that for plug-in authors, you should\n\t\t * use the `stateSaveParams` event to save parameters for a plug-in.\n\t\t *  @type function\n\t\t *  @param {object} settings DataTables settings object\n\t\t *  @param {object} data The state object to be saved\n\t\t *\n\t\t *  @dtopt Callbacks\n\t\t *  @name DataTable.defaults.stateSaveParams\n\t\t *\n\t\t *  @example\n\t\t *    // Remove a saved filter, so filtering is never saved\n\t\t *    $(document).ready( function() {\n\t\t *      $('#example').dataTable( {\n\t\t *        \"stateSave\": true,\n\t\t *        \"stateSaveParams\": function (settings, data) {\n\t\t *          data.oSearch.sSearch = \"\";\n\t\t *        }\n\t\t *      } );\n\t\t *    } );\n\t\t */\n\t\t\"fnStateSaveParams\": null,\n\t\n\t\n\t\t/**\n\t\t * Duration for which the saved state information is considered valid. After this period\n\t\t * has elapsed the state will be returned to the default.\n\t\t * Value is given in seconds.\n\t\t *  @type int\n\t\t *  @default 7200 <i>(2 hours)</i>\n\t\t *\n\t\t *  @dtopt Options\n\t\t *  @name DataTable.defaults.stateDuration\n\t\t *\n\t\t *  @example\n\t\t *    $(document).ready( function() {\n\t\t *      $('#example').dataTable( {\n\t\t *        \"stateDuration\": 60*60*24; // 1 day\n\t\t *      } );\n\t\t *    } )\n\t\t */\n\t\t\"iStateDuration\": 7200,\n\t\n\t\n\t\t/**\n\t\t * When enabled DataTables will not make a request to the server for the first\n\t\t * page draw - rather it will use the data already on the page (no sorting etc\n\t\t * will be applied to it), thus saving on an XHR at load time. `deferLoading`\n\t\t * is used to indicate that deferred loading is required, but it is also used\n\t\t * to tell DataTables how many records there are in the full table (allowing\n\t\t * the information element and pagination to be displayed correctly). In the case\n\t\t * where a filtering is applied to the table on initial load, this can be\n\t\t * indicated by giving the parameter as an array, where the first element is\n\t\t * the number of records available after filtering and the second element is the\n\t\t * number of records without filtering (allowing the table information element\n\t\t * to be shown correctly).\n\t\t *  @type int | array\n\t\t *  @default null\n\t\t *\n\t\t *  @dtopt Options\n\t\t *  @name DataTable.defaults.deferLoading\n\t\t *\n\t\t *  @example\n\t\t *    // 57 records available in the table, no filtering applied\n\t\t *    $(document).ready( function() {\n\t\t *      $('#example').dataTable( {\n\t\t *        \"serverSide\": true,\n\t\t *        \"ajax\": \"scripts/server_processing.php\",\n\t\t *        \"deferLoading\": 57\n\t\t *      } );\n\t\t *    } );\n\t\t *\n\t\t *  @example\n\t\t *    // 57 records after filtering, 100 without filtering (an initial filter applied)\n\t\t *    $(document).ready( function() {\n\t\t *      $('#example').dataTable( {\n\t\t *        \"serverSide\": true,\n\t\t *        \"ajax\": \"scripts/server_processing.php\",\n\t\t *        \"deferLoading\": [ 57, 100 ],\n\t\t *        \"search\": {\n\t\t *          \"search\": \"my_filter\"\n\t\t *        }\n\t\t *      } );\n\t\t *    } );\n\t\t */\n\t\t\"iDeferLoading\": null,\n\t\n\t\n\t\t/**\n\t\t * Number of rows to display on a single page when using pagination. If\n\t\t * feature enabled (`lengthChange`) then the end user will be able to override\n\t\t * this to a custom setting using a pop-up menu.\n\t\t *  @type int\n\t\t *  @default 10\n\t\t *\n\t\t *  @dtopt Options\n\t\t *  @name DataTable.defaults.pageLength\n\t\t *\n\t\t *  @example\n\t\t *    $(document).ready( function() {\n\t\t *      $('#example').dataTable( {\n\t\t *        \"pageLength\": 50\n\t\t *      } );\n\t\t *    } )\n\t\t */\n\t\t\"iDisplayLength\": 10,\n\t\n\t\n\t\t/**\n\t\t * Define the starting point for data display when using DataTables with\n\t\t * pagination. Note that this parameter is the number of records, rather than\n\t\t * the page number, so if you have 10 records per page and want to start on\n\t\t * the third page, it should be \"20\".\n\t\t *  @type int\n\t\t *  @default 0\n\t\t *\n\t\t *  @dtopt Options\n\t\t *  @name DataTable.defaults.displayStart\n\t\t *\n\t\t *  @example\n\t\t *    $(document).ready( function() {\n\t\t *      $('#example').dataTable( {\n\t\t *        \"displayStart\": 20\n\t\t *      } );\n\t\t *    } )\n\t\t */\n\t\t\"iDisplayStart\": 0,\n\t\n\t\n\t\t/**\n\t\t * By default DataTables allows keyboard navigation of the table (sorting, paging,\n\t\t * and filtering) by adding a `tabindex` attribute to the required elements. This\n\t\t * allows you to tab through the controls and press the enter key to activate them.\n\t\t * The tabindex is default 0, meaning that the tab follows the flow of the document.\n\t\t * You can overrule this using this parameter if you wish. Use a value of -1 to\n\t\t * disable built-in keyboard navigation.\n\t\t *  @type int\n\t\t *  @default 0\n\t\t *\n\t\t *  @dtopt Options\n\t\t *  @name DataTable.defaults.tabIndex\n\t\t *\n\t\t *  @example\n\t\t *    $(document).ready( function() {\n\t\t *      $('#example').dataTable( {\n\t\t *        \"tabIndex\": 1\n\t\t *      } );\n\t\t *    } );\n\t\t */\n\t\t\"iTabIndex\": 0,\n\t\n\t\n\t\t/**\n\t\t * Classes that DataTables assigns to the various components and features\n\t\t * that it adds to the HTML table. This allows classes to be configured\n\t\t * during initialisation in addition to through the static\n\t\t * {@link DataTable.ext.oStdClasses} object).\n\t\t *  @namespace\n\t\t *  @name DataTable.defaults.classes\n\t\t */\n\t\t\"oClasses\": {},\n\t\n\t\n\t\t/**\n\t\t * All strings that DataTables uses in the user interface that it creates\n\t\t * are defined in this object, allowing you to modified them individually or\n\t\t * completely replace them all as required.\n\t\t *  @namespace\n\t\t *  @name DataTable.defaults.language\n\t\t */\n\t\t\"oLanguage\": {\n\t\t\t/**\n\t\t\t * Strings that are used for WAI-ARIA labels and controls only (these are not\n\t\t\t * actually visible on the page, but will be read by screenreaders, and thus\n\t\t\t * must be internationalised as well).\n\t\t\t *  @namespace\n\t\t\t *  @name DataTable.defaults.language.aria\n\t\t\t */\n\t\t\t\"oAria\": {\n\t\t\t\t/**\n\t\t\t\t * ARIA label that is added to the table headers when the column may be\n\t\t\t\t * sorted ascending by activing the column (click or return when focused).\n\t\t\t\t * Note that the column header is prefixed to this string.\n\t\t\t\t *  @type string\n\t\t\t\t *  @default : activate to sort column ascending\n\t\t\t\t *\n\t\t\t\t *  @dtopt Language\n\t\t\t\t *  @name DataTable.defaults.language.aria.sortAscending\n\t\t\t\t *\n\t\t\t\t *  @example\n\t\t\t\t *    $(document).ready( function() {\n\t\t\t\t *      $('#example').dataTable( {\n\t\t\t\t *        \"language\": {\n\t\t\t\t *          \"aria\": {\n\t\t\t\t *            \"sortAscending\": \" - click/return to sort ascending\"\n\t\t\t\t *          }\n\t\t\t\t *        }\n\t\t\t\t *      } );\n\t\t\t\t *    } );\n\t\t\t\t */\n\t\t\t\t\"sSortAscending\": \": activate to sort column ascending\",\n\t\n\t\t\t\t/**\n\t\t\t\t * ARIA label that is added to the table headers when the column may be\n\t\t\t\t * sorted descending by activing the column (click or return when focused).\n\t\t\t\t * Note that the column header is prefixed to this string.\n\t\t\t\t *  @type string\n\t\t\t\t *  @default : activate to sort column ascending\n\t\t\t\t *\n\t\t\t\t *  @dtopt Language\n\t\t\t\t *  @name DataTable.defaults.language.aria.sortDescending\n\t\t\t\t *\n\t\t\t\t *  @example\n\t\t\t\t *    $(document).ready( function() {\n\t\t\t\t *      $('#example').dataTable( {\n\t\t\t\t *        \"language\": {\n\t\t\t\t *          \"aria\": {\n\t\t\t\t *            \"sortDescending\": \" - click/return to sort descending\"\n\t\t\t\t *          }\n\t\t\t\t *        }\n\t\t\t\t *      } );\n\t\t\t\t *    } );\n\t\t\t\t */\n\t\t\t\t\"sSortDescending\": \": activate to sort column descending\"\n\t\t\t},\n\t\n\t\t\t/**\n\t\t\t * Pagination string used by DataTables for the built-in pagination\n\t\t\t * control types.\n\t\t\t *  @namespace\n\t\t\t *  @name DataTable.defaults.language.paginate\n\t\t\t */\n\t\t\t\"oPaginate\": {\n\t\t\t\t/**\n\t\t\t\t * Text to use when using the 'full_numbers' type of pagination for the\n\t\t\t\t * button to take the user to the first page.\n\t\t\t\t *  @type string\n\t\t\t\t *  @default First\n\t\t\t\t *\n\t\t\t\t *  @dtopt Language\n\t\t\t\t *  @name DataTable.defaults.language.paginate.first\n\t\t\t\t *\n\t\t\t\t *  @example\n\t\t\t\t *    $(document).ready( function() {\n\t\t\t\t *      $('#example').dataTable( {\n\t\t\t\t *        \"language\": {\n\t\t\t\t *          \"paginate\": {\n\t\t\t\t *            \"first\": \"First page\"\n\t\t\t\t *          }\n\t\t\t\t *        }\n\t\t\t\t *      } );\n\t\t\t\t *    } );\n\t\t\t\t */\n\t\t\t\t\"sFirst\": \"First\",\n\t\n\t\n\t\t\t\t/**\n\t\t\t\t * Text to use when using the 'full_numbers' type of pagination for the\n\t\t\t\t * button to take the user to the last page.\n\t\t\t\t *  @type string\n\t\t\t\t *  @default Last\n\t\t\t\t *\n\t\t\t\t *  @dtopt Language\n\t\t\t\t *  @name DataTable.defaults.language.paginate.last\n\t\t\t\t *\n\t\t\t\t *  @example\n\t\t\t\t *    $(document).ready( function() {\n\t\t\t\t *      $('#example').dataTable( {\n\t\t\t\t *        \"language\": {\n\t\t\t\t *          \"paginate\": {\n\t\t\t\t *            \"last\": \"Last page\"\n\t\t\t\t *          }\n\t\t\t\t *        }\n\t\t\t\t *      } );\n\t\t\t\t *    } );\n\t\t\t\t */\n\t\t\t\t\"sLast\": \"Last\",\n\t\n\t\n\t\t\t\t/**\n\t\t\t\t * Text to use for the 'next' pagination button (to take the user to the\n\t\t\t\t * next page).\n\t\t\t\t *  @type string\n\t\t\t\t *  @default Next\n\t\t\t\t *\n\t\t\t\t *  @dtopt Language\n\t\t\t\t *  @name DataTable.defaults.language.paginate.next\n\t\t\t\t *\n\t\t\t\t *  @example\n\t\t\t\t *    $(document).ready( function() {\n\t\t\t\t *      $('#example').dataTable( {\n\t\t\t\t *        \"language\": {\n\t\t\t\t *          \"paginate\": {\n\t\t\t\t *            \"next\": \"Next page\"\n\t\t\t\t *          }\n\t\t\t\t *        }\n\t\t\t\t *      } );\n\t\t\t\t *    } );\n\t\t\t\t */\n\t\t\t\t\"sNext\": \"Next\",\n\t\n\t\n\t\t\t\t/**\n\t\t\t\t * Text to use for the 'previous' pagination button (to take the user to\n\t\t\t\t * the previous page).\n\t\t\t\t *  @type string\n\t\t\t\t *  @default Previous\n\t\t\t\t *\n\t\t\t\t *  @dtopt Language\n\t\t\t\t *  @name DataTable.defaults.language.paginate.previous\n\t\t\t\t *\n\t\t\t\t *  @example\n\t\t\t\t *    $(document).ready( function() {\n\t\t\t\t *      $('#example').dataTable( {\n\t\t\t\t *        \"language\": {\n\t\t\t\t *          \"paginate\": {\n\t\t\t\t *            \"previous\": \"Previous page\"\n\t\t\t\t *          }\n\t\t\t\t *        }\n\t\t\t\t *      } );\n\t\t\t\t *    } );\n\t\t\t\t */\n\t\t\t\t\"sPrevious\": \"Previous\"\n\t\t\t},\n\t\n\t\t\t/**\n\t\t\t * This string is shown in preference to `zeroRecords` when the table is\n\t\t\t * empty of data (regardless of filtering). Note that this is an optional\n\t\t\t * parameter - if it is not given, the value of `zeroRecords` will be used\n\t\t\t * instead (either the default or given value).\n\t\t\t *  @type string\n\t\t\t *  @default No data available in table\n\t\t\t *\n\t\t\t *  @dtopt Language\n\t\t\t *  @name DataTable.defaults.language.emptyTable\n\t\t\t *\n\t\t\t *  @example\n\t\t\t *    $(document).ready( function() {\n\t\t\t *      $('#example').dataTable( {\n\t\t\t *        \"language\": {\n\t\t\t *          \"emptyTable\": \"No data available in table\"\n\t\t\t *        }\n\t\t\t *      } );\n\t\t\t *    } );\n\t\t\t */\n\t\t\t\"sEmptyTable\": \"No data available in table\",\n\t\n\t\n\t\t\t/**\n\t\t\t * This string gives information to the end user about the information\n\t\t\t * that is current on display on the page. The following tokens can be\n\t\t\t * used in the string and will be dynamically replaced as the table\n\t\t\t * display updates. This tokens can be placed anywhere in the string, or\n\t\t\t * removed as needed by the language requires:\n\t\t\t *\n\t\t\t * * `\\_START\\_` - Display index of the first record on the current page\n\t\t\t * * `\\_END\\_` - Display index of the last record on the current page\n\t\t\t * * `\\_TOTAL\\_` - Number of records in the table after filtering\n\t\t\t * * `\\_MAX\\_` - Number of records in the table without filtering\n\t\t\t * * `\\_PAGE\\_` - Current page number\n\t\t\t * * `\\_PAGES\\_` - Total number of pages of data in the table\n\t\t\t *\n\t\t\t *  @type string\n\t\t\t *  @default Showing _START_ to _END_ of _TOTAL_ entries\n\t\t\t *\n\t\t\t *  @dtopt Language\n\t\t\t *  @name DataTable.defaults.language.info\n\t\t\t *\n\t\t\t *  @example\n\t\t\t *    $(document).ready( function() {\n\t\t\t *      $('#example').dataTable( {\n\t\t\t *        \"language\": {\n\t\t\t *          \"info\": \"Showing page _PAGE_ of _PAGES_\"\n\t\t\t *        }\n\t\t\t *      } );\n\t\t\t *    } );\n\t\t\t */\n\t\t\t\"sInfo\": \"Showing _START_ to _END_ of _TOTAL_ entries\",\n\t\n\t\n\t\t\t/**\n\t\t\t * Display information string for when the table is empty. Typically the\n\t\t\t * format of this string should match `info`.\n\t\t\t *  @type string\n\t\t\t *  @default Showing 0 to 0 of 0 entries\n\t\t\t *\n\t\t\t *  @dtopt Language\n\t\t\t *  @name DataTable.defaults.language.infoEmpty\n\t\t\t *\n\t\t\t *  @example\n\t\t\t *    $(document).ready( function() {\n\t\t\t *      $('#example').dataTable( {\n\t\t\t *        \"language\": {\n\t\t\t *          \"infoEmpty\": \"No entries to show\"\n\t\t\t *        }\n\t\t\t *      } );\n\t\t\t *    } );\n\t\t\t */\n\t\t\t\"sInfoEmpty\": \"Showing 0 to 0 of 0 entries\",\n\t\n\t\n\t\t\t/**\n\t\t\t * When a user filters the information in a table, this string is appended\n\t\t\t * to the information (`info`) to give an idea of how strong the filtering\n\t\t\t * is. The variable _MAX_ is dynamically updated.\n\t\t\t *  @type string\n\t\t\t *  @default (filtered from _MAX_ total entries)\n\t\t\t *\n\t\t\t *  @dtopt Language\n\t\t\t *  @name DataTable.defaults.language.infoFiltered\n\t\t\t *\n\t\t\t *  @example\n\t\t\t *    $(document).ready( function() {\n\t\t\t *      $('#example').dataTable( {\n\t\t\t *        \"language\": {\n\t\t\t *          \"infoFiltered\": \" - filtering from _MAX_ records\"\n\t\t\t *        }\n\t\t\t *      } );\n\t\t\t *    } );\n\t\t\t */\n\t\t\t\"sInfoFiltered\": \"(filtered from _MAX_ total entries)\",\n\t\n\t\n\t\t\t/**\n\t\t\t * If can be useful to append extra information to the info string at times,\n\t\t\t * and this variable does exactly that. This information will be appended to\n\t\t\t * the `info` (`infoEmpty` and `infoFiltered` in whatever combination they are\n\t\t\t * being used) at all times.\n\t\t\t *  @type string\n\t\t\t *  @default <i>Empty string</i>\n\t\t\t *\n\t\t\t *  @dtopt Language\n\t\t\t *  @name DataTable.defaults.language.infoPostFix\n\t\t\t *\n\t\t\t *  @example\n\t\t\t *    $(document).ready( function() {\n\t\t\t *      $('#example').dataTable( {\n\t\t\t *        \"language\": {\n\t\t\t *          \"infoPostFix\": \"All records shown are derived from real information.\"\n\t\t\t *        }\n\t\t\t *      } );\n\t\t\t *    } );\n\t\t\t */\n\t\t\t\"sInfoPostFix\": \"\",\n\t\n\t\n\t\t\t/**\n\t\t\t * This decimal place operator is a little different from the other\n\t\t\t * language options since DataTables doesn't output floating point\n\t\t\t * numbers, so it won't ever use this for display of a number. Rather,\n\t\t\t * what this parameter does is modify the sort methods of the table so\n\t\t\t * that numbers which are in a format which has a character other than\n\t\t\t * a period (`.`) as a decimal place will be sorted numerically.\n\t\t\t *\n\t\t\t * Note that numbers with different decimal places cannot be shown in\n\t\t\t * the same table and still be sortable, the table must be consistent.\n\t\t\t * However, multiple different tables on the page can use different\n\t\t\t * decimal place characters.\n\t\t\t *  @type string\n\t\t\t *  @default \n\t\t\t *\n\t\t\t *  @dtopt Language\n\t\t\t *  @name DataTable.defaults.language.decimal\n\t\t\t *\n\t\t\t *  @example\n\t\t\t *    $(document).ready( function() {\n\t\t\t *      $('#example').dataTable( {\n\t\t\t *        \"language\": {\n\t\t\t *          \"decimal\": \",\"\n\t\t\t *          \"thousands\": \".\"\n\t\t\t *        }\n\t\t\t *      } );\n\t\t\t *    } );\n\t\t\t */\n\t\t\t\"sDecimal\": \"\",\n\t\n\t\n\t\t\t/**\n\t\t\t * DataTables has a build in number formatter (`formatNumber`) which is\n\t\t\t * used to format large numbers that are used in the table information.\n\t\t\t * By default a comma is used, but this can be trivially changed to any\n\t\t\t * character you wish with this parameter.\n\t\t\t *  @type string\n\t\t\t *  @default ,\n\t\t\t *\n\t\t\t *  @dtopt Language\n\t\t\t *  @name DataTable.defaults.language.thousands\n\t\t\t *\n\t\t\t *  @example\n\t\t\t *    $(document).ready( function() {\n\t\t\t *      $('#example').dataTable( {\n\t\t\t *        \"language\": {\n\t\t\t *          \"thousands\": \"'\"\n\t\t\t *        }\n\t\t\t *      } );\n\t\t\t *    } );\n\t\t\t */\n\t\t\t\"sThousands\": \",\",\n\t\n\t\n\t\t\t/**\n\t\t\t * Detail the action that will be taken when the drop down menu for the\n\t\t\t * pagination length option is changed. The '_MENU_' variable is replaced\n\t\t\t * with a default select list of 10, 25, 50 and 100, and can be replaced\n\t\t\t * with a custom select box if required.\n\t\t\t *  @type string\n\t\t\t *  @default Show _MENU_ entries\n\t\t\t *\n\t\t\t *  @dtopt Language\n\t\t\t *  @name DataTable.defaults.language.lengthMenu\n\t\t\t *\n\t\t\t *  @example\n\t\t\t *    // Language change only\n\t\t\t *    $(document).ready( function() {\n\t\t\t *      $('#example').dataTable( {\n\t\t\t *        \"language\": {\n\t\t\t *          \"lengthMenu\": \"Display _MENU_ records\"\n\t\t\t *        }\n\t\t\t *      } );\n\t\t\t *    } );\n\t\t\t *\n\t\t\t *  @example\n\t\t\t *    // Language and options change\n\t\t\t *    $(document).ready( function() {\n\t\t\t *      $('#example').dataTable( {\n\t\t\t *        \"language\": {\n\t\t\t *          \"lengthMenu\": 'Display <select>'+\n\t\t\t *            '<option value=\"10\">10</option>'+\n\t\t\t *            '<option value=\"20\">20</option>'+\n\t\t\t *            '<option value=\"30\">30</option>'+\n\t\t\t *            '<option value=\"40\">40</option>'+\n\t\t\t *            '<option value=\"50\">50</option>'+\n\t\t\t *            '<option value=\"-1\">All</option>'+\n\t\t\t *            '</select> records'\n\t\t\t *        }\n\t\t\t *      } );\n\t\t\t *    } );\n\t\t\t */\n\t\t\t\"sLengthMenu\": \"Show _MENU_ entries\",\n\t\n\t\n\t\t\t/**\n\t\t\t * When using Ajax sourced data and during the first draw when DataTables is\n\t\t\t * gathering the data, this message is shown in an empty row in the table to\n\t\t\t * indicate to the end user the the data is being loaded. Note that this\n\t\t\t * parameter is not used when loading data by server-side processing, just\n\t\t\t * Ajax sourced data with client-side processing.\n\t\t\t *  @type string\n\t\t\t *  @default Loading...\n\t\t\t *\n\t\t\t *  @dtopt Language\n\t\t\t *  @name DataTable.defaults.language.loadingRecords\n\t\t\t *\n\t\t\t *  @example\n\t\t\t *    $(document).ready( function() {\n\t\t\t *      $('#example').dataTable( {\n\t\t\t *        \"language\": {\n\t\t\t *          \"loadingRecords\": \"Please wait - loading...\"\n\t\t\t *        }\n\t\t\t *      } );\n\t\t\t *    } );\n\t\t\t */\n\t\t\t\"sLoadingRecords\": \"Loading...\",\n\t\n\t\n\t\t\t/**\n\t\t\t * Text which is displayed when the table is processing a user action\n\t\t\t * (usually a sort command or similar).\n\t\t\t *  @type string\n\t\t\t *  @default Processing...\n\t\t\t *\n\t\t\t *  @dtopt Language\n\t\t\t *  @name DataTable.defaults.language.processing\n\t\t\t *\n\t\t\t *  @example\n\t\t\t *    $(document).ready( function() {\n\t\t\t *      $('#example').dataTable( {\n\t\t\t *        \"language\": {\n\t\t\t *          \"processing\": \"DataTables is currently busy\"\n\t\t\t *        }\n\t\t\t *      } );\n\t\t\t *    } );\n\t\t\t */\n\t\t\t\"sProcessing\": \"Processing...\",\n\t\n\t\n\t\t\t/**\n\t\t\t * Details the actions that will be taken when the user types into the\n\t\t\t * filtering input text box. The variable \"_INPUT_\", if used in the string,\n\t\t\t * is replaced with the HTML text box for the filtering input allowing\n\t\t\t * control over where it appears in the string. If \"_INPUT_\" is not given\n\t\t\t * then the input box is appended to the string automatically.\n\t\t\t *  @type string\n\t\t\t *  @default Search:\n\t\t\t *\n\t\t\t *  @dtopt Language\n\t\t\t *  @name DataTable.defaults.language.search\n\t\t\t *\n\t\t\t *  @example\n\t\t\t *    // Input text box will be appended at the end automatically\n\t\t\t *    $(document).ready( function() {\n\t\t\t *      $('#example').dataTable( {\n\t\t\t *        \"language\": {\n\t\t\t *          \"search\": \"Filter records:\"\n\t\t\t *        }\n\t\t\t *      } );\n\t\t\t *    } );\n\t\t\t *\n\t\t\t *  @example\n\t\t\t *    // Specify where the filter should appear\n\t\t\t *    $(document).ready( function() {\n\t\t\t *      $('#example').dataTable( {\n\t\t\t *        \"language\": {\n\t\t\t *          \"search\": \"Apply filter _INPUT_ to table\"\n\t\t\t *        }\n\t\t\t *      } );\n\t\t\t *    } );\n\t\t\t */\n\t\t\t\"sSearch\": \"Search:\",\n\t\n\t\n\t\t\t/**\n\t\t\t * Assign a `placeholder` attribute to the search `input` element\n\t\t\t *  @type string\n\t\t\t *  @default \n\t\t\t *\n\t\t\t *  @dtopt Language\n\t\t\t *  @name DataTable.defaults.language.searchPlaceholder\n\t\t\t */\n\t\t\t\"sSearchPlaceholder\": \"\",\n\t\n\t\n\t\t\t/**\n\t\t\t * All of the language information can be stored in a file on the\n\t\t\t * server-side, which DataTables will look up if this parameter is passed.\n\t\t\t * It must store the URL of the language file, which is in a JSON format,\n\t\t\t * and the object has the same properties as the oLanguage object in the\n\t\t\t * initialiser object (i.e. the above parameters). Please refer to one of\n\t\t\t * the example language files to see how this works in action.\n\t\t\t *  @type string\n\t\t\t *  @default <i>Empty string - i.e. disabled</i>\n\t\t\t *\n\t\t\t *  @dtopt Language\n\t\t\t *  @name DataTable.defaults.language.url\n\t\t\t *\n\t\t\t *  @example\n\t\t\t *    $(document).ready( function() {\n\t\t\t *      $('#example').dataTable( {\n\t\t\t *        \"language\": {\n\t\t\t *          \"url\": \"http://www.sprymedia.co.uk/dataTables/lang.txt\"\n\t\t\t *        }\n\t\t\t *      } );\n\t\t\t *    } );\n\t\t\t */\n\t\t\t\"sUrl\": \"\",\n\t\n\t\n\t\t\t/**\n\t\t\t * Text shown inside the table records when the is no information to be\n\t\t\t * displayed after filtering. `emptyTable` is shown when there is simply no\n\t\t\t * information in the table at all (regardless of filtering).\n\t\t\t *  @type string\n\t\t\t *  @default No matching records found\n\t\t\t *\n\t\t\t *  @dtopt Language\n\t\t\t *  @name DataTable.defaults.language.zeroRecords\n\t\t\t *\n\t\t\t *  @example\n\t\t\t *    $(document).ready( function() {\n\t\t\t *      $('#example').dataTable( {\n\t\t\t *        \"language\": {\n\t\t\t *          \"zeroRecords\": \"No records to display\"\n\t\t\t *        }\n\t\t\t *      } );\n\t\t\t *    } );\n\t\t\t */\n\t\t\t\"sZeroRecords\": \"No matching records found\"\n\t\t},\n\t\n\t\n\t\t/**\n\t\t * This parameter allows you to have define the global filtering state at\n\t\t * initialisation time. As an object the `search` parameter must be\n\t\t * defined, but all other parameters are optional. When `regex` is true,\n\t\t * the search string will be treated as a regular expression, when false\n\t\t * (default) it will be treated as a straight string. When `smart`\n\t\t * DataTables will use it's smart filtering methods (to word match at\n\t\t * any point in the data), when false this will not be done.\n\t\t *  @namespace\n\t\t *  @extends DataTable.models.oSearch\n\t\t *\n\t\t *  @dtopt Options\n\t\t *  @name DataTable.defaults.search\n\t\t *\n\t\t *  @example\n\t\t *    $(document).ready( function() {\n\t\t *      $('#example').dataTable( {\n\t\t *        \"search\": {\"search\": \"Initial search\"}\n\t\t *      } );\n\t\t *    } )\n\t\t */\n\t\t\"oSearch\": $.extend( {}, DataTable.models.oSearch ),\n\t\n\t\n\t\t/**\n\t\t * __Deprecated__ The functionality provided by this parameter has now been\n\t\t * superseded by that provided through `ajax`, which should be used instead.\n\t\t *\n\t\t * By default DataTables will look for the property `data` (or `aaData` for\n\t\t * compatibility with DataTables 1.9-) when obtaining data from an Ajax\n\t\t * source or for server-side processing - this parameter allows that\n\t\t * property to be changed. You can use Javascript dotted object notation to\n\t\t * get a data source for multiple levels of nesting.\n\t\t *  @type string\n\t\t *  @default data\n\t\t *\n\t\t *  @dtopt Options\n\t\t *  @dtopt Server-side\n\t\t *  @name DataTable.defaults.ajaxDataProp\n\t\t *\n\t\t *  @deprecated 1.10. Please use `ajax` for this functionality now.\n\t\t */\n\t\t\"sAjaxDataProp\": \"data\",\n\t\n\t\n\t\t/**\n\t\t * __Deprecated__ The functionality provided by this parameter has now been\n\t\t * superseded by that provided through `ajax`, which should be used instead.\n\t\t *\n\t\t * You can instruct DataTables to load data from an external\n\t\t * source using this parameter (use aData if you want to pass data in you\n\t\t * already have). Simply provide a url a JSON object can be obtained from.\n\t\t *  @type string\n\t\t *  @default null\n\t\t *\n\t\t *  @dtopt Options\n\t\t *  @dtopt Server-side\n\t\t *  @name DataTable.defaults.ajaxSource\n\t\t *\n\t\t *  @deprecated 1.10. Please use `ajax` for this functionality now.\n\t\t */\n\t\t\"sAjaxSource\": null,\n\t\n\t\n\t\t/**\n\t\t * This initialisation variable allows you to specify exactly where in the\n\t\t * DOM you want DataTables to inject the various controls it adds to the page\n\t\t * (for example you might want the pagination controls at the top of the\n\t\t * table). DIV elements (with or without a custom class) can also be added to\n\t\t * aid styling. The follow syntax is used:\n\t\t *   <ul>\n\t\t *     <li>The following options are allowed:\n\t\t *       <ul>\n\t\t *         <li>'l' - Length changing</li>\n\t\t *         <li>'f' - Filtering input</li>\n\t\t *         <li>'t' - The table!</li>\n\t\t *         <li>'i' - Information</li>\n\t\t *         <li>'p' - Pagination</li>\n\t\t *         <li>'r' - pRocessing</li>\n\t\t *       </ul>\n\t\t *     </li>\n\t\t *     <li>The following constants are allowed:\n\t\t *       <ul>\n\t\t *         <li>'H' - jQueryUI theme \"header\" classes ('fg-toolbar ui-widget-header ui-corner-tl ui-corner-tr ui-helper-clearfix')</li>\n\t\t *         <li>'F' - jQueryUI theme \"footer\" classes ('fg-toolbar ui-widget-header ui-corner-bl ui-corner-br ui-helper-clearfix')</li>\n\t\t *       </ul>\n\t\t *     </li>\n\t\t *     <li>The following syntax is expected:\n\t\t *       <ul>\n\t\t *         <li>'&lt;' and '&gt;' - div elements</li>\n\t\t *         <li>'&lt;\"class\" and '&gt;' - div with a class</li>\n\t\t *         <li>'&lt;\"#id\" and '&gt;' - div with an ID</li>\n\t\t *       </ul>\n\t\t *     </li>\n\t\t *     <li>Examples:\n\t\t *       <ul>\n\t\t *         <li>'&lt;\"wrapper\"flipt&gt;'</li>\n\t\t *         <li>'&lt;lf&lt;t&gt;ip&gt;'</li>\n\t\t *       </ul>\n\t\t *     </li>\n\t\t *   </ul>\n\t\t *  @type string\n\t\t *  @default lfrtip <i>(when `jQueryUI` is false)</i> <b>or</b>\n\t\t *    <\"H\"lfr>t<\"F\"ip> <i>(when `jQueryUI` is true)</i>\n\t\t *\n\t\t *  @dtopt Options\n\t\t *  @name DataTable.defaults.dom\n\t\t *\n\t\t *  @example\n\t\t *    $(document).ready( function() {\n\t\t *      $('#example').dataTable( {\n\t\t *        \"dom\": '&lt;\"top\"i&gt;rt&lt;\"bottom\"flp&gt;&lt;\"clear\"&gt;'\n\t\t *      } );\n\t\t *    } );\n\t\t */\n\t\t\"sDom\": \"lfrtip\",\n\t\n\t\n\t\t/**\n\t\t * Search delay option. This will throttle full table searches that use the\n\t\t * DataTables provided search input element (it does not effect calls to\n\t\t * `dt-api search()`, providing a delay before the search is made.\n\t\t *  @type integer\n\t\t *  @default 0\n\t\t *\n\t\t *  @dtopt Options\n\t\t *  @name DataTable.defaults.searchDelay\n\t\t *\n\t\t *  @example\n\t\t *    $(document).ready( function() {\n\t\t *      $('#example').dataTable( {\n\t\t *        \"searchDelay\": 200\n\t\t *      } );\n\t\t *    } )\n\t\t */\n\t\t\"searchDelay\": null,\n\t\n\t\n\t\t/**\n\t\t * DataTables features four different built-in options for the buttons to\n\t\t * display for pagination control:\n\t\t *\n\t\t * * `simple` - 'Previous' and 'Next' buttons only\n\t\t * * 'simple_numbers` - 'Previous' and 'Next' buttons, plus page numbers\n\t\t * * `full` - 'First', 'Previous', 'Next' and 'Last' buttons\n\t\t * * `full_numbers` - 'First', 'Previous', 'Next' and 'Last' buttons, plus\n\t\t *   page numbers\n\t\t *  \n\t\t * Further methods can be added using {@link DataTable.ext.oPagination}.\n\t\t *  @type string\n\t\t *  @default simple_numbers\n\t\t *\n\t\t *  @dtopt Options\n\t\t *  @name DataTable.defaults.pagingType\n\t\t *\n\t\t *  @example\n\t\t *    $(document).ready( function() {\n\t\t *      $('#example').dataTable( {\n\t\t *        \"pagingType\": \"full_numbers\"\n\t\t *      } );\n\t\t *    } )\n\t\t */\n\t\t\"sPaginationType\": \"simple_numbers\",\n\t\n\t\n\t\t/**\n\t\t * Enable horizontal scrolling. When a table is too wide to fit into a\n\t\t * certain layout, or you have a large number of columns in the table, you\n\t\t * can enable x-scrolling to show the table in a viewport, which can be\n\t\t * scrolled. This property can be `true` which will allow the table to\n\t\t * scroll horizontally when needed, or any CSS unit, or a number (in which\n\t\t * case it will be treated as a pixel measurement). Setting as simply `true`\n\t\t * is recommended.\n\t\t *  @type boolean|string\n\t\t *  @default <i>blank string - i.e. disabled</i>\n\t\t *\n\t\t *  @dtopt Features\n\t\t *  @name DataTable.defaults.scrollX\n\t\t *\n\t\t *  @example\n\t\t *    $(document).ready( function() {\n\t\t *      $('#example').dataTable( {\n\t\t *        \"scrollX\": true,\n\t\t *        \"scrollCollapse\": true\n\t\t *      } );\n\t\t *    } );\n\t\t */\n\t\t\"sScrollX\": \"\",\n\t\n\t\n\t\t/**\n\t\t * This property can be used to force a DataTable to use more width than it\n\t\t * might otherwise do when x-scrolling is enabled. For example if you have a\n\t\t * table which requires to be well spaced, this parameter is useful for\n\t\t * \"over-sizing\" the table, and thus forcing scrolling. This property can by\n\t\t * any CSS unit, or a number (in which case it will be treated as a pixel\n\t\t * measurement).\n\t\t *  @type string\n\t\t *  @default <i>blank string - i.e. disabled</i>\n\t\t *\n\t\t *  @dtopt Options\n\t\t *  @name DataTable.defaults.scrollXInner\n\t\t *\n\t\t *  @example\n\t\t *    $(document).ready( function() {\n\t\t *      $('#example').dataTable( {\n\t\t *        \"scrollX\": \"100%\",\n\t\t *        \"scrollXInner\": \"110%\"\n\t\t *      } );\n\t\t *    } );\n\t\t */\n\t\t\"sScrollXInner\": \"\",\n\t\n\t\n\t\t/**\n\t\t * Enable vertical scrolling. Vertical scrolling will constrain the DataTable\n\t\t * to the given height, and enable scrolling for any data which overflows the\n\t\t * current viewport. This can be used as an alternative to paging to display\n\t\t * a lot of data in a small area (although paging and scrolling can both be\n\t\t * enabled at the same time). This property can be any CSS unit, or a number\n\t\t * (in which case it will be treated as a pixel measurement).\n\t\t *  @type string\n\t\t *  @default <i>blank string - i.e. disabled</i>\n\t\t *\n\t\t *  @dtopt Features\n\t\t *  @name DataTable.defaults.scrollY\n\t\t *\n\t\t *  @example\n\t\t *    $(document).ready( function() {\n\t\t *      $('#example').dataTable( {\n\t\t *        \"scrollY\": \"200px\",\n\t\t *        \"paginate\": false\n\t\t *      } );\n\t\t *    } );\n\t\t */\n\t\t\"sScrollY\": \"\",\n\t\n\t\n\t\t/**\n\t\t * __Deprecated__ The functionality provided by this parameter has now been\n\t\t * superseded by that provided through `ajax`, which should be used instead.\n\t\t *\n\t\t * Set the HTTP method that is used to make the Ajax call for server-side\n\t\t * processing or Ajax sourced data.\n\t\t *  @type string\n\t\t *  @default GET\n\t\t *\n\t\t *  @dtopt Options\n\t\t *  @dtopt Server-side\n\t\t *  @name DataTable.defaults.serverMethod\n\t\t *\n\t\t *  @deprecated 1.10. Please use `ajax` for this functionality now.\n\t\t */\n\t\t\"sServerMethod\": \"GET\",\n\t\n\t\n\t\t/**\n\t\t * DataTables makes use of renderers when displaying HTML elements for\n\t\t * a table. These renderers can be added or modified by plug-ins to\n\t\t * generate suitable mark-up for a site. For example the Bootstrap\n\t\t * integration plug-in for DataTables uses a paging button renderer to\n\t\t * display pagination buttons in the mark-up required by Bootstrap.\n\t\t *\n\t\t * For further information about the renderers available see\n\t\t * DataTable.ext.renderer\n\t\t *  @type string|object\n\t\t *  @default null\n\t\t *\n\t\t *  @name DataTable.defaults.renderer\n\t\t *\n\t\t */\n\t\t\"renderer\": null,\n\t\n\t\n\t\t/**\n\t\t * Set the data property name that DataTables should use to get a row's id\n\t\t * to set as the `id` property in the node.\n\t\t *  @type string\n\t\t *  @default DT_RowId\n\t\t *\n\t\t *  @name DataTable.defaults.rowId\n\t\t */\n\t\t\"rowId\": \"DT_RowId\"\n\t};\n\t\n\t_fnHungarianMap( DataTable.defaults );\n\t\n\t\n\t\n\t/*\n\t * Developer note - See note in model.defaults.js about the use of Hungarian\n\t * notation and camel case.\n\t */\n\t\n\t/**\n\t * Column options that can be given to DataTables at initialisation time.\n\t *  @namespace\n\t */\n\tDataTable.defaults.column = {\n\t\t/**\n\t\t * Define which column(s) an order will occur on for this column. This\n\t\t * allows a column's ordering to take multiple columns into account when\n\t\t * doing a sort or use the data from a different column. For example first\n\t\t * name / last name columns make sense to do a multi-column sort over the\n\t\t * two columns.\n\t\t *  @type array|int\n\t\t *  @default null <i>Takes the value of the column index automatically</i>\n\t\t *\n\t\t *  @name DataTable.defaults.column.orderData\n\t\t *  @dtopt Columns\n\t\t *\n\t\t *  @example\n\t\t *    // Using `columnDefs`\n\t\t *    $(document).ready( function() {\n\t\t *      $('#example').dataTable( {\n\t\t *        \"columnDefs\": [\n\t\t *          { \"orderData\": [ 0, 1 ], \"targets\": [ 0 ] },\n\t\t *          { \"orderData\": [ 1, 0 ], \"targets\": [ 1 ] },\n\t\t *          { \"orderData\": 2, \"targets\": [ 2 ] }\n\t\t *        ]\n\t\t *      } );\n\t\t *    } );\n\t\t *\n\t\t *  @example\n\t\t *    // Using `columns`\n\t\t *    $(document).ready( function() {\n\t\t *      $('#example').dataTable( {\n\t\t *        \"columns\": [\n\t\t *          { \"orderData\": [ 0, 1 ] },\n\t\t *          { \"orderData\": [ 1, 0 ] },\n\t\t *          { \"orderData\": 2 },\n\t\t *          null,\n\t\t *          null\n\t\t *        ]\n\t\t *      } );\n\t\t *    } );\n\t\t */\n\t\t\"aDataSort\": null,\n\t\t\"iDataSort\": -1,\n\t\n\t\n\t\t/**\n\t\t * You can control the default ordering direction, and even alter the\n\t\t * behaviour of the sort handler (i.e. only allow ascending ordering etc)\n\t\t * using this parameter.\n\t\t *  @type array\n\t\t *  @default [ 'asc', 'desc' ]\n\t\t *\n\t\t *  @name DataTable.defaults.column.orderSequence\n\t\t *  @dtopt Columns\n\t\t *\n\t\t *  @example\n\t\t *    // Using `columnDefs`\n\t\t *    $(document).ready( function() {\n\t\t *      $('#example').dataTable( {\n\t\t *        \"columnDefs\": [\n\t\t *          { \"orderSequence\": [ \"asc\" ], \"targets\": [ 1 ] },\n\t\t *          { \"orderSequence\": [ \"desc\", \"asc\", \"asc\" ], \"targets\": [ 2 ] },\n\t\t *          { \"orderSequence\": [ \"desc\" ], \"targets\": [ 3 ] }\n\t\t *        ]\n\t\t *      } );\n\t\t *    } );\n\t\t *\n\t\t *  @example\n\t\t *    // Using `columns`\n\t\t *    $(document).ready( function() {\n\t\t *      $('#example').dataTable( {\n\t\t *        \"columns\": [\n\t\t *          null,\n\t\t *          { \"orderSequence\": [ \"asc\" ] },\n\t\t *          { \"orderSequence\": [ \"desc\", \"asc\", \"asc\" ] },\n\t\t *          { \"orderSequence\": [ \"desc\" ] },\n\t\t *          null\n\t\t *        ]\n\t\t *      } );\n\t\t *    } );\n\t\t */\n\t\t\"asSorting\": [ 'asc', 'desc' ],\n\t\n\t\n\t\t/**\n\t\t * Enable or disable filtering on the data in this column.\n\t\t *  @type boolean\n\t\t *  @default true\n\t\t *\n\t\t *  @name DataTable.defaults.column.searchable\n\t\t *  @dtopt Columns\n\t\t *\n\t\t *  @example\n\t\t *    // Using `columnDefs`\n\t\t *    $(document).ready( function() {\n\t\t *      $('#example').dataTable( {\n\t\t *        \"columnDefs\": [\n\t\t *          { \"searchable\": false, \"targets\": [ 0 ] }\n\t\t *        ] } );\n\t\t *    } );\n\t\t *\n\t\t *  @example\n\t\t *    // Using `columns`\n\t\t *    $(document).ready( function() {\n\t\t *      $('#example').dataTable( {\n\t\t *        \"columns\": [\n\t\t *          { \"searchable\": false },\n\t\t *          null,\n\t\t *          null,\n\t\t *          null,\n\t\t *          null\n\t\t *        ] } );\n\t\t *    } );\n\t\t */\n\t\t\"bSearchable\": true,\n\t\n\t\n\t\t/**\n\t\t * Enable or disable ordering on this column.\n\t\t *  @type boolean\n\t\t *  @default true\n\t\t *\n\t\t *  @name DataTable.defaults.column.orderable\n\t\t *  @dtopt Columns\n\t\t *\n\t\t *  @example\n\t\t *    // Using `columnDefs`\n\t\t *    $(document).ready( function() {\n\t\t *      $('#example').dataTable( {\n\t\t *        \"columnDefs\": [\n\t\t *          { \"orderable\": false, \"targets\": [ 0 ] }\n\t\t *        ] } );\n\t\t *    } );\n\t\t *\n\t\t *  @example\n\t\t *    // Using `columns`\n\t\t *    $(document).ready( function() {\n\t\t *      $('#example').dataTable( {\n\t\t *        \"columns\": [\n\t\t *          { \"orderable\": false },\n\t\t *          null,\n\t\t *          null,\n\t\t *          null,\n\t\t *          null\n\t\t *        ] } );\n\t\t *    } );\n\t\t */\n\t\t\"bSortable\": true,\n\t\n\t\n\t\t/**\n\t\t * Enable or disable the display of this column.\n\t\t *  @type boolean\n\t\t *  @default true\n\t\t *\n\t\t *  @name DataTable.defaults.column.visible\n\t\t *  @dtopt Columns\n\t\t *\n\t\t *  @example\n\t\t *    // Using `columnDefs`\n\t\t *    $(document).ready( function() {\n\t\t *      $('#example').dataTable( {\n\t\t *        \"columnDefs\": [\n\t\t *          { \"visible\": false, \"targets\": [ 0 ] }\n\t\t *        ] } );\n\t\t *    } );\n\t\t *\n\t\t *  @example\n\t\t *    // Using `columns`\n\t\t *    $(document).ready( function() {\n\t\t *      $('#example').dataTable( {\n\t\t *        \"columns\": [\n\t\t *          { \"visible\": false },\n\t\t *          null,\n\t\t *          null,\n\t\t *          null,\n\t\t *          null\n\t\t *        ] } );\n\t\t *    } );\n\t\t */\n\t\t\"bVisible\": true,\n\t\n\t\n\t\t/**\n\t\t * Developer definable function that is called whenever a cell is created (Ajax source,\n\t\t * etc) or processed for input (DOM source). This can be used as a compliment to mRender\n\t\t * allowing you to modify the DOM element (add background colour for example) when the\n\t\t * element is available.\n\t\t *  @type function\n\t\t *  @param {element} td The TD node that has been created\n\t\t *  @param {*} cellData The Data for the cell\n\t\t *  @param {array|object} rowData The data for the whole row\n\t\t *  @param {int} row The row index for the aoData data store\n\t\t *  @param {int} col The column index for aoColumns\n\t\t *\n\t\t *  @name DataTable.defaults.column.createdCell\n\t\t *  @dtopt Columns\n\t\t *\n\t\t *  @example\n\t\t *    $(document).ready( function() {\n\t\t *      $('#example').dataTable( {\n\t\t *        \"columnDefs\": [ {\n\t\t *          \"targets\": [3],\n\t\t *          \"createdCell\": function (td, cellData, rowData, row, col) {\n\t\t *            if ( cellData == \"1.7\" ) {\n\t\t *              $(td).css('color', 'blue')\n\t\t *            }\n\t\t *          }\n\t\t *        } ]\n\t\t *      });\n\t\t *    } );\n\t\t */\n\t\t\"fnCreatedCell\": null,\n\t\n\t\n\t\t/**\n\t\t * This parameter has been replaced by `data` in DataTables to ensure naming\n\t\t * consistency. `dataProp` can still be used, as there is backwards\n\t\t * compatibility in DataTables for this option, but it is strongly\n\t\t * recommended that you use `data` in preference to `dataProp`.\n\t\t *  @name DataTable.defaults.column.dataProp\n\t\t */\n\t\n\t\n\t\t/**\n\t\t * This property can be used to read data from any data source property,\n\t\t * including deeply nested objects / properties. `data` can be given in a\n\t\t * number of different ways which effect its behaviour:\n\t\t *\n\t\t * * `integer` - treated as an array index for the data source. This is the\n\t\t *   default that DataTables uses (incrementally increased for each column).\n\t\t * * `string` - read an object property from the data source. There are\n\t\t *   three 'special' options that can be used in the string to alter how\n\t\t *   DataTables reads the data from the source object:\n\t\t *    * `.` - Dotted Javascript notation. Just as you use a `.` in\n\t\t *      Javascript to read from nested objects, so to can the options\n\t\t *      specified in `data`. For example: `browser.version` or\n\t\t *      `browser.name`. If your object parameter name contains a period, use\n\t\t *      `\\\\` to escape it - i.e. `first\\\\.name`.\n\t\t *    * `[]` - Array notation. DataTables can automatically combine data\n\t\t *      from and array source, joining the data with the characters provided\n\t\t *      between the two brackets. For example: `name[, ]` would provide a\n\t\t *      comma-space separated list from the source array. If no characters\n\t\t *      are provided between the brackets, the original array source is\n\t\t *      returned.\n\t\t *    * `()` - Function notation. Adding `()` to the end of a parameter will\n\t\t *      execute a function of the name given. For example: `browser()` for a\n\t\t *      simple function on the data source, `browser.version()` for a\n\t\t *      function in a nested property or even `browser().version` to get an\n\t\t *      object property if the function called returns an object. Note that\n\t\t *      function notation is recommended for use in `render` rather than\n\t\t *      `data` as it is much simpler to use as a renderer.\n\t\t * * `null` - use the original data source for the row rather than plucking\n\t\t *   data directly from it. This action has effects on two other\n\t\t *   initialisation options:\n\t\t *    * `defaultContent` - When null is given as the `data` option and\n\t\t *      `defaultContent` is specified for the column, the value defined by\n\t\t *      `defaultContent` will be used for the cell.\n\t\t *    * `render` - When null is used for the `data` option and the `render`\n\t\t *      option is specified for the column, the whole data source for the\n\t\t *      row is used for the renderer.\n\t\t * * `function` - the function given will be executed whenever DataTables\n\t\t *   needs to set or get the data for a cell in the column. The function\n\t\t *   takes three parameters:\n\t\t *    * Parameters:\n\t\t *      * `{array|object}` The data source for the row\n\t\t *      * `{string}` The type call data requested - this will be 'set' when\n\t\t *        setting data or 'filter', 'display', 'type', 'sort' or undefined\n\t\t *        when gathering data. Note that when `undefined` is given for the\n\t\t *        type DataTables expects to get the raw data for the object back<\n\t\t *      * `{*}` Data to set when the second parameter is 'set'.\n\t\t *    * Return:\n\t\t *      * The return value from the function is not required when 'set' is\n\t\t *        the type of call, but otherwise the return is what will be used\n\t\t *        for the data requested.\n\t\t *\n\t\t * Note that `data` is a getter and setter option. If you just require\n\t\t * formatting of data for output, you will likely want to use `render` which\n\t\t * is simply a getter and thus simpler to use.\n\t\t *\n\t\t * Note that prior to DataTables 1.9.2 `data` was called `mDataProp`. The\n\t\t * name change reflects the flexibility of this property and is consistent\n\t\t * with the naming of mRender. If 'mDataProp' is given, then it will still\n\t\t * be used by DataTables, as it automatically maps the old name to the new\n\t\t * if required.\n\t\t *\n\t\t *  @type string|int|function|null\n\t\t *  @default null <i>Use automatically calculated column index</i>\n\t\t *\n\t\t *  @name DataTable.defaults.column.data\n\t\t *  @dtopt Columns\n\t\t *\n\t\t *  @example\n\t\t *    // Read table data from objects\n\t\t *    // JSON structure for each row:\n\t\t *    //   {\n\t\t *    //      \"engine\": {value},\n\t\t *    //      \"browser\": {value},\n\t\t *    //      \"platform\": {value},\n\t\t *    //      \"version\": {value},\n\t\t *    //      \"grade\": {value}\n\t\t *    //   }\n\t\t *    $(document).ready( function() {\n\t\t *      $('#example').dataTable( {\n\t\t *        \"ajaxSource\": \"sources/objects.txt\",\n\t\t *        \"columns\": [\n\t\t *          { \"data\": \"engine\" },\n\t\t *          { \"data\": \"browser\" },\n\t\t *          { \"data\": \"platform\" },\n\t\t *          { \"data\": \"version\" },\n\t\t *          { \"data\": \"grade\" }\n\t\t *        ]\n\t\t *      } );\n\t\t *    } );\n\t\t *\n\t\t *  @example\n\t\t *    // Read information from deeply nested objects\n\t\t *    // JSON structure for each row:\n\t\t *    //   {\n\t\t *    //      \"engine\": {value},\n\t\t *    //      \"browser\": {value},\n\t\t *    //      \"platform\": {\n\t\t *    //         \"inner\": {value}\n\t\t *    //      },\n\t\t *    //      \"details\": [\n\t\t *    //         {value}, {value}\n\t\t *    //      ]\n\t\t *    //   }\n\t\t *    $(document).ready( function() {\n\t\t *      $('#example').dataTable( {\n\t\t *        \"ajaxSource\": \"sources/deep.txt\",\n\t\t *        \"columns\": [\n\t\t *          { \"data\": \"engine\" },\n\t\t *          { \"data\": \"browser\" },\n\t\t *          { \"data\": \"platform.inner\" },\n\t\t *          { \"data\": \"platform.details.0\" },\n\t\t *          { \"data\": \"platform.details.1\" }\n\t\t *        ]\n\t\t *      } );\n\t\t *    } );\n\t\t *\n\t\t *  @example\n\t\t *    // Using `data` as a function to provide different information for\n\t\t *    // sorting, filtering and display. In this case, currency (price)\n\t\t *    $(document).ready( function() {\n\t\t *      $('#example').dataTable( {\n\t\t *        \"columnDefs\": [ {\n\t\t *          \"targets\": [ 0 ],\n\t\t *          \"data\": function ( source, type, val ) {\n\t\t *            if (type === 'set') {\n\t\t *              source.price = val;\n\t\t *              // Store the computed dislay and filter values for efficiency\n\t\t *              source.price_display = val==\"\" ? \"\" : \"$\"+numberFormat(val);\n\t\t *              source.price_filter  = val==\"\" ? \"\" : \"$\"+numberFormat(val)+\" \"+val;\n\t\t *              return;\n\t\t *            }\n\t\t *            else if (type === 'display') {\n\t\t *              return source.price_display;\n\t\t *            }\n\t\t *            else if (type === 'filter') {\n\t\t *              return source.price_filter;\n\t\t *            }\n\t\t *            // 'sort', 'type' and undefined all just use the integer\n\t\t *            return source.price;\n\t\t *          }\n\t\t *        } ]\n\t\t *      } );\n\t\t *    } );\n\t\t *\n\t\t *  @example\n\t\t *    // Using default content\n\t\t *    $(document).ready( function() {\n\t\t *      $('#example').dataTable( {\n\t\t *        \"columnDefs\": [ {\n\t\t *          \"targets\": [ 0 ],\n\t\t *          \"data\": null,\n\t\t *          \"defaultContent\": \"Click to edit\"\n\t\t *        } ]\n\t\t *      } );\n\t\t *    } );\n\t\t *\n\t\t *  @example\n\t\t *    // Using array notation - outputting a list from an array\n\t\t *    $(document).ready( function() {\n\t\t *      $('#example').dataTable( {\n\t\t *        \"columnDefs\": [ {\n\t\t *          \"targets\": [ 0 ],\n\t\t *          \"data\": \"name[, ]\"\n\t\t *        } ]\n\t\t *      } );\n\t\t *    } );\n\t\t *\n\t\t */\n\t\t\"mData\": null,\n\t\n\t\n\t\t/**\n\t\t * This property is the rendering partner to `data` and it is suggested that\n\t\t * when you want to manipulate data for display (including filtering,\n\t\t * sorting etc) without altering the underlying data for the table, use this\n\t\t * property. `render` can be considered to be the the read only companion to\n\t\t * `data` which is read / write (then as such more complex). Like `data`\n\t\t * this option can be given in a number of different ways to effect its\n\t\t * behaviour:\n\t\t *\n\t\t * * `integer` - treated as an array index for the data source. This is the\n\t\t *   default that DataTables uses (incrementally increased for each column).\n\t\t * * `string` - read an object property from the data source. There are\n\t\t *   three 'special' options that can be used in the string to alter how\n\t\t *   DataTables reads the data from the source object:\n\t\t *    * `.` - Dotted Javascript notation. Just as you use a `.` in\n\t\t *      Javascript to read from nested objects, so to can the options\n\t\t *      specified in `data`. For example: `browser.version` or\n\t\t *      `browser.name`. If your object parameter name contains a period, use\n\t\t *      `\\\\` to escape it - i.e. `first\\\\.name`.\n\t\t *    * `[]` - Array notation. DataTables can automatically combine data\n\t\t *      from and array source, joining the data with the characters provided\n\t\t *      between the two brackets. For example: `name[, ]` would provide a\n\t\t *      comma-space separated list from the source array. If no characters\n\t\t *      are provided between the brackets, the original array source is\n\t\t *      returned.\n\t\t *    * `()` - Function notation. Adding `()` to the end of a parameter will\n\t\t *      execute a function of the name given. For example: `browser()` for a\n\t\t *      simple function on the data source, `browser.version()` for a\n\t\t *      function in a nested property or even `browser().version` to get an\n\t\t *      object property if the function called returns an object.\n\t\t * * `object` - use different data for the different data types requested by\n\t\t *   DataTables ('filter', 'display', 'type' or 'sort'). The property names\n\t\t *   of the object is the data type the property refers to and the value can\n\t\t *   defined using an integer, string or function using the same rules as\n\t\t *   `render` normally does. Note that an `_` option _must_ be specified.\n\t\t *   This is the default value to use if you haven't specified a value for\n\t\t *   the data type requested by DataTables.\n\t\t * * `function` - the function given will be executed whenever DataTables\n\t\t *   needs to set or get the data for a cell in the column. The function\n\t\t *   takes three parameters:\n\t\t *    * Parameters:\n\t\t *      * {array|object} The data source for the row (based on `data`)\n\t\t *      * {string} The type call data requested - this will be 'filter',\n\t\t *        'display', 'type' or 'sort'.\n\t\t *      * {array|object} The full data source for the row (not based on\n\t\t *        `data`)\n\t\t *    * Return:\n\t\t *      * The return value from the function is what will be used for the\n\t\t *        data requested.\n\t\t *\n\t\t *  @type string|int|function|object|null\n\t\t *  @default null Use the data source value.\n\t\t *\n\t\t *  @name DataTable.defaults.column.render\n\t\t *  @dtopt Columns\n\t\t *\n\t\t *  @example\n\t\t *    // Create a comma separated list from an array of objects\n\t\t *    $(document).ready( function() {\n\t\t *      $('#example').dataTable( {\n\t\t *        \"ajaxSource\": \"sources/deep.txt\",\n\t\t *        \"columns\": [\n\t\t *          { \"data\": \"engine\" },\n\t\t *          { \"data\": \"browser\" },\n\t\t *          {\n\t\t *            \"data\": \"platform\",\n\t\t *            \"render\": \"[, ].name\"\n\t\t *          }\n\t\t *        ]\n\t\t *      } );\n\t\t *    } );\n\t\t *\n\t\t *  @example\n\t\t *    // Execute a function to obtain data\n\t\t *    $(document).ready( function() {\n\t\t *      $('#example').dataTable( {\n\t\t *        \"columnDefs\": [ {\n\t\t *          \"targets\": [ 0 ],\n\t\t *          \"data\": null, // Use the full data source object for the renderer's source\n\t\t *          \"render\": \"browserName()\"\n\t\t *        } ]\n\t\t *      } );\n\t\t *    } );\n\t\t *\n\t\t *  @example\n\t\t *    // As an object, extracting different data for the different types\n\t\t *    // This would be used with a data source such as:\n\t\t *    //   { \"phone\": 5552368, \"phone_filter\": \"5552368 555-2368\", \"phone_display\": \"555-2368\" }\n\t\t *    // Here the `phone` integer is used for sorting and type detection, while `phone_filter`\n\t\t *    // (which has both forms) is used for filtering for if a user inputs either format, while\n\t\t *    // the formatted phone number is the one that is shown in the table.\n\t\t *    $(document).ready( function() {\n\t\t *      $('#example').dataTable( {\n\t\t *        \"columnDefs\": [ {\n\t\t *          \"targets\": [ 0 ],\n\t\t *          \"data\": null, // Use the full data source object for the renderer's source\n\t\t *          \"render\": {\n\t\t *            \"_\": \"phone\",\n\t\t *            \"filter\": \"phone_filter\",\n\t\t *            \"display\": \"phone_display\"\n\t\t *          }\n\t\t *        } ]\n\t\t *      } );\n\t\t *    } );\n\t\t *\n\t\t *  @example\n\t\t *    // Use as a function to create a link from the data source\n\t\t *    $(document).ready( function() {\n\t\t *      $('#example').dataTable( {\n\t\t *        \"columnDefs\": [ {\n\t\t *          \"targets\": [ 0 ],\n\t\t *          \"data\": \"download_link\",\n\t\t *          \"render\": function ( data, type, full ) {\n\t\t *            return '<a href=\"'+data+'\">Download</a>';\n\t\t *          }\n\t\t *        } ]\n\t\t *      } );\n\t\t *    } );\n\t\t */\n\t\t\"mRender\": null,\n\t\n\t\n\t\t/**\n\t\t * Change the cell type created for the column - either TD cells or TH cells. This\n\t\t * can be useful as TH cells have semantic meaning in the table body, allowing them\n\t\t * to act as a header for a row (you may wish to add scope='row' to the TH elements).\n\t\t *  @type string\n\t\t *  @default td\n\t\t *\n\t\t *  @name DataTable.defaults.column.cellType\n\t\t *  @dtopt Columns\n\t\t *\n\t\t *  @example\n\t\t *    // Make the first column use TH cells\n\t\t *    $(document).ready( function() {\n\t\t *      $('#example').dataTable( {\n\t\t *        \"columnDefs\": [ {\n\t\t *          \"targets\": [ 0 ],\n\t\t *          \"cellType\": \"th\"\n\t\t *        } ]\n\t\t *      } );\n\t\t *    } );\n\t\t */\n\t\t\"sCellType\": \"td\",\n\t\n\t\n\t\t/**\n\t\t * Class to give to each cell in this column.\n\t\t *  @type string\n\t\t *  @default <i>Empty string</i>\n\t\t *\n\t\t *  @name DataTable.defaults.column.class\n\t\t *  @dtopt Columns\n\t\t *\n\t\t *  @example\n\t\t *    // Using `columnDefs`\n\t\t *    $(document).ready( function() {\n\t\t *      $('#example').dataTable( {\n\t\t *        \"columnDefs\": [\n\t\t *          { \"class\": \"my_class\", \"targets\": [ 0 ] }\n\t\t *        ]\n\t\t *      } );\n\t\t *    } );\n\t\t *\n\t\t *  @example\n\t\t *    // Using `columns`\n\t\t *    $(document).ready( function() {\n\t\t *      $('#example').dataTable( {\n\t\t *        \"columns\": [\n\t\t *          { \"class\": \"my_class\" },\n\t\t *          null,\n\t\t *          null,\n\t\t *          null,\n\t\t *          null\n\t\t *        ]\n\t\t *      } );\n\t\t *    } );\n\t\t */\n\t\t\"sClass\": \"\",\n\t\n\t\t/**\n\t\t * When DataTables calculates the column widths to assign to each column,\n\t\t * it finds the longest string in each column and then constructs a\n\t\t * temporary table and reads the widths from that. The problem with this\n\t\t * is that \"mmm\" is much wider then \"iiii\", but the latter is a longer\n\t\t * string - thus the calculation can go wrong (doing it properly and putting\n\t\t * it into an DOM object and measuring that is horribly(!) slow). Thus as\n\t\t * a \"work around\" we provide this option. It will append its value to the\n\t\t * text that is found to be the longest string for the column - i.e. padding.\n\t\t * Generally you shouldn't need this!\n\t\t *  @type string\n\t\t *  @default <i>Empty string<i>\n\t\t *\n\t\t *  @name DataTable.defaults.column.contentPadding\n\t\t *  @dtopt Columns\n\t\t *\n\t\t *  @example\n\t\t *    // Using `columns`\n\t\t *    $(document).ready( function() {\n\t\t *      $('#example').dataTable( {\n\t\t *        \"columns\": [\n\t\t *          null,\n\t\t *          null,\n\t\t *          null,\n\t\t *          {\n\t\t *            \"contentPadding\": \"mmm\"\n\t\t *          }\n\t\t *        ]\n\t\t *      } );\n\t\t *    } );\n\t\t */\n\t\t\"sContentPadding\": \"\",\n\t\n\t\n\t\t/**\n\t\t * Allows a default value to be given for a column's data, and will be used\n\t\t * whenever a null data source is encountered (this can be because `data`\n\t\t * is set to null, or because the data source itself is null).\n\t\t *  @type string\n\t\t *  @default null\n\t\t *\n\t\t *  @name DataTable.defaults.column.defaultContent\n\t\t *  @dtopt Columns\n\t\t *\n\t\t *  @example\n\t\t *    // Using `columnDefs`\n\t\t *    $(document).ready( function() {\n\t\t *      $('#example').dataTable( {\n\t\t *        \"columnDefs\": [\n\t\t *          {\n\t\t *            \"data\": null,\n\t\t *            \"defaultContent\": \"Edit\",\n\t\t *            \"targets\": [ -1 ]\n\t\t *          }\n\t\t *        ]\n\t\t *      } );\n\t\t *    } );\n\t\t *\n\t\t *  @example\n\t\t *    // Using `columns`\n\t\t *    $(document).ready( function() {\n\t\t *      $('#example').dataTable( {\n\t\t *        \"columns\": [\n\t\t *          null,\n\t\t *          null,\n\t\t *          null,\n\t\t *          {\n\t\t *            \"data\": null,\n\t\t *            \"defaultContent\": \"Edit\"\n\t\t *          }\n\t\t *        ]\n\t\t *      } );\n\t\t *    } );\n\t\t */\n\t\t\"sDefaultContent\": null,\n\t\n\t\n\t\t/**\n\t\t * This parameter is only used in DataTables' server-side processing. It can\n\t\t * be exceptionally useful to know what columns are being displayed on the\n\t\t * client side, and to map these to database fields. When defined, the names\n\t\t * also allow DataTables to reorder information from the server if it comes\n\t\t * back in an unexpected order (i.e. if you switch your columns around on the\n\t\t * client-side, your server-side code does not also need updating).\n\t\t *  @type string\n\t\t *  @default <i>Empty string</i>\n\t\t *\n\t\t *  @name DataTable.defaults.column.name\n\t\t *  @dtopt Columns\n\t\t *\n\t\t *  @example\n\t\t *    // Using `columnDefs`\n\t\t *    $(document).ready( function() {\n\t\t *      $('#example').dataTable( {\n\t\t *        \"columnDefs\": [\n\t\t *          { \"name\": \"engine\", \"targets\": [ 0 ] },\n\t\t *          { \"name\": \"browser\", \"targets\": [ 1 ] },\n\t\t *          { \"name\": \"platform\", \"targets\": [ 2 ] },\n\t\t *          { \"name\": \"version\", \"targets\": [ 3 ] },\n\t\t *          { \"name\": \"grade\", \"targets\": [ 4 ] }\n\t\t *        ]\n\t\t *      } );\n\t\t *    } );\n\t\t *\n\t\t *  @example\n\t\t *    // Using `columns`\n\t\t *    $(document).ready( function() {\n\t\t *      $('#example').dataTable( {\n\t\t *        \"columns\": [\n\t\t *          { \"name\": \"engine\" },\n\t\t *          { \"name\": \"browser\" },\n\t\t *          { \"name\": \"platform\" },\n\t\t *          { \"name\": \"version\" },\n\t\t *          { \"name\": \"grade\" }\n\t\t *        ]\n\t\t *      } );\n\t\t *    } );\n\t\t */\n\t\t\"sName\": \"\",\n\t\n\t\n\t\t/**\n\t\t * Defines a data source type for the ordering which can be used to read\n\t\t * real-time information from the table (updating the internally cached\n\t\t * version) prior to ordering. This allows ordering to occur on user\n\t\t * editable elements such as form inputs.\n\t\t *  @type string\n\t\t *  @default std\n\t\t *\n\t\t *  @name DataTable.defaults.column.orderDataType\n\t\t *  @dtopt Columns\n\t\t *\n\t\t *  @example\n\t\t *    // Using `columnDefs`\n\t\t *    $(document).ready( function() {\n\t\t *      $('#example').dataTable( {\n\t\t *        \"columnDefs\": [\n\t\t *          { \"orderDataType\": \"dom-text\", \"targets\": [ 2, 3 ] },\n\t\t *          { \"type\": \"numeric\", \"targets\": [ 3 ] },\n\t\t *          { \"orderDataType\": \"dom-select\", \"targets\": [ 4 ] },\n\t\t *          { \"orderDataType\": \"dom-checkbox\", \"targets\": [ 5 ] }\n\t\t *        ]\n\t\t *      } );\n\t\t *    } );\n\t\t *\n\t\t *  @example\n\t\t *    // Using `columns`\n\t\t *    $(document).ready( function() {\n\t\t *      $('#example').dataTable( {\n\t\t *        \"columns\": [\n\t\t *          null,\n\t\t *          null,\n\t\t *          { \"orderDataType\": \"dom-text\" },\n\t\t *          { \"orderDataType\": \"dom-text\", \"type\": \"numeric\" },\n\t\t *          { \"orderDataType\": \"dom-select\" },\n\t\t *          { \"orderDataType\": \"dom-checkbox\" }\n\t\t *        ]\n\t\t *      } );\n\t\t *    } );\n\t\t */\n\t\t\"sSortDataType\": \"std\",\n\t\n\t\n\t\t/**\n\t\t * The title of this column.\n\t\t *  @type string\n\t\t *  @default null <i>Derived from the 'TH' value for this column in the\n\t\t *    original HTML table.</i>\n\t\t *\n\t\t *  @name DataTable.defaults.column.title\n\t\t *  @dtopt Columns\n\t\t *\n\t\t *  @example\n\t\t *    // Using `columnDefs`\n\t\t *    $(document).ready( function() {\n\t\t *      $('#example').dataTable( {\n\t\t *        \"columnDefs\": [\n\t\t *          { \"title\": \"My column title\", \"targets\": [ 0 ] }\n\t\t *        ]\n\t\t *      } );\n\t\t *    } );\n\t\t *\n\t\t *  @example\n\t\t *    // Using `columns`\n\t\t *    $(document).ready( function() {\n\t\t *      $('#example').dataTable( {\n\t\t *        \"columns\": [\n\t\t *          { \"title\": \"My column title\" },\n\t\t *          null,\n\t\t *          null,\n\t\t *          null,\n\t\t *          null\n\t\t *        ]\n\t\t *      } );\n\t\t *    } );\n\t\t */\n\t\t\"sTitle\": null,\n\t\n\t\n\t\t/**\n\t\t * The type allows you to specify how the data for this column will be\n\t\t * ordered. Four types (string, numeric, date and html (which will strip\n\t\t * HTML tags before ordering)) are currently available. Note that only date\n\t\t * formats understood by Javascript's Date() object will be accepted as type\n\t\t * date. For example: \"Mar 26, 2008 5:03 PM\". May take the values: 'string',\n\t\t * 'numeric', 'date' or 'html' (by default). Further types can be adding\n\t\t * through plug-ins.\n\t\t *  @type string\n\t\t *  @default null <i>Auto-detected from raw data</i>\n\t\t *\n\t\t *  @name DataTable.defaults.column.type\n\t\t *  @dtopt Columns\n\t\t *\n\t\t *  @example\n\t\t *    // Using `columnDefs`\n\t\t *    $(document).ready( function() {\n\t\t *      $('#example').dataTable( {\n\t\t *        \"columnDefs\": [\n\t\t *          { \"type\": \"html\", \"targets\": [ 0 ] }\n\t\t *        ]\n\t\t *      } );\n\t\t *    } );\n\t\t *\n\t\t *  @example\n\t\t *    // Using `columns`\n\t\t *    $(document).ready( function() {\n\t\t *      $('#example').dataTable( {\n\t\t *        \"columns\": [\n\t\t *          { \"type\": \"html\" },\n\t\t *          null,\n\t\t *          null,\n\t\t *          null,\n\t\t *          null\n\t\t *        ]\n\t\t *      } );\n\t\t *    } );\n\t\t */\n\t\t\"sType\": null,\n\t\n\t\n\t\t/**\n\t\t * Defining the width of the column, this parameter may take any CSS value\n\t\t * (3em, 20px etc). DataTables applies 'smart' widths to columns which have not\n\t\t * been given a specific width through this interface ensuring that the table\n\t\t * remains readable.\n\t\t *  @type string\n\t\t *  @default null <i>Automatic</i>\n\t\t *\n\t\t *  @name DataTable.defaults.column.width\n\t\t *  @dtopt Columns\n\t\t *\n\t\t *  @example\n\t\t *    // Using `columnDefs`\n\t\t *    $(document).ready( function() {\n\t\t *      $('#example').dataTable( {\n\t\t *        \"columnDefs\": [\n\t\t *          { \"width\": \"20%\", \"targets\": [ 0 ] }\n\t\t *        ]\n\t\t *      } );\n\t\t *    } );\n\t\t *\n\t\t *  @example\n\t\t *    // Using `columns`\n\t\t *    $(document).ready( function() {\n\t\t *      $('#example').dataTable( {\n\t\t *        \"columns\": [\n\t\t *          { \"width\": \"20%\" },\n\t\t *          null,\n\t\t *          null,\n\t\t *          null,\n\t\t *          null\n\t\t *        ]\n\t\t *      } );\n\t\t *    } );\n\t\t */\n\t\t\"sWidth\": null\n\t};\n\t\n\t_fnHungarianMap( DataTable.defaults.column );\n\t\n\t\n\t\n\t/**\n\t * DataTables settings object - this holds all the information needed for a\n\t * given table, including configuration, data and current application of the\n\t * table options. DataTables does not have a single instance for each DataTable\n\t * with the settings attached to that instance, but rather instances of the\n\t * DataTable \"class\" are created on-the-fly as needed (typically by a\n\t * $().dataTable() call) and the settings object is then applied to that\n\t * instance.\n\t *\n\t * Note that this object is related to {@link DataTable.defaults} but this\n\t * one is the internal data store for DataTables's cache of columns. It should\n\t * NOT be manipulated outside of DataTables. Any configuration should be done\n\t * through the initialisation options.\n\t *  @namespace\n\t *  @todo Really should attach the settings object to individual instances so we\n\t *    don't need to create new instances on each $().dataTable() call (if the\n\t *    table already exists). It would also save passing oSettings around and\n\t *    into every single function. However, this is a very significant\n\t *    architecture change for DataTables and will almost certainly break\n\t *    backwards compatibility with older installations. This is something that\n\t *    will be done in 2.0.\n\t */\n\tDataTable.models.oSettings = {\n\t\t/**\n\t\t * Primary features of DataTables and their enablement state.\n\t\t *  @namespace\n\t\t */\n\t\t\"oFeatures\": {\n\t\n\t\t\t/**\n\t\t\t * Flag to say if DataTables should automatically try to calculate the\n\t\t\t * optimum table and columns widths (true) or not (false).\n\t\t\t * Note that this parameter will be set by the initialisation routine. To\n\t\t\t * set a default use {@link DataTable.defaults}.\n\t\t\t *  @type boolean\n\t\t\t */\n\t\t\t\"bAutoWidth\": null,\n\t\n\t\t\t/**\n\t\t\t * Delay the creation of TR and TD elements until they are actually\n\t\t\t * needed by a driven page draw. This can give a significant speed\n\t\t\t * increase for Ajax source and Javascript source data, but makes no\n\t\t\t * difference at all fro DOM and server-side processing tables.\n\t\t\t * Note that this parameter will be set by the initialisation routine. To\n\t\t\t * set a default use {@link DataTable.defaults}.\n\t\t\t *  @type boolean\n\t\t\t */\n\t\t\t\"bDeferRender\": null,\n\t\n\t\t\t/**\n\t\t\t * Enable filtering on the table or not. Note that if this is disabled\n\t\t\t * then there is no filtering at all on the table, including fnFilter.\n\t\t\t * To just remove the filtering input use sDom and remove the 'f' option.\n\t\t\t * Note that this parameter will be set by the initialisation routine. To\n\t\t\t * set a default use {@link DataTable.defaults}.\n\t\t\t *  @type boolean\n\t\t\t */\n\t\t\t\"bFilter\": null,\n\t\n\t\t\t/**\n\t\t\t * Table information element (the 'Showing x of y records' div) enable\n\t\t\t * flag.\n\t\t\t * Note that this parameter will be set by the initialisation routine. To\n\t\t\t * set a default use {@link DataTable.defaults}.\n\t\t\t *  @type boolean\n\t\t\t */\n\t\t\t\"bInfo\": null,\n\t\n\t\t\t/**\n\t\t\t * Present a user control allowing the end user to change the page size\n\t\t\t * when pagination is enabled.\n\t\t\t * Note that this parameter will be set by the initialisation routine. To\n\t\t\t * set a default use {@link DataTable.defaults}.\n\t\t\t *  @type boolean\n\t\t\t */\n\t\t\t\"bLengthChange\": null,\n\t\n\t\t\t/**\n\t\t\t * Pagination enabled or not. Note that if this is disabled then length\n\t\t\t * changing must also be disabled.\n\t\t\t * Note that this parameter will be set by the initialisation routine. To\n\t\t\t * set a default use {@link DataTable.defaults}.\n\t\t\t *  @type boolean\n\t\t\t */\n\t\t\t\"bPaginate\": null,\n\t\n\t\t\t/**\n\t\t\t * Processing indicator enable flag whenever DataTables is enacting a\n\t\t\t * user request - typically an Ajax request for server-side processing.\n\t\t\t * Note that this parameter will be set by the initialisation routine. To\n\t\t\t * set a default use {@link DataTable.defaults}.\n\t\t\t *  @type boolean\n\t\t\t */\n\t\t\t\"bProcessing\": null,\n\t\n\t\t\t/**\n\t\t\t * Server-side processing enabled flag - when enabled DataTables will\n\t\t\t * get all data from the server for every draw - there is no filtering,\n\t\t\t * sorting or paging done on the client-side.\n\t\t\t * Note that this parameter will be set by the initialisation routine. To\n\t\t\t * set a default use {@link DataTable.defaults}.\n\t\t\t *  @type boolean\n\t\t\t */\n\t\t\t\"bServerSide\": null,\n\t\n\t\t\t/**\n\t\t\t * Sorting enablement flag.\n\t\t\t * Note that this parameter will be set by the initialisation routine. To\n\t\t\t * set a default use {@link DataTable.defaults}.\n\t\t\t *  @type boolean\n\t\t\t */\n\t\t\t\"bSort\": null,\n\t\n\t\t\t/**\n\t\t\t * Multi-column sorting\n\t\t\t * Note that this parameter will be set by the initialisation routine. To\n\t\t\t * set a default use {@link DataTable.defaults}.\n\t\t\t *  @type boolean\n\t\t\t */\n\t\t\t\"bSortMulti\": null,\n\t\n\t\t\t/**\n\t\t\t * Apply a class to the columns which are being sorted to provide a\n\t\t\t * visual highlight or not. This can slow things down when enabled since\n\t\t\t * there is a lot of DOM interaction.\n\t\t\t * Note that this parameter will be set by the initialisation routine. To\n\t\t\t * set a default use {@link DataTable.defaults}.\n\t\t\t *  @type boolean\n\t\t\t */\n\t\t\t\"bSortClasses\": null,\n\t\n\t\t\t/**\n\t\t\t * State saving enablement flag.\n\t\t\t * Note that this parameter will be set by the initialisation routine. To\n\t\t\t * set a default use {@link DataTable.defaults}.\n\t\t\t *  @type boolean\n\t\t\t */\n\t\t\t\"bStateSave\": null\n\t\t},\n\t\n\t\n\t\t/**\n\t\t * Scrolling settings for a table.\n\t\t *  @namespace\n\t\t */\n\t\t\"oScroll\": {\n\t\t\t/**\n\t\t\t * When the table is shorter in height than sScrollY, collapse the\n\t\t\t * table container down to the height of the table (when true).\n\t\t\t * Note that this parameter will be set by the initialisation routine. To\n\t\t\t * set a default use {@link DataTable.defaults}.\n\t\t\t *  @type boolean\n\t\t\t */\n\t\t\t\"bCollapse\": null,\n\t\n\t\t\t/**\n\t\t\t * Width of the scrollbar for the web-browser's platform. Calculated\n\t\t\t * during table initialisation.\n\t\t\t *  @type int\n\t\t\t *  @default 0\n\t\t\t */\n\t\t\t\"iBarWidth\": 0,\n\t\n\t\t\t/**\n\t\t\t * Viewport width for horizontal scrolling. Horizontal scrolling is\n\t\t\t * disabled if an empty string.\n\t\t\t * Note that this parameter will be set by the initialisation routine. To\n\t\t\t * set a default use {@link DataTable.defaults}.\n\t\t\t *  @type string\n\t\t\t */\n\t\t\t\"sX\": null,\n\t\n\t\t\t/**\n\t\t\t * Width to expand the table to when using x-scrolling. Typically you\n\t\t\t * should not need to use this.\n\t\t\t * Note that this parameter will be set by the initialisation routine. To\n\t\t\t * set a default use {@link DataTable.defaults}.\n\t\t\t *  @type string\n\t\t\t *  @deprecated\n\t\t\t */\n\t\t\t\"sXInner\": null,\n\t\n\t\t\t/**\n\t\t\t * Viewport height for vertical scrolling. Vertical scrolling is disabled\n\t\t\t * if an empty string.\n\t\t\t * Note that this parameter will be set by the initialisation routine. To\n\t\t\t * set a default use {@link DataTable.defaults}.\n\t\t\t *  @type string\n\t\t\t */\n\t\t\t\"sY\": null\n\t\t},\n\t\n\t\t/**\n\t\t * Language information for the table.\n\t\t *  @namespace\n\t\t *  @extends DataTable.defaults.oLanguage\n\t\t */\n\t\t\"oLanguage\": {\n\t\t\t/**\n\t\t\t * Information callback function. See\n\t\t\t * {@link DataTable.defaults.fnInfoCallback}\n\t\t\t *  @type function\n\t\t\t *  @default null\n\t\t\t */\n\t\t\t\"fnInfoCallback\": null\n\t\t},\n\t\n\t\t/**\n\t\t * Browser support parameters\n\t\t *  @namespace\n\t\t */\n\t\t\"oBrowser\": {\n\t\t\t/**\n\t\t\t * Indicate if the browser incorrectly calculates width:100% inside a\n\t\t\t * scrolling element (IE6/7)\n\t\t\t *  @type boolean\n\t\t\t *  @default false\n\t\t\t */\n\t\t\t\"bScrollOversize\": false,\n\t\n\t\t\t/**\n\t\t\t * Determine if the vertical scrollbar is on the right or left of the\n\t\t\t * scrolling container - needed for rtl language layout, although not\n\t\t\t * all browsers move the scrollbar (Safari).\n\t\t\t *  @type boolean\n\t\t\t *  @default false\n\t\t\t */\n\t\t\t\"bScrollbarLeft\": false,\n\t\n\t\t\t/**\n\t\t\t * Flag for if `getBoundingClientRect` is fully supported or not\n\t\t\t *  @type boolean\n\t\t\t *  @default false\n\t\t\t */\n\t\t\t\"bBounding\": false,\n\t\n\t\t\t/**\n\t\t\t * Browser scrollbar width\n\t\t\t *  @type integer\n\t\t\t *  @default 0\n\t\t\t */\n\t\t\t\"barWidth\": 0\n\t\t},\n\t\n\t\n\t\t\"ajax\": null,\n\t\n\t\n\t\t/**\n\t\t * Array referencing the nodes which are used for the features. The\n\t\t * parameters of this object match what is allowed by sDom - i.e.\n\t\t *   <ul>\n\t\t *     <li>'l' - Length changing</li>\n\t\t *     <li>'f' - Filtering input</li>\n\t\t *     <li>'t' - The table!</li>\n\t\t *     <li>'i' - Information</li>\n\t\t *     <li>'p' - Pagination</li>\n\t\t *     <li>'r' - pRocessing</li>\n\t\t *   </ul>\n\t\t *  @type array\n\t\t *  @default []\n\t\t */\n\t\t\"aanFeatures\": [],\n\t\n\t\t/**\n\t\t * Store data information - see {@link DataTable.models.oRow} for detailed\n\t\t * information.\n\t\t *  @type array\n\t\t *  @default []\n\t\t */\n\t\t\"aoData\": [],\n\t\n\t\t/**\n\t\t * Array of indexes which are in the current display (after filtering etc)\n\t\t *  @type array\n\t\t *  @default []\n\t\t */\n\t\t\"aiDisplay\": [],\n\t\n\t\t/**\n\t\t * Array of indexes for display - no filtering\n\t\t *  @type array\n\t\t *  @default []\n\t\t */\n\t\t\"aiDisplayMaster\": [],\n\t\n\t\t/**\n\t\t * Map of row ids to data indexes\n\t\t *  @type object\n\t\t *  @default {}\n\t\t */\n\t\t\"aIds\": {},\n\t\n\t\t/**\n\t\t * Store information about each column that is in use\n\t\t *  @type array\n\t\t *  @default []\n\t\t */\n\t\t\"aoColumns\": [],\n\t\n\t\t/**\n\t\t * Store information about the table's header\n\t\t *  @type array\n\t\t *  @default []\n\t\t */\n\t\t\"aoHeader\": [],\n\t\n\t\t/**\n\t\t * Store information about the table's footer\n\t\t *  @type array\n\t\t *  @default []\n\t\t */\n\t\t\"aoFooter\": [],\n\t\n\t\t/**\n\t\t * Store the applied global search information in case we want to force a\n\t\t * research or compare the old search to a new one.\n\t\t * Note that this parameter will be set by the initialisation routine. To\n\t\t * set a default use {@link DataTable.defaults}.\n\t\t *  @namespace\n\t\t *  @extends DataTable.models.oSearch\n\t\t */\n\t\t\"oPreviousSearch\": {},\n\t\n\t\t/**\n\t\t * Store the applied search for each column - see\n\t\t * {@link DataTable.models.oSearch} for the format that is used for the\n\t\t * filtering information for each column.\n\t\t *  @type array\n\t\t *  @default []\n\t\t */\n\t\t\"aoPreSearchCols\": [],\n\t\n\t\t/**\n\t\t * Sorting that is applied to the table. Note that the inner arrays are\n\t\t * used in the following manner:\n\t\t * <ul>\n\t\t *   <li>Index 0 - column number</li>\n\t\t *   <li>Index 1 - current sorting direction</li>\n\t\t * </ul>\n\t\t * Note that this parameter will be set by the initialisation routine. To\n\t\t * set a default use {@link DataTable.defaults}.\n\t\t *  @type array\n\t\t *  @todo These inner arrays should really be objects\n\t\t */\n\t\t\"aaSorting\": null,\n\t\n\t\t/**\n\t\t * Sorting that is always applied to the table (i.e. prefixed in front of\n\t\t * aaSorting).\n\t\t * Note that this parameter will be set by the initialisation routine. To\n\t\t * set a default use {@link DataTable.defaults}.\n\t\t *  @type array\n\t\t *  @default []\n\t\t */\n\t\t\"aaSortingFixed\": [],\n\t\n\t\t/**\n\t\t * Classes to use for the striping of a table.\n\t\t * Note that this parameter will be set by the initialisation routine. To\n\t\t * set a default use {@link DataTable.defaults}.\n\t\t *  @type array\n\t\t *  @default []\n\t\t */\n\t\t\"asStripeClasses\": null,\n\t\n\t\t/**\n\t\t * If restoring a table - we should restore its striping classes as well\n\t\t *  @type array\n\t\t *  @default []\n\t\t */\n\t\t\"asDestroyStripes\": [],\n\t\n\t\t/**\n\t\t * If restoring a table - we should restore its width\n\t\t *  @type int\n\t\t *  @default 0\n\t\t */\n\t\t\"sDestroyWidth\": 0,\n\t\n\t\t/**\n\t\t * Callback functions array for every time a row is inserted (i.e. on a draw).\n\t\t *  @type array\n\t\t *  @default []\n\t\t */\n\t\t\"aoRowCallback\": [],\n\t\n\t\t/**\n\t\t * Callback functions for the header on each draw.\n\t\t *  @type array\n\t\t *  @default []\n\t\t */\n\t\t\"aoHeaderCallback\": [],\n\t\n\t\t/**\n\t\t * Callback function for the footer on each draw.\n\t\t *  @type array\n\t\t *  @default []\n\t\t */\n\t\t\"aoFooterCallback\": [],\n\t\n\t\t/**\n\t\t * Array of callback functions for draw callback functions\n\t\t *  @type array\n\t\t *  @default []\n\t\t */\n\t\t\"aoDrawCallback\": [],\n\t\n\t\t/**\n\t\t * Array of callback functions for row created function\n\t\t *  @type array\n\t\t *  @default []\n\t\t */\n\t\t\"aoRowCreatedCallback\": [],\n\t\n\t\t/**\n\t\t * Callback functions for just before the table is redrawn. A return of\n\t\t * false will be used to cancel the draw.\n\t\t *  @type array\n\t\t *  @default []\n\t\t */\n\t\t\"aoPreDrawCallback\": [],\n\t\n\t\t/**\n\t\t * Callback functions for when the table has been initialised.\n\t\t *  @type array\n\t\t *  @default []\n\t\t */\n\t\t\"aoInitComplete\": [],\n\t\n\t\n\t\t/**\n\t\t * Callbacks for modifying the settings to be stored for state saving, prior to\n\t\t * saving state.\n\t\t *  @type array\n\t\t *  @default []\n\t\t */\n\t\t\"aoStateSaveParams\": [],\n\t\n\t\t/**\n\t\t * Callbacks for modifying the settings that have been stored for state saving\n\t\t * prior to using the stored values to restore the state.\n\t\t *  @type array\n\t\t *  @default []\n\t\t */\n\t\t\"aoStateLoadParams\": [],\n\t\n\t\t/**\n\t\t * Callbacks for operating on the settings object once the saved state has been\n\t\t * loaded\n\t\t *  @type array\n\t\t *  @default []\n\t\t */\n\t\t\"aoStateLoaded\": [],\n\t\n\t\t/**\n\t\t * Cache the table ID for quick access\n\t\t *  @type string\n\t\t *  @default <i>Empty string</i>\n\t\t */\n\t\t\"sTableId\": \"\",\n\t\n\t\t/**\n\t\t * The TABLE node for the main table\n\t\t *  @type node\n\t\t *  @default null\n\t\t */\n\t\t\"nTable\": null,\n\t\n\t\t/**\n\t\t * Permanent ref to the thead element\n\t\t *  @type node\n\t\t *  @default null\n\t\t */\n\t\t\"nTHead\": null,\n\t\n\t\t/**\n\t\t * Permanent ref to the tfoot element - if it exists\n\t\t *  @type node\n\t\t *  @default null\n\t\t */\n\t\t\"nTFoot\": null,\n\t\n\t\t/**\n\t\t * Permanent ref to the tbody element\n\t\t *  @type node\n\t\t *  @default null\n\t\t */\n\t\t\"nTBody\": null,\n\t\n\t\t/**\n\t\t * Cache the wrapper node (contains all DataTables controlled elements)\n\t\t *  @type node\n\t\t *  @default null\n\t\t */\n\t\t\"nTableWrapper\": null,\n\t\n\t\t/**\n\t\t * Indicate if when using server-side processing the loading of data\n\t\t * should be deferred until the second draw.\n\t\t * Note that this parameter will be set by the initialisation routine. To\n\t\t * set a default use {@link DataTable.defaults}.\n\t\t *  @type boolean\n\t\t *  @default false\n\t\t */\n\t\t\"bDeferLoading\": false,\n\t\n\t\t/**\n\t\t * Indicate if all required information has been read in\n\t\t *  @type boolean\n\t\t *  @default false\n\t\t */\n\t\t\"bInitialised\": false,\n\t\n\t\t/**\n\t\t * Information about open rows. Each object in the array has the parameters\n\t\t * 'nTr' and 'nParent'\n\t\t *  @type array\n\t\t *  @default []\n\t\t */\n\t\t\"aoOpenRows\": [],\n\t\n\t\t/**\n\t\t * Dictate the positioning of DataTables' control elements - see\n\t\t * {@link DataTable.model.oInit.sDom}.\n\t\t * Note that this parameter will be set by the initialisation routine. To\n\t\t * set a default use {@link DataTable.defaults}.\n\t\t *  @type string\n\t\t *  @default null\n\t\t */\n\t\t\"sDom\": null,\n\t\n\t\t/**\n\t\t * Search delay (in mS)\n\t\t *  @type integer\n\t\t *  @default null\n\t\t */\n\t\t\"searchDelay\": null,\n\t\n\t\t/**\n\t\t * Which type of pagination should be used.\n\t\t * Note that this parameter will be set by the initialisation routine. To\n\t\t * set a default use {@link DataTable.defaults}.\n\t\t *  @type string\n\t\t *  @default two_button\n\t\t */\n\t\t\"sPaginationType\": \"two_button\",\n\t\n\t\t/**\n\t\t * The state duration (for `stateSave`) in seconds.\n\t\t * Note that this parameter will be set by the initialisation routine. To\n\t\t * set a default use {@link DataTable.defaults}.\n\t\t *  @type int\n\t\t *  @default 0\n\t\t */\n\t\t\"iStateDuration\": 0,\n\t\n\t\t/**\n\t\t * Array of callback functions for state saving. Each array element is an\n\t\t * object with the following parameters:\n\t\t *   <ul>\n\t\t *     <li>function:fn - function to call. Takes two parameters, oSettings\n\t\t *       and the JSON string to save that has been thus far created. Returns\n\t\t *       a JSON string to be inserted into a json object\n\t\t *       (i.e. '\"param\": [ 0, 1, 2]')</li>\n\t\t *     <li>string:sName - name of callback</li>\n\t\t *   </ul>\n\t\t *  @type array\n\t\t *  @default []\n\t\t */\n\t\t\"aoStateSave\": [],\n\t\n\t\t/**\n\t\t * Array of callback functions for state loading. Each array element is an\n\t\t * object with the following parameters:\n\t\t *   <ul>\n\t\t *     <li>function:fn - function to call. Takes two parameters, oSettings\n\t\t *       and the object stored. May return false to cancel state loading</li>\n\t\t *     <li>string:sName - name of callback</li>\n\t\t *   </ul>\n\t\t *  @type array\n\t\t *  @default []\n\t\t */\n\t\t\"aoStateLoad\": [],\n\t\n\t\t/**\n\t\t * State that was saved. Useful for back reference\n\t\t *  @type object\n\t\t *  @default null\n\t\t */\n\t\t\"oSavedState\": null,\n\t\n\t\t/**\n\t\t * State that was loaded. Useful for back reference\n\t\t *  @type object\n\t\t *  @default null\n\t\t */\n\t\t\"oLoadedState\": null,\n\t\n\t\t/**\n\t\t * Source url for AJAX data for the table.\n\t\t * Note that this parameter will be set by the initialisation routine. To\n\t\t * set a default use {@link DataTable.defaults}.\n\t\t *  @type string\n\t\t *  @default null\n\t\t */\n\t\t\"sAjaxSource\": null,\n\t\n\t\t/**\n\t\t * Property from a given object from which to read the table data from. This\n\t\t * can be an empty string (when not server-side processing), in which case\n\t\t * it is  assumed an an array is given directly.\n\t\t * Note that this parameter will be set by the initialisation routine. To\n\t\t * set a default use {@link DataTable.defaults}.\n\t\t *  @type string\n\t\t */\n\t\t\"sAjaxDataProp\": null,\n\t\n\t\t/**\n\t\t * Note if draw should be blocked while getting data\n\t\t *  @type boolean\n\t\t *  @default true\n\t\t */\n\t\t\"bAjaxDataGet\": true,\n\t\n\t\t/**\n\t\t * The last jQuery XHR object that was used for server-side data gathering.\n\t\t * This can be used for working with the XHR information in one of the\n\t\t * callbacks\n\t\t *  @type object\n\t\t *  @default null\n\t\t */\n\t\t\"jqXHR\": null,\n\t\n\t\t/**\n\t\t * JSON returned from the server in the last Ajax request\n\t\t *  @type object\n\t\t *  @default undefined\n\t\t */\n\t\t\"json\": undefined,\n\t\n\t\t/**\n\t\t * Data submitted as part of the last Ajax request\n\t\t *  @type object\n\t\t *  @default undefined\n\t\t */\n\t\t\"oAjaxData\": undefined,\n\t\n\t\t/**\n\t\t * Function to get the server-side data.\n\t\t * Note that this parameter will be set by the initialisation routine. To\n\t\t * set a default use {@link DataTable.defaults}.\n\t\t *  @type function\n\t\t */\n\t\t\"fnServerData\": null,\n\t\n\t\t/**\n\t\t * Functions which are called prior to sending an Ajax request so extra\n\t\t * parameters can easily be sent to the server\n\t\t *  @type array\n\t\t *  @default []\n\t\t */\n\t\t\"aoServerParams\": [],\n\t\n\t\t/**\n\t\t * Send the XHR HTTP method - GET or POST (could be PUT or DELETE if\n\t\t * required).\n\t\t * Note that this parameter will be set by the initialisation routine. To\n\t\t * set a default use {@link DataTable.defaults}.\n\t\t *  @type string\n\t\t */\n\t\t\"sServerMethod\": null,\n\t\n\t\t/**\n\t\t * Format numbers for display.\n\t\t * Note that this parameter will be set by the initialisation routine. To\n\t\t * set a default use {@link DataTable.defaults}.\n\t\t *  @type function\n\t\t */\n\t\t\"fnFormatNumber\": null,\n\t\n\t\t/**\n\t\t * List of options that can be used for the user selectable length menu.\n\t\t * Note that this parameter will be set by the initialisation routine. To\n\t\t * set a default use {@link DataTable.defaults}.\n\t\t *  @type array\n\t\t *  @default []\n\t\t */\n\t\t\"aLengthMenu\": null,\n\t\n\t\t/**\n\t\t * Counter for the draws that the table does. Also used as a tracker for\n\t\t * server-side processing\n\t\t *  @type int\n\t\t *  @default 0\n\t\t */\n\t\t\"iDraw\": 0,\n\t\n\t\t/**\n\t\t * Indicate if a redraw is being done - useful for Ajax\n\t\t *  @type boolean\n\t\t *  @default false\n\t\t */\n\t\t\"bDrawing\": false,\n\t\n\t\t/**\n\t\t * Draw index (iDraw) of the last error when parsing the returned data\n\t\t *  @type int\n\t\t *  @default -1\n\t\t */\n\t\t\"iDrawError\": -1,\n\t\n\t\t/**\n\t\t * Paging display length\n\t\t *  @type int\n\t\t *  @default 10\n\t\t */\n\t\t\"_iDisplayLength\": 10,\n\t\n\t\t/**\n\t\t * Paging start point - aiDisplay index\n\t\t *  @type int\n\t\t *  @default 0\n\t\t */\n\t\t\"_iDisplayStart\": 0,\n\t\n\t\t/**\n\t\t * Server-side processing - number of records in the result set\n\t\t * (i.e. before filtering), Use fnRecordsTotal rather than\n\t\t * this property to get the value of the number of records, regardless of\n\t\t * the server-side processing setting.\n\t\t *  @type int\n\t\t *  @default 0\n\t\t *  @private\n\t\t */\n\t\t\"_iRecordsTotal\": 0,\n\t\n\t\t/**\n\t\t * Server-side processing - number of records in the current display set\n\t\t * (i.e. after filtering). Use fnRecordsDisplay rather than\n\t\t * this property to get the value of the number of records, regardless of\n\t\t * the server-side processing setting.\n\t\t *  @type boolean\n\t\t *  @default 0\n\t\t *  @private\n\t\t */\n\t\t\"_iRecordsDisplay\": 0,\n\t\n\t\t/**\n\t\t * Flag to indicate if jQuery UI marking and classes should be used.\n\t\t * Note that this parameter will be set by the initialisation routine. To\n\t\t * set a default use {@link DataTable.defaults}.\n\t\t *  @type boolean\n\t\t */\n\t\t\"bJUI\": null,\n\t\n\t\t/**\n\t\t * The classes to use for the table\n\t\t *  @type object\n\t\t *  @default {}\n\t\t */\n\t\t\"oClasses\": {},\n\t\n\t\t/**\n\t\t * Flag attached to the settings object so you can check in the draw\n\t\t * callback if filtering has been done in the draw. Deprecated in favour of\n\t\t * events.\n\t\t *  @type boolean\n\t\t *  @default false\n\t\t *  @deprecated\n\t\t */\n\t\t\"bFiltered\": false,\n\t\n\t\t/**\n\t\t * Flag attached to the settings object so you can check in the draw\n\t\t * callback if sorting has been done in the draw. Deprecated in favour of\n\t\t * events.\n\t\t *  @type boolean\n\t\t *  @default false\n\t\t *  @deprecated\n\t\t */\n\t\t\"bSorted\": false,\n\t\n\t\t/**\n\t\t * Indicate that if multiple rows are in the header and there is more than\n\t\t * one unique cell per column, if the top one (true) or bottom one (false)\n\t\t * should be used for sorting / title by DataTables.\n\t\t * Note that this parameter will be set by the initialisation routine. To\n\t\t * set a default use {@link DataTable.defaults}.\n\t\t *  @type boolean\n\t\t */\n\t\t\"bSortCellsTop\": null,\n\t\n\t\t/**\n\t\t * Initialisation object that is used for the table\n\t\t *  @type object\n\t\t *  @default null\n\t\t */\n\t\t\"oInit\": null,\n\t\n\t\t/**\n\t\t * Destroy callback functions - for plug-ins to attach themselves to the\n\t\t * destroy so they can clean up markup and events.\n\t\t *  @type array\n\t\t *  @default []\n\t\t */\n\t\t\"aoDestroyCallback\": [],\n\t\n\t\n\t\t/**\n\t\t * Get the number of records in the current record set, before filtering\n\t\t *  @type function\n\t\t */\n\t\t\"fnRecordsTotal\": function ()\n\t\t{\n\t\t\treturn _fnDataSource( this ) == 'ssp' ?\n\t\t\t\tthis._iRecordsTotal * 1 :\n\t\t\t\tthis.aiDisplayMaster.length;\n\t\t},\n\t\n\t\t/**\n\t\t * Get the number of records in the current record set, after filtering\n\t\t *  @type function\n\t\t */\n\t\t\"fnRecordsDisplay\": function ()\n\t\t{\n\t\t\treturn _fnDataSource( this ) == 'ssp' ?\n\t\t\t\tthis._iRecordsDisplay * 1 :\n\t\t\t\tthis.aiDisplay.length;\n\t\t},\n\t\n\t\t/**\n\t\t * Get the display end point - aiDisplay index\n\t\t *  @type function\n\t\t */\n\t\t\"fnDisplayEnd\": function ()\n\t\t{\n\t\t\tvar\n\t\t\t\tlen      = this._iDisplayLength,\n\t\t\t\tstart    = this._iDisplayStart,\n\t\t\t\tcalc     = start + len,\n\t\t\t\trecords  = this.aiDisplay.length,\n\t\t\t\tfeatures = this.oFeatures,\n\t\t\t\tpaginate = features.bPaginate;\n\t\n\t\t\tif ( features.bServerSide ) {\n\t\t\t\treturn paginate === false || len === -1 ?\n\t\t\t\t\tstart + records :\n\t\t\t\t\tMath.min( start+len, this._iRecordsDisplay );\n\t\t\t}\n\t\t\telse {\n\t\t\t\treturn ! paginate || calc>records || len===-1 ?\n\t\t\t\t\trecords :\n\t\t\t\t\tcalc;\n\t\t\t}\n\t\t},\n\t\n\t\t/**\n\t\t * The DataTables object for this table\n\t\t *  @type object\n\t\t *  @default null\n\t\t */\n\t\t\"oInstance\": null,\n\t\n\t\t/**\n\t\t * Unique identifier for each instance of the DataTables object. If there\n\t\t * is an ID on the table node, then it takes that value, otherwise an\n\t\t * incrementing internal counter is used.\n\t\t *  @type string\n\t\t *  @default null\n\t\t */\n\t\t\"sInstance\": null,\n\t\n\t\t/**\n\t\t * tabindex attribute value that is added to DataTables control elements, allowing\n\t\t * keyboard navigation of the table and its controls.\n\t\t */\n\t\t\"iTabIndex\": 0,\n\t\n\t\t/**\n\t\t * DIV container for the footer scrolling table if scrolling\n\t\t */\n\t\t\"nScrollHead\": null,\n\t\n\t\t/**\n\t\t * DIV container for the footer scrolling table if scrolling\n\t\t */\n\t\t\"nScrollFoot\": null,\n\t\n\t\t/**\n\t\t * Last applied sort\n\t\t *  @type array\n\t\t *  @default []\n\t\t */\n\t\t\"aLastSort\": [],\n\t\n\t\t/**\n\t\t * Stored plug-in instances\n\t\t *  @type object\n\t\t *  @default {}\n\t\t */\n\t\t\"oPlugins\": {},\n\t\n\t\t/**\n\t\t * Function used to get a row's id from the row's data\n\t\t *  @type function\n\t\t *  @default null\n\t\t */\n\t\t\"rowIdFn\": null,\n\t\n\t\t/**\n\t\t * Data location where to store a row's id\n\t\t *  @type string\n\t\t *  @default null\n\t\t */\n\t\t\"rowId\": null\n\t};\n\n\t/**\n\t * Extension object for DataTables that is used to provide all extension\n\t * options.\n\t *\n\t * Note that the `DataTable.ext` object is available through\n\t * `jQuery.fn.dataTable.ext` where it may be accessed and manipulated. It is\n\t * also aliased to `jQuery.fn.dataTableExt` for historic reasons.\n\t *  @namespace\n\t *  @extends DataTable.models.ext\n\t */\n\t\n\t\n\t/**\n\t * DataTables extensions\n\t * \n\t * This namespace acts as a collection area for plug-ins that can be used to\n\t * extend DataTables capabilities. Indeed many of the build in methods\n\t * use this method to provide their own capabilities (sorting methods for\n\t * example).\n\t *\n\t * Note that this namespace is aliased to `jQuery.fn.dataTableExt` for legacy\n\t * reasons\n\t *\n\t *  @namespace\n\t */\n\tDataTable.ext = _ext = {\n\t\t/**\n\t\t * Buttons. For use with the Buttons extension for DataTables. This is\n\t\t * defined here so other extensions can define buttons regardless of load\n\t\t * order. It is _not_ used by DataTables core.\n\t\t *\n\t\t *  @type object\n\t\t *  @default {}\n\t\t */\n\t\tbuttons: {},\n\t\n\t\n\t\t/**\n\t\t * Element class names\n\t\t *\n\t\t *  @type object\n\t\t *  @default {}\n\t\t */\n\t\tclasses: {},\n\t\n\t\n\t\t/**\n\t\t * DataTables build type (expanded by the download builder)\n\t\t *\n\t\t *  @type string\n\t\t */\n\t\tbuilder: \"-source-\",\n\t\n\t\n\t\t/**\n\t\t * Error reporting.\n\t\t * \n\t\t * How should DataTables report an error. Can take the value 'alert',\n\t\t * 'throw', 'none' or a function.\n\t\t *\n\t\t *  @type string|function\n\t\t *  @default alert\n\t\t */\n\t\terrMode: \"alert\",\n\t\n\t\n\t\t/**\n\t\t * Feature plug-ins.\n\t\t * \n\t\t * This is an array of objects which describe the feature plug-ins that are\n\t\t * available to DataTables. These feature plug-ins are then available for\n\t\t * use through the `dom` initialisation option.\n\t\t * \n\t\t * Each feature plug-in is described by an object which must have the\n\t\t * following properties:\n\t\t * \n\t\t * * `fnInit` - function that is used to initialise the plug-in,\n\t\t * * `cFeature` - a character so the feature can be enabled by the `dom`\n\t\t *   instillation option. This is case sensitive.\n\t\t *\n\t\t * The `fnInit` function has the following input parameters:\n\t\t *\n\t\t * 1. `{object}` DataTables settings object: see\n\t\t *    {@link DataTable.models.oSettings}\n\t\t *\n\t\t * And the following return is expected:\n\t\t * \n\t\t * * {node|null} The element which contains your feature. Note that the\n\t\t *   return may also be void if your plug-in does not require to inject any\n\t\t *   DOM elements into DataTables control (`dom`) - for example this might\n\t\t *   be useful when developing a plug-in which allows table control via\n\t\t *   keyboard entry\n\t\t *\n\t\t *  @type array\n\t\t *\n\t\t *  @example\n\t\t *    $.fn.dataTable.ext.features.push( {\n\t\t *      \"fnInit\": function( oSettings ) {\n\t\t *        return new TableTools( { \"oDTSettings\": oSettings } );\n\t\t *      },\n\t\t *      \"cFeature\": \"T\"\n\t\t *    } );\n\t\t */\n\t\tfeature: [],\n\t\n\t\n\t\t/**\n\t\t * Row searching.\n\t\t * \n\t\t * This method of searching is complimentary to the default type based\n\t\t * searching, and a lot more comprehensive as it allows you complete control\n\t\t * over the searching logic. Each element in this array is a function\n\t\t * (parameters described below) that is called for every row in the table,\n\t\t * and your logic decides if it should be included in the searching data set\n\t\t * or not.\n\t\t *\n\t\t * Searching functions have the following input parameters:\n\t\t *\n\t\t * 1. `{object}` DataTables settings object: see\n\t\t *    {@link DataTable.models.oSettings}\n\t\t * 2. `{array|object}` Data for the row to be processed (same as the\n\t\t *    original format that was passed in as the data source, or an array\n\t\t *    from a DOM data source\n\t\t * 3. `{int}` Row index ({@link DataTable.models.oSettings.aoData}), which\n\t\t *    can be useful to retrieve the `TR` element if you need DOM interaction.\n\t\t *\n\t\t * And the following return is expected:\n\t\t *\n\t\t * * {boolean} Include the row in the searched result set (true) or not\n\t\t *   (false)\n\t\t *\n\t\t * Note that as with the main search ability in DataTables, technically this\n\t\t * is \"filtering\", since it is subtractive. However, for consistency in\n\t\t * naming we call it searching here.\n\t\t *\n\t\t *  @type array\n\t\t *  @default []\n\t\t *\n\t\t *  @example\n\t\t *    // The following example shows custom search being applied to the\n\t\t *    // fourth column (i.e. the data[3] index) based on two input values\n\t\t *    // from the end-user, matching the data in a certain range.\n\t\t *    $.fn.dataTable.ext.search.push(\n\t\t *      function( settings, data, dataIndex ) {\n\t\t *        var min = document.getElementById('min').value * 1;\n\t\t *        var max = document.getElementById('max').value * 1;\n\t\t *        var version = data[3] == \"-\" ? 0 : data[3]*1;\n\t\t *\n\t\t *        if ( min == \"\" && max == \"\" ) {\n\t\t *          return true;\n\t\t *        }\n\t\t *        else if ( min == \"\" && version < max ) {\n\t\t *          return true;\n\t\t *        }\n\t\t *        else if ( min < version && \"\" == max ) {\n\t\t *          return true;\n\t\t *        }\n\t\t *        else if ( min < version && version < max ) {\n\t\t *          return true;\n\t\t *        }\n\t\t *        return false;\n\t\t *      }\n\t\t *    );\n\t\t */\n\t\tsearch: [],\n\t\n\t\n\t\t/**\n\t\t * Selector extensions\n\t\t *\n\t\t * The `selector` option can be used to extend the options available for the\n\t\t * selector modifier options (`selector-modifier` object data type) that\n\t\t * each of the three built in selector types offer (row, column and cell +\n\t\t * their plural counterparts). For example the Select extension uses this\n\t\t * mechanism to provide an option to select only rows, columns and cells\n\t\t * that have been marked as selected by the end user (`{selected: true}`),\n\t\t * which can be used in conjunction with the existing built in selector\n\t\t * options.\n\t\t *\n\t\t * Each property is an array to which functions can be pushed. The functions\n\t\t * take three attributes:\n\t\t *\n\t\t * * Settings object for the host table\n\t\t * * Options object (`selector-modifier` object type)\n\t\t * * Array of selected item indexes\n\t\t *\n\t\t * The return is an array of the resulting item indexes after the custom\n\t\t * selector has been applied.\n\t\t *\n\t\t *  @type object\n\t\t */\n\t\tselector: {\n\t\t\tcell: [],\n\t\t\tcolumn: [],\n\t\t\trow: []\n\t\t},\n\t\n\t\n\t\t/**\n\t\t * Internal functions, exposed for used in plug-ins.\n\t\t * \n\t\t * Please note that you should not need to use the internal methods for\n\t\t * anything other than a plug-in (and even then, try to avoid if possible).\n\t\t * The internal function may change between releases.\n\t\t *\n\t\t *  @type object\n\t\t *  @default {}\n\t\t */\n\t\tinternal: {},\n\t\n\t\n\t\t/**\n\t\t * Legacy configuration options. Enable and disable legacy options that\n\t\t * are available in DataTables.\n\t\t *\n\t\t *  @type object\n\t\t */\n\t\tlegacy: {\n\t\t\t/**\n\t\t\t * Enable / disable DataTables 1.9 compatible server-side processing\n\t\t\t * requests\n\t\t\t *\n\t\t\t *  @type boolean\n\t\t\t *  @default null\n\t\t\t */\n\t\t\tajax: null\n\t\t},\n\t\n\t\n\t\t/**\n\t\t * Pagination plug-in methods.\n\t\t * \n\t\t * Each entry in this object is a function and defines which buttons should\n\t\t * be shown by the pagination rendering method that is used for the table:\n\t\t * {@link DataTable.ext.renderer.pageButton}. The renderer addresses how the\n\t\t * buttons are displayed in the document, while the functions here tell it\n\t\t * what buttons to display. This is done by returning an array of button\n\t\t * descriptions (what each button will do).\n\t\t *\n\t\t * Pagination types (the four built in options and any additional plug-in\n\t\t * options defined here) can be used through the `paginationType`\n\t\t * initialisation parameter.\n\t\t *\n\t\t * The functions defined take two parameters:\n\t\t *\n\t\t * 1. `{int} page` The current page index\n\t\t * 2. `{int} pages` The number of pages in the table\n\t\t *\n\t\t * Each function is expected to return an array where each element of the\n\t\t * array can be one of:\n\t\t *\n\t\t * * `first` - Jump to first page when activated\n\t\t * * `last` - Jump to last page when activated\n\t\t * * `previous` - Show previous page when activated\n\t\t * * `next` - Show next page when activated\n\t\t * * `{int}` - Show page of the index given\n\t\t * * `{array}` - A nested array containing the above elements to add a\n\t\t *   containing 'DIV' element (might be useful for styling).\n\t\t *\n\t\t * Note that DataTables v1.9- used this object slightly differently whereby\n\t\t * an object with two functions would be defined for each plug-in. That\n\t\t * ability is still supported by DataTables 1.10+ to provide backwards\n\t\t * compatibility, but this option of use is now decremented and no longer\n\t\t * documented in DataTables 1.10+.\n\t\t *\n\t\t *  @type object\n\t\t *  @default {}\n\t\t *\n\t\t *  @example\n\t\t *    // Show previous, next and current page buttons only\n\t\t *    $.fn.dataTableExt.oPagination.current = function ( page, pages ) {\n\t\t *      return [ 'previous', page, 'next' ];\n\t\t *    };\n\t\t */\n\t\tpager: {},\n\t\n\t\n\t\trenderer: {\n\t\t\tpageButton: {},\n\t\t\theader: {}\n\t\t},\n\t\n\t\n\t\t/**\n\t\t * Ordering plug-ins - custom data source\n\t\t * \n\t\t * The extension options for ordering of data available here is complimentary\n\t\t * to the default type based ordering that DataTables typically uses. It\n\t\t * allows much greater control over the the data that is being used to\n\t\t * order a column, but is necessarily therefore more complex.\n\t\t * \n\t\t * This type of ordering is useful if you want to do ordering based on data\n\t\t * live from the DOM (for example the contents of an 'input' element) rather\n\t\t * than just the static string that DataTables knows of.\n\t\t * \n\t\t * The way these plug-ins work is that you create an array of the values you\n\t\t * wish to be ordering for the column in question and then return that\n\t\t * array. The data in the array much be in the index order of the rows in\n\t\t * the table (not the currently ordering order!). Which order data gathering\n\t\t * function is run here depends on the `dt-init columns.orderDataType`\n\t\t * parameter that is used for the column (if any).\n\t\t *\n\t\t * The functions defined take two parameters:\n\t\t *\n\t\t * 1. `{object}` DataTables settings object: see\n\t\t *    {@link DataTable.models.oSettings}\n\t\t * 2. `{int}` Target column index\n\t\t *\n\t\t * Each function is expected to return an array:\n\t\t *\n\t\t * * `{array}` Data for the column to be ordering upon\n\t\t *\n\t\t *  @type array\n\t\t *\n\t\t *  @example\n\t\t *    // Ordering using `input` node values\n\t\t *    $.fn.dataTable.ext.order['dom-text'] = function  ( settings, col )\n\t\t *    {\n\t\t *      return this.api().column( col, {order:'index'} ).nodes().map( function ( td, i ) {\n\t\t *        return $('input', td).val();\n\t\t *      } );\n\t\t *    }\n\t\t */\n\t\torder: {},\n\t\n\t\n\t\t/**\n\t\t * Type based plug-ins.\n\t\t *\n\t\t * Each column in DataTables has a type assigned to it, either by automatic\n\t\t * detection or by direct assignment using the `type` option for the column.\n\t\t * The type of a column will effect how it is ordering and search (plug-ins\n\t\t * can also make use of the column type if required).\n\t\t *\n\t\t * @namespace\n\t\t */\n\t\ttype: {\n\t\t\t/**\n\t\t\t * Type detection functions.\n\t\t\t *\n\t\t\t * The functions defined in this object are used to automatically detect\n\t\t\t * a column's type, making initialisation of DataTables super easy, even\n\t\t\t * when complex data is in the table.\n\t\t\t *\n\t\t\t * The functions defined take two parameters:\n\t\t\t *\n\t\t     *  1. `{*}` Data from the column cell to be analysed\n\t\t     *  2. `{settings}` DataTables settings object. This can be used to\n\t\t     *     perform context specific type detection - for example detection\n\t\t     *     based on language settings such as using a comma for a decimal\n\t\t     *     place. Generally speaking the options from the settings will not\n\t\t     *     be required\n\t\t\t *\n\t\t\t * Each function is expected to return:\n\t\t\t *\n\t\t\t * * `{string|null}` Data type detected, or null if unknown (and thus\n\t\t\t *   pass it on to the other type detection functions.\n\t\t\t *\n\t\t\t *  @type array\n\t\t\t *\n\t\t\t *  @example\n\t\t\t *    // Currency type detection plug-in:\n\t\t\t *    $.fn.dataTable.ext.type.detect.push(\n\t\t\t *      function ( data, settings ) {\n\t\t\t *        // Check the numeric part\n\t\t\t *        if ( ! $.isNumeric( data.substring(1) ) ) {\n\t\t\t *          return null;\n\t\t\t *        }\n\t\t\t *\n\t\t\t *        // Check prefixed by currency\n\t\t\t *        if ( data.charAt(0) == '$' || data.charAt(0) == '&pound;' ) {\n\t\t\t *          return 'currency';\n\t\t\t *        }\n\t\t\t *        return null;\n\t\t\t *      }\n\t\t\t *    );\n\t\t\t */\n\t\t\tdetect: [],\n\t\n\t\n\t\t\t/**\n\t\t\t * Type based search formatting.\n\t\t\t *\n\t\t\t * The type based searching functions can be used to pre-format the\n\t\t\t * data to be search on. For example, it can be used to strip HTML\n\t\t\t * tags or to de-format telephone numbers for numeric only searching.\n\t\t\t *\n\t\t\t * Note that is a search is not defined for a column of a given type,\n\t\t\t * no search formatting will be performed.\n\t\t\t * \n\t\t\t * Pre-processing of searching data plug-ins - When you assign the sType\n\t\t\t * for a column (or have it automatically detected for you by DataTables\n\t\t\t * or a type detection plug-in), you will typically be using this for\n\t\t\t * custom sorting, but it can also be used to provide custom searching\n\t\t\t * by allowing you to pre-processing the data and returning the data in\n\t\t\t * the format that should be searched upon. This is done by adding\n\t\t\t * functions this object with a parameter name which matches the sType\n\t\t\t * for that target column. This is the corollary of <i>afnSortData</i>\n\t\t\t * for searching data.\n\t\t\t *\n\t\t\t * The functions defined take a single parameter:\n\t\t\t *\n\t\t     *  1. `{*}` Data from the column cell to be prepared for searching\n\t\t\t *\n\t\t\t * Each function is expected to return:\n\t\t\t *\n\t\t\t * * `{string|null}` Formatted string that will be used for the searching.\n\t\t\t *\n\t\t\t *  @type object\n\t\t\t *  @default {}\n\t\t\t *\n\t\t\t *  @example\n\t\t\t *    $.fn.dataTable.ext.type.search['title-numeric'] = function ( d ) {\n\t\t\t *      return d.replace(/\\n/g,\" \").replace( /<.*?>/g, \"\" );\n\t\t\t *    }\n\t\t\t */\n\t\t\tsearch: {},\n\t\n\t\n\t\t\t/**\n\t\t\t * Type based ordering.\n\t\t\t *\n\t\t\t * The column type tells DataTables what ordering to apply to the table\n\t\t\t * when a column is sorted upon. The order for each type that is defined,\n\t\t\t * is defined by the functions available in this object.\n\t\t\t *\n\t\t\t * Each ordering option can be described by three properties added to\n\t\t\t * this object:\n\t\t\t *\n\t\t\t * * `{type}-pre` - Pre-formatting function\n\t\t\t * * `{type}-asc` - Ascending order function\n\t\t\t * * `{type}-desc` - Descending order function\n\t\t\t *\n\t\t\t * All three can be used together, only `{type}-pre` or only\n\t\t\t * `{type}-asc` and `{type}-desc` together. It is generally recommended\n\t\t\t * that only `{type}-pre` is used, as this provides the optimal\n\t\t\t * implementation in terms of speed, although the others are provided\n\t\t\t * for compatibility with existing Javascript sort functions.\n\t\t\t *\n\t\t\t * `{type}-pre`: Functions defined take a single parameter:\n\t\t\t *\n\t\t     *  1. `{*}` Data from the column cell to be prepared for ordering\n\t\t\t *\n\t\t\t * And return:\n\t\t\t *\n\t\t\t * * `{*}` Data to be sorted upon\n\t\t\t *\n\t\t\t * `{type}-asc` and `{type}-desc`: Functions are typical Javascript sort\n\t\t\t * functions, taking two parameters:\n\t\t\t *\n\t\t     *  1. `{*}` Data to compare to the second parameter\n\t\t     *  2. `{*}` Data to compare to the first parameter\n\t\t\t *\n\t\t\t * And returning:\n\t\t\t *\n\t\t\t * * `{*}` Ordering match: <0 if first parameter should be sorted lower\n\t\t\t *   than the second parameter, ===0 if the two parameters are equal and\n\t\t\t *   >0 if the first parameter should be sorted height than the second\n\t\t\t *   parameter.\n\t\t\t * \n\t\t\t *  @type object\n\t\t\t *  @default {}\n\t\t\t *\n\t\t\t *  @example\n\t\t\t *    // Numeric ordering of formatted numbers with a pre-formatter\n\t\t\t *    $.extend( $.fn.dataTable.ext.type.order, {\n\t\t\t *      \"string-pre\": function(x) {\n\t\t\t *        a = (a === \"-\" || a === \"\") ? 0 : a.replace( /[^\\d\\-\\.]/g, \"\" );\n\t\t\t *        return parseFloat( a );\n\t\t\t *      }\n\t\t\t *    } );\n\t\t\t *\n\t\t\t *  @example\n\t\t\t *    // Case-sensitive string ordering, with no pre-formatting method\n\t\t\t *    $.extend( $.fn.dataTable.ext.order, {\n\t\t\t *      \"string-case-asc\": function(x,y) {\n\t\t\t *        return ((x < y) ? -1 : ((x > y) ? 1 : 0));\n\t\t\t *      },\n\t\t\t *      \"string-case-desc\": function(x,y) {\n\t\t\t *        return ((x < y) ? 1 : ((x > y) ? -1 : 0));\n\t\t\t *      }\n\t\t\t *    } );\n\t\t\t */\n\t\t\torder: {}\n\t\t},\n\t\n\t\t/**\n\t\t * Unique DataTables instance counter\n\t\t *\n\t\t * @type int\n\t\t * @private\n\t\t */\n\t\t_unique: 0,\n\t\n\t\n\t\t//\n\t\t// Depreciated\n\t\t// The following properties are retained for backwards compatiblity only.\n\t\t// The should not be used in new projects and will be removed in a future\n\t\t// version\n\t\t//\n\t\n\t\t/**\n\t\t * Version check function.\n\t\t *  @type function\n\t\t *  @depreciated Since 1.10\n\t\t */\n\t\tfnVersionCheck: DataTable.fnVersionCheck,\n\t\n\t\n\t\t/**\n\t\t * Index for what 'this' index API functions should use\n\t\t *  @type int\n\t\t *  @deprecated Since v1.10\n\t\t */\n\t\tiApiIndex: 0,\n\t\n\t\n\t\t/**\n\t\t * jQuery UI class container\n\t\t *  @type object\n\t\t *  @deprecated Since v1.10\n\t\t */\n\t\toJUIClasses: {},\n\t\n\t\n\t\t/**\n\t\t * Software version\n\t\t *  @type string\n\t\t *  @deprecated Since v1.10\n\t\t */\n\t\tsVersion: DataTable.version\n\t};\n\t\n\t\n\t//\n\t// Backwards compatibility. Alias to pre 1.10 Hungarian notation counter parts\n\t//\n\t$.extend( _ext, {\n\t\tafnFiltering: _ext.search,\n\t\taTypes:       _ext.type.detect,\n\t\tofnSearch:    _ext.type.search,\n\t\toSort:        _ext.type.order,\n\t\tafnSortData:  _ext.order,\n\t\taoFeatures:   _ext.feature,\n\t\toApi:         _ext.internal,\n\t\toStdClasses:  _ext.classes,\n\t\toPagination:  _ext.pager\n\t} );\n\t\n\t\n\t$.extend( DataTable.ext.classes, {\n\t\t\"sTable\": \"dataTable\",\n\t\t\"sNoFooter\": \"no-footer\",\n\t\n\t\t/* Paging buttons */\n\t\t\"sPageButton\": \"paginate_button\",\n\t\t\"sPageButtonActive\": \"current\",\n\t\t\"sPageButtonDisabled\": \"disabled\",\n\t\n\t\t/* Striping classes */\n\t\t\"sStripeOdd\": \"odd\",\n\t\t\"sStripeEven\": \"even\",\n\t\n\t\t/* Empty row */\n\t\t\"sRowEmpty\": \"dataTables_empty\",\n\t\n\t\t/* Features */\n\t\t\"sWrapper\": \"dataTables_wrapper\",\n\t\t\"sFilter\": \"dataTables_filter\",\n\t\t\"sInfo\": \"dataTables_info\",\n\t\t\"sPaging\": \"dataTables_paginate paging_\", /* Note that the type is postfixed */\n\t\t\"sLength\": \"dataTables_length\",\n\t\t\"sProcessing\": \"dataTables_processing\",\n\t\n\t\t/* Sorting */\n\t\t\"sSortAsc\": \"sorting_asc\",\n\t\t\"sSortDesc\": \"sorting_desc\",\n\t\t\"sSortable\": \"sorting\", /* Sortable in both directions */\n\t\t\"sSortableAsc\": \"sorting_asc_disabled\",\n\t\t\"sSortableDesc\": \"sorting_desc_disabled\",\n\t\t\"sSortableNone\": \"sorting_disabled\",\n\t\t\"sSortColumn\": \"sorting_\", /* Note that an int is postfixed for the sorting order */\n\t\n\t\t/* Filtering */\n\t\t\"sFilterInput\": \"\",\n\t\n\t\t/* Page length */\n\t\t\"sLengthSelect\": \"\",\n\t\n\t\t/* Scrolling */\n\t\t\"sScrollWrapper\": \"dataTables_scroll\",\n\t\t\"sScrollHead\": \"dataTables_scrollHead\",\n\t\t\"sScrollHeadInner\": \"dataTables_scrollHeadInner\",\n\t\t\"sScrollBody\": \"dataTables_scrollBody\",\n\t\t\"sScrollFoot\": \"dataTables_scrollFoot\",\n\t\t\"sScrollFootInner\": \"dataTables_scrollFootInner\",\n\t\n\t\t/* Misc */\n\t\t\"sHeaderTH\": \"\",\n\t\t\"sFooterTH\": \"\",\n\t\n\t\t// Deprecated\n\t\t\"sSortJUIAsc\": \"\",\n\t\t\"sSortJUIDesc\": \"\",\n\t\t\"sSortJUI\": \"\",\n\t\t\"sSortJUIAscAllowed\": \"\",\n\t\t\"sSortJUIDescAllowed\": \"\",\n\t\t\"sSortJUIWrapper\": \"\",\n\t\t\"sSortIcon\": \"\",\n\t\t\"sJUIHeader\": \"\",\n\t\t\"sJUIFooter\": \"\"\n\t} );\n\t\n\t\n\t(function() {\n\t\n\t// Reused strings for better compression. Closure compiler appears to have a\n\t// weird edge case where it is trying to expand strings rather than use the\n\t// variable version. This results in about 200 bytes being added, for very\n\t// little preference benefit since it this run on script load only.\n\tvar _empty = '';\n\t_empty = '';\n\t\n\tvar _stateDefault = _empty + 'ui-state-default';\n\tvar _sortIcon     = _empty + 'css_right ui-icon ui-icon-';\n\tvar _headerFooter = _empty + 'fg-toolbar ui-toolbar ui-widget-header ui-helper-clearfix';\n\t\n\t$.extend( DataTable.ext.oJUIClasses, DataTable.ext.classes, {\n\t\t/* Full numbers paging buttons */\n\t\t\"sPageButton\":         \"fg-button ui-button \"+_stateDefault,\n\t\t\"sPageButtonActive\":   \"ui-state-disabled\",\n\t\t\"sPageButtonDisabled\": \"ui-state-disabled\",\n\t\n\t\t/* Features */\n\t\t\"sPaging\": \"dataTables_paginate fg-buttonset ui-buttonset fg-buttonset-multi \"+\n\t\t\t\"ui-buttonset-multi paging_\", /* Note that the type is postfixed */\n\t\n\t\t/* Sorting */\n\t\t\"sSortAsc\":            _stateDefault+\" sorting_asc\",\n\t\t\"sSortDesc\":           _stateDefault+\" sorting_desc\",\n\t\t\"sSortable\":           _stateDefault+\" sorting\",\n\t\t\"sSortableAsc\":        _stateDefault+\" sorting_asc_disabled\",\n\t\t\"sSortableDesc\":       _stateDefault+\" sorting_desc_disabled\",\n\t\t\"sSortableNone\":       _stateDefault+\" sorting_disabled\",\n\t\t\"sSortJUIAsc\":         _sortIcon+\"triangle-1-n\",\n\t\t\"sSortJUIDesc\":        _sortIcon+\"triangle-1-s\",\n\t\t\"sSortJUI\":            _sortIcon+\"carat-2-n-s\",\n\t\t\"sSortJUIAscAllowed\":  _sortIcon+\"carat-1-n\",\n\t\t\"sSortJUIDescAllowed\": _sortIcon+\"carat-1-s\",\n\t\t\"sSortJUIWrapper\":     \"DataTables_sort_wrapper\",\n\t\t\"sSortIcon\":           \"DataTables_sort_icon\",\n\t\n\t\t/* Scrolling */\n\t\t\"sScrollHead\": \"dataTables_scrollHead \"+_stateDefault,\n\t\t\"sScrollFoot\": \"dataTables_scrollFoot \"+_stateDefault,\n\t\n\t\t/* Misc */\n\t\t\"sHeaderTH\":  _stateDefault,\n\t\t\"sFooterTH\":  _stateDefault,\n\t\t\"sJUIHeader\": _headerFooter+\" ui-corner-tl ui-corner-tr\",\n\t\t\"sJUIFooter\": _headerFooter+\" ui-corner-bl ui-corner-br\"\n\t} );\n\t\n\t}());\n\t\n\t\n\t\n\tvar extPagination = DataTable.ext.pager;\n\t\n\tfunction _numbers ( page, pages ) {\n\t\tvar\n\t\t\tnumbers = [],\n\t\t\tbuttons = extPagination.numbers_length,\n\t\t\thalf = Math.floor( buttons / 2 ),\n\t\t\ti = 1;\n\t\n\t\tif ( pages <= buttons ) {\n\t\t\tnumbers = _range( 0, pages );\n\t\t}\n\t\telse if ( page <= half ) {\n\t\t\tnumbers = _range( 0, buttons-2 );\n\t\t\tnumbers.push( 'ellipsis' );\n\t\t\tnumbers.push( pages-1 );\n\t\t}\n\t\telse if ( page >= pages - 1 - half ) {\n\t\t\tnumbers = _range( pages-(buttons-2), pages );\n\t\t\tnumbers.splice( 0, 0, 'ellipsis' ); // no unshift in ie6\n\t\t\tnumbers.splice( 0, 0, 0 );\n\t\t}\n\t\telse {\n\t\t\tnumbers = _range( page-half+2, page+half-1 );\n\t\t\tnumbers.push( 'ellipsis' );\n\t\t\tnumbers.push( pages-1 );\n\t\t\tnumbers.splice( 0, 0, 'ellipsis' );\n\t\t\tnumbers.splice( 0, 0, 0 );\n\t\t}\n\t\n\t\tnumbers.DT_el = 'span';\n\t\treturn numbers;\n\t}\n\t\n\t\n\t$.extend( extPagination, {\n\t\tsimple: function ( page, pages ) {\n\t\t\treturn [ 'previous', 'next' ];\n\t\t},\n\t\n\t\tfull: function ( page, pages ) {\n\t\t\treturn [  'first', 'previous', 'next', 'last' ];\n\t\t},\n\t\n\t\tnumbers: function ( page, pages ) {\n\t\t\treturn [ _numbers(page, pages) ];\n\t\t},\n\t\n\t\tsimple_numbers: function ( page, pages ) {\n\t\t\treturn [ 'previous', _numbers(page, pages), 'next' ];\n\t\t},\n\t\n\t\tfull_numbers: function ( page, pages ) {\n\t\t\treturn [ 'first', 'previous', _numbers(page, pages), 'next', 'last' ];\n\t\t},\n\t\n\t\t// For testing and plug-ins to use\n\t\t_numbers: _numbers,\n\t\n\t\t// Number of number buttons (including ellipsis) to show. _Must be odd!_\n\t\tnumbers_length: 7\n\t} );\n\t\n\t\n\t$.extend( true, DataTable.ext.renderer, {\n\t\tpageButton: {\n\t\t\t_: function ( settings, host, idx, buttons, page, pages ) {\n\t\t\t\tvar classes = settings.oClasses;\n\t\t\t\tvar lang = settings.oLanguage.oPaginate;\n\t\t\t\tvar aria = settings.oLanguage.oAria.paginate || {};\n\t\t\t\tvar btnDisplay, btnClass, counter=0;\n\t\n\t\t\t\tvar attach = function( container, buttons ) {\n\t\t\t\t\tvar i, ien, node, button;\n\t\t\t\t\tvar clickHandler = function ( e ) {\n\t\t\t\t\t\t_fnPageChange( settings, e.data.action, true );\n\t\t\t\t\t};\n\t\n\t\t\t\t\tfor ( i=0, ien=buttons.length ; i<ien ; i++ ) {\n\t\t\t\t\t\tbutton = buttons[i];\n\t\n\t\t\t\t\t\tif ( $.isArray( button ) ) {\n\t\t\t\t\t\t\tvar inner = $( '<'+(button.DT_el || 'div')+'/>' )\n\t\t\t\t\t\t\t\t.appendTo( container );\n\t\t\t\t\t\t\tattach( inner, button );\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse {\n\t\t\t\t\t\t\tbtnDisplay = null;\n\t\t\t\t\t\t\tbtnClass = '';\n\t\n\t\t\t\t\t\t\tswitch ( button ) {\n\t\t\t\t\t\t\t\tcase 'ellipsis':\n\t\t\t\t\t\t\t\t\tcontainer.append('<span class=\"ellipsis\">&#x2026;</span>');\n\t\t\t\t\t\t\t\t\tbreak;\n\t\n\t\t\t\t\t\t\t\tcase 'first':\n\t\t\t\t\t\t\t\t\tbtnDisplay = lang.sFirst;\n\t\t\t\t\t\t\t\t\tbtnClass = button + (page > 0 ?\n\t\t\t\t\t\t\t\t\t\t'' : ' '+classes.sPageButtonDisabled);\n\t\t\t\t\t\t\t\t\tbreak;\n\t\n\t\t\t\t\t\t\t\tcase 'previous':\n\t\t\t\t\t\t\t\t\tbtnDisplay = lang.sPrevious;\n\t\t\t\t\t\t\t\t\tbtnClass = button + (page > 0 ?\n\t\t\t\t\t\t\t\t\t\t'' : ' '+classes.sPageButtonDisabled);\n\t\t\t\t\t\t\t\t\tbreak;\n\t\n\t\t\t\t\t\t\t\tcase 'next':\n\t\t\t\t\t\t\t\t\tbtnDisplay = lang.sNext;\n\t\t\t\t\t\t\t\t\tbtnClass = button + (page < pages-1 ?\n\t\t\t\t\t\t\t\t\t\t'' : ' '+classes.sPageButtonDisabled);\n\t\t\t\t\t\t\t\t\tbreak;\n\t\n\t\t\t\t\t\t\t\tcase 'last':\n\t\t\t\t\t\t\t\t\tbtnDisplay = lang.sLast;\n\t\t\t\t\t\t\t\t\tbtnClass = button + (page < pages-1 ?\n\t\t\t\t\t\t\t\t\t\t'' : ' '+classes.sPageButtonDisabled);\n\t\t\t\t\t\t\t\t\tbreak;\n\t\n\t\t\t\t\t\t\t\tdefault:\n\t\t\t\t\t\t\t\t\tbtnDisplay = button + 1;\n\t\t\t\t\t\t\t\t\tbtnClass = page === button ?\n\t\t\t\t\t\t\t\t\t\tclasses.sPageButtonActive : '';\n\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t}\n\t\n\t\t\t\t\t\t\tif ( btnDisplay !== null ) {\n\t\t\t\t\t\t\t\tnode = $('<a>', {\n\t\t\t\t\t\t\t\t\t\t'class': classes.sPageButton+' '+btnClass,\n\t\t\t\t\t\t\t\t\t\t'aria-controls': settings.sTableId,\n\t\t\t\t\t\t\t\t\t\t'aria-label': aria[ button ],\n\t\t\t\t\t\t\t\t\t\t'data-dt-idx': counter,\n\t\t\t\t\t\t\t\t\t\t'tabindex': settings.iTabIndex,\n\t\t\t\t\t\t\t\t\t\t'id': idx === 0 && typeof button === 'string' ?\n\t\t\t\t\t\t\t\t\t\t\tsettings.sTableId +'_'+ button :\n\t\t\t\t\t\t\t\t\t\t\tnull\n\t\t\t\t\t\t\t\t\t} )\n\t\t\t\t\t\t\t\t\t.html( btnDisplay )\n\t\t\t\t\t\t\t\t\t.appendTo( container );\n\t\n\t\t\t\t\t\t\t\t_fnBindAction(\n\t\t\t\t\t\t\t\t\tnode, {action: button}, clickHandler\n\t\t\t\t\t\t\t\t);\n\t\n\t\t\t\t\t\t\t\tcounter++;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t};\n\t\n\t\t\t\t// IE9 throws an 'unknown error' if document.activeElement is used\n\t\t\t\t// inside an iframe or frame. Try / catch the error. Not good for\n\t\t\t\t// accessibility, but neither are frames.\n\t\t\t\tvar activeEl;\n\t\n\t\t\t\ttry {\n\t\t\t\t\t// Because this approach is destroying and recreating the paging\n\t\t\t\t\t// elements, focus is lost on the select button which is bad for\n\t\t\t\t\t// accessibility. So we want to restore focus once the draw has\n\t\t\t\t\t// completed\n\t\t\t\t\tactiveEl = $(host).find(document.activeElement).data('dt-idx');\n\t\t\t\t}\n\t\t\t\tcatch (e) {}\n\t\n\t\t\t\tattach( $(host).empty(), buttons );\n\t\n\t\t\t\tif ( activeEl ) {\n\t\t\t\t\t$(host).find( '[data-dt-idx='+activeEl+']' ).focus();\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t} );\n\t\n\t\n\t\n\t// Built in type detection. See model.ext.aTypes for information about\n\t// what is required from this methods.\n\t$.extend( DataTable.ext.type.detect, [\n\t\t// Plain numbers - first since V8 detects some plain numbers as dates\n\t\t// e.g. Date.parse('55') (but not all, e.g. Date.parse('22')...).\n\t\tfunction ( d, settings )\n\t\t{\n\t\t\tvar decimal = settings.oLanguage.sDecimal;\n\t\t\treturn _isNumber( d, decimal ) ? 'num'+decimal : null;\n\t\t},\n\t\n\t\t// Dates (only those recognised by the browser's Date.parse)\n\t\tfunction ( d, settings )\n\t\t{\n\t\t\t// V8 will remove any unknown characters at the start and end of the\n\t\t\t// expression, leading to false matches such as `$245.12` or `10%` being\n\t\t\t// a valid date. See forum thread 18941 for detail.\n\t\t\tif ( d && !(d instanceof Date) && ( ! _re_date_start.test(d) || ! _re_date_end.test(d) ) ) {\n\t\t\t\treturn null;\n\t\t\t}\n\t\t\tvar parsed = Date.parse(d);\n\t\t\treturn (parsed !== null && !isNaN(parsed)) || _empty(d) ? 'date' : null;\n\t\t},\n\t\n\t\t// Formatted numbers\n\t\tfunction ( d, settings )\n\t\t{\n\t\t\tvar decimal = settings.oLanguage.sDecimal;\n\t\t\treturn _isNumber( d, decimal, true ) ? 'num-fmt'+decimal : null;\n\t\t},\n\t\n\t\t// HTML numeric\n\t\tfunction ( d, settings )\n\t\t{\n\t\t\tvar decimal = settings.oLanguage.sDecimal;\n\t\t\treturn _htmlNumeric( d, decimal ) ? 'html-num'+decimal : null;\n\t\t},\n\t\n\t\t// HTML numeric, formatted\n\t\tfunction ( d, settings )\n\t\t{\n\t\t\tvar decimal = settings.oLanguage.sDecimal;\n\t\t\treturn _htmlNumeric( d, decimal, true ) ? 'html-num-fmt'+decimal : null;\n\t\t},\n\t\n\t\t// HTML (this is strict checking - there must be html)\n\t\tfunction ( d, settings )\n\t\t{\n\t\t\treturn _empty( d ) || (typeof d === 'string' && d.indexOf('<') !== -1) ?\n\t\t\t\t'html' : null;\n\t\t}\n\t] );\n\t\n\t\n\t\n\t// Filter formatting functions. See model.ext.ofnSearch for information about\n\t// what is required from these methods.\n\t// \n\t// Note that additional search methods are added for the html numbers and\n\t// html formatted numbers by `_addNumericSort()` when we know what the decimal\n\t// place is\n\t\n\t\n\t$.extend( DataTable.ext.type.search, {\n\t\thtml: function ( data ) {\n\t\t\treturn _empty(data) ?\n\t\t\t\tdata :\n\t\t\t\ttypeof data === 'string' ?\n\t\t\t\t\tdata\n\t\t\t\t\t\t.replace( _re_new_lines, \" \" )\n\t\t\t\t\t\t.replace( _re_html, \"\" ) :\n\t\t\t\t\t'';\n\t\t},\n\t\n\t\tstring: function ( data ) {\n\t\t\treturn _empty(data) ?\n\t\t\t\tdata :\n\t\t\t\ttypeof data === 'string' ?\n\t\t\t\t\tdata.replace( _re_new_lines, \" \" ) :\n\t\t\t\t\tdata;\n\t\t}\n\t} );\n\t\n\t\n\t\n\tvar __numericReplace = function ( d, decimalPlace, re1, re2 ) {\n\t\tif ( d !== 0 && (!d || d === '-') ) {\n\t\t\treturn -Infinity;\n\t\t}\n\t\n\t\t// If a decimal place other than `.` is used, it needs to be given to the\n\t\t// function so we can detect it and replace with a `.` which is the only\n\t\t// decimal place Javascript recognises - it is not locale aware.\n\t\tif ( decimalPlace ) {\n\t\t\td = _numToDecimal( d, decimalPlace );\n\t\t}\n\t\n\t\tif ( d.replace ) {\n\t\t\tif ( re1 ) {\n\t\t\t\td = d.replace( re1, '' );\n\t\t\t}\n\t\n\t\t\tif ( re2 ) {\n\t\t\t\td = d.replace( re2, '' );\n\t\t\t}\n\t\t}\n\t\n\t\treturn d * 1;\n\t};\n\t\n\t\n\t// Add the numeric 'deformatting' functions for sorting and search. This is done\n\t// in a function to provide an easy ability for the language options to add\n\t// additional methods if a non-period decimal place is used.\n\tfunction _addNumericSort ( decimalPlace ) {\n\t\t$.each(\n\t\t\t{\n\t\t\t\t// Plain numbers\n\t\t\t\t\"num\": function ( d ) {\n\t\t\t\t\treturn __numericReplace( d, decimalPlace );\n\t\t\t\t},\n\t\n\t\t\t\t// Formatted numbers\n\t\t\t\t\"num-fmt\": function ( d ) {\n\t\t\t\t\treturn __numericReplace( d, decimalPlace, _re_formatted_numeric );\n\t\t\t\t},\n\t\n\t\t\t\t// HTML numeric\n\t\t\t\t\"html-num\": function ( d ) {\n\t\t\t\t\treturn __numericReplace( d, decimalPlace, _re_html );\n\t\t\t\t},\n\t\n\t\t\t\t// HTML numeric, formatted\n\t\t\t\t\"html-num-fmt\": function ( d ) {\n\t\t\t\t\treturn __numericReplace( d, decimalPlace, _re_html, _re_formatted_numeric );\n\t\t\t\t}\n\t\t\t},\n\t\t\tfunction ( key, fn ) {\n\t\t\t\t// Add the ordering method\n\t\t\t\t_ext.type.order[ key+decimalPlace+'-pre' ] = fn;\n\t\n\t\t\t\t// For HTML types add a search formatter that will strip the HTML\n\t\t\t\tif ( key.match(/^html\\-/) ) {\n\t\t\t\t\t_ext.type.search[ key+decimalPlace ] = _ext.type.search.html;\n\t\t\t\t}\n\t\t\t}\n\t\t);\n\t}\n\t\n\t\n\t// Default sort methods\n\t$.extend( _ext.type.order, {\n\t\t// Dates\n\t\t\"date-pre\": function ( d ) {\n\t\t\treturn Date.parse( d ) || 0;\n\t\t},\n\t\n\t\t// html\n\t\t\"html-pre\": function ( a ) {\n\t\t\treturn _empty(a) ?\n\t\t\t\t'' :\n\t\t\t\ta.replace ?\n\t\t\t\t\ta.replace( /<.*?>/g, \"\" ).toLowerCase() :\n\t\t\t\t\ta+'';\n\t\t},\n\t\n\t\t// string\n\t\t\"string-pre\": function ( a ) {\n\t\t\t// This is a little complex, but faster than always calling toString,\n\t\t\t// http://jsperf.com/tostring-v-check\n\t\t\treturn _empty(a) ?\n\t\t\t\t'' :\n\t\t\t\ttypeof a === 'string' ?\n\t\t\t\t\ta.toLowerCase() :\n\t\t\t\t\t! a.toString ?\n\t\t\t\t\t\t'' :\n\t\t\t\t\t\ta.toString();\n\t\t},\n\t\n\t\t// string-asc and -desc are retained only for compatibility with the old\n\t\t// sort methods\n\t\t\"string-asc\": function ( x, y ) {\n\t\t\treturn ((x < y) ? -1 : ((x > y) ? 1 : 0));\n\t\t},\n\t\n\t\t\"string-desc\": function ( x, y ) {\n\t\t\treturn ((x < y) ? 1 : ((x > y) ? -1 : 0));\n\t\t}\n\t} );\n\t\n\t\n\t// Numeric sorting types - order doesn't matter here\n\t_addNumericSort( '' );\n\t\n\t\n\t$.extend( true, DataTable.ext.renderer, {\n\t\theader: {\n\t\t\t_: function ( settings, cell, column, classes ) {\n\t\t\t\t// No additional mark-up required\n\t\t\t\t// Attach a sort listener to update on sort - note that using the\n\t\t\t\t// `DT` namespace will allow the event to be removed automatically\n\t\t\t\t// on destroy, while the `dt` namespaced event is the one we are\n\t\t\t\t// listening for\n\t\t\t\t$(settings.nTable).on( 'order.dt.DT', function ( e, ctx, sorting, columns ) {\n\t\t\t\t\tif ( settings !== ctx ) { // need to check this this is the host\n\t\t\t\t\t\treturn;               // table, not a nested one\n\t\t\t\t\t}\n\t\n\t\t\t\t\tvar colIdx = column.idx;\n\t\n\t\t\t\t\tcell\n\t\t\t\t\t\t.removeClass(\n\t\t\t\t\t\t\tcolumn.sSortingClass +' '+\n\t\t\t\t\t\t\tclasses.sSortAsc +' '+\n\t\t\t\t\t\t\tclasses.sSortDesc\n\t\t\t\t\t\t)\n\t\t\t\t\t\t.addClass( columns[ colIdx ] == 'asc' ?\n\t\t\t\t\t\t\tclasses.sSortAsc : columns[ colIdx ] == 'desc' ?\n\t\t\t\t\t\t\t\tclasses.sSortDesc :\n\t\t\t\t\t\t\t\tcolumn.sSortingClass\n\t\t\t\t\t\t);\n\t\t\t\t} );\n\t\t\t},\n\t\n\t\t\tjqueryui: function ( settings, cell, column, classes ) {\n\t\t\t\t$('<div/>')\n\t\t\t\t\t.addClass( classes.sSortJUIWrapper )\n\t\t\t\t\t.append( cell.contents() )\n\t\t\t\t\t.append( $('<span/>')\n\t\t\t\t\t\t.addClass( classes.sSortIcon+' '+column.sSortingClassJUI )\n\t\t\t\t\t)\n\t\t\t\t\t.appendTo( cell );\n\t\n\t\t\t\t// Attach a sort listener to update on sort\n\t\t\t\t$(settings.nTable).on( 'order.dt.DT', function ( e, ctx, sorting, columns ) {\n\t\t\t\t\tif ( settings !== ctx ) {\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\n\t\t\t\t\tvar colIdx = column.idx;\n\t\n\t\t\t\t\tcell\n\t\t\t\t\t\t.removeClass( classes.sSortAsc +\" \"+classes.sSortDesc )\n\t\t\t\t\t\t.addClass( columns[ colIdx ] == 'asc' ?\n\t\t\t\t\t\t\tclasses.sSortAsc : columns[ colIdx ] == 'desc' ?\n\t\t\t\t\t\t\t\tclasses.sSortDesc :\n\t\t\t\t\t\t\t\tcolumn.sSortingClass\n\t\t\t\t\t\t);\n\t\n\t\t\t\t\tcell\n\t\t\t\t\t\t.find( 'span.'+classes.sSortIcon )\n\t\t\t\t\t\t.removeClass(\n\t\t\t\t\t\t\tclasses.sSortJUIAsc +\" \"+\n\t\t\t\t\t\t\tclasses.sSortJUIDesc +\" \"+\n\t\t\t\t\t\t\tclasses.sSortJUI +\" \"+\n\t\t\t\t\t\t\tclasses.sSortJUIAscAllowed +\" \"+\n\t\t\t\t\t\t\tclasses.sSortJUIDescAllowed\n\t\t\t\t\t\t)\n\t\t\t\t\t\t.addClass( columns[ colIdx ] == 'asc' ?\n\t\t\t\t\t\t\tclasses.sSortJUIAsc : columns[ colIdx ] == 'desc' ?\n\t\t\t\t\t\t\t\tclasses.sSortJUIDesc :\n\t\t\t\t\t\t\t\tcolumn.sSortingClassJUI\n\t\t\t\t\t\t);\n\t\t\t\t} );\n\t\t\t}\n\t\t}\n\t} );\n\t\n\t/*\n\t * Public helper functions. These aren't used internally by DataTables, or\n\t * called by any of the options passed into DataTables, but they can be used\n\t * externally by developers working with DataTables. They are helper functions\n\t * to make working with DataTables a little bit easier.\n\t */\n\t\n\tvar __htmlEscapeEntities = function ( d ) {\n\t\treturn typeof d === 'string' ?\n\t\t\td.replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/\"/g, '&quot;') :\n\t\t\td;\n\t};\n\t\n\t/**\n\t * Helpers for `columns.render`.\n\t *\n\t * The options defined here can be used with the `columns.render` initialisation\n\t * option to provide a display renderer. The following functions are defined:\n\t *\n\t * * `number` - Will format numeric data (defined by `columns.data`) for\n\t *   display, retaining the original unformatted data for sorting and filtering.\n\t *   It takes 5 parameters:\n\t *   * `string` - Thousands grouping separator\n\t *   * `string` - Decimal point indicator\n\t *   * `integer` - Number of decimal points to show\n\t *   * `string` (optional) - Prefix.\n\t *   * `string` (optional) - Postfix (/suffix).\n\t * * `text` - Escape HTML to help prevent XSS attacks. It has no optional\n\t *   parameters.\n\t *\n\t * @example\n\t *   // Column definition using the number renderer\n\t *   {\n\t *     data: \"salary\",\n\t *     render: $.fn.dataTable.render.number( '\\'', '.', 0, '$' )\n\t *   }\n\t *\n\t * @namespace\n\t */\n\tDataTable.render = {\n\t\tnumber: function ( thousands, decimal, precision, prefix, postfix ) {\n\t\t\treturn {\n\t\t\t\tdisplay: function ( d ) {\n\t\t\t\t\tif ( typeof d !== 'number' && typeof d !== 'string' ) {\n\t\t\t\t\t\treturn d;\n\t\t\t\t\t}\n\t\n\t\t\t\t\tvar negative = d < 0 ? '-' : '';\n\t\t\t\t\tvar flo = parseFloat( d );\n\t\n\t\t\t\t\t// If NaN then there isn't much formatting that we can do - just\n\t\t\t\t\t// return immediately, escaping any HTML (this was supposed to\n\t\t\t\t\t// be a number after all)\n\t\t\t\t\tif ( isNaN( flo ) ) {\n\t\t\t\t\t\treturn __htmlEscapeEntities( d );\n\t\t\t\t\t}\n\t\n\t\t\t\t\td = Math.abs( flo );\n\t\n\t\t\t\t\tvar intPart = parseInt( d, 10 );\n\t\t\t\t\tvar floatPart = precision ?\n\t\t\t\t\t\tdecimal+(d - intPart).toFixed( precision ).substring( 2 ):\n\t\t\t\t\t\t'';\n\t\n\t\t\t\t\treturn negative + (prefix||'') +\n\t\t\t\t\t\tintPart.toString().replace(\n\t\t\t\t\t\t\t/\\B(?=(\\d{3})+(?!\\d))/g, thousands\n\t\t\t\t\t\t) +\n\t\t\t\t\t\tfloatPart +\n\t\t\t\t\t\t(postfix||'');\n\t\t\t\t}\n\t\t\t};\n\t\t},\n\t\n\t\ttext: function () {\n\t\t\treturn {\n\t\t\t\tdisplay: __htmlEscapeEntities\n\t\t\t};\n\t\t}\n\t};\n\t\n\t\n\t/*\n\t * This is really a good bit rubbish this method of exposing the internal methods\n\t * publicly... - To be fixed in 2.0 using methods on the prototype\n\t */\n\t\n\t\n\t/**\n\t * Create a wrapper function for exporting an internal functions to an external API.\n\t *  @param {string} fn API function name\n\t *  @returns {function} wrapped function\n\t *  @memberof DataTable#internal\n\t */\n\tfunction _fnExternApiFunc (fn)\n\t{\n\t\treturn function() {\n\t\t\tvar args = [_fnSettingsFromNode( this[DataTable.ext.iApiIndex] )].concat(\n\t\t\t\tArray.prototype.slice.call(arguments)\n\t\t\t);\n\t\t\treturn DataTable.ext.internal[fn].apply( this, args );\n\t\t};\n\t}\n\t\n\t\n\t/**\n\t * Reference to internal functions for use by plug-in developers. Note that\n\t * these methods are references to internal functions and are considered to be\n\t * private. If you use these methods, be aware that they are liable to change\n\t * between versions.\n\t *  @namespace\n\t */\n\t$.extend( DataTable.ext.internal, {\n\t\t_fnExternApiFunc: _fnExternApiFunc,\n\t\t_fnBuildAjax: _fnBuildAjax,\n\t\t_fnAjaxUpdate: _fnAjaxUpdate,\n\t\t_fnAjaxParameters: _fnAjaxParameters,\n\t\t_fnAjaxUpdateDraw: _fnAjaxUpdateDraw,\n\t\t_fnAjaxDataSrc: _fnAjaxDataSrc,\n\t\t_fnAddColumn: _fnAddColumn,\n\t\t_fnColumnOptions: _fnColumnOptions,\n\t\t_fnAdjustColumnSizing: _fnAdjustColumnSizing,\n\t\t_fnVisibleToColumnIndex: _fnVisibleToColumnIndex,\n\t\t_fnColumnIndexToVisible: _fnColumnIndexToVisible,\n\t\t_fnVisbleColumns: _fnVisbleColumns,\n\t\t_fnGetColumns: _fnGetColumns,\n\t\t_fnColumnTypes: _fnColumnTypes,\n\t\t_fnApplyColumnDefs: _fnApplyColumnDefs,\n\t\t_fnHungarianMap: _fnHungarianMap,\n\t\t_fnCamelToHungarian: _fnCamelToHungarian,\n\t\t_fnLanguageCompat: _fnLanguageCompat,\n\t\t_fnBrowserDetect: _fnBrowserDetect,\n\t\t_fnAddData: _fnAddData,\n\t\t_fnAddTr: _fnAddTr,\n\t\t_fnNodeToDataIndex: _fnNodeToDataIndex,\n\t\t_fnNodeToColumnIndex: _fnNodeToColumnIndex,\n\t\t_fnGetCellData: _fnGetCellData,\n\t\t_fnSetCellData: _fnSetCellData,\n\t\t_fnSplitObjNotation: _fnSplitObjNotation,\n\t\t_fnGetObjectDataFn: _fnGetObjectDataFn,\n\t\t_fnSetObjectDataFn: _fnSetObjectDataFn,\n\t\t_fnGetDataMaster: _fnGetDataMaster,\n\t\t_fnClearTable: _fnClearTable,\n\t\t_fnDeleteIndex: _fnDeleteIndex,\n\t\t_fnInvalidate: _fnInvalidate,\n\t\t_fnGetRowElements: _fnGetRowElements,\n\t\t_fnCreateTr: _fnCreateTr,\n\t\t_fnBuildHead: _fnBuildHead,\n\t\t_fnDrawHead: _fnDrawHead,\n\t\t_fnDraw: _fnDraw,\n\t\t_fnReDraw: _fnReDraw,\n\t\t_fnAddOptionsHtml: _fnAddOptionsHtml,\n\t\t_fnDetectHeader: _fnDetectHeader,\n\t\t_fnGetUniqueThs: _fnGetUniqueThs,\n\t\t_fnFeatureHtmlFilter: _fnFeatureHtmlFilter,\n\t\t_fnFilterComplete: _fnFilterComplete,\n\t\t_fnFilterCustom: _fnFilterCustom,\n\t\t_fnFilterColumn: _fnFilterColumn,\n\t\t_fnFilter: _fnFilter,\n\t\t_fnFilterCreateSearch: _fnFilterCreateSearch,\n\t\t_fnEscapeRegex: _fnEscapeRegex,\n\t\t_fnFilterData: _fnFilterData,\n\t\t_fnFeatureHtmlInfo: _fnFeatureHtmlInfo,\n\t\t_fnUpdateInfo: _fnUpdateInfo,\n\t\t_fnInfoMacros: _fnInfoMacros,\n\t\t_fnInitialise: _fnInitialise,\n\t\t_fnInitComplete: _fnInitComplete,\n\t\t_fnLengthChange: _fnLengthChange,\n\t\t_fnFeatureHtmlLength: _fnFeatureHtmlLength,\n\t\t_fnFeatureHtmlPaginate: _fnFeatureHtmlPaginate,\n\t\t_fnPageChange: _fnPageChange,\n\t\t_fnFeatureHtmlProcessing: _fnFeatureHtmlProcessing,\n\t\t_fnProcessingDisplay: _fnProcessingDisplay,\n\t\t_fnFeatureHtmlTable: _fnFeatureHtmlTable,\n\t\t_fnScrollDraw: _fnScrollDraw,\n\t\t_fnApplyToChildren: _fnApplyToChildren,\n\t\t_fnCalculateColumnWidths: _fnCalculateColumnWidths,\n\t\t_fnThrottle: _fnThrottle,\n\t\t_fnConvertToWidth: _fnConvertToWidth,\n\t\t_fnGetWidestNode: _fnGetWidestNode,\n\t\t_fnGetMaxLenString: _fnGetMaxLenString,\n\t\t_fnStringToCss: _fnStringToCss,\n\t\t_fnSortFlatten: _fnSortFlatten,\n\t\t_fnSort: _fnSort,\n\t\t_fnSortAria: _fnSortAria,\n\t\t_fnSortListener: _fnSortListener,\n\t\t_fnSortAttachListener: _fnSortAttachListener,\n\t\t_fnSortingClasses: _fnSortingClasses,\n\t\t_fnSortData: _fnSortData,\n\t\t_fnSaveState: _fnSaveState,\n\t\t_fnLoadState: _fnLoadState,\n\t\t_fnSettingsFromNode: _fnSettingsFromNode,\n\t\t_fnLog: _fnLog,\n\t\t_fnMap: _fnMap,\n\t\t_fnBindAction: _fnBindAction,\n\t\t_fnCallbackReg: _fnCallbackReg,\n\t\t_fnCallbackFire: _fnCallbackFire,\n\t\t_fnLengthOverflow: _fnLengthOverflow,\n\t\t_fnRenderer: _fnRenderer,\n\t\t_fnDataSource: _fnDataSource,\n\t\t_fnRowAttributes: _fnRowAttributes,\n\t\t_fnCalculateEnd: function () {} // Used by a lot of plug-ins, but redundant\n\t\t                                // in 1.10, so this dead-end function is\n\t\t                                // added to prevent errors\n\t} );\n\t\n\n\t// jQuery access\n\t$.fn.dataTable = DataTable;\n\n\t// Provide access to the host jQuery object (circular reference)\n\tDataTable.$ = $;\n\n\t// Legacy aliases\n\t$.fn.dataTableSettings = DataTable.settings;\n\t$.fn.dataTableExt = DataTable.ext;\n\n\t// With a capital `D` we return a DataTables API instance rather than a\n\t// jQuery object\n\t$.fn.DataTable = function ( opts ) {\n\t\treturn $(this).dataTable( opts ).api();\n\t};\n\n\t// All properties that are available to $.fn.dataTable should also be\n\t// available on $.fn.DataTable\n\t$.each( DataTable, function ( prop, val ) {\n\t\t$.fn.DataTable[ prop ] = val;\n\t} );\n\n\n\t// Information about events fired by DataTables - for documentation.\n\t/**\n\t * Draw event, fired whenever the table is redrawn on the page, at the same\n\t * point as fnDrawCallback. This may be useful for binding events or\n\t * performing calculations when the table is altered at all.\n\t *  @name DataTable#draw.dt\n\t *  @event\n\t *  @param {event} e jQuery event object\n\t *  @param {object} o DataTables settings object {@link DataTable.models.oSettings}\n\t */\n\n\t/**\n\t * Search event, fired when the searching applied to the table (using the\n\t * built-in global search, or column filters) is altered.\n\t *  @name DataTable#search.dt\n\t *  @event\n\t *  @param {event} e jQuery event object\n\t *  @param {object} o DataTables settings object {@link DataTable.models.oSettings}\n\t */\n\n\t/**\n\t * Page change event, fired when the paging of the table is altered.\n\t *  @name DataTable#page.dt\n\t *  @event\n\t *  @param {event} e jQuery event object\n\t *  @param {object} o DataTables settings object {@link DataTable.models.oSettings}\n\t */\n\n\t/**\n\t * Order event, fired when the ordering applied to the table is altered.\n\t *  @name DataTable#order.dt\n\t *  @event\n\t *  @param {event} e jQuery event object\n\t *  @param {object} o DataTables settings object {@link DataTable.models.oSettings}\n\t */\n\n\t/**\n\t * DataTables initialisation complete event, fired when the table is fully\n\t * drawn, including Ajax data loaded, if Ajax data is required.\n\t *  @name DataTable#init.dt\n\t *  @event\n\t *  @param {event} e jQuery event object\n\t *  @param {object} oSettings DataTables settings object\n\t *  @param {object} json The JSON object request from the server - only\n\t *    present if client-side Ajax sourced data is used</li></ol>\n\t */\n\n\t/**\n\t * State save event, fired when the table has changed state a new state save\n\t * is required. This event allows modification of the state saving object\n\t * prior to actually doing the save, including addition or other state\n\t * properties (for plug-ins) or modification of a DataTables core property.\n\t *  @name DataTable#stateSaveParams.dt\n\t *  @event\n\t *  @param {event} e jQuery event object\n\t *  @param {object} oSettings DataTables settings object\n\t *  @param {object} json The state information to be saved\n\t */\n\n\t/**\n\t * State load event, fired when the table is loading state from the stored\n\t * data, but prior to the settings object being modified by the saved state\n\t * - allowing modification of the saved state is required or loading of\n\t * state for a plug-in.\n\t *  @name DataTable#stateLoadParams.dt\n\t *  @event\n\t *  @param {event} e jQuery event object\n\t *  @param {object} oSettings DataTables settings object\n\t *  @param {object} json The saved state information\n\t */\n\n\t/**\n\t * State loaded event, fired when state has been loaded from stored data and\n\t * the settings object has been modified by the loaded data.\n\t *  @name DataTable#stateLoaded.dt\n\t *  @event\n\t *  @param {event} e jQuery event object\n\t *  @param {object} oSettings DataTables settings object\n\t *  @param {object} json The saved state information\n\t */\n\n\t/**\n\t * Processing event, fired when DataTables is doing some kind of processing\n\t * (be it, order, searcg or anything else). It can be used to indicate to\n\t * the end user that there is something happening, or that something has\n\t * finished.\n\t *  @name DataTable#processing.dt\n\t *  @event\n\t *  @param {event} e jQuery event object\n\t *  @param {object} oSettings DataTables settings object\n\t *  @param {boolean} bShow Flag for if DataTables is doing processing or not\n\t */\n\n\t/**\n\t * Ajax (XHR) event, fired whenever an Ajax request is completed from a\n\t * request to made to the server for new data. This event is called before\n\t * DataTables processed the returned data, so it can also be used to pre-\n\t * process the data returned from the server, if needed.\n\t *\n\t * Note that this trigger is called in `fnServerData`, if you override\n\t * `fnServerData` and which to use this event, you need to trigger it in you\n\t * success function.\n\t *  @name DataTable#xhr.dt\n\t *  @event\n\t *  @param {event} e jQuery event object\n\t *  @param {object} o DataTables settings object {@link DataTable.models.oSettings}\n\t *  @param {object} json JSON returned from the server\n\t *\n\t *  @example\n\t *     // Use a custom property returned from the server in another DOM element\n\t *     $('#table').dataTable().on('xhr.dt', function (e, settings, json) {\n\t *       $('#status').html( json.status );\n\t *     } );\n\t *\n\t *  @example\n\t *     // Pre-process the data returned from the server\n\t *     $('#table').dataTable().on('xhr.dt', function (e, settings, json) {\n\t *       for ( var i=0, ien=json.aaData.length ; i<ien ; i++ ) {\n\t *         json.aaData[i].sum = json.aaData[i].one + json.aaData[i].two;\n\t *       }\n\t *       // Note no return - manipulate the data directly in the JSON object.\n\t *     } );\n\t */\n\n\t/**\n\t * Destroy event, fired when the DataTable is destroyed by calling fnDestroy\n\t * or passing the bDestroy:true parameter in the initialisation object. This\n\t * can be used to remove bound events, added DOM nodes, etc.\n\t *  @name DataTable#destroy.dt\n\t *  @event\n\t *  @param {event} e jQuery event object\n\t *  @param {object} o DataTables settings object {@link DataTable.models.oSettings}\n\t */\n\n\t/**\n\t * Page length change event, fired when number of records to show on each\n\t * page (the length) is changed.\n\t *  @name DataTable#length.dt\n\t *  @event\n\t *  @param {event} e jQuery event object\n\t *  @param {object} o DataTables settings object {@link DataTable.models.oSettings}\n\t *  @param {integer} len New length\n\t */\n\n\t/**\n\t * Column sizing has changed.\n\t *  @name DataTable#column-sizing.dt\n\t *  @event\n\t *  @param {event} e jQuery event object\n\t *  @param {object} o DataTables settings object {@link DataTable.models.oSettings}\n\t */\n\n\t/**\n\t * Column visibility has changed.\n\t *  @name DataTable#column-visibility.dt\n\t *  @event\n\t *  @param {event} e jQuery event object\n\t *  @param {object} o DataTables settings object {@link DataTable.models.oSettings}\n\t *  @param {int} column Column index\n\t *  @param {bool} vis `false` if column now hidden, or `true` if visible\n\t */\n\n\treturn $.fn.dataTable;\n}));\n"
  },
  {
    "path": "app_backend/vendor/datatables/js/jquery.js",
    "content": "/*! jQuery v1.12.0 | (c) jQuery Foundation | jquery.org/license */\n!function(a,b){\"object\"==typeof module&&\"object\"==typeof module.exports?module.exports=a.document?b(a,!0):function(a){if(!a.document)throw new Error(\"jQuery requires a window with a document\");return b(a)}:b(a)}(\"undefined\"!=typeof window?window:this,function(a,b){var c=[],d=a.document,e=c.slice,f=c.concat,g=c.push,h=c.indexOf,i={},j=i.toString,k=i.hasOwnProperty,l={},m=\"1.12.0\",n=function(a,b){return new n.fn.init(a,b)},o=/^[\\s\\uFEFF\\xA0]+|[\\s\\uFEFF\\xA0]+$/g,p=/^-ms-/,q=/-([\\da-z])/gi,r=function(a,b){return b.toUpperCase()};n.fn=n.prototype={jquery:m,constructor:n,selector:\"\",length:0,toArray:function(){return e.call(this)},get:function(a){return null!=a?0>a?this[a+this.length]:this[a]:e.call(this)},pushStack:function(a){var b=n.merge(this.constructor(),a);return b.prevObject=this,b.context=this.context,b},each:function(a){return n.each(this,a)},map:function(a){return this.pushStack(n.map(this,function(b,c){return a.call(b,c,b)}))},slice:function(){return this.pushStack(e.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},eq:function(a){var b=this.length,c=+a+(0>a?b:0);return this.pushStack(c>=0&&b>c?[this[c]]:[])},end:function(){return this.prevObject||this.constructor()},push:g,sort:c.sort,splice:c.splice},n.extend=n.fn.extend=function(){var a,b,c,d,e,f,g=arguments[0]||{},h=1,i=arguments.length,j=!1;for(\"boolean\"==typeof g&&(j=g,g=arguments[h]||{},h++),\"object\"==typeof g||n.isFunction(g)||(g={}),h===i&&(g=this,h--);i>h;h++)if(null!=(e=arguments[h]))for(d in e)a=g[d],c=e[d],g!==c&&(j&&c&&(n.isPlainObject(c)||(b=n.isArray(c)))?(b?(b=!1,f=a&&n.isArray(a)?a:[]):f=a&&n.isPlainObject(a)?a:{},g[d]=n.extend(j,f,c)):void 0!==c&&(g[d]=c));return g},n.extend({expando:\"jQuery\"+(m+Math.random()).replace(/\\D/g,\"\"),isReady:!0,error:function(a){throw new Error(a)},noop:function(){},isFunction:function(a){return\"function\"===n.type(a)},isArray:Array.isArray||function(a){return\"array\"===n.type(a)},isWindow:function(a){return null!=a&&a==a.window},isNumeric:function(a){var b=a&&a.toString();return!n.isArray(a)&&b-parseFloat(b)+1>=0},isEmptyObject:function(a){var b;for(b in a)return!1;return!0},isPlainObject:function(a){var b;if(!a||\"object\"!==n.type(a)||a.nodeType||n.isWindow(a))return!1;try{if(a.constructor&&!k.call(a,\"constructor\")&&!k.call(a.constructor.prototype,\"isPrototypeOf\"))return!1}catch(c){return!1}if(!l.ownFirst)for(b in a)return k.call(a,b);for(b in a);return void 0===b||k.call(a,b)},type:function(a){return null==a?a+\"\":\"object\"==typeof a||\"function\"==typeof a?i[j.call(a)]||\"object\":typeof a},globalEval:function(b){b&&n.trim(b)&&(a.execScript||function(b){a.eval.call(a,b)})(b)},camelCase:function(a){return a.replace(p,\"ms-\").replace(q,r)},nodeName:function(a,b){return a.nodeName&&a.nodeName.toLowerCase()===b.toLowerCase()},each:function(a,b){var c,d=0;if(s(a)){for(c=a.length;c>d;d++)if(b.call(a[d],d,a[d])===!1)break}else for(d in a)if(b.call(a[d],d,a[d])===!1)break;return a},trim:function(a){return null==a?\"\":(a+\"\").replace(o,\"\")},makeArray:function(a,b){var c=b||[];return null!=a&&(s(Object(a))?n.merge(c,\"string\"==typeof a?[a]:a):g.call(c,a)),c},inArray:function(a,b,c){var d;if(b){if(h)return h.call(b,a,c);for(d=b.length,c=c?0>c?Math.max(0,d+c):c:0;d>c;c++)if(c in b&&b[c]===a)return c}return-1},merge:function(a,b){var c=+b.length,d=0,e=a.length;while(c>d)a[e++]=b[d++];if(c!==c)while(void 0!==b[d])a[e++]=b[d++];return a.length=e,a},grep:function(a,b,c){for(var d,e=[],f=0,g=a.length,h=!c;g>f;f++)d=!b(a[f],f),d!==h&&e.push(a[f]);return e},map:function(a,b,c){var d,e,g=0,h=[];if(s(a))for(d=a.length;d>g;g++)e=b(a[g],g,c),null!=e&&h.push(e);else for(g in a)e=b(a[g],g,c),null!=e&&h.push(e);return f.apply([],h)},guid:1,proxy:function(a,b){var c,d,f;return\"string\"==typeof b&&(f=a[b],b=a,a=f),n.isFunction(a)?(c=e.call(arguments,2),d=function(){return a.apply(b||this,c.concat(e.call(arguments)))},d.guid=a.guid=a.guid||n.guid++,d):void 0},now:function(){return+new Date},support:l}),\"function\"==typeof Symbol&&(n.fn[Symbol.iterator]=c[Symbol.iterator]),n.each(\"Boolean Number String Function Array Date RegExp Object Error Symbol\".split(\" \"),function(a,b){i[\"[object \"+b+\"]\"]=b.toLowerCase()});function s(a){var b=!!a&&\"length\"in a&&a.length,c=n.type(a);return\"function\"===c||n.isWindow(a)?!1:\"array\"===c||0===b||\"number\"==typeof b&&b>0&&b-1 in a}var t=function(a){var b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u=\"sizzle\"+1*new Date,v=a.document,w=0,x=0,y=ga(),z=ga(),A=ga(),B=function(a,b){return a===b&&(l=!0),0},C=1<<31,D={}.hasOwnProperty,E=[],F=E.pop,G=E.push,H=E.push,I=E.slice,J=function(a,b){for(var c=0,d=a.length;d>c;c++)if(a[c]===b)return c;return-1},K=\"checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped\",L=\"[\\\\x20\\\\t\\\\r\\\\n\\\\f]\",M=\"(?:\\\\\\\\.|[\\\\w-]|[^\\\\x00-\\\\xa0])+\",N=\"\\\\[\"+L+\"*(\"+M+\")(?:\"+L+\"*([*^$|!~]?=)\"+L+\"*(?:'((?:\\\\\\\\.|[^\\\\\\\\'])*)'|\\\"((?:\\\\\\\\.|[^\\\\\\\\\\\"])*)\\\"|(\"+M+\"))|)\"+L+\"*\\\\]\",O=\":(\"+M+\")(?:\\\\((('((?:\\\\\\\\.|[^\\\\\\\\'])*)'|\\\"((?:\\\\\\\\.|[^\\\\\\\\\\\"])*)\\\")|((?:\\\\\\\\.|[^\\\\\\\\()[\\\\]]|\"+N+\")*)|.*)\\\\)|)\",P=new RegExp(L+\"+\",\"g\"),Q=new RegExp(\"^\"+L+\"+|((?:^|[^\\\\\\\\])(?:\\\\\\\\.)*)\"+L+\"+$\",\"g\"),R=new RegExp(\"^\"+L+\"*,\"+L+\"*\"),S=new RegExp(\"^\"+L+\"*([>+~]|\"+L+\")\"+L+\"*\"),T=new RegExp(\"=\"+L+\"*([^\\\\]'\\\"]*?)\"+L+\"*\\\\]\",\"g\"),U=new RegExp(O),V=new RegExp(\"^\"+M+\"$\"),W={ID:new RegExp(\"^#(\"+M+\")\"),CLASS:new RegExp(\"^\\\\.(\"+M+\")\"),TAG:new RegExp(\"^(\"+M+\"|[*])\"),ATTR:new RegExp(\"^\"+N),PSEUDO:new RegExp(\"^\"+O),CHILD:new RegExp(\"^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\\\(\"+L+\"*(even|odd|(([+-]|)(\\\\d*)n|)\"+L+\"*(?:([+-]|)\"+L+\"*(\\\\d+)|))\"+L+\"*\\\\)|)\",\"i\"),bool:new RegExp(\"^(?:\"+K+\")$\",\"i\"),needsContext:new RegExp(\"^\"+L+\"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\\\(\"+L+\"*((?:-\\\\d)?\\\\d*)\"+L+\"*\\\\)|)(?=[^-]|$)\",\"i\")},X=/^(?:input|select|textarea|button)$/i,Y=/^h\\d$/i,Z=/^[^{]+\\{\\s*\\[native \\w/,$=/^(?:#([\\w-]+)|(\\w+)|\\.([\\w-]+))$/,_=/[+~]/,aa=/'|\\\\/g,ba=new RegExp(\"\\\\\\\\([\\\\da-f]{1,6}\"+L+\"?|(\"+L+\")|.)\",\"ig\"),ca=function(a,b,c){var d=\"0x\"+b-65536;return d!==d||c?b:0>d?String.fromCharCode(d+65536):String.fromCharCode(d>>10|55296,1023&d|56320)},da=function(){m()};try{H.apply(E=I.call(v.childNodes),v.childNodes),E[v.childNodes.length].nodeType}catch(ea){H={apply:E.length?function(a,b){G.apply(a,I.call(b))}:function(a,b){var c=a.length,d=0;while(a[c++]=b[d++]);a.length=c-1}}}function fa(a,b,d,e){var f,h,j,k,l,o,r,s,w=b&&b.ownerDocument,x=b?b.nodeType:9;if(d=d||[],\"string\"!=typeof a||!a||1!==x&&9!==x&&11!==x)return d;if(!e&&((b?b.ownerDocument||b:v)!==n&&m(b),b=b||n,p)){if(11!==x&&(o=$.exec(a)))if(f=o[1]){if(9===x){if(!(j=b.getElementById(f)))return d;if(j.id===f)return d.push(j),d}else if(w&&(j=w.getElementById(f))&&t(b,j)&&j.id===f)return d.push(j),d}else{if(o[2])return H.apply(d,b.getElementsByTagName(a)),d;if((f=o[3])&&c.getElementsByClassName&&b.getElementsByClassName)return H.apply(d,b.getElementsByClassName(f)),d}if(c.qsa&&!A[a+\" \"]&&(!q||!q.test(a))){if(1!==x)w=b,s=a;else if(\"object\"!==b.nodeName.toLowerCase()){(k=b.getAttribute(\"id\"))?k=k.replace(aa,\"\\\\$&\"):b.setAttribute(\"id\",k=u),r=g(a),h=r.length,l=V.test(k)?\"#\"+k:\"[id='\"+k+\"']\";while(h--)r[h]=l+\" \"+qa(r[h]);s=r.join(\",\"),w=_.test(a)&&oa(b.parentNode)||b}if(s)try{return H.apply(d,w.querySelectorAll(s)),d}catch(y){}finally{k===u&&b.removeAttribute(\"id\")}}}return i(a.replace(Q,\"$1\"),b,d,e)}function ga(){var a=[];function b(c,e){return a.push(c+\" \")>d.cacheLength&&delete b[a.shift()],b[c+\" \"]=e}return b}function ha(a){return a[u]=!0,a}function ia(a){var b=n.createElement(\"div\");try{return!!a(b)}catch(c){return!1}finally{b.parentNode&&b.parentNode.removeChild(b),b=null}}function ja(a,b){var c=a.split(\"|\"),e=c.length;while(e--)d.attrHandle[c[e]]=b}function ka(a,b){var c=b&&a,d=c&&1===a.nodeType&&1===b.nodeType&&(~b.sourceIndex||C)-(~a.sourceIndex||C);if(d)return d;if(c)while(c=c.nextSibling)if(c===b)return-1;return a?1:-1}function la(a){return function(b){var c=b.nodeName.toLowerCase();return\"input\"===c&&b.type===a}}function ma(a){return function(b){var c=b.nodeName.toLowerCase();return(\"input\"===c||\"button\"===c)&&b.type===a}}function na(a){return ha(function(b){return b=+b,ha(function(c,d){var e,f=a([],c.length,b),g=f.length;while(g--)c[e=f[g]]&&(c[e]=!(d[e]=c[e]))})})}function oa(a){return a&&\"undefined\"!=typeof a.getElementsByTagName&&a}c=fa.support={},f=fa.isXML=function(a){var b=a&&(a.ownerDocument||a).documentElement;return b?\"HTML\"!==b.nodeName:!1},m=fa.setDocument=function(a){var b,e,g=a?a.ownerDocument||a:v;return g!==n&&9===g.nodeType&&g.documentElement?(n=g,o=n.documentElement,p=!f(n),(e=n.defaultView)&&e.top!==e&&(e.addEventListener?e.addEventListener(\"unload\",da,!1):e.attachEvent&&e.attachEvent(\"onunload\",da)),c.attributes=ia(function(a){return a.className=\"i\",!a.getAttribute(\"className\")}),c.getElementsByTagName=ia(function(a){return a.appendChild(n.createComment(\"\")),!a.getElementsByTagName(\"*\").length}),c.getElementsByClassName=Z.test(n.getElementsByClassName),c.getById=ia(function(a){return o.appendChild(a).id=u,!n.getElementsByName||!n.getElementsByName(u).length}),c.getById?(d.find.ID=function(a,b){if(\"undefined\"!=typeof b.getElementById&&p){var c=b.getElementById(a);return c?[c]:[]}},d.filter.ID=function(a){var b=a.replace(ba,ca);return function(a){return a.getAttribute(\"id\")===b}}):(delete d.find.ID,d.filter.ID=function(a){var b=a.replace(ba,ca);return function(a){var c=\"undefined\"!=typeof a.getAttributeNode&&a.getAttributeNode(\"id\");return c&&c.value===b}}),d.find.TAG=c.getElementsByTagName?function(a,b){return\"undefined\"!=typeof b.getElementsByTagName?b.getElementsByTagName(a):c.qsa?b.querySelectorAll(a):void 0}:function(a,b){var c,d=[],e=0,f=b.getElementsByTagName(a);if(\"*\"===a){while(c=f[e++])1===c.nodeType&&d.push(c);return d}return f},d.find.CLASS=c.getElementsByClassName&&function(a,b){return\"undefined\"!=typeof b.getElementsByClassName&&p?b.getElementsByClassName(a):void 0},r=[],q=[],(c.qsa=Z.test(n.querySelectorAll))&&(ia(function(a){o.appendChild(a).innerHTML=\"<a id='\"+u+\"'></a><select id='\"+u+\"-\\r\\\\' msallowcapture=''><option selected=''></option></select>\",a.querySelectorAll(\"[msallowcapture^='']\").length&&q.push(\"[*^$]=\"+L+\"*(?:''|\\\"\\\")\"),a.querySelectorAll(\"[selected]\").length||q.push(\"\\\\[\"+L+\"*(?:value|\"+K+\")\"),a.querySelectorAll(\"[id~=\"+u+\"-]\").length||q.push(\"~=\"),a.querySelectorAll(\":checked\").length||q.push(\":checked\"),a.querySelectorAll(\"a#\"+u+\"+*\").length||q.push(\".#.+[+~]\")}),ia(function(a){var b=n.createElement(\"input\");b.setAttribute(\"type\",\"hidden\"),a.appendChild(b).setAttribute(\"name\",\"D\"),a.querySelectorAll(\"[name=d]\").length&&q.push(\"name\"+L+\"*[*^$|!~]?=\"),a.querySelectorAll(\":enabled\").length||q.push(\":enabled\",\":disabled\"),a.querySelectorAll(\"*,:x\"),q.push(\",.*:\")})),(c.matchesSelector=Z.test(s=o.matches||o.webkitMatchesSelector||o.mozMatchesSelector||o.oMatchesSelector||o.msMatchesSelector))&&ia(function(a){c.disconnectedMatch=s.call(a,\"div\"),s.call(a,\"[s!='']:x\"),r.push(\"!=\",O)}),q=q.length&&new RegExp(q.join(\"|\")),r=r.length&&new RegExp(r.join(\"|\")),b=Z.test(o.compareDocumentPosition),t=b||Z.test(o.contains)?function(a,b){var c=9===a.nodeType?a.documentElement:a,d=b&&b.parentNode;return a===d||!(!d||1!==d.nodeType||!(c.contains?c.contains(d):a.compareDocumentPosition&&16&a.compareDocumentPosition(d)))}:function(a,b){if(b)while(b=b.parentNode)if(b===a)return!0;return!1},B=b?function(a,b){if(a===b)return l=!0,0;var d=!a.compareDocumentPosition-!b.compareDocumentPosition;return d?d:(d=(a.ownerDocument||a)===(b.ownerDocument||b)?a.compareDocumentPosition(b):1,1&d||!c.sortDetached&&b.compareDocumentPosition(a)===d?a===n||a.ownerDocument===v&&t(v,a)?-1:b===n||b.ownerDocument===v&&t(v,b)?1:k?J(k,a)-J(k,b):0:4&d?-1:1)}:function(a,b){if(a===b)return l=!0,0;var c,d=0,e=a.parentNode,f=b.parentNode,g=[a],h=[b];if(!e||!f)return a===n?-1:b===n?1:e?-1:f?1:k?J(k,a)-J(k,b):0;if(e===f)return ka(a,b);c=a;while(c=c.parentNode)g.unshift(c);c=b;while(c=c.parentNode)h.unshift(c);while(g[d]===h[d])d++;return d?ka(g[d],h[d]):g[d]===v?-1:h[d]===v?1:0},n):n},fa.matches=function(a,b){return fa(a,null,null,b)},fa.matchesSelector=function(a,b){if((a.ownerDocument||a)!==n&&m(a),b=b.replace(T,\"='$1']\"),c.matchesSelector&&p&&!A[b+\" \"]&&(!r||!r.test(b))&&(!q||!q.test(b)))try{var d=s.call(a,b);if(d||c.disconnectedMatch||a.document&&11!==a.document.nodeType)return d}catch(e){}return fa(b,n,null,[a]).length>0},fa.contains=function(a,b){return(a.ownerDocument||a)!==n&&m(a),t(a,b)},fa.attr=function(a,b){(a.ownerDocument||a)!==n&&m(a);var e=d.attrHandle[b.toLowerCase()],f=e&&D.call(d.attrHandle,b.toLowerCase())?e(a,b,!p):void 0;return void 0!==f?f:c.attributes||!p?a.getAttribute(b):(f=a.getAttributeNode(b))&&f.specified?f.value:null},fa.error=function(a){throw new Error(\"Syntax error, unrecognized expression: \"+a)},fa.uniqueSort=function(a){var b,d=[],e=0,f=0;if(l=!c.detectDuplicates,k=!c.sortStable&&a.slice(0),a.sort(B),l){while(b=a[f++])b===a[f]&&(e=d.push(f));while(e--)a.splice(d[e],1)}return k=null,a},e=fa.getText=function(a){var b,c=\"\",d=0,f=a.nodeType;if(f){if(1===f||9===f||11===f){if(\"string\"==typeof a.textContent)return a.textContent;for(a=a.firstChild;a;a=a.nextSibling)c+=e(a)}else if(3===f||4===f)return a.nodeValue}else while(b=a[d++])c+=e(b);return c},d=fa.selectors={cacheLength:50,createPseudo:ha,match:W,attrHandle:{},find:{},relative:{\">\":{dir:\"parentNode\",first:!0},\" \":{dir:\"parentNode\"},\"+\":{dir:\"previousSibling\",first:!0},\"~\":{dir:\"previousSibling\"}},preFilter:{ATTR:function(a){return a[1]=a[1].replace(ba,ca),a[3]=(a[3]||a[4]||a[5]||\"\").replace(ba,ca),\"~=\"===a[2]&&(a[3]=\" \"+a[3]+\" \"),a.slice(0,4)},CHILD:function(a){return a[1]=a[1].toLowerCase(),\"nth\"===a[1].slice(0,3)?(a[3]||fa.error(a[0]),a[4]=+(a[4]?a[5]+(a[6]||1):2*(\"even\"===a[3]||\"odd\"===a[3])),a[5]=+(a[7]+a[8]||\"odd\"===a[3])):a[3]&&fa.error(a[0]),a},PSEUDO:function(a){var b,c=!a[6]&&a[2];return W.CHILD.test(a[0])?null:(a[3]?a[2]=a[4]||a[5]||\"\":c&&U.test(c)&&(b=g(c,!0))&&(b=c.indexOf(\")\",c.length-b)-c.length)&&(a[0]=a[0].slice(0,b),a[2]=c.slice(0,b)),a.slice(0,3))}},filter:{TAG:function(a){var b=a.replace(ba,ca).toLowerCase();return\"*\"===a?function(){return!0}:function(a){return a.nodeName&&a.nodeName.toLowerCase()===b}},CLASS:function(a){var b=y[a+\" \"];return b||(b=new RegExp(\"(^|\"+L+\")\"+a+\"(\"+L+\"|$)\"))&&y(a,function(a){return b.test(\"string\"==typeof a.className&&a.className||\"undefined\"!=typeof a.getAttribute&&a.getAttribute(\"class\")||\"\")})},ATTR:function(a,b,c){return function(d){var e=fa.attr(d,a);return null==e?\"!=\"===b:b?(e+=\"\",\"=\"===b?e===c:\"!=\"===b?e!==c:\"^=\"===b?c&&0===e.indexOf(c):\"*=\"===b?c&&e.indexOf(c)>-1:\"$=\"===b?c&&e.slice(-c.length)===c:\"~=\"===b?(\" \"+e.replace(P,\" \")+\" \").indexOf(c)>-1:\"|=\"===b?e===c||e.slice(0,c.length+1)===c+\"-\":!1):!0}},CHILD:function(a,b,c,d,e){var f=\"nth\"!==a.slice(0,3),g=\"last\"!==a.slice(-4),h=\"of-type\"===b;return 1===d&&0===e?function(a){return!!a.parentNode}:function(b,c,i){var j,k,l,m,n,o,p=f!==g?\"nextSibling\":\"previousSibling\",q=b.parentNode,r=h&&b.nodeName.toLowerCase(),s=!i&&!h,t=!1;if(q){if(f){while(p){m=b;while(m=m[p])if(h?m.nodeName.toLowerCase()===r:1===m.nodeType)return!1;o=p=\"only\"===a&&!o&&\"nextSibling\"}return!0}if(o=[g?q.firstChild:q.lastChild],g&&s){m=q,l=m[u]||(m[u]={}),k=l[m.uniqueID]||(l[m.uniqueID]={}),j=k[a]||[],n=j[0]===w&&j[1],t=n&&j[2],m=n&&q.childNodes[n];while(m=++n&&m&&m[p]||(t=n=0)||o.pop())if(1===m.nodeType&&++t&&m===b){k[a]=[w,n,t];break}}else if(s&&(m=b,l=m[u]||(m[u]={}),k=l[m.uniqueID]||(l[m.uniqueID]={}),j=k[a]||[],n=j[0]===w&&j[1],t=n),t===!1)while(m=++n&&m&&m[p]||(t=n=0)||o.pop())if((h?m.nodeName.toLowerCase()===r:1===m.nodeType)&&++t&&(s&&(l=m[u]||(m[u]={}),k=l[m.uniqueID]||(l[m.uniqueID]={}),k[a]=[w,t]),m===b))break;return t-=e,t===d||t%d===0&&t/d>=0}}},PSEUDO:function(a,b){var c,e=d.pseudos[a]||d.setFilters[a.toLowerCase()]||fa.error(\"unsupported pseudo: \"+a);return e[u]?e(b):e.length>1?(c=[a,a,\"\",b],d.setFilters.hasOwnProperty(a.toLowerCase())?ha(function(a,c){var d,f=e(a,b),g=f.length;while(g--)d=J(a,f[g]),a[d]=!(c[d]=f[g])}):function(a){return e(a,0,c)}):e}},pseudos:{not:ha(function(a){var b=[],c=[],d=h(a.replace(Q,\"$1\"));return d[u]?ha(function(a,b,c,e){var f,g=d(a,null,e,[]),h=a.length;while(h--)(f=g[h])&&(a[h]=!(b[h]=f))}):function(a,e,f){return b[0]=a,d(b,null,f,c),b[0]=null,!c.pop()}}),has:ha(function(a){return function(b){return fa(a,b).length>0}}),contains:ha(function(a){return a=a.replace(ba,ca),function(b){return(b.textContent||b.innerText||e(b)).indexOf(a)>-1}}),lang:ha(function(a){return V.test(a||\"\")||fa.error(\"unsupported lang: \"+a),a=a.replace(ba,ca).toLowerCase(),function(b){var c;do if(c=p?b.lang:b.getAttribute(\"xml:lang\")||b.getAttribute(\"lang\"))return c=c.toLowerCase(),c===a||0===c.indexOf(a+\"-\");while((b=b.parentNode)&&1===b.nodeType);return!1}}),target:function(b){var c=a.location&&a.location.hash;return c&&c.slice(1)===b.id},root:function(a){return a===o},focus:function(a){return a===n.activeElement&&(!n.hasFocus||n.hasFocus())&&!!(a.type||a.href||~a.tabIndex)},enabled:function(a){return a.disabled===!1},disabled:function(a){return a.disabled===!0},checked:function(a){var b=a.nodeName.toLowerCase();return\"input\"===b&&!!a.checked||\"option\"===b&&!!a.selected},selected:function(a){return a.parentNode&&a.parentNode.selectedIndex,a.selected===!0},empty:function(a){for(a=a.firstChild;a;a=a.nextSibling)if(a.nodeType<6)return!1;return!0},parent:function(a){return!d.pseudos.empty(a)},header:function(a){return Y.test(a.nodeName)},input:function(a){return X.test(a.nodeName)},button:function(a){var b=a.nodeName.toLowerCase();return\"input\"===b&&\"button\"===a.type||\"button\"===b},text:function(a){var b;return\"input\"===a.nodeName.toLowerCase()&&\"text\"===a.type&&(null==(b=a.getAttribute(\"type\"))||\"text\"===b.toLowerCase())},first:na(function(){return[0]}),last:na(function(a,b){return[b-1]}),eq:na(function(a,b,c){return[0>c?c+b:c]}),even:na(function(a,b){for(var c=0;b>c;c+=2)a.push(c);return a}),odd:na(function(a,b){for(var c=1;b>c;c+=2)a.push(c);return a}),lt:na(function(a,b,c){for(var d=0>c?c+b:c;--d>=0;)a.push(d);return a}),gt:na(function(a,b,c){for(var d=0>c?c+b:c;++d<b;)a.push(d);return a})}},d.pseudos.nth=d.pseudos.eq;for(b in{radio:!0,checkbox:!0,file:!0,password:!0,image:!0})d.pseudos[b]=la(b);for(b in{submit:!0,reset:!0})d.pseudos[b]=ma(b);function pa(){}pa.prototype=d.filters=d.pseudos,d.setFilters=new pa,g=fa.tokenize=function(a,b){var c,e,f,g,h,i,j,k=z[a+\" \"];if(k)return b?0:k.slice(0);h=a,i=[],j=d.preFilter;while(h){(!c||(e=R.exec(h)))&&(e&&(h=h.slice(e[0].length)||h),i.push(f=[])),c=!1,(e=S.exec(h))&&(c=e.shift(),f.push({value:c,type:e[0].replace(Q,\" \")}),h=h.slice(c.length));for(g in d.filter)!(e=W[g].exec(h))||j[g]&&!(e=j[g](e))||(c=e.shift(),f.push({value:c,type:g,matches:e}),h=h.slice(c.length));if(!c)break}return b?h.length:h?fa.error(a):z(a,i).slice(0)};function qa(a){for(var b=0,c=a.length,d=\"\";c>b;b++)d+=a[b].value;return d}function ra(a,b,c){var d=b.dir,e=c&&\"parentNode\"===d,f=x++;return b.first?function(b,c,f){while(b=b[d])if(1===b.nodeType||e)return a(b,c,f)}:function(b,c,g){var h,i,j,k=[w,f];if(g){while(b=b[d])if((1===b.nodeType||e)&&a(b,c,g))return!0}else while(b=b[d])if(1===b.nodeType||e){if(j=b[u]||(b[u]={}),i=j[b.uniqueID]||(j[b.uniqueID]={}),(h=i[d])&&h[0]===w&&h[1]===f)return k[2]=h[2];if(i[d]=k,k[2]=a(b,c,g))return!0}}}function sa(a){return a.length>1?function(b,c,d){var e=a.length;while(e--)if(!a[e](b,c,d))return!1;return!0}:a[0]}function ta(a,b,c){for(var d=0,e=b.length;e>d;d++)fa(a,b[d],c);return c}function ua(a,b,c,d,e){for(var f,g=[],h=0,i=a.length,j=null!=b;i>h;h++)(f=a[h])&&(!c||c(f,d,e))&&(g.push(f),j&&b.push(h));return g}function va(a,b,c,d,e,f){return d&&!d[u]&&(d=va(d)),e&&!e[u]&&(e=va(e,f)),ha(function(f,g,h,i){var j,k,l,m=[],n=[],o=g.length,p=f||ta(b||\"*\",h.nodeType?[h]:h,[]),q=!a||!f&&b?p:ua(p,m,a,h,i),r=c?e||(f?a:o||d)?[]:g:q;if(c&&c(q,r,h,i),d){j=ua(r,n),d(j,[],h,i),k=j.length;while(k--)(l=j[k])&&(r[n[k]]=!(q[n[k]]=l))}if(f){if(e||a){if(e){j=[],k=r.length;while(k--)(l=r[k])&&j.push(q[k]=l);e(null,r=[],j,i)}k=r.length;while(k--)(l=r[k])&&(j=e?J(f,l):m[k])>-1&&(f[j]=!(g[j]=l))}}else r=ua(r===g?r.splice(o,r.length):r),e?e(null,g,r,i):H.apply(g,r)})}function wa(a){for(var b,c,e,f=a.length,g=d.relative[a[0].type],h=g||d.relative[\" \"],i=g?1:0,k=ra(function(a){return a===b},h,!0),l=ra(function(a){return J(b,a)>-1},h,!0),m=[function(a,c,d){var e=!g&&(d||c!==j)||((b=c).nodeType?k(a,c,d):l(a,c,d));return b=null,e}];f>i;i++)if(c=d.relative[a[i].type])m=[ra(sa(m),c)];else{if(c=d.filter[a[i].type].apply(null,a[i].matches),c[u]){for(e=++i;f>e;e++)if(d.relative[a[e].type])break;return va(i>1&&sa(m),i>1&&qa(a.slice(0,i-1).concat({value:\" \"===a[i-2].type?\"*\":\"\"})).replace(Q,\"$1\"),c,e>i&&wa(a.slice(i,e)),f>e&&wa(a=a.slice(e)),f>e&&qa(a))}m.push(c)}return sa(m)}function xa(a,b){var c=b.length>0,e=a.length>0,f=function(f,g,h,i,k){var l,o,q,r=0,s=\"0\",t=f&&[],u=[],v=j,x=f||e&&d.find.TAG(\"*\",k),y=w+=null==v?1:Math.random()||.1,z=x.length;for(k&&(j=g===n||g||k);s!==z&&null!=(l=x[s]);s++){if(e&&l){o=0,g||l.ownerDocument===n||(m(l),h=!p);while(q=a[o++])if(q(l,g||n,h)){i.push(l);break}k&&(w=y)}c&&((l=!q&&l)&&r--,f&&t.push(l))}if(r+=s,c&&s!==r){o=0;while(q=b[o++])q(t,u,g,h);if(f){if(r>0)while(s--)t[s]||u[s]||(u[s]=F.call(i));u=ua(u)}H.apply(i,u),k&&!f&&u.length>0&&r+b.length>1&&fa.uniqueSort(i)}return k&&(w=y,j=v),t};return c?ha(f):f}return h=fa.compile=function(a,b){var c,d=[],e=[],f=A[a+\" \"];if(!f){b||(b=g(a)),c=b.length;while(c--)f=wa(b[c]),f[u]?d.push(f):e.push(f);f=A(a,xa(e,d)),f.selector=a}return f},i=fa.select=function(a,b,e,f){var i,j,k,l,m,n=\"function\"==typeof a&&a,o=!f&&g(a=n.selector||a);if(e=e||[],1===o.length){if(j=o[0]=o[0].slice(0),j.length>2&&\"ID\"===(k=j[0]).type&&c.getById&&9===b.nodeType&&p&&d.relative[j[1].type]){if(b=(d.find.ID(k.matches[0].replace(ba,ca),b)||[])[0],!b)return e;n&&(b=b.parentNode),a=a.slice(j.shift().value.length)}i=W.needsContext.test(a)?0:j.length;while(i--){if(k=j[i],d.relative[l=k.type])break;if((m=d.find[l])&&(f=m(k.matches[0].replace(ba,ca),_.test(j[0].type)&&oa(b.parentNode)||b))){if(j.splice(i,1),a=f.length&&qa(j),!a)return H.apply(e,f),e;break}}}return(n||h(a,o))(f,b,!p,e,!b||_.test(a)&&oa(b.parentNode)||b),e},c.sortStable=u.split(\"\").sort(B).join(\"\")===u,c.detectDuplicates=!!l,m(),c.sortDetached=ia(function(a){return 1&a.compareDocumentPosition(n.createElement(\"div\"))}),ia(function(a){return a.innerHTML=\"<a href='#'></a>\",\"#\"===a.firstChild.getAttribute(\"href\")})||ja(\"type|href|height|width\",function(a,b,c){return c?void 0:a.getAttribute(b,\"type\"===b.toLowerCase()?1:2)}),c.attributes&&ia(function(a){return a.innerHTML=\"<input/>\",a.firstChild.setAttribute(\"value\",\"\"),\"\"===a.firstChild.getAttribute(\"value\")})||ja(\"value\",function(a,b,c){return c||\"input\"!==a.nodeName.toLowerCase()?void 0:a.defaultValue}),ia(function(a){return null==a.getAttribute(\"disabled\")})||ja(K,function(a,b,c){var d;return c?void 0:a[b]===!0?b.toLowerCase():(d=a.getAttributeNode(b))&&d.specified?d.value:null}),fa}(a);n.find=t,n.expr=t.selectors,n.expr[\":\"]=n.expr.pseudos,n.uniqueSort=n.unique=t.uniqueSort,n.text=t.getText,n.isXMLDoc=t.isXML,n.contains=t.contains;var u=function(a,b,c){var d=[],e=void 0!==c;while((a=a[b])&&9!==a.nodeType)if(1===a.nodeType){if(e&&n(a).is(c))break;d.push(a)}return d},v=function(a,b){for(var c=[];a;a=a.nextSibling)1===a.nodeType&&a!==b&&c.push(a);return c},w=n.expr.match.needsContext,x=/^<([\\w-]+)\\s*\\/?>(?:<\\/\\1>|)$/,y=/^.[^:#\\[\\.,]*$/;function z(a,b,c){if(n.isFunction(b))return n.grep(a,function(a,d){return!!b.call(a,d,a)!==c});if(b.nodeType)return n.grep(a,function(a){return a===b!==c});if(\"string\"==typeof b){if(y.test(b))return n.filter(b,a,c);b=n.filter(b,a)}return n.grep(a,function(a){return n.inArray(a,b)>-1!==c})}n.filter=function(a,b,c){var d=b[0];return c&&(a=\":not(\"+a+\")\"),1===b.length&&1===d.nodeType?n.find.matchesSelector(d,a)?[d]:[]:n.find.matches(a,n.grep(b,function(a){return 1===a.nodeType}))},n.fn.extend({find:function(a){var b,c=[],d=this,e=d.length;if(\"string\"!=typeof a)return this.pushStack(n(a).filter(function(){for(b=0;e>b;b++)if(n.contains(d[b],this))return!0}));for(b=0;e>b;b++)n.find(a,d[b],c);return c=this.pushStack(e>1?n.unique(c):c),c.selector=this.selector?this.selector+\" \"+a:a,c},filter:function(a){return this.pushStack(z(this,a||[],!1))},not:function(a){return this.pushStack(z(this,a||[],!0))},is:function(a){return!!z(this,\"string\"==typeof a&&w.test(a)?n(a):a||[],!1).length}});var A,B=/^(?:\\s*(<[\\w\\W]+>)[^>]*|#([\\w-]*))$/,C=n.fn.init=function(a,b,c){var e,f;if(!a)return this;if(c=c||A,\"string\"==typeof a){if(e=\"<\"===a.charAt(0)&&\">\"===a.charAt(a.length-1)&&a.length>=3?[null,a,null]:B.exec(a),!e||!e[1]&&b)return!b||b.jquery?(b||c).find(a):this.constructor(b).find(a);if(e[1]){if(b=b instanceof n?b[0]:b,n.merge(this,n.parseHTML(e[1],b&&b.nodeType?b.ownerDocument||b:d,!0)),x.test(e[1])&&n.isPlainObject(b))for(e in b)n.isFunction(this[e])?this[e](b[e]):this.attr(e,b[e]);return this}if(f=d.getElementById(e[2]),f&&f.parentNode){if(f.id!==e[2])return A.find(a);this.length=1,this[0]=f}return this.context=d,this.selector=a,this}return a.nodeType?(this.context=this[0]=a,this.length=1,this):n.isFunction(a)?\"undefined\"!=typeof c.ready?c.ready(a):a(n):(void 0!==a.selector&&(this.selector=a.selector,this.context=a.context),n.makeArray(a,this))};C.prototype=n.fn,A=n(d);var D=/^(?:parents|prev(?:Until|All))/,E={children:!0,contents:!0,next:!0,prev:!0};n.fn.extend({has:function(a){var b,c=n(a,this),d=c.length;return this.filter(function(){for(b=0;d>b;b++)if(n.contains(this,c[b]))return!0})},closest:function(a,b){for(var c,d=0,e=this.length,f=[],g=w.test(a)||\"string\"!=typeof a?n(a,b||this.context):0;e>d;d++)for(c=this[d];c&&c!==b;c=c.parentNode)if(c.nodeType<11&&(g?g.index(c)>-1:1===c.nodeType&&n.find.matchesSelector(c,a))){f.push(c);break}return this.pushStack(f.length>1?n.uniqueSort(f):f)},index:function(a){return a?\"string\"==typeof a?n.inArray(this[0],n(a)):n.inArray(a.jquery?a[0]:a,this):this[0]&&this[0].parentNode?this.first().prevAll().length:-1},add:function(a,b){return this.pushStack(n.uniqueSort(n.merge(this.get(),n(a,b))))},addBack:function(a){return this.add(null==a?this.prevObject:this.prevObject.filter(a))}});function F(a,b){do a=a[b];while(a&&1!==a.nodeType);return a}n.each({parent:function(a){var b=a.parentNode;return b&&11!==b.nodeType?b:null},parents:function(a){return u(a,\"parentNode\")},parentsUntil:function(a,b,c){return u(a,\"parentNode\",c)},next:function(a){return F(a,\"nextSibling\")},prev:function(a){return F(a,\"previousSibling\")},nextAll:function(a){return u(a,\"nextSibling\")},prevAll:function(a){return u(a,\"previousSibling\")},nextUntil:function(a,b,c){return u(a,\"nextSibling\",c)},prevUntil:function(a,b,c){return u(a,\"previousSibling\",c)},siblings:function(a){return v((a.parentNode||{}).firstChild,a)},children:function(a){return v(a.firstChild)},contents:function(a){return n.nodeName(a,\"iframe\")?a.contentDocument||a.contentWindow.document:n.merge([],a.childNodes)}},function(a,b){n.fn[a]=function(c,d){var e=n.map(this,b,c);return\"Until\"!==a.slice(-5)&&(d=c),d&&\"string\"==typeof d&&(e=n.filter(d,e)),this.length>1&&(E[a]||(e=n.uniqueSort(e)),D.test(a)&&(e=e.reverse())),this.pushStack(e)}});var G=/\\S+/g;function H(a){var b={};return n.each(a.match(G)||[],function(a,c){b[c]=!0}),b}n.Callbacks=function(a){a=\"string\"==typeof a?H(a):n.extend({},a);var b,c,d,e,f=[],g=[],h=-1,i=function(){for(e=a.once,d=b=!0;g.length;h=-1){c=g.shift();while(++h<f.length)f[h].apply(c[0],c[1])===!1&&a.stopOnFalse&&(h=f.length,c=!1)}a.memory||(c=!1),b=!1,e&&(f=c?[]:\"\")},j={add:function(){return f&&(c&&!b&&(h=f.length-1,g.push(c)),function d(b){n.each(b,function(b,c){n.isFunction(c)?a.unique&&j.has(c)||f.push(c):c&&c.length&&\"string\"!==n.type(c)&&d(c)})}(arguments),c&&!b&&i()),this},remove:function(){return n.each(arguments,function(a,b){var c;while((c=n.inArray(b,f,c))>-1)f.splice(c,1),h>=c&&h--}),this},has:function(a){return a?n.inArray(a,f)>-1:f.length>0},empty:function(){return f&&(f=[]),this},disable:function(){return e=g=[],f=c=\"\",this},disabled:function(){return!f},lock:function(){return e=!0,c||j.disable(),this},locked:function(){return!!e},fireWith:function(a,c){return e||(c=c||[],c=[a,c.slice?c.slice():c],g.push(c),b||i()),this},fire:function(){return j.fireWith(this,arguments),this},fired:function(){return!!d}};return j},n.extend({Deferred:function(a){var b=[[\"resolve\",\"done\",n.Callbacks(\"once memory\"),\"resolved\"],[\"reject\",\"fail\",n.Callbacks(\"once memory\"),\"rejected\"],[\"notify\",\"progress\",n.Callbacks(\"memory\")]],c=\"pending\",d={state:function(){return c},always:function(){return e.done(arguments).fail(arguments),this},then:function(){var a=arguments;return n.Deferred(function(c){n.each(b,function(b,f){var g=n.isFunction(a[b])&&a[b];e[f[1]](function(){var a=g&&g.apply(this,arguments);a&&n.isFunction(a.promise)?a.promise().progress(c.notify).done(c.resolve).fail(c.reject):c[f[0]+\"With\"](this===d?c.promise():this,g?[a]:arguments)})}),a=null}).promise()},promise:function(a){return null!=a?n.extend(a,d):d}},e={};return d.pipe=d.then,n.each(b,function(a,f){var g=f[2],h=f[3];d[f[1]]=g.add,h&&g.add(function(){c=h},b[1^a][2].disable,b[2][2].lock),e[f[0]]=function(){return e[f[0]+\"With\"](this===e?d:this,arguments),this},e[f[0]+\"With\"]=g.fireWith}),d.promise(e),a&&a.call(e,e),e},when:function(a){var b=0,c=e.call(arguments),d=c.length,f=1!==d||a&&n.isFunction(a.promise)?d:0,g=1===f?a:n.Deferred(),h=function(a,b,c){return function(d){b[a]=this,c[a]=arguments.length>1?e.call(arguments):d,c===i?g.notifyWith(b,c):--f||g.resolveWith(b,c)}},i,j,k;if(d>1)for(i=new Array(d),j=new Array(d),k=new Array(d);d>b;b++)c[b]&&n.isFunction(c[b].promise)?c[b].promise().progress(h(b,j,i)).done(h(b,k,c)).fail(g.reject):--f;return f||g.resolveWith(k,c),g.promise()}});var I;n.fn.ready=function(a){return n.ready.promise().done(a),this},n.extend({isReady:!1,readyWait:1,holdReady:function(a){a?n.readyWait++:n.ready(!0)},ready:function(a){(a===!0?--n.readyWait:n.isReady)||(n.isReady=!0,a!==!0&&--n.readyWait>0||(I.resolveWith(d,[n]),n.fn.triggerHandler&&(n(d).triggerHandler(\"ready\"),n(d).off(\"ready\"))))}});function J(){d.addEventListener?(d.removeEventListener(\"DOMContentLoaded\",K),a.removeEventListener(\"load\",K)):(d.detachEvent(\"onreadystatechange\",K),a.detachEvent(\"onload\",K))}function K(){(d.addEventListener||\"load\"===a.event.type||\"complete\"===d.readyState)&&(J(),n.ready())}n.ready.promise=function(b){if(!I)if(I=n.Deferred(),\"complete\"===d.readyState)a.setTimeout(n.ready);else if(d.addEventListener)d.addEventListener(\"DOMContentLoaded\",K),a.addEventListener(\"load\",K);else{d.attachEvent(\"onreadystatechange\",K),a.attachEvent(\"onload\",K);var c=!1;try{c=null==a.frameElement&&d.documentElement}catch(e){}c&&c.doScroll&&!function f(){if(!n.isReady){try{c.doScroll(\"left\")}catch(b){return a.setTimeout(f,50)}J(),n.ready()}}()}return I.promise(b)},n.ready.promise();var L;for(L in n(l))break;l.ownFirst=\"0\"===L,l.inlineBlockNeedsLayout=!1,n(function(){var a,b,c,e;c=d.getElementsByTagName(\"body\")[0],c&&c.style&&(b=d.createElement(\"div\"),e=d.createElement(\"div\"),e.style.cssText=\"position:absolute;border:0;width:0;height:0;top:0;left:-9999px\",c.appendChild(e).appendChild(b),\"undefined\"!=typeof b.style.zoom&&(b.style.cssText=\"display:inline;margin:0;border:0;padding:1px;width:1px;zoom:1\",l.inlineBlockNeedsLayout=a=3===b.offsetWidth,a&&(c.style.zoom=1)),c.removeChild(e))}),function(){var a=d.createElement(\"div\");l.deleteExpando=!0;try{delete a.test}catch(b){l.deleteExpando=!1}a=null}();var M=function(a){var b=n.noData[(a.nodeName+\" \").toLowerCase()],c=+a.nodeType||1;return 1!==c&&9!==c?!1:!b||b!==!0&&a.getAttribute(\"classid\")===b},N=/^(?:\\{[\\w\\W]*\\}|\\[[\\w\\W]*\\])$/,O=/([A-Z])/g;function P(a,b,c){if(void 0===c&&1===a.nodeType){var d=\"data-\"+b.replace(O,\"-$1\").toLowerCase();if(c=a.getAttribute(d),\"string\"==typeof c){try{c=\"true\"===c?!0:\"false\"===c?!1:\"null\"===c?null:+c+\"\"===c?+c:N.test(c)?n.parseJSON(c):c}catch(e){}n.data(a,b,c)}else c=void 0}return c}function Q(a){var b;for(b in a)if((\"data\"!==b||!n.isEmptyObject(a[b]))&&\"toJSON\"!==b)return!1;\nreturn!0}function R(a,b,d,e){if(M(a)){var f,g,h=n.expando,i=a.nodeType,j=i?n.cache:a,k=i?a[h]:a[h]&&h;if(k&&j[k]&&(e||j[k].data)||void 0!==d||\"string\"!=typeof b)return k||(k=i?a[h]=c.pop()||n.guid++:h),j[k]||(j[k]=i?{}:{toJSON:n.noop}),(\"object\"==typeof b||\"function\"==typeof b)&&(e?j[k]=n.extend(j[k],b):j[k].data=n.extend(j[k].data,b)),g=j[k],e||(g.data||(g.data={}),g=g.data),void 0!==d&&(g[n.camelCase(b)]=d),\"string\"==typeof b?(f=g[b],null==f&&(f=g[n.camelCase(b)])):f=g,f}}function S(a,b,c){if(M(a)){var d,e,f=a.nodeType,g=f?n.cache:a,h=f?a[n.expando]:n.expando;if(g[h]){if(b&&(d=c?g[h]:g[h].data)){n.isArray(b)?b=b.concat(n.map(b,n.camelCase)):b in d?b=[b]:(b=n.camelCase(b),b=b in d?[b]:b.split(\" \")),e=b.length;while(e--)delete d[b[e]];if(c?!Q(d):!n.isEmptyObject(d))return}(c||(delete g[h].data,Q(g[h])))&&(f?n.cleanData([a],!0):l.deleteExpando||g!=g.window?delete g[h]:g[h]=void 0)}}}n.extend({cache:{},noData:{\"applet \":!0,\"embed \":!0,\"object \":\"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000\"},hasData:function(a){return a=a.nodeType?n.cache[a[n.expando]]:a[n.expando],!!a&&!Q(a)},data:function(a,b,c){return R(a,b,c)},removeData:function(a,b){return S(a,b)},_data:function(a,b,c){return R(a,b,c,!0)},_removeData:function(a,b){return S(a,b,!0)}}),n.fn.extend({data:function(a,b){var c,d,e,f=this[0],g=f&&f.attributes;if(void 0===a){if(this.length&&(e=n.data(f),1===f.nodeType&&!n._data(f,\"parsedAttrs\"))){c=g.length;while(c--)g[c]&&(d=g[c].name,0===d.indexOf(\"data-\")&&(d=n.camelCase(d.slice(5)),P(f,d,e[d])));n._data(f,\"parsedAttrs\",!0)}return e}return\"object\"==typeof a?this.each(function(){n.data(this,a)}):arguments.length>1?this.each(function(){n.data(this,a,b)}):f?P(f,a,n.data(f,a)):void 0},removeData:function(a){return this.each(function(){n.removeData(this,a)})}}),n.extend({queue:function(a,b,c){var d;return a?(b=(b||\"fx\")+\"queue\",d=n._data(a,b),c&&(!d||n.isArray(c)?d=n._data(a,b,n.makeArray(c)):d.push(c)),d||[]):void 0},dequeue:function(a,b){b=b||\"fx\";var c=n.queue(a,b),d=c.length,e=c.shift(),f=n._queueHooks(a,b),g=function(){n.dequeue(a,b)};\"inprogress\"===e&&(e=c.shift(),d--),e&&(\"fx\"===b&&c.unshift(\"inprogress\"),delete f.stop,e.call(a,g,f)),!d&&f&&f.empty.fire()},_queueHooks:function(a,b){var c=b+\"queueHooks\";return n._data(a,c)||n._data(a,c,{empty:n.Callbacks(\"once memory\").add(function(){n._removeData(a,b+\"queue\"),n._removeData(a,c)})})}}),n.fn.extend({queue:function(a,b){var c=2;return\"string\"!=typeof a&&(b=a,a=\"fx\",c--),arguments.length<c?n.queue(this[0],a):void 0===b?this:this.each(function(){var c=n.queue(this,a,b);n._queueHooks(this,a),\"fx\"===a&&\"inprogress\"!==c[0]&&n.dequeue(this,a)})},dequeue:function(a){return this.each(function(){n.dequeue(this,a)})},clearQueue:function(a){return this.queue(a||\"fx\",[])},promise:function(a,b){var c,d=1,e=n.Deferred(),f=this,g=this.length,h=function(){--d||e.resolveWith(f,[f])};\"string\"!=typeof a&&(b=a,a=void 0),a=a||\"fx\";while(g--)c=n._data(f[g],a+\"queueHooks\"),c&&c.empty&&(d++,c.empty.add(h));return h(),e.promise(b)}}),function(){var a;l.shrinkWrapBlocks=function(){if(null!=a)return a;a=!1;var b,c,e;return c=d.getElementsByTagName(\"body\")[0],c&&c.style?(b=d.createElement(\"div\"),e=d.createElement(\"div\"),e.style.cssText=\"position:absolute;border:0;width:0;height:0;top:0;left:-9999px\",c.appendChild(e).appendChild(b),\"undefined\"!=typeof b.style.zoom&&(b.style.cssText=\"-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box;display:block;margin:0;border:0;padding:1px;width:1px;zoom:1\",b.appendChild(d.createElement(\"div\")).style.width=\"5px\",a=3!==b.offsetWidth),c.removeChild(e),a):void 0}}();var T=/[+-]?(?:\\d*\\.|)\\d+(?:[eE][+-]?\\d+|)/.source,U=new RegExp(\"^(?:([+-])=|)(\"+T+\")([a-z%]*)$\",\"i\"),V=[\"Top\",\"Right\",\"Bottom\",\"Left\"],W=function(a,b){return a=b||a,\"none\"===n.css(a,\"display\")||!n.contains(a.ownerDocument,a)};function X(a,b,c,d){var e,f=1,g=20,h=d?function(){return d.cur()}:function(){return n.css(a,b,\"\")},i=h(),j=c&&c[3]||(n.cssNumber[b]?\"\":\"px\"),k=(n.cssNumber[b]||\"px\"!==j&&+i)&&U.exec(n.css(a,b));if(k&&k[3]!==j){j=j||k[3],c=c||[],k=+i||1;do f=f||\".5\",k/=f,n.style(a,b,k+j);while(f!==(f=h()/i)&&1!==f&&--g)}return c&&(k=+k||+i||0,e=c[1]?k+(c[1]+1)*c[2]:+c[2],d&&(d.unit=j,d.start=k,d.end=e)),e}var Y=function(a,b,c,d,e,f,g){var h=0,i=a.length,j=null==c;if(\"object\"===n.type(c)){e=!0;for(h in c)Y(a,b,h,c[h],!0,f,g)}else if(void 0!==d&&(e=!0,n.isFunction(d)||(g=!0),j&&(g?(b.call(a,d),b=null):(j=b,b=function(a,b,c){return j.call(n(a),c)})),b))for(;i>h;h++)b(a[h],c,g?d:d.call(a[h],h,b(a[h],c)));return e?a:j?b.call(a):i?b(a[0],c):f},Z=/^(?:checkbox|radio)$/i,$=/<([\\w:-]+)/,_=/^$|\\/(?:java|ecma)script/i,aa=/^\\s+/,ba=\"abbr|article|aside|audio|bdi|canvas|data|datalist|details|dialog|figcaption|figure|footer|header|hgroup|main|mark|meter|nav|output|picture|progress|section|summary|template|time|video\";function ca(a){var b=ba.split(\"|\"),c=a.createDocumentFragment();if(c.createElement)while(b.length)c.createElement(b.pop());return c}!function(){var a=d.createElement(\"div\"),b=d.createDocumentFragment(),c=d.createElement(\"input\");a.innerHTML=\"  <link/><table></table><a href='/a'>a</a><input type='checkbox'/>\",l.leadingWhitespace=3===a.firstChild.nodeType,l.tbody=!a.getElementsByTagName(\"tbody\").length,l.htmlSerialize=!!a.getElementsByTagName(\"link\").length,l.html5Clone=\"<:nav></:nav>\"!==d.createElement(\"nav\").cloneNode(!0).outerHTML,c.type=\"checkbox\",c.checked=!0,b.appendChild(c),l.appendChecked=c.checked,a.innerHTML=\"<textarea>x</textarea>\",l.noCloneChecked=!!a.cloneNode(!0).lastChild.defaultValue,b.appendChild(a),c=d.createElement(\"input\"),c.setAttribute(\"type\",\"radio\"),c.setAttribute(\"checked\",\"checked\"),c.setAttribute(\"name\",\"t\"),a.appendChild(c),l.checkClone=a.cloneNode(!0).cloneNode(!0).lastChild.checked,l.noCloneEvent=!!a.addEventListener,a[n.expando]=1,l.attributes=!a.getAttribute(n.expando)}();var da={option:[1,\"<select multiple='multiple'>\",\"</select>\"],legend:[1,\"<fieldset>\",\"</fieldset>\"],area:[1,\"<map>\",\"</map>\"],param:[1,\"<object>\",\"</object>\"],thead:[1,\"<table>\",\"</table>\"],tr:[2,\"<table><tbody>\",\"</tbody></table>\"],col:[2,\"<table><tbody></tbody><colgroup>\",\"</colgroup></table>\"],td:[3,\"<table><tbody><tr>\",\"</tr></tbody></table>\"],_default:l.htmlSerialize?[0,\"\",\"\"]:[1,\"X<div>\",\"</div>\"]};da.optgroup=da.option,da.tbody=da.tfoot=da.colgroup=da.caption=da.thead,da.th=da.td;function ea(a,b){var c,d,e=0,f=\"undefined\"!=typeof a.getElementsByTagName?a.getElementsByTagName(b||\"*\"):\"undefined\"!=typeof a.querySelectorAll?a.querySelectorAll(b||\"*\"):void 0;if(!f)for(f=[],c=a.childNodes||a;null!=(d=c[e]);e++)!b||n.nodeName(d,b)?f.push(d):n.merge(f,ea(d,b));return void 0===b||b&&n.nodeName(a,b)?n.merge([a],f):f}function fa(a,b){for(var c,d=0;null!=(c=a[d]);d++)n._data(c,\"globalEval\",!b||n._data(b[d],\"globalEval\"))}var ga=/<|&#?\\w+;/,ha=/<tbody/i;function ia(a){Z.test(a.type)&&(a.defaultChecked=a.checked)}function ja(a,b,c,d,e){for(var f,g,h,i,j,k,m,o=a.length,p=ca(b),q=[],r=0;o>r;r++)if(g=a[r],g||0===g)if(\"object\"===n.type(g))n.merge(q,g.nodeType?[g]:g);else if(ga.test(g)){i=i||p.appendChild(b.createElement(\"div\")),j=($.exec(g)||[\"\",\"\"])[1].toLowerCase(),m=da[j]||da._default,i.innerHTML=m[1]+n.htmlPrefilter(g)+m[2],f=m[0];while(f--)i=i.lastChild;if(!l.leadingWhitespace&&aa.test(g)&&q.push(b.createTextNode(aa.exec(g)[0])),!l.tbody){g=\"table\"!==j||ha.test(g)?\"<table>\"!==m[1]||ha.test(g)?0:i:i.firstChild,f=g&&g.childNodes.length;while(f--)n.nodeName(k=g.childNodes[f],\"tbody\")&&!k.childNodes.length&&g.removeChild(k)}n.merge(q,i.childNodes),i.textContent=\"\";while(i.firstChild)i.removeChild(i.firstChild);i=p.lastChild}else q.push(b.createTextNode(g));i&&p.removeChild(i),l.appendChecked||n.grep(ea(q,\"input\"),ia),r=0;while(g=q[r++])if(d&&n.inArray(g,d)>-1)e&&e.push(g);else if(h=n.contains(g.ownerDocument,g),i=ea(p.appendChild(g),\"script\"),h&&fa(i),c){f=0;while(g=i[f++])_.test(g.type||\"\")&&c.push(g)}return i=null,p}!function(){var b,c,e=d.createElement(\"div\");for(b in{submit:!0,change:!0,focusin:!0})c=\"on\"+b,(l[b]=c in a)||(e.setAttribute(c,\"t\"),l[b]=e.attributes[c].expando===!1);e=null}();var ka=/^(?:input|select|textarea)$/i,la=/^key/,ma=/^(?:mouse|pointer|contextmenu|drag|drop)|click/,na=/^(?:focusinfocus|focusoutblur)$/,oa=/^([^.]*)(?:\\.(.+)|)/;function pa(){return!0}function qa(){return!1}function ra(){try{return d.activeElement}catch(a){}}function sa(a,b,c,d,e,f){var g,h;if(\"object\"==typeof b){\"string\"!=typeof c&&(d=d||c,c=void 0);for(h in b)sa(a,h,c,d,b[h],f);return a}if(null==d&&null==e?(e=c,d=c=void 0):null==e&&(\"string\"==typeof c?(e=d,d=void 0):(e=d,d=c,c=void 0)),e===!1)e=qa;else if(!e)return a;return 1===f&&(g=e,e=function(a){return n().off(a),g.apply(this,arguments)},e.guid=g.guid||(g.guid=n.guid++)),a.each(function(){n.event.add(this,b,e,d,c)})}n.event={global:{},add:function(a,b,c,d,e){var f,g,h,i,j,k,l,m,o,p,q,r=n._data(a);if(r){c.handler&&(i=c,c=i.handler,e=i.selector),c.guid||(c.guid=n.guid++),(g=r.events)||(g=r.events={}),(k=r.handle)||(k=r.handle=function(a){return\"undefined\"==typeof n||a&&n.event.triggered===a.type?void 0:n.event.dispatch.apply(k.elem,arguments)},k.elem=a),b=(b||\"\").match(G)||[\"\"],h=b.length;while(h--)f=oa.exec(b[h])||[],o=q=f[1],p=(f[2]||\"\").split(\".\").sort(),o&&(j=n.event.special[o]||{},o=(e?j.delegateType:j.bindType)||o,j=n.event.special[o]||{},l=n.extend({type:o,origType:q,data:d,handler:c,guid:c.guid,selector:e,needsContext:e&&n.expr.match.needsContext.test(e),namespace:p.join(\".\")},i),(m=g[o])||(m=g[o]=[],m.delegateCount=0,j.setup&&j.setup.call(a,d,p,k)!==!1||(a.addEventListener?a.addEventListener(o,k,!1):a.attachEvent&&a.attachEvent(\"on\"+o,k))),j.add&&(j.add.call(a,l),l.handler.guid||(l.handler.guid=c.guid)),e?m.splice(m.delegateCount++,0,l):m.push(l),n.event.global[o]=!0);a=null}},remove:function(a,b,c,d,e){var f,g,h,i,j,k,l,m,o,p,q,r=n.hasData(a)&&n._data(a);if(r&&(k=r.events)){b=(b||\"\").match(G)||[\"\"],j=b.length;while(j--)if(h=oa.exec(b[j])||[],o=q=h[1],p=(h[2]||\"\").split(\".\").sort(),o){l=n.event.special[o]||{},o=(d?l.delegateType:l.bindType)||o,m=k[o]||[],h=h[2]&&new RegExp(\"(^|\\\\.)\"+p.join(\"\\\\.(?:.*\\\\.|)\")+\"(\\\\.|$)\"),i=f=m.length;while(f--)g=m[f],!e&&q!==g.origType||c&&c.guid!==g.guid||h&&!h.test(g.namespace)||d&&d!==g.selector&&(\"**\"!==d||!g.selector)||(m.splice(f,1),g.selector&&m.delegateCount--,l.remove&&l.remove.call(a,g));i&&!m.length&&(l.teardown&&l.teardown.call(a,p,r.handle)!==!1||n.removeEvent(a,o,r.handle),delete k[o])}else for(o in k)n.event.remove(a,o+b[j],c,d,!0);n.isEmptyObject(k)&&(delete r.handle,n._removeData(a,\"events\"))}},trigger:function(b,c,e,f){var g,h,i,j,l,m,o,p=[e||d],q=k.call(b,\"type\")?b.type:b,r=k.call(b,\"namespace\")?b.namespace.split(\".\"):[];if(i=m=e=e||d,3!==e.nodeType&&8!==e.nodeType&&!na.test(q+n.event.triggered)&&(q.indexOf(\".\")>-1&&(r=q.split(\".\"),q=r.shift(),r.sort()),h=q.indexOf(\":\")<0&&\"on\"+q,b=b[n.expando]?b:new n.Event(q,\"object\"==typeof b&&b),b.isTrigger=f?2:3,b.namespace=r.join(\".\"),b.rnamespace=b.namespace?new RegExp(\"(^|\\\\.)\"+r.join(\"\\\\.(?:.*\\\\.|)\")+\"(\\\\.|$)\"):null,b.result=void 0,b.target||(b.target=e),c=null==c?[b]:n.makeArray(c,[b]),l=n.event.special[q]||{},f||!l.trigger||l.trigger.apply(e,c)!==!1)){if(!f&&!l.noBubble&&!n.isWindow(e)){for(j=l.delegateType||q,na.test(j+q)||(i=i.parentNode);i;i=i.parentNode)p.push(i),m=i;m===(e.ownerDocument||d)&&p.push(m.defaultView||m.parentWindow||a)}o=0;while((i=p[o++])&&!b.isPropagationStopped())b.type=o>1?j:l.bindType||q,g=(n._data(i,\"events\")||{})[b.type]&&n._data(i,\"handle\"),g&&g.apply(i,c),g=h&&i[h],g&&g.apply&&M(i)&&(b.result=g.apply(i,c),b.result===!1&&b.preventDefault());if(b.type=q,!f&&!b.isDefaultPrevented()&&(!l._default||l._default.apply(p.pop(),c)===!1)&&M(e)&&h&&e[q]&&!n.isWindow(e)){m=e[h],m&&(e[h]=null),n.event.triggered=q;try{e[q]()}catch(s){}n.event.triggered=void 0,m&&(e[h]=m)}return b.result}},dispatch:function(a){a=n.event.fix(a);var b,c,d,f,g,h=[],i=e.call(arguments),j=(n._data(this,\"events\")||{})[a.type]||[],k=n.event.special[a.type]||{};if(i[0]=a,a.delegateTarget=this,!k.preDispatch||k.preDispatch.call(this,a)!==!1){h=n.event.handlers.call(this,a,j),b=0;while((f=h[b++])&&!a.isPropagationStopped()){a.currentTarget=f.elem,c=0;while((g=f.handlers[c++])&&!a.isImmediatePropagationStopped())(!a.rnamespace||a.rnamespace.test(g.namespace))&&(a.handleObj=g,a.data=g.data,d=((n.event.special[g.origType]||{}).handle||g.handler).apply(f.elem,i),void 0!==d&&(a.result=d)===!1&&(a.preventDefault(),a.stopPropagation()))}return k.postDispatch&&k.postDispatch.call(this,a),a.result}},handlers:function(a,b){var c,d,e,f,g=[],h=b.delegateCount,i=a.target;if(h&&i.nodeType&&(\"click\"!==a.type||isNaN(a.button)||a.button<1))for(;i!=this;i=i.parentNode||this)if(1===i.nodeType&&(i.disabled!==!0||\"click\"!==a.type)){for(d=[],c=0;h>c;c++)f=b[c],e=f.selector+\" \",void 0===d[e]&&(d[e]=f.needsContext?n(e,this).index(i)>-1:n.find(e,this,null,[i]).length),d[e]&&d.push(f);d.length&&g.push({elem:i,handlers:d})}return h<b.length&&g.push({elem:this,handlers:b.slice(h)}),g},fix:function(a){if(a[n.expando])return a;var b,c,e,f=a.type,g=a,h=this.fixHooks[f];h||(this.fixHooks[f]=h=ma.test(f)?this.mouseHooks:la.test(f)?this.keyHooks:{}),e=h.props?this.props.concat(h.props):this.props,a=new n.Event(g),b=e.length;while(b--)c=e[b],a[c]=g[c];return a.target||(a.target=g.srcElement||d),3===a.target.nodeType&&(a.target=a.target.parentNode),a.metaKey=!!a.metaKey,h.filter?h.filter(a,g):a},props:\"altKey bubbles cancelable ctrlKey currentTarget detail eventPhase metaKey relatedTarget shiftKey target timeStamp view which\".split(\" \"),fixHooks:{},keyHooks:{props:\"char charCode key keyCode\".split(\" \"),filter:function(a,b){return null==a.which&&(a.which=null!=b.charCode?b.charCode:b.keyCode),a}},mouseHooks:{props:\"button buttons clientX clientY fromElement offsetX offsetY pageX pageY screenX screenY toElement\".split(\" \"),filter:function(a,b){var c,e,f,g=b.button,h=b.fromElement;return null==a.pageX&&null!=b.clientX&&(e=a.target.ownerDocument||d,f=e.documentElement,c=e.body,a.pageX=b.clientX+(f&&f.scrollLeft||c&&c.scrollLeft||0)-(f&&f.clientLeft||c&&c.clientLeft||0),a.pageY=b.clientY+(f&&f.scrollTop||c&&c.scrollTop||0)-(f&&f.clientTop||c&&c.clientTop||0)),!a.relatedTarget&&h&&(a.relatedTarget=h===a.target?b.toElement:h),a.which||void 0===g||(a.which=1&g?1:2&g?3:4&g?2:0),a}},special:{load:{noBubble:!0},focus:{trigger:function(){if(this!==ra()&&this.focus)try{return this.focus(),!1}catch(a){}},delegateType:\"focusin\"},blur:{trigger:function(){return this===ra()&&this.blur?(this.blur(),!1):void 0},delegateType:\"focusout\"},click:{trigger:function(){return n.nodeName(this,\"input\")&&\"checkbox\"===this.type&&this.click?(this.click(),!1):void 0},_default:function(a){return n.nodeName(a.target,\"a\")}},beforeunload:{postDispatch:function(a){void 0!==a.result&&a.originalEvent&&(a.originalEvent.returnValue=a.result)}}},simulate:function(a,b,c){var d=n.extend(new n.Event,c,{type:a,isSimulated:!0});n.event.trigger(d,null,b),d.isDefaultPrevented()&&c.preventDefault()}},n.removeEvent=d.removeEventListener?function(a,b,c){a.removeEventListener&&a.removeEventListener(b,c)}:function(a,b,c){var d=\"on\"+b;a.detachEvent&&(\"undefined\"==typeof a[d]&&(a[d]=null),a.detachEvent(d,c))},n.Event=function(a,b){return this instanceof n.Event?(a&&a.type?(this.originalEvent=a,this.type=a.type,this.isDefaultPrevented=a.defaultPrevented||void 0===a.defaultPrevented&&a.returnValue===!1?pa:qa):this.type=a,b&&n.extend(this,b),this.timeStamp=a&&a.timeStamp||n.now(),void(this[n.expando]=!0)):new n.Event(a,b)},n.Event.prototype={constructor:n.Event,isDefaultPrevented:qa,isPropagationStopped:qa,isImmediatePropagationStopped:qa,preventDefault:function(){var a=this.originalEvent;this.isDefaultPrevented=pa,a&&(a.preventDefault?a.preventDefault():a.returnValue=!1)},stopPropagation:function(){var a=this.originalEvent;this.isPropagationStopped=pa,a&&!this.isSimulated&&(a.stopPropagation&&a.stopPropagation(),a.cancelBubble=!0)},stopImmediatePropagation:function(){var a=this.originalEvent;this.isImmediatePropagationStopped=pa,a&&a.stopImmediatePropagation&&a.stopImmediatePropagation(),this.stopPropagation()}},n.each({mouseenter:\"mouseover\",mouseleave:\"mouseout\",pointerenter:\"pointerover\",pointerleave:\"pointerout\"},function(a,b){n.event.special[a]={delegateType:b,bindType:b,handle:function(a){var c,d=this,e=a.relatedTarget,f=a.handleObj;return(!e||e!==d&&!n.contains(d,e))&&(a.type=f.origType,c=f.handler.apply(this,arguments),a.type=b),c}}}),l.submit||(n.event.special.submit={setup:function(){return n.nodeName(this,\"form\")?!1:void n.event.add(this,\"click._submit keypress._submit\",function(a){var b=a.target,c=n.nodeName(b,\"input\")||n.nodeName(b,\"button\")?n.prop(b,\"form\"):void 0;c&&!n._data(c,\"submit\")&&(n.event.add(c,\"submit._submit\",function(a){a._submitBubble=!0}),n._data(c,\"submit\",!0))})},postDispatch:function(a){a._submitBubble&&(delete a._submitBubble,this.parentNode&&!a.isTrigger&&n.event.simulate(\"submit\",this.parentNode,a))},teardown:function(){return n.nodeName(this,\"form\")?!1:void n.event.remove(this,\"._submit\")}}),l.change||(n.event.special.change={setup:function(){return ka.test(this.nodeName)?((\"checkbox\"===this.type||\"radio\"===this.type)&&(n.event.add(this,\"propertychange._change\",function(a){\"checked\"===a.originalEvent.propertyName&&(this._justChanged=!0)}),n.event.add(this,\"click._change\",function(a){this._justChanged&&!a.isTrigger&&(this._justChanged=!1),n.event.simulate(\"change\",this,a)})),!1):void n.event.add(this,\"beforeactivate._change\",function(a){var b=a.target;ka.test(b.nodeName)&&!n._data(b,\"change\")&&(n.event.add(b,\"change._change\",function(a){!this.parentNode||a.isSimulated||a.isTrigger||n.event.simulate(\"change\",this.parentNode,a)}),n._data(b,\"change\",!0))})},handle:function(a){var b=a.target;return this!==b||a.isSimulated||a.isTrigger||\"radio\"!==b.type&&\"checkbox\"!==b.type?a.handleObj.handler.apply(this,arguments):void 0},teardown:function(){return n.event.remove(this,\"._change\"),!ka.test(this.nodeName)}}),l.focusin||n.each({focus:\"focusin\",blur:\"focusout\"},function(a,b){var c=function(a){n.event.simulate(b,a.target,n.event.fix(a))};n.event.special[b]={setup:function(){var d=this.ownerDocument||this,e=n._data(d,b);e||d.addEventListener(a,c,!0),n._data(d,b,(e||0)+1)},teardown:function(){var d=this.ownerDocument||this,e=n._data(d,b)-1;e?n._data(d,b,e):(d.removeEventListener(a,c,!0),n._removeData(d,b))}}}),n.fn.extend({on:function(a,b,c,d){return sa(this,a,b,c,d)},one:function(a,b,c,d){return sa(this,a,b,c,d,1)},off:function(a,b,c){var d,e;if(a&&a.preventDefault&&a.handleObj)return d=a.handleObj,n(a.delegateTarget).off(d.namespace?d.origType+\".\"+d.namespace:d.origType,d.selector,d.handler),this;if(\"object\"==typeof a){for(e in a)this.off(e,b,a[e]);return this}return(b===!1||\"function\"==typeof b)&&(c=b,b=void 0),c===!1&&(c=qa),this.each(function(){n.event.remove(this,a,c,b)})},trigger:function(a,b){return this.each(function(){n.event.trigger(a,b,this)})},triggerHandler:function(a,b){var c=this[0];return c?n.event.trigger(a,b,c,!0):void 0}});var ta=/ jQuery\\d+=\"(?:null|\\d+)\"/g,ua=new RegExp(\"<(?:\"+ba+\")[\\\\s/>]\",\"i\"),va=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\\w:-]+)[^>]*)\\/>/gi,wa=/<script|<style|<link/i,xa=/checked\\s*(?:[^=]|=\\s*.checked.)/i,ya=/^true\\/(.*)/,za=/^\\s*<!(?:\\[CDATA\\[|--)|(?:\\]\\]|--)>\\s*$/g,Aa=ca(d),Ba=Aa.appendChild(d.createElement(\"div\"));function Ca(a,b){return n.nodeName(a,\"table\")&&n.nodeName(11!==b.nodeType?b:b.firstChild,\"tr\")?a.getElementsByTagName(\"tbody\")[0]||a.appendChild(a.ownerDocument.createElement(\"tbody\")):a}function Da(a){return a.type=(null!==n.find.attr(a,\"type\"))+\"/\"+a.type,a}function Ea(a){var b=ya.exec(a.type);return b?a.type=b[1]:a.removeAttribute(\"type\"),a}function Fa(a,b){if(1===b.nodeType&&n.hasData(a)){var c,d,e,f=n._data(a),g=n._data(b,f),h=f.events;if(h){delete g.handle,g.events={};for(c in h)for(d=0,e=h[c].length;e>d;d++)n.event.add(b,c,h[c][d])}g.data&&(g.data=n.extend({},g.data))}}function Ga(a,b){var c,d,e;if(1===b.nodeType){if(c=b.nodeName.toLowerCase(),!l.noCloneEvent&&b[n.expando]){e=n._data(b);for(d in e.events)n.removeEvent(b,d,e.handle);b.removeAttribute(n.expando)}\"script\"===c&&b.text!==a.text?(Da(b).text=a.text,Ea(b)):\"object\"===c?(b.parentNode&&(b.outerHTML=a.outerHTML),l.html5Clone&&a.innerHTML&&!n.trim(b.innerHTML)&&(b.innerHTML=a.innerHTML)):\"input\"===c&&Z.test(a.type)?(b.defaultChecked=b.checked=a.checked,b.value!==a.value&&(b.value=a.value)):\"option\"===c?b.defaultSelected=b.selected=a.defaultSelected:(\"input\"===c||\"textarea\"===c)&&(b.defaultValue=a.defaultValue)}}function Ha(a,b,c,d){b=f.apply([],b);var e,g,h,i,j,k,m=0,o=a.length,p=o-1,q=b[0],r=n.isFunction(q);if(r||o>1&&\"string\"==typeof q&&!l.checkClone&&xa.test(q))return a.each(function(e){var f=a.eq(e);r&&(b[0]=q.call(this,e,f.html())),Ha(f,b,c,d)});if(o&&(k=ja(b,a[0].ownerDocument,!1,a,d),e=k.firstChild,1===k.childNodes.length&&(k=e),e||d)){for(i=n.map(ea(k,\"script\"),Da),h=i.length;o>m;m++)g=k,m!==p&&(g=n.clone(g,!0,!0),h&&n.merge(i,ea(g,\"script\"))),c.call(a[m],g,m);if(h)for(j=i[i.length-1].ownerDocument,n.map(i,Ea),m=0;h>m;m++)g=i[m],_.test(g.type||\"\")&&!n._data(g,\"globalEval\")&&n.contains(j,g)&&(g.src?n._evalUrl&&n._evalUrl(g.src):n.globalEval((g.text||g.textContent||g.innerHTML||\"\").replace(za,\"\")));k=e=null}return a}function Ia(a,b,c){for(var d,e=b?n.filter(b,a):a,f=0;null!=(d=e[f]);f++)c||1!==d.nodeType||n.cleanData(ea(d)),d.parentNode&&(c&&n.contains(d.ownerDocument,d)&&fa(ea(d,\"script\")),d.parentNode.removeChild(d));return a}n.extend({htmlPrefilter:function(a){return a.replace(va,\"<$1></$2>\")},clone:function(a,b,c){var d,e,f,g,h,i=n.contains(a.ownerDocument,a);if(l.html5Clone||n.isXMLDoc(a)||!ua.test(\"<\"+a.nodeName+\">\")?f=a.cloneNode(!0):(Ba.innerHTML=a.outerHTML,Ba.removeChild(f=Ba.firstChild)),!(l.noCloneEvent&&l.noCloneChecked||1!==a.nodeType&&11!==a.nodeType||n.isXMLDoc(a)))for(d=ea(f),h=ea(a),g=0;null!=(e=h[g]);++g)d[g]&&Ga(e,d[g]);if(b)if(c)for(h=h||ea(a),d=d||ea(f),g=0;null!=(e=h[g]);g++)Fa(e,d[g]);else Fa(a,f);return d=ea(f,\"script\"),d.length>0&&fa(d,!i&&ea(a,\"script\")),d=h=e=null,f},cleanData:function(a,b){for(var d,e,f,g,h=0,i=n.expando,j=n.cache,k=l.attributes,m=n.event.special;null!=(d=a[h]);h++)if((b||M(d))&&(f=d[i],g=f&&j[f])){if(g.events)for(e in g.events)m[e]?n.event.remove(d,e):n.removeEvent(d,e,g.handle);j[f]&&(delete j[f],k||\"undefined\"==typeof d.removeAttribute?d[i]=void 0:d.removeAttribute(i),c.push(f))}}}),n.fn.extend({domManip:Ha,detach:function(a){return Ia(this,a,!0)},remove:function(a){return Ia(this,a)},text:function(a){return Y(this,function(a){return void 0===a?n.text(this):this.empty().append((this[0]&&this[0].ownerDocument||d).createTextNode(a))},null,a,arguments.length)},append:function(){return Ha(this,arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=Ca(this,a);b.appendChild(a)}})},prepend:function(){return Ha(this,arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=Ca(this,a);b.insertBefore(a,b.firstChild)}})},before:function(){return Ha(this,arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this)})},after:function(){return Ha(this,arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this.nextSibling)})},empty:function(){for(var a,b=0;null!=(a=this[b]);b++){1===a.nodeType&&n.cleanData(ea(a,!1));while(a.firstChild)a.removeChild(a.firstChild);a.options&&n.nodeName(a,\"select\")&&(a.options.length=0)}return this},clone:function(a,b){return a=null==a?!1:a,b=null==b?a:b,this.map(function(){return n.clone(this,a,b)})},html:function(a){return Y(this,function(a){var b=this[0]||{},c=0,d=this.length;if(void 0===a)return 1===b.nodeType?b.innerHTML.replace(ta,\"\"):void 0;if(\"string\"==typeof a&&!wa.test(a)&&(l.htmlSerialize||!ua.test(a))&&(l.leadingWhitespace||!aa.test(a))&&!da[($.exec(a)||[\"\",\"\"])[1].toLowerCase()]){a=n.htmlPrefilter(a);try{for(;d>c;c++)b=this[c]||{},1===b.nodeType&&(n.cleanData(ea(b,!1)),b.innerHTML=a);b=0}catch(e){}}b&&this.empty().append(a)},null,a,arguments.length)},replaceWith:function(){var a=[];return Ha(this,arguments,function(b){var c=this.parentNode;n.inArray(this,a)<0&&(n.cleanData(ea(this)),c&&c.replaceChild(b,this))},a)}}),n.each({appendTo:\"append\",prependTo:\"prepend\",insertBefore:\"before\",insertAfter:\"after\",replaceAll:\"replaceWith\"},function(a,b){n.fn[a]=function(a){for(var c,d=0,e=[],f=n(a),h=f.length-1;h>=d;d++)c=d===h?this:this.clone(!0),n(f[d])[b](c),g.apply(e,c.get());return this.pushStack(e)}});var Ja,Ka={HTML:\"block\",BODY:\"block\"};function La(a,b){var c=n(b.createElement(a)).appendTo(b.body),d=n.css(c[0],\"display\");return c.detach(),d}function Ma(a){var b=d,c=Ka[a];return c||(c=La(a,b),\"none\"!==c&&c||(Ja=(Ja||n(\"<iframe frameborder='0' width='0' height='0'/>\")).appendTo(b.documentElement),b=(Ja[0].contentWindow||Ja[0].contentDocument).document,b.write(),b.close(),c=La(a,b),Ja.detach()),Ka[a]=c),c}var Na=/^margin/,Oa=new RegExp(\"^(\"+T+\")(?!px)[a-z%]+$\",\"i\"),Pa=function(a,b,c,d){var e,f,g={};for(f in b)g[f]=a.style[f],a.style[f]=b[f];e=c.apply(a,d||[]);for(f in b)a.style[f]=g[f];return e},Qa=d.documentElement;!function(){var b,c,e,f,g,h,i=d.createElement(\"div\"),j=d.createElement(\"div\");if(j.style){j.style.cssText=\"float:left;opacity:.5\",l.opacity=\"0.5\"===j.style.opacity,l.cssFloat=!!j.style.cssFloat,j.style.backgroundClip=\"content-box\",j.cloneNode(!0).style.backgroundClip=\"\",l.clearCloneStyle=\"content-box\"===j.style.backgroundClip,i=d.createElement(\"div\"),i.style.cssText=\"border:0;width:8px;height:0;top:0;left:-9999px;padding:0;margin-top:1px;position:absolute\",j.innerHTML=\"\",i.appendChild(j),l.boxSizing=\"\"===j.style.boxSizing||\"\"===j.style.MozBoxSizing||\"\"===j.style.WebkitBoxSizing,n.extend(l,{reliableHiddenOffsets:function(){return null==b&&k(),f},boxSizingReliable:function(){return null==b&&k(),e},pixelMarginRight:function(){return null==b&&k(),c},pixelPosition:function(){return null==b&&k(),b},reliableMarginRight:function(){return null==b&&k(),g},reliableMarginLeft:function(){return null==b&&k(),h}});function k(){var k,l,m=d.documentElement;m.appendChild(i),j.style.cssText=\"-webkit-box-sizing:border-box;box-sizing:border-box;position:relative;display:block;margin:auto;border:1px;padding:1px;top:1%;width:50%\",b=e=h=!1,c=g=!0,a.getComputedStyle&&(l=a.getComputedStyle(j),b=\"1%\"!==(l||{}).top,h=\"2px\"===(l||{}).marginLeft,e=\"4px\"===(l||{width:\"4px\"}).width,j.style.marginRight=\"50%\",c=\"4px\"===(l||{marginRight:\"4px\"}).marginRight,k=j.appendChild(d.createElement(\"div\")),k.style.cssText=j.style.cssText=\"-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box;display:block;margin:0;border:0;padding:0\",k.style.marginRight=k.style.width=\"0\",j.style.width=\"1px\",g=!parseFloat((a.getComputedStyle(k)||{}).marginRight),j.removeChild(k)),j.style.display=\"none\",f=0===j.getClientRects().length,f&&(j.style.display=\"\",j.innerHTML=\"<table><tr><td></td><td>t</td></tr></table>\",k=j.getElementsByTagName(\"td\"),k[0].style.cssText=\"margin:0;border:0;padding:0;display:none\",f=0===k[0].offsetHeight,f&&(k[0].style.display=\"\",k[1].style.display=\"none\",f=0===k[0].offsetHeight)),m.removeChild(i)}}}();var Ra,Sa,Ta=/^(top|right|bottom|left)$/;a.getComputedStyle?(Ra=function(b){var c=b.ownerDocument.defaultView;return c.opener||(c=a),c.getComputedStyle(b)},Sa=function(a,b,c){var d,e,f,g,h=a.style;return c=c||Ra(a),g=c?c.getPropertyValue(b)||c[b]:void 0,c&&(\"\"!==g||n.contains(a.ownerDocument,a)||(g=n.style(a,b)),!l.pixelMarginRight()&&Oa.test(g)&&Na.test(b)&&(d=h.width,e=h.minWidth,f=h.maxWidth,h.minWidth=h.maxWidth=h.width=g,g=c.width,h.width=d,h.minWidth=e,h.maxWidth=f)),void 0===g?g:g+\"\"}):Qa.currentStyle&&(Ra=function(a){return a.currentStyle},Sa=function(a,b,c){var d,e,f,g,h=a.style;return c=c||Ra(a),g=c?c[b]:void 0,null==g&&h&&h[b]&&(g=h[b]),Oa.test(g)&&!Ta.test(b)&&(d=h.left,e=a.runtimeStyle,f=e&&e.left,f&&(e.left=a.currentStyle.left),h.left=\"fontSize\"===b?\"1em\":g,g=h.pixelLeft+\"px\",h.left=d,f&&(e.left=f)),void 0===g?g:g+\"\"||\"auto\"});function Ua(a,b){return{get:function(){return a()?void delete this.get:(this.get=b).apply(this,arguments)}}}var Va=/alpha\\([^)]*\\)/i,Wa=/opacity\\s*=\\s*([^)]*)/i,Xa=/^(none|table(?!-c[ea]).+)/,Ya=new RegExp(\"^(\"+T+\")(.*)$\",\"i\"),Za={position:\"absolute\",visibility:\"hidden\",display:\"block\"},$a={letterSpacing:\"0\",fontWeight:\"400\"},_a=[\"Webkit\",\"O\",\"Moz\",\"ms\"],ab=d.createElement(\"div\").style;function bb(a){if(a in ab)return a;var b=a.charAt(0).toUpperCase()+a.slice(1),c=_a.length;while(c--)if(a=_a[c]+b,a in ab)return a}function cb(a,b){for(var c,d,e,f=[],g=0,h=a.length;h>g;g++)d=a[g],d.style&&(f[g]=n._data(d,\"olddisplay\"),c=d.style.display,b?(f[g]||\"none\"!==c||(d.style.display=\"\"),\"\"===d.style.display&&W(d)&&(f[g]=n._data(d,\"olddisplay\",Ma(d.nodeName)))):(e=W(d),(c&&\"none\"!==c||!e)&&n._data(d,\"olddisplay\",e?c:n.css(d,\"display\"))));for(g=0;h>g;g++)d=a[g],d.style&&(b&&\"none\"!==d.style.display&&\"\"!==d.style.display||(d.style.display=b?f[g]||\"\":\"none\"));return a}function db(a,b,c){var d=Ya.exec(b);return d?Math.max(0,d[1]-(c||0))+(d[2]||\"px\"):b}function eb(a,b,c,d,e){for(var f=c===(d?\"border\":\"content\")?4:\"width\"===b?1:0,g=0;4>f;f+=2)\"margin\"===c&&(g+=n.css(a,c+V[f],!0,e)),d?(\"content\"===c&&(g-=n.css(a,\"padding\"+V[f],!0,e)),\"margin\"!==c&&(g-=n.css(a,\"border\"+V[f]+\"Width\",!0,e))):(g+=n.css(a,\"padding\"+V[f],!0,e),\"padding\"!==c&&(g+=n.css(a,\"border\"+V[f]+\"Width\",!0,e)));return g}function fb(b,c,e){var f=!0,g=\"width\"===c?b.offsetWidth:b.offsetHeight,h=Ra(b),i=l.boxSizing&&\"border-box\"===n.css(b,\"boxSizing\",!1,h);if(d.msFullscreenElement&&a.top!==a&&b.getClientRects().length&&(g=Math.round(100*b.getBoundingClientRect()[c])),0>=g||null==g){if(g=Sa(b,c,h),(0>g||null==g)&&(g=b.style[c]),Oa.test(g))return g;f=i&&(l.boxSizingReliable()||g===b.style[c]),g=parseFloat(g)||0}return g+eb(b,c,e||(i?\"border\":\"content\"),f,h)+\"px\"}n.extend({cssHooks:{opacity:{get:function(a,b){if(b){var c=Sa(a,\"opacity\");return\"\"===c?\"1\":c}}}},cssNumber:{animationIterationCount:!0,columnCount:!0,fillOpacity:!0,flexGrow:!0,flexShrink:!0,fontWeight:!0,lineHeight:!0,opacity:!0,order:!0,orphans:!0,widows:!0,zIndex:!0,zoom:!0},cssProps:{\"float\":l.cssFloat?\"cssFloat\":\"styleFloat\"},style:function(a,b,c,d){if(a&&3!==a.nodeType&&8!==a.nodeType&&a.style){var e,f,g,h=n.camelCase(b),i=a.style;if(b=n.cssProps[h]||(n.cssProps[h]=bb(h)||h),g=n.cssHooks[b]||n.cssHooks[h],void 0===c)return g&&\"get\"in g&&void 0!==(e=g.get(a,!1,d))?e:i[b];if(f=typeof c,\"string\"===f&&(e=U.exec(c))&&e[1]&&(c=X(a,b,e),f=\"number\"),null!=c&&c===c&&(\"number\"===f&&(c+=e&&e[3]||(n.cssNumber[h]?\"\":\"px\")),l.clearCloneStyle||\"\"!==c||0!==b.indexOf(\"background\")||(i[b]=\"inherit\"),!(g&&\"set\"in g&&void 0===(c=g.set(a,c,d)))))try{i[b]=c}catch(j){}}},css:function(a,b,c,d){var e,f,g,h=n.camelCase(b);return b=n.cssProps[h]||(n.cssProps[h]=bb(h)||h),g=n.cssHooks[b]||n.cssHooks[h],g&&\"get\"in g&&(f=g.get(a,!0,c)),void 0===f&&(f=Sa(a,b,d)),\"normal\"===f&&b in $a&&(f=$a[b]),\"\"===c||c?(e=parseFloat(f),c===!0||isFinite(e)?e||0:f):f}}),n.each([\"height\",\"width\"],function(a,b){n.cssHooks[b]={get:function(a,c,d){return c?Xa.test(n.css(a,\"display\"))&&0===a.offsetWidth?Pa(a,Za,function(){return fb(a,b,d)}):fb(a,b,d):void 0},set:function(a,c,d){var e=d&&Ra(a);return db(a,c,d?eb(a,b,d,l.boxSizing&&\"border-box\"===n.css(a,\"boxSizing\",!1,e),e):0)}}}),l.opacity||(n.cssHooks.opacity={get:function(a,b){return Wa.test((b&&a.currentStyle?a.currentStyle.filter:a.style.filter)||\"\")?.01*parseFloat(RegExp.$1)+\"\":b?\"1\":\"\"},set:function(a,b){var c=a.style,d=a.currentStyle,e=n.isNumeric(b)?\"alpha(opacity=\"+100*b+\")\":\"\",f=d&&d.filter||c.filter||\"\";c.zoom=1,(b>=1||\"\"===b)&&\"\"===n.trim(f.replace(Va,\"\"))&&c.removeAttribute&&(c.removeAttribute(\"filter\"),\"\"===b||d&&!d.filter)||(c.filter=Va.test(f)?f.replace(Va,e):f+\" \"+e)}}),n.cssHooks.marginRight=Ua(l.reliableMarginRight,function(a,b){return b?Pa(a,{display:\"inline-block\"},Sa,[a,\"marginRight\"]):void 0}),n.cssHooks.marginLeft=Ua(l.reliableMarginLeft,function(a,b){return b?(parseFloat(Sa(a,\"marginLeft\"))||(n.contains(a.ownerDocument,a)?a.getBoundingClientRect().left-Pa(a,{\nmarginLeft:0},function(){return a.getBoundingClientRect().left}):0))+\"px\":void 0}),n.each({margin:\"\",padding:\"\",border:\"Width\"},function(a,b){n.cssHooks[a+b]={expand:function(c){for(var d=0,e={},f=\"string\"==typeof c?c.split(\" \"):[c];4>d;d++)e[a+V[d]+b]=f[d]||f[d-2]||f[0];return e}},Na.test(a)||(n.cssHooks[a+b].set=db)}),n.fn.extend({css:function(a,b){return Y(this,function(a,b,c){var d,e,f={},g=0;if(n.isArray(b)){for(d=Ra(a),e=b.length;e>g;g++)f[b[g]]=n.css(a,b[g],!1,d);return f}return void 0!==c?n.style(a,b,c):n.css(a,b)},a,b,arguments.length>1)},show:function(){return cb(this,!0)},hide:function(){return cb(this)},toggle:function(a){return\"boolean\"==typeof a?a?this.show():this.hide():this.each(function(){W(this)?n(this).show():n(this).hide()})}});function gb(a,b,c,d,e){return new gb.prototype.init(a,b,c,d,e)}n.Tween=gb,gb.prototype={constructor:gb,init:function(a,b,c,d,e,f){this.elem=a,this.prop=c,this.easing=e||n.easing._default,this.options=b,this.start=this.now=this.cur(),this.end=d,this.unit=f||(n.cssNumber[c]?\"\":\"px\")},cur:function(){var a=gb.propHooks[this.prop];return a&&a.get?a.get(this):gb.propHooks._default.get(this)},run:function(a){var b,c=gb.propHooks[this.prop];return this.options.duration?this.pos=b=n.easing[this.easing](a,this.options.duration*a,0,1,this.options.duration):this.pos=b=a,this.now=(this.end-this.start)*b+this.start,this.options.step&&this.options.step.call(this.elem,this.now,this),c&&c.set?c.set(this):gb.propHooks._default.set(this),this}},gb.prototype.init.prototype=gb.prototype,gb.propHooks={_default:{get:function(a){var b;return 1!==a.elem.nodeType||null!=a.elem[a.prop]&&null==a.elem.style[a.prop]?a.elem[a.prop]:(b=n.css(a.elem,a.prop,\"\"),b&&\"auto\"!==b?b:0)},set:function(a){n.fx.step[a.prop]?n.fx.step[a.prop](a):1!==a.elem.nodeType||null==a.elem.style[n.cssProps[a.prop]]&&!n.cssHooks[a.prop]?a.elem[a.prop]=a.now:n.style(a.elem,a.prop,a.now+a.unit)}}},gb.propHooks.scrollTop=gb.propHooks.scrollLeft={set:function(a){a.elem.nodeType&&a.elem.parentNode&&(a.elem[a.prop]=a.now)}},n.easing={linear:function(a){return a},swing:function(a){return.5-Math.cos(a*Math.PI)/2},_default:\"swing\"},n.fx=gb.prototype.init,n.fx.step={};var hb,ib,jb=/^(?:toggle|show|hide)$/,kb=/queueHooks$/;function lb(){return a.setTimeout(function(){hb=void 0}),hb=n.now()}function mb(a,b){var c,d={height:a},e=0;for(b=b?1:0;4>e;e+=2-b)c=V[e],d[\"margin\"+c]=d[\"padding\"+c]=a;return b&&(d.opacity=d.width=a),d}function nb(a,b,c){for(var d,e=(qb.tweeners[b]||[]).concat(qb.tweeners[\"*\"]),f=0,g=e.length;g>f;f++)if(d=e[f].call(c,b,a))return d}function ob(a,b,c){var d,e,f,g,h,i,j,k,m=this,o={},p=a.style,q=a.nodeType&&W(a),r=n._data(a,\"fxshow\");c.queue||(h=n._queueHooks(a,\"fx\"),null==h.unqueued&&(h.unqueued=0,i=h.empty.fire,h.empty.fire=function(){h.unqueued||i()}),h.unqueued++,m.always(function(){m.always(function(){h.unqueued--,n.queue(a,\"fx\").length||h.empty.fire()})})),1===a.nodeType&&(\"height\"in b||\"width\"in b)&&(c.overflow=[p.overflow,p.overflowX,p.overflowY],j=n.css(a,\"display\"),k=\"none\"===j?n._data(a,\"olddisplay\")||Ma(a.nodeName):j,\"inline\"===k&&\"none\"===n.css(a,\"float\")&&(l.inlineBlockNeedsLayout&&\"inline\"!==Ma(a.nodeName)?p.zoom=1:p.display=\"inline-block\")),c.overflow&&(p.overflow=\"hidden\",l.shrinkWrapBlocks()||m.always(function(){p.overflow=c.overflow[0],p.overflowX=c.overflow[1],p.overflowY=c.overflow[2]}));for(d in b)if(e=b[d],jb.exec(e)){if(delete b[d],f=f||\"toggle\"===e,e===(q?\"hide\":\"show\")){if(\"show\"!==e||!r||void 0===r[d])continue;q=!0}o[d]=r&&r[d]||n.style(a,d)}else j=void 0;if(n.isEmptyObject(o))\"inline\"===(\"none\"===j?Ma(a.nodeName):j)&&(p.display=j);else{r?\"hidden\"in r&&(q=r.hidden):r=n._data(a,\"fxshow\",{}),f&&(r.hidden=!q),q?n(a).show():m.done(function(){n(a).hide()}),m.done(function(){var b;n._removeData(a,\"fxshow\");for(b in o)n.style(a,b,o[b])});for(d in o)g=nb(q?r[d]:0,d,m),d in r||(r[d]=g.start,q&&(g.end=g.start,g.start=\"width\"===d||\"height\"===d?1:0))}}function pb(a,b){var c,d,e,f,g;for(c in a)if(d=n.camelCase(c),e=b[d],f=a[c],n.isArray(f)&&(e=f[1],f=a[c]=f[0]),c!==d&&(a[d]=f,delete a[c]),g=n.cssHooks[d],g&&\"expand\"in g){f=g.expand(f),delete a[d];for(c in f)c in a||(a[c]=f[c],b[c]=e)}else b[d]=e}function qb(a,b,c){var d,e,f=0,g=qb.prefilters.length,h=n.Deferred().always(function(){delete i.elem}),i=function(){if(e)return!1;for(var b=hb||lb(),c=Math.max(0,j.startTime+j.duration-b),d=c/j.duration||0,f=1-d,g=0,i=j.tweens.length;i>g;g++)j.tweens[g].run(f);return h.notifyWith(a,[j,f,c]),1>f&&i?c:(h.resolveWith(a,[j]),!1)},j=h.promise({elem:a,props:n.extend({},b),opts:n.extend(!0,{specialEasing:{},easing:n.easing._default},c),originalProperties:b,originalOptions:c,startTime:hb||lb(),duration:c.duration,tweens:[],createTween:function(b,c){var d=n.Tween(a,j.opts,b,c,j.opts.specialEasing[b]||j.opts.easing);return j.tweens.push(d),d},stop:function(b){var c=0,d=b?j.tweens.length:0;if(e)return this;for(e=!0;d>c;c++)j.tweens[c].run(1);return b?(h.notifyWith(a,[j,1,0]),h.resolveWith(a,[j,b])):h.rejectWith(a,[j,b]),this}}),k=j.props;for(pb(k,j.opts.specialEasing);g>f;f++)if(d=qb.prefilters[f].call(j,a,k,j.opts))return n.isFunction(d.stop)&&(n._queueHooks(j.elem,j.opts.queue).stop=n.proxy(d.stop,d)),d;return n.map(k,nb,j),n.isFunction(j.opts.start)&&j.opts.start.call(a,j),n.fx.timer(n.extend(i,{elem:a,anim:j,queue:j.opts.queue})),j.progress(j.opts.progress).done(j.opts.done,j.opts.complete).fail(j.opts.fail).always(j.opts.always)}n.Animation=n.extend(qb,{tweeners:{\"*\":[function(a,b){var c=this.createTween(a,b);return X(c.elem,a,U.exec(b),c),c}]},tweener:function(a,b){n.isFunction(a)?(b=a,a=[\"*\"]):a=a.match(G);for(var c,d=0,e=a.length;e>d;d++)c=a[d],qb.tweeners[c]=qb.tweeners[c]||[],qb.tweeners[c].unshift(b)},prefilters:[ob],prefilter:function(a,b){b?qb.prefilters.unshift(a):qb.prefilters.push(a)}}),n.speed=function(a,b,c){var d=a&&\"object\"==typeof a?n.extend({},a):{complete:c||!c&&b||n.isFunction(a)&&a,duration:a,easing:c&&b||b&&!n.isFunction(b)&&b};return d.duration=n.fx.off?0:\"number\"==typeof d.duration?d.duration:d.duration in n.fx.speeds?n.fx.speeds[d.duration]:n.fx.speeds._default,(null==d.queue||d.queue===!0)&&(d.queue=\"fx\"),d.old=d.complete,d.complete=function(){n.isFunction(d.old)&&d.old.call(this),d.queue&&n.dequeue(this,d.queue)},d},n.fn.extend({fadeTo:function(a,b,c,d){return this.filter(W).css(\"opacity\",0).show().end().animate({opacity:b},a,c,d)},animate:function(a,b,c,d){var e=n.isEmptyObject(a),f=n.speed(b,c,d),g=function(){var b=qb(this,n.extend({},a),f);(e||n._data(this,\"finish\"))&&b.stop(!0)};return g.finish=g,e||f.queue===!1?this.each(g):this.queue(f.queue,g)},stop:function(a,b,c){var d=function(a){var b=a.stop;delete a.stop,b(c)};return\"string\"!=typeof a&&(c=b,b=a,a=void 0),b&&a!==!1&&this.queue(a||\"fx\",[]),this.each(function(){var b=!0,e=null!=a&&a+\"queueHooks\",f=n.timers,g=n._data(this);if(e)g[e]&&g[e].stop&&d(g[e]);else for(e in g)g[e]&&g[e].stop&&kb.test(e)&&d(g[e]);for(e=f.length;e--;)f[e].elem!==this||null!=a&&f[e].queue!==a||(f[e].anim.stop(c),b=!1,f.splice(e,1));(b||!c)&&n.dequeue(this,a)})},finish:function(a){return a!==!1&&(a=a||\"fx\"),this.each(function(){var b,c=n._data(this),d=c[a+\"queue\"],e=c[a+\"queueHooks\"],f=n.timers,g=d?d.length:0;for(c.finish=!0,n.queue(this,a,[]),e&&e.stop&&e.stop.call(this,!0),b=f.length;b--;)f[b].elem===this&&f[b].queue===a&&(f[b].anim.stop(!0),f.splice(b,1));for(b=0;g>b;b++)d[b]&&d[b].finish&&d[b].finish.call(this);delete c.finish})}}),n.each([\"toggle\",\"show\",\"hide\"],function(a,b){var c=n.fn[b];n.fn[b]=function(a,d,e){return null==a||\"boolean\"==typeof a?c.apply(this,arguments):this.animate(mb(b,!0),a,d,e)}}),n.each({slideDown:mb(\"show\"),slideUp:mb(\"hide\"),slideToggle:mb(\"toggle\"),fadeIn:{opacity:\"show\"},fadeOut:{opacity:\"hide\"},fadeToggle:{opacity:\"toggle\"}},function(a,b){n.fn[a]=function(a,c,d){return this.animate(b,a,c,d)}}),n.timers=[],n.fx.tick=function(){var a,b=n.timers,c=0;for(hb=n.now();c<b.length;c++)a=b[c],a()||b[c]!==a||b.splice(c--,1);b.length||n.fx.stop(),hb=void 0},n.fx.timer=function(a){n.timers.push(a),a()?n.fx.start():n.timers.pop()},n.fx.interval=13,n.fx.start=function(){ib||(ib=a.setInterval(n.fx.tick,n.fx.interval))},n.fx.stop=function(){a.clearInterval(ib),ib=null},n.fx.speeds={slow:600,fast:200,_default:400},n.fn.delay=function(b,c){return b=n.fx?n.fx.speeds[b]||b:b,c=c||\"fx\",this.queue(c,function(c,d){var e=a.setTimeout(c,b);d.stop=function(){a.clearTimeout(e)}})},function(){var a,b=d.createElement(\"input\"),c=d.createElement(\"div\"),e=d.createElement(\"select\"),f=e.appendChild(d.createElement(\"option\"));c=d.createElement(\"div\"),c.setAttribute(\"className\",\"t\"),c.innerHTML=\"  <link/><table></table><a href='/a'>a</a><input type='checkbox'/>\",a=c.getElementsByTagName(\"a\")[0],b.setAttribute(\"type\",\"checkbox\"),c.appendChild(b),a=c.getElementsByTagName(\"a\")[0],a.style.cssText=\"top:1px\",l.getSetAttribute=\"t\"!==c.className,l.style=/top/.test(a.getAttribute(\"style\")),l.hrefNormalized=\"/a\"===a.getAttribute(\"href\"),l.checkOn=!!b.value,l.optSelected=f.selected,l.enctype=!!d.createElement(\"form\").enctype,e.disabled=!0,l.optDisabled=!f.disabled,b=d.createElement(\"input\"),b.setAttribute(\"value\",\"\"),l.input=\"\"===b.getAttribute(\"value\"),b.value=\"t\",b.setAttribute(\"type\",\"radio\"),l.radioValue=\"t\"===b.value}();var rb=/\\r/g;n.fn.extend({val:function(a){var b,c,d,e=this[0];{if(arguments.length)return d=n.isFunction(a),this.each(function(c){var e;1===this.nodeType&&(e=d?a.call(this,c,n(this).val()):a,null==e?e=\"\":\"number\"==typeof e?e+=\"\":n.isArray(e)&&(e=n.map(e,function(a){return null==a?\"\":a+\"\"})),b=n.valHooks[this.type]||n.valHooks[this.nodeName.toLowerCase()],b&&\"set\"in b&&void 0!==b.set(this,e,\"value\")||(this.value=e))});if(e)return b=n.valHooks[e.type]||n.valHooks[e.nodeName.toLowerCase()],b&&\"get\"in b&&void 0!==(c=b.get(e,\"value\"))?c:(c=e.value,\"string\"==typeof c?c.replace(rb,\"\"):null==c?\"\":c)}}}),n.extend({valHooks:{option:{get:function(a){var b=n.find.attr(a,\"value\");return null!=b?b:n.trim(n.text(a))}},select:{get:function(a){for(var b,c,d=a.options,e=a.selectedIndex,f=\"select-one\"===a.type||0>e,g=f?null:[],h=f?e+1:d.length,i=0>e?h:f?e:0;h>i;i++)if(c=d[i],(c.selected||i===e)&&(l.optDisabled?!c.disabled:null===c.getAttribute(\"disabled\"))&&(!c.parentNode.disabled||!n.nodeName(c.parentNode,\"optgroup\"))){if(b=n(c).val(),f)return b;g.push(b)}return g},set:function(a,b){var c,d,e=a.options,f=n.makeArray(b),g=e.length;while(g--)if(d=e[g],n.inArray(n.valHooks.option.get(d),f)>=0)try{d.selected=c=!0}catch(h){d.scrollHeight}else d.selected=!1;return c||(a.selectedIndex=-1),e}}}}),n.each([\"radio\",\"checkbox\"],function(){n.valHooks[this]={set:function(a,b){return n.isArray(b)?a.checked=n.inArray(n(a).val(),b)>-1:void 0}},l.checkOn||(n.valHooks[this].get=function(a){return null===a.getAttribute(\"value\")?\"on\":a.value})});var sb,tb,ub=n.expr.attrHandle,vb=/^(?:checked|selected)$/i,wb=l.getSetAttribute,xb=l.input;n.fn.extend({attr:function(a,b){return Y(this,n.attr,a,b,arguments.length>1)},removeAttr:function(a){return this.each(function(){n.removeAttr(this,a)})}}),n.extend({attr:function(a,b,c){var d,e,f=a.nodeType;if(3!==f&&8!==f&&2!==f)return\"undefined\"==typeof a.getAttribute?n.prop(a,b,c):(1===f&&n.isXMLDoc(a)||(b=b.toLowerCase(),e=n.attrHooks[b]||(n.expr.match.bool.test(b)?tb:sb)),void 0!==c?null===c?void n.removeAttr(a,b):e&&\"set\"in e&&void 0!==(d=e.set(a,c,b))?d:(a.setAttribute(b,c+\"\"),c):e&&\"get\"in e&&null!==(d=e.get(a,b))?d:(d=n.find.attr(a,b),null==d?void 0:d))},attrHooks:{type:{set:function(a,b){if(!l.radioValue&&\"radio\"===b&&n.nodeName(a,\"input\")){var c=a.value;return a.setAttribute(\"type\",b),c&&(a.value=c),b}}}},removeAttr:function(a,b){var c,d,e=0,f=b&&b.match(G);if(f&&1===a.nodeType)while(c=f[e++])d=n.propFix[c]||c,n.expr.match.bool.test(c)?xb&&wb||!vb.test(c)?a[d]=!1:a[n.camelCase(\"default-\"+c)]=a[d]=!1:n.attr(a,c,\"\"),a.removeAttribute(wb?c:d)}}),tb={set:function(a,b,c){return b===!1?n.removeAttr(a,c):xb&&wb||!vb.test(c)?a.setAttribute(!wb&&n.propFix[c]||c,c):a[n.camelCase(\"default-\"+c)]=a[c]=!0,c}},n.each(n.expr.match.bool.source.match(/\\w+/g),function(a,b){var c=ub[b]||n.find.attr;xb&&wb||!vb.test(b)?ub[b]=function(a,b,d){var e,f;return d||(f=ub[b],ub[b]=e,e=null!=c(a,b,d)?b.toLowerCase():null,ub[b]=f),e}:ub[b]=function(a,b,c){return c?void 0:a[n.camelCase(\"default-\"+b)]?b.toLowerCase():null}}),xb&&wb||(n.attrHooks.value={set:function(a,b,c){return n.nodeName(a,\"input\")?void(a.defaultValue=b):sb&&sb.set(a,b,c)}}),wb||(sb={set:function(a,b,c){var d=a.getAttributeNode(c);return d||a.setAttributeNode(d=a.ownerDocument.createAttribute(c)),d.value=b+=\"\",\"value\"===c||b===a.getAttribute(c)?b:void 0}},ub.id=ub.name=ub.coords=function(a,b,c){var d;return c?void 0:(d=a.getAttributeNode(b))&&\"\"!==d.value?d.value:null},n.valHooks.button={get:function(a,b){var c=a.getAttributeNode(b);return c&&c.specified?c.value:void 0},set:sb.set},n.attrHooks.contenteditable={set:function(a,b,c){sb.set(a,\"\"===b?!1:b,c)}},n.each([\"width\",\"height\"],function(a,b){n.attrHooks[b]={set:function(a,c){return\"\"===c?(a.setAttribute(b,\"auto\"),c):void 0}}})),l.style||(n.attrHooks.style={get:function(a){return a.style.cssText||void 0},set:function(a,b){return a.style.cssText=b+\"\"}});var yb=/^(?:input|select|textarea|button|object)$/i,zb=/^(?:a|area)$/i;n.fn.extend({prop:function(a,b){return Y(this,n.prop,a,b,arguments.length>1)},removeProp:function(a){return a=n.propFix[a]||a,this.each(function(){try{this[a]=void 0,delete this[a]}catch(b){}})}}),n.extend({prop:function(a,b,c){var d,e,f=a.nodeType;if(3!==f&&8!==f&&2!==f)return 1===f&&n.isXMLDoc(a)||(b=n.propFix[b]||b,e=n.propHooks[b]),void 0!==c?e&&\"set\"in e&&void 0!==(d=e.set(a,c,b))?d:a[b]=c:e&&\"get\"in e&&null!==(d=e.get(a,b))?d:a[b]},propHooks:{tabIndex:{get:function(a){var b=n.find.attr(a,\"tabindex\");return b?parseInt(b,10):yb.test(a.nodeName)||zb.test(a.nodeName)&&a.href?0:-1}}},propFix:{\"for\":\"htmlFor\",\"class\":\"className\"}}),l.hrefNormalized||n.each([\"href\",\"src\"],function(a,b){n.propHooks[b]={get:function(a){return a.getAttribute(b,4)}}}),l.optSelected||(n.propHooks.selected={get:function(a){var b=a.parentNode;return b&&(b.selectedIndex,b.parentNode&&b.parentNode.selectedIndex),null}}),n.each([\"tabIndex\",\"readOnly\",\"maxLength\",\"cellSpacing\",\"cellPadding\",\"rowSpan\",\"colSpan\",\"useMap\",\"frameBorder\",\"contentEditable\"],function(){n.propFix[this.toLowerCase()]=this}),l.enctype||(n.propFix.enctype=\"encoding\");var Ab=/[\\t\\r\\n\\f]/g;function Bb(a){return n.attr(a,\"class\")||\"\"}n.fn.extend({addClass:function(a){var b,c,d,e,f,g,h,i=0;if(n.isFunction(a))return this.each(function(b){n(this).addClass(a.call(this,b,Bb(this)))});if(\"string\"==typeof a&&a){b=a.match(G)||[];while(c=this[i++])if(e=Bb(c),d=1===c.nodeType&&(\" \"+e+\" \").replace(Ab,\" \")){g=0;while(f=b[g++])d.indexOf(\" \"+f+\" \")<0&&(d+=f+\" \");h=n.trim(d),e!==h&&n.attr(c,\"class\",h)}}return this},removeClass:function(a){var b,c,d,e,f,g,h,i=0;if(n.isFunction(a))return this.each(function(b){n(this).removeClass(a.call(this,b,Bb(this)))});if(!arguments.length)return this.attr(\"class\",\"\");if(\"string\"==typeof a&&a){b=a.match(G)||[];while(c=this[i++])if(e=Bb(c),d=1===c.nodeType&&(\" \"+e+\" \").replace(Ab,\" \")){g=0;while(f=b[g++])while(d.indexOf(\" \"+f+\" \")>-1)d=d.replace(\" \"+f+\" \",\" \");h=n.trim(d),e!==h&&n.attr(c,\"class\",h)}}return this},toggleClass:function(a,b){var c=typeof a;return\"boolean\"==typeof b&&\"string\"===c?b?this.addClass(a):this.removeClass(a):n.isFunction(a)?this.each(function(c){n(this).toggleClass(a.call(this,c,Bb(this),b),b)}):this.each(function(){var b,d,e,f;if(\"string\"===c){d=0,e=n(this),f=a.match(G)||[];while(b=f[d++])e.hasClass(b)?e.removeClass(b):e.addClass(b)}else(void 0===a||\"boolean\"===c)&&(b=Bb(this),b&&n._data(this,\"__className__\",b),n.attr(this,\"class\",b||a===!1?\"\":n._data(this,\"__className__\")||\"\"))})},hasClass:function(a){var b,c,d=0;b=\" \"+a+\" \";while(c=this[d++])if(1===c.nodeType&&(\" \"+Bb(c)+\" \").replace(Ab,\" \").indexOf(b)>-1)return!0;return!1}}),n.each(\"blur focus focusin focusout load resize scroll unload click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup error contextmenu\".split(\" \"),function(a,b){n.fn[b]=function(a,c){return arguments.length>0?this.on(b,null,a,c):this.trigger(b)}}),n.fn.extend({hover:function(a,b){return this.mouseenter(a).mouseleave(b||a)}});var Cb=a.location,Db=n.now(),Eb=/\\?/,Fb=/(,)|(\\[|{)|(}|])|\"(?:[^\"\\\\\\r\\n]|\\\\[\"\\\\\\/bfnrt]|\\\\u[\\da-fA-F]{4})*\"\\s*:?|true|false|null|-?(?!0\\d)\\d+(?:\\.\\d+|)(?:[eE][+-]?\\d+|)/g;n.parseJSON=function(b){if(a.JSON&&a.JSON.parse)return a.JSON.parse(b+\"\");var c,d=null,e=n.trim(b+\"\");return e&&!n.trim(e.replace(Fb,function(a,b,e,f){return c&&b&&(d=0),0===d?a:(c=e||b,d+=!f-!e,\"\")}))?Function(\"return \"+e)():n.error(\"Invalid JSON: \"+b)},n.parseXML=function(b){var c,d;if(!b||\"string\"!=typeof b)return null;try{a.DOMParser?(d=new a.DOMParser,c=d.parseFromString(b,\"text/xml\")):(c=new a.ActiveXObject(\"Microsoft.XMLDOM\"),c.async=\"false\",c.loadXML(b))}catch(e){c=void 0}return c&&c.documentElement&&!c.getElementsByTagName(\"parsererror\").length||n.error(\"Invalid XML: \"+b),c};var Gb=/#.*$/,Hb=/([?&])_=[^&]*/,Ib=/^(.*?):[ \\t]*([^\\r\\n]*)\\r?$/gm,Jb=/^(?:about|app|app-storage|.+-extension|file|res|widget):$/,Kb=/^(?:GET|HEAD)$/,Lb=/^\\/\\//,Mb=/^([\\w.+-]+:)(?:\\/\\/(?:[^\\/?#]*@|)([^\\/?#:]*)(?::(\\d+)|)|)/,Nb={},Ob={},Pb=\"*/\".concat(\"*\"),Qb=Cb.href,Rb=Mb.exec(Qb.toLowerCase())||[];function Sb(a){return function(b,c){\"string\"!=typeof b&&(c=b,b=\"*\");var d,e=0,f=b.toLowerCase().match(G)||[];if(n.isFunction(c))while(d=f[e++])\"+\"===d.charAt(0)?(d=d.slice(1)||\"*\",(a[d]=a[d]||[]).unshift(c)):(a[d]=a[d]||[]).push(c)}}function Tb(a,b,c,d){var e={},f=a===Ob;function g(h){var i;return e[h]=!0,n.each(a[h]||[],function(a,h){var j=h(b,c,d);return\"string\"!=typeof j||f||e[j]?f?!(i=j):void 0:(b.dataTypes.unshift(j),g(j),!1)}),i}return g(b.dataTypes[0])||!e[\"*\"]&&g(\"*\")}function Ub(a,b){var c,d,e=n.ajaxSettings.flatOptions||{};for(d in b)void 0!==b[d]&&((e[d]?a:c||(c={}))[d]=b[d]);return c&&n.extend(!0,a,c),a}function Vb(a,b,c){var d,e,f,g,h=a.contents,i=a.dataTypes;while(\"*\"===i[0])i.shift(),void 0===e&&(e=a.mimeType||b.getResponseHeader(\"Content-Type\"));if(e)for(g in h)if(h[g]&&h[g].test(e)){i.unshift(g);break}if(i[0]in c)f=i[0];else{for(g in c){if(!i[0]||a.converters[g+\" \"+i[0]]){f=g;break}d||(d=g)}f=f||d}return f?(f!==i[0]&&i.unshift(f),c[f]):void 0}function Wb(a,b,c,d){var e,f,g,h,i,j={},k=a.dataTypes.slice();if(k[1])for(g in a.converters)j[g.toLowerCase()]=a.converters[g];f=k.shift();while(f)if(a.responseFields[f]&&(c[a.responseFields[f]]=b),!i&&d&&a.dataFilter&&(b=a.dataFilter(b,a.dataType)),i=f,f=k.shift())if(\"*\"===f)f=i;else if(\"*\"!==i&&i!==f){if(g=j[i+\" \"+f]||j[\"* \"+f],!g)for(e in j)if(h=e.split(\" \"),h[1]===f&&(g=j[i+\" \"+h[0]]||j[\"* \"+h[0]])){g===!0?g=j[e]:j[e]!==!0&&(f=h[0],k.unshift(h[1]));break}if(g!==!0)if(g&&a[\"throws\"])b=g(b);else try{b=g(b)}catch(l){return{state:\"parsererror\",error:g?l:\"No conversion from \"+i+\" to \"+f}}}return{state:\"success\",data:b}}n.extend({active:0,lastModified:{},etag:{},ajaxSettings:{url:Qb,type:\"GET\",isLocal:Jb.test(Rb[1]),global:!0,processData:!0,async:!0,contentType:\"application/x-www-form-urlencoded; charset=UTF-8\",accepts:{\"*\":Pb,text:\"text/plain\",html:\"text/html\",xml:\"application/xml, text/xml\",json:\"application/json, text/javascript\"},contents:{xml:/\\bxml\\b/,html:/\\bhtml/,json:/\\bjson\\b/},responseFields:{xml:\"responseXML\",text:\"responseText\",json:\"responseJSON\"},converters:{\"* text\":String,\"text html\":!0,\"text json\":n.parseJSON,\"text xml\":n.parseXML},flatOptions:{url:!0,context:!0}},ajaxSetup:function(a,b){return b?Ub(Ub(a,n.ajaxSettings),b):Ub(n.ajaxSettings,a)},ajaxPrefilter:Sb(Nb),ajaxTransport:Sb(Ob),ajax:function(b,c){\"object\"==typeof b&&(c=b,b=void 0),c=c||{};var d,e,f,g,h,i,j,k,l=n.ajaxSetup({},c),m=l.context||l,o=l.context&&(m.nodeType||m.jquery)?n(m):n.event,p=n.Deferred(),q=n.Callbacks(\"once memory\"),r=l.statusCode||{},s={},t={},u=0,v=\"canceled\",w={readyState:0,getResponseHeader:function(a){var b;if(2===u){if(!k){k={};while(b=Ib.exec(g))k[b[1].toLowerCase()]=b[2]}b=k[a.toLowerCase()]}return null==b?null:b},getAllResponseHeaders:function(){return 2===u?g:null},setRequestHeader:function(a,b){var c=a.toLowerCase();return u||(a=t[c]=t[c]||a,s[a]=b),this},overrideMimeType:function(a){return u||(l.mimeType=a),this},statusCode:function(a){var b;if(a)if(2>u)for(b in a)r[b]=[r[b],a[b]];else w.always(a[w.status]);return this},abort:function(a){var b=a||v;return j&&j.abort(b),y(0,b),this}};if(p.promise(w).complete=q.add,w.success=w.done,w.error=w.fail,l.url=((b||l.url||Qb)+\"\").replace(Gb,\"\").replace(Lb,Rb[1]+\"//\"),l.type=c.method||c.type||l.method||l.type,l.dataTypes=n.trim(l.dataType||\"*\").toLowerCase().match(G)||[\"\"],null==l.crossDomain&&(d=Mb.exec(l.url.toLowerCase()),l.crossDomain=!(!d||d[1]===Rb[1]&&d[2]===Rb[2]&&(d[3]||(\"http:\"===d[1]?\"80\":\"443\"))===(Rb[3]||(\"http:\"===Rb[1]?\"80\":\"443\")))),l.data&&l.processData&&\"string\"!=typeof l.data&&(l.data=n.param(l.data,l.traditional)),Tb(Nb,l,c,w),2===u)return w;i=n.event&&l.global,i&&0===n.active++&&n.event.trigger(\"ajaxStart\"),l.type=l.type.toUpperCase(),l.hasContent=!Kb.test(l.type),f=l.url,l.hasContent||(l.data&&(f=l.url+=(Eb.test(f)?\"&\":\"?\")+l.data,delete l.data),l.cache===!1&&(l.url=Hb.test(f)?f.replace(Hb,\"$1_=\"+Db++):f+(Eb.test(f)?\"&\":\"?\")+\"_=\"+Db++)),l.ifModified&&(n.lastModified[f]&&w.setRequestHeader(\"If-Modified-Since\",n.lastModified[f]),n.etag[f]&&w.setRequestHeader(\"If-None-Match\",n.etag[f])),(l.data&&l.hasContent&&l.contentType!==!1||c.contentType)&&w.setRequestHeader(\"Content-Type\",l.contentType),w.setRequestHeader(\"Accept\",l.dataTypes[0]&&l.accepts[l.dataTypes[0]]?l.accepts[l.dataTypes[0]]+(\"*\"!==l.dataTypes[0]?\", \"+Pb+\"; q=0.01\":\"\"):l.accepts[\"*\"]);for(e in l.headers)w.setRequestHeader(e,l.headers[e]);if(l.beforeSend&&(l.beforeSend.call(m,w,l)===!1||2===u))return w.abort();v=\"abort\";for(e in{success:1,error:1,complete:1})w[e](l[e]);if(j=Tb(Ob,l,c,w)){if(w.readyState=1,i&&o.trigger(\"ajaxSend\",[w,l]),2===u)return w;l.async&&l.timeout>0&&(h=a.setTimeout(function(){w.abort(\"timeout\")},l.timeout));try{u=1,j.send(s,y)}catch(x){if(!(2>u))throw x;y(-1,x)}}else y(-1,\"No Transport\");function y(b,c,d,e){var k,s,t,v,x,y=c;2!==u&&(u=2,h&&a.clearTimeout(h),j=void 0,g=e||\"\",w.readyState=b>0?4:0,k=b>=200&&300>b||304===b,d&&(v=Vb(l,w,d)),v=Wb(l,v,w,k),k?(l.ifModified&&(x=w.getResponseHeader(\"Last-Modified\"),x&&(n.lastModified[f]=x),x=w.getResponseHeader(\"etag\"),x&&(n.etag[f]=x)),204===b||\"HEAD\"===l.type?y=\"nocontent\":304===b?y=\"notmodified\":(y=v.state,s=v.data,t=v.error,k=!t)):(t=y,(b||!y)&&(y=\"error\",0>b&&(b=0))),w.status=b,w.statusText=(c||y)+\"\",k?p.resolveWith(m,[s,y,w]):p.rejectWith(m,[w,y,t]),w.statusCode(r),r=void 0,i&&o.trigger(k?\"ajaxSuccess\":\"ajaxError\",[w,l,k?s:t]),q.fireWith(m,[w,y]),i&&(o.trigger(\"ajaxComplete\",[w,l]),--n.active||n.event.trigger(\"ajaxStop\")))}return w},getJSON:function(a,b,c){return n.get(a,b,c,\"json\")},getScript:function(a,b){return n.get(a,void 0,b,\"script\")}}),n.each([\"get\",\"post\"],function(a,b){n[b]=function(a,c,d,e){return n.isFunction(c)&&(e=e||d,d=c,c=void 0),n.ajax(n.extend({url:a,type:b,dataType:e,data:c,success:d},n.isPlainObject(a)&&a))}}),n._evalUrl=function(a){return n.ajax({url:a,type:\"GET\",dataType:\"script\",cache:!0,async:!1,global:!1,\"throws\":!0})},n.fn.extend({wrapAll:function(a){if(n.isFunction(a))return this.each(function(b){n(this).wrapAll(a.call(this,b))});if(this[0]){var b=n(a,this[0].ownerDocument).eq(0).clone(!0);this[0].parentNode&&b.insertBefore(this[0]),b.map(function(){var a=this;while(a.firstChild&&1===a.firstChild.nodeType)a=a.firstChild;return a}).append(this)}return this},wrapInner:function(a){return n.isFunction(a)?this.each(function(b){n(this).wrapInner(a.call(this,b))}):this.each(function(){var b=n(this),c=b.contents();c.length?c.wrapAll(a):b.append(a)})},wrap:function(a){var b=n.isFunction(a);return this.each(function(c){n(this).wrapAll(b?a.call(this,c):a)})},unwrap:function(){return this.parent().each(function(){n.nodeName(this,\"body\")||n(this).replaceWith(this.childNodes)}).end()}});function Xb(a){return a.style&&a.style.display||n.css(a,\"display\")}function Yb(a){while(a&&1===a.nodeType){if(\"none\"===Xb(a)||\"hidden\"===a.type)return!0;a=a.parentNode}return!1}n.expr.filters.hidden=function(a){return l.reliableHiddenOffsets()?a.offsetWidth<=0&&a.offsetHeight<=0&&!a.getClientRects().length:Yb(a)},n.expr.filters.visible=function(a){return!n.expr.filters.hidden(a)};var Zb=/%20/g,$b=/\\[\\]$/,_b=/\\r?\\n/g,ac=/^(?:submit|button|image|reset|file)$/i,bc=/^(?:input|select|textarea|keygen)/i;function cc(a,b,c,d){var e;if(n.isArray(b))n.each(b,function(b,e){c||$b.test(a)?d(a,e):cc(a+\"[\"+(\"object\"==typeof e&&null!=e?b:\"\")+\"]\",e,c,d)});else if(c||\"object\"!==n.type(b))d(a,b);else for(e in b)cc(a+\"[\"+e+\"]\",b[e],c,d)}n.param=function(a,b){var c,d=[],e=function(a,b){b=n.isFunction(b)?b():null==b?\"\":b,d[d.length]=encodeURIComponent(a)+\"=\"+encodeURIComponent(b)};if(void 0===b&&(b=n.ajaxSettings&&n.ajaxSettings.traditional),n.isArray(a)||a.jquery&&!n.isPlainObject(a))n.each(a,function(){e(this.name,this.value)});else for(c in a)cc(c,a[c],b,e);return d.join(\"&\").replace(Zb,\"+\")},n.fn.extend({serialize:function(){return n.param(this.serializeArray())},serializeArray:function(){return this.map(function(){var a=n.prop(this,\"elements\");return a?n.makeArray(a):this}).filter(function(){var a=this.type;return this.name&&!n(this).is(\":disabled\")&&bc.test(this.nodeName)&&!ac.test(a)&&(this.checked||!Z.test(a))}).map(function(a,b){var c=n(this).val();return null==c?null:n.isArray(c)?n.map(c,function(a){return{name:b.name,value:a.replace(_b,\"\\r\\n\")}}):{name:b.name,value:c.replace(_b,\"\\r\\n\")}}).get()}}),n.ajaxSettings.xhr=void 0!==a.ActiveXObject?function(){return this.isLocal?hc():d.documentMode>8?gc():/^(get|post|head|put|delete|options)$/i.test(this.type)&&gc()||hc()}:gc;var dc=0,ec={},fc=n.ajaxSettings.xhr();a.attachEvent&&a.attachEvent(\"onunload\",function(){for(var a in ec)ec[a](void 0,!0)}),l.cors=!!fc&&\"withCredentials\"in fc,fc=l.ajax=!!fc,fc&&n.ajaxTransport(function(b){if(!b.crossDomain||l.cors){var c;return{send:function(d,e){var f,g=b.xhr(),h=++dc;if(g.open(b.type,b.url,b.async,b.username,b.password),b.xhrFields)for(f in b.xhrFields)g[f]=b.xhrFields[f];b.mimeType&&g.overrideMimeType&&g.overrideMimeType(b.mimeType),b.crossDomain||d[\"X-Requested-With\"]||(d[\"X-Requested-With\"]=\"XMLHttpRequest\");for(f in d)void 0!==d[f]&&g.setRequestHeader(f,d[f]+\"\");g.send(b.hasContent&&b.data||null),c=function(a,d){var f,i,j;if(c&&(d||4===g.readyState))if(delete ec[h],c=void 0,g.onreadystatechange=n.noop,d)4!==g.readyState&&g.abort();else{j={},f=g.status,\"string\"==typeof g.responseText&&(j.text=g.responseText);try{i=g.statusText}catch(k){i=\"\"}f||!b.isLocal||b.crossDomain?1223===f&&(f=204):f=j.text?200:404}j&&e(f,i,j,g.getAllResponseHeaders())},b.async?4===g.readyState?a.setTimeout(c):g.onreadystatechange=ec[h]=c:c()},abort:function(){c&&c(void 0,!0)}}}});function gc(){try{return new a.XMLHttpRequest}catch(b){}}function hc(){try{return new a.ActiveXObject(\"Microsoft.XMLHTTP\")}catch(b){}}n.ajaxPrefilter(function(a){a.crossDomain&&(a.contents.script=!1)}),n.ajaxSetup({accepts:{script:\"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript\"},contents:{script:/\\b(?:java|ecma)script\\b/},converters:{\"text script\":function(a){return n.globalEval(a),a}}}),n.ajaxPrefilter(\"script\",function(a){void 0===a.cache&&(a.cache=!1),a.crossDomain&&(a.type=\"GET\",a.global=!1)}),n.ajaxTransport(\"script\",function(a){if(a.crossDomain){var b,c=d.head||n(\"head\")[0]||d.documentElement;return{send:function(e,f){b=d.createElement(\"script\"),b.async=!0,a.scriptCharset&&(b.charset=a.scriptCharset),b.src=a.url,b.onload=b.onreadystatechange=function(a,c){(c||!b.readyState||/loaded|complete/.test(b.readyState))&&(b.onload=b.onreadystatechange=null,b.parentNode&&b.parentNode.removeChild(b),b=null,c||f(200,\"success\"))},c.insertBefore(b,c.firstChild)},abort:function(){b&&b.onload(void 0,!0)}}}});var ic=[],jc=/(=)\\?(?=&|$)|\\?\\?/;n.ajaxSetup({jsonp:\"callback\",jsonpCallback:function(){var a=ic.pop()||n.expando+\"_\"+Db++;return this[a]=!0,a}}),n.ajaxPrefilter(\"json jsonp\",function(b,c,d){var e,f,g,h=b.jsonp!==!1&&(jc.test(b.url)?\"url\":\"string\"==typeof b.data&&0===(b.contentType||\"\").indexOf(\"application/x-www-form-urlencoded\")&&jc.test(b.data)&&\"data\");return h||\"jsonp\"===b.dataTypes[0]?(e=b.jsonpCallback=n.isFunction(b.jsonpCallback)?b.jsonpCallback():b.jsonpCallback,h?b[h]=b[h].replace(jc,\"$1\"+e):b.jsonp!==!1&&(b.url+=(Eb.test(b.url)?\"&\":\"?\")+b.jsonp+\"=\"+e),b.converters[\"script json\"]=function(){return g||n.error(e+\" was not called\"),g[0]},b.dataTypes[0]=\"json\",f=a[e],a[e]=function(){g=arguments},d.always(function(){void 0===f?n(a).removeProp(e):a[e]=f,b[e]&&(b.jsonpCallback=c.jsonpCallback,ic.push(e)),g&&n.isFunction(f)&&f(g[0]),g=f=void 0}),\"script\"):void 0}),l.createHTMLDocument=function(){if(!d.implementation.createHTMLDocument)return!1;var a=d.implementation.createHTMLDocument(\"\");return a.body.innerHTML=\"<form></form><form></form>\",2===a.body.childNodes.length}(),n.parseHTML=function(a,b,c){if(!a||\"string\"!=typeof a)return null;\"boolean\"==typeof b&&(c=b,b=!1),b=b||(l.createHTMLDocument?d.implementation.createHTMLDocument(\"\"):d);var e=x.exec(a),f=!c&&[];return e?[b.createElement(e[1])]:(e=ja([a],b,f),f&&f.length&&n(f).remove(),n.merge([],e.childNodes))};var kc=n.fn.load;n.fn.load=function(a,b,c){if(\"string\"!=typeof a&&kc)return kc.apply(this,arguments);var d,e,f,g=this,h=a.indexOf(\" \");return h>-1&&(d=n.trim(a.slice(h,a.length)),a=a.slice(0,h)),n.isFunction(b)?(c=b,b=void 0):b&&\"object\"==typeof b&&(e=\"POST\"),g.length>0&&n.ajax({url:a,type:e||\"GET\",dataType:\"html\",data:b}).done(function(a){f=arguments,g.html(d?n(\"<div>\").append(n.parseHTML(a)).find(d):a)}).always(c&&function(a,b){g.each(function(){c.apply(g,f||[a.responseText,b,a])})}),this},n.each([\"ajaxStart\",\"ajaxStop\",\"ajaxComplete\",\"ajaxError\",\"ajaxSuccess\",\"ajaxSend\"],function(a,b){n.fn[b]=function(a){return this.on(b,a)}}),n.expr.filters.animated=function(a){return n.grep(n.timers,function(b){return a===b.elem}).length};function lc(a){return n.isWindow(a)?a:9===a.nodeType?a.defaultView||a.parentWindow:!1}n.offset={setOffset:function(a,b,c){var d,e,f,g,h,i,j,k=n.css(a,\"position\"),l=n(a),m={};\"static\"===k&&(a.style.position=\"relative\"),h=l.offset(),f=n.css(a,\"top\"),i=n.css(a,\"left\"),j=(\"absolute\"===k||\"fixed\"===k)&&n.inArray(\"auto\",[f,i])>-1,j?(d=l.position(),g=d.top,e=d.left):(g=parseFloat(f)||0,e=parseFloat(i)||0),n.isFunction(b)&&(b=b.call(a,c,n.extend({},h))),null!=b.top&&(m.top=b.top-h.top+g),null!=b.left&&(m.left=b.left-h.left+e),\"using\"in b?b.using.call(a,m):l.css(m)}},n.fn.extend({offset:function(a){if(arguments.length)return void 0===a?this:this.each(function(b){n.offset.setOffset(this,a,b)});var b,c,d={top:0,left:0},e=this[0],f=e&&e.ownerDocument;if(f)return b=f.documentElement,n.contains(b,e)?(\"undefined\"!=typeof e.getBoundingClientRect&&(d=e.getBoundingClientRect()),c=lc(f),{top:d.top+(c.pageYOffset||b.scrollTop)-(b.clientTop||0),left:d.left+(c.pageXOffset||b.scrollLeft)-(b.clientLeft||0)}):d},position:function(){if(this[0]){var a,b,c={top:0,left:0},d=this[0];return\"fixed\"===n.css(d,\"position\")?b=d.getBoundingClientRect():(a=this.offsetParent(),b=this.offset(),n.nodeName(a[0],\"html\")||(c=a.offset()),c.top+=n.css(a[0],\"borderTopWidth\",!0)-a.scrollTop(),c.left+=n.css(a[0],\"borderLeftWidth\",!0)-a.scrollLeft()),{top:b.top-c.top-n.css(d,\"marginTop\",!0),left:b.left-c.left-n.css(d,\"marginLeft\",!0)}}},offsetParent:function(){return this.map(function(){var a=this.offsetParent;while(a&&!n.nodeName(a,\"html\")&&\"static\"===n.css(a,\"position\"))a=a.offsetParent;return a||Qa})}}),n.each({scrollLeft:\"pageXOffset\",scrollTop:\"pageYOffset\"},function(a,b){var c=/Y/.test(b);n.fn[a]=function(d){return Y(this,function(a,d,e){var f=lc(a);return void 0===e?f?b in f?f[b]:f.document.documentElement[d]:a[d]:void(f?f.scrollTo(c?n(f).scrollLeft():e,c?e:n(f).scrollTop()):a[d]=e)},a,d,arguments.length,null)}}),n.each([\"top\",\"left\"],function(a,b){\nn.cssHooks[b]=Ua(l.pixelPosition,function(a,c){return c?(c=Sa(a,b),Oa.test(c)?n(a).position()[b]+\"px\":c):void 0})}),n.each({Height:\"height\",Width:\"width\"},function(a,b){n.each({padding:\"inner\"+a,content:b,\"\":\"outer\"+a},function(c,d){n.fn[d]=function(d,e){var f=arguments.length&&(c||\"boolean\"!=typeof d),g=c||(d===!0||e===!0?\"margin\":\"border\");return Y(this,function(b,c,d){var e;return n.isWindow(b)?b.document.documentElement[\"client\"+a]:9===b.nodeType?(e=b.documentElement,Math.max(b.body[\"scroll\"+a],e[\"scroll\"+a],b.body[\"offset\"+a],e[\"offset\"+a],e[\"client\"+a])):void 0===d?n.css(b,c,g):n.style(b,c,d,g)},b,f?d:void 0,f,null)}})}),n.fn.extend({bind:function(a,b,c){return this.on(a,null,b,c)},unbind:function(a,b){return this.off(a,null,b)},delegate:function(a,b,c,d){return this.on(b,a,c,d)},undelegate:function(a,b,c){return 1===arguments.length?this.off(a,\"**\"):this.off(b,a||\"**\",c)}}),n.fn.size=function(){return this.length},n.fn.andSelf=n.fn.addBack,\"function\"==typeof define&&define.amd&&define(\"jquery\",[],function(){return n});var mc=a.jQuery,nc=a.$;return n.noConflict=function(b){return a.$===n&&(a.$=nc),b&&a.jQuery===n&&(a.jQuery=mc),n},b||(a.jQuery=a.$=n),n});"
  },
  {
    "path": "app_backend/vendor/datatables-plugins/dataTables.bootstrap.css",
    "content": "div.dataTables_length label {\n\tfont-weight: normal;\n\ttext-align: left;\n\twhite-space: nowrap;\n}\n\ndiv.dataTables_length select {\n\twidth: 75px;\n\tdisplay: inline-block;\n}\n\ndiv.dataTables_filter {\n\ttext-align: right;\n}\n\ndiv.dataTables_filter label {\n\tfont-weight: normal;\n\twhite-space: nowrap;\n\ttext-align: left;\n}\n\ndiv.dataTables_filter input {\n\tmargin-left: 0.5em;\n\tdisplay: inline-block;\n}\n\ndiv.dataTables_info {\n\tpadding-top: 8px;\n\twhite-space: nowrap;\n}\n\ndiv.dataTables_paginate {\n\tmargin: 0;\n\twhite-space: nowrap;\n\ttext-align: right;\n}\n\ndiv.dataTables_paginate ul.pagination {\n\tmargin: 2px 0;\n\twhite-space: nowrap;\n}\n\n@media screen and (max-width: 767px) {\n\tdiv.dataTables_length,\n\tdiv.dataTables_filter,\n\tdiv.dataTables_info,\n\tdiv.dataTables_paginate {\n\t\ttext-align: center;\n\t}\n}\n\n\ntable.dataTable td,\ntable.dataTable th {\n\t-webkit-box-sizing: content-box;\n\t-moz-box-sizing: content-box;\n\tbox-sizing: content-box;\n}\n\n\ntable.dataTable {\n\tclear: both;\n\tmargin-top: 6px !important;\n\tmargin-bottom: 6px !important;\n\tmax-width: none !important;\n}\n\ntable.dataTable thead .sorting,\ntable.dataTable thead .sorting_asc,\ntable.dataTable thead .sorting_desc,\ntable.dataTable thead .sorting_asc_disabled,\ntable.dataTable thead .sorting_desc_disabled {\n\tcursor: pointer;\n}\n\ntable.dataTable thead .sorting { background: url('../images/sort_both.png') no-repeat center right; }\ntable.dataTable thead .sorting_asc { background: url('../images/sort_asc.png') no-repeat center right; }\ntable.dataTable thead .sorting_desc { background: url('../images/sort_desc.png') no-repeat center right; }\n\ntable.dataTable thead .sorting_asc_disabled { background: url('../images/sort_asc_disabled.png') no-repeat center right; }\ntable.dataTable thead .sorting_desc_disabled { background: url('../images/sort_desc_disabled.png') no-repeat center right; }\n\ntable.dataTable thead > tr > th {\n\tpadding-left: 18px;\n\tpadding-right: 18px;\n}\n\ntable.dataTable th:active {\n\toutline: none;\n}\n\n/* Scrolling */\ndiv.dataTables_scrollHead table {\n\tmargin-bottom: 0 !important;\n\tborder-bottom-left-radius: 0;\n\tborder-bottom-right-radius: 0;\n}\n\ndiv.dataTables_scrollHead table thead tr:last-child th:first-child,\ndiv.dataTables_scrollHead table thead tr:last-child td:first-child {\n\tborder-bottom-left-radius: 0 !important;\n\tborder-bottom-right-radius: 0 !important;\n}\n\ndiv.dataTables_scrollBody table {\n\tborder-top: none;\n\tmargin-top: 0 !important;\n\tmargin-bottom: 0 !important;\n}\n\ndiv.dataTables_scrollBody tbody tr:first-child th,\ndiv.dataTables_scrollBody tbody tr:first-child td {\n\tborder-top: none;\n}\n\ndiv.dataTables_scrollFoot table {\n\tmargin-top: 0 !important;\n\tborder-top: none;\n}\n\n/* Frustratingly the border-collapse:collapse used by Bootstrap makes the column\n   width calculations when using scrolling impossible to align columns. We have\n   to use separate\n */\ntable.table-bordered.dataTable {\n\tborder-collapse: separate !important;\n}\ntable.table-bordered thead th,\ntable.table-bordered thead td {\n\tborder-left-width: 0;\n\tborder-top-width: 0;\n}\ntable.table-bordered tbody th,\ntable.table-bordered tbody td {\n\tborder-left-width: 0;\n\tborder-bottom-width: 0;\n}\ntable.table-bordered th:last-child,\ntable.table-bordered td:last-child {\n\tborder-right-width: 0;\n}\ndiv.dataTables_scrollHead table.table-bordered {\n\tborder-bottom-width: 0;\n}\n\n\n\n\n/*\n * TableTools styles\n */\n.table.dataTable tbody tr.active td,\n.table.dataTable tbody tr.active th {\n\tbackground-color: #08C;\n\tcolor: white;\n}\n\n.table.dataTable tbody tr.active:hover td,\n.table.dataTable tbody tr.active:hover th {\n\tbackground-color: #0075b0 !important;\n}\n\n.table.dataTable tbody tr.active th > a,\n.table.dataTable tbody tr.active td > a {\n\tcolor: white;\n}\n\n.table-striped.dataTable tbody tr.active:nth-child(odd) td,\n.table-striped.dataTable tbody tr.active:nth-child(odd) th {\n\tbackground-color: #017ebc;\n}\n\ntable.DTTT_selectable tbody tr {\n\tcursor: pointer;\n}\n\ndiv.DTTT .btn:hover {\n\ttext-decoration: none !important;\n}\n\nul.DTTT_dropdown.dropdown-menu {\n  z-index: 2003;\n}\n\nul.DTTT_dropdown.dropdown-menu a {\n\tcolor: #333 !important; /* needed only when demo_page.css is included */\n}\n\nul.DTTT_dropdown.dropdown-menu li {\n\tposition: relative;\n}\n\nul.DTTT_dropdown.dropdown-menu li:hover a {\n\tbackground-color: #0088cc;\n\tcolor: white !important;\n}\n\ndiv.DTTT_collection_background {\n\tz-index: 2002;\t\n}\n\n/* TableTools information display */\ndiv.DTTT_print_info {\n\tposition: fixed;\n\ttop: 50%;\n\tleft: 50%;\n\twidth: 400px;\n\theight: 150px;\n\tmargin-left: -200px;\n\tmargin-top: -75px;\n\ttext-align: center;\n\tcolor: #333;\n\tpadding: 10px 30px;\n\topacity: 0.95;\n\n\tbackground-color: white;\n\tborder: 1px solid rgba(0, 0, 0, 0.2);\n\tborder-radius: 6px;\n\t\n\t-webkit-box-shadow: 0 3px 7px rgba(0, 0, 0, 0.5);\n\t        box-shadow: 0 3px 7px rgba(0, 0, 0, 0.5);\n}\n\ndiv.DTTT_print_info h6 {\n\tfont-weight: normal;\n\tfont-size: 28px;\n\tline-height: 28px;\n\tmargin: 1em;\n}\n\ndiv.DTTT_print_info p {\n\tfont-size: 14px;\n\tline-height: 20px;\n}\n\ndiv.dataTables_processing {\n    position: absolute;\n    top: 50%;\n    left: 50%;\n    width: 100%;\n    height: 60px;\n    margin-left: -50%;\n    margin-top: -25px;\n    padding-top: 20px;\n    padding-bottom: 20px;\n    text-align: center;\n    font-size: 1.2em;\n    background-color: white;\n    background: -webkit-gradient(linear, left top, right top, color-stop(0%, rgba(255,255,255,0)), color-stop(25%, rgba(255,255,255,0.9)), color-stop(75%, rgba(255,255,255,0.9)), color-stop(100%, rgba(255,255,255,0)));\n    background: -webkit-linear-gradient(left, rgba(255,255,255,0) 0%, rgba(255,255,255,0.9) 25%, rgba(255,255,255,0.9) 75%, rgba(255,255,255,0) 100%);\n    background: -moz-linear-gradient(left, rgba(255,255,255,0) 0%, rgba(255,255,255,0.9) 25%, rgba(255,255,255,0.9) 75%, rgba(255,255,255,0) 100%);\n    background: -ms-linear-gradient(left, rgba(255,255,255,0) 0%, rgba(255,255,255,0.9) 25%, rgba(255,255,255,0.9) 75%, rgba(255,255,255,0) 100%);\n    background: -o-linear-gradient(left, rgba(255,255,255,0) 0%, rgba(255,255,255,0.9) 25%, rgba(255,255,255,0.9) 75%, rgba(255,255,255,0) 100%);\n    background: linear-gradient(to right, rgba(255,255,255,0) 0%, rgba(255,255,255,0.9) 25%, rgba(255,255,255,0.9) 75%, rgba(255,255,255,0) 100%);\n}\n\n\n\n/*\n * FixedColumns styles\n */\ndiv.DTFC_LeftHeadWrapper table,\ndiv.DTFC_LeftFootWrapper table,\ndiv.DTFC_RightHeadWrapper table,\ndiv.DTFC_RightFootWrapper table,\ntable.DTFC_Cloned tr.even {\n    background-color: white;\n    margin-bottom: 0;\n}\n \ndiv.DTFC_RightHeadWrapper table ,\ndiv.DTFC_LeftHeadWrapper table {\n\tborder-bottom: none !important;\n    margin-bottom: 0 !important;\n    border-top-right-radius: 0 !important;\n    border-bottom-left-radius: 0 !important;\n    border-bottom-right-radius: 0 !important;\n}\n \ndiv.DTFC_RightHeadWrapper table thead tr:last-child th:first-child,\ndiv.DTFC_RightHeadWrapper table thead tr:last-child td:first-child,\ndiv.DTFC_LeftHeadWrapper table thead tr:last-child th:first-child,\ndiv.DTFC_LeftHeadWrapper table thead tr:last-child td:first-child {\n    border-bottom-left-radius: 0 !important;\n    border-bottom-right-radius: 0 !important;\n}\n \ndiv.DTFC_RightBodyWrapper table,\ndiv.DTFC_LeftBodyWrapper table {\n    border-top: none;\n    margin: 0 !important;\n}\n \ndiv.DTFC_RightBodyWrapper tbody tr:first-child th,\ndiv.DTFC_RightBodyWrapper tbody tr:first-child td,\ndiv.DTFC_LeftBodyWrapper tbody tr:first-child th,\ndiv.DTFC_LeftBodyWrapper tbody tr:first-child td {\n    border-top: none;\n}\n \ndiv.DTFC_RightFootWrapper table,\ndiv.DTFC_LeftFootWrapper table {\n    border-top: none;\n    margin-top: 0 !important;\n}\n\n\n/*\n * FixedHeader styles\n */\ndiv.FixedHeader_Cloned table {\n\tmargin: 0 !important\n}\n\n"
  },
  {
    "path": "app_backend/vendor/datatables-plugins/dataTables.bootstrap.js",
    "content": "/*! DataTables Bootstrap 3 integration\n * ©2011-2014 SpryMedia Ltd - datatables.net/license\n */\n\n/**\n * DataTables integration for Bootstrap 3. This requires Bootstrap 3 and\n * DataTables 1.10 or newer.\n *\n * This file sets the defaults and adds options to DataTables to style its\n * controls using Bootstrap. See http://datatables.net/manual/styling/bootstrap\n * for further information.\n */\n(function(window, document, undefined){\n\nvar factory = function( $, DataTable ) {\n\"use strict\";\n\n\n/* Set the defaults for DataTables initialisation */\n$.extend( true, DataTable.defaults, {\n\tdom:\n\t\t\"<'row'<'col-sm-6'l><'col-sm-6'f>>\" +\n\t\t\"<'row'<'col-sm-12'tr>>\" +\n\t\t\"<'row'<'col-sm-6'i><'col-sm-6'p>>\",\n\trenderer: 'bootstrap'\n} );\n\n\n/* Default class modification */\n$.extend( DataTable.ext.classes, {\n\tsWrapper:      \"dataTables_wrapper form-inline dt-bootstrap\",\n\tsFilterInput:  \"form-control input-sm\",\n\tsLengthSelect: \"form-control input-sm\"\n} );\n\n\n/* Bootstrap paging button renderer */\nDataTable.ext.renderer.pageButton.bootstrap = function ( settings, host, idx, buttons, page, pages ) {\n\tvar api     = new DataTable.Api( settings );\n\tvar classes = settings.oClasses;\n\tvar lang    = settings.oLanguage.oPaginate;\n\tvar btnDisplay, btnClass;\n\n\tvar attach = function( container, buttons ) {\n\t\tvar i, ien, node, button;\n\t\tvar clickHandler = function ( e ) {\n\t\t\te.preventDefault();\n\t\t\tif ( !$(e.currentTarget).hasClass('disabled') ) {\n\t\t\t\tapi.page( e.data.action ).draw( false );\n\t\t\t}\n\t\t};\n\n\t\tfor ( i=0, ien=buttons.length ; i<ien ; i++ ) {\n\t\t\tbutton = buttons[i];\n\n\t\t\tif ( $.isArray( button ) ) {\n\t\t\t\tattach( container, button );\n\t\t\t}\n\t\t\telse {\n\t\t\t\tbtnDisplay = '';\n\t\t\t\tbtnClass = '';\n\n\t\t\t\tswitch ( button ) {\n\t\t\t\t\tcase 'ellipsis':\n\t\t\t\t\t\tbtnDisplay = '&hellip;';\n\t\t\t\t\t\tbtnClass = 'disabled';\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'first':\n\t\t\t\t\t\tbtnDisplay = lang.sFirst;\n\t\t\t\t\t\tbtnClass = button + (page > 0 ?\n\t\t\t\t\t\t\t'' : ' disabled');\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'previous':\n\t\t\t\t\t\tbtnDisplay = lang.sPrevious;\n\t\t\t\t\t\tbtnClass = button + (page > 0 ?\n\t\t\t\t\t\t\t'' : ' disabled');\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'next':\n\t\t\t\t\t\tbtnDisplay = lang.sNext;\n\t\t\t\t\t\tbtnClass = button + (page < pages-1 ?\n\t\t\t\t\t\t\t'' : ' disabled');\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'last':\n\t\t\t\t\t\tbtnDisplay = lang.sLast;\n\t\t\t\t\t\tbtnClass = button + (page < pages-1 ?\n\t\t\t\t\t\t\t'' : ' disabled');\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tdefault:\n\t\t\t\t\t\tbtnDisplay = button + 1;\n\t\t\t\t\t\tbtnClass = page === button ?\n\t\t\t\t\t\t\t'active' : '';\n\t\t\t\t\t\tbreak;\n\t\t\t\t}\n\n\t\t\t\tif ( btnDisplay ) {\n\t\t\t\t\tnode = $('<li>', {\n\t\t\t\t\t\t\t'class': classes.sPageButton+' '+btnClass,\n\t\t\t\t\t\t\t'aria-controls': settings.sTableId,\n\t\t\t\t\t\t\t'tabindex': settings.iTabIndex,\n\t\t\t\t\t\t\t'id': idx === 0 && typeof button === 'string' ?\n\t\t\t\t\t\t\t\tsettings.sTableId +'_'+ button :\n\t\t\t\t\t\t\t\tnull\n\t\t\t\t\t\t} )\n\t\t\t\t\t\t.append( $('<a>', {\n\t\t\t\t\t\t\t\t'href': '#'\n\t\t\t\t\t\t\t} )\n\t\t\t\t\t\t\t.html( btnDisplay )\n\t\t\t\t\t\t)\n\t\t\t\t\t\t.appendTo( container );\n\n\t\t\t\t\tsettings.oApi._fnBindAction(\n\t\t\t\t\t\tnode, {action: button}, clickHandler\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t};\n\n\tattach(\n\t\t$(host).empty().html('<ul class=\"pagination\"/>').children('ul'),\n\t\tbuttons\n\t);\n};\n\n\n/*\n * TableTools Bootstrap compatibility\n * Required TableTools 2.1+\n */\nif ( DataTable.TableTools ) {\n\t// Set the classes that TableTools uses to something suitable for Bootstrap\n\t$.extend( true, DataTable.TableTools.classes, {\n\t\t\"container\": \"DTTT btn-group\",\n\t\t\"buttons\": {\n\t\t\t\"normal\": \"btn btn-default\",\n\t\t\t\"disabled\": \"disabled\"\n\t\t},\n\t\t\"collection\": {\n\t\t\t\"container\": \"DTTT_dropdown dropdown-menu\",\n\t\t\t\"buttons\": {\n\t\t\t\t\"normal\": \"\",\n\t\t\t\t\"disabled\": \"disabled\"\n\t\t\t}\n\t\t},\n\t\t\"print\": {\n\t\t\t\"info\": \"DTTT_print_info\"\n\t\t},\n\t\t\"select\": {\n\t\t\t\"row\": \"active\"\n\t\t}\n\t} );\n\n\t// Have the collection use a bootstrap compatible drop down\n\t$.extend( true, DataTable.TableTools.DEFAULTS.oTags, {\n\t\t\"collection\": {\n\t\t\t\"container\": \"ul\",\n\t\t\t\"button\": \"li\",\n\t\t\t\"liner\": \"a\"\n\t\t}\n\t} );\n}\n\n}; // /factory\n\n\n// Define as an AMD module if possible\nif ( typeof define === 'function' && define.amd ) {\n\tdefine( ['jquery', 'datatables'], factory );\n}\nelse if ( typeof exports === 'object' ) {\n    // Node/CommonJS\n    factory( require('jquery'), require('datatables') );\n}\nelse if ( jQuery ) {\n\t// Otherwise simply initialise as normal, stopping multiple evaluation\n\tfactory( jQuery, jQuery.fn.dataTable );\n}\n\n\n})(window, document);\n\n"
  },
  {
    "path": "app_backend/vendor/datatables-plugins/index.html",
    "content": "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01//EN\" \"http://www.w3.org/TR/html4/strict.dtd\">\n<html>\n\t<head>\n\t\t<meta http-equiv=\"content-type\" content=\"text/html; charset=utf-8\" />\n\t\t\n\t\t<title>DataTables Bootstrap 3 example</title>\n\n\t\t<link rel=\"stylesheet\" type=\"text/css\" href=\"//maxcdn.bootstrapcdn.com/bootstrap/3.3.0/css/bootstrap.min.css\">\n\t\t<link rel=\"stylesheet\" type=\"text/css\" href=\"dataTables.bootstrap.css\">\n\n\t\t<script type=\"text/javascript\" language=\"javascript\" src=\"//code.jquery.com/jquery-1.11.1.min.js\"></script>\n\t\t<script type=\"text/javascript\" language=\"javascript\" src=\"//cdn.datatables.net/1.10.3/js/jquery.dataTables.min.js\"></script>\n\t\t<script type=\"text/javascript\" language=\"javascript\" src=\"dataTables.bootstrap.js\"></script>\n\t\t<script type=\"text/javascript\" charset=\"utf-8\">\n\t\t\t$(document).ready(function() {\n\t\t\t\t$('#example').dataTable();\n\t\t\t} );\n\t\t</script>\n\t</head>\n\t<body>\n\t\t<div class=\"container\">\n\t\t\t\n<table cellpadding=\"0\" cellspacing=\"0\" border=\"0\" class=\"table table-striped table-bordered\" id=\"example\">\n\t<thead>\n\t\t<tr>\n\t\t\t<th>Rendering engine</th>\n\t\t\t<th>Browser</th>\n\t\t\t<th>Platform(s)</th>\n\t\t\t<th>Engine version</th>\n\t\t\t<th>CSS grade</th>\n\t\t</tr>\n\t</thead>\n\t<tbody>\n\t\t<tr class=\"odd gradeX\">\n\t\t\t<td>Trident</td>\n\t\t\t<td>Internet\n\t\t\t\t Explorer 4.0</td>\n\t\t\t<td>Win 95+</td>\n\t\t\t<td class=\"center\"> 4</td>\n\t\t\t<td class=\"center\">X</td>\n\t\t</tr>\n\t\t<tr class=\"even gradeC\">\n\t\t\t<td>Trident</td>\n\t\t\t<td>Internet\n\t\t\t\t Explorer 5.0</td>\n\t\t\t<td>Win 95+</td>\n\t\t\t<td class=\"center\">5</td>\n\t\t\t<td class=\"center\">C</td>\n\t\t</tr>\n\t\t<tr class=\"odd gradeA\">\n\t\t\t<td>Trident</td>\n\t\t\t<td>Internet\n\t\t\t\t Explorer 5.5</td>\n\t\t\t<td>Win 95+</td>\n\t\t\t<td class=\"center\">5.5</td>\n\t\t\t<td class=\"center\">A</td>\n\t\t</tr>\n\t\t<tr class=\"even gradeA\">\n\t\t\t<td>Trident</td>\n\t\t\t<td>Internet\n\t\t\t\t Explorer 6</td>\n\t\t\t<td>Win 98+</td>\n\t\t\t<td class=\"center\">6</td>\n\t\t\t<td class=\"center\">A</td>\n\t\t</tr>\n\t\t<tr class=\"odd gradeA\">\n\t\t\t<td>Trident</td>\n\t\t\t<td>Internet Explorer 7</td>\n\t\t\t<td>Win XP SP2+</td>\n\t\t\t<td class=\"center\">7</td>\n\t\t\t<td class=\"center\">A</td>\n\t\t</tr>\n\t\t<tr class=\"even gradeA\">\n\t\t\t<td>Trident</td>\n\t\t\t<td>AOL browser (AOL desktop)</td>\n\t\t\t<td>Win XP</td>\n\t\t\t<td class=\"center\">6</td>\n\t\t\t<td class=\"center\">A</td>\n\t\t</tr>\n\t\t<tr class=\"gradeA\">\n\t\t\t<td>Gecko</td>\n\t\t\t<td>Firefox 1.0</td>\n\t\t\t<td>Win 98+ / OSX.2+</td>\n\t\t\t<td class=\"center\">1.7</td>\n\t\t\t<td class=\"center\">A</td>\n\t\t</tr>\n\t\t<tr class=\"gradeA\">\n\t\t\t<td>Gecko</td>\n\t\t\t<td>Firefox 1.5</td>\n\t\t\t<td>Win 98+ / OSX.2+</td>\n\t\t\t<td class=\"center\">1.8</td>\n\t\t\t<td class=\"center\">A</td>\n\t\t</tr>\n\t\t<tr class=\"gradeA\">\n\t\t\t<td>Gecko</td>\n\t\t\t<td>Firefox 2.0</td>\n\t\t\t<td>Win 98+ / OSX.2+</td>\n\t\t\t<td class=\"center\">1.8</td>\n\t\t\t<td class=\"center\">A</td>\n\t\t</tr>\n\t\t<tr class=\"gradeA\">\n\t\t\t<td>Gecko</td>\n\t\t\t<td>Firefox 3.0</td>\n\t\t\t<td>Win 2k+ / OSX.3+</td>\n\t\t\t<td class=\"center\">1.9</td>\n\t\t\t<td class=\"center\">A</td>\n\t\t</tr>\n\t\t<tr class=\"gradeA\">\n\t\t\t<td>Gecko</td>\n\t\t\t<td>Camino 1.0</td>\n\t\t\t<td>OSX.2+</td>\n\t\t\t<td class=\"center\">1.8</td>\n\t\t\t<td class=\"center\">A</td>\n\t\t</tr>\n\t\t<tr class=\"gradeA\">\n\t\t\t<td>Gecko</td>\n\t\t\t<td>Camino 1.5</td>\n\t\t\t<td>OSX.3+</td>\n\t\t\t<td class=\"center\">1.8</td>\n\t\t\t<td class=\"center\">A</td>\n\t\t</tr>\n\t\t<tr class=\"gradeA\">\n\t\t\t<td>Gecko</td>\n\t\t\t<td>Netscape 7.2</td>\n\t\t\t<td>Win 95+ / Mac OS 8.6-9.2</td>\n\t\t\t<td class=\"center\">1.7</td>\n\t\t\t<td class=\"center\">A</td>\n\t\t</tr>\n\t\t<tr class=\"gradeA\">\n\t\t\t<td>Gecko</td>\n\t\t\t<td>Netscape Browser 8</td>\n\t\t\t<td>Win 98SE+</td>\n\t\t\t<td class=\"center\">1.7</td>\n\t\t\t<td class=\"center\">A</td>\n\t\t</tr>\n\t\t<tr class=\"gradeA\">\n\t\t\t<td>Gecko</td>\n\t\t\t<td>Netscape Navigator 9</td>\n\t\t\t<td>Win 98+ / OSX.2+</td>\n\t\t\t<td class=\"center\">1.8</td>\n\t\t\t<td class=\"center\">A</td>\n\t\t</tr>\n\t\t<tr class=\"gradeA\">\n\t\t\t<td>Gecko</td>\n\t\t\t<td>Mozilla 1.0</td>\n\t\t\t<td>Win 95+ / OSX.1+</td>\n\t\t\t<td class=\"center\">1</td>\n\t\t\t<td class=\"center\">A</td>\n\t\t</tr>\n\t\t<tr class=\"gradeA\">\n\t\t\t<td>Gecko</td>\n\t\t\t<td>Mozilla 1.1</td>\n\t\t\t<td>Win 95+ / OSX.1+</td>\n\t\t\t<td class=\"center\">1.1</td>\n\t\t\t<td class=\"center\">A</td>\n\t\t</tr>\n\t\t<tr class=\"gradeA\">\n\t\t\t<td>Gecko</td>\n\t\t\t<td>Mozilla 1.2</td>\n\t\t\t<td>Win 95+ / OSX.1+</td>\n\t\t\t<td class=\"center\">1.2</td>\n\t\t\t<td class=\"center\">A</td>\n\t\t</tr>\n\t\t<tr class=\"gradeA\">\n\t\t\t<td>Gecko</td>\n\t\t\t<td>Mozilla 1.3</td>\n\t\t\t<td>Win 95+ / OSX.1+</td>\n\t\t\t<td class=\"center\">1.3</td>\n\t\t\t<td class=\"center\">A</td>\n\t\t</tr>\n\t\t<tr class=\"gradeA\">\n\t\t\t<td>Gecko</td>\n\t\t\t<td>Mozilla 1.4</td>\n\t\t\t<td>Win 95+ / OSX.1+</td>\n\t\t\t<td class=\"center\">1.4</td>\n\t\t\t<td class=\"center\">A</td>\n\t\t</tr>\n\t\t<tr class=\"gradeA\">\n\t\t\t<td>Gecko</td>\n\t\t\t<td>Mozilla 1.5</td>\n\t\t\t<td>Win 95+ / OSX.1+</td>\n\t\t\t<td class=\"center\">1.5</td>\n\t\t\t<td class=\"center\">A</td>\n\t\t</tr>\n\t\t<tr class=\"gradeA\">\n\t\t\t<td>Gecko</td>\n\t\t\t<td>Mozilla 1.6</td>\n\t\t\t<td>Win 95+ / OSX.1+</td>\n\t\t\t<td class=\"center\">1.6</td>\n\t\t\t<td class=\"center\">A</td>\n\t\t</tr>\n\t\t<tr class=\"gradeA\">\n\t\t\t<td>Gecko</td>\n\t\t\t<td>Mozilla 1.7</td>\n\t\t\t<td>Win 98+ / OSX.1+</td>\n\t\t\t<td class=\"center\">1.7</td>\n\t\t\t<td class=\"center\">A</td>\n\t\t</tr>\n\t\t<tr class=\"gradeA\">\n\t\t\t<td>Gecko</td>\n\t\t\t<td>Mozilla 1.8</td>\n\t\t\t<td>Win 98+ / OSX.1+</td>\n\t\t\t<td class=\"center\">1.8</td>\n\t\t\t<td class=\"center\">A</td>\n\t\t</tr>\n\t\t<tr class=\"gradeA\">\n\t\t\t<td>Gecko</td>\n\t\t\t<td>Seamonkey 1.1</td>\n\t\t\t<td>Win 98+ / OSX.2+</td>\n\t\t\t<td class=\"center\">1.8</td>\n\t\t\t<td class=\"center\">A</td>\n\t\t</tr>\n\t\t<tr class=\"gradeA\">\n\t\t\t<td>Gecko</td>\n\t\t\t<td>Epiphany 2.20</td>\n\t\t\t<td>Gnome</td>\n\t\t\t<td class=\"center\">1.8</td>\n\t\t\t<td class=\"center\">A</td>\n\t\t</tr>\n\t\t<tr class=\"gradeA\">\n\t\t\t<td>Webkit</td>\n\t\t\t<td>Safari 1.2</td>\n\t\t\t<td>OSX.3</td>\n\t\t\t<td class=\"center\">125.5</td>\n\t\t\t<td class=\"center\">A</td>\n\t\t</tr>\n\t\t<tr class=\"gradeA\">\n\t\t\t<td>Webkit</td>\n\t\t\t<td>Safari 1.3</td>\n\t\t\t<td>OSX.3</td>\n\t\t\t<td class=\"center\">312.8</td>\n\t\t\t<td class=\"center\">A</td>\n\t\t</tr>\n\t\t<tr class=\"gradeA\">\n\t\t\t<td>Webkit</td>\n\t\t\t<td>Safari 2.0</td>\n\t\t\t<td>OSX.4+</td>\n\t\t\t<td class=\"center\">419.3</td>\n\t\t\t<td class=\"center\">A</td>\n\t\t</tr>\n\t\t<tr class=\"gradeA\">\n\t\t\t<td>Webkit</td>\n\t\t\t<td>Safari 3.0</td>\n\t\t\t<td>OSX.4+</td>\n\t\t\t<td class=\"center\">522.1</td>\n\t\t\t<td class=\"center\">A</td>\n\t\t</tr>\n\t\t<tr class=\"gradeA\">\n\t\t\t<td>Webkit</td>\n\t\t\t<td>OmniWeb 5.5</td>\n\t\t\t<td>OSX.4+</td>\n\t\t\t<td class=\"center\">420</td>\n\t\t\t<td class=\"center\">A</td>\n\t\t</tr>\n\t\t<tr class=\"gradeA\">\n\t\t\t<td>Webkit</td>\n\t\t\t<td>iPod Touch / iPhone</td>\n\t\t\t<td>iPod</td>\n\t\t\t<td class=\"center\">420.1</td>\n\t\t\t<td class=\"center\">A</td>\n\t\t</tr>\n\t\t<tr class=\"gradeA\">\n\t\t\t<td>Webkit</td>\n\t\t\t<td>S60</td>\n\t\t\t<td>S60</td>\n\t\t\t<td class=\"center\">413</td>\n\t\t\t<td class=\"center\">A</td>\n\t\t</tr>\n\t\t<tr class=\"gradeA\">\n\t\t\t<td>Presto</td>\n\t\t\t<td>Opera 7.0</td>\n\t\t\t<td>Win 95+ / OSX.1+</td>\n\t\t\t<td class=\"center\">-</td>\n\t\t\t<td class=\"center\">A</td>\n\t\t</tr>\n\t\t<tr class=\"gradeA\">\n\t\t\t<td>Presto</td>\n\t\t\t<td>Opera 7.5</td>\n\t\t\t<td>Win 95+ / OSX.2+</td>\n\t\t\t<td class=\"center\">-</td>\n\t\t\t<td class=\"center\">A</td>\n\t\t</tr>\n\t\t<tr class=\"gradeA\">\n\t\t\t<td>Presto</td>\n\t\t\t<td>Opera 8.0</td>\n\t\t\t<td>Win 95+ / OSX.2+</td>\n\t\t\t<td class=\"center\">-</td>\n\t\t\t<td class=\"center\">A</td>\n\t\t</tr>\n\t\t<tr class=\"gradeA\">\n\t\t\t<td>Presto</td>\n\t\t\t<td>Opera 8.5</td>\n\t\t\t<td>Win 95+ / OSX.2+</td>\n\t\t\t<td class=\"center\">-</td>\n\t\t\t<td class=\"center\">A</td>\n\t\t</tr>\n\t\t<tr class=\"gradeA\">\n\t\t\t<td>Presto</td>\n\t\t\t<td>Opera 9.0</td>\n\t\t\t<td>Win 95+ / OSX.3+</td>\n\t\t\t<td class=\"center\">-</td>\n\t\t\t<td class=\"center\">A</td>\n\t\t</tr>\n\t\t<tr class=\"gradeA\">\n\t\t\t<td>Presto</td>\n\t\t\t<td>Opera 9.2</td>\n\t\t\t<td>Win 88+ / OSX.3+</td>\n\t\t\t<td class=\"center\">-</td>\n\t\t\t<td class=\"center\">A</td>\n\t\t</tr>\n\t\t<tr class=\"gradeA\">\n\t\t\t<td>Presto</td>\n\t\t\t<td>Opera 9.5</td>\n\t\t\t<td>Win 88+ / OSX.3+</td>\n\t\t\t<td class=\"center\">-</td>\n\t\t\t<td class=\"center\">A</td>\n\t\t</tr>\n\t\t<tr class=\"gradeA\">\n\t\t\t<td>Presto</td>\n\t\t\t<td>Opera for Wii</td>\n\t\t\t<td>Wii</td>\n\t\t\t<td class=\"center\">-</td>\n\t\t\t<td class=\"center\">A</td>\n\t\t</tr>\n\t\t<tr class=\"gradeA\">\n\t\t\t<td>Presto</td>\n\t\t\t<td>Nokia N800</td>\n\t\t\t<td>N800</td>\n\t\t\t<td class=\"center\">-</td>\n\t\t\t<td class=\"center\">A</td>\n\t\t</tr>\n\t\t<tr class=\"gradeA\">\n\t\t\t<td>Presto</td>\n\t\t\t<td>Nintendo DS browser</td>\n\t\t\t<td>Nintendo DS</td>\n\t\t\t<td class=\"center\">8.5</td>\n\t\t\t<td class=\"center\">C/A<sup>1</sup></td>\n\t\t</tr>\n\t\t<tr class=\"gradeC\">\n\t\t\t<td>KHTML</td>\n\t\t\t<td>Konqureror 3.1</td>\n\t\t\t<td>KDE 3.1</td>\n\t\t\t<td class=\"center\">3.1</td>\n\t\t\t<td class=\"center\">C</td>\n\t\t</tr>\n\t\t<tr class=\"gradeA\">\n\t\t\t<td>KHTML</td>\n\t\t\t<td>Konqureror 3.3</td>\n\t\t\t<td>KDE 3.3</td>\n\t\t\t<td class=\"center\">3.3</td>\n\t\t\t<td class=\"center\">A</td>\n\t\t</tr>\n\t\t<tr class=\"gradeA\">\n\t\t\t<td>KHTML</td>\n\t\t\t<td>Konqureror 3.5</td>\n\t\t\t<td>KDE 3.5</td>\n\t\t\t<td class=\"center\">3.5</td>\n\t\t\t<td class=\"center\">A</td>\n\t\t</tr>\n\t\t<tr class=\"gradeX\">\n\t\t\t<td>Tasman</td>\n\t\t\t<td>Internet Explorer 4.5</td>\n\t\t\t<td>Mac OS 8-9</td>\n\t\t\t<td class=\"center\">-</td>\n\t\t\t<td class=\"center\">X</td>\n\t\t</tr>\n\t\t<tr class=\"gradeC\">\n\t\t\t<td>Tasman</td>\n\t\t\t<td>Internet Explorer 5.1</td>\n\t\t\t<td>Mac OS 7.6-9</td>\n\t\t\t<td class=\"center\">1</td>\n\t\t\t<td class=\"center\">C</td>\n\t\t</tr>\n\t\t<tr class=\"gradeC\">\n\t\t\t<td>Tasman</td>\n\t\t\t<td>Internet Explorer 5.2</td>\n\t\t\t<td>Mac OS 8-X</td>\n\t\t\t<td class=\"center\">1</td>\n\t\t\t<td class=\"center\">C</td>\n\t\t</tr>\n\t\t<tr class=\"gradeA\">\n\t\t\t<td>Misc</td>\n\t\t\t<td>NetFront 3.1</td>\n\t\t\t<td>Embedded devices</td>\n\t\t\t<td class=\"center\">-</td>\n\t\t\t<td class=\"center\">C</td>\n\t\t</tr>\n\t\t<tr class=\"gradeA\">\n\t\t\t<td>Misc</td>\n\t\t\t<td>NetFront 3.4</td>\n\t\t\t<td>Embedded devices</td>\n\t\t\t<td class=\"center\">-</td>\n\t\t\t<td class=\"center\">A</td>\n\t\t</tr>\n\t\t<tr class=\"gradeX\">\n\t\t\t<td>Misc</td>\n\t\t\t<td>Dillo 0.8</td>\n\t\t\t<td>Embedded devices</td>\n\t\t\t<td class=\"center\">-</td>\n\t\t\t<td class=\"center\">X</td>\n\t\t</tr>\n\t\t<tr class=\"gradeX\">\n\t\t\t<td>Misc</td>\n\t\t\t<td>Links</td>\n\t\t\t<td>Text only</td>\n\t\t\t<td class=\"center\">-</td>\n\t\t\t<td class=\"center\">X</td>\n\t\t</tr>\n\t\t<tr class=\"gradeX\">\n\t\t\t<td>Misc</td>\n\t\t\t<td>Lynx</td>\n\t\t\t<td>Text only</td>\n\t\t\t<td class=\"center\">-</td>\n\t\t\t<td class=\"center\">X</td>\n\t\t</tr>\n\t\t<tr class=\"gradeC\">\n\t\t\t<td>Misc</td>\n\t\t\t<td>IE Mobile</td>\n\t\t\t<td>Windows Mobile 6</td>\n\t\t\t<td class=\"center\">-</td>\n\t\t\t<td class=\"center\">C</td>\n\t\t</tr>\n\t\t<tr class=\"gradeC\">\n\t\t\t<td>Misc</td>\n\t\t\t<td>PSP browser</td>\n\t\t\t<td>PSP</td>\n\t\t\t<td class=\"center\">-</td>\n\t\t\t<td class=\"center\">C</td>\n\t\t</tr>\n\t\t<tr class=\"gradeU\">\n\t\t\t<td>Other browsers</td>\n\t\t\t<td>All others</td>\n\t\t\t<td>-</td>\n\t\t\t<td class=\"center\">-</td>\n\t\t\t<td class=\"center\">U</td>\n\t\t</tr>\n\t</tbody>\n</table>\n\t\t\t\n\t\t</div>\n\t</body>\n</html>"
  },
  {
    "path": "app_backend/vendor/datatables-responsive/dataTables.responsive.css",
    "content": "table.dataTable.dtr-inline.collapsed > tbody > tr > td:first-child,\ntable.dataTable.dtr-inline.collapsed > tbody > tr > th:first-child {\n  position: relative;\n  padding-left: 30px;\n  cursor: pointer;\n}\ntable.dataTable.dtr-inline.collapsed > tbody > tr > td:first-child:before,\ntable.dataTable.dtr-inline.collapsed > tbody > tr > th:first-child:before {\n  top: 8px;\n  left: 4px;\n  height: 16px;\n  width: 16px;\n  display: block;\n  position: absolute;\n  color: white;\n  border: 2px solid white;\n  border-radius: 16px;\n  text-align: center;\n  line-height: 14px;\n  box-shadow: 0 0 3px #444;\n  box-sizing: content-box;\n  content: '+';\n  background-color: #31b131;\n}\ntable.dataTable.dtr-inline.collapsed > tbody > tr > td:first-child.dataTables_empty:before,\ntable.dataTable.dtr-inline.collapsed > tbody > tr > th:first-child.dataTables_empty:before {\n  display: none;\n}\ntable.dataTable.dtr-inline.collapsed > tbody > tr.parent > td:first-child:before,\ntable.dataTable.dtr-inline.collapsed > tbody > tr.parent > th:first-child:before {\n  content: '-';\n  background-color: #d33333;\n}\ntable.dataTable.dtr-inline.collapsed > tbody > tr.child td:before {\n  display: none;\n}\ntable.dataTable.dtr-inline.collapsed.compact > tbody > tr > td:first-child,\ntable.dataTable.dtr-inline.collapsed.compact > tbody > tr > th:first-child {\n  padding-left: 27px;\n}\ntable.dataTable.dtr-inline.collapsed.compact > tbody > tr > td:first-child:before,\ntable.dataTable.dtr-inline.collapsed.compact > tbody > tr > th:first-child:before {\n  top: 5px;\n  left: 4px;\n  height: 14px;\n  width: 14px;\n  border-radius: 14px;\n  line-height: 12px;\n}\ntable.dataTable.dtr-column > tbody > tr > td.control,\ntable.dataTable.dtr-column > tbody > tr > th.control {\n  position: relative;\n  cursor: pointer;\n}\ntable.dataTable.dtr-column > tbody > tr > td.control:before,\ntable.dataTable.dtr-column > tbody > tr > th.control:before {\n  top: 50%;\n  left: 50%;\n  height: 16px;\n  width: 16px;\n  margin-top: -10px;\n  margin-left: -10px;\n  display: block;\n  position: absolute;\n  color: white;\n  border: 2px solid white;\n  border-radius: 16px;\n  text-align: center;\n  line-height: 14px;\n  box-shadow: 0 0 3px #444;\n  box-sizing: content-box;\n  content: '+';\n  background-color: #31b131;\n}\ntable.dataTable.dtr-column > tbody > tr.parent td.control:before,\ntable.dataTable.dtr-column > tbody > tr.parent th.control:before {\n  content: '-';\n  background-color: #d33333;\n}\ntable.dataTable > tbody > tr.child {\n  padding: 0.5em 1em;\n}\ntable.dataTable > tbody > tr.child:hover {\n  background: transparent !important;\n}\ntable.dataTable > tbody > tr.child ul {\n  display: inline-block;\n  list-style-type: none;\n  margin: 0;\n  padding: 0;\n}\ntable.dataTable > tbody > tr.child ul li {\n  border-bottom: 1px solid #efefef;\n  padding: 0.5em 0;\n}\ntable.dataTable > tbody > tr.child ul li:first-child {\n  padding-top: 0;\n}\ntable.dataTable > tbody > tr.child ul li:last-child {\n  border-bottom: none;\n}\ntable.dataTable > tbody > tr.child span.dtr-title {\n  display: inline-block;\n  min-width: 75px;\n  font-weight: bold;\n}\n"
  },
  {
    "path": "app_backend/vendor/datatables-responsive/dataTables.responsive.js",
    "content": "/*! Responsive 1.0.6\n * 2014-2015 SpryMedia Ltd - datatables.net/license\n */\n\n/**\n * @summary     Responsive\n * @description Responsive tables plug-in for DataTables\n * @version     1.0.6\n * @file        dataTables.responsive.js\n * @author      SpryMedia Ltd (www.sprymedia.co.uk)\n * @contact     www.sprymedia.co.uk/contact\n * @copyright   Copyright 2014-2015 SpryMedia Ltd.\n *\n * This source file is free software, available under the following license:\n *   MIT license - http://datatables.net/license/mit\n *\n * This source file is distributed in the hope that it will be useful, but\n * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY\n * or FITNESS FOR A PARTICULAR PURPOSE. See the license files for details.\n *\n * For details please refer to: http://www.datatables.net\n */\n\n(function(window, document, undefined) {\n\n\nvar factory = function( $, DataTable ) {\n\"use strict\";\n\n/**\n * Responsive is a plug-in for the DataTables library that makes use of\n * DataTables' ability to change the visibility of columns, changing the\n * visibility of columns so the displayed columns fit into the table container.\n * The end result is that complex tables will be dynamically adjusted to fit\n * into the viewport, be it on a desktop, tablet or mobile browser.\n *\n * Responsive for DataTables has two modes of operation, which can used\n * individually or combined:\n *\n * * Class name based control - columns assigned class names that match the\n *   breakpoint logic can be shown / hidden as required for each breakpoint.\n * * Automatic control - columns are automatically hidden when there is no\n *   room left to display them. Columns removed from the right.\n *\n * In additional to column visibility control, Responsive also has built into\n * options to use DataTables' child row display to show / hide the information\n * from the table that has been hidden. There are also two modes of operation\n * for this child row display:\n *\n * * Inline - when the control element that the user can use to show / hide\n *   child rows is displayed inside the first column of the table.\n * * Column - where a whole column is dedicated to be the show / hide control.\n *\n * Initialisation of Responsive is performed by:\n *\n * * Adding the class `responsive` or `dt-responsive` to the table. In this case\n *   Responsive will automatically be initialised with the default configuration\n *   options when the DataTable is created.\n * * Using the `responsive` option in the DataTables configuration options. This\n *   can also be used to specify the configuration options, or simply set to\n *   `true` to use the defaults.\n *\n *  @class\n *  @param {object} settings DataTables settings object for the host table\n *  @param {object} [opts] Configuration options\n *  @requires jQuery 1.7+\n *  @requires DataTables 1.10.1+\n *\n *  @example\n *      $('#example').DataTable( {\n *        responsive: true\n *      } );\n *    } );\n */\nvar Responsive = function ( settings, opts ) {\n\t// Sanity check that we are using DataTables 1.10 or newer\n\tif ( ! DataTable.versionCheck || ! DataTable.versionCheck( '1.10.1' ) ) {\n\t\tthrow 'DataTables Responsive requires DataTables 1.10.1 or newer';\n\t}\n\n\tthis.s = {\n\t\tdt: new DataTable.Api( settings ),\n\t\tcolumns: []\n\t};\n\n\t// Check if responsive has already been initialised on this table\n\tif ( this.s.dt.settings()[0].responsive ) {\n\t\treturn;\n\t}\n\n\t// details is an object, but for simplicity the user can give it as a string\n\tif ( opts && typeof opts.details === 'string' ) {\n\t\topts.details = { type: opts.details };\n\t}\n\n\tthis.c = $.extend( true, {}, Responsive.defaults, DataTable.defaults.responsive, opts );\n\tsettings.responsive = this;\n\tthis._constructor();\n};\n\nResponsive.prototype = {\n\t/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\n\t * Constructor\n\t */\n\n\t/**\n\t * Initialise the Responsive instance\n\t *\n\t * @private\n\t */\n\t_constructor: function ()\n\t{\n\t\tvar that = this;\n\t\tvar dt = this.s.dt;\n\n\t\tdt.settings()[0]._responsive = this;\n\n\t\t// Use DataTables' private throttle function to avoid processor thrashing\n\t\t$(window).on( 'resize.dtr orientationchange.dtr', dt.settings()[0].oApi._fnThrottle( function () {\n\t\t\tthat._resize();\n\t\t} ) );\n\n\t\t// Destroy event handler\n\t\tdt.on( 'destroy.dtr', function () {\n\t\t\t$(window).off( 'resize.dtr orientationchange.dtr draw.dtr' );\n\t\t} );\n\n\t\t// Reorder the breakpoints array here in case they have been added out\n\t\t// of order\n\t\tthis.c.breakpoints.sort( function (a, b) {\n\t\t\treturn a.width < b.width ? 1 :\n\t\t\t\ta.width > b.width ? -1 : 0;\n\t\t} );\n\n\t\t// Determine which columns are already hidden, and should therefore\n\t\t// remain hidden. todo - should this be done? See thread 22677\n\t\t//\n\t\t// this.s.alwaysHidden = dt.columns(':hidden').indexes();\n\n\t\tthis._classLogic();\n\t\tthis._resizeAuto();\n\n\t\t// Details handler\n\t\tvar details = this.c.details;\n\t\tif ( details.type ) {\n\t\t\tthat._detailsInit();\n\t\t\tthis._detailsVis();\n\n\t\t\tdt.on( 'column-visibility.dtr', function () {\n\t\t\t\tthat._detailsVis();\n\t\t\t} );\n\n\t\t\t// Redraw the details box on each draw. This is used until\n\t\t\t// DataTables implements a native `updated` event for rows\n\t\t\tdt.on( 'draw.dtr', function () {\n\t\t\t\tdt.rows( {page: 'current'} ).iterator( 'row', function ( settings, idx ) {\n\t\t\t\t\tvar row = dt.row( idx );\n\n\t\t\t\t\tif ( row.child.isShown() ) {\n\t\t\t\t\t\tvar info = that.c.details.renderer( dt, idx );\n\t\t\t\t\t\trow.child( info, 'child' ).show();\n\t\t\t\t\t}\n\t\t\t\t} );\n\t\t\t} );\n\n\t\t\t$(dt.table().node()).addClass( 'dtr-'+details.type );\n\t\t}\n\n\t\t// First pass - draw the table for the current viewport size\n\t\tthis._resize();\n\t},\n\n\n\t/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\n\t * Private methods\n\t */\n\n\t/**\n\t * Calculate the visibility for the columns in a table for a given\n\t * breakpoint. The result is pre-determined based on the class logic if\n\t * class names are used to control all columns, but the width of the table\n\t * is also used if there are columns which are to be automatically shown\n\t * and hidden.\n\t *\n\t * @param  {string} breakpoint Breakpoint name to use for the calculation\n\t * @return {array} Array of boolean values initiating the visibility of each\n\t *   column.\n\t *  @private\n\t */\n\t_columnsVisiblity: function ( breakpoint )\n\t{\n\t\tvar dt = this.s.dt;\n\t\tvar columns = this.s.columns;\n\t\tvar i, ien;\n\n\t\t// Class logic - determine which columns are in this breakpoint based\n\t\t// on the classes. If no class control (i.e. `auto`) then `-` is used\n\t\t// to indicate this to the rest of the function\n\t\tvar display = $.map( columns, function ( col ) {\n\t\t\treturn col.auto && col.minWidth === null ?\n\t\t\t\tfalse :\n\t\t\t\tcol.auto === true ?\n\t\t\t\t\t'-' :\n\t\t\t\t\t$.inArray( breakpoint, col.includeIn ) !== -1;\n\t\t} );\n\n\t\t// Auto column control - first pass: how much width is taken by the\n\t\t// ones that must be included from the non-auto columns\n\t\tvar requiredWidth = 0;\n\t\tfor ( i=0, ien=display.length ; i<ien ; i++ ) {\n\t\t\tif ( display[i] === true ) {\n\t\t\t\trequiredWidth += columns[i].minWidth;\n\t\t\t}\n\t\t}\n\n\t\t// Second pass, use up any remaining width for other columns. For\n\t\t// scrolling tables we need to subtract the width of the scrollbar. It\n\t\t// may not be requires which makes this sub-optimal, but it would\n\t\t// require another full redraw to make complete use of those extra few\n\t\t// pixels\n\t\tvar scrolling = dt.settings()[0].oScroll;\n\t\tvar bar = scrolling.sY || scrolling.sX ? scrolling.iBarWidth : 0;\n\t\tvar widthAvailable = dt.table().container().offsetWidth - bar;\n\t\tvar usedWidth = widthAvailable - requiredWidth;\n\n\t\t// Control column needs to always be included. This makes it sub-\n\t\t// optimal in terms of using the available with, but to stop layout\n\t\t// thrashing or overflow. Also we need to account for the control column\n\t\t// width first so we know how much width is available for the other\n\t\t// columns, since the control column might not be the first one shown\n\t\tfor ( i=0, ien=display.length ; i<ien ; i++ ) {\n\t\t\tif ( columns[i].control ) {\n\t\t\t\tusedWidth -= columns[i].minWidth;\n\t\t\t}\n\t\t}\n\n\t\t// Allow columns to be shown (counting from the left) until we run out\n\t\t// of room\n\t\tvar empty = false;\n\t\tfor ( i=0, ien=display.length ; i<ien ; i++ ) {\n\t\t\tif ( display[i] === '-' && ! columns[i].control ) {\n\t\t\t\t// Once we've found a column that won't fit we don't let any\n\t\t\t\t// others display either, or columns might disappear in the\n\t\t\t\t// middle of the table\n\t\t\t\tif ( empty || usedWidth - columns[i].minWidth < 0 ) {\n\t\t\t\t\tempty = true;\n\t\t\t\t\tdisplay[i] = false;\n\t\t\t\t}\n\t\t\t\telse {\n\t\t\t\t\tdisplay[i] = true;\n\t\t\t\t}\n\n\t\t\t\tusedWidth -= columns[i].minWidth;\n\t\t\t}\n\t\t}\n\n\t\t// Determine if the 'control' column should be shown (if there is one).\n\t\t// This is the case when there is a hidden column (that is not the\n\t\t// control column). The two loops look inefficient here, but they are\n\t\t// trivial and will fly through. We need to know the outcome from the\n\t\t// first , before the action in the second can be taken\n\t\tvar showControl = false;\n\n\t\tfor ( i=0, ien=columns.length ; i<ien ; i++ ) {\n\t\t\tif ( ! columns[i].control && ! columns[i].never && ! display[i] ) {\n\t\t\t\tshowControl = true;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\tfor ( i=0, ien=columns.length ; i<ien ; i++ ) {\n\t\t\tif ( columns[i].control ) {\n\t\t\t\tdisplay[i] = showControl;\n\t\t\t}\n\t\t}\n\n\t\t// Finally we need to make sure that there is at least one column that\n\t\t// is visible\n\t\tif ( $.inArray( true, display ) === -1 ) {\n\t\t\tdisplay[0] = true;\n\t\t}\n\n\t\treturn display;\n\t},\n\n\n\t/**\n\t * Create the internal `columns` array with information about the columns\n\t * for the table. This includes determining which breakpoints the column\n\t * will appear in, based upon class names in the column, which makes up the\n\t * vast majority of this method.\n\t *\n\t * @private\n\t */\n\t_classLogic: function ()\n\t{\n\t\tvar that = this;\n\t\tvar calc = {};\n\t\tvar breakpoints = this.c.breakpoints;\n\t\tvar columns = this.s.dt.columns().eq(0).map( function (i) {\n\t\t\tvar className = this.column(i).header().className;\n\n\t\t\treturn {\n\t\t\t\tclassName: className,\n\t\t\t\tincludeIn: [],\n\t\t\t\tauto:      false,\n\t\t\t\tcontrol:   false,\n\t\t\t\tnever:     className.match(/\\bnever\\b/) ? true : false\n\t\t\t};\n\t\t} );\n\n\t\t// Simply add a breakpoint to `includeIn` array, ensuring that there are\n\t\t// no duplicates\n\t\tvar add = function ( colIdx, name ) {\n\t\t\tvar includeIn = columns[ colIdx ].includeIn;\n\n\t\t\tif ( $.inArray( name, includeIn ) === -1 ) {\n\t\t\t\tincludeIn.push( name );\n\t\t\t}\n\t\t};\n\n\t\tvar column = function ( colIdx, name, operator, matched ) {\n\t\t\tvar size, i, ien;\n\n\t\t\tif ( ! operator ) {\n\t\t\t\tcolumns[ colIdx ].includeIn.push( name );\n\t\t\t}\n\t\t\telse if ( operator === 'max-' ) {\n\t\t\t\t// Add this breakpoint and all smaller\n\t\t\t\tsize = that._find( name ).width;\n\n\t\t\t\tfor ( i=0, ien=breakpoints.length ; i<ien ; i++ ) {\n\t\t\t\t\tif ( breakpoints[i].width <= size ) {\n\t\t\t\t\t\tadd( colIdx, breakpoints[i].name );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\telse if ( operator === 'min-' ) {\n\t\t\t\t// Add this breakpoint and all larger\n\t\t\t\tsize = that._find( name ).width;\n\n\t\t\t\tfor ( i=0, ien=breakpoints.length ; i<ien ; i++ ) {\n\t\t\t\t\tif ( breakpoints[i].width >= size ) {\n\t\t\t\t\t\tadd( colIdx, breakpoints[i].name );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\telse if ( operator === 'not-' ) {\n\t\t\t\t// Add all but this breakpoint (xxx need extra information)\n\n\t\t\t\tfor ( i=0, ien=breakpoints.length ; i<ien ; i++ ) {\n\t\t\t\t\tif ( breakpoints[i].name.indexOf( matched ) === -1 ) {\n\t\t\t\t\t\tadd( colIdx, breakpoints[i].name );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\n\t\t// Loop over each column and determine if it has a responsive control\n\t\t// class\n\t\tcolumns.each( function ( col, i ) {\n\t\t\tvar classNames = col.className.split(' ');\n\t\t\tvar hasClass = false;\n\n\t\t\t// Split the class name up so multiple rules can be applied if needed\n\t\t\tfor ( var k=0, ken=classNames.length ; k<ken ; k++ ) {\n\t\t\t\tvar className = $.trim( classNames[k] );\n\n\t\t\t\tif ( className === 'all' ) {\n\t\t\t\t\t// Include in all\n\t\t\t\t\thasClass = true;\n\t\t\t\t\tcol.includeIn = $.map( breakpoints, function (a) {\n\t\t\t\t\t\treturn a.name;\n\t\t\t\t\t} );\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\telse if ( className === 'none' || className === 'never' ) {\n\t\t\t\t\t// Include in none (default) and no auto\n\t\t\t\t\thasClass = true;\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\telse if ( className === 'control' ) {\n\t\t\t\t\t// Special column that is only visible, when one of the other\n\t\t\t\t\t// columns is hidden. This is used for the details control\n\t\t\t\t\thasClass = true;\n\t\t\t\t\tcol.control = true;\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\t$.each( breakpoints, function ( j, breakpoint ) {\n\t\t\t\t\t// Does this column have a class that matches this breakpoint?\n\t\t\t\t\tvar brokenPoint = breakpoint.name.split('-');\n\t\t\t\t\tvar re = new RegExp( '(min\\\\-|max\\\\-|not\\\\-)?('+brokenPoint[0]+')(\\\\-[_a-zA-Z0-9])?' );\n\t\t\t\t\tvar match = className.match( re );\n\n\t\t\t\t\tif ( match ) {\n\t\t\t\t\t\thasClass = true;\n\n\t\t\t\t\t\tif ( match[2] === brokenPoint[0] && match[3] === '-'+brokenPoint[1] ) {\n\t\t\t\t\t\t\t// Class name matches breakpoint name fully\n\t\t\t\t\t\t\tcolumn( i, breakpoint.name, match[1], match[2]+match[3] );\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse if ( match[2] === brokenPoint[0] && ! match[3] ) {\n\t\t\t\t\t\t\t// Class name matched primary breakpoint name with no qualifier\n\t\t\t\t\t\t\tcolumn( i, breakpoint.name, match[1], match[2] );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t} );\n\t\t\t}\n\n\t\t\t// If there was no control class, then automatic sizing is used\n\t\t\tif ( ! hasClass ) {\n\t\t\t\tcol.auto = true;\n\t\t\t}\n\t\t} );\n\n\t\tthis.s.columns = columns;\n\t},\n\n\n\t/**\n\t * Initialisation for the details handler\n\t *\n\t * @private\n\t */\n\t_detailsInit: function ()\n\t{\n\t\tvar that    = this;\n\t\tvar dt      = this.s.dt;\n\t\tvar details = this.c.details;\n\n\t\t// The inline type always uses the first child as the target\n\t\tif ( details.type === 'inline' ) {\n\t\t\tdetails.target = 'td:first-child';\n\t\t}\n\n\t\t// type.target can be a string jQuery selector or a column index\n\t\tvar target   = details.target;\n\t\tvar selector = typeof target === 'string' ? target : 'td';\n\n\t\t// Click handler to show / hide the details rows when they are available\n\t\t$( dt.table().body() ).on( 'click', selector, function (e) {\n\t\t\t// If the table is not collapsed (i.e. there is no hidden columns)\n\t\t\t// then take no action\n\t\t\tif ( ! $(dt.table().node()).hasClass('collapsed' ) ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// Check that the row is actually a DataTable's controlled node\n\t\t\tif ( ! dt.row( $(this).closest('tr') ).length ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// For column index, we determine if we should act or not in the\n\t\t\t// handler - otherwise it is already okay\n\t\t\tif ( typeof target === 'number' ) {\n\t\t\t\tvar targetIdx = target < 0 ?\n\t\t\t\t\tdt.columns().eq(0).length + target :\n\t\t\t\t\ttarget;\n\n\t\t\t\tif ( dt.cell( this ).index().column !== targetIdx ) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// $().closest() includes itself in its check\n\t\t\tvar row = dt.row( $(this).closest('tr') );\n\n\t\t\tif ( row.child.isShown() ) {\n\t\t\t\trow.child( false );\n\t\t\t\t$( row.node() ).removeClass( 'parent' );\n\t\t\t}\n\t\t\telse {\n\t\t\t\tvar info = that.c.details.renderer( dt, row[0] );\n\t\t\t\trow.child( info, 'child' ).show();\n\t\t\t\t$( row.node() ).addClass( 'parent' );\n\t\t\t}\n\t\t} );\n\t},\n\n\n\t/**\n\t * Update the child rows in the table whenever the column visibility changes\n\t *\n\t * @private\n\t */\n\t_detailsVis: function ()\n\t{\n\t\tvar that = this;\n\t\tvar dt = this.s.dt;\n\n\t\t// Find how many columns are hidden\n\t\tvar hiddenColumns = dt.columns().indexes().filter( function ( idx ) {\n\t\t\tvar col = dt.column( idx );\n\n\t\t\tif ( col.visible() ) {\n\t\t\t\treturn null;\n\t\t\t}\n\n\t\t\t// Only counts as hidden if it doesn't have the `never` class\n\t\t\treturn $( col.header() ).hasClass( 'never' ) ? null : idx;\n\t\t} );\n\t\tvar haveHidden = true;\n\n\t\tif ( hiddenColumns.length === 0 || ( hiddenColumns.length === 1 && this.s.columns[ hiddenColumns[0] ].control ) ) {\n\t\t\thaveHidden = false;\n\t\t}\n\n\t\tif ( haveHidden ) {\n\t\t\t// Show all existing child rows\n\t\t\tdt.rows( { page: 'current' } ).eq(0).each( function (idx) {\n\t\t\t\tvar row = dt.row( idx );\n\n\t\t\t\tif ( row.child() ) {\n\t\t\t\t\tvar info = that.c.details.renderer( dt, row[0] );\n\n\t\t\t\t\t// The renderer can return false to have no child row\n\t\t\t\t\tif ( info === false ) {\n\t\t\t\t\t\trow.child.hide();\n\t\t\t\t\t}\n\t\t\t\t\telse {\n\t\t\t\t\t\trow.child( info, 'child' ).show();\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} );\n\t\t}\n\t\telse {\n\t\t\t// Hide all existing child rows\n\t\t\tdt.rows( { page: 'current' } ).eq(0).each( function (idx) {\n\t\t\t\tdt.row( idx ).child.hide();\n\t\t\t} );\n\t\t}\n\t},\n\n\n\t/**\n\t * Find a breakpoint object from a name\n\t * @param  {string} name Breakpoint name to find\n\t * @return {object}      Breakpoint description object\n\t */\n\t_find: function ( name )\n\t{\n\t\tvar breakpoints = this.c.breakpoints;\n\n\t\tfor ( var i=0, ien=breakpoints.length ; i<ien ; i++ ) {\n\t\t\tif ( breakpoints[i].name === name ) {\n\t\t\t\treturn breakpoints[i];\n\t\t\t}\n\t\t}\n\t},\n\n\n\t/**\n\t * Alter the table display for a resized viewport. This involves first\n\t * determining what breakpoint the window currently is in, getting the\n\t * column visibilities to apply and then setting them.\n\t *\n\t * @private\n\t */\n\t_resize: function ()\n\t{\n\t\tvar dt = this.s.dt;\n\t\tvar width = $(window).width();\n\t\tvar breakpoints = this.c.breakpoints;\n\t\tvar breakpoint = breakpoints[0].name;\n\t\tvar columns = this.s.columns;\n\t\tvar i, ien;\n\n\t\t// Determine what breakpoint we are currently at\n\t\tfor ( i=breakpoints.length-1 ; i>=0 ; i-- ) {\n\t\t\tif ( width <= breakpoints[i].width ) {\n\t\t\t\tbreakpoint = breakpoints[i].name;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t\t\n\t\t// Show the columns for that break point\n\t\tvar columnsVis = this._columnsVisiblity( breakpoint );\n\n\t\t// Set the class before the column visibility is changed so event\n\t\t// listeners know what the state is. Need to determine if there are\n\t\t// any columns that are not visible but can be shown\n\t\tvar collapsedClass = false;\n\t\tfor ( i=0, ien=columns.length ; i<ien ; i++ ) {\n\t\t\tif ( columnsVis[i] === false && ! columns[i].never ) {\n\t\t\t\tcollapsedClass = true;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\t$( dt.table().node() ).toggleClass('collapsed', collapsedClass );\n\n\t\tdt.columns().eq(0).each( function ( colIdx, i ) {\n\t\t\tdt.column( colIdx ).visible( columnsVis[i] );\n\t\t} );\n\t},\n\n\n\t/**\n\t * Determine the width of each column in the table so the auto column hiding\n\t * has that information to work with. This method is never going to be 100%\n\t * perfect since column widths can change slightly per page, but without\n\t * seriously compromising performance this is quite effective.\n\t *\n\t * @private\n\t */\n\t_resizeAuto: function ()\n\t{\n\t\tvar dt = this.s.dt;\n\t\tvar columns = this.s.columns;\n\n\t\t// Are we allowed to do auto sizing?\n\t\tif ( ! this.c.auto ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Are there any columns that actually need auto-sizing, or do they all\n\t\t// have classes defined\n\t\tif ( $.inArray( true, $.map( columns, function (c) { return c.auto; } ) ) === -1 ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Clone the table with the current data in it\n\t\tvar tableWidth   = dt.table().node().offsetWidth;\n\t\tvar columnWidths = dt.columns;\n\t\tvar clonedTable  = dt.table().node().cloneNode( false );\n\t\tvar clonedHeader = $( dt.table().header().cloneNode( false ) ).appendTo( clonedTable );\n\t\tvar clonedBody   = $( dt.table().body().cloneNode( false ) ).appendTo( clonedTable );\n\n\t\t$( dt.table().footer() ).clone( false ).appendTo( clonedTable );\n\n\t\t// This is a bit slow, but we need to get a clone of each row that\n\t\t// includes all columns. As such, try to do this as little as possible.\n\t\tdt.rows( { page: 'current' } ).indexes().flatten().each( function ( idx ) {\n\t\t\tvar clone = dt.row( idx ).node().cloneNode( true );\n\t\t\t\n\t\t\tif ( dt.columns( ':hidden' ).flatten().length ) {\n\t\t\t\t$(clone).append( dt.cells( idx, ':hidden' ).nodes().to$().clone() );\n\t\t\t}\n\n\t\t\t$(clone).appendTo( clonedBody );\n\t\t} );\n\n\t\tvar cells = dt.columns().header().to$().clone( false );\n\t\t$('<tr/>')\n\t\t\t.append( cells )\n\t\t\t.appendTo( clonedHeader );\n\n\t\t// In the inline case extra padding is applied to the first column to\n\t\t// give space for the show / hide icon. We need to use this in the\n\t\t// calculation\n\t\tif ( this.c.details.type === 'inline' ) {\n\t\t\t$(clonedTable).addClass( 'dtr-inline collapsed' );\n\t\t}\n\n\t\tvar inserted = $('<div/>')\n\t\t\t.css( {\n\t\t\t\twidth: 1,\n\t\t\t\theight: 1,\n\t\t\t\toverflow: 'hidden'\n\t\t\t} )\n\t\t\t.append( clonedTable );\n\n\t\t// Remove columns which are not to be included\n\t\tinserted.find('th.never, td.never').remove();\n\n\t\tinserted.insertBefore( dt.table().node() );\n\n\t\t// The cloned header now contains the smallest that each column can be\n\t\tdt.columns().eq(0).each( function ( idx ) {\n\t\t\tcolumns[idx].minWidth = cells[ idx ].offsetWidth || 0;\n\t\t} );\n\n\t\tinserted.remove();\n\t}\n};\n\n\n/**\n * List of default breakpoints. Each item in the array is an object with two\n * properties:\n *\n * * `name` - the breakpoint name.\n * * `width` - the breakpoint width\n *\n * @name Responsive.breakpoints\n * @static\n */\nResponsive.breakpoints = [\n\t{ name: 'desktop',  width: Infinity },\n\t{ name: 'tablet-l', width: 1024 },\n\t{ name: 'tablet-p', width: 768 },\n\t{ name: 'mobile-l', width: 480 },\n\t{ name: 'mobile-p', width: 320 }\n];\n\n\n/**\n * Responsive default settings for initialisation\n *\n * @namespace\n * @name Responsive.defaults\n * @static\n */\nResponsive.defaults = {\n\t/**\n\t * List of breakpoints for the instance. Note that this means that each\n\t * instance can have its own breakpoints. Additionally, the breakpoints\n\t * cannot be changed once an instance has been creased.\n\t *\n\t * @type {Array}\n\t * @default Takes the value of `Responsive.breakpoints`\n\t */\n\tbreakpoints: Responsive.breakpoints,\n\n\t/**\n\t * Enable / disable auto hiding calculations. It can help to increase\n\t * performance slightly if you disable this option, but all columns would\n\t * need to have breakpoint classes assigned to them\n\t *\n\t * @type {Boolean}\n\t * @default  `true`\n\t */\n\tauto: true,\n\n\t/**\n\t * Details control. If given as a string value, the `type` property of the\n\t * default object is set to that value, and the defaults used for the rest\n\t * of the object - this is for ease of implementation.\n\t *\n\t * The object consists of the following properties:\n\t *\n\t * * `renderer` - function that is called for display of the child row data.\n\t *   The default function will show the data from the hidden columns\n\t * * `target` - Used as the selector for what objects to attach the child\n\t *   open / close to\n\t * * `type` - `false` to disable the details display, `inline` or `column`\n\t *   for the two control types\n\t *\n\t * @type {Object|string}\n\t */\n\tdetails: {\n\t\trenderer: function ( api, rowIdx ) {\n\t\t\tvar data = api.cells( rowIdx, ':hidden' ).eq(0).map( function ( cell ) {\n\t\t\t\tvar header = $( api.column( cell.column ).header() );\n\t\t\t\tvar idx = api.cell( cell ).index();\n\n\t\t\t\tif ( header.hasClass( 'control' ) || header.hasClass( 'never' ) ) {\n\t\t\t\t\treturn '';\n\t\t\t\t}\n\n\t\t\t\t// Use a non-public DT API method to render the data for display\n\t\t\t\t// This needs to be updated when DT adds a suitable method for\n\t\t\t\t// this type of data retrieval\n\t\t\t\tvar dtPrivate = api.settings()[0];\n\t\t\t\tvar cellData = dtPrivate.oApi._fnGetCellData(\n\t\t\t\t\tdtPrivate, idx.row, idx.column, 'display'\n\t\t\t\t);\n\t\t\t\tvar title = header.text();\n\t\t\t\tif ( title ) {\n\t\t\t\t\ttitle = title + ':';\n\t\t\t\t}\n\n\t\t\t\treturn '<li data-dtr-index=\"'+idx.column+'\">'+\n\t\t\t\t\t\t'<span class=\"dtr-title\">'+\n\t\t\t\t\t\t\ttitle+\n\t\t\t\t\t\t'</span> '+\n\t\t\t\t\t\t'<span class=\"dtr-data\">'+\n\t\t\t\t\t\t\tcellData+\n\t\t\t\t\t\t'</span>'+\n\t\t\t\t\t'</li>';\n\t\t\t} ).toArray().join('');\n\n\t\t\treturn data ?\n\t\t\t\t$('<ul data-dtr-index=\"'+rowIdx+'\"/>').append( data ) :\n\t\t\t\tfalse;\n\t\t},\n\n\t\ttarget: 0,\n\n\t\ttype: 'inline'\n\t}\n};\n\n\n/*\n * API\n */\nvar Api = $.fn.dataTable.Api;\n\n// Doesn't do anything - work around for a bug in DT... Not documented\nApi.register( 'responsive()', function () {\n\treturn this;\n} );\n\nApi.register( 'responsive.index()', function ( li ) {\n\tli = $(li);\n\n\treturn {\n\t\tcolumn: li.data('dtr-index'),\n\t\trow:    li.parent().data('dtr-index')\n\t};\n} );\n\nApi.register( 'responsive.rebuild()', function () {\n\treturn this.iterator( 'table', function ( ctx ) {\n\t\tif ( ctx._responsive ) {\n\t\t\tctx._responsive._classLogic();\n\t\t}\n\t} );\n} );\n\nApi.register( 'responsive.recalc()', function () {\n\treturn this.iterator( 'table', function ( ctx ) {\n\t\tif ( ctx._responsive ) {\n\t\t\tctx._responsive._resizeAuto();\n\t\t\tctx._responsive._resize();\n\t\t}\n\t} );\n} );\n\n\n/**\n * Version information\n *\n * @name Responsive.version\n * @static\n */\nResponsive.version = '1.0.6';\n\n\n$.fn.dataTable.Responsive = Responsive;\n$.fn.DataTable.Responsive = Responsive;\n\n// Attach a listener to the document which listens for DataTables initialisation\n// events so we can automatically initialise\n$(document).on( 'init.dt.dtr', function (e, settings, json) {\n\tif ( e.namespace !== 'dt' ) {\n\t\treturn;\n\t}\n\n\tif ( $(settings.nTable).hasClass( 'responsive' ) ||\n\t\t $(settings.nTable).hasClass( 'dt-responsive' ) ||\n\t\t settings.oInit.responsive ||\n\t\t DataTable.defaults.responsive\n\t) {\n\t\tvar init = settings.oInit.responsive;\n\n\t\tif ( init !== false ) {\n\t\t\tnew Responsive( settings, $.isPlainObject( init ) ? init : {}  );\n\t\t}\n\t}\n} );\n\nreturn Responsive;\n}; // /factory\n\n\n// Define as an AMD module if possible\nif ( typeof define === 'function' && define.amd ) {\n\tdefine( ['jquery', 'datatables'], factory );\n}\nelse if ( typeof exports === 'object' ) {\n    // Node/CommonJS\n    factory( require('jquery'), require('datatables') );\n}\nelse if ( jQuery && !jQuery.fn.dataTable.Responsive ) {\n\t// Otherwise simply initialise as normal, stopping multiple evaluation\n\tfactory( jQuery, jQuery.fn.dataTable );\n}\n\n\n})(window, document);\n"
  },
  {
    "path": "app_backend/vendor/datatables-responsive/dataTables.responsive.scss",
    "content": "\n//\n// Mixins\n//\n@mixin control() {\n\tdisplay: block;\n\tposition: absolute;\n\tcolor: white;\n\tborder: 2px solid white;\n\tborder-radius: 16px;\n\ttext-align: center;\n\tline-height: 14px;\n\tbox-shadow: 0 0 3px #444;\n\tbox-sizing: content-box;\n}\n\n@mixin control-open() {\n\tcontent: '+';\n\tbackground-color: #31b131;\n}\n\n@mixin control-close() {\n\tcontent: '-';\n\tbackground-color: #d33333;\n}\n\n\n//\n// Table styles\n//\ntable.dataTable {\n\t// Styling for the `inline` type\n\t&.dtr-inline.collapsed > tbody {\n\t\t> tr > td:first-child,\n\t\t> tr > th:first-child {\n\t\t\tposition: relative;\n\t\t\tpadding-left: 30px;\n\t\t\tcursor: pointer;\n\n\t\t\t&:before {\n\t\t\t\ttop: 8px;\n\t\t\t\tleft: 4px;\n\t\t\t\theight: 16px;\n\t\t\t\twidth: 16px;\n\t\t\t\t@include control;\n\t\t\t\t@include control-open;\n\t\t\t}\n\n\t\t\t&.dataTables_empty:before {\n\t\t\t\tdisplay: none;\n\t\t\t}\n\t\t}\n\n\t\t> tr.parent {\n\t\t\t> td:first-child:before,\n\t\t\t> th:first-child:before {\n\t\t\t\t@include control-close;\n\t\t\t}\n\t\t}\n\n\t\t> tr.child td:before {\n\t\t\tdisplay: none;\n\t\t}\n\t}\n\n\t// DataTables' `compact` styling\n\t&.dtr-inline.collapsed.compact > tbody {\n\t\t> tr > td:first-child,\n\t\t> tr > th:first-child {\n\t\t\tpadding-left: 27px;\n\n\t\t\t&:before {\n\t\t\t\ttop: 5px;\n\t\t\t\tleft: 4px;\n\t\t\t\theight: 14px;\n\t\t\t\twidth: 14px;\n\t\t\t\tborder-radius: 14px;\n\t\t\t\tline-height: 12px;\n\t\t\t}\n\t\t}\n\t}\n\n\n\t// Styling for the `column` type\n\t&.dtr-column > tbody {\n\t\t> tr > td.control,\n\t\t> tr > th.control {\n\t\t\tposition: relative;\n\t\t\tcursor: pointer;\n\n\t\t\t&:before {\n\t\t\t\ttop: 50%;\n\t\t\t\tleft: 50%;\n\t\t\t\theight: 16px;\n\t\t\t\twidth: 16px;\n\t\t\t\tmargin-top: -10px;\n\t\t\t\tmargin-left: -10px;\n\t\t\t\t@include control;\n\t\t\t\t@include control-open;\n\t\t\t}\n\t\t}\n\n\t\t> tr.parent {\n\t\t\ttd.control:before,\n\t\t\tth.control:before {\n\t\t\t\t@include control-close;\n\t\t\t}\n\t\t}\n\t}\n\n\n\t// Child row styling\n\t> tbody > tr.child {\n\t\tpadding: 0.5em 1em;\n\n\t\t&:hover {\n\t\t\tbackground: transparent !important;\n\t\t}\n\n\t\tul {\n\t\t\tdisplay: inline-block;\n\t\t\tlist-style-type: none;\n\t\t\tmargin: 0;\n\t\t\tpadding: 0;\n\n\t\t\tli {\n\t\t\t\tborder-bottom: 1px solid #efefef;\n\t\t\t\tpadding: 0.5em 0;\n\n\t\t\t\t&:first-child {\n\t\t\t\t\tpadding-top: 0;\n\t\t\t\t}\n\n\t\t\t\t&:last-child {\n\t\t\t\t\tborder-bottom: none;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tspan.dtr-title {\n\t\t\tdisplay: inline-block;\n\t\t\tmin-width: 75px;\n\t\t\tfont-weight: bold;\n\t\t}\n\n\t\tspan.dtr-data {}\n\t}\n}\n\n"
  },
  {
    "path": "app_backend/vendor/flot/excanvas.js",
    "content": "// Copyright 2006 Google Inc.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//   http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n\n// Known Issues:\n//\n// * Patterns only support repeat.\n// * Radial gradient are not implemented. The VML version of these look very\n//   different from the canvas one.\n// * Clipping paths are not implemented.\n// * Coordsize. The width and height attribute have higher priority than the\n//   width and height style values which isn't correct.\n// * Painting mode isn't implemented.\n// * Canvas width/height should is using content-box by default. IE in\n//   Quirks mode will draw the canvas using border-box. Either change your\n//   doctype to HTML5\n//   (http://www.whatwg.org/specs/web-apps/current-work/#the-doctype)\n//   or use Box Sizing Behavior from WebFX\n//   (http://webfx.eae.net/dhtml/boxsizing/boxsizing.html)\n// * Non uniform scaling does not correctly scale strokes.\n// * Filling very large shapes (above 5000 points) is buggy.\n// * Optimize. There is always room for speed improvements.\n\n// Only add this code if we do not already have a canvas implementation\nif (!document.createElement('canvas').getContext) {\n\n(function() {\n\n  // alias some functions to make (compiled) code shorter\n  var m = Math;\n  var mr = m.round;\n  var ms = m.sin;\n  var mc = m.cos;\n  var abs = m.abs;\n  var sqrt = m.sqrt;\n\n  // this is used for sub pixel precision\n  var Z = 10;\n  var Z2 = Z / 2;\n\n  var IE_VERSION = +navigator.userAgent.match(/MSIE ([\\d.]+)?/)[1];\n\n  /**\n   * This funtion is assigned to the <canvas> elements as element.getContext().\n   * @this {HTMLElement}\n   * @return {CanvasRenderingContext2D_}\n   */\n  function getContext() {\n    return this.context_ ||\n        (this.context_ = new CanvasRenderingContext2D_(this));\n  }\n\n  var slice = Array.prototype.slice;\n\n  /**\n   * Binds a function to an object. The returned function will always use the\n   * passed in {@code obj} as {@code this}.\n   *\n   * Example:\n   *\n   *   g = bind(f, obj, a, b)\n   *   g(c, d) // will do f.call(obj, a, b, c, d)\n   *\n   * @param {Function} f The function to bind the object to\n   * @param {Object} obj The object that should act as this when the function\n   *     is called\n   * @param {*} var_args Rest arguments that will be used as the initial\n   *     arguments when the function is called\n   * @return {Function} A new function that has bound this\n   */\n  function bind(f, obj, var_args) {\n    var a = slice.call(arguments, 2);\n    return function() {\n      return f.apply(obj, a.concat(slice.call(arguments)));\n    };\n  }\n\n  function encodeHtmlAttribute(s) {\n    return String(s).replace(/&/g, '&amp;').replace(/\"/g, '&quot;');\n  }\n\n  function addNamespace(doc, prefix, urn) {\n    if (!doc.namespaces[prefix]) {\n      doc.namespaces.add(prefix, urn, '#default#VML');\n    }\n  }\n\n  function addNamespacesAndStylesheet(doc) {\n    addNamespace(doc, 'g_vml_', 'urn:schemas-microsoft-com:vml');\n    addNamespace(doc, 'g_o_', 'urn:schemas-microsoft-com:office:office');\n\n    // Setup default CSS.  Only add one style sheet per document\n    if (!doc.styleSheets['ex_canvas_']) {\n      var ss = doc.createStyleSheet();\n      ss.owningElement.id = 'ex_canvas_';\n      ss.cssText = 'canvas{display:inline-block;overflow:hidden;' +\n          // default size is 300x150 in Gecko and Opera\n          'text-align:left;width:300px;height:150px}';\n    }\n  }\n\n  // Add namespaces and stylesheet at startup.\n  addNamespacesAndStylesheet(document);\n\n  var G_vmlCanvasManager_ = {\n    init: function(opt_doc) {\n      var doc = opt_doc || document;\n      // Create a dummy element so that IE will allow canvas elements to be\n      // recognized.\n      doc.createElement('canvas');\n      doc.attachEvent('onreadystatechange', bind(this.init_, this, doc));\n    },\n\n    init_: function(doc) {\n      // find all canvas elements\n      var els = doc.getElementsByTagName('canvas');\n      for (var i = 0; i < els.length; i++) {\n        this.initElement(els[i]);\n      }\n    },\n\n    /**\n     * Public initializes a canvas element so that it can be used as canvas\n     * element from now on. This is called automatically before the page is\n     * loaded but if you are creating elements using createElement you need to\n     * make sure this is called on the element.\n     * @param {HTMLElement} el The canvas element to initialize.\n     * @return {HTMLElement} the element that was created.\n     */\n    initElement: function(el) {\n      if (!el.getContext) {\n        el.getContext = getContext;\n\n        // Add namespaces and stylesheet to document of the element.\n        addNamespacesAndStylesheet(el.ownerDocument);\n\n        // Remove fallback content. There is no way to hide text nodes so we\n        // just remove all childNodes. We could hide all elements and remove\n        // text nodes but who really cares about the fallback content.\n        el.innerHTML = '';\n\n        // do not use inline function because that will leak memory\n        el.attachEvent('onpropertychange', onPropertyChange);\n        el.attachEvent('onresize', onResize);\n\n        var attrs = el.attributes;\n        if (attrs.width && attrs.width.specified) {\n          // TODO: use runtimeStyle and coordsize\n          // el.getContext().setWidth_(attrs.width.nodeValue);\n          el.style.width = attrs.width.nodeValue + 'px';\n        } else {\n          el.width = el.clientWidth;\n        }\n        if (attrs.height && attrs.height.specified) {\n          // TODO: use runtimeStyle and coordsize\n          // el.getContext().setHeight_(attrs.height.nodeValue);\n          el.style.height = attrs.height.nodeValue + 'px';\n        } else {\n          el.height = el.clientHeight;\n        }\n        //el.getContext().setCoordsize_()\n      }\n      return el;\n    }\n  };\n\n  function onPropertyChange(e) {\n    var el = e.srcElement;\n\n    switch (e.propertyName) {\n      case 'width':\n        el.getContext().clearRect();\n        el.style.width = el.attributes.width.nodeValue + 'px';\n        // In IE8 this does not trigger onresize.\n        el.firstChild.style.width =  el.clientWidth + 'px';\n        break;\n      case 'height':\n        el.getContext().clearRect();\n        el.style.height = el.attributes.height.nodeValue + 'px';\n        el.firstChild.style.height = el.clientHeight + 'px';\n        break;\n    }\n  }\n\n  function onResize(e) {\n    var el = e.srcElement;\n    if (el.firstChild) {\n      el.firstChild.style.width =  el.clientWidth + 'px';\n      el.firstChild.style.height = el.clientHeight + 'px';\n    }\n  }\n\n  G_vmlCanvasManager_.init();\n\n  // precompute \"00\" to \"FF\"\n  var decToHex = [];\n  for (var i = 0; i < 16; i++) {\n    for (var j = 0; j < 16; j++) {\n      decToHex[i * 16 + j] = i.toString(16) + j.toString(16);\n    }\n  }\n\n  function createMatrixIdentity() {\n    return [\n      [1, 0, 0],\n      [0, 1, 0],\n      [0, 0, 1]\n    ];\n  }\n\n  function matrixMultiply(m1, m2) {\n    var result = createMatrixIdentity();\n\n    for (var x = 0; x < 3; x++) {\n      for (var y = 0; y < 3; y++) {\n        var sum = 0;\n\n        for (var z = 0; z < 3; z++) {\n          sum += m1[x][z] * m2[z][y];\n        }\n\n        result[x][y] = sum;\n      }\n    }\n    return result;\n  }\n\n  function copyState(o1, o2) {\n    o2.fillStyle     = o1.fillStyle;\n    o2.lineCap       = o1.lineCap;\n    o2.lineJoin      = o1.lineJoin;\n    o2.lineWidth     = o1.lineWidth;\n    o2.miterLimit    = o1.miterLimit;\n    o2.shadowBlur    = o1.shadowBlur;\n    o2.shadowColor   = o1.shadowColor;\n    o2.shadowOffsetX = o1.shadowOffsetX;\n    o2.shadowOffsetY = o1.shadowOffsetY;\n    o2.strokeStyle   = o1.strokeStyle;\n    o2.globalAlpha   = o1.globalAlpha;\n    o2.font          = o1.font;\n    o2.textAlign     = o1.textAlign;\n    o2.textBaseline  = o1.textBaseline;\n    o2.arcScaleX_    = o1.arcScaleX_;\n    o2.arcScaleY_    = o1.arcScaleY_;\n    o2.lineScale_    = o1.lineScale_;\n  }\n\n  var colorData = {\n    aliceblue: '#F0F8FF',\n    antiquewhite: '#FAEBD7',\n    aquamarine: '#7FFFD4',\n    azure: '#F0FFFF',\n    beige: '#F5F5DC',\n    bisque: '#FFE4C4',\n    black: '#000000',\n    blanchedalmond: '#FFEBCD',\n    blueviolet: '#8A2BE2',\n    brown: '#A52A2A',\n    burlywood: '#DEB887',\n    cadetblue: '#5F9EA0',\n    chartreuse: '#7FFF00',\n    chocolate: '#D2691E',\n    coral: '#FF7F50',\n    cornflowerblue: '#6495ED',\n    cornsilk: '#FFF8DC',\n    crimson: '#DC143C',\n    cyan: '#00FFFF',\n    darkblue: '#00008B',\n    darkcyan: '#008B8B',\n    darkgoldenrod: '#B8860B',\n    darkgray: '#A9A9A9',\n    darkgreen: '#006400',\n    darkgrey: '#A9A9A9',\n    darkkhaki: '#BDB76B',\n    darkmagenta: '#8B008B',\n    darkolivegreen: '#556B2F',\n    darkorange: '#FF8C00',\n    darkorchid: '#9932CC',\n    darkred: '#8B0000',\n    darksalmon: '#E9967A',\n    darkseagreen: '#8FBC8F',\n    darkslateblue: '#483D8B',\n    darkslategray: '#2F4F4F',\n    darkslategrey: '#2F4F4F',\n    darkturquoise: '#00CED1',\n    darkviolet: '#9400D3',\n    deeppink: '#FF1493',\n    deepskyblue: '#00BFFF',\n    dimgray: '#696969',\n    dimgrey: '#696969',\n    dodgerblue: '#1E90FF',\n    firebrick: '#B22222',\n    floralwhite: '#FFFAF0',\n    forestgreen: '#228B22',\n    gainsboro: '#DCDCDC',\n    ghostwhite: '#F8F8FF',\n    gold: '#FFD700',\n    goldenrod: '#DAA520',\n    grey: '#808080',\n    greenyellow: '#ADFF2F',\n    honeydew: '#F0FFF0',\n    hotpink: '#FF69B4',\n    indianred: '#CD5C5C',\n    indigo: '#4B0082',\n    ivory: '#FFFFF0',\n    khaki: '#F0E68C',\n    lavender: '#E6E6FA',\n    lavenderblush: '#FFF0F5',\n    lawngreen: '#7CFC00',\n    lemonchiffon: '#FFFACD',\n    lightblue: '#ADD8E6',\n    lightcoral: '#F08080',\n    lightcyan: '#E0FFFF',\n    lightgoldenrodyellow: '#FAFAD2',\n    lightgreen: '#90EE90',\n    lightgrey: '#D3D3D3',\n    lightpink: '#FFB6C1',\n    lightsalmon: '#FFA07A',\n    lightseagreen: '#20B2AA',\n    lightskyblue: '#87CEFA',\n    lightslategray: '#778899',\n    lightslategrey: '#778899',\n    lightsteelblue: '#B0C4DE',\n    lightyellow: '#FFFFE0',\n    limegreen: '#32CD32',\n    linen: '#FAF0E6',\n    magenta: '#FF00FF',\n    mediumaquamarine: '#66CDAA',\n    mediumblue: '#0000CD',\n    mediumorchid: '#BA55D3',\n    mediumpurple: '#9370DB',\n    mediumseagreen: '#3CB371',\n    mediumslateblue: '#7B68EE',\n    mediumspringgreen: '#00FA9A',\n    mediumturquoise: '#48D1CC',\n    mediumvioletred: '#C71585',\n    midnightblue: '#191970',\n    mintcream: '#F5FFFA',\n    mistyrose: '#FFE4E1',\n    moccasin: '#FFE4B5',\n    navajowhite: '#FFDEAD',\n    oldlace: '#FDF5E6',\n    olivedrab: '#6B8E23',\n    orange: '#FFA500',\n    orangered: '#FF4500',\n    orchid: '#DA70D6',\n    palegoldenrod: '#EEE8AA',\n    palegreen: '#98FB98',\n    paleturquoise: '#AFEEEE',\n    palevioletred: '#DB7093',\n    papayawhip: '#FFEFD5',\n    peachpuff: '#FFDAB9',\n    peru: '#CD853F',\n    pink: '#FFC0CB',\n    plum: '#DDA0DD',\n    powderblue: '#B0E0E6',\n    rosybrown: '#BC8F8F',\n    royalblue: '#4169E1',\n    saddlebrown: '#8B4513',\n    salmon: '#FA8072',\n    sandybrown: '#F4A460',\n    seagreen: '#2E8B57',\n    seashell: '#FFF5EE',\n    sienna: '#A0522D',\n    skyblue: '#87CEEB',\n    slateblue: '#6A5ACD',\n    slategray: '#708090',\n    slategrey: '#708090',\n    snow: '#FFFAFA',\n    springgreen: '#00FF7F',\n    steelblue: '#4682B4',\n    tan: '#D2B48C',\n    thistle: '#D8BFD8',\n    tomato: '#FF6347',\n    turquoise: '#40E0D0',\n    violet: '#EE82EE',\n    wheat: '#F5DEB3',\n    whitesmoke: '#F5F5F5',\n    yellowgreen: '#9ACD32'\n  };\n\n\n  function getRgbHslContent(styleString) {\n    var start = styleString.indexOf('(', 3);\n    var end = styleString.indexOf(')', start + 1);\n    var parts = styleString.substring(start + 1, end).split(',');\n    // add alpha if needed\n    if (parts.length != 4 || styleString.charAt(3) != 'a') {\n      parts[3] = 1;\n    }\n    return parts;\n  }\n\n  function percent(s) {\n    return parseFloat(s) / 100;\n  }\n\n  function clamp(v, min, max) {\n    return Math.min(max, Math.max(min, v));\n  }\n\n  function hslToRgb(parts){\n    var r, g, b, h, s, l;\n    h = parseFloat(parts[0]) / 360 % 360;\n    if (h < 0)\n      h++;\n    s = clamp(percent(parts[1]), 0, 1);\n    l = clamp(percent(parts[2]), 0, 1);\n    if (s == 0) {\n      r = g = b = l; // achromatic\n    } else {\n      var q = l < 0.5 ? l * (1 + s) : l + s - l * s;\n      var p = 2 * l - q;\n      r = hueToRgb(p, q, h + 1 / 3);\n      g = hueToRgb(p, q, h);\n      b = hueToRgb(p, q, h - 1 / 3);\n    }\n\n    return '#' + decToHex[Math.floor(r * 255)] +\n        decToHex[Math.floor(g * 255)] +\n        decToHex[Math.floor(b * 255)];\n  }\n\n  function hueToRgb(m1, m2, h) {\n    if (h < 0)\n      h++;\n    if (h > 1)\n      h--;\n\n    if (6 * h < 1)\n      return m1 + (m2 - m1) * 6 * h;\n    else if (2 * h < 1)\n      return m2;\n    else if (3 * h < 2)\n      return m1 + (m2 - m1) * (2 / 3 - h) * 6;\n    else\n      return m1;\n  }\n\n  var processStyleCache = {};\n\n  function processStyle(styleString) {\n    if (styleString in processStyleCache) {\n      return processStyleCache[styleString];\n    }\n\n    var str, alpha = 1;\n\n    styleString = String(styleString);\n    if (styleString.charAt(0) == '#') {\n      str = styleString;\n    } else if (/^rgb/.test(styleString)) {\n      var parts = getRgbHslContent(styleString);\n      var str = '#', n;\n      for (var i = 0; i < 3; i++) {\n        if (parts[i].indexOf('%') != -1) {\n          n = Math.floor(percent(parts[i]) * 255);\n        } else {\n          n = +parts[i];\n        }\n        str += decToHex[clamp(n, 0, 255)];\n      }\n      alpha = +parts[3];\n    } else if (/^hsl/.test(styleString)) {\n      var parts = getRgbHslContent(styleString);\n      str = hslToRgb(parts);\n      alpha = parts[3];\n    } else {\n      str = colorData[styleString] || styleString;\n    }\n    return processStyleCache[styleString] = {color: str, alpha: alpha};\n  }\n\n  var DEFAULT_STYLE = {\n    style: 'normal',\n    variant: 'normal',\n    weight: 'normal',\n    size: 10,\n    family: 'sans-serif'\n  };\n\n  // Internal text style cache\n  var fontStyleCache = {};\n\n  function processFontStyle(styleString) {\n    if (fontStyleCache[styleString]) {\n      return fontStyleCache[styleString];\n    }\n\n    var el = document.createElement('div');\n    var style = el.style;\n    try {\n      style.font = styleString;\n    } catch (ex) {\n      // Ignore failures to set to invalid font.\n    }\n\n    return fontStyleCache[styleString] = {\n      style: style.fontStyle || DEFAULT_STYLE.style,\n      variant: style.fontVariant || DEFAULT_STYLE.variant,\n      weight: style.fontWeight || DEFAULT_STYLE.weight,\n      size: style.fontSize || DEFAULT_STYLE.size,\n      family: style.fontFamily || DEFAULT_STYLE.family\n    };\n  }\n\n  function getComputedStyle(style, element) {\n    var computedStyle = {};\n\n    for (var p in style) {\n      computedStyle[p] = style[p];\n    }\n\n    // Compute the size\n    var canvasFontSize = parseFloat(element.currentStyle.fontSize),\n        fontSize = parseFloat(style.size);\n\n    if (typeof style.size == 'number') {\n      computedStyle.size = style.size;\n    } else if (style.size.indexOf('px') != -1) {\n      computedStyle.size = fontSize;\n    } else if (style.size.indexOf('em') != -1) {\n      computedStyle.size = canvasFontSize * fontSize;\n    } else if(style.size.indexOf('%') != -1) {\n      computedStyle.size = (canvasFontSize / 100) * fontSize;\n    } else if (style.size.indexOf('pt') != -1) {\n      computedStyle.size = fontSize / .75;\n    } else {\n      computedStyle.size = canvasFontSize;\n    }\n\n    // Different scaling between normal text and VML text. This was found using\n    // trial and error to get the same size as non VML text.\n    computedStyle.size *= 0.981;\n\n    return computedStyle;\n  }\n\n  function buildStyle(style) {\n    return style.style + ' ' + style.variant + ' ' + style.weight + ' ' +\n        style.size + 'px ' + style.family;\n  }\n\n  var lineCapMap = {\n    'butt': 'flat',\n    'round': 'round'\n  };\n\n  function processLineCap(lineCap) {\n    return lineCapMap[lineCap] || 'square';\n  }\n\n  /**\n   * This class implements CanvasRenderingContext2D interface as described by\n   * the WHATWG.\n   * @param {HTMLElement} canvasElement The element that the 2D context should\n   * be associated with\n   */\n  function CanvasRenderingContext2D_(canvasElement) {\n    this.m_ = createMatrixIdentity();\n\n    this.mStack_ = [];\n    this.aStack_ = [];\n    this.currentPath_ = [];\n\n    // Canvas context properties\n    this.strokeStyle = '#000';\n    this.fillStyle = '#000';\n\n    this.lineWidth = 1;\n    this.lineJoin = 'miter';\n    this.lineCap = 'butt';\n    this.miterLimit = Z * 1;\n    this.globalAlpha = 1;\n    this.font = '10px sans-serif';\n    this.textAlign = 'left';\n    this.textBaseline = 'alphabetic';\n    this.canvas = canvasElement;\n\n    var cssText = 'width:' + canvasElement.clientWidth + 'px;height:' +\n        canvasElement.clientHeight + 'px;overflow:hidden;position:absolute';\n    var el = canvasElement.ownerDocument.createElement('div');\n    el.style.cssText = cssText;\n    canvasElement.appendChild(el);\n\n    var overlayEl = el.cloneNode(false);\n    // Use a non transparent background.\n    overlayEl.style.backgroundColor = 'red';\n    overlayEl.style.filter = 'alpha(opacity=0)';\n    canvasElement.appendChild(overlayEl);\n\n    this.element_ = el;\n    this.arcScaleX_ = 1;\n    this.arcScaleY_ = 1;\n    this.lineScale_ = 1;\n  }\n\n  var contextPrototype = CanvasRenderingContext2D_.prototype;\n  contextPrototype.clearRect = function() {\n    if (this.textMeasureEl_) {\n      this.textMeasureEl_.removeNode(true);\n      this.textMeasureEl_ = null;\n    }\n    this.element_.innerHTML = '';\n  };\n\n  contextPrototype.beginPath = function() {\n    // TODO: Branch current matrix so that save/restore has no effect\n    //       as per safari docs.\n    this.currentPath_ = [];\n  };\n\n  contextPrototype.moveTo = function(aX, aY) {\n    var p = getCoords(this, aX, aY);\n    this.currentPath_.push({type: 'moveTo', x: p.x, y: p.y});\n    this.currentX_ = p.x;\n    this.currentY_ = p.y;\n  };\n\n  contextPrototype.lineTo = function(aX, aY) {\n    var p = getCoords(this, aX, aY);\n    this.currentPath_.push({type: 'lineTo', x: p.x, y: p.y});\n\n    this.currentX_ = p.x;\n    this.currentY_ = p.y;\n  };\n\n  contextPrototype.bezierCurveTo = function(aCP1x, aCP1y,\n                                            aCP2x, aCP2y,\n                                            aX, aY) {\n    var p = getCoords(this, aX, aY);\n    var cp1 = getCoords(this, aCP1x, aCP1y);\n    var cp2 = getCoords(this, aCP2x, aCP2y);\n    bezierCurveTo(this, cp1, cp2, p);\n  };\n\n  // Helper function that takes the already fixed cordinates.\n  function bezierCurveTo(self, cp1, cp2, p) {\n    self.currentPath_.push({\n      type: 'bezierCurveTo',\n      cp1x: cp1.x,\n      cp1y: cp1.y,\n      cp2x: cp2.x,\n      cp2y: cp2.y,\n      x: p.x,\n      y: p.y\n    });\n    self.currentX_ = p.x;\n    self.currentY_ = p.y;\n  }\n\n  contextPrototype.quadraticCurveTo = function(aCPx, aCPy, aX, aY) {\n    // the following is lifted almost directly from\n    // http://developer.mozilla.org/en/docs/Canvas_tutorial:Drawing_shapes\n\n    var cp = getCoords(this, aCPx, aCPy);\n    var p = getCoords(this, aX, aY);\n\n    var cp1 = {\n      x: this.currentX_ + 2.0 / 3.0 * (cp.x - this.currentX_),\n      y: this.currentY_ + 2.0 / 3.0 * (cp.y - this.currentY_)\n    };\n    var cp2 = {\n      x: cp1.x + (p.x - this.currentX_) / 3.0,\n      y: cp1.y + (p.y - this.currentY_) / 3.0\n    };\n\n    bezierCurveTo(this, cp1, cp2, p);\n  };\n\n  contextPrototype.arc = function(aX, aY, aRadius,\n                                  aStartAngle, aEndAngle, aClockwise) {\n    aRadius *= Z;\n    var arcType = aClockwise ? 'at' : 'wa';\n\n    var xStart = aX + mc(aStartAngle) * aRadius - Z2;\n    var yStart = aY + ms(aStartAngle) * aRadius - Z2;\n\n    var xEnd = aX + mc(aEndAngle) * aRadius - Z2;\n    var yEnd = aY + ms(aEndAngle) * aRadius - Z2;\n\n    // IE won't render arches drawn counter clockwise if xStart == xEnd.\n    if (xStart == xEnd && !aClockwise) {\n      xStart += 0.125; // Offset xStart by 1/80 of a pixel. Use something\n                       // that can be represented in binary\n    }\n\n    var p = getCoords(this, aX, aY);\n    var pStart = getCoords(this, xStart, yStart);\n    var pEnd = getCoords(this, xEnd, yEnd);\n\n    this.currentPath_.push({type: arcType,\n                           x: p.x,\n                           y: p.y,\n                           radius: aRadius,\n                           xStart: pStart.x,\n                           yStart: pStart.y,\n                           xEnd: pEnd.x,\n                           yEnd: pEnd.y});\n\n  };\n\n  contextPrototype.rect = function(aX, aY, aWidth, aHeight) {\n    this.moveTo(aX, aY);\n    this.lineTo(aX + aWidth, aY);\n    this.lineTo(aX + aWidth, aY + aHeight);\n    this.lineTo(aX, aY + aHeight);\n    this.closePath();\n  };\n\n  contextPrototype.strokeRect = function(aX, aY, aWidth, aHeight) {\n    var oldPath = this.currentPath_;\n    this.beginPath();\n\n    this.moveTo(aX, aY);\n    this.lineTo(aX + aWidth, aY);\n    this.lineTo(aX + aWidth, aY + aHeight);\n    this.lineTo(aX, aY + aHeight);\n    this.closePath();\n    this.stroke();\n\n    this.currentPath_ = oldPath;\n  };\n\n  contextPrototype.fillRect = function(aX, aY, aWidth, aHeight) {\n    var oldPath = this.currentPath_;\n    this.beginPath();\n\n    this.moveTo(aX, aY);\n    this.lineTo(aX + aWidth, aY);\n    this.lineTo(aX + aWidth, aY + aHeight);\n    this.lineTo(aX, aY + aHeight);\n    this.closePath();\n    this.fill();\n\n    this.currentPath_ = oldPath;\n  };\n\n  contextPrototype.createLinearGradient = function(aX0, aY0, aX1, aY1) {\n    var gradient = new CanvasGradient_('gradient');\n    gradient.x0_ = aX0;\n    gradient.y0_ = aY0;\n    gradient.x1_ = aX1;\n    gradient.y1_ = aY1;\n    return gradient;\n  };\n\n  contextPrototype.createRadialGradient = function(aX0, aY0, aR0,\n                                                   aX1, aY1, aR1) {\n    var gradient = new CanvasGradient_('gradientradial');\n    gradient.x0_ = aX0;\n    gradient.y0_ = aY0;\n    gradient.r0_ = aR0;\n    gradient.x1_ = aX1;\n    gradient.y1_ = aY1;\n    gradient.r1_ = aR1;\n    return gradient;\n  };\n\n  contextPrototype.drawImage = function(image, var_args) {\n    var dx, dy, dw, dh, sx, sy, sw, sh;\n\n    // to find the original width we overide the width and height\n    var oldRuntimeWidth = image.runtimeStyle.width;\n    var oldRuntimeHeight = image.runtimeStyle.height;\n    image.runtimeStyle.width = 'auto';\n    image.runtimeStyle.height = 'auto';\n\n    // get the original size\n    var w = image.width;\n    var h = image.height;\n\n    // and remove overides\n    image.runtimeStyle.width = oldRuntimeWidth;\n    image.runtimeStyle.height = oldRuntimeHeight;\n\n    if (arguments.length == 3) {\n      dx = arguments[1];\n      dy = arguments[2];\n      sx = sy = 0;\n      sw = dw = w;\n      sh = dh = h;\n    } else if (arguments.length == 5) {\n      dx = arguments[1];\n      dy = arguments[2];\n      dw = arguments[3];\n      dh = arguments[4];\n      sx = sy = 0;\n      sw = w;\n      sh = h;\n    } else if (arguments.length == 9) {\n      sx = arguments[1];\n      sy = arguments[2];\n      sw = arguments[3];\n      sh = arguments[4];\n      dx = arguments[5];\n      dy = arguments[6];\n      dw = arguments[7];\n      dh = arguments[8];\n    } else {\n      throw Error('Invalid number of arguments');\n    }\n\n    var d = getCoords(this, dx, dy);\n\n    var w2 = sw / 2;\n    var h2 = sh / 2;\n\n    var vmlStr = [];\n\n    var W = 10;\n    var H = 10;\n\n    // For some reason that I've now forgotten, using divs didn't work\n    vmlStr.push(' <g_vml_:group',\n                ' coordsize=\"', Z * W, ',', Z * H, '\"',\n                ' coordorigin=\"0,0\"' ,\n                ' style=\"width:', W, 'px;height:', H, 'px;position:absolute;');\n\n    // If filters are necessary (rotation exists), create them\n    // filters are bog-slow, so only create them if abbsolutely necessary\n    // The following check doesn't account for skews (which don't exist\n    // in the canvas spec (yet) anyway.\n\n    if (this.m_[0][0] != 1 || this.m_[0][1] ||\n        this.m_[1][1] != 1 || this.m_[1][0]) {\n      var filter = [];\n\n      // Note the 12/21 reversal\n      filter.push('M11=', this.m_[0][0], ',',\n                  'M12=', this.m_[1][0], ',',\n                  'M21=', this.m_[0][1], ',',\n                  'M22=', this.m_[1][1], ',',\n                  'Dx=', mr(d.x / Z), ',',\n                  'Dy=', mr(d.y / Z), '');\n\n      // Bounding box calculation (need to minimize displayed area so that\n      // filters don't waste time on unused pixels.\n      var max = d;\n      var c2 = getCoords(this, dx + dw, dy);\n      var c3 = getCoords(this, dx, dy + dh);\n      var c4 = getCoords(this, dx + dw, dy + dh);\n\n      max.x = m.max(max.x, c2.x, c3.x, c4.x);\n      max.y = m.max(max.y, c2.y, c3.y, c4.y);\n\n      vmlStr.push('padding:0 ', mr(max.x / Z), 'px ', mr(max.y / Z),\n                  'px 0;filter:progid:DXImageTransform.Microsoft.Matrix(',\n                  filter.join(''), \", sizingmethod='clip');\");\n\n    } else {\n      vmlStr.push('top:', mr(d.y / Z), 'px;left:', mr(d.x / Z), 'px;');\n    }\n\n    vmlStr.push(' \">' ,\n                '<g_vml_:image src=\"', image.src, '\"',\n                ' style=\"width:', Z * dw, 'px;',\n                ' height:', Z * dh, 'px\"',\n                ' cropleft=\"', sx / w, '\"',\n                ' croptop=\"', sy / h, '\"',\n                ' cropright=\"', (w - sx - sw) / w, '\"',\n                ' cropbottom=\"', (h - sy - sh) / h, '\"',\n                ' />',\n                '</g_vml_:group>');\n\n    this.element_.insertAdjacentHTML('BeforeEnd', vmlStr.join(''));\n  };\n\n  contextPrototype.stroke = function(aFill) {\n    var W = 10;\n    var H = 10;\n    // Divide the shape into chunks if it's too long because IE has a limit\n    // somewhere for how long a VML shape can be. This simple division does\n    // not work with fills, only strokes, unfortunately.\n    var chunkSize = 5000;\n\n    var min = {x: null, y: null};\n    var max = {x: null, y: null};\n\n    for (var j = 0; j < this.currentPath_.length; j += chunkSize) {\n      var lineStr = [];\n      var lineOpen = false;\n\n      lineStr.push('<g_vml_:shape',\n                   ' filled=\"', !!aFill, '\"',\n                   ' style=\"position:absolute;width:', W, 'px;height:', H, 'px;\"',\n                   ' coordorigin=\"0,0\"',\n                   ' coordsize=\"', Z * W, ',', Z * H, '\"',\n                   ' stroked=\"', !aFill, '\"',\n                   ' path=\"');\n\n      var newSeq = false;\n\n      for (var i = j; i < Math.min(j + chunkSize, this.currentPath_.length); i++) {\n        if (i % chunkSize == 0 && i > 0) { // move into position for next chunk\n          lineStr.push(' m ', mr(this.currentPath_[i-1].x), ',', mr(this.currentPath_[i-1].y));\n        }\n\n        var p = this.currentPath_[i];\n        var c;\n\n        switch (p.type) {\n          case 'moveTo':\n            c = p;\n            lineStr.push(' m ', mr(p.x), ',', mr(p.y));\n            break;\n          case 'lineTo':\n            lineStr.push(' l ', mr(p.x), ',', mr(p.y));\n            break;\n          case 'close':\n            lineStr.push(' x ');\n            p = null;\n            break;\n          case 'bezierCurveTo':\n            lineStr.push(' c ',\n                         mr(p.cp1x), ',', mr(p.cp1y), ',',\n                         mr(p.cp2x), ',', mr(p.cp2y), ',',\n                         mr(p.x), ',', mr(p.y));\n            break;\n          case 'at':\n          case 'wa':\n            lineStr.push(' ', p.type, ' ',\n                         mr(p.x - this.arcScaleX_ * p.radius), ',',\n                         mr(p.y - this.arcScaleY_ * p.radius), ' ',\n                         mr(p.x + this.arcScaleX_ * p.radius), ',',\n                         mr(p.y + this.arcScaleY_ * p.radius), ' ',\n                         mr(p.xStart), ',', mr(p.yStart), ' ',\n                         mr(p.xEnd), ',', mr(p.yEnd));\n            break;\n        }\n  \n  \n        // TODO: Following is broken for curves due to\n        //       move to proper paths.\n  \n        // Figure out dimensions so we can do gradient fills\n        // properly\n        if (p) {\n          if (min.x == null || p.x < min.x) {\n            min.x = p.x;\n          }\n          if (max.x == null || p.x > max.x) {\n            max.x = p.x;\n          }\n          if (min.y == null || p.y < min.y) {\n            min.y = p.y;\n          }\n          if (max.y == null || p.y > max.y) {\n            max.y = p.y;\n          }\n        }\n      }\n      lineStr.push(' \">');\n  \n      if (!aFill) {\n        appendStroke(this, lineStr);\n      } else {\n        appendFill(this, lineStr, min, max);\n      }\n  \n      lineStr.push('</g_vml_:shape>');\n  \n      this.element_.insertAdjacentHTML('beforeEnd', lineStr.join(''));\n    }\n  };\n\n  function appendStroke(ctx, lineStr) {\n    var a = processStyle(ctx.strokeStyle);\n    var color = a.color;\n    var opacity = a.alpha * ctx.globalAlpha;\n    var lineWidth = ctx.lineScale_ * ctx.lineWidth;\n\n    // VML cannot correctly render a line if the width is less than 1px.\n    // In that case, we dilute the color to make the line look thinner.\n    if (lineWidth < 1) {\n      opacity *= lineWidth;\n    }\n\n    lineStr.push(\n      '<g_vml_:stroke',\n      ' opacity=\"', opacity, '\"',\n      ' joinstyle=\"', ctx.lineJoin, '\"',\n      ' miterlimit=\"', ctx.miterLimit, '\"',\n      ' endcap=\"', processLineCap(ctx.lineCap), '\"',\n      ' weight=\"', lineWidth, 'px\"',\n      ' color=\"', color, '\" />'\n    );\n  }\n\n  function appendFill(ctx, lineStr, min, max) {\n    var fillStyle = ctx.fillStyle;\n    var arcScaleX = ctx.arcScaleX_;\n    var arcScaleY = ctx.arcScaleY_;\n    var width = max.x - min.x;\n    var height = max.y - min.y;\n    if (fillStyle instanceof CanvasGradient_) {\n      // TODO: Gradients transformed with the transformation matrix.\n      var angle = 0;\n      var focus = {x: 0, y: 0};\n\n      // additional offset\n      var shift = 0;\n      // scale factor for offset\n      var expansion = 1;\n\n      if (fillStyle.type_ == 'gradient') {\n        var x0 = fillStyle.x0_ / arcScaleX;\n        var y0 = fillStyle.y0_ / arcScaleY;\n        var x1 = fillStyle.x1_ / arcScaleX;\n        var y1 = fillStyle.y1_ / arcScaleY;\n        var p0 = getCoords(ctx, x0, y0);\n        var p1 = getCoords(ctx, x1, y1);\n        var dx = p1.x - p0.x;\n        var dy = p1.y - p0.y;\n        angle = Math.atan2(dx, dy) * 180 / Math.PI;\n\n        // The angle should be a non-negative number.\n        if (angle < 0) {\n          angle += 360;\n        }\n\n        // Very small angles produce an unexpected result because they are\n        // converted to a scientific notation string.\n        if (angle < 1e-6) {\n          angle = 0;\n        }\n      } else {\n        var p0 = getCoords(ctx, fillStyle.x0_, fillStyle.y0_);\n        focus = {\n          x: (p0.x - min.x) / width,\n          y: (p0.y - min.y) / height\n        };\n\n        width  /= arcScaleX * Z;\n        height /= arcScaleY * Z;\n        var dimension = m.max(width, height);\n        shift = 2 * fillStyle.r0_ / dimension;\n        expansion = 2 * fillStyle.r1_ / dimension - shift;\n      }\n\n      // We need to sort the color stops in ascending order by offset,\n      // otherwise IE won't interpret it correctly.\n      var stops = fillStyle.colors_;\n      stops.sort(function(cs1, cs2) {\n        return cs1.offset - cs2.offset;\n      });\n\n      var length = stops.length;\n      var color1 = stops[0].color;\n      var color2 = stops[length - 1].color;\n      var opacity1 = stops[0].alpha * ctx.globalAlpha;\n      var opacity2 = stops[length - 1].alpha * ctx.globalAlpha;\n\n      var colors = [];\n      for (var i = 0; i < length; i++) {\n        var stop = stops[i];\n        colors.push(stop.offset * expansion + shift + ' ' + stop.color);\n      }\n\n      // When colors attribute is used, the meanings of opacity and o:opacity2\n      // are reversed.\n      lineStr.push('<g_vml_:fill type=\"', fillStyle.type_, '\"',\n                   ' method=\"none\" focus=\"100%\"',\n                   ' color=\"', color1, '\"',\n                   ' color2=\"', color2, '\"',\n                   ' colors=\"', colors.join(','), '\"',\n                   ' opacity=\"', opacity2, '\"',\n                   ' g_o_:opacity2=\"', opacity1, '\"',\n                   ' angle=\"', angle, '\"',\n                   ' focusposition=\"', focus.x, ',', focus.y, '\" />');\n    } else if (fillStyle instanceof CanvasPattern_) {\n      if (width && height) {\n        var deltaLeft = -min.x;\n        var deltaTop = -min.y;\n        lineStr.push('<g_vml_:fill',\n                     ' position=\"',\n                     deltaLeft / width * arcScaleX * arcScaleX, ',',\n                     deltaTop / height * arcScaleY * arcScaleY, '\"',\n                     ' type=\"tile\"',\n                     // TODO: Figure out the correct size to fit the scale.\n                     //' size=\"', w, 'px ', h, 'px\"',\n                     ' src=\"', fillStyle.src_, '\" />');\n       }\n    } else {\n      var a = processStyle(ctx.fillStyle);\n      var color = a.color;\n      var opacity = a.alpha * ctx.globalAlpha;\n      lineStr.push('<g_vml_:fill color=\"', color, '\" opacity=\"', opacity,\n                   '\" />');\n    }\n  }\n\n  contextPrototype.fill = function() {\n    this.stroke(true);\n  };\n\n  contextPrototype.closePath = function() {\n    this.currentPath_.push({type: 'close'});\n  };\n\n  function getCoords(ctx, aX, aY) {\n    var m = ctx.m_;\n    return {\n      x: Z * (aX * m[0][0] + aY * m[1][0] + m[2][0]) - Z2,\n      y: Z * (aX * m[0][1] + aY * m[1][1] + m[2][1]) - Z2\n    };\n  };\n\n  contextPrototype.save = function() {\n    var o = {};\n    copyState(this, o);\n    this.aStack_.push(o);\n    this.mStack_.push(this.m_);\n    this.m_ = matrixMultiply(createMatrixIdentity(), this.m_);\n  };\n\n  contextPrototype.restore = function() {\n    if (this.aStack_.length) {\n      copyState(this.aStack_.pop(), this);\n      this.m_ = this.mStack_.pop();\n    }\n  };\n\n  function matrixIsFinite(m) {\n    return isFinite(m[0][0]) && isFinite(m[0][1]) &&\n        isFinite(m[1][0]) && isFinite(m[1][1]) &&\n        isFinite(m[2][0]) && isFinite(m[2][1]);\n  }\n\n  function setM(ctx, m, updateLineScale) {\n    if (!matrixIsFinite(m)) {\n      return;\n    }\n    ctx.m_ = m;\n\n    if (updateLineScale) {\n      // Get the line scale.\n      // Determinant of this.m_ means how much the area is enlarged by the\n      // transformation. So its square root can be used as a scale factor\n      // for width.\n      var det = m[0][0] * m[1][1] - m[0][1] * m[1][0];\n      ctx.lineScale_ = sqrt(abs(det));\n    }\n  }\n\n  contextPrototype.translate = function(aX, aY) {\n    var m1 = [\n      [1,  0,  0],\n      [0,  1,  0],\n      [aX, aY, 1]\n    ];\n\n    setM(this, matrixMultiply(m1, this.m_), false);\n  };\n\n  contextPrototype.rotate = function(aRot) {\n    var c = mc(aRot);\n    var s = ms(aRot);\n\n    var m1 = [\n      [c,  s, 0],\n      [-s, c, 0],\n      [0,  0, 1]\n    ];\n\n    setM(this, matrixMultiply(m1, this.m_), false);\n  };\n\n  contextPrototype.scale = function(aX, aY) {\n    this.arcScaleX_ *= aX;\n    this.arcScaleY_ *= aY;\n    var m1 = [\n      [aX, 0,  0],\n      [0,  aY, 0],\n      [0,  0,  1]\n    ];\n\n    setM(this, matrixMultiply(m1, this.m_), true);\n  };\n\n  contextPrototype.transform = function(m11, m12, m21, m22, dx, dy) {\n    var m1 = [\n      [m11, m12, 0],\n      [m21, m22, 0],\n      [dx,  dy,  1]\n    ];\n\n    setM(this, matrixMultiply(m1, this.m_), true);\n  };\n\n  contextPrototype.setTransform = function(m11, m12, m21, m22, dx, dy) {\n    var m = [\n      [m11, m12, 0],\n      [m21, m22, 0],\n      [dx,  dy,  1]\n    ];\n\n    setM(this, m, true);\n  };\n\n  /**\n   * The text drawing function.\n   * The maxWidth argument isn't taken in account, since no browser supports\n   * it yet.\n   */\n  contextPrototype.drawText_ = function(text, x, y, maxWidth, stroke) {\n    var m = this.m_,\n        delta = 1000,\n        left = 0,\n        right = delta,\n        offset = {x: 0, y: 0},\n        lineStr = [];\n\n    var fontStyle = getComputedStyle(processFontStyle(this.font),\n                                     this.element_);\n\n    var fontStyleString = buildStyle(fontStyle);\n\n    var elementStyle = this.element_.currentStyle;\n    var textAlign = this.textAlign.toLowerCase();\n    switch (textAlign) {\n      case 'left':\n      case 'center':\n      case 'right':\n        break;\n      case 'end':\n        textAlign = elementStyle.direction == 'ltr' ? 'right' : 'left';\n        break;\n      case 'start':\n        textAlign = elementStyle.direction == 'rtl' ? 'right' : 'left';\n        break;\n      default:\n        textAlign = 'left';\n    }\n\n    // 1.75 is an arbitrary number, as there is no info about the text baseline\n    switch (this.textBaseline) {\n      case 'hanging':\n      case 'top':\n        offset.y = fontStyle.size / 1.75;\n        break;\n      case 'middle':\n        break;\n      default:\n      case null:\n      case 'alphabetic':\n      case 'ideographic':\n      case 'bottom':\n        offset.y = -fontStyle.size / 2.25;\n        break;\n    }\n\n    switch(textAlign) {\n      case 'right':\n        left = delta;\n        right = 0.05;\n        break;\n      case 'center':\n        left = right = delta / 2;\n        break;\n    }\n\n    var d = getCoords(this, x + offset.x, y + offset.y);\n\n    lineStr.push('<g_vml_:line from=\"', -left ,' 0\" to=\"', right ,' 0.05\" ',\n                 ' coordsize=\"100 100\" coordorigin=\"0 0\"',\n                 ' filled=\"', !stroke, '\" stroked=\"', !!stroke,\n                 '\" style=\"position:absolute;width:1px;height:1px;\">');\n\n    if (stroke) {\n      appendStroke(this, lineStr);\n    } else {\n      // TODO: Fix the min and max params.\n      appendFill(this, lineStr, {x: -left, y: 0},\n                 {x: right, y: fontStyle.size});\n    }\n\n    var skewM = m[0][0].toFixed(3) + ',' + m[1][0].toFixed(3) + ',' +\n                m[0][1].toFixed(3) + ',' + m[1][1].toFixed(3) + ',0,0';\n\n    var skewOffset = mr(d.x / Z) + ',' + mr(d.y / Z);\n\n    lineStr.push('<g_vml_:skew on=\"t\" matrix=\"', skewM ,'\" ',\n                 ' offset=\"', skewOffset, '\" origin=\"', left ,' 0\" />',\n                 '<g_vml_:path textpathok=\"true\" />',\n                 '<g_vml_:textpath on=\"true\" string=\"',\n                 encodeHtmlAttribute(text),\n                 '\" style=\"v-text-align:', textAlign,\n                 ';font:', encodeHtmlAttribute(fontStyleString),\n                 '\" /></g_vml_:line>');\n\n    this.element_.insertAdjacentHTML('beforeEnd', lineStr.join(''));\n  };\n\n  contextPrototype.fillText = function(text, x, y, maxWidth) {\n    this.drawText_(text, x, y, maxWidth, false);\n  };\n\n  contextPrototype.strokeText = function(text, x, y, maxWidth) {\n    this.drawText_(text, x, y, maxWidth, true);\n  };\n\n  contextPrototype.measureText = function(text) {\n    if (!this.textMeasureEl_) {\n      var s = '<span style=\"position:absolute;' +\n          'top:-20000px;left:0;padding:0;margin:0;border:none;' +\n          'white-space:pre;\"></span>';\n      this.element_.insertAdjacentHTML('beforeEnd', s);\n      this.textMeasureEl_ = this.element_.lastChild;\n    }\n    var doc = this.element_.ownerDocument;\n    this.textMeasureEl_.innerHTML = '';\n    this.textMeasureEl_.style.font = this.font;\n    // Don't use innerHTML or innerText because they allow markup/whitespace.\n    this.textMeasureEl_.appendChild(doc.createTextNode(text));\n    return {width: this.textMeasureEl_.offsetWidth};\n  };\n\n  /******** STUBS ********/\n  contextPrototype.clip = function() {\n    // TODO: Implement\n  };\n\n  contextPrototype.arcTo = function() {\n    // TODO: Implement\n  };\n\n  contextPrototype.createPattern = function(image, repetition) {\n    return new CanvasPattern_(image, repetition);\n  };\n\n  // Gradient / Pattern Stubs\n  function CanvasGradient_(aType) {\n    this.type_ = aType;\n    this.x0_ = 0;\n    this.y0_ = 0;\n    this.r0_ = 0;\n    this.x1_ = 0;\n    this.y1_ = 0;\n    this.r1_ = 0;\n    this.colors_ = [];\n  }\n\n  CanvasGradient_.prototype.addColorStop = function(aOffset, aColor) {\n    aColor = processStyle(aColor);\n    this.colors_.push({offset: aOffset,\n                       color: aColor.color,\n                       alpha: aColor.alpha});\n  };\n\n  function CanvasPattern_(image, repetition) {\n    assertImageIsValid(image);\n    switch (repetition) {\n      case 'repeat':\n      case null:\n      case '':\n        this.repetition_ = 'repeat';\n        break\n      case 'repeat-x':\n      case 'repeat-y':\n      case 'no-repeat':\n        this.repetition_ = repetition;\n        break;\n      default:\n        throwException('SYNTAX_ERR');\n    }\n\n    this.src_ = image.src;\n    this.width_ = image.width;\n    this.height_ = image.height;\n  }\n\n  function throwException(s) {\n    throw new DOMException_(s);\n  }\n\n  function assertImageIsValid(img) {\n    if (!img || img.nodeType != 1 || img.tagName != 'IMG') {\n      throwException('TYPE_MISMATCH_ERR');\n    }\n    if (img.readyState != 'complete') {\n      throwException('INVALID_STATE_ERR');\n    }\n  }\n\n  function DOMException_(s) {\n    this.code = this[s];\n    this.message = s +': DOM Exception ' + this.code;\n  }\n  var p = DOMException_.prototype = new Error;\n  p.INDEX_SIZE_ERR = 1;\n  p.DOMSTRING_SIZE_ERR = 2;\n  p.HIERARCHY_REQUEST_ERR = 3;\n  p.WRONG_DOCUMENT_ERR = 4;\n  p.INVALID_CHARACTER_ERR = 5;\n  p.NO_DATA_ALLOWED_ERR = 6;\n  p.NO_MODIFICATION_ALLOWED_ERR = 7;\n  p.NOT_FOUND_ERR = 8;\n  p.NOT_SUPPORTED_ERR = 9;\n  p.INUSE_ATTRIBUTE_ERR = 10;\n  p.INVALID_STATE_ERR = 11;\n  p.SYNTAX_ERR = 12;\n  p.INVALID_MODIFICATION_ERR = 13;\n  p.NAMESPACE_ERR = 14;\n  p.INVALID_ACCESS_ERR = 15;\n  p.VALIDATION_ERR = 16;\n  p.TYPE_MISMATCH_ERR = 17;\n\n  // set up externs\n  G_vmlCanvasManager = G_vmlCanvasManager_;\n  CanvasRenderingContext2D = CanvasRenderingContext2D_;\n  CanvasGradient = CanvasGradient_;\n  CanvasPattern = CanvasPattern_;\n  DOMException = DOMException_;\n})();\n\n} // if\n"
  },
  {
    "path": "app_backend/vendor/flot/jquery.colorhelpers.js",
    "content": "/* Plugin for jQuery for working with colors.\n * \n * Version 1.1.\n * \n * Inspiration from jQuery color animation plugin by John Resig.\n *\n * Released under the MIT license by Ole Laursen, October 2009.\n *\n * Examples:\n *\n *   $.color.parse(\"#fff\").scale('rgb', 0.25).add('a', -0.5).toString()\n *   var c = $.color.extract($(\"#mydiv\"), 'background-color');\n *   console.log(c.r, c.g, c.b, c.a);\n *   $.color.make(100, 50, 25, 0.4).toString() // returns \"rgba(100,50,25,0.4)\"\n *\n * Note that .scale() and .add() return the same modified object\n * instead of making a new one.\n *\n * V. 1.1: Fix error handling so e.g. parsing an empty string does\n * produce a color rather than just crashing.\n */ \n\n(function($) {\n    $.color = {};\n\n    // construct color object with some convenient chainable helpers\n    $.color.make = function (r, g, b, a) {\n        var o = {};\n        o.r = r || 0;\n        o.g = g || 0;\n        o.b = b || 0;\n        o.a = a != null ? a : 1;\n\n        o.add = function (c, d) {\n            for (var i = 0; i < c.length; ++i)\n                o[c.charAt(i)] += d;\n            return o.normalize();\n        };\n        \n        o.scale = function (c, f) {\n            for (var i = 0; i < c.length; ++i)\n                o[c.charAt(i)] *= f;\n            return o.normalize();\n        };\n        \n        o.toString = function () {\n            if (o.a >= 1.0) {\n                return \"rgb(\"+[o.r, o.g, o.b].join(\",\")+\")\";\n            } else {\n                return \"rgba(\"+[o.r, o.g, o.b, o.a].join(\",\")+\")\";\n            }\n        };\n\n        o.normalize = function () {\n            function clamp(min, value, max) {\n                return value < min ? min: (value > max ? max: value);\n            }\n            \n            o.r = clamp(0, parseInt(o.r), 255);\n            o.g = clamp(0, parseInt(o.g), 255);\n            o.b = clamp(0, parseInt(o.b), 255);\n            o.a = clamp(0, o.a, 1);\n            return o;\n        };\n\n        o.clone = function () {\n            return $.color.make(o.r, o.b, o.g, o.a);\n        };\n\n        return o.normalize();\n    }\n\n    // extract CSS color property from element, going up in the DOM\n    // if it's \"transparent\"\n    $.color.extract = function (elem, css) {\n        var c;\n\n        do {\n            c = elem.css(css).toLowerCase();\n            // keep going until we find an element that has color, or\n            // we hit the body or root (have no parent)\n            if (c != '' && c != 'transparent')\n                break;\n            elem = elem.parent();\n        } while (elem.length && !$.nodeName(elem.get(0), \"body\"));\n\n        // catch Safari's way of signalling transparent\n        if (c == \"rgba(0, 0, 0, 0)\")\n            c = \"transparent\";\n        \n        return $.color.parse(c);\n    }\n    \n    // parse CSS color string (like \"rgb(10, 32, 43)\" or \"#fff\"),\n    // returns color object, if parsing failed, you get black (0, 0,\n    // 0) out\n    $.color.parse = function (str) {\n        var res, m = $.color.make;\n\n        // Look for rgb(num,num,num)\n        if (res = /rgb\\(\\s*([0-9]{1,3})\\s*,\\s*([0-9]{1,3})\\s*,\\s*([0-9]{1,3})\\s*\\)/.exec(str))\n            return m(parseInt(res[1], 10), parseInt(res[2], 10), parseInt(res[3], 10));\n        \n        // Look for rgba(num,num,num,num)\n        if (res = /rgba\\(\\s*([0-9]{1,3})\\s*,\\s*([0-9]{1,3})\\s*,\\s*([0-9]{1,3})\\s*,\\s*([0-9]+(?:\\.[0-9]+)?)\\s*\\)/.exec(str))\n            return m(parseInt(res[1], 10), parseInt(res[2], 10), parseInt(res[3], 10), parseFloat(res[4]));\n            \n        // Look for rgb(num%,num%,num%)\n        if (res = /rgb\\(\\s*([0-9]+(?:\\.[0-9]+)?)\\%\\s*,\\s*([0-9]+(?:\\.[0-9]+)?)\\%\\s*,\\s*([0-9]+(?:\\.[0-9]+)?)\\%\\s*\\)/.exec(str))\n            return m(parseFloat(res[1])*2.55, parseFloat(res[2])*2.55, parseFloat(res[3])*2.55);\n\n        // Look for rgba(num%,num%,num%,num)\n        if (res = /rgba\\(\\s*([0-9]+(?:\\.[0-9]+)?)\\%\\s*,\\s*([0-9]+(?:\\.[0-9]+)?)\\%\\s*,\\s*([0-9]+(?:\\.[0-9]+)?)\\%\\s*,\\s*([0-9]+(?:\\.[0-9]+)?)\\s*\\)/.exec(str))\n            return m(parseFloat(res[1])*2.55, parseFloat(res[2])*2.55, parseFloat(res[3])*2.55, parseFloat(res[4]));\n        \n        // Look for #a0b1c2\n        if (res = /#([a-fA-F0-9]{2})([a-fA-F0-9]{2})([a-fA-F0-9]{2})/.exec(str))\n            return m(parseInt(res[1], 16), parseInt(res[2], 16), parseInt(res[3], 16));\n\n        // Look for #fff\n        if (res = /#([a-fA-F0-9])([a-fA-F0-9])([a-fA-F0-9])/.exec(str))\n            return m(parseInt(res[1]+res[1], 16), parseInt(res[2]+res[2], 16), parseInt(res[3]+res[3], 16));\n\n        // Otherwise, we're most likely dealing with a named color\n        var name = $.trim(str).toLowerCase();\n        if (name == \"transparent\")\n            return m(255, 255, 255, 0);\n        else {\n            // default to black\n            res = lookupColors[name] || [0, 0, 0];\n            return m(res[0], res[1], res[2]);\n        }\n    }\n    \n    var lookupColors = {\n        aqua:[0,255,255],\n        azure:[240,255,255],\n        beige:[245,245,220],\n        black:[0,0,0],\n        blue:[0,0,255],\n        brown:[165,42,42],\n        cyan:[0,255,255],\n        darkblue:[0,0,139],\n        darkcyan:[0,139,139],\n        darkgrey:[169,169,169],\n        darkgreen:[0,100,0],\n        darkkhaki:[189,183,107],\n        darkmagenta:[139,0,139],\n        darkolivegreen:[85,107,47],\n        darkorange:[255,140,0],\n        darkorchid:[153,50,204],\n        darkred:[139,0,0],\n        darksalmon:[233,150,122],\n        darkviolet:[148,0,211],\n        fuchsia:[255,0,255],\n        gold:[255,215,0],\n        green:[0,128,0],\n        indigo:[75,0,130],\n        khaki:[240,230,140],\n        lightblue:[173,216,230],\n        lightcyan:[224,255,255],\n        lightgreen:[144,238,144],\n        lightgrey:[211,211,211],\n        lightpink:[255,182,193],\n        lightyellow:[255,255,224],\n        lime:[0,255,0],\n        magenta:[255,0,255],\n        maroon:[128,0,0],\n        navy:[0,0,128],\n        olive:[128,128,0],\n        orange:[255,165,0],\n        pink:[255,192,203],\n        purple:[128,0,128],\n        violet:[128,0,128],\n        red:[255,0,0],\n        silver:[192,192,192],\n        white:[255,255,255],\n        yellow:[255,255,0]\n    };\n})(jQuery);\n"
  },
  {
    "path": "app_backend/vendor/flot/jquery.flot.canvas.js",
    "content": "/* Flot plugin for drawing all elements of a plot on the canvas.\n\nCopyright (c) 2007-2014 IOLA and Ole Laursen.\nLicensed under the MIT license.\n\nFlot normally produces certain elements, like axis labels and the legend, using\nHTML elements. This permits greater interactivity and customization, and often\nlooks better, due to cross-browser canvas text inconsistencies and limitations.\n\nIt can also be desirable to render the plot entirely in canvas, particularly\nif the goal is to save it as an image, or if Flot is being used in a context\nwhere the HTML DOM does not exist, as is the case within Node.js. This plugin\nswitches out Flot's standard drawing operations for canvas-only replacements.\n\nCurrently the plugin supports only axis labels, but it will eventually allow\nevery element of the plot to be rendered directly to canvas.\n\nThe plugin supports these options:\n\n{\n    canvas: boolean\n}\n\nThe \"canvas\" option controls whether full canvas drawing is enabled, making it\npossible to toggle on and off. This is useful when a plot uses HTML text in the\nbrowser, but needs to redraw with canvas text when exporting as an image.\n\n*/\n\n(function($) {\n\n\tvar options = {\n\t\tcanvas: true\n\t};\n\n\tvar render, getTextInfo, addText;\n\n\t// Cache the prototype hasOwnProperty for faster access\n\n\tvar hasOwnProperty = Object.prototype.hasOwnProperty;\n\n\tfunction init(plot, classes) {\n\n\t\tvar Canvas = classes.Canvas;\n\n\t\t// We only want to replace the functions once; the second time around\n\t\t// we would just get our new function back.  This whole replacing of\n\t\t// prototype functions is a disaster, and needs to be changed ASAP.\n\n\t\tif (render == null) {\n\t\t\tgetTextInfo = Canvas.prototype.getTextInfo,\n\t\t\taddText = Canvas.prototype.addText,\n\t\t\trender = Canvas.prototype.render;\n\t\t}\n\n\t\t// Finishes rendering the canvas, including overlaid text\n\n\t\tCanvas.prototype.render = function() {\n\n\t\t\tif (!plot.getOptions().canvas) {\n\t\t\t\treturn render.call(this);\n\t\t\t}\n\n\t\t\tvar context = this.context,\n\t\t\t\tcache = this._textCache;\n\n\t\t\t// For each text layer, render elements marked as active\n\n\t\t\tcontext.save();\n\t\t\tcontext.textBaseline = \"middle\";\n\n\t\t\tfor (var layerKey in cache) {\n\t\t\t\tif (hasOwnProperty.call(cache, layerKey)) {\n\t\t\t\t\tvar layerCache = cache[layerKey];\n\t\t\t\t\tfor (var styleKey in layerCache) {\n\t\t\t\t\t\tif (hasOwnProperty.call(layerCache, styleKey)) {\n\t\t\t\t\t\t\tvar styleCache = layerCache[styleKey],\n\t\t\t\t\t\t\t\tupdateStyles = true;\n\t\t\t\t\t\t\tfor (var key in styleCache) {\n\t\t\t\t\t\t\t\tif (hasOwnProperty.call(styleCache, key)) {\n\n\t\t\t\t\t\t\t\t\tvar info = styleCache[key],\n\t\t\t\t\t\t\t\t\t\tpositions = info.positions,\n\t\t\t\t\t\t\t\t\t\tlines = info.lines;\n\n\t\t\t\t\t\t\t\t\t// Since every element at this level of the cache have the\n\t\t\t\t\t\t\t\t\t// same font and fill styles, we can just change them once\n\t\t\t\t\t\t\t\t\t// using the values from the first element.\n\n\t\t\t\t\t\t\t\t\tif (updateStyles) {\n\t\t\t\t\t\t\t\t\t\tcontext.fillStyle = info.font.color;\n\t\t\t\t\t\t\t\t\t\tcontext.font = info.font.definition;\n\t\t\t\t\t\t\t\t\t\tupdateStyles = false;\n\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t\tfor (var i = 0, position; position = positions[i]; i++) {\n\t\t\t\t\t\t\t\t\t\tif (position.active) {\n\t\t\t\t\t\t\t\t\t\t\tfor (var j = 0, line; line = position.lines[j]; j++) {\n\t\t\t\t\t\t\t\t\t\t\t\tcontext.fillText(lines[j].text, line[0], line[1]);\n\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\t\t\tpositions.splice(i--, 1);\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t\tif (positions.length == 0) {\n\t\t\t\t\t\t\t\t\t\tdelete styleCache[key];\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tcontext.restore();\n\t\t};\n\n\t\t// Creates (if necessary) and returns a text info object.\n\t\t//\n\t\t// When the canvas option is set, the object looks like this:\n\t\t//\n\t\t// {\n\t\t//     width: Width of the text's bounding box.\n\t\t//     height: Height of the text's bounding box.\n\t\t//     positions: Array of positions at which this text is drawn.\n\t\t//     lines: [{\n\t\t//         height: Height of this line.\n\t\t//         widths: Width of this line.\n\t\t//         text: Text on this line.\n\t\t//     }],\n\t\t//     font: {\n\t\t//         definition: Canvas font property string.\n\t\t//         color: Color of the text.\n\t\t//     },\n\t\t// }\n\t\t//\n\t\t// The positions array contains objects that look like this:\n\t\t//\n\t\t// {\n\t\t//     active: Flag indicating whether the text should be visible.\n\t\t//     lines: Array of [x, y] coordinates at which to draw the line.\n\t\t//     x: X coordinate at which to draw the text.\n\t\t//     y: Y coordinate at which to draw the text.\n\t\t// }\n\n\t\tCanvas.prototype.getTextInfo = function(layer, text, font, angle, width) {\n\n\t\t\tif (!plot.getOptions().canvas) {\n\t\t\t\treturn getTextInfo.call(this, layer, text, font, angle, width);\n\t\t\t}\n\n\t\t\tvar textStyle, layerCache, styleCache, info;\n\n\t\t\t// Cast the value to a string, in case we were given a number\n\n\t\t\ttext = \"\" + text;\n\n\t\t\t// If the font is a font-spec object, generate a CSS definition\n\n\t\t\tif (typeof font === \"object\") {\n\t\t\t\ttextStyle = font.style + \" \" + font.variant + \" \" + font.weight + \" \" + font.size + \"px \" + font.family;\n\t\t\t} else {\n\t\t\t\ttextStyle = font;\n\t\t\t}\n\n\t\t\t// Retrieve (or create) the cache for the text's layer and styles\n\n\t\t\tlayerCache = this._textCache[layer];\n\n\t\t\tif (layerCache == null) {\n\t\t\t\tlayerCache = this._textCache[layer] = {};\n\t\t\t}\n\n\t\t\tstyleCache = layerCache[textStyle];\n\n\t\t\tif (styleCache == null) {\n\t\t\t\tstyleCache = layerCache[textStyle] = {};\n\t\t\t}\n\n\t\t\tinfo = styleCache[text];\n\n\t\t\tif (info == null) {\n\n\t\t\t\tvar context = this.context;\n\n\t\t\t\t// If the font was provided as CSS, create a div with those\n\t\t\t\t// classes and examine it to generate a canvas font spec.\n\n\t\t\t\tif (typeof font !== \"object\") {\n\n\t\t\t\t\tvar element = $(\"<div>&nbsp;</div>\")\n\t\t\t\t\t\t.css(\"position\", \"absolute\")\n\t\t\t\t\t\t.addClass(typeof font === \"string\" ? font : null)\n\t\t\t\t\t\t.appendTo(this.getTextLayer(layer));\n\n\t\t\t\t\tfont = {\n\t\t\t\t\t\tlineHeight: element.height(),\n\t\t\t\t\t\tstyle: element.css(\"font-style\"),\n\t\t\t\t\t\tvariant: element.css(\"font-variant\"),\n\t\t\t\t\t\tweight: element.css(\"font-weight\"),\n\t\t\t\t\t\tfamily: element.css(\"font-family\"),\n\t\t\t\t\t\tcolor: element.css(\"color\")\n\t\t\t\t\t};\n\n\t\t\t\t\t// Setting line-height to 1, without units, sets it equal\n\t\t\t\t\t// to the font-size, even if the font-size is abstract,\n\t\t\t\t\t// like 'smaller'.  This enables us to read the real size\n\t\t\t\t\t// via the element's height, working around browsers that\n\t\t\t\t\t// return the literal 'smaller' value.\n\n\t\t\t\t\tfont.size = element.css(\"line-height\", 1).height();\n\n\t\t\t\t\telement.remove();\n\t\t\t\t}\n\n\t\t\t\ttextStyle = font.style + \" \" + font.variant + \" \" + font.weight + \" \" + font.size + \"px \" + font.family;\n\n\t\t\t\t// Create a new info object, initializing the dimensions to\n\t\t\t\t// zero so we can count them up line-by-line.\n\n\t\t\t\tinfo = styleCache[text] = {\n\t\t\t\t\twidth: 0,\n\t\t\t\t\theight: 0,\n\t\t\t\t\tpositions: [],\n\t\t\t\t\tlines: [],\n\t\t\t\t\tfont: {\n\t\t\t\t\t\tdefinition: textStyle,\n\t\t\t\t\t\tcolor: font.color\n\t\t\t\t\t}\n\t\t\t\t};\n\n\t\t\t\tcontext.save();\n\t\t\t\tcontext.font = textStyle;\n\n\t\t\t\t// Canvas can't handle multi-line strings; break on various\n\t\t\t\t// newlines, including HTML brs, to build a list of lines.\n\t\t\t\t// Note that we could split directly on regexps, but IE < 9 is\n\t\t\t\t// broken; revisit when we drop IE 7/8 support.\n\n\t\t\t\tvar lines = (text + \"\").replace(/<br ?\\/?>|\\r\\n|\\r/g, \"\\n\").split(\"\\n\");\n\n\t\t\t\tfor (var i = 0; i < lines.length; ++i) {\n\n\t\t\t\t\tvar lineText = lines[i],\n\t\t\t\t\t\tmeasured = context.measureText(lineText);\n\n\t\t\t\t\tinfo.width = Math.max(measured.width, info.width);\n\t\t\t\t\tinfo.height += font.lineHeight;\n\n\t\t\t\t\tinfo.lines.push({\n\t\t\t\t\t\ttext: lineText,\n\t\t\t\t\t\twidth: measured.width,\n\t\t\t\t\t\theight: font.lineHeight\n\t\t\t\t\t});\n\t\t\t\t}\n\n\t\t\t\tcontext.restore();\n\t\t\t}\n\n\t\t\treturn info;\n\t\t};\n\n\t\t// Adds a text string to the canvas text overlay.\n\n\t\tCanvas.prototype.addText = function(layer, x, y, text, font, angle, width, halign, valign) {\n\n\t\t\tif (!plot.getOptions().canvas) {\n\t\t\t\treturn addText.call(this, layer, x, y, text, font, angle, width, halign, valign);\n\t\t\t}\n\n\t\t\tvar info = this.getTextInfo(layer, text, font, angle, width),\n\t\t\t\tpositions = info.positions,\n\t\t\t\tlines = info.lines;\n\n\t\t\t// Text is drawn with baseline 'middle', which we need to account\n\t\t\t// for by adding half a line's height to the y position.\n\n\t\t\ty += info.height / lines.length / 2;\n\n\t\t\t// Tweak the initial y-position to match vertical alignment\n\n\t\t\tif (valign == \"middle\") {\n\t\t\t\ty = Math.round(y - info.height / 2);\n\t\t\t} else if (valign == \"bottom\") {\n\t\t\t\ty = Math.round(y - info.height);\n\t\t\t} else {\n\t\t\t\ty = Math.round(y);\n\t\t\t}\n\n\t\t\t// FIXME: LEGACY BROWSER FIX\n\t\t\t// AFFECTS: Opera < 12.00\n\n\t\t\t// Offset the y coordinate, since Opera is off pretty\n\t\t\t// consistently compared to the other browsers.\n\n\t\t\tif (!!(window.opera && window.opera.version().split(\".\")[0] < 12)) {\n\t\t\t\ty -= 2;\n\t\t\t}\n\n\t\t\t// Determine whether this text already exists at this position.\n\t\t\t// If so, mark it for inclusion in the next render pass.\n\n\t\t\tfor (var i = 0, position; position = positions[i]; i++) {\n\t\t\t\tif (position.x == x && position.y == y) {\n\t\t\t\t\tposition.active = true;\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// If the text doesn't exist at this position, create a new entry\n\n\t\t\tposition = {\n\t\t\t\tactive: true,\n\t\t\t\tlines: [],\n\t\t\t\tx: x,\n\t\t\t\ty: y\n\t\t\t};\n\n\t\t\tpositions.push(position);\n\n\t\t\t// Fill in the x & y positions of each line, adjusting them\n\t\t\t// individually for horizontal alignment.\n\n\t\t\tfor (var i = 0, line; line = lines[i]; i++) {\n\t\t\t\tif (halign == \"center\") {\n\t\t\t\t\tposition.lines.push([Math.round(x - line.width / 2), y]);\n\t\t\t\t} else if (halign == \"right\") {\n\t\t\t\t\tposition.lines.push([Math.round(x - line.width), y]);\n\t\t\t\t} else {\n\t\t\t\t\tposition.lines.push([Math.round(x), y]);\n\t\t\t\t}\n\t\t\t\ty += line.height;\n\t\t\t}\n\t\t};\n\t}\n\n\t$.plot.plugins.push({\n\t\tinit: init,\n\t\toptions: options,\n\t\tname: \"canvas\",\n\t\tversion: \"1.0\"\n\t});\n\n})(jQuery);\n"
  },
  {
    "path": "app_backend/vendor/flot/jquery.flot.categories.js",
    "content": "/* Flot plugin for plotting textual data or categories.\n\nCopyright (c) 2007-2014 IOLA and Ole Laursen.\nLicensed under the MIT license.\n\nConsider a dataset like [[\"February\", 34], [\"March\", 20], ...]. This plugin\nallows you to plot such a dataset directly.\n\nTo enable it, you must specify mode: \"categories\" on the axis with the textual\nlabels, e.g.\n\n\t$.plot(\"#placeholder\", data, { xaxis: { mode: \"categories\" } });\n\nBy default, the labels are ordered as they are met in the data series. If you\nneed a different ordering, you can specify \"categories\" on the axis options\nand list the categories there:\n\n\txaxis: {\n\t\tmode: \"categories\",\n\t\tcategories: [\"February\", \"March\", \"April\"]\n\t}\n\nIf you need to customize the distances between the categories, you can specify\n\"categories\" as an object mapping labels to values\n\n\txaxis: {\n\t\tmode: \"categories\",\n\t\tcategories: { \"February\": 1, \"March\": 3, \"April\": 4 }\n\t}\n\nIf you don't specify all categories, the remaining categories will be numbered\nfrom the max value plus 1 (with a spacing of 1 between each).\n\nInternally, the plugin works by transforming the input data through an auto-\ngenerated mapping where the first category becomes 0, the second 1, etc.\nHence, a point like [\"February\", 34] becomes [0, 34] internally in Flot (this\nis visible in hover and click events that return numbers rather than the\ncategory labels). The plugin also overrides the tick generator to spit out the\ncategories as ticks instead of the values.\n\nIf you need to map a value back to its label, the mapping is always accessible\nas \"categories\" on the axis object, e.g. plot.getAxes().xaxis.categories.\n\n*/\n\n(function ($) {\n    var options = {\n        xaxis: {\n            categories: null\n        },\n        yaxis: {\n            categories: null\n        }\n    };\n    \n    function processRawData(plot, series, data, datapoints) {\n        // if categories are enabled, we need to disable\n        // auto-transformation to numbers so the strings are intact\n        // for later processing\n\n        var xCategories = series.xaxis.options.mode == \"categories\",\n            yCategories = series.yaxis.options.mode == \"categories\";\n        \n        if (!(xCategories || yCategories))\n            return;\n\n        var format = datapoints.format;\n\n        if (!format) {\n            // FIXME: auto-detection should really not be defined here\n            var s = series;\n            format = [];\n            format.push({ x: true, number: true, required: true });\n            format.push({ y: true, number: true, required: true });\n\n            if (s.bars.show || (s.lines.show && s.lines.fill)) {\n                var autoscale = !!((s.bars.show && s.bars.zero) || (s.lines.show && s.lines.zero));\n                format.push({ y: true, number: true, required: false, defaultValue: 0, autoscale: autoscale });\n                if (s.bars.horizontal) {\n                    delete format[format.length - 1].y;\n                    format[format.length - 1].x = true;\n                }\n            }\n            \n            datapoints.format = format;\n        }\n\n        for (var m = 0; m < format.length; ++m) {\n            if (format[m].x && xCategories)\n                format[m].number = false;\n            \n            if (format[m].y && yCategories)\n                format[m].number = false;\n        }\n    }\n\n    function getNextIndex(categories) {\n        var index = -1;\n        \n        for (var v in categories)\n            if (categories[v] > index)\n                index = categories[v];\n\n        return index + 1;\n    }\n\n    function categoriesTickGenerator(axis) {\n        var res = [];\n        for (var label in axis.categories) {\n            var v = axis.categories[label];\n            if (v >= axis.min && v <= axis.max)\n                res.push([v, label]);\n        }\n\n        res.sort(function (a, b) { return a[0] - b[0]; });\n\n        return res;\n    }\n    \n    function setupCategoriesForAxis(series, axis, datapoints) {\n        if (series[axis].options.mode != \"categories\")\n            return;\n        \n        if (!series[axis].categories) {\n            // parse options\n            var c = {}, o = series[axis].options.categories || {};\n            if ($.isArray(o)) {\n                for (var i = 0; i < o.length; ++i)\n                    c[o[i]] = i;\n            }\n            else {\n                for (var v in o)\n                    c[v] = o[v];\n            }\n            \n            series[axis].categories = c;\n        }\n\n        // fix ticks\n        if (!series[axis].options.ticks)\n            series[axis].options.ticks = categoriesTickGenerator;\n\n        transformPointsOnAxis(datapoints, axis, series[axis].categories);\n    }\n    \n    function transformPointsOnAxis(datapoints, axis, categories) {\n        // go through the points, transforming them\n        var points = datapoints.points,\n            ps = datapoints.pointsize,\n            format = datapoints.format,\n            formatColumn = axis.charAt(0),\n            index = getNextIndex(categories);\n\n        for (var i = 0; i < points.length; i += ps) {\n            if (points[i] == null)\n                continue;\n            \n            for (var m = 0; m < ps; ++m) {\n                var val = points[i + m];\n\n                if (val == null || !format[m][formatColumn])\n                    continue;\n\n                if (!(val in categories)) {\n                    categories[val] = index;\n                    ++index;\n                }\n                \n                points[i + m] = categories[val];\n            }\n        }\n    }\n\n    function processDatapoints(plot, series, datapoints) {\n        setupCategoriesForAxis(series, \"xaxis\", datapoints);\n        setupCategoriesForAxis(series, \"yaxis\", datapoints);\n    }\n\n    function init(plot) {\n        plot.hooks.processRawData.push(processRawData);\n        plot.hooks.processDatapoints.push(processDatapoints);\n    }\n    \n    $.plot.plugins.push({\n        init: init,\n        options: options,\n        name: 'categories',\n        version: '1.0'\n    });\n})(jQuery);\n"
  },
  {
    "path": "app_backend/vendor/flot/jquery.flot.crosshair.js",
    "content": "/* Flot plugin for showing crosshairs when the mouse hovers over the plot.\n\nCopyright (c) 2007-2014 IOLA and Ole Laursen.\nLicensed under the MIT license.\n\nThe plugin supports these options:\n\n\tcrosshair: {\n\t\tmode: null or \"x\" or \"y\" or \"xy\"\n\t\tcolor: color\n\t\tlineWidth: number\n\t}\n\nSet the mode to one of \"x\", \"y\" or \"xy\". The \"x\" mode enables a vertical\ncrosshair that lets you trace the values on the x axis, \"y\" enables a\nhorizontal crosshair and \"xy\" enables them both. \"color\" is the color of the\ncrosshair (default is \"rgba(170, 0, 0, 0.80)\"), \"lineWidth\" is the width of\nthe drawn lines (default is 1).\n\nThe plugin also adds four public methods:\n\n  - setCrosshair( pos )\n\n    Set the position of the crosshair. Note that this is cleared if the user\n    moves the mouse. \"pos\" is in coordinates of the plot and should be on the\n    form { x: xpos, y: ypos } (you can use x2/x3/... if you're using multiple\n    axes), which is coincidentally the same format as what you get from a\n    \"plothover\" event. If \"pos\" is null, the crosshair is cleared.\n\n  - clearCrosshair()\n\n    Clear the crosshair.\n\n  - lockCrosshair(pos)\n\n    Cause the crosshair to lock to the current location, no longer updating if\n    the user moves the mouse. Optionally supply a position (passed on to\n    setCrosshair()) to move it to.\n\n    Example usage:\n\n\tvar myFlot = $.plot( $(\"#graph\"), ..., { crosshair: { mode: \"x\" } } };\n\t$(\"#graph\").bind( \"plothover\", function ( evt, position, item ) {\n\t\tif ( item ) {\n\t\t\t// Lock the crosshair to the data point being hovered\n\t\t\tmyFlot.lockCrosshair({\n\t\t\t\tx: item.datapoint[ 0 ],\n\t\t\t\ty: item.datapoint[ 1 ]\n\t\t\t});\n\t\t} else {\n\t\t\t// Return normal crosshair operation\n\t\t\tmyFlot.unlockCrosshair();\n\t\t}\n\t});\n\n  - unlockCrosshair()\n\n    Free the crosshair to move again after locking it.\n*/\n\n(function ($) {\n    var options = {\n        crosshair: {\n            mode: null, // one of null, \"x\", \"y\" or \"xy\",\n            color: \"rgba(170, 0, 0, 0.80)\",\n            lineWidth: 1\n        }\n    };\n    \n    function init(plot) {\n        // position of crosshair in pixels\n        var crosshair = { x: -1, y: -1, locked: false };\n\n        plot.setCrosshair = function setCrosshair(pos) {\n            if (!pos)\n                crosshair.x = -1;\n            else {\n                var o = plot.p2c(pos);\n                crosshair.x = Math.max(0, Math.min(o.left, plot.width()));\n                crosshair.y = Math.max(0, Math.min(o.top, plot.height()));\n            }\n            \n            plot.triggerRedrawOverlay();\n        };\n        \n        plot.clearCrosshair = plot.setCrosshair; // passes null for pos\n        \n        plot.lockCrosshair = function lockCrosshair(pos) {\n            if (pos)\n                plot.setCrosshair(pos);\n            crosshair.locked = true;\n        };\n\n        plot.unlockCrosshair = function unlockCrosshair() {\n            crosshair.locked = false;\n        };\n\n        function onMouseOut(e) {\n            if (crosshair.locked)\n                return;\n\n            if (crosshair.x != -1) {\n                crosshair.x = -1;\n                plot.triggerRedrawOverlay();\n            }\n        }\n\n        function onMouseMove(e) {\n            if (crosshair.locked)\n                return;\n                \n            if (plot.getSelection && plot.getSelection()) {\n                crosshair.x = -1; // hide the crosshair while selecting\n                return;\n            }\n                \n            var offset = plot.offset();\n            crosshair.x = Math.max(0, Math.min(e.pageX - offset.left, plot.width()));\n            crosshair.y = Math.max(0, Math.min(e.pageY - offset.top, plot.height()));\n            plot.triggerRedrawOverlay();\n        }\n        \n        plot.hooks.bindEvents.push(function (plot, eventHolder) {\n            if (!plot.getOptions().crosshair.mode)\n                return;\n\n            eventHolder.mouseout(onMouseOut);\n            eventHolder.mousemove(onMouseMove);\n        });\n\n        plot.hooks.drawOverlay.push(function (plot, ctx) {\n            var c = plot.getOptions().crosshair;\n            if (!c.mode)\n                return;\n\n            var plotOffset = plot.getPlotOffset();\n            \n            ctx.save();\n            ctx.translate(plotOffset.left, plotOffset.top);\n\n            if (crosshair.x != -1) {\n                var adj = plot.getOptions().crosshair.lineWidth % 2 ? 0.5 : 0;\n\n                ctx.strokeStyle = c.color;\n                ctx.lineWidth = c.lineWidth;\n                ctx.lineJoin = \"round\";\n\n                ctx.beginPath();\n                if (c.mode.indexOf(\"x\") != -1) {\n                    var drawX = Math.floor(crosshair.x) + adj;\n                    ctx.moveTo(drawX, 0);\n                    ctx.lineTo(drawX, plot.height());\n                }\n                if (c.mode.indexOf(\"y\") != -1) {\n                    var drawY = Math.floor(crosshair.y) + adj;\n                    ctx.moveTo(0, drawY);\n                    ctx.lineTo(plot.width(), drawY);\n                }\n                ctx.stroke();\n            }\n            ctx.restore();\n        });\n\n        plot.hooks.shutdown.push(function (plot, eventHolder) {\n            eventHolder.unbind(\"mouseout\", onMouseOut);\n            eventHolder.unbind(\"mousemove\", onMouseMove);\n        });\n    }\n    \n    $.plot.plugins.push({\n        init: init,\n        options: options,\n        name: 'crosshair',\n        version: '1.0'\n    });\n})(jQuery);\n"
  },
  {
    "path": "app_backend/vendor/flot/jquery.flot.errorbars.js",
    "content": "/* Flot plugin for plotting error bars.\n\nCopyright (c) 2007-2014 IOLA and Ole Laursen.\nLicensed under the MIT license.\n\nError bars are used to show standard deviation and other statistical\nproperties in a plot.\n\n* Created by Rui Pereira  -  rui (dot) pereira (at) gmail (dot) com\n\nThis plugin allows you to plot error-bars over points. Set \"errorbars\" inside\nthe points series to the axis name over which there will be error values in\nyour data array (*even* if you do not intend to plot them later, by setting\n\"show: null\" on xerr/yerr).\n\nThe plugin supports these options:\n\n\tseries: {\n\t\tpoints: {\n\t\t\terrorbars: \"x\" or \"y\" or \"xy\",\n\t\t\txerr: {\n\t\t\t\tshow: null/false or true,\n\t\t\t\tasymmetric: null/false or true,\n\t\t\t\tupperCap: null or \"-\" or function,\n\t\t\t\tlowerCap: null or \"-\" or function,\n\t\t\t\tcolor: null or color,\n\t\t\t\tradius: null or number\n\t\t\t},\n\t\t\tyerr: { same options as xerr }\n\t\t}\n\t}\n\nEach data point array is expected to be of the type:\n\n\t\"x\"  [ x, y, xerr ]\n\t\"y\"  [ x, y, yerr ]\n\t\"xy\" [ x, y, xerr, yerr ]\n\nWhere xerr becomes xerr_lower,xerr_upper for the asymmetric error case, and\nequivalently for yerr. Eg., a datapoint for the \"xy\" case with symmetric\nerror-bars on X and asymmetric on Y would be:\n\n\t[ x, y, xerr, yerr_lower, yerr_upper ]\n\nBy default no end caps are drawn. Setting upperCap and/or lowerCap to \"-\" will\ndraw a small cap perpendicular to the error bar. They can also be set to a\nuser-defined drawing function, with (ctx, x, y, radius) as parameters, as eg.\n\n\tfunction drawSemiCircle( ctx, x, y, radius ) {\n\t\tctx.beginPath();\n\t\tctx.arc( x, y, radius, 0, Math.PI, false );\n\t\tctx.moveTo( x - radius, y );\n\t\tctx.lineTo( x + radius, y );\n\t\tctx.stroke();\n\t}\n\nColor and radius both default to the same ones of the points series if not\nset. The independent radius parameter on xerr/yerr is useful for the case when\nwe may want to add error-bars to a line, without showing the interconnecting\npoints (with radius: 0), and still showing end caps on the error-bars.\nshadowSize and lineWidth are derived as well from the points series.\n\n*/\n\n(function ($) {\n    var options = {\n        series: {\n            points: {\n                errorbars: null, //should be 'x', 'y' or 'xy'\n                xerr: { err: 'x', show: null, asymmetric: null, upperCap: null, lowerCap: null, color: null, radius: null},\n                yerr: { err: 'y', show: null, asymmetric: null, upperCap: null, lowerCap: null, color: null, radius: null}\n            }\n        }\n    };\n\n    function processRawData(plot, series, data, datapoints){\n        if (!series.points.errorbars)\n            return;\n\n        // x,y values\n        var format = [\n            { x: true, number: true, required: true },\n            { y: true, number: true, required: true }\n        ];\n\n        var errors = series.points.errorbars;\n        // error bars - first X then Y\n        if (errors == 'x' || errors == 'xy') {\n            // lower / upper error\n            if (series.points.xerr.asymmetric) {\n                format.push({ x: true, number: true, required: true });\n                format.push({ x: true, number: true, required: true });\n            } else\n                format.push({ x: true, number: true, required: true });\n        }\n        if (errors == 'y' || errors == 'xy') {\n            // lower / upper error\n            if (series.points.yerr.asymmetric) {\n                format.push({ y: true, number: true, required: true });\n                format.push({ y: true, number: true, required: true });\n            } else\n                format.push({ y: true, number: true, required: true });\n        }\n        datapoints.format = format;\n    }\n\n    function parseErrors(series, i){\n\n        var points = series.datapoints.points;\n\n        // read errors from points array\n        var exl = null,\n                exu = null,\n                eyl = null,\n                eyu = null;\n        var xerr = series.points.xerr,\n                yerr = series.points.yerr;\n\n        var eb = series.points.errorbars;\n        // error bars - first X\n        if (eb == 'x' || eb == 'xy') {\n            if (xerr.asymmetric) {\n                exl = points[i + 2];\n                exu = points[i + 3];\n                if (eb == 'xy')\n                    if (yerr.asymmetric){\n                        eyl = points[i + 4];\n                        eyu = points[i + 5];\n                    } else eyl = points[i + 4];\n            } else {\n                exl = points[i + 2];\n                if (eb == 'xy')\n                    if (yerr.asymmetric) {\n                        eyl = points[i + 3];\n                        eyu = points[i + 4];\n                    } else eyl = points[i + 3];\n            }\n        // only Y\n        } else if (eb == 'y')\n            if (yerr.asymmetric) {\n                eyl = points[i + 2];\n                eyu = points[i + 3];\n            } else eyl = points[i + 2];\n\n        // symmetric errors?\n        if (exu == null) exu = exl;\n        if (eyu == null) eyu = eyl;\n\n        var errRanges = [exl, exu, eyl, eyu];\n        // nullify if not showing\n        if (!xerr.show){\n            errRanges[0] = null;\n            errRanges[1] = null;\n        }\n        if (!yerr.show){\n            errRanges[2] = null;\n            errRanges[3] = null;\n        }\n        return errRanges;\n    }\n\n    function drawSeriesErrors(plot, ctx, s){\n\n        var points = s.datapoints.points,\n                ps = s.datapoints.pointsize,\n                ax = [s.xaxis, s.yaxis],\n                radius = s.points.radius,\n                err = [s.points.xerr, s.points.yerr];\n\n        //sanity check, in case some inverted axis hack is applied to flot\n        var invertX = false;\n        if (ax[0].p2c(ax[0].max) < ax[0].p2c(ax[0].min)) {\n            invertX = true;\n            var tmp = err[0].lowerCap;\n            err[0].lowerCap = err[0].upperCap;\n            err[0].upperCap = tmp;\n        }\n\n        var invertY = false;\n        if (ax[1].p2c(ax[1].min) < ax[1].p2c(ax[1].max)) {\n            invertY = true;\n            var tmp = err[1].lowerCap;\n            err[1].lowerCap = err[1].upperCap;\n            err[1].upperCap = tmp;\n        }\n\n        for (var i = 0; i < s.datapoints.points.length; i += ps) {\n\n            //parse\n            var errRanges = parseErrors(s, i);\n\n            //cycle xerr & yerr\n            for (var e = 0; e < err.length; e++){\n\n                var minmax = [ax[e].min, ax[e].max];\n\n                //draw this error?\n                if (errRanges[e * err.length]){\n\n                    //data coordinates\n                    var x = points[i],\n                        y = points[i + 1];\n\n                    //errorbar ranges\n                    var upper = [x, y][e] + errRanges[e * err.length + 1],\n                        lower = [x, y][e] - errRanges[e * err.length];\n\n                    //points outside of the canvas\n                    if (err[e].err == 'x')\n                        if (y > ax[1].max || y < ax[1].min || upper < ax[0].min || lower > ax[0].max)\n                            continue;\n                    if (err[e].err == 'y')\n                        if (x > ax[0].max || x < ax[0].min || upper < ax[1].min || lower > ax[1].max)\n                            continue;\n\n                    // prevent errorbars getting out of the canvas\n                    var drawUpper = true,\n                        drawLower = true;\n\n                    if (upper > minmax[1]) {\n                        drawUpper = false;\n                        upper = minmax[1];\n                    }\n                    if (lower < minmax[0]) {\n                        drawLower = false;\n                        lower = minmax[0];\n                    }\n\n                    //sanity check, in case some inverted axis hack is applied to flot\n                    if ((err[e].err == 'x' && invertX) || (err[e].err == 'y' && invertY)) {\n                        //swap coordinates\n                        var tmp = lower;\n                        lower = upper;\n                        upper = tmp;\n                        tmp = drawLower;\n                        drawLower = drawUpper;\n                        drawUpper = tmp;\n                        tmp = minmax[0];\n                        minmax[0] = minmax[1];\n                        minmax[1] = tmp;\n                    }\n\n                    // convert to pixels\n                    x = ax[0].p2c(x),\n                        y = ax[1].p2c(y),\n                        upper = ax[e].p2c(upper);\n                    lower = ax[e].p2c(lower);\n                    minmax[0] = ax[e].p2c(minmax[0]);\n                    minmax[1] = ax[e].p2c(minmax[1]);\n\n                    //same style as points by default\n                    var lw = err[e].lineWidth ? err[e].lineWidth : s.points.lineWidth,\n                        sw = s.points.shadowSize != null ? s.points.shadowSize : s.shadowSize;\n\n                    //shadow as for points\n                    if (lw > 0 && sw > 0) {\n                        var w = sw / 2;\n                        ctx.lineWidth = w;\n                        ctx.strokeStyle = \"rgba(0,0,0,0.1)\";\n                        drawError(ctx, err[e], x, y, upper, lower, drawUpper, drawLower, radius, w + w/2, minmax);\n\n                        ctx.strokeStyle = \"rgba(0,0,0,0.2)\";\n                        drawError(ctx, err[e], x, y, upper, lower, drawUpper, drawLower, radius, w/2, minmax);\n                    }\n\n                    ctx.strokeStyle = err[e].color? err[e].color: s.color;\n                    ctx.lineWidth = lw;\n                    //draw it\n                    drawError(ctx, err[e], x, y, upper, lower, drawUpper, drawLower, radius, 0, minmax);\n                }\n            }\n        }\n    }\n\n    function drawError(ctx,err,x,y,upper,lower,drawUpper,drawLower,radius,offset,minmax){\n\n        //shadow offset\n        y += offset;\n        upper += offset;\n        lower += offset;\n\n        // error bar - avoid plotting over circles\n        if (err.err == 'x'){\n            if (upper > x + radius) drawPath(ctx, [[upper,y],[Math.max(x + radius,minmax[0]),y]]);\n            else drawUpper = false;\n            if (lower < x - radius) drawPath(ctx, [[Math.min(x - radius,minmax[1]),y],[lower,y]] );\n            else drawLower = false;\n        }\n        else {\n            if (upper < y - radius) drawPath(ctx, [[x,upper],[x,Math.min(y - radius,minmax[0])]] );\n            else drawUpper = false;\n            if (lower > y + radius) drawPath(ctx, [[x,Math.max(y + radius,minmax[1])],[x,lower]] );\n            else drawLower = false;\n        }\n\n        //internal radius value in errorbar, allows to plot radius 0 points and still keep proper sized caps\n        //this is a way to get errorbars on lines without visible connecting dots\n        radius = err.radius != null? err.radius: radius;\n\n        // upper cap\n        if (drawUpper) {\n            if (err.upperCap == '-'){\n                if (err.err=='x') drawPath(ctx, [[upper,y - radius],[upper,y + radius]] );\n                else drawPath(ctx, [[x - radius,upper],[x + radius,upper]] );\n            } else if ($.isFunction(err.upperCap)){\n                if (err.err=='x') err.upperCap(ctx, upper, y, radius);\n                else err.upperCap(ctx, x, upper, radius);\n            }\n        }\n        // lower cap\n        if (drawLower) {\n            if (err.lowerCap == '-'){\n                if (err.err=='x') drawPath(ctx, [[lower,y - radius],[lower,y + radius]] );\n                else drawPath(ctx, [[x - radius,lower],[x + radius,lower]] );\n            } else if ($.isFunction(err.lowerCap)){\n                if (err.err=='x') err.lowerCap(ctx, lower, y, radius);\n                else err.lowerCap(ctx, x, lower, radius);\n            }\n        }\n    }\n\n    function drawPath(ctx, pts){\n        ctx.beginPath();\n        ctx.moveTo(pts[0][0], pts[0][1]);\n        for (var p=1; p < pts.length; p++)\n            ctx.lineTo(pts[p][0], pts[p][1]);\n        ctx.stroke();\n    }\n\n    function draw(plot, ctx){\n        var plotOffset = plot.getPlotOffset();\n\n        ctx.save();\n        ctx.translate(plotOffset.left, plotOffset.top);\n        $.each(plot.getData(), function (i, s) {\n            if (s.points.errorbars && (s.points.xerr.show || s.points.yerr.show))\n                drawSeriesErrors(plot, ctx, s);\n        });\n        ctx.restore();\n    }\n\n    function init(plot) {\n        plot.hooks.processRawData.push(processRawData);\n        plot.hooks.draw.push(draw);\n    }\n\n    $.plot.plugins.push({\n                init: init,\n                options: options,\n                name: 'errorbars',\n                version: '1.0'\n            });\n})(jQuery);\n"
  },
  {
    "path": "app_backend/vendor/flot/jquery.flot.fillbetween.js",
    "content": "/* Flot plugin for computing bottoms for filled line and bar charts.\n\nCopyright (c) 2007-2014 IOLA and Ole Laursen.\nLicensed under the MIT license.\n\nThe case: you've got two series that you want to fill the area between. In Flot\nterms, you need to use one as the fill bottom of the other. You can specify the\nbottom of each data point as the third coordinate manually, or you can use this\nplugin to compute it for you.\n\nIn order to name the other series, you need to give it an id, like this:\n\n\tvar dataset = [\n\t\t{ data: [ ... ], id: \"foo\" } ,         // use default bottom\n\t\t{ data: [ ... ], fillBetween: \"foo\" }, // use first dataset as bottom\n\t];\n\n\t$.plot($(\"#placeholder\"), dataset, { lines: { show: true, fill: true }});\n\nAs a convenience, if the id given is a number that doesn't appear as an id in\nthe series, it is interpreted as the index in the array instead (so fillBetween:\n0 can also mean the first series).\n\nInternally, the plugin modifies the datapoints in each series. For line series,\nextra data points might be inserted through interpolation. Note that at points\nwhere the bottom line is not defined (due to a null point or start/end of line),\nthe current line will show a gap too. The algorithm comes from the\njquery.flot.stack.js plugin, possibly some code could be shared.\n\n*/\n\n(function ( $ ) {\n\n\tvar options = {\n\t\tseries: {\n\t\t\tfillBetween: null\t// or number\n\t\t}\n\t};\n\n\tfunction init( plot ) {\n\n\t\tfunction findBottomSeries( s, allseries ) {\n\n\t\t\tvar i;\n\n\t\t\tfor ( i = 0; i < allseries.length; ++i ) {\n\t\t\t\tif ( allseries[ i ].id === s.fillBetween ) {\n\t\t\t\t\treturn allseries[ i ];\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif ( typeof s.fillBetween === \"number\" ) {\n\t\t\t\tif ( s.fillBetween < 0 || s.fillBetween >= allseries.length ) {\n\t\t\t\t\treturn null;\n\t\t\t\t}\n\t\t\t\treturn allseries[ s.fillBetween ];\n\t\t\t}\n\n\t\t\treturn null;\n\t\t}\n\n\t\tfunction computeFillBottoms( plot, s, datapoints ) {\n\n\t\t\tif ( s.fillBetween == null ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tvar other = findBottomSeries( s, plot.getData() );\n\n\t\t\tif ( !other ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tvar ps = datapoints.pointsize,\n\t\t\t\tpoints = datapoints.points,\n\t\t\t\totherps = other.datapoints.pointsize,\n\t\t\t\totherpoints = other.datapoints.points,\n\t\t\t\tnewpoints = [],\n\t\t\t\tpx, py, intery, qx, qy, bottom,\n\t\t\t\twithlines = s.lines.show,\n\t\t\t\twithbottom = ps > 2 && datapoints.format[2].y,\n\t\t\t\twithsteps = withlines && s.lines.steps,\n\t\t\t\tfromgap = true,\n\t\t\t\ti = 0,\n\t\t\t\tj = 0,\n\t\t\t\tl, m;\n\n\t\t\twhile ( true ) {\n\n\t\t\t\tif ( i >= points.length ) {\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\n\t\t\t\tl = newpoints.length;\n\n\t\t\t\tif ( points[ i ] == null ) {\n\n\t\t\t\t\t// copy gaps\n\n\t\t\t\t\tfor ( m = 0; m < ps; ++m ) {\n\t\t\t\t\t\tnewpoints.push( points[ i + m ] );\n\t\t\t\t\t}\n\n\t\t\t\t\ti += ps;\n\n\t\t\t\t} else if ( j >= otherpoints.length ) {\n\n\t\t\t\t\t// for lines, we can't use the rest of the points\n\n\t\t\t\t\tif ( !withlines ) {\n\t\t\t\t\t\tfor ( m = 0; m < ps; ++m ) {\n\t\t\t\t\t\t\tnewpoints.push( points[ i + m ] );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\ti += ps;\n\n\t\t\t\t} else if ( otherpoints[ j ] == null ) {\n\n\t\t\t\t\t// oops, got a gap\n\n\t\t\t\t\tfor ( m = 0; m < ps; ++m ) {\n\t\t\t\t\t\tnewpoints.push( null );\n\t\t\t\t\t}\n\n\t\t\t\t\tfromgap = true;\n\t\t\t\t\tj += otherps;\n\n\t\t\t\t} else {\n\n\t\t\t\t\t// cases where we actually got two points\n\n\t\t\t\t\tpx = points[ i ];\n\t\t\t\t\tpy = points[ i + 1 ];\n\t\t\t\t\tqx = otherpoints[ j ];\n\t\t\t\t\tqy = otherpoints[ j + 1 ];\n\t\t\t\t\tbottom = 0;\n\n\t\t\t\t\tif ( px === qx ) {\n\n\t\t\t\t\t\tfor ( m = 0; m < ps; ++m ) {\n\t\t\t\t\t\t\tnewpoints.push( points[ i + m ] );\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t//newpoints[ l + 1 ] += qy;\n\t\t\t\t\t\tbottom = qy;\n\n\t\t\t\t\t\ti += ps;\n\t\t\t\t\t\tj += otherps;\n\n\t\t\t\t\t} else if ( px > qx ) {\n\n\t\t\t\t\t\t// we got past point below, might need to\n\t\t\t\t\t\t// insert interpolated extra point\n\n\t\t\t\t\t\tif ( withlines && i > 0 && points[ i - ps ] != null ) {\n\t\t\t\t\t\t\tintery = py + ( points[ i - ps + 1 ] - py ) * ( qx - px ) / ( points[ i - ps ] - px );\n\t\t\t\t\t\t\tnewpoints.push( qx );\n\t\t\t\t\t\t\tnewpoints.push( intery );\n\t\t\t\t\t\t\tfor ( m = 2; m < ps; ++m ) {\n\t\t\t\t\t\t\t\tnewpoints.push( points[ i + m ] );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tbottom = qy;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tj += otherps;\n\n\t\t\t\t\t} else { // px < qx\n\n\t\t\t\t\t\t// if we come from a gap, we just skip this point\n\n\t\t\t\t\t\tif ( fromgap && withlines ) {\n\t\t\t\t\t\t\ti += ps;\n\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tfor ( m = 0; m < ps; ++m ) {\n\t\t\t\t\t\t\tnewpoints.push( points[ i + m ] );\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// we might be able to interpolate a point below,\n\t\t\t\t\t\t// this can give us a better y\n\n\t\t\t\t\t\tif ( withlines && j > 0 && otherpoints[ j - otherps ] != null ) {\n\t\t\t\t\t\t\tbottom = qy + ( otherpoints[ j - otherps + 1 ] - qy ) * ( px - qx ) / ( otherpoints[ j - otherps ] - qx );\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t//newpoints[l + 1] += bottom;\n\n\t\t\t\t\t\ti += ps;\n\t\t\t\t\t}\n\n\t\t\t\t\tfromgap = false;\n\n\t\t\t\t\tif ( l !== newpoints.length && withbottom ) {\n\t\t\t\t\t\tnewpoints[ l + 2 ] = bottom;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// maintain the line steps invariant\n\n\t\t\t\tif ( withsteps && l !== newpoints.length && l > 0 &&\n\t\t\t\t\tnewpoints[ l ] !== null &&\n\t\t\t\t\tnewpoints[ l ] !== newpoints[ l - ps ] &&\n\t\t\t\t\tnewpoints[ l + 1 ] !== newpoints[ l - ps + 1 ] ) {\n\t\t\t\t\tfor (m = 0; m < ps; ++m) {\n\t\t\t\t\t\tnewpoints[ l + ps + m ] = newpoints[ l + m ];\n\t\t\t\t\t}\n\t\t\t\t\tnewpoints[ l + 1 ] = newpoints[ l - ps + 1 ];\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tdatapoints.points = newpoints;\n\t\t}\n\n\t\tplot.hooks.processDatapoints.push( computeFillBottoms );\n\t}\n\n\t$.plot.plugins.push({\n\t\tinit: init,\n\t\toptions: options,\n\t\tname: \"fillbetween\",\n\t\tversion: \"1.0\"\n\t});\n\n})(jQuery);\n"
  },
  {
    "path": "app_backend/vendor/flot/jquery.flot.image.js",
    "content": "/* Flot plugin for plotting images.\n\nCopyright (c) 2007-2014 IOLA and Ole Laursen.\nLicensed under the MIT license.\n\nThe data syntax is [ [ image, x1, y1, x2, y2 ], ... ] where (x1, y1) and\n(x2, y2) are where you intend the two opposite corners of the image to end up\nin the plot. Image must be a fully loaded Javascript image (you can make one\nwith new Image()). If the image is not complete, it's skipped when plotting.\n\nThere are two helpers included for retrieving images. The easiest work the way\nthat you put in URLs instead of images in the data, like this:\n\n\t[ \"myimage.png\", 0, 0, 10, 10 ]\n\nThen call $.plot.image.loadData( data, options, callback ) where data and\noptions are the same as you pass in to $.plot. This loads the images, replaces\nthe URLs in the data with the corresponding images and calls \"callback\" when\nall images are loaded (or failed loading). In the callback, you can then call\n$.plot with the data set. See the included example.\n\nA more low-level helper, $.plot.image.load(urls, callback) is also included.\nGiven a list of URLs, it calls callback with an object mapping from URL to\nImage object when all images are loaded or have failed loading.\n\nThe plugin supports these options:\n\n\tseries: {\n\t\timages: {\n\t\t\tshow: boolean\n\t\t\tanchor: \"corner\" or \"center\"\n\t\t\talpha: [ 0, 1 ]\n\t\t}\n\t}\n\nThey can be specified for a specific series:\n\n\t$.plot( $(\"#placeholder\"), [{\n\t\tdata: [ ... ],\n\t\timages: { ... }\n\t])\n\nNote that because the data format is different from usual data points, you\ncan't use images with anything else in a specific data series.\n\nSetting \"anchor\" to \"center\" causes the pixels in the image to be anchored at\nthe corner pixel centers inside of at the pixel corners, effectively letting\nhalf a pixel stick out to each side in the plot.\n\nA possible future direction could be support for tiling for large images (like\nGoogle Maps).\n\n*/\n\n(function ($) {\n    var options = {\n        series: {\n            images: {\n                show: false,\n                alpha: 1,\n                anchor: \"corner\" // or \"center\"\n            }\n        }\n    };\n\n    $.plot.image = {};\n\n    $.plot.image.loadDataImages = function (series, options, callback) {\n        var urls = [], points = [];\n\n        var defaultShow = options.series.images.show;\n        \n        $.each(series, function (i, s) {\n            if (!(defaultShow || s.images.show))\n                return;\n            \n            if (s.data)\n                s = s.data;\n\n            $.each(s, function (i, p) {\n                if (typeof p[0] == \"string\") {\n                    urls.push(p[0]);\n                    points.push(p);\n                }\n            });\n        });\n\n        $.plot.image.load(urls, function (loadedImages) {\n            $.each(points, function (i, p) {\n                var url = p[0];\n                if (loadedImages[url])\n                    p[0] = loadedImages[url];\n            });\n\n            callback();\n        });\n    }\n    \n    $.plot.image.load = function (urls, callback) {\n        var missing = urls.length, loaded = {};\n        if (missing == 0)\n            callback({});\n\n        $.each(urls, function (i, url) {\n            var handler = function () {\n                --missing;\n                \n                loaded[url] = this;\n                \n                if (missing == 0)\n                    callback(loaded);\n            };\n\n            $('<img />').load(handler).error(handler).attr('src', url);\n        });\n    };\n    \n    function drawSeries(plot, ctx, series) {\n        var plotOffset = plot.getPlotOffset();\n        \n        if (!series.images || !series.images.show)\n            return;\n        \n        var points = series.datapoints.points,\n            ps = series.datapoints.pointsize;\n        \n        for (var i = 0; i < points.length; i += ps) {\n            var img = points[i],\n                x1 = points[i + 1], y1 = points[i + 2],\n                x2 = points[i + 3], y2 = points[i + 4],\n                xaxis = series.xaxis, yaxis = series.yaxis,\n                tmp;\n\n            // actually we should check img.complete, but it\n            // appears to be a somewhat unreliable indicator in\n            // IE6 (false even after load event)\n            if (!img || img.width <= 0 || img.height <= 0)\n                continue;\n\n            if (x1 > x2) {\n                tmp = x2;\n                x2 = x1;\n                x1 = tmp;\n            }\n            if (y1 > y2) {\n                tmp = y2;\n                y2 = y1;\n                y1 = tmp;\n            }\n            \n            // if the anchor is at the center of the pixel, expand the \n            // image by 1/2 pixel in each direction\n            if (series.images.anchor == \"center\") {\n                tmp = 0.5 * (x2-x1) / (img.width - 1);\n                x1 -= tmp;\n                x2 += tmp;\n                tmp = 0.5 * (y2-y1) / (img.height - 1);\n                y1 -= tmp;\n                y2 += tmp;\n            }\n            \n            // clip\n            if (x1 == x2 || y1 == y2 ||\n                x1 >= xaxis.max || x2 <= xaxis.min ||\n                y1 >= yaxis.max || y2 <= yaxis.min)\n                continue;\n\n            var sx1 = 0, sy1 = 0, sx2 = img.width, sy2 = img.height;\n            if (x1 < xaxis.min) {\n                sx1 += (sx2 - sx1) * (xaxis.min - x1) / (x2 - x1);\n                x1 = xaxis.min;\n            }\n\n            if (x2 > xaxis.max) {\n                sx2 += (sx2 - sx1) * (xaxis.max - x2) / (x2 - x1);\n                x2 = xaxis.max;\n            }\n\n            if (y1 < yaxis.min) {\n                sy2 += (sy1 - sy2) * (yaxis.min - y1) / (y2 - y1);\n                y1 = yaxis.min;\n            }\n\n            if (y2 > yaxis.max) {\n                sy1 += (sy1 - sy2) * (yaxis.max - y2) / (y2 - y1);\n                y2 = yaxis.max;\n            }\n            \n            x1 = xaxis.p2c(x1);\n            x2 = xaxis.p2c(x2);\n            y1 = yaxis.p2c(y1);\n            y2 = yaxis.p2c(y2);\n            \n            // the transformation may have swapped us\n            if (x1 > x2) {\n                tmp = x2;\n                x2 = x1;\n                x1 = tmp;\n            }\n            if (y1 > y2) {\n                tmp = y2;\n                y2 = y1;\n                y1 = tmp;\n            }\n\n            tmp = ctx.globalAlpha;\n            ctx.globalAlpha *= series.images.alpha;\n            ctx.drawImage(img,\n                          sx1, sy1, sx2 - sx1, sy2 - sy1,\n                          x1 + plotOffset.left, y1 + plotOffset.top,\n                          x2 - x1, y2 - y1);\n            ctx.globalAlpha = tmp;\n        }\n    }\n\n    function processRawData(plot, series, data, datapoints) {\n        if (!series.images.show)\n            return;\n\n        // format is Image, x1, y1, x2, y2 (opposite corners)\n        datapoints.format = [\n            { required: true },\n            { x: true, number: true, required: true },\n            { y: true, number: true, required: true },\n            { x: true, number: true, required: true },\n            { y: true, number: true, required: true }\n        ];\n    }\n    \n    function init(plot) {\n        plot.hooks.processRawData.push(processRawData);\n        plot.hooks.drawSeries.push(drawSeries);\n    }\n    \n    $.plot.plugins.push({\n        init: init,\n        options: options,\n        name: 'image',\n        version: '1.1'\n    });\n})(jQuery);\n"
  },
  {
    "path": "app_backend/vendor/flot/jquery.flot.js",
    "content": "/* Javascript plotting library for jQuery, version 0.8.3.\n\nCopyright (c) 2007-2014 IOLA and Ole Laursen.\nLicensed under the MIT license.\n\n*/\n\n// first an inline dependency, jquery.colorhelpers.js, we inline it here\n// for convenience\n\n/* Plugin for jQuery for working with colors.\n *\n * Version 1.1.\n *\n * Inspiration from jQuery color animation plugin by John Resig.\n *\n * Released under the MIT license by Ole Laursen, October 2009.\n *\n * Examples:\n *\n *   $.color.parse(\"#fff\").scale('rgb', 0.25).add('a', -0.5).toString()\n *   var c = $.color.extract($(\"#mydiv\"), 'background-color');\n *   console.log(c.r, c.g, c.b, c.a);\n *   $.color.make(100, 50, 25, 0.4).toString() // returns \"rgba(100,50,25,0.4)\"\n *\n * Note that .scale() and .add() return the same modified object\n * instead of making a new one.\n *\n * V. 1.1: Fix error handling so e.g. parsing an empty string does\n * produce a color rather than just crashing.\n */\n(function($){$.color={};$.color.make=function(r,g,b,a){var o={};o.r=r||0;o.g=g||0;o.b=b||0;o.a=a!=null?a:1;o.add=function(c,d){for(var i=0;i<c.length;++i)o[c.charAt(i)]+=d;return o.normalize()};o.scale=function(c,f){for(var i=0;i<c.length;++i)o[c.charAt(i)]*=f;return o.normalize()};o.toString=function(){if(o.a>=1){return\"rgb(\"+[o.r,o.g,o.b].join(\",\")+\")\"}else{return\"rgba(\"+[o.r,o.g,o.b,o.a].join(\",\")+\")\"}};o.normalize=function(){function clamp(min,value,max){return value<min?min:value>max?max:value}o.r=clamp(0,parseInt(o.r),255);o.g=clamp(0,parseInt(o.g),255);o.b=clamp(0,parseInt(o.b),255);o.a=clamp(0,o.a,1);return o};o.clone=function(){return $.color.make(o.r,o.b,o.g,o.a)};return o.normalize()};$.color.extract=function(elem,css){var c;do{c=elem.css(css).toLowerCase();if(c!=\"\"&&c!=\"transparent\")break;elem=elem.parent()}while(elem.length&&!$.nodeName(elem.get(0),\"body\"));if(c==\"rgba(0, 0, 0, 0)\")c=\"transparent\";return $.color.parse(c)};$.color.parse=function(str){var res,m=$.color.make;if(res=/rgb\\(\\s*([0-9]{1,3})\\s*,\\s*([0-9]{1,3})\\s*,\\s*([0-9]{1,3})\\s*\\)/.exec(str))return m(parseInt(res[1],10),parseInt(res[2],10),parseInt(res[3],10));if(res=/rgba\\(\\s*([0-9]{1,3})\\s*,\\s*([0-9]{1,3})\\s*,\\s*([0-9]{1,3})\\s*,\\s*([0-9]+(?:\\.[0-9]+)?)\\s*\\)/.exec(str))return m(parseInt(res[1],10),parseInt(res[2],10),parseInt(res[3],10),parseFloat(res[4]));if(res=/rgb\\(\\s*([0-9]+(?:\\.[0-9]+)?)\\%\\s*,\\s*([0-9]+(?:\\.[0-9]+)?)\\%\\s*,\\s*([0-9]+(?:\\.[0-9]+)?)\\%\\s*\\)/.exec(str))return m(parseFloat(res[1])*2.55,parseFloat(res[2])*2.55,parseFloat(res[3])*2.55);if(res=/rgba\\(\\s*([0-9]+(?:\\.[0-9]+)?)\\%\\s*,\\s*([0-9]+(?:\\.[0-9]+)?)\\%\\s*,\\s*([0-9]+(?:\\.[0-9]+)?)\\%\\s*,\\s*([0-9]+(?:\\.[0-9]+)?)\\s*\\)/.exec(str))return m(parseFloat(res[1])*2.55,parseFloat(res[2])*2.55,parseFloat(res[3])*2.55,parseFloat(res[4]));if(res=/#([a-fA-F0-9]{2})([a-fA-F0-9]{2})([a-fA-F0-9]{2})/.exec(str))return m(parseInt(res[1],16),parseInt(res[2],16),parseInt(res[3],16));if(res=/#([a-fA-F0-9])([a-fA-F0-9])([a-fA-F0-9])/.exec(str))return m(parseInt(res[1]+res[1],16),parseInt(res[2]+res[2],16),parseInt(res[3]+res[3],16));var name=$.trim(str).toLowerCase();if(name==\"transparent\")return m(255,255,255,0);else{res=lookupColors[name]||[0,0,0];return m(res[0],res[1],res[2])}};var lookupColors={aqua:[0,255,255],azure:[240,255,255],beige:[245,245,220],black:[0,0,0],blue:[0,0,255],brown:[165,42,42],cyan:[0,255,255],darkblue:[0,0,139],darkcyan:[0,139,139],darkgrey:[169,169,169],darkgreen:[0,100,0],darkkhaki:[189,183,107],darkmagenta:[139,0,139],darkolivegreen:[85,107,47],darkorange:[255,140,0],darkorchid:[153,50,204],darkred:[139,0,0],darksalmon:[233,150,122],darkviolet:[148,0,211],fuchsia:[255,0,255],gold:[255,215,0],green:[0,128,0],indigo:[75,0,130],khaki:[240,230,140],lightblue:[173,216,230],lightcyan:[224,255,255],lightgreen:[144,238,144],lightgrey:[211,211,211],lightpink:[255,182,193],lightyellow:[255,255,224],lime:[0,255,0],magenta:[255,0,255],maroon:[128,0,0],navy:[0,0,128],olive:[128,128,0],orange:[255,165,0],pink:[255,192,203],purple:[128,0,128],violet:[128,0,128],red:[255,0,0],silver:[192,192,192],white:[255,255,255],yellow:[255,255,0]}})(jQuery);\n\n// the actual Flot code\n(function($) {\n\n\t// Cache the prototype hasOwnProperty for faster access\n\n\tvar hasOwnProperty = Object.prototype.hasOwnProperty;\n\n    // A shim to provide 'detach' to jQuery versions prior to 1.4.  Using a DOM\n    // operation produces the same effect as detach, i.e. removing the element\n    // without touching its jQuery data.\n\n    // Do not merge this into Flot 0.9, since it requires jQuery 1.4.4+.\n\n    if (!$.fn.detach) {\n        $.fn.detach = function() {\n            return this.each(function() {\n                if (this.parentNode) {\n                    this.parentNode.removeChild( this );\n                }\n            });\n        };\n    }\n\n\t///////////////////////////////////////////////////////////////////////////\n\t// The Canvas object is a wrapper around an HTML5 <canvas> tag.\n\t//\n\t// @constructor\n\t// @param {string} cls List of classes to apply to the canvas.\n\t// @param {element} container Element onto which to append the canvas.\n\t//\n\t// Requiring a container is a little iffy, but unfortunately canvas\n\t// operations don't work unless the canvas is attached to the DOM.\n\n\tfunction Canvas(cls, container) {\n\n\t\tvar element = container.children(\".\" + cls)[0];\n\n\t\tif (element == null) {\n\n\t\t\telement = document.createElement(\"canvas\");\n\t\t\telement.className = cls;\n\n\t\t\t$(element).css({ direction: \"ltr\", position: \"absolute\", left: 0, top: 0 })\n\t\t\t\t.appendTo(container);\n\n\t\t\t// If HTML5 Canvas isn't available, fall back to [Ex|Flash]canvas\n\n\t\t\tif (!element.getContext) {\n\t\t\t\tif (window.G_vmlCanvasManager) {\n\t\t\t\t\telement = window.G_vmlCanvasManager.initElement(element);\n\t\t\t\t} else {\n\t\t\t\t\tthrow new Error(\"Canvas is not available. If you're using IE with a fall-back such as Excanvas, then there's either a mistake in your conditional include, or the page has no DOCTYPE and is rendering in Quirks Mode.\");\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tthis.element = element;\n\n\t\tvar context = this.context = element.getContext(\"2d\");\n\n\t\t// Determine the screen's ratio of physical to device-independent\n\t\t// pixels.  This is the ratio between the canvas width that the browser\n\t\t// advertises and the number of pixels actually present in that space.\n\n\t\t// The iPhone 4, for example, has a device-independent width of 320px,\n\t\t// but its screen is actually 640px wide.  It therefore has a pixel\n\t\t// ratio of 2, while most normal devices have a ratio of 1.\n\n\t\tvar devicePixelRatio = window.devicePixelRatio || 1,\n\t\t\tbackingStoreRatio =\n\t\t\t\tcontext.webkitBackingStorePixelRatio ||\n\t\t\t\tcontext.mozBackingStorePixelRatio ||\n\t\t\t\tcontext.msBackingStorePixelRatio ||\n\t\t\t\tcontext.oBackingStorePixelRatio ||\n\t\t\t\tcontext.backingStorePixelRatio || 1;\n\n\t\tthis.pixelRatio = devicePixelRatio / backingStoreRatio;\n\n\t\t// Size the canvas to match the internal dimensions of its container\n\n\t\tthis.resize(container.width(), container.height());\n\n\t\t// Collection of HTML div layers for text overlaid onto the canvas\n\n\t\tthis.textContainer = null;\n\t\tthis.text = {};\n\n\t\t// Cache of text fragments and metrics, so we can avoid expensively\n\t\t// re-calculating them when the plot is re-rendered in a loop.\n\n\t\tthis._textCache = {};\n\t}\n\n\t// Resizes the canvas to the given dimensions.\n\t//\n\t// @param {number} width New width of the canvas, in pixels.\n\t// @param {number} width New height of the canvas, in pixels.\n\n\tCanvas.prototype.resize = function(width, height) {\n\n\t\tif (width <= 0 || height <= 0) {\n\t\t\tthrow new Error(\"Invalid dimensions for plot, width = \" + width + \", height = \" + height);\n\t\t}\n\n\t\tvar element = this.element,\n\t\t\tcontext = this.context,\n\t\t\tpixelRatio = this.pixelRatio;\n\n\t\t// Resize the canvas, increasing its density based on the display's\n\t\t// pixel ratio; basically giving it more pixels without increasing the\n\t\t// size of its element, to take advantage of the fact that retina\n\t\t// displays have that many more pixels in the same advertised space.\n\n\t\t// Resizing should reset the state (excanvas seems to be buggy though)\n\n\t\tif (this.width != width) {\n\t\t\telement.width = width * pixelRatio;\n\t\t\telement.style.width = width + \"px\";\n\t\t\tthis.width = width;\n\t\t}\n\n\t\tif (this.height != height) {\n\t\t\telement.height = height * pixelRatio;\n\t\t\telement.style.height = height + \"px\";\n\t\t\tthis.height = height;\n\t\t}\n\n\t\t// Save the context, so we can reset in case we get replotted.  The\n\t\t// restore ensure that we're really back at the initial state, and\n\t\t// should be safe even if we haven't saved the initial state yet.\n\n\t\tcontext.restore();\n\t\tcontext.save();\n\n\t\t// Scale the coordinate space to match the display density; so even though we\n\t\t// may have twice as many pixels, we still want lines and other drawing to\n\t\t// appear at the same size; the extra pixels will just make them crisper.\n\n\t\tcontext.scale(pixelRatio, pixelRatio);\n\t};\n\n\t// Clears the entire canvas area, not including any overlaid HTML text\n\n\tCanvas.prototype.clear = function() {\n\t\tthis.context.clearRect(0, 0, this.width, this.height);\n\t};\n\n\t// Finishes rendering the canvas, including managing the text overlay.\n\n\tCanvas.prototype.render = function() {\n\n\t\tvar cache = this._textCache;\n\n\t\t// For each text layer, add elements marked as active that haven't\n\t\t// already been rendered, and remove those that are no longer active.\n\n\t\tfor (var layerKey in cache) {\n\t\t\tif (hasOwnProperty.call(cache, layerKey)) {\n\n\t\t\t\tvar layer = this.getTextLayer(layerKey),\n\t\t\t\t\tlayerCache = cache[layerKey];\n\n\t\t\t\tlayer.hide();\n\n\t\t\t\tfor (var styleKey in layerCache) {\n\t\t\t\t\tif (hasOwnProperty.call(layerCache, styleKey)) {\n\t\t\t\t\t\tvar styleCache = layerCache[styleKey];\n\t\t\t\t\t\tfor (var key in styleCache) {\n\t\t\t\t\t\t\tif (hasOwnProperty.call(styleCache, key)) {\n\n\t\t\t\t\t\t\t\tvar positions = styleCache[key].positions;\n\n\t\t\t\t\t\t\t\tfor (var i = 0, position; position = positions[i]; i++) {\n\t\t\t\t\t\t\t\t\tif (position.active) {\n\t\t\t\t\t\t\t\t\t\tif (!position.rendered) {\n\t\t\t\t\t\t\t\t\t\t\tlayer.append(position.element);\n\t\t\t\t\t\t\t\t\t\t\tposition.rendered = true;\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\t\tpositions.splice(i--, 1);\n\t\t\t\t\t\t\t\t\t\tif (position.rendered) {\n\t\t\t\t\t\t\t\t\t\t\tposition.element.detach();\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\tif (positions.length == 0) {\n\t\t\t\t\t\t\t\t\tdelete styleCache[key];\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tlayer.show();\n\t\t\t}\n\t\t}\n\t};\n\n\t// Creates (if necessary) and returns the text overlay container.\n\t//\n\t// @param {string} classes String of space-separated CSS classes used to\n\t//     uniquely identify the text layer.\n\t// @return {object} The jQuery-wrapped text-layer div.\n\n\tCanvas.prototype.getTextLayer = function(classes) {\n\n\t\tvar layer = this.text[classes];\n\n\t\t// Create the text layer if it doesn't exist\n\n\t\tif (layer == null) {\n\n\t\t\t// Create the text layer container, if it doesn't exist\n\n\t\t\tif (this.textContainer == null) {\n\t\t\t\tthis.textContainer = $(\"<div class='flot-text'></div>\")\n\t\t\t\t\t.css({\n\t\t\t\t\t\tposition: \"absolute\",\n\t\t\t\t\t\ttop: 0,\n\t\t\t\t\t\tleft: 0,\n\t\t\t\t\t\tbottom: 0,\n\t\t\t\t\t\tright: 0,\n\t\t\t\t\t\t'font-size': \"smaller\",\n\t\t\t\t\t\tcolor: \"#545454\"\n\t\t\t\t\t})\n\t\t\t\t\t.insertAfter(this.element);\n\t\t\t}\n\n\t\t\tlayer = this.text[classes] = $(\"<div></div>\")\n\t\t\t\t.addClass(classes)\n\t\t\t\t.css({\n\t\t\t\t\tposition: \"absolute\",\n\t\t\t\t\ttop: 0,\n\t\t\t\t\tleft: 0,\n\t\t\t\t\tbottom: 0,\n\t\t\t\t\tright: 0\n\t\t\t\t})\n\t\t\t\t.appendTo(this.textContainer);\n\t\t}\n\n\t\treturn layer;\n\t};\n\n\t// Creates (if necessary) and returns a text info object.\n\t//\n\t// The object looks like this:\n\t//\n\t// {\n\t//     width: Width of the text's wrapper div.\n\t//     height: Height of the text's wrapper div.\n\t//     element: The jQuery-wrapped HTML div containing the text.\n\t//     positions: Array of positions at which this text is drawn.\n\t// }\n\t//\n\t// The positions array contains objects that look like this:\n\t//\n\t// {\n\t//     active: Flag indicating whether the text should be visible.\n\t//     rendered: Flag indicating whether the text is currently visible.\n\t//     element: The jQuery-wrapped HTML div containing the text.\n\t//     x: X coordinate at which to draw the text.\n\t//     y: Y coordinate at which to draw the text.\n\t// }\n\t//\n\t// Each position after the first receives a clone of the original element.\n\t//\n\t// The idea is that that the width, height, and general 'identity' of the\n\t// text is constant no matter where it is placed; the placements are a\n\t// secondary property.\n\t//\n\t// Canvas maintains a cache of recently-used text info objects; getTextInfo\n\t// either returns the cached element or creates a new entry.\n\t//\n\t// @param {string} layer A string of space-separated CSS classes uniquely\n\t//     identifying the layer containing this text.\n\t// @param {string} text Text string to retrieve info for.\n\t// @param {(string|object)=} font Either a string of space-separated CSS\n\t//     classes or a font-spec object, defining the text's font and style.\n\t// @param {number=} angle Angle at which to rotate the text, in degrees.\n\t//     Angle is currently unused, it will be implemented in the future.\n\t// @param {number=} width Maximum width of the text before it wraps.\n\t// @return {object} a text info object.\n\n\tCanvas.prototype.getTextInfo = function(layer, text, font, angle, width) {\n\n\t\tvar textStyle, layerCache, styleCache, info;\n\n\t\t// Cast the value to a string, in case we were given a number or such\n\n\t\ttext = \"\" + text;\n\n\t\t// If the font is a font-spec object, generate a CSS font definition\n\n\t\tif (typeof font === \"object\") {\n\t\t\ttextStyle = font.style + \" \" + font.variant + \" \" + font.weight + \" \" + font.size + \"px/\" + font.lineHeight + \"px \" + font.family;\n\t\t} else {\n\t\t\ttextStyle = font;\n\t\t}\n\n\t\t// Retrieve (or create) the cache for the text's layer and styles\n\n\t\tlayerCache = this._textCache[layer];\n\n\t\tif (layerCache == null) {\n\t\t\tlayerCache = this._textCache[layer] = {};\n\t\t}\n\n\t\tstyleCache = layerCache[textStyle];\n\n\t\tif (styleCache == null) {\n\t\t\tstyleCache = layerCache[textStyle] = {};\n\t\t}\n\n\t\tinfo = styleCache[text];\n\n\t\t// If we can't find a matching element in our cache, create a new one\n\n\t\tif (info == null) {\n\n\t\t\tvar element = $(\"<div></div>\").html(text)\n\t\t\t\t.css({\n\t\t\t\t\tposition: \"absolute\",\n\t\t\t\t\t'max-width': width,\n\t\t\t\t\ttop: -9999\n\t\t\t\t})\n\t\t\t\t.appendTo(this.getTextLayer(layer));\n\n\t\t\tif (typeof font === \"object\") {\n\t\t\t\telement.css({\n\t\t\t\t\tfont: textStyle,\n\t\t\t\t\tcolor: font.color\n\t\t\t\t});\n\t\t\t} else if (typeof font === \"string\") {\n\t\t\t\telement.addClass(font);\n\t\t\t}\n\n\t\t\tinfo = styleCache[text] = {\n\t\t\t\twidth: element.outerWidth(true),\n\t\t\t\theight: element.outerHeight(true),\n\t\t\t\telement: element,\n\t\t\t\tpositions: []\n\t\t\t};\n\n\t\t\telement.detach();\n\t\t}\n\n\t\treturn info;\n\t};\n\n\t// Adds a text string to the canvas text overlay.\n\t//\n\t// The text isn't drawn immediately; it is marked as rendering, which will\n\t// result in its addition to the canvas on the next render pass.\n\t//\n\t// @param {string} layer A string of space-separated CSS classes uniquely\n\t//     identifying the layer containing this text.\n\t// @param {number} x X coordinate at which to draw the text.\n\t// @param {number} y Y coordinate at which to draw the text.\n\t// @param {string} text Text string to draw.\n\t// @param {(string|object)=} font Either a string of space-separated CSS\n\t//     classes or a font-spec object, defining the text's font and style.\n\t// @param {number=} angle Angle at which to rotate the text, in degrees.\n\t//     Angle is currently unused, it will be implemented in the future.\n\t// @param {number=} width Maximum width of the text before it wraps.\n\t// @param {string=} halign Horizontal alignment of the text; either \"left\",\n\t//     \"center\" or \"right\".\n\t// @param {string=} valign Vertical alignment of the text; either \"top\",\n\t//     \"middle\" or \"bottom\".\n\n\tCanvas.prototype.addText = function(layer, x, y, text, font, angle, width, halign, valign) {\n\n\t\tvar info = this.getTextInfo(layer, text, font, angle, width),\n\t\t\tpositions = info.positions;\n\n\t\t// Tweak the div's position to match the text's alignment\n\n\t\tif (halign == \"center\") {\n\t\t\tx -= info.width / 2;\n\t\t} else if (halign == \"right\") {\n\t\t\tx -= info.width;\n\t\t}\n\n\t\tif (valign == \"middle\") {\n\t\t\ty -= info.height / 2;\n\t\t} else if (valign == \"bottom\") {\n\t\t\ty -= info.height;\n\t\t}\n\n\t\t// Determine whether this text already exists at this position.\n\t\t// If so, mark it for inclusion in the next render pass.\n\n\t\tfor (var i = 0, position; position = positions[i]; i++) {\n\t\t\tif (position.x == x && position.y == y) {\n\t\t\t\tposition.active = true;\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\n\t\t// If the text doesn't exist at this position, create a new entry\n\n\t\t// For the very first position we'll re-use the original element,\n\t\t// while for subsequent ones we'll clone it.\n\n\t\tposition = {\n\t\t\tactive: true,\n\t\t\trendered: false,\n\t\t\telement: positions.length ? info.element.clone() : info.element,\n\t\t\tx: x,\n\t\t\ty: y\n\t\t};\n\n\t\tpositions.push(position);\n\n\t\t// Move the element to its final position within the container\n\n\t\tposition.element.css({\n\t\t\ttop: Math.round(y),\n\t\t\tleft: Math.round(x),\n\t\t\t'text-align': halign\t// In case the text wraps\n\t\t});\n\t};\n\n\t// Removes one or more text strings from the canvas text overlay.\n\t//\n\t// If no parameters are given, all text within the layer is removed.\n\t//\n\t// Note that the text is not immediately removed; it is simply marked as\n\t// inactive, which will result in its removal on the next render pass.\n\t// This avoids the performance penalty for 'clear and redraw' behavior,\n\t// where we potentially get rid of all text on a layer, but will likely\n\t// add back most or all of it later, as when redrawing axes, for example.\n\t//\n\t// @param {string} layer A string of space-separated CSS classes uniquely\n\t//     identifying the layer containing this text.\n\t// @param {number=} x X coordinate of the text.\n\t// @param {number=} y Y coordinate of the text.\n\t// @param {string=} text Text string to remove.\n\t// @param {(string|object)=} font Either a string of space-separated CSS\n\t//     classes or a font-spec object, defining the text's font and style.\n\t// @param {number=} angle Angle at which the text is rotated, in degrees.\n\t//     Angle is currently unused, it will be implemented in the future.\n\n\tCanvas.prototype.removeText = function(layer, x, y, text, font, angle) {\n\t\tif (text == null) {\n\t\t\tvar layerCache = this._textCache[layer];\n\t\t\tif (layerCache != null) {\n\t\t\t\tfor (var styleKey in layerCache) {\n\t\t\t\t\tif (hasOwnProperty.call(layerCache, styleKey)) {\n\t\t\t\t\t\tvar styleCache = layerCache[styleKey];\n\t\t\t\t\t\tfor (var key in styleCache) {\n\t\t\t\t\t\t\tif (hasOwnProperty.call(styleCache, key)) {\n\t\t\t\t\t\t\t\tvar positions = styleCache[key].positions;\n\t\t\t\t\t\t\t\tfor (var i = 0, position; position = positions[i]; i++) {\n\t\t\t\t\t\t\t\t\tposition.active = false;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\tvar positions = this.getTextInfo(layer, text, font, angle).positions;\n\t\t\tfor (var i = 0, position; position = positions[i]; i++) {\n\t\t\t\tif (position.x == x && position.y == y) {\n\t\t\t\t\tposition.active = false;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t};\n\n\t///////////////////////////////////////////////////////////////////////////\n\t// The top-level container for the entire plot.\n\n    function Plot(placeholder, data_, options_, plugins) {\n        // data is on the form:\n        //   [ series1, series2 ... ]\n        // where series is either just the data as [ [x1, y1], [x2, y2], ... ]\n        // or { data: [ [x1, y1], [x2, y2], ... ], label: \"some label\", ... }\n\n        var series = [],\n            options = {\n                // the color theme used for graphs\n                colors: [\"#edc240\", \"#afd8f8\", \"#cb4b4b\", \"#4da74d\", \"#9440ed\"],\n                legend: {\n                    show: true,\n                    noColumns: 1, // number of colums in legend table\n                    labelFormatter: null, // fn: string -> string\n                    labelBoxBorderColor: \"#ccc\", // border color for the little label boxes\n                    container: null, // container (as jQuery object) to put legend in, null means default on top of graph\n                    position: \"ne\", // position of default legend container within plot\n                    margin: 5, // distance from grid edge to default legend container within plot\n                    backgroundColor: null, // null means auto-detect\n                    backgroundOpacity: 0.85, // set to 0 to avoid background\n                    sorted: null    // default to no legend sorting\n                },\n                xaxis: {\n                    show: null, // null = auto-detect, true = always, false = never\n                    position: \"bottom\", // or \"top\"\n                    mode: null, // null or \"time\"\n                    font: null, // null (derived from CSS in placeholder) or object like { size: 11, lineHeight: 13, style: \"italic\", weight: \"bold\", family: \"sans-serif\", variant: \"small-caps\" }\n                    color: null, // base color, labels, ticks\n                    tickColor: null, // possibly different color of ticks, e.g. \"rgba(0,0,0,0.15)\"\n                    transform: null, // null or f: number -> number to transform axis\n                    inverseTransform: null, // if transform is set, this should be the inverse function\n                    min: null, // min. value to show, null means set automatically\n                    max: null, // max. value to show, null means set automatically\n                    autoscaleMargin: null, // margin in % to add if auto-setting min/max\n                    ticks: null, // either [1, 3] or [[1, \"a\"], 3] or (fn: axis info -> ticks) or app. number of ticks for auto-ticks\n                    tickFormatter: null, // fn: number -> string\n                    labelWidth: null, // size of tick labels in pixels\n                    labelHeight: null,\n                    reserveSpace: null, // whether to reserve space even if axis isn't shown\n                    tickLength: null, // size in pixels of ticks, or \"full\" for whole line\n                    alignTicksWithAxis: null, // axis number or null for no sync\n                    tickDecimals: null, // no. of decimals, null means auto\n                    tickSize: null, // number or [number, \"unit\"]\n                    minTickSize: null // number or [number, \"unit\"]\n                },\n                yaxis: {\n                    autoscaleMargin: 0.02,\n                    position: \"left\" // or \"right\"\n                },\n                xaxes: [],\n                yaxes: [],\n                series: {\n                    points: {\n                        show: false,\n                        radius: 3,\n                        lineWidth: 2, // in pixels\n                        fill: true,\n                        fillColor: \"#ffffff\",\n                        symbol: \"circle\" // or callback\n                    },\n                    lines: {\n                        // we don't put in show: false so we can see\n                        // whether lines were actively disabled\n                        lineWidth: 2, // in pixels\n                        fill: false,\n                        fillColor: null,\n                        steps: false\n                        // Omit 'zero', so we can later default its value to\n                        // match that of the 'fill' option.\n                    },\n                    bars: {\n                        show: false,\n                        lineWidth: 2, // in pixels\n                        barWidth: 1, // in units of the x axis\n                        fill: true,\n                        fillColor: null,\n                        align: \"left\", // \"left\", \"right\", or \"center\"\n                        horizontal: false,\n                        zero: true\n                    },\n                    shadowSize: 3,\n                    highlightColor: null\n                },\n                grid: {\n                    show: true,\n                    aboveData: false,\n                    color: \"#545454\", // primary color used for outline and labels\n                    backgroundColor: null, // null for transparent, else color\n                    borderColor: null, // set if different from the grid color\n                    tickColor: null, // color for the ticks, e.g. \"rgba(0,0,0,0.15)\"\n                    margin: 0, // distance from the canvas edge to the grid\n                    labelMargin: 5, // in pixels\n                    axisMargin: 8, // in pixels\n                    borderWidth: 2, // in pixels\n                    minBorderMargin: null, // in pixels, null means taken from points radius\n                    markings: null, // array of ranges or fn: axes -> array of ranges\n                    markingsColor: \"#f4f4f4\",\n                    markingsLineWidth: 2,\n                    // interactive stuff\n                    clickable: false,\n                    hoverable: false,\n                    autoHighlight: true, // highlight in case mouse is near\n                    mouseActiveRadius: 10 // how far the mouse can be away to activate an item\n                },\n                interaction: {\n                    redrawOverlayInterval: 1000/60 // time between updates, -1 means in same flow\n                },\n                hooks: {}\n            },\n        surface = null,     // the canvas for the plot itself\n        overlay = null,     // canvas for interactive stuff on top of plot\n        eventHolder = null, // jQuery object that events should be bound to\n        ctx = null, octx = null,\n        xaxes = [], yaxes = [],\n        plotOffset = { left: 0, right: 0, top: 0, bottom: 0},\n        plotWidth = 0, plotHeight = 0,\n        hooks = {\n            processOptions: [],\n            processRawData: [],\n            processDatapoints: [],\n            processOffset: [],\n            drawBackground: [],\n            drawSeries: [],\n            draw: [],\n            bindEvents: [],\n            drawOverlay: [],\n            shutdown: []\n        },\n        plot = this;\n\n        // public functions\n        plot.setData = setData;\n        plot.setupGrid = setupGrid;\n        plot.draw = draw;\n        plot.getPlaceholder = function() { return placeholder; };\n        plot.getCanvas = function() { return surface.element; };\n        plot.getPlotOffset = function() { return plotOffset; };\n        plot.width = function () { return plotWidth; };\n        plot.height = function () { return plotHeight; };\n        plot.offset = function () {\n            var o = eventHolder.offset();\n            o.left += plotOffset.left;\n            o.top += plotOffset.top;\n            return o;\n        };\n        plot.getData = function () { return series; };\n        plot.getAxes = function () {\n            var res = {}, i;\n            $.each(xaxes.concat(yaxes), function (_, axis) {\n                if (axis)\n                    res[axis.direction + (axis.n != 1 ? axis.n : \"\") + \"axis\"] = axis;\n            });\n            return res;\n        };\n        plot.getXAxes = function () { return xaxes; };\n        plot.getYAxes = function () { return yaxes; };\n        plot.c2p = canvasToAxisCoords;\n        plot.p2c = axisToCanvasCoords;\n        plot.getOptions = function () { return options; };\n        plot.highlight = highlight;\n        plot.unhighlight = unhighlight;\n        plot.triggerRedrawOverlay = triggerRedrawOverlay;\n        plot.pointOffset = function(point) {\n            return {\n                left: parseInt(xaxes[axisNumber(point, \"x\") - 1].p2c(+point.x) + plotOffset.left, 10),\n                top: parseInt(yaxes[axisNumber(point, \"y\") - 1].p2c(+point.y) + plotOffset.top, 10)\n            };\n        };\n        plot.shutdown = shutdown;\n        plot.destroy = function () {\n            shutdown();\n            placeholder.removeData(\"plot\").empty();\n\n            series = [];\n            options = null;\n            surface = null;\n            overlay = null;\n            eventHolder = null;\n            ctx = null;\n            octx = null;\n            xaxes = [];\n            yaxes = [];\n            hooks = null;\n            highlights = [];\n            plot = null;\n        };\n        plot.resize = function () {\n        \tvar width = placeholder.width(),\n        \t\theight = placeholder.height();\n            surface.resize(width, height);\n            overlay.resize(width, height);\n        };\n\n        // public attributes\n        plot.hooks = hooks;\n\n        // initialize\n        initPlugins(plot);\n        parseOptions(options_);\n        setupCanvases();\n        setData(data_);\n        setupGrid();\n        draw();\n        bindEvents();\n\n\n        function executeHooks(hook, args) {\n            args = [plot].concat(args);\n            for (var i = 0; i < hook.length; ++i)\n                hook[i].apply(this, args);\n        }\n\n        function initPlugins() {\n\n            // References to key classes, allowing plugins to modify them\n\n            var classes = {\n                Canvas: Canvas\n            };\n\n            for (var i = 0; i < plugins.length; ++i) {\n                var p = plugins[i];\n                p.init(plot, classes);\n                if (p.options)\n                    $.extend(true, options, p.options);\n            }\n        }\n\n        function parseOptions(opts) {\n\n            $.extend(true, options, opts);\n\n            // $.extend merges arrays, rather than replacing them.  When less\n            // colors are provided than the size of the default palette, we\n            // end up with those colors plus the remaining defaults, which is\n            // not expected behavior; avoid it by replacing them here.\n\n            if (opts && opts.colors) {\n            \toptions.colors = opts.colors;\n            }\n\n            if (options.xaxis.color == null)\n                options.xaxis.color = $.color.parse(options.grid.color).scale('a', 0.22).toString();\n            if (options.yaxis.color == null)\n                options.yaxis.color = $.color.parse(options.grid.color).scale('a', 0.22).toString();\n\n            if (options.xaxis.tickColor == null) // grid.tickColor for back-compatibility\n                options.xaxis.tickColor = options.grid.tickColor || options.xaxis.color;\n            if (options.yaxis.tickColor == null) // grid.tickColor for back-compatibility\n                options.yaxis.tickColor = options.grid.tickColor || options.yaxis.color;\n\n            if (options.grid.borderColor == null)\n                options.grid.borderColor = options.grid.color;\n            if (options.grid.tickColor == null)\n                options.grid.tickColor = $.color.parse(options.grid.color).scale('a', 0.22).toString();\n\n            // Fill in defaults for axis options, including any unspecified\n            // font-spec fields, if a font-spec was provided.\n\n            // If no x/y axis options were provided, create one of each anyway,\n            // since the rest of the code assumes that they exist.\n\n            var i, axisOptions, axisCount,\n                fontSize = placeholder.css(\"font-size\"),\n                fontSizeDefault = fontSize ? +fontSize.replace(\"px\", \"\") : 13,\n                fontDefaults = {\n                    style: placeholder.css(\"font-style\"),\n                    size: Math.round(0.8 * fontSizeDefault),\n                    variant: placeholder.css(\"font-variant\"),\n                    weight: placeholder.css(\"font-weight\"),\n                    family: placeholder.css(\"font-family\")\n                };\n\n            axisCount = options.xaxes.length || 1;\n            for (i = 0; i < axisCount; ++i) {\n\n                axisOptions = options.xaxes[i];\n                if (axisOptions && !axisOptions.tickColor) {\n                    axisOptions.tickColor = axisOptions.color;\n                }\n\n                axisOptions = $.extend(true, {}, options.xaxis, axisOptions);\n                options.xaxes[i] = axisOptions;\n\n                if (axisOptions.font) {\n                    axisOptions.font = $.extend({}, fontDefaults, axisOptions.font);\n                    if (!axisOptions.font.color) {\n                        axisOptions.font.color = axisOptions.color;\n                    }\n                    if (!axisOptions.font.lineHeight) {\n                        axisOptions.font.lineHeight = Math.round(axisOptions.font.size * 1.15);\n                    }\n                }\n            }\n\n            axisCount = options.yaxes.length || 1;\n            for (i = 0; i < axisCount; ++i) {\n\n                axisOptions = options.yaxes[i];\n                if (axisOptions && !axisOptions.tickColor) {\n                    axisOptions.tickColor = axisOptions.color;\n                }\n\n                axisOptions = $.extend(true, {}, options.yaxis, axisOptions);\n                options.yaxes[i] = axisOptions;\n\n                if (axisOptions.font) {\n                    axisOptions.font = $.extend({}, fontDefaults, axisOptions.font);\n                    if (!axisOptions.font.color) {\n                        axisOptions.font.color = axisOptions.color;\n                    }\n                    if (!axisOptions.font.lineHeight) {\n                        axisOptions.font.lineHeight = Math.round(axisOptions.font.size * 1.15);\n                    }\n                }\n            }\n\n            // backwards compatibility, to be removed in future\n            if (options.xaxis.noTicks && options.xaxis.ticks == null)\n                options.xaxis.ticks = options.xaxis.noTicks;\n            if (options.yaxis.noTicks && options.yaxis.ticks == null)\n                options.yaxis.ticks = options.yaxis.noTicks;\n            if (options.x2axis) {\n                options.xaxes[1] = $.extend(true, {}, options.xaxis, options.x2axis);\n                options.xaxes[1].position = \"top\";\n                // Override the inherit to allow the axis to auto-scale\n                if (options.x2axis.min == null) {\n                    options.xaxes[1].min = null;\n                }\n                if (options.x2axis.max == null) {\n                    options.xaxes[1].max = null;\n                }\n            }\n            if (options.y2axis) {\n                options.yaxes[1] = $.extend(true, {}, options.yaxis, options.y2axis);\n                options.yaxes[1].position = \"right\";\n                // Override the inherit to allow the axis to auto-scale\n                if (options.y2axis.min == null) {\n                    options.yaxes[1].min = null;\n                }\n                if (options.y2axis.max == null) {\n                    options.yaxes[1].max = null;\n                }\n            }\n            if (options.grid.coloredAreas)\n                options.grid.markings = options.grid.coloredAreas;\n            if (options.grid.coloredAreasColor)\n                options.grid.markingsColor = options.grid.coloredAreasColor;\n            if (options.lines)\n                $.extend(true, options.series.lines, options.lines);\n            if (options.points)\n                $.extend(true, options.series.points, options.points);\n            if (options.bars)\n                $.extend(true, options.series.bars, options.bars);\n            if (options.shadowSize != null)\n                options.series.shadowSize = options.shadowSize;\n            if (options.highlightColor != null)\n                options.series.highlightColor = options.highlightColor;\n\n            // save options on axes for future reference\n            for (i = 0; i < options.xaxes.length; ++i)\n                getOrCreateAxis(xaxes, i + 1).options = options.xaxes[i];\n            for (i = 0; i < options.yaxes.length; ++i)\n                getOrCreateAxis(yaxes, i + 1).options = options.yaxes[i];\n\n            // add hooks from options\n            for (var n in hooks)\n                if (options.hooks[n] && options.hooks[n].length)\n                    hooks[n] = hooks[n].concat(options.hooks[n]);\n\n            executeHooks(hooks.processOptions, [options]);\n        }\n\n        function setData(d) {\n            series = parseData(d);\n            fillInSeriesOptions();\n            processData();\n        }\n\n        function parseData(d) {\n            var res = [];\n            for (var i = 0; i < d.length; ++i) {\n                var s = $.extend(true, {}, options.series);\n\n                if (d[i].data != null) {\n                    s.data = d[i].data; // move the data instead of deep-copy\n                    delete d[i].data;\n\n                    $.extend(true, s, d[i]);\n\n                    d[i].data = s.data;\n                }\n                else\n                    s.data = d[i];\n                res.push(s);\n            }\n\n            return res;\n        }\n\n        function axisNumber(obj, coord) {\n            var a = obj[coord + \"axis\"];\n            if (typeof a == \"object\") // if we got a real axis, extract number\n                a = a.n;\n            if (typeof a != \"number\")\n                a = 1; // default to first axis\n            return a;\n        }\n\n        function allAxes() {\n            // return flat array without annoying null entries\n            return $.grep(xaxes.concat(yaxes), function (a) { return a; });\n        }\n\n        function canvasToAxisCoords(pos) {\n            // return an object with x/y corresponding to all used axes\n            var res = {}, i, axis;\n            for (i = 0; i < xaxes.length; ++i) {\n                axis = xaxes[i];\n                if (axis && axis.used)\n                    res[\"x\" + axis.n] = axis.c2p(pos.left);\n            }\n\n            for (i = 0; i < yaxes.length; ++i) {\n                axis = yaxes[i];\n                if (axis && axis.used)\n                    res[\"y\" + axis.n] = axis.c2p(pos.top);\n            }\n\n            if (res.x1 !== undefined)\n                res.x = res.x1;\n            if (res.y1 !== undefined)\n                res.y = res.y1;\n\n            return res;\n        }\n\n        function axisToCanvasCoords(pos) {\n            // get canvas coords from the first pair of x/y found in pos\n            var res = {}, i, axis, key;\n\n            for (i = 0; i < xaxes.length; ++i) {\n                axis = xaxes[i];\n                if (axis && axis.used) {\n                    key = \"x\" + axis.n;\n                    if (pos[key] == null && axis.n == 1)\n                        key = \"x\";\n\n                    if (pos[key] != null) {\n                        res.left = axis.p2c(pos[key]);\n                        break;\n                    }\n                }\n            }\n\n            for (i = 0; i < yaxes.length; ++i) {\n                axis = yaxes[i];\n                if (axis && axis.used) {\n                    key = \"y\" + axis.n;\n                    if (pos[key] == null && axis.n == 1)\n                        key = \"y\";\n\n                    if (pos[key] != null) {\n                        res.top = axis.p2c(pos[key]);\n                        break;\n                    }\n                }\n            }\n\n            return res;\n        }\n\n        function getOrCreateAxis(axes, number) {\n            if (!axes[number - 1])\n                axes[number - 1] = {\n                    n: number, // save the number for future reference\n                    direction: axes == xaxes ? \"x\" : \"y\",\n                    options: $.extend(true, {}, axes == xaxes ? options.xaxis : options.yaxis)\n                };\n\n            return axes[number - 1];\n        }\n\n        function fillInSeriesOptions() {\n\n            var neededColors = series.length, maxIndex = -1, i;\n\n            // Subtract the number of series that already have fixed colors or\n            // color indexes from the number that we still need to generate.\n\n            for (i = 0; i < series.length; ++i) {\n                var sc = series[i].color;\n                if (sc != null) {\n                    neededColors--;\n                    if (typeof sc == \"number\" && sc > maxIndex) {\n                        maxIndex = sc;\n                    }\n                }\n            }\n\n            // If any of the series have fixed color indexes, then we need to\n            // generate at least as many colors as the highest index.\n\n            if (neededColors <= maxIndex) {\n                neededColors = maxIndex + 1;\n            }\n\n            // Generate all the colors, using first the option colors and then\n            // variations on those colors once they're exhausted.\n\n            var c, colors = [], colorPool = options.colors,\n                colorPoolSize = colorPool.length, variation = 0;\n\n            for (i = 0; i < neededColors; i++) {\n\n                c = $.color.parse(colorPool[i % colorPoolSize] || \"#666\");\n\n                // Each time we exhaust the colors in the pool we adjust\n                // a scaling factor used to produce more variations on\n                // those colors. The factor alternates negative/positive\n                // to produce lighter/darker colors.\n\n                // Reset the variation after every few cycles, or else\n                // it will end up producing only white or black colors.\n\n                if (i % colorPoolSize == 0 && i) {\n                    if (variation >= 0) {\n                        if (variation < 0.5) {\n                            variation = -variation - 0.2;\n                        } else variation = 0;\n                    } else variation = -variation;\n                }\n\n                colors[i] = c.scale('rgb', 1 + variation);\n            }\n\n            // Finalize the series options, filling in their colors\n\n            var colori = 0, s;\n            for (i = 0; i < series.length; ++i) {\n                s = series[i];\n\n                // assign colors\n                if (s.color == null) {\n                    s.color = colors[colori].toString();\n                    ++colori;\n                }\n                else if (typeof s.color == \"number\")\n                    s.color = colors[s.color].toString();\n\n                // turn on lines automatically in case nothing is set\n                if (s.lines.show == null) {\n                    var v, show = true;\n                    for (v in s)\n                        if (s[v] && s[v].show) {\n                            show = false;\n                            break;\n                        }\n                    if (show)\n                        s.lines.show = true;\n                }\n\n                // If nothing was provided for lines.zero, default it to match\n                // lines.fill, since areas by default should extend to zero.\n\n                if (s.lines.zero == null) {\n                    s.lines.zero = !!s.lines.fill;\n                }\n\n                // setup axes\n                s.xaxis = getOrCreateAxis(xaxes, axisNumber(s, \"x\"));\n                s.yaxis = getOrCreateAxis(yaxes, axisNumber(s, \"y\"));\n            }\n        }\n\n        function processData() {\n            var topSentry = Number.POSITIVE_INFINITY,\n                bottomSentry = Number.NEGATIVE_INFINITY,\n                fakeInfinity = Number.MAX_VALUE,\n                i, j, k, m, length,\n                s, points, ps, x, y, axis, val, f, p,\n                data, format;\n\n            function updateAxis(axis, min, max) {\n                if (min < axis.datamin && min != -fakeInfinity)\n                    axis.datamin = min;\n                if (max > axis.datamax && max != fakeInfinity)\n                    axis.datamax = max;\n            }\n\n            $.each(allAxes(), function (_, axis) {\n                // init axis\n                axis.datamin = topSentry;\n                axis.datamax = bottomSentry;\n                axis.used = false;\n            });\n\n            for (i = 0; i < series.length; ++i) {\n                s = series[i];\n                s.datapoints = { points: [] };\n\n                executeHooks(hooks.processRawData, [ s, s.data, s.datapoints ]);\n            }\n\n            // first pass: clean and copy data\n            for (i = 0; i < series.length; ++i) {\n                s = series[i];\n\n                data = s.data;\n                format = s.datapoints.format;\n\n                if (!format) {\n                    format = [];\n                    // find out how to copy\n                    format.push({ x: true, number: true, required: true });\n                    format.push({ y: true, number: true, required: true });\n\n                    if (s.bars.show || (s.lines.show && s.lines.fill)) {\n                        var autoscale = !!((s.bars.show && s.bars.zero) || (s.lines.show && s.lines.zero));\n                        format.push({ y: true, number: true, required: false, defaultValue: 0, autoscale: autoscale });\n                        if (s.bars.horizontal) {\n                            delete format[format.length - 1].y;\n                            format[format.length - 1].x = true;\n                        }\n                    }\n\n                    s.datapoints.format = format;\n                }\n\n                if (s.datapoints.pointsize != null)\n                    continue; // already filled in\n\n                s.datapoints.pointsize = format.length;\n\n                ps = s.datapoints.pointsize;\n                points = s.datapoints.points;\n\n                var insertSteps = s.lines.show && s.lines.steps;\n                s.xaxis.used = s.yaxis.used = true;\n\n                for (j = k = 0; j < data.length; ++j, k += ps) {\n                    p = data[j];\n\n                    var nullify = p == null;\n                    if (!nullify) {\n                        for (m = 0; m < ps; ++m) {\n                            val = p[m];\n                            f = format[m];\n\n                            if (f) {\n                                if (f.number && val != null) {\n                                    val = +val; // convert to number\n                                    if (isNaN(val))\n                                        val = null;\n                                    else if (val == Infinity)\n                                        val = fakeInfinity;\n                                    else if (val == -Infinity)\n                                        val = -fakeInfinity;\n                                }\n\n                                if (val == null) {\n                                    if (f.required)\n                                        nullify = true;\n\n                                    if (f.defaultValue != null)\n                                        val = f.defaultValue;\n                                }\n                            }\n\n                            points[k + m] = val;\n                        }\n                    }\n\n                    if (nullify) {\n                        for (m = 0; m < ps; ++m) {\n                            val = points[k + m];\n                            if (val != null) {\n                                f = format[m];\n                                // extract min/max info\n                                if (f.autoscale !== false) {\n                                    if (f.x) {\n                                        updateAxis(s.xaxis, val, val);\n                                    }\n                                    if (f.y) {\n                                        updateAxis(s.yaxis, val, val);\n                                    }\n                                }\n                            }\n                            points[k + m] = null;\n                        }\n                    }\n                    else {\n                        // a little bit of line specific stuff that\n                        // perhaps shouldn't be here, but lacking\n                        // better means...\n                        if (insertSteps && k > 0\n                            && points[k - ps] != null\n                            && points[k - ps] != points[k]\n                            && points[k - ps + 1] != points[k + 1]) {\n                            // copy the point to make room for a middle point\n                            for (m = 0; m < ps; ++m)\n                                points[k + ps + m] = points[k + m];\n\n                            // middle point has same y\n                            points[k + 1] = points[k - ps + 1];\n\n                            // we've added a point, better reflect that\n                            k += ps;\n                        }\n                    }\n                }\n            }\n\n            // give the hooks a chance to run\n            for (i = 0; i < series.length; ++i) {\n                s = series[i];\n\n                executeHooks(hooks.processDatapoints, [ s, s.datapoints]);\n            }\n\n            // second pass: find datamax/datamin for auto-scaling\n            for (i = 0; i < series.length; ++i) {\n                s = series[i];\n                points = s.datapoints.points;\n                ps = s.datapoints.pointsize;\n                format = s.datapoints.format;\n\n                var xmin = topSentry, ymin = topSentry,\n                    xmax = bottomSentry, ymax = bottomSentry;\n\n                for (j = 0; j < points.length; j += ps) {\n                    if (points[j] == null)\n                        continue;\n\n                    for (m = 0; m < ps; ++m) {\n                        val = points[j + m];\n                        f = format[m];\n                        if (!f || f.autoscale === false || val == fakeInfinity || val == -fakeInfinity)\n                            continue;\n\n                        if (f.x) {\n                            if (val < xmin)\n                                xmin = val;\n                            if (val > xmax)\n                                xmax = val;\n                        }\n                        if (f.y) {\n                            if (val < ymin)\n                                ymin = val;\n                            if (val > ymax)\n                                ymax = val;\n                        }\n                    }\n                }\n\n                if (s.bars.show) {\n                    // make sure we got room for the bar on the dancing floor\n                    var delta;\n\n                    switch (s.bars.align) {\n                        case \"left\":\n                            delta = 0;\n                            break;\n                        case \"right\":\n                            delta = -s.bars.barWidth;\n                            break;\n                        default:\n                            delta = -s.bars.barWidth / 2;\n                    }\n\n                    if (s.bars.horizontal) {\n                        ymin += delta;\n                        ymax += delta + s.bars.barWidth;\n                    }\n                    else {\n                        xmin += delta;\n                        xmax += delta + s.bars.barWidth;\n                    }\n                }\n\n                updateAxis(s.xaxis, xmin, xmax);\n                updateAxis(s.yaxis, ymin, ymax);\n            }\n\n            $.each(allAxes(), function (_, axis) {\n                if (axis.datamin == topSentry)\n                    axis.datamin = null;\n                if (axis.datamax == bottomSentry)\n                    axis.datamax = null;\n            });\n        }\n\n        function setupCanvases() {\n\n            // Make sure the placeholder is clear of everything except canvases\n            // from a previous plot in this container that we'll try to re-use.\n\n            placeholder.css(\"padding\", 0) // padding messes up the positioning\n                .children().filter(function(){\n                    return !$(this).hasClass(\"flot-overlay\") && !$(this).hasClass('flot-base');\n                }).remove();\n\n            if (placeholder.css(\"position\") == 'static')\n                placeholder.css(\"position\", \"relative\"); // for positioning labels and overlay\n\n            surface = new Canvas(\"flot-base\", placeholder);\n            overlay = new Canvas(\"flot-overlay\", placeholder); // overlay canvas for interactive features\n\n            ctx = surface.context;\n            octx = overlay.context;\n\n            // define which element we're listening for events on\n            eventHolder = $(overlay.element).unbind();\n\n            // If we're re-using a plot object, shut down the old one\n\n            var existing = placeholder.data(\"plot\");\n\n            if (existing) {\n                existing.shutdown();\n                overlay.clear();\n            }\n\n            // save in case we get replotted\n            placeholder.data(\"plot\", plot);\n        }\n\n        function bindEvents() {\n            // bind events\n            if (options.grid.hoverable) {\n                eventHolder.mousemove(onMouseMove);\n\n                // Use bind, rather than .mouseleave, because we officially\n                // still support jQuery 1.2.6, which doesn't define a shortcut\n                // for mouseenter or mouseleave.  This was a bug/oversight that\n                // was fixed somewhere around 1.3.x.  We can return to using\n                // .mouseleave when we drop support for 1.2.6.\n\n                eventHolder.bind(\"mouseleave\", onMouseLeave);\n            }\n\n            if (options.grid.clickable)\n                eventHolder.click(onClick);\n\n            executeHooks(hooks.bindEvents, [eventHolder]);\n        }\n\n        function shutdown() {\n            if (redrawTimeout)\n                clearTimeout(redrawTimeout);\n\n            eventHolder.unbind(\"mousemove\", onMouseMove);\n            eventHolder.unbind(\"mouseleave\", onMouseLeave);\n            eventHolder.unbind(\"click\", onClick);\n\n            executeHooks(hooks.shutdown, [eventHolder]);\n        }\n\n        function setTransformationHelpers(axis) {\n            // set helper functions on the axis, assumes plot area\n            // has been computed already\n\n            function identity(x) { return x; }\n\n            var s, m, t = axis.options.transform || identity,\n                it = axis.options.inverseTransform;\n\n            // precompute how much the axis is scaling a point\n            // in canvas space\n            if (axis.direction == \"x\") {\n                s = axis.scale = plotWidth / Math.abs(t(axis.max) - t(axis.min));\n                m = Math.min(t(axis.max), t(axis.min));\n            }\n            else {\n                s = axis.scale = plotHeight / Math.abs(t(axis.max) - t(axis.min));\n                s = -s;\n                m = Math.max(t(axis.max), t(axis.min));\n            }\n\n            // data point to canvas coordinate\n            if (t == identity) // slight optimization\n                axis.p2c = function (p) { return (p - m) * s; };\n            else\n                axis.p2c = function (p) { return (t(p) - m) * s; };\n            // canvas coordinate to data point\n            if (!it)\n                axis.c2p = function (c) { return m + c / s; };\n            else\n                axis.c2p = function (c) { return it(m + c / s); };\n        }\n\n        function measureTickLabels(axis) {\n\n            var opts = axis.options,\n                ticks = axis.ticks || [],\n                labelWidth = opts.labelWidth || 0,\n                labelHeight = opts.labelHeight || 0,\n                maxWidth = labelWidth || (axis.direction == \"x\" ? Math.floor(surface.width / (ticks.length || 1)) : null),\n                legacyStyles = axis.direction + \"Axis \" + axis.direction + axis.n + \"Axis\",\n                layer = \"flot-\" + axis.direction + \"-axis flot-\" + axis.direction + axis.n + \"-axis \" + legacyStyles,\n                font = opts.font || \"flot-tick-label tickLabel\";\n\n            for (var i = 0; i < ticks.length; ++i) {\n\n                var t = ticks[i];\n\n                if (!t.label)\n                    continue;\n\n                var info = surface.getTextInfo(layer, t.label, font, null, maxWidth);\n\n                labelWidth = Math.max(labelWidth, info.width);\n                labelHeight = Math.max(labelHeight, info.height);\n            }\n\n            axis.labelWidth = opts.labelWidth || labelWidth;\n            axis.labelHeight = opts.labelHeight || labelHeight;\n        }\n\n        function allocateAxisBoxFirstPhase(axis) {\n            // find the bounding box of the axis by looking at label\n            // widths/heights and ticks, make room by diminishing the\n            // plotOffset; this first phase only looks at one\n            // dimension per axis, the other dimension depends on the\n            // other axes so will have to wait\n\n            var lw = axis.labelWidth,\n                lh = axis.labelHeight,\n                pos = axis.options.position,\n                isXAxis = axis.direction === \"x\",\n                tickLength = axis.options.tickLength,\n                axisMargin = options.grid.axisMargin,\n                padding = options.grid.labelMargin,\n                innermost = true,\n                outermost = true,\n                first = true,\n                found = false;\n\n            // Determine the axis's position in its direction and on its side\n\n            $.each(isXAxis ? xaxes : yaxes, function(i, a) {\n                if (a && (a.show || a.reserveSpace)) {\n                    if (a === axis) {\n                        found = true;\n                    } else if (a.options.position === pos) {\n                        if (found) {\n                            outermost = false;\n                        } else {\n                            innermost = false;\n                        }\n                    }\n                    if (!found) {\n                        first = false;\n                    }\n                }\n            });\n\n            // The outermost axis on each side has no margin\n\n            if (outermost) {\n                axisMargin = 0;\n            }\n\n            // The ticks for the first axis in each direction stretch across\n\n            if (tickLength == null) {\n                tickLength = first ? \"full\" : 5;\n            }\n\n            if (!isNaN(+tickLength))\n                padding += +tickLength;\n\n            if (isXAxis) {\n                lh += padding;\n\n                if (pos == \"bottom\") {\n                    plotOffset.bottom += lh + axisMargin;\n                    axis.box = { top: surface.height - plotOffset.bottom, height: lh };\n                }\n                else {\n                    axis.box = { top: plotOffset.top + axisMargin, height: lh };\n                    plotOffset.top += lh + axisMargin;\n                }\n            }\n            else {\n                lw += padding;\n\n                if (pos == \"left\") {\n                    axis.box = { left: plotOffset.left + axisMargin, width: lw };\n                    plotOffset.left += lw + axisMargin;\n                }\n                else {\n                    plotOffset.right += lw + axisMargin;\n                    axis.box = { left: surface.width - plotOffset.right, width: lw };\n                }\n            }\n\n             // save for future reference\n            axis.position = pos;\n            axis.tickLength = tickLength;\n            axis.box.padding = padding;\n            axis.innermost = innermost;\n        }\n\n        function allocateAxisBoxSecondPhase(axis) {\n            // now that all axis boxes have been placed in one\n            // dimension, we can set the remaining dimension coordinates\n            if (axis.direction == \"x\") {\n                axis.box.left = plotOffset.left - axis.labelWidth / 2;\n                axis.box.width = surface.width - plotOffset.left - plotOffset.right + axis.labelWidth;\n            }\n            else {\n                axis.box.top = plotOffset.top - axis.labelHeight / 2;\n                axis.box.height = surface.height - plotOffset.bottom - plotOffset.top + axis.labelHeight;\n            }\n        }\n\n        function adjustLayoutForThingsStickingOut() {\n            // possibly adjust plot offset to ensure everything stays\n            // inside the canvas and isn't clipped off\n\n            var minMargin = options.grid.minBorderMargin,\n                axis, i;\n\n            // check stuff from the plot (FIXME: this should just read\n            // a value from the series, otherwise it's impossible to\n            // customize)\n            if (minMargin == null) {\n                minMargin = 0;\n                for (i = 0; i < series.length; ++i)\n                    minMargin = Math.max(minMargin, 2 * (series[i].points.radius + series[i].points.lineWidth/2));\n            }\n\n            var margins = {\n                left: minMargin,\n                right: minMargin,\n                top: minMargin,\n                bottom: minMargin\n            };\n\n            // check axis labels, note we don't check the actual\n            // labels but instead use the overall width/height to not\n            // jump as much around with replots\n            $.each(allAxes(), function (_, axis) {\n                if (axis.reserveSpace && axis.ticks && axis.ticks.length) {\n                    if (axis.direction === \"x\") {\n                        margins.left = Math.max(margins.left, axis.labelWidth / 2);\n                        margins.right = Math.max(margins.right, axis.labelWidth / 2);\n                    } else {\n                        margins.bottom = Math.max(margins.bottom, axis.labelHeight / 2);\n                        margins.top = Math.max(margins.top, axis.labelHeight / 2);\n                    }\n                }\n            });\n\n            plotOffset.left = Math.ceil(Math.max(margins.left, plotOffset.left));\n            plotOffset.right = Math.ceil(Math.max(margins.right, plotOffset.right));\n            plotOffset.top = Math.ceil(Math.max(margins.top, plotOffset.top));\n            plotOffset.bottom = Math.ceil(Math.max(margins.bottom, plotOffset.bottom));\n        }\n\n        function setupGrid() {\n            var i, axes = allAxes(), showGrid = options.grid.show;\n\n            // Initialize the plot's offset from the edge of the canvas\n\n            for (var a in plotOffset) {\n                var margin = options.grid.margin || 0;\n                plotOffset[a] = typeof margin == \"number\" ? margin : margin[a] || 0;\n            }\n\n            executeHooks(hooks.processOffset, [plotOffset]);\n\n            // If the grid is visible, add its border width to the offset\n\n            for (var a in plotOffset) {\n                if(typeof(options.grid.borderWidth) == \"object\") {\n                    plotOffset[a] += showGrid ? options.grid.borderWidth[a] : 0;\n                }\n                else {\n                    plotOffset[a] += showGrid ? options.grid.borderWidth : 0;\n                }\n            }\n\n            $.each(axes, function (_, axis) {\n                var axisOpts = axis.options;\n                axis.show = axisOpts.show == null ? axis.used : axisOpts.show;\n                axis.reserveSpace = axisOpts.reserveSpace == null ? axis.show : axisOpts.reserveSpace;\n                setRange(axis);\n            });\n\n            if (showGrid) {\n\n                var allocatedAxes = $.grep(axes, function (axis) {\n                    return axis.show || axis.reserveSpace;\n                });\n\n                $.each(allocatedAxes, function (_, axis) {\n                    // make the ticks\n                    setupTickGeneration(axis);\n                    setTicks(axis);\n                    snapRangeToTicks(axis, axis.ticks);\n                    // find labelWidth/Height for axis\n                    measureTickLabels(axis);\n                });\n\n                // with all dimensions calculated, we can compute the\n                // axis bounding boxes, start from the outside\n                // (reverse order)\n                for (i = allocatedAxes.length - 1; i >= 0; --i)\n                    allocateAxisBoxFirstPhase(allocatedAxes[i]);\n\n                // make sure we've got enough space for things that\n                // might stick out\n                adjustLayoutForThingsStickingOut();\n\n                $.each(allocatedAxes, function (_, axis) {\n                    allocateAxisBoxSecondPhase(axis);\n                });\n            }\n\n            plotWidth = surface.width - plotOffset.left - plotOffset.right;\n            plotHeight = surface.height - plotOffset.bottom - plotOffset.top;\n\n            // now we got the proper plot dimensions, we can compute the scaling\n            $.each(axes, function (_, axis) {\n                setTransformationHelpers(axis);\n            });\n\n            if (showGrid) {\n                drawAxisLabels();\n            }\n\n            insertLegend();\n        }\n\n        function setRange(axis) {\n            var opts = axis.options,\n                min = +(opts.min != null ? opts.min : axis.datamin),\n                max = +(opts.max != null ? opts.max : axis.datamax),\n                delta = max - min;\n\n            if (delta == 0.0) {\n                // degenerate case\n                var widen = max == 0 ? 1 : 0.01;\n\n                if (opts.min == null)\n                    min -= widen;\n                // always widen max if we couldn't widen min to ensure we\n                // don't fall into min == max which doesn't work\n                if (opts.max == null || opts.min != null)\n                    max += widen;\n            }\n            else {\n                // consider autoscaling\n                var margin = opts.autoscaleMargin;\n                if (margin != null) {\n                    if (opts.min == null) {\n                        min -= delta * margin;\n                        // make sure we don't go below zero if all values\n                        // are positive\n                        if (min < 0 && axis.datamin != null && axis.datamin >= 0)\n                            min = 0;\n                    }\n                    if (opts.max == null) {\n                        max += delta * margin;\n                        if (max > 0 && axis.datamax != null && axis.datamax <= 0)\n                            max = 0;\n                    }\n                }\n            }\n            axis.min = min;\n            axis.max = max;\n        }\n\n        function setupTickGeneration(axis) {\n            var opts = axis.options;\n\n            // estimate number of ticks\n            var noTicks;\n            if (typeof opts.ticks == \"number\" && opts.ticks > 0)\n                noTicks = opts.ticks;\n            else\n                // heuristic based on the model a*sqrt(x) fitted to\n                // some data points that seemed reasonable\n                noTicks = 0.3 * Math.sqrt(axis.direction == \"x\" ? surface.width : surface.height);\n\n            var delta = (axis.max - axis.min) / noTicks,\n                dec = -Math.floor(Math.log(delta) / Math.LN10),\n                maxDec = opts.tickDecimals;\n\n            if (maxDec != null && dec > maxDec) {\n                dec = maxDec;\n            }\n\n            var magn = Math.pow(10, -dec),\n                norm = delta / magn, // norm is between 1.0 and 10.0\n                size;\n\n            if (norm < 1.5) {\n                size = 1;\n            } else if (norm < 3) {\n                size = 2;\n                // special case for 2.5, requires an extra decimal\n                if (norm > 2.25 && (maxDec == null || dec + 1 <= maxDec)) {\n                    size = 2.5;\n                    ++dec;\n                }\n            } else if (norm < 7.5) {\n                size = 5;\n            } else {\n                size = 10;\n            }\n\n            size *= magn;\n\n            if (opts.minTickSize != null && size < opts.minTickSize) {\n                size = opts.minTickSize;\n            }\n\n            axis.delta = delta;\n            axis.tickDecimals = Math.max(0, maxDec != null ? maxDec : dec);\n            axis.tickSize = opts.tickSize || size;\n\n            // Time mode was moved to a plug-in in 0.8, and since so many people use it\n            // we'll add an especially friendly reminder to make sure they included it.\n\n            if (opts.mode == \"time\" && !axis.tickGenerator) {\n                throw new Error(\"Time mode requires the flot.time plugin.\");\n            }\n\n            // Flot supports base-10 axes; any other mode else is handled by a plug-in,\n            // like flot.time.js.\n\n            if (!axis.tickGenerator) {\n\n                axis.tickGenerator = function (axis) {\n\n                    var ticks = [],\n                        start = floorInBase(axis.min, axis.tickSize),\n                        i = 0,\n                        v = Number.NaN,\n                        prev;\n\n                    do {\n                        prev = v;\n                        v = start + i * axis.tickSize;\n                        ticks.push(v);\n                        ++i;\n                    } while (v < axis.max && v != prev);\n                    return ticks;\n                };\n\n\t\t\t\taxis.tickFormatter = function (value, axis) {\n\n\t\t\t\t\tvar factor = axis.tickDecimals ? Math.pow(10, axis.tickDecimals) : 1;\n\t\t\t\t\tvar formatted = \"\" + Math.round(value * factor) / factor;\n\n\t\t\t\t\t// If tickDecimals was specified, ensure that we have exactly that\n\t\t\t\t\t// much precision; otherwise default to the value's own precision.\n\n\t\t\t\t\tif (axis.tickDecimals != null) {\n\t\t\t\t\t\tvar decimal = formatted.indexOf(\".\");\n\t\t\t\t\t\tvar precision = decimal == -1 ? 0 : formatted.length - decimal - 1;\n\t\t\t\t\t\tif (precision < axis.tickDecimals) {\n\t\t\t\t\t\t\treturn (precision ? formatted : formatted + \".\") + (\"\" + factor).substr(1, axis.tickDecimals - precision);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n                    return formatted;\n                };\n            }\n\n            if ($.isFunction(opts.tickFormatter))\n                axis.tickFormatter = function (v, axis) { return \"\" + opts.tickFormatter(v, axis); };\n\n            if (opts.alignTicksWithAxis != null) {\n                var otherAxis = (axis.direction == \"x\" ? xaxes : yaxes)[opts.alignTicksWithAxis - 1];\n                if (otherAxis && otherAxis.used && otherAxis != axis) {\n                    // consider snapping min/max to outermost nice ticks\n                    var niceTicks = axis.tickGenerator(axis);\n                    if (niceTicks.length > 0) {\n                        if (opts.min == null)\n                            axis.min = Math.min(axis.min, niceTicks[0]);\n                        if (opts.max == null && niceTicks.length > 1)\n                            axis.max = Math.max(axis.max, niceTicks[niceTicks.length - 1]);\n                    }\n\n                    axis.tickGenerator = function (axis) {\n                        // copy ticks, scaled to this axis\n                        var ticks = [], v, i;\n                        for (i = 0; i < otherAxis.ticks.length; ++i) {\n                            v = (otherAxis.ticks[i].v - otherAxis.min) / (otherAxis.max - otherAxis.min);\n                            v = axis.min + v * (axis.max - axis.min);\n                            ticks.push(v);\n                        }\n                        return ticks;\n                    };\n\n                    // we might need an extra decimal since forced\n                    // ticks don't necessarily fit naturally\n                    if (!axis.mode && opts.tickDecimals == null) {\n                        var extraDec = Math.max(0, -Math.floor(Math.log(axis.delta) / Math.LN10) + 1),\n                            ts = axis.tickGenerator(axis);\n\n                        // only proceed if the tick interval rounded\n                        // with an extra decimal doesn't give us a\n                        // zero at end\n                        if (!(ts.length > 1 && /\\..*0$/.test((ts[1] - ts[0]).toFixed(extraDec))))\n                            axis.tickDecimals = extraDec;\n                    }\n                }\n            }\n        }\n\n        function setTicks(axis) {\n            var oticks = axis.options.ticks, ticks = [];\n            if (oticks == null || (typeof oticks == \"number\" && oticks > 0))\n                ticks = axis.tickGenerator(axis);\n            else if (oticks) {\n                if ($.isFunction(oticks))\n                    // generate the ticks\n                    ticks = oticks(axis);\n                else\n                    ticks = oticks;\n            }\n\n            // clean up/labelify the supplied ticks, copy them over\n            var i, v;\n            axis.ticks = [];\n            for (i = 0; i < ticks.length; ++i) {\n                var label = null;\n                var t = ticks[i];\n                if (typeof t == \"object\") {\n                    v = +t[0];\n                    if (t.length > 1)\n                        label = t[1];\n                }\n                else\n                    v = +t;\n                if (label == null)\n                    label = axis.tickFormatter(v, axis);\n                if (!isNaN(v))\n                    axis.ticks.push({ v: v, label: label });\n            }\n        }\n\n        function snapRangeToTicks(axis, ticks) {\n            if (axis.options.autoscaleMargin && ticks.length > 0) {\n                // snap to ticks\n                if (axis.options.min == null)\n                    axis.min = Math.min(axis.min, ticks[0].v);\n                if (axis.options.max == null && ticks.length > 1)\n                    axis.max = Math.max(axis.max, ticks[ticks.length - 1].v);\n            }\n        }\n\n        function draw() {\n\n            surface.clear();\n\n            executeHooks(hooks.drawBackground, [ctx]);\n\n            var grid = options.grid;\n\n            // draw background, if any\n            if (grid.show && grid.backgroundColor)\n                drawBackground();\n\n            if (grid.show && !grid.aboveData) {\n                drawGrid();\n            }\n\n            for (var i = 0; i < series.length; ++i) {\n                executeHooks(hooks.drawSeries, [ctx, series[i]]);\n                drawSeries(series[i]);\n            }\n\n            executeHooks(hooks.draw, [ctx]);\n\n            if (grid.show && grid.aboveData) {\n                drawGrid();\n            }\n\n            surface.render();\n\n            // A draw implies that either the axes or data have changed, so we\n            // should probably update the overlay highlights as well.\n\n            triggerRedrawOverlay();\n        }\n\n        function extractRange(ranges, coord) {\n            var axis, from, to, key, axes = allAxes();\n\n            for (var i = 0; i < axes.length; ++i) {\n                axis = axes[i];\n                if (axis.direction == coord) {\n                    key = coord + axis.n + \"axis\";\n                    if (!ranges[key] && axis.n == 1)\n                        key = coord + \"axis\"; // support x1axis as xaxis\n                    if (ranges[key]) {\n                        from = ranges[key].from;\n                        to = ranges[key].to;\n                        break;\n                    }\n                }\n            }\n\n            // backwards-compat stuff - to be removed in future\n            if (!ranges[key]) {\n                axis = coord == \"x\" ? xaxes[0] : yaxes[0];\n                from = ranges[coord + \"1\"];\n                to = ranges[coord + \"2\"];\n            }\n\n            // auto-reverse as an added bonus\n            if (from != null && to != null && from > to) {\n                var tmp = from;\n                from = to;\n                to = tmp;\n            }\n\n            return { from: from, to: to, axis: axis };\n        }\n\n        function drawBackground() {\n            ctx.save();\n            ctx.translate(plotOffset.left, plotOffset.top);\n\n            ctx.fillStyle = getColorOrGradient(options.grid.backgroundColor, plotHeight, 0, \"rgba(255, 255, 255, 0)\");\n            ctx.fillRect(0, 0, plotWidth, plotHeight);\n            ctx.restore();\n        }\n\n        function drawGrid() {\n            var i, axes, bw, bc;\n\n            ctx.save();\n            ctx.translate(plotOffset.left, plotOffset.top);\n\n            // draw markings\n            var markings = options.grid.markings;\n            if (markings) {\n                if ($.isFunction(markings)) {\n                    axes = plot.getAxes();\n                    // xmin etc. is backwards compatibility, to be\n                    // removed in the future\n                    axes.xmin = axes.xaxis.min;\n                    axes.xmax = axes.xaxis.max;\n                    axes.ymin = axes.yaxis.min;\n                    axes.ymax = axes.yaxis.max;\n\n                    markings = markings(axes);\n                }\n\n                for (i = 0; i < markings.length; ++i) {\n                    var m = markings[i],\n                        xrange = extractRange(m, \"x\"),\n                        yrange = extractRange(m, \"y\");\n\n                    // fill in missing\n                    if (xrange.from == null)\n                        xrange.from = xrange.axis.min;\n                    if (xrange.to == null)\n                        xrange.to = xrange.axis.max;\n                    if (yrange.from == null)\n                        yrange.from = yrange.axis.min;\n                    if (yrange.to == null)\n                        yrange.to = yrange.axis.max;\n\n                    // clip\n                    if (xrange.to < xrange.axis.min || xrange.from > xrange.axis.max ||\n                        yrange.to < yrange.axis.min || yrange.from > yrange.axis.max)\n                        continue;\n\n                    xrange.from = Math.max(xrange.from, xrange.axis.min);\n                    xrange.to = Math.min(xrange.to, xrange.axis.max);\n                    yrange.from = Math.max(yrange.from, yrange.axis.min);\n                    yrange.to = Math.min(yrange.to, yrange.axis.max);\n\n                    var xequal = xrange.from === xrange.to,\n                        yequal = yrange.from === yrange.to;\n\n                    if (xequal && yequal) {\n                        continue;\n                    }\n\n                    // then draw\n                    xrange.from = Math.floor(xrange.axis.p2c(xrange.from));\n                    xrange.to = Math.floor(xrange.axis.p2c(xrange.to));\n                    yrange.from = Math.floor(yrange.axis.p2c(yrange.from));\n                    yrange.to = Math.floor(yrange.axis.p2c(yrange.to));\n\n                    if (xequal || yequal) {\n                        var lineWidth = m.lineWidth || options.grid.markingsLineWidth,\n                            subPixel = lineWidth % 2 ? 0.5 : 0;\n                        ctx.beginPath();\n                        ctx.strokeStyle = m.color || options.grid.markingsColor;\n                        ctx.lineWidth = lineWidth;\n                        if (xequal) {\n                            ctx.moveTo(xrange.to + subPixel, yrange.from);\n                            ctx.lineTo(xrange.to + subPixel, yrange.to);\n                        } else {\n                            ctx.moveTo(xrange.from, yrange.to + subPixel);\n                            ctx.lineTo(xrange.to, yrange.to + subPixel);                            \n                        }\n                        ctx.stroke();\n                    } else {\n                        ctx.fillStyle = m.color || options.grid.markingsColor;\n                        ctx.fillRect(xrange.from, yrange.to,\n                                     xrange.to - xrange.from,\n                                     yrange.from - yrange.to);\n                    }\n                }\n            }\n\n            // draw the ticks\n            axes = allAxes();\n            bw = options.grid.borderWidth;\n\n            for (var j = 0; j < axes.length; ++j) {\n                var axis = axes[j], box = axis.box,\n                    t = axis.tickLength, x, y, xoff, yoff;\n                if (!axis.show || axis.ticks.length == 0)\n                    continue;\n\n                ctx.lineWidth = 1;\n\n                // find the edges\n                if (axis.direction == \"x\") {\n                    x = 0;\n                    if (t == \"full\")\n                        y = (axis.position == \"top\" ? 0 : plotHeight);\n                    else\n                        y = box.top - plotOffset.top + (axis.position == \"top\" ? box.height : 0);\n                }\n                else {\n                    y = 0;\n                    if (t == \"full\")\n                        x = (axis.position == \"left\" ? 0 : plotWidth);\n                    else\n                        x = box.left - plotOffset.left + (axis.position == \"left\" ? box.width : 0);\n                }\n\n                // draw tick bar\n                if (!axis.innermost) {\n                    ctx.strokeStyle = axis.options.color;\n                    ctx.beginPath();\n                    xoff = yoff = 0;\n                    if (axis.direction == \"x\")\n                        xoff = plotWidth + 1;\n                    else\n                        yoff = plotHeight + 1;\n\n                    if (ctx.lineWidth == 1) {\n                        if (axis.direction == \"x\") {\n                            y = Math.floor(y) + 0.5;\n                        } else {\n                            x = Math.floor(x) + 0.5;\n                        }\n                    }\n\n                    ctx.moveTo(x, y);\n                    ctx.lineTo(x + xoff, y + yoff);\n                    ctx.stroke();\n                }\n\n                // draw ticks\n\n                ctx.strokeStyle = axis.options.tickColor;\n\n                ctx.beginPath();\n                for (i = 0; i < axis.ticks.length; ++i) {\n                    var v = axis.ticks[i].v;\n\n                    xoff = yoff = 0;\n\n                    if (isNaN(v) || v < axis.min || v > axis.max\n                        // skip those lying on the axes if we got a border\n                        || (t == \"full\"\n                            && ((typeof bw == \"object\" && bw[axis.position] > 0) || bw > 0)\n                            && (v == axis.min || v == axis.max)))\n                        continue;\n\n                    if (axis.direction == \"x\") {\n                        x = axis.p2c(v);\n                        yoff = t == \"full\" ? -plotHeight : t;\n\n                        if (axis.position == \"top\")\n                            yoff = -yoff;\n                    }\n                    else {\n                        y = axis.p2c(v);\n                        xoff = t == \"full\" ? -plotWidth : t;\n\n                        if (axis.position == \"left\")\n                            xoff = -xoff;\n                    }\n\n                    if (ctx.lineWidth == 1) {\n                        if (axis.direction == \"x\")\n                            x = Math.floor(x) + 0.5;\n                        else\n                            y = Math.floor(y) + 0.5;\n                    }\n\n                    ctx.moveTo(x, y);\n                    ctx.lineTo(x + xoff, y + yoff);\n                }\n\n                ctx.stroke();\n            }\n\n\n            // draw border\n            if (bw) {\n                // If either borderWidth or borderColor is an object, then draw the border\n                // line by line instead of as one rectangle\n                bc = options.grid.borderColor;\n                if(typeof bw == \"object\" || typeof bc == \"object\") {\n                    if (typeof bw !== \"object\") {\n                        bw = {top: bw, right: bw, bottom: bw, left: bw};\n                    }\n                    if (typeof bc !== \"object\") {\n                        bc = {top: bc, right: bc, bottom: bc, left: bc};\n                    }\n\n                    if (bw.top > 0) {\n                        ctx.strokeStyle = bc.top;\n                        ctx.lineWidth = bw.top;\n                        ctx.beginPath();\n                        ctx.moveTo(0 - bw.left, 0 - bw.top/2);\n                        ctx.lineTo(plotWidth, 0 - bw.top/2);\n                        ctx.stroke();\n                    }\n\n                    if (bw.right > 0) {\n                        ctx.strokeStyle = bc.right;\n                        ctx.lineWidth = bw.right;\n                        ctx.beginPath();\n                        ctx.moveTo(plotWidth + bw.right / 2, 0 - bw.top);\n                        ctx.lineTo(plotWidth + bw.right / 2, plotHeight);\n                        ctx.stroke();\n                    }\n\n                    if (bw.bottom > 0) {\n                        ctx.strokeStyle = bc.bottom;\n                        ctx.lineWidth = bw.bottom;\n                        ctx.beginPath();\n                        ctx.moveTo(plotWidth + bw.right, plotHeight + bw.bottom / 2);\n                        ctx.lineTo(0, plotHeight + bw.bottom / 2);\n                        ctx.stroke();\n                    }\n\n                    if (bw.left > 0) {\n                        ctx.strokeStyle = bc.left;\n                        ctx.lineWidth = bw.left;\n                        ctx.beginPath();\n                        ctx.moveTo(0 - bw.left/2, plotHeight + bw.bottom);\n                        ctx.lineTo(0- bw.left/2, 0);\n                        ctx.stroke();\n                    }\n                }\n                else {\n                    ctx.lineWidth = bw;\n                    ctx.strokeStyle = options.grid.borderColor;\n                    ctx.strokeRect(-bw/2, -bw/2, plotWidth + bw, plotHeight + bw);\n                }\n            }\n\n            ctx.restore();\n        }\n\n        function drawAxisLabels() {\n\n            $.each(allAxes(), function (_, axis) {\n                var box = axis.box,\n                    legacyStyles = axis.direction + \"Axis \" + axis.direction + axis.n + \"Axis\",\n                    layer = \"flot-\" + axis.direction + \"-axis flot-\" + axis.direction + axis.n + \"-axis \" + legacyStyles,\n                    font = axis.options.font || \"flot-tick-label tickLabel\",\n                    tick, x, y, halign, valign;\n\n                // Remove text before checking for axis.show and ticks.length;\n                // otherwise plugins, like flot-tickrotor, that draw their own\n                // tick labels will end up with both theirs and the defaults.\n\n                surface.removeText(layer);\n\n                if (!axis.show || axis.ticks.length == 0)\n                    return;\n\n                for (var i = 0; i < axis.ticks.length; ++i) {\n\n                    tick = axis.ticks[i];\n                    if (!tick.label || tick.v < axis.min || tick.v > axis.max)\n                        continue;\n\n                    if (axis.direction == \"x\") {\n                        halign = \"center\";\n                        x = plotOffset.left + axis.p2c(tick.v);\n                        if (axis.position == \"bottom\") {\n                            y = box.top + box.padding;\n                        } else {\n                            y = box.top + box.height - box.padding;\n                            valign = \"bottom\";\n                        }\n                    } else {\n                        valign = \"middle\";\n                        y = plotOffset.top + axis.p2c(tick.v);\n                        if (axis.position == \"left\") {\n                            x = box.left + box.width - box.padding;\n                            halign = \"right\";\n                        } else {\n                            x = box.left + box.padding;\n                        }\n                    }\n\n                    surface.addText(layer, x, y, tick.label, font, null, null, halign, valign);\n                }\n            });\n        }\n\n        function drawSeries(series) {\n            if (series.lines.show)\n                drawSeriesLines(series);\n            if (series.bars.show)\n                drawSeriesBars(series);\n            if (series.points.show)\n                drawSeriesPoints(series);\n        }\n\n        function drawSeriesLines(series) {\n            function plotLine(datapoints, xoffset, yoffset, axisx, axisy) {\n                var points = datapoints.points,\n                    ps = datapoints.pointsize,\n                    prevx = null, prevy = null;\n\n                ctx.beginPath();\n                for (var i = ps; i < points.length; i += ps) {\n                    var x1 = points[i - ps], y1 = points[i - ps + 1],\n                        x2 = points[i], y2 = points[i + 1];\n\n                    if (x1 == null || x2 == null)\n                        continue;\n\n                    // clip with ymin\n                    if (y1 <= y2 && y1 < axisy.min) {\n                        if (y2 < axisy.min)\n                            continue;   // line segment is outside\n                        // compute new intersection point\n                        x1 = (axisy.min - y1) / (y2 - y1) * (x2 - x1) + x1;\n                        y1 = axisy.min;\n                    }\n                    else if (y2 <= y1 && y2 < axisy.min) {\n                        if (y1 < axisy.min)\n                            continue;\n                        x2 = (axisy.min - y1) / (y2 - y1) * (x2 - x1) + x1;\n                        y2 = axisy.min;\n                    }\n\n                    // clip with ymax\n                    if (y1 >= y2 && y1 > axisy.max) {\n                        if (y2 > axisy.max)\n                            continue;\n                        x1 = (axisy.max - y1) / (y2 - y1) * (x2 - x1) + x1;\n                        y1 = axisy.max;\n                    }\n                    else if (y2 >= y1 && y2 > axisy.max) {\n                        if (y1 > axisy.max)\n                            continue;\n                        x2 = (axisy.max - y1) / (y2 - y1) * (x2 - x1) + x1;\n                        y2 = axisy.max;\n                    }\n\n                    // clip with xmin\n                    if (x1 <= x2 && x1 < axisx.min) {\n                        if (x2 < axisx.min)\n                            continue;\n                        y1 = (axisx.min - x1) / (x2 - x1) * (y2 - y1) + y1;\n                        x1 = axisx.min;\n                    }\n                    else if (x2 <= x1 && x2 < axisx.min) {\n                        if (x1 < axisx.min)\n                            continue;\n                        y2 = (axisx.min - x1) / (x2 - x1) * (y2 - y1) + y1;\n                        x2 = axisx.min;\n                    }\n\n                    // clip with xmax\n                    if (x1 >= x2 && x1 > axisx.max) {\n                        if (x2 > axisx.max)\n                            continue;\n                        y1 = (axisx.max - x1) / (x2 - x1) * (y2 - y1) + y1;\n                        x1 = axisx.max;\n                    }\n                    else if (x2 >= x1 && x2 > axisx.max) {\n                        if (x1 > axisx.max)\n                            continue;\n                        y2 = (axisx.max - x1) / (x2 - x1) * (y2 - y1) + y1;\n                        x2 = axisx.max;\n                    }\n\n                    if (x1 != prevx || y1 != prevy)\n                        ctx.moveTo(axisx.p2c(x1) + xoffset, axisy.p2c(y1) + yoffset);\n\n                    prevx = x2;\n                    prevy = y2;\n                    ctx.lineTo(axisx.p2c(x2) + xoffset, axisy.p2c(y2) + yoffset);\n                }\n                ctx.stroke();\n            }\n\n            function plotLineArea(datapoints, axisx, axisy) {\n                var points = datapoints.points,\n                    ps = datapoints.pointsize,\n                    bottom = Math.min(Math.max(0, axisy.min), axisy.max),\n                    i = 0, top, areaOpen = false,\n                    ypos = 1, segmentStart = 0, segmentEnd = 0;\n\n                // we process each segment in two turns, first forward\n                // direction to sketch out top, then once we hit the\n                // end we go backwards to sketch the bottom\n                while (true) {\n                    if (ps > 0 && i > points.length + ps)\n                        break;\n\n                    i += ps; // ps is negative if going backwards\n\n                    var x1 = points[i - ps],\n                        y1 = points[i - ps + ypos],\n                        x2 = points[i], y2 = points[i + ypos];\n\n                    if (areaOpen) {\n                        if (ps > 0 && x1 != null && x2 == null) {\n                            // at turning point\n                            segmentEnd = i;\n                            ps = -ps;\n                            ypos = 2;\n                            continue;\n                        }\n\n                        if (ps < 0 && i == segmentStart + ps) {\n                            // done with the reverse sweep\n                            ctx.fill();\n                            areaOpen = false;\n                            ps = -ps;\n                            ypos = 1;\n                            i = segmentStart = segmentEnd + ps;\n                            continue;\n                        }\n                    }\n\n                    if (x1 == null || x2 == null)\n                        continue;\n\n                    // clip x values\n\n                    // clip with xmin\n                    if (x1 <= x2 && x1 < axisx.min) {\n                        if (x2 < axisx.min)\n                            continue;\n                        y1 = (axisx.min - x1) / (x2 - x1) * (y2 - y1) + y1;\n                        x1 = axisx.min;\n                    }\n                    else if (x2 <= x1 && x2 < axisx.min) {\n                        if (x1 < axisx.min)\n                            continue;\n                        y2 = (axisx.min - x1) / (x2 - x1) * (y2 - y1) + y1;\n                        x2 = axisx.min;\n                    }\n\n                    // clip with xmax\n                    if (x1 >= x2 && x1 > axisx.max) {\n                        if (x2 > axisx.max)\n                            continue;\n                        y1 = (axisx.max - x1) / (x2 - x1) * (y2 - y1) + y1;\n                        x1 = axisx.max;\n                    }\n                    else if (x2 >= x1 && x2 > axisx.max) {\n                        if (x1 > axisx.max)\n                            continue;\n                        y2 = (axisx.max - x1) / (x2 - x1) * (y2 - y1) + y1;\n                        x2 = axisx.max;\n                    }\n\n                    if (!areaOpen) {\n                        // open area\n                        ctx.beginPath();\n                        ctx.moveTo(axisx.p2c(x1), axisy.p2c(bottom));\n                        areaOpen = true;\n                    }\n\n                    // now first check the case where both is outside\n                    if (y1 >= axisy.max && y2 >= axisy.max) {\n                        ctx.lineTo(axisx.p2c(x1), axisy.p2c(axisy.max));\n                        ctx.lineTo(axisx.p2c(x2), axisy.p2c(axisy.max));\n                        continue;\n                    }\n                    else if (y1 <= axisy.min && y2 <= axisy.min) {\n                        ctx.lineTo(axisx.p2c(x1), axisy.p2c(axisy.min));\n                        ctx.lineTo(axisx.p2c(x2), axisy.p2c(axisy.min));\n                        continue;\n                    }\n\n                    // else it's a bit more complicated, there might\n                    // be a flat maxed out rectangle first, then a\n                    // triangular cutout or reverse; to find these\n                    // keep track of the current x values\n                    var x1old = x1, x2old = x2;\n\n                    // clip the y values, without shortcutting, we\n                    // go through all cases in turn\n\n                    // clip with ymin\n                    if (y1 <= y2 && y1 < axisy.min && y2 >= axisy.min) {\n                        x1 = (axisy.min - y1) / (y2 - y1) * (x2 - x1) + x1;\n                        y1 = axisy.min;\n                    }\n                    else if (y2 <= y1 && y2 < axisy.min && y1 >= axisy.min) {\n                        x2 = (axisy.min - y1) / (y2 - y1) * (x2 - x1) + x1;\n                        y2 = axisy.min;\n                    }\n\n                    // clip with ymax\n                    if (y1 >= y2 && y1 > axisy.max && y2 <= axisy.max) {\n                        x1 = (axisy.max - y1) / (y2 - y1) * (x2 - x1) + x1;\n                        y1 = axisy.max;\n                    }\n                    else if (y2 >= y1 && y2 > axisy.max && y1 <= axisy.max) {\n                        x2 = (axisy.max - y1) / (y2 - y1) * (x2 - x1) + x1;\n                        y2 = axisy.max;\n                    }\n\n                    // if the x value was changed we got a rectangle\n                    // to fill\n                    if (x1 != x1old) {\n                        ctx.lineTo(axisx.p2c(x1old), axisy.p2c(y1));\n                        // it goes to (x1, y1), but we fill that below\n                    }\n\n                    // fill triangular section, this sometimes result\n                    // in redundant points if (x1, y1) hasn't changed\n                    // from previous line to, but we just ignore that\n                    ctx.lineTo(axisx.p2c(x1), axisy.p2c(y1));\n                    ctx.lineTo(axisx.p2c(x2), axisy.p2c(y2));\n\n                    // fill the other rectangle if it's there\n                    if (x2 != x2old) {\n                        ctx.lineTo(axisx.p2c(x2), axisy.p2c(y2));\n                        ctx.lineTo(axisx.p2c(x2old), axisy.p2c(y2));\n                    }\n                }\n            }\n\n            ctx.save();\n            ctx.translate(plotOffset.left, plotOffset.top);\n            ctx.lineJoin = \"round\";\n\n            var lw = series.lines.lineWidth,\n                sw = series.shadowSize;\n            // FIXME: consider another form of shadow when filling is turned on\n            if (lw > 0 && sw > 0) {\n                // draw shadow as a thick and thin line with transparency\n                ctx.lineWidth = sw;\n                ctx.strokeStyle = \"rgba(0,0,0,0.1)\";\n                // position shadow at angle from the mid of line\n                var angle = Math.PI/18;\n                plotLine(series.datapoints, Math.sin(angle) * (lw/2 + sw/2), Math.cos(angle) * (lw/2 + sw/2), series.xaxis, series.yaxis);\n                ctx.lineWidth = sw/2;\n                plotLine(series.datapoints, Math.sin(angle) * (lw/2 + sw/4), Math.cos(angle) * (lw/2 + sw/4), series.xaxis, series.yaxis);\n            }\n\n            ctx.lineWidth = lw;\n            ctx.strokeStyle = series.color;\n            var fillStyle = getFillStyle(series.lines, series.color, 0, plotHeight);\n            if (fillStyle) {\n                ctx.fillStyle = fillStyle;\n                plotLineArea(series.datapoints, series.xaxis, series.yaxis);\n            }\n\n            if (lw > 0)\n                plotLine(series.datapoints, 0, 0, series.xaxis, series.yaxis);\n            ctx.restore();\n        }\n\n        function drawSeriesPoints(series) {\n            function plotPoints(datapoints, radius, fillStyle, offset, shadow, axisx, axisy, symbol) {\n                var points = datapoints.points, ps = datapoints.pointsize;\n\n                for (var i = 0; i < points.length; i += ps) {\n                    var x = points[i], y = points[i + 1];\n                    if (x == null || x < axisx.min || x > axisx.max || y < axisy.min || y > axisy.max)\n                        continue;\n\n                    ctx.beginPath();\n                    x = axisx.p2c(x);\n                    y = axisy.p2c(y) + offset;\n                    if (symbol == \"circle\")\n                        ctx.arc(x, y, radius, 0, shadow ? Math.PI : Math.PI * 2, false);\n                    else\n                        symbol(ctx, x, y, radius, shadow);\n                    ctx.closePath();\n\n                    if (fillStyle) {\n                        ctx.fillStyle = fillStyle;\n                        ctx.fill();\n                    }\n                    ctx.stroke();\n                }\n            }\n\n            ctx.save();\n            ctx.translate(plotOffset.left, plotOffset.top);\n\n            var lw = series.points.lineWidth,\n                sw = series.shadowSize,\n                radius = series.points.radius,\n                symbol = series.points.symbol;\n\n            // If the user sets the line width to 0, we change it to a very \n            // small value. A line width of 0 seems to force the default of 1.\n            // Doing the conditional here allows the shadow setting to still be \n            // optional even with a lineWidth of 0.\n\n            if( lw == 0 )\n                lw = 0.0001;\n\n            if (lw > 0 && sw > 0) {\n                // draw shadow in two steps\n                var w = sw / 2;\n                ctx.lineWidth = w;\n                ctx.strokeStyle = \"rgba(0,0,0,0.1)\";\n                plotPoints(series.datapoints, radius, null, w + w/2, true,\n                           series.xaxis, series.yaxis, symbol);\n\n                ctx.strokeStyle = \"rgba(0,0,0,0.2)\";\n                plotPoints(series.datapoints, radius, null, w/2, true,\n                           series.xaxis, series.yaxis, symbol);\n            }\n\n            ctx.lineWidth = lw;\n            ctx.strokeStyle = series.color;\n            plotPoints(series.datapoints, radius,\n                       getFillStyle(series.points, series.color), 0, false,\n                       series.xaxis, series.yaxis, symbol);\n            ctx.restore();\n        }\n\n        function drawBar(x, y, b, barLeft, barRight, fillStyleCallback, axisx, axisy, c, horizontal, lineWidth) {\n            var left, right, bottom, top,\n                drawLeft, drawRight, drawTop, drawBottom,\n                tmp;\n\n            // in horizontal mode, we start the bar from the left\n            // instead of from the bottom so it appears to be\n            // horizontal rather than vertical\n            if (horizontal) {\n                drawBottom = drawRight = drawTop = true;\n                drawLeft = false;\n                left = b;\n                right = x;\n                top = y + barLeft;\n                bottom = y + barRight;\n\n                // account for negative bars\n                if (right < left) {\n                    tmp = right;\n                    right = left;\n                    left = tmp;\n                    drawLeft = true;\n                    drawRight = false;\n                }\n            }\n            else {\n                drawLeft = drawRight = drawTop = true;\n                drawBottom = false;\n                left = x + barLeft;\n                right = x + barRight;\n                bottom = b;\n                top = y;\n\n                // account for negative bars\n                if (top < bottom) {\n                    tmp = top;\n                    top = bottom;\n                    bottom = tmp;\n                    drawBottom = true;\n                    drawTop = false;\n                }\n            }\n\n            // clip\n            if (right < axisx.min || left > axisx.max ||\n                top < axisy.min || bottom > axisy.max)\n                return;\n\n            if (left < axisx.min) {\n                left = axisx.min;\n                drawLeft = false;\n            }\n\n            if (right > axisx.max) {\n                right = axisx.max;\n                drawRight = false;\n            }\n\n            if (bottom < axisy.min) {\n                bottom = axisy.min;\n                drawBottom = false;\n            }\n\n            if (top > axisy.max) {\n                top = axisy.max;\n                drawTop = false;\n            }\n\n            left = axisx.p2c(left);\n            bottom = axisy.p2c(bottom);\n            right = axisx.p2c(right);\n            top = axisy.p2c(top);\n\n            // fill the bar\n            if (fillStyleCallback) {\n                c.fillStyle = fillStyleCallback(bottom, top);\n                c.fillRect(left, top, right - left, bottom - top)\n            }\n\n            // draw outline\n            if (lineWidth > 0 && (drawLeft || drawRight || drawTop || drawBottom)) {\n                c.beginPath();\n\n                // FIXME: inline moveTo is buggy with excanvas\n                c.moveTo(left, bottom);\n                if (drawLeft)\n                    c.lineTo(left, top);\n                else\n                    c.moveTo(left, top);\n                if (drawTop)\n                    c.lineTo(right, top);\n                else\n                    c.moveTo(right, top);\n                if (drawRight)\n                    c.lineTo(right, bottom);\n                else\n                    c.moveTo(right, bottom);\n                if (drawBottom)\n                    c.lineTo(left, bottom);\n                else\n                    c.moveTo(left, bottom);\n                c.stroke();\n            }\n        }\n\n        function drawSeriesBars(series) {\n            function plotBars(datapoints, barLeft, barRight, fillStyleCallback, axisx, axisy) {\n                var points = datapoints.points, ps = datapoints.pointsize;\n\n                for (var i = 0; i < points.length; i += ps) {\n                    if (points[i] == null)\n                        continue;\n                    drawBar(points[i], points[i + 1], points[i + 2], barLeft, barRight, fillStyleCallback, axisx, axisy, ctx, series.bars.horizontal, series.bars.lineWidth);\n                }\n            }\n\n            ctx.save();\n            ctx.translate(plotOffset.left, plotOffset.top);\n\n            // FIXME: figure out a way to add shadows (for instance along the right edge)\n            ctx.lineWidth = series.bars.lineWidth;\n            ctx.strokeStyle = series.color;\n\n            var barLeft;\n\n            switch (series.bars.align) {\n                case \"left\":\n                    barLeft = 0;\n                    break;\n                case \"right\":\n                    barLeft = -series.bars.barWidth;\n                    break;\n                default:\n                    barLeft = -series.bars.barWidth / 2;\n            }\n\n            var fillStyleCallback = series.bars.fill ? function (bottom, top) { return getFillStyle(series.bars, series.color, bottom, top); } : null;\n            plotBars(series.datapoints, barLeft, barLeft + series.bars.barWidth, fillStyleCallback, series.xaxis, series.yaxis);\n            ctx.restore();\n        }\n\n        function getFillStyle(filloptions, seriesColor, bottom, top) {\n            var fill = filloptions.fill;\n            if (!fill)\n                return null;\n\n            if (filloptions.fillColor)\n                return getColorOrGradient(filloptions.fillColor, bottom, top, seriesColor);\n\n            var c = $.color.parse(seriesColor);\n            c.a = typeof fill == \"number\" ? fill : 0.4;\n            c.normalize();\n            return c.toString();\n        }\n\n        function insertLegend() {\n\n            if (options.legend.container != null) {\n                $(options.legend.container).html(\"\");\n            } else {\n                placeholder.find(\".legend\").remove();\n            }\n\n            if (!options.legend.show) {\n                return;\n            }\n\n            var fragments = [], entries = [], rowStarted = false,\n                lf = options.legend.labelFormatter, s, label;\n\n            // Build a list of legend entries, with each having a label and a color\n\n            for (var i = 0; i < series.length; ++i) {\n                s = series[i];\n                if (s.label) {\n                    label = lf ? lf(s.label, s) : s.label;\n                    if (label) {\n                        entries.push({\n                            label: label,\n                            color: s.color\n                        });\n                    }\n                }\n            }\n\n            // Sort the legend using either the default or a custom comparator\n\n            if (options.legend.sorted) {\n                if ($.isFunction(options.legend.sorted)) {\n                    entries.sort(options.legend.sorted);\n                } else if (options.legend.sorted == \"reverse\") {\n                \tentries.reverse();\n                } else {\n                    var ascending = options.legend.sorted != \"descending\";\n                    entries.sort(function(a, b) {\n                        return a.label == b.label ? 0 : (\n                            (a.label < b.label) != ascending ? 1 : -1   // Logical XOR\n                        );\n                    });\n                }\n            }\n\n            // Generate markup for the list of entries, in their final order\n\n            for (var i = 0; i < entries.length; ++i) {\n\n                var entry = entries[i];\n\n                if (i % options.legend.noColumns == 0) {\n                    if (rowStarted)\n                        fragments.push('</tr>');\n                    fragments.push('<tr>');\n                    rowStarted = true;\n                }\n\n                fragments.push(\n                    '<td class=\"legendColorBox\"><div style=\"border:1px solid ' + options.legend.labelBoxBorderColor + ';padding:1px\"><div style=\"width:4px;height:0;border:5px solid ' + entry.color + ';overflow:hidden\"></div></div></td>' +\n                    '<td class=\"legendLabel\">' + entry.label + '</td>'\n                );\n            }\n\n            if (rowStarted)\n                fragments.push('</tr>');\n\n            if (fragments.length == 0)\n                return;\n\n            var table = '<table style=\"font-size:smaller;color:' + options.grid.color + '\">' + fragments.join(\"\") + '</table>';\n            if (options.legend.container != null)\n                $(options.legend.container).html(table);\n            else {\n                var pos = \"\",\n                    p = options.legend.position,\n                    m = options.legend.margin;\n                if (m[0] == null)\n                    m = [m, m];\n                if (p.charAt(0) == \"n\")\n                    pos += 'top:' + (m[1] + plotOffset.top) + 'px;';\n                else if (p.charAt(0) == \"s\")\n                    pos += 'bottom:' + (m[1] + plotOffset.bottom) + 'px;';\n                if (p.charAt(1) == \"e\")\n                    pos += 'right:' + (m[0] + plotOffset.right) + 'px;';\n                else if (p.charAt(1) == \"w\")\n                    pos += 'left:' + (m[0] + plotOffset.left) + 'px;';\n                var legend = $('<div class=\"legend\">' + table.replace('style=\"', 'style=\"position:absolute;' + pos +';') + '</div>').appendTo(placeholder);\n                if (options.legend.backgroundOpacity != 0.0) {\n                    // put in the transparent background\n                    // separately to avoid blended labels and\n                    // label boxes\n                    var c = options.legend.backgroundColor;\n                    if (c == null) {\n                        c = options.grid.backgroundColor;\n                        if (c && typeof c == \"string\")\n                            c = $.color.parse(c);\n                        else\n                            c = $.color.extract(legend, 'background-color');\n                        c.a = 1;\n                        c = c.toString();\n                    }\n                    var div = legend.children();\n                    $('<div style=\"position:absolute;width:' + div.width() + 'px;height:' + div.height() + 'px;' + pos +'background-color:' + c + ';\"> </div>').prependTo(legend).css('opacity', options.legend.backgroundOpacity);\n                }\n            }\n        }\n\n\n        // interactive features\n\n        var highlights = [],\n            redrawTimeout = null;\n\n        // returns the data item the mouse is over, or null if none is found\n        function findNearbyItem(mouseX, mouseY, seriesFilter) {\n            var maxDistance = options.grid.mouseActiveRadius,\n                smallestDistance = maxDistance * maxDistance + 1,\n                item = null, foundPoint = false, i, j, ps;\n\n            for (i = series.length - 1; i >= 0; --i) {\n                if (!seriesFilter(series[i]))\n                    continue;\n\n                var s = series[i],\n                    axisx = s.xaxis,\n                    axisy = s.yaxis,\n                    points = s.datapoints.points,\n                    mx = axisx.c2p(mouseX), // precompute some stuff to make the loop faster\n                    my = axisy.c2p(mouseY),\n                    maxx = maxDistance / axisx.scale,\n                    maxy = maxDistance / axisy.scale;\n\n                ps = s.datapoints.pointsize;\n                // with inverse transforms, we can't use the maxx/maxy\n                // optimization, sadly\n                if (axisx.options.inverseTransform)\n                    maxx = Number.MAX_VALUE;\n                if (axisy.options.inverseTransform)\n                    maxy = Number.MAX_VALUE;\n\n                if (s.lines.show || s.points.show) {\n                    for (j = 0; j < points.length; j += ps) {\n                        var x = points[j], y = points[j + 1];\n                        if (x == null)\n                            continue;\n\n                        // For points and lines, the cursor must be within a\n                        // certain distance to the data point\n                        if (x - mx > maxx || x - mx < -maxx ||\n                            y - my > maxy || y - my < -maxy)\n                            continue;\n\n                        // We have to calculate distances in pixels, not in\n                        // data units, because the scales of the axes may be different\n                        var dx = Math.abs(axisx.p2c(x) - mouseX),\n                            dy = Math.abs(axisy.p2c(y) - mouseY),\n                            dist = dx * dx + dy * dy; // we save the sqrt\n\n                        // use <= to ensure last point takes precedence\n                        // (last generally means on top of)\n                        if (dist < smallestDistance) {\n                            smallestDistance = dist;\n                            item = [i, j / ps];\n                        }\n                    }\n                }\n\n                if (s.bars.show && !item) { // no other point can be nearby\n\n                    var barLeft, barRight;\n\n                    switch (s.bars.align) {\n                        case \"left\":\n                            barLeft = 0;\n                            break;\n                        case \"right\":\n                            barLeft = -s.bars.barWidth;\n                            break;\n                        default:\n                            barLeft = -s.bars.barWidth / 2;\n                    }\n\n                    barRight = barLeft + s.bars.barWidth;\n\n                    for (j = 0; j < points.length; j += ps) {\n                        var x = points[j], y = points[j + 1], b = points[j + 2];\n                        if (x == null)\n                            continue;\n\n                        // for a bar graph, the cursor must be inside the bar\n                        if (series[i].bars.horizontal ?\n                            (mx <= Math.max(b, x) && mx >= Math.min(b, x) &&\n                             my >= y + barLeft && my <= y + barRight) :\n                            (mx >= x + barLeft && mx <= x + barRight &&\n                             my >= Math.min(b, y) && my <= Math.max(b, y)))\n                                item = [i, j / ps];\n                    }\n                }\n            }\n\n            if (item) {\n                i = item[0];\n                j = item[1];\n                ps = series[i].datapoints.pointsize;\n\n                return { datapoint: series[i].datapoints.points.slice(j * ps, (j + 1) * ps),\n                         dataIndex: j,\n                         series: series[i],\n                         seriesIndex: i };\n            }\n\n            return null;\n        }\n\n        function onMouseMove(e) {\n            if (options.grid.hoverable)\n                triggerClickHoverEvent(\"plothover\", e,\n                                       function (s) { return s[\"hoverable\"] != false; });\n        }\n\n        function onMouseLeave(e) {\n            if (options.grid.hoverable)\n                triggerClickHoverEvent(\"plothover\", e,\n                                       function (s) { return false; });\n        }\n\n        function onClick(e) {\n            triggerClickHoverEvent(\"plotclick\", e,\n                                   function (s) { return s[\"clickable\"] != false; });\n        }\n\n        // trigger click or hover event (they send the same parameters\n        // so we share their code)\n        function triggerClickHoverEvent(eventname, event, seriesFilter) {\n            var offset = eventHolder.offset(),\n                canvasX = event.pageX - offset.left - plotOffset.left,\n                canvasY = event.pageY - offset.top - plotOffset.top,\n            pos = canvasToAxisCoords({ left: canvasX, top: canvasY });\n\n            pos.pageX = event.pageX;\n            pos.pageY = event.pageY;\n\n            var item = findNearbyItem(canvasX, canvasY, seriesFilter);\n\n            if (item) {\n                // fill in mouse pos for any listeners out there\n                item.pageX = parseInt(item.series.xaxis.p2c(item.datapoint[0]) + offset.left + plotOffset.left, 10);\n                item.pageY = parseInt(item.series.yaxis.p2c(item.datapoint[1]) + offset.top + plotOffset.top, 10);\n            }\n\n            if (options.grid.autoHighlight) {\n                // clear auto-highlights\n                for (var i = 0; i < highlights.length; ++i) {\n                    var h = highlights[i];\n                    if (h.auto == eventname &&\n                        !(item && h.series == item.series &&\n                          h.point[0] == item.datapoint[0] &&\n                          h.point[1] == item.datapoint[1]))\n                        unhighlight(h.series, h.point);\n                }\n\n                if (item)\n                    highlight(item.series, item.datapoint, eventname);\n            }\n\n            placeholder.trigger(eventname, [ pos, item ]);\n        }\n\n        function triggerRedrawOverlay() {\n            var t = options.interaction.redrawOverlayInterval;\n            if (t == -1) {      // skip event queue\n                drawOverlay();\n                return;\n            }\n\n            if (!redrawTimeout)\n                redrawTimeout = setTimeout(drawOverlay, t);\n        }\n\n        function drawOverlay() {\n            redrawTimeout = null;\n\n            // draw highlights\n            octx.save();\n            overlay.clear();\n            octx.translate(plotOffset.left, plotOffset.top);\n\n            var i, hi;\n            for (i = 0; i < highlights.length; ++i) {\n                hi = highlights[i];\n\n                if (hi.series.bars.show)\n                    drawBarHighlight(hi.series, hi.point);\n                else\n                    drawPointHighlight(hi.series, hi.point);\n            }\n            octx.restore();\n\n            executeHooks(hooks.drawOverlay, [octx]);\n        }\n\n        function highlight(s, point, auto) {\n            if (typeof s == \"number\")\n                s = series[s];\n\n            if (typeof point == \"number\") {\n                var ps = s.datapoints.pointsize;\n                point = s.datapoints.points.slice(ps * point, ps * (point + 1));\n            }\n\n            var i = indexOfHighlight(s, point);\n            if (i == -1) {\n                highlights.push({ series: s, point: point, auto: auto });\n\n                triggerRedrawOverlay();\n            }\n            else if (!auto)\n                highlights[i].auto = false;\n        }\n\n        function unhighlight(s, point) {\n            if (s == null && point == null) {\n                highlights = [];\n                triggerRedrawOverlay();\n                return;\n            }\n\n            if (typeof s == \"number\")\n                s = series[s];\n\n            if (typeof point == \"number\") {\n                var ps = s.datapoints.pointsize;\n                point = s.datapoints.points.slice(ps * point, ps * (point + 1));\n            }\n\n            var i = indexOfHighlight(s, point);\n            if (i != -1) {\n                highlights.splice(i, 1);\n\n                triggerRedrawOverlay();\n            }\n        }\n\n        function indexOfHighlight(s, p) {\n            for (var i = 0; i < highlights.length; ++i) {\n                var h = highlights[i];\n                if (h.series == s && h.point[0] == p[0]\n                    && h.point[1] == p[1])\n                    return i;\n            }\n            return -1;\n        }\n\n        function drawPointHighlight(series, point) {\n            var x = point[0], y = point[1],\n                axisx = series.xaxis, axisy = series.yaxis,\n                highlightColor = (typeof series.highlightColor === \"string\") ? series.highlightColor : $.color.parse(series.color).scale('a', 0.5).toString();\n\n            if (x < axisx.min || x > axisx.max || y < axisy.min || y > axisy.max)\n                return;\n\n            var pointRadius = series.points.radius + series.points.lineWidth / 2;\n            octx.lineWidth = pointRadius;\n            octx.strokeStyle = highlightColor;\n            var radius = 1.5 * pointRadius;\n            x = axisx.p2c(x);\n            y = axisy.p2c(y);\n\n            octx.beginPath();\n            if (series.points.symbol == \"circle\")\n                octx.arc(x, y, radius, 0, 2 * Math.PI, false);\n            else\n                series.points.symbol(octx, x, y, radius, false);\n            octx.closePath();\n            octx.stroke();\n        }\n\n        function drawBarHighlight(series, point) {\n            var highlightColor = (typeof series.highlightColor === \"string\") ? series.highlightColor : $.color.parse(series.color).scale('a', 0.5).toString(),\n                fillStyle = highlightColor,\n                barLeft;\n\n            switch (series.bars.align) {\n                case \"left\":\n                    barLeft = 0;\n                    break;\n                case \"right\":\n                    barLeft = -series.bars.barWidth;\n                    break;\n                default:\n                    barLeft = -series.bars.barWidth / 2;\n            }\n\n            octx.lineWidth = series.bars.lineWidth;\n            octx.strokeStyle = highlightColor;\n\n            drawBar(point[0], point[1], point[2] || 0, barLeft, barLeft + series.bars.barWidth,\n                    function () { return fillStyle; }, series.xaxis, series.yaxis, octx, series.bars.horizontal, series.bars.lineWidth);\n        }\n\n        function getColorOrGradient(spec, bottom, top, defaultColor) {\n            if (typeof spec == \"string\")\n                return spec;\n            else {\n                // assume this is a gradient spec; IE currently only\n                // supports a simple vertical gradient properly, so that's\n                // what we support too\n                var gradient = ctx.createLinearGradient(0, top, 0, bottom);\n\n                for (var i = 0, l = spec.colors.length; i < l; ++i) {\n                    var c = spec.colors[i];\n                    if (typeof c != \"string\") {\n                        var co = $.color.parse(defaultColor);\n                        if (c.brightness != null)\n                            co = co.scale('rgb', c.brightness);\n                        if (c.opacity != null)\n                            co.a *= c.opacity;\n                        c = co.toString();\n                    }\n                    gradient.addColorStop(i / (l - 1), c);\n                }\n\n                return gradient;\n            }\n        }\n    }\n\n    // Add the plot function to the top level of the jQuery object\n\n    $.plot = function(placeholder, data, options) {\n        //var t0 = new Date();\n        var plot = new Plot($(placeholder), data, options, $.plot.plugins);\n        //(window.console ? console.log : alert)(\"time used (msecs): \" + ((new Date()).getTime() - t0.getTime()));\n        return plot;\n    };\n\n    $.plot.version = \"0.8.3\";\n\n    $.plot.plugins = [];\n\n    // Also add the plot function as a chainable property\n\n    $.fn.plot = function(data, options) {\n        return this.each(function() {\n            $.plot(this, data, options);\n        });\n    };\n\n    // round to nearby lower multiple of base\n    function floorInBase(n, base) {\n        return base * Math.floor(n / base);\n    }\n\n})(jQuery);\n"
  },
  {
    "path": "app_backend/vendor/flot/jquery.flot.navigate.js",
    "content": "/* Flot plugin for adding the ability to pan and zoom the plot.\n\nCopyright (c) 2007-2014 IOLA and Ole Laursen.\nLicensed under the MIT license.\n\nThe default behaviour is double click and scrollwheel up/down to zoom in, drag\nto pan. The plugin defines plot.zoom({ center }), plot.zoomOut() and\nplot.pan( offset ) so you easily can add custom controls. It also fires\n\"plotpan\" and \"plotzoom\" events, useful for synchronizing plots.\n\nThe plugin supports these options:\n\n\tzoom: {\n\t\tinteractive: false\n\t\ttrigger: \"dblclick\" // or \"click\" for single click\n\t\tamount: 1.5         // 2 = 200% (zoom in), 0.5 = 50% (zoom out)\n\t}\n\n\tpan: {\n\t\tinteractive: false\n\t\tcursor: \"move\"      // CSS mouse cursor value used when dragging, e.g. \"pointer\"\n\t\tframeRate: 20\n\t}\n\n\txaxis, yaxis, x2axis, y2axis: {\n\t\tzoomRange: null  // or [ number, number ] (min range, max range) or false\n\t\tpanRange: null   // or [ number, number ] (min, max) or false\n\t}\n\n\"interactive\" enables the built-in drag/click behaviour. If you enable\ninteractive for pan, then you'll have a basic plot that supports moving\naround; the same for zoom.\n\n\"amount\" specifies the default amount to zoom in (so 1.5 = 150%) relative to\nthe current viewport.\n\n\"cursor\" is a standard CSS mouse cursor string used for visual feedback to the\nuser when dragging.\n\n\"frameRate\" specifies the maximum number of times per second the plot will\nupdate itself while the user is panning around on it (set to null to disable\nintermediate pans, the plot will then not update until the mouse button is\nreleased).\n\n\"zoomRange\" is the interval in which zooming can happen, e.g. with zoomRange:\n[1, 100] the zoom will never scale the axis so that the difference between min\nand max is smaller than 1 or larger than 100. You can set either end to null\nto ignore, e.g. [1, null]. If you set zoomRange to false, zooming on that axis\nwill be disabled.\n\n\"panRange\" confines the panning to stay within a range, e.g. with panRange:\n[-10, 20] panning stops at -10 in one end and at 20 in the other. Either can\nbe null, e.g. [-10, null]. If you set panRange to false, panning on that axis\nwill be disabled.\n\nExample API usage:\n\n\tplot = $.plot(...);\n\n\t// zoom default amount in on the pixel ( 10, 20 )\n\tplot.zoom({ center: { left: 10, top: 20 } });\n\n\t// zoom out again\n\tplot.zoomOut({ center: { left: 10, top: 20 } });\n\n\t// zoom 200% in on the pixel (10, 20)\n\tplot.zoom({ amount: 2, center: { left: 10, top: 20 } });\n\n\t// pan 100 pixels to the left and 20 down\n\tplot.pan({ left: -100, top: 20 })\n\nHere, \"center\" specifies where the center of the zooming should happen. Note\nthat this is defined in pixel space, not the space of the data points (you can\nuse the p2c helpers on the axes in Flot to help you convert between these).\n\n\"amount\" is the amount to zoom the viewport relative to the current range, so\n1 is 100% (i.e. no change), 1.5 is 150% (zoom in), 0.7 is 70% (zoom out). You\ncan set the default in the options.\n\n*/\n\n// First two dependencies, jquery.event.drag.js and\n// jquery.mousewheel.js, we put them inline here to save people the\n// effort of downloading them.\n\n/*\njquery.event.drag.js ~ v1.5 ~ Copyright (c) 2008, Three Dub Media (http://threedubmedia.com)\nLicensed under the MIT License ~ http://threedubmedia.googlecode.com/files/MIT-LICENSE.txt\n*/\n(function(a){function e(h){var k,j=this,l=h.data||{};if(l.elem)j=h.dragTarget=l.elem,h.dragProxy=d.proxy||j,h.cursorOffsetX=l.pageX-l.left,h.cursorOffsetY=l.pageY-l.top,h.offsetX=h.pageX-h.cursorOffsetX,h.offsetY=h.pageY-h.cursorOffsetY;else if(d.dragging||l.which>0&&h.which!=l.which||a(h.target).is(l.not))return;switch(h.type){case\"mousedown\":return a.extend(l,a(j).offset(),{elem:j,target:h.target,pageX:h.pageX,pageY:h.pageY}),b.add(document,\"mousemove mouseup\",e,l),i(j,!1),d.dragging=null,!1;case!d.dragging&&\"mousemove\":if(g(h.pageX-l.pageX)+g(h.pageY-l.pageY)<l.distance)break;h.target=l.target,k=f(h,\"dragstart\",j),k!==!1&&(d.dragging=j,d.proxy=h.dragProxy=a(k||j)[0]);case\"mousemove\":if(d.dragging){if(k=f(h,\"drag\",j),c.drop&&(c.drop.allowed=k!==!1,c.drop.handler(h)),k!==!1)break;h.type=\"mouseup\"}case\"mouseup\":b.remove(document,\"mousemove mouseup\",e),d.dragging&&(c.drop&&c.drop.handler(h),f(h,\"dragend\",j)),i(j,!0),d.dragging=d.proxy=l.elem=!1}return!0}function f(b,c,d){b.type=c;var e=a.event.dispatch.call(d,b);return e===!1?!1:e||b.result}function g(a){return Math.pow(a,2)}function h(){return d.dragging===!1}function i(a,b){a&&(a.unselectable=b?\"off\":\"on\",a.onselectstart=function(){return b},a.style&&(a.style.MozUserSelect=b?\"\":\"none\"))}a.fn.drag=function(a,b,c){return b&&this.bind(\"dragstart\",a),c&&this.bind(\"dragend\",c),a?this.bind(\"drag\",b?b:a):this.trigger(\"drag\")};var b=a.event,c=b.special,d=c.drag={not:\":input\",distance:0,which:1,dragging:!1,setup:function(c){c=a.extend({distance:d.distance,which:d.which,not:d.not},c||{}),c.distance=g(c.distance),b.add(this,\"mousedown\",e,c),this.attachEvent&&this.attachEvent(\"ondragstart\",h)},teardown:function(){b.remove(this,\"mousedown\",e),this===d.dragging&&(d.dragging=d.proxy=!1),i(this,!0),this.detachEvent&&this.detachEvent(\"ondragstart\",h)}};c.dragstart=c.dragend={setup:function(){},teardown:function(){}}})(jQuery);\n\n/* jquery.mousewheel.min.js\n * Copyright (c) 2011 Brandon Aaron (http://brandonaaron.net)\n * Licensed under the MIT License (LICENSE.txt).\n * Thanks to: http://adomas.org/javascript-mouse-wheel/ for some pointers.\n * Thanks to: Mathias Bank(http://www.mathias-bank.de) for a scope bug fix.\n * Thanks to: Seamus Leahy for adding deltaX and deltaY\n *\n * Version: 3.0.6\n *\n * Requires: 1.2.2+\n */\n(function(d){function e(a){var b=a||window.event,c=[].slice.call(arguments,1),f=0,e=0,g=0,a=d.event.fix(b);a.type=\"mousewheel\";b.wheelDelta&&(f=b.wheelDelta/120);b.detail&&(f=-b.detail/3);g=f;void 0!==b.axis&&b.axis===b.HORIZONTAL_AXIS&&(g=0,e=-1*f);void 0!==b.wheelDeltaY&&(g=b.wheelDeltaY/120);void 0!==b.wheelDeltaX&&(e=-1*b.wheelDeltaX/120);c.unshift(a,f,e,g);return(d.event.dispatch||d.event.handle).apply(this,c)}var c=[\"DOMMouseScroll\",\"mousewheel\"];if(d.event.fixHooks)for(var h=c.length;h;)d.event.fixHooks[c[--h]]=d.event.mouseHooks;d.event.special.mousewheel={setup:function(){if(this.addEventListener)for(var a=c.length;a;)this.addEventListener(c[--a],e,!1);else this.onmousewheel=e},teardown:function(){if(this.removeEventListener)for(var a=c.length;a;)this.removeEventListener(c[--a],e,!1);else this.onmousewheel=null}};d.fn.extend({mousewheel:function(a){return a?this.bind(\"mousewheel\",a):this.trigger(\"mousewheel\")},unmousewheel:function(a){return this.unbind(\"mousewheel\",a)}})})(jQuery);\n\n\n\n\n(function ($) {\n    var options = {\n        xaxis: {\n            zoomRange: null, // or [number, number] (min range, max range)\n            panRange: null // or [number, number] (min, max)\n        },\n        zoom: {\n            interactive: false,\n            trigger: \"dblclick\", // or \"click\" for single click\n            amount: 1.5 // how much to zoom relative to current position, 2 = 200% (zoom in), 0.5 = 50% (zoom out)\n        },\n        pan: {\n            interactive: false,\n            cursor: \"move\",\n            frameRate: 20\n        }\n    };\n\n    function init(plot) {\n        function onZoomClick(e, zoomOut) {\n            var c = plot.offset();\n            c.left = e.pageX - c.left;\n            c.top = e.pageY - c.top;\n            if (zoomOut)\n                plot.zoomOut({ center: c });\n            else\n                plot.zoom({ center: c });\n        }\n\n        function onMouseWheel(e, delta) {\n            e.preventDefault();\n            onZoomClick(e, delta < 0);\n            return false;\n        }\n        \n        var prevCursor = 'default', prevPageX = 0, prevPageY = 0,\n            panTimeout = null;\n\n        function onDragStart(e) {\n            if (e.which != 1)  // only accept left-click\n                return false;\n            var c = plot.getPlaceholder().css('cursor');\n            if (c)\n                prevCursor = c;\n            plot.getPlaceholder().css('cursor', plot.getOptions().pan.cursor);\n            prevPageX = e.pageX;\n            prevPageY = e.pageY;\n        }\n        \n        function onDrag(e) {\n            var frameRate = plot.getOptions().pan.frameRate;\n            if (panTimeout || !frameRate)\n                return;\n\n            panTimeout = setTimeout(function () {\n                plot.pan({ left: prevPageX - e.pageX,\n                           top: prevPageY - e.pageY });\n                prevPageX = e.pageX;\n                prevPageY = e.pageY;\n                                                    \n                panTimeout = null;\n            }, 1 / frameRate * 1000);\n        }\n\n        function onDragEnd(e) {\n            if (panTimeout) {\n                clearTimeout(panTimeout);\n                panTimeout = null;\n            }\n                    \n            plot.getPlaceholder().css('cursor', prevCursor);\n            plot.pan({ left: prevPageX - e.pageX,\n                       top: prevPageY - e.pageY });\n        }\n        \n        function bindEvents(plot, eventHolder) {\n            var o = plot.getOptions();\n            if (o.zoom.interactive) {\n                eventHolder[o.zoom.trigger](onZoomClick);\n                eventHolder.mousewheel(onMouseWheel);\n            }\n\n            if (o.pan.interactive) {\n                eventHolder.bind(\"dragstart\", { distance: 10 }, onDragStart);\n                eventHolder.bind(\"drag\", onDrag);\n                eventHolder.bind(\"dragend\", onDragEnd);\n            }\n        }\n\n        plot.zoomOut = function (args) {\n            if (!args)\n                args = {};\n            \n            if (!args.amount)\n                args.amount = plot.getOptions().zoom.amount;\n\n            args.amount = 1 / args.amount;\n            plot.zoom(args);\n        };\n        \n        plot.zoom = function (args) {\n            if (!args)\n                args = {};\n            \n            var c = args.center,\n                amount = args.amount || plot.getOptions().zoom.amount,\n                w = plot.width(), h = plot.height();\n\n            if (!c)\n                c = { left: w / 2, top: h / 2 };\n                \n            var xf = c.left / w,\n                yf = c.top / h,\n                minmax = {\n                    x: {\n                        min: c.left - xf * w / amount,\n                        max: c.left + (1 - xf) * w / amount\n                    },\n                    y: {\n                        min: c.top - yf * h / amount,\n                        max: c.top + (1 - yf) * h / amount\n                    }\n                };\n\n            $.each(plot.getAxes(), function(_, axis) {\n                var opts = axis.options,\n                    min = minmax[axis.direction].min,\n                    max = minmax[axis.direction].max,\n                    zr = opts.zoomRange,\n                    pr = opts.panRange;\n\n                if (zr === false) // no zooming on this axis\n                    return;\n                    \n                min = axis.c2p(min);\n                max = axis.c2p(max);\n                if (min > max) {\n                    // make sure min < max\n                    var tmp = min;\n                    min = max;\n                    max = tmp;\n                }\n\n                //Check that we are in panRange\n                if (pr) {\n                    if (pr[0] != null && min < pr[0]) {\n                        min = pr[0];\n                    }\n                    if (pr[1] != null && max > pr[1]) {\n                        max = pr[1];\n                    }\n                }\n\n                var range = max - min;\n                if (zr &&\n                    ((zr[0] != null && range < zr[0] && amount >1) ||\n                     (zr[1] != null && range > zr[1] && amount <1)))\n                    return;\n            \n                opts.min = min;\n                opts.max = max;\n            });\n            \n            plot.setupGrid();\n            plot.draw();\n            \n            if (!args.preventEvent)\n                plot.getPlaceholder().trigger(\"plotzoom\", [ plot, args ]);\n        };\n\n        plot.pan = function (args) {\n            var delta = {\n                x: +args.left,\n                y: +args.top\n            };\n\n            if (isNaN(delta.x))\n                delta.x = 0;\n            if (isNaN(delta.y))\n                delta.y = 0;\n\n            $.each(plot.getAxes(), function (_, axis) {\n                var opts = axis.options,\n                    min, max, d = delta[axis.direction];\n\n                min = axis.c2p(axis.p2c(axis.min) + d),\n                max = axis.c2p(axis.p2c(axis.max) + d);\n\n                var pr = opts.panRange;\n                if (pr === false) // no panning on this axis\n                    return;\n                \n                if (pr) {\n                    // check whether we hit the wall\n                    if (pr[0] != null && pr[0] > min) {\n                        d = pr[0] - min;\n                        min += d;\n                        max += d;\n                    }\n                    \n                    if (pr[1] != null && pr[1] < max) {\n                        d = pr[1] - max;\n                        min += d;\n                        max += d;\n                    }\n                }\n                \n                opts.min = min;\n                opts.max = max;\n            });\n            \n            plot.setupGrid();\n            plot.draw();\n            \n            if (!args.preventEvent)\n                plot.getPlaceholder().trigger(\"plotpan\", [ plot, args ]);\n        };\n\n        function shutdown(plot, eventHolder) {\n            eventHolder.unbind(plot.getOptions().zoom.trigger, onZoomClick);\n            eventHolder.unbind(\"mousewheel\", onMouseWheel);\n            eventHolder.unbind(\"dragstart\", onDragStart);\n            eventHolder.unbind(\"drag\", onDrag);\n            eventHolder.unbind(\"dragend\", onDragEnd);\n            if (panTimeout)\n                clearTimeout(panTimeout);\n        }\n        \n        plot.hooks.bindEvents.push(bindEvents);\n        plot.hooks.shutdown.push(shutdown);\n    }\n    \n    $.plot.plugins.push({\n        init: init,\n        options: options,\n        name: 'navigate',\n        version: '1.3'\n    });\n})(jQuery);\n"
  },
  {
    "path": "app_backend/vendor/flot/jquery.flot.pie.js",
    "content": "/* Flot plugin for rendering pie charts.\n\nCopyright (c) 2007-2014 IOLA and Ole Laursen.\nLicensed under the MIT license.\n\nThe plugin assumes that each series has a single data value, and that each\nvalue is a positive integer or zero.  Negative numbers don't make sense for a\npie chart, and have unpredictable results.  The values do NOT need to be\npassed in as percentages; the plugin will calculate the total and per-slice\npercentages internally.\n\n* Created by Brian Medendorp\n\n* Updated with contributions from btburnett3, Anthony Aragues and Xavi Ivars\n\nThe plugin supports these options:\n\n\tseries: {\n\t\tpie: {\n\t\t\tshow: true/false\n\t\t\tradius: 0-1 for percentage of fullsize, or a specified pixel length, or 'auto'\n\t\t\tinnerRadius: 0-1 for percentage of fullsize or a specified pixel length, for creating a donut effect\n\t\t\tstartAngle: 0-2 factor of PI used for starting angle (in radians) i.e 3/2 starts at the top, 0 and 2 have the same result\n\t\t\ttilt: 0-1 for percentage to tilt the pie, where 1 is no tilt, and 0 is completely flat (nothing will show)\n\t\t\toffset: {\n\t\t\t\ttop: integer value to move the pie up or down\n\t\t\t\tleft: integer value to move the pie left or right, or 'auto'\n\t\t\t},\n\t\t\tstroke: {\n\t\t\t\tcolor: any hexidecimal color value (other formats may or may not work, so best to stick with something like '#FFF')\n\t\t\t\twidth: integer pixel width of the stroke\n\t\t\t},\n\t\t\tlabel: {\n\t\t\t\tshow: true/false, or 'auto'\n\t\t\t\tformatter:  a user-defined function that modifies the text/style of the label text\n\t\t\t\tradius: 0-1 for percentage of fullsize, or a specified pixel length\n\t\t\t\tbackground: {\n\t\t\t\t\tcolor: any hexidecimal color value (other formats may or may not work, so best to stick with something like '#000')\n\t\t\t\t\topacity: 0-1\n\t\t\t\t},\n\t\t\t\tthreshold: 0-1 for the percentage value at which to hide labels (if they're too small)\n\t\t\t},\n\t\t\tcombine: {\n\t\t\t\tthreshold: 0-1 for the percentage value at which to combine slices (if they're too small)\n\t\t\t\tcolor: any hexidecimal color value (other formats may or may not work, so best to stick with something like '#CCC'), if null, the plugin will automatically use the color of the first slice to be combined\n\t\t\t\tlabel: any text value of what the combined slice should be labeled\n\t\t\t}\n\t\t\thighlight: {\n\t\t\t\topacity: 0-1\n\t\t\t}\n\t\t}\n\t}\n\nMore detail and specific examples can be found in the included HTML file.\n\n*/\n\n(function($) {\n\n\t// Maximum redraw attempts when fitting labels within the plot\n\n\tvar REDRAW_ATTEMPTS = 10;\n\n\t// Factor by which to shrink the pie when fitting labels within the plot\n\n\tvar REDRAW_SHRINK = 0.95;\n\n\tfunction init(plot) {\n\n\t\tvar canvas = null,\n\t\t\ttarget = null,\n\t\t\toptions = null,\n\t\t\tmaxRadius = null,\n\t\t\tcenterLeft = null,\n\t\t\tcenterTop = null,\n\t\t\tprocessed = false,\n\t\t\tctx = null;\n\n\t\t// interactive variables\n\n\t\tvar highlights = [];\n\n\t\t// add hook to determine if pie plugin in enabled, and then perform necessary operations\n\n\t\tplot.hooks.processOptions.push(function(plot, options) {\n\t\t\tif (options.series.pie.show) {\n\n\t\t\t\toptions.grid.show = false;\n\n\t\t\t\t// set labels.show\n\n\t\t\t\tif (options.series.pie.label.show == \"auto\") {\n\t\t\t\t\tif (options.legend.show) {\n\t\t\t\t\t\toptions.series.pie.label.show = false;\n\t\t\t\t\t} else {\n\t\t\t\t\t\toptions.series.pie.label.show = true;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// set radius\n\n\t\t\t\tif (options.series.pie.radius == \"auto\") {\n\t\t\t\t\tif (options.series.pie.label.show) {\n\t\t\t\t\t\toptions.series.pie.radius = 3/4;\n\t\t\t\t\t} else {\n\t\t\t\t\t\toptions.series.pie.radius = 1;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// ensure sane tilt\n\n\t\t\t\tif (options.series.pie.tilt > 1) {\n\t\t\t\t\toptions.series.pie.tilt = 1;\n\t\t\t\t} else if (options.series.pie.tilt < 0) {\n\t\t\t\t\toptions.series.pie.tilt = 0;\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\n\t\tplot.hooks.bindEvents.push(function(plot, eventHolder) {\n\t\t\tvar options = plot.getOptions();\n\t\t\tif (options.series.pie.show) {\n\t\t\t\tif (options.grid.hoverable) {\n\t\t\t\t\teventHolder.unbind(\"mousemove\").mousemove(onMouseMove);\n\t\t\t\t}\n\t\t\t\tif (options.grid.clickable) {\n\t\t\t\t\teventHolder.unbind(\"click\").click(onClick);\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\n\t\tplot.hooks.processDatapoints.push(function(plot, series, data, datapoints) {\n\t\t\tvar options = plot.getOptions();\n\t\t\tif (options.series.pie.show) {\n\t\t\t\tprocessDatapoints(plot, series, data, datapoints);\n\t\t\t}\n\t\t});\n\n\t\tplot.hooks.drawOverlay.push(function(plot, octx) {\n\t\t\tvar options = plot.getOptions();\n\t\t\tif (options.series.pie.show) {\n\t\t\t\tdrawOverlay(plot, octx);\n\t\t\t}\n\t\t});\n\n\t\tplot.hooks.draw.push(function(plot, newCtx) {\n\t\t\tvar options = plot.getOptions();\n\t\t\tif (options.series.pie.show) {\n\t\t\t\tdraw(plot, newCtx);\n\t\t\t}\n\t\t});\n\n\t\tfunction processDatapoints(plot, series, datapoints) {\n\t\t\tif (!processed)\t{\n\t\t\t\tprocessed = true;\n\t\t\t\tcanvas = plot.getCanvas();\n\t\t\t\ttarget = $(canvas).parent();\n\t\t\t\toptions = plot.getOptions();\n\t\t\t\tplot.setData(combine(plot.getData()));\n\t\t\t}\n\t\t}\n\n\t\tfunction combine(data) {\n\n\t\t\tvar total = 0,\n\t\t\t\tcombined = 0,\n\t\t\t\tnumCombined = 0,\n\t\t\t\tcolor = options.series.pie.combine.color,\n\t\t\t\tnewdata = [];\n\n\t\t\t// Fix up the raw data from Flot, ensuring the data is numeric\n\n\t\t\tfor (var i = 0; i < data.length; ++i) {\n\n\t\t\t\tvar value = data[i].data;\n\n\t\t\t\t// If the data is an array, we'll assume that it's a standard\n\t\t\t\t// Flot x-y pair, and are concerned only with the second value.\n\n\t\t\t\t// Note how we use the original array, rather than creating a\n\t\t\t\t// new one; this is more efficient and preserves any extra data\n\t\t\t\t// that the user may have stored in higher indexes.\n\n\t\t\t\tif ($.isArray(value) && value.length == 1) {\n    \t\t\t\tvalue = value[0];\n\t\t\t\t}\n\n\t\t\t\tif ($.isArray(value)) {\n\t\t\t\t\t// Equivalent to $.isNumeric() but compatible with jQuery < 1.7\n\t\t\t\t\tif (!isNaN(parseFloat(value[1])) && isFinite(value[1])) {\n\t\t\t\t\t\tvalue[1] = +value[1];\n\t\t\t\t\t} else {\n\t\t\t\t\t\tvalue[1] = 0;\n\t\t\t\t\t}\n\t\t\t\t} else if (!isNaN(parseFloat(value)) && isFinite(value)) {\n\t\t\t\t\tvalue = [1, +value];\n\t\t\t\t} else {\n\t\t\t\t\tvalue = [1, 0];\n\t\t\t\t}\n\n\t\t\t\tdata[i].data = [value];\n\t\t\t}\n\n\t\t\t// Sum up all the slices, so we can calculate percentages for each\n\n\t\t\tfor (var i = 0; i < data.length; ++i) {\n\t\t\t\ttotal += data[i].data[0][1];\n\t\t\t}\n\n\t\t\t// Count the number of slices with percentages below the combine\n\t\t\t// threshold; if it turns out to be just one, we won't combine.\n\n\t\t\tfor (var i = 0; i < data.length; ++i) {\n\t\t\t\tvar value = data[i].data[0][1];\n\t\t\t\tif (value / total <= options.series.pie.combine.threshold) {\n\t\t\t\t\tcombined += value;\n\t\t\t\t\tnumCombined++;\n\t\t\t\t\tif (!color) {\n\t\t\t\t\t\tcolor = data[i].color;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tfor (var i = 0; i < data.length; ++i) {\n\t\t\t\tvar value = data[i].data[0][1];\n\t\t\t\tif (numCombined < 2 || value / total > options.series.pie.combine.threshold) {\n\t\t\t\t\tnewdata.push(\n\t\t\t\t\t\t$.extend(data[i], {     /* extend to allow keeping all other original data values\n\t\t\t\t\t\t                           and using them e.g. in labelFormatter. */\n\t\t\t\t\t\t\tdata: [[1, value]],\n\t\t\t\t\t\t\tcolor: data[i].color,\n\t\t\t\t\t\t\tlabel: data[i].label,\n\t\t\t\t\t\t\tangle: value * Math.PI * 2 / total,\n\t\t\t\t\t\t\tpercent: value / (total / 100)\n\t\t\t\t\t\t})\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (numCombined > 1) {\n\t\t\t\tnewdata.push({\n\t\t\t\t\tdata: [[1, combined]],\n\t\t\t\t\tcolor: color,\n\t\t\t\t\tlabel: options.series.pie.combine.label,\n\t\t\t\t\tangle: combined * Math.PI * 2 / total,\n\t\t\t\t\tpercent: combined / (total / 100)\n\t\t\t\t});\n\t\t\t}\n\n\t\t\treturn newdata;\n\t\t}\n\n\t\tfunction draw(plot, newCtx) {\n\n\t\t\tif (!target) {\n\t\t\t\treturn; // if no series were passed\n\t\t\t}\n\n\t\t\tvar canvasWidth = plot.getPlaceholder().width(),\n\t\t\t\tcanvasHeight = plot.getPlaceholder().height(),\n\t\t\t\tlegendWidth = target.children().filter(\".legend\").children().width() || 0;\n\n\t\t\tctx = newCtx;\n\n\t\t\t// WARNING: HACK! REWRITE THIS CODE AS SOON AS POSSIBLE!\n\n\t\t\t// When combining smaller slices into an 'other' slice, we need to\n\t\t\t// add a new series.  Since Flot gives plugins no way to modify the\n\t\t\t// list of series, the pie plugin uses a hack where the first call\n\t\t\t// to processDatapoints results in a call to setData with the new\n\t\t\t// list of series, then subsequent processDatapoints do nothing.\n\n\t\t\t// The plugin-global 'processed' flag is used to control this hack;\n\t\t\t// it starts out false, and is set to true after the first call to\n\t\t\t// processDatapoints.\n\n\t\t\t// Unfortunately this turns future setData calls into no-ops; they\n\t\t\t// call processDatapoints, the flag is true, and nothing happens.\n\n\t\t\t// To fix this we'll set the flag back to false here in draw, when\n\t\t\t// all series have been processed, so the next sequence of calls to\n\t\t\t// processDatapoints once again starts out with a slice-combine.\n\t\t\t// This is really a hack; in 0.9 we need to give plugins a proper\n\t\t\t// way to modify series before any processing begins.\n\n\t\t\tprocessed = false;\n\n\t\t\t// calculate maximum radius and center point\n\n\t\t\tmaxRadius =  Math.min(canvasWidth, canvasHeight / options.series.pie.tilt) / 2;\n\t\t\tcenterTop = canvasHeight / 2 + options.series.pie.offset.top;\n\t\t\tcenterLeft = canvasWidth / 2;\n\n\t\t\tif (options.series.pie.offset.left == \"auto\") {\n\t\t\t\tif (options.legend.position.match(\"w\")) {\n\t\t\t\t\tcenterLeft += legendWidth / 2;\n\t\t\t\t} else {\n\t\t\t\t\tcenterLeft -= legendWidth / 2;\n\t\t\t\t}\n\t\t\t\tif (centerLeft < maxRadius) {\n\t\t\t\t\tcenterLeft = maxRadius;\n\t\t\t\t} else if (centerLeft > canvasWidth - maxRadius) {\n\t\t\t\t\tcenterLeft = canvasWidth - maxRadius;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tcenterLeft += options.series.pie.offset.left;\n\t\t\t}\n\n\t\t\tvar slices = plot.getData(),\n\t\t\t\tattempts = 0;\n\n\t\t\t// Keep shrinking the pie's radius until drawPie returns true,\n\t\t\t// indicating that all the labels fit, or we try too many times.\n\n\t\t\tdo {\n\t\t\t\tif (attempts > 0) {\n\t\t\t\t\tmaxRadius *= REDRAW_SHRINK;\n\t\t\t\t}\n\t\t\t\tattempts += 1;\n\t\t\t\tclear();\n\t\t\t\tif (options.series.pie.tilt <= 0.8) {\n\t\t\t\t\tdrawShadow();\n\t\t\t\t}\n\t\t\t} while (!drawPie() && attempts < REDRAW_ATTEMPTS)\n\n\t\t\tif (attempts >= REDRAW_ATTEMPTS) {\n\t\t\t\tclear();\n\t\t\t\ttarget.prepend(\"<div class='error'>Could not draw pie with labels contained inside canvas</div>\");\n\t\t\t}\n\n\t\t\tif (plot.setSeries && plot.insertLegend) {\n\t\t\t\tplot.setSeries(slices);\n\t\t\t\tplot.insertLegend();\n\t\t\t}\n\n\t\t\t// we're actually done at this point, just defining internal functions at this point\n\n\t\t\tfunction clear() {\n\t\t\t\tctx.clearRect(0, 0, canvasWidth, canvasHeight);\n\t\t\t\ttarget.children().filter(\".pieLabel, .pieLabelBackground\").remove();\n\t\t\t}\n\n\t\t\tfunction drawShadow() {\n\n\t\t\t\tvar shadowLeft = options.series.pie.shadow.left;\n\t\t\t\tvar shadowTop = options.series.pie.shadow.top;\n\t\t\t\tvar edge = 10;\n\t\t\t\tvar alpha = options.series.pie.shadow.alpha;\n\t\t\t\tvar radius = options.series.pie.radius > 1 ? options.series.pie.radius : maxRadius * options.series.pie.radius;\n\n\t\t\t\tif (radius >= canvasWidth / 2 - shadowLeft || radius * options.series.pie.tilt >= canvasHeight / 2 - shadowTop || radius <= edge) {\n\t\t\t\t\treturn;\t// shadow would be outside canvas, so don't draw it\n\t\t\t\t}\n\n\t\t\t\tctx.save();\n\t\t\t\tctx.translate(shadowLeft,shadowTop);\n\t\t\t\tctx.globalAlpha = alpha;\n\t\t\t\tctx.fillStyle = \"#000\";\n\n\t\t\t\t// center and rotate to starting position\n\n\t\t\t\tctx.translate(centerLeft,centerTop);\n\t\t\t\tctx.scale(1, options.series.pie.tilt);\n\n\t\t\t\t//radius -= edge;\n\n\t\t\t\tfor (var i = 1; i <= edge; i++) {\n\t\t\t\t\tctx.beginPath();\n\t\t\t\t\tctx.arc(0, 0, radius, 0, Math.PI * 2, false);\n\t\t\t\t\tctx.fill();\n\t\t\t\t\tradius -= i;\n\t\t\t\t}\n\n\t\t\t\tctx.restore();\n\t\t\t}\n\n\t\t\tfunction drawPie() {\n\n\t\t\t\tvar startAngle = Math.PI * options.series.pie.startAngle;\n\t\t\t\tvar radius = options.series.pie.radius > 1 ? options.series.pie.radius : maxRadius * options.series.pie.radius;\n\n\t\t\t\t// center and rotate to starting position\n\n\t\t\t\tctx.save();\n\t\t\t\tctx.translate(centerLeft,centerTop);\n\t\t\t\tctx.scale(1, options.series.pie.tilt);\n\t\t\t\t//ctx.rotate(startAngle); // start at top; -- This doesn't work properly in Opera\n\n\t\t\t\t// draw slices\n\n\t\t\t\tctx.save();\n\t\t\t\tvar currentAngle = startAngle;\n\t\t\t\tfor (var i = 0; i < slices.length; ++i) {\n\t\t\t\t\tslices[i].startAngle = currentAngle;\n\t\t\t\t\tdrawSlice(slices[i].angle, slices[i].color, true);\n\t\t\t\t}\n\t\t\t\tctx.restore();\n\n\t\t\t\t// draw slice outlines\n\n\t\t\t\tif (options.series.pie.stroke.width > 0) {\n\t\t\t\t\tctx.save();\n\t\t\t\t\tctx.lineWidth = options.series.pie.stroke.width;\n\t\t\t\t\tcurrentAngle = startAngle;\n\t\t\t\t\tfor (var i = 0; i < slices.length; ++i) {\n\t\t\t\t\t\tdrawSlice(slices[i].angle, options.series.pie.stroke.color, false);\n\t\t\t\t\t}\n\t\t\t\t\tctx.restore();\n\t\t\t\t}\n\n\t\t\t\t// draw donut hole\n\n\t\t\t\tdrawDonutHole(ctx);\n\n\t\t\t\tctx.restore();\n\n\t\t\t\t// Draw the labels, returning true if they fit within the plot\n\n\t\t\t\tif (options.series.pie.label.show) {\n\t\t\t\t\treturn drawLabels();\n\t\t\t\t} else return true;\n\n\t\t\t\tfunction drawSlice(angle, color, fill) {\n\n\t\t\t\t\tif (angle <= 0 || isNaN(angle)) {\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\n\t\t\t\t\tif (fill) {\n\t\t\t\t\t\tctx.fillStyle = color;\n\t\t\t\t\t} else {\n\t\t\t\t\t\tctx.strokeStyle = color;\n\t\t\t\t\t\tctx.lineJoin = \"round\";\n\t\t\t\t\t}\n\n\t\t\t\t\tctx.beginPath();\n\t\t\t\t\tif (Math.abs(angle - Math.PI * 2) > 0.000000001) {\n\t\t\t\t\t\tctx.moveTo(0, 0); // Center of the pie\n\t\t\t\t\t}\n\n\t\t\t\t\t//ctx.arc(0, 0, radius, 0, angle, false); // This doesn't work properly in Opera\n\t\t\t\t\tctx.arc(0, 0, radius,currentAngle, currentAngle + angle / 2, false);\n\t\t\t\t\tctx.arc(0, 0, radius,currentAngle + angle / 2, currentAngle + angle, false);\n\t\t\t\t\tctx.closePath();\n\t\t\t\t\t//ctx.rotate(angle); // This doesn't work properly in Opera\n\t\t\t\t\tcurrentAngle += angle;\n\n\t\t\t\t\tif (fill) {\n\t\t\t\t\t\tctx.fill();\n\t\t\t\t\t} else {\n\t\t\t\t\t\tctx.stroke();\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tfunction drawLabels() {\n\n\t\t\t\t\tvar currentAngle = startAngle;\n\t\t\t\t\tvar radius = options.series.pie.label.radius > 1 ? options.series.pie.label.radius : maxRadius * options.series.pie.label.radius;\n\n\t\t\t\t\tfor (var i = 0; i < slices.length; ++i) {\n\t\t\t\t\t\tif (slices[i].percent >= options.series.pie.label.threshold * 100) {\n\t\t\t\t\t\t\tif (!drawLabel(slices[i], currentAngle, i)) {\n\t\t\t\t\t\t\t\treturn false;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\tcurrentAngle += slices[i].angle;\n\t\t\t\t\t}\n\n\t\t\t\t\treturn true;\n\n\t\t\t\t\tfunction drawLabel(slice, startAngle, index) {\n\n\t\t\t\t\t\tif (slice.data[0][1] == 0) {\n\t\t\t\t\t\t\treturn true;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// format label text\n\n\t\t\t\t\t\tvar lf = options.legend.labelFormatter, text, plf = options.series.pie.label.formatter;\n\n\t\t\t\t\t\tif (lf) {\n\t\t\t\t\t\t\ttext = lf(slice.label, slice);\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\ttext = slice.label;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif (plf) {\n\t\t\t\t\t\t\ttext = plf(text, slice);\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tvar halfAngle = ((startAngle + slice.angle) + startAngle) / 2;\n\t\t\t\t\t\tvar x = centerLeft + Math.round(Math.cos(halfAngle) * radius);\n\t\t\t\t\t\tvar y = centerTop + Math.round(Math.sin(halfAngle) * radius) * options.series.pie.tilt;\n\n\t\t\t\t\t\tvar html = \"<span class='pieLabel' id='pieLabel\" + index + \"' style='position:absolute;top:\" + y + \"px;left:\" + x + \"px;'>\" + text + \"</span>\";\n\t\t\t\t\t\ttarget.append(html);\n\n\t\t\t\t\t\tvar label = target.children(\"#pieLabel\" + index);\n\t\t\t\t\t\tvar labelTop = (y - label.height() / 2);\n\t\t\t\t\t\tvar labelLeft = (x - label.width() / 2);\n\n\t\t\t\t\t\tlabel.css(\"top\", labelTop);\n\t\t\t\t\t\tlabel.css(\"left\", labelLeft);\n\n\t\t\t\t\t\t// check to make sure that the label is not outside the canvas\n\n\t\t\t\t\t\tif (0 - labelTop > 0 || 0 - labelLeft > 0 || canvasHeight - (labelTop + label.height()) < 0 || canvasWidth - (labelLeft + label.width()) < 0) {\n\t\t\t\t\t\t\treturn false;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif (options.series.pie.label.background.opacity != 0) {\n\n\t\t\t\t\t\t\t// put in the transparent background separately to avoid blended labels and label boxes\n\n\t\t\t\t\t\t\tvar c = options.series.pie.label.background.color;\n\n\t\t\t\t\t\t\tif (c == null) {\n\t\t\t\t\t\t\t\tc = slice.color;\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tvar pos = \"top:\" + labelTop + \"px;left:\" + labelLeft + \"px;\";\n\t\t\t\t\t\t\t$(\"<div class='pieLabelBackground' style='position:absolute;width:\" + label.width() + \"px;height:\" + label.height() + \"px;\" + pos + \"background-color:\" + c + \";'></div>\")\n\t\t\t\t\t\t\t\t.css(\"opacity\", options.series.pie.label.background.opacity)\n\t\t\t\t\t\t\t\t.insertBefore(label);\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\treturn true;\n\t\t\t\t\t} // end individual label function\n\t\t\t\t} // end drawLabels function\n\t\t\t} // end drawPie function\n\t\t} // end draw function\n\n\t\t// Placed here because it needs to be accessed from multiple locations\n\n\t\tfunction drawDonutHole(layer) {\n\t\t\tif (options.series.pie.innerRadius > 0) {\n\n\t\t\t\t// subtract the center\n\n\t\t\t\tlayer.save();\n\t\t\t\tvar innerRadius = options.series.pie.innerRadius > 1 ? options.series.pie.innerRadius : maxRadius * options.series.pie.innerRadius;\n\t\t\t\tlayer.globalCompositeOperation = \"destination-out\"; // this does not work with excanvas, but it will fall back to using the stroke color\n\t\t\t\tlayer.beginPath();\n\t\t\t\tlayer.fillStyle = options.series.pie.stroke.color;\n\t\t\t\tlayer.arc(0, 0, innerRadius, 0, Math.PI * 2, false);\n\t\t\t\tlayer.fill();\n\t\t\t\tlayer.closePath();\n\t\t\t\tlayer.restore();\n\n\t\t\t\t// add inner stroke\n\n\t\t\t\tlayer.save();\n\t\t\t\tlayer.beginPath();\n\t\t\t\tlayer.strokeStyle = options.series.pie.stroke.color;\n\t\t\t\tlayer.arc(0, 0, innerRadius, 0, Math.PI * 2, false);\n\t\t\t\tlayer.stroke();\n\t\t\t\tlayer.closePath();\n\t\t\t\tlayer.restore();\n\n\t\t\t\t// TODO: add extra shadow inside hole (with a mask) if the pie is tilted.\n\t\t\t}\n\t\t}\n\n\t\t//-- Additional Interactive related functions --\n\n\t\tfunction isPointInPoly(poly, pt) {\n\t\t\tfor(var c = false, i = -1, l = poly.length, j = l - 1; ++i < l; j = i)\n\t\t\t\t((poly[i][1] <= pt[1] && pt[1] < poly[j][1]) || (poly[j][1] <= pt[1] && pt[1]< poly[i][1]))\n\t\t\t\t&& (pt[0] < (poly[j][0] - poly[i][0]) * (pt[1] - poly[i][1]) / (poly[j][1] - poly[i][1]) + poly[i][0])\n\t\t\t\t&& (c = !c);\n\t\t\treturn c;\n\t\t}\n\n\t\tfunction findNearbySlice(mouseX, mouseY) {\n\n\t\t\tvar slices = plot.getData(),\n\t\t\t\toptions = plot.getOptions(),\n\t\t\t\tradius = options.series.pie.radius > 1 ? options.series.pie.radius : maxRadius * options.series.pie.radius,\n\t\t\t\tx, y;\n\n\t\t\tfor (var i = 0; i < slices.length; ++i) {\n\n\t\t\t\tvar s = slices[i];\n\n\t\t\t\tif (s.pie.show) {\n\n\t\t\t\t\tctx.save();\n\t\t\t\t\tctx.beginPath();\n\t\t\t\t\tctx.moveTo(0, 0); // Center of the pie\n\t\t\t\t\t//ctx.scale(1, options.series.pie.tilt);\t// this actually seems to break everything when here.\n\t\t\t\t\tctx.arc(0, 0, radius, s.startAngle, s.startAngle + s.angle / 2, false);\n\t\t\t\t\tctx.arc(0, 0, radius, s.startAngle + s.angle / 2, s.startAngle + s.angle, false);\n\t\t\t\t\tctx.closePath();\n\t\t\t\t\tx = mouseX - centerLeft;\n\t\t\t\t\ty = mouseY - centerTop;\n\n\t\t\t\t\tif (ctx.isPointInPath) {\n\t\t\t\t\t\tif (ctx.isPointInPath(mouseX - centerLeft, mouseY - centerTop)) {\n\t\t\t\t\t\t\tctx.restore();\n\t\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\t\tdatapoint: [s.percent, s.data],\n\t\t\t\t\t\t\t\tdataIndex: 0,\n\t\t\t\t\t\t\t\tseries: s,\n\t\t\t\t\t\t\t\tseriesIndex: i\n\t\t\t\t\t\t\t};\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\t// excanvas for IE doesn;t support isPointInPath, this is a workaround.\n\n\t\t\t\t\t\tvar p1X = radius * Math.cos(s.startAngle),\n\t\t\t\t\t\t\tp1Y = radius * Math.sin(s.startAngle),\n\t\t\t\t\t\t\tp2X = radius * Math.cos(s.startAngle + s.angle / 4),\n\t\t\t\t\t\t\tp2Y = radius * Math.sin(s.startAngle + s.angle / 4),\n\t\t\t\t\t\t\tp3X = radius * Math.cos(s.startAngle + s.angle / 2),\n\t\t\t\t\t\t\tp3Y = radius * Math.sin(s.startAngle + s.angle / 2),\n\t\t\t\t\t\t\tp4X = radius * Math.cos(s.startAngle + s.angle / 1.5),\n\t\t\t\t\t\t\tp4Y = radius * Math.sin(s.startAngle + s.angle / 1.5),\n\t\t\t\t\t\t\tp5X = radius * Math.cos(s.startAngle + s.angle),\n\t\t\t\t\t\t\tp5Y = radius * Math.sin(s.startAngle + s.angle),\n\t\t\t\t\t\t\tarrPoly = [[0, 0], [p1X, p1Y], [p2X, p2Y], [p3X, p3Y], [p4X, p4Y], [p5X, p5Y]],\n\t\t\t\t\t\t\tarrPoint = [x, y];\n\n\t\t\t\t\t\t// TODO: perhaps do some mathmatical trickery here with the Y-coordinate to compensate for pie tilt?\n\n\t\t\t\t\t\tif (isPointInPoly(arrPoly, arrPoint)) {\n\t\t\t\t\t\t\tctx.restore();\n\t\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\t\tdatapoint: [s.percent, s.data],\n\t\t\t\t\t\t\t\tdataIndex: 0,\n\t\t\t\t\t\t\t\tseries: s,\n\t\t\t\t\t\t\t\tseriesIndex: i\n\t\t\t\t\t\t\t};\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tctx.restore();\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn null;\n\t\t}\n\n\t\tfunction onMouseMove(e) {\n\t\t\ttriggerClickHoverEvent(\"plothover\", e);\n\t\t}\n\n\t\tfunction onClick(e) {\n\t\t\ttriggerClickHoverEvent(\"plotclick\", e);\n\t\t}\n\n\t\t// trigger click or hover event (they send the same parameters so we share their code)\n\n\t\tfunction triggerClickHoverEvent(eventname, e) {\n\n\t\t\tvar offset = plot.offset();\n\t\t\tvar canvasX = parseInt(e.pageX - offset.left);\n\t\t\tvar canvasY =  parseInt(e.pageY - offset.top);\n\t\t\tvar item = findNearbySlice(canvasX, canvasY);\n\n\t\t\tif (options.grid.autoHighlight) {\n\n\t\t\t\t// clear auto-highlights\n\n\t\t\t\tfor (var i = 0; i < highlights.length; ++i) {\n\t\t\t\t\tvar h = highlights[i];\n\t\t\t\t\tif (h.auto == eventname && !(item && h.series == item.series)) {\n\t\t\t\t\t\tunhighlight(h.series);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// highlight the slice\n\n\t\t\tif (item) {\n\t\t\t\thighlight(item.series, eventname);\n\t\t\t}\n\n\t\t\t// trigger any hover bind events\n\n\t\t\tvar pos = { pageX: e.pageX, pageY: e.pageY };\n\t\t\ttarget.trigger(eventname, [pos, item]);\n\t\t}\n\n\t\tfunction highlight(s, auto) {\n\t\t\t//if (typeof s == \"number\") {\n\t\t\t//\ts = series[s];\n\t\t\t//}\n\n\t\t\tvar i = indexOfHighlight(s);\n\n\t\t\tif (i == -1) {\n\t\t\t\thighlights.push({ series: s, auto: auto });\n\t\t\t\tplot.triggerRedrawOverlay();\n\t\t\t} else if (!auto) {\n\t\t\t\thighlights[i].auto = false;\n\t\t\t}\n\t\t}\n\n\t\tfunction unhighlight(s) {\n\t\t\tif (s == null) {\n\t\t\t\thighlights = [];\n\t\t\t\tplot.triggerRedrawOverlay();\n\t\t\t}\n\n\t\t\t//if (typeof s == \"number\") {\n\t\t\t//\ts = series[s];\n\t\t\t//}\n\n\t\t\tvar i = indexOfHighlight(s);\n\n\t\t\tif (i != -1) {\n\t\t\t\thighlights.splice(i, 1);\n\t\t\t\tplot.triggerRedrawOverlay();\n\t\t\t}\n\t\t}\n\n\t\tfunction indexOfHighlight(s) {\n\t\t\tfor (var i = 0; i < highlights.length; ++i) {\n\t\t\t\tvar h = highlights[i];\n\t\t\t\tif (h.series == s)\n\t\t\t\t\treturn i;\n\t\t\t}\n\t\t\treturn -1;\n\t\t}\n\n\t\tfunction drawOverlay(plot, octx) {\n\n\t\t\tvar options = plot.getOptions();\n\n\t\t\tvar radius = options.series.pie.radius > 1 ? options.series.pie.radius : maxRadius * options.series.pie.radius;\n\n\t\t\toctx.save();\n\t\t\toctx.translate(centerLeft, centerTop);\n\t\t\toctx.scale(1, options.series.pie.tilt);\n\n\t\t\tfor (var i = 0; i < highlights.length; ++i) {\n\t\t\t\tdrawHighlight(highlights[i].series);\n\t\t\t}\n\n\t\t\tdrawDonutHole(octx);\n\n\t\t\toctx.restore();\n\n\t\t\tfunction drawHighlight(series) {\n\n\t\t\t\tif (series.angle <= 0 || isNaN(series.angle)) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\t//octx.fillStyle = parseColor(options.series.pie.highlight.color).scale(null, null, null, options.series.pie.highlight.opacity).toString();\n\t\t\t\toctx.fillStyle = \"rgba(255, 255, 255, \" + options.series.pie.highlight.opacity + \")\"; // this is temporary until we have access to parseColor\n\t\t\t\toctx.beginPath();\n\t\t\t\tif (Math.abs(series.angle - Math.PI * 2) > 0.000000001) {\n\t\t\t\t\toctx.moveTo(0, 0); // Center of the pie\n\t\t\t\t}\n\t\t\t\toctx.arc(0, 0, radius, series.startAngle, series.startAngle + series.angle / 2, false);\n\t\t\t\toctx.arc(0, 0, radius, series.startAngle + series.angle / 2, series.startAngle + series.angle, false);\n\t\t\t\toctx.closePath();\n\t\t\t\toctx.fill();\n\t\t\t}\n\t\t}\n\t} // end init (plugin body)\n\n\t// define pie specific options and their default values\n\n\tvar options = {\n\t\tseries: {\n\t\t\tpie: {\n\t\t\t\tshow: false,\n\t\t\t\tradius: \"auto\",\t// actual radius of the visible pie (based on full calculated radius if <=1, or hard pixel value)\n\t\t\t\tinnerRadius: 0, /* for donut */\n\t\t\t\tstartAngle: 3/2,\n\t\t\t\ttilt: 1,\n\t\t\t\tshadow: {\n\t\t\t\t\tleft: 5,\t// shadow left offset\n\t\t\t\t\ttop: 15,\t// shadow top offset\n\t\t\t\t\talpha: 0.02\t// shadow alpha\n\t\t\t\t},\n\t\t\t\toffset: {\n\t\t\t\t\ttop: 0,\n\t\t\t\t\tleft: \"auto\"\n\t\t\t\t},\n\t\t\t\tstroke: {\n\t\t\t\t\tcolor: \"#fff\",\n\t\t\t\t\twidth: 1\n\t\t\t\t},\n\t\t\t\tlabel: {\n\t\t\t\t\tshow: \"auto\",\n\t\t\t\t\tformatter: function(label, slice) {\n\t\t\t\t\t\treturn \"<div style='font-size:x-small;text-align:center;padding:2px;color:\" + slice.color + \";'>\" + label + \"<br/>\" + Math.round(slice.percent) + \"%</div>\";\n\t\t\t\t\t},\t// formatter function\n\t\t\t\t\tradius: 1,\t// radius at which to place the labels (based on full calculated radius if <=1, or hard pixel value)\n\t\t\t\t\tbackground: {\n\t\t\t\t\t\tcolor: null,\n\t\t\t\t\t\topacity: 0\n\t\t\t\t\t},\n\t\t\t\t\tthreshold: 0\t// percentage at which to hide the label (i.e. the slice is too narrow)\n\t\t\t\t},\n\t\t\t\tcombine: {\n\t\t\t\t\tthreshold: -1,\t// percentage at which to combine little slices into one larger slice\n\t\t\t\t\tcolor: null,\t// color to give the new slice (auto-generated if null)\n\t\t\t\t\tlabel: \"Other\"\t// label to give the new slice\n\t\t\t\t},\n\t\t\t\thighlight: {\n\t\t\t\t\t//color: \"#fff\",\t\t// will add this functionality once parseColor is available\n\t\t\t\t\topacity: 0.5\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t};\n\n\t$.plot.plugins.push({\n\t\tinit: init,\n\t\toptions: options,\n\t\tname: \"pie\",\n\t\tversion: \"1.1\"\n\t});\n\n})(jQuery);\n"
  },
  {
    "path": "app_backend/vendor/flot/jquery.flot.resize.js",
    "content": "/* Flot plugin for automatically redrawing plots as the placeholder resizes.\n\nCopyright (c) 2007-2014 IOLA and Ole Laursen.\nLicensed under the MIT license.\n\nIt works by listening for changes on the placeholder div (through the jQuery\nresize event plugin) - if the size changes, it will redraw the plot.\n\nThere are no options. If you need to disable the plugin for some plots, you\ncan just fix the size of their placeholders.\n\n*/\n\n/* Inline dependency:\n * jQuery resize event - v1.1 - 3/14/2010\n * http://benalman.com/projects/jquery-resize-plugin/\n *\n * Copyright (c) 2010 \"Cowboy\" Ben Alman\n * Dual licensed under the MIT and GPL licenses.\n * http://benalman.com/about/license/\n */\n(function($,e,t){\"$:nomunge\";var i=[],n=$.resize=$.extend($.resize,{}),a,r=false,s=\"setTimeout\",u=\"resize\",m=u+\"-special-event\",o=\"pendingDelay\",l=\"activeDelay\",f=\"throttleWindow\";n[o]=200;n[l]=20;n[f]=true;$.event.special[u]={setup:function(){if(!n[f]&&this[s]){return false}var e=$(this);i.push(this);e.data(m,{w:e.width(),h:e.height()});if(i.length===1){a=t;h()}},teardown:function(){if(!n[f]&&this[s]){return false}var e=$(this);for(var t=i.length-1;t>=0;t--){if(i[t]==this){i.splice(t,1);break}}e.removeData(m);if(!i.length){if(r){cancelAnimationFrame(a)}else{clearTimeout(a)}a=null}},add:function(e){if(!n[f]&&this[s]){return false}var i;function a(e,n,a){var r=$(this),s=r.data(m)||{};s.w=n!==t?n:r.width();s.h=a!==t?a:r.height();i.apply(this,arguments)}if($.isFunction(e)){i=e;return a}else{i=e.handler;e.handler=a}}};function h(t){if(r===true){r=t||1}for(var s=i.length-1;s>=0;s--){var l=$(i[s]);if(l[0]==e||l.is(\":visible\")){var f=l.width(),c=l.height(),d=l.data(m);if(d&&(f!==d.w||c!==d.h)){l.trigger(u,[d.w=f,d.h=c]);r=t||true}}else{d=l.data(m);d.w=0;d.h=0}}if(a!==null){if(r&&(t==null||t-r<1e3)){a=e.requestAnimationFrame(h)}else{a=setTimeout(h,n[o]);r=false}}}if(!e.requestAnimationFrame){e.requestAnimationFrame=function(){return e.webkitRequestAnimationFrame||e.mozRequestAnimationFrame||e.oRequestAnimationFrame||e.msRequestAnimationFrame||function(t,i){return e.setTimeout(function(){t((new Date).getTime())},n[l])}}()}if(!e.cancelAnimationFrame){e.cancelAnimationFrame=function(){return e.webkitCancelRequestAnimationFrame||e.mozCancelRequestAnimationFrame||e.oCancelRequestAnimationFrame||e.msCancelRequestAnimationFrame||clearTimeout}()}})(jQuery,this);\n\n(function ($) {\n    var options = { }; // no options\n\n    function init(plot) {\n        function onResize() {\n            var placeholder = plot.getPlaceholder();\n\n            // somebody might have hidden us and we can't plot\n            // when we don't have the dimensions\n            if (placeholder.width() == 0 || placeholder.height() == 0)\n                return;\n\n            plot.resize();\n            plot.setupGrid();\n            plot.draw();\n        }\n        \n        function bindEvents(plot, eventHolder) {\n            plot.getPlaceholder().resize(onResize);\n        }\n\n        function shutdown(plot, eventHolder) {\n            plot.getPlaceholder().unbind(\"resize\", onResize);\n        }\n        \n        plot.hooks.bindEvents.push(bindEvents);\n        plot.hooks.shutdown.push(shutdown);\n    }\n    \n    $.plot.plugins.push({\n        init: init,\n        options: options,\n        name: 'resize',\n        version: '1.0'\n    });\n})(jQuery);\n"
  },
  {
    "path": "app_backend/vendor/flot/jquery.flot.selection.js",
    "content": "/* Flot plugin for selecting regions of a plot.\n\nCopyright (c) 2007-2014 IOLA and Ole Laursen.\nLicensed under the MIT license.\n\nThe plugin supports these options:\n\nselection: {\n\tmode: null or \"x\" or \"y\" or \"xy\",\n\tcolor: color,\n\tshape: \"round\" or \"miter\" or \"bevel\",\n\tminSize: number of pixels\n}\n\nSelection support is enabled by setting the mode to one of \"x\", \"y\" or \"xy\".\nIn \"x\" mode, the user will only be able to specify the x range, similarly for\n\"y\" mode. For \"xy\", the selection becomes a rectangle where both ranges can be\nspecified. \"color\" is color of the selection (if you need to change the color\nlater on, you can get to it with plot.getOptions().selection.color). \"shape\"\nis the shape of the corners of the selection.\n\n\"minSize\" is the minimum size a selection can be in pixels. This value can\nbe customized to determine the smallest size a selection can be and still\nhave the selection rectangle be displayed. When customizing this value, the\nfact that it refers to pixels, not axis units must be taken into account.\nThus, for example, if there is a bar graph in time mode with BarWidth set to 1\nminute, setting \"minSize\" to 1 will not make the minimum selection size 1\nminute, but rather 1 pixel. Note also that setting \"minSize\" to 0 will prevent\n\"plotunselected\" events from being fired when the user clicks the mouse without\ndragging.\n\nWhen selection support is enabled, a \"plotselected\" event will be emitted on\nthe DOM element you passed into the plot function. The event handler gets a\nparameter with the ranges selected on the axes, like this:\n\n\tplaceholder.bind( \"plotselected\", function( event, ranges ) {\n\t\talert(\"You selected \" + ranges.xaxis.from + \" to \" + ranges.xaxis.to)\n\t\t// similar for yaxis - with multiple axes, the extra ones are in\n\t\t// x2axis, x3axis, ...\n\t});\n\nThe \"plotselected\" event is only fired when the user has finished making the\nselection. A \"plotselecting\" event is fired during the process with the same\nparameters as the \"plotselected\" event, in case you want to know what's\nhappening while it's happening,\n\nA \"plotunselected\" event with no arguments is emitted when the user clicks the\nmouse to remove the selection. As stated above, setting \"minSize\" to 0 will\ndestroy this behavior.\n\nThe plugin allso adds the following methods to the plot object:\n\n- setSelection( ranges, preventEvent )\n\n  Set the selection rectangle. The passed in ranges is on the same form as\n  returned in the \"plotselected\" event. If the selection mode is \"x\", you\n  should put in either an xaxis range, if the mode is \"y\" you need to put in\n  an yaxis range and both xaxis and yaxis if the selection mode is \"xy\", like\n  this:\n\n\tsetSelection({ xaxis: { from: 0, to: 10 }, yaxis: { from: 40, to: 60 } });\n\n  setSelection will trigger the \"plotselected\" event when called. If you don't\n  want that to happen, e.g. if you're inside a \"plotselected\" handler, pass\n  true as the second parameter. If you are using multiple axes, you can\n  specify the ranges on any of those, e.g. as x2axis/x3axis/... instead of\n  xaxis, the plugin picks the first one it sees.\n\n- clearSelection( preventEvent )\n\n  Clear the selection rectangle. Pass in true to avoid getting a\n  \"plotunselected\" event.\n\n- getSelection()\n\n  Returns the current selection in the same format as the \"plotselected\"\n  event. If there's currently no selection, the function returns null.\n\n*/\n\n(function ($) {\n    function init(plot) {\n        var selection = {\n                first: { x: -1, y: -1}, second: { x: -1, y: -1},\n                show: false,\n                active: false\n            };\n\n        // FIXME: The drag handling implemented here should be\n        // abstracted out, there's some similar code from a library in\n        // the navigation plugin, this should be massaged a bit to fit\n        // the Flot cases here better and reused. Doing this would\n        // make this plugin much slimmer.\n        var savedhandlers = {};\n\n        var mouseUpHandler = null;\n        \n        function onMouseMove(e) {\n            if (selection.active) {\n                updateSelection(e);\n                \n                plot.getPlaceholder().trigger(\"plotselecting\", [ getSelection() ]);\n            }\n        }\n\n        function onMouseDown(e) {\n            if (e.which != 1)  // only accept left-click\n                return;\n            \n            // cancel out any text selections\n            document.body.focus();\n\n            // prevent text selection and drag in old-school browsers\n            if (document.onselectstart !== undefined && savedhandlers.onselectstart == null) {\n                savedhandlers.onselectstart = document.onselectstart;\n                document.onselectstart = function () { return false; };\n            }\n            if (document.ondrag !== undefined && savedhandlers.ondrag == null) {\n                savedhandlers.ondrag = document.ondrag;\n                document.ondrag = function () { return false; };\n            }\n\n            setSelectionPos(selection.first, e);\n\n            selection.active = true;\n\n            // this is a bit silly, but we have to use a closure to be\n            // able to whack the same handler again\n            mouseUpHandler = function (e) { onMouseUp(e); };\n            \n            $(document).one(\"mouseup\", mouseUpHandler);\n        }\n\n        function onMouseUp(e) {\n            mouseUpHandler = null;\n            \n            // revert drag stuff for old-school browsers\n            if (document.onselectstart !== undefined)\n                document.onselectstart = savedhandlers.onselectstart;\n            if (document.ondrag !== undefined)\n                document.ondrag = savedhandlers.ondrag;\n\n            // no more dragging\n            selection.active = false;\n            updateSelection(e);\n\n            if (selectionIsSane())\n                triggerSelectedEvent();\n            else {\n                // this counts as a clear\n                plot.getPlaceholder().trigger(\"plotunselected\", [ ]);\n                plot.getPlaceholder().trigger(\"plotselecting\", [ null ]);\n            }\n\n            return false;\n        }\n\n        function getSelection() {\n            if (!selectionIsSane())\n                return null;\n            \n            if (!selection.show) return null;\n\n            var r = {}, c1 = selection.first, c2 = selection.second;\n            $.each(plot.getAxes(), function (name, axis) {\n                if (axis.used) {\n                    var p1 = axis.c2p(c1[axis.direction]), p2 = axis.c2p(c2[axis.direction]); \n                    r[name] = { from: Math.min(p1, p2), to: Math.max(p1, p2) };\n                }\n            });\n            return r;\n        }\n\n        function triggerSelectedEvent() {\n            var r = getSelection();\n\n            plot.getPlaceholder().trigger(\"plotselected\", [ r ]);\n\n            // backwards-compat stuff, to be removed in future\n            if (r.xaxis && r.yaxis)\n                plot.getPlaceholder().trigger(\"selected\", [ { x1: r.xaxis.from, y1: r.yaxis.from, x2: r.xaxis.to, y2: r.yaxis.to } ]);\n        }\n\n        function clamp(min, value, max) {\n            return value < min ? min: (value > max ? max: value);\n        }\n\n        function setSelectionPos(pos, e) {\n            var o = plot.getOptions();\n            var offset = plot.getPlaceholder().offset();\n            var plotOffset = plot.getPlotOffset();\n            pos.x = clamp(0, e.pageX - offset.left - plotOffset.left, plot.width());\n            pos.y = clamp(0, e.pageY - offset.top - plotOffset.top, plot.height());\n\n            if (o.selection.mode == \"y\")\n                pos.x = pos == selection.first ? 0 : plot.width();\n\n            if (o.selection.mode == \"x\")\n                pos.y = pos == selection.first ? 0 : plot.height();\n        }\n\n        function updateSelection(pos) {\n            if (pos.pageX == null)\n                return;\n\n            setSelectionPos(selection.second, pos);\n            if (selectionIsSane()) {\n                selection.show = true;\n                plot.triggerRedrawOverlay();\n            }\n            else\n                clearSelection(true);\n        }\n\n        function clearSelection(preventEvent) {\n            if (selection.show) {\n                selection.show = false;\n                plot.triggerRedrawOverlay();\n                if (!preventEvent)\n                    plot.getPlaceholder().trigger(\"plotunselected\", [ ]);\n            }\n        }\n\n        // function taken from markings support in Flot\n        function extractRange(ranges, coord) {\n            var axis, from, to, key, axes = plot.getAxes();\n\n            for (var k in axes) {\n                axis = axes[k];\n                if (axis.direction == coord) {\n                    key = coord + axis.n + \"axis\";\n                    if (!ranges[key] && axis.n == 1)\n                        key = coord + \"axis\"; // support x1axis as xaxis\n                    if (ranges[key]) {\n                        from = ranges[key].from;\n                        to = ranges[key].to;\n                        break;\n                    }\n                }\n            }\n\n            // backwards-compat stuff - to be removed in future\n            if (!ranges[key]) {\n                axis = coord == \"x\" ? plot.getXAxes()[0] : plot.getYAxes()[0];\n                from = ranges[coord + \"1\"];\n                to = ranges[coord + \"2\"];\n            }\n\n            // auto-reverse as an added bonus\n            if (from != null && to != null && from > to) {\n                var tmp = from;\n                from = to;\n                to = tmp;\n            }\n            \n            return { from: from, to: to, axis: axis };\n        }\n        \n        function setSelection(ranges, preventEvent) {\n            var axis, range, o = plot.getOptions();\n\n            if (o.selection.mode == \"y\") {\n                selection.first.x = 0;\n                selection.second.x = plot.width();\n            }\n            else {\n                range = extractRange(ranges, \"x\");\n\n                selection.first.x = range.axis.p2c(range.from);\n                selection.second.x = range.axis.p2c(range.to);\n            }\n\n            if (o.selection.mode == \"x\") {\n                selection.first.y = 0;\n                selection.second.y = plot.height();\n            }\n            else {\n                range = extractRange(ranges, \"y\");\n\n                selection.first.y = range.axis.p2c(range.from);\n                selection.second.y = range.axis.p2c(range.to);\n            }\n\n            selection.show = true;\n            plot.triggerRedrawOverlay();\n            if (!preventEvent && selectionIsSane())\n                triggerSelectedEvent();\n        }\n\n        function selectionIsSane() {\n            var minSize = plot.getOptions().selection.minSize;\n            return Math.abs(selection.second.x - selection.first.x) >= minSize &&\n                Math.abs(selection.second.y - selection.first.y) >= minSize;\n        }\n\n        plot.clearSelection = clearSelection;\n        plot.setSelection = setSelection;\n        plot.getSelection = getSelection;\n\n        plot.hooks.bindEvents.push(function(plot, eventHolder) {\n            var o = plot.getOptions();\n            if (o.selection.mode != null) {\n                eventHolder.mousemove(onMouseMove);\n                eventHolder.mousedown(onMouseDown);\n            }\n        });\n\n\n        plot.hooks.drawOverlay.push(function (plot, ctx) {\n            // draw selection\n            if (selection.show && selectionIsSane()) {\n                var plotOffset = plot.getPlotOffset();\n                var o = plot.getOptions();\n\n                ctx.save();\n                ctx.translate(plotOffset.left, plotOffset.top);\n\n                var c = $.color.parse(o.selection.color);\n\n                ctx.strokeStyle = c.scale('a', 0.8).toString();\n                ctx.lineWidth = 1;\n                ctx.lineJoin = o.selection.shape;\n                ctx.fillStyle = c.scale('a', 0.4).toString();\n\n                var x = Math.min(selection.first.x, selection.second.x) + 0.5,\n                    y = Math.min(selection.first.y, selection.second.y) + 0.5,\n                    w = Math.abs(selection.second.x - selection.first.x) - 1,\n                    h = Math.abs(selection.second.y - selection.first.y) - 1;\n\n                ctx.fillRect(x, y, w, h);\n                ctx.strokeRect(x, y, w, h);\n\n                ctx.restore();\n            }\n        });\n        \n        plot.hooks.shutdown.push(function (plot, eventHolder) {\n            eventHolder.unbind(\"mousemove\", onMouseMove);\n            eventHolder.unbind(\"mousedown\", onMouseDown);\n            \n            if (mouseUpHandler)\n                $(document).unbind(\"mouseup\", mouseUpHandler);\n        });\n\n    }\n\n    $.plot.plugins.push({\n        init: init,\n        options: {\n            selection: {\n                mode: null, // one of null, \"x\", \"y\" or \"xy\"\n                color: \"#e8cfac\",\n                shape: \"round\", // one of \"round\", \"miter\", or \"bevel\"\n                minSize: 5 // minimum number of pixels\n            }\n        },\n        name: 'selection',\n        version: '1.1'\n    });\n})(jQuery);\n"
  },
  {
    "path": "app_backend/vendor/flot/jquery.flot.stack.js",
    "content": "/* Flot plugin for stacking data sets rather than overlyaing them.\n\nCopyright (c) 2007-2014 IOLA and Ole Laursen.\nLicensed under the MIT license.\n\nThe plugin assumes the data is sorted on x (or y if stacking horizontally).\nFor line charts, it is assumed that if a line has an undefined gap (from a\nnull point), then the line above it should have the same gap - insert zeros\ninstead of \"null\" if you want another behaviour. This also holds for the start\nand end of the chart. Note that stacking a mix of positive and negative values\nin most instances doesn't make sense (so it looks weird).\n\nTwo or more series are stacked when their \"stack\" attribute is set to the same\nkey (which can be any number or string or just \"true\"). To specify the default\nstack, you can set the stack option like this:\n\n\tseries: {\n\t\tstack: null/false, true, or a key (number/string)\n\t}\n\nYou can also specify it for a single series, like this:\n\n\t$.plot( $(\"#placeholder\"), [{\n\t\tdata: [ ... ],\n\t\tstack: true\n\t}])\n\nThe stacking order is determined by the order of the data series in the array\n(later series end up on top of the previous).\n\nInternally, the plugin modifies the datapoints in each series, adding an\noffset to the y value. For line series, extra data points are inserted through\ninterpolation. If there's a second y value, it's also adjusted (e.g for bar\ncharts or filled areas).\n\n*/\n\n(function ($) {\n    var options = {\n        series: { stack: null } // or number/string\n    };\n    \n    function init(plot) {\n        function findMatchingSeries(s, allseries) {\n            var res = null;\n            for (var i = 0; i < allseries.length; ++i) {\n                if (s == allseries[i])\n                    break;\n                \n                if (allseries[i].stack == s.stack)\n                    res = allseries[i];\n            }\n            \n            return res;\n        }\n        \n        function stackData(plot, s, datapoints) {\n            if (s.stack == null || s.stack === false)\n                return;\n\n            var other = findMatchingSeries(s, plot.getData());\n            if (!other)\n                return;\n\n            var ps = datapoints.pointsize,\n                points = datapoints.points,\n                otherps = other.datapoints.pointsize,\n                otherpoints = other.datapoints.points,\n                newpoints = [],\n                px, py, intery, qx, qy, bottom,\n                withlines = s.lines.show,\n                horizontal = s.bars.horizontal,\n                withbottom = ps > 2 && (horizontal ? datapoints.format[2].x : datapoints.format[2].y),\n                withsteps = withlines && s.lines.steps,\n                fromgap = true,\n                keyOffset = horizontal ? 1 : 0,\n                accumulateOffset = horizontal ? 0 : 1,\n                i = 0, j = 0, l, m;\n\n            while (true) {\n                if (i >= points.length)\n                    break;\n\n                l = newpoints.length;\n\n                if (points[i] == null) {\n                    // copy gaps\n                    for (m = 0; m < ps; ++m)\n                        newpoints.push(points[i + m]);\n                    i += ps;\n                }\n                else if (j >= otherpoints.length) {\n                    // for lines, we can't use the rest of the points\n                    if (!withlines) {\n                        for (m = 0; m < ps; ++m)\n                            newpoints.push(points[i + m]);\n                    }\n                    i += ps;\n                }\n                else if (otherpoints[j] == null) {\n                    // oops, got a gap\n                    for (m = 0; m < ps; ++m)\n                        newpoints.push(null);\n                    fromgap = true;\n                    j += otherps;\n                }\n                else {\n                    // cases where we actually got two points\n                    px = points[i + keyOffset];\n                    py = points[i + accumulateOffset];\n                    qx = otherpoints[j + keyOffset];\n                    qy = otherpoints[j + accumulateOffset];\n                    bottom = 0;\n\n                    if (px == qx) {\n                        for (m = 0; m < ps; ++m)\n                            newpoints.push(points[i + m]);\n\n                        newpoints[l + accumulateOffset] += qy;\n                        bottom = qy;\n                        \n                        i += ps;\n                        j += otherps;\n                    }\n                    else if (px > qx) {\n                        // we got past point below, might need to\n                        // insert interpolated extra point\n                        if (withlines && i > 0 && points[i - ps] != null) {\n                            intery = py + (points[i - ps + accumulateOffset] - py) * (qx - px) / (points[i - ps + keyOffset] - px);\n                            newpoints.push(qx);\n                            newpoints.push(intery + qy);\n                            for (m = 2; m < ps; ++m)\n                                newpoints.push(points[i + m]);\n                            bottom = qy; \n                        }\n\n                        j += otherps;\n                    }\n                    else { // px < qx\n                        if (fromgap && withlines) {\n                            // if we come from a gap, we just skip this point\n                            i += ps;\n                            continue;\n                        }\n                            \n                        for (m = 0; m < ps; ++m)\n                            newpoints.push(points[i + m]);\n                        \n                        // we might be able to interpolate a point below,\n                        // this can give us a better y\n                        if (withlines && j > 0 && otherpoints[j - otherps] != null)\n                            bottom = qy + (otherpoints[j - otherps + accumulateOffset] - qy) * (px - qx) / (otherpoints[j - otherps + keyOffset] - qx);\n\n                        newpoints[l + accumulateOffset] += bottom;\n                        \n                        i += ps;\n                    }\n\n                    fromgap = false;\n                    \n                    if (l != newpoints.length && withbottom)\n                        newpoints[l + 2] += bottom;\n                }\n\n                // maintain the line steps invariant\n                if (withsteps && l != newpoints.length && l > 0\n                    && newpoints[l] != null\n                    && newpoints[l] != newpoints[l - ps]\n                    && newpoints[l + 1] != newpoints[l - ps + 1]) {\n                    for (m = 0; m < ps; ++m)\n                        newpoints[l + ps + m] = newpoints[l + m];\n                    newpoints[l + 1] = newpoints[l - ps + 1];\n                }\n            }\n\n            datapoints.points = newpoints;\n        }\n        \n        plot.hooks.processDatapoints.push(stackData);\n    }\n    \n    $.plot.plugins.push({\n        init: init,\n        options: options,\n        name: 'stack',\n        version: '1.2'\n    });\n})(jQuery);\n"
  },
  {
    "path": "app_backend/vendor/flot/jquery.flot.symbol.js",
    "content": "/* Flot plugin that adds some extra symbols for plotting points.\n\nCopyright (c) 2007-2014 IOLA and Ole Laursen.\nLicensed under the MIT license.\n\nThe symbols are accessed as strings through the standard symbol options:\n\n\tseries: {\n\t\tpoints: {\n\t\t\tsymbol: \"square\" // or \"diamond\", \"triangle\", \"cross\"\n\t\t}\n\t}\n\n*/\n\n(function ($) {\n    function processRawData(plot, series, datapoints) {\n        // we normalize the area of each symbol so it is approximately the\n        // same as a circle of the given radius\n\n        var handlers = {\n            square: function (ctx, x, y, radius, shadow) {\n                // pi * r^2 = (2s)^2  =>  s = r * sqrt(pi)/2\n                var size = radius * Math.sqrt(Math.PI) / 2;\n                ctx.rect(x - size, y - size, size + size, size + size);\n            },\n            diamond: function (ctx, x, y, radius, shadow) {\n                // pi * r^2 = 2s^2  =>  s = r * sqrt(pi/2)\n                var size = radius * Math.sqrt(Math.PI / 2);\n                ctx.moveTo(x - size, y);\n                ctx.lineTo(x, y - size);\n                ctx.lineTo(x + size, y);\n                ctx.lineTo(x, y + size);\n                ctx.lineTo(x - size, y);\n            },\n            triangle: function (ctx, x, y, radius, shadow) {\n                // pi * r^2 = 1/2 * s^2 * sin (pi / 3)  =>  s = r * sqrt(2 * pi / sin(pi / 3))\n                var size = radius * Math.sqrt(2 * Math.PI / Math.sin(Math.PI / 3));\n                var height = size * Math.sin(Math.PI / 3);\n                ctx.moveTo(x - size/2, y + height/2);\n                ctx.lineTo(x + size/2, y + height/2);\n                if (!shadow) {\n                    ctx.lineTo(x, y - height/2);\n                    ctx.lineTo(x - size/2, y + height/2);\n                }\n            },\n            cross: function (ctx, x, y, radius, shadow) {\n                // pi * r^2 = (2s)^2  =>  s = r * sqrt(pi)/2\n                var size = radius * Math.sqrt(Math.PI) / 2;\n                ctx.moveTo(x - size, y - size);\n                ctx.lineTo(x + size, y + size);\n                ctx.moveTo(x - size, y + size);\n                ctx.lineTo(x + size, y - size);\n            }\n        };\n\n        var s = series.points.symbol;\n        if (handlers[s])\n            series.points.symbol = handlers[s];\n    }\n    \n    function init(plot) {\n        plot.hooks.processDatapoints.push(processRawData);\n    }\n    \n    $.plot.plugins.push({\n        init: init,\n        name: 'symbols',\n        version: '1.0'\n    });\n})(jQuery);\n"
  },
  {
    "path": "app_backend/vendor/flot/jquery.flot.threshold.js",
    "content": "/* Flot plugin for thresholding data.\n\nCopyright (c) 2007-2014 IOLA and Ole Laursen.\nLicensed under the MIT license.\n\nThe plugin supports these options:\n\n\tseries: {\n\t\tthreshold: {\n\t\t\tbelow: number\n\t\t\tcolor: colorspec\n\t\t}\n\t}\n\nIt can also be applied to a single series, like this:\n\n\t$.plot( $(\"#placeholder\"), [{\n\t\tdata: [ ... ],\n\t\tthreshold: { ... }\n\t}])\n\nAn array can be passed for multiple thresholding, like this:\n\n\tthreshold: [{\n\t\tbelow: number1\n\t\tcolor: color1\n\t},{\n\t\tbelow: number2\n\t\tcolor: color2\n\t}]\n\nThese multiple threshold objects can be passed in any order since they are\nsorted by the processing function.\n\nThe data points below \"below\" are drawn with the specified color. This makes\nit easy to mark points below 0, e.g. for budget data.\n\nInternally, the plugin works by splitting the data into two series, above and\nbelow the threshold. The extra series below the threshold will have its label\ncleared and the special \"originSeries\" attribute set to the original series.\nYou may need to check for this in hover events.\n\n*/\n\n(function ($) {\n    var options = {\n        series: { threshold: null } // or { below: number, color: color spec}\n    };\n    \n    function init(plot) {\n        function thresholdData(plot, s, datapoints, below, color) {\n            var ps = datapoints.pointsize, i, x, y, p, prevp,\n                thresholded = $.extend({}, s); // note: shallow copy\n\n            thresholded.datapoints = { points: [], pointsize: ps, format: datapoints.format };\n            thresholded.label = null;\n            thresholded.color = color;\n            thresholded.threshold = null;\n            thresholded.originSeries = s;\n            thresholded.data = [];\n \n            var origpoints = datapoints.points,\n                addCrossingPoints = s.lines.show;\n\n            var threspoints = [];\n            var newpoints = [];\n            var m;\n\n            for (i = 0; i < origpoints.length; i += ps) {\n                x = origpoints[i];\n                y = origpoints[i + 1];\n\n                prevp = p;\n                if (y < below)\n                    p = threspoints;\n                else\n                    p = newpoints;\n\n                if (addCrossingPoints && prevp != p && x != null\n                    && i > 0 && origpoints[i - ps] != null) {\n                    var interx = x + (below - y) * (x - origpoints[i - ps]) / (y - origpoints[i - ps + 1]);\n                    prevp.push(interx);\n                    prevp.push(below);\n                    for (m = 2; m < ps; ++m)\n                        prevp.push(origpoints[i + m]);\n                    \n                    p.push(null); // start new segment\n                    p.push(null);\n                    for (m = 2; m < ps; ++m)\n                        p.push(origpoints[i + m]);\n                    p.push(interx);\n                    p.push(below);\n                    for (m = 2; m < ps; ++m)\n                        p.push(origpoints[i + m]);\n                }\n\n                p.push(x);\n                p.push(y);\n                for (m = 2; m < ps; ++m)\n                    p.push(origpoints[i + m]);\n            }\n\n            datapoints.points = newpoints;\n            thresholded.datapoints.points = threspoints;\n            \n            if (thresholded.datapoints.points.length > 0) {\n                var origIndex = $.inArray(s, plot.getData());\n                // Insert newly-generated series right after original one (to prevent it from becoming top-most)\n                plot.getData().splice(origIndex + 1, 0, thresholded);\n            }\n                \n            // FIXME: there are probably some edge cases left in bars\n        }\n        \n        function processThresholds(plot, s, datapoints) {\n            if (!s.threshold)\n                return;\n            \n            if (s.threshold instanceof Array) {\n                s.threshold.sort(function(a, b) {\n                    return a.below - b.below;\n                });\n                \n                $(s.threshold).each(function(i, th) {\n                    thresholdData(plot, s, datapoints, th.below, th.color);\n                });\n            }\n            else {\n                thresholdData(plot, s, datapoints, s.threshold.below, s.threshold.color);\n            }\n        }\n        \n        plot.hooks.processDatapoints.push(processThresholds);\n    }\n    \n    $.plot.plugins.push({\n        init: init,\n        options: options,\n        name: 'threshold',\n        version: '1.2'\n    });\n})(jQuery);\n"
  },
  {
    "path": "app_backend/vendor/flot/jquery.flot.time.js",
    "content": "/* Pretty handling of time axes.\n\nCopyright (c) 2007-2014 IOLA and Ole Laursen.\nLicensed under the MIT license.\n\nSet axis.mode to \"time\" to enable. See the section \"Time series data\" in\nAPI.txt for details.\n\n*/\n\n(function($) {\n\n\tvar options = {\n\t\txaxis: {\n\t\t\ttimezone: null,\t\t// \"browser\" for local to the client or timezone for timezone-js\n\t\t\ttimeformat: null,\t// format string to use\n\t\t\ttwelveHourClock: false,\t// 12 or 24 time in time mode\n\t\t\tmonthNames: null\t// list of names of months\n\t\t}\n\t};\n\n\t// round to nearby lower multiple of base\n\n\tfunction floorInBase(n, base) {\n\t\treturn base * Math.floor(n / base);\n\t}\n\n\t// Returns a string with the date d formatted according to fmt.\n\t// A subset of the Open Group's strftime format is supported.\n\n\tfunction formatDate(d, fmt, monthNames, dayNames) {\n\n\t\tif (typeof d.strftime == \"function\") {\n\t\t\treturn d.strftime(fmt);\n\t\t}\n\n\t\tvar leftPad = function(n, pad) {\n\t\t\tn = \"\" + n;\n\t\t\tpad = \"\" + (pad == null ? \"0\" : pad);\n\t\t\treturn n.length == 1 ? pad + n : n;\n\t\t};\n\n\t\tvar r = [];\n\t\tvar escape = false;\n\t\tvar hours = d.getHours();\n\t\tvar isAM = hours < 12;\n\n\t\tif (monthNames == null) {\n\t\t\tmonthNames = [\"Jan\", \"Feb\", \"Mar\", \"Apr\", \"May\", \"Jun\", \"Jul\", \"Aug\", \"Sep\", \"Oct\", \"Nov\", \"Dec\"];\n\t\t}\n\n\t\tif (dayNames == null) {\n\t\t\tdayNames = [\"Sun\", \"Mon\", \"Tue\", \"Wed\", \"Thu\", \"Fri\", \"Sat\"];\n\t\t}\n\n\t\tvar hours12;\n\n\t\tif (hours > 12) {\n\t\t\thours12 = hours - 12;\n\t\t} else if (hours == 0) {\n\t\t\thours12 = 12;\n\t\t} else {\n\t\t\thours12 = hours;\n\t\t}\n\n\t\tfor (var i = 0; i < fmt.length; ++i) {\n\n\t\t\tvar c = fmt.charAt(i);\n\n\t\t\tif (escape) {\n\t\t\t\tswitch (c) {\n\t\t\t\t\tcase 'a': c = \"\" + dayNames[d.getDay()]; break;\n\t\t\t\t\tcase 'b': c = \"\" + monthNames[d.getMonth()]; break;\n\t\t\t\t\tcase 'd': c = leftPad(d.getDate()); break;\n\t\t\t\t\tcase 'e': c = leftPad(d.getDate(), \" \"); break;\n\t\t\t\t\tcase 'h':\t// For back-compat with 0.7; remove in 1.0\n\t\t\t\t\tcase 'H': c = leftPad(hours); break;\n\t\t\t\t\tcase 'I': c = leftPad(hours12); break;\n\t\t\t\t\tcase 'l': c = leftPad(hours12, \" \"); break;\n\t\t\t\t\tcase 'm': c = leftPad(d.getMonth() + 1); break;\n\t\t\t\t\tcase 'M': c = leftPad(d.getMinutes()); break;\n\t\t\t\t\t// quarters not in Open Group's strftime specification\n\t\t\t\t\tcase 'q':\n\t\t\t\t\t\tc = \"\" + (Math.floor(d.getMonth() / 3) + 1); break;\n\t\t\t\t\tcase 'S': c = leftPad(d.getSeconds()); break;\n\t\t\t\t\tcase 'y': c = leftPad(d.getFullYear() % 100); break;\n\t\t\t\t\tcase 'Y': c = \"\" + d.getFullYear(); break;\n\t\t\t\t\tcase 'p': c = (isAM) ? (\"\" + \"am\") : (\"\" + \"pm\"); break;\n\t\t\t\t\tcase 'P': c = (isAM) ? (\"\" + \"AM\") : (\"\" + \"PM\"); break;\n\t\t\t\t\tcase 'w': c = \"\" + d.getDay(); break;\n\t\t\t\t}\n\t\t\t\tr.push(c);\n\t\t\t\tescape = false;\n\t\t\t} else {\n\t\t\t\tif (c == \"%\") {\n\t\t\t\t\tescape = true;\n\t\t\t\t} else {\n\t\t\t\t\tr.push(c);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn r.join(\"\");\n\t}\n\n\t// To have a consistent view of time-based data independent of which time\n\t// zone the client happens to be in we need a date-like object independent\n\t// of time zones.  This is done through a wrapper that only calls the UTC\n\t// versions of the accessor methods.\n\n\tfunction makeUtcWrapper(d) {\n\n\t\tfunction addProxyMethod(sourceObj, sourceMethod, targetObj, targetMethod) {\n\t\t\tsourceObj[sourceMethod] = function() {\n\t\t\t\treturn targetObj[targetMethod].apply(targetObj, arguments);\n\t\t\t};\n\t\t};\n\n\t\tvar utc = {\n\t\t\tdate: d\n\t\t};\n\n\t\t// support strftime, if found\n\n\t\tif (d.strftime != undefined) {\n\t\t\taddProxyMethod(utc, \"strftime\", d, \"strftime\");\n\t\t}\n\n\t\taddProxyMethod(utc, \"getTime\", d, \"getTime\");\n\t\taddProxyMethod(utc, \"setTime\", d, \"setTime\");\n\n\t\tvar props = [\"Date\", \"Day\", \"FullYear\", \"Hours\", \"Milliseconds\", \"Minutes\", \"Month\", \"Seconds\"];\n\n\t\tfor (var p = 0; p < props.length; p++) {\n\t\t\taddProxyMethod(utc, \"get\" + props[p], d, \"getUTC\" + props[p]);\n\t\t\taddProxyMethod(utc, \"set\" + props[p], d, \"setUTC\" + props[p]);\n\t\t}\n\n\t\treturn utc;\n\t};\n\n\t// select time zone strategy.  This returns a date-like object tied to the\n\t// desired timezone\n\n\tfunction dateGenerator(ts, opts) {\n\t\tif (opts.timezone == \"browser\") {\n\t\t\treturn new Date(ts);\n\t\t} else if (!opts.timezone || opts.timezone == \"utc\") {\n\t\t\treturn makeUtcWrapper(new Date(ts));\n\t\t} else if (typeof timezoneJS != \"undefined\" && typeof timezoneJS.Date != \"undefined\") {\n\t\t\tvar d = new timezoneJS.Date();\n\t\t\t// timezone-js is fickle, so be sure to set the time zone before\n\t\t\t// setting the time.\n\t\t\td.setTimezone(opts.timezone);\n\t\t\td.setTime(ts);\n\t\t\treturn d;\n\t\t} else {\n\t\t\treturn makeUtcWrapper(new Date(ts));\n\t\t}\n\t}\n\t\n\t// map of app. size of time units in milliseconds\n\n\tvar timeUnitSize = {\n\t\t\"second\": 1000,\n\t\t\"minute\": 60 * 1000,\n\t\t\"hour\": 60 * 60 * 1000,\n\t\t\"day\": 24 * 60 * 60 * 1000,\n\t\t\"month\": 30 * 24 * 60 * 60 * 1000,\n\t\t\"quarter\": 3 * 30 * 24 * 60 * 60 * 1000,\n\t\t\"year\": 365.2425 * 24 * 60 * 60 * 1000\n\t};\n\n\t// the allowed tick sizes, after 1 year we use\n\t// an integer algorithm\n\n\tvar baseSpec = [\n\t\t[1, \"second\"], [2, \"second\"], [5, \"second\"], [10, \"second\"],\n\t\t[30, \"second\"], \n\t\t[1, \"minute\"], [2, \"minute\"], [5, \"minute\"], [10, \"minute\"],\n\t\t[30, \"minute\"], \n\t\t[1, \"hour\"], [2, \"hour\"], [4, \"hour\"],\n\t\t[8, \"hour\"], [12, \"hour\"],\n\t\t[1, \"day\"], [2, \"day\"], [3, \"day\"],\n\t\t[0.25, \"month\"], [0.5, \"month\"], [1, \"month\"],\n\t\t[2, \"month\"]\n\t];\n\n\t// we don't know which variant(s) we'll need yet, but generating both is\n\t// cheap\n\n\tvar specMonths = baseSpec.concat([[3, \"month\"], [6, \"month\"],\n\t\t[1, \"year\"]]);\n\tvar specQuarters = baseSpec.concat([[1, \"quarter\"], [2, \"quarter\"],\n\t\t[1, \"year\"]]);\n\n\tfunction init(plot) {\n\t\tplot.hooks.processOptions.push(function (plot, options) {\n\t\t\t$.each(plot.getAxes(), function(axisName, axis) {\n\n\t\t\t\tvar opts = axis.options;\n\n\t\t\t\tif (opts.mode == \"time\") {\n\t\t\t\t\taxis.tickGenerator = function(axis) {\n\n\t\t\t\t\t\tvar ticks = [];\n\t\t\t\t\t\tvar d = dateGenerator(axis.min, opts);\n\t\t\t\t\t\tvar minSize = 0;\n\n\t\t\t\t\t\t// make quarter use a possibility if quarters are\n\t\t\t\t\t\t// mentioned in either of these options\n\n\t\t\t\t\t\tvar spec = (opts.tickSize && opts.tickSize[1] ===\n\t\t\t\t\t\t\t\"quarter\") ||\n\t\t\t\t\t\t\t(opts.minTickSize && opts.minTickSize[1] ===\n\t\t\t\t\t\t\t\"quarter\") ? specQuarters : specMonths;\n\n\t\t\t\t\t\tif (opts.minTickSize != null) {\n\t\t\t\t\t\t\tif (typeof opts.tickSize == \"number\") {\n\t\t\t\t\t\t\t\tminSize = opts.tickSize;\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tminSize = opts.minTickSize[0] * timeUnitSize[opts.minTickSize[1]];\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tfor (var i = 0; i < spec.length - 1; ++i) {\n\t\t\t\t\t\t\tif (axis.delta < (spec[i][0] * timeUnitSize[spec[i][1]]\n\t\t\t\t\t\t\t\t\t\t\t  + spec[i + 1][0] * timeUnitSize[spec[i + 1][1]]) / 2\n\t\t\t\t\t\t\t\t&& spec[i][0] * timeUnitSize[spec[i][1]] >= minSize) {\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tvar size = spec[i][0];\n\t\t\t\t\t\tvar unit = spec[i][1];\n\n\t\t\t\t\t\t// special-case the possibility of several years\n\n\t\t\t\t\t\tif (unit == \"year\") {\n\n\t\t\t\t\t\t\t// if given a minTickSize in years, just use it,\n\t\t\t\t\t\t\t// ensuring that it's an integer\n\n\t\t\t\t\t\t\tif (opts.minTickSize != null && opts.minTickSize[1] == \"year\") {\n\t\t\t\t\t\t\t\tsize = Math.floor(opts.minTickSize[0]);\n\t\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\t\tvar magn = Math.pow(10, Math.floor(Math.log(axis.delta / timeUnitSize.year) / Math.LN10));\n\t\t\t\t\t\t\t\tvar norm = (axis.delta / timeUnitSize.year) / magn;\n\n\t\t\t\t\t\t\t\tif (norm < 1.5) {\n\t\t\t\t\t\t\t\t\tsize = 1;\n\t\t\t\t\t\t\t\t} else if (norm < 3) {\n\t\t\t\t\t\t\t\t\tsize = 2;\n\t\t\t\t\t\t\t\t} else if (norm < 7.5) {\n\t\t\t\t\t\t\t\t\tsize = 5;\n\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\tsize = 10;\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\tsize *= magn;\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t// minimum size for years is 1\n\n\t\t\t\t\t\t\tif (size < 1) {\n\t\t\t\t\t\t\t\tsize = 1;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\taxis.tickSize = opts.tickSize || [size, unit];\n\t\t\t\t\t\tvar tickSize = axis.tickSize[0];\n\t\t\t\t\t\tunit = axis.tickSize[1];\n\n\t\t\t\t\t\tvar step = tickSize * timeUnitSize[unit];\n\n\t\t\t\t\t\tif (unit == \"second\") {\n\t\t\t\t\t\t\td.setSeconds(floorInBase(d.getSeconds(), tickSize));\n\t\t\t\t\t\t} else if (unit == \"minute\") {\n\t\t\t\t\t\t\td.setMinutes(floorInBase(d.getMinutes(), tickSize));\n\t\t\t\t\t\t} else if (unit == \"hour\") {\n\t\t\t\t\t\t\td.setHours(floorInBase(d.getHours(), tickSize));\n\t\t\t\t\t\t} else if (unit == \"month\") {\n\t\t\t\t\t\t\td.setMonth(floorInBase(d.getMonth(), tickSize));\n\t\t\t\t\t\t} else if (unit == \"quarter\") {\n\t\t\t\t\t\t\td.setMonth(3 * floorInBase(d.getMonth() / 3,\n\t\t\t\t\t\t\t\ttickSize));\n\t\t\t\t\t\t} else if (unit == \"year\") {\n\t\t\t\t\t\t\td.setFullYear(floorInBase(d.getFullYear(), tickSize));\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// reset smaller components\n\n\t\t\t\t\t\td.setMilliseconds(0);\n\n\t\t\t\t\t\tif (step >= timeUnitSize.minute) {\n\t\t\t\t\t\t\td.setSeconds(0);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (step >= timeUnitSize.hour) {\n\t\t\t\t\t\t\td.setMinutes(0);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (step >= timeUnitSize.day) {\n\t\t\t\t\t\t\td.setHours(0);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (step >= timeUnitSize.day * 4) {\n\t\t\t\t\t\t\td.setDate(1);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (step >= timeUnitSize.month * 2) {\n\t\t\t\t\t\t\td.setMonth(floorInBase(d.getMonth(), 3));\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (step >= timeUnitSize.quarter * 2) {\n\t\t\t\t\t\t\td.setMonth(floorInBase(d.getMonth(), 6));\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (step >= timeUnitSize.year) {\n\t\t\t\t\t\t\td.setMonth(0);\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tvar carry = 0;\n\t\t\t\t\t\tvar v = Number.NaN;\n\t\t\t\t\t\tvar prev;\n\n\t\t\t\t\t\tdo {\n\n\t\t\t\t\t\t\tprev = v;\n\t\t\t\t\t\t\tv = d.getTime();\n\t\t\t\t\t\t\tticks.push(v);\n\n\t\t\t\t\t\t\tif (unit == \"month\" || unit == \"quarter\") {\n\t\t\t\t\t\t\t\tif (tickSize < 1) {\n\n\t\t\t\t\t\t\t\t\t// a bit complicated - we'll divide the\n\t\t\t\t\t\t\t\t\t// month/quarter up but we need to take\n\t\t\t\t\t\t\t\t\t// care of fractions so we don't end up in\n\t\t\t\t\t\t\t\t\t// the middle of a day\n\n\t\t\t\t\t\t\t\t\td.setDate(1);\n\t\t\t\t\t\t\t\t\tvar start = d.getTime();\n\t\t\t\t\t\t\t\t\td.setMonth(d.getMonth() +\n\t\t\t\t\t\t\t\t\t\t(unit == \"quarter\" ? 3 : 1));\n\t\t\t\t\t\t\t\t\tvar end = d.getTime();\n\t\t\t\t\t\t\t\t\td.setTime(v + carry * timeUnitSize.hour + (end - start) * tickSize);\n\t\t\t\t\t\t\t\t\tcarry = d.getHours();\n\t\t\t\t\t\t\t\t\td.setHours(0);\n\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\td.setMonth(d.getMonth() +\n\t\t\t\t\t\t\t\t\t\ttickSize * (unit == \"quarter\" ? 3 : 1));\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t} else if (unit == \"year\") {\n\t\t\t\t\t\t\t\td.setFullYear(d.getFullYear() + tickSize);\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\td.setTime(v + step);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} while (v < axis.max && v != prev);\n\n\t\t\t\t\t\treturn ticks;\n\t\t\t\t\t};\n\n\t\t\t\t\taxis.tickFormatter = function (v, axis) {\n\n\t\t\t\t\t\tvar d = dateGenerator(v, axis.options);\n\n\t\t\t\t\t\t// first check global format\n\n\t\t\t\t\t\tif (opts.timeformat != null) {\n\t\t\t\t\t\t\treturn formatDate(d, opts.timeformat, opts.monthNames, opts.dayNames);\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// possibly use quarters if quarters are mentioned in\n\t\t\t\t\t\t// any of these places\n\n\t\t\t\t\t\tvar useQuarters = (axis.options.tickSize &&\n\t\t\t\t\t\t\t\taxis.options.tickSize[1] == \"quarter\") ||\n\t\t\t\t\t\t\t(axis.options.minTickSize &&\n\t\t\t\t\t\t\t\taxis.options.minTickSize[1] == \"quarter\");\n\n\t\t\t\t\t\tvar t = axis.tickSize[0] * timeUnitSize[axis.tickSize[1]];\n\t\t\t\t\t\tvar span = axis.max - axis.min;\n\t\t\t\t\t\tvar suffix = (opts.twelveHourClock) ? \" %p\" : \"\";\n\t\t\t\t\t\tvar hourCode = (opts.twelveHourClock) ? \"%I\" : \"%H\";\n\t\t\t\t\t\tvar fmt;\n\n\t\t\t\t\t\tif (t < timeUnitSize.minute) {\n\t\t\t\t\t\t\tfmt = hourCode + \":%M:%S\" + suffix;\n\t\t\t\t\t\t} else if (t < timeUnitSize.day) {\n\t\t\t\t\t\t\tif (span < 2 * timeUnitSize.day) {\n\t\t\t\t\t\t\t\tfmt = hourCode + \":%M\" + suffix;\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tfmt = \"%b %d \" + hourCode + \":%M\" + suffix;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} else if (t < timeUnitSize.month) {\n\t\t\t\t\t\t\tfmt = \"%b %d\";\n\t\t\t\t\t\t} else if ((useQuarters && t < timeUnitSize.quarter) ||\n\t\t\t\t\t\t\t(!useQuarters && t < timeUnitSize.year)) {\n\t\t\t\t\t\t\tif (span < timeUnitSize.year) {\n\t\t\t\t\t\t\t\tfmt = \"%b\";\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tfmt = \"%b %Y\";\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} else if (useQuarters && t < timeUnitSize.year) {\n\t\t\t\t\t\t\tif (span < timeUnitSize.year) {\n\t\t\t\t\t\t\t\tfmt = \"Q%q\";\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tfmt = \"Q%q %Y\";\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tfmt = \"%Y\";\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tvar rt = formatDate(d, fmt, opts.monthNames, opts.dayNames);\n\n\t\t\t\t\t\treturn rt;\n\t\t\t\t\t};\n\t\t\t\t}\n\t\t\t});\n\t\t});\n\t}\n\n\t$.plot.plugins.push({\n\t\tinit: init,\n\t\toptions: options,\n\t\tname: 'time',\n\t\tversion: '1.0'\n\t});\n\n\t// Time-axis support used to be in Flot core, which exposed the\n\t// formatDate function on the plot object.  Various plugins depend\n\t// on the function, so we need to re-expose it here.\n\n\t$.plot.formatDate = formatDate;\n\t$.plot.dateGenerator = dateGenerator;\n\n})(jQuery);\n"
  },
  {
    "path": "app_backend/vendor/flot/jquery.js",
    "content": "/*!\n * jQuery JavaScript Library v1.8.3\n * http://jquery.com/\n *\n * Includes Sizzle.js\n * http://sizzlejs.com/\n *\n * Copyright 2012 jQuery Foundation and other contributors\n * Released under the MIT license\n * http://jquery.org/license\n *\n * Date: Tue Nov 13 2012 08:20:33 GMT-0500 (Eastern Standard Time)\n */\n(function( window, undefined ) {\nvar\n\t// A central reference to the root jQuery(document)\n\trootjQuery,\n\n\t// The deferred used on DOM ready\n\treadyList,\n\n\t// Use the correct document accordingly with window argument (sandbox)\n\tdocument = window.document,\n\tlocation = window.location,\n\tnavigator = window.navigator,\n\n\t// Map over jQuery in case of overwrite\n\t_jQuery = window.jQuery,\n\n\t// Map over the $ in case of overwrite\n\t_$ = window.$,\n\n\t// Save a reference to some core methods\n\tcore_push = Array.prototype.push,\n\tcore_slice = Array.prototype.slice,\n\tcore_indexOf = Array.prototype.indexOf,\n\tcore_toString = Object.prototype.toString,\n\tcore_hasOwn = Object.prototype.hasOwnProperty,\n\tcore_trim = String.prototype.trim,\n\n\t// Define a local copy of jQuery\n\tjQuery = function( selector, context ) {\n\t\t// The jQuery object is actually just the init constructor 'enhanced'\n\t\treturn new jQuery.fn.init( selector, context, rootjQuery );\n\t},\n\n\t// Used for matching numbers\n\tcore_pnum = /[\\-+]?(?:\\d*\\.|)\\d+(?:[eE][\\-+]?\\d+|)/.source,\n\n\t// Used for detecting and trimming whitespace\n\tcore_rnotwhite = /\\S/,\n\tcore_rspace = /\\s+/,\n\n\t// Make sure we trim BOM and NBSP (here's looking at you, Safari 5.0 and IE)\n\trtrim = /^[\\s\\uFEFF\\xA0]+|[\\s\\uFEFF\\xA0]+$/g,\n\n\t// A simple way to check for HTML strings\n\t// Prioritize #id over <tag> to avoid XSS via location.hash (#9521)\n\trquickExpr = /^(?:[^#<]*(<[\\w\\W]+>)[^>]*$|#([\\w\\-]*)$)/,\n\n\t// Match a standalone tag\n\trsingleTag = /^<(\\w+)\\s*\\/?>(?:<\\/\\1>|)$/,\n\n\t// JSON RegExp\n\trvalidchars = /^[\\],:{}\\s]*$/,\n\trvalidbraces = /(?:^|:|,)(?:\\s*\\[)+/g,\n\trvalidescape = /\\\\(?:[\"\\\\\\/bfnrt]|u[\\da-fA-F]{4})/g,\n\trvalidtokens = /\"[^\"\\\\\\r\\n]*\"|true|false|null|-?(?:\\d\\d*\\.|)\\d+(?:[eE][\\-+]?\\d+|)/g,\n\n\t// Matches dashed string for camelizing\n\trmsPrefix = /^-ms-/,\n\trdashAlpha = /-([\\da-z])/gi,\n\n\t// Used by jQuery.camelCase as callback to replace()\n\tfcamelCase = function( all, letter ) {\n\t\treturn ( letter + \"\" ).toUpperCase();\n\t},\n\n\t// The ready event handler and self cleanup method\n\tDOMContentLoaded = function() {\n\t\tif ( document.addEventListener ) {\n\t\t\tdocument.removeEventListener( \"DOMContentLoaded\", DOMContentLoaded, false );\n\t\t\tjQuery.ready();\n\t\t} else if ( document.readyState === \"complete\" ) {\n\t\t\t// we're here because readyState === \"complete\" in oldIE\n\t\t\t// which is good enough for us to call the dom ready!\n\t\t\tdocument.detachEvent( \"onreadystatechange\", DOMContentLoaded );\n\t\t\tjQuery.ready();\n\t\t}\n\t},\n\n\t// [[Class]] -> type pairs\n\tclass2type = {};\n\njQuery.fn = jQuery.prototype = {\n\tconstructor: jQuery,\n\tinit: function( selector, context, rootjQuery ) {\n\t\tvar match, elem, ret, doc;\n\n\t\t// Handle $(\"\"), $(null), $(undefined), $(false)\n\t\tif ( !selector ) {\n\t\t\treturn this;\n\t\t}\n\n\t\t// Handle $(DOMElement)\n\t\tif ( selector.nodeType ) {\n\t\t\tthis.context = this[0] = selector;\n\t\t\tthis.length = 1;\n\t\t\treturn this;\n\t\t}\n\n\t\t// Handle HTML strings\n\t\tif ( typeof selector === \"string\" ) {\n\t\t\tif ( selector.charAt(0) === \"<\" && selector.charAt( selector.length - 1 ) === \">\" && selector.length >= 3 ) {\n\t\t\t\t// Assume that strings that start and end with <> are HTML and skip the regex check\n\t\t\t\tmatch = [ null, selector, null ];\n\n\t\t\t} else {\n\t\t\t\tmatch = rquickExpr.exec( selector );\n\t\t\t}\n\n\t\t\t// Match html or make sure no context is specified for #id\n\t\t\tif ( match && (match[1] || !context) ) {\n\n\t\t\t\t// HANDLE: $(html) -> $(array)\n\t\t\t\tif ( match[1] ) {\n\t\t\t\t\tcontext = context instanceof jQuery ? context[0] : context;\n\t\t\t\t\tdoc = ( context && context.nodeType ? context.ownerDocument || context : document );\n\n\t\t\t\t\t// scripts is true for back-compat\n\t\t\t\t\tselector = jQuery.parseHTML( match[1], doc, true );\n\t\t\t\t\tif ( rsingleTag.test( match[1] ) && jQuery.isPlainObject( context ) ) {\n\t\t\t\t\t\tthis.attr.call( selector, context, true );\n\t\t\t\t\t}\n\n\t\t\t\t\treturn jQuery.merge( this, selector );\n\n\t\t\t\t// HANDLE: $(#id)\n\t\t\t\t} else {\n\t\t\t\t\telem = document.getElementById( match[2] );\n\n\t\t\t\t\t// Check parentNode to catch when Blackberry 4.6 returns\n\t\t\t\t\t// nodes that are no longer in the document #6963\n\t\t\t\t\tif ( elem && elem.parentNode ) {\n\t\t\t\t\t\t// Handle the case where IE and Opera return items\n\t\t\t\t\t\t// by name instead of ID\n\t\t\t\t\t\tif ( elem.id !== match[2] ) {\n\t\t\t\t\t\t\treturn rootjQuery.find( selector );\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// Otherwise, we inject the element directly into the jQuery object\n\t\t\t\t\t\tthis.length = 1;\n\t\t\t\t\t\tthis[0] = elem;\n\t\t\t\t\t}\n\n\t\t\t\t\tthis.context = document;\n\t\t\t\t\tthis.selector = selector;\n\t\t\t\t\treturn this;\n\t\t\t\t}\n\n\t\t\t// HANDLE: $(expr, $(...))\n\t\t\t} else if ( !context || context.jquery ) {\n\t\t\t\treturn ( context || rootjQuery ).find( selector );\n\n\t\t\t// HANDLE: $(expr, context)\n\t\t\t// (which is just equivalent to: $(context).find(expr)\n\t\t\t} else {\n\t\t\t\treturn this.constructor( context ).find( selector );\n\t\t\t}\n\n\t\t// HANDLE: $(function)\n\t\t// Shortcut for document ready\n\t\t} else if ( jQuery.isFunction( selector ) ) {\n\t\t\treturn rootjQuery.ready( selector );\n\t\t}\n\n\t\tif ( selector.selector !== undefined ) {\n\t\t\tthis.selector = selector.selector;\n\t\t\tthis.context = selector.context;\n\t\t}\n\n\t\treturn jQuery.makeArray( selector, this );\n\t},\n\n\t// Start with an empty selector\n\tselector: \"\",\n\n\t// The current version of jQuery being used\n\tjquery: \"1.8.3\",\n\n\t// The default length of a jQuery object is 0\n\tlength: 0,\n\n\t// The number of elements contained in the matched element set\n\tsize: function() {\n\t\treturn this.length;\n\t},\n\n\ttoArray: function() {\n\t\treturn core_slice.call( this );\n\t},\n\n\t// Get the Nth element in the matched element set OR\n\t// Get the whole matched element set as a clean array\n\tget: function( num ) {\n\t\treturn num == null ?\n\n\t\t\t// Return a 'clean' array\n\t\t\tthis.toArray() :\n\n\t\t\t// Return just the object\n\t\t\t( num < 0 ? this[ this.length + num ] : this[ num ] );\n\t},\n\n\t// Take an array of elements and push it onto the stack\n\t// (returning the new matched element set)\n\tpushStack: function( elems, name, selector ) {\n\n\t\t// Build a new jQuery matched element set\n\t\tvar ret = jQuery.merge( this.constructor(), elems );\n\n\t\t// Add the old object onto the stack (as a reference)\n\t\tret.prevObject = this;\n\n\t\tret.context = this.context;\n\n\t\tif ( name === \"find\" ) {\n\t\t\tret.selector = this.selector + ( this.selector ? \" \" : \"\" ) + selector;\n\t\t} else if ( name ) {\n\t\t\tret.selector = this.selector + \".\" + name + \"(\" + selector + \")\";\n\t\t}\n\n\t\t// Return the newly-formed element set\n\t\treturn ret;\n\t},\n\n\t// Execute a callback for every element in the matched set.\n\t// (You can seed the arguments with an array of args, but this is\n\t// only used internally.)\n\teach: function( callback, args ) {\n\t\treturn jQuery.each( this, callback, args );\n\t},\n\n\tready: function( fn ) {\n\t\t// Add the callback\n\t\tjQuery.ready.promise().done( fn );\n\n\t\treturn this;\n\t},\n\n\teq: function( i ) {\n\t\ti = +i;\n\t\treturn i === -1 ?\n\t\t\tthis.slice( i ) :\n\t\t\tthis.slice( i, i + 1 );\n\t},\n\n\tfirst: function() {\n\t\treturn this.eq( 0 );\n\t},\n\n\tlast: function() {\n\t\treturn this.eq( -1 );\n\t},\n\n\tslice: function() {\n\t\treturn this.pushStack( core_slice.apply( this, arguments ),\n\t\t\t\"slice\", core_slice.call(arguments).join(\",\") );\n\t},\n\n\tmap: function( callback ) {\n\t\treturn this.pushStack( jQuery.map(this, function( elem, i ) {\n\t\t\treturn callback.call( elem, i, elem );\n\t\t}));\n\t},\n\n\tend: function() {\n\t\treturn this.prevObject || this.constructor(null);\n\t},\n\n\t// For internal use only.\n\t// Behaves like an Array's method, not like a jQuery method.\n\tpush: core_push,\n\tsort: [].sort,\n\tsplice: [].splice\n};\n\n// Give the init function the jQuery prototype for later instantiation\njQuery.fn.init.prototype = jQuery.fn;\n\njQuery.extend = jQuery.fn.extend = function() {\n\tvar options, name, src, copy, copyIsArray, clone,\n\t\ttarget = arguments[0] || {},\n\t\ti = 1,\n\t\tlength = arguments.length,\n\t\tdeep = false;\n\n\t// Handle a deep copy situation\n\tif ( typeof target === \"boolean\" ) {\n\t\tdeep = target;\n\t\ttarget = arguments[1] || {};\n\t\t// skip the boolean and the target\n\t\ti = 2;\n\t}\n\n\t// Handle case when target is a string or something (possible in deep copy)\n\tif ( typeof target !== \"object\" && !jQuery.isFunction(target) ) {\n\t\ttarget = {};\n\t}\n\n\t// extend jQuery itself if only one argument is passed\n\tif ( length === i ) {\n\t\ttarget = this;\n\t\t--i;\n\t}\n\n\tfor ( ; i < length; i++ ) {\n\t\t// Only deal with non-null/undefined values\n\t\tif ( (options = arguments[ i ]) != null ) {\n\t\t\t// Extend the base object\n\t\t\tfor ( name in options ) {\n\t\t\t\tsrc = target[ name ];\n\t\t\t\tcopy = options[ name ];\n\n\t\t\t\t// Prevent never-ending loop\n\t\t\t\tif ( target === copy ) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\t// Recurse if we're merging plain objects or arrays\n\t\t\t\tif ( deep && copy && ( jQuery.isPlainObject(copy) || (copyIsArray = jQuery.isArray(copy)) ) ) {\n\t\t\t\t\tif ( copyIsArray ) {\n\t\t\t\t\t\tcopyIsArray = false;\n\t\t\t\t\t\tclone = src && jQuery.isArray(src) ? src : [];\n\n\t\t\t\t\t} else {\n\t\t\t\t\t\tclone = src && jQuery.isPlainObject(src) ? src : {};\n\t\t\t\t\t}\n\n\t\t\t\t\t// Never move original objects, clone them\n\t\t\t\t\ttarget[ name ] = jQuery.extend( deep, clone, copy );\n\n\t\t\t\t// Don't bring in undefined values\n\t\t\t\t} else if ( copy !== undefined ) {\n\t\t\t\t\ttarget[ name ] = copy;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t// Return the modified object\n\treturn target;\n};\n\njQuery.extend({\n\tnoConflict: function( deep ) {\n\t\tif ( window.$ === jQuery ) {\n\t\t\twindow.$ = _$;\n\t\t}\n\n\t\tif ( deep && window.jQuery === jQuery ) {\n\t\t\twindow.jQuery = _jQuery;\n\t\t}\n\n\t\treturn jQuery;\n\t},\n\n\t// Is the DOM ready to be used? Set to true once it occurs.\n\tisReady: false,\n\n\t// A counter to track how many items to wait for before\n\t// the ready event fires. See #6781\n\treadyWait: 1,\n\n\t// Hold (or release) the ready event\n\tholdReady: function( hold ) {\n\t\tif ( hold ) {\n\t\t\tjQuery.readyWait++;\n\t\t} else {\n\t\t\tjQuery.ready( true );\n\t\t}\n\t},\n\n\t// Handle when the DOM is ready\n\tready: function( wait ) {\n\n\t\t// Abort if there are pending holds or we're already ready\n\t\tif ( wait === true ? --jQuery.readyWait : jQuery.isReady ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443).\n\t\tif ( !document.body ) {\n\t\t\treturn setTimeout( jQuery.ready, 1 );\n\t\t}\n\n\t\t// Remember that the DOM is ready\n\t\tjQuery.isReady = true;\n\n\t\t// If a normal DOM Ready event fired, decrement, and wait if need be\n\t\tif ( wait !== true && --jQuery.readyWait > 0 ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// If there are functions bound, to execute\n\t\treadyList.resolveWith( document, [ jQuery ] );\n\n\t\t// Trigger any bound ready events\n\t\tif ( jQuery.fn.trigger ) {\n\t\t\tjQuery( document ).trigger(\"ready\").off(\"ready\");\n\t\t}\n\t},\n\n\t// See test/unit/core.js for details concerning isFunction.\n\t// Since version 1.3, DOM methods and functions like alert\n\t// aren't supported. They return false on IE (#2968).\n\tisFunction: function( obj ) {\n\t\treturn jQuery.type(obj) === \"function\";\n\t},\n\n\tisArray: Array.isArray || function( obj ) {\n\t\treturn jQuery.type(obj) === \"array\";\n\t},\n\n\tisWindow: function( obj ) {\n\t\treturn obj != null && obj == obj.window;\n\t},\n\n\tisNumeric: function( obj ) {\n\t\treturn !isNaN( parseFloat(obj) ) && isFinite( obj );\n\t},\n\n\ttype: function( obj ) {\n\t\treturn obj == null ?\n\t\t\tString( obj ) :\n\t\t\tclass2type[ core_toString.call(obj) ] || \"object\";\n\t},\n\n\tisPlainObject: function( obj ) {\n\t\t// Must be an Object.\n\t\t// Because of IE, we also have to check the presence of the constructor property.\n\t\t// Make sure that DOM nodes and window objects don't pass through, as well\n\t\tif ( !obj || jQuery.type(obj) !== \"object\" || obj.nodeType || jQuery.isWindow( obj ) ) {\n\t\t\treturn false;\n\t\t}\n\n\t\ttry {\n\t\t\t// Not own constructor property must be Object\n\t\t\tif ( obj.constructor &&\n\t\t\t\t!core_hasOwn.call(obj, \"constructor\") &&\n\t\t\t\t!core_hasOwn.call(obj.constructor.prototype, \"isPrototypeOf\") ) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t} catch ( e ) {\n\t\t\t// IE8,9 Will throw exceptions on certain host objects #9897\n\t\t\treturn false;\n\t\t}\n\n\t\t// Own properties are enumerated firstly, so to speed up,\n\t\t// if last one is own, then all properties are own.\n\n\t\tvar key;\n\t\tfor ( key in obj ) {}\n\n\t\treturn key === undefined || core_hasOwn.call( obj, key );\n\t},\n\n\tisEmptyObject: function( obj ) {\n\t\tvar name;\n\t\tfor ( name in obj ) {\n\t\t\treturn false;\n\t\t}\n\t\treturn true;\n\t},\n\n\terror: function( msg ) {\n\t\tthrow new Error( msg );\n\t},\n\n\t// data: string of html\n\t// context (optional): If specified, the fragment will be created in this context, defaults to document\n\t// scripts (optional): If true, will include scripts passed in the html string\n\tparseHTML: function( data, context, scripts ) {\n\t\tvar parsed;\n\t\tif ( !data || typeof data !== \"string\" ) {\n\t\t\treturn null;\n\t\t}\n\t\tif ( typeof context === \"boolean\" ) {\n\t\t\tscripts = context;\n\t\t\tcontext = 0;\n\t\t}\n\t\tcontext = context || document;\n\n\t\t// Single tag\n\t\tif ( (parsed = rsingleTag.exec( data )) ) {\n\t\t\treturn [ context.createElement( parsed[1] ) ];\n\t\t}\n\n\t\tparsed = jQuery.buildFragment( [ data ], context, scripts ? null : [] );\n\t\treturn jQuery.merge( [],\n\t\t\t(parsed.cacheable ? jQuery.clone( parsed.fragment ) : parsed.fragment).childNodes );\n\t},\n\n\tparseJSON: function( data ) {\n\t\tif ( !data || typeof data !== \"string\") {\n\t\t\treturn null;\n\t\t}\n\n\t\t// Make sure leading/trailing whitespace is removed (IE can't handle it)\n\t\tdata = jQuery.trim( data );\n\n\t\t// Attempt to parse using the native JSON parser first\n\t\tif ( window.JSON && window.JSON.parse ) {\n\t\t\treturn window.JSON.parse( data );\n\t\t}\n\n\t\t// Make sure the incoming data is actual JSON\n\t\t// Logic borrowed from http://json.org/json2.js\n\t\tif ( rvalidchars.test( data.replace( rvalidescape, \"@\" )\n\t\t\t.replace( rvalidtokens, \"]\" )\n\t\t\t.replace( rvalidbraces, \"\")) ) {\n\n\t\t\treturn ( new Function( \"return \" + data ) )();\n\n\t\t}\n\t\tjQuery.error( \"Invalid JSON: \" + data );\n\t},\n\n\t// Cross-browser xml parsing\n\tparseXML: function( data ) {\n\t\tvar xml, tmp;\n\t\tif ( !data || typeof data !== \"string\" ) {\n\t\t\treturn null;\n\t\t}\n\t\ttry {\n\t\t\tif ( window.DOMParser ) { // Standard\n\t\t\t\ttmp = new DOMParser();\n\t\t\t\txml = tmp.parseFromString( data , \"text/xml\" );\n\t\t\t} else { // IE\n\t\t\t\txml = new ActiveXObject( \"Microsoft.XMLDOM\" );\n\t\t\t\txml.async = \"false\";\n\t\t\t\txml.loadXML( data );\n\t\t\t}\n\t\t} catch( e ) {\n\t\t\txml = undefined;\n\t\t}\n\t\tif ( !xml || !xml.documentElement || xml.getElementsByTagName( \"parsererror\" ).length ) {\n\t\t\tjQuery.error( \"Invalid XML: \" + data );\n\t\t}\n\t\treturn xml;\n\t},\n\n\tnoop: function() {},\n\n\t// Evaluates a script in a global context\n\t// Workarounds based on findings by Jim Driscoll\n\t// http://weblogs.java.net/blog/driscoll/archive/2009/09/08/eval-javascript-global-context\n\tglobalEval: function( data ) {\n\t\tif ( data && core_rnotwhite.test( data ) ) {\n\t\t\t// We use execScript on Internet Explorer\n\t\t\t// We use an anonymous function so that context is window\n\t\t\t// rather than jQuery in Firefox\n\t\t\t( window.execScript || function( data ) {\n\t\t\t\twindow[ \"eval\" ].call( window, data );\n\t\t\t} )( data );\n\t\t}\n\t},\n\n\t// Convert dashed to camelCase; used by the css and data modules\n\t// Microsoft forgot to hump their vendor prefix (#9572)\n\tcamelCase: function( string ) {\n\t\treturn string.replace( rmsPrefix, \"ms-\" ).replace( rdashAlpha, fcamelCase );\n\t},\n\n\tnodeName: function( elem, name ) {\n\t\treturn elem.nodeName && elem.nodeName.toLowerCase() === name.toLowerCase();\n\t},\n\n\t// args is for internal usage only\n\teach: function( obj, callback, args ) {\n\t\tvar name,\n\t\t\ti = 0,\n\t\t\tlength = obj.length,\n\t\t\tisObj = length === undefined || jQuery.isFunction( obj );\n\n\t\tif ( args ) {\n\t\t\tif ( isObj ) {\n\t\t\t\tfor ( name in obj ) {\n\t\t\t\t\tif ( callback.apply( obj[ name ], args ) === false ) {\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tfor ( ; i < length; ) {\n\t\t\t\t\tif ( callback.apply( obj[ i++ ], args ) === false ) {\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t// A special, fast, case for the most common use of each\n\t\t} else {\n\t\t\tif ( isObj ) {\n\t\t\t\tfor ( name in obj ) {\n\t\t\t\t\tif ( callback.call( obj[ name ], name, obj[ name ] ) === false ) {\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tfor ( ; i < length; ) {\n\t\t\t\t\tif ( callback.call( obj[ i ], i, obj[ i++ ] ) === false ) {\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn obj;\n\t},\n\n\t// Use native String.trim function wherever possible\n\ttrim: core_trim && !core_trim.call(\"\\uFEFF\\xA0\") ?\n\t\tfunction( text ) {\n\t\t\treturn text == null ?\n\t\t\t\t\"\" :\n\t\t\t\tcore_trim.call( text );\n\t\t} :\n\n\t\t// Otherwise use our own trimming functionality\n\t\tfunction( text ) {\n\t\t\treturn text == null ?\n\t\t\t\t\"\" :\n\t\t\t\t( text + \"\" ).replace( rtrim, \"\" );\n\t\t},\n\n\t// results is for internal usage only\n\tmakeArray: function( arr, results ) {\n\t\tvar type,\n\t\t\tret = results || [];\n\n\t\tif ( arr != null ) {\n\t\t\t// The window, strings (and functions) also have 'length'\n\t\t\t// Tweaked logic slightly to handle Blackberry 4.7 RegExp issues #6930\n\t\t\ttype = jQuery.type( arr );\n\n\t\t\tif ( arr.length == null || type === \"string\" || type === \"function\" || type === \"regexp\" || jQuery.isWindow( arr ) ) {\n\t\t\t\tcore_push.call( ret, arr );\n\t\t\t} else {\n\t\t\t\tjQuery.merge( ret, arr );\n\t\t\t}\n\t\t}\n\n\t\treturn ret;\n\t},\n\n\tinArray: function( elem, arr, i ) {\n\t\tvar len;\n\n\t\tif ( arr ) {\n\t\t\tif ( core_indexOf ) {\n\t\t\t\treturn core_indexOf.call( arr, elem, i );\n\t\t\t}\n\n\t\t\tlen = arr.length;\n\t\t\ti = i ? i < 0 ? Math.max( 0, len + i ) : i : 0;\n\n\t\t\tfor ( ; i < len; i++ ) {\n\t\t\t\t// Skip accessing in sparse arrays\n\t\t\t\tif ( i in arr && arr[ i ] === elem ) {\n\t\t\t\t\treturn i;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn -1;\n\t},\n\n\tmerge: function( first, second ) {\n\t\tvar l = second.length,\n\t\t\ti = first.length,\n\t\t\tj = 0;\n\n\t\tif ( typeof l === \"number\" ) {\n\t\t\tfor ( ; j < l; j++ ) {\n\t\t\t\tfirst[ i++ ] = second[ j ];\n\t\t\t}\n\n\t\t} else {\n\t\t\twhile ( second[j] !== undefined ) {\n\t\t\t\tfirst[ i++ ] = second[ j++ ];\n\t\t\t}\n\t\t}\n\n\t\tfirst.length = i;\n\n\t\treturn first;\n\t},\n\n\tgrep: function( elems, callback, inv ) {\n\t\tvar retVal,\n\t\t\tret = [],\n\t\t\ti = 0,\n\t\t\tlength = elems.length;\n\t\tinv = !!inv;\n\n\t\t// Go through the array, only saving the items\n\t\t// that pass the validator function\n\t\tfor ( ; i < length; i++ ) {\n\t\t\tretVal = !!callback( elems[ i ], i );\n\t\t\tif ( inv !== retVal ) {\n\t\t\t\tret.push( elems[ i ] );\n\t\t\t}\n\t\t}\n\n\t\treturn ret;\n\t},\n\n\t// arg is for internal usage only\n\tmap: function( elems, callback, arg ) {\n\t\tvar value, key,\n\t\t\tret = [],\n\t\t\ti = 0,\n\t\t\tlength = elems.length,\n\t\t\t// jquery objects are treated as arrays\n\t\t\tisArray = elems instanceof jQuery || length !== undefined && typeof length === \"number\" && ( ( length > 0 && elems[ 0 ] && elems[ length -1 ] ) || length === 0 || jQuery.isArray( elems ) ) ;\n\n\t\t// Go through the array, translating each of the items to their\n\t\tif ( isArray ) {\n\t\t\tfor ( ; i < length; i++ ) {\n\t\t\t\tvalue = callback( elems[ i ], i, arg );\n\n\t\t\t\tif ( value != null ) {\n\t\t\t\t\tret[ ret.length ] = value;\n\t\t\t\t}\n\t\t\t}\n\n\t\t// Go through every key on the object,\n\t\t} else {\n\t\t\tfor ( key in elems ) {\n\t\t\t\tvalue = callback( elems[ key ], key, arg );\n\n\t\t\t\tif ( value != null ) {\n\t\t\t\t\tret[ ret.length ] = value;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Flatten any nested arrays\n\t\treturn ret.concat.apply( [], ret );\n\t},\n\n\t// A global GUID counter for objects\n\tguid: 1,\n\n\t// Bind a function to a context, optionally partially applying any\n\t// arguments.\n\tproxy: function( fn, context ) {\n\t\tvar tmp, args, proxy;\n\n\t\tif ( typeof context === \"string\" ) {\n\t\t\ttmp = fn[ context ];\n\t\t\tcontext = fn;\n\t\t\tfn = tmp;\n\t\t}\n\n\t\t// Quick check to determine if target is callable, in the spec\n\t\t// this throws a TypeError, but we will just return undefined.\n\t\tif ( !jQuery.isFunction( fn ) ) {\n\t\t\treturn undefined;\n\t\t}\n\n\t\t// Simulated bind\n\t\targs = core_slice.call( arguments, 2 );\n\t\tproxy = function() {\n\t\t\treturn fn.apply( context, args.concat( core_slice.call( arguments ) ) );\n\t\t};\n\n\t\t// Set the guid of unique handler to the same of original handler, so it can be removed\n\t\tproxy.guid = fn.guid = fn.guid || jQuery.guid++;\n\n\t\treturn proxy;\n\t},\n\n\t// Multifunctional method to get and set values of a collection\n\t// The value/s can optionally be executed if it's a function\n\taccess: function( elems, fn, key, value, chainable, emptyGet, pass ) {\n\t\tvar exec,\n\t\t\tbulk = key == null,\n\t\t\ti = 0,\n\t\t\tlength = elems.length;\n\n\t\t// Sets many values\n\t\tif ( key && typeof key === \"object\" ) {\n\t\t\tfor ( i in key ) {\n\t\t\t\tjQuery.access( elems, fn, i, key[i], 1, emptyGet, value );\n\t\t\t}\n\t\t\tchainable = 1;\n\n\t\t// Sets one value\n\t\t} else if ( value !== undefined ) {\n\t\t\t// Optionally, function values get executed if exec is true\n\t\t\texec = pass === undefined && jQuery.isFunction( value );\n\n\t\t\tif ( bulk ) {\n\t\t\t\t// Bulk operations only iterate when executing function values\n\t\t\t\tif ( exec ) {\n\t\t\t\t\texec = fn;\n\t\t\t\t\tfn = function( elem, key, value ) {\n\t\t\t\t\t\treturn exec.call( jQuery( elem ), value );\n\t\t\t\t\t};\n\n\t\t\t\t// Otherwise they run against the entire set\n\t\t\t\t} else {\n\t\t\t\t\tfn.call( elems, value );\n\t\t\t\t\tfn = null;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif ( fn ) {\n\t\t\t\tfor (; i < length; i++ ) {\n\t\t\t\t\tfn( elems[i], key, exec ? value.call( elems[i], i, fn( elems[i], key ) ) : value, pass );\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tchainable = 1;\n\t\t}\n\n\t\treturn chainable ?\n\t\t\telems :\n\n\t\t\t// Gets\n\t\t\tbulk ?\n\t\t\t\tfn.call( elems ) :\n\t\t\t\tlength ? fn( elems[0], key ) : emptyGet;\n\t},\n\n\tnow: function() {\n\t\treturn ( new Date() ).getTime();\n\t}\n});\n\njQuery.ready.promise = function( obj ) {\n\tif ( !readyList ) {\n\n\t\treadyList = jQuery.Deferred();\n\n\t\t// Catch cases where $(document).ready() is called after the browser event has already occurred.\n\t\t// we once tried to use readyState \"interactive\" here, but it caused issues like the one\n\t\t// discovered by ChrisS here: http://bugs.jquery.com/ticket/12282#comment:15\n\t\tif ( document.readyState === \"complete\" ) {\n\t\t\t// Handle it asynchronously to allow scripts the opportunity to delay ready\n\t\t\tsetTimeout( jQuery.ready, 1 );\n\n\t\t// Standards-based browsers support DOMContentLoaded\n\t\t} else if ( document.addEventListener ) {\n\t\t\t// Use the handy event callback\n\t\t\tdocument.addEventListener( \"DOMContentLoaded\", DOMContentLoaded, false );\n\n\t\t\t// A fallback to window.onload, that will always work\n\t\t\twindow.addEventListener( \"load\", jQuery.ready, false );\n\n\t\t// If IE event model is used\n\t\t} else {\n\t\t\t// Ensure firing before onload, maybe late but safe also for iframes\n\t\t\tdocument.attachEvent( \"onreadystatechange\", DOMContentLoaded );\n\n\t\t\t// A fallback to window.onload, that will always work\n\t\t\twindow.attachEvent( \"onload\", jQuery.ready );\n\n\t\t\t// If IE and not a frame\n\t\t\t// continually check to see if the document is ready\n\t\t\tvar top = false;\n\n\t\t\ttry {\n\t\t\t\ttop = window.frameElement == null && document.documentElement;\n\t\t\t} catch(e) {}\n\n\t\t\tif ( top && top.doScroll ) {\n\t\t\t\t(function doScrollCheck() {\n\t\t\t\t\tif ( !jQuery.isReady ) {\n\n\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t// Use the trick by Diego Perini\n\t\t\t\t\t\t\t// http://javascript.nwbox.com/IEContentLoaded/\n\t\t\t\t\t\t\ttop.doScroll(\"left\");\n\t\t\t\t\t\t} catch(e) {\n\t\t\t\t\t\t\treturn setTimeout( doScrollCheck, 50 );\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// and execute any waiting functions\n\t\t\t\t\t\tjQuery.ready();\n\t\t\t\t\t}\n\t\t\t\t})();\n\t\t\t}\n\t\t}\n\t}\n\treturn readyList.promise( obj );\n};\n\n// Populate the class2type map\njQuery.each(\"Boolean Number String Function Array Date RegExp Object\".split(\" \"), function(i, name) {\n\tclass2type[ \"[object \" + name + \"]\" ] = name.toLowerCase();\n});\n\n// All jQuery objects should point back to these\nrootjQuery = jQuery(document);\n// String to Object options format cache\nvar optionsCache = {};\n\n// Convert String-formatted options into Object-formatted ones and store in cache\nfunction createOptions( options ) {\n\tvar object = optionsCache[ options ] = {};\n\tjQuery.each( options.split( core_rspace ), function( _, flag ) {\n\t\tobject[ flag ] = true;\n\t});\n\treturn object;\n}\n\n/*\n * Create a callback list using the following parameters:\n *\n *\toptions: an optional list of space-separated options that will change how\n *\t\t\tthe callback list behaves or a more traditional option object\n *\n * By default a callback list will act like an event callback list and can be\n * \"fired\" multiple times.\n *\n * Possible options:\n *\n *\tonce:\t\t\twill ensure the callback list can only be fired once (like a Deferred)\n *\n *\tmemory:\t\t\twill keep track of previous values and will call any callback added\n *\t\t\t\t\tafter the list has been fired right away with the latest \"memorized\"\n *\t\t\t\t\tvalues (like a Deferred)\n *\n *\tunique:\t\t\twill ensure a callback can only be added once (no duplicate in the list)\n *\n *\tstopOnFalse:\tinterrupt callings when a callback returns false\n *\n */\njQuery.Callbacks = function( options ) {\n\n\t// Convert options from String-formatted to Object-formatted if needed\n\t// (we check in cache first)\n\toptions = typeof options === \"string\" ?\n\t\t( optionsCache[ options ] || createOptions( options ) ) :\n\t\tjQuery.extend( {}, options );\n\n\tvar // Last fire value (for non-forgettable lists)\n\t\tmemory,\n\t\t// Flag to know if list was already fired\n\t\tfired,\n\t\t// Flag to know if list is currently firing\n\t\tfiring,\n\t\t// First callback to fire (used internally by add and fireWith)\n\t\tfiringStart,\n\t\t// End of the loop when firing\n\t\tfiringLength,\n\t\t// Index of currently firing callback (modified by remove if needed)\n\t\tfiringIndex,\n\t\t// Actual callback list\n\t\tlist = [],\n\t\t// Stack of fire calls for repeatable lists\n\t\tstack = !options.once && [],\n\t\t// Fire callbacks\n\t\tfire = function( data ) {\n\t\t\tmemory = options.memory && data;\n\t\t\tfired = true;\n\t\t\tfiringIndex = firingStart || 0;\n\t\t\tfiringStart = 0;\n\t\t\tfiringLength = list.length;\n\t\t\tfiring = true;\n\t\t\tfor ( ; list && firingIndex < firingLength; firingIndex++ ) {\n\t\t\t\tif ( list[ firingIndex ].apply( data[ 0 ], data[ 1 ] ) === false && options.stopOnFalse ) {\n\t\t\t\t\tmemory = false; // To prevent further calls using add\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t\tfiring = false;\n\t\t\tif ( list ) {\n\t\t\t\tif ( stack ) {\n\t\t\t\t\tif ( stack.length ) {\n\t\t\t\t\t\tfire( stack.shift() );\n\t\t\t\t\t}\n\t\t\t\t} else if ( memory ) {\n\t\t\t\t\tlist = [];\n\t\t\t\t} else {\n\t\t\t\t\tself.disable();\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\t// Actual Callbacks object\n\t\tself = {\n\t\t\t// Add a callback or a collection of callbacks to the list\n\t\t\tadd: function() {\n\t\t\t\tif ( list ) {\n\t\t\t\t\t// First, we save the current length\n\t\t\t\t\tvar start = list.length;\n\t\t\t\t\t(function add( args ) {\n\t\t\t\t\t\tjQuery.each( args, function( _, arg ) {\n\t\t\t\t\t\t\tvar type = jQuery.type( arg );\n\t\t\t\t\t\t\tif ( type === \"function\" ) {\n\t\t\t\t\t\t\t\tif ( !options.unique || !self.has( arg ) ) {\n\t\t\t\t\t\t\t\t\tlist.push( arg );\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t} else if ( arg && arg.length && type !== \"string\" ) {\n\t\t\t\t\t\t\t\t// Inspect recursively\n\t\t\t\t\t\t\t\tadd( arg );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t});\n\t\t\t\t\t})( arguments );\n\t\t\t\t\t// Do we need to add the callbacks to the\n\t\t\t\t\t// current firing batch?\n\t\t\t\t\tif ( firing ) {\n\t\t\t\t\t\tfiringLength = list.length;\n\t\t\t\t\t// With memory, if we're not firing then\n\t\t\t\t\t// we should call right away\n\t\t\t\t\t} else if ( memory ) {\n\t\t\t\t\t\tfiringStart = start;\n\t\t\t\t\t\tfire( memory );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn this;\n\t\t\t},\n\t\t\t// Remove a callback from the list\n\t\t\tremove: function() {\n\t\t\t\tif ( list ) {\n\t\t\t\t\tjQuery.each( arguments, function( _, arg ) {\n\t\t\t\t\t\tvar index;\n\t\t\t\t\t\twhile( ( index = jQuery.inArray( arg, list, index ) ) > -1 ) {\n\t\t\t\t\t\t\tlist.splice( index, 1 );\n\t\t\t\t\t\t\t// Handle firing indexes\n\t\t\t\t\t\t\tif ( firing ) {\n\t\t\t\t\t\t\t\tif ( index <= firingLength ) {\n\t\t\t\t\t\t\t\t\tfiringLength--;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tif ( index <= firingIndex ) {\n\t\t\t\t\t\t\t\t\tfiringIndex--;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t\treturn this;\n\t\t\t},\n\t\t\t// Control if a given callback is in the list\n\t\t\thas: function( fn ) {\n\t\t\t\treturn jQuery.inArray( fn, list ) > -1;\n\t\t\t},\n\t\t\t// Remove all callbacks from the list\n\t\t\tempty: function() {\n\t\t\t\tlist = [];\n\t\t\t\treturn this;\n\t\t\t},\n\t\t\t// Have the list do nothing anymore\n\t\t\tdisable: function() {\n\t\t\t\tlist = stack = memory = undefined;\n\t\t\t\treturn this;\n\t\t\t},\n\t\t\t// Is it disabled?\n\t\t\tdisabled: function() {\n\t\t\t\treturn !list;\n\t\t\t},\n\t\t\t// Lock the list in its current state\n\t\t\tlock: function() {\n\t\t\t\tstack = undefined;\n\t\t\t\tif ( !memory ) {\n\t\t\t\t\tself.disable();\n\t\t\t\t}\n\t\t\t\treturn this;\n\t\t\t},\n\t\t\t// Is it locked?\n\t\t\tlocked: function() {\n\t\t\t\treturn !stack;\n\t\t\t},\n\t\t\t// Call all callbacks with the given context and arguments\n\t\t\tfireWith: function( context, args ) {\n\t\t\t\targs = args || [];\n\t\t\t\targs = [ context, args.slice ? args.slice() : args ];\n\t\t\t\tif ( list && ( !fired || stack ) ) {\n\t\t\t\t\tif ( firing ) {\n\t\t\t\t\t\tstack.push( args );\n\t\t\t\t\t} else {\n\t\t\t\t\t\tfire( args );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn this;\n\t\t\t},\n\t\t\t// Call all the callbacks with the given arguments\n\t\t\tfire: function() {\n\t\t\t\tself.fireWith( this, arguments );\n\t\t\t\treturn this;\n\t\t\t},\n\t\t\t// To know if the callbacks have already been called at least once\n\t\t\tfired: function() {\n\t\t\t\treturn !!fired;\n\t\t\t}\n\t\t};\n\n\treturn self;\n};\njQuery.extend({\n\n\tDeferred: function( func ) {\n\t\tvar tuples = [\n\t\t\t\t// action, add listener, listener list, final state\n\t\t\t\t[ \"resolve\", \"done\", jQuery.Callbacks(\"once memory\"), \"resolved\" ],\n\t\t\t\t[ \"reject\", \"fail\", jQuery.Callbacks(\"once memory\"), \"rejected\" ],\n\t\t\t\t[ \"notify\", \"progress\", jQuery.Callbacks(\"memory\") ]\n\t\t\t],\n\t\t\tstate = \"pending\",\n\t\t\tpromise = {\n\t\t\t\tstate: function() {\n\t\t\t\t\treturn state;\n\t\t\t\t},\n\t\t\t\talways: function() {\n\t\t\t\t\tdeferred.done( arguments ).fail( arguments );\n\t\t\t\t\treturn this;\n\t\t\t\t},\n\t\t\t\tthen: function( /* fnDone, fnFail, fnProgress */ ) {\n\t\t\t\t\tvar fns = arguments;\n\t\t\t\t\treturn jQuery.Deferred(function( newDefer ) {\n\t\t\t\t\t\tjQuery.each( tuples, function( i, tuple ) {\n\t\t\t\t\t\t\tvar action = tuple[ 0 ],\n\t\t\t\t\t\t\t\tfn = fns[ i ];\n\t\t\t\t\t\t\t// deferred[ done | fail | progress ] for forwarding actions to newDefer\n\t\t\t\t\t\t\tdeferred[ tuple[1] ]( jQuery.isFunction( fn ) ?\n\t\t\t\t\t\t\t\tfunction() {\n\t\t\t\t\t\t\t\t\tvar returned = fn.apply( this, arguments );\n\t\t\t\t\t\t\t\t\tif ( returned && jQuery.isFunction( returned.promise ) ) {\n\t\t\t\t\t\t\t\t\t\treturned.promise()\n\t\t\t\t\t\t\t\t\t\t\t.done( newDefer.resolve )\n\t\t\t\t\t\t\t\t\t\t\t.fail( newDefer.reject )\n\t\t\t\t\t\t\t\t\t\t\t.progress( newDefer.notify );\n\t\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\t\tnewDefer[ action + \"With\" ]( this === deferred ? newDefer : this, [ returned ] );\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t} :\n\t\t\t\t\t\t\t\tnewDefer[ action ]\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t});\n\t\t\t\t\t\tfns = null;\n\t\t\t\t\t}).promise();\n\t\t\t\t},\n\t\t\t\t// Get a promise for this deferred\n\t\t\t\t// If obj is provided, the promise aspect is added to the object\n\t\t\t\tpromise: function( obj ) {\n\t\t\t\t\treturn obj != null ? jQuery.extend( obj, promise ) : promise;\n\t\t\t\t}\n\t\t\t},\n\t\t\tdeferred = {};\n\n\t\t// Keep pipe for back-compat\n\t\tpromise.pipe = promise.then;\n\n\t\t// Add list-specific methods\n\t\tjQuery.each( tuples, function( i, tuple ) {\n\t\t\tvar list = tuple[ 2 ],\n\t\t\t\tstateString = tuple[ 3 ];\n\n\t\t\t// promise[ done | fail | progress ] = list.add\n\t\t\tpromise[ tuple[1] ] = list.add;\n\n\t\t\t// Handle state\n\t\t\tif ( stateString ) {\n\t\t\t\tlist.add(function() {\n\t\t\t\t\t// state = [ resolved | rejected ]\n\t\t\t\t\tstate = stateString;\n\n\t\t\t\t// [ reject_list | resolve_list ].disable; progress_list.lock\n\t\t\t\t}, tuples[ i ^ 1 ][ 2 ].disable, tuples[ 2 ][ 2 ].lock );\n\t\t\t}\n\n\t\t\t// deferred[ resolve | reject | notify ] = list.fire\n\t\t\tdeferred[ tuple[0] ] = list.fire;\n\t\t\tdeferred[ tuple[0] + \"With\" ] = list.fireWith;\n\t\t});\n\n\t\t// Make the deferred a promise\n\t\tpromise.promise( deferred );\n\n\t\t// Call given func if any\n\t\tif ( func ) {\n\t\t\tfunc.call( deferred, deferred );\n\t\t}\n\n\t\t// All done!\n\t\treturn deferred;\n\t},\n\n\t// Deferred helper\n\twhen: function( subordinate /* , ..., subordinateN */ ) {\n\t\tvar i = 0,\n\t\t\tresolveValues = core_slice.call( arguments ),\n\t\t\tlength = resolveValues.length,\n\n\t\t\t// the count of uncompleted subordinates\n\t\t\tremaining = length !== 1 || ( subordinate && jQuery.isFunction( subordinate.promise ) ) ? length : 0,\n\n\t\t\t// the master Deferred. If resolveValues consist of only a single Deferred, just use that.\n\t\t\tdeferred = remaining === 1 ? subordinate : jQuery.Deferred(),\n\n\t\t\t// Update function for both resolve and progress values\n\t\t\tupdateFunc = function( i, contexts, values ) {\n\t\t\t\treturn function( value ) {\n\t\t\t\t\tcontexts[ i ] = this;\n\t\t\t\t\tvalues[ i ] = arguments.length > 1 ? core_slice.call( arguments ) : value;\n\t\t\t\t\tif( values === progressValues ) {\n\t\t\t\t\t\tdeferred.notifyWith( contexts, values );\n\t\t\t\t\t} else if ( !( --remaining ) ) {\n\t\t\t\t\t\tdeferred.resolveWith( contexts, values );\n\t\t\t\t\t}\n\t\t\t\t};\n\t\t\t},\n\n\t\t\tprogressValues, progressContexts, resolveContexts;\n\n\t\t// add listeners to Deferred subordinates; treat others as resolved\n\t\tif ( length > 1 ) {\n\t\t\tprogressValues = new Array( length );\n\t\t\tprogressContexts = new Array( length );\n\t\t\tresolveContexts = new Array( length );\n\t\t\tfor ( ; i < length; i++ ) {\n\t\t\t\tif ( resolveValues[ i ] && jQuery.isFunction( resolveValues[ i ].promise ) ) {\n\t\t\t\t\tresolveValues[ i ].promise()\n\t\t\t\t\t\t.done( updateFunc( i, resolveContexts, resolveValues ) )\n\t\t\t\t\t\t.fail( deferred.reject )\n\t\t\t\t\t\t.progress( updateFunc( i, progressContexts, progressValues ) );\n\t\t\t\t} else {\n\t\t\t\t\t--remaining;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// if we're not waiting on anything, resolve the master\n\t\tif ( !remaining ) {\n\t\t\tdeferred.resolveWith( resolveContexts, resolveValues );\n\t\t}\n\n\t\treturn deferred.promise();\n\t}\n});\njQuery.support = (function() {\n\n\tvar support,\n\t\tall,\n\t\ta,\n\t\tselect,\n\t\topt,\n\t\tinput,\n\t\tfragment,\n\t\teventName,\n\t\ti,\n\t\tisSupported,\n\t\tclickFn,\n\t\tdiv = document.createElement(\"div\");\n\n\t// Setup\n\tdiv.setAttribute( \"className\", \"t\" );\n\tdiv.innerHTML = \"  <link/><table></table><a href='/a'>a</a><input type='checkbox'/>\";\n\n\t// Support tests won't run in some limited or non-browser environments\n\tall = div.getElementsByTagName(\"*\");\n\ta = div.getElementsByTagName(\"a\")[ 0 ];\n\tif ( !all || !a || !all.length ) {\n\t\treturn {};\n\t}\n\n\t// First batch of tests\n\tselect = document.createElement(\"select\");\n\topt = select.appendChild( document.createElement(\"option\") );\n\tinput = div.getElementsByTagName(\"input\")[ 0 ];\n\n\ta.style.cssText = \"top:1px;float:left;opacity:.5\";\n\tsupport = {\n\t\t// IE strips leading whitespace when .innerHTML is used\n\t\tleadingWhitespace: ( div.firstChild.nodeType === 3 ),\n\n\t\t// Make sure that tbody elements aren't automatically inserted\n\t\t// IE will insert them into empty tables\n\t\ttbody: !div.getElementsByTagName(\"tbody\").length,\n\n\t\t// Make sure that link elements get serialized correctly by innerHTML\n\t\t// This requires a wrapper element in IE\n\t\thtmlSerialize: !!div.getElementsByTagName(\"link\").length,\n\n\t\t// Get the style information from getAttribute\n\t\t// (IE uses .cssText instead)\n\t\tstyle: /top/.test( a.getAttribute(\"style\") ),\n\n\t\t// Make sure that URLs aren't manipulated\n\t\t// (IE normalizes it by default)\n\t\threfNormalized: ( a.getAttribute(\"href\") === \"/a\" ),\n\n\t\t// Make sure that element opacity exists\n\t\t// (IE uses filter instead)\n\t\t// Use a regex to work around a WebKit issue. See #5145\n\t\topacity: /^0.5/.test( a.style.opacity ),\n\n\t\t// Verify style float existence\n\t\t// (IE uses styleFloat instead of cssFloat)\n\t\tcssFloat: !!a.style.cssFloat,\n\n\t\t// Make sure that if no value is specified for a checkbox\n\t\t// that it defaults to \"on\".\n\t\t// (WebKit defaults to \"\" instead)\n\t\tcheckOn: ( input.value === \"on\" ),\n\n\t\t// Make sure that a selected-by-default option has a working selected property.\n\t\t// (WebKit defaults to false instead of true, IE too, if it's in an optgroup)\n\t\toptSelected: opt.selected,\n\n\t\t// Test setAttribute on camelCase class. If it works, we need attrFixes when doing get/setAttribute (ie6/7)\n\t\tgetSetAttribute: div.className !== \"t\",\n\n\t\t// Tests for enctype support on a form (#6743)\n\t\tenctype: !!document.createElement(\"form\").enctype,\n\n\t\t// Makes sure cloning an html5 element does not cause problems\n\t\t// Where outerHTML is undefined, this still works\n\t\thtml5Clone: document.createElement(\"nav\").cloneNode( true ).outerHTML !== \"<:nav></:nav>\",\n\n\t\t// jQuery.support.boxModel DEPRECATED in 1.8 since we don't support Quirks Mode\n\t\tboxModel: ( document.compatMode === \"CSS1Compat\" ),\n\n\t\t// Will be defined later\n\t\tsubmitBubbles: true,\n\t\tchangeBubbles: true,\n\t\tfocusinBubbles: false,\n\t\tdeleteExpando: true,\n\t\tnoCloneEvent: true,\n\t\tinlineBlockNeedsLayout: false,\n\t\tshrinkWrapBlocks: false,\n\t\treliableMarginRight: true,\n\t\tboxSizingReliable: true,\n\t\tpixelPosition: false\n\t};\n\n\t// Make sure checked status is properly cloned\n\tinput.checked = true;\n\tsupport.noCloneChecked = input.cloneNode( true ).checked;\n\n\t// Make sure that the options inside disabled selects aren't marked as disabled\n\t// (WebKit marks them as disabled)\n\tselect.disabled = true;\n\tsupport.optDisabled = !opt.disabled;\n\n\t// Test to see if it's possible to delete an expando from an element\n\t// Fails in Internet Explorer\n\ttry {\n\t\tdelete div.test;\n\t} catch( e ) {\n\t\tsupport.deleteExpando = false;\n\t}\n\n\tif ( !div.addEventListener && div.attachEvent && div.fireEvent ) {\n\t\tdiv.attachEvent( \"onclick\", clickFn = function() {\n\t\t\t// Cloning a node shouldn't copy over any\n\t\t\t// bound event handlers (IE does this)\n\t\t\tsupport.noCloneEvent = false;\n\t\t});\n\t\tdiv.cloneNode( true ).fireEvent(\"onclick\");\n\t\tdiv.detachEvent( \"onclick\", clickFn );\n\t}\n\n\t// Check if a radio maintains its value\n\t// after being appended to the DOM\n\tinput = document.createElement(\"input\");\n\tinput.value = \"t\";\n\tinput.setAttribute( \"type\", \"radio\" );\n\tsupport.radioValue = input.value === \"t\";\n\n\tinput.setAttribute( \"checked\", \"checked\" );\n\n\t// #11217 - WebKit loses check when the name is after the checked attribute\n\tinput.setAttribute( \"name\", \"t\" );\n\n\tdiv.appendChild( input );\n\tfragment = document.createDocumentFragment();\n\tfragment.appendChild( div.lastChild );\n\n\t// WebKit doesn't clone checked state correctly in fragments\n\tsupport.checkClone = fragment.cloneNode( true ).cloneNode( true ).lastChild.checked;\n\n\t// Check if a disconnected checkbox will retain its checked\n\t// value of true after appended to the DOM (IE6/7)\n\tsupport.appendChecked = input.checked;\n\n\tfragment.removeChild( input );\n\tfragment.appendChild( div );\n\n\t// Technique from Juriy Zaytsev\n\t// http://perfectionkills.com/detecting-event-support-without-browser-sniffing/\n\t// We only care about the case where non-standard event systems\n\t// are used, namely in IE. Short-circuiting here helps us to\n\t// avoid an eval call (in setAttribute) which can cause CSP\n\t// to go haywire. See: https://developer.mozilla.org/en/Security/CSP\n\tif ( div.attachEvent ) {\n\t\tfor ( i in {\n\t\t\tsubmit: true,\n\t\t\tchange: true,\n\t\t\tfocusin: true\n\t\t}) {\n\t\t\teventName = \"on\" + i;\n\t\t\tisSupported = ( eventName in div );\n\t\t\tif ( !isSupported ) {\n\t\t\t\tdiv.setAttribute( eventName, \"return;\" );\n\t\t\t\tisSupported = ( typeof div[ eventName ] === \"function\" );\n\t\t\t}\n\t\t\tsupport[ i + \"Bubbles\" ] = isSupported;\n\t\t}\n\t}\n\n\t// Run tests that need a body at doc ready\n\tjQuery(function() {\n\t\tvar container, div, tds, marginDiv,\n\t\t\tdivReset = \"padding:0;margin:0;border:0;display:block;overflow:hidden;\",\n\t\t\tbody = document.getElementsByTagName(\"body\")[0];\n\n\t\tif ( !body ) {\n\t\t\t// Return for frameset docs that don't have a body\n\t\t\treturn;\n\t\t}\n\n\t\tcontainer = document.createElement(\"div\");\n\t\tcontainer.style.cssText = \"visibility:hidden;border:0;width:0;height:0;position:static;top:0;margin-top:1px\";\n\t\tbody.insertBefore( container, body.firstChild );\n\n\t\t// Construct the test element\n\t\tdiv = document.createElement(\"div\");\n\t\tcontainer.appendChild( div );\n\n\t\t// Check if table cells still have offsetWidth/Height when they are set\n\t\t// to display:none and there are still other visible table cells in a\n\t\t// table row; if so, offsetWidth/Height are not reliable for use when\n\t\t// determining if an element has been hidden directly using\n\t\t// display:none (it is still safe to use offsets if a parent element is\n\t\t// hidden; don safety goggles and see bug #4512 for more information).\n\t\t// (only IE 8 fails this test)\n\t\tdiv.innerHTML = \"<table><tr><td></td><td>t</td></tr></table>\";\n\t\ttds = div.getElementsByTagName(\"td\");\n\t\ttds[ 0 ].style.cssText = \"padding:0;margin:0;border:0;display:none\";\n\t\tisSupported = ( tds[ 0 ].offsetHeight === 0 );\n\n\t\ttds[ 0 ].style.display = \"\";\n\t\ttds[ 1 ].style.display = \"none\";\n\n\t\t// Check if empty table cells still have offsetWidth/Height\n\t\t// (IE <= 8 fail this test)\n\t\tsupport.reliableHiddenOffsets = isSupported && ( tds[ 0 ].offsetHeight === 0 );\n\n\t\t// Check box-sizing and margin behavior\n\t\tdiv.innerHTML = \"\";\n\t\tdiv.style.cssText = \"box-sizing:border-box;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;padding:1px;border:1px;display:block;width:4px;margin-top:1%;position:absolute;top:1%;\";\n\t\tsupport.boxSizing = ( div.offsetWidth === 4 );\n\t\tsupport.doesNotIncludeMarginInBodyOffset = ( body.offsetTop !== 1 );\n\n\t\t// NOTE: To any future maintainer, we've window.getComputedStyle\n\t\t// because jsdom on node.js will break without it.\n\t\tif ( window.getComputedStyle ) {\n\t\t\tsupport.pixelPosition = ( window.getComputedStyle( div, null ) || {} ).top !== \"1%\";\n\t\t\tsupport.boxSizingReliable = ( window.getComputedStyle( div, null ) || { width: \"4px\" } ).width === \"4px\";\n\n\t\t\t// Check if div with explicit width and no margin-right incorrectly\n\t\t\t// gets computed margin-right based on width of container. For more\n\t\t\t// info see bug #3333\n\t\t\t// Fails in WebKit before Feb 2011 nightlies\n\t\t\t// WebKit Bug 13343 - getComputedStyle returns wrong value for margin-right\n\t\t\tmarginDiv = document.createElement(\"div\");\n\t\t\tmarginDiv.style.cssText = div.style.cssText = divReset;\n\t\t\tmarginDiv.style.marginRight = marginDiv.style.width = \"0\";\n\t\t\tdiv.style.width = \"1px\";\n\t\t\tdiv.appendChild( marginDiv );\n\t\t\tsupport.reliableMarginRight =\n\t\t\t\t!parseFloat( ( window.getComputedStyle( marginDiv, null ) || {} ).marginRight );\n\t\t}\n\n\t\tif ( typeof div.style.zoom !== \"undefined\" ) {\n\t\t\t// Check if natively block-level elements act like inline-block\n\t\t\t// elements when setting their display to 'inline' and giving\n\t\t\t// them layout\n\t\t\t// (IE < 8 does this)\n\t\t\tdiv.innerHTML = \"\";\n\t\t\tdiv.style.cssText = divReset + \"width:1px;padding:1px;display:inline;zoom:1\";\n\t\t\tsupport.inlineBlockNeedsLayout = ( div.offsetWidth === 3 );\n\n\t\t\t// Check if elements with layout shrink-wrap their children\n\t\t\t// (IE 6 does this)\n\t\t\tdiv.style.display = \"block\";\n\t\t\tdiv.style.overflow = \"visible\";\n\t\t\tdiv.innerHTML = \"<div></div>\";\n\t\t\tdiv.firstChild.style.width = \"5px\";\n\t\t\tsupport.shrinkWrapBlocks = ( div.offsetWidth !== 3 );\n\n\t\t\tcontainer.style.zoom = 1;\n\t\t}\n\n\t\t// Null elements to avoid leaks in IE\n\t\tbody.removeChild( container );\n\t\tcontainer = div = tds = marginDiv = null;\n\t});\n\n\t// Null elements to avoid leaks in IE\n\tfragment.removeChild( div );\n\tall = a = select = opt = input = fragment = div = null;\n\n\treturn support;\n})();\nvar rbrace = /(?:\\{[\\s\\S]*\\}|\\[[\\s\\S]*\\])$/,\n\trmultiDash = /([A-Z])/g;\n\njQuery.extend({\n\tcache: {},\n\n\tdeletedIds: [],\n\n\t// Remove at next major release (1.9/2.0)\n\tuuid: 0,\n\n\t// Unique for each copy of jQuery on the page\n\t// Non-digits removed to match rinlinejQuery\n\texpando: \"jQuery\" + ( jQuery.fn.jquery + Math.random() ).replace( /\\D/g, \"\" ),\n\n\t// The following elements throw uncatchable exceptions if you\n\t// attempt to add expando properties to them.\n\tnoData: {\n\t\t\"embed\": true,\n\t\t// Ban all objects except for Flash (which handle expandos)\n\t\t\"object\": \"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000\",\n\t\t\"applet\": true\n\t},\n\n\thasData: function( elem ) {\n\t\telem = elem.nodeType ? jQuery.cache[ elem[jQuery.expando] ] : elem[ jQuery.expando ];\n\t\treturn !!elem && !isEmptyDataObject( elem );\n\t},\n\n\tdata: function( elem, name, data, pvt /* Internal Use Only */ ) {\n\t\tif ( !jQuery.acceptData( elem ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\tvar thisCache, ret,\n\t\t\tinternalKey = jQuery.expando,\n\t\t\tgetByName = typeof name === \"string\",\n\n\t\t\t// We have to handle DOM nodes and JS objects differently because IE6-7\n\t\t\t// can't GC object references properly across the DOM-JS boundary\n\t\t\tisNode = elem.nodeType,\n\n\t\t\t// Only DOM nodes need the global jQuery cache; JS object data is\n\t\t\t// attached directly to the object so GC can occur automatically\n\t\t\tcache = isNode ? jQuery.cache : elem,\n\n\t\t\t// Only defining an ID for JS objects if its cache already exists allows\n\t\t\t// the code to shortcut on the same path as a DOM node with no cache\n\t\t\tid = isNode ? elem[ internalKey ] : elem[ internalKey ] && internalKey;\n\n\t\t// Avoid doing any more work than we need to when trying to get data on an\n\t\t// object that has no data at all\n\t\tif ( (!id || !cache[id] || (!pvt && !cache[id].data)) && getByName && data === undefined ) {\n\t\t\treturn;\n\t\t}\n\n\t\tif ( !id ) {\n\t\t\t// Only DOM nodes need a new unique ID for each element since their data\n\t\t\t// ends up in the global cache\n\t\t\tif ( isNode ) {\n\t\t\t\telem[ internalKey ] = id = jQuery.deletedIds.pop() || jQuery.guid++;\n\t\t\t} else {\n\t\t\t\tid = internalKey;\n\t\t\t}\n\t\t}\n\n\t\tif ( !cache[ id ] ) {\n\t\t\tcache[ id ] = {};\n\n\t\t\t// Avoids exposing jQuery metadata on plain JS objects when the object\n\t\t\t// is serialized using JSON.stringify\n\t\t\tif ( !isNode ) {\n\t\t\t\tcache[ id ].toJSON = jQuery.noop;\n\t\t\t}\n\t\t}\n\n\t\t// An object can be passed to jQuery.data instead of a key/value pair; this gets\n\t\t// shallow copied over onto the existing cache\n\t\tif ( typeof name === \"object\" || typeof name === \"function\" ) {\n\t\t\tif ( pvt ) {\n\t\t\t\tcache[ id ] = jQuery.extend( cache[ id ], name );\n\t\t\t} else {\n\t\t\t\tcache[ id ].data = jQuery.extend( cache[ id ].data, name );\n\t\t\t}\n\t\t}\n\n\t\tthisCache = cache[ id ];\n\n\t\t// jQuery data() is stored in a separate object inside the object's internal data\n\t\t// cache in order to avoid key collisions between internal data and user-defined\n\t\t// data.\n\t\tif ( !pvt ) {\n\t\t\tif ( !thisCache.data ) {\n\t\t\t\tthisCache.data = {};\n\t\t\t}\n\n\t\t\tthisCache = thisCache.data;\n\t\t}\n\n\t\tif ( data !== undefined ) {\n\t\t\tthisCache[ jQuery.camelCase( name ) ] = data;\n\t\t}\n\n\t\t// Check for both converted-to-camel and non-converted data property names\n\t\t// If a data property was specified\n\t\tif ( getByName ) {\n\n\t\t\t// First Try to find as-is property data\n\t\t\tret = thisCache[ name ];\n\n\t\t\t// Test for null|undefined property data\n\t\t\tif ( ret == null ) {\n\n\t\t\t\t// Try to find the camelCased property\n\t\t\t\tret = thisCache[ jQuery.camelCase( name ) ];\n\t\t\t}\n\t\t} else {\n\t\t\tret = thisCache;\n\t\t}\n\n\t\treturn ret;\n\t},\n\n\tremoveData: function( elem, name, pvt /* Internal Use Only */ ) {\n\t\tif ( !jQuery.acceptData( elem ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\tvar thisCache, i, l,\n\n\t\t\tisNode = elem.nodeType,\n\n\t\t\t// See jQuery.data for more information\n\t\t\tcache = isNode ? jQuery.cache : elem,\n\t\t\tid = isNode ? elem[ jQuery.expando ] : jQuery.expando;\n\n\t\t// If there is already no cache entry for this object, there is no\n\t\t// purpose in continuing\n\t\tif ( !cache[ id ] ) {\n\t\t\treturn;\n\t\t}\n\n\t\tif ( name ) {\n\n\t\t\tthisCache = pvt ? cache[ id ] : cache[ id ].data;\n\n\t\t\tif ( thisCache ) {\n\n\t\t\t\t// Support array or space separated string names for data keys\n\t\t\t\tif ( !jQuery.isArray( name ) ) {\n\n\t\t\t\t\t// try the string as a key before any manipulation\n\t\t\t\t\tif ( name in thisCache ) {\n\t\t\t\t\t\tname = [ name ];\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\t// split the camel cased version by spaces unless a key with the spaces exists\n\t\t\t\t\t\tname = jQuery.camelCase( name );\n\t\t\t\t\t\tif ( name in thisCache ) {\n\t\t\t\t\t\t\tname = [ name ];\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tname = name.split(\" \");\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tfor ( i = 0, l = name.length; i < l; i++ ) {\n\t\t\t\t\tdelete thisCache[ name[i] ];\n\t\t\t\t}\n\n\t\t\t\t// If there is no data left in the cache, we want to continue\n\t\t\t\t// and let the cache object itself get destroyed\n\t\t\t\tif ( !( pvt ? isEmptyDataObject : jQuery.isEmptyObject )( thisCache ) ) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// See jQuery.data for more information\n\t\tif ( !pvt ) {\n\t\t\tdelete cache[ id ].data;\n\n\t\t\t// Don't destroy the parent cache unless the internal data object\n\t\t\t// had been the only thing left in it\n\t\t\tif ( !isEmptyDataObject( cache[ id ] ) ) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\n\t\t// Destroy the cache\n\t\tif ( isNode ) {\n\t\t\tjQuery.cleanData( [ elem ], true );\n\n\t\t// Use delete when supported for expandos or `cache` is not a window per isWindow (#10080)\n\t\t} else if ( jQuery.support.deleteExpando || cache != cache.window ) {\n\t\t\tdelete cache[ id ];\n\n\t\t// When all else fails, null\n\t\t} else {\n\t\t\tcache[ id ] = null;\n\t\t}\n\t},\n\n\t// For internal use only.\n\t_data: function( elem, name, data ) {\n\t\treturn jQuery.data( elem, name, data, true );\n\t},\n\n\t// A method for determining if a DOM node can handle the data expando\n\tacceptData: function( elem ) {\n\t\tvar noData = elem.nodeName && jQuery.noData[ elem.nodeName.toLowerCase() ];\n\n\t\t// nodes accept data unless otherwise specified; rejection can be conditional\n\t\treturn !noData || noData !== true && elem.getAttribute(\"classid\") === noData;\n\t}\n});\n\njQuery.fn.extend({\n\tdata: function( key, value ) {\n\t\tvar parts, part, attr, name, l,\n\t\t\telem = this[0],\n\t\t\ti = 0,\n\t\t\tdata = null;\n\n\t\t// Gets all values\n\t\tif ( key === undefined ) {\n\t\t\tif ( this.length ) {\n\t\t\t\tdata = jQuery.data( elem );\n\n\t\t\t\tif ( elem.nodeType === 1 && !jQuery._data( elem, \"parsedAttrs\" ) ) {\n\t\t\t\t\tattr = elem.attributes;\n\t\t\t\t\tfor ( l = attr.length; i < l; i++ ) {\n\t\t\t\t\t\tname = attr[i].name;\n\n\t\t\t\t\t\tif ( !name.indexOf( \"data-\" ) ) {\n\t\t\t\t\t\t\tname = jQuery.camelCase( name.substring(5) );\n\n\t\t\t\t\t\t\tdataAttr( elem, name, data[ name ] );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tjQuery._data( elem, \"parsedAttrs\", true );\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn data;\n\t\t}\n\n\t\t// Sets multiple values\n\t\tif ( typeof key === \"object\" ) {\n\t\t\treturn this.each(function() {\n\t\t\t\tjQuery.data( this, key );\n\t\t\t});\n\t\t}\n\n\t\tparts = key.split( \".\", 2 );\n\t\tparts[1] = parts[1] ? \".\" + parts[1] : \"\";\n\t\tpart = parts[1] + \"!\";\n\n\t\treturn jQuery.access( this, function( value ) {\n\n\t\t\tif ( value === undefined ) {\n\t\t\t\tdata = this.triggerHandler( \"getData\" + part, [ parts[0] ] );\n\n\t\t\t\t// Try to fetch any internally stored data first\n\t\t\t\tif ( data === undefined && elem ) {\n\t\t\t\t\tdata = jQuery.data( elem, key );\n\t\t\t\t\tdata = dataAttr( elem, key, data );\n\t\t\t\t}\n\n\t\t\t\treturn data === undefined && parts[1] ?\n\t\t\t\t\tthis.data( parts[0] ) :\n\t\t\t\t\tdata;\n\t\t\t}\n\n\t\t\tparts[1] = value;\n\t\t\tthis.each(function() {\n\t\t\t\tvar self = jQuery( this );\n\n\t\t\t\tself.triggerHandler( \"setData\" + part, parts );\n\t\t\t\tjQuery.data( this, key, value );\n\t\t\t\tself.triggerHandler( \"changeData\" + part, parts );\n\t\t\t});\n\t\t}, null, value, arguments.length > 1, null, false );\n\t},\n\n\tremoveData: function( key ) {\n\t\treturn this.each(function() {\n\t\t\tjQuery.removeData( this, key );\n\t\t});\n\t}\n});\n\nfunction dataAttr( elem, key, data ) {\n\t// If nothing was found internally, try to fetch any\n\t// data from the HTML5 data-* attribute\n\tif ( data === undefined && elem.nodeType === 1 ) {\n\n\t\tvar name = \"data-\" + key.replace( rmultiDash, \"-$1\" ).toLowerCase();\n\n\t\tdata = elem.getAttribute( name );\n\n\t\tif ( typeof data === \"string\" ) {\n\t\t\ttry {\n\t\t\t\tdata = data === \"true\" ? true :\n\t\t\t\tdata === \"false\" ? false :\n\t\t\t\tdata === \"null\" ? null :\n\t\t\t\t// Only convert to a number if it doesn't change the string\n\t\t\t\t+data + \"\" === data ? +data :\n\t\t\t\trbrace.test( data ) ? jQuery.parseJSON( data ) :\n\t\t\t\t\tdata;\n\t\t\t} catch( e ) {}\n\n\t\t\t// Make sure we set the data so it isn't changed later\n\t\t\tjQuery.data( elem, key, data );\n\n\t\t} else {\n\t\t\tdata = undefined;\n\t\t}\n\t}\n\n\treturn data;\n}\n\n// checks a cache object for emptiness\nfunction isEmptyDataObject( obj ) {\n\tvar name;\n\tfor ( name in obj ) {\n\n\t\t// if the public data object is empty, the private is still empty\n\t\tif ( name === \"data\" && jQuery.isEmptyObject( obj[name] ) ) {\n\t\t\tcontinue;\n\t\t}\n\t\tif ( name !== \"toJSON\" ) {\n\t\t\treturn false;\n\t\t}\n\t}\n\n\treturn true;\n}\njQuery.extend({\n\tqueue: function( elem, type, data ) {\n\t\tvar queue;\n\n\t\tif ( elem ) {\n\t\t\ttype = ( type || \"fx\" ) + \"queue\";\n\t\t\tqueue = jQuery._data( elem, type );\n\n\t\t\t// Speed up dequeue by getting out quickly if this is just a lookup\n\t\t\tif ( data ) {\n\t\t\t\tif ( !queue || jQuery.isArray(data) ) {\n\t\t\t\t\tqueue = jQuery._data( elem, type, jQuery.makeArray(data) );\n\t\t\t\t} else {\n\t\t\t\t\tqueue.push( data );\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn queue || [];\n\t\t}\n\t},\n\n\tdequeue: function( elem, type ) {\n\t\ttype = type || \"fx\";\n\n\t\tvar queue = jQuery.queue( elem, type ),\n\t\t\tstartLength = queue.length,\n\t\t\tfn = queue.shift(),\n\t\t\thooks = jQuery._queueHooks( elem, type ),\n\t\t\tnext = function() {\n\t\t\t\tjQuery.dequeue( elem, type );\n\t\t\t};\n\n\t\t// If the fx queue is dequeued, always remove the progress sentinel\n\t\tif ( fn === \"inprogress\" ) {\n\t\t\tfn = queue.shift();\n\t\t\tstartLength--;\n\t\t}\n\n\t\tif ( fn ) {\n\n\t\t\t// Add a progress sentinel to prevent the fx queue from being\n\t\t\t// automatically dequeued\n\t\t\tif ( type === \"fx\" ) {\n\t\t\t\tqueue.unshift( \"inprogress\" );\n\t\t\t}\n\n\t\t\t// clear up the last queue stop function\n\t\t\tdelete hooks.stop;\n\t\t\tfn.call( elem, next, hooks );\n\t\t}\n\n\t\tif ( !startLength && hooks ) {\n\t\t\thooks.empty.fire();\n\t\t}\n\t},\n\n\t// not intended for public consumption - generates a queueHooks object, or returns the current one\n\t_queueHooks: function( elem, type ) {\n\t\tvar key = type + \"queueHooks\";\n\t\treturn jQuery._data( elem, key ) || jQuery._data( elem, key, {\n\t\t\tempty: jQuery.Callbacks(\"once memory\").add(function() {\n\t\t\t\tjQuery.removeData( elem, type + \"queue\", true );\n\t\t\t\tjQuery.removeData( elem, key, true );\n\t\t\t})\n\t\t});\n\t}\n});\n\njQuery.fn.extend({\n\tqueue: function( type, data ) {\n\t\tvar setter = 2;\n\n\t\tif ( typeof type !== \"string\" ) {\n\t\t\tdata = type;\n\t\t\ttype = \"fx\";\n\t\t\tsetter--;\n\t\t}\n\n\t\tif ( arguments.length < setter ) {\n\t\t\treturn jQuery.queue( this[0], type );\n\t\t}\n\n\t\treturn data === undefined ?\n\t\t\tthis :\n\t\t\tthis.each(function() {\n\t\t\t\tvar queue = jQuery.queue( this, type, data );\n\n\t\t\t\t// ensure a hooks for this queue\n\t\t\t\tjQuery._queueHooks( this, type );\n\n\t\t\t\tif ( type === \"fx\" && queue[0] !== \"inprogress\" ) {\n\t\t\t\t\tjQuery.dequeue( this, type );\n\t\t\t\t}\n\t\t\t});\n\t},\n\tdequeue: function( type ) {\n\t\treturn this.each(function() {\n\t\t\tjQuery.dequeue( this, type );\n\t\t});\n\t},\n\t// Based off of the plugin by Clint Helfers, with permission.\n\t// http://blindsignals.com/index.php/2009/07/jquery-delay/\n\tdelay: function( time, type ) {\n\t\ttime = jQuery.fx ? jQuery.fx.speeds[ time ] || time : time;\n\t\ttype = type || \"fx\";\n\n\t\treturn this.queue( type, function( next, hooks ) {\n\t\t\tvar timeout = setTimeout( next, time );\n\t\t\thooks.stop = function() {\n\t\t\t\tclearTimeout( timeout );\n\t\t\t};\n\t\t});\n\t},\n\tclearQueue: function( type ) {\n\t\treturn this.queue( type || \"fx\", [] );\n\t},\n\t// Get a promise resolved when queues of a certain type\n\t// are emptied (fx is the type by default)\n\tpromise: function( type, obj ) {\n\t\tvar tmp,\n\t\t\tcount = 1,\n\t\t\tdefer = jQuery.Deferred(),\n\t\t\telements = this,\n\t\t\ti = this.length,\n\t\t\tresolve = function() {\n\t\t\t\tif ( !( --count ) ) {\n\t\t\t\t\tdefer.resolveWith( elements, [ elements ] );\n\t\t\t\t}\n\t\t\t};\n\n\t\tif ( typeof type !== \"string\" ) {\n\t\t\tobj = type;\n\t\t\ttype = undefined;\n\t\t}\n\t\ttype = type || \"fx\";\n\n\t\twhile( i-- ) {\n\t\t\ttmp = jQuery._data( elements[ i ], type + \"queueHooks\" );\n\t\t\tif ( tmp && tmp.empty ) {\n\t\t\t\tcount++;\n\t\t\t\ttmp.empty.add( resolve );\n\t\t\t}\n\t\t}\n\t\tresolve();\n\t\treturn defer.promise( obj );\n\t}\n});\nvar nodeHook, boolHook, fixSpecified,\n\trclass = /[\\t\\r\\n]/g,\n\trreturn = /\\r/g,\n\trtype = /^(?:button|input)$/i,\n\trfocusable = /^(?:button|input|object|select|textarea)$/i,\n\trclickable = /^a(?:rea|)$/i,\n\trboolean = /^(?:autofocus|autoplay|async|checked|controls|defer|disabled|hidden|loop|multiple|open|readonly|required|scoped|selected)$/i,\n\tgetSetAttribute = jQuery.support.getSetAttribute;\n\njQuery.fn.extend({\n\tattr: function( name, value ) {\n\t\treturn jQuery.access( this, jQuery.attr, name, value, arguments.length > 1 );\n\t},\n\n\tremoveAttr: function( name ) {\n\t\treturn this.each(function() {\n\t\t\tjQuery.removeAttr( this, name );\n\t\t});\n\t},\n\n\tprop: function( name, value ) {\n\t\treturn jQuery.access( this, jQuery.prop, name, value, arguments.length > 1 );\n\t},\n\n\tremoveProp: function( name ) {\n\t\tname = jQuery.propFix[ name ] || name;\n\t\treturn this.each(function() {\n\t\t\t// try/catch handles cases where IE balks (such as removing a property on window)\n\t\t\ttry {\n\t\t\t\tthis[ name ] = undefined;\n\t\t\t\tdelete this[ name ];\n\t\t\t} catch( e ) {}\n\t\t});\n\t},\n\n\taddClass: function( value ) {\n\t\tvar classNames, i, l, elem,\n\t\t\tsetClass, c, cl;\n\n\t\tif ( jQuery.isFunction( value ) ) {\n\t\t\treturn this.each(function( j ) {\n\t\t\t\tjQuery( this ).addClass( value.call(this, j, this.className) );\n\t\t\t});\n\t\t}\n\n\t\tif ( value && typeof value === \"string\" ) {\n\t\t\tclassNames = value.split( core_rspace );\n\n\t\t\tfor ( i = 0, l = this.length; i < l; i++ ) {\n\t\t\t\telem = this[ i ];\n\n\t\t\t\tif ( elem.nodeType === 1 ) {\n\t\t\t\t\tif ( !elem.className && classNames.length === 1 ) {\n\t\t\t\t\t\telem.className = value;\n\n\t\t\t\t\t} else {\n\t\t\t\t\t\tsetClass = \" \" + elem.className + \" \";\n\n\t\t\t\t\t\tfor ( c = 0, cl = classNames.length; c < cl; c++ ) {\n\t\t\t\t\t\t\tif ( setClass.indexOf( \" \" + classNames[ c ] + \" \" ) < 0 ) {\n\t\t\t\t\t\t\t\tsetClass += classNames[ c ] + \" \";\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\telem.className = jQuery.trim( setClass );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn this;\n\t},\n\n\tremoveClass: function( value ) {\n\t\tvar removes, className, elem, c, cl, i, l;\n\n\t\tif ( jQuery.isFunction( value ) ) {\n\t\t\treturn this.each(function( j ) {\n\t\t\t\tjQuery( this ).removeClass( value.call(this, j, this.className) );\n\t\t\t});\n\t\t}\n\t\tif ( (value && typeof value === \"string\") || value === undefined ) {\n\t\t\tremoves = ( value || \"\" ).split( core_rspace );\n\n\t\t\tfor ( i = 0, l = this.length; i < l; i++ ) {\n\t\t\t\telem = this[ i ];\n\t\t\t\tif ( elem.nodeType === 1 && elem.className ) {\n\n\t\t\t\t\tclassName = (\" \" + elem.className + \" \").replace( rclass, \" \" );\n\n\t\t\t\t\t// loop over each item in the removal list\n\t\t\t\t\tfor ( c = 0, cl = removes.length; c < cl; c++ ) {\n\t\t\t\t\t\t// Remove until there is nothing to remove,\n\t\t\t\t\t\twhile ( className.indexOf(\" \" + removes[ c ] + \" \") >= 0 ) {\n\t\t\t\t\t\t\tclassName = className.replace( \" \" + removes[ c ] + \" \" , \" \" );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\telem.className = value ? jQuery.trim( className ) : \"\";\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn this;\n\t},\n\n\ttoggleClass: function( value, stateVal ) {\n\t\tvar type = typeof value,\n\t\t\tisBool = typeof stateVal === \"boolean\";\n\n\t\tif ( jQuery.isFunction( value ) ) {\n\t\t\treturn this.each(function( i ) {\n\t\t\t\tjQuery( this ).toggleClass( value.call(this, i, this.className, stateVal), stateVal );\n\t\t\t});\n\t\t}\n\n\t\treturn this.each(function() {\n\t\t\tif ( type === \"string\" ) {\n\t\t\t\t// toggle individual class names\n\t\t\t\tvar className,\n\t\t\t\t\ti = 0,\n\t\t\t\t\tself = jQuery( this ),\n\t\t\t\t\tstate = stateVal,\n\t\t\t\t\tclassNames = value.split( core_rspace );\n\n\t\t\t\twhile ( (className = classNames[ i++ ]) ) {\n\t\t\t\t\t// check each className given, space separated list\n\t\t\t\t\tstate = isBool ? state : !self.hasClass( className );\n\t\t\t\t\tself[ state ? \"addClass\" : \"removeClass\" ]( className );\n\t\t\t\t}\n\n\t\t\t} else if ( type === \"undefined\" || type === \"boolean\" ) {\n\t\t\t\tif ( this.className ) {\n\t\t\t\t\t// store className if set\n\t\t\t\t\tjQuery._data( this, \"__className__\", this.className );\n\t\t\t\t}\n\n\t\t\t\t// toggle whole className\n\t\t\t\tthis.className = this.className || value === false ? \"\" : jQuery._data( this, \"__className__\" ) || \"\";\n\t\t\t}\n\t\t});\n\t},\n\n\thasClass: function( selector ) {\n\t\tvar className = \" \" + selector + \" \",\n\t\t\ti = 0,\n\t\t\tl = this.length;\n\t\tfor ( ; i < l; i++ ) {\n\t\t\tif ( this[i].nodeType === 1 && (\" \" + this[i].className + \" \").replace(rclass, \" \").indexOf( className ) >= 0 ) {\n\t\t\t\treturn true;\n\t\t\t}\n\t\t}\n\n\t\treturn false;\n\t},\n\n\tval: function( value ) {\n\t\tvar hooks, ret, isFunction,\n\t\t\telem = this[0];\n\n\t\tif ( !arguments.length ) {\n\t\t\tif ( elem ) {\n\t\t\t\thooks = jQuery.valHooks[ elem.type ] || jQuery.valHooks[ elem.nodeName.toLowerCase() ];\n\n\t\t\t\tif ( hooks && \"get\" in hooks && (ret = hooks.get( elem, \"value\" )) !== undefined ) {\n\t\t\t\t\treturn ret;\n\t\t\t\t}\n\n\t\t\t\tret = elem.value;\n\n\t\t\t\treturn typeof ret === \"string\" ?\n\t\t\t\t\t// handle most common string cases\n\t\t\t\t\tret.replace(rreturn, \"\") :\n\t\t\t\t\t// handle cases where value is null/undef or number\n\t\t\t\t\tret == null ? \"\" : ret;\n\t\t\t}\n\n\t\t\treturn;\n\t\t}\n\n\t\tisFunction = jQuery.isFunction( value );\n\n\t\treturn this.each(function( i ) {\n\t\t\tvar val,\n\t\t\t\tself = jQuery(this);\n\n\t\t\tif ( this.nodeType !== 1 ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif ( isFunction ) {\n\t\t\t\tval = value.call( this, i, self.val() );\n\t\t\t} else {\n\t\t\t\tval = value;\n\t\t\t}\n\n\t\t\t// Treat null/undefined as \"\"; convert numbers to string\n\t\t\tif ( val == null ) {\n\t\t\t\tval = \"\";\n\t\t\t} else if ( typeof val === \"number\" ) {\n\t\t\t\tval += \"\";\n\t\t\t} else if ( jQuery.isArray( val ) ) {\n\t\t\t\tval = jQuery.map(val, function ( value ) {\n\t\t\t\t\treturn value == null ? \"\" : value + \"\";\n\t\t\t\t});\n\t\t\t}\n\n\t\t\thooks = jQuery.valHooks[ this.type ] || jQuery.valHooks[ this.nodeName.toLowerCase() ];\n\n\t\t\t// If set returns undefined, fall back to normal setting\n\t\t\tif ( !hooks || !(\"set\" in hooks) || hooks.set( this, val, \"value\" ) === undefined ) {\n\t\t\t\tthis.value = val;\n\t\t\t}\n\t\t});\n\t}\n});\n\njQuery.extend({\n\tvalHooks: {\n\t\toption: {\n\t\t\tget: function( elem ) {\n\t\t\t\t// attributes.value is undefined in Blackberry 4.7 but\n\t\t\t\t// uses .value. See #6932\n\t\t\t\tvar val = elem.attributes.value;\n\t\t\t\treturn !val || val.specified ? elem.value : elem.text;\n\t\t\t}\n\t\t},\n\t\tselect: {\n\t\t\tget: function( elem ) {\n\t\t\t\tvar value, option,\n\t\t\t\t\toptions = elem.options,\n\t\t\t\t\tindex = elem.selectedIndex,\n\t\t\t\t\tone = elem.type === \"select-one\" || index < 0,\n\t\t\t\t\tvalues = one ? null : [],\n\t\t\t\t\tmax = one ? index + 1 : options.length,\n\t\t\t\t\ti = index < 0 ?\n\t\t\t\t\t\tmax :\n\t\t\t\t\t\tone ? index : 0;\n\n\t\t\t\t// Loop through all the selected options\n\t\t\t\tfor ( ; i < max; i++ ) {\n\t\t\t\t\toption = options[ i ];\n\n\t\t\t\t\t// oldIE doesn't update selected after form reset (#2551)\n\t\t\t\t\tif ( ( option.selected || i === index ) &&\n\t\t\t\t\t\t\t// Don't return options that are disabled or in a disabled optgroup\n\t\t\t\t\t\t\t( jQuery.support.optDisabled ? !option.disabled : option.getAttribute(\"disabled\") === null ) &&\n\t\t\t\t\t\t\t( !option.parentNode.disabled || !jQuery.nodeName( option.parentNode, \"optgroup\" ) ) ) {\n\n\t\t\t\t\t\t// Get the specific value for the option\n\t\t\t\t\t\tvalue = jQuery( option ).val();\n\n\t\t\t\t\t\t// We don't need an array for one selects\n\t\t\t\t\t\tif ( one ) {\n\t\t\t\t\t\t\treturn value;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// Multi-Selects return an array\n\t\t\t\t\t\tvalues.push( value );\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\treturn values;\n\t\t\t},\n\n\t\t\tset: function( elem, value ) {\n\t\t\t\tvar values = jQuery.makeArray( value );\n\n\t\t\t\tjQuery(elem).find(\"option\").each(function() {\n\t\t\t\t\tthis.selected = jQuery.inArray( jQuery(this).val(), values ) >= 0;\n\t\t\t\t});\n\n\t\t\t\tif ( !values.length ) {\n\t\t\t\t\telem.selectedIndex = -1;\n\t\t\t\t}\n\t\t\t\treturn values;\n\t\t\t}\n\t\t}\n\t},\n\n\t// Unused in 1.8, left in so attrFn-stabbers won't die; remove in 1.9\n\tattrFn: {},\n\n\tattr: function( elem, name, value, pass ) {\n\t\tvar ret, hooks, notxml,\n\t\t\tnType = elem.nodeType;\n\n\t\t// don't get/set attributes on text, comment and attribute nodes\n\t\tif ( !elem || nType === 3 || nType === 8 || nType === 2 ) {\n\t\t\treturn;\n\t\t}\n\n\t\tif ( pass && jQuery.isFunction( jQuery.fn[ name ] ) ) {\n\t\t\treturn jQuery( elem )[ name ]( value );\n\t\t}\n\n\t\t// Fallback to prop when attributes are not supported\n\t\tif ( typeof elem.getAttribute === \"undefined\" ) {\n\t\t\treturn jQuery.prop( elem, name, value );\n\t\t}\n\n\t\tnotxml = nType !== 1 || !jQuery.isXMLDoc( elem );\n\n\t\t// All attributes are lowercase\n\t\t// Grab necessary hook if one is defined\n\t\tif ( notxml ) {\n\t\t\tname = name.toLowerCase();\n\t\t\thooks = jQuery.attrHooks[ name ] || ( rboolean.test( name ) ? boolHook : nodeHook );\n\t\t}\n\n\t\tif ( value !== undefined ) {\n\n\t\t\tif ( value === null ) {\n\t\t\t\tjQuery.removeAttr( elem, name );\n\t\t\t\treturn;\n\n\t\t\t} else if ( hooks && \"set\" in hooks && notxml && (ret = hooks.set( elem, value, name )) !== undefined ) {\n\t\t\t\treturn ret;\n\n\t\t\t} else {\n\t\t\t\telem.setAttribute( name, value + \"\" );\n\t\t\t\treturn value;\n\t\t\t}\n\n\t\t} else if ( hooks && \"get\" in hooks && notxml && (ret = hooks.get( elem, name )) !== null ) {\n\t\t\treturn ret;\n\n\t\t} else {\n\n\t\t\tret = elem.getAttribute( name );\n\n\t\t\t// Non-existent attributes return null, we normalize to undefined\n\t\t\treturn ret === null ?\n\t\t\t\tundefined :\n\t\t\t\tret;\n\t\t}\n\t},\n\n\tremoveAttr: function( elem, value ) {\n\t\tvar propName, attrNames, name, isBool,\n\t\t\ti = 0;\n\n\t\tif ( value && elem.nodeType === 1 ) {\n\n\t\t\tattrNames = value.split( core_rspace );\n\n\t\t\tfor ( ; i < attrNames.length; i++ ) {\n\t\t\t\tname = attrNames[ i ];\n\n\t\t\t\tif ( name ) {\n\t\t\t\t\tpropName = jQuery.propFix[ name ] || name;\n\t\t\t\t\tisBool = rboolean.test( name );\n\n\t\t\t\t\t// See #9699 for explanation of this approach (setting first, then removal)\n\t\t\t\t\t// Do not do this for boolean attributes (see #10870)\n\t\t\t\t\tif ( !isBool ) {\n\t\t\t\t\t\tjQuery.attr( elem, name, \"\" );\n\t\t\t\t\t}\n\t\t\t\t\telem.removeAttribute( getSetAttribute ? name : propName );\n\n\t\t\t\t\t// Set corresponding property to false for boolean attributes\n\t\t\t\t\tif ( isBool && propName in elem ) {\n\t\t\t\t\t\telem[ propName ] = false;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t},\n\n\tattrHooks: {\n\t\ttype: {\n\t\t\tset: function( elem, value ) {\n\t\t\t\t// We can't allow the type property to be changed (since it causes problems in IE)\n\t\t\t\tif ( rtype.test( elem.nodeName ) && elem.parentNode ) {\n\t\t\t\t\tjQuery.error( \"type property can't be changed\" );\n\t\t\t\t} else if ( !jQuery.support.radioValue && value === \"radio\" && jQuery.nodeName(elem, \"input\") ) {\n\t\t\t\t\t// Setting the type on a radio button after the value resets the value in IE6-9\n\t\t\t\t\t// Reset value to it's default in case type is set after value\n\t\t\t\t\t// This is for element creation\n\t\t\t\t\tvar val = elem.value;\n\t\t\t\t\telem.setAttribute( \"type\", value );\n\t\t\t\t\tif ( val ) {\n\t\t\t\t\t\telem.value = val;\n\t\t\t\t\t}\n\t\t\t\t\treturn value;\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\t// Use the value property for back compat\n\t\t// Use the nodeHook for button elements in IE6/7 (#1954)\n\t\tvalue: {\n\t\t\tget: function( elem, name ) {\n\t\t\t\tif ( nodeHook && jQuery.nodeName( elem, \"button\" ) ) {\n\t\t\t\t\treturn nodeHook.get( elem, name );\n\t\t\t\t}\n\t\t\t\treturn name in elem ?\n\t\t\t\t\telem.value :\n\t\t\t\t\tnull;\n\t\t\t},\n\t\t\tset: function( elem, value, name ) {\n\t\t\t\tif ( nodeHook && jQuery.nodeName( elem, \"button\" ) ) {\n\t\t\t\t\treturn nodeHook.set( elem, value, name );\n\t\t\t\t}\n\t\t\t\t// Does not return so that setAttribute is also used\n\t\t\t\telem.value = value;\n\t\t\t}\n\t\t}\n\t},\n\n\tpropFix: {\n\t\ttabindex: \"tabIndex\",\n\t\treadonly: \"readOnly\",\n\t\t\"for\": \"htmlFor\",\n\t\t\"class\": \"className\",\n\t\tmaxlength: \"maxLength\",\n\t\tcellspacing: \"cellSpacing\",\n\t\tcellpadding: \"cellPadding\",\n\t\trowspan: \"rowSpan\",\n\t\tcolspan: \"colSpan\",\n\t\tusemap: \"useMap\",\n\t\tframeborder: \"frameBorder\",\n\t\tcontenteditable: \"contentEditable\"\n\t},\n\n\tprop: function( elem, name, value ) {\n\t\tvar ret, hooks, notxml,\n\t\t\tnType = elem.nodeType;\n\n\t\t// don't get/set properties on text, comment and attribute nodes\n\t\tif ( !elem || nType === 3 || nType === 8 || nType === 2 ) {\n\t\t\treturn;\n\t\t}\n\n\t\tnotxml = nType !== 1 || !jQuery.isXMLDoc( elem );\n\n\t\tif ( notxml ) {\n\t\t\t// Fix name and attach hooks\n\t\t\tname = jQuery.propFix[ name ] || name;\n\t\t\thooks = jQuery.propHooks[ name ];\n\t\t}\n\n\t\tif ( value !== undefined ) {\n\t\t\tif ( hooks && \"set\" in hooks && (ret = hooks.set( elem, value, name )) !== undefined ) {\n\t\t\t\treturn ret;\n\n\t\t\t} else {\n\t\t\t\treturn ( elem[ name ] = value );\n\t\t\t}\n\n\t\t} else {\n\t\t\tif ( hooks && \"get\" in hooks && (ret = hooks.get( elem, name )) !== null ) {\n\t\t\t\treturn ret;\n\n\t\t\t} else {\n\t\t\t\treturn elem[ name ];\n\t\t\t}\n\t\t}\n\t},\n\n\tpropHooks: {\n\t\ttabIndex: {\n\t\t\tget: function( elem ) {\n\t\t\t\t// elem.tabIndex doesn't always return the correct value when it hasn't been explicitly set\n\t\t\t\t// http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/\n\t\t\t\tvar attributeNode = elem.getAttributeNode(\"tabindex\");\n\n\t\t\t\treturn attributeNode && attributeNode.specified ?\n\t\t\t\t\tparseInt( attributeNode.value, 10 ) :\n\t\t\t\t\trfocusable.test( elem.nodeName ) || rclickable.test( elem.nodeName ) && elem.href ?\n\t\t\t\t\t\t0 :\n\t\t\t\t\t\tundefined;\n\t\t\t}\n\t\t}\n\t}\n});\n\n// Hook for boolean attributes\nboolHook = {\n\tget: function( elem, name ) {\n\t\t// Align boolean attributes with corresponding properties\n\t\t// Fall back to attribute presence where some booleans are not supported\n\t\tvar attrNode,\n\t\t\tproperty = jQuery.prop( elem, name );\n\t\treturn property === true || typeof property !== \"boolean\" && ( attrNode = elem.getAttributeNode(name) ) && attrNode.nodeValue !== false ?\n\t\t\tname.toLowerCase() :\n\t\t\tundefined;\n\t},\n\tset: function( elem, value, name ) {\n\t\tvar propName;\n\t\tif ( value === false ) {\n\t\t\t// Remove boolean attributes when set to false\n\t\t\tjQuery.removeAttr( elem, name );\n\t\t} else {\n\t\t\t// value is true since we know at this point it's type boolean and not false\n\t\t\t// Set boolean attributes to the same name and set the DOM property\n\t\t\tpropName = jQuery.propFix[ name ] || name;\n\t\t\tif ( propName in elem ) {\n\t\t\t\t// Only set the IDL specifically if it already exists on the element\n\t\t\t\telem[ propName ] = true;\n\t\t\t}\n\n\t\t\telem.setAttribute( name, name.toLowerCase() );\n\t\t}\n\t\treturn name;\n\t}\n};\n\n// IE6/7 do not support getting/setting some attributes with get/setAttribute\nif ( !getSetAttribute ) {\n\n\tfixSpecified = {\n\t\tname: true,\n\t\tid: true,\n\t\tcoords: true\n\t};\n\n\t// Use this for any attribute in IE6/7\n\t// This fixes almost every IE6/7 issue\n\tnodeHook = jQuery.valHooks.button = {\n\t\tget: function( elem, name ) {\n\t\t\tvar ret;\n\t\t\tret = elem.getAttributeNode( name );\n\t\t\treturn ret && ( fixSpecified[ name ] ? ret.value !== \"\" : ret.specified ) ?\n\t\t\t\tret.value :\n\t\t\t\tundefined;\n\t\t},\n\t\tset: function( elem, value, name ) {\n\t\t\t// Set the existing or create a new attribute node\n\t\t\tvar ret = elem.getAttributeNode( name );\n\t\t\tif ( !ret ) {\n\t\t\t\tret = document.createAttribute( name );\n\t\t\t\telem.setAttributeNode( ret );\n\t\t\t}\n\t\t\treturn ( ret.value = value + \"\" );\n\t\t}\n\t};\n\n\t// Set width and height to auto instead of 0 on empty string( Bug #8150 )\n\t// This is for removals\n\tjQuery.each([ \"width\", \"height\" ], function( i, name ) {\n\t\tjQuery.attrHooks[ name ] = jQuery.extend( jQuery.attrHooks[ name ], {\n\t\t\tset: function( elem, value ) {\n\t\t\t\tif ( value === \"\" ) {\n\t\t\t\t\telem.setAttribute( name, \"auto\" );\n\t\t\t\t\treturn value;\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\t});\n\n\t// Set contenteditable to false on removals(#10429)\n\t// Setting to empty string throws an error as an invalid value\n\tjQuery.attrHooks.contenteditable = {\n\t\tget: nodeHook.get,\n\t\tset: function( elem, value, name ) {\n\t\t\tif ( value === \"\" ) {\n\t\t\t\tvalue = \"false\";\n\t\t\t}\n\t\t\tnodeHook.set( elem, value, name );\n\t\t}\n\t};\n}\n\n\n// Some attributes require a special call on IE\nif ( !jQuery.support.hrefNormalized ) {\n\tjQuery.each([ \"href\", \"src\", \"width\", \"height\" ], function( i, name ) {\n\t\tjQuery.attrHooks[ name ] = jQuery.extend( jQuery.attrHooks[ name ], {\n\t\t\tget: function( elem ) {\n\t\t\t\tvar ret = elem.getAttribute( name, 2 );\n\t\t\t\treturn ret === null ? undefined : ret;\n\t\t\t}\n\t\t});\n\t});\n}\n\nif ( !jQuery.support.style ) {\n\tjQuery.attrHooks.style = {\n\t\tget: function( elem ) {\n\t\t\t// Return undefined in the case of empty string\n\t\t\t// Normalize to lowercase since IE uppercases css property names\n\t\t\treturn elem.style.cssText.toLowerCase() || undefined;\n\t\t},\n\t\tset: function( elem, value ) {\n\t\t\treturn ( elem.style.cssText = value + \"\" );\n\t\t}\n\t};\n}\n\n// Safari mis-reports the default selected property of an option\n// Accessing the parent's selectedIndex property fixes it\nif ( !jQuery.support.optSelected ) {\n\tjQuery.propHooks.selected = jQuery.extend( jQuery.propHooks.selected, {\n\t\tget: function( elem ) {\n\t\t\tvar parent = elem.parentNode;\n\n\t\t\tif ( parent ) {\n\t\t\t\tparent.selectedIndex;\n\n\t\t\t\t// Make sure that it also works with optgroups, see #5701\n\t\t\t\tif ( parent.parentNode ) {\n\t\t\t\t\tparent.parentNode.selectedIndex;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn null;\n\t\t}\n\t});\n}\n\n// IE6/7 call enctype encoding\nif ( !jQuery.support.enctype ) {\n\tjQuery.propFix.enctype = \"encoding\";\n}\n\n// Radios and checkboxes getter/setter\nif ( !jQuery.support.checkOn ) {\n\tjQuery.each([ \"radio\", \"checkbox\" ], function() {\n\t\tjQuery.valHooks[ this ] = {\n\t\t\tget: function( elem ) {\n\t\t\t\t// Handle the case where in Webkit \"\" is returned instead of \"on\" if a value isn't specified\n\t\t\t\treturn elem.getAttribute(\"value\") === null ? \"on\" : elem.value;\n\t\t\t}\n\t\t};\n\t});\n}\njQuery.each([ \"radio\", \"checkbox\" ], function() {\n\tjQuery.valHooks[ this ] = jQuery.extend( jQuery.valHooks[ this ], {\n\t\tset: function( elem, value ) {\n\t\t\tif ( jQuery.isArray( value ) ) {\n\t\t\t\treturn ( elem.checked = jQuery.inArray( jQuery(elem).val(), value ) >= 0 );\n\t\t\t}\n\t\t}\n\t});\n});\nvar rformElems = /^(?:textarea|input|select)$/i,\n\trtypenamespace = /^([^\\.]*|)(?:\\.(.+)|)$/,\n\trhoverHack = /(?:^|\\s)hover(\\.\\S+|)\\b/,\n\trkeyEvent = /^key/,\n\trmouseEvent = /^(?:mouse|contextmenu)|click/,\n\trfocusMorph = /^(?:focusinfocus|focusoutblur)$/,\n\thoverHack = function( events ) {\n\t\treturn jQuery.event.special.hover ? events : events.replace( rhoverHack, \"mouseenter$1 mouseleave$1\" );\n\t};\n\n/*\n * Helper functions for managing events -- not part of the public interface.\n * Props to Dean Edwards' addEvent library for many of the ideas.\n */\njQuery.event = {\n\n\tadd: function( elem, types, handler, data, selector ) {\n\n\t\tvar elemData, eventHandle, events,\n\t\t\tt, tns, type, namespaces, handleObj,\n\t\t\thandleObjIn, handlers, special;\n\n\t\t// Don't attach events to noData or text/comment nodes (allow plain objects tho)\n\t\tif ( elem.nodeType === 3 || elem.nodeType === 8 || !types || !handler || !(elemData = jQuery._data( elem )) ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Caller can pass in an object of custom data in lieu of the handler\n\t\tif ( handler.handler ) {\n\t\t\thandleObjIn = handler;\n\t\t\thandler = handleObjIn.handler;\n\t\t\tselector = handleObjIn.selector;\n\t\t}\n\n\t\t// Make sure that the handler has a unique ID, used to find/remove it later\n\t\tif ( !handler.guid ) {\n\t\t\thandler.guid = jQuery.guid++;\n\t\t}\n\n\t\t// Init the element's event structure and main handler, if this is the first\n\t\tevents = elemData.events;\n\t\tif ( !events ) {\n\t\t\telemData.events = events = {};\n\t\t}\n\t\teventHandle = elemData.handle;\n\t\tif ( !eventHandle ) {\n\t\t\telemData.handle = eventHandle = function( e ) {\n\t\t\t\t// Discard the second event of a jQuery.event.trigger() and\n\t\t\t\t// when an event is called after a page has unloaded\n\t\t\t\treturn typeof jQuery !== \"undefined\" && (!e || jQuery.event.triggered !== e.type) ?\n\t\t\t\t\tjQuery.event.dispatch.apply( eventHandle.elem, arguments ) :\n\t\t\t\t\tundefined;\n\t\t\t};\n\t\t\t// Add elem as a property of the handle fn to prevent a memory leak with IE non-native events\n\t\t\teventHandle.elem = elem;\n\t\t}\n\n\t\t// Handle multiple events separated by a space\n\t\t// jQuery(...).bind(\"mouseover mouseout\", fn);\n\t\ttypes = jQuery.trim( hoverHack(types) ).split( \" \" );\n\t\tfor ( t = 0; t < types.length; t++ ) {\n\n\t\t\ttns = rtypenamespace.exec( types[t] ) || [];\n\t\t\ttype = tns[1];\n\t\t\tnamespaces = ( tns[2] || \"\" ).split( \".\" ).sort();\n\n\t\t\t// If event changes its type, use the special event handlers for the changed type\n\t\t\tspecial = jQuery.event.special[ type ] || {};\n\n\t\t\t// If selector defined, determine special event api type, otherwise given type\n\t\t\ttype = ( selector ? special.delegateType : special.bindType ) || type;\n\n\t\t\t// Update special based on newly reset type\n\t\t\tspecial = jQuery.event.special[ type ] || {};\n\n\t\t\t// handleObj is passed to all event handlers\n\t\t\thandleObj = jQuery.extend({\n\t\t\t\ttype: type,\n\t\t\t\torigType: tns[1],\n\t\t\t\tdata: data,\n\t\t\t\thandler: handler,\n\t\t\t\tguid: handler.guid,\n\t\t\t\tselector: selector,\n\t\t\t\tneedsContext: selector && jQuery.expr.match.needsContext.test( selector ),\n\t\t\t\tnamespace: namespaces.join(\".\")\n\t\t\t}, handleObjIn );\n\n\t\t\t// Init the event handler queue if we're the first\n\t\t\thandlers = events[ type ];\n\t\t\tif ( !handlers ) {\n\t\t\t\thandlers = events[ type ] = [];\n\t\t\t\thandlers.delegateCount = 0;\n\n\t\t\t\t// Only use addEventListener/attachEvent if the special events handler returns false\n\t\t\t\tif ( !special.setup || special.setup.call( elem, data, namespaces, eventHandle ) === false ) {\n\t\t\t\t\t// Bind the global event handler to the element\n\t\t\t\t\tif ( elem.addEventListener ) {\n\t\t\t\t\t\telem.addEventListener( type, eventHandle, false );\n\n\t\t\t\t\t} else if ( elem.attachEvent ) {\n\t\t\t\t\t\telem.attachEvent( \"on\" + type, eventHandle );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif ( special.add ) {\n\t\t\t\tspecial.add.call( elem, handleObj );\n\n\t\t\t\tif ( !handleObj.handler.guid ) {\n\t\t\t\t\thandleObj.handler.guid = handler.guid;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Add to the element's handler list, delegates in front\n\t\t\tif ( selector ) {\n\t\t\t\thandlers.splice( handlers.delegateCount++, 0, handleObj );\n\t\t\t} else {\n\t\t\t\thandlers.push( handleObj );\n\t\t\t}\n\n\t\t\t// Keep track of which events have ever been used, for event optimization\n\t\t\tjQuery.event.global[ type ] = true;\n\t\t}\n\n\t\t// Nullify elem to prevent memory leaks in IE\n\t\telem = null;\n\t},\n\n\tglobal: {},\n\n\t// Detach an event or set of events from an element\n\tremove: function( elem, types, handler, selector, mappedTypes ) {\n\n\t\tvar t, tns, type, origType, namespaces, origCount,\n\t\t\tj, events, special, eventType, handleObj,\n\t\t\telemData = jQuery.hasData( elem ) && jQuery._data( elem );\n\n\t\tif ( !elemData || !(events = elemData.events) ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Once for each type.namespace in types; type may be omitted\n\t\ttypes = jQuery.trim( hoverHack( types || \"\" ) ).split(\" \");\n\t\tfor ( t = 0; t < types.length; t++ ) {\n\t\t\ttns = rtypenamespace.exec( types[t] ) || [];\n\t\t\ttype = origType = tns[1];\n\t\t\tnamespaces = tns[2];\n\n\t\t\t// Unbind all events (on this namespace, if provided) for the element\n\t\t\tif ( !type ) {\n\t\t\t\tfor ( type in events ) {\n\t\t\t\t\tjQuery.event.remove( elem, type + types[ t ], handler, selector, true );\n\t\t\t\t}\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tspecial = jQuery.event.special[ type ] || {};\n\t\t\ttype = ( selector? special.delegateType : special.bindType ) || type;\n\t\t\teventType = events[ type ] || [];\n\t\t\torigCount = eventType.length;\n\t\t\tnamespaces = namespaces ? new RegExp(\"(^|\\\\.)\" + namespaces.split(\".\").sort().join(\"\\\\.(?:.*\\\\.|)\") + \"(\\\\.|$)\") : null;\n\n\t\t\t// Remove matching events\n\t\t\tfor ( j = 0; j < eventType.length; j++ ) {\n\t\t\t\thandleObj = eventType[ j ];\n\n\t\t\t\tif ( ( mappedTypes || origType === handleObj.origType ) &&\n\t\t\t\t\t ( !handler || handler.guid === handleObj.guid ) &&\n\t\t\t\t\t ( !namespaces || namespaces.test( handleObj.namespace ) ) &&\n\t\t\t\t\t ( !selector || selector === handleObj.selector || selector === \"**\" && handleObj.selector ) ) {\n\t\t\t\t\teventType.splice( j--, 1 );\n\n\t\t\t\t\tif ( handleObj.selector ) {\n\t\t\t\t\t\teventType.delegateCount--;\n\t\t\t\t\t}\n\t\t\t\t\tif ( special.remove ) {\n\t\t\t\t\t\tspecial.remove.call( elem, handleObj );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Remove generic event handler if we removed something and no more handlers exist\n\t\t\t// (avoids potential for endless recursion during removal of special event handlers)\n\t\t\tif ( eventType.length === 0 && origCount !== eventType.length ) {\n\t\t\t\tif ( !special.teardown || special.teardown.call( elem, namespaces, elemData.handle ) === false ) {\n\t\t\t\t\tjQuery.removeEvent( elem, type, elemData.handle );\n\t\t\t\t}\n\n\t\t\t\tdelete events[ type ];\n\t\t\t}\n\t\t}\n\n\t\t// Remove the expando if it's no longer used\n\t\tif ( jQuery.isEmptyObject( events ) ) {\n\t\t\tdelete elemData.handle;\n\n\t\t\t// removeData also checks for emptiness and clears the expando if empty\n\t\t\t// so use it instead of delete\n\t\t\tjQuery.removeData( elem, \"events\", true );\n\t\t}\n\t},\n\n\t// Events that are safe to short-circuit if no handlers are attached.\n\t// Native DOM events should not be added, they may have inline handlers.\n\tcustomEvent: {\n\t\t\"getData\": true,\n\t\t\"setData\": true,\n\t\t\"changeData\": true\n\t},\n\n\ttrigger: function( event, data, elem, onlyHandlers ) {\n\t\t// Don't do events on text and comment nodes\n\t\tif ( elem && (elem.nodeType === 3 || elem.nodeType === 8) ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Event object or event type\n\t\tvar cache, exclusive, i, cur, old, ontype, special, handle, eventPath, bubbleType,\n\t\t\ttype = event.type || event,\n\t\t\tnamespaces = [];\n\n\t\t// focus/blur morphs to focusin/out; ensure we're not firing them right now\n\t\tif ( rfocusMorph.test( type + jQuery.event.triggered ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\tif ( type.indexOf( \"!\" ) >= 0 ) {\n\t\t\t// Exclusive events trigger only for the exact event (no namespaces)\n\t\t\ttype = type.slice(0, -1);\n\t\t\texclusive = true;\n\t\t}\n\n\t\tif ( type.indexOf( \".\" ) >= 0 ) {\n\t\t\t// Namespaced trigger; create a regexp to match event type in handle()\n\t\t\tnamespaces = type.split(\".\");\n\t\t\ttype = namespaces.shift();\n\t\t\tnamespaces.sort();\n\t\t}\n\n\t\tif ( (!elem || jQuery.event.customEvent[ type ]) && !jQuery.event.global[ type ] ) {\n\t\t\t// No jQuery handlers for this event type, and it can't have inline handlers\n\t\t\treturn;\n\t\t}\n\n\t\t// Caller can pass in an Event, Object, or just an event type string\n\t\tevent = typeof event === \"object\" ?\n\t\t\t// jQuery.Event object\n\t\t\tevent[ jQuery.expando ] ? event :\n\t\t\t// Object literal\n\t\t\tnew jQuery.Event( type, event ) :\n\t\t\t// Just the event type (string)\n\t\t\tnew jQuery.Event( type );\n\n\t\tevent.type = type;\n\t\tevent.isTrigger = true;\n\t\tevent.exclusive = exclusive;\n\t\tevent.namespace = namespaces.join( \".\" );\n\t\tevent.namespace_re = event.namespace? new RegExp(\"(^|\\\\.)\" + namespaces.join(\"\\\\.(?:.*\\\\.|)\") + \"(\\\\.|$)\") : null;\n\t\tontype = type.indexOf( \":\" ) < 0 ? \"on\" + type : \"\";\n\n\t\t// Handle a global trigger\n\t\tif ( !elem ) {\n\n\t\t\t// TODO: Stop taunting the data cache; remove global events and always attach to document\n\t\t\tcache = jQuery.cache;\n\t\t\tfor ( i in cache ) {\n\t\t\t\tif ( cache[ i ].events && cache[ i ].events[ type ] ) {\n\t\t\t\t\tjQuery.event.trigger( event, data, cache[ i ].handle.elem, true );\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn;\n\t\t}\n\n\t\t// Clean up the event in case it is being reused\n\t\tevent.result = undefined;\n\t\tif ( !event.target ) {\n\t\t\tevent.target = elem;\n\t\t}\n\n\t\t// Clone any incoming data and prepend the event, creating the handler arg list\n\t\tdata = data != null ? jQuery.makeArray( data ) : [];\n\t\tdata.unshift( event );\n\n\t\t// Allow special events to draw outside the lines\n\t\tspecial = jQuery.event.special[ type ] || {};\n\t\tif ( special.trigger && special.trigger.apply( elem, data ) === false ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Determine event propagation path in advance, per W3C events spec (#9951)\n\t\t// Bubble up to document, then to window; watch for a global ownerDocument var (#9724)\n\t\teventPath = [[ elem, special.bindType || type ]];\n\t\tif ( !onlyHandlers && !special.noBubble && !jQuery.isWindow( elem ) ) {\n\n\t\t\tbubbleType = special.delegateType || type;\n\t\t\tcur = rfocusMorph.test( bubbleType + type ) ? elem : elem.parentNode;\n\t\t\tfor ( old = elem; cur; cur = cur.parentNode ) {\n\t\t\t\teventPath.push([ cur, bubbleType ]);\n\t\t\t\told = cur;\n\t\t\t}\n\n\t\t\t// Only add window if we got to document (e.g., not plain obj or detached DOM)\n\t\t\tif ( old === (elem.ownerDocument || document) ) {\n\t\t\t\teventPath.push([ old.defaultView || old.parentWindow || window, bubbleType ]);\n\t\t\t}\n\t\t}\n\n\t\t// Fire handlers on the event path\n\t\tfor ( i = 0; i < eventPath.length && !event.isPropagationStopped(); i++ ) {\n\n\t\t\tcur = eventPath[i][0];\n\t\t\tevent.type = eventPath[i][1];\n\n\t\t\thandle = ( jQuery._data( cur, \"events\" ) || {} )[ event.type ] && jQuery._data( cur, \"handle\" );\n\t\t\tif ( handle ) {\n\t\t\t\thandle.apply( cur, data );\n\t\t\t}\n\t\t\t// Note that this is a bare JS function and not a jQuery handler\n\t\t\thandle = ontype && cur[ ontype ];\n\t\t\tif ( handle && jQuery.acceptData( cur ) && handle.apply && handle.apply( cur, data ) === false ) {\n\t\t\t\tevent.preventDefault();\n\t\t\t}\n\t\t}\n\t\tevent.type = type;\n\n\t\t// If nobody prevented the default action, do it now\n\t\tif ( !onlyHandlers && !event.isDefaultPrevented() ) {\n\n\t\t\tif ( (!special._default || special._default.apply( elem.ownerDocument, data ) === false) &&\n\t\t\t\t!(type === \"click\" && jQuery.nodeName( elem, \"a\" )) && jQuery.acceptData( elem ) ) {\n\n\t\t\t\t// Call a native DOM method on the target with the same name name as the event.\n\t\t\t\t// Can't use an .isFunction() check here because IE6/7 fails that test.\n\t\t\t\t// Don't do default actions on window, that's where global variables be (#6170)\n\t\t\t\t// IE<9 dies on focus/blur to hidden element (#1486)\n\t\t\t\tif ( ontype && elem[ type ] && ((type !== \"focus\" && type !== \"blur\") || event.target.offsetWidth !== 0) && !jQuery.isWindow( elem ) ) {\n\n\t\t\t\t\t// Don't re-trigger an onFOO event when we call its FOO() method\n\t\t\t\t\told = elem[ ontype ];\n\n\t\t\t\t\tif ( old ) {\n\t\t\t\t\t\telem[ ontype ] = null;\n\t\t\t\t\t}\n\n\t\t\t\t\t// Prevent re-triggering of the same event, since we already bubbled it above\n\t\t\t\t\tjQuery.event.triggered = type;\n\t\t\t\t\telem[ type ]();\n\t\t\t\t\tjQuery.event.triggered = undefined;\n\n\t\t\t\t\tif ( old ) {\n\t\t\t\t\t\telem[ ontype ] = old;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn event.result;\n\t},\n\n\tdispatch: function( event ) {\n\n\t\t// Make a writable jQuery.Event from the native event object\n\t\tevent = jQuery.event.fix( event || window.event );\n\n\t\tvar i, j, cur, ret, selMatch, matched, matches, handleObj, sel, related,\n\t\t\thandlers = ( (jQuery._data( this, \"events\" ) || {} )[ event.type ] || []),\n\t\t\tdelegateCount = handlers.delegateCount,\n\t\t\targs = core_slice.call( arguments ),\n\t\t\trun_all = !event.exclusive && !event.namespace,\n\t\t\tspecial = jQuery.event.special[ event.type ] || {},\n\t\t\thandlerQueue = [];\n\n\t\t// Use the fix-ed jQuery.Event rather than the (read-only) native event\n\t\targs[0] = event;\n\t\tevent.delegateTarget = this;\n\n\t\t// Call the preDispatch hook for the mapped type, and let it bail if desired\n\t\tif ( special.preDispatch && special.preDispatch.call( this, event ) === false ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Determine handlers that should run if there are delegated events\n\t\t// Avoid non-left-click bubbling in Firefox (#3861)\n\t\tif ( delegateCount && !(event.button && event.type === \"click\") ) {\n\n\t\t\tfor ( cur = event.target; cur != this; cur = cur.parentNode || this ) {\n\n\t\t\t\t// Don't process clicks (ONLY) on disabled elements (#6911, #8165, #11382, #11764)\n\t\t\t\tif ( cur.disabled !== true || event.type !== \"click\" ) {\n\t\t\t\t\tselMatch = {};\n\t\t\t\t\tmatches = [];\n\t\t\t\t\tfor ( i = 0; i < delegateCount; i++ ) {\n\t\t\t\t\t\thandleObj = handlers[ i ];\n\t\t\t\t\t\tsel = handleObj.selector;\n\n\t\t\t\t\t\tif ( selMatch[ sel ] === undefined ) {\n\t\t\t\t\t\t\tselMatch[ sel ] = handleObj.needsContext ?\n\t\t\t\t\t\t\t\tjQuery( sel, this ).index( cur ) >= 0 :\n\t\t\t\t\t\t\t\tjQuery.find( sel, this, null, [ cur ] ).length;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif ( selMatch[ sel ] ) {\n\t\t\t\t\t\t\tmatches.push( handleObj );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tif ( matches.length ) {\n\t\t\t\t\t\thandlerQueue.push({ elem: cur, matches: matches });\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Add the remaining (directly-bound) handlers\n\t\tif ( handlers.length > delegateCount ) {\n\t\t\thandlerQueue.push({ elem: this, matches: handlers.slice( delegateCount ) });\n\t\t}\n\n\t\t// Run delegates first; they may want to stop propagation beneath us\n\t\tfor ( i = 0; i < handlerQueue.length && !event.isPropagationStopped(); i++ ) {\n\t\t\tmatched = handlerQueue[ i ];\n\t\t\tevent.currentTarget = matched.elem;\n\n\t\t\tfor ( j = 0; j < matched.matches.length && !event.isImmediatePropagationStopped(); j++ ) {\n\t\t\t\thandleObj = matched.matches[ j ];\n\n\t\t\t\t// Triggered event must either 1) be non-exclusive and have no namespace, or\n\t\t\t\t// 2) have namespace(s) a subset or equal to those in the bound event (both can have no namespace).\n\t\t\t\tif ( run_all || (!event.namespace && !handleObj.namespace) || event.namespace_re && event.namespace_re.test( handleObj.namespace ) ) {\n\n\t\t\t\t\tevent.data = handleObj.data;\n\t\t\t\t\tevent.handleObj = handleObj;\n\n\t\t\t\t\tret = ( (jQuery.event.special[ handleObj.origType ] || {}).handle || handleObj.handler )\n\t\t\t\t\t\t\t.apply( matched.elem, args );\n\n\t\t\t\t\tif ( ret !== undefined ) {\n\t\t\t\t\t\tevent.result = ret;\n\t\t\t\t\t\tif ( ret === false ) {\n\t\t\t\t\t\t\tevent.preventDefault();\n\t\t\t\t\t\t\tevent.stopPropagation();\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Call the postDispatch hook for the mapped type\n\t\tif ( special.postDispatch ) {\n\t\t\tspecial.postDispatch.call( this, event );\n\t\t}\n\n\t\treturn event.result;\n\t},\n\n\t// Includes some event props shared by KeyEvent and MouseEvent\n\t// *** attrChange attrName relatedNode srcElement  are not normalized, non-W3C, deprecated, will be removed in 1.8 ***\n\tprops: \"attrChange attrName relatedNode srcElement altKey bubbles cancelable ctrlKey currentTarget eventPhase metaKey relatedTarget shiftKey target timeStamp view which\".split(\" \"),\n\n\tfixHooks: {},\n\n\tkeyHooks: {\n\t\tprops: \"char charCode key keyCode\".split(\" \"),\n\t\tfilter: function( event, original ) {\n\n\t\t\t// Add which for key events\n\t\t\tif ( event.which == null ) {\n\t\t\t\tevent.which = original.charCode != null ? original.charCode : original.keyCode;\n\t\t\t}\n\n\t\t\treturn event;\n\t\t}\n\t},\n\n\tmouseHooks: {\n\t\tprops: \"button buttons clientX clientY fromElement offsetX offsetY pageX pageY screenX screenY toElement\".split(\" \"),\n\t\tfilter: function( event, original ) {\n\t\t\tvar eventDoc, doc, body,\n\t\t\t\tbutton = original.button,\n\t\t\t\tfromElement = original.fromElement;\n\n\t\t\t// Calculate pageX/Y if missing and clientX/Y available\n\t\t\tif ( event.pageX == null && original.clientX != null ) {\n\t\t\t\teventDoc = event.target.ownerDocument || document;\n\t\t\t\tdoc = eventDoc.documentElement;\n\t\t\t\tbody = eventDoc.body;\n\n\t\t\t\tevent.pageX = original.clientX + ( doc && doc.scrollLeft || body && body.scrollLeft || 0 ) - ( doc && doc.clientLeft || body && body.clientLeft || 0 );\n\t\t\t\tevent.pageY = original.clientY + ( doc && doc.scrollTop  || body && body.scrollTop  || 0 ) - ( doc && doc.clientTop  || body && body.clientTop  || 0 );\n\t\t\t}\n\n\t\t\t// Add relatedTarget, if necessary\n\t\t\tif ( !event.relatedTarget && fromElement ) {\n\t\t\t\tevent.relatedTarget = fromElement === event.target ? original.toElement : fromElement;\n\t\t\t}\n\n\t\t\t// Add which for click: 1 === left; 2 === middle; 3 === right\n\t\t\t// Note: button is not normalized, so don't use it\n\t\t\tif ( !event.which && button !== undefined ) {\n\t\t\t\tevent.which = ( button & 1 ? 1 : ( button & 2 ? 3 : ( button & 4 ? 2 : 0 ) ) );\n\t\t\t}\n\n\t\t\treturn event;\n\t\t}\n\t},\n\n\tfix: function( event ) {\n\t\tif ( event[ jQuery.expando ] ) {\n\t\t\treturn event;\n\t\t}\n\n\t\t// Create a writable copy of the event object and normalize some properties\n\t\tvar i, prop,\n\t\t\toriginalEvent = event,\n\t\t\tfixHook = jQuery.event.fixHooks[ event.type ] || {},\n\t\t\tcopy = fixHook.props ? this.props.concat( fixHook.props ) : this.props;\n\n\t\tevent = jQuery.Event( originalEvent );\n\n\t\tfor ( i = copy.length; i; ) {\n\t\t\tprop = copy[ --i ];\n\t\t\tevent[ prop ] = originalEvent[ prop ];\n\t\t}\n\n\t\t// Fix target property, if necessary (#1925, IE 6/7/8 & Safari2)\n\t\tif ( !event.target ) {\n\t\t\tevent.target = originalEvent.srcElement || document;\n\t\t}\n\n\t\t// Target should not be a text node (#504, Safari)\n\t\tif ( event.target.nodeType === 3 ) {\n\t\t\tevent.target = event.target.parentNode;\n\t\t}\n\n\t\t// For mouse/key events, metaKey==false if it's undefined (#3368, #11328; IE6/7/8)\n\t\tevent.metaKey = !!event.metaKey;\n\n\t\treturn fixHook.filter? fixHook.filter( event, originalEvent ) : event;\n\t},\n\n\tspecial: {\n\t\tload: {\n\t\t\t// Prevent triggered image.load events from bubbling to window.load\n\t\t\tnoBubble: true\n\t\t},\n\n\t\tfocus: {\n\t\t\tdelegateType: \"focusin\"\n\t\t},\n\t\tblur: {\n\t\t\tdelegateType: \"focusout\"\n\t\t},\n\n\t\tbeforeunload: {\n\t\t\tsetup: function( data, namespaces, eventHandle ) {\n\t\t\t\t// We only want to do this special case on windows\n\t\t\t\tif ( jQuery.isWindow( this ) ) {\n\t\t\t\t\tthis.onbeforeunload = eventHandle;\n\t\t\t\t}\n\t\t\t},\n\n\t\t\tteardown: function( namespaces, eventHandle ) {\n\t\t\t\tif ( this.onbeforeunload === eventHandle ) {\n\t\t\t\t\tthis.onbeforeunload = null;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t},\n\n\tsimulate: function( type, elem, event, bubble ) {\n\t\t// Piggyback on a donor event to simulate a different one.\n\t\t// Fake originalEvent to avoid donor's stopPropagation, but if the\n\t\t// simulated event prevents default then we do the same on the donor.\n\t\tvar e = jQuery.extend(\n\t\t\tnew jQuery.Event(),\n\t\t\tevent,\n\t\t\t{ type: type,\n\t\t\t\tisSimulated: true,\n\t\t\t\toriginalEvent: {}\n\t\t\t}\n\t\t);\n\t\tif ( bubble ) {\n\t\t\tjQuery.event.trigger( e, null, elem );\n\t\t} else {\n\t\t\tjQuery.event.dispatch.call( elem, e );\n\t\t}\n\t\tif ( e.isDefaultPrevented() ) {\n\t\t\tevent.preventDefault();\n\t\t}\n\t}\n};\n\n// Some plugins are using, but it's undocumented/deprecated and will be removed.\n// The 1.7 special event interface should provide all the hooks needed now.\njQuery.event.handle = jQuery.event.dispatch;\n\njQuery.removeEvent = document.removeEventListener ?\n\tfunction( elem, type, handle ) {\n\t\tif ( elem.removeEventListener ) {\n\t\t\telem.removeEventListener( type, handle, false );\n\t\t}\n\t} :\n\tfunction( elem, type, handle ) {\n\t\tvar name = \"on\" + type;\n\n\t\tif ( elem.detachEvent ) {\n\n\t\t\t// #8545, #7054, preventing memory leaks for custom events in IE6-8\n\t\t\t// detachEvent needed property on element, by name of that event, to properly expose it to GC\n\t\t\tif ( typeof elem[ name ] === \"undefined\" ) {\n\t\t\t\telem[ name ] = null;\n\t\t\t}\n\n\t\t\telem.detachEvent( name, handle );\n\t\t}\n\t};\n\njQuery.Event = function( src, props ) {\n\t// Allow instantiation without the 'new' keyword\n\tif ( !(this instanceof jQuery.Event) ) {\n\t\treturn new jQuery.Event( src, props );\n\t}\n\n\t// Event object\n\tif ( src && src.type ) {\n\t\tthis.originalEvent = src;\n\t\tthis.type = src.type;\n\n\t\t// Events bubbling up the document may have been marked as prevented\n\t\t// by a handler lower down the tree; reflect the correct value.\n\t\tthis.isDefaultPrevented = ( src.defaultPrevented || src.returnValue === false ||\n\t\t\tsrc.getPreventDefault && src.getPreventDefault() ) ? returnTrue : returnFalse;\n\n\t// Event type\n\t} else {\n\t\tthis.type = src;\n\t}\n\n\t// Put explicitly provided properties onto the event object\n\tif ( props ) {\n\t\tjQuery.extend( this, props );\n\t}\n\n\t// Create a timestamp if incoming event doesn't have one\n\tthis.timeStamp = src && src.timeStamp || jQuery.now();\n\n\t// Mark it as fixed\n\tthis[ jQuery.expando ] = true;\n};\n\nfunction returnFalse() {\n\treturn false;\n}\nfunction returnTrue() {\n\treturn true;\n}\n\n// jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding\n// http://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html\njQuery.Event.prototype = {\n\tpreventDefault: function() {\n\t\tthis.isDefaultPrevented = returnTrue;\n\n\t\tvar e = this.originalEvent;\n\t\tif ( !e ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// if preventDefault exists run it on the original event\n\t\tif ( e.preventDefault ) {\n\t\t\te.preventDefault();\n\n\t\t// otherwise set the returnValue property of the original event to false (IE)\n\t\t} else {\n\t\t\te.returnValue = false;\n\t\t}\n\t},\n\tstopPropagation: function() {\n\t\tthis.isPropagationStopped = returnTrue;\n\n\t\tvar e = this.originalEvent;\n\t\tif ( !e ) {\n\t\t\treturn;\n\t\t}\n\t\t// if stopPropagation exists run it on the original event\n\t\tif ( e.stopPropagation ) {\n\t\t\te.stopPropagation();\n\t\t}\n\t\t// otherwise set the cancelBubble property of the original event to true (IE)\n\t\te.cancelBubble = true;\n\t},\n\tstopImmediatePropagation: function() {\n\t\tthis.isImmediatePropagationStopped = returnTrue;\n\t\tthis.stopPropagation();\n\t},\n\tisDefaultPrevented: returnFalse,\n\tisPropagationStopped: returnFalse,\n\tisImmediatePropagationStopped: returnFalse\n};\n\n// Create mouseenter/leave events using mouseover/out and event-time checks\njQuery.each({\n\tmouseenter: \"mouseover\",\n\tmouseleave: \"mouseout\"\n}, function( orig, fix ) {\n\tjQuery.event.special[ orig ] = {\n\t\tdelegateType: fix,\n\t\tbindType: fix,\n\n\t\thandle: function( event ) {\n\t\t\tvar ret,\n\t\t\t\ttarget = this,\n\t\t\t\trelated = event.relatedTarget,\n\t\t\t\thandleObj = event.handleObj,\n\t\t\t\tselector = handleObj.selector;\n\n\t\t\t// For mousenter/leave call the handler if related is outside the target.\n\t\t\t// NB: No relatedTarget if the mouse left/entered the browser window\n\t\t\tif ( !related || (related !== target && !jQuery.contains( target, related )) ) {\n\t\t\t\tevent.type = handleObj.origType;\n\t\t\t\tret = handleObj.handler.apply( this, arguments );\n\t\t\t\tevent.type = fix;\n\t\t\t}\n\t\t\treturn ret;\n\t\t}\n\t};\n});\n\n// IE submit delegation\nif ( !jQuery.support.submitBubbles ) {\n\n\tjQuery.event.special.submit = {\n\t\tsetup: function() {\n\t\t\t// Only need this for delegated form submit events\n\t\t\tif ( jQuery.nodeName( this, \"form\" ) ) {\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\t// Lazy-add a submit handler when a descendant form may potentially be submitted\n\t\t\tjQuery.event.add( this, \"click._submit keypress._submit\", function( e ) {\n\t\t\t\t// Node name check avoids a VML-related crash in IE (#9807)\n\t\t\t\tvar elem = e.target,\n\t\t\t\t\tform = jQuery.nodeName( elem, \"input\" ) || jQuery.nodeName( elem, \"button\" ) ? elem.form : undefined;\n\t\t\t\tif ( form && !jQuery._data( form, \"_submit_attached\" ) ) {\n\t\t\t\t\tjQuery.event.add( form, \"submit._submit\", function( event ) {\n\t\t\t\t\t\tevent._submit_bubble = true;\n\t\t\t\t\t});\n\t\t\t\t\tjQuery._data( form, \"_submit_attached\", true );\n\t\t\t\t}\n\t\t\t});\n\t\t\t// return undefined since we don't need an event listener\n\t\t},\n\n\t\tpostDispatch: function( event ) {\n\t\t\t// If form was submitted by the user, bubble the event up the tree\n\t\t\tif ( event._submit_bubble ) {\n\t\t\t\tdelete event._submit_bubble;\n\t\t\t\tif ( this.parentNode && !event.isTrigger ) {\n\t\t\t\t\tjQuery.event.simulate( \"submit\", this.parentNode, event, true );\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\n\t\tteardown: function() {\n\t\t\t// Only need this for delegated form submit events\n\t\t\tif ( jQuery.nodeName( this, \"form\" ) ) {\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\t// Remove delegated handlers; cleanData eventually reaps submit handlers attached above\n\t\t\tjQuery.event.remove( this, \"._submit\" );\n\t\t}\n\t};\n}\n\n// IE change delegation and checkbox/radio fix\nif ( !jQuery.support.changeBubbles ) {\n\n\tjQuery.event.special.change = {\n\n\t\tsetup: function() {\n\n\t\t\tif ( rformElems.test( this.nodeName ) ) {\n\t\t\t\t// IE doesn't fire change on a check/radio until blur; trigger it on click\n\t\t\t\t// after a propertychange. Eat the blur-change in special.change.handle.\n\t\t\t\t// This still fires onchange a second time for check/radio after blur.\n\t\t\t\tif ( this.type === \"checkbox\" || this.type === \"radio\" ) {\n\t\t\t\t\tjQuery.event.add( this, \"propertychange._change\", function( event ) {\n\t\t\t\t\t\tif ( event.originalEvent.propertyName === \"checked\" ) {\n\t\t\t\t\t\t\tthis._just_changed = true;\n\t\t\t\t\t\t}\n\t\t\t\t\t});\n\t\t\t\t\tjQuery.event.add( this, \"click._change\", function( event ) {\n\t\t\t\t\t\tif ( this._just_changed && !event.isTrigger ) {\n\t\t\t\t\t\t\tthis._just_changed = false;\n\t\t\t\t\t\t}\n\t\t\t\t\t\t// Allow triggered, simulated change events (#11500)\n\t\t\t\t\t\tjQuery.event.simulate( \"change\", this, event, true );\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\t// Delegated event; lazy-add a change handler on descendant inputs\n\t\t\tjQuery.event.add( this, \"beforeactivate._change\", function( e ) {\n\t\t\t\tvar elem = e.target;\n\n\t\t\t\tif ( rformElems.test( elem.nodeName ) && !jQuery._data( elem, \"_change_attached\" ) ) {\n\t\t\t\t\tjQuery.event.add( elem, \"change._change\", function( event ) {\n\t\t\t\t\t\tif ( this.parentNode && !event.isSimulated && !event.isTrigger ) {\n\t\t\t\t\t\t\tjQuery.event.simulate( \"change\", this.parentNode, event, true );\n\t\t\t\t\t\t}\n\t\t\t\t\t});\n\t\t\t\t\tjQuery._data( elem, \"_change_attached\", true );\n\t\t\t\t}\n\t\t\t});\n\t\t},\n\n\t\thandle: function( event ) {\n\t\t\tvar elem = event.target;\n\n\t\t\t// Swallow native change events from checkbox/radio, we already triggered them above\n\t\t\tif ( this !== elem || event.isSimulated || event.isTrigger || (elem.type !== \"radio\" && elem.type !== \"checkbox\") ) {\n\t\t\t\treturn event.handleObj.handler.apply( this, arguments );\n\t\t\t}\n\t\t},\n\n\t\tteardown: function() {\n\t\t\tjQuery.event.remove( this, \"._change\" );\n\n\t\t\treturn !rformElems.test( this.nodeName );\n\t\t}\n\t};\n}\n\n// Create \"bubbling\" focus and blur events\nif ( !jQuery.support.focusinBubbles ) {\n\tjQuery.each({ focus: \"focusin\", blur: \"focusout\" }, function( orig, fix ) {\n\n\t\t// Attach a single capturing handler while someone wants focusin/focusout\n\t\tvar attaches = 0,\n\t\t\thandler = function( event ) {\n\t\t\t\tjQuery.event.simulate( fix, event.target, jQuery.event.fix( event ), true );\n\t\t\t};\n\n\t\tjQuery.event.special[ fix ] = {\n\t\t\tsetup: function() {\n\t\t\t\tif ( attaches++ === 0 ) {\n\t\t\t\t\tdocument.addEventListener( orig, handler, true );\n\t\t\t\t}\n\t\t\t},\n\t\t\tteardown: function() {\n\t\t\t\tif ( --attaches === 0 ) {\n\t\t\t\t\tdocument.removeEventListener( orig, handler, true );\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\t});\n}\n\njQuery.fn.extend({\n\n\ton: function( types, selector, data, fn, /*INTERNAL*/ one ) {\n\t\tvar origFn, type;\n\n\t\t// Types can be a map of types/handlers\n\t\tif ( typeof types === \"object\" ) {\n\t\t\t// ( types-Object, selector, data )\n\t\t\tif ( typeof selector !== \"string\" ) { // && selector != null\n\t\t\t\t// ( types-Object, data )\n\t\t\t\tdata = data || selector;\n\t\t\t\tselector = undefined;\n\t\t\t}\n\t\t\tfor ( type in types ) {\n\t\t\t\tthis.on( type, selector, data, types[ type ], one );\n\t\t\t}\n\t\t\treturn this;\n\t\t}\n\n\t\tif ( data == null && fn == null ) {\n\t\t\t// ( types, fn )\n\t\t\tfn = selector;\n\t\t\tdata = selector = undefined;\n\t\t} else if ( fn == null ) {\n\t\t\tif ( typeof selector === \"string\" ) {\n\t\t\t\t// ( types, selector, fn )\n\t\t\t\tfn = data;\n\t\t\t\tdata = undefined;\n\t\t\t} else {\n\t\t\t\t// ( types, data, fn )\n\t\t\t\tfn = data;\n\t\t\t\tdata = selector;\n\t\t\t\tselector = undefined;\n\t\t\t}\n\t\t}\n\t\tif ( fn === false ) {\n\t\t\tfn = returnFalse;\n\t\t} else if ( !fn ) {\n\t\t\treturn this;\n\t\t}\n\n\t\tif ( one === 1 ) {\n\t\t\torigFn = fn;\n\t\t\tfn = function( event ) {\n\t\t\t\t// Can use an empty set, since event contains the info\n\t\t\t\tjQuery().off( event );\n\t\t\t\treturn origFn.apply( this, arguments );\n\t\t\t};\n\t\t\t// Use same guid so caller can remove using origFn\n\t\t\tfn.guid = origFn.guid || ( origFn.guid = jQuery.guid++ );\n\t\t}\n\t\treturn this.each( function() {\n\t\t\tjQuery.event.add( this, types, fn, data, selector );\n\t\t});\n\t},\n\tone: function( types, selector, data, fn ) {\n\t\treturn this.on( types, selector, data, fn, 1 );\n\t},\n\toff: function( types, selector, fn ) {\n\t\tvar handleObj, type;\n\t\tif ( types && types.preventDefault && types.handleObj ) {\n\t\t\t// ( event )  dispatched jQuery.Event\n\t\t\thandleObj = types.handleObj;\n\t\t\tjQuery( types.delegateTarget ).off(\n\t\t\t\thandleObj.namespace ? handleObj.origType + \".\" + handleObj.namespace : handleObj.origType,\n\t\t\t\thandleObj.selector,\n\t\t\t\thandleObj.handler\n\t\t\t);\n\t\t\treturn this;\n\t\t}\n\t\tif ( typeof types === \"object\" ) {\n\t\t\t// ( types-object [, selector] )\n\t\t\tfor ( type in types ) {\n\t\t\t\tthis.off( type, selector, types[ type ] );\n\t\t\t}\n\t\t\treturn this;\n\t\t}\n\t\tif ( selector === false || typeof selector === \"function\" ) {\n\t\t\t// ( types [, fn] )\n\t\t\tfn = selector;\n\t\t\tselector = undefined;\n\t\t}\n\t\tif ( fn === false ) {\n\t\t\tfn = returnFalse;\n\t\t}\n\t\treturn this.each(function() {\n\t\t\tjQuery.event.remove( this, types, fn, selector );\n\t\t});\n\t},\n\n\tbind: function( types, data, fn ) {\n\t\treturn this.on( types, null, data, fn );\n\t},\n\tunbind: function( types, fn ) {\n\t\treturn this.off( types, null, fn );\n\t},\n\n\tlive: function( types, data, fn ) {\n\t\tjQuery( this.context ).on( types, this.selector, data, fn );\n\t\treturn this;\n\t},\n\tdie: function( types, fn ) {\n\t\tjQuery( this.context ).off( types, this.selector || \"**\", fn );\n\t\treturn this;\n\t},\n\n\tdelegate: function( selector, types, data, fn ) {\n\t\treturn this.on( types, selector, data, fn );\n\t},\n\tundelegate: function( selector, types, fn ) {\n\t\t// ( namespace ) or ( selector, types [, fn] )\n\t\treturn arguments.length === 1 ? this.off( selector, \"**\" ) : this.off( types, selector || \"**\", fn );\n\t},\n\n\ttrigger: function( type, data ) {\n\t\treturn this.each(function() {\n\t\t\tjQuery.event.trigger( type, data, this );\n\t\t});\n\t},\n\ttriggerHandler: function( type, data ) {\n\t\tif ( this[0] ) {\n\t\t\treturn jQuery.event.trigger( type, data, this[0], true );\n\t\t}\n\t},\n\n\ttoggle: function( fn ) {\n\t\t// Save reference to arguments for access in closure\n\t\tvar args = arguments,\n\t\t\tguid = fn.guid || jQuery.guid++,\n\t\t\ti = 0,\n\t\t\ttoggler = function( event ) {\n\t\t\t\t// Figure out which function to execute\n\t\t\t\tvar lastToggle = ( jQuery._data( this, \"lastToggle\" + fn.guid ) || 0 ) % i;\n\t\t\t\tjQuery._data( this, \"lastToggle\" + fn.guid, lastToggle + 1 );\n\n\t\t\t\t// Make sure that clicks stop\n\t\t\t\tevent.preventDefault();\n\n\t\t\t\t// and execute the function\n\t\t\t\treturn args[ lastToggle ].apply( this, arguments ) || false;\n\t\t\t};\n\n\t\t// link all the functions, so any of them can unbind this click handler\n\t\ttoggler.guid = guid;\n\t\twhile ( i < args.length ) {\n\t\t\targs[ i++ ].guid = guid;\n\t\t}\n\n\t\treturn this.click( toggler );\n\t},\n\n\thover: function( fnOver, fnOut ) {\n\t\treturn this.mouseenter( fnOver ).mouseleave( fnOut || fnOver );\n\t}\n});\n\njQuery.each( (\"blur focus focusin focusout load resize scroll unload click dblclick \" +\n\t\"mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave \" +\n\t\"change select submit keydown keypress keyup error contextmenu\").split(\" \"), function( i, name ) {\n\n\t// Handle event binding\n\tjQuery.fn[ name ] = function( data, fn ) {\n\t\tif ( fn == null ) {\n\t\t\tfn = data;\n\t\t\tdata = null;\n\t\t}\n\n\t\treturn arguments.length > 0 ?\n\t\t\tthis.on( name, null, data, fn ) :\n\t\t\tthis.trigger( name );\n\t};\n\n\tif ( rkeyEvent.test( name ) ) {\n\t\tjQuery.event.fixHooks[ name ] = jQuery.event.keyHooks;\n\t}\n\n\tif ( rmouseEvent.test( name ) ) {\n\t\tjQuery.event.fixHooks[ name ] = jQuery.event.mouseHooks;\n\t}\n});\n/*!\n * Sizzle CSS Selector Engine\n * Copyright 2012 jQuery Foundation and other contributors\n * Released under the MIT license\n * http://sizzlejs.com/\n */\n(function( window, undefined ) {\n\nvar cachedruns,\n\tassertGetIdNotName,\n\tExpr,\n\tgetText,\n\tisXML,\n\tcontains,\n\tcompile,\n\tsortOrder,\n\thasDuplicate,\n\toutermostContext,\n\n\tbaseHasDuplicate = true,\n\tstrundefined = \"undefined\",\n\n\texpando = ( \"sizcache\" + Math.random() ).replace( \".\", \"\" ),\n\n\tToken = String,\n\tdocument = window.document,\n\tdocElem = document.documentElement,\n\tdirruns = 0,\n\tdone = 0,\n\tpop = [].pop,\n\tpush = [].push,\n\tslice = [].slice,\n\t// Use a stripped-down indexOf if a native one is unavailable\n\tindexOf = [].indexOf || function( elem ) {\n\t\tvar i = 0,\n\t\t\tlen = this.length;\n\t\tfor ( ; i < len; i++ ) {\n\t\t\tif ( this[i] === elem ) {\n\t\t\t\treturn i;\n\t\t\t}\n\t\t}\n\t\treturn -1;\n\t},\n\n\t// Augment a function for special use by Sizzle\n\tmarkFunction = function( fn, value ) {\n\t\tfn[ expando ] = value == null || value;\n\t\treturn fn;\n\t},\n\n\tcreateCache = function() {\n\t\tvar cache = {},\n\t\t\tkeys = [];\n\n\t\treturn markFunction(function( key, value ) {\n\t\t\t// Only keep the most recent entries\n\t\t\tif ( keys.push( key ) > Expr.cacheLength ) {\n\t\t\t\tdelete cache[ keys.shift() ];\n\t\t\t}\n\n\t\t\t// Retrieve with (key + \" \") to avoid collision with native Object.prototype properties (see Issue #157)\n\t\t\treturn (cache[ key + \" \" ] = value);\n\t\t}, cache );\n\t},\n\n\tclassCache = createCache(),\n\ttokenCache = createCache(),\n\tcompilerCache = createCache(),\n\n\t// Regex\n\n\t// Whitespace characters http://www.w3.org/TR/css3-selectors/#whitespace\n\twhitespace = \"[\\\\x20\\\\t\\\\r\\\\n\\\\f]\",\n\t// http://www.w3.org/TR/css3-syntax/#characters\n\tcharacterEncoding = \"(?:\\\\\\\\.|[-\\\\w]|[^\\\\x00-\\\\xa0])+\",\n\n\t// Loosely modeled on CSS identifier characters\n\t// An unquoted value should be a CSS identifier (http://www.w3.org/TR/css3-selectors/#attribute-selectors)\n\t// Proper syntax: http://www.w3.org/TR/CSS21/syndata.html#value-def-identifier\n\tidentifier = characterEncoding.replace( \"w\", \"w#\" ),\n\n\t// Acceptable operators http://www.w3.org/TR/selectors/#attribute-selectors\n\toperators = \"([*^$|!~]?=)\",\n\tattributes = \"\\\\[\" + whitespace + \"*(\" + characterEncoding + \")\" + whitespace +\n\t\t\"*(?:\" + operators + whitespace + \"*(?:(['\\\"])((?:\\\\\\\\.|[^\\\\\\\\])*?)\\\\3|(\" + identifier + \")|)|)\" + whitespace + \"*\\\\]\",\n\n\t// Prefer arguments not in parens/brackets,\n\t//   then attribute selectors and non-pseudos (denoted by :),\n\t//   then anything else\n\t// These preferences are here to reduce the number of selectors\n\t//   needing tokenize in the PSEUDO preFilter\n\tpseudos = \":(\" + characterEncoding + \")(?:\\\\((?:(['\\\"])((?:\\\\\\\\.|[^\\\\\\\\])*?)\\\\2|([^()[\\\\]]*|(?:(?:\" + attributes + \")|[^:]|\\\\\\\\.)*|.*))\\\\)|)\",\n\n\t// For matchExpr.POS and matchExpr.needsContext\n\tpos = \":(even|odd|eq|gt|lt|nth|first|last)(?:\\\\(\" + whitespace +\n\t\t\"*((?:-\\\\d)?\\\\d*)\" + whitespace + \"*\\\\)|)(?=[^-]|$)\",\n\n\t// Leading and non-escaped trailing whitespace, capturing some non-whitespace characters preceding the latter\n\trtrim = new RegExp( \"^\" + whitespace + \"+|((?:^|[^\\\\\\\\])(?:\\\\\\\\.)*)\" + whitespace + \"+$\", \"g\" ),\n\n\trcomma = new RegExp( \"^\" + whitespace + \"*,\" + whitespace + \"*\" ),\n\trcombinators = new RegExp( \"^\" + whitespace + \"*([\\\\x20\\\\t\\\\r\\\\n\\\\f>+~])\" + whitespace + \"*\" ),\n\trpseudo = new RegExp( pseudos ),\n\n\t// Easily-parseable/retrievable ID or TAG or CLASS selectors\n\trquickExpr = /^(?:#([\\w\\-]+)|(\\w+)|\\.([\\w\\-]+))$/,\n\n\trnot = /^:not/,\n\trsibling = /[\\x20\\t\\r\\n\\f]*[+~]/,\n\trendsWithNot = /:not\\($/,\n\n\trheader = /h\\d/i,\n\trinputs = /input|select|textarea|button/i,\n\n\trbackslash = /\\\\(?!\\\\)/g,\n\n\tmatchExpr = {\n\t\t\"ID\": new RegExp( \"^#(\" + characterEncoding + \")\" ),\n\t\t\"CLASS\": new RegExp( \"^\\\\.(\" + characterEncoding + \")\" ),\n\t\t\"NAME\": new RegExp( \"^\\\\[name=['\\\"]?(\" + characterEncoding + \")['\\\"]?\\\\]\" ),\n\t\t\"TAG\": new RegExp( \"^(\" + characterEncoding.replace( \"w\", \"w*\" ) + \")\" ),\n\t\t\"ATTR\": new RegExp( \"^\" + attributes ),\n\t\t\"PSEUDO\": new RegExp( \"^\" + pseudos ),\n\t\t\"POS\": new RegExp( pos, \"i\" ),\n\t\t\"CHILD\": new RegExp( \"^:(only|nth|first|last)-child(?:\\\\(\" + whitespace +\n\t\t\t\"*(even|odd|(([+-]|)(\\\\d*)n|)\" + whitespace + \"*(?:([+-]|)\" + whitespace +\n\t\t\t\"*(\\\\d+)|))\" + whitespace + \"*\\\\)|)\", \"i\" ),\n\t\t// For use in libraries implementing .is()\n\t\t\"needsContext\": new RegExp( \"^\" + whitespace + \"*[>+~]|\" + pos, \"i\" )\n\t},\n\n\t// Support\n\n\t// Used for testing something on an element\n\tassert = function( fn ) {\n\t\tvar div = document.createElement(\"div\");\n\n\t\ttry {\n\t\t\treturn fn( div );\n\t\t} catch (e) {\n\t\t\treturn false;\n\t\t} finally {\n\t\t\t// release memory in IE\n\t\t\tdiv = null;\n\t\t}\n\t},\n\n\t// Check if getElementsByTagName(\"*\") returns only elements\n\tassertTagNameNoComments = assert(function( div ) {\n\t\tdiv.appendChild( document.createComment(\"\") );\n\t\treturn !div.getElementsByTagName(\"*\").length;\n\t}),\n\n\t// Check if getAttribute returns normalized href attributes\n\tassertHrefNotNormalized = assert(function( div ) {\n\t\tdiv.innerHTML = \"<a href='#'></a>\";\n\t\treturn div.firstChild && typeof div.firstChild.getAttribute !== strundefined &&\n\t\t\tdiv.firstChild.getAttribute(\"href\") === \"#\";\n\t}),\n\n\t// Check if attributes should be retrieved by attribute nodes\n\tassertAttributes = assert(function( div ) {\n\t\tdiv.innerHTML = \"<select></select>\";\n\t\tvar type = typeof div.lastChild.getAttribute(\"multiple\");\n\t\t// IE8 returns a string for some attributes even when not present\n\t\treturn type !== \"boolean\" && type !== \"string\";\n\t}),\n\n\t// Check if getElementsByClassName can be trusted\n\tassertUsableClassName = assert(function( div ) {\n\t\t// Opera can't find a second classname (in 9.6)\n\t\tdiv.innerHTML = \"<div class='hidden e'></div><div class='hidden'></div>\";\n\t\tif ( !div.getElementsByClassName || !div.getElementsByClassName(\"e\").length ) {\n\t\t\treturn false;\n\t\t}\n\n\t\t// Safari 3.2 caches class attributes and doesn't catch changes\n\t\tdiv.lastChild.className = \"e\";\n\t\treturn div.getElementsByClassName(\"e\").length === 2;\n\t}),\n\n\t// Check if getElementById returns elements by name\n\t// Check if getElementsByName privileges form controls or returns elements by ID\n\tassertUsableName = assert(function( div ) {\n\t\t// Inject content\n\t\tdiv.id = expando + 0;\n\t\tdiv.innerHTML = \"<a name='\" + expando + \"'></a><div name='\" + expando + \"'></div>\";\n\t\tdocElem.insertBefore( div, docElem.firstChild );\n\n\t\t// Test\n\t\tvar pass = document.getElementsByName &&\n\t\t\t// buggy browsers will return fewer than the correct 2\n\t\t\tdocument.getElementsByName( expando ).length === 2 +\n\t\t\t// buggy browsers will return more than the correct 0\n\t\t\tdocument.getElementsByName( expando + 0 ).length;\n\t\tassertGetIdNotName = !document.getElementById( expando );\n\n\t\t// Cleanup\n\t\tdocElem.removeChild( div );\n\n\t\treturn pass;\n\t});\n\n// If slice is not available, provide a backup\ntry {\n\tslice.call( docElem.childNodes, 0 )[0].nodeType;\n} catch ( e ) {\n\tslice = function( i ) {\n\t\tvar elem,\n\t\t\tresults = [];\n\t\tfor ( ; (elem = this[i]); i++ ) {\n\t\t\tresults.push( elem );\n\t\t}\n\t\treturn results;\n\t};\n}\n\nfunction Sizzle( selector, context, results, seed ) {\n\tresults = results || [];\n\tcontext = context || document;\n\tvar match, elem, xml, m,\n\t\tnodeType = context.nodeType;\n\n\tif ( !selector || typeof selector !== \"string\" ) {\n\t\treturn results;\n\t}\n\n\tif ( nodeType !== 1 && nodeType !== 9 ) {\n\t\treturn [];\n\t}\n\n\txml = isXML( context );\n\n\tif ( !xml && !seed ) {\n\t\tif ( (match = rquickExpr.exec( selector )) ) {\n\t\t\t// Speed-up: Sizzle(\"#ID\")\n\t\t\tif ( (m = match[1]) ) {\n\t\t\t\tif ( nodeType === 9 ) {\n\t\t\t\t\telem = context.getElementById( m );\n\t\t\t\t\t// Check parentNode to catch when Blackberry 4.6 returns\n\t\t\t\t\t// nodes that are no longer in the document #6963\n\t\t\t\t\tif ( elem && elem.parentNode ) {\n\t\t\t\t\t\t// Handle the case where IE, Opera, and Webkit return items\n\t\t\t\t\t\t// by name instead of ID\n\t\t\t\t\t\tif ( elem.id === m ) {\n\t\t\t\t\t\t\tresults.push( elem );\n\t\t\t\t\t\t\treturn results;\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\treturn results;\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\t// Context is not a document\n\t\t\t\t\tif ( context.ownerDocument && (elem = context.ownerDocument.getElementById( m )) &&\n\t\t\t\t\t\tcontains( context, elem ) && elem.id === m ) {\n\t\t\t\t\t\tresults.push( elem );\n\t\t\t\t\t\treturn results;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t// Speed-up: Sizzle(\"TAG\")\n\t\t\t} else if ( match[2] ) {\n\t\t\t\tpush.apply( results, slice.call(context.getElementsByTagName( selector ), 0) );\n\t\t\t\treturn results;\n\n\t\t\t// Speed-up: Sizzle(\".CLASS\")\n\t\t\t} else if ( (m = match[3]) && assertUsableClassName && context.getElementsByClassName ) {\n\t\t\t\tpush.apply( results, slice.call(context.getElementsByClassName( m ), 0) );\n\t\t\t\treturn results;\n\t\t\t}\n\t\t}\n\t}\n\n\t// All others\n\treturn select( selector.replace( rtrim, \"$1\" ), context, results, seed, xml );\n}\n\nSizzle.matches = function( expr, elements ) {\n\treturn Sizzle( expr, null, null, elements );\n};\n\nSizzle.matchesSelector = function( elem, expr ) {\n\treturn Sizzle( expr, null, null, [ elem ] ).length > 0;\n};\n\n// Returns a function to use in pseudos for input types\nfunction createInputPseudo( type ) {\n\treturn function( elem ) {\n\t\tvar name = elem.nodeName.toLowerCase();\n\t\treturn name === \"input\" && elem.type === type;\n\t};\n}\n\n// Returns a function to use in pseudos for buttons\nfunction createButtonPseudo( type ) {\n\treturn function( elem ) {\n\t\tvar name = elem.nodeName.toLowerCase();\n\t\treturn (name === \"input\" || name === \"button\") && elem.type === type;\n\t};\n}\n\n// Returns a function to use in pseudos for positionals\nfunction createPositionalPseudo( fn ) {\n\treturn markFunction(function( argument ) {\n\t\targument = +argument;\n\t\treturn markFunction(function( seed, matches ) {\n\t\t\tvar j,\n\t\t\t\tmatchIndexes = fn( [], seed.length, argument ),\n\t\t\t\ti = matchIndexes.length;\n\n\t\t\t// Match elements found at the specified indexes\n\t\t\twhile ( i-- ) {\n\t\t\t\tif ( seed[ (j = matchIndexes[i]) ] ) {\n\t\t\t\t\tseed[j] = !(matches[j] = seed[j]);\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\t});\n}\n\n/**\n * Utility function for retrieving the text value of an array of DOM nodes\n * @param {Array|Element} elem\n */\ngetText = Sizzle.getText = function( elem ) {\n\tvar node,\n\t\tret = \"\",\n\t\ti = 0,\n\t\tnodeType = elem.nodeType;\n\n\tif ( nodeType ) {\n\t\tif ( nodeType === 1 || nodeType === 9 || nodeType === 11 ) {\n\t\t\t// Use textContent for elements\n\t\t\t// innerText usage removed for consistency of new lines (see #11153)\n\t\t\tif ( typeof elem.textContent === \"string\" ) {\n\t\t\t\treturn elem.textContent;\n\t\t\t} else {\n\t\t\t\t// Traverse its children\n\t\t\t\tfor ( elem = elem.firstChild; elem; elem = elem.nextSibling ) {\n\t\t\t\t\tret += getText( elem );\n\t\t\t\t}\n\t\t\t}\n\t\t} else if ( nodeType === 3 || nodeType === 4 ) {\n\t\t\treturn elem.nodeValue;\n\t\t}\n\t\t// Do not include comment or processing instruction nodes\n\t} else {\n\n\t\t// If no nodeType, this is expected to be an array\n\t\tfor ( ; (node = elem[i]); i++ ) {\n\t\t\t// Do not traverse comment nodes\n\t\t\tret += getText( node );\n\t\t}\n\t}\n\treturn ret;\n};\n\nisXML = Sizzle.isXML = function( elem ) {\n\t// documentElement is verified for cases where it doesn't yet exist\n\t// (such as loading iframes in IE - #4833)\n\tvar documentElement = elem && (elem.ownerDocument || elem).documentElement;\n\treturn documentElement ? documentElement.nodeName !== \"HTML\" : false;\n};\n\n// Element contains another\ncontains = Sizzle.contains = docElem.contains ?\n\tfunction( a, b ) {\n\t\tvar adown = a.nodeType === 9 ? a.documentElement : a,\n\t\t\tbup = b && b.parentNode;\n\t\treturn a === bup || !!( bup && bup.nodeType === 1 && adown.contains && adown.contains(bup) );\n\t} :\n\tdocElem.compareDocumentPosition ?\n\tfunction( a, b ) {\n\t\treturn b && !!( a.compareDocumentPosition( b ) & 16 );\n\t} :\n\tfunction( a, b ) {\n\t\twhile ( (b = b.parentNode) ) {\n\t\t\tif ( b === a ) {\n\t\t\t\treturn true;\n\t\t\t}\n\t\t}\n\t\treturn false;\n\t};\n\nSizzle.attr = function( elem, name ) {\n\tvar val,\n\t\txml = isXML( elem );\n\n\tif ( !xml ) {\n\t\tname = name.toLowerCase();\n\t}\n\tif ( (val = Expr.attrHandle[ name ]) ) {\n\t\treturn val( elem );\n\t}\n\tif ( xml || assertAttributes ) {\n\t\treturn elem.getAttribute( name );\n\t}\n\tval = elem.getAttributeNode( name );\n\treturn val ?\n\t\ttypeof elem[ name ] === \"boolean\" ?\n\t\t\telem[ name ] ? name : null :\n\t\t\tval.specified ? val.value : null :\n\t\tnull;\n};\n\nExpr = Sizzle.selectors = {\n\n\t// Can be adjusted by the user\n\tcacheLength: 50,\n\n\tcreatePseudo: markFunction,\n\n\tmatch: matchExpr,\n\n\t// IE6/7 return a modified href\n\tattrHandle: assertHrefNotNormalized ?\n\t\t{} :\n\t\t{\n\t\t\t\"href\": function( elem ) {\n\t\t\t\treturn elem.getAttribute( \"href\", 2 );\n\t\t\t},\n\t\t\t\"type\": function( elem ) {\n\t\t\t\treturn elem.getAttribute(\"type\");\n\t\t\t}\n\t\t},\n\n\tfind: {\n\t\t\"ID\": assertGetIdNotName ?\n\t\t\tfunction( id, context, xml ) {\n\t\t\t\tif ( typeof context.getElementById !== strundefined && !xml ) {\n\t\t\t\t\tvar m = context.getElementById( id );\n\t\t\t\t\t// Check parentNode to catch when Blackberry 4.6 returns\n\t\t\t\t\t// nodes that are no longer in the document #6963\n\t\t\t\t\treturn m && m.parentNode ? [m] : [];\n\t\t\t\t}\n\t\t\t} :\n\t\t\tfunction( id, context, xml ) {\n\t\t\t\tif ( typeof context.getElementById !== strundefined && !xml ) {\n\t\t\t\t\tvar m = context.getElementById( id );\n\n\t\t\t\t\treturn m ?\n\t\t\t\t\t\tm.id === id || typeof m.getAttributeNode !== strundefined && m.getAttributeNode(\"id\").value === id ?\n\t\t\t\t\t\t\t[m] :\n\t\t\t\t\t\t\tundefined :\n\t\t\t\t\t\t[];\n\t\t\t\t}\n\t\t\t},\n\n\t\t\"TAG\": assertTagNameNoComments ?\n\t\t\tfunction( tag, context ) {\n\t\t\t\tif ( typeof context.getElementsByTagName !== strundefined ) {\n\t\t\t\t\treturn context.getElementsByTagName( tag );\n\t\t\t\t}\n\t\t\t} :\n\t\t\tfunction( tag, context ) {\n\t\t\t\tvar results = context.getElementsByTagName( tag );\n\n\t\t\t\t// Filter out possible comments\n\t\t\t\tif ( tag === \"*\" ) {\n\t\t\t\t\tvar elem,\n\t\t\t\t\t\ttmp = [],\n\t\t\t\t\t\ti = 0;\n\n\t\t\t\t\tfor ( ; (elem = results[i]); i++ ) {\n\t\t\t\t\t\tif ( elem.nodeType === 1 ) {\n\t\t\t\t\t\t\ttmp.push( elem );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\treturn tmp;\n\t\t\t\t}\n\t\t\t\treturn results;\n\t\t\t},\n\n\t\t\"NAME\": assertUsableName && function( tag, context ) {\n\t\t\tif ( typeof context.getElementsByName !== strundefined ) {\n\t\t\t\treturn context.getElementsByName( name );\n\t\t\t}\n\t\t},\n\n\t\t\"CLASS\": assertUsableClassName && function( className, context, xml ) {\n\t\t\tif ( typeof context.getElementsByClassName !== strundefined && !xml ) {\n\t\t\t\treturn context.getElementsByClassName( className );\n\t\t\t}\n\t\t}\n\t},\n\n\trelative: {\n\t\t\">\": { dir: \"parentNode\", first: true },\n\t\t\" \": { dir: \"parentNode\" },\n\t\t\"+\": { dir: \"previousSibling\", first: true },\n\t\t\"~\": { dir: \"previousSibling\" }\n\t},\n\n\tpreFilter: {\n\t\t\"ATTR\": function( match ) {\n\t\t\tmatch[1] = match[1].replace( rbackslash, \"\" );\n\n\t\t\t// Move the given value to match[3] whether quoted or unquoted\n\t\t\tmatch[3] = ( match[4] || match[5] || \"\" ).replace( rbackslash, \"\" );\n\n\t\t\tif ( match[2] === \"~=\" ) {\n\t\t\t\tmatch[3] = \" \" + match[3] + \" \";\n\t\t\t}\n\n\t\t\treturn match.slice( 0, 4 );\n\t\t},\n\n\t\t\"CHILD\": function( match ) {\n\t\t\t/* matches from matchExpr[\"CHILD\"]\n\t\t\t\t1 type (only|nth|...)\n\t\t\t\t2 argument (even|odd|\\d*|\\d*n([+-]\\d+)?|...)\n\t\t\t\t3 xn-component of xn+y argument ([+-]?\\d*n|)\n\t\t\t\t4 sign of xn-component\n\t\t\t\t5 x of xn-component\n\t\t\t\t6 sign of y-component\n\t\t\t\t7 y of y-component\n\t\t\t*/\n\t\t\tmatch[1] = match[1].toLowerCase();\n\n\t\t\tif ( match[1] === \"nth\" ) {\n\t\t\t\t// nth-child requires argument\n\t\t\t\tif ( !match[2] ) {\n\t\t\t\t\tSizzle.error( match[0] );\n\t\t\t\t}\n\n\t\t\t\t// numeric x and y parameters for Expr.filter.CHILD\n\t\t\t\t// remember that false/true cast respectively to 0/1\n\t\t\t\tmatch[3] = +( match[3] ? match[4] + (match[5] || 1) : 2 * ( match[2] === \"even\" || match[2] === \"odd\" ) );\n\t\t\t\tmatch[4] = +( ( match[6] + match[7] ) || match[2] === \"odd\" );\n\n\t\t\t// other types prohibit arguments\n\t\t\t} else if ( match[2] ) {\n\t\t\t\tSizzle.error( match[0] );\n\t\t\t}\n\n\t\t\treturn match;\n\t\t},\n\n\t\t\"PSEUDO\": function( match ) {\n\t\t\tvar unquoted, excess;\n\t\t\tif ( matchExpr[\"CHILD\"].test( match[0] ) ) {\n\t\t\t\treturn null;\n\t\t\t}\n\n\t\t\tif ( match[3] ) {\n\t\t\t\tmatch[2] = match[3];\n\t\t\t} else if ( (unquoted = match[4]) ) {\n\t\t\t\t// Only check arguments that contain a pseudo\n\t\t\t\tif ( rpseudo.test(unquoted) &&\n\t\t\t\t\t// Get excess from tokenize (recursively)\n\t\t\t\t\t(excess = tokenize( unquoted, true )) &&\n\t\t\t\t\t// advance to the next closing parenthesis\n\t\t\t\t\t(excess = unquoted.indexOf( \")\", unquoted.length - excess ) - unquoted.length) ) {\n\n\t\t\t\t\t// excess is a negative index\n\t\t\t\t\tunquoted = unquoted.slice( 0, excess );\n\t\t\t\t\tmatch[0] = match[0].slice( 0, excess );\n\t\t\t\t}\n\t\t\t\tmatch[2] = unquoted;\n\t\t\t}\n\n\t\t\t// Return only captures needed by the pseudo filter method (type and argument)\n\t\t\treturn match.slice( 0, 3 );\n\t\t}\n\t},\n\n\tfilter: {\n\t\t\"ID\": assertGetIdNotName ?\n\t\t\tfunction( id ) {\n\t\t\t\tid = id.replace( rbackslash, \"\" );\n\t\t\t\treturn function( elem ) {\n\t\t\t\t\treturn elem.getAttribute(\"id\") === id;\n\t\t\t\t};\n\t\t\t} :\n\t\t\tfunction( id ) {\n\t\t\t\tid = id.replace( rbackslash, \"\" );\n\t\t\t\treturn function( elem ) {\n\t\t\t\t\tvar node = typeof elem.getAttributeNode !== strundefined && elem.getAttributeNode(\"id\");\n\t\t\t\t\treturn node && node.value === id;\n\t\t\t\t};\n\t\t\t},\n\n\t\t\"TAG\": function( nodeName ) {\n\t\t\tif ( nodeName === \"*\" ) {\n\t\t\t\treturn function() { return true; };\n\t\t\t}\n\t\t\tnodeName = nodeName.replace( rbackslash, \"\" ).toLowerCase();\n\n\t\t\treturn function( elem ) {\n\t\t\t\treturn elem.nodeName && elem.nodeName.toLowerCase() === nodeName;\n\t\t\t};\n\t\t},\n\n\t\t\"CLASS\": function( className ) {\n\t\t\tvar pattern = classCache[ expando ][ className + \" \" ];\n\n\t\t\treturn pattern ||\n\t\t\t\t(pattern = new RegExp( \"(^|\" + whitespace + \")\" + className + \"(\" + whitespace + \"|$)\" )) &&\n\t\t\t\tclassCache( className, function( elem ) {\n\t\t\t\t\treturn pattern.test( elem.className || (typeof elem.getAttribute !== strundefined && elem.getAttribute(\"class\")) || \"\" );\n\t\t\t\t});\n\t\t},\n\n\t\t\"ATTR\": function( name, operator, check ) {\n\t\t\treturn function( elem, context ) {\n\t\t\t\tvar result = Sizzle.attr( elem, name );\n\n\t\t\t\tif ( result == null ) {\n\t\t\t\t\treturn operator === \"!=\";\n\t\t\t\t}\n\t\t\t\tif ( !operator ) {\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\n\t\t\t\tresult += \"\";\n\n\t\t\t\treturn operator === \"=\" ? result === check :\n\t\t\t\t\toperator === \"!=\" ? result !== check :\n\t\t\t\t\toperator === \"^=\" ? check && result.indexOf( check ) === 0 :\n\t\t\t\t\toperator === \"*=\" ? check && result.indexOf( check ) > -1 :\n\t\t\t\t\toperator === \"$=\" ? check && result.substr( result.length - check.length ) === check :\n\t\t\t\t\toperator === \"~=\" ? ( \" \" + result + \" \" ).indexOf( check ) > -1 :\n\t\t\t\t\toperator === \"|=\" ? result === check || result.substr( 0, check.length + 1 ) === check + \"-\" :\n\t\t\t\t\tfalse;\n\t\t\t};\n\t\t},\n\n\t\t\"CHILD\": function( type, argument, first, last ) {\n\n\t\t\tif ( type === \"nth\" ) {\n\t\t\t\treturn function( elem ) {\n\t\t\t\t\tvar node, diff,\n\t\t\t\t\t\tparent = elem.parentNode;\n\n\t\t\t\t\tif ( first === 1 && last === 0 ) {\n\t\t\t\t\t\treturn true;\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( parent ) {\n\t\t\t\t\t\tdiff = 0;\n\t\t\t\t\t\tfor ( node = parent.firstChild; node; node = node.nextSibling ) {\n\t\t\t\t\t\t\tif ( node.nodeType === 1 ) {\n\t\t\t\t\t\t\t\tdiff++;\n\t\t\t\t\t\t\t\tif ( elem === node ) {\n\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\t// Incorporate the offset (or cast to NaN), then check against cycle size\n\t\t\t\t\tdiff -= last;\n\t\t\t\t\treturn diff === first || ( diff % first === 0 && diff / first >= 0 );\n\t\t\t\t};\n\t\t\t}\n\n\t\t\treturn function( elem ) {\n\t\t\t\tvar node = elem;\n\n\t\t\t\tswitch ( type ) {\n\t\t\t\t\tcase \"only\":\n\t\t\t\t\tcase \"first\":\n\t\t\t\t\t\twhile ( (node = node.previousSibling) ) {\n\t\t\t\t\t\t\tif ( node.nodeType === 1 ) {\n\t\t\t\t\t\t\t\treturn false;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif ( type === \"first\" ) {\n\t\t\t\t\t\t\treturn true;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tnode = elem;\n\n\t\t\t\t\t\t/* falls through */\n\t\t\t\t\tcase \"last\":\n\t\t\t\t\t\twhile ( (node = node.nextSibling) ) {\n\t\t\t\t\t\t\tif ( node.nodeType === 1 ) {\n\t\t\t\t\t\t\t\treturn false;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t};\n\t\t},\n\n\t\t\"PSEUDO\": function( pseudo, argument ) {\n\t\t\t// pseudo-class names are case-insensitive\n\t\t\t// http://www.w3.org/TR/selectors/#pseudo-classes\n\t\t\t// Prioritize by case sensitivity in case custom pseudos are added with uppercase letters\n\t\t\t// Remember that setFilters inherits from pseudos\n\t\t\tvar args,\n\t\t\t\tfn = Expr.pseudos[ pseudo ] || Expr.setFilters[ pseudo.toLowerCase() ] ||\n\t\t\t\t\tSizzle.error( \"unsupported pseudo: \" + pseudo );\n\n\t\t\t// The user may use createPseudo to indicate that\n\t\t\t// arguments are needed to create the filter function\n\t\t\t// just as Sizzle does\n\t\t\tif ( fn[ expando ] ) {\n\t\t\t\treturn fn( argument );\n\t\t\t}\n\n\t\t\t// But maintain support for old signatures\n\t\t\tif ( fn.length > 1 ) {\n\t\t\t\targs = [ pseudo, pseudo, \"\", argument ];\n\t\t\t\treturn Expr.setFilters.hasOwnProperty( pseudo.toLowerCase() ) ?\n\t\t\t\t\tmarkFunction(function( seed, matches ) {\n\t\t\t\t\t\tvar idx,\n\t\t\t\t\t\t\tmatched = fn( seed, argument ),\n\t\t\t\t\t\t\ti = matched.length;\n\t\t\t\t\t\twhile ( i-- ) {\n\t\t\t\t\t\t\tidx = indexOf.call( seed, matched[i] );\n\t\t\t\t\t\t\tseed[ idx ] = !( matches[ idx ] = matched[i] );\n\t\t\t\t\t\t}\n\t\t\t\t\t}) :\n\t\t\t\t\tfunction( elem ) {\n\t\t\t\t\t\treturn fn( elem, 0, args );\n\t\t\t\t\t};\n\t\t\t}\n\n\t\t\treturn fn;\n\t\t}\n\t},\n\n\tpseudos: {\n\t\t\"not\": markFunction(function( selector ) {\n\t\t\t// Trim the selector passed to compile\n\t\t\t// to avoid treating leading and trailing\n\t\t\t// spaces as combinators\n\t\t\tvar input = [],\n\t\t\t\tresults = [],\n\t\t\t\tmatcher = compile( selector.replace( rtrim, \"$1\" ) );\n\n\t\t\treturn matcher[ expando ] ?\n\t\t\t\tmarkFunction(function( seed, matches, context, xml ) {\n\t\t\t\t\tvar elem,\n\t\t\t\t\t\tunmatched = matcher( seed, null, xml, [] ),\n\t\t\t\t\t\ti = seed.length;\n\n\t\t\t\t\t// Match elements unmatched by `matcher`\n\t\t\t\t\twhile ( i-- ) {\n\t\t\t\t\t\tif ( (elem = unmatched[i]) ) {\n\t\t\t\t\t\t\tseed[i] = !(matches[i] = elem);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}) :\n\t\t\t\tfunction( elem, context, xml ) {\n\t\t\t\t\tinput[0] = elem;\n\t\t\t\t\tmatcher( input, null, xml, results );\n\t\t\t\t\treturn !results.pop();\n\t\t\t\t};\n\t\t}),\n\n\t\t\"has\": markFunction(function( selector ) {\n\t\t\treturn function( elem ) {\n\t\t\t\treturn Sizzle( selector, elem ).length > 0;\n\t\t\t};\n\t\t}),\n\n\t\t\"contains\": markFunction(function( text ) {\n\t\t\treturn function( elem ) {\n\t\t\t\treturn ( elem.textContent || elem.innerText || getText( elem ) ).indexOf( text ) > -1;\n\t\t\t};\n\t\t}),\n\n\t\t\"enabled\": function( elem ) {\n\t\t\treturn elem.disabled === false;\n\t\t},\n\n\t\t\"disabled\": function( elem ) {\n\t\t\treturn elem.disabled === true;\n\t\t},\n\n\t\t\"checked\": function( elem ) {\n\t\t\t// In CSS3, :checked should return both checked and selected elements\n\t\t\t// http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked\n\t\t\tvar nodeName = elem.nodeName.toLowerCase();\n\t\t\treturn (nodeName === \"input\" && !!elem.checked) || (nodeName === \"option\" && !!elem.selected);\n\t\t},\n\n\t\t\"selected\": function( elem ) {\n\t\t\t// Accessing this property makes selected-by-default\n\t\t\t// options in Safari work properly\n\t\t\tif ( elem.parentNode ) {\n\t\t\t\telem.parentNode.selectedIndex;\n\t\t\t}\n\n\t\t\treturn elem.selected === true;\n\t\t},\n\n\t\t\"parent\": function( elem ) {\n\t\t\treturn !Expr.pseudos[\"empty\"]( elem );\n\t\t},\n\n\t\t\"empty\": function( elem ) {\n\t\t\t// http://www.w3.org/TR/selectors/#empty-pseudo\n\t\t\t// :empty is only affected by element nodes and content nodes(including text(3), cdata(4)),\n\t\t\t//   not comment, processing instructions, or others\n\t\t\t// Thanks to Diego Perini for the nodeName shortcut\n\t\t\t//   Greater than \"@\" means alpha characters (specifically not starting with \"#\" or \"?\")\n\t\t\tvar nodeType;\n\t\t\telem = elem.firstChild;\n\t\t\twhile ( elem ) {\n\t\t\t\tif ( elem.nodeName > \"@\" || (nodeType = elem.nodeType) === 3 || nodeType === 4 ) {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t\telem = elem.nextSibling;\n\t\t\t}\n\t\t\treturn true;\n\t\t},\n\n\t\t\"header\": function( elem ) {\n\t\t\treturn rheader.test( elem.nodeName );\n\t\t},\n\n\t\t\"text\": function( elem ) {\n\t\t\tvar type, attr;\n\t\t\t// IE6 and 7 will map elem.type to 'text' for new HTML5 types (search, etc)\n\t\t\t// use getAttribute instead to test this case\n\t\t\treturn elem.nodeName.toLowerCase() === \"input\" &&\n\t\t\t\t(type = elem.type) === \"text\" &&\n\t\t\t\t( (attr = elem.getAttribute(\"type\")) == null || attr.toLowerCase() === type );\n\t\t},\n\n\t\t// Input types\n\t\t\"radio\": createInputPseudo(\"radio\"),\n\t\t\"checkbox\": createInputPseudo(\"checkbox\"),\n\t\t\"file\": createInputPseudo(\"file\"),\n\t\t\"password\": createInputPseudo(\"password\"),\n\t\t\"image\": createInputPseudo(\"image\"),\n\n\t\t\"submit\": createButtonPseudo(\"submit\"),\n\t\t\"reset\": createButtonPseudo(\"reset\"),\n\n\t\t\"button\": function( elem ) {\n\t\t\tvar name = elem.nodeName.toLowerCase();\n\t\t\treturn name === \"input\" && elem.type === \"button\" || name === \"button\";\n\t\t},\n\n\t\t\"input\": function( elem ) {\n\t\t\treturn rinputs.test( elem.nodeName );\n\t\t},\n\n\t\t\"focus\": function( elem ) {\n\t\t\tvar doc = elem.ownerDocument;\n\t\t\treturn elem === doc.activeElement && (!doc.hasFocus || doc.hasFocus()) && !!(elem.type || elem.href || ~elem.tabIndex);\n\t\t},\n\n\t\t\"active\": function( elem ) {\n\t\t\treturn elem === elem.ownerDocument.activeElement;\n\t\t},\n\n\t\t// Positional types\n\t\t\"first\": createPositionalPseudo(function() {\n\t\t\treturn [ 0 ];\n\t\t}),\n\n\t\t\"last\": createPositionalPseudo(function( matchIndexes, length ) {\n\t\t\treturn [ length - 1 ];\n\t\t}),\n\n\t\t\"eq\": createPositionalPseudo(function( matchIndexes, length, argument ) {\n\t\t\treturn [ argument < 0 ? argument + length : argument ];\n\t\t}),\n\n\t\t\"even\": createPositionalPseudo(function( matchIndexes, length ) {\n\t\t\tfor ( var i = 0; i < length; i += 2 ) {\n\t\t\t\tmatchIndexes.push( i );\n\t\t\t}\n\t\t\treturn matchIndexes;\n\t\t}),\n\n\t\t\"odd\": createPositionalPseudo(function( matchIndexes, length ) {\n\t\t\tfor ( var i = 1; i < length; i += 2 ) {\n\t\t\t\tmatchIndexes.push( i );\n\t\t\t}\n\t\t\treturn matchIndexes;\n\t\t}),\n\n\t\t\"lt\": createPositionalPseudo(function( matchIndexes, length, argument ) {\n\t\t\tfor ( var i = argument < 0 ? argument + length : argument; --i >= 0; ) {\n\t\t\t\tmatchIndexes.push( i );\n\t\t\t}\n\t\t\treturn matchIndexes;\n\t\t}),\n\n\t\t\"gt\": createPositionalPseudo(function( matchIndexes, length, argument ) {\n\t\t\tfor ( var i = argument < 0 ? argument + length : argument; ++i < length; ) {\n\t\t\t\tmatchIndexes.push( i );\n\t\t\t}\n\t\t\treturn matchIndexes;\n\t\t})\n\t}\n};\n\nfunction siblingCheck( a, b, ret ) {\n\tif ( a === b ) {\n\t\treturn ret;\n\t}\n\n\tvar cur = a.nextSibling;\n\n\twhile ( cur ) {\n\t\tif ( cur === b ) {\n\t\t\treturn -1;\n\t\t}\n\n\t\tcur = cur.nextSibling;\n\t}\n\n\treturn 1;\n}\n\nsortOrder = docElem.compareDocumentPosition ?\n\tfunction( a, b ) {\n\t\tif ( a === b ) {\n\t\t\thasDuplicate = true;\n\t\t\treturn 0;\n\t\t}\n\n\t\treturn ( !a.compareDocumentPosition || !b.compareDocumentPosition ?\n\t\t\ta.compareDocumentPosition :\n\t\t\ta.compareDocumentPosition(b) & 4\n\t\t) ? -1 : 1;\n\t} :\n\tfunction( a, b ) {\n\t\t// The nodes are identical, we can exit early\n\t\tif ( a === b ) {\n\t\t\thasDuplicate = true;\n\t\t\treturn 0;\n\n\t\t// Fallback to using sourceIndex (in IE) if it's available on both nodes\n\t\t} else if ( a.sourceIndex && b.sourceIndex ) {\n\t\t\treturn a.sourceIndex - b.sourceIndex;\n\t\t}\n\n\t\tvar al, bl,\n\t\t\tap = [],\n\t\t\tbp = [],\n\t\t\taup = a.parentNode,\n\t\t\tbup = b.parentNode,\n\t\t\tcur = aup;\n\n\t\t// If the nodes are siblings (or identical) we can do a quick check\n\t\tif ( aup === bup ) {\n\t\t\treturn siblingCheck( a, b );\n\n\t\t// If no parents were found then the nodes are disconnected\n\t\t} else if ( !aup ) {\n\t\t\treturn -1;\n\n\t\t} else if ( !bup ) {\n\t\t\treturn 1;\n\t\t}\n\n\t\t// Otherwise they're somewhere else in the tree so we need\n\t\t// to build up a full list of the parentNodes for comparison\n\t\twhile ( cur ) {\n\t\t\tap.unshift( cur );\n\t\t\tcur = cur.parentNode;\n\t\t}\n\n\t\tcur = bup;\n\n\t\twhile ( cur ) {\n\t\t\tbp.unshift( cur );\n\t\t\tcur = cur.parentNode;\n\t\t}\n\n\t\tal = ap.length;\n\t\tbl = bp.length;\n\n\t\t// Start walking down the tree looking for a discrepancy\n\t\tfor ( var i = 0; i < al && i < bl; i++ ) {\n\t\t\tif ( ap[i] !== bp[i] ) {\n\t\t\t\treturn siblingCheck( ap[i], bp[i] );\n\t\t\t}\n\t\t}\n\n\t\t// We ended someplace up the tree so do a sibling check\n\t\treturn i === al ?\n\t\t\tsiblingCheck( a, bp[i], -1 ) :\n\t\t\tsiblingCheck( ap[i], b, 1 );\n\t};\n\n// Always assume the presence of duplicates if sort doesn't\n// pass them to our comparison function (as in Google Chrome).\n[0, 0].sort( sortOrder );\nbaseHasDuplicate = !hasDuplicate;\n\n// Document sorting and removing duplicates\nSizzle.uniqueSort = function( results ) {\n\tvar elem,\n\t\tduplicates = [],\n\t\ti = 1,\n\t\tj = 0;\n\n\thasDuplicate = baseHasDuplicate;\n\tresults.sort( sortOrder );\n\n\tif ( hasDuplicate ) {\n\t\tfor ( ; (elem = results[i]); i++ ) {\n\t\t\tif ( elem === results[ i - 1 ] ) {\n\t\t\t\tj = duplicates.push( i );\n\t\t\t}\n\t\t}\n\t\twhile ( j-- ) {\n\t\t\tresults.splice( duplicates[ j ], 1 );\n\t\t}\n\t}\n\n\treturn results;\n};\n\nSizzle.error = function( msg ) {\n\tthrow new Error( \"Syntax error, unrecognized expression: \" + msg );\n};\n\nfunction tokenize( selector, parseOnly ) {\n\tvar matched, match, tokens, type,\n\t\tsoFar, groups, preFilters,\n\t\tcached = tokenCache[ expando ][ selector + \" \" ];\n\n\tif ( cached ) {\n\t\treturn parseOnly ? 0 : cached.slice( 0 );\n\t}\n\n\tsoFar = selector;\n\tgroups = [];\n\tpreFilters = Expr.preFilter;\n\n\twhile ( soFar ) {\n\n\t\t// Comma and first run\n\t\tif ( !matched || (match = rcomma.exec( soFar )) ) {\n\t\t\tif ( match ) {\n\t\t\t\t// Don't consume trailing commas as valid\n\t\t\t\tsoFar = soFar.slice( match[0].length ) || soFar;\n\t\t\t}\n\t\t\tgroups.push( tokens = [] );\n\t\t}\n\n\t\tmatched = false;\n\n\t\t// Combinators\n\t\tif ( (match = rcombinators.exec( soFar )) ) {\n\t\t\ttokens.push( matched = new Token( match.shift() ) );\n\t\t\tsoFar = soFar.slice( matched.length );\n\n\t\t\t// Cast descendant combinators to space\n\t\t\tmatched.type = match[0].replace( rtrim, \" \" );\n\t\t}\n\n\t\t// Filters\n\t\tfor ( type in Expr.filter ) {\n\t\t\tif ( (match = matchExpr[ type ].exec( soFar )) && (!preFilters[ type ] ||\n\t\t\t\t(match = preFilters[ type ]( match ))) ) {\n\n\t\t\t\ttokens.push( matched = new Token( match.shift() ) );\n\t\t\t\tsoFar = soFar.slice( matched.length );\n\t\t\t\tmatched.type = type;\n\t\t\t\tmatched.matches = match;\n\t\t\t}\n\t\t}\n\n\t\tif ( !matched ) {\n\t\t\tbreak;\n\t\t}\n\t}\n\n\t// Return the length of the invalid excess\n\t// if we're just parsing\n\t// Otherwise, throw an error or return tokens\n\treturn parseOnly ?\n\t\tsoFar.length :\n\t\tsoFar ?\n\t\t\tSizzle.error( selector ) :\n\t\t\t// Cache the tokens\n\t\t\ttokenCache( selector, groups ).slice( 0 );\n}\n\nfunction addCombinator( matcher, combinator, base ) {\n\tvar dir = combinator.dir,\n\t\tcheckNonElements = base && combinator.dir === \"parentNode\",\n\t\tdoneName = done++;\n\n\treturn combinator.first ?\n\t\t// Check against closest ancestor/preceding element\n\t\tfunction( elem, context, xml ) {\n\t\t\twhile ( (elem = elem[ dir ]) ) {\n\t\t\t\tif ( checkNonElements || elem.nodeType === 1  ) {\n\t\t\t\t\treturn matcher( elem, context, xml );\n\t\t\t\t}\n\t\t\t}\n\t\t} :\n\n\t\t// Check against all ancestor/preceding elements\n\t\tfunction( elem, context, xml ) {\n\t\t\t// We can't set arbitrary data on XML nodes, so they don't benefit from dir caching\n\t\t\tif ( !xml ) {\n\t\t\t\tvar cache,\n\t\t\t\t\tdirkey = dirruns + \" \" + doneName + \" \",\n\t\t\t\t\tcachedkey = dirkey + cachedruns;\n\t\t\t\twhile ( (elem = elem[ dir ]) ) {\n\t\t\t\t\tif ( checkNonElements || elem.nodeType === 1 ) {\n\t\t\t\t\t\tif ( (cache = elem[ expando ]) === cachedkey ) {\n\t\t\t\t\t\t\treturn elem.sizset;\n\t\t\t\t\t\t} else if ( typeof cache === \"string\" && cache.indexOf(dirkey) === 0 ) {\n\t\t\t\t\t\t\tif ( elem.sizset ) {\n\t\t\t\t\t\t\t\treturn elem;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\telem[ expando ] = cachedkey;\n\t\t\t\t\t\t\tif ( matcher( elem, context, xml ) ) {\n\t\t\t\t\t\t\t\telem.sizset = true;\n\t\t\t\t\t\t\t\treturn elem;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\telem.sizset = false;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\twhile ( (elem = elem[ dir ]) ) {\n\t\t\t\t\tif ( checkNonElements || elem.nodeType === 1 ) {\n\t\t\t\t\t\tif ( matcher( elem, context, xml ) ) {\n\t\t\t\t\t\t\treturn elem;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t};\n}\n\nfunction elementMatcher( matchers ) {\n\treturn matchers.length > 1 ?\n\t\tfunction( elem, context, xml ) {\n\t\t\tvar i = matchers.length;\n\t\t\twhile ( i-- ) {\n\t\t\t\tif ( !matchers[i]( elem, context, xml ) ) {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn true;\n\t\t} :\n\t\tmatchers[0];\n}\n\nfunction condense( unmatched, map, filter, context, xml ) {\n\tvar elem,\n\t\tnewUnmatched = [],\n\t\ti = 0,\n\t\tlen = unmatched.length,\n\t\tmapped = map != null;\n\n\tfor ( ; i < len; i++ ) {\n\t\tif ( (elem = unmatched[i]) ) {\n\t\t\tif ( !filter || filter( elem, context, xml ) ) {\n\t\t\t\tnewUnmatched.push( elem );\n\t\t\t\tif ( mapped ) {\n\t\t\t\t\tmap.push( i );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\treturn newUnmatched;\n}\n\nfunction setMatcher( preFilter, selector, matcher, postFilter, postFinder, postSelector ) {\n\tif ( postFilter && !postFilter[ expando ] ) {\n\t\tpostFilter = setMatcher( postFilter );\n\t}\n\tif ( postFinder && !postFinder[ expando ] ) {\n\t\tpostFinder = setMatcher( postFinder, postSelector );\n\t}\n\treturn markFunction(function( seed, results, context, xml ) {\n\t\tvar temp, i, elem,\n\t\t\tpreMap = [],\n\t\t\tpostMap = [],\n\t\t\tpreexisting = results.length,\n\n\t\t\t// Get initial elements from seed or context\n\t\t\telems = seed || multipleContexts( selector || \"*\", context.nodeType ? [ context ] : context, [] ),\n\n\t\t\t// Prefilter to get matcher input, preserving a map for seed-results synchronization\n\t\t\tmatcherIn = preFilter && ( seed || !selector ) ?\n\t\t\t\tcondense( elems, preMap, preFilter, context, xml ) :\n\t\t\t\telems,\n\n\t\t\tmatcherOut = matcher ?\n\t\t\t\t// If we have a postFinder, or filtered seed, or non-seed postFilter or preexisting results,\n\t\t\t\tpostFinder || ( seed ? preFilter : preexisting || postFilter ) ?\n\n\t\t\t\t\t// ...intermediate processing is necessary\n\t\t\t\t\t[] :\n\n\t\t\t\t\t// ...otherwise use results directly\n\t\t\t\t\tresults :\n\t\t\t\tmatcherIn;\n\n\t\t// Find primary matches\n\t\tif ( matcher ) {\n\t\t\tmatcher( matcherIn, matcherOut, context, xml );\n\t\t}\n\n\t\t// Apply postFilter\n\t\tif ( postFilter ) {\n\t\t\ttemp = condense( matcherOut, postMap );\n\t\t\tpostFilter( temp, [], context, xml );\n\n\t\t\t// Un-match failing elements by moving them back to matcherIn\n\t\t\ti = temp.length;\n\t\t\twhile ( i-- ) {\n\t\t\t\tif ( (elem = temp[i]) ) {\n\t\t\t\t\tmatcherOut[ postMap[i] ] = !(matcherIn[ postMap[i] ] = elem);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif ( seed ) {\n\t\t\tif ( postFinder || preFilter ) {\n\t\t\t\tif ( postFinder ) {\n\t\t\t\t\t// Get the final matcherOut by condensing this intermediate into postFinder contexts\n\t\t\t\t\ttemp = [];\n\t\t\t\t\ti = matcherOut.length;\n\t\t\t\t\twhile ( i-- ) {\n\t\t\t\t\t\tif ( (elem = matcherOut[i]) ) {\n\t\t\t\t\t\t\t// Restore matcherIn since elem is not yet a final match\n\t\t\t\t\t\t\ttemp.push( (matcherIn[i] = elem) );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tpostFinder( null, (matcherOut = []), temp, xml );\n\t\t\t\t}\n\n\t\t\t\t// Move matched elements from seed to results to keep them synchronized\n\t\t\t\ti = matcherOut.length;\n\t\t\t\twhile ( i-- ) {\n\t\t\t\t\tif ( (elem = matcherOut[i]) &&\n\t\t\t\t\t\t(temp = postFinder ? indexOf.call( seed, elem ) : preMap[i]) > -1 ) {\n\n\t\t\t\t\t\tseed[temp] = !(results[temp] = elem);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t// Add elements to results, through postFinder if defined\n\t\t} else {\n\t\t\tmatcherOut = condense(\n\t\t\t\tmatcherOut === results ?\n\t\t\t\t\tmatcherOut.splice( preexisting, matcherOut.length ) :\n\t\t\t\t\tmatcherOut\n\t\t\t);\n\t\t\tif ( postFinder ) {\n\t\t\t\tpostFinder( null, results, matcherOut, xml );\n\t\t\t} else {\n\t\t\t\tpush.apply( results, matcherOut );\n\t\t\t}\n\t\t}\n\t});\n}\n\nfunction matcherFromTokens( tokens ) {\n\tvar checkContext, matcher, j,\n\t\tlen = tokens.length,\n\t\tleadingRelative = Expr.relative[ tokens[0].type ],\n\t\timplicitRelative = leadingRelative || Expr.relative[\" \"],\n\t\ti = leadingRelative ? 1 : 0,\n\n\t\t// The foundational matcher ensures that elements are reachable from top-level context(s)\n\t\tmatchContext = addCombinator( function( elem ) {\n\t\t\treturn elem === checkContext;\n\t\t}, implicitRelative, true ),\n\t\tmatchAnyContext = addCombinator( function( elem ) {\n\t\t\treturn indexOf.call( checkContext, elem ) > -1;\n\t\t}, implicitRelative, true ),\n\t\tmatchers = [ function( elem, context, xml ) {\n\t\t\treturn ( !leadingRelative && ( xml || context !== outermostContext ) ) || (\n\t\t\t\t(checkContext = context).nodeType ?\n\t\t\t\t\tmatchContext( elem, context, xml ) :\n\t\t\t\t\tmatchAnyContext( elem, context, xml ) );\n\t\t} ];\n\n\tfor ( ; i < len; i++ ) {\n\t\tif ( (matcher = Expr.relative[ tokens[i].type ]) ) {\n\t\t\tmatchers = [ addCombinator( elementMatcher( matchers ), matcher ) ];\n\t\t} else {\n\t\t\tmatcher = Expr.filter[ tokens[i].type ].apply( null, tokens[i].matches );\n\n\t\t\t// Return special upon seeing a positional matcher\n\t\t\tif ( matcher[ expando ] ) {\n\t\t\t\t// Find the next relative operator (if any) for proper handling\n\t\t\t\tj = ++i;\n\t\t\t\tfor ( ; j < len; j++ ) {\n\t\t\t\t\tif ( Expr.relative[ tokens[j].type ] ) {\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn setMatcher(\n\t\t\t\t\ti > 1 && elementMatcher( matchers ),\n\t\t\t\t\ti > 1 && tokens.slice( 0, i - 1 ).join(\"\").replace( rtrim, \"$1\" ),\n\t\t\t\t\tmatcher,\n\t\t\t\t\ti < j && matcherFromTokens( tokens.slice( i, j ) ),\n\t\t\t\t\tj < len && matcherFromTokens( (tokens = tokens.slice( j )) ),\n\t\t\t\t\tj < len && tokens.join(\"\")\n\t\t\t\t);\n\t\t\t}\n\t\t\tmatchers.push( matcher );\n\t\t}\n\t}\n\n\treturn elementMatcher( matchers );\n}\n\nfunction matcherFromGroupMatchers( elementMatchers, setMatchers ) {\n\tvar bySet = setMatchers.length > 0,\n\t\tbyElement = elementMatchers.length > 0,\n\t\tsuperMatcher = function( seed, context, xml, results, expandContext ) {\n\t\t\tvar elem, j, matcher,\n\t\t\t\tsetMatched = [],\n\t\t\t\tmatchedCount = 0,\n\t\t\t\ti = \"0\",\n\t\t\t\tunmatched = seed && [],\n\t\t\t\toutermost = expandContext != null,\n\t\t\t\tcontextBackup = outermostContext,\n\t\t\t\t// We must always have either seed elements or context\n\t\t\t\telems = seed || byElement && Expr.find[\"TAG\"]( \"*\", expandContext && context.parentNode || context ),\n\t\t\t\t// Nested matchers should use non-integer dirruns\n\t\t\t\tdirrunsUnique = (dirruns += contextBackup == null ? 1 : Math.E);\n\n\t\t\tif ( outermost ) {\n\t\t\t\toutermostContext = context !== document && context;\n\t\t\t\tcachedruns = superMatcher.el;\n\t\t\t}\n\n\t\t\t// Add elements passing elementMatchers directly to results\n\t\t\tfor ( ; (elem = elems[i]) != null; i++ ) {\n\t\t\t\tif ( byElement && elem ) {\n\t\t\t\t\tfor ( j = 0; (matcher = elementMatchers[j]); j++ ) {\n\t\t\t\t\t\tif ( matcher( elem, context, xml ) ) {\n\t\t\t\t\t\t\tresults.push( elem );\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tif ( outermost ) {\n\t\t\t\t\t\tdirruns = dirrunsUnique;\n\t\t\t\t\t\tcachedruns = ++superMatcher.el;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// Track unmatched elements for set filters\n\t\t\t\tif ( bySet ) {\n\t\t\t\t\t// They will have gone through all possible matchers\n\t\t\t\t\tif ( (elem = !matcher && elem) ) {\n\t\t\t\t\t\tmatchedCount--;\n\t\t\t\t\t}\n\n\t\t\t\t\t// Lengthen the array for every element, matched or not\n\t\t\t\t\tif ( seed ) {\n\t\t\t\t\t\tunmatched.push( elem );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Apply set filters to unmatched elements\n\t\t\tmatchedCount += i;\n\t\t\tif ( bySet && i !== matchedCount ) {\n\t\t\t\tfor ( j = 0; (matcher = setMatchers[j]); j++ ) {\n\t\t\t\t\tmatcher( unmatched, setMatched, context, xml );\n\t\t\t\t}\n\n\t\t\t\tif ( seed ) {\n\t\t\t\t\t// Reintegrate element matches to eliminate the need for sorting\n\t\t\t\t\tif ( matchedCount > 0 ) {\n\t\t\t\t\t\twhile ( i-- ) {\n\t\t\t\t\t\t\tif ( !(unmatched[i] || setMatched[i]) ) {\n\t\t\t\t\t\t\t\tsetMatched[i] = pop.call( results );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\t// Discard index placeholder values to get only actual matches\n\t\t\t\t\tsetMatched = condense( setMatched );\n\t\t\t\t}\n\n\t\t\t\t// Add matches to results\n\t\t\t\tpush.apply( results, setMatched );\n\n\t\t\t\t// Seedless set matches succeeding multiple successful matchers stipulate sorting\n\t\t\t\tif ( outermost && !seed && setMatched.length > 0 &&\n\t\t\t\t\t( matchedCount + setMatchers.length ) > 1 ) {\n\n\t\t\t\t\tSizzle.uniqueSort( results );\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Override manipulation of globals by nested matchers\n\t\t\tif ( outermost ) {\n\t\t\t\tdirruns = dirrunsUnique;\n\t\t\t\toutermostContext = contextBackup;\n\t\t\t}\n\n\t\t\treturn unmatched;\n\t\t};\n\n\tsuperMatcher.el = 0;\n\treturn bySet ?\n\t\tmarkFunction( superMatcher ) :\n\t\tsuperMatcher;\n}\n\ncompile = Sizzle.compile = function( selector, group /* Internal Use Only */ ) {\n\tvar i,\n\t\tsetMatchers = [],\n\t\telementMatchers = [],\n\t\tcached = compilerCache[ expando ][ selector + \" \" ];\n\n\tif ( !cached ) {\n\t\t// Generate a function of recursive functions that can be used to check each element\n\t\tif ( !group ) {\n\t\t\tgroup = tokenize( selector );\n\t\t}\n\t\ti = group.length;\n\t\twhile ( i-- ) {\n\t\t\tcached = matcherFromTokens( group[i] );\n\t\t\tif ( cached[ expando ] ) {\n\t\t\t\tsetMatchers.push( cached );\n\t\t\t} else {\n\t\t\t\telementMatchers.push( cached );\n\t\t\t}\n\t\t}\n\n\t\t// Cache the compiled function\n\t\tcached = compilerCache( selector, matcherFromGroupMatchers( elementMatchers, setMatchers ) );\n\t}\n\treturn cached;\n};\n\nfunction multipleContexts( selector, contexts, results ) {\n\tvar i = 0,\n\t\tlen = contexts.length;\n\tfor ( ; i < len; i++ ) {\n\t\tSizzle( selector, contexts[i], results );\n\t}\n\treturn results;\n}\n\nfunction select( selector, context, results, seed, xml ) {\n\tvar i, tokens, token, type, find,\n\t\tmatch = tokenize( selector ),\n\t\tj = match.length;\n\n\tif ( !seed ) {\n\t\t// Try to minimize operations if there is only one group\n\t\tif ( match.length === 1 ) {\n\n\t\t\t// Take a shortcut and set the context if the root selector is an ID\n\t\t\ttokens = match[0] = match[0].slice( 0 );\n\t\t\tif ( tokens.length > 2 && (token = tokens[0]).type === \"ID\" &&\n\t\t\t\t\tcontext.nodeType === 9 && !xml &&\n\t\t\t\t\tExpr.relative[ tokens[1].type ] ) {\n\n\t\t\t\tcontext = Expr.find[\"ID\"]( token.matches[0].replace( rbackslash, \"\" ), context, xml )[0];\n\t\t\t\tif ( !context ) {\n\t\t\t\t\treturn results;\n\t\t\t\t}\n\n\t\t\t\tselector = selector.slice( tokens.shift().length );\n\t\t\t}\n\n\t\t\t// Fetch a seed set for right-to-left matching\n\t\t\tfor ( i = matchExpr[\"POS\"].test( selector ) ? -1 : tokens.length - 1; i >= 0; i-- ) {\n\t\t\t\ttoken = tokens[i];\n\n\t\t\t\t// Abort if we hit a combinator\n\t\t\t\tif ( Expr.relative[ (type = token.type) ] ) {\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tif ( (find = Expr.find[ type ]) ) {\n\t\t\t\t\t// Search, expanding context for leading sibling combinators\n\t\t\t\t\tif ( (seed = find(\n\t\t\t\t\t\ttoken.matches[0].replace( rbackslash, \"\" ),\n\t\t\t\t\t\trsibling.test( tokens[0].type ) && context.parentNode || context,\n\t\t\t\t\t\txml\n\t\t\t\t\t)) ) {\n\n\t\t\t\t\t\t// If seed is empty or no tokens remain, we can return early\n\t\t\t\t\t\ttokens.splice( i, 1 );\n\t\t\t\t\t\tselector = seed.length && tokens.join(\"\");\n\t\t\t\t\t\tif ( !selector ) {\n\t\t\t\t\t\t\tpush.apply( results, slice.call( seed, 0 ) );\n\t\t\t\t\t\t\treturn results;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t// Compile and execute a filtering function\n\t// Provide `match` to avoid retokenization if we modified the selector above\n\tcompile( selector, match )(\n\t\tseed,\n\t\tcontext,\n\t\txml,\n\t\tresults,\n\t\trsibling.test( selector )\n\t);\n\treturn results;\n}\n\nif ( document.querySelectorAll ) {\n\t(function() {\n\t\tvar disconnectedMatch,\n\t\t\toldSelect = select,\n\t\t\trescape = /'|\\\\/g,\n\t\t\trattributeQuotes = /\\=[\\x20\\t\\r\\n\\f]*([^'\"\\]]*)[\\x20\\t\\r\\n\\f]*\\]/g,\n\n\t\t\t// qSa(:focus) reports false when true (Chrome 21), no need to also add to buggyMatches since matches checks buggyQSA\n\t\t\t// A support test would require too much code (would include document ready)\n\t\t\trbuggyQSA = [ \":focus\" ],\n\n\t\t\t// matchesSelector(:active) reports false when true (IE9/Opera 11.5)\n\t\t\t// A support test would require too much code (would include document ready)\n\t\t\t// just skip matchesSelector for :active\n\t\t\trbuggyMatches = [ \":active\" ],\n\t\t\tmatches = docElem.matchesSelector ||\n\t\t\t\tdocElem.mozMatchesSelector ||\n\t\t\t\tdocElem.webkitMatchesSelector ||\n\t\t\t\tdocElem.oMatchesSelector ||\n\t\t\t\tdocElem.msMatchesSelector;\n\n\t\t// Build QSA regex\n\t\t// Regex strategy adopted from Diego Perini\n\t\tassert(function( div ) {\n\t\t\t// Select is set to empty string on purpose\n\t\t\t// This is to test IE's treatment of not explictly\n\t\t\t// setting a boolean content attribute,\n\t\t\t// since its presence should be enough\n\t\t\t// http://bugs.jquery.com/ticket/12359\n\t\t\tdiv.innerHTML = \"<select><option selected=''></option></select>\";\n\n\t\t\t// IE8 - Some boolean attributes are not treated correctly\n\t\t\tif ( !div.querySelectorAll(\"[selected]\").length ) {\n\t\t\t\trbuggyQSA.push( \"\\\\[\" + whitespace + \"*(?:checked|disabled|ismap|multiple|readonly|selected|value)\" );\n\t\t\t}\n\n\t\t\t// Webkit/Opera - :checked should return selected option elements\n\t\t\t// http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked\n\t\t\t// IE8 throws error here (do not put tests after this one)\n\t\t\tif ( !div.querySelectorAll(\":checked\").length ) {\n\t\t\t\trbuggyQSA.push(\":checked\");\n\t\t\t}\n\t\t});\n\n\t\tassert(function( div ) {\n\n\t\t\t// Opera 10-12/IE9 - ^= $= *= and empty values\n\t\t\t// Should not select anything\n\t\t\tdiv.innerHTML = \"<p test=''></p>\";\n\t\t\tif ( div.querySelectorAll(\"[test^='']\").length ) {\n\t\t\t\trbuggyQSA.push( \"[*^$]=\" + whitespace + \"*(?:\\\"\\\"|'')\" );\n\t\t\t}\n\n\t\t\t// FF 3.5 - :enabled/:disabled and hidden elements (hidden elements are still enabled)\n\t\t\t// IE8 throws error here (do not put tests after this one)\n\t\t\tdiv.innerHTML = \"<input type='hidden'/>\";\n\t\t\tif ( !div.querySelectorAll(\":enabled\").length ) {\n\t\t\t\trbuggyQSA.push(\":enabled\", \":disabled\");\n\t\t\t}\n\t\t});\n\n\t\t// rbuggyQSA always contains :focus, so no need for a length check\n\t\trbuggyQSA = /* rbuggyQSA.length && */ new RegExp( rbuggyQSA.join(\"|\") );\n\n\t\tselect = function( selector, context, results, seed, xml ) {\n\t\t\t// Only use querySelectorAll when not filtering,\n\t\t\t// when this is not xml,\n\t\t\t// and when no QSA bugs apply\n\t\t\tif ( !seed && !xml && !rbuggyQSA.test( selector ) ) {\n\t\t\t\tvar groups, i,\n\t\t\t\t\told = true,\n\t\t\t\t\tnid = expando,\n\t\t\t\t\tnewContext = context,\n\t\t\t\t\tnewSelector = context.nodeType === 9 && selector;\n\n\t\t\t\t// qSA works strangely on Element-rooted queries\n\t\t\t\t// We can work around this by specifying an extra ID on the root\n\t\t\t\t// and working up from there (Thanks to Andrew Dupont for the technique)\n\t\t\t\t// IE 8 doesn't work on object elements\n\t\t\t\tif ( context.nodeType === 1 && context.nodeName.toLowerCase() !== \"object\" ) {\n\t\t\t\t\tgroups = tokenize( selector );\n\n\t\t\t\t\tif ( (old = context.getAttribute(\"id\")) ) {\n\t\t\t\t\t\tnid = old.replace( rescape, \"\\\\$&\" );\n\t\t\t\t\t} else {\n\t\t\t\t\t\tcontext.setAttribute( \"id\", nid );\n\t\t\t\t\t}\n\t\t\t\t\tnid = \"[id='\" + nid + \"'] \";\n\n\t\t\t\t\ti = groups.length;\n\t\t\t\t\twhile ( i-- ) {\n\t\t\t\t\t\tgroups[i] = nid + groups[i].join(\"\");\n\t\t\t\t\t}\n\t\t\t\t\tnewContext = rsibling.test( selector ) && context.parentNode || context;\n\t\t\t\t\tnewSelector = groups.join(\",\");\n\t\t\t\t}\n\n\t\t\t\tif ( newSelector ) {\n\t\t\t\t\ttry {\n\t\t\t\t\t\tpush.apply( results, slice.call( newContext.querySelectorAll(\n\t\t\t\t\t\t\tnewSelector\n\t\t\t\t\t\t), 0 ) );\n\t\t\t\t\t\treturn results;\n\t\t\t\t\t} catch(qsaError) {\n\t\t\t\t\t} finally {\n\t\t\t\t\t\tif ( !old ) {\n\t\t\t\t\t\t\tcontext.removeAttribute(\"id\");\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn oldSelect( selector, context, results, seed, xml );\n\t\t};\n\n\t\tif ( matches ) {\n\t\t\tassert(function( div ) {\n\t\t\t\t// Check to see if it's possible to do matchesSelector\n\t\t\t\t// on a disconnected node (IE 9)\n\t\t\t\tdisconnectedMatch = matches.call( div, \"div\" );\n\n\t\t\t\t// This should fail with an exception\n\t\t\t\t// Gecko does not error, returns false instead\n\t\t\t\ttry {\n\t\t\t\t\tmatches.call( div, \"[test!='']:sizzle\" );\n\t\t\t\t\trbuggyMatches.push( \"!=\", pseudos );\n\t\t\t\t} catch ( e ) {}\n\t\t\t});\n\n\t\t\t// rbuggyMatches always contains :active and :focus, so no need for a length check\n\t\t\trbuggyMatches = /* rbuggyMatches.length && */ new RegExp( rbuggyMatches.join(\"|\") );\n\n\t\t\tSizzle.matchesSelector = function( elem, expr ) {\n\t\t\t\t// Make sure that attribute selectors are quoted\n\t\t\t\texpr = expr.replace( rattributeQuotes, \"='$1']\" );\n\n\t\t\t\t// rbuggyMatches always contains :active, so no need for an existence check\n\t\t\t\tif ( !isXML( elem ) && !rbuggyMatches.test( expr ) && !rbuggyQSA.test( expr ) ) {\n\t\t\t\t\ttry {\n\t\t\t\t\t\tvar ret = matches.call( elem, expr );\n\n\t\t\t\t\t\t// IE 9's matchesSelector returns false on disconnected nodes\n\t\t\t\t\t\tif ( ret || disconnectedMatch ||\n\t\t\t\t\t\t\t\t// As well, disconnected nodes are said to be in a document\n\t\t\t\t\t\t\t\t// fragment in IE 9\n\t\t\t\t\t\t\t\telem.document && elem.document.nodeType !== 11 ) {\n\t\t\t\t\t\t\treturn ret;\n\t\t\t\t\t\t}\n\t\t\t\t\t} catch(e) {}\n\t\t\t\t}\n\n\t\t\t\treturn Sizzle( expr, null, null, [ elem ] ).length > 0;\n\t\t\t};\n\t\t}\n\t})();\n}\n\n// Deprecated\nExpr.pseudos[\"nth\"] = Expr.pseudos[\"eq\"];\n\n// Back-compat\nfunction setFilters() {}\nExpr.filters = setFilters.prototype = Expr.pseudos;\nExpr.setFilters = new setFilters();\n\n// Override sizzle attribute retrieval\nSizzle.attr = jQuery.attr;\njQuery.find = Sizzle;\njQuery.expr = Sizzle.selectors;\njQuery.expr[\":\"] = jQuery.expr.pseudos;\njQuery.unique = Sizzle.uniqueSort;\njQuery.text = Sizzle.getText;\njQuery.isXMLDoc = Sizzle.isXML;\njQuery.contains = Sizzle.contains;\n\n\n})( window );\nvar runtil = /Until$/,\n\trparentsprev = /^(?:parents|prev(?:Until|All))/,\n\tisSimple = /^.[^:#\\[\\.,]*$/,\n\trneedsContext = jQuery.expr.match.needsContext,\n\t// methods guaranteed to produce a unique set when starting from a unique set\n\tguaranteedUnique = {\n\t\tchildren: true,\n\t\tcontents: true,\n\t\tnext: true,\n\t\tprev: true\n\t};\n\njQuery.fn.extend({\n\tfind: function( selector ) {\n\t\tvar i, l, length, n, r, ret,\n\t\t\tself = this;\n\n\t\tif ( typeof selector !== \"string\" ) {\n\t\t\treturn jQuery( selector ).filter(function() {\n\t\t\t\tfor ( i = 0, l = self.length; i < l; i++ ) {\n\t\t\t\t\tif ( jQuery.contains( self[ i ], this ) ) {\n\t\t\t\t\t\treturn true;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\n\t\tret = this.pushStack( \"\", \"find\", selector );\n\n\t\tfor ( i = 0, l = this.length; i < l; i++ ) {\n\t\t\tlength = ret.length;\n\t\t\tjQuery.find( selector, this[i], ret );\n\n\t\t\tif ( i > 0 ) {\n\t\t\t\t// Make sure that the results are unique\n\t\t\t\tfor ( n = length; n < ret.length; n++ ) {\n\t\t\t\t\tfor ( r = 0; r < length; r++ ) {\n\t\t\t\t\t\tif ( ret[r] === ret[n] ) {\n\t\t\t\t\t\t\tret.splice(n--, 1);\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn ret;\n\t},\n\n\thas: function( target ) {\n\t\tvar i,\n\t\t\ttargets = jQuery( target, this ),\n\t\t\tlen = targets.length;\n\n\t\treturn this.filter(function() {\n\t\t\tfor ( i = 0; i < len; i++ ) {\n\t\t\t\tif ( jQuery.contains( this, targets[i] ) ) {\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\t},\n\n\tnot: function( selector ) {\n\t\treturn this.pushStack( winnow(this, selector, false), \"not\", selector);\n\t},\n\n\tfilter: function( selector ) {\n\t\treturn this.pushStack( winnow(this, selector, true), \"filter\", selector );\n\t},\n\n\tis: function( selector ) {\n\t\treturn !!selector && (\n\t\t\ttypeof selector === \"string\" ?\n\t\t\t\t// If this is a positional/relative selector, check membership in the returned set\n\t\t\t\t// so $(\"p:first\").is(\"p:last\") won't return true for a doc with two \"p\".\n\t\t\t\trneedsContext.test( selector ) ?\n\t\t\t\t\tjQuery( selector, this.context ).index( this[0] ) >= 0 :\n\t\t\t\t\tjQuery.filter( selector, this ).length > 0 :\n\t\t\t\tthis.filter( selector ).length > 0 );\n\t},\n\n\tclosest: function( selectors, context ) {\n\t\tvar cur,\n\t\t\ti = 0,\n\t\t\tl = this.length,\n\t\t\tret = [],\n\t\t\tpos = rneedsContext.test( selectors ) || typeof selectors !== \"string\" ?\n\t\t\t\tjQuery( selectors, context || this.context ) :\n\t\t\t\t0;\n\n\t\tfor ( ; i < l; i++ ) {\n\t\t\tcur = this[i];\n\n\t\t\twhile ( cur && cur.ownerDocument && cur !== context && cur.nodeType !== 11 ) {\n\t\t\t\tif ( pos ? pos.index(cur) > -1 : jQuery.find.matchesSelector(cur, selectors) ) {\n\t\t\t\t\tret.push( cur );\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tcur = cur.parentNode;\n\t\t\t}\n\t\t}\n\n\t\tret = ret.length > 1 ? jQuery.unique( ret ) : ret;\n\n\t\treturn this.pushStack( ret, \"closest\", selectors );\n\t},\n\n\t// Determine the position of an element within\n\t// the matched set of elements\n\tindex: function( elem ) {\n\n\t\t// No argument, return index in parent\n\t\tif ( !elem ) {\n\t\t\treturn ( this[0] && this[0].parentNode ) ? this.prevAll().length : -1;\n\t\t}\n\n\t\t// index in selector\n\t\tif ( typeof elem === \"string\" ) {\n\t\t\treturn jQuery.inArray( this[0], jQuery( elem ) );\n\t\t}\n\n\t\t// Locate the position of the desired element\n\t\treturn jQuery.inArray(\n\t\t\t// If it receives a jQuery object, the first element is used\n\t\t\telem.jquery ? elem[0] : elem, this );\n\t},\n\n\tadd: function( selector, context ) {\n\t\tvar set = typeof selector === \"string\" ?\n\t\t\t\tjQuery( selector, context ) :\n\t\t\t\tjQuery.makeArray( selector && selector.nodeType ? [ selector ] : selector ),\n\t\t\tall = jQuery.merge( this.get(), set );\n\n\t\treturn this.pushStack( isDisconnected( set[0] ) || isDisconnected( all[0] ) ?\n\t\t\tall :\n\t\t\tjQuery.unique( all ) );\n\t},\n\n\taddBack: function( selector ) {\n\t\treturn this.add( selector == null ?\n\t\t\tthis.prevObject : this.prevObject.filter(selector)\n\t\t);\n\t}\n});\n\njQuery.fn.andSelf = jQuery.fn.addBack;\n\n// A painfully simple check to see if an element is disconnected\n// from a document (should be improved, where feasible).\nfunction isDisconnected( node ) {\n\treturn !node || !node.parentNode || node.parentNode.nodeType === 11;\n}\n\nfunction sibling( cur, dir ) {\n\tdo {\n\t\tcur = cur[ dir ];\n\t} while ( cur && cur.nodeType !== 1 );\n\n\treturn cur;\n}\n\njQuery.each({\n\tparent: function( elem ) {\n\t\tvar parent = elem.parentNode;\n\t\treturn parent && parent.nodeType !== 11 ? parent : null;\n\t},\n\tparents: function( elem ) {\n\t\treturn jQuery.dir( elem, \"parentNode\" );\n\t},\n\tparentsUntil: function( elem, i, until ) {\n\t\treturn jQuery.dir( elem, \"parentNode\", until );\n\t},\n\tnext: function( elem ) {\n\t\treturn sibling( elem, \"nextSibling\" );\n\t},\n\tprev: function( elem ) {\n\t\treturn sibling( elem, \"previousSibling\" );\n\t},\n\tnextAll: function( elem ) {\n\t\treturn jQuery.dir( elem, \"nextSibling\" );\n\t},\n\tprevAll: function( elem ) {\n\t\treturn jQuery.dir( elem, \"previousSibling\" );\n\t},\n\tnextUntil: function( elem, i, until ) {\n\t\treturn jQuery.dir( elem, \"nextSibling\", until );\n\t},\n\tprevUntil: function( elem, i, until ) {\n\t\treturn jQuery.dir( elem, \"previousSibling\", until );\n\t},\n\tsiblings: function( elem ) {\n\t\treturn jQuery.sibling( ( elem.parentNode || {} ).firstChild, elem );\n\t},\n\tchildren: function( elem ) {\n\t\treturn jQuery.sibling( elem.firstChild );\n\t},\n\tcontents: function( elem ) {\n\t\treturn jQuery.nodeName( elem, \"iframe\" ) ?\n\t\t\telem.contentDocument || elem.contentWindow.document :\n\t\t\tjQuery.merge( [], elem.childNodes );\n\t}\n}, function( name, fn ) {\n\tjQuery.fn[ name ] = function( until, selector ) {\n\t\tvar ret = jQuery.map( this, fn, until );\n\n\t\tif ( !runtil.test( name ) ) {\n\t\t\tselector = until;\n\t\t}\n\n\t\tif ( selector && typeof selector === \"string\" ) {\n\t\t\tret = jQuery.filter( selector, ret );\n\t\t}\n\n\t\tret = this.length > 1 && !guaranteedUnique[ name ] ? jQuery.unique( ret ) : ret;\n\n\t\tif ( this.length > 1 && rparentsprev.test( name ) ) {\n\t\t\tret = ret.reverse();\n\t\t}\n\n\t\treturn this.pushStack( ret, name, core_slice.call( arguments ).join(\",\") );\n\t};\n});\n\njQuery.extend({\n\tfilter: function( expr, elems, not ) {\n\t\tif ( not ) {\n\t\t\texpr = \":not(\" + expr + \")\";\n\t\t}\n\n\t\treturn elems.length === 1 ?\n\t\t\tjQuery.find.matchesSelector(elems[0], expr) ? [ elems[0] ] : [] :\n\t\t\tjQuery.find.matches(expr, elems);\n\t},\n\n\tdir: function( elem, dir, until ) {\n\t\tvar matched = [],\n\t\t\tcur = elem[ dir ];\n\n\t\twhile ( cur && cur.nodeType !== 9 && (until === undefined || cur.nodeType !== 1 || !jQuery( cur ).is( until )) ) {\n\t\t\tif ( cur.nodeType === 1 ) {\n\t\t\t\tmatched.push( cur );\n\t\t\t}\n\t\t\tcur = cur[dir];\n\t\t}\n\t\treturn matched;\n\t},\n\n\tsibling: function( n, elem ) {\n\t\tvar r = [];\n\n\t\tfor ( ; n; n = n.nextSibling ) {\n\t\t\tif ( n.nodeType === 1 && n !== elem ) {\n\t\t\t\tr.push( n );\n\t\t\t}\n\t\t}\n\n\t\treturn r;\n\t}\n});\n\n// Implement the identical functionality for filter and not\nfunction winnow( elements, qualifier, keep ) {\n\n\t// Can't pass null or undefined to indexOf in Firefox 4\n\t// Set to 0 to skip string check\n\tqualifier = qualifier || 0;\n\n\tif ( jQuery.isFunction( qualifier ) ) {\n\t\treturn jQuery.grep(elements, function( elem, i ) {\n\t\t\tvar retVal = !!qualifier.call( elem, i, elem );\n\t\t\treturn retVal === keep;\n\t\t});\n\n\t} else if ( qualifier.nodeType ) {\n\t\treturn jQuery.grep(elements, function( elem, i ) {\n\t\t\treturn ( elem === qualifier ) === keep;\n\t\t});\n\n\t} else if ( typeof qualifier === \"string\" ) {\n\t\tvar filtered = jQuery.grep(elements, function( elem ) {\n\t\t\treturn elem.nodeType === 1;\n\t\t});\n\n\t\tif ( isSimple.test( qualifier ) ) {\n\t\t\treturn jQuery.filter(qualifier, filtered, !keep);\n\t\t} else {\n\t\t\tqualifier = jQuery.filter( qualifier, filtered );\n\t\t}\n\t}\n\n\treturn jQuery.grep(elements, function( elem, i ) {\n\t\treturn ( jQuery.inArray( elem, qualifier ) >= 0 ) === keep;\n\t});\n}\nfunction createSafeFragment( document ) {\n\tvar list = nodeNames.split( \"|\" ),\n\tsafeFrag = document.createDocumentFragment();\n\n\tif ( safeFrag.createElement ) {\n\t\twhile ( list.length ) {\n\t\t\tsafeFrag.createElement(\n\t\t\t\tlist.pop()\n\t\t\t);\n\t\t}\n\t}\n\treturn safeFrag;\n}\n\nvar nodeNames = \"abbr|article|aside|audio|bdi|canvas|data|datalist|details|figcaption|figure|footer|\" +\n\t\t\"header|hgroup|mark|meter|nav|output|progress|section|summary|time|video\",\n\trinlinejQuery = / jQuery\\d+=\"(?:null|\\d+)\"/g,\n\trleadingWhitespace = /^\\s+/,\n\trxhtmlTag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\\w:]+)[^>]*)\\/>/gi,\n\trtagName = /<([\\w:]+)/,\n\trtbody = /<tbody/i,\n\trhtml = /<|&#?\\w+;/,\n\trnoInnerhtml = /<(?:script|style|link)/i,\n\trnocache = /<(?:script|object|embed|option|style)/i,\n\trnoshimcache = new RegExp(\"<(?:\" + nodeNames + \")[\\\\s/>]\", \"i\"),\n\trcheckableType = /^(?:checkbox|radio)$/,\n\t// checked=\"checked\" or checked\n\trchecked = /checked\\s*(?:[^=]|=\\s*.checked.)/i,\n\trscriptType = /\\/(java|ecma)script/i,\n\trcleanScript = /^\\s*<!(?:\\[CDATA\\[|\\-\\-)|[\\]\\-]{2}>\\s*$/g,\n\twrapMap = {\n\t\toption: [ 1, \"<select multiple='multiple'>\", \"</select>\" ],\n\t\tlegend: [ 1, \"<fieldset>\", \"</fieldset>\" ],\n\t\tthead: [ 1, \"<table>\", \"</table>\" ],\n\t\ttr: [ 2, \"<table><tbody>\", \"</tbody></table>\" ],\n\t\ttd: [ 3, \"<table><tbody><tr>\", \"</tr></tbody></table>\" ],\n\t\tcol: [ 2, \"<table><tbody></tbody><colgroup>\", \"</colgroup></table>\" ],\n\t\tarea: [ 1, \"<map>\", \"</map>\" ],\n\t\t_default: [ 0, \"\", \"\" ]\n\t},\n\tsafeFragment = createSafeFragment( document ),\n\tfragmentDiv = safeFragment.appendChild( document.createElement(\"div\") );\n\nwrapMap.optgroup = wrapMap.option;\nwrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead;\nwrapMap.th = wrapMap.td;\n\n// IE6-8 can't serialize link, script, style, or any html5 (NoScope) tags,\n// unless wrapped in a div with non-breaking characters in front of it.\nif ( !jQuery.support.htmlSerialize ) {\n\twrapMap._default = [ 1, \"X<div>\", \"</div>\" ];\n}\n\njQuery.fn.extend({\n\ttext: function( value ) {\n\t\treturn jQuery.access( this, function( value ) {\n\t\t\treturn value === undefined ?\n\t\t\t\tjQuery.text( this ) :\n\t\t\t\tthis.empty().append( ( this[0] && this[0].ownerDocument || document ).createTextNode( value ) );\n\t\t}, null, value, arguments.length );\n\t},\n\n\twrapAll: function( html ) {\n\t\tif ( jQuery.isFunction( html ) ) {\n\t\t\treturn this.each(function(i) {\n\t\t\t\tjQuery(this).wrapAll( html.call(this, i) );\n\t\t\t});\n\t\t}\n\n\t\tif ( this[0] ) {\n\t\t\t// The elements to wrap the target around\n\t\t\tvar wrap = jQuery( html, this[0].ownerDocument ).eq(0).clone(true);\n\n\t\t\tif ( this[0].parentNode ) {\n\t\t\t\twrap.insertBefore( this[0] );\n\t\t\t}\n\n\t\t\twrap.map(function() {\n\t\t\t\tvar elem = this;\n\n\t\t\t\twhile ( elem.firstChild && elem.firstChild.nodeType === 1 ) {\n\t\t\t\t\telem = elem.firstChild;\n\t\t\t\t}\n\n\t\t\t\treturn elem;\n\t\t\t}).append( this );\n\t\t}\n\n\t\treturn this;\n\t},\n\n\twrapInner: function( html ) {\n\t\tif ( jQuery.isFunction( html ) ) {\n\t\t\treturn this.each(function(i) {\n\t\t\t\tjQuery(this).wrapInner( html.call(this, i) );\n\t\t\t});\n\t\t}\n\n\t\treturn this.each(function() {\n\t\t\tvar self = jQuery( this ),\n\t\t\t\tcontents = self.contents();\n\n\t\t\tif ( contents.length ) {\n\t\t\t\tcontents.wrapAll( html );\n\n\t\t\t} else {\n\t\t\t\tself.append( html );\n\t\t\t}\n\t\t});\n\t},\n\n\twrap: function( html ) {\n\t\tvar isFunction = jQuery.isFunction( html );\n\n\t\treturn this.each(function(i) {\n\t\t\tjQuery( this ).wrapAll( isFunction ? html.call(this, i) : html );\n\t\t});\n\t},\n\n\tunwrap: function() {\n\t\treturn this.parent().each(function() {\n\t\t\tif ( !jQuery.nodeName( this, \"body\" ) ) {\n\t\t\t\tjQuery( this ).replaceWith( this.childNodes );\n\t\t\t}\n\t\t}).end();\n\t},\n\n\tappend: function() {\n\t\treturn this.domManip(arguments, true, function( elem ) {\n\t\t\tif ( this.nodeType === 1 || this.nodeType === 11 ) {\n\t\t\t\tthis.appendChild( elem );\n\t\t\t}\n\t\t});\n\t},\n\n\tprepend: function() {\n\t\treturn this.domManip(arguments, true, function( elem ) {\n\t\t\tif ( this.nodeType === 1 || this.nodeType === 11 ) {\n\t\t\t\tthis.insertBefore( elem, this.firstChild );\n\t\t\t}\n\t\t});\n\t},\n\n\tbefore: function() {\n\t\tif ( !isDisconnected( this[0] ) ) {\n\t\t\treturn this.domManip(arguments, false, function( elem ) {\n\t\t\t\tthis.parentNode.insertBefore( elem, this );\n\t\t\t});\n\t\t}\n\n\t\tif ( arguments.length ) {\n\t\t\tvar set = jQuery.clean( arguments );\n\t\t\treturn this.pushStack( jQuery.merge( set, this ), \"before\", this.selector );\n\t\t}\n\t},\n\n\tafter: function() {\n\t\tif ( !isDisconnected( this[0] ) ) {\n\t\t\treturn this.domManip(arguments, false, function( elem ) {\n\t\t\t\tthis.parentNode.insertBefore( elem, this.nextSibling );\n\t\t\t});\n\t\t}\n\n\t\tif ( arguments.length ) {\n\t\t\tvar set = jQuery.clean( arguments );\n\t\t\treturn this.pushStack( jQuery.merge( this, set ), \"after\", this.selector );\n\t\t}\n\t},\n\n\t// keepData is for internal use only--do not document\n\tremove: function( selector, keepData ) {\n\t\tvar elem,\n\t\t\ti = 0;\n\n\t\tfor ( ; (elem = this[i]) != null; i++ ) {\n\t\t\tif ( !selector || jQuery.filter( selector, [ elem ] ).length ) {\n\t\t\t\tif ( !keepData && elem.nodeType === 1 ) {\n\t\t\t\t\tjQuery.cleanData( elem.getElementsByTagName(\"*\") );\n\t\t\t\t\tjQuery.cleanData( [ elem ] );\n\t\t\t\t}\n\n\t\t\t\tif ( elem.parentNode ) {\n\t\t\t\t\telem.parentNode.removeChild( elem );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn this;\n\t},\n\n\tempty: function() {\n\t\tvar elem,\n\t\t\ti = 0;\n\n\t\tfor ( ; (elem = this[i]) != null; i++ ) {\n\t\t\t// Remove element nodes and prevent memory leaks\n\t\t\tif ( elem.nodeType === 1 ) {\n\t\t\t\tjQuery.cleanData( elem.getElementsByTagName(\"*\") );\n\t\t\t}\n\n\t\t\t// Remove any remaining nodes\n\t\t\twhile ( elem.firstChild ) {\n\t\t\t\telem.removeChild( elem.firstChild );\n\t\t\t}\n\t\t}\n\n\t\treturn this;\n\t},\n\n\tclone: function( dataAndEvents, deepDataAndEvents ) {\n\t\tdataAndEvents = dataAndEvents == null ? false : dataAndEvents;\n\t\tdeepDataAndEvents = deepDataAndEvents == null ? dataAndEvents : deepDataAndEvents;\n\n\t\treturn this.map( function () {\n\t\t\treturn jQuery.clone( this, dataAndEvents, deepDataAndEvents );\n\t\t});\n\t},\n\n\thtml: function( value ) {\n\t\treturn jQuery.access( this, function( value ) {\n\t\t\tvar elem = this[0] || {},\n\t\t\t\ti = 0,\n\t\t\t\tl = this.length;\n\n\t\t\tif ( value === undefined ) {\n\t\t\t\treturn elem.nodeType === 1 ?\n\t\t\t\t\telem.innerHTML.replace( rinlinejQuery, \"\" ) :\n\t\t\t\t\tundefined;\n\t\t\t}\n\n\t\t\t// See if we can take a shortcut and just use innerHTML\n\t\t\tif ( typeof value === \"string\" && !rnoInnerhtml.test( value ) &&\n\t\t\t\t( jQuery.support.htmlSerialize || !rnoshimcache.test( value )  ) &&\n\t\t\t\t( jQuery.support.leadingWhitespace || !rleadingWhitespace.test( value ) ) &&\n\t\t\t\t!wrapMap[ ( rtagName.exec( value ) || [\"\", \"\"] )[1].toLowerCase() ] ) {\n\n\t\t\t\tvalue = value.replace( rxhtmlTag, \"<$1></$2>\" );\n\n\t\t\t\ttry {\n\t\t\t\t\tfor (; i < l; i++ ) {\n\t\t\t\t\t\t// Remove element nodes and prevent memory leaks\n\t\t\t\t\t\telem = this[i] || {};\n\t\t\t\t\t\tif ( elem.nodeType === 1 ) {\n\t\t\t\t\t\t\tjQuery.cleanData( elem.getElementsByTagName( \"*\" ) );\n\t\t\t\t\t\t\telem.innerHTML = value;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\telem = 0;\n\n\t\t\t\t// If using innerHTML throws an exception, use the fallback method\n\t\t\t\t} catch(e) {}\n\t\t\t}\n\n\t\t\tif ( elem ) {\n\t\t\t\tthis.empty().append( value );\n\t\t\t}\n\t\t}, null, value, arguments.length );\n\t},\n\n\treplaceWith: function( value ) {\n\t\tif ( !isDisconnected( this[0] ) ) {\n\t\t\t// Make sure that the elements are removed from the DOM before they are inserted\n\t\t\t// this can help fix replacing a parent with child elements\n\t\t\tif ( jQuery.isFunction( value ) ) {\n\t\t\t\treturn this.each(function(i) {\n\t\t\t\t\tvar self = jQuery(this), old = self.html();\n\t\t\t\t\tself.replaceWith( value.call( this, i, old ) );\n\t\t\t\t});\n\t\t\t}\n\n\t\t\tif ( typeof value !== \"string\" ) {\n\t\t\t\tvalue = jQuery( value ).detach();\n\t\t\t}\n\n\t\t\treturn this.each(function() {\n\t\t\t\tvar next = this.nextSibling,\n\t\t\t\t\tparent = this.parentNode;\n\n\t\t\t\tjQuery( this ).remove();\n\n\t\t\t\tif ( next ) {\n\t\t\t\t\tjQuery(next).before( value );\n\t\t\t\t} else {\n\t\t\t\t\tjQuery(parent).append( value );\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\n\t\treturn this.length ?\n\t\t\tthis.pushStack( jQuery(jQuery.isFunction(value) ? value() : value), \"replaceWith\", value ) :\n\t\t\tthis;\n\t},\n\n\tdetach: function( selector ) {\n\t\treturn this.remove( selector, true );\n\t},\n\n\tdomManip: function( args, table, callback ) {\n\n\t\t// Flatten any nested arrays\n\t\targs = [].concat.apply( [], args );\n\n\t\tvar results, first, fragment, iNoClone,\n\t\t\ti = 0,\n\t\t\tvalue = args[0],\n\t\t\tscripts = [],\n\t\t\tl = this.length;\n\n\t\t// We can't cloneNode fragments that contain checked, in WebKit\n\t\tif ( !jQuery.support.checkClone && l > 1 && typeof value === \"string\" && rchecked.test( value ) ) {\n\t\t\treturn this.each(function() {\n\t\t\t\tjQuery(this).domManip( args, table, callback );\n\t\t\t});\n\t\t}\n\n\t\tif ( jQuery.isFunction(value) ) {\n\t\t\treturn this.each(function(i) {\n\t\t\t\tvar self = jQuery(this);\n\t\t\t\targs[0] = value.call( this, i, table ? self.html() : undefined );\n\t\t\t\tself.domManip( args, table, callback );\n\t\t\t});\n\t\t}\n\n\t\tif ( this[0] ) {\n\t\t\tresults = jQuery.buildFragment( args, this, scripts );\n\t\t\tfragment = results.fragment;\n\t\t\tfirst = fragment.firstChild;\n\n\t\t\tif ( fragment.childNodes.length === 1 ) {\n\t\t\t\tfragment = first;\n\t\t\t}\n\n\t\t\tif ( first ) {\n\t\t\t\ttable = table && jQuery.nodeName( first, \"tr\" );\n\n\t\t\t\t// Use the original fragment for the last item instead of the first because it can end up\n\t\t\t\t// being emptied incorrectly in certain situations (#8070).\n\t\t\t\t// Fragments from the fragment cache must always be cloned and never used in place.\n\t\t\t\tfor ( iNoClone = results.cacheable || l - 1; i < l; i++ ) {\n\t\t\t\t\tcallback.call(\n\t\t\t\t\t\ttable && jQuery.nodeName( this[i], \"table\" ) ?\n\t\t\t\t\t\t\tfindOrAppend( this[i], \"tbody\" ) :\n\t\t\t\t\t\t\tthis[i],\n\t\t\t\t\t\ti === iNoClone ?\n\t\t\t\t\t\t\tfragment :\n\t\t\t\t\t\t\tjQuery.clone( fragment, true, true )\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Fix #11809: Avoid leaking memory\n\t\t\tfragment = first = null;\n\n\t\t\tif ( scripts.length ) {\n\t\t\t\tjQuery.each( scripts, function( i, elem ) {\n\t\t\t\t\tif ( elem.src ) {\n\t\t\t\t\t\tif ( jQuery.ajax ) {\n\t\t\t\t\t\t\tjQuery.ajax({\n\t\t\t\t\t\t\t\turl: elem.src,\n\t\t\t\t\t\t\t\ttype: \"GET\",\n\t\t\t\t\t\t\t\tdataType: \"script\",\n\t\t\t\t\t\t\t\tasync: false,\n\t\t\t\t\t\t\t\tglobal: false,\n\t\t\t\t\t\t\t\t\"throws\": true\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tjQuery.error(\"no ajax\");\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\tjQuery.globalEval( ( elem.text || elem.textContent || elem.innerHTML || \"\" ).replace( rcleanScript, \"\" ) );\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( elem.parentNode ) {\n\t\t\t\t\t\telem.parentNode.removeChild( elem );\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\n\t\treturn this;\n\t}\n});\n\nfunction findOrAppend( elem, tag ) {\n\treturn elem.getElementsByTagName( tag )[0] || elem.appendChild( elem.ownerDocument.createElement( tag ) );\n}\n\nfunction cloneCopyEvent( src, dest ) {\n\n\tif ( dest.nodeType !== 1 || !jQuery.hasData( src ) ) {\n\t\treturn;\n\t}\n\n\tvar type, i, l,\n\t\toldData = jQuery._data( src ),\n\t\tcurData = jQuery._data( dest, oldData ),\n\t\tevents = oldData.events;\n\n\tif ( events ) {\n\t\tdelete curData.handle;\n\t\tcurData.events = {};\n\n\t\tfor ( type in events ) {\n\t\t\tfor ( i = 0, l = events[ type ].length; i < l; i++ ) {\n\t\t\t\tjQuery.event.add( dest, type, events[ type ][ i ] );\n\t\t\t}\n\t\t}\n\t}\n\n\t// make the cloned public data object a copy from the original\n\tif ( curData.data ) {\n\t\tcurData.data = jQuery.extend( {}, curData.data );\n\t}\n}\n\nfunction cloneFixAttributes( src, dest ) {\n\tvar nodeName;\n\n\t// We do not need to do anything for non-Elements\n\tif ( dest.nodeType !== 1 ) {\n\t\treturn;\n\t}\n\n\t// clearAttributes removes the attributes, which we don't want,\n\t// but also removes the attachEvent events, which we *do* want\n\tif ( dest.clearAttributes ) {\n\t\tdest.clearAttributes();\n\t}\n\n\t// mergeAttributes, in contrast, only merges back on the\n\t// original attributes, not the events\n\tif ( dest.mergeAttributes ) {\n\t\tdest.mergeAttributes( src );\n\t}\n\n\tnodeName = dest.nodeName.toLowerCase();\n\n\tif ( nodeName === \"object\" ) {\n\t\t// IE6-10 improperly clones children of object elements using classid.\n\t\t// IE10 throws NoModificationAllowedError if parent is null, #12132.\n\t\tif ( dest.parentNode ) {\n\t\t\tdest.outerHTML = src.outerHTML;\n\t\t}\n\n\t\t// This path appears unavoidable for IE9. When cloning an object\n\t\t// element in IE9, the outerHTML strategy above is not sufficient.\n\t\t// If the src has innerHTML and the destination does not,\n\t\t// copy the src.innerHTML into the dest.innerHTML. #10324\n\t\tif ( jQuery.support.html5Clone && (src.innerHTML && !jQuery.trim(dest.innerHTML)) ) {\n\t\t\tdest.innerHTML = src.innerHTML;\n\t\t}\n\n\t} else if ( nodeName === \"input\" && rcheckableType.test( src.type ) ) {\n\t\t// IE6-8 fails to persist the checked state of a cloned checkbox\n\t\t// or radio button. Worse, IE6-7 fail to give the cloned element\n\t\t// a checked appearance if the defaultChecked value isn't also set\n\n\t\tdest.defaultChecked = dest.checked = src.checked;\n\n\t\t// IE6-7 get confused and end up setting the value of a cloned\n\t\t// checkbox/radio button to an empty string instead of \"on\"\n\t\tif ( dest.value !== src.value ) {\n\t\t\tdest.value = src.value;\n\t\t}\n\n\t// IE6-8 fails to return the selected option to the default selected\n\t// state when cloning options\n\t} else if ( nodeName === \"option\" ) {\n\t\tdest.selected = src.defaultSelected;\n\n\t// IE6-8 fails to set the defaultValue to the correct value when\n\t// cloning other types of input fields\n\t} else if ( nodeName === \"input\" || nodeName === \"textarea\" ) {\n\t\tdest.defaultValue = src.defaultValue;\n\n\t// IE blanks contents when cloning scripts\n\t} else if ( nodeName === \"script\" && dest.text !== src.text ) {\n\t\tdest.text = src.text;\n\t}\n\n\t// Event data gets referenced instead of copied if the expando\n\t// gets copied too\n\tdest.removeAttribute( jQuery.expando );\n}\n\njQuery.buildFragment = function( args, context, scripts ) {\n\tvar fragment, cacheable, cachehit,\n\t\tfirst = args[ 0 ];\n\n\t// Set context from what may come in as undefined or a jQuery collection or a node\n\t// Updated to fix #12266 where accessing context[0] could throw an exception in IE9/10 &\n\t// also doubles as fix for #8950 where plain objects caused createDocumentFragment exception\n\tcontext = context || document;\n\tcontext = !context.nodeType && context[0] || context;\n\tcontext = context.ownerDocument || context;\n\n\t// Only cache \"small\" (1/2 KB) HTML strings that are associated with the main document\n\t// Cloning options loses the selected state, so don't cache them\n\t// IE 6 doesn't like it when you put <object> or <embed> elements in a fragment\n\t// Also, WebKit does not clone 'checked' attributes on cloneNode, so don't cache\n\t// Lastly, IE6,7,8 will not correctly reuse cached fragments that were created from unknown elems #10501\n\tif ( args.length === 1 && typeof first === \"string\" && first.length < 512 && context === document &&\n\t\tfirst.charAt(0) === \"<\" && !rnocache.test( first ) &&\n\t\t(jQuery.support.checkClone || !rchecked.test( first )) &&\n\t\t(jQuery.support.html5Clone || !rnoshimcache.test( first )) ) {\n\n\t\t// Mark cacheable and look for a hit\n\t\tcacheable = true;\n\t\tfragment = jQuery.fragments[ first ];\n\t\tcachehit = fragment !== undefined;\n\t}\n\n\tif ( !fragment ) {\n\t\tfragment = context.createDocumentFragment();\n\t\tjQuery.clean( args, context, fragment, scripts );\n\n\t\t// Update the cache, but only store false\n\t\t// unless this is a second parsing of the same content\n\t\tif ( cacheable ) {\n\t\t\tjQuery.fragments[ first ] = cachehit && fragment;\n\t\t}\n\t}\n\n\treturn { fragment: fragment, cacheable: cacheable };\n};\n\njQuery.fragments = {};\n\njQuery.each({\n\tappendTo: \"append\",\n\tprependTo: \"prepend\",\n\tinsertBefore: \"before\",\n\tinsertAfter: \"after\",\n\treplaceAll: \"replaceWith\"\n}, function( name, original ) {\n\tjQuery.fn[ name ] = function( selector ) {\n\t\tvar elems,\n\t\t\ti = 0,\n\t\t\tret = [],\n\t\t\tinsert = jQuery( selector ),\n\t\t\tl = insert.length,\n\t\t\tparent = this.length === 1 && this[0].parentNode;\n\n\t\tif ( (parent == null || parent && parent.nodeType === 11 && parent.childNodes.length === 1) && l === 1 ) {\n\t\t\tinsert[ original ]( this[0] );\n\t\t\treturn this;\n\t\t} else {\n\t\t\tfor ( ; i < l; i++ ) {\n\t\t\t\telems = ( i > 0 ? this.clone(true) : this ).get();\n\t\t\t\tjQuery( insert[i] )[ original ]( elems );\n\t\t\t\tret = ret.concat( elems );\n\t\t\t}\n\n\t\t\treturn this.pushStack( ret, name, insert.selector );\n\t\t}\n\t};\n});\n\nfunction getAll( elem ) {\n\tif ( typeof elem.getElementsByTagName !== \"undefined\" ) {\n\t\treturn elem.getElementsByTagName( \"*\" );\n\n\t} else if ( typeof elem.querySelectorAll !== \"undefined\" ) {\n\t\treturn elem.querySelectorAll( \"*\" );\n\n\t} else {\n\t\treturn [];\n\t}\n}\n\n// Used in clean, fixes the defaultChecked property\nfunction fixDefaultChecked( elem ) {\n\tif ( rcheckableType.test( elem.type ) ) {\n\t\telem.defaultChecked = elem.checked;\n\t}\n}\n\njQuery.extend({\n\tclone: function( elem, dataAndEvents, deepDataAndEvents ) {\n\t\tvar srcElements,\n\t\t\tdestElements,\n\t\t\ti,\n\t\t\tclone;\n\n\t\tif ( jQuery.support.html5Clone || jQuery.isXMLDoc(elem) || !rnoshimcache.test( \"<\" + elem.nodeName + \">\" ) ) {\n\t\t\tclone = elem.cloneNode( true );\n\n\t\t// IE<=8 does not properly clone detached, unknown element nodes\n\t\t} else {\n\t\t\tfragmentDiv.innerHTML = elem.outerHTML;\n\t\t\tfragmentDiv.removeChild( clone = fragmentDiv.firstChild );\n\t\t}\n\n\t\tif ( (!jQuery.support.noCloneEvent || !jQuery.support.noCloneChecked) &&\n\t\t\t\t(elem.nodeType === 1 || elem.nodeType === 11) && !jQuery.isXMLDoc(elem) ) {\n\t\t\t// IE copies events bound via attachEvent when using cloneNode.\n\t\t\t// Calling detachEvent on the clone will also remove the events\n\t\t\t// from the original. In order to get around this, we use some\n\t\t\t// proprietary methods to clear the events. Thanks to MooTools\n\t\t\t// guys for this hotness.\n\n\t\t\tcloneFixAttributes( elem, clone );\n\n\t\t\t// Using Sizzle here is crazy slow, so we use getElementsByTagName instead\n\t\t\tsrcElements = getAll( elem );\n\t\t\tdestElements = getAll( clone );\n\n\t\t\t// Weird iteration because IE will replace the length property\n\t\t\t// with an element if you are cloning the body and one of the\n\t\t\t// elements on the page has a name or id of \"length\"\n\t\t\tfor ( i = 0; srcElements[i]; ++i ) {\n\t\t\t\t// Ensure that the destination node is not null; Fixes #9587\n\t\t\t\tif ( destElements[i] ) {\n\t\t\t\t\tcloneFixAttributes( srcElements[i], destElements[i] );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Copy the events from the original to the clone\n\t\tif ( dataAndEvents ) {\n\t\t\tcloneCopyEvent( elem, clone );\n\n\t\t\tif ( deepDataAndEvents ) {\n\t\t\t\tsrcElements = getAll( elem );\n\t\t\t\tdestElements = getAll( clone );\n\n\t\t\t\tfor ( i = 0; srcElements[i]; ++i ) {\n\t\t\t\t\tcloneCopyEvent( srcElements[i], destElements[i] );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tsrcElements = destElements = null;\n\n\t\t// Return the cloned set\n\t\treturn clone;\n\t},\n\n\tclean: function( elems, context, fragment, scripts ) {\n\t\tvar i, j, elem, tag, wrap, depth, div, hasBody, tbody, len, handleScript, jsTags,\n\t\t\tsafe = context === document && safeFragment,\n\t\t\tret = [];\n\n\t\t// Ensure that context is a document\n\t\tif ( !context || typeof context.createDocumentFragment === \"undefined\" ) {\n\t\t\tcontext = document;\n\t\t}\n\n\t\t// Use the already-created safe fragment if context permits\n\t\tfor ( i = 0; (elem = elems[i]) != null; i++ ) {\n\t\t\tif ( typeof elem === \"number\" ) {\n\t\t\t\telem += \"\";\n\t\t\t}\n\n\t\t\tif ( !elem ) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\t// Convert html string into DOM nodes\n\t\t\tif ( typeof elem === \"string\" ) {\n\t\t\t\tif ( !rhtml.test( elem ) ) {\n\t\t\t\t\telem = context.createTextNode( elem );\n\t\t\t\t} else {\n\t\t\t\t\t// Ensure a safe container in which to render the html\n\t\t\t\t\tsafe = safe || createSafeFragment( context );\n\t\t\t\t\tdiv = context.createElement(\"div\");\n\t\t\t\t\tsafe.appendChild( div );\n\n\t\t\t\t\t// Fix \"XHTML\"-style tags in all browsers\n\t\t\t\t\telem = elem.replace(rxhtmlTag, \"<$1></$2>\");\n\n\t\t\t\t\t// Go to html and back, then peel off extra wrappers\n\t\t\t\t\ttag = ( rtagName.exec( elem ) || [\"\", \"\"] )[1].toLowerCase();\n\t\t\t\t\twrap = wrapMap[ tag ] || wrapMap._default;\n\t\t\t\t\tdepth = wrap[0];\n\t\t\t\t\tdiv.innerHTML = wrap[1] + elem + wrap[2];\n\n\t\t\t\t\t// Move to the right depth\n\t\t\t\t\twhile ( depth-- ) {\n\t\t\t\t\t\tdiv = div.lastChild;\n\t\t\t\t\t}\n\n\t\t\t\t\t// Remove IE's autoinserted <tbody> from table fragments\n\t\t\t\t\tif ( !jQuery.support.tbody ) {\n\n\t\t\t\t\t\t// String was a <table>, *may* have spurious <tbody>\n\t\t\t\t\t\thasBody = rtbody.test(elem);\n\t\t\t\t\t\t\ttbody = tag === \"table\" && !hasBody ?\n\t\t\t\t\t\t\t\tdiv.firstChild && div.firstChild.childNodes :\n\n\t\t\t\t\t\t\t\t// String was a bare <thead> or <tfoot>\n\t\t\t\t\t\t\t\twrap[1] === \"<table>\" && !hasBody ?\n\t\t\t\t\t\t\t\t\tdiv.childNodes :\n\t\t\t\t\t\t\t\t\t[];\n\n\t\t\t\t\t\tfor ( j = tbody.length - 1; j >= 0 ; --j ) {\n\t\t\t\t\t\t\tif ( jQuery.nodeName( tbody[ j ], \"tbody\" ) && !tbody[ j ].childNodes.length ) {\n\t\t\t\t\t\t\t\ttbody[ j ].parentNode.removeChild( tbody[ j ] );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\t// IE completely kills leading whitespace when innerHTML is used\n\t\t\t\t\tif ( !jQuery.support.leadingWhitespace && rleadingWhitespace.test( elem ) ) {\n\t\t\t\t\t\tdiv.insertBefore( context.createTextNode( rleadingWhitespace.exec(elem)[0] ), div.firstChild );\n\t\t\t\t\t}\n\n\t\t\t\t\telem = div.childNodes;\n\n\t\t\t\t\t// Take out of fragment container (we need a fresh div each time)\n\t\t\t\t\tdiv.parentNode.removeChild( div );\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif ( elem.nodeType ) {\n\t\t\t\tret.push( elem );\n\t\t\t} else {\n\t\t\t\tjQuery.merge( ret, elem );\n\t\t\t}\n\t\t}\n\n\t\t// Fix #11356: Clear elements from safeFragment\n\t\tif ( div ) {\n\t\t\telem = div = safe = null;\n\t\t}\n\n\t\t// Reset defaultChecked for any radios and checkboxes\n\t\t// about to be appended to the DOM in IE 6/7 (#8060)\n\t\tif ( !jQuery.support.appendChecked ) {\n\t\t\tfor ( i = 0; (elem = ret[i]) != null; i++ ) {\n\t\t\t\tif ( jQuery.nodeName( elem, \"input\" ) ) {\n\t\t\t\t\tfixDefaultChecked( elem );\n\t\t\t\t} else if ( typeof elem.getElementsByTagName !== \"undefined\" ) {\n\t\t\t\t\tjQuery.grep( elem.getElementsByTagName(\"input\"), fixDefaultChecked );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Append elements to a provided document fragment\n\t\tif ( fragment ) {\n\t\t\t// Special handling of each script element\n\t\t\thandleScript = function( elem ) {\n\t\t\t\t// Check if we consider it executable\n\t\t\t\tif ( !elem.type || rscriptType.test( elem.type ) ) {\n\t\t\t\t\t// Detach the script and store it in the scripts array (if provided) or the fragment\n\t\t\t\t\t// Return truthy to indicate that it has been handled\n\t\t\t\t\treturn scripts ?\n\t\t\t\t\t\tscripts.push( elem.parentNode ? elem.parentNode.removeChild( elem ) : elem ) :\n\t\t\t\t\t\tfragment.appendChild( elem );\n\t\t\t\t}\n\t\t\t};\n\n\t\t\tfor ( i = 0; (elem = ret[i]) != null; i++ ) {\n\t\t\t\t// Check if we're done after handling an executable script\n\t\t\t\tif ( !( jQuery.nodeName( elem, \"script\" ) && handleScript( elem ) ) ) {\n\t\t\t\t\t// Append to fragment and handle embedded scripts\n\t\t\t\t\tfragment.appendChild( elem );\n\t\t\t\t\tif ( typeof elem.getElementsByTagName !== \"undefined\" ) {\n\t\t\t\t\t\t// handleScript alters the DOM, so use jQuery.merge to ensure snapshot iteration\n\t\t\t\t\t\tjsTags = jQuery.grep( jQuery.merge( [], elem.getElementsByTagName(\"script\") ), handleScript );\n\n\t\t\t\t\t\t// Splice the scripts into ret after their former ancestor and advance our index beyond them\n\t\t\t\t\t\tret.splice.apply( ret, [i + 1, 0].concat( jsTags ) );\n\t\t\t\t\t\ti += jsTags.length;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn ret;\n\t},\n\n\tcleanData: function( elems, /* internal */ acceptData ) {\n\t\tvar data, id, elem, type,\n\t\t\ti = 0,\n\t\t\tinternalKey = jQuery.expando,\n\t\t\tcache = jQuery.cache,\n\t\t\tdeleteExpando = jQuery.support.deleteExpando,\n\t\t\tspecial = jQuery.event.special;\n\n\t\tfor ( ; (elem = elems[i]) != null; i++ ) {\n\n\t\t\tif ( acceptData || jQuery.acceptData( elem ) ) {\n\n\t\t\t\tid = elem[ internalKey ];\n\t\t\t\tdata = id && cache[ id ];\n\n\t\t\t\tif ( data ) {\n\t\t\t\t\tif ( data.events ) {\n\t\t\t\t\t\tfor ( type in data.events ) {\n\t\t\t\t\t\t\tif ( special[ type ] ) {\n\t\t\t\t\t\t\t\tjQuery.event.remove( elem, type );\n\n\t\t\t\t\t\t\t// This is a shortcut to avoid jQuery.event.remove's overhead\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tjQuery.removeEvent( elem, type, data.handle );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\t// Remove cache only if it was not already removed by jQuery.event.remove\n\t\t\t\t\tif ( cache[ id ] ) {\n\n\t\t\t\t\t\tdelete cache[ id ];\n\n\t\t\t\t\t\t// IE does not allow us to delete expando properties from nodes,\n\t\t\t\t\t\t// nor does it have a removeAttribute function on Document nodes;\n\t\t\t\t\t\t// we must handle all of these cases\n\t\t\t\t\t\tif ( deleteExpando ) {\n\t\t\t\t\t\t\tdelete elem[ internalKey ];\n\n\t\t\t\t\t\t} else if ( elem.removeAttribute ) {\n\t\t\t\t\t\t\telem.removeAttribute( internalKey );\n\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\telem[ internalKey ] = null;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tjQuery.deletedIds.push( id );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n});\n// Limit scope pollution from any deprecated API\n(function() {\n\nvar matched, browser;\n\n// Use of jQuery.browser is frowned upon.\n// More details: http://api.jquery.com/jQuery.browser\n// jQuery.uaMatch maintained for back-compat\njQuery.uaMatch = function( ua ) {\n\tua = ua.toLowerCase();\n\n\tvar match = /(chrome)[ \\/]([\\w.]+)/.exec( ua ) ||\n\t\t/(webkit)[ \\/]([\\w.]+)/.exec( ua ) ||\n\t\t/(opera)(?:.*version|)[ \\/]([\\w.]+)/.exec( ua ) ||\n\t\t/(msie) ([\\w.]+)/.exec( ua ) ||\n\t\tua.indexOf(\"compatible\") < 0 && /(mozilla)(?:.*? rv:([\\w.]+)|)/.exec( ua ) ||\n\t\t[];\n\n\treturn {\n\t\tbrowser: match[ 1 ] || \"\",\n\t\tversion: match[ 2 ] || \"0\"\n\t};\n};\n\nmatched = jQuery.uaMatch( navigator.userAgent );\nbrowser = {};\n\nif ( matched.browser ) {\n\tbrowser[ matched.browser ] = true;\n\tbrowser.version = matched.version;\n}\n\n// Chrome is Webkit, but Webkit is also Safari.\nif ( browser.chrome ) {\n\tbrowser.webkit = true;\n} else if ( browser.webkit ) {\n\tbrowser.safari = true;\n}\n\njQuery.browser = browser;\n\njQuery.sub = function() {\n\tfunction jQuerySub( selector, context ) {\n\t\treturn new jQuerySub.fn.init( selector, context );\n\t}\n\tjQuery.extend( true, jQuerySub, this );\n\tjQuerySub.superclass = this;\n\tjQuerySub.fn = jQuerySub.prototype = this();\n\tjQuerySub.fn.constructor = jQuerySub;\n\tjQuerySub.sub = this.sub;\n\tjQuerySub.fn.init = function init( selector, context ) {\n\t\tif ( context && context instanceof jQuery && !(context instanceof jQuerySub) ) {\n\t\t\tcontext = jQuerySub( context );\n\t\t}\n\n\t\treturn jQuery.fn.init.call( this, selector, context, rootjQuerySub );\n\t};\n\tjQuerySub.fn.init.prototype = jQuerySub.fn;\n\tvar rootjQuerySub = jQuerySub(document);\n\treturn jQuerySub;\n};\n\n})();\nvar curCSS, iframe, iframeDoc,\n\tralpha = /alpha\\([^)]*\\)/i,\n\tropacity = /opacity=([^)]*)/,\n\trposition = /^(top|right|bottom|left)$/,\n\t// swappable if display is none or starts with table except \"table\", \"table-cell\", or \"table-caption\"\n\t// see here for display values: https://developer.mozilla.org/en-US/docs/CSS/display\n\trdisplayswap = /^(none|table(?!-c[ea]).+)/,\n\trmargin = /^margin/,\n\trnumsplit = new RegExp( \"^(\" + core_pnum + \")(.*)$\", \"i\" ),\n\trnumnonpx = new RegExp( \"^(\" + core_pnum + \")(?!px)[a-z%]+$\", \"i\" ),\n\trrelNum = new RegExp( \"^([-+])=(\" + core_pnum + \")\", \"i\" ),\n\telemdisplay = { BODY: \"block\" },\n\n\tcssShow = { position: \"absolute\", visibility: \"hidden\", display: \"block\" },\n\tcssNormalTransform = {\n\t\tletterSpacing: 0,\n\t\tfontWeight: 400\n\t},\n\n\tcssExpand = [ \"Top\", \"Right\", \"Bottom\", \"Left\" ],\n\tcssPrefixes = [ \"Webkit\", \"O\", \"Moz\", \"ms\" ],\n\n\teventsToggle = jQuery.fn.toggle;\n\n// return a css property mapped to a potentially vendor prefixed property\nfunction vendorPropName( style, name ) {\n\n\t// shortcut for names that are not vendor prefixed\n\tif ( name in style ) {\n\t\treturn name;\n\t}\n\n\t// check for vendor prefixed names\n\tvar capName = name.charAt(0).toUpperCase() + name.slice(1),\n\t\torigName = name,\n\t\ti = cssPrefixes.length;\n\n\twhile ( i-- ) {\n\t\tname = cssPrefixes[ i ] + capName;\n\t\tif ( name in style ) {\n\t\t\treturn name;\n\t\t}\n\t}\n\n\treturn origName;\n}\n\nfunction isHidden( elem, el ) {\n\telem = el || elem;\n\treturn jQuery.css( elem, \"display\" ) === \"none\" || !jQuery.contains( elem.ownerDocument, elem );\n}\n\nfunction showHide( elements, show ) {\n\tvar elem, display,\n\t\tvalues = [],\n\t\tindex = 0,\n\t\tlength = elements.length;\n\n\tfor ( ; index < length; index++ ) {\n\t\telem = elements[ index ];\n\t\tif ( !elem.style ) {\n\t\t\tcontinue;\n\t\t}\n\t\tvalues[ index ] = jQuery._data( elem, \"olddisplay\" );\n\t\tif ( show ) {\n\t\t\t// Reset the inline display of this element to learn if it is\n\t\t\t// being hidden by cascaded rules or not\n\t\t\tif ( !values[ index ] && elem.style.display === \"none\" ) {\n\t\t\t\telem.style.display = \"\";\n\t\t\t}\n\n\t\t\t// Set elements which have been overridden with display: none\n\t\t\t// in a stylesheet to whatever the default browser style is\n\t\t\t// for such an element\n\t\t\tif ( elem.style.display === \"\" && isHidden( elem ) ) {\n\t\t\t\tvalues[ index ] = jQuery._data( elem, \"olddisplay\", css_defaultDisplay(elem.nodeName) );\n\t\t\t}\n\t\t} else {\n\t\t\tdisplay = curCSS( elem, \"display\" );\n\n\t\t\tif ( !values[ index ] && display !== \"none\" ) {\n\t\t\t\tjQuery._data( elem, \"olddisplay\", display );\n\t\t\t}\n\t\t}\n\t}\n\n\t// Set the display of most of the elements in a second loop\n\t// to avoid the constant reflow\n\tfor ( index = 0; index < length; index++ ) {\n\t\telem = elements[ index ];\n\t\tif ( !elem.style ) {\n\t\t\tcontinue;\n\t\t}\n\t\tif ( !show || elem.style.display === \"none\" || elem.style.display === \"\" ) {\n\t\t\telem.style.display = show ? values[ index ] || \"\" : \"none\";\n\t\t}\n\t}\n\n\treturn elements;\n}\n\njQuery.fn.extend({\n\tcss: function( name, value ) {\n\t\treturn jQuery.access( this, function( elem, name, value ) {\n\t\t\treturn value !== undefined ?\n\t\t\t\tjQuery.style( elem, name, value ) :\n\t\t\t\tjQuery.css( elem, name );\n\t\t}, name, value, arguments.length > 1 );\n\t},\n\tshow: function() {\n\t\treturn showHide( this, true );\n\t},\n\thide: function() {\n\t\treturn showHide( this );\n\t},\n\ttoggle: function( state, fn2 ) {\n\t\tvar bool = typeof state === \"boolean\";\n\n\t\tif ( jQuery.isFunction( state ) && jQuery.isFunction( fn2 ) ) {\n\t\t\treturn eventsToggle.apply( this, arguments );\n\t\t}\n\n\t\treturn this.each(function() {\n\t\t\tif ( bool ? state : isHidden( this ) ) {\n\t\t\t\tjQuery( this ).show();\n\t\t\t} else {\n\t\t\t\tjQuery( this ).hide();\n\t\t\t}\n\t\t});\n\t}\n});\n\njQuery.extend({\n\t// Add in style property hooks for overriding the default\n\t// behavior of getting and setting a style property\n\tcssHooks: {\n\t\topacity: {\n\t\t\tget: function( elem, computed ) {\n\t\t\t\tif ( computed ) {\n\t\t\t\t\t// We should always get a number back from opacity\n\t\t\t\t\tvar ret = curCSS( elem, \"opacity\" );\n\t\t\t\t\treturn ret === \"\" ? \"1\" : ret;\n\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t},\n\n\t// Exclude the following css properties to add px\n\tcssNumber: {\n\t\t\"fillOpacity\": true,\n\t\t\"fontWeight\": true,\n\t\t\"lineHeight\": true,\n\t\t\"opacity\": true,\n\t\t\"orphans\": true,\n\t\t\"widows\": true,\n\t\t\"zIndex\": true,\n\t\t\"zoom\": true\n\t},\n\n\t// Add in properties whose names you wish to fix before\n\t// setting or getting the value\n\tcssProps: {\n\t\t// normalize float css property\n\t\t\"float\": jQuery.support.cssFloat ? \"cssFloat\" : \"styleFloat\"\n\t},\n\n\t// Get and set the style property on a DOM Node\n\tstyle: function( elem, name, value, extra ) {\n\t\t// Don't set styles on text and comment nodes\n\t\tif ( !elem || elem.nodeType === 3 || elem.nodeType === 8 || !elem.style ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Make sure that we're working with the right name\n\t\tvar ret, type, hooks,\n\t\t\torigName = jQuery.camelCase( name ),\n\t\t\tstyle = elem.style;\n\n\t\tname = jQuery.cssProps[ origName ] || ( jQuery.cssProps[ origName ] = vendorPropName( style, origName ) );\n\n\t\t// gets hook for the prefixed version\n\t\t// followed by the unprefixed version\n\t\thooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ];\n\n\t\t// Check if we're setting a value\n\t\tif ( value !== undefined ) {\n\t\t\ttype = typeof value;\n\n\t\t\t// convert relative number strings (+= or -=) to relative numbers. #7345\n\t\t\tif ( type === \"string\" && (ret = rrelNum.exec( value )) ) {\n\t\t\t\tvalue = ( ret[1] + 1 ) * ret[2] + parseFloat( jQuery.css( elem, name ) );\n\t\t\t\t// Fixes bug #9237\n\t\t\t\ttype = \"number\";\n\t\t\t}\n\n\t\t\t// Make sure that NaN and null values aren't set. See: #7116\n\t\t\tif ( value == null || type === \"number\" && isNaN( value ) ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// If a number was passed in, add 'px' to the (except for certain CSS properties)\n\t\t\tif ( type === \"number\" && !jQuery.cssNumber[ origName ] ) {\n\t\t\t\tvalue += \"px\";\n\t\t\t}\n\n\t\t\t// If a hook was provided, use that value, otherwise just set the specified value\n\t\t\tif ( !hooks || !(\"set\" in hooks) || (value = hooks.set( elem, value, extra )) !== undefined ) {\n\t\t\t\t// Wrapped to prevent IE from throwing errors when 'invalid' values are provided\n\t\t\t\t// Fixes bug #5509\n\t\t\t\ttry {\n\t\t\t\t\tstyle[ name ] = value;\n\t\t\t\t} catch(e) {}\n\t\t\t}\n\n\t\t} else {\n\t\t\t// If a hook was provided get the non-computed value from there\n\t\t\tif ( hooks && \"get\" in hooks && (ret = hooks.get( elem, false, extra )) !== undefined ) {\n\t\t\t\treturn ret;\n\t\t\t}\n\n\t\t\t// Otherwise just get the value from the style object\n\t\t\treturn style[ name ];\n\t\t}\n\t},\n\n\tcss: function( elem, name, numeric, extra ) {\n\t\tvar val, num, hooks,\n\t\t\torigName = jQuery.camelCase( name );\n\n\t\t// Make sure that we're working with the right name\n\t\tname = jQuery.cssProps[ origName ] || ( jQuery.cssProps[ origName ] = vendorPropName( elem.style, origName ) );\n\n\t\t// gets hook for the prefixed version\n\t\t// followed by the unprefixed version\n\t\thooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ];\n\n\t\t// If a hook was provided get the computed value from there\n\t\tif ( hooks && \"get\" in hooks ) {\n\t\t\tval = hooks.get( elem, true, extra );\n\t\t}\n\n\t\t// Otherwise, if a way to get the computed value exists, use that\n\t\tif ( val === undefined ) {\n\t\t\tval = curCSS( elem, name );\n\t\t}\n\n\t\t//convert \"normal\" to computed value\n\t\tif ( val === \"normal\" && name in cssNormalTransform ) {\n\t\t\tval = cssNormalTransform[ name ];\n\t\t}\n\n\t\t// Return, converting to number if forced or a qualifier was provided and val looks numeric\n\t\tif ( numeric || extra !== undefined ) {\n\t\t\tnum = parseFloat( val );\n\t\t\treturn numeric || jQuery.isNumeric( num ) ? num || 0 : val;\n\t\t}\n\t\treturn val;\n\t},\n\n\t// A method for quickly swapping in/out CSS properties to get correct calculations\n\tswap: function( elem, options, callback ) {\n\t\tvar ret, name,\n\t\t\told = {};\n\n\t\t// Remember the old values, and insert the new ones\n\t\tfor ( name in options ) {\n\t\t\told[ name ] = elem.style[ name ];\n\t\t\telem.style[ name ] = options[ name ];\n\t\t}\n\n\t\tret = callback.call( elem );\n\n\t\t// Revert the old values\n\t\tfor ( name in options ) {\n\t\t\telem.style[ name ] = old[ name ];\n\t\t}\n\n\t\treturn ret;\n\t}\n});\n\n// NOTE: To any future maintainer, we've window.getComputedStyle\n// because jsdom on node.js will break without it.\nif ( window.getComputedStyle ) {\n\tcurCSS = function( elem, name ) {\n\t\tvar ret, width, minWidth, maxWidth,\n\t\t\tcomputed = window.getComputedStyle( elem, null ),\n\t\t\tstyle = elem.style;\n\n\t\tif ( computed ) {\n\n\t\t\t// getPropertyValue is only needed for .css('filter') in IE9, see #12537\n\t\t\tret = computed.getPropertyValue( name ) || computed[ name ];\n\n\t\t\tif ( ret === \"\" && !jQuery.contains( elem.ownerDocument, elem ) ) {\n\t\t\t\tret = jQuery.style( elem, name );\n\t\t\t}\n\n\t\t\t// A tribute to the \"awesome hack by Dean Edwards\"\n\t\t\t// Chrome < 17 and Safari 5.0 uses \"computed value\" instead of \"used value\" for margin-right\n\t\t\t// Safari 5.1.7 (at least) returns percentage for a larger set of values, but width seems to be reliably pixels\n\t\t\t// this is against the CSSOM draft spec: http://dev.w3.org/csswg/cssom/#resolved-values\n\t\t\tif ( rnumnonpx.test( ret ) && rmargin.test( name ) ) {\n\t\t\t\twidth = style.width;\n\t\t\t\tminWidth = style.minWidth;\n\t\t\t\tmaxWidth = style.maxWidth;\n\n\t\t\t\tstyle.minWidth = style.maxWidth = style.width = ret;\n\t\t\t\tret = computed.width;\n\n\t\t\t\tstyle.width = width;\n\t\t\t\tstyle.minWidth = minWidth;\n\t\t\t\tstyle.maxWidth = maxWidth;\n\t\t\t}\n\t\t}\n\n\t\treturn ret;\n\t};\n} else if ( document.documentElement.currentStyle ) {\n\tcurCSS = function( elem, name ) {\n\t\tvar left, rsLeft,\n\t\t\tret = elem.currentStyle && elem.currentStyle[ name ],\n\t\t\tstyle = elem.style;\n\n\t\t// Avoid setting ret to empty string here\n\t\t// so we don't default to auto\n\t\tif ( ret == null && style && style[ name ] ) {\n\t\t\tret = style[ name ];\n\t\t}\n\n\t\t// From the awesome hack by Dean Edwards\n\t\t// http://erik.eae.net/archives/2007/07/27/18.54.15/#comment-102291\n\n\t\t// If we're not dealing with a regular pixel number\n\t\t// but a number that has a weird ending, we need to convert it to pixels\n\t\t// but not position css attributes, as those are proportional to the parent element instead\n\t\t// and we can't measure the parent instead because it might trigger a \"stacking dolls\" problem\n\t\tif ( rnumnonpx.test( ret ) && !rposition.test( name ) ) {\n\n\t\t\t// Remember the original values\n\t\t\tleft = style.left;\n\t\t\trsLeft = elem.runtimeStyle && elem.runtimeStyle.left;\n\n\t\t\t// Put in the new values to get a computed value out\n\t\t\tif ( rsLeft ) {\n\t\t\t\telem.runtimeStyle.left = elem.currentStyle.left;\n\t\t\t}\n\t\t\tstyle.left = name === \"fontSize\" ? \"1em\" : ret;\n\t\t\tret = style.pixelLeft + \"px\";\n\n\t\t\t// Revert the changed values\n\t\t\tstyle.left = left;\n\t\t\tif ( rsLeft ) {\n\t\t\t\telem.runtimeStyle.left = rsLeft;\n\t\t\t}\n\t\t}\n\n\t\treturn ret === \"\" ? \"auto\" : ret;\n\t};\n}\n\nfunction setPositiveNumber( elem, value, subtract ) {\n\tvar matches = rnumsplit.exec( value );\n\treturn matches ?\n\t\t\tMath.max( 0, matches[ 1 ] - ( subtract || 0 ) ) + ( matches[ 2 ] || \"px\" ) :\n\t\t\tvalue;\n}\n\nfunction augmentWidthOrHeight( elem, name, extra, isBorderBox ) {\n\tvar i = extra === ( isBorderBox ? \"border\" : \"content\" ) ?\n\t\t// If we already have the right measurement, avoid augmentation\n\t\t4 :\n\t\t// Otherwise initialize for horizontal or vertical properties\n\t\tname === \"width\" ? 1 : 0,\n\n\t\tval = 0;\n\n\tfor ( ; i < 4; i += 2 ) {\n\t\t// both box models exclude margin, so add it if we want it\n\t\tif ( extra === \"margin\" ) {\n\t\t\t// we use jQuery.css instead of curCSS here\n\t\t\t// because of the reliableMarginRight CSS hook!\n\t\t\tval += jQuery.css( elem, extra + cssExpand[ i ], true );\n\t\t}\n\n\t\t// From this point on we use curCSS for maximum performance (relevant in animations)\n\t\tif ( isBorderBox ) {\n\t\t\t// border-box includes padding, so remove it if we want content\n\t\t\tif ( extra === \"content\" ) {\n\t\t\t\tval -= parseFloat( curCSS( elem, \"padding\" + cssExpand[ i ] ) ) || 0;\n\t\t\t}\n\n\t\t\t// at this point, extra isn't border nor margin, so remove border\n\t\t\tif ( extra !== \"margin\" ) {\n\t\t\t\tval -= parseFloat( curCSS( elem, \"border\" + cssExpand[ i ] + \"Width\" ) ) || 0;\n\t\t\t}\n\t\t} else {\n\t\t\t// at this point, extra isn't content, so add padding\n\t\t\tval += parseFloat( curCSS( elem, \"padding\" + cssExpand[ i ] ) ) || 0;\n\n\t\t\t// at this point, extra isn't content nor padding, so add border\n\t\t\tif ( extra !== \"padding\" ) {\n\t\t\t\tval += parseFloat( curCSS( elem, \"border\" + cssExpand[ i ] + \"Width\" ) ) || 0;\n\t\t\t}\n\t\t}\n\t}\n\n\treturn val;\n}\n\nfunction getWidthOrHeight( elem, name, extra ) {\n\n\t// Start with offset property, which is equivalent to the border-box value\n\tvar val = name === \"width\" ? elem.offsetWidth : elem.offsetHeight,\n\t\tvalueIsBorderBox = true,\n\t\tisBorderBox = jQuery.support.boxSizing && jQuery.css( elem, \"boxSizing\" ) === \"border-box\";\n\n\t// some non-html elements return undefined for offsetWidth, so check for null/undefined\n\t// svg - https://bugzilla.mozilla.org/show_bug.cgi?id=649285\n\t// MathML - https://bugzilla.mozilla.org/show_bug.cgi?id=491668\n\tif ( val <= 0 || val == null ) {\n\t\t// Fall back to computed then uncomputed css if necessary\n\t\tval = curCSS( elem, name );\n\t\tif ( val < 0 || val == null ) {\n\t\t\tval = elem.style[ name ];\n\t\t}\n\n\t\t// Computed unit is not pixels. Stop here and return.\n\t\tif ( rnumnonpx.test(val) ) {\n\t\t\treturn val;\n\t\t}\n\n\t\t// we need the check for style in case a browser which returns unreliable values\n\t\t// for getComputedStyle silently falls back to the reliable elem.style\n\t\tvalueIsBorderBox = isBorderBox && ( jQuery.support.boxSizingReliable || val === elem.style[ name ] );\n\n\t\t// Normalize \"\", auto, and prepare for extra\n\t\tval = parseFloat( val ) || 0;\n\t}\n\n\t// use the active box-sizing model to add/subtract irrelevant styles\n\treturn ( val +\n\t\taugmentWidthOrHeight(\n\t\t\telem,\n\t\t\tname,\n\t\t\textra || ( isBorderBox ? \"border\" : \"content\" ),\n\t\t\tvalueIsBorderBox\n\t\t)\n\t) + \"px\";\n}\n\n\n// Try to determine the default display value of an element\nfunction css_defaultDisplay( nodeName ) {\n\tif ( elemdisplay[ nodeName ] ) {\n\t\treturn elemdisplay[ nodeName ];\n\t}\n\n\tvar elem = jQuery( \"<\" + nodeName + \">\" ).appendTo( document.body ),\n\t\tdisplay = elem.css(\"display\");\n\telem.remove();\n\n\t// If the simple way fails,\n\t// get element's real default display by attaching it to a temp iframe\n\tif ( display === \"none\" || display === \"\" ) {\n\t\t// Use the already-created iframe if possible\n\t\tiframe = document.body.appendChild(\n\t\t\tiframe || jQuery.extend( document.createElement(\"iframe\"), {\n\t\t\t\tframeBorder: 0,\n\t\t\t\twidth: 0,\n\t\t\t\theight: 0\n\t\t\t})\n\t\t);\n\n\t\t// Create a cacheable copy of the iframe document on first call.\n\t\t// IE and Opera will allow us to reuse the iframeDoc without re-writing the fake HTML\n\t\t// document to it; WebKit & Firefox won't allow reusing the iframe document.\n\t\tif ( !iframeDoc || !iframe.createElement ) {\n\t\t\tiframeDoc = ( iframe.contentWindow || iframe.contentDocument ).document;\n\t\t\tiframeDoc.write(\"<!doctype html><html><body>\");\n\t\t\tiframeDoc.close();\n\t\t}\n\n\t\telem = iframeDoc.body.appendChild( iframeDoc.createElement(nodeName) );\n\n\t\tdisplay = curCSS( elem, \"display\" );\n\t\tdocument.body.removeChild( iframe );\n\t}\n\n\t// Store the correct default display\n\telemdisplay[ nodeName ] = display;\n\n\treturn display;\n}\n\njQuery.each([ \"height\", \"width\" ], function( i, name ) {\n\tjQuery.cssHooks[ name ] = {\n\t\tget: function( elem, computed, extra ) {\n\t\t\tif ( computed ) {\n\t\t\t\t// certain elements can have dimension info if we invisibly show them\n\t\t\t\t// however, it must have a current display style that would benefit from this\n\t\t\t\tif ( elem.offsetWidth === 0 && rdisplayswap.test( curCSS( elem, \"display\" ) ) ) {\n\t\t\t\t\treturn jQuery.swap( elem, cssShow, function() {\n\t\t\t\t\t\treturn getWidthOrHeight( elem, name, extra );\n\t\t\t\t\t});\n\t\t\t\t} else {\n\t\t\t\t\treturn getWidthOrHeight( elem, name, extra );\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\n\t\tset: function( elem, value, extra ) {\n\t\t\treturn setPositiveNumber( elem, value, extra ?\n\t\t\t\taugmentWidthOrHeight(\n\t\t\t\t\telem,\n\t\t\t\t\tname,\n\t\t\t\t\textra,\n\t\t\t\t\tjQuery.support.boxSizing && jQuery.css( elem, \"boxSizing\" ) === \"border-box\"\n\t\t\t\t) : 0\n\t\t\t);\n\t\t}\n\t};\n});\n\nif ( !jQuery.support.opacity ) {\n\tjQuery.cssHooks.opacity = {\n\t\tget: function( elem, computed ) {\n\t\t\t// IE uses filters for opacity\n\t\t\treturn ropacity.test( (computed && elem.currentStyle ? elem.currentStyle.filter : elem.style.filter) || \"\" ) ?\n\t\t\t\t( 0.01 * parseFloat( RegExp.$1 ) ) + \"\" :\n\t\t\t\tcomputed ? \"1\" : \"\";\n\t\t},\n\n\t\tset: function( elem, value ) {\n\t\t\tvar style = elem.style,\n\t\t\t\tcurrentStyle = elem.currentStyle,\n\t\t\t\topacity = jQuery.isNumeric( value ) ? \"alpha(opacity=\" + value * 100 + \")\" : \"\",\n\t\t\t\tfilter = currentStyle && currentStyle.filter || style.filter || \"\";\n\n\t\t\t// IE has trouble with opacity if it does not have layout\n\t\t\t// Force it by setting the zoom level\n\t\t\tstyle.zoom = 1;\n\n\t\t\t// if setting opacity to 1, and no other filters exist - attempt to remove filter attribute #6652\n\t\t\tif ( value >= 1 && jQuery.trim( filter.replace( ralpha, \"\" ) ) === \"\" &&\n\t\t\t\tstyle.removeAttribute ) {\n\n\t\t\t\t// Setting style.filter to null, \"\" & \" \" still leave \"filter:\" in the cssText\n\t\t\t\t// if \"filter:\" is present at all, clearType is disabled, we want to avoid this\n\t\t\t\t// style.removeAttribute is IE Only, but so apparently is this code path...\n\t\t\t\tstyle.removeAttribute( \"filter\" );\n\n\t\t\t\t// if there there is no filter style applied in a css rule, we are done\n\t\t\t\tif ( currentStyle && !currentStyle.filter ) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// otherwise, set new filter values\n\t\t\tstyle.filter = ralpha.test( filter ) ?\n\t\t\t\tfilter.replace( ralpha, opacity ) :\n\t\t\t\tfilter + \" \" + opacity;\n\t\t}\n\t};\n}\n\n// These hooks cannot be added until DOM ready because the support test\n// for it is not run until after DOM ready\njQuery(function() {\n\tif ( !jQuery.support.reliableMarginRight ) {\n\t\tjQuery.cssHooks.marginRight = {\n\t\t\tget: function( elem, computed ) {\n\t\t\t\t// WebKit Bug 13343 - getComputedStyle returns wrong value for margin-right\n\t\t\t\t// Work around by temporarily setting element display to inline-block\n\t\t\t\treturn jQuery.swap( elem, { \"display\": \"inline-block\" }, function() {\n\t\t\t\t\tif ( computed ) {\n\t\t\t\t\t\treturn curCSS( elem, \"marginRight\" );\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t}\n\t\t};\n\t}\n\n\t// Webkit bug: https://bugs.webkit.org/show_bug.cgi?id=29084\n\t// getComputedStyle returns percent when specified for top/left/bottom/right\n\t// rather than make the css module depend on the offset module, we just check for it here\n\tif ( !jQuery.support.pixelPosition && jQuery.fn.position ) {\n\t\tjQuery.each( [ \"top\", \"left\" ], function( i, prop ) {\n\t\t\tjQuery.cssHooks[ prop ] = {\n\t\t\t\tget: function( elem, computed ) {\n\t\t\t\t\tif ( computed ) {\n\t\t\t\t\t\tvar ret = curCSS( elem, prop );\n\t\t\t\t\t\t// if curCSS returns percentage, fallback to offset\n\t\t\t\t\t\treturn rnumnonpx.test( ret ) ? jQuery( elem ).position()[ prop ] + \"px\" : ret;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t};\n\t\t});\n\t}\n\n});\n\nif ( jQuery.expr && jQuery.expr.filters ) {\n\tjQuery.expr.filters.hidden = function( elem ) {\n\t\treturn ( elem.offsetWidth === 0 && elem.offsetHeight === 0 ) || (!jQuery.support.reliableHiddenOffsets && ((elem.style && elem.style.display) || curCSS( elem, \"display\" )) === \"none\");\n\t};\n\n\tjQuery.expr.filters.visible = function( elem ) {\n\t\treturn !jQuery.expr.filters.hidden( elem );\n\t};\n}\n\n// These hooks are used by animate to expand properties\njQuery.each({\n\tmargin: \"\",\n\tpadding: \"\",\n\tborder: \"Width\"\n}, function( prefix, suffix ) {\n\tjQuery.cssHooks[ prefix + suffix ] = {\n\t\texpand: function( value ) {\n\t\t\tvar i,\n\n\t\t\t\t// assumes a single number if not a string\n\t\t\t\tparts = typeof value === \"string\" ? value.split(\" \") : [ value ],\n\t\t\t\texpanded = {};\n\n\t\t\tfor ( i = 0; i < 4; i++ ) {\n\t\t\t\texpanded[ prefix + cssExpand[ i ] + suffix ] =\n\t\t\t\t\tparts[ i ] || parts[ i - 2 ] || parts[ 0 ];\n\t\t\t}\n\n\t\t\treturn expanded;\n\t\t}\n\t};\n\n\tif ( !rmargin.test( prefix ) ) {\n\t\tjQuery.cssHooks[ prefix + suffix ].set = setPositiveNumber;\n\t}\n});\nvar r20 = /%20/g,\n\trbracket = /\\[\\]$/,\n\trCRLF = /\\r?\\n/g,\n\trinput = /^(?:color|date|datetime|datetime-local|email|hidden|month|number|password|range|search|tel|text|time|url|week)$/i,\n\trselectTextarea = /^(?:select|textarea)/i;\n\njQuery.fn.extend({\n\tserialize: function() {\n\t\treturn jQuery.param( this.serializeArray() );\n\t},\n\tserializeArray: function() {\n\t\treturn this.map(function(){\n\t\t\treturn this.elements ? jQuery.makeArray( this.elements ) : this;\n\t\t})\n\t\t.filter(function(){\n\t\t\treturn this.name && !this.disabled &&\n\t\t\t\t( this.checked || rselectTextarea.test( this.nodeName ) ||\n\t\t\t\t\trinput.test( this.type ) );\n\t\t})\n\t\t.map(function( i, elem ){\n\t\t\tvar val = jQuery( this ).val();\n\n\t\t\treturn val == null ?\n\t\t\t\tnull :\n\t\t\t\tjQuery.isArray( val ) ?\n\t\t\t\t\tjQuery.map( val, function( val, i ){\n\t\t\t\t\t\treturn { name: elem.name, value: val.replace( rCRLF, \"\\r\\n\" ) };\n\t\t\t\t\t}) :\n\t\t\t\t\t{ name: elem.name, value: val.replace( rCRLF, \"\\r\\n\" ) };\n\t\t}).get();\n\t}\n});\n\n//Serialize an array of form elements or a set of\n//key/values into a query string\njQuery.param = function( a, traditional ) {\n\tvar prefix,\n\t\ts = [],\n\t\tadd = function( key, value ) {\n\t\t\t// If value is a function, invoke it and return its value\n\t\t\tvalue = jQuery.isFunction( value ) ? value() : ( value == null ? \"\" : value );\n\t\t\ts[ s.length ] = encodeURIComponent( key ) + \"=\" + encodeURIComponent( value );\n\t\t};\n\n\t// Set traditional to true for jQuery <= 1.3.2 behavior.\n\tif ( traditional === undefined ) {\n\t\ttraditional = jQuery.ajaxSettings && jQuery.ajaxSettings.traditional;\n\t}\n\n\t// If an array was passed in, assume that it is an array of form elements.\n\tif ( jQuery.isArray( a ) || ( a.jquery && !jQuery.isPlainObject( a ) ) ) {\n\t\t// Serialize the form elements\n\t\tjQuery.each( a, function() {\n\t\t\tadd( this.name, this.value );\n\t\t});\n\n\t} else {\n\t\t// If traditional, encode the \"old\" way (the way 1.3.2 or older\n\t\t// did it), otherwise encode params recursively.\n\t\tfor ( prefix in a ) {\n\t\t\tbuildParams( prefix, a[ prefix ], traditional, add );\n\t\t}\n\t}\n\n\t// Return the resulting serialization\n\treturn s.join( \"&\" ).replace( r20, \"+\" );\n};\n\nfunction buildParams( prefix, obj, traditional, add ) {\n\tvar name;\n\n\tif ( jQuery.isArray( obj ) ) {\n\t\t// Serialize array item.\n\t\tjQuery.each( obj, function( i, v ) {\n\t\t\tif ( traditional || rbracket.test( prefix ) ) {\n\t\t\t\t// Treat each array item as a scalar.\n\t\t\t\tadd( prefix, v );\n\n\t\t\t} else {\n\t\t\t\t// If array item is non-scalar (array or object), encode its\n\t\t\t\t// numeric index to resolve deserialization ambiguity issues.\n\t\t\t\t// Note that rack (as of 1.0.0) can't currently deserialize\n\t\t\t\t// nested arrays properly, and attempting to do so may cause\n\t\t\t\t// a server error. Possible fixes are to modify rack's\n\t\t\t\t// deserialization algorithm or to provide an option or flag\n\t\t\t\t// to force array serialization to be shallow.\n\t\t\t\tbuildParams( prefix + \"[\" + ( typeof v === \"object\" ? i : \"\" ) + \"]\", v, traditional, add );\n\t\t\t}\n\t\t});\n\n\t} else if ( !traditional && jQuery.type( obj ) === \"object\" ) {\n\t\t// Serialize object item.\n\t\tfor ( name in obj ) {\n\t\t\tbuildParams( prefix + \"[\" + name + \"]\", obj[ name ], traditional, add );\n\t\t}\n\n\t} else {\n\t\t// Serialize scalar item.\n\t\tadd( prefix, obj );\n\t}\n}\nvar\n\t// Document location\n\tajaxLocParts,\n\tajaxLocation,\n\n\trhash = /#.*$/,\n\trheaders = /^(.*?):[ \\t]*([^\\r\\n]*)\\r?$/mg, // IE leaves an \\r character at EOL\n\t// #7653, #8125, #8152: local protocol detection\n\trlocalProtocol = /^(?:about|app|app\\-storage|.+\\-extension|file|res|widget):$/,\n\trnoContent = /^(?:GET|HEAD)$/,\n\trprotocol = /^\\/\\//,\n\trquery = /\\?/,\n\trscript = /<script\\b[^<]*(?:(?!<\\/script>)<[^<]*)*<\\/script>/gi,\n\trts = /([?&])_=[^&]*/,\n\trurl = /^([\\w\\+\\.\\-]+:)(?:\\/\\/([^\\/?#:]*)(?::(\\d+)|)|)/,\n\n\t// Keep a copy of the old load method\n\t_load = jQuery.fn.load,\n\n\t/* Prefilters\n\t * 1) They are useful to introduce custom dataTypes (see ajax/jsonp.js for an example)\n\t * 2) These are called:\n\t *    - BEFORE asking for a transport\n\t *    - AFTER param serialization (s.data is a string if s.processData is true)\n\t * 3) key is the dataType\n\t * 4) the catchall symbol \"*\" can be used\n\t * 5) execution will start with transport dataType and THEN continue down to \"*\" if needed\n\t */\n\tprefilters = {},\n\n\t/* Transports bindings\n\t * 1) key is the dataType\n\t * 2) the catchall symbol \"*\" can be used\n\t * 3) selection will start with transport dataType and THEN go to \"*\" if needed\n\t */\n\ttransports = {},\n\n\t// Avoid comment-prolog char sequence (#10098); must appease lint and evade compression\n\tallTypes = [\"*/\"] + [\"*\"];\n\n// #8138, IE may throw an exception when accessing\n// a field from window.location if document.domain has been set\ntry {\n\tajaxLocation = location.href;\n} catch( e ) {\n\t// Use the href attribute of an A element\n\t// since IE will modify it given document.location\n\tajaxLocation = document.createElement( \"a\" );\n\tajaxLocation.href = \"\";\n\tajaxLocation = ajaxLocation.href;\n}\n\n// Segment location into parts\najaxLocParts = rurl.exec( ajaxLocation.toLowerCase() ) || [];\n\n// Base \"constructor\" for jQuery.ajaxPrefilter and jQuery.ajaxTransport\nfunction addToPrefiltersOrTransports( structure ) {\n\n\t// dataTypeExpression is optional and defaults to \"*\"\n\treturn function( dataTypeExpression, func ) {\n\n\t\tif ( typeof dataTypeExpression !== \"string\" ) {\n\t\t\tfunc = dataTypeExpression;\n\t\t\tdataTypeExpression = \"*\";\n\t\t}\n\n\t\tvar dataType, list, placeBefore,\n\t\t\tdataTypes = dataTypeExpression.toLowerCase().split( core_rspace ),\n\t\t\ti = 0,\n\t\t\tlength = dataTypes.length;\n\n\t\tif ( jQuery.isFunction( func ) ) {\n\t\t\t// For each dataType in the dataTypeExpression\n\t\t\tfor ( ; i < length; i++ ) {\n\t\t\t\tdataType = dataTypes[ i ];\n\t\t\t\t// We control if we're asked to add before\n\t\t\t\t// any existing element\n\t\t\t\tplaceBefore = /^\\+/.test( dataType );\n\t\t\t\tif ( placeBefore ) {\n\t\t\t\t\tdataType = dataType.substr( 1 ) || \"*\";\n\t\t\t\t}\n\t\t\t\tlist = structure[ dataType ] = structure[ dataType ] || [];\n\t\t\t\t// then we add to the structure accordingly\n\t\t\t\tlist[ placeBefore ? \"unshift\" : \"push\" ]( func );\n\t\t\t}\n\t\t}\n\t};\n}\n\n// Base inspection function for prefilters and transports\nfunction inspectPrefiltersOrTransports( structure, options, originalOptions, jqXHR,\n\t\tdataType /* internal */, inspected /* internal */ ) {\n\n\tdataType = dataType || options.dataTypes[ 0 ];\n\tinspected = inspected || {};\n\n\tinspected[ dataType ] = true;\n\n\tvar selection,\n\t\tlist = structure[ dataType ],\n\t\ti = 0,\n\t\tlength = list ? list.length : 0,\n\t\texecuteOnly = ( structure === prefilters );\n\n\tfor ( ; i < length && ( executeOnly || !selection ); i++ ) {\n\t\tselection = list[ i ]( options, originalOptions, jqXHR );\n\t\t// If we got redirected to another dataType\n\t\t// we try there if executing only and not done already\n\t\tif ( typeof selection === \"string\" ) {\n\t\t\tif ( !executeOnly || inspected[ selection ] ) {\n\t\t\t\tselection = undefined;\n\t\t\t} else {\n\t\t\t\toptions.dataTypes.unshift( selection );\n\t\t\t\tselection = inspectPrefiltersOrTransports(\n\t\t\t\t\t\tstructure, options, originalOptions, jqXHR, selection, inspected );\n\t\t\t}\n\t\t}\n\t}\n\t// If we're only executing or nothing was selected\n\t// we try the catchall dataType if not done already\n\tif ( ( executeOnly || !selection ) && !inspected[ \"*\" ] ) {\n\t\tselection = inspectPrefiltersOrTransports(\n\t\t\t\tstructure, options, originalOptions, jqXHR, \"*\", inspected );\n\t}\n\t// unnecessary when only executing (prefilters)\n\t// but it'll be ignored by the caller in that case\n\treturn selection;\n}\n\n// A special extend for ajax options\n// that takes \"flat\" options (not to be deep extended)\n// Fixes #9887\nfunction ajaxExtend( target, src ) {\n\tvar key, deep,\n\t\tflatOptions = jQuery.ajaxSettings.flatOptions || {};\n\tfor ( key in src ) {\n\t\tif ( src[ key ] !== undefined ) {\n\t\t\t( flatOptions[ key ] ? target : ( deep || ( deep = {} ) ) )[ key ] = src[ key ];\n\t\t}\n\t}\n\tif ( deep ) {\n\t\tjQuery.extend( true, target, deep );\n\t}\n}\n\njQuery.fn.load = function( url, params, callback ) {\n\tif ( typeof url !== \"string\" && _load ) {\n\t\treturn _load.apply( this, arguments );\n\t}\n\n\t// Don't do a request if no elements are being requested\n\tif ( !this.length ) {\n\t\treturn this;\n\t}\n\n\tvar selector, type, response,\n\t\tself = this,\n\t\toff = url.indexOf(\" \");\n\n\tif ( off >= 0 ) {\n\t\tselector = url.slice( off, url.length );\n\t\turl = url.slice( 0, off );\n\t}\n\n\t// If it's a function\n\tif ( jQuery.isFunction( params ) ) {\n\n\t\t// We assume that it's the callback\n\t\tcallback = params;\n\t\tparams = undefined;\n\n\t// Otherwise, build a param string\n\t} else if ( params && typeof params === \"object\" ) {\n\t\ttype = \"POST\";\n\t}\n\n\t// Request the remote document\n\tjQuery.ajax({\n\t\turl: url,\n\n\t\t// if \"type\" variable is undefined, then \"GET\" method will be used\n\t\ttype: type,\n\t\tdataType: \"html\",\n\t\tdata: params,\n\t\tcomplete: function( jqXHR, status ) {\n\t\t\tif ( callback ) {\n\t\t\t\tself.each( callback, response || [ jqXHR.responseText, status, jqXHR ] );\n\t\t\t}\n\t\t}\n\t}).done(function( responseText ) {\n\n\t\t// Save response for use in complete callback\n\t\tresponse = arguments;\n\n\t\t// See if a selector was specified\n\t\tself.html( selector ?\n\n\t\t\t// Create a dummy div to hold the results\n\t\t\tjQuery(\"<div>\")\n\n\t\t\t\t// inject the contents of the document in, removing the scripts\n\t\t\t\t// to avoid any 'Permission Denied' errors in IE\n\t\t\t\t.append( responseText.replace( rscript, \"\" ) )\n\n\t\t\t\t// Locate the specified elements\n\t\t\t\t.find( selector ) :\n\n\t\t\t// If not, just inject the full result\n\t\t\tresponseText );\n\n\t});\n\n\treturn this;\n};\n\n// Attach a bunch of functions for handling common AJAX events\njQuery.each( \"ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend\".split( \" \" ), function( i, o ){\n\tjQuery.fn[ o ] = function( f ){\n\t\treturn this.on( o, f );\n\t};\n});\n\njQuery.each( [ \"get\", \"post\" ], function( i, method ) {\n\tjQuery[ method ] = function( url, data, callback, type ) {\n\t\t// shift arguments if data argument was omitted\n\t\tif ( jQuery.isFunction( data ) ) {\n\t\t\ttype = type || callback;\n\t\t\tcallback = data;\n\t\t\tdata = undefined;\n\t\t}\n\n\t\treturn jQuery.ajax({\n\t\t\ttype: method,\n\t\t\turl: url,\n\t\t\tdata: data,\n\t\t\tsuccess: callback,\n\t\t\tdataType: type\n\t\t});\n\t};\n});\n\njQuery.extend({\n\n\tgetScript: function( url, callback ) {\n\t\treturn jQuery.get( url, undefined, callback, \"script\" );\n\t},\n\n\tgetJSON: function( url, data, callback ) {\n\t\treturn jQuery.get( url, data, callback, \"json\" );\n\t},\n\n\t// Creates a full fledged settings object into target\n\t// with both ajaxSettings and settings fields.\n\t// If target is omitted, writes into ajaxSettings.\n\tajaxSetup: function( target, settings ) {\n\t\tif ( settings ) {\n\t\t\t// Building a settings object\n\t\t\tajaxExtend( target, jQuery.ajaxSettings );\n\t\t} else {\n\t\t\t// Extending ajaxSettings\n\t\t\tsettings = target;\n\t\t\ttarget = jQuery.ajaxSettings;\n\t\t}\n\t\tajaxExtend( target, settings );\n\t\treturn target;\n\t},\n\n\tajaxSettings: {\n\t\turl: ajaxLocation,\n\t\tisLocal: rlocalProtocol.test( ajaxLocParts[ 1 ] ),\n\t\tglobal: true,\n\t\ttype: \"GET\",\n\t\tcontentType: \"application/x-www-form-urlencoded; charset=UTF-8\",\n\t\tprocessData: true,\n\t\tasync: true,\n\t\t/*\n\t\ttimeout: 0,\n\t\tdata: null,\n\t\tdataType: null,\n\t\tusername: null,\n\t\tpassword: null,\n\t\tcache: null,\n\t\tthrows: false,\n\t\ttraditional: false,\n\t\theaders: {},\n\t\t*/\n\n\t\taccepts: {\n\t\t\txml: \"application/xml, text/xml\",\n\t\t\thtml: \"text/html\",\n\t\t\ttext: \"text/plain\",\n\t\t\tjson: \"application/json, text/javascript\",\n\t\t\t\"*\": allTypes\n\t\t},\n\n\t\tcontents: {\n\t\t\txml: /xml/,\n\t\t\thtml: /html/,\n\t\t\tjson: /json/\n\t\t},\n\n\t\tresponseFields: {\n\t\t\txml: \"responseXML\",\n\t\t\ttext: \"responseText\"\n\t\t},\n\n\t\t// List of data converters\n\t\t// 1) key format is \"source_type destination_type\" (a single space in-between)\n\t\t// 2) the catchall symbol \"*\" can be used for source_type\n\t\tconverters: {\n\n\t\t\t// Convert anything to text\n\t\t\t\"* text\": window.String,\n\n\t\t\t// Text to html (true = no transformation)\n\t\t\t\"text html\": true,\n\n\t\t\t// Evaluate text as a json expression\n\t\t\t\"text json\": jQuery.parseJSON,\n\n\t\t\t// Parse text as xml\n\t\t\t\"text xml\": jQuery.parseXML\n\t\t},\n\n\t\t// For options that shouldn't be deep extended:\n\t\t// you can add your own custom options here if\n\t\t// and when you create one that shouldn't be\n\t\t// deep extended (see ajaxExtend)\n\t\tflatOptions: {\n\t\t\tcontext: true,\n\t\t\turl: true\n\t\t}\n\t},\n\n\tajaxPrefilter: addToPrefiltersOrTransports( prefilters ),\n\tajaxTransport: addToPrefiltersOrTransports( transports ),\n\n\t// Main method\n\tajax: function( url, options ) {\n\n\t\t// If url is an object, simulate pre-1.5 signature\n\t\tif ( typeof url === \"object\" ) {\n\t\t\toptions = url;\n\t\t\turl = undefined;\n\t\t}\n\n\t\t// Force options to be an object\n\t\toptions = options || {};\n\n\t\tvar // ifModified key\n\t\t\tifModifiedKey,\n\t\t\t// Response headers\n\t\t\tresponseHeadersString,\n\t\t\tresponseHeaders,\n\t\t\t// transport\n\t\t\ttransport,\n\t\t\t// timeout handle\n\t\t\ttimeoutTimer,\n\t\t\t// Cross-domain detection vars\n\t\t\tparts,\n\t\t\t// To know if global events are to be dispatched\n\t\t\tfireGlobals,\n\t\t\t// Loop variable\n\t\t\ti,\n\t\t\t// Create the final options object\n\t\t\ts = jQuery.ajaxSetup( {}, options ),\n\t\t\t// Callbacks context\n\t\t\tcallbackContext = s.context || s,\n\t\t\t// Context for global events\n\t\t\t// It's the callbackContext if one was provided in the options\n\t\t\t// and if it's a DOM node or a jQuery collection\n\t\t\tglobalEventContext = callbackContext !== s &&\n\t\t\t\t( callbackContext.nodeType || callbackContext instanceof jQuery ) ?\n\t\t\t\t\t\tjQuery( callbackContext ) : jQuery.event,\n\t\t\t// Deferreds\n\t\t\tdeferred = jQuery.Deferred(),\n\t\t\tcompleteDeferred = jQuery.Callbacks( \"once memory\" ),\n\t\t\t// Status-dependent callbacks\n\t\t\tstatusCode = s.statusCode || {},\n\t\t\t// Headers (they are sent all at once)\n\t\t\trequestHeaders = {},\n\t\t\trequestHeadersNames = {},\n\t\t\t// The jqXHR state\n\t\t\tstate = 0,\n\t\t\t// Default abort message\n\t\t\tstrAbort = \"canceled\",\n\t\t\t// Fake xhr\n\t\t\tjqXHR = {\n\n\t\t\t\treadyState: 0,\n\n\t\t\t\t// Caches the header\n\t\t\t\tsetRequestHeader: function( name, value ) {\n\t\t\t\t\tif ( !state ) {\n\t\t\t\t\t\tvar lname = name.toLowerCase();\n\t\t\t\t\t\tname = requestHeadersNames[ lname ] = requestHeadersNames[ lname ] || name;\n\t\t\t\t\t\trequestHeaders[ name ] = value;\n\t\t\t\t\t}\n\t\t\t\t\treturn this;\n\t\t\t\t},\n\n\t\t\t\t// Raw string\n\t\t\t\tgetAllResponseHeaders: function() {\n\t\t\t\t\treturn state === 2 ? responseHeadersString : null;\n\t\t\t\t},\n\n\t\t\t\t// Builds headers hashtable if needed\n\t\t\t\tgetResponseHeader: function( key ) {\n\t\t\t\t\tvar match;\n\t\t\t\t\tif ( state === 2 ) {\n\t\t\t\t\t\tif ( !responseHeaders ) {\n\t\t\t\t\t\t\tresponseHeaders = {};\n\t\t\t\t\t\t\twhile( ( match = rheaders.exec( responseHeadersString ) ) ) {\n\t\t\t\t\t\t\t\tresponseHeaders[ match[1].toLowerCase() ] = match[ 2 ];\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\tmatch = responseHeaders[ key.toLowerCase() ];\n\t\t\t\t\t}\n\t\t\t\t\treturn match === undefined ? null : match;\n\t\t\t\t},\n\n\t\t\t\t// Overrides response content-type header\n\t\t\t\toverrideMimeType: function( type ) {\n\t\t\t\t\tif ( !state ) {\n\t\t\t\t\t\ts.mimeType = type;\n\t\t\t\t\t}\n\t\t\t\t\treturn this;\n\t\t\t\t},\n\n\t\t\t\t// Cancel the request\n\t\t\t\tabort: function( statusText ) {\n\t\t\t\t\tstatusText = statusText || strAbort;\n\t\t\t\t\tif ( transport ) {\n\t\t\t\t\t\ttransport.abort( statusText );\n\t\t\t\t\t}\n\t\t\t\t\tdone( 0, statusText );\n\t\t\t\t\treturn this;\n\t\t\t\t}\n\t\t\t};\n\n\t\t// Callback for when everything is done\n\t\t// It is defined here because jslint complains if it is declared\n\t\t// at the end of the function (which would be more logical and readable)\n\t\tfunction done( status, nativeStatusText, responses, headers ) {\n\t\t\tvar isSuccess, success, error, response, modified,\n\t\t\t\tstatusText = nativeStatusText;\n\n\t\t\t// Called once\n\t\t\tif ( state === 2 ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// State is \"done\" now\n\t\t\tstate = 2;\n\n\t\t\t// Clear timeout if it exists\n\t\t\tif ( timeoutTimer ) {\n\t\t\t\tclearTimeout( timeoutTimer );\n\t\t\t}\n\n\t\t\t// Dereference transport for early garbage collection\n\t\t\t// (no matter how long the jqXHR object will be used)\n\t\t\ttransport = undefined;\n\n\t\t\t// Cache response headers\n\t\t\tresponseHeadersString = headers || \"\";\n\n\t\t\t// Set readyState\n\t\t\tjqXHR.readyState = status > 0 ? 4 : 0;\n\n\t\t\t// Get response data\n\t\t\tif ( responses ) {\n\t\t\t\tresponse = ajaxHandleResponses( s, jqXHR, responses );\n\t\t\t}\n\n\t\t\t// If successful, handle type chaining\n\t\t\tif ( status >= 200 && status < 300 || status === 304 ) {\n\n\t\t\t\t// Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.\n\t\t\t\tif ( s.ifModified ) {\n\n\t\t\t\t\tmodified = jqXHR.getResponseHeader(\"Last-Modified\");\n\t\t\t\t\tif ( modified ) {\n\t\t\t\t\t\tjQuery.lastModified[ ifModifiedKey ] = modified;\n\t\t\t\t\t}\n\t\t\t\t\tmodified = jqXHR.getResponseHeader(\"Etag\");\n\t\t\t\t\tif ( modified ) {\n\t\t\t\t\t\tjQuery.etag[ ifModifiedKey ] = modified;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// If not modified\n\t\t\t\tif ( status === 304 ) {\n\n\t\t\t\t\tstatusText = \"notmodified\";\n\t\t\t\t\tisSuccess = true;\n\n\t\t\t\t// If we have data\n\t\t\t\t} else {\n\n\t\t\t\t\tisSuccess = ajaxConvert( s, response );\n\t\t\t\t\tstatusText = isSuccess.state;\n\t\t\t\t\tsuccess = isSuccess.data;\n\t\t\t\t\terror = isSuccess.error;\n\t\t\t\t\tisSuccess = !error;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t// We extract error from statusText\n\t\t\t\t// then normalize statusText and status for non-aborts\n\t\t\t\terror = statusText;\n\t\t\t\tif ( !statusText || status ) {\n\t\t\t\t\tstatusText = \"error\";\n\t\t\t\t\tif ( status < 0 ) {\n\t\t\t\t\t\tstatus = 0;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Set data for the fake xhr object\n\t\t\tjqXHR.status = status;\n\t\t\tjqXHR.statusText = ( nativeStatusText || statusText ) + \"\";\n\n\t\t\t// Success/Error\n\t\t\tif ( isSuccess ) {\n\t\t\t\tdeferred.resolveWith( callbackContext, [ success, statusText, jqXHR ] );\n\t\t\t} else {\n\t\t\t\tdeferred.rejectWith( callbackContext, [ jqXHR, statusText, error ] );\n\t\t\t}\n\n\t\t\t// Status-dependent callbacks\n\t\t\tjqXHR.statusCode( statusCode );\n\t\t\tstatusCode = undefined;\n\n\t\t\tif ( fireGlobals ) {\n\t\t\t\tglobalEventContext.trigger( \"ajax\" + ( isSuccess ? \"Success\" : \"Error\" ),\n\t\t\t\t\t\t[ jqXHR, s, isSuccess ? success : error ] );\n\t\t\t}\n\n\t\t\t// Complete\n\t\t\tcompleteDeferred.fireWith( callbackContext, [ jqXHR, statusText ] );\n\n\t\t\tif ( fireGlobals ) {\n\t\t\t\tglobalEventContext.trigger( \"ajaxComplete\", [ jqXHR, s ] );\n\t\t\t\t// Handle the global AJAX counter\n\t\t\t\tif ( !( --jQuery.active ) ) {\n\t\t\t\t\tjQuery.event.trigger( \"ajaxStop\" );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Attach deferreds\n\t\tdeferred.promise( jqXHR );\n\t\tjqXHR.success = jqXHR.done;\n\t\tjqXHR.error = jqXHR.fail;\n\t\tjqXHR.complete = completeDeferred.add;\n\n\t\t// Status-dependent callbacks\n\t\tjqXHR.statusCode = function( map ) {\n\t\t\tif ( map ) {\n\t\t\t\tvar tmp;\n\t\t\t\tif ( state < 2 ) {\n\t\t\t\t\tfor ( tmp in map ) {\n\t\t\t\t\t\tstatusCode[ tmp ] = [ statusCode[tmp], map[tmp] ];\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\ttmp = map[ jqXHR.status ];\n\t\t\t\t\tjqXHR.always( tmp );\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn this;\n\t\t};\n\n\t\t// Remove hash character (#7531: and string promotion)\n\t\t// Add protocol if not provided (#5866: IE7 issue with protocol-less urls)\n\t\t// We also use the url parameter if available\n\t\ts.url = ( ( url || s.url ) + \"\" ).replace( rhash, \"\" ).replace( rprotocol, ajaxLocParts[ 1 ] + \"//\" );\n\n\t\t// Extract dataTypes list\n\t\ts.dataTypes = jQuery.trim( s.dataType || \"*\" ).toLowerCase().split( core_rspace );\n\n\t\t// A cross-domain request is in order when we have a protocol:host:port mismatch\n\t\tif ( s.crossDomain == null ) {\n\t\t\tparts = rurl.exec( s.url.toLowerCase() );\n\t\t\ts.crossDomain = !!( parts &&\n\t\t\t\t( parts[ 1 ] !== ajaxLocParts[ 1 ] || parts[ 2 ] !== ajaxLocParts[ 2 ] ||\n\t\t\t\t\t( parts[ 3 ] || ( parts[ 1 ] === \"http:\" ? 80 : 443 ) ) !=\n\t\t\t\t\t\t( ajaxLocParts[ 3 ] || ( ajaxLocParts[ 1 ] === \"http:\" ? 80 : 443 ) ) )\n\t\t\t);\n\t\t}\n\n\t\t// Convert data if not already a string\n\t\tif ( s.data && s.processData && typeof s.data !== \"string\" ) {\n\t\t\ts.data = jQuery.param( s.data, s.traditional );\n\t\t}\n\n\t\t// Apply prefilters\n\t\tinspectPrefiltersOrTransports( prefilters, s, options, jqXHR );\n\n\t\t// If request was aborted inside a prefilter, stop there\n\t\tif ( state === 2 ) {\n\t\t\treturn jqXHR;\n\t\t}\n\n\t\t// We can fire global events as of now if asked to\n\t\tfireGlobals = s.global;\n\n\t\t// Uppercase the type\n\t\ts.type = s.type.toUpperCase();\n\n\t\t// Determine if request has content\n\t\ts.hasContent = !rnoContent.test( s.type );\n\n\t\t// Watch for a new set of requests\n\t\tif ( fireGlobals && jQuery.active++ === 0 ) {\n\t\t\tjQuery.event.trigger( \"ajaxStart\" );\n\t\t}\n\n\t\t// More options handling for requests with no content\n\t\tif ( !s.hasContent ) {\n\n\t\t\t// If data is available, append data to url\n\t\t\tif ( s.data ) {\n\t\t\t\ts.url += ( rquery.test( s.url ) ? \"&\" : \"?\" ) + s.data;\n\t\t\t\t// #9682: remove data so that it's not used in an eventual retry\n\t\t\t\tdelete s.data;\n\t\t\t}\n\n\t\t\t// Get ifModifiedKey before adding the anti-cache parameter\n\t\t\tifModifiedKey = s.url;\n\n\t\t\t// Add anti-cache in url if needed\n\t\t\tif ( s.cache === false ) {\n\n\t\t\t\tvar ts = jQuery.now(),\n\t\t\t\t\t// try replacing _= if it is there\n\t\t\t\t\tret = s.url.replace( rts, \"$1_=\" + ts );\n\n\t\t\t\t// if nothing was replaced, add timestamp to the end\n\t\t\t\ts.url = ret + ( ( ret === s.url ) ? ( rquery.test( s.url ) ? \"&\" : \"?\" ) + \"_=\" + ts : \"\" );\n\t\t\t}\n\t\t}\n\n\t\t// Set the correct header, if data is being sent\n\t\tif ( s.data && s.hasContent && s.contentType !== false || options.contentType ) {\n\t\t\tjqXHR.setRequestHeader( \"Content-Type\", s.contentType );\n\t\t}\n\n\t\t// Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.\n\t\tif ( s.ifModified ) {\n\t\t\tifModifiedKey = ifModifiedKey || s.url;\n\t\t\tif ( jQuery.lastModified[ ifModifiedKey ] ) {\n\t\t\t\tjqXHR.setRequestHeader( \"If-Modified-Since\", jQuery.lastModified[ ifModifiedKey ] );\n\t\t\t}\n\t\t\tif ( jQuery.etag[ ifModifiedKey ] ) {\n\t\t\t\tjqXHR.setRequestHeader( \"If-None-Match\", jQuery.etag[ ifModifiedKey ] );\n\t\t\t}\n\t\t}\n\n\t\t// Set the Accepts header for the server, depending on the dataType\n\t\tjqXHR.setRequestHeader(\n\t\t\t\"Accept\",\n\t\t\ts.dataTypes[ 0 ] && s.accepts[ s.dataTypes[0] ] ?\n\t\t\t\ts.accepts[ s.dataTypes[0] ] + ( s.dataTypes[ 0 ] !== \"*\" ? \", \" + allTypes + \"; q=0.01\" : \"\" ) :\n\t\t\t\ts.accepts[ \"*\" ]\n\t\t);\n\n\t\t// Check for headers option\n\t\tfor ( i in s.headers ) {\n\t\t\tjqXHR.setRequestHeader( i, s.headers[ i ] );\n\t\t}\n\n\t\t// Allow custom headers/mimetypes and early abort\n\t\tif ( s.beforeSend && ( s.beforeSend.call( callbackContext, jqXHR, s ) === false || state === 2 ) ) {\n\t\t\t\t// Abort if not done already and return\n\t\t\t\treturn jqXHR.abort();\n\n\t\t}\n\n\t\t// aborting is no longer a cancellation\n\t\tstrAbort = \"abort\";\n\n\t\t// Install callbacks on deferreds\n\t\tfor ( i in { success: 1, error: 1, complete: 1 } ) {\n\t\t\tjqXHR[ i ]( s[ i ] );\n\t\t}\n\n\t\t// Get transport\n\t\ttransport = inspectPrefiltersOrTransports( transports, s, options, jqXHR );\n\n\t\t// If no transport, we auto-abort\n\t\tif ( !transport ) {\n\t\t\tdone( -1, \"No Transport\" );\n\t\t} else {\n\t\t\tjqXHR.readyState = 1;\n\t\t\t// Send global event\n\t\t\tif ( fireGlobals ) {\n\t\t\t\tglobalEventContext.trigger( \"ajaxSend\", [ jqXHR, s ] );\n\t\t\t}\n\t\t\t// Timeout\n\t\t\tif ( s.async && s.timeout > 0 ) {\n\t\t\t\ttimeoutTimer = setTimeout( function(){\n\t\t\t\t\tjqXHR.abort( \"timeout\" );\n\t\t\t\t}, s.timeout );\n\t\t\t}\n\n\t\t\ttry {\n\t\t\t\tstate = 1;\n\t\t\t\ttransport.send( requestHeaders, done );\n\t\t\t} catch (e) {\n\t\t\t\t// Propagate exception as error if not done\n\t\t\t\tif ( state < 2 ) {\n\t\t\t\t\tdone( -1, e );\n\t\t\t\t// Simply rethrow otherwise\n\t\t\t\t} else {\n\t\t\t\t\tthrow e;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn jqXHR;\n\t},\n\n\t// Counter for holding the number of active queries\n\tactive: 0,\n\n\t// Last-Modified header cache for next request\n\tlastModified: {},\n\tetag: {}\n\n});\n\n/* Handles responses to an ajax request:\n * - sets all responseXXX fields accordingly\n * - finds the right dataType (mediates between content-type and expected dataType)\n * - returns the corresponding response\n */\nfunction ajaxHandleResponses( s, jqXHR, responses ) {\n\n\tvar ct, type, finalDataType, firstDataType,\n\t\tcontents = s.contents,\n\t\tdataTypes = s.dataTypes,\n\t\tresponseFields = s.responseFields;\n\n\t// Fill responseXXX fields\n\tfor ( type in responseFields ) {\n\t\tif ( type in responses ) {\n\t\t\tjqXHR[ responseFields[type] ] = responses[ type ];\n\t\t}\n\t}\n\n\t// Remove auto dataType and get content-type in the process\n\twhile( dataTypes[ 0 ] === \"*\" ) {\n\t\tdataTypes.shift();\n\t\tif ( ct === undefined ) {\n\t\t\tct = s.mimeType || jqXHR.getResponseHeader( \"content-type\" );\n\t\t}\n\t}\n\n\t// Check if we're dealing with a known content-type\n\tif ( ct ) {\n\t\tfor ( type in contents ) {\n\t\t\tif ( contents[ type ] && contents[ type ].test( ct ) ) {\n\t\t\t\tdataTypes.unshift( type );\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t}\n\n\t// Check to see if we have a response for the expected dataType\n\tif ( dataTypes[ 0 ] in responses ) {\n\t\tfinalDataType = dataTypes[ 0 ];\n\t} else {\n\t\t// Try convertible dataTypes\n\t\tfor ( type in responses ) {\n\t\t\tif ( !dataTypes[ 0 ] || s.converters[ type + \" \" + dataTypes[0] ] ) {\n\t\t\t\tfinalDataType = type;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tif ( !firstDataType ) {\n\t\t\t\tfirstDataType = type;\n\t\t\t}\n\t\t}\n\t\t// Or just use first one\n\t\tfinalDataType = finalDataType || firstDataType;\n\t}\n\n\t// If we found a dataType\n\t// We add the dataType to the list if needed\n\t// and return the corresponding response\n\tif ( finalDataType ) {\n\t\tif ( finalDataType !== dataTypes[ 0 ] ) {\n\t\t\tdataTypes.unshift( finalDataType );\n\t\t}\n\t\treturn responses[ finalDataType ];\n\t}\n}\n\n// Chain conversions given the request and the original response\nfunction ajaxConvert( s, response ) {\n\n\tvar conv, conv2, current, tmp,\n\t\t// Work with a copy of dataTypes in case we need to modify it for conversion\n\t\tdataTypes = s.dataTypes.slice(),\n\t\tprev = dataTypes[ 0 ],\n\t\tconverters = {},\n\t\ti = 0;\n\n\t// Apply the dataFilter if provided\n\tif ( s.dataFilter ) {\n\t\tresponse = s.dataFilter( response, s.dataType );\n\t}\n\n\t// Create converters map with lowercased keys\n\tif ( dataTypes[ 1 ] ) {\n\t\tfor ( conv in s.converters ) {\n\t\t\tconverters[ conv.toLowerCase() ] = s.converters[ conv ];\n\t\t}\n\t}\n\n\t// Convert to each sequential dataType, tolerating list modification\n\tfor ( ; (current = dataTypes[++i]); ) {\n\n\t\t// There's only work to do if current dataType is non-auto\n\t\tif ( current !== \"*\" ) {\n\n\t\t\t// Convert response if prev dataType is non-auto and differs from current\n\t\t\tif ( prev !== \"*\" && prev !== current ) {\n\n\t\t\t\t// Seek a direct converter\n\t\t\t\tconv = converters[ prev + \" \" + current ] || converters[ \"* \" + current ];\n\n\t\t\t\t// If none found, seek a pair\n\t\t\t\tif ( !conv ) {\n\t\t\t\t\tfor ( conv2 in converters ) {\n\n\t\t\t\t\t\t// If conv2 outputs current\n\t\t\t\t\t\ttmp = conv2.split(\" \");\n\t\t\t\t\t\tif ( tmp[ 1 ] === current ) {\n\n\t\t\t\t\t\t\t// If prev can be converted to accepted input\n\t\t\t\t\t\t\tconv = converters[ prev + \" \" + tmp[ 0 ] ] ||\n\t\t\t\t\t\t\t\tconverters[ \"* \" + tmp[ 0 ] ];\n\t\t\t\t\t\t\tif ( conv ) {\n\t\t\t\t\t\t\t\t// Condense equivalence converters\n\t\t\t\t\t\t\t\tif ( conv === true ) {\n\t\t\t\t\t\t\t\t\tconv = converters[ conv2 ];\n\n\t\t\t\t\t\t\t\t// Otherwise, insert the intermediate dataType\n\t\t\t\t\t\t\t\t} else if ( converters[ conv2 ] !== true ) {\n\t\t\t\t\t\t\t\t\tcurrent = tmp[ 0 ];\n\t\t\t\t\t\t\t\t\tdataTypes.splice( i--, 0, current );\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// Apply converter (if not an equivalence)\n\t\t\t\tif ( conv !== true ) {\n\n\t\t\t\t\t// Unless errors are allowed to bubble, catch and return them\n\t\t\t\t\tif ( conv && s[\"throws\"] ) {\n\t\t\t\t\t\tresponse = conv( response );\n\t\t\t\t\t} else {\n\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\tresponse = conv( response );\n\t\t\t\t\t\t} catch ( e ) {\n\t\t\t\t\t\t\treturn { state: \"parsererror\", error: conv ? e : \"No conversion from \" + prev + \" to \" + current };\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Update prev for next iteration\n\t\t\tprev = current;\n\t\t}\n\t}\n\n\treturn { state: \"success\", data: response };\n}\nvar oldCallbacks = [],\n\trquestion = /\\?/,\n\trjsonp = /(=)\\?(?=&|$)|\\?\\?/,\n\tnonce = jQuery.now();\n\n// Default jsonp settings\njQuery.ajaxSetup({\n\tjsonp: \"callback\",\n\tjsonpCallback: function() {\n\t\tvar callback = oldCallbacks.pop() || ( jQuery.expando + \"_\" + ( nonce++ ) );\n\t\tthis[ callback ] = true;\n\t\treturn callback;\n\t}\n});\n\n// Detect, normalize options and install callbacks for jsonp requests\njQuery.ajaxPrefilter( \"json jsonp\", function( s, originalSettings, jqXHR ) {\n\n\tvar callbackName, overwritten, responseContainer,\n\t\tdata = s.data,\n\t\turl = s.url,\n\t\thasCallback = s.jsonp !== false,\n\t\treplaceInUrl = hasCallback && rjsonp.test( url ),\n\t\treplaceInData = hasCallback && !replaceInUrl && typeof data === \"string\" &&\n\t\t\t!( s.contentType || \"\" ).indexOf(\"application/x-www-form-urlencoded\") &&\n\t\t\trjsonp.test( data );\n\n\t// Handle iff the expected data type is \"jsonp\" or we have a parameter to set\n\tif ( s.dataTypes[ 0 ] === \"jsonp\" || replaceInUrl || replaceInData ) {\n\n\t\t// Get callback name, remembering preexisting value associated with it\n\t\tcallbackName = s.jsonpCallback = jQuery.isFunction( s.jsonpCallback ) ?\n\t\t\ts.jsonpCallback() :\n\t\t\ts.jsonpCallback;\n\t\toverwritten = window[ callbackName ];\n\n\t\t// Insert callback into url or form data\n\t\tif ( replaceInUrl ) {\n\t\t\ts.url = url.replace( rjsonp, \"$1\" + callbackName );\n\t\t} else if ( replaceInData ) {\n\t\t\ts.data = data.replace( rjsonp, \"$1\" + callbackName );\n\t\t} else if ( hasCallback ) {\n\t\t\ts.url += ( rquestion.test( url ) ? \"&\" : \"?\" ) + s.jsonp + \"=\" + callbackName;\n\t\t}\n\n\t\t// Use data converter to retrieve json after script execution\n\t\ts.converters[\"script json\"] = function() {\n\t\t\tif ( !responseContainer ) {\n\t\t\t\tjQuery.error( callbackName + \" was not called\" );\n\t\t\t}\n\t\t\treturn responseContainer[ 0 ];\n\t\t};\n\n\t\t// force json dataType\n\t\ts.dataTypes[ 0 ] = \"json\";\n\n\t\t// Install callback\n\t\twindow[ callbackName ] = function() {\n\t\t\tresponseContainer = arguments;\n\t\t};\n\n\t\t// Clean-up function (fires after converters)\n\t\tjqXHR.always(function() {\n\t\t\t// Restore preexisting value\n\t\t\twindow[ callbackName ] = overwritten;\n\n\t\t\t// Save back as free\n\t\t\tif ( s[ callbackName ] ) {\n\t\t\t\t// make sure that re-using the options doesn't screw things around\n\t\t\t\ts.jsonpCallback = originalSettings.jsonpCallback;\n\n\t\t\t\t// save the callback name for future use\n\t\t\t\toldCallbacks.push( callbackName );\n\t\t\t}\n\n\t\t\t// Call if it was a function and we have a response\n\t\t\tif ( responseContainer && jQuery.isFunction( overwritten ) ) {\n\t\t\t\toverwritten( responseContainer[ 0 ] );\n\t\t\t}\n\n\t\t\tresponseContainer = overwritten = undefined;\n\t\t});\n\n\t\t// Delegate to script\n\t\treturn \"script\";\n\t}\n});\n// Install script dataType\njQuery.ajaxSetup({\n\taccepts: {\n\t\tscript: \"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript\"\n\t},\n\tcontents: {\n\t\tscript: /javascript|ecmascript/\n\t},\n\tconverters: {\n\t\t\"text script\": function( text ) {\n\t\t\tjQuery.globalEval( text );\n\t\t\treturn text;\n\t\t}\n\t}\n});\n\n// Handle cache's special case and global\njQuery.ajaxPrefilter( \"script\", function( s ) {\n\tif ( s.cache === undefined ) {\n\t\ts.cache = false;\n\t}\n\tif ( s.crossDomain ) {\n\t\ts.type = \"GET\";\n\t\ts.global = false;\n\t}\n});\n\n// Bind script tag hack transport\njQuery.ajaxTransport( \"script\", function(s) {\n\n\t// This transport only deals with cross domain requests\n\tif ( s.crossDomain ) {\n\n\t\tvar script,\n\t\t\thead = document.head || document.getElementsByTagName( \"head\" )[0] || document.documentElement;\n\n\t\treturn {\n\n\t\t\tsend: function( _, callback ) {\n\n\t\t\t\tscript = document.createElement( \"script\" );\n\n\t\t\t\tscript.async = \"async\";\n\n\t\t\t\tif ( s.scriptCharset ) {\n\t\t\t\t\tscript.charset = s.scriptCharset;\n\t\t\t\t}\n\n\t\t\t\tscript.src = s.url;\n\n\t\t\t\t// Attach handlers for all browsers\n\t\t\t\tscript.onload = script.onreadystatechange = function( _, isAbort ) {\n\n\t\t\t\t\tif ( isAbort || !script.readyState || /loaded|complete/.test( script.readyState ) ) {\n\n\t\t\t\t\t\t// Handle memory leak in IE\n\t\t\t\t\t\tscript.onload = script.onreadystatechange = null;\n\n\t\t\t\t\t\t// Remove the script\n\t\t\t\t\t\tif ( head && script.parentNode ) {\n\t\t\t\t\t\t\thead.removeChild( script );\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// Dereference the script\n\t\t\t\t\t\tscript = undefined;\n\n\t\t\t\t\t\t// Callback if not abort\n\t\t\t\t\t\tif ( !isAbort ) {\n\t\t\t\t\t\t\tcallback( 200, \"success\" );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t};\n\t\t\t\t// Use insertBefore instead of appendChild  to circumvent an IE6 bug.\n\t\t\t\t// This arises when a base node is used (#2709 and #4378).\n\t\t\t\thead.insertBefore( script, head.firstChild );\n\t\t\t},\n\n\t\t\tabort: function() {\n\t\t\t\tif ( script ) {\n\t\t\t\t\tscript.onload( 0, 1 );\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\t}\n});\nvar xhrCallbacks,\n\t// #5280: Internet Explorer will keep connections alive if we don't abort on unload\n\txhrOnUnloadAbort = window.ActiveXObject ? function() {\n\t\t// Abort all pending requests\n\t\tfor ( var key in xhrCallbacks ) {\n\t\t\txhrCallbacks[ key ]( 0, 1 );\n\t\t}\n\t} : false,\n\txhrId = 0;\n\n// Functions to create xhrs\nfunction createStandardXHR() {\n\ttry {\n\t\treturn new window.XMLHttpRequest();\n\t} catch( e ) {}\n}\n\nfunction createActiveXHR() {\n\ttry {\n\t\treturn new window.ActiveXObject( \"Microsoft.XMLHTTP\" );\n\t} catch( e ) {}\n}\n\n// Create the request object\n// (This is still attached to ajaxSettings for backward compatibility)\njQuery.ajaxSettings.xhr = window.ActiveXObject ?\n\t/* Microsoft failed to properly\n\t * implement the XMLHttpRequest in IE7 (can't request local files),\n\t * so we use the ActiveXObject when it is available\n\t * Additionally XMLHttpRequest can be disabled in IE7/IE8 so\n\t * we need a fallback.\n\t */\n\tfunction() {\n\t\treturn !this.isLocal && createStandardXHR() || createActiveXHR();\n\t} :\n\t// For all other browsers, use the standard XMLHttpRequest object\n\tcreateStandardXHR;\n\n// Determine support properties\n(function( xhr ) {\n\tjQuery.extend( jQuery.support, {\n\t\tajax: !!xhr,\n\t\tcors: !!xhr && ( \"withCredentials\" in xhr )\n\t});\n})( jQuery.ajaxSettings.xhr() );\n\n// Create transport if the browser can provide an xhr\nif ( jQuery.support.ajax ) {\n\n\tjQuery.ajaxTransport(function( s ) {\n\t\t// Cross domain only allowed if supported through XMLHttpRequest\n\t\tif ( !s.crossDomain || jQuery.support.cors ) {\n\n\t\t\tvar callback;\n\n\t\t\treturn {\n\t\t\t\tsend: function( headers, complete ) {\n\n\t\t\t\t\t// Get a new xhr\n\t\t\t\t\tvar handle, i,\n\t\t\t\t\t\txhr = s.xhr();\n\n\t\t\t\t\t// Open the socket\n\t\t\t\t\t// Passing null username, generates a login popup on Opera (#2865)\n\t\t\t\t\tif ( s.username ) {\n\t\t\t\t\t\txhr.open( s.type, s.url, s.async, s.username, s.password );\n\t\t\t\t\t} else {\n\t\t\t\t\t\txhr.open( s.type, s.url, s.async );\n\t\t\t\t\t}\n\n\t\t\t\t\t// Apply custom fields if provided\n\t\t\t\t\tif ( s.xhrFields ) {\n\t\t\t\t\t\tfor ( i in s.xhrFields ) {\n\t\t\t\t\t\t\txhr[ i ] = s.xhrFields[ i ];\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\t// Override mime type if needed\n\t\t\t\t\tif ( s.mimeType && xhr.overrideMimeType ) {\n\t\t\t\t\t\txhr.overrideMimeType( s.mimeType );\n\t\t\t\t\t}\n\n\t\t\t\t\t// X-Requested-With header\n\t\t\t\t\t// For cross-domain requests, seeing as conditions for a preflight are\n\t\t\t\t\t// akin to a jigsaw puzzle, we simply never set it to be sure.\n\t\t\t\t\t// (it can always be set on a per-request basis or even using ajaxSetup)\n\t\t\t\t\t// For same-domain requests, won't change header if already provided.\n\t\t\t\t\tif ( !s.crossDomain && !headers[\"X-Requested-With\"] ) {\n\t\t\t\t\t\theaders[ \"X-Requested-With\" ] = \"XMLHttpRequest\";\n\t\t\t\t\t}\n\n\t\t\t\t\t// Need an extra try/catch for cross domain requests in Firefox 3\n\t\t\t\t\ttry {\n\t\t\t\t\t\tfor ( i in headers ) {\n\t\t\t\t\t\t\txhr.setRequestHeader( i, headers[ i ] );\n\t\t\t\t\t\t}\n\t\t\t\t\t} catch( _ ) {}\n\n\t\t\t\t\t// Do send the request\n\t\t\t\t\t// This may raise an exception which is actually\n\t\t\t\t\t// handled in jQuery.ajax (so no try/catch here)\n\t\t\t\t\txhr.send( ( s.hasContent && s.data ) || null );\n\n\t\t\t\t\t// Listener\n\t\t\t\t\tcallback = function( _, isAbort ) {\n\n\t\t\t\t\t\tvar status,\n\t\t\t\t\t\t\tstatusText,\n\t\t\t\t\t\t\tresponseHeaders,\n\t\t\t\t\t\t\tresponses,\n\t\t\t\t\t\t\txml;\n\n\t\t\t\t\t\t// Firefox throws exceptions when accessing properties\n\t\t\t\t\t\t// of an xhr when a network error occurred\n\t\t\t\t\t\t// http://helpful.knobs-dials.com/index.php/Component_returned_failure_code:_0x80040111_(NS_ERROR_NOT_AVAILABLE)\n\t\t\t\t\t\ttry {\n\n\t\t\t\t\t\t\t// Was never called and is aborted or complete\n\t\t\t\t\t\t\tif ( callback && ( isAbort || xhr.readyState === 4 ) ) {\n\n\t\t\t\t\t\t\t\t// Only called once\n\t\t\t\t\t\t\t\tcallback = undefined;\n\n\t\t\t\t\t\t\t\t// Do not keep as active anymore\n\t\t\t\t\t\t\t\tif ( handle ) {\n\t\t\t\t\t\t\t\t\txhr.onreadystatechange = jQuery.noop;\n\t\t\t\t\t\t\t\t\tif ( xhrOnUnloadAbort ) {\n\t\t\t\t\t\t\t\t\t\tdelete xhrCallbacks[ handle ];\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t// If it's an abort\n\t\t\t\t\t\t\t\tif ( isAbort ) {\n\t\t\t\t\t\t\t\t\t// Abort it manually if needed\n\t\t\t\t\t\t\t\t\tif ( xhr.readyState !== 4 ) {\n\t\t\t\t\t\t\t\t\t\txhr.abort();\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\tstatus = xhr.status;\n\t\t\t\t\t\t\t\t\tresponseHeaders = xhr.getAllResponseHeaders();\n\t\t\t\t\t\t\t\t\tresponses = {};\n\t\t\t\t\t\t\t\t\txml = xhr.responseXML;\n\n\t\t\t\t\t\t\t\t\t// Construct response list\n\t\t\t\t\t\t\t\t\tif ( xml && xml.documentElement /* #4958 */ ) {\n\t\t\t\t\t\t\t\t\t\tresponses.xml = xml;\n\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t\t// When requesting binary data, IE6-9 will throw an exception\n\t\t\t\t\t\t\t\t\t// on any attempt to access responseText (#11426)\n\t\t\t\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t\t\t\tresponses.text = xhr.responseText;\n\t\t\t\t\t\t\t\t\t} catch( e ) {\n\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t\t// Firefox throws an exception when accessing\n\t\t\t\t\t\t\t\t\t// statusText for faulty cross-domain requests\n\t\t\t\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t\t\t\tstatusText = xhr.statusText;\n\t\t\t\t\t\t\t\t\t} catch( e ) {\n\t\t\t\t\t\t\t\t\t\t// We normalize with Webkit giving an empty statusText\n\t\t\t\t\t\t\t\t\t\tstatusText = \"\";\n\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t\t// Filter status for non standard behaviors\n\n\t\t\t\t\t\t\t\t\t// If the request is local and we have data: assume a success\n\t\t\t\t\t\t\t\t\t// (success with no data won't get notified, that's the best we\n\t\t\t\t\t\t\t\t\t// can do given current implementations)\n\t\t\t\t\t\t\t\t\tif ( !status && s.isLocal && !s.crossDomain ) {\n\t\t\t\t\t\t\t\t\t\tstatus = responses.text ? 200 : 404;\n\t\t\t\t\t\t\t\t\t// IE - #1450: sometimes returns 1223 when it should be 204\n\t\t\t\t\t\t\t\t\t} else if ( status === 1223 ) {\n\t\t\t\t\t\t\t\t\t\tstatus = 204;\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} catch( firefoxAccessException ) {\n\t\t\t\t\t\t\tif ( !isAbort ) {\n\t\t\t\t\t\t\t\tcomplete( -1, firefoxAccessException );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// Call complete if needed\n\t\t\t\t\t\tif ( responses ) {\n\t\t\t\t\t\t\tcomplete( status, statusText, responses, responseHeaders );\n\t\t\t\t\t\t}\n\t\t\t\t\t};\n\n\t\t\t\t\tif ( !s.async ) {\n\t\t\t\t\t\t// if we're in sync mode we fire the callback\n\t\t\t\t\t\tcallback();\n\t\t\t\t\t} else if ( xhr.readyState === 4 ) {\n\t\t\t\t\t\t// (IE6 & IE7) if it's in cache and has been\n\t\t\t\t\t\t// retrieved directly we need to fire the callback\n\t\t\t\t\t\tsetTimeout( callback, 0 );\n\t\t\t\t\t} else {\n\t\t\t\t\t\thandle = ++xhrId;\n\t\t\t\t\t\tif ( xhrOnUnloadAbort ) {\n\t\t\t\t\t\t\t// Create the active xhrs callbacks list if needed\n\t\t\t\t\t\t\t// and attach the unload handler\n\t\t\t\t\t\t\tif ( !xhrCallbacks ) {\n\t\t\t\t\t\t\t\txhrCallbacks = {};\n\t\t\t\t\t\t\t\tjQuery( window ).unload( xhrOnUnloadAbort );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t// Add to list of active xhrs callbacks\n\t\t\t\t\t\t\txhrCallbacks[ handle ] = callback;\n\t\t\t\t\t\t}\n\t\t\t\t\t\txhr.onreadystatechange = callback;\n\t\t\t\t\t}\n\t\t\t\t},\n\n\t\t\t\tabort: function() {\n\t\t\t\t\tif ( callback ) {\n\t\t\t\t\t\tcallback(0,1);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t};\n\t\t}\n\t});\n}\nvar fxNow, timerId,\n\trfxtypes = /^(?:toggle|show|hide)$/,\n\trfxnum = new RegExp( \"^(?:([-+])=|)(\" + core_pnum + \")([a-z%]*)$\", \"i\" ),\n\trrun = /queueHooks$/,\n\tanimationPrefilters = [ defaultPrefilter ],\n\ttweeners = {\n\t\t\"*\": [function( prop, value ) {\n\t\t\tvar end, unit,\n\t\t\t\ttween = this.createTween( prop, value ),\n\t\t\t\tparts = rfxnum.exec( value ),\n\t\t\t\ttarget = tween.cur(),\n\t\t\t\tstart = +target || 0,\n\t\t\t\tscale = 1,\n\t\t\t\tmaxIterations = 20;\n\n\t\t\tif ( parts ) {\n\t\t\t\tend = +parts[2];\n\t\t\t\tunit = parts[3] || ( jQuery.cssNumber[ prop ] ? \"\" : \"px\" );\n\n\t\t\t\t// We need to compute starting value\n\t\t\t\tif ( unit !== \"px\" && start ) {\n\t\t\t\t\t// Iteratively approximate from a nonzero starting point\n\t\t\t\t\t// Prefer the current property, because this process will be trivial if it uses the same units\n\t\t\t\t\t// Fallback to end or a simple constant\n\t\t\t\t\tstart = jQuery.css( tween.elem, prop, true ) || end || 1;\n\n\t\t\t\t\tdo {\n\t\t\t\t\t\t// If previous iteration zeroed out, double until we get *something*\n\t\t\t\t\t\t// Use a string for doubling factor so we don't accidentally see scale as unchanged below\n\t\t\t\t\t\tscale = scale || \".5\";\n\n\t\t\t\t\t\t// Adjust and apply\n\t\t\t\t\t\tstart = start / scale;\n\t\t\t\t\t\tjQuery.style( tween.elem, prop, start + unit );\n\n\t\t\t\t\t// Update scale, tolerating zero or NaN from tween.cur()\n\t\t\t\t\t// And breaking the loop if scale is unchanged or perfect, or if we've just had enough\n\t\t\t\t\t} while ( scale !== (scale = tween.cur() / target) && scale !== 1 && --maxIterations );\n\t\t\t\t}\n\n\t\t\t\ttween.unit = unit;\n\t\t\t\ttween.start = start;\n\t\t\t\t// If a +=/-= token was provided, we're doing a relative animation\n\t\t\t\ttween.end = parts[1] ? start + ( parts[1] + 1 ) * end : end;\n\t\t\t}\n\t\t\treturn tween;\n\t\t}]\n\t};\n\n// Animations created synchronously will run synchronously\nfunction createFxNow() {\n\tsetTimeout(function() {\n\t\tfxNow = undefined;\n\t}, 0 );\n\treturn ( fxNow = jQuery.now() );\n}\n\nfunction createTweens( animation, props ) {\n\tjQuery.each( props, function( prop, value ) {\n\t\tvar collection = ( tweeners[ prop ] || [] ).concat( tweeners[ \"*\" ] ),\n\t\t\tindex = 0,\n\t\t\tlength = collection.length;\n\t\tfor ( ; index < length; index++ ) {\n\t\t\tif ( collection[ index ].call( animation, prop, value ) ) {\n\n\t\t\t\t// we're done with this property\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\t});\n}\n\nfunction Animation( elem, properties, options ) {\n\tvar result,\n\t\tindex = 0,\n\t\ttweenerIndex = 0,\n\t\tlength = animationPrefilters.length,\n\t\tdeferred = jQuery.Deferred().always( function() {\n\t\t\t// don't match elem in the :animated selector\n\t\t\tdelete tick.elem;\n\t\t}),\n\t\ttick = function() {\n\t\t\tvar currentTime = fxNow || createFxNow(),\n\t\t\t\tremaining = Math.max( 0, animation.startTime + animation.duration - currentTime ),\n\t\t\t\t// archaic crash bug won't allow us to use 1 - ( 0.5 || 0 ) (#12497)\n\t\t\t\ttemp = remaining / animation.duration || 0,\n\t\t\t\tpercent = 1 - temp,\n\t\t\t\tindex = 0,\n\t\t\t\tlength = animation.tweens.length;\n\n\t\t\tfor ( ; index < length ; index++ ) {\n\t\t\t\tanimation.tweens[ index ].run( percent );\n\t\t\t}\n\n\t\t\tdeferred.notifyWith( elem, [ animation, percent, remaining ]);\n\n\t\t\tif ( percent < 1 && length ) {\n\t\t\t\treturn remaining;\n\t\t\t} else {\n\t\t\t\tdeferred.resolveWith( elem, [ animation ] );\n\t\t\t\treturn false;\n\t\t\t}\n\t\t},\n\t\tanimation = deferred.promise({\n\t\t\telem: elem,\n\t\t\tprops: jQuery.extend( {}, properties ),\n\t\t\topts: jQuery.extend( true, { specialEasing: {} }, options ),\n\t\t\toriginalProperties: properties,\n\t\t\toriginalOptions: options,\n\t\t\tstartTime: fxNow || createFxNow(),\n\t\t\tduration: options.duration,\n\t\t\ttweens: [],\n\t\t\tcreateTween: function( prop, end, easing ) {\n\t\t\t\tvar tween = jQuery.Tween( elem, animation.opts, prop, end,\n\t\t\t\t\t\tanimation.opts.specialEasing[ prop ] || animation.opts.easing );\n\t\t\t\tanimation.tweens.push( tween );\n\t\t\t\treturn tween;\n\t\t\t},\n\t\t\tstop: function( gotoEnd ) {\n\t\t\t\tvar index = 0,\n\t\t\t\t\t// if we are going to the end, we want to run all the tweens\n\t\t\t\t\t// otherwise we skip this part\n\t\t\t\t\tlength = gotoEnd ? animation.tweens.length : 0;\n\n\t\t\t\tfor ( ; index < length ; index++ ) {\n\t\t\t\t\tanimation.tweens[ index ].run( 1 );\n\t\t\t\t}\n\n\t\t\t\t// resolve when we played the last frame\n\t\t\t\t// otherwise, reject\n\t\t\t\tif ( gotoEnd ) {\n\t\t\t\t\tdeferred.resolveWith( elem, [ animation, gotoEnd ] );\n\t\t\t\t} else {\n\t\t\t\t\tdeferred.rejectWith( elem, [ animation, gotoEnd ] );\n\t\t\t\t}\n\t\t\t\treturn this;\n\t\t\t}\n\t\t}),\n\t\tprops = animation.props;\n\n\tpropFilter( props, animation.opts.specialEasing );\n\n\tfor ( ; index < length ; index++ ) {\n\t\tresult = animationPrefilters[ index ].call( animation, elem, props, animation.opts );\n\t\tif ( result ) {\n\t\t\treturn result;\n\t\t}\n\t}\n\n\tcreateTweens( animation, props );\n\n\tif ( jQuery.isFunction( animation.opts.start ) ) {\n\t\tanimation.opts.start.call( elem, animation );\n\t}\n\n\tjQuery.fx.timer(\n\t\tjQuery.extend( tick, {\n\t\t\tanim: animation,\n\t\t\tqueue: animation.opts.queue,\n\t\t\telem: elem\n\t\t})\n\t);\n\n\t// attach callbacks from options\n\treturn animation.progress( animation.opts.progress )\n\t\t.done( animation.opts.done, animation.opts.complete )\n\t\t.fail( animation.opts.fail )\n\t\t.always( animation.opts.always );\n}\n\nfunction propFilter( props, specialEasing ) {\n\tvar index, name, easing, value, hooks;\n\n\t// camelCase, specialEasing and expand cssHook pass\n\tfor ( index in props ) {\n\t\tname = jQuery.camelCase( index );\n\t\teasing = specialEasing[ name ];\n\t\tvalue = props[ index ];\n\t\tif ( jQuery.isArray( value ) ) {\n\t\t\teasing = value[ 1 ];\n\t\t\tvalue = props[ index ] = value[ 0 ];\n\t\t}\n\n\t\tif ( index !== name ) {\n\t\t\tprops[ name ] = value;\n\t\t\tdelete props[ index ];\n\t\t}\n\n\t\thooks = jQuery.cssHooks[ name ];\n\t\tif ( hooks && \"expand\" in hooks ) {\n\t\t\tvalue = hooks.expand( value );\n\t\t\tdelete props[ name ];\n\n\t\t\t// not quite $.extend, this wont overwrite keys already present.\n\t\t\t// also - reusing 'index' from above because we have the correct \"name\"\n\t\t\tfor ( index in value ) {\n\t\t\t\tif ( !( index in props ) ) {\n\t\t\t\t\tprops[ index ] = value[ index ];\n\t\t\t\t\tspecialEasing[ index ] = easing;\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\tspecialEasing[ name ] = easing;\n\t\t}\n\t}\n}\n\njQuery.Animation = jQuery.extend( Animation, {\n\n\ttweener: function( props, callback ) {\n\t\tif ( jQuery.isFunction( props ) ) {\n\t\t\tcallback = props;\n\t\t\tprops = [ \"*\" ];\n\t\t} else {\n\t\t\tprops = props.split(\" \");\n\t\t}\n\n\t\tvar prop,\n\t\t\tindex = 0,\n\t\t\tlength = props.length;\n\n\t\tfor ( ; index < length ; index++ ) {\n\t\t\tprop = props[ index ];\n\t\t\ttweeners[ prop ] = tweeners[ prop ] || [];\n\t\t\ttweeners[ prop ].unshift( callback );\n\t\t}\n\t},\n\n\tprefilter: function( callback, prepend ) {\n\t\tif ( prepend ) {\n\t\t\tanimationPrefilters.unshift( callback );\n\t\t} else {\n\t\t\tanimationPrefilters.push( callback );\n\t\t}\n\t}\n});\n\nfunction defaultPrefilter( elem, props, opts ) {\n\tvar index, prop, value, length, dataShow, toggle, tween, hooks, oldfire,\n\t\tanim = this,\n\t\tstyle = elem.style,\n\t\torig = {},\n\t\thandled = [],\n\t\thidden = elem.nodeType && isHidden( elem );\n\n\t// handle queue: false promises\n\tif ( !opts.queue ) {\n\t\thooks = jQuery._queueHooks( elem, \"fx\" );\n\t\tif ( hooks.unqueued == null ) {\n\t\t\thooks.unqueued = 0;\n\t\t\toldfire = hooks.empty.fire;\n\t\t\thooks.empty.fire = function() {\n\t\t\t\tif ( !hooks.unqueued ) {\n\t\t\t\t\toldfire();\n\t\t\t\t}\n\t\t\t};\n\t\t}\n\t\thooks.unqueued++;\n\n\t\tanim.always(function() {\n\t\t\t// doing this makes sure that the complete handler will be called\n\t\t\t// before this completes\n\t\t\tanim.always(function() {\n\t\t\t\thooks.unqueued--;\n\t\t\t\tif ( !jQuery.queue( elem, \"fx\" ).length ) {\n\t\t\t\t\thooks.empty.fire();\n\t\t\t\t}\n\t\t\t});\n\t\t});\n\t}\n\n\t// height/width overflow pass\n\tif ( elem.nodeType === 1 && ( \"height\" in props || \"width\" in props ) ) {\n\t\t// Make sure that nothing sneaks out\n\t\t// Record all 3 overflow attributes because IE does not\n\t\t// change the overflow attribute when overflowX and\n\t\t// overflowY are set to the same value\n\t\topts.overflow = [ style.overflow, style.overflowX, style.overflowY ];\n\n\t\t// Set display property to inline-block for height/width\n\t\t// animations on inline elements that are having width/height animated\n\t\tif ( jQuery.css( elem, \"display\" ) === \"inline\" &&\n\t\t\t\tjQuery.css( elem, \"float\" ) === \"none\" ) {\n\n\t\t\t// inline-level elements accept inline-block;\n\t\t\t// block-level elements need to be inline with layout\n\t\t\tif ( !jQuery.support.inlineBlockNeedsLayout || css_defaultDisplay( elem.nodeName ) === \"inline\" ) {\n\t\t\t\tstyle.display = \"inline-block\";\n\n\t\t\t} else {\n\t\t\t\tstyle.zoom = 1;\n\t\t\t}\n\t\t}\n\t}\n\n\tif ( opts.overflow ) {\n\t\tstyle.overflow = \"hidden\";\n\t\tif ( !jQuery.support.shrinkWrapBlocks ) {\n\t\t\tanim.done(function() {\n\t\t\t\tstyle.overflow = opts.overflow[ 0 ];\n\t\t\t\tstyle.overflowX = opts.overflow[ 1 ];\n\t\t\t\tstyle.overflowY = opts.overflow[ 2 ];\n\t\t\t});\n\t\t}\n\t}\n\n\n\t// show/hide pass\n\tfor ( index in props ) {\n\t\tvalue = props[ index ];\n\t\tif ( rfxtypes.exec( value ) ) {\n\t\t\tdelete props[ index ];\n\t\t\ttoggle = toggle || value === \"toggle\";\n\t\t\tif ( value === ( hidden ? \"hide\" : \"show\" ) ) {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\thandled.push( index );\n\t\t}\n\t}\n\n\tlength = handled.length;\n\tif ( length ) {\n\t\tdataShow = jQuery._data( elem, \"fxshow\" ) || jQuery._data( elem, \"fxshow\", {} );\n\t\tif ( \"hidden\" in dataShow ) {\n\t\t\thidden = dataShow.hidden;\n\t\t}\n\n\t\t// store state if its toggle - enables .stop().toggle() to \"reverse\"\n\t\tif ( toggle ) {\n\t\t\tdataShow.hidden = !hidden;\n\t\t}\n\t\tif ( hidden ) {\n\t\t\tjQuery( elem ).show();\n\t\t} else {\n\t\t\tanim.done(function() {\n\t\t\t\tjQuery( elem ).hide();\n\t\t\t});\n\t\t}\n\t\tanim.done(function() {\n\t\t\tvar prop;\n\t\t\tjQuery.removeData( elem, \"fxshow\", true );\n\t\t\tfor ( prop in orig ) {\n\t\t\t\tjQuery.style( elem, prop, orig[ prop ] );\n\t\t\t}\n\t\t});\n\t\tfor ( index = 0 ; index < length ; index++ ) {\n\t\t\tprop = handled[ index ];\n\t\t\ttween = anim.createTween( prop, hidden ? dataShow[ prop ] : 0 );\n\t\t\torig[ prop ] = dataShow[ prop ] || jQuery.style( elem, prop );\n\n\t\t\tif ( !( prop in dataShow ) ) {\n\t\t\t\tdataShow[ prop ] = tween.start;\n\t\t\t\tif ( hidden ) {\n\t\t\t\t\ttween.end = tween.start;\n\t\t\t\t\ttween.start = prop === \"width\" || prop === \"height\" ? 1 : 0;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n}\n\nfunction Tween( elem, options, prop, end, easing ) {\n\treturn new Tween.prototype.init( elem, options, prop, end, easing );\n}\njQuery.Tween = Tween;\n\nTween.prototype = {\n\tconstructor: Tween,\n\tinit: function( elem, options, prop, end, easing, unit ) {\n\t\tthis.elem = elem;\n\t\tthis.prop = prop;\n\t\tthis.easing = easing || \"swing\";\n\t\tthis.options = options;\n\t\tthis.start = this.now = this.cur();\n\t\tthis.end = end;\n\t\tthis.unit = unit || ( jQuery.cssNumber[ prop ] ? \"\" : \"px\" );\n\t},\n\tcur: function() {\n\t\tvar hooks = Tween.propHooks[ this.prop ];\n\n\t\treturn hooks && hooks.get ?\n\t\t\thooks.get( this ) :\n\t\t\tTween.propHooks._default.get( this );\n\t},\n\trun: function( percent ) {\n\t\tvar eased,\n\t\t\thooks = Tween.propHooks[ this.prop ];\n\n\t\tif ( this.options.duration ) {\n\t\t\tthis.pos = eased = jQuery.easing[ this.easing ](\n\t\t\t\tpercent, this.options.duration * percent, 0, 1, this.options.duration\n\t\t\t);\n\t\t} else {\n\t\t\tthis.pos = eased = percent;\n\t\t}\n\t\tthis.now = ( this.end - this.start ) * eased + this.start;\n\n\t\tif ( this.options.step ) {\n\t\t\tthis.options.step.call( this.elem, this.now, this );\n\t\t}\n\n\t\tif ( hooks && hooks.set ) {\n\t\t\thooks.set( this );\n\t\t} else {\n\t\t\tTween.propHooks._default.set( this );\n\t\t}\n\t\treturn this;\n\t}\n};\n\nTween.prototype.init.prototype = Tween.prototype;\n\nTween.propHooks = {\n\t_default: {\n\t\tget: function( tween ) {\n\t\t\tvar result;\n\n\t\t\tif ( tween.elem[ tween.prop ] != null &&\n\t\t\t\t(!tween.elem.style || tween.elem.style[ tween.prop ] == null) ) {\n\t\t\t\treturn tween.elem[ tween.prop ];\n\t\t\t}\n\n\t\t\t// passing any value as a 4th parameter to .css will automatically\n\t\t\t// attempt a parseFloat and fallback to a string if the parse fails\n\t\t\t// so, simple values such as \"10px\" are parsed to Float.\n\t\t\t// complex values such as \"rotate(1rad)\" are returned as is.\n\t\t\tresult = jQuery.css( tween.elem, tween.prop, false, \"\" );\n\t\t\t// Empty strings, null, undefined and \"auto\" are converted to 0.\n\t\t\treturn !result || result === \"auto\" ? 0 : result;\n\t\t},\n\t\tset: function( tween ) {\n\t\t\t// use step hook for back compat - use cssHook if its there - use .style if its\n\t\t\t// available and use plain properties where available\n\t\t\tif ( jQuery.fx.step[ tween.prop ] ) {\n\t\t\t\tjQuery.fx.step[ tween.prop ]( tween );\n\t\t\t} else if ( tween.elem.style && ( tween.elem.style[ jQuery.cssProps[ tween.prop ] ] != null || jQuery.cssHooks[ tween.prop ] ) ) {\n\t\t\t\tjQuery.style( tween.elem, tween.prop, tween.now + tween.unit );\n\t\t\t} else {\n\t\t\t\ttween.elem[ tween.prop ] = tween.now;\n\t\t\t}\n\t\t}\n\t}\n};\n\n// Remove in 2.0 - this supports IE8's panic based approach\n// to setting things on disconnected nodes\n\nTween.propHooks.scrollTop = Tween.propHooks.scrollLeft = {\n\tset: function( tween ) {\n\t\tif ( tween.elem.nodeType && tween.elem.parentNode ) {\n\t\t\ttween.elem[ tween.prop ] = tween.now;\n\t\t}\n\t}\n};\n\njQuery.each([ \"toggle\", \"show\", \"hide\" ], function( i, name ) {\n\tvar cssFn = jQuery.fn[ name ];\n\tjQuery.fn[ name ] = function( speed, easing, callback ) {\n\t\treturn speed == null || typeof speed === \"boolean\" ||\n\t\t\t// special check for .toggle( handler, handler, ... )\n\t\t\t( !i && jQuery.isFunction( speed ) && jQuery.isFunction( easing ) ) ?\n\t\t\tcssFn.apply( this, arguments ) :\n\t\t\tthis.animate( genFx( name, true ), speed, easing, callback );\n\t};\n});\n\njQuery.fn.extend({\n\tfadeTo: function( speed, to, easing, callback ) {\n\n\t\t// show any hidden elements after setting opacity to 0\n\t\treturn this.filter( isHidden ).css( \"opacity\", 0 ).show()\n\n\t\t\t// animate to the value specified\n\t\t\t.end().animate({ opacity: to }, speed, easing, callback );\n\t},\n\tanimate: function( prop, speed, easing, callback ) {\n\t\tvar empty = jQuery.isEmptyObject( prop ),\n\t\t\toptall = jQuery.speed( speed, easing, callback ),\n\t\t\tdoAnimation = function() {\n\t\t\t\t// Operate on a copy of prop so per-property easing won't be lost\n\t\t\t\tvar anim = Animation( this, jQuery.extend( {}, prop ), optall );\n\n\t\t\t\t// Empty animations resolve immediately\n\t\t\t\tif ( empty ) {\n\t\t\t\t\tanim.stop( true );\n\t\t\t\t}\n\t\t\t};\n\n\t\treturn empty || optall.queue === false ?\n\t\t\tthis.each( doAnimation ) :\n\t\t\tthis.queue( optall.queue, doAnimation );\n\t},\n\tstop: function( type, clearQueue, gotoEnd ) {\n\t\tvar stopQueue = function( hooks ) {\n\t\t\tvar stop = hooks.stop;\n\t\t\tdelete hooks.stop;\n\t\t\tstop( gotoEnd );\n\t\t};\n\n\t\tif ( typeof type !== \"string\" ) {\n\t\t\tgotoEnd = clearQueue;\n\t\t\tclearQueue = type;\n\t\t\ttype = undefined;\n\t\t}\n\t\tif ( clearQueue && type !== false ) {\n\t\t\tthis.queue( type || \"fx\", [] );\n\t\t}\n\n\t\treturn this.each(function() {\n\t\t\tvar dequeue = true,\n\t\t\t\tindex = type != null && type + \"queueHooks\",\n\t\t\t\ttimers = jQuery.timers,\n\t\t\t\tdata = jQuery._data( this );\n\n\t\t\tif ( index ) {\n\t\t\t\tif ( data[ index ] && data[ index ].stop ) {\n\t\t\t\t\tstopQueue( data[ index ] );\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tfor ( index in data ) {\n\t\t\t\t\tif ( data[ index ] && data[ index ].stop && rrun.test( index ) ) {\n\t\t\t\t\t\tstopQueue( data[ index ] );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tfor ( index = timers.length; index--; ) {\n\t\t\t\tif ( timers[ index ].elem === this && (type == null || timers[ index ].queue === type) ) {\n\t\t\t\t\ttimers[ index ].anim.stop( gotoEnd );\n\t\t\t\t\tdequeue = false;\n\t\t\t\t\ttimers.splice( index, 1 );\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// start the next in the queue if the last step wasn't forced\n\t\t\t// timers currently will call their complete callbacks, which will dequeue\n\t\t\t// but only if they were gotoEnd\n\t\t\tif ( dequeue || !gotoEnd ) {\n\t\t\t\tjQuery.dequeue( this, type );\n\t\t\t}\n\t\t});\n\t}\n});\n\n// Generate parameters to create a standard animation\nfunction genFx( type, includeWidth ) {\n\tvar which,\n\t\tattrs = { height: type },\n\t\ti = 0;\n\n\t// if we include width, step value is 1 to do all cssExpand values,\n\t// if we don't include width, step value is 2 to skip over Left and Right\n\tincludeWidth = includeWidth? 1 : 0;\n\tfor( ; i < 4 ; i += 2 - includeWidth ) {\n\t\twhich = cssExpand[ i ];\n\t\tattrs[ \"margin\" + which ] = attrs[ \"padding\" + which ] = type;\n\t}\n\n\tif ( includeWidth ) {\n\t\tattrs.opacity = attrs.width = type;\n\t}\n\n\treturn attrs;\n}\n\n// Generate shortcuts for custom animations\njQuery.each({\n\tslideDown: genFx(\"show\"),\n\tslideUp: genFx(\"hide\"),\n\tslideToggle: genFx(\"toggle\"),\n\tfadeIn: { opacity: \"show\" },\n\tfadeOut: { opacity: \"hide\" },\n\tfadeToggle: { opacity: \"toggle\" }\n}, function( name, props ) {\n\tjQuery.fn[ name ] = function( speed, easing, callback ) {\n\t\treturn this.animate( props, speed, easing, callback );\n\t};\n});\n\njQuery.speed = function( speed, easing, fn ) {\n\tvar opt = speed && typeof speed === \"object\" ? jQuery.extend( {}, speed ) : {\n\t\tcomplete: fn || !fn && easing ||\n\t\t\tjQuery.isFunction( speed ) && speed,\n\t\tduration: speed,\n\t\teasing: fn && easing || easing && !jQuery.isFunction( easing ) && easing\n\t};\n\n\topt.duration = jQuery.fx.off ? 0 : typeof opt.duration === \"number\" ? opt.duration :\n\t\topt.duration in jQuery.fx.speeds ? jQuery.fx.speeds[ opt.duration ] : jQuery.fx.speeds._default;\n\n\t// normalize opt.queue - true/undefined/null -> \"fx\"\n\tif ( opt.queue == null || opt.queue === true ) {\n\t\topt.queue = \"fx\";\n\t}\n\n\t// Queueing\n\topt.old = opt.complete;\n\n\topt.complete = function() {\n\t\tif ( jQuery.isFunction( opt.old ) ) {\n\t\t\topt.old.call( this );\n\t\t}\n\n\t\tif ( opt.queue ) {\n\t\t\tjQuery.dequeue( this, opt.queue );\n\t\t}\n\t};\n\n\treturn opt;\n};\n\njQuery.easing = {\n\tlinear: function( p ) {\n\t\treturn p;\n\t},\n\tswing: function( p ) {\n\t\treturn 0.5 - Math.cos( p*Math.PI ) / 2;\n\t}\n};\n\njQuery.timers = [];\njQuery.fx = Tween.prototype.init;\njQuery.fx.tick = function() {\n\tvar timer,\n\t\ttimers = jQuery.timers,\n\t\ti = 0;\n\n\tfxNow = jQuery.now();\n\n\tfor ( ; i < timers.length; i++ ) {\n\t\ttimer = timers[ i ];\n\t\t// Checks the timer has not already been removed\n\t\tif ( !timer() && timers[ i ] === timer ) {\n\t\t\ttimers.splice( i--, 1 );\n\t\t}\n\t}\n\n\tif ( !timers.length ) {\n\t\tjQuery.fx.stop();\n\t}\n\tfxNow = undefined;\n};\n\njQuery.fx.timer = function( timer ) {\n\tif ( timer() && jQuery.timers.push( timer ) && !timerId ) {\n\t\ttimerId = setInterval( jQuery.fx.tick, jQuery.fx.interval );\n\t}\n};\n\njQuery.fx.interval = 13;\n\njQuery.fx.stop = function() {\n\tclearInterval( timerId );\n\ttimerId = null;\n};\n\njQuery.fx.speeds = {\n\tslow: 600,\n\tfast: 200,\n\t// Default speed\n\t_default: 400\n};\n\n// Back Compat <1.8 extension point\njQuery.fx.step = {};\n\nif ( jQuery.expr && jQuery.expr.filters ) {\n\tjQuery.expr.filters.animated = function( elem ) {\n\t\treturn jQuery.grep(jQuery.timers, function( fn ) {\n\t\t\treturn elem === fn.elem;\n\t\t}).length;\n\t};\n}\nvar rroot = /^(?:body|html)$/i;\n\njQuery.fn.offset = function( options ) {\n\tif ( arguments.length ) {\n\t\treturn options === undefined ?\n\t\t\tthis :\n\t\t\tthis.each(function( i ) {\n\t\t\t\tjQuery.offset.setOffset( this, options, i );\n\t\t\t});\n\t}\n\n\tvar docElem, body, win, clientTop, clientLeft, scrollTop, scrollLeft,\n\t\tbox = { top: 0, left: 0 },\n\t\telem = this[ 0 ],\n\t\tdoc = elem && elem.ownerDocument;\n\n\tif ( !doc ) {\n\t\treturn;\n\t}\n\n\tif ( (body = doc.body) === elem ) {\n\t\treturn jQuery.offset.bodyOffset( elem );\n\t}\n\n\tdocElem = doc.documentElement;\n\n\t// Make sure it's not a disconnected DOM node\n\tif ( !jQuery.contains( docElem, elem ) ) {\n\t\treturn box;\n\t}\n\n\t// If we don't have gBCR, just use 0,0 rather than error\n\t// BlackBerry 5, iOS 3 (original iPhone)\n\tif ( typeof elem.getBoundingClientRect !== \"undefined\" ) {\n\t\tbox = elem.getBoundingClientRect();\n\t}\n\twin = getWindow( doc );\n\tclientTop  = docElem.clientTop  || body.clientTop  || 0;\n\tclientLeft = docElem.clientLeft || body.clientLeft || 0;\n\tscrollTop  = win.pageYOffset || docElem.scrollTop;\n\tscrollLeft = win.pageXOffset || docElem.scrollLeft;\n\treturn {\n\t\ttop: box.top  + scrollTop  - clientTop,\n\t\tleft: box.left + scrollLeft - clientLeft\n\t};\n};\n\njQuery.offset = {\n\n\tbodyOffset: function( body ) {\n\t\tvar top = body.offsetTop,\n\t\t\tleft = body.offsetLeft;\n\n\t\tif ( jQuery.support.doesNotIncludeMarginInBodyOffset ) {\n\t\t\ttop  += parseFloat( jQuery.css(body, \"marginTop\") ) || 0;\n\t\t\tleft += parseFloat( jQuery.css(body, \"marginLeft\") ) || 0;\n\t\t}\n\n\t\treturn { top: top, left: left };\n\t},\n\n\tsetOffset: function( elem, options, i ) {\n\t\tvar position = jQuery.css( elem, \"position\" );\n\n\t\t// set position first, in-case top/left are set even on static elem\n\t\tif ( position === \"static\" ) {\n\t\t\telem.style.position = \"relative\";\n\t\t}\n\n\t\tvar curElem = jQuery( elem ),\n\t\t\tcurOffset = curElem.offset(),\n\t\t\tcurCSSTop = jQuery.css( elem, \"top\" ),\n\t\t\tcurCSSLeft = jQuery.css( elem, \"left\" ),\n\t\t\tcalculatePosition = ( position === \"absolute\" || position === \"fixed\" ) && jQuery.inArray(\"auto\", [curCSSTop, curCSSLeft]) > -1,\n\t\t\tprops = {}, curPosition = {}, curTop, curLeft;\n\n\t\t// need to be able to calculate position if either top or left is auto and position is either absolute or fixed\n\t\tif ( calculatePosition ) {\n\t\t\tcurPosition = curElem.position();\n\t\t\tcurTop = curPosition.top;\n\t\t\tcurLeft = curPosition.left;\n\t\t} else {\n\t\t\tcurTop = parseFloat( curCSSTop ) || 0;\n\t\t\tcurLeft = parseFloat( curCSSLeft ) || 0;\n\t\t}\n\n\t\tif ( jQuery.isFunction( options ) ) {\n\t\t\toptions = options.call( elem, i, curOffset );\n\t\t}\n\n\t\tif ( options.top != null ) {\n\t\t\tprops.top = ( options.top - curOffset.top ) + curTop;\n\t\t}\n\t\tif ( options.left != null ) {\n\t\t\tprops.left = ( options.left - curOffset.left ) + curLeft;\n\t\t}\n\n\t\tif ( \"using\" in options ) {\n\t\t\toptions.using.call( elem, props );\n\t\t} else {\n\t\t\tcurElem.css( props );\n\t\t}\n\t}\n};\n\n\njQuery.fn.extend({\n\n\tposition: function() {\n\t\tif ( !this[0] ) {\n\t\t\treturn;\n\t\t}\n\n\t\tvar elem = this[0],\n\n\t\t// Get *real* offsetParent\n\t\toffsetParent = this.offsetParent(),\n\n\t\t// Get correct offsets\n\t\toffset       = this.offset(),\n\t\tparentOffset = rroot.test(offsetParent[0].nodeName) ? { top: 0, left: 0 } : offsetParent.offset();\n\n\t\t// Subtract element margins\n\t\t// note: when an element has margin: auto the offsetLeft and marginLeft\n\t\t// are the same in Safari causing offset.left to incorrectly be 0\n\t\toffset.top  -= parseFloat( jQuery.css(elem, \"marginTop\") ) || 0;\n\t\toffset.left -= parseFloat( jQuery.css(elem, \"marginLeft\") ) || 0;\n\n\t\t// Add offsetParent borders\n\t\tparentOffset.top  += parseFloat( jQuery.css(offsetParent[0], \"borderTopWidth\") ) || 0;\n\t\tparentOffset.left += parseFloat( jQuery.css(offsetParent[0], \"borderLeftWidth\") ) || 0;\n\n\t\t// Subtract the two offsets\n\t\treturn {\n\t\t\ttop:  offset.top  - parentOffset.top,\n\t\t\tleft: offset.left - parentOffset.left\n\t\t};\n\t},\n\n\toffsetParent: function() {\n\t\treturn this.map(function() {\n\t\t\tvar offsetParent = this.offsetParent || document.body;\n\t\t\twhile ( offsetParent && (!rroot.test(offsetParent.nodeName) && jQuery.css(offsetParent, \"position\") === \"static\") ) {\n\t\t\t\toffsetParent = offsetParent.offsetParent;\n\t\t\t}\n\t\t\treturn offsetParent || document.body;\n\t\t});\n\t}\n});\n\n\n// Create scrollLeft and scrollTop methods\njQuery.each( {scrollLeft: \"pageXOffset\", scrollTop: \"pageYOffset\"}, function( method, prop ) {\n\tvar top = /Y/.test( prop );\n\n\tjQuery.fn[ method ] = function( val ) {\n\t\treturn jQuery.access( this, function( elem, method, val ) {\n\t\t\tvar win = getWindow( elem );\n\n\t\t\tif ( val === undefined ) {\n\t\t\t\treturn win ? (prop in win) ? win[ prop ] :\n\t\t\t\t\twin.document.documentElement[ method ] :\n\t\t\t\t\telem[ method ];\n\t\t\t}\n\n\t\t\tif ( win ) {\n\t\t\t\twin.scrollTo(\n\t\t\t\t\t!top ? val : jQuery( win ).scrollLeft(),\n\t\t\t\t\t top ? val : jQuery( win ).scrollTop()\n\t\t\t\t);\n\n\t\t\t} else {\n\t\t\t\telem[ method ] = val;\n\t\t\t}\n\t\t}, method, val, arguments.length, null );\n\t};\n});\n\nfunction getWindow( elem ) {\n\treturn jQuery.isWindow( elem ) ?\n\t\telem :\n\t\telem.nodeType === 9 ?\n\t\t\telem.defaultView || elem.parentWindow :\n\t\t\tfalse;\n}\n// Create innerHeight, innerWidth, height, width, outerHeight and outerWidth methods\njQuery.each( { Height: \"height\", Width: \"width\" }, function( name, type ) {\n\tjQuery.each( { padding: \"inner\" + name, content: type, \"\": \"outer\" + name }, function( defaultExtra, funcName ) {\n\t\t// margin is only for outerHeight, outerWidth\n\t\tjQuery.fn[ funcName ] = function( margin, value ) {\n\t\t\tvar chainable = arguments.length && ( defaultExtra || typeof margin !== \"boolean\" ),\n\t\t\t\textra = defaultExtra || ( margin === true || value === true ? \"margin\" : \"border\" );\n\n\t\t\treturn jQuery.access( this, function( elem, type, value ) {\n\t\t\t\tvar doc;\n\n\t\t\t\tif ( jQuery.isWindow( elem ) ) {\n\t\t\t\t\t// As of 5/8/2012 this will yield incorrect results for Mobile Safari, but there\n\t\t\t\t\t// isn't a whole lot we can do. See pull request at this URL for discussion:\n\t\t\t\t\t// https://github.com/jquery/jquery/pull/764\n\t\t\t\t\treturn elem.document.documentElement[ \"client\" + name ];\n\t\t\t\t}\n\n\t\t\t\t// Get document width or height\n\t\t\t\tif ( elem.nodeType === 9 ) {\n\t\t\t\t\tdoc = elem.documentElement;\n\n\t\t\t\t\t// Either scroll[Width/Height] or offset[Width/Height] or client[Width/Height], whichever is greatest\n\t\t\t\t\t// unfortunately, this causes bug #3838 in IE6/8 only, but there is currently no good, small way to fix it.\n\t\t\t\t\treturn Math.max(\n\t\t\t\t\t\telem.body[ \"scroll\" + name ], doc[ \"scroll\" + name ],\n\t\t\t\t\t\telem.body[ \"offset\" + name ], doc[ \"offset\" + name ],\n\t\t\t\t\t\tdoc[ \"client\" + name ]\n\t\t\t\t\t);\n\t\t\t\t}\n\n\t\t\t\treturn value === undefined ?\n\t\t\t\t\t// Get width or height on the element, requesting but not forcing parseFloat\n\t\t\t\t\tjQuery.css( elem, type, value, extra ) :\n\n\t\t\t\t\t// Set width or height on the element\n\t\t\t\t\tjQuery.style( elem, type, value, extra );\n\t\t\t}, type, chainable ? margin : undefined, chainable, null );\n\t\t};\n\t});\n});\n// Expose jQuery to the global object\nwindow.jQuery = window.$ = jQuery;\n\n// Expose jQuery as an AMD module, but only for AMD loaders that\n// understand the issues with loading multiple versions of jQuery\n// in a page that all might call define(). The loader will indicate\n// they have special allowances for multiple jQuery versions by\n// specifying define.amd.jQuery = true. Register as a named module,\n// since jQuery can be concatenated with other files that may use define,\n// but not use a proper concatenation script that understands anonymous\n// AMD modules. A named AMD is safest and most robust way to register.\n// Lowercase jquery is used because AMD module names are derived from\n// file names, and jQuery is normally delivered in a lowercase file name.\n// Do this after creating the global so that if an AMD module wants to call\n// noConflict to hide this version of jQuery, it will work.\nif ( typeof define === \"function\" && define.amd && define.amd.jQuery ) {\n\tdefine( \"jquery\", [], function () { return jQuery; } );\n}\n\n})( window );\n"
  },
  {
    "path": "app_backend/vendor/flot-tooltip/jquery.flot.tooltip.js",
    "content": "/*\n * jquery.flot.tooltip\n * \n * description: easy-to-use tooltips for Flot charts\n * version: 0.8.7\n * authors: Krzysztof Urbas @krzysu [myviews.pl],Evan Steinkerchner @Roundaround\n * website: https://github.com/krzysu/flot.tooltip\n * \n * build on 2016-03-15\n * released under MIT License, 2012\n*/ \n(function ($) {\n    // plugin options, default values\n    var defaultOptions = {\n        tooltip: {\n            show: false,\n            cssClass: \"flotTip\",\n            content: \"%s | X: %x | Y: %y\",\n            // allowed templates are:\n            // %s -> series label,\n            // %c -> series color,\n            // %lx -> x axis label (requires flot-axislabels plugin https://github.com/markrcote/flot-axislabels),\n            // %ly -> y axis label (requires flot-axislabels plugin https://github.com/markrcote/flot-axislabels),\n            // %x -> X value,\n            // %y -> Y value,\n            // %x.2 -> precision of X value,\n            // %p -> percent\n\t    // %n -> value (not percent) of pie chart\n            xDateFormat: null,\n            yDateFormat: null,\n            monthNames: null,\n            dayNames: null,\n            shifts: {\n                x: 10,\n                y: 20\n            },\n            defaultTheme: true,\n            snap: true,\n            lines: false,\n            clickTips: false,\n\n            // callbacks\n            onHover: function (flotItem, $tooltipEl) {},\n\n            $compat: false\n        }\n    };\n\n    // dummy default options object for legacy code (<0.8.5) - is deleted later\n    defaultOptions.tooltipOpts = defaultOptions.tooltip;\n\n    // object\n    var FlotTooltip = function (plot) {\n        // variables\n        this.tipPosition = {x: 0, y: 0};\n\n        this.init(plot);\n    };\n\n    // main plugin function\n    FlotTooltip.prototype.init = function (plot) {\n        var that = this;\n\n        // detect other flot plugins\n        var plotPluginsLength = $.plot.plugins.length;\n        this.plotPlugins = [];\n\n        if (plotPluginsLength) {\n            for (var p = 0; p < plotPluginsLength; p++) {\n                this.plotPlugins.push($.plot.plugins[p].name);\n            }\n        }\n\n        plot.hooks.bindEvents.push(function (plot, eventHolder) {\n\n            // get plot options\n            that.plotOptions = plot.getOptions();\n\n            // for legacy (<0.8.5) implementations\n            if (typeof(that.plotOptions.tooltip) === 'boolean') {\n                that.plotOptions.tooltipOpts.show = that.plotOptions.tooltip;\n                that.plotOptions.tooltip = that.plotOptions.tooltipOpts;\n                delete that.plotOptions.tooltipOpts;\n            }\n\n            // if not enabled return\n            if (that.plotOptions.tooltip.show === false || typeof that.plotOptions.tooltip.show === 'undefined') return;\n\n            // shortcut to access tooltip options\n            that.tooltipOptions = that.plotOptions.tooltip;\n\n            if (that.tooltipOptions.$compat) {\n                that.wfunc = 'width';\n                that.hfunc = 'height';\n            } else {\n                that.wfunc = 'innerWidth';\n                that.hfunc = 'innerHeight';\n            }\n\n            // create tooltip DOM element\n            var $tip = that.getDomElement();\n\n            // bind event\n            $( plot.getPlaceholder() ).bind(\"plothover\", plothover);\n            if (that.tooltipOptions.clickTips) {\n                $( plot.getPlaceholder() ).bind(\"plotclick\", plotclick);\n            }\n            that.clickmode = false;\n\n            $(eventHolder).bind('mousemove', mouseMove);\n        });\n\n        plot.hooks.shutdown.push(function (plot, eventHolder){\n            $(plot.getPlaceholder()).unbind(\"plothover\", plothover);\n            $(plot.getPlaceholder()).unbind(\"plotclick\", plotclick);\n            plot.removeTooltip();\n            $(eventHolder).unbind(\"mousemove\", mouseMove);\n        });\n\n        function mouseMove(e){\n            var pos = {};\n            pos.x = e.pageX;\n            pos.y = e.pageY;\n            plot.setTooltipPosition(pos);\n        }\n\n        /**\n         *  open the tooltip (if not already open) and freeze it on the current position till the next click\n         */\n        function plotclick(event, pos, item) {\n            if (! that.clickmode) {\n                // it is the click activating the clicktip\n                plothover(event, pos, item);\n                if (that.getDomElement().is(\":visible\")) {\n                    $(plot.getPlaceholder()).unbind(\"plothover\", plothover);\n                    that.clickmode = true;\n                }\n            } else {\n                // it is the click deactivating the clicktip\n                $( plot.getPlaceholder() ).bind(\"plothover\", plothover);\n                plot.hideTooltip();\n                that.clickmode = false;\n            }\n        }\n\n        function plothover(event, pos, item) {\n            // Simple distance formula.\n            var lineDistance = function (p1x, p1y, p2x, p2y) {\n                return Math.sqrt((p2x - p1x) * (p2x - p1x) + (p2y - p1y) * (p2y - p1y));\n            };\n\n            // Here is some voodoo magic for determining the distance to a line form a given point {x, y}.\n            var dotLineLength = function (x, y, x0, y0, x1, y1, o) {\n                if (o && !(o =\n                    function (x, y, x0, y0, x1, y1) {\n                        if (typeof x0 !== 'undefined') return { x: x0, y: y };\n                        else if (typeof y0 !== 'undefined') return { x: x, y: y0 };\n\n                        var left,\n                            tg = -1 / ((y1 - y0) / (x1 - x0));\n\n                        return {\n                            x: left = (x1 * (x * tg - y + y0) + x0 * (x * -tg + y - y1)) / (tg * (x1 - x0) + y0 - y1),\n                            y: tg * left - tg * x + y\n                        };\n                    } (x, y, x0, y0, x1, y1),\n                    o.x >= Math.min(x0, x1) && o.x <= Math.max(x0, x1) && o.y >= Math.min(y0, y1) && o.y <= Math.max(y0, y1))\n                ) {\n                    var l1 = lineDistance(x, y, x0, y0), l2 = lineDistance(x, y, x1, y1);\n                    return l1 > l2 ? l2 : l1;\n                } else {\n                    var a = y0 - y1, b = x1 - x0, c = x0 * y1 - y0 * x1;\n                    return Math.abs(a * x + b * y + c) / Math.sqrt(a * a + b * b);\n                }\n            };\n\n            if (item) {\n                plot.showTooltip(item, that.tooltipOptions.snap ? item : pos);\n            } else if (that.plotOptions.series.lines.show && that.tooltipOptions.lines === true) {\n                var maxDistance = that.plotOptions.grid.mouseActiveRadius;\n\n                var closestTrace = {\n                    distance: maxDistance + 1\n                };\n\n                var ttPos = pos;\n\n                $.each(plot.getData(), function (i, series) {\n                    var xBeforeIndex = 0,\n                        xAfterIndex = -1;\n\n                    // Our search here assumes our data is sorted via the x-axis.\n                    // TODO: Improve efficiency somehow - search smaller sets of data.\n                    for (var j = 1; j < series.data.length; j++) {\n                        if (series.data[j - 1][0] <= pos.x && series.data[j][0] >= pos.x) {\n                            xBeforeIndex = j - 1;\n                            xAfterIndex = j;\n                        }\n                    }\n\n                    if (xAfterIndex === -1) {\n                        plot.hideTooltip();\n                        return;\n                    }\n\n                    var pointPrev = { x: series.data[xBeforeIndex][0], y: series.data[xBeforeIndex][1] },\n                        pointNext = { x: series.data[xAfterIndex][0], y: series.data[xAfterIndex][1] };\n\n                    var distToLine = dotLineLength(series.xaxis.p2c(pos.x), series.yaxis.p2c(pos.y), series.xaxis.p2c(pointPrev.x),\n                        series.yaxis.p2c(pointPrev.y), series.xaxis.p2c(pointNext.x), series.yaxis.p2c(pointNext.y), false);\n\n                    if (distToLine < closestTrace.distance) {\n\n                        var closestIndex = lineDistance(pointPrev.x, pointPrev.y, pos.x, pos.y) <\n                            lineDistance(pos.x, pos.y, pointNext.x, pointNext.y) ? xBeforeIndex : xAfterIndex;\n\n                        var pointSize = series.datapoints.pointsize;\n\n                        // Calculate the point on the line vertically closest to our cursor.\n                        var pointOnLine = [\n                            pos.x,\n                            pointPrev.y + ((pointNext.y - pointPrev.y) * ((pos.x - pointPrev.x) / (pointNext.x - pointPrev.x)))\n                        ];\n\n                        var item = {\n                            datapoint: pointOnLine,\n                            dataIndex: closestIndex,\n                            series: series,\n                            seriesIndex: i\n                        };\n\n                        closestTrace = {\n                            distance: distToLine,\n                            item: item\n                        };\n\n                        if (that.tooltipOptions.snap) {\n                            ttPos = {\n                                pageX: series.xaxis.p2c(pointOnLine[0]),\n                                pageY: series.yaxis.p2c(pointOnLine[1])\n                            };\n                        }\n                    }\n                });\n\n                if (closestTrace.distance < maxDistance + 1)\n                    plot.showTooltip(closestTrace.item, ttPos);\n                else\n                    plot.hideTooltip();\n            } else {\n                plot.hideTooltip();\n            }\n        }\n\n        // Quick little function for setting the tooltip position.\n        plot.setTooltipPosition = function (pos) {\n            var $tip = that.getDomElement();\n\n            var totalTipWidth = $tip.outerWidth() + that.tooltipOptions.shifts.x;\n            var totalTipHeight = $tip.outerHeight() + that.tooltipOptions.shifts.y;\n            if ((pos.x - $(window).scrollLeft()) > ($(window)[that.wfunc]() - totalTipWidth)) {\n                pos.x -= totalTipWidth;\n            }\n            if ((pos.y - $(window).scrollTop()) > ($(window)[that.hfunc]() - totalTipHeight)) {\n                pos.y -= totalTipHeight;\n            }\n\n\t    /* \n\t       The section applies the new positioning ONLY if pos.x and pos.y\n\t       are numbers. If they are undefined or not a number, use the last\n\t       known numerical position. This hack fixes a bug that kept pie \n\t       charts from keeping their tooltip positioning.\n\t     */\n\t    \n            if (isNaN(pos.x)) {\n\t\tthat.tipPosition.x = that.tipPosition.xPrev;\n\t    }\n\t    else {\n\t\tthat.tipPosition.x = pos.x;\n\t\tthat.tipPosition.xPrev = pos.x;\n\t    }\n\t    if (isNaN(pos.y)) {\n\t\tthat.tipPosition.y = that.tipPosition.yPrev;\n\t    }\n\t    else {\n\t\tthat.tipPosition.y = pos.y;\n\t\tthat.tipPosition.yPrev = pos.y;\n\t    }\n\t    \n        };\n\n        // Quick little function for showing the tooltip.\n        plot.showTooltip = function (target, position, targetPosition) {\n            var $tip = that.getDomElement();\n\n            // convert tooltip content template to real tipText\n            var tipText = that.stringFormat(that.tooltipOptions.content, target);\n            if (tipText === '')\n                return;\n\n            $tip.html(tipText);\n            plot.setTooltipPosition({ x: position.pageX, y: position.pageY });\n            $tip.css({\n                left: that.tipPosition.x + that.tooltipOptions.shifts.x,\n                top: that.tipPosition.y + that.tooltipOptions.shifts.y\n            }).show();\n\n            // run callback\n            if (typeof that.tooltipOptions.onHover === 'function') {\n                that.tooltipOptions.onHover(target, $tip);\n            }\n        };\n\n        // Quick little function for hiding the tooltip.\n        plot.hideTooltip = function () {\n            that.getDomElement().hide().html('');\n        };\n\n        plot.removeTooltip = function() {\n            that.getDomElement().remove();\n        };\n    };\n\n    /**\n     * get or create tooltip DOM element\n     * @return jQuery object\n     */\n    FlotTooltip.prototype.getDomElement = function () {\n        var $tip = $('<div>');\n        if (this.tooltipOptions && this.tooltipOptions.cssClass) {\n            $tip = $('.' + this.tooltipOptions.cssClass);\n\n            if( $tip.length === 0 ){\n                $tip = $('<div />').addClass(this.tooltipOptions.cssClass);\n                $tip.appendTo('body').hide().css({position: 'absolute'});\n    \n                if(this.tooltipOptions.defaultTheme) {\n                    $tip.css({\n                        'background': '#fff',\n                        'z-index': '1040',\n                        'padding': '0.4em 0.6em',\n                        'border-radius': '0.5em',\n                        'font-size': '0.8em',\n                        'border': '1px solid #111',\n                        'display': 'none',\n                        'white-space': 'nowrap'\n                    });\n                }\n            }\n        }\n\n        return $tip;\n    };\n\n    /**\n     * core function, create tooltip content\n     * @param  {string} content - template with tooltip content\n     * @param  {object} item - Flot item\n     * @return {string} real tooltip content for current item\n     */\n    FlotTooltip.prototype.stringFormat = function (content, item) {\n        var percentPattern = /%p\\.{0,1}(\\d{0,})/;\n        var seriesPattern = /%s/;\n        var colorPattern = /%c/;\n        var xLabelPattern = /%lx/; // requires flot-axislabels plugin https://github.com/markrcote/flot-axislabels, will be ignored if plugin isn't loaded\n        var yLabelPattern = /%ly/; // requires flot-axislabels plugin https://github.com/markrcote/flot-axislabels, will be ignored if plugin isn't loaded\n        var xPattern = /%x\\.{0,1}(\\d{0,})/;\n        var yPattern = /%y\\.{0,1}(\\d{0,})/;\n        var xPatternWithoutPrecision = \"%x\";\n        var yPatternWithoutPrecision = \"%y\";\n        var customTextPattern = \"%ct\";\n\tvar nPiePattern = \"%n\";\n\t\n        var x, y, customText, p, n;\n\n        // for threshold plugin we need to read data from different place\n        if (typeof item.series.threshold !== \"undefined\") {\n            x = item.datapoint[0];\n            y = item.datapoint[1];\n            customText = item.datapoint[2];\n\t}\n\n\t// for CurvedLines plugin we need to read data from different place\n\t    else if (typeof item.series.curvedLines !== \"undefined\") {\n\t\tx = item.datapoint[0];\n\t\ty = item.datapoint[1];\n\t    }\n\t    \n        else if (typeof item.series.lines !== \"undefined\" && item.series.lines.steps) {\n            x = item.series.datapoints.points[item.dataIndex * 2];\n            y = item.series.datapoints.points[item.dataIndex * 2 + 1];\n            // TODO: where to find custom text in this variant?\n            customText = \"\";\n        } else {\n            x = item.series.data[item.dataIndex][0];\n            y = item.series.data[item.dataIndex][1];\n            customText = item.series.data[item.dataIndex][2];\n        }\n\n        // I think this is only in case of threshold plugin\n        if (item.series.label === null && item.series.originSeries) {\n            item.series.label = item.series.originSeries.label;\n        }\n\n        // if it is a function callback get the content string\n        if (typeof(content) === 'function') {\n            content = content(item.series.label, x, y, item);\n        }\n\n        // the case where the passed content is equal to false\n        if (typeof(content) === 'boolean' && !content) {\n            return '';\n        }\n\n\t/* replacement of %ct and other multi-character templates must\n\t   precede the replacement of single-character templates \n\t   to avoid conflict between '%c' and '%ct'  and similar substrings\n\t*/\n\tif (customText)\n            content = content.replace(customTextPattern, customText);\n\n        // percent match for pie charts and stacked percent\n        if (typeof (item.series.percent) !== 'undefined') {\n            p = item.series.percent;\n        } else if (typeof (item.series.percents) !== 'undefined') {\n            p = item.series.percents[item.dataIndex];\n        }        \n        if (typeof p === 'number') {\n            content = this.adjustValPrecision(percentPattern, content, p);\n        }\n\n\t// replace %n with number of items represented by slice in pie charts\n\tif (item.series.hasOwnProperty('pie')) {\n\t    if (typeof (item.series.data[0][1] !== 'undefined')) {\n\t\tn = item.series.data[0][1];\n\t    }\n\t}\n\tif (typeof n === 'number') {\n            content = content.replace(nPiePattern, n);\n\t}\n\t\n        // series match\n        if (typeof(item.series.label) !== 'undefined') {\n            content = content.replace(seriesPattern, item.series.label);\n        } else {\n            //remove %s if label is undefined\n            content = content.replace(seriesPattern, \"\");\n        }\n        \n        // color match\n        if (typeof(item.series.color) !== 'undefined') {\n            content = content.replace(colorPattern, item.series.color);\n        } else {\n            //remove %s if color is undefined\n            content = content.replace(colorPattern, \"\");\n        }\n\n        // x axis label match\n        if (this.hasAxisLabel('xaxis', item)) {\n            content = content.replace(xLabelPattern, item.series.xaxis.options.axisLabel);\n        } else {\n            //remove %lx if axis label is undefined or axislabels plugin not present\n            content = content.replace(xLabelPattern, \"\");\n        }\n\n        // y axis label match\n        if (this.hasAxisLabel('yaxis', item)) {\n            content = content.replace(yLabelPattern, item.series.yaxis.options.axisLabel);\n        } else {\n            //remove %ly if axis label is undefined or axislabels plugin not present\n            content = content.replace(yLabelPattern, \"\");\n        }\n\n        // time mode axes with custom dateFormat\n        if (this.isTimeMode('xaxis', item) && this.isXDateFormat(item)) {\n            content = content.replace(xPattern, this.timestampToDate(x, this.tooltipOptions.xDateFormat, item.series.xaxis.options));\n        }\n        if (this.isTimeMode('yaxis', item) && this.isYDateFormat(item)) {\n            content = content.replace(yPattern, this.timestampToDate(y, this.tooltipOptions.yDateFormat, item.series.yaxis.options));\n        }\n\n        // set precision if defined\n        if (typeof x === 'number') {\n            content = this.adjustValPrecision(xPattern, content, x);\n        }\n        if (typeof y === 'number') {\n            content = this.adjustValPrecision(yPattern, content, y);\n        }\n\n        // change x from number to given label, if given\n        if (typeof item.series.xaxis.ticks !== 'undefined') {\n\n            var ticks;\n            if (this.hasRotatedXAxisTicks(item)) {\n                // xaxis.ticks will be an empty array if tickRotor is being used, but the values are available in rotatedTicks\n                ticks = 'rotatedTicks';\n            } else {\n                ticks = 'ticks';\n            }\n\n            // see https://github.com/krzysu/flot.tooltip/issues/65\n            var tickIndex = item.dataIndex + item.seriesIndex;\n\n            for (var xIndex in item.series.xaxis[ticks]) {\n                if (item.series.xaxis[ticks].hasOwnProperty(tickIndex) && !this.isTimeMode('xaxis', item)) {\n                    var valueX = (this.isCategoriesMode('xaxis', item)) ? item.series.xaxis[ticks][tickIndex].label : item.series.xaxis[ticks][tickIndex].v;\n                    if (valueX === x) {\n                        content = content.replace(xPattern, item.series.xaxis[ticks][tickIndex].label.replace(/\\$/g, '$$$$'));\n                    }\n                }\n            }\n        }\n\n        // change y from number to given label, if given\n        if (typeof item.series.yaxis.ticks !== 'undefined') {\n            for (var yIndex in item.series.yaxis.ticks) {\n                if (item.series.yaxis.ticks.hasOwnProperty(yIndex)) {\n                    var valueY = (this.isCategoriesMode('yaxis', item)) ? item.series.yaxis.ticks[yIndex].label : item.series.yaxis.ticks[yIndex].v;\n                    if (valueY === y) {\n                        content = content.replace(yPattern, item.series.yaxis.ticks[yIndex].label.replace(/\\$/g, '$$$$'));\n                    }\n                }\n            }\n        }\n\n        // if no value customization, use tickFormatter by default\n        if (typeof item.series.xaxis.tickFormatter !== 'undefined') {\n            //escape dollar\n            content = content.replace(xPatternWithoutPrecision, item.series.xaxis.tickFormatter(x, item.series.xaxis).replace(/\\$/g, '$$'));\n        }\n        if (typeof item.series.yaxis.tickFormatter !== 'undefined') {\n            //escape dollar\n            content = content.replace(yPatternWithoutPrecision, item.series.yaxis.tickFormatter(y, item.series.yaxis).replace(/\\$/g, '$$'));\n        }\n\n        return content;\n    };\n\n    // helpers just for readability\n    FlotTooltip.prototype.isTimeMode = function (axisName, item) {\n        return (typeof item.series[axisName].options.mode !== 'undefined' && item.series[axisName].options.mode === 'time');\n    };\n\n    FlotTooltip.prototype.isXDateFormat = function (item) {\n        return (typeof this.tooltipOptions.xDateFormat !== 'undefined' && this.tooltipOptions.xDateFormat !== null);\n    };\n\n    FlotTooltip.prototype.isYDateFormat = function (item) {\n        return (typeof this.tooltipOptions.yDateFormat !== 'undefined' && this.tooltipOptions.yDateFormat !== null);\n    };\n\n    FlotTooltip.prototype.isCategoriesMode = function (axisName, item) {\n        return (typeof item.series[axisName].options.mode !== 'undefined' && item.series[axisName].options.mode === 'categories');\n    };\n\n    //\n    FlotTooltip.prototype.timestampToDate = function (tmst, dateFormat, options) {\n        var theDate = $.plot.dateGenerator(tmst, options);\n        return $.plot.formatDate(theDate, dateFormat, this.tooltipOptions.monthNames, this.tooltipOptions.dayNames);\n    };\n\n    //\n    FlotTooltip.prototype.adjustValPrecision = function (pattern, content, value) {\n\n        var precision;\n        var matchResult = content.match(pattern);\n        if( matchResult !== null ) {\n            if(RegExp.$1 !== '') {\n                precision = RegExp.$1;\n                value = value.toFixed(precision);\n\n                // only replace content if precision exists, in other case use thickformater\n                content = content.replace(pattern, value);\n            }\n        }\n        return content;\n    };\n\n    // other plugins detection below\n\n    // check if flot-axislabels plugin (https://github.com/markrcote/flot-axislabels) is used and that an axis label is given\n    FlotTooltip.prototype.hasAxisLabel = function (axisName, item) {\n        return ($.inArray('axisLabels', this.plotPlugins) !== -1 && typeof item.series[axisName].options.axisLabel !== 'undefined' && item.series[axisName].options.axisLabel.length > 0);\n    };\n\n    // check whether flot-tickRotor, a plugin which allows rotation of X-axis ticks, is being used\n    FlotTooltip.prototype.hasRotatedXAxisTicks = function (item) {\n        return ($.inArray('tickRotor',this.plotPlugins) !== -1 && typeof item.series.xaxis.rotatedTicks !== 'undefined');\n    };\n\n    //\n    var init = function (plot) {\n      new FlotTooltip(plot);\n    };\n\n    // define Flot plugin\n    $.plot.plugins.push({\n        init: init,\n        options: defaultOptions,\n        name: 'tooltip',\n        version: '0.8.5'\n    });\n\n})(jQuery);\n"
  },
  {
    "path": "app_backend/vendor/flot-tooltip/jquery.flot.tooltip.source.js",
    "content": "(function ($) {\n    // plugin options, default values\n    var defaultOptions = {\n        tooltip: {\n            show: false,\n            cssClass: \"flotTip\",\n            content: \"%s | X: %x | Y: %y\",\n            // allowed templates are:\n            // %s -> series label,\n            // %c -> series color,\n            // %lx -> x axis label (requires flot-axislabels plugin https://github.com/markrcote/flot-axislabels),\n            // %ly -> y axis label (requires flot-axislabels plugin https://github.com/markrcote/flot-axislabels),\n            // %x -> X value,\n            // %y -> Y value,\n            // %x.2 -> precision of X value,\n            // %p -> percent\n\t    // %n -> value (not percent) of pie chart\n            xDateFormat: null,\n            yDateFormat: null,\n            monthNames: null,\n            dayNames: null,\n            shifts: {\n                x: 10,\n                y: 20\n            },\n            defaultTheme: true,\n            snap: true,\n            lines: false,\n            clickTips: false,\n\n            // callbacks\n            onHover: function (flotItem, $tooltipEl) {},\n\n            $compat: false\n        }\n    };\n\n    // dummy default options object for legacy code (<0.8.5) - is deleted later\n    defaultOptions.tooltipOpts = defaultOptions.tooltip;\n\n    // object\n    var FlotTooltip = function (plot) {\n        // variables\n        this.tipPosition = {x: 0, y: 0};\n\n        this.init(plot);\n    };\n\n    // main plugin function\n    FlotTooltip.prototype.init = function (plot) {\n        var that = this;\n\n        // detect other flot plugins\n        var plotPluginsLength = $.plot.plugins.length;\n        this.plotPlugins = [];\n\n        if (plotPluginsLength) {\n            for (var p = 0; p < plotPluginsLength; p++) {\n                this.plotPlugins.push($.plot.plugins[p].name);\n            }\n        }\n\n        plot.hooks.bindEvents.push(function (plot, eventHolder) {\n\n            // get plot options\n            that.plotOptions = plot.getOptions();\n\n            // for legacy (<0.8.5) implementations\n            if (typeof(that.plotOptions.tooltip) === 'boolean') {\n                that.plotOptions.tooltipOpts.show = that.plotOptions.tooltip;\n                that.plotOptions.tooltip = that.plotOptions.tooltipOpts;\n                delete that.plotOptions.tooltipOpts;\n            }\n\n            // if not enabled return\n            if (that.plotOptions.tooltip.show === false || typeof that.plotOptions.tooltip.show === 'undefined') return;\n\n            // shortcut to access tooltip options\n            that.tooltipOptions = that.plotOptions.tooltip;\n\n            if (that.tooltipOptions.$compat) {\n                that.wfunc = 'width';\n                that.hfunc = 'height';\n            } else {\n                that.wfunc = 'innerWidth';\n                that.hfunc = 'innerHeight';\n            }\n\n            // create tooltip DOM element\n            var $tip = that.getDomElement();\n\n            // bind event\n            $( plot.getPlaceholder() ).bind(\"plothover\", plothover);\n            if (that.tooltipOptions.clickTips) {\n                $( plot.getPlaceholder() ).bind(\"plotclick\", plotclick);\n            }\n            that.clickmode = false;\n\n            $(eventHolder).bind('mousemove', mouseMove);\n        });\n\n        plot.hooks.shutdown.push(function (plot, eventHolder){\n            $(plot.getPlaceholder()).unbind(\"plothover\", plothover);\n            $(plot.getPlaceholder()).unbind(\"plotclick\", plotclick);\n            plot.removeTooltip();\n            $(eventHolder).unbind(\"mousemove\", mouseMove);\n        });\n\n        function mouseMove(e){\n            var pos = {};\n            pos.x = e.pageX;\n            pos.y = e.pageY;\n            plot.setTooltipPosition(pos);\n        }\n\n        /**\n         *  open the tooltip (if not already open) and freeze it on the current position till the next click\n         */\n        function plotclick(event, pos, item) {\n            if (! that.clickmode) {\n                // it is the click activating the clicktip\n                plothover(event, pos, item);\n                if (that.getDomElement().is(\":visible\")) {\n                    $(plot.getPlaceholder()).unbind(\"plothover\", plothover);\n                    that.clickmode = true;\n                }\n            } else {\n                // it is the click deactivating the clicktip\n                $( plot.getPlaceholder() ).bind(\"plothover\", plothover);\n                plot.hideTooltip();\n                that.clickmode = false;\n            }\n        }\n\n        function plothover(event, pos, item) {\n            // Simple distance formula.\n            var lineDistance = function (p1x, p1y, p2x, p2y) {\n                return Math.sqrt((p2x - p1x) * (p2x - p1x) + (p2y - p1y) * (p2y - p1y));\n            };\n\n            // Here is some voodoo magic for determining the distance to a line form a given point {x, y}.\n            var dotLineLength = function (x, y, x0, y0, x1, y1, o) {\n                if (o && !(o =\n                    function (x, y, x0, y0, x1, y1) {\n                        if (typeof x0 !== 'undefined') return { x: x0, y: y };\n                        else if (typeof y0 !== 'undefined') return { x: x, y: y0 };\n\n                        var left,\n                            tg = -1 / ((y1 - y0) / (x1 - x0));\n\n                        return {\n                            x: left = (x1 * (x * tg - y + y0) + x0 * (x * -tg + y - y1)) / (tg * (x1 - x0) + y0 - y1),\n                            y: tg * left - tg * x + y\n                        };\n                    } (x, y, x0, y0, x1, y1),\n                    o.x >= Math.min(x0, x1) && o.x <= Math.max(x0, x1) && o.y >= Math.min(y0, y1) && o.y <= Math.max(y0, y1))\n                ) {\n                    var l1 = lineDistance(x, y, x0, y0), l2 = lineDistance(x, y, x1, y1);\n                    return l1 > l2 ? l2 : l1;\n                } else {\n                    var a = y0 - y1, b = x1 - x0, c = x0 * y1 - y0 * x1;\n                    return Math.abs(a * x + b * y + c) / Math.sqrt(a * a + b * b);\n                }\n            };\n\n            if (item) {\n                plot.showTooltip(item, that.tooltipOptions.snap ? item : pos);\n            } else if (that.plotOptions.series.lines.show && that.tooltipOptions.lines === true) {\n                var maxDistance = that.plotOptions.grid.mouseActiveRadius;\n\n                var closestTrace = {\n                    distance: maxDistance + 1\n                };\n\n                var ttPos = pos;\n\n                $.each(plot.getData(), function (i, series) {\n                    var xBeforeIndex = 0,\n                        xAfterIndex = -1;\n\n                    // Our search here assumes our data is sorted via the x-axis.\n                    // TODO: Improve efficiency somehow - search smaller sets of data.\n                    for (var j = 1; j < series.data.length; j++) {\n                        if (series.data[j - 1][0] <= pos.x && series.data[j][0] >= pos.x) {\n                            xBeforeIndex = j - 1;\n                            xAfterIndex = j;\n                        }\n                    }\n\n                    if (xAfterIndex === -1) {\n                        plot.hideTooltip();\n                        return;\n                    }\n\n                    var pointPrev = { x: series.data[xBeforeIndex][0], y: series.data[xBeforeIndex][1] },\n                        pointNext = { x: series.data[xAfterIndex][0], y: series.data[xAfterIndex][1] };\n\n                    var distToLine = dotLineLength(series.xaxis.p2c(pos.x), series.yaxis.p2c(pos.y), series.xaxis.p2c(pointPrev.x),\n                        series.yaxis.p2c(pointPrev.y), series.xaxis.p2c(pointNext.x), series.yaxis.p2c(pointNext.y), false);\n\n                    if (distToLine < closestTrace.distance) {\n\n                        var closestIndex = lineDistance(pointPrev.x, pointPrev.y, pos.x, pos.y) <\n                            lineDistance(pos.x, pos.y, pointNext.x, pointNext.y) ? xBeforeIndex : xAfterIndex;\n\n                        var pointSize = series.datapoints.pointsize;\n\n                        // Calculate the point on the line vertically closest to our cursor.\n                        var pointOnLine = [\n                            pos.x,\n                            pointPrev.y + ((pointNext.y - pointPrev.y) * ((pos.x - pointPrev.x) / (pointNext.x - pointPrev.x)))\n                        ];\n\n                        var item = {\n                            datapoint: pointOnLine,\n                            dataIndex: closestIndex,\n                            series: series,\n                            seriesIndex: i\n                        };\n\n                        closestTrace = {\n                            distance: distToLine,\n                            item: item\n                        };\n\n                        if (that.tooltipOptions.snap) {\n                            ttPos = {\n                                pageX: series.xaxis.p2c(pointOnLine[0]),\n                                pageY: series.yaxis.p2c(pointOnLine[1])\n                            };\n                        }\n                    }\n                });\n\n                if (closestTrace.distance < maxDistance + 1)\n                    plot.showTooltip(closestTrace.item, ttPos);\n                else\n                    plot.hideTooltip();\n            } else {\n                plot.hideTooltip();\n            }\n        }\n\n        // Quick little function for setting the tooltip position.\n        plot.setTooltipPosition = function (pos) {\n            var $tip = that.getDomElement();\n\n            var totalTipWidth = $tip.outerWidth() + that.tooltipOptions.shifts.x;\n            var totalTipHeight = $tip.outerHeight() + that.tooltipOptions.shifts.y;\n            if ((pos.x - $(window).scrollLeft()) > ($(window)[that.wfunc]() - totalTipWidth)) {\n                pos.x -= totalTipWidth;\n            }\n            if ((pos.y - $(window).scrollTop()) > ($(window)[that.hfunc]() - totalTipHeight)) {\n                pos.y -= totalTipHeight;\n            }\n\n\t    /* \n\t       The section applies the new positioning ONLY if pos.x and pos.y\n\t       are numbers. If they are undefined or not a number, use the last\n\t       known numerical position. This hack fixes a bug that kept pie \n\t       charts from keeping their tooltip positioning.\n\t     */\n\t    \n            if (isNaN(pos.x)) {\n\t\tthat.tipPosition.x = that.tipPosition.xPrev;\n\t    }\n\t    else {\n\t\tthat.tipPosition.x = pos.x;\n\t\tthat.tipPosition.xPrev = pos.x;\n\t    }\n\t    if (isNaN(pos.y)) {\n\t\tthat.tipPosition.y = that.tipPosition.yPrev;\n\t    }\n\t    else {\n\t\tthat.tipPosition.y = pos.y;\n\t\tthat.tipPosition.yPrev = pos.y;\n\t    }\n\t    \n        };\n\n        // Quick little function for showing the tooltip.\n        plot.showTooltip = function (target, position, targetPosition) {\n            var $tip = that.getDomElement();\n\n            // convert tooltip content template to real tipText\n            var tipText = that.stringFormat(that.tooltipOptions.content, target);\n            if (tipText === '')\n                return;\n\n            $tip.html(tipText);\n            plot.setTooltipPosition({ x: position.pageX, y: position.pageY });\n            $tip.css({\n                left: that.tipPosition.x + that.tooltipOptions.shifts.x,\n                top: that.tipPosition.y + that.tooltipOptions.shifts.y\n            }).show();\n\n            // run callback\n            if (typeof that.tooltipOptions.onHover === 'function') {\n                that.tooltipOptions.onHover(target, $tip);\n            }\n        };\n\n        // Quick little function for hiding the tooltip.\n        plot.hideTooltip = function () {\n            that.getDomElement().hide().html('');\n        };\n\n        plot.removeTooltip = function() {\n            that.getDomElement().remove();\n        };\n    };\n\n    /**\n     * get or create tooltip DOM element\n     * @return jQuery object\n     */\n    FlotTooltip.prototype.getDomElement = function () {\n        var $tip = $('<div>');\n        if (this.tooltipOptions && this.tooltipOptions.cssClass) {\n            $tip = $('.' + this.tooltipOptions.cssClass);\n\n            if( $tip.length === 0 ){\n                $tip = $('<div />').addClass(this.tooltipOptions.cssClass);\n                $tip.appendTo('body').hide().css({position: 'absolute'});\n    \n                if(this.tooltipOptions.defaultTheme) {\n                    $tip.css({\n                        'background': '#fff',\n                        'z-index': '1040',\n                        'padding': '0.4em 0.6em',\n                        'border-radius': '0.5em',\n                        'font-size': '0.8em',\n                        'border': '1px solid #111',\n                        'display': 'none',\n                        'white-space': 'nowrap'\n                    });\n                }\n            }\n        }\n\n        return $tip;\n    };\n\n    /**\n     * core function, create tooltip content\n     * @param  {string} content - template with tooltip content\n     * @param  {object} item - Flot item\n     * @return {string} real tooltip content for current item\n     */\n    FlotTooltip.prototype.stringFormat = function (content, item) {\n        var percentPattern = /%p\\.{0,1}(\\d{0,})/;\n        var seriesPattern = /%s/;\n        var colorPattern = /%c/;\n        var xLabelPattern = /%lx/; // requires flot-axislabels plugin https://github.com/markrcote/flot-axislabels, will be ignored if plugin isn't loaded\n        var yLabelPattern = /%ly/; // requires flot-axislabels plugin https://github.com/markrcote/flot-axislabels, will be ignored if plugin isn't loaded\n        var xPattern = /%x\\.{0,1}(\\d{0,})/;\n        var yPattern = /%y\\.{0,1}(\\d{0,})/;\n        var xPatternWithoutPrecision = \"%x\";\n        var yPatternWithoutPrecision = \"%y\";\n        var customTextPattern = \"%ct\";\n\tvar nPiePattern = \"%n\";\n\t\n        var x, y, customText, p, n;\n\n        // for threshold plugin we need to read data from different place\n        if (typeof item.series.threshold !== \"undefined\") {\n            x = item.datapoint[0];\n            y = item.datapoint[1];\n            customText = item.datapoint[2];\n\t}\n\n\t// for CurvedLines plugin we need to read data from different place\n\t    else if (typeof item.series.curvedLines !== \"undefined\") {\n\t\tx = item.datapoint[0];\n\t\ty = item.datapoint[1];\n\t    }\n\t    \n        else if (typeof item.series.lines !== \"undefined\" && item.series.lines.steps) {\n            x = item.series.datapoints.points[item.dataIndex * 2];\n            y = item.series.datapoints.points[item.dataIndex * 2 + 1];\n            // TODO: where to find custom text in this variant?\n            customText = \"\";\n        } else {\n            x = item.series.data[item.dataIndex][0];\n            y = item.series.data[item.dataIndex][1];\n            customText = item.series.data[item.dataIndex][2];\n        }\n\n        // I think this is only in case of threshold plugin\n        if (item.series.label === null && item.series.originSeries) {\n            item.series.label = item.series.originSeries.label;\n        }\n\n        // if it is a function callback get the content string\n        if (typeof(content) === 'function') {\n            content = content(item.series.label, x, y, item);\n        }\n\n        // the case where the passed content is equal to false\n        if (typeof(content) === 'boolean' && !content) {\n            return '';\n        }\n\n\t/* replacement of %ct and other multi-character templates must\n\t   precede the replacement of single-character templates \n\t   to avoid conflict between '%c' and '%ct'  and similar substrings\n\t*/\n\tif (customText)\n            content = content.replace(customTextPattern, customText);\n\n        // percent match for pie charts and stacked percent\n        if (typeof (item.series.percent) !== 'undefined') {\n            p = item.series.percent;\n        } else if (typeof (item.series.percents) !== 'undefined') {\n            p = item.series.percents[item.dataIndex];\n        }        \n        if (typeof p === 'number') {\n            content = this.adjustValPrecision(percentPattern, content, p);\n        }\n\n\t// replace %n with number of items represented by slice in pie charts\n\tif (item.series.hasOwnProperty('pie')) {\n\t    if (typeof (item.series.data[0][1] !== 'undefined')) {\n\t\tn = item.series.data[0][1];\n\t    }\n\t}\n\tif (typeof n === 'number') {\n            content = content.replace(nPiePattern, n);\n\t}\n\t\n        // series match\n        if (typeof(item.series.label) !== 'undefined') {\n            content = content.replace(seriesPattern, item.series.label);\n        } else {\n            //remove %s if label is undefined\n            content = content.replace(seriesPattern, \"\");\n        }\n        \n        // color match\n        if (typeof(item.series.color) !== 'undefined') {\n            content = content.replace(colorPattern, item.series.color);\n        } else {\n            //remove %s if color is undefined\n            content = content.replace(colorPattern, \"\");\n        }\n\n        // x axis label match\n        if (this.hasAxisLabel('xaxis', item)) {\n            content = content.replace(xLabelPattern, item.series.xaxis.options.axisLabel);\n        } else {\n            //remove %lx if axis label is undefined or axislabels plugin not present\n            content = content.replace(xLabelPattern, \"\");\n        }\n\n        // y axis label match\n        if (this.hasAxisLabel('yaxis', item)) {\n            content = content.replace(yLabelPattern, item.series.yaxis.options.axisLabel);\n        } else {\n            //remove %ly if axis label is undefined or axislabels plugin not present\n            content = content.replace(yLabelPattern, \"\");\n        }\n\n        // time mode axes with custom dateFormat\n        if (this.isTimeMode('xaxis', item) && this.isXDateFormat(item)) {\n            content = content.replace(xPattern, this.timestampToDate(x, this.tooltipOptions.xDateFormat, item.series.xaxis.options));\n        }\n        if (this.isTimeMode('yaxis', item) && this.isYDateFormat(item)) {\n            content = content.replace(yPattern, this.timestampToDate(y, this.tooltipOptions.yDateFormat, item.series.yaxis.options));\n        }\n\n        // set precision if defined\n        if (typeof x === 'number') {\n            content = this.adjustValPrecision(xPattern, content, x);\n        }\n        if (typeof y === 'number') {\n            content = this.adjustValPrecision(yPattern, content, y);\n        }\n\n        // change x from number to given label, if given\n        if (typeof item.series.xaxis.ticks !== 'undefined') {\n\n            var ticks;\n            if (this.hasRotatedXAxisTicks(item)) {\n                // xaxis.ticks will be an empty array if tickRotor is being used, but the values are available in rotatedTicks\n                ticks = 'rotatedTicks';\n            } else {\n                ticks = 'ticks';\n            }\n\n            // see https://github.com/krzysu/flot.tooltip/issues/65\n            var tickIndex = item.dataIndex + item.seriesIndex;\n\n            for (var xIndex in item.series.xaxis[ticks]) {\n                if (item.series.xaxis[ticks].hasOwnProperty(tickIndex) && !this.isTimeMode('xaxis', item)) {\n                    var valueX = (this.isCategoriesMode('xaxis', item)) ? item.series.xaxis[ticks][tickIndex].label : item.series.xaxis[ticks][tickIndex].v;\n                    if (valueX === x) {\n                        content = content.replace(xPattern, item.series.xaxis[ticks][tickIndex].label.replace(/\\$/g, '$$$$'));\n                    }\n                }\n            }\n        }\n\n        // change y from number to given label, if given\n        if (typeof item.series.yaxis.ticks !== 'undefined') {\n            for (var yIndex in item.series.yaxis.ticks) {\n                if (item.series.yaxis.ticks.hasOwnProperty(yIndex)) {\n                    var valueY = (this.isCategoriesMode('yaxis', item)) ? item.series.yaxis.ticks[yIndex].label : item.series.yaxis.ticks[yIndex].v;\n                    if (valueY === y) {\n                        content = content.replace(yPattern, item.series.yaxis.ticks[yIndex].label.replace(/\\$/g, '$$$$'));\n                    }\n                }\n            }\n        }\n\n        // if no value customization, use tickFormatter by default\n        if (typeof item.series.xaxis.tickFormatter !== 'undefined') {\n            //escape dollar\n            content = content.replace(xPatternWithoutPrecision, item.series.xaxis.tickFormatter(x, item.series.xaxis).replace(/\\$/g, '$$'));\n        }\n        if (typeof item.series.yaxis.tickFormatter !== 'undefined') {\n            //escape dollar\n            content = content.replace(yPatternWithoutPrecision, item.series.yaxis.tickFormatter(y, item.series.yaxis).replace(/\\$/g, '$$'));\n        }\n\n        return content;\n    };\n\n    // helpers just for readability\n    FlotTooltip.prototype.isTimeMode = function (axisName, item) {\n        return (typeof item.series[axisName].options.mode !== 'undefined' && item.series[axisName].options.mode === 'time');\n    };\n\n    FlotTooltip.prototype.isXDateFormat = function (item) {\n        return (typeof this.tooltipOptions.xDateFormat !== 'undefined' && this.tooltipOptions.xDateFormat !== null);\n    };\n\n    FlotTooltip.prototype.isYDateFormat = function (item) {\n        return (typeof this.tooltipOptions.yDateFormat !== 'undefined' && this.tooltipOptions.yDateFormat !== null);\n    };\n\n    FlotTooltip.prototype.isCategoriesMode = function (axisName, item) {\n        return (typeof item.series[axisName].options.mode !== 'undefined' && item.series[axisName].options.mode === 'categories');\n    };\n\n    //\n    FlotTooltip.prototype.timestampToDate = function (tmst, dateFormat, options) {\n        var theDate = $.plot.dateGenerator(tmst, options);\n        return $.plot.formatDate(theDate, dateFormat, this.tooltipOptions.monthNames, this.tooltipOptions.dayNames);\n    };\n\n    //\n    FlotTooltip.prototype.adjustValPrecision = function (pattern, content, value) {\n\n        var precision;\n        var matchResult = content.match(pattern);\n        if( matchResult !== null ) {\n            if(RegExp.$1 !== '') {\n                precision = RegExp.$1;\n                value = value.toFixed(precision);\n\n                // only replace content if precision exists, in other case use thickformater\n                content = content.replace(pattern, value);\n            }\n        }\n        return content;\n    };\n\n    // other plugins detection below\n\n    // check if flot-axislabels plugin (https://github.com/markrcote/flot-axislabels) is used and that an axis label is given\n    FlotTooltip.prototype.hasAxisLabel = function (axisName, item) {\n        return ($.inArray('axisLabels', this.plotPlugins) !== -1 && typeof item.series[axisName].options.axisLabel !== 'undefined' && item.series[axisName].options.axisLabel.length > 0);\n    };\n\n    // check whether flot-tickRotor, a plugin which allows rotation of X-axis ticks, is being used\n    FlotTooltip.prototype.hasRotatedXAxisTicks = function (item) {\n        return ($.inArray('tickRotor',this.plotPlugins) !== -1 && typeof item.series.xaxis.rotatedTicks !== 'undefined');\n    };\n\n    //\n    var init = function (plot) {\n      new FlotTooltip(plot);\n    };\n\n    // define Flot plugin\n    $.plot.plugins.push({\n        init: init,\n        options: defaultOptions,\n        name: 'tooltip',\n        version: '0.8.5'\n    });\n\n})(jQuery);\n"
  },
  {
    "path": "app_backend/vendor/font-awesome/HELP-US-OUT.txt",
    "content": "I hope you love Font Awesome. If you've found it useful, please do me a favor and check out my latest project,\nFort Awesome (https://fortawesome.com). It makes it easy to put the perfect icons on your website. Choose from our awesome,\ncomprehensive icon sets or copy and paste your own.\n\nPlease. Check it out.\n\n-Dave Gandy\n"
  },
  {
    "path": "app_backend/vendor/font-awesome/css/font-awesome.css",
    "content": "/*!\n *  Font Awesome 4.6.3 by @davegandy - http://fontawesome.io - @fontawesome\n *  License - http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License)\n */\n/* FONT PATH\n * -------------------------- */\n@font-face {\n  font-family: 'FontAwesome';\n  src: url('../fonts/fontawesome-webfont.eot?v=4.6.3');\n  src: url('../fonts/fontawesome-webfont.eot?#iefix&v=4.6.3') format('embedded-opentype'), url('../fonts/fontawesome-webfont.woff2?v=4.6.3') format('woff2'), url('../fonts/fontawesome-webfont.woff?v=4.6.3') format('woff'), url('../fonts/fontawesome-webfont.ttf?v=4.6.3') format('truetype'), url('../fonts/fontawesome-webfont.svg?v=4.6.3#fontawesomeregular') format('svg');\n  font-weight: normal;\n  font-style: normal;\n}\n.fa {\n  display: inline-block;\n  font: normal normal normal 14px/1 FontAwesome;\n  font-size: inherit;\n  text-rendering: auto;\n  -webkit-font-smoothing: antialiased;\n  -moz-osx-font-smoothing: grayscale;\n}\n/* makes the font 33% larger relative to the icon container */\n.fa-lg {\n  font-size: 1.33333333em;\n  line-height: 0.75em;\n  vertical-align: -15%;\n}\n.fa-2x {\n  font-size: 2em;\n}\n.fa-3x {\n  font-size: 3em;\n}\n.fa-4x {\n  font-size: 4em;\n}\n.fa-5x {\n  font-size: 5em;\n}\n.fa-fw {\n  width: 1.28571429em;\n  text-align: center;\n}\n.fa-ul {\n  padding-left: 0;\n  margin-left: 2.14285714em;\n  list-style-type: none;\n}\n.fa-ul > li {\n  position: relative;\n}\n.fa-li {\n  position: absolute;\n  left: -2.14285714em;\n  width: 2.14285714em;\n  top: 0.14285714em;\n  text-align: center;\n}\n.fa-li.fa-lg {\n  left: -1.85714286em;\n}\n.fa-border {\n  padding: .2em .25em .15em;\n  border: solid 0.08em #eeeeee;\n  border-radius: .1em;\n}\n.fa-pull-left {\n  float: left;\n}\n.fa-pull-right {\n  float: right;\n}\n.fa.fa-pull-left {\n  margin-right: .3em;\n}\n.fa.fa-pull-right {\n  margin-left: .3em;\n}\n/* Deprecated as of 4.4.0 */\n.pull-right {\n  float: right;\n}\n.pull-left {\n  float: left;\n}\n.fa.pull-left {\n  margin-right: .3em;\n}\n.fa.pull-right {\n  margin-left: .3em;\n}\n.fa-spin {\n  -webkit-animation: fa-spin 2s infinite linear;\n  animation: fa-spin 2s infinite linear;\n}\n.fa-pulse {\n  -webkit-animation: fa-spin 1s infinite steps(8);\n  animation: fa-spin 1s infinite steps(8);\n}\n@-webkit-keyframes fa-spin {\n  0% {\n    -webkit-transform: rotate(0deg);\n    transform: rotate(0deg);\n  }\n  100% {\n    -webkit-transform: rotate(359deg);\n    transform: rotate(359deg);\n  }\n}\n@keyframes fa-spin {\n  0% {\n    -webkit-transform: rotate(0deg);\n    transform: rotate(0deg);\n  }\n  100% {\n    -webkit-transform: rotate(359deg);\n    transform: rotate(359deg);\n  }\n}\n.fa-rotate-90 {\n  -ms-filter: \"progid:DXImageTransform.Microsoft.BasicImage(rotation=1)\";\n  -webkit-transform: rotate(90deg);\n  -ms-transform: rotate(90deg);\n  transform: rotate(90deg);\n}\n.fa-rotate-180 {\n  -ms-filter: \"progid:DXImageTransform.Microsoft.BasicImage(rotation=2)\";\n  -webkit-transform: rotate(180deg);\n  -ms-transform: rotate(180deg);\n  transform: rotate(180deg);\n}\n.fa-rotate-270 {\n  -ms-filter: \"progid:DXImageTransform.Microsoft.BasicImage(rotation=3)\";\n  -webkit-transform: rotate(270deg);\n  -ms-transform: rotate(270deg);\n  transform: rotate(270deg);\n}\n.fa-flip-horizontal {\n  -ms-filter: \"progid:DXImageTransform.Microsoft.BasicImage(rotation=0, mirror=1)\";\n  -webkit-transform: scale(-1, 1);\n  -ms-transform: scale(-1, 1);\n  transform: scale(-1, 1);\n}\n.fa-flip-vertical {\n  -ms-filter: \"progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1)\";\n  -webkit-transform: scale(1, -1);\n  -ms-transform: scale(1, -1);\n  transform: scale(1, -1);\n}\n:root .fa-rotate-90,\n:root .fa-rotate-180,\n:root .fa-rotate-270,\n:root .fa-flip-horizontal,\n:root .fa-flip-vertical {\n  filter: none;\n}\n.fa-stack {\n  position: relative;\n  display: inline-block;\n  width: 2em;\n  height: 2em;\n  line-height: 2em;\n  vertical-align: middle;\n}\n.fa-stack-1x,\n.fa-stack-2x {\n  position: absolute;\n  left: 0;\n  width: 100%;\n  text-align: center;\n}\n.fa-stack-1x {\n  line-height: inherit;\n}\n.fa-stack-2x {\n  font-size: 2em;\n}\n.fa-inverse {\n  color: #ffffff;\n}\n/* Font Awesome uses the Unicode Private Use Area (PUA) to ensure screen\n   readers do not read off random characters that represent icons */\n.fa-glass:before {\n  content: \"\\f000\";\n}\n.fa-music:before {\n  content: \"\\f001\";\n}\n.fa-search:before {\n  content: \"\\f002\";\n}\n.fa-envelope-o:before {\n  content: \"\\f003\";\n}\n.fa-heart:before {\n  content: \"\\f004\";\n}\n.fa-star:before {\n  content: \"\\f005\";\n}\n.fa-star-o:before {\n  content: \"\\f006\";\n}\n.fa-user:before {\n  content: \"\\f007\";\n}\n.fa-film:before {\n  content: \"\\f008\";\n}\n.fa-th-large:before {\n  content: \"\\f009\";\n}\n.fa-th:before {\n  content: \"\\f00a\";\n}\n.fa-th-list:before {\n  content: \"\\f00b\";\n}\n.fa-check:before {\n  content: \"\\f00c\";\n}\n.fa-remove:before,\n.fa-close:before,\n.fa-times:before {\n  content: \"\\f00d\";\n}\n.fa-search-plus:before {\n  content: \"\\f00e\";\n}\n.fa-search-minus:before {\n  content: \"\\f010\";\n}\n.fa-power-off:before {\n  content: \"\\f011\";\n}\n.fa-signal:before {\n  content: \"\\f012\";\n}\n.fa-gear:before,\n.fa-cog:before {\n  content: \"\\f013\";\n}\n.fa-trash-o:before {\n  content: \"\\f014\";\n}\n.fa-home:before {\n  content: \"\\f015\";\n}\n.fa-file-o:before {\n  content: \"\\f016\";\n}\n.fa-clock-o:before {\n  content: \"\\f017\";\n}\n.fa-road:before {\n  content: \"\\f018\";\n}\n.fa-download:before {\n  content: \"\\f019\";\n}\n.fa-arrow-circle-o-down:before {\n  content: \"\\f01a\";\n}\n.fa-arrow-circle-o-up:before {\n  content: \"\\f01b\";\n}\n.fa-inbox:before {\n  content: \"\\f01c\";\n}\n.fa-play-circle-o:before {\n  content: \"\\f01d\";\n}\n.fa-rotate-right:before,\n.fa-repeat:before {\n  content: \"\\f01e\";\n}\n.fa-refresh:before {\n  content: \"\\f021\";\n}\n.fa-list-alt:before {\n  content: \"\\f022\";\n}\n.fa-lock:before {\n  content: \"\\f023\";\n}\n.fa-flag:before {\n  content: \"\\f024\";\n}\n.fa-headphones:before {\n  content: \"\\f025\";\n}\n.fa-volume-off:before {\n  content: \"\\f026\";\n}\n.fa-volume-down:before {\n  content: \"\\f027\";\n}\n.fa-volume-up:before {\n  content: \"\\f028\";\n}\n.fa-qrcode:before {\n  content: \"\\f029\";\n}\n.fa-barcode:before {\n  content: \"\\f02a\";\n}\n.fa-tag:before {\n  content: \"\\f02b\";\n}\n.fa-tags:before {\n  content: \"\\f02c\";\n}\n.fa-book:before {\n  content: \"\\f02d\";\n}\n.fa-bookmark:before {\n  content: \"\\f02e\";\n}\n.fa-print:before {\n  content: \"\\f02f\";\n}\n.fa-camera:before {\n  content: \"\\f030\";\n}\n.fa-font:before {\n  content: \"\\f031\";\n}\n.fa-bold:before {\n  content: \"\\f032\";\n}\n.fa-italic:before {\n  content: \"\\f033\";\n}\n.fa-text-height:before {\n  content: \"\\f034\";\n}\n.fa-text-width:before {\n  content: \"\\f035\";\n}\n.fa-align-left:before {\n  content: \"\\f036\";\n}\n.fa-align-center:before {\n  content: \"\\f037\";\n}\n.fa-align-right:before {\n  content: \"\\f038\";\n}\n.fa-align-justify:before {\n  content: \"\\f039\";\n}\n.fa-list:before {\n  content: \"\\f03a\";\n}\n.fa-dedent:before,\n.fa-outdent:before {\n  content: \"\\f03b\";\n}\n.fa-indent:before {\n  content: \"\\f03c\";\n}\n.fa-video-camera:before {\n  content: \"\\f03d\";\n}\n.fa-photo:before,\n.fa-image:before,\n.fa-picture-o:before {\n  content: \"\\f03e\";\n}\n.fa-pencil:before {\n  content: \"\\f040\";\n}\n.fa-map-marker:before {\n  content: \"\\f041\";\n}\n.fa-adjust:before {\n  content: \"\\f042\";\n}\n.fa-tint:before {\n  content: \"\\f043\";\n}\n.fa-edit:before,\n.fa-pencil-square-o:before {\n  content: \"\\f044\";\n}\n.fa-share-square-o:before {\n  content: \"\\f045\";\n}\n.fa-check-square-o:before {\n  content: \"\\f046\";\n}\n.fa-arrows:before {\n  content: \"\\f047\";\n}\n.fa-step-backward:before {\n  content: \"\\f048\";\n}\n.fa-fast-backward:before {\n  content: \"\\f049\";\n}\n.fa-backward:before {\n  content: \"\\f04a\";\n}\n.fa-play:before {\n  content: \"\\f04b\";\n}\n.fa-pause:before {\n  content: \"\\f04c\";\n}\n.fa-stop:before {\n  content: \"\\f04d\";\n}\n.fa-forward:before {\n  content: \"\\f04e\";\n}\n.fa-fast-forward:before {\n  content: \"\\f050\";\n}\n.fa-step-forward:before {\n  content: \"\\f051\";\n}\n.fa-eject:before {\n  content: \"\\f052\";\n}\n.fa-chevron-left:before {\n  content: \"\\f053\";\n}\n.fa-chevron-right:before {\n  content: \"\\f054\";\n}\n.fa-plus-circle:before {\n  content: \"\\f055\";\n}\n.fa-minus-circle:before {\n  content: \"\\f056\";\n}\n.fa-times-circle:before {\n  content: \"\\f057\";\n}\n.fa-check-circle:before {\n  content: \"\\f058\";\n}\n.fa-question-circle:before {\n  content: \"\\f059\";\n}\n.fa-info-circle:before {\n  content: \"\\f05a\";\n}\n.fa-crosshairs:before {\n  content: \"\\f05b\";\n}\n.fa-times-circle-o:before {\n  content: \"\\f05c\";\n}\n.fa-check-circle-o:before {\n  content: \"\\f05d\";\n}\n.fa-ban:before {\n  content: \"\\f05e\";\n}\n.fa-arrow-left:before {\n  content: \"\\f060\";\n}\n.fa-arrow-right:before {\n  content: \"\\f061\";\n}\n.fa-arrow-up:before {\n  content: \"\\f062\";\n}\n.fa-arrow-down:before {\n  content: \"\\f063\";\n}\n.fa-mail-forward:before,\n.fa-share:before {\n  content: \"\\f064\";\n}\n.fa-expand:before {\n  content: \"\\f065\";\n}\n.fa-compress:before {\n  content: \"\\f066\";\n}\n.fa-plus:before {\n  content: \"\\f067\";\n}\n.fa-minus:before {\n  content: \"\\f068\";\n}\n.fa-asterisk:before {\n  content: \"\\f069\";\n}\n.fa-exclamation-circle:before {\n  content: \"\\f06a\";\n}\n.fa-gift:before {\n  content: \"\\f06b\";\n}\n.fa-leaf:before {\n  content: \"\\f06c\";\n}\n.fa-fire:before {\n  content: \"\\f06d\";\n}\n.fa-eye:before {\n  content: \"\\f06e\";\n}\n.fa-eye-slash:before {\n  content: \"\\f070\";\n}\n.fa-warning:before,\n.fa-exclamation-triangle:before {\n  content: \"\\f071\";\n}\n.fa-plane:before {\n  content: \"\\f072\";\n}\n.fa-calendar:before {\n  content: \"\\f073\";\n}\n.fa-random:before {\n  content: \"\\f074\";\n}\n.fa-comment:before {\n  content: \"\\f075\";\n}\n.fa-magnet:before {\n  content: \"\\f076\";\n}\n.fa-chevron-up:before {\n  content: \"\\f077\";\n}\n.fa-chevron-down:before {\n  content: \"\\f078\";\n}\n.fa-retweet:before {\n  content: \"\\f079\";\n}\n.fa-shopping-cart:before {\n  content: \"\\f07a\";\n}\n.fa-folder:before {\n  content: \"\\f07b\";\n}\n.fa-folder-open:before {\n  content: \"\\f07c\";\n}\n.fa-arrows-v:before {\n  content: \"\\f07d\";\n}\n.fa-arrows-h:before {\n  content: \"\\f07e\";\n}\n.fa-bar-chart-o:before,\n.fa-bar-chart:before {\n  content: \"\\f080\";\n}\n.fa-twitter-square:before {\n  content: \"\\f081\";\n}\n.fa-facebook-square:before {\n  content: \"\\f082\";\n}\n.fa-camera-retro:before {\n  content: \"\\f083\";\n}\n.fa-key:before {\n  content: \"\\f084\";\n}\n.fa-gears:before,\n.fa-cogs:before {\n  content: \"\\f085\";\n}\n.fa-comments:before {\n  content: \"\\f086\";\n}\n.fa-thumbs-o-up:before {\n  content: \"\\f087\";\n}\n.fa-thumbs-o-down:before {\n  content: \"\\f088\";\n}\n.fa-star-half:before {\n  content: \"\\f089\";\n}\n.fa-heart-o:before {\n  content: \"\\f08a\";\n}\n.fa-sign-out:before {\n  content: \"\\f08b\";\n}\n.fa-linkedin-square:before {\n  content: \"\\f08c\";\n}\n.fa-thumb-tack:before {\n  content: \"\\f08d\";\n}\n.fa-external-link:before {\n  content: \"\\f08e\";\n}\n.fa-sign-in:before {\n  content: \"\\f090\";\n}\n.fa-trophy:before {\n  content: \"\\f091\";\n}\n.fa-github-square:before {\n  content: \"\\f092\";\n}\n.fa-upload:before {\n  content: \"\\f093\";\n}\n.fa-lemon-o:before {\n  content: \"\\f094\";\n}\n.fa-phone:before {\n  content: \"\\f095\";\n}\n.fa-square-o:before {\n  content: \"\\f096\";\n}\n.fa-bookmark-o:before {\n  content: \"\\f097\";\n}\n.fa-phone-square:before {\n  content: \"\\f098\";\n}\n.fa-twitter:before {\n  content: \"\\f099\";\n}\n.fa-facebook-f:before,\n.fa-facebook:before {\n  content: \"\\f09a\";\n}\n.fa-github:before {\n  content: \"\\f09b\";\n}\n.fa-unlock:before {\n  content: \"\\f09c\";\n}\n.fa-credit-card:before {\n  content: \"\\f09d\";\n}\n.fa-feed:before,\n.fa-rss:before {\n  content: \"\\f09e\";\n}\n.fa-hdd-o:before {\n  content: \"\\f0a0\";\n}\n.fa-bullhorn:before {\n  content: \"\\f0a1\";\n}\n.fa-bell:before {\n  content: \"\\f0f3\";\n}\n.fa-certificate:before {\n  content: \"\\f0a3\";\n}\n.fa-hand-o-right:before {\n  content: \"\\f0a4\";\n}\n.fa-hand-o-left:before {\n  content: \"\\f0a5\";\n}\n.fa-hand-o-up:before {\n  content: \"\\f0a6\";\n}\n.fa-hand-o-down:before {\n  content: \"\\f0a7\";\n}\n.fa-arrow-circle-left:before {\n  content: \"\\f0a8\";\n}\n.fa-arrow-circle-right:before {\n  content: \"\\f0a9\";\n}\n.fa-arrow-circle-up:before {\n  content: \"\\f0aa\";\n}\n.fa-arrow-circle-down:before {\n  content: \"\\f0ab\";\n}\n.fa-globe:before {\n  content: \"\\f0ac\";\n}\n.fa-wrench:before {\n  content: \"\\f0ad\";\n}\n.fa-tasks:before {\n  content: \"\\f0ae\";\n}\n.fa-filter:before {\n  content: \"\\f0b0\";\n}\n.fa-briefcase:before {\n  content: \"\\f0b1\";\n}\n.fa-arrows-alt:before {\n  content: \"\\f0b2\";\n}\n.fa-group:before,\n.fa-users:before {\n  content: \"\\f0c0\";\n}\n.fa-chain:before,\n.fa-link:before {\n  content: \"\\f0c1\";\n}\n.fa-cloud:before {\n  content: \"\\f0c2\";\n}\n.fa-flask:before {\n  content: \"\\f0c3\";\n}\n.fa-cut:before,\n.fa-scissors:before {\n  content: \"\\f0c4\";\n}\n.fa-copy:before,\n.fa-files-o:before {\n  content: \"\\f0c5\";\n}\n.fa-paperclip:before {\n  content: \"\\f0c6\";\n}\n.fa-save:before,\n.fa-floppy-o:before {\n  content: \"\\f0c7\";\n}\n.fa-square:before {\n  content: \"\\f0c8\";\n}\n.fa-navicon:before,\n.fa-reorder:before,\n.fa-bars:before {\n  content: \"\\f0c9\";\n}\n.fa-list-ul:before {\n  content: \"\\f0ca\";\n}\n.fa-list-ol:before {\n  content: \"\\f0cb\";\n}\n.fa-strikethrough:before {\n  content: \"\\f0cc\";\n}\n.fa-underline:before {\n  content: \"\\f0cd\";\n}\n.fa-table:before {\n  content: \"\\f0ce\";\n}\n.fa-magic:before {\n  content: \"\\f0d0\";\n}\n.fa-truck:before {\n  content: \"\\f0d1\";\n}\n.fa-pinterest:before {\n  content: \"\\f0d2\";\n}\n.fa-pinterest-square:before {\n  content: \"\\f0d3\";\n}\n.fa-google-plus-square:before {\n  content: \"\\f0d4\";\n}\n.fa-google-plus:before {\n  content: \"\\f0d5\";\n}\n.fa-money:before {\n  content: \"\\f0d6\";\n}\n.fa-caret-down:before {\n  content: \"\\f0d7\";\n}\n.fa-caret-up:before {\n  content: \"\\f0d8\";\n}\n.fa-caret-left:before {\n  content: \"\\f0d9\";\n}\n.fa-caret-right:before {\n  content: \"\\f0da\";\n}\n.fa-columns:before {\n  content: \"\\f0db\";\n}\n.fa-unsorted:before,\n.fa-sort:before {\n  content: \"\\f0dc\";\n}\n.fa-sort-down:before,\n.fa-sort-desc:before {\n  content: \"\\f0dd\";\n}\n.fa-sort-up:before,\n.fa-sort-asc:before {\n  content: \"\\f0de\";\n}\n.fa-envelope:before {\n  content: \"\\f0e0\";\n}\n.fa-linkedin:before {\n  content: \"\\f0e1\";\n}\n.fa-rotate-left:before,\n.fa-undo:before {\n  content: \"\\f0e2\";\n}\n.fa-legal:before,\n.fa-gavel:before {\n  content: \"\\f0e3\";\n}\n.fa-dashboard:before,\n.fa-tachometer:before {\n  content: \"\\f0e4\";\n}\n.fa-comment-o:before {\n  content: \"\\f0e5\";\n}\n.fa-comments-o:before {\n  content: \"\\f0e6\";\n}\n.fa-flash:before,\n.fa-bolt:before {\n  content: \"\\f0e7\";\n}\n.fa-sitemap:before {\n  content: \"\\f0e8\";\n}\n.fa-umbrella:before {\n  content: \"\\f0e9\";\n}\n.fa-paste:before,\n.fa-clipboard:before {\n  content: \"\\f0ea\";\n}\n.fa-lightbulb-o:before {\n  content: \"\\f0eb\";\n}\n.fa-exchange:before {\n  content: \"\\f0ec\";\n}\n.fa-cloud-download:before {\n  content: \"\\f0ed\";\n}\n.fa-cloud-upload:before {\n  content: \"\\f0ee\";\n}\n.fa-user-md:before {\n  content: \"\\f0f0\";\n}\n.fa-stethoscope:before {\n  content: \"\\f0f1\";\n}\n.fa-suitcase:before {\n  content: \"\\f0f2\";\n}\n.fa-bell-o:before {\n  content: \"\\f0a2\";\n}\n.fa-coffee:before {\n  content: \"\\f0f4\";\n}\n.fa-cutlery:before {\n  content: \"\\f0f5\";\n}\n.fa-file-text-o:before {\n  content: \"\\f0f6\";\n}\n.fa-building-o:before {\n  content: \"\\f0f7\";\n}\n.fa-hospital-o:before {\n  content: \"\\f0f8\";\n}\n.fa-ambulance:before {\n  content: \"\\f0f9\";\n}\n.fa-medkit:before {\n  content: \"\\f0fa\";\n}\n.fa-fighter-jet:before {\n  content: \"\\f0fb\";\n}\n.fa-beer:before {\n  content: \"\\f0fc\";\n}\n.fa-h-square:before {\n  content: \"\\f0fd\";\n}\n.fa-plus-square:before {\n  content: \"\\f0fe\";\n}\n.fa-angle-double-left:before {\n  content: \"\\f100\";\n}\n.fa-angle-double-right:before {\n  content: \"\\f101\";\n}\n.fa-angle-double-up:before {\n  content: \"\\f102\";\n}\n.fa-angle-double-down:before {\n  content: \"\\f103\";\n}\n.fa-angle-left:before {\n  content: \"\\f104\";\n}\n.fa-angle-right:before {\n  content: \"\\f105\";\n}\n.fa-angle-up:before {\n  content: \"\\f106\";\n}\n.fa-angle-down:before {\n  content: \"\\f107\";\n}\n.fa-desktop:before {\n  content: \"\\f108\";\n}\n.fa-laptop:before {\n  content: \"\\f109\";\n}\n.fa-tablet:before {\n  content: \"\\f10a\";\n}\n.fa-mobile-phone:before,\n.fa-mobile:before {\n  content: \"\\f10b\";\n}\n.fa-circle-o:before {\n  content: \"\\f10c\";\n}\n.fa-quote-left:before {\n  content: \"\\f10d\";\n}\n.fa-quote-right:before {\n  content: \"\\f10e\";\n}\n.fa-spinner:before {\n  content: \"\\f110\";\n}\n.fa-circle:before {\n  content: \"\\f111\";\n}\n.fa-mail-reply:before,\n.fa-reply:before {\n  content: \"\\f112\";\n}\n.fa-github-alt:before {\n  content: \"\\f113\";\n}\n.fa-folder-o:before {\n  content: \"\\f114\";\n}\n.fa-folder-open-o:before {\n  content: \"\\f115\";\n}\n.fa-smile-o:before {\n  content: \"\\f118\";\n}\n.fa-frown-o:before {\n  content: \"\\f119\";\n}\n.fa-meh-o:before {\n  content: \"\\f11a\";\n}\n.fa-gamepad:before {\n  content: \"\\f11b\";\n}\n.fa-keyboard-o:before {\n  content: \"\\f11c\";\n}\n.fa-flag-o:before {\n  content: \"\\f11d\";\n}\n.fa-flag-checkered:before {\n  content: \"\\f11e\";\n}\n.fa-terminal:before {\n  content: \"\\f120\";\n}\n.fa-code:before {\n  content: \"\\f121\";\n}\n.fa-mail-reply-all:before,\n.fa-reply-all:before {\n  content: \"\\f122\";\n}\n.fa-star-half-empty:before,\n.fa-star-half-full:before,\n.fa-star-half-o:before {\n  content: \"\\f123\";\n}\n.fa-location-arrow:before {\n  content: \"\\f124\";\n}\n.fa-crop:before {\n  content: \"\\f125\";\n}\n.fa-code-fork:before {\n  content: \"\\f126\";\n}\n.fa-unlink:before,\n.fa-chain-broken:before {\n  content: \"\\f127\";\n}\n.fa-question:before {\n  content: \"\\f128\";\n}\n.fa-info:before {\n  content: \"\\f129\";\n}\n.fa-exclamation:before {\n  content: \"\\f12a\";\n}\n.fa-superscript:before {\n  content: \"\\f12b\";\n}\n.fa-subscript:before {\n  content: \"\\f12c\";\n}\n.fa-eraser:before {\n  content: \"\\f12d\";\n}\n.fa-puzzle-piece:before {\n  content: \"\\f12e\";\n}\n.fa-microphone:before {\n  content: \"\\f130\";\n}\n.fa-microphone-slash:before {\n  content: \"\\f131\";\n}\n.fa-shield:before {\n  content: \"\\f132\";\n}\n.fa-calendar-o:before {\n  content: \"\\f133\";\n}\n.fa-fire-extinguisher:before {\n  content: \"\\f134\";\n}\n.fa-rocket:before {\n  content: \"\\f135\";\n}\n.fa-maxcdn:before {\n  content: \"\\f136\";\n}\n.fa-chevron-circle-left:before {\n  content: \"\\f137\";\n}\n.fa-chevron-circle-right:before {\n  content: \"\\f138\";\n}\n.fa-chevron-circle-up:before {\n  content: \"\\f139\";\n}\n.fa-chevron-circle-down:before {\n  content: \"\\f13a\";\n}\n.fa-html5:before {\n  content: \"\\f13b\";\n}\n.fa-css3:before {\n  content: \"\\f13c\";\n}\n.fa-anchor:before {\n  content: \"\\f13d\";\n}\n.fa-unlock-alt:before {\n  content: \"\\f13e\";\n}\n.fa-bullseye:before {\n  content: \"\\f140\";\n}\n.fa-ellipsis-h:before {\n  content: \"\\f141\";\n}\n.fa-ellipsis-v:before {\n  content: \"\\f142\";\n}\n.fa-rss-square:before {\n  content: \"\\f143\";\n}\n.fa-play-circle:before {\n  content: \"\\f144\";\n}\n.fa-ticket:before {\n  content: \"\\f145\";\n}\n.fa-minus-square:before {\n  content: \"\\f146\";\n}\n.fa-minus-square-o:before {\n  content: \"\\f147\";\n}\n.fa-level-up:before {\n  content: \"\\f148\";\n}\n.fa-level-down:before {\n  content: \"\\f149\";\n}\n.fa-check-square:before {\n  content: \"\\f14a\";\n}\n.fa-pencil-square:before {\n  content: \"\\f14b\";\n}\n.fa-external-link-square:before {\n  content: \"\\f14c\";\n}\n.fa-share-square:before {\n  content: \"\\f14d\";\n}\n.fa-compass:before {\n  content: \"\\f14e\";\n}\n.fa-toggle-down:before,\n.fa-caret-square-o-down:before {\n  content: \"\\f150\";\n}\n.fa-toggle-up:before,\n.fa-caret-square-o-up:before {\n  content: \"\\f151\";\n}\n.fa-toggle-right:before,\n.fa-caret-square-o-right:before {\n  content: \"\\f152\";\n}\n.fa-euro:before,\n.fa-eur:before {\n  content: \"\\f153\";\n}\n.fa-gbp:before {\n  content: \"\\f154\";\n}\n.fa-dollar:before,\n.fa-usd:before {\n  content: \"\\f155\";\n}\n.fa-rupee:before,\n.fa-inr:before {\n  content: \"\\f156\";\n}\n.fa-cny:before,\n.fa-rmb:before,\n.fa-yen:before,\n.fa-jpy:before {\n  content: \"\\f157\";\n}\n.fa-ruble:before,\n.fa-rouble:before,\n.fa-rub:before {\n  content: \"\\f158\";\n}\n.fa-won:before,\n.fa-krw:before {\n  content: \"\\f159\";\n}\n.fa-bitcoin:before,\n.fa-btc:before {\n  content: \"\\f15a\";\n}\n.fa-file:before {\n  content: \"\\f15b\";\n}\n.fa-file-text:before {\n  content: \"\\f15c\";\n}\n.fa-sort-alpha-asc:before {\n  content: \"\\f15d\";\n}\n.fa-sort-alpha-desc:before {\n  content: \"\\f15e\";\n}\n.fa-sort-amount-asc:before {\n  content: \"\\f160\";\n}\n.fa-sort-amount-desc:before {\n  content: \"\\f161\";\n}\n.fa-sort-numeric-asc:before {\n  content: \"\\f162\";\n}\n.fa-sort-numeric-desc:before {\n  content: \"\\f163\";\n}\n.fa-thumbs-up:before {\n  content: \"\\f164\";\n}\n.fa-thumbs-down:before {\n  content: \"\\f165\";\n}\n.fa-youtube-square:before {\n  content: \"\\f166\";\n}\n.fa-youtube:before {\n  content: \"\\f167\";\n}\n.fa-xing:before {\n  content: \"\\f168\";\n}\n.fa-xing-square:before {\n  content: \"\\f169\";\n}\n.fa-youtube-play:before {\n  content: \"\\f16a\";\n}\n.fa-dropbox:before {\n  content: \"\\f16b\";\n}\n.fa-stack-overflow:before {\n  content: \"\\f16c\";\n}\n.fa-instagram:before {\n  content: \"\\f16d\";\n}\n.fa-flickr:before {\n  content: \"\\f16e\";\n}\n.fa-adn:before {\n  content: \"\\f170\";\n}\n.fa-bitbucket:before {\n  content: \"\\f171\";\n}\n.fa-bitbucket-square:before {\n  content: \"\\f172\";\n}\n.fa-tumblr:before {\n  content: \"\\f173\";\n}\n.fa-tumblr-square:before {\n  content: \"\\f174\";\n}\n.fa-long-arrow-down:before {\n  content: \"\\f175\";\n}\n.fa-long-arrow-up:before {\n  content: \"\\f176\";\n}\n.fa-long-arrow-left:before {\n  content: \"\\f177\";\n}\n.fa-long-arrow-right:before {\n  content: \"\\f178\";\n}\n.fa-apple:before {\n  content: \"\\f179\";\n}\n.fa-windows:before {\n  content: \"\\f17a\";\n}\n.fa-android:before {\n  content: \"\\f17b\";\n}\n.fa-linux:before {\n  content: \"\\f17c\";\n}\n.fa-dribbble:before {\n  content: \"\\f17d\";\n}\n.fa-skype:before {\n  content: \"\\f17e\";\n}\n.fa-foursquare:before {\n  content: \"\\f180\";\n}\n.fa-trello:before {\n  content: \"\\f181\";\n}\n.fa-female:before {\n  content: \"\\f182\";\n}\n.fa-male:before {\n  content: \"\\f183\";\n}\n.fa-gittip:before,\n.fa-gratipay:before {\n  content: \"\\f184\";\n}\n.fa-sun-o:before {\n  content: \"\\f185\";\n}\n.fa-moon-o:before {\n  content: \"\\f186\";\n}\n.fa-archive:before {\n  content: \"\\f187\";\n}\n.fa-bug:before {\n  content: \"\\f188\";\n}\n.fa-vk:before {\n  content: \"\\f189\";\n}\n.fa-weibo:before {\n  content: \"\\f18a\";\n}\n.fa-renren:before {\n  content: \"\\f18b\";\n}\n.fa-pagelines:before {\n  content: \"\\f18c\";\n}\n.fa-stack-exchange:before {\n  content: \"\\f18d\";\n}\n.fa-arrow-circle-o-right:before {\n  content: \"\\f18e\";\n}\n.fa-arrow-circle-o-left:before {\n  content: \"\\f190\";\n}\n.fa-toggle-left:before,\n.fa-caret-square-o-left:before {\n  content: \"\\f191\";\n}\n.fa-dot-circle-o:before {\n  content: \"\\f192\";\n}\n.fa-wheelchair:before {\n  content: \"\\f193\";\n}\n.fa-vimeo-square:before {\n  content: \"\\f194\";\n}\n.fa-turkish-lira:before,\n.fa-try:before {\n  content: \"\\f195\";\n}\n.fa-plus-square-o:before {\n  content: \"\\f196\";\n}\n.fa-space-shuttle:before {\n  content: \"\\f197\";\n}\n.fa-slack:before {\n  content: \"\\f198\";\n}\n.fa-envelope-square:before {\n  content: \"\\f199\";\n}\n.fa-wordpress:before {\n  content: \"\\f19a\";\n}\n.fa-openid:before {\n  content: \"\\f19b\";\n}\n.fa-institution:before,\n.fa-bank:before,\n.fa-university:before {\n  content: \"\\f19c\";\n}\n.fa-mortar-board:before,\n.fa-graduation-cap:before {\n  content: \"\\f19d\";\n}\n.fa-yahoo:before {\n  content: \"\\f19e\";\n}\n.fa-google:before {\n  content: \"\\f1a0\";\n}\n.fa-reddit:before {\n  content: \"\\f1a1\";\n}\n.fa-reddit-square:before {\n  content: \"\\f1a2\";\n}\n.fa-stumbleupon-circle:before {\n  content: \"\\f1a3\";\n}\n.fa-stumbleupon:before {\n  content: \"\\f1a4\";\n}\n.fa-delicious:before {\n  content: \"\\f1a5\";\n}\n.fa-digg:before {\n  content: \"\\f1a6\";\n}\n.fa-pied-piper-pp:before {\n  content: \"\\f1a7\";\n}\n.fa-pied-piper-alt:before {\n  content: \"\\f1a8\";\n}\n.fa-drupal:before {\n  content: \"\\f1a9\";\n}\n.fa-joomla:before {\n  content: \"\\f1aa\";\n}\n.fa-language:before {\n  content: \"\\f1ab\";\n}\n.fa-fax:before {\n  content: \"\\f1ac\";\n}\n.fa-building:before {\n  content: \"\\f1ad\";\n}\n.fa-child:before {\n  content: \"\\f1ae\";\n}\n.fa-paw:before {\n  content: \"\\f1b0\";\n}\n.fa-spoon:before {\n  content: \"\\f1b1\";\n}\n.fa-cube:before {\n  content: \"\\f1b2\";\n}\n.fa-cubes:before {\n  content: \"\\f1b3\";\n}\n.fa-behance:before {\n  content: \"\\f1b4\";\n}\n.fa-behance-square:before {\n  content: \"\\f1b5\";\n}\n.fa-steam:before {\n  content: \"\\f1b6\";\n}\n.fa-steam-square:before {\n  content: \"\\f1b7\";\n}\n.fa-recycle:before {\n  content: \"\\f1b8\";\n}\n.fa-automobile:before,\n.fa-car:before {\n  content: \"\\f1b9\";\n}\n.fa-cab:before,\n.fa-taxi:before {\n  content: \"\\f1ba\";\n}\n.fa-tree:before {\n  content: \"\\f1bb\";\n}\n.fa-spotify:before {\n  content: \"\\f1bc\";\n}\n.fa-deviantart:before {\n  content: \"\\f1bd\";\n}\n.fa-soundcloud:before {\n  content: \"\\f1be\";\n}\n.fa-database:before {\n  content: \"\\f1c0\";\n}\n.fa-file-pdf-o:before {\n  content: \"\\f1c1\";\n}\n.fa-file-word-o:before {\n  content: \"\\f1c2\";\n}\n.fa-file-excel-o:before {\n  content: \"\\f1c3\";\n}\n.fa-file-powerpoint-o:before {\n  content: \"\\f1c4\";\n}\n.fa-file-photo-o:before,\n.fa-file-picture-o:before,\n.fa-file-image-o:before {\n  content: \"\\f1c5\";\n}\n.fa-file-zip-o:before,\n.fa-file-archive-o:before {\n  content: \"\\f1c6\";\n}\n.fa-file-sound-o:before,\n.fa-file-audio-o:before {\n  content: \"\\f1c7\";\n}\n.fa-file-movie-o:before,\n.fa-file-video-o:before {\n  content: \"\\f1c8\";\n}\n.fa-file-code-o:before {\n  content: \"\\f1c9\";\n}\n.fa-vine:before {\n  content: \"\\f1ca\";\n}\n.fa-codepen:before {\n  content: \"\\f1cb\";\n}\n.fa-jsfiddle:before {\n  content: \"\\f1cc\";\n}\n.fa-life-bouy:before,\n.fa-life-buoy:before,\n.fa-life-saver:before,\n.fa-support:before,\n.fa-life-ring:before {\n  content: \"\\f1cd\";\n}\n.fa-circle-o-notch:before {\n  content: \"\\f1ce\";\n}\n.fa-ra:before,\n.fa-resistance:before,\n.fa-rebel:before {\n  content: \"\\f1d0\";\n}\n.fa-ge:before,\n.fa-empire:before {\n  content: \"\\f1d1\";\n}\n.fa-git-square:before {\n  content: \"\\f1d2\";\n}\n.fa-git:before {\n  content: \"\\f1d3\";\n}\n.fa-y-combinator-square:before,\n.fa-yc-square:before,\n.fa-hacker-news:before {\n  content: \"\\f1d4\";\n}\n.fa-tencent-weibo:before {\n  content: \"\\f1d5\";\n}\n.fa-qq:before {\n  content: \"\\f1d6\";\n}\n.fa-wechat:before,\n.fa-weixin:before {\n  content: \"\\f1d7\";\n}\n.fa-send:before,\n.fa-paper-plane:before {\n  content: \"\\f1d8\";\n}\n.fa-send-o:before,\n.fa-paper-plane-o:before {\n  content: \"\\f1d9\";\n}\n.fa-history:before {\n  content: \"\\f1da\";\n}\n.fa-circle-thin:before {\n  content: \"\\f1db\";\n}\n.fa-header:before {\n  content: \"\\f1dc\";\n}\n.fa-paragraph:before {\n  content: \"\\f1dd\";\n}\n.fa-sliders:before {\n  content: \"\\f1de\";\n}\n.fa-share-alt:before {\n  content: \"\\f1e0\";\n}\n.fa-share-alt-square:before {\n  content: \"\\f1e1\";\n}\n.fa-bomb:before {\n  content: \"\\f1e2\";\n}\n.fa-soccer-ball-o:before,\n.fa-futbol-o:before {\n  content: \"\\f1e3\";\n}\n.fa-tty:before {\n  content: \"\\f1e4\";\n}\n.fa-binoculars:before {\n  content: \"\\f1e5\";\n}\n.fa-plug:before {\n  content: \"\\f1e6\";\n}\n.fa-slideshare:before {\n  content: \"\\f1e7\";\n}\n.fa-twitch:before {\n  content: \"\\f1e8\";\n}\n.fa-yelp:before {\n  content: \"\\f1e9\";\n}\n.fa-newspaper-o:before {\n  content: \"\\f1ea\";\n}\n.fa-wifi:before {\n  content: \"\\f1eb\";\n}\n.fa-calculator:before {\n  content: \"\\f1ec\";\n}\n.fa-paypal:before {\n  content: \"\\f1ed\";\n}\n.fa-google-wallet:before {\n  content: \"\\f1ee\";\n}\n.fa-cc-visa:before {\n  content: \"\\f1f0\";\n}\n.fa-cc-mastercard:before {\n  content: \"\\f1f1\";\n}\n.fa-cc-discover:before {\n  content: \"\\f1f2\";\n}\n.fa-cc-amex:before {\n  content: \"\\f1f3\";\n}\n.fa-cc-paypal:before {\n  content: \"\\f1f4\";\n}\n.fa-cc-stripe:before {\n  content: \"\\f1f5\";\n}\n.fa-bell-slash:before {\n  content: \"\\f1f6\";\n}\n.fa-bell-slash-o:before {\n  content: \"\\f1f7\";\n}\n.fa-trash:before {\n  content: \"\\f1f8\";\n}\n.fa-copyright:before {\n  content: \"\\f1f9\";\n}\n.fa-at:before {\n  content: \"\\f1fa\";\n}\n.fa-eyedropper:before {\n  content: \"\\f1fb\";\n}\n.fa-paint-brush:before {\n  content: \"\\f1fc\";\n}\n.fa-birthday-cake:before {\n  content: \"\\f1fd\";\n}\n.fa-area-chart:before {\n  content: \"\\f1fe\";\n}\n.fa-pie-chart:before {\n  content: \"\\f200\";\n}\n.fa-line-chart:before {\n  content: \"\\f201\";\n}\n.fa-lastfm:before {\n  content: \"\\f202\";\n}\n.fa-lastfm-square:before {\n  content: \"\\f203\";\n}\n.fa-toggle-off:before {\n  content: \"\\f204\";\n}\n.fa-toggle-on:before {\n  content: \"\\f205\";\n}\n.fa-bicycle:before {\n  content: \"\\f206\";\n}\n.fa-bus:before {\n  content: \"\\f207\";\n}\n.fa-ioxhost:before {\n  content: \"\\f208\";\n}\n.fa-angellist:before {\n  content: \"\\f209\";\n}\n.fa-cc:before {\n  content: \"\\f20a\";\n}\n.fa-shekel:before,\n.fa-sheqel:before,\n.fa-ils:before {\n  content: \"\\f20b\";\n}\n.fa-meanpath:before {\n  content: \"\\f20c\";\n}\n.fa-buysellads:before {\n  content: \"\\f20d\";\n}\n.fa-connectdevelop:before {\n  content: \"\\f20e\";\n}\n.fa-dashcube:before {\n  content: \"\\f210\";\n}\n.fa-forumbee:before {\n  content: \"\\f211\";\n}\n.fa-leanpub:before {\n  content: \"\\f212\";\n}\n.fa-sellsy:before {\n  content: \"\\f213\";\n}\n.fa-shirtsinbulk:before {\n  content: \"\\f214\";\n}\n.fa-simplybuilt:before {\n  content: \"\\f215\";\n}\n.fa-skyatlas:before {\n  content: \"\\f216\";\n}\n.fa-cart-plus:before {\n  content: \"\\f217\";\n}\n.fa-cart-arrow-down:before {\n  content: \"\\f218\";\n}\n.fa-diamond:before {\n  content: \"\\f219\";\n}\n.fa-ship:before {\n  content: \"\\f21a\";\n}\n.fa-user-secret:before {\n  content: \"\\f21b\";\n}\n.fa-motorcycle:before {\n  content: \"\\f21c\";\n}\n.fa-street-view:before {\n  content: \"\\f21d\";\n}\n.fa-heartbeat:before {\n  content: \"\\f21e\";\n}\n.fa-venus:before {\n  content: \"\\f221\";\n}\n.fa-mars:before {\n  content: \"\\f222\";\n}\n.fa-mercury:before {\n  content: \"\\f223\";\n}\n.fa-intersex:before,\n.fa-transgender:before {\n  content: \"\\f224\";\n}\n.fa-transgender-alt:before {\n  content: \"\\f225\";\n}\n.fa-venus-double:before {\n  content: \"\\f226\";\n}\n.fa-mars-double:before {\n  content: \"\\f227\";\n}\n.fa-venus-mars:before {\n  content: \"\\f228\";\n}\n.fa-mars-stroke:before {\n  content: \"\\f229\";\n}\n.fa-mars-stroke-v:before {\n  content: \"\\f22a\";\n}\n.fa-mars-stroke-h:before {\n  content: \"\\f22b\";\n}\n.fa-neuter:before {\n  content: \"\\f22c\";\n}\n.fa-genderless:before {\n  content: \"\\f22d\";\n}\n.fa-facebook-official:before {\n  content: \"\\f230\";\n}\n.fa-pinterest-p:before {\n  content: \"\\f231\";\n}\n.fa-whatsapp:before {\n  content: \"\\f232\";\n}\n.fa-server:before {\n  content: \"\\f233\";\n}\n.fa-user-plus:before {\n  content: \"\\f234\";\n}\n.fa-user-times:before {\n  content: \"\\f235\";\n}\n.fa-hotel:before,\n.fa-bed:before {\n  content: \"\\f236\";\n}\n.fa-viacoin:before {\n  content: \"\\f237\";\n}\n.fa-train:before {\n  content: \"\\f238\";\n}\n.fa-subway:before {\n  content: \"\\f239\";\n}\n.fa-medium:before {\n  content: \"\\f23a\";\n}\n.fa-yc:before,\n.fa-y-combinator:before {\n  content: \"\\f23b\";\n}\n.fa-optin-monster:before {\n  content: \"\\f23c\";\n}\n.fa-opencart:before {\n  content: \"\\f23d\";\n}\n.fa-expeditedssl:before {\n  content: \"\\f23e\";\n}\n.fa-battery-4:before,\n.fa-battery-full:before {\n  content: \"\\f240\";\n}\n.fa-battery-3:before,\n.fa-battery-three-quarters:before {\n  content: \"\\f241\";\n}\n.fa-battery-2:before,\n.fa-battery-half:before {\n  content: \"\\f242\";\n}\n.fa-battery-1:before,\n.fa-battery-quarter:before {\n  content: \"\\f243\";\n}\n.fa-battery-0:before,\n.fa-battery-empty:before {\n  content: \"\\f244\";\n}\n.fa-mouse-pointer:before {\n  content: \"\\f245\";\n}\n.fa-i-cursor:before {\n  content: \"\\f246\";\n}\n.fa-object-group:before {\n  content: \"\\f247\";\n}\n.fa-object-ungroup:before {\n  content: \"\\f248\";\n}\n.fa-sticky-note:before {\n  content: \"\\f249\";\n}\n.fa-sticky-note-o:before {\n  content: \"\\f24a\";\n}\n.fa-cc-jcb:before {\n  content: \"\\f24b\";\n}\n.fa-cc-diners-club:before {\n  content: \"\\f24c\";\n}\n.fa-clone:before {\n  content: \"\\f24d\";\n}\n.fa-balance-scale:before {\n  content: \"\\f24e\";\n}\n.fa-hourglass-o:before {\n  content: \"\\f250\";\n}\n.fa-hourglass-1:before,\n.fa-hourglass-start:before {\n  content: \"\\f251\";\n}\n.fa-hourglass-2:before,\n.fa-hourglass-half:before {\n  content: \"\\f252\";\n}\n.fa-hourglass-3:before,\n.fa-hourglass-end:before {\n  content: \"\\f253\";\n}\n.fa-hourglass:before {\n  content: \"\\f254\";\n}\n.fa-hand-grab-o:before,\n.fa-hand-rock-o:before {\n  content: \"\\f255\";\n}\n.fa-hand-stop-o:before,\n.fa-hand-paper-o:before {\n  content: \"\\f256\";\n}\n.fa-hand-scissors-o:before {\n  content: \"\\f257\";\n}\n.fa-hand-lizard-o:before {\n  content: \"\\f258\";\n}\n.fa-hand-spock-o:before {\n  content: \"\\f259\";\n}\n.fa-hand-pointer-o:before {\n  content: \"\\f25a\";\n}\n.fa-hand-peace-o:before {\n  content: \"\\f25b\";\n}\n.fa-trademark:before {\n  content: \"\\f25c\";\n}\n.fa-registered:before {\n  content: \"\\f25d\";\n}\n.fa-creative-commons:before {\n  content: \"\\f25e\";\n}\n.fa-gg:before {\n  content: \"\\f260\";\n}\n.fa-gg-circle:before {\n  content: \"\\f261\";\n}\n.fa-tripadvisor:before {\n  content: \"\\f262\";\n}\n.fa-odnoklassniki:before {\n  content: \"\\f263\";\n}\n.fa-odnoklassniki-square:before {\n  content: \"\\f264\";\n}\n.fa-get-pocket:before {\n  content: \"\\f265\";\n}\n.fa-wikipedia-w:before {\n  content: \"\\f266\";\n}\n.fa-safari:before {\n  content: \"\\f267\";\n}\n.fa-chrome:before {\n  content: \"\\f268\";\n}\n.fa-firefox:before {\n  content: \"\\f269\";\n}\n.fa-opera:before {\n  content: \"\\f26a\";\n}\n.fa-internet-explorer:before {\n  content: \"\\f26b\";\n}\n.fa-tv:before,\n.fa-television:before {\n  content: \"\\f26c\";\n}\n.fa-contao:before {\n  content: \"\\f26d\";\n}\n.fa-500px:before {\n  content: \"\\f26e\";\n}\n.fa-amazon:before {\n  content: \"\\f270\";\n}\n.fa-calendar-plus-o:before {\n  content: \"\\f271\";\n}\n.fa-calendar-minus-o:before {\n  content: \"\\f272\";\n}\n.fa-calendar-times-o:before {\n  content: \"\\f273\";\n}\n.fa-calendar-check-o:before {\n  content: \"\\f274\";\n}\n.fa-industry:before {\n  content: \"\\f275\";\n}\n.fa-map-pin:before {\n  content: \"\\f276\";\n}\n.fa-map-signs:before {\n  content: \"\\f277\";\n}\n.fa-map-o:before {\n  content: \"\\f278\";\n}\n.fa-map:before {\n  content: \"\\f279\";\n}\n.fa-commenting:before {\n  content: \"\\f27a\";\n}\n.fa-commenting-o:before {\n  content: \"\\f27b\";\n}\n.fa-houzz:before {\n  content: \"\\f27c\";\n}\n.fa-vimeo:before {\n  content: \"\\f27d\";\n}\n.fa-black-tie:before {\n  content: \"\\f27e\";\n}\n.fa-fonticons:before {\n  content: \"\\f280\";\n}\n.fa-reddit-alien:before {\n  content: \"\\f281\";\n}\n.fa-edge:before {\n  content: \"\\f282\";\n}\n.fa-credit-card-alt:before {\n  content: \"\\f283\";\n}\n.fa-codiepie:before {\n  content: \"\\f284\";\n}\n.fa-modx:before {\n  content: \"\\f285\";\n}\n.fa-fort-awesome:before {\n  content: \"\\f286\";\n}\n.fa-usb:before {\n  content: \"\\f287\";\n}\n.fa-product-hunt:before {\n  content: \"\\f288\";\n}\n.fa-mixcloud:before {\n  content: \"\\f289\";\n}\n.fa-scribd:before {\n  content: \"\\f28a\";\n}\n.fa-pause-circle:before {\n  content: \"\\f28b\";\n}\n.fa-pause-circle-o:before {\n  content: \"\\f28c\";\n}\n.fa-stop-circle:before {\n  content: \"\\f28d\";\n}\n.fa-stop-circle-o:before {\n  content: \"\\f28e\";\n}\n.fa-shopping-bag:before {\n  content: \"\\f290\";\n}\n.fa-shopping-basket:before {\n  content: \"\\f291\";\n}\n.fa-hashtag:before {\n  content: \"\\f292\";\n}\n.fa-bluetooth:before {\n  content: \"\\f293\";\n}\n.fa-bluetooth-b:before {\n  content: \"\\f294\";\n}\n.fa-percent:before {\n  content: \"\\f295\";\n}\n.fa-gitlab:before {\n  content: \"\\f296\";\n}\n.fa-wpbeginner:before {\n  content: \"\\f297\";\n}\n.fa-wpforms:before {\n  content: \"\\f298\";\n}\n.fa-envira:before {\n  content: \"\\f299\";\n}\n.fa-universal-access:before {\n  content: \"\\f29a\";\n}\n.fa-wheelchair-alt:before {\n  content: \"\\f29b\";\n}\n.fa-question-circle-o:before {\n  content: \"\\f29c\";\n}\n.fa-blind:before {\n  content: \"\\f29d\";\n}\n.fa-audio-description:before {\n  content: \"\\f29e\";\n}\n.fa-volume-control-phone:before {\n  content: \"\\f2a0\";\n}\n.fa-braille:before {\n  content: \"\\f2a1\";\n}\n.fa-assistive-listening-systems:before {\n  content: \"\\f2a2\";\n}\n.fa-asl-interpreting:before,\n.fa-american-sign-language-interpreting:before {\n  content: \"\\f2a3\";\n}\n.fa-deafness:before,\n.fa-hard-of-hearing:before,\n.fa-deaf:before {\n  content: \"\\f2a4\";\n}\n.fa-glide:before {\n  content: \"\\f2a5\";\n}\n.fa-glide-g:before {\n  content: \"\\f2a6\";\n}\n.fa-signing:before,\n.fa-sign-language:before {\n  content: \"\\f2a7\";\n}\n.fa-low-vision:before {\n  content: \"\\f2a8\";\n}\n.fa-viadeo:before {\n  content: \"\\f2a9\";\n}\n.fa-viadeo-square:before {\n  content: \"\\f2aa\";\n}\n.fa-snapchat:before {\n  content: \"\\f2ab\";\n}\n.fa-snapchat-ghost:before {\n  content: \"\\f2ac\";\n}\n.fa-snapchat-square:before {\n  content: \"\\f2ad\";\n}\n.fa-pied-piper:before {\n  content: \"\\f2ae\";\n}\n.fa-first-order:before {\n  content: \"\\f2b0\";\n}\n.fa-yoast:before {\n  content: \"\\f2b1\";\n}\n.fa-themeisle:before {\n  content: \"\\f2b2\";\n}\n.fa-google-plus-circle:before,\n.fa-google-plus-official:before {\n  content: \"\\f2b3\";\n}\n.fa-fa:before,\n.fa-font-awesome:before {\n  content: \"\\f2b4\";\n}\n.sr-only {\n  position: absolute;\n  width: 1px;\n  height: 1px;\n  padding: 0;\n  margin: -1px;\n  overflow: hidden;\n  clip: rect(0, 0, 0, 0);\n  border: 0;\n}\n.sr-only-focusable:active,\n.sr-only-focusable:focus {\n  position: static;\n  width: auto;\n  height: auto;\n  margin: 0;\n  overflow: visible;\n  clip: auto;\n}\n"
  },
  {
    "path": "app_backend/vendor/font-awesome/less/animated.less",
    "content": "// Animated Icons\n// --------------------------\n\n.@{fa-css-prefix}-spin {\n  -webkit-animation: fa-spin 2s infinite linear;\n          animation: fa-spin 2s infinite linear;\n}\n\n.@{fa-css-prefix}-pulse {\n  -webkit-animation: fa-spin 1s infinite steps(8);\n          animation: fa-spin 1s infinite steps(8);\n}\n\n@-webkit-keyframes fa-spin {\n  0% {\n    -webkit-transform: rotate(0deg);\n            transform: rotate(0deg);\n  }\n  100% {\n    -webkit-transform: rotate(359deg);\n            transform: rotate(359deg);\n  }\n}\n\n@keyframes fa-spin {\n  0% {\n    -webkit-transform: rotate(0deg);\n            transform: rotate(0deg);\n  }\n  100% {\n    -webkit-transform: rotate(359deg);\n            transform: rotate(359deg);\n  }\n}\n"
  },
  {
    "path": "app_backend/vendor/font-awesome/less/bordered-pulled.less",
    "content": "// Bordered & Pulled\n// -------------------------\n\n.@{fa-css-prefix}-border {\n  padding: .2em .25em .15em;\n  border: solid .08em @fa-border-color;\n  border-radius: .1em;\n}\n\n.@{fa-css-prefix}-pull-left { float: left; }\n.@{fa-css-prefix}-pull-right { float: right; }\n\n.@{fa-css-prefix} {\n  &.@{fa-css-prefix}-pull-left { margin-right: .3em; }\n  &.@{fa-css-prefix}-pull-right { margin-left: .3em; }\n}\n\n/* Deprecated as of 4.4.0 */\n.pull-right { float: right; }\n.pull-left { float: left; }\n\n.@{fa-css-prefix} {\n  &.pull-left { margin-right: .3em; }\n  &.pull-right { margin-left: .3em; }\n}\n"
  },
  {
    "path": "app_backend/vendor/font-awesome/less/core.less",
    "content": "// Base Class Definition\n// -------------------------\n\n.@{fa-css-prefix} {\n  display: inline-block;\n  font: normal normal normal @fa-font-size-base/@fa-line-height-base FontAwesome; // shortening font declaration\n  font-size: inherit; // can't have font-size inherit on line above, so need to override\n  text-rendering: auto; // optimizelegibility throws things off #1094\n  -webkit-font-smoothing: antialiased;\n  -moz-osx-font-smoothing: grayscale;\n\n}\n"
  },
  {
    "path": "app_backend/vendor/font-awesome/less/extras.less",
    "content": "// Extras\n// --------------------------\n"
  },
  {
    "path": "app_backend/vendor/font-awesome/less/fixed-width.less",
    "content": "// Fixed Width Icons\n// -------------------------\n.@{fa-css-prefix}-fw {\n  width: (18em / 14);\n  text-align: center;\n}\n"
  },
  {
    "path": "app_backend/vendor/font-awesome/less/font-awesome.less",
    "content": "/*!\n *  Font Awesome 4.6.3 by @davegandy - http://fontawesome.io - @fontawesome\n *  License - http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License)\n */\n\n@import \"variables.less\";\n@import \"mixins.less\";\n@import \"path.less\";\n@import \"core.less\";\n@import \"larger.less\";\n@import \"fixed-width.less\";\n@import \"list.less\";\n@import \"bordered-pulled.less\";\n@import \"animated.less\";\n@import \"rotated-flipped.less\";\n@import \"stacked.less\";\n@import \"icons.less\";\n@import \"screen-reader.less\";\n"
  },
  {
    "path": "app_backend/vendor/font-awesome/less/icons.less",
    "content": "/* Font Awesome uses the Unicode Private Use Area (PUA) to ensure screen\n   readers do not read off random characters that represent icons */\n\n.@{fa-css-prefix}-glass:before { content: @fa-var-glass; }\n.@{fa-css-prefix}-music:before { content: @fa-var-music; }\n.@{fa-css-prefix}-search:before { content: @fa-var-search; }\n.@{fa-css-prefix}-envelope-o:before { content: @fa-var-envelope-o; }\n.@{fa-css-prefix}-heart:before { content: @fa-var-heart; }\n.@{fa-css-prefix}-star:before { content: @fa-var-star; }\n.@{fa-css-prefix}-star-o:before { content: @fa-var-star-o; }\n.@{fa-css-prefix}-user:before { content: @fa-var-user; }\n.@{fa-css-prefix}-film:before { content: @fa-var-film; }\n.@{fa-css-prefix}-th-large:before { content: @fa-var-th-large; }\n.@{fa-css-prefix}-th:before { content: @fa-var-th; }\n.@{fa-css-prefix}-th-list:before { content: @fa-var-th-list; }\n.@{fa-css-prefix}-check:before { content: @fa-var-check; }\n.@{fa-css-prefix}-remove:before,\n.@{fa-css-prefix}-close:before,\n.@{fa-css-prefix}-times:before { content: @fa-var-times; }\n.@{fa-css-prefix}-search-plus:before { content: @fa-var-search-plus; }\n.@{fa-css-prefix}-search-minus:before { content: @fa-var-search-minus; }\n.@{fa-css-prefix}-power-off:before { content: @fa-var-power-off; }\n.@{fa-css-prefix}-signal:before { content: @fa-var-signal; }\n.@{fa-css-prefix}-gear:before,\n.@{fa-css-prefix}-cog:before { content: @fa-var-cog; }\n.@{fa-css-prefix}-trash-o:before { content: @fa-var-trash-o; }\n.@{fa-css-prefix}-home:before { content: @fa-var-home; }\n.@{fa-css-prefix}-file-o:before { content: @fa-var-file-o; }\n.@{fa-css-prefix}-clock-o:before { content: @fa-var-clock-o; }\n.@{fa-css-prefix}-road:before { content: @fa-var-road; }\n.@{fa-css-prefix}-download:before { content: @fa-var-download; }\n.@{fa-css-prefix}-arrow-circle-o-down:before { content: @fa-var-arrow-circle-o-down; }\n.@{fa-css-prefix}-arrow-circle-o-up:before { content: @fa-var-arrow-circle-o-up; }\n.@{fa-css-prefix}-inbox:before { content: @fa-var-inbox; }\n.@{fa-css-prefix}-play-circle-o:before { content: @fa-var-play-circle-o; }\n.@{fa-css-prefix}-rotate-right:before,\n.@{fa-css-prefix}-repeat:before { content: @fa-var-repeat; }\n.@{fa-css-prefix}-refresh:before { content: @fa-var-refresh; }\n.@{fa-css-prefix}-list-alt:before { content: @fa-var-list-alt; }\n.@{fa-css-prefix}-lock:before { content: @fa-var-lock; }\n.@{fa-css-prefix}-flag:before { content: @fa-var-flag; }\n.@{fa-css-prefix}-headphones:before { content: @fa-var-headphones; }\n.@{fa-css-prefix}-volume-off:before { content: @fa-var-volume-off; }\n.@{fa-css-prefix}-volume-down:before { content: @fa-var-volume-down; }\n.@{fa-css-prefix}-volume-up:before { content: @fa-var-volume-up; }\n.@{fa-css-prefix}-qrcode:before { content: @fa-var-qrcode; }\n.@{fa-css-prefix}-barcode:before { content: @fa-var-barcode; }\n.@{fa-css-prefix}-tag:before { content: @fa-var-tag; }\n.@{fa-css-prefix}-tags:before { content: @fa-var-tags; }\n.@{fa-css-prefix}-book:before { content: @fa-var-book; }\n.@{fa-css-prefix}-bookmark:before { content: @fa-var-bookmark; }\n.@{fa-css-prefix}-print:before { content: @fa-var-print; }\n.@{fa-css-prefix}-camera:before { content: @fa-var-camera; }\n.@{fa-css-prefix}-font:before { content: @fa-var-font; }\n.@{fa-css-prefix}-bold:before { content: @fa-var-bold; }\n.@{fa-css-prefix}-italic:before { content: @fa-var-italic; }\n.@{fa-css-prefix}-text-height:before { content: @fa-var-text-height; }\n.@{fa-css-prefix}-text-width:before { content: @fa-var-text-width; }\n.@{fa-css-prefix}-align-left:before { content: @fa-var-align-left; }\n.@{fa-css-prefix}-align-center:before { content: @fa-var-align-center; }\n.@{fa-css-prefix}-align-right:before { content: @fa-var-align-right; }\n.@{fa-css-prefix}-align-justify:before { content: @fa-var-align-justify; }\n.@{fa-css-prefix}-list:before { content: @fa-var-list; }\n.@{fa-css-prefix}-dedent:before,\n.@{fa-css-prefix}-outdent:before { content: @fa-var-outdent; }\n.@{fa-css-prefix}-indent:before { content: @fa-var-indent; }\n.@{fa-css-prefix}-video-camera:before { content: @fa-var-video-camera; }\n.@{fa-css-prefix}-photo:before,\n.@{fa-css-prefix}-image:before,\n.@{fa-css-prefix}-picture-o:before { content: @fa-var-picture-o; }\n.@{fa-css-prefix}-pencil:before { content: @fa-var-pencil; }\n.@{fa-css-prefix}-map-marker:before { content: @fa-var-map-marker; }\n.@{fa-css-prefix}-adjust:before { content: @fa-var-adjust; }\n.@{fa-css-prefix}-tint:before { content: @fa-var-tint; }\n.@{fa-css-prefix}-edit:before,\n.@{fa-css-prefix}-pencil-square-o:before { content: @fa-var-pencil-square-o; }\n.@{fa-css-prefix}-share-square-o:before { content: @fa-var-share-square-o; }\n.@{fa-css-prefix}-check-square-o:before { content: @fa-var-check-square-o; }\n.@{fa-css-prefix}-arrows:before { content: @fa-var-arrows; }\n.@{fa-css-prefix}-step-backward:before { content: @fa-var-step-backward; }\n.@{fa-css-prefix}-fast-backward:before { content: @fa-var-fast-backward; }\n.@{fa-css-prefix}-backward:before { content: @fa-var-backward; }\n.@{fa-css-prefix}-play:before { content: @fa-var-play; }\n.@{fa-css-prefix}-pause:before { content: @fa-var-pause; }\n.@{fa-css-prefix}-stop:before { content: @fa-var-stop; }\n.@{fa-css-prefix}-forward:before { content: @fa-var-forward; }\n.@{fa-css-prefix}-fast-forward:before { content: @fa-var-fast-forward; }\n.@{fa-css-prefix}-step-forward:before { content: @fa-var-step-forward; }\n.@{fa-css-prefix}-eject:before { content: @fa-var-eject; }\n.@{fa-css-prefix}-chevron-left:before { content: @fa-var-chevron-left; }\n.@{fa-css-prefix}-chevron-right:before { content: @fa-var-chevron-right; }\n.@{fa-css-prefix}-plus-circle:before { content: @fa-var-plus-circle; }\n.@{fa-css-prefix}-minus-circle:before { content: @fa-var-minus-circle; }\n.@{fa-css-prefix}-times-circle:before { content: @fa-var-times-circle; }\n.@{fa-css-prefix}-check-circle:before { content: @fa-var-check-circle; }\n.@{fa-css-prefix}-question-circle:before { content: @fa-var-question-circle; }\n.@{fa-css-prefix}-info-circle:before { content: @fa-var-info-circle; }\n.@{fa-css-prefix}-crosshairs:before { content: @fa-var-crosshairs; }\n.@{fa-css-prefix}-times-circle-o:before { content: @fa-var-times-circle-o; }\n.@{fa-css-prefix}-check-circle-o:before { content: @fa-var-check-circle-o; }\n.@{fa-css-prefix}-ban:before { content: @fa-var-ban; }\n.@{fa-css-prefix}-arrow-left:before { content: @fa-var-arrow-left; }\n.@{fa-css-prefix}-arrow-right:before { content: @fa-var-arrow-right; }\n.@{fa-css-prefix}-arrow-up:before { content: @fa-var-arrow-up; }\n.@{fa-css-prefix}-arrow-down:before { content: @fa-var-arrow-down; }\n.@{fa-css-prefix}-mail-forward:before,\n.@{fa-css-prefix}-share:before { content: @fa-var-share; }\n.@{fa-css-prefix}-expand:before { content: @fa-var-expand; }\n.@{fa-css-prefix}-compress:before { content: @fa-var-compress; }\n.@{fa-css-prefix}-plus:before { content: @fa-var-plus; }\n.@{fa-css-prefix}-minus:before { content: @fa-var-minus; }\n.@{fa-css-prefix}-asterisk:before { content: @fa-var-asterisk; }\n.@{fa-css-prefix}-exclamation-circle:before { content: @fa-var-exclamation-circle; }\n.@{fa-css-prefix}-gift:before { content: @fa-var-gift; }\n.@{fa-css-prefix}-leaf:before { content: @fa-var-leaf; }\n.@{fa-css-prefix}-fire:before { content: @fa-var-fire; }\n.@{fa-css-prefix}-eye:before { content: @fa-var-eye; }\n.@{fa-css-prefix}-eye-slash:before { content: @fa-var-eye-slash; }\n.@{fa-css-prefix}-warning:before,\n.@{fa-css-prefix}-exclamation-triangle:before { content: @fa-var-exclamation-triangle; }\n.@{fa-css-prefix}-plane:before { content: @fa-var-plane; }\n.@{fa-css-prefix}-calendar:before { content: @fa-var-calendar; }\n.@{fa-css-prefix}-random:before { content: @fa-var-random; }\n.@{fa-css-prefix}-comment:before { content: @fa-var-comment; }\n.@{fa-css-prefix}-magnet:before { content: @fa-var-magnet; }\n.@{fa-css-prefix}-chevron-up:before { content: @fa-var-chevron-up; }\n.@{fa-css-prefix}-chevron-down:before { content: @fa-var-chevron-down; }\n.@{fa-css-prefix}-retweet:before { content: @fa-var-retweet; }\n.@{fa-css-prefix}-shopping-cart:before { content: @fa-var-shopping-cart; }\n.@{fa-css-prefix}-folder:before { content: @fa-var-folder; }\n.@{fa-css-prefix}-folder-open:before { content: @fa-var-folder-open; }\n.@{fa-css-prefix}-arrows-v:before { content: @fa-var-arrows-v; }\n.@{fa-css-prefix}-arrows-h:before { content: @fa-var-arrows-h; }\n.@{fa-css-prefix}-bar-chart-o:before,\n.@{fa-css-prefix}-bar-chart:before { content: @fa-var-bar-chart; }\n.@{fa-css-prefix}-twitter-square:before { content: @fa-var-twitter-square; }\n.@{fa-css-prefix}-facebook-square:before { content: @fa-var-facebook-square; }\n.@{fa-css-prefix}-camera-retro:before { content: @fa-var-camera-retro; }\n.@{fa-css-prefix}-key:before { content: @fa-var-key; }\n.@{fa-css-prefix}-gears:before,\n.@{fa-css-prefix}-cogs:before { content: @fa-var-cogs; }\n.@{fa-css-prefix}-comments:before { content: @fa-var-comments; }\n.@{fa-css-prefix}-thumbs-o-up:before { content: @fa-var-thumbs-o-up; }\n.@{fa-css-prefix}-thumbs-o-down:before { content: @fa-var-thumbs-o-down; }\n.@{fa-css-prefix}-star-half:before { content: @fa-var-star-half; }\n.@{fa-css-prefix}-heart-o:before { content: @fa-var-heart-o; }\n.@{fa-css-prefix}-sign-out:before { content: @fa-var-sign-out; }\n.@{fa-css-prefix}-linkedin-square:before { content: @fa-var-linkedin-square; }\n.@{fa-css-prefix}-thumb-tack:before { content: @fa-var-thumb-tack; }\n.@{fa-css-prefix}-external-link:before { content: @fa-var-external-link; }\n.@{fa-css-prefix}-sign-in:before { content: @fa-var-sign-in; }\n.@{fa-css-prefix}-trophy:before { content: @fa-var-trophy; }\n.@{fa-css-prefix}-github-square:before { content: @fa-var-github-square; }\n.@{fa-css-prefix}-upload:before { content: @fa-var-upload; }\n.@{fa-css-prefix}-lemon-o:before { content: @fa-var-lemon-o; }\n.@{fa-css-prefix}-phone:before { content: @fa-var-phone; }\n.@{fa-css-prefix}-square-o:before { content: @fa-var-square-o; }\n.@{fa-css-prefix}-bookmark-o:before { content: @fa-var-bookmark-o; }\n.@{fa-css-prefix}-phone-square:before { content: @fa-var-phone-square; }\n.@{fa-css-prefix}-twitter:before { content: @fa-var-twitter; }\n.@{fa-css-prefix}-facebook-f:before,\n.@{fa-css-prefix}-facebook:before { content: @fa-var-facebook; }\n.@{fa-css-prefix}-github:before { content: @fa-var-github; }\n.@{fa-css-prefix}-unlock:before { content: @fa-var-unlock; }\n.@{fa-css-prefix}-credit-card:before { content: @fa-var-credit-card; }\n.@{fa-css-prefix}-feed:before,\n.@{fa-css-prefix}-rss:before { content: @fa-var-rss; }\n.@{fa-css-prefix}-hdd-o:before { content: @fa-var-hdd-o; }\n.@{fa-css-prefix}-bullhorn:before { content: @fa-var-bullhorn; }\n.@{fa-css-prefix}-bell:before { content: @fa-var-bell; }\n.@{fa-css-prefix}-certificate:before { content: @fa-var-certificate; }\n.@{fa-css-prefix}-hand-o-right:before { content: @fa-var-hand-o-right; }\n.@{fa-css-prefix}-hand-o-left:before { content: @fa-var-hand-o-left; }\n.@{fa-css-prefix}-hand-o-up:before { content: @fa-var-hand-o-up; }\n.@{fa-css-prefix}-hand-o-down:before { content: @fa-var-hand-o-down; }\n.@{fa-css-prefix}-arrow-circle-left:before { content: @fa-var-arrow-circle-left; }\n.@{fa-css-prefix}-arrow-circle-right:before { content: @fa-var-arrow-circle-right; }\n.@{fa-css-prefix}-arrow-circle-up:before { content: @fa-var-arrow-circle-up; }\n.@{fa-css-prefix}-arrow-circle-down:before { content: @fa-var-arrow-circle-down; }\n.@{fa-css-prefix}-globe:before { content: @fa-var-globe; }\n.@{fa-css-prefix}-wrench:before { content: @fa-var-wrench; }\n.@{fa-css-prefix}-tasks:before { content: @fa-var-tasks; }\n.@{fa-css-prefix}-filter:before { content: @fa-var-filter; }\n.@{fa-css-prefix}-briefcase:before { content: @fa-var-briefcase; }\n.@{fa-css-prefix}-arrows-alt:before { content: @fa-var-arrows-alt; }\n.@{fa-css-prefix}-group:before,\n.@{fa-css-prefix}-users:before { content: @fa-var-users; }\n.@{fa-css-prefix}-chain:before,\n.@{fa-css-prefix}-link:before { content: @fa-var-link; }\n.@{fa-css-prefix}-cloud:before { content: @fa-var-cloud; }\n.@{fa-css-prefix}-flask:before { content: @fa-var-flask; }\n.@{fa-css-prefix}-cut:before,\n.@{fa-css-prefix}-scissors:before { content: @fa-var-scissors; }\n.@{fa-css-prefix}-copy:before,\n.@{fa-css-prefix}-files-o:before { content: @fa-var-files-o; }\n.@{fa-css-prefix}-paperclip:before { content: @fa-var-paperclip; }\n.@{fa-css-prefix}-save:before,\n.@{fa-css-prefix}-floppy-o:before { content: @fa-var-floppy-o; }\n.@{fa-css-prefix}-square:before { content: @fa-var-square; }\n.@{fa-css-prefix}-navicon:before,\n.@{fa-css-prefix}-reorder:before,\n.@{fa-css-prefix}-bars:before { content: @fa-var-bars; }\n.@{fa-css-prefix}-list-ul:before { content: @fa-var-list-ul; }\n.@{fa-css-prefix}-list-ol:before { content: @fa-var-list-ol; }\n.@{fa-css-prefix}-strikethrough:before { content: @fa-var-strikethrough; }\n.@{fa-css-prefix}-underline:before { content: @fa-var-underline; }\n.@{fa-css-prefix}-table:before { content: @fa-var-table; }\n.@{fa-css-prefix}-magic:before { content: @fa-var-magic; }\n.@{fa-css-prefix}-truck:before { content: @fa-var-truck; }\n.@{fa-css-prefix}-pinterest:before { content: @fa-var-pinterest; }\n.@{fa-css-prefix}-pinterest-square:before { content: @fa-var-pinterest-square; }\n.@{fa-css-prefix}-google-plus-square:before { content: @fa-var-google-plus-square; }\n.@{fa-css-prefix}-google-plus:before { content: @fa-var-google-plus; }\n.@{fa-css-prefix}-money:before { content: @fa-var-money; }\n.@{fa-css-prefix}-caret-down:before { content: @fa-var-caret-down; }\n.@{fa-css-prefix}-caret-up:before { content: @fa-var-caret-up; }\n.@{fa-css-prefix}-caret-left:before { content: @fa-var-caret-left; }\n.@{fa-css-prefix}-caret-right:before { content: @fa-var-caret-right; }\n.@{fa-css-prefix}-columns:before { content: @fa-var-columns; }\n.@{fa-css-prefix}-unsorted:before,\n.@{fa-css-prefix}-sort:before { content: @fa-var-sort; }\n.@{fa-css-prefix}-sort-down:before,\n.@{fa-css-prefix}-sort-desc:before { content: @fa-var-sort-desc; }\n.@{fa-css-prefix}-sort-up:before,\n.@{fa-css-prefix}-sort-asc:before { content: @fa-var-sort-asc; }\n.@{fa-css-prefix}-envelope:before { content: @fa-var-envelope; }\n.@{fa-css-prefix}-linkedin:before { content: @fa-var-linkedin; }\n.@{fa-css-prefix}-rotate-left:before,\n.@{fa-css-prefix}-undo:before { content: @fa-var-undo; }\n.@{fa-css-prefix}-legal:before,\n.@{fa-css-prefix}-gavel:before { content: @fa-var-gavel; }\n.@{fa-css-prefix}-dashboard:before,\n.@{fa-css-prefix}-tachometer:before { content: @fa-var-tachometer; }\n.@{fa-css-prefix}-comment-o:before { content: @fa-var-comment-o; }\n.@{fa-css-prefix}-comments-o:before { content: @fa-var-comments-o; }\n.@{fa-css-prefix}-flash:before,\n.@{fa-css-prefix}-bolt:before { content: @fa-var-bolt; }\n.@{fa-css-prefix}-sitemap:before { content: @fa-var-sitemap; }\n.@{fa-css-prefix}-umbrella:before { content: @fa-var-umbrella; }\n.@{fa-css-prefix}-paste:before,\n.@{fa-css-prefix}-clipboard:before { content: @fa-var-clipboard; }\n.@{fa-css-prefix}-lightbulb-o:before { content: @fa-var-lightbulb-o; }\n.@{fa-css-prefix}-exchange:before { content: @fa-var-exchange; }\n.@{fa-css-prefix}-cloud-download:before { content: @fa-var-cloud-download; }\n.@{fa-css-prefix}-cloud-upload:before { content: @fa-var-cloud-upload; }\n.@{fa-css-prefix}-user-md:before { content: @fa-var-user-md; }\n.@{fa-css-prefix}-stethoscope:before { content: @fa-var-stethoscope; }\n.@{fa-css-prefix}-suitcase:before { content: @fa-var-suitcase; }\n.@{fa-css-prefix}-bell-o:before { content: @fa-var-bell-o; }\n.@{fa-css-prefix}-coffee:before { content: @fa-var-coffee; }\n.@{fa-css-prefix}-cutlery:before { content: @fa-var-cutlery; }\n.@{fa-css-prefix}-file-text-o:before { content: @fa-var-file-text-o; }\n.@{fa-css-prefix}-building-o:before { content: @fa-var-building-o; }\n.@{fa-css-prefix}-hospital-o:before { content: @fa-var-hospital-o; }\n.@{fa-css-prefix}-ambulance:before { content: @fa-var-ambulance; }\n.@{fa-css-prefix}-medkit:before { content: @fa-var-medkit; }\n.@{fa-css-prefix}-fighter-jet:before { content: @fa-var-fighter-jet; }\n.@{fa-css-prefix}-beer:before { content: @fa-var-beer; }\n.@{fa-css-prefix}-h-square:before { content: @fa-var-h-square; }\n.@{fa-css-prefix}-plus-square:before { content: @fa-var-plus-square; }\n.@{fa-css-prefix}-angle-double-left:before { content: @fa-var-angle-double-left; }\n.@{fa-css-prefix}-angle-double-right:before { content: @fa-var-angle-double-right; }\n.@{fa-css-prefix}-angle-double-up:before { content: @fa-var-angle-double-up; }\n.@{fa-css-prefix}-angle-double-down:before { content: @fa-var-angle-double-down; }\n.@{fa-css-prefix}-angle-left:before { content: @fa-var-angle-left; }\n.@{fa-css-prefix}-angle-right:before { content: @fa-var-angle-right; }\n.@{fa-css-prefix}-angle-up:before { content: @fa-var-angle-up; }\n.@{fa-css-prefix}-angle-down:before { content: @fa-var-angle-down; }\n.@{fa-css-prefix}-desktop:before { content: @fa-var-desktop; }\n.@{fa-css-prefix}-laptop:before { content: @fa-var-laptop; }\n.@{fa-css-prefix}-tablet:before { content: @fa-var-tablet; }\n.@{fa-css-prefix}-mobile-phone:before,\n.@{fa-css-prefix}-mobile:before { content: @fa-var-mobile; }\n.@{fa-css-prefix}-circle-o:before { content: @fa-var-circle-o; }\n.@{fa-css-prefix}-quote-left:before { content: @fa-var-quote-left; }\n.@{fa-css-prefix}-quote-right:before { content: @fa-var-quote-right; }\n.@{fa-css-prefix}-spinner:before { content: @fa-var-spinner; }\n.@{fa-css-prefix}-circle:before { content: @fa-var-circle; }\n.@{fa-css-prefix}-mail-reply:before,\n.@{fa-css-prefix}-reply:before { content: @fa-var-reply; }\n.@{fa-css-prefix}-github-alt:before { content: @fa-var-github-alt; }\n.@{fa-css-prefix}-folder-o:before { content: @fa-var-folder-o; }\n.@{fa-css-prefix}-folder-open-o:before { content: @fa-var-folder-open-o; }\n.@{fa-css-prefix}-smile-o:before { content: @fa-var-smile-o; }\n.@{fa-css-prefix}-frown-o:before { content: @fa-var-frown-o; }\n.@{fa-css-prefix}-meh-o:before { content: @fa-var-meh-o; }\n.@{fa-css-prefix}-gamepad:before { content: @fa-var-gamepad; }\n.@{fa-css-prefix}-keyboard-o:before { content: @fa-var-keyboard-o; }\n.@{fa-css-prefix}-flag-o:before { content: @fa-var-flag-o; }\n.@{fa-css-prefix}-flag-checkered:before { content: @fa-var-flag-checkered; }\n.@{fa-css-prefix}-terminal:before { content: @fa-var-terminal; }\n.@{fa-css-prefix}-code:before { content: @fa-var-code; }\n.@{fa-css-prefix}-mail-reply-all:before,\n.@{fa-css-prefix}-reply-all:before { content: @fa-var-reply-all; }\n.@{fa-css-prefix}-star-half-empty:before,\n.@{fa-css-prefix}-star-half-full:before,\n.@{fa-css-prefix}-star-half-o:before { content: @fa-var-star-half-o; }\n.@{fa-css-prefix}-location-arrow:before { content: @fa-var-location-arrow; }\n.@{fa-css-prefix}-crop:before { content: @fa-var-crop; }\n.@{fa-css-prefix}-code-fork:before { content: @fa-var-code-fork; }\n.@{fa-css-prefix}-unlink:before,\n.@{fa-css-prefix}-chain-broken:before { content: @fa-var-chain-broken; }\n.@{fa-css-prefix}-question:before { content: @fa-var-question; }\n.@{fa-css-prefix}-info:before { content: @fa-var-info; }\n.@{fa-css-prefix}-exclamation:before { content: @fa-var-exclamation; }\n.@{fa-css-prefix}-superscript:before { content: @fa-var-superscript; }\n.@{fa-css-prefix}-subscript:before { content: @fa-var-subscript; }\n.@{fa-css-prefix}-eraser:before { content: @fa-var-eraser; }\n.@{fa-css-prefix}-puzzle-piece:before { content: @fa-var-puzzle-piece; }\n.@{fa-css-prefix}-microphone:before { content: @fa-var-microphone; }\n.@{fa-css-prefix}-microphone-slash:before { content: @fa-var-microphone-slash; }\n.@{fa-css-prefix}-shield:before { content: @fa-var-shield; }\n.@{fa-css-prefix}-calendar-o:before { content: @fa-var-calendar-o; }\n.@{fa-css-prefix}-fire-extinguisher:before { content: @fa-var-fire-extinguisher; }\n.@{fa-css-prefix}-rocket:before { content: @fa-var-rocket; }\n.@{fa-css-prefix}-maxcdn:before { content: @fa-var-maxcdn; }\n.@{fa-css-prefix}-chevron-circle-left:before { content: @fa-var-chevron-circle-left; }\n.@{fa-css-prefix}-chevron-circle-right:before { content: @fa-var-chevron-circle-right; }\n.@{fa-css-prefix}-chevron-circle-up:before { content: @fa-var-chevron-circle-up; }\n.@{fa-css-prefix}-chevron-circle-down:before { content: @fa-var-chevron-circle-down; }\n.@{fa-css-prefix}-html5:before { content: @fa-var-html5; }\n.@{fa-css-prefix}-css3:before { content: @fa-var-css3; }\n.@{fa-css-prefix}-anchor:before { content: @fa-var-anchor; }\n.@{fa-css-prefix}-unlock-alt:before { content: @fa-var-unlock-alt; }\n.@{fa-css-prefix}-bullseye:before { content: @fa-var-bullseye; }\n.@{fa-css-prefix}-ellipsis-h:before { content: @fa-var-ellipsis-h; }\n.@{fa-css-prefix}-ellipsis-v:before { content: @fa-var-ellipsis-v; }\n.@{fa-css-prefix}-rss-square:before { content: @fa-var-rss-square; }\n.@{fa-css-prefix}-play-circle:before { content: @fa-var-play-circle; }\n.@{fa-css-prefix}-ticket:before { content: @fa-var-ticket; }\n.@{fa-css-prefix}-minus-square:before { content: @fa-var-minus-square; }\n.@{fa-css-prefix}-minus-square-o:before { content: @fa-var-minus-square-o; }\n.@{fa-css-prefix}-level-up:before { content: @fa-var-level-up; }\n.@{fa-css-prefix}-level-down:before { content: @fa-var-level-down; }\n.@{fa-css-prefix}-check-square:before { content: @fa-var-check-square; }\n.@{fa-css-prefix}-pencil-square:before { content: @fa-var-pencil-square; }\n.@{fa-css-prefix}-external-link-square:before { content: @fa-var-external-link-square; }\n.@{fa-css-prefix}-share-square:before { content: @fa-var-share-square; }\n.@{fa-css-prefix}-compass:before { content: @fa-var-compass; }\n.@{fa-css-prefix}-toggle-down:before,\n.@{fa-css-prefix}-caret-square-o-down:before { content: @fa-var-caret-square-o-down; }\n.@{fa-css-prefix}-toggle-up:before,\n.@{fa-css-prefix}-caret-square-o-up:before { content: @fa-var-caret-square-o-up; }\n.@{fa-css-prefix}-toggle-right:before,\n.@{fa-css-prefix}-caret-square-o-right:before { content: @fa-var-caret-square-o-right; }\n.@{fa-css-prefix}-euro:before,\n.@{fa-css-prefix}-eur:before { content: @fa-var-eur; }\n.@{fa-css-prefix}-gbp:before { content: @fa-var-gbp; }\n.@{fa-css-prefix}-dollar:before,\n.@{fa-css-prefix}-usd:before { content: @fa-var-usd; }\n.@{fa-css-prefix}-rupee:before,\n.@{fa-css-prefix}-inr:before { content: @fa-var-inr; }\n.@{fa-css-prefix}-cny:before,\n.@{fa-css-prefix}-rmb:before,\n.@{fa-css-prefix}-yen:before,\n.@{fa-css-prefix}-jpy:before { content: @fa-var-jpy; }\n.@{fa-css-prefix}-ruble:before,\n.@{fa-css-prefix}-rouble:before,\n.@{fa-css-prefix}-rub:before { content: @fa-var-rub; }\n.@{fa-css-prefix}-won:before,\n.@{fa-css-prefix}-krw:before { content: @fa-var-krw; }\n.@{fa-css-prefix}-bitcoin:before,\n.@{fa-css-prefix}-btc:before { content: @fa-var-btc; }\n.@{fa-css-prefix}-file:before { content: @fa-var-file; }\n.@{fa-css-prefix}-file-text:before { content: @fa-var-file-text; }\n.@{fa-css-prefix}-sort-alpha-asc:before { content: @fa-var-sort-alpha-asc; }\n.@{fa-css-prefix}-sort-alpha-desc:before { content: @fa-var-sort-alpha-desc; }\n.@{fa-css-prefix}-sort-amount-asc:before { content: @fa-var-sort-amount-asc; }\n.@{fa-css-prefix}-sort-amount-desc:before { content: @fa-var-sort-amount-desc; }\n.@{fa-css-prefix}-sort-numeric-asc:before { content: @fa-var-sort-numeric-asc; }\n.@{fa-css-prefix}-sort-numeric-desc:before { content: @fa-var-sort-numeric-desc; }\n.@{fa-css-prefix}-thumbs-up:before { content: @fa-var-thumbs-up; }\n.@{fa-css-prefix}-thumbs-down:before { content: @fa-var-thumbs-down; }\n.@{fa-css-prefix}-youtube-square:before { content: @fa-var-youtube-square; }\n.@{fa-css-prefix}-youtube:before { content: @fa-var-youtube; }\n.@{fa-css-prefix}-xing:before { content: @fa-var-xing; }\n.@{fa-css-prefix}-xing-square:before { content: @fa-var-xing-square; }\n.@{fa-css-prefix}-youtube-play:before { content: @fa-var-youtube-play; }\n.@{fa-css-prefix}-dropbox:before { content: @fa-var-dropbox; }\n.@{fa-css-prefix}-stack-overflow:before { content: @fa-var-stack-overflow; }\n.@{fa-css-prefix}-instagram:before { content: @fa-var-instagram; }\n.@{fa-css-prefix}-flickr:before { content: @fa-var-flickr; }\n.@{fa-css-prefix}-adn:before { content: @fa-var-adn; }\n.@{fa-css-prefix}-bitbucket:before { content: @fa-var-bitbucket; }\n.@{fa-css-prefix}-bitbucket-square:before { content: @fa-var-bitbucket-square; }\n.@{fa-css-prefix}-tumblr:before { content: @fa-var-tumblr; }\n.@{fa-css-prefix}-tumblr-square:before { content: @fa-var-tumblr-square; }\n.@{fa-css-prefix}-long-arrow-down:before { content: @fa-var-long-arrow-down; }\n.@{fa-css-prefix}-long-arrow-up:before { content: @fa-var-long-arrow-up; }\n.@{fa-css-prefix}-long-arrow-left:before { content: @fa-var-long-arrow-left; }\n.@{fa-css-prefix}-long-arrow-right:before { content: @fa-var-long-arrow-right; }\n.@{fa-css-prefix}-apple:before { content: @fa-var-apple; }\n.@{fa-css-prefix}-windows:before { content: @fa-var-windows; }\n.@{fa-css-prefix}-android:before { content: @fa-var-android; }\n.@{fa-css-prefix}-linux:before { content: @fa-var-linux; }\n.@{fa-css-prefix}-dribbble:before { content: @fa-var-dribbble; }\n.@{fa-css-prefix}-skype:before { content: @fa-var-skype; }\n.@{fa-css-prefix}-foursquare:before { content: @fa-var-foursquare; }\n.@{fa-css-prefix}-trello:before { content: @fa-var-trello; }\n.@{fa-css-prefix}-female:before { content: @fa-var-female; }\n.@{fa-css-prefix}-male:before { content: @fa-var-male; }\n.@{fa-css-prefix}-gittip:before,\n.@{fa-css-prefix}-gratipay:before { content: @fa-var-gratipay; }\n.@{fa-css-prefix}-sun-o:before { content: @fa-var-sun-o; }\n.@{fa-css-prefix}-moon-o:before { content: @fa-var-moon-o; }\n.@{fa-css-prefix}-archive:before { content: @fa-var-archive; }\n.@{fa-css-prefix}-bug:before { content: @fa-var-bug; }\n.@{fa-css-prefix}-vk:before { content: @fa-var-vk; }\n.@{fa-css-prefix}-weibo:before { content: @fa-var-weibo; }\n.@{fa-css-prefix}-renren:before { content: @fa-var-renren; }\n.@{fa-css-prefix}-pagelines:before { content: @fa-var-pagelines; }\n.@{fa-css-prefix}-stack-exchange:before { content: @fa-var-stack-exchange; }\n.@{fa-css-prefix}-arrow-circle-o-right:before { content: @fa-var-arrow-circle-o-right; }\n.@{fa-css-prefix}-arrow-circle-o-left:before { content: @fa-var-arrow-circle-o-left; }\n.@{fa-css-prefix}-toggle-left:before,\n.@{fa-css-prefix}-caret-square-o-left:before { content: @fa-var-caret-square-o-left; }\n.@{fa-css-prefix}-dot-circle-o:before { content: @fa-var-dot-circle-o; }\n.@{fa-css-prefix}-wheelchair:before { content: @fa-var-wheelchair; }\n.@{fa-css-prefix}-vimeo-square:before { content: @fa-var-vimeo-square; }\n.@{fa-css-prefix}-turkish-lira:before,\n.@{fa-css-prefix}-try:before { content: @fa-var-try; }\n.@{fa-css-prefix}-plus-square-o:before { content: @fa-var-plus-square-o; }\n.@{fa-css-prefix}-space-shuttle:before { content: @fa-var-space-shuttle; }\n.@{fa-css-prefix}-slack:before { content: @fa-var-slack; }\n.@{fa-css-prefix}-envelope-square:before { content: @fa-var-envelope-square; }\n.@{fa-css-prefix}-wordpress:before { content: @fa-var-wordpress; }\n.@{fa-css-prefix}-openid:before { content: @fa-var-openid; }\n.@{fa-css-prefix}-institution:before,\n.@{fa-css-prefix}-bank:before,\n.@{fa-css-prefix}-university:before { content: @fa-var-university; }\n.@{fa-css-prefix}-mortar-board:before,\n.@{fa-css-prefix}-graduation-cap:before { content: @fa-var-graduation-cap; }\n.@{fa-css-prefix}-yahoo:before { content: @fa-var-yahoo; }\n.@{fa-css-prefix}-google:before { content: @fa-var-google; }\n.@{fa-css-prefix}-reddit:before { content: @fa-var-reddit; }\n.@{fa-css-prefix}-reddit-square:before { content: @fa-var-reddit-square; }\n.@{fa-css-prefix}-stumbleupon-circle:before { content: @fa-var-stumbleupon-circle; }\n.@{fa-css-prefix}-stumbleupon:before { content: @fa-var-stumbleupon; }\n.@{fa-css-prefix}-delicious:before { content: @fa-var-delicious; }\n.@{fa-css-prefix}-digg:before { content: @fa-var-digg; }\n.@{fa-css-prefix}-pied-piper-pp:before { content: @fa-var-pied-piper-pp; }\n.@{fa-css-prefix}-pied-piper-alt:before { content: @fa-var-pied-piper-alt; }\n.@{fa-css-prefix}-drupal:before { content: @fa-var-drupal; }\n.@{fa-css-prefix}-joomla:before { content: @fa-var-joomla; }\n.@{fa-css-prefix}-language:before { content: @fa-var-language; }\n.@{fa-css-prefix}-fax:before { content: @fa-var-fax; }\n.@{fa-css-prefix}-building:before { content: @fa-var-building; }\n.@{fa-css-prefix}-child:before { content: @fa-var-child; }\n.@{fa-css-prefix}-paw:before { content: @fa-var-paw; }\n.@{fa-css-prefix}-spoon:before { content: @fa-var-spoon; }\n.@{fa-css-prefix}-cube:before { content: @fa-var-cube; }\n.@{fa-css-prefix}-cubes:before { content: @fa-var-cubes; }\n.@{fa-css-prefix}-behance:before { content: @fa-var-behance; }\n.@{fa-css-prefix}-behance-square:before { content: @fa-var-behance-square; }\n.@{fa-css-prefix}-steam:before { content: @fa-var-steam; }\n.@{fa-css-prefix}-steam-square:before { content: @fa-var-steam-square; }\n.@{fa-css-prefix}-recycle:before { content: @fa-var-recycle; }\n.@{fa-css-prefix}-automobile:before,\n.@{fa-css-prefix}-car:before { content: @fa-var-car; }\n.@{fa-css-prefix}-cab:before,\n.@{fa-css-prefix}-taxi:before { content: @fa-var-taxi; }\n.@{fa-css-prefix}-tree:before { content: @fa-var-tree; }\n.@{fa-css-prefix}-spotify:before { content: @fa-var-spotify; }\n.@{fa-css-prefix}-deviantart:before { content: @fa-var-deviantart; }\n.@{fa-css-prefix}-soundcloud:before { content: @fa-var-soundcloud; }\n.@{fa-css-prefix}-database:before { content: @fa-var-database; }\n.@{fa-css-prefix}-file-pdf-o:before { content: @fa-var-file-pdf-o; }\n.@{fa-css-prefix}-file-word-o:before { content: @fa-var-file-word-o; }\n.@{fa-css-prefix}-file-excel-o:before { content: @fa-var-file-excel-o; }\n.@{fa-css-prefix}-file-powerpoint-o:before { content: @fa-var-file-powerpoint-o; }\n.@{fa-css-prefix}-file-photo-o:before,\n.@{fa-css-prefix}-file-picture-o:before,\n.@{fa-css-prefix}-file-image-o:before { content: @fa-var-file-image-o; }\n.@{fa-css-prefix}-file-zip-o:before,\n.@{fa-css-prefix}-file-archive-o:before { content: @fa-var-file-archive-o; }\n.@{fa-css-prefix}-file-sound-o:before,\n.@{fa-css-prefix}-file-audio-o:before { content: @fa-var-file-audio-o; }\n.@{fa-css-prefix}-file-movie-o:before,\n.@{fa-css-prefix}-file-video-o:before { content: @fa-var-file-video-o; }\n.@{fa-css-prefix}-file-code-o:before { content: @fa-var-file-code-o; }\n.@{fa-css-prefix}-vine:before { content: @fa-var-vine; }\n.@{fa-css-prefix}-codepen:before { content: @fa-var-codepen; }\n.@{fa-css-prefix}-jsfiddle:before { content: @fa-var-jsfiddle; }\n.@{fa-css-prefix}-life-bouy:before,\n.@{fa-css-prefix}-life-buoy:before,\n.@{fa-css-prefix}-life-saver:before,\n.@{fa-css-prefix}-support:before,\n.@{fa-css-prefix}-life-ring:before { content: @fa-var-life-ring; }\n.@{fa-css-prefix}-circle-o-notch:before { content: @fa-var-circle-o-notch; }\n.@{fa-css-prefix}-ra:before,\n.@{fa-css-prefix}-resistance:before,\n.@{fa-css-prefix}-rebel:before { content: @fa-var-rebel; }\n.@{fa-css-prefix}-ge:before,\n.@{fa-css-prefix}-empire:before { content: @fa-var-empire; }\n.@{fa-css-prefix}-git-square:before { content: @fa-var-git-square; }\n.@{fa-css-prefix}-git:before { content: @fa-var-git; }\n.@{fa-css-prefix}-y-combinator-square:before,\n.@{fa-css-prefix}-yc-square:before,\n.@{fa-css-prefix}-hacker-news:before { content: @fa-var-hacker-news; }\n.@{fa-css-prefix}-tencent-weibo:before { content: @fa-var-tencent-weibo; }\n.@{fa-css-prefix}-qq:before { content: @fa-var-qq; }\n.@{fa-css-prefix}-wechat:before,\n.@{fa-css-prefix}-weixin:before { content: @fa-var-weixin; }\n.@{fa-css-prefix}-send:before,\n.@{fa-css-prefix}-paper-plane:before { content: @fa-var-paper-plane; }\n.@{fa-css-prefix}-send-o:before,\n.@{fa-css-prefix}-paper-plane-o:before { content: @fa-var-paper-plane-o; }\n.@{fa-css-prefix}-history:before { content: @fa-var-history; }\n.@{fa-css-prefix}-circle-thin:before { content: @fa-var-circle-thin; }\n.@{fa-css-prefix}-header:before { content: @fa-var-header; }\n.@{fa-css-prefix}-paragraph:before { content: @fa-var-paragraph; }\n.@{fa-css-prefix}-sliders:before { content: @fa-var-sliders; }\n.@{fa-css-prefix}-share-alt:before { content: @fa-var-share-alt; }\n.@{fa-css-prefix}-share-alt-square:before { content: @fa-var-share-alt-square; }\n.@{fa-css-prefix}-bomb:before { content: @fa-var-bomb; }\n.@{fa-css-prefix}-soccer-ball-o:before,\n.@{fa-css-prefix}-futbol-o:before { content: @fa-var-futbol-o; }\n.@{fa-css-prefix}-tty:before { content: @fa-var-tty; }\n.@{fa-css-prefix}-binoculars:before { content: @fa-var-binoculars; }\n.@{fa-css-prefix}-plug:before { content: @fa-var-plug; }\n.@{fa-css-prefix}-slideshare:before { content: @fa-var-slideshare; }\n.@{fa-css-prefix}-twitch:before { content: @fa-var-twitch; }\n.@{fa-css-prefix}-yelp:before { content: @fa-var-yelp; }\n.@{fa-css-prefix}-newspaper-o:before { content: @fa-var-newspaper-o; }\n.@{fa-css-prefix}-wifi:before { content: @fa-var-wifi; }\n.@{fa-css-prefix}-calculator:before { content: @fa-var-calculator; }\n.@{fa-css-prefix}-paypal:before { content: @fa-var-paypal; }\n.@{fa-css-prefix}-google-wallet:before { content: @fa-var-google-wallet; }\n.@{fa-css-prefix}-cc-visa:before { content: @fa-var-cc-visa; }\n.@{fa-css-prefix}-cc-mastercard:before { content: @fa-var-cc-mastercard; }\n.@{fa-css-prefix}-cc-discover:before { content: @fa-var-cc-discover; }\n.@{fa-css-prefix}-cc-amex:before { content: @fa-var-cc-amex; }\n.@{fa-css-prefix}-cc-paypal:before { content: @fa-var-cc-paypal; }\n.@{fa-css-prefix}-cc-stripe:before { content: @fa-var-cc-stripe; }\n.@{fa-css-prefix}-bell-slash:before { content: @fa-var-bell-slash; }\n.@{fa-css-prefix}-bell-slash-o:before { content: @fa-var-bell-slash-o; }\n.@{fa-css-prefix}-trash:before { content: @fa-var-trash; }\n.@{fa-css-prefix}-copyright:before { content: @fa-var-copyright; }\n.@{fa-css-prefix}-at:before { content: @fa-var-at; }\n.@{fa-css-prefix}-eyedropper:before { content: @fa-var-eyedropper; }\n.@{fa-css-prefix}-paint-brush:before { content: @fa-var-paint-brush; }\n.@{fa-css-prefix}-birthday-cake:before { content: @fa-var-birthday-cake; }\n.@{fa-css-prefix}-area-chart:before { content: @fa-var-area-chart; }\n.@{fa-css-prefix}-pie-chart:before { content: @fa-var-pie-chart; }\n.@{fa-css-prefix}-line-chart:before { content: @fa-var-line-chart; }\n.@{fa-css-prefix}-lastfm:before { content: @fa-var-lastfm; }\n.@{fa-css-prefix}-lastfm-square:before { content: @fa-var-lastfm-square; }\n.@{fa-css-prefix}-toggle-off:before { content: @fa-var-toggle-off; }\n.@{fa-css-prefix}-toggle-on:before { content: @fa-var-toggle-on; }\n.@{fa-css-prefix}-bicycle:before { content: @fa-var-bicycle; }\n.@{fa-css-prefix}-bus:before { content: @fa-var-bus; }\n.@{fa-css-prefix}-ioxhost:before { content: @fa-var-ioxhost; }\n.@{fa-css-prefix}-angellist:before { content: @fa-var-angellist; }\n.@{fa-css-prefix}-cc:before { content: @fa-var-cc; }\n.@{fa-css-prefix}-shekel:before,\n.@{fa-css-prefix}-sheqel:before,\n.@{fa-css-prefix}-ils:before { content: @fa-var-ils; }\n.@{fa-css-prefix}-meanpath:before { content: @fa-var-meanpath; }\n.@{fa-css-prefix}-buysellads:before { content: @fa-var-buysellads; }\n.@{fa-css-prefix}-connectdevelop:before { content: @fa-var-connectdevelop; }\n.@{fa-css-prefix}-dashcube:before { content: @fa-var-dashcube; }\n.@{fa-css-prefix}-forumbee:before { content: @fa-var-forumbee; }\n.@{fa-css-prefix}-leanpub:before { content: @fa-var-leanpub; }\n.@{fa-css-prefix}-sellsy:before { content: @fa-var-sellsy; }\n.@{fa-css-prefix}-shirtsinbulk:before { content: @fa-var-shirtsinbulk; }\n.@{fa-css-prefix}-simplybuilt:before { content: @fa-var-simplybuilt; }\n.@{fa-css-prefix}-skyatlas:before { content: @fa-var-skyatlas; }\n.@{fa-css-prefix}-cart-plus:before { content: @fa-var-cart-plus; }\n.@{fa-css-prefix}-cart-arrow-down:before { content: @fa-var-cart-arrow-down; }\n.@{fa-css-prefix}-diamond:before { content: @fa-var-diamond; }\n.@{fa-css-prefix}-ship:before { content: @fa-var-ship; }\n.@{fa-css-prefix}-user-secret:before { content: @fa-var-user-secret; }\n.@{fa-css-prefix}-motorcycle:before { content: @fa-var-motorcycle; }\n.@{fa-css-prefix}-street-view:before { content: @fa-var-street-view; }\n.@{fa-css-prefix}-heartbeat:before { content: @fa-var-heartbeat; }\n.@{fa-css-prefix}-venus:before { content: @fa-var-venus; }\n.@{fa-css-prefix}-mars:before { content: @fa-var-mars; }\n.@{fa-css-prefix}-mercury:before { content: @fa-var-mercury; }\n.@{fa-css-prefix}-intersex:before,\n.@{fa-css-prefix}-transgender:before { content: @fa-var-transgender; }\n.@{fa-css-prefix}-transgender-alt:before { content: @fa-var-transgender-alt; }\n.@{fa-css-prefix}-venus-double:before { content: @fa-var-venus-double; }\n.@{fa-css-prefix}-mars-double:before { content: @fa-var-mars-double; }\n.@{fa-css-prefix}-venus-mars:before { content: @fa-var-venus-mars; }\n.@{fa-css-prefix}-mars-stroke:before { content: @fa-var-mars-stroke; }\n.@{fa-css-prefix}-mars-stroke-v:before { content: @fa-var-mars-stroke-v; }\n.@{fa-css-prefix}-mars-stroke-h:before { content: @fa-var-mars-stroke-h; }\n.@{fa-css-prefix}-neuter:before { content: @fa-var-neuter; }\n.@{fa-css-prefix}-genderless:before { content: @fa-var-genderless; }\n.@{fa-css-prefix}-facebook-official:before { content: @fa-var-facebook-official; }\n.@{fa-css-prefix}-pinterest-p:before { content: @fa-var-pinterest-p; }\n.@{fa-css-prefix}-whatsapp:before { content: @fa-var-whatsapp; }\n.@{fa-css-prefix}-server:before { content: @fa-var-server; }\n.@{fa-css-prefix}-user-plus:before { content: @fa-var-user-plus; }\n.@{fa-css-prefix}-user-times:before { content: @fa-var-user-times; }\n.@{fa-css-prefix}-hotel:before,\n.@{fa-css-prefix}-bed:before { content: @fa-var-bed; }\n.@{fa-css-prefix}-viacoin:before { content: @fa-var-viacoin; }\n.@{fa-css-prefix}-train:before { content: @fa-var-train; }\n.@{fa-css-prefix}-subway:before { content: @fa-var-subway; }\n.@{fa-css-prefix}-medium:before { content: @fa-var-medium; }\n.@{fa-css-prefix}-yc:before,\n.@{fa-css-prefix}-y-combinator:before { content: @fa-var-y-combinator; }\n.@{fa-css-prefix}-optin-monster:before { content: @fa-var-optin-monster; }\n.@{fa-css-prefix}-opencart:before { content: @fa-var-opencart; }\n.@{fa-css-prefix}-expeditedssl:before { content: @fa-var-expeditedssl; }\n.@{fa-css-prefix}-battery-4:before,\n.@{fa-css-prefix}-battery-full:before { content: @fa-var-battery-full; }\n.@{fa-css-prefix}-battery-3:before,\n.@{fa-css-prefix}-battery-three-quarters:before { content: @fa-var-battery-three-quarters; }\n.@{fa-css-prefix}-battery-2:before,\n.@{fa-css-prefix}-battery-half:before { content: @fa-var-battery-half; }\n.@{fa-css-prefix}-battery-1:before,\n.@{fa-css-prefix}-battery-quarter:before { content: @fa-var-battery-quarter; }\n.@{fa-css-prefix}-battery-0:before,\n.@{fa-css-prefix}-battery-empty:before { content: @fa-var-battery-empty; }\n.@{fa-css-prefix}-mouse-pointer:before { content: @fa-var-mouse-pointer; }\n.@{fa-css-prefix}-i-cursor:before { content: @fa-var-i-cursor; }\n.@{fa-css-prefix}-object-group:before { content: @fa-var-object-group; }\n.@{fa-css-prefix}-object-ungroup:before { content: @fa-var-object-ungroup; }\n.@{fa-css-prefix}-sticky-note:before { content: @fa-var-sticky-note; }\n.@{fa-css-prefix}-sticky-note-o:before { content: @fa-var-sticky-note-o; }\n.@{fa-css-prefix}-cc-jcb:before { content: @fa-var-cc-jcb; }\n.@{fa-css-prefix}-cc-diners-club:before { content: @fa-var-cc-diners-club; }\n.@{fa-css-prefix}-clone:before { content: @fa-var-clone; }\n.@{fa-css-prefix}-balance-scale:before { content: @fa-var-balance-scale; }\n.@{fa-css-prefix}-hourglass-o:before { content: @fa-var-hourglass-o; }\n.@{fa-css-prefix}-hourglass-1:before,\n.@{fa-css-prefix}-hourglass-start:before { content: @fa-var-hourglass-start; }\n.@{fa-css-prefix}-hourglass-2:before,\n.@{fa-css-prefix}-hourglass-half:before { content: @fa-var-hourglass-half; }\n.@{fa-css-prefix}-hourglass-3:before,\n.@{fa-css-prefix}-hourglass-end:before { content: @fa-var-hourglass-end; }\n.@{fa-css-prefix}-hourglass:before { content: @fa-var-hourglass; }\n.@{fa-css-prefix}-hand-grab-o:before,\n.@{fa-css-prefix}-hand-rock-o:before { content: @fa-var-hand-rock-o; }\n.@{fa-css-prefix}-hand-stop-o:before,\n.@{fa-css-prefix}-hand-paper-o:before { content: @fa-var-hand-paper-o; }\n.@{fa-css-prefix}-hand-scissors-o:before { content: @fa-var-hand-scissors-o; }\n.@{fa-css-prefix}-hand-lizard-o:before { content: @fa-var-hand-lizard-o; }\n.@{fa-css-prefix}-hand-spock-o:before { content: @fa-var-hand-spock-o; }\n.@{fa-css-prefix}-hand-pointer-o:before { content: @fa-var-hand-pointer-o; }\n.@{fa-css-prefix}-hand-peace-o:before { content: @fa-var-hand-peace-o; }\n.@{fa-css-prefix}-trademark:before { content: @fa-var-trademark; }\n.@{fa-css-prefix}-registered:before { content: @fa-var-registered; }\n.@{fa-css-prefix}-creative-commons:before { content: @fa-var-creative-commons; }\n.@{fa-css-prefix}-gg:before { content: @fa-var-gg; }\n.@{fa-css-prefix}-gg-circle:before { content: @fa-var-gg-circle; }\n.@{fa-css-prefix}-tripadvisor:before { content: @fa-var-tripadvisor; }\n.@{fa-css-prefix}-odnoklassniki:before { content: @fa-var-odnoklassniki; }\n.@{fa-css-prefix}-odnoklassniki-square:before { content: @fa-var-odnoklassniki-square; }\n.@{fa-css-prefix}-get-pocket:before { content: @fa-var-get-pocket; }\n.@{fa-css-prefix}-wikipedia-w:before { content: @fa-var-wikipedia-w; }\n.@{fa-css-prefix}-safari:before { content: @fa-var-safari; }\n.@{fa-css-prefix}-chrome:before { content: @fa-var-chrome; }\n.@{fa-css-prefix}-firefox:before { content: @fa-var-firefox; }\n.@{fa-css-prefix}-opera:before { content: @fa-var-opera; }\n.@{fa-css-prefix}-internet-explorer:before { content: @fa-var-internet-explorer; }\n.@{fa-css-prefix}-tv:before,\n.@{fa-css-prefix}-television:before { content: @fa-var-television; }\n.@{fa-css-prefix}-contao:before { content: @fa-var-contao; }\n.@{fa-css-prefix}-500px:before { content: @fa-var-500px; }\n.@{fa-css-prefix}-amazon:before { content: @fa-var-amazon; }\n.@{fa-css-prefix}-calendar-plus-o:before { content: @fa-var-calendar-plus-o; }\n.@{fa-css-prefix}-calendar-minus-o:before { content: @fa-var-calendar-minus-o; }\n.@{fa-css-prefix}-calendar-times-o:before { content: @fa-var-calendar-times-o; }\n.@{fa-css-prefix}-calendar-check-o:before { content: @fa-var-calendar-check-o; }\n.@{fa-css-prefix}-industry:before { content: @fa-var-industry; }\n.@{fa-css-prefix}-map-pin:before { content: @fa-var-map-pin; }\n.@{fa-css-prefix}-map-signs:before { content: @fa-var-map-signs; }\n.@{fa-css-prefix}-map-o:before { content: @fa-var-map-o; }\n.@{fa-css-prefix}-map:before { content: @fa-var-map; }\n.@{fa-css-prefix}-commenting:before { content: @fa-var-commenting; }\n.@{fa-css-prefix}-commenting-o:before { content: @fa-var-commenting-o; }\n.@{fa-css-prefix}-houzz:before { content: @fa-var-houzz; }\n.@{fa-css-prefix}-vimeo:before { content: @fa-var-vimeo; }\n.@{fa-css-prefix}-black-tie:before { content: @fa-var-black-tie; }\n.@{fa-css-prefix}-fonticons:before { content: @fa-var-fonticons; }\n.@{fa-css-prefix}-reddit-alien:before { content: @fa-var-reddit-alien; }\n.@{fa-css-prefix}-edge:before { content: @fa-var-edge; }\n.@{fa-css-prefix}-credit-card-alt:before { content: @fa-var-credit-card-alt; }\n.@{fa-css-prefix}-codiepie:before { content: @fa-var-codiepie; }\n.@{fa-css-prefix}-modx:before { content: @fa-var-modx; }\n.@{fa-css-prefix}-fort-awesome:before { content: @fa-var-fort-awesome; }\n.@{fa-css-prefix}-usb:before { content: @fa-var-usb; }\n.@{fa-css-prefix}-product-hunt:before { content: @fa-var-product-hunt; }\n.@{fa-css-prefix}-mixcloud:before { content: @fa-var-mixcloud; }\n.@{fa-css-prefix}-scribd:before { content: @fa-var-scribd; }\n.@{fa-css-prefix}-pause-circle:before { content: @fa-var-pause-circle; }\n.@{fa-css-prefix}-pause-circle-o:before { content: @fa-var-pause-circle-o; }\n.@{fa-css-prefix}-stop-circle:before { content: @fa-var-stop-circle; }\n.@{fa-css-prefix}-stop-circle-o:before { content: @fa-var-stop-circle-o; }\n.@{fa-css-prefix}-shopping-bag:before { content: @fa-var-shopping-bag; }\n.@{fa-css-prefix}-shopping-basket:before { content: @fa-var-shopping-basket; }\n.@{fa-css-prefix}-hashtag:before { content: @fa-var-hashtag; }\n.@{fa-css-prefix}-bluetooth:before { content: @fa-var-bluetooth; }\n.@{fa-css-prefix}-bluetooth-b:before { content: @fa-var-bluetooth-b; }\n.@{fa-css-prefix}-percent:before { content: @fa-var-percent; }\n.@{fa-css-prefix}-gitlab:before { content: @fa-var-gitlab; }\n.@{fa-css-prefix}-wpbeginner:before { content: @fa-var-wpbeginner; }\n.@{fa-css-prefix}-wpforms:before { content: @fa-var-wpforms; }\n.@{fa-css-prefix}-envira:before { content: @fa-var-envira; }\n.@{fa-css-prefix}-universal-access:before { content: @fa-var-universal-access; }\n.@{fa-css-prefix}-wheelchair-alt:before { content: @fa-var-wheelchair-alt; }\n.@{fa-css-prefix}-question-circle-o:before { content: @fa-var-question-circle-o; }\n.@{fa-css-prefix}-blind:before { content: @fa-var-blind; }\n.@{fa-css-prefix}-audio-description:before { content: @fa-var-audio-description; }\n.@{fa-css-prefix}-volume-control-phone:before { content: @fa-var-volume-control-phone; }\n.@{fa-css-prefix}-braille:before { content: @fa-var-braille; }\n.@{fa-css-prefix}-assistive-listening-systems:before { content: @fa-var-assistive-listening-systems; }\n.@{fa-css-prefix}-asl-interpreting:before,\n.@{fa-css-prefix}-american-sign-language-interpreting:before { content: @fa-var-american-sign-language-interpreting; }\n.@{fa-css-prefix}-deafness:before,\n.@{fa-css-prefix}-hard-of-hearing:before,\n.@{fa-css-prefix}-deaf:before { content: @fa-var-deaf; }\n.@{fa-css-prefix}-glide:before { content: @fa-var-glide; }\n.@{fa-css-prefix}-glide-g:before { content: @fa-var-glide-g; }\n.@{fa-css-prefix}-signing:before,\n.@{fa-css-prefix}-sign-language:before { content: @fa-var-sign-language; }\n.@{fa-css-prefix}-low-vision:before { content: @fa-var-low-vision; }\n.@{fa-css-prefix}-viadeo:before { content: @fa-var-viadeo; }\n.@{fa-css-prefix}-viadeo-square:before { content: @fa-var-viadeo-square; }\n.@{fa-css-prefix}-snapchat:before { content: @fa-var-snapchat; }\n.@{fa-css-prefix}-snapchat-ghost:before { content: @fa-var-snapchat-ghost; }\n.@{fa-css-prefix}-snapchat-square:before { content: @fa-var-snapchat-square; }\n.@{fa-css-prefix}-pied-piper:before { content: @fa-var-pied-piper; }\n.@{fa-css-prefix}-first-order:before { content: @fa-var-first-order; }\n.@{fa-css-prefix}-yoast:before { content: @fa-var-yoast; }\n.@{fa-css-prefix}-themeisle:before { content: @fa-var-themeisle; }\n.@{fa-css-prefix}-google-plus-circle:before,\n.@{fa-css-prefix}-google-plus-official:before { content: @fa-var-google-plus-official; }\n.@{fa-css-prefix}-fa:before,\n.@{fa-css-prefix}-font-awesome:before { content: @fa-var-font-awesome; }\n"
  },
  {
    "path": "app_backend/vendor/font-awesome/less/larger.less",
    "content": "// Icon Sizes\n// -------------------------\n\n/* makes the font 33% larger relative to the icon container */\n.@{fa-css-prefix}-lg {\n  font-size: (4em / 3);\n  line-height: (3em / 4);\n  vertical-align: -15%;\n}\n.@{fa-css-prefix}-2x { font-size: 2em; }\n.@{fa-css-prefix}-3x { font-size: 3em; }\n.@{fa-css-prefix}-4x { font-size: 4em; }\n.@{fa-css-prefix}-5x { font-size: 5em; }\n"
  },
  {
    "path": "app_backend/vendor/font-awesome/less/list.less",
    "content": "// List Icons\n// -------------------------\n\n.@{fa-css-prefix}-ul {\n  padding-left: 0;\n  margin-left: @fa-li-width;\n  list-style-type: none;\n  > li { position: relative; }\n}\n.@{fa-css-prefix}-li {\n  position: absolute;\n  left: -@fa-li-width;\n  width: @fa-li-width;\n  top: (2em / 14);\n  text-align: center;\n  &.@{fa-css-prefix}-lg {\n    left: (-@fa-li-width + (4em / 14));\n  }\n}\n"
  },
  {
    "path": "app_backend/vendor/font-awesome/less/mixins.less",
    "content": "// Mixins\n// --------------------------\n\n.fa-icon() {\n  display: inline-block;\n  font: normal normal normal @fa-font-size-base/@fa-line-height-base FontAwesome; // shortening font declaration\n  font-size: inherit; // can't have font-size inherit on line above, so need to override\n  text-rendering: auto; // optimizelegibility throws things off #1094\n  -webkit-font-smoothing: antialiased;\n  -moz-osx-font-smoothing: grayscale;\n\n}\n\n.fa-icon-rotate(@degrees, @rotation) {\n  -ms-filter: \"progid:DXImageTransform.Microsoft.BasicImage(rotation=@{rotation})\";\n  -webkit-transform: rotate(@degrees);\n      -ms-transform: rotate(@degrees);\n          transform: rotate(@degrees);\n}\n\n.fa-icon-flip(@horiz, @vert, @rotation) {\n  -ms-filter: \"progid:DXImageTransform.Microsoft.BasicImage(rotation=@{rotation}, mirror=1)\";\n  -webkit-transform: scale(@horiz, @vert);\n      -ms-transform: scale(@horiz, @vert);\n          transform: scale(@horiz, @vert);\n}\n\n\n// Only display content to screen readers. A la Bootstrap 4.\n//\n// See: http://a11yproject.com/posts/how-to-hide-content/\n\n.sr-only() {\n  position: absolute;\n  width: 1px;\n  height: 1px;\n  padding: 0;\n  margin: -1px;\n  overflow: hidden;\n  clip: rect(0,0,0,0);\n  border: 0;\n}\n\n// Use in conjunction with .sr-only to only display content when it's focused.\n//\n// Useful for \"Skip to main content\" links; see http://www.w3.org/TR/2013/NOTE-WCAG20-TECHS-20130905/G1\n//\n// Credit: HTML5 Boilerplate\n\n.sr-only-focusable() {\n  &:active,\n  &:focus {\n    position: static;\n    width: auto;\n    height: auto;\n    margin: 0;\n    overflow: visible;\n    clip: auto;\n  }\n}\n"
  },
  {
    "path": "app_backend/vendor/font-awesome/less/path.less",
    "content": "/* FONT PATH\n * -------------------------- */\n\n@font-face {\n  font-family: 'FontAwesome';\n  src: url('@{fa-font-path}/fontawesome-webfont.eot?v=@{fa-version}');\n  src: url('@{fa-font-path}/fontawesome-webfont.eot?#iefix&v=@{fa-version}') format('embedded-opentype'),\n    url('@{fa-font-path}/fontawesome-webfont.woff2?v=@{fa-version}') format('woff2'),\n    url('@{fa-font-path}/fontawesome-webfont.woff?v=@{fa-version}') format('woff'),\n    url('@{fa-font-path}/fontawesome-webfont.ttf?v=@{fa-version}') format('truetype'),\n    url('@{fa-font-path}/fontawesome-webfont.svg?v=@{fa-version}#fontawesomeregular') format('svg');\n  // src: url('@{fa-font-path}/FontAwesome.otf') format('opentype'); // used when developing fonts\n  font-weight: normal;\n  font-style: normal;\n}\n"
  },
  {
    "path": "app_backend/vendor/font-awesome/less/rotated-flipped.less",
    "content": "// Rotated & Flipped Icons\n// -------------------------\n\n.@{fa-css-prefix}-rotate-90  { .fa-icon-rotate(90deg, 1);  }\n.@{fa-css-prefix}-rotate-180 { .fa-icon-rotate(180deg, 2); }\n.@{fa-css-prefix}-rotate-270 { .fa-icon-rotate(270deg, 3); }\n\n.@{fa-css-prefix}-flip-horizontal { .fa-icon-flip(-1, 1, 0); }\n.@{fa-css-prefix}-flip-vertical   { .fa-icon-flip(1, -1, 2); }\n\n// Hook for IE8-9\n// -------------------------\n\n:root .@{fa-css-prefix}-rotate-90,\n:root .@{fa-css-prefix}-rotate-180,\n:root .@{fa-css-prefix}-rotate-270,\n:root .@{fa-css-prefix}-flip-horizontal,\n:root .@{fa-css-prefix}-flip-vertical {\n  filter: none;\n}\n"
  },
  {
    "path": "app_backend/vendor/font-awesome/less/screen-reader.less",
    "content": "// Screen Readers\n// -------------------------\n\n.sr-only { .sr-only(); }\n.sr-only-focusable { .sr-only-focusable(); }\n"
  },
  {
    "path": "app_backend/vendor/font-awesome/less/spinning.less",
    "content": "// Spinning Icons\n// --------------------------\n\n.@{fa-css-prefix}-spin {\n  -webkit-animation: fa-spin 2s infinite linear;\n          animation: fa-spin 2s infinite linear;\n}\n\n@-webkit-keyframes fa-spin {\n  0% {\n    -webkit-transform: rotate(0deg);\n            transform: rotate(0deg);\n  }\n  100% {\n    -webkit-transform: rotate(359deg);\n            transform: rotate(359deg);\n  }\n}\n\n@keyframes fa-spin {\n  0% {\n    -webkit-transform: rotate(0deg);\n            transform: rotate(0deg);\n  }\n  100% {\n    -webkit-transform: rotate(359deg);\n            transform: rotate(359deg);\n  }\n}\n"
  },
  {
    "path": "app_backend/vendor/font-awesome/less/stacked.less",
    "content": "// Stacked Icons\n// -------------------------\n\n.@{fa-css-prefix}-stack {\n  position: relative;\n  display: inline-block;\n  width: 2em;\n  height: 2em;\n  line-height: 2em;\n  vertical-align: middle;\n}\n.@{fa-css-prefix}-stack-1x, .@{fa-css-prefix}-stack-2x {\n  position: absolute;\n  left: 0;\n  width: 100%;\n  text-align: center;\n}\n.@{fa-css-prefix}-stack-1x { line-height: inherit; }\n.@{fa-css-prefix}-stack-2x { font-size: 2em; }\n.@{fa-css-prefix}-inverse { color: @fa-inverse; }\n"
  },
  {
    "path": "app_backend/vendor/font-awesome/less/variables.less",
    "content": "// Variables\n// --------------------------\n\n@fa-font-path:        \"../fonts\";\n@fa-font-size-base:   14px;\n@fa-line-height-base: 1;\n//@fa-font-path:        \"//netdna.bootstrapcdn.com/font-awesome/4.6.3/fonts\"; // for referencing Bootstrap CDN font files directly\n@fa-css-prefix:       fa;\n@fa-version:          \"4.6.3\";\n@fa-border-color:     #eee;\n@fa-inverse:          #fff;\n@fa-li-width:         (30em / 14);\n\n@fa-var-500px: \"\\f26e\";\n@fa-var-adjust: \"\\f042\";\n@fa-var-adn: \"\\f170\";\n@fa-var-align-center: \"\\f037\";\n@fa-var-align-justify: \"\\f039\";\n@fa-var-align-left: \"\\f036\";\n@fa-var-align-right: \"\\f038\";\n@fa-var-amazon: \"\\f270\";\n@fa-var-ambulance: \"\\f0f9\";\n@fa-var-american-sign-language-interpreting: \"\\f2a3\";\n@fa-var-anchor: \"\\f13d\";\n@fa-var-android: \"\\f17b\";\n@fa-var-angellist: \"\\f209\";\n@fa-var-angle-double-down: \"\\f103\";\n@fa-var-angle-double-left: \"\\f100\";\n@fa-var-angle-double-right: \"\\f101\";\n@fa-var-angle-double-up: \"\\f102\";\n@fa-var-angle-down: \"\\f107\";\n@fa-var-angle-left: \"\\f104\";\n@fa-var-angle-right: \"\\f105\";\n@fa-var-angle-up: \"\\f106\";\n@fa-var-apple: \"\\f179\";\n@fa-var-archive: \"\\f187\";\n@fa-var-area-chart: \"\\f1fe\";\n@fa-var-arrow-circle-down: \"\\f0ab\";\n@fa-var-arrow-circle-left: \"\\f0a8\";\n@fa-var-arrow-circle-o-down: \"\\f01a\";\n@fa-var-arrow-circle-o-left: \"\\f190\";\n@fa-var-arrow-circle-o-right: \"\\f18e\";\n@fa-var-arrow-circle-o-up: \"\\f01b\";\n@fa-var-arrow-circle-right: \"\\f0a9\";\n@fa-var-arrow-circle-up: \"\\f0aa\";\n@fa-var-arrow-down: \"\\f063\";\n@fa-var-arrow-left: \"\\f060\";\n@fa-var-arrow-right: \"\\f061\";\n@fa-var-arrow-up: \"\\f062\";\n@fa-var-arrows: \"\\f047\";\n@fa-var-arrows-alt: \"\\f0b2\";\n@fa-var-arrows-h: \"\\f07e\";\n@fa-var-arrows-v: \"\\f07d\";\n@fa-var-asl-interpreting: \"\\f2a3\";\n@fa-var-assistive-listening-systems: \"\\f2a2\";\n@fa-var-asterisk: \"\\f069\";\n@fa-var-at: \"\\f1fa\";\n@fa-var-audio-description: \"\\f29e\";\n@fa-var-automobile: \"\\f1b9\";\n@fa-var-backward: \"\\f04a\";\n@fa-var-balance-scale: \"\\f24e\";\n@fa-var-ban: \"\\f05e\";\n@fa-var-bank: \"\\f19c\";\n@fa-var-bar-chart: \"\\f080\";\n@fa-var-bar-chart-o: \"\\f080\";\n@fa-var-barcode: \"\\f02a\";\n@fa-var-bars: \"\\f0c9\";\n@fa-var-battery-0: \"\\f244\";\n@fa-var-battery-1: \"\\f243\";\n@fa-var-battery-2: \"\\f242\";\n@fa-var-battery-3: \"\\f241\";\n@fa-var-battery-4: \"\\f240\";\n@fa-var-battery-empty: \"\\f244\";\n@fa-var-battery-full: \"\\f240\";\n@fa-var-battery-half: \"\\f242\";\n@fa-var-battery-quarter: \"\\f243\";\n@fa-var-battery-three-quarters: \"\\f241\";\n@fa-var-bed: \"\\f236\";\n@fa-var-beer: \"\\f0fc\";\n@fa-var-behance: \"\\f1b4\";\n@fa-var-behance-square: \"\\f1b5\";\n@fa-var-bell: \"\\f0f3\";\n@fa-var-bell-o: \"\\f0a2\";\n@fa-var-bell-slash: \"\\f1f6\";\n@fa-var-bell-slash-o: \"\\f1f7\";\n@fa-var-bicycle: \"\\f206\";\n@fa-var-binoculars: \"\\f1e5\";\n@fa-var-birthday-cake: \"\\f1fd\";\n@fa-var-bitbucket: \"\\f171\";\n@fa-var-bitbucket-square: \"\\f172\";\n@fa-var-bitcoin: \"\\f15a\";\n@fa-var-black-tie: \"\\f27e\";\n@fa-var-blind: \"\\f29d\";\n@fa-var-bluetooth: \"\\f293\";\n@fa-var-bluetooth-b: \"\\f294\";\n@fa-var-bold: \"\\f032\";\n@fa-var-bolt: \"\\f0e7\";\n@fa-var-bomb: \"\\f1e2\";\n@fa-var-book: \"\\f02d\";\n@fa-var-bookmark: \"\\f02e\";\n@fa-var-bookmark-o: \"\\f097\";\n@fa-var-braille: \"\\f2a1\";\n@fa-var-briefcase: \"\\f0b1\";\n@fa-var-btc: \"\\f15a\";\n@fa-var-bug: \"\\f188\";\n@fa-var-building: \"\\f1ad\";\n@fa-var-building-o: \"\\f0f7\";\n@fa-var-bullhorn: \"\\f0a1\";\n@fa-var-bullseye: \"\\f140\";\n@fa-var-bus: \"\\f207\";\n@fa-var-buysellads: \"\\f20d\";\n@fa-var-cab: \"\\f1ba\";\n@fa-var-calculator: \"\\f1ec\";\n@fa-var-calendar: \"\\f073\";\n@fa-var-calendar-check-o: \"\\f274\";\n@fa-var-calendar-minus-o: \"\\f272\";\n@fa-var-calendar-o: \"\\f133\";\n@fa-var-calendar-plus-o: \"\\f271\";\n@fa-var-calendar-times-o: \"\\f273\";\n@fa-var-camera: \"\\f030\";\n@fa-var-camera-retro: \"\\f083\";\n@fa-var-car: \"\\f1b9\";\n@fa-var-caret-down: \"\\f0d7\";\n@fa-var-caret-left: \"\\f0d9\";\n@fa-var-caret-right: \"\\f0da\";\n@fa-var-caret-square-o-down: \"\\f150\";\n@fa-var-caret-square-o-left: \"\\f191\";\n@fa-var-caret-square-o-right: \"\\f152\";\n@fa-var-caret-square-o-up: \"\\f151\";\n@fa-var-caret-up: \"\\f0d8\";\n@fa-var-cart-arrow-down: \"\\f218\";\n@fa-var-cart-plus: \"\\f217\";\n@fa-var-cc: \"\\f20a\";\n@fa-var-cc-amex: \"\\f1f3\";\n@fa-var-cc-diners-club: \"\\f24c\";\n@fa-var-cc-discover: \"\\f1f2\";\n@fa-var-cc-jcb: \"\\f24b\";\n@fa-var-cc-mastercard: \"\\f1f1\";\n@fa-var-cc-paypal: \"\\f1f4\";\n@fa-var-cc-stripe: \"\\f1f5\";\n@fa-var-cc-visa: \"\\f1f0\";\n@fa-var-certificate: \"\\f0a3\";\n@fa-var-chain: \"\\f0c1\";\n@fa-var-chain-broken: \"\\f127\";\n@fa-var-check: \"\\f00c\";\n@fa-var-check-circle: \"\\f058\";\n@fa-var-check-circle-o: \"\\f05d\";\n@fa-var-check-square: \"\\f14a\";\n@fa-var-check-square-o: \"\\f046\";\n@fa-var-chevron-circle-down: \"\\f13a\";\n@fa-var-chevron-circle-left: \"\\f137\";\n@fa-var-chevron-circle-right: \"\\f138\";\n@fa-var-chevron-circle-up: \"\\f139\";\n@fa-var-chevron-down: \"\\f078\";\n@fa-var-chevron-left: \"\\f053\";\n@fa-var-chevron-right: \"\\f054\";\n@fa-var-chevron-up: \"\\f077\";\n@fa-var-child: \"\\f1ae\";\n@fa-var-chrome: \"\\f268\";\n@fa-var-circle: \"\\f111\";\n@fa-var-circle-o: \"\\f10c\";\n@fa-var-circle-o-notch: \"\\f1ce\";\n@fa-var-circle-thin: \"\\f1db\";\n@fa-var-clipboard: \"\\f0ea\";\n@fa-var-clock-o: \"\\f017\";\n@fa-var-clone: \"\\f24d\";\n@fa-var-close: \"\\f00d\";\n@fa-var-cloud: \"\\f0c2\";\n@fa-var-cloud-download: \"\\f0ed\";\n@fa-var-cloud-upload: \"\\f0ee\";\n@fa-var-cny: \"\\f157\";\n@fa-var-code: \"\\f121\";\n@fa-var-code-fork: \"\\f126\";\n@fa-var-codepen: \"\\f1cb\";\n@fa-var-codiepie: \"\\f284\";\n@fa-var-coffee: \"\\f0f4\";\n@fa-var-cog: \"\\f013\";\n@fa-var-cogs: \"\\f085\";\n@fa-var-columns: \"\\f0db\";\n@fa-var-comment: \"\\f075\";\n@fa-var-comment-o: \"\\f0e5\";\n@fa-var-commenting: \"\\f27a\";\n@fa-var-commenting-o: \"\\f27b\";\n@fa-var-comments: \"\\f086\";\n@fa-var-comments-o: \"\\f0e6\";\n@fa-var-compass: \"\\f14e\";\n@fa-var-compress: \"\\f066\";\n@fa-var-connectdevelop: \"\\f20e\";\n@fa-var-contao: \"\\f26d\";\n@fa-var-copy: \"\\f0c5\";\n@fa-var-copyright: \"\\f1f9\";\n@fa-var-creative-commons: \"\\f25e\";\n@fa-var-credit-card: \"\\f09d\";\n@fa-var-credit-card-alt: \"\\f283\";\n@fa-var-crop: \"\\f125\";\n@fa-var-crosshairs: \"\\f05b\";\n@fa-var-css3: \"\\f13c\";\n@fa-var-cube: \"\\f1b2\";\n@fa-var-cubes: \"\\f1b3\";\n@fa-var-cut: \"\\f0c4\";\n@fa-var-cutlery: \"\\f0f5\";\n@fa-var-dashboard: \"\\f0e4\";\n@fa-var-dashcube: \"\\f210\";\n@fa-var-database: \"\\f1c0\";\n@fa-var-deaf: \"\\f2a4\";\n@fa-var-deafness: \"\\f2a4\";\n@fa-var-dedent: \"\\f03b\";\n@fa-var-delicious: \"\\f1a5\";\n@fa-var-desktop: \"\\f108\";\n@fa-var-deviantart: \"\\f1bd\";\n@fa-var-diamond: \"\\f219\";\n@fa-var-digg: \"\\f1a6\";\n@fa-var-dollar: \"\\f155\";\n@fa-var-dot-circle-o: \"\\f192\";\n@fa-var-download: \"\\f019\";\n@fa-var-dribbble: \"\\f17d\";\n@fa-var-dropbox: \"\\f16b\";\n@fa-var-drupal: \"\\f1a9\";\n@fa-var-edge: \"\\f282\";\n@fa-var-edit: \"\\f044\";\n@fa-var-eject: \"\\f052\";\n@fa-var-ellipsis-h: \"\\f141\";\n@fa-var-ellipsis-v: \"\\f142\";\n@fa-var-empire: \"\\f1d1\";\n@fa-var-envelope: \"\\f0e0\";\n@fa-var-envelope-o: \"\\f003\";\n@fa-var-envelope-square: \"\\f199\";\n@fa-var-envira: \"\\f299\";\n@fa-var-eraser: \"\\f12d\";\n@fa-var-eur: \"\\f153\";\n@fa-var-euro: \"\\f153\";\n@fa-var-exchange: \"\\f0ec\";\n@fa-var-exclamation: \"\\f12a\";\n@fa-var-exclamation-circle: \"\\f06a\";\n@fa-var-exclamation-triangle: \"\\f071\";\n@fa-var-expand: \"\\f065\";\n@fa-var-expeditedssl: \"\\f23e\";\n@fa-var-external-link: \"\\f08e\";\n@fa-var-external-link-square: \"\\f14c\";\n@fa-var-eye: \"\\f06e\";\n@fa-var-eye-slash: \"\\f070\";\n@fa-var-eyedropper: \"\\f1fb\";\n@fa-var-fa: \"\\f2b4\";\n@fa-var-facebook: \"\\f09a\";\n@fa-var-facebook-f: \"\\f09a\";\n@fa-var-facebook-official: \"\\f230\";\n@fa-var-facebook-square: \"\\f082\";\n@fa-var-fast-backward: \"\\f049\";\n@fa-var-fast-forward: \"\\f050\";\n@fa-var-fax: \"\\f1ac\";\n@fa-var-feed: \"\\f09e\";\n@fa-var-female: \"\\f182\";\n@fa-var-fighter-jet: \"\\f0fb\";\n@fa-var-file: \"\\f15b\";\n@fa-var-file-archive-o: \"\\f1c6\";\n@fa-var-file-audio-o: \"\\f1c7\";\n@fa-var-file-code-o: \"\\f1c9\";\n@fa-var-file-excel-o: \"\\f1c3\";\n@fa-var-file-image-o: \"\\f1c5\";\n@fa-var-file-movie-o: \"\\f1c8\";\n@fa-var-file-o: \"\\f016\";\n@fa-var-file-pdf-o: \"\\f1c1\";\n@fa-var-file-photo-o: \"\\f1c5\";\n@fa-var-file-picture-o: \"\\f1c5\";\n@fa-var-file-powerpoint-o: \"\\f1c4\";\n@fa-var-file-sound-o: \"\\f1c7\";\n@fa-var-file-text: \"\\f15c\";\n@fa-var-file-text-o: \"\\f0f6\";\n@fa-var-file-video-o: \"\\f1c8\";\n@fa-var-file-word-o: \"\\f1c2\";\n@fa-var-file-zip-o: \"\\f1c6\";\n@fa-var-files-o: \"\\f0c5\";\n@fa-var-film: \"\\f008\";\n@fa-var-filter: \"\\f0b0\";\n@fa-var-fire: \"\\f06d\";\n@fa-var-fire-extinguisher: \"\\f134\";\n@fa-var-firefox: \"\\f269\";\n@fa-var-first-order: \"\\f2b0\";\n@fa-var-flag: \"\\f024\";\n@fa-var-flag-checkered: \"\\f11e\";\n@fa-var-flag-o: \"\\f11d\";\n@fa-var-flash: \"\\f0e7\";\n@fa-var-flask: \"\\f0c3\";\n@fa-var-flickr: \"\\f16e\";\n@fa-var-floppy-o: \"\\f0c7\";\n@fa-var-folder: \"\\f07b\";\n@fa-var-folder-o: \"\\f114\";\n@fa-var-folder-open: \"\\f07c\";\n@fa-var-folder-open-o: \"\\f115\";\n@fa-var-font: \"\\f031\";\n@fa-var-font-awesome: \"\\f2b4\";\n@fa-var-fonticons: \"\\f280\";\n@fa-var-fort-awesome: \"\\f286\";\n@fa-var-forumbee: \"\\f211\";\n@fa-var-forward: \"\\f04e\";\n@fa-var-foursquare: \"\\f180\";\n@fa-var-frown-o: \"\\f119\";\n@fa-var-futbol-o: \"\\f1e3\";\n@fa-var-gamepad: \"\\f11b\";\n@fa-var-gavel: \"\\f0e3\";\n@fa-var-gbp: \"\\f154\";\n@fa-var-ge: \"\\f1d1\";\n@fa-var-gear: \"\\f013\";\n@fa-var-gears: \"\\f085\";\n@fa-var-genderless: \"\\f22d\";\n@fa-var-get-pocket: \"\\f265\";\n@fa-var-gg: \"\\f260\";\n@fa-var-gg-circle: \"\\f261\";\n@fa-var-gift: \"\\f06b\";\n@fa-var-git: \"\\f1d3\";\n@fa-var-git-square: \"\\f1d2\";\n@fa-var-github: \"\\f09b\";\n@fa-var-github-alt: \"\\f113\";\n@fa-var-github-square: \"\\f092\";\n@fa-var-gitlab: \"\\f296\";\n@fa-var-gittip: \"\\f184\";\n@fa-var-glass: \"\\f000\";\n@fa-var-glide: \"\\f2a5\";\n@fa-var-glide-g: \"\\f2a6\";\n@fa-var-globe: \"\\f0ac\";\n@fa-var-google: \"\\f1a0\";\n@fa-var-google-plus: \"\\f0d5\";\n@fa-var-google-plus-circle: \"\\f2b3\";\n@fa-var-google-plus-official: \"\\f2b3\";\n@fa-var-google-plus-square: \"\\f0d4\";\n@fa-var-google-wallet: \"\\f1ee\";\n@fa-var-graduation-cap: \"\\f19d\";\n@fa-var-gratipay: \"\\f184\";\n@fa-var-group: \"\\f0c0\";\n@fa-var-h-square: \"\\f0fd\";\n@fa-var-hacker-news: \"\\f1d4\";\n@fa-var-hand-grab-o: \"\\f255\";\n@fa-var-hand-lizard-o: \"\\f258\";\n@fa-var-hand-o-down: \"\\f0a7\";\n@fa-var-hand-o-left: \"\\f0a5\";\n@fa-var-hand-o-right: \"\\f0a4\";\n@fa-var-hand-o-up: \"\\f0a6\";\n@fa-var-hand-paper-o: \"\\f256\";\n@fa-var-hand-peace-o: \"\\f25b\";\n@fa-var-hand-pointer-o: \"\\f25a\";\n@fa-var-hand-rock-o: \"\\f255\";\n@fa-var-hand-scissors-o: \"\\f257\";\n@fa-var-hand-spock-o: \"\\f259\";\n@fa-var-hand-stop-o: \"\\f256\";\n@fa-var-hard-of-hearing: \"\\f2a4\";\n@fa-var-hashtag: \"\\f292\";\n@fa-var-hdd-o: \"\\f0a0\";\n@fa-var-header: \"\\f1dc\";\n@fa-var-headphones: \"\\f025\";\n@fa-var-heart: \"\\f004\";\n@fa-var-heart-o: \"\\f08a\";\n@fa-var-heartbeat: \"\\f21e\";\n@fa-var-history: \"\\f1da\";\n@fa-var-home: \"\\f015\";\n@fa-var-hospital-o: \"\\f0f8\";\n@fa-var-hotel: \"\\f236\";\n@fa-var-hourglass: \"\\f254\";\n@fa-var-hourglass-1: \"\\f251\";\n@fa-var-hourglass-2: \"\\f252\";\n@fa-var-hourglass-3: \"\\f253\";\n@fa-var-hourglass-end: \"\\f253\";\n@fa-var-hourglass-half: \"\\f252\";\n@fa-var-hourglass-o: \"\\f250\";\n@fa-var-hourglass-start: \"\\f251\";\n@fa-var-houzz: \"\\f27c\";\n@fa-var-html5: \"\\f13b\";\n@fa-var-i-cursor: \"\\f246\";\n@fa-var-ils: \"\\f20b\";\n@fa-var-image: \"\\f03e\";\n@fa-var-inbox: \"\\f01c\";\n@fa-var-indent: \"\\f03c\";\n@fa-var-industry: \"\\f275\";\n@fa-var-info: \"\\f129\";\n@fa-var-info-circle: \"\\f05a\";\n@fa-var-inr: \"\\f156\";\n@fa-var-instagram: \"\\f16d\";\n@fa-var-institution: \"\\f19c\";\n@fa-var-internet-explorer: \"\\f26b\";\n@fa-var-intersex: \"\\f224\";\n@fa-var-ioxhost: \"\\f208\";\n@fa-var-italic: \"\\f033\";\n@fa-var-joomla: \"\\f1aa\";\n@fa-var-jpy: \"\\f157\";\n@fa-var-jsfiddle: \"\\f1cc\";\n@fa-var-key: \"\\f084\";\n@fa-var-keyboard-o: \"\\f11c\";\n@fa-var-krw: \"\\f159\";\n@fa-var-language: \"\\f1ab\";\n@fa-var-laptop: \"\\f109\";\n@fa-var-lastfm: \"\\f202\";\n@fa-var-lastfm-square: \"\\f203\";\n@fa-var-leaf: \"\\f06c\";\n@fa-var-leanpub: \"\\f212\";\n@fa-var-legal: \"\\f0e3\";\n@fa-var-lemon-o: \"\\f094\";\n@fa-var-level-down: \"\\f149\";\n@fa-var-level-up: \"\\f148\";\n@fa-var-life-bouy: \"\\f1cd\";\n@fa-var-life-buoy: \"\\f1cd\";\n@fa-var-life-ring: \"\\f1cd\";\n@fa-var-life-saver: \"\\f1cd\";\n@fa-var-lightbulb-o: \"\\f0eb\";\n@fa-var-line-chart: \"\\f201\";\n@fa-var-link: \"\\f0c1\";\n@fa-var-linkedin: \"\\f0e1\";\n@fa-var-linkedin-square: \"\\f08c\";\n@fa-var-linux: \"\\f17c\";\n@fa-var-list: \"\\f03a\";\n@fa-var-list-alt: \"\\f022\";\n@fa-var-list-ol: \"\\f0cb\";\n@fa-var-list-ul: \"\\f0ca\";\n@fa-var-location-arrow: \"\\f124\";\n@fa-var-lock: \"\\f023\";\n@fa-var-long-arrow-down: \"\\f175\";\n@fa-var-long-arrow-left: \"\\f177\";\n@fa-var-long-arrow-right: \"\\f178\";\n@fa-var-long-arrow-up: \"\\f176\";\n@fa-var-low-vision: \"\\f2a8\";\n@fa-var-magic: \"\\f0d0\";\n@fa-var-magnet: \"\\f076\";\n@fa-var-mail-forward: \"\\f064\";\n@fa-var-mail-reply: \"\\f112\";\n@fa-var-mail-reply-all: \"\\f122\";\n@fa-var-male: \"\\f183\";\n@fa-var-map: \"\\f279\";\n@fa-var-map-marker: \"\\f041\";\n@fa-var-map-o: \"\\f278\";\n@fa-var-map-pin: \"\\f276\";\n@fa-var-map-signs: \"\\f277\";\n@fa-var-mars: \"\\f222\";\n@fa-var-mars-double: \"\\f227\";\n@fa-var-mars-stroke: \"\\f229\";\n@fa-var-mars-stroke-h: \"\\f22b\";\n@fa-var-mars-stroke-v: \"\\f22a\";\n@fa-var-maxcdn: \"\\f136\";\n@fa-var-meanpath: \"\\f20c\";\n@fa-var-medium: \"\\f23a\";\n@fa-var-medkit: \"\\f0fa\";\n@fa-var-meh-o: \"\\f11a\";\n@fa-var-mercury: \"\\f223\";\n@fa-var-microphone: \"\\f130\";\n@fa-var-microphone-slash: \"\\f131\";\n@fa-var-minus: \"\\f068\";\n@fa-var-minus-circle: \"\\f056\";\n@fa-var-minus-square: \"\\f146\";\n@fa-var-minus-square-o: \"\\f147\";\n@fa-var-mixcloud: \"\\f289\";\n@fa-var-mobile: \"\\f10b\";\n@fa-var-mobile-phone: \"\\f10b\";\n@fa-var-modx: \"\\f285\";\n@fa-var-money: \"\\f0d6\";\n@fa-var-moon-o: \"\\f186\";\n@fa-var-mortar-board: \"\\f19d\";\n@fa-var-motorcycle: \"\\f21c\";\n@fa-var-mouse-pointer: \"\\f245\";\n@fa-var-music: \"\\f001\";\n@fa-var-navicon: \"\\f0c9\";\n@fa-var-neuter: \"\\f22c\";\n@fa-var-newspaper-o: \"\\f1ea\";\n@fa-var-object-group: \"\\f247\";\n@fa-var-object-ungroup: \"\\f248\";\n@fa-var-odnoklassniki: \"\\f263\";\n@fa-var-odnoklassniki-square: \"\\f264\";\n@fa-var-opencart: \"\\f23d\";\n@fa-var-openid: \"\\f19b\";\n@fa-var-opera: \"\\f26a\";\n@fa-var-optin-monster: \"\\f23c\";\n@fa-var-outdent: \"\\f03b\";\n@fa-var-pagelines: \"\\f18c\";\n@fa-var-paint-brush: \"\\f1fc\";\n@fa-var-paper-plane: \"\\f1d8\";\n@fa-var-paper-plane-o: \"\\f1d9\";\n@fa-var-paperclip: \"\\f0c6\";\n@fa-var-paragraph: \"\\f1dd\";\n@fa-var-paste: \"\\f0ea\";\n@fa-var-pause: \"\\f04c\";\n@fa-var-pause-circle: \"\\f28b\";\n@fa-var-pause-circle-o: \"\\f28c\";\n@fa-var-paw: \"\\f1b0\";\n@fa-var-paypal: \"\\f1ed\";\n@fa-var-pencil: \"\\f040\";\n@fa-var-pencil-square: \"\\f14b\";\n@fa-var-pencil-square-o: \"\\f044\";\n@fa-var-percent: \"\\f295\";\n@fa-var-phone: \"\\f095\";\n@fa-var-phone-square: \"\\f098\";\n@fa-var-photo: \"\\f03e\";\n@fa-var-picture-o: \"\\f03e\";\n@fa-var-pie-chart: \"\\f200\";\n@fa-var-pied-piper: \"\\f2ae\";\n@fa-var-pied-piper-alt: \"\\f1a8\";\n@fa-var-pied-piper-pp: \"\\f1a7\";\n@fa-var-pinterest: \"\\f0d2\";\n@fa-var-pinterest-p: \"\\f231\";\n@fa-var-pinterest-square: \"\\f0d3\";\n@fa-var-plane: \"\\f072\";\n@fa-var-play: \"\\f04b\";\n@fa-var-play-circle: \"\\f144\";\n@fa-var-play-circle-o: \"\\f01d\";\n@fa-var-plug: \"\\f1e6\";\n@fa-var-plus: \"\\f067\";\n@fa-var-plus-circle: \"\\f055\";\n@fa-var-plus-square: \"\\f0fe\";\n@fa-var-plus-square-o: \"\\f196\";\n@fa-var-power-off: \"\\f011\";\n@fa-var-print: \"\\f02f\";\n@fa-var-product-hunt: \"\\f288\";\n@fa-var-puzzle-piece: \"\\f12e\";\n@fa-var-qq: \"\\f1d6\";\n@fa-var-qrcode: \"\\f029\";\n@fa-var-question: \"\\f128\";\n@fa-var-question-circle: \"\\f059\";\n@fa-var-question-circle-o: \"\\f29c\";\n@fa-var-quote-left: \"\\f10d\";\n@fa-var-quote-right: \"\\f10e\";\n@fa-var-ra: \"\\f1d0\";\n@fa-var-random: \"\\f074\";\n@fa-var-rebel: \"\\f1d0\";\n@fa-var-recycle: \"\\f1b8\";\n@fa-var-reddit: \"\\f1a1\";\n@fa-var-reddit-alien: \"\\f281\";\n@fa-var-reddit-square: \"\\f1a2\";\n@fa-var-refresh: \"\\f021\";\n@fa-var-registered: \"\\f25d\";\n@fa-var-remove: \"\\f00d\";\n@fa-var-renren: \"\\f18b\";\n@fa-var-reorder: \"\\f0c9\";\n@fa-var-repeat: \"\\f01e\";\n@fa-var-reply: \"\\f112\";\n@fa-var-reply-all: \"\\f122\";\n@fa-var-resistance: \"\\f1d0\";\n@fa-var-retweet: \"\\f079\";\n@fa-var-rmb: \"\\f157\";\n@fa-var-road: \"\\f018\";\n@fa-var-rocket: \"\\f135\";\n@fa-var-rotate-left: \"\\f0e2\";\n@fa-var-rotate-right: \"\\f01e\";\n@fa-var-rouble: \"\\f158\";\n@fa-var-rss: \"\\f09e\";\n@fa-var-rss-square: \"\\f143\";\n@fa-var-rub: \"\\f158\";\n@fa-var-ruble: \"\\f158\";\n@fa-var-rupee: \"\\f156\";\n@fa-var-safari: \"\\f267\";\n@fa-var-save: \"\\f0c7\";\n@fa-var-scissors: \"\\f0c4\";\n@fa-var-scribd: \"\\f28a\";\n@fa-var-search: \"\\f002\";\n@fa-var-search-minus: \"\\f010\";\n@fa-var-search-plus: \"\\f00e\";\n@fa-var-sellsy: \"\\f213\";\n@fa-var-send: \"\\f1d8\";\n@fa-var-send-o: \"\\f1d9\";\n@fa-var-server: \"\\f233\";\n@fa-var-share: \"\\f064\";\n@fa-var-share-alt: \"\\f1e0\";\n@fa-var-share-alt-square: \"\\f1e1\";\n@fa-var-share-square: \"\\f14d\";\n@fa-var-share-square-o: \"\\f045\";\n@fa-var-shekel: \"\\f20b\";\n@fa-var-sheqel: \"\\f20b\";\n@fa-var-shield: \"\\f132\";\n@fa-var-ship: \"\\f21a\";\n@fa-var-shirtsinbulk: \"\\f214\";\n@fa-var-shopping-bag: \"\\f290\";\n@fa-var-shopping-basket: \"\\f291\";\n@fa-var-shopping-cart: \"\\f07a\";\n@fa-var-sign-in: \"\\f090\";\n@fa-var-sign-language: \"\\f2a7\";\n@fa-var-sign-out: \"\\f08b\";\n@fa-var-signal: \"\\f012\";\n@fa-var-signing: \"\\f2a7\";\n@fa-var-simplybuilt: \"\\f215\";\n@fa-var-sitemap: \"\\f0e8\";\n@fa-var-skyatlas: \"\\f216\";\n@fa-var-skype: \"\\f17e\";\n@fa-var-slack: \"\\f198\";\n@fa-var-sliders: \"\\f1de\";\n@fa-var-slideshare: \"\\f1e7\";\n@fa-var-smile-o: \"\\f118\";\n@fa-var-snapchat: \"\\f2ab\";\n@fa-var-snapchat-ghost: \"\\f2ac\";\n@fa-var-snapchat-square: \"\\f2ad\";\n@fa-var-soccer-ball-o: \"\\f1e3\";\n@fa-var-sort: \"\\f0dc\";\n@fa-var-sort-alpha-asc: \"\\f15d\";\n@fa-var-sort-alpha-desc: \"\\f15e\";\n@fa-var-sort-amount-asc: \"\\f160\";\n@fa-var-sort-amount-desc: \"\\f161\";\n@fa-var-sort-asc: \"\\f0de\";\n@fa-var-sort-desc: \"\\f0dd\";\n@fa-var-sort-down: \"\\f0dd\";\n@fa-var-sort-numeric-asc: \"\\f162\";\n@fa-var-sort-numeric-desc: \"\\f163\";\n@fa-var-sort-up: \"\\f0de\";\n@fa-var-soundcloud: \"\\f1be\";\n@fa-var-space-shuttle: \"\\f197\";\n@fa-var-spinner: \"\\f110\";\n@fa-var-spoon: \"\\f1b1\";\n@fa-var-spotify: \"\\f1bc\";\n@fa-var-square: \"\\f0c8\";\n@fa-var-square-o: \"\\f096\";\n@fa-var-stack-exchange: \"\\f18d\";\n@fa-var-stack-overflow: \"\\f16c\";\n@fa-var-star: \"\\f005\";\n@fa-var-star-half: \"\\f089\";\n@fa-var-star-half-empty: \"\\f123\";\n@fa-var-star-half-full: \"\\f123\";\n@fa-var-star-half-o: \"\\f123\";\n@fa-var-star-o: \"\\f006\";\n@fa-var-steam: \"\\f1b6\";\n@fa-var-steam-square: \"\\f1b7\";\n@fa-var-step-backward: \"\\f048\";\n@fa-var-step-forward: \"\\f051\";\n@fa-var-stethoscope: \"\\f0f1\";\n@fa-var-sticky-note: \"\\f249\";\n@fa-var-sticky-note-o: \"\\f24a\";\n@fa-var-stop: \"\\f04d\";\n@fa-var-stop-circle: \"\\f28d\";\n@fa-var-stop-circle-o: \"\\f28e\";\n@fa-var-street-view: \"\\f21d\";\n@fa-var-strikethrough: \"\\f0cc\";\n@fa-var-stumbleupon: \"\\f1a4\";\n@fa-var-stumbleupon-circle: \"\\f1a3\";\n@fa-var-subscript: \"\\f12c\";\n@fa-var-subway: \"\\f239\";\n@fa-var-suitcase: \"\\f0f2\";\n@fa-var-sun-o: \"\\f185\";\n@fa-var-superscript: \"\\f12b\";\n@fa-var-support: \"\\f1cd\";\n@fa-var-table: \"\\f0ce\";\n@fa-var-tablet: \"\\f10a\";\n@fa-var-tachometer: \"\\f0e4\";\n@fa-var-tag: \"\\f02b\";\n@fa-var-tags: \"\\f02c\";\n@fa-var-tasks: \"\\f0ae\";\n@fa-var-taxi: \"\\f1ba\";\n@fa-var-television: \"\\f26c\";\n@fa-var-tencent-weibo: \"\\f1d5\";\n@fa-var-terminal: \"\\f120\";\n@fa-var-text-height: \"\\f034\";\n@fa-var-text-width: \"\\f035\";\n@fa-var-th: \"\\f00a\";\n@fa-var-th-large: \"\\f009\";\n@fa-var-th-list: \"\\f00b\";\n@fa-var-themeisle: \"\\f2b2\";\n@fa-var-thumb-tack: \"\\f08d\";\n@fa-var-thumbs-down: \"\\f165\";\n@fa-var-thumbs-o-down: \"\\f088\";\n@fa-var-thumbs-o-up: \"\\f087\";\n@fa-var-thumbs-up: \"\\f164\";\n@fa-var-ticket: \"\\f145\";\n@fa-var-times: \"\\f00d\";\n@fa-var-times-circle: \"\\f057\";\n@fa-var-times-circle-o: \"\\f05c\";\n@fa-var-tint: \"\\f043\";\n@fa-var-toggle-down: \"\\f150\";\n@fa-var-toggle-left: \"\\f191\";\n@fa-var-toggle-off: \"\\f204\";\n@fa-var-toggle-on: \"\\f205\";\n@fa-var-toggle-right: \"\\f152\";\n@fa-var-toggle-up: \"\\f151\";\n@fa-var-trademark: \"\\f25c\";\n@fa-var-train: \"\\f238\";\n@fa-var-transgender: \"\\f224\";\n@fa-var-transgender-alt: \"\\f225\";\n@fa-var-trash: \"\\f1f8\";\n@fa-var-trash-o: \"\\f014\";\n@fa-var-tree: \"\\f1bb\";\n@fa-var-trello: \"\\f181\";\n@fa-var-tripadvisor: \"\\f262\";\n@fa-var-trophy: \"\\f091\";\n@fa-var-truck: \"\\f0d1\";\n@fa-var-try: \"\\f195\";\n@fa-var-tty: \"\\f1e4\";\n@fa-var-tumblr: \"\\f173\";\n@fa-var-tumblr-square: \"\\f174\";\n@fa-var-turkish-lira: \"\\f195\";\n@fa-var-tv: \"\\f26c\";\n@fa-var-twitch: \"\\f1e8\";\n@fa-var-twitter: \"\\f099\";\n@fa-var-twitter-square: \"\\f081\";\n@fa-var-umbrella: \"\\f0e9\";\n@fa-var-underline: \"\\f0cd\";\n@fa-var-undo: \"\\f0e2\";\n@fa-var-universal-access: \"\\f29a\";\n@fa-var-university: \"\\f19c\";\n@fa-var-unlink: \"\\f127\";\n@fa-var-unlock: \"\\f09c\";\n@fa-var-unlock-alt: \"\\f13e\";\n@fa-var-unsorted: \"\\f0dc\";\n@fa-var-upload: \"\\f093\";\n@fa-var-usb: \"\\f287\";\n@fa-var-usd: \"\\f155\";\n@fa-var-user: \"\\f007\";\n@fa-var-user-md: \"\\f0f0\";\n@fa-var-user-plus: \"\\f234\";\n@fa-var-user-secret: \"\\f21b\";\n@fa-var-user-times: \"\\f235\";\n@fa-var-users: \"\\f0c0\";\n@fa-var-venus: \"\\f221\";\n@fa-var-venus-double: \"\\f226\";\n@fa-var-venus-mars: \"\\f228\";\n@fa-var-viacoin: \"\\f237\";\n@fa-var-viadeo: \"\\f2a9\";\n@fa-var-viadeo-square: \"\\f2aa\";\n@fa-var-video-camera: \"\\f03d\";\n@fa-var-vimeo: \"\\f27d\";\n@fa-var-vimeo-square: \"\\f194\";\n@fa-var-vine: \"\\f1ca\";\n@fa-var-vk: \"\\f189\";\n@fa-var-volume-control-phone: \"\\f2a0\";\n@fa-var-volume-down: \"\\f027\";\n@fa-var-volume-off: \"\\f026\";\n@fa-var-volume-up: \"\\f028\";\n@fa-var-warning: \"\\f071\";\n@fa-var-wechat: \"\\f1d7\";\n@fa-var-weibo: \"\\f18a\";\n@fa-var-weixin: \"\\f1d7\";\n@fa-var-whatsapp: \"\\f232\";\n@fa-var-wheelchair: \"\\f193\";\n@fa-var-wheelchair-alt: \"\\f29b\";\n@fa-var-wifi: \"\\f1eb\";\n@fa-var-wikipedia-w: \"\\f266\";\n@fa-var-windows: \"\\f17a\";\n@fa-var-won: \"\\f159\";\n@fa-var-wordpress: \"\\f19a\";\n@fa-var-wpbeginner: \"\\f297\";\n@fa-var-wpforms: \"\\f298\";\n@fa-var-wrench: \"\\f0ad\";\n@fa-var-xing: \"\\f168\";\n@fa-var-xing-square: \"\\f169\";\n@fa-var-y-combinator: \"\\f23b\";\n@fa-var-y-combinator-square: \"\\f1d4\";\n@fa-var-yahoo: \"\\f19e\";\n@fa-var-yc: \"\\f23b\";\n@fa-var-yc-square: \"\\f1d4\";\n@fa-var-yelp: \"\\f1e9\";\n@fa-var-yen: \"\\f157\";\n@fa-var-yoast: \"\\f2b1\";\n@fa-var-youtube: \"\\f167\";\n@fa-var-youtube-play: \"\\f16a\";\n@fa-var-youtube-square: \"\\f166\";\n\n"
  },
  {
    "path": "app_backend/vendor/font-awesome/scss/_animated.scss",
    "content": "// Spinning Icons\n// --------------------------\n\n.#{$fa-css-prefix}-spin {\n  -webkit-animation: fa-spin 2s infinite linear;\n          animation: fa-spin 2s infinite linear;\n}\n\n.#{$fa-css-prefix}-pulse {\n  -webkit-animation: fa-spin 1s infinite steps(8);\n          animation: fa-spin 1s infinite steps(8);\n}\n\n@-webkit-keyframes fa-spin {\n  0% {\n    -webkit-transform: rotate(0deg);\n            transform: rotate(0deg);\n  }\n  100% {\n    -webkit-transform: rotate(359deg);\n            transform: rotate(359deg);\n  }\n}\n\n@keyframes fa-spin {\n  0% {\n    -webkit-transform: rotate(0deg);\n            transform: rotate(0deg);\n  }\n  100% {\n    -webkit-transform: rotate(359deg);\n            transform: rotate(359deg);\n  }\n}\n"
  },
  {
    "path": "app_backend/vendor/font-awesome/scss/_bordered-pulled.scss",
    "content": "// Bordered & Pulled\n// -------------------------\n\n.#{$fa-css-prefix}-border {\n  padding: .2em .25em .15em;\n  border: solid .08em $fa-border-color;\n  border-radius: .1em;\n}\n\n.#{$fa-css-prefix}-pull-left { float: left; }\n.#{$fa-css-prefix}-pull-right { float: right; }\n\n.#{$fa-css-prefix} {\n  &.#{$fa-css-prefix}-pull-left { margin-right: .3em; }\n  &.#{$fa-css-prefix}-pull-right { margin-left: .3em; }\n}\n\n/* Deprecated as of 4.4.0 */\n.pull-right { float: right; }\n.pull-left { float: left; }\n\n.#{$fa-css-prefix} {\n  &.pull-left { margin-right: .3em; }\n  &.pull-right { margin-left: .3em; }\n}\n"
  },
  {
    "path": "app_backend/vendor/font-awesome/scss/_core.scss",
    "content": "// Base Class Definition\n// -------------------------\n\n.#{$fa-css-prefix} {\n  display: inline-block;\n  font: normal normal normal #{$fa-font-size-base}/#{$fa-line-height-base} FontAwesome; // shortening font declaration\n  font-size: inherit; // can't have font-size inherit on line above, so need to override\n  text-rendering: auto; // optimizelegibility throws things off #1094\n  -webkit-font-smoothing: antialiased;\n  -moz-osx-font-smoothing: grayscale;\n\n}\n"
  },
  {
    "path": "app_backend/vendor/font-awesome/scss/_extras.scss",
    "content": "/* EXTRAS\n * -------------------------- */\n\n/* Stacked and layered icon */\n\n/* Animated rotating icon */\n.#{$fa-css-prefix}-spin {\n  -webkit-animation: spin 2s infinite linear;\n  -moz-animation: spin 2s infinite linear;\n  -o-animation: spin 2s infinite linear;\n  animation: spin 2s infinite linear;\n}\n\n@-moz-keyframes spin {\n  0% { -moz-transform: rotate(0deg); }\n  100% { -moz-transform: rotate(359deg); }\n}\n@-webkit-keyframes spin {\n  0% { -webkit-transform: rotate(0deg); }\n  100% { -webkit-transform: rotate(359deg); }\n}\n@-o-keyframes spin {\n  0% { -o-transform: rotate(0deg); }\n  100% { -o-transform: rotate(359deg); }\n}\n@-ms-keyframes spin {\n  0% { -ms-transform: rotate(0deg); }\n  100% { -ms-transform: rotate(359deg); }\n}\n@keyframes spin {\n  0% { transform: rotate(0deg); }\n  100% { transform: rotate(359deg); }\n}\n\n\n// Icon rotations & flipping\n// -------------------------\n\n.#{$fa-css-prefix}-rotate-90  { @include fa-icon-rotate(90deg, 1);  }\n.#{$fa-css-prefix}-rotate-180 { @include fa-icon-rotate(180deg, 2); }\n.#{$fa-css-prefix}-rotate-270 { @include fa-icon-rotate(270deg, 3); }\n\n.#{$fa-css-prefix}-flip-horizontal { @include fa-icon-flip(-1, 1, 0); }\n.#{$fa-css-prefix}-flip-vertical   { @include fa-icon-flip(1, -1, 2); }\n"
  },
  {
    "path": "app_backend/vendor/font-awesome/scss/_fixed-width.scss",
    "content": "// Fixed Width Icons\n// -------------------------\n.#{$fa-css-prefix}-fw {\n  width: (18em / 14);\n  text-align: center;\n}\n"
  },
  {
    "path": "app_backend/vendor/font-awesome/scss/_icons.scss",
    "content": "/* Font Awesome uses the Unicode Private Use Area (PUA) to ensure screen\n   readers do not read off random characters that represent icons */\n\n.#{$fa-css-prefix}-glass:before { content: $fa-var-glass; }\n.#{$fa-css-prefix}-music:before { content: $fa-var-music; }\n.#{$fa-css-prefix}-search:before { content: $fa-var-search; }\n.#{$fa-css-prefix}-envelope-o:before { content: $fa-var-envelope-o; }\n.#{$fa-css-prefix}-heart:before { content: $fa-var-heart; }\n.#{$fa-css-prefix}-star:before { content: $fa-var-star; }\n.#{$fa-css-prefix}-star-o:before { content: $fa-var-star-o; }\n.#{$fa-css-prefix}-user:before { content: $fa-var-user; }\n.#{$fa-css-prefix}-film:before { content: $fa-var-film; }\n.#{$fa-css-prefix}-th-large:before { content: $fa-var-th-large; }\n.#{$fa-css-prefix}-th:before { content: $fa-var-th; }\n.#{$fa-css-prefix}-th-list:before { content: $fa-var-th-list; }\n.#{$fa-css-prefix}-check:before { content: $fa-var-check; }\n.#{$fa-css-prefix}-remove:before,\n.#{$fa-css-prefix}-close:before,\n.#{$fa-css-prefix}-times:before { content: $fa-var-times; }\n.#{$fa-css-prefix}-search-plus:before { content: $fa-var-search-plus; }\n.#{$fa-css-prefix}-search-minus:before { content: $fa-var-search-minus; }\n.#{$fa-css-prefix}-power-off:before { content: $fa-var-power-off; }\n.#{$fa-css-prefix}-signal:before { content: $fa-var-signal; }\n.#{$fa-css-prefix}-gear:before,\n.#{$fa-css-prefix}-cog:before { content: $fa-var-cog; }\n.#{$fa-css-prefix}-trash-o:before { content: $fa-var-trash-o; }\n.#{$fa-css-prefix}-home:before { content: $fa-var-home; }\n.#{$fa-css-prefix}-file-o:before { content: $fa-var-file-o; }\n.#{$fa-css-prefix}-clock-o:before { content: $fa-var-clock-o; }\n.#{$fa-css-prefix}-road:before { content: $fa-var-road; }\n.#{$fa-css-prefix}-download:before { content: $fa-var-download; }\n.#{$fa-css-prefix}-arrow-circle-o-down:before { content: $fa-var-arrow-circle-o-down; }\n.#{$fa-css-prefix}-arrow-circle-o-up:before { content: $fa-var-arrow-circle-o-up; }\n.#{$fa-css-prefix}-inbox:before { content: $fa-var-inbox; }\n.#{$fa-css-prefix}-play-circle-o:before { content: $fa-var-play-circle-o; }\n.#{$fa-css-prefix}-rotate-right:before,\n.#{$fa-css-prefix}-repeat:before { content: $fa-var-repeat; }\n.#{$fa-css-prefix}-refresh:before { content: $fa-var-refresh; }\n.#{$fa-css-prefix}-list-alt:before { content: $fa-var-list-alt; }\n.#{$fa-css-prefix}-lock:before { content: $fa-var-lock; }\n.#{$fa-css-prefix}-flag:before { content: $fa-var-flag; }\n.#{$fa-css-prefix}-headphones:before { content: $fa-var-headphones; }\n.#{$fa-css-prefix}-volume-off:before { content: $fa-var-volume-off; }\n.#{$fa-css-prefix}-volume-down:before { content: $fa-var-volume-down; }\n.#{$fa-css-prefix}-volume-up:before { content: $fa-var-volume-up; }\n.#{$fa-css-prefix}-qrcode:before { content: $fa-var-qrcode; }\n.#{$fa-css-prefix}-barcode:before { content: $fa-var-barcode; }\n.#{$fa-css-prefix}-tag:before { content: $fa-var-tag; }\n.#{$fa-css-prefix}-tags:before { content: $fa-var-tags; }\n.#{$fa-css-prefix}-book:before { content: $fa-var-book; }\n.#{$fa-css-prefix}-bookmark:before { content: $fa-var-bookmark; }\n.#{$fa-css-prefix}-print:before { content: $fa-var-print; }\n.#{$fa-css-prefix}-camera:before { content: $fa-var-camera; }\n.#{$fa-css-prefix}-font:before { content: $fa-var-font; }\n.#{$fa-css-prefix}-bold:before { content: $fa-var-bold; }\n.#{$fa-css-prefix}-italic:before { content: $fa-var-italic; }\n.#{$fa-css-prefix}-text-height:before { content: $fa-var-text-height; }\n.#{$fa-css-prefix}-text-width:before { content: $fa-var-text-width; }\n.#{$fa-css-prefix}-align-left:before { content: $fa-var-align-left; }\n.#{$fa-css-prefix}-align-center:before { content: $fa-var-align-center; }\n.#{$fa-css-prefix}-align-right:before { content: $fa-var-align-right; }\n.#{$fa-css-prefix}-align-justify:before { content: $fa-var-align-justify; }\n.#{$fa-css-prefix}-list:before { content: $fa-var-list; }\n.#{$fa-css-prefix}-dedent:before,\n.#{$fa-css-prefix}-outdent:before { content: $fa-var-outdent; }\n.#{$fa-css-prefix}-indent:before { content: $fa-var-indent; }\n.#{$fa-css-prefix}-video-camera:before { content: $fa-var-video-camera; }\n.#{$fa-css-prefix}-photo:before,\n.#{$fa-css-prefix}-image:before,\n.#{$fa-css-prefix}-picture-o:before { content: $fa-var-picture-o; }\n.#{$fa-css-prefix}-pencil:before { content: $fa-var-pencil; }\n.#{$fa-css-prefix}-map-marker:before { content: $fa-var-map-marker; }\n.#{$fa-css-prefix}-adjust:before { content: $fa-var-adjust; }\n.#{$fa-css-prefix}-tint:before { content: $fa-var-tint; }\n.#{$fa-css-prefix}-edit:before,\n.#{$fa-css-prefix}-pencil-square-o:before { content: $fa-var-pencil-square-o; }\n.#{$fa-css-prefix}-share-square-o:before { content: $fa-var-share-square-o; }\n.#{$fa-css-prefix}-check-square-o:before { content: $fa-var-check-square-o; }\n.#{$fa-css-prefix}-arrows:before { content: $fa-var-arrows; }\n.#{$fa-css-prefix}-step-backward:before { content: $fa-var-step-backward; }\n.#{$fa-css-prefix}-fast-backward:before { content: $fa-var-fast-backward; }\n.#{$fa-css-prefix}-backward:before { content: $fa-var-backward; }\n.#{$fa-css-prefix}-play:before { content: $fa-var-play; }\n.#{$fa-css-prefix}-pause:before { content: $fa-var-pause; }\n.#{$fa-css-prefix}-stop:before { content: $fa-var-stop; }\n.#{$fa-css-prefix}-forward:before { content: $fa-var-forward; }\n.#{$fa-css-prefix}-fast-forward:before { content: $fa-var-fast-forward; }\n.#{$fa-css-prefix}-step-forward:before { content: $fa-var-step-forward; }\n.#{$fa-css-prefix}-eject:before { content: $fa-var-eject; }\n.#{$fa-css-prefix}-chevron-left:before { content: $fa-var-chevron-left; }\n.#{$fa-css-prefix}-chevron-right:before { content: $fa-var-chevron-right; }\n.#{$fa-css-prefix}-plus-circle:before { content: $fa-var-plus-circle; }\n.#{$fa-css-prefix}-minus-circle:before { content: $fa-var-minus-circle; }\n.#{$fa-css-prefix}-times-circle:before { content: $fa-var-times-circle; }\n.#{$fa-css-prefix}-check-circle:before { content: $fa-var-check-circle; }\n.#{$fa-css-prefix}-question-circle:before { content: $fa-var-question-circle; }\n.#{$fa-css-prefix}-info-circle:before { content: $fa-var-info-circle; }\n.#{$fa-css-prefix}-crosshairs:before { content: $fa-var-crosshairs; }\n.#{$fa-css-prefix}-times-circle-o:before { content: $fa-var-times-circle-o; }\n.#{$fa-css-prefix}-check-circle-o:before { content: $fa-var-check-circle-o; }\n.#{$fa-css-prefix}-ban:before { content: $fa-var-ban; }\n.#{$fa-css-prefix}-arrow-left:before { content: $fa-var-arrow-left; }\n.#{$fa-css-prefix}-arrow-right:before { content: $fa-var-arrow-right; }\n.#{$fa-css-prefix}-arrow-up:before { content: $fa-var-arrow-up; }\n.#{$fa-css-prefix}-arrow-down:before { content: $fa-var-arrow-down; }\n.#{$fa-css-prefix}-mail-forward:before,\n.#{$fa-css-prefix}-share:before { content: $fa-var-share; }\n.#{$fa-css-prefix}-expand:before { content: $fa-var-expand; }\n.#{$fa-css-prefix}-compress:before { content: $fa-var-compress; }\n.#{$fa-css-prefix}-plus:before { content: $fa-var-plus; }\n.#{$fa-css-prefix}-minus:before { content: $fa-var-minus; }\n.#{$fa-css-prefix}-asterisk:before { content: $fa-var-asterisk; }\n.#{$fa-css-prefix}-exclamation-circle:before { content: $fa-var-exclamation-circle; }\n.#{$fa-css-prefix}-gift:before { content: $fa-var-gift; }\n.#{$fa-css-prefix}-leaf:before { content: $fa-var-leaf; }\n.#{$fa-css-prefix}-fire:before { content: $fa-var-fire; }\n.#{$fa-css-prefix}-eye:before { content: $fa-var-eye; }\n.#{$fa-css-prefix}-eye-slash:before { content: $fa-var-eye-slash; }\n.#{$fa-css-prefix}-warning:before,\n.#{$fa-css-prefix}-exclamation-triangle:before { content: $fa-var-exclamation-triangle; }\n.#{$fa-css-prefix}-plane:before { content: $fa-var-plane; }\n.#{$fa-css-prefix}-calendar:before { content: $fa-var-calendar; }\n.#{$fa-css-prefix}-random:before { content: $fa-var-random; }\n.#{$fa-css-prefix}-comment:before { content: $fa-var-comment; }\n.#{$fa-css-prefix}-magnet:before { content: $fa-var-magnet; }\n.#{$fa-css-prefix}-chevron-up:before { content: $fa-var-chevron-up; }\n.#{$fa-css-prefix}-chevron-down:before { content: $fa-var-chevron-down; }\n.#{$fa-css-prefix}-retweet:before { content: $fa-var-retweet; }\n.#{$fa-css-prefix}-shopping-cart:before { content: $fa-var-shopping-cart; }\n.#{$fa-css-prefix}-folder:before { content: $fa-var-folder; }\n.#{$fa-css-prefix}-folder-open:before { content: $fa-var-folder-open; }\n.#{$fa-css-prefix}-arrows-v:before { content: $fa-var-arrows-v; }\n.#{$fa-css-prefix}-arrows-h:before { content: $fa-var-arrows-h; }\n.#{$fa-css-prefix}-bar-chart-o:before,\n.#{$fa-css-prefix}-bar-chart:before { content: $fa-var-bar-chart; }\n.#{$fa-css-prefix}-twitter-square:before { content: $fa-var-twitter-square; }\n.#{$fa-css-prefix}-facebook-square:before { content: $fa-var-facebook-square; }\n.#{$fa-css-prefix}-camera-retro:before { content: $fa-var-camera-retro; }\n.#{$fa-css-prefix}-key:before { content: $fa-var-key; }\n.#{$fa-css-prefix}-gears:before,\n.#{$fa-css-prefix}-cogs:before { content: $fa-var-cogs; }\n.#{$fa-css-prefix}-comments:before { content: $fa-var-comments; }\n.#{$fa-css-prefix}-thumbs-o-up:before { content: $fa-var-thumbs-o-up; }\n.#{$fa-css-prefix}-thumbs-o-down:before { content: $fa-var-thumbs-o-down; }\n.#{$fa-css-prefix}-star-half:before { content: $fa-var-star-half; }\n.#{$fa-css-prefix}-heart-o:before { content: $fa-var-heart-o; }\n.#{$fa-css-prefix}-sign-out:before { content: $fa-var-sign-out; }\n.#{$fa-css-prefix}-linkedin-square:before { content: $fa-var-linkedin-square; }\n.#{$fa-css-prefix}-thumb-tack:before { content: $fa-var-thumb-tack; }\n.#{$fa-css-prefix}-external-link:before { content: $fa-var-external-link; }\n.#{$fa-css-prefix}-sign-in:before { content: $fa-var-sign-in; }\n.#{$fa-css-prefix}-trophy:before { content: $fa-var-trophy; }\n.#{$fa-css-prefix}-github-square:before { content: $fa-var-github-square; }\n.#{$fa-css-prefix}-upload:before { content: $fa-var-upload; }\n.#{$fa-css-prefix}-lemon-o:before { content: $fa-var-lemon-o; }\n.#{$fa-css-prefix}-phone:before { content: $fa-var-phone; }\n.#{$fa-css-prefix}-square-o:before { content: $fa-var-square-o; }\n.#{$fa-css-prefix}-bookmark-o:before { content: $fa-var-bookmark-o; }\n.#{$fa-css-prefix}-phone-square:before { content: $fa-var-phone-square; }\n.#{$fa-css-prefix}-twitter:before { content: $fa-var-twitter; }\n.#{$fa-css-prefix}-facebook-f:before,\n.#{$fa-css-prefix}-facebook:before { content: $fa-var-facebook; }\n.#{$fa-css-prefix}-github:before { content: $fa-var-github; }\n.#{$fa-css-prefix}-unlock:before { content: $fa-var-unlock; }\n.#{$fa-css-prefix}-credit-card:before { content: $fa-var-credit-card; }\n.#{$fa-css-prefix}-feed:before,\n.#{$fa-css-prefix}-rss:before { content: $fa-var-rss; }\n.#{$fa-css-prefix}-hdd-o:before { content: $fa-var-hdd-o; }\n.#{$fa-css-prefix}-bullhorn:before { content: $fa-var-bullhorn; }\n.#{$fa-css-prefix}-bell:before { content: $fa-var-bell; }\n.#{$fa-css-prefix}-certificate:before { content: $fa-var-certificate; }\n.#{$fa-css-prefix}-hand-o-right:before { content: $fa-var-hand-o-right; }\n.#{$fa-css-prefix}-hand-o-left:before { content: $fa-var-hand-o-left; }\n.#{$fa-css-prefix}-hand-o-up:before { content: $fa-var-hand-o-up; }\n.#{$fa-css-prefix}-hand-o-down:before { content: $fa-var-hand-o-down; }\n.#{$fa-css-prefix}-arrow-circle-left:before { content: $fa-var-arrow-circle-left; }\n.#{$fa-css-prefix}-arrow-circle-right:before { content: $fa-var-arrow-circle-right; }\n.#{$fa-css-prefix}-arrow-circle-up:before { content: $fa-var-arrow-circle-up; }\n.#{$fa-css-prefix}-arrow-circle-down:before { content: $fa-var-arrow-circle-down; }\n.#{$fa-css-prefix}-globe:before { content: $fa-var-globe; }\n.#{$fa-css-prefix}-wrench:before { content: $fa-var-wrench; }\n.#{$fa-css-prefix}-tasks:before { content: $fa-var-tasks; }\n.#{$fa-css-prefix}-filter:before { content: $fa-var-filter; }\n.#{$fa-css-prefix}-briefcase:before { content: $fa-var-briefcase; }\n.#{$fa-css-prefix}-arrows-alt:before { content: $fa-var-arrows-alt; }\n.#{$fa-css-prefix}-group:before,\n.#{$fa-css-prefix}-users:before { content: $fa-var-users; }\n.#{$fa-css-prefix}-chain:before,\n.#{$fa-css-prefix}-link:before { content: $fa-var-link; }\n.#{$fa-css-prefix}-cloud:before { content: $fa-var-cloud; }\n.#{$fa-css-prefix}-flask:before { content: $fa-var-flask; }\n.#{$fa-css-prefix}-cut:before,\n.#{$fa-css-prefix}-scissors:before { content: $fa-var-scissors; }\n.#{$fa-css-prefix}-copy:before,\n.#{$fa-css-prefix}-files-o:before { content: $fa-var-files-o; }\n.#{$fa-css-prefix}-paperclip:before { content: $fa-var-paperclip; }\n.#{$fa-css-prefix}-save:before,\n.#{$fa-css-prefix}-floppy-o:before { content: $fa-var-floppy-o; }\n.#{$fa-css-prefix}-square:before { content: $fa-var-square; }\n.#{$fa-css-prefix}-navicon:before,\n.#{$fa-css-prefix}-reorder:before,\n.#{$fa-css-prefix}-bars:before { content: $fa-var-bars; }\n.#{$fa-css-prefix}-list-ul:before { content: $fa-var-list-ul; }\n.#{$fa-css-prefix}-list-ol:before { content: $fa-var-list-ol; }\n.#{$fa-css-prefix}-strikethrough:before { content: $fa-var-strikethrough; }\n.#{$fa-css-prefix}-underline:before { content: $fa-var-underline; }\n.#{$fa-css-prefix}-table:before { content: $fa-var-table; }\n.#{$fa-css-prefix}-magic:before { content: $fa-var-magic; }\n.#{$fa-css-prefix}-truck:before { content: $fa-var-truck; }\n.#{$fa-css-prefix}-pinterest:before { content: $fa-var-pinterest; }\n.#{$fa-css-prefix}-pinterest-square:before { content: $fa-var-pinterest-square; }\n.#{$fa-css-prefix}-google-plus-square:before { content: $fa-var-google-plus-square; }\n.#{$fa-css-prefix}-google-plus:before { content: $fa-var-google-plus; }\n.#{$fa-css-prefix}-money:before { content: $fa-var-money; }\n.#{$fa-css-prefix}-caret-down:before { content: $fa-var-caret-down; }\n.#{$fa-css-prefix}-caret-up:before { content: $fa-var-caret-up; }\n.#{$fa-css-prefix}-caret-left:before { content: $fa-var-caret-left; }\n.#{$fa-css-prefix}-caret-right:before { content: $fa-var-caret-right; }\n.#{$fa-css-prefix}-columns:before { content: $fa-var-columns; }\n.#{$fa-css-prefix}-unsorted:before,\n.#{$fa-css-prefix}-sort:before { content: $fa-var-sort; }\n.#{$fa-css-prefix}-sort-down:before,\n.#{$fa-css-prefix}-sort-desc:before { content: $fa-var-sort-desc; }\n.#{$fa-css-prefix}-sort-up:before,\n.#{$fa-css-prefix}-sort-asc:before { content: $fa-var-sort-asc; }\n.#{$fa-css-prefix}-envelope:before { content: $fa-var-envelope; }\n.#{$fa-css-prefix}-linkedin:before { content: $fa-var-linkedin; }\n.#{$fa-css-prefix}-rotate-left:before,\n.#{$fa-css-prefix}-undo:before { content: $fa-var-undo; }\n.#{$fa-css-prefix}-legal:before,\n.#{$fa-css-prefix}-gavel:before { content: $fa-var-gavel; }\n.#{$fa-css-prefix}-dashboard:before,\n.#{$fa-css-prefix}-tachometer:before { content: $fa-var-tachometer; }\n.#{$fa-css-prefix}-comment-o:before { content: $fa-var-comment-o; }\n.#{$fa-css-prefix}-comments-o:before { content: $fa-var-comments-o; }\n.#{$fa-css-prefix}-flash:before,\n.#{$fa-css-prefix}-bolt:before { content: $fa-var-bolt; }\n.#{$fa-css-prefix}-sitemap:before { content: $fa-var-sitemap; }\n.#{$fa-css-prefix}-umbrella:before { content: $fa-var-umbrella; }\n.#{$fa-css-prefix}-paste:before,\n.#{$fa-css-prefix}-clipboard:before { content: $fa-var-clipboard; }\n.#{$fa-css-prefix}-lightbulb-o:before { content: $fa-var-lightbulb-o; }\n.#{$fa-css-prefix}-exchange:before { content: $fa-var-exchange; }\n.#{$fa-css-prefix}-cloud-download:before { content: $fa-var-cloud-download; }\n.#{$fa-css-prefix}-cloud-upload:before { content: $fa-var-cloud-upload; }\n.#{$fa-css-prefix}-user-md:before { content: $fa-var-user-md; }\n.#{$fa-css-prefix}-stethoscope:before { content: $fa-var-stethoscope; }\n.#{$fa-css-prefix}-suitcase:before { content: $fa-var-suitcase; }\n.#{$fa-css-prefix}-bell-o:before { content: $fa-var-bell-o; }\n.#{$fa-css-prefix}-coffee:before { content: $fa-var-coffee; }\n.#{$fa-css-prefix}-cutlery:before { content: $fa-var-cutlery; }\n.#{$fa-css-prefix}-file-text-o:before { content: $fa-var-file-text-o; }\n.#{$fa-css-prefix}-building-o:before { content: $fa-var-building-o; }\n.#{$fa-css-prefix}-hospital-o:before { content: $fa-var-hospital-o; }\n.#{$fa-css-prefix}-ambulance:before { content: $fa-var-ambulance; }\n.#{$fa-css-prefix}-medkit:before { content: $fa-var-medkit; }\n.#{$fa-css-prefix}-fighter-jet:before { content: $fa-var-fighter-jet; }\n.#{$fa-css-prefix}-beer:before { content: $fa-var-beer; }\n.#{$fa-css-prefix}-h-square:before { content: $fa-var-h-square; }\n.#{$fa-css-prefix}-plus-square:before { content: $fa-var-plus-square; }\n.#{$fa-css-prefix}-angle-double-left:before { content: $fa-var-angle-double-left; }\n.#{$fa-css-prefix}-angle-double-right:before { content: $fa-var-angle-double-right; }\n.#{$fa-css-prefix}-angle-double-up:before { content: $fa-var-angle-double-up; }\n.#{$fa-css-prefix}-angle-double-down:before { content: $fa-var-angle-double-down; }\n.#{$fa-css-prefix}-angle-left:before { content: $fa-var-angle-left; }\n.#{$fa-css-prefix}-angle-right:before { content: $fa-var-angle-right; }\n.#{$fa-css-prefix}-angle-up:before { content: $fa-var-angle-up; }\n.#{$fa-css-prefix}-angle-down:before { content: $fa-var-angle-down; }\n.#{$fa-css-prefix}-desktop:before { content: $fa-var-desktop; }\n.#{$fa-css-prefix}-laptop:before { content: $fa-var-laptop; }\n.#{$fa-css-prefix}-tablet:before { content: $fa-var-tablet; }\n.#{$fa-css-prefix}-mobile-phone:before,\n.#{$fa-css-prefix}-mobile:before { content: $fa-var-mobile; }\n.#{$fa-css-prefix}-circle-o:before { content: $fa-var-circle-o; }\n.#{$fa-css-prefix}-quote-left:before { content: $fa-var-quote-left; }\n.#{$fa-css-prefix}-quote-right:before { content: $fa-var-quote-right; }\n.#{$fa-css-prefix}-spinner:before { content: $fa-var-spinner; }\n.#{$fa-css-prefix}-circle:before { content: $fa-var-circle; }\n.#{$fa-css-prefix}-mail-reply:before,\n.#{$fa-css-prefix}-reply:before { content: $fa-var-reply; }\n.#{$fa-css-prefix}-github-alt:before { content: $fa-var-github-alt; }\n.#{$fa-css-prefix}-folder-o:before { content: $fa-var-folder-o; }\n.#{$fa-css-prefix}-folder-open-o:before { content: $fa-var-folder-open-o; }\n.#{$fa-css-prefix}-smile-o:before { content: $fa-var-smile-o; }\n.#{$fa-css-prefix}-frown-o:before { content: $fa-var-frown-o; }\n.#{$fa-css-prefix}-meh-o:before { content: $fa-var-meh-o; }\n.#{$fa-css-prefix}-gamepad:before { content: $fa-var-gamepad; }\n.#{$fa-css-prefix}-keyboard-o:before { content: $fa-var-keyboard-o; }\n.#{$fa-css-prefix}-flag-o:before { content: $fa-var-flag-o; }\n.#{$fa-css-prefix}-flag-checkered:before { content: $fa-var-flag-checkered; }\n.#{$fa-css-prefix}-terminal:before { content: $fa-var-terminal; }\n.#{$fa-css-prefix}-code:before { content: $fa-var-code; }\n.#{$fa-css-prefix}-mail-reply-all:before,\n.#{$fa-css-prefix}-reply-all:before { content: $fa-var-reply-all; }\n.#{$fa-css-prefix}-star-half-empty:before,\n.#{$fa-css-prefix}-star-half-full:before,\n.#{$fa-css-prefix}-star-half-o:before { content: $fa-var-star-half-o; }\n.#{$fa-css-prefix}-location-arrow:before { content: $fa-var-location-arrow; }\n.#{$fa-css-prefix}-crop:before { content: $fa-var-crop; }\n.#{$fa-css-prefix}-code-fork:before { content: $fa-var-code-fork; }\n.#{$fa-css-prefix}-unlink:before,\n.#{$fa-css-prefix}-chain-broken:before { content: $fa-var-chain-broken; }\n.#{$fa-css-prefix}-question:before { content: $fa-var-question; }\n.#{$fa-css-prefix}-info:before { content: $fa-var-info; }\n.#{$fa-css-prefix}-exclamation:before { content: $fa-var-exclamation; }\n.#{$fa-css-prefix}-superscript:before { content: $fa-var-superscript; }\n.#{$fa-css-prefix}-subscript:before { content: $fa-var-subscript; }\n.#{$fa-css-prefix}-eraser:before { content: $fa-var-eraser; }\n.#{$fa-css-prefix}-puzzle-piece:before { content: $fa-var-puzzle-piece; }\n.#{$fa-css-prefix}-microphone:before { content: $fa-var-microphone; }\n.#{$fa-css-prefix}-microphone-slash:before { content: $fa-var-microphone-slash; }\n.#{$fa-css-prefix}-shield:before { content: $fa-var-shield; }\n.#{$fa-css-prefix}-calendar-o:before { content: $fa-var-calendar-o; }\n.#{$fa-css-prefix}-fire-extinguisher:before { content: $fa-var-fire-extinguisher; }\n.#{$fa-css-prefix}-rocket:before { content: $fa-var-rocket; }\n.#{$fa-css-prefix}-maxcdn:before { content: $fa-var-maxcdn; }\n.#{$fa-css-prefix}-chevron-circle-left:before { content: $fa-var-chevron-circle-left; }\n.#{$fa-css-prefix}-chevron-circle-right:before { content: $fa-var-chevron-circle-right; }\n.#{$fa-css-prefix}-chevron-circle-up:before { content: $fa-var-chevron-circle-up; }\n.#{$fa-css-prefix}-chevron-circle-down:before { content: $fa-var-chevron-circle-down; }\n.#{$fa-css-prefix}-html5:before { content: $fa-var-html5; }\n.#{$fa-css-prefix}-css3:before { content: $fa-var-css3; }\n.#{$fa-css-prefix}-anchor:before { content: $fa-var-anchor; }\n.#{$fa-css-prefix}-unlock-alt:before { content: $fa-var-unlock-alt; }\n.#{$fa-css-prefix}-bullseye:before { content: $fa-var-bullseye; }\n.#{$fa-css-prefix}-ellipsis-h:before { content: $fa-var-ellipsis-h; }\n.#{$fa-css-prefix}-ellipsis-v:before { content: $fa-var-ellipsis-v; }\n.#{$fa-css-prefix}-rss-square:before { content: $fa-var-rss-square; }\n.#{$fa-css-prefix}-play-circle:before { content: $fa-var-play-circle; }\n.#{$fa-css-prefix}-ticket:before { content: $fa-var-ticket; }\n.#{$fa-css-prefix}-minus-square:before { content: $fa-var-minus-square; }\n.#{$fa-css-prefix}-minus-square-o:before { content: $fa-var-minus-square-o; }\n.#{$fa-css-prefix}-level-up:before { content: $fa-var-level-up; }\n.#{$fa-css-prefix}-level-down:before { content: $fa-var-level-down; }\n.#{$fa-css-prefix}-check-square:before { content: $fa-var-check-square; }\n.#{$fa-css-prefix}-pencil-square:before { content: $fa-var-pencil-square; }\n.#{$fa-css-prefix}-external-link-square:before { content: $fa-var-external-link-square; }\n.#{$fa-css-prefix}-share-square:before { content: $fa-var-share-square; }\n.#{$fa-css-prefix}-compass:before { content: $fa-var-compass; }\n.#{$fa-css-prefix}-toggle-down:before,\n.#{$fa-css-prefix}-caret-square-o-down:before { content: $fa-var-caret-square-o-down; }\n.#{$fa-css-prefix}-toggle-up:before,\n.#{$fa-css-prefix}-caret-square-o-up:before { content: $fa-var-caret-square-o-up; }\n.#{$fa-css-prefix}-toggle-right:before,\n.#{$fa-css-prefix}-caret-square-o-right:before { content: $fa-var-caret-square-o-right; }\n.#{$fa-css-prefix}-euro:before,\n.#{$fa-css-prefix}-eur:before { content: $fa-var-eur; }\n.#{$fa-css-prefix}-gbp:before { content: $fa-var-gbp; }\n.#{$fa-css-prefix}-dollar:before,\n.#{$fa-css-prefix}-usd:before { content: $fa-var-usd; }\n.#{$fa-css-prefix}-rupee:before,\n.#{$fa-css-prefix}-inr:before { content: $fa-var-inr; }\n.#{$fa-css-prefix}-cny:before,\n.#{$fa-css-prefix}-rmb:before,\n.#{$fa-css-prefix}-yen:before,\n.#{$fa-css-prefix}-jpy:before { content: $fa-var-jpy; }\n.#{$fa-css-prefix}-ruble:before,\n.#{$fa-css-prefix}-rouble:before,\n.#{$fa-css-prefix}-rub:before { content: $fa-var-rub; }\n.#{$fa-css-prefix}-won:before,\n.#{$fa-css-prefix}-krw:before { content: $fa-var-krw; }\n.#{$fa-css-prefix}-bitcoin:before,\n.#{$fa-css-prefix}-btc:before { content: $fa-var-btc; }\n.#{$fa-css-prefix}-file:before { content: $fa-var-file; }\n.#{$fa-css-prefix}-file-text:before { content: $fa-var-file-text; }\n.#{$fa-css-prefix}-sort-alpha-asc:before { content: $fa-var-sort-alpha-asc; }\n.#{$fa-css-prefix}-sort-alpha-desc:before { content: $fa-var-sort-alpha-desc; }\n.#{$fa-css-prefix}-sort-amount-asc:before { content: $fa-var-sort-amount-asc; }\n.#{$fa-css-prefix}-sort-amount-desc:before { content: $fa-var-sort-amount-desc; }\n.#{$fa-css-prefix}-sort-numeric-asc:before { content: $fa-var-sort-numeric-asc; }\n.#{$fa-css-prefix}-sort-numeric-desc:before { content: $fa-var-sort-numeric-desc; }\n.#{$fa-css-prefix}-thumbs-up:before { content: $fa-var-thumbs-up; }\n.#{$fa-css-prefix}-thumbs-down:before { content: $fa-var-thumbs-down; }\n.#{$fa-css-prefix}-youtube-square:before { content: $fa-var-youtube-square; }\n.#{$fa-css-prefix}-youtube:before { content: $fa-var-youtube; }\n.#{$fa-css-prefix}-xing:before { content: $fa-var-xing; }\n.#{$fa-css-prefix}-xing-square:before { content: $fa-var-xing-square; }\n.#{$fa-css-prefix}-youtube-play:before { content: $fa-var-youtube-play; }\n.#{$fa-css-prefix}-dropbox:before { content: $fa-var-dropbox; }\n.#{$fa-css-prefix}-stack-overflow:before { content: $fa-var-stack-overflow; }\n.#{$fa-css-prefix}-instagram:before { content: $fa-var-instagram; }\n.#{$fa-css-prefix}-flickr:before { content: $fa-var-flickr; }\n.#{$fa-css-prefix}-adn:before { content: $fa-var-adn; }\n.#{$fa-css-prefix}-bitbucket:before { content: $fa-var-bitbucket; }\n.#{$fa-css-prefix}-bitbucket-square:before { content: $fa-var-bitbucket-square; }\n.#{$fa-css-prefix}-tumblr:before { content: $fa-var-tumblr; }\n.#{$fa-css-prefix}-tumblr-square:before { content: $fa-var-tumblr-square; }\n.#{$fa-css-prefix}-long-arrow-down:before { content: $fa-var-long-arrow-down; }\n.#{$fa-css-prefix}-long-arrow-up:before { content: $fa-var-long-arrow-up; }\n.#{$fa-css-prefix}-long-arrow-left:before { content: $fa-var-long-arrow-left; }\n.#{$fa-css-prefix}-long-arrow-right:before { content: $fa-var-long-arrow-right; }\n.#{$fa-css-prefix}-apple:before { content: $fa-var-apple; }\n.#{$fa-css-prefix}-windows:before { content: $fa-var-windows; }\n.#{$fa-css-prefix}-android:before { content: $fa-var-android; }\n.#{$fa-css-prefix}-linux:before { content: $fa-var-linux; }\n.#{$fa-css-prefix}-dribbble:before { content: $fa-var-dribbble; }\n.#{$fa-css-prefix}-skype:before { content: $fa-var-skype; }\n.#{$fa-css-prefix}-foursquare:before { content: $fa-var-foursquare; }\n.#{$fa-css-prefix}-trello:before { content: $fa-var-trello; }\n.#{$fa-css-prefix}-female:before { content: $fa-var-female; }\n.#{$fa-css-prefix}-male:before { content: $fa-var-male; }\n.#{$fa-css-prefix}-gittip:before,\n.#{$fa-css-prefix}-gratipay:before { content: $fa-var-gratipay; }\n.#{$fa-css-prefix}-sun-o:before { content: $fa-var-sun-o; }\n.#{$fa-css-prefix}-moon-o:before { content: $fa-var-moon-o; }\n.#{$fa-css-prefix}-archive:before { content: $fa-var-archive; }\n.#{$fa-css-prefix}-bug:before { content: $fa-var-bug; }\n.#{$fa-css-prefix}-vk:before { content: $fa-var-vk; }\n.#{$fa-css-prefix}-weibo:before { content: $fa-var-weibo; }\n.#{$fa-css-prefix}-renren:before { content: $fa-var-renren; }\n.#{$fa-css-prefix}-pagelines:before { content: $fa-var-pagelines; }\n.#{$fa-css-prefix}-stack-exchange:before { content: $fa-var-stack-exchange; }\n.#{$fa-css-prefix}-arrow-circle-o-right:before { content: $fa-var-arrow-circle-o-right; }\n.#{$fa-css-prefix}-arrow-circle-o-left:before { content: $fa-var-arrow-circle-o-left; }\n.#{$fa-css-prefix}-toggle-left:before,\n.#{$fa-css-prefix}-caret-square-o-left:before { content: $fa-var-caret-square-o-left; }\n.#{$fa-css-prefix}-dot-circle-o:before { content: $fa-var-dot-circle-o; }\n.#{$fa-css-prefix}-wheelchair:before { content: $fa-var-wheelchair; }\n.#{$fa-css-prefix}-vimeo-square:before { content: $fa-var-vimeo-square; }\n.#{$fa-css-prefix}-turkish-lira:before,\n.#{$fa-css-prefix}-try:before { content: $fa-var-try; }\n.#{$fa-css-prefix}-plus-square-o:before { content: $fa-var-plus-square-o; }\n.#{$fa-css-prefix}-space-shuttle:before { content: $fa-var-space-shuttle; }\n.#{$fa-css-prefix}-slack:before { content: $fa-var-slack; }\n.#{$fa-css-prefix}-envelope-square:before { content: $fa-var-envelope-square; }\n.#{$fa-css-prefix}-wordpress:before { content: $fa-var-wordpress; }\n.#{$fa-css-prefix}-openid:before { content: $fa-var-openid; }\n.#{$fa-css-prefix}-institution:before,\n.#{$fa-css-prefix}-bank:before,\n.#{$fa-css-prefix}-university:before { content: $fa-var-university; }\n.#{$fa-css-prefix}-mortar-board:before,\n.#{$fa-css-prefix}-graduation-cap:before { content: $fa-var-graduation-cap; }\n.#{$fa-css-prefix}-yahoo:before { content: $fa-var-yahoo; }\n.#{$fa-css-prefix}-google:before { content: $fa-var-google; }\n.#{$fa-css-prefix}-reddit:before { content: $fa-var-reddit; }\n.#{$fa-css-prefix}-reddit-square:before { content: $fa-var-reddit-square; }\n.#{$fa-css-prefix}-stumbleupon-circle:before { content: $fa-var-stumbleupon-circle; }\n.#{$fa-css-prefix}-stumbleupon:before { content: $fa-var-stumbleupon; }\n.#{$fa-css-prefix}-delicious:before { content: $fa-var-delicious; }\n.#{$fa-css-prefix}-digg:before { content: $fa-var-digg; }\n.#{$fa-css-prefix}-pied-piper-pp:before { content: $fa-var-pied-piper-pp; }\n.#{$fa-css-prefix}-pied-piper-alt:before { content: $fa-var-pied-piper-alt; }\n.#{$fa-css-prefix}-drupal:before { content: $fa-var-drupal; }\n.#{$fa-css-prefix}-joomla:before { content: $fa-var-joomla; }\n.#{$fa-css-prefix}-language:before { content: $fa-var-language; }\n.#{$fa-css-prefix}-fax:before { content: $fa-var-fax; }\n.#{$fa-css-prefix}-building:before { content: $fa-var-building; }\n.#{$fa-css-prefix}-child:before { content: $fa-var-child; }\n.#{$fa-css-prefix}-paw:before { content: $fa-var-paw; }\n.#{$fa-css-prefix}-spoon:before { content: $fa-var-spoon; }\n.#{$fa-css-prefix}-cube:before { content: $fa-var-cube; }\n.#{$fa-css-prefix}-cubes:before { content: $fa-var-cubes; }\n.#{$fa-css-prefix}-behance:before { content: $fa-var-behance; }\n.#{$fa-css-prefix}-behance-square:before { content: $fa-var-behance-square; }\n.#{$fa-css-prefix}-steam:before { content: $fa-var-steam; }\n.#{$fa-css-prefix}-steam-square:before { content: $fa-var-steam-square; }\n.#{$fa-css-prefix}-recycle:before { content: $fa-var-recycle; }\n.#{$fa-css-prefix}-automobile:before,\n.#{$fa-css-prefix}-car:before { content: $fa-var-car; }\n.#{$fa-css-prefix}-cab:before,\n.#{$fa-css-prefix}-taxi:before { content: $fa-var-taxi; }\n.#{$fa-css-prefix}-tree:before { content: $fa-var-tree; }\n.#{$fa-css-prefix}-spotify:before { content: $fa-var-spotify; }\n.#{$fa-css-prefix}-deviantart:before { content: $fa-var-deviantart; }\n.#{$fa-css-prefix}-soundcloud:before { content: $fa-var-soundcloud; }\n.#{$fa-css-prefix}-database:before { content: $fa-var-database; }\n.#{$fa-css-prefix}-file-pdf-o:before { content: $fa-var-file-pdf-o; }\n.#{$fa-css-prefix}-file-word-o:before { content: $fa-var-file-word-o; }\n.#{$fa-css-prefix}-file-excel-o:before { content: $fa-var-file-excel-o; }\n.#{$fa-css-prefix}-file-powerpoint-o:before { content: $fa-var-file-powerpoint-o; }\n.#{$fa-css-prefix}-file-photo-o:before,\n.#{$fa-css-prefix}-file-picture-o:before,\n.#{$fa-css-prefix}-file-image-o:before { content: $fa-var-file-image-o; }\n.#{$fa-css-prefix}-file-zip-o:before,\n.#{$fa-css-prefix}-file-archive-o:before { content: $fa-var-file-archive-o; }\n.#{$fa-css-prefix}-file-sound-o:before,\n.#{$fa-css-prefix}-file-audio-o:before { content: $fa-var-file-audio-o; }\n.#{$fa-css-prefix}-file-movie-o:before,\n.#{$fa-css-prefix}-file-video-o:before { content: $fa-var-file-video-o; }\n.#{$fa-css-prefix}-file-code-o:before { content: $fa-var-file-code-o; }\n.#{$fa-css-prefix}-vine:before { content: $fa-var-vine; }\n.#{$fa-css-prefix}-codepen:before { content: $fa-var-codepen; }\n.#{$fa-css-prefix}-jsfiddle:before { content: $fa-var-jsfiddle; }\n.#{$fa-css-prefix}-life-bouy:before,\n.#{$fa-css-prefix}-life-buoy:before,\n.#{$fa-css-prefix}-life-saver:before,\n.#{$fa-css-prefix}-support:before,\n.#{$fa-css-prefix}-life-ring:before { content: $fa-var-life-ring; }\n.#{$fa-css-prefix}-circle-o-notch:before { content: $fa-var-circle-o-notch; }\n.#{$fa-css-prefix}-ra:before,\n.#{$fa-css-prefix}-resistance:before,\n.#{$fa-css-prefix}-rebel:before { content: $fa-var-rebel; }\n.#{$fa-css-prefix}-ge:before,\n.#{$fa-css-prefix}-empire:before { content: $fa-var-empire; }\n.#{$fa-css-prefix}-git-square:before { content: $fa-var-git-square; }\n.#{$fa-css-prefix}-git:before { content: $fa-var-git; }\n.#{$fa-css-prefix}-y-combinator-square:before,\n.#{$fa-css-prefix}-yc-square:before,\n.#{$fa-css-prefix}-hacker-news:before { content: $fa-var-hacker-news; }\n.#{$fa-css-prefix}-tencent-weibo:before { content: $fa-var-tencent-weibo; }\n.#{$fa-css-prefix}-qq:before { content: $fa-var-qq; }\n.#{$fa-css-prefix}-wechat:before,\n.#{$fa-css-prefix}-weixin:before { content: $fa-var-weixin; }\n.#{$fa-css-prefix}-send:before,\n.#{$fa-css-prefix}-paper-plane:before { content: $fa-var-paper-plane; }\n.#{$fa-css-prefix}-send-o:before,\n.#{$fa-css-prefix}-paper-plane-o:before { content: $fa-var-paper-plane-o; }\n.#{$fa-css-prefix}-history:before { content: $fa-var-history; }\n.#{$fa-css-prefix}-circle-thin:before { content: $fa-var-circle-thin; }\n.#{$fa-css-prefix}-header:before { content: $fa-var-header; }\n.#{$fa-css-prefix}-paragraph:before { content: $fa-var-paragraph; }\n.#{$fa-css-prefix}-sliders:before { content: $fa-var-sliders; }\n.#{$fa-css-prefix}-share-alt:before { content: $fa-var-share-alt; }\n.#{$fa-css-prefix}-share-alt-square:before { content: $fa-var-share-alt-square; }\n.#{$fa-css-prefix}-bomb:before { content: $fa-var-bomb; }\n.#{$fa-css-prefix}-soccer-ball-o:before,\n.#{$fa-css-prefix}-futbol-o:before { content: $fa-var-futbol-o; }\n.#{$fa-css-prefix}-tty:before { content: $fa-var-tty; }\n.#{$fa-css-prefix}-binoculars:before { content: $fa-var-binoculars; }\n.#{$fa-css-prefix}-plug:before { content: $fa-var-plug; }\n.#{$fa-css-prefix}-slideshare:before { content: $fa-var-slideshare; }\n.#{$fa-css-prefix}-twitch:before { content: $fa-var-twitch; }\n.#{$fa-css-prefix}-yelp:before { content: $fa-var-yelp; }\n.#{$fa-css-prefix}-newspaper-o:before { content: $fa-var-newspaper-o; }\n.#{$fa-css-prefix}-wifi:before { content: $fa-var-wifi; }\n.#{$fa-css-prefix}-calculator:before { content: $fa-var-calculator; }\n.#{$fa-css-prefix}-paypal:before { content: $fa-var-paypal; }\n.#{$fa-css-prefix}-google-wallet:before { content: $fa-var-google-wallet; }\n.#{$fa-css-prefix}-cc-visa:before { content: $fa-var-cc-visa; }\n.#{$fa-css-prefix}-cc-mastercard:before { content: $fa-var-cc-mastercard; }\n.#{$fa-css-prefix}-cc-discover:before { content: $fa-var-cc-discover; }\n.#{$fa-css-prefix}-cc-amex:before { content: $fa-var-cc-amex; }\n.#{$fa-css-prefix}-cc-paypal:before { content: $fa-var-cc-paypal; }\n.#{$fa-css-prefix}-cc-stripe:before { content: $fa-var-cc-stripe; }\n.#{$fa-css-prefix}-bell-slash:before { content: $fa-var-bell-slash; }\n.#{$fa-css-prefix}-bell-slash-o:before { content: $fa-var-bell-slash-o; }\n.#{$fa-css-prefix}-trash:before { content: $fa-var-trash; }\n.#{$fa-css-prefix}-copyright:before { content: $fa-var-copyright; }\n.#{$fa-css-prefix}-at:before { content: $fa-var-at; }\n.#{$fa-css-prefix}-eyedropper:before { content: $fa-var-eyedropper; }\n.#{$fa-css-prefix}-paint-brush:before { content: $fa-var-paint-brush; }\n.#{$fa-css-prefix}-birthday-cake:before { content: $fa-var-birthday-cake; }\n.#{$fa-css-prefix}-area-chart:before { content: $fa-var-area-chart; }\n.#{$fa-css-prefix}-pie-chart:before { content: $fa-var-pie-chart; }\n.#{$fa-css-prefix}-line-chart:before { content: $fa-var-line-chart; }\n.#{$fa-css-prefix}-lastfm:before { content: $fa-var-lastfm; }\n.#{$fa-css-prefix}-lastfm-square:before { content: $fa-var-lastfm-square; }\n.#{$fa-css-prefix}-toggle-off:before { content: $fa-var-toggle-off; }\n.#{$fa-css-prefix}-toggle-on:before { content: $fa-var-toggle-on; }\n.#{$fa-css-prefix}-bicycle:before { content: $fa-var-bicycle; }\n.#{$fa-css-prefix}-bus:before { content: $fa-var-bus; }\n.#{$fa-css-prefix}-ioxhost:before { content: $fa-var-ioxhost; }\n.#{$fa-css-prefix}-angellist:before { content: $fa-var-angellist; }\n.#{$fa-css-prefix}-cc:before { content: $fa-var-cc; }\n.#{$fa-css-prefix}-shekel:before,\n.#{$fa-css-prefix}-sheqel:before,\n.#{$fa-css-prefix}-ils:before { content: $fa-var-ils; }\n.#{$fa-css-prefix}-meanpath:before { content: $fa-var-meanpath; }\n.#{$fa-css-prefix}-buysellads:before { content: $fa-var-buysellads; }\n.#{$fa-css-prefix}-connectdevelop:before { content: $fa-var-connectdevelop; }\n.#{$fa-css-prefix}-dashcube:before { content: $fa-var-dashcube; }\n.#{$fa-css-prefix}-forumbee:before { content: $fa-var-forumbee; }\n.#{$fa-css-prefix}-leanpub:before { content: $fa-var-leanpub; }\n.#{$fa-css-prefix}-sellsy:before { content: $fa-var-sellsy; }\n.#{$fa-css-prefix}-shirtsinbulk:before { content: $fa-var-shirtsinbulk; }\n.#{$fa-css-prefix}-simplybuilt:before { content: $fa-var-simplybuilt; }\n.#{$fa-css-prefix}-skyatlas:before { content: $fa-var-skyatlas; }\n.#{$fa-css-prefix}-cart-plus:before { content: $fa-var-cart-plus; }\n.#{$fa-css-prefix}-cart-arrow-down:before { content: $fa-var-cart-arrow-down; }\n.#{$fa-css-prefix}-diamond:before { content: $fa-var-diamond; }\n.#{$fa-css-prefix}-ship:before { content: $fa-var-ship; }\n.#{$fa-css-prefix}-user-secret:before { content: $fa-var-user-secret; }\n.#{$fa-css-prefix}-motorcycle:before { content: $fa-var-motorcycle; }\n.#{$fa-css-prefix}-street-view:before { content: $fa-var-street-view; }\n.#{$fa-css-prefix}-heartbeat:before { content: $fa-var-heartbeat; }\n.#{$fa-css-prefix}-venus:before { content: $fa-var-venus; }\n.#{$fa-css-prefix}-mars:before { content: $fa-var-mars; }\n.#{$fa-css-prefix}-mercury:before { content: $fa-var-mercury; }\n.#{$fa-css-prefix}-intersex:before,\n.#{$fa-css-prefix}-transgender:before { content: $fa-var-transgender; }\n.#{$fa-css-prefix}-transgender-alt:before { content: $fa-var-transgender-alt; }\n.#{$fa-css-prefix}-venus-double:before { content: $fa-var-venus-double; }\n.#{$fa-css-prefix}-mars-double:before { content: $fa-var-mars-double; }\n.#{$fa-css-prefix}-venus-mars:before { content: $fa-var-venus-mars; }\n.#{$fa-css-prefix}-mars-stroke:before { content: $fa-var-mars-stroke; }\n.#{$fa-css-prefix}-mars-stroke-v:before { content: $fa-var-mars-stroke-v; }\n.#{$fa-css-prefix}-mars-stroke-h:before { content: $fa-var-mars-stroke-h; }\n.#{$fa-css-prefix}-neuter:before { content: $fa-var-neuter; }\n.#{$fa-css-prefix}-genderless:before { content: $fa-var-genderless; }\n.#{$fa-css-prefix}-facebook-official:before { content: $fa-var-facebook-official; }\n.#{$fa-css-prefix}-pinterest-p:before { content: $fa-var-pinterest-p; }\n.#{$fa-css-prefix}-whatsapp:before { content: $fa-var-whatsapp; }\n.#{$fa-css-prefix}-server:before { content: $fa-var-server; }\n.#{$fa-css-prefix}-user-plus:before { content: $fa-var-user-plus; }\n.#{$fa-css-prefix}-user-times:before { content: $fa-var-user-times; }\n.#{$fa-css-prefix}-hotel:before,\n.#{$fa-css-prefix}-bed:before { content: $fa-var-bed; }\n.#{$fa-css-prefix}-viacoin:before { content: $fa-var-viacoin; }\n.#{$fa-css-prefix}-train:before { content: $fa-var-train; }\n.#{$fa-css-prefix}-subway:before { content: $fa-var-subway; }\n.#{$fa-css-prefix}-medium:before { content: $fa-var-medium; }\n.#{$fa-css-prefix}-yc:before,\n.#{$fa-css-prefix}-y-combinator:before { content: $fa-var-y-combinator; }\n.#{$fa-css-prefix}-optin-monster:before { content: $fa-var-optin-monster; }\n.#{$fa-css-prefix}-opencart:before { content: $fa-var-opencart; }\n.#{$fa-css-prefix}-expeditedssl:before { content: $fa-var-expeditedssl; }\n.#{$fa-css-prefix}-battery-4:before,\n.#{$fa-css-prefix}-battery-full:before { content: $fa-var-battery-full; }\n.#{$fa-css-prefix}-battery-3:before,\n.#{$fa-css-prefix}-battery-three-quarters:before { content: $fa-var-battery-three-quarters; }\n.#{$fa-css-prefix}-battery-2:before,\n.#{$fa-css-prefix}-battery-half:before { content: $fa-var-battery-half; }\n.#{$fa-css-prefix}-battery-1:before,\n.#{$fa-css-prefix}-battery-quarter:before { content: $fa-var-battery-quarter; }\n.#{$fa-css-prefix}-battery-0:before,\n.#{$fa-css-prefix}-battery-empty:before { content: $fa-var-battery-empty; }\n.#{$fa-css-prefix}-mouse-pointer:before { content: $fa-var-mouse-pointer; }\n.#{$fa-css-prefix}-i-cursor:before { content: $fa-var-i-cursor; }\n.#{$fa-css-prefix}-object-group:before { content: $fa-var-object-group; }\n.#{$fa-css-prefix}-object-ungroup:before { content: $fa-var-object-ungroup; }\n.#{$fa-css-prefix}-sticky-note:before { content: $fa-var-sticky-note; }\n.#{$fa-css-prefix}-sticky-note-o:before { content: $fa-var-sticky-note-o; }\n.#{$fa-css-prefix}-cc-jcb:before { content: $fa-var-cc-jcb; }\n.#{$fa-css-prefix}-cc-diners-club:before { content: $fa-var-cc-diners-club; }\n.#{$fa-css-prefix}-clone:before { content: $fa-var-clone; }\n.#{$fa-css-prefix}-balance-scale:before { content: $fa-var-balance-scale; }\n.#{$fa-css-prefix}-hourglass-o:before { content: $fa-var-hourglass-o; }\n.#{$fa-css-prefix}-hourglass-1:before,\n.#{$fa-css-prefix}-hourglass-start:before { content: $fa-var-hourglass-start; }\n.#{$fa-css-prefix}-hourglass-2:before,\n.#{$fa-css-prefix}-hourglass-half:before { content: $fa-var-hourglass-half; }\n.#{$fa-css-prefix}-hourglass-3:before,\n.#{$fa-css-prefix}-hourglass-end:before { content: $fa-var-hourglass-end; }\n.#{$fa-css-prefix}-hourglass:before { content: $fa-var-hourglass; }\n.#{$fa-css-prefix}-hand-grab-o:before,\n.#{$fa-css-prefix}-hand-rock-o:before { content: $fa-var-hand-rock-o; }\n.#{$fa-css-prefix}-hand-stop-o:before,\n.#{$fa-css-prefix}-hand-paper-o:before { content: $fa-var-hand-paper-o; }\n.#{$fa-css-prefix}-hand-scissors-o:before { content: $fa-var-hand-scissors-o; }\n.#{$fa-css-prefix}-hand-lizard-o:before { content: $fa-var-hand-lizard-o; }\n.#{$fa-css-prefix}-hand-spock-o:before { content: $fa-var-hand-spock-o; }\n.#{$fa-css-prefix}-hand-pointer-o:before { content: $fa-var-hand-pointer-o; }\n.#{$fa-css-prefix}-hand-peace-o:before { content: $fa-var-hand-peace-o; }\n.#{$fa-css-prefix}-trademark:before { content: $fa-var-trademark; }\n.#{$fa-css-prefix}-registered:before { content: $fa-var-registered; }\n.#{$fa-css-prefix}-creative-commons:before { content: $fa-var-creative-commons; }\n.#{$fa-css-prefix}-gg:before { content: $fa-var-gg; }\n.#{$fa-css-prefix}-gg-circle:before { content: $fa-var-gg-circle; }\n.#{$fa-css-prefix}-tripadvisor:before { content: $fa-var-tripadvisor; }\n.#{$fa-css-prefix}-odnoklassniki:before { content: $fa-var-odnoklassniki; }\n.#{$fa-css-prefix}-odnoklassniki-square:before { content: $fa-var-odnoklassniki-square; }\n.#{$fa-css-prefix}-get-pocket:before { content: $fa-var-get-pocket; }\n.#{$fa-css-prefix}-wikipedia-w:before { content: $fa-var-wikipedia-w; }\n.#{$fa-css-prefix}-safari:before { content: $fa-var-safari; }\n.#{$fa-css-prefix}-chrome:before { content: $fa-var-chrome; }\n.#{$fa-css-prefix}-firefox:before { content: $fa-var-firefox; }\n.#{$fa-css-prefix}-opera:before { content: $fa-var-opera; }\n.#{$fa-css-prefix}-internet-explorer:before { content: $fa-var-internet-explorer; }\n.#{$fa-css-prefix}-tv:before,\n.#{$fa-css-prefix}-television:before { content: $fa-var-television; }\n.#{$fa-css-prefix}-contao:before { content: $fa-var-contao; }\n.#{$fa-css-prefix}-500px:before { content: $fa-var-500px; }\n.#{$fa-css-prefix}-amazon:before { content: $fa-var-amazon; }\n.#{$fa-css-prefix}-calendar-plus-o:before { content: $fa-var-calendar-plus-o; }\n.#{$fa-css-prefix}-calendar-minus-o:before { content: $fa-var-calendar-minus-o; }\n.#{$fa-css-prefix}-calendar-times-o:before { content: $fa-var-calendar-times-o; }\n.#{$fa-css-prefix}-calendar-check-o:before { content: $fa-var-calendar-check-o; }\n.#{$fa-css-prefix}-industry:before { content: $fa-var-industry; }\n.#{$fa-css-prefix}-map-pin:before { content: $fa-var-map-pin; }\n.#{$fa-css-prefix}-map-signs:before { content: $fa-var-map-signs; }\n.#{$fa-css-prefix}-map-o:before { content: $fa-var-map-o; }\n.#{$fa-css-prefix}-map:before { content: $fa-var-map; }\n.#{$fa-css-prefix}-commenting:before { content: $fa-var-commenting; }\n.#{$fa-css-prefix}-commenting-o:before { content: $fa-var-commenting-o; }\n.#{$fa-css-prefix}-houzz:before { content: $fa-var-houzz; }\n.#{$fa-css-prefix}-vimeo:before { content: $fa-var-vimeo; }\n.#{$fa-css-prefix}-black-tie:before { content: $fa-var-black-tie; }\n.#{$fa-css-prefix}-fonticons:before { content: $fa-var-fonticons; }\n.#{$fa-css-prefix}-reddit-alien:before { content: $fa-var-reddit-alien; }\n.#{$fa-css-prefix}-edge:before { content: $fa-var-edge; }\n.#{$fa-css-prefix}-credit-card-alt:before { content: $fa-var-credit-card-alt; }\n.#{$fa-css-prefix}-codiepie:before { content: $fa-var-codiepie; }\n.#{$fa-css-prefix}-modx:before { content: $fa-var-modx; }\n.#{$fa-css-prefix}-fort-awesome:before { content: $fa-var-fort-awesome; }\n.#{$fa-css-prefix}-usb:before { content: $fa-var-usb; }\n.#{$fa-css-prefix}-product-hunt:before { content: $fa-var-product-hunt; }\n.#{$fa-css-prefix}-mixcloud:before { content: $fa-var-mixcloud; }\n.#{$fa-css-prefix}-scribd:before { content: $fa-var-scribd; }\n.#{$fa-css-prefix}-pause-circle:before { content: $fa-var-pause-circle; }\n.#{$fa-css-prefix}-pause-circle-o:before { content: $fa-var-pause-circle-o; }\n.#{$fa-css-prefix}-stop-circle:before { content: $fa-var-stop-circle; }\n.#{$fa-css-prefix}-stop-circle-o:before { content: $fa-var-stop-circle-o; }\n.#{$fa-css-prefix}-shopping-bag:before { content: $fa-var-shopping-bag; }\n.#{$fa-css-prefix}-shopping-basket:before { content: $fa-var-shopping-basket; }\n.#{$fa-css-prefix}-hashtag:before { content: $fa-var-hashtag; }\n.#{$fa-css-prefix}-bluetooth:before { content: $fa-var-bluetooth; }\n.#{$fa-css-prefix}-bluetooth-b:before { content: $fa-var-bluetooth-b; }\n.#{$fa-css-prefix}-percent:before { content: $fa-var-percent; }\n.#{$fa-css-prefix}-gitlab:before { content: $fa-var-gitlab; }\n.#{$fa-css-prefix}-wpbeginner:before { content: $fa-var-wpbeginner; }\n.#{$fa-css-prefix}-wpforms:before { content: $fa-var-wpforms; }\n.#{$fa-css-prefix}-envira:before { content: $fa-var-envira; }\n.#{$fa-css-prefix}-universal-access:before { content: $fa-var-universal-access; }\n.#{$fa-css-prefix}-wheelchair-alt:before { content: $fa-var-wheelchair-alt; }\n.#{$fa-css-prefix}-question-circle-o:before { content: $fa-var-question-circle-o; }\n.#{$fa-css-prefix}-blind:before { content: $fa-var-blind; }\n.#{$fa-css-prefix}-audio-description:before { content: $fa-var-audio-description; }\n.#{$fa-css-prefix}-volume-control-phone:before { content: $fa-var-volume-control-phone; }\n.#{$fa-css-prefix}-braille:before { content: $fa-var-braille; }\n.#{$fa-css-prefix}-assistive-listening-systems:before { content: $fa-var-assistive-listening-systems; }\n.#{$fa-css-prefix}-asl-interpreting:before,\n.#{$fa-css-prefix}-american-sign-language-interpreting:before { content: $fa-var-american-sign-language-interpreting; }\n.#{$fa-css-prefix}-deafness:before,\n.#{$fa-css-prefix}-hard-of-hearing:before,\n.#{$fa-css-prefix}-deaf:before { content: $fa-var-deaf; }\n.#{$fa-css-prefix}-glide:before { content: $fa-var-glide; }\n.#{$fa-css-prefix}-glide-g:before { content: $fa-var-glide-g; }\n.#{$fa-css-prefix}-signing:before,\n.#{$fa-css-prefix}-sign-language:before { content: $fa-var-sign-language; }\n.#{$fa-css-prefix}-low-vision:before { content: $fa-var-low-vision; }\n.#{$fa-css-prefix}-viadeo:before { content: $fa-var-viadeo; }\n.#{$fa-css-prefix}-viadeo-square:before { content: $fa-var-viadeo-square; }\n.#{$fa-css-prefix}-snapchat:before { content: $fa-var-snapchat; }\n.#{$fa-css-prefix}-snapchat-ghost:before { content: $fa-var-snapchat-ghost; }\n.#{$fa-css-prefix}-snapchat-square:before { content: $fa-var-snapchat-square; }\n.#{$fa-css-prefix}-pied-piper:before { content: $fa-var-pied-piper; }\n.#{$fa-css-prefix}-first-order:before { content: $fa-var-first-order; }\n.#{$fa-css-prefix}-yoast:before { content: $fa-var-yoast; }\n.#{$fa-css-prefix}-themeisle:before { content: $fa-var-themeisle; }\n.#{$fa-css-prefix}-google-plus-circle:before,\n.#{$fa-css-prefix}-google-plus-official:before { content: $fa-var-google-plus-official; }\n.#{$fa-css-prefix}-fa:before,\n.#{$fa-css-prefix}-font-awesome:before { content: $fa-var-font-awesome; }\n"
  },
  {
    "path": "app_backend/vendor/font-awesome/scss/_larger.scss",
    "content": "// Icon Sizes\n// -------------------------\n\n/* makes the font 33% larger relative to the icon container */\n.#{$fa-css-prefix}-lg {\n  font-size: (4em / 3);\n  line-height: (3em / 4);\n  vertical-align: -15%;\n}\n.#{$fa-css-prefix}-2x { font-size: 2em; }\n.#{$fa-css-prefix}-3x { font-size: 3em; }\n.#{$fa-css-prefix}-4x { font-size: 4em; }\n.#{$fa-css-prefix}-5x { font-size: 5em; }\n"
  },
  {
    "path": "app_backend/vendor/font-awesome/scss/_list.scss",
    "content": "// List Icons\n// -------------------------\n\n.#{$fa-css-prefix}-ul {\n  padding-left: 0;\n  margin-left: $fa-li-width;\n  list-style-type: none;\n  > li { position: relative; }\n}\n.#{$fa-css-prefix}-li {\n  position: absolute;\n  left: -$fa-li-width;\n  width: $fa-li-width;\n  top: (2em / 14);\n  text-align: center;\n  &.#{$fa-css-prefix}-lg {\n    left: -$fa-li-width + (4em / 14);\n  }\n}\n"
  },
  {
    "path": "app_backend/vendor/font-awesome/scss/_mixins.scss",
    "content": "// Mixins\n// --------------------------\n\n@mixin fa-icon() {\n  display: inline-block;\n  font: normal normal normal #{$fa-font-size-base}/#{$fa-line-height-base} FontAwesome; // shortening font declaration\n  font-size: inherit; // can't have font-size inherit on line above, so need to override\n  text-rendering: auto; // optimizelegibility throws things off #1094\n  -webkit-font-smoothing: antialiased;\n  -moz-osx-font-smoothing: grayscale;\n\n}\n\n@mixin fa-icon-rotate($degrees, $rotation) {\n  -ms-filter: \"progid:DXImageTransform.Microsoft.BasicImage(rotation=#{$rotation})\";\n  -webkit-transform: rotate($degrees);\n      -ms-transform: rotate($degrees);\n          transform: rotate($degrees);\n}\n\n@mixin fa-icon-flip($horiz, $vert, $rotation) {\n  -ms-filter: \"progid:DXImageTransform.Microsoft.BasicImage(rotation=#{$rotation}, mirror=1)\";\n  -webkit-transform: scale($horiz, $vert);\n      -ms-transform: scale($horiz, $vert);\n          transform: scale($horiz, $vert);\n}\n\n\n// Only display content to screen readers. A la Bootstrap 4.\n//\n// See: http://a11yproject.com/posts/how-to-hide-content/\n\n@mixin sr-only {\n  position: absolute;\n  width: 1px;\n  height: 1px;\n  padding: 0;\n  margin: -1px;\n  overflow: hidden;\n  clip: rect(0,0,0,0);\n  border: 0;\n}\n\n// Use in conjunction with .sr-only to only display content when it's focused.\n//\n// Useful for \"Skip to main content\" links; see http://www.w3.org/TR/2013/NOTE-WCAG20-TECHS-20130905/G1\n//\n// Credit: HTML5 Boilerplate\n\n@mixin sr-only-focusable {\n  &:active,\n  &:focus {\n    position: static;\n    width: auto;\n    height: auto;\n    margin: 0;\n    overflow: visible;\n    clip: auto;\n  }\n}\n"
  },
  {
    "path": "app_backend/vendor/font-awesome/scss/_path.scss",
    "content": "/* FONT PATH\n * -------------------------- */\n\n@font-face {\n  font-family: 'FontAwesome';\n  src: url('#{$fa-font-path}/fontawesome-webfont.eot?v=#{$fa-version}');\n  src: url('#{$fa-font-path}/fontawesome-webfont.eot?#iefix&v=#{$fa-version}') format('embedded-opentype'),\n    url('#{$fa-font-path}/fontawesome-webfont.woff2?v=#{$fa-version}') format('woff2'),\n    url('#{$fa-font-path}/fontawesome-webfont.woff?v=#{$fa-version}') format('woff'),\n    url('#{$fa-font-path}/fontawesome-webfont.ttf?v=#{$fa-version}') format('truetype'),\n    url('#{$fa-font-path}/fontawesome-webfont.svg?v=#{$fa-version}#fontawesomeregular') format('svg');\n//  src: url('#{$fa-font-path}/FontAwesome.otf') format('opentype'); // used when developing fonts\n  font-weight: normal;\n  font-style: normal;\n}\n"
  },
  {
    "path": "app_backend/vendor/font-awesome/scss/_rotated-flipped.scss",
    "content": "// Rotated & Flipped Icons\n// -------------------------\n\n.#{$fa-css-prefix}-rotate-90  { @include fa-icon-rotate(90deg, 1);  }\n.#{$fa-css-prefix}-rotate-180 { @include fa-icon-rotate(180deg, 2); }\n.#{$fa-css-prefix}-rotate-270 { @include fa-icon-rotate(270deg, 3); }\n\n.#{$fa-css-prefix}-flip-horizontal { @include fa-icon-flip(-1, 1, 0); }\n.#{$fa-css-prefix}-flip-vertical   { @include fa-icon-flip(1, -1, 2); }\n\n// Hook for IE8-9\n// -------------------------\n\n:root .#{$fa-css-prefix}-rotate-90,\n:root .#{$fa-css-prefix}-rotate-180,\n:root .#{$fa-css-prefix}-rotate-270,\n:root .#{$fa-css-prefix}-flip-horizontal,\n:root .#{$fa-css-prefix}-flip-vertical {\n  filter: none;\n}\n"
  },
  {
    "path": "app_backend/vendor/font-awesome/scss/_screen-reader.scss",
    "content": "// Screen Readers\n// -------------------------\n\n.sr-only { @include sr-only(); }\n.sr-only-focusable { @include sr-only-focusable(); }\n"
  },
  {
    "path": "app_backend/vendor/font-awesome/scss/_spinning.scss",
    "content": "// Spinning Icons\n// --------------------------\n\n.#{$fa-css-prefix}-spin {\n  -webkit-animation: fa-spin 2s infinite linear;\n          animation: fa-spin 2s infinite linear;\n}\n\n@-webkit-keyframes fa-spin {\n  0% {\n    -webkit-transform: rotate(0deg);\n            transform: rotate(0deg);\n  }\n  100% {\n    -webkit-transform: rotate(359deg);\n            transform: rotate(359deg);\n  }\n}\n\n@keyframes fa-spin {\n  0% {\n    -webkit-transform: rotate(0deg);\n            transform: rotate(0deg);\n  }\n  100% {\n    -webkit-transform: rotate(359deg);\n            transform: rotate(359deg);\n  }\n}\n"
  },
  {
    "path": "app_backend/vendor/font-awesome/scss/_stacked.scss",
    "content": "// Stacked Icons\n// -------------------------\n\n.#{$fa-css-prefix}-stack {\n  position: relative;\n  display: inline-block;\n  width: 2em;\n  height: 2em;\n  line-height: 2em;\n  vertical-align: middle;\n}\n.#{$fa-css-prefix}-stack-1x, .#{$fa-css-prefix}-stack-2x {\n  position: absolute;\n  left: 0;\n  width: 100%;\n  text-align: center;\n}\n.#{$fa-css-prefix}-stack-1x { line-height: inherit; }\n.#{$fa-css-prefix}-stack-2x { font-size: 2em; }\n.#{$fa-css-prefix}-inverse { color: $fa-inverse; }\n"
  },
  {
    "path": "app_backend/vendor/font-awesome/scss/_variables.scss",
    "content": "// Variables\n// --------------------------\n\n$fa-font-path:        \"../fonts\" !default;\n$fa-font-size-base:   14px !default;\n$fa-line-height-base: 1 !default;\n//$fa-font-path:        \"//netdna.bootstrapcdn.com/font-awesome/4.6.3/fonts\" !default; // for referencing Bootstrap CDN font files directly\n$fa-css-prefix:       fa !default;\n$fa-version:          \"4.6.3\" !default;\n$fa-border-color:     #eee !default;\n$fa-inverse:          #fff !default;\n$fa-li-width:         (30em / 14) !default;\n\n$fa-var-500px: \"\\f26e\";\n$fa-var-adjust: \"\\f042\";\n$fa-var-adn: \"\\f170\";\n$fa-var-align-center: \"\\f037\";\n$fa-var-align-justify: \"\\f039\";\n$fa-var-align-left: \"\\f036\";\n$fa-var-align-right: \"\\f038\";\n$fa-var-amazon: \"\\f270\";\n$fa-var-ambulance: \"\\f0f9\";\n$fa-var-american-sign-language-interpreting: \"\\f2a3\";\n$fa-var-anchor: \"\\f13d\";\n$fa-var-android: \"\\f17b\";\n$fa-var-angellist: \"\\f209\";\n$fa-var-angle-double-down: \"\\f103\";\n$fa-var-angle-double-left: \"\\f100\";\n$fa-var-angle-double-right: \"\\f101\";\n$fa-var-angle-double-up: \"\\f102\";\n$fa-var-angle-down: \"\\f107\";\n$fa-var-angle-left: \"\\f104\";\n$fa-var-angle-right: \"\\f105\";\n$fa-var-angle-up: \"\\f106\";\n$fa-var-apple: \"\\f179\";\n$fa-var-archive: \"\\f187\";\n$fa-var-area-chart: \"\\f1fe\";\n$fa-var-arrow-circle-down: \"\\f0ab\";\n$fa-var-arrow-circle-left: \"\\f0a8\";\n$fa-var-arrow-circle-o-down: \"\\f01a\";\n$fa-var-arrow-circle-o-left: \"\\f190\";\n$fa-var-arrow-circle-o-right: \"\\f18e\";\n$fa-var-arrow-circle-o-up: \"\\f01b\";\n$fa-var-arrow-circle-right: \"\\f0a9\";\n$fa-var-arrow-circle-up: \"\\f0aa\";\n$fa-var-arrow-down: \"\\f063\";\n$fa-var-arrow-left: \"\\f060\";\n$fa-var-arrow-right: \"\\f061\";\n$fa-var-arrow-up: \"\\f062\";\n$fa-var-arrows: \"\\f047\";\n$fa-var-arrows-alt: \"\\f0b2\";\n$fa-var-arrows-h: \"\\f07e\";\n$fa-var-arrows-v: \"\\f07d\";\n$fa-var-asl-interpreting: \"\\f2a3\";\n$fa-var-assistive-listening-systems: \"\\f2a2\";\n$fa-var-asterisk: \"\\f069\";\n$fa-var-at: \"\\f1fa\";\n$fa-var-audio-description: \"\\f29e\";\n$fa-var-automobile: \"\\f1b9\";\n$fa-var-backward: \"\\f04a\";\n$fa-var-balance-scale: \"\\f24e\";\n$fa-var-ban: \"\\f05e\";\n$fa-var-bank: \"\\f19c\";\n$fa-var-bar-chart: \"\\f080\";\n$fa-var-bar-chart-o: \"\\f080\";\n$fa-var-barcode: \"\\f02a\";\n$fa-var-bars: \"\\f0c9\";\n$fa-var-battery-0: \"\\f244\";\n$fa-var-battery-1: \"\\f243\";\n$fa-var-battery-2: \"\\f242\";\n$fa-var-battery-3: \"\\f241\";\n$fa-var-battery-4: \"\\f240\";\n$fa-var-battery-empty: \"\\f244\";\n$fa-var-battery-full: \"\\f240\";\n$fa-var-battery-half: \"\\f242\";\n$fa-var-battery-quarter: \"\\f243\";\n$fa-var-battery-three-quarters: \"\\f241\";\n$fa-var-bed: \"\\f236\";\n$fa-var-beer: \"\\f0fc\";\n$fa-var-behance: \"\\f1b4\";\n$fa-var-behance-square: \"\\f1b5\";\n$fa-var-bell: \"\\f0f3\";\n$fa-var-bell-o: \"\\f0a2\";\n$fa-var-bell-slash: \"\\f1f6\";\n$fa-var-bell-slash-o: \"\\f1f7\";\n$fa-var-bicycle: \"\\f206\";\n$fa-var-binoculars: \"\\f1e5\";\n$fa-var-birthday-cake: \"\\f1fd\";\n$fa-var-bitbucket: \"\\f171\";\n$fa-var-bitbucket-square: \"\\f172\";\n$fa-var-bitcoin: \"\\f15a\";\n$fa-var-black-tie: \"\\f27e\";\n$fa-var-blind: \"\\f29d\";\n$fa-var-bluetooth: \"\\f293\";\n$fa-var-bluetooth-b: \"\\f294\";\n$fa-var-bold: \"\\f032\";\n$fa-var-bolt: \"\\f0e7\";\n$fa-var-bomb: \"\\f1e2\";\n$fa-var-book: \"\\f02d\";\n$fa-var-bookmark: \"\\f02e\";\n$fa-var-bookmark-o: \"\\f097\";\n$fa-var-braille: \"\\f2a1\";\n$fa-var-briefcase: \"\\f0b1\";\n$fa-var-btc: \"\\f15a\";\n$fa-var-bug: \"\\f188\";\n$fa-var-building: \"\\f1ad\";\n$fa-var-building-o: \"\\f0f7\";\n$fa-var-bullhorn: \"\\f0a1\";\n$fa-var-bullseye: \"\\f140\";\n$fa-var-bus: \"\\f207\";\n$fa-var-buysellads: \"\\f20d\";\n$fa-var-cab: \"\\f1ba\";\n$fa-var-calculator: \"\\f1ec\";\n$fa-var-calendar: \"\\f073\";\n$fa-var-calendar-check-o: \"\\f274\";\n$fa-var-calendar-minus-o: \"\\f272\";\n$fa-var-calendar-o: \"\\f133\";\n$fa-var-calendar-plus-o: \"\\f271\";\n$fa-var-calendar-times-o: \"\\f273\";\n$fa-var-camera: \"\\f030\";\n$fa-var-camera-retro: \"\\f083\";\n$fa-var-car: \"\\f1b9\";\n$fa-var-caret-down: \"\\f0d7\";\n$fa-var-caret-left: \"\\f0d9\";\n$fa-var-caret-right: \"\\f0da\";\n$fa-var-caret-square-o-down: \"\\f150\";\n$fa-var-caret-square-o-left: \"\\f191\";\n$fa-var-caret-square-o-right: \"\\f152\";\n$fa-var-caret-square-o-up: \"\\f151\";\n$fa-var-caret-up: \"\\f0d8\";\n$fa-var-cart-arrow-down: \"\\f218\";\n$fa-var-cart-plus: \"\\f217\";\n$fa-var-cc: \"\\f20a\";\n$fa-var-cc-amex: \"\\f1f3\";\n$fa-var-cc-diners-club: \"\\f24c\";\n$fa-var-cc-discover: \"\\f1f2\";\n$fa-var-cc-jcb: \"\\f24b\";\n$fa-var-cc-mastercard: \"\\f1f1\";\n$fa-var-cc-paypal: \"\\f1f4\";\n$fa-var-cc-stripe: \"\\f1f5\";\n$fa-var-cc-visa: \"\\f1f0\";\n$fa-var-certificate: \"\\f0a3\";\n$fa-var-chain: \"\\f0c1\";\n$fa-var-chain-broken: \"\\f127\";\n$fa-var-check: \"\\f00c\";\n$fa-var-check-circle: \"\\f058\";\n$fa-var-check-circle-o: \"\\f05d\";\n$fa-var-check-square: \"\\f14a\";\n$fa-var-check-square-o: \"\\f046\";\n$fa-var-chevron-circle-down: \"\\f13a\";\n$fa-var-chevron-circle-left: \"\\f137\";\n$fa-var-chevron-circle-right: \"\\f138\";\n$fa-var-chevron-circle-up: \"\\f139\";\n$fa-var-chevron-down: \"\\f078\";\n$fa-var-chevron-left: \"\\f053\";\n$fa-var-chevron-right: \"\\f054\";\n$fa-var-chevron-up: \"\\f077\";\n$fa-var-child: \"\\f1ae\";\n$fa-var-chrome: \"\\f268\";\n$fa-var-circle: \"\\f111\";\n$fa-var-circle-o: \"\\f10c\";\n$fa-var-circle-o-notch: \"\\f1ce\";\n$fa-var-circle-thin: \"\\f1db\";\n$fa-var-clipboard: \"\\f0ea\";\n$fa-var-clock-o: \"\\f017\";\n$fa-var-clone: \"\\f24d\";\n$fa-var-close: \"\\f00d\";\n$fa-var-cloud: \"\\f0c2\";\n$fa-var-cloud-download: \"\\f0ed\";\n$fa-var-cloud-upload: \"\\f0ee\";\n$fa-var-cny: \"\\f157\";\n$fa-var-code: \"\\f121\";\n$fa-var-code-fork: \"\\f126\";\n$fa-var-codepen: \"\\f1cb\";\n$fa-var-codiepie: \"\\f284\";\n$fa-var-coffee: \"\\f0f4\";\n$fa-var-cog: \"\\f013\";\n$fa-var-cogs: \"\\f085\";\n$fa-var-columns: \"\\f0db\";\n$fa-var-comment: \"\\f075\";\n$fa-var-comment-o: \"\\f0e5\";\n$fa-var-commenting: \"\\f27a\";\n$fa-var-commenting-o: \"\\f27b\";\n$fa-var-comments: \"\\f086\";\n$fa-var-comments-o: \"\\f0e6\";\n$fa-var-compass: \"\\f14e\";\n$fa-var-compress: \"\\f066\";\n$fa-var-connectdevelop: \"\\f20e\";\n$fa-var-contao: \"\\f26d\";\n$fa-var-copy: \"\\f0c5\";\n$fa-var-copyright: \"\\f1f9\";\n$fa-var-creative-commons: \"\\f25e\";\n$fa-var-credit-card: \"\\f09d\";\n$fa-var-credit-card-alt: \"\\f283\";\n$fa-var-crop: \"\\f125\";\n$fa-var-crosshairs: \"\\f05b\";\n$fa-var-css3: \"\\f13c\";\n$fa-var-cube: \"\\f1b2\";\n$fa-var-cubes: \"\\f1b3\";\n$fa-var-cut: \"\\f0c4\";\n$fa-var-cutlery: \"\\f0f5\";\n$fa-var-dashboard: \"\\f0e4\";\n$fa-var-dashcube: \"\\f210\";\n$fa-var-database: \"\\f1c0\";\n$fa-var-deaf: \"\\f2a4\";\n$fa-var-deafness: \"\\f2a4\";\n$fa-var-dedent: \"\\f03b\";\n$fa-var-delicious: \"\\f1a5\";\n$fa-var-desktop: \"\\f108\";\n$fa-var-deviantart: \"\\f1bd\";\n$fa-var-diamond: \"\\f219\";\n$fa-var-digg: \"\\f1a6\";\n$fa-var-dollar: \"\\f155\";\n$fa-var-dot-circle-o: \"\\f192\";\n$fa-var-download: \"\\f019\";\n$fa-var-dribbble: \"\\f17d\";\n$fa-var-dropbox: \"\\f16b\";\n$fa-var-drupal: \"\\f1a9\";\n$fa-var-edge: \"\\f282\";\n$fa-var-edit: \"\\f044\";\n$fa-var-eject: \"\\f052\";\n$fa-var-ellipsis-h: \"\\f141\";\n$fa-var-ellipsis-v: \"\\f142\";\n$fa-var-empire: \"\\f1d1\";\n$fa-var-envelope: \"\\f0e0\";\n$fa-var-envelope-o: \"\\f003\";\n$fa-var-envelope-square: \"\\f199\";\n$fa-var-envira: \"\\f299\";\n$fa-var-eraser: \"\\f12d\";\n$fa-var-eur: \"\\f153\";\n$fa-var-euro: \"\\f153\";\n$fa-var-exchange: \"\\f0ec\";\n$fa-var-exclamation: \"\\f12a\";\n$fa-var-exclamation-circle: \"\\f06a\";\n$fa-var-exclamation-triangle: \"\\f071\";\n$fa-var-expand: \"\\f065\";\n$fa-var-expeditedssl: \"\\f23e\";\n$fa-var-external-link: \"\\f08e\";\n$fa-var-external-link-square: \"\\f14c\";\n$fa-var-eye: \"\\f06e\";\n$fa-var-eye-slash: \"\\f070\";\n$fa-var-eyedropper: \"\\f1fb\";\n$fa-var-fa: \"\\f2b4\";\n$fa-var-facebook: \"\\f09a\";\n$fa-var-facebook-f: \"\\f09a\";\n$fa-var-facebook-official: \"\\f230\";\n$fa-var-facebook-square: \"\\f082\";\n$fa-var-fast-backward: \"\\f049\";\n$fa-var-fast-forward: \"\\f050\";\n$fa-var-fax: \"\\f1ac\";\n$fa-var-feed: \"\\f09e\";\n$fa-var-female: \"\\f182\";\n$fa-var-fighter-jet: \"\\f0fb\";\n$fa-var-file: \"\\f15b\";\n$fa-var-file-archive-o: \"\\f1c6\";\n$fa-var-file-audio-o: \"\\f1c7\";\n$fa-var-file-code-o: \"\\f1c9\";\n$fa-var-file-excel-o: \"\\f1c3\";\n$fa-var-file-image-o: \"\\f1c5\";\n$fa-var-file-movie-o: \"\\f1c8\";\n$fa-var-file-o: \"\\f016\";\n$fa-var-file-pdf-o: \"\\f1c1\";\n$fa-var-file-photo-o: \"\\f1c5\";\n$fa-var-file-picture-o: \"\\f1c5\";\n$fa-var-file-powerpoint-o: \"\\f1c4\";\n$fa-var-file-sound-o: \"\\f1c7\";\n$fa-var-file-text: \"\\f15c\";\n$fa-var-file-text-o: \"\\f0f6\";\n$fa-var-file-video-o: \"\\f1c8\";\n$fa-var-file-word-o: \"\\f1c2\";\n$fa-var-file-zip-o: \"\\f1c6\";\n$fa-var-files-o: \"\\f0c5\";\n$fa-var-film: \"\\f008\";\n$fa-var-filter: \"\\f0b0\";\n$fa-var-fire: \"\\f06d\";\n$fa-var-fire-extinguisher: \"\\f134\";\n$fa-var-firefox: \"\\f269\";\n$fa-var-first-order: \"\\f2b0\";\n$fa-var-flag: \"\\f024\";\n$fa-var-flag-checkered: \"\\f11e\";\n$fa-var-flag-o: \"\\f11d\";\n$fa-var-flash: \"\\f0e7\";\n$fa-var-flask: \"\\f0c3\";\n$fa-var-flickr: \"\\f16e\";\n$fa-var-floppy-o: \"\\f0c7\";\n$fa-var-folder: \"\\f07b\";\n$fa-var-folder-o: \"\\f114\";\n$fa-var-folder-open: \"\\f07c\";\n$fa-var-folder-open-o: \"\\f115\";\n$fa-var-font: \"\\f031\";\n$fa-var-font-awesome: \"\\f2b4\";\n$fa-var-fonticons: \"\\f280\";\n$fa-var-fort-awesome: \"\\f286\";\n$fa-var-forumbee: \"\\f211\";\n$fa-var-forward: \"\\f04e\";\n$fa-var-foursquare: \"\\f180\";\n$fa-var-frown-o: \"\\f119\";\n$fa-var-futbol-o: \"\\f1e3\";\n$fa-var-gamepad: \"\\f11b\";\n$fa-var-gavel: \"\\f0e3\";\n$fa-var-gbp: \"\\f154\";\n$fa-var-ge: \"\\f1d1\";\n$fa-var-gear: \"\\f013\";\n$fa-var-gears: \"\\f085\";\n$fa-var-genderless: \"\\f22d\";\n$fa-var-get-pocket: \"\\f265\";\n$fa-var-gg: \"\\f260\";\n$fa-var-gg-circle: \"\\f261\";\n$fa-var-gift: \"\\f06b\";\n$fa-var-git: \"\\f1d3\";\n$fa-var-git-square: \"\\f1d2\";\n$fa-var-github: \"\\f09b\";\n$fa-var-github-alt: \"\\f113\";\n$fa-var-github-square: \"\\f092\";\n$fa-var-gitlab: \"\\f296\";\n$fa-var-gittip: \"\\f184\";\n$fa-var-glass: \"\\f000\";\n$fa-var-glide: \"\\f2a5\";\n$fa-var-glide-g: \"\\f2a6\";\n$fa-var-globe: \"\\f0ac\";\n$fa-var-google: \"\\f1a0\";\n$fa-var-google-plus: \"\\f0d5\";\n$fa-var-google-plus-circle: \"\\f2b3\";\n$fa-var-google-plus-official: \"\\f2b3\";\n$fa-var-google-plus-square: \"\\f0d4\";\n$fa-var-google-wallet: \"\\f1ee\";\n$fa-var-graduation-cap: \"\\f19d\";\n$fa-var-gratipay: \"\\f184\";\n$fa-var-group: \"\\f0c0\";\n$fa-var-h-square: \"\\f0fd\";\n$fa-var-hacker-news: \"\\f1d4\";\n$fa-var-hand-grab-o: \"\\f255\";\n$fa-var-hand-lizard-o: \"\\f258\";\n$fa-var-hand-o-down: \"\\f0a7\";\n$fa-var-hand-o-left: \"\\f0a5\";\n$fa-var-hand-o-right: \"\\f0a4\";\n$fa-var-hand-o-up: \"\\f0a6\";\n$fa-var-hand-paper-o: \"\\f256\";\n$fa-var-hand-peace-o: \"\\f25b\";\n$fa-var-hand-pointer-o: \"\\f25a\";\n$fa-var-hand-rock-o: \"\\f255\";\n$fa-var-hand-scissors-o: \"\\f257\";\n$fa-var-hand-spock-o: \"\\f259\";\n$fa-var-hand-stop-o: \"\\f256\";\n$fa-var-hard-of-hearing: \"\\f2a4\";\n$fa-var-hashtag: \"\\f292\";\n$fa-var-hdd-o: \"\\f0a0\";\n$fa-var-header: \"\\f1dc\";\n$fa-var-headphones: \"\\f025\";\n$fa-var-heart: \"\\f004\";\n$fa-var-heart-o: \"\\f08a\";\n$fa-var-heartbeat: \"\\f21e\";\n$fa-var-history: \"\\f1da\";\n$fa-var-home: \"\\f015\";\n$fa-var-hospital-o: \"\\f0f8\";\n$fa-var-hotel: \"\\f236\";\n$fa-var-hourglass: \"\\f254\";\n$fa-var-hourglass-1: \"\\f251\";\n$fa-var-hourglass-2: \"\\f252\";\n$fa-var-hourglass-3: \"\\f253\";\n$fa-var-hourglass-end: \"\\f253\";\n$fa-var-hourglass-half: \"\\f252\";\n$fa-var-hourglass-o: \"\\f250\";\n$fa-var-hourglass-start: \"\\f251\";\n$fa-var-houzz: \"\\f27c\";\n$fa-var-html5: \"\\f13b\";\n$fa-var-i-cursor: \"\\f246\";\n$fa-var-ils: \"\\f20b\";\n$fa-var-image: \"\\f03e\";\n$fa-var-inbox: \"\\f01c\";\n$fa-var-indent: \"\\f03c\";\n$fa-var-industry: \"\\f275\";\n$fa-var-info: \"\\f129\";\n$fa-var-info-circle: \"\\f05a\";\n$fa-var-inr: \"\\f156\";\n$fa-var-instagram: \"\\f16d\";\n$fa-var-institution: \"\\f19c\";\n$fa-var-internet-explorer: \"\\f26b\";\n$fa-var-intersex: \"\\f224\";\n$fa-var-ioxhost: \"\\f208\";\n$fa-var-italic: \"\\f033\";\n$fa-var-joomla: \"\\f1aa\";\n$fa-var-jpy: \"\\f157\";\n$fa-var-jsfiddle: \"\\f1cc\";\n$fa-var-key: \"\\f084\";\n$fa-var-keyboard-o: \"\\f11c\";\n$fa-var-krw: \"\\f159\";\n$fa-var-language: \"\\f1ab\";\n$fa-var-laptop: \"\\f109\";\n$fa-var-lastfm: \"\\f202\";\n$fa-var-lastfm-square: \"\\f203\";\n$fa-var-leaf: \"\\f06c\";\n$fa-var-leanpub: \"\\f212\";\n$fa-var-legal: \"\\f0e3\";\n$fa-var-lemon-o: \"\\f094\";\n$fa-var-level-down: \"\\f149\";\n$fa-var-level-up: \"\\f148\";\n$fa-var-life-bouy: \"\\f1cd\";\n$fa-var-life-buoy: \"\\f1cd\";\n$fa-var-life-ring: \"\\f1cd\";\n$fa-var-life-saver: \"\\f1cd\";\n$fa-var-lightbulb-o: \"\\f0eb\";\n$fa-var-line-chart: \"\\f201\";\n$fa-var-link: \"\\f0c1\";\n$fa-var-linkedin: \"\\f0e1\";\n$fa-var-linkedin-square: \"\\f08c\";\n$fa-var-linux: \"\\f17c\";\n$fa-var-list: \"\\f03a\";\n$fa-var-list-alt: \"\\f022\";\n$fa-var-list-ol: \"\\f0cb\";\n$fa-var-list-ul: \"\\f0ca\";\n$fa-var-location-arrow: \"\\f124\";\n$fa-var-lock: \"\\f023\";\n$fa-var-long-arrow-down: \"\\f175\";\n$fa-var-long-arrow-left: \"\\f177\";\n$fa-var-long-arrow-right: \"\\f178\";\n$fa-var-long-arrow-up: \"\\f176\";\n$fa-var-low-vision: \"\\f2a8\";\n$fa-var-magic: \"\\f0d0\";\n$fa-var-magnet: \"\\f076\";\n$fa-var-mail-forward: \"\\f064\";\n$fa-var-mail-reply: \"\\f112\";\n$fa-var-mail-reply-all: \"\\f122\";\n$fa-var-male: \"\\f183\";\n$fa-var-map: \"\\f279\";\n$fa-var-map-marker: \"\\f041\";\n$fa-var-map-o: \"\\f278\";\n$fa-var-map-pin: \"\\f276\";\n$fa-var-map-signs: \"\\f277\";\n$fa-var-mars: \"\\f222\";\n$fa-var-mars-double: \"\\f227\";\n$fa-var-mars-stroke: \"\\f229\";\n$fa-var-mars-stroke-h: \"\\f22b\";\n$fa-var-mars-stroke-v: \"\\f22a\";\n$fa-var-maxcdn: \"\\f136\";\n$fa-var-meanpath: \"\\f20c\";\n$fa-var-medium: \"\\f23a\";\n$fa-var-medkit: \"\\f0fa\";\n$fa-var-meh-o: \"\\f11a\";\n$fa-var-mercury: \"\\f223\";\n$fa-var-microphone: \"\\f130\";\n$fa-var-microphone-slash: \"\\f131\";\n$fa-var-minus: \"\\f068\";\n$fa-var-minus-circle: \"\\f056\";\n$fa-var-minus-square: \"\\f146\";\n$fa-var-minus-square-o: \"\\f147\";\n$fa-var-mixcloud: \"\\f289\";\n$fa-var-mobile: \"\\f10b\";\n$fa-var-mobile-phone: \"\\f10b\";\n$fa-var-modx: \"\\f285\";\n$fa-var-money: \"\\f0d6\";\n$fa-var-moon-o: \"\\f186\";\n$fa-var-mortar-board: \"\\f19d\";\n$fa-var-motorcycle: \"\\f21c\";\n$fa-var-mouse-pointer: \"\\f245\";\n$fa-var-music: \"\\f001\";\n$fa-var-navicon: \"\\f0c9\";\n$fa-var-neuter: \"\\f22c\";\n$fa-var-newspaper-o: \"\\f1ea\";\n$fa-var-object-group: \"\\f247\";\n$fa-var-object-ungroup: \"\\f248\";\n$fa-var-odnoklassniki: \"\\f263\";\n$fa-var-odnoklassniki-square: \"\\f264\";\n$fa-var-opencart: \"\\f23d\";\n$fa-var-openid: \"\\f19b\";\n$fa-var-opera: \"\\f26a\";\n$fa-var-optin-monster: \"\\f23c\";\n$fa-var-outdent: \"\\f03b\";\n$fa-var-pagelines: \"\\f18c\";\n$fa-var-paint-brush: \"\\f1fc\";\n$fa-var-paper-plane: \"\\f1d8\";\n$fa-var-paper-plane-o: \"\\f1d9\";\n$fa-var-paperclip: \"\\f0c6\";\n$fa-var-paragraph: \"\\f1dd\";\n$fa-var-paste: \"\\f0ea\";\n$fa-var-pause: \"\\f04c\";\n$fa-var-pause-circle: \"\\f28b\";\n$fa-var-pause-circle-o: \"\\f28c\";\n$fa-var-paw: \"\\f1b0\";\n$fa-var-paypal: \"\\f1ed\";\n$fa-var-pencil: \"\\f040\";\n$fa-var-pencil-square: \"\\f14b\";\n$fa-var-pencil-square-o: \"\\f044\";\n$fa-var-percent: \"\\f295\";\n$fa-var-phone: \"\\f095\";\n$fa-var-phone-square: \"\\f098\";\n$fa-var-photo: \"\\f03e\";\n$fa-var-picture-o: \"\\f03e\";\n$fa-var-pie-chart: \"\\f200\";\n$fa-var-pied-piper: \"\\f2ae\";\n$fa-var-pied-piper-alt: \"\\f1a8\";\n$fa-var-pied-piper-pp: \"\\f1a7\";\n$fa-var-pinterest: \"\\f0d2\";\n$fa-var-pinterest-p: \"\\f231\";\n$fa-var-pinterest-square: \"\\f0d3\";\n$fa-var-plane: \"\\f072\";\n$fa-var-play: \"\\f04b\";\n$fa-var-play-circle: \"\\f144\";\n$fa-var-play-circle-o: \"\\f01d\";\n$fa-var-plug: \"\\f1e6\";\n$fa-var-plus: \"\\f067\";\n$fa-var-plus-circle: \"\\f055\";\n$fa-var-plus-square: \"\\f0fe\";\n$fa-var-plus-square-o: \"\\f196\";\n$fa-var-power-off: \"\\f011\";\n$fa-var-print: \"\\f02f\";\n$fa-var-product-hunt: \"\\f288\";\n$fa-var-puzzle-piece: \"\\f12e\";\n$fa-var-qq: \"\\f1d6\";\n$fa-var-qrcode: \"\\f029\";\n$fa-var-question: \"\\f128\";\n$fa-var-question-circle: \"\\f059\";\n$fa-var-question-circle-o: \"\\f29c\";\n$fa-var-quote-left: \"\\f10d\";\n$fa-var-quote-right: \"\\f10e\";\n$fa-var-ra: \"\\f1d0\";\n$fa-var-random: \"\\f074\";\n$fa-var-rebel: \"\\f1d0\";\n$fa-var-recycle: \"\\f1b8\";\n$fa-var-reddit: \"\\f1a1\";\n$fa-var-reddit-alien: \"\\f281\";\n$fa-var-reddit-square: \"\\f1a2\";\n$fa-var-refresh: \"\\f021\";\n$fa-var-registered: \"\\f25d\";\n$fa-var-remove: \"\\f00d\";\n$fa-var-renren: \"\\f18b\";\n$fa-var-reorder: \"\\f0c9\";\n$fa-var-repeat: \"\\f01e\";\n$fa-var-reply: \"\\f112\";\n$fa-var-reply-all: \"\\f122\";\n$fa-var-resistance: \"\\f1d0\";\n$fa-var-retweet: \"\\f079\";\n$fa-var-rmb: \"\\f157\";\n$fa-var-road: \"\\f018\";\n$fa-var-rocket: \"\\f135\";\n$fa-var-rotate-left: \"\\f0e2\";\n$fa-var-rotate-right: \"\\f01e\";\n$fa-var-rouble: \"\\f158\";\n$fa-var-rss: \"\\f09e\";\n$fa-var-rss-square: \"\\f143\";\n$fa-var-rub: \"\\f158\";\n$fa-var-ruble: \"\\f158\";\n$fa-var-rupee: \"\\f156\";\n$fa-var-safari: \"\\f267\";\n$fa-var-save: \"\\f0c7\";\n$fa-var-scissors: \"\\f0c4\";\n$fa-var-scribd: \"\\f28a\";\n$fa-var-search: \"\\f002\";\n$fa-var-search-minus: \"\\f010\";\n$fa-var-search-plus: \"\\f00e\";\n$fa-var-sellsy: \"\\f213\";\n$fa-var-send: \"\\f1d8\";\n$fa-var-send-o: \"\\f1d9\";\n$fa-var-server: \"\\f233\";\n$fa-var-share: \"\\f064\";\n$fa-var-share-alt: \"\\f1e0\";\n$fa-var-share-alt-square: \"\\f1e1\";\n$fa-var-share-square: \"\\f14d\";\n$fa-var-share-square-o: \"\\f045\";\n$fa-var-shekel: \"\\f20b\";\n$fa-var-sheqel: \"\\f20b\";\n$fa-var-shield: \"\\f132\";\n$fa-var-ship: \"\\f21a\";\n$fa-var-shirtsinbulk: \"\\f214\";\n$fa-var-shopping-bag: \"\\f290\";\n$fa-var-shopping-basket: \"\\f291\";\n$fa-var-shopping-cart: \"\\f07a\";\n$fa-var-sign-in: \"\\f090\";\n$fa-var-sign-language: \"\\f2a7\";\n$fa-var-sign-out: \"\\f08b\";\n$fa-var-signal: \"\\f012\";\n$fa-var-signing: \"\\f2a7\";\n$fa-var-simplybuilt: \"\\f215\";\n$fa-var-sitemap: \"\\f0e8\";\n$fa-var-skyatlas: \"\\f216\";\n$fa-var-skype: \"\\f17e\";\n$fa-var-slack: \"\\f198\";\n$fa-var-sliders: \"\\f1de\";\n$fa-var-slideshare: \"\\f1e7\";\n$fa-var-smile-o: \"\\f118\";\n$fa-var-snapchat: \"\\f2ab\";\n$fa-var-snapchat-ghost: \"\\f2ac\";\n$fa-var-snapchat-square: \"\\f2ad\";\n$fa-var-soccer-ball-o: \"\\f1e3\";\n$fa-var-sort: \"\\f0dc\";\n$fa-var-sort-alpha-asc: \"\\f15d\";\n$fa-var-sort-alpha-desc: \"\\f15e\";\n$fa-var-sort-amount-asc: \"\\f160\";\n$fa-var-sort-amount-desc: \"\\f161\";\n$fa-var-sort-asc: \"\\f0de\";\n$fa-var-sort-desc: \"\\f0dd\";\n$fa-var-sort-down: \"\\f0dd\";\n$fa-var-sort-numeric-asc: \"\\f162\";\n$fa-var-sort-numeric-desc: \"\\f163\";\n$fa-var-sort-up: \"\\f0de\";\n$fa-var-soundcloud: \"\\f1be\";\n$fa-var-space-shuttle: \"\\f197\";\n$fa-var-spinner: \"\\f110\";\n$fa-var-spoon: \"\\f1b1\";\n$fa-var-spotify: \"\\f1bc\";\n$fa-var-square: \"\\f0c8\";\n$fa-var-square-o: \"\\f096\";\n$fa-var-stack-exchange: \"\\f18d\";\n$fa-var-stack-overflow: \"\\f16c\";\n$fa-var-star: \"\\f005\";\n$fa-var-star-half: \"\\f089\";\n$fa-var-star-half-empty: \"\\f123\";\n$fa-var-star-half-full: \"\\f123\";\n$fa-var-star-half-o: \"\\f123\";\n$fa-var-star-o: \"\\f006\";\n$fa-var-steam: \"\\f1b6\";\n$fa-var-steam-square: \"\\f1b7\";\n$fa-var-step-backward: \"\\f048\";\n$fa-var-step-forward: \"\\f051\";\n$fa-var-stethoscope: \"\\f0f1\";\n$fa-var-sticky-note: \"\\f249\";\n$fa-var-sticky-note-o: \"\\f24a\";\n$fa-var-stop: \"\\f04d\";\n$fa-var-stop-circle: \"\\f28d\";\n$fa-var-stop-circle-o: \"\\f28e\";\n$fa-var-street-view: \"\\f21d\";\n$fa-var-strikethrough: \"\\f0cc\";\n$fa-var-stumbleupon: \"\\f1a4\";\n$fa-var-stumbleupon-circle: \"\\f1a3\";\n$fa-var-subscript: \"\\f12c\";\n$fa-var-subway: \"\\f239\";\n$fa-var-suitcase: \"\\f0f2\";\n$fa-var-sun-o: \"\\f185\";\n$fa-var-superscript: \"\\f12b\";\n$fa-var-support: \"\\f1cd\";\n$fa-var-table: \"\\f0ce\";\n$fa-var-tablet: \"\\f10a\";\n$fa-var-tachometer: \"\\f0e4\";\n$fa-var-tag: \"\\f02b\";\n$fa-var-tags: \"\\f02c\";\n$fa-var-tasks: \"\\f0ae\";\n$fa-var-taxi: \"\\f1ba\";\n$fa-var-television: \"\\f26c\";\n$fa-var-tencent-weibo: \"\\f1d5\";\n$fa-var-terminal: \"\\f120\";\n$fa-var-text-height: \"\\f034\";\n$fa-var-text-width: \"\\f035\";\n$fa-var-th: \"\\f00a\";\n$fa-var-th-large: \"\\f009\";\n$fa-var-th-list: \"\\f00b\";\n$fa-var-themeisle: \"\\f2b2\";\n$fa-var-thumb-tack: \"\\f08d\";\n$fa-var-thumbs-down: \"\\f165\";\n$fa-var-thumbs-o-down: \"\\f088\";\n$fa-var-thumbs-o-up: \"\\f087\";\n$fa-var-thumbs-up: \"\\f164\";\n$fa-var-ticket: \"\\f145\";\n$fa-var-times: \"\\f00d\";\n$fa-var-times-circle: \"\\f057\";\n$fa-var-times-circle-o: \"\\f05c\";\n$fa-var-tint: \"\\f043\";\n$fa-var-toggle-down: \"\\f150\";\n$fa-var-toggle-left: \"\\f191\";\n$fa-var-toggle-off: \"\\f204\";\n$fa-var-toggle-on: \"\\f205\";\n$fa-var-toggle-right: \"\\f152\";\n$fa-var-toggle-up: \"\\f151\";\n$fa-var-trademark: \"\\f25c\";\n$fa-var-train: \"\\f238\";\n$fa-var-transgender: \"\\f224\";\n$fa-var-transgender-alt: \"\\f225\";\n$fa-var-trash: \"\\f1f8\";\n$fa-var-trash-o: \"\\f014\";\n$fa-var-tree: \"\\f1bb\";\n$fa-var-trello: \"\\f181\";\n$fa-var-tripadvisor: \"\\f262\";\n$fa-var-trophy: \"\\f091\";\n$fa-var-truck: \"\\f0d1\";\n$fa-var-try: \"\\f195\";\n$fa-var-tty: \"\\f1e4\";\n$fa-var-tumblr: \"\\f173\";\n$fa-var-tumblr-square: \"\\f174\";\n$fa-var-turkish-lira: \"\\f195\";\n$fa-var-tv: \"\\f26c\";\n$fa-var-twitch: \"\\f1e8\";\n$fa-var-twitter: \"\\f099\";\n$fa-var-twitter-square: \"\\f081\";\n$fa-var-umbrella: \"\\f0e9\";\n$fa-var-underline: \"\\f0cd\";\n$fa-var-undo: \"\\f0e2\";\n$fa-var-universal-access: \"\\f29a\";\n$fa-var-university: \"\\f19c\";\n$fa-var-unlink: \"\\f127\";\n$fa-var-unlock: \"\\f09c\";\n$fa-var-unlock-alt: \"\\f13e\";\n$fa-var-unsorted: \"\\f0dc\";\n$fa-var-upload: \"\\f093\";\n$fa-var-usb: \"\\f287\";\n$fa-var-usd: \"\\f155\";\n$fa-var-user: \"\\f007\";\n$fa-var-user-md: \"\\f0f0\";\n$fa-var-user-plus: \"\\f234\";\n$fa-var-user-secret: \"\\f21b\";\n$fa-var-user-times: \"\\f235\";\n$fa-var-users: \"\\f0c0\";\n$fa-var-venus: \"\\f221\";\n$fa-var-venus-double: \"\\f226\";\n$fa-var-venus-mars: \"\\f228\";\n$fa-var-viacoin: \"\\f237\";\n$fa-var-viadeo: \"\\f2a9\";\n$fa-var-viadeo-square: \"\\f2aa\";\n$fa-var-video-camera: \"\\f03d\";\n$fa-var-vimeo: \"\\f27d\";\n$fa-var-vimeo-square: \"\\f194\";\n$fa-var-vine: \"\\f1ca\";\n$fa-var-vk: \"\\f189\";\n$fa-var-volume-control-phone: \"\\f2a0\";\n$fa-var-volume-down: \"\\f027\";\n$fa-var-volume-off: \"\\f026\";\n$fa-var-volume-up: \"\\f028\";\n$fa-var-warning: \"\\f071\";\n$fa-var-wechat: \"\\f1d7\";\n$fa-var-weibo: \"\\f18a\";\n$fa-var-weixin: \"\\f1d7\";\n$fa-var-whatsapp: \"\\f232\";\n$fa-var-wheelchair: \"\\f193\";\n$fa-var-wheelchair-alt: \"\\f29b\";\n$fa-var-wifi: \"\\f1eb\";\n$fa-var-wikipedia-w: \"\\f266\";\n$fa-var-windows: \"\\f17a\";\n$fa-var-won: \"\\f159\";\n$fa-var-wordpress: \"\\f19a\";\n$fa-var-wpbeginner: \"\\f297\";\n$fa-var-wpforms: \"\\f298\";\n$fa-var-wrench: \"\\f0ad\";\n$fa-var-xing: \"\\f168\";\n$fa-var-xing-square: \"\\f169\";\n$fa-var-y-combinator: \"\\f23b\";\n$fa-var-y-combinator-square: \"\\f1d4\";\n$fa-var-yahoo: \"\\f19e\";\n$fa-var-yc: \"\\f23b\";\n$fa-var-yc-square: \"\\f1d4\";\n$fa-var-yelp: \"\\f1e9\";\n$fa-var-yen: \"\\f157\";\n$fa-var-yoast: \"\\f2b1\";\n$fa-var-youtube: \"\\f167\";\n$fa-var-youtube-play: \"\\f16a\";\n$fa-var-youtube-square: \"\\f166\";\n\n"
  },
  {
    "path": "app_backend/vendor/font-awesome/scss/font-awesome.scss",
    "content": "/*!\n *  Font Awesome 4.6.3 by @davegandy - http://fontawesome.io - @fontawesome\n *  License - http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License)\n */\n\n@import \"variables\";\n@import \"mixins\";\n@import \"path\";\n@import \"core\";\n@import \"larger\";\n@import \"fixed-width\";\n@import \"list\";\n@import \"bordered-pulled\";\n@import \"animated\";\n@import \"rotated-flipped\";\n@import \"stacked\";\n@import \"icons\";\n@import \"screen-reader\";\n"
  },
  {
    "path": "app_backend/vendor/jquery/jquery.js",
    "content": "/*eslint-disable no-unused-vars*/\n/*!\n * jQuery JavaScript Library v3.1.0\n * https://jquery.com/\n *\n * Includes Sizzle.js\n * https://sizzlejs.com/\n *\n * Copyright jQuery Foundation and other contributors\n * Released under the MIT license\n * https://jquery.org/license\n *\n * Date: 2016-07-07T21:44Z\n */\n( function( global, factory ) {\n\n\t\"use strict\";\n\n\tif ( typeof module === \"object\" && typeof module.exports === \"object\" ) {\n\n\t\t// For CommonJS and CommonJS-like environments where a proper `window`\n\t\t// is present, execute the factory and get jQuery.\n\t\t// For environments that do not have a `window` with a `document`\n\t\t// (such as Node.js), expose a factory as module.exports.\n\t\t// This accentuates the need for the creation of a real `window`.\n\t\t// e.g. var jQuery = require(\"jquery\")(window);\n\t\t// See ticket #14549 for more info.\n\t\tmodule.exports = global.document ?\n\t\t\tfactory( global, true ) :\n\t\t\tfunction( w ) {\n\t\t\t\tif ( !w.document ) {\n\t\t\t\t\tthrow new Error( \"jQuery requires a window with a document\" );\n\t\t\t\t}\n\t\t\t\treturn factory( w );\n\t\t\t};\n\t} else {\n\t\tfactory( global );\n\t}\n\n// Pass this if window is not defined yet\n} )( typeof window !== \"undefined\" ? window : this, function( window, noGlobal ) {\n\n// Edge <= 12 - 13+, Firefox <=18 - 45+, IE 10 - 11, Safari 5.1 - 9+, iOS 6 - 9.1\n// throw exceptions when non-strict code (e.g., ASP.NET 4.5) accesses strict mode\n// arguments.callee.caller (trac-13335). But as of jQuery 3.0 (2016), strict mode should be common\n// enough that all such attempts are guarded in a try block.\n\"use strict\";\n\nvar arr = [];\n\nvar document = window.document;\n\nvar getProto = Object.getPrototypeOf;\n\nvar slice = arr.slice;\n\nvar concat = arr.concat;\n\nvar push = arr.push;\n\nvar indexOf = arr.indexOf;\n\nvar class2type = {};\n\nvar toString = class2type.toString;\n\nvar hasOwn = class2type.hasOwnProperty;\n\nvar fnToString = hasOwn.toString;\n\nvar ObjectFunctionString = fnToString.call( Object );\n\nvar support = {};\n\n\n\n\tfunction DOMEval( code, doc ) {\n\t\tdoc = doc || document;\n\n\t\tvar script = doc.createElement( \"script\" );\n\n\t\tscript.text = code;\n\t\tdoc.head.appendChild( script ).parentNode.removeChild( script );\n\t}\n/* global Symbol */\n// Defining this global in .eslintrc would create a danger of using the global\n// unguarded in another place, it seems safer to define global only for this module\n\n\n\nvar\n\tversion = \"3.1.0\",\n\n\t// Define a local copy of jQuery\n\tjQuery = function( selector, context ) {\n\n\t\t// The jQuery object is actually just the init constructor 'enhanced'\n\t\t// Need init if jQuery is called (just allow error to be thrown if not included)\n\t\treturn new jQuery.fn.init( selector, context );\n\t},\n\n\t// Support: Android <=4.0 only\n\t// Make sure we trim BOM and NBSP\n\trtrim = /^[\\s\\uFEFF\\xA0]+|[\\s\\uFEFF\\xA0]+$/g,\n\n\t// Matches dashed string for camelizing\n\trmsPrefix = /^-ms-/,\n\trdashAlpha = /-([a-z])/g,\n\n\t// Used by jQuery.camelCase as callback to replace()\n\tfcamelCase = function( all, letter ) {\n\t\treturn letter.toUpperCase();\n\t};\n\njQuery.fn = jQuery.prototype = {\n\n\t// The current version of jQuery being used\n\tjquery: version,\n\n\tconstructor: jQuery,\n\n\t// The default length of a jQuery object is 0\n\tlength: 0,\n\n\ttoArray: function() {\n\t\treturn slice.call( this );\n\t},\n\n\t// Get the Nth element in the matched element set OR\n\t// Get the whole matched element set as a clean array\n\tget: function( num ) {\n\t\treturn num != null ?\n\n\t\t\t// Return just the one element from the set\n\t\t\t( num < 0 ? this[ num + this.length ] : this[ num ] ) :\n\n\t\t\t// Return all the elements in a clean array\n\t\t\tslice.call( this );\n\t},\n\n\t// Take an array of elements and push it onto the stack\n\t// (returning the new matched element set)\n\tpushStack: function( elems ) {\n\n\t\t// Build a new jQuery matched element set\n\t\tvar ret = jQuery.merge( this.constructor(), elems );\n\n\t\t// Add the old object onto the stack (as a reference)\n\t\tret.prevObject = this;\n\n\t\t// Return the newly-formed element set\n\t\treturn ret;\n\t},\n\n\t// Execute a callback for every element in the matched set.\n\teach: function( callback ) {\n\t\treturn jQuery.each( this, callback );\n\t},\n\n\tmap: function( callback ) {\n\t\treturn this.pushStack( jQuery.map( this, function( elem, i ) {\n\t\t\treturn callback.call( elem, i, elem );\n\t\t} ) );\n\t},\n\n\tslice: function() {\n\t\treturn this.pushStack( slice.apply( this, arguments ) );\n\t},\n\n\tfirst: function() {\n\t\treturn this.eq( 0 );\n\t},\n\n\tlast: function() {\n\t\treturn this.eq( -1 );\n\t},\n\n\teq: function( i ) {\n\t\tvar len = this.length,\n\t\t\tj = +i + ( i < 0 ? len : 0 );\n\t\treturn this.pushStack( j >= 0 && j < len ? [ this[ j ] ] : [] );\n\t},\n\n\tend: function() {\n\t\treturn this.prevObject || this.constructor();\n\t},\n\n\t// For internal use only.\n\t// Behaves like an Array's method, not like a jQuery method.\n\tpush: push,\n\tsort: arr.sort,\n\tsplice: arr.splice\n};\n\njQuery.extend = jQuery.fn.extend = function() {\n\tvar options, name, src, copy, copyIsArray, clone,\n\t\ttarget = arguments[ 0 ] || {},\n\t\ti = 1,\n\t\tlength = arguments.length,\n\t\tdeep = false;\n\n\t// Handle a deep copy situation\n\tif ( typeof target === \"boolean\" ) {\n\t\tdeep = target;\n\n\t\t// Skip the boolean and the target\n\t\ttarget = arguments[ i ] || {};\n\t\ti++;\n\t}\n\n\t// Handle case when target is a string or something (possible in deep copy)\n\tif ( typeof target !== \"object\" && !jQuery.isFunction( target ) ) {\n\t\ttarget = {};\n\t}\n\n\t// Extend jQuery itself if only one argument is passed\n\tif ( i === length ) {\n\t\ttarget = this;\n\t\ti--;\n\t}\n\n\tfor ( ; i < length; i++ ) {\n\n\t\t// Only deal with non-null/undefined values\n\t\tif ( ( options = arguments[ i ] ) != null ) {\n\n\t\t\t// Extend the base object\n\t\t\tfor ( name in options ) {\n\t\t\t\tsrc = target[ name ];\n\t\t\t\tcopy = options[ name ];\n\n\t\t\t\t// Prevent never-ending loop\n\t\t\t\tif ( target === copy ) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\t// Recurse if we're merging plain objects or arrays\n\t\t\t\tif ( deep && copy && ( jQuery.isPlainObject( copy ) ||\n\t\t\t\t\t( copyIsArray = jQuery.isArray( copy ) ) ) ) {\n\n\t\t\t\t\tif ( copyIsArray ) {\n\t\t\t\t\t\tcopyIsArray = false;\n\t\t\t\t\t\tclone = src && jQuery.isArray( src ) ? src : [];\n\n\t\t\t\t\t} else {\n\t\t\t\t\t\tclone = src && jQuery.isPlainObject( src ) ? src : {};\n\t\t\t\t\t}\n\n\t\t\t\t\t// Never move original objects, clone them\n\t\t\t\t\ttarget[ name ] = jQuery.extend( deep, clone, copy );\n\n\t\t\t\t// Don't bring in undefined values\n\t\t\t\t} else if ( copy !== undefined ) {\n\t\t\t\t\ttarget[ name ] = copy;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t// Return the modified object\n\treturn target;\n};\n\njQuery.extend( {\n\n\t// Unique for each copy of jQuery on the page\n\texpando: \"jQuery\" + ( version + Math.random() ).replace( /\\D/g, \"\" ),\n\n\t// Assume jQuery is ready without the ready module\n\tisReady: true,\n\n\terror: function( msg ) {\n\t\tthrow new Error( msg );\n\t},\n\n\tnoop: function() {},\n\n\tisFunction: function( obj ) {\n\t\treturn jQuery.type( obj ) === \"function\";\n\t},\n\n\tisArray: Array.isArray,\n\n\tisWindow: function( obj ) {\n\t\treturn obj != null && obj === obj.window;\n\t},\n\n\tisNumeric: function( obj ) {\n\n\t\t// As of jQuery 3.0, isNumeric is limited to\n\t\t// strings and numbers (primitives or objects)\n\t\t// that can be coerced to finite numbers (gh-2662)\n\t\tvar type = jQuery.type( obj );\n\t\treturn ( type === \"number\" || type === \"string\" ) &&\n\n\t\t\t// parseFloat NaNs numeric-cast false positives (\"\")\n\t\t\t// ...but misinterprets leading-number strings, particularly hex literals (\"0x...\")\n\t\t\t// subtraction forces infinities to NaN\n\t\t\t!isNaN( obj - parseFloat( obj ) );\n\t},\n\n\tisPlainObject: function( obj ) {\n\t\tvar proto, Ctor;\n\n\t\t// Detect obvious negatives\n\t\t// Use toString instead of jQuery.type to catch host objects\n\t\tif ( !obj || toString.call( obj ) !== \"[object Object]\" ) {\n\t\t\treturn false;\n\t\t}\n\n\t\tproto = getProto( obj );\n\n\t\t// Objects with no prototype (e.g., `Object.create( null )`) are plain\n\t\tif ( !proto ) {\n\t\t\treturn true;\n\t\t}\n\n\t\t// Objects with prototype are plain iff they were constructed by a global Object function\n\t\tCtor = hasOwn.call( proto, \"constructor\" ) && proto.constructor;\n\t\treturn typeof Ctor === \"function\" && fnToString.call( Ctor ) === ObjectFunctionString;\n\t},\n\n\tisEmptyObject: function( obj ) {\n\n\t\t/* eslint-disable no-unused-vars */\n\t\t// See https://github.com/eslint/eslint/issues/6125\n\t\tvar name;\n\n\t\tfor ( name in obj ) {\n\t\t\treturn false;\n\t\t}\n\t\treturn true;\n\t},\n\n\ttype: function( obj ) {\n\t\tif ( obj == null ) {\n\t\t\treturn obj + \"\";\n\t\t}\n\n\t\t// Support: Android <=2.3 only (functionish RegExp)\n\t\treturn typeof obj === \"object\" || typeof obj === \"function\" ?\n\t\t\tclass2type[ toString.call( obj ) ] || \"object\" :\n\t\t\ttypeof obj;\n\t},\n\n\t// Evaluates a script in a global context\n\tglobalEval: function( code ) {\n\t\tDOMEval( code );\n\t},\n\n\t// Convert dashed to camelCase; used by the css and data modules\n\t// Support: IE <=9 - 11, Edge 12 - 13\n\t// Microsoft forgot to hump their vendor prefix (#9572)\n\tcamelCase: function( string ) {\n\t\treturn string.replace( rmsPrefix, \"ms-\" ).replace( rdashAlpha, fcamelCase );\n\t},\n\n\tnodeName: function( elem, name ) {\n\t\treturn elem.nodeName && elem.nodeName.toLowerCase() === name.toLowerCase();\n\t},\n\n\teach: function( obj, callback ) {\n\t\tvar length, i = 0;\n\n\t\tif ( isArrayLike( obj ) ) {\n\t\t\tlength = obj.length;\n\t\t\tfor ( ; i < length; i++ ) {\n\t\t\t\tif ( callback.call( obj[ i ], i, obj[ i ] ) === false ) {\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\tfor ( i in obj ) {\n\t\t\t\tif ( callback.call( obj[ i ], i, obj[ i ] ) === false ) {\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn obj;\n\t},\n\n\t// Support: Android <=4.0 only\n\ttrim: function( text ) {\n\t\treturn text == null ?\n\t\t\t\"\" :\n\t\t\t( text + \"\" ).replace( rtrim, \"\" );\n\t},\n\n\t// results is for internal usage only\n\tmakeArray: function( arr, results ) {\n\t\tvar ret = results || [];\n\n\t\tif ( arr != null ) {\n\t\t\tif ( isArrayLike( Object( arr ) ) ) {\n\t\t\t\tjQuery.merge( ret,\n\t\t\t\t\ttypeof arr === \"string\" ?\n\t\t\t\t\t[ arr ] : arr\n\t\t\t\t);\n\t\t\t} else {\n\t\t\t\tpush.call( ret, arr );\n\t\t\t}\n\t\t}\n\n\t\treturn ret;\n\t},\n\n\tinArray: function( elem, arr, i ) {\n\t\treturn arr == null ? -1 : indexOf.call( arr, elem, i );\n\t},\n\n\t// Support: Android <=4.0 only, PhantomJS 1 only\n\t// push.apply(_, arraylike) throws on ancient WebKit\n\tmerge: function( first, second ) {\n\t\tvar len = +second.length,\n\t\t\tj = 0,\n\t\t\ti = first.length;\n\n\t\tfor ( ; j < len; j++ ) {\n\t\t\tfirst[ i++ ] = second[ j ];\n\t\t}\n\n\t\tfirst.length = i;\n\n\t\treturn first;\n\t},\n\n\tgrep: function( elems, callback, invert ) {\n\t\tvar callbackInverse,\n\t\t\tmatches = [],\n\t\t\ti = 0,\n\t\t\tlength = elems.length,\n\t\t\tcallbackExpect = !invert;\n\n\t\t// Go through the array, only saving the items\n\t\t// that pass the validator function\n\t\tfor ( ; i < length; i++ ) {\n\t\t\tcallbackInverse = !callback( elems[ i ], i );\n\t\t\tif ( callbackInverse !== callbackExpect ) {\n\t\t\t\tmatches.push( elems[ i ] );\n\t\t\t}\n\t\t}\n\n\t\treturn matches;\n\t},\n\n\t// arg is for internal usage only\n\tmap: function( elems, callback, arg ) {\n\t\tvar length, value,\n\t\t\ti = 0,\n\t\t\tret = [];\n\n\t\t// Go through the array, translating each of the items to their new values\n\t\tif ( isArrayLike( elems ) ) {\n\t\t\tlength = elems.length;\n\t\t\tfor ( ; i < length; i++ ) {\n\t\t\t\tvalue = callback( elems[ i ], i, arg );\n\n\t\t\t\tif ( value != null ) {\n\t\t\t\t\tret.push( value );\n\t\t\t\t}\n\t\t\t}\n\n\t\t// Go through every key on the object,\n\t\t} else {\n\t\t\tfor ( i in elems ) {\n\t\t\t\tvalue = callback( elems[ i ], i, arg );\n\n\t\t\t\tif ( value != null ) {\n\t\t\t\t\tret.push( value );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Flatten any nested arrays\n\t\treturn concat.apply( [], ret );\n\t},\n\n\t// A global GUID counter for objects\n\tguid: 1,\n\n\t// Bind a function to a context, optionally partially applying any\n\t// arguments.\n\tproxy: function( fn, context ) {\n\t\tvar tmp, args, proxy;\n\n\t\tif ( typeof context === \"string\" ) {\n\t\t\ttmp = fn[ context ];\n\t\t\tcontext = fn;\n\t\t\tfn = tmp;\n\t\t}\n\n\t\t// Quick check to determine if target is callable, in the spec\n\t\t// this throws a TypeError, but we will just return undefined.\n\t\tif ( !jQuery.isFunction( fn ) ) {\n\t\t\treturn undefined;\n\t\t}\n\n\t\t// Simulated bind\n\t\targs = slice.call( arguments, 2 );\n\t\tproxy = function() {\n\t\t\treturn fn.apply( context || this, args.concat( slice.call( arguments ) ) );\n\t\t};\n\n\t\t// Set the guid of unique handler to the same of original handler, so it can be removed\n\t\tproxy.guid = fn.guid = fn.guid || jQuery.guid++;\n\n\t\treturn proxy;\n\t},\n\n\tnow: Date.now,\n\n\t// jQuery.support is not used in Core but other projects attach their\n\t// properties to it so it needs to exist.\n\tsupport: support\n} );\n\nif ( typeof Symbol === \"function\" ) {\n\tjQuery.fn[ Symbol.iterator ] = arr[ Symbol.iterator ];\n}\n\n// Populate the class2type map\njQuery.each( \"Boolean Number String Function Array Date RegExp Object Error Symbol\".split( \" \" ),\nfunction( i, name ) {\n\tclass2type[ \"[object \" + name + \"]\" ] = name.toLowerCase();\n} );\n\nfunction isArrayLike( obj ) {\n\n\t// Support: real iOS 8.2 only (not reproducible in simulator)\n\t// `in` check used to prevent JIT error (gh-2145)\n\t// hasOwn isn't used here due to false negatives\n\t// regarding Nodelist length in IE\n\tvar length = !!obj && \"length\" in obj && obj.length,\n\t\ttype = jQuery.type( obj );\n\n\tif ( type === \"function\" || jQuery.isWindow( obj ) ) {\n\t\treturn false;\n\t}\n\n\treturn type === \"array\" || length === 0 ||\n\t\ttypeof length === \"number\" && length > 0 && ( length - 1 ) in obj;\n}\nvar Sizzle =\n/*!\n * Sizzle CSS Selector Engine v2.3.0\n * https://sizzlejs.com/\n *\n * Copyright jQuery Foundation and other contributors\n * Released under the MIT license\n * http://jquery.org/license\n *\n * Date: 2016-01-04\n */\n(function( window ) {\n\nvar i,\n\tsupport,\n\tExpr,\n\tgetText,\n\tisXML,\n\ttokenize,\n\tcompile,\n\tselect,\n\toutermostContext,\n\tsortInput,\n\thasDuplicate,\n\n\t// Local document vars\n\tsetDocument,\n\tdocument,\n\tdocElem,\n\tdocumentIsHTML,\n\trbuggyQSA,\n\trbuggyMatches,\n\tmatches,\n\tcontains,\n\n\t// Instance-specific data\n\texpando = \"sizzle\" + 1 * new Date(),\n\tpreferredDoc = window.document,\n\tdirruns = 0,\n\tdone = 0,\n\tclassCache = createCache(),\n\ttokenCache = createCache(),\n\tcompilerCache = createCache(),\n\tsortOrder = function( a, b ) {\n\t\tif ( a === b ) {\n\t\t\thasDuplicate = true;\n\t\t}\n\t\treturn 0;\n\t},\n\n\t// Instance methods\n\thasOwn = ({}).hasOwnProperty,\n\tarr = [],\n\tpop = arr.pop,\n\tpush_native = arr.push,\n\tpush = arr.push,\n\tslice = arr.slice,\n\t// Use a stripped-down indexOf as it's faster than native\n\t// https://jsperf.com/thor-indexof-vs-for/5\n\tindexOf = function( list, elem ) {\n\t\tvar i = 0,\n\t\t\tlen = list.length;\n\t\tfor ( ; i < len; i++ ) {\n\t\t\tif ( list[i] === elem ) {\n\t\t\t\treturn i;\n\t\t\t}\n\t\t}\n\t\treturn -1;\n\t},\n\n\tbooleans = \"checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped\",\n\n\t// Regular expressions\n\n\t// http://www.w3.org/TR/css3-selectors/#whitespace\n\twhitespace = \"[\\\\x20\\\\t\\\\r\\\\n\\\\f]\",\n\n\t// http://www.w3.org/TR/CSS21/syndata.html#value-def-identifier\n\tidentifier = \"(?:\\\\\\\\.|[\\\\w-]|[^\\0-\\\\xa0])+\",\n\n\t// Attribute selectors: http://www.w3.org/TR/selectors/#attribute-selectors\n\tattributes = \"\\\\[\" + whitespace + \"*(\" + identifier + \")(?:\" + whitespace +\n\t\t// Operator (capture 2)\n\t\t\"*([*^$|!~]?=)\" + whitespace +\n\t\t// \"Attribute values must be CSS identifiers [capture 5] or strings [capture 3 or capture 4]\"\n\t\t\"*(?:'((?:\\\\\\\\.|[^\\\\\\\\'])*)'|\\\"((?:\\\\\\\\.|[^\\\\\\\\\\\"])*)\\\"|(\" + identifier + \"))|)\" + whitespace +\n\t\t\"*\\\\]\",\n\n\tpseudos = \":(\" + identifier + \")(?:\\\\((\" +\n\t\t// To reduce the number of selectors needing tokenize in the preFilter, prefer arguments:\n\t\t// 1. quoted (capture 3; capture 4 or capture 5)\n\t\t\"('((?:\\\\\\\\.|[^\\\\\\\\'])*)'|\\\"((?:\\\\\\\\.|[^\\\\\\\\\\\"])*)\\\")|\" +\n\t\t// 2. simple (capture 6)\n\t\t\"((?:\\\\\\\\.|[^\\\\\\\\()[\\\\]]|\" + attributes + \")*)|\" +\n\t\t// 3. anything else (capture 2)\n\t\t\".*\" +\n\t\t\")\\\\)|)\",\n\n\t// Leading and non-escaped trailing whitespace, capturing some non-whitespace characters preceding the latter\n\trwhitespace = new RegExp( whitespace + \"+\", \"g\" ),\n\trtrim = new RegExp( \"^\" + whitespace + \"+|((?:^|[^\\\\\\\\])(?:\\\\\\\\.)*)\" + whitespace + \"+$\", \"g\" ),\n\n\trcomma = new RegExp( \"^\" + whitespace + \"*,\" + whitespace + \"*\" ),\n\trcombinators = new RegExp( \"^\" + whitespace + \"*([>+~]|\" + whitespace + \")\" + whitespace + \"*\" ),\n\n\trattributeQuotes = new RegExp( \"=\" + whitespace + \"*([^\\\\]'\\\"]*?)\" + whitespace + \"*\\\\]\", \"g\" ),\n\n\trpseudo = new RegExp( pseudos ),\n\tridentifier = new RegExp( \"^\" + identifier + \"$\" ),\n\n\tmatchExpr = {\n\t\t\"ID\": new RegExp( \"^#(\" + identifier + \")\" ),\n\t\t\"CLASS\": new RegExp( \"^\\\\.(\" + identifier + \")\" ),\n\t\t\"TAG\": new RegExp( \"^(\" + identifier + \"|[*])\" ),\n\t\t\"ATTR\": new RegExp( \"^\" + attributes ),\n\t\t\"PSEUDO\": new RegExp( \"^\" + pseudos ),\n\t\t\"CHILD\": new RegExp( \"^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\\\(\" + whitespace +\n\t\t\t\"*(even|odd|(([+-]|)(\\\\d*)n|)\" + whitespace + \"*(?:([+-]|)\" + whitespace +\n\t\t\t\"*(\\\\d+)|))\" + whitespace + \"*\\\\)|)\", \"i\" ),\n\t\t\"bool\": new RegExp( \"^(?:\" + booleans + \")$\", \"i\" ),\n\t\t// For use in libraries implementing .is()\n\t\t// We use this for POS matching in `select`\n\t\t\"needsContext\": new RegExp( \"^\" + whitespace + \"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\\\(\" +\n\t\t\twhitespace + \"*((?:-\\\\d)?\\\\d*)\" + whitespace + \"*\\\\)|)(?=[^-]|$)\", \"i\" )\n\t},\n\n\trinputs = /^(?:input|select|textarea|button)$/i,\n\trheader = /^h\\d$/i,\n\n\trnative = /^[^{]+\\{\\s*\\[native \\w/,\n\n\t// Easily-parseable/retrievable ID or TAG or CLASS selectors\n\trquickExpr = /^(?:#([\\w-]+)|(\\w+)|\\.([\\w-]+))$/,\n\n\trsibling = /[+~]/,\n\n\t// CSS escapes\n\t// http://www.w3.org/TR/CSS21/syndata.html#escaped-characters\n\trunescape = new RegExp( \"\\\\\\\\([\\\\da-f]{1,6}\" + whitespace + \"?|(\" + whitespace + \")|.)\", \"ig\" ),\n\tfunescape = function( _, escaped, escapedWhitespace ) {\n\t\tvar high = \"0x\" + escaped - 0x10000;\n\t\t// NaN means non-codepoint\n\t\t// Support: Firefox<24\n\t\t// Workaround erroneous numeric interpretation of +\"0x\"\n\t\treturn high !== high || escapedWhitespace ?\n\t\t\tescaped :\n\t\t\thigh < 0 ?\n\t\t\t\t// BMP codepoint\n\t\t\t\tString.fromCharCode( high + 0x10000 ) :\n\t\t\t\t// Supplemental Plane codepoint (surrogate pair)\n\t\t\t\tString.fromCharCode( high >> 10 | 0xD800, high & 0x3FF | 0xDC00 );\n\t},\n\n\t// CSS string/identifier serialization\n\t// https://drafts.csswg.org/cssom/#common-serializing-idioms\n\trcssescape = /([\\0-\\x1f\\x7f]|^-?\\d)|^-$|[^\\x80-\\uFFFF\\w-]/g,\n\tfcssescape = function( ch, asCodePoint ) {\n\t\tif ( asCodePoint ) {\n\n\t\t\t// U+0000 NULL becomes U+FFFD REPLACEMENT CHARACTER\n\t\t\tif ( ch === \"\\0\" ) {\n\t\t\t\treturn \"\\uFFFD\";\n\t\t\t}\n\n\t\t\t// Control characters and (dependent upon position) numbers get escaped as code points\n\t\t\treturn ch.slice( 0, -1 ) + \"\\\\\" + ch.charCodeAt( ch.length - 1 ).toString( 16 ) + \" \";\n\t\t}\n\n\t\t// Other potentially-special ASCII characters get backslash-escaped\n\t\treturn \"\\\\\" + ch;\n\t},\n\n\t// Used for iframes\n\t// See setDocument()\n\t// Removing the function wrapper causes a \"Permission Denied\"\n\t// error in IE\n\tunloadHandler = function() {\n\t\tsetDocument();\n\t},\n\n\tdisabledAncestor = addCombinator(\n\t\tfunction( elem ) {\n\t\t\treturn elem.disabled === true;\n\t\t},\n\t\t{ dir: \"parentNode\", next: \"legend\" }\n\t);\n\n// Optimize for push.apply( _, NodeList )\ntry {\n\tpush.apply(\n\t\t(arr = slice.call( preferredDoc.childNodes )),\n\t\tpreferredDoc.childNodes\n\t);\n\t// Support: Android<4.0\n\t// Detect silently failing push.apply\n\tarr[ preferredDoc.childNodes.length ].nodeType;\n} catch ( e ) {\n\tpush = { apply: arr.length ?\n\n\t\t// Leverage slice if possible\n\t\tfunction( target, els ) {\n\t\t\tpush_native.apply( target, slice.call(els) );\n\t\t} :\n\n\t\t// Support: IE<9\n\t\t// Otherwise append directly\n\t\tfunction( target, els ) {\n\t\t\tvar j = target.length,\n\t\t\t\ti = 0;\n\t\t\t// Can't trust NodeList.length\n\t\t\twhile ( (target[j++] = els[i++]) ) {}\n\t\t\ttarget.length = j - 1;\n\t\t}\n\t};\n}\n\nfunction Sizzle( selector, context, results, seed ) {\n\tvar m, i, elem, nid, match, groups, newSelector,\n\t\tnewContext = context && context.ownerDocument,\n\n\t\t// nodeType defaults to 9, since context defaults to document\n\t\tnodeType = context ? context.nodeType : 9;\n\n\tresults = results || [];\n\n\t// Return early from calls with invalid selector or context\n\tif ( typeof selector !== \"string\" || !selector ||\n\t\tnodeType !== 1 && nodeType !== 9 && nodeType !== 11 ) {\n\n\t\treturn results;\n\t}\n\n\t// Try to shortcut find operations (as opposed to filters) in HTML documents\n\tif ( !seed ) {\n\n\t\tif ( ( context ? context.ownerDocument || context : preferredDoc ) !== document ) {\n\t\t\tsetDocument( context );\n\t\t}\n\t\tcontext = context || document;\n\n\t\tif ( documentIsHTML ) {\n\n\t\t\t// If the selector is sufficiently simple, try using a \"get*By*\" DOM method\n\t\t\t// (excepting DocumentFragment context, where the methods don't exist)\n\t\t\tif ( nodeType !== 11 && (match = rquickExpr.exec( selector )) ) {\n\n\t\t\t\t// ID selector\n\t\t\t\tif ( (m = match[1]) ) {\n\n\t\t\t\t\t// Document context\n\t\t\t\t\tif ( nodeType === 9 ) {\n\t\t\t\t\t\tif ( (elem = context.getElementById( m )) ) {\n\n\t\t\t\t\t\t\t// Support: IE, Opera, Webkit\n\t\t\t\t\t\t\t// TODO: identify versions\n\t\t\t\t\t\t\t// getElementById can match elements by name instead of ID\n\t\t\t\t\t\t\tif ( elem.id === m ) {\n\t\t\t\t\t\t\t\tresults.push( elem );\n\t\t\t\t\t\t\t\treturn results;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\treturn results;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t// Element context\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\t// Support: IE, Opera, Webkit\n\t\t\t\t\t\t// TODO: identify versions\n\t\t\t\t\t\t// getElementById can match elements by name instead of ID\n\t\t\t\t\t\tif ( newContext && (elem = newContext.getElementById( m )) &&\n\t\t\t\t\t\t\tcontains( context, elem ) &&\n\t\t\t\t\t\t\telem.id === m ) {\n\n\t\t\t\t\t\t\tresults.push( elem );\n\t\t\t\t\t\t\treturn results;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t// Type selector\n\t\t\t\t} else if ( match[2] ) {\n\t\t\t\t\tpush.apply( results, context.getElementsByTagName( selector ) );\n\t\t\t\t\treturn results;\n\n\t\t\t\t// Class selector\n\t\t\t\t} else if ( (m = match[3]) && support.getElementsByClassName &&\n\t\t\t\t\tcontext.getElementsByClassName ) {\n\n\t\t\t\t\tpush.apply( results, context.getElementsByClassName( m ) );\n\t\t\t\t\treturn results;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Take advantage of querySelectorAll\n\t\t\tif ( support.qsa &&\n\t\t\t\t!compilerCache[ selector + \" \" ] &&\n\t\t\t\t(!rbuggyQSA || !rbuggyQSA.test( selector )) ) {\n\n\t\t\t\tif ( nodeType !== 1 ) {\n\t\t\t\t\tnewContext = context;\n\t\t\t\t\tnewSelector = selector;\n\n\t\t\t\t// qSA looks outside Element context, which is not what we want\n\t\t\t\t// Thanks to Andrew Dupont for this workaround technique\n\t\t\t\t// Support: IE <=8\n\t\t\t\t// Exclude object elements\n\t\t\t\t} else if ( context.nodeName.toLowerCase() !== \"object\" ) {\n\n\t\t\t\t\t// Capture the context ID, setting it first if necessary\n\t\t\t\t\tif ( (nid = context.getAttribute( \"id\" )) ) {\n\t\t\t\t\t\tnid = nid.replace( rcssescape, fcssescape );\n\t\t\t\t\t} else {\n\t\t\t\t\t\tcontext.setAttribute( \"id\", (nid = expando) );\n\t\t\t\t\t}\n\n\t\t\t\t\t// Prefix every selector in the list\n\t\t\t\t\tgroups = tokenize( selector );\n\t\t\t\t\ti = groups.length;\n\t\t\t\t\twhile ( i-- ) {\n\t\t\t\t\t\tgroups[i] = \"#\" + nid + \" \" + toSelector( groups[i] );\n\t\t\t\t\t}\n\t\t\t\t\tnewSelector = groups.join( \",\" );\n\n\t\t\t\t\t// Expand context for sibling selectors\n\t\t\t\t\tnewContext = rsibling.test( selector ) && testContext( context.parentNode ) ||\n\t\t\t\t\t\tcontext;\n\t\t\t\t}\n\n\t\t\t\tif ( newSelector ) {\n\t\t\t\t\ttry {\n\t\t\t\t\t\tpush.apply( results,\n\t\t\t\t\t\t\tnewContext.querySelectorAll( newSelector )\n\t\t\t\t\t\t);\n\t\t\t\t\t\treturn results;\n\t\t\t\t\t} catch ( qsaError ) {\n\t\t\t\t\t} finally {\n\t\t\t\t\t\tif ( nid === expando ) {\n\t\t\t\t\t\t\tcontext.removeAttribute( \"id\" );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t// All others\n\treturn select( selector.replace( rtrim, \"$1\" ), context, results, seed );\n}\n\n/**\n * Create key-value caches of limited size\n * @returns {function(string, object)} Returns the Object data after storing it on itself with\n *\tproperty name the (space-suffixed) string and (if the cache is larger than Expr.cacheLength)\n *\tdeleting the oldest entry\n */\nfunction createCache() {\n\tvar keys = [];\n\n\tfunction cache( key, value ) {\n\t\t// Use (key + \" \") to avoid collision with native prototype properties (see Issue #157)\n\t\tif ( keys.push( key + \" \" ) > Expr.cacheLength ) {\n\t\t\t// Only keep the most recent entries\n\t\t\tdelete cache[ keys.shift() ];\n\t\t}\n\t\treturn (cache[ key + \" \" ] = value);\n\t}\n\treturn cache;\n}\n\n/**\n * Mark a function for special use by Sizzle\n * @param {Function} fn The function to mark\n */\nfunction markFunction( fn ) {\n\tfn[ expando ] = true;\n\treturn fn;\n}\n\n/**\n * Support testing using an element\n * @param {Function} fn Passed the created element and returns a boolean result\n */\nfunction assert( fn ) {\n\tvar el = document.createElement(\"fieldset\");\n\n\ttry {\n\t\treturn !!fn( el );\n\t} catch (e) {\n\t\treturn false;\n\t} finally {\n\t\t// Remove from its parent by default\n\t\tif ( el.parentNode ) {\n\t\t\tel.parentNode.removeChild( el );\n\t\t}\n\t\t// release memory in IE\n\t\tel = null;\n\t}\n}\n\n/**\n * Adds the same handler for all of the specified attrs\n * @param {String} attrs Pipe-separated list of attributes\n * @param {Function} handler The method that will be applied\n */\nfunction addHandle( attrs, handler ) {\n\tvar arr = attrs.split(\"|\"),\n\t\ti = arr.length;\n\n\twhile ( i-- ) {\n\t\tExpr.attrHandle[ arr[i] ] = handler;\n\t}\n}\n\n/**\n * Checks document order of two siblings\n * @param {Element} a\n * @param {Element} b\n * @returns {Number} Returns less than 0 if a precedes b, greater than 0 if a follows b\n */\nfunction siblingCheck( a, b ) {\n\tvar cur = b && a,\n\t\tdiff = cur && a.nodeType === 1 && b.nodeType === 1 &&\n\t\t\ta.sourceIndex - b.sourceIndex;\n\n\t// Use IE sourceIndex if available on both nodes\n\tif ( diff ) {\n\t\treturn diff;\n\t}\n\n\t// Check if b follows a\n\tif ( cur ) {\n\t\twhile ( (cur = cur.nextSibling) ) {\n\t\t\tif ( cur === b ) {\n\t\t\t\treturn -1;\n\t\t\t}\n\t\t}\n\t}\n\n\treturn a ? 1 : -1;\n}\n\n/**\n * Returns a function to use in pseudos for input types\n * @param {String} type\n */\nfunction createInputPseudo( type ) {\n\treturn function( elem ) {\n\t\tvar name = elem.nodeName.toLowerCase();\n\t\treturn name === \"input\" && elem.type === type;\n\t};\n}\n\n/**\n * Returns a function to use in pseudos for buttons\n * @param {String} type\n */\nfunction createButtonPseudo( type ) {\n\treturn function( elem ) {\n\t\tvar name = elem.nodeName.toLowerCase();\n\t\treturn (name === \"input\" || name === \"button\") && elem.type === type;\n\t};\n}\n\n/**\n * Returns a function to use in pseudos for :enabled/:disabled\n * @param {Boolean} disabled true for :disabled; false for :enabled\n */\nfunction createDisabledPseudo( disabled ) {\n\t// Known :disabled false positives:\n\t// IE: *[disabled]:not(button, input, select, textarea, optgroup, option, menuitem, fieldset)\n\t// not IE: fieldset[disabled] > legend:nth-of-type(n+2) :can-disable\n\treturn function( elem ) {\n\n\t\t// Check form elements and option elements for explicit disabling\n\t\treturn \"label\" in elem && elem.disabled === disabled ||\n\t\t\t\"form\" in elem && elem.disabled === disabled ||\n\n\t\t\t// Check non-disabled form elements for fieldset[disabled] ancestors\n\t\t\t\"form\" in elem && elem.disabled === false && (\n\t\t\t\t// Support: IE6-11+\n\t\t\t\t// Ancestry is covered for us\n\t\t\t\telem.isDisabled === disabled ||\n\n\t\t\t\t// Otherwise, assume any non-<option> under fieldset[disabled] is disabled\n\t\t\t\t/* jshint -W018 */\n\t\t\t\telem.isDisabled !== !disabled &&\n\t\t\t\t\t(\"label\" in elem || !disabledAncestor( elem )) !== disabled\n\t\t\t);\n\t};\n}\n\n/**\n * Returns a function to use in pseudos for positionals\n * @param {Function} fn\n */\nfunction createPositionalPseudo( fn ) {\n\treturn markFunction(function( argument ) {\n\t\targument = +argument;\n\t\treturn markFunction(function( seed, matches ) {\n\t\t\tvar j,\n\t\t\t\tmatchIndexes = fn( [], seed.length, argument ),\n\t\t\t\ti = matchIndexes.length;\n\n\t\t\t// Match elements found at the specified indexes\n\t\t\twhile ( i-- ) {\n\t\t\t\tif ( seed[ (j = matchIndexes[i]) ] ) {\n\t\t\t\t\tseed[j] = !(matches[j] = seed[j]);\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\t});\n}\n\n/**\n * Checks a node for validity as a Sizzle context\n * @param {Element|Object=} context\n * @returns {Element|Object|Boolean} The input node if acceptable, otherwise a falsy value\n */\nfunction testContext( context ) {\n\treturn context && typeof context.getElementsByTagName !== \"undefined\" && context;\n}\n\n// Expose support vars for convenience\nsupport = Sizzle.support = {};\n\n/**\n * Detects XML nodes\n * @param {Element|Object} elem An element or a document\n * @returns {Boolean} True iff elem is a non-HTML XML node\n */\nisXML = Sizzle.isXML = function( elem ) {\n\t// documentElement is verified for cases where it doesn't yet exist\n\t// (such as loading iframes in IE - #4833)\n\tvar documentElement = elem && (elem.ownerDocument || elem).documentElement;\n\treturn documentElement ? documentElement.nodeName !== \"HTML\" : false;\n};\n\n/**\n * Sets document-related variables once based on the current document\n * @param {Element|Object} [doc] An element or document object to use to set the document\n * @returns {Object} Returns the current document\n */\nsetDocument = Sizzle.setDocument = function( node ) {\n\tvar hasCompare, subWindow,\n\t\tdoc = node ? node.ownerDocument || node : preferredDoc;\n\n\t// Return early if doc is invalid or already selected\n\tif ( doc === document || doc.nodeType !== 9 || !doc.documentElement ) {\n\t\treturn document;\n\t}\n\n\t// Update global variables\n\tdocument = doc;\n\tdocElem = document.documentElement;\n\tdocumentIsHTML = !isXML( document );\n\n\t// Support: IE 9-11, Edge\n\t// Accessing iframe documents after unload throws \"permission denied\" errors (jQuery #13936)\n\tif ( preferredDoc !== document &&\n\t\t(subWindow = document.defaultView) && subWindow.top !== subWindow ) {\n\n\t\t// Support: IE 11, Edge\n\t\tif ( subWindow.addEventListener ) {\n\t\t\tsubWindow.addEventListener( \"unload\", unloadHandler, false );\n\n\t\t// Support: IE 9 - 10 only\n\t\t} else if ( subWindow.attachEvent ) {\n\t\t\tsubWindow.attachEvent( \"onunload\", unloadHandler );\n\t\t}\n\t}\n\n\t/* Attributes\n\t---------------------------------------------------------------------- */\n\n\t// Support: IE<8\n\t// Verify that getAttribute really returns attributes and not properties\n\t// (excepting IE8 booleans)\n\tsupport.attributes = assert(function( el ) {\n\t\tel.className = \"i\";\n\t\treturn !el.getAttribute(\"className\");\n\t});\n\n\t/* getElement(s)By*\n\t---------------------------------------------------------------------- */\n\n\t// Check if getElementsByTagName(\"*\") returns only elements\n\tsupport.getElementsByTagName = assert(function( el ) {\n\t\tel.appendChild( document.createComment(\"\") );\n\t\treturn !el.getElementsByTagName(\"*\").length;\n\t});\n\n\t// Support: IE<9\n\tsupport.getElementsByClassName = rnative.test( document.getElementsByClassName );\n\n\t// Support: IE<10\n\t// Check if getElementById returns elements by name\n\t// The broken getElementById methods don't pick up programmatically-set names,\n\t// so use a roundabout getElementsByName test\n\tsupport.getById = assert(function( el ) {\n\t\tdocElem.appendChild( el ).id = expando;\n\t\treturn !document.getElementsByName || !document.getElementsByName( expando ).length;\n\t});\n\n\t// ID find and filter\n\tif ( support.getById ) {\n\t\tExpr.find[\"ID\"] = function( id, context ) {\n\t\t\tif ( typeof context.getElementById !== \"undefined\" && documentIsHTML ) {\n\t\t\t\tvar m = context.getElementById( id );\n\t\t\t\treturn m ? [ m ] : [];\n\t\t\t}\n\t\t};\n\t\tExpr.filter[\"ID\"] = function( id ) {\n\t\t\tvar attrId = id.replace( runescape, funescape );\n\t\t\treturn function( elem ) {\n\t\t\t\treturn elem.getAttribute(\"id\") === attrId;\n\t\t\t};\n\t\t};\n\t} else {\n\t\t// Support: IE6/7\n\t\t// getElementById is not reliable as a find shortcut\n\t\tdelete Expr.find[\"ID\"];\n\n\t\tExpr.filter[\"ID\"] =  function( id ) {\n\t\t\tvar attrId = id.replace( runescape, funescape );\n\t\t\treturn function( elem ) {\n\t\t\t\tvar node = typeof elem.getAttributeNode !== \"undefined\" &&\n\t\t\t\t\telem.getAttributeNode(\"id\");\n\t\t\t\treturn node && node.value === attrId;\n\t\t\t};\n\t\t};\n\t}\n\n\t// Tag\n\tExpr.find[\"TAG\"] = support.getElementsByTagName ?\n\t\tfunction( tag, context ) {\n\t\t\tif ( typeof context.getElementsByTagName !== \"undefined\" ) {\n\t\t\t\treturn context.getElementsByTagName( tag );\n\n\t\t\t// DocumentFragment nodes don't have gEBTN\n\t\t\t} else if ( support.qsa ) {\n\t\t\t\treturn context.querySelectorAll( tag );\n\t\t\t}\n\t\t} :\n\n\t\tfunction( tag, context ) {\n\t\t\tvar elem,\n\t\t\t\ttmp = [],\n\t\t\t\ti = 0,\n\t\t\t\t// By happy coincidence, a (broken) gEBTN appears on DocumentFragment nodes too\n\t\t\t\tresults = context.getElementsByTagName( tag );\n\n\t\t\t// Filter out possible comments\n\t\t\tif ( tag === \"*\" ) {\n\t\t\t\twhile ( (elem = results[i++]) ) {\n\t\t\t\t\tif ( elem.nodeType === 1 ) {\n\t\t\t\t\t\ttmp.push( elem );\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\treturn tmp;\n\t\t\t}\n\t\t\treturn results;\n\t\t};\n\n\t// Class\n\tExpr.find[\"CLASS\"] = support.getElementsByClassName && function( className, context ) {\n\t\tif ( typeof context.getElementsByClassName !== \"undefined\" && documentIsHTML ) {\n\t\t\treturn context.getElementsByClassName( className );\n\t\t}\n\t};\n\n\t/* QSA/matchesSelector\n\t---------------------------------------------------------------------- */\n\n\t// QSA and matchesSelector support\n\n\t// matchesSelector(:active) reports false when true (IE9/Opera 11.5)\n\trbuggyMatches = [];\n\n\t// qSa(:focus) reports false when true (Chrome 21)\n\t// We allow this because of a bug in IE8/9 that throws an error\n\t// whenever `document.activeElement` is accessed on an iframe\n\t// So, we allow :focus to pass through QSA all the time to avoid the IE error\n\t// See https://bugs.jquery.com/ticket/13378\n\trbuggyQSA = [];\n\n\tif ( (support.qsa = rnative.test( document.querySelectorAll )) ) {\n\t\t// Build QSA regex\n\t\t// Regex strategy adopted from Diego Perini\n\t\tassert(function( el ) {\n\t\t\t// Select is set to empty string on purpose\n\t\t\t// This is to test IE's treatment of not explicitly\n\t\t\t// setting a boolean content attribute,\n\t\t\t// since its presence should be enough\n\t\t\t// https://bugs.jquery.com/ticket/12359\n\t\t\tdocElem.appendChild( el ).innerHTML = \"<a id='\" + expando + \"'></a>\" +\n\t\t\t\t\"<select id='\" + expando + \"-\\r\\\\' msallowcapture=''>\" +\n\t\t\t\t\"<option selected=''></option></select>\";\n\n\t\t\t// Support: IE8, Opera 11-12.16\n\t\t\t// Nothing should be selected when empty strings follow ^= or $= or *=\n\t\t\t// The test attribute must be unknown in Opera but \"safe\" for WinRT\n\t\t\t// https://msdn.microsoft.com/en-us/library/ie/hh465388.aspx#attribute_section\n\t\t\tif ( el.querySelectorAll(\"[msallowcapture^='']\").length ) {\n\t\t\t\trbuggyQSA.push( \"[*^$]=\" + whitespace + \"*(?:''|\\\"\\\")\" );\n\t\t\t}\n\n\t\t\t// Support: IE8\n\t\t\t// Boolean attributes and \"value\" are not treated correctly\n\t\t\tif ( !el.querySelectorAll(\"[selected]\").length ) {\n\t\t\t\trbuggyQSA.push( \"\\\\[\" + whitespace + \"*(?:value|\" + booleans + \")\" );\n\t\t\t}\n\n\t\t\t// Support: Chrome<29, Android<4.4, Safari<7.0+, iOS<7.0+, PhantomJS<1.9.8+\n\t\t\tif ( !el.querySelectorAll( \"[id~=\" + expando + \"-]\" ).length ) {\n\t\t\t\trbuggyQSA.push(\"~=\");\n\t\t\t}\n\n\t\t\t// Webkit/Opera - :checked should return selected option elements\n\t\t\t// http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked\n\t\t\t// IE8 throws error here and will not see later tests\n\t\t\tif ( !el.querySelectorAll(\":checked\").length ) {\n\t\t\t\trbuggyQSA.push(\":checked\");\n\t\t\t}\n\n\t\t\t// Support: Safari 8+, iOS 8+\n\t\t\t// https://bugs.webkit.org/show_bug.cgi?id=136851\n\t\t\t// In-page `selector#id sibling-combinator selector` fails\n\t\t\tif ( !el.querySelectorAll( \"a#\" + expando + \"+*\" ).length ) {\n\t\t\t\trbuggyQSA.push(\".#.+[+~]\");\n\t\t\t}\n\t\t});\n\n\t\tassert(function( el ) {\n\t\t\tel.innerHTML = \"<a href='' disabled='disabled'></a>\" +\n\t\t\t\t\"<select disabled='disabled'><option/></select>\";\n\n\t\t\t// Support: Windows 8 Native Apps\n\t\t\t// The type and name attributes are restricted during .innerHTML assignment\n\t\t\tvar input = document.createElement(\"input\");\n\t\t\tinput.setAttribute( \"type\", \"hidden\" );\n\t\t\tel.appendChild( input ).setAttribute( \"name\", \"D\" );\n\n\t\t\t// Support: IE8\n\t\t\t// Enforce case-sensitivity of name attribute\n\t\t\tif ( el.querySelectorAll(\"[name=d]\").length ) {\n\t\t\t\trbuggyQSA.push( \"name\" + whitespace + \"*[*^$|!~]?=\" );\n\t\t\t}\n\n\t\t\t// FF 3.5 - :enabled/:disabled and hidden elements (hidden elements are still enabled)\n\t\t\t// IE8 throws error here and will not see later tests\n\t\t\tif ( el.querySelectorAll(\":enabled\").length !== 2 ) {\n\t\t\t\trbuggyQSA.push( \":enabled\", \":disabled\" );\n\t\t\t}\n\n\t\t\t// Support: IE9-11+\n\t\t\t// IE's :disabled selector does not pick up the children of disabled fieldsets\n\t\t\tdocElem.appendChild( el ).disabled = true;\n\t\t\tif ( el.querySelectorAll(\":disabled\").length !== 2 ) {\n\t\t\t\trbuggyQSA.push( \":enabled\", \":disabled\" );\n\t\t\t}\n\n\t\t\t// Opera 10-11 does not throw on post-comma invalid pseudos\n\t\t\tel.querySelectorAll(\"*,:x\");\n\t\t\trbuggyQSA.push(\",.*:\");\n\t\t});\n\t}\n\n\tif ( (support.matchesSelector = rnative.test( (matches = docElem.matches ||\n\t\tdocElem.webkitMatchesSelector ||\n\t\tdocElem.mozMatchesSelector ||\n\t\tdocElem.oMatchesSelector ||\n\t\tdocElem.msMatchesSelector) )) ) {\n\n\t\tassert(function( el ) {\n\t\t\t// Check to see if it's possible to do matchesSelector\n\t\t\t// on a disconnected node (IE 9)\n\t\t\tsupport.disconnectedMatch = matches.call( el, \"*\" );\n\n\t\t\t// This should fail with an exception\n\t\t\t// Gecko does not error, returns false instead\n\t\t\tmatches.call( el, \"[s!='']:x\" );\n\t\t\trbuggyMatches.push( \"!=\", pseudos );\n\t\t});\n\t}\n\n\trbuggyQSA = rbuggyQSA.length && new RegExp( rbuggyQSA.join(\"|\") );\n\trbuggyMatches = rbuggyMatches.length && new RegExp( rbuggyMatches.join(\"|\") );\n\n\t/* Contains\n\t---------------------------------------------------------------------- */\n\thasCompare = rnative.test( docElem.compareDocumentPosition );\n\n\t// Element contains another\n\t// Purposefully self-exclusive\n\t// As in, an element does not contain itself\n\tcontains = hasCompare || rnative.test( docElem.contains ) ?\n\t\tfunction( a, b ) {\n\t\t\tvar adown = a.nodeType === 9 ? a.documentElement : a,\n\t\t\t\tbup = b && b.parentNode;\n\t\t\treturn a === bup || !!( bup && bup.nodeType === 1 && (\n\t\t\t\tadown.contains ?\n\t\t\t\t\tadown.contains( bup ) :\n\t\t\t\t\ta.compareDocumentPosition && a.compareDocumentPosition( bup ) & 16\n\t\t\t));\n\t\t} :\n\t\tfunction( a, b ) {\n\t\t\tif ( b ) {\n\t\t\t\twhile ( (b = b.parentNode) ) {\n\t\t\t\t\tif ( b === a ) {\n\t\t\t\t\t\treturn true;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn false;\n\t\t};\n\n\t/* Sorting\n\t---------------------------------------------------------------------- */\n\n\t// Document order sorting\n\tsortOrder = hasCompare ?\n\tfunction( a, b ) {\n\n\t\t// Flag for duplicate removal\n\t\tif ( a === b ) {\n\t\t\thasDuplicate = true;\n\t\t\treturn 0;\n\t\t}\n\n\t\t// Sort on method existence if only one input has compareDocumentPosition\n\t\tvar compare = !a.compareDocumentPosition - !b.compareDocumentPosition;\n\t\tif ( compare ) {\n\t\t\treturn compare;\n\t\t}\n\n\t\t// Calculate position if both inputs belong to the same document\n\t\tcompare = ( a.ownerDocument || a ) === ( b.ownerDocument || b ) ?\n\t\t\ta.compareDocumentPosition( b ) :\n\n\t\t\t// Otherwise we know they are disconnected\n\t\t\t1;\n\n\t\t// Disconnected nodes\n\t\tif ( compare & 1 ||\n\t\t\t(!support.sortDetached && b.compareDocumentPosition( a ) === compare) ) {\n\n\t\t\t// Choose the first element that is related to our preferred document\n\t\t\tif ( a === document || a.ownerDocument === preferredDoc && contains(preferredDoc, a) ) {\n\t\t\t\treturn -1;\n\t\t\t}\n\t\t\tif ( b === document || b.ownerDocument === preferredDoc && contains(preferredDoc, b) ) {\n\t\t\t\treturn 1;\n\t\t\t}\n\n\t\t\t// Maintain original order\n\t\t\treturn sortInput ?\n\t\t\t\t( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) :\n\t\t\t\t0;\n\t\t}\n\n\t\treturn compare & 4 ? -1 : 1;\n\t} :\n\tfunction( a, b ) {\n\t\t// Exit early if the nodes are identical\n\t\tif ( a === b ) {\n\t\t\thasDuplicate = true;\n\t\t\treturn 0;\n\t\t}\n\n\t\tvar cur,\n\t\t\ti = 0,\n\t\t\taup = a.parentNode,\n\t\t\tbup = b.parentNode,\n\t\t\tap = [ a ],\n\t\t\tbp = [ b ];\n\n\t\t// Parentless nodes are either documents or disconnected\n\t\tif ( !aup || !bup ) {\n\t\t\treturn a === document ? -1 :\n\t\t\t\tb === document ? 1 :\n\t\t\t\taup ? -1 :\n\t\t\t\tbup ? 1 :\n\t\t\t\tsortInput ?\n\t\t\t\t( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) :\n\t\t\t\t0;\n\n\t\t// If the nodes are siblings, we can do a quick check\n\t\t} else if ( aup === bup ) {\n\t\t\treturn siblingCheck( a, b );\n\t\t}\n\n\t\t// Otherwise we need full lists of their ancestors for comparison\n\t\tcur = a;\n\t\twhile ( (cur = cur.parentNode) ) {\n\t\t\tap.unshift( cur );\n\t\t}\n\t\tcur = b;\n\t\twhile ( (cur = cur.parentNode) ) {\n\t\t\tbp.unshift( cur );\n\t\t}\n\n\t\t// Walk down the tree looking for a discrepancy\n\t\twhile ( ap[i] === bp[i] ) {\n\t\t\ti++;\n\t\t}\n\n\t\treturn i ?\n\t\t\t// Do a sibling check if the nodes have a common ancestor\n\t\t\tsiblingCheck( ap[i], bp[i] ) :\n\n\t\t\t// Otherwise nodes in our document sort first\n\t\t\tap[i] === preferredDoc ? -1 :\n\t\t\tbp[i] === preferredDoc ? 1 :\n\t\t\t0;\n\t};\n\n\treturn document;\n};\n\nSizzle.matches = function( expr, elements ) {\n\treturn Sizzle( expr, null, null, elements );\n};\n\nSizzle.matchesSelector = function( elem, expr ) {\n\t// Set document vars if needed\n\tif ( ( elem.ownerDocument || elem ) !== document ) {\n\t\tsetDocument( elem );\n\t}\n\n\t// Make sure that attribute selectors are quoted\n\texpr = expr.replace( rattributeQuotes, \"='$1']\" );\n\n\tif ( support.matchesSelector && documentIsHTML &&\n\t\t!compilerCache[ expr + \" \" ] &&\n\t\t( !rbuggyMatches || !rbuggyMatches.test( expr ) ) &&\n\t\t( !rbuggyQSA     || !rbuggyQSA.test( expr ) ) ) {\n\n\t\ttry {\n\t\t\tvar ret = matches.call( elem, expr );\n\n\t\t\t// IE 9's matchesSelector returns false on disconnected nodes\n\t\t\tif ( ret || support.disconnectedMatch ||\n\t\t\t\t\t// As well, disconnected nodes are said to be in a document\n\t\t\t\t\t// fragment in IE 9\n\t\t\t\t\telem.document && elem.document.nodeType !== 11 ) {\n\t\t\t\treturn ret;\n\t\t\t}\n\t\t} catch (e) {}\n\t}\n\n\treturn Sizzle( expr, document, null, [ elem ] ).length > 0;\n};\n\nSizzle.contains = function( context, elem ) {\n\t// Set document vars if needed\n\tif ( ( context.ownerDocument || context ) !== document ) {\n\t\tsetDocument( context );\n\t}\n\treturn contains( context, elem );\n};\n\nSizzle.attr = function( elem, name ) {\n\t// Set document vars if needed\n\tif ( ( elem.ownerDocument || elem ) !== document ) {\n\t\tsetDocument( elem );\n\t}\n\n\tvar fn = Expr.attrHandle[ name.toLowerCase() ],\n\t\t// Don't get fooled by Object.prototype properties (jQuery #13807)\n\t\tval = fn && hasOwn.call( Expr.attrHandle, name.toLowerCase() ) ?\n\t\t\tfn( elem, name, !documentIsHTML ) :\n\t\t\tundefined;\n\n\treturn val !== undefined ?\n\t\tval :\n\t\tsupport.attributes || !documentIsHTML ?\n\t\t\telem.getAttribute( name ) :\n\t\t\t(val = elem.getAttributeNode(name)) && val.specified ?\n\t\t\t\tval.value :\n\t\t\t\tnull;\n};\n\nSizzle.escape = function( sel ) {\n\treturn (sel + \"\").replace( rcssescape, fcssescape );\n};\n\nSizzle.error = function( msg ) {\n\tthrow new Error( \"Syntax error, unrecognized expression: \" + msg );\n};\n\n/**\n * Document sorting and removing duplicates\n * @param {ArrayLike} results\n */\nSizzle.uniqueSort = function( results ) {\n\tvar elem,\n\t\tduplicates = [],\n\t\tj = 0,\n\t\ti = 0;\n\n\t// Unless we *know* we can detect duplicates, assume their presence\n\thasDuplicate = !support.detectDuplicates;\n\tsortInput = !support.sortStable && results.slice( 0 );\n\tresults.sort( sortOrder );\n\n\tif ( hasDuplicate ) {\n\t\twhile ( (elem = results[i++]) ) {\n\t\t\tif ( elem === results[ i ] ) {\n\t\t\t\tj = duplicates.push( i );\n\t\t\t}\n\t\t}\n\t\twhile ( j-- ) {\n\t\t\tresults.splice( duplicates[ j ], 1 );\n\t\t}\n\t}\n\n\t// Clear input after sorting to release objects\n\t// See https://github.com/jquery/sizzle/pull/225\n\tsortInput = null;\n\n\treturn results;\n};\n\n/**\n * Utility function for retrieving the text value of an array of DOM nodes\n * @param {Array|Element} elem\n */\ngetText = Sizzle.getText = function( elem ) {\n\tvar node,\n\t\tret = \"\",\n\t\ti = 0,\n\t\tnodeType = elem.nodeType;\n\n\tif ( !nodeType ) {\n\t\t// If no nodeType, this is expected to be an array\n\t\twhile ( (node = elem[i++]) ) {\n\t\t\t// Do not traverse comment nodes\n\t\t\tret += getText( node );\n\t\t}\n\t} else if ( nodeType === 1 || nodeType === 9 || nodeType === 11 ) {\n\t\t// Use textContent for elements\n\t\t// innerText usage removed for consistency of new lines (jQuery #11153)\n\t\tif ( typeof elem.textContent === \"string\" ) {\n\t\t\treturn elem.textContent;\n\t\t} else {\n\t\t\t// Traverse its children\n\t\t\tfor ( elem = elem.firstChild; elem; elem = elem.nextSibling ) {\n\t\t\t\tret += getText( elem );\n\t\t\t}\n\t\t}\n\t} else if ( nodeType === 3 || nodeType === 4 ) {\n\t\treturn elem.nodeValue;\n\t}\n\t// Do not include comment or processing instruction nodes\n\n\treturn ret;\n};\n\nExpr = Sizzle.selectors = {\n\n\t// Can be adjusted by the user\n\tcacheLength: 50,\n\n\tcreatePseudo: markFunction,\n\n\tmatch: matchExpr,\n\n\tattrHandle: {},\n\n\tfind: {},\n\n\trelative: {\n\t\t\">\": { dir: \"parentNode\", first: true },\n\t\t\" \": { dir: \"parentNode\" },\n\t\t\"+\": { dir: \"previousSibling\", first: true },\n\t\t\"~\": { dir: \"previousSibling\" }\n\t},\n\n\tpreFilter: {\n\t\t\"ATTR\": function( match ) {\n\t\t\tmatch[1] = match[1].replace( runescape, funescape );\n\n\t\t\t// Move the given value to match[3] whether quoted or unquoted\n\t\t\tmatch[3] = ( match[3] || match[4] || match[5] || \"\" ).replace( runescape, funescape );\n\n\t\t\tif ( match[2] === \"~=\" ) {\n\t\t\t\tmatch[3] = \" \" + match[3] + \" \";\n\t\t\t}\n\n\t\t\treturn match.slice( 0, 4 );\n\t\t},\n\n\t\t\"CHILD\": function( match ) {\n\t\t\t/* matches from matchExpr[\"CHILD\"]\n\t\t\t\t1 type (only|nth|...)\n\t\t\t\t2 what (child|of-type)\n\t\t\t\t3 argument (even|odd|\\d*|\\d*n([+-]\\d+)?|...)\n\t\t\t\t4 xn-component of xn+y argument ([+-]?\\d*n|)\n\t\t\t\t5 sign of xn-component\n\t\t\t\t6 x of xn-component\n\t\t\t\t7 sign of y-component\n\t\t\t\t8 y of y-component\n\t\t\t*/\n\t\t\tmatch[1] = match[1].toLowerCase();\n\n\t\t\tif ( match[1].slice( 0, 3 ) === \"nth\" ) {\n\t\t\t\t// nth-* requires argument\n\t\t\t\tif ( !match[3] ) {\n\t\t\t\t\tSizzle.error( match[0] );\n\t\t\t\t}\n\n\t\t\t\t// numeric x and y parameters for Expr.filter.CHILD\n\t\t\t\t// remember that false/true cast respectively to 0/1\n\t\t\t\tmatch[4] = +( match[4] ? match[5] + (match[6] || 1) : 2 * ( match[3] === \"even\" || match[3] === \"odd\" ) );\n\t\t\t\tmatch[5] = +( ( match[7] + match[8] ) || match[3] === \"odd\" );\n\n\t\t\t// other types prohibit arguments\n\t\t\t} else if ( match[3] ) {\n\t\t\t\tSizzle.error( match[0] );\n\t\t\t}\n\n\t\t\treturn match;\n\t\t},\n\n\t\t\"PSEUDO\": function( match ) {\n\t\t\tvar excess,\n\t\t\t\tunquoted = !match[6] && match[2];\n\n\t\t\tif ( matchExpr[\"CHILD\"].test( match[0] ) ) {\n\t\t\t\treturn null;\n\t\t\t}\n\n\t\t\t// Accept quoted arguments as-is\n\t\t\tif ( match[3] ) {\n\t\t\t\tmatch[2] = match[4] || match[5] || \"\";\n\n\t\t\t// Strip excess characters from unquoted arguments\n\t\t\t} else if ( unquoted && rpseudo.test( unquoted ) &&\n\t\t\t\t// Get excess from tokenize (recursively)\n\t\t\t\t(excess = tokenize( unquoted, true )) &&\n\t\t\t\t// advance to the next closing parenthesis\n\t\t\t\t(excess = unquoted.indexOf( \")\", unquoted.length - excess ) - unquoted.length) ) {\n\n\t\t\t\t// excess is a negative index\n\t\t\t\tmatch[0] = match[0].slice( 0, excess );\n\t\t\t\tmatch[2] = unquoted.slice( 0, excess );\n\t\t\t}\n\n\t\t\t// Return only captures needed by the pseudo filter method (type and argument)\n\t\t\treturn match.slice( 0, 3 );\n\t\t}\n\t},\n\n\tfilter: {\n\n\t\t\"TAG\": function( nodeNameSelector ) {\n\t\t\tvar nodeName = nodeNameSelector.replace( runescape, funescape ).toLowerCase();\n\t\t\treturn nodeNameSelector === \"*\" ?\n\t\t\t\tfunction() { return true; } :\n\t\t\t\tfunction( elem ) {\n\t\t\t\t\treturn elem.nodeName && elem.nodeName.toLowerCase() === nodeName;\n\t\t\t\t};\n\t\t},\n\n\t\t\"CLASS\": function( className ) {\n\t\t\tvar pattern = classCache[ className + \" \" ];\n\n\t\t\treturn pattern ||\n\t\t\t\t(pattern = new RegExp( \"(^|\" + whitespace + \")\" + className + \"(\" + whitespace + \"|$)\" )) &&\n\t\t\t\tclassCache( className, function( elem ) {\n\t\t\t\t\treturn pattern.test( typeof elem.className === \"string\" && elem.className || typeof elem.getAttribute !== \"undefined\" && elem.getAttribute(\"class\") || \"\" );\n\t\t\t\t});\n\t\t},\n\n\t\t\"ATTR\": function( name, operator, check ) {\n\t\t\treturn function( elem ) {\n\t\t\t\tvar result = Sizzle.attr( elem, name );\n\n\t\t\t\tif ( result == null ) {\n\t\t\t\t\treturn operator === \"!=\";\n\t\t\t\t}\n\t\t\t\tif ( !operator ) {\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\n\t\t\t\tresult += \"\";\n\n\t\t\t\treturn operator === \"=\" ? result === check :\n\t\t\t\t\toperator === \"!=\" ? result !== check :\n\t\t\t\t\toperator === \"^=\" ? check && result.indexOf( check ) === 0 :\n\t\t\t\t\toperator === \"*=\" ? check && result.indexOf( check ) > -1 :\n\t\t\t\t\toperator === \"$=\" ? check && result.slice( -check.length ) === check :\n\t\t\t\t\toperator === \"~=\" ? ( \" \" + result.replace( rwhitespace, \" \" ) + \" \" ).indexOf( check ) > -1 :\n\t\t\t\t\toperator === \"|=\" ? result === check || result.slice( 0, check.length + 1 ) === check + \"-\" :\n\t\t\t\t\tfalse;\n\t\t\t};\n\t\t},\n\n\t\t\"CHILD\": function( type, what, argument, first, last ) {\n\t\t\tvar simple = type.slice( 0, 3 ) !== \"nth\",\n\t\t\t\tforward = type.slice( -4 ) !== \"last\",\n\t\t\t\tofType = what === \"of-type\";\n\n\t\t\treturn first === 1 && last === 0 ?\n\n\t\t\t\t// Shortcut for :nth-*(n)\n\t\t\t\tfunction( elem ) {\n\t\t\t\t\treturn !!elem.parentNode;\n\t\t\t\t} :\n\n\t\t\t\tfunction( elem, context, xml ) {\n\t\t\t\t\tvar cache, uniqueCache, outerCache, node, nodeIndex, start,\n\t\t\t\t\t\tdir = simple !== forward ? \"nextSibling\" : \"previousSibling\",\n\t\t\t\t\t\tparent = elem.parentNode,\n\t\t\t\t\t\tname = ofType && elem.nodeName.toLowerCase(),\n\t\t\t\t\t\tuseCache = !xml && !ofType,\n\t\t\t\t\t\tdiff = false;\n\n\t\t\t\t\tif ( parent ) {\n\n\t\t\t\t\t\t// :(first|last|only)-(child|of-type)\n\t\t\t\t\t\tif ( simple ) {\n\t\t\t\t\t\t\twhile ( dir ) {\n\t\t\t\t\t\t\t\tnode = elem;\n\t\t\t\t\t\t\t\twhile ( (node = node[ dir ]) ) {\n\t\t\t\t\t\t\t\t\tif ( ofType ?\n\t\t\t\t\t\t\t\t\t\tnode.nodeName.toLowerCase() === name :\n\t\t\t\t\t\t\t\t\t\tnode.nodeType === 1 ) {\n\n\t\t\t\t\t\t\t\t\t\treturn false;\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t// Reverse direction for :only-* (if we haven't yet done so)\n\t\t\t\t\t\t\t\tstart = dir = type === \"only\" && !start && \"nextSibling\";\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\treturn true;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tstart = [ forward ? parent.firstChild : parent.lastChild ];\n\n\t\t\t\t\t\t// non-xml :nth-child(...) stores cache data on `parent`\n\t\t\t\t\t\tif ( forward && useCache ) {\n\n\t\t\t\t\t\t\t// Seek `elem` from a previously-cached index\n\n\t\t\t\t\t\t\t// ...in a gzip-friendly way\n\t\t\t\t\t\t\tnode = parent;\n\t\t\t\t\t\t\touterCache = node[ expando ] || (node[ expando ] = {});\n\n\t\t\t\t\t\t\t// Support: IE <9 only\n\t\t\t\t\t\t\t// Defend against cloned attroperties (jQuery gh-1709)\n\t\t\t\t\t\t\tuniqueCache = outerCache[ node.uniqueID ] ||\n\t\t\t\t\t\t\t\t(outerCache[ node.uniqueID ] = {});\n\n\t\t\t\t\t\t\tcache = uniqueCache[ type ] || [];\n\t\t\t\t\t\t\tnodeIndex = cache[ 0 ] === dirruns && cache[ 1 ];\n\t\t\t\t\t\t\tdiff = nodeIndex && cache[ 2 ];\n\t\t\t\t\t\t\tnode = nodeIndex && parent.childNodes[ nodeIndex ];\n\n\t\t\t\t\t\t\twhile ( (node = ++nodeIndex && node && node[ dir ] ||\n\n\t\t\t\t\t\t\t\t// Fallback to seeking `elem` from the start\n\t\t\t\t\t\t\t\t(diff = nodeIndex = 0) || start.pop()) ) {\n\n\t\t\t\t\t\t\t\t// When found, cache indexes on `parent` and break\n\t\t\t\t\t\t\t\tif ( node.nodeType === 1 && ++diff && node === elem ) {\n\t\t\t\t\t\t\t\t\tuniqueCache[ type ] = [ dirruns, nodeIndex, diff ];\n\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t// Use previously-cached element index if available\n\t\t\t\t\t\t\tif ( useCache ) {\n\t\t\t\t\t\t\t\t// ...in a gzip-friendly way\n\t\t\t\t\t\t\t\tnode = elem;\n\t\t\t\t\t\t\t\touterCache = node[ expando ] || (node[ expando ] = {});\n\n\t\t\t\t\t\t\t\t// Support: IE <9 only\n\t\t\t\t\t\t\t\t// Defend against cloned attroperties (jQuery gh-1709)\n\t\t\t\t\t\t\t\tuniqueCache = outerCache[ node.uniqueID ] ||\n\t\t\t\t\t\t\t\t\t(outerCache[ node.uniqueID ] = {});\n\n\t\t\t\t\t\t\t\tcache = uniqueCache[ type ] || [];\n\t\t\t\t\t\t\t\tnodeIndex = cache[ 0 ] === dirruns && cache[ 1 ];\n\t\t\t\t\t\t\t\tdiff = nodeIndex;\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t// xml :nth-child(...)\n\t\t\t\t\t\t\t// or :nth-last-child(...) or :nth(-last)?-of-type(...)\n\t\t\t\t\t\t\tif ( diff === false ) {\n\t\t\t\t\t\t\t\t// Use the same loop as above to seek `elem` from the start\n\t\t\t\t\t\t\t\twhile ( (node = ++nodeIndex && node && node[ dir ] ||\n\t\t\t\t\t\t\t\t\t(diff = nodeIndex = 0) || start.pop()) ) {\n\n\t\t\t\t\t\t\t\t\tif ( ( ofType ?\n\t\t\t\t\t\t\t\t\t\tnode.nodeName.toLowerCase() === name :\n\t\t\t\t\t\t\t\t\t\tnode.nodeType === 1 ) &&\n\t\t\t\t\t\t\t\t\t\t++diff ) {\n\n\t\t\t\t\t\t\t\t\t\t// Cache the index of each encountered element\n\t\t\t\t\t\t\t\t\t\tif ( useCache ) {\n\t\t\t\t\t\t\t\t\t\t\touterCache = node[ expando ] || (node[ expando ] = {});\n\n\t\t\t\t\t\t\t\t\t\t\t// Support: IE <9 only\n\t\t\t\t\t\t\t\t\t\t\t// Defend against cloned attroperties (jQuery gh-1709)\n\t\t\t\t\t\t\t\t\t\t\tuniqueCache = outerCache[ node.uniqueID ] ||\n\t\t\t\t\t\t\t\t\t\t\t\t(outerCache[ node.uniqueID ] = {});\n\n\t\t\t\t\t\t\t\t\t\t\tuniqueCache[ type ] = [ dirruns, diff ];\n\t\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t\t\tif ( node === elem ) {\n\t\t\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// Incorporate the offset, then check against cycle size\n\t\t\t\t\t\tdiff -= last;\n\t\t\t\t\t\treturn diff === first || ( diff % first === 0 && diff / first >= 0 );\n\t\t\t\t\t}\n\t\t\t\t};\n\t\t},\n\n\t\t\"PSEUDO\": function( pseudo, argument ) {\n\t\t\t// pseudo-class names are case-insensitive\n\t\t\t// http://www.w3.org/TR/selectors/#pseudo-classes\n\t\t\t// Prioritize by case sensitivity in case custom pseudos are added with uppercase letters\n\t\t\t// Remember that setFilters inherits from pseudos\n\t\t\tvar args,\n\t\t\t\tfn = Expr.pseudos[ pseudo ] || Expr.setFilters[ pseudo.toLowerCase() ] ||\n\t\t\t\t\tSizzle.error( \"unsupported pseudo: \" + pseudo );\n\n\t\t\t// The user may use createPseudo to indicate that\n\t\t\t// arguments are needed to create the filter function\n\t\t\t// just as Sizzle does\n\t\t\tif ( fn[ expando ] ) {\n\t\t\t\treturn fn( argument );\n\t\t\t}\n\n\t\t\t// But maintain support for old signatures\n\t\t\tif ( fn.length > 1 ) {\n\t\t\t\targs = [ pseudo, pseudo, \"\", argument ];\n\t\t\t\treturn Expr.setFilters.hasOwnProperty( pseudo.toLowerCase() ) ?\n\t\t\t\t\tmarkFunction(function( seed, matches ) {\n\t\t\t\t\t\tvar idx,\n\t\t\t\t\t\t\tmatched = fn( seed, argument ),\n\t\t\t\t\t\t\ti = matched.length;\n\t\t\t\t\t\twhile ( i-- ) {\n\t\t\t\t\t\t\tidx = indexOf( seed, matched[i] );\n\t\t\t\t\t\t\tseed[ idx ] = !( matches[ idx ] = matched[i] );\n\t\t\t\t\t\t}\n\t\t\t\t\t}) :\n\t\t\t\t\tfunction( elem ) {\n\t\t\t\t\t\treturn fn( elem, 0, args );\n\t\t\t\t\t};\n\t\t\t}\n\n\t\t\treturn fn;\n\t\t}\n\t},\n\n\tpseudos: {\n\t\t// Potentially complex pseudos\n\t\t\"not\": markFunction(function( selector ) {\n\t\t\t// Trim the selector passed to compile\n\t\t\t// to avoid treating leading and trailing\n\t\t\t// spaces as combinators\n\t\t\tvar input = [],\n\t\t\t\tresults = [],\n\t\t\t\tmatcher = compile( selector.replace( rtrim, \"$1\" ) );\n\n\t\t\treturn matcher[ expando ] ?\n\t\t\t\tmarkFunction(function( seed, matches, context, xml ) {\n\t\t\t\t\tvar elem,\n\t\t\t\t\t\tunmatched = matcher( seed, null, xml, [] ),\n\t\t\t\t\t\ti = seed.length;\n\n\t\t\t\t\t// Match elements unmatched by `matcher`\n\t\t\t\t\twhile ( i-- ) {\n\t\t\t\t\t\tif ( (elem = unmatched[i]) ) {\n\t\t\t\t\t\t\tseed[i] = !(matches[i] = elem);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}) :\n\t\t\t\tfunction( elem, context, xml ) {\n\t\t\t\t\tinput[0] = elem;\n\t\t\t\t\tmatcher( input, null, xml, results );\n\t\t\t\t\t// Don't keep the element (issue #299)\n\t\t\t\t\tinput[0] = null;\n\t\t\t\t\treturn !results.pop();\n\t\t\t\t};\n\t\t}),\n\n\t\t\"has\": markFunction(function( selector ) {\n\t\t\treturn function( elem ) {\n\t\t\t\treturn Sizzle( selector, elem ).length > 0;\n\t\t\t};\n\t\t}),\n\n\t\t\"contains\": markFunction(function( text ) {\n\t\t\ttext = text.replace( runescape, funescape );\n\t\t\treturn function( elem ) {\n\t\t\t\treturn ( elem.textContent || elem.innerText || getText( elem ) ).indexOf( text ) > -1;\n\t\t\t};\n\t\t}),\n\n\t\t// \"Whether an element is represented by a :lang() selector\n\t\t// is based solely on the element's language value\n\t\t// being equal to the identifier C,\n\t\t// or beginning with the identifier C immediately followed by \"-\".\n\t\t// The matching of C against the element's language value is performed case-insensitively.\n\t\t// The identifier C does not have to be a valid language name.\"\n\t\t// http://www.w3.org/TR/selectors/#lang-pseudo\n\t\t\"lang\": markFunction( function( lang ) {\n\t\t\t// lang value must be a valid identifier\n\t\t\tif ( !ridentifier.test(lang || \"\") ) {\n\t\t\t\tSizzle.error( \"unsupported lang: \" + lang );\n\t\t\t}\n\t\t\tlang = lang.replace( runescape, funescape ).toLowerCase();\n\t\t\treturn function( elem ) {\n\t\t\t\tvar elemLang;\n\t\t\t\tdo {\n\t\t\t\t\tif ( (elemLang = documentIsHTML ?\n\t\t\t\t\t\telem.lang :\n\t\t\t\t\t\telem.getAttribute(\"xml:lang\") || elem.getAttribute(\"lang\")) ) {\n\n\t\t\t\t\t\telemLang = elemLang.toLowerCase();\n\t\t\t\t\t\treturn elemLang === lang || elemLang.indexOf( lang + \"-\" ) === 0;\n\t\t\t\t\t}\n\t\t\t\t} while ( (elem = elem.parentNode) && elem.nodeType === 1 );\n\t\t\t\treturn false;\n\t\t\t};\n\t\t}),\n\n\t\t// Miscellaneous\n\t\t\"target\": function( elem ) {\n\t\t\tvar hash = window.location && window.location.hash;\n\t\t\treturn hash && hash.slice( 1 ) === elem.id;\n\t\t},\n\n\t\t\"root\": function( elem ) {\n\t\t\treturn elem === docElem;\n\t\t},\n\n\t\t\"focus\": function( elem ) {\n\t\t\treturn elem === document.activeElement && (!document.hasFocus || document.hasFocus()) && !!(elem.type || elem.href || ~elem.tabIndex);\n\t\t},\n\n\t\t// Boolean properties\n\t\t\"enabled\": createDisabledPseudo( false ),\n\t\t\"disabled\": createDisabledPseudo( true ),\n\n\t\t\"checked\": function( elem ) {\n\t\t\t// In CSS3, :checked should return both checked and selected elements\n\t\t\t// http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked\n\t\t\tvar nodeName = elem.nodeName.toLowerCase();\n\t\t\treturn (nodeName === \"input\" && !!elem.checked) || (nodeName === \"option\" && !!elem.selected);\n\t\t},\n\n\t\t\"selected\": function( elem ) {\n\t\t\t// Accessing this property makes selected-by-default\n\t\t\t// options in Safari work properly\n\t\t\tif ( elem.parentNode ) {\n\t\t\t\telem.parentNode.selectedIndex;\n\t\t\t}\n\n\t\t\treturn elem.selected === true;\n\t\t},\n\n\t\t// Contents\n\t\t\"empty\": function( elem ) {\n\t\t\t// http://www.w3.org/TR/selectors/#empty-pseudo\n\t\t\t// :empty is negated by element (1) or content nodes (text: 3; cdata: 4; entity ref: 5),\n\t\t\t//   but not by others (comment: 8; processing instruction: 7; etc.)\n\t\t\t// nodeType < 6 works because attributes (2) do not appear as children\n\t\t\tfor ( elem = elem.firstChild; elem; elem = elem.nextSibling ) {\n\t\t\t\tif ( elem.nodeType < 6 ) {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn true;\n\t\t},\n\n\t\t\"parent\": function( elem ) {\n\t\t\treturn !Expr.pseudos[\"empty\"]( elem );\n\t\t},\n\n\t\t// Element/input types\n\t\t\"header\": function( elem ) {\n\t\t\treturn rheader.test( elem.nodeName );\n\t\t},\n\n\t\t\"input\": function( elem ) {\n\t\t\treturn rinputs.test( elem.nodeName );\n\t\t},\n\n\t\t\"button\": function( elem ) {\n\t\t\tvar name = elem.nodeName.toLowerCase();\n\t\t\treturn name === \"input\" && elem.type === \"button\" || name === \"button\";\n\t\t},\n\n\t\t\"text\": function( elem ) {\n\t\t\tvar attr;\n\t\t\treturn elem.nodeName.toLowerCase() === \"input\" &&\n\t\t\t\telem.type === \"text\" &&\n\n\t\t\t\t// Support: IE<8\n\t\t\t\t// New HTML5 attribute values (e.g., \"search\") appear with elem.type === \"text\"\n\t\t\t\t( (attr = elem.getAttribute(\"type\")) == null || attr.toLowerCase() === \"text\" );\n\t\t},\n\n\t\t// Position-in-collection\n\t\t\"first\": createPositionalPseudo(function() {\n\t\t\treturn [ 0 ];\n\t\t}),\n\n\t\t\"last\": createPositionalPseudo(function( matchIndexes, length ) {\n\t\t\treturn [ length - 1 ];\n\t\t}),\n\n\t\t\"eq\": createPositionalPseudo(function( matchIndexes, length, argument ) {\n\t\t\treturn [ argument < 0 ? argument + length : argument ];\n\t\t}),\n\n\t\t\"even\": createPositionalPseudo(function( matchIndexes, length ) {\n\t\t\tvar i = 0;\n\t\t\tfor ( ; i < length; i += 2 ) {\n\t\t\t\tmatchIndexes.push( i );\n\t\t\t}\n\t\t\treturn matchIndexes;\n\t\t}),\n\n\t\t\"odd\": createPositionalPseudo(function( matchIndexes, length ) {\n\t\t\tvar i = 1;\n\t\t\tfor ( ; i < length; i += 2 ) {\n\t\t\t\tmatchIndexes.push( i );\n\t\t\t}\n\t\t\treturn matchIndexes;\n\t\t}),\n\n\t\t\"lt\": createPositionalPseudo(function( matchIndexes, length, argument ) {\n\t\t\tvar i = argument < 0 ? argument + length : argument;\n\t\t\tfor ( ; --i >= 0; ) {\n\t\t\t\tmatchIndexes.push( i );\n\t\t\t}\n\t\t\treturn matchIndexes;\n\t\t}),\n\n\t\t\"gt\": createPositionalPseudo(function( matchIndexes, length, argument ) {\n\t\t\tvar i = argument < 0 ? argument + length : argument;\n\t\t\tfor ( ; ++i < length; ) {\n\t\t\t\tmatchIndexes.push( i );\n\t\t\t}\n\t\t\treturn matchIndexes;\n\t\t})\n\t}\n};\n\nExpr.pseudos[\"nth\"] = Expr.pseudos[\"eq\"];\n\n// Add button/input type pseudos\nfor ( i in { radio: true, checkbox: true, file: true, password: true, image: true } ) {\n\tExpr.pseudos[ i ] = createInputPseudo( i );\n}\nfor ( i in { submit: true, reset: true } ) {\n\tExpr.pseudos[ i ] = createButtonPseudo( i );\n}\n\n// Easy API for creating new setFilters\nfunction setFilters() {}\nsetFilters.prototype = Expr.filters = Expr.pseudos;\nExpr.setFilters = new setFilters();\n\ntokenize = Sizzle.tokenize = function( selector, parseOnly ) {\n\tvar matched, match, tokens, type,\n\t\tsoFar, groups, preFilters,\n\t\tcached = tokenCache[ selector + \" \" ];\n\n\tif ( cached ) {\n\t\treturn parseOnly ? 0 : cached.slice( 0 );\n\t}\n\n\tsoFar = selector;\n\tgroups = [];\n\tpreFilters = Expr.preFilter;\n\n\twhile ( soFar ) {\n\n\t\t// Comma and first run\n\t\tif ( !matched || (match = rcomma.exec( soFar )) ) {\n\t\t\tif ( match ) {\n\t\t\t\t// Don't consume trailing commas as valid\n\t\t\t\tsoFar = soFar.slice( match[0].length ) || soFar;\n\t\t\t}\n\t\t\tgroups.push( (tokens = []) );\n\t\t}\n\n\t\tmatched = false;\n\n\t\t// Combinators\n\t\tif ( (match = rcombinators.exec( soFar )) ) {\n\t\t\tmatched = match.shift();\n\t\t\ttokens.push({\n\t\t\t\tvalue: matched,\n\t\t\t\t// Cast descendant combinators to space\n\t\t\t\ttype: match[0].replace( rtrim, \" \" )\n\t\t\t});\n\t\t\tsoFar = soFar.slice( matched.length );\n\t\t}\n\n\t\t// Filters\n\t\tfor ( type in Expr.filter ) {\n\t\t\tif ( (match = matchExpr[ type ].exec( soFar )) && (!preFilters[ type ] ||\n\t\t\t\t(match = preFilters[ type ]( match ))) ) {\n\t\t\t\tmatched = match.shift();\n\t\t\t\ttokens.push({\n\t\t\t\t\tvalue: matched,\n\t\t\t\t\ttype: type,\n\t\t\t\t\tmatches: match\n\t\t\t\t});\n\t\t\t\tsoFar = soFar.slice( matched.length );\n\t\t\t}\n\t\t}\n\n\t\tif ( !matched ) {\n\t\t\tbreak;\n\t\t}\n\t}\n\n\t// Return the length of the invalid excess\n\t// if we're just parsing\n\t// Otherwise, throw an error or return tokens\n\treturn parseOnly ?\n\t\tsoFar.length :\n\t\tsoFar ?\n\t\t\tSizzle.error( selector ) :\n\t\t\t// Cache the tokens\n\t\t\ttokenCache( selector, groups ).slice( 0 );\n};\n\nfunction toSelector( tokens ) {\n\tvar i = 0,\n\t\tlen = tokens.length,\n\t\tselector = \"\";\n\tfor ( ; i < len; i++ ) {\n\t\tselector += tokens[i].value;\n\t}\n\treturn selector;\n}\n\nfunction addCombinator( matcher, combinator, base ) {\n\tvar dir = combinator.dir,\n\t\tskip = combinator.next,\n\t\tkey = skip || dir,\n\t\tcheckNonElements = base && key === \"parentNode\",\n\t\tdoneName = done++;\n\n\treturn combinator.first ?\n\t\t// Check against closest ancestor/preceding element\n\t\tfunction( elem, context, xml ) {\n\t\t\twhile ( (elem = elem[ dir ]) ) {\n\t\t\t\tif ( elem.nodeType === 1 || checkNonElements ) {\n\t\t\t\t\treturn matcher( elem, context, xml );\n\t\t\t\t}\n\t\t\t}\n\t\t} :\n\n\t\t// Check against all ancestor/preceding elements\n\t\tfunction( elem, context, xml ) {\n\t\t\tvar oldCache, uniqueCache, outerCache,\n\t\t\t\tnewCache = [ dirruns, doneName ];\n\n\t\t\t// We can't set arbitrary data on XML nodes, so they don't benefit from combinator caching\n\t\t\tif ( xml ) {\n\t\t\t\twhile ( (elem = elem[ dir ]) ) {\n\t\t\t\t\tif ( elem.nodeType === 1 || checkNonElements ) {\n\t\t\t\t\t\tif ( matcher( elem, context, xml ) ) {\n\t\t\t\t\t\t\treturn true;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\twhile ( (elem = elem[ dir ]) ) {\n\t\t\t\t\tif ( elem.nodeType === 1 || checkNonElements ) {\n\t\t\t\t\t\touterCache = elem[ expando ] || (elem[ expando ] = {});\n\n\t\t\t\t\t\t// Support: IE <9 only\n\t\t\t\t\t\t// Defend against cloned attroperties (jQuery gh-1709)\n\t\t\t\t\t\tuniqueCache = outerCache[ elem.uniqueID ] || (outerCache[ elem.uniqueID ] = {});\n\n\t\t\t\t\t\tif ( skip && skip === elem.nodeName.toLowerCase() ) {\n\t\t\t\t\t\t\telem = elem[ dir ] || elem;\n\t\t\t\t\t\t} else if ( (oldCache = uniqueCache[ key ]) &&\n\t\t\t\t\t\t\toldCache[ 0 ] === dirruns && oldCache[ 1 ] === doneName ) {\n\n\t\t\t\t\t\t\t// Assign to newCache so results back-propagate to previous elements\n\t\t\t\t\t\t\treturn (newCache[ 2 ] = oldCache[ 2 ]);\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t// Reuse newcache so results back-propagate to previous elements\n\t\t\t\t\t\t\tuniqueCache[ key ] = newCache;\n\n\t\t\t\t\t\t\t// A match means we're done; a fail means we have to keep checking\n\t\t\t\t\t\t\tif ( (newCache[ 2 ] = matcher( elem, context, xml )) ) {\n\t\t\t\t\t\t\t\treturn true;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t};\n}\n\nfunction elementMatcher( matchers ) {\n\treturn matchers.length > 1 ?\n\t\tfunction( elem, context, xml ) {\n\t\t\tvar i = matchers.length;\n\t\t\twhile ( i-- ) {\n\t\t\t\tif ( !matchers[i]( elem, context, xml ) ) {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn true;\n\t\t} :\n\t\tmatchers[0];\n}\n\nfunction multipleContexts( selector, contexts, results ) {\n\tvar i = 0,\n\t\tlen = contexts.length;\n\tfor ( ; i < len; i++ ) {\n\t\tSizzle( selector, contexts[i], results );\n\t}\n\treturn results;\n}\n\nfunction condense( unmatched, map, filter, context, xml ) {\n\tvar elem,\n\t\tnewUnmatched = [],\n\t\ti = 0,\n\t\tlen = unmatched.length,\n\t\tmapped = map != null;\n\n\tfor ( ; i < len; i++ ) {\n\t\tif ( (elem = unmatched[i]) ) {\n\t\t\tif ( !filter || filter( elem, context, xml ) ) {\n\t\t\t\tnewUnmatched.push( elem );\n\t\t\t\tif ( mapped ) {\n\t\t\t\t\tmap.push( i );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\treturn newUnmatched;\n}\n\nfunction setMatcher( preFilter, selector, matcher, postFilter, postFinder, postSelector ) {\n\tif ( postFilter && !postFilter[ expando ] ) {\n\t\tpostFilter = setMatcher( postFilter );\n\t}\n\tif ( postFinder && !postFinder[ expando ] ) {\n\t\tpostFinder = setMatcher( postFinder, postSelector );\n\t}\n\treturn markFunction(function( seed, results, context, xml ) {\n\t\tvar temp, i, elem,\n\t\t\tpreMap = [],\n\t\t\tpostMap = [],\n\t\t\tpreexisting = results.length,\n\n\t\t\t// Get initial elements from seed or context\n\t\t\telems = seed || multipleContexts( selector || \"*\", context.nodeType ? [ context ] : context, [] ),\n\n\t\t\t// Prefilter to get matcher input, preserving a map for seed-results synchronization\n\t\t\tmatcherIn = preFilter && ( seed || !selector ) ?\n\t\t\t\tcondense( elems, preMap, preFilter, context, xml ) :\n\t\t\t\telems,\n\n\t\t\tmatcherOut = matcher ?\n\t\t\t\t// If we have a postFinder, or filtered seed, or non-seed postFilter or preexisting results,\n\t\t\t\tpostFinder || ( seed ? preFilter : preexisting || postFilter ) ?\n\n\t\t\t\t\t// ...intermediate processing is necessary\n\t\t\t\t\t[] :\n\n\t\t\t\t\t// ...otherwise use results directly\n\t\t\t\t\tresults :\n\t\t\t\tmatcherIn;\n\n\t\t// Find primary matches\n\t\tif ( matcher ) {\n\t\t\tmatcher( matcherIn, matcherOut, context, xml );\n\t\t}\n\n\t\t// Apply postFilter\n\t\tif ( postFilter ) {\n\t\t\ttemp = condense( matcherOut, postMap );\n\t\t\tpostFilter( temp, [], context, xml );\n\n\t\t\t// Un-match failing elements by moving them back to matcherIn\n\t\t\ti = temp.length;\n\t\t\twhile ( i-- ) {\n\t\t\t\tif ( (elem = temp[i]) ) {\n\t\t\t\t\tmatcherOut[ postMap[i] ] = !(matcherIn[ postMap[i] ] = elem);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif ( seed ) {\n\t\t\tif ( postFinder || preFilter ) {\n\t\t\t\tif ( postFinder ) {\n\t\t\t\t\t// Get the final matcherOut by condensing this intermediate into postFinder contexts\n\t\t\t\t\ttemp = [];\n\t\t\t\t\ti = matcherOut.length;\n\t\t\t\t\twhile ( i-- ) {\n\t\t\t\t\t\tif ( (elem = matcherOut[i]) ) {\n\t\t\t\t\t\t\t// Restore matcherIn since elem is not yet a final match\n\t\t\t\t\t\t\ttemp.push( (matcherIn[i] = elem) );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tpostFinder( null, (matcherOut = []), temp, xml );\n\t\t\t\t}\n\n\t\t\t\t// Move matched elements from seed to results to keep them synchronized\n\t\t\t\ti = matcherOut.length;\n\t\t\t\twhile ( i-- ) {\n\t\t\t\t\tif ( (elem = matcherOut[i]) &&\n\t\t\t\t\t\t(temp = postFinder ? indexOf( seed, elem ) : preMap[i]) > -1 ) {\n\n\t\t\t\t\t\tseed[temp] = !(results[temp] = elem);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t// Add elements to results, through postFinder if defined\n\t\t} else {\n\t\t\tmatcherOut = condense(\n\t\t\t\tmatcherOut === results ?\n\t\t\t\t\tmatcherOut.splice( preexisting, matcherOut.length ) :\n\t\t\t\t\tmatcherOut\n\t\t\t);\n\t\t\tif ( postFinder ) {\n\t\t\t\tpostFinder( null, results, matcherOut, xml );\n\t\t\t} else {\n\t\t\t\tpush.apply( results, matcherOut );\n\t\t\t}\n\t\t}\n\t});\n}\n\nfunction matcherFromTokens( tokens ) {\n\tvar checkContext, matcher, j,\n\t\tlen = tokens.length,\n\t\tleadingRelative = Expr.relative[ tokens[0].type ],\n\t\timplicitRelative = leadingRelative || Expr.relative[\" \"],\n\t\ti = leadingRelative ? 1 : 0,\n\n\t\t// The foundational matcher ensures that elements are reachable from top-level context(s)\n\t\tmatchContext = addCombinator( function( elem ) {\n\t\t\treturn elem === checkContext;\n\t\t}, implicitRelative, true ),\n\t\tmatchAnyContext = addCombinator( function( elem ) {\n\t\t\treturn indexOf( checkContext, elem ) > -1;\n\t\t}, implicitRelative, true ),\n\t\tmatchers = [ function( elem, context, xml ) {\n\t\t\tvar ret = ( !leadingRelative && ( xml || context !== outermostContext ) ) || (\n\t\t\t\t(checkContext = context).nodeType ?\n\t\t\t\t\tmatchContext( elem, context, xml ) :\n\t\t\t\t\tmatchAnyContext( elem, context, xml ) );\n\t\t\t// Avoid hanging onto element (issue #299)\n\t\t\tcheckContext = null;\n\t\t\treturn ret;\n\t\t} ];\n\n\tfor ( ; i < len; i++ ) {\n\t\tif ( (matcher = Expr.relative[ tokens[i].type ]) ) {\n\t\t\tmatchers = [ addCombinator(elementMatcher( matchers ), matcher) ];\n\t\t} else {\n\t\t\tmatcher = Expr.filter[ tokens[i].type ].apply( null, tokens[i].matches );\n\n\t\t\t// Return special upon seeing a positional matcher\n\t\t\tif ( matcher[ expando ] ) {\n\t\t\t\t// Find the next relative operator (if any) for proper handling\n\t\t\t\tj = ++i;\n\t\t\t\tfor ( ; j < len; j++ ) {\n\t\t\t\t\tif ( Expr.relative[ tokens[j].type ] ) {\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn setMatcher(\n\t\t\t\t\ti > 1 && elementMatcher( matchers ),\n\t\t\t\t\ti > 1 && toSelector(\n\t\t\t\t\t\t// If the preceding token was a descendant combinator, insert an implicit any-element `*`\n\t\t\t\t\t\ttokens.slice( 0, i - 1 ).concat({ value: tokens[ i - 2 ].type === \" \" ? \"*\" : \"\" })\n\t\t\t\t\t).replace( rtrim, \"$1\" ),\n\t\t\t\t\tmatcher,\n\t\t\t\t\ti < j && matcherFromTokens( tokens.slice( i, j ) ),\n\t\t\t\t\tj < len && matcherFromTokens( (tokens = tokens.slice( j )) ),\n\t\t\t\t\tj < len && toSelector( tokens )\n\t\t\t\t);\n\t\t\t}\n\t\t\tmatchers.push( matcher );\n\t\t}\n\t}\n\n\treturn elementMatcher( matchers );\n}\n\nfunction matcherFromGroupMatchers( elementMatchers, setMatchers ) {\n\tvar bySet = setMatchers.length > 0,\n\t\tbyElement = elementMatchers.length > 0,\n\t\tsuperMatcher = function( seed, context, xml, results, outermost ) {\n\t\t\tvar elem, j, matcher,\n\t\t\t\tmatchedCount = 0,\n\t\t\t\ti = \"0\",\n\t\t\t\tunmatched = seed && [],\n\t\t\t\tsetMatched = [],\n\t\t\t\tcontextBackup = outermostContext,\n\t\t\t\t// We must always have either seed elements or outermost context\n\t\t\t\telems = seed || byElement && Expr.find[\"TAG\"]( \"*\", outermost ),\n\t\t\t\t// Use integer dirruns iff this is the outermost matcher\n\t\t\t\tdirrunsUnique = (dirruns += contextBackup == null ? 1 : Math.random() || 0.1),\n\t\t\t\tlen = elems.length;\n\n\t\t\tif ( outermost ) {\n\t\t\t\toutermostContext = context === document || context || outermost;\n\t\t\t}\n\n\t\t\t// Add elements passing elementMatchers directly to results\n\t\t\t// Support: IE<9, Safari\n\t\t\t// Tolerate NodeList properties (IE: \"length\"; Safari: <number>) matching elements by id\n\t\t\tfor ( ; i !== len && (elem = elems[i]) != null; i++ ) {\n\t\t\t\tif ( byElement && elem ) {\n\t\t\t\t\tj = 0;\n\t\t\t\t\tif ( !context && elem.ownerDocument !== document ) {\n\t\t\t\t\t\tsetDocument( elem );\n\t\t\t\t\t\txml = !documentIsHTML;\n\t\t\t\t\t}\n\t\t\t\t\twhile ( (matcher = elementMatchers[j++]) ) {\n\t\t\t\t\t\tif ( matcher( elem, context || document, xml) ) {\n\t\t\t\t\t\t\tresults.push( elem );\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tif ( outermost ) {\n\t\t\t\t\t\tdirruns = dirrunsUnique;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// Track unmatched elements for set filters\n\t\t\t\tif ( bySet ) {\n\t\t\t\t\t// They will have gone through all possible matchers\n\t\t\t\t\tif ( (elem = !matcher && elem) ) {\n\t\t\t\t\t\tmatchedCount--;\n\t\t\t\t\t}\n\n\t\t\t\t\t// Lengthen the array for every element, matched or not\n\t\t\t\t\tif ( seed ) {\n\t\t\t\t\t\tunmatched.push( elem );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// `i` is now the count of elements visited above, and adding it to `matchedCount`\n\t\t\t// makes the latter nonnegative.\n\t\t\tmatchedCount += i;\n\n\t\t\t// Apply set filters to unmatched elements\n\t\t\t// NOTE: This can be skipped if there are no unmatched elements (i.e., `matchedCount`\n\t\t\t// equals `i`), unless we didn't visit _any_ elements in the above loop because we have\n\t\t\t// no element matchers and no seed.\n\t\t\t// Incrementing an initially-string \"0\" `i` allows `i` to remain a string only in that\n\t\t\t// case, which will result in a \"00\" `matchedCount` that differs from `i` but is also\n\t\t\t// numerically zero.\n\t\t\tif ( bySet && i !== matchedCount ) {\n\t\t\t\tj = 0;\n\t\t\t\twhile ( (matcher = setMatchers[j++]) ) {\n\t\t\t\t\tmatcher( unmatched, setMatched, context, xml );\n\t\t\t\t}\n\n\t\t\t\tif ( seed ) {\n\t\t\t\t\t// Reintegrate element matches to eliminate the need for sorting\n\t\t\t\t\tif ( matchedCount > 0 ) {\n\t\t\t\t\t\twhile ( i-- ) {\n\t\t\t\t\t\t\tif ( !(unmatched[i] || setMatched[i]) ) {\n\t\t\t\t\t\t\t\tsetMatched[i] = pop.call( results );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\t// Discard index placeholder values to get only actual matches\n\t\t\t\t\tsetMatched = condense( setMatched );\n\t\t\t\t}\n\n\t\t\t\t// Add matches to results\n\t\t\t\tpush.apply( results, setMatched );\n\n\t\t\t\t// Seedless set matches succeeding multiple successful matchers stipulate sorting\n\t\t\t\tif ( outermost && !seed && setMatched.length > 0 &&\n\t\t\t\t\t( matchedCount + setMatchers.length ) > 1 ) {\n\n\t\t\t\t\tSizzle.uniqueSort( results );\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Override manipulation of globals by nested matchers\n\t\t\tif ( outermost ) {\n\t\t\t\tdirruns = dirrunsUnique;\n\t\t\t\toutermostContext = contextBackup;\n\t\t\t}\n\n\t\t\treturn unmatched;\n\t\t};\n\n\treturn bySet ?\n\t\tmarkFunction( superMatcher ) :\n\t\tsuperMatcher;\n}\n\ncompile = Sizzle.compile = function( selector, match /* Internal Use Only */ ) {\n\tvar i,\n\t\tsetMatchers = [],\n\t\telementMatchers = [],\n\t\tcached = compilerCache[ selector + \" \" ];\n\n\tif ( !cached ) {\n\t\t// Generate a function of recursive functions that can be used to check each element\n\t\tif ( !match ) {\n\t\t\tmatch = tokenize( selector );\n\t\t}\n\t\ti = match.length;\n\t\twhile ( i-- ) {\n\t\t\tcached = matcherFromTokens( match[i] );\n\t\t\tif ( cached[ expando ] ) {\n\t\t\t\tsetMatchers.push( cached );\n\t\t\t} else {\n\t\t\t\telementMatchers.push( cached );\n\t\t\t}\n\t\t}\n\n\t\t// Cache the compiled function\n\t\tcached = compilerCache( selector, matcherFromGroupMatchers( elementMatchers, setMatchers ) );\n\n\t\t// Save selector and tokenization\n\t\tcached.selector = selector;\n\t}\n\treturn cached;\n};\n\n/**\n * A low-level selection function that works with Sizzle's compiled\n *  selector functions\n * @param {String|Function} selector A selector or a pre-compiled\n *  selector function built with Sizzle.compile\n * @param {Element} context\n * @param {Array} [results]\n * @param {Array} [seed] A set of elements to match against\n */\nselect = Sizzle.select = function( selector, context, results, seed ) {\n\tvar i, tokens, token, type, find,\n\t\tcompiled = typeof selector === \"function\" && selector,\n\t\tmatch = !seed && tokenize( (selector = compiled.selector || selector) );\n\n\tresults = results || [];\n\n\t// Try to minimize operations if there is only one selector in the list and no seed\n\t// (the latter of which guarantees us context)\n\tif ( match.length === 1 ) {\n\n\t\t// Reduce context if the leading compound selector is an ID\n\t\ttokens = match[0] = match[0].slice( 0 );\n\t\tif ( tokens.length > 2 && (token = tokens[0]).type === \"ID\" &&\n\t\t\t\tsupport.getById && context.nodeType === 9 && documentIsHTML &&\n\t\t\t\tExpr.relative[ tokens[1].type ] ) {\n\n\t\t\tcontext = ( Expr.find[\"ID\"]( token.matches[0].replace(runescape, funescape), context ) || [] )[0];\n\t\t\tif ( !context ) {\n\t\t\t\treturn results;\n\n\t\t\t// Precompiled matchers will still verify ancestry, so step up a level\n\t\t\t} else if ( compiled ) {\n\t\t\t\tcontext = context.parentNode;\n\t\t\t}\n\n\t\t\tselector = selector.slice( tokens.shift().value.length );\n\t\t}\n\n\t\t// Fetch a seed set for right-to-left matching\n\t\ti = matchExpr[\"needsContext\"].test( selector ) ? 0 : tokens.length;\n\t\twhile ( i-- ) {\n\t\t\ttoken = tokens[i];\n\n\t\t\t// Abort if we hit a combinator\n\t\t\tif ( Expr.relative[ (type = token.type) ] ) {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tif ( (find = Expr.find[ type ]) ) {\n\t\t\t\t// Search, expanding context for leading sibling combinators\n\t\t\t\tif ( (seed = find(\n\t\t\t\t\ttoken.matches[0].replace( runescape, funescape ),\n\t\t\t\t\trsibling.test( tokens[0].type ) && testContext( context.parentNode ) || context\n\t\t\t\t)) ) {\n\n\t\t\t\t\t// If seed is empty or no tokens remain, we can return early\n\t\t\t\t\ttokens.splice( i, 1 );\n\t\t\t\t\tselector = seed.length && toSelector( tokens );\n\t\t\t\t\tif ( !selector ) {\n\t\t\t\t\t\tpush.apply( results, seed );\n\t\t\t\t\t\treturn results;\n\t\t\t\t\t}\n\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t// Compile and execute a filtering function if one is not provided\n\t// Provide `match` to avoid retokenization if we modified the selector above\n\t( compiled || compile( selector, match ) )(\n\t\tseed,\n\t\tcontext,\n\t\t!documentIsHTML,\n\t\tresults,\n\t\t!context || rsibling.test( selector ) && testContext( context.parentNode ) || context\n\t);\n\treturn results;\n};\n\n// One-time assignments\n\n// Sort stability\nsupport.sortStable = expando.split(\"\").sort( sortOrder ).join(\"\") === expando;\n\n// Support: Chrome 14-35+\n// Always assume duplicates if they aren't passed to the comparison function\nsupport.detectDuplicates = !!hasDuplicate;\n\n// Initialize against the default document\nsetDocument();\n\n// Support: Webkit<537.32 - Safari 6.0.3/Chrome 25 (fixed in Chrome 27)\n// Detached nodes confoundingly follow *each other*\nsupport.sortDetached = assert(function( el ) {\n\t// Should return 1, but returns 4 (following)\n\treturn el.compareDocumentPosition( document.createElement(\"fieldset\") ) & 1;\n});\n\n// Support: IE<8\n// Prevent attribute/property \"interpolation\"\n// https://msdn.microsoft.com/en-us/library/ms536429%28VS.85%29.aspx\nif ( !assert(function( el ) {\n\tel.innerHTML = \"<a href='#'></a>\";\n\treturn el.firstChild.getAttribute(\"href\") === \"#\" ;\n}) ) {\n\taddHandle( \"type|href|height|width\", function( elem, name, isXML ) {\n\t\tif ( !isXML ) {\n\t\t\treturn elem.getAttribute( name, name.toLowerCase() === \"type\" ? 1 : 2 );\n\t\t}\n\t});\n}\n\n// Support: IE<9\n// Use defaultValue in place of getAttribute(\"value\")\nif ( !support.attributes || !assert(function( el ) {\n\tel.innerHTML = \"<input/>\";\n\tel.firstChild.setAttribute( \"value\", \"\" );\n\treturn el.firstChild.getAttribute( \"value\" ) === \"\";\n}) ) {\n\taddHandle( \"value\", function( elem, name, isXML ) {\n\t\tif ( !isXML && elem.nodeName.toLowerCase() === \"input\" ) {\n\t\t\treturn elem.defaultValue;\n\t\t}\n\t});\n}\n\n// Support: IE<9\n// Use getAttributeNode to fetch booleans when getAttribute lies\nif ( !assert(function( el ) {\n\treturn el.getAttribute(\"disabled\") == null;\n}) ) {\n\taddHandle( booleans, function( elem, name, isXML ) {\n\t\tvar val;\n\t\tif ( !isXML ) {\n\t\t\treturn elem[ name ] === true ? name.toLowerCase() :\n\t\t\t\t\t(val = elem.getAttributeNode( name )) && val.specified ?\n\t\t\t\t\tval.value :\n\t\t\t\tnull;\n\t\t}\n\t});\n}\n\nreturn Sizzle;\n\n})( window );\n\n\n\njQuery.find = Sizzle;\njQuery.expr = Sizzle.selectors;\n\n// Deprecated\njQuery.expr[ \":\" ] = jQuery.expr.pseudos;\njQuery.uniqueSort = jQuery.unique = Sizzle.uniqueSort;\njQuery.text = Sizzle.getText;\njQuery.isXMLDoc = Sizzle.isXML;\njQuery.contains = Sizzle.contains;\njQuery.escapeSelector = Sizzle.escape;\n\n\n\n\nvar dir = function( elem, dir, until ) {\n\tvar matched = [],\n\t\ttruncate = until !== undefined;\n\n\twhile ( ( elem = elem[ dir ] ) && elem.nodeType !== 9 ) {\n\t\tif ( elem.nodeType === 1 ) {\n\t\t\tif ( truncate && jQuery( elem ).is( until ) ) {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tmatched.push( elem );\n\t\t}\n\t}\n\treturn matched;\n};\n\n\nvar siblings = function( n, elem ) {\n\tvar matched = [];\n\n\tfor ( ; n; n = n.nextSibling ) {\n\t\tif ( n.nodeType === 1 && n !== elem ) {\n\t\t\tmatched.push( n );\n\t\t}\n\t}\n\n\treturn matched;\n};\n\n\nvar rneedsContext = jQuery.expr.match.needsContext;\n\nvar rsingleTag = ( /^<([a-z][^\\/\\0>:\\x20\\t\\r\\n\\f]*)[\\x20\\t\\r\\n\\f]*\\/?>(?:<\\/\\1>|)$/i );\n\n\n\nvar risSimple = /^.[^:#\\[\\.,]*$/;\n\n// Implement the identical functionality for filter and not\nfunction winnow( elements, qualifier, not ) {\n\tif ( jQuery.isFunction( qualifier ) ) {\n\t\treturn jQuery.grep( elements, function( elem, i ) {\n\t\t\treturn !!qualifier.call( elem, i, elem ) !== not;\n\t\t} );\n\n\t}\n\n\tif ( qualifier.nodeType ) {\n\t\treturn jQuery.grep( elements, function( elem ) {\n\t\t\treturn ( elem === qualifier ) !== not;\n\t\t} );\n\n\t}\n\n\tif ( typeof qualifier === \"string\" ) {\n\t\tif ( risSimple.test( qualifier ) ) {\n\t\t\treturn jQuery.filter( qualifier, elements, not );\n\t\t}\n\n\t\tqualifier = jQuery.filter( qualifier, elements );\n\t}\n\n\treturn jQuery.grep( elements, function( elem ) {\n\t\treturn ( indexOf.call( qualifier, elem ) > -1 ) !== not && elem.nodeType === 1;\n\t} );\n}\n\njQuery.filter = function( expr, elems, not ) {\n\tvar elem = elems[ 0 ];\n\n\tif ( not ) {\n\t\texpr = \":not(\" + expr + \")\";\n\t}\n\n\treturn elems.length === 1 && elem.nodeType === 1 ?\n\t\tjQuery.find.matchesSelector( elem, expr ) ? [ elem ] : [] :\n\t\tjQuery.find.matches( expr, jQuery.grep( elems, function( elem ) {\n\t\t\treturn elem.nodeType === 1;\n\t\t} ) );\n};\n\njQuery.fn.extend( {\n\tfind: function( selector ) {\n\t\tvar i, ret,\n\t\t\tlen = this.length,\n\t\t\tself = this;\n\n\t\tif ( typeof selector !== \"string\" ) {\n\t\t\treturn this.pushStack( jQuery( selector ).filter( function() {\n\t\t\t\tfor ( i = 0; i < len; i++ ) {\n\t\t\t\t\tif ( jQuery.contains( self[ i ], this ) ) {\n\t\t\t\t\t\treturn true;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} ) );\n\t\t}\n\n\t\tret = this.pushStack( [] );\n\n\t\tfor ( i = 0; i < len; i++ ) {\n\t\t\tjQuery.find( selector, self[ i ], ret );\n\t\t}\n\n\t\treturn len > 1 ? jQuery.uniqueSort( ret ) : ret;\n\t},\n\tfilter: function( selector ) {\n\t\treturn this.pushStack( winnow( this, selector || [], false ) );\n\t},\n\tnot: function( selector ) {\n\t\treturn this.pushStack( winnow( this, selector || [], true ) );\n\t},\n\tis: function( selector ) {\n\t\treturn !!winnow(\n\t\t\tthis,\n\n\t\t\t// If this is a positional/relative selector, check membership in the returned set\n\t\t\t// so $(\"p:first\").is(\"p:last\") won't return true for a doc with two \"p\".\n\t\t\ttypeof selector === \"string\" && rneedsContext.test( selector ) ?\n\t\t\t\tjQuery( selector ) :\n\t\t\t\tselector || [],\n\t\t\tfalse\n\t\t).length;\n\t}\n} );\n\n\n// Initialize a jQuery object\n\n\n// A central reference to the root jQuery(document)\nvar rootjQuery,\n\n\t// A simple way to check for HTML strings\n\t// Prioritize #id over <tag> to avoid XSS via location.hash (#9521)\n\t// Strict HTML recognition (#11290: must start with <)\n\t// Shortcut simple #id case for speed\n\trquickExpr = /^(?:\\s*(<[\\w\\W]+>)[^>]*|#([\\w-]+))$/,\n\n\tinit = jQuery.fn.init = function( selector, context, root ) {\n\t\tvar match, elem;\n\n\t\t// HANDLE: $(\"\"), $(null), $(undefined), $(false)\n\t\tif ( !selector ) {\n\t\t\treturn this;\n\t\t}\n\n\t\t// Method init() accepts an alternate rootjQuery\n\t\t// so migrate can support jQuery.sub (gh-2101)\n\t\troot = root || rootjQuery;\n\n\t\t// Handle HTML strings\n\t\tif ( typeof selector === \"string\" ) {\n\t\t\tif ( selector[ 0 ] === \"<\" &&\n\t\t\t\tselector[ selector.length - 1 ] === \">\" &&\n\t\t\t\tselector.length >= 3 ) {\n\n\t\t\t\t// Assume that strings that start and end with <> are HTML and skip the regex check\n\t\t\t\tmatch = [ null, selector, null ];\n\n\t\t\t} else {\n\t\t\t\tmatch = rquickExpr.exec( selector );\n\t\t\t}\n\n\t\t\t// Match html or make sure no context is specified for #id\n\t\t\tif ( match && ( match[ 1 ] || !context ) ) {\n\n\t\t\t\t// HANDLE: $(html) -> $(array)\n\t\t\t\tif ( match[ 1 ] ) {\n\t\t\t\t\tcontext = context instanceof jQuery ? context[ 0 ] : context;\n\n\t\t\t\t\t// Option to run scripts is true for back-compat\n\t\t\t\t\t// Intentionally let the error be thrown if parseHTML is not present\n\t\t\t\t\tjQuery.merge( this, jQuery.parseHTML(\n\t\t\t\t\t\tmatch[ 1 ],\n\t\t\t\t\t\tcontext && context.nodeType ? context.ownerDocument || context : document,\n\t\t\t\t\t\ttrue\n\t\t\t\t\t) );\n\n\t\t\t\t\t// HANDLE: $(html, props)\n\t\t\t\t\tif ( rsingleTag.test( match[ 1 ] ) && jQuery.isPlainObject( context ) ) {\n\t\t\t\t\t\tfor ( match in context ) {\n\n\t\t\t\t\t\t\t// Properties of context are called as methods if possible\n\t\t\t\t\t\t\tif ( jQuery.isFunction( this[ match ] ) ) {\n\t\t\t\t\t\t\t\tthis[ match ]( context[ match ] );\n\n\t\t\t\t\t\t\t// ...and otherwise set as attributes\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tthis.attr( match, context[ match ] );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\treturn this;\n\n\t\t\t\t// HANDLE: $(#id)\n\t\t\t\t} else {\n\t\t\t\t\telem = document.getElementById( match[ 2 ] );\n\n\t\t\t\t\tif ( elem ) {\n\n\t\t\t\t\t\t// Inject the element directly into the jQuery object\n\t\t\t\t\t\tthis[ 0 ] = elem;\n\t\t\t\t\t\tthis.length = 1;\n\t\t\t\t\t}\n\t\t\t\t\treturn this;\n\t\t\t\t}\n\n\t\t\t// HANDLE: $(expr, $(...))\n\t\t\t} else if ( !context || context.jquery ) {\n\t\t\t\treturn ( context || root ).find( selector );\n\n\t\t\t// HANDLE: $(expr, context)\n\t\t\t// (which is just equivalent to: $(context).find(expr)\n\t\t\t} else {\n\t\t\t\treturn this.constructor( context ).find( selector );\n\t\t\t}\n\n\t\t// HANDLE: $(DOMElement)\n\t\t} else if ( selector.nodeType ) {\n\t\t\tthis[ 0 ] = selector;\n\t\t\tthis.length = 1;\n\t\t\treturn this;\n\n\t\t// HANDLE: $(function)\n\t\t// Shortcut for document ready\n\t\t} else if ( jQuery.isFunction( selector ) ) {\n\t\t\treturn root.ready !== undefined ?\n\t\t\t\troot.ready( selector ) :\n\n\t\t\t\t// Execute immediately if ready is not present\n\t\t\t\tselector( jQuery );\n\t\t}\n\n\t\treturn jQuery.makeArray( selector, this );\n\t};\n\n// Give the init function the jQuery prototype for later instantiation\ninit.prototype = jQuery.fn;\n\n// Initialize central reference\nrootjQuery = jQuery( document );\n\n\nvar rparentsprev = /^(?:parents|prev(?:Until|All))/,\n\n\t// Methods guaranteed to produce a unique set when starting from a unique set\n\tguaranteedUnique = {\n\t\tchildren: true,\n\t\tcontents: true,\n\t\tnext: true,\n\t\tprev: true\n\t};\n\njQuery.fn.extend( {\n\thas: function( target ) {\n\t\tvar targets = jQuery( target, this ),\n\t\t\tl = targets.length;\n\n\t\treturn this.filter( function() {\n\t\t\tvar i = 0;\n\t\t\tfor ( ; i < l; i++ ) {\n\t\t\t\tif ( jQuery.contains( this, targets[ i ] ) ) {\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t}\n\t\t} );\n\t},\n\n\tclosest: function( selectors, context ) {\n\t\tvar cur,\n\t\t\ti = 0,\n\t\t\tl = this.length,\n\t\t\tmatched = [],\n\t\t\ttargets = typeof selectors !== \"string\" && jQuery( selectors );\n\n\t\t// Positional selectors never match, since there's no _selection_ context\n\t\tif ( !rneedsContext.test( selectors ) ) {\n\t\t\tfor ( ; i < l; i++ ) {\n\t\t\t\tfor ( cur = this[ i ]; cur && cur !== context; cur = cur.parentNode ) {\n\n\t\t\t\t\t// Always skip document fragments\n\t\t\t\t\tif ( cur.nodeType < 11 && ( targets ?\n\t\t\t\t\t\ttargets.index( cur ) > -1 :\n\n\t\t\t\t\t\t// Don't pass non-elements to Sizzle\n\t\t\t\t\t\tcur.nodeType === 1 &&\n\t\t\t\t\t\t\tjQuery.find.matchesSelector( cur, selectors ) ) ) {\n\n\t\t\t\t\t\tmatched.push( cur );\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn this.pushStack( matched.length > 1 ? jQuery.uniqueSort( matched ) : matched );\n\t},\n\n\t// Determine the position of an element within the set\n\tindex: function( elem ) {\n\n\t\t// No argument, return index in parent\n\t\tif ( !elem ) {\n\t\t\treturn ( this[ 0 ] && this[ 0 ].parentNode ) ? this.first().prevAll().length : -1;\n\t\t}\n\n\t\t// Index in selector\n\t\tif ( typeof elem === \"string\" ) {\n\t\t\treturn indexOf.call( jQuery( elem ), this[ 0 ] );\n\t\t}\n\n\t\t// Locate the position of the desired element\n\t\treturn indexOf.call( this,\n\n\t\t\t// If it receives a jQuery object, the first element is used\n\t\t\telem.jquery ? elem[ 0 ] : elem\n\t\t);\n\t},\n\n\tadd: function( selector, context ) {\n\t\treturn this.pushStack(\n\t\t\tjQuery.uniqueSort(\n\t\t\t\tjQuery.merge( this.get(), jQuery( selector, context ) )\n\t\t\t)\n\t\t);\n\t},\n\n\taddBack: function( selector ) {\n\t\treturn this.add( selector == null ?\n\t\t\tthis.prevObject : this.prevObject.filter( selector )\n\t\t);\n\t}\n} );\n\nfunction sibling( cur, dir ) {\n\twhile ( ( cur = cur[ dir ] ) && cur.nodeType !== 1 ) {}\n\treturn cur;\n}\n\njQuery.each( {\n\tparent: function( elem ) {\n\t\tvar parent = elem.parentNode;\n\t\treturn parent && parent.nodeType !== 11 ? parent : null;\n\t},\n\tparents: function( elem ) {\n\t\treturn dir( elem, \"parentNode\" );\n\t},\n\tparentsUntil: function( elem, i, until ) {\n\t\treturn dir( elem, \"parentNode\", until );\n\t},\n\tnext: function( elem ) {\n\t\treturn sibling( elem, \"nextSibling\" );\n\t},\n\tprev: function( elem ) {\n\t\treturn sibling( elem, \"previousSibling\" );\n\t},\n\tnextAll: function( elem ) {\n\t\treturn dir( elem, \"nextSibling\" );\n\t},\n\tprevAll: function( elem ) {\n\t\treturn dir( elem, \"previousSibling\" );\n\t},\n\tnextUntil: function( elem, i, until ) {\n\t\treturn dir( elem, \"nextSibling\", until );\n\t},\n\tprevUntil: function( elem, i, until ) {\n\t\treturn dir( elem, \"previousSibling\", until );\n\t},\n\tsiblings: function( elem ) {\n\t\treturn siblings( ( elem.parentNode || {} ).firstChild, elem );\n\t},\n\tchildren: function( elem ) {\n\t\treturn siblings( elem.firstChild );\n\t},\n\tcontents: function( elem ) {\n\t\treturn elem.contentDocument || jQuery.merge( [], elem.childNodes );\n\t}\n}, function( name, fn ) {\n\tjQuery.fn[ name ] = function( until, selector ) {\n\t\tvar matched = jQuery.map( this, fn, until );\n\n\t\tif ( name.slice( -5 ) !== \"Until\" ) {\n\t\t\tselector = until;\n\t\t}\n\n\t\tif ( selector && typeof selector === \"string\" ) {\n\t\t\tmatched = jQuery.filter( selector, matched );\n\t\t}\n\n\t\tif ( this.length > 1 ) {\n\n\t\t\t// Remove duplicates\n\t\t\tif ( !guaranteedUnique[ name ] ) {\n\t\t\t\tjQuery.uniqueSort( matched );\n\t\t\t}\n\n\t\t\t// Reverse order for parents* and prev-derivatives\n\t\t\tif ( rparentsprev.test( name ) ) {\n\t\t\t\tmatched.reverse();\n\t\t\t}\n\t\t}\n\n\t\treturn this.pushStack( matched );\n\t};\n} );\nvar rnotwhite = ( /\\S+/g );\n\n\n\n// Convert String-formatted options into Object-formatted ones\nfunction createOptions( options ) {\n\tvar object = {};\n\tjQuery.each( options.match( rnotwhite ) || [], function( _, flag ) {\n\t\tobject[ flag ] = true;\n\t} );\n\treturn object;\n}\n\n/*\n * Create a callback list using the following parameters:\n *\n *\toptions: an optional list of space-separated options that will change how\n *\t\t\tthe callback list behaves or a more traditional option object\n *\n * By default a callback list will act like an event callback list and can be\n * \"fired\" multiple times.\n *\n * Possible options:\n *\n *\tonce:\t\t\twill ensure the callback list can only be fired once (like a Deferred)\n *\n *\tmemory:\t\t\twill keep track of previous values and will call any callback added\n *\t\t\t\t\tafter the list has been fired right away with the latest \"memorized\"\n *\t\t\t\t\tvalues (like a Deferred)\n *\n *\tunique:\t\t\twill ensure a callback can only be added once (no duplicate in the list)\n *\n *\tstopOnFalse:\tinterrupt callings when a callback returns false\n *\n */\njQuery.Callbacks = function( options ) {\n\n\t// Convert options from String-formatted to Object-formatted if needed\n\t// (we check in cache first)\n\toptions = typeof options === \"string\" ?\n\t\tcreateOptions( options ) :\n\t\tjQuery.extend( {}, options );\n\n\tvar // Flag to know if list is currently firing\n\t\tfiring,\n\n\t\t// Last fire value for non-forgettable lists\n\t\tmemory,\n\n\t\t// Flag to know if list was already fired\n\t\tfired,\n\n\t\t// Flag to prevent firing\n\t\tlocked,\n\n\t\t// Actual callback list\n\t\tlist = [],\n\n\t\t// Queue of execution data for repeatable lists\n\t\tqueue = [],\n\n\t\t// Index of currently firing callback (modified by add/remove as needed)\n\t\tfiringIndex = -1,\n\n\t\t// Fire callbacks\n\t\tfire = function() {\n\n\t\t\t// Enforce single-firing\n\t\t\tlocked = options.once;\n\n\t\t\t// Execute callbacks for all pending executions,\n\t\t\t// respecting firingIndex overrides and runtime changes\n\t\t\tfired = firing = true;\n\t\t\tfor ( ; queue.length; firingIndex = -1 ) {\n\t\t\t\tmemory = queue.shift();\n\t\t\t\twhile ( ++firingIndex < list.length ) {\n\n\t\t\t\t\t// Run callback and check for early termination\n\t\t\t\t\tif ( list[ firingIndex ].apply( memory[ 0 ], memory[ 1 ] ) === false &&\n\t\t\t\t\t\toptions.stopOnFalse ) {\n\n\t\t\t\t\t\t// Jump to end and forget the data so .add doesn't re-fire\n\t\t\t\t\t\tfiringIndex = list.length;\n\t\t\t\t\t\tmemory = false;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Forget the data if we're done with it\n\t\t\tif ( !options.memory ) {\n\t\t\t\tmemory = false;\n\t\t\t}\n\n\t\t\tfiring = false;\n\n\t\t\t// Clean up if we're done firing for good\n\t\t\tif ( locked ) {\n\n\t\t\t\t// Keep an empty list if we have data for future add calls\n\t\t\t\tif ( memory ) {\n\t\t\t\t\tlist = [];\n\n\t\t\t\t// Otherwise, this object is spent\n\t\t\t\t} else {\n\t\t\t\t\tlist = \"\";\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\n\t\t// Actual Callbacks object\n\t\tself = {\n\n\t\t\t// Add a callback or a collection of callbacks to the list\n\t\t\tadd: function() {\n\t\t\t\tif ( list ) {\n\n\t\t\t\t\t// If we have memory from a past run, we should fire after adding\n\t\t\t\t\tif ( memory && !firing ) {\n\t\t\t\t\t\tfiringIndex = list.length - 1;\n\t\t\t\t\t\tqueue.push( memory );\n\t\t\t\t\t}\n\n\t\t\t\t\t( function add( args ) {\n\t\t\t\t\t\tjQuery.each( args, function( _, arg ) {\n\t\t\t\t\t\t\tif ( jQuery.isFunction( arg ) ) {\n\t\t\t\t\t\t\t\tif ( !options.unique || !self.has( arg ) ) {\n\t\t\t\t\t\t\t\t\tlist.push( arg );\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t} else if ( arg && arg.length && jQuery.type( arg ) !== \"string\" ) {\n\n\t\t\t\t\t\t\t\t// Inspect recursively\n\t\t\t\t\t\t\t\tadd( arg );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} );\n\t\t\t\t\t} )( arguments );\n\n\t\t\t\t\tif ( memory && !firing ) {\n\t\t\t\t\t\tfire();\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn this;\n\t\t\t},\n\n\t\t\t// Remove a callback from the list\n\t\t\tremove: function() {\n\t\t\t\tjQuery.each( arguments, function( _, arg ) {\n\t\t\t\t\tvar index;\n\t\t\t\t\twhile ( ( index = jQuery.inArray( arg, list, index ) ) > -1 ) {\n\t\t\t\t\t\tlist.splice( index, 1 );\n\n\t\t\t\t\t\t// Handle firing indexes\n\t\t\t\t\t\tif ( index <= firingIndex ) {\n\t\t\t\t\t\t\tfiringIndex--;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t} );\n\t\t\t\treturn this;\n\t\t\t},\n\n\t\t\t// Check if a given callback is in the list.\n\t\t\t// If no argument is given, return whether or not list has callbacks attached.\n\t\t\thas: function( fn ) {\n\t\t\t\treturn fn ?\n\t\t\t\t\tjQuery.inArray( fn, list ) > -1 :\n\t\t\t\t\tlist.length > 0;\n\t\t\t},\n\n\t\t\t// Remove all callbacks from the list\n\t\t\tempty: function() {\n\t\t\t\tif ( list ) {\n\t\t\t\t\tlist = [];\n\t\t\t\t}\n\t\t\t\treturn this;\n\t\t\t},\n\n\t\t\t// Disable .fire and .add\n\t\t\t// Abort any current/pending executions\n\t\t\t// Clear all callbacks and values\n\t\t\tdisable: function() {\n\t\t\t\tlocked = queue = [];\n\t\t\t\tlist = memory = \"\";\n\t\t\t\treturn this;\n\t\t\t},\n\t\t\tdisabled: function() {\n\t\t\t\treturn !list;\n\t\t\t},\n\n\t\t\t// Disable .fire\n\t\t\t// Also disable .add unless we have memory (since it would have no effect)\n\t\t\t// Abort any pending executions\n\t\t\tlock: function() {\n\t\t\t\tlocked = queue = [];\n\t\t\t\tif ( !memory && !firing ) {\n\t\t\t\t\tlist = memory = \"\";\n\t\t\t\t}\n\t\t\t\treturn this;\n\t\t\t},\n\t\t\tlocked: function() {\n\t\t\t\treturn !!locked;\n\t\t\t},\n\n\t\t\t// Call all callbacks with the given context and arguments\n\t\t\tfireWith: function( context, args ) {\n\t\t\t\tif ( !locked ) {\n\t\t\t\t\targs = args || [];\n\t\t\t\t\targs = [ context, args.slice ? args.slice() : args ];\n\t\t\t\t\tqueue.push( args );\n\t\t\t\t\tif ( !firing ) {\n\t\t\t\t\t\tfire();\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn this;\n\t\t\t},\n\n\t\t\t// Call all the callbacks with the given arguments\n\t\t\tfire: function() {\n\t\t\t\tself.fireWith( this, arguments );\n\t\t\t\treturn this;\n\t\t\t},\n\n\t\t\t// To know if the callbacks have already been called at least once\n\t\t\tfired: function() {\n\t\t\t\treturn !!fired;\n\t\t\t}\n\t\t};\n\n\treturn self;\n};\n\n\nfunction Identity( v ) {\n\treturn v;\n}\nfunction Thrower( ex ) {\n\tthrow ex;\n}\n\nfunction adoptValue( value, resolve, reject ) {\n\tvar method;\n\n\ttry {\n\n\t\t// Check for promise aspect first to privilege synchronous behavior\n\t\tif ( value && jQuery.isFunction( ( method = value.promise ) ) ) {\n\t\t\tmethod.call( value ).done( resolve ).fail( reject );\n\n\t\t// Other thenables\n\t\t} else if ( value && jQuery.isFunction( ( method = value.then ) ) ) {\n\t\t\tmethod.call( value, resolve, reject );\n\n\t\t// Other non-thenables\n\t\t} else {\n\n\t\t\t// Support: Android 4.0 only\n\t\t\t// Strict mode functions invoked without .call/.apply get global-object context\n\t\t\tresolve.call( undefined, value );\n\t\t}\n\n\t// For Promises/A+, convert exceptions into rejections\n\t// Since jQuery.when doesn't unwrap thenables, we can skip the extra checks appearing in\n\t// Deferred#then to conditionally suppress rejection.\n\t} catch ( value ) {\n\n\t\t// Support: Android 4.0 only\n\t\t// Strict mode functions invoked without .call/.apply get global-object context\n\t\treject.call( undefined, value );\n\t}\n}\n\njQuery.extend( {\n\n\tDeferred: function( func ) {\n\t\tvar tuples = [\n\n\t\t\t\t// action, add listener, callbacks,\n\t\t\t\t// ... .then handlers, argument index, [final state]\n\t\t\t\t[ \"notify\", \"progress\", jQuery.Callbacks( \"memory\" ),\n\t\t\t\t\tjQuery.Callbacks( \"memory\" ), 2 ],\n\t\t\t\t[ \"resolve\", \"done\", jQuery.Callbacks( \"once memory\" ),\n\t\t\t\t\tjQuery.Callbacks( \"once memory\" ), 0, \"resolved\" ],\n\t\t\t\t[ \"reject\", \"fail\", jQuery.Callbacks( \"once memory\" ),\n\t\t\t\t\tjQuery.Callbacks( \"once memory\" ), 1, \"rejected\" ]\n\t\t\t],\n\t\t\tstate = \"pending\",\n\t\t\tpromise = {\n\t\t\t\tstate: function() {\n\t\t\t\t\treturn state;\n\t\t\t\t},\n\t\t\t\talways: function() {\n\t\t\t\t\tdeferred.done( arguments ).fail( arguments );\n\t\t\t\t\treturn this;\n\t\t\t\t},\n\t\t\t\t\"catch\": function( fn ) {\n\t\t\t\t\treturn promise.then( null, fn );\n\t\t\t\t},\n\n\t\t\t\t// Keep pipe for back-compat\n\t\t\t\tpipe: function( /* fnDone, fnFail, fnProgress */ ) {\n\t\t\t\t\tvar fns = arguments;\n\n\t\t\t\t\treturn jQuery.Deferred( function( newDefer ) {\n\t\t\t\t\t\tjQuery.each( tuples, function( i, tuple ) {\n\n\t\t\t\t\t\t\t// Map tuples (progress, done, fail) to arguments (done, fail, progress)\n\t\t\t\t\t\t\tvar fn = jQuery.isFunction( fns[ tuple[ 4 ] ] ) && fns[ tuple[ 4 ] ];\n\n\t\t\t\t\t\t\t// deferred.progress(function() { bind to newDefer or newDefer.notify })\n\t\t\t\t\t\t\t// deferred.done(function() { bind to newDefer or newDefer.resolve })\n\t\t\t\t\t\t\t// deferred.fail(function() { bind to newDefer or newDefer.reject })\n\t\t\t\t\t\t\tdeferred[ tuple[ 1 ] ]( function() {\n\t\t\t\t\t\t\t\tvar returned = fn && fn.apply( this, arguments );\n\t\t\t\t\t\t\t\tif ( returned && jQuery.isFunction( returned.promise ) ) {\n\t\t\t\t\t\t\t\t\treturned.promise()\n\t\t\t\t\t\t\t\t\t\t.progress( newDefer.notify )\n\t\t\t\t\t\t\t\t\t\t.done( newDefer.resolve )\n\t\t\t\t\t\t\t\t\t\t.fail( newDefer.reject );\n\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\tnewDefer[ tuple[ 0 ] + \"With\" ](\n\t\t\t\t\t\t\t\t\t\tthis,\n\t\t\t\t\t\t\t\t\t\tfn ? [ returned ] : arguments\n\t\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t} );\n\t\t\t\t\t\t} );\n\t\t\t\t\t\tfns = null;\n\t\t\t\t\t} ).promise();\n\t\t\t\t},\n\t\t\t\tthen: function( onFulfilled, onRejected, onProgress ) {\n\t\t\t\t\tvar maxDepth = 0;\n\t\t\t\t\tfunction resolve( depth, deferred, handler, special ) {\n\t\t\t\t\t\treturn function() {\n\t\t\t\t\t\t\tvar that = this,\n\t\t\t\t\t\t\t\targs = arguments,\n\t\t\t\t\t\t\t\tmightThrow = function() {\n\t\t\t\t\t\t\t\t\tvar returned, then;\n\n\t\t\t\t\t\t\t\t\t// Support: Promises/A+ section 2.3.3.3.3\n\t\t\t\t\t\t\t\t\t// https://promisesaplus.com/#point-59\n\t\t\t\t\t\t\t\t\t// Ignore double-resolution attempts\n\t\t\t\t\t\t\t\t\tif ( depth < maxDepth ) {\n\t\t\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t\treturned = handler.apply( that, args );\n\n\t\t\t\t\t\t\t\t\t// Support: Promises/A+ section 2.3.1\n\t\t\t\t\t\t\t\t\t// https://promisesaplus.com/#point-48\n\t\t\t\t\t\t\t\t\tif ( returned === deferred.promise() ) {\n\t\t\t\t\t\t\t\t\t\tthrow new TypeError( \"Thenable self-resolution\" );\n\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t\t// Support: Promises/A+ sections 2.3.3.1, 3.5\n\t\t\t\t\t\t\t\t\t// https://promisesaplus.com/#point-54\n\t\t\t\t\t\t\t\t\t// https://promisesaplus.com/#point-75\n\t\t\t\t\t\t\t\t\t// Retrieve `then` only once\n\t\t\t\t\t\t\t\t\tthen = returned &&\n\n\t\t\t\t\t\t\t\t\t\t// Support: Promises/A+ section 2.3.4\n\t\t\t\t\t\t\t\t\t\t// https://promisesaplus.com/#point-64\n\t\t\t\t\t\t\t\t\t\t// Only check objects and functions for thenability\n\t\t\t\t\t\t\t\t\t\t( typeof returned === \"object\" ||\n\t\t\t\t\t\t\t\t\t\t\ttypeof returned === \"function\" ) &&\n\t\t\t\t\t\t\t\t\t\treturned.then;\n\n\t\t\t\t\t\t\t\t\t// Handle a returned thenable\n\t\t\t\t\t\t\t\t\tif ( jQuery.isFunction( then ) ) {\n\n\t\t\t\t\t\t\t\t\t\t// Special processors (notify) just wait for resolution\n\t\t\t\t\t\t\t\t\t\tif ( special ) {\n\t\t\t\t\t\t\t\t\t\t\tthen.call(\n\t\t\t\t\t\t\t\t\t\t\t\treturned,\n\t\t\t\t\t\t\t\t\t\t\t\tresolve( maxDepth, deferred, Identity, special ),\n\t\t\t\t\t\t\t\t\t\t\t\tresolve( maxDepth, deferred, Thrower, special )\n\t\t\t\t\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\t\t\t\t\t// Normal processors (resolve) also hook into progress\n\t\t\t\t\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\t\t\t\t\t// ...and disregard older resolution values\n\t\t\t\t\t\t\t\t\t\t\tmaxDepth++;\n\n\t\t\t\t\t\t\t\t\t\t\tthen.call(\n\t\t\t\t\t\t\t\t\t\t\t\treturned,\n\t\t\t\t\t\t\t\t\t\t\t\tresolve( maxDepth, deferred, Identity, special ),\n\t\t\t\t\t\t\t\t\t\t\t\tresolve( maxDepth, deferred, Thrower, special ),\n\t\t\t\t\t\t\t\t\t\t\t\tresolve( maxDepth, deferred, Identity,\n\t\t\t\t\t\t\t\t\t\t\t\t\tdeferred.notifyWith )\n\t\t\t\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t\t// Handle all other returned values\n\t\t\t\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\t\t\t\t// Only substitute handlers pass on context\n\t\t\t\t\t\t\t\t\t\t// and multiple values (non-spec behavior)\n\t\t\t\t\t\t\t\t\t\tif ( handler !== Identity ) {\n\t\t\t\t\t\t\t\t\t\t\tthat = undefined;\n\t\t\t\t\t\t\t\t\t\t\targs = [ returned ];\n\t\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t\t\t// Process the value(s)\n\t\t\t\t\t\t\t\t\t\t// Default process is resolve\n\t\t\t\t\t\t\t\t\t\t( special || deferred.resolveWith )( that, args );\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t},\n\n\t\t\t\t\t\t\t\t// Only normal processors (resolve) catch and reject exceptions\n\t\t\t\t\t\t\t\tprocess = special ?\n\t\t\t\t\t\t\t\t\tmightThrow :\n\t\t\t\t\t\t\t\t\tfunction() {\n\t\t\t\t\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t\t\t\t\tmightThrow();\n\t\t\t\t\t\t\t\t\t\t} catch ( e ) {\n\n\t\t\t\t\t\t\t\t\t\t\tif ( jQuery.Deferred.exceptionHook ) {\n\t\t\t\t\t\t\t\t\t\t\t\tjQuery.Deferred.exceptionHook( e,\n\t\t\t\t\t\t\t\t\t\t\t\t\tprocess.stackTrace );\n\t\t\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t\t\t\t// Support: Promises/A+ section 2.3.3.3.4.1\n\t\t\t\t\t\t\t\t\t\t\t// https://promisesaplus.com/#point-61\n\t\t\t\t\t\t\t\t\t\t\t// Ignore post-resolution exceptions\n\t\t\t\t\t\t\t\t\t\t\tif ( depth + 1 >= maxDepth ) {\n\n\t\t\t\t\t\t\t\t\t\t\t\t// Only substitute handlers pass on context\n\t\t\t\t\t\t\t\t\t\t\t\t// and multiple values (non-spec behavior)\n\t\t\t\t\t\t\t\t\t\t\t\tif ( handler !== Thrower ) {\n\t\t\t\t\t\t\t\t\t\t\t\t\tthat = undefined;\n\t\t\t\t\t\t\t\t\t\t\t\t\targs = [ e ];\n\t\t\t\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t\t\t\t\tdeferred.rejectWith( that, args );\n\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t};\n\n\t\t\t\t\t\t\t// Support: Promises/A+ section 2.3.3.3.1\n\t\t\t\t\t\t\t// https://promisesaplus.com/#point-57\n\t\t\t\t\t\t\t// Re-resolve promises immediately to dodge false rejection from\n\t\t\t\t\t\t\t// subsequent errors\n\t\t\t\t\t\t\tif ( depth ) {\n\t\t\t\t\t\t\t\tprocess();\n\t\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\t\t// Call an optional hook to record the stack, in case of exception\n\t\t\t\t\t\t\t\t// since it's otherwise lost when execution goes async\n\t\t\t\t\t\t\t\tif ( jQuery.Deferred.getStackHook ) {\n\t\t\t\t\t\t\t\t\tprocess.stackTrace = jQuery.Deferred.getStackHook();\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\twindow.setTimeout( process );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t};\n\t\t\t\t\t}\n\n\t\t\t\t\treturn jQuery.Deferred( function( newDefer ) {\n\n\t\t\t\t\t\t// progress_handlers.add( ... )\n\t\t\t\t\t\ttuples[ 0 ][ 3 ].add(\n\t\t\t\t\t\t\tresolve(\n\t\t\t\t\t\t\t\t0,\n\t\t\t\t\t\t\t\tnewDefer,\n\t\t\t\t\t\t\t\tjQuery.isFunction( onProgress ) ?\n\t\t\t\t\t\t\t\t\tonProgress :\n\t\t\t\t\t\t\t\t\tIdentity,\n\t\t\t\t\t\t\t\tnewDefer.notifyWith\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t);\n\n\t\t\t\t\t\t// fulfilled_handlers.add( ... )\n\t\t\t\t\t\ttuples[ 1 ][ 3 ].add(\n\t\t\t\t\t\t\tresolve(\n\t\t\t\t\t\t\t\t0,\n\t\t\t\t\t\t\t\tnewDefer,\n\t\t\t\t\t\t\t\tjQuery.isFunction( onFulfilled ) ?\n\t\t\t\t\t\t\t\t\tonFulfilled :\n\t\t\t\t\t\t\t\t\tIdentity\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t);\n\n\t\t\t\t\t\t// rejected_handlers.add( ... )\n\t\t\t\t\t\ttuples[ 2 ][ 3 ].add(\n\t\t\t\t\t\t\tresolve(\n\t\t\t\t\t\t\t\t0,\n\t\t\t\t\t\t\t\tnewDefer,\n\t\t\t\t\t\t\t\tjQuery.isFunction( onRejected ) ?\n\t\t\t\t\t\t\t\t\tonRejected :\n\t\t\t\t\t\t\t\t\tThrower\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t);\n\t\t\t\t\t} ).promise();\n\t\t\t\t},\n\n\t\t\t\t// Get a promise for this deferred\n\t\t\t\t// If obj is provided, the promise aspect is added to the object\n\t\t\t\tpromise: function( obj ) {\n\t\t\t\t\treturn obj != null ? jQuery.extend( obj, promise ) : promise;\n\t\t\t\t}\n\t\t\t},\n\t\t\tdeferred = {};\n\n\t\t// Add list-specific methods\n\t\tjQuery.each( tuples, function( i, tuple ) {\n\t\t\tvar list = tuple[ 2 ],\n\t\t\t\tstateString = tuple[ 5 ];\n\n\t\t\t// promise.progress = list.add\n\t\t\t// promise.done = list.add\n\t\t\t// promise.fail = list.add\n\t\t\tpromise[ tuple[ 1 ] ] = list.add;\n\n\t\t\t// Handle state\n\t\t\tif ( stateString ) {\n\t\t\t\tlist.add(\n\t\t\t\t\tfunction() {\n\n\t\t\t\t\t\t// state = \"resolved\" (i.e., fulfilled)\n\t\t\t\t\t\t// state = \"rejected\"\n\t\t\t\t\t\tstate = stateString;\n\t\t\t\t\t},\n\n\t\t\t\t\t// rejected_callbacks.disable\n\t\t\t\t\t// fulfilled_callbacks.disable\n\t\t\t\t\ttuples[ 3 - i ][ 2 ].disable,\n\n\t\t\t\t\t// progress_callbacks.lock\n\t\t\t\t\ttuples[ 0 ][ 2 ].lock\n\t\t\t\t);\n\t\t\t}\n\n\t\t\t// progress_handlers.fire\n\t\t\t// fulfilled_handlers.fire\n\t\t\t// rejected_handlers.fire\n\t\t\tlist.add( tuple[ 3 ].fire );\n\n\t\t\t// deferred.notify = function() { deferred.notifyWith(...) }\n\t\t\t// deferred.resolve = function() { deferred.resolveWith(...) }\n\t\t\t// deferred.reject = function() { deferred.rejectWith(...) }\n\t\t\tdeferred[ tuple[ 0 ] ] = function() {\n\t\t\t\tdeferred[ tuple[ 0 ] + \"With\" ]( this === deferred ? undefined : this, arguments );\n\t\t\t\treturn this;\n\t\t\t};\n\n\t\t\t// deferred.notifyWith = list.fireWith\n\t\t\t// deferred.resolveWith = list.fireWith\n\t\t\t// deferred.rejectWith = list.fireWith\n\t\t\tdeferred[ tuple[ 0 ] + \"With\" ] = list.fireWith;\n\t\t} );\n\n\t\t// Make the deferred a promise\n\t\tpromise.promise( deferred );\n\n\t\t// Call given func if any\n\t\tif ( func ) {\n\t\t\tfunc.call( deferred, deferred );\n\t\t}\n\n\t\t// All done!\n\t\treturn deferred;\n\t},\n\n\t// Deferred helper\n\twhen: function( singleValue ) {\n\t\tvar\n\n\t\t\t// count of uncompleted subordinates\n\t\t\tremaining = arguments.length,\n\n\t\t\t// count of unprocessed arguments\n\t\t\ti = remaining,\n\n\t\t\t// subordinate fulfillment data\n\t\t\tresolveContexts = Array( i ),\n\t\t\tresolveValues = slice.call( arguments ),\n\n\t\t\t// the master Deferred\n\t\t\tmaster = jQuery.Deferred(),\n\n\t\t\t// subordinate callback factory\n\t\t\tupdateFunc = function( i ) {\n\t\t\t\treturn function( value ) {\n\t\t\t\t\tresolveContexts[ i ] = this;\n\t\t\t\t\tresolveValues[ i ] = arguments.length > 1 ? slice.call( arguments ) : value;\n\t\t\t\t\tif ( !( --remaining ) ) {\n\t\t\t\t\t\tmaster.resolveWith( resolveContexts, resolveValues );\n\t\t\t\t\t}\n\t\t\t\t};\n\t\t\t};\n\n\t\t// Single- and empty arguments are adopted like Promise.resolve\n\t\tif ( remaining <= 1 ) {\n\t\t\tadoptValue( singleValue, master.done( updateFunc( i ) ).resolve, master.reject );\n\n\t\t\t// Use .then() to unwrap secondary thenables (cf. gh-3000)\n\t\t\tif ( master.state() === \"pending\" ||\n\t\t\t\tjQuery.isFunction( resolveValues[ i ] && resolveValues[ i ].then ) ) {\n\n\t\t\t\treturn master.then();\n\t\t\t}\n\t\t}\n\n\t\t// Multiple arguments are aggregated like Promise.all array elements\n\t\twhile ( i-- ) {\n\t\t\tadoptValue( resolveValues[ i ], updateFunc( i ), master.reject );\n\t\t}\n\n\t\treturn master.promise();\n\t}\n} );\n\n\n// These usually indicate a programmer mistake during development,\n// warn about them ASAP rather than swallowing them by default.\nvar rerrorNames = /^(Eval|Internal|Range|Reference|Syntax|Type|URI)Error$/;\n\njQuery.Deferred.exceptionHook = function( error, stack ) {\n\n\t// Support: IE 8 - 9 only\n\t// Console exists when dev tools are open, which can happen at any time\n\tif ( window.console && window.console.warn && error && rerrorNames.test( error.name ) ) {\n\t\twindow.console.warn( \"jQuery.Deferred exception: \" + error.message, error.stack, stack );\n\t}\n};\n\n\n\n\njQuery.readyException = function( error ) {\n\twindow.setTimeout( function() {\n\t\tthrow error;\n\t} );\n};\n\n\n\n\n// The deferred used on DOM ready\nvar readyList = jQuery.Deferred();\n\njQuery.fn.ready = function( fn ) {\n\n\treadyList\n\t\t.then( fn )\n\n\t\t// Wrap jQuery.readyException in a function so that the lookup\n\t\t// happens at the time of error handling instead of callback\n\t\t// registration.\n\t\t.catch( function( error ) {\n\t\t\tjQuery.readyException( error );\n\t\t} );\n\n\treturn this;\n};\n\njQuery.extend( {\n\n\t// Is the DOM ready to be used? Set to true once it occurs.\n\tisReady: false,\n\n\t// A counter to track how many items to wait for before\n\t// the ready event fires. See #6781\n\treadyWait: 1,\n\n\t// Hold (or release) the ready event\n\tholdReady: function( hold ) {\n\t\tif ( hold ) {\n\t\t\tjQuery.readyWait++;\n\t\t} else {\n\t\t\tjQuery.ready( true );\n\t\t}\n\t},\n\n\t// Handle when the DOM is ready\n\tready: function( wait ) {\n\n\t\t// Abort if there are pending holds or we're already ready\n\t\tif ( wait === true ? --jQuery.readyWait : jQuery.isReady ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Remember that the DOM is ready\n\t\tjQuery.isReady = true;\n\n\t\t// If a normal DOM Ready event fired, decrement, and wait if need be\n\t\tif ( wait !== true && --jQuery.readyWait > 0 ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// If there are functions bound, to execute\n\t\treadyList.resolveWith( document, [ jQuery ] );\n\t}\n} );\n\njQuery.ready.then = readyList.then;\n\n// The ready event handler and self cleanup method\nfunction completed() {\n\tdocument.removeEventListener( \"DOMContentLoaded\", completed );\n\twindow.removeEventListener( \"load\", completed );\n\tjQuery.ready();\n}\n\n// Catch cases where $(document).ready() is called\n// after the browser event has already occurred.\n// Support: IE <=9 - 10 only\n// Older IE sometimes signals \"interactive\" too soon\nif ( document.readyState === \"complete\" ||\n\t( document.readyState !== \"loading\" && !document.documentElement.doScroll ) ) {\n\n\t// Handle it asynchronously to allow scripts the opportunity to delay ready\n\twindow.setTimeout( jQuery.ready );\n\n} else {\n\n\t// Use the handy event callback\n\tdocument.addEventListener( \"DOMContentLoaded\", completed );\n\n\t// A fallback to window.onload, that will always work\n\twindow.addEventListener( \"load\", completed );\n}\n\n\n\n\n// Multifunctional method to get and set values of a collection\n// The value/s can optionally be executed if it's a function\nvar access = function( elems, fn, key, value, chainable, emptyGet, raw ) {\n\tvar i = 0,\n\t\tlen = elems.length,\n\t\tbulk = key == null;\n\n\t// Sets many values\n\tif ( jQuery.type( key ) === \"object\" ) {\n\t\tchainable = true;\n\t\tfor ( i in key ) {\n\t\t\taccess( elems, fn, i, key[ i ], true, emptyGet, raw );\n\t\t}\n\n\t// Sets one value\n\t} else if ( value !== undefined ) {\n\t\tchainable = true;\n\n\t\tif ( !jQuery.isFunction( value ) ) {\n\t\t\traw = true;\n\t\t}\n\n\t\tif ( bulk ) {\n\n\t\t\t// Bulk operations run against the entire set\n\t\t\tif ( raw ) {\n\t\t\t\tfn.call( elems, value );\n\t\t\t\tfn = null;\n\n\t\t\t// ...except when executing function values\n\t\t\t} else {\n\t\t\t\tbulk = fn;\n\t\t\t\tfn = function( elem, key, value ) {\n\t\t\t\t\treturn bulk.call( jQuery( elem ), value );\n\t\t\t\t};\n\t\t\t}\n\t\t}\n\n\t\tif ( fn ) {\n\t\t\tfor ( ; i < len; i++ ) {\n\t\t\t\tfn(\n\t\t\t\t\telems[ i ], key, raw ?\n\t\t\t\t\tvalue :\n\t\t\t\t\tvalue.call( elems[ i ], i, fn( elems[ i ], key ) )\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\t}\n\n\treturn chainable ?\n\t\telems :\n\n\t\t// Gets\n\t\tbulk ?\n\t\t\tfn.call( elems ) :\n\t\t\tlen ? fn( elems[ 0 ], key ) : emptyGet;\n};\nvar acceptData = function( owner ) {\n\n\t// Accepts only:\n\t//  - Node\n\t//    - Node.ELEMENT_NODE\n\t//    - Node.DOCUMENT_NODE\n\t//  - Object\n\t//    - Any\n\treturn owner.nodeType === 1 || owner.nodeType === 9 || !( +owner.nodeType );\n};\n\n\n\n\nfunction Data() {\n\tthis.expando = jQuery.expando + Data.uid++;\n}\n\nData.uid = 1;\n\nData.prototype = {\n\n\tcache: function( owner ) {\n\n\t\t// Check if the owner object already has a cache\n\t\tvar value = owner[ this.expando ];\n\n\t\t// If not, create one\n\t\tif ( !value ) {\n\t\t\tvalue = {};\n\n\t\t\t// We can accept data for non-element nodes in modern browsers,\n\t\t\t// but we should not, see #8335.\n\t\t\t// Always return an empty object.\n\t\t\tif ( acceptData( owner ) ) {\n\n\t\t\t\t// If it is a node unlikely to be stringify-ed or looped over\n\t\t\t\t// use plain assignment\n\t\t\t\tif ( owner.nodeType ) {\n\t\t\t\t\towner[ this.expando ] = value;\n\n\t\t\t\t// Otherwise secure it in a non-enumerable property\n\t\t\t\t// configurable must be true to allow the property to be\n\t\t\t\t// deleted when data is removed\n\t\t\t\t} else {\n\t\t\t\t\tObject.defineProperty( owner, this.expando, {\n\t\t\t\t\t\tvalue: value,\n\t\t\t\t\t\tconfigurable: true\n\t\t\t\t\t} );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn value;\n\t},\n\tset: function( owner, data, value ) {\n\t\tvar prop,\n\t\t\tcache = this.cache( owner );\n\n\t\t// Handle: [ owner, key, value ] args\n\t\t// Always use camelCase key (gh-2257)\n\t\tif ( typeof data === \"string\" ) {\n\t\t\tcache[ jQuery.camelCase( data ) ] = value;\n\n\t\t// Handle: [ owner, { properties } ] args\n\t\t} else {\n\n\t\t\t// Copy the properties one-by-one to the cache object\n\t\t\tfor ( prop in data ) {\n\t\t\t\tcache[ jQuery.camelCase( prop ) ] = data[ prop ];\n\t\t\t}\n\t\t}\n\t\treturn cache;\n\t},\n\tget: function( owner, key ) {\n\t\treturn key === undefined ?\n\t\t\tthis.cache( owner ) :\n\n\t\t\t// Always use camelCase key (gh-2257)\n\t\t\towner[ this.expando ] && owner[ this.expando ][ jQuery.camelCase( key ) ];\n\t},\n\taccess: function( owner, key, value ) {\n\n\t\t// In cases where either:\n\t\t//\n\t\t//   1. No key was specified\n\t\t//   2. A string key was specified, but no value provided\n\t\t//\n\t\t// Take the \"read\" path and allow the get method to determine\n\t\t// which value to return, respectively either:\n\t\t//\n\t\t//   1. The entire cache object\n\t\t//   2. The data stored at the key\n\t\t//\n\t\tif ( key === undefined ||\n\t\t\t\t( ( key && typeof key === \"string\" ) && value === undefined ) ) {\n\n\t\t\treturn this.get( owner, key );\n\t\t}\n\n\t\t// When the key is not a string, or both a key and value\n\t\t// are specified, set or extend (existing objects) with either:\n\t\t//\n\t\t//   1. An object of properties\n\t\t//   2. A key and value\n\t\t//\n\t\tthis.set( owner, key, value );\n\n\t\t// Since the \"set\" path can have two possible entry points\n\t\t// return the expected data based on which path was taken[*]\n\t\treturn value !== undefined ? value : key;\n\t},\n\tremove: function( owner, key ) {\n\t\tvar i,\n\t\t\tcache = owner[ this.expando ];\n\n\t\tif ( cache === undefined ) {\n\t\t\treturn;\n\t\t}\n\n\t\tif ( key !== undefined ) {\n\n\t\t\t// Support array or space separated string of keys\n\t\t\tif ( jQuery.isArray( key ) ) {\n\n\t\t\t\t// If key is an array of keys...\n\t\t\t\t// We always set camelCase keys, so remove that.\n\t\t\t\tkey = key.map( jQuery.camelCase );\n\t\t\t} else {\n\t\t\t\tkey = jQuery.camelCase( key );\n\n\t\t\t\t// If a key with the spaces exists, use it.\n\t\t\t\t// Otherwise, create an array by matching non-whitespace\n\t\t\t\tkey = key in cache ?\n\t\t\t\t\t[ key ] :\n\t\t\t\t\t( key.match( rnotwhite ) || [] );\n\t\t\t}\n\n\t\t\ti = key.length;\n\n\t\t\twhile ( i-- ) {\n\t\t\t\tdelete cache[ key[ i ] ];\n\t\t\t}\n\t\t}\n\n\t\t// Remove the expando if there's no more data\n\t\tif ( key === undefined || jQuery.isEmptyObject( cache ) ) {\n\n\t\t\t// Support: Chrome <=35 - 45\n\t\t\t// Webkit & Blink performance suffers when deleting properties\n\t\t\t// from DOM nodes, so set to undefined instead\n\t\t\t// https://bugs.chromium.org/p/chromium/issues/detail?id=378607 (bug restricted)\n\t\t\tif ( owner.nodeType ) {\n\t\t\t\towner[ this.expando ] = undefined;\n\t\t\t} else {\n\t\t\t\tdelete owner[ this.expando ];\n\t\t\t}\n\t\t}\n\t},\n\thasData: function( owner ) {\n\t\tvar cache = owner[ this.expando ];\n\t\treturn cache !== undefined && !jQuery.isEmptyObject( cache );\n\t}\n};\nvar dataPriv = new Data();\n\nvar dataUser = new Data();\n\n\n\n//\tImplementation Summary\n//\n//\t1. Enforce API surface and semantic compatibility with 1.9.x branch\n//\t2. Improve the module's maintainability by reducing the storage\n//\t\tpaths to a single mechanism.\n//\t3. Use the same single mechanism to support \"private\" and \"user\" data.\n//\t4. _Never_ expose \"private\" data to user code (TODO: Drop _data, _removeData)\n//\t5. Avoid exposing implementation details on user objects (eg. expando properties)\n//\t6. Provide a clear path for implementation upgrade to WeakMap in 2014\n\nvar rbrace = /^(?:\\{[\\w\\W]*\\}|\\[[\\w\\W]*\\])$/,\n\trmultiDash = /[A-Z]/g;\n\nfunction dataAttr( elem, key, data ) {\n\tvar name;\n\n\t// If nothing was found internally, try to fetch any\n\t// data from the HTML5 data-* attribute\n\tif ( data === undefined && elem.nodeType === 1 ) {\n\t\tname = \"data-\" + key.replace( rmultiDash, \"-$&\" ).toLowerCase();\n\t\tdata = elem.getAttribute( name );\n\n\t\tif ( typeof data === \"string\" ) {\n\t\t\ttry {\n\t\t\t\tdata = data === \"true\" ? true :\n\t\t\t\t\tdata === \"false\" ? false :\n\t\t\t\t\tdata === \"null\" ? null :\n\n\t\t\t\t\t// Only convert to a number if it doesn't change the string\n\t\t\t\t\t+data + \"\" === data ? +data :\n\t\t\t\t\trbrace.test( data ) ? JSON.parse( data ) :\n\t\t\t\t\tdata;\n\t\t\t} catch ( e ) {}\n\n\t\t\t// Make sure we set the data so it isn't changed later\n\t\t\tdataUser.set( elem, key, data );\n\t\t} else {\n\t\t\tdata = undefined;\n\t\t}\n\t}\n\treturn data;\n}\n\njQuery.extend( {\n\thasData: function( elem ) {\n\t\treturn dataUser.hasData( elem ) || dataPriv.hasData( elem );\n\t},\n\n\tdata: function( elem, name, data ) {\n\t\treturn dataUser.access( elem, name, data );\n\t},\n\n\tremoveData: function( elem, name ) {\n\t\tdataUser.remove( elem, name );\n\t},\n\n\t// TODO: Now that all calls to _data and _removeData have been replaced\n\t// with direct calls to dataPriv methods, these can be deprecated.\n\t_data: function( elem, name, data ) {\n\t\treturn dataPriv.access( elem, name, data );\n\t},\n\n\t_removeData: function( elem, name ) {\n\t\tdataPriv.remove( elem, name );\n\t}\n} );\n\njQuery.fn.extend( {\n\tdata: function( key, value ) {\n\t\tvar i, name, data,\n\t\t\telem = this[ 0 ],\n\t\t\tattrs = elem && elem.attributes;\n\n\t\t// Gets all values\n\t\tif ( key === undefined ) {\n\t\t\tif ( this.length ) {\n\t\t\t\tdata = dataUser.get( elem );\n\n\t\t\t\tif ( elem.nodeType === 1 && !dataPriv.get( elem, \"hasDataAttrs\" ) ) {\n\t\t\t\t\ti = attrs.length;\n\t\t\t\t\twhile ( i-- ) {\n\n\t\t\t\t\t\t// Support: IE 11 only\n\t\t\t\t\t\t// The attrs elements can be null (#14894)\n\t\t\t\t\t\tif ( attrs[ i ] ) {\n\t\t\t\t\t\t\tname = attrs[ i ].name;\n\t\t\t\t\t\t\tif ( name.indexOf( \"data-\" ) === 0 ) {\n\t\t\t\t\t\t\t\tname = jQuery.camelCase( name.slice( 5 ) );\n\t\t\t\t\t\t\t\tdataAttr( elem, name, data[ name ] );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tdataPriv.set( elem, \"hasDataAttrs\", true );\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn data;\n\t\t}\n\n\t\t// Sets multiple values\n\t\tif ( typeof key === \"object\" ) {\n\t\t\treturn this.each( function() {\n\t\t\t\tdataUser.set( this, key );\n\t\t\t} );\n\t\t}\n\n\t\treturn access( this, function( value ) {\n\t\t\tvar data;\n\n\t\t\t// The calling jQuery object (element matches) is not empty\n\t\t\t// (and therefore has an element appears at this[ 0 ]) and the\n\t\t\t// `value` parameter was not undefined. An empty jQuery object\n\t\t\t// will result in `undefined` for elem = this[ 0 ] which will\n\t\t\t// throw an exception if an attempt to read a data cache is made.\n\t\t\tif ( elem && value === undefined ) {\n\n\t\t\t\t// Attempt to get data from the cache\n\t\t\t\t// The key will always be camelCased in Data\n\t\t\t\tdata = dataUser.get( elem, key );\n\t\t\t\tif ( data !== undefined ) {\n\t\t\t\t\treturn data;\n\t\t\t\t}\n\n\t\t\t\t// Attempt to \"discover\" the data in\n\t\t\t\t// HTML5 custom data-* attrs\n\t\t\t\tdata = dataAttr( elem, key );\n\t\t\t\tif ( data !== undefined ) {\n\t\t\t\t\treturn data;\n\t\t\t\t}\n\n\t\t\t\t// We tried really hard, but the data doesn't exist.\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// Set the data...\n\t\t\tthis.each( function() {\n\n\t\t\t\t// We always store the camelCased key\n\t\t\t\tdataUser.set( this, key, value );\n\t\t\t} );\n\t\t}, null, value, arguments.length > 1, null, true );\n\t},\n\n\tremoveData: function( key ) {\n\t\treturn this.each( function() {\n\t\t\tdataUser.remove( this, key );\n\t\t} );\n\t}\n} );\n\n\njQuery.extend( {\n\tqueue: function( elem, type, data ) {\n\t\tvar queue;\n\n\t\tif ( elem ) {\n\t\t\ttype = ( type || \"fx\" ) + \"queue\";\n\t\t\tqueue = dataPriv.get( elem, type );\n\n\t\t\t// Speed up dequeue by getting out quickly if this is just a lookup\n\t\t\tif ( data ) {\n\t\t\t\tif ( !queue || jQuery.isArray( data ) ) {\n\t\t\t\t\tqueue = dataPriv.access( elem, type, jQuery.makeArray( data ) );\n\t\t\t\t} else {\n\t\t\t\t\tqueue.push( data );\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn queue || [];\n\t\t}\n\t},\n\n\tdequeue: function( elem, type ) {\n\t\ttype = type || \"fx\";\n\n\t\tvar queue = jQuery.queue( elem, type ),\n\t\t\tstartLength = queue.length,\n\t\t\tfn = queue.shift(),\n\t\t\thooks = jQuery._queueHooks( elem, type ),\n\t\t\tnext = function() {\n\t\t\t\tjQuery.dequeue( elem, type );\n\t\t\t};\n\n\t\t// If the fx queue is dequeued, always remove the progress sentinel\n\t\tif ( fn === \"inprogress\" ) {\n\t\t\tfn = queue.shift();\n\t\t\tstartLength--;\n\t\t}\n\n\t\tif ( fn ) {\n\n\t\t\t// Add a progress sentinel to prevent the fx queue from being\n\t\t\t// automatically dequeued\n\t\t\tif ( type === \"fx\" ) {\n\t\t\t\tqueue.unshift( \"inprogress\" );\n\t\t\t}\n\n\t\t\t// Clear up the last queue stop function\n\t\t\tdelete hooks.stop;\n\t\t\tfn.call( elem, next, hooks );\n\t\t}\n\n\t\tif ( !startLength && hooks ) {\n\t\t\thooks.empty.fire();\n\t\t}\n\t},\n\n\t// Not public - generate a queueHooks object, or return the current one\n\t_queueHooks: function( elem, type ) {\n\t\tvar key = type + \"queueHooks\";\n\t\treturn dataPriv.get( elem, key ) || dataPriv.access( elem, key, {\n\t\t\tempty: jQuery.Callbacks( \"once memory\" ).add( function() {\n\t\t\t\tdataPriv.remove( elem, [ type + \"queue\", key ] );\n\t\t\t} )\n\t\t} );\n\t}\n} );\n\njQuery.fn.extend( {\n\tqueue: function( type, data ) {\n\t\tvar setter = 2;\n\n\t\tif ( typeof type !== \"string\" ) {\n\t\t\tdata = type;\n\t\t\ttype = \"fx\";\n\t\t\tsetter--;\n\t\t}\n\n\t\tif ( arguments.length < setter ) {\n\t\t\treturn jQuery.queue( this[ 0 ], type );\n\t\t}\n\n\t\treturn data === undefined ?\n\t\t\tthis :\n\t\t\tthis.each( function() {\n\t\t\t\tvar queue = jQuery.queue( this, type, data );\n\n\t\t\t\t// Ensure a hooks for this queue\n\t\t\t\tjQuery._queueHooks( this, type );\n\n\t\t\t\tif ( type === \"fx\" && queue[ 0 ] !== \"inprogress\" ) {\n\t\t\t\t\tjQuery.dequeue( this, type );\n\t\t\t\t}\n\t\t\t} );\n\t},\n\tdequeue: function( type ) {\n\t\treturn this.each( function() {\n\t\t\tjQuery.dequeue( this, type );\n\t\t} );\n\t},\n\tclearQueue: function( type ) {\n\t\treturn this.queue( type || \"fx\", [] );\n\t},\n\n\t// Get a promise resolved when queues of a certain type\n\t// are emptied (fx is the type by default)\n\tpromise: function( type, obj ) {\n\t\tvar tmp,\n\t\t\tcount = 1,\n\t\t\tdefer = jQuery.Deferred(),\n\t\t\telements = this,\n\t\t\ti = this.length,\n\t\t\tresolve = function() {\n\t\t\t\tif ( !( --count ) ) {\n\t\t\t\t\tdefer.resolveWith( elements, [ elements ] );\n\t\t\t\t}\n\t\t\t};\n\n\t\tif ( typeof type !== \"string\" ) {\n\t\t\tobj = type;\n\t\t\ttype = undefined;\n\t\t}\n\t\ttype = type || \"fx\";\n\n\t\twhile ( i-- ) {\n\t\t\ttmp = dataPriv.get( elements[ i ], type + \"queueHooks\" );\n\t\t\tif ( tmp && tmp.empty ) {\n\t\t\t\tcount++;\n\t\t\t\ttmp.empty.add( resolve );\n\t\t\t}\n\t\t}\n\t\tresolve();\n\t\treturn defer.promise( obj );\n\t}\n} );\nvar pnum = ( /[+-]?(?:\\d*\\.|)\\d+(?:[eE][+-]?\\d+|)/ ).source;\n\nvar rcssNum = new RegExp( \"^(?:([+-])=|)(\" + pnum + \")([a-z%]*)$\", \"i\" );\n\n\nvar cssExpand = [ \"Top\", \"Right\", \"Bottom\", \"Left\" ];\n\nvar isHiddenWithinTree = function( elem, el ) {\n\n\t\t// isHiddenWithinTree might be called from jQuery#filter function;\n\t\t// in that case, element will be second argument\n\t\telem = el || elem;\n\n\t\t// Inline style trumps all\n\t\treturn elem.style.display === \"none\" ||\n\t\t\telem.style.display === \"\" &&\n\n\t\t\t// Otherwise, check computed style\n\t\t\t// Support: Firefox <=43 - 45\n\t\t\t// Disconnected elements can have computed display: none, so first confirm that elem is\n\t\t\t// in the document.\n\t\t\tjQuery.contains( elem.ownerDocument, elem ) &&\n\n\t\t\tjQuery.css( elem, \"display\" ) === \"none\";\n\t};\n\nvar swap = function( elem, options, callback, args ) {\n\tvar ret, name,\n\t\told = {};\n\n\t// Remember the old values, and insert the new ones\n\tfor ( name in options ) {\n\t\told[ name ] = elem.style[ name ];\n\t\telem.style[ name ] = options[ name ];\n\t}\n\n\tret = callback.apply( elem, args || [] );\n\n\t// Revert the old values\n\tfor ( name in options ) {\n\t\telem.style[ name ] = old[ name ];\n\t}\n\n\treturn ret;\n};\n\n\n\n\nfunction adjustCSS( elem, prop, valueParts, tween ) {\n\tvar adjusted,\n\t\tscale = 1,\n\t\tmaxIterations = 20,\n\t\tcurrentValue = tween ?\n\t\t\tfunction() {\n\t\t\t\treturn tween.cur();\n\t\t\t} :\n\t\t\tfunction() {\n\t\t\t\treturn jQuery.css( elem, prop, \"\" );\n\t\t\t},\n\t\tinitial = currentValue(),\n\t\tunit = valueParts && valueParts[ 3 ] || ( jQuery.cssNumber[ prop ] ? \"\" : \"px\" ),\n\n\t\t// Starting value computation is required for potential unit mismatches\n\t\tinitialInUnit = ( jQuery.cssNumber[ prop ] || unit !== \"px\" && +initial ) &&\n\t\t\trcssNum.exec( jQuery.css( elem, prop ) );\n\n\tif ( initialInUnit && initialInUnit[ 3 ] !== unit ) {\n\n\t\t// Trust units reported by jQuery.css\n\t\tunit = unit || initialInUnit[ 3 ];\n\n\t\t// Make sure we update the tween properties later on\n\t\tvalueParts = valueParts || [];\n\n\t\t// Iteratively approximate from a nonzero starting point\n\t\tinitialInUnit = +initial || 1;\n\n\t\tdo {\n\n\t\t\t// If previous iteration zeroed out, double until we get *something*.\n\t\t\t// Use string for doubling so we don't accidentally see scale as unchanged below\n\t\t\tscale = scale || \".5\";\n\n\t\t\t// Adjust and apply\n\t\t\tinitialInUnit = initialInUnit / scale;\n\t\t\tjQuery.style( elem, prop, initialInUnit + unit );\n\n\t\t// Update scale, tolerating zero or NaN from tween.cur()\n\t\t// Break the loop if scale is unchanged or perfect, or if we've just had enough.\n\t\t} while (\n\t\t\tscale !== ( scale = currentValue() / initial ) && scale !== 1 && --maxIterations\n\t\t);\n\t}\n\n\tif ( valueParts ) {\n\t\tinitialInUnit = +initialInUnit || +initial || 0;\n\n\t\t// Apply relative offset (+=/-=) if specified\n\t\tadjusted = valueParts[ 1 ] ?\n\t\t\tinitialInUnit + ( valueParts[ 1 ] + 1 ) * valueParts[ 2 ] :\n\t\t\t+valueParts[ 2 ];\n\t\tif ( tween ) {\n\t\t\ttween.unit = unit;\n\t\t\ttween.start = initialInUnit;\n\t\t\ttween.end = adjusted;\n\t\t}\n\t}\n\treturn adjusted;\n}\n\n\nvar defaultDisplayMap = {};\n\nfunction getDefaultDisplay( elem ) {\n\tvar temp,\n\t\tdoc = elem.ownerDocument,\n\t\tnodeName = elem.nodeName,\n\t\tdisplay = defaultDisplayMap[ nodeName ];\n\n\tif ( display ) {\n\t\treturn display;\n\t}\n\n\ttemp = doc.body.appendChild( doc.createElement( nodeName ) ),\n\tdisplay = jQuery.css( temp, \"display\" );\n\n\ttemp.parentNode.removeChild( temp );\n\n\tif ( display === \"none\" ) {\n\t\tdisplay = \"block\";\n\t}\n\tdefaultDisplayMap[ nodeName ] = display;\n\n\treturn display;\n}\n\nfunction showHide( elements, show ) {\n\tvar display, elem,\n\t\tvalues = [],\n\t\tindex = 0,\n\t\tlength = elements.length;\n\n\t// Determine new display value for elements that need to change\n\tfor ( ; index < length; index++ ) {\n\t\telem = elements[ index ];\n\t\tif ( !elem.style ) {\n\t\t\tcontinue;\n\t\t}\n\n\t\tdisplay = elem.style.display;\n\t\tif ( show ) {\n\n\t\t\t// Since we force visibility upon cascade-hidden elements, an immediate (and slow)\n\t\t\t// check is required in this first loop unless we have a nonempty display value (either\n\t\t\t// inline or about-to-be-restored)\n\t\t\tif ( display === \"none\" ) {\n\t\t\t\tvalues[ index ] = dataPriv.get( elem, \"display\" ) || null;\n\t\t\t\tif ( !values[ index ] ) {\n\t\t\t\t\telem.style.display = \"\";\n\t\t\t\t}\n\t\t\t}\n\t\t\tif ( elem.style.display === \"\" && isHiddenWithinTree( elem ) ) {\n\t\t\t\tvalues[ index ] = getDefaultDisplay( elem );\n\t\t\t}\n\t\t} else {\n\t\t\tif ( display !== \"none\" ) {\n\t\t\t\tvalues[ index ] = \"none\";\n\n\t\t\t\t// Remember what we're overwriting\n\t\t\t\tdataPriv.set( elem, \"display\", display );\n\t\t\t}\n\t\t}\n\t}\n\n\t// Set the display of the elements in a second loop to avoid constant reflow\n\tfor ( index = 0; index < length; index++ ) {\n\t\tif ( values[ index ] != null ) {\n\t\t\telements[ index ].style.display = values[ index ];\n\t\t}\n\t}\n\n\treturn elements;\n}\n\njQuery.fn.extend( {\n\tshow: function() {\n\t\treturn showHide( this, true );\n\t},\n\thide: function() {\n\t\treturn showHide( this );\n\t},\n\ttoggle: function( state ) {\n\t\tif ( typeof state === \"boolean\" ) {\n\t\t\treturn state ? this.show() : this.hide();\n\t\t}\n\n\t\treturn this.each( function() {\n\t\t\tif ( isHiddenWithinTree( this ) ) {\n\t\t\t\tjQuery( this ).show();\n\t\t\t} else {\n\t\t\t\tjQuery( this ).hide();\n\t\t\t}\n\t\t} );\n\t}\n} );\nvar rcheckableType = ( /^(?:checkbox|radio)$/i );\n\nvar rtagName = ( /<([a-z][^\\/\\0>\\x20\\t\\r\\n\\f]+)/i );\n\nvar rscriptType = ( /^$|\\/(?:java|ecma)script/i );\n\n\n\n// We have to close these tags to support XHTML (#13200)\nvar wrapMap = {\n\n\t// Support: IE <=9 only\n\toption: [ 1, \"<select multiple='multiple'>\", \"</select>\" ],\n\n\t// XHTML parsers do not magically insert elements in the\n\t// same way that tag soup parsers do. So we cannot shorten\n\t// this by omitting <tbody> or other required elements.\n\tthead: [ 1, \"<table>\", \"</table>\" ],\n\tcol: [ 2, \"<table><colgroup>\", \"</colgroup></table>\" ],\n\ttr: [ 2, \"<table><tbody>\", \"</tbody></table>\" ],\n\ttd: [ 3, \"<table><tbody><tr>\", \"</tr></tbody></table>\" ],\n\n\t_default: [ 0, \"\", \"\" ]\n};\n\n// Support: IE <=9 only\nwrapMap.optgroup = wrapMap.option;\n\nwrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead;\nwrapMap.th = wrapMap.td;\n\n\nfunction getAll( context, tag ) {\n\n\t// Support: IE <=9 - 11 only\n\t// Use typeof to avoid zero-argument method invocation on host objects (#15151)\n\tvar ret = typeof context.getElementsByTagName !== \"undefined\" ?\n\t\t\tcontext.getElementsByTagName( tag || \"*\" ) :\n\t\t\ttypeof context.querySelectorAll !== \"undefined\" ?\n\t\t\t\tcontext.querySelectorAll( tag || \"*\" ) :\n\t\t\t[];\n\n\treturn tag === undefined || tag && jQuery.nodeName( context, tag ) ?\n\t\tjQuery.merge( [ context ], ret ) :\n\t\tret;\n}\n\n\n// Mark scripts as having already been evaluated\nfunction setGlobalEval( elems, refElements ) {\n\tvar i = 0,\n\t\tl = elems.length;\n\n\tfor ( ; i < l; i++ ) {\n\t\tdataPriv.set(\n\t\t\telems[ i ],\n\t\t\t\"globalEval\",\n\t\t\t!refElements || dataPriv.get( refElements[ i ], \"globalEval\" )\n\t\t);\n\t}\n}\n\n\nvar rhtml = /<|&#?\\w+;/;\n\nfunction buildFragment( elems, context, scripts, selection, ignored ) {\n\tvar elem, tmp, tag, wrap, contains, j,\n\t\tfragment = context.createDocumentFragment(),\n\t\tnodes = [],\n\t\ti = 0,\n\t\tl = elems.length;\n\n\tfor ( ; i < l; i++ ) {\n\t\telem = elems[ i ];\n\n\t\tif ( elem || elem === 0 ) {\n\n\t\t\t// Add nodes directly\n\t\t\tif ( jQuery.type( elem ) === \"object\" ) {\n\n\t\t\t\t// Support: Android <=4.0 only, PhantomJS 1 only\n\t\t\t\t// push.apply(_, arraylike) throws on ancient WebKit\n\t\t\t\tjQuery.merge( nodes, elem.nodeType ? [ elem ] : elem );\n\n\t\t\t// Convert non-html into a text node\n\t\t\t} else if ( !rhtml.test( elem ) ) {\n\t\t\t\tnodes.push( context.createTextNode( elem ) );\n\n\t\t\t// Convert html into DOM nodes\n\t\t\t} else {\n\t\t\t\ttmp = tmp || fragment.appendChild( context.createElement( \"div\" ) );\n\n\t\t\t\t// Deserialize a standard representation\n\t\t\t\ttag = ( rtagName.exec( elem ) || [ \"\", \"\" ] )[ 1 ].toLowerCase();\n\t\t\t\twrap = wrapMap[ tag ] || wrapMap._default;\n\t\t\t\ttmp.innerHTML = wrap[ 1 ] + jQuery.htmlPrefilter( elem ) + wrap[ 2 ];\n\n\t\t\t\t// Descend through wrappers to the right content\n\t\t\t\tj = wrap[ 0 ];\n\t\t\t\twhile ( j-- ) {\n\t\t\t\t\ttmp = tmp.lastChild;\n\t\t\t\t}\n\n\t\t\t\t// Support: Android <=4.0 only, PhantomJS 1 only\n\t\t\t\t// push.apply(_, arraylike) throws on ancient WebKit\n\t\t\t\tjQuery.merge( nodes, tmp.childNodes );\n\n\t\t\t\t// Remember the top-level container\n\t\t\t\ttmp = fragment.firstChild;\n\n\t\t\t\t// Ensure the created nodes are orphaned (#12392)\n\t\t\t\ttmp.textContent = \"\";\n\t\t\t}\n\t\t}\n\t}\n\n\t// Remove wrapper from fragment\n\tfragment.textContent = \"\";\n\n\ti = 0;\n\twhile ( ( elem = nodes[ i++ ] ) ) {\n\n\t\t// Skip elements already in the context collection (trac-4087)\n\t\tif ( selection && jQuery.inArray( elem, selection ) > -1 ) {\n\t\t\tif ( ignored ) {\n\t\t\t\tignored.push( elem );\n\t\t\t}\n\t\t\tcontinue;\n\t\t}\n\n\t\tcontains = jQuery.contains( elem.ownerDocument, elem );\n\n\t\t// Append to fragment\n\t\ttmp = getAll( fragment.appendChild( elem ), \"script\" );\n\n\t\t// Preserve script evaluation history\n\t\tif ( contains ) {\n\t\t\tsetGlobalEval( tmp );\n\t\t}\n\n\t\t// Capture executables\n\t\tif ( scripts ) {\n\t\t\tj = 0;\n\t\t\twhile ( ( elem = tmp[ j++ ] ) ) {\n\t\t\t\tif ( rscriptType.test( elem.type || \"\" ) ) {\n\t\t\t\t\tscripts.push( elem );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\treturn fragment;\n}\n\n\n( function() {\n\tvar fragment = document.createDocumentFragment(),\n\t\tdiv = fragment.appendChild( document.createElement( \"div\" ) ),\n\t\tinput = document.createElement( \"input\" );\n\n\t// Support: Android 4.0 - 4.3 only\n\t// Check state lost if the name is set (#11217)\n\t// Support: Windows Web Apps (WWA)\n\t// `name` and `type` must use .setAttribute for WWA (#14901)\n\tinput.setAttribute( \"type\", \"radio\" );\n\tinput.setAttribute( \"checked\", \"checked\" );\n\tinput.setAttribute( \"name\", \"t\" );\n\n\tdiv.appendChild( input );\n\n\t// Support: Android <=4.1 only\n\t// Older WebKit doesn't clone checked state correctly in fragments\n\tsupport.checkClone = div.cloneNode( true ).cloneNode( true ).lastChild.checked;\n\n\t// Support: IE <=11 only\n\t// Make sure textarea (and checkbox) defaultValue is properly cloned\n\tdiv.innerHTML = \"<textarea>x</textarea>\";\n\tsupport.noCloneChecked = !!div.cloneNode( true ).lastChild.defaultValue;\n} )();\nvar documentElement = document.documentElement;\n\n\n\nvar\n\trkeyEvent = /^key/,\n\trmouseEvent = /^(?:mouse|pointer|contextmenu|drag|drop)|click/,\n\trtypenamespace = /^([^.]*)(?:\\.(.+)|)/;\n\nfunction returnTrue() {\n\treturn true;\n}\n\nfunction returnFalse() {\n\treturn false;\n}\n\n// Support: IE <=9 only\n// See #13393 for more info\nfunction safeActiveElement() {\n\ttry {\n\t\treturn document.activeElement;\n\t} catch ( err ) { }\n}\n\nfunction on( elem, types, selector, data, fn, one ) {\n\tvar origFn, type;\n\n\t// Types can be a map of types/handlers\n\tif ( typeof types === \"object\" ) {\n\n\t\t// ( types-Object, selector, data )\n\t\tif ( typeof selector !== \"string\" ) {\n\n\t\t\t// ( types-Object, data )\n\t\t\tdata = data || selector;\n\t\t\tselector = undefined;\n\t\t}\n\t\tfor ( type in types ) {\n\t\t\ton( elem, type, selector, data, types[ type ], one );\n\t\t}\n\t\treturn elem;\n\t}\n\n\tif ( data == null && fn == null ) {\n\n\t\t// ( types, fn )\n\t\tfn = selector;\n\t\tdata = selector = undefined;\n\t} else if ( fn == null ) {\n\t\tif ( typeof selector === \"string\" ) {\n\n\t\t\t// ( types, selector, fn )\n\t\t\tfn = data;\n\t\t\tdata = undefined;\n\t\t} else {\n\n\t\t\t// ( types, data, fn )\n\t\t\tfn = data;\n\t\t\tdata = selector;\n\t\t\tselector = undefined;\n\t\t}\n\t}\n\tif ( fn === false ) {\n\t\tfn = returnFalse;\n\t} else if ( !fn ) {\n\t\treturn elem;\n\t}\n\n\tif ( one === 1 ) {\n\t\torigFn = fn;\n\t\tfn = function( event ) {\n\n\t\t\t// Can use an empty set, since event contains the info\n\t\t\tjQuery().off( event );\n\t\t\treturn origFn.apply( this, arguments );\n\t\t};\n\n\t\t// Use same guid so caller can remove using origFn\n\t\tfn.guid = origFn.guid || ( origFn.guid = jQuery.guid++ );\n\t}\n\treturn elem.each( function() {\n\t\tjQuery.event.add( this, types, fn, data, selector );\n\t} );\n}\n\n/*\n * Helper functions for managing events -- not part of the public interface.\n * Props to Dean Edwards' addEvent library for many of the ideas.\n */\njQuery.event = {\n\n\tglobal: {},\n\n\tadd: function( elem, types, handler, data, selector ) {\n\n\t\tvar handleObjIn, eventHandle, tmp,\n\t\t\tevents, t, handleObj,\n\t\t\tspecial, handlers, type, namespaces, origType,\n\t\t\telemData = dataPriv.get( elem );\n\n\t\t// Don't attach events to noData or text/comment nodes (but allow plain objects)\n\t\tif ( !elemData ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Caller can pass in an object of custom data in lieu of the handler\n\t\tif ( handler.handler ) {\n\t\t\thandleObjIn = handler;\n\t\t\thandler = handleObjIn.handler;\n\t\t\tselector = handleObjIn.selector;\n\t\t}\n\n\t\t// Ensure that invalid selectors throw exceptions at attach time\n\t\t// Evaluate against documentElement in case elem is a non-element node (e.g., document)\n\t\tif ( selector ) {\n\t\t\tjQuery.find.matchesSelector( documentElement, selector );\n\t\t}\n\n\t\t// Make sure that the handler has a unique ID, used to find/remove it later\n\t\tif ( !handler.guid ) {\n\t\t\thandler.guid = jQuery.guid++;\n\t\t}\n\n\t\t// Init the element's event structure and main handler, if this is the first\n\t\tif ( !( events = elemData.events ) ) {\n\t\t\tevents = elemData.events = {};\n\t\t}\n\t\tif ( !( eventHandle = elemData.handle ) ) {\n\t\t\teventHandle = elemData.handle = function( e ) {\n\n\t\t\t\t// Discard the second event of a jQuery.event.trigger() and\n\t\t\t\t// when an event is called after a page has unloaded\n\t\t\t\treturn typeof jQuery !== \"undefined\" && jQuery.event.triggered !== e.type ?\n\t\t\t\t\tjQuery.event.dispatch.apply( elem, arguments ) : undefined;\n\t\t\t};\n\t\t}\n\n\t\t// Handle multiple events separated by a space\n\t\ttypes = ( types || \"\" ).match( rnotwhite ) || [ \"\" ];\n\t\tt = types.length;\n\t\twhile ( t-- ) {\n\t\t\ttmp = rtypenamespace.exec( types[ t ] ) || [];\n\t\t\ttype = origType = tmp[ 1 ];\n\t\t\tnamespaces = ( tmp[ 2 ] || \"\" ).split( \".\" ).sort();\n\n\t\t\t// There *must* be a type, no attaching namespace-only handlers\n\t\t\tif ( !type ) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\t// If event changes its type, use the special event handlers for the changed type\n\t\t\tspecial = jQuery.event.special[ type ] || {};\n\n\t\t\t// If selector defined, determine special event api type, otherwise given type\n\t\t\ttype = ( selector ? special.delegateType : special.bindType ) || type;\n\n\t\t\t// Update special based on newly reset type\n\t\t\tspecial = jQuery.event.special[ type ] || {};\n\n\t\t\t// handleObj is passed to all event handlers\n\t\t\thandleObj = jQuery.extend( {\n\t\t\t\ttype: type,\n\t\t\t\torigType: origType,\n\t\t\t\tdata: data,\n\t\t\t\thandler: handler,\n\t\t\t\tguid: handler.guid,\n\t\t\t\tselector: selector,\n\t\t\t\tneedsContext: selector && jQuery.expr.match.needsContext.test( selector ),\n\t\t\t\tnamespace: namespaces.join( \".\" )\n\t\t\t}, handleObjIn );\n\n\t\t\t// Init the event handler queue if we're the first\n\t\t\tif ( !( handlers = events[ type ] ) ) {\n\t\t\t\thandlers = events[ type ] = [];\n\t\t\t\thandlers.delegateCount = 0;\n\n\t\t\t\t// Only use addEventListener if the special events handler returns false\n\t\t\t\tif ( !special.setup ||\n\t\t\t\t\tspecial.setup.call( elem, data, namespaces, eventHandle ) === false ) {\n\n\t\t\t\t\tif ( elem.addEventListener ) {\n\t\t\t\t\t\telem.addEventListener( type, eventHandle );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif ( special.add ) {\n\t\t\t\tspecial.add.call( elem, handleObj );\n\n\t\t\t\tif ( !handleObj.handler.guid ) {\n\t\t\t\t\thandleObj.handler.guid = handler.guid;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Add to the element's handler list, delegates in front\n\t\t\tif ( selector ) {\n\t\t\t\thandlers.splice( handlers.delegateCount++, 0, handleObj );\n\t\t\t} else {\n\t\t\t\thandlers.push( handleObj );\n\t\t\t}\n\n\t\t\t// Keep track of which events have ever been used, for event optimization\n\t\t\tjQuery.event.global[ type ] = true;\n\t\t}\n\n\t},\n\n\t// Detach an event or set of events from an element\n\tremove: function( elem, types, handler, selector, mappedTypes ) {\n\n\t\tvar j, origCount, tmp,\n\t\t\tevents, t, handleObj,\n\t\t\tspecial, handlers, type, namespaces, origType,\n\t\t\telemData = dataPriv.hasData( elem ) && dataPriv.get( elem );\n\n\t\tif ( !elemData || !( events = elemData.events ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Once for each type.namespace in types; type may be omitted\n\t\ttypes = ( types || \"\" ).match( rnotwhite ) || [ \"\" ];\n\t\tt = types.length;\n\t\twhile ( t-- ) {\n\t\t\ttmp = rtypenamespace.exec( types[ t ] ) || [];\n\t\t\ttype = origType = tmp[ 1 ];\n\t\t\tnamespaces = ( tmp[ 2 ] || \"\" ).split( \".\" ).sort();\n\n\t\t\t// Unbind all events (on this namespace, if provided) for the element\n\t\t\tif ( !type ) {\n\t\t\t\tfor ( type in events ) {\n\t\t\t\t\tjQuery.event.remove( elem, type + types[ t ], handler, selector, true );\n\t\t\t\t}\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tspecial = jQuery.event.special[ type ] || {};\n\t\t\ttype = ( selector ? special.delegateType : special.bindType ) || type;\n\t\t\thandlers = events[ type ] || [];\n\t\t\ttmp = tmp[ 2 ] &&\n\t\t\t\tnew RegExp( \"(^|\\\\.)\" + namespaces.join( \"\\\\.(?:.*\\\\.|)\" ) + \"(\\\\.|$)\" );\n\n\t\t\t// Remove matching events\n\t\t\torigCount = j = handlers.length;\n\t\t\twhile ( j-- ) {\n\t\t\t\thandleObj = handlers[ j ];\n\n\t\t\t\tif ( ( mappedTypes || origType === handleObj.origType ) &&\n\t\t\t\t\t( !handler || handler.guid === handleObj.guid ) &&\n\t\t\t\t\t( !tmp || tmp.test( handleObj.namespace ) ) &&\n\t\t\t\t\t( !selector || selector === handleObj.selector ||\n\t\t\t\t\t\tselector === \"**\" && handleObj.selector ) ) {\n\t\t\t\t\thandlers.splice( j, 1 );\n\n\t\t\t\t\tif ( handleObj.selector ) {\n\t\t\t\t\t\thandlers.delegateCount--;\n\t\t\t\t\t}\n\t\t\t\t\tif ( special.remove ) {\n\t\t\t\t\t\tspecial.remove.call( elem, handleObj );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Remove generic event handler if we removed something and no more handlers exist\n\t\t\t// (avoids potential for endless recursion during removal of special event handlers)\n\t\t\tif ( origCount && !handlers.length ) {\n\t\t\t\tif ( !special.teardown ||\n\t\t\t\t\tspecial.teardown.call( elem, namespaces, elemData.handle ) === false ) {\n\n\t\t\t\t\tjQuery.removeEvent( elem, type, elemData.handle );\n\t\t\t\t}\n\n\t\t\t\tdelete events[ type ];\n\t\t\t}\n\t\t}\n\n\t\t// Remove data and the expando if it's no longer used\n\t\tif ( jQuery.isEmptyObject( events ) ) {\n\t\t\tdataPriv.remove( elem, \"handle events\" );\n\t\t}\n\t},\n\n\tdispatch: function( nativeEvent ) {\n\n\t\t// Make a writable jQuery.Event from the native event object\n\t\tvar event = jQuery.event.fix( nativeEvent );\n\n\t\tvar i, j, ret, matched, handleObj, handlerQueue,\n\t\t\targs = new Array( arguments.length ),\n\t\t\thandlers = ( dataPriv.get( this, \"events\" ) || {} )[ event.type ] || [],\n\t\t\tspecial = jQuery.event.special[ event.type ] || {};\n\n\t\t// Use the fix-ed jQuery.Event rather than the (read-only) native event\n\t\targs[ 0 ] = event;\n\n\t\tfor ( i = 1; i < arguments.length; i++ ) {\n\t\t\targs[ i ] = arguments[ i ];\n\t\t}\n\n\t\tevent.delegateTarget = this;\n\n\t\t// Call the preDispatch hook for the mapped type, and let it bail if desired\n\t\tif ( special.preDispatch && special.preDispatch.call( this, event ) === false ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Determine handlers\n\t\thandlerQueue = jQuery.event.handlers.call( this, event, handlers );\n\n\t\t// Run delegates first; they may want to stop propagation beneath us\n\t\ti = 0;\n\t\twhile ( ( matched = handlerQueue[ i++ ] ) && !event.isPropagationStopped() ) {\n\t\t\tevent.currentTarget = matched.elem;\n\n\t\t\tj = 0;\n\t\t\twhile ( ( handleObj = matched.handlers[ j++ ] ) &&\n\t\t\t\t!event.isImmediatePropagationStopped() ) {\n\n\t\t\t\t// Triggered event must either 1) have no namespace, or 2) have namespace(s)\n\t\t\t\t// a subset or equal to those in the bound event (both can have no namespace).\n\t\t\t\tif ( !event.rnamespace || event.rnamespace.test( handleObj.namespace ) ) {\n\n\t\t\t\t\tevent.handleObj = handleObj;\n\t\t\t\t\tevent.data = handleObj.data;\n\n\t\t\t\t\tret = ( ( jQuery.event.special[ handleObj.origType ] || {} ).handle ||\n\t\t\t\t\t\thandleObj.handler ).apply( matched.elem, args );\n\n\t\t\t\t\tif ( ret !== undefined ) {\n\t\t\t\t\t\tif ( ( event.result = ret ) === false ) {\n\t\t\t\t\t\t\tevent.preventDefault();\n\t\t\t\t\t\t\tevent.stopPropagation();\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Call the postDispatch hook for the mapped type\n\t\tif ( special.postDispatch ) {\n\t\t\tspecial.postDispatch.call( this, event );\n\t\t}\n\n\t\treturn event.result;\n\t},\n\n\thandlers: function( event, handlers ) {\n\t\tvar i, matches, sel, handleObj,\n\t\t\thandlerQueue = [],\n\t\t\tdelegateCount = handlers.delegateCount,\n\t\t\tcur = event.target;\n\n\t\t// Support: IE <=9\n\t\t// Find delegate handlers\n\t\t// Black-hole SVG <use> instance trees (#13180)\n\t\t//\n\t\t// Support: Firefox <=42\n\t\t// Avoid non-left-click in FF but don't block IE radio events (#3861, gh-2343)\n\t\tif ( delegateCount && cur.nodeType &&\n\t\t\t( event.type !== \"click\" || isNaN( event.button ) || event.button < 1 ) ) {\n\n\t\t\tfor ( ; cur !== this; cur = cur.parentNode || this ) {\n\n\t\t\t\t// Don't check non-elements (#13208)\n\t\t\t\t// Don't process clicks on disabled elements (#6911, #8165, #11382, #11764)\n\t\t\t\tif ( cur.nodeType === 1 && ( cur.disabled !== true || event.type !== \"click\" ) ) {\n\t\t\t\t\tmatches = [];\n\t\t\t\t\tfor ( i = 0; i < delegateCount; i++ ) {\n\t\t\t\t\t\thandleObj = handlers[ i ];\n\n\t\t\t\t\t\t// Don't conflict with Object.prototype properties (#13203)\n\t\t\t\t\t\tsel = handleObj.selector + \" \";\n\n\t\t\t\t\t\tif ( matches[ sel ] === undefined ) {\n\t\t\t\t\t\t\tmatches[ sel ] = handleObj.needsContext ?\n\t\t\t\t\t\t\t\tjQuery( sel, this ).index( cur ) > -1 :\n\t\t\t\t\t\t\t\tjQuery.find( sel, this, null, [ cur ] ).length;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif ( matches[ sel ] ) {\n\t\t\t\t\t\t\tmatches.push( handleObj );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tif ( matches.length ) {\n\t\t\t\t\t\thandlerQueue.push( { elem: cur, handlers: matches } );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Add the remaining (directly-bound) handlers\n\t\tif ( delegateCount < handlers.length ) {\n\t\t\thandlerQueue.push( { elem: this, handlers: handlers.slice( delegateCount ) } );\n\t\t}\n\n\t\treturn handlerQueue;\n\t},\n\n\taddProp: function( name, hook ) {\n\t\tObject.defineProperty( jQuery.Event.prototype, name, {\n\t\t\tenumerable: true,\n\t\t\tconfigurable: true,\n\n\t\t\tget: jQuery.isFunction( hook ) ?\n\t\t\t\tfunction() {\n\t\t\t\t\tif ( this.originalEvent ) {\n\t\t\t\t\t\t\treturn hook( this.originalEvent );\n\t\t\t\t\t}\n\t\t\t\t} :\n\t\t\t\tfunction() {\n\t\t\t\t\tif ( this.originalEvent ) {\n\t\t\t\t\t\t\treturn this.originalEvent[ name ];\n\t\t\t\t\t}\n\t\t\t\t},\n\n\t\t\tset: function( value ) {\n\t\t\t\tObject.defineProperty( this, name, {\n\t\t\t\t\tenumerable: true,\n\t\t\t\t\tconfigurable: true,\n\t\t\t\t\twritable: true,\n\t\t\t\t\tvalue: value\n\t\t\t\t} );\n\t\t\t}\n\t\t} );\n\t},\n\n\tfix: function( originalEvent ) {\n\t\treturn originalEvent[ jQuery.expando ] ?\n\t\t\toriginalEvent :\n\t\t\tnew jQuery.Event( originalEvent );\n\t},\n\n\tspecial: {\n\t\tload: {\n\n\t\t\t// Prevent triggered image.load events from bubbling to window.load\n\t\t\tnoBubble: true\n\t\t},\n\t\tfocus: {\n\n\t\t\t// Fire native event if possible so blur/focus sequence is correct\n\t\t\ttrigger: function() {\n\t\t\t\tif ( this !== safeActiveElement() && this.focus ) {\n\t\t\t\t\tthis.focus();\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t},\n\t\t\tdelegateType: \"focusin\"\n\t\t},\n\t\tblur: {\n\t\t\ttrigger: function() {\n\t\t\t\tif ( this === safeActiveElement() && this.blur ) {\n\t\t\t\t\tthis.blur();\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t},\n\t\t\tdelegateType: \"focusout\"\n\t\t},\n\t\tclick: {\n\n\t\t\t// For checkbox, fire native event so checked state will be right\n\t\t\ttrigger: function() {\n\t\t\t\tif ( this.type === \"checkbox\" && this.click && jQuery.nodeName( this, \"input\" ) ) {\n\t\t\t\t\tthis.click();\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t},\n\n\t\t\t// For cross-browser consistency, don't fire native .click() on links\n\t\t\t_default: function( event ) {\n\t\t\t\treturn jQuery.nodeName( event.target, \"a\" );\n\t\t\t}\n\t\t},\n\n\t\tbeforeunload: {\n\t\t\tpostDispatch: function( event ) {\n\n\t\t\t\t// Support: Firefox 20+\n\t\t\t\t// Firefox doesn't alert if the returnValue field is not set.\n\t\t\t\tif ( event.result !== undefined && event.originalEvent ) {\n\t\t\t\t\tevent.originalEvent.returnValue = event.result;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n};\n\njQuery.removeEvent = function( elem, type, handle ) {\n\n\t// This \"if\" is needed for plain objects\n\tif ( elem.removeEventListener ) {\n\t\telem.removeEventListener( type, handle );\n\t}\n};\n\njQuery.Event = function( src, props ) {\n\n\t// Allow instantiation without the 'new' keyword\n\tif ( !( this instanceof jQuery.Event ) ) {\n\t\treturn new jQuery.Event( src, props );\n\t}\n\n\t// Event object\n\tif ( src && src.type ) {\n\t\tthis.originalEvent = src;\n\t\tthis.type = src.type;\n\n\t\t// Events bubbling up the document may have been marked as prevented\n\t\t// by a handler lower down the tree; reflect the correct value.\n\t\tthis.isDefaultPrevented = src.defaultPrevented ||\n\t\t\t\tsrc.defaultPrevented === undefined &&\n\n\t\t\t\t// Support: Android <=2.3 only\n\t\t\t\tsrc.returnValue === false ?\n\t\t\treturnTrue :\n\t\t\treturnFalse;\n\n\t\t// Create target properties\n\t\t// Support: Safari <=6 - 7 only\n\t\t// Target should not be a text node (#504, #13143)\n\t\tthis.target = ( src.target && src.target.nodeType === 3 ) ?\n\t\t\tsrc.target.parentNode :\n\t\t\tsrc.target;\n\n\t\tthis.currentTarget = src.currentTarget;\n\t\tthis.relatedTarget = src.relatedTarget;\n\n\t// Event type\n\t} else {\n\t\tthis.type = src;\n\t}\n\n\t// Put explicitly provided properties onto the event object\n\tif ( props ) {\n\t\tjQuery.extend( this, props );\n\t}\n\n\t// Create a timestamp if incoming event doesn't have one\n\tthis.timeStamp = src && src.timeStamp || jQuery.now();\n\n\t// Mark it as fixed\n\tthis[ jQuery.expando ] = true;\n};\n\n// jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding\n// https://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html\njQuery.Event.prototype = {\n\tconstructor: jQuery.Event,\n\tisDefaultPrevented: returnFalse,\n\tisPropagationStopped: returnFalse,\n\tisImmediatePropagationStopped: returnFalse,\n\tisSimulated: false,\n\n\tpreventDefault: function() {\n\t\tvar e = this.originalEvent;\n\n\t\tthis.isDefaultPrevented = returnTrue;\n\n\t\tif ( e && !this.isSimulated ) {\n\t\t\te.preventDefault();\n\t\t}\n\t},\n\tstopPropagation: function() {\n\t\tvar e = this.originalEvent;\n\n\t\tthis.isPropagationStopped = returnTrue;\n\n\t\tif ( e && !this.isSimulated ) {\n\t\t\te.stopPropagation();\n\t\t}\n\t},\n\tstopImmediatePropagation: function() {\n\t\tvar e = this.originalEvent;\n\n\t\tthis.isImmediatePropagationStopped = returnTrue;\n\n\t\tif ( e && !this.isSimulated ) {\n\t\t\te.stopImmediatePropagation();\n\t\t}\n\n\t\tthis.stopPropagation();\n\t}\n};\n\n// Includes all common event props including KeyEvent and MouseEvent specific props\njQuery.each( {\n\taltKey: true,\n\tbubbles: true,\n\tcancelable: true,\n\tchangedTouches: true,\n\tctrlKey: true,\n\tdetail: true,\n\teventPhase: true,\n\tmetaKey: true,\n\tpageX: true,\n\tpageY: true,\n\tshiftKey: true,\n\tview: true,\n\t\"char\": true,\n\tcharCode: true,\n\tkey: true,\n\tkeyCode: true,\n\tbutton: true,\n\tbuttons: true,\n\tclientX: true,\n\tclientY: true,\n\toffsetX: true,\n\toffsetY: true,\n\tpointerId: true,\n\tpointerType: true,\n\tscreenX: true,\n\tscreenY: true,\n\ttargetTouches: true,\n\ttoElement: true,\n\ttouches: true,\n\n\twhich: function( event ) {\n\t\tvar button = event.button;\n\n\t\t// Add which for key events\n\t\tif ( event.which == null && rkeyEvent.test( event.type ) ) {\n\t\t\treturn event.charCode != null ? event.charCode : event.keyCode;\n\t\t}\n\n\t\t// Add which for click: 1 === left; 2 === middle; 3 === right\n\t\tif ( !event.which && button !== undefined && rmouseEvent.test( event.type ) ) {\n\t\t\treturn ( button & 1 ? 1 : ( button & 2 ? 3 : ( button & 4 ? 2 : 0 ) ) );\n\t\t}\n\n\t\treturn event.which;\n\t}\n}, jQuery.event.addProp );\n\n// Create mouseenter/leave events using mouseover/out and event-time checks\n// so that event delegation works in jQuery.\n// Do the same for pointerenter/pointerleave and pointerover/pointerout\n//\n// Support: Safari 7 only\n// Safari sends mouseenter too often; see:\n// https://bugs.chromium.org/p/chromium/issues/detail?id=470258\n// for the description of the bug (it existed in older Chrome versions as well).\njQuery.each( {\n\tmouseenter: \"mouseover\",\n\tmouseleave: \"mouseout\",\n\tpointerenter: \"pointerover\",\n\tpointerleave: \"pointerout\"\n}, function( orig, fix ) {\n\tjQuery.event.special[ orig ] = {\n\t\tdelegateType: fix,\n\t\tbindType: fix,\n\n\t\thandle: function( event ) {\n\t\t\tvar ret,\n\t\t\t\ttarget = this,\n\t\t\t\trelated = event.relatedTarget,\n\t\t\t\thandleObj = event.handleObj;\n\n\t\t\t// For mouseenter/leave call the handler if related is outside the target.\n\t\t\t// NB: No relatedTarget if the mouse left/entered the browser window\n\t\t\tif ( !related || ( related !== target && !jQuery.contains( target, related ) ) ) {\n\t\t\t\tevent.type = handleObj.origType;\n\t\t\t\tret = handleObj.handler.apply( this, arguments );\n\t\t\t\tevent.type = fix;\n\t\t\t}\n\t\t\treturn ret;\n\t\t}\n\t};\n} );\n\njQuery.fn.extend( {\n\n\ton: function( types, selector, data, fn ) {\n\t\treturn on( this, types, selector, data, fn );\n\t},\n\tone: function( types, selector, data, fn ) {\n\t\treturn on( this, types, selector, data, fn, 1 );\n\t},\n\toff: function( types, selector, fn ) {\n\t\tvar handleObj, type;\n\t\tif ( types && types.preventDefault && types.handleObj ) {\n\n\t\t\t// ( event )  dispatched jQuery.Event\n\t\t\thandleObj = types.handleObj;\n\t\t\tjQuery( types.delegateTarget ).off(\n\t\t\t\thandleObj.namespace ?\n\t\t\t\t\thandleObj.origType + \".\" + handleObj.namespace :\n\t\t\t\t\thandleObj.origType,\n\t\t\t\thandleObj.selector,\n\t\t\t\thandleObj.handler\n\t\t\t);\n\t\t\treturn this;\n\t\t}\n\t\tif ( typeof types === \"object\" ) {\n\n\t\t\t// ( types-object [, selector] )\n\t\t\tfor ( type in types ) {\n\t\t\t\tthis.off( type, selector, types[ type ] );\n\t\t\t}\n\t\t\treturn this;\n\t\t}\n\t\tif ( selector === false || typeof selector === \"function\" ) {\n\n\t\t\t// ( types [, fn] )\n\t\t\tfn = selector;\n\t\t\tselector = undefined;\n\t\t}\n\t\tif ( fn === false ) {\n\t\t\tfn = returnFalse;\n\t\t}\n\t\treturn this.each( function() {\n\t\t\tjQuery.event.remove( this, types, fn, selector );\n\t\t} );\n\t}\n} );\n\n\nvar\n\n\t/* eslint-disable max-len */\n\n\t// See https://github.com/eslint/eslint/issues/3229\n\trxhtmlTag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([a-z][^\\/\\0>\\x20\\t\\r\\n\\f]*)[^>]*)\\/>/gi,\n\n\t/* eslint-enable */\n\n\t// Support: IE <=10 - 11, Edge 12 - 13\n\t// In IE/Edge using regex groups here causes severe slowdowns.\n\t// See https://connect.microsoft.com/IE/feedback/details/1736512/\n\trnoInnerhtml = /<script|<style|<link/i,\n\n\t// checked=\"checked\" or checked\n\trchecked = /checked\\s*(?:[^=]|=\\s*.checked.)/i,\n\trscriptTypeMasked = /^true\\/(.*)/,\n\trcleanScript = /^\\s*<!(?:\\[CDATA\\[|--)|(?:\\]\\]|--)>\\s*$/g;\n\nfunction manipulationTarget( elem, content ) {\n\tif ( jQuery.nodeName( elem, \"table\" ) &&\n\t\tjQuery.nodeName( content.nodeType !== 11 ? content : content.firstChild, \"tr\" ) ) {\n\n\t\treturn elem.getElementsByTagName( \"tbody\" )[ 0 ] || elem;\n\t}\n\n\treturn elem;\n}\n\n// Replace/restore the type attribute of script elements for safe DOM manipulation\nfunction disableScript( elem ) {\n\telem.type = ( elem.getAttribute( \"type\" ) !== null ) + \"/\" + elem.type;\n\treturn elem;\n}\nfunction restoreScript( elem ) {\n\tvar match = rscriptTypeMasked.exec( elem.type );\n\n\tif ( match ) {\n\t\telem.type = match[ 1 ];\n\t} else {\n\t\telem.removeAttribute( \"type\" );\n\t}\n\n\treturn elem;\n}\n\nfunction cloneCopyEvent( src, dest ) {\n\tvar i, l, type, pdataOld, pdataCur, udataOld, udataCur, events;\n\n\tif ( dest.nodeType !== 1 ) {\n\t\treturn;\n\t}\n\n\t// 1. Copy private data: events, handlers, etc.\n\tif ( dataPriv.hasData( src ) ) {\n\t\tpdataOld = dataPriv.access( src );\n\t\tpdataCur = dataPriv.set( dest, pdataOld );\n\t\tevents = pdataOld.events;\n\n\t\tif ( events ) {\n\t\t\tdelete pdataCur.handle;\n\t\t\tpdataCur.events = {};\n\n\t\t\tfor ( type in events ) {\n\t\t\t\tfor ( i = 0, l = events[ type ].length; i < l; i++ ) {\n\t\t\t\t\tjQuery.event.add( dest, type, events[ type ][ i ] );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t// 2. Copy user data\n\tif ( dataUser.hasData( src ) ) {\n\t\tudataOld = dataUser.access( src );\n\t\tudataCur = jQuery.extend( {}, udataOld );\n\n\t\tdataUser.set( dest, udataCur );\n\t}\n}\n\n// Fix IE bugs, see support tests\nfunction fixInput( src, dest ) {\n\tvar nodeName = dest.nodeName.toLowerCase();\n\n\t// Fails to persist the checked state of a cloned checkbox or radio button.\n\tif ( nodeName === \"input\" && rcheckableType.test( src.type ) ) {\n\t\tdest.checked = src.checked;\n\n\t// Fails to return the selected option to the default selected state when cloning options\n\t} else if ( nodeName === \"input\" || nodeName === \"textarea\" ) {\n\t\tdest.defaultValue = src.defaultValue;\n\t}\n}\n\nfunction domManip( collection, args, callback, ignored ) {\n\n\t// Flatten any nested arrays\n\targs = concat.apply( [], args );\n\n\tvar fragment, first, scripts, hasScripts, node, doc,\n\t\ti = 0,\n\t\tl = collection.length,\n\t\tiNoClone = l - 1,\n\t\tvalue = args[ 0 ],\n\t\tisFunction = jQuery.isFunction( value );\n\n\t// We can't cloneNode fragments that contain checked, in WebKit\n\tif ( isFunction ||\n\t\t\t( l > 1 && typeof value === \"string\" &&\n\t\t\t\t!support.checkClone && rchecked.test( value ) ) ) {\n\t\treturn collection.each( function( index ) {\n\t\t\tvar self = collection.eq( index );\n\t\t\tif ( isFunction ) {\n\t\t\t\targs[ 0 ] = value.call( this, index, self.html() );\n\t\t\t}\n\t\t\tdomManip( self, args, callback, ignored );\n\t\t} );\n\t}\n\n\tif ( l ) {\n\t\tfragment = buildFragment( args, collection[ 0 ].ownerDocument, false, collection, ignored );\n\t\tfirst = fragment.firstChild;\n\n\t\tif ( fragment.childNodes.length === 1 ) {\n\t\t\tfragment = first;\n\t\t}\n\n\t\t// Require either new content or an interest in ignored elements to invoke the callback\n\t\tif ( first || ignored ) {\n\t\t\tscripts = jQuery.map( getAll( fragment, \"script\" ), disableScript );\n\t\t\thasScripts = scripts.length;\n\n\t\t\t// Use the original fragment for the last item\n\t\t\t// instead of the first because it can end up\n\t\t\t// being emptied incorrectly in certain situations (#8070).\n\t\t\tfor ( ; i < l; i++ ) {\n\t\t\t\tnode = fragment;\n\n\t\t\t\tif ( i !== iNoClone ) {\n\t\t\t\t\tnode = jQuery.clone( node, true, true );\n\n\t\t\t\t\t// Keep references to cloned scripts for later restoration\n\t\t\t\t\tif ( hasScripts ) {\n\n\t\t\t\t\t\t// Support: Android <=4.0 only, PhantomJS 1 only\n\t\t\t\t\t\t// push.apply(_, arraylike) throws on ancient WebKit\n\t\t\t\t\t\tjQuery.merge( scripts, getAll( node, \"script\" ) );\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tcallback.call( collection[ i ], node, i );\n\t\t\t}\n\n\t\t\tif ( hasScripts ) {\n\t\t\t\tdoc = scripts[ scripts.length - 1 ].ownerDocument;\n\n\t\t\t\t// Reenable scripts\n\t\t\t\tjQuery.map( scripts, restoreScript );\n\n\t\t\t\t// Evaluate executable scripts on first document insertion\n\t\t\t\tfor ( i = 0; i < hasScripts; i++ ) {\n\t\t\t\t\tnode = scripts[ i ];\n\t\t\t\t\tif ( rscriptType.test( node.type || \"\" ) &&\n\t\t\t\t\t\t!dataPriv.access( node, \"globalEval\" ) &&\n\t\t\t\t\t\tjQuery.contains( doc, node ) ) {\n\n\t\t\t\t\t\tif ( node.src ) {\n\n\t\t\t\t\t\t\t// Optional AJAX dependency, but won't run scripts if not present\n\t\t\t\t\t\t\tif ( jQuery._evalUrl ) {\n\t\t\t\t\t\t\t\tjQuery._evalUrl( node.src );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tDOMEval( node.textContent.replace( rcleanScript, \"\" ), doc );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\treturn collection;\n}\n\nfunction remove( elem, selector, keepData ) {\n\tvar node,\n\t\tnodes = selector ? jQuery.filter( selector, elem ) : elem,\n\t\ti = 0;\n\n\tfor ( ; ( node = nodes[ i ] ) != null; i++ ) {\n\t\tif ( !keepData && node.nodeType === 1 ) {\n\t\t\tjQuery.cleanData( getAll( node ) );\n\t\t}\n\n\t\tif ( node.parentNode ) {\n\t\t\tif ( keepData && jQuery.contains( node.ownerDocument, node ) ) {\n\t\t\t\tsetGlobalEval( getAll( node, \"script\" ) );\n\t\t\t}\n\t\t\tnode.parentNode.removeChild( node );\n\t\t}\n\t}\n\n\treturn elem;\n}\n\njQuery.extend( {\n\thtmlPrefilter: function( html ) {\n\t\treturn html.replace( rxhtmlTag, \"<$1></$2>\" );\n\t},\n\n\tclone: function( elem, dataAndEvents, deepDataAndEvents ) {\n\t\tvar i, l, srcElements, destElements,\n\t\t\tclone = elem.cloneNode( true ),\n\t\t\tinPage = jQuery.contains( elem.ownerDocument, elem );\n\n\t\t// Fix IE cloning issues\n\t\tif ( !support.noCloneChecked && ( elem.nodeType === 1 || elem.nodeType === 11 ) &&\n\t\t\t\t!jQuery.isXMLDoc( elem ) ) {\n\n\t\t\t// We eschew Sizzle here for performance reasons: https://jsperf.com/getall-vs-sizzle/2\n\t\t\tdestElements = getAll( clone );\n\t\t\tsrcElements = getAll( elem );\n\n\t\t\tfor ( i = 0, l = srcElements.length; i < l; i++ ) {\n\t\t\t\tfixInput( srcElements[ i ], destElements[ i ] );\n\t\t\t}\n\t\t}\n\n\t\t// Copy the events from the original to the clone\n\t\tif ( dataAndEvents ) {\n\t\t\tif ( deepDataAndEvents ) {\n\t\t\t\tsrcElements = srcElements || getAll( elem );\n\t\t\t\tdestElements = destElements || getAll( clone );\n\n\t\t\t\tfor ( i = 0, l = srcElements.length; i < l; i++ ) {\n\t\t\t\t\tcloneCopyEvent( srcElements[ i ], destElements[ i ] );\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tcloneCopyEvent( elem, clone );\n\t\t\t}\n\t\t}\n\n\t\t// Preserve script evaluation history\n\t\tdestElements = getAll( clone, \"script\" );\n\t\tif ( destElements.length > 0 ) {\n\t\t\tsetGlobalEval( destElements, !inPage && getAll( elem, \"script\" ) );\n\t\t}\n\n\t\t// Return the cloned set\n\t\treturn clone;\n\t},\n\n\tcleanData: function( elems ) {\n\t\tvar data, elem, type,\n\t\t\tspecial = jQuery.event.special,\n\t\t\ti = 0;\n\n\t\tfor ( ; ( elem = elems[ i ] ) !== undefined; i++ ) {\n\t\t\tif ( acceptData( elem ) ) {\n\t\t\t\tif ( ( data = elem[ dataPriv.expando ] ) ) {\n\t\t\t\t\tif ( data.events ) {\n\t\t\t\t\t\tfor ( type in data.events ) {\n\t\t\t\t\t\t\tif ( special[ type ] ) {\n\t\t\t\t\t\t\t\tjQuery.event.remove( elem, type );\n\n\t\t\t\t\t\t\t// This is a shortcut to avoid jQuery.event.remove's overhead\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tjQuery.removeEvent( elem, type, data.handle );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\t// Support: Chrome <=35 - 45+\n\t\t\t\t\t// Assign undefined instead of using delete, see Data#remove\n\t\t\t\t\telem[ dataPriv.expando ] = undefined;\n\t\t\t\t}\n\t\t\t\tif ( elem[ dataUser.expando ] ) {\n\n\t\t\t\t\t// Support: Chrome <=35 - 45+\n\t\t\t\t\t// Assign undefined instead of using delete, see Data#remove\n\t\t\t\t\telem[ dataUser.expando ] = undefined;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n} );\n\njQuery.fn.extend( {\n\tdetach: function( selector ) {\n\t\treturn remove( this, selector, true );\n\t},\n\n\tremove: function( selector ) {\n\t\treturn remove( this, selector );\n\t},\n\n\ttext: function( value ) {\n\t\treturn access( this, function( value ) {\n\t\t\treturn value === undefined ?\n\t\t\t\tjQuery.text( this ) :\n\t\t\t\tthis.empty().each( function() {\n\t\t\t\t\tif ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) {\n\t\t\t\t\t\tthis.textContent = value;\n\t\t\t\t\t}\n\t\t\t\t} );\n\t\t}, null, value, arguments.length );\n\t},\n\n\tappend: function() {\n\t\treturn domManip( this, arguments, function( elem ) {\n\t\t\tif ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) {\n\t\t\t\tvar target = manipulationTarget( this, elem );\n\t\t\t\ttarget.appendChild( elem );\n\t\t\t}\n\t\t} );\n\t},\n\n\tprepend: function() {\n\t\treturn domManip( this, arguments, function( elem ) {\n\t\t\tif ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) {\n\t\t\t\tvar target = manipulationTarget( this, elem );\n\t\t\t\ttarget.insertBefore( elem, target.firstChild );\n\t\t\t}\n\t\t} );\n\t},\n\n\tbefore: function() {\n\t\treturn domManip( this, arguments, function( elem ) {\n\t\t\tif ( this.parentNode ) {\n\t\t\t\tthis.parentNode.insertBefore( elem, this );\n\t\t\t}\n\t\t} );\n\t},\n\n\tafter: function() {\n\t\treturn domManip( this, arguments, function( elem ) {\n\t\t\tif ( this.parentNode ) {\n\t\t\t\tthis.parentNode.insertBefore( elem, this.nextSibling );\n\t\t\t}\n\t\t} );\n\t},\n\n\tempty: function() {\n\t\tvar elem,\n\t\t\ti = 0;\n\n\t\tfor ( ; ( elem = this[ i ] ) != null; i++ ) {\n\t\t\tif ( elem.nodeType === 1 ) {\n\n\t\t\t\t// Prevent memory leaks\n\t\t\t\tjQuery.cleanData( getAll( elem, false ) );\n\n\t\t\t\t// Remove any remaining nodes\n\t\t\t\telem.textContent = \"\";\n\t\t\t}\n\t\t}\n\n\t\treturn this;\n\t},\n\n\tclone: function( dataAndEvents, deepDataAndEvents ) {\n\t\tdataAndEvents = dataAndEvents == null ? false : dataAndEvents;\n\t\tdeepDataAndEvents = deepDataAndEvents == null ? dataAndEvents : deepDataAndEvents;\n\n\t\treturn this.map( function() {\n\t\t\treturn jQuery.clone( this, dataAndEvents, deepDataAndEvents );\n\t\t} );\n\t},\n\n\thtml: function( value ) {\n\t\treturn access( this, function( value ) {\n\t\t\tvar elem = this[ 0 ] || {},\n\t\t\t\ti = 0,\n\t\t\t\tl = this.length;\n\n\t\t\tif ( value === undefined && elem.nodeType === 1 ) {\n\t\t\t\treturn elem.innerHTML;\n\t\t\t}\n\n\t\t\t// See if we can take a shortcut and just use innerHTML\n\t\t\tif ( typeof value === \"string\" && !rnoInnerhtml.test( value ) &&\n\t\t\t\t!wrapMap[ ( rtagName.exec( value ) || [ \"\", \"\" ] )[ 1 ].toLowerCase() ] ) {\n\n\t\t\t\tvalue = jQuery.htmlPrefilter( value );\n\n\t\t\t\ttry {\n\t\t\t\t\tfor ( ; i < l; i++ ) {\n\t\t\t\t\t\telem = this[ i ] || {};\n\n\t\t\t\t\t\t// Remove element nodes and prevent memory leaks\n\t\t\t\t\t\tif ( elem.nodeType === 1 ) {\n\t\t\t\t\t\t\tjQuery.cleanData( getAll( elem, false ) );\n\t\t\t\t\t\t\telem.innerHTML = value;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\telem = 0;\n\n\t\t\t\t// If using innerHTML throws an exception, use the fallback method\n\t\t\t\t} catch ( e ) {}\n\t\t\t}\n\n\t\t\tif ( elem ) {\n\t\t\t\tthis.empty().append( value );\n\t\t\t}\n\t\t}, null, value, arguments.length );\n\t},\n\n\treplaceWith: function() {\n\t\tvar ignored = [];\n\n\t\t// Make the changes, replacing each non-ignored context element with the new content\n\t\treturn domManip( this, arguments, function( elem ) {\n\t\t\tvar parent = this.parentNode;\n\n\t\t\tif ( jQuery.inArray( this, ignored ) < 0 ) {\n\t\t\t\tjQuery.cleanData( getAll( this ) );\n\t\t\t\tif ( parent ) {\n\t\t\t\t\tparent.replaceChild( elem, this );\n\t\t\t\t}\n\t\t\t}\n\n\t\t// Force callback invocation\n\t\t}, ignored );\n\t}\n} );\n\njQuery.each( {\n\tappendTo: \"append\",\n\tprependTo: \"prepend\",\n\tinsertBefore: \"before\",\n\tinsertAfter: \"after\",\n\treplaceAll: \"replaceWith\"\n}, function( name, original ) {\n\tjQuery.fn[ name ] = function( selector ) {\n\t\tvar elems,\n\t\t\tret = [],\n\t\t\tinsert = jQuery( selector ),\n\t\t\tlast = insert.length - 1,\n\t\t\ti = 0;\n\n\t\tfor ( ; i <= last; i++ ) {\n\t\t\telems = i === last ? this : this.clone( true );\n\t\t\tjQuery( insert[ i ] )[ original ]( elems );\n\n\t\t\t// Support: Android <=4.0 only, PhantomJS 1 only\n\t\t\t// .get() because push.apply(_, arraylike) throws on ancient WebKit\n\t\t\tpush.apply( ret, elems.get() );\n\t\t}\n\n\t\treturn this.pushStack( ret );\n\t};\n} );\nvar rmargin = ( /^margin/ );\n\nvar rnumnonpx = new RegExp( \"^(\" + pnum + \")(?!px)[a-z%]+$\", \"i\" );\n\nvar getStyles = function( elem ) {\n\n\t\t// Support: IE <=11 only, Firefox <=30 (#15098, #14150)\n\t\t// IE throws on elements created in popups\n\t\t// FF meanwhile throws on frame elements through \"defaultView.getComputedStyle\"\n\t\tvar view = elem.ownerDocument.defaultView;\n\n\t\tif ( !view || !view.opener ) {\n\t\t\tview = window;\n\t\t}\n\n\t\treturn view.getComputedStyle( elem );\n\t};\n\n\n\n( function() {\n\n\t// Executing both pixelPosition & boxSizingReliable tests require only one layout\n\t// so they're executed at the same time to save the second computation.\n\tfunction computeStyleTests() {\n\n\t\t// This is a singleton, we need to execute it only once\n\t\tif ( !div ) {\n\t\t\treturn;\n\t\t}\n\n\t\tdiv.style.cssText =\n\t\t\t\"box-sizing:border-box;\" +\n\t\t\t\"position:relative;display:block;\" +\n\t\t\t\"margin:auto;border:1px;padding:1px;\" +\n\t\t\t\"top:1%;width:50%\";\n\t\tdiv.innerHTML = \"\";\n\t\tdocumentElement.appendChild( container );\n\n\t\tvar divStyle = window.getComputedStyle( div );\n\t\tpixelPositionVal = divStyle.top !== \"1%\";\n\n\t\t// Support: Android 4.0 - 4.3 only, Firefox <=3 - 44\n\t\treliableMarginLeftVal = divStyle.marginLeft === \"2px\";\n\t\tboxSizingReliableVal = divStyle.width === \"4px\";\n\n\t\t// Support: Android 4.0 - 4.3 only\n\t\t// Some styles come back with percentage values, even though they shouldn't\n\t\tdiv.style.marginRight = \"50%\";\n\t\tpixelMarginRightVal = divStyle.marginRight === \"4px\";\n\n\t\tdocumentElement.removeChild( container );\n\n\t\t// Nullify the div so it wouldn't be stored in the memory and\n\t\t// it will also be a sign that checks already performed\n\t\tdiv = null;\n\t}\n\n\tvar pixelPositionVal, boxSizingReliableVal, pixelMarginRightVal, reliableMarginLeftVal,\n\t\tcontainer = document.createElement( \"div\" ),\n\t\tdiv = document.createElement( \"div\" );\n\n\t// Finish early in limited (non-browser) environments\n\tif ( !div.style ) {\n\t\treturn;\n\t}\n\n\t// Support: IE <=9 - 11 only\n\t// Style of cloned element affects source element cloned (#8908)\n\tdiv.style.backgroundClip = \"content-box\";\n\tdiv.cloneNode( true ).style.backgroundClip = \"\";\n\tsupport.clearCloneStyle = div.style.backgroundClip === \"content-box\";\n\n\tcontainer.style.cssText = \"border:0;width:8px;height:0;top:0;left:-9999px;\" +\n\t\t\"padding:0;margin-top:1px;position:absolute\";\n\tcontainer.appendChild( div );\n\n\tjQuery.extend( support, {\n\t\tpixelPosition: function() {\n\t\t\tcomputeStyleTests();\n\t\t\treturn pixelPositionVal;\n\t\t},\n\t\tboxSizingReliable: function() {\n\t\t\tcomputeStyleTests();\n\t\t\treturn boxSizingReliableVal;\n\t\t},\n\t\tpixelMarginRight: function() {\n\t\t\tcomputeStyleTests();\n\t\t\treturn pixelMarginRightVal;\n\t\t},\n\t\treliableMarginLeft: function() {\n\t\t\tcomputeStyleTests();\n\t\t\treturn reliableMarginLeftVal;\n\t\t}\n\t} );\n} )();\n\n\nfunction curCSS( elem, name, computed ) {\n\tvar width, minWidth, maxWidth, ret,\n\t\tstyle = elem.style;\n\n\tcomputed = computed || getStyles( elem );\n\n\t// Support: IE <=9 only\n\t// getPropertyValue is only needed for .css('filter') (#12537)\n\tif ( computed ) {\n\t\tret = computed.getPropertyValue( name ) || computed[ name ];\n\n\t\tif ( ret === \"\" && !jQuery.contains( elem.ownerDocument, elem ) ) {\n\t\t\tret = jQuery.style( elem, name );\n\t\t}\n\n\t\t// A tribute to the \"awesome hack by Dean Edwards\"\n\t\t// Android Browser returns percentage for some values,\n\t\t// but width seems to be reliably pixels.\n\t\t// This is against the CSSOM draft spec:\n\t\t// https://drafts.csswg.org/cssom/#resolved-values\n\t\tif ( !support.pixelMarginRight() && rnumnonpx.test( ret ) && rmargin.test( name ) ) {\n\n\t\t\t// Remember the original values\n\t\t\twidth = style.width;\n\t\t\tminWidth = style.minWidth;\n\t\t\tmaxWidth = style.maxWidth;\n\n\t\t\t// Put in the new values to get a computed value out\n\t\t\tstyle.minWidth = style.maxWidth = style.width = ret;\n\t\t\tret = computed.width;\n\n\t\t\t// Revert the changed values\n\t\t\tstyle.width = width;\n\t\t\tstyle.minWidth = minWidth;\n\t\t\tstyle.maxWidth = maxWidth;\n\t\t}\n\t}\n\n\treturn ret !== undefined ?\n\n\t\t// Support: IE <=9 - 11 only\n\t\t// IE returns zIndex value as an integer.\n\t\tret + \"\" :\n\t\tret;\n}\n\n\nfunction addGetHookIf( conditionFn, hookFn ) {\n\n\t// Define the hook, we'll check on the first run if it's really needed.\n\treturn {\n\t\tget: function() {\n\t\t\tif ( conditionFn() ) {\n\n\t\t\t\t// Hook not needed (or it's not possible to use it due\n\t\t\t\t// to missing dependency), remove it.\n\t\t\t\tdelete this.get;\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// Hook needed; redefine it so that the support test is not executed again.\n\t\t\treturn ( this.get = hookFn ).apply( this, arguments );\n\t\t}\n\t};\n}\n\n\nvar\n\n\t// Swappable if display is none or starts with table\n\t// except \"table\", \"table-cell\", or \"table-caption\"\n\t// See here for display values: https://developer.mozilla.org/en-US/docs/CSS/display\n\trdisplayswap = /^(none|table(?!-c[ea]).+)/,\n\tcssShow = { position: \"absolute\", visibility: \"hidden\", display: \"block\" },\n\tcssNormalTransform = {\n\t\tletterSpacing: \"0\",\n\t\tfontWeight: \"400\"\n\t},\n\n\tcssPrefixes = [ \"Webkit\", \"Moz\", \"ms\" ],\n\temptyStyle = document.createElement( \"div\" ).style;\n\n// Return a css property mapped to a potentially vendor prefixed property\nfunction vendorPropName( name ) {\n\n\t// Shortcut for names that are not vendor prefixed\n\tif ( name in emptyStyle ) {\n\t\treturn name;\n\t}\n\n\t// Check for vendor prefixed names\n\tvar capName = name[ 0 ].toUpperCase() + name.slice( 1 ),\n\t\ti = cssPrefixes.length;\n\n\twhile ( i-- ) {\n\t\tname = cssPrefixes[ i ] + capName;\n\t\tif ( name in emptyStyle ) {\n\t\t\treturn name;\n\t\t}\n\t}\n}\n\nfunction setPositiveNumber( elem, value, subtract ) {\n\n\t// Any relative (+/-) values have already been\n\t// normalized at this point\n\tvar matches = rcssNum.exec( value );\n\treturn matches ?\n\n\t\t// Guard against undefined \"subtract\", e.g., when used as in cssHooks\n\t\tMath.max( 0, matches[ 2 ] - ( subtract || 0 ) ) + ( matches[ 3 ] || \"px\" ) :\n\t\tvalue;\n}\n\nfunction augmentWidthOrHeight( elem, name, extra, isBorderBox, styles ) {\n\tvar i = extra === ( isBorderBox ? \"border\" : \"content\" ) ?\n\n\t\t// If we already have the right measurement, avoid augmentation\n\t\t4 :\n\n\t\t// Otherwise initialize for horizontal or vertical properties\n\t\tname === \"width\" ? 1 : 0,\n\n\t\tval = 0;\n\n\tfor ( ; i < 4; i += 2 ) {\n\n\t\t// Both box models exclude margin, so add it if we want it\n\t\tif ( extra === \"margin\" ) {\n\t\t\tval += jQuery.css( elem, extra + cssExpand[ i ], true, styles );\n\t\t}\n\n\t\tif ( isBorderBox ) {\n\n\t\t\t// border-box includes padding, so remove it if we want content\n\t\t\tif ( extra === \"content\" ) {\n\t\t\t\tval -= jQuery.css( elem, \"padding\" + cssExpand[ i ], true, styles );\n\t\t\t}\n\n\t\t\t// At this point, extra isn't border nor margin, so remove border\n\t\t\tif ( extra !== \"margin\" ) {\n\t\t\t\tval -= jQuery.css( elem, \"border\" + cssExpand[ i ] + \"Width\", true, styles );\n\t\t\t}\n\t\t} else {\n\n\t\t\t// At this point, extra isn't content, so add padding\n\t\t\tval += jQuery.css( elem, \"padding\" + cssExpand[ i ], true, styles );\n\n\t\t\t// At this point, extra isn't content nor padding, so add border\n\t\t\tif ( extra !== \"padding\" ) {\n\t\t\t\tval += jQuery.css( elem, \"border\" + cssExpand[ i ] + \"Width\", true, styles );\n\t\t\t}\n\t\t}\n\t}\n\n\treturn val;\n}\n\nfunction getWidthOrHeight( elem, name, extra ) {\n\n\t// Start with offset property, which is equivalent to the border-box value\n\tvar val,\n\t\tvalueIsBorderBox = true,\n\t\tstyles = getStyles( elem ),\n\t\tisBorderBox = jQuery.css( elem, \"boxSizing\", false, styles ) === \"border-box\";\n\n\t// Support: IE <=11 only\n\t// Running getBoundingClientRect on a disconnected node\n\t// in IE throws an error.\n\tif ( elem.getClientRects().length ) {\n\t\tval = elem.getBoundingClientRect()[ name ];\n\t}\n\n\t// Some non-html elements return undefined for offsetWidth, so check for null/undefined\n\t// svg - https://bugzilla.mozilla.org/show_bug.cgi?id=649285\n\t// MathML - https://bugzilla.mozilla.org/show_bug.cgi?id=491668\n\tif ( val <= 0 || val == null ) {\n\n\t\t// Fall back to computed then uncomputed css if necessary\n\t\tval = curCSS( elem, name, styles );\n\t\tif ( val < 0 || val == null ) {\n\t\t\tval = elem.style[ name ];\n\t\t}\n\n\t\t// Computed unit is not pixels. Stop here and return.\n\t\tif ( rnumnonpx.test( val ) ) {\n\t\t\treturn val;\n\t\t}\n\n\t\t// Check for style in case a browser which returns unreliable values\n\t\t// for getComputedStyle silently falls back to the reliable elem.style\n\t\tvalueIsBorderBox = isBorderBox &&\n\t\t\t( support.boxSizingReliable() || val === elem.style[ name ] );\n\n\t\t// Normalize \"\", auto, and prepare for extra\n\t\tval = parseFloat( val ) || 0;\n\t}\n\n\t// Use the active box-sizing model to add/subtract irrelevant styles\n\treturn ( val +\n\t\taugmentWidthOrHeight(\n\t\t\telem,\n\t\t\tname,\n\t\t\textra || ( isBorderBox ? \"border\" : \"content\" ),\n\t\t\tvalueIsBorderBox,\n\t\t\tstyles\n\t\t)\n\t) + \"px\";\n}\n\njQuery.extend( {\n\n\t// Add in style property hooks for overriding the default\n\t// behavior of getting and setting a style property\n\tcssHooks: {\n\t\topacity: {\n\t\t\tget: function( elem, computed ) {\n\t\t\t\tif ( computed ) {\n\n\t\t\t\t\t// We should always get a number back from opacity\n\t\t\t\t\tvar ret = curCSS( elem, \"opacity\" );\n\t\t\t\t\treturn ret === \"\" ? \"1\" : ret;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t},\n\n\t// Don't automatically add \"px\" to these possibly-unitless properties\n\tcssNumber: {\n\t\t\"animationIterationCount\": true,\n\t\t\"columnCount\": true,\n\t\t\"fillOpacity\": true,\n\t\t\"flexGrow\": true,\n\t\t\"flexShrink\": true,\n\t\t\"fontWeight\": true,\n\t\t\"lineHeight\": true,\n\t\t\"opacity\": true,\n\t\t\"order\": true,\n\t\t\"orphans\": true,\n\t\t\"widows\": true,\n\t\t\"zIndex\": true,\n\t\t\"zoom\": true\n\t},\n\n\t// Add in properties whose names you wish to fix before\n\t// setting or getting the value\n\tcssProps: {\n\t\t\"float\": \"cssFloat\"\n\t},\n\n\t// Get and set the style property on a DOM Node\n\tstyle: function( elem, name, value, extra ) {\n\n\t\t// Don't set styles on text and comment nodes\n\t\tif ( !elem || elem.nodeType === 3 || elem.nodeType === 8 || !elem.style ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Make sure that we're working with the right name\n\t\tvar ret, type, hooks,\n\t\t\torigName = jQuery.camelCase( name ),\n\t\t\tstyle = elem.style;\n\n\t\tname = jQuery.cssProps[ origName ] ||\n\t\t\t( jQuery.cssProps[ origName ] = vendorPropName( origName ) || origName );\n\n\t\t// Gets hook for the prefixed version, then unprefixed version\n\t\thooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ];\n\n\t\t// Check if we're setting a value\n\t\tif ( value !== undefined ) {\n\t\t\ttype = typeof value;\n\n\t\t\t// Convert \"+=\" or \"-=\" to relative numbers (#7345)\n\t\t\tif ( type === \"string\" && ( ret = rcssNum.exec( value ) ) && ret[ 1 ] ) {\n\t\t\t\tvalue = adjustCSS( elem, name, ret );\n\n\t\t\t\t// Fixes bug #9237\n\t\t\t\ttype = \"number\";\n\t\t\t}\n\n\t\t\t// Make sure that null and NaN values aren't set (#7116)\n\t\t\tif ( value == null || value !== value ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// If a number was passed in, add the unit (except for certain CSS properties)\n\t\t\tif ( type === \"number\" ) {\n\t\t\t\tvalue += ret && ret[ 3 ] || ( jQuery.cssNumber[ origName ] ? \"\" : \"px\" );\n\t\t\t}\n\n\t\t\t// background-* props affect original clone's values\n\t\t\tif ( !support.clearCloneStyle && value === \"\" && name.indexOf( \"background\" ) === 0 ) {\n\t\t\t\tstyle[ name ] = \"inherit\";\n\t\t\t}\n\n\t\t\t// If a hook was provided, use that value, otherwise just set the specified value\n\t\t\tif ( !hooks || !( \"set\" in hooks ) ||\n\t\t\t\t( value = hooks.set( elem, value, extra ) ) !== undefined ) {\n\n\t\t\t\tstyle[ name ] = value;\n\t\t\t}\n\n\t\t} else {\n\n\t\t\t// If a hook was provided get the non-computed value from there\n\t\t\tif ( hooks && \"get\" in hooks &&\n\t\t\t\t( ret = hooks.get( elem, false, extra ) ) !== undefined ) {\n\n\t\t\t\treturn ret;\n\t\t\t}\n\n\t\t\t// Otherwise just get the value from the style object\n\t\t\treturn style[ name ];\n\t\t}\n\t},\n\n\tcss: function( elem, name, extra, styles ) {\n\t\tvar val, num, hooks,\n\t\t\torigName = jQuery.camelCase( name );\n\n\t\t// Make sure that we're working with the right name\n\t\tname = jQuery.cssProps[ origName ] ||\n\t\t\t( jQuery.cssProps[ origName ] = vendorPropName( origName ) || origName );\n\n\t\t// Try prefixed name followed by the unprefixed name\n\t\thooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ];\n\n\t\t// If a hook was provided get the computed value from there\n\t\tif ( hooks && \"get\" in hooks ) {\n\t\t\tval = hooks.get( elem, true, extra );\n\t\t}\n\n\t\t// Otherwise, if a way to get the computed value exists, use that\n\t\tif ( val === undefined ) {\n\t\t\tval = curCSS( elem, name, styles );\n\t\t}\n\n\t\t// Convert \"normal\" to computed value\n\t\tif ( val === \"normal\" && name in cssNormalTransform ) {\n\t\t\tval = cssNormalTransform[ name ];\n\t\t}\n\n\t\t// Make numeric if forced or a qualifier was provided and val looks numeric\n\t\tif ( extra === \"\" || extra ) {\n\t\t\tnum = parseFloat( val );\n\t\t\treturn extra === true || isFinite( num ) ? num || 0 : val;\n\t\t}\n\t\treturn val;\n\t}\n} );\n\njQuery.each( [ \"height\", \"width\" ], function( i, name ) {\n\tjQuery.cssHooks[ name ] = {\n\t\tget: function( elem, computed, extra ) {\n\t\t\tif ( computed ) {\n\n\t\t\t\t// Certain elements can have dimension info if we invisibly show them\n\t\t\t\t// but it must have a current display style that would benefit\n\t\t\t\treturn rdisplayswap.test( jQuery.css( elem, \"display\" ) ) &&\n\n\t\t\t\t\t// Support: Safari 8+\n\t\t\t\t\t// Table columns in Safari have non-zero offsetWidth & zero\n\t\t\t\t\t// getBoundingClientRect().width unless display is changed.\n\t\t\t\t\t// Support: IE <=11 only\n\t\t\t\t\t// Running getBoundingClientRect on a disconnected node\n\t\t\t\t\t// in IE throws an error.\n\t\t\t\t\t( !elem.getClientRects().length || !elem.getBoundingClientRect().width ) ?\n\t\t\t\t\t\tswap( elem, cssShow, function() {\n\t\t\t\t\t\t\treturn getWidthOrHeight( elem, name, extra );\n\t\t\t\t\t\t} ) :\n\t\t\t\t\t\tgetWidthOrHeight( elem, name, extra );\n\t\t\t}\n\t\t},\n\n\t\tset: function( elem, value, extra ) {\n\t\t\tvar matches,\n\t\t\t\tstyles = extra && getStyles( elem ),\n\t\t\t\tsubtract = extra && augmentWidthOrHeight(\n\t\t\t\t\telem,\n\t\t\t\t\tname,\n\t\t\t\t\textra,\n\t\t\t\t\tjQuery.css( elem, \"boxSizing\", false, styles ) === \"border-box\",\n\t\t\t\t\tstyles\n\t\t\t\t);\n\n\t\t\t// Convert to pixels if value adjustment is needed\n\t\t\tif ( subtract && ( matches = rcssNum.exec( value ) ) &&\n\t\t\t\t( matches[ 3 ] || \"px\" ) !== \"px\" ) {\n\n\t\t\t\telem.style[ name ] = value;\n\t\t\t\tvalue = jQuery.css( elem, name );\n\t\t\t}\n\n\t\t\treturn setPositiveNumber( elem, value, subtract );\n\t\t}\n\t};\n} );\n\njQuery.cssHooks.marginLeft = addGetHookIf( support.reliableMarginLeft,\n\tfunction( elem, computed ) {\n\t\tif ( computed ) {\n\t\t\treturn ( parseFloat( curCSS( elem, \"marginLeft\" ) ) ||\n\t\t\t\telem.getBoundingClientRect().left -\n\t\t\t\t\tswap( elem, { marginLeft: 0 }, function() {\n\t\t\t\t\t\treturn elem.getBoundingClientRect().left;\n\t\t\t\t\t} )\n\t\t\t\t) + \"px\";\n\t\t}\n\t}\n);\n\n// These hooks are used by animate to expand properties\njQuery.each( {\n\tmargin: \"\",\n\tpadding: \"\",\n\tborder: \"Width\"\n}, function( prefix, suffix ) {\n\tjQuery.cssHooks[ prefix + suffix ] = {\n\t\texpand: function( value ) {\n\t\t\tvar i = 0,\n\t\t\t\texpanded = {},\n\n\t\t\t\t// Assumes a single number if not a string\n\t\t\t\tparts = typeof value === \"string\" ? value.split( \" \" ) : [ value ];\n\n\t\t\tfor ( ; i < 4; i++ ) {\n\t\t\t\texpanded[ prefix + cssExpand[ i ] + suffix ] =\n\t\t\t\t\tparts[ i ] || parts[ i - 2 ] || parts[ 0 ];\n\t\t\t}\n\n\t\t\treturn expanded;\n\t\t}\n\t};\n\n\tif ( !rmargin.test( prefix ) ) {\n\t\tjQuery.cssHooks[ prefix + suffix ].set = setPositiveNumber;\n\t}\n} );\n\njQuery.fn.extend( {\n\tcss: function( name, value ) {\n\t\treturn access( this, function( elem, name, value ) {\n\t\t\tvar styles, len,\n\t\t\t\tmap = {},\n\t\t\t\ti = 0;\n\n\t\t\tif ( jQuery.isArray( name ) ) {\n\t\t\t\tstyles = getStyles( elem );\n\t\t\t\tlen = name.length;\n\n\t\t\t\tfor ( ; i < len; i++ ) {\n\t\t\t\t\tmap[ name[ i ] ] = jQuery.css( elem, name[ i ], false, styles );\n\t\t\t\t}\n\n\t\t\t\treturn map;\n\t\t\t}\n\n\t\t\treturn value !== undefined ?\n\t\t\t\tjQuery.style( elem, name, value ) :\n\t\t\t\tjQuery.css( elem, name );\n\t\t}, name, value, arguments.length > 1 );\n\t}\n} );\n\n\nfunction Tween( elem, options, prop, end, easing ) {\n\treturn new Tween.prototype.init( elem, options, prop, end, easing );\n}\njQuery.Tween = Tween;\n\nTween.prototype = {\n\tconstructor: Tween,\n\tinit: function( elem, options, prop, end, easing, unit ) {\n\t\tthis.elem = elem;\n\t\tthis.prop = prop;\n\t\tthis.easing = easing || jQuery.easing._default;\n\t\tthis.options = options;\n\t\tthis.start = this.now = this.cur();\n\t\tthis.end = end;\n\t\tthis.unit = unit || ( jQuery.cssNumber[ prop ] ? \"\" : \"px\" );\n\t},\n\tcur: function() {\n\t\tvar hooks = Tween.propHooks[ this.prop ];\n\n\t\treturn hooks && hooks.get ?\n\t\t\thooks.get( this ) :\n\t\t\tTween.propHooks._default.get( this );\n\t},\n\trun: function( percent ) {\n\t\tvar eased,\n\t\t\thooks = Tween.propHooks[ this.prop ];\n\n\t\tif ( this.options.duration ) {\n\t\t\tthis.pos = eased = jQuery.easing[ this.easing ](\n\t\t\t\tpercent, this.options.duration * percent, 0, 1, this.options.duration\n\t\t\t);\n\t\t} else {\n\t\t\tthis.pos = eased = percent;\n\t\t}\n\t\tthis.now = ( this.end - this.start ) * eased + this.start;\n\n\t\tif ( this.options.step ) {\n\t\t\tthis.options.step.call( this.elem, this.now, this );\n\t\t}\n\n\t\tif ( hooks && hooks.set ) {\n\t\t\thooks.set( this );\n\t\t} else {\n\t\t\tTween.propHooks._default.set( this );\n\t\t}\n\t\treturn this;\n\t}\n};\n\nTween.prototype.init.prototype = Tween.prototype;\n\nTween.propHooks = {\n\t_default: {\n\t\tget: function( tween ) {\n\t\t\tvar result;\n\n\t\t\t// Use a property on the element directly when it is not a DOM element,\n\t\t\t// or when there is no matching style property that exists.\n\t\t\tif ( tween.elem.nodeType !== 1 ||\n\t\t\t\ttween.elem[ tween.prop ] != null && tween.elem.style[ tween.prop ] == null ) {\n\t\t\t\treturn tween.elem[ tween.prop ];\n\t\t\t}\n\n\t\t\t// Passing an empty string as a 3rd parameter to .css will automatically\n\t\t\t// attempt a parseFloat and fallback to a string if the parse fails.\n\t\t\t// Simple values such as \"10px\" are parsed to Float;\n\t\t\t// complex values such as \"rotate(1rad)\" are returned as-is.\n\t\t\tresult = jQuery.css( tween.elem, tween.prop, \"\" );\n\n\t\t\t// Empty strings, null, undefined and \"auto\" are converted to 0.\n\t\t\treturn !result || result === \"auto\" ? 0 : result;\n\t\t},\n\t\tset: function( tween ) {\n\n\t\t\t// Use step hook for back compat.\n\t\t\t// Use cssHook if its there.\n\t\t\t// Use .style if available and use plain properties where available.\n\t\t\tif ( jQuery.fx.step[ tween.prop ] ) {\n\t\t\t\tjQuery.fx.step[ tween.prop ]( tween );\n\t\t\t} else if ( tween.elem.nodeType === 1 &&\n\t\t\t\t( tween.elem.style[ jQuery.cssProps[ tween.prop ] ] != null ||\n\t\t\t\t\tjQuery.cssHooks[ tween.prop ] ) ) {\n\t\t\t\tjQuery.style( tween.elem, tween.prop, tween.now + tween.unit );\n\t\t\t} else {\n\t\t\t\ttween.elem[ tween.prop ] = tween.now;\n\t\t\t}\n\t\t}\n\t}\n};\n\n// Support: IE <=9 only\n// Panic based approach to setting things on disconnected nodes\nTween.propHooks.scrollTop = Tween.propHooks.scrollLeft = {\n\tset: function( tween ) {\n\t\tif ( tween.elem.nodeType && tween.elem.parentNode ) {\n\t\t\ttween.elem[ tween.prop ] = tween.now;\n\t\t}\n\t}\n};\n\njQuery.easing = {\n\tlinear: function( p ) {\n\t\treturn p;\n\t},\n\tswing: function( p ) {\n\t\treturn 0.5 - Math.cos( p * Math.PI ) / 2;\n\t},\n\t_default: \"swing\"\n};\n\njQuery.fx = Tween.prototype.init;\n\n// Back compat <1.8 extension point\njQuery.fx.step = {};\n\n\n\n\nvar\n\tfxNow, timerId,\n\trfxtypes = /^(?:toggle|show|hide)$/,\n\trrun = /queueHooks$/;\n\nfunction raf() {\n\tif ( timerId ) {\n\t\twindow.requestAnimationFrame( raf );\n\t\tjQuery.fx.tick();\n\t}\n}\n\n// Animations created synchronously will run synchronously\nfunction createFxNow() {\n\twindow.setTimeout( function() {\n\t\tfxNow = undefined;\n\t} );\n\treturn ( fxNow = jQuery.now() );\n}\n\n// Generate parameters to create a standard animation\nfunction genFx( type, includeWidth ) {\n\tvar which,\n\t\ti = 0,\n\t\tattrs = { height: type };\n\n\t// If we include width, step value is 1 to do all cssExpand values,\n\t// otherwise step value is 2 to skip over Left and Right\n\tincludeWidth = includeWidth ? 1 : 0;\n\tfor ( ; i < 4; i += 2 - includeWidth ) {\n\t\twhich = cssExpand[ i ];\n\t\tattrs[ \"margin\" + which ] = attrs[ \"padding\" + which ] = type;\n\t}\n\n\tif ( includeWidth ) {\n\t\tattrs.opacity = attrs.width = type;\n\t}\n\n\treturn attrs;\n}\n\nfunction createTween( value, prop, animation ) {\n\tvar tween,\n\t\tcollection = ( Animation.tweeners[ prop ] || [] ).concat( Animation.tweeners[ \"*\" ] ),\n\t\tindex = 0,\n\t\tlength = collection.length;\n\tfor ( ; index < length; index++ ) {\n\t\tif ( ( tween = collection[ index ].call( animation, prop, value ) ) ) {\n\n\t\t\t// We're done with this property\n\t\t\treturn tween;\n\t\t}\n\t}\n}\n\nfunction defaultPrefilter( elem, props, opts ) {\n\tvar prop, value, toggle, hooks, oldfire, propTween, restoreDisplay, display,\n\t\tisBox = \"width\" in props || \"height\" in props,\n\t\tanim = this,\n\t\torig = {},\n\t\tstyle = elem.style,\n\t\thidden = elem.nodeType && isHiddenWithinTree( elem ),\n\t\tdataShow = dataPriv.get( elem, \"fxshow\" );\n\n\t// Queue-skipping animations hijack the fx hooks\n\tif ( !opts.queue ) {\n\t\thooks = jQuery._queueHooks( elem, \"fx\" );\n\t\tif ( hooks.unqueued == null ) {\n\t\t\thooks.unqueued = 0;\n\t\t\toldfire = hooks.empty.fire;\n\t\t\thooks.empty.fire = function() {\n\t\t\t\tif ( !hooks.unqueued ) {\n\t\t\t\t\toldfire();\n\t\t\t\t}\n\t\t\t};\n\t\t}\n\t\thooks.unqueued++;\n\n\t\tanim.always( function() {\n\n\t\t\t// Ensure the complete handler is called before this completes\n\t\t\tanim.always( function() {\n\t\t\t\thooks.unqueued--;\n\t\t\t\tif ( !jQuery.queue( elem, \"fx\" ).length ) {\n\t\t\t\t\thooks.empty.fire();\n\t\t\t\t}\n\t\t\t} );\n\t\t} );\n\t}\n\n\t// Detect show/hide animations\n\tfor ( prop in props ) {\n\t\tvalue = props[ prop ];\n\t\tif ( rfxtypes.test( value ) ) {\n\t\t\tdelete props[ prop ];\n\t\t\ttoggle = toggle || value === \"toggle\";\n\t\t\tif ( value === ( hidden ? \"hide\" : \"show\" ) ) {\n\n\t\t\t\t// Pretend to be hidden if this is a \"show\" and\n\t\t\t\t// there is still data from a stopped show/hide\n\t\t\t\tif ( value === \"show\" && dataShow && dataShow[ prop ] !== undefined ) {\n\t\t\t\t\thidden = true;\n\n\t\t\t\t// Ignore all other no-op show/hide data\n\t\t\t\t} else {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t}\n\t\t\torig[ prop ] = dataShow && dataShow[ prop ] || jQuery.style( elem, prop );\n\t\t}\n\t}\n\n\t// Bail out if this is a no-op like .hide().hide()\n\tpropTween = !jQuery.isEmptyObject( props );\n\tif ( !propTween && jQuery.isEmptyObject( orig ) ) {\n\t\treturn;\n\t}\n\n\t// Restrict \"overflow\" and \"display\" styles during box animations\n\tif ( isBox && elem.nodeType === 1 ) {\n\n\t\t// Support: IE <=9 - 11, Edge 12 - 13\n\t\t// Record all 3 overflow attributes because IE does not infer the shorthand\n\t\t// from identically-valued overflowX and overflowY\n\t\topts.overflow = [ style.overflow, style.overflowX, style.overflowY ];\n\n\t\t// Identify a display type, preferring old show/hide data over the CSS cascade\n\t\trestoreDisplay = dataShow && dataShow.display;\n\t\tif ( restoreDisplay == null ) {\n\t\t\trestoreDisplay = dataPriv.get( elem, \"display\" );\n\t\t}\n\t\tdisplay = jQuery.css( elem, \"display\" );\n\t\tif ( display === \"none\" ) {\n\t\t\tif ( restoreDisplay ) {\n\t\t\t\tdisplay = restoreDisplay;\n\t\t\t} else {\n\n\t\t\t\t// Get nonempty value(s) by temporarily forcing visibility\n\t\t\t\tshowHide( [ elem ], true );\n\t\t\t\trestoreDisplay = elem.style.display || restoreDisplay;\n\t\t\t\tdisplay = jQuery.css( elem, \"display\" );\n\t\t\t\tshowHide( [ elem ] );\n\t\t\t}\n\t\t}\n\n\t\t// Animate inline elements as inline-block\n\t\tif ( display === \"inline\" || display === \"inline-block\" && restoreDisplay != null ) {\n\t\t\tif ( jQuery.css( elem, \"float\" ) === \"none\" ) {\n\n\t\t\t\t// Restore the original display value at the end of pure show/hide animations\n\t\t\t\tif ( !propTween ) {\n\t\t\t\t\tanim.done( function() {\n\t\t\t\t\t\tstyle.display = restoreDisplay;\n\t\t\t\t\t} );\n\t\t\t\t\tif ( restoreDisplay == null ) {\n\t\t\t\t\t\tdisplay = style.display;\n\t\t\t\t\t\trestoreDisplay = display === \"none\" ? \"\" : display;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tstyle.display = \"inline-block\";\n\t\t\t}\n\t\t}\n\t}\n\n\tif ( opts.overflow ) {\n\t\tstyle.overflow = \"hidden\";\n\t\tanim.always( function() {\n\t\t\tstyle.overflow = opts.overflow[ 0 ];\n\t\t\tstyle.overflowX = opts.overflow[ 1 ];\n\t\t\tstyle.overflowY = opts.overflow[ 2 ];\n\t\t} );\n\t}\n\n\t// Implement show/hide animations\n\tpropTween = false;\n\tfor ( prop in orig ) {\n\n\t\t// General show/hide setup for this element animation\n\t\tif ( !propTween ) {\n\t\t\tif ( dataShow ) {\n\t\t\t\tif ( \"hidden\" in dataShow ) {\n\t\t\t\t\thidden = dataShow.hidden;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tdataShow = dataPriv.access( elem, \"fxshow\", { display: restoreDisplay } );\n\t\t\t}\n\n\t\t\t// Store hidden/visible for toggle so `.stop().toggle()` \"reverses\"\n\t\t\tif ( toggle ) {\n\t\t\t\tdataShow.hidden = !hidden;\n\t\t\t}\n\n\t\t\t// Show elements before animating them\n\t\t\tif ( hidden ) {\n\t\t\t\tshowHide( [ elem ], true );\n\t\t\t}\n\n\t\t\t/* eslint-disable no-loop-func */\n\n\t\t\tanim.done( function() {\n\n\t\t\t/* eslint-enable no-loop-func */\n\n\t\t\t\t// The final step of a \"hide\" animation is actually hiding the element\n\t\t\t\tif ( !hidden ) {\n\t\t\t\t\tshowHide( [ elem ] );\n\t\t\t\t}\n\t\t\t\tdataPriv.remove( elem, \"fxshow\" );\n\t\t\t\tfor ( prop in orig ) {\n\t\t\t\t\tjQuery.style( elem, prop, orig[ prop ] );\n\t\t\t\t}\n\t\t\t} );\n\t\t}\n\n\t\t// Per-property setup\n\t\tpropTween = createTween( hidden ? dataShow[ prop ] : 0, prop, anim );\n\t\tif ( !( prop in dataShow ) ) {\n\t\t\tdataShow[ prop ] = propTween.start;\n\t\t\tif ( hidden ) {\n\t\t\t\tpropTween.end = propTween.start;\n\t\t\t\tpropTween.start = 0;\n\t\t\t}\n\t\t}\n\t}\n}\n\nfunction propFilter( props, specialEasing ) {\n\tvar index, name, easing, value, hooks;\n\n\t// camelCase, specialEasing and expand cssHook pass\n\tfor ( index in props ) {\n\t\tname = jQuery.camelCase( index );\n\t\teasing = specialEasing[ name ];\n\t\tvalue = props[ index ];\n\t\tif ( jQuery.isArray( value ) ) {\n\t\t\teasing = value[ 1 ];\n\t\t\tvalue = props[ index ] = value[ 0 ];\n\t\t}\n\n\t\tif ( index !== name ) {\n\t\t\tprops[ name ] = value;\n\t\t\tdelete props[ index ];\n\t\t}\n\n\t\thooks = jQuery.cssHooks[ name ];\n\t\tif ( hooks && \"expand\" in hooks ) {\n\t\t\tvalue = hooks.expand( value );\n\t\t\tdelete props[ name ];\n\n\t\t\t// Not quite $.extend, this won't overwrite existing keys.\n\t\t\t// Reusing 'index' because we have the correct \"name\"\n\t\t\tfor ( index in value ) {\n\t\t\t\tif ( !( index in props ) ) {\n\t\t\t\t\tprops[ index ] = value[ index ];\n\t\t\t\t\tspecialEasing[ index ] = easing;\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\tspecialEasing[ name ] = easing;\n\t\t}\n\t}\n}\n\nfunction Animation( elem, properties, options ) {\n\tvar result,\n\t\tstopped,\n\t\tindex = 0,\n\t\tlength = Animation.prefilters.length,\n\t\tdeferred = jQuery.Deferred().always( function() {\n\n\t\t\t// Don't match elem in the :animated selector\n\t\t\tdelete tick.elem;\n\t\t} ),\n\t\ttick = function() {\n\t\t\tif ( stopped ) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\tvar currentTime = fxNow || createFxNow(),\n\t\t\t\tremaining = Math.max( 0, animation.startTime + animation.duration - currentTime ),\n\n\t\t\t\t// Support: Android 2.3 only\n\t\t\t\t// Archaic crash bug won't allow us to use `1 - ( 0.5 || 0 )` (#12497)\n\t\t\t\ttemp = remaining / animation.duration || 0,\n\t\t\t\tpercent = 1 - temp,\n\t\t\t\tindex = 0,\n\t\t\t\tlength = animation.tweens.length;\n\n\t\t\tfor ( ; index < length; index++ ) {\n\t\t\t\tanimation.tweens[ index ].run( percent );\n\t\t\t}\n\n\t\t\tdeferred.notifyWith( elem, [ animation, percent, remaining ] );\n\n\t\t\tif ( percent < 1 && length ) {\n\t\t\t\treturn remaining;\n\t\t\t} else {\n\t\t\t\tdeferred.resolveWith( elem, [ animation ] );\n\t\t\t\treturn false;\n\t\t\t}\n\t\t},\n\t\tanimation = deferred.promise( {\n\t\t\telem: elem,\n\t\t\tprops: jQuery.extend( {}, properties ),\n\t\t\topts: jQuery.extend( true, {\n\t\t\t\tspecialEasing: {},\n\t\t\t\teasing: jQuery.easing._default\n\t\t\t}, options ),\n\t\t\toriginalProperties: properties,\n\t\t\toriginalOptions: options,\n\t\t\tstartTime: fxNow || createFxNow(),\n\t\t\tduration: options.duration,\n\t\t\ttweens: [],\n\t\t\tcreateTween: function( prop, end ) {\n\t\t\t\tvar tween = jQuery.Tween( elem, animation.opts, prop, end,\n\t\t\t\t\t\tanimation.opts.specialEasing[ prop ] || animation.opts.easing );\n\t\t\t\tanimation.tweens.push( tween );\n\t\t\t\treturn tween;\n\t\t\t},\n\t\t\tstop: function( gotoEnd ) {\n\t\t\t\tvar index = 0,\n\n\t\t\t\t\t// If we are going to the end, we want to run all the tweens\n\t\t\t\t\t// otherwise we skip this part\n\t\t\t\t\tlength = gotoEnd ? animation.tweens.length : 0;\n\t\t\t\tif ( stopped ) {\n\t\t\t\t\treturn this;\n\t\t\t\t}\n\t\t\t\tstopped = true;\n\t\t\t\tfor ( ; index < length; index++ ) {\n\t\t\t\t\tanimation.tweens[ index ].run( 1 );\n\t\t\t\t}\n\n\t\t\t\t// Resolve when we played the last frame; otherwise, reject\n\t\t\t\tif ( gotoEnd ) {\n\t\t\t\t\tdeferred.notifyWith( elem, [ animation, 1, 0 ] );\n\t\t\t\t\tdeferred.resolveWith( elem, [ animation, gotoEnd ] );\n\t\t\t\t} else {\n\t\t\t\t\tdeferred.rejectWith( elem, [ animation, gotoEnd ] );\n\t\t\t\t}\n\t\t\t\treturn this;\n\t\t\t}\n\t\t} ),\n\t\tprops = animation.props;\n\n\tpropFilter( props, animation.opts.specialEasing );\n\n\tfor ( ; index < length; index++ ) {\n\t\tresult = Animation.prefilters[ index ].call( animation, elem, props, animation.opts );\n\t\tif ( result ) {\n\t\t\tif ( jQuery.isFunction( result.stop ) ) {\n\t\t\t\tjQuery._queueHooks( animation.elem, animation.opts.queue ).stop =\n\t\t\t\t\tjQuery.proxy( result.stop, result );\n\t\t\t}\n\t\t\treturn result;\n\t\t}\n\t}\n\n\tjQuery.map( props, createTween, animation );\n\n\tif ( jQuery.isFunction( animation.opts.start ) ) {\n\t\tanimation.opts.start.call( elem, animation );\n\t}\n\n\tjQuery.fx.timer(\n\t\tjQuery.extend( tick, {\n\t\t\telem: elem,\n\t\t\tanim: animation,\n\t\t\tqueue: animation.opts.queue\n\t\t} )\n\t);\n\n\t// attach callbacks from options\n\treturn animation.progress( animation.opts.progress )\n\t\t.done( animation.opts.done, animation.opts.complete )\n\t\t.fail( animation.opts.fail )\n\t\t.always( animation.opts.always );\n}\n\njQuery.Animation = jQuery.extend( Animation, {\n\n\ttweeners: {\n\t\t\"*\": [ function( prop, value ) {\n\t\t\tvar tween = this.createTween( prop, value );\n\t\t\tadjustCSS( tween.elem, prop, rcssNum.exec( value ), tween );\n\t\t\treturn tween;\n\t\t} ]\n\t},\n\n\ttweener: function( props, callback ) {\n\t\tif ( jQuery.isFunction( props ) ) {\n\t\t\tcallback = props;\n\t\t\tprops = [ \"*\" ];\n\t\t} else {\n\t\t\tprops = props.match( rnotwhite );\n\t\t}\n\n\t\tvar prop,\n\t\t\tindex = 0,\n\t\t\tlength = props.length;\n\n\t\tfor ( ; index < length; index++ ) {\n\t\t\tprop = props[ index ];\n\t\t\tAnimation.tweeners[ prop ] = Animation.tweeners[ prop ] || [];\n\t\t\tAnimation.tweeners[ prop ].unshift( callback );\n\t\t}\n\t},\n\n\tprefilters: [ defaultPrefilter ],\n\n\tprefilter: function( callback, prepend ) {\n\t\tif ( prepend ) {\n\t\t\tAnimation.prefilters.unshift( callback );\n\t\t} else {\n\t\t\tAnimation.prefilters.push( callback );\n\t\t}\n\t}\n} );\n\njQuery.speed = function( speed, easing, fn ) {\n\tvar opt = speed && typeof speed === \"object\" ? jQuery.extend( {}, speed ) : {\n\t\tcomplete: fn || !fn && easing ||\n\t\t\tjQuery.isFunction( speed ) && speed,\n\t\tduration: speed,\n\t\teasing: fn && easing || easing && !jQuery.isFunction( easing ) && easing\n\t};\n\n\t// Go to the end state if fx are off or if document is hidden\n\tif ( jQuery.fx.off || document.hidden ) {\n\t\topt.duration = 0;\n\n\t} else {\n\t\topt.duration = typeof opt.duration === \"number\" ?\n\t\t\topt.duration : opt.duration in jQuery.fx.speeds ?\n\t\t\t\tjQuery.fx.speeds[ opt.duration ] : jQuery.fx.speeds._default;\n\t}\n\n\t// Normalize opt.queue - true/undefined/null -> \"fx\"\n\tif ( opt.queue == null || opt.queue === true ) {\n\t\topt.queue = \"fx\";\n\t}\n\n\t// Queueing\n\topt.old = opt.complete;\n\n\topt.complete = function() {\n\t\tif ( jQuery.isFunction( opt.old ) ) {\n\t\t\topt.old.call( this );\n\t\t}\n\n\t\tif ( opt.queue ) {\n\t\t\tjQuery.dequeue( this, opt.queue );\n\t\t}\n\t};\n\n\treturn opt;\n};\n\njQuery.fn.extend( {\n\tfadeTo: function( speed, to, easing, callback ) {\n\n\t\t// Show any hidden elements after setting opacity to 0\n\t\treturn this.filter( isHiddenWithinTree ).css( \"opacity\", 0 ).show()\n\n\t\t\t// Animate to the value specified\n\t\t\t.end().animate( { opacity: to }, speed, easing, callback );\n\t},\n\tanimate: function( prop, speed, easing, callback ) {\n\t\tvar empty = jQuery.isEmptyObject( prop ),\n\t\t\toptall = jQuery.speed( speed, easing, callback ),\n\t\t\tdoAnimation = function() {\n\n\t\t\t\t// Operate on a copy of prop so per-property easing won't be lost\n\t\t\t\tvar anim = Animation( this, jQuery.extend( {}, prop ), optall );\n\n\t\t\t\t// Empty animations, or finishing resolves immediately\n\t\t\t\tif ( empty || dataPriv.get( this, \"finish\" ) ) {\n\t\t\t\t\tanim.stop( true );\n\t\t\t\t}\n\t\t\t};\n\t\t\tdoAnimation.finish = doAnimation;\n\n\t\treturn empty || optall.queue === false ?\n\t\t\tthis.each( doAnimation ) :\n\t\t\tthis.queue( optall.queue, doAnimation );\n\t},\n\tstop: function( type, clearQueue, gotoEnd ) {\n\t\tvar stopQueue = function( hooks ) {\n\t\t\tvar stop = hooks.stop;\n\t\t\tdelete hooks.stop;\n\t\t\tstop( gotoEnd );\n\t\t};\n\n\t\tif ( typeof type !== \"string\" ) {\n\t\t\tgotoEnd = clearQueue;\n\t\t\tclearQueue = type;\n\t\t\ttype = undefined;\n\t\t}\n\t\tif ( clearQueue && type !== false ) {\n\t\t\tthis.queue( type || \"fx\", [] );\n\t\t}\n\n\t\treturn this.each( function() {\n\t\t\tvar dequeue = true,\n\t\t\t\tindex = type != null && type + \"queueHooks\",\n\t\t\t\ttimers = jQuery.timers,\n\t\t\t\tdata = dataPriv.get( this );\n\n\t\t\tif ( index ) {\n\t\t\t\tif ( data[ index ] && data[ index ].stop ) {\n\t\t\t\t\tstopQueue( data[ index ] );\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tfor ( index in data ) {\n\t\t\t\t\tif ( data[ index ] && data[ index ].stop && rrun.test( index ) ) {\n\t\t\t\t\t\tstopQueue( data[ index ] );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tfor ( index = timers.length; index--; ) {\n\t\t\t\tif ( timers[ index ].elem === this &&\n\t\t\t\t\t( type == null || timers[ index ].queue === type ) ) {\n\n\t\t\t\t\ttimers[ index ].anim.stop( gotoEnd );\n\t\t\t\t\tdequeue = false;\n\t\t\t\t\ttimers.splice( index, 1 );\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Start the next in the queue if the last step wasn't forced.\n\t\t\t// Timers currently will call their complete callbacks, which\n\t\t\t// will dequeue but only if they were gotoEnd.\n\t\t\tif ( dequeue || !gotoEnd ) {\n\t\t\t\tjQuery.dequeue( this, type );\n\t\t\t}\n\t\t} );\n\t},\n\tfinish: function( type ) {\n\t\tif ( type !== false ) {\n\t\t\ttype = type || \"fx\";\n\t\t}\n\t\treturn this.each( function() {\n\t\t\tvar index,\n\t\t\t\tdata = dataPriv.get( this ),\n\t\t\t\tqueue = data[ type + \"queue\" ],\n\t\t\t\thooks = data[ type + \"queueHooks\" ],\n\t\t\t\ttimers = jQuery.timers,\n\t\t\t\tlength = queue ? queue.length : 0;\n\n\t\t\t// Enable finishing flag on private data\n\t\t\tdata.finish = true;\n\n\t\t\t// Empty the queue first\n\t\t\tjQuery.queue( this, type, [] );\n\n\t\t\tif ( hooks && hooks.stop ) {\n\t\t\t\thooks.stop.call( this, true );\n\t\t\t}\n\n\t\t\t// Look for any active animations, and finish them\n\t\t\tfor ( index = timers.length; index--; ) {\n\t\t\t\tif ( timers[ index ].elem === this && timers[ index ].queue === type ) {\n\t\t\t\t\ttimers[ index ].anim.stop( true );\n\t\t\t\t\ttimers.splice( index, 1 );\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Look for any animations in the old queue and finish them\n\t\t\tfor ( index = 0; index < length; index++ ) {\n\t\t\t\tif ( queue[ index ] && queue[ index ].finish ) {\n\t\t\t\t\tqueue[ index ].finish.call( this );\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Turn off finishing flag\n\t\t\tdelete data.finish;\n\t\t} );\n\t}\n} );\n\njQuery.each( [ \"toggle\", \"show\", \"hide\" ], function( i, name ) {\n\tvar cssFn = jQuery.fn[ name ];\n\tjQuery.fn[ name ] = function( speed, easing, callback ) {\n\t\treturn speed == null || typeof speed === \"boolean\" ?\n\t\t\tcssFn.apply( this, arguments ) :\n\t\t\tthis.animate( genFx( name, true ), speed, easing, callback );\n\t};\n} );\n\n// Generate shortcuts for custom animations\njQuery.each( {\n\tslideDown: genFx( \"show\" ),\n\tslideUp: genFx( \"hide\" ),\n\tslideToggle: genFx( \"toggle\" ),\n\tfadeIn: { opacity: \"show\" },\n\tfadeOut: { opacity: \"hide\" },\n\tfadeToggle: { opacity: \"toggle\" }\n}, function( name, props ) {\n\tjQuery.fn[ name ] = function( speed, easing, callback ) {\n\t\treturn this.animate( props, speed, easing, callback );\n\t};\n} );\n\njQuery.timers = [];\njQuery.fx.tick = function() {\n\tvar timer,\n\t\ti = 0,\n\t\ttimers = jQuery.timers;\n\n\tfxNow = jQuery.now();\n\n\tfor ( ; i < timers.length; i++ ) {\n\t\ttimer = timers[ i ];\n\n\t\t// Checks the timer has not already been removed\n\t\tif ( !timer() && timers[ i ] === timer ) {\n\t\t\ttimers.splice( i--, 1 );\n\t\t}\n\t}\n\n\tif ( !timers.length ) {\n\t\tjQuery.fx.stop();\n\t}\n\tfxNow = undefined;\n};\n\njQuery.fx.timer = function( timer ) {\n\tjQuery.timers.push( timer );\n\tif ( timer() ) {\n\t\tjQuery.fx.start();\n\t} else {\n\t\tjQuery.timers.pop();\n\t}\n};\n\njQuery.fx.interval = 13;\njQuery.fx.start = function() {\n\tif ( !timerId ) {\n\t\ttimerId = window.requestAnimationFrame ?\n\t\t\twindow.requestAnimationFrame( raf ) :\n\t\t\twindow.setInterval( jQuery.fx.tick, jQuery.fx.interval );\n\t}\n};\n\njQuery.fx.stop = function() {\n\tif ( window.cancelAnimationFrame ) {\n\t\twindow.cancelAnimationFrame( timerId );\n\t} else {\n\t\twindow.clearInterval( timerId );\n\t}\n\n\ttimerId = null;\n};\n\njQuery.fx.speeds = {\n\tslow: 600,\n\tfast: 200,\n\n\t// Default speed\n\t_default: 400\n};\n\n\n// Based off of the plugin by Clint Helfers, with permission.\n// https://web.archive.org/web/20100324014747/http://blindsignals.com/index.php/2009/07/jquery-delay/\njQuery.fn.delay = function( time, type ) {\n\ttime = jQuery.fx ? jQuery.fx.speeds[ time ] || time : time;\n\ttype = type || \"fx\";\n\n\treturn this.queue( type, function( next, hooks ) {\n\t\tvar timeout = window.setTimeout( next, time );\n\t\thooks.stop = function() {\n\t\t\twindow.clearTimeout( timeout );\n\t\t};\n\t} );\n};\n\n\n( function() {\n\tvar input = document.createElement( \"input\" ),\n\t\tselect = document.createElement( \"select\" ),\n\t\topt = select.appendChild( document.createElement( \"option\" ) );\n\n\tinput.type = \"checkbox\";\n\n\t// Support: Android <=4.3 only\n\t// Default value for a checkbox should be \"on\"\n\tsupport.checkOn = input.value !== \"\";\n\n\t// Support: IE <=11 only\n\t// Must access selectedIndex to make default options select\n\tsupport.optSelected = opt.selected;\n\n\t// Support: IE <=11 only\n\t// An input loses its value after becoming a radio\n\tinput = document.createElement( \"input\" );\n\tinput.value = \"t\";\n\tinput.type = \"radio\";\n\tsupport.radioValue = input.value === \"t\";\n} )();\n\n\nvar boolHook,\n\tattrHandle = jQuery.expr.attrHandle;\n\njQuery.fn.extend( {\n\tattr: function( name, value ) {\n\t\treturn access( this, jQuery.attr, name, value, arguments.length > 1 );\n\t},\n\n\tremoveAttr: function( name ) {\n\t\treturn this.each( function() {\n\t\t\tjQuery.removeAttr( this, name );\n\t\t} );\n\t}\n} );\n\njQuery.extend( {\n\tattr: function( elem, name, value ) {\n\t\tvar ret, hooks,\n\t\t\tnType = elem.nodeType;\n\n\t\t// Don't get/set attributes on text, comment and attribute nodes\n\t\tif ( nType === 3 || nType === 8 || nType === 2 ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Fallback to prop when attributes are not supported\n\t\tif ( typeof elem.getAttribute === \"undefined\" ) {\n\t\t\treturn jQuery.prop( elem, name, value );\n\t\t}\n\n\t\t// Attribute hooks are determined by the lowercase version\n\t\t// Grab necessary hook if one is defined\n\t\tif ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) {\n\t\t\thooks = jQuery.attrHooks[ name.toLowerCase() ] ||\n\t\t\t\t( jQuery.expr.match.bool.test( name ) ? boolHook : undefined );\n\t\t}\n\n\t\tif ( value !== undefined ) {\n\t\t\tif ( value === null ) {\n\t\t\t\tjQuery.removeAttr( elem, name );\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif ( hooks && \"set\" in hooks &&\n\t\t\t\t( ret = hooks.set( elem, value, name ) ) !== undefined ) {\n\t\t\t\treturn ret;\n\t\t\t}\n\n\t\t\telem.setAttribute( name, value + \"\" );\n\t\t\treturn value;\n\t\t}\n\n\t\tif ( hooks && \"get\" in hooks && ( ret = hooks.get( elem, name ) ) !== null ) {\n\t\t\treturn ret;\n\t\t}\n\n\t\tret = jQuery.find.attr( elem, name );\n\n\t\t// Non-existent attributes return null, we normalize to undefined\n\t\treturn ret == null ? undefined : ret;\n\t},\n\n\tattrHooks: {\n\t\ttype: {\n\t\t\tset: function( elem, value ) {\n\t\t\t\tif ( !support.radioValue && value === \"radio\" &&\n\t\t\t\t\tjQuery.nodeName( elem, \"input\" ) ) {\n\t\t\t\t\tvar val = elem.value;\n\t\t\t\t\telem.setAttribute( \"type\", value );\n\t\t\t\t\tif ( val ) {\n\t\t\t\t\t\telem.value = val;\n\t\t\t\t\t}\n\t\t\t\t\treturn value;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t},\n\n\tremoveAttr: function( elem, value ) {\n\t\tvar name,\n\t\t\ti = 0,\n\t\t\tattrNames = value && value.match( rnotwhite );\n\n\t\tif ( attrNames && elem.nodeType === 1 ) {\n\t\t\twhile ( ( name = attrNames[ i++ ] ) ) {\n\t\t\t\telem.removeAttribute( name );\n\t\t\t}\n\t\t}\n\t}\n} );\n\n// Hooks for boolean attributes\nboolHook = {\n\tset: function( elem, value, name ) {\n\t\tif ( value === false ) {\n\n\t\t\t// Remove boolean attributes when set to false\n\t\t\tjQuery.removeAttr( elem, name );\n\t\t} else {\n\t\t\telem.setAttribute( name, name );\n\t\t}\n\t\treturn name;\n\t}\n};\n\njQuery.each( jQuery.expr.match.bool.source.match( /\\w+/g ), function( i, name ) {\n\tvar getter = attrHandle[ name ] || jQuery.find.attr;\n\n\tattrHandle[ name ] = function( elem, name, isXML ) {\n\t\tvar ret, handle,\n\t\t\tlowercaseName = name.toLowerCase();\n\n\t\tif ( !isXML ) {\n\n\t\t\t// Avoid an infinite loop by temporarily removing this function from the getter\n\t\t\thandle = attrHandle[ lowercaseName ];\n\t\t\tattrHandle[ lowercaseName ] = ret;\n\t\t\tret = getter( elem, name, isXML ) != null ?\n\t\t\t\tlowercaseName :\n\t\t\t\tnull;\n\t\t\tattrHandle[ lowercaseName ] = handle;\n\t\t}\n\t\treturn ret;\n\t};\n} );\n\n\n\n\nvar rfocusable = /^(?:input|select|textarea|button)$/i,\n\trclickable = /^(?:a|area)$/i;\n\njQuery.fn.extend( {\n\tprop: function( name, value ) {\n\t\treturn access( this, jQuery.prop, name, value, arguments.length > 1 );\n\t},\n\n\tremoveProp: function( name ) {\n\t\treturn this.each( function() {\n\t\t\tdelete this[ jQuery.propFix[ name ] || name ];\n\t\t} );\n\t}\n} );\n\njQuery.extend( {\n\tprop: function( elem, name, value ) {\n\t\tvar ret, hooks,\n\t\t\tnType = elem.nodeType;\n\n\t\t// Don't get/set properties on text, comment and attribute nodes\n\t\tif ( nType === 3 || nType === 8 || nType === 2 ) {\n\t\t\treturn;\n\t\t}\n\n\t\tif ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) {\n\n\t\t\t// Fix name and attach hooks\n\t\t\tname = jQuery.propFix[ name ] || name;\n\t\t\thooks = jQuery.propHooks[ name ];\n\t\t}\n\n\t\tif ( value !== undefined ) {\n\t\t\tif ( hooks && \"set\" in hooks &&\n\t\t\t\t( ret = hooks.set( elem, value, name ) ) !== undefined ) {\n\t\t\t\treturn ret;\n\t\t\t}\n\n\t\t\treturn ( elem[ name ] = value );\n\t\t}\n\n\t\tif ( hooks && \"get\" in hooks && ( ret = hooks.get( elem, name ) ) !== null ) {\n\t\t\treturn ret;\n\t\t}\n\n\t\treturn elem[ name ];\n\t},\n\n\tpropHooks: {\n\t\ttabIndex: {\n\t\t\tget: function( elem ) {\n\n\t\t\t\t// Support: IE <=9 - 11 only\n\t\t\t\t// elem.tabIndex doesn't always return the\n\t\t\t\t// correct value when it hasn't been explicitly set\n\t\t\t\t// https://web.archive.org/web/20141116233347/http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/\n\t\t\t\t// Use proper attribute retrieval(#12072)\n\t\t\t\tvar tabindex = jQuery.find.attr( elem, \"tabindex\" );\n\n\t\t\t\treturn tabindex ?\n\t\t\t\t\tparseInt( tabindex, 10 ) :\n\t\t\t\t\trfocusable.test( elem.nodeName ) ||\n\t\t\t\t\t\trclickable.test( elem.nodeName ) && elem.href ?\n\t\t\t\t\t\t\t0 :\n\t\t\t\t\t\t\t-1;\n\t\t\t}\n\t\t}\n\t},\n\n\tpropFix: {\n\t\t\"for\": \"htmlFor\",\n\t\t\"class\": \"className\"\n\t}\n} );\n\n// Support: IE <=11 only\n// Accessing the selectedIndex property\n// forces the browser to respect setting selected\n// on the option\n// The getter ensures a default option is selected\n// when in an optgroup\nif ( !support.optSelected ) {\n\tjQuery.propHooks.selected = {\n\t\tget: function( elem ) {\n\t\t\tvar parent = elem.parentNode;\n\t\t\tif ( parent && parent.parentNode ) {\n\t\t\t\tparent.parentNode.selectedIndex;\n\t\t\t}\n\t\t\treturn null;\n\t\t},\n\t\tset: function( elem ) {\n\t\t\tvar parent = elem.parentNode;\n\t\t\tif ( parent ) {\n\t\t\t\tparent.selectedIndex;\n\n\t\t\t\tif ( parent.parentNode ) {\n\t\t\t\t\tparent.parentNode.selectedIndex;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t};\n}\n\njQuery.each( [\n\t\"tabIndex\",\n\t\"readOnly\",\n\t\"maxLength\",\n\t\"cellSpacing\",\n\t\"cellPadding\",\n\t\"rowSpan\",\n\t\"colSpan\",\n\t\"useMap\",\n\t\"frameBorder\",\n\t\"contentEditable\"\n], function() {\n\tjQuery.propFix[ this.toLowerCase() ] = this;\n} );\n\n\n\n\nvar rclass = /[\\t\\r\\n\\f]/g;\n\nfunction getClass( elem ) {\n\treturn elem.getAttribute && elem.getAttribute( \"class\" ) || \"\";\n}\n\njQuery.fn.extend( {\n\taddClass: function( value ) {\n\t\tvar classes, elem, cur, curValue, clazz, j, finalValue,\n\t\t\ti = 0;\n\n\t\tif ( jQuery.isFunction( value ) ) {\n\t\t\treturn this.each( function( j ) {\n\t\t\t\tjQuery( this ).addClass( value.call( this, j, getClass( this ) ) );\n\t\t\t} );\n\t\t}\n\n\t\tif ( typeof value === \"string\" && value ) {\n\t\t\tclasses = value.match( rnotwhite ) || [];\n\n\t\t\twhile ( ( elem = this[ i++ ] ) ) {\n\t\t\t\tcurValue = getClass( elem );\n\t\t\t\tcur = elem.nodeType === 1 &&\n\t\t\t\t\t( \" \" + curValue + \" \" ).replace( rclass, \" \" );\n\n\t\t\t\tif ( cur ) {\n\t\t\t\t\tj = 0;\n\t\t\t\t\twhile ( ( clazz = classes[ j++ ] ) ) {\n\t\t\t\t\t\tif ( cur.indexOf( \" \" + clazz + \" \" ) < 0 ) {\n\t\t\t\t\t\t\tcur += clazz + \" \";\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\t// Only assign if different to avoid unneeded rendering.\n\t\t\t\t\tfinalValue = jQuery.trim( cur );\n\t\t\t\t\tif ( curValue !== finalValue ) {\n\t\t\t\t\t\telem.setAttribute( \"class\", finalValue );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn this;\n\t},\n\n\tremoveClass: function( value ) {\n\t\tvar classes, elem, cur, curValue, clazz, j, finalValue,\n\t\t\ti = 0;\n\n\t\tif ( jQuery.isFunction( value ) ) {\n\t\t\treturn this.each( function( j ) {\n\t\t\t\tjQuery( this ).removeClass( value.call( this, j, getClass( this ) ) );\n\t\t\t} );\n\t\t}\n\n\t\tif ( !arguments.length ) {\n\t\t\treturn this.attr( \"class\", \"\" );\n\t\t}\n\n\t\tif ( typeof value === \"string\" && value ) {\n\t\t\tclasses = value.match( rnotwhite ) || [];\n\n\t\t\twhile ( ( elem = this[ i++ ] ) ) {\n\t\t\t\tcurValue = getClass( elem );\n\n\t\t\t\t// This expression is here for better compressibility (see addClass)\n\t\t\t\tcur = elem.nodeType === 1 &&\n\t\t\t\t\t( \" \" + curValue + \" \" ).replace( rclass, \" \" );\n\n\t\t\t\tif ( cur ) {\n\t\t\t\t\tj = 0;\n\t\t\t\t\twhile ( ( clazz = classes[ j++ ] ) ) {\n\n\t\t\t\t\t\t// Remove *all* instances\n\t\t\t\t\t\twhile ( cur.indexOf( \" \" + clazz + \" \" ) > -1 ) {\n\t\t\t\t\t\t\tcur = cur.replace( \" \" + clazz + \" \", \" \" );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\t// Only assign if different to avoid unneeded rendering.\n\t\t\t\t\tfinalValue = jQuery.trim( cur );\n\t\t\t\t\tif ( curValue !== finalValue ) {\n\t\t\t\t\t\telem.setAttribute( \"class\", finalValue );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn this;\n\t},\n\n\ttoggleClass: function( value, stateVal ) {\n\t\tvar type = typeof value;\n\n\t\tif ( typeof stateVal === \"boolean\" && type === \"string\" ) {\n\t\t\treturn stateVal ? this.addClass( value ) : this.removeClass( value );\n\t\t}\n\n\t\tif ( jQuery.isFunction( value ) ) {\n\t\t\treturn this.each( function( i ) {\n\t\t\t\tjQuery( this ).toggleClass(\n\t\t\t\t\tvalue.call( this, i, getClass( this ), stateVal ),\n\t\t\t\t\tstateVal\n\t\t\t\t);\n\t\t\t} );\n\t\t}\n\n\t\treturn this.each( function() {\n\t\t\tvar className, i, self, classNames;\n\n\t\t\tif ( type === \"string\" ) {\n\n\t\t\t\t// Toggle individual class names\n\t\t\t\ti = 0;\n\t\t\t\tself = jQuery( this );\n\t\t\t\tclassNames = value.match( rnotwhite ) || [];\n\n\t\t\t\twhile ( ( className = classNames[ i++ ] ) ) {\n\n\t\t\t\t\t// Check each className given, space separated list\n\t\t\t\t\tif ( self.hasClass( className ) ) {\n\t\t\t\t\t\tself.removeClass( className );\n\t\t\t\t\t} else {\n\t\t\t\t\t\tself.addClass( className );\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t// Toggle whole class name\n\t\t\t} else if ( value === undefined || type === \"boolean\" ) {\n\t\t\t\tclassName = getClass( this );\n\t\t\t\tif ( className ) {\n\n\t\t\t\t\t// Store className if set\n\t\t\t\t\tdataPriv.set( this, \"__className__\", className );\n\t\t\t\t}\n\n\t\t\t\t// If the element has a class name or if we're passed `false`,\n\t\t\t\t// then remove the whole classname (if there was one, the above saved it).\n\t\t\t\t// Otherwise bring back whatever was previously saved (if anything),\n\t\t\t\t// falling back to the empty string if nothing was stored.\n\t\t\t\tif ( this.setAttribute ) {\n\t\t\t\t\tthis.setAttribute( \"class\",\n\t\t\t\t\t\tclassName || value === false ?\n\t\t\t\t\t\t\"\" :\n\t\t\t\t\t\tdataPriv.get( this, \"__className__\" ) || \"\"\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t}\n\t\t} );\n\t},\n\n\thasClass: function( selector ) {\n\t\tvar className, elem,\n\t\t\ti = 0;\n\n\t\tclassName = \" \" + selector + \" \";\n\t\twhile ( ( elem = this[ i++ ] ) ) {\n\t\t\tif ( elem.nodeType === 1 &&\n\t\t\t\t( \" \" + getClass( elem ) + \" \" ).replace( rclass, \" \" )\n\t\t\t\t\t.indexOf( className ) > -1\n\t\t\t) {\n\t\t\t\treturn true;\n\t\t\t}\n\t\t}\n\n\t\treturn false;\n\t}\n} );\n\n\n\n\nvar rreturn = /\\r/g,\n\trspaces = /[\\x20\\t\\r\\n\\f]+/g;\n\njQuery.fn.extend( {\n\tval: function( value ) {\n\t\tvar hooks, ret, isFunction,\n\t\t\telem = this[ 0 ];\n\n\t\tif ( !arguments.length ) {\n\t\t\tif ( elem ) {\n\t\t\t\thooks = jQuery.valHooks[ elem.type ] ||\n\t\t\t\t\tjQuery.valHooks[ elem.nodeName.toLowerCase() ];\n\n\t\t\t\tif ( hooks &&\n\t\t\t\t\t\"get\" in hooks &&\n\t\t\t\t\t( ret = hooks.get( elem, \"value\" ) ) !== undefined\n\t\t\t\t) {\n\t\t\t\t\treturn ret;\n\t\t\t\t}\n\n\t\t\t\tret = elem.value;\n\n\t\t\t\treturn typeof ret === \"string\" ?\n\n\t\t\t\t\t// Handle most common string cases\n\t\t\t\t\tret.replace( rreturn, \"\" ) :\n\n\t\t\t\t\t// Handle cases where value is null/undef or number\n\t\t\t\t\tret == null ? \"\" : ret;\n\t\t\t}\n\n\t\t\treturn;\n\t\t}\n\n\t\tisFunction = jQuery.isFunction( value );\n\n\t\treturn this.each( function( i ) {\n\t\t\tvar val;\n\n\t\t\tif ( this.nodeType !== 1 ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif ( isFunction ) {\n\t\t\t\tval = value.call( this, i, jQuery( this ).val() );\n\t\t\t} else {\n\t\t\t\tval = value;\n\t\t\t}\n\n\t\t\t// Treat null/undefined as \"\"; convert numbers to string\n\t\t\tif ( val == null ) {\n\t\t\t\tval = \"\";\n\n\t\t\t} else if ( typeof val === \"number\" ) {\n\t\t\t\tval += \"\";\n\n\t\t\t} else if ( jQuery.isArray( val ) ) {\n\t\t\t\tval = jQuery.map( val, function( value ) {\n\t\t\t\t\treturn value == null ? \"\" : value + \"\";\n\t\t\t\t} );\n\t\t\t}\n\n\t\t\thooks = jQuery.valHooks[ this.type ] || jQuery.valHooks[ this.nodeName.toLowerCase() ];\n\n\t\t\t// If set returns undefined, fall back to normal setting\n\t\t\tif ( !hooks || !( \"set\" in hooks ) || hooks.set( this, val, \"value\" ) === undefined ) {\n\t\t\t\tthis.value = val;\n\t\t\t}\n\t\t} );\n\t}\n} );\n\njQuery.extend( {\n\tvalHooks: {\n\t\toption: {\n\t\t\tget: function( elem ) {\n\n\t\t\t\tvar val = jQuery.find.attr( elem, \"value\" );\n\t\t\t\treturn val != null ?\n\t\t\t\t\tval :\n\n\t\t\t\t\t// Support: IE <=10 - 11 only\n\t\t\t\t\t// option.text throws exceptions (#14686, #14858)\n\t\t\t\t\t// Strip and collapse whitespace\n\t\t\t\t\t// https://html.spec.whatwg.org/#strip-and-collapse-whitespace\n\t\t\t\t\tjQuery.trim( jQuery.text( elem ) ).replace( rspaces, \" \" );\n\t\t\t}\n\t\t},\n\t\tselect: {\n\t\t\tget: function( elem ) {\n\t\t\t\tvar value, option,\n\t\t\t\t\toptions = elem.options,\n\t\t\t\t\tindex = elem.selectedIndex,\n\t\t\t\t\tone = elem.type === \"select-one\",\n\t\t\t\t\tvalues = one ? null : [],\n\t\t\t\t\tmax = one ? index + 1 : options.length,\n\t\t\t\t\ti = index < 0 ?\n\t\t\t\t\t\tmax :\n\t\t\t\t\t\tone ? index : 0;\n\n\t\t\t\t// Loop through all the selected options\n\t\t\t\tfor ( ; i < max; i++ ) {\n\t\t\t\t\toption = options[ i ];\n\n\t\t\t\t\t// Support: IE <=9 only\n\t\t\t\t\t// IE8-9 doesn't update selected after form reset (#2551)\n\t\t\t\t\tif ( ( option.selected || i === index ) &&\n\n\t\t\t\t\t\t\t// Don't return options that are disabled or in a disabled optgroup\n\t\t\t\t\t\t\t!option.disabled &&\n\t\t\t\t\t\t\t( !option.parentNode.disabled ||\n\t\t\t\t\t\t\t\t!jQuery.nodeName( option.parentNode, \"optgroup\" ) ) ) {\n\n\t\t\t\t\t\t// Get the specific value for the option\n\t\t\t\t\t\tvalue = jQuery( option ).val();\n\n\t\t\t\t\t\t// We don't need an array for one selects\n\t\t\t\t\t\tif ( one ) {\n\t\t\t\t\t\t\treturn value;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// Multi-Selects return an array\n\t\t\t\t\t\tvalues.push( value );\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\treturn values;\n\t\t\t},\n\n\t\t\tset: function( elem, value ) {\n\t\t\t\tvar optionSet, option,\n\t\t\t\t\toptions = elem.options,\n\t\t\t\t\tvalues = jQuery.makeArray( value ),\n\t\t\t\t\ti = options.length;\n\n\t\t\t\twhile ( i-- ) {\n\t\t\t\t\toption = options[ i ];\n\n\t\t\t\t\t/* eslint-disable no-cond-assign */\n\n\t\t\t\t\tif ( option.selected =\n\t\t\t\t\t\tjQuery.inArray( jQuery.valHooks.option.get( option ), values ) > -1\n\t\t\t\t\t) {\n\t\t\t\t\t\toptionSet = true;\n\t\t\t\t\t}\n\n\t\t\t\t\t/* eslint-enable no-cond-assign */\n\t\t\t\t}\n\n\t\t\t\t// Force browsers to behave consistently when non-matching value is set\n\t\t\t\tif ( !optionSet ) {\n\t\t\t\t\telem.selectedIndex = -1;\n\t\t\t\t}\n\t\t\t\treturn values;\n\t\t\t}\n\t\t}\n\t}\n} );\n\n// Radios and checkboxes getter/setter\njQuery.each( [ \"radio\", \"checkbox\" ], function() {\n\tjQuery.valHooks[ this ] = {\n\t\tset: function( elem, value ) {\n\t\t\tif ( jQuery.isArray( value ) ) {\n\t\t\t\treturn ( elem.checked = jQuery.inArray( jQuery( elem ).val(), value ) > -1 );\n\t\t\t}\n\t\t}\n\t};\n\tif ( !support.checkOn ) {\n\t\tjQuery.valHooks[ this ].get = function( elem ) {\n\t\t\treturn elem.getAttribute( \"value\" ) === null ? \"on\" : elem.value;\n\t\t};\n\t}\n} );\n\n\n\n\n// Return jQuery for attributes-only inclusion\n\n\nvar rfocusMorph = /^(?:focusinfocus|focusoutblur)$/;\n\njQuery.extend( jQuery.event, {\n\n\ttrigger: function( event, data, elem, onlyHandlers ) {\n\n\t\tvar i, cur, tmp, bubbleType, ontype, handle, special,\n\t\t\teventPath = [ elem || document ],\n\t\t\ttype = hasOwn.call( event, \"type\" ) ? event.type : event,\n\t\t\tnamespaces = hasOwn.call( event, \"namespace\" ) ? event.namespace.split( \".\" ) : [];\n\n\t\tcur = tmp = elem = elem || document;\n\n\t\t// Don't do events on text and comment nodes\n\t\tif ( elem.nodeType === 3 || elem.nodeType === 8 ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// focus/blur morphs to focusin/out; ensure we're not firing them right now\n\t\tif ( rfocusMorph.test( type + jQuery.event.triggered ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\tif ( type.indexOf( \".\" ) > -1 ) {\n\n\t\t\t// Namespaced trigger; create a regexp to match event type in handle()\n\t\t\tnamespaces = type.split( \".\" );\n\t\t\ttype = namespaces.shift();\n\t\t\tnamespaces.sort();\n\t\t}\n\t\tontype = type.indexOf( \":\" ) < 0 && \"on\" + type;\n\n\t\t// Caller can pass in a jQuery.Event object, Object, or just an event type string\n\t\tevent = event[ jQuery.expando ] ?\n\t\t\tevent :\n\t\t\tnew jQuery.Event( type, typeof event === \"object\" && event );\n\n\t\t// Trigger bitmask: & 1 for native handlers; & 2 for jQuery (always true)\n\t\tevent.isTrigger = onlyHandlers ? 2 : 3;\n\t\tevent.namespace = namespaces.join( \".\" );\n\t\tevent.rnamespace = event.namespace ?\n\t\t\tnew RegExp( \"(^|\\\\.)\" + namespaces.join( \"\\\\.(?:.*\\\\.|)\" ) + \"(\\\\.|$)\" ) :\n\t\t\tnull;\n\n\t\t// Clean up the event in case it is being reused\n\t\tevent.result = undefined;\n\t\tif ( !event.target ) {\n\t\t\tevent.target = elem;\n\t\t}\n\n\t\t// Clone any incoming data and prepend the event, creating the handler arg list\n\t\tdata = data == null ?\n\t\t\t[ event ] :\n\t\t\tjQuery.makeArray( data, [ event ] );\n\n\t\t// Allow special events to draw outside the lines\n\t\tspecial = jQuery.event.special[ type ] || {};\n\t\tif ( !onlyHandlers && special.trigger && special.trigger.apply( elem, data ) === false ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Determine event propagation path in advance, per W3C events spec (#9951)\n\t\t// Bubble up to document, then to window; watch for a global ownerDocument var (#9724)\n\t\tif ( !onlyHandlers && !special.noBubble && !jQuery.isWindow( elem ) ) {\n\n\t\t\tbubbleType = special.delegateType || type;\n\t\t\tif ( !rfocusMorph.test( bubbleType + type ) ) {\n\t\t\t\tcur = cur.parentNode;\n\t\t\t}\n\t\t\tfor ( ; cur; cur = cur.parentNode ) {\n\t\t\t\teventPath.push( cur );\n\t\t\t\ttmp = cur;\n\t\t\t}\n\n\t\t\t// Only add window if we got to document (e.g., not plain obj or detached DOM)\n\t\t\tif ( tmp === ( elem.ownerDocument || document ) ) {\n\t\t\t\teventPath.push( tmp.defaultView || tmp.parentWindow || window );\n\t\t\t}\n\t\t}\n\n\t\t// Fire handlers on the event path\n\t\ti = 0;\n\t\twhile ( ( cur = eventPath[ i++ ] ) && !event.isPropagationStopped() ) {\n\n\t\t\tevent.type = i > 1 ?\n\t\t\t\tbubbleType :\n\t\t\t\tspecial.bindType || type;\n\n\t\t\t// jQuery handler\n\t\t\thandle = ( dataPriv.get( cur, \"events\" ) || {} )[ event.type ] &&\n\t\t\t\tdataPriv.get( cur, \"handle\" );\n\t\t\tif ( handle ) {\n\t\t\t\thandle.apply( cur, data );\n\t\t\t}\n\n\t\t\t// Native handler\n\t\t\thandle = ontype && cur[ ontype ];\n\t\t\tif ( handle && handle.apply && acceptData( cur ) ) {\n\t\t\t\tevent.result = handle.apply( cur, data );\n\t\t\t\tif ( event.result === false ) {\n\t\t\t\t\tevent.preventDefault();\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tevent.type = type;\n\n\t\t// If nobody prevented the default action, do it now\n\t\tif ( !onlyHandlers && !event.isDefaultPrevented() ) {\n\n\t\t\tif ( ( !special._default ||\n\t\t\t\tspecial._default.apply( eventPath.pop(), data ) === false ) &&\n\t\t\t\tacceptData( elem ) ) {\n\n\t\t\t\t// Call a native DOM method on the target with the same name as the event.\n\t\t\t\t// Don't do default actions on window, that's where global variables be (#6170)\n\t\t\t\tif ( ontype && jQuery.isFunction( elem[ type ] ) && !jQuery.isWindow( elem ) ) {\n\n\t\t\t\t\t// Don't re-trigger an onFOO event when we call its FOO() method\n\t\t\t\t\ttmp = elem[ ontype ];\n\n\t\t\t\t\tif ( tmp ) {\n\t\t\t\t\t\telem[ ontype ] = null;\n\t\t\t\t\t}\n\n\t\t\t\t\t// Prevent re-triggering of the same event, since we already bubbled it above\n\t\t\t\t\tjQuery.event.triggered = type;\n\t\t\t\t\telem[ type ]();\n\t\t\t\t\tjQuery.event.triggered = undefined;\n\n\t\t\t\t\tif ( tmp ) {\n\t\t\t\t\t\telem[ ontype ] = tmp;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn event.result;\n\t},\n\n\t// Piggyback on a donor event to simulate a different one\n\t// Used only for `focus(in | out)` events\n\tsimulate: function( type, elem, event ) {\n\t\tvar e = jQuery.extend(\n\t\t\tnew jQuery.Event(),\n\t\t\tevent,\n\t\t\t{\n\t\t\t\ttype: type,\n\t\t\t\tisSimulated: true\n\t\t\t}\n\t\t);\n\n\t\tjQuery.event.trigger( e, null, elem );\n\t}\n\n} );\n\njQuery.fn.extend( {\n\n\ttrigger: function( type, data ) {\n\t\treturn this.each( function() {\n\t\t\tjQuery.event.trigger( type, data, this );\n\t\t} );\n\t},\n\ttriggerHandler: function( type, data ) {\n\t\tvar elem = this[ 0 ];\n\t\tif ( elem ) {\n\t\t\treturn jQuery.event.trigger( type, data, elem, true );\n\t\t}\n\t}\n} );\n\n\njQuery.each( ( \"blur focus focusin focusout resize scroll click dblclick \" +\n\t\"mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave \" +\n\t\"change select submit keydown keypress keyup contextmenu\" ).split( \" \" ),\n\tfunction( i, name ) {\n\n\t// Handle event binding\n\tjQuery.fn[ name ] = function( data, fn ) {\n\t\treturn arguments.length > 0 ?\n\t\t\tthis.on( name, null, data, fn ) :\n\t\t\tthis.trigger( name );\n\t};\n} );\n\njQuery.fn.extend( {\n\thover: function( fnOver, fnOut ) {\n\t\treturn this.mouseenter( fnOver ).mouseleave( fnOut || fnOver );\n\t}\n} );\n\n\n\n\nsupport.focusin = \"onfocusin\" in window;\n\n\n// Support: Firefox <=44\n// Firefox doesn't have focus(in | out) events\n// Related ticket - https://bugzilla.mozilla.org/show_bug.cgi?id=687787\n//\n// Support: Chrome <=48 - 49, Safari <=9.0 - 9.1\n// focus(in | out) events fire after focus & blur events,\n// which is spec violation - http://www.w3.org/TR/DOM-Level-3-Events/#events-focusevent-event-order\n// Related ticket - https://bugs.chromium.org/p/chromium/issues/detail?id=449857\nif ( !support.focusin ) {\n\tjQuery.each( { focus: \"focusin\", blur: \"focusout\" }, function( orig, fix ) {\n\n\t\t// Attach a single capturing handler on the document while someone wants focusin/focusout\n\t\tvar handler = function( event ) {\n\t\t\tjQuery.event.simulate( fix, event.target, jQuery.event.fix( event ) );\n\t\t};\n\n\t\tjQuery.event.special[ fix ] = {\n\t\t\tsetup: function() {\n\t\t\t\tvar doc = this.ownerDocument || this,\n\t\t\t\t\tattaches = dataPriv.access( doc, fix );\n\n\t\t\t\tif ( !attaches ) {\n\t\t\t\t\tdoc.addEventListener( orig, handler, true );\n\t\t\t\t}\n\t\t\t\tdataPriv.access( doc, fix, ( attaches || 0 ) + 1 );\n\t\t\t},\n\t\t\tteardown: function() {\n\t\t\t\tvar doc = this.ownerDocument || this,\n\t\t\t\t\tattaches = dataPriv.access( doc, fix ) - 1;\n\n\t\t\t\tif ( !attaches ) {\n\t\t\t\t\tdoc.removeEventListener( orig, handler, true );\n\t\t\t\t\tdataPriv.remove( doc, fix );\n\n\t\t\t\t} else {\n\t\t\t\t\tdataPriv.access( doc, fix, attaches );\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\t} );\n}\nvar location = window.location;\n\nvar nonce = jQuery.now();\n\nvar rquery = ( /\\?/ );\n\n\n\n// Cross-browser xml parsing\njQuery.parseXML = function( data ) {\n\tvar xml;\n\tif ( !data || typeof data !== \"string\" ) {\n\t\treturn null;\n\t}\n\n\t// Support: IE 9 - 11 only\n\t// IE throws on parseFromString with invalid input.\n\ttry {\n\t\txml = ( new window.DOMParser() ).parseFromString( data, \"text/xml\" );\n\t} catch ( e ) {\n\t\txml = undefined;\n\t}\n\n\tif ( !xml || xml.getElementsByTagName( \"parsererror\" ).length ) {\n\t\tjQuery.error( \"Invalid XML: \" + data );\n\t}\n\treturn xml;\n};\n\n\nvar\n\trbracket = /\\[\\]$/,\n\trCRLF = /\\r?\\n/g,\n\trsubmitterTypes = /^(?:submit|button|image|reset|file)$/i,\n\trsubmittable = /^(?:input|select|textarea|keygen)/i;\n\nfunction buildParams( prefix, obj, traditional, add ) {\n\tvar name;\n\n\tif ( jQuery.isArray( obj ) ) {\n\n\t\t// Serialize array item.\n\t\tjQuery.each( obj, function( i, v ) {\n\t\t\tif ( traditional || rbracket.test( prefix ) ) {\n\n\t\t\t\t// Treat each array item as a scalar.\n\t\t\t\tadd( prefix, v );\n\n\t\t\t} else {\n\n\t\t\t\t// Item is non-scalar (array or object), encode its numeric index.\n\t\t\t\tbuildParams(\n\t\t\t\t\tprefix + \"[\" + ( typeof v === \"object\" && v != null ? i : \"\" ) + \"]\",\n\t\t\t\t\tv,\n\t\t\t\t\ttraditional,\n\t\t\t\t\tadd\n\t\t\t\t);\n\t\t\t}\n\t\t} );\n\n\t} else if ( !traditional && jQuery.type( obj ) === \"object\" ) {\n\n\t\t// Serialize object item.\n\t\tfor ( name in obj ) {\n\t\t\tbuildParams( prefix + \"[\" + name + \"]\", obj[ name ], traditional, add );\n\t\t}\n\n\t} else {\n\n\t\t// Serialize scalar item.\n\t\tadd( prefix, obj );\n\t}\n}\n\n// Serialize an array of form elements or a set of\n// key/values into a query string\njQuery.param = function( a, traditional ) {\n\tvar prefix,\n\t\ts = [],\n\t\tadd = function( key, valueOrFunction ) {\n\n\t\t\t// If value is a function, invoke it and use its return value\n\t\t\tvar value = jQuery.isFunction( valueOrFunction ) ?\n\t\t\t\tvalueOrFunction() :\n\t\t\t\tvalueOrFunction;\n\n\t\t\ts[ s.length ] = encodeURIComponent( key ) + \"=\" +\n\t\t\t\tencodeURIComponent( value == null ? \"\" : value );\n\t\t};\n\n\t// If an array was passed in, assume that it is an array of form elements.\n\tif ( jQuery.isArray( a ) || ( a.jquery && !jQuery.isPlainObject( a ) ) ) {\n\n\t\t// Serialize the form elements\n\t\tjQuery.each( a, function() {\n\t\t\tadd( this.name, this.value );\n\t\t} );\n\n\t} else {\n\n\t\t// If traditional, encode the \"old\" way (the way 1.3.2 or older\n\t\t// did it), otherwise encode params recursively.\n\t\tfor ( prefix in a ) {\n\t\t\tbuildParams( prefix, a[ prefix ], traditional, add );\n\t\t}\n\t}\n\n\t// Return the resulting serialization\n\treturn s.join( \"&\" );\n};\n\njQuery.fn.extend( {\n\tserialize: function() {\n\t\treturn jQuery.param( this.serializeArray() );\n\t},\n\tserializeArray: function() {\n\t\treturn this.map( function() {\n\n\t\t\t// Can add propHook for \"elements\" to filter or add form elements\n\t\t\tvar elements = jQuery.prop( this, \"elements\" );\n\t\t\treturn elements ? jQuery.makeArray( elements ) : this;\n\t\t} )\n\t\t.filter( function() {\n\t\t\tvar type = this.type;\n\n\t\t\t// Use .is( \":disabled\" ) so that fieldset[disabled] works\n\t\t\treturn this.name && !jQuery( this ).is( \":disabled\" ) &&\n\t\t\t\trsubmittable.test( this.nodeName ) && !rsubmitterTypes.test( type ) &&\n\t\t\t\t( this.checked || !rcheckableType.test( type ) );\n\t\t} )\n\t\t.map( function( i, elem ) {\n\t\t\tvar val = jQuery( this ).val();\n\n\t\t\treturn val == null ?\n\t\t\t\tnull :\n\t\t\t\tjQuery.isArray( val ) ?\n\t\t\t\t\tjQuery.map( val, function( val ) {\n\t\t\t\t\t\treturn { name: elem.name, value: val.replace( rCRLF, \"\\r\\n\" ) };\n\t\t\t\t\t} ) :\n\t\t\t\t\t{ name: elem.name, value: val.replace( rCRLF, \"\\r\\n\" ) };\n\t\t} ).get();\n\t}\n} );\n\n\nvar\n\tr20 = /%20/g,\n\trhash = /#.*$/,\n\trts = /([?&])_=[^&]*/,\n\trheaders = /^(.*?):[ \\t]*([^\\r\\n]*)$/mg,\n\n\t// #7653, #8125, #8152: local protocol detection\n\trlocalProtocol = /^(?:about|app|app-storage|.+-extension|file|res|widget):$/,\n\trnoContent = /^(?:GET|HEAD)$/,\n\trprotocol = /^\\/\\//,\n\n\t/* Prefilters\n\t * 1) They are useful to introduce custom dataTypes (see ajax/jsonp.js for an example)\n\t * 2) These are called:\n\t *    - BEFORE asking for a transport\n\t *    - AFTER param serialization (s.data is a string if s.processData is true)\n\t * 3) key is the dataType\n\t * 4) the catchall symbol \"*\" can be used\n\t * 5) execution will start with transport dataType and THEN continue down to \"*\" if needed\n\t */\n\tprefilters = {},\n\n\t/* Transports bindings\n\t * 1) key is the dataType\n\t * 2) the catchall symbol \"*\" can be used\n\t * 3) selection will start with transport dataType and THEN go to \"*\" if needed\n\t */\n\ttransports = {},\n\n\t// Avoid comment-prolog char sequence (#10098); must appease lint and evade compression\n\tallTypes = \"*/\".concat( \"*\" ),\n\n\t// Anchor tag for parsing the document origin\n\toriginAnchor = document.createElement( \"a\" );\n\toriginAnchor.href = location.href;\n\n// Base \"constructor\" for jQuery.ajaxPrefilter and jQuery.ajaxTransport\nfunction addToPrefiltersOrTransports( structure ) {\n\n\t// dataTypeExpression is optional and defaults to \"*\"\n\treturn function( dataTypeExpression, func ) {\n\n\t\tif ( typeof dataTypeExpression !== \"string\" ) {\n\t\t\tfunc = dataTypeExpression;\n\t\t\tdataTypeExpression = \"*\";\n\t\t}\n\n\t\tvar dataType,\n\t\t\ti = 0,\n\t\t\tdataTypes = dataTypeExpression.toLowerCase().match( rnotwhite ) || [];\n\n\t\tif ( jQuery.isFunction( func ) ) {\n\n\t\t\t// For each dataType in the dataTypeExpression\n\t\t\twhile ( ( dataType = dataTypes[ i++ ] ) ) {\n\n\t\t\t\t// Prepend if requested\n\t\t\t\tif ( dataType[ 0 ] === \"+\" ) {\n\t\t\t\t\tdataType = dataType.slice( 1 ) || \"*\";\n\t\t\t\t\t( structure[ dataType ] = structure[ dataType ] || [] ).unshift( func );\n\n\t\t\t\t// Otherwise append\n\t\t\t\t} else {\n\t\t\t\t\t( structure[ dataType ] = structure[ dataType ] || [] ).push( func );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t};\n}\n\n// Base inspection function for prefilters and transports\nfunction inspectPrefiltersOrTransports( structure, options, originalOptions, jqXHR ) {\n\n\tvar inspected = {},\n\t\tseekingTransport = ( structure === transports );\n\n\tfunction inspect( dataType ) {\n\t\tvar selected;\n\t\tinspected[ dataType ] = true;\n\t\tjQuery.each( structure[ dataType ] || [], function( _, prefilterOrFactory ) {\n\t\t\tvar dataTypeOrTransport = prefilterOrFactory( options, originalOptions, jqXHR );\n\t\t\tif ( typeof dataTypeOrTransport === \"string\" &&\n\t\t\t\t!seekingTransport && !inspected[ dataTypeOrTransport ] ) {\n\n\t\t\t\toptions.dataTypes.unshift( dataTypeOrTransport );\n\t\t\t\tinspect( dataTypeOrTransport );\n\t\t\t\treturn false;\n\t\t\t} else if ( seekingTransport ) {\n\t\t\t\treturn !( selected = dataTypeOrTransport );\n\t\t\t}\n\t\t} );\n\t\treturn selected;\n\t}\n\n\treturn inspect( options.dataTypes[ 0 ] ) || !inspected[ \"*\" ] && inspect( \"*\" );\n}\n\n// A special extend for ajax options\n// that takes \"flat\" options (not to be deep extended)\n// Fixes #9887\nfunction ajaxExtend( target, src ) {\n\tvar key, deep,\n\t\tflatOptions = jQuery.ajaxSettings.flatOptions || {};\n\n\tfor ( key in src ) {\n\t\tif ( src[ key ] !== undefined ) {\n\t\t\t( flatOptions[ key ] ? target : ( deep || ( deep = {} ) ) )[ key ] = src[ key ];\n\t\t}\n\t}\n\tif ( deep ) {\n\t\tjQuery.extend( true, target, deep );\n\t}\n\n\treturn target;\n}\n\n/* Handles responses to an ajax request:\n * - finds the right dataType (mediates between content-type and expected dataType)\n * - returns the corresponding response\n */\nfunction ajaxHandleResponses( s, jqXHR, responses ) {\n\n\tvar ct, type, finalDataType, firstDataType,\n\t\tcontents = s.contents,\n\t\tdataTypes = s.dataTypes;\n\n\t// Remove auto dataType and get content-type in the process\n\twhile ( dataTypes[ 0 ] === \"*\" ) {\n\t\tdataTypes.shift();\n\t\tif ( ct === undefined ) {\n\t\t\tct = s.mimeType || jqXHR.getResponseHeader( \"Content-Type\" );\n\t\t}\n\t}\n\n\t// Check if we're dealing with a known content-type\n\tif ( ct ) {\n\t\tfor ( type in contents ) {\n\t\t\tif ( contents[ type ] && contents[ type ].test( ct ) ) {\n\t\t\t\tdataTypes.unshift( type );\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t}\n\n\t// Check to see if we have a response for the expected dataType\n\tif ( dataTypes[ 0 ] in responses ) {\n\t\tfinalDataType = dataTypes[ 0 ];\n\t} else {\n\n\t\t// Try convertible dataTypes\n\t\tfor ( type in responses ) {\n\t\t\tif ( !dataTypes[ 0 ] || s.converters[ type + \" \" + dataTypes[ 0 ] ] ) {\n\t\t\t\tfinalDataType = type;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tif ( !firstDataType ) {\n\t\t\t\tfirstDataType = type;\n\t\t\t}\n\t\t}\n\n\t\t// Or just use first one\n\t\tfinalDataType = finalDataType || firstDataType;\n\t}\n\n\t// If we found a dataType\n\t// We add the dataType to the list if needed\n\t// and return the corresponding response\n\tif ( finalDataType ) {\n\t\tif ( finalDataType !== dataTypes[ 0 ] ) {\n\t\t\tdataTypes.unshift( finalDataType );\n\t\t}\n\t\treturn responses[ finalDataType ];\n\t}\n}\n\n/* Chain conversions given the request and the original response\n * Also sets the responseXXX fields on the jqXHR instance\n */\nfunction ajaxConvert( s, response, jqXHR, isSuccess ) {\n\tvar conv2, current, conv, tmp, prev,\n\t\tconverters = {},\n\n\t\t// Work with a copy of dataTypes in case we need to modify it for conversion\n\t\tdataTypes = s.dataTypes.slice();\n\n\t// Create converters map with lowercased keys\n\tif ( dataTypes[ 1 ] ) {\n\t\tfor ( conv in s.converters ) {\n\t\t\tconverters[ conv.toLowerCase() ] = s.converters[ conv ];\n\t\t}\n\t}\n\n\tcurrent = dataTypes.shift();\n\n\t// Convert to each sequential dataType\n\twhile ( current ) {\n\n\t\tif ( s.responseFields[ current ] ) {\n\t\t\tjqXHR[ s.responseFields[ current ] ] = response;\n\t\t}\n\n\t\t// Apply the dataFilter if provided\n\t\tif ( !prev && isSuccess && s.dataFilter ) {\n\t\t\tresponse = s.dataFilter( response, s.dataType );\n\t\t}\n\n\t\tprev = current;\n\t\tcurrent = dataTypes.shift();\n\n\t\tif ( current ) {\n\n\t\t\t// There's only work to do if current dataType is non-auto\n\t\t\tif ( current === \"*\" ) {\n\n\t\t\t\tcurrent = prev;\n\n\t\t\t// Convert response if prev dataType is non-auto and differs from current\n\t\t\t} else if ( prev !== \"*\" && prev !== current ) {\n\n\t\t\t\t// Seek a direct converter\n\t\t\t\tconv = converters[ prev + \" \" + current ] || converters[ \"* \" + current ];\n\n\t\t\t\t// If none found, seek a pair\n\t\t\t\tif ( !conv ) {\n\t\t\t\t\tfor ( conv2 in converters ) {\n\n\t\t\t\t\t\t// If conv2 outputs current\n\t\t\t\t\t\ttmp = conv2.split( \" \" );\n\t\t\t\t\t\tif ( tmp[ 1 ] === current ) {\n\n\t\t\t\t\t\t\t// If prev can be converted to accepted input\n\t\t\t\t\t\t\tconv = converters[ prev + \" \" + tmp[ 0 ] ] ||\n\t\t\t\t\t\t\t\tconverters[ \"* \" + tmp[ 0 ] ];\n\t\t\t\t\t\t\tif ( conv ) {\n\n\t\t\t\t\t\t\t\t// Condense equivalence converters\n\t\t\t\t\t\t\t\tif ( conv === true ) {\n\t\t\t\t\t\t\t\t\tconv = converters[ conv2 ];\n\n\t\t\t\t\t\t\t\t// Otherwise, insert the intermediate dataType\n\t\t\t\t\t\t\t\t} else if ( converters[ conv2 ] !== true ) {\n\t\t\t\t\t\t\t\t\tcurrent = tmp[ 0 ];\n\t\t\t\t\t\t\t\t\tdataTypes.unshift( tmp[ 1 ] );\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// Apply converter (if not an equivalence)\n\t\t\t\tif ( conv !== true ) {\n\n\t\t\t\t\t// Unless errors are allowed to bubble, catch and return them\n\t\t\t\t\tif ( conv && s.throws ) {\n\t\t\t\t\t\tresponse = conv( response );\n\t\t\t\t\t} else {\n\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\tresponse = conv( response );\n\t\t\t\t\t\t} catch ( e ) {\n\t\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\t\tstate: \"parsererror\",\n\t\t\t\t\t\t\t\terror: conv ? e : \"No conversion from \" + prev + \" to \" + current\n\t\t\t\t\t\t\t};\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\treturn { state: \"success\", data: response };\n}\n\njQuery.extend( {\n\n\t// Counter for holding the number of active queries\n\tactive: 0,\n\n\t// Last-Modified header cache for next request\n\tlastModified: {},\n\tetag: {},\n\n\tajaxSettings: {\n\t\turl: location.href,\n\t\ttype: \"GET\",\n\t\tisLocal: rlocalProtocol.test( location.protocol ),\n\t\tglobal: true,\n\t\tprocessData: true,\n\t\tasync: true,\n\t\tcontentType: \"application/x-www-form-urlencoded; charset=UTF-8\",\n\n\t\t/*\n\t\ttimeout: 0,\n\t\tdata: null,\n\t\tdataType: null,\n\t\tusername: null,\n\t\tpassword: null,\n\t\tcache: null,\n\t\tthrows: false,\n\t\ttraditional: false,\n\t\theaders: {},\n\t\t*/\n\n\t\taccepts: {\n\t\t\t\"*\": allTypes,\n\t\t\ttext: \"text/plain\",\n\t\t\thtml: \"text/html\",\n\t\t\txml: \"application/xml, text/xml\",\n\t\t\tjson: \"application/json, text/javascript\"\n\t\t},\n\n\t\tcontents: {\n\t\t\txml: /\\bxml\\b/,\n\t\t\thtml: /\\bhtml/,\n\t\t\tjson: /\\bjson\\b/\n\t\t},\n\n\t\tresponseFields: {\n\t\t\txml: \"responseXML\",\n\t\t\ttext: \"responseText\",\n\t\t\tjson: \"responseJSON\"\n\t\t},\n\n\t\t// Data converters\n\t\t// Keys separate source (or catchall \"*\") and destination types with a single space\n\t\tconverters: {\n\n\t\t\t// Convert anything to text\n\t\t\t\"* text\": String,\n\n\t\t\t// Text to html (true = no transformation)\n\t\t\t\"text html\": true,\n\n\t\t\t// Evaluate text as a json expression\n\t\t\t\"text json\": JSON.parse,\n\n\t\t\t// Parse text as xml\n\t\t\t\"text xml\": jQuery.parseXML\n\t\t},\n\n\t\t// For options that shouldn't be deep extended:\n\t\t// you can add your own custom options here if\n\t\t// and when you create one that shouldn't be\n\t\t// deep extended (see ajaxExtend)\n\t\tflatOptions: {\n\t\t\turl: true,\n\t\t\tcontext: true\n\t\t}\n\t},\n\n\t// Creates a full fledged settings object into target\n\t// with both ajaxSettings and settings fields.\n\t// If target is omitted, writes into ajaxSettings.\n\tajaxSetup: function( target, settings ) {\n\t\treturn settings ?\n\n\t\t\t// Building a settings object\n\t\t\tajaxExtend( ajaxExtend( target, jQuery.ajaxSettings ), settings ) :\n\n\t\t\t// Extending ajaxSettings\n\t\t\tajaxExtend( jQuery.ajaxSettings, target );\n\t},\n\n\tajaxPrefilter: addToPrefiltersOrTransports( prefilters ),\n\tajaxTransport: addToPrefiltersOrTransports( transports ),\n\n\t// Main method\n\tajax: function( url, options ) {\n\n\t\t// If url is an object, simulate pre-1.5 signature\n\t\tif ( typeof url === \"object\" ) {\n\t\t\toptions = url;\n\t\t\turl = undefined;\n\t\t}\n\n\t\t// Force options to be an object\n\t\toptions = options || {};\n\n\t\tvar transport,\n\n\t\t\t// URL without anti-cache param\n\t\t\tcacheURL,\n\n\t\t\t// Response headers\n\t\t\tresponseHeadersString,\n\t\t\tresponseHeaders,\n\n\t\t\t// timeout handle\n\t\t\ttimeoutTimer,\n\n\t\t\t// Url cleanup var\n\t\t\turlAnchor,\n\n\t\t\t// Request state (becomes false upon send and true upon completion)\n\t\t\tcompleted,\n\n\t\t\t// To know if global events are to be dispatched\n\t\t\tfireGlobals,\n\n\t\t\t// Loop variable\n\t\t\ti,\n\n\t\t\t// uncached part of the url\n\t\t\tuncached,\n\n\t\t\t// Create the final options object\n\t\t\ts = jQuery.ajaxSetup( {}, options ),\n\n\t\t\t// Callbacks context\n\t\t\tcallbackContext = s.context || s,\n\n\t\t\t// Context for global events is callbackContext if it is a DOM node or jQuery collection\n\t\t\tglobalEventContext = s.context &&\n\t\t\t\t( callbackContext.nodeType || callbackContext.jquery ) ?\n\t\t\t\t\tjQuery( callbackContext ) :\n\t\t\t\t\tjQuery.event,\n\n\t\t\t// Deferreds\n\t\t\tdeferred = jQuery.Deferred(),\n\t\t\tcompleteDeferred = jQuery.Callbacks( \"once memory\" ),\n\n\t\t\t// Status-dependent callbacks\n\t\t\tstatusCode = s.statusCode || {},\n\n\t\t\t// Headers (they are sent all at once)\n\t\t\trequestHeaders = {},\n\t\t\trequestHeadersNames = {},\n\n\t\t\t// Default abort message\n\t\t\tstrAbort = \"canceled\",\n\n\t\t\t// Fake xhr\n\t\t\tjqXHR = {\n\t\t\t\treadyState: 0,\n\n\t\t\t\t// Builds headers hashtable if needed\n\t\t\t\tgetResponseHeader: function( key ) {\n\t\t\t\t\tvar match;\n\t\t\t\t\tif ( completed ) {\n\t\t\t\t\t\tif ( !responseHeaders ) {\n\t\t\t\t\t\t\tresponseHeaders = {};\n\t\t\t\t\t\t\twhile ( ( match = rheaders.exec( responseHeadersString ) ) ) {\n\t\t\t\t\t\t\t\tresponseHeaders[ match[ 1 ].toLowerCase() ] = match[ 2 ];\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\tmatch = responseHeaders[ key.toLowerCase() ];\n\t\t\t\t\t}\n\t\t\t\t\treturn match == null ? null : match;\n\t\t\t\t},\n\n\t\t\t\t// Raw string\n\t\t\t\tgetAllResponseHeaders: function() {\n\t\t\t\t\treturn completed ? responseHeadersString : null;\n\t\t\t\t},\n\n\t\t\t\t// Caches the header\n\t\t\t\tsetRequestHeader: function( name, value ) {\n\t\t\t\t\tif ( completed == null ) {\n\t\t\t\t\t\tname = requestHeadersNames[ name.toLowerCase() ] =\n\t\t\t\t\t\t\trequestHeadersNames[ name.toLowerCase() ] || name;\n\t\t\t\t\t\trequestHeaders[ name ] = value;\n\t\t\t\t\t}\n\t\t\t\t\treturn this;\n\t\t\t\t},\n\n\t\t\t\t// Overrides response content-type header\n\t\t\t\toverrideMimeType: function( type ) {\n\t\t\t\t\tif ( completed == null ) {\n\t\t\t\t\t\ts.mimeType = type;\n\t\t\t\t\t}\n\t\t\t\t\treturn this;\n\t\t\t\t},\n\n\t\t\t\t// Status-dependent callbacks\n\t\t\t\tstatusCode: function( map ) {\n\t\t\t\t\tvar code;\n\t\t\t\t\tif ( map ) {\n\t\t\t\t\t\tif ( completed ) {\n\n\t\t\t\t\t\t\t// Execute the appropriate callbacks\n\t\t\t\t\t\t\tjqXHR.always( map[ jqXHR.status ] );\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\t// Lazy-add the new callbacks in a way that preserves old ones\n\t\t\t\t\t\t\tfor ( code in map ) {\n\t\t\t\t\t\t\t\tstatusCode[ code ] = [ statusCode[ code ], map[ code ] ];\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\treturn this;\n\t\t\t\t},\n\n\t\t\t\t// Cancel the request\n\t\t\t\tabort: function( statusText ) {\n\t\t\t\t\tvar finalText = statusText || strAbort;\n\t\t\t\t\tif ( transport ) {\n\t\t\t\t\t\ttransport.abort( finalText );\n\t\t\t\t\t}\n\t\t\t\t\tdone( 0, finalText );\n\t\t\t\t\treturn this;\n\t\t\t\t}\n\t\t\t};\n\n\t\t// Attach deferreds\n\t\tdeferred.promise( jqXHR );\n\n\t\t// Add protocol if not provided (prefilters might expect it)\n\t\t// Handle falsy url in the settings object (#10093: consistency with old signature)\n\t\t// We also use the url parameter if available\n\t\ts.url = ( ( url || s.url || location.href ) + \"\" )\n\t\t\t.replace( rprotocol, location.protocol + \"//\" );\n\n\t\t// Alias method option to type as per ticket #12004\n\t\ts.type = options.method || options.type || s.method || s.type;\n\n\t\t// Extract dataTypes list\n\t\ts.dataTypes = ( s.dataType || \"*\" ).toLowerCase().match( rnotwhite ) || [ \"\" ];\n\n\t\t// A cross-domain request is in order when the origin doesn't match the current origin.\n\t\tif ( s.crossDomain == null ) {\n\t\t\turlAnchor = document.createElement( \"a\" );\n\n\t\t\t// Support: IE <=8 - 11, Edge 12 - 13\n\t\t\t// IE throws exception on accessing the href property if url is malformed,\n\t\t\t// e.g. http://example.com:80x/\n\t\t\ttry {\n\t\t\t\turlAnchor.href = s.url;\n\n\t\t\t\t// Support: IE <=8 - 11 only\n\t\t\t\t// Anchor's host property isn't correctly set when s.url is relative\n\t\t\t\turlAnchor.href = urlAnchor.href;\n\t\t\t\ts.crossDomain = originAnchor.protocol + \"//\" + originAnchor.host !==\n\t\t\t\t\turlAnchor.protocol + \"//\" + urlAnchor.host;\n\t\t\t} catch ( e ) {\n\n\t\t\t\t// If there is an error parsing the URL, assume it is crossDomain,\n\t\t\t\t// it can be rejected by the transport if it is invalid\n\t\t\t\ts.crossDomain = true;\n\t\t\t}\n\t\t}\n\n\t\t// Convert data if not already a string\n\t\tif ( s.data && s.processData && typeof s.data !== \"string\" ) {\n\t\t\ts.data = jQuery.param( s.data, s.traditional );\n\t\t}\n\n\t\t// Apply prefilters\n\t\tinspectPrefiltersOrTransports( prefilters, s, options, jqXHR );\n\n\t\t// If request was aborted inside a prefilter, stop there\n\t\tif ( completed ) {\n\t\t\treturn jqXHR;\n\t\t}\n\n\t\t// We can fire global events as of now if asked to\n\t\t// Don't fire events if jQuery.event is undefined in an AMD-usage scenario (#15118)\n\t\tfireGlobals = jQuery.event && s.global;\n\n\t\t// Watch for a new set of requests\n\t\tif ( fireGlobals && jQuery.active++ === 0 ) {\n\t\t\tjQuery.event.trigger( \"ajaxStart\" );\n\t\t}\n\n\t\t// Uppercase the type\n\t\ts.type = s.type.toUpperCase();\n\n\t\t// Determine if request has content\n\t\ts.hasContent = !rnoContent.test( s.type );\n\n\t\t// Save the URL in case we're toying with the If-Modified-Since\n\t\t// and/or If-None-Match header later on\n\t\t// Remove hash to simplify url manipulation\n\t\tcacheURL = s.url.replace( rhash, \"\" );\n\n\t\t// More options handling for requests with no content\n\t\tif ( !s.hasContent ) {\n\n\t\t\t// Remember the hash so we can put it back\n\t\t\tuncached = s.url.slice( cacheURL.length );\n\n\t\t\t// If data is available, append data to url\n\t\t\tif ( s.data ) {\n\t\t\t\tcacheURL += ( rquery.test( cacheURL ) ? \"&\" : \"?\" ) + s.data;\n\n\t\t\t\t// #9682: remove data so that it's not used in an eventual retry\n\t\t\t\tdelete s.data;\n\t\t\t}\n\n\t\t\t// Add anti-cache in uncached url if needed\n\t\t\tif ( s.cache === false ) {\n\t\t\t\tcacheURL = cacheURL.replace( rts, \"\" );\n\t\t\t\tuncached = ( rquery.test( cacheURL ) ? \"&\" : \"?\" ) + \"_=\" + ( nonce++ ) + uncached;\n\t\t\t}\n\n\t\t\t// Put hash and anti-cache on the URL that will be requested (gh-1732)\n\t\t\ts.url = cacheURL + uncached;\n\n\t\t// Change '%20' to '+' if this is encoded form body content (gh-2658)\n\t\t} else if ( s.data && s.processData &&\n\t\t\t( s.contentType || \"\" ).indexOf( \"application/x-www-form-urlencoded\" ) === 0 ) {\n\t\t\ts.data = s.data.replace( r20, \"+\" );\n\t\t}\n\n\t\t// Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.\n\t\tif ( s.ifModified ) {\n\t\t\tif ( jQuery.lastModified[ cacheURL ] ) {\n\t\t\t\tjqXHR.setRequestHeader( \"If-Modified-Since\", jQuery.lastModified[ cacheURL ] );\n\t\t\t}\n\t\t\tif ( jQuery.etag[ cacheURL ] ) {\n\t\t\t\tjqXHR.setRequestHeader( \"If-None-Match\", jQuery.etag[ cacheURL ] );\n\t\t\t}\n\t\t}\n\n\t\t// Set the correct header, if data is being sent\n\t\tif ( s.data && s.hasContent && s.contentType !== false || options.contentType ) {\n\t\t\tjqXHR.setRequestHeader( \"Content-Type\", s.contentType );\n\t\t}\n\n\t\t// Set the Accepts header for the server, depending on the dataType\n\t\tjqXHR.setRequestHeader(\n\t\t\t\"Accept\",\n\t\t\ts.dataTypes[ 0 ] && s.accepts[ s.dataTypes[ 0 ] ] ?\n\t\t\t\ts.accepts[ s.dataTypes[ 0 ] ] +\n\t\t\t\t\t( s.dataTypes[ 0 ] !== \"*\" ? \", \" + allTypes + \"; q=0.01\" : \"\" ) :\n\t\t\t\ts.accepts[ \"*\" ]\n\t\t);\n\n\t\t// Check for headers option\n\t\tfor ( i in s.headers ) {\n\t\t\tjqXHR.setRequestHeader( i, s.headers[ i ] );\n\t\t}\n\n\t\t// Allow custom headers/mimetypes and early abort\n\t\tif ( s.beforeSend &&\n\t\t\t( s.beforeSend.call( callbackContext, jqXHR, s ) === false || completed ) ) {\n\n\t\t\t// Abort if not done already and return\n\t\t\treturn jqXHR.abort();\n\t\t}\n\n\t\t// Aborting is no longer a cancellation\n\t\tstrAbort = \"abort\";\n\n\t\t// Install callbacks on deferreds\n\t\tcompleteDeferred.add( s.complete );\n\t\tjqXHR.done( s.success );\n\t\tjqXHR.fail( s.error );\n\n\t\t// Get transport\n\t\ttransport = inspectPrefiltersOrTransports( transports, s, options, jqXHR );\n\n\t\t// If no transport, we auto-abort\n\t\tif ( !transport ) {\n\t\t\tdone( -1, \"No Transport\" );\n\t\t} else {\n\t\t\tjqXHR.readyState = 1;\n\n\t\t\t// Send global event\n\t\t\tif ( fireGlobals ) {\n\t\t\t\tglobalEventContext.trigger( \"ajaxSend\", [ jqXHR, s ] );\n\t\t\t}\n\n\t\t\t// If request was aborted inside ajaxSend, stop there\n\t\t\tif ( completed ) {\n\t\t\t\treturn jqXHR;\n\t\t\t}\n\n\t\t\t// Timeout\n\t\t\tif ( s.async && s.timeout > 0 ) {\n\t\t\t\ttimeoutTimer = window.setTimeout( function() {\n\t\t\t\t\tjqXHR.abort( \"timeout\" );\n\t\t\t\t}, s.timeout );\n\t\t\t}\n\n\t\t\ttry {\n\t\t\t\tcompleted = false;\n\t\t\t\ttransport.send( requestHeaders, done );\n\t\t\t} catch ( e ) {\n\n\t\t\t\t// Rethrow post-completion exceptions\n\t\t\t\tif ( completed ) {\n\t\t\t\t\tthrow e;\n\t\t\t\t}\n\n\t\t\t\t// Propagate others as results\n\t\t\t\tdone( -1, e );\n\t\t\t}\n\t\t}\n\n\t\t// Callback for when everything is done\n\t\tfunction done( status, nativeStatusText, responses, headers ) {\n\t\t\tvar isSuccess, success, error, response, modified,\n\t\t\t\tstatusText = nativeStatusText;\n\n\t\t\t// Ignore repeat invocations\n\t\t\tif ( completed ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tcompleted = true;\n\n\t\t\t// Clear timeout if it exists\n\t\t\tif ( timeoutTimer ) {\n\t\t\t\twindow.clearTimeout( timeoutTimer );\n\t\t\t}\n\n\t\t\t// Dereference transport for early garbage collection\n\t\t\t// (no matter how long the jqXHR object will be used)\n\t\t\ttransport = undefined;\n\n\t\t\t// Cache response headers\n\t\t\tresponseHeadersString = headers || \"\";\n\n\t\t\t// Set readyState\n\t\t\tjqXHR.readyState = status > 0 ? 4 : 0;\n\n\t\t\t// Determine if successful\n\t\t\tisSuccess = status >= 200 && status < 300 || status === 304;\n\n\t\t\t// Get response data\n\t\t\tif ( responses ) {\n\t\t\t\tresponse = ajaxHandleResponses( s, jqXHR, responses );\n\t\t\t}\n\n\t\t\t// Convert no matter what (that way responseXXX fields are always set)\n\t\t\tresponse = ajaxConvert( s, response, jqXHR, isSuccess );\n\n\t\t\t// If successful, handle type chaining\n\t\t\tif ( isSuccess ) {\n\n\t\t\t\t// Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.\n\t\t\t\tif ( s.ifModified ) {\n\t\t\t\t\tmodified = jqXHR.getResponseHeader( \"Last-Modified\" );\n\t\t\t\t\tif ( modified ) {\n\t\t\t\t\t\tjQuery.lastModified[ cacheURL ] = modified;\n\t\t\t\t\t}\n\t\t\t\t\tmodified = jqXHR.getResponseHeader( \"etag\" );\n\t\t\t\t\tif ( modified ) {\n\t\t\t\t\t\tjQuery.etag[ cacheURL ] = modified;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// if no content\n\t\t\t\tif ( status === 204 || s.type === \"HEAD\" ) {\n\t\t\t\t\tstatusText = \"nocontent\";\n\n\t\t\t\t// if not modified\n\t\t\t\t} else if ( status === 304 ) {\n\t\t\t\t\tstatusText = \"notmodified\";\n\n\t\t\t\t// If we have data, let's convert it\n\t\t\t\t} else {\n\t\t\t\t\tstatusText = response.state;\n\t\t\t\t\tsuccess = response.data;\n\t\t\t\t\terror = response.error;\n\t\t\t\t\tisSuccess = !error;\n\t\t\t\t}\n\t\t\t} else {\n\n\t\t\t\t// Extract error from statusText and normalize for non-aborts\n\t\t\t\terror = statusText;\n\t\t\t\tif ( status || !statusText ) {\n\t\t\t\t\tstatusText = \"error\";\n\t\t\t\t\tif ( status < 0 ) {\n\t\t\t\t\t\tstatus = 0;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Set data for the fake xhr object\n\t\t\tjqXHR.status = status;\n\t\t\tjqXHR.statusText = ( nativeStatusText || statusText ) + \"\";\n\n\t\t\t// Success/Error\n\t\t\tif ( isSuccess ) {\n\t\t\t\tdeferred.resolveWith( callbackContext, [ success, statusText, jqXHR ] );\n\t\t\t} else {\n\t\t\t\tdeferred.rejectWith( callbackContext, [ jqXHR, statusText, error ] );\n\t\t\t}\n\n\t\t\t// Status-dependent callbacks\n\t\t\tjqXHR.statusCode( statusCode );\n\t\t\tstatusCode = undefined;\n\n\t\t\tif ( fireGlobals ) {\n\t\t\t\tglobalEventContext.trigger( isSuccess ? \"ajaxSuccess\" : \"ajaxError\",\n\t\t\t\t\t[ jqXHR, s, isSuccess ? success : error ] );\n\t\t\t}\n\n\t\t\t// Complete\n\t\t\tcompleteDeferred.fireWith( callbackContext, [ jqXHR, statusText ] );\n\n\t\t\tif ( fireGlobals ) {\n\t\t\t\tglobalEventContext.trigger( \"ajaxComplete\", [ jqXHR, s ] );\n\n\t\t\t\t// Handle the global AJAX counter\n\t\t\t\tif ( !( --jQuery.active ) ) {\n\t\t\t\t\tjQuery.event.trigger( \"ajaxStop\" );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn jqXHR;\n\t},\n\n\tgetJSON: function( url, data, callback ) {\n\t\treturn jQuery.get( url, data, callback, \"json\" );\n\t},\n\n\tgetScript: function( url, callback ) {\n\t\treturn jQuery.get( url, undefined, callback, \"script\" );\n\t}\n} );\n\njQuery.each( [ \"get\", \"post\" ], function( i, method ) {\n\tjQuery[ method ] = function( url, data, callback, type ) {\n\n\t\t// Shift arguments if data argument was omitted\n\t\tif ( jQuery.isFunction( data ) ) {\n\t\t\ttype = type || callback;\n\t\t\tcallback = data;\n\t\t\tdata = undefined;\n\t\t}\n\n\t\t// The url can be an options object (which then must have .url)\n\t\treturn jQuery.ajax( jQuery.extend( {\n\t\t\turl: url,\n\t\t\ttype: method,\n\t\t\tdataType: type,\n\t\t\tdata: data,\n\t\t\tsuccess: callback\n\t\t}, jQuery.isPlainObject( url ) && url ) );\n\t};\n} );\n\n\njQuery._evalUrl = function( url ) {\n\treturn jQuery.ajax( {\n\t\turl: url,\n\n\t\t// Make this explicit, since user can override this through ajaxSetup (#11264)\n\t\ttype: \"GET\",\n\t\tdataType: \"script\",\n\t\tcache: true,\n\t\tasync: false,\n\t\tglobal: false,\n\t\t\"throws\": true\n\t} );\n};\n\n\njQuery.fn.extend( {\n\twrapAll: function( html ) {\n\t\tvar wrap;\n\n\t\tif ( this[ 0 ] ) {\n\t\t\tif ( jQuery.isFunction( html ) ) {\n\t\t\t\thtml = html.call( this[ 0 ] );\n\t\t\t}\n\n\t\t\t// The elements to wrap the target around\n\t\t\twrap = jQuery( html, this[ 0 ].ownerDocument ).eq( 0 ).clone( true );\n\n\t\t\tif ( this[ 0 ].parentNode ) {\n\t\t\t\twrap.insertBefore( this[ 0 ] );\n\t\t\t}\n\n\t\t\twrap.map( function() {\n\t\t\t\tvar elem = this;\n\n\t\t\t\twhile ( elem.firstElementChild ) {\n\t\t\t\t\telem = elem.firstElementChild;\n\t\t\t\t}\n\n\t\t\t\treturn elem;\n\t\t\t} ).append( this );\n\t\t}\n\n\t\treturn this;\n\t},\n\n\twrapInner: function( html ) {\n\t\tif ( jQuery.isFunction( html ) ) {\n\t\t\treturn this.each( function( i ) {\n\t\t\t\tjQuery( this ).wrapInner( html.call( this, i ) );\n\t\t\t} );\n\t\t}\n\n\t\treturn this.each( function() {\n\t\t\tvar self = jQuery( this ),\n\t\t\t\tcontents = self.contents();\n\n\t\t\tif ( contents.length ) {\n\t\t\t\tcontents.wrapAll( html );\n\n\t\t\t} else {\n\t\t\t\tself.append( html );\n\t\t\t}\n\t\t} );\n\t},\n\n\twrap: function( html ) {\n\t\tvar isFunction = jQuery.isFunction( html );\n\n\t\treturn this.each( function( i ) {\n\t\t\tjQuery( this ).wrapAll( isFunction ? html.call( this, i ) : html );\n\t\t} );\n\t},\n\n\tunwrap: function( selector ) {\n\t\tthis.parent( selector ).not( \"body\" ).each( function() {\n\t\t\tjQuery( this ).replaceWith( this.childNodes );\n\t\t} );\n\t\treturn this;\n\t}\n} );\n\n\njQuery.expr.pseudos.hidden = function( elem ) {\n\treturn !jQuery.expr.pseudos.visible( elem );\n};\njQuery.expr.pseudos.visible = function( elem ) {\n\treturn !!( elem.offsetWidth || elem.offsetHeight || elem.getClientRects().length );\n};\n\n\n\n\njQuery.ajaxSettings.xhr = function() {\n\ttry {\n\t\treturn new window.XMLHttpRequest();\n\t} catch ( e ) {}\n};\n\nvar xhrSuccessStatus = {\n\n\t\t// File protocol always yields status code 0, assume 200\n\t\t0: 200,\n\n\t\t// Support: IE <=9 only\n\t\t// #1450: sometimes IE returns 1223 when it should be 204\n\t\t1223: 204\n\t},\n\txhrSupported = jQuery.ajaxSettings.xhr();\n\nsupport.cors = !!xhrSupported && ( \"withCredentials\" in xhrSupported );\nsupport.ajax = xhrSupported = !!xhrSupported;\n\njQuery.ajaxTransport( function( options ) {\n\tvar callback, errorCallback;\n\n\t// Cross domain only allowed if supported through XMLHttpRequest\n\tif ( support.cors || xhrSupported && !options.crossDomain ) {\n\t\treturn {\n\t\t\tsend: function( headers, complete ) {\n\t\t\t\tvar i,\n\t\t\t\t\txhr = options.xhr();\n\n\t\t\t\txhr.open(\n\t\t\t\t\toptions.type,\n\t\t\t\t\toptions.url,\n\t\t\t\t\toptions.async,\n\t\t\t\t\toptions.username,\n\t\t\t\t\toptions.password\n\t\t\t\t);\n\n\t\t\t\t// Apply custom fields if provided\n\t\t\t\tif ( options.xhrFields ) {\n\t\t\t\t\tfor ( i in options.xhrFields ) {\n\t\t\t\t\t\txhr[ i ] = options.xhrFields[ i ];\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// Override mime type if needed\n\t\t\t\tif ( options.mimeType && xhr.overrideMimeType ) {\n\t\t\t\t\txhr.overrideMimeType( options.mimeType );\n\t\t\t\t}\n\n\t\t\t\t// X-Requested-With header\n\t\t\t\t// For cross-domain requests, seeing as conditions for a preflight are\n\t\t\t\t// akin to a jigsaw puzzle, we simply never set it to be sure.\n\t\t\t\t// (it can always be set on a per-request basis or even using ajaxSetup)\n\t\t\t\t// For same-domain requests, won't change header if already provided.\n\t\t\t\tif ( !options.crossDomain && !headers[ \"X-Requested-With\" ] ) {\n\t\t\t\t\theaders[ \"X-Requested-With\" ] = \"XMLHttpRequest\";\n\t\t\t\t}\n\n\t\t\t\t// Set headers\n\t\t\t\tfor ( i in headers ) {\n\t\t\t\t\txhr.setRequestHeader( i, headers[ i ] );\n\t\t\t\t}\n\n\t\t\t\t// Callback\n\t\t\t\tcallback = function( type ) {\n\t\t\t\t\treturn function() {\n\t\t\t\t\t\tif ( callback ) {\n\t\t\t\t\t\t\tcallback = errorCallback = xhr.onload =\n\t\t\t\t\t\t\t\txhr.onerror = xhr.onabort = xhr.onreadystatechange = null;\n\n\t\t\t\t\t\t\tif ( type === \"abort\" ) {\n\t\t\t\t\t\t\t\txhr.abort();\n\t\t\t\t\t\t\t} else if ( type === \"error\" ) {\n\n\t\t\t\t\t\t\t\t// Support: IE <=9 only\n\t\t\t\t\t\t\t\t// On a manual native abort, IE9 throws\n\t\t\t\t\t\t\t\t// errors on any property access that is not readyState\n\t\t\t\t\t\t\t\tif ( typeof xhr.status !== \"number\" ) {\n\t\t\t\t\t\t\t\t\tcomplete( 0, \"error\" );\n\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\tcomplete(\n\n\t\t\t\t\t\t\t\t\t\t// File: protocol always yields status 0; see #8605, #14207\n\t\t\t\t\t\t\t\t\t\txhr.status,\n\t\t\t\t\t\t\t\t\t\txhr.statusText\n\t\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tcomplete(\n\t\t\t\t\t\t\t\t\txhrSuccessStatus[ xhr.status ] || xhr.status,\n\t\t\t\t\t\t\t\t\txhr.statusText,\n\n\t\t\t\t\t\t\t\t\t// Support: IE <=9 only\n\t\t\t\t\t\t\t\t\t// IE9 has no XHR2 but throws on binary (trac-11426)\n\t\t\t\t\t\t\t\t\t// For XHR2 non-text, let the caller handle it (gh-2498)\n\t\t\t\t\t\t\t\t\t( xhr.responseType || \"text\" ) !== \"text\"  ||\n\t\t\t\t\t\t\t\t\ttypeof xhr.responseText !== \"string\" ?\n\t\t\t\t\t\t\t\t\t\t{ binary: xhr.response } :\n\t\t\t\t\t\t\t\t\t\t{ text: xhr.responseText },\n\t\t\t\t\t\t\t\t\txhr.getAllResponseHeaders()\n\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t};\n\t\t\t\t};\n\n\t\t\t\t// Listen to events\n\t\t\t\txhr.onload = callback();\n\t\t\t\terrorCallback = xhr.onerror = callback( \"error\" );\n\n\t\t\t\t// Support: IE 9 only\n\t\t\t\t// Use onreadystatechange to replace onabort\n\t\t\t\t// to handle uncaught aborts\n\t\t\t\tif ( xhr.onabort !== undefined ) {\n\t\t\t\t\txhr.onabort = errorCallback;\n\t\t\t\t} else {\n\t\t\t\t\txhr.onreadystatechange = function() {\n\n\t\t\t\t\t\t// Check readyState before timeout as it changes\n\t\t\t\t\t\tif ( xhr.readyState === 4 ) {\n\n\t\t\t\t\t\t\t// Allow onerror to be called first,\n\t\t\t\t\t\t\t// but that will not handle a native abort\n\t\t\t\t\t\t\t// Also, save errorCallback to a variable\n\t\t\t\t\t\t\t// as xhr.onerror cannot be accessed\n\t\t\t\t\t\t\twindow.setTimeout( function() {\n\t\t\t\t\t\t\t\tif ( callback ) {\n\t\t\t\t\t\t\t\t\terrorCallback();\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t} );\n\t\t\t\t\t\t}\n\t\t\t\t\t};\n\t\t\t\t}\n\n\t\t\t\t// Create the abort callback\n\t\t\t\tcallback = callback( \"abort\" );\n\n\t\t\t\ttry {\n\n\t\t\t\t\t// Do send the request (this may raise an exception)\n\t\t\t\t\txhr.send( options.hasContent && options.data || null );\n\t\t\t\t} catch ( e ) {\n\n\t\t\t\t\t// #14683: Only rethrow if this hasn't been notified as an error yet\n\t\t\t\t\tif ( callback ) {\n\t\t\t\t\t\tthrow e;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t},\n\n\t\t\tabort: function() {\n\t\t\t\tif ( callback ) {\n\t\t\t\t\tcallback();\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\t}\n} );\n\n\n\n\n// Prevent auto-execution of scripts when no explicit dataType was provided (See gh-2432)\njQuery.ajaxPrefilter( function( s ) {\n\tif ( s.crossDomain ) {\n\t\ts.contents.script = false;\n\t}\n} );\n\n// Install script dataType\njQuery.ajaxSetup( {\n\taccepts: {\n\t\tscript: \"text/javascript, application/javascript, \" +\n\t\t\t\"application/ecmascript, application/x-ecmascript\"\n\t},\n\tcontents: {\n\t\tscript: /\\b(?:java|ecma)script\\b/\n\t},\n\tconverters: {\n\t\t\"text script\": function( text ) {\n\t\t\tjQuery.globalEval( text );\n\t\t\treturn text;\n\t\t}\n\t}\n} );\n\n// Handle cache's special case and crossDomain\njQuery.ajaxPrefilter( \"script\", function( s ) {\n\tif ( s.cache === undefined ) {\n\t\ts.cache = false;\n\t}\n\tif ( s.crossDomain ) {\n\t\ts.type = \"GET\";\n\t}\n} );\n\n// Bind script tag hack transport\njQuery.ajaxTransport( \"script\", function( s ) {\n\n\t// This transport only deals with cross domain requests\n\tif ( s.crossDomain ) {\n\t\tvar script, callback;\n\t\treturn {\n\t\t\tsend: function( _, complete ) {\n\t\t\t\tscript = jQuery( \"<script>\" ).prop( {\n\t\t\t\t\tcharset: s.scriptCharset,\n\t\t\t\t\tsrc: s.url\n\t\t\t\t} ).on(\n\t\t\t\t\t\"load error\",\n\t\t\t\t\tcallback = function( evt ) {\n\t\t\t\t\t\tscript.remove();\n\t\t\t\t\t\tcallback = null;\n\t\t\t\t\t\tif ( evt ) {\n\t\t\t\t\t\t\tcomplete( evt.type === \"error\" ? 404 : 200, evt.type );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t);\n\n\t\t\t\t// Use native DOM manipulation to avoid our domManip AJAX trickery\n\t\t\t\tdocument.head.appendChild( script[ 0 ] );\n\t\t\t},\n\t\t\tabort: function() {\n\t\t\t\tif ( callback ) {\n\t\t\t\t\tcallback();\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\t}\n} );\n\n\n\n\nvar oldCallbacks = [],\n\trjsonp = /(=)\\?(?=&|$)|\\?\\?/;\n\n// Default jsonp settings\njQuery.ajaxSetup( {\n\tjsonp: \"callback\",\n\tjsonpCallback: function() {\n\t\tvar callback = oldCallbacks.pop() || ( jQuery.expando + \"_\" + ( nonce++ ) );\n\t\tthis[ callback ] = true;\n\t\treturn callback;\n\t}\n} );\n\n// Detect, normalize options and install callbacks for jsonp requests\njQuery.ajaxPrefilter( \"json jsonp\", function( s, originalSettings, jqXHR ) {\n\n\tvar callbackName, overwritten, responseContainer,\n\t\tjsonProp = s.jsonp !== false && ( rjsonp.test( s.url ) ?\n\t\t\t\"url\" :\n\t\t\ttypeof s.data === \"string\" &&\n\t\t\t\t( s.contentType || \"\" )\n\t\t\t\t\t.indexOf( \"application/x-www-form-urlencoded\" ) === 0 &&\n\t\t\t\trjsonp.test( s.data ) && \"data\"\n\t\t);\n\n\t// Handle iff the expected data type is \"jsonp\" or we have a parameter to set\n\tif ( jsonProp || s.dataTypes[ 0 ] === \"jsonp\" ) {\n\n\t\t// Get callback name, remembering preexisting value associated with it\n\t\tcallbackName = s.jsonpCallback = jQuery.isFunction( s.jsonpCallback ) ?\n\t\t\ts.jsonpCallback() :\n\t\t\ts.jsonpCallback;\n\n\t\t// Insert callback into url or form data\n\t\tif ( jsonProp ) {\n\t\t\ts[ jsonProp ] = s[ jsonProp ].replace( rjsonp, \"$1\" + callbackName );\n\t\t} else if ( s.jsonp !== false ) {\n\t\t\ts.url += ( rquery.test( s.url ) ? \"&\" : \"?\" ) + s.jsonp + \"=\" + callbackName;\n\t\t}\n\n\t\t// Use data converter to retrieve json after script execution\n\t\ts.converters[ \"script json\" ] = function() {\n\t\t\tif ( !responseContainer ) {\n\t\t\t\tjQuery.error( callbackName + \" was not called\" );\n\t\t\t}\n\t\t\treturn responseContainer[ 0 ];\n\t\t};\n\n\t\t// Force json dataType\n\t\ts.dataTypes[ 0 ] = \"json\";\n\n\t\t// Install callback\n\t\toverwritten = window[ callbackName ];\n\t\twindow[ callbackName ] = function() {\n\t\t\tresponseContainer = arguments;\n\t\t};\n\n\t\t// Clean-up function (fires after converters)\n\t\tjqXHR.always( function() {\n\n\t\t\t// If previous value didn't exist - remove it\n\t\t\tif ( overwritten === undefined ) {\n\t\t\t\tjQuery( window ).removeProp( callbackName );\n\n\t\t\t// Otherwise restore preexisting value\n\t\t\t} else {\n\t\t\t\twindow[ callbackName ] = overwritten;\n\t\t\t}\n\n\t\t\t// Save back as free\n\t\t\tif ( s[ callbackName ] ) {\n\n\t\t\t\t// Make sure that re-using the options doesn't screw things around\n\t\t\t\ts.jsonpCallback = originalSettings.jsonpCallback;\n\n\t\t\t\t// Save the callback name for future use\n\t\t\t\toldCallbacks.push( callbackName );\n\t\t\t}\n\n\t\t\t// Call if it was a function and we have a response\n\t\t\tif ( responseContainer && jQuery.isFunction( overwritten ) ) {\n\t\t\t\toverwritten( responseContainer[ 0 ] );\n\t\t\t}\n\n\t\t\tresponseContainer = overwritten = undefined;\n\t\t} );\n\n\t\t// Delegate to script\n\t\treturn \"script\";\n\t}\n} );\n\n\n\n\n// Support: Safari 8 only\n// In Safari 8 documents created via document.implementation.createHTMLDocument\n// collapse sibling forms: the second one becomes a child of the first one.\n// Because of that, this security measure has to be disabled in Safari 8.\n// https://bugs.webkit.org/show_bug.cgi?id=137337\nsupport.createHTMLDocument = ( function() {\n\tvar body = document.implementation.createHTMLDocument( \"\" ).body;\n\tbody.innerHTML = \"<form></form><form></form>\";\n\treturn body.childNodes.length === 2;\n} )();\n\n\n// Argument \"data\" should be string of html\n// context (optional): If specified, the fragment will be created in this context,\n// defaults to document\n// keepScripts (optional): If true, will include scripts passed in the html string\njQuery.parseHTML = function( data, context, keepScripts ) {\n\tif ( typeof data !== \"string\" ) {\n\t\treturn [];\n\t}\n\tif ( typeof context === \"boolean\" ) {\n\t\tkeepScripts = context;\n\t\tcontext = false;\n\t}\n\n\tvar base, parsed, scripts;\n\n\tif ( !context ) {\n\n\t\t// Stop scripts or inline event handlers from being executed immediately\n\t\t// by using document.implementation\n\t\tif ( support.createHTMLDocument ) {\n\t\t\tcontext = document.implementation.createHTMLDocument( \"\" );\n\n\t\t\t// Set the base href for the created document\n\t\t\t// so any parsed elements with URLs\n\t\t\t// are based on the document's URL (gh-2965)\n\t\t\tbase = context.createElement( \"base\" );\n\t\t\tbase.href = document.location.href;\n\t\t\tcontext.head.appendChild( base );\n\t\t} else {\n\t\t\tcontext = document;\n\t\t}\n\t}\n\n\tparsed = rsingleTag.exec( data );\n\tscripts = !keepScripts && [];\n\n\t// Single tag\n\tif ( parsed ) {\n\t\treturn [ context.createElement( parsed[ 1 ] ) ];\n\t}\n\n\tparsed = buildFragment( [ data ], context, scripts );\n\n\tif ( scripts && scripts.length ) {\n\t\tjQuery( scripts ).remove();\n\t}\n\n\treturn jQuery.merge( [], parsed.childNodes );\n};\n\n\n/**\n * Load a url into a page\n */\njQuery.fn.load = function( url, params, callback ) {\n\tvar selector, type, response,\n\t\tself = this,\n\t\toff = url.indexOf( \" \" );\n\n\tif ( off > -1 ) {\n\t\tselector = jQuery.trim( url.slice( off ) );\n\t\turl = url.slice( 0, off );\n\t}\n\n\t// If it's a function\n\tif ( jQuery.isFunction( params ) ) {\n\n\t\t// We assume that it's the callback\n\t\tcallback = params;\n\t\tparams = undefined;\n\n\t// Otherwise, build a param string\n\t} else if ( params && typeof params === \"object\" ) {\n\t\ttype = \"POST\";\n\t}\n\n\t// If we have elements to modify, make the request\n\tif ( self.length > 0 ) {\n\t\tjQuery.ajax( {\n\t\t\turl: url,\n\n\t\t\t// If \"type\" variable is undefined, then \"GET\" method will be used.\n\t\t\t// Make value of this field explicit since\n\t\t\t// user can override it through ajaxSetup method\n\t\t\ttype: type || \"GET\",\n\t\t\tdataType: \"html\",\n\t\t\tdata: params\n\t\t} ).done( function( responseText ) {\n\n\t\t\t// Save response for use in complete callback\n\t\t\tresponse = arguments;\n\n\t\t\tself.html( selector ?\n\n\t\t\t\t// If a selector was specified, locate the right elements in a dummy div\n\t\t\t\t// Exclude scripts to avoid IE 'Permission Denied' errors\n\t\t\t\tjQuery( \"<div>\" ).append( jQuery.parseHTML( responseText ) ).find( selector ) :\n\n\t\t\t\t// Otherwise use the full result\n\t\t\t\tresponseText );\n\n\t\t// If the request succeeds, this function gets \"data\", \"status\", \"jqXHR\"\n\t\t// but they are ignored because response was set above.\n\t\t// If it fails, this function gets \"jqXHR\", \"status\", \"error\"\n\t\t} ).always( callback && function( jqXHR, status ) {\n\t\t\tself.each( function() {\n\t\t\t\tcallback.apply( this, response || [ jqXHR.responseText, status, jqXHR ] );\n\t\t\t} );\n\t\t} );\n\t}\n\n\treturn this;\n};\n\n\n\n\n// Attach a bunch of functions for handling common AJAX events\njQuery.each( [\n\t\"ajaxStart\",\n\t\"ajaxStop\",\n\t\"ajaxComplete\",\n\t\"ajaxError\",\n\t\"ajaxSuccess\",\n\t\"ajaxSend\"\n], function( i, type ) {\n\tjQuery.fn[ type ] = function( fn ) {\n\t\treturn this.on( type, fn );\n\t};\n} );\n\n\n\n\njQuery.expr.pseudos.animated = function( elem ) {\n\treturn jQuery.grep( jQuery.timers, function( fn ) {\n\t\treturn elem === fn.elem;\n\t} ).length;\n};\n\n\n\n\n/**\n * Gets a window from an element\n */\nfunction getWindow( elem ) {\n\treturn jQuery.isWindow( elem ) ? elem : elem.nodeType === 9 && elem.defaultView;\n}\n\njQuery.offset = {\n\tsetOffset: function( elem, options, i ) {\n\t\tvar curPosition, curLeft, curCSSTop, curTop, curOffset, curCSSLeft, calculatePosition,\n\t\t\tposition = jQuery.css( elem, \"position\" ),\n\t\t\tcurElem = jQuery( elem ),\n\t\t\tprops = {};\n\n\t\t// Set position first, in-case top/left are set even on static elem\n\t\tif ( position === \"static\" ) {\n\t\t\telem.style.position = \"relative\";\n\t\t}\n\n\t\tcurOffset = curElem.offset();\n\t\tcurCSSTop = jQuery.css( elem, \"top\" );\n\t\tcurCSSLeft = jQuery.css( elem, \"left\" );\n\t\tcalculatePosition = ( position === \"absolute\" || position === \"fixed\" ) &&\n\t\t\t( curCSSTop + curCSSLeft ).indexOf( \"auto\" ) > -1;\n\n\t\t// Need to be able to calculate position if either\n\t\t// top or left is auto and position is either absolute or fixed\n\t\tif ( calculatePosition ) {\n\t\t\tcurPosition = curElem.position();\n\t\t\tcurTop = curPosition.top;\n\t\t\tcurLeft = curPosition.left;\n\n\t\t} else {\n\t\t\tcurTop = parseFloat( curCSSTop ) || 0;\n\t\t\tcurLeft = parseFloat( curCSSLeft ) || 0;\n\t\t}\n\n\t\tif ( jQuery.isFunction( options ) ) {\n\n\t\t\t// Use jQuery.extend here to allow modification of coordinates argument (gh-1848)\n\t\t\toptions = options.call( elem, i, jQuery.extend( {}, curOffset ) );\n\t\t}\n\n\t\tif ( options.top != null ) {\n\t\t\tprops.top = ( options.top - curOffset.top ) + curTop;\n\t\t}\n\t\tif ( options.left != null ) {\n\t\t\tprops.left = ( options.left - curOffset.left ) + curLeft;\n\t\t}\n\n\t\tif ( \"using\" in options ) {\n\t\t\toptions.using.call( elem, props );\n\n\t\t} else {\n\t\t\tcurElem.css( props );\n\t\t}\n\t}\n};\n\njQuery.fn.extend( {\n\toffset: function( options ) {\n\n\t\t// Preserve chaining for setter\n\t\tif ( arguments.length ) {\n\t\t\treturn options === undefined ?\n\t\t\t\tthis :\n\t\t\t\tthis.each( function( i ) {\n\t\t\t\t\tjQuery.offset.setOffset( this, options, i );\n\t\t\t\t} );\n\t\t}\n\n\t\tvar docElem, win, rect, doc,\n\t\t\telem = this[ 0 ];\n\n\t\tif ( !elem ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Support: IE <=11 only\n\t\t// Running getBoundingClientRect on a\n\t\t// disconnected node in IE throws an error\n\t\tif ( !elem.getClientRects().length ) {\n\t\t\treturn { top: 0, left: 0 };\n\t\t}\n\n\t\trect = elem.getBoundingClientRect();\n\n\t\t// Make sure element is not hidden (display: none)\n\t\tif ( rect.width || rect.height ) {\n\t\t\tdoc = elem.ownerDocument;\n\t\t\twin = getWindow( doc );\n\t\t\tdocElem = doc.documentElement;\n\n\t\t\treturn {\n\t\t\t\ttop: rect.top + win.pageYOffset - docElem.clientTop,\n\t\t\t\tleft: rect.left + win.pageXOffset - docElem.clientLeft\n\t\t\t};\n\t\t}\n\n\t\t// Return zeros for disconnected and hidden elements (gh-2310)\n\t\treturn rect;\n\t},\n\n\tposition: function() {\n\t\tif ( !this[ 0 ] ) {\n\t\t\treturn;\n\t\t}\n\n\t\tvar offsetParent, offset,\n\t\t\telem = this[ 0 ],\n\t\t\tparentOffset = { top: 0, left: 0 };\n\n\t\t// Fixed elements are offset from window (parentOffset = {top:0, left: 0},\n\t\t// because it is its only offset parent\n\t\tif ( jQuery.css( elem, \"position\" ) === \"fixed\" ) {\n\n\t\t\t// Assume getBoundingClientRect is there when computed position is fixed\n\t\t\toffset = elem.getBoundingClientRect();\n\n\t\t} else {\n\n\t\t\t// Get *real* offsetParent\n\t\t\toffsetParent = this.offsetParent();\n\n\t\t\t// Get correct offsets\n\t\t\toffset = this.offset();\n\t\t\tif ( !jQuery.nodeName( offsetParent[ 0 ], \"html\" ) ) {\n\t\t\t\tparentOffset = offsetParent.offset();\n\t\t\t}\n\n\t\t\t// Add offsetParent borders\n\t\t\tparentOffset = {\n\t\t\t\ttop: parentOffset.top + jQuery.css( offsetParent[ 0 ], \"borderTopWidth\", true ),\n\t\t\t\tleft: parentOffset.left + jQuery.css( offsetParent[ 0 ], \"borderLeftWidth\", true )\n\t\t\t};\n\t\t}\n\n\t\t// Subtract parent offsets and element margins\n\t\treturn {\n\t\t\ttop: offset.top - parentOffset.top - jQuery.css( elem, \"marginTop\", true ),\n\t\t\tleft: offset.left - parentOffset.left - jQuery.css( elem, \"marginLeft\", true )\n\t\t};\n\t},\n\n\t// This method will return documentElement in the following cases:\n\t// 1) For the element inside the iframe without offsetParent, this method will return\n\t//    documentElement of the parent window\n\t// 2) For the hidden or detached element\n\t// 3) For body or html element, i.e. in case of the html node - it will return itself\n\t//\n\t// but those exceptions were never presented as a real life use-cases\n\t// and might be considered as more preferable results.\n\t//\n\t// This logic, however, is not guaranteed and can change at any point in the future\n\toffsetParent: function() {\n\t\treturn this.map( function() {\n\t\t\tvar offsetParent = this.offsetParent;\n\n\t\t\twhile ( offsetParent && jQuery.css( offsetParent, \"position\" ) === \"static\" ) {\n\t\t\t\toffsetParent = offsetParent.offsetParent;\n\t\t\t}\n\n\t\t\treturn offsetParent || documentElement;\n\t\t} );\n\t}\n} );\n\n// Create scrollLeft and scrollTop methods\njQuery.each( { scrollLeft: \"pageXOffset\", scrollTop: \"pageYOffset\" }, function( method, prop ) {\n\tvar top = \"pageYOffset\" === prop;\n\n\tjQuery.fn[ method ] = function( val ) {\n\t\treturn access( this, function( elem, method, val ) {\n\t\t\tvar win = getWindow( elem );\n\n\t\t\tif ( val === undefined ) {\n\t\t\t\treturn win ? win[ prop ] : elem[ method ];\n\t\t\t}\n\n\t\t\tif ( win ) {\n\t\t\t\twin.scrollTo(\n\t\t\t\t\t!top ? val : win.pageXOffset,\n\t\t\t\t\ttop ? val : win.pageYOffset\n\t\t\t\t);\n\n\t\t\t} else {\n\t\t\t\telem[ method ] = val;\n\t\t\t}\n\t\t}, method, val, arguments.length );\n\t};\n} );\n\n// Support: Safari <=7 - 9.1, Chrome <=37 - 49\n// Add the top/left cssHooks using jQuery.fn.position\n// Webkit bug: https://bugs.webkit.org/show_bug.cgi?id=29084\n// Blink bug: https://bugs.chromium.org/p/chromium/issues/detail?id=589347\n// getComputedStyle returns percent when specified for top/left/bottom/right;\n// rather than make the css module depend on the offset module, just check for it here\njQuery.each( [ \"top\", \"left\" ], function( i, prop ) {\n\tjQuery.cssHooks[ prop ] = addGetHookIf( support.pixelPosition,\n\t\tfunction( elem, computed ) {\n\t\t\tif ( computed ) {\n\t\t\t\tcomputed = curCSS( elem, prop );\n\n\t\t\t\t// If curCSS returns percentage, fallback to offset\n\t\t\t\treturn rnumnonpx.test( computed ) ?\n\t\t\t\t\tjQuery( elem ).position()[ prop ] + \"px\" :\n\t\t\t\t\tcomputed;\n\t\t\t}\n\t\t}\n\t);\n} );\n\n\n// Create innerHeight, innerWidth, height, width, outerHeight and outerWidth methods\njQuery.each( { Height: \"height\", Width: \"width\" }, function( name, type ) {\n\tjQuery.each( { padding: \"inner\" + name, content: type, \"\": \"outer\" + name },\n\t\tfunction( defaultExtra, funcName ) {\n\n\t\t// Margin is only for outerHeight, outerWidth\n\t\tjQuery.fn[ funcName ] = function( margin, value ) {\n\t\t\tvar chainable = arguments.length && ( defaultExtra || typeof margin !== \"boolean\" ),\n\t\t\t\textra = defaultExtra || ( margin === true || value === true ? \"margin\" : \"border\" );\n\n\t\t\treturn access( this, function( elem, type, value ) {\n\t\t\t\tvar doc;\n\n\t\t\t\tif ( jQuery.isWindow( elem ) ) {\n\n\t\t\t\t\t// $( window ).outerWidth/Height return w/h including scrollbars (gh-1729)\n\t\t\t\t\treturn funcName.indexOf( \"outer\" ) === 0 ?\n\t\t\t\t\t\telem[ \"inner\" + name ] :\n\t\t\t\t\t\telem.document.documentElement[ \"client\" + name ];\n\t\t\t\t}\n\n\t\t\t\t// Get document width or height\n\t\t\t\tif ( elem.nodeType === 9 ) {\n\t\t\t\t\tdoc = elem.documentElement;\n\n\t\t\t\t\t// Either scroll[Width/Height] or offset[Width/Height] or client[Width/Height],\n\t\t\t\t\t// whichever is greatest\n\t\t\t\t\treturn Math.max(\n\t\t\t\t\t\telem.body[ \"scroll\" + name ], doc[ \"scroll\" + name ],\n\t\t\t\t\t\telem.body[ \"offset\" + name ], doc[ \"offset\" + name ],\n\t\t\t\t\t\tdoc[ \"client\" + name ]\n\t\t\t\t\t);\n\t\t\t\t}\n\n\t\t\t\treturn value === undefined ?\n\n\t\t\t\t\t// Get width or height on the element, requesting but not forcing parseFloat\n\t\t\t\t\tjQuery.css( elem, type, extra ) :\n\n\t\t\t\t\t// Set width or height on the element\n\t\t\t\t\tjQuery.style( elem, type, value, extra );\n\t\t\t}, type, chainable ? margin : undefined, chainable );\n\t\t};\n\t} );\n} );\n\n\njQuery.fn.extend( {\n\n\tbind: function( types, data, fn ) {\n\t\treturn this.on( types, null, data, fn );\n\t},\n\tunbind: function( types, fn ) {\n\t\treturn this.off( types, null, fn );\n\t},\n\n\tdelegate: function( selector, types, data, fn ) {\n\t\treturn this.on( types, selector, data, fn );\n\t},\n\tundelegate: function( selector, types, fn ) {\n\n\t\t// ( namespace ) or ( selector, types [, fn] )\n\t\treturn arguments.length === 1 ?\n\t\t\tthis.off( selector, \"**\" ) :\n\t\t\tthis.off( types, selector || \"**\", fn );\n\t}\n} );\n\njQuery.parseJSON = JSON.parse;\n\n\n\n\n// Register as a named AMD module, since jQuery can be concatenated with other\n// files that may use define, but not via a proper concatenation script that\n// understands anonymous AMD modules. A named AMD is safest and most robust\n// way to register. Lowercase jquery is used because AMD module names are\n// derived from file names, and jQuery is normally delivered in a lowercase\n// file name. Do this after creating the global so that if an AMD module wants\n// to call noConflict to hide this version of jQuery, it will work.\n\n// Note that for maximum portability, libraries that are not jQuery should\n// declare themselves as anonymous modules, and avoid setting a global if an\n// AMD loader is present. jQuery is a special case. For more information, see\n// https://github.com/jrburke/requirejs/wiki/Updating-existing-libraries#wiki-anon\n\nif ( typeof define === \"function\" && define.amd ) {\n\tdefine( \"jquery\", [], function() {\n\t\treturn jQuery;\n\t} );\n}\n\n\n\n\n\nvar\n\n\t// Map over jQuery in case of overwrite\n\t_jQuery = window.jQuery,\n\n\t// Map over the $ in case of overwrite\n\t_$ = window.$;\n\njQuery.noConflict = function( deep ) {\n\tif ( window.$ === jQuery ) {\n\t\twindow.$ = _$;\n\t}\n\n\tif ( deep && window.jQuery === jQuery ) {\n\t\twindow.jQuery = _jQuery;\n\t}\n\n\treturn jQuery;\n};\n\n// Expose jQuery and $ identifiers, even in AMD\n// (#7102#comment:10, https://github.com/jquery/jquery/pull/557)\n// and CommonJS for browser emulators (#13566)\nif ( !noGlobal ) {\n\twindow.jQuery = window.$ = jQuery;\n}\n\n\nreturn jQuery;\n} );\n"
  },
  {
    "path": "app_backend/vendor/metisMenu/metisMenu.css",
    "content": "/*\n * metismenu - v1.1.3\n * Easy menu jQuery plugin for Twitter Bootstrap 3\n * https://github.com/onokumus/metisMenu\n *\n * Made by Osman Nuri Okumus\n * Under MIT License\n */\n.arrow {\n    float: right;\n    line-height: 1.42857;\n}\n\n.glyphicon.arrow:before {\n    content: \"\\e079\";\n}\n\n.active > a > .glyphicon.arrow:before {\n    content: \"\\e114\";\n}\n\n\n/*\n * Require Font-Awesome\n * http://fortawesome.github.io/Font-Awesome/\n*/\n\n\n.fa.arrow:before {\n    content: \"\\f104\";\n}\n\n.active > a > .fa.arrow:before {\n    content: \"\\f107\";\n}\n\n.plus-times {\n    float: right;\n}\n\n.fa.plus-times:before {\n    content: \"\\f067\";\n}\n\n.active > a > .fa.plus-times {\n    filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=1);\n    -webkit-transform: rotate(45deg);\n    -moz-transform: rotate(45deg);\n    -ms-transform: rotate(45deg);\n    -o-transform: rotate(45deg);\n    transform: rotate(45deg);\n}\n\n.plus-minus {\n    float: right;\n}\n\n.fa.plus-minus:before {\n    content: \"\\f067\";\n}\n\n.active > a > .fa.plus-minus:before {\n    content: \"\\f068\";\n}"
  },
  {
    "path": "app_backend/vendor/metisMenu/metisMenu.js",
    "content": "/*\n * metismenu - v1.1.3\n * Easy menu jQuery plugin for Twitter Bootstrap 3\n * https://github.com/onokumus/metisMenu\n *\n * Made by Osman Nuri Okumus\n * Under MIT License\n */\n;(function($, window, document, undefined) {\n\n    var pluginName = \"metisMenu\",\n        defaults = {\n            toggle: true,\n            doubleTapToGo: false\n        };\n\n    function Plugin(element, options) {\n        this.element = $(element);\n        this.settings = $.extend({}, defaults, options);\n        this._defaults = defaults;\n        this._name = pluginName;\n        this.init();\n    }\n\n    Plugin.prototype = {\n        init: function() {\n\n            var $this = this.element,\n                $toggle = this.settings.toggle,\n                obj = this;\n\n            if (this.isIE() <= 9) {\n                $this.find(\"li.active\").has(\"ul\").children(\"ul\").collapse(\"show\");\n                $this.find(\"li\").not(\".active\").has(\"ul\").children(\"ul\").collapse(\"hide\");\n            } else {\n                $this.find(\"li.active\").has(\"ul\").children(\"ul\").addClass(\"collapse in\");\n                $this.find(\"li\").not(\".active\").has(\"ul\").children(\"ul\").addClass(\"collapse\");\n            }\n\n            //add the \"doubleTapToGo\" class to active items if needed\n            if (obj.settings.doubleTapToGo) {\n                $this.find(\"li.active\").has(\"ul\").children(\"a\").addClass(\"doubleTapToGo\");\n            }\n\n            $this.find(\"li\").has(\"ul\").children(\"a\").on(\"click\" + \".\" + pluginName, function(e) {\n                e.preventDefault();\n\n                //Do we need to enable the double tap\n                if (obj.settings.doubleTapToGo) {\n\n                    //if we hit a second time on the link and the href is valid, navigate to that url\n                    if (obj.doubleTapToGo($(this)) && $(this).attr(\"href\") !== \"#\" && $(this).attr(\"href\") !== \"\") {\n                        e.stopPropagation();\n                        document.location = $(this).attr(\"href\");\n                        return;\n                    }\n                }\n\n                $(this).parent(\"li\").toggleClass(\"active\").children(\"ul\").collapse(\"toggle\");\n\n                if ($toggle) {\n                    $(this).parent(\"li\").siblings().removeClass(\"active\").children(\"ul.in\").collapse(\"hide\");\n                }\n\n            });\n        },\n\n        isIE: function() { //https://gist.github.com/padolsey/527683\n            var undef,\n                v = 3,\n                div = document.createElement(\"div\"),\n                all = div.getElementsByTagName(\"i\");\n\n            while (\n                div.innerHTML = \"<!--[if gt IE \" + (++v) + \"]><i></i><![endif]-->\",\n                all[0]\n            ) {\n                return v > 4 ? v : undef;\n            }\n        },\n\n        //Enable the link on the second click.\n        doubleTapToGo: function(elem) {\n            var $this = this.element;\n\n            //if the class \"doubleTapToGo\" exists, remove it and return\n            if (elem.hasClass(\"doubleTapToGo\")) {\n                elem.removeClass(\"doubleTapToGo\");\n                return true;\n            }\n\n            //does not exists, add a new class and return false\n            if (elem.parent().children(\"ul\").length) {\n                 //first remove all other class\n                $this.find(\".doubleTapToGo\").removeClass(\"doubleTapToGo\");\n                //add the class on the current element\n                elem.addClass(\"doubleTapToGo\");\n                return false;\n            }\n        },\n\n        remove: function() {\n            this.element.off(\".\" + pluginName);\n            this.element.removeData(pluginName);\n        }\n\n    };\n\n    $.fn[pluginName] = function(options) {\n        this.each(function () {\n            var el = $(this);\n            if (el.data(pluginName)) {\n                el.data(pluginName).remove();\n            }\n            el.data(pluginName, new Plugin(this, options));\n        });\n        return this;\n    };\n\n})(jQuery, window, document);"
  },
  {
    "path": "app_backend/vendor/morrisjs/morris.css",
    "content": ".morris-hover{position:absolute;z-index:1000}.morris-hover.morris-default-style{border-radius:10px;padding:6px;color:#666;background:rgba(255,255,255,0.8);border:solid 2px rgba(230,230,230,0.8);font-family:sans-serif;font-size:12px;text-align:center}.morris-hover.morris-default-style .morris-hover-row-label{font-weight:bold;margin:0.25em 0}\n.morris-hover.morris-default-style .morris-hover-point{white-space:nowrap;margin:0.1em 0}\n"
  },
  {
    "path": "app_backend/vendor/morrisjs/morris.js",
    "content": "/* @license\nmorris.js v0.5.0\nCopyright 2014 Olly Smith All rights reserved.\nLicensed under the BSD-2-Clause License.\n*/\n\n\n(function() {\n  var $, Morris, minutesSpecHelper, secondsSpecHelper,\n    __slice = [].slice,\n    __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; },\n    __hasProp = {}.hasOwnProperty,\n    __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },\n    __indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; };\n\n  Morris = window.Morris = {};\n\n  $ = jQuery;\n\n  Morris.EventEmitter = (function() {\n    function EventEmitter() {}\n\n    EventEmitter.prototype.on = function(name, handler) {\n      if (this.handlers == null) {\n        this.handlers = {};\n      }\n      if (this.handlers[name] == null) {\n        this.handlers[name] = [];\n      }\n      this.handlers[name].push(handler);\n      return this;\n    };\n\n    EventEmitter.prototype.fire = function() {\n      var args, handler, name, _i, _len, _ref, _results;\n      name = arguments[0], args = 2 <= arguments.length ? __slice.call(arguments, 1) : [];\n      if ((this.handlers != null) && (this.handlers[name] != null)) {\n        _ref = this.handlers[name];\n        _results = [];\n        for (_i = 0, _len = _ref.length; _i < _len; _i++) {\n          handler = _ref[_i];\n          _results.push(handler.apply(null, args));\n        }\n        return _results;\n      }\n    };\n\n    return EventEmitter;\n\n  })();\n\n  Morris.commas = function(num) {\n    var absnum, intnum, ret, strabsnum;\n    if (num != null) {\n      ret = num < 0 ? \"-\" : \"\";\n      absnum = Math.abs(num);\n      intnum = Math.floor(absnum).toFixed(0);\n      ret += intnum.replace(/(?=(?:\\d{3})+$)(?!^)/g, ',');\n      strabsnum = absnum.toString();\n      if (strabsnum.length > intnum.length) {\n        ret += strabsnum.slice(intnum.length);\n      }\n      return ret;\n    } else {\n      return '-';\n    }\n  };\n\n  Morris.pad2 = function(number) {\n    return (number < 10 ? '0' : '') + number;\n  };\n\n  Morris.Grid = (function(_super) {\n    __extends(Grid, _super);\n\n    function Grid(options) {\n      this.resizeHandler = __bind(this.resizeHandler, this);\n      var _this = this;\n      if (typeof options.element === 'string') {\n        this.el = $(document.getElementById(options.element));\n      } else {\n        this.el = $(options.element);\n      }\n      if ((this.el == null) || this.el.length === 0) {\n        throw new Error(\"Graph container element not found\");\n      }\n      if (this.el.css('position') === 'static') {\n        this.el.css('position', 'relative');\n      }\n      this.options = $.extend({}, this.gridDefaults, this.defaults || {}, options);\n      if (typeof this.options.units === 'string') {\n        this.options.postUnits = options.units;\n      }\n      this.raphael = new Raphael(this.el[0]);\n      this.elementWidth = null;\n      this.elementHeight = null;\n      this.dirty = false;\n      this.selectFrom = null;\n      if (this.init) {\n        this.init();\n      }\n      this.setData(this.options.data);\n      this.el.bind('mousemove', function(evt) {\n        var left, offset, right, width, x;\n        offset = _this.el.offset();\n        x = evt.pageX - offset.left;\n        if (_this.selectFrom) {\n          left = _this.data[_this.hitTest(Math.min(x, _this.selectFrom))]._x;\n          right = _this.data[_this.hitTest(Math.max(x, _this.selectFrom))]._x;\n          width = right - left;\n          return _this.selectionRect.attr({\n            x: left,\n            width: width\n          });\n        } else {\n          return _this.fire('hovermove', x, evt.pageY - offset.top);\n        }\n      });\n      this.el.bind('mouseleave', function(evt) {\n        if (_this.selectFrom) {\n          _this.selectionRect.hide();\n          _this.selectFrom = null;\n        }\n        return _this.fire('hoverout');\n      });\n      this.el.bind('touchstart touchmove touchend', function(evt) {\n        var offset, touch;\n        touch = evt.originalEvent.touches[0] || evt.originalEvent.changedTouches[0];\n        offset = _this.el.offset();\n        return _this.fire('hovermove', touch.pageX - offset.left, touch.pageY - offset.top);\n      });\n      this.el.bind('click', function(evt) {\n        var offset;\n        offset = _this.el.offset();\n        return _this.fire('gridclick', evt.pageX - offset.left, evt.pageY - offset.top);\n      });\n      if (this.options.rangeSelect) {\n        this.selectionRect = this.raphael.rect(0, 0, 0, this.el.innerHeight()).attr({\n          fill: this.options.rangeSelectColor,\n          stroke: false\n        }).toBack().hide();\n        this.el.bind('mousedown', function(evt) {\n          var offset;\n          offset = _this.el.offset();\n          return _this.startRange(evt.pageX - offset.left);\n        });\n        this.el.bind('mouseup', function(evt) {\n          var offset;\n          offset = _this.el.offset();\n          _this.endRange(evt.pageX - offset.left);\n          return _this.fire('hovermove', evt.pageX - offset.left, evt.pageY - offset.top);\n        });\n      }\n      if (this.options.resize) {\n        $(window).bind('resize', function(evt) {\n          if (_this.timeoutId != null) {\n            window.clearTimeout(_this.timeoutId);\n          }\n          return _this.timeoutId = window.setTimeout(_this.resizeHandler, 100);\n        });\n      }\n      this.el.css('-webkit-tap-highlight-color', 'rgba(0,0,0,0)');\n      if (this.postInit) {\n        this.postInit();\n      }\n    }\n\n    Grid.prototype.gridDefaults = {\n      dateFormat: null,\n      axes: true,\n      grid: true,\n      gridLineColor: '#aaa',\n      gridStrokeWidth: 0.5,\n      gridTextColor: '#888',\n      gridTextSize: 12,\n      gridTextFamily: 'sans-serif',\n      gridTextWeight: 'normal',\n      hideHover: false,\n      yLabelFormat: null,\n      xLabelAngle: 0,\n      numLines: 5,\n      padding: 25,\n      parseTime: true,\n      postUnits: '',\n      preUnits: '',\n      ymax: 'auto',\n      ymin: 'auto 0',\n      goals: [],\n      goalStrokeWidth: 1.0,\n      goalLineColors: ['#666633', '#999966', '#cc6666', '#663333'],\n      events: [],\n      eventStrokeWidth: 1.0,\n      eventLineColors: ['#005a04', '#ccffbb', '#3a5f0b', '#005502'],\n      rangeSelect: null,\n      rangeSelectColor: '#eef',\n      resize: false\n    };\n\n    Grid.prototype.setData = function(data, redraw) {\n      var e, idx, index, maxGoal, minGoal, ret, row, step, total, y, ykey, ymax, ymin, yval, _ref;\n      if (redraw == null) {\n        redraw = true;\n      }\n      this.options.data = data;\n      if ((data == null) || data.length === 0) {\n        this.data = [];\n        this.raphael.clear();\n        if (this.hover != null) {\n          this.hover.hide();\n        }\n        return;\n      }\n      ymax = this.cumulative ? 0 : null;\n      ymin = this.cumulative ? 0 : null;\n      if (this.options.goals.length > 0) {\n        minGoal = Math.min.apply(Math, this.options.goals);\n        maxGoal = Math.max.apply(Math, this.options.goals);\n        ymin = ymin != null ? Math.min(ymin, minGoal) : minGoal;\n        ymax = ymax != null ? Math.max(ymax, maxGoal) : maxGoal;\n      }\n      this.data = (function() {\n        var _i, _len, _results;\n        _results = [];\n        for (index = _i = 0, _len = data.length; _i < _len; index = ++_i) {\n          row = data[index];\n          ret = {\n            src: row\n          };\n          ret.label = row[this.options.xkey];\n          if (this.options.parseTime) {\n            ret.x = Morris.parseDate(ret.label);\n            if (this.options.dateFormat) {\n              ret.label = this.options.dateFormat(ret.x);\n            } else if (typeof ret.label === 'number') {\n              ret.label = new Date(ret.label).toString();\n            }\n          } else {\n            ret.x = index;\n            if (this.options.xLabelFormat) {\n              ret.label = this.options.xLabelFormat(ret);\n            }\n          }\n          total = 0;\n          ret.y = (function() {\n            var _j, _len1, _ref, _results1;\n            _ref = this.options.ykeys;\n            _results1 = [];\n            for (idx = _j = 0, _len1 = _ref.length; _j < _len1; idx = ++_j) {\n              ykey = _ref[idx];\n              yval = row[ykey];\n              if (typeof yval === 'string') {\n                yval = parseFloat(yval);\n              }\n              if ((yval != null) && typeof yval !== 'number') {\n                yval = null;\n              }\n              if (yval != null) {\n                if (this.cumulative) {\n                  total += yval;\n                } else {\n                  if (ymax != null) {\n                    ymax = Math.max(yval, ymax);\n                    ymin = Math.min(yval, ymin);\n                  } else {\n                    ymax = ymin = yval;\n                  }\n                }\n              }\n              if (this.cumulative && (total != null)) {\n                ymax = Math.max(total, ymax);\n                ymin = Math.min(total, ymin);\n              }\n              _results1.push(yval);\n            }\n            return _results1;\n          }).call(this);\n          _results.push(ret);\n        }\n        return _results;\n      }).call(this);\n      if (this.options.parseTime) {\n        this.data = this.data.sort(function(a, b) {\n          return (a.x > b.x) - (b.x > a.x);\n        });\n      }\n      this.xmin = this.data[0].x;\n      this.xmax = this.data[this.data.length - 1].x;\n      this.events = [];\n      if (this.options.events.length > 0) {\n        if (this.options.parseTime) {\n          this.events = (function() {\n            var _i, _len, _ref, _results;\n            _ref = this.options.events;\n            _results = [];\n            for (_i = 0, _len = _ref.length; _i < _len; _i++) {\n              e = _ref[_i];\n              _results.push(Morris.parseDate(e));\n            }\n            return _results;\n          }).call(this);\n        } else {\n          this.events = this.options.events;\n        }\n        this.xmax = Math.max(this.xmax, Math.max.apply(Math, this.events));\n        this.xmin = Math.min(this.xmin, Math.min.apply(Math, this.events));\n      }\n      if (this.xmin === this.xmax) {\n        this.xmin -= 1;\n        this.xmax += 1;\n      }\n      this.ymin = this.yboundary('min', ymin);\n      this.ymax = this.yboundary('max', ymax);\n      if (this.ymin === this.ymax) {\n        if (ymin) {\n          this.ymin -= 1;\n        }\n        this.ymax += 1;\n      }\n      if (((_ref = this.options.axes) === true || _ref === 'both' || _ref === 'y') || this.options.grid === true) {\n        if (this.options.ymax === this.gridDefaults.ymax && this.options.ymin === this.gridDefaults.ymin) {\n          this.grid = this.autoGridLines(this.ymin, this.ymax, this.options.numLines);\n          this.ymin = Math.min(this.ymin, this.grid[0]);\n          this.ymax = Math.max(this.ymax, this.grid[this.grid.length - 1]);\n        } else {\n          step = (this.ymax - this.ymin) / (this.options.numLines - 1);\n          this.grid = (function() {\n            var _i, _ref1, _ref2, _results;\n            _results = [];\n            for (y = _i = _ref1 = this.ymin, _ref2 = this.ymax; step > 0 ? _i <= _ref2 : _i >= _ref2; y = _i += step) {\n              _results.push(y);\n            }\n            return _results;\n          }).call(this);\n        }\n      }\n      this.dirty = true;\n      if (redraw) {\n        return this.redraw();\n      }\n    };\n\n    Grid.prototype.yboundary = function(boundaryType, currentValue) {\n      var boundaryOption, suggestedValue;\n      boundaryOption = this.options[\"y\" + boundaryType];\n      if (typeof boundaryOption === 'string') {\n        if (boundaryOption.slice(0, 4) === 'auto') {\n          if (boundaryOption.length > 5) {\n            suggestedValue = parseInt(boundaryOption.slice(5), 10);\n            if (currentValue == null) {\n              return suggestedValue;\n            }\n            return Math[boundaryType](currentValue, suggestedValue);\n          } else {\n            if (currentValue != null) {\n              return currentValue;\n            } else {\n              return 0;\n            }\n          }\n        } else {\n          return parseInt(boundaryOption, 10);\n        }\n      } else {\n        return boundaryOption;\n      }\n    };\n\n    Grid.prototype.autoGridLines = function(ymin, ymax, nlines) {\n      var gmax, gmin, grid, smag, span, step, unit, y, ymag;\n      span = ymax - ymin;\n      ymag = Math.floor(Math.log(span) / Math.log(10));\n      unit = Math.pow(10, ymag);\n      gmin = Math.floor(ymin / unit) * unit;\n      gmax = Math.ceil(ymax / unit) * unit;\n      step = (gmax - gmin) / (nlines - 1);\n      if (unit === 1 && step > 1 && Math.ceil(step) !== step) {\n        step = Math.ceil(step);\n        gmax = gmin + step * (nlines - 1);\n      }\n      if (gmin < 0 && gmax > 0) {\n        gmin = Math.floor(ymin / step) * step;\n        gmax = Math.ceil(ymax / step) * step;\n      }\n      if (step < 1) {\n        smag = Math.floor(Math.log(step) / Math.log(10));\n        grid = (function() {\n          var _i, _results;\n          _results = [];\n          for (y = _i = gmin; step > 0 ? _i <= gmax : _i >= gmax; y = _i += step) {\n            _results.push(parseFloat(y.toFixed(1 - smag)));\n          }\n          return _results;\n        })();\n      } else {\n        grid = (function() {\n          var _i, _results;\n          _results = [];\n          for (y = _i = gmin; step > 0 ? _i <= gmax : _i >= gmax; y = _i += step) {\n            _results.push(y);\n          }\n          return _results;\n        })();\n      }\n      return grid;\n    };\n\n    Grid.prototype._calc = function() {\n      var bottomOffsets, gridLine, h, i, w, yLabelWidths, _ref, _ref1;\n      w = this.el.width();\n      h = this.el.height();\n      if (this.elementWidth !== w || this.elementHeight !== h || this.dirty) {\n        this.elementWidth = w;\n        this.elementHeight = h;\n        this.dirty = false;\n        this.left = this.options.padding;\n        this.right = this.elementWidth - this.options.padding;\n        this.top = this.options.padding;\n        this.bottom = this.elementHeight - this.options.padding;\n        if ((_ref = this.options.axes) === true || _ref === 'both' || _ref === 'y') {\n          yLabelWidths = (function() {\n            var _i, _len, _ref1, _results;\n            _ref1 = this.grid;\n            _results = [];\n            for (_i = 0, _len = _ref1.length; _i < _len; _i++) {\n              gridLine = _ref1[_i];\n              _results.push(this.measureText(this.yAxisFormat(gridLine)).width);\n            }\n            return _results;\n          }).call(this);\n          this.left += Math.max.apply(Math, yLabelWidths);\n        }\n        if ((_ref1 = this.options.axes) === true || _ref1 === 'both' || _ref1 === 'x') {\n          bottomOffsets = (function() {\n            var _i, _ref2, _results;\n            _results = [];\n            for (i = _i = 0, _ref2 = this.data.length; 0 <= _ref2 ? _i < _ref2 : _i > _ref2; i = 0 <= _ref2 ? ++_i : --_i) {\n              _results.push(this.measureText(this.data[i].text, -this.options.xLabelAngle).height);\n            }\n            return _results;\n          }).call(this);\n          this.bottom -= Math.max.apply(Math, bottomOffsets);\n        }\n        this.width = Math.max(1, this.right - this.left);\n        this.height = Math.max(1, this.bottom - this.top);\n        this.dx = this.width / (this.xmax - this.xmin);\n        this.dy = this.height / (this.ymax - this.ymin);\n        if (this.calc) {\n          return this.calc();\n        }\n      }\n    };\n\n    Grid.prototype.transY = function(y) {\n      return this.bottom - (y - this.ymin) * this.dy;\n    };\n\n    Grid.prototype.transX = function(x) {\n      if (this.data.length === 1) {\n        return (this.left + this.right) / 2;\n      } else {\n        return this.left + (x - this.xmin) * this.dx;\n      }\n    };\n\n    Grid.prototype.redraw = function() {\n      this.raphael.clear();\n      this._calc();\n      this.drawGrid();\n      this.drawGoals();\n      this.drawEvents();\n      if (this.draw) {\n        return this.draw();\n      }\n    };\n\n    Grid.prototype.measureText = function(text, angle) {\n      var ret, tt;\n      if (angle == null) {\n        angle = 0;\n      }\n      tt = this.raphael.text(100, 100, text).attr('font-size', this.options.gridTextSize).attr('font-family', this.options.gridTextFamily).attr('font-weight', this.options.gridTextWeight).rotate(angle);\n      ret = tt.getBBox();\n      tt.remove();\n      return ret;\n    };\n\n    Grid.prototype.yAxisFormat = function(label) {\n      return this.yLabelFormat(label);\n    };\n\n    Grid.prototype.yLabelFormat = function(label) {\n      if (typeof this.options.yLabelFormat === 'function') {\n        return this.options.yLabelFormat(label);\n      } else {\n        return \"\" + this.options.preUnits + (Morris.commas(label)) + this.options.postUnits;\n      }\n    };\n\n    Grid.prototype.drawGrid = function() {\n      var lineY, y, _i, _len, _ref, _ref1, _ref2, _results;\n      if (this.options.grid === false && ((_ref = this.options.axes) !== true && _ref !== 'both' && _ref !== 'y')) {\n        return;\n      }\n      _ref1 = this.grid;\n      _results = [];\n      for (_i = 0, _len = _ref1.length; _i < _len; _i++) {\n        lineY = _ref1[_i];\n        y = this.transY(lineY);\n        if ((_ref2 = this.options.axes) === true || _ref2 === 'both' || _ref2 === 'y') {\n          this.drawYAxisLabel(this.left - this.options.padding / 2, y, this.yAxisFormat(lineY));\n        }\n        if (this.options.grid) {\n          _results.push(this.drawGridLine(\"M\" + this.left + \",\" + y + \"H\" + (this.left + this.width)));\n        } else {\n          _results.push(void 0);\n        }\n      }\n      return _results;\n    };\n\n    Grid.prototype.drawGoals = function() {\n      var color, goal, i, _i, _len, _ref, _results;\n      _ref = this.options.goals;\n      _results = [];\n      for (i = _i = 0, _len = _ref.length; _i < _len; i = ++_i) {\n        goal = _ref[i];\n        color = this.options.goalLineColors[i % this.options.goalLineColors.length];\n        _results.push(this.drawGoal(goal, color));\n      }\n      return _results;\n    };\n\n    Grid.prototype.drawEvents = function() {\n      var color, event, i, _i, _len, _ref, _results;\n      _ref = this.events;\n      _results = [];\n      for (i = _i = 0, _len = _ref.length; _i < _len; i = ++_i) {\n        event = _ref[i];\n        color = this.options.eventLineColors[i % this.options.eventLineColors.length];\n        _results.push(this.drawEvent(event, color));\n      }\n      return _results;\n    };\n\n    Grid.prototype.drawGoal = function(goal, color) {\n      return this.raphael.path(\"M\" + this.left + \",\" + (this.transY(goal)) + \"H\" + this.right).attr('stroke', color).attr('stroke-width', this.options.goalStrokeWidth);\n    };\n\n    Grid.prototype.drawEvent = function(event, color) {\n      return this.raphael.path(\"M\" + (this.transX(event)) + \",\" + this.bottom + \"V\" + this.top).attr('stroke', color).attr('stroke-width', this.options.eventStrokeWidth);\n    };\n\n    Grid.prototype.drawYAxisLabel = function(xPos, yPos, text) {\n      return this.raphael.text(xPos, yPos, text).attr('font-size', this.options.gridTextSize).attr('font-family', this.options.gridTextFamily).attr('font-weight', this.options.gridTextWeight).attr('fill', this.options.gridTextColor).attr('text-anchor', 'end');\n    };\n\n    Grid.prototype.drawGridLine = function(path) {\n      return this.raphael.path(path).attr('stroke', this.options.gridLineColor).attr('stroke-width', this.options.gridStrokeWidth);\n    };\n\n    Grid.prototype.startRange = function(x) {\n      this.hover.hide();\n      this.selectFrom = x;\n      return this.selectionRect.attr({\n        x: x,\n        width: 0\n      }).show();\n    };\n\n    Grid.prototype.endRange = function(x) {\n      var end, start;\n      if (this.selectFrom) {\n        start = Math.min(this.selectFrom, x);\n        end = Math.max(this.selectFrom, x);\n        this.options.rangeSelect.call(this.el, {\n          start: this.data[this.hitTest(start)].x,\n          end: this.data[this.hitTest(end)].x\n        });\n        return this.selectFrom = null;\n      }\n    };\n\n    Grid.prototype.resizeHandler = function() {\n      this.timeoutId = null;\n      this.raphael.setSize(this.el.width(), this.el.height());\n      return this.redraw();\n    };\n\n    return Grid;\n\n  })(Morris.EventEmitter);\n\n  Morris.parseDate = function(date) {\n    var isecs, m, msecs, n, o, offsetmins, p, q, r, ret, secs;\n    if (typeof date === 'number') {\n      return date;\n    }\n    m = date.match(/^(\\d+) Q(\\d)$/);\n    n = date.match(/^(\\d+)-(\\d+)$/);\n    o = date.match(/^(\\d+)-(\\d+)-(\\d+)$/);\n    p = date.match(/^(\\d+) W(\\d+)$/);\n    q = date.match(/^(\\d+)-(\\d+)-(\\d+)[ T](\\d+):(\\d+)(Z|([+-])(\\d\\d):?(\\d\\d))?$/);\n    r = date.match(/^(\\d+)-(\\d+)-(\\d+)[ T](\\d+):(\\d+):(\\d+(\\.\\d+)?)(Z|([+-])(\\d\\d):?(\\d\\d))?$/);\n    if (m) {\n      return new Date(parseInt(m[1], 10), parseInt(m[2], 10) * 3 - 1, 1).getTime();\n    } else if (n) {\n      return new Date(parseInt(n[1], 10), parseInt(n[2], 10) - 1, 1).getTime();\n    } else if (o) {\n      return new Date(parseInt(o[1], 10), parseInt(o[2], 10) - 1, parseInt(o[3], 10)).getTime();\n    } else if (p) {\n      ret = new Date(parseInt(p[1], 10), 0, 1);\n      if (ret.getDay() !== 4) {\n        ret.setMonth(0, 1 + ((4 - ret.getDay()) + 7) % 7);\n      }\n      return ret.getTime() + parseInt(p[2], 10) * 604800000;\n    } else if (q) {\n      if (!q[6]) {\n        return new Date(parseInt(q[1], 10), parseInt(q[2], 10) - 1, parseInt(q[3], 10), parseInt(q[4], 10), parseInt(q[5], 10)).getTime();\n      } else {\n        offsetmins = 0;\n        if (q[6] !== 'Z') {\n          offsetmins = parseInt(q[8], 10) * 60 + parseInt(q[9], 10);\n          if (q[7] === '+') {\n            offsetmins = 0 - offsetmins;\n          }\n        }\n        return Date.UTC(parseInt(q[1], 10), parseInt(q[2], 10) - 1, parseInt(q[3], 10), parseInt(q[4], 10), parseInt(q[5], 10) + offsetmins);\n      }\n    } else if (r) {\n      secs = parseFloat(r[6]);\n      isecs = Math.floor(secs);\n      msecs = Math.round((secs - isecs) * 1000);\n      if (!r[8]) {\n        return new Date(parseInt(r[1], 10), parseInt(r[2], 10) - 1, parseInt(r[3], 10), parseInt(r[4], 10), parseInt(r[5], 10), isecs, msecs).getTime();\n      } else {\n        offsetmins = 0;\n        if (r[8] !== 'Z') {\n          offsetmins = parseInt(r[10], 10) * 60 + parseInt(r[11], 10);\n          if (r[9] === '+') {\n            offsetmins = 0 - offsetmins;\n          }\n        }\n        return Date.UTC(parseInt(r[1], 10), parseInt(r[2], 10) - 1, parseInt(r[3], 10), parseInt(r[4], 10), parseInt(r[5], 10) + offsetmins, isecs, msecs);\n      }\n    } else {\n      return new Date(parseInt(date, 10), 0, 1).getTime();\n    }\n  };\n\n  Morris.Hover = (function() {\n    Hover.defaults = {\n      \"class\": 'morris-hover morris-default-style'\n    };\n\n    function Hover(options) {\n      if (options == null) {\n        options = {};\n      }\n      this.options = $.extend({}, Morris.Hover.defaults, options);\n      this.el = $(\"<div class='\" + this.options[\"class\"] + \"'></div>\");\n      this.el.hide();\n      this.options.parent.append(this.el);\n    }\n\n    Hover.prototype.update = function(html, x, y) {\n      if (!html) {\n        return this.hide();\n      } else {\n        this.html(html);\n        this.show();\n        return this.moveTo(x, y);\n      }\n    };\n\n    Hover.prototype.html = function(content) {\n      return this.el.html(content);\n    };\n\n    Hover.prototype.moveTo = function(x, y) {\n      var hoverHeight, hoverWidth, left, parentHeight, parentWidth, top;\n      parentWidth = this.options.parent.innerWidth();\n      parentHeight = this.options.parent.innerHeight();\n      hoverWidth = this.el.outerWidth();\n      hoverHeight = this.el.outerHeight();\n      left = Math.min(Math.max(0, x - hoverWidth / 2), parentWidth - hoverWidth);\n      if (y != null) {\n        top = y - hoverHeight - 10;\n        if (top < 0) {\n          top = y + 10;\n          if (top + hoverHeight > parentHeight) {\n            top = parentHeight / 2 - hoverHeight / 2;\n          }\n        }\n      } else {\n        top = parentHeight / 2 - hoverHeight / 2;\n      }\n      return this.el.css({\n        left: left + \"px\",\n        top: parseInt(top) + \"px\"\n      });\n    };\n\n    Hover.prototype.show = function() {\n      return this.el.show();\n    };\n\n    Hover.prototype.hide = function() {\n      return this.el.hide();\n    };\n\n    return Hover;\n\n  })();\n\n  Morris.Line = (function(_super) {\n    __extends(Line, _super);\n\n    function Line(options) {\n      this.hilight = __bind(this.hilight, this);\n      this.onHoverOut = __bind(this.onHoverOut, this);\n      this.onHoverMove = __bind(this.onHoverMove, this);\n      this.onGridClick = __bind(this.onGridClick, this);\n      if (!(this instanceof Morris.Line)) {\n        return new Morris.Line(options);\n      }\n      Line.__super__.constructor.call(this, options);\n    }\n\n    Line.prototype.init = function() {\n      if (this.options.hideHover !== 'always') {\n        this.hover = new Morris.Hover({\n          parent: this.el\n        });\n        this.on('hovermove', this.onHoverMove);\n        this.on('hoverout', this.onHoverOut);\n        return this.on('gridclick', this.onGridClick);\n      }\n    };\n\n    Line.prototype.defaults = {\n      lineWidth: 3,\n      pointSize: 4,\n      lineColors: ['#0b62a4', '#7A92A3', '#4da74d', '#afd8f8', '#edc240', '#cb4b4b', '#9440ed'],\n      pointStrokeWidths: [1],\n      pointStrokeColors: ['#ffffff'],\n      pointFillColors: [],\n      smooth: true,\n      xLabels: 'auto',\n      xLabelFormat: null,\n      xLabelMargin: 24,\n      hideHover: false\n    };\n\n    Line.prototype.calc = function() {\n      this.calcPoints();\n      return this.generatePaths();\n    };\n\n    Line.prototype.calcPoints = function() {\n      var row, y, _i, _len, _ref, _results;\n      _ref = this.data;\n      _results = [];\n      for (_i = 0, _len = _ref.length; _i < _len; _i++) {\n        row = _ref[_i];\n        row._x = this.transX(row.x);\n        row._y = (function() {\n          var _j, _len1, _ref1, _results1;\n          _ref1 = row.y;\n          _results1 = [];\n          for (_j = 0, _len1 = _ref1.length; _j < _len1; _j++) {\n            y = _ref1[_j];\n            if (y != null) {\n              _results1.push(this.transY(y));\n            } else {\n              _results1.push(y);\n            }\n          }\n          return _results1;\n        }).call(this);\n        _results.push(row._ymax = Math.min.apply(Math, [this.bottom].concat((function() {\n          var _j, _len1, _ref1, _results1;\n          _ref1 = row._y;\n          _results1 = [];\n          for (_j = 0, _len1 = _ref1.length; _j < _len1; _j++) {\n            y = _ref1[_j];\n            if (y != null) {\n              _results1.push(y);\n            }\n          }\n          return _results1;\n        })())));\n      }\n      return _results;\n    };\n\n    Line.prototype.hitTest = function(x) {\n      var index, r, _i, _len, _ref;\n      if (this.data.length === 0) {\n        return null;\n      }\n      _ref = this.data.slice(1);\n      for (index = _i = 0, _len = _ref.length; _i < _len; index = ++_i) {\n        r = _ref[index];\n        if (x < (r._x + this.data[index]._x) / 2) {\n          break;\n        }\n      }\n      return index;\n    };\n\n    Line.prototype.onGridClick = function(x, y) {\n      var index;\n      index = this.hitTest(x);\n      return this.fire('click', index, this.data[index].src, x, y);\n    };\n\n    Line.prototype.onHoverMove = function(x, y) {\n      var index;\n      index = this.hitTest(x);\n      return this.displayHoverForRow(index);\n    };\n\n    Line.prototype.onHoverOut = function() {\n      if (this.options.hideHover !== false) {\n        return this.displayHoverForRow(null);\n      }\n    };\n\n    Line.prototype.displayHoverForRow = function(index) {\n      var _ref;\n      if (index != null) {\n        (_ref = this.hover).update.apply(_ref, this.hoverContentForRow(index));\n        return this.hilight(index);\n      } else {\n        this.hover.hide();\n        return this.hilight();\n      }\n    };\n\n    Line.prototype.hoverContentForRow = function(index) {\n      var content, j, row, y, _i, _len, _ref;\n      row = this.data[index];\n      content = \"<div class='morris-hover-row-label'>\" + row.label + \"</div>\";\n      _ref = row.y;\n      for (j = _i = 0, _len = _ref.length; _i < _len; j = ++_i) {\n        y = _ref[j];\n        content += \"<div class='morris-hover-point' style='color: \" + (this.colorFor(row, j, 'label')) + \"'>\\n  \" + this.options.labels[j] + \":\\n  \" + (this.yLabelFormat(y)) + \"\\n</div>\";\n      }\n      if (typeof this.options.hoverCallback === 'function') {\n        content = this.options.hoverCallback(index, this.options, content, row.src);\n      }\n      return [content, row._x, row._ymax];\n    };\n\n    Line.prototype.generatePaths = function() {\n      var coords, i, r, smooth;\n      return this.paths = (function() {\n        var _i, _ref, _ref1, _results;\n        _results = [];\n        for (i = _i = 0, _ref = this.options.ykeys.length; 0 <= _ref ? _i < _ref : _i > _ref; i = 0 <= _ref ? ++_i : --_i) {\n          smooth = typeof this.options.smooth === \"boolean\" ? this.options.smooth : (_ref1 = this.options.ykeys[i], __indexOf.call(this.options.smooth, _ref1) >= 0);\n          coords = (function() {\n            var _j, _len, _ref2, _results1;\n            _ref2 = this.data;\n            _results1 = [];\n            for (_j = 0, _len = _ref2.length; _j < _len; _j++) {\n              r = _ref2[_j];\n              if (r._y[i] !== void 0) {\n                _results1.push({\n                  x: r._x,\n                  y: r._y[i]\n                });\n              }\n            }\n            return _results1;\n          }).call(this);\n          if (coords.length > 1) {\n            _results.push(Morris.Line.createPath(coords, smooth, this.bottom));\n          } else {\n            _results.push(null);\n          }\n        }\n        return _results;\n      }).call(this);\n    };\n\n    Line.prototype.draw = function() {\n      var _ref;\n      if ((_ref = this.options.axes) === true || _ref === 'both' || _ref === 'x') {\n        this.drawXAxis();\n      }\n      this.drawSeries();\n      if (this.options.hideHover === false) {\n        return this.displayHoverForRow(this.data.length - 1);\n      }\n    };\n\n    Line.prototype.drawXAxis = function() {\n      var drawLabel, l, labels, prevAngleMargin, prevLabelMargin, row, ypos, _i, _len, _results,\n        _this = this;\n      ypos = this.bottom + this.options.padding / 2;\n      prevLabelMargin = null;\n      prevAngleMargin = null;\n      drawLabel = function(labelText, xpos) {\n        var label, labelBox, margin, offset, textBox;\n        label = _this.drawXAxisLabel(_this.transX(xpos), ypos, labelText);\n        textBox = label.getBBox();\n        label.transform(\"r\" + (-_this.options.xLabelAngle));\n        labelBox = label.getBBox();\n        label.transform(\"t0,\" + (labelBox.height / 2) + \"...\");\n        if (_this.options.xLabelAngle !== 0) {\n          offset = -0.5 * textBox.width * Math.cos(_this.options.xLabelAngle * Math.PI / 180.0);\n          label.transform(\"t\" + offset + \",0...\");\n        }\n        labelBox = label.getBBox();\n        if (((prevLabelMargin == null) || prevLabelMargin >= labelBox.x + labelBox.width || (prevAngleMargin != null) && prevAngleMargin >= labelBox.x) && labelBox.x >= 0 && (labelBox.x + labelBox.width) < _this.el.width()) {\n          if (_this.options.xLabelAngle !== 0) {\n            margin = 1.25 * _this.options.gridTextSize / Math.sin(_this.options.xLabelAngle * Math.PI / 180.0);\n            prevAngleMargin = labelBox.x - margin;\n          }\n          return prevLabelMargin = labelBox.x - _this.options.xLabelMargin;\n        } else {\n          return label.remove();\n        }\n      };\n      if (this.options.parseTime) {\n        if (this.data.length === 1 && this.options.xLabels === 'auto') {\n          labels = [[this.data[0].label, this.data[0].x]];\n        } else {\n          labels = Morris.labelSeries(this.xmin, this.xmax, this.width, this.options.xLabels, this.options.xLabelFormat);\n        }\n      } else {\n        labels = (function() {\n          var _i, _len, _ref, _results;\n          _ref = this.data;\n          _results = [];\n          for (_i = 0, _len = _ref.length; _i < _len; _i++) {\n            row = _ref[_i];\n            _results.push([row.label, row.x]);\n          }\n          return _results;\n        }).call(this);\n      }\n      labels.reverse();\n      _results = [];\n      for (_i = 0, _len = labels.length; _i < _len; _i++) {\n        l = labels[_i];\n        _results.push(drawLabel(l[0], l[1]));\n      }\n      return _results;\n    };\n\n    Line.prototype.drawSeries = function() {\n      var i, _i, _j, _ref, _ref1, _results;\n      this.seriesPoints = [];\n      for (i = _i = _ref = this.options.ykeys.length - 1; _ref <= 0 ? _i <= 0 : _i >= 0; i = _ref <= 0 ? ++_i : --_i) {\n        this._drawLineFor(i);\n      }\n      _results = [];\n      for (i = _j = _ref1 = this.options.ykeys.length - 1; _ref1 <= 0 ? _j <= 0 : _j >= 0; i = _ref1 <= 0 ? ++_j : --_j) {\n        _results.push(this._drawPointFor(i));\n      }\n      return _results;\n    };\n\n    Line.prototype._drawPointFor = function(index) {\n      var circle, row, _i, _len, _ref, _results;\n      this.seriesPoints[index] = [];\n      _ref = this.data;\n      _results = [];\n      for (_i = 0, _len = _ref.length; _i < _len; _i++) {\n        row = _ref[_i];\n        circle = null;\n        if (row._y[index] != null) {\n          circle = this.drawLinePoint(row._x, row._y[index], this.colorFor(row, index, 'point'), index);\n        }\n        _results.push(this.seriesPoints[index].push(circle));\n      }\n      return _results;\n    };\n\n    Line.prototype._drawLineFor = function(index) {\n      var path;\n      path = this.paths[index];\n      if (path !== null) {\n        return this.drawLinePath(path, this.colorFor(null, index, 'line'), index);\n      }\n    };\n\n    Line.createPath = function(coords, smooth, bottom) {\n      var coord, g, grads, i, ix, lg, path, prevCoord, x1, x2, y1, y2, _i, _len;\n      path = \"\";\n      if (smooth) {\n        grads = Morris.Line.gradients(coords);\n      }\n      prevCoord = {\n        y: null\n      };\n      for (i = _i = 0, _len = coords.length; _i < _len; i = ++_i) {\n        coord = coords[i];\n        if (coord.y != null) {\n          if (prevCoord.y != null) {\n            if (smooth) {\n              g = grads[i];\n              lg = grads[i - 1];\n              ix = (coord.x - prevCoord.x) / 4;\n              x1 = prevCoord.x + ix;\n              y1 = Math.min(bottom, prevCoord.y + ix * lg);\n              x2 = coord.x - ix;\n              y2 = Math.min(bottom, coord.y - ix * g);\n              path += \"C\" + x1 + \",\" + y1 + \",\" + x2 + \",\" + y2 + \",\" + coord.x + \",\" + coord.y;\n            } else {\n              path += \"L\" + coord.x + \",\" + coord.y;\n            }\n          } else {\n            if (!smooth || (grads[i] != null)) {\n              path += \"M\" + coord.x + \",\" + coord.y;\n            }\n          }\n        }\n        prevCoord = coord;\n      }\n      return path;\n    };\n\n    Line.gradients = function(coords) {\n      var coord, grad, i, nextCoord, prevCoord, _i, _len, _results;\n      grad = function(a, b) {\n        return (a.y - b.y) / (a.x - b.x);\n      };\n      _results = [];\n      for (i = _i = 0, _len = coords.length; _i < _len; i = ++_i) {\n        coord = coords[i];\n        if (coord.y != null) {\n          nextCoord = coords[i + 1] || {\n            y: null\n          };\n          prevCoord = coords[i - 1] || {\n            y: null\n          };\n          if ((prevCoord.y != null) && (nextCoord.y != null)) {\n            _results.push(grad(prevCoord, nextCoord));\n          } else if (prevCoord.y != null) {\n            _results.push(grad(prevCoord, coord));\n          } else if (nextCoord.y != null) {\n            _results.push(grad(coord, nextCoord));\n          } else {\n            _results.push(null);\n          }\n        } else {\n          _results.push(null);\n        }\n      }\n      return _results;\n    };\n\n    Line.prototype.hilight = function(index) {\n      var i, _i, _j, _ref, _ref1;\n      if (this.prevHilight !== null && this.prevHilight !== index) {\n        for (i = _i = 0, _ref = this.seriesPoints.length - 1; 0 <= _ref ? _i <= _ref : _i >= _ref; i = 0 <= _ref ? ++_i : --_i) {\n          if (this.seriesPoints[i][this.prevHilight]) {\n            this.seriesPoints[i][this.prevHilight].animate(this.pointShrinkSeries(i));\n          }\n        }\n      }\n      if (index !== null && this.prevHilight !== index) {\n        for (i = _j = 0, _ref1 = this.seriesPoints.length - 1; 0 <= _ref1 ? _j <= _ref1 : _j >= _ref1; i = 0 <= _ref1 ? ++_j : --_j) {\n          if (this.seriesPoints[i][index]) {\n            this.seriesPoints[i][index].animate(this.pointGrowSeries(i));\n          }\n        }\n      }\n      return this.prevHilight = index;\n    };\n\n    Line.prototype.colorFor = function(row, sidx, type) {\n      if (typeof this.options.lineColors === 'function') {\n        return this.options.lineColors.call(this, row, sidx, type);\n      } else if (type === 'point') {\n        return this.options.pointFillColors[sidx % this.options.pointFillColors.length] || this.options.lineColors[sidx % this.options.lineColors.length];\n      } else {\n        return this.options.lineColors[sidx % this.options.lineColors.length];\n      }\n    };\n\n    Line.prototype.drawXAxisLabel = function(xPos, yPos, text) {\n      return this.raphael.text(xPos, yPos, text).attr('font-size', this.options.gridTextSize).attr('font-family', this.options.gridTextFamily).attr('font-weight', this.options.gridTextWeight).attr('fill', this.options.gridTextColor);\n    };\n\n    Line.prototype.drawLinePath = function(path, lineColor, lineIndex) {\n      return this.raphael.path(path).attr('stroke', lineColor).attr('stroke-width', this.lineWidthForSeries(lineIndex));\n    };\n\n    Line.prototype.drawLinePoint = function(xPos, yPos, pointColor, lineIndex) {\n      return this.raphael.circle(xPos, yPos, this.pointSizeForSeries(lineIndex)).attr('fill', pointColor).attr('stroke-width', this.pointStrokeWidthForSeries(lineIndex)).attr('stroke', this.pointStrokeColorForSeries(lineIndex));\n    };\n\n    Line.prototype.pointStrokeWidthForSeries = function(index) {\n      return this.options.pointStrokeWidths[index % this.options.pointStrokeWidths.length];\n    };\n\n    Line.prototype.pointStrokeColorForSeries = function(index) {\n      return this.options.pointStrokeColors[index % this.options.pointStrokeColors.length];\n    };\n\n    Line.prototype.lineWidthForSeries = function(index) {\n      if (this.options.lineWidth instanceof Array) {\n        return this.options.lineWidth[index % this.options.lineWidth.length];\n      } else {\n        return this.options.lineWidth;\n      }\n    };\n\n    Line.prototype.pointSizeForSeries = function(index) {\n      if (this.options.pointSize instanceof Array) {\n        return this.options.pointSize[index % this.options.pointSize.length];\n      } else {\n        return this.options.pointSize;\n      }\n    };\n\n    Line.prototype.pointGrowSeries = function(index) {\n      return Raphael.animation({\n        r: this.pointSizeForSeries(index) + 3\n      }, 25, 'linear');\n    };\n\n    Line.prototype.pointShrinkSeries = function(index) {\n      return Raphael.animation({\n        r: this.pointSizeForSeries(index)\n      }, 25, 'linear');\n    };\n\n    return Line;\n\n  })(Morris.Grid);\n\n  Morris.labelSeries = function(dmin, dmax, pxwidth, specName, xLabelFormat) {\n    var d, d0, ddensity, name, ret, s, spec, t, _i, _len, _ref;\n    ddensity = 200 * (dmax - dmin) / pxwidth;\n    d0 = new Date(dmin);\n    spec = Morris.LABEL_SPECS[specName];\n    if (spec === void 0) {\n      _ref = Morris.AUTO_LABEL_ORDER;\n      for (_i = 0, _len = _ref.length; _i < _len; _i++) {\n        name = _ref[_i];\n        s = Morris.LABEL_SPECS[name];\n        if (ddensity >= s.span) {\n          spec = s;\n          break;\n        }\n      }\n    }\n    if (spec === void 0) {\n      spec = Morris.LABEL_SPECS[\"second\"];\n    }\n    if (xLabelFormat) {\n      spec = $.extend({}, spec, {\n        fmt: xLabelFormat\n      });\n    }\n    d = spec.start(d0);\n    ret = [];\n    while ((t = d.getTime()) <= dmax) {\n      if (t >= dmin) {\n        ret.push([spec.fmt(d), t]);\n      }\n      spec.incr(d);\n    }\n    return ret;\n  };\n\n  minutesSpecHelper = function(interval) {\n    return {\n      span: interval * 60 * 1000,\n      start: function(d) {\n        return new Date(d.getFullYear(), d.getMonth(), d.getDate(), d.getHours());\n      },\n      fmt: function(d) {\n        return \"\" + (Morris.pad2(d.getHours())) + \":\" + (Morris.pad2(d.getMinutes()));\n      },\n      incr: function(d) {\n        return d.setUTCMinutes(d.getUTCMinutes() + interval);\n      }\n    };\n  };\n\n  secondsSpecHelper = function(interval) {\n    return {\n      span: interval * 1000,\n      start: function(d) {\n        return new Date(d.getFullYear(), d.getMonth(), d.getDate(), d.getHours(), d.getMinutes());\n      },\n      fmt: function(d) {\n        return \"\" + (Morris.pad2(d.getHours())) + \":\" + (Morris.pad2(d.getMinutes())) + \":\" + (Morris.pad2(d.getSeconds()));\n      },\n      incr: function(d) {\n        return d.setUTCSeconds(d.getUTCSeconds() + interval);\n      }\n    };\n  };\n\n  Morris.LABEL_SPECS = {\n    \"decade\": {\n      span: 172800000000,\n      start: function(d) {\n        return new Date(d.getFullYear() - d.getFullYear() % 10, 0, 1);\n      },\n      fmt: function(d) {\n        return \"\" + (d.getFullYear());\n      },\n      incr: function(d) {\n        return d.setFullYear(d.getFullYear() + 10);\n      }\n    },\n    \"year\": {\n      span: 17280000000,\n      start: function(d) {\n        return new Date(d.getFullYear(), 0, 1);\n      },\n      fmt: function(d) {\n        return \"\" + (d.getFullYear());\n      },\n      incr: function(d) {\n        return d.setFullYear(d.getFullYear() + 1);\n      }\n    },\n    \"month\": {\n      span: 2419200000,\n      start: function(d) {\n        return new Date(d.getFullYear(), d.getMonth(), 1);\n      },\n      fmt: function(d) {\n        return \"\" + (d.getFullYear()) + \"-\" + (Morris.pad2(d.getMonth() + 1));\n      },\n      incr: function(d) {\n        return d.setMonth(d.getMonth() + 1);\n      }\n    },\n    \"week\": {\n      span: 604800000,\n      start: function(d) {\n        return new Date(d.getFullYear(), d.getMonth(), d.getDate());\n      },\n      fmt: function(d) {\n        return \"\" + (d.getFullYear()) + \"-\" + (Morris.pad2(d.getMonth() + 1)) + \"-\" + (Morris.pad2(d.getDate()));\n      },\n      incr: function(d) {\n        return d.setDate(d.getDate() + 7);\n      }\n    },\n    \"day\": {\n      span: 86400000,\n      start: function(d) {\n        return new Date(d.getFullYear(), d.getMonth(), d.getDate());\n      },\n      fmt: function(d) {\n        return \"\" + (d.getFullYear()) + \"-\" + (Morris.pad2(d.getMonth() + 1)) + \"-\" + (Morris.pad2(d.getDate()));\n      },\n      incr: function(d) {\n        return d.setDate(d.getDate() + 1);\n      }\n    },\n    \"hour\": minutesSpecHelper(60),\n    \"30min\": minutesSpecHelper(30),\n    \"15min\": minutesSpecHelper(15),\n    \"10min\": minutesSpecHelper(10),\n    \"5min\": minutesSpecHelper(5),\n    \"minute\": minutesSpecHelper(1),\n    \"30sec\": secondsSpecHelper(30),\n    \"15sec\": secondsSpecHelper(15),\n    \"10sec\": secondsSpecHelper(10),\n    \"5sec\": secondsSpecHelper(5),\n    \"second\": secondsSpecHelper(1)\n  };\n\n  Morris.AUTO_LABEL_ORDER = [\"decade\", \"year\", \"month\", \"week\", \"day\", \"hour\", \"30min\", \"15min\", \"10min\", \"5min\", \"minute\", \"30sec\", \"15sec\", \"10sec\", \"5sec\", \"second\"];\n\n  Morris.Area = (function(_super) {\n    var areaDefaults;\n\n    __extends(Area, _super);\n\n    areaDefaults = {\n      fillOpacity: 'auto',\n      behaveLikeLine: false\n    };\n\n    function Area(options) {\n      var areaOptions;\n      if (!(this instanceof Morris.Area)) {\n        return new Morris.Area(options);\n      }\n      areaOptions = $.extend({}, areaDefaults, options);\n      this.cumulative = !areaOptions.behaveLikeLine;\n      if (areaOptions.fillOpacity === 'auto') {\n        areaOptions.fillOpacity = areaOptions.behaveLikeLine ? .8 : 1;\n      }\n      Area.__super__.constructor.call(this, areaOptions);\n    }\n\n    Area.prototype.calcPoints = function() {\n      var row, total, y, _i, _len, _ref, _results;\n      _ref = this.data;\n      _results = [];\n      for (_i = 0, _len = _ref.length; _i < _len; _i++) {\n        row = _ref[_i];\n        row._x = this.transX(row.x);\n        total = 0;\n        row._y = (function() {\n          var _j, _len1, _ref1, _results1;\n          _ref1 = row.y;\n          _results1 = [];\n          for (_j = 0, _len1 = _ref1.length; _j < _len1; _j++) {\n            y = _ref1[_j];\n            if (this.options.behaveLikeLine) {\n              _results1.push(this.transY(y));\n            } else {\n              total += y || 0;\n              _results1.push(this.transY(total));\n            }\n          }\n          return _results1;\n        }).call(this);\n        _results.push(row._ymax = Math.max.apply(Math, row._y));\n      }\n      return _results;\n    };\n\n    Area.prototype.drawSeries = function() {\n      var i, range, _i, _j, _k, _len, _ref, _ref1, _results, _results1, _results2;\n      this.seriesPoints = [];\n      if (this.options.behaveLikeLine) {\n        range = (function() {\n          _results = [];\n          for (var _i = 0, _ref = this.options.ykeys.length - 1; 0 <= _ref ? _i <= _ref : _i >= _ref; 0 <= _ref ? _i++ : _i--){ _results.push(_i); }\n          return _results;\n        }).apply(this);\n      } else {\n        range = (function() {\n          _results1 = [];\n          for (var _j = _ref1 = this.options.ykeys.length - 1; _ref1 <= 0 ? _j <= 0 : _j >= 0; _ref1 <= 0 ? _j++ : _j--){ _results1.push(_j); }\n          return _results1;\n        }).apply(this);\n      }\n      _results2 = [];\n      for (_k = 0, _len = range.length; _k < _len; _k++) {\n        i = range[_k];\n        this._drawFillFor(i);\n        this._drawLineFor(i);\n        _results2.push(this._drawPointFor(i));\n      }\n      return _results2;\n    };\n\n    Area.prototype._drawFillFor = function(index) {\n      var path;\n      path = this.paths[index];\n      if (path !== null) {\n        path = path + (\"L\" + (this.transX(this.xmax)) + \",\" + this.bottom + \"L\" + (this.transX(this.xmin)) + \",\" + this.bottom + \"Z\");\n        return this.drawFilledPath(path, this.fillForSeries(index));\n      }\n    };\n\n    Area.prototype.fillForSeries = function(i) {\n      var color;\n      color = Raphael.rgb2hsl(this.colorFor(this.data[i], i, 'line'));\n      return Raphael.hsl(color.h, this.options.behaveLikeLine ? color.s * 0.9 : color.s * 0.75, Math.min(0.98, this.options.behaveLikeLine ? color.l * 1.2 : color.l * 1.25));\n    };\n\n    Area.prototype.drawFilledPath = function(path, fill) {\n      return this.raphael.path(path).attr('fill', fill).attr('fill-opacity', this.options.fillOpacity).attr('stroke', 'none');\n    };\n\n    return Area;\n\n  })(Morris.Line);\n\n  Morris.Bar = (function(_super) {\n    __extends(Bar, _super);\n\n    function Bar(options) {\n      this.onHoverOut = __bind(this.onHoverOut, this);\n      this.onHoverMove = __bind(this.onHoverMove, this);\n      this.onGridClick = __bind(this.onGridClick, this);\n      if (!(this instanceof Morris.Bar)) {\n        return new Morris.Bar(options);\n      }\n      Bar.__super__.constructor.call(this, $.extend({}, options, {\n        parseTime: false\n      }));\n    }\n\n    Bar.prototype.init = function() {\n      this.cumulative = this.options.stacked;\n      if (this.options.hideHover !== 'always') {\n        this.hover = new Morris.Hover({\n          parent: this.el\n        });\n        this.on('hovermove', this.onHoverMove);\n        this.on('hoverout', this.onHoverOut);\n        return this.on('gridclick', this.onGridClick);\n      }\n    };\n\n    Bar.prototype.defaults = {\n      barSizeRatio: 0.75,\n      barGap: 3,\n      barColors: ['#0b62a4', '#7a92a3', '#4da74d', '#afd8f8', '#edc240', '#cb4b4b', '#9440ed'],\n      barOpacity: 1.0,\n      barRadius: [0, 0, 0, 0],\n      xLabelMargin: 50\n    };\n\n    Bar.prototype.calc = function() {\n      var _ref;\n      this.calcBars();\n      if (this.options.hideHover === false) {\n        return (_ref = this.hover).update.apply(_ref, this.hoverContentForRow(this.data.length - 1));\n      }\n    };\n\n    Bar.prototype.calcBars = function() {\n      var idx, row, y, _i, _len, _ref, _results;\n      _ref = this.data;\n      _results = [];\n      for (idx = _i = 0, _len = _ref.length; _i < _len; idx = ++_i) {\n        row = _ref[idx];\n        row._x = this.left + this.width * (idx + 0.5) / this.data.length;\n        _results.push(row._y = (function() {\n          var _j, _len1, _ref1, _results1;\n          _ref1 = row.y;\n          _results1 = [];\n          for (_j = 0, _len1 = _ref1.length; _j < _len1; _j++) {\n            y = _ref1[_j];\n            if (y != null) {\n              _results1.push(this.transY(y));\n            } else {\n              _results1.push(null);\n            }\n          }\n          return _results1;\n        }).call(this));\n      }\n      return _results;\n    };\n\n    Bar.prototype.draw = function() {\n      var _ref;\n      if ((_ref = this.options.axes) === true || _ref === 'both' || _ref === 'x') {\n        this.drawXAxis();\n      }\n      return this.drawSeries();\n    };\n\n    Bar.prototype.drawXAxis = function() {\n      var i, label, labelBox, margin, offset, prevAngleMargin, prevLabelMargin, row, textBox, ypos, _i, _ref, _results;\n      ypos = this.bottom + (this.options.xAxisLabelTopPadding || this.options.padding / 2);\n      prevLabelMargin = null;\n      prevAngleMargin = null;\n      _results = [];\n      for (i = _i = 0, _ref = this.data.length; 0 <= _ref ? _i < _ref : _i > _ref; i = 0 <= _ref ? ++_i : --_i) {\n        row = this.data[this.data.length - 1 - i];\n        label = this.drawXAxisLabel(row._x, ypos, row.label);\n        textBox = label.getBBox();\n        label.transform(\"r\" + (-this.options.xLabelAngle));\n        labelBox = label.getBBox();\n        label.transform(\"t0,\" + (labelBox.height / 2) + \"...\");\n        if (this.options.xLabelAngle !== 0) {\n          offset = -0.5 * textBox.width * Math.cos(this.options.xLabelAngle * Math.PI / 180.0);\n          label.transform(\"t\" + offset + \",0...\");\n        }\n        if (((prevLabelMargin == null) || prevLabelMargin >= labelBox.x + labelBox.width || (prevAngleMargin != null) && prevAngleMargin >= labelBox.x) && labelBox.x >= 0 && (labelBox.x + labelBox.width) < this.el.width()) {\n          if (this.options.xLabelAngle !== 0) {\n            margin = 1.25 * this.options.gridTextSize / Math.sin(this.options.xLabelAngle * Math.PI / 180.0);\n            prevAngleMargin = labelBox.x - margin;\n          }\n          _results.push(prevLabelMargin = labelBox.x - this.options.xLabelMargin);\n        } else {\n          _results.push(label.remove());\n        }\n      }\n      return _results;\n    };\n\n    Bar.prototype.drawSeries = function() {\n      var barWidth, bottom, groupWidth, idx, lastTop, left, leftPadding, numBars, row, sidx, size, spaceLeft, top, ypos, zeroPos;\n      groupWidth = this.width / this.options.data.length;\n      numBars = this.options.stacked ? 1 : this.options.ykeys.length;\n      barWidth = (groupWidth * this.options.barSizeRatio - this.options.barGap * (numBars - 1)) / numBars;\n      if (this.options.barSize) {\n        barWidth = Math.min(barWidth, this.options.barSize);\n      }\n      spaceLeft = groupWidth - barWidth * numBars - this.options.barGap * (numBars - 1);\n      leftPadding = spaceLeft / 2;\n      zeroPos = this.ymin <= 0 && this.ymax >= 0 ? this.transY(0) : null;\n      return this.bars = (function() {\n        var _i, _len, _ref, _results;\n        _ref = this.data;\n        _results = [];\n        for (idx = _i = 0, _len = _ref.length; _i < _len; idx = ++_i) {\n          row = _ref[idx];\n          lastTop = 0;\n          _results.push((function() {\n            var _j, _len1, _ref1, _results1;\n            _ref1 = row._y;\n            _results1 = [];\n            for (sidx = _j = 0, _len1 = _ref1.length; _j < _len1; sidx = ++_j) {\n              ypos = _ref1[sidx];\n              if (ypos !== null) {\n                if (zeroPos) {\n                  top = Math.min(ypos, zeroPos);\n                  bottom = Math.max(ypos, zeroPos);\n                } else {\n                  top = ypos;\n                  bottom = this.bottom;\n                }\n                left = this.left + idx * groupWidth + leftPadding;\n                if (!this.options.stacked) {\n                  left += sidx * (barWidth + this.options.barGap);\n                }\n                size = bottom - top;\n                if (this.options.verticalGridCondition && this.options.verticalGridCondition(row.x)) {\n                  this.drawBar(this.left + idx * groupWidth, this.top, groupWidth, Math.abs(this.top - this.bottom), this.options.verticalGridColor, this.options.verticalGridOpacity, this.options.barRadius);\n                }\n                if (this.options.stacked) {\n                  top -= lastTop;\n                }\n                this.drawBar(left, top, barWidth, size, this.colorFor(row, sidx, 'bar'), this.options.barOpacity, this.options.barRadius);\n                _results1.push(lastTop += size);\n              } else {\n                _results1.push(null);\n              }\n            }\n            return _results1;\n          }).call(this));\n        }\n        return _results;\n      }).call(this);\n    };\n\n    Bar.prototype.colorFor = function(row, sidx, type) {\n      var r, s;\n      if (typeof this.options.barColors === 'function') {\n        r = {\n          x: row.x,\n          y: row.y[sidx],\n          label: row.label\n        };\n        s = {\n          index: sidx,\n          key: this.options.ykeys[sidx],\n          label: this.options.labels[sidx]\n        };\n        return this.options.barColors.call(this, r, s, type);\n      } else {\n        return this.options.barColors[sidx % this.options.barColors.length];\n      }\n    };\n\n    Bar.prototype.hitTest = function(x) {\n      if (this.data.length === 0) {\n        return null;\n      }\n      x = Math.max(Math.min(x, this.right), this.left);\n      return Math.min(this.data.length - 1, Math.floor((x - this.left) / (this.width / this.data.length)));\n    };\n\n    Bar.prototype.onGridClick = function(x, y) {\n      var index;\n      index = this.hitTest(x);\n      return this.fire('click', index, this.data[index].src, x, y);\n    };\n\n    Bar.prototype.onHoverMove = function(x, y) {\n      var index, _ref;\n      index = this.hitTest(x);\n      return (_ref = this.hover).update.apply(_ref, this.hoverContentForRow(index));\n    };\n\n    Bar.prototype.onHoverOut = function() {\n      if (this.options.hideHover !== false) {\n        return this.hover.hide();\n      }\n    };\n\n    Bar.prototype.hoverContentForRow = function(index) {\n      var content, j, row, x, y, _i, _len, _ref;\n      row = this.data[index];\n      content = \"<div class='morris-hover-row-label'>\" + row.label + \"</div>\";\n      _ref = row.y;\n      for (j = _i = 0, _len = _ref.length; _i < _len; j = ++_i) {\n        y = _ref[j];\n        content += \"<div class='morris-hover-point' style='color: \" + (this.colorFor(row, j, 'label')) + \"'>\\n  \" + this.options.labels[j] + \":\\n  \" + (this.yLabelFormat(y)) + \"\\n</div>\";\n      }\n      if (typeof this.options.hoverCallback === 'function') {\n        content = this.options.hoverCallback(index, this.options, content, row.src);\n      }\n      x = this.left + (index + 0.5) * this.width / this.data.length;\n      return [content, x];\n    };\n\n    Bar.prototype.drawXAxisLabel = function(xPos, yPos, text) {\n      var label;\n      return label = this.raphael.text(xPos, yPos, text).attr('font-size', this.options.gridTextSize).attr('font-family', this.options.gridTextFamily).attr('font-weight', this.options.gridTextWeight).attr('fill', this.options.gridTextColor);\n    };\n\n    Bar.prototype.drawBar = function(xPos, yPos, width, height, barColor, opacity, radiusArray) {\n      var maxRadius, path;\n      maxRadius = Math.max.apply(Math, radiusArray);\n      if (maxRadius === 0 || maxRadius > height) {\n        path = this.raphael.rect(xPos, yPos, width, height);\n      } else {\n        path = this.raphael.path(this.roundedRect(xPos, yPos, width, height, radiusArray));\n      }\n      return path.attr('fill', barColor).attr('fill-opacity', opacity).attr('stroke', 'none');\n    };\n\n    Bar.prototype.roundedRect = function(x, y, w, h, r) {\n      if (r == null) {\n        r = [0, 0, 0, 0];\n      }\n      return [\"M\", x, r[0] + y, \"Q\", x, y, x + r[0], y, \"L\", x + w - r[1], y, \"Q\", x + w, y, x + w, y + r[1], \"L\", x + w, y + h - r[2], \"Q\", x + w, y + h, x + w - r[2], y + h, \"L\", x + r[3], y + h, \"Q\", x, y + h, x, y + h - r[3], \"Z\"];\n    };\n\n    return Bar;\n\n  })(Morris.Grid);\n\n  Morris.Donut = (function(_super) {\n    __extends(Donut, _super);\n\n    Donut.prototype.defaults = {\n      colors: ['#0B62A4', '#3980B5', '#679DC6', '#95BBD7', '#B0CCE1', '#095791', '#095085', '#083E67', '#052C48', '#042135'],\n      backgroundColor: '#FFFFFF',\n      labelColor: '#000000',\n      formatter: Morris.commas,\n      resize: false\n    };\n\n    function Donut(options) {\n      this.resizeHandler = __bind(this.resizeHandler, this);\n      this.select = __bind(this.select, this);\n      this.click = __bind(this.click, this);\n      var _this = this;\n      if (!(this instanceof Morris.Donut)) {\n        return new Morris.Donut(options);\n      }\n      this.options = $.extend({}, this.defaults, options);\n      if (typeof options.element === 'string') {\n        this.el = $(document.getElementById(options.element));\n      } else {\n        this.el = $(options.element);\n      }\n      if (this.el === null || this.el.length === 0) {\n        throw new Error(\"Graph placeholder not found.\");\n      }\n      if (options.data === void 0 || options.data.length === 0) {\n        return;\n      }\n      this.raphael = new Raphael(this.el[0]);\n      if (this.options.resize) {\n        $(window).bind('resize', function(evt) {\n          if (_this.timeoutId != null) {\n            window.clearTimeout(_this.timeoutId);\n          }\n          return _this.timeoutId = window.setTimeout(_this.resizeHandler, 100);\n        });\n      }\n      this.setData(options.data);\n    }\n\n    Donut.prototype.redraw = function() {\n      var C, cx, cy, i, idx, last, max_value, min, next, seg, total, value, w, _i, _j, _k, _len, _len1, _len2, _ref, _ref1, _ref2, _results;\n      this.raphael.clear();\n      cx = this.el.width() / 2;\n      cy = this.el.height() / 2;\n      w = (Math.min(cx, cy) - 10) / 3;\n      total = 0;\n      _ref = this.values;\n      for (_i = 0, _len = _ref.length; _i < _len; _i++) {\n        value = _ref[_i];\n        total += value;\n      }\n      min = 5 / (2 * w);\n      C = 1.9999 * Math.PI - min * this.data.length;\n      last = 0;\n      idx = 0;\n      this.segments = [];\n      _ref1 = this.values;\n      for (i = _j = 0, _len1 = _ref1.length; _j < _len1; i = ++_j) {\n        value = _ref1[i];\n        next = last + min + C * (value / total);\n        seg = new Morris.DonutSegment(cx, cy, w * 2, w, last, next, this.data[i].color || this.options.colors[idx % this.options.colors.length], this.options.backgroundColor, idx, this.raphael);\n        seg.render();\n        this.segments.push(seg);\n        seg.on('hover', this.select);\n        seg.on('click', this.click);\n        last = next;\n        idx += 1;\n      }\n      this.text1 = this.drawEmptyDonutLabel(cx, cy - 10, this.options.labelColor, 15, 800);\n      this.text2 = this.drawEmptyDonutLabel(cx, cy + 10, this.options.labelColor, 14);\n      max_value = Math.max.apply(Math, this.values);\n      idx = 0;\n      _ref2 = this.values;\n      _results = [];\n      for (_k = 0, _len2 = _ref2.length; _k < _len2; _k++) {\n        value = _ref2[_k];\n        if (value === max_value) {\n          this.select(idx);\n          break;\n        }\n        _results.push(idx += 1);\n      }\n      return _results;\n    };\n\n    Donut.prototype.setData = function(data) {\n      var row;\n      this.data = data;\n      this.values = (function() {\n        var _i, _len, _ref, _results;\n        _ref = this.data;\n        _results = [];\n        for (_i = 0, _len = _ref.length; _i < _len; _i++) {\n          row = _ref[_i];\n          _results.push(parseFloat(row.value));\n        }\n        return _results;\n      }).call(this);\n      return this.redraw();\n    };\n\n    Donut.prototype.click = function(idx) {\n      return this.fire('click', idx, this.data[idx]);\n    };\n\n    Donut.prototype.select = function(idx) {\n      var row, s, segment, _i, _len, _ref;\n      _ref = this.segments;\n      for (_i = 0, _len = _ref.length; _i < _len; _i++) {\n        s = _ref[_i];\n        s.deselect();\n      }\n      segment = this.segments[idx];\n      segment.select();\n      row = this.data[idx];\n      return this.setLabels(row.label, this.options.formatter(row.value, row));\n    };\n\n    Donut.prototype.setLabels = function(label1, label2) {\n      var inner, maxHeightBottom, maxHeightTop, maxWidth, text1bbox, text1scale, text2bbox, text2scale;\n      inner = (Math.min(this.el.width() / 2, this.el.height() / 2) - 10) * 2 / 3;\n      maxWidth = 1.8 * inner;\n      maxHeightTop = inner / 2;\n      maxHeightBottom = inner / 3;\n      this.text1.attr({\n        text: label1,\n        transform: ''\n      });\n      text1bbox = this.text1.getBBox();\n      text1scale = Math.min(maxWidth / text1bbox.width, maxHeightTop / text1bbox.height);\n      this.text1.attr({\n        transform: \"S\" + text1scale + \",\" + text1scale + \",\" + (text1bbox.x + text1bbox.width / 2) + \",\" + (text1bbox.y + text1bbox.height)\n      });\n      this.text2.attr({\n        text: label2,\n        transform: ''\n      });\n      text2bbox = this.text2.getBBox();\n      text2scale = Math.min(maxWidth / text2bbox.width, maxHeightBottom / text2bbox.height);\n      return this.text2.attr({\n        transform: \"S\" + text2scale + \",\" + text2scale + \",\" + (text2bbox.x + text2bbox.width / 2) + \",\" + text2bbox.y\n      });\n    };\n\n    Donut.prototype.drawEmptyDonutLabel = function(xPos, yPos, color, fontSize, fontWeight) {\n      var text;\n      text = this.raphael.text(xPos, yPos, '').attr('font-size', fontSize).attr('fill', color);\n      if (fontWeight != null) {\n        text.attr('font-weight', fontWeight);\n      }\n      return text;\n    };\n\n    Donut.prototype.resizeHandler = function() {\n      this.timeoutId = null;\n      this.raphael.setSize(this.el.width(), this.el.height());\n      return this.redraw();\n    };\n\n    return Donut;\n\n  })(Morris.EventEmitter);\n\n  Morris.DonutSegment = (function(_super) {\n    __extends(DonutSegment, _super);\n\n    function DonutSegment(cx, cy, inner, outer, p0, p1, color, backgroundColor, index, raphael) {\n      this.cx = cx;\n      this.cy = cy;\n      this.inner = inner;\n      this.outer = outer;\n      this.color = color;\n      this.backgroundColor = backgroundColor;\n      this.index = index;\n      this.raphael = raphael;\n      this.deselect = __bind(this.deselect, this);\n      this.select = __bind(this.select, this);\n      this.sin_p0 = Math.sin(p0);\n      this.cos_p0 = Math.cos(p0);\n      this.sin_p1 = Math.sin(p1);\n      this.cos_p1 = Math.cos(p1);\n      this.is_long = (p1 - p0) > Math.PI ? 1 : 0;\n      this.path = this.calcSegment(this.inner + 3, this.inner + this.outer - 5);\n      this.selectedPath = this.calcSegment(this.inner + 3, this.inner + this.outer);\n      this.hilight = this.calcArc(this.inner);\n    }\n\n    DonutSegment.prototype.calcArcPoints = function(r) {\n      return [this.cx + r * this.sin_p0, this.cy + r * this.cos_p0, this.cx + r * this.sin_p1, this.cy + r * this.cos_p1];\n    };\n\n    DonutSegment.prototype.calcSegment = function(r1, r2) {\n      var ix0, ix1, iy0, iy1, ox0, ox1, oy0, oy1, _ref, _ref1;\n      _ref = this.calcArcPoints(r1), ix0 = _ref[0], iy0 = _ref[1], ix1 = _ref[2], iy1 = _ref[3];\n      _ref1 = this.calcArcPoints(r2), ox0 = _ref1[0], oy0 = _ref1[1], ox1 = _ref1[2], oy1 = _ref1[3];\n      return (\"M\" + ix0 + \",\" + iy0) + (\"A\" + r1 + \",\" + r1 + \",0,\" + this.is_long + \",0,\" + ix1 + \",\" + iy1) + (\"L\" + ox1 + \",\" + oy1) + (\"A\" + r2 + \",\" + r2 + \",0,\" + this.is_long + \",1,\" + ox0 + \",\" + oy0) + \"Z\";\n    };\n\n    DonutSegment.prototype.calcArc = function(r) {\n      var ix0, ix1, iy0, iy1, _ref;\n      _ref = this.calcArcPoints(r), ix0 = _ref[0], iy0 = _ref[1], ix1 = _ref[2], iy1 = _ref[3];\n      return (\"M\" + ix0 + \",\" + iy0) + (\"A\" + r + \",\" + r + \",0,\" + this.is_long + \",0,\" + ix1 + \",\" + iy1);\n    };\n\n    DonutSegment.prototype.render = function() {\n      var _this = this;\n      this.arc = this.drawDonutArc(this.hilight, this.color);\n      return this.seg = this.drawDonutSegment(this.path, this.color, this.backgroundColor, function() {\n        return _this.fire('hover', _this.index);\n      }, function() {\n        return _this.fire('click', _this.index);\n      });\n    };\n\n    DonutSegment.prototype.drawDonutArc = function(path, color) {\n      return this.raphael.path(path).attr({\n        stroke: color,\n        'stroke-width': 2,\n        opacity: 0\n      });\n    };\n\n    DonutSegment.prototype.drawDonutSegment = function(path, fillColor, strokeColor, hoverFunction, clickFunction) {\n      return this.raphael.path(path).attr({\n        fill: fillColor,\n        stroke: strokeColor,\n        'stroke-width': 3\n      }).hover(hoverFunction).click(clickFunction);\n    };\n\n    DonutSegment.prototype.select = function() {\n      if (!this.selected) {\n        this.seg.animate({\n          path: this.selectedPath\n        }, 150, '<>');\n        this.arc.animate({\n          opacity: 1\n        }, 150, '<>');\n        return this.selected = true;\n      }\n    };\n\n    DonutSegment.prototype.deselect = function() {\n      if (this.selected) {\n        this.seg.animate({\n          path: this.path\n        }, 150, '<>');\n        this.arc.animate({\n          opacity: 0\n        }, 150, '<>');\n        return this.selected = false;\n      }\n    };\n\n    return DonutSegment;\n\n  })(Morris.EventEmitter);\n\n}).call(this);\n"
  },
  {
    "path": "app_backend/vendor/raphael/raphael.js",
    "content": "// ┌───────────────────────────────────────────────────────────────────────────────────────────────────────┐ \\\\\n// │ Raphaël 2.2.0 - JavaScript Vector Library                                                             │ \\\\\n// ├───────────────────────────────────────────────────────────────────────────────────────────────────────┤ \\\\\n// │ Copyright © 2008-2016 Dmitry Baranovskiy (http://raphaeljs.com)                                       │ \\\\\n// │ Copyright © 2008-2016 Sencha Labs (http://sencha.com)                                                 │ \\\\\n// ├───────────────────────────────────────────────────────────────────────────────────────────────────────┤ \\\\\n// │ Licensed under the MIT (https://github.com/DmitryBaranovskiy/raphael/blob/master/license.txt) license.│ \\\\\n// └───────────────────────────────────────────────────────────────────────────────────────────────────────┘ \\\\\n\n(function webpackUniversalModuleDefinition(root, factory) {\n\tif(typeof exports === 'object' && typeof module === 'object')\n\t\tmodule.exports = factory();\n\telse if(typeof define === 'function' && define.amd)\n\t\tdefine([], factory);\n\telse if(typeof exports === 'object')\n\t\texports[\"Raphael\"] = factory();\n\telse\n\t\troot[\"Raphael\"] = factory();\n})(this, function() {\nreturn /******/ (function(modules) { // webpackBootstrap\n/******/ \t// The module cache\n/******/ \tvar installedModules = {};\n\n/******/ \t// The require function\n/******/ \tfunction __webpack_require__(moduleId) {\n\n/******/ \t\t// Check if module is in cache\n/******/ \t\tif(installedModules[moduleId])\n/******/ \t\t\treturn installedModules[moduleId].exports;\n\n/******/ \t\t// Create a new module (and put it into the cache)\n/******/ \t\tvar module = installedModules[moduleId] = {\n/******/ \t\t\texports: {},\n/******/ \t\t\tid: moduleId,\n/******/ \t\t\tloaded: false\n/******/ \t\t};\n\n/******/ \t\t// Execute the module function\n/******/ \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n/******/ \t\t// Flag the module as loaded\n/******/ \t\tmodule.loaded = true;\n\n/******/ \t\t// Return the exports of the module\n/******/ \t\treturn module.exports;\n/******/ \t}\n\n\n/******/ \t// expose the modules object (__webpack_modules__)\n/******/ \t__webpack_require__.m = modules;\n\n/******/ \t// expose the module cache\n/******/ \t__webpack_require__.c = installedModules;\n\n/******/ \t// __webpack_public_path__\n/******/ \t__webpack_require__.p = \"\";\n\n/******/ \t// Load entry module and return exports\n/******/ \treturn __webpack_require__(0);\n/******/ })\n/************************************************************************/\n/******/ ([\n/* 0 */\n/***/ function(module, exports, __webpack_require__) {\n\n\tvar __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;!(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(1), __webpack_require__(3), __webpack_require__(4)], __WEBPACK_AMD_DEFINE_RESULT__ = function(R) {\n\n\t    return R;\n\n\t}.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));\n\n/***/ },\n/* 1 */\n/***/ function(module, exports, __webpack_require__) {\n\n\tvar __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;!(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(2)], __WEBPACK_AMD_DEFINE_RESULT__ = function(eve) {\n\n\t    /*\\\n\t     * Raphael\n\t     [ method ]\n\t     **\n\t     * Creates a canvas object on which to draw.\n\t     * You must do this first, as all future calls to drawing methods\n\t     * from this instance will be bound to this canvas.\n\t     > Parameters\n\t     **\n\t     - container (HTMLElement|string) DOM element or its ID which is going to be a parent for drawing surface\n\t     - width (number)\n\t     - height (number)\n\t     - callback (function) #optional callback function which is going to be executed in the context of newly created paper\n\t     * or\n\t     - x (number)\n\t     - y (number)\n\t     - width (number)\n\t     - height (number)\n\t     - callback (function) #optional callback function which is going to be executed in the context of newly created paper\n\t     * or\n\t     - all (array) (first 3 or 4 elements in the array are equal to [containerID, width, height] or [x, y, width, height]. The rest are element descriptions in format {type: type, <attributes>}). See @Paper.add.\n\t     - callback (function) #optional callback function which is going to be executed in the context of newly created paper\n\t     * or\n\t     - onReadyCallback (function) function that is going to be called on DOM ready event. You can also subscribe to this event via Eve’s “DOMLoad” event. In this case method returns `undefined`.\n\t     = (object) @Paper\n\t     > Usage\n\t     | // Each of the following examples create a canvas\n\t     | // that is 320px wide by 200px high.\n\t     | // Canvas is created at the viewport’s 10,50 coordinate.\n\t     | var paper = Raphael(10, 50, 320, 200);\n\t     | // Canvas is created at the top left corner of the #notepad element\n\t     | // (or its top right corner in dir=\"rtl\" elements)\n\t     | var paper = Raphael(document.getElementById(\"notepad\"), 320, 200);\n\t     | // Same as above\n\t     | var paper = Raphael(\"notepad\", 320, 200);\n\t     | // Image dump\n\t     | var set = Raphael([\"notepad\", 320, 200, {\n\t     |     type: \"rect\",\n\t     |     x: 10,\n\t     |     y: 10,\n\t     |     width: 25,\n\t     |     height: 25,\n\t     |     stroke: \"#f00\"\n\t     | }, {\n\t     |     type: \"text\",\n\t     |     x: 30,\n\t     |     y: 40,\n\t     |     text: \"Dump\"\n\t     | }]);\n\t    \\*/\n\t    function R(first) {\n\t        if (R.is(first, \"function\")) {\n\t            return loaded ? first() : eve.on(\"raphael.DOMload\", first);\n\t        } else if (R.is(first, array)) {\n\t            return R._engine.create[apply](R, first.splice(0, 3 + R.is(first[0], nu))).add(first);\n\t        } else {\n\t            var args = Array.prototype.slice.call(arguments, 0);\n\t            if (R.is(args[args.length - 1], \"function\")) {\n\t                var f = args.pop();\n\t                return loaded ? f.call(R._engine.create[apply](R, args)) : eve.on(\"raphael.DOMload\", function () {\n\t                    f.call(R._engine.create[apply](R, args));\n\t                });\n\t            } else {\n\t                return R._engine.create[apply](R, arguments);\n\t            }\n\t        }\n\t    }\n\t    R.version = \"2.2.0\";\n\t    R.eve = eve;\n\t    var loaded,\n\t        separator = /[, ]+/,\n\t        elements = {circle: 1, rect: 1, path: 1, ellipse: 1, text: 1, image: 1},\n\t        formatrg = /\\{(\\d+)\\}/g,\n\t        proto = \"prototype\",\n\t        has = \"hasOwnProperty\",\n\t        g = {\n\t            doc: document,\n\t            win: window\n\t        },\n\t        oldRaphael = {\n\t            was: Object.prototype[has].call(g.win, \"Raphael\"),\n\t            is: g.win.Raphael\n\t        },\n\t        Paper = function () {\n\t            /*\\\n\t             * Paper.ca\n\t             [ property (object) ]\n\t             **\n\t             * Shortcut for @Paper.customAttributes\n\t            \\*/\n\t            /*\\\n\t             * Paper.customAttributes\n\t             [ property (object) ]\n\t             **\n\t             * If you have a set of attributes that you would like to represent\n\t             * as a function of some number you can do it easily with custom attributes:\n\t             > Usage\n\t             | paper.customAttributes.hue = function (num) {\n\t             |     num = num % 1;\n\t             |     return {fill: \"hsb(\" + num + \", 0.75, 1)\"};\n\t             | };\n\t             | // Custom attribute “hue” will change fill\n\t             | // to be given hue with fixed saturation and brightness.\n\t             | // Now you can use it like this:\n\t             | var c = paper.circle(10, 10, 10).attr({hue: .45});\n\t             | // or even like this:\n\t             | c.animate({hue: 1}, 1e3);\n\t             |\n\t             | // You could also create custom attribute\n\t             | // with multiple parameters:\n\t             | paper.customAttributes.hsb = function (h, s, b) {\n\t             |     return {fill: \"hsb(\" + [h, s, b].join(\",\") + \")\"};\n\t             | };\n\t             | c.attr({hsb: \"0.5 .8 1\"});\n\t             | c.animate({hsb: [1, 0, 0.5]}, 1e3);\n\t            \\*/\n\t            this.ca = this.customAttributes = {};\n\t        },\n\t        paperproto,\n\t        appendChild = \"appendChild\",\n\t        apply = \"apply\",\n\t        concat = \"concat\",\n\t        supportsTouch = ('ontouchstart' in g.win) || g.win.DocumentTouch && g.doc instanceof DocumentTouch, //taken from Modernizr touch test\n\t        E = \"\",\n\t        S = \" \",\n\t        Str = String,\n\t        split = \"split\",\n\t        events = \"click dblclick mousedown mousemove mouseout mouseover mouseup touchstart touchmove touchend touchcancel\"[split](S),\n\t        touchMap = {\n\t            mousedown: \"touchstart\",\n\t            mousemove: \"touchmove\",\n\t            mouseup: \"touchend\"\n\t        },\n\t        lowerCase = Str.prototype.toLowerCase,\n\t        math = Math,\n\t        mmax = math.max,\n\t        mmin = math.min,\n\t        abs = math.abs,\n\t        pow = math.pow,\n\t        PI = math.PI,\n\t        nu = \"number\",\n\t        string = \"string\",\n\t        array = \"array\",\n\t        toString = \"toString\",\n\t        fillString = \"fill\",\n\t        objectToString = Object.prototype.toString,\n\t        paper = {},\n\t        push = \"push\",\n\t        ISURL = R._ISURL = /^url\\(['\"]?(.+?)['\"]?\\)$/i,\n\t        colourRegExp = /^\\s*((#[a-f\\d]{6})|(#[a-f\\d]{3})|rgba?\\(\\s*([\\d\\.]+%?\\s*,\\s*[\\d\\.]+%?\\s*,\\s*[\\d\\.]+%?(?:\\s*,\\s*[\\d\\.]+%?)?)\\s*\\)|hsba?\\(\\s*([\\d\\.]+(?:deg|\\xb0|%)?\\s*,\\s*[\\d\\.]+%?\\s*,\\s*[\\d\\.]+(?:%?\\s*,\\s*[\\d\\.]+)?)%?\\s*\\)|hsla?\\(\\s*([\\d\\.]+(?:deg|\\xb0|%)?\\s*,\\s*[\\d\\.]+%?\\s*,\\s*[\\d\\.]+(?:%?\\s*,\\s*[\\d\\.]+)?)%?\\s*\\))\\s*$/i,\n\t        isnan = {\"NaN\": 1, \"Infinity\": 1, \"-Infinity\": 1},\n\t        bezierrg = /^(?:cubic-)?bezier\\(([^,]+),([^,]+),([^,]+),([^\\)]+)\\)/,\n\t        round = math.round,\n\t        setAttribute = \"setAttribute\",\n\t        toFloat = parseFloat,\n\t        toInt = parseInt,\n\t        upperCase = Str.prototype.toUpperCase,\n\t        availableAttrs = R._availableAttrs = {\n\t            \"arrow-end\": \"none\",\n\t            \"arrow-start\": \"none\",\n\t            blur: 0,\n\t            \"clip-rect\": \"0 0 1e9 1e9\",\n\t            cursor: \"default\",\n\t            cx: 0,\n\t            cy: 0,\n\t            fill: \"#fff\",\n\t            \"fill-opacity\": 1,\n\t            font: '10px \"Arial\"',\n\t            \"font-family\": '\"Arial\"',\n\t            \"font-size\": \"10\",\n\t            \"font-style\": \"normal\",\n\t            \"font-weight\": 400,\n\t            gradient: 0,\n\t            height: 0,\n\t            href: \"http://raphaeljs.com/\",\n\t            \"letter-spacing\": 0,\n\t            opacity: 1,\n\t            path: \"M0,0\",\n\t            r: 0,\n\t            rx: 0,\n\t            ry: 0,\n\t            src: \"\",\n\t            stroke: \"#000\",\n\t            \"stroke-dasharray\": \"\",\n\t            \"stroke-linecap\": \"butt\",\n\t            \"stroke-linejoin\": \"butt\",\n\t            \"stroke-miterlimit\": 0,\n\t            \"stroke-opacity\": 1,\n\t            \"stroke-width\": 1,\n\t            target: \"_blank\",\n\t            \"text-anchor\": \"middle\",\n\t            title: \"Raphael\",\n\t            transform: \"\",\n\t            width: 0,\n\t            x: 0,\n\t            y: 0,\n\t            class: \"\"\n\t        },\n\t        availableAnimAttrs = R._availableAnimAttrs = {\n\t            blur: nu,\n\t            \"clip-rect\": \"csv\",\n\t            cx: nu,\n\t            cy: nu,\n\t            fill: \"colour\",\n\t            \"fill-opacity\": nu,\n\t            \"font-size\": nu,\n\t            height: nu,\n\t            opacity: nu,\n\t            path: \"path\",\n\t            r: nu,\n\t            rx: nu,\n\t            ry: nu,\n\t            stroke: \"colour\",\n\t            \"stroke-opacity\": nu,\n\t            \"stroke-width\": nu,\n\t            transform: \"transform\",\n\t            width: nu,\n\t            x: nu,\n\t            y: nu\n\t        },\n\t        whitespace = /[\\x09\\x0a\\x0b\\x0c\\x0d\\x20\\xa0\\u1680\\u180e\\u2000\\u2001\\u2002\\u2003\\u2004\\u2005\\u2006\\u2007\\u2008\\u2009\\u200a\\u202f\\u205f\\u3000\\u2028\\u2029]/g,\n\t        commaSpaces = /[\\x09\\x0a\\x0b\\x0c\\x0d\\x20\\xa0\\u1680\\u180e\\u2000\\u2001\\u2002\\u2003\\u2004\\u2005\\u2006\\u2007\\u2008\\u2009\\u200a\\u202f\\u205f\\u3000\\u2028\\u2029]*,[\\x09\\x0a\\x0b\\x0c\\x0d\\x20\\xa0\\u1680\\u180e\\u2000\\u2001\\u2002\\u2003\\u2004\\u2005\\u2006\\u2007\\u2008\\u2009\\u200a\\u202f\\u205f\\u3000\\u2028\\u2029]*/,\n\t        hsrg = {hs: 1, rg: 1},\n\t        p2s = /,?([achlmqrstvxz]),?/gi,\n\t        pathCommand = /([achlmrqstvz])[\\x09\\x0a\\x0b\\x0c\\x0d\\x20\\xa0\\u1680\\u180e\\u2000\\u2001\\u2002\\u2003\\u2004\\u2005\\u2006\\u2007\\u2008\\u2009\\u200a\\u202f\\u205f\\u3000\\u2028\\u2029,]*((-?\\d*\\.?\\d*(?:e[\\-+]?\\d+)?[\\x09\\x0a\\x0b\\x0c\\x0d\\x20\\xa0\\u1680\\u180e\\u2000\\u2001\\u2002\\u2003\\u2004\\u2005\\u2006\\u2007\\u2008\\u2009\\u200a\\u202f\\u205f\\u3000\\u2028\\u2029]*,?[\\x09\\x0a\\x0b\\x0c\\x0d\\x20\\xa0\\u1680\\u180e\\u2000\\u2001\\u2002\\u2003\\u2004\\u2005\\u2006\\u2007\\u2008\\u2009\\u200a\\u202f\\u205f\\u3000\\u2028\\u2029]*)+)/ig,\n\t        tCommand = /([rstm])[\\x09\\x0a\\x0b\\x0c\\x0d\\x20\\xa0\\u1680\\u180e\\u2000\\u2001\\u2002\\u2003\\u2004\\u2005\\u2006\\u2007\\u2008\\u2009\\u200a\\u202f\\u205f\\u3000\\u2028\\u2029,]*((-?\\d*\\.?\\d*(?:e[\\-+]?\\d+)?[\\x09\\x0a\\x0b\\x0c\\x0d\\x20\\xa0\\u1680\\u180e\\u2000\\u2001\\u2002\\u2003\\u2004\\u2005\\u2006\\u2007\\u2008\\u2009\\u200a\\u202f\\u205f\\u3000\\u2028\\u2029]*,?[\\x09\\x0a\\x0b\\x0c\\x0d\\x20\\xa0\\u1680\\u180e\\u2000\\u2001\\u2002\\u2003\\u2004\\u2005\\u2006\\u2007\\u2008\\u2009\\u200a\\u202f\\u205f\\u3000\\u2028\\u2029]*)+)/ig,\n\t        pathValues = /(-?\\d*\\.?\\d*(?:e[\\-+]?\\d+)?)[\\x09\\x0a\\x0b\\x0c\\x0d\\x20\\xa0\\u1680\\u180e\\u2000\\u2001\\u2002\\u2003\\u2004\\u2005\\u2006\\u2007\\u2008\\u2009\\u200a\\u202f\\u205f\\u3000\\u2028\\u2029]*,?[\\x09\\x0a\\x0b\\x0c\\x0d\\x20\\xa0\\u1680\\u180e\\u2000\\u2001\\u2002\\u2003\\u2004\\u2005\\u2006\\u2007\\u2008\\u2009\\u200a\\u202f\\u205f\\u3000\\u2028\\u2029]*/ig,\n\t        radial_gradient = R._radial_gradient = /^r(?:\\(([^,]+?)[\\x09\\x0a\\x0b\\x0c\\x0d\\x20\\xa0\\u1680\\u180e\\u2000\\u2001\\u2002\\u2003\\u2004\\u2005\\u2006\\u2007\\u2008\\u2009\\u200a\\u202f\\u205f\\u3000\\u2028\\u2029]*,[\\x09\\x0a\\x0b\\x0c\\x0d\\x20\\xa0\\u1680\\u180e\\u2000\\u2001\\u2002\\u2003\\u2004\\u2005\\u2006\\u2007\\u2008\\u2009\\u200a\\u202f\\u205f\\u3000\\u2028\\u2029]*([^\\)]+?)\\))?/,\n\t        eldata = {},\n\t        sortByKey = function (a, b) {\n\t            return a.key - b.key;\n\t        },\n\t        sortByNumber = function (a, b) {\n\t            return toFloat(a) - toFloat(b);\n\t        },\n\t        fun = function () {},\n\t        pipe = function (x) {\n\t            return x;\n\t        },\n\t        rectPath = R._rectPath = function (x, y, w, h, r) {\n\t            if (r) {\n\t                return [[\"M\", x + r, y], [\"l\", w - r * 2, 0], [\"a\", r, r, 0, 0, 1, r, r], [\"l\", 0, h - r * 2], [\"a\", r, r, 0, 0, 1, -r, r], [\"l\", r * 2 - w, 0], [\"a\", r, r, 0, 0, 1, -r, -r], [\"l\", 0, r * 2 - h], [\"a\", r, r, 0, 0, 1, r, -r], [\"z\"]];\n\t            }\n\t            return [[\"M\", x, y], [\"l\", w, 0], [\"l\", 0, h], [\"l\", -w, 0], [\"z\"]];\n\t        },\n\t        ellipsePath = function (x, y, rx, ry) {\n\t            if (ry == null) {\n\t                ry = rx;\n\t            }\n\t            return [[\"M\", x, y], [\"m\", 0, -ry], [\"a\", rx, ry, 0, 1, 1, 0, 2 * ry], [\"a\", rx, ry, 0, 1, 1, 0, -2 * ry], [\"z\"]];\n\t        },\n\t        getPath = R._getPath = {\n\t            path: function (el) {\n\t                return el.attr(\"path\");\n\t            },\n\t            circle: function (el) {\n\t                var a = el.attrs;\n\t                return ellipsePath(a.cx, a.cy, a.r);\n\t            },\n\t            ellipse: function (el) {\n\t                var a = el.attrs;\n\t                return ellipsePath(a.cx, a.cy, a.rx, a.ry);\n\t            },\n\t            rect: function (el) {\n\t                var a = el.attrs;\n\t                return rectPath(a.x, a.y, a.width, a.height, a.r);\n\t            },\n\t            image: function (el) {\n\t                var a = el.attrs;\n\t                return rectPath(a.x, a.y, a.width, a.height);\n\t            },\n\t            text: function (el) {\n\t                var bbox = el._getBBox();\n\t                return rectPath(bbox.x, bbox.y, bbox.width, bbox.height);\n\t            },\n\t            set : function(el) {\n\t                var bbox = el._getBBox();\n\t                return rectPath(bbox.x, bbox.y, bbox.width, bbox.height);\n\t            }\n\t        },\n\t        /*\\\n\t         * Raphael.mapPath\n\t         [ method ]\n\t         **\n\t         * Transform the path string with given matrix.\n\t         > Parameters\n\t         - path (string) path string\n\t         - matrix (object) see @Matrix\n\t         = (string) transformed path string\n\t        \\*/\n\t        mapPath = R.mapPath = function (path, matrix) {\n\t            if (!matrix) {\n\t                return path;\n\t            }\n\t            var x, y, i, j, ii, jj, pathi;\n\t            path = path2curve(path);\n\t            for (i = 0, ii = path.length; i < ii; i++) {\n\t                pathi = path[i];\n\t                for (j = 1, jj = pathi.length; j < jj; j += 2) {\n\t                    x = matrix.x(pathi[j], pathi[j + 1]);\n\t                    y = matrix.y(pathi[j], pathi[j + 1]);\n\t                    pathi[j] = x;\n\t                    pathi[j + 1] = y;\n\t                }\n\t            }\n\t            return path;\n\t        };\n\n\t    R._g = g;\n\t    /*\\\n\t     * Raphael.type\n\t     [ property (string) ]\n\t     **\n\t     * Can be “SVG”, “VML” or empty, depending on browser support.\n\t    \\*/\n\t    R.type = (g.win.SVGAngle || g.doc.implementation.hasFeature(\"http://www.w3.org/TR/SVG11/feature#BasicStructure\", \"1.1\") ? \"SVG\" : \"VML\");\n\t    if (R.type == \"VML\") {\n\t        var d = g.doc.createElement(\"div\"),\n\t            b;\n\t        d.innerHTML = '<v:shape adj=\"1\"/>';\n\t        b = d.firstChild;\n\t        b.style.behavior = \"url(#default#VML)\";\n\t        if (!(b && typeof b.adj == \"object\")) {\n\t            return (R.type = E);\n\t        }\n\t        d = null;\n\t    }\n\t    /*\\\n\t     * Raphael.svg\n\t     [ property (boolean) ]\n\t     **\n\t     * `true` if browser supports SVG.\n\t    \\*/\n\t    /*\\\n\t     * Raphael.vml\n\t     [ property (boolean) ]\n\t     **\n\t     * `true` if browser supports VML.\n\t    \\*/\n\t    R.svg = !(R.vml = R.type == \"VML\");\n\t    R._Paper = Paper;\n\t    /*\\\n\t     * Raphael.fn\n\t     [ property (object) ]\n\t     **\n\t     * You can add your own method to the canvas. For example if you want to draw a pie chart,\n\t     * you can create your own pie chart function and ship it as a Raphaël plugin. To do this\n\t     * you need to extend the `Raphael.fn` object. You should modify the `fn` object before a\n\t     * Raphaël instance is created, otherwise it will take no effect. Please note that the\n\t     * ability for namespaced plugins was removed in Raphael 2.0. It is up to the plugin to\n\t     * ensure any namespacing ensures proper context.\n\t     > Usage\n\t     | Raphael.fn.arrow = function (x1, y1, x2, y2, size) {\n\t     |     return this.path( ... );\n\t     | };\n\t     | // or create namespace\n\t     | Raphael.fn.mystuff = {\n\t     |     arrow: function () {…},\n\t     |     star: function () {…},\n\t     |     // etc…\n\t     | };\n\t     | var paper = Raphael(10, 10, 630, 480);\n\t     | // then use it\n\t     | paper.arrow(10, 10, 30, 30, 5).attr({fill: \"#f00\"});\n\t     | paper.mystuff.arrow();\n\t     | paper.mystuff.star();\n\t    \\*/\n\t    R.fn = paperproto = Paper.prototype = R.prototype;\n\t    R._id = 0;\n\t    R._oid = 0;\n\t    /*\\\n\t     * Raphael.is\n\t     [ method ]\n\t     **\n\t     * Handful of replacements for `typeof` operator.\n\t     > Parameters\n\t     - o (…) any object or primitive\n\t     - type (string) name of the type, i.e. “string”, “function”, “number”, etc.\n\t     = (boolean) is given value is of given type\n\t    \\*/\n\t    R.is = function (o, type) {\n\t        type = lowerCase.call(type);\n\t        if (type == \"finite\") {\n\t            return !isnan[has](+o);\n\t        }\n\t        if (type == \"array\") {\n\t            return o instanceof Array;\n\t        }\n\t        return  (type == \"null\" && o === null) ||\n\t                (type == typeof o && o !== null) ||\n\t                (type == \"object\" && o === Object(o)) ||\n\t                (type == \"array\" && Array.isArray && Array.isArray(o)) ||\n\t                objectToString.call(o).slice(8, -1).toLowerCase() == type;\n\t    };\n\n\t    function clone(obj) {\n\t        if (typeof obj == \"function\" || Object(obj) !== obj) {\n\t            return obj;\n\t        }\n\t        var res = new obj.constructor;\n\t        for (var key in obj) if (obj[has](key)) {\n\t            res[key] = clone(obj[key]);\n\t        }\n\t        return res;\n\t    }\n\n\t    /*\\\n\t     * Raphael.angle\n\t     [ method ]\n\t     **\n\t     * Returns angle between two or three points\n\t     > Parameters\n\t     - x1 (number) x coord of first point\n\t     - y1 (number) y coord of first point\n\t     - x2 (number) x coord of second point\n\t     - y2 (number) y coord of second point\n\t     - x3 (number) #optional x coord of third point\n\t     - y3 (number) #optional y coord of third point\n\t     = (number) angle in degrees.\n\t    \\*/\n\t    R.angle = function (x1, y1, x2, y2, x3, y3) {\n\t        if (x3 == null) {\n\t            var x = x1 - x2,\n\t                y = y1 - y2;\n\t            if (!x && !y) {\n\t                return 0;\n\t            }\n\t            return (180 + math.atan2(-y, -x) * 180 / PI + 360) % 360;\n\t        } else {\n\t            return R.angle(x1, y1, x3, y3) - R.angle(x2, y2, x3, y3);\n\t        }\n\t    };\n\t    /*\\\n\t     * Raphael.rad\n\t     [ method ]\n\t     **\n\t     * Transform angle to radians\n\t     > Parameters\n\t     - deg (number) angle in degrees\n\t     = (number) angle in radians.\n\t    \\*/\n\t    R.rad = function (deg) {\n\t        return deg % 360 * PI / 180;\n\t    };\n\t    /*\\\n\t     * Raphael.deg\n\t     [ method ]\n\t     **\n\t     * Transform angle to degrees\n\t     > Parameters\n\t     - rad (number) angle in radians\n\t     = (number) angle in degrees.\n\t    \\*/\n\t    R.deg = function (rad) {\n\t        return Math.round ((rad * 180 / PI% 360)* 1000) / 1000;\n\t    };\n\t    /*\\\n\t     * Raphael.snapTo\n\t     [ method ]\n\t     **\n\t     * Snaps given value to given grid.\n\t     > Parameters\n\t     - values (array|number) given array of values or step of the grid\n\t     - value (number) value to adjust\n\t     - tolerance (number) #optional tolerance for snapping. Default is `10`.\n\t     = (number) adjusted value.\n\t    \\*/\n\t    R.snapTo = function (values, value, tolerance) {\n\t        tolerance = R.is(tolerance, \"finite\") ? tolerance : 10;\n\t        if (R.is(values, array)) {\n\t            var i = values.length;\n\t            while (i--) if (abs(values[i] - value) <= tolerance) {\n\t                return values[i];\n\t            }\n\t        } else {\n\t            values = +values;\n\t            var rem = value % values;\n\t            if (rem < tolerance) {\n\t                return value - rem;\n\t            }\n\t            if (rem > values - tolerance) {\n\t                return value - rem + values;\n\t            }\n\t        }\n\t        return value;\n\t    };\n\n\t    /*\\\n\t     * Raphael.createUUID\n\t     [ method ]\n\t     **\n\t     * Returns RFC4122, version 4 ID\n\t    \\*/\n\t    var createUUID = R.createUUID = (function (uuidRegEx, uuidReplacer) {\n\t        return function () {\n\t            return \"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx\".replace(uuidRegEx, uuidReplacer).toUpperCase();\n\t        };\n\t    })(/[xy]/g, function (c) {\n\t        var r = math.random() * 16 | 0,\n\t            v = c == \"x\" ? r : (r & 3 | 8);\n\t        return v.toString(16);\n\t    });\n\n\t    /*\\\n\t     * Raphael.setWindow\n\t     [ method ]\n\t     **\n\t     * Used when you need to draw in `&lt;iframe>`. Switched window to the iframe one.\n\t     > Parameters\n\t     - newwin (window) new window object\n\t    \\*/\n\t    R.setWindow = function (newwin) {\n\t        eve(\"raphael.setWindow\", R, g.win, newwin);\n\t        g.win = newwin;\n\t        g.doc = g.win.document;\n\t        if (R._engine.initWin) {\n\t            R._engine.initWin(g.win);\n\t        }\n\t    };\n\t    var toHex = function (color) {\n\t        if (R.vml) {\n\t            // http://dean.edwards.name/weblog/2009/10/convert-any-colour-value-to-hex-in-msie/\n\t            var trim = /^\\s+|\\s+$/g;\n\t            var bod;\n\t            try {\n\t                var docum = new ActiveXObject(\"htmlfile\");\n\t                docum.write(\"<body>\");\n\t                docum.close();\n\t                bod = docum.body;\n\t            } catch(e) {\n\t                bod = createPopup().document.body;\n\t            }\n\t            var range = bod.createTextRange();\n\t            toHex = cacher(function (color) {\n\t                try {\n\t                    bod.style.color = Str(color).replace(trim, E);\n\t                    var value = range.queryCommandValue(\"ForeColor\");\n\t                    value = ((value & 255) << 16) | (value & 65280) | ((value & 16711680) >>> 16);\n\t                    return \"#\" + (\"000000\" + value.toString(16)).slice(-6);\n\t                } catch(e) {\n\t                    return \"none\";\n\t                }\n\t            });\n\t        } else {\n\t            var i = g.doc.createElement(\"i\");\n\t            i.title = \"Rapha\\xebl Colour Picker\";\n\t            i.style.display = \"none\";\n\t            g.doc.body.appendChild(i);\n\t            toHex = cacher(function (color) {\n\t                i.style.color = color;\n\t                return g.doc.defaultView.getComputedStyle(i, E).getPropertyValue(\"color\");\n\t            });\n\t        }\n\t        return toHex(color);\n\t    },\n\t    hsbtoString = function () {\n\t        return \"hsb(\" + [this.h, this.s, this.b] + \")\";\n\t    },\n\t    hsltoString = function () {\n\t        return \"hsl(\" + [this.h, this.s, this.l] + \")\";\n\t    },\n\t    rgbtoString = function () {\n\t        return this.hex;\n\t    },\n\t    prepareRGB = function (r, g, b) {\n\t        if (g == null && R.is(r, \"object\") && \"r\" in r && \"g\" in r && \"b\" in r) {\n\t            b = r.b;\n\t            g = r.g;\n\t            r = r.r;\n\t        }\n\t        if (g == null && R.is(r, string)) {\n\t            var clr = R.getRGB(r);\n\t            r = clr.r;\n\t            g = clr.g;\n\t            b = clr.b;\n\t        }\n\t        if (r > 1 || g > 1 || b > 1) {\n\t            r /= 255;\n\t            g /= 255;\n\t            b /= 255;\n\t        }\n\n\t        return [r, g, b];\n\t    },\n\t    packageRGB = function (r, g, b, o) {\n\t        r *= 255;\n\t        g *= 255;\n\t        b *= 255;\n\t        var rgb = {\n\t            r: r,\n\t            g: g,\n\t            b: b,\n\t            hex: R.rgb(r, g, b),\n\t            toString: rgbtoString\n\t        };\n\t        R.is(o, \"finite\") && (rgb.opacity = o);\n\t        return rgb;\n\t    };\n\n\t    /*\\\n\t     * Raphael.color\n\t     [ method ]\n\t     **\n\t     * Parses the color string and returns object with all values for the given color.\n\t     > Parameters\n\t     - clr (string) color string in one of the supported formats (see @Raphael.getRGB)\n\t     = (object) Combined RGB & HSB object in format:\n\t     o {\n\t     o     r (number) red,\n\t     o     g (number) green,\n\t     o     b (number) blue,\n\t     o     hex (string) color in HTML/CSS format: #••••••,\n\t     o     error (boolean) `true` if string can’t be parsed,\n\t     o     h (number) hue,\n\t     o     s (number) saturation,\n\t     o     v (number) value (brightness),\n\t     o     l (number) lightness\n\t     o }\n\t    \\*/\n\t    R.color = function (clr) {\n\t        var rgb;\n\t        if (R.is(clr, \"object\") && \"h\" in clr && \"s\" in clr && \"b\" in clr) {\n\t            rgb = R.hsb2rgb(clr);\n\t            clr.r = rgb.r;\n\t            clr.g = rgb.g;\n\t            clr.b = rgb.b;\n\t            clr.hex = rgb.hex;\n\t        } else if (R.is(clr, \"object\") && \"h\" in clr && \"s\" in clr && \"l\" in clr) {\n\t            rgb = R.hsl2rgb(clr);\n\t            clr.r = rgb.r;\n\t            clr.g = rgb.g;\n\t            clr.b = rgb.b;\n\t            clr.hex = rgb.hex;\n\t        } else {\n\t            if (R.is(clr, \"string\")) {\n\t                clr = R.getRGB(clr);\n\t            }\n\t            if (R.is(clr, \"object\") && \"r\" in clr && \"g\" in clr && \"b\" in clr) {\n\t                rgb = R.rgb2hsl(clr);\n\t                clr.h = rgb.h;\n\t                clr.s = rgb.s;\n\t                clr.l = rgb.l;\n\t                rgb = R.rgb2hsb(clr);\n\t                clr.v = rgb.b;\n\t            } else {\n\t                clr = {hex: \"none\"};\n\t                clr.r = clr.g = clr.b = clr.h = clr.s = clr.v = clr.l = -1;\n\t            }\n\t        }\n\t        clr.toString = rgbtoString;\n\t        return clr;\n\t    };\n\t    /*\\\n\t     * Raphael.hsb2rgb\n\t     [ method ]\n\t     **\n\t     * Converts HSB values to RGB object.\n\t     > Parameters\n\t     - h (number) hue\n\t     - s (number) saturation\n\t     - v (number) value or brightness\n\t     = (object) RGB object in format:\n\t     o {\n\t     o     r (number) red,\n\t     o     g (number) green,\n\t     o     b (number) blue,\n\t     o     hex (string) color in HTML/CSS format: #••••••\n\t     o }\n\t    \\*/\n\t    R.hsb2rgb = function (h, s, v, o) {\n\t        if (this.is(h, \"object\") && \"h\" in h && \"s\" in h && \"b\" in h) {\n\t            v = h.b;\n\t            s = h.s;\n\t            o = h.o;\n\t            h = h.h;\n\t        }\n\t        h *= 360;\n\t        var R, G, B, X, C;\n\t        h = (h % 360) / 60;\n\t        C = v * s;\n\t        X = C * (1 - abs(h % 2 - 1));\n\t        R = G = B = v - C;\n\n\t        h = ~~h;\n\t        R += [C, X, 0, 0, X, C][h];\n\t        G += [X, C, C, X, 0, 0][h];\n\t        B += [0, 0, X, C, C, X][h];\n\t        return packageRGB(R, G, B, o);\n\t    };\n\t    /*\\\n\t     * Raphael.hsl2rgb\n\t     [ method ]\n\t     **\n\t     * Converts HSL values to RGB object.\n\t     > Parameters\n\t     - h (number) hue\n\t     - s (number) saturation\n\t     - l (number) luminosity\n\t     = (object) RGB object in format:\n\t     o {\n\t     o     r (number) red,\n\t     o     g (number) green,\n\t     o     b (number) blue,\n\t     o     hex (string) color in HTML/CSS format: #••••••\n\t     o }\n\t    \\*/\n\t    R.hsl2rgb = function (h, s, l, o) {\n\t        if (this.is(h, \"object\") && \"h\" in h && \"s\" in h && \"l\" in h) {\n\t            l = h.l;\n\t            s = h.s;\n\t            h = h.h;\n\t        }\n\t        if (h > 1 || s > 1 || l > 1) {\n\t            h /= 360;\n\t            s /= 100;\n\t            l /= 100;\n\t        }\n\t        h *= 360;\n\t        var R, G, B, X, C;\n\t        h = (h % 360) / 60;\n\t        C = 2 * s * (l < .5 ? l : 1 - l);\n\t        X = C * (1 - abs(h % 2 - 1));\n\t        R = G = B = l - C / 2;\n\n\t        h = ~~h;\n\t        R += [C, X, 0, 0, X, C][h];\n\t        G += [X, C, C, X, 0, 0][h];\n\t        B += [0, 0, X, C, C, X][h];\n\t        return packageRGB(R, G, B, o);\n\t    };\n\t    /*\\\n\t     * Raphael.rgb2hsb\n\t     [ method ]\n\t     **\n\t     * Converts RGB values to HSB object.\n\t     > Parameters\n\t     - r (number) red\n\t     - g (number) green\n\t     - b (number) blue\n\t     = (object) HSB object in format:\n\t     o {\n\t     o     h (number) hue\n\t     o     s (number) saturation\n\t     o     b (number) brightness\n\t     o }\n\t    \\*/\n\t    R.rgb2hsb = function (r, g, b) {\n\t        b = prepareRGB(r, g, b);\n\t        r = b[0];\n\t        g = b[1];\n\t        b = b[2];\n\n\t        var H, S, V, C;\n\t        V = mmax(r, g, b);\n\t        C = V - mmin(r, g, b);\n\t        H = (C == 0 ? null :\n\t             V == r ? (g - b) / C :\n\t             V == g ? (b - r) / C + 2 :\n\t                      (r - g) / C + 4\n\t            );\n\t        H = ((H + 360) % 6) * 60 / 360;\n\t        S = C == 0 ? 0 : C / V;\n\t        return {h: H, s: S, b: V, toString: hsbtoString};\n\t    };\n\t    /*\\\n\t     * Raphael.rgb2hsl\n\t     [ method ]\n\t     **\n\t     * Converts RGB values to HSL object.\n\t     > Parameters\n\t     - r (number) red\n\t     - g (number) green\n\t     - b (number) blue\n\t     = (object) HSL object in format:\n\t     o {\n\t     o     h (number) hue\n\t     o     s (number) saturation\n\t     o     l (number) luminosity\n\t     o }\n\t    \\*/\n\t    R.rgb2hsl = function (r, g, b) {\n\t        b = prepareRGB(r, g, b);\n\t        r = b[0];\n\t        g = b[1];\n\t        b = b[2];\n\n\t        var H, S, L, M, m, C;\n\t        M = mmax(r, g, b);\n\t        m = mmin(r, g, b);\n\t        C = M - m;\n\t        H = (C == 0 ? null :\n\t             M == r ? (g - b) / C :\n\t             M == g ? (b - r) / C + 2 :\n\t                      (r - g) / C + 4);\n\t        H = ((H + 360) % 6) * 60 / 360;\n\t        L = (M + m) / 2;\n\t        S = (C == 0 ? 0 :\n\t             L < .5 ? C / (2 * L) :\n\t                      C / (2 - 2 * L));\n\t        return {h: H, s: S, l: L, toString: hsltoString};\n\t    };\n\t    R._path2string = function () {\n\t        return this.join(\",\").replace(p2s, \"$1\");\n\t    };\n\t    function repush(array, item) {\n\t        for (var i = 0, ii = array.length; i < ii; i++) if (array[i] === item) {\n\t            return array.push(array.splice(i, 1)[0]);\n\t        }\n\t    }\n\t    function cacher(f, scope, postprocessor) {\n\t        function newf() {\n\t            var arg = Array.prototype.slice.call(arguments, 0),\n\t                args = arg.join(\"\\u2400\"),\n\t                cache = newf.cache = newf.cache || {},\n\t                count = newf.count = newf.count || [];\n\t            if (cache[has](args)) {\n\t                repush(count, args);\n\t                return postprocessor ? postprocessor(cache[args]) : cache[args];\n\t            }\n\t            count.length >= 1e3 && delete cache[count.shift()];\n\t            count.push(args);\n\t            cache[args] = f[apply](scope, arg);\n\t            return postprocessor ? postprocessor(cache[args]) : cache[args];\n\t        }\n\t        return newf;\n\t    }\n\n\t    var preload = R._preload = function (src, f) {\n\t        var img = g.doc.createElement(\"img\");\n\t        img.style.cssText = \"position:absolute;left:-9999em;top:-9999em\";\n\t        img.onload = function () {\n\t            f.call(this);\n\t            this.onload = null;\n\t            g.doc.body.removeChild(this);\n\t        };\n\t        img.onerror = function () {\n\t            g.doc.body.removeChild(this);\n\t        };\n\t        g.doc.body.appendChild(img);\n\t        img.src = src;\n\t    };\n\n\t    function clrToString() {\n\t        return this.hex;\n\t    }\n\n\t    /*\\\n\t     * Raphael.getRGB\n\t     [ method ]\n\t     **\n\t     * Parses colour string as RGB object\n\t     > Parameters\n\t     - colour (string) colour string in one of formats:\n\t     # <ul>\n\t     #     <li>Colour name (“<code>red</code>”, “<code>green</code>”, “<code>cornflowerblue</code>”, etc)</li>\n\t     #     <li>#••• — shortened HTML colour: (“<code>#000</code>”, “<code>#fc0</code>”, etc)</li>\n\t     #     <li>#•••••• — full length HTML colour: (“<code>#000000</code>”, “<code>#bd2300</code>”)</li>\n\t     #     <li>rgb(•••, •••, •••) — red, green and blue channels’ values: (“<code>rgb(200,&nbsp;100,&nbsp;0)</code>”)</li>\n\t     #     <li>rgb(•••%, •••%, •••%) — same as above, but in %: (“<code>rgb(100%,&nbsp;175%,&nbsp;0%)</code>”)</li>\n\t     #     <li>hsb(•••, •••, •••) — hue, saturation and brightness values: (“<code>hsb(0.5,&nbsp;0.25,&nbsp;1)</code>”)</li>\n\t     #     <li>hsb(•••%, •••%, •••%) — same as above, but in %</li>\n\t     #     <li>hsl(•••, •••, •••) — same as hsb</li>\n\t     #     <li>hsl(•••%, •••%, •••%) — same as hsb</li>\n\t     # </ul>\n\t     = (object) RGB object in format:\n\t     o {\n\t     o     r (number) red,\n\t     o     g (number) green,\n\t     o     b (number) blue\n\t     o     hex (string) color in HTML/CSS format: #••••••,\n\t     o     error (boolean) true if string can’t be parsed\n\t     o }\n\t    \\*/\n\t    R.getRGB = cacher(function (colour) {\n\t        if (!colour || !!((colour = Str(colour)).indexOf(\"-\") + 1)) {\n\t            return {r: -1, g: -1, b: -1, hex: \"none\", error: 1, toString: clrToString};\n\t        }\n\t        if (colour == \"none\") {\n\t            return {r: -1, g: -1, b: -1, hex: \"none\", toString: clrToString};\n\t        }\n\t        !(hsrg[has](colour.toLowerCase().substring(0, 2)) || colour.charAt() == \"#\") && (colour = toHex(colour));\n\t        var res,\n\t            red,\n\t            green,\n\t            blue,\n\t            opacity,\n\t            t,\n\t            values,\n\t            rgb = colour.match(colourRegExp);\n\t        if (rgb) {\n\t            if (rgb[2]) {\n\t                blue = toInt(rgb[2].substring(5), 16);\n\t                green = toInt(rgb[2].substring(3, 5), 16);\n\t                red = toInt(rgb[2].substring(1, 3), 16);\n\t            }\n\t            if (rgb[3]) {\n\t                blue = toInt((t = rgb[3].charAt(3)) + t, 16);\n\t                green = toInt((t = rgb[3].charAt(2)) + t, 16);\n\t                red = toInt((t = rgb[3].charAt(1)) + t, 16);\n\t            }\n\t            if (rgb[4]) {\n\t                values = rgb[4][split](commaSpaces);\n\t                red = toFloat(values[0]);\n\t                values[0].slice(-1) == \"%\" && (red *= 2.55);\n\t                green = toFloat(values[1]);\n\t                values[1].slice(-1) == \"%\" && (green *= 2.55);\n\t                blue = toFloat(values[2]);\n\t                values[2].slice(-1) == \"%\" && (blue *= 2.55);\n\t                rgb[1].toLowerCase().slice(0, 4) == \"rgba\" && (opacity = toFloat(values[3]));\n\t                values[3] && values[3].slice(-1) == \"%\" && (opacity /= 100);\n\t            }\n\t            if (rgb[5]) {\n\t                values = rgb[5][split](commaSpaces);\n\t                red = toFloat(values[0]);\n\t                values[0].slice(-1) == \"%\" && (red *= 2.55);\n\t                green = toFloat(values[1]);\n\t                values[1].slice(-1) == \"%\" && (green *= 2.55);\n\t                blue = toFloat(values[2]);\n\t                values[2].slice(-1) == \"%\" && (blue *= 2.55);\n\t                (values[0].slice(-3) == \"deg\" || values[0].slice(-1) == \"\\xb0\") && (red /= 360);\n\t                rgb[1].toLowerCase().slice(0, 4) == \"hsba\" && (opacity = toFloat(values[3]));\n\t                values[3] && values[3].slice(-1) == \"%\" && (opacity /= 100);\n\t                return R.hsb2rgb(red, green, blue, opacity);\n\t            }\n\t            if (rgb[6]) {\n\t                values = rgb[6][split](commaSpaces);\n\t                red = toFloat(values[0]);\n\t                values[0].slice(-1) == \"%\" && (red *= 2.55);\n\t                green = toFloat(values[1]);\n\t                values[1].slice(-1) == \"%\" && (green *= 2.55);\n\t                blue = toFloat(values[2]);\n\t                values[2].slice(-1) == \"%\" && (blue *= 2.55);\n\t                (values[0].slice(-3) == \"deg\" || values[0].slice(-1) == \"\\xb0\") && (red /= 360);\n\t                rgb[1].toLowerCase().slice(0, 4) == \"hsla\" && (opacity = toFloat(values[3]));\n\t                values[3] && values[3].slice(-1) == \"%\" && (opacity /= 100);\n\t                return R.hsl2rgb(red, green, blue, opacity);\n\t            }\n\t            rgb = {r: red, g: green, b: blue, toString: clrToString};\n\t            rgb.hex = \"#\" + (16777216 | blue | (green << 8) | (red << 16)).toString(16).slice(1);\n\t            R.is(opacity, \"finite\") && (rgb.opacity = opacity);\n\t            return rgb;\n\t        }\n\t        return {r: -1, g: -1, b: -1, hex: \"none\", error: 1, toString: clrToString};\n\t    }, R);\n\t    /*\\\n\t     * Raphael.hsb\n\t     [ method ]\n\t     **\n\t     * Converts HSB values to hex representation of the colour.\n\t     > Parameters\n\t     - h (number) hue\n\t     - s (number) saturation\n\t     - b (number) value or brightness\n\t     = (string) hex representation of the colour.\n\t    \\*/\n\t    R.hsb = cacher(function (h, s, b) {\n\t        return R.hsb2rgb(h, s, b).hex;\n\t    });\n\t    /*\\\n\t     * Raphael.hsl\n\t     [ method ]\n\t     **\n\t     * Converts HSL values to hex representation of the colour.\n\t     > Parameters\n\t     - h (number) hue\n\t     - s (number) saturation\n\t     - l (number) luminosity\n\t     = (string) hex representation of the colour.\n\t    \\*/\n\t    R.hsl = cacher(function (h, s, l) {\n\t        return R.hsl2rgb(h, s, l).hex;\n\t    });\n\t    /*\\\n\t     * Raphael.rgb\n\t     [ method ]\n\t     **\n\t     * Converts RGB values to hex representation of the colour.\n\t     > Parameters\n\t     - r (number) red\n\t     - g (number) green\n\t     - b (number) blue\n\t     = (string) hex representation of the colour.\n\t    \\*/\n\t    R.rgb = cacher(function (r, g, b) {\n\t        function round(x) { return (x + 0.5) | 0; }\n\t        return \"#\" + (16777216 | round(b) | (round(g) << 8) | (round(r) << 16)).toString(16).slice(1);\n\t    });\n\t    /*\\\n\t     * Raphael.getColor\n\t     [ method ]\n\t     **\n\t     * On each call returns next colour in the spectrum. To reset it back to red call @Raphael.getColor.reset\n\t     > Parameters\n\t     - value (number) #optional brightness, default is `0.75`\n\t     = (string) hex representation of the colour.\n\t    \\*/\n\t    R.getColor = function (value) {\n\t        var start = this.getColor.start = this.getColor.start || {h: 0, s: 1, b: value || .75},\n\t            rgb = this.hsb2rgb(start.h, start.s, start.b);\n\t        start.h += .075;\n\t        if (start.h > 1) {\n\t            start.h = 0;\n\t            start.s -= .2;\n\t            start.s <= 0 && (this.getColor.start = {h: 0, s: 1, b: start.b});\n\t        }\n\t        return rgb.hex;\n\t    };\n\t    /*\\\n\t     * Raphael.getColor.reset\n\t     [ method ]\n\t     **\n\t     * Resets spectrum position for @Raphael.getColor back to red.\n\t    \\*/\n\t    R.getColor.reset = function () {\n\t        delete this.start;\n\t    };\n\n\t    // http://schepers.cc/getting-to-the-point\n\t    function catmullRom2bezier(crp, z) {\n\t        var d = [];\n\t        for (var i = 0, iLen = crp.length; iLen - 2 * !z > i; i += 2) {\n\t            var p = [\n\t                        {x: +crp[i - 2], y: +crp[i - 1]},\n\t                        {x: +crp[i],     y: +crp[i + 1]},\n\t                        {x: +crp[i + 2], y: +crp[i + 3]},\n\t                        {x: +crp[i + 4], y: +crp[i + 5]}\n\t                    ];\n\t            if (z) {\n\t                if (!i) {\n\t                    p[0] = {x: +crp[iLen - 2], y: +crp[iLen - 1]};\n\t                } else if (iLen - 4 == i) {\n\t                    p[3] = {x: +crp[0], y: +crp[1]};\n\t                } else if (iLen - 2 == i) {\n\t                    p[2] = {x: +crp[0], y: +crp[1]};\n\t                    p[3] = {x: +crp[2], y: +crp[3]};\n\t                }\n\t            } else {\n\t                if (iLen - 4 == i) {\n\t                    p[3] = p[2];\n\t                } else if (!i) {\n\t                    p[0] = {x: +crp[i], y: +crp[i + 1]};\n\t                }\n\t            }\n\t            d.push([\"C\",\n\t                  (-p[0].x + 6 * p[1].x + p[2].x) / 6,\n\t                  (-p[0].y + 6 * p[1].y + p[2].y) / 6,\n\t                  (p[1].x + 6 * p[2].x - p[3].x) / 6,\n\t                  (p[1].y + 6*p[2].y - p[3].y) / 6,\n\t                  p[2].x,\n\t                  p[2].y\n\t            ]);\n\t        }\n\n\t        return d;\n\t    }\n\t    /*\\\n\t     * Raphael.parsePathString\n\t     [ method ]\n\t     **\n\t     * Utility method\n\t     **\n\t     * Parses given path string into an array of arrays of path segments.\n\t     > Parameters\n\t     - pathString (string|array) path string or array of segments (in the last case it will be returned straight away)\n\t     = (array) array of segments.\n\t    \\*/\n\t    R.parsePathString = function (pathString) {\n\t        if (!pathString) {\n\t            return null;\n\t        }\n\t        var pth = paths(pathString);\n\t        if (pth.arr) {\n\t            return pathClone(pth.arr);\n\t        }\n\n\t        var paramCounts = {a: 7, c: 6, h: 1, l: 2, m: 2, r: 4, q: 4, s: 4, t: 2, v: 1, z: 0},\n\t            data = [];\n\t        if (R.is(pathString, array) && R.is(pathString[0], array)) { // rough assumption\n\t            data = pathClone(pathString);\n\t        }\n\t        if (!data.length) {\n\t            Str(pathString).replace(pathCommand, function (a, b, c) {\n\t                var params = [],\n\t                    name = b.toLowerCase();\n\t                c.replace(pathValues, function (a, b) {\n\t                    b && params.push(+b);\n\t                });\n\t                if (name == \"m\" && params.length > 2) {\n\t                    data.push([b][concat](params.splice(0, 2)));\n\t                    name = \"l\";\n\t                    b = b == \"m\" ? \"l\" : \"L\";\n\t                }\n\t                if (name == \"r\") {\n\t                    data.push([b][concat](params));\n\t                } else while (params.length >= paramCounts[name]) {\n\t                    data.push([b][concat](params.splice(0, paramCounts[name])));\n\t                    if (!paramCounts[name]) {\n\t                        break;\n\t                    }\n\t                }\n\t            });\n\t        }\n\t        data.toString = R._path2string;\n\t        pth.arr = pathClone(data);\n\t        return data;\n\t    };\n\t    /*\\\n\t     * Raphael.parseTransformString\n\t     [ method ]\n\t     **\n\t     * Utility method\n\t     **\n\t     * Parses given path string into an array of transformations.\n\t     > Parameters\n\t     - TString (string|array) transform string or array of transformations (in the last case it will be returned straight away)\n\t     = (array) array of transformations.\n\t    \\*/\n\t    R.parseTransformString = cacher(function (TString) {\n\t        if (!TString) {\n\t            return null;\n\t        }\n\t        var paramCounts = {r: 3, s: 4, t: 2, m: 6},\n\t            data = [];\n\t        if (R.is(TString, array) && R.is(TString[0], array)) { // rough assumption\n\t            data = pathClone(TString);\n\t        }\n\t        if (!data.length) {\n\t            Str(TString).replace(tCommand, function (a, b, c) {\n\t                var params = [],\n\t                    name = lowerCase.call(b);\n\t                c.replace(pathValues, function (a, b) {\n\t                    b && params.push(+b);\n\t                });\n\t                data.push([b][concat](params));\n\t            });\n\t        }\n\t        data.toString = R._path2string;\n\t        return data;\n\t    });\n\t    // PATHS\n\t    var paths = function (ps) {\n\t        var p = paths.ps = paths.ps || {};\n\t        if (p[ps]) {\n\t            p[ps].sleep = 100;\n\t        } else {\n\t            p[ps] = {\n\t                sleep: 100\n\t            };\n\t        }\n\t        setTimeout(function () {\n\t            for (var key in p) if (p[has](key) && key != ps) {\n\t                p[key].sleep--;\n\t                !p[key].sleep && delete p[key];\n\t            }\n\t        });\n\t        return p[ps];\n\t    };\n\t    /*\\\n\t     * Raphael.findDotsAtSegment\n\t     [ method ]\n\t     **\n\t     * Utility method\n\t     **\n\t     * Find dot coordinates on the given cubic bezier curve at the given t.\n\t     > Parameters\n\t     - p1x (number) x of the first point of the curve\n\t     - p1y (number) y of the first point of the curve\n\t     - c1x (number) x of the first anchor of the curve\n\t     - c1y (number) y of the first anchor of the curve\n\t     - c2x (number) x of the second anchor of the curve\n\t     - c2y (number) y of the second anchor of the curve\n\t     - p2x (number) x of the second point of the curve\n\t     - p2y (number) y of the second point of the curve\n\t     - t (number) position on the curve (0..1)\n\t     = (object) point information in format:\n\t     o {\n\t     o     x: (number) x coordinate of the point\n\t     o     y: (number) y coordinate of the point\n\t     o     m: {\n\t     o         x: (number) x coordinate of the left anchor\n\t     o         y: (number) y coordinate of the left anchor\n\t     o     }\n\t     o     n: {\n\t     o         x: (number) x coordinate of the right anchor\n\t     o         y: (number) y coordinate of the right anchor\n\t     o     }\n\t     o     start: {\n\t     o         x: (number) x coordinate of the start of the curve\n\t     o         y: (number) y coordinate of the start of the curve\n\t     o     }\n\t     o     end: {\n\t     o         x: (number) x coordinate of the end of the curve\n\t     o         y: (number) y coordinate of the end of the curve\n\t     o     }\n\t     o     alpha: (number) angle of the curve derivative at the point\n\t     o }\n\t    \\*/\n\t    R.findDotsAtSegment = function (p1x, p1y, c1x, c1y, c2x, c2y, p2x, p2y, t) {\n\t        var t1 = 1 - t,\n\t            t13 = pow(t1, 3),\n\t            t12 = pow(t1, 2),\n\t            t2 = t * t,\n\t            t3 = t2 * t,\n\t            x = t13 * p1x + t12 * 3 * t * c1x + t1 * 3 * t * t * c2x + t3 * p2x,\n\t            y = t13 * p1y + t12 * 3 * t * c1y + t1 * 3 * t * t * c2y + t3 * p2y,\n\t            mx = p1x + 2 * t * (c1x - p1x) + t2 * (c2x - 2 * c1x + p1x),\n\t            my = p1y + 2 * t * (c1y - p1y) + t2 * (c2y - 2 * c1y + p1y),\n\t            nx = c1x + 2 * t * (c2x - c1x) + t2 * (p2x - 2 * c2x + c1x),\n\t            ny = c1y + 2 * t * (c2y - c1y) + t2 * (p2y - 2 * c2y + c1y),\n\t            ax = t1 * p1x + t * c1x,\n\t            ay = t1 * p1y + t * c1y,\n\t            cx = t1 * c2x + t * p2x,\n\t            cy = t1 * c2y + t * p2y,\n\t            alpha = (90 - math.atan2(mx - nx, my - ny) * 180 / PI);\n\t        (mx > nx || my < ny) && (alpha += 180);\n\t        return {\n\t            x: x,\n\t            y: y,\n\t            m: {x: mx, y: my},\n\t            n: {x: nx, y: ny},\n\t            start: {x: ax, y: ay},\n\t            end: {x: cx, y: cy},\n\t            alpha: alpha\n\t        };\n\t    };\n\t    /*\\\n\t     * Raphael.bezierBBox\n\t     [ method ]\n\t     **\n\t     * Utility method\n\t     **\n\t     * Return bounding box of a given cubic bezier curve\n\t     > Parameters\n\t     - p1x (number) x of the first point of the curve\n\t     - p1y (number) y of the first point of the curve\n\t     - c1x (number) x of the first anchor of the curve\n\t     - c1y (number) y of the first anchor of the curve\n\t     - c2x (number) x of the second anchor of the curve\n\t     - c2y (number) y of the second anchor of the curve\n\t     - p2x (number) x of the second point of the curve\n\t     - p2y (number) y of the second point of the curve\n\t     * or\n\t     - bez (array) array of six points for bezier curve\n\t     = (object) point information in format:\n\t     o {\n\t     o     min: {\n\t     o         x: (number) x coordinate of the left point\n\t     o         y: (number) y coordinate of the top point\n\t     o     }\n\t     o     max: {\n\t     o         x: (number) x coordinate of the right point\n\t     o         y: (number) y coordinate of the bottom point\n\t     o     }\n\t     o }\n\t    \\*/\n\t    R.bezierBBox = function (p1x, p1y, c1x, c1y, c2x, c2y, p2x, p2y) {\n\t        if (!R.is(p1x, \"array\")) {\n\t            p1x = [p1x, p1y, c1x, c1y, c2x, c2y, p2x, p2y];\n\t        }\n\t        var bbox = curveDim.apply(null, p1x);\n\t        return {\n\t            x: bbox.min.x,\n\t            y: bbox.min.y,\n\t            x2: bbox.max.x,\n\t            y2: bbox.max.y,\n\t            width: bbox.max.x - bbox.min.x,\n\t            height: bbox.max.y - bbox.min.y\n\t        };\n\t    };\n\t    /*\\\n\t     * Raphael.isPointInsideBBox\n\t     [ method ]\n\t     **\n\t     * Utility method\n\t     **\n\t     * Returns `true` if given point is inside bounding boxes.\n\t     > Parameters\n\t     - bbox (string) bounding box\n\t     - x (string) x coordinate of the point\n\t     - y (string) y coordinate of the point\n\t     = (boolean) `true` if point inside\n\t    \\*/\n\t    R.isPointInsideBBox = function (bbox, x, y) {\n\t        return x >= bbox.x && x <= bbox.x2 && y >= bbox.y && y <= bbox.y2;\n\t    };\n\t    /*\\\n\t     * Raphael.isBBoxIntersect\n\t     [ method ]\n\t     **\n\t     * Utility method\n\t     **\n\t     * Returns `true` if two bounding boxes intersect\n\t     > Parameters\n\t     - bbox1 (string) first bounding box\n\t     - bbox2 (string) second bounding box\n\t     = (boolean) `true` if they intersect\n\t    \\*/\n\t    R.isBBoxIntersect = function (bbox1, bbox2) {\n\t        var i = R.isPointInsideBBox;\n\t        return i(bbox2, bbox1.x, bbox1.y)\n\t            || i(bbox2, bbox1.x2, bbox1.y)\n\t            || i(bbox2, bbox1.x, bbox1.y2)\n\t            || i(bbox2, bbox1.x2, bbox1.y2)\n\t            || i(bbox1, bbox2.x, bbox2.y)\n\t            || i(bbox1, bbox2.x2, bbox2.y)\n\t            || i(bbox1, bbox2.x, bbox2.y2)\n\t            || i(bbox1, bbox2.x2, bbox2.y2)\n\t            || (bbox1.x < bbox2.x2 && bbox1.x > bbox2.x || bbox2.x < bbox1.x2 && bbox2.x > bbox1.x)\n\t            && (bbox1.y < bbox2.y2 && bbox1.y > bbox2.y || bbox2.y < bbox1.y2 && bbox2.y > bbox1.y);\n\t    };\n\t    function base3(t, p1, p2, p3, p4) {\n\t        var t1 = -3 * p1 + 9 * p2 - 9 * p3 + 3 * p4,\n\t            t2 = t * t1 + 6 * p1 - 12 * p2 + 6 * p3;\n\t        return t * t2 - 3 * p1 + 3 * p2;\n\t    }\n\t    function bezlen(x1, y1, x2, y2, x3, y3, x4, y4, z) {\n\t        if (z == null) {\n\t            z = 1;\n\t        }\n\t        z = z > 1 ? 1 : z < 0 ? 0 : z;\n\t        var z2 = z / 2,\n\t            n = 12,\n\t            Tvalues = [-0.1252,0.1252,-0.3678,0.3678,-0.5873,0.5873,-0.7699,0.7699,-0.9041,0.9041,-0.9816,0.9816],\n\t            Cvalues = [0.2491,0.2491,0.2335,0.2335,0.2032,0.2032,0.1601,0.1601,0.1069,0.1069,0.0472,0.0472],\n\t            sum = 0;\n\t        for (var i = 0; i < n; i++) {\n\t            var ct = z2 * Tvalues[i] + z2,\n\t                xbase = base3(ct, x1, x2, x3, x4),\n\t                ybase = base3(ct, y1, y2, y3, y4),\n\t                comb = xbase * xbase + ybase * ybase;\n\t            sum += Cvalues[i] * math.sqrt(comb);\n\t        }\n\t        return z2 * sum;\n\t    }\n\t    function getTatLen(x1, y1, x2, y2, x3, y3, x4, y4, ll) {\n\t        if (ll < 0 || bezlen(x1, y1, x2, y2, x3, y3, x4, y4) < ll) {\n\t            return;\n\t        }\n\t        var t = 1,\n\t            step = t / 2,\n\t            t2 = t - step,\n\t            l,\n\t            e = .01;\n\t        l = bezlen(x1, y1, x2, y2, x3, y3, x4, y4, t2);\n\t        while (abs(l - ll) > e) {\n\t            step /= 2;\n\t            t2 += (l < ll ? 1 : -1) * step;\n\t            l = bezlen(x1, y1, x2, y2, x3, y3, x4, y4, t2);\n\t        }\n\t        return t2;\n\t    }\n\t    function intersect(x1, y1, x2, y2, x3, y3, x4, y4) {\n\t        if (\n\t            mmax(x1, x2) < mmin(x3, x4) ||\n\t            mmin(x1, x2) > mmax(x3, x4) ||\n\t            mmax(y1, y2) < mmin(y3, y4) ||\n\t            mmin(y1, y2) > mmax(y3, y4)\n\t        ) {\n\t            return;\n\t        }\n\t        var nx = (x1 * y2 - y1 * x2) * (x3 - x4) - (x1 - x2) * (x3 * y4 - y3 * x4),\n\t            ny = (x1 * y2 - y1 * x2) * (y3 - y4) - (y1 - y2) * (x3 * y4 - y3 * x4),\n\t            denominator = (x1 - x2) * (y3 - y4) - (y1 - y2) * (x3 - x4);\n\n\t        if (!denominator) {\n\t            return;\n\t        }\n\t        var px = nx / denominator,\n\t            py = ny / denominator,\n\t            px2 = +px.toFixed(2),\n\t            py2 = +py.toFixed(2);\n\t        if (\n\t            px2 < +mmin(x1, x2).toFixed(2) ||\n\t            px2 > +mmax(x1, x2).toFixed(2) ||\n\t            px2 < +mmin(x3, x4).toFixed(2) ||\n\t            px2 > +mmax(x3, x4).toFixed(2) ||\n\t            py2 < +mmin(y1, y2).toFixed(2) ||\n\t            py2 > +mmax(y1, y2).toFixed(2) ||\n\t            py2 < +mmin(y3, y4).toFixed(2) ||\n\t            py2 > +mmax(y3, y4).toFixed(2)\n\t        ) {\n\t            return;\n\t        }\n\t        return {x: px, y: py};\n\t    }\n\t    function inter(bez1, bez2) {\n\t        return interHelper(bez1, bez2);\n\t    }\n\t    function interCount(bez1, bez2) {\n\t        return interHelper(bez1, bez2, 1);\n\t    }\n\t    function interHelper(bez1, bez2, justCount) {\n\t        var bbox1 = R.bezierBBox(bez1),\n\t            bbox2 = R.bezierBBox(bez2);\n\t        if (!R.isBBoxIntersect(bbox1, bbox2)) {\n\t            return justCount ? 0 : [];\n\t        }\n\t        var l1 = bezlen.apply(0, bez1),\n\t            l2 = bezlen.apply(0, bez2),\n\t            n1 = mmax(~~(l1 / 5), 1),\n\t            n2 = mmax(~~(l2 / 5), 1),\n\t            dots1 = [],\n\t            dots2 = [],\n\t            xy = {},\n\t            res = justCount ? 0 : [];\n\t        for (var i = 0; i < n1 + 1; i++) {\n\t            var p = R.findDotsAtSegment.apply(R, bez1.concat(i / n1));\n\t            dots1.push({x: p.x, y: p.y, t: i / n1});\n\t        }\n\t        for (i = 0; i < n2 + 1; i++) {\n\t            p = R.findDotsAtSegment.apply(R, bez2.concat(i / n2));\n\t            dots2.push({x: p.x, y: p.y, t: i / n2});\n\t        }\n\t        for (i = 0; i < n1; i++) {\n\t            for (var j = 0; j < n2; j++) {\n\t                var di = dots1[i],\n\t                    di1 = dots1[i + 1],\n\t                    dj = dots2[j],\n\t                    dj1 = dots2[j + 1],\n\t                    ci = abs(di1.x - di.x) < .001 ? \"y\" : \"x\",\n\t                    cj = abs(dj1.x - dj.x) < .001 ? \"y\" : \"x\",\n\t                    is = intersect(di.x, di.y, di1.x, di1.y, dj.x, dj.y, dj1.x, dj1.y);\n\t                if (is) {\n\t                    if (xy[is.x.toFixed(4)] == is.y.toFixed(4)) {\n\t                        continue;\n\t                    }\n\t                    xy[is.x.toFixed(4)] = is.y.toFixed(4);\n\t                    var t1 = di.t + abs((is[ci] - di[ci]) / (di1[ci] - di[ci])) * (di1.t - di.t),\n\t                        t2 = dj.t + abs((is[cj] - dj[cj]) / (dj1[cj] - dj[cj])) * (dj1.t - dj.t);\n\t                    if (t1 >= 0 && t1 <= 1.001 && t2 >= 0 && t2 <= 1.001) {\n\t                        if (justCount) {\n\t                            res++;\n\t                        } else {\n\t                            res.push({\n\t                                x: is.x,\n\t                                y: is.y,\n\t                                t1: mmin(t1, 1),\n\t                                t2: mmin(t2, 1)\n\t                            });\n\t                        }\n\t                    }\n\t                }\n\t            }\n\t        }\n\t        return res;\n\t    }\n\t    /*\\\n\t     * Raphael.pathIntersection\n\t     [ method ]\n\t     **\n\t     * Utility method\n\t     **\n\t     * Finds intersections of two paths\n\t     > Parameters\n\t     - path1 (string) path string\n\t     - path2 (string) path string\n\t     = (array) dots of intersection\n\t     o [\n\t     o     {\n\t     o         x: (number) x coordinate of the point\n\t     o         y: (number) y coordinate of the point\n\t     o         t1: (number) t value for segment of path1\n\t     o         t2: (number) t value for segment of path2\n\t     o         segment1: (number) order number for segment of path1\n\t     o         segment2: (number) order number for segment of path2\n\t     o         bez1: (array) eight coordinates representing beziér curve for the segment of path1\n\t     o         bez2: (array) eight coordinates representing beziér curve for the segment of path2\n\t     o     }\n\t     o ]\n\t    \\*/\n\t    R.pathIntersection = function (path1, path2) {\n\t        return interPathHelper(path1, path2);\n\t    };\n\t    R.pathIntersectionNumber = function (path1, path2) {\n\t        return interPathHelper(path1, path2, 1);\n\t    };\n\t    function interPathHelper(path1, path2, justCount) {\n\t        path1 = R._path2curve(path1);\n\t        path2 = R._path2curve(path2);\n\t        var x1, y1, x2, y2, x1m, y1m, x2m, y2m, bez1, bez2,\n\t            res = justCount ? 0 : [];\n\t        for (var i = 0, ii = path1.length; i < ii; i++) {\n\t            var pi = path1[i];\n\t            if (pi[0] == \"M\") {\n\t                x1 = x1m = pi[1];\n\t                y1 = y1m = pi[2];\n\t            } else {\n\t                if (pi[0] == \"C\") {\n\t                    bez1 = [x1, y1].concat(pi.slice(1));\n\t                    x1 = bez1[6];\n\t                    y1 = bez1[7];\n\t                } else {\n\t                    bez1 = [x1, y1, x1, y1, x1m, y1m, x1m, y1m];\n\t                    x1 = x1m;\n\t                    y1 = y1m;\n\t                }\n\t                for (var j = 0, jj = path2.length; j < jj; j++) {\n\t                    var pj = path2[j];\n\t                    if (pj[0] == \"M\") {\n\t                        x2 = x2m = pj[1];\n\t                        y2 = y2m = pj[2];\n\t                    } else {\n\t                        if (pj[0] == \"C\") {\n\t                            bez2 = [x2, y2].concat(pj.slice(1));\n\t                            x2 = bez2[6];\n\t                            y2 = bez2[7];\n\t                        } else {\n\t                            bez2 = [x2, y2, x2, y2, x2m, y2m, x2m, y2m];\n\t                            x2 = x2m;\n\t                            y2 = y2m;\n\t                        }\n\t                        var intr = interHelper(bez1, bez2, justCount);\n\t                        if (justCount) {\n\t                            res += intr;\n\t                        } else {\n\t                            for (var k = 0, kk = intr.length; k < kk; k++) {\n\t                                intr[k].segment1 = i;\n\t                                intr[k].segment2 = j;\n\t                                intr[k].bez1 = bez1;\n\t                                intr[k].bez2 = bez2;\n\t                            }\n\t                            res = res.concat(intr);\n\t                        }\n\t                    }\n\t                }\n\t            }\n\t        }\n\t        return res;\n\t    }\n\t    /*\\\n\t     * Raphael.isPointInsidePath\n\t     [ method ]\n\t     **\n\t     * Utility method\n\t     **\n\t     * Returns `true` if given point is inside a given closed path.\n\t     > Parameters\n\t     - path (string) path string\n\t     - x (number) x of the point\n\t     - y (number) y of the point\n\t     = (boolean) true, if point is inside the path\n\t    \\*/\n\t    R.isPointInsidePath = function (path, x, y) {\n\t        var bbox = R.pathBBox(path);\n\t        return R.isPointInsideBBox(bbox, x, y) &&\n\t               interPathHelper(path, [[\"M\", x, y], [\"H\", bbox.x2 + 10]], 1) % 2 == 1;\n\t    };\n\t    R._removedFactory = function (methodname) {\n\t        return function () {\n\t            eve(\"raphael.log\", null, \"Rapha\\xebl: you are calling to method \\u201c\" + methodname + \"\\u201d of removed object\", methodname);\n\t        };\n\t    };\n\t    /*\\\n\t     * Raphael.pathBBox\n\t     [ method ]\n\t     **\n\t     * Utility method\n\t     **\n\t     * Return bounding box of a given path\n\t     > Parameters\n\t     - path (string) path string\n\t     = (object) bounding box\n\t     o {\n\t     o     x: (number) x coordinate of the left top point of the box\n\t     o     y: (number) y coordinate of the left top point of the box\n\t     o     x2: (number) x coordinate of the right bottom point of the box\n\t     o     y2: (number) y coordinate of the right bottom point of the box\n\t     o     width: (number) width of the box\n\t     o     height: (number) height of the box\n\t     o     cx: (number) x coordinate of the center of the box\n\t     o     cy: (number) y coordinate of the center of the box\n\t     o }\n\t    \\*/\n\t    var pathDimensions = R.pathBBox = function (path) {\n\t        var pth = paths(path);\n\t        if (pth.bbox) {\n\t            return clone(pth.bbox);\n\t        }\n\t        if (!path) {\n\t            return {x: 0, y: 0, width: 0, height: 0, x2: 0, y2: 0};\n\t        }\n\t        path = path2curve(path);\n\t        var x = 0,\n\t            y = 0,\n\t            X = [],\n\t            Y = [],\n\t            p;\n\t        for (var i = 0, ii = path.length; i < ii; i++) {\n\t            p = path[i];\n\t            if (p[0] == \"M\") {\n\t                x = p[1];\n\t                y = p[2];\n\t                X.push(x);\n\t                Y.push(y);\n\t            } else {\n\t                var dim = curveDim(x, y, p[1], p[2], p[3], p[4], p[5], p[6]);\n\t                X = X[concat](dim.min.x, dim.max.x);\n\t                Y = Y[concat](dim.min.y, dim.max.y);\n\t                x = p[5];\n\t                y = p[6];\n\t            }\n\t        }\n\t        var xmin = mmin[apply](0, X),\n\t            ymin = mmin[apply](0, Y),\n\t            xmax = mmax[apply](0, X),\n\t            ymax = mmax[apply](0, Y),\n\t            width = xmax - xmin,\n\t            height = ymax - ymin,\n\t                bb = {\n\t                x: xmin,\n\t                y: ymin,\n\t                x2: xmax,\n\t                y2: ymax,\n\t                width: width,\n\t                height: height,\n\t                cx: xmin + width / 2,\n\t                cy: ymin + height / 2\n\t            };\n\t        pth.bbox = clone(bb);\n\t        return bb;\n\t    },\n\t        pathClone = function (pathArray) {\n\t            var res = clone(pathArray);\n\t            res.toString = R._path2string;\n\t            return res;\n\t        },\n\t        pathToRelative = R._pathToRelative = function (pathArray) {\n\t            var pth = paths(pathArray);\n\t            if (pth.rel) {\n\t                return pathClone(pth.rel);\n\t            }\n\t            if (!R.is(pathArray, array) || !R.is(pathArray && pathArray[0], array)) { // rough assumption\n\t                pathArray = R.parsePathString(pathArray);\n\t            }\n\t            var res = [],\n\t                x = 0,\n\t                y = 0,\n\t                mx = 0,\n\t                my = 0,\n\t                start = 0;\n\t            if (pathArray[0][0] == \"M\") {\n\t                x = pathArray[0][1];\n\t                y = pathArray[0][2];\n\t                mx = x;\n\t                my = y;\n\t                start++;\n\t                res.push([\"M\", x, y]);\n\t            }\n\t            for (var i = start, ii = pathArray.length; i < ii; i++) {\n\t                var r = res[i] = [],\n\t                    pa = pathArray[i];\n\t                if (pa[0] != lowerCase.call(pa[0])) {\n\t                    r[0] = lowerCase.call(pa[0]);\n\t                    switch (r[0]) {\n\t                        case \"a\":\n\t                            r[1] = pa[1];\n\t                            r[2] = pa[2];\n\t                            r[3] = pa[3];\n\t                            r[4] = pa[4];\n\t                            r[5] = pa[5];\n\t                            r[6] = +(pa[6] - x).toFixed(3);\n\t                            r[7] = +(pa[7] - y).toFixed(3);\n\t                            break;\n\t                        case \"v\":\n\t                            r[1] = +(pa[1] - y).toFixed(3);\n\t                            break;\n\t                        case \"m\":\n\t                            mx = pa[1];\n\t                            my = pa[2];\n\t                        default:\n\t                            for (var j = 1, jj = pa.length; j < jj; j++) {\n\t                                r[j] = +(pa[j] - ((j % 2) ? x : y)).toFixed(3);\n\t                            }\n\t                    }\n\t                } else {\n\t                    r = res[i] = [];\n\t                    if (pa[0] == \"m\") {\n\t                        mx = pa[1] + x;\n\t                        my = pa[2] + y;\n\t                    }\n\t                    for (var k = 0, kk = pa.length; k < kk; k++) {\n\t                        res[i][k] = pa[k];\n\t                    }\n\t                }\n\t                var len = res[i].length;\n\t                switch (res[i][0]) {\n\t                    case \"z\":\n\t                        x = mx;\n\t                        y = my;\n\t                        break;\n\t                    case \"h\":\n\t                        x += +res[i][len - 1];\n\t                        break;\n\t                    case \"v\":\n\t                        y += +res[i][len - 1];\n\t                        break;\n\t                    default:\n\t                        x += +res[i][len - 2];\n\t                        y += +res[i][len - 1];\n\t                }\n\t            }\n\t            res.toString = R._path2string;\n\t            pth.rel = pathClone(res);\n\t            return res;\n\t        },\n\t        pathToAbsolute = R._pathToAbsolute = function (pathArray) {\n\t            var pth = paths(pathArray);\n\t            if (pth.abs) {\n\t                return pathClone(pth.abs);\n\t            }\n\t            if (!R.is(pathArray, array) || !R.is(pathArray && pathArray[0], array)) { // rough assumption\n\t                pathArray = R.parsePathString(pathArray);\n\t            }\n\t            if (!pathArray || !pathArray.length) {\n\t                return [[\"M\", 0, 0]];\n\t            }\n\t            var res = [],\n\t                x = 0,\n\t                y = 0,\n\t                mx = 0,\n\t                my = 0,\n\t                start = 0;\n\t            if (pathArray[0][0] == \"M\") {\n\t                x = +pathArray[0][1];\n\t                y = +pathArray[0][2];\n\t                mx = x;\n\t                my = y;\n\t                start++;\n\t                res[0] = [\"M\", x, y];\n\t            }\n\t            var crz = pathArray.length == 3 && pathArray[0][0] == \"M\" && pathArray[1][0].toUpperCase() == \"R\" && pathArray[2][0].toUpperCase() == \"Z\";\n\t            for (var r, pa, i = start, ii = pathArray.length; i < ii; i++) {\n\t                res.push(r = []);\n\t                pa = pathArray[i];\n\t                if (pa[0] != upperCase.call(pa[0])) {\n\t                    r[0] = upperCase.call(pa[0]);\n\t                    switch (r[0]) {\n\t                        case \"A\":\n\t                            r[1] = pa[1];\n\t                            r[2] = pa[2];\n\t                            r[3] = pa[3];\n\t                            r[4] = pa[4];\n\t                            r[5] = pa[5];\n\t                            r[6] = +(pa[6] + x);\n\t                            r[7] = +(pa[7] + y);\n\t                            break;\n\t                        case \"V\":\n\t                            r[1] = +pa[1] + y;\n\t                            break;\n\t                        case \"H\":\n\t                            r[1] = +pa[1] + x;\n\t                            break;\n\t                        case \"R\":\n\t                            var dots = [x, y][concat](pa.slice(1));\n\t                            for (var j = 2, jj = dots.length; j < jj; j++) {\n\t                                dots[j] = +dots[j] + x;\n\t                                dots[++j] = +dots[j] + y;\n\t                            }\n\t                            res.pop();\n\t                            res = res[concat](catmullRom2bezier(dots, crz));\n\t                            break;\n\t                        case \"M\":\n\t                            mx = +pa[1] + x;\n\t                            my = +pa[2] + y;\n\t                        default:\n\t                            for (j = 1, jj = pa.length; j < jj; j++) {\n\t                                r[j] = +pa[j] + ((j % 2) ? x : y);\n\t                            }\n\t                    }\n\t                } else if (pa[0] == \"R\") {\n\t                    dots = [x, y][concat](pa.slice(1));\n\t                    res.pop();\n\t                    res = res[concat](catmullRom2bezier(dots, crz));\n\t                    r = [\"R\"][concat](pa.slice(-2));\n\t                } else {\n\t                    for (var k = 0, kk = pa.length; k < kk; k++) {\n\t                        r[k] = pa[k];\n\t                    }\n\t                }\n\t                switch (r[0]) {\n\t                    case \"Z\":\n\t                        x = mx;\n\t                        y = my;\n\t                        break;\n\t                    case \"H\":\n\t                        x = r[1];\n\t                        break;\n\t                    case \"V\":\n\t                        y = r[1];\n\t                        break;\n\t                    case \"M\":\n\t                        mx = r[r.length - 2];\n\t                        my = r[r.length - 1];\n\t                    default:\n\t                        x = r[r.length - 2];\n\t                        y = r[r.length - 1];\n\t                }\n\t            }\n\t            res.toString = R._path2string;\n\t            pth.abs = pathClone(res);\n\t            return res;\n\t        },\n\t        l2c = function (x1, y1, x2, y2) {\n\t            return [x1, y1, x2, y2, x2, y2];\n\t        },\n\t        q2c = function (x1, y1, ax, ay, x2, y2) {\n\t            var _13 = 1 / 3,\n\t                _23 = 2 / 3;\n\t            return [\n\t                    _13 * x1 + _23 * ax,\n\t                    _13 * y1 + _23 * ay,\n\t                    _13 * x2 + _23 * ax,\n\t                    _13 * y2 + _23 * ay,\n\t                    x2,\n\t                    y2\n\t                ];\n\t        },\n\t        a2c = function (x1, y1, rx, ry, angle, large_arc_flag, sweep_flag, x2, y2, recursive) {\n\t            // for more information of where this math came from visit:\n\t            // http://www.w3.org/TR/SVG11/implnote.html#ArcImplementationNotes\n\t            var _120 = PI * 120 / 180,\n\t                rad = PI / 180 * (+angle || 0),\n\t                res = [],\n\t                xy,\n\t                rotate = cacher(function (x, y, rad) {\n\t                    var X = x * math.cos(rad) - y * math.sin(rad),\n\t                        Y = x * math.sin(rad) + y * math.cos(rad);\n\t                    return {x: X, y: Y};\n\t                });\n\t            if (!recursive) {\n\t                xy = rotate(x1, y1, -rad);\n\t                x1 = xy.x;\n\t                y1 = xy.y;\n\t                xy = rotate(x2, y2, -rad);\n\t                x2 = xy.x;\n\t                y2 = xy.y;\n\t                var cos = math.cos(PI / 180 * angle),\n\t                    sin = math.sin(PI / 180 * angle),\n\t                    x = (x1 - x2) / 2,\n\t                    y = (y1 - y2) / 2;\n\t                var h = (x * x) / (rx * rx) + (y * y) / (ry * ry);\n\t                if (h > 1) {\n\t                    h = math.sqrt(h);\n\t                    rx = h * rx;\n\t                    ry = h * ry;\n\t                }\n\t                var rx2 = rx * rx,\n\t                    ry2 = ry * ry,\n\t                    k = (large_arc_flag == sweep_flag ? -1 : 1) *\n\t                        math.sqrt(abs((rx2 * ry2 - rx2 * y * y - ry2 * x * x) / (rx2 * y * y + ry2 * x * x))),\n\t                    cx = k * rx * y / ry + (x1 + x2) / 2,\n\t                    cy = k * -ry * x / rx + (y1 + y2) / 2,\n\t                    f1 = math.asin(((y1 - cy) / ry).toFixed(9)),\n\t                    f2 = math.asin(((y2 - cy) / ry).toFixed(9));\n\n\t                f1 = x1 < cx ? PI - f1 : f1;\n\t                f2 = x2 < cx ? PI - f2 : f2;\n\t                f1 < 0 && (f1 = PI * 2 + f1);\n\t                f2 < 0 && (f2 = PI * 2 + f2);\n\t                if (sweep_flag && f1 > f2) {\n\t                    f1 = f1 - PI * 2;\n\t                }\n\t                if (!sweep_flag && f2 > f1) {\n\t                    f2 = f2 - PI * 2;\n\t                }\n\t            } else {\n\t                f1 = recursive[0];\n\t                f2 = recursive[1];\n\t                cx = recursive[2];\n\t                cy = recursive[3];\n\t            }\n\t            var df = f2 - f1;\n\t            if (abs(df) > _120) {\n\t                var f2old = f2,\n\t                    x2old = x2,\n\t                    y2old = y2;\n\t                f2 = f1 + _120 * (sweep_flag && f2 > f1 ? 1 : -1);\n\t                x2 = cx + rx * math.cos(f2);\n\t                y2 = cy + ry * math.sin(f2);\n\t                res = a2c(x2, y2, rx, ry, angle, 0, sweep_flag, x2old, y2old, [f2, f2old, cx, cy]);\n\t            }\n\t            df = f2 - f1;\n\t            var c1 = math.cos(f1),\n\t                s1 = math.sin(f1),\n\t                c2 = math.cos(f2),\n\t                s2 = math.sin(f2),\n\t                t = math.tan(df / 4),\n\t                hx = 4 / 3 * rx * t,\n\t                hy = 4 / 3 * ry * t,\n\t                m1 = [x1, y1],\n\t                m2 = [x1 + hx * s1, y1 - hy * c1],\n\t                m3 = [x2 + hx * s2, y2 - hy * c2],\n\t                m4 = [x2, y2];\n\t            m2[0] = 2 * m1[0] - m2[0];\n\t            m2[1] = 2 * m1[1] - m2[1];\n\t            if (recursive) {\n\t                return [m2, m3, m4][concat](res);\n\t            } else {\n\t                res = [m2, m3, m4][concat](res).join()[split](\",\");\n\t                var newres = [];\n\t                for (var i = 0, ii = res.length; i < ii; i++) {\n\t                    newres[i] = i % 2 ? rotate(res[i - 1], res[i], rad).y : rotate(res[i], res[i + 1], rad).x;\n\t                }\n\t                return newres;\n\t            }\n\t        },\n\t        findDotAtSegment = function (p1x, p1y, c1x, c1y, c2x, c2y, p2x, p2y, t) {\n\t            var t1 = 1 - t;\n\t            return {\n\t                x: pow(t1, 3) * p1x + pow(t1, 2) * 3 * t * c1x + t1 * 3 * t * t * c2x + pow(t, 3) * p2x,\n\t                y: pow(t1, 3) * p1y + pow(t1, 2) * 3 * t * c1y + t1 * 3 * t * t * c2y + pow(t, 3) * p2y\n\t            };\n\t        },\n\t        curveDim = cacher(function (p1x, p1y, c1x, c1y, c2x, c2y, p2x, p2y) {\n\t            var a = (c2x - 2 * c1x + p1x) - (p2x - 2 * c2x + c1x),\n\t                b = 2 * (c1x - p1x) - 2 * (c2x - c1x),\n\t                c = p1x - c1x,\n\t                t1 = (-b + math.sqrt(b * b - 4 * a * c)) / 2 / a,\n\t                t2 = (-b - math.sqrt(b * b - 4 * a * c)) / 2 / a,\n\t                y = [p1y, p2y],\n\t                x = [p1x, p2x],\n\t                dot;\n\t            abs(t1) > \"1e12\" && (t1 = .5);\n\t            abs(t2) > \"1e12\" && (t2 = .5);\n\t            if (t1 > 0 && t1 < 1) {\n\t                dot = findDotAtSegment(p1x, p1y, c1x, c1y, c2x, c2y, p2x, p2y, t1);\n\t                x.push(dot.x);\n\t                y.push(dot.y);\n\t            }\n\t            if (t2 > 0 && t2 < 1) {\n\t                dot = findDotAtSegment(p1x, p1y, c1x, c1y, c2x, c2y, p2x, p2y, t2);\n\t                x.push(dot.x);\n\t                y.push(dot.y);\n\t            }\n\t            a = (c2y - 2 * c1y + p1y) - (p2y - 2 * c2y + c1y);\n\t            b = 2 * (c1y - p1y) - 2 * (c2y - c1y);\n\t            c = p1y - c1y;\n\t            t1 = (-b + math.sqrt(b * b - 4 * a * c)) / 2 / a;\n\t            t2 = (-b - math.sqrt(b * b - 4 * a * c)) / 2 / a;\n\t            abs(t1) > \"1e12\" && (t1 = .5);\n\t            abs(t2) > \"1e12\" && (t2 = .5);\n\t            if (t1 > 0 && t1 < 1) {\n\t                dot = findDotAtSegment(p1x, p1y, c1x, c1y, c2x, c2y, p2x, p2y, t1);\n\t                x.push(dot.x);\n\t                y.push(dot.y);\n\t            }\n\t            if (t2 > 0 && t2 < 1) {\n\t                dot = findDotAtSegment(p1x, p1y, c1x, c1y, c2x, c2y, p2x, p2y, t2);\n\t                x.push(dot.x);\n\t                y.push(dot.y);\n\t            }\n\t            return {\n\t                min: {x: mmin[apply](0, x), y: mmin[apply](0, y)},\n\t                max: {x: mmax[apply](0, x), y: mmax[apply](0, y)}\n\t            };\n\t        }),\n\t        path2curve = R._path2curve = cacher(function (path, path2) {\n\t            var pth = !path2 && paths(path);\n\t            if (!path2 && pth.curve) {\n\t                return pathClone(pth.curve);\n\t            }\n\t            var p = pathToAbsolute(path),\n\t                p2 = path2 && pathToAbsolute(path2),\n\t                attrs = {x: 0, y: 0, bx: 0, by: 0, X: 0, Y: 0, qx: null, qy: null},\n\t                attrs2 = {x: 0, y: 0, bx: 0, by: 0, X: 0, Y: 0, qx: null, qy: null},\n\t                processPath = function (path, d, pcom) {\n\t                    var nx, ny, tq = {T:1, Q:1};\n\t                    if (!path) {\n\t                        return [\"C\", d.x, d.y, d.x, d.y, d.x, d.y];\n\t                    }\n\t                    !(path[0] in tq) && (d.qx = d.qy = null);\n\t                    switch (path[0]) {\n\t                        case \"M\":\n\t                            d.X = path[1];\n\t                            d.Y = path[2];\n\t                            break;\n\t                        case \"A\":\n\t                            path = [\"C\"][concat](a2c[apply](0, [d.x, d.y][concat](path.slice(1))));\n\t                            break;\n\t                        case \"S\":\n\t                            if (pcom == \"C\" || pcom == \"S\") { // In \"S\" case we have to take into account, if the previous command is C/S.\n\t                                nx = d.x * 2 - d.bx;          // And reflect the previous\n\t                                ny = d.y * 2 - d.by;          // command's control point relative to the current point.\n\t                            }\n\t                            else {                            // or some else or nothing\n\t                                nx = d.x;\n\t                                ny = d.y;\n\t                            }\n\t                            path = [\"C\", nx, ny][concat](path.slice(1));\n\t                            break;\n\t                        case \"T\":\n\t                            if (pcom == \"Q\" || pcom == \"T\") { // In \"T\" case we have to take into account, if the previous command is Q/T.\n\t                                d.qx = d.x * 2 - d.qx;        // And make a reflection similar\n\t                                d.qy = d.y * 2 - d.qy;        // to case \"S\".\n\t                            }\n\t                            else {                            // or something else or nothing\n\t                                d.qx = d.x;\n\t                                d.qy = d.y;\n\t                            }\n\t                            path = [\"C\"][concat](q2c(d.x, d.y, d.qx, d.qy, path[1], path[2]));\n\t                            break;\n\t                        case \"Q\":\n\t                            d.qx = path[1];\n\t                            d.qy = path[2];\n\t                            path = [\"C\"][concat](q2c(d.x, d.y, path[1], path[2], path[3], path[4]));\n\t                            break;\n\t                        case \"L\":\n\t                            path = [\"C\"][concat](l2c(d.x, d.y, path[1], path[2]));\n\t                            break;\n\t                        case \"H\":\n\t                            path = [\"C\"][concat](l2c(d.x, d.y, path[1], d.y));\n\t                            break;\n\t                        case \"V\":\n\t                            path = [\"C\"][concat](l2c(d.x, d.y, d.x, path[1]));\n\t                            break;\n\t                        case \"Z\":\n\t                            path = [\"C\"][concat](l2c(d.x, d.y, d.X, d.Y));\n\t                            break;\n\t                    }\n\t                    return path;\n\t                },\n\t                fixArc = function (pp, i) {\n\t                    if (pp[i].length > 7) {\n\t                        pp[i].shift();\n\t                        var pi = pp[i];\n\t                        while (pi.length) {\n\t                            pcoms1[i]=\"A\"; // if created multiple C:s, their original seg is saved\n\t                            p2 && (pcoms2[i]=\"A\"); // the same as above\n\t                            pp.splice(i++, 0, [\"C\"][concat](pi.splice(0, 6)));\n\t                        }\n\t                        pp.splice(i, 1);\n\t                        ii = mmax(p.length, p2 && p2.length || 0);\n\t                    }\n\t                },\n\t                fixM = function (path1, path2, a1, a2, i) {\n\t                    if (path1 && path2 && path1[i][0] == \"M\" && path2[i][0] != \"M\") {\n\t                        path2.splice(i, 0, [\"M\", a2.x, a2.y]);\n\t                        a1.bx = 0;\n\t                        a1.by = 0;\n\t                        a1.x = path1[i][1];\n\t                        a1.y = path1[i][2];\n\t                        ii = mmax(p.length, p2 && p2.length || 0);\n\t                    }\n\t                },\n\t                pcoms1 = [], // path commands of original path p\n\t                pcoms2 = [], // path commands of original path p2\n\t                pfirst = \"\", // temporary holder for original path command\n\t                pcom = \"\"; // holder for previous path command of original path\n\t            for (var i = 0, ii = mmax(p.length, p2 && p2.length || 0); i < ii; i++) {\n\t                p[i] && (pfirst = p[i][0]); // save current path command\n\n\t                if (pfirst != \"C\") // C is not saved yet, because it may be result of conversion\n\t                {\n\t                    pcoms1[i] = pfirst; // Save current path command\n\t                    i && ( pcom = pcoms1[i-1]); // Get previous path command pcom\n\t                }\n\t                p[i] = processPath(p[i], attrs, pcom); // Previous path command is inputted to processPath\n\n\t                if (pcoms1[i] != \"A\" && pfirst == \"C\") pcoms1[i] = \"C\"; // A is the only command\n\t                // which may produce multiple C:s\n\t                // so we have to make sure that C is also C in original path\n\n\t                fixArc(p, i); // fixArc adds also the right amount of A:s to pcoms1\n\n\t                if (p2) { // the same procedures is done to p2\n\t                    p2[i] && (pfirst = p2[i][0]);\n\t                    if (pfirst != \"C\")\n\t                    {\n\t                        pcoms2[i] = pfirst;\n\t                        i && (pcom = pcoms2[i-1]);\n\t                    }\n\t                    p2[i] = processPath(p2[i], attrs2, pcom);\n\n\t                    if (pcoms2[i]!=\"A\" && pfirst==\"C\") pcoms2[i]=\"C\";\n\n\t                    fixArc(p2, i);\n\t                }\n\t                fixM(p, p2, attrs, attrs2, i);\n\t                fixM(p2, p, attrs2, attrs, i);\n\t                var seg = p[i],\n\t                    seg2 = p2 && p2[i],\n\t                    seglen = seg.length,\n\t                    seg2len = p2 && seg2.length;\n\t                attrs.x = seg[seglen - 2];\n\t                attrs.y = seg[seglen - 1];\n\t                attrs.bx = toFloat(seg[seglen - 4]) || attrs.x;\n\t                attrs.by = toFloat(seg[seglen - 3]) || attrs.y;\n\t                attrs2.bx = p2 && (toFloat(seg2[seg2len - 4]) || attrs2.x);\n\t                attrs2.by = p2 && (toFloat(seg2[seg2len - 3]) || attrs2.y);\n\t                attrs2.x = p2 && seg2[seg2len - 2];\n\t                attrs2.y = p2 && seg2[seg2len - 1];\n\t            }\n\t            if (!p2) {\n\t                pth.curve = pathClone(p);\n\t            }\n\t            return p2 ? [p, p2] : p;\n\t        }, null, pathClone),\n\t        parseDots = R._parseDots = cacher(function (gradient) {\n\t            var dots = [];\n\t            for (var i = 0, ii = gradient.length; i < ii; i++) {\n\t                var dot = {},\n\t                    par = gradient[i].match(/^([^:]*):?([\\d\\.]*)/);\n\t                dot.color = R.getRGB(par[1]);\n\t                if (dot.color.error) {\n\t                    return null;\n\t                }\n\t                dot.opacity = dot.color.opacity;\n\t                dot.color = dot.color.hex;\n\t                par[2] && (dot.offset = par[2] + \"%\");\n\t                dots.push(dot);\n\t            }\n\t            for (i = 1, ii = dots.length - 1; i < ii; i++) {\n\t                if (!dots[i].offset) {\n\t                    var start = toFloat(dots[i - 1].offset || 0),\n\t                        end = 0;\n\t                    for (var j = i + 1; j < ii; j++) {\n\t                        if (dots[j].offset) {\n\t                            end = dots[j].offset;\n\t                            break;\n\t                        }\n\t                    }\n\t                    if (!end) {\n\t                        end = 100;\n\t                        j = ii;\n\t                    }\n\t                    end = toFloat(end);\n\t                    var d = (end - start) / (j - i + 1);\n\t                    for (; i < j; i++) {\n\t                        start += d;\n\t                        dots[i].offset = start + \"%\";\n\t                    }\n\t                }\n\t            }\n\t            return dots;\n\t        }),\n\t        tear = R._tear = function (el, paper) {\n\t            el == paper.top && (paper.top = el.prev);\n\t            el == paper.bottom && (paper.bottom = el.next);\n\t            el.next && (el.next.prev = el.prev);\n\t            el.prev && (el.prev.next = el.next);\n\t        },\n\t        tofront = R._tofront = function (el, paper) {\n\t            if (paper.top === el) {\n\t                return;\n\t            }\n\t            tear(el, paper);\n\t            el.next = null;\n\t            el.prev = paper.top;\n\t            paper.top.next = el;\n\t            paper.top = el;\n\t        },\n\t        toback = R._toback = function (el, paper) {\n\t            if (paper.bottom === el) {\n\t                return;\n\t            }\n\t            tear(el, paper);\n\t            el.next = paper.bottom;\n\t            el.prev = null;\n\t            paper.bottom.prev = el;\n\t            paper.bottom = el;\n\t        },\n\t        insertafter = R._insertafter = function (el, el2, paper) {\n\t            tear(el, paper);\n\t            el2 == paper.top && (paper.top = el);\n\t            el2.next && (el2.next.prev = el);\n\t            el.next = el2.next;\n\t            el.prev = el2;\n\t            el2.next = el;\n\t        },\n\t        insertbefore = R._insertbefore = function (el, el2, paper) {\n\t            tear(el, paper);\n\t            el2 == paper.bottom && (paper.bottom = el);\n\t            el2.prev && (el2.prev.next = el);\n\t            el.prev = el2.prev;\n\t            el2.prev = el;\n\t            el.next = el2;\n\t        },\n\t        /*\\\n\t         * Raphael.toMatrix\n\t         [ method ]\n\t         **\n\t         * Utility method\n\t         **\n\t         * Returns matrix of transformations applied to a given path\n\t         > Parameters\n\t         - path (string) path string\n\t         - transform (string|array) transformation string\n\t         = (object) @Matrix\n\t        \\*/\n\t        toMatrix = R.toMatrix = function (path, transform) {\n\t            var bb = pathDimensions(path),\n\t                el = {\n\t                    _: {\n\t                        transform: E\n\t                    },\n\t                    getBBox: function () {\n\t                        return bb;\n\t                    }\n\t                };\n\t            extractTransform(el, transform);\n\t            return el.matrix;\n\t        },\n\t        /*\\\n\t         * Raphael.transformPath\n\t         [ method ]\n\t         **\n\t         * Utility method\n\t         **\n\t         * Returns path transformed by a given transformation\n\t         > Parameters\n\t         - path (string) path string\n\t         - transform (string|array) transformation string\n\t         = (string) path\n\t        \\*/\n\t        transformPath = R.transformPath = function (path, transform) {\n\t            return mapPath(path, toMatrix(path, transform));\n\t        },\n\t        extractTransform = R._extractTransform = function (el, tstr) {\n\t            if (tstr == null) {\n\t                return el._.transform;\n\t            }\n\t            tstr = Str(tstr).replace(/\\.{3}|\\u2026/g, el._.transform || E);\n\t            var tdata = R.parseTransformString(tstr),\n\t                deg = 0,\n\t                dx = 0,\n\t                dy = 0,\n\t                sx = 1,\n\t                sy = 1,\n\t                _ = el._,\n\t                m = new Matrix;\n\t            _.transform = tdata || [];\n\t            if (tdata) {\n\t                for (var i = 0, ii = tdata.length; i < ii; i++) {\n\t                    var t = tdata[i],\n\t                        tlen = t.length,\n\t                        command = Str(t[0]).toLowerCase(),\n\t                        absolute = t[0] != command,\n\t                        inver = absolute ? m.invert() : 0,\n\t                        x1,\n\t                        y1,\n\t                        x2,\n\t                        y2,\n\t                        bb;\n\t                    if (command == \"t\" && tlen == 3) {\n\t                        if (absolute) {\n\t                            x1 = inver.x(0, 0);\n\t                            y1 = inver.y(0, 0);\n\t                            x2 = inver.x(t[1], t[2]);\n\t                            y2 = inver.y(t[1], t[2]);\n\t                            m.translate(x2 - x1, y2 - y1);\n\t                        } else {\n\t                            m.translate(t[1], t[2]);\n\t                        }\n\t                    } else if (command == \"r\") {\n\t                        if (tlen == 2) {\n\t                            bb = bb || el.getBBox(1);\n\t                            m.rotate(t[1], bb.x + bb.width / 2, bb.y + bb.height / 2);\n\t                            deg += t[1];\n\t                        } else if (tlen == 4) {\n\t                            if (absolute) {\n\t                                x2 = inver.x(t[2], t[3]);\n\t                                y2 = inver.y(t[2], t[3]);\n\t                                m.rotate(t[1], x2, y2);\n\t                            } else {\n\t                                m.rotate(t[1], t[2], t[3]);\n\t                            }\n\t                            deg += t[1];\n\t                        }\n\t                    } else if (command == \"s\") {\n\t                        if (tlen == 2 || tlen == 3) {\n\t                            bb = bb || el.getBBox(1);\n\t                            m.scale(t[1], t[tlen - 1], bb.x + bb.width / 2, bb.y + bb.height / 2);\n\t                            sx *= t[1];\n\t                            sy *= t[tlen - 1];\n\t                        } else if (tlen == 5) {\n\t                            if (absolute) {\n\t                                x2 = inver.x(t[3], t[4]);\n\t                                y2 = inver.y(t[3], t[4]);\n\t                                m.scale(t[1], t[2], x2, y2);\n\t                            } else {\n\t                                m.scale(t[1], t[2], t[3], t[4]);\n\t                            }\n\t                            sx *= t[1];\n\t                            sy *= t[2];\n\t                        }\n\t                    } else if (command == \"m\" && tlen == 7) {\n\t                        m.add(t[1], t[2], t[3], t[4], t[5], t[6]);\n\t                    }\n\t                    _.dirtyT = 1;\n\t                    el.matrix = m;\n\t                }\n\t            }\n\n\t            /*\\\n\t             * Element.matrix\n\t             [ property (object) ]\n\t             **\n\t             * Keeps @Matrix object, which represents element transformation\n\t            \\*/\n\t            el.matrix = m;\n\n\t            _.sx = sx;\n\t            _.sy = sy;\n\t            _.deg = deg;\n\t            _.dx = dx = m.e;\n\t            _.dy = dy = m.f;\n\n\t            if (sx == 1 && sy == 1 && !deg && _.bbox) {\n\t                _.bbox.x += +dx;\n\t                _.bbox.y += +dy;\n\t            } else {\n\t                _.dirtyT = 1;\n\t            }\n\t        },\n\t        getEmpty = function (item) {\n\t            var l = item[0];\n\t            switch (l.toLowerCase()) {\n\t                case \"t\": return [l, 0, 0];\n\t                case \"m\": return [l, 1, 0, 0, 1, 0, 0];\n\t                case \"r\": if (item.length == 4) {\n\t                    return [l, 0, item[2], item[3]];\n\t                } else {\n\t                    return [l, 0];\n\t                }\n\t                case \"s\": if (item.length == 5) {\n\t                    return [l, 1, 1, item[3], item[4]];\n\t                } else if (item.length == 3) {\n\t                    return [l, 1, 1];\n\t                } else {\n\t                    return [l, 1];\n\t                }\n\t            }\n\t        },\n\t        equaliseTransform = R._equaliseTransform = function (t1, t2) {\n\t            t2 = Str(t2).replace(/\\.{3}|\\u2026/g, t1);\n\t            t1 = R.parseTransformString(t1) || [];\n\t            t2 = R.parseTransformString(t2) || [];\n\t            var maxlength = mmax(t1.length, t2.length),\n\t                from = [],\n\t                to = [],\n\t                i = 0, j, jj,\n\t                tt1, tt2;\n\t            for (; i < maxlength; i++) {\n\t                tt1 = t1[i] || getEmpty(t2[i]);\n\t                tt2 = t2[i] || getEmpty(tt1);\n\t                if ((tt1[0] != tt2[0]) ||\n\t                    (tt1[0].toLowerCase() == \"r\" && (tt1[2] != tt2[2] || tt1[3] != tt2[3])) ||\n\t                    (tt1[0].toLowerCase() == \"s\" && (tt1[3] != tt2[3] || tt1[4] != tt2[4]))\n\t                    ) {\n\t                    return;\n\t                }\n\t                from[i] = [];\n\t                to[i] = [];\n\t                for (j = 0, jj = mmax(tt1.length, tt2.length); j < jj; j++) {\n\t                    j in tt1 && (from[i][j] = tt1[j]);\n\t                    j in tt2 && (to[i][j] = tt2[j]);\n\t                }\n\t            }\n\t            return {\n\t                from: from,\n\t                to: to\n\t            };\n\t        };\n\t    R._getContainer = function (x, y, w, h) {\n\t        var container;\n\t        container = h == null && !R.is(x, \"object\") ? g.doc.getElementById(x) : x;\n\t        if (container == null) {\n\t            return;\n\t        }\n\t        if (container.tagName) {\n\t            if (y == null) {\n\t                return {\n\t                    container: container,\n\t                    width: container.style.pixelWidth || container.offsetWidth,\n\t                    height: container.style.pixelHeight || container.offsetHeight\n\t                };\n\t            } else {\n\t                return {\n\t                    container: container,\n\t                    width: y,\n\t                    height: w\n\t                };\n\t            }\n\t        }\n\t        return {\n\t            container: 1,\n\t            x: x,\n\t            y: y,\n\t            width: w,\n\t            height: h\n\t        };\n\t    };\n\t    /*\\\n\t     * Raphael.pathToRelative\n\t     [ method ]\n\t     **\n\t     * Utility method\n\t     **\n\t     * Converts path to relative form\n\t     > Parameters\n\t     - pathString (string|array) path string or array of segments\n\t     = (array) array of segments.\n\t    \\*/\n\t    R.pathToRelative = pathToRelative;\n\t    R._engine = {};\n\t    /*\\\n\t     * Raphael.path2curve\n\t     [ method ]\n\t     **\n\t     * Utility method\n\t     **\n\t     * Converts path to a new path where all segments are cubic bezier curves.\n\t     > Parameters\n\t     - pathString (string|array) path string or array of segments\n\t     = (array) array of segments.\n\t    \\*/\n\t    R.path2curve = path2curve;\n\t    /*\\\n\t     * Raphael.matrix\n\t     [ method ]\n\t     **\n\t     * Utility method\n\t     **\n\t     * Returns matrix based on given parameters.\n\t     > Parameters\n\t     - a (number)\n\t     - b (number)\n\t     - c (number)\n\t     - d (number)\n\t     - e (number)\n\t     - f (number)\n\t     = (object) @Matrix\n\t    \\*/\n\t    R.matrix = function (a, b, c, d, e, f) {\n\t        return new Matrix(a, b, c, d, e, f);\n\t    };\n\t    function Matrix(a, b, c, d, e, f) {\n\t        if (a != null) {\n\t            this.a = +a;\n\t            this.b = +b;\n\t            this.c = +c;\n\t            this.d = +d;\n\t            this.e = +e;\n\t            this.f = +f;\n\t        } else {\n\t            this.a = 1;\n\t            this.b = 0;\n\t            this.c = 0;\n\t            this.d = 1;\n\t            this.e = 0;\n\t            this.f = 0;\n\t        }\n\t    }\n\t    (function (matrixproto) {\n\t        /*\\\n\t         * Matrix.add\n\t         [ method ]\n\t         **\n\t         * Adds given matrix to existing one.\n\t         > Parameters\n\t         - a (number)\n\t         - b (number)\n\t         - c (number)\n\t         - d (number)\n\t         - e (number)\n\t         - f (number)\n\t         or\n\t         - matrix (object) @Matrix\n\t        \\*/\n\t        matrixproto.add = function (a, b, c, d, e, f) {\n\t            var out = [[], [], []],\n\t                m = [[this.a, this.c, this.e], [this.b, this.d, this.f], [0, 0, 1]],\n\t                matrix = [[a, c, e], [b, d, f], [0, 0, 1]],\n\t                x, y, z, res;\n\n\t            if (a && a instanceof Matrix) {\n\t                matrix = [[a.a, a.c, a.e], [a.b, a.d, a.f], [0, 0, 1]];\n\t            }\n\n\t            for (x = 0; x < 3; x++) {\n\t                for (y = 0; y < 3; y++) {\n\t                    res = 0;\n\t                    for (z = 0; z < 3; z++) {\n\t                        res += m[x][z] * matrix[z][y];\n\t                    }\n\t                    out[x][y] = res;\n\t                }\n\t            }\n\t            this.a = out[0][0];\n\t            this.b = out[1][0];\n\t            this.c = out[0][1];\n\t            this.d = out[1][1];\n\t            this.e = out[0][2];\n\t            this.f = out[1][2];\n\t        };\n\t        /*\\\n\t         * Matrix.invert\n\t         [ method ]\n\t         **\n\t         * Returns inverted version of the matrix\n\t         = (object) @Matrix\n\t        \\*/\n\t        matrixproto.invert = function () {\n\t            var me = this,\n\t                x = me.a * me.d - me.b * me.c;\n\t            return new Matrix(me.d / x, -me.b / x, -me.c / x, me.a / x, (me.c * me.f - me.d * me.e) / x, (me.b * me.e - me.a * me.f) / x);\n\t        };\n\t        /*\\\n\t         * Matrix.clone\n\t         [ method ]\n\t         **\n\t         * Returns copy of the matrix\n\t         = (object) @Matrix\n\t        \\*/\n\t        matrixproto.clone = function () {\n\t            return new Matrix(this.a, this.b, this.c, this.d, this.e, this.f);\n\t        };\n\t        /*\\\n\t         * Matrix.translate\n\t         [ method ]\n\t         **\n\t         * Translate the matrix\n\t         > Parameters\n\t         - x (number)\n\t         - y (number)\n\t        \\*/\n\t        matrixproto.translate = function (x, y) {\n\t            this.add(1, 0, 0, 1, x, y);\n\t        };\n\t        /*\\\n\t         * Matrix.scale\n\t         [ method ]\n\t         **\n\t         * Scales the matrix\n\t         > Parameters\n\t         - x (number)\n\t         - y (number) #optional\n\t         - cx (number) #optional\n\t         - cy (number) #optional\n\t        \\*/\n\t        matrixproto.scale = function (x, y, cx, cy) {\n\t            y == null && (y = x);\n\t            (cx || cy) && this.add(1, 0, 0, 1, cx, cy);\n\t            this.add(x, 0, 0, y, 0, 0);\n\t            (cx || cy) && this.add(1, 0, 0, 1, -cx, -cy);\n\t        };\n\t        /*\\\n\t         * Matrix.rotate\n\t         [ method ]\n\t         **\n\t         * Rotates the matrix\n\t         > Parameters\n\t         - a (number)\n\t         - x (number)\n\t         - y (number)\n\t        \\*/\n\t        matrixproto.rotate = function (a, x, y) {\n\t            a = R.rad(a);\n\t            x = x || 0;\n\t            y = y || 0;\n\t            var cos = +math.cos(a).toFixed(9),\n\t                sin = +math.sin(a).toFixed(9);\n\t            this.add(cos, sin, -sin, cos, x, y);\n\t            this.add(1, 0, 0, 1, -x, -y);\n\t        };\n\t        /*\\\n\t         * Matrix.x\n\t         [ method ]\n\t         **\n\t         * Return x coordinate for given point after transformation described by the matrix. See also @Matrix.y\n\t         > Parameters\n\t         - x (number)\n\t         - y (number)\n\t         = (number) x\n\t        \\*/\n\t        matrixproto.x = function (x, y) {\n\t            return x * this.a + y * this.c + this.e;\n\t        };\n\t        /*\\\n\t         * Matrix.y\n\t         [ method ]\n\t         **\n\t         * Return y coordinate for given point after transformation described by the matrix. See also @Matrix.x\n\t         > Parameters\n\t         - x (number)\n\t         - y (number)\n\t         = (number) y\n\t        \\*/\n\t        matrixproto.y = function (x, y) {\n\t            return x * this.b + y * this.d + this.f;\n\t        };\n\t        matrixproto.get = function (i) {\n\t            return +this[Str.fromCharCode(97 + i)].toFixed(4);\n\t        };\n\t        matrixproto.toString = function () {\n\t            return R.svg ?\n\t                \"matrix(\" + [this.get(0), this.get(1), this.get(2), this.get(3), this.get(4), this.get(5)].join() + \")\" :\n\t                [this.get(0), this.get(2), this.get(1), this.get(3), 0, 0].join();\n\t        };\n\t        matrixproto.toFilter = function () {\n\t            return \"progid:DXImageTransform.Microsoft.Matrix(M11=\" + this.get(0) +\n\t                \", M12=\" + this.get(2) + \", M21=\" + this.get(1) + \", M22=\" + this.get(3) +\n\t                \", Dx=\" + this.get(4) + \", Dy=\" + this.get(5) + \", sizingmethod='auto expand')\";\n\t        };\n\t        matrixproto.offset = function () {\n\t            return [this.e.toFixed(4), this.f.toFixed(4)];\n\t        };\n\t        function norm(a) {\n\t            return a[0] * a[0] + a[1] * a[1];\n\t        }\n\t        function normalize(a) {\n\t            var mag = math.sqrt(norm(a));\n\t            a[0] && (a[0] /= mag);\n\t            a[1] && (a[1] /= mag);\n\t        }\n\t        /*\\\n\t         * Matrix.split\n\t         [ method ]\n\t         **\n\t         * Splits matrix into primitive transformations\n\t         = (object) in format:\n\t         o dx (number) translation by x\n\t         o dy (number) translation by y\n\t         o scalex (number) scale by x\n\t         o scaley (number) scale by y\n\t         o shear (number) shear\n\t         o rotate (number) rotation in deg\n\t         o isSimple (boolean) could it be represented via simple transformations\n\t        \\*/\n\t        matrixproto.split = function () {\n\t            var out = {};\n\t            // translation\n\t            out.dx = this.e;\n\t            out.dy = this.f;\n\n\t            // scale and shear\n\t            var row = [[this.a, this.c], [this.b, this.d]];\n\t            out.scalex = math.sqrt(norm(row[0]));\n\t            normalize(row[0]);\n\n\t            out.shear = row[0][0] * row[1][0] + row[0][1] * row[1][1];\n\t            row[1] = [row[1][0] - row[0][0] * out.shear, row[1][1] - row[0][1] * out.shear];\n\n\t            out.scaley = math.sqrt(norm(row[1]));\n\t            normalize(row[1]);\n\t            out.shear /= out.scaley;\n\n\t            // rotation\n\t            var sin = -row[0][1],\n\t                cos = row[1][1];\n\t            if (cos < 0) {\n\t                out.rotate = R.deg(math.acos(cos));\n\t                if (sin < 0) {\n\t                    out.rotate = 360 - out.rotate;\n\t                }\n\t            } else {\n\t                out.rotate = R.deg(math.asin(sin));\n\t            }\n\n\t            out.isSimple = !+out.shear.toFixed(9) && (out.scalex.toFixed(9) == out.scaley.toFixed(9) || !out.rotate);\n\t            out.isSuperSimple = !+out.shear.toFixed(9) && out.scalex.toFixed(9) == out.scaley.toFixed(9) && !out.rotate;\n\t            out.noRotation = !+out.shear.toFixed(9) && !out.rotate;\n\t            return out;\n\t        };\n\t        /*\\\n\t         * Matrix.toTransformString\n\t         [ method ]\n\t         **\n\t         * Return transform string that represents given matrix\n\t         = (string) transform string\n\t        \\*/\n\t        matrixproto.toTransformString = function (shorter) {\n\t            var s = shorter || this[split]();\n\t            if (s.isSimple) {\n\t                s.scalex = +s.scalex.toFixed(4);\n\t                s.scaley = +s.scaley.toFixed(4);\n\t                s.rotate = +s.rotate.toFixed(4);\n\t                return  (s.dx || s.dy ? \"t\" + [s.dx, s.dy] : E) +\n\t                        (s.scalex != 1 || s.scaley != 1 ? \"s\" + [s.scalex, s.scaley, 0, 0] : E) +\n\t                        (s.rotate ? \"r\" + [s.rotate, 0, 0] : E);\n\t            } else {\n\t                return \"m\" + [this.get(0), this.get(1), this.get(2), this.get(3), this.get(4), this.get(5)];\n\t            }\n\t        };\n\t    })(Matrix.prototype);\n\n\t    var preventDefault = function () {\n\t        this.returnValue = false;\n\t    },\n\t    preventTouch = function () {\n\t        return this.originalEvent.preventDefault();\n\t    },\n\t    stopPropagation = function () {\n\t        this.cancelBubble = true;\n\t    },\n\t    stopTouch = function () {\n\t        return this.originalEvent.stopPropagation();\n\t    },\n\t    getEventPosition = function (e) {\n\t        var scrollY = g.doc.documentElement.scrollTop || g.doc.body.scrollTop,\n\t            scrollX = g.doc.documentElement.scrollLeft || g.doc.body.scrollLeft;\n\n\t        return {\n\t            x: e.clientX + scrollX,\n\t            y: e.clientY + scrollY\n\t        };\n\t    },\n\t    addEvent = (function () {\n\t        if (g.doc.addEventListener) {\n\t            return function (obj, type, fn, element) {\n\t                var f = function (e) {\n\t                    var pos = getEventPosition(e);\n\t                    return fn.call(element, e, pos.x, pos.y);\n\t                };\n\t                obj.addEventListener(type, f, false);\n\n\t                if (supportsTouch && touchMap[type]) {\n\t                    var _f = function (e) {\n\t                        var pos = getEventPosition(e),\n\t                            olde = e;\n\n\t                        for (var i = 0, ii = e.targetTouches && e.targetTouches.length; i < ii; i++) {\n\t                            if (e.targetTouches[i].target == obj) {\n\t                                e = e.targetTouches[i];\n\t                                e.originalEvent = olde;\n\t                                e.preventDefault = preventTouch;\n\t                                e.stopPropagation = stopTouch;\n\t                                break;\n\t                            }\n\t                        }\n\n\t                        return fn.call(element, e, pos.x, pos.y);\n\t                    };\n\t                    obj.addEventListener(touchMap[type], _f, false);\n\t                }\n\n\t                return function () {\n\t                    obj.removeEventListener(type, f, false);\n\n\t                    if (supportsTouch && touchMap[type])\n\t                        obj.removeEventListener(touchMap[type], _f, false);\n\n\t                    return true;\n\t                };\n\t            };\n\t        } else if (g.doc.attachEvent) {\n\t            return function (obj, type, fn, element) {\n\t                var f = function (e) {\n\t                    e = e || g.win.event;\n\t                    var scrollY = g.doc.documentElement.scrollTop || g.doc.body.scrollTop,\n\t                        scrollX = g.doc.documentElement.scrollLeft || g.doc.body.scrollLeft,\n\t                        x = e.clientX + scrollX,\n\t                        y = e.clientY + scrollY;\n\t                    e.preventDefault = e.preventDefault || preventDefault;\n\t                    e.stopPropagation = e.stopPropagation || stopPropagation;\n\t                    return fn.call(element, e, x, y);\n\t                };\n\t                obj.attachEvent(\"on\" + type, f);\n\t                var detacher = function () {\n\t                    obj.detachEvent(\"on\" + type, f);\n\t                    return true;\n\t                };\n\t                return detacher;\n\t            };\n\t        }\n\t    })(),\n\t    drag = [],\n\t    dragMove = function (e) {\n\t        var x = e.clientX,\n\t            y = e.clientY,\n\t            scrollY = g.doc.documentElement.scrollTop || g.doc.body.scrollTop,\n\t            scrollX = g.doc.documentElement.scrollLeft || g.doc.body.scrollLeft,\n\t            dragi,\n\t            j = drag.length;\n\t        while (j--) {\n\t            dragi = drag[j];\n\t            if (supportsTouch && e.touches) {\n\t                var i = e.touches.length,\n\t                    touch;\n\t                while (i--) {\n\t                    touch = e.touches[i];\n\t                    if (touch.identifier == dragi.el._drag.id) {\n\t                        x = touch.clientX;\n\t                        y = touch.clientY;\n\t                        (e.originalEvent ? e.originalEvent : e).preventDefault();\n\t                        break;\n\t                    }\n\t                }\n\t            } else {\n\t                e.preventDefault();\n\t            }\n\t            var node = dragi.el.node,\n\t                o,\n\t                next = node.nextSibling,\n\t                parent = node.parentNode,\n\t                display = node.style.display;\n\t            g.win.opera && parent.removeChild(node);\n\t            node.style.display = \"none\";\n\t            o = dragi.el.paper.getElementByPoint(x, y);\n\t            node.style.display = display;\n\t            g.win.opera && (next ? parent.insertBefore(node, next) : parent.appendChild(node));\n\t            o && eve(\"raphael.drag.over.\" + dragi.el.id, dragi.el, o);\n\t            x += scrollX;\n\t            y += scrollY;\n\t            eve(\"raphael.drag.move.\" + dragi.el.id, dragi.move_scope || dragi.el, x - dragi.el._drag.x, y - dragi.el._drag.y, x, y, e);\n\t        }\n\t    },\n\t    dragUp = function (e) {\n\t        R.unmousemove(dragMove).unmouseup(dragUp);\n\t        var i = drag.length,\n\t            dragi;\n\t        while (i--) {\n\t            dragi = drag[i];\n\t            dragi.el._drag = {};\n\t            eve(\"raphael.drag.end.\" + dragi.el.id, dragi.end_scope || dragi.start_scope || dragi.move_scope || dragi.el, e);\n\t        }\n\t        drag = [];\n\t    },\n\t    /*\\\n\t     * Raphael.el\n\t     [ property (object) ]\n\t     **\n\t     * You can add your own method to elements. This is useful when you want to hack default functionality or\n\t     * want to wrap some common transformation or attributes in one method. In difference to canvas methods,\n\t     * you can redefine element method at any time. Expending element methods wouldn’t affect set.\n\t     > Usage\n\t     | Raphael.el.red = function () {\n\t     |     this.attr({fill: \"#f00\"});\n\t     | };\n\t     | // then use it\n\t     | paper.circle(100, 100, 20).red();\n\t    \\*/\n\t    elproto = R.el = {};\n\t    /*\\\n\t     * Element.click\n\t     [ method ]\n\t     **\n\t     * Adds event handler for click for the element.\n\t     > Parameters\n\t     - handler (function) handler for the event\n\t     = (object) @Element\n\t    \\*/\n\t    /*\\\n\t     * Element.unclick\n\t     [ method ]\n\t     **\n\t     * Removes event handler for click for the element.\n\t     > Parameters\n\t     - handler (function) #optional handler for the event\n\t     = (object) @Element\n\t    \\*/\n\n\t    /*\\\n\t     * Element.dblclick\n\t     [ method ]\n\t     **\n\t     * Adds event handler for double click for the element.\n\t     > Parameters\n\t     - handler (function) handler for the event\n\t     = (object) @Element\n\t    \\*/\n\t    /*\\\n\t     * Element.undblclick\n\t     [ method ]\n\t     **\n\t     * Removes event handler for double click for the element.\n\t     > Parameters\n\t     - handler (function) #optional handler for the event\n\t     = (object) @Element\n\t    \\*/\n\n\t    /*\\\n\t     * Element.mousedown\n\t     [ method ]\n\t     **\n\t     * Adds event handler for mousedown for the element.\n\t     > Parameters\n\t     - handler (function) handler for the event\n\t     = (object) @Element\n\t    \\*/\n\t    /*\\\n\t     * Element.unmousedown\n\t     [ method ]\n\t     **\n\t     * Removes event handler for mousedown for the element.\n\t     > Parameters\n\t     - handler (function) #optional handler for the event\n\t     = (object) @Element\n\t    \\*/\n\n\t    /*\\\n\t     * Element.mousemove\n\t     [ method ]\n\t     **\n\t     * Adds event handler for mousemove for the element.\n\t     > Parameters\n\t     - handler (function) handler for the event\n\t     = (object) @Element\n\t    \\*/\n\t    /*\\\n\t     * Element.unmousemove\n\t     [ method ]\n\t     **\n\t     * Removes event handler for mousemove for the element.\n\t     > Parameters\n\t     - handler (function) #optional handler for the event\n\t     = (object) @Element\n\t    \\*/\n\n\t    /*\\\n\t     * Element.mouseout\n\t     [ method ]\n\t     **\n\t     * Adds event handler for mouseout for the element.\n\t     > Parameters\n\t     - handler (function) handler for the event\n\t     = (object) @Element\n\t    \\*/\n\t    /*\\\n\t     * Element.unmouseout\n\t     [ method ]\n\t     **\n\t     * Removes event handler for mouseout for the element.\n\t     > Parameters\n\t     - handler (function) #optional handler for the event\n\t     = (object) @Element\n\t    \\*/\n\n\t    /*\\\n\t     * Element.mouseover\n\t     [ method ]\n\t     **\n\t     * Adds event handler for mouseover for the element.\n\t     > Parameters\n\t     - handler (function) handler for the event\n\t     = (object) @Element\n\t    \\*/\n\t    /*\\\n\t     * Element.unmouseover\n\t     [ method ]\n\t     **\n\t     * Removes event handler for mouseover for the element.\n\t     > Parameters\n\t     - handler (function) #optional handler for the event\n\t     = (object) @Element\n\t    \\*/\n\n\t    /*\\\n\t     * Element.mouseup\n\t     [ method ]\n\t     **\n\t     * Adds event handler for mouseup for the element.\n\t     > Parameters\n\t     - handler (function) handler for the event\n\t     = (object) @Element\n\t    \\*/\n\t    /*\\\n\t     * Element.unmouseup\n\t     [ method ]\n\t     **\n\t     * Removes event handler for mouseup for the element.\n\t     > Parameters\n\t     - handler (function) #optional handler for the event\n\t     = (object) @Element\n\t    \\*/\n\n\t    /*\\\n\t     * Element.touchstart\n\t     [ method ]\n\t     **\n\t     * Adds event handler for touchstart for the element.\n\t     > Parameters\n\t     - handler (function) handler for the event\n\t     = (object) @Element\n\t    \\*/\n\t    /*\\\n\t     * Element.untouchstart\n\t     [ method ]\n\t     **\n\t     * Removes event handler for touchstart for the element.\n\t     > Parameters\n\t     - handler (function) #optional handler for the event\n\t     = (object) @Element\n\t    \\*/\n\n\t    /*\\\n\t     * Element.touchmove\n\t     [ method ]\n\t     **\n\t     * Adds event handler for touchmove for the element.\n\t     > Parameters\n\t     - handler (function) handler for the event\n\t     = (object) @Element\n\t    \\*/\n\t    /*\\\n\t     * Element.untouchmove\n\t     [ method ]\n\t     **\n\t     * Removes event handler for touchmove for the element.\n\t     > Parameters\n\t     - handler (function) #optional handler for the event\n\t     = (object) @Element\n\t    \\*/\n\n\t    /*\\\n\t     * Element.touchend\n\t     [ method ]\n\t     **\n\t     * Adds event handler for touchend for the element.\n\t     > Parameters\n\t     - handler (function) handler for the event\n\t     = (object) @Element\n\t    \\*/\n\t    /*\\\n\t     * Element.untouchend\n\t     [ method ]\n\t     **\n\t     * Removes event handler for touchend for the element.\n\t     > Parameters\n\t     - handler (function) #optional handler for the event\n\t     = (object) @Element\n\t    \\*/\n\n\t    /*\\\n\t     * Element.touchcancel\n\t     [ method ]\n\t     **\n\t     * Adds event handler for touchcancel for the element.\n\t     > Parameters\n\t     - handler (function) handler for the event\n\t     = (object) @Element\n\t    \\*/\n\t    /*\\\n\t     * Element.untouchcancel\n\t     [ method ]\n\t     **\n\t     * Removes event handler for touchcancel for the element.\n\t     > Parameters\n\t     - handler (function) #optional handler for the event\n\t     = (object) @Element\n\t    \\*/\n\t    for (var i = events.length; i--;) {\n\t        (function (eventName) {\n\t            R[eventName] = elproto[eventName] = function (fn, scope) {\n\t                if (R.is(fn, \"function\")) {\n\t                    this.events = this.events || [];\n\t                    this.events.push({name: eventName, f: fn, unbind: addEvent(this.shape || this.node || g.doc, eventName, fn, scope || this)});\n\t                }\n\t                return this;\n\t            };\n\t            R[\"un\" + eventName] = elproto[\"un\" + eventName] = function (fn) {\n\t                var events = this.events || [],\n\t                    l = events.length;\n\t                while (l--){\n\t                    if (events[l].name == eventName && (R.is(fn, \"undefined\") || events[l].f == fn)) {\n\t                        events[l].unbind();\n\t                        events.splice(l, 1);\n\t                        !events.length && delete this.events;\n\t                    }\n\t                }\n\t                return this;\n\t            };\n\t        })(events[i]);\n\t    }\n\n\t    /*\\\n\t     * Element.data\n\t     [ method ]\n\t     **\n\t     * Adds or retrieves given value associated with given key.\n\t     **\n\t     * See also @Element.removeData\n\t     > Parameters\n\t     - key (string) key to store data\n\t     - value (any) #optional value to store\n\t     = (object) @Element\n\t     * or, if value is not specified:\n\t     = (any) value\n\t     * or, if key and value are not specified:\n\t     = (object) Key/value pairs for all the data associated with the element.\n\t     > Usage\n\t     | for (var i = 0, i < 5, i++) {\n\t     |     paper.circle(10 + 15 * i, 10, 10)\n\t     |          .attr({fill: \"#000\"})\n\t     |          .data(\"i\", i)\n\t     |          .click(function () {\n\t     |             alert(this.data(\"i\"));\n\t     |          });\n\t     | }\n\t    \\*/\n\t    elproto.data = function (key, value) {\n\t        var data = eldata[this.id] = eldata[this.id] || {};\n\t        if (arguments.length == 0) {\n\t            return data;\n\t        }\n\t        if (arguments.length == 1) {\n\t            if (R.is(key, \"object\")) {\n\t                for (var i in key) if (key[has](i)) {\n\t                    this.data(i, key[i]);\n\t                }\n\t                return this;\n\t            }\n\t            eve(\"raphael.data.get.\" + this.id, this, data[key], key);\n\t            return data[key];\n\t        }\n\t        data[key] = value;\n\t        eve(\"raphael.data.set.\" + this.id, this, value, key);\n\t        return this;\n\t    };\n\t    /*\\\n\t     * Element.removeData\n\t     [ method ]\n\t     **\n\t     * Removes value associated with an element by given key.\n\t     * If key is not provided, removes all the data of the element.\n\t     > Parameters\n\t     - key (string) #optional key\n\t     = (object) @Element\n\t    \\*/\n\t    elproto.removeData = function (key) {\n\t        if (key == null) {\n\t            eldata[this.id] = {};\n\t        } else {\n\t            eldata[this.id] && delete eldata[this.id][key];\n\t        }\n\t        return this;\n\t    };\n\t     /*\\\n\t     * Element.getData\n\t     [ method ]\n\t     **\n\t     * Retrieves the element data\n\t     = (object) data\n\t    \\*/\n\t    elproto.getData = function () {\n\t        return clone(eldata[this.id] || {});\n\t    };\n\t    /*\\\n\t     * Element.hover\n\t     [ method ]\n\t     **\n\t     * Adds event handlers for hover for the element.\n\t     > Parameters\n\t     - f_in (function) handler for hover in\n\t     - f_out (function) handler for hover out\n\t     - icontext (object) #optional context for hover in handler\n\t     - ocontext (object) #optional context for hover out handler\n\t     = (object) @Element\n\t    \\*/\n\t    elproto.hover = function (f_in, f_out, scope_in, scope_out) {\n\t        return this.mouseover(f_in, scope_in).mouseout(f_out, scope_out || scope_in);\n\t    };\n\t    /*\\\n\t     * Element.unhover\n\t     [ method ]\n\t     **\n\t     * Removes event handlers for hover for the element.\n\t     > Parameters\n\t     - f_in (function) handler for hover in\n\t     - f_out (function) handler for hover out\n\t     = (object) @Element\n\t    \\*/\n\t    elproto.unhover = function (f_in, f_out) {\n\t        return this.unmouseover(f_in).unmouseout(f_out);\n\t    };\n\t    var draggable = [];\n\t    /*\\\n\t     * Element.drag\n\t     [ method ]\n\t     **\n\t     * Adds event handlers for drag of the element.\n\t     > Parameters\n\t     - onmove (function) handler for moving\n\t     - onstart (function) handler for drag start\n\t     - onend (function) handler for drag end\n\t     - mcontext (object) #optional context for moving handler\n\t     - scontext (object) #optional context for drag start handler\n\t     - econtext (object) #optional context for drag end handler\n\t     * Additionally following `drag` events will be triggered: `drag.start.<id>` on start,\n\t     * `drag.end.<id>` on end and `drag.move.<id>` on every move. When element will be dragged over another element\n\t     * `drag.over.<id>` will be fired as well.\n\t     *\n\t     * Start event and start handler will be called in specified context or in context of the element with following parameters:\n\t     o x (number) x position of the mouse\n\t     o y (number) y position of the mouse\n\t     o event (object) DOM event object\n\t     * Move event and move handler will be called in specified context or in context of the element with following parameters:\n\t     o dx (number) shift by x from the start point\n\t     o dy (number) shift by y from the start point\n\t     o x (number) x position of the mouse\n\t     o y (number) y position of the mouse\n\t     o event (object) DOM event object\n\t     * End event and end handler will be called in specified context or in context of the element with following parameters:\n\t     o event (object) DOM event object\n\t     = (object) @Element\n\t    \\*/\n\t    elproto.drag = function (onmove, onstart, onend, move_scope, start_scope, end_scope) {\n\t        function start(e) {\n\t            (e.originalEvent || e).preventDefault();\n\t            var x = e.clientX,\n\t                y = e.clientY,\n\t                scrollY = g.doc.documentElement.scrollTop || g.doc.body.scrollTop,\n\t                scrollX = g.doc.documentElement.scrollLeft || g.doc.body.scrollLeft;\n\t            this._drag.id = e.identifier;\n\t            if (supportsTouch && e.touches) {\n\t                var i = e.touches.length, touch;\n\t                while (i--) {\n\t                    touch = e.touches[i];\n\t                    this._drag.id = touch.identifier;\n\t                    if (touch.identifier == this._drag.id) {\n\t                        x = touch.clientX;\n\t                        y = touch.clientY;\n\t                        break;\n\t                    }\n\t                }\n\t            }\n\t            this._drag.x = x + scrollX;\n\t            this._drag.y = y + scrollY;\n\t            !drag.length && R.mousemove(dragMove).mouseup(dragUp);\n\t            drag.push({el: this, move_scope: move_scope, start_scope: start_scope, end_scope: end_scope});\n\t            onstart && eve.on(\"raphael.drag.start.\" + this.id, onstart);\n\t            onmove && eve.on(\"raphael.drag.move.\" + this.id, onmove);\n\t            onend && eve.on(\"raphael.drag.end.\" + this.id, onend);\n\t            eve(\"raphael.drag.start.\" + this.id, start_scope || move_scope || this, e.clientX + scrollX, e.clientY + scrollY, e);\n\t        }\n\t        this._drag = {};\n\t        draggable.push({el: this, start: start});\n\t        this.mousedown(start);\n\t        return this;\n\t    };\n\t    /*\\\n\t     * Element.onDragOver\n\t     [ method ]\n\t     **\n\t     * Shortcut for assigning event handler for `drag.over.<id>` event, where id is id of the element (see @Element.id).\n\t     > Parameters\n\t     - f (function) handler for event, first argument would be the element you are dragging over\n\t    \\*/\n\t    elproto.onDragOver = function (f) {\n\t        f ? eve.on(\"raphael.drag.over.\" + this.id, f) : eve.unbind(\"raphael.drag.over.\" + this.id);\n\t    };\n\t    /*\\\n\t     * Element.undrag\n\t     [ method ]\n\t     **\n\t     * Removes all drag event handlers from given element.\n\t    \\*/\n\t    elproto.undrag = function () {\n\t        var i = draggable.length;\n\t        while (i--) if (draggable[i].el == this) {\n\t            this.unmousedown(draggable[i].start);\n\t            draggable.splice(i, 1);\n\t            eve.unbind(\"raphael.drag.*.\" + this.id);\n\t        }\n\t        !draggable.length && R.unmousemove(dragMove).unmouseup(dragUp);\n\t        drag = [];\n\t    };\n\t    /*\\\n\t     * Paper.circle\n\t     [ method ]\n\t     **\n\t     * Draws a circle.\n\t     **\n\t     > Parameters\n\t     **\n\t     - x (number) x coordinate of the centre\n\t     - y (number) y coordinate of the centre\n\t     - r (number) radius\n\t     = (object) Raphaël element object with type “circle”\n\t     **\n\t     > Usage\n\t     | var c = paper.circle(50, 50, 40);\n\t    \\*/\n\t    paperproto.circle = function (x, y, r) {\n\t        var out = R._engine.circle(this, x || 0, y || 0, r || 0);\n\t        this.__set__ && this.__set__.push(out);\n\t        return out;\n\t    };\n\t    /*\\\n\t     * Paper.rect\n\t     [ method ]\n\t     *\n\t     * Draws a rectangle.\n\t     **\n\t     > Parameters\n\t     **\n\t     - x (number) x coordinate of the top left corner\n\t     - y (number) y coordinate of the top left corner\n\t     - width (number) width\n\t     - height (number) height\n\t     - r (number) #optional radius for rounded corners, default is 0\n\t     = (object) Raphaël element object with type “rect”\n\t     **\n\t     > Usage\n\t     | // regular rectangle\n\t     | var c = paper.rect(10, 10, 50, 50);\n\t     | // rectangle with rounded corners\n\t     | var c = paper.rect(40, 40, 50, 50, 10);\n\t    \\*/\n\t    paperproto.rect = function (x, y, w, h, r) {\n\t        var out = R._engine.rect(this, x || 0, y || 0, w || 0, h || 0, r || 0);\n\t        this.__set__ && this.__set__.push(out);\n\t        return out;\n\t    };\n\t    /*\\\n\t     * Paper.ellipse\n\t     [ method ]\n\t     **\n\t     * Draws an ellipse.\n\t     **\n\t     > Parameters\n\t     **\n\t     - x (number) x coordinate of the centre\n\t     - y (number) y coordinate of the centre\n\t     - rx (number) horizontal radius\n\t     - ry (number) vertical radius\n\t     = (object) Raphaël element object with type “ellipse”\n\t     **\n\t     > Usage\n\t     | var c = paper.ellipse(50, 50, 40, 20);\n\t    \\*/\n\t    paperproto.ellipse = function (x, y, rx, ry) {\n\t        var out = R._engine.ellipse(this, x || 0, y || 0, rx || 0, ry || 0);\n\t        this.__set__ && this.__set__.push(out);\n\t        return out;\n\t    };\n\t    /*\\\n\t     * Paper.path\n\t     [ method ]\n\t     **\n\t     * Creates a path element by given path data string.\n\t     > Parameters\n\t     - pathString (string) #optional path string in SVG format.\n\t     * Path string consists of one-letter commands, followed by comma seprarated arguments in numercal form. Example:\n\t     | \"M10,20L30,40\"\n\t     * Here we can see two commands: “M”, with arguments `(10, 20)` and “L” with arguments `(30, 40)`. Upper case letter mean command is absolute, lower case—relative.\n\t     *\n\t     # <p>Here is short list of commands available, for more details see <a href=\"http://www.w3.org/TR/SVG/paths.html#PathData\" title=\"Details of a path's data attribute's format are described in the SVG specification.\">SVG path string format</a>.</p>\n\t     # <table><thead><tr><th>Command</th><th>Name</th><th>Parameters</th></tr></thead><tbody>\n\t     # <tr><td>M</td><td>moveto</td><td>(x y)+</td></tr>\n\t     # <tr><td>Z</td><td>closepath</td><td>(none)</td></tr>\n\t     # <tr><td>L</td><td>lineto</td><td>(x y)+</td></tr>\n\t     # <tr><td>H</td><td>horizontal lineto</td><td>x+</td></tr>\n\t     # <tr><td>V</td><td>vertical lineto</td><td>y+</td></tr>\n\t     # <tr><td>C</td><td>curveto</td><td>(x1 y1 x2 y2 x y)+</td></tr>\n\t     # <tr><td>S</td><td>smooth curveto</td><td>(x2 y2 x y)+</td></tr>\n\t     # <tr><td>Q</td><td>quadratic Bézier curveto</td><td>(x1 y1 x y)+</td></tr>\n\t     # <tr><td>T</td><td>smooth quadratic Bézier curveto</td><td>(x y)+</td></tr>\n\t     # <tr><td>A</td><td>elliptical arc</td><td>(rx ry x-axis-rotation large-arc-flag sweep-flag x y)+</td></tr>\n\t     # <tr><td>R</td><td><a href=\"http://en.wikipedia.org/wiki/Catmull–Rom_spline#Catmull.E2.80.93Rom_spline\">Catmull-Rom curveto</a>*</td><td>x1 y1 (x y)+</td></tr></tbody></table>\n\t     * * “Catmull-Rom curveto” is a not standard SVG command and added in 2.0 to make life easier.\n\t     * Note: there is a special case when path consist of just three commands: “M10,10R…z”. In this case path will smoothly connects to its beginning.\n\t     > Usage\n\t     | var c = paper.path(\"M10 10L90 90\");\n\t     | // draw a diagonal line:\n\t     | // move to 10,10, line to 90,90\n\t     * For example of path strings, check out these icons: http://raphaeljs.com/icons/\n\t    \\*/\n\t    paperproto.path = function (pathString) {\n\t        pathString && !R.is(pathString, string) && !R.is(pathString[0], array) && (pathString += E);\n\t        var out = R._engine.path(R.format[apply](R, arguments), this);\n\t        this.__set__ && this.__set__.push(out);\n\t        return out;\n\t    };\n\t    /*\\\n\t     * Paper.image\n\t     [ method ]\n\t     **\n\t     * Embeds an image into the surface.\n\t     **\n\t     > Parameters\n\t     **\n\t     - src (string) URI of the source image\n\t     - x (number) x coordinate position\n\t     - y (number) y coordinate position\n\t     - width (number) width of the image\n\t     - height (number) height of the image\n\t     = (object) Raphaël element object with type “image”\n\t     **\n\t     > Usage\n\t     | var c = paper.image(\"apple.png\", 10, 10, 80, 80);\n\t    \\*/\n\t    paperproto.image = function (src, x, y, w, h) {\n\t        var out = R._engine.image(this, src || \"about:blank\", x || 0, y || 0, w || 0, h || 0);\n\t        this.__set__ && this.__set__.push(out);\n\t        return out;\n\t    };\n\t    /*\\\n\t     * Paper.text\n\t     [ method ]\n\t     **\n\t     * Draws a text string. If you need line breaks, put “\\n” in the string.\n\t     **\n\t     > Parameters\n\t     **\n\t     - x (number) x coordinate position\n\t     - y (number) y coordinate position\n\t     - text (string) The text string to draw\n\t     = (object) Raphaël element object with type “text”\n\t     **\n\t     > Usage\n\t     | var t = paper.text(50, 50, \"Raphaël\\nkicks\\nbutt!\");\n\t    \\*/\n\t    paperproto.text = function (x, y, text) {\n\t        var out = R._engine.text(this, x || 0, y || 0, Str(text));\n\t        this.__set__ && this.__set__.push(out);\n\t        return out;\n\t    };\n\t    /*\\\n\t     * Paper.set\n\t     [ method ]\n\t     **\n\t     * Creates array-like object to keep and operate several elements at once.\n\t     * Warning: it doesn’t create any elements for itself in the page, it just groups existing elements.\n\t     * Sets act as pseudo elements — all methods available to an element can be used on a set.\n\t     = (object) array-like object that represents set of elements\n\t     **\n\t     > Usage\n\t     | var st = paper.set();\n\t     | st.push(\n\t     |     paper.circle(10, 10, 5),\n\t     |     paper.circle(30, 10, 5)\n\t     | );\n\t     | st.attr({fill: \"red\"}); // changes the fill of both circles\n\t    \\*/\n\t    paperproto.set = function (itemsArray) {\n\t        !R.is(itemsArray, \"array\") && (itemsArray = Array.prototype.splice.call(arguments, 0, arguments.length));\n\t        var out = new Set(itemsArray);\n\t        this.__set__ && this.__set__.push(out);\n\t        out[\"paper\"] = this;\n\t        out[\"type\"] = \"set\";\n\t        return out;\n\t    };\n\t    /*\\\n\t     * Paper.setStart\n\t     [ method ]\n\t     **\n\t     * Creates @Paper.set. All elements that will be created after calling this method and before calling\n\t     * @Paper.setFinish will be added to the set.\n\t     **\n\t     > Usage\n\t     | paper.setStart();\n\t     | paper.circle(10, 10, 5),\n\t     | paper.circle(30, 10, 5)\n\t     | var st = paper.setFinish();\n\t     | st.attr({fill: \"red\"}); // changes the fill of both circles\n\t    \\*/\n\t    paperproto.setStart = function (set) {\n\t        this.__set__ = set || this.set();\n\t    };\n\t    /*\\\n\t     * Paper.setFinish\n\t     [ method ]\n\t     **\n\t     * See @Paper.setStart. This method finishes catching and returns resulting set.\n\t     **\n\t     = (object) set\n\t    \\*/\n\t    paperproto.setFinish = function (set) {\n\t        var out = this.__set__;\n\t        delete this.__set__;\n\t        return out;\n\t    };\n\t    /*\\\n\t     * Paper.getSize\n\t     [ method ]\n\t     **\n\t     * Obtains current paper actual size.\n\t     **\n\t     = (object)\n\t     \\*/\n\t    paperproto.getSize = function () {\n\t        var container = this.canvas.parentNode;\n\t        return {\n\t            width: container.offsetWidth,\n\t            height: container.offsetHeight\n\t                };\n\t        };\n\t    /*\\\n\t     * Paper.setSize\n\t     [ method ]\n\t     **\n\t     * If you need to change dimensions of the canvas call this method\n\t     **\n\t     > Parameters\n\t     **\n\t     - width (number) new width of the canvas\n\t     - height (number) new height of the canvas\n\t    \\*/\n\t    paperproto.setSize = function (width, height) {\n\t        return R._engine.setSize.call(this, width, height);\n\t    };\n\t    /*\\\n\t     * Paper.setViewBox\n\t     [ method ]\n\t     **\n\t     * Sets the view box of the paper. Practically it gives you ability to zoom and pan whole paper surface by\n\t     * specifying new boundaries.\n\t     **\n\t     > Parameters\n\t     **\n\t     - x (number) new x position, default is `0`\n\t     - y (number) new y position, default is `0`\n\t     - w (number) new width of the canvas\n\t     - h (number) new height of the canvas\n\t     - fit (boolean) `true` if you want graphics to fit into new boundary box\n\t    \\*/\n\t    paperproto.setViewBox = function (x, y, w, h, fit) {\n\t        return R._engine.setViewBox.call(this, x, y, w, h, fit);\n\t    };\n\t    /*\\\n\t     * Paper.top\n\t     [ property ]\n\t     **\n\t     * Points to the topmost element on the paper\n\t    \\*/\n\t    /*\\\n\t     * Paper.bottom\n\t     [ property ]\n\t     **\n\t     * Points to the bottom element on the paper\n\t    \\*/\n\t    paperproto.top = paperproto.bottom = null;\n\t    /*\\\n\t     * Paper.raphael\n\t     [ property ]\n\t     **\n\t     * Points to the @Raphael object/function\n\t    \\*/\n\t    paperproto.raphael = R;\n\t    var getOffset = function (elem) {\n\t        var box = elem.getBoundingClientRect(),\n\t            doc = elem.ownerDocument,\n\t            body = doc.body,\n\t            docElem = doc.documentElement,\n\t            clientTop = docElem.clientTop || body.clientTop || 0, clientLeft = docElem.clientLeft || body.clientLeft || 0,\n\t            top  = box.top  + (g.win.pageYOffset || docElem.scrollTop || body.scrollTop ) - clientTop,\n\t            left = box.left + (g.win.pageXOffset || docElem.scrollLeft || body.scrollLeft) - clientLeft;\n\t        return {\n\t            y: top,\n\t            x: left\n\t        };\n\t    };\n\t    /*\\\n\t     * Paper.getElementByPoint\n\t     [ method ]\n\t     **\n\t     * Returns you topmost element under given point.\n\t     **\n\t     = (object) Raphaël element object\n\t     > Parameters\n\t     **\n\t     - x (number) x coordinate from the top left corner of the window\n\t     - y (number) y coordinate from the top left corner of the window\n\t     > Usage\n\t     | paper.getElementByPoint(mouseX, mouseY).attr({stroke: \"#f00\"});\n\t    \\*/\n\t    paperproto.getElementByPoint = function (x, y) {\n\t        var paper = this,\n\t            svg = paper.canvas,\n\t            target = g.doc.elementFromPoint(x, y);\n\t        if (g.win.opera && target.tagName == \"svg\") {\n\t            var so = getOffset(svg),\n\t                sr = svg.createSVGRect();\n\t            sr.x = x - so.x;\n\t            sr.y = y - so.y;\n\t            sr.width = sr.height = 1;\n\t            var hits = svg.getIntersectionList(sr, null);\n\t            if (hits.length) {\n\t                target = hits[hits.length - 1];\n\t            }\n\t        }\n\t        if (!target) {\n\t            return null;\n\t        }\n\t        while (target.parentNode && target != svg.parentNode && !target.raphael) {\n\t            target = target.parentNode;\n\t        }\n\t        target == paper.canvas.parentNode && (target = svg);\n\t        target = target && target.raphael ? paper.getById(target.raphaelid) : null;\n\t        return target;\n\t    };\n\n\t    /*\\\n\t     * Paper.getElementsByBBox\n\t     [ method ]\n\t     **\n\t     * Returns set of elements that have an intersecting bounding box\n\t     **\n\t     > Parameters\n\t     **\n\t     - bbox (object) bbox to check with\n\t     = (object) @Set\n\t     \\*/\n\t    paperproto.getElementsByBBox = function (bbox) {\n\t        var set = this.set();\n\t        this.forEach(function (el) {\n\t            if (R.isBBoxIntersect(el.getBBox(), bbox)) {\n\t                set.push(el);\n\t            }\n\t        });\n\t        return set;\n\t    };\n\n\t    /*\\\n\t     * Paper.getById\n\t     [ method ]\n\t     **\n\t     * Returns you element by its internal ID.\n\t     **\n\t     > Parameters\n\t     **\n\t     - id (number) id\n\t     = (object) Raphaël element object\n\t    \\*/\n\t    paperproto.getById = function (id) {\n\t        var bot = this.bottom;\n\t        while (bot) {\n\t            if (bot.id == id) {\n\t                return bot;\n\t            }\n\t            bot = bot.next;\n\t        }\n\t        return null;\n\t    };\n\t    /*\\\n\t     * Paper.forEach\n\t     [ method ]\n\t     **\n\t     * Executes given function for each element on the paper\n\t     *\n\t     * If callback function returns `false` it will stop loop running.\n\t     **\n\t     > Parameters\n\t     **\n\t     - callback (function) function to run\n\t     - thisArg (object) context object for the callback\n\t     = (object) Paper object\n\t     > Usage\n\t     | paper.forEach(function (el) {\n\t     |     el.attr({ stroke: \"blue\" });\n\t     | });\n\t    \\*/\n\t    paperproto.forEach = function (callback, thisArg) {\n\t        var bot = this.bottom;\n\t        while (bot) {\n\t            if (callback.call(thisArg, bot) === false) {\n\t                return this;\n\t            }\n\t            bot = bot.next;\n\t        }\n\t        return this;\n\t    };\n\t    /*\\\n\t     * Paper.getElementsByPoint\n\t     [ method ]\n\t     **\n\t     * Returns set of elements that have common point inside\n\t     **\n\t     > Parameters\n\t     **\n\t     - x (number) x coordinate of the point\n\t     - y (number) y coordinate of the point\n\t     = (object) @Set\n\t    \\*/\n\t    paperproto.getElementsByPoint = function (x, y) {\n\t        var set = this.set();\n\t        this.forEach(function (el) {\n\t            if (el.isPointInside(x, y)) {\n\t                set.push(el);\n\t            }\n\t        });\n\t        return set;\n\t    };\n\t    function x_y() {\n\t        return this.x + S + this.y;\n\t    }\n\t    function x_y_w_h() {\n\t        return this.x + S + this.y + S + this.width + \" \\xd7 \" + this.height;\n\t    }\n\t    /*\\\n\t     * Element.isPointInside\n\t     [ method ]\n\t     **\n\t     * Determine if given point is inside this element’s shape\n\t     **\n\t     > Parameters\n\t     **\n\t     - x (number) x coordinate of the point\n\t     - y (number) y coordinate of the point\n\t     = (boolean) `true` if point inside the shape\n\t    \\*/\n\t    elproto.isPointInside = function (x, y) {\n\t        var rp = this.realPath = getPath[this.type](this);\n\t        if (this.attr('transform') && this.attr('transform').length) {\n\t            rp = R.transformPath(rp, this.attr('transform'));\n\t        }\n\t        return R.isPointInsidePath(rp, x, y);\n\t    };\n\t    /*\\\n\t     * Element.getBBox\n\t     [ method ]\n\t     **\n\t     * Return bounding box for a given element\n\t     **\n\t     > Parameters\n\t     **\n\t     - isWithoutTransform (boolean) flag, `true` if you want to have bounding box before transformations. Default is `false`.\n\t     = (object) Bounding box object:\n\t     o {\n\t     o     x: (number) top left corner x\n\t     o     y: (number) top left corner y\n\t     o     x2: (number) bottom right corner x\n\t     o     y2: (number) bottom right corner y\n\t     o     width: (number) width\n\t     o     height: (number) height\n\t     o }\n\t    \\*/\n\t    elproto.getBBox = function (isWithoutTransform) {\n\t        if (this.removed) {\n\t            return {};\n\t        }\n\t        var _ = this._;\n\t        if (isWithoutTransform) {\n\t            if (_.dirty || !_.bboxwt) {\n\t                this.realPath = getPath[this.type](this);\n\t                _.bboxwt = pathDimensions(this.realPath);\n\t                _.bboxwt.toString = x_y_w_h;\n\t                _.dirty = 0;\n\t            }\n\t            return _.bboxwt;\n\t        }\n\t        if (_.dirty || _.dirtyT || !_.bbox) {\n\t            if (_.dirty || !this.realPath) {\n\t                _.bboxwt = 0;\n\t                this.realPath = getPath[this.type](this);\n\t            }\n\t            _.bbox = pathDimensions(mapPath(this.realPath, this.matrix));\n\t            _.bbox.toString = x_y_w_h;\n\t            _.dirty = _.dirtyT = 0;\n\t        }\n\t        return _.bbox;\n\t    };\n\t    /*\\\n\t     * Element.clone\n\t     [ method ]\n\t     **\n\t     = (object) clone of a given element\n\t     **\n\t    \\*/\n\t    elproto.clone = function () {\n\t        if (this.removed) {\n\t            return null;\n\t        }\n\t        var out = this.paper[this.type]().attr(this.attr());\n\t        this.__set__ && this.__set__.push(out);\n\t        return out;\n\t    };\n\t    /*\\\n\t     * Element.glow\n\t     [ method ]\n\t     **\n\t     * Return set of elements that create glow-like effect around given element. See @Paper.set.\n\t     *\n\t     * Note: Glow is not connected to the element. If you change element attributes it won’t adjust itself.\n\t     **\n\t     > Parameters\n\t     **\n\t     - glow (object) #optional parameters object with all properties optional:\n\t     o {\n\t     o     width (number) size of the glow, default is `10`\n\t     o     fill (boolean) will it be filled, default is `false`\n\t     o     opacity (number) opacity, default is `0.5`\n\t     o     offsetx (number) horizontal offset, default is `0`\n\t     o     offsety (number) vertical offset, default is `0`\n\t     o     color (string) glow colour, default is `black`\n\t     o }\n\t     = (object) @Paper.set of elements that represents glow\n\t    \\*/\n\t    elproto.glow = function (glow) {\n\t        if (this.type == \"text\") {\n\t            return null;\n\t        }\n\t        glow = glow || {};\n\t        var s = {\n\t            width: (glow.width || 10) + (+this.attr(\"stroke-width\") || 1),\n\t            fill: glow.fill || false,\n\t            opacity: glow.opacity == null ? .5 : glow.opacity,\n\t            offsetx: glow.offsetx || 0,\n\t            offsety: glow.offsety || 0,\n\t            color: glow.color || \"#000\"\n\t        },\n\t            c = s.width / 2,\n\t            r = this.paper,\n\t            out = r.set(),\n\t            path = this.realPath || getPath[this.type](this);\n\t        path = this.matrix ? mapPath(path, this.matrix) : path;\n\t        for (var i = 1; i < c + 1; i++) {\n\t            out.push(r.path(path).attr({\n\t                stroke: s.color,\n\t                fill: s.fill ? s.color : \"none\",\n\t                \"stroke-linejoin\": \"round\",\n\t                \"stroke-linecap\": \"round\",\n\t                \"stroke-width\": +(s.width / c * i).toFixed(3),\n\t                opacity: +(s.opacity / c).toFixed(3)\n\t            }));\n\t        }\n\t        return out.insertBefore(this).translate(s.offsetx, s.offsety);\n\t    };\n\t    var curveslengths = {},\n\t    getPointAtSegmentLength = function (p1x, p1y, c1x, c1y, c2x, c2y, p2x, p2y, length) {\n\t        if (length == null) {\n\t            return bezlen(p1x, p1y, c1x, c1y, c2x, c2y, p2x, p2y);\n\t        } else {\n\t            return R.findDotsAtSegment(p1x, p1y, c1x, c1y, c2x, c2y, p2x, p2y, getTatLen(p1x, p1y, c1x, c1y, c2x, c2y, p2x, p2y, length));\n\t        }\n\t    },\n\t    getLengthFactory = function (istotal, subpath) {\n\t        return function (path, length, onlystart) {\n\t            path = path2curve(path);\n\t            var x, y, p, l, sp = \"\", subpaths = {}, point,\n\t                len = 0;\n\t            for (var i = 0, ii = path.length; i < ii; i++) {\n\t                p = path[i];\n\t                if (p[0] == \"M\") {\n\t                    x = +p[1];\n\t                    y = +p[2];\n\t                } else {\n\t                    l = getPointAtSegmentLength(x, y, p[1], p[2], p[3], p[4], p[5], p[6]);\n\t                    if (len + l > length) {\n\t                        if (subpath && !subpaths.start) {\n\t                            point = getPointAtSegmentLength(x, y, p[1], p[2], p[3], p[4], p[5], p[6], length - len);\n\t                            sp += [\"C\" + point.start.x, point.start.y, point.m.x, point.m.y, point.x, point.y];\n\t                            if (onlystart) {return sp;}\n\t                            subpaths.start = sp;\n\t                            sp = [\"M\" + point.x, point.y + \"C\" + point.n.x, point.n.y, point.end.x, point.end.y, p[5], p[6]].join();\n\t                            len += l;\n\t                            x = +p[5];\n\t                            y = +p[6];\n\t                            continue;\n\t                        }\n\t                        if (!istotal && !subpath) {\n\t                            point = getPointAtSegmentLength(x, y, p[1], p[2], p[3], p[4], p[5], p[6], length - len);\n\t                            return {x: point.x, y: point.y, alpha: point.alpha};\n\t                        }\n\t                    }\n\t                    len += l;\n\t                    x = +p[5];\n\t                    y = +p[6];\n\t                }\n\t                sp += p.shift() + p;\n\t            }\n\t            subpaths.end = sp;\n\t            point = istotal ? len : subpath ? subpaths : R.findDotsAtSegment(x, y, p[0], p[1], p[2], p[3], p[4], p[5], 1);\n\t            point.alpha && (point = {x: point.x, y: point.y, alpha: point.alpha});\n\t            return point;\n\t        };\n\t    };\n\t    var getTotalLength = getLengthFactory(1),\n\t        getPointAtLength = getLengthFactory(),\n\t        getSubpathsAtLength = getLengthFactory(0, 1);\n\t    /*\\\n\t     * Raphael.getTotalLength\n\t     [ method ]\n\t     **\n\t     * Returns length of the given path in pixels.\n\t     **\n\t     > Parameters\n\t     **\n\t     - path (string) SVG path string.\n\t     **\n\t     = (number) length.\n\t    \\*/\n\t    R.getTotalLength = getTotalLength;\n\t    /*\\\n\t     * Raphael.getPointAtLength\n\t     [ method ]\n\t     **\n\t     * Return coordinates of the point located at the given length on the given path.\n\t     **\n\t     > Parameters\n\t     **\n\t     - path (string) SVG path string\n\t     - length (number)\n\t     **\n\t     = (object) representation of the point:\n\t     o {\n\t     o     x: (number) x coordinate\n\t     o     y: (number) y coordinate\n\t     o     alpha: (number) angle of derivative\n\t     o }\n\t    \\*/\n\t    R.getPointAtLength = getPointAtLength;\n\t    /*\\\n\t     * Raphael.getSubpath\n\t     [ method ]\n\t     **\n\t     * Return subpath of a given path from given length to given length.\n\t     **\n\t     > Parameters\n\t     **\n\t     - path (string) SVG path string\n\t     - from (number) position of the start of the segment\n\t     - to (number) position of the end of the segment\n\t     **\n\t     = (string) pathstring for the segment\n\t    \\*/\n\t    R.getSubpath = function (path, from, to) {\n\t        if (this.getTotalLength(path) - to < 1e-6) {\n\t            return getSubpathsAtLength(path, from).end;\n\t        }\n\t        var a = getSubpathsAtLength(path, to, 1);\n\t        return from ? getSubpathsAtLength(a, from).end : a;\n\t    };\n\t    /*\\\n\t     * Element.getTotalLength\n\t     [ method ]\n\t     **\n\t     * Returns length of the path in pixels. Only works for element of “path” type.\n\t     = (number) length.\n\t    \\*/\n\t    elproto.getTotalLength = function () {\n\t        var path = this.getPath();\n\t        if (!path) {\n\t            return;\n\t        }\n\n\t        if (this.node.getTotalLength) {\n\t            return this.node.getTotalLength();\n\t        }\n\n\t        return getTotalLength(path);\n\t    };\n\t    /*\\\n\t     * Element.getPointAtLength\n\t     [ method ]\n\t     **\n\t     * Return coordinates of the point located at the given length on the given path. Only works for element of “path” type.\n\t     **\n\t     > Parameters\n\t     **\n\t     - length (number)\n\t     **\n\t     = (object) representation of the point:\n\t     o {\n\t     o     x: (number) x coordinate\n\t     o     y: (number) y coordinate\n\t     o     alpha: (number) angle of derivative\n\t     o }\n\t    \\*/\n\t    elproto.getPointAtLength = function (length) {\n\t        var path = this.getPath();\n\t        if (!path) {\n\t            return;\n\t        }\n\n\t        return getPointAtLength(path, length);\n\t    };\n\t    /*\\\n\t     * Element.getPath\n\t     [ method ]\n\t     **\n\t     * Returns path of the element. Only works for elements of “path” type and simple elements like circle.\n\t     = (object) path\n\t     **\n\t    \\*/\n\t    elproto.getPath = function () {\n\t        var path,\n\t            getPath = R._getPath[this.type];\n\n\t        if (this.type == \"text\" || this.type == \"set\") {\n\t            return;\n\t        }\n\n\t        if (getPath) {\n\t            path = getPath(this);\n\t        }\n\n\t        return path;\n\t    };\n\t    /*\\\n\t     * Element.getSubpath\n\t     [ method ]\n\t     **\n\t     * Return subpath of a given element from given length to given length. Only works for element of “path” type.\n\t     **\n\t     > Parameters\n\t     **\n\t     - from (number) position of the start of the segment\n\t     - to (number) position of the end of the segment\n\t     **\n\t     = (string) pathstring for the segment\n\t    \\*/\n\t    elproto.getSubpath = function (from, to) {\n\t        var path = this.getPath();\n\t        if (!path) {\n\t            return;\n\t        }\n\n\t        return R.getSubpath(path, from, to);\n\t    };\n\t    /*\\\n\t     * Raphael.easing_formulas\n\t     [ property ]\n\t     **\n\t     * Object that contains easing formulas for animation. You could extend it with your own. By default it has following list of easing:\n\t     # <ul>\n\t     #     <li>“linear”</li>\n\t     #     <li>“&lt;” or “easeIn” or “ease-in”</li>\n\t     #     <li>“>” or “easeOut” or “ease-out”</li>\n\t     #     <li>“&lt;>” or “easeInOut” or “ease-in-out”</li>\n\t     #     <li>“backIn” or “back-in”</li>\n\t     #     <li>“backOut” or “back-out”</li>\n\t     #     <li>“elastic”</li>\n\t     #     <li>“bounce”</li>\n\t     # </ul>\n\t     # <p>See also <a href=\"http://raphaeljs.com/easing.html\">Easing demo</a>.</p>\n\t    \\*/\n\t    var ef = R.easing_formulas = {\n\t        linear: function (n) {\n\t            return n;\n\t        },\n\t        \"<\": function (n) {\n\t            return pow(n, 1.7);\n\t        },\n\t        \">\": function (n) {\n\t            return pow(n, .48);\n\t        },\n\t        \"<>\": function (n) {\n\t            var q = .48 - n / 1.04,\n\t                Q = math.sqrt(.1734 + q * q),\n\t                x = Q - q,\n\t                X = pow(abs(x), 1 / 3) * (x < 0 ? -1 : 1),\n\t                y = -Q - q,\n\t                Y = pow(abs(y), 1 / 3) * (y < 0 ? -1 : 1),\n\t                t = X + Y + .5;\n\t            return (1 - t) * 3 * t * t + t * t * t;\n\t        },\n\t        backIn: function (n) {\n\t            var s = 1.70158;\n\t            return n * n * ((s + 1) * n - s);\n\t        },\n\t        backOut: function (n) {\n\t            n = n - 1;\n\t            var s = 1.70158;\n\t            return n * n * ((s + 1) * n + s) + 1;\n\t        },\n\t        elastic: function (n) {\n\t            if (n == !!n) {\n\t                return n;\n\t            }\n\t            return pow(2, -10 * n) * math.sin((n - .075) * (2 * PI) / .3) + 1;\n\t        },\n\t        bounce: function (n) {\n\t            var s = 7.5625,\n\t                p = 2.75,\n\t                l;\n\t            if (n < (1 / p)) {\n\t                l = s * n * n;\n\t            } else {\n\t                if (n < (2 / p)) {\n\t                    n -= (1.5 / p);\n\t                    l = s * n * n + .75;\n\t                } else {\n\t                    if (n < (2.5 / p)) {\n\t                        n -= (2.25 / p);\n\t                        l = s * n * n + .9375;\n\t                    } else {\n\t                        n -= (2.625 / p);\n\t                        l = s * n * n + .984375;\n\t                    }\n\t                }\n\t            }\n\t            return l;\n\t        }\n\t    };\n\t    ef.easeIn = ef[\"ease-in\"] = ef[\"<\"];\n\t    ef.easeOut = ef[\"ease-out\"] = ef[\">\"];\n\t    ef.easeInOut = ef[\"ease-in-out\"] = ef[\"<>\"];\n\t    ef[\"back-in\"] = ef.backIn;\n\t    ef[\"back-out\"] = ef.backOut;\n\n\t    var animationElements = [],\n\t        requestAnimFrame = window.requestAnimationFrame       ||\n\t                           window.webkitRequestAnimationFrame ||\n\t                           window.mozRequestAnimationFrame    ||\n\t                           window.oRequestAnimationFrame      ||\n\t                           window.msRequestAnimationFrame     ||\n\t                           function (callback) {\n\t                               setTimeout(callback, 16);\n\t                           },\n\t        animation = function () {\n\t            var Now = +new Date,\n\t                l = 0;\n\t            for (; l < animationElements.length; l++) {\n\t                var e = animationElements[l];\n\t                if (e.el.removed || e.paused) {\n\t                    continue;\n\t                }\n\t                var time = Now - e.start,\n\t                    ms = e.ms,\n\t                    easing = e.easing,\n\t                    from = e.from,\n\t                    diff = e.diff,\n\t                    to = e.to,\n\t                    t = e.t,\n\t                    that = e.el,\n\t                    set = {},\n\t                    now,\n\t                    init = {},\n\t                    key;\n\t                if (e.initstatus) {\n\t                    time = (e.initstatus * e.anim.top - e.prev) / (e.percent - e.prev) * ms;\n\t                    e.status = e.initstatus;\n\t                    delete e.initstatus;\n\t                    e.stop && animationElements.splice(l--, 1);\n\t                } else {\n\t                    e.status = (e.prev + (e.percent - e.prev) * (time / ms)) / e.anim.top;\n\t                }\n\t                if (time < 0) {\n\t                    continue;\n\t                }\n\t                if (time < ms) {\n\t                    var pos = easing(time / ms);\n\t                    for (var attr in from) if (from[has](attr)) {\n\t                        switch (availableAnimAttrs[attr]) {\n\t                            case nu:\n\t                                now = +from[attr] + pos * ms * diff[attr];\n\t                                break;\n\t                            case \"colour\":\n\t                                now = \"rgb(\" + [\n\t                                    upto255(round(from[attr].r + pos * ms * diff[attr].r)),\n\t                                    upto255(round(from[attr].g + pos * ms * diff[attr].g)),\n\t                                    upto255(round(from[attr].b + pos * ms * diff[attr].b))\n\t                                ].join(\",\") + \")\";\n\t                                break;\n\t                            case \"path\":\n\t                                now = [];\n\t                                for (var i = 0, ii = from[attr].length; i < ii; i++) {\n\t                                    now[i] = [from[attr][i][0]];\n\t                                    for (var j = 1, jj = from[attr][i].length; j < jj; j++) {\n\t                                        now[i][j] = +from[attr][i][j] + pos * ms * diff[attr][i][j];\n\t                                    }\n\t                                    now[i] = now[i].join(S);\n\t                                }\n\t                                now = now.join(S);\n\t                                break;\n\t                            case \"transform\":\n\t                                if (diff[attr].real) {\n\t                                    now = [];\n\t                                    for (i = 0, ii = from[attr].length; i < ii; i++) {\n\t                                        now[i] = [from[attr][i][0]];\n\t                                        for (j = 1, jj = from[attr][i].length; j < jj; j++) {\n\t                                            now[i][j] = from[attr][i][j] + pos * ms * diff[attr][i][j];\n\t                                        }\n\t                                    }\n\t                                } else {\n\t                                    var get = function (i) {\n\t                                        return +from[attr][i] + pos * ms * diff[attr][i];\n\t                                    };\n\t                                    // now = [[\"r\", get(2), 0, 0], [\"t\", get(3), get(4)], [\"s\", get(0), get(1), 0, 0]];\n\t                                    now = [[\"m\", get(0), get(1), get(2), get(3), get(4), get(5)]];\n\t                                }\n\t                                break;\n\t                            case \"csv\":\n\t                                if (attr == \"clip-rect\") {\n\t                                    now = [];\n\t                                    i = 4;\n\t                                    while (i--) {\n\t                                        now[i] = +from[attr][i] + pos * ms * diff[attr][i];\n\t                                    }\n\t                                }\n\t                                break;\n\t                            default:\n\t                                var from2 = [][concat](from[attr]);\n\t                                now = [];\n\t                                i = that.paper.customAttributes[attr].length;\n\t                                while (i--) {\n\t                                    now[i] = +from2[i] + pos * ms * diff[attr][i];\n\t                                }\n\t                                break;\n\t                        }\n\t                        set[attr] = now;\n\t                    }\n\t                    that.attr(set);\n\t                    (function (id, that, anim) {\n\t                        setTimeout(function () {\n\t                            eve(\"raphael.anim.frame.\" + id, that, anim);\n\t                        });\n\t                    })(that.id, that, e.anim);\n\t                } else {\n\t                    (function(f, el, a) {\n\t                        setTimeout(function() {\n\t                            eve(\"raphael.anim.frame.\" + el.id, el, a);\n\t                            eve(\"raphael.anim.finish.\" + el.id, el, a);\n\t                            R.is(f, \"function\") && f.call(el);\n\t                        });\n\t                    })(e.callback, that, e.anim);\n\t                    that.attr(to);\n\t                    animationElements.splice(l--, 1);\n\t                    if (e.repeat > 1 && !e.next) {\n\t                        for (key in to) if (to[has](key)) {\n\t                            init[key] = e.totalOrigin[key];\n\t                        }\n\t                        e.el.attr(init);\n\t                        runAnimation(e.anim, e.el, e.anim.percents[0], null, e.totalOrigin, e.repeat - 1);\n\t                    }\n\t                    if (e.next && !e.stop) {\n\t                        runAnimation(e.anim, e.el, e.next, null, e.totalOrigin, e.repeat);\n\t                    }\n\t                }\n\t            }\n\t            animationElements.length && requestAnimFrame(animation);\n\t        },\n\t        upto255 = function (color) {\n\t            return color > 255 ? 255 : color < 0 ? 0 : color;\n\t        };\n\t    /*\\\n\t     * Element.animateWith\n\t     [ method ]\n\t     **\n\t     * Acts similar to @Element.animate, but ensure that given animation runs in sync with another given element.\n\t     **\n\t     > Parameters\n\t     **\n\t     - el (object) element to sync with\n\t     - anim (object) animation to sync with\n\t     - params (object) #optional final attributes for the element, see also @Element.attr\n\t     - ms (number) #optional number of milliseconds for animation to run\n\t     - easing (string) #optional easing type. Accept on of @Raphael.easing_formulas or CSS format: `cubic&#x2010;bezier(XX,&#160;XX,&#160;XX,&#160;XX)`\n\t     - callback (function) #optional callback function. Will be called at the end of animation.\n\t     * or\n\t     - element (object) element to sync with\n\t     - anim (object) animation to sync with\n\t     - animation (object) #optional animation object, see @Raphael.animation\n\t     **\n\t     = (object) original element\n\t    \\*/\n\t    elproto.animateWith = function (el, anim, params, ms, easing, callback) {\n\t        var element = this;\n\t        if (element.removed) {\n\t            callback && callback.call(element);\n\t            return element;\n\t        }\n\t        var a = params instanceof Animation ? params : R.animation(params, ms, easing, callback),\n\t            x, y;\n\t        runAnimation(a, element, a.percents[0], null, element.attr());\n\t        for (var i = 0, ii = animationElements.length; i < ii; i++) {\n\t            if (animationElements[i].anim == anim && animationElements[i].el == el) {\n\t                animationElements[ii - 1].start = animationElements[i].start;\n\t                break;\n\t            }\n\t        }\n\t        return element;\n\t        //\n\t        //\n\t        // var a = params ? R.animation(params, ms, easing, callback) : anim,\n\t        //     status = element.status(anim);\n\t        // return this.animate(a).status(a, status * anim.ms / a.ms);\n\t    };\n\t    function CubicBezierAtTime(t, p1x, p1y, p2x, p2y, duration) {\n\t        var cx = 3 * p1x,\n\t            bx = 3 * (p2x - p1x) - cx,\n\t            ax = 1 - cx - bx,\n\t            cy = 3 * p1y,\n\t            by = 3 * (p2y - p1y) - cy,\n\t            ay = 1 - cy - by;\n\t        function sampleCurveX(t) {\n\t            return ((ax * t + bx) * t + cx) * t;\n\t        }\n\t        function solve(x, epsilon) {\n\t            var t = solveCurveX(x, epsilon);\n\t            return ((ay * t + by) * t + cy) * t;\n\t        }\n\t        function solveCurveX(x, epsilon) {\n\t            var t0, t1, t2, x2, d2, i;\n\t            for(t2 = x, i = 0; i < 8; i++) {\n\t                x2 = sampleCurveX(t2) - x;\n\t                if (abs(x2) < epsilon) {\n\t                    return t2;\n\t                }\n\t                d2 = (3 * ax * t2 + 2 * bx) * t2 + cx;\n\t                if (abs(d2) < 1e-6) {\n\t                    break;\n\t                }\n\t                t2 = t2 - x2 / d2;\n\t            }\n\t            t0 = 0;\n\t            t1 = 1;\n\t            t2 = x;\n\t            if (t2 < t0) {\n\t                return t0;\n\t            }\n\t            if (t2 > t1) {\n\t                return t1;\n\t            }\n\t            while (t0 < t1) {\n\t                x2 = sampleCurveX(t2);\n\t                if (abs(x2 - x) < epsilon) {\n\t                    return t2;\n\t                }\n\t                if (x > x2) {\n\t                    t0 = t2;\n\t                } else {\n\t                    t1 = t2;\n\t                }\n\t                t2 = (t1 - t0) / 2 + t0;\n\t            }\n\t            return t2;\n\t        }\n\t        return solve(t, 1 / (200 * duration));\n\t    }\n\t    elproto.onAnimation = function (f) {\n\t        f ? eve.on(\"raphael.anim.frame.\" + this.id, f) : eve.unbind(\"raphael.anim.frame.\" + this.id);\n\t        return this;\n\t    };\n\t    function Animation(anim, ms) {\n\t        var percents = [],\n\t            newAnim = {};\n\t        this.ms = ms;\n\t        this.times = 1;\n\t        if (anim) {\n\t            for (var attr in anim) if (anim[has](attr)) {\n\t                newAnim[toFloat(attr)] = anim[attr];\n\t                percents.push(toFloat(attr));\n\t            }\n\t            percents.sort(sortByNumber);\n\t        }\n\t        this.anim = newAnim;\n\t        this.top = percents[percents.length - 1];\n\t        this.percents = percents;\n\t    }\n\t    /*\\\n\t     * Animation.delay\n\t     [ method ]\n\t     **\n\t     * Creates a copy of existing animation object with given delay.\n\t     **\n\t     > Parameters\n\t     **\n\t     - delay (number) number of ms to pass between animation start and actual animation\n\t     **\n\t     = (object) new altered Animation object\n\t     | var anim = Raphael.animation({cx: 10, cy: 20}, 2e3);\n\t     | circle1.animate(anim); // run the given animation immediately\n\t     | circle2.animate(anim.delay(500)); // run the given animation after 500 ms\n\t    \\*/\n\t    Animation.prototype.delay = function (delay) {\n\t        var a = new Animation(this.anim, this.ms);\n\t        a.times = this.times;\n\t        a.del = +delay || 0;\n\t        return a;\n\t    };\n\t    /*\\\n\t     * Animation.repeat\n\t     [ method ]\n\t     **\n\t     * Creates a copy of existing animation object with given repetition.\n\t     **\n\t     > Parameters\n\t     **\n\t     - repeat (number) number iterations of animation. For infinite animation pass `Infinity`\n\t     **\n\t     = (object) new altered Animation object\n\t    \\*/\n\t    Animation.prototype.repeat = function (times) {\n\t        var a = new Animation(this.anim, this.ms);\n\t        a.del = this.del;\n\t        a.times = math.floor(mmax(times, 0)) || 1;\n\t        return a;\n\t    };\n\t    function runAnimation(anim, element, percent, status, totalOrigin, times) {\n\t        percent = toFloat(percent);\n\t        var params,\n\t            isInAnim,\n\t            isInAnimSet,\n\t            percents = [],\n\t            next,\n\t            prev,\n\t            timestamp,\n\t            ms = anim.ms,\n\t            from = {},\n\t            to = {},\n\t            diff = {};\n\t        if (status) {\n\t            for (i = 0, ii = animationElements.length; i < ii; i++) {\n\t                var e = animationElements[i];\n\t                if (e.el.id == element.id && e.anim == anim) {\n\t                    if (e.percent != percent) {\n\t                        animationElements.splice(i, 1);\n\t                        isInAnimSet = 1;\n\t                    } else {\n\t                        isInAnim = e;\n\t                    }\n\t                    element.attr(e.totalOrigin);\n\t                    break;\n\t                }\n\t            }\n\t        } else {\n\t            status = +to; // NaN\n\t        }\n\t        for (var i = 0, ii = anim.percents.length; i < ii; i++) {\n\t            if (anim.percents[i] == percent || anim.percents[i] > status * anim.top) {\n\t                percent = anim.percents[i];\n\t                prev = anim.percents[i - 1] || 0;\n\t                ms = ms / anim.top * (percent - prev);\n\t                next = anim.percents[i + 1];\n\t                params = anim.anim[percent];\n\t                break;\n\t            } else if (status) {\n\t                element.attr(anim.anim[anim.percents[i]]);\n\t            }\n\t        }\n\t        if (!params) {\n\t            return;\n\t        }\n\t        if (!isInAnim) {\n\t            for (var attr in params) if (params[has](attr)) {\n\t                if (availableAnimAttrs[has](attr) || element.paper.customAttributes[has](attr)) {\n\t                    from[attr] = element.attr(attr);\n\t                    (from[attr] == null) && (from[attr] = availableAttrs[attr]);\n\t                    to[attr] = params[attr];\n\t                    switch (availableAnimAttrs[attr]) {\n\t                        case nu:\n\t                            diff[attr] = (to[attr] - from[attr]) / ms;\n\t                            break;\n\t                        case \"colour\":\n\t                            from[attr] = R.getRGB(from[attr]);\n\t                            var toColour = R.getRGB(to[attr]);\n\t                            diff[attr] = {\n\t                                r: (toColour.r - from[attr].r) / ms,\n\t                                g: (toColour.g - from[attr].g) / ms,\n\t                                b: (toColour.b - from[attr].b) / ms\n\t                            };\n\t                            break;\n\t                        case \"path\":\n\t                            var pathes = path2curve(from[attr], to[attr]),\n\t                                toPath = pathes[1];\n\t                            from[attr] = pathes[0];\n\t                            diff[attr] = [];\n\t                            for (i = 0, ii = from[attr].length; i < ii; i++) {\n\t                                diff[attr][i] = [0];\n\t                                for (var j = 1, jj = from[attr][i].length; j < jj; j++) {\n\t                                    diff[attr][i][j] = (toPath[i][j] - from[attr][i][j]) / ms;\n\t                                }\n\t                            }\n\t                            break;\n\t                        case \"transform\":\n\t                            var _ = element._,\n\t                                eq = equaliseTransform(_[attr], to[attr]);\n\t                            if (eq) {\n\t                                from[attr] = eq.from;\n\t                                to[attr] = eq.to;\n\t                                diff[attr] = [];\n\t                                diff[attr].real = true;\n\t                                for (i = 0, ii = from[attr].length; i < ii; i++) {\n\t                                    diff[attr][i] = [from[attr][i][0]];\n\t                                    for (j = 1, jj = from[attr][i].length; j < jj; j++) {\n\t                                        diff[attr][i][j] = (to[attr][i][j] - from[attr][i][j]) / ms;\n\t                                    }\n\t                                }\n\t                            } else {\n\t                                var m = (element.matrix || new Matrix),\n\t                                    to2 = {\n\t                                        _: {transform: _.transform},\n\t                                        getBBox: function () {\n\t                                            return element.getBBox(1);\n\t                                        }\n\t                                    };\n\t                                from[attr] = [\n\t                                    m.a,\n\t                                    m.b,\n\t                                    m.c,\n\t                                    m.d,\n\t                                    m.e,\n\t                                    m.f\n\t                                ];\n\t                                extractTransform(to2, to[attr]);\n\t                                to[attr] = to2._.transform;\n\t                                diff[attr] = [\n\t                                    (to2.matrix.a - m.a) / ms,\n\t                                    (to2.matrix.b - m.b) / ms,\n\t                                    (to2.matrix.c - m.c) / ms,\n\t                                    (to2.matrix.d - m.d) / ms,\n\t                                    (to2.matrix.e - m.e) / ms,\n\t                                    (to2.matrix.f - m.f) / ms\n\t                                ];\n\t                                // from[attr] = [_.sx, _.sy, _.deg, _.dx, _.dy];\n\t                                // var to2 = {_:{}, getBBox: function () { return element.getBBox(); }};\n\t                                // extractTransform(to2, to[attr]);\n\t                                // diff[attr] = [\n\t                                //     (to2._.sx - _.sx) / ms,\n\t                                //     (to2._.sy - _.sy) / ms,\n\t                                //     (to2._.deg - _.deg) / ms,\n\t                                //     (to2._.dx - _.dx) / ms,\n\t                                //     (to2._.dy - _.dy) / ms\n\t                                // ];\n\t                            }\n\t                            break;\n\t                        case \"csv\":\n\t                            var values = Str(params[attr])[split](separator),\n\t                                from2 = Str(from[attr])[split](separator);\n\t                            if (attr == \"clip-rect\") {\n\t                                from[attr] = from2;\n\t                                diff[attr] = [];\n\t                                i = from2.length;\n\t                                while (i--) {\n\t                                    diff[attr][i] = (values[i] - from[attr][i]) / ms;\n\t                                }\n\t                            }\n\t                            to[attr] = values;\n\t                            break;\n\t                        default:\n\t                            values = [][concat](params[attr]);\n\t                            from2 = [][concat](from[attr]);\n\t                            diff[attr] = [];\n\t                            i = element.paper.customAttributes[attr].length;\n\t                            while (i--) {\n\t                                diff[attr][i] = ((values[i] || 0) - (from2[i] || 0)) / ms;\n\t                            }\n\t                            break;\n\t                    }\n\t                }\n\t            }\n\t            var easing = params.easing,\n\t                easyeasy = R.easing_formulas[easing];\n\t            if (!easyeasy) {\n\t                easyeasy = Str(easing).match(bezierrg);\n\t                if (easyeasy && easyeasy.length == 5) {\n\t                    var curve = easyeasy;\n\t                    easyeasy = function (t) {\n\t                        return CubicBezierAtTime(t, +curve[1], +curve[2], +curve[3], +curve[4], ms);\n\t                    };\n\t                } else {\n\t                    easyeasy = pipe;\n\t                }\n\t            }\n\t            timestamp = params.start || anim.start || +new Date;\n\t            e = {\n\t                anim: anim,\n\t                percent: percent,\n\t                timestamp: timestamp,\n\t                start: timestamp + (anim.del || 0),\n\t                status: 0,\n\t                initstatus: status || 0,\n\t                stop: false,\n\t                ms: ms,\n\t                easing: easyeasy,\n\t                from: from,\n\t                diff: diff,\n\t                to: to,\n\t                el: element,\n\t                callback: params.callback,\n\t                prev: prev,\n\t                next: next,\n\t                repeat: times || anim.times,\n\t                origin: element.attr(),\n\t                totalOrigin: totalOrigin\n\t            };\n\t            animationElements.push(e);\n\t            if (status && !isInAnim && !isInAnimSet) {\n\t                e.stop = true;\n\t                e.start = new Date - ms * status;\n\t                if (animationElements.length == 1) {\n\t                    return animation();\n\t                }\n\t            }\n\t            if (isInAnimSet) {\n\t                e.start = new Date - e.ms * status;\n\t            }\n\t            animationElements.length == 1 && requestAnimFrame(animation);\n\t        } else {\n\t            isInAnim.initstatus = status;\n\t            isInAnim.start = new Date - isInAnim.ms * status;\n\t        }\n\t        eve(\"raphael.anim.start.\" + element.id, element, anim);\n\t    }\n\t    /*\\\n\t     * Raphael.animation\n\t     [ method ]\n\t     **\n\t     * Creates an animation object that can be passed to the @Element.animate or @Element.animateWith methods.\n\t     * See also @Animation.delay and @Animation.repeat methods.\n\t     **\n\t     > Parameters\n\t     **\n\t     - params (object) final attributes for the element, see also @Element.attr\n\t     - ms (number) number of milliseconds for animation to run\n\t     - easing (string) #optional easing type. Accept one of @Raphael.easing_formulas or CSS format: `cubic&#x2010;bezier(XX,&#160;XX,&#160;XX,&#160;XX)`\n\t     - callback (function) #optional callback function. Will be called at the end of animation.\n\t     **\n\t     = (object) @Animation\n\t    \\*/\n\t    R.animation = function (params, ms, easing, callback) {\n\t        if (params instanceof Animation) {\n\t            return params;\n\t        }\n\t        if (R.is(easing, \"function\") || !easing) {\n\t            callback = callback || easing || null;\n\t            easing = null;\n\t        }\n\t        params = Object(params);\n\t        ms = +ms || 0;\n\t        var p = {},\n\t            json,\n\t            attr;\n\t        for (attr in params) if (params[has](attr) && toFloat(attr) != attr && toFloat(attr) + \"%\" != attr) {\n\t            json = true;\n\t            p[attr] = params[attr];\n\t        }\n\t        if (!json) {\n\t            // if percent-like syntax is used and end-of-all animation callback used\n\t            if(callback){\n\t                // find the last one\n\t                var lastKey = 0;\n\t                for(var i in params){\n\t                    var percent = toInt(i);\n\t                    if(params[has](i) && percent > lastKey){\n\t                        lastKey = percent;\n\t                    }\n\t                }\n\t                lastKey += '%';\n\t                // if already defined callback in the last keyframe, skip\n\t                !params[lastKey].callback && (params[lastKey].callback = callback);\n\t            }\n\t          return new Animation(params, ms);\n\t        } else {\n\t            easing && (p.easing = easing);\n\t            callback && (p.callback = callback);\n\t            return new Animation({100: p}, ms);\n\t        }\n\t    };\n\t    /*\\\n\t     * Element.animate\n\t     [ method ]\n\t     **\n\t     * Creates and starts animation for given element.\n\t     **\n\t     > Parameters\n\t     **\n\t     - params (object) final attributes for the element, see also @Element.attr\n\t     - ms (number) number of milliseconds for animation to run\n\t     - easing (string) #optional easing type. Accept one of @Raphael.easing_formulas or CSS format: `cubic&#x2010;bezier(XX,&#160;XX,&#160;XX,&#160;XX)`\n\t     - callback (function) #optional callback function. Will be called at the end of animation.\n\t     * or\n\t     - animation (object) animation object, see @Raphael.animation\n\t     **\n\t     = (object) original element\n\t    \\*/\n\t    elproto.animate = function (params, ms, easing, callback) {\n\t        var element = this;\n\t        if (element.removed) {\n\t            callback && callback.call(element);\n\t            return element;\n\t        }\n\t        var anim = params instanceof Animation ? params : R.animation(params, ms, easing, callback);\n\t        runAnimation(anim, element, anim.percents[0], null, element.attr());\n\t        return element;\n\t    };\n\t    /*\\\n\t     * Element.setTime\n\t     [ method ]\n\t     **\n\t     * Sets the status of animation of the element in milliseconds. Similar to @Element.status method.\n\t     **\n\t     > Parameters\n\t     **\n\t     - anim (object) animation object\n\t     - value (number) number of milliseconds from the beginning of the animation\n\t     **\n\t     = (object) original element if `value` is specified\n\t     * Note, that during animation following events are triggered:\n\t     *\n\t     * On each animation frame event `anim.frame.<id>`, on start `anim.start.<id>` and on end `anim.finish.<id>`.\n\t    \\*/\n\t    elproto.setTime = function (anim, value) {\n\t        if (anim && value != null) {\n\t            this.status(anim, mmin(value, anim.ms) / anim.ms);\n\t        }\n\t        return this;\n\t    };\n\t    /*\\\n\t     * Element.status\n\t     [ method ]\n\t     **\n\t     * Gets or sets the status of animation of the element.\n\t     **\n\t     > Parameters\n\t     **\n\t     - anim (object) #optional animation object\n\t     - value (number) #optional 0 – 1. If specified, method works like a setter and sets the status of a given animation to the value. This will cause animation to jump to the given position.\n\t     **\n\t     = (number) status\n\t     * or\n\t     = (array) status if `anim` is not specified. Array of objects in format:\n\t     o {\n\t     o     anim: (object) animation object\n\t     o     status: (number) status\n\t     o }\n\t     * or\n\t     = (object) original element if `value` is specified\n\t    \\*/\n\t    elproto.status = function (anim, value) {\n\t        var out = [],\n\t            i = 0,\n\t            len,\n\t            e;\n\t        if (value != null) {\n\t            runAnimation(anim, this, -1, mmin(value, 1));\n\t            return this;\n\t        } else {\n\t            len = animationElements.length;\n\t            for (; i < len; i++) {\n\t                e = animationElements[i];\n\t                if (e.el.id == this.id && (!anim || e.anim == anim)) {\n\t                    if (anim) {\n\t                        return e.status;\n\t                    }\n\t                    out.push({\n\t                        anim: e.anim,\n\t                        status: e.status\n\t                    });\n\t                }\n\t            }\n\t            if (anim) {\n\t                return 0;\n\t            }\n\t            return out;\n\t        }\n\t    };\n\t    /*\\\n\t     * Element.pause\n\t     [ method ]\n\t     **\n\t     * Stops animation of the element with ability to resume it later on.\n\t     **\n\t     > Parameters\n\t     **\n\t     - anim (object) #optional animation object\n\t     **\n\t     = (object) original element\n\t    \\*/\n\t    elproto.pause = function (anim) {\n\t        for (var i = 0; i < animationElements.length; i++) if (animationElements[i].el.id == this.id && (!anim || animationElements[i].anim == anim)) {\n\t            if (eve(\"raphael.anim.pause.\" + this.id, this, animationElements[i].anim) !== false) {\n\t                animationElements[i].paused = true;\n\t            }\n\t        }\n\t        return this;\n\t    };\n\t    /*\\\n\t     * Element.resume\n\t     [ method ]\n\t     **\n\t     * Resumes animation if it was paused with @Element.pause method.\n\t     **\n\t     > Parameters\n\t     **\n\t     - anim (object) #optional animation object\n\t     **\n\t     = (object) original element\n\t    \\*/\n\t    elproto.resume = function (anim) {\n\t        for (var i = 0; i < animationElements.length; i++) if (animationElements[i].el.id == this.id && (!anim || animationElements[i].anim == anim)) {\n\t            var e = animationElements[i];\n\t            if (eve(\"raphael.anim.resume.\" + this.id, this, e.anim) !== false) {\n\t                delete e.paused;\n\t                this.status(e.anim, e.status);\n\t            }\n\t        }\n\t        return this;\n\t    };\n\t    /*\\\n\t     * Element.stop\n\t     [ method ]\n\t     **\n\t     * Stops animation of the element.\n\t     **\n\t     > Parameters\n\t     **\n\t     - anim (object) #optional animation object\n\t     **\n\t     = (object) original element\n\t    \\*/\n\t    elproto.stop = function (anim) {\n\t        for (var i = 0; i < animationElements.length; i++) if (animationElements[i].el.id == this.id && (!anim || animationElements[i].anim == anim)) {\n\t            if (eve(\"raphael.anim.stop.\" + this.id, this, animationElements[i].anim) !== false) {\n\t                animationElements.splice(i--, 1);\n\t            }\n\t        }\n\t        return this;\n\t    };\n\t    function stopAnimation(paper) {\n\t        for (var i = 0; i < animationElements.length; i++) if (animationElements[i].el.paper == paper) {\n\t            animationElements.splice(i--, 1);\n\t        }\n\t    }\n\t    eve.on(\"raphael.remove\", stopAnimation);\n\t    eve.on(\"raphael.clear\", stopAnimation);\n\t    elproto.toString = function () {\n\t        return \"Rapha\\xebl\\u2019s object\";\n\t    };\n\n\t    // Set\n\t    var Set = function (items) {\n\t        this.items = [];\n\t        this.length = 0;\n\t        this.type = \"set\";\n\t        if (items) {\n\t            for (var i = 0, ii = items.length; i < ii; i++) {\n\t                if (items[i] && (items[i].constructor == elproto.constructor || items[i].constructor == Set)) {\n\t                    this[this.items.length] = this.items[this.items.length] = items[i];\n\t                    this.length++;\n\t                }\n\t            }\n\t        }\n\t    },\n\t    setproto = Set.prototype;\n\t    /*\\\n\t     * Set.push\n\t     [ method ]\n\t     **\n\t     * Adds each argument to the current set.\n\t     = (object) original element\n\t    \\*/\n\t    setproto.push = function () {\n\t        var item,\n\t            len;\n\t        for (var i = 0, ii = arguments.length; i < ii; i++) {\n\t            item = arguments[i];\n\t            if (item && (item.constructor == elproto.constructor || item.constructor == Set)) {\n\t                len = this.items.length;\n\t                this[len] = this.items[len] = item;\n\t                this.length++;\n\t            }\n\t        }\n\t        return this;\n\t    };\n\t    /*\\\n\t     * Set.pop\n\t     [ method ]\n\t     **\n\t     * Removes last element and returns it.\n\t     = (object) element\n\t    \\*/\n\t    setproto.pop = function () {\n\t        this.length && delete this[this.length--];\n\t        return this.items.pop();\n\t    };\n\t    /*\\\n\t     * Set.forEach\n\t     [ method ]\n\t     **\n\t     * Executes given function for each element in the set.\n\t     *\n\t     * If function returns `false` it will stop loop running.\n\t     **\n\t     > Parameters\n\t     **\n\t     - callback (function) function to run\n\t     - thisArg (object) context object for the callback\n\t     = (object) Set object\n\t    \\*/\n\t    setproto.forEach = function (callback, thisArg) {\n\t        for (var i = 0, ii = this.items.length; i < ii; i++) {\n\t            if (callback.call(thisArg, this.items[i], i) === false) {\n\t                return this;\n\t            }\n\t        }\n\t        return this;\n\t    };\n\t    for (var method in elproto) if (elproto[has](method)) {\n\t        setproto[method] = (function (methodname) {\n\t            return function () {\n\t                var arg = arguments;\n\t                return this.forEach(function (el) {\n\t                    el[methodname][apply](el, arg);\n\t                });\n\t            };\n\t        })(method);\n\t    }\n\t    setproto.attr = function (name, value) {\n\t        if (name && R.is(name, array) && R.is(name[0], \"object\")) {\n\t            for (var j = 0, jj = name.length; j < jj; j++) {\n\t                this.items[j].attr(name[j]);\n\t            }\n\t        } else {\n\t            for (var i = 0, ii = this.items.length; i < ii; i++) {\n\t                this.items[i].attr(name, value);\n\t            }\n\t        }\n\t        return this;\n\t    };\n\t    /*\\\n\t     * Set.clear\n\t     [ method ]\n\t     **\n\t     * Removes all elements from the set\n\t    \\*/\n\t    setproto.clear = function () {\n\t        while (this.length) {\n\t            this.pop();\n\t        }\n\t    };\n\t    /*\\\n\t     * Set.splice\n\t     [ method ]\n\t     **\n\t     * Removes given element from the set\n\t     **\n\t     > Parameters\n\t     **\n\t     - index (number) position of the deletion\n\t     - count (number) number of element to remove\n\t     - insertion… (object) #optional elements to insert\n\t     = (object) set elements that were deleted\n\t    \\*/\n\t    setproto.splice = function (index, count, insertion) {\n\t        index = index < 0 ? mmax(this.length + index, 0) : index;\n\t        count = mmax(0, mmin(this.length - index, count));\n\t        var tail = [],\n\t            todel = [],\n\t            args = [],\n\t            i;\n\t        for (i = 2; i < arguments.length; i++) {\n\t            args.push(arguments[i]);\n\t        }\n\t        for (i = 0; i < count; i++) {\n\t            todel.push(this[index + i]);\n\t        }\n\t        for (; i < this.length - index; i++) {\n\t            tail.push(this[index + i]);\n\t        }\n\t        var arglen = args.length;\n\t        for (i = 0; i < arglen + tail.length; i++) {\n\t            this.items[index + i] = this[index + i] = i < arglen ? args[i] : tail[i - arglen];\n\t        }\n\t        i = this.items.length = this.length -= count - arglen;\n\t        while (this[i]) {\n\t            delete this[i++];\n\t        }\n\t        return new Set(todel);\n\t    };\n\t    /*\\\n\t     * Set.exclude\n\t     [ method ]\n\t     **\n\t     * Removes given element from the set\n\t     **\n\t     > Parameters\n\t     **\n\t     - element (object) element to remove\n\t     = (boolean) `true` if object was found & removed from the set\n\t    \\*/\n\t    setproto.exclude = function (el) {\n\t        for (var i = 0, ii = this.length; i < ii; i++) if (this[i] == el) {\n\t            this.splice(i, 1);\n\t            return true;\n\t        }\n\t    };\n\t    setproto.animate = function (params, ms, easing, callback) {\n\t        (R.is(easing, \"function\") || !easing) && (callback = easing || null);\n\t        var len = this.items.length,\n\t            i = len,\n\t            item,\n\t            set = this,\n\t            collector;\n\t        if (!len) {\n\t            return this;\n\t        }\n\t        callback && (collector = function () {\n\t            !--len && callback.call(set);\n\t        });\n\t        easing = R.is(easing, string) ? easing : collector;\n\t        var anim = R.animation(params, ms, easing, collector);\n\t        item = this.items[--i].animate(anim);\n\t        while (i--) {\n\t            this.items[i] && !this.items[i].removed && this.items[i].animateWith(item, anim, anim);\n\t            (this.items[i] && !this.items[i].removed) || len--;\n\t        }\n\t        return this;\n\t    };\n\t    setproto.insertAfter = function (el) {\n\t        var i = this.items.length;\n\t        while (i--) {\n\t            this.items[i].insertAfter(el);\n\t        }\n\t        return this;\n\t    };\n\t    setproto.getBBox = function () {\n\t        var x = [],\n\t            y = [],\n\t            x2 = [],\n\t            y2 = [];\n\t        for (var i = this.items.length; i--;) if (!this.items[i].removed) {\n\t            var box = this.items[i].getBBox();\n\t            x.push(box.x);\n\t            y.push(box.y);\n\t            x2.push(box.x + box.width);\n\t            y2.push(box.y + box.height);\n\t        }\n\t        x = mmin[apply](0, x);\n\t        y = mmin[apply](0, y);\n\t        x2 = mmax[apply](0, x2);\n\t        y2 = mmax[apply](0, y2);\n\t        return {\n\t            x: x,\n\t            y: y,\n\t            x2: x2,\n\t            y2: y2,\n\t            width: x2 - x,\n\t            height: y2 - y\n\t        };\n\t    };\n\t    setproto.clone = function (s) {\n\t        s = this.paper.set();\n\t        for (var i = 0, ii = this.items.length; i < ii; i++) {\n\t            s.push(this.items[i].clone());\n\t        }\n\t        return s;\n\t    };\n\t    setproto.toString = function () {\n\t        return \"Rapha\\xebl\\u2018s set\";\n\t    };\n\n\t    setproto.glow = function(glowConfig) {\n\t        var ret = this.paper.set();\n\t        this.forEach(function(shape, index){\n\t            var g = shape.glow(glowConfig);\n\t            if(g != null){\n\t                g.forEach(function(shape2, index2){\n\t                    ret.push(shape2);\n\t                });\n\t            }\n\t        });\n\t        return ret;\n\t    };\n\n\n\t    /*\\\n\t     * Set.isPointInside\n\t     [ method ]\n\t     **\n\t     * Determine if given point is inside this set’s elements\n\t     **\n\t     > Parameters\n\t     **\n\t     - x (number) x coordinate of the point\n\t     - y (number) y coordinate of the point\n\t     = (boolean) `true` if point is inside any of the set's elements\n\t     \\*/\n\t    setproto.isPointInside = function (x, y) {\n\t        var isPointInside = false;\n\t        this.forEach(function (el) {\n\t            if (el.isPointInside(x, y)) {\n\t                isPointInside = true;\n\t                return false; // stop loop\n\t            }\n\t        });\n\t        return isPointInside;\n\t    };\n\n\t    /*\\\n\t     * Raphael.registerFont\n\t     [ method ]\n\t     **\n\t     * Adds given font to the registered set of fonts for Raphaël. Should be used as an internal call from within Cufón’s font file.\n\t     * Returns original parameter, so it could be used with chaining.\n\t     # <a href=\"http://wiki.github.com/sorccu/cufon/about\">More about Cufón and how to convert your font form TTF, OTF, etc to JavaScript file.</a>\n\t     **\n\t     > Parameters\n\t     **\n\t     - font (object) the font to register\n\t     = (object) the font you passed in\n\t     > Usage\n\t     | Cufon.registerFont(Raphael.registerFont({…}));\n\t    \\*/\n\t    R.registerFont = function (font) {\n\t        if (!font.face) {\n\t            return font;\n\t        }\n\t        this.fonts = this.fonts || {};\n\t        var fontcopy = {\n\t                w: font.w,\n\t                face: {},\n\t                glyphs: {}\n\t            },\n\t            family = font.face[\"font-family\"];\n\t        for (var prop in font.face) if (font.face[has](prop)) {\n\t            fontcopy.face[prop] = font.face[prop];\n\t        }\n\t        if (this.fonts[family]) {\n\t            this.fonts[family].push(fontcopy);\n\t        } else {\n\t            this.fonts[family] = [fontcopy];\n\t        }\n\t        if (!font.svg) {\n\t            fontcopy.face[\"units-per-em\"] = toInt(font.face[\"units-per-em\"], 10);\n\t            for (var glyph in font.glyphs) if (font.glyphs[has](glyph)) {\n\t                var path = font.glyphs[glyph];\n\t                fontcopy.glyphs[glyph] = {\n\t                    w: path.w,\n\t                    k: {},\n\t                    d: path.d && \"M\" + path.d.replace(/[mlcxtrv]/g, function (command) {\n\t                            return {l: \"L\", c: \"C\", x: \"z\", t: \"m\", r: \"l\", v: \"c\"}[command] || \"M\";\n\t                        }) + \"z\"\n\t                };\n\t                if (path.k) {\n\t                    for (var k in path.k) if (path[has](k)) {\n\t                        fontcopy.glyphs[glyph].k[k] = path.k[k];\n\t                    }\n\t                }\n\t            }\n\t        }\n\t        return font;\n\t    };\n\t    /*\\\n\t     * Paper.getFont\n\t     [ method ]\n\t     **\n\t     * Finds font object in the registered fonts by given parameters. You could specify only one word from the font name, like “Myriad” for “Myriad Pro”.\n\t     **\n\t     > Parameters\n\t     **\n\t     - family (string) font family name or any word from it\n\t     - weight (string) #optional font weight\n\t     - style (string) #optional font style\n\t     - stretch (string) #optional font stretch\n\t     = (object) the font object\n\t     > Usage\n\t     | paper.print(100, 100, \"Test string\", paper.getFont(\"Times\", 800), 30);\n\t    \\*/\n\t    paperproto.getFont = function (family, weight, style, stretch) {\n\t        stretch = stretch || \"normal\";\n\t        style = style || \"normal\";\n\t        weight = +weight || {normal: 400, bold: 700, lighter: 300, bolder: 800}[weight] || 400;\n\t        if (!R.fonts) {\n\t            return;\n\t        }\n\t        var font = R.fonts[family];\n\t        if (!font) {\n\t            var name = new RegExp(\"(^|\\\\s)\" + family.replace(/[^\\w\\d\\s+!~.:_-]/g, E) + \"(\\\\s|$)\", \"i\");\n\t            for (var fontName in R.fonts) if (R.fonts[has](fontName)) {\n\t                if (name.test(fontName)) {\n\t                    font = R.fonts[fontName];\n\t                    break;\n\t                }\n\t            }\n\t        }\n\t        var thefont;\n\t        if (font) {\n\t            for (var i = 0, ii = font.length; i < ii; i++) {\n\t                thefont = font[i];\n\t                if (thefont.face[\"font-weight\"] == weight && (thefont.face[\"font-style\"] == style || !thefont.face[\"font-style\"]) && thefont.face[\"font-stretch\"] == stretch) {\n\t                    break;\n\t                }\n\t            }\n\t        }\n\t        return thefont;\n\t    };\n\t    /*\\\n\t     * Paper.print\n\t     [ method ]\n\t     **\n\t     * Creates path that represent given text written using given font at given position with given size.\n\t     * Result of the method is path element that contains whole text as a separate path.\n\t     **\n\t     > Parameters\n\t     **\n\t     - x (number) x position of the text\n\t     - y (number) y position of the text\n\t     - string (string) text to print\n\t     - font (object) font object, see @Paper.getFont\n\t     - size (number) #optional size of the font, default is `16`\n\t     - origin (string) #optional could be `\"baseline\"` or `\"middle\"`, default is `\"middle\"`\n\t     - letter_spacing (number) #optional number in range `-1..1`, default is `0`\n\t     - line_spacing (number) #optional number in range `1..3`, default is `1`\n\t     = (object) resulting path element, which consist of all letters\n\t     > Usage\n\t     | var txt = r.print(10, 50, \"print\", r.getFont(\"Museo\"), 30).attr({fill: \"#fff\"});\n\t    \\*/\n\t    paperproto.print = function (x, y, string, font, size, origin, letter_spacing, line_spacing) {\n\t        origin = origin || \"middle\"; // baseline|middle\n\t        letter_spacing = mmax(mmin(letter_spacing || 0, 1), -1);\n\t        line_spacing = mmax(mmin(line_spacing || 1, 3), 1);\n\t        var letters = Str(string)[split](E),\n\t            shift = 0,\n\t            notfirst = 0,\n\t            path = E,\n\t            scale;\n\t        R.is(font, \"string\") && (font = this.getFont(font));\n\t        if (font) {\n\t            scale = (size || 16) / font.face[\"units-per-em\"];\n\t            var bb = font.face.bbox[split](separator),\n\t                top = +bb[0],\n\t                lineHeight = bb[3] - bb[1],\n\t                shifty = 0,\n\t                height = +bb[1] + (origin == \"baseline\" ? lineHeight + (+font.face.descent) : lineHeight / 2);\n\t            for (var i = 0, ii = letters.length; i < ii; i++) {\n\t                if (letters[i] == \"\\n\") {\n\t                    shift = 0;\n\t                    curr = 0;\n\t                    notfirst = 0;\n\t                    shifty += lineHeight * line_spacing;\n\t                } else {\n\t                    var prev = notfirst && font.glyphs[letters[i - 1]] || {},\n\t                        curr = font.glyphs[letters[i]];\n\t                    shift += notfirst ? (prev.w || font.w) + (prev.k && prev.k[letters[i]] || 0) + (font.w * letter_spacing) : 0;\n\t                    notfirst = 1;\n\t                }\n\t                if (curr && curr.d) {\n\t                    path += R.transformPath(curr.d, [\"t\", shift * scale, shifty * scale, \"s\", scale, scale, top, height, \"t\", (x - top) / scale, (y - height) / scale]);\n\t                }\n\t            }\n\t        }\n\t        return this.path(path).attr({\n\t            fill: \"#000\",\n\t            stroke: \"none\"\n\t        });\n\t    };\n\n\t    /*\\\n\t     * Paper.add\n\t     [ method ]\n\t     **\n\t     * Imports elements in JSON array in format `{type: type, <attributes>}`\n\t     **\n\t     > Parameters\n\t     **\n\t     - json (array)\n\t     = (object) resulting set of imported elements\n\t     > Usage\n\t     | paper.add([\n\t     |     {\n\t     |         type: \"circle\",\n\t     |         cx: 10,\n\t     |         cy: 10,\n\t     |         r: 5\n\t     |     },\n\t     |     {\n\t     |         type: \"rect\",\n\t     |         x: 10,\n\t     |         y: 10,\n\t     |         width: 10,\n\t     |         height: 10,\n\t     |         fill: \"#fc0\"\n\t     |     }\n\t     | ]);\n\t    \\*/\n\t    paperproto.add = function (json) {\n\t        if (R.is(json, \"array\")) {\n\t            var res = this.set(),\n\t                i = 0,\n\t                ii = json.length,\n\t                j;\n\t            for (; i < ii; i++) {\n\t                j = json[i] || {};\n\t                elements[has](j.type) && res.push(this[j.type]().attr(j));\n\t            }\n\t        }\n\t        return res;\n\t    };\n\n\t    /*\\\n\t     * Raphael.format\n\t     [ method ]\n\t     **\n\t     * Simple format function. Replaces construction of type “`{<number>}`” to the corresponding argument.\n\t     **\n\t     > Parameters\n\t     **\n\t     - token (string) string to format\n\t     - … (string) rest of arguments will be treated as parameters for replacement\n\t     = (string) formated string\n\t     > Usage\n\t     | var x = 10,\n\t     |     y = 20,\n\t     |     width = 40,\n\t     |     height = 50;\n\t     | // this will draw a rectangular shape equivalent to \"M10,20h40v50h-40z\"\n\t     | paper.path(Raphael.format(\"M{0},{1}h{2}v{3}h{4}z\", x, y, width, height, -width));\n\t    \\*/\n\t    R.format = function (token, params) {\n\t        var args = R.is(params, array) ? [0][concat](params) : arguments;\n\t        token && R.is(token, string) && args.length - 1 && (token = token.replace(formatrg, function (str, i) {\n\t            return args[++i] == null ? E : args[i];\n\t        }));\n\t        return token || E;\n\t    };\n\t    /*\\\n\t     * Raphael.fullfill\n\t     [ method ]\n\t     **\n\t     * A little bit more advanced format function than @Raphael.format. Replaces construction of type “`{<name>}`” to the corresponding argument.\n\t     **\n\t     > Parameters\n\t     **\n\t     - token (string) string to format\n\t     - json (object) object which properties will be used as a replacement\n\t     = (string) formated string\n\t     > Usage\n\t     | // this will draw a rectangular shape equivalent to \"M10,20h40v50h-40z\"\n\t     | paper.path(Raphael.fullfill(\"M{x},{y}h{dim.width}v{dim.height}h{dim['negative width']}z\", {\n\t     |     x: 10,\n\t     |     y: 20,\n\t     |     dim: {\n\t     |         width: 40,\n\t     |         height: 50,\n\t     |         \"negative width\": -40\n\t     |     }\n\t     | }));\n\t    \\*/\n\t    R.fullfill = (function () {\n\t        var tokenRegex = /\\{([^\\}]+)\\}/g,\n\t            objNotationRegex = /(?:(?:^|\\.)(.+?)(?=\\[|\\.|$|\\()|\\[('|\")(.+?)\\2\\])(\\(\\))?/g, // matches .xxxxx or [\"xxxxx\"] to run over object properties\n\t            replacer = function (all, key, obj) {\n\t                var res = obj;\n\t                key.replace(objNotationRegex, function (all, name, quote, quotedName, isFunc) {\n\t                    name = name || quotedName;\n\t                    if (res) {\n\t                        if (name in res) {\n\t                            res = res[name];\n\t                        }\n\t                        typeof res == \"function\" && isFunc && (res = res());\n\t                    }\n\t                });\n\t                res = (res == null || res == obj ? all : res) + \"\";\n\t                return res;\n\t            };\n\t        return function (str, obj) {\n\t            return String(str).replace(tokenRegex, function (all, key) {\n\t                return replacer(all, key, obj);\n\t            });\n\t        };\n\t    })();\n\t    /*\\\n\t     * Raphael.ninja\n\t     [ method ]\n\t     **\n\t     * If you want to leave no trace of Raphaël (Well, Raphaël creates only one global variable `Raphael`, but anyway.) You can use `ninja` method.\n\t     * Beware, that in this case plugins could stop working, because they are depending on global variable existence.\n\t     **\n\t     = (object) Raphael object\n\t     > Usage\n\t     | (function (local_raphael) {\n\t     |     var paper = local_raphael(10, 10, 320, 200);\n\t     |     …\n\t     | })(Raphael.ninja());\n\t    \\*/\n\t    R.ninja = function () {\n\t        if (oldRaphael.was) {\n\t            g.win.Raphael = oldRaphael.is;\n\t        } else {\n\t            // IE8 raises an error when deleting window property\n\t            window.Raphael = undefined;\n\t            try {\n\t                delete window.Raphael;\n\t            } catch(e) {}\n\t        }\n\t        return R;\n\t    };\n\t    /*\\\n\t     * Raphael.st\n\t     [ property (object) ]\n\t     **\n\t     * You can add your own method to elements and sets. It is wise to add a set method for each element method\n\t     * you added, so you will be able to call the same method on sets too.\n\t     **\n\t     * See also @Raphael.el.\n\t     > Usage\n\t     | Raphael.el.red = function () {\n\t     |     this.attr({fill: \"#f00\"});\n\t     | };\n\t     | Raphael.st.red = function () {\n\t     |     this.forEach(function (el) {\n\t     |         el.red();\n\t     |     });\n\t     | };\n\t     | // then use it\n\t     | paper.set(paper.circle(100, 100, 20), paper.circle(110, 100, 20)).red();\n\t    \\*/\n\t    R.st = setproto;\n\n\t    eve.on(\"raphael.DOMload\", function () {\n\t        loaded = true;\n\t    });\n\n\t    // Firefox <3.6 fix: http://webreflection.blogspot.com/2009/11/195-chars-to-help-lazy-loading.html\n\t    (function (doc, loaded, f) {\n\t        if (doc.readyState == null && doc.addEventListener){\n\t            doc.addEventListener(loaded, f = function () {\n\t                doc.removeEventListener(loaded, f, false);\n\t                doc.readyState = \"complete\";\n\t            }, false);\n\t            doc.readyState = \"loading\";\n\t        }\n\t        function isLoaded() {\n\t            (/in/).test(doc.readyState) ? setTimeout(isLoaded, 9) : R.eve(\"raphael.DOMload\");\n\t        }\n\t        isLoaded();\n\t    })(document, \"DOMContentLoaded\");\n\n\t    return R;\n\t}.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));\n\n\n/***/ },\n/* 2 */\n/***/ function(module, exports, __webpack_require__) {\n\n\tvar __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;// Copyright (c) 2013 Adobe Systems Incorporated. All rights reserved.\n\t// \n\t// Licensed under the Apache License, Version 2.0 (the \"License\");\n\t// you may not use this file except in compliance with the License.\n\t// You may obtain a copy of the License at\n\t// \n\t// http://www.apache.org/licenses/LICENSE-2.0\n\t// \n\t// Unless required by applicable law or agreed to in writing, software\n\t// distributed under the License is distributed on an \"AS IS\" BASIS,\n\t// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n\t// See the License for the specific language governing permissions and\n\t// limitations under the License.\n\t// ┌────────────────────────────────────────────────────────────┐ \\\\\n\t// │ Eve 0.4.2 - JavaScript Events Library                      │ \\\\\n\t// ├────────────────────────────────────────────────────────────┤ \\\\\n\t// │ Author Dmitry Baranovskiy (http://dmitry.baranovskiy.com/) │ \\\\\n\t// └────────────────────────────────────────────────────────────┘ \\\\\n\n\t(function (glob) {\n\t    var version = \"0.4.2\",\n\t        has = \"hasOwnProperty\",\n\t        separator = /[\\.\\/]/,\n\t        wildcard = \"*\",\n\t        fun = function () {},\n\t        numsort = function (a, b) {\n\t            return a - b;\n\t        },\n\t        current_event,\n\t        stop,\n\t        events = {n: {}},\n\t    /*\\\n\t     * eve\n\t     [ method ]\n\n\t     * Fires event with given `name`, given scope and other parameters.\n\n\t     > Arguments\n\n\t     - name (string) name of the *event*, dot (`.`) or slash (`/`) separated\n\t     - scope (object) context for the event handlers\n\t     - varargs (...) the rest of arguments will be sent to event handlers\n\n\t     = (object) array of returned values from the listeners\n\t    \\*/\n\t        eve = function (name, scope) {\n\t\t\t\tname = String(name);\n\t            var e = events,\n\t                oldstop = stop,\n\t                args = Array.prototype.slice.call(arguments, 2),\n\t                listeners = eve.listeners(name),\n\t                z = 0,\n\t                f = false,\n\t                l,\n\t                indexed = [],\n\t                queue = {},\n\t                out = [],\n\t                ce = current_event,\n\t                errors = [];\n\t            current_event = name;\n\t            stop = 0;\n\t            for (var i = 0, ii = listeners.length; i < ii; i++) if (\"zIndex\" in listeners[i]) {\n\t                indexed.push(listeners[i].zIndex);\n\t                if (listeners[i].zIndex < 0) {\n\t                    queue[listeners[i].zIndex] = listeners[i];\n\t                }\n\t            }\n\t            indexed.sort(numsort);\n\t            while (indexed[z] < 0) {\n\t                l = queue[indexed[z++]];\n\t                out.push(l.apply(scope, args));\n\t                if (stop) {\n\t                    stop = oldstop;\n\t                    return out;\n\t                }\n\t            }\n\t            for (i = 0; i < ii; i++) {\n\t                l = listeners[i];\n\t                if (\"zIndex\" in l) {\n\t                    if (l.zIndex == indexed[z]) {\n\t                        out.push(l.apply(scope, args));\n\t                        if (stop) {\n\t                            break;\n\t                        }\n\t                        do {\n\t                            z++;\n\t                            l = queue[indexed[z]];\n\t                            l && out.push(l.apply(scope, args));\n\t                            if (stop) {\n\t                                break;\n\t                            }\n\t                        } while (l)\n\t                    } else {\n\t                        queue[l.zIndex] = l;\n\t                    }\n\t                } else {\n\t                    out.push(l.apply(scope, args));\n\t                    if (stop) {\n\t                        break;\n\t                    }\n\t                }\n\t            }\n\t            stop = oldstop;\n\t            current_event = ce;\n\t            return out.length ? out : null;\n\t        };\n\t\t\t// Undocumented. Debug only.\n\t\t\teve._events = events;\n\t    /*\\\n\t     * eve.listeners\n\t     [ method ]\n\n\t     * Internal method which gives you array of all event handlers that will be triggered by the given `name`.\n\n\t     > Arguments\n\n\t     - name (string) name of the event, dot (`.`) or slash (`/`) separated\n\n\t     = (array) array of event handlers\n\t    \\*/\n\t    eve.listeners = function (name) {\n\t        var names = name.split(separator),\n\t            e = events,\n\t            item,\n\t            items,\n\t            k,\n\t            i,\n\t            ii,\n\t            j,\n\t            jj,\n\t            nes,\n\t            es = [e],\n\t            out = [];\n\t        for (i = 0, ii = names.length; i < ii; i++) {\n\t            nes = [];\n\t            for (j = 0, jj = es.length; j < jj; j++) {\n\t                e = es[j].n;\n\t                items = [e[names[i]], e[wildcard]];\n\t                k = 2;\n\t                while (k--) {\n\t                    item = items[k];\n\t                    if (item) {\n\t                        nes.push(item);\n\t                        out = out.concat(item.f || []);\n\t                    }\n\t                }\n\t            }\n\t            es = nes;\n\t        }\n\t        return out;\n\t    };\n\t    \n\t    /*\\\n\t     * eve.on\n\t     [ method ]\n\t     **\n\t     * Binds given event handler with a given name. You can use wildcards “`*`” for the names:\n\t     | eve.on(\"*.under.*\", f);\n\t     | eve(\"mouse.under.floor\"); // triggers f\n\t     * Use @eve to trigger the listener.\n\t     **\n\t     > Arguments\n\t     **\n\t     - name (string) name of the event, dot (`.`) or slash (`/`) separated, with optional wildcards\n\t     - f (function) event handler function\n\t     **\n\t     = (function) returned function accepts a single numeric parameter that represents z-index of the handler. It is an optional feature and only used when you need to ensure that some subset of handlers will be invoked in a given order, despite of the order of assignment. \n\t     > Example:\n\t     | eve.on(\"mouse\", eatIt)(2);\n\t     | eve.on(\"mouse\", scream);\n\t     | eve.on(\"mouse\", catchIt)(1);\n\t     * This will ensure that `catchIt()` function will be called before `eatIt()`.\n\t\t *\n\t     * If you want to put your handler before non-indexed handlers, specify a negative value.\n\t     * Note: I assume most of the time you don’t need to worry about z-index, but it’s nice to have this feature “just in case”.\n\t    \\*/\n\t    eve.on = function (name, f) {\n\t\t\tname = String(name);\n\t\t\tif (typeof f != \"function\") {\n\t\t\t\treturn function () {};\n\t\t\t}\n\t        var names = name.split(separator),\n\t            e = events;\n\t        for (var i = 0, ii = names.length; i < ii; i++) {\n\t            e = e.n;\n\t            e = e.hasOwnProperty(names[i]) && e[names[i]] || (e[names[i]] = {n: {}});\n\t        }\n\t        e.f = e.f || [];\n\t        for (i = 0, ii = e.f.length; i < ii; i++) if (e.f[i] == f) {\n\t            return fun;\n\t        }\n\t        e.f.push(f);\n\t        return function (zIndex) {\n\t            if (+zIndex == +zIndex) {\n\t                f.zIndex = +zIndex;\n\t            }\n\t        };\n\t    };\n\t    /*\\\n\t     * eve.f\n\t     [ method ]\n\t     **\n\t     * Returns function that will fire given event with optional arguments.\n\t\t * Arguments that will be passed to the result function will be also\n\t\t * concated to the list of final arguments.\n\t \t | el.onclick = eve.f(\"click\", 1, 2);\n\t \t | eve.on(\"click\", function (a, b, c) {\n\t \t |     console.log(a, b, c); // 1, 2, [event object]\n\t \t | });\n\t     > Arguments\n\t\t - event (string) event name\n\t\t - varargs (…) and any other arguments\n\t\t = (function) possible event handler function\n\t    \\*/\n\t\teve.f = function (event) {\n\t\t\tvar attrs = [].slice.call(arguments, 1);\n\t\t\treturn function () {\n\t\t\t\teve.apply(null, [event, null].concat(attrs).concat([].slice.call(arguments, 0)));\n\t\t\t};\n\t\t};\n\t    /*\\\n\t     * eve.stop\n\t     [ method ]\n\t     **\n\t     * Is used inside an event handler to stop the event, preventing any subsequent listeners from firing.\n\t    \\*/\n\t    eve.stop = function () {\n\t        stop = 1;\n\t    };\n\t    /*\\\n\t     * eve.nt\n\t     [ method ]\n\t     **\n\t     * Could be used inside event handler to figure out actual name of the event.\n\t     **\n\t     > Arguments\n\t     **\n\t     - subname (string) #optional subname of the event\n\t     **\n\t     = (string) name of the event, if `subname` is not specified\n\t     * or\n\t     = (boolean) `true`, if current event’s name contains `subname`\n\t    \\*/\n\t    eve.nt = function (subname) {\n\t        if (subname) {\n\t            return new RegExp(\"(?:\\\\.|\\\\/|^)\" + subname + \"(?:\\\\.|\\\\/|$)\").test(current_event);\n\t        }\n\t        return current_event;\n\t    };\n\t    /*\\\n\t     * eve.nts\n\t     [ method ]\n\t     **\n\t     * Could be used inside event handler to figure out actual name of the event.\n\t     **\n\t     **\n\t     = (array) names of the event\n\t    \\*/\n\t    eve.nts = function () {\n\t        return current_event.split(separator);\n\t    };\n\t    /*\\\n\t     * eve.off\n\t     [ method ]\n\t     **\n\t     * Removes given function from the list of event listeners assigned to given name.\n\t\t * If no arguments specified all the events will be cleared.\n\t     **\n\t     > Arguments\n\t     **\n\t     - name (string) name of the event, dot (`.`) or slash (`/`) separated, with optional wildcards\n\t     - f (function) event handler function\n\t    \\*/\n\t    /*\\\n\t     * eve.unbind\n\t     [ method ]\n\t     **\n\t     * See @eve.off\n\t    \\*/\n\t    eve.off = eve.unbind = function (name, f) {\n\t\t\tif (!name) {\n\t\t\t    eve._events = events = {n: {}};\n\t\t\t\treturn;\n\t\t\t}\n\t        var names = name.split(separator),\n\t            e,\n\t            key,\n\t            splice,\n\t            i, ii, j, jj,\n\t            cur = [events];\n\t        for (i = 0, ii = names.length; i < ii; i++) {\n\t            for (j = 0; j < cur.length; j += splice.length - 2) {\n\t                splice = [j, 1];\n\t                e = cur[j].n;\n\t                if (names[i] != wildcard) {\n\t                    if (e[names[i]]) {\n\t                        splice.push(e[names[i]]);\n\t                    }\n\t                } else {\n\t                    for (key in e) if (e[has](key)) {\n\t                        splice.push(e[key]);\n\t                    }\n\t                }\n\t                cur.splice.apply(cur, splice);\n\t            }\n\t        }\n\t        for (i = 0, ii = cur.length; i < ii; i++) {\n\t            e = cur[i];\n\t            while (e.n) {\n\t                if (f) {\n\t                    if (e.f) {\n\t                        for (j = 0, jj = e.f.length; j < jj; j++) if (e.f[j] == f) {\n\t                            e.f.splice(j, 1);\n\t                            break;\n\t                        }\n\t                        !e.f.length && delete e.f;\n\t                    }\n\t                    for (key in e.n) if (e.n[has](key) && e.n[key].f) {\n\t                        var funcs = e.n[key].f;\n\t                        for (j = 0, jj = funcs.length; j < jj; j++) if (funcs[j] == f) {\n\t                            funcs.splice(j, 1);\n\t                            break;\n\t                        }\n\t                        !funcs.length && delete e.n[key].f;\n\t                    }\n\t                } else {\n\t                    delete e.f;\n\t                    for (key in e.n) if (e.n[has](key) && e.n[key].f) {\n\t                        delete e.n[key].f;\n\t                    }\n\t                }\n\t                e = e.n;\n\t            }\n\t        }\n\t    };\n\t    /*\\\n\t     * eve.once\n\t     [ method ]\n\t     **\n\t     * Binds given event handler with a given name to only run once then unbind itself.\n\t     | eve.once(\"login\", f);\n\t     | eve(\"login\"); // triggers f\n\t     | eve(\"login\"); // no listeners\n\t     * Use @eve to trigger the listener.\n\t     **\n\t     > Arguments\n\t     **\n\t     - name (string) name of the event, dot (`.`) or slash (`/`) separated, with optional wildcards\n\t     - f (function) event handler function\n\t     **\n\t     = (function) same return function as @eve.on\n\t    \\*/\n\t    eve.once = function (name, f) {\n\t        var f2 = function () {\n\t            eve.unbind(name, f2);\n\t            return f.apply(this, arguments);\n\t        };\n\t        return eve.on(name, f2);\n\t    };\n\t    /*\\\n\t     * eve.version\n\t     [ property (string) ]\n\t     **\n\t     * Current version of the library.\n\t    \\*/\n\t    eve.version = version;\n\t    eve.toString = function () {\n\t        return \"You are running Eve \" + version;\n\t    };\n\t    (typeof module != \"undefined\" && module.exports) ? (module.exports = eve) : ( true ? (!(__WEBPACK_AMD_DEFINE_ARRAY__ = [], __WEBPACK_AMD_DEFINE_RESULT__ = function() { return eve; }.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__))) : (glob.eve = eve));\n\t})(this);\n\n\n/***/ },\n/* 3 */\n/***/ function(module, exports, __webpack_require__) {\n\n\tvar __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;!(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(1)], __WEBPACK_AMD_DEFINE_RESULT__ = function(R) {\n\t    if (R && !R.svg) {\n\t        return;\n\t    }\n\n\t    var has = \"hasOwnProperty\",\n\t        Str = String,\n\t        toFloat = parseFloat,\n\t        toInt = parseInt,\n\t        math = Math,\n\t        mmax = math.max,\n\t        abs = math.abs,\n\t        pow = math.pow,\n\t        separator = /[, ]+/,\n\t        eve = R.eve,\n\t        E = \"\",\n\t        S = \" \";\n\t    var xlink = \"http://www.w3.org/1999/xlink\",\n\t        markers = {\n\t            block: \"M5,0 0,2.5 5,5z\",\n\t            classic: \"M5,0 0,2.5 5,5 3.5,3 3.5,2z\",\n\t            diamond: \"M2.5,0 5,2.5 2.5,5 0,2.5z\",\n\t            open: \"M6,1 1,3.5 6,6\",\n\t            oval: \"M2.5,0A2.5,2.5,0,0,1,2.5,5 2.5,2.5,0,0,1,2.5,0z\"\n\t        },\n\t        markerCounter = {};\n\t    R.toString = function () {\n\t        return  \"Your browser supports SVG.\\nYou are running Rapha\\xebl \" + this.version;\n\t    };\n\t    var $ = function (el, attr) {\n\t        if (attr) {\n\t            if (typeof el == \"string\") {\n\t                el = $(el);\n\t            }\n\t            for (var key in attr) if (attr[has](key)) {\n\t                if (key.substring(0, 6) == \"xlink:\") {\n\t                    el.setAttributeNS(xlink, key.substring(6), Str(attr[key]));\n\t                } else {\n\t                    el.setAttribute(key, Str(attr[key]));\n\t                }\n\t            }\n\t        } else {\n\t            el = R._g.doc.createElementNS(\"http://www.w3.org/2000/svg\", el);\n\t            el.style && (el.style.webkitTapHighlightColor = \"rgba(0,0,0,0)\");\n\t        }\n\t        return el;\n\t    },\n\t    addGradientFill = function (element, gradient) {\n\t        var type = \"linear\",\n\t            id = element.id + gradient,\n\t            fx = .5, fy = .5,\n\t            o = element.node,\n\t            SVG = element.paper,\n\t            s = o.style,\n\t            el = R._g.doc.getElementById(id);\n\t        if (!el) {\n\t            gradient = Str(gradient).replace(R._radial_gradient, function (all, _fx, _fy) {\n\t                type = \"radial\";\n\t                if (_fx && _fy) {\n\t                    fx = toFloat(_fx);\n\t                    fy = toFloat(_fy);\n\t                    var dir = ((fy > .5) * 2 - 1);\n\t                    pow(fx - .5, 2) + pow(fy - .5, 2) > .25 &&\n\t                        (fy = math.sqrt(.25 - pow(fx - .5, 2)) * dir + .5) &&\n\t                        fy != .5 &&\n\t                        (fy = fy.toFixed(5) - 1e-5 * dir);\n\t                }\n\t                return E;\n\t            });\n\t            gradient = gradient.split(/\\s*\\-\\s*/);\n\t            if (type == \"linear\") {\n\t                var angle = gradient.shift();\n\t                angle = -toFloat(angle);\n\t                if (isNaN(angle)) {\n\t                    return null;\n\t                }\n\t                var vector = [0, 0, math.cos(R.rad(angle)), math.sin(R.rad(angle))],\n\t                    max = 1 / (mmax(abs(vector[2]), abs(vector[3])) || 1);\n\t                vector[2] *= max;\n\t                vector[3] *= max;\n\t                if (vector[2] < 0) {\n\t                    vector[0] = -vector[2];\n\t                    vector[2] = 0;\n\t                }\n\t                if (vector[3] < 0) {\n\t                    vector[1] = -vector[3];\n\t                    vector[3] = 0;\n\t                }\n\t            }\n\t            var dots = R._parseDots(gradient);\n\t            if (!dots) {\n\t                return null;\n\t            }\n\t            id = id.replace(/[\\(\\)\\s,\\xb0#]/g, \"_\");\n\n\t            if (element.gradient && id != element.gradient.id) {\n\t                SVG.defs.removeChild(element.gradient);\n\t                delete element.gradient;\n\t            }\n\n\t            if (!element.gradient) {\n\t                el = $(type + \"Gradient\", {id: id});\n\t                element.gradient = el;\n\t                $(el, type == \"radial\" ? {\n\t                    fx: fx,\n\t                    fy: fy\n\t                } : {\n\t                    x1: vector[0],\n\t                    y1: vector[1],\n\t                    x2: vector[2],\n\t                    y2: vector[3],\n\t                    gradientTransform: element.matrix.invert()\n\t                });\n\t                SVG.defs.appendChild(el);\n\t                for (var i = 0, ii = dots.length; i < ii; i++) {\n\t                    el.appendChild($(\"stop\", {\n\t                        offset: dots[i].offset ? dots[i].offset : i ? \"100%\" : \"0%\",\n\t                        \"stop-color\": dots[i].color || \"#fff\",\n\t                        \"stop-opacity\": isFinite(dots[i].opacity) ? dots[i].opacity : 1\n\t                    }));\n\t                }\n\t            }\n\t        }\n\t        $(o, {\n\t            fill: fillurl(id),\n\t            opacity: 1,\n\t            \"fill-opacity\": 1\n\t        });\n\t        s.fill = E;\n\t        s.opacity = 1;\n\t        s.fillOpacity = 1;\n\t        return 1;\n\t    },\n\t    isIE9or10 = function () {\n\t      var mode = document.documentMode;\n\t      return mode && (mode === 9 || mode === 10);\n\t    },\n\t    fillurl = function (id) {\n\t      if (isIE9or10()) {\n\t          return \"url('#\" + id + \"')\";\n\t      }\n\t      var location = document.location;\n\t      var locationString = (\n\t          location.protocol + '//' +\n\t          location.host +\n\t          location.pathname +\n\t          location.search\n\t      );\n\t      return \"url('\" + locationString + \"#\" + id + \"')\";\n\t    },\n\t    updatePosition = function (o) {\n\t        var bbox = o.getBBox(1);\n\t        $(o.pattern, {patternTransform: o.matrix.invert() + \" translate(\" + bbox.x + \",\" + bbox.y + \")\"});\n\t    },\n\t    addArrow = function (o, value, isEnd) {\n\t        if (o.type == \"path\") {\n\t            var values = Str(value).toLowerCase().split(\"-\"),\n\t                p = o.paper,\n\t                se = isEnd ? \"end\" : \"start\",\n\t                node = o.node,\n\t                attrs = o.attrs,\n\t                stroke = attrs[\"stroke-width\"],\n\t                i = values.length,\n\t                type = \"classic\",\n\t                from,\n\t                to,\n\t                dx,\n\t                refX,\n\t                attr,\n\t                w = 3,\n\t                h = 3,\n\t                t = 5;\n\t            while (i--) {\n\t                switch (values[i]) {\n\t                    case \"block\":\n\t                    case \"classic\":\n\t                    case \"oval\":\n\t                    case \"diamond\":\n\t                    case \"open\":\n\t                    case \"none\":\n\t                        type = values[i];\n\t                        break;\n\t                    case \"wide\": h = 5; break;\n\t                    case \"narrow\": h = 2; break;\n\t                    case \"long\": w = 5; break;\n\t                    case \"short\": w = 2; break;\n\t                }\n\t            }\n\t            if (type == \"open\") {\n\t                w += 2;\n\t                h += 2;\n\t                t += 2;\n\t                dx = 1;\n\t                refX = isEnd ? 4 : 1;\n\t                attr = {\n\t                    fill: \"none\",\n\t                    stroke: attrs.stroke\n\t                };\n\t            } else {\n\t                refX = dx = w / 2;\n\t                attr = {\n\t                    fill: attrs.stroke,\n\t                    stroke: \"none\"\n\t                };\n\t            }\n\t            if (o._.arrows) {\n\t                if (isEnd) {\n\t                    o._.arrows.endPath && markerCounter[o._.arrows.endPath]--;\n\t                    o._.arrows.endMarker && markerCounter[o._.arrows.endMarker]--;\n\t                } else {\n\t                    o._.arrows.startPath && markerCounter[o._.arrows.startPath]--;\n\t                    o._.arrows.startMarker && markerCounter[o._.arrows.startMarker]--;\n\t                }\n\t            } else {\n\t                o._.arrows = {};\n\t            }\n\t            if (type != \"none\") {\n\t                var pathId = \"raphael-marker-\" + type,\n\t                    markerId = \"raphael-marker-\" + se + type + w + h + \"-obj\" + o.id;\n\t                if (!R._g.doc.getElementById(pathId)) {\n\t                    p.defs.appendChild($($(\"path\"), {\n\t                        \"stroke-linecap\": \"round\",\n\t                        d: markers[type],\n\t                        id: pathId\n\t                    }));\n\t                    markerCounter[pathId] = 1;\n\t                } else {\n\t                    markerCounter[pathId]++;\n\t                }\n\t                var marker = R._g.doc.getElementById(markerId),\n\t                    use;\n\t                if (!marker) {\n\t                    marker = $($(\"marker\"), {\n\t                        id: markerId,\n\t                        markerHeight: h,\n\t                        markerWidth: w,\n\t                        orient: \"auto\",\n\t                        refX: refX,\n\t                        refY: h / 2\n\t                    });\n\t                    use = $($(\"use\"), {\n\t                        \"xlink:href\": \"#\" + pathId,\n\t                        transform: (isEnd ? \"rotate(180 \" + w / 2 + \" \" + h / 2 + \") \" : E) + \"scale(\" + w / t + \",\" + h / t + \")\",\n\t                        \"stroke-width\": (1 / ((w / t + h / t) / 2)).toFixed(4)\n\t                    });\n\t                    marker.appendChild(use);\n\t                    p.defs.appendChild(marker);\n\t                    markerCounter[markerId] = 1;\n\t                } else {\n\t                    markerCounter[markerId]++;\n\t                    use = marker.getElementsByTagName(\"use\")[0];\n\t                }\n\t                $(use, attr);\n\t                var delta = dx * (type != \"diamond\" && type != \"oval\");\n\t                if (isEnd) {\n\t                    from = o._.arrows.startdx * stroke || 0;\n\t                    to = R.getTotalLength(attrs.path) - delta * stroke;\n\t                } else {\n\t                    from = delta * stroke;\n\t                    to = R.getTotalLength(attrs.path) - (o._.arrows.enddx * stroke || 0);\n\t                }\n\t                attr = {};\n\t                attr[\"marker-\" + se] = \"url(#\" + markerId + \")\";\n\t                if (to || from) {\n\t                    attr.d = R.getSubpath(attrs.path, from, to);\n\t                }\n\t                $(node, attr);\n\t                o._.arrows[se + \"Path\"] = pathId;\n\t                o._.arrows[se + \"Marker\"] = markerId;\n\t                o._.arrows[se + \"dx\"] = delta;\n\t                o._.arrows[se + \"Type\"] = type;\n\t                o._.arrows[se + \"String\"] = value;\n\t            } else {\n\t                if (isEnd) {\n\t                    from = o._.arrows.startdx * stroke || 0;\n\t                    to = R.getTotalLength(attrs.path) - from;\n\t                } else {\n\t                    from = 0;\n\t                    to = R.getTotalLength(attrs.path) - (o._.arrows.enddx * stroke || 0);\n\t                }\n\t                o._.arrows[se + \"Path\"] && $(node, {d: R.getSubpath(attrs.path, from, to)});\n\t                delete o._.arrows[se + \"Path\"];\n\t                delete o._.arrows[se + \"Marker\"];\n\t                delete o._.arrows[se + \"dx\"];\n\t                delete o._.arrows[se + \"Type\"];\n\t                delete o._.arrows[se + \"String\"];\n\t            }\n\t            for (attr in markerCounter) if (markerCounter[has](attr) && !markerCounter[attr]) {\n\t                var item = R._g.doc.getElementById(attr);\n\t                item && item.parentNode.removeChild(item);\n\t            }\n\t        }\n\t    },\n\t    dasharray = {\n\t        \"-\": [3, 1],\n\t        \".\": [1, 1],\n\t        \"-.\": [3, 1, 1, 1],\n\t        \"-..\": [3, 1, 1, 1, 1, 1],\n\t        \". \": [1, 3],\n\t        \"- \": [4, 3],\n\t        \"--\": [8, 3],\n\t        \"- .\": [4, 3, 1, 3],\n\t        \"--.\": [8, 3, 1, 3],\n\t        \"--..\": [8, 3, 1, 3, 1, 3]\n\t    },\n\t    addDashes = function (o, value, params) {\n\t        value = dasharray[Str(value).toLowerCase()];\n\t        if (value) {\n\t            var width = o.attrs[\"stroke-width\"] || \"1\",\n\t                butt = {round: width, square: width, butt: 0}[o.attrs[\"stroke-linecap\"] || params[\"stroke-linecap\"]] || 0,\n\t                dashes = [],\n\t                i = value.length;\n\t            while (i--) {\n\t                dashes[i] = value[i] * width + ((i % 2) ? 1 : -1) * butt;\n\t            }\n\t            $(o.node, {\"stroke-dasharray\": dashes.join(\",\")});\n\t        }\n\t        else {\n\t          $(o.node, {\"stroke-dasharray\": \"none\"});\n\t        }\n\t    },\n\t    setFillAndStroke = function (o, params) {\n\t        var node = o.node,\n\t            attrs = o.attrs,\n\t            vis = node.style.visibility;\n\t        node.style.visibility = \"hidden\";\n\t        for (var att in params) {\n\t            if (params[has](att)) {\n\t                if (!R._availableAttrs[has](att)) {\n\t                    continue;\n\t                }\n\t                var value = params[att];\n\t                attrs[att] = value;\n\t                switch (att) {\n\t                    case \"blur\":\n\t                        o.blur(value);\n\t                        break;\n\t                    case \"title\":\n\t                        var title = node.getElementsByTagName(\"title\");\n\n\t                        // Use the existing <title>.\n\t                        if (title.length && (title = title[0])) {\n\t                          title.firstChild.nodeValue = value;\n\t                        } else {\n\t                          title = $(\"title\");\n\t                          var val = R._g.doc.createTextNode(value);\n\t                          title.appendChild(val);\n\t                          node.appendChild(title);\n\t                        }\n\t                        break;\n\t                    case \"href\":\n\t                    case \"target\":\n\t                        var pn = node.parentNode;\n\t                        if (pn.tagName.toLowerCase() != \"a\") {\n\t                            var hl = $(\"a\");\n\t                            pn.insertBefore(hl, node);\n\t                            hl.appendChild(node);\n\t                            pn = hl;\n\t                        }\n\t                        if (att == \"target\") {\n\t                            pn.setAttributeNS(xlink, \"show\", value == \"blank\" ? \"new\" : value);\n\t                        } else {\n\t                            pn.setAttributeNS(xlink, att, value);\n\t                        }\n\t                        break;\n\t                    case \"cursor\":\n\t                        node.style.cursor = value;\n\t                        break;\n\t                    case \"transform\":\n\t                        o.transform(value);\n\t                        break;\n\t                    case \"arrow-start\":\n\t                        addArrow(o, value);\n\t                        break;\n\t                    case \"arrow-end\":\n\t                        addArrow(o, value, 1);\n\t                        break;\n\t                    case \"clip-rect\":\n\t                        var rect = Str(value).split(separator);\n\t                        if (rect.length == 4) {\n\t                            o.clip && o.clip.parentNode.parentNode.removeChild(o.clip.parentNode);\n\t                            var el = $(\"clipPath\"),\n\t                                rc = $(\"rect\");\n\t                            el.id = R.createUUID();\n\t                            $(rc, {\n\t                                x: rect[0],\n\t                                y: rect[1],\n\t                                width: rect[2],\n\t                                height: rect[3]\n\t                            });\n\t                            el.appendChild(rc);\n\t                            o.paper.defs.appendChild(el);\n\t                            $(node, {\"clip-path\": \"url(#\" + el.id + \")\"});\n\t                            o.clip = rc;\n\t                        }\n\t                        if (!value) {\n\t                            var path = node.getAttribute(\"clip-path\");\n\t                            if (path) {\n\t                                var clip = R._g.doc.getElementById(path.replace(/(^url\\(#|\\)$)/g, E));\n\t                                clip && clip.parentNode.removeChild(clip);\n\t                                $(node, {\"clip-path\": E});\n\t                                delete o.clip;\n\t                            }\n\t                        }\n\t                    break;\n\t                    case \"path\":\n\t                        if (o.type == \"path\") {\n\t                            $(node, {d: value ? attrs.path = R._pathToAbsolute(value) : \"M0,0\"});\n\t                            o._.dirty = 1;\n\t                            if (o._.arrows) {\n\t                                \"startString\" in o._.arrows && addArrow(o, o._.arrows.startString);\n\t                                \"endString\" in o._.arrows && addArrow(o, o._.arrows.endString, 1);\n\t                            }\n\t                        }\n\t                        break;\n\t                    case \"width\":\n\t                        node.setAttribute(att, value);\n\t                        o._.dirty = 1;\n\t                        if (attrs.fx) {\n\t                            att = \"x\";\n\t                            value = attrs.x;\n\t                        } else {\n\t                            break;\n\t                        }\n\t                    case \"x\":\n\t                        if (attrs.fx) {\n\t                            value = -attrs.x - (attrs.width || 0);\n\t                        }\n\t                    case \"rx\":\n\t                        if (att == \"rx\" && o.type == \"rect\") {\n\t                            break;\n\t                        }\n\t                    case \"cx\":\n\t                        node.setAttribute(att, value);\n\t                        o.pattern && updatePosition(o);\n\t                        o._.dirty = 1;\n\t                        break;\n\t                    case \"height\":\n\t                        node.setAttribute(att, value);\n\t                        o._.dirty = 1;\n\t                        if (attrs.fy) {\n\t                            att = \"y\";\n\t                            value = attrs.y;\n\t                        } else {\n\t                            break;\n\t                        }\n\t                    case \"y\":\n\t                        if (attrs.fy) {\n\t                            value = -attrs.y - (attrs.height || 0);\n\t                        }\n\t                    case \"ry\":\n\t                        if (att == \"ry\" && o.type == \"rect\") {\n\t                            break;\n\t                        }\n\t                    case \"cy\":\n\t                        node.setAttribute(att, value);\n\t                        o.pattern && updatePosition(o);\n\t                        o._.dirty = 1;\n\t                        break;\n\t                    case \"r\":\n\t                        if (o.type == \"rect\") {\n\t                            $(node, {rx: value, ry: value});\n\t                        } else {\n\t                            node.setAttribute(att, value);\n\t                        }\n\t                        o._.dirty = 1;\n\t                        break;\n\t                    case \"src\":\n\t                        if (o.type == \"image\") {\n\t                            node.setAttributeNS(xlink, \"href\", value);\n\t                        }\n\t                        break;\n\t                    case \"stroke-width\":\n\t                        if (o._.sx != 1 || o._.sy != 1) {\n\t                            value /= mmax(abs(o._.sx), abs(o._.sy)) || 1;\n\t                        }\n\t                        node.setAttribute(att, value);\n\t                        if (attrs[\"stroke-dasharray\"]) {\n\t                            addDashes(o, attrs[\"stroke-dasharray\"], params);\n\t                        }\n\t                        if (o._.arrows) {\n\t                            \"startString\" in o._.arrows && addArrow(o, o._.arrows.startString);\n\t                            \"endString\" in o._.arrows && addArrow(o, o._.arrows.endString, 1);\n\t                        }\n\t                        break;\n\t                    case \"stroke-dasharray\":\n\t                        addDashes(o, value, params);\n\t                        break;\n\t                    case \"fill\":\n\t                        var isURL = Str(value).match(R._ISURL);\n\t                        if (isURL) {\n\t                            el = $(\"pattern\");\n\t                            var ig = $(\"image\");\n\t                            el.id = R.createUUID();\n\t                            $(el, {x: 0, y: 0, patternUnits: \"userSpaceOnUse\", height: 1, width: 1});\n\t                            $(ig, {x: 0, y: 0, \"xlink:href\": isURL[1]});\n\t                            el.appendChild(ig);\n\n\t                            (function (el) {\n\t                                R._preload(isURL[1], function () {\n\t                                    var w = this.offsetWidth,\n\t                                        h = this.offsetHeight;\n\t                                    $(el, {width: w, height: h});\n\t                                    $(ig, {width: w, height: h});\n\t                                });\n\t                            })(el);\n\t                            o.paper.defs.appendChild(el);\n\t                            $(node, {fill: \"url(#\" + el.id + \")\"});\n\t                            o.pattern = el;\n\t                            o.pattern && updatePosition(o);\n\t                            break;\n\t                        }\n\t                        var clr = R.getRGB(value);\n\t                        if (!clr.error) {\n\t                            delete params.gradient;\n\t                            delete attrs.gradient;\n\t                            !R.is(attrs.opacity, \"undefined\") &&\n\t                                R.is(params.opacity, \"undefined\") &&\n\t                                $(node, {opacity: attrs.opacity});\n\t                            !R.is(attrs[\"fill-opacity\"], \"undefined\") &&\n\t                                R.is(params[\"fill-opacity\"], \"undefined\") &&\n\t                                $(node, {\"fill-opacity\": attrs[\"fill-opacity\"]});\n\t                        } else if ((o.type == \"circle\" || o.type == \"ellipse\" || Str(value).charAt() != \"r\") && addGradientFill(o, value)) {\n\t                            if (\"opacity\" in attrs || \"fill-opacity\" in attrs) {\n\t                                var gradient = R._g.doc.getElementById(node.getAttribute(\"fill\").replace(/^url\\(#|\\)$/g, E));\n\t                                if (gradient) {\n\t                                    var stops = gradient.getElementsByTagName(\"stop\");\n\t                                    $(stops[stops.length - 1], {\"stop-opacity\": (\"opacity\" in attrs ? attrs.opacity : 1) * (\"fill-opacity\" in attrs ? attrs[\"fill-opacity\"] : 1)});\n\t                                }\n\t                            }\n\t                            attrs.gradient = value;\n\t                            attrs.fill = \"none\";\n\t                            break;\n\t                        }\n\t                        clr[has](\"opacity\") && $(node, {\"fill-opacity\": clr.opacity > 1 ? clr.opacity / 100 : clr.opacity});\n\t                    case \"stroke\":\n\t                        clr = R.getRGB(value);\n\t                        node.setAttribute(att, clr.hex);\n\t                        att == \"stroke\" && clr[has](\"opacity\") && $(node, {\"stroke-opacity\": clr.opacity > 1 ? clr.opacity / 100 : clr.opacity});\n\t                        if (att == \"stroke\" && o._.arrows) {\n\t                            \"startString\" in o._.arrows && addArrow(o, o._.arrows.startString);\n\t                            \"endString\" in o._.arrows && addArrow(o, o._.arrows.endString, 1);\n\t                        }\n\t                        break;\n\t                    case \"gradient\":\n\t                        (o.type == \"circle\" || o.type == \"ellipse\" || Str(value).charAt() != \"r\") && addGradientFill(o, value);\n\t                        break;\n\t                    case \"opacity\":\n\t                        if (attrs.gradient && !attrs[has](\"stroke-opacity\")) {\n\t                            $(node, {\"stroke-opacity\": value > 1 ? value / 100 : value});\n\t                        }\n\t                        // fall\n\t                    case \"fill-opacity\":\n\t                        if (attrs.gradient) {\n\t                            gradient = R._g.doc.getElementById(node.getAttribute(\"fill\").replace(/^url\\(#|\\)$/g, E));\n\t                            if (gradient) {\n\t                                stops = gradient.getElementsByTagName(\"stop\");\n\t                                $(stops[stops.length - 1], {\"stop-opacity\": value});\n\t                            }\n\t                            break;\n\t                        }\n\t                    default:\n\t                        att == \"font-size\" && (value = toInt(value, 10) + \"px\");\n\t                        var cssrule = att.replace(/(\\-.)/g, function (w) {\n\t                            return w.substring(1).toUpperCase();\n\t                        });\n\t                        node.style[cssrule] = value;\n\t                        o._.dirty = 1;\n\t                        node.setAttribute(att, value);\n\t                        break;\n\t                }\n\t            }\n\t        }\n\n\t        tuneText(o, params);\n\t        node.style.visibility = vis;\n\t    },\n\t    leading = 1.2,\n\t    tuneText = function (el, params) {\n\t        if (el.type != \"text\" || !(params[has](\"text\") || params[has](\"font\") || params[has](\"font-size\") || params[has](\"x\") || params[has](\"y\"))) {\n\t            return;\n\t        }\n\t        var a = el.attrs,\n\t            node = el.node,\n\t            fontSize = node.firstChild ? toInt(R._g.doc.defaultView.getComputedStyle(node.firstChild, E).getPropertyValue(\"font-size\"), 10) : 10;\n\n\t        if (params[has](\"text\")) {\n\t            a.text = params.text;\n\t            while (node.firstChild) {\n\t                node.removeChild(node.firstChild);\n\t            }\n\t            var texts = Str(params.text).split(\"\\n\"),\n\t                tspans = [],\n\t                tspan;\n\t            for (var i = 0, ii = texts.length; i < ii; i++) {\n\t                tspan = $(\"tspan\");\n\t                i && $(tspan, {dy: fontSize * leading, x: a.x});\n\t                tspan.appendChild(R._g.doc.createTextNode(texts[i]));\n\t                node.appendChild(tspan);\n\t                tspans[i] = tspan;\n\t            }\n\t        } else {\n\t            tspans = node.getElementsByTagName(\"tspan\");\n\t            for (i = 0, ii = tspans.length; i < ii; i++) if (i) {\n\t                $(tspans[i], {dy: fontSize * leading, x: a.x});\n\t            } else {\n\t                $(tspans[0], {dy: 0});\n\t            }\n\t        }\n\t        $(node, {x: a.x, y: a.y});\n\t        el._.dirty = 1;\n\t        var bb = el._getBBox(),\n\t            dif = a.y - (bb.y + bb.height / 2);\n\t        dif && R.is(dif, \"finite\") && $(tspans[0], {dy: dif});\n\t    },\n\t    getRealNode = function (node) {\n\t        if (node.parentNode && node.parentNode.tagName.toLowerCase() === \"a\") {\n\t            return node.parentNode;\n\t        } else {\n\t            return node;\n\t        }\n\t    },\n\t    Element = function (node, svg) {\n\t        var X = 0,\n\t            Y = 0;\n\t        /*\\\n\t         * Element.node\n\t         [ property (object) ]\n\t         **\n\t         * Gives you a reference to the DOM object, so you can assign event handlers or just mess around.\n\t         **\n\t         * Note: Don’t mess with it.\n\t         > Usage\n\t         | // draw a circle at coordinate 10,10 with radius of 10\n\t         | var c = paper.circle(10, 10, 10);\n\t         | c.node.onclick = function () {\n\t         |     c.attr(\"fill\", \"red\");\n\t         | };\n\t        \\*/\n\t        this[0] = this.node = node;\n\t        /*\\\n\t         * Element.raphael\n\t         [ property (object) ]\n\t         **\n\t         * Internal reference to @Raphael object. In case it is not available.\n\t         > Usage\n\t         | Raphael.el.red = function () {\n\t         |     var hsb = this.paper.raphael.rgb2hsb(this.attr(\"fill\"));\n\t         |     hsb.h = 1;\n\t         |     this.attr({fill: this.paper.raphael.hsb2rgb(hsb).hex});\n\t         | }\n\t        \\*/\n\t        node.raphael = true;\n\t        /*\\\n\t         * Element.id\n\t         [ property (number) ]\n\t         **\n\t         * Unique id of the element. Especially useful when you want to listen to events of the element,\n\t         * because all events are fired in format `<module>.<action>.<id>`. Also useful for @Paper.getById method.\n\t        \\*/\n\t        this.id = R._oid++;\n\t        node.raphaelid = this.id;\n\t        this.matrix = R.matrix();\n\t        this.realPath = null;\n\t        /*\\\n\t         * Element.paper\n\t         [ property (object) ]\n\t         **\n\t         * Internal reference to “paper” where object drawn. Mainly for use in plugins and element extensions.\n\t         > Usage\n\t         | Raphael.el.cross = function () {\n\t         |     this.attr({fill: \"red\"});\n\t         |     this.paper.path(\"M10,10L50,50M50,10L10,50\")\n\t         |         .attr({stroke: \"red\"});\n\t         | }\n\t        \\*/\n\t        this.paper = svg;\n\t        this.attrs = this.attrs || {};\n\t        this._ = {\n\t            transform: [],\n\t            sx: 1,\n\t            sy: 1,\n\t            deg: 0,\n\t            dx: 0,\n\t            dy: 0,\n\t            dirty: 1\n\t        };\n\t        !svg.bottom && (svg.bottom = this);\n\t        /*\\\n\t         * Element.prev\n\t         [ property (object) ]\n\t         **\n\t         * Reference to the previous element in the hierarchy.\n\t        \\*/\n\t        this.prev = svg.top;\n\t        svg.top && (svg.top.next = this);\n\t        svg.top = this;\n\t        /*\\\n\t         * Element.next\n\t         [ property (object) ]\n\t         **\n\t         * Reference to the next element in the hierarchy.\n\t        \\*/\n\t        this.next = null;\n\t    },\n\t    elproto = R.el;\n\n\t    Element.prototype = elproto;\n\t    elproto.constructor = Element;\n\n\t    R._engine.path = function (pathString, SVG) {\n\t        var el = $(\"path\");\n\t        SVG.canvas && SVG.canvas.appendChild(el);\n\t        var p = new Element(el, SVG);\n\t        p.type = \"path\";\n\t        setFillAndStroke(p, {\n\t            fill: \"none\",\n\t            stroke: \"#000\",\n\t            path: pathString\n\t        });\n\t        return p;\n\t    };\n\t    /*\\\n\t     * Element.rotate\n\t     [ method ]\n\t     **\n\t     * Deprecated! Use @Element.transform instead.\n\t     * Adds rotation by given angle around given point to the list of\n\t     * transformations of the element.\n\t     > Parameters\n\t     - deg (number) angle in degrees\n\t     - cx (number) #optional x coordinate of the centre of rotation\n\t     - cy (number) #optional y coordinate of the centre of rotation\n\t     * If cx & cy aren’t specified centre of the shape is used as a point of rotation.\n\t     = (object) @Element\n\t    \\*/\n\t    elproto.rotate = function (deg, cx, cy) {\n\t        if (this.removed) {\n\t            return this;\n\t        }\n\t        deg = Str(deg).split(separator);\n\t        if (deg.length - 1) {\n\t            cx = toFloat(deg[1]);\n\t            cy = toFloat(deg[2]);\n\t        }\n\t        deg = toFloat(deg[0]);\n\t        (cy == null) && (cx = cy);\n\t        if (cx == null || cy == null) {\n\t            var bbox = this.getBBox(1);\n\t            cx = bbox.x + bbox.width / 2;\n\t            cy = bbox.y + bbox.height / 2;\n\t        }\n\t        this.transform(this._.transform.concat([[\"r\", deg, cx, cy]]));\n\t        return this;\n\t    };\n\t    /*\\\n\t     * Element.scale\n\t     [ method ]\n\t     **\n\t     * Deprecated! Use @Element.transform instead.\n\t     * Adds scale by given amount relative to given point to the list of\n\t     * transformations of the element.\n\t     > Parameters\n\t     - sx (number) horisontal scale amount\n\t     - sy (number) vertical scale amount\n\t     - cx (number) #optional x coordinate of the centre of scale\n\t     - cy (number) #optional y coordinate of the centre of scale\n\t     * If cx & cy aren’t specified centre of the shape is used instead.\n\t     = (object) @Element\n\t    \\*/\n\t    elproto.scale = function (sx, sy, cx, cy) {\n\t        if (this.removed) {\n\t            return this;\n\t        }\n\t        sx = Str(sx).split(separator);\n\t        if (sx.length - 1) {\n\t            sy = toFloat(sx[1]);\n\t            cx = toFloat(sx[2]);\n\t            cy = toFloat(sx[3]);\n\t        }\n\t        sx = toFloat(sx[0]);\n\t        (sy == null) && (sy = sx);\n\t        (cy == null) && (cx = cy);\n\t        if (cx == null || cy == null) {\n\t            var bbox = this.getBBox(1);\n\t        }\n\t        cx = cx == null ? bbox.x + bbox.width / 2 : cx;\n\t        cy = cy == null ? bbox.y + bbox.height / 2 : cy;\n\t        this.transform(this._.transform.concat([[\"s\", sx, sy, cx, cy]]));\n\t        return this;\n\t    };\n\t    /*\\\n\t     * Element.translate\n\t     [ method ]\n\t     **\n\t     * Deprecated! Use @Element.transform instead.\n\t     * Adds translation by given amount to the list of transformations of the element.\n\t     > Parameters\n\t     - dx (number) horisontal shift\n\t     - dy (number) vertical shift\n\t     = (object) @Element\n\t    \\*/\n\t    elproto.translate = function (dx, dy) {\n\t        if (this.removed) {\n\t            return this;\n\t        }\n\t        dx = Str(dx).split(separator);\n\t        if (dx.length - 1) {\n\t            dy = toFloat(dx[1]);\n\t        }\n\t        dx = toFloat(dx[0]) || 0;\n\t        dy = +dy || 0;\n\t        this.transform(this._.transform.concat([[\"t\", dx, dy]]));\n\t        return this;\n\t    };\n\t    /*\\\n\t     * Element.transform\n\t     [ method ]\n\t     **\n\t     * Adds transformation to the element which is separate to other attributes,\n\t     * i.e. translation doesn’t change `x` or `y` of the rectange. The format\n\t     * of transformation string is similar to the path string syntax:\n\t     | \"t100,100r30,100,100s2,2,100,100r45s1.5\"\n\t     * Each letter is a command. There are four commands: `t` is for translate, `r` is for rotate, `s` is for\n\t     * scale and `m` is for matrix.\n\t     *\n\t     * There are also alternative “absolute” translation, rotation and scale: `T`, `R` and `S`. They will not take previous transformation into account. For example, `...T100,0` will always move element 100 px horisontally, while `...t100,0` could move it vertically if there is `r90` before. Just compare results of `r90t100,0` and `r90T100,0`.\n\t     *\n\t     * So, the example line above could be read like “translate by 100, 100; rotate 30° around 100, 100; scale twice around 100, 100;\n\t     * rotate 45° around centre; scale 1.5 times relative to centre”. As you can see rotate and scale commands have origin\n\t     * coordinates as optional parameters, the default is the centre point of the element.\n\t     * Matrix accepts six parameters.\n\t     > Usage\n\t     | var el = paper.rect(10, 20, 300, 200);\n\t     | // translate 100, 100, rotate 45°, translate -100, 0\n\t     | el.transform(\"t100,100r45t-100,0\");\n\t     | // if you want you can append or prepend transformations\n\t     | el.transform(\"...t50,50\");\n\t     | el.transform(\"s2...\");\n\t     | // or even wrap\n\t     | el.transform(\"t50,50...t-50-50\");\n\t     | // to reset transformation call method with empty string\n\t     | el.transform(\"\");\n\t     | // to get current value call it without parameters\n\t     | console.log(el.transform());\n\t     > Parameters\n\t     - tstr (string) #optional transformation string\n\t     * If tstr isn’t specified\n\t     = (string) current transformation string\n\t     * else\n\t     = (object) @Element\n\t    \\*/\n\t    elproto.transform = function (tstr) {\n\t        var _ = this._;\n\t        if (tstr == null) {\n\t            return _.transform;\n\t        }\n\t        R._extractTransform(this, tstr);\n\n\t        this.clip && $(this.clip, {transform: this.matrix.invert()});\n\t        this.pattern && updatePosition(this);\n\t        this.node && $(this.node, {transform: this.matrix});\n\n\t        if (_.sx != 1 || _.sy != 1) {\n\t            var sw = this.attrs[has](\"stroke-width\") ? this.attrs[\"stroke-width\"] : 1;\n\t            this.attr({\"stroke-width\": sw});\n\t        }\n\n\t        //Reduce transform string\n\t        _.transform = this.matrix.toTransformString();\n\n\t        return this;\n\t    };\n\t    /*\\\n\t     * Element.hide\n\t     [ method ]\n\t     **\n\t     * Makes element invisible. See @Element.show.\n\t     = (object) @Element\n\t    \\*/\n\t    elproto.hide = function () {\n\t        if(!this.removed) this.node.style.display = \"none\";\n\t        return this;\n\t    };\n\t    /*\\\n\t     * Element.show\n\t     [ method ]\n\t     **\n\t     * Makes element visible. See @Element.hide.\n\t     = (object) @Element\n\t    \\*/\n\t    elproto.show = function () {\n\t        if(!this.removed) this.node.style.display = \"\";\n\t        return this;\n\t    };\n\t    /*\\\n\t     * Element.remove\n\t     [ method ]\n\t     **\n\t     * Removes element from the paper.\n\t    \\*/\n\t    elproto.remove = function () {\n\t        var node = getRealNode(this.node);\n\t        if (this.removed || !node.parentNode) {\n\t            return;\n\t        }\n\t        var paper = this.paper;\n\t        paper.__set__ && paper.__set__.exclude(this);\n\t        eve.unbind(\"raphael.*.*.\" + this.id);\n\t        if (this.gradient) {\n\t            paper.defs.removeChild(this.gradient);\n\t        }\n\t        R._tear(this, paper);\n\n\t        node.parentNode.removeChild(node);\n\n\t        // Remove custom data for element\n\t        this.removeData();\n\n\t        for (var i in this) {\n\t            this[i] = typeof this[i] == \"function\" ? R._removedFactory(i) : null;\n\t        }\n\t        this.removed = true;\n\t    };\n\t    elproto._getBBox = function () {\n\t        if (this.node.style.display == \"none\") {\n\t            this.show();\n\t            var hide = true;\n\t        }\n\t        var canvasHidden = false,\n\t            containerStyle;\n\t        if (this.paper.canvas.parentElement) {\n\t          containerStyle = this.paper.canvas.parentElement.style;\n\t        } //IE10+ can't find parentElement\n\t        else if (this.paper.canvas.parentNode) {\n\t          containerStyle = this.paper.canvas.parentNode.style;\n\t        }\n\n\t        if(containerStyle && containerStyle.display == \"none\") {\n\t          canvasHidden = true;\n\t          containerStyle.display = \"\";\n\t        }\n\t        var bbox = {};\n\t        try {\n\t            bbox = this.node.getBBox();\n\t        } catch(e) {\n\t            // Firefox 3.0.x, 25.0.1 (probably more versions affected) play badly here - possible fix\n\t            bbox = {\n\t                x: this.node.clientLeft,\n\t                y: this.node.clientTop,\n\t                width: this.node.clientWidth,\n\t                height: this.node.clientHeight\n\t            }\n\t        } finally {\n\t            bbox = bbox || {};\n\t            if(canvasHidden){\n\t              containerStyle.display = \"none\";\n\t            }\n\t        }\n\t        hide && this.hide();\n\t        return bbox;\n\t    };\n\t    /*\\\n\t     * Element.attr\n\t     [ method ]\n\t     **\n\t     * Sets the attributes of the element.\n\t     > Parameters\n\t     - attrName (string) attribute’s name\n\t     - value (string) value\n\t     * or\n\t     - params (object) object of name/value pairs\n\t     * or\n\t     - attrName (string) attribute’s name\n\t     * or\n\t     - attrNames (array) in this case method returns array of current values for given attribute names\n\t     = (object) @Element if attrsName & value or params are passed in.\n\t     = (...) value of the attribute if only attrsName is passed in.\n\t     = (array) array of values of the attribute if attrsNames is passed in.\n\t     = (object) object of attributes if nothing is passed in.\n\t     > Possible parameters\n\t     # <p>Please refer to the <a href=\"http://www.w3.org/TR/SVG/\" title=\"The W3C Recommendation for the SVG language describes these properties in detail.\">SVG specification</a> for an explanation of these parameters.</p>\n\t     o arrow-end (string) arrowhead on the end of the path. The format for string is `<type>[-<width>[-<length>]]`. Possible types: `classic`, `block`, `open`, `oval`, `diamond`, `none`, width: `wide`, `narrow`, `medium`, length: `long`, `short`, `midium`.\n\t     o clip-rect (string) comma or space separated values: x, y, width and height\n\t     o cursor (string) CSS type of the cursor\n\t     o cx (number) the x-axis coordinate of the center of the circle, or ellipse\n\t     o cy (number) the y-axis coordinate of the center of the circle, or ellipse\n\t     o fill (string) colour, gradient or image\n\t     o fill-opacity (number)\n\t     o font (string)\n\t     o font-family (string)\n\t     o font-size (number) font size in pixels\n\t     o font-weight (string)\n\t     o height (number)\n\t     o href (string) URL, if specified element behaves as hyperlink\n\t     o opacity (number)\n\t     o path (string) SVG path string format\n\t     o r (number) radius of the circle, ellipse or rounded corner on the rect\n\t     o rx (number) horisontal radius of the ellipse\n\t     o ry (number) vertical radius of the ellipse\n\t     o src (string) image URL, only works for @Element.image element\n\t     o stroke (string) stroke colour\n\t     o stroke-dasharray (string) [“”, “none”, “`-`”, “`.`”, “`-.`”, “`-..`”, “`. `”, “`- `”, “`--`”, “`- .`”, “`--.`”, “`--..`”]\n\t     o stroke-linecap (string) [“`butt`”, “`square`”, “`round`”]\n\t     o stroke-linejoin (string) [“`bevel`”, “`round`”, “`miter`”]\n\t     o stroke-miterlimit (number)\n\t     o stroke-opacity (number)\n\t     o stroke-width (number) stroke width in pixels, default is '1'\n\t     o target (string) used with href\n\t     o text (string) contents of the text element. Use `\\n` for multiline text\n\t     o text-anchor (string) [“`start`”, “`middle`”, “`end`”], default is “`middle`”\n\t     o title (string) will create tooltip with a given text\n\t     o transform (string) see @Element.transform\n\t     o width (number)\n\t     o x (number)\n\t     o y (number)\n\t     > Gradients\n\t     * Linear gradient format: “`‹angle›-‹colour›[-‹colour›[:‹offset›]]*-‹colour›`”, example: “`90-#fff-#000`” – 90°\n\t     * gradient from white to black or “`0-#fff-#f00:20-#000`” – 0° gradient from white via red (at 20%) to black.\n\t     *\n\t     * radial gradient: “`r[(‹fx›, ‹fy›)]‹colour›[-‹colour›[:‹offset›]]*-‹colour›`”, example: “`r#fff-#000`” –\n\t     * gradient from white to black or “`r(0.25, 0.75)#fff-#000`” – gradient from white to black with focus point\n\t     * at 0.25, 0.75. Focus point coordinates are in 0..1 range. Radial gradients can only be applied to circles and ellipses.\n\t     > Path String\n\t     # <p>Please refer to <a href=\"http://www.w3.org/TR/SVG/paths.html#PathData\" title=\"Details of a path’s data attribute’s format are described in the SVG specification.\">SVG documentation regarding path string</a>. Raphaël fully supports it.</p>\n\t     > Colour Parsing\n\t     # <ul>\n\t     #     <li>Colour name (“<code>red</code>”, “<code>green</code>”, “<code>cornflowerblue</code>”, etc)</li>\n\t     #     <li>#••• — shortened HTML colour: (“<code>#000</code>”, “<code>#fc0</code>”, etc)</li>\n\t     #     <li>#•••••• — full length HTML colour: (“<code>#000000</code>”, “<code>#bd2300</code>”)</li>\n\t     #     <li>rgb(•••, •••, •••) — red, green and blue channels’ values: (“<code>rgb(200,&nbsp;100,&nbsp;0)</code>”)</li>\n\t     #     <li>rgb(•••%, •••%, •••%) — same as above, but in %: (“<code>rgb(100%,&nbsp;175%,&nbsp;0%)</code>”)</li>\n\t     #     <li>rgba(•••, •••, •••, •••) — red, green and blue channels’ values: (“<code>rgba(200,&nbsp;100,&nbsp;0, .5)</code>”)</li>\n\t     #     <li>rgba(•••%, •••%, •••%, •••%) — same as above, but in %: (“<code>rgba(100%,&nbsp;175%,&nbsp;0%, 50%)</code>”)</li>\n\t     #     <li>hsb(•••, •••, •••) — hue, saturation and brightness values: (“<code>hsb(0.5,&nbsp;0.25,&nbsp;1)</code>”)</li>\n\t     #     <li>hsb(•••%, •••%, •••%) — same as above, but in %</li>\n\t     #     <li>hsba(•••, •••, •••, •••) — same as above, but with opacity</li>\n\t     #     <li>hsl(•••, •••, •••) — almost the same as hsb, see <a href=\"http://en.wikipedia.org/wiki/HSL_and_HSV\" title=\"HSL and HSV - Wikipedia, the free encyclopedia\">Wikipedia page</a></li>\n\t     #     <li>hsl(•••%, •••%, •••%) — same as above, but in %</li>\n\t     #     <li>hsla(•••, •••, •••, •••) — same as above, but with opacity</li>\n\t     #     <li>Optionally for hsb and hsl you could specify hue as a degree: “<code>hsl(240deg,&nbsp;1,&nbsp;.5)</code>” or, if you want to go fancy, “<code>hsl(240°,&nbsp;1,&nbsp;.5)</code>”</li>\n\t     # </ul>\n\t    \\*/\n\t    elproto.attr = function (name, value) {\n\t        if (this.removed) {\n\t            return this;\n\t        }\n\t        if (name == null) {\n\t            var res = {};\n\t            for (var a in this.attrs) if (this.attrs[has](a)) {\n\t                res[a] = this.attrs[a];\n\t            }\n\t            res.gradient && res.fill == \"none\" && (res.fill = res.gradient) && delete res.gradient;\n\t            res.transform = this._.transform;\n\t            return res;\n\t        }\n\t        if (value == null && R.is(name, \"string\")) {\n\t            if (name == \"fill\" && this.attrs.fill == \"none\" && this.attrs.gradient) {\n\t                return this.attrs.gradient;\n\t            }\n\t            if (name == \"transform\") {\n\t                return this._.transform;\n\t            }\n\t            var names = name.split(separator),\n\t                out = {};\n\t            for (var i = 0, ii = names.length; i < ii; i++) {\n\t                name = names[i];\n\t                if (name in this.attrs) {\n\t                    out[name] = this.attrs[name];\n\t                } else if (R.is(this.paper.customAttributes[name], \"function\")) {\n\t                    out[name] = this.paper.customAttributes[name].def;\n\t                } else {\n\t                    out[name] = R._availableAttrs[name];\n\t                }\n\t            }\n\t            return ii - 1 ? out : out[names[0]];\n\t        }\n\t        if (value == null && R.is(name, \"array\")) {\n\t            out = {};\n\t            for (i = 0, ii = name.length; i < ii; i++) {\n\t                out[name[i]] = this.attr(name[i]);\n\t            }\n\t            return out;\n\t        }\n\t        if (value != null) {\n\t            var params = {};\n\t            params[name] = value;\n\t        } else if (name != null && R.is(name, \"object\")) {\n\t            params = name;\n\t        }\n\t        for (var key in params) {\n\t            eve(\"raphael.attr.\" + key + \".\" + this.id, this, params[key]);\n\t        }\n\t        for (key in this.paper.customAttributes) if (this.paper.customAttributes[has](key) && params[has](key) && R.is(this.paper.customAttributes[key], \"function\")) {\n\t            var par = this.paper.customAttributes[key].apply(this, [].concat(params[key]));\n\t            this.attrs[key] = params[key];\n\t            for (var subkey in par) if (par[has](subkey)) {\n\t                params[subkey] = par[subkey];\n\t            }\n\t        }\n\t        setFillAndStroke(this, params);\n\t        return this;\n\t    };\n\t    /*\\\n\t     * Element.toFront\n\t     [ method ]\n\t     **\n\t     * Moves the element so it is the closest to the viewer’s eyes, on top of other elements.\n\t     = (object) @Element\n\t    \\*/\n\t    elproto.toFront = function () {\n\t        if (this.removed) {\n\t            return this;\n\t        }\n\t        var node = getRealNode(this.node);\n\t        node.parentNode.appendChild(node);\n\t        var svg = this.paper;\n\t        svg.top != this && R._tofront(this, svg);\n\t        return this;\n\t    };\n\t    /*\\\n\t     * Element.toBack\n\t     [ method ]\n\t     **\n\t     * Moves the element so it is the furthest from the viewer’s eyes, behind other elements.\n\t     = (object) @Element\n\t    \\*/\n\t    elproto.toBack = function () {\n\t        if (this.removed) {\n\t            return this;\n\t        }\n\t        var node = getRealNode(this.node);\n\t        var parentNode = node.parentNode;\n\t        parentNode.insertBefore(node, parentNode.firstChild);\n\t        R._toback(this, this.paper);\n\t        var svg = this.paper;\n\t        return this;\n\t    };\n\t    /*\\\n\t     * Element.insertAfter\n\t     [ method ]\n\t     **\n\t     * Inserts current object after the given one.\n\t     = (object) @Element\n\t    \\*/\n\t    elproto.insertAfter = function (element) {\n\t        if (this.removed || !element) {\n\t            return this;\n\t        }\n\n\t        var node = getRealNode(this.node);\n\t        var afterNode = getRealNode(element.node || element[element.length - 1].node);\n\t        if (afterNode.nextSibling) {\n\t            afterNode.parentNode.insertBefore(node, afterNode.nextSibling);\n\t        } else {\n\t            afterNode.parentNode.appendChild(node);\n\t        }\n\t        R._insertafter(this, element, this.paper);\n\t        return this;\n\t    };\n\t    /*\\\n\t     * Element.insertBefore\n\t     [ method ]\n\t     **\n\t     * Inserts current object before the given one.\n\t     = (object) @Element\n\t    \\*/\n\t    elproto.insertBefore = function (element) {\n\t        if (this.removed || !element) {\n\t            return this;\n\t        }\n\n\t        var node = getRealNode(this.node);\n\t        var beforeNode = getRealNode(element.node || element[0].node);\n\t        beforeNode.parentNode.insertBefore(node, beforeNode);\n\t        R._insertbefore(this, element, this.paper);\n\t        return this;\n\t    };\n\t    elproto.blur = function (size) {\n\t        // Experimental. No Safari support. Use it on your own risk.\n\t        var t = this;\n\t        if (+size !== 0) {\n\t            var fltr = $(\"filter\"),\n\t                blur = $(\"feGaussianBlur\");\n\t            t.attrs.blur = size;\n\t            fltr.id = R.createUUID();\n\t            $(blur, {stdDeviation: +size || 1.5});\n\t            fltr.appendChild(blur);\n\t            t.paper.defs.appendChild(fltr);\n\t            t._blur = fltr;\n\t            $(t.node, {filter: \"url(#\" + fltr.id + \")\"});\n\t        } else {\n\t            if (t._blur) {\n\t                t._blur.parentNode.removeChild(t._blur);\n\t                delete t._blur;\n\t                delete t.attrs.blur;\n\t            }\n\t            t.node.removeAttribute(\"filter\");\n\t        }\n\t        return t;\n\t    };\n\t    R._engine.circle = function (svg, x, y, r) {\n\t        var el = $(\"circle\");\n\t        svg.canvas && svg.canvas.appendChild(el);\n\t        var res = new Element(el, svg);\n\t        res.attrs = {cx: x, cy: y, r: r, fill: \"none\", stroke: \"#000\"};\n\t        res.type = \"circle\";\n\t        $(el, res.attrs);\n\t        return res;\n\t    };\n\t    R._engine.rect = function (svg, x, y, w, h, r) {\n\t        var el = $(\"rect\");\n\t        svg.canvas && svg.canvas.appendChild(el);\n\t        var res = new Element(el, svg);\n\t        res.attrs = {x: x, y: y, width: w, height: h, rx: r || 0, ry: r || 0, fill: \"none\", stroke: \"#000\"};\n\t        res.type = \"rect\";\n\t        $(el, res.attrs);\n\t        return res;\n\t    };\n\t    R._engine.ellipse = function (svg, x, y, rx, ry) {\n\t        var el = $(\"ellipse\");\n\t        svg.canvas && svg.canvas.appendChild(el);\n\t        var res = new Element(el, svg);\n\t        res.attrs = {cx: x, cy: y, rx: rx, ry: ry, fill: \"none\", stroke: \"#000\"};\n\t        res.type = \"ellipse\";\n\t        $(el, res.attrs);\n\t        return res;\n\t    };\n\t    R._engine.image = function (svg, src, x, y, w, h) {\n\t        var el = $(\"image\");\n\t        $(el, {x: x, y: y, width: w, height: h, preserveAspectRatio: \"none\"});\n\t        el.setAttributeNS(xlink, \"href\", src);\n\t        svg.canvas && svg.canvas.appendChild(el);\n\t        var res = new Element(el, svg);\n\t        res.attrs = {x: x, y: y, width: w, height: h, src: src};\n\t        res.type = \"image\";\n\t        return res;\n\t    };\n\t    R._engine.text = function (svg, x, y, text) {\n\t        var el = $(\"text\");\n\t        svg.canvas && svg.canvas.appendChild(el);\n\t        var res = new Element(el, svg);\n\t        res.attrs = {\n\t            x: x,\n\t            y: y,\n\t            \"text-anchor\": \"middle\",\n\t            text: text,\n\t            \"font-family\": R._availableAttrs[\"font-family\"],\n\t            \"font-size\": R._availableAttrs[\"font-size\"],\n\t            stroke: \"none\",\n\t            fill: \"#000\"\n\t        };\n\t        res.type = \"text\";\n\t        setFillAndStroke(res, res.attrs);\n\t        return res;\n\t    };\n\t    R._engine.setSize = function (width, height) {\n\t        this.width = width || this.width;\n\t        this.height = height || this.height;\n\t        this.canvas.setAttribute(\"width\", this.width);\n\t        this.canvas.setAttribute(\"height\", this.height);\n\t        if (this._viewBox) {\n\t            this.setViewBox.apply(this, this._viewBox);\n\t        }\n\t        return this;\n\t    };\n\t    R._engine.create = function () {\n\t        var con = R._getContainer.apply(0, arguments),\n\t            container = con && con.container,\n\t            x = con.x,\n\t            y = con.y,\n\t            width = con.width,\n\t            height = con.height;\n\t        if (!container) {\n\t            throw new Error(\"SVG container not found.\");\n\t        }\n\t        var cnvs = $(\"svg\"),\n\t            css = \"overflow:hidden;\",\n\t            isFloating;\n\t        x = x || 0;\n\t        y = y || 0;\n\t        width = width || 512;\n\t        height = height || 342;\n\t        $(cnvs, {\n\t            height: height,\n\t            version: 1.1,\n\t            width: width,\n\t            xmlns: \"http://www.w3.org/2000/svg\",\n\t            \"xmlns:xlink\": \"http://www.w3.org/1999/xlink\"\n\t        });\n\t        if (container == 1) {\n\t            cnvs.style.cssText = css + \"position:absolute;left:\" + x + \"px;top:\" + y + \"px\";\n\t            R._g.doc.body.appendChild(cnvs);\n\t            isFloating = 1;\n\t        } else {\n\t            cnvs.style.cssText = css + \"position:relative\";\n\t            if (container.firstChild) {\n\t                container.insertBefore(cnvs, container.firstChild);\n\t            } else {\n\t                container.appendChild(cnvs);\n\t            }\n\t        }\n\t        container = new R._Paper;\n\t        container.width = width;\n\t        container.height = height;\n\t        container.canvas = cnvs;\n\t        container.clear();\n\t        container._left = container._top = 0;\n\t        isFloating && (container.renderfix = function () {});\n\t        container.renderfix();\n\t        return container;\n\t    };\n\t    R._engine.setViewBox = function (x, y, w, h, fit) {\n\t        eve(\"raphael.setViewBox\", this, this._viewBox, [x, y, w, h, fit]);\n\t        var paperSize = this.getSize(),\n\t            size = mmax(w / paperSize.width, h / paperSize.height),\n\t            top = this.top,\n\t            aspectRatio = fit ? \"xMidYMid meet\" : \"xMinYMin\",\n\t            vb,\n\t            sw;\n\t        if (x == null) {\n\t            if (this._vbSize) {\n\t                size = 1;\n\t            }\n\t            delete this._vbSize;\n\t            vb = \"0 0 \" + this.width + S + this.height;\n\t        } else {\n\t            this._vbSize = size;\n\t            vb = x + S + y + S + w + S + h;\n\t        }\n\t        $(this.canvas, {\n\t            viewBox: vb,\n\t            preserveAspectRatio: aspectRatio\n\t        });\n\t        while (size && top) {\n\t            sw = \"stroke-width\" in top.attrs ? top.attrs[\"stroke-width\"] : 1;\n\t            top.attr({\"stroke-width\": sw});\n\t            top._.dirty = 1;\n\t            top._.dirtyT = 1;\n\t            top = top.prev;\n\t        }\n\t        this._viewBox = [x, y, w, h, !!fit];\n\t        return this;\n\t    };\n\t    /*\\\n\t     * Paper.renderfix\n\t     [ method ]\n\t     **\n\t     * Fixes the issue of Firefox and IE9 regarding subpixel rendering. If paper is dependent\n\t     * on other elements after reflow it could shift half pixel which cause for lines to lost their crispness.\n\t     * This method fixes the issue.\n\t     **\n\t       Special thanks to Mariusz Nowak (http://www.medikoo.com/) for this method.\n\t    \\*/\n\t    R.prototype.renderfix = function () {\n\t        var cnvs = this.canvas,\n\t            s = cnvs.style,\n\t            pos;\n\t        try {\n\t            pos = cnvs.getScreenCTM() || cnvs.createSVGMatrix();\n\t        } catch (e) {\n\t            pos = cnvs.createSVGMatrix();\n\t        }\n\t        var left = -pos.e % 1,\n\t            top = -pos.f % 1;\n\t        if (left || top) {\n\t            if (left) {\n\t                this._left = (this._left + left) % 1;\n\t                s.left = this._left + \"px\";\n\t            }\n\t            if (top) {\n\t                this._top = (this._top + top) % 1;\n\t                s.top = this._top + \"px\";\n\t            }\n\t        }\n\t    };\n\t    /*\\\n\t     * Paper.clear\n\t     [ method ]\n\t     **\n\t     * Clears the paper, i.e. removes all the elements.\n\t    \\*/\n\t    R.prototype.clear = function () {\n\t        R.eve(\"raphael.clear\", this);\n\t        var c = this.canvas;\n\t        while (c.firstChild) {\n\t            c.removeChild(c.firstChild);\n\t        }\n\t        this.bottom = this.top = null;\n\t        (this.desc = $(\"desc\")).appendChild(R._g.doc.createTextNode(\"Created with Rapha\\xebl \" + R.version));\n\t        c.appendChild(this.desc);\n\t        c.appendChild(this.defs = $(\"defs\"));\n\t    };\n\t    /*\\\n\t     * Paper.remove\n\t     [ method ]\n\t     **\n\t     * Removes the paper from the DOM.\n\t    \\*/\n\t    R.prototype.remove = function () {\n\t        eve(\"raphael.remove\", this);\n\t        this.canvas.parentNode && this.canvas.parentNode.removeChild(this.canvas);\n\t        for (var i in this) {\n\t            this[i] = typeof this[i] == \"function\" ? R._removedFactory(i) : null;\n\t        }\n\t    };\n\t    var setproto = R.st;\n\t    for (var method in elproto) if (elproto[has](method) && !setproto[has](method)) {\n\t        setproto[method] = (function (methodname) {\n\t            return function () {\n\t                var arg = arguments;\n\t                return this.forEach(function (el) {\n\t                    el[methodname].apply(el, arg);\n\t                });\n\t            };\n\t        })(method);\n\t    }\n\t}.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));\n\n\n/***/ },\n/* 4 */\n/***/ function(module, exports, __webpack_require__) {\n\n\tvar __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;!(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(1)], __WEBPACK_AMD_DEFINE_RESULT__ = function(R) {\n\t    if (R && !R.vml) {\n\t        return;\n\t    }\n\n\t    var has = \"hasOwnProperty\",\n\t        Str = String,\n\t        toFloat = parseFloat,\n\t        math = Math,\n\t        round = math.round,\n\t        mmax = math.max,\n\t        mmin = math.min,\n\t        abs = math.abs,\n\t        fillString = \"fill\",\n\t        separator = /[, ]+/,\n\t        eve = R.eve,\n\t        ms = \" progid:DXImageTransform.Microsoft\",\n\t        S = \" \",\n\t        E = \"\",\n\t        map = {M: \"m\", L: \"l\", C: \"c\", Z: \"x\", m: \"t\", l: \"r\", c: \"v\", z: \"x\"},\n\t        bites = /([clmz]),?([^clmz]*)/gi,\n\t        blurregexp = / progid:\\S+Blur\\([^\\)]+\\)/g,\n\t        val = /-?[^,\\s-]+/g,\n\t        cssDot = \"position:absolute;left:0;top:0;width:1px;height:1px;behavior:url(#default#VML)\",\n\t        zoom = 21600,\n\t        pathTypes = {path: 1, rect: 1, image: 1},\n\t        ovalTypes = {circle: 1, ellipse: 1},\n\t        path2vml = function (path) {\n\t            var total =  /[ahqstv]/ig,\n\t                command = R._pathToAbsolute;\n\t            Str(path).match(total) && (command = R._path2curve);\n\t            total = /[clmz]/g;\n\t            if (command == R._pathToAbsolute && !Str(path).match(total)) {\n\t                var res = Str(path).replace(bites, function (all, command, args) {\n\t                    var vals = [],\n\t                        isMove = command.toLowerCase() == \"m\",\n\t                        res = map[command];\n\t                    args.replace(val, function (value) {\n\t                        if (isMove && vals.length == 2) {\n\t                            res += vals + map[command == \"m\" ? \"l\" : \"L\"];\n\t                            vals = [];\n\t                        }\n\t                        vals.push(round(value * zoom));\n\t                    });\n\t                    return res + vals;\n\t                });\n\t                return res;\n\t            }\n\t            var pa = command(path), p, r;\n\t            res = [];\n\t            for (var i = 0, ii = pa.length; i < ii; i++) {\n\t                p = pa[i];\n\t                r = pa[i][0].toLowerCase();\n\t                r == \"z\" && (r = \"x\");\n\t                for (var j = 1, jj = p.length; j < jj; j++) {\n\t                    r += round(p[j] * zoom) + (j != jj - 1 ? \",\" : E);\n\t                }\n\t                res.push(r);\n\t            }\n\t            return res.join(S);\n\t        },\n\t        compensation = function (deg, dx, dy) {\n\t            var m = R.matrix();\n\t            m.rotate(-deg, .5, .5);\n\t            return {\n\t                dx: m.x(dx, dy),\n\t                dy: m.y(dx, dy)\n\t            };\n\t        },\n\t        setCoords = function (p, sx, sy, dx, dy, deg) {\n\t            var _ = p._,\n\t                m = p.matrix,\n\t                fillpos = _.fillpos,\n\t                o = p.node,\n\t                s = o.style,\n\t                y = 1,\n\t                flip = \"\",\n\t                dxdy,\n\t                kx = zoom / sx,\n\t                ky = zoom / sy;\n\t            s.visibility = \"hidden\";\n\t            if (!sx || !sy) {\n\t                return;\n\t            }\n\t            o.coordsize = abs(kx) + S + abs(ky);\n\t            s.rotation = deg * (sx * sy < 0 ? -1 : 1);\n\t            if (deg) {\n\t                var c = compensation(deg, dx, dy);\n\t                dx = c.dx;\n\t                dy = c.dy;\n\t            }\n\t            sx < 0 && (flip += \"x\");\n\t            sy < 0 && (flip += \" y\") && (y = -1);\n\t            s.flip = flip;\n\t            o.coordorigin = (dx * -kx) + S + (dy * -ky);\n\t            if (fillpos || _.fillsize) {\n\t                var fill = o.getElementsByTagName(fillString);\n\t                fill = fill && fill[0];\n\t                o.removeChild(fill);\n\t                if (fillpos) {\n\t                    c = compensation(deg, m.x(fillpos[0], fillpos[1]), m.y(fillpos[0], fillpos[1]));\n\t                    fill.position = c.dx * y + S + c.dy * y;\n\t                }\n\t                if (_.fillsize) {\n\t                    fill.size = _.fillsize[0] * abs(sx) + S + _.fillsize[1] * abs(sy);\n\t                }\n\t                o.appendChild(fill);\n\t            }\n\t            s.visibility = \"visible\";\n\t        };\n\t    R.toString = function () {\n\t        return  \"Your browser doesn\\u2019t support SVG. Falling down to VML.\\nYou are running Rapha\\xebl \" + this.version;\n\t    };\n\t    var addArrow = function (o, value, isEnd) {\n\t        var values = Str(value).toLowerCase().split(\"-\"),\n\t            se = isEnd ? \"end\" : \"start\",\n\t            i = values.length,\n\t            type = \"classic\",\n\t            w = \"medium\",\n\t            h = \"medium\";\n\t        while (i--) {\n\t            switch (values[i]) {\n\t                case \"block\":\n\t                case \"classic\":\n\t                case \"oval\":\n\t                case \"diamond\":\n\t                case \"open\":\n\t                case \"none\":\n\t                    type = values[i];\n\t                    break;\n\t                case \"wide\":\n\t                case \"narrow\": h = values[i]; break;\n\t                case \"long\":\n\t                case \"short\": w = values[i]; break;\n\t            }\n\t        }\n\t        var stroke = o.node.getElementsByTagName(\"stroke\")[0];\n\t        stroke[se + \"arrow\"] = type;\n\t        stroke[se + \"arrowlength\"] = w;\n\t        stroke[se + \"arrowwidth\"] = h;\n\t    },\n\t    setFillAndStroke = function (o, params) {\n\t        // o.paper.canvas.style.display = \"none\";\n\t        o.attrs = o.attrs || {};\n\t        var node = o.node,\n\t            a = o.attrs,\n\t            s = node.style,\n\t            xy,\n\t            newpath = pathTypes[o.type] && (params.x != a.x || params.y != a.y || params.width != a.width || params.height != a.height || params.cx != a.cx || params.cy != a.cy || params.rx != a.rx || params.ry != a.ry || params.r != a.r),\n\t            isOval = ovalTypes[o.type] && (a.cx != params.cx || a.cy != params.cy || a.r != params.r || a.rx != params.rx || a.ry != params.ry),\n\t            res = o;\n\n\n\t        for (var par in params) if (params[has](par)) {\n\t            a[par] = params[par];\n\t        }\n\t        if (newpath) {\n\t            a.path = R._getPath[o.type](o);\n\t            o._.dirty = 1;\n\t        }\n\t        params.href && (node.href = params.href);\n\t        params.title && (node.title = params.title);\n\t        params.target && (node.target = params.target);\n\t        params.cursor && (s.cursor = params.cursor);\n\t        \"blur\" in params && o.blur(params.blur);\n\t        if (params.path && o.type == \"path\" || newpath) {\n\t            node.path = path2vml(~Str(a.path).toLowerCase().indexOf(\"r\") ? R._pathToAbsolute(a.path) : a.path);\n\t            o._.dirty = 1;\n\t            if (o.type == \"image\") {\n\t                o._.fillpos = [a.x, a.y];\n\t                o._.fillsize = [a.width, a.height];\n\t                setCoords(o, 1, 1, 0, 0, 0);\n\t            }\n\t        }\n\t        \"transform\" in params && o.transform(params.transform);\n\t        if (isOval) {\n\t            var cx = +a.cx,\n\t                cy = +a.cy,\n\t                rx = +a.rx || +a.r || 0,\n\t                ry = +a.ry || +a.r || 0;\n\t            node.path = R.format(\"ar{0},{1},{2},{3},{4},{1},{4},{1}x\", round((cx - rx) * zoom), round((cy - ry) * zoom), round((cx + rx) * zoom), round((cy + ry) * zoom), round(cx * zoom));\n\t            o._.dirty = 1;\n\t        }\n\t        if (\"clip-rect\" in params) {\n\t            var rect = Str(params[\"clip-rect\"]).split(separator);\n\t            if (rect.length == 4) {\n\t                rect[2] = +rect[2] + (+rect[0]);\n\t                rect[3] = +rect[3] + (+rect[1]);\n\t                var div = node.clipRect || R._g.doc.createElement(\"div\"),\n\t                    dstyle = div.style;\n\t                dstyle.clip = R.format(\"rect({1}px {2}px {3}px {0}px)\", rect);\n\t                if (!node.clipRect) {\n\t                    dstyle.position = \"absolute\";\n\t                    dstyle.top = 0;\n\t                    dstyle.left = 0;\n\t                    dstyle.width = o.paper.width + \"px\";\n\t                    dstyle.height = o.paper.height + \"px\";\n\t                    node.parentNode.insertBefore(div, node);\n\t                    div.appendChild(node);\n\t                    node.clipRect = div;\n\t                }\n\t            }\n\t            if (!params[\"clip-rect\"]) {\n\t                node.clipRect && (node.clipRect.style.clip = \"auto\");\n\t            }\n\t        }\n\t        if (o.textpath) {\n\t            var textpathStyle = o.textpath.style;\n\t            params.font && (textpathStyle.font = params.font);\n\t            params[\"font-family\"] && (textpathStyle.fontFamily = '\"' + params[\"font-family\"].split(\",\")[0].replace(/^['\"]+|['\"]+$/g, E) + '\"');\n\t            params[\"font-size\"] && (textpathStyle.fontSize = params[\"font-size\"]);\n\t            params[\"font-weight\"] && (textpathStyle.fontWeight = params[\"font-weight\"]);\n\t            params[\"font-style\"] && (textpathStyle.fontStyle = params[\"font-style\"]);\n\t        }\n\t        if (\"arrow-start\" in params) {\n\t            addArrow(res, params[\"arrow-start\"]);\n\t        }\n\t        if (\"arrow-end\" in params) {\n\t            addArrow(res, params[\"arrow-end\"], 1);\n\t        }\n\t        if (params.opacity != null ||\n\t            params.fill != null ||\n\t            params.src != null ||\n\t            params.stroke != null ||\n\t            params[\"stroke-width\"] != null ||\n\t            params[\"stroke-opacity\"] != null ||\n\t            params[\"fill-opacity\"] != null ||\n\t            params[\"stroke-dasharray\"] != null ||\n\t            params[\"stroke-miterlimit\"] != null ||\n\t            params[\"stroke-linejoin\"] != null ||\n\t            params[\"stroke-linecap\"] != null) {\n\t            var fill = node.getElementsByTagName(fillString),\n\t                newfill = false;\n\t            fill = fill && fill[0];\n\t            !fill && (newfill = fill = createNode(fillString));\n\t            if (o.type == \"image\" && params.src) {\n\t                fill.src = params.src;\n\t            }\n\t            params.fill && (fill.on = true);\n\t            if (fill.on == null || params.fill == \"none\" || params.fill === null) {\n\t                fill.on = false;\n\t            }\n\t            if (fill.on && params.fill) {\n\t                var isURL = Str(params.fill).match(R._ISURL);\n\t                if (isURL) {\n\t                    fill.parentNode == node && node.removeChild(fill);\n\t                    fill.rotate = true;\n\t                    fill.src = isURL[1];\n\t                    fill.type = \"tile\";\n\t                    var bbox = o.getBBox(1);\n\t                    fill.position = bbox.x + S + bbox.y;\n\t                    o._.fillpos = [bbox.x, bbox.y];\n\n\t                    R._preload(isURL[1], function () {\n\t                        o._.fillsize = [this.offsetWidth, this.offsetHeight];\n\t                    });\n\t                } else {\n\t                    fill.color = R.getRGB(params.fill).hex;\n\t                    fill.src = E;\n\t                    fill.type = \"solid\";\n\t                    if (R.getRGB(params.fill).error && (res.type in {circle: 1, ellipse: 1} || Str(params.fill).charAt() != \"r\") && addGradientFill(res, params.fill, fill)) {\n\t                        a.fill = \"none\";\n\t                        a.gradient = params.fill;\n\t                        fill.rotate = false;\n\t                    }\n\t                }\n\t            }\n\t            if (\"fill-opacity\" in params || \"opacity\" in params) {\n\t                var opacity = ((+a[\"fill-opacity\"] + 1 || 2) - 1) * ((+a.opacity + 1 || 2) - 1) * ((+R.getRGB(params.fill).o + 1 || 2) - 1);\n\t                opacity = mmin(mmax(opacity, 0), 1);\n\t                fill.opacity = opacity;\n\t                if (fill.src) {\n\t                    fill.color = \"none\";\n\t                }\n\t            }\n\t            node.appendChild(fill);\n\t            var stroke = (node.getElementsByTagName(\"stroke\") && node.getElementsByTagName(\"stroke\")[0]),\n\t            newstroke = false;\n\t            !stroke && (newstroke = stroke = createNode(\"stroke\"));\n\t            if ((params.stroke && params.stroke != \"none\") ||\n\t                params[\"stroke-width\"] ||\n\t                params[\"stroke-opacity\"] != null ||\n\t                params[\"stroke-dasharray\"] ||\n\t                params[\"stroke-miterlimit\"] ||\n\t                params[\"stroke-linejoin\"] ||\n\t                params[\"stroke-linecap\"]) {\n\t                stroke.on = true;\n\t            }\n\t            (params.stroke == \"none\" || params.stroke === null || stroke.on == null || params.stroke == 0 || params[\"stroke-width\"] == 0) && (stroke.on = false);\n\t            var strokeColor = R.getRGB(params.stroke);\n\t            stroke.on && params.stroke && (stroke.color = strokeColor.hex);\n\t            opacity = ((+a[\"stroke-opacity\"] + 1 || 2) - 1) * ((+a.opacity + 1 || 2) - 1) * ((+strokeColor.o + 1 || 2) - 1);\n\t            var width = (toFloat(params[\"stroke-width\"]) || 1) * .75;\n\t            opacity = mmin(mmax(opacity, 0), 1);\n\t            params[\"stroke-width\"] == null && (width = a[\"stroke-width\"]);\n\t            params[\"stroke-width\"] && (stroke.weight = width);\n\t            width && width < 1 && (opacity *= width) && (stroke.weight = 1);\n\t            stroke.opacity = opacity;\n\n\t            params[\"stroke-linejoin\"] && (stroke.joinstyle = params[\"stroke-linejoin\"] || \"miter\");\n\t            stroke.miterlimit = params[\"stroke-miterlimit\"] || 8;\n\t            params[\"stroke-linecap\"] && (stroke.endcap = params[\"stroke-linecap\"] == \"butt\" ? \"flat\" : params[\"stroke-linecap\"] == \"square\" ? \"square\" : \"round\");\n\t            if (\"stroke-dasharray\" in params) {\n\t                var dasharray = {\n\t                    \"-\": \"shortdash\",\n\t                    \".\": \"shortdot\",\n\t                    \"-.\": \"shortdashdot\",\n\t                    \"-..\": \"shortdashdotdot\",\n\t                    \". \": \"dot\",\n\t                    \"- \": \"dash\",\n\t                    \"--\": \"longdash\",\n\t                    \"- .\": \"dashdot\",\n\t                    \"--.\": \"longdashdot\",\n\t                    \"--..\": \"longdashdotdot\"\n\t                };\n\t                stroke.dashstyle = dasharray[has](params[\"stroke-dasharray\"]) ? dasharray[params[\"stroke-dasharray\"]] : E;\n\t            }\n\t            newstroke && node.appendChild(stroke);\n\t        }\n\t        if (res.type == \"text\") {\n\t            res.paper.canvas.style.display = E;\n\t            var span = res.paper.span,\n\t                m = 100,\n\t                fontSize = a.font && a.font.match(/\\d+(?:\\.\\d*)?(?=px)/);\n\t            s = span.style;\n\t            a.font && (s.font = a.font);\n\t            a[\"font-family\"] && (s.fontFamily = a[\"font-family\"]);\n\t            a[\"font-weight\"] && (s.fontWeight = a[\"font-weight\"]);\n\t            a[\"font-style\"] && (s.fontStyle = a[\"font-style\"]);\n\t            fontSize = toFloat(a[\"font-size\"] || fontSize && fontSize[0]) || 10;\n\t            s.fontSize = fontSize * m + \"px\";\n\t            res.textpath.string && (span.innerHTML = Str(res.textpath.string).replace(/</g, \"&#60;\").replace(/&/g, \"&#38;\").replace(/\\n/g, \"<br>\"));\n\t            var brect = span.getBoundingClientRect();\n\t            res.W = a.w = (brect.right - brect.left) / m;\n\t            res.H = a.h = (brect.bottom - brect.top) / m;\n\t            // res.paper.canvas.style.display = \"none\";\n\t            res.X = a.x;\n\t            res.Y = a.y + res.H / 2;\n\n\t            (\"x\" in params || \"y\" in params) && (res.path.v = R.format(\"m{0},{1}l{2},{1}\", round(a.x * zoom), round(a.y * zoom), round(a.x * zoom) + 1));\n\t            var dirtyattrs = [\"x\", \"y\", \"text\", \"font\", \"font-family\", \"font-weight\", \"font-style\", \"font-size\"];\n\t            for (var d = 0, dd = dirtyattrs.length; d < dd; d++) if (dirtyattrs[d] in params) {\n\t                res._.dirty = 1;\n\t                break;\n\t            }\n\n\t            // text-anchor emulation\n\t            switch (a[\"text-anchor\"]) {\n\t                case \"start\":\n\t                    res.textpath.style[\"v-text-align\"] = \"left\";\n\t                    res.bbx = res.W / 2;\n\t                break;\n\t                case \"end\":\n\t                    res.textpath.style[\"v-text-align\"] = \"right\";\n\t                    res.bbx = -res.W / 2;\n\t                break;\n\t                default:\n\t                    res.textpath.style[\"v-text-align\"] = \"center\";\n\t                    res.bbx = 0;\n\t                break;\n\t            }\n\t            res.textpath.style[\"v-text-kern\"] = true;\n\t        }\n\t        // res.paper.canvas.style.display = E;\n\t    },\n\t    addGradientFill = function (o, gradient, fill) {\n\t        o.attrs = o.attrs || {};\n\t        var attrs = o.attrs,\n\t            pow = Math.pow,\n\t            opacity,\n\t            oindex,\n\t            type = \"linear\",\n\t            fxfy = \".5 .5\";\n\t        o.attrs.gradient = gradient;\n\t        gradient = Str(gradient).replace(R._radial_gradient, function (all, fx, fy) {\n\t            type = \"radial\";\n\t            if (fx && fy) {\n\t                fx = toFloat(fx);\n\t                fy = toFloat(fy);\n\t                pow(fx - .5, 2) + pow(fy - .5, 2) > .25 && (fy = math.sqrt(.25 - pow(fx - .5, 2)) * ((fy > .5) * 2 - 1) + .5);\n\t                fxfy = fx + S + fy;\n\t            }\n\t            return E;\n\t        });\n\t        gradient = gradient.split(/\\s*\\-\\s*/);\n\t        if (type == \"linear\") {\n\t            var angle = gradient.shift();\n\t            angle = -toFloat(angle);\n\t            if (isNaN(angle)) {\n\t                return null;\n\t            }\n\t        }\n\t        var dots = R._parseDots(gradient);\n\t        if (!dots) {\n\t            return null;\n\t        }\n\t        o = o.shape || o.node;\n\t        if (dots.length) {\n\t            o.removeChild(fill);\n\t            fill.on = true;\n\t            fill.method = \"none\";\n\t            fill.color = dots[0].color;\n\t            fill.color2 = dots[dots.length - 1].color;\n\t            var clrs = [];\n\t            for (var i = 0, ii = dots.length; i < ii; i++) {\n\t                dots[i].offset && clrs.push(dots[i].offset + S + dots[i].color);\n\t            }\n\t            fill.colors = clrs.length ? clrs.join() : \"0% \" + fill.color;\n\t            if (type == \"radial\") {\n\t                fill.type = \"gradientTitle\";\n\t                fill.focus = \"100%\";\n\t                fill.focussize = \"0 0\";\n\t                fill.focusposition = fxfy;\n\t                fill.angle = 0;\n\t            } else {\n\t                // fill.rotate= true;\n\t                fill.type = \"gradient\";\n\t                fill.angle = (270 - angle) % 360;\n\t            }\n\t            o.appendChild(fill);\n\t        }\n\t        return 1;\n\t    },\n\t    Element = function (node, vml) {\n\t        this[0] = this.node = node;\n\t        node.raphael = true;\n\t        this.id = R._oid++;\n\t        node.raphaelid = this.id;\n\t        this.X = 0;\n\t        this.Y = 0;\n\t        this.attrs = {};\n\t        this.paper = vml;\n\t        this.matrix = R.matrix();\n\t        this._ = {\n\t            transform: [],\n\t            sx: 1,\n\t            sy: 1,\n\t            dx: 0,\n\t            dy: 0,\n\t            deg: 0,\n\t            dirty: 1,\n\t            dirtyT: 1\n\t        };\n\t        !vml.bottom && (vml.bottom = this);\n\t        this.prev = vml.top;\n\t        vml.top && (vml.top.next = this);\n\t        vml.top = this;\n\t        this.next = null;\n\t    };\n\t    var elproto = R.el;\n\n\t    Element.prototype = elproto;\n\t    elproto.constructor = Element;\n\t    elproto.transform = function (tstr) {\n\t        if (tstr == null) {\n\t            return this._.transform;\n\t        }\n\t        var vbs = this.paper._viewBoxShift,\n\t            vbt = vbs ? \"s\" + [vbs.scale, vbs.scale] + \"-1-1t\" + [vbs.dx, vbs.dy] : E,\n\t            oldt;\n\t        if (vbs) {\n\t            oldt = tstr = Str(tstr).replace(/\\.{3}|\\u2026/g, this._.transform || E);\n\t        }\n\t        R._extractTransform(this, vbt + tstr);\n\t        var matrix = this.matrix.clone(),\n\t            skew = this.skew,\n\t            o = this.node,\n\t            split,\n\t            isGrad = ~Str(this.attrs.fill).indexOf(\"-\"),\n\t            isPatt = !Str(this.attrs.fill).indexOf(\"url(\");\n\t        matrix.translate(1, 1);\n\t        if (isPatt || isGrad || this.type == \"image\") {\n\t            skew.matrix = \"1 0 0 1\";\n\t            skew.offset = \"0 0\";\n\t            split = matrix.split();\n\t            if ((isGrad && split.noRotation) || !split.isSimple) {\n\t                o.style.filter = matrix.toFilter();\n\t                var bb = this.getBBox(),\n\t                    bbt = this.getBBox(1),\n\t                    dx = bb.x - bbt.x,\n\t                    dy = bb.y - bbt.y;\n\t                o.coordorigin = (dx * -zoom) + S + (dy * -zoom);\n\t                setCoords(this, 1, 1, dx, dy, 0);\n\t            } else {\n\t                o.style.filter = E;\n\t                setCoords(this, split.scalex, split.scaley, split.dx, split.dy, split.rotate);\n\t            }\n\t        } else {\n\t            o.style.filter = E;\n\t            skew.matrix = Str(matrix);\n\t            skew.offset = matrix.offset();\n\t        }\n\t        if (oldt !== null) { // empty string value is true as well\n\t            this._.transform = oldt;\n\t            R._extractTransform(this, oldt);\n\t        }\n\t        return this;\n\t    };\n\t    elproto.rotate = function (deg, cx, cy) {\n\t        if (this.removed) {\n\t            return this;\n\t        }\n\t        if (deg == null) {\n\t            return;\n\t        }\n\t        deg = Str(deg).split(separator);\n\t        if (deg.length - 1) {\n\t            cx = toFloat(deg[1]);\n\t            cy = toFloat(deg[2]);\n\t        }\n\t        deg = toFloat(deg[0]);\n\t        (cy == null) && (cx = cy);\n\t        if (cx == null || cy == null) {\n\t            var bbox = this.getBBox(1);\n\t            cx = bbox.x + bbox.width / 2;\n\t            cy = bbox.y + bbox.height / 2;\n\t        }\n\t        this._.dirtyT = 1;\n\t        this.transform(this._.transform.concat([[\"r\", deg, cx, cy]]));\n\t        return this;\n\t    };\n\t    elproto.translate = function (dx, dy) {\n\t        if (this.removed) {\n\t            return this;\n\t        }\n\t        dx = Str(dx).split(separator);\n\t        if (dx.length - 1) {\n\t            dy = toFloat(dx[1]);\n\t        }\n\t        dx = toFloat(dx[0]) || 0;\n\t        dy = +dy || 0;\n\t        if (this._.bbox) {\n\t            this._.bbox.x += dx;\n\t            this._.bbox.y += dy;\n\t        }\n\t        this.transform(this._.transform.concat([[\"t\", dx, dy]]));\n\t        return this;\n\t    };\n\t    elproto.scale = function (sx, sy, cx, cy) {\n\t        if (this.removed) {\n\t            return this;\n\t        }\n\t        sx = Str(sx).split(separator);\n\t        if (sx.length - 1) {\n\t            sy = toFloat(sx[1]);\n\t            cx = toFloat(sx[2]);\n\t            cy = toFloat(sx[3]);\n\t            isNaN(cx) && (cx = null);\n\t            isNaN(cy) && (cy = null);\n\t        }\n\t        sx = toFloat(sx[0]);\n\t        (sy == null) && (sy = sx);\n\t        (cy == null) && (cx = cy);\n\t        if (cx == null || cy == null) {\n\t            var bbox = this.getBBox(1);\n\t        }\n\t        cx = cx == null ? bbox.x + bbox.width / 2 : cx;\n\t        cy = cy == null ? bbox.y + bbox.height / 2 : cy;\n\n\t        this.transform(this._.transform.concat([[\"s\", sx, sy, cx, cy]]));\n\t        this._.dirtyT = 1;\n\t        return this;\n\t    };\n\t    elproto.hide = function () {\n\t        !this.removed && (this.node.style.display = \"none\");\n\t        return this;\n\t    };\n\t    elproto.show = function () {\n\t        !this.removed && (this.node.style.display = E);\n\t        return this;\n\t    };\n\t    // Needed to fix the vml setViewBox issues\n\t    elproto.auxGetBBox = R.el.getBBox;\n\t    elproto.getBBox = function(){\n\t      var b = this.auxGetBBox();\n\t      if (this.paper && this.paper._viewBoxShift)\n\t      {\n\t        var c = {};\n\t        var z = 1/this.paper._viewBoxShift.scale;\n\t        c.x = b.x - this.paper._viewBoxShift.dx;\n\t        c.x *= z;\n\t        c.y = b.y - this.paper._viewBoxShift.dy;\n\t        c.y *= z;\n\t        c.width  = b.width  * z;\n\t        c.height = b.height * z;\n\t        c.x2 = c.x + c.width;\n\t        c.y2 = c.y + c.height;\n\t        return c;\n\t      }\n\t      return b;\n\t    };\n\t    elproto._getBBox = function () {\n\t        if (this.removed) {\n\t            return {};\n\t        }\n\t        return {\n\t            x: this.X + (this.bbx || 0) - this.W / 2,\n\t            y: this.Y - this.H,\n\t            width: this.W,\n\t            height: this.H\n\t        };\n\t    };\n\t    elproto.remove = function () {\n\t        if (this.removed || !this.node.parentNode) {\n\t            return;\n\t        }\n\t        this.paper.__set__ && this.paper.__set__.exclude(this);\n\t        R.eve.unbind(\"raphael.*.*.\" + this.id);\n\t        R._tear(this, this.paper);\n\t        this.node.parentNode.removeChild(this.node);\n\t        this.shape && this.shape.parentNode.removeChild(this.shape);\n\t        for (var i in this) {\n\t            this[i] = typeof this[i] == \"function\" ? R._removedFactory(i) : null;\n\t        }\n\t        this.removed = true;\n\t    };\n\t    elproto.attr = function (name, value) {\n\t        if (this.removed) {\n\t            return this;\n\t        }\n\t        if (name == null) {\n\t            var res = {};\n\t            for (var a in this.attrs) if (this.attrs[has](a)) {\n\t                res[a] = this.attrs[a];\n\t            }\n\t            res.gradient && res.fill == \"none\" && (res.fill = res.gradient) && delete res.gradient;\n\t            res.transform = this._.transform;\n\t            return res;\n\t        }\n\t        if (value == null && R.is(name, \"string\")) {\n\t            if (name == fillString && this.attrs.fill == \"none\" && this.attrs.gradient) {\n\t                return this.attrs.gradient;\n\t            }\n\t            var names = name.split(separator),\n\t                out = {};\n\t            for (var i = 0, ii = names.length; i < ii; i++) {\n\t                name = names[i];\n\t                if (name in this.attrs) {\n\t                    out[name] = this.attrs[name];\n\t                } else if (R.is(this.paper.customAttributes[name], \"function\")) {\n\t                    out[name] = this.paper.customAttributes[name].def;\n\t                } else {\n\t                    out[name] = R._availableAttrs[name];\n\t                }\n\t            }\n\t            return ii - 1 ? out : out[names[0]];\n\t        }\n\t        if (this.attrs && value == null && R.is(name, \"array\")) {\n\t            out = {};\n\t            for (i = 0, ii = name.length; i < ii; i++) {\n\t                out[name[i]] = this.attr(name[i]);\n\t            }\n\t            return out;\n\t        }\n\t        var params;\n\t        if (value != null) {\n\t            params = {};\n\t            params[name] = value;\n\t        }\n\t        value == null && R.is(name, \"object\") && (params = name);\n\t        for (var key in params) {\n\t            eve(\"raphael.attr.\" + key + \".\" + this.id, this, params[key]);\n\t        }\n\t        if (params) {\n\t            for (key in this.paper.customAttributes) if (this.paper.customAttributes[has](key) && params[has](key) && R.is(this.paper.customAttributes[key], \"function\")) {\n\t                var par = this.paper.customAttributes[key].apply(this, [].concat(params[key]));\n\t                this.attrs[key] = params[key];\n\t                for (var subkey in par) if (par[has](subkey)) {\n\t                    params[subkey] = par[subkey];\n\t                }\n\t            }\n\t            // this.paper.canvas.style.display = \"none\";\n\t            if (params.text && this.type == \"text\") {\n\t                this.textpath.string = params.text;\n\t            }\n\t            setFillAndStroke(this, params);\n\t            // this.paper.canvas.style.display = E;\n\t        }\n\t        return this;\n\t    };\n\t    elproto.toFront = function () {\n\t        !this.removed && this.node.parentNode.appendChild(this.node);\n\t        this.paper && this.paper.top != this && R._tofront(this, this.paper);\n\t        return this;\n\t    };\n\t    elproto.toBack = function () {\n\t        if (this.removed) {\n\t            return this;\n\t        }\n\t        if (this.node.parentNode.firstChild != this.node) {\n\t            this.node.parentNode.insertBefore(this.node, this.node.parentNode.firstChild);\n\t            R._toback(this, this.paper);\n\t        }\n\t        return this;\n\t    };\n\t    elproto.insertAfter = function (element) {\n\t        if (this.removed) {\n\t            return this;\n\t        }\n\t        if (element.constructor == R.st.constructor) {\n\t            element = element[element.length - 1];\n\t        }\n\t        if (element.node.nextSibling) {\n\t            element.node.parentNode.insertBefore(this.node, element.node.nextSibling);\n\t        } else {\n\t            element.node.parentNode.appendChild(this.node);\n\t        }\n\t        R._insertafter(this, element, this.paper);\n\t        return this;\n\t    };\n\t    elproto.insertBefore = function (element) {\n\t        if (this.removed) {\n\t            return this;\n\t        }\n\t        if (element.constructor == R.st.constructor) {\n\t            element = element[0];\n\t        }\n\t        element.node.parentNode.insertBefore(this.node, element.node);\n\t        R._insertbefore(this, element, this.paper);\n\t        return this;\n\t    };\n\t    elproto.blur = function (size) {\n\t        var s = this.node.runtimeStyle,\n\t            f = s.filter;\n\t        f = f.replace(blurregexp, E);\n\t        if (+size !== 0) {\n\t            this.attrs.blur = size;\n\t            s.filter = f + S + ms + \".Blur(pixelradius=\" + (+size || 1.5) + \")\";\n\t            s.margin = R.format(\"-{0}px 0 0 -{0}px\", round(+size || 1.5));\n\t        } else {\n\t            s.filter = f;\n\t            s.margin = 0;\n\t            delete this.attrs.blur;\n\t        }\n\t        return this;\n\t    };\n\n\t    R._engine.path = function (pathString, vml) {\n\t        var el = createNode(\"shape\");\n\t        el.style.cssText = cssDot;\n\t        el.coordsize = zoom + S + zoom;\n\t        el.coordorigin = vml.coordorigin;\n\t        var p = new Element(el, vml),\n\t            attr = {fill: \"none\", stroke: \"#000\"};\n\t        pathString && (attr.path = pathString);\n\t        p.type = \"path\";\n\t        p.path = [];\n\t        p.Path = E;\n\t        setFillAndStroke(p, attr);\n\t        vml.canvas && vml.canvas.appendChild(el);\n\t        var skew = createNode(\"skew\");\n\t        skew.on = true;\n\t        el.appendChild(skew);\n\t        p.skew = skew;\n\t        p.transform(E);\n\t        return p;\n\t    };\n\t    R._engine.rect = function (vml, x, y, w, h, r) {\n\t        var path = R._rectPath(x, y, w, h, r),\n\t            res = vml.path(path),\n\t            a = res.attrs;\n\t        res.X = a.x = x;\n\t        res.Y = a.y = y;\n\t        res.W = a.width = w;\n\t        res.H = a.height = h;\n\t        a.r = r;\n\t        a.path = path;\n\t        res.type = \"rect\";\n\t        return res;\n\t    };\n\t    R._engine.ellipse = function (vml, x, y, rx, ry) {\n\t        var res = vml.path(),\n\t            a = res.attrs;\n\t        res.X = x - rx;\n\t        res.Y = y - ry;\n\t        res.W = rx * 2;\n\t        res.H = ry * 2;\n\t        res.type = \"ellipse\";\n\t        setFillAndStroke(res, {\n\t            cx: x,\n\t            cy: y,\n\t            rx: rx,\n\t            ry: ry\n\t        });\n\t        return res;\n\t    };\n\t    R._engine.circle = function (vml, x, y, r) {\n\t        var res = vml.path(),\n\t            a = res.attrs;\n\t        res.X = x - r;\n\t        res.Y = y - r;\n\t        res.W = res.H = r * 2;\n\t        res.type = \"circle\";\n\t        setFillAndStroke(res, {\n\t            cx: x,\n\t            cy: y,\n\t            r: r\n\t        });\n\t        return res;\n\t    };\n\t    R._engine.image = function (vml, src, x, y, w, h) {\n\t        var path = R._rectPath(x, y, w, h),\n\t            res = vml.path(path).attr({stroke: \"none\"}),\n\t            a = res.attrs,\n\t            node = res.node,\n\t            fill = node.getElementsByTagName(fillString)[0];\n\t        a.src = src;\n\t        res.X = a.x = x;\n\t        res.Y = a.y = y;\n\t        res.W = a.width = w;\n\t        res.H = a.height = h;\n\t        a.path = path;\n\t        res.type = \"image\";\n\t        fill.parentNode == node && node.removeChild(fill);\n\t        fill.rotate = true;\n\t        fill.src = src;\n\t        fill.type = \"tile\";\n\t        res._.fillpos = [x, y];\n\t        res._.fillsize = [w, h];\n\t        node.appendChild(fill);\n\t        setCoords(res, 1, 1, 0, 0, 0);\n\t        return res;\n\t    };\n\t    R._engine.text = function (vml, x, y, text) {\n\t        var el = createNode(\"shape\"),\n\t            path = createNode(\"path\"),\n\t            o = createNode(\"textpath\");\n\t        x = x || 0;\n\t        y = y || 0;\n\t        text = text || \"\";\n\t        path.v = R.format(\"m{0},{1}l{2},{1}\", round(x * zoom), round(y * zoom), round(x * zoom) + 1);\n\t        path.textpathok = true;\n\t        o.string = Str(text);\n\t        o.on = true;\n\t        el.style.cssText = cssDot;\n\t        el.coordsize = zoom + S + zoom;\n\t        el.coordorigin = \"0 0\";\n\t        var p = new Element(el, vml),\n\t            attr = {\n\t                fill: \"#000\",\n\t                stroke: \"none\",\n\t                font: R._availableAttrs.font,\n\t                text: text\n\t            };\n\t        p.shape = el;\n\t        p.path = path;\n\t        p.textpath = o;\n\t        p.type = \"text\";\n\t        p.attrs.text = Str(text);\n\t        p.attrs.x = x;\n\t        p.attrs.y = y;\n\t        p.attrs.w = 1;\n\t        p.attrs.h = 1;\n\t        setFillAndStroke(p, attr);\n\t        el.appendChild(o);\n\t        el.appendChild(path);\n\t        vml.canvas.appendChild(el);\n\t        var skew = createNode(\"skew\");\n\t        skew.on = true;\n\t        el.appendChild(skew);\n\t        p.skew = skew;\n\t        p.transform(E);\n\t        return p;\n\t    };\n\t    R._engine.setSize = function (width, height) {\n\t        var cs = this.canvas.style;\n\t        this.width = width;\n\t        this.height = height;\n\t        width == +width && (width += \"px\");\n\t        height == +height && (height += \"px\");\n\t        cs.width = width;\n\t        cs.height = height;\n\t        cs.clip = \"rect(0 \" + width + \" \" + height + \" 0)\";\n\t        if (this._viewBox) {\n\t            R._engine.setViewBox.apply(this, this._viewBox);\n\t        }\n\t        return this;\n\t    };\n\t    R._engine.setViewBox = function (x, y, w, h, fit) {\n\t        R.eve(\"raphael.setViewBox\", this, this._viewBox, [x, y, w, h, fit]);\n\t        var paperSize = this.getSize(),\n\t            width = paperSize.width,\n\t            height = paperSize.height,\n\t            H, W;\n\t        if (fit) {\n\t            H = height / h;\n\t            W = width / w;\n\t            if (w * H < width) {\n\t                x -= (width - w * H) / 2 / H;\n\t            }\n\t            if (h * W < height) {\n\t                y -= (height - h * W) / 2 / W;\n\t            }\n\t        }\n\t        this._viewBox = [x, y, w, h, !!fit];\n\t        this._viewBoxShift = {\n\t            dx: -x,\n\t            dy: -y,\n\t            scale: paperSize\n\t        };\n\t        this.forEach(function (el) {\n\t            el.transform(\"...\");\n\t        });\n\t        return this;\n\t    };\n\t    var createNode;\n\t    R._engine.initWin = function (win) {\n\t            var doc = win.document;\n\t            if (doc.styleSheets.length < 31) {\n\t                doc.createStyleSheet().addRule(\".rvml\", \"behavior:url(#default#VML)\");\n\t            } else {\n\t                // no more room, add to the existing one\n\t                // http://msdn.microsoft.com/en-us/library/ms531194%28VS.85%29.aspx\n\t                doc.styleSheets[0].addRule(\".rvml\", \"behavior:url(#default#VML)\");\n\t            }\n\t            try {\n\t                !doc.namespaces.rvml && doc.namespaces.add(\"rvml\", \"urn:schemas-microsoft-com:vml\");\n\t                createNode = function (tagName) {\n\t                    return doc.createElement('<rvml:' + tagName + ' class=\"rvml\">');\n\t                };\n\t            } catch (e) {\n\t                createNode = function (tagName) {\n\t                    return doc.createElement('<' + tagName + ' xmlns=\"urn:schemas-microsoft.com:vml\" class=\"rvml\">');\n\t                };\n\t            }\n\t        };\n\t    R._engine.initWin(R._g.win);\n\t    R._engine.create = function () {\n\t        var con = R._getContainer.apply(0, arguments),\n\t            container = con.container,\n\t            height = con.height,\n\t            s,\n\t            width = con.width,\n\t            x = con.x,\n\t            y = con.y;\n\t        if (!container) {\n\t            throw new Error(\"VML container not found.\");\n\t        }\n\t        var res = new R._Paper,\n\t            c = res.canvas = R._g.doc.createElement(\"div\"),\n\t            cs = c.style;\n\t        x = x || 0;\n\t        y = y || 0;\n\t        width = width || 512;\n\t        height = height || 342;\n\t        res.width = width;\n\t        res.height = height;\n\t        width == +width && (width += \"px\");\n\t        height == +height && (height += \"px\");\n\t        res.coordsize = zoom * 1e3 + S + zoom * 1e3;\n\t        res.coordorigin = \"0 0\";\n\t        res.span = R._g.doc.createElement(\"span\");\n\t        res.span.style.cssText = \"position:absolute;left:-9999em;top:-9999em;padding:0;margin:0;line-height:1;\";\n\t        c.appendChild(res.span);\n\t        cs.cssText = R.format(\"top:0;left:0;width:{0};height:{1};display:inline-block;position:relative;clip:rect(0 {0} {1} 0);overflow:hidden\", width, height);\n\t        if (container == 1) {\n\t            R._g.doc.body.appendChild(c);\n\t            cs.left = x + \"px\";\n\t            cs.top = y + \"px\";\n\t            cs.position = \"absolute\";\n\t        } else {\n\t            if (container.firstChild) {\n\t                container.insertBefore(c, container.firstChild);\n\t            } else {\n\t                container.appendChild(c);\n\t            }\n\t        }\n\t        res.renderfix = function () {};\n\t        return res;\n\t    };\n\t    R.prototype.clear = function () {\n\t        R.eve(\"raphael.clear\", this);\n\t        this.canvas.innerHTML = E;\n\t        this.span = R._g.doc.createElement(\"span\");\n\t        this.span.style.cssText = \"position:absolute;left:-9999em;top:-9999em;padding:0;margin:0;line-height:1;display:inline;\";\n\t        this.canvas.appendChild(this.span);\n\t        this.bottom = this.top = null;\n\t    };\n\t    R.prototype.remove = function () {\n\t        R.eve(\"raphael.remove\", this);\n\t        this.canvas.parentNode.removeChild(this.canvas);\n\t        for (var i in this) {\n\t            this[i] = typeof this[i] == \"function\" ? R._removedFactory(i) : null;\n\t        }\n\t        return true;\n\t    };\n\n\t    var setproto = R.st;\n\t    for (var method in elproto) if (elproto[has](method) && !setproto[has](method)) {\n\t        setproto[method] = (function (methodname) {\n\t            return function () {\n\t                var arg = arguments;\n\t                return this.forEach(function (el) {\n\t                    el[methodname].apply(el, arg);\n\t                });\n\t            };\n\t        })(method);\n\t    }\n\t}.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));\n\n\n/***/ }\n/******/ ])\n});\n;"
  },
  {
    "path": "app_backend/views/__init__.py",
    "content": "#!/usr/bin/env python\n# encoding: utf-8\n\n\"\"\"\n@author: zhanghe\n@software: PyCharm\n@file: __init__.py.py\n@time: 2017/3/10 下午10:56\n\"\"\"\n\n\nimport os\nfrom datetime import datetime\nimport json\nimport traceback\n\nfrom flask import current_app, Response\nfrom sqlalchemy.exc import OperationalError\nfrom pika.exceptions import ConnectionClosed\nfrom flask import send_from_directory\nfrom flask_principal import identity_changed, Identity, AnonymousIdentity\nfrom flask_principal import identity_loaded, RoleNeed, UserNeed\n\nfrom flask import g, request, render_template, jsonify\nfrom flask import session, redirect, url_for, flash\nfrom flask_login import login_user\nfrom flask_login import logout_user\nfrom flask_login import current_user\nfrom flask_login import login_required\nfrom flask_login import user_loaded_from_cookie\n\nfrom app_backend.api.admin_role import get_admin_role_row_by_id\nfrom app_backend.lib.rabbit_mq import RabbitPriorityQueue\nfrom app_backend.tools.db import get_row_by_id\nfrom app_common.maps import area_code_map\nfrom app_backend import app, oauth_github, oauth_qq, oauth_weibo\nfrom app_common.maps.type_auth import *\nfrom app_common.maps.status_delete import *\n\nfrom app_backend import app, login_manager\n\n# cache = SimpleCache()  # 默认最大支持500个key, 超时时间5分钟, 参数可配置\nfrom app_backend.api.admin import get_admin_row\n# from app_backend.lib.sms_chuanglan_iso import SmsChuangLanIsoApi\nfrom app_common.tools import md5, get_randint\nfrom app_backend.tools.send_sms import UN, PW\nfrom app_common.tools.ip import get_real_ip\n\nfrom app_backend.permissions import permission_admin\nfrom app_backend.permissions import permission_other\n\nSMS_CODE_LOGIN = app.config['SMS_CODE_LOGIN']\nEXCHANGE_NAME = app.config['EXCHANGE_NAME']\n\n\n@login_manager.user_loader\ndef load_user(user_id):\n    \"\"\"\n    如果 user_id 无效，它应该返回 None （ 而不是抛出异常 ）。\n    :param user_id:\n    :return:\n    \"\"\"\n    from app_backend.login import LoginUser\n    return get_row_by_id(LoginUser, int(user_id))\n    # return LoginUser.query.get(int(user_id))\n\n\n# @app.before_request\n# def before_request():\n#     \"\"\"\n#     当前用户信息\n#     \"\"\"\n#     g.user = current_user\n\n\n@identity_loaded.connect_via(app)\ndef on_identity_loaded(sender, identity):\n    # Set the identity user object\n    identity.user = current_user\n\n    # Add the UserNeed to the identity\n    if hasattr(current_user, 'id'):\n        identity.provides.add(UserNeed(current_user.id))\n\n    # Assuming the User model has a list of roles, update the\n    # identity with the roles that the user provides\n    if hasattr(current_user, 'role_id'):\n        row = get_admin_role_row_by_id(current_user.role_id)\n        modules = row.module.split(',') if row else []\n        for module in modules:\n            role_need = RoleNeed(module)\n            identity.provides.add(role_need)\n\n\n@user_loaded_from_cookie.connect_via(app)\ndef on_user_loaded_from_cookie(sender, user):\n    \"\"\"\n    记住密码后，通过cookie加载用户，需要重新赋予权限，否则权限会丢失\n    :param sender:\n    :param user:\n    :return:\n    \"\"\"\n    identity_changed.send(app, identity=Identity(user.id, user.role_id))\n\n\n@app.route('/favicon.ico')\ndef favicon():\n    \"\"\"\n    首页ico图标\n    \"\"\"\n    from app_backend import app\n    return send_from_directory(os.path.join(app.root_path, 'static'),\n                               'img/favicon.ico', mimetype='image/vnd.microsoft.icon')\n\n\n@app.route('/')\n@app.route('/index/')\n@login_required\ndef index():\n    \"\"\"\n    后台首页\n    \"\"\"\n    # return \"Hello, World!\"\n    # return str(current_user.__dict__)\n    return render_template('index.html', title='home')\n\n\n@app.route('/login/', methods=['GET', 'POST'])\ndef login():\n    \"\"\"\n    后台登录页面\n    \"\"\"\n    # print current_user.__dict__\n    # return json.dumps(current_user.__dict__)\n    if current_user and current_user.is_authenticated:\n        return redirect(url_for('index'))\n    from app_backend.forms.login import LoginForm\n    form = LoginForm()\n    if request.method == 'POST':\n        if form.validate_on_submit():\n            from app_backend.api.admin import get_admin_row\n            condition = {\n                'username': form.account.data,\n                'password': md5(form.password.data)\n            }\n            admin_info = get_admin_row(**condition)\n            if admin_info is None:\n                flash(u'%s, 登录失败，账号密码错误' % form.account.data, 'warning')\n                return render_template('login.html', title='login', form=form)\n            if admin_info.status_delete == STATUS_DEL_OK:\n                flash(u'%s, 登录失败，账号已被删除' % form.account.data, 'warning')\n                return render_template('login.html', title='login', form=form)\n            # session['logged_in'] = True\n            # 用户通过验证后，记录登入IP\n            from app_backend.api.admin import edit_admin\n            ip_data = {\n                'login_ip': get_real_ip(),\n                'login_time': datetime.utcnow()\n            }\n            edit_admin(admin_info.id, ip_data)\n            # 用 login_user 函数来登入他们\n            from app_backend.api.admin import get_admin_row_by_id\n            login_user(get_admin_row_by_id(admin_info.id), remember=form.remember.data)\n\n            # 加载权限\n            # Tell Flask-Principal the identity changed\n            identity_changed.send(app, identity=Identity(admin_info.id, admin_info.role_id))\n\n            flash(u'%s, 恭喜，登录成功' % form.account.data, 'success')\n            return redirect(request.args.get('next') or url_for('index'))\n        # flash(form.errors, 'warning')  # 调试打开\n    return render_template('login.html', title='login', form=form)\n\n\n@app.route('/logout/')\ndef logout():\n    \"\"\"\n    退出登录\n    \"\"\"\n    logout_user()\n    session.pop('qq_token', None)\n    session.pop('weibo_token', None)\n    session.pop('github_token', None)\n\n    # 退出权限\n    # Remove session keys set by Flask-Principal\n    for key in ('identity.name', 'identity.auth_type'):\n        session.pop(key, None)\n\n    # Tell Flask-Principal the user is anonymous\n    identity_changed.send(app, identity=AnonymousIdentity())\n\n    flash(u'成功退出登录', 'info')\n    return redirect(url_for('login'))\n\n\n@app.route('/ajax/get_sms_code/', methods=['GET', 'POST'])\ndef ajax_get_sms_code():\n    \"\"\"\n    获取短信验证码\n    :return:\n    \"\"\"\n    try:\n        # 获取短信验证码\n        account = request.args.get('account', '', type=str)\n        if not account:\n            return json.dumps({'result': False, 'msg': u'账号为空，请重新填写'})\n        account = request.args.get('account', '', type=str)\n        admin_info = get_admin_row(username=account)\n        if not admin_info:\n            return json.dumps({'result': False, 'msg': u'账号不存在，请填写正确'})\n        area_code = admin_info.area_code\n        mobile = admin_info.phone\n        if not area_code or not mobile:\n            return json.dumps({'result': False, 'msg': u'手机号码错误，请在后台更新'})\n        mobile_iso = '%s%s' % (area_code, mobile)\n\n        sms_code = str(get_randint())\n        code_key = '%s:%s' % ('sms_code', 'login')\n        session[code_key] = sms_code\n\n        sms_content = SMS_CODE_LOGIN % sms_code\n\n        # sms_client = SmsChuangLanIsoApi(UN, PW)\n        # result = sms_client.send_international(mobile_iso, msg)\n\n        # 推送短信优先级队列\n        q = RabbitPriorityQueue(exchange=EXCHANGE_NAME, queue_name='send_sms_p')\n        q.put({'mobile': mobile_iso, 'sms_content': sms_content}, 20)\n\n        return json.dumps({'result': True})\n    except OperationalError:\n        print traceback.print_exc()\n        return json.dumps({'result': False, 'msg': u'数据库连接失败'})\n    except ConnectionClosed:\n        print traceback.print_exc()\n        return json.dumps({'result': False, 'msg': u'短信队列连接失败'})\n    except Exception as e:\n        print traceback.print_exc()\n        return json.dumps({'result': False, 'msg': u'服务器异常，短信获取失败；%s' % e.message})\n\n\n@app.errorhandler(403)\ndef page_permission_denied(error):\n    flash(u'暂无权限', 'warning')\n    session['redirected_from'] = request.url\n    return redirect(url_for('index'))\n\n\n@app.errorhandler(404)\ndef page_not_found(error):\n    return render_template('404.html'), 404\n\n\n@app.errorhandler(500)\ndef internal_error(error):\n    from app_backend.database import db\n    db.session.rollback()\n    return render_template('500.html'), 500\n\n\n@app.route('/permission_admin/')\n@permission_admin.require(http_exception=403)\ndef test_admin_permission():\n    \"\"\"\n    管理员权限测试\n    :return:\n    \"\"\"\n    return Response('Only if you are admin')\n\n\n@app.route('/permission_other/')\n@permission_other.require(http_exception=403)\ndef test_other_permission():\n    \"\"\"\n    管理员权限测试\n    :return:\n    \"\"\"\n    return Response('Only if you are other')\n\n\n@app.route('/performance/')\n# @login_required\ndef performance():\n    \"\"\"\n    性能测试\n    \"\"\"\n    from app_backend.models import UserProfile\n    from app_backend.database import db\n    from random import randint\n    user_id = randint(1, 20)\n    row = UserProfile.query.filter(UserProfile.user_id == user_id).first()\n    db.session.commit()\n    return row.nickname\n\n\n@app.route('/stream/')\ndef stream():\n    \"\"\"\n    流式响应\n    http://0.0.0.0:8010/stream/\n    :return:\n    \"\"\"\n    import time\n\n    def gen():\n        for c in 'Hello world!':\n            yield c\n            time.sleep(0.5)\n    return Response(gen())\n\n\n@app.route('/stream_with_context/')\ndef stream_with_context():\n    \"\"\"\n    http://0.0.0.0:8010/stream_with_context/?name=Administrator\n    :return:\n    \"\"\"\n    import time\n    from flask import stream_with_context, request, Response\n\n    def generate():\n        for i in 'Hello %s!' % (request.args.get('name', '')):\n            time.sleep(0.5)\n            yield i\n    return Response(stream_with_context(generate()))\n"
  },
  {
    "path": "app_backend/views/active.py",
    "content": "#!/usr/bin/env python\n# encoding: utf-8\n\n\"\"\"\n@author: zhanghe\n@software: PyCharm\n@file: active.py\n@time: 2017/6/16 下午10:19\n\"\"\"\n\n\nfrom datetime import datetime\nfrom flask import redirect\nfrom flask import render_template, request, flash, g\nfrom flask import url_for\nfrom flask_login import current_user, login_required\nfrom sqlalchemy.orm import aliased\n\nfrom app_backend import app\nfrom app_backend.api.active import give_active\nfrom app_backend.models import User, UserProfile, ActiveItem\nfrom app_backend.api.active_item import get_active_item_rows\nfrom app_common.maps.type_active import *\nfrom app_backend.forms.active import ActiveAddForm\nfrom app_backend.database import db\n\nPER_PAGE_BACKEND = app.config['PER_PAGE_BACKEND']\n\nfrom flask import Blueprint\n\n\nbp_active = Blueprint('active', __name__, url_prefix='/active')\n\n\n@bp_active.route('/list/')\n@bp_active.route('/list/<int:page>/')\n@login_required\ndef lists(page=1):\n    \"\"\"\n    激活列表\n    \"\"\"\n    # 系统赠送（默认）；2、会员转赠；3、上游激活；4、自行激活\n    active_list_type = request.args.get('active_list_type', 0, type=int)\n\n    # 多次连接同一张表，需要别名\n    user_profile_put = aliased(UserProfile)\n    user_profile_get = aliased(UserProfile)\n\n    if active_list_type == 2:\n        condition = [\n            ActiveItem.type == TYPE_ACTIVE_GIVE,\n            user_profile_put.user_id != user_profile_get.user_id\n        ]\n    elif active_list_type == 3:\n        condition = [\n            ActiveItem.type == TYPE_ACTIVE_USER,\n            user_profile_put.user_id != user_profile_get.user_id\n        ]\n    elif active_list_type == 4:\n        condition = [\n            ActiveItem.type == TYPE_ACTIVE_USER,\n            user_profile_put.user_id == user_profile_get.user_id\n        ]\n    else:\n        condition = [\n            ActiveItem.type == TYPE_ACTIVE_GIVE,\n            ActiveItem.user_id == 0\n        ]\n    try:\n        pagination = ActiveItem.query. \\\n            outerjoin(user_profile_put, ActiveItem.user_id == user_profile_put.user_id). \\\n            add_entity(user_profile_put). \\\n            outerjoin(user_profile_get, ActiveItem.sc_id == user_profile_get.user_id). \\\n            add_entity(user_profile_get). \\\n            filter(*condition). \\\n            order_by(ActiveItem.id.desc()). \\\n            paginate(page, PER_PAGE_BACKEND, False)\n        db.session.commit()\n        return render_template('active/list.html', title='active_list', pagination=pagination)\n    except Exception as e:\n        db.session.rollback()\n        flash(e.message, category='warning')\n        return redirect(url_for('index'))\n\n\n@bp_active.route('/add/', methods=['GET', 'POST'])\n@login_required\ndef add():\n    \"\"\"\n    添加激活记录\n    :return:\n    \"\"\"\n    user_id = request.args.get('user_id', '', type=int)\n\n    form = ActiveAddForm(request.form)\n\n    # 初始化表单的值\n    if user_id:\n        form.user_id.data = user_id\n    if not form.amount.data:\n        form.amount.data = 1\n\n    if request.method == 'POST':\n        if form.validate_on_submit():\n            # 赠送激活数量\n            try:\n                result = give_active(form.user_id.data, form.amount.data)\n                if result:\n                    flash(u'赠送激活数量操作成功', 'success')\n                return redirect(url_for('.lists'))\n            except Exception as e:\n                flash(e.message or u'赠送激活数量操作失败', 'warning')\n        # 闪现消息 success info warning danger\n        # flash(form.errors, 'warning')  # 调试打开\n    return render_template('active/add.html', title='active_add', form=form)\n\n\n@bp_active.route('/del/', methods=['GET', 'POST'])\n@login_required\ndef delete():\n    \"\"\"\n    删除激活\n    :return:\n    \"\"\"\n    pass\n\n\n@bp_active.route('/stats/', methods=['GET', 'POST'])\n@login_required\ndef stats():\n    \"\"\"\n    激活统计\n    :return:\n    \"\"\"\n    pass\n"
  },
  {
    "path": "app_backend/views/admin.py",
    "content": "#!/usr/bin/env python\n# encoding: utf-8\n\n\"\"\"\n@author: zhanghe\n@software: PyCharm\n@file: admin.py\n@time: 2017/4/22 下午5:02\n\"\"\"\n\n\nimport json\nfrom datetime import datetime\n\nfrom flask import abort\nfrom flask import redirect\nfrom flask import render_template, request, flash, g\nfrom flask import url_for\nfrom flask_login import current_user, login_required\n\nfrom app_backend.api.admin_role import get_admin_role_lists\nfrom app_common.maps import area_code_map\nfrom app_common.tools import md5\nfrom app_backend import app\nfrom app_backend.forms.admin import AdminProfileForm, AdminAddForm, AdminEditForm\nfrom app_backend.models import User\nfrom app_backend.api.admin import get_admin_rows, get_admin_row, edit_admin, add_admin, get_admin_row_by_id\nfrom app_backend.api.admin_role import get_admin_role_row_by_id, edit_admin_role\nfrom app_common.maps.status_delete import *\n\nfrom flask import Blueprint\n\n\nfrom app_backend.permissions import permission_admin\n\nbp_admin = Blueprint('admin', __name__, url_prefix='/admin')\n\n\n@bp_admin.route('/profile/', methods=['GET', 'POST'])\n@login_required\n@permission_admin.require(http_exception=403)\ndef profile():\n    \"\"\"\n    当前登录管理员信息\n    :return:\n    \"\"\"\n    admin_id = current_user.id\n    # return render_template('admin/profile.html', title='admin_profile')\n\n    form = AdminProfileForm(request.form)\n    admin_info = get_admin_row_by_id(admin_id)\n    if request.method == 'GET':\n        form.id.data = admin_id\n        form.username.data = admin_info.username\n        form.password.data = ''\n        form.area_id.data = admin_info.area_id\n        form.phone.data = admin_info.phone\n        form.role_id.data = admin_info.role_id\n        form.create_time.data = admin_info.create_time\n        form.update_time.data = admin_info.update_time\n    if request.method == 'POST':\n        if form.validate_on_submit():\n            current_time = datetime.utcnow()\n            # 手机号码国际化\n            area_id = form.area_id.data\n            area_code = area_code_map.get(area_id, '86')\n            admin_data = {\n                'username': form.username.data,\n                'area_id': area_id,\n                'area_code': area_code,\n                'phone': form.phone.data,\n                'role_id': form.role_id.data,\n                'update_time': current_time,\n            }\n            if form.password.data:\n                admin_data['password'] = md5(form.password.data)\n\n            result = edit_admin(admin_id, admin_data)\n            if result:\n                flash(u'修改成功', 'success')\n                return redirect(url_for('admin.lists'))\n        else:\n            form.create_time.data = admin_info.create_time\n            form.update_time.data = admin_info.update_time\n            flash(u'修改失败', 'warning')\n    # flash(form.errors, 'warning')  # 调试打开\n    return render_template('admin/profile.html', title='admin_profile', form=form)\n\n\n@bp_admin.route('/list/')\n@bp_admin.route('/list/<int:page>/')\n@login_required\n@permission_admin.require(http_exception=403)\ndef lists(page=1):\n    \"\"\"\n    管理列表\n    \"\"\"\n    pagination = get_admin_rows(page)\n    return render_template('admin/list.html', title='admin_list', pagination=pagination)\n\n\n@bp_admin.route('/add/', methods=['GET', 'POST'])\n@login_required\n@permission_admin.require(http_exception=403)\ndef add():\n    \"\"\"\n    添加管理\n    \"\"\"\n    # return render_template('admin/add.html', title='admin_add')\n\n    form = AdminAddForm(request.form)\n    if request.method == 'POST':\n        if form.validate_on_submit():\n            current_time = datetime.utcnow()\n            # 手机号码国际化\n            area_id = form.area_id.data\n            area_code = area_code_map.get(area_id, '86')\n            admin_info = {\n                'username': form.username.data,\n                'password': md5(form.password.data),\n                'area_id': area_id,\n                'area_code': area_code,\n                'phone': form.phone.data,\n                'role_id': form.role_id.data,\n                'create_time': current_time,\n                'update_time': current_time,\n            }\n            admin_uid = add_admin(admin_info)\n            if admin_uid:\n                flash(u'Add Success', 'success')\n                return redirect(url_for('admin.lists'))\n            else:\n                flash(u'Add Failed', 'warning')\n    # flash(form.errors, 'warning')  # 调试打开\n    return render_template('admin/add.html', title='admin_add', form=form)\n\n\n@bp_admin.route('/edit/<int:admin_id>', methods=['GET', 'POST'])\n@login_required\n@permission_admin.require(http_exception=403)\ndef edit(admin_id):\n    \"\"\"\n    编辑管理成员\n    \"\"\"\n    form = AdminEditForm(request.form)\n    admin_info = get_admin_row_by_id(admin_id)\n    if request.method == 'GET':\n        if admin_info:\n            form.id.data = admin_info.id\n            form.username.data = admin_info.username\n            form.password.data = ''\n            form.area_id.data = admin_info.area_id\n            form.phone.data = admin_info.phone\n            form.role_id.data = admin_info.role_id\n            form.create_time.data = admin_info.create_time\n            form.update_time.data = admin_info.update_time\n    if request.method == 'POST':\n        if form.validate_on_submit():\n            current_time = datetime.utcnow()\n            # 手机号码国际化\n            area_id = form.area_id.data\n            area_code = area_code_map.get(area_id, '86')\n            admin_data = {\n                'username': form.username.data,\n                'area_id': area_id,\n                'area_code': area_code,\n                'phone': form.phone.data,\n                'role_id': form.role_id.data,\n                'update_time': current_time,\n            }\n            if form.password.data:\n                admin_data['password'] = md5(form.password.data)\n\n            result = edit_admin(admin_id, admin_data)\n            if result:\n                flash(u'修改成功', 'success')\n                return redirect(url_for('admin.lists'))\n        else:\n            form.create_time.data = admin_info.create_time\n            form.update_time.data = admin_info.update_time\n            flash(u'修改失败', 'warning')\n        # flash(form.errors, 'warning')  # 调试打开\n\n    return render_template('admin/edit.html', title='admin_edit', form=form)\n\n\n@bp_admin.route('/ajax/del/', methods=['GET', 'POST'])\n@login_required\n@permission_admin.require(http_exception=403)\ndef ajax_delete():\n    \"\"\"\n    删除管理\n    :return:\n    \"\"\"\n    if request.method == 'GET' and request.is_xhr:\n        admin_uid = request.args.get('admin_uid', 0, type=int)\n        if not admin_uid:\n            return json.dumps({'error': u'删除失败'})\n        current_time = datetime.utcnow()\n        admin_data = {\n            'status_delete': STATUS_DEL_OK,\n            'delete_time': current_time,\n            'update_time': current_time\n        }\n        result = edit_admin(admin_uid, admin_data)\n        if result == 1:\n            return json.dumps({'success': u'删除成功'})\n        if result == 0:\n            return json.dumps({'error': u'删除失败'})\n    abort(404)\n\n\n@bp_admin.route('/role/', methods=['GET', 'POST'])\n@login_required\n@permission_admin.require(http_exception=403)\ndef role():\n    \"\"\"\n    角色管理\n    \"\"\"\n    from app_backend.forms.admin import AdminRoleForm\n    form = AdminRoleForm(request.form)\n    if request.method == 'GET':\n        role_id = request.args.get('role_id', 1, type=int)\n        admin_role = get_admin_role_row_by_id(role_id)\n        if admin_role:\n            form.role_id.data = admin_role.id\n            form.name.data = admin_role.name\n            form.note.data = admin_role.note\n            form.module.data = admin_role.module\n            form.create_time.data = admin_role.create_time\n            form.update_time.data = admin_role.update_time\n    if request.method == 'POST':\n        if form.validate_on_submit():\n            current_time = datetime.utcnow()\n            admin_role_info = {\n                'note': form.note.data,\n                'module': form.module.data.replace(u'，', u','),\n                'update_time': current_time,\n            }\n            result = edit_admin_role(form.role_id.data, admin_role_info)\n            if result:\n                flash(u'修改成功', 'success')\n                return redirect(url_for('.role', role_id=form.role_id.data))\n            else:\n                flash(u'修改失败', 'warning')\n    return render_template('admin/role.html', title='admin_role', form=form)\n"
  },
  {
    "path": "app_backend/views/apply_get.py",
    "content": "#!/usr/bin/env python\n# encoding: utf-8\n\n\"\"\"\n@author: zhanghe\n@software: PyCharm\n@file: apply_get.py\n@time: 2017/4/13 下午9:32\n\"\"\"\n\n\nfrom datetime import datetime\n\nfrom flask import abort\nfrom flask import Blueprint\nimport json\nfrom flask import redirect\nfrom flask import render_template, request, flash, g\nfrom flask import url_for\nfrom flask_login import current_user, login_required\n\nfrom app_backend import app\nfrom app_backend.api.apply_put import get_apply_put_rows_by_ids, edit_apply_put\nfrom app_backend.api.order import get_order_lists, add_order, get_get_match_order_rows\n\nfrom app_backend.forms.admin import AdminProfileForm\nfrom app_backend.forms.apply_put import ApplyPutSearchForm\nfrom app_backend.models import User, ApplyGet, UserProfile, ApplyPut\nfrom app_backend.api.apply_get import get_apply_get_rows, get_apply_get_row, get_apply_get_row_by_id, \\\n    get_apply_get_rows_by_ids, edit_apply_get, apply_get_match, apply_get_stats\nfrom app_backend.forms.apply_get import ApplyGetSearchForm\n\nfrom app_common.maps.status_delete import *\nfrom app_common.maps.status_order import *\nfrom app_common.maps.status_pay import *\nfrom app_common.maps.status_rec import *\nfrom app_common.maps.status_audit import *\nfrom app_common.tools import json_default\nfrom app_common.tools.date_time import time_local_to_utc\nfrom app_backend.permissions import permission_order\nfrom app_backend.database import db\n\n\nPER_PAGE_BACKEND = app.config['PER_PAGE_BACKEND']\n\nbp_apply_get = Blueprint('apply_get', __name__, url_prefix='/apply_get')\n\n\n@bp_apply_get.route('/list/')\n@bp_apply_get.route('/list/<int:page>/')\n@login_required\n@permission_order.require(http_exception=403)\ndef lists(page=1):\n    \"\"\"\n    提现申请列表\n    \"\"\"\n    form = ApplyGetSearchForm(request.form)\n\n    apply_get_id = request.args.get('apply_get_id', '', type=int)\n    user_id = request.args.get('user_id', '', type=int)\n    type_apply = request.args.get('type_apply', '', type=str)\n    money_apply = request.args.get('money_apply', '', type=str)\n    status_apply = request.args.get('status_apply', '', type=str)\n    status_order = request.args.get('status_order', '', type=str)\n    status_delete = request.args.get('status_delete', '', type=str)\n    start_time = request.args.get('start_time', '', type=str)\n    end_time = request.args.get('end_time', '', type=str)\n    op = request.args.get('op', 0, type=int)\n\n    form.apply_get_id.data = apply_get_id\n    form.user_id.data = user_id\n    form.type_apply.data = type_apply\n    form.money_apply.data = money_apply\n    form.status_apply.data = status_apply\n    form.status_order.data = status_order\n    form.status_delete.data = status_delete\n    form.start_time.data = start_time\n    form.end_time.data = end_time\n\n    search_condition_apply_get = [\n        ApplyGet.status_delete == STATUS_DEL_NO,\n    ]\n    if apply_get_id:\n        search_condition_apply_get.append(ApplyGet.id == apply_get_id)\n    if user_id:\n        search_condition_apply_get.append(ApplyGet.user_id == user_id)\n    if status_apply:\n        search_condition_apply_get.append(ApplyGet.status_apply == status_apply)\n    if status_order:\n        search_condition_apply_get.append(ApplyGet.status_order == status_order)\n    if status_delete:\n        search_condition_apply_get.append(ApplyGet.status_delete == status_delete)\n    if start_time:\n        search_condition_apply_get.append(ApplyGet.create_time >= time_local_to_utc(start_time))\n    if end_time:\n        search_condition_apply_get.append(ApplyGet.create_time <= time_local_to_utc(end_time))\n\n    # pagination = get_apply_get_rows(page)\n    try:\n        pagination = ApplyGet.query. \\\n            filter(*search_condition_apply_get). \\\n            outerjoin(UserProfile, ApplyGet.user_id == UserProfile.user_id). \\\n            add_entity(UserProfile). \\\n            order_by(ApplyGet.id.desc()). \\\n            paginate(page, PER_PAGE_BACKEND, False)\n        db.session.commit()\n        return render_template('apply_get/list.html', title='apply_get_list', pagination=pagination, form=form)\n    except Exception as e:\n        db.session.rollback()\n        flash(e.message, category='warning')\n        return redirect(url_for('index'))\n\n\n@bp_apply_get.route('/info/<int:apply_get_id>/')\n@bp_apply_get.route('/info/<int:apply_get_id>/<int:page>/')\n@login_required\n@permission_order.require(http_exception=403)\ndef info(apply_get_id, page=1):\n    \"\"\"\n    提现申请信息\n    \"\"\"\n    apply_get_info = get_apply_get_row_by_id(apply_get_id)\n    # 没有信息\n    if not apply_get_info:\n        return redirect('apply_get.lists')\n    # 删除状态\n    if apply_get_info.status_delete == int(STATUS_DEL_OK):\n        return redirect('apply_get.lists')\n    apply_put_list = []\n    # 已经匹配, 显示匹配的信息\n    if apply_get_info.status_order > int(STATUS_ORDER_HANDING):\n        apply_put_list = get_get_match_order_rows(apply_get_id)\n\n    form = ApplyPutSearchForm(request.form)\n\n    user_id = request.args.get('user_id', '', type=int)\n    type_apply = request.args.get('type_apply', '', type=str)\n    money_apply = request.args.get('money_apply', '', type=str)\n    status_apply = request.args.get('status_apply', '', type=str)\n    status_order = request.args.get('status_order', '', type=str)\n    status_delete = request.args.get('status_delete', '', type=str)\n    min_money = request.args.get('min_money', '', type=str)\n    max_money = request.args.get('max_money', '', type=str)\n    start_time = request.args.get('start_time', '', type=str)\n    end_time = request.args.get('end_time', '', type=str)\n    op = request.args.get('op', 0, type=int)\n\n    form.user_id.data = user_id\n    form.type_apply.data = type_apply\n    form.money_apply.data = money_apply\n    form.status_apply.data = status_apply\n    form.status_order.data = status_order\n    form.status_delete.data = status_delete\n    form.min_money.data = min_money\n    form.max_money.data = max_money\n    form.start_time.data = start_time\n    form.end_time.data = end_time\n\n    search_condition_apply_put = [\n        ApplyPut.status_delete == STATUS_DEL_NO,\n        ApplyPut.status_order < STATUS_ORDER_COMPLETED,\n        ApplyPut.user_id != apply_get_info.user_id\n    ]\n    if user_id:\n        search_condition_apply_put.append(ApplyPut.user_id == user_id)\n    if min_money:\n        search_condition_apply_put.append(ApplyPut.money_apply >= min_money)\n    if max_money:\n        search_condition_apply_put.append(ApplyPut.money_apply <= max_money)\n    if start_time:\n        search_condition_apply_put.append(ApplyPut.create_time >= start_time)\n    if end_time:\n        search_condition_apply_put.append(ApplyPut.create_time <= end_time)\n\n    # pagination = get_apply_get_rows(page)\n    try:\n        pagination = ApplyPut.query. \\\n            filter(*search_condition_apply_put). \\\n            outerjoin(UserProfile, ApplyPut.user_id == UserProfile.user_id). \\\n            add_entity(UserProfile). \\\n            order_by(ApplyPut.id.desc()). \\\n            paginate(page, PER_PAGE_BACKEND, False)\n        db.session.commit()\n        return render_template(\n            'apply_get/info.html',\n            title='apply_get_info',\n            apply_get_info=apply_get_info,\n            apply_put_list=apply_put_list,\n            pagination=pagination,\n            form=form,\n            STATUS_ORDER_HANDING=STATUS_ORDER_HANDING,\n            STATUS_ORDER_COMPLETED=STATUS_ORDER_COMPLETED,\n        )\n    except Exception as e:\n        db.session.rollback()\n        flash(e.message, category='warning')\n        return redirect(url_for('index'))\n\n\n@bp_apply_get.route('/ajax/match/', methods=['GET', 'POST'])\n@login_required\n@permission_order.require(http_exception=403)\ndef ajax_match():\n    \"\"\"\n    提现申请匹配\n    :return:\n    \"\"\"\n    if request.method == 'POST' and request.is_xhr:\n        form = request.form\n        accept_split = form.get('accept_split', 0, type=int)\n        apply_get_id = form.get('apply_get_id', 0, type=int)\n        apply_put_ids = form.getlist('apply_put_id')\n\n        try:\n            result = apply_get_match(apply_get_id, apply_put_ids, accept_split)\n            if result == 1:\n                return json.dumps({'success': u'匹配成功'})\n            if result == 0:\n                return json.dumps({'error': u'匹配失败'})\n        except Exception as e:\n            return json.dumps({'error': e.message})\n    abort(404)\n\n\n@bp_apply_get.route('/add/', methods=['GET', 'POST'])\n@login_required\n@permission_order.require(http_exception=403)\ndef add():\n    \"\"\"\n    创建提现申请\n    :return:\n    \"\"\"\n    return render_template('apply_get/add.html', title='apply_get_add')\n\n\n@bp_apply_get.route('/ajax/del/', methods=['GET', 'POST'])\n@login_required\n@permission_order.require(http_exception=403)\ndef ajax_delete():\n    \"\"\"\n    删除提现申请\n    :return:\n    \"\"\"\n    if request.method == 'GET' and request.is_xhr:\n        apply_get_id = request.args.get('apply_get_id', 0, type=int)\n        if not apply_get_id:\n            return json.dumps({'error': u'删除失败'})\n\n        apply_get_info = get_apply_get_row_by_id(apply_get_id)\n        # 判断提现申请是否开始匹配\n        if apply_get_info.status_order != int(STATUS_ORDER_HANDING):\n            return json.dumps({'error': u'提现处理中，不能删除'})\n        current_time = datetime.utcnow()\n        apply_get_data = {\n            'status_delete': STATUS_DEL_OK,\n            'delete_time': current_time,\n            'update_time': current_time\n        }\n        result = edit_apply_get(apply_get_id, apply_get_data)\n        if result:\n            return json.dumps({'success': u'删除成功'})\n        else:\n            return json.dumps({'error': u'删除失败'})\n    abort(404)\n\n\n# @bp_apply_get.route('/stats/', methods=['GET', 'POST'])\n# @login_required\n# def stats():\n#     \"\"\"\n#     提现申请统计\n#     :return:\n#     \"\"\"\n#     return render_template('apply_get/stats.html', title='apply_get_stats')\n\n\n@bp_apply_get.route('/ajax_stats/', methods=['GET', 'POST'])\n@login_required\ndef ajax_stats():\n    \"\"\"\n    提现申请统计\n    :return:\n    \"\"\"\n    time_based = request.args.get('time_based', 'hour')\n    result_apply_get = apply_get_stats(time_based)\n\n    line_chart_data = {\n        'labels': [label for label, _ in result_apply_get],\n        'datasets': [\n            {\n                'label': u'提现申请',\n                'backgroundColor': 'rgba(220,220,220,0.5)',\n                'borderColor': 'rgba(220,220,220,1)',\n                'pointBackgroundColor': 'rgba(220,220,220,1)',\n                'pointBorderColor': '#fff',\n                'pointBorderWidth': 2,\n                'data': [data for _, data in result_apply_get]\n            }\n        ]\n    }\n    return json.dumps(line_chart_data, default=json_default)\n"
  },
  {
    "path": "app_backend/views/apply_put.py",
    "content": "#!/usr/bin/env python\n# encoding: utf-8\n\n\"\"\"\n@author: zhanghe\n@software: PyCharm\n@file: apply_put.py\n@time: 2017/4/13 下午9:32\n\"\"\"\n\n\nfrom datetime import datetime\nimport json\nfrom flask import Blueprint\nfrom flask import abort\nfrom flask import redirect\nfrom flask import render_template, request, flash, g\nfrom flask import url_for\nfrom flask_login import current_user, login_required\n\nfrom app_backend import app\nfrom app_backend.api.apply_get import get_apply_get_rows, get_apply_get_rows_by_ids, edit_apply_get\n\nfrom app_backend.forms.admin import AdminProfileForm\nfrom app_backend.forms.apply_get import ApplyGetSearchForm\nfrom app_backend.models import User, ApplyGet, UserProfile, ApplyPut\nfrom app_backend.api.apply_put import get_apply_put_rows, get_apply_put_row, get_apply_put_row_by_id, edit_apply_put, apply_put_match, \\\n    apply_put_stats\nfrom app_backend.api.order import get_order_row, get_order_rows, get_order_lists, add_order, get_put_match_order_rows\nfrom app_backend.forms.apply_put import ApplyPutSearchForm\n\nfrom app_common.maps.status_delete import *\nfrom app_common.maps.status_order import *\nfrom app_common.maps.status_pay import *\nfrom app_common.maps.status_rec import *\nfrom app_common.maps.status_audit import *\nfrom app_common.tools import json_default\nfrom app_common.tools.date_time import time_local_to_utc\n\nfrom app_backend.permissions import permission_order\n\nfrom app_backend.database import db\n\n\nPER_PAGE_BACKEND = app.config['PER_PAGE_BACKEND']\n\n\nbp_apply_put = Blueprint('apply_put', __name__, url_prefix='/apply_put')\n\n\n@bp_apply_put.route('/list/')\n@bp_apply_put.route('/list/<int:page>/')\n@login_required\n@permission_order.require(http_exception=403)\ndef lists(page=1):\n    \"\"\"\n    投资申请列表\n    \"\"\"\n    form = ApplyPutSearchForm(request.form)\n\n    apply_put_id = request.args.get('apply_put_id', '', type=int)\n    user_id = request.args.get('user_id', '', type=int)\n    type_apply = request.args.get('type_apply', '', type=str)\n    money_apply = request.args.get('money_apply', '', type=str)\n    status_apply = request.args.get('status_apply', '', type=str)\n    status_order = request.args.get('status_order', '', type=str)\n    status_delete = request.args.get('status_delete', '', type=str)\n    start_time = request.args.get('start_time', '', type=str)\n    end_time = request.args.get('end_time', '', type=str)\n    op = request.args.get('op', 0, type=int)\n\n    form.apply_put_id.data = apply_put_id\n    form.user_id.data = user_id\n    form.type_apply.data = type_apply\n    form.money_apply.data = money_apply\n    form.status_apply.data = status_apply\n    form.status_order.data = status_order\n    form.status_delete.data = status_delete\n    form.start_time.data = start_time\n    form.end_time.data = end_time\n\n    search_condition_apply_put = [\n        ApplyPut.status_delete == STATUS_DEL_NO,\n    ]\n    if apply_put_id:\n        search_condition_apply_put.append(ApplyPut.id == apply_put_id)\n    if user_id:\n        search_condition_apply_put.append(ApplyPut.user_id == user_id)\n    if status_apply:\n        search_condition_apply_put.append(ApplyPut.status_apply == status_apply)\n    if status_order:\n        search_condition_apply_put.append(ApplyPut.status_order == status_order)\n    if status_delete:\n        search_condition_apply_put.append(ApplyPut.status_delete == status_delete)\n    if start_time:\n        search_condition_apply_put.append(ApplyPut.create_time >= time_local_to_utc(start_time))\n    if end_time:\n        search_condition_apply_put.append(ApplyPut.create_time <= time_local_to_utc(end_time))\n\n    # pagination = get_apply_put_rows(page)\n    try:\n        pagination = ApplyPut.query. \\\n            filter(*search_condition_apply_put). \\\n            outerjoin(UserProfile, ApplyPut.user_id == UserProfile.user_id). \\\n            add_entity(UserProfile). \\\n            order_by(ApplyPut.id.desc()). \\\n            paginate(page, PER_PAGE_BACKEND, False)\n        db.session.commit()\n        return render_template('apply_put/list.html', title='apply_put_list', pagination=pagination, form=form)\n    except Exception as e:\n        db.session.rollback()\n        flash(e.message, category='warning')\n        return redirect(url_for('index'))\n\n\n@bp_apply_put.route('/info/<int:apply_put_id>/')\n@bp_apply_put.route('/info/<int:apply_put_id>/<int:page>/')\n@login_required\n@permission_order.require(http_exception=403)\ndef info(apply_put_id, page=1):\n    \"\"\"\n    投资申请信息\n    \"\"\"\n    apply_put_info = get_apply_put_row_by_id(apply_put_id)\n    # 没有信息\n    if not apply_put_info:\n        return redirect('apply_put.lists')\n    # 删除状态\n    if apply_put_info.status_delete == int(STATUS_DEL_OK):\n        return redirect('apply_put.lists')\n    apply_get_list = []\n    # 已经匹配, 显示匹配的信息\n    if apply_put_info.status_order > int(STATUS_ORDER_HANDING):\n        apply_get_list = get_put_match_order_rows(apply_put_id)\n\n    form = ApplyGetSearchForm(request.form)\n\n    user_id = request.args.get('user_id', '', type=int)\n    type_apply = request.args.get('type_apply', '', type=str)\n    money_apply = request.args.get('money_apply', '', type=str)\n    status_apply = request.args.get('status_apply', '', type=str)\n    status_order = request.args.get('status_order', '', type=str)\n    status_delete = request.args.get('status_delete', '', type=str)\n    min_money = request.args.get('min_money', '', type=str)\n    max_money = request.args.get('max_money', '', type=str)\n    start_time = request.args.get('start_time', '', type=str)\n    end_time = request.args.get('end_time', '', type=str)\n    op = request.args.get('op', 0, type=int)\n\n    form.user_id.data = user_id\n    form.type_apply.data = type_apply\n    form.money_apply.data = money_apply\n    form.status_apply.data = status_apply\n    form.status_order.data = status_order\n    form.status_delete.data = status_delete\n    form.min_money.data = min_money\n    form.max_money.data = max_money\n    form.start_time.data = start_time\n    form.end_time.data = end_time\n\n    search_condition_apply_get = [\n        ApplyGet.status_delete == STATUS_DEL_NO,\n        ApplyGet.status_order < STATUS_ORDER_COMPLETED,\n        ApplyGet.user_id != apply_put_info.user_id\n    ]\n    if user_id:\n        search_condition_apply_get.append(ApplyGet.user_id == user_id)\n    if min_money:\n        search_condition_apply_get.append(ApplyGet.money_apply >= min_money)\n    if max_money:\n        search_condition_apply_get.append(ApplyGet.money_apply <= max_money)\n    if start_time:\n        search_condition_apply_get.append(ApplyGet.create_time >= start_time)\n    if end_time:\n        search_condition_apply_get.append(ApplyGet.create_time <= end_time)\n\n    # pagination = get_apply_get_rows(page)\n    try:\n        pagination = ApplyGet.query. \\\n            filter(*search_condition_apply_get). \\\n            outerjoin(UserProfile, ApplyGet.user_id == UserProfile.user_id). \\\n            add_entity(UserProfile). \\\n            order_by(ApplyGet.id.desc()). \\\n            paginate(page, PER_PAGE_BACKEND, False)\n\n        return render_template(\n            'apply_put/info.html',\n            title='apply_put_info',\n            apply_put_info=apply_put_info,\n            apply_get_list=apply_get_list,\n            pagination=pagination,\n            form=form,\n            STATUS_ORDER_HANDING=STATUS_ORDER_HANDING,\n            STATUS_ORDER_COMPLETED=STATUS_ORDER_COMPLETED,\n        )\n    except Exception as e:\n        db.session.rollback()\n        flash(e.message, category='warning')\n        return redirect(url_for('index'))\n\n\n@bp_apply_put.route('/ajax/match/', methods=['GET', 'POST'])\n@login_required\n@permission_order.require(http_exception=403)\ndef ajax_match():\n    \"\"\"\n    投资申请匹配\n    :return:\n    \"\"\"\n    if request.method == 'POST' and request.is_xhr:\n        form = request.form\n        accept_split = form.get('accept_split', 0, type=int)\n        apply_put_id = form.get('apply_put_id', 0, type=int)\n        apply_get_ids = form.getlist('apply_get_id')\n\n        try:\n            result = apply_put_match(apply_put_id, apply_get_ids, accept_split)\n            if result == 1:\n                return json.dumps({'success': u'匹配成功'})\n            if result == 0:\n                return json.dumps({'error': u'匹配失败'})\n        except Exception as e:\n            return json.dumps({'error': e.message})\n    abort(404)\n\n\n@bp_apply_put.route('/add/', methods=['GET', 'POST'])\n@login_required\n@permission_order.require(http_exception=403)\ndef add():\n    \"\"\"\n    创建投资申请\n    :return:\n    \"\"\"\n    return render_template('apply_put/add.html', title='apply_put_add')\n\n\n@bp_apply_put.route('/ajax/del/', methods=['GET', 'POST'])\n@login_required\n@permission_order.require(http_exception=403)\ndef ajax_delete():\n    \"\"\"\n    删除投资申请\n    :return:\n    \"\"\"\n    if request.method == 'GET' and request.is_xhr:\n        apply_put_id = request.args.get('apply_put_id', 0, type=int)\n        if not apply_put_id:\n            return json.dumps({'error': u'删除失败'})\n\n        apply_put_info = get_apply_put_row_by_id(apply_put_id)\n        # 判断投资申请是否开始匹配\n        if apply_put_info.status_order != int(STATUS_ORDER_HANDING):\n            return json.dumps({'error': u'投资处理中，不能删除'})\n        current_time = datetime.utcnow()\n        apply_put_data = {\n            'status_delete': STATUS_DEL_OK,\n            'delete_time': current_time,\n            'update_time': current_time\n        }\n        result = edit_apply_put(apply_put_id, apply_put_data)\n        if result:\n            return json.dumps({'success': u'删除成功'})\n        else:\n            return json.dumps({'error': u'删除失败'})\n    abort(404)\n\n\n@bp_apply_put.route('/stats/', methods=['GET', 'POST'])\n@login_required\n@permission_order.require(http_exception=403)\ndef stats():\n    \"\"\"\n    投资申请统计\n    :return:\n    \"\"\"\n    return render_template('apply_put/stats.html', title='apply_put_stats')\n\n\n@bp_apply_put.route('/ajax_stats/', methods=['GET', 'POST'])\n@login_required\ndef ajax_stats():\n    \"\"\"\n    投资申请统计\n    :return:\n    \"\"\"\n    time_based = request.args.get('time_based', 'hour')\n    result_apply_put = apply_put_stats(time_based)\n\n    line_chart_data = {\n        'labels': [label for label, _ in result_apply_put],\n        'datasets': [\n            {\n                'label': u'投资申请',\n                'backgroundColor': 'rgba(220,220,220,0.5)',\n                'borderColor': 'rgba(220,220,220,1)',\n                'pointBackgroundColor': 'rgba(220,220,220,1)',\n                'pointBorderColor': '#fff',\n                'pointBorderWidth': 2,\n                'data': [data for _, data in result_apply_put]\n            }\n        ]\n    }\n    return json.dumps(line_chart_data, default=json_default)\n"
  },
  {
    "path": "app_backend/views/complaint.py",
    "content": "#!/usr/bin/env python\n# encoding: utf-8\n\n\"\"\"\n@author: zhanghe\n@software: PyCharm\n@file: complaint.py\n@time: 2017/4/30 下午10:31\n\"\"\"\n\n\nimport json\nfrom datetime import datetime\n\nfrom flask import abort\nfrom flask import redirect\nfrom flask import render_template, request, flash, g\nfrom flask import url_for\nfrom flask_login import current_user, login_required\nimport flask_excel as excel\nfrom sqlalchemy.orm import aliased\n\nfrom app_backend import app\nfrom app_backend.database import db\nfrom app_backend.forms.admin import AdminProfileForm\nfrom app_backend.models import User, UserProfile, Complaint\nfrom app_backend.api.order import get_order_rows, get_order_row\nfrom app_backend.forms.order import OrderSearchForm\nfrom app_backend.api.complaint import edit_complaint, get_complaint_row_by_id\n\nfrom app_backend.forms.complaint import ComplaintReplyForm\n\nfrom flask import Blueprint\n\nfrom app_backend.permissions import permission_msg\nfrom app_common.maps.status_delete import STATUS_DEL_OK\nfrom app_common.maps.status_reply import STATUS_REPLY_DICT, STATUS_REPLY_SUCCESS\n\nPER_PAGE_BACKEND = app.config['PER_PAGE_BACKEND']\n\nbp_complaint = Blueprint('complaint', __name__, url_prefix='/complaint')\n\n\n@bp_complaint.route('/list/', methods=['GET', 'POST'])\n@bp_complaint.route('/list/<int:page>/', methods=['GET', 'POST'])\n@login_required\n@permission_msg.require(http_exception=403)\ndef lists(page=1):\n    \"\"\"\n    投诉列表\n    :return:\n    \"\"\"\n    condition = {\n        'status_reply': 0,  # 默认未处理\n        'status_delete': 0\n    }\n    # 回复状态\n    status_reply = request.args.get('status_reply', 0, type=int)\n    if status_reply in STATUS_REPLY_DICT:\n        condition['status_reply'] = status_reply\n\n    # pagination = get_complaint_rows(page, **condition)\n    # return render_template('complaint/list.html', title='complaint_list', pagination=pagination)\n\n    # 多次连接同一张表，需要别名\n    user_profile_put = aliased(UserProfile)\n    user_profile_get = aliased(UserProfile)\n    try:\n        pagination = Complaint.query. \\\n            filter_by(**condition). \\\n            outerjoin(user_profile_put, Complaint.send_user_id == user_profile_put.user_id). \\\n            add_entity(user_profile_put). \\\n            outerjoin(user_profile_get, Complaint.receive_user_id == user_profile_get.user_id). \\\n            add_entity(user_profile_get). \\\n            order_by(Complaint.id.desc()). \\\n            paginate(page, PER_PAGE_BACKEND, False)\n        db.session.commit()\n        return render_template('complaint/list.html', title='complaint_list', pagination=pagination)\n    except Exception as e:\n        db.session.rollback()\n        flash(e.message, category='warning')\n        return redirect(url_for('index'))\n\n\n@bp_complaint.route('/reply/<int:complaint_id>/', methods=['GET', 'POST'])\n@login_required\n@permission_msg.require(http_exception=403)\ndef reply(complaint_id):\n    \"\"\"\n    投诉处理\n    :param complaint_id:\n    :return:\n    \"\"\"\n    complaint_info = get_complaint_row_by_id(complaint_id)\n    form = ComplaintReplyForm(request.form)\n    if complaint_info:\n        if request.method == 'GET':\n            form.send_user_id.data = complaint_info.send_user_id\n            form.receive_user_id.data = complaint_info.receive_user_id\n            form.content.data = complaint_info.content\n    if request.method == 'POST':\n        if form.validate_on_submit():\n            current_time = datetime.utcnow()\n            complaint_data = {\n                'content_reply': form.content_reply.data,\n                'status_reply': STATUS_REPLY_SUCCESS,\n                'reply_time': current_time,\n                'update_time': current_time,\n            }\n            result = edit_complaint(complaint_id, complaint_data)\n            if result:\n                flash(u'处理投诉成功', 'success')\n                return redirect(url_for('.lists', msg_type='send'))\n            else:\n                flash(u'处理投诉失败', 'warning')\n        flash(u'处理投诉失败', 'warning')\n    return render_template('complaint/reply.html', title='complaint_reply', form=form)\n\n\n@bp_complaint.route('/ajax/del/', methods=['GET', 'POST'])\n@login_required\n@permission_msg.require(http_exception=403)\ndef ajax_delete():\n    \"\"\"\n    删除投诉\n    :return:\n    \"\"\"\n    if request.method == 'GET' and request.is_xhr:\n        msg_id = request.args.get('msg_id', 0, type=int)\n        if not msg_id:\n            return json.dumps({'error': u'删除失败'})\n        current_time = datetime.utcnow()\n        msg_data = {\n            'status_delete': STATUS_DEL_OK,\n            'delete_time': current_time,\n            'update_time': current_time\n        }\n        result = edit_complaint(msg_id, msg_data)\n        if result == 1:\n            return json.dumps({'success': u'删除成功'})\n        if result == 0:\n            return json.dumps({'error': u'删除失败'})\n    abort(404)\n"
  },
  {
    "path": "app_backend/views/message.py",
    "content": "#!/usr/bin/env python\n# encoding: utf-8\n\n\"\"\"\n@author: zhanghe\n@software: PyCharm\n@file: message.py\n@time: 2017/5/1 上午2:17\n\"\"\"\n\nimport json\nfrom datetime import datetime\n\nfrom flask import abort\nfrom flask import redirect\nfrom flask import render_template, request, flash, g\nfrom flask import url_for\nfrom flask_login import current_user, login_required\nimport flask_excel as excel\nfrom sqlalchemy.orm import aliased\n\nfrom app_backend import app\nfrom app_backend.forms.admin import AdminProfileForm\nfrom app_backend.models import User, UserProfile, Message\nfrom app_backend.api.message import edit_message\n\nfrom flask import Blueprint\nfrom app_backend.database import db\nfrom app_common.maps.status_delete import STATUS_DEL_OK\nfrom app_backend.permissions import permission_msg\n\n\nPER_PAGE_BACKEND = app.config['PER_PAGE_BACKEND']\n\nbp_message = Blueprint('message', __name__, url_prefix='/message')\n\n\n@bp_message.route('/list/', methods=['GET', 'POST'])\n@bp_message.route('/list/<int:page>/', methods=['GET', 'POST'])\n@login_required\n@permission_msg.require(http_exception=403)\ndef lists(page=1):\n    \"\"\"\n    留言列表\n    \"\"\"\n    # 多次连接同一张表，需要别名\n    user_profile_put = aliased(UserProfile)\n    user_profile_get = aliased(UserProfile)\n\n    condition = {\n        'status_delete': 0\n    }\n    try:\n        pagination = Message.query. \\\n            filter_by(**condition). \\\n            outerjoin(user_profile_put, Message.send_user_id == user_profile_put.user_id). \\\n            add_entity(user_profile_put). \\\n            outerjoin(user_profile_get, Message.receive_user_id == user_profile_get.user_id). \\\n            add_entity(user_profile_get). \\\n            order_by(Message.id.desc()). \\\n            paginate(page, PER_PAGE_BACKEND, False)\n        db.session.commit()\n        return render_template('message/list.html', title='message_list', pagination=pagination)\n    except Exception as e:\n        db.session.rollback()\n        flash(e.message, category='warning')\n        return redirect(url_for('index'))\n\n\n@bp_message.route('/ajax/del/', methods=['GET', 'POST'])\n@login_required\n@permission_msg.require(http_exception=403)\ndef ajax_delete():\n    \"\"\"\n    删除留言\n    :return:\n    \"\"\"\n    if request.method == 'GET' and request.is_xhr:\n        msg_id = request.args.get('msg_id', 0, type=int)\n        if not msg_id:\n            return json.dumps({'error': u'删除失败'})\n        current_time = datetime.utcnow()\n        msg_data = {\n            'status_delete': STATUS_DEL_OK,\n            'delete_time': current_time,\n            'update_time': current_time\n        }\n        result = edit_message(msg_id, msg_data)\n        if result == 1:\n            return json.dumps({'success': u'删除成功'})\n        if result == 0:\n            return json.dumps({'error': u'删除失败'})\n    abort(404)\n"
  },
  {
    "path": "app_backend/views/order.py",
    "content": "#!/usr/bin/env python\n# encoding: utf-8\n\n\"\"\"\n@author: zhanghe\n@software: PyCharm\n@file: order.py\n@time: 2017/4/24 下午10:49\n\"\"\"\n\n\nimport json\n\nfrom flask import abort\nfrom sqlalchemy.orm import aliased\nfrom datetime import datetime\nfrom flask import redirect\nfrom flask import render_template, request, flash, g\nfrom flask import url_for\nfrom flask_login import current_user, login_required\nimport flask_excel as excel\n\nfrom app_backend import app\nfrom app_backend.forms.admin import AdminProfileForm\nfrom app_backend.models import User, UserProfile, Order\nfrom app_backend.api.order import get_order_rows, get_order_row, order_stats, edit_order, get_order_row_by_id\nfrom app_backend.api.apply_put import edit_apply_put, get_apply_put_row_by_id\nfrom app_backend.api.apply_get import edit_apply_get, get_apply_get_row_by_id\nfrom app_backend.forms.order import OrderSearchForm\nfrom app_common.maps.status_order import STATUS_ORDER_HANDING, STATUS_ORDER_PROCESSING\n\nfrom flask import Blueprint\n\nfrom app_common.maps.status_delete import STATUS_DEL_NO, STATUS_DEL_OK\nfrom app_common.tools import json_default\nfrom app_common.tools.date_time import time_local_to_utc\n\nfrom app_backend.permissions import permission_order\nfrom app_backend.database import db\n\nPER_PAGE_BACKEND = app.config['PER_PAGE_BACKEND']\n\nbp_order = Blueprint('order', __name__, url_prefix='/order')\n\n\n@bp_order.route('/list/')\n@bp_order.route('/list/<int:page>/')\n@login_required\n@permission_order.require(http_exception=403)\ndef lists(page=1):\n    \"\"\"\n    订单列表\n    \"\"\"\n    form = OrderSearchForm(request.form)\n\n    order_id = request.args.get('order_id', '', type=int)\n    apply_put_id = request.args.get('apply_put_id', '', type=int)\n    apply_get_id = request.args.get('apply_get_id', '', type=int)\n    apply_put_uid = request.args.get('apply_put_uid', '', type=int)\n    apply_get_uid = request.args.get('apply_get_uid', '', type=int)\n    status_audit = request.args.get('status_audit', '', type=str)\n    status_pay = request.args.get('status_pay', '', type=str)\n    status_rec = request.args.get('status_rec', '', type=str)\n    start_time = request.args.get('start_time', '', type=str)\n    end_time = request.args.get('end_time', '', type=str)\n    op = request.args.get('op', 0, type=int)\n\n    form.order_id.data = order_id\n    form.apply_put_id.data = apply_put_id\n    form.apply_get_id.data = apply_get_id\n    form.apply_put_uid.data = apply_put_uid\n    form.apply_get_uid.data = apply_get_uid\n    form.status_audit.data = status_audit\n    form.status_pay.data = status_pay\n    form.status_rec.data = status_rec\n    form.start_time.data = start_time\n    form.end_time.data = end_time\n\n    # 搜索条件\n    search_condition_order = [\n        Order.status_delete == STATUS_DEL_NO,\n    ]\n\n    if order_id:\n        search_condition_order.append(Order.id == order_id)\n    if apply_put_id:\n        search_condition_order.append(Order.apply_put_id == apply_put_id)\n    if apply_get_id:\n        search_condition_order.append(Order.apply_get_id == apply_get_id)\n    if apply_put_uid:\n        search_condition_order.append(Order.apply_put_uid == apply_put_uid)\n    if apply_get_uid:\n        search_condition_order.append(Order.apply_get_uid == apply_get_uid)\n    if status_audit:\n        search_condition_order.append(Order.status_audit == status_audit)\n    if status_pay:\n        search_condition_order.append(Order.status_pay == status_pay)\n    if status_rec:\n        search_condition_order.append(Order.status_rec == status_rec)\n    if start_time:\n        search_condition_order.append(Order.create_time >= time_local_to_utc(start_time))\n    if end_time:\n        search_condition_order.append(Order.create_time <= time_local_to_utc(end_time))\n\n    # 多次连接同一张表，需要别名\n    user_profile_put = aliased(UserProfile)\n    user_profile_get = aliased(UserProfile)\n\n    try:\n        pagination = Order.query. \\\n            filter(*search_condition_order). \\\n            outerjoin(user_profile_put, Order.apply_put_uid == user_profile_put.user_id). \\\n            add_entity(user_profile_put). \\\n            outerjoin(user_profile_get, Order.apply_get_uid == user_profile_get.user_id). \\\n            add_entity(user_profile_get). \\\n            order_by(Order.id.desc()). \\\n            paginate(page, PER_PAGE_BACKEND, False)\n        db.session.commit()\n        return render_template('order/list.html', title='order_list', pagination=pagination, form=form)\n    except Exception as e:\n        db.session.rollback()\n        flash(e.message, category='warning')\n        return redirect(url_for('index'))\n\n\n@bp_order.route('/add/', methods=['GET', 'POST'])\n@login_required\n@permission_order.require(http_exception=403)\ndef add():\n    \"\"\"\n    创建订单\n    :return:\n    \"\"\"\n    pass\n\n\n@bp_order.route('/del/', methods=['GET', 'POST'])\n@login_required\n@permission_order.require(http_exception=403)\ndef delete():\n    \"\"\"\n    删除订单\n    :return:\n    \"\"\"\n    pass\n\n\n@bp_order.route('/stats/', methods=['GET', 'POST'])\n@login_required\n@permission_order.require(http_exception=403)\ndef stats():\n    \"\"\"\n    订单统计\n    :return:\n    \"\"\"\n    return render_template('order/stats.html', title='order_stats')\n\n\n@bp_order.route('/ajax_stats/', methods=['GET', 'POST'])\n@login_required\ndef ajax_stats():\n    \"\"\"\n    订单金额统计\n    :return:\n    \"\"\"\n    time_based = request.args.get('time_based', 'hour')\n    result_order = order_stats(time_based)\n\n    line_chart_data = {\n        'labels': [label for label, _ in result_order],\n        'datasets': [\n            {\n                'label': u'订单金额',\n                'backgroundColor': 'rgba(220,220,220,0.5)',\n                'borderColor': 'rgba(220,220,220,1)',\n                'pointBackgroundColor': 'rgba(220,220,220,1)',\n                'pointBorderColor': '#fff',\n                'pointBorderWidth': 2,\n                'data': [data for _, data in result_order]\n            }\n        ]\n    }\n    return json.dumps(line_chart_data, default=json_default)\n\n\n@bp_order.route('/ajax/audit/', methods=['GET', 'POST'])\n@login_required\n@permission_order.require(http_exception=403)\ndef ajax_audit():\n    \"\"\"\n    订单审核\n    :return:\n    \"\"\"\n    if 1:\n        return json.dumps({'success': u'审核成功'})\n    else:\n        return json.dumps({'error': u'审核失败'})\n\n\n@bp_order.route('/ajax/del/', methods=['GET', 'POST'])\n@login_required\n@permission_order.require(http_exception=403)\ndef ajax_delete():\n    \"\"\"\n    删除订单\n    :return:\n    \"\"\"\n    if request.method == 'GET' and request.is_xhr:\n        order_id = request.args.get('order_id', 0, type=int)\n        if not order_id:\n            return json.dumps({'error': u'参数错误，删除失败'})\n        order_info = get_order_row_by_id(order_id)\n        if not order_info:\n            return json.dumps({'error': u'订单不存在，删除失败'})\n        if order_info.status_delete == int(STATUS_DEL_OK):\n            return json.dumps({'error': u'订单已删除，不能重复删除'})\n        current_time = datetime.utcnow()\n        # 修改订单删除状态\n        order_data = {\n            'status_delete': STATUS_DEL_OK,\n            'delete_time': current_time,\n            'update_time': current_time\n        }\n        result = edit_order(order_id, order_data)\n\n        # 还原提现申请订单金额\n        apply_get_info = get_apply_get_row_by_id(order_info.apply_get_id)\n\n        last_money = apply_get_info.money_order - order_info.money\n        status_order = STATUS_ORDER_PROCESSING if last_money > 0 else STATUS_ORDER_HANDING\n\n        apply_get_data = {\n            'money_order': last_money,\n            'status_order': status_order,\n            'update_time': current_time\n        }\n\n        edit_apply_get(order_info.apply_get_id, apply_get_data)\n\n        # 还原投资申请订单金额\n        apply_put_info = get_apply_put_row_by_id(order_info.apply_put_id)\n\n        last_money = apply_put_info.money_order - order_info.money\n        status_order = STATUS_ORDER_PROCESSING if last_money > 0 else STATUS_ORDER_HANDING\n\n        apply_put_data = {\n            'money_order': last_money,\n            'status_order': status_order,\n            'update_time': current_time\n        }\n\n        edit_apply_put(order_info.apply_put_id, apply_put_data)\n\n        if result:\n            return json.dumps({'success': u'删除成功'})\n        else:\n            return json.dumps({'error': u'删除失败'})\n    abort(404)\n"
  },
  {
    "path": "app_backend/views/scheduling.py",
    "content": "#!/usr/bin/env python\n# encoding: utf-8\n\n\"\"\"\n@author: zhanghe\n@software: PyCharm\n@file: scheduling.py\n@time: 2017/6/29 下午8:45\n\"\"\"\n\n\nfrom datetime import datetime\nfrom flask import redirect\nfrom flask import render_template, request, flash, g\nfrom flask import url_for\nfrom flask_login import current_user, login_required\nfrom sqlalchemy.orm import aliased\n\nfrom app_backend import app\nfrom app_backend.api.scheduling import give_scheduling\nfrom app_backend.models import User, UserProfile, SchedulingItem\nfrom app_backend.api.active_item import get_active_item_rows\nfrom app_common.maps.type_scheduling import *\nfrom app_backend.forms.scheduling import SchedulingAddForm\nfrom app_backend.database import db\n\nPER_PAGE_BACKEND = app.config['PER_PAGE_BACKEND']\n\nfrom flask import Blueprint\n\n\nbp_scheduling = Blueprint('scheduling', __name__, url_prefix='/scheduling')\n\n\n@bp_scheduling.route('/list/')\n@bp_scheduling.route('/list/<int:page>/')\n@login_required\ndef lists(page=1):\n    \"\"\"\n    排单列表\n    \"\"\"\n    # （1：用户排单、2：系统发送）\n    scheduling_type = request.args.get('scheduling_list', 0, int)\n\n    # 多次连接同一张表，需要别名\n    user_profile_put = aliased(UserProfile)\n    user_profile_get = aliased(UserProfile)\n\n    if scheduling_type == 1:\n        condition = [\n            SchedulingItem.type == TYPE_SCHEDULING_USER\n        ]\n    elif scheduling_type == 2:\n        condition = [\n            SchedulingItem.type == TYPE_SCHEDULING_GIVE\n        ]\n    else:\n        condition = []\n\n    try:\n        pagination = SchedulingItem.query. \\\n            outerjoin(user_profile_put, SchedulingItem.user_id == user_profile_put.user_id). \\\n            add_entity(user_profile_put). \\\n            outerjoin(user_profile_get, SchedulingItem.sc_id == user_profile_get.user_id). \\\n            add_entity(user_profile_get). \\\n            filter(*condition). \\\n            order_by(SchedulingItem.id.desc()). \\\n            paginate(page, PER_PAGE_BACKEND, False)\n        db.session.commit()\n        return render_template('scheduling/list.html', title='scheduling_list', pagination=pagination)\n    except Exception as e:\n        db.session.rollback()\n        flash(e.message, category='warning')\n        return redirect(url_for('index'))\n\n\n@bp_scheduling.route('/add/', methods=['GET', 'POST'])\n@login_required\ndef add():\n    \"\"\"\n    添加排单记录\n    :return:\n    \"\"\"\n    user_id = request.args.get('user_id', '', type=int)\n\n    form = SchedulingAddForm(request.form)\n\n    # 初始化表单的值\n    if user_id:\n        form.user_id.data = user_id\n    if not form.amount.data:\n        form.amount.data = 1\n\n    if request.method == 'POST':\n        if form.validate_on_submit():\n            # 赠送排单数量\n            try:\n                result = give_scheduling(form.user_id.data, form.amount.data)\n                if result:\n                    flash(u'赠送排单数量操作成功', 'success')\n                return redirect(url_for('.lists'))\n            except Exception as e:\n                flash(e.message or u'赠送排单数量操作失败', 'warning')\n        # 闪现消息 success info warning danger\n        # flash(form.errors, 'warning')  # 调试打开\n    return render_template('scheduling/add.html', title='scheduling_add', form=form)\n\n\n@bp_scheduling.route('/del/', methods=['GET', 'POST'])\n@login_required\ndef delete():\n    \"\"\"\n    删除排单\n    :return:\n    \"\"\"\n    pass\n\n\n@bp_scheduling.route('/stats/', methods=['GET', 'POST'])\n@login_required\ndef stats():\n    \"\"\"\n    排单统计\n    :return:\n    \"\"\"\n    pass\n"
  },
  {
    "path": "app_backend/views/score.py",
    "content": "#!/usr/bin/env python\n# encoding: utf-8\n\n\"\"\"\n@author: zhanghe\n@software: PyCharm\n@file: score.py\n@time: 2017/4/25 下午1:25\n\"\"\"\n\n\nfrom datetime import datetime\nfrom flask import redirect\nfrom flask import render_template, request, flash, g\nfrom flask import url_for\nfrom flask_login import current_user, login_required\n\nfrom app_backend import app\nfrom app_backend.api.score import get_score_rows\n\nfrom flask import Blueprint\n\n\nbp_score = Blueprint('score', __name__, url_prefix='/score')\n\n\n@bp_score.route('/list/')\n@bp_score.route('/list/<int:page>/')\n@login_required\ndef lists(page=1):\n    \"\"\"\n    积分列表\n    \"\"\"\n\n    pagination = get_score_rows(page)\n    return render_template('score/list.html', title='score_list', pagination=pagination)\n\n\n@bp_score.route('/add/', methods=['GET', 'POST'])\n@login_required\ndef add():\n    \"\"\"\n    创建积分\n    :return:\n    \"\"\"\n    pass\n\n\n@bp_score.route('/del/', methods=['GET', 'POST'])\n@login_required\ndef delete():\n    \"\"\"\n    删除积分\n    :return:\n    \"\"\"\n    pass\n\n\n@bp_score.route('/stats/', methods=['GET', 'POST'])\n@login_required\ndef stats():\n    \"\"\"\n    积分统计\n    :return:\n    \"\"\"\n    return render_template('score/stats.html', title='score_stats')\n"
  },
  {
    "path": "app_backend/views/settings.py",
    "content": "#!/usr/bin/env python\n# encoding: utf-8\n\n\"\"\"\n@author: zhanghe\n@software: PyCharm\n@file: settings.py\n@time: 2017/4/30 下午9:11\n\"\"\"\n\n\nimport json\nfrom decimal import Decimal\nfrom datetime import datetime\n\nfrom flask import abort\nfrom flask import redirect\nfrom flask import render_template, request, flash, g\nfrom flask import url_for\nfrom flask_login import current_user, login_required\n\nfrom app_backend import app\nfrom app_backend.api.score import get_score_rows\n\nfrom app_backend.forms.settings import SwitchForm, UserForm, OrderForm, ApplyPutForm, ApplyGetForm, InterestForm\nfrom app_backend.tools.config_manage import get_conf, set_conf\n\nfrom app_backend.tools.config_manage import clean_conf\nfrom flask import Blueprint\n\nfrom app_backend.permissions import permission_sys\n\n\nbp_settings = Blueprint('settings', __name__, url_prefix='/settings')\n\n\n@bp_settings.route('/ajax_clean/', methods=['GET', 'POST'])\n@login_required\n@permission_sys.require(http_exception=403)\ndef ajax_clean():\n    if request.method == 'GET' and request.is_xhr:\n        result = clean_conf()\n        if result:\n            return json.dumps({'success': u'还原配置成功'})\n        else:\n            return json.dumps({'error': u'还原配置失败'})\n    abort(404)\n\n\n@bp_settings.route('/switch/', methods=['GET', 'POST'])\n@login_required\n@permission_sys.require(http_exception=403)\ndef switch():\n    \"\"\"\n    开关配置\n    SWITCH_EXPORT = OFF         # 导出\n\n    SWITCH_REG_ACCOUNT = ON     # 用户账号注册\n    SWITCH_REG_PHONE = OFF      # 用户手机注册\n    SWITCH_REG_EMAIL = OFF      # 用户邮箱注册\n\n    SWITCH_REG_THREE_PART = OFF     # 第三方平台注册\n\n    SWITCH_LOGIN_ACCOUNT = ON   # 用户账号登录\n    SWITCH_LOGIN_PHONE = ON     # 用户手机登录\n    SWITCH_LOGIN_EMAIL = ON     # 用户邮箱登录\n\n    SWITCH_LOGIN_THREE_PART = OFF     # 第三方平台登录\n    :return:\n    \"\"\"\n    form = SwitchForm(request.form)\n    if request.method == 'GET':\n        load_dict = {\n            'ON': True,\n            'OFF': False,\n            True: True,\n            False: False\n        }\n        form.SWITCH_EXPORT.data = load_dict.get(get_conf('SWITCH_EXPORT'))\n\n        form.SWITCH_REG_ACCOUNT.data = load_dict.get(get_conf('SWITCH_REG_ACCOUNT'))\n        form.SWITCH_REG_PHONE.data = load_dict.get(get_conf('SWITCH_REG_PHONE'))\n        form.SWITCH_REG_EMAIL.data = load_dict.get(get_conf('SWITCH_REG_EMAIL'))\n        form.SWITCH_REG_THREE_PART.data = load_dict.get(get_conf('SWITCH_REG_THREE_PART'))\n\n        form.SWITCH_LOGIN_ACCOUNT.data = load_dict.get(get_conf('SWITCH_LOGIN_ACCOUNT'))\n        form.SWITCH_LOGIN_PHONE.data = load_dict.get(get_conf('SWITCH_LOGIN_PHONE'))\n        form.SWITCH_LOGIN_EMAIL.data = load_dict.get(get_conf('SWITCH_LOGIN_EMAIL'))\n        form.SWITCH_LOGIN_THREE_PART.data = load_dict.get(get_conf('SWITCH_LOGIN_THREE_PART'))\n\n    if request.method == 'POST':\n        dump_dict = {\n            True: 'ON',\n            False: 'OFF'\n        }\n        if form.validate_on_submit():\n            set_conf('SWITCH_EXPORT', dump_dict.get(form.SWITCH_EXPORT.data))\n\n            set_conf('SWITCH_REG_ACCOUNT', dump_dict.get(form.SWITCH_REG_ACCOUNT.data))\n            set_conf('SWITCH_REG_PHONE', dump_dict.get(form.SWITCH_REG_PHONE.data))\n            set_conf('SWITCH_REG_EMAIL', dump_dict.get(form.SWITCH_REG_EMAIL.data))\n            set_conf('SWITCH_REG_THREE_PART', dump_dict.get(form.SWITCH_REG_THREE_PART.data))\n\n            set_conf('SWITCH_LOGIN_ACCOUNT', dump_dict.get(form.SWITCH_LOGIN_ACCOUNT.data))\n            set_conf('SWITCH_LOGIN_PHONE', dump_dict.get(form.SWITCH_LOGIN_PHONE.data))\n            set_conf('SWITCH_LOGIN_EMAIL', dump_dict.get(form.SWITCH_LOGIN_EMAIL.data))\n            set_conf('SWITCH_LOGIN_THREE_PART', dump_dict.get(form.SWITCH_LOGIN_THREE_PART.data))\n\n            flash(u'修改成功', 'success')\n        else:\n            flash(u'修改失败', 'warning')\n    return render_template('settings/switch.html', title='settings_switch', form=form)\n\n\n@bp_settings.route('/user/', methods=['GET', 'POST'])\n@login_required\n@permission_sys.require(http_exception=403)\ndef user():\n    \"\"\"\n    会员配置\n    LOCK_REG_NOT_ACTIVE_TTL = 3600*24*3     # 注册后3天内未激活\n    LOCK_ACTIVE_NOT_PUT_TTL = 3600*24*3     # 激活后3天内未排单\n    LOCK_ORDER_NOT_PAY_TTL = 3600*48        # 匹配后超过48小时不打款\n    LOCK_PAY_NOT_REC_TTL = 3600*48          # 收款后48小时不确认\n    :return:\n    \"\"\"\n    form = UserForm(request.form)\n    if request.method == 'GET':\n        form.LOCK_REG_NOT_ACTIVE_TTL.data = get_conf('LOCK_REG_NOT_ACTIVE_TTL')\n        form.LOCK_ACTIVE_NOT_PUT_TTL.data = get_conf('LOCK_ACTIVE_NOT_PUT_TTL')\n        form.LOCK_ORDER_NOT_PAY_TTL.data = get_conf('LOCK_ORDER_NOT_PAY_TTL')\n        form.LOCK_PAY_NOT_REC_TTL.data = get_conf('LOCK_PAY_NOT_REC_TTL')\n\n    if request.method == 'POST':\n        if form.validate_on_submit():\n            set_conf('LOCK_REG_NOT_ACTIVE_TTL', form.LOCK_REG_NOT_ACTIVE_TTL.data)\n            set_conf('LOCK_ACTIVE_NOT_PUT_TTL', form.LOCK_ACTIVE_NOT_PUT_TTL.data)\n            set_conf('LOCK_ORDER_NOT_PAY_TTL', form.LOCK_ORDER_NOT_PAY_TTL.data)\n            set_conf('LOCK_PAY_NOT_REC_TTL', form.LOCK_PAY_NOT_REC_TTL.data)\n            flash(u'修改成功', 'success')\n        else:\n            flash(u'修改失败', 'warning')\n    return render_template('settings/user.html', title='settings_user', form=form)\n\n\n@bp_settings.route('/order/', methods=['GET', 'POST'])\n@login_required\n@permission_sys.require(http_exception=403)\ndef order():\n    \"\"\"\n    订单配置\n\n    # 订单限制\n    ORDER_MAX_AMOUNT = 10000  # 订单最大金额\n    ORDER_MAX_COUNT = 100  # 订单最大数量\n\n    # 推广奖励\n    BONUS_DIRECT = 0.03  # 直接推荐奖励\n    BONUS_LEVEL_FIRST = 0.05        # 一级推荐奖励\n    BONUS_LEVEL_SECOND = 0.05       # 二级推荐奖励\n    BONUS_LEVEL_THIRD = 0.03        # 三级推荐奖励\n    :return:\n    \"\"\"\n    form = OrderForm(request.form)\n    if request.method == 'GET':\n        # 订单限制\n        form.ORDER_MAX_AMOUNT.data = get_conf('ORDER_MAX_AMOUNT')\n        form.ORDER_MAX_COUNT.data = get_conf('ORDER_MAX_COUNT')\n\n        # 推广奖励\n        form.BONUS_DIRECT.data = Decimal(get_conf('BONUS_DIRECT'))\n\n        form.BONUS_LEVEL_FIRST.data = Decimal(get_conf('BONUS_LEVEL_FIRST'))\n        form.BONUS_LEVEL_SECOND.data = Decimal(get_conf('BONUS_LEVEL_SECOND'))\n        form.BONUS_LEVEL_THIRD.data = Decimal(get_conf('BONUS_LEVEL_THIRD'))\n\n    if request.method == 'POST':\n        if form.validate_on_submit():\n            # 订单限制\n            set_conf('ORDER_MAX_AMOUNT', form.ORDER_MAX_AMOUNT.data)\n            set_conf('ORDER_MAX_COUNT', form.ORDER_MAX_COUNT.data)\n\n            # 推广奖励\n            set_conf('BONUS_DIRECT', form.BONUS_DIRECT.data)\n\n            set_conf('BONUS_LEVEL_FIRST', form.BONUS_LEVEL_FIRST.data)\n            set_conf('BONUS_LEVEL_SECOND', form.BONUS_LEVEL_SECOND.data)\n            set_conf('BONUS_LEVEL_THIRD', form.BONUS_LEVEL_THIRD.data)\n\n            flash(u'修改成功', 'success')\n        else:\n            flash(u'修改失败', 'warning')\n    return render_template('settings/order.html', title='settings_order', form=form)\n\n\n@bp_settings.route('/apply_put/', methods=['GET', 'POST'])\n@login_required\n@permission_sys.require(http_exception=403)\ndef apply_put():\n    \"\"\"\n    投资申请配置\n\n    # 单次投资金额范围\n    APPLY_PUT_MIN_EACH = 2000               # 最小值\n    APPLY_PUT_MAX_EACH = 20000              # 最大值\n    APPLY_PUT_STEP = 1000                   # 投资金额步长（基数）\n\n    # 单个用户投资限制\n    APPLY_PUT_USER_MAX_AMOUNT = 30000       # 单个用户投资最大交易中金额\n    APPLY_PUT_USER_MAX_COUNT = 1            # 单个用户投资最大交易中单数(0 表示不限制)\n\n    # 每日投资限制\n    APPLY_PUT_MAX_AMOUNT_DAILY = 1000000    # 最大金额\n    APPLY_PUT_MAX_COUNT_DAILY = 0           # 最大数量(0 表示不限制)\n\n    # 每月投资限制\n    APPLY_PUT_MAX_AMOUNT_MONTHLY = 30000000 # 最大值\n    APPLY_PUT_MAX_COUNT_MONTHLY = 0         # 最大数量(0 表示不限制)\n\n    # 投资时间配置\n    APPLY_PUT_TIME_START = '00:00:00'       # 每天投资申请开始时间\n    APPLY_PUT_TIME_END = '59:00:00'         # 每天投资申请结束时间\n\n    # 分红配置\n    APPLY_PUT_DAYS_BONUS = 15               # 分红计算天数\n    APPLY_PUT_DAYS_LOCK = 15                # 投资锁定天数、提现冻结天数\n\n    APPLY_PUT_INTEREST_ON_PRINCIPAL_TTL = 3600*24*15     # 投资申请后15天完成的订单执行回收本息\n    :return:\n    \"\"\"\n    form = ApplyPutForm(request.form)\n    if request.method == 'GET':\n        # 单次投资金额范围\n        form.APPLY_PUT_MIN_EACH.data = get_conf('APPLY_PUT_MIN_EACH')\n        form.APPLY_PUT_MAX_EACH.data = get_conf('APPLY_PUT_MAX_EACH')\n        form.APPLY_PUT_STEP.data = get_conf('APPLY_PUT_STEP')\n\n        # 单个用户投资限制\n        form.APPLY_PUT_USER_MAX_AMOUNT.data = get_conf('APPLY_PUT_USER_MAX_AMOUNT')\n        form.APPLY_PUT_USER_MAX_COUNT.data = get_conf('APPLY_PUT_USER_MAX_COUNT')\n\n        # 每日投资限额\n        form.APPLY_PUT_MAX_AMOUNT_DAILY.data = get_conf('APPLY_PUT_MAX_AMOUNT_DAILY')\n        form.APPLY_PUT_MAX_COUNT_DAILY.data = get_conf('APPLY_PUT_MAX_COUNT_DAILY')\n\n        # 每月投资限额\n        form.APPLY_PUT_MAX_AMOUNT_MONTHLY.data = get_conf('APPLY_PUT_MAX_AMOUNT_MONTHLY')\n        form.APPLY_PUT_MAX_COUNT_MONTHLY.data = get_conf('APPLY_PUT_MAX_COUNT_MONTHLY')\n\n        # 投资时间配置\n        form.APPLY_PUT_TIME_START.data = get_conf('APPLY_PUT_TIME_START')\n        form.APPLY_PUT_TIME_END.data = get_conf('APPLY_PUT_TIME_END')\n\n    if request.method == 'POST':\n        if form.validate_on_submit():\n            # 单次投资金额范围\n            set_conf('APPLY_PUT_MIN_EACH', form.APPLY_PUT_MIN_EACH.data)\n            set_conf('APPLY_PUT_MAX_EACH', form.APPLY_PUT_MAX_EACH.data)\n            set_conf('APPLY_PUT_STEP', form.APPLY_PUT_STEP.data)\n\n            # 单个用户投资限制\n            set_conf('APPLY_PUT_USER_MAX_AMOUNT', form.APPLY_PUT_USER_MAX_AMOUNT.data)\n            set_conf('APPLY_PUT_USER_MAX_COUNT', form.APPLY_PUT_USER_MAX_COUNT.data)\n\n            # 每日投资限额\n            set_conf('APPLY_PUT_MAX_AMOUNT_DAILY', form.APPLY_PUT_MAX_AMOUNT_DAILY.data)\n            set_conf('APPLY_PUT_MAX_COUNT_DAILY', form.APPLY_PUT_MAX_COUNT_DAILY.data)\n\n            # 每月投资限额\n            set_conf('APPLY_PUT_MAX_AMOUNT_MONTHLY', form.APPLY_PUT_MAX_AMOUNT_MONTHLY.data)\n            set_conf('APPLY_PUT_MAX_COUNT_MONTHLY', form.APPLY_PUT_MAX_COUNT_MONTHLY.data)\n\n            # 投资时间配置\n            set_conf('APPLY_PUT_TIME_START', form.APPLY_PUT_TIME_START.data)\n            set_conf('APPLY_PUT_TIME_END', form.APPLY_PUT_TIME_END.data)\n\n            flash(u'修改成功', 'success')\n        else:\n            flash(u'修改失败', 'warning')\n    return render_template('settings/apply_put.html', title='apply_put', form=form)\n\n\n@bp_settings.route('/apply_get/', methods=['GET', 'POST'])\n@login_required\n@permission_sys.require(http_exception=403)\ndef apply_get():\n    \"\"\"\n    提现申请配置\n\n    # 单次提现金额范围\n    APPLY_GET_MIN_EACH = 2000               # 最小值\n    APPLY_GET_MAX_EACH = 20000              # 最大值\n    APPLY_GET_STEP = 1000                   # 投资金额步长（基数）\n\n    # 单个用户提现限制\n    APPLY_GET_USER_MAX_AMOUNT = 30000       # 单个用户提现最大交易中金额\n    APPLY_GET_USER_MAX_COUNT = 1            # 单个用户提现最大交易中单数(0 表示不限制)\n\n    # 每日提现限制\n    APPLY_GET_MAX_AMOUNT_DAILY = 1000000    # 最大金额\n    APPLY_GET_MAX_COUNT_DAILY = 0           # 最大数量(0 表示不限制)\n\n    # 每月提现限制\n    APPLY_GET_MAX_AMOUNT_MONTHLY = 30000000 # 最大值\n    APPLY_GET_MAX_COUNT_MONTHLY = 0         # 最大数量(0 表示不限制)\n\n    # 提现时间配置\n    APPLY_GET_TIME_START = '00:00:00'       # 每天提现申请开始时间\n    APPLY_GET_TIME_END = '59:00:00'         # 每天提现申请结束时间\n\n    :return:\n    \"\"\"\n    form = ApplyGetForm(request.form)\n    if request.method == 'GET':\n        # 单次提现金额范围\n        form.APPLY_GET_MIN_EACH.data = get_conf('APPLY_GET_MIN_EACH')\n        form.APPLY_GET_MAX_EACH.data = get_conf('APPLY_GET_MAX_EACH')\n        form.APPLY_GET_STEP.data = get_conf('APPLY_GET_STEP')\n\n        # 单个用户提现限制\n        form.APPLY_GET_USER_MAX_AMOUNT.data = get_conf('APPLY_GET_USER_MAX_AMOUNT')\n        form.APPLY_GET_USER_MAX_COUNT.data = get_conf('APPLY_GET_USER_MAX_COUNT')\n\n        # 每日提现限额\n        form.APPLY_GET_MAX_AMOUNT_DAILY.data = get_conf('APPLY_GET_MAX_AMOUNT_DAILY')\n        form.APPLY_GET_MAX_COUNT_DAILY.data = get_conf('APPLY_GET_MAX_COUNT_DAILY')\n\n        # 每月提现限额\n        form.APPLY_GET_MAX_AMOUNT_MONTHLY.data = get_conf('APPLY_GET_MAX_AMOUNT_MONTHLY')\n        form.APPLY_GET_MAX_COUNT_MONTHLY.data = get_conf('APPLY_GET_MAX_COUNT_MONTHLY')\n\n        # 提现时间配置\n        form.APPLY_GET_TIME_START.data = get_conf('APPLY_GET_TIME_START')\n        form.APPLY_GET_TIME_END.data = get_conf('APPLY_GET_TIME_END')\n\n    if request.method == 'POST':\n        if form.validate_on_submit():\n            # 单次提现金额范围\n            set_conf('APPLY_GET_MIN_EACH', form.APPLY_GET_MIN_EACH.data)\n            set_conf('APPLY_GET_MAX_EACH', form.APPLY_GET_MAX_EACH.data)\n            set_conf('APPLY_GET_STEP', form.APPLY_GET_STEP.data)\n\n            # 单个用户提现限制\n            set_conf('APPLY_GET_USER_MAX_AMOUNT', form.APPLY_GET_USER_MAX_AMOUNT.data)\n            set_conf('APPLY_GET_USER_MAX_COUNT', form.APPLY_GET_USER_MAX_COUNT.data)\n\n            # 每日提现限额\n            set_conf('APPLY_GET_MAX_AMOUNT_DAILY', form.APPLY_GET_MAX_AMOUNT_DAILY.data)\n            set_conf('APPLY_GET_MAX_COUNT_DAILY', form.APPLY_GET_MAX_COUNT_DAILY.data)\n\n            # 每月提现限额\n            set_conf('APPLY_GET_MAX_AMOUNT_MONTHLY', form.APPLY_GET_MAX_AMOUNT_MONTHLY.data)\n            set_conf('APPLY_GET_MAX_COUNT_MONTHLY', form.APPLY_GET_MAX_COUNT_MONTHLY.data)\n\n            # 提现时间配置\n            set_conf('APPLY_GET_TIME_START', form.APPLY_GET_TIME_START.data)\n            set_conf('APPLY_GET_TIME_END', form.APPLY_GET_TIME_END.data)\n\n            flash(u'修改成功', 'success')\n        else:\n            flash(u'修改失败', 'warning')\n    return render_template('settings/apply_get.html', title='apply_get', form=form)\n\n\n@bp_settings.route('/wallet/', methods=['GET', 'POST'])\n@login_required\n@permission_sys.require(http_exception=403)\ndef wallet():\n    \"\"\"\n    钱包配置\n    :return:\n    \"\"\"\n    return render_template('settings/wallet.html', title='settings_wallet')\n\n\n@bp_settings.route('/score/', methods=['GET', 'POST'])\n@login_required\n@permission_sys.require(http_exception=403)\ndef score():\n    \"\"\"\n    积分配置\n    :return:\n    \"\"\"\n    return render_template('settings/score.html', title='settings_score')\n\n\n@bp_settings.route('/bonus/', methods=['GET', 'POST'])\n@login_required\n@permission_sys.require(http_exception=403)\ndef bonus():\n    \"\"\"\n    奖金配置\n    :return:\n    \"\"\"\n    return render_template('settings/bonus.html', title='settings_bonus')\n\n\n@bp_settings.route('/interest/', methods=['GET', 'POST'])\n@login_required\n@permission_sys.require(http_exception=403)\ndef interest():\n    \"\"\"\n    利息配置\n    INTEREST_PUT = 0.01  # 投资利息（日息）\n\n    # 支付奖惩比例\n    INTEREST_PAY_AHEAD = 0.02  # 提前支付奖金比例\n    INTEREST_PAY_DELAY = 0.02  # 延迟支付罚金比例\n\n    # 支付时间差\n    DIFF_TIME_PAY_AHEAD = 60*60*1   # 提前支付奖金时间差\n    DIFF_TIME_PAY_DELAY = 60*60*24  # 延迟支付罚金时间差\n\n    # 确认奖惩比例\n    INTEREST_REC_AHEAD = 0.02  # 提前确认奖金比例\n    INTEREST_REC_DELAY = 0.02  # 延迟确认罚金比例\n\n    # 确认时间差\n    DIFF_TIME_REC_AHEAD = 60*60*1   # 提前确认奖金时间差\n    DIFF_TIME_REC_DELAY = 60*60*24  # 延迟确认罚金时间差\n    :return:\n    \"\"\"\n    form = InterestForm(request.form)\n    if request.method == 'GET':\n        # 利息配置\n        form.INTEREST_PUT.data = Decimal(get_conf('INTEREST_PUT'))\n\n        # 支付奖惩比例\n        form.INTEREST_PAY_AHEAD.data = Decimal(get_conf('INTEREST_PAY_AHEAD'))\n        form.INTEREST_PAY_DELAY.data = Decimal(get_conf('INTEREST_PAY_DELAY'))\n\n        # 支付时间差\n        form.DIFF_TIME_PAY_AHEAD.data = get_conf('DIFF_TIME_PAY_AHEAD')\n        form.DIFF_TIME_PAY_DELAY.data = get_conf('DIFF_TIME_PAY_DELAY')\n\n        # 确认奖惩比例\n        form.INTEREST_REC_AHEAD.data = Decimal(get_conf('INTEREST_REC_AHEAD'))\n        form.INTEREST_REC_DELAY.data = Decimal(get_conf('INTEREST_REC_DELAY'))\n\n        # 确认时间差\n        form.DIFF_TIME_REC_AHEAD.data = get_conf('DIFF_TIME_REC_AHEAD')\n        form.DIFF_TIME_REC_DELAY.data = get_conf('DIFF_TIME_REC_DELAY')\n\n    if request.method == 'POST':\n        if form.validate_on_submit():\n            # 利息配置\n            set_conf('INTEREST_PUT', form.INTEREST_PUT.data)\n\n            # 支付奖惩比例\n            set_conf('INTEREST_PAY_AHEAD', form.INTEREST_PAY_AHEAD.data)\n            set_conf('INTEREST_PAY_DELAY', form.INTEREST_PAY_DELAY.data)\n\n            # 支付时间差\n            set_conf('DIFF_TIME_PAY_AHEAD', form.DIFF_TIME_PAY_AHEAD.data)\n            set_conf('DIFF_TIME_PAY_DELAY', form.DIFF_TIME_PAY_DELAY.data)\n\n            # 确认奖惩比例\n            set_conf('INTEREST_REC_AHEAD', form.INTEREST_REC_AHEAD.data)\n            set_conf('INTEREST_REC_DELAY', form.INTEREST_REC_DELAY.data)\n\n            # 确认时间差\n            set_conf('DIFF_TIME_REC_AHEAD', form.DIFF_TIME_REC_AHEAD.data)\n            set_conf('DIFF_TIME_REC_DELAY', form.DIFF_TIME_REC_DELAY.data)\n\n            flash(u'修改成功', 'success')\n        else:\n            flash(u'修改失败', 'warning')\n    return render_template('settings/interest.html', title='settings_interest', form=form)\n"
  },
  {
    "path": "app_backend/views/stats.py",
    "content": "#!/usr/bin/env python\n# encoding: utf-8\n\n\"\"\"\n@author: zhanghe\n@software: PyCharm\n@file: stats.py\n@time: 2017/6/10 下午1:29\n\"\"\"\n\n\n\nimport json\nfrom datetime import datetime\n\nfrom flask import Blueprint\nfrom flask import abort\nfrom flask import redirect\nfrom flask import render_template, request, flash\nfrom flask import url_for\nfrom flask_login import current_user, login_required\n\nfrom app_backend.permissions import permission_stats\n\nbp_stats = Blueprint('stats', __name__, url_prefix='/stats')\n\n\n@bp_stats.route('/user/', methods=['GET', 'POST'])\n@login_required\n@permission_stats.require(http_exception=403)\ndef user():\n    \"\"\"\n    用户统计\n    按日、周、月统计注册量\n    :return:\n    \"\"\"\n    time_based = request.args.get('time_based', 'hour')\n    if time_based not in ['hour', 'date', 'month']:\n        time_based = 'hour'\n    return render_template('stats/user.html', title='user_stats', time_based=time_based)\n\n\n@bp_stats.route('/apply_put/', methods=['GET', 'POST'])\n@login_required\n@permission_stats.require(http_exception=403)\ndef apply_put():\n    \"\"\"\n    投资统计\n    按日、周、月统计注册量\n    :return:\n    \"\"\"\n    time_based = request.args.get('time_based', 'hour')\n    if time_based not in ['hour', 'date', 'month']:\n        time_based = 'hour'\n    return render_template('stats/apply_put.html', title='apply_put_stats', time_based=time_based)\n\n\n@bp_stats.route('/apply_get/', methods=['GET', 'POST'])\n@login_required\n@permission_stats.require(http_exception=403)\ndef apply_get():\n    \"\"\"\n    提现统计\n    按日、周、月统计注册量\n    :return:\n    \"\"\"\n    time_based = request.args.get('time_based', 'hour')\n    if time_based not in ['hour', 'date', 'month']:\n        time_based = 'hour'\n    return render_template('stats/apply_get.html', title='apply_get_stats', time_based=time_based)\n\n\n@bp_stats.route('/order/', methods=['GET', 'POST'])\n@login_required\n@permission_stats.require(http_exception=403)\ndef order():\n    \"\"\"\n    订单统计\n    按日、周、月统计注册量\n    :return:\n    \"\"\"\n    time_based = request.args.get('time_based', 'hour')\n    if time_based not in ['hour', 'date', 'month']:\n        time_based = 'hour'\n    return render_template('stats/order.html', title='order_stats', time_based=time_based)\n"
  },
  {
    "path": "app_backend/views/user.py",
    "content": "#!/usr/bin/env python\n# encoding: utf-8\n\n\"\"\"\n@author: zhanghe\n@software: PyCharm\n@file: user.py\n@time: 2017/3/17 下午11:47\n\"\"\"\n\n\nimport json\nfrom datetime import datetime\nimport traceback\n\nimport flask_excel as excel\nfrom flask import Blueprint\nfrom flask import abort\nfrom flask import redirect\nfrom flask import render_template, request, flash\nfrom flask import url_for\nfrom flask_login import current_user, login_required\nfrom itsdangerous import TimestampSigner\nfrom sqlalchemy.orm import aliased\n\nfrom app_backend.api.user_config import merge_user_config\nfrom app_backend.tools.config_manage import get_conf\nfrom app_common.maps import area_code_map\nfrom app_common.maps.type_auth import *\nfrom app_common.tools import md5, json_default\nfrom app_common.tools.date_time import time_local_to_utc\nfrom app_backend import app\nfrom app_backend.api.user import edit_user, user_reg_stats, user_active_stats\nfrom app_backend.api.user_auth import get_user_auth_row, edit_user_auth\nfrom app_backend.api.user_bank import get_user_bank_row_by_id, add_user_bank, edit_user_bank\nfrom app_backend.api.user_profile import get_user_profile_row_by_id, edit_user_profile, get_team_tree_recursion, get_user_profile_row\nfrom app_backend.api.user_config import get_user_config_row_by_id\nfrom app_backend.forms.user import UserProfileForm, UserAuthForm, UserBankForm, UserSearchForm, UserConfigForm\nfrom app_backend.models import User, Scheduling\nfrom app_backend.models import UserProfile\nfrom app_backend.models import UserBank\nfrom app_backend.models import Wallet\nfrom app_backend.models import Score\nfrom app_backend.models import Bonus\nfrom app_backend.models import BitCoin\n\nfrom app_common.maps.status_lock import *\nfrom app_common.maps.status_delete import *\nfrom app_common.tools.ip import get_real_ip\n\nfrom app_backend.permissions import permission_user\n\nfrom app_backend.database import db\n\nSWITCH_EXPORT = get_conf('SWITCH_EXPORT')\nPER_PAGE_BACKEND = app.config['PER_PAGE_BACKEND']\n\nbp_user = Blueprint('user', __name__, url_prefix='/user')\n\n\n@bp_user.route('/list/')\n@bp_user.route('/list/<int:page>/')\n@login_required\n@permission_user.require(http_exception=403)\ndef lists(page=1):\n    \"\"\"\n    会员列表\n    \"\"\"\n    form = UserSearchForm(request.form)\n\n    user_id = request.args.get('user_id', '', type=int)\n    user_name = request.args.get('user_name', '', type=str)\n    start_time = request.args.get('start_time', '', type=str)\n    end_time = request.args.get('end_time', '', type=str)\n    status_active = request.args.get('status_active', '', type=str)\n    status_lock = request.args.get('status_lock', '', type=str)\n    op = request.args.get('op', 0, type=int)\n\n    form.user_id.data = user_id\n    form.user_name.data = user_name\n    form.start_time.data = start_time\n    form.end_time.data = end_time\n    form.status_active.data = status_active\n    form.status_lock.data = status_lock\n\n    search_condition_user = [User.status_delete == STATUS_DEL_NO]\n    search_condition_user_profile = []\n\n    # 多次连接同一张表，需要别名\n    user_profile_c = aliased(UserProfile)  # 子\n    user_profile_p = aliased(UserProfile)  # 父\n\n    if user_id:\n        search_condition_user.append(User.id == user_id)\n    if start_time:\n        search_condition_user.append(User.create_time >= time_local_to_utc(start_time))\n    if end_time:\n        search_condition_user.append(User.create_time <= time_local_to_utc(end_time))\n    if status_active:\n        search_condition_user.append(User.status_active == status_active)\n    if status_lock:\n        search_condition_user.append(User.status_lock == status_lock)\n    if user_name:\n        search_condition_user_profile.append(user_profile_c.nickname == user_name)\n    # 处理导出\n    if op == 1:\n        if not SWITCH_EXPORT or SWITCH_EXPORT == 'OFF':\n            flash(u'导出功能关闭，暂不支持导出', 'warning')\n            return redirect(url_for('user.lists'))\n        data_list = []\n        try:\n            query_sets = User.query. \\\n                filter(*search_condition_user). \\\n                outerjoin(user_profile_c, User.id == user_profile_c.user_id). \\\n                filter(*search_condition_user_profile). \\\n                outerjoin(user_profile_p, user_profile_c.user_pid == user_profile_p.user_id). \\\n                outerjoin(Wallet, User.id == Wallet.user_id). \\\n                outerjoin(BitCoin, User.id == BitCoin.user_id). \\\n                outerjoin(Score, User.id == Score.user_id). \\\n                outerjoin(Bonus, User.id == Bonus.user_id). \\\n                outerjoin(Scheduling, User.id == Scheduling.user_id). \\\n                add_entity(user_profile_c). \\\n                add_entity(user_profile_p). \\\n                add_entity(Wallet). \\\n                add_entity(BitCoin). \\\n                add_entity(Score). \\\n                add_entity(Bonus). \\\n                add_entity(Scheduling). \\\n                all()\n            db.session.commit()\n            column_names = [u'用户编号', u'用户名称', u'等级', u'手机号码', u'推荐人', u'钱包余额', u'数字货币', u'积分', u'奖金', u'激活状态', u'锁定状态', u'创建时间']\n            data_list.append(column_names)\n            for (user, user_profile_c, user_profile_p, wallet, bit_coin, score, bonus) in query_sets:\n                row = [\n                    user.id if user else '',\n                    user_profile_c.nickname if user_profile_c else '',\n                    user_profile_c.type_level if user_profile_c else 0,\n                    user_profile_c.phone if user_profile_c else '',\n                    user_profile_p.nickname if user_profile_p else '',\n                    wallet.amount_current if wallet else 0,\n                    bit_coin.amount if bit_coin else 0,\n                    score.amount if score else 0,\n                    bonus.amount if bonus else 0,\n                    user.status_active if user else 0,\n                    user.status_lock if user else 0,\n                    user.create_time if user else ''\n                ]\n                data_list.append(row)\n            return excel.make_response_from_array(\n                data_list,\n                \"csv\",\n                file_name=\"用户列表_%s\" % datetime.now().strftime('%Y-%m-%d %H:%M:%S')\n            )\n        except Exception as e:\n            db.session.rollback()\n            flash(e.message, category='warning')\n            return redirect(url_for('index'))\n    # 处理查询\n    try:\n        pagination = User.query. \\\n            filter(*search_condition_user). \\\n            outerjoin(user_profile_c, User.id == user_profile_c.user_id). \\\n            filter(*search_condition_user_profile). \\\n            outerjoin(user_profile_p, user_profile_c.user_pid == user_profile_p.user_id). \\\n            outerjoin(Wallet, User.id == Wallet.user_id). \\\n            outerjoin(BitCoin, User.id == BitCoin.user_id). \\\n            outerjoin(Score, User.id == Score.user_id). \\\n            outerjoin(Bonus, User.id == Bonus.user_id). \\\n            outerjoin(Scheduling, User.id == Scheduling.user_id). \\\n            add_entity(user_profile_c). \\\n            add_entity(user_profile_p). \\\n            add_entity(Wallet). \\\n            add_entity(BitCoin). \\\n            add_entity(Score). \\\n            add_entity(Bonus). \\\n            add_entity(Scheduling). \\\n            paginate(page, PER_PAGE_BACKEND, False)\n        db.session.commit()\n        return render_template(\n            'user/list.html',\n            title='user_list',\n            pagination=pagination,\n            form=form,\n            STATUS_LOCK_OK=STATUS_LOCK_OK,\n            STATUS_DEL_OK=STATUS_DEL_OK,\n        )\n    except Exception as e:\n        db.session.rollback()\n        print traceback.print_exc()\n        flash(e.message, category='warning')\n        return redirect(url_for('index'))\n\n\n@bp_user.route('/add/')\n@login_required\n@permission_user.require(http_exception=403)\ndef add():\n    return render_template('user/add.html', title='user_add')\n\n\n@bp_user.route('/relationship/')\n@login_required\n@permission_user.require(http_exception=403)\ndef relationship():\n    \"\"\"\n    全站会员关系结构\n    :return:\n    \"\"\"\n    form = UserSearchForm(request.form)\n\n    user_id = request.args.get('user_id', '', type=int)\n    user_name = request.args.get('user_name', '', type=str)\n\n    if user_name and not user_id:\n        user_profile_info = get_user_profile_row(**{'nickname': user_name})\n        user_id = user_profile_info.user_id if user_profile_info else 0\n\n    form.user_id.data = user_id\n    form.user_name.data = user_name\n\n    # 获取用户团队树形结构\n    team_tree = dict(get_team_tree_recursion(user_id or 0))\n\n    return render_template('user/relationship.html', title='user_relationship', form=form, team_tree=team_tree)\n\n\n@bp_user.route('/auth/<int:user_id>', methods=['GET', 'POST'])\n@login_required\n@permission_user.require(http_exception=403)\ndef auth(user_id):\n    \"\"\"\n    用户登录认证信息\n    \"\"\"\n    form = UserAuthForm(request.form)\n    condition = {\n        'user_id': user_id,\n        'type_auth': TYPE_AUTH_ACCOUNT,\n    }\n    user_auth_info = get_user_auth_row(**condition)\n\n    if user_auth_info:\n        form.id.data = user_auth_info.id\n        form.type_auth.data = user_auth_info.type_auth\n        form.create_time.data = user_auth_info.create_time\n        form.update_time.data = user_auth_info.update_time\n        if request.method == 'GET':\n            form.id.data = user_auth_info.id\n            form.user_id.data = user_id\n            form.auth_key.data = user_auth_info.auth_key\n            form.auth_secret.data = ''\n            form.status_verified.data = user_auth_info.status_verified\n    if request.method == 'POST':\n        if form.validate_on_submit():\n            # 权限校验\n            condition = {\n                'id': form.id.data,\n                'user_id': user_id,\n                'type_auth': TYPE_AUTH_ACCOUNT,\n            }\n            op_right = get_user_auth_row(**condition)\n            if not op_right:\n                flash(u'修改失败', 'warning')\n                return redirect(url_for('index'))\n\n            current_time = datetime.utcnow()\n            user_auth_data = {\n                # 'type_auth': TYPE_AUTH_ACCOUNT,\n                'auth_key': form.auth_key.data,\n                # 'status_verified': form.status_verified.data,\n                'update_time': current_time,\n            }\n            if form.auth_secret.data:\n                user_auth_data['auth_secret'] = md5(form.auth_secret.data)\n            result = edit_user_auth(form.id.data, user_auth_data)\n            if result:\n                flash(u'修改成功', 'success')\n                return redirect(url_for('.auth', user_id=user_id))\n            else:\n                flash(u'信息不变', 'info')\n        else:\n            flash(u'修改失败', 'warning')\n        # flash(form.errors, 'warning')  # 调试打开\n\n    # flash(u'Hello, %s' % current_user.id, 'info')  # 测试打开\n    return render_template('user/auth.html', title='auth', form=form)\n\n\n@bp_user.route('/bank/<int:user_id>', methods=['GET', 'POST'])\n@login_required\n@permission_user.require(http_exception=403)\ndef bank(user_id):\n    \"\"\"\n    银行信息\n    :return:\n    \"\"\"\n    form = UserBankForm(request.form)\n    bank_info = get_user_bank_row_by_id(user_id)\n\n    if bank_info:\n        form.status_verified.data = bank_info.status_verified\n        form.create_time.data = bank_info.create_time\n        form.update_time.data = bank_info.update_time\n        if request.method == 'GET':\n            form.user_id.data = user_id\n            form.bank_name.data = bank_info.bank_name\n            form.bank_address.data = bank_info.bank_address\n            form.bank_account.data = bank_info.bank_account\n            form.status_verified.data = bank_info.status_verified\n    if request.method == 'POST':\n        if form.validate_on_submit():\n            current_time = datetime.utcnow()\n            bank_data = {\n                'bank_name': form.bank_name.data,\n                'bank_address': form.bank_address.data,\n                'bank_account': form.bank_account.data,\n                # 'status_verified': form.status_verified.data,\n                'update_time': current_time,\n            }\n            if bank_info:\n                result = edit_user_bank(user_id, bank_data)\n            else:\n                bank_data['create_time'] = current_time\n                result = add_user_bank(bank_data)\n            if result:\n                flash(u'修改成功', 'success')\n            else:\n                flash(u'信息不变', 'info')\n        else:\n            flash(u'修改失败', 'warning')\n        # flash(form.errors, 'warning')  # 调试打开\n\n    # flash(u'Hello, %s' % current_user.id, 'info')  # 测试打开\n    return render_template('user/bank.html', title='bank', form=form)\n\n\n@bp_user.route('/profile/<int:user_id>', methods=['GET', 'POST'])\n@login_required\n@permission_user.require(http_exception=403)\ndef profile(user_id):\n    \"\"\"\n    用户基本信息\n    \"\"\"\n    form = UserProfileForm(request.form)\n    user_info = get_user_profile_row_by_id(user_id)\n    if user_info:\n        form.user_pid.data = user_info.user_pid\n        form.nickname.data = user_info.nickname\n        form.avatar_url.data = user_info.avatar_url\n        form.create_time.data = user_info.create_time\n        form.update_time.data = user_info.update_time\n        if request.method == 'GET':\n            form.user_id.data = user_id\n            form.area_id.data = user_info.area_id\n            form.area_code.data = user_info.area_code\n            form.phone.data = user_info.phone\n            form.email.data = user_info.email\n            form.birthday.data = user_info.birthday\n            form.real_name.data = user_info.real_name\n            form.id_card.data = user_info.id_card\n    if request.method == 'POST':\n        if form.validate_on_submit():\n            current_time = datetime.utcnow()\n            # 手机号码国际化\n            area_id = form.area_id.data\n            area_code = area_code_map.get(area_id, '86')\n            user_data = {\n                'email': form.email.data,\n                'area_id': area_id,\n                'area_code': area_code,\n                'phone': form.phone.data,\n                'birthday': form.birthday.data,\n                'update_time': current_time,\n            }\n            result = edit_user_profile(user_id, user_data)\n            if result:\n                flash(u'修改成功', 'success')\n                return redirect(url_for('.profile', user_id=user_id))\n            else:\n                flash(u'信息不变', 'info')\n        else:\n            flash(u'修改失败', 'warning')\n    # flash(form.errors, 'warning')  # 调试打开\n\n    # flash(u'Hello, %s' % current_user.id, 'info')  # 测试打开\n    return render_template('user/profile.html', title='profile', form=form)\n\n\n@bp_user.route('/setting/', methods=['GET', 'POST'])\n@login_required\n@permission_user.require(http_exception=403)\ndef setting():\n    \"\"\"\n    设置\n    \"\"\"\n    # return \"Hello, World!\\nSetting!\"\n    form = UserProfileForm(request.form)\n    if request.method == 'GET':\n        from app_backend.api.user import get_user_row_by_id\n        user_info = get_user_row_by_id(current_user.id)\n        if user_info:\n            form.nickname.data = user_info.nickname\n            form.avatar_url.data = user_info.avatar_url\n            form.email.data = user_info.email\n            form.phone.data = user_info.phone\n            form.birthday.data = user_info.birthday\n            form.create_time.data = user_info.create_time\n            form.update_time.data = user_info.update_time\n    if request.method == 'POST':\n        if form.validate_on_submit():\n            # todo 判断邮箱是否重复\n            from app_backend.api.user import edit_user\n            from datetime import datetime\n            user_info = {\n                'nickname': form.nickname.data,\n                'avatar_url': form.avatar_url.data,\n                'email': form.email.data,\n                'phone': form.phone.data,\n                'birthday': form.birthday.data,\n                'update_time': datetime.utcnow(),\n                'last_ip': get_real_ip(),\n            }\n            result = edit_user(current_user.id, user_info)\n            if result == 1:\n                flash(u'修改成功', 'success')\n            if result == 0:\n                flash(u'修改失败', 'warning')\n        flash(form.errors, 'warning')  # 调试打开\n    flash(u'Hello, %s' % current_user.email, 'info')  # 测试打开\n    return render_template('./setting.html', title='setting', form=form)\n\n\n@bp_user.route('/ajax/lock/', methods=['GET', 'POST'])\n@login_required\n@permission_user.require(http_exception=403)\ndef ajax_lock():\n    \"\"\"\n    锁定用户\n    :return:\n    \"\"\"\n    if request.method == 'GET' and request.is_xhr:\n        user_id = request.args.get('user_id', 0, type=int)\n        if not user_id:\n            return json.dumps({'error': u'锁定失败'})\n        current_time = datetime.utcnow()\n        user_data = {\n            'status_lock': STATUS_LOCK_OK,\n            'lock_time': current_time,\n            'update_time': current_time\n        }\n        result = edit_user(user_id, user_data)\n        if result == 1:\n            return json.dumps({'success': u'锁定成功'})\n        if result == 0:\n            return json.dumps({'error': u'锁定失败'})\n    abort(404)\n\n\n@bp_user.route('/ajax/unlock/', methods=['GET', 'POST'])\n@login_required\n@permission_user.require(http_exception=403)\ndef ajax_unlock():\n    \"\"\"\n    锁定用户\n    :return:\n    \"\"\"\n    if request.method == 'GET' and request.is_xhr:\n        user_id = request.args.get('user_id', 0, type=int)\n        if not user_id:\n            return json.dumps({'error': u'解锁失败'})\n        current_time = datetime.utcnow()\n        user_data = {\n            'status_lock': STATUS_LOCK_NO,\n            'update_time': current_time\n        }\n        result = edit_user(user_id, user_data)\n        if result == 1:\n            return json.dumps({'success': u'解锁成功'})\n        if result == 0:\n            return json.dumps({'error': u'解锁失败'})\n    abort(404)\n\n\n@bp_user.route('/ajax/del/', methods=['GET', 'POST'])\n@login_required\n@permission_user.require(http_exception=403)\ndef ajax_delete():\n    \"\"\"\n    删除用户\n    :return:\n    \"\"\"\n    if request.method == 'GET' and request.is_xhr:\n        user_id = request.args.get('user_id', 0, type=int)\n        if not user_id:\n            return json.dumps({'error': u'删除失败'})\n        current_time = datetime.utcnow()\n        user_data = {\n            'status_delete': STATUS_DEL_OK,\n            'delete_time': current_time,\n            'update_time': current_time\n        }\n        result = edit_user(user_id, user_data)\n        if result == 1:\n            return json.dumps({'success': u'删除成功'})\n        if result == 0:\n            return json.dumps({'error': u'删除失败'})\n    abort(404)\n\n\n# @bp_user.route('/stats/', methods=['GET', 'POST'])\n# @login_required\n# def stats():\n#     \"\"\"\n#     用户统计\n#     按日、周、月统计注册量\n#     :return:\n#     \"\"\"\n#     time_based = request.args.get('time_based', 'date')\n#     if time_based not in ['date', 'week', 'month']:\n#         time_based = 'date'\n#     # 获取注册量，获取激活量\n#     return render_template('user/stats.html', title='user_stats')\n\n\n@bp_user.route('/ajax_stats/', methods=['GET', 'POST'])\n@login_required\ndef ajax_stats():\n    \"\"\"\n    获取用户统计\n    :return:\n    \"\"\"\n    import time\n    # time.sleep(3)\n    # start_time, end_time, time_based = 'hour'\n    time_based = request.args.get('time_based', 'hour')\n    result_user_reg = user_reg_stats(time_based)\n    result_user_active = user_active_stats(time_based)\n\n    line_chart_data = {\n        'labels': [label for label, _ in result_user_reg],\n        'datasets': [\n            {\n                'label': u'注册',\n                'backgroundColor': 'rgba(220,220,220,0.5)',\n                'borderColor': 'rgba(220,220,220,1)',\n                'pointBackgroundColor': 'rgba(220,220,220,1)',\n                'pointBorderColor': '#fff',\n                'pointBorderWidth': 2,\n                'data': [data for _, data in result_user_reg]\n            },\n            {\n                'label': u'激活',\n                'backgroundColor': 'rgba(151,187,205,0.5)',\n                'borderColor': 'rgba(151,187,205,1)',\n                'pointBackgroundColor': 'rgba(151,187,205,1)',\n                'pointBorderColor': '#fff',\n                'pointBorderWidth': 2,\n                'data': [data for _, data in result_user_active]\n            }\n        ]\n    }\n    return json.dumps(line_chart_data, default=json_default)\n\n\n@bp_user.route('/admin_login/<int:user_id>/', methods=['GET', 'POST'])\n@login_required\n@permission_user.require(http_exception=403)\ndef admin_login(user_id):\n    \"\"\"\n    后台登录前台用户\n    :return:\n    \"\"\"\n    s = TimestampSigner(app.config.get('ADMIN_TO_USER_LOGIN_SIGN_KEY'))\n    user_id_sign = s.sign(str(user_id))\n    return redirect('%s/auth/admin_login/?uid_sign=%s' % (app.config.get('FRONTEND_URL', ''), user_id_sign))\n\n\n@bp_user.route('/config/', methods=['GET', 'POST'])\n@login_required\ndef config():\n    \"\"\"\n    用户配置\n    :return:\n    \"\"\"\n    user_id = request.args.get('user_id', 0, type=int)\n\n    form = UserConfigForm(request.form)\n\n    # 初始化表单的值\n    if user_id:\n        form.user_id.data = user_id\n    else:\n        flash(u'用户参数错误', 'warning')\n        return redirect('.lists')\n    if request.method == 'GET':\n        user_config = get_user_config_row_by_id(user_id)\n        form.team_bonus.data = user_config.team_bonus if user_config else ''\n    if request.method == 'POST':\n        if form.validate_on_submit():\n            # 用户配置\n            current_time = datetime.utcnow()\n            data = {\n                'user_id': user_id,\n                'team_bonus': form.team_bonus.data,\n                'create_time': current_time,\n                'update_time': current_time\n            }\n            res = merge_user_config(data)\n            if res:\n                flash(u'配置成功', 'success')\n            else:\n                flash(u'配置失败', 'warning')\n        else:\n            flash(u'配置失败', 'warning')\n        # 闪现消息 success info warning danger\n        # flash(form.errors, 'warning')  # 调试打开\n    return render_template('user/config.html', title='user_config', form=form)\n"
  },
  {
    "path": "app_backend/views/wallet.py",
    "content": "#!/usr/bin/env python\n# encoding: utf-8\n\n\"\"\"\n@author: zhanghe\n@software: PyCharm\n@file: wallet.py\n@time: 2017/4/25 下午1:25\n\"\"\"\n\n\nfrom datetime import datetime\nfrom flask import redirect\nfrom flask import render_template, request, flash, g\nfrom flask import url_for\nfrom flask_login import current_user, login_required\n\nfrom app_backend import app\nfrom app_backend.forms.admin import AdminProfileForm\nfrom app_backend.models import User\nfrom app_backend.api.wallet import get_wallet_rows\n\nfrom flask import Blueprint\n\n\nbp_wallet = Blueprint('wallet', __name__, url_prefix='/wallet')\n\n\n@bp_wallet.route('/list/')\n@bp_wallet.route('/list/<int:page>/')\n@login_required\ndef lists(page=1):\n    \"\"\"\n    钱包列表\n    \"\"\"\n\n    pagination = get_wallet_rows(page)\n    return render_template('wallet/list.html', title='wallet_list', pagination=pagination)\n\n\n@bp_wallet.route('/add/', methods=['GET', 'POST'])\n@login_required\ndef add():\n    \"\"\"\n    创建钱包\n    :return:\n    \"\"\"\n    pass\n\n\n@bp_wallet.route('/del/', methods=['GET', 'POST'])\n@login_required\ndef delete():\n    \"\"\"\n    删除钱包\n    :return:\n    \"\"\"\n    pass\n\n\n@bp_wallet.route('/stats/', methods=['GET', 'POST'])\n@login_required\ndef stats():\n    \"\"\"\n    钱包统计\n    :return:\n    \"\"\"\n    return render_template('wallet/stats.html', title='wallet_stats')\n"
  },
  {
    "path": "app_common/README.md",
    "content": "## App 公共文件\n"
  },
  {
    "path": "app_common/__init__.py",
    "content": "#!/usr/bin/env python\n# encoding: utf-8\n\n\"\"\"\n@author: zhanghe\n@software: PyCharm\n@file: __init__.py.py\n@time: 2017/5/1 下午4:25\n\"\"\"\n\n\ndef func():\n    pass\n\n\nclass Main(object):\n    def __init__(self):\n        pass\n\n\nif __name__ == '__main__':\n    pass\n"
  },
  {
    "path": "app_common/maps/__init__.py",
    "content": "#!/usr/bin/env python\n# encoding: utf-8\n\n\"\"\"\n@author: zhanghe\n@software: PyCharm\n@file: __init__.py.py\n@time: 2017/4/14 上午1:52\n\"\"\"\n\n\n# 激活状态（0未激活，1已激活）\nstatus_active_list = [('', u'全部'), (0, u'未激活'), (1, u'已激活')]\n\n# 锁定状态（0未锁定，1已锁定）\nstatus_lock_list = [('', u'全部'), (0, u'正常'), (1, u'锁定')]\n\n# 删除状态（0未删除，1已删除）\nstatus_delete_list = [('', u'全部'), (0, u'正常'), (1, u'删除')]\n\n# 认证状态（0未认证，1已认证）\nstatus_verified_list = [('', u'全部'), (0, u'未认证'), (1, u'已认证')]\n\n# 申请状态:0:待生效，1:已生效，2:取消\nstatus_apply_list = [('', u'全部'), (0, u'待生效'), (1, u'已生效'), (2, u'取消')]\n\n# 订单状态:0:待匹配，1:部分匹配，2:完全匹配\nstatus_order_list = [('', u'全部'), (0, u'待匹配'), (1, u'部分匹配'), (2, u'完全匹配')]\n\n# 支付状态:0:待支付，1:支付成功，2:支付失败\nstatus_pay_list = [('', u'全部'), (0, u'待支付'), (1, u'支付成功'), (2, u'支付失败')]\n\n# 收款状态:0:待收款，1:收款成功，2:收款失败\nstatus_rec_list = [('', u'全部'), (0, u'待收款'), (1, u'收款成功'), (2, u'收款失败')]\n\n# 审核状态:0:待审核，1:审核通过，2:审核失败\nstatus_audit_list = [('', u'全部'), (0, u'待审核'), (1, u'审核通过'), (2, u'审核失败')]\n\n# 认证类型（0账号，1邮箱，2手机，3qq，4微信，5微博）\ntype_auth_list = [('', u'全部'), (0, u'未知'), (1, u'邮箱'), (2, u'手机'), (3, u'QQ'), (4, u'微信'), (5, u'微博')]\n\n# 申请类型:0:自主添加，1:系统生成\ntype_apply_list = [('', u'全部'), (0, u'自主添加'), (1, u'系统生成')]\n\n# 支付/收款方式:0:不限，1:银行转账，2:数字货币，3:支付宝，4:微信\ntype_pay_list = [('', u'全部'), (0, u'不限'), (1, u'银行转账'), (2, u'数字货币'), (3, u'支付宝'), (4, u'微信')]\n\n# 提现类型:0:钱包余额，1:数字货币\ntype_withdraw_list = [('', u'全部'), (0, u'钱包余额'), (1, u'数字货币')]\n\n# 钱包类型（1：收、2：支）\n\n# 钱包明细状态:0:待生效，1:已生效，2:作废\n\n# 积分类型（1：加、2：减）\n\n# 管理角色:（1:系统,2:客服,3:运营,4:市场,5:销售,6:普通,7:高级）\nrole_admin_list = [('', u'全部'), (1, u'系统'), (2, u'客服'), (3, u'运营'), (4, u'市场'), (5, u'销售'), (6, u'普通'), (7, u'高级')]\n\n# 区号代码\narea_code_list = [\n    {\n        u'亚洲': [\n            {\n                \"phone_pre\": \"+0086\",\n                \"short_code\": \"CN\",\n                \"area_code\": 86,\n                \"name_c\": u\"中国\",\n                \"name_e\": \"China\",\n                \"country_area\": u\"亚洲\",\n                \"id\": 0\n            },\n            {\n                \"phone_pre\": \"+00852\",\n                \"short_code\": \"HK\",\n                \"area_code\": 852,\n                \"name_c\": u\"中国香港\",\n                \"name_e\": \"Hongkong\",\n                \"country_area\": u\"亚洲\",\n                \"id\": 1\n            },\n            {\n                \"phone_pre\": \"+00853\",\n                \"short_code\": \"MO\",\n                \"area_code\": 853,\n                \"name_c\": u\"中国澳门\",\n                \"name_e\": \"Macao\",\n                \"country_area\": u\"亚洲\",\n                \"id\": 2\n            },\n            {\n                \"phone_pre\": \"+00886\",\n                \"short_code\": \"TW\",\n                \"area_code\": 886,\n                \"name_c\": u\"中国台湾\",\n                \"name_e\": \"Taiwan\",\n                \"country_area\": u\"亚洲\",\n                \"id\": 3\n            },\n            {\n                \"phone_pre\": \"+0060\",\n                \"short_code\": \"MY\",\n                \"area_code\": 60,\n                \"name_c\": u\"马来西亚\",\n                \"name_e\": \"Malaysia\",\n                \"country_area\": u\"亚洲\",\n                \"id\": 4\n            },\n            {\n                \"phone_pre\": \"+0065\",\n                \"short_code\": \"SG\",\n                \"area_code\": 65,\n                \"name_c\": u\"新加坡\",\n                \"name_e\": \"Singapore\",\n                \"country_area\": u\"亚洲\",\n                \"id\": 5\n            },\n            {\n                \"phone_pre\": \"+0062\",\n                \"short_code\": \"ID\",\n                \"area_code\": 62,\n                \"name_c\": u\"印度尼西亚\",\n                \"name_e\": \"Indonesia\",\n                \"country_area\": u\"亚洲\",\n                \"id\": 6\n            },\n            {\n                \"phone_pre\": \"+0063\",\n                \"short_code\": \"PH\",\n                \"area_code\": 63,\n                \"name_c\": u\"菲律宾\",\n                \"name_e\": \"Philippines\",\n                \"country_area\": u\"亚洲\",\n                \"id\": 7\n            },\n            {\n                \"phone_pre\": \"+0066\",\n                \"short_code\": \"TH\",\n                \"area_code\": 66,\n                \"name_c\": u\"泰国\",\n                \"name_e\": \"Thailand\",\n                \"country_area\": u\"亚洲\",\n                \"id\": 8\n            },\n            {\n                \"phone_pre\": \"+0073\",\n                \"short_code\": \"KZ\",\n                \"area_code\": 73,\n                \"name_c\": u\"哈萨克斯坦\",\n                \"name_e\": \"Kazakhstan\",\n                \"country_area\": u\"亚洲\",\n                \"id\": 9\n            },\n            {\n                \"phone_pre\": \"+0081\",\n                \"short_code\": \"JP\",\n                \"area_code\": 81,\n                \"name_c\": u\"日本\",\n                \"name_e\": \"Japan\",\n                \"country_area\": u\"亚洲\",\n                \"id\": 10\n            },\n            {\n                \"phone_pre\": \"+0082\",\n                \"short_code\": \"KR\",\n                \"area_code\": 82,\n                \"name_c\": u\"韩国\",\n                \"name_e\": \"Korea\",\n                \"country_area\": u\"亚洲\",\n                \"id\": 11\n            },\n            {\n                \"phone_pre\": \"+0084\",\n                \"short_code\": \"VN\",\n                \"area_code\": 84,\n                \"name_c\": u\"越南\",\n                \"name_e\": \"Vietnam\",\n                \"country_area\": u\"亚洲\",\n                \"id\": 12\n            },\n            {\n                \"phone_pre\": \"+0090\",\n                \"short_code\": \"TR\",\n                \"area_code\": 90,\n                \"name_c\": u\"土耳其\",\n                \"name_e\": \"Turkey\",\n                \"country_area\": u\"亚洲\",\n                \"id\": 13\n            },\n            {\n                \"phone_pre\": \"+0091\",\n                \"short_code\": \"IN\",\n                \"area_code\": 91,\n                \"name_c\": u\"印度\",\n                \"name_e\": \"India\",\n                \"country_area\": u\"亚洲\",\n                \"id\": 14\n            },\n            {\n                \"phone_pre\": \"+0092\",\n                \"short_code\": \"PK\",\n                \"area_code\": 92,\n                \"name_c\": u\"巴基斯坦\",\n                \"name_e\": \"Pakistan\",\n                \"country_area\": u\"亚洲\",\n                \"id\": 15\n            },\n            {\n                \"phone_pre\": \"+0093\",\n                \"short_code\": \"AF\",\n                \"area_code\": 93,\n                \"name_c\": u\"阿富汗\",\n                \"name_e\": \"Afghanistan\",\n                \"country_area\": u\"亚洲\",\n                \"id\": 16\n            },\n            {\n                \"phone_pre\": \"+0094\",\n                \"short_code\": \"LK\",\n                \"area_code\": 94,\n                \"name_c\": u\"斯里兰卡\",\n                \"name_e\": \"Sri Lanka\",\n                \"country_area\": u\"亚洲\",\n                \"id\": 17\n            },\n            {\n                \"phone_pre\": \"+0095\",\n                \"short_code\": \"MM\",\n                \"area_code\": 95,\n                \"name_c\": u\"缅甸\",\n                \"name_e\": \"Burma\",\n                \"country_area\": u\"亚洲\",\n                \"id\": 18\n            },\n            {\n                \"phone_pre\": \"+0098\",\n                \"short_code\": \"IR\",\n                \"area_code\": 98,\n                \"name_c\": u\"伊朗\",\n                \"name_e\": \"Iran\",\n                \"country_area\": u\"亚洲\",\n                \"id\": 19\n            },\n            {\n                \"phone_pre\": \"+00374\",\n                \"short_code\": \"AM\",\n                \"area_code\": 374,\n                \"name_c\": u\"亚美尼亚\",\n                \"name_e\": \"Armenia\",\n                \"country_area\": u\"亚洲\",\n                \"id\": 20\n            },\n            {\n                \"phone_pre\": \"+00673\",\n                \"short_code\": \"BN\",\n                \"area_code\": 673,\n                \"name_c\": u\"文莱\",\n                \"name_e\": \"Brunei\",\n                \"country_area\": u\"亚洲\",\n                \"id\": 21\n            },\n            {\n                \"phone_pre\": \"+00855\",\n                \"short_code\": \"KH\",\n                \"area_code\": 855,\n                \"name_c\": u\"柬埔寨\",\n                \"name_e\": \"Cambodia\",\n                \"country_area\": u\"亚洲\",\n                \"id\": 22\n            },\n            {\n                \"phone_pre\": \"+00856\",\n                \"short_code\": \"LA\",\n                \"area_code\": 856,\n                \"name_c\": u\"老挝\",\n                \"name_e\": \"Laos\",\n                \"country_area\": u\"亚洲\",\n                \"id\": 23\n            },\n            {\n                \"phone_pre\": \"+00880\",\n                \"short_code\": \"BD\",\n                \"area_code\": 880,\n                \"name_c\": u\"孟加拉国\",\n                \"name_e\": \"Bangladesh\",\n                \"country_area\": u\"亚洲\",\n                \"id\": 24\n            },\n            {\n                \"phone_pre\": \"+00960\",\n                \"short_code\": \"MV\",\n                \"area_code\": 960,\n                \"name_c\": u\"马尔代夫\",\n                \"name_e\": \"Maldives\",\n                \"country_area\": u\"亚洲\",\n                \"id\": 25\n            },\n            {\n                \"phone_pre\": \"+00961\",\n                \"short_code\": \"LB\",\n                \"area_code\": 961,\n                \"name_c\": u\"黎巴嫩\",\n                \"name_e\": \"Lebanon\",\n                \"country_area\": u\"亚洲\",\n                \"id\": 26\n            },\n            {\n                \"phone_pre\": \"+00962\",\n                \"short_code\": \"JO\",\n                \"area_code\": 962,\n                \"name_c\": u\"约旦\",\n                \"name_e\": \"Jordan\",\n                \"country_area\": u\"亚洲\",\n                \"id\": 27\n            },\n            {\n                \"phone_pre\": \"+00963\",\n                \"short_code\": \"SY\",\n                \"area_code\": 963,\n                \"name_c\": u\"叙利亚\",\n                \"name_e\": \"Syria\",\n                \"country_area\": u\"亚洲\",\n                \"id\": 28\n            },\n            {\n                \"phone_pre\": \"+00964\",\n                \"short_code\": \"IQ\",\n                \"area_code\": 964,\n                \"name_c\": u\"伊拉克\",\n                \"name_e\": \"Iraq\",\n                \"country_area\": u\"亚洲\",\n                \"id\": 29\n            },\n            {\n                \"phone_pre\": \"+00965\",\n                \"short_code\": \"KW\",\n                \"area_code\": 965,\n                \"name_c\": u\"科威特\",\n                \"name_e\": \"Kuwait\",\n                \"country_area\": u\"亚洲\",\n                \"id\": 30\n            },\n            {\n                \"phone_pre\": \"+00966\",\n                \"short_code\": \"SA\",\n                \"area_code\": 966,\n                \"name_c\": u\"沙特阿拉伯\",\n                \"name_e\": \"Saudi Arabia\",\n                \"country_area\": u\"亚洲\",\n                \"id\": 31\n            },\n            {\n                \"phone_pre\": \"+00967\",\n                \"short_code\": \"YE\",\n                \"area_code\": 967,\n                \"name_c\": u\"也门\",\n                \"name_e\": \"Yemen\",\n                \"country_area\": u\"亚洲\",\n                \"id\": 32\n            },\n            {\n                \"phone_pre\": \"+00968\",\n                \"short_code\": \"OM\",\n                \"area_code\": 968,\n                \"name_c\": u\"阿曼\",\n                \"name_e\": \"Oman\",\n                \"country_area\": u\"亚洲\",\n                \"id\": 33\n            },\n            {\n                \"phone_pre\": \"+00971\",\n                \"short_code\": \"AE\",\n                \"area_code\": 971,\n                \"name_c\": u\"阿拉伯联合酋长国\",\n                \"name_e\": \"Arab Emirates\",\n                \"country_area\": u\"亚洲\",\n                \"id\": 34\n            },\n            {\n                \"phone_pre\": \"+00972\",\n                \"short_code\": \"IL\",\n                \"area_code\": 972,\n                \"name_c\": u\"以色列\",\n                \"name_e\": \"Israel\",\n                \"country_area\": u\"亚洲\",\n                \"id\": 35\n            },\n            {\n                \"phone_pre\": \"+00973\",\n                \"short_code\": \"BH\",\n                \"area_code\": 973,\n                \"name_c\": u\"巴林\",\n                \"name_e\": \"Bahrain\",\n                \"country_area\": u\"亚洲\",\n                \"id\": 36\n            },\n            {\n                \"phone_pre\": \"+00974\",\n                \"short_code\": \"QA\",\n                \"area_code\": 974,\n                \"name_c\": u\"卡塔尔\",\n                \"name_e\": \"Qatar\",\n                \"country_area\": u\"亚洲\",\n                \"id\": 37\n            },\n            {\n                \"phone_pre\": \"+00976\",\n                \"short_code\": \"MN\",\n                \"area_code\": 976,\n                \"name_c\": u\"蒙古\",\n                \"name_e\": \"Mongolia\",\n                \"country_area\": u\"亚洲\",\n                \"id\": 38\n            },\n            {\n                \"phone_pre\": \"+00977\",\n                \"short_code\": \"NP\",\n                \"area_code\": 977,\n                \"name_c\": u\"尼泊尔\",\n                \"name_e\": \"Nepal\",\n                \"country_area\": u\"亚洲\",\n                \"id\": 39\n            },\n            {\n                \"phone_pre\": \"+00992\",\n                \"short_code\": \"TJ\",\n                \"area_code\": 992,\n                \"name_c\": u\"塔吉克斯坦\",\n                \"name_e\": \"Tajikistan\",\n                \"country_area\": u\"亚洲\",\n                \"id\": 40\n            },\n            {\n                \"phone_pre\": \"+00993\",\n                \"short_code\": \"TM\",\n                \"area_code\": 993,\n                \"name_c\": u\"土库曼斯坦\",\n                \"name_e\": \"Turkmenistan\",\n                \"country_area\": u\"亚洲\",\n                \"id\": 41\n            },\n            {\n                \"phone_pre\": \"+00994\",\n                \"short_code\": \"AZ\",\n                \"area_code\": 994,\n                \"name_c\": u\"阿塞拜疆\",\n                \"name_e\": \"Azerbaijan\",\n                \"country_area\": u\"亚洲\",\n                \"id\": 42\n            },\n            {\n                \"phone_pre\": \"+00995\",\n                \"short_code\": \"GE\",\n                \"area_code\": 995,\n                \"name_c\": u\"格鲁吉亚\",\n                \"name_e\": \"Georgia\",\n                \"country_area\": u\"亚洲\",\n                \"id\": 43\n            },\n            {\n                \"phone_pre\": \"+00996\",\n                \"short_code\": \"KG\",\n                \"area_code\": 996,\n                \"name_c\": u\"吉尔吉斯斯坦\",\n                \"name_e\": \"Kyrgyzstan\",\n                \"country_area\": u\"亚洲\",\n                \"id\": 44\n            },\n            {\n                \"phone_pre\": \"+00998\",\n                \"short_code\": \"UZ\",\n                \"area_code\": 998,\n                \"name_c\": u\"乌兹别克斯坦\",\n                \"name_e\": \"Uzbekistan\",\n                \"country_area\": u\"亚洲\",\n                \"id\": 45\n            },\n        ]},\n    {\n        u'欧洲': [\n            {\n                \"phone_pre\": \"+0044\",\n                \"short_code\": \"GB\",\n                \"area_code\": 44,\n                \"name_c\": u\"英国\",\n                \"name_e\": \"United Kiongdom\",\n                \"country_area\": u\"欧洲\",\n                \"id\": 47\n            },\n            {\n                \"phone_pre\": \"+0049\",\n                \"short_code\": \"DE\",\n                \"area_code\": 49,\n                \"name_c\": u\"德国\",\n                \"name_e\": \"Germany\",\n                \"country_area\": u\"欧洲\",\n                \"id\": 48\n            },\n            {\n                \"phone_pre\": \"+007\",\n                \"short_code\": \"RU\",\n                \"area_code\": 7,\n                \"name_c\": u\"俄罗斯\",\n                \"name_e\": \"Russia\",\n                \"country_area\": u\"欧洲\",\n                \"id\": 49\n            },\n            {\n                \"phone_pre\": \"+0030\",\n                \"short_code\": \"GR\",\n                \"area_code\": 30,\n                \"name_c\": u\"希腊\",\n                \"name_e\": \"Greece\",\n                \"country_area\": u\"欧洲\",\n                \"id\": 50\n            },\n            {\n                \"phone_pre\": \"+0031\",\n                \"short_code\": \"NL\",\n                \"area_code\": 31,\n                \"name_c\": u\"荷兰\",\n                \"name_e\": \"Netherlands\",\n                \"country_area\": u\"欧洲\",\n                \"id\": 51\n            },\n            {\n                \"phone_pre\": \"+0032\",\n                \"short_code\": \"BE\",\n                \"area_code\": 32,\n                \"name_c\": u\"比利时\",\n                \"name_e\": \"Belgium\",\n                \"country_area\": u\"欧洲\",\n                \"id\": 52\n            },\n            {\n                \"phone_pre\": \"+0033\",\n                \"short_code\": \"FR\",\n                \"area_code\": 33,\n                \"name_c\": u\"法国\",\n                \"name_e\": \"France\",\n                \"country_area\": u\"欧洲\",\n                \"id\": 53\n            },\n            {\n                \"phone_pre\": \"+0034\",\n                \"short_code\": \"ES\",\n                \"area_code\": 34,\n                \"name_c\": u\"西班牙\",\n                \"name_e\": \"Spain\",\n                \"country_area\": u\"欧洲\",\n                \"id\": 54\n            },\n            {\n                \"phone_pre\": \"+0036\",\n                \"short_code\": \"HU\",\n                \"area_code\": 36,\n                \"name_c\": u\"匈牙利\",\n                \"name_e\": \"Hungary\",\n                \"country_area\": u\"欧洲\",\n                \"id\": 55\n            },\n            {\n                \"phone_pre\": \"+0039\",\n                \"short_code\": \"IT\",\n                \"area_code\": 39,\n                \"name_c\": u\"意大利\",\n                \"name_e\": \"Italy\",\n                \"country_area\": u\"欧洲\",\n                \"id\": 56\n            },\n            {\n                \"phone_pre\": \"+0040\",\n                \"short_code\": \"RO\",\n                \"area_code\": 40,\n                \"name_c\": u\"罗马尼亚\",\n                \"name_e\": \"Romania\",\n                \"country_area\": u\"欧洲\",\n                \"id\": 57\n            },\n            {\n                \"phone_pre\": \"+0041\",\n                \"short_code\": \"CH\",\n                \"area_code\": 41,\n                \"name_c\": u\"瑞士\",\n                \"name_e\": \"Switzerland\",\n                \"country_area\": u\"欧洲\",\n                \"id\": 58\n            },\n            {\n                \"phone_pre\": \"+0043\",\n                \"short_code\": \"AT\",\n                \"area_code\": 43,\n                \"name_c\": u\"奥地利\",\n                \"name_e\": \"Austria\",\n                \"country_area\": u\"欧洲\",\n                \"id\": 59\n            },\n            {\n                \"phone_pre\": \"+0045\",\n                \"short_code\": \"DK\",\n                \"area_code\": 45,\n                \"name_c\": u\"丹麦\",\n                \"name_e\": \"Denmark\",\n                \"country_area\": u\"欧洲\",\n                \"id\": 60\n            },\n            {\n                \"phone_pre\": \"+0046\",\n                \"short_code\": \"SE\",\n                \"area_code\": 46,\n                \"name_c\": u\"瑞典\",\n                \"name_e\": \"Sweden\",\n                \"country_area\": u\"欧洲\",\n                \"id\": 61\n            },\n            {\n                \"phone_pre\": \"+0047\",\n                \"short_code\": \"NO\",\n                \"area_code\": 47,\n                \"name_c\": u\"挪威\",\n                \"name_e\": \"Norway\",\n                \"country_area\": u\"欧洲\",\n                \"id\": 62\n            },\n            {\n                \"phone_pre\": \"+0048\",\n                \"short_code\": \"PL\",\n                \"area_code\": 48,\n                \"name_c\": u\"波兰\",\n                \"name_e\": \"Poland\",\n                \"country_area\": u\"欧洲\",\n                \"id\": 63\n            },\n            {\n                \"phone_pre\": \"+00350\",\n                \"short_code\": \"GI\",\n                \"area_code\": 350,\n                \"name_c\": u\"直布罗陀\",\n                \"name_e\": \"Gibraltar\",\n                \"country_area\": u\"欧洲\",\n                \"id\": 64\n            },\n            {\n                \"phone_pre\": \"+00351\",\n                \"short_code\": \"PT\",\n                \"area_code\": 351,\n                \"name_c\": u\"葡萄牙\",\n                \"name_e\": \"Portugal\",\n                \"country_area\": u\"欧洲\",\n                \"id\": 65\n            },\n            {\n                \"phone_pre\": \"+00352\",\n                \"short_code\": \"LU\",\n                \"area_code\": 352,\n                \"name_c\": u\"卢森堡\",\n                \"name_e\": \"Luxembourg\",\n                \"country_area\": u\"欧洲\",\n                \"id\": 66\n            },\n            {\n                \"phone_pre\": \"+00353\",\n                \"short_code\": \"IE\",\n                \"area_code\": 353,\n                \"name_c\": u\"爱尔兰\",\n                \"name_e\": \"Ireland\",\n                \"country_area\": u\"欧洲\",\n                \"id\": 67\n            },\n            {\n                \"phone_pre\": \"+00354\",\n                \"short_code\": \"IS\",\n                \"area_code\": 354,\n                \"name_c\": u\"冰岛\",\n                \"name_e\": \"Iceland\",\n                \"country_area\": u\"欧洲\",\n                \"id\": 68\n            },\n            {\n                \"phone_pre\": \"+00355\",\n                \"short_code\": \"AL\",\n                \"area_code\": 355,\n                \"name_c\": u\"阿尔巴尼亚\",\n                \"name_e\": \"Albania\",\n                \"country_area\": u\"欧洲\",\n                \"id\": 69\n            },\n            {\n                \"phone_pre\": \"+00356\",\n                \"short_code\": \"MT\",\n                \"area_code\": 356,\n                \"name_c\": u\"马耳他\",\n                \"name_e\": \"Malta\",\n                \"country_area\": u\"欧洲\",\n                \"id\": 70\n            },\n            {\n                \"phone_pre\": \"+00357\",\n                \"short_code\": \"CY\",\n                \"area_code\": 357,\n                \"name_c\": u\"塞浦路斯\",\n                \"name_e\": \"Cyprus\",\n                \"country_area\": u\"欧洲\",\n                \"id\": 71\n            },\n            {\n                \"phone_pre\": \"+00358\",\n                \"short_code\": \"FI\",\n                \"area_code\": 358,\n                \"name_c\": u\"芬兰\",\n                \"name_e\": \"Finland\",\n                \"country_area\": u\"欧洲\",\n                \"id\": 72\n            },\n            {\n                \"phone_pre\": \"+00359\",\n                \"short_code\": \"BG\",\n                \"area_code\": 359,\n                \"name_c\": u\"保加利亚\",\n                \"name_e\": \"Bulgaria\",\n                \"country_area\": u\"欧洲\",\n                \"id\": 73\n            },\n            {\n                \"phone_pre\": \"+00370\",\n                \"short_code\": \"LT\",\n                \"area_code\": 370,\n                \"name_c\": u\"立陶宛\",\n                \"name_e\": \"Lithuania\",\n                \"country_area\": u\"欧洲\",\n                \"id\": 74\n            },\n            {\n                \"phone_pre\": \"+00371\",\n                \"short_code\": \"LV\",\n                \"area_code\": 371,\n                \"name_c\": u\"拉脱维亚\",\n                \"name_e\": \"Latvia\",\n                \"country_area\": u\"欧洲\",\n                \"id\": 75\n            },\n            {\n                \"phone_pre\": \"+00372\",\n                \"short_code\": \"EE\",\n                \"area_code\": 372,\n                \"name_c\": u\"爱沙尼亚\",\n                \"name_e\": \"Estonia\",\n                \"country_area\": u\"欧洲\",\n                \"id\": 76\n            },\n            {\n                \"phone_pre\": \"+00373\",\n                \"short_code\": \"MD\",\n                \"area_code\": 373,\n                \"name_c\": u\"摩尔多瓦\",\n                \"name_e\": \"Moldova\",\n                \"country_area\": u\"欧洲\",\n                \"id\": 77\n            },\n            {\n                \"phone_pre\": \"+00375\",\n                \"short_code\": \"BY\",\n                \"area_code\": 375,\n                \"name_c\": u\"白俄罗斯\",\n                \"name_e\": \"Belarus\",\n                \"country_area\": u\"欧洲\",\n                \"id\": 78\n            },\n            {\n                \"phone_pre\": \"+00377\",\n                \"short_code\": \"MC\",\n                \"area_code\": 377,\n                \"name_c\": u\"摩纳哥\",\n                \"name_e\": \"Monaco\",\n                \"country_area\": u\"欧洲\",\n                \"id\": 79\n            },\n            {\n                \"phone_pre\": \"+00378\",\n                \"short_code\": \"SM\",\n                \"area_code\": 378,\n                \"name_c\": u\"圣马力诺\",\n                \"name_e\": \"San Marino\",\n                \"country_area\": u\"欧洲\",\n                \"id\": 80\n            },\n            {\n                \"phone_pre\": \"+00380\",\n                \"short_code\": \"UA\",\n                \"area_code\": 380,\n                \"name_c\": u\"乌克兰\",\n                \"name_e\": \"Ukraine\",\n                \"country_area\": u\"欧洲\",\n                \"id\": 81\n            },\n            {\n                \"phone_pre\": \"+00386\",\n                \"short_code\": \"SI\",\n                \"area_code\": 386,\n                \"name_c\": u\"斯洛文尼亚\",\n                \"name_e\": \"Slovenia\",\n                \"country_area\": u\"欧洲\",\n                \"id\": 82\n            },\n            {\n                \"phone_pre\": \"+00420\",\n                \"short_code\": \"CZ\",\n                \"area_code\": 420,\n                \"name_c\": u\"捷克\",\n                \"name_e\": \"Czech\",\n                \"country_area\": u\"欧洲\",\n                \"id\": 83\n            },\n            {\n                \"phone_pre\": \"+00421\",\n                \"short_code\": \"SK\",\n                \"area_code\": 421,\n                \"name_c\": u\"斯洛伐克\",\n                \"name_e\": \"Slovak\",\n                \"country_area\": u\"欧洲\",\n                \"id\": 84\n            },\n            {\n                \"phone_pre\": \"+00423\",\n                \"short_code\": \"LI\",\n                \"area_code\": 423,\n                \"name_c\": u\"列支敦士登\",\n                \"name_e\": \"Liechtenstein\",\n                \"country_area\": u\"欧洲\",\n                \"id\": 85\n            },\n        ]\n    },\n    {\n        u'南美洲': [\n            {\n                \"phone_pre\": \"+0051\",\n                \"short_code\": \"PE\",\n                \"area_code\": 51,\n                \"name_c\": u\"秘鲁\",\n                \"name_e\": \"Peru\",\n                \"country_area\": u\"南美洲\",\n                \"id\": 86\n            },\n            {\n                \"phone_pre\": \"+0052\",\n                \"short_code\": \"MX\",\n                \"area_code\": 52,\n                \"name_c\": u\"墨西哥\",\n                \"name_e\": \"Mexico\",\n                \"country_area\": u\"南美洲\",\n                \"id\": 87\n            },\n            {\n                \"phone_pre\": \"+0053\",\n                \"short_code\": \"CU\",\n                \"area_code\": 53,\n                \"name_c\": u\"古巴\",\n                \"name_e\": \"Cuba\",\n                \"country_area\": u\"南美洲\",\n                \"id\": 88\n            },\n            {\n                \"phone_pre\": \"+0054\",\n                \"short_code\": \"AR\",\n                \"area_code\": 54,\n                \"name_c\": u\"阿根廷\",\n                \"name_e\": \"Argentina\",\n                \"country_area\": u\"南美洲\",\n                \"id\": 89\n            },\n            {\n                \"phone_pre\": \"+0055\",\n                \"short_code\": \"BR\",\n                \"area_code\": 55,\n                \"name_c\": u\"巴西\",\n                \"name_e\": \"Brazil\",\n                \"country_area\": u\"南美洲\",\n                \"id\": 90\n            },\n            {\n                \"phone_pre\": \"+0056\",\n                \"short_code\": \"CL\",\n                \"area_code\": 56,\n                \"name_c\": u\"智利\",\n                \"name_e\": \"Chile\",\n                \"country_area\": u\"南美洲\",\n                \"id\": 91\n            },\n            {\n                \"phone_pre\": \"+0057\",\n                \"short_code\": \"CO\",\n                \"area_code\": 57,\n                \"name_c\": u\"哥伦比亚\",\n                \"name_e\": \"Colombia\",\n                \"country_area\": u\"南美洲\",\n                \"id\": 92\n            },\n            {\n                \"phone_pre\": \"+0058\",\n                \"short_code\": \"VE\",\n                \"area_code\": 58,\n                \"name_c\": u\"委内瑞拉\",\n                \"name_e\": \"Venezuela\",\n                \"country_area\": u\"南美洲\",\n                \"id\": 93\n            },\n            {\n                \"phone_pre\": \"+00501\",\n                \"short_code\": \"BZ\",\n                \"area_code\": 501,\n                \"name_c\": u\"伯利兹\",\n                \"name_e\": \"Belize\",\n                \"country_area\": u\"南美洲\",\n                \"id\": 94\n            },\n            {\n                \"phone_pre\": \"+00503\",\n                \"short_code\": \"SV\",\n                \"area_code\": 503,\n                \"name_c\": u\"萨尔瓦多\",\n                \"name_e\": \"EI Salvador\",\n                \"country_area\": u\"南美洲\",\n                \"id\": 95\n            },\n            {\n                \"phone_pre\": \"+00504\",\n                \"short_code\": \"HN\",\n                \"area_code\": 504,\n                \"name_c\": u\"洪都拉斯\",\n                \"name_e\": \"Honduras\",\n                \"country_area\": u\"南美洲\",\n                \"id\": 96\n            },\n            {\n                \"phone_pre\": \"+00505\",\n                \"short_code\": \"NI\",\n                \"area_code\": 505,\n                \"name_c\": u\"尼加拉瓜\",\n                \"name_e\": \"Nicaragua\",\n                \"country_area\": u\"南美洲\",\n                \"id\": 97\n            },\n            {\n                \"phone_pre\": \"+00506\",\n                \"short_code\": \"CR\",\n                \"area_code\": 506,\n                \"name_c\": u\"哥斯达黎加\",\n                \"name_e\": \"Costa Rica\",\n                \"country_area\": u\"南美洲\",\n                \"id\": 98\n            },\n            {\n                \"phone_pre\": \"+00507\",\n                \"short_code\": \"PA\",\n                \"area_code\": 507,\n                \"name_c\": u\"巴拿马\",\n                \"name_e\": \"Panama\",\n                \"country_area\": u\"南美洲\",\n                \"id\": 99\n            },\n            {\n                \"phone_pre\": \"+00509\",\n                \"short_code\": \"HT\",\n                \"area_code\": 509,\n                \"name_c\": u\"海地\",\n                \"name_e\": \"Haiti\",\n                \"country_area\": u\"南美洲\",\n                \"id\": 100\n            },\n            {\n                \"phone_pre\": \"+00591\",\n                \"short_code\": \"BO\",\n                \"area_code\": 591,\n                \"name_c\": u\"玻利维亚\",\n                \"name_e\": \"Bolivia\",\n                \"country_area\": u\"南美洲\",\n                \"id\": 101\n            },\n            {\n                \"phone_pre\": \"+00592\",\n                \"short_code\": \"GY\",\n                \"area_code\": 592,\n                \"name_c\": u\"圭亚那\",\n                \"name_e\": \"Guyana\",\n                \"country_area\": u\"南美洲\",\n                \"id\": 102\n            },\n            {\n                \"phone_pre\": \"+00593\",\n                \"short_code\": \"EC\",\n                \"area_code\": 593,\n                \"name_c\": u\"厄瓜多尔\",\n                \"name_e\": \"Ecuador\",\n                \"country_area\": u\"南美洲\",\n                \"id\": 103\n            },\n            {\n                \"phone_pre\": \"+00594\",\n                \"short_code\": \"GF\",\n                \"area_code\": 594,\n                \"name_c\": u\"法属圭亚那\",\n                \"name_e\": \"French Guiana\",\n                \"country_area\": u\"南美洲\",\n                \"id\": 104\n            },\n            {\n                \"phone_pre\": \"+00595\",\n                \"short_code\": \"PY\",\n                \"area_code\": 595,\n                \"name_c\": u\"巴拉圭\",\n                \"name_e\": \"Paraguay\",\n                \"country_area\": u\"南美洲\",\n                \"id\": 105\n            },\n            {\n                \"phone_pre\": \"+00596\",\n                \"short_code\": \"MQ\",\n                \"area_code\": 596,\n                \"name_c\": u\"马提尼克\",\n                \"name_e\": \"Martinique\",\n                \"country_area\": u\"南美洲\",\n                \"id\": 106\n            },\n            {\n                \"phone_pre\": \"+00597\",\n                \"short_code\": \"SR\",\n                \"area_code\": 597,\n                \"name_c\": u\"苏里南\",\n                \"name_e\": \"Suriname\",\n                \"country_area\": u\"南美洲\",\n                \"id\": 107\n            },\n            {\n                \"phone_pre\": \"+00598\",\n                \"short_code\": \"UY\",\n                \"area_code\": 598,\n                \"name_c\": u\"乌拉圭\",\n                \"name_e\": \"Uruguay\",\n                \"country_area\": u\"南美洲\",\n                \"id\": 108\n            },\n        ]\n    },\n    {\n        u'北美洲': [\n            {\n                \"phone_pre\": \"+001\",\n                \"short_code\": \"US\",\n                \"area_code\": 1,\n                \"name_c\": u\"美国\",\n                \"name_e\": \"America\",\n                \"country_area\": u\"北美洲\",\n                \"id\": 163\n            },\n            {\n                \"phone_pre\": \"+001\",\n                \"short_code\": \"CA\",\n                \"area_code\": 1,\n                \"name_c\": u\"加拿大\",\n                \"name_e\": \"Canada\",\n                \"country_area\": u\"北美洲\",\n                \"id\": 164\n            },\n            {\n                \"phone_pre\": \"+00502\",\n                \"short_code\": \"GT\",\n                \"area_code\": 502,\n                \"name_c\": u\"瓜地马拉\",\n                \"name_e\": \"Guatemala\",\n                \"country_area\": u\"北美洲\",\n                \"id\": 165\n            },\n            {\n                \"phone_pre\": \"+001242\",\n                \"short_code\": \"BS\",\n                \"area_code\": 1242,\n                \"name_c\": u\"巴哈马\",\n                \"name_e\": \"Bahamas\",\n                \"country_area\": u\"北美洲\",\n                \"id\": 166\n            },\n            {\n                \"phone_pre\": \"+001246\",\n                \"short_code\": \"BB\",\n                \"area_code\": 1246,\n                \"name_c\": u\"巴巴多斯\",\n                \"name_e\": \"Barbados\",\n                \"country_area\": u\"北美洲\",\n                \"id\": 167\n            },\n            {\n                \"phone_pre\": \"+001264\",\n                \"short_code\": \"AI\",\n                \"area_code\": 1264,\n                \"name_c\": u\"安圭拉岛\",\n                \"name_e\": \"Anguilla\",\n                \"country_area\": u\"北美洲\",\n                \"id\": 168\n            },\n            {\n                \"phone_pre\": \"+001268\",\n                \"short_code\": \"AG\",\n                \"area_code\": 1268,\n                \"name_c\": u\"安提瓜和巴布达\",\n                \"name_e\": \"Antigua and Barbuda\",\n                \"country_area\": u\"北美洲\",\n                \"id\": 169\n            },\n            {\n                \"phone_pre\": \"+001345\",\n                \"short_code\": \"KY\",\n                \"area_code\": 1345,\n                \"name_c\": u\"开曼群岛\",\n                \"name_e\": \"Cayman Islands\",\n                \"country_area\": u\"北美洲\",\n                \"id\": 170\n            },\n            {\n                \"phone_pre\": \"+001473\",\n                \"short_code\": \"GD\",\n                \"area_code\": 1473,\n                \"name_c\": u\"格林纳达\",\n                \"name_e\": \"Grenada\",\n                \"country_area\": u\"北美洲\",\n                \"id\": 171\n            },\n            {\n                \"phone_pre\": \"+001758\",\n                \"short_code\": \"LC\",\n                \"area_code\": 1758,\n                \"name_c\": u\"圣卢西亚\",\n                \"name_e\": \"Saint Lucia\",\n                \"country_area\": u\"北美洲\",\n                \"id\": 172\n            },\n            {\n                \"phone_pre\": \"+001787\",\n                \"short_code\": \"PR\",\n                \"area_code\": 1787,\n                \"name_c\": u\"波多黎各\",\n                \"name_e\": \"Puerto Rico\",\n                \"country_area\": u\"北美洲\",\n                \"id\": 173\n            },\n            {\n                \"phone_pre\": \"+001809\",\n                \"short_code\": \"DO\",\n                \"area_code\": 1809,\n                \"name_c\": u\"多米尼加共和国\",\n                \"name_e\": \"Dominican\",\n                \"country_area\": u\"北美洲\",\n                \"id\": 174\n            },\n            {\n                \"phone_pre\": \"+001868\",\n                \"short_code\": \"TT\",\n                \"area_code\": 1868,\n                \"name_c\": u\"特立尼达和多巴哥\",\n                \"name_e\": \"Trinidad and Tobago\",\n                \"country_area\": u\"北美洲\",\n                \"id\": 175\n            },\n            {\n                \"phone_pre\": \"+001876\",\n                \"short_code\": \"JM\",\n                \"area_code\": 1876,\n                \"name_c\": u\"牙买加\",\n                \"name_e\": \"Jamaica\",\n                \"country_area\": u\"北美洲\",\n                \"id\": 176\n            },\n        ]\n    },\n    {\n        u'非洲': [\n            {\n                \"phone_pre\": \"+0020\",\n                \"short_code\": \"EG\",\n                \"area_code\": 20,\n                \"name_c\": u\"埃及\",\n                \"name_e\": \"Egypt\",\n                \"country_area\": u\"非洲\",\n                \"id\": 109\n            },\n            {\n                \"phone_pre\": \"+0027\",\n                \"short_code\": \"ZA\",\n                \"area_code\": 27,\n                \"name_c\": u\"南非\",\n                \"name_e\": \"South Africa\",\n                \"country_area\": u\"非洲\",\n                \"id\": 110\n            },\n            {\n                \"phone_pre\": \"+00212\",\n                \"short_code\": \"MA\",\n                \"area_code\": 212,\n                \"name_c\": u\"摩洛哥\",\n                \"name_e\": \"Morocco\",\n                \"country_area\": u\"非洲\",\n                \"id\": 111\n            },\n            {\n                \"phone_pre\": \"+00213\",\n                \"short_code\": \"DZ\",\n                \"area_code\": 213,\n                \"name_c\": u\"阿尔及利亚\",\n                \"name_e\": \"Algeria\",\n                \"country_area\": u\"非洲\",\n                \"id\": 112\n            },\n            {\n                \"phone_pre\": \"+00216\",\n                \"short_code\": \"TN\",\n                \"area_code\": 216,\n                \"name_c\": u\"突尼斯\",\n                \"name_e\": \"Tunisia\",\n                \"country_area\": u\"非洲\",\n                \"id\": 113\n            },\n            {\n                \"phone_pre\": \"+00218\",\n                \"short_code\": \"LY\",\n                \"area_code\": 218,\n                \"name_c\": u\"利比亚\",\n                \"name_e\": \"Libya\",\n                \"country_area\": u\"非洲\",\n                \"id\": 114\n            },\n            {\n                \"phone_pre\": \"+00220\",\n                \"short_code\": \"GM\",\n                \"area_code\": 220,\n                \"name_c\": u\"冈比亚\",\n                \"name_e\": \"Gambia\",\n                \"country_area\": u\"非洲\",\n                \"id\": 115\n            },\n            {\n                \"phone_pre\": \"+00221\",\n                \"short_code\": \"SN\",\n                \"area_code\": 221,\n                \"name_c\": u\"塞内加尔\",\n                \"name_e\": \"Senegal\",\n                \"country_area\": u\"非洲\",\n                \"id\": 116\n            },\n            {\n                \"phone_pre\": \"+00223\",\n                \"short_code\": \"ML\",\n                \"area_code\": 223,\n                \"name_c\": u\"马里\",\n                \"name_e\": \"Mali\",\n                \"country_area\": u\"非洲\",\n                \"id\": 117\n            },\n            {\n                \"phone_pre\": \"+00224\",\n                \"short_code\": \"GN\",\n                \"area_code\": 224,\n                \"name_c\": u\"几内亚\",\n                \"name_e\": \"Guinea\",\n                \"country_area\": u\"非洲\",\n                \"id\": 118\n            },\n            {\n                \"phone_pre\": \"+00225\",\n                \"short_code\": \"CI\",\n                \"area_code\": 225,\n                \"name_c\": u\"科特迪瓦\",\n                \"name_e\": \"Ivory Coast\",\n                \"country_area\": u\"非洲\",\n                \"id\": 119\n            },\n            {\n                \"phone_pre\": \"+00226\",\n                \"short_code\": \"BF\",\n                \"area_code\": 226,\n                \"name_c\": u\"布基纳法索\",\n                \"name_e\": \"Burkina Faso\",\n                \"country_area\": u\"非洲\",\n                \"id\": 120\n            },\n            {\n                \"phone_pre\": \"+00227\",\n                \"short_code\": \"NE\",\n                \"area_code\": 227,\n                \"name_c\": u\"尼日尔\",\n                \"name_e\": \"Niger\",\n                \"country_area\": u\"非洲\",\n                \"id\": 121\n            },\n            {\n                \"phone_pre\": \"+00228\",\n                \"short_code\": \"TG\",\n                \"area_code\": 228,\n                \"name_c\": u\"多哥\",\n                \"name_e\": \"Togo\",\n                \"country_area\": u\"非洲\",\n                \"id\": 122\n            },\n            {\n                \"phone_pre\": \"+00229\",\n                \"short_code\": \"BJ\",\n                \"area_code\": 229,\n                \"name_c\": u\"贝宁\",\n                \"name_e\": \"Benin\",\n                \"country_area\": u\"非洲\",\n                \"id\": 123\n            },\n            {\n                \"phone_pre\": \"+00230\",\n                \"short_code\": \"MU\",\n                \"area_code\": 230,\n                \"name_c\": u\"毛里求斯\",\n                \"name_e\": \"Mauritius\",\n                \"country_area\": u\"非洲\",\n                \"id\": 124\n            },\n            {\n                \"phone_pre\": \"+00231\",\n                \"short_code\": \"LR\",\n                \"area_code\": 231,\n                \"name_c\": u\"利比里亚\",\n                \"name_e\": \"Liberia\",\n                \"country_area\": u\"非洲\",\n                \"id\": 125\n            },\n            {\n                \"phone_pre\": \"+00232\",\n                \"short_code\": \"SL\",\n                \"area_code\": 232,\n                \"name_c\": u\"塞拉利昂\",\n                \"name_e\": \"Sierra Leone\",\n                \"country_area\": u\"非洲\",\n                \"id\": 126\n            },\n            {\n                \"phone_pre\": \"+00233\",\n                \"short_code\": \"GH\",\n                \"area_code\": 233,\n                \"name_c\": u\"加纳\",\n                \"name_e\": \"Ghana\",\n                \"country_area\": u\"非洲\",\n                \"id\": 127\n            },\n            {\n                \"phone_pre\": \"+00234\",\n                \"short_code\": \"NG\",\n                \"area_code\": 234,\n                \"name_c\": u\"尼日利亚\",\n                \"name_e\": \"Nigeria\",\n                \"country_area\": u\"非洲\",\n                \"id\": 128\n            },\n            {\n                \"phone_pre\": \"+00235\",\n                \"short_code\": \"TD\",\n                \"area_code\": 235,\n                \"name_c\": u\"乍得\",\n                \"name_e\": \"Chad\",\n                \"country_area\": u\"非洲\",\n                \"id\": 129\n            },\n            {\n                \"phone_pre\": \"+00236\",\n                \"short_code\": \"CF\",\n                \"area_code\": 236,\n                \"name_c\": u\"中非共和国\",\n                \"name_e\": \"Central Africa\",\n                \"country_area\": u\"非洲\",\n                \"id\": 130\n            },\n            {\n                \"phone_pre\": \"+00237\",\n                \"short_code\": \"CM\",\n                \"area_code\": 237,\n                \"name_c\": u\"喀麦隆\",\n                \"name_e\": \"Cameroon\",\n                \"country_area\": u\"非洲\",\n                \"id\": 131\n            },\n            {\n                \"phone_pre\": \"+00239\",\n                \"short_code\": \"ST\",\n                \"area_code\": 239,\n                \"name_c\": u\"圣多美和普林西比\",\n                \"name_e\": \"Sao Tome and Principe\",\n                \"country_area\": u\"非洲\",\n                \"id\": 132\n            },\n            {\n                \"phone_pre\": \"+00241\",\n                \"short_code\": \"GA\",\n                \"area_code\": 241,\n                \"name_c\": u\"加蓬\",\n                \"name_e\": \"Gabon\",\n                \"country_area\": u\"非洲\",\n                \"id\": 133\n            },\n            {\n                \"phone_pre\": \"+00243\",\n                \"short_code\": \"CG\",\n                \"area_code\": 243,\n                \"name_c\": u\"刚果民主共和国\",\n                \"name_e\": \"Congo\",\n                \"country_area\": u\"非洲\",\n                \"id\": 134\n            },\n            {\n                \"phone_pre\": \"+00244\",\n                \"short_code\": \"AO\",\n                \"area_code\": 244,\n                \"name_c\": u\"安哥拉\",\n                \"name_e\": \"Angola\",\n                \"country_area\": u\"非洲\",\n                \"id\": 135\n            },\n            {\n                \"phone_pre\": \"+00248\",\n                \"short_code\": \"SC\",\n                \"area_code\": 248,\n                \"name_c\": u\"塞舌尔\",\n                \"name_e\": \"Seychelles\",\n                \"country_area\": u\"非洲\",\n                \"id\": 136\n            },\n            {\n                \"phone_pre\": \"+00249\",\n                \"short_code\": \"SD\",\n                \"area_code\": 249,\n                \"name_c\": u\"苏丹\",\n                \"name_e\": \"Sudan\",\n                \"country_area\": u\"非洲\",\n                \"id\": 137\n            },\n            {\n                \"phone_pre\": \"+00251\",\n                \"short_code\": \"ET\",\n                \"area_code\": 251,\n                \"name_c\": u\"埃塞俄比亚\",\n                \"name_e\": \"Ethiopia\",\n                \"country_area\": u\"非洲\",\n                \"id\": 138\n            },\n            {\n                \"phone_pre\": \"+00252\",\n                \"short_code\": \"SO\",\n                \"area_code\": 252,\n                \"name_c\": u\"索马里\",\n                \"name_e\": \"Somali\",\n                \"country_area\": u\"非洲\",\n                \"id\": 139\n            },\n            {\n                \"phone_pre\": \"+00253\",\n                \"short_code\": \"DJ\",\n                \"area_code\": 253,\n                \"name_c\": u\"吉布提\",\n                \"name_e\": \"Djibouti\",\n                \"country_area\": u\"非洲\",\n                \"id\": 140\n            },\n            {\n                \"phone_pre\": \"+00254\",\n                \"short_code\": \"KE\",\n                \"area_code\": 254,\n                \"name_c\": u\"肯尼亚\",\n                \"name_e\": \"Kenya\",\n                \"country_area\": u\"非洲\",\n                \"id\": 141\n            },\n            {\n                \"phone_pre\": \"+00255\",\n                \"short_code\": \"TZ\",\n                \"area_code\": 255,\n                \"name_c\": u\"坦桑尼亚\",\n                \"name_e\": \"Tanzania\",\n                \"country_area\": u\"非洲\",\n                \"id\": 142\n            },\n            {\n                \"phone_pre\": \"+00256\",\n                \"short_code\": \"UG\",\n                \"area_code\": 256,\n                \"name_c\": u\"乌干达\",\n                \"name_e\": \"Uganda\",\n                \"country_area\": u\"非洲\",\n                \"id\": 143\n            },\n            {\n                \"phone_pre\": \"+00257\",\n                \"short_code\": \"BI\",\n                \"area_code\": 257,\n                \"name_c\": u\"布隆迪\",\n                \"name_e\": \"Burundi\",\n                \"country_area\": u\"非洲\",\n                \"id\": 144\n            },\n            {\n                \"phone_pre\": \"+00258\",\n                \"short_code\": \"MZ\",\n                \"area_code\": 258,\n                \"name_c\": u\"莫桑比克\",\n                \"name_e\": \"Mozambique\",\n                \"country_area\": u\"非洲\",\n                \"id\": 145\n            },\n            {\n                \"phone_pre\": \"+00260\",\n                \"short_code\": \"ZM\",\n                \"area_code\": 260,\n                \"name_c\": u\"赞比亚\",\n                \"name_e\": \"Zambia\",\n                \"country_area\": u\"非洲\",\n                \"id\": 146\n            },\n            {\n                \"phone_pre\": \"+00261\",\n                \"short_code\": \"MG\",\n                \"area_code\": 261,\n                \"name_c\": u\"马达加斯加\",\n                \"name_e\": \"Madagascar\",\n                \"country_area\": u\"非洲\",\n                \"id\": 147\n            },\n            {\n                \"phone_pre\": \"+00263\",\n                \"short_code\": \"ZW\",\n                \"area_code\": 263,\n                \"name_c\": u\"津巴布韦\",\n                \"name_e\": \"Zimbabwe\",\n                \"country_area\": u\"非洲\",\n                \"id\": 148\n            },\n            {\n                \"phone_pre\": \"+00264\",\n                \"short_code\": \"NA\",\n                \"area_code\": 264,\n                \"name_c\": u\"纳米比亚\",\n                \"name_e\": \"Namibia\",\n                \"country_area\": u\"非洲\",\n                \"id\": 149\n            },\n            {\n                \"phone_pre\": \"+00265\",\n                \"short_code\": \"MW\",\n                \"area_code\": 265,\n                \"name_c\": u\"马拉维\",\n                \"name_e\": \"Malawi\",\n                \"country_area\": u\"非洲\",\n                \"id\": 150\n            },\n            {\n                \"phone_pre\": \"+00266\",\n                \"short_code\": \"LS\",\n                \"area_code\": 266,\n                \"name_c\": u\"莱索托\",\n                \"name_e\": \"Lesotho\",\n                \"country_area\": u\"非洲\",\n                \"id\": 151\n            },\n            {\n                \"phone_pre\": \"+00267\",\n                \"short_code\": \"BW\",\n                \"area_code\": 267,\n                \"name_c\": u\"博茨瓦纳\",\n                \"name_e\": \"Botswana\",\n                \"country_area\": u\"非洲\",\n                \"id\": 152\n            },\n            {\n                \"phone_pre\": \"+00268\",\n                \"short_code\": \"SZ\",\n                \"area_code\": 268,\n                \"name_c\": u\"斯威士兰\",\n                \"name_e\": \"Swaziland\",\n                \"country_area\": u\"非洲\",\n                \"id\": 153\n            },\n        ]\n    },\n    {\n        u'大洋洲': [\n            {\n                \"phone_pre\": \"+0061\",\n                \"short_code\": \"AU\",\n                \"area_code\": 61,\n                \"name_c\": u\"澳大利亚\",\n                \"name_e\": \"Australia\",\n                \"country_area\": u\"大洋洲\",\n                \"id\": 154\n            },\n            {\n                \"phone_pre\": \"+0064\",\n                \"short_code\": \"NZ\",\n                \"area_code\": 64,\n                \"name_c\": u\"新西兰\",\n                \"name_e\": \"New Zealand\",\n                \"country_area\": u\"大洋洲\",\n                \"id\": 155\n            },\n            {\n                \"phone_pre\": \"+00675\",\n                \"short_code\": \"PG\",\n                \"area_code\": 675,\n                \"name_c\": u\"巴布亚新几内亚\",\n                \"name_e\": \"Papua New Guinea\",\n                \"country_area\": u\"大洋洲\",\n                \"id\": 156\n            },\n            {\n                \"phone_pre\": \"+00676\",\n                \"short_code\": \"TO\",\n                \"area_code\": 676,\n                \"name_c\": u\"汤加\",\n                \"name_e\": \"Tonga\",\n                \"country_area\": u\"大洋洲\",\n                \"id\": 157\n            },\n            {\n                \"phone_pre\": \"+00677\",\n                \"short_code\": \"SB\",\n                \"area_code\": 677,\n                \"name_c\": u\"所罗门群岛\",\n                \"name_e\": \"Solomon Is\",\n                \"country_area\": u\"大洋洲\",\n                \"id\": 158\n            },\n            {\n                \"phone_pre\": \"+00679\",\n                \"short_code\": \"FJ\",\n                \"area_code\": 679,\n                \"name_c\": u\"斐济\",\n                \"name_e\": \"Fiji\",\n                \"country_area\": u\"大洋洲\",\n                \"id\": 159\n            },\n            {\n                \"phone_pre\": \"+00682\",\n                \"short_code\": \"CK\",\n                \"area_code\": 682,\n                \"name_c\": u\"库克群岛\",\n                \"name_e\": \"Cook Islands\",\n                \"country_area\": u\"大洋洲\",\n                \"id\": 160\n            },\n            {\n                \"phone_pre\": \"+001671\",\n                \"short_code\": \"GU\",\n                \"area_code\": 1671,\n                \"name_c\": u\"关岛\",\n                \"name_e\": \"Guam\",\n                \"country_area\": u\"大洋洲\",\n                \"id\": 161\n            },\n        ]\n    },\n    {\n        u'太平洋': [\n            {\n                \"phone_pre\": \"+00689\",\n                \"short_code\": \"PF\",\n                \"area_code\": 689,\n                \"name_c\": u\"法属波利尼西亚\",\n                \"name_e\": \"French Polynesia\",\n                \"country_area\": u\"太平洋\",\n                \"id\": 46\n            },\n        ]\n    },\n    {\n        u'大西洋': [\n            {\n                \"phone_pre\": \"+001441\",\n                \"short_code\": \"BM\",\n                \"area_code\": 1441,\n                \"name_c\": u\"百慕大群岛\",\n                \"name_e\": \"Bermuda\",\n                \"country_area\": u\"大西洋\",\n                \"id\": 162\n            },\n        ]\n    }\n]\n\n\narea_code_map = {\n    '0': '86',  # [CN]中国(China) 亚洲\n    '1': '852',  # [HK]中国香港(Hongkong) 亚洲\n    '2': '853',  # [MO]中国澳门(Macao) 亚洲\n    '3': '886',  # [TW]中国台湾(Taiwan) 亚洲\n    '4': '60',  # [MY]马来西亚(Malaysia) 亚洲\n    '5': '65',  # [SG]新加坡(Singapore) 亚洲\n    '6': '62',  # [ID]印度尼西亚(Indonesia) 亚洲\n    '7': '63',  # [PH]菲律宾(Philippines) 亚洲\n    '8': '66',  # [TH]泰国(Thailand) 亚洲\n    '9': '73',  # [KZ]哈萨克斯坦(Kazakhstan) 亚洲\n    '10': '81',  # [JP]日本(Japan) 亚洲\n    '11': '82',  # [KR]韩国(Korea) 亚洲\n    '12': '84',  # [VN]越南(Vietnam) 亚洲\n    '13': '90',  # [TR]土耳其(Turkey) 亚洲\n    '14': '91',  # [IN]印度(India) 亚洲\n    '15': '92',  # [PK]巴基斯坦(Pakistan) 亚洲\n    '16': '93',  # [AF]阿富汗(Afghanistan) 亚洲\n    '17': '94',  # [LK]斯里兰卡(Sri Lanka) 亚洲\n    '18': '95',  # [MM]缅甸(Burma) 亚洲\n    '19': '98',  # [IR]伊朗(Iran) 亚洲\n    '20': '374',  # [AM]亚美尼亚(Armenia) 亚洲\n    '21': '673',  # [BN]文莱(Brunei) 亚洲\n    '22': '855',  # [KH]柬埔寨(Cambodia) 亚洲\n    '23': '856',  # [LA]老挝(Laos) 亚洲\n    '24': '880',  # [BD]孟加拉国(Bangladesh) 亚洲\n    '25': '960',  # [MV]马尔代夫(Maldives) 亚洲\n    '26': '961',  # [LB]黎巴嫩(Lebanon) 亚洲\n    '27': '962',  # [JO]约旦(Jordan) 亚洲\n    '28': '963',  # [SY]叙利亚(Syria) 亚洲\n    '29': '964',  # [IQ]伊拉克(Iraq) 亚洲\n    '30': '965',  # [KW]科威特(Kuwait) 亚洲\n    '31': '966',  # [SA]沙特阿拉伯(Saudi Arabia) 亚洲\n    '32': '967',  # [YE]也门(Yemen) 亚洲\n    '33': '968',  # [OM]阿曼(Oman) 亚洲\n    '34': '971',  # [AE]阿拉伯联合酋长国(Arab Emirates) 亚洲\n    '35': '972',  # [IL]以色列(Israel) 亚洲\n    '36': '973',  # [BH]巴林(Bahrain) 亚洲\n    '37': '974',  # [QA]卡塔尔(Qatar) 亚洲\n    '38': '976',  # [MN]蒙古(Mongolia) 亚洲\n    '39': '977',  # [NP]尼泊尔(Nepal) 亚洲\n    '40': '992',  # [TJ]塔吉克斯坦(Tajikistan) 亚洲\n    '41': '993',  # [TM]土库曼斯坦(Turkmenistan) 亚洲\n    '42': '994',  # [AZ]阿塞拜疆(Azerbaijan) 亚洲\n    '43': '995',  # [GE]格鲁吉亚(Georgia) 亚洲\n    '44': '996',  # [KG]吉尔吉斯斯坦(Kyrgyzstan) 亚洲\n    '45': '998',  # [UZ]乌兹别克斯坦(Uzbekistan) 亚洲\n    '46': '689',  # [PF]法属波利尼西亚(French Polynesia) 太平洋\n    '47': '44',  # [GB]英国(United Kiongdom) 欧洲\n    '48': '49',  # [DE]德国(Germany) 欧洲\n    '49': '7',  # [RU]俄罗斯(Russia) 欧洲\n    '50': '30',  # [GR]希腊(Greece) 欧洲\n    '51': '31',  # [NL]荷兰(Netherlands) 欧洲\n    '52': '32',  # [BE]比利时(Belgium) 欧洲\n    '53': '33',  # [FR]法国(France) 欧洲\n    '54': '34',  # [ES]西班牙(Spain) 欧洲\n    '55': '36',  # [HU]匈牙利(Hungary) 欧洲\n    '56': '39',  # [IT]意大利(Italy) 欧洲\n    '57': '40',  # [RO]罗马尼亚(Romania) 欧洲\n    '58': '41',  # [CH]瑞士(Switzerland) 欧洲\n    '59': '43',  # [AT]奥地利(Austria) 欧洲\n    '60': '45',  # [DK]丹麦(Denmark) 欧洲\n    '61': '46',  # [SE]瑞典(Sweden) 欧洲\n    '62': '47',  # [NO]挪威(Norway) 欧洲\n    '63': '48',  # [PL]波兰(Poland) 欧洲\n    '64': '350',  # [GI]直布罗陀(Gibraltar) 欧洲\n    '65': '351',  # [PT]葡萄牙(Portugal) 欧洲\n    '66': '352',  # [LU]卢森堡(Luxembourg) 欧洲\n    '67': '353',  # [IE]爱尔兰(Ireland) 欧洲\n    '68': '354',  # [IS]冰岛(Iceland) 欧洲\n    '69': '355',  # [AL]阿尔巴尼亚(Albania) 欧洲\n    '70': '356',  # [MT]马耳他(Malta) 欧洲\n    '71': '357',  # [CY]塞浦路斯(Cyprus) 欧洲\n    '72': '358',  # [FI]芬兰(Finland) 欧洲\n    '73': '359',  # [BG]保加利亚(Bulgaria) 欧洲\n    '74': '370',  # [LT]立陶宛(Lithuania) 欧洲\n    '75': '371',  # [LV]拉脱维亚(Latvia) 欧洲\n    '76': '372',  # [EE]爱沙尼亚(Estonia) 欧洲\n    '77': '373',  # [MD]摩尔多瓦(Moldova) 欧洲\n    '78': '375',  # [BY]白俄罗斯(Belarus) 欧洲\n    '79': '377',  # [MC]摩纳哥(Monaco) 欧洲\n    '80': '378',  # [SM]圣马力诺(San Marino) 欧洲\n    '81': '380',  # [UA]乌克兰(Ukraine) 欧洲\n    '82': '386',  # [SI]斯洛文尼亚(Slovenia) 欧洲\n    '83': '420',  # [CZ]捷克(Czech) 欧洲\n    '84': '421',  # [SK]斯洛伐克(Slovak) 欧洲\n    '85': '423',  # [LI]列支敦士登(Liechtenstein) 欧洲\n    '86': '51',  # [PE]秘鲁(Peru) 南美洲\n    '87': '52',  # [MX]墨西哥(Mexico) 南美洲\n    '88': '53',  # [CU]古巴(Cuba) 南美洲\n    '89': '54',  # [AR]阿根廷(Argentina) 南美洲\n    '90': '55',  # [BR]巴西(Brazil) 南美洲\n    '91': '56',  # [CL]智利(Chile) 南美洲\n    '92': '57',  # [CO]哥伦比亚(Colombia) 南美洲\n    '93': '58',  # [VE]委内瑞拉(Venezuela) 南美洲\n    '94': '501',  # [BZ]伯利兹(Belize) 南美洲\n    '95': '503',  # [SV]萨尔瓦多(EI Salvador) 南美洲\n    '96': '504',  # [HN]洪都拉斯(Honduras) 南美洲\n    '97': '505',  # [NI]尼加拉瓜(Nicaragua) 南美洲\n    '98': '506',  # [CR]哥斯达黎加(Costa Rica) 南美洲\n    '99': '507',  # [PA]巴拿马(Panama) 南美洲\n    '100': '509',  # [HT]海地(Haiti) 南美洲\n    '101': '591',  # [BO]玻利维亚(Bolivia) 南美洲\n    '102': '592',  # [GY]圭亚那(Guyana) 南美洲\n    '103': '593',  # [EC]厄瓜多尔(Ecuador) 南美洲\n    '104': '594',  # [GF]法属圭亚那(French Guiana) 南美洲\n    '105': '595',  # [PY]巴拉圭(Paraguay) 南美洲\n    '106': '596',  # [MQ]马提尼克(Martinique) 南美洲\n    '107': '597',  # [SR]苏里南(Suriname) 南美洲\n    '108': '598',  # [UY]乌拉圭(Uruguay) 南美洲\n    '109': '20',  # [EG]埃及(Egypt) 非洲\n    '110': '27',  # [ZA]南非(South Africa) 非洲\n    '111': '212',  # [MA]摩洛哥(Morocco) 非洲\n    '112': '213',  # [DZ]阿尔及利亚(Algeria) 非洲\n    '113': '216',  # [TN]突尼斯(Tunisia) 非洲\n    '114': '218',  # [LY]利比亚(Libya) 非洲\n    '115': '220',  # [GM]冈比亚(Gambia) 非洲\n    '116': '221',  # [SN]塞内加尔(Senegal) 非洲\n    '117': '223',  # [ML]马里(Mali) 非洲\n    '118': '224',  # [GN]几内亚(Guinea) 非洲\n    '119': '225',  # [CI]科特迪瓦(Ivory Coast) 非洲\n    '120': '226',  # [BF]布基纳法索(Burkina Faso) 非洲\n    '121': '227',  # [NE]尼日尔(Niger) 非洲\n    '122': '228',  # [TG]多哥(Togo) 非洲\n    '123': '229',  # [BJ]贝宁(Benin) 非洲\n    '124': '230',  # [MU]毛里求斯(Mauritius) 非洲\n    '125': '231',  # [LR]利比里亚(Liberia) 非洲\n    '126': '232',  # [SL]塞拉利昂(Sierra Leone) 非洲\n    '127': '233',  # [GH]加纳(Ghana) 非洲\n    '128': '234',  # [NG]尼日利亚(Nigeria) 非洲\n    '129': '235',  # [TD]乍得(Chad) 非洲\n    '130': '236',  # [CF]中非共和国(Central Africa) 非洲\n    '131': '237',  # [CM]喀麦隆(Cameroon) 非洲\n    '132': '239',  # [ST]圣多美和普林西比(Sao Tome and Principe) 非洲\n    '133': '241',  # [GA]加蓬(Gabon) 非洲\n    '134': '243',  # [CG]刚果民主共和国(Congo) 非洲\n    '135': '244',  # [AO]安哥拉(Angola) 非洲\n    '136': '248',  # [SC]塞舌尔(Seychelles) 非洲\n    '137': '249',  # [SD]苏丹(Sudan) 非洲\n    '138': '251',  # [ET]埃塞俄比亚(Ethiopia) 非洲\n    '139': '252',  # [SO]索马里(Somali) 非洲\n    '140': '253',  # [DJ]吉布提(Djibouti) 非洲\n    '141': '254',  # [KE]肯尼亚(Kenya) 非洲\n    '142': '255',  # [TZ]坦桑尼亚(Tanzania) 非洲\n    '143': '256',  # [UG]乌干达(Uganda) 非洲\n    '144': '257',  # [BI]布隆迪(Burundi) 非洲\n    '145': '258',  # [MZ]莫桑比克(Mozambique) 非洲\n    '146': '260',  # [ZM]赞比亚(Zambia) 非洲\n    '147': '261',  # [MG]马达加斯加(Madagascar) 非洲\n    '148': '263',  # [ZW]津巴布韦(Zimbabwe) 非洲\n    '149': '264',  # [nan]纳米比亚(Namibia) 非洲\n    '150': '265',  # [MW]马拉维(Malawi) 非洲\n    '151': '266',  # [LS]莱索托(Lesotho) 非洲\n    '152': '267',  # [BW]博茨瓦纳(Botswana) 非洲\n    '153': '268',  # [SZ]斯威士兰(Swaziland) 非洲\n    '154': '61',  # [AU]澳大利亚(Australia) 大洋洲\n    '155': '64',  # [NZ]新西兰(New Zealand) 大洋洲\n    '156': '675',  # [PG]巴布亚新几内亚(Papua New Guinea) 大洋洲\n    '157': '676',  # [TO]汤加(Tonga) 大洋洲\n    '158': '677',  # [SB]所罗门群岛(Solomon Is) 大洋洲\n    '159': '679',  # [FJ]斐济(Fiji) 大洋洲\n    '160': '682',  # [CK]库克群岛(Cook Islands) 大洋洲\n    '161': '1671',  # [GU]关岛(Guam) 大洋洲\n    '162': '1441',  # [BM]百慕大群岛(Bermuda) 大西洋\n    '163': '1',  # [US]美国(America) 北美洲\n    '164': '1',  # [CA]加拿大(Canada) 北美洲\n    '165': '502',  # [GT]瓜地马拉(Guatemala) 北美洲\n    '166': '1242',  # [BS]巴哈马(Bahamas) 北美洲\n    '167': '1246',  # [BB]巴巴多斯(Barbados) 北美洲\n    '168': '1264',  # [AI]安圭拉岛(Anguilla) 北美洲\n    '169': '1268',  # [AG]安提瓜和巴布达(Antigua and Barbuda) 北美洲\n    '170': '1345',  # [KY]开曼群岛(Cayman Islands) 北美洲\n    '171': '1473',  # [GD]格林纳达(Grenada) 北美洲\n    '172': '1758',  # [LC]圣卢西亚(Saint Lucia) 北美洲\n    '173': '1787',  # [PR]波多黎各(Puerto Rico) 北美洲\n    '174': '1809',  # [DO]多米尼加共和国(Dominican) 北美洲\n    '175': '1868',  # [TT]特立尼达和多巴哥(Trinidad and Tobago) 北美洲\n    '176': '1876',  # [JM]牙买加(Jamaica) 北美洲\n}\n\n\nif __name__ == '__main__':\n    # html = ['<select>']\n    # for area_data in area_code_list:\n    #     for area_name, area_list in area_data.items():\n    #         html.append('\\t<optgroup label=\"%s\">' % area_name)\n    #         for country_data in area_list:\n    #             html.append('\\t\\t<option value=\"%s\" data-subtext=\"%s(%s)\">[%s] %s</option>' % (\n    #             country_data['id'], country_data['name_c'], country_data['name_e'], country_data['short_code'],\n    #             country_data['phone_pre']))\n    #         html.append('\\t</optgroup>')\n    # html.append('</select>')\n    # print '\\n'.join(html)\n    area_code_choices = []\n    for m, n in enumerate(area_code_list):\n        area_code_choices.append((m, n))\n    print area_code_choices\n"
  },
  {
    "path": "app_common/maps/output.py",
    "content": "#!/usr/bin/env python\n# encoding: utf-8\n\n\"\"\"\n@author: zhanghe\n@software: PyCharm\n@file: output.py\n@time: 2017/4/17 下午11:15\n\"\"\"\n\nimport pandas as pd\nimport json\n\n\ndef area_code_list():\n    file_path = '全球区号.xlsx'\n    df = pd.read_excel(file_path, sheetname='code')  # sheet_name=str(0)\n    print list(df.keys())\n    for i in df.values:\n        code_dict = {\n            'id': i[0],\n            'name_c': i[1],\n            'area_code': i[2],\n            'phone_pre': '+00%s' % i[2],\n            'country_area': i[3],\n            'short_code': i[4],\n            'name_e': i[5]\n        }\n        print json.dumps(code_dict, indent=4, ensure_ascii=False)+','\n\n\ndef area_code_map():\n    file_path = '全球区号.xlsx'\n    df = pd.read_excel(file_path, sheetname='code')  # sheet_name=str(0)\n    print list(df.keys())\n    for i in df.values:\n        print '%s: \\'%s\\',  # [%s]%s(%s) %s' % (i[0], i[2], i[4], i[1], i[5], i[3])\n\n\nif __name__ == '__main__':\n    area_code_list()\n    area_code_map()\n"
  },
  {
    "path": "app_common/maps/role_admin.py",
    "content": "#!/usr/bin/env python\n# encoding: utf-8\n\n\"\"\"\n@author: zhanghe\n@software: PyCharm\n@file: role_admin.py\n@time: 2017/4/28 上午12:34\n\"\"\"\n\n\n# 管理角色:\n# 1 系统\n# 2 客服\n# 3 运营\n# 4 市场\n# 5 销售\n# 6 普通\n# 7 高级\n\nROLE_ADMIN_SYSTEM = 1\nROLE_ADMIN_CS = 2\nROLE_ADMIN_OP = 3\nROLE_ADMIN_MARKET = 4\nROLE_ADMIN_SALES = 5\nROLE_ADMIN_JUNIOR = 6\nROLE_ADMIN_SENIOR = 7\n\nROLE_ADMIN_DICT = {\n    1: u'系统',\n    2: u'客服',\n    3: u'运营',\n    4: u'市场',\n    5: u'销售',\n    6: u'普通',\n    7: u'高级',\n}\n"
  },
  {
    "path": "app_common/maps/status_active.py",
    "content": "#!/usr/bin/env python\n# encoding: utf-8\n\n\"\"\"\n@author: zhanghe\n@software: PyCharm\n@file: status_active.py\n@time: 2017/5/3 下午7:54\n\"\"\"\n\n\n# 激活状态（0未激活，1已激活）\nSTATUS_ACTIVE_NO = '0'\nSTATUS_ACTIVE_OK = '1'\n\nSTATUS_ACTIVE_DICT = {\n    0: u'未激活',\n    1: u'已激活',\n}\n"
  },
  {
    "path": "app_common/maps/status_apply.py",
    "content": "#!/usr/bin/env python\n# encoding: utf-8\n\n\"\"\"\n@author: zhanghe\n@software: PyCharm\n@file: status_apply.py\n@time: 2017/4/27 上午11:44\n\"\"\"\n\n\n# 申请状态:0:待生效，1:生效，2:取消\nSTATUS_APPLY_HANDING = '0'\nSTATUS_APPLY_SUCCESS = '1'\nSTATUS_APPLY_CANCEL = '2'\n\nSTATUS_APPLY_DICT = {\n    0: u'待生效',\n    1: u'生效',\n    2: u'取消',\n}\n"
  },
  {
    "path": "app_common/maps/status_audit.py",
    "content": "#!/usr/bin/env python\n# encoding: utf-8\n\n\"\"\"\n@author: zhanghe\n@software: PyCharm\n@file: status_audit.py\n@time: 2017/4/29 上午10:51\n\"\"\"\n\n\n# 审核状态:0:待审核，1:审核通过，2:审核失败\nSTATUS_AUDIT_HANDING = '0'\nSTATUS_AUDIT_SUCCESS = '1'\nSTATUS_AUDIT_CANCEL = '2'\n\nSTATUS_AUDIT_DICT = {\n    0: u'待审核',\n    1: u'审核通过',\n    2: u'审核失败',\n}\n"
  },
  {
    "path": "app_common/maps/status_delete.py",
    "content": "#!/usr/bin/env python\n# encoding: utf-8\n\n\"\"\"\n@author: zhanghe\n@software: PyCharm\n@file: status_delete.py\n@time: 2017/4/27 下午3:31\n\"\"\"\n\n\n# 删除状态:0:未删除，1:已删除\nSTATUS_DEL_NO = '0'\nSTATUS_DEL_OK = '1'\n\nSTATUS_DEL_DICT = {\n    0: u'未删除',\n    1: u'已删除',\n}\n"
  },
  {
    "path": "app_common/maps/status_flow.py",
    "content": "#!/usr/bin/env python\n# encoding: utf-8\n\n\"\"\"\n@author: zhanghe\n@software: PyCharm\n@file: status_flow.py\n@time: 2017/6/30 下午1:31\n\"\"\"\n\n\n# 流转状态:0:未流转，1:已流转'\nSTATUS_FLOW_NO = '0'\nSTATUS_FLOW_OK = '1'\n\nSTATUS_FLOW_DICT = {\n    0: u'未流转',\n    1: u'已流转',\n}\n"
  },
  {
    "path": "app_common/maps/status_lock.py",
    "content": "#!/usr/bin/env python\n# encoding: utf-8\n\n\"\"\"\n@author: zhanghe\n@software: PyCharm\n@file: status_lock.py\n@time: 2017/5/1 上午02:44\n\"\"\"\n\n\n# 锁定状态（0未锁定，1已锁定）\nSTATUS_LOCK_NO = '0'\nSTATUS_LOCK_OK = '1'\n\nSTATUS_LOCK_DICT = {\n    0: u'未锁定',\n    1: u'已锁定',\n}\n"
  },
  {
    "path": "app_common/maps/status_order.py",
    "content": "#!/usr/bin/env python\n# encoding: utf-8\n\n\"\"\"\n@author: zhanghe\n@software: PyCharm\n@file: status_order.py\n@time: 2017/4/27 上午11:44\n\"\"\"\n\n\n# 订单状态:0:待匹配，1:部分匹配，2:完全匹配\nSTATUS_ORDER_HANDING = '0'\nSTATUS_ORDER_PROCESSING = '1'\nSTATUS_ORDER_COMPLETED = '2'\n\nSTATUS_ORDER_DICT = {\n    0: u'待匹配',\n    1: u'部分匹配',\n    2: u'完全匹配',\n}\n"
  },
  {
    "path": "app_common/maps/status_pay.py",
    "content": "#!/usr/bin/env python\n# encoding: utf-8\n\n\"\"\"\n@author: zhanghe\n@software: PyCharm\n@file: status_pay.py\n@time: 2017/4/27 下午1:46\n\"\"\"\n\n\n# 支付状态:0:待支付，1:支付成功，2:支付失败\nSTATUS_PAY_HOLDING = '0'\nSTATUS_PAY_SUCCESS = '1'\nSTATUS_PAY_FAILURE = '2'\n\nSTATUS_PAY_DICT = {\n    0: u'待支付',\n    1: u'支付成功',\n    2: u'支付失败',\n}\n"
  },
  {
    "path": "app_common/maps/status_rec.py",
    "content": "#!/usr/bin/env python\n# encoding: utf-8\n\n\"\"\"\n@author: zhanghe\n@software: PyCharm\n@file: status_rec.py\n@time: 2017/4/27 下午1:39\n\"\"\"\n\n\n# 收款状态:0:待收款，1:收款成功，2:收款失败\nSTATUS_REC_HOLDING = '0'\nSTATUS_REC_SUCCESS = '1'\nSTATUS_REC_FAILURE = '2'\n\nSTATUS_REC_DICT = {\n    0: u'待收款',\n    1: u'收款成功',\n    2: u'收款失败',\n}\n"
  },
  {
    "path": "app_common/maps/status_reply.py",
    "content": "#!/usr/bin/env python\n# encoding: utf-8\n\n\"\"\"\n@author: zhanghe\n@software: PyCharm\n@file: status_reply.py\n@time: 2017/4/29 上午10:51\n\"\"\"\n\n\n# 回复状态（0未回复，1已回复）\nSTATUS_REPLY_HANDING = '0'\nSTATUS_REPLY_SUCCESS = '1'\n\nSTATUS_REPLY_DICT = {\n    0: u'未回复',\n    1: u'已回复',\n}\n"
  },
  {
    "path": "app_common/maps/type_active.py",
    "content": "#!/usr/bin/env python\n# encoding: utf-8\n\n\"\"\"\n@author: zhanghe\n@software: PyCharm\n@file: type_active.py\n@time: 2017/5/13 下午2:15\n\"\"\"\n\n\n# 激活类型（1：激活、2：赠送）\nTYPE_ACTIVE = '0'\nTYPE_ACTIVE_USER = '1'\nTYPE_ACTIVE_GIVE = '2'\n\nTYPE_ACTIVE_DICT = {\n    0: u'不限',\n    1: u'激活',\n    2: u'赠送'\n}\n"
  },
  {
    "path": "app_common/maps/type_apply.py",
    "content": "#!/usr/bin/env python\n# encoding: utf-8\n\n\"\"\"\n@author: zhanghe\n@software: PyCharm\n@file: type_apply.py\n@time: 2017/4/27 下午3:20\n\"\"\"\n\n\n# 申请类型:0:自主添加，1:系统生成\nTYPE_APPLY_USER = '0'\nTYPE_APPLY_ADMIN = '1'\n\nTYPE_APPLY_DICT = {\n    0: u'自主添加',\n    1: u'系统生成',\n}\n"
  },
  {
    "path": "app_common/maps/type_auth.py",
    "content": "#!/usr/bin/env python\n# encoding: utf-8\n\n\"\"\"\n@author: zhanghe\n@software: PyCharm\n@file: type_auth.py\n@time: 2017/4/19 下午8:08\n\"\"\"\n\n\n# 认证类型（0未知，1邮箱，2手机，3qq，4微信，5微博）\nTYPE_AUTH_ACCOUNT = '0'\nTYPE_AUTH_EMAIL = '1'\nTYPE_AUTH_PHONE = '2'\nTYPE_AUTH_QQ = '3'\nTYPE_AUTH_WECHAT = '4'\nTYPE_AUTH_WEIBO = '5'\n\nTYPE_AUTH_DICT = {\n    0: u'未知',\n    1: u'邮箱',\n    2: u'手机',\n    3: u'QQ',\n    4: u'微信',\n    5: u'微博',\n}\n"
  },
  {
    "path": "app_common/maps/type_level.py",
    "content": "#!/usr/bin/env python\n# encoding: utf-8\n\n\"\"\"\n@author: zhanghe\n@software: PyCharm\n@file: type_level.py\n@time: 2017/4/27 上午12:53\n\"\"\"\n\n\n# 等级类型（0普通，1铜牌，2银牌，3金牌，4钻石）\nTYPE_LEVEL_ORDINARY = '0'\nTYPE_LEVEL_COPPER = '1'\nTYPE_LEVEL_SILVER = '2'\nTYPE_LEVEL_GOLD = '3'\nTYPE_LEVEL_DIAMOND = '4'\n\nTYPE_LEVEL_DICT = {\n    0: u'普通',\n    1: u'铜牌',\n    2: u'银牌',\n    3: u'金牌',\n    4: u'钻石',\n}\n"
  },
  {
    "path": "app_common/maps/type_order.py",
    "content": "#!/usr/bin/env python\n# encoding: utf-8\n\n\"\"\"\n@author: zhanghe\n@software: PyCharm\n@file: type_order.py\n@time: 2017/5/6 下午6:01\n\"\"\"\n\n\n# 订单类型0:正常订单，1:流转订单\nTYPE_ORDER_NORMAL = '0'\nTYPE_ORDER_FLOWED = '1'\n\nTYPE_ORDER_DICT = {\n    0: u'正常订单',\n    1: u'流转订单',\n}\n\n"
  },
  {
    "path": "app_common/maps/type_pay.py",
    "content": "#!/usr/bin/env python\n# encoding: utf-8\n\n\"\"\"\n@author: zhanghe\n@software: PyCharm\n@file: type_pay.py\n@time: 2017/5/10 下午9:59\n\"\"\"\n\n\n# 支付/收款方式:0:不限，1:银行转账，2:数字货币，3:支付宝，4:微信\nTYPE_PAY = '0'\nTYPE_PAY_WALLET = '1'\nTYPE_PAY_BIT_COIN = '2'\nTYPE_PAY_ALI_PAY = '3'\nTYPE_PAY_WE_CHAT = '4'\n\nTYPE_PAY_DICT = {\n    0: u'不限',\n    1: u'钱包余额',\n    2: u'数字货币',\n    3: u'支付宝',\n    4: u'微信',\n}\n"
  },
  {
    "path": "app_common/maps/type_payment.py",
    "content": "#!/usr/bin/env python\n# encoding: utf-8\n\n\"\"\"\n@author: zhanghe\n@software: PyCharm\n@file: type_payment.py\n@time: 2017/5/13 下午2:15\n\"\"\"\n\n\n# 收支类型:（1：收、2：支）\nTYPE_PAYMENT = '0'\nTYPE_PAYMENT_INCOME = '1'\nTYPE_PAYMENT_EXPENSE = '2'\n\nTYPE_PAYMENT_DICT = {\n    0: u'不限',\n    1: u'收入',\n    2: u'支出'\n}\n"
  },
  {
    "path": "app_common/maps/type_scheduling.py",
    "content": "#!/usr/bin/env python\n# encoding: utf-8\n\n\"\"\"\n@author: zhanghe\n@software: PyCharm\n@file: type_scheduling.py\n@time: 2017/5/13 下午2:15\n\"\"\"\n\n\n# 排单类型（1：用户排单、2：系统发送）\nTYPE_SCHEDULING = '0'\nTYPE_SCHEDULING_USER = '1'\nTYPE_SCHEDULING_GIVE = '2'\n\nTYPE_SCHEDULING_DICT = {\n    0: u'不限',\n    1: u'用户排单',\n    2: u'系统发送'\n}\n"
  },
  {
    "path": "app_common/maps/type_score.py",
    "content": "#!/usr/bin/env python\n# encoding: utf-8\n\n\"\"\"\n@author: zhanghe\n@software: PyCharm\n@file: type_score.py\n@time: 2017/6/9 下午7:11\n\"\"\"\n\n\n# 积分类型:（1：获得、2：消费）\nTYPE_SCORE = '0'\nTYPE_SCORE_INCOME = '1'\nTYPE_SCORE_EXPENSE = '2'\n\nTYPE_SCORE_DICT = {\n    0: u'不限',\n    1: u'获得',\n    2: u'消费'\n}\n"
  },
  {
    "path": "app_common/maps/type_withdraw.py",
    "content": "#!/usr/bin/env python\n# encoding: utf-8\n\n\"\"\"\n@author: zhanghe\n@software: PyCharm\n@file: type_withdraw.py\n@time: 2017/5/10 下午9:59\n\"\"\"\n\n\n# 提现类型:0:钱包余额，1:数字货币\nTYPE_WITHDRAW_WALLET = '0'\nTYPE_WITHDRAW_BIT_COIN = '1'\n\nTYPE_WITHDRAW_DICT = {\n    0: u'钱包余额',\n    1: u'数字货币',\n}\n"
  },
  {
    "path": "app_common/tools/__init__.py",
    "content": "#!/usr/bin/env python\n# encoding: utf-8\n\n\"\"\"\n@author: zhanghe\n@software: PyCharm\n@file: __init__.py.py\n@time: 2017/4/24 下午9:04\n\"\"\"\n\n\nimport json\nimport hashlib\nimport datetime\nfrom decimal import Decimal\nfrom random import randint\n\n\ndef md5(source_str):\n    \"\"\"\n    md5加密\n    :param source_str:\n    :return:\n    \"\"\"\n    return hashlib.md5(source_str.encode(\"utf8\") if isinstance(source_str, unicode) else source_str).hexdigest()\n\n\ndef json_default(obj):\n    \"\"\"\n    支持datetime的json encode\n    TypeError: datetime.datetime(2015, 10, 21, 8, 42, 54) is not JSON serializable\n    :param obj:\n    :return:\n    \"\"\"\n    if isinstance(obj, datetime.datetime):\n        return obj.strftime('%Y-%m-%d %H:%M:%S')\n    elif isinstance(obj, datetime.date):\n        return obj.strftime('%Y-%m-%d')\n    elif isinstance(obj, Decimal):\n        return str(obj)\n    else:\n        raise TypeError('%r is not JSON serializable' % obj)\n\n\ndef get_randint(length=6):\n    \"\"\"\n    获取随机数字\n    :param length:\n    :return:\n    \"\"\"\n    return randint(10**(length-1), 10**length-1)\n\n\nif __name__ == '__main__':\n    print md5('123456')  # e10adc3949ba59abbe56e057f20f883e\n    print get_randint(), 10**5, 10**6-1  # 210551 100000 999999\n"
  },
  {
    "path": "app_common/tools/date_time.py",
    "content": "#!/usr/bin/env python\n# encoding: utf-8\n\n\"\"\"\n@author: zhanghe\n@software: PyCharm\n@file: date.py\n@time: 2017/6/10 下午6:00\n\"\"\"\n\n\nimport time\nimport calendar\nfrom datetime import datetime, timedelta, date\n\n\ndef get_current_day_time_ends():\n    \"\"\"\n    获取当天开始结束时刻\n    :return:\n    \"\"\"\n    today = datetime.today()\n    start_time = datetime(today.year, today.month, today.day, 0, 0, 0)\n    end_time = datetime(today.year, today.month, today.day, 23, 59, 59)\n    return start_time, end_time\n\n\ndef get_current_month_time_ends():\n    \"\"\"\n    获取当月开始结束时刻\n    :return:\n    \"\"\"\n    today = datetime.today()\n    _, days = calendar.monthrange(today.year, today.month)\n    start_time = datetime(today.year, today.month, 1, 0, 0, 0)\n    end_time = datetime(today.year, today.month, days, 23, 59, 59)\n    return start_time, end_time\n\n\ndef get_current_year_time_ends():\n    \"\"\"\n    获取当年开始结束时刻\n    :return:\n    \"\"\"\n    today = datetime.today()\n    start_time = datetime(today.year, 1, 1, 0, 0, 0)\n    end_time = datetime(today.year, 12, 31, 23, 59, 59)\n    return start_time, end_time\n\n\ndef get_hours(zerofill=True):\n    \"\"\"\n    列出1天所有24小时\n    :return:\n    \"\"\"\n    if zerofill:\n        return ['%02d' % i for i in range(24)]\n    else:\n        return range(24)\n\n\ndef get_days(year=1970, month=1, zerofill=True):\n    \"\"\"\n    列出当月的所有日期\n    :param year:\n    :param month:\n    :param zerofill:\n    :return:\n    \"\"\"\n    year = int(year)\n    month = int(month)\n    _, days = calendar.monthrange(year, month)\n    if zerofill:\n        return ['%02d' % i for i in range(1, days+1)]\n    else:\n        return range(1, days+1)\n\n\ndef get_weeks():\n    \"\"\"\n    列出所有星期\n    :return:\n    \"\"\"\n    return [u'周一', u'周二', u'周三', u'周四', u'周五', u'周六', u'周日']\n\n\ndef get_months(zerofill=True):\n    \"\"\"\n    列出1年所有12月份\n    :return:\n    \"\"\"\n    if zerofill:\n        return ['%02d' % i for i in range(1, 13)]\n    else:\n        return [i for i in range(1, 13)]\n\n\ndef time_local_to_utc(local_time):\n    \"\"\"\n    本地时间转UTC时间\n    :param local_time:\n    :return:\n    \"\"\"\n    # 字符串处理\n    if isinstance(local_time, str) and len(local_time) == 10:\n        local_time = datetime.strptime(local_time, '%Y-%m-%d')\n    elif isinstance(local_time, str) and len(local_time) >= 19:\n        local_time = datetime.strptime(local_time[:19], '%Y-%m-%d %H:%M:%S')\n    elif not (isinstance(local_time, datetime) or isinstance(local_time, date)):\n        local_time = datetime.now()\n    # 时间转换\n    utc_time = local_time + timedelta(seconds=time.timezone)\n    return utc_time\n\n\ndef time_utc_to_local(utc_time):\n    \"\"\"\n    UTC时间转本地时间\n    :param utc_time:\n    :return:\n    \"\"\"\n    # 字符串处理\n    if isinstance(utc_time, str) and len(utc_time) == 10:\n        utc_time = datetime.strptime(utc_time, '%Y-%m-%d')\n    elif isinstance(utc_time, str) and len(utc_time) >= 19:\n        utc_time = datetime.strptime(utc_time[:19], '%Y-%m-%d %H:%M:%S')\n    elif not (isinstance(utc_time, datetime) or isinstance(utc_time, date)):\n        utc_time = datetime.utcnow()\n    # 时间转换\n    local_time = utc_time - timedelta(seconds=time.timezone)\n    return local_time\n\n\nif __name__ == '__main__':\n    print get_current_day_time_ends()\n    print get_current_month_time_ends()\n    print get_current_year_time_ends()\n\n    print get_hours()\n    print get_days(2017, 2)\n    print get_days(2017, 2, True)\n    print get_weeks()\n    print get_months()\n\n    print time.timezone\n    # 时间对象本地时间与UTC时间互转\n    print datetime.now(), time_local_to_utc(datetime.now())\n    print datetime.utcnow(), time_utc_to_local(datetime.utcnow())\n    # 字符串本地时间转UTC时间\n    print '2017-01-01', time_local_to_utc(datetime.strptime('2017-01-01', '%Y-%m-%d'))\n    print '2017-01-01 00:00:00', time_local_to_utc(datetime.strptime('2017-01-01 00:00:00', '%Y-%m-%d %H:%M:%S'))\n    # 字符串UTC时间转本地时间\n    print '2017-01-01', time_utc_to_local(datetime.strptime('2017-01-01', '%Y-%m-%d'))\n    print '2017-01-01 00:00:00', time_utc_to_local(datetime.strptime('2017-01-01 00:00:00', '%Y-%m-%d %H:%M:%S'))\n\n    # 日期对象本地时间与UTC时间互转\n    local_date = date(*time.localtime()[:3])\n    print local_date, type(local_date), time_local_to_utc(local_date)\n    utc_date = date(*time.strptime('2009-09-07', '%Y-%m-%d')[:3])\n    print utc_date, type(utc_date), time_utc_to_local(utc_date)\n"
  },
  {
    "path": "app_common/tools/file.py",
    "content": "#!/usr/bin/env python\n# encoding: utf-8\n\n\"\"\"\n@author: zhanghe\n@software: PyCharm\n@file: file.py\n@time: 2017/5/11 下午9:36\n\"\"\"\n\n\nfrom datetime import datetime\nfrom config import ALLOWED_EXTENSIONS\nfrom config import MIN_CONTENT_LENGTH\nfrom config import MAX_CONTENT_LENGTH\n\n\ndef allowed_file(filename):\n    \"\"\"\n    校验文件类型\n    \"\"\"\n    return '.' in filename and filename.rsplit('.', 1)[1] in ALLOWED_EXTENSIONS\n\n\ndef get_extend_type(filename):\n    \"\"\"\n    获取文件扩展\n    :param filename:\n    :return:\n    \"\"\"\n    if allowed_file(filename):\n        return filename.rsplit('.', 1)[1]\n    else:\n        return ''\n\n\ndef get_file_size(file_obj):\n    \"\"\"\n    获取文件大小\n    :param file_obj:\n    :return:\n    \"\"\"\n    file_obj.seek(0, 2)  # Seek to the end of the file\n    size = file_obj.tell()  # Get the position of EOF\n    file_obj.seek(0)  # Reset the file position to the beginning\n    return size\n\n\ndef create_file_name(file_obj):\n    \"\"\"\n    创建文件名称\n    :param file_obj:\n    :return:\n    \"\"\"\n    # from werkzeug.utils import secure_filename\n    # file_name = secure_filename(file_obj.filename)\n    extend_type = get_extend_type(file_obj.filename)\n    file_name = datetime.utcnow().strftime('%Y%m%d%H%M%S%f')\n    return '%s.%s' % (file_name, extend_type) if extend_type else file_obj.filename\n\n\ndef validate(file_obj):\n    \"\"\"\n    文件尺寸校验\n    :param file_obj:\n    :return:\n    \"\"\"\n    if not allowed_file(file_obj.filename):\n        raise Exception(u'文件类型暂不支持')\n    file_size = get_file_size(file_obj)\n    if file_size < MIN_CONTENT_LENGTH:\n        raise Exception(u'文件太小，未到最低要求')\n    elif file_size > MAX_CONTENT_LENGTH:\n        raise Exception(u'文件太大，超过最大限制')\n    else:\n        return True\n"
  },
  {
    "path": "app_common/tools/ip.py",
    "content": "#!/usr/bin/env python\n# encoding: utf-8\n\n\"\"\"\n@author: zhanghe\n@software: PyCharm\n@file: ip.py\n@time: 2017/5/15 下午4:17\n\"\"\"\n\n\nfrom flask import request\n\n\ndef get_real_ip():\n    \"\"\"\n    获取用户真实IP\n    :return:\n    \"\"\"\n    address = request.headers.get('X-Forwarded-For', request.remote_addr)\n    if address is not None:\n        # An 'X-Forwarded-For' header includes a comma separated list of the\n        # addresses, the first address being the actual remote address.\n        address = address.encode('utf-8').split(b',')[0].strip()\n    return address\n"
  },
  {
    "path": "app_common/tools/tree.py",
    "content": "#!/usr/bin/env python\n# encoding: utf-8\n\n\"\"\"\n@author: zhanghe\n@software: PyCharm\n@file: tree.py\n@time: 2017/5/31 下午9:25\n\"\"\"\n\n\nfrom collections import defaultdict\n\n\ndef tree():\n    \"\"\"\n    定义一棵树\n    python 字典的特性，赋值操作必须事先声明，所以这里使用 collections 很方便的为字典设置初始值\n    :return:\n    \"\"\"\n    return defaultdict(tree)\n\n\nif __name__ == '__main__':\n    tr = tree()\n    print tr\n    tr['fdsf']['erer'] = 2\n    print tr\n\n"
  },
  {
    "path": "app_frontend/README.md",
    "content": "## 用户前台\n"
  },
  {
    "path": "app_frontend/__init__.py",
    "content": "#!/usr/bin/env python\n# encoding: utf-8\n\n\"\"\"\n@author: zhanghe\n@software: PyCharm\n@file: __init__.py\n@time: 16-1-7 上午12:08\n\"\"\"\n\nfrom logging.config import dictConfig\nfrom config import current_config\n\nfrom flask import Flask\nfrom flask_login import LoginManager\nfrom flask_moment import Moment\nfrom flask_oauthlib.client import OAuth\n\nfrom app_frontend.lib.qiniu_store import QiNiuClient\nfrom app_frontend.lib.redis_session import RedisSessionInterface\nfrom app_frontend.lib.sendcloud import SendCloudClient\nfrom app_frontend.lib.sms_chuanglan_iso import SmsChuangLanIsoApi\nfrom app_frontend.middlewares import HTTPMethodOverrideMiddleware\n\n\napp = Flask(__name__)\napp.config.from_object(current_config)\napp.config['REMEMBER_COOKIE_NAME'] = 'r_u'\napp.session_cookie_name = 's_u'\napp.session_interface = RedisSessionInterface(prefix='s:u:', **app.config['REDIS'])\n\napp.wsgi_app = HTTPMethodOverrideMiddleware(app.wsgi_app)\n\nlogin_manager = LoginManager()\nlogin_manager.init_app(app)  # setup_app 方法已淘汰\nlogin_manager.login_view = 'auth.index'\nlogin_manager.login_message = u'请登录后操作'  # 设置登录提示消息\nlogin_manager.login_message_category = 'info'  # 设置消息分类\n\n# Moment 时间插件\nmoment = Moment(app)\n\n# 短信通道\nsms_client = SmsChuangLanIsoApi(app.config['SMS']['UN'], app.config['SMS']['PW'])\n\n# SendCloud 邮件\nsend_cloud_client = SendCloudClient(app)\n\n# 七牛云存储\nqi_niu_client = QiNiuClient(app)\n\n# 第三方开放授权登录\noauth = OAuth(app)\n\n# GitHub\noauth_github = oauth.remote_app(\n    'github',\n    **app.config['GITHUB_OAUTH']\n)\n\n# QQ\noauth_qq = oauth.remote_app(\n    'qq',\n    **app.config['QQ_OAUTH']\n)\n\n# WeiBo\noauth_weibo = oauth.remote_app(\n    'weibo',\n    **app.config['WEIBO_OAUTH']\n)\n\n# Google\n# 要银子，妹的\n\n\n# 配置日志\ndictConfig(app.config['LOG_CONFIG'])\n\nif not app.config['DEBUG']:\n    import logging\n    from logging.handlers import SMTPHandler\n    credentials = None\n    if app.config['MAIL_USERNAME'] or app.config['MAIL_PASSWORD']:\n        credentials = (app.config['MAIL_USERNAME'], app.config['MAIL_PASSWORD'])\n    mail_handler = SMTPHandler(\n        (app.config['MAIL_SERVER'], app.config['MAIL_PORT']),\n        app.config['MAIL_DEFAULT_SENDER'][1],\n        app.config['ADMINS'],\n        'App Error Message',\n        credentials\n    )\n    mail_handler.setLevel(logging.DEBUG)\n    app.logger.addHandler(mail_handler)\n\n\n# 这个 import 语句放在这里, 防止views, models import发生循环import\nfrom app_frontend import models, tasks\n\n# 导入视图（不使用蓝图的单模式方式）\nfrom app_frontend import views\n\n# 导入视图（不使用蓝图的多模块方式）\n# from application.views import auth\n# from application.views import blog\n# from application.views import reg\n# from application.views import site\n# from application.views import user\n\n# 导入蓝图（使用蓝图的多模块方式）\nfrom app_frontend.views.captcha import bp_captcha\nfrom app_frontend.views.auth import bp_auth\nfrom app_frontend.views.blog import bp_blog\nfrom app_frontend.views.file import bp_file\nfrom app_frontend.views.reg import bp_reg\nfrom app_frontend.views.user import bp_user\nfrom app_frontend.views.credit import bp_credit\nfrom app_frontend.views.apply import bp_apply\nfrom app_frontend.views.order import bp_order\nfrom app_frontend.views.score import bp_score\nfrom app_frontend.views.wallet import bp_wallet\nfrom app_frontend.views.complaint import bp_complaint\nfrom app_frontend.views.message import bp_message\nfrom app_frontend.views.penetration import bp_penetration\nfrom app_frontend.views.active import bp_active\nfrom app_frontend.views.bit_coin import bp_bit_coin\nfrom app_frontend.views.scheduling import bp_scheduling\n\n# 注册蓝图\napp.register_blueprint(bp_captcha)\napp.register_blueprint(bp_auth)\napp.register_blueprint(bp_blog)\napp.register_blueprint(bp_file)\napp.register_blueprint(bp_reg)\napp.register_blueprint(bp_user)\napp.register_blueprint(bp_credit)\napp.register_blueprint(bp_apply)\napp.register_blueprint(bp_order)\napp.register_blueprint(bp_score)\napp.register_blueprint(bp_wallet)\napp.register_blueprint(bp_complaint)\napp.register_blueprint(bp_message)\napp.register_blueprint(bp_penetration)\napp.register_blueprint(bp_active)\napp.register_blueprint(bp_bit_coin)\napp.register_blueprint(bp_scheduling)\n\n# 导入自定义过滤器\nfrom app_frontend import filters\n"
  },
  {
    "path": "app_frontend/api/__init__.py",
    "content": "#!/usr/bin/env python\n# encoding: utf-8\n\n\"\"\"\n@author: zhanghe\n@software: PyCharm\n@file: __init__.py.py\n@time: 2017/3/10 下午11:32\n\"\"\"\n\n\ndef func():\n    pass\n\n\nclass Main(object):\n    def __init__(self):\n        pass\n\n\nif __name__ == '__main__':\n    pass\n"
  },
  {
    "path": "app_frontend/api/active.py",
    "content": "#!/usr/bin/env python\n# encoding: utf-8\n\n\"\"\"\n@author: zhanghe\n@software: PyCharm\n@file: active.py\n@time: 2017/5/14 上午1:42\n\"\"\"\n\n\nfrom datetime import datetime\nfrom app_frontend.database import db\nfrom app_frontend.api.user import get_user_row_by_id\nfrom app_frontend.api.user_profile import get_user_profile_row_by_id\nfrom app_frontend.models import Active, ActiveItem, User\nfrom app_frontend.tools.db import get_row, get_rows, get_row_by_id, add, edit, delete\nfrom app_common.maps.status_audit import *\nfrom app_common.maps.type_active import *\nfrom app_common.maps.status_active import *\n\n\ndef get_active_row_by_id(active_id):\n    \"\"\"\n    通过 id 获取激活信息\n    :param active_id:\n    :return: None/object\n    \"\"\"\n    return get_row_by_id(Active, active_id)\n\n\ndef get_active_row(*args, **kwargs):\n    \"\"\"\n    获取激活信息\n    :param args:\n    :param kwargs:\n    :return: None/object\n    \"\"\"\n    return get_row(Active, *args, **kwargs)\n\n\ndef add_active(active_data):\n    \"\"\"\n    添加激活信息\n    :param active_data:\n    :return: None/Value of active.id\n    \"\"\"\n    return add(Active, active_data)\n\n\ndef edit_active(active_id, active_data):\n    \"\"\"\n    修改激活信息\n    :param active_id:\n    :param active_data:\n    :return: Number of affected rows (Example: 0/1)\n    \"\"\"\n    return edit(Active, active_id, active_data)\n\n\ndef delete_active(active_id):\n    \"\"\"\n    删除激活信息\n    :param active_id:\n    :return: Number of affected rows (Example: 0/1)\n    \"\"\"\n    return delete(Active, active_id)\n\n\ndef get_active_rows(page=1, per_page=10, *args, **kwargs):\n    \"\"\"\n    获取激活列表（分页）\n    Usage:\n        items: 信息列表\n        has_next: 如果本页之后还有超过一个分页，则返回True\n        has_prev: 如果本页之前还有超过一个分页，则返回True\n        next_num: 返回下一页的页码\n        prev_num: 返回上一页的页码\n        iter_pages(): 页码列表\n        iter_pages(left_edge=2, left_current=2, right_current=5, right_edge=2) 页码列表默认参数\n    :param page:\n    :param per_page:\n    :param args:\n    :param kwargs:\n    :return:\n    \"\"\"\n    rows = get_rows(Active, page, per_page, *args, **kwargs)\n    return rows\n\n\ndef user_active(user_id, user_id_active, amount=1):\n    \"\"\"\n    用户激活\n    :param user_id:\n    :param user_id_active:\n    :param amount:\n    :return:\n    \"\"\"\n    try:\n        active_obj = db.session.query(Active).filter(Active.user_id == user_id)\n        active_info = active_obj.first()\n\n        # 检查剩余激活次数\n        if not active_info or active_info.amount < amount:\n            raise Exception(u'剩余激活次数不够')\n\n        current_time = datetime.utcnow()\n\n        # 扣除激活码剩余数量\n        active_data = {\n            'user_id': user_id,\n            'amount': active_info.amount - amount,\n            'update_time': current_time,\n        }\n        active_obj.update(active_data)\n\n        # 添加激活码消费明细\n        active_item_data = {\n            'user_id': user_id,\n            'type': TYPE_ACTIVE_USER,\n            'amount': amount,\n            'sc_id': user_id_active,\n            'status_audit': STATUS_AUDIT_SUCCESS,\n            'audit_time': current_time,\n            'create_time': current_time,\n            'update_time': current_time,\n        }\n        db.session.add(ActiveItem(**active_item_data))\n\n        # 更新激活\n        user_data = {\n            'status_active': STATUS_ACTIVE_OK,\n            'active_time': current_time,\n            'update_time': current_time,\n        }\n        active_obj = db.session.query(User).filter(User.id == user_id_active)\n        active_obj.update(user_data)\n\n        db.session.commit()\n        return True\n    except Exception as e:\n        db.session.rollback()\n        raise e\n\n\ndef give_active(user_id, user_id_active, amount=1):\n    \"\"\"\n    赠送激活数量\n    :param user_id:\n    :param user_id_active:\n    :param amount:\n    :return:\n    \"\"\"\n    try:\n        active_obj = db.session.query(Active).filter(Active.user_id == user_id)\n        active_info = active_obj.first()\n\n        # 检查剩余激活次数\n        if not active_info or active_info.amount < amount:\n            raise Exception(u'剩余激活次数不够')\n\n        current_time = datetime.utcnow()\n\n        # 扣除激活码剩余数量\n        active_data = {\n            'user_id': user_id,\n            'amount': active_info.amount - amount,\n            'update_time': current_time,\n        }\n        active_obj.update(active_data)\n\n        # 添加激活码消费明细\n        active_item_data = {\n            'user_id': user_id,\n            'type': TYPE_ACTIVE_GIVE,\n            'amount': amount,\n            'sc_id': user_id_active,\n            'status_audit': STATUS_AUDIT_SUCCESS,\n            'audit_time': current_time,\n            'create_time': current_time,\n            'update_time': current_time,\n        }\n        db.session.add(ActiveItem(**active_item_data))\n\n        # 新增接收用户激活码总数量\n        active_obj = db.session.query(Active).filter(Active.user_id == user_id_active)\n        active_info = active_obj.first()\n        if active_info:\n            active_data = {\n                'user_id': user_id_active,\n                'amount': active_info.amount + amount,\n                'update_time': current_time,\n            }\n            active_obj.update(active_data)\n        else:\n            active_data = {\n                'user_id': user_id_active,\n                'amount': amount,\n                'create_time': current_time,\n                'update_time': current_time,\n            }\n            db.session.add(Active(**active_data))\n\n        db.session.commit()\n        return True\n    except Exception as e:\n        db.session.rollback()\n        raise e\n"
  },
  {
    "path": "app_frontend/api/active_item.py",
    "content": "#!/usr/bin/env python\n# encoding: utf-8\n\n\"\"\"\n@author: zhanghe\n@software: PyCharm\n@file: active_item.py\n@time: 2017/5/20 下午6:29\n\"\"\"\n\n\nfrom app_frontend.models import ActiveItem\nfrom app_frontend.tools.db import get_row, get_rows, get_row_by_id, add, edit, delete\n\n\ndef get_active_item_row_by_id(active_item_id):\n    \"\"\"\n    通过 id 获取激活信息\n    :param active_item_id:\n    :return: None/object\n    \"\"\"\n    return get_row_by_id(ActiveItem, active_item_id)\n\n\ndef get_active_item_row(*args, **kwargs):\n    \"\"\"\n    获取激活信息\n    :param args:\n    :param kwargs:\n    :return: None/object\n    \"\"\"\n    return get_row(ActiveItem, *args, **kwargs)\n\n\ndef add_active_item(active_item_data):\n    \"\"\"\n    添加激活信息\n    :param active_item_data:\n    :return: None/Value of active.id\n    \"\"\"\n    return add(ActiveItem, active_item_data)\n\n\ndef edit_active_item(active_item_id, active_item_data):\n    \"\"\"\n    修改激活信息\n    :param active_item_id:\n    :param active_item_data:\n    :return: Number of affected rows (Example: 0/1)\n    \"\"\"\n    return edit(ActiveItem, active_item_id, active_item_data)\n\n\ndef delete_active_item(active_item_id):\n    \"\"\"\n    删除激活信息\n    :param active_item_id:\n    :return: Number of affected rows (Example: 0/1)\n    \"\"\"\n    return delete(ActiveItem, active_item_id)\n\n\ndef get_active_item_rows(page=1, per_page=10, *args, **kwargs):\n    \"\"\"\n    获取激活列表（分页）\n    Usage:\n        items: 信息列表\n        has_next: 如果本页之后还有超过一个分页，则返回True\n        has_prev: 如果本页之前还有超过一个分页，则返回True\n        next_num: 返回下一页的页码\n        prev_num: 返回上一页的页码\n        iter_pages(): 页码列表\n        iter_pages(left_edge=2, left_current=2, right_current=5, right_edge=2) 页码列表默认参数\n    :param page:\n    :param per_page:\n    :param args:\n    :param kwargs:\n    :return:\n    \"\"\"\n    rows = get_rows(ActiveItem, page, per_page, *args, **kwargs)\n    return rows\n"
  },
  {
    "path": "app_frontend/api/apply_get.py",
    "content": "#!/usr/bin/env python\n# encoding: utf-8\n\n\"\"\"\n@author: zhanghe\n@software: PyCharm\n@file: apply_get.py\n@time: 2017/4/13 上午11:27\n\"\"\"\n\n\nfrom datetime import datetime\nimport traceback\n\nfrom sqlalchemy import func\n\nfrom app_common.maps.status_audit import STATUS_AUDIT_SUCCESS\nfrom app_common.maps.status_delete import STATUS_DEL_NO\nfrom app_common.maps.status_order import STATUS_ORDER_COMPLETED\nfrom app_common.tools.date_time import get_current_day_time_ends, get_current_month_time_ends\nfrom app_frontend.database import db\nfrom app_common.maps.type_withdraw import *\nfrom app_common.maps.type_pay import *\nfrom app_common.maps.type_payment import *\nfrom app_common.maps.status_apply import *\nfrom app_common.maps.type_apply import *\nfrom app_frontend.models import ApplyGet, Wallet, WalletItem, BitCoin, BitCoinItem\nfrom app_frontend.tools.db import get_row, get_rows, get_row_by_id, add, edit, delete, count\n\n\ndef get_apply_get_row_by_id(apply_get_id):\n    \"\"\"\n    通过 id 获取提现申请信息\n    :param apply_get_id:\n    :return: None/object\n    \"\"\"\n    return get_row_by_id(ApplyGet, apply_get_id)\n\n\ndef get_apply_get_row(*args, **kwargs):\n    \"\"\"\n    获取提现申请信息\n    :param args:\n    :param kwargs:\n    :return: None/object\n    \"\"\"\n    return get_row(ApplyGet, *args, **kwargs)\n\n\ndef add_apply_get(apply_get_data):\n    \"\"\"\n    添加提现申请信息\n    :param apply_get_data:\n    :return: None/Value of apply_get.id\n    \"\"\"\n    return add(ApplyGet, apply_get_data)\n\n\ndef edit_apply_get(apply_get_id, apply_get_data):\n    \"\"\"\n    修改提现申请信息\n    :param apply_get_id:\n    :param apply_get_data:\n    :return: Number of affected rows (Example: 0/1)\n    \"\"\"\n    return edit(ApplyGet, apply_get_id, apply_get_data)\n\n\ndef delete_apply_get(apply_get_id):\n    \"\"\"\n    删除提现申请信息\n    :param apply_get_id:\n    :return: Number of affected rows (Example: 0/1)\n    \"\"\"\n    return delete(ApplyGet, apply_get_id)\n\n\ndef get_apply_get_rows(page=1, per_page=10, *args, **kwargs):\n    \"\"\"\n    获取提现申请列表（分页）\n    Usage:\n        items: 信息列表\n        has_next: 如果本页之后还有超过一个分页，则返回True\n        has_prev: 如果本页之前还有超过一个分页，则返回True\n        next_num: 返回下一页的页码\n        prev_num: 返回上一页的页码\n        iter_pages(): 页码列表\n        iter_pages(left_edge=2, left_current=2, right_current=5, right_edge=2) 页码列表默认参数\n    :param page:\n    :param per_page:\n    :param args:\n    :param kwargs:\n    :return:\n    \"\"\"\n    rows = get_rows(ApplyGet, page, per_page, *args, **kwargs)\n    return rows\n\n\ndef user_apply_get(user_id, type_pay, type_withdraw, money_apply):\n    \"\"\"\n    用户提现申请 - 事务\n    :param user_id:\n    :param type_pay:\n    :param type_withdraw:\n    :param money_apply:\n    :return:\n    \"\"\"\n    try:\n        current_time = datetime.utcnow()\n        # 新增用户提现申请记录\n        apply_get_data = {\n            'user_id': user_id,\n            'type_apply': TYPE_APPLY_USER,\n            'type_pay': type_pay,\n            'type_withdraw': type_withdraw,\n            'money_apply': money_apply,\n            'status_apply': STATUS_APPLY_SUCCESS,\n            'create_time': current_time,\n            'update_time': current_time,\n        }\n\n        apply_get_obj = ApplyGet(**apply_get_data)\n        db.session.add(apply_get_obj)\n        db.session.flush()\n        apply_get_id = apply_get_obj.id\n\n        # 新增钱包、数字货币支出明细\n        if type_withdraw == TYPE_WITHDRAW_WALLET:\n            # 新增钱包明细\n            wallet_item_info = {\n                'user_id': user_id,\n                'type': TYPE_PAYMENT_EXPENSE,\n                'amount': money_apply,\n                'sc_id': apply_get_id,\n                # 'note': u'',\n                'status_audit': STATUS_AUDIT_SUCCESS,\n                'create_time': current_time,\n                'update_time': current_time,\n            }\n            db.session.add(WalletItem(**wallet_item_info))\n\n            # 获取钱包总额\n            wallet_info = db.session.query(Wallet).filter(Wallet.user_id == user_id).first()\n            amount_current = wallet_info.amount_current if wallet_info else 0\n            # 更新(新增)钱包总额\n            wallet_data = {\n                'user_id': user_id,\n                'amount_current': amount_current - money_apply,\n                'create_time': current_time,\n                'update_time': current_time,\n            }\n            db.session.merge(Wallet(**wallet_data))\n        # 更新钱包、数字货币余额\n        if type_withdraw == TYPE_WITHDRAW_BIT_COIN:\n            # 新增数字货币明细\n            bit_coin_item_info = {\n                'user_id': user_id,\n                'type': TYPE_PAYMENT_EXPENSE,\n                'amount': money_apply,\n                'sc_id': apply_get_id,\n                # 'note': u'',\n                'status_audit': STATUS_AUDIT_SUCCESS,\n                'create_time': current_time,\n                'update_time': current_time,\n            }\n            db.session.add(BitCoinItem(**bit_coin_item_info))\n\n            # 获取数字货币总额\n            bit_coin_info = db.session.query(BitCoin).filter(BitCoin.user_id == user_id).first()\n            amount = bit_coin_info.amount if bit_coin_info else 0\n            # 更新(新增)数字货币总额\n            bit_coin_data = {\n                'user_id': user_id,\n                'amount': amount - money_apply,\n                'create_time': current_time,\n                'update_time': current_time,\n            }\n            db.session.merge(BitCoin(**bit_coin_data))\n        # 提交事务\n        db.session.commit()\n        return True\n    except Exception as e:\n        print traceback.print_exc()\n        db.session.rollback()  # 回滚事务\n        raise e\n\n\ndef get_current_day_get_amount(user_id=None):\n    \"\"\"\n    获取当天提现总额\n    :return:\n    \"\"\"\n    start_time, end_time = get_current_day_time_ends()\n    condition = [\n        ApplyGet.create_time >= start_time,\n        ApplyGet.create_time <= end_time\n    ]\n    if user_id:\n        condition.append(ApplyGet.user_id == user_id)\n    res = db.session \\\n        .query(func.sum(ApplyGet.money_apply).label('amount')) \\\n        .filter(*condition) \\\n        .first()\n    return res.amount or 0\n\n\ndef get_current_month_get_amount(user_id=None):\n    \"\"\"\n    获取当月提现总额\n    :return:\n    \"\"\"\n    start_time, end_time = get_current_month_time_ends()\n    condition = [\n        ApplyGet.create_time >= start_time,\n        ApplyGet.create_time <= end_time\n    ]\n    if user_id:\n        condition.append(ApplyGet.user_id == user_id)\n    res = db.session \\\n        .query(func.sum(ApplyGet.money_apply).label('amount')) \\\n        .filter(*condition) \\\n        .first()\n    return res.amount or 0\n\n\ndef get_get_processing_amount(user_id):\n    \"\"\"\n    获取用户提现申请未匹配总金额\n    :param user_id:\n    :return:\n    \"\"\"\n    condition = [\n        ApplyGet.user_id == user_id,\n        ApplyGet.status_order <= int(STATUS_ORDER_COMPLETED),\n        ApplyGet.status_delete == int(STATUS_DEL_NO)\n    ]\n    res = db.session \\\n        .query(func.sum(ApplyGet.money_apply).label('money_apply_amount'),\n               func.sum(ApplyGet.money_order).label('money_order_amount')) \\\n        .filter(*condition) \\\n        .first()\n    return (res.money_apply_amount or 0) - (res.money_order_amount or 0)\n\n\ndef get_get_processing_count(user_id):\n    \"\"\"\n    获取用户提现申请未匹配总单数\n    :param user_id:\n    :return:\n    \"\"\"\n    condition = [\n        ApplyGet.user_id == user_id,\n        ApplyGet.status_order <= int(STATUS_ORDER_COMPLETED),\n        ApplyGet.status_delete == int(STATUS_DEL_NO)\n    ]\n    num = count(ApplyGet, *condition)\n    return num\n"
  },
  {
    "path": "app_frontend/api/apply_put.py",
    "content": "#!/usr/bin/env python\n# encoding: utf-8\n\n\"\"\"\n@author: zhanghe\n@software: PyCharm\n@file: apply_put.py\n@time: 2017/4/13 下午9:45\n\"\"\"\n\n\nfrom app_common.tools.date_time import get_current_day_time_ends, get_current_month_time_ends\nfrom app_frontend.models import ApplyPut\nfrom app_frontend.tools.db import get_row, get_rows, get_row_by_id, add, edit, delete, count\nfrom app_common.maps.status_delete import *\nfrom app_frontend.database import db\nfrom sqlalchemy.sql import func\nfrom app_common.maps.status_order import *\nfrom app_common.maps.status_delete import *\n\n\ndef get_apply_put_row_by_id(apply_put_id):\n    \"\"\"\n    通过 id 获取投资申请信息\n    :param apply_put_id:\n    :return: None/object\n    \"\"\"\n    return get_row_by_id(ApplyPut, apply_put_id)\n\n\ndef get_apply_put_row(*args, **kwargs):\n    \"\"\"\n    获取投资申请信息\n    :param args:\n    :param kwargs:\n    :return: None/object\n    \"\"\"\n    return get_row(ApplyPut, *args, **kwargs)\n\n\ndef add_apply_put(apply_put_data):\n    \"\"\"\n    添加投资申请信息\n    :param apply_put_data:\n    :return: None/Value of apply_put.id\n    \"\"\"\n    return add(ApplyPut, apply_put_data)\n\n\ndef edit_apply_put(apply_put_id, apply_put_data):\n    \"\"\"\n    修改投资申请信息\n    :param apply_put_id:\n    :param apply_put_data:\n    :return: Number of affected rows (Example: 0/1)\n    \"\"\"\n    return edit(ApplyPut, apply_put_id, apply_put_data)\n\n\ndef delete_apply_put(apply_put_id):\n    \"\"\"\n    删除投资申请信息\n    :param apply_put_id:\n    :return: Number of affected rows (Example: 0/1)\n    \"\"\"\n    return delete(ApplyPut, apply_put_id)\n\n\ndef get_apply_put_rows(page=1, per_page=10, *args, **kwargs):\n    \"\"\"\n    获取投资申请列表（分页）\n    Usage:\n        items: 信息列表\n        has_next: 如果本页之后还有超过一个分页，则返回True\n        has_prev: 如果本页之前还有超过一个分页，则返回True\n        next_num: 返回下一页的页码\n        prev_num: 返回上一页的页码\n        iter_pages(): 页码列表\n        iter_pages(left_edge=2, left_current=2, right_current=5, right_edge=2) 页码列表默认参数\n    :param page:\n    :param per_page:\n    :param args:\n    :param kwargs:\n    :return:\n    \"\"\"\n    rows = get_rows(ApplyPut, page, per_page, *args, **kwargs)\n    return rows\n\n\ndef is_put(user_id):\n    \"\"\"\n    是否投资\n    :param user_id:\n    :return:\n    \"\"\"\n    condition = {\n        'user_id': user_id,\n        'status_delete': STATUS_DEL_NO\n    }\n    return bool(count(ApplyPut, **condition))\n\n\ndef get_current_day_put_amount(user_id=None):\n    \"\"\"\n    获取当天投资总额\n    :return:\n    \"\"\"\n    start_time, end_time = get_current_day_time_ends()\n    condition = [\n        ApplyPut.create_time >= start_time,\n        ApplyPut.create_time <= end_time\n    ]\n    if user_id:\n        condition.append(ApplyPut.user_id == user_id)\n    res = db.session \\\n        .query(func.sum(ApplyPut.money_apply).label('amount')) \\\n        .filter(*condition) \\\n        .first()\n    return res.amount or 0\n\n\ndef get_current_month_put_amount(user_id=None):\n    \"\"\"\n    获取当月投资总额\n    :return:\n    \"\"\"\n    start_time, end_time = get_current_month_time_ends()\n    condition = [\n        ApplyPut.create_time >= start_time,\n        ApplyPut.create_time <= end_time\n    ]\n    if user_id:\n        condition.append(ApplyPut.user_id == user_id)\n    res = db.session \\\n        .query(func.sum(ApplyPut.money_apply).label('amount')) \\\n        .filter(*condition) \\\n        .first()\n    return res.amount or 0\n\n\ndef get_put_processing_amount(user_id):\n    \"\"\"\n    获取用户投资申请未匹配总金额\n    :param user_id:\n    :return:\n    \"\"\"\n    condition = [\n        ApplyPut.user_id == user_id,\n        ApplyPut.status_order <= int(STATUS_ORDER_COMPLETED),\n        ApplyPut.status_delete == int(STATUS_DEL_NO)\n    ]\n    res = db.session \\\n        .query(func.sum(ApplyPut.money_apply).label('money_apply_amount'),\n               func.sum(ApplyPut.money_order).label('money_order_amount')) \\\n        .filter(*condition) \\\n        .first()\n    return (res.money_apply_amount or 0) - (res.money_order_amount or 0)\n\n\ndef get_put_processing_count(user_id):\n    \"\"\"\n    获取用户投资申请未匹配总单数\n    :param user_id:\n    :return:\n    \"\"\"\n    condition = [\n        ApplyPut.user_id == user_id,\n        ApplyPut.status_order <= int(STATUS_ORDER_COMPLETED),\n        ApplyPut.status_delete == int(STATUS_DEL_NO)\n    ]\n    num = count(ApplyPut, *condition)\n    return num\n"
  },
  {
    "path": "app_frontend/api/author.py",
    "content": "#!/usr/bin/env python\n# encoding: utf-8\n\n\"\"\"\n@author: zhanghe\n@software: PyCharm\n@file: author.py\n@time: 16-1-17 上午12:05\n\"\"\"\n\n\nfrom app_frontend.models import Author\nfrom app_frontend.tools.db import get_row, get_rows, get_row_by_id, add, edit, delete\n\n\ndef get_author_row_by_id(author_id):\n    \"\"\"\n    通过 id 获取博客信息\n    :param author_id:\n    :return: None/object\n    \"\"\"\n    return get_row_by_id(Author, author_id)\n\n\ndef get_author_row(*args, **kwargs):\n    \"\"\"\n    获取博客信息\n    :param args:\n    :param kwargs:\n    :return: None/object\n    \"\"\"\n    return get_row(Author, *args, **kwargs)\n\n\ndef add_author(author_data):\n    \"\"\"\n    添加博客信息\n    :param author_data:\n    :return: None/Value of author.id\n    \"\"\"\n    return add(Author, author_data)\n\n\ndef edit_author(author_id, author_data):\n    \"\"\"\n    修改博客信息\n    :param author_id:\n    :param author_data:\n    :return: Number of affected rows (Example: 0/1)\n    \"\"\"\n    return edit(Author, author_id, author_data)\n\n\ndef delete_author(author_id):\n    \"\"\"\n    删除博客信息\n    :param author_id:\n    :return: Number of affected rows (Example: 0/1)\n    \"\"\"\n    return delete(Author, author_id)\n\n\ndef get_author_rows(page=1, per_page=10, *args, **kwargs):\n    \"\"\"\n    获取博客列表（分页）\n    Usage:\n        items: 信息列表\n        has_next: 如果本页之后还有超过一个分页，则返回True\n        has_prev: 如果本页之前还有超过一个分页，则返回True\n        next_num: 返回下一页的页码\n        prev_num: 返回上一页的页码\n        iter_pages(): 页码列表\n        iter_pages(left_edge=2, left_current=2, right_current=5, right_edge=2) 页码列表默认参数\n    :param page:\n    :param per_page:\n    :param args:\n    :param kwargs:\n    :return:\n    \"\"\"\n    rows = get_rows(Author, page, per_page, *args, **kwargs)\n    return rows\n"
  },
  {
    "path": "app_frontend/api/bit_coin.py",
    "content": "#!/usr/bin/env python\n# encoding: utf-8\n\n\"\"\"\n@author: zhanghe\n@software: PyCharm\n@file: bit_coin.py\n@time: 2017/5/5 下午7:56\n\"\"\"\n\n\nfrom app_frontend.models import BitCoin\nfrom app_frontend.tools.db import get_row, get_rows, get_row_by_id, add, edit, delete\n\n\ndef get_bit_coin_row_by_id(bit_coin_id):\n    \"\"\"\n    通过 id 获取数字货币信息\n    :param bit_coin_id:\n    :return: None/object\n    \"\"\"\n    return get_row_by_id(BitCoin, bit_coin_id)\n\n\ndef get_bit_coin_row(*args, **kwargs):\n    \"\"\"\n    获取数字货币信息\n    :param args:\n    :param kwargs:\n    :return: None/object\n    \"\"\"\n    return get_row(BitCoin, *args, **kwargs)\n\n\ndef add_bit_coin(bit_coin_data):\n    \"\"\"\n    添加数字货币信息\n    :param bit_coin_data:\n    :return: None/Value of bit_coin.id\n    \"\"\"\n    return add(BitCoin, bit_coin_data)\n\n\ndef edit_bit_coin(bit_coin_id, bit_coin_data):\n    \"\"\"\n    修改数字货币信息\n    :param bit_coin_id:\n    :param bit_coin_data:\n    :return: Number of affected rows (Example: 0/1)\n    \"\"\"\n    return edit(BitCoin, bit_coin_id, bit_coin_data)\n\n\ndef delete_bit_coin(bit_coin_id):\n    \"\"\"\n    删除数字货币信息\n    :param bit_coin_id:\n    :return: Number of affected rows (Example: 0/1)\n    \"\"\"\n    return delete(BitCoin, bit_coin_id)\n\n\ndef get_bit_coin_rows(page=1, per_page=10, *args, **kwargs):\n    \"\"\"\n    获取数字货币列表（分页）\n    Usage:\n        items: 信息列表\n        has_next: 如果本页之后还有超过一个分页，则返回True\n        has_prev: 如果本页之前还有超过一个分页，则返回True\n        next_num: 返回下一页的页码\n        prev_num: 返回上一页的页码\n        iter_pages(): 页码列表\n        iter_pages(left_edge=2, left_current=2, right_current=5, right_edge=2) 页码列表默认参数\n    :param page:\n    :param per_page:\n    :param args:\n    :param kwargs:\n    :return:\n    \"\"\"\n    rows = get_rows(BitCoin, page, per_page, *args, **kwargs)\n    return rows\n"
  },
  {
    "path": "app_frontend/api/bit_coin_item.py",
    "content": "#!/usr/bin/env python\n# encoding: utf-8\n\n\"\"\"\n@author: zhanghe\n@software: PyCharm\n@file: bit_coin_item.py\n@time: 2017/6/28 下午2:00\n\"\"\"\n\n\nfrom app_frontend.models import BitCoinItem\nfrom app_frontend.tools.db import get_row, get_rows, get_row_by_id, add, edit, delete\n\n\ndef get_bit_coin_item_row_by_id(bit_coin_item_id):\n    \"\"\"\n    通过 id 获取钱包信息\n    :param bit_coin_item_id:\n    :return: None/object\n    \"\"\"\n    return get_row_by_id(BitCoinItem, bit_coin_item_id)\n\n\ndef get_bit_coin_item_row(*args, **kwargs):\n    \"\"\"\n    获取钱包信息\n    :param args:\n    :param kwargs:\n    :return: None/object\n    \"\"\"\n    return get_row(BitCoinItem, *args, **kwargs)\n\n\ndef add_bit_coin_item(bit_coin_item_data):\n    \"\"\"\n    添加钱包信息\n    :param bit_coin_item_data:\n    :return: None/Value of wallet.id\n    \"\"\"\n    return add(BitCoinItem, bit_coin_item_data)\n\n\ndef edit_bit_coin_item(bit_coin_item_id, bit_coin_item_data):\n    \"\"\"\n    修改钱包信息\n    :param bit_coin_item_id:\n    :param bit_coin_item_data:\n    :return: Number of affected rows (Example: 0/1)\n    \"\"\"\n    return edit(BitCoinItem, bit_coin_item_id, bit_coin_item_data)\n\n\ndef delete_bit_coin_item(bit_coin_item_id):\n    \"\"\"\n    删除钱包信息\n    :param bit_coin_item_id:\n    :return: Number of affected rows (Example: 0/1)\n    \"\"\"\n    return delete(BitCoinItem, bit_coin_item_id)\n\n\ndef get_bit_coin_item_rows(page=1, per_page=10, *args, **kwargs):\n    \"\"\"\n    获取钱包列表（分页）\n    Usage:\n        items: 信息列表\n        has_next: 如果本页之后还有超过一个分页，则返回True\n        has_prev: 如果本页之前还有超过一个分页，则返回True\n        next_num: 返回下一页的页码\n        prev_num: 返回上一页的页码\n        iter_pages(): 页码列表\n        iter_pages(left_edge=2, left_current=2, right_current=5, right_edge=2) 页码列表默认参数\n    :param page:\n    :param per_page:\n    :param args:\n    :param kwargs:\n    :return:\n    \"\"\"\n    rows = get_rows(BitCoinItem, page, per_page, *args, **kwargs)\n    return rows\n"
  },
  {
    "path": "app_frontend/api/blog.py",
    "content": "#!/usr/bin/env python\n# encoding: utf-8\n\n\"\"\"\n@blog: zhanghe\n@software: PyCharm\n@file: blog.py\n@time: 16-1-21 上午10:24\n\"\"\"\n\n\nfrom app_frontend.models import Blog\nfrom app_frontend.tools.db import get_row, get_rows, get_row_by_id, add, edit, delete\nfrom app_frontend.lib.counter import Counter\nfrom app_frontend.lib.container import Container\n\n\ndef get_blog_row_by_id(blog_id):\n    \"\"\"\n    通过 id 获取博客信息\n    :param blog_id:\n    :return: None/object\n    \"\"\"\n    return get_row_by_id(Blog, blog_id)\n\n\ndef get_blog_row(*args, **kwargs):\n    \"\"\"\n    获取博客信息\n    :param args:\n    :param kwargs:\n    :return: None/object\n    \"\"\"\n    return get_row(Blog, *args, **kwargs)\n\n\ndef add_blog(blog_data):\n    \"\"\"\n    添加博客信息\n    :param blog_data:\n    :return: None/Value of blog.id\n    \"\"\"\n    return add(Blog, blog_data)\n\n\ndef edit_blog(blog_id, blog_data):\n    \"\"\"\n    修改博客信息\n    :param blog_id:\n    :param blog_data:\n    :return: Number of affected rows (Example: 0/1)\n    \"\"\"\n    return edit(Blog, blog_id, blog_data)\n\n\ndef delete_blog(blog_id):\n    \"\"\"\n    删除博客信息\n    :param blog_id:\n    :return: Number of affected rows (Example: 0/1)\n    \"\"\"\n    return delete(Blog, blog_id)\n\n\ndef get_blog_rows(page=1, per_page=10, *args, **kwargs):\n    \"\"\"\n    获取博客列表（分页）\n    Usage:\n        items: 信息列表\n        has_next: 如果本页之后还有超过一个分页，则返回True\n        has_prev: 如果本页之前还有超过一个分页，则返回True\n        next_num: 返回下一页的页码\n        prev_num: 返回上一页的页码\n        iter_pages(): 页码列表\n        iter_pages(left_edge=2, left_current=2, right_current=5, right_edge=2) 页码列表默认参数\n    :param page:\n    :param per_page:\n    :param args:\n    :param kwargs:\n    :return:\n    \"\"\"\n    rows = get_rows(Blog, page, per_page, *args, **kwargs)\n    return rows\n\n\ndef get_blog_counter(blog_id):\n    \"\"\"\n    获取blog计数器\n    :param blog_id:\n    :return:\n    \"\"\"\n    blog_cnt_obj = Counter('blog')\n    return blog_cnt_obj.counter_blog_item(blog_id)\n\n\ndef set_blog_counter(blog_id, stat_type, num):\n    \"\"\"\n    设置blog计数器\n    :param blog_id:\n    :param stat_type:\n    :param num:\n    :return:\n    \"\"\"\n    blog_cnt_obj = Counter('blog')\n    return blog_cnt_obj.set_blog_counter(blog_id, stat_type, num)\n\n\ndef get_blog_list_counter(blog_id_list):\n    \"\"\"\n    获取blog计数器\n    :param blog_id_list:\n    :return:\n    \"\"\"\n    blog_cnt_obj = Counter('blog')\n    return blog_cnt_obj.counter_blog_list(blog_id_list)\n\n\ndef get_blog_container_status(blog_id, uid):\n    \"\"\"\n    获取blog容器状态\n    :param blog_id:\n    :param uid:\n    :return:\n    \"\"\"\n    blog_container_obj = Container('blog')\n    return blog_container_obj.get_item_container_status(blog_id, uid)\n\n\ndef get_blog_list_container_status(blog_id_list, uid):\n    \"\"\"\n    获取blog容器状态\n    :param blog_id_list:\n    :param uid:\n    :return:\n    \"\"\"\n    blog_container_obj = Container('blog')\n    return blog_container_obj.get_item_list_container_status(blog_id_list, uid)\n\n\ndef add_blog_stat_item(stat_type, blog_id, uid):\n    \"\"\"\n    添加blog统计明细\n    :param stat_type:\n    :param blog_id:\n    :param uid:\n    :return:\n    \"\"\"\n    blog_container_obj = Container('blog')\n    return blog_container_obj.add_item(stat_type, blog_id, uid)\n\nif __name__ == '__main__':\n    blog_rows = get_blog_rows(1, 10)\n    if blog_rows:\n        for item in blog_rows.items:\n            print item.id, item.author, item.title, item.pub_date\n\n    import json\n    print json.dumps(get_blog_counter(['1', '2', '3']), indent=4, ensure_ascii=False)\n"
  },
  {
    "path": "app_frontend/api/bonus.py",
    "content": "#!/usr/bin/env python\n# encoding: utf-8\n\n\"\"\"\n@author: zhanghe\n@software: PyCharm\n@file: bonus.py\n@time: 2017/5/2 上午12:36\n\"\"\"\n\n\nfrom app_frontend.models import Bonus\nfrom app_frontend.tools.db import get_row, get_rows, get_row_by_id, add, edit, delete\n\n\ndef get_bonus_row_by_id(bonus_id):\n    \"\"\"\n    通过 id 获取奖金信息\n    :param bonus_id:\n    :return: None/object\n    \"\"\"\n    return get_row_by_id(Bonus, bonus_id)\n\n\ndef get_bonus_row(*args, **kwargs):\n    \"\"\"\n    获取奖金信息\n    :param args:\n    :param kwargs:\n    :return: None/object\n    \"\"\"\n    return get_row(Bonus, *args, **kwargs)\n\n\ndef add_bonus(bonus_data):\n    \"\"\"\n    添加奖金信息\n    :param bonus_data:\n    :return: None/Value of wallet.id\n    \"\"\"\n    return add(Bonus, bonus_data)\n\n\ndef edit_bonus(bonus_id, bonus_data):\n    \"\"\"\n    修改奖金信息\n    :param bonus_id:\n    :param bonus_data:\n    :return: Number of affected rows (Example: 0/1)\n    \"\"\"\n    return edit(Bonus, bonus_id, bonus_data)\n\n\ndef delete_bonus(bonus_id):\n    \"\"\"\n    删除奖金信息\n    :param bonus_id:\n    :return: Number of affected rows (Example: 0/1)\n    \"\"\"\n    return delete(Bonus, bonus_id)\n\n\ndef get_bonus_rows(page=1, per_page=10, *args, **kwargs):\n    \"\"\"\n    获取奖金列表（分页）\n    Usage:\n        items: 信息列表\n        has_next: 如果本页之后还有超过一个分页，则返回True\n        has_prev: 如果本页之前还有超过一个分页，则返回True\n        next_num: 返回下一页的页码\n        prev_num: 返回上一页的页码\n        iter_pages(): 页码列表\n        iter_pages(left_edge=2, left_current=2, right_current=5, right_edge=2) 页码列表默认参数\n    :param page:\n    :param per_page:\n    :param args:\n    :param kwargs:\n    :return:\n    \"\"\"\n    rows = get_rows(Bonus, page, per_page, *args, **kwargs)\n    return rows\n"
  },
  {
    "path": "app_frontend/api/bonus_item.py",
    "content": "#!/usr/bin/env python\n# encoding: utf-8\n\n\"\"\"\n@author: zhanghe\n@software: PyCharm\n@file: bonus_item.py\n@time: 2017/5/22 下午10:58\n\"\"\"\n\n\nfrom app_frontend.models import BonusItem\nfrom app_frontend.tools.db import get_row, get_rows, get_row_by_id, add, edit, delete\n\n\ndef get_bonus_item_row_by_id(bonus_item_id):\n    \"\"\"\n    通过 id 获取奖金信息\n    :param bonus_item_id:\n    :return: None/object\n    \"\"\"\n    return get_row_by_id(BonusItem, bonus_item_id)\n\n\ndef get_bonus_item_row(*args, **kwargs):\n    \"\"\"\n    获取奖金信息\n    :param args:\n    :param kwargs:\n    :return: None/object\n    \"\"\"\n    return get_row(BonusItem, *args, **kwargs)\n\n\ndef add_bonus_item(bonus_item_data):\n    \"\"\"\n    添加奖金信息\n    :param bonus_item_data:\n    :return: None/Value of wallet.id\n    \"\"\"\n    return add(BonusItem, bonus_item_data)\n\n\ndef edit_bonus_item(bonus_item_id, bonus_item_data):\n    \"\"\"\n    修改奖金信息\n    :param bonus_item_id:\n    :param bonus_item_data:\n    :return: Number of affected rows (Example: 0/1)\n    \"\"\"\n    return edit(BonusItem, bonus_item_id, bonus_item_data)\n\n\ndef delete_bonus_item(bonus_item_id):\n    \"\"\"\n    删除奖金信息\n    :param bonus_item_id:\n    :return: Number of affected rows (Example: 0/1)\n    \"\"\"\n    return delete(BonusItem, bonus_item_id)\n\n\ndef get_bonus_item_rows(page=1, per_page=10, *args, **kwargs):\n    \"\"\"\n    获取奖金列表（分页）\n    Usage:\n        items: 信息列表\n        has_next: 如果本页之后还有超过一个分页，则返回True\n        has_prev: 如果本页之前还有超过一个分页，则返回True\n        next_num: 返回下一页的页码\n        prev_num: 返回上一页的页码\n        iter_pages(): 页码列表\n        iter_pages(left_edge=2, left_current=2, right_current=5, right_edge=2) 页码列表默认参数\n    :param page:\n    :param per_page:\n    :param args:\n    :param kwargs:\n    :return:\n    \"\"\"\n    rows = get_rows(BonusItem, page, per_page, *args, **kwargs)\n    return rows\n\n"
  },
  {
    "path": "app_frontend/api/complaint.py",
    "content": "#!/usr/bin/env python\n# encoding: utf-8\n\n\"\"\"\n@author: zhanghe\n@software: PyCharm\n@file: complaint.py\n@time: 2017/4/29 下午2:30\n\"\"\"\n\n\nfrom app_frontend.models import Complaint\nfrom app_frontend.tools.db import get_row, get_rows, get_row_by_id, add, edit, delete\n\n\ndef get_complaint_row_by_id(complaint_id):\n    \"\"\"\n    通过 id 获取投诉信息\n    :param complaint_id:\n    :return: None/object\n    \"\"\"\n    return get_row_by_id(Complaint, complaint_id)\n\n\ndef get_complaint_row(*args, **kwargs):\n    \"\"\"\n    获取投诉信息\n    :param args:\n    :param kwargs:\n    :return: None/object\n    \"\"\"\n    return get_row(Complaint, *args, **kwargs)\n\n\ndef add_complaint(complaint_data):\n    \"\"\"\n    添加投诉信息\n    :param complaint_data:\n    :return: None/Value of order.id\n    \"\"\"\n    return add(Complaint, complaint_data)\n\n\ndef edit_complaint(complaint_id, complaint_data):\n    \"\"\"\n    修改投诉信息\n    :param complaint_id:\n    :param complaint_data:\n    :return: Number of affected rows (Example: 0/1)\n    \"\"\"\n    return edit(Complaint, complaint_id, complaint_data)\n\n\ndef delete_complaint(complaint_id):\n    \"\"\"\n    删除投诉信息\n    :param complaint_id:\n    :return: Number of affected rows (Example: 0/1)\n    \"\"\"\n    return delete(Complaint, complaint_id)\n\n\ndef get_complaint_rows(page=1, per_page=10, *args, **kwargs):\n    \"\"\"\n    获取投诉列表（分页）\n    Usage:\n        items: 信息列表\n        has_next: 如果本页之后还有超过一个分页，则返回True\n        has_prev: 如果本页之前还有超过一个分页，则返回True\n        next_num: 返回下一页的页码\n        prev_num: 返回上一页的页码\n        iter_pages(): 页码列表\n        iter_pages(left_edge=2, left_current=2, right_current=5, right_edge=2) 页码列表默认参数\n    :param page:\n    :param per_page:\n    :param args:\n    :param kwargs:\n    :return:\n    \"\"\"\n    rows = get_rows(Complaint, page, per_page, *args, **kwargs)\n    return rows\n\n"
  },
  {
    "path": "app_frontend/api/credit.py",
    "content": "#!/usr/bin/env python\n# encoding: utf-8\n\n\"\"\"\n@author: zhanghe\n@software: PyCharm\n@file: credit.py\n@time: 2017/4/24 下午4:22\n\"\"\"\n\n\nfrom app_frontend.models import Credit\nfrom app_frontend.tools.db import get_row, get_rows, get_row_by_id, add, edit, delete, update_rows\n\n\ndef get_user_credit_row_by_id(user_credit_id):\n    \"\"\"\n    通过 id 获取用户声望信息\n    :param user_credit_id:\n    :return: None/object\n    \"\"\"\n    return get_row_by_id(Credit, user_credit_id)\n\n\ndef get_user_credit_row(*args, **kwargs):\n    \"\"\"\n    获取用户声望信息\n    :param args:\n    :param kwargs:\n    :return: None/object\n    \"\"\"\n    return get_row(Credit, *args, **kwargs)\n\n\ndef add_user_credit(user_credit_data):\n    \"\"\"\n    添加用户声望信息\n    :param user_credit_data:\n    :return: None/Value of user.id\n    \"\"\"\n    return add(Credit, user_credit_data)\n\n\ndef edit_user_credit(user_credit_id, user_credit_data):\n    \"\"\"\n    修改用户声望信息\n    :param user_credit_id:\n    :param user_credit_data:\n    :return: Number of affected rows (Example: 0/1)\n    \"\"\"\n    return edit(Credit, user_credit_id, user_credit_data)\n\n\ndef delete_user_credit(user_credit_id):\n    \"\"\"\n    删除用户信息\n    :param user_credit_id:\n    :return: Number of affected rows (Example: 0/1)\n    \"\"\"\n    return delete(Credit, user_credit_id)\n\n\ndef get_user_credit_rows(page=1, per_page=10, *args, **kwargs):\n    \"\"\"\n    获取用户声望列表（分页）\n    Usage:\n        items: 信息列表\n        has_next: 如果本页之后还有超过一个分页，则返回True\n        has_prev: 如果本页之前还有超过一个分页，则返回True\n        next_num: 返回下一页的页码\n        prev_num: 返回上一页的页码\n        iter_pages(): 页码列表\n        iter_pages(left_edge=2, left_current=2, right_current=5, right_edge=2) 页码列表默认参数\n    :param page:\n    :param per_page:\n    :param args:\n    :param kwargs:\n    :return:\n    \"\"\"\n    rows = get_rows(Credit, page, per_page, *args, **kwargs)\n    return rows\n\n\ndef update_user_credit_rows(data, *args, **kwargs):\n    \"\"\"\n    批量更新用户声望信息\n    \"\"\"\n    return update_rows(Credit, data, *args, **kwargs)\n"
  },
  {
    "path": "app_frontend/api/message.py",
    "content": "#!/usr/bin/env python\n# encoding: utf-8\n\n\"\"\"\n@author: zhanghe\n@software: PyCharm\n@file: message.py\n@time: 2017/4/29 下午2:30\n\"\"\"\n\n\nfrom app_frontend.models import Message\nfrom app_frontend.tools.db import get_row, get_rows, get_row_by_id, add, edit, delete\n\n\ndef get_message_row_by_id(message_id):\n    \"\"\"\n    通过 id 获取留言信息\n    :param message_id:\n    :return: None/object\n    \"\"\"\n    return get_row_by_id(Message, message_id)\n\n\ndef get_message_row(*args, **kwargs):\n    \"\"\"\n    获取留言信息\n    :param args:\n    :param kwargs:\n    :return: None/object\n    \"\"\"\n    return get_row(Message, *args, **kwargs)\n\n\ndef add_message(message_data):\n    \"\"\"\n    添加留言信息\n    :param message_data:\n    :return: None/Value of order.id\n    \"\"\"\n    return add(Message, message_data)\n\n\ndef edit_message(message_id, message_data):\n    \"\"\"\n    修改留言信息\n    :param message_id:\n    :param message_data:\n    :return: Number of affected rows (Example: 0/1)\n    \"\"\"\n    return edit(Message, message_id, message_data)\n\n\ndef delete_message(message_id):\n    \"\"\"\n    删除留言信息\n    :param message_id:\n    :return: Number of affected rows (Example: 0/1)\n    \"\"\"\n    return delete(Message, message_id)\n\n\ndef get_message_rows(page=1, per_page=10, *args, **kwargs):\n    \"\"\"\n    获取留言列表（分页）\n    Usage:\n        items: 信息列表\n        has_next: 如果本页之后还有超过一个分页，则返回True\n        has_prev: 如果本页之前还有超过一个分页，则返回True\n        next_num: 返回下一页的页码\n        prev_num: 返回上一页的页码\n        iter_pages(): 页码列表\n        iter_pages(left_edge=2, left_current=2, right_current=5, right_edge=2) 页码列表默认参数\n    :param page:\n    :param per_page:\n    :param args:\n    :param kwargs:\n    :return:\n    \"\"\"\n    rows = get_rows(Message, page, per_page, *args, **kwargs)\n    return rows\n"
  },
  {
    "path": "app_frontend/api/order.py",
    "content": "#!/usr/bin/env python\n# encoding: utf-8\n\n\"\"\"\n@author: zhanghe\n@software: PyCharm\n@file: order.py\n@time: 2017/4/13 下午9:45\n\"\"\"\n\n\nfrom app_frontend.models import Order\nfrom app_frontend.tools.db import get_row, get_rows, get_lists, get_row_by_id, add, edit, delete\n\n\ndef get_order_row_by_id(order_id):\n    \"\"\"\n    通过 id 获取订单信息\n    :param order_id:\n    :return: None/object\n    \"\"\"\n    return get_row_by_id(Order, order_id)\n\n\ndef get_order_row(*args, **kwargs):\n    \"\"\"\n    获取订单信息\n    :param args:\n    :param kwargs:\n    :return: None/object\n    \"\"\"\n    return get_row(Order, *args, **kwargs)\n\n\ndef add_order(order_data):\n    \"\"\"\n    添加订单信息\n    :param order_data:\n    :return: None/Value of order.id\n    \"\"\"\n    return add(Order, order_data)\n\n\ndef edit_order(order_id, order_data):\n    \"\"\"\n    修改订单信息\n    :param order_id:\n    :param order_data:\n    :return: Number of affected rows (Example: 0/1)\n    \"\"\"\n    return edit(Order, order_id, order_data)\n\n\ndef delete_order(order_id):\n    \"\"\"\n    删除订单信息\n    :param order_id:\n    :return: Number of affected rows (Example: 0/1)\n    \"\"\"\n    return delete(Order, order_id)\n\n\ndef get_order_rows(page=1, per_page=10, *args, **kwargs):\n    \"\"\"\n    获取订单列表（分页）\n    Usage:\n        items: 信息列表\n        has_next: 如果本页之后还有超过一个分页，则返回True\n        has_prev: 如果本页之前还有超过一个分页，则返回True\n        next_num: 返回下一页的页码\n        prev_num: 返回上一页的页码\n        iter_pages(): 页码列表\n        iter_pages(left_edge=2, left_current=2, right_current=5, right_edge=2) 页码列表默认参数\n    :param page:\n    :param per_page:\n    :param args:\n    :param kwargs:\n    :return:\n    \"\"\"\n    rows = get_rows(Order, page, per_page, *args, **kwargs)\n    return rows\n\n\ndef get_order_lists(*args, **kwargs):\n    \"\"\"\n    获取订单列表信息\n    :param args:\n    :param kwargs:\n    :return:\n    \"\"\"\n    return get_lists(Order, *args, **kwargs)\n"
  },
  {
    "path": "app_frontend/api/order_bill.py",
    "content": "#!/usr/bin/env python\n# encoding: utf-8\n\n\"\"\"\n@author: zhanghe\n@software: PyCharm\n@file: order_bill.py\n@time: 2017/5/13 下午11:24\n\"\"\"\n\n\nfrom app_frontend.models import OrderBill\nfrom app_frontend.tools.db import get_row, get_rows, get_row_by_id, add, edit, delete, get_lists, count\n\n\ndef get_order_bill_row_by_id(order_bill_id):\n    \"\"\"\n    通过 id 获取订单支付凭证信息\n    :param order_bill_id:\n    :return: None/object\n    \"\"\"\n    return get_row_by_id(OrderBill, order_bill_id)\n\n\ndef get_order_bill_row(*args, **kwargs):\n    \"\"\"\n    获取订单支付凭证信息\n    :param args:\n    :param kwargs:\n    :return: None/object\n    \"\"\"\n    return get_row(OrderBill, *args, **kwargs)\n\n\ndef add_order_bill(order_data):\n    \"\"\"\n    添加订单支付凭证信息\n    :param order_data:\n    :return: None/Value of order.id\n    \"\"\"\n    return add(OrderBill, order_data)\n\n\ndef edit_order_bill(order_bill_id, order_data):\n    \"\"\"\n    修改订单支付凭证信息\n    :param order_bill_id:\n    :param order_data:\n    :return: Number of affected rows (Example: 0/1)\n    \"\"\"\n    return edit(OrderBill, order_bill_id, order_data)\n\n\ndef delete_order_bill(order_bill_id):\n    \"\"\"\n    删除订单支付凭证信息\n    :param order_bill_id:\n    :return: Number of affected rows (Example: 0/1)\n    \"\"\"\n    return delete(OrderBill, order_bill_id)\n\n\ndef get_order_bill_rows(page=1, per_page=10, *args, **kwargs):\n    \"\"\"\n    获取订单支付凭证列表（分页）\n    Usage:\n        items: 信息列表\n        has_next: 如果本页之后还有超过一个分页，则返回True\n        has_prev: 如果本页之前还有超过一个分页，则返回True\n        next_num: 返回下一页的页码\n        prev_num: 返回上一页的页码\n        iter_pages(): 页码列表\n        iter_pages(left_edge=2, left_current=2, right_current=5, right_edge=2) 页码列表默认参数\n    :param page:\n    :param per_page:\n    :param args:\n    :param kwargs:\n    :return:\n    \"\"\"\n    rows = get_rows(OrderBill, page, per_page, *args, **kwargs)\n    return rows\n\n\ndef get_order_bill_lists(*args, **kwargs):\n    \"\"\"\n    获取订单支付凭证列表\n    :param args:\n    :param kwargs:\n    :return: None/list\n    \"\"\"\n    return get_lists(OrderBill, *args, **kwargs)\n\n\ndef get_order_bill_count(*args, **kwargs):\n    \"\"\"\n    获取订单支付凭证个数\n    :param args:\n    :param kwargs:\n    :return: 0/Number（int）\n    \"\"\"\n    return count(OrderBill, *args, **kwargs)\n"
  },
  {
    "path": "app_frontend/api/scheduling.py",
    "content": "#!/usr/bin/env python\n# encoding: utf-8\n\n\"\"\"\n@author: zhanghe\n@software: PyCharm\n@file: scheduling.py\n@time: 2017/6/29 下午8:46\n\"\"\"\n\n\nfrom app_frontend.models import Scheduling\nfrom app_frontend.tools.db import get_row, get_rows, get_row_by_id, add, edit, delete\n\n\ndef get_scheduling_row_by_id(scheduling_id):\n    \"\"\"\n    通过 id 获取排单信息\n    :param scheduling_id:\n    :return: None/object\n    \"\"\"\n    return get_row_by_id(Scheduling, scheduling_id)\n\n\ndef get_scheduling_row(*args, **kwargs):\n    \"\"\"\n    获取排单信息\n    :param args:\n    :param kwargs:\n    :return: None/object\n    \"\"\"\n    return get_row(Scheduling, *args, **kwargs)\n\n\ndef add_scheduling(scheduling_data):\n    \"\"\"\n    添加排单信息\n    :param scheduling_data:\n    :return: None/Value of score.id\n    \"\"\"\n    return add(Scheduling, scheduling_data)\n\n\ndef edit_scheduling(scheduling_id, scheduling_data):\n    \"\"\"\n    修改排单信息\n    :param scheduling_id:\n    :param scheduling_data:\n    :return: Number of affected rows (Example: 0/1)\n    \"\"\"\n    return edit(Scheduling, scheduling_id, scheduling_data)\n\n\ndef delete_scheduling(scheduling_id):\n    \"\"\"\n    删除排单信息\n    :param scheduling_id:\n    :return: Number of affected rows (Example: 0/1)\n    \"\"\"\n    return delete(Scheduling, scheduling_id)\n\n\ndef get_scheduling_rows(page=1, per_page=10, *args, **kwargs):\n    \"\"\"\n    获取排单列表（分页）\n    Usage:\n        items: 信息列表\n        has_next: 如果本页之后还有超过一个分页，则返回True\n        has_prev: 如果本页之前还有超过一个分页，则返回True\n        next_num: 返回下一页的页码\n        prev_num: 返回上一页的页码\n        iter_pages(): 页码列表\n        iter_pages(left_edge=2, left_current=2, right_current=5, right_edge=2) 页码列表默认参数\n    :param page:\n    :param per_page:\n    :param args:\n    :param kwargs:\n    :return:\n    \"\"\"\n    rows = get_rows(Scheduling, page, per_page, *args, **kwargs)\n    return rows\n"
  },
  {
    "path": "app_frontend/api/scheduling_item.py",
    "content": "#!/usr/bin/env python\n# encoding: utf-8\n\n\"\"\"\n@author: zhanghe\n@software: PyCharm\n@file: scheduling_item.py\n@time: 2017/6/29 下午8:46\n\"\"\"\n\n\nfrom app_frontend.models import SchedulingItem\nfrom app_frontend.tools.db import get_row, get_rows, get_row_by_id, add, edit, delete\n\n\ndef get_scheduling_item_item_row_by_id(scheduling_item_item_id):\n    \"\"\"\n    通过 id 获取排单明细信息\n    :param scheduling_item_item_id:\n    :return: None/object\n    \"\"\"\n    return get_row_by_id(SchedulingItem, scheduling_item_item_id)\n\n\ndef get_scheduling_item_item_row(*args, **kwargs):\n    \"\"\"\n    获取排单明细信息\n    :param args:\n    :param kwargs:\n    :return: None/object\n    \"\"\"\n    return get_row(SchedulingItem, *args, **kwargs)\n\n\ndef add_scheduling_item(scheduling_item_item_data):\n    \"\"\"\n    添加排单明细信息\n    :param scheduling_item_item_data:\n    :return: None/Value of score.id\n    \"\"\"\n    return add(SchedulingItem, scheduling_item_item_data)\n\n\ndef edit_scheduling_item(scheduling_item_item_id, scheduling_item_item_data):\n    \"\"\"\n    修改排单明细信息\n    :param scheduling_item_item_id:\n    :param scheduling_item_item_data:\n    :return: Number of affected rows (Example: 0/1)\n    \"\"\"\n    return edit(SchedulingItem, scheduling_item_item_id, scheduling_item_item_data)\n\n\ndef delete_scheduling_item(scheduling_item_item_id):\n    \"\"\"\n    删除排单明细信息\n    :param scheduling_item_item_id:\n    :return: Number of affected rows (Example: 0/1)\n    \"\"\"\n    return delete(SchedulingItem, scheduling_item_item_id)\n\n\ndef get_scheduling_item_item_rows(page=1, per_page=10, *args, **kwargs):\n    \"\"\"\n    获取排单明细列表（分页）\n    Usage:\n        items: 信息列表\n        has_next: 如果本页之后还有超过一个分页，则返回True\n        has_prev: 如果本页之前还有超过一个分页，则返回True\n        next_num: 返回下一页的页码\n        prev_num: 返回上一页的页码\n        iter_pages(): 页码列表\n        iter_pages(left_edge=2, left_current=2, right_current=5, right_edge=2) 页码列表默认参数\n    :param page:\n    :param per_page:\n    :param args:\n    :param kwargs:\n    :return:\n    \"\"\"\n    rows = get_rows(SchedulingItem, page, per_page, *args, **kwargs)\n    return rows\n"
  },
  {
    "path": "app_frontend/api/score.py",
    "content": "#!/usr/bin/env python\n# encoding: utf-8\n\n\"\"\"\n@author: zhanghe\n@software: PyCharm\n@file: score.py\n@time: 2017/4/25 下午1:29\n\"\"\"\n\n\nfrom app_frontend.models import Score\nfrom app_frontend.tools.db import get_row, get_rows, get_row_by_id, add, edit, delete\n\n\ndef get_score_row_by_id(score_id):\n    \"\"\"\n    通过 id 获取积分信息\n    :param score_id:\n    :return: None/object\n    \"\"\"\n    return get_row_by_id(Score, score_id)\n\n\ndef get_score_row(*args, **kwargs):\n    \"\"\"\n    获取积分信息\n    :param args:\n    :param kwargs:\n    :return: None/object\n    \"\"\"\n    return get_row(Score, *args, **kwargs)\n\n\ndef add_score(score_data):\n    \"\"\"\n    添加积分信息\n    :param score_data:\n    :return: None/Value of score.id\n    \"\"\"\n    return add(Score, score_data)\n\n\ndef edit_score(score_id, score_data):\n    \"\"\"\n    修改积分信息\n    :param score_id:\n    :param score_data:\n    :return: Number of affected rows (Example: 0/1)\n    \"\"\"\n    return edit(Score, score_id, score_data)\n\n\ndef delete_score(score_id):\n    \"\"\"\n    删除积分信息\n    :param score_id:\n    :return: Number of affected rows (Example: 0/1)\n    \"\"\"\n    return delete(Score, score_id)\n\n\ndef get_score_rows(page=1, per_page=10, *args, **kwargs):\n    \"\"\"\n    获取积分列表（分页）\n    Usage:\n        items: 信息列表\n        has_next: 如果本页之后还有超过一个分页，则返回True\n        has_prev: 如果本页之前还有超过一个分页，则返回True\n        next_num: 返回下一页的页码\n        prev_num: 返回上一页的页码\n        iter_pages(): 页码列表\n        iter_pages(left_edge=2, left_current=2, right_current=5, right_edge=2) 页码列表默认参数\n    :param page:\n    :param per_page:\n    :param args:\n    :param kwargs:\n    :return:\n    \"\"\"\n    rows = get_rows(Score, page, per_page, *args, **kwargs)\n    return rows\n"
  },
  {
    "path": "app_frontend/api/score_charity.py",
    "content": "#!/usr/bin/env python\n# encoding: utf-8\n\n\"\"\"\n@author: zhanghe\n@software: PyCharm\n@file: score_charity.py\n@time: 2017/6/28 下午2:34\n\"\"\"\n\n\nfrom datetime import datetime\n\nfrom decimal import Decimal\n\nfrom app_frontend.database import db\nfrom app_frontend.models import ScoreCharity, ScoreCharityItem\nfrom app_frontend.tools.db import get_row, get_rows, get_row_by_id, add, edit, delete\n\n\ndef get_score_charity_row_by_id(score_charity_id):\n    \"\"\"\n    通过 id 获取积分信息\n    :param score_charity_id:\n    :return: None/object\n    \"\"\"\n    return get_row_by_id(ScoreCharity, score_charity_id)\n\n\ndef get_score_charity_row(*args, **kwargs):\n    \"\"\"\n    获取积分信息\n    :param args:\n    :param kwargs:\n    :return: None/object\n    \"\"\"\n    return get_row(ScoreCharity, *args, **kwargs)\n\n\ndef add_score_charity(score_charity_data):\n    \"\"\"\n    添加积分信息\n    :param score_charity_data:\n    :return: None/Value of score.id\n    \"\"\"\n    return add(ScoreCharity, score_charity_data)\n\n\ndef edit_score_charity(score_charity_id, score_charity_data):\n    \"\"\"\n    修改积分信息\n    :param score_charity_id:\n    :param score_charity_data:\n    :return: Number of affected rows (Example: 0/1)\n    \"\"\"\n    return edit(ScoreCharity, score_charity_id, score_charity_data)\n\n\ndef delete_score_charity(score_charity_id):\n    \"\"\"\n    删除积分信息\n    :param score_charity_id:\n    :return: Number of affected rows (Example: 0/1)\n    \"\"\"\n    return delete(ScoreCharity, score_charity_id)\n\n\ndef get_score_charity_rows(page=1, per_page=10, *args, **kwargs):\n    \"\"\"\n    获取积分列表（分页）\n    Usage:\n        items: 信息列表\n        has_next: 如果本页之后还有超过一个分页，则返回True\n        has_prev: 如果本页之前还有超过一个分页，则返回True\n        next_num: 返回下一页的页码\n        prev_num: 返回上一页的页码\n        iter_pages(): 页码列表\n        iter_pages(left_edge=2, left_current=2, right_current=5, right_edge=2) 页码列表默认参数\n    :param page:\n    :param per_page:\n    :param args:\n    :param kwargs:\n    :return:\n    \"\"\"\n    rows = get_rows(ScoreCharity, page, per_page, *args, **kwargs)\n    return rows\n\n\ndef increase_score_charity(user_id, num=1):\n    \"\"\"\n    增加积分\n    :param user_id:\n    :param num:\n    :return: Decimal 0/1\n    :raise: Exception\n    \"\"\"\n    try:\n        if not isinstance(num, Decimal):\n            num = Decimal(num)\n        current_time = datetime.utcnow()\n        # 更新积分总表\n        score_obj = db.session.query(ScoreCharity).filter(ScoreCharity.user_id == user_id)\n        if score_obj.first():\n            # 总表有记录，更新\n            score_amount = ScoreCharity.amount + num\n            score_charity_data = {\n                'user_id': user_id,\n                'amount': score_amount,\n                'update_time': current_time\n            }\n            result_update = score_obj.update(score_charity_data)\n            result = score_obj.first().amount if result_update else 0\n        else:\n            # 总表无记录，插入\n            score_charity_data = {\n                'user_id': user_id,\n                'amount': num,\n                'create_time': current_time,\n                'update_time': current_time\n            }\n            score_obj = ScoreCharity(**score_charity_data)\n            db.session.add(score_obj)\n            result_add = score_obj.user_id\n            result = num if result_add else 0\n        db.session.commit()\n        return result\n    except Exception as e:\n        db.session.rollback()\n        raise e\n\n\nif __name__ == '__main__':\n    print increase_score_charity(7, num=1)\n"
  },
  {
    "path": "app_frontend/api/score_charity_item.py",
    "content": "#!/usr/bin/env python\n# encoding: utf-8\n\n\"\"\"\n@author: zhanghe\n@software: PyCharm\n@file: score_charity_item.py\n@time: 2017/6/9 下午2:34\n\"\"\"\n\n\nfrom app_frontend.models import ScoreCharityItem\nfrom app_frontend.tools.db import get_row, get_rows, get_row_by_id, add, edit, delete\n\n\ndef get_score_charity_item_row_by_id(score_charity_item_id):\n    \"\"\"\n    通过 id 获取积分信息\n    :param score_charity_item_id:\n    :return: None/object\n    \"\"\"\n    return get_row_by_id(ScoreCharityItem, score_charity_item_id)\n\n\ndef get_score_charity_item_row(*args, **kwargs):\n    \"\"\"\n    获取积分信息\n    :param args:\n    :param kwargs:\n    :return: None/object\n    \"\"\"\n    return get_row(ScoreCharityItem, *args, **kwargs)\n\n\ndef add_score_charity_item(score_charity_item_data):\n    \"\"\"\n    添加积分信息\n    :param score_charity_item_data:\n    :return: None/Value of score.id\n    \"\"\"\n    return add(ScoreCharityItem, score_charity_item_data)\n\n\ndef edit_score_charity_item(score_charity_item_id, score_charity_item_data):\n    \"\"\"\n    修改积分信息\n    :param score_charity_item_id:\n    :param score_charity_item_data:\n    :return: Number of affected rows (Example: 0/1)\n    \"\"\"\n    return edit(ScoreCharityItem, score_charity_item_id, score_charity_item_data)\n\n\ndef delete_score_charity_item(score_charity_item_id):\n    \"\"\"\n    删除积分信息\n    :param score_charity_item_id:\n    :return: Number of affected rows (Example: 0/1)\n    \"\"\"\n    return delete(ScoreCharityItem, score_charity_item_id)\n\n\ndef get_score_charity_item_rows(page=1, per_page=10, *args, **kwargs):\n    \"\"\"\n    获取积分列表（分页）\n    Usage:\n        items: 信息列表\n        has_next: 如果本页之后还有超过一个分页，则返回True\n        has_prev: 如果本页之前还有超过一个分页，则返回True\n        next_num: 返回下一页的页码\n        prev_num: 返回上一页的页码\n        iter_pages(): 页码列表\n        iter_pages(left_edge=2, left_current=2, right_current=5, right_edge=2) 页码列表默认参数\n    :param page:\n    :param per_page:\n    :param args:\n    :param kwargs:\n    :return:\n    \"\"\"\n    rows = get_rows(ScoreCharityItem, page, per_page, *args, **kwargs)\n    return rows\n"
  },
  {
    "path": "app_frontend/api/score_digital.py",
    "content": "#!/usr/bin/env python\n# encoding: utf-8\n\n\"\"\"\n@author: zhanghe\n@software: PyCharm\n@file: score_digital.py\n@time: 2017/6/28 下午2:34\n\"\"\"\nfrom datetime import datetime\nfrom decimal import Decimal\n\nfrom app_frontend.models import ScoreDigital\nfrom app_frontend.database import db\nfrom app_frontend.tools.db import get_row, get_rows, get_row_by_id, add, edit, delete\n\n\ndef get_score_digital_row_by_id(score_digital_id):\n    \"\"\"\n    通过 id 获取积分信息\n    :param score_digital_id:\n    :return: None/object\n    \"\"\"\n    return get_row_by_id(ScoreDigital, score_digital_id)\n\n\ndef get_score_digital_row(*args, **kwargs):\n    \"\"\"\n    获取积分信息\n    :param args:\n    :param kwargs:\n    :return: None/object\n    \"\"\"\n    return get_row(ScoreDigital, *args, **kwargs)\n\n\ndef add_score_digital(score_digital_data):\n    \"\"\"\n    添加积分信息\n    :param score_digital_data:\n    :return: None/Value of score.id\n    \"\"\"\n    return add(ScoreDigital, score_digital_data)\n\n\ndef edit_score_digital(score_digital_id, score_digital_data):\n    \"\"\"\n    修改积分信息\n    :param score_digital_id:\n    :param score_digital_data:\n    :return: Number of affected rows (Example: 0/1)\n    \"\"\"\n    return edit(ScoreDigital, score_digital_id, score_digital_data)\n\n\ndef delete_score_digital(score_digital_id):\n    \"\"\"\n    删除积分信息\n    :param score_digital_id:\n    :return: Number of affected rows (Example: 0/1)\n    \"\"\"\n    return delete(ScoreDigital, score_digital_id)\n\n\ndef get_score_digital_rows(page=1, per_page=10, *args, **kwargs):\n    \"\"\"\n    获取积分列表（分页）\n    Usage:\n        items: 信息列表\n        has_next: 如果本页之后还有超过一个分页，则返回True\n        has_prev: 如果本页之前还有超过一个分页，则返回True\n        next_num: 返回下一页的页码\n        prev_num: 返回上一页的页码\n        iter_pages(): 页码列表\n        iter_pages(left_edge=2, left_current=2, right_current=5, right_edge=2) 页码列表默认参数\n    :param page:\n    :param per_page:\n    :param args:\n    :param kwargs:\n    :return:\n    \"\"\"\n    rows = get_rows(ScoreDigital, page, per_page, *args, **kwargs)\n    return rows\n\n\ndef increase_score_digital(user_id, num=1):\n    \"\"\"\n    增加积分\n    :param user_id:\n    :param num:\n    :return: Decimal 0/1\n    :raise: Exception\n    \"\"\"\n    try:\n        if not isinstance(num, Decimal):\n            num = Decimal(num)\n        current_time = datetime.utcnow()\n        # 更新积分总表\n        score_obj = db.session.query(ScoreDigital).filter(ScoreDigital.user_id == user_id)\n        if score_obj.first():\n            # 总表有记录，更新\n            score_amount = ScoreDigital.amount + num\n            score_digital_data = {\n                'user_id': user_id,\n                'amount': score_amount,\n                'update_time': current_time\n            }\n            result_update = score_obj.update(score_digital_data)\n            result = score_obj.first().amount if result_update else 0\n        else:\n            # 总表无记录，插入\n            score_digital_data = {\n                'user_id': user_id,\n                'amount': num,\n                'create_time': current_time,\n                'update_time': current_time\n            }\n            score_obj = ScoreDigital(**score_digital_data)\n            db.session.add(score_obj)\n            result_add = score_obj.user_id\n            result = num if result_add else 0\n        db.session.commit()\n        return result\n    except Exception as e:\n        db.session.rollback()\n        raise e\n"
  },
  {
    "path": "app_frontend/api/score_digital_item.py",
    "content": "#!/usr/bin/env python\n# encoding: utf-8\n\n\"\"\"\n@author: zhanghe\n@software: PyCharm\n@file: score_digital_item.py\n@time: 2017/6/9 下午2:34\n\"\"\"\n\n\nfrom app_frontend.models import ScoreDigitalItem\nfrom app_frontend.tools.db import get_row, get_rows, get_row_by_id, add, edit, delete\n\n\ndef get_score_digital_item_row_by_id(score_digital_item_id):\n    \"\"\"\n    通过 id 获取积分信息\n    :param score_digital_item_id:\n    :return: None/object\n    \"\"\"\n    return get_row_by_id(ScoreDigitalItem, score_digital_item_id)\n\n\ndef get_score_digital_item_row(*args, **kwargs):\n    \"\"\"\n    获取积分信息\n    :param args:\n    :param kwargs:\n    :return: None/object\n    \"\"\"\n    return get_row(ScoreDigitalItem, *args, **kwargs)\n\n\ndef add_score_digital_item(score_digital_item_data):\n    \"\"\"\n    添加积分信息\n    :param score_digital_item_data:\n    :return: None/Value of score.id\n    \"\"\"\n    return add(ScoreDigitalItem, score_digital_item_data)\n\n\ndef edit_score_digital_item(score_digital_item_id, score_digital_item_data):\n    \"\"\"\n    修改积分信息\n    :param score_digital_item_id:\n    :param score_digital_item_data:\n    :return: Number of affected rows (Example: 0/1)\n    \"\"\"\n    return edit(ScoreDigitalItem, score_digital_item_id, score_digital_item_data)\n\n\ndef delete_score_digital_item(score_digital_item_id):\n    \"\"\"\n    删除积分信息\n    :param score_digital_item_id:\n    :return: Number of affected rows (Example: 0/1)\n    \"\"\"\n    return delete(ScoreDigitalItem, score_digital_item_id)\n\n\ndef get_score_digital_item_rows(page=1, per_page=10, *args, **kwargs):\n    \"\"\"\n    获取积分列表（分页）\n    Usage:\n        items: 信息列表\n        has_next: 如果本页之后还有超过一个分页，则返回True\n        has_prev: 如果本页之前还有超过一个分页，则返回True\n        next_num: 返回下一页的页码\n        prev_num: 返回上一页的页码\n        iter_pages(): 页码列表\n        iter_pages(left_edge=2, left_current=2, right_current=5, right_edge=2) 页码列表默认参数\n    :param page:\n    :param per_page:\n    :param args:\n    :param kwargs:\n    :return:\n    \"\"\"\n    rows = get_rows(ScoreDigitalItem, page, per_page, *args, **kwargs)\n    return rows\n"
  },
  {
    "path": "app_frontend/api/score_expense.py",
    "content": "#!/usr/bin/env python\n# encoding: utf-8\n\n\"\"\"\n@author: zhanghe\n@software: PyCharm\n@file: score_expense.py\n@time: 2017/6/28 下午2:34\n\"\"\"\nfrom datetime import datetime\nfrom decimal import Decimal\n\nfrom app_frontend.database import db\nfrom app_frontend.models import ScoreExpense\nfrom app_frontend.tools.db import get_row, get_rows, get_row_by_id, add, edit, delete\n\n\ndef get_score_expense_row_by_id(score_expense_id):\n    \"\"\"\n    通过 id 获取积分信息\n    :param score_expense_id:\n    :return: None/object\n    \"\"\"\n    return get_row_by_id(ScoreExpense, score_expense_id)\n\n\ndef get_score_expense_row(*args, **kwargs):\n    \"\"\"\n    获取积分信息\n    :param args:\n    :param kwargs:\n    :return: None/object\n    \"\"\"\n    return get_row(ScoreExpense, *args, **kwargs)\n\n\ndef add_score_expense(score_expense_data):\n    \"\"\"\n    添加积分信息\n    :param score_expense_data:\n    :return: None/Value of score.id\n    \"\"\"\n    return add(ScoreExpense, score_expense_data)\n\n\ndef edit_score_expense(score_expense_id, score_expense_data):\n    \"\"\"\n    修改积分信息\n    :param score_expense_id:\n    :param score_expense_data:\n    :return: Number of affected rows (Example: 0/1)\n    \"\"\"\n    return edit(ScoreExpense, score_expense_id, score_expense_data)\n\n\ndef delete_score_expense(score_expense_id):\n    \"\"\"\n    删除积分信息\n    :param score_expense_id:\n    :return: Number of affected rows (Example: 0/1)\n    \"\"\"\n    return delete(ScoreExpense, score_expense_id)\n\n\ndef get_score_expense_rows(page=1, per_page=10, *args, **kwargs):\n    \"\"\"\n    获取积分列表（分页）\n    Usage:\n        items: 信息列表\n        has_next: 如果本页之后还有超过一个分页，则返回True\n        has_prev: 如果本页之前还有超过一个分页，则返回True\n        next_num: 返回下一页的页码\n        prev_num: 返回上一页的页码\n        iter_pages(): 页码列表\n        iter_pages(left_edge=2, left_current=2, right_current=5, right_edge=2) 页码列表默认参数\n    :param page:\n    :param per_page:\n    :param args:\n    :param kwargs:\n    :return:\n    \"\"\"\n    rows = get_rows(ScoreExpense, page, per_page, *args, **kwargs)\n    return rows\n\n\ndef increase_score_expense(user_id, num=1):\n    \"\"\"\n    增加积分\n    :param user_id:\n    :param num:\n    :return: Decimal 0/1\n    :raise: Exception\n    \"\"\"\n    try:\n        if not isinstance(num, Decimal):\n            num = Decimal(num)\n        current_time = datetime.utcnow()\n        # 更新积分总表\n        score_obj = db.session.query(ScoreExpense).filter(ScoreExpense.user_id == user_id)\n        if score_obj.first():\n            # 总表有记录，更新\n            score_amount = ScoreExpense.amount + num\n            score_expense_data = {\n                'user_id': user_id,\n                'amount': score_amount,\n                'update_time': current_time\n            }\n            result_update = score_obj.update(score_expense_data)\n            result = score_obj.first().amount if result_update else 0\n        else:\n            # 总表无记录，插入\n            score_expense_data = {\n                'user_id': user_id,\n                'amount': num,\n                'create_time': current_time,\n                'update_time': current_time\n            }\n            score_obj = ScoreExpense(**score_expense_data)\n            db.session.add(score_obj)\n            result_add = score_obj.user_id\n            result = num if result_add else 0\n        db.session.commit()\n        return result\n    except Exception as e:\n        db.session.rollback()\n        raise e\n"
  },
  {
    "path": "app_frontend/api/score_expense_item.py",
    "content": "#!/usr/bin/env python\n# encoding: utf-8\n\n\"\"\"\n@author: zhanghe\n@software: PyCharm\n@file: score_expense_item.py\n@time: 2017/6/9 下午2:34\n\"\"\"\n\n\nfrom app_frontend.models import ScoreExpenseItem\nfrom app_frontend.tools.db import get_row, get_rows, get_row_by_id, add, edit, delete\n\n\ndef get_score_expense_item_row_by_id(score_expense_item_id):\n    \"\"\"\n    通过 id 获取积分信息\n    :param score_expense_item_id:\n    :return: None/object\n    \"\"\"\n    return get_row_by_id(ScoreExpenseItem, score_expense_item_id)\n\n\ndef get_score_expense_item_row(*args, **kwargs):\n    \"\"\"\n    获取积分信息\n    :param args:\n    :param kwargs:\n    :return: None/object\n    \"\"\"\n    return get_row(ScoreExpenseItem, *args, **kwargs)\n\n\ndef add_score_expense_item(score_expense_item_data):\n    \"\"\"\n    添加积分信息\n    :param score_expense_item_data:\n    :return: None/Value of score.id\n    \"\"\"\n    return add(ScoreExpenseItem, score_expense_item_data)\n\n\ndef edit_score_expense_item(score_expense_item_id, score_expense_item_data):\n    \"\"\"\n    修改积分信息\n    :param score_expense_item_id:\n    :param score_expense_item_data:\n    :return: Number of affected rows (Example: 0/1)\n    \"\"\"\n    return edit(ScoreExpenseItem, score_expense_item_id, score_expense_item_data)\n\n\ndef delete_score_expense_item(score_expense_item_id):\n    \"\"\"\n    删除积分信息\n    :param score_expense_item_id:\n    :return: Number of affected rows (Example: 0/1)\n    \"\"\"\n    return delete(ScoreExpenseItem, score_expense_item_id)\n\n\ndef get_score_expense_item_rows(page=1, per_page=10, *args, **kwargs):\n    \"\"\"\n    获取积分列表（分页）\n    Usage:\n        items: 信息列表\n        has_next: 如果本页之后还有超过一个分页，则返回True\n        has_prev: 如果本页之前还有超过一个分页，则返回True\n        next_num: 返回下一页的页码\n        prev_num: 返回上一页的页码\n        iter_pages(): 页码列表\n        iter_pages(left_edge=2, left_current=2, right_current=5, right_edge=2) 页码列表默认参数\n    :param page:\n    :param per_page:\n    :param args:\n    :param kwargs:\n    :return:\n    \"\"\"\n    rows = get_rows(ScoreExpenseItem, page, per_page, *args, **kwargs)\n    return rows\n"
  },
  {
    "path": "app_frontend/api/user.py",
    "content": "#!/usr/bin/env python\n# encoding: utf-8\n\n\"\"\"\n@user: zhanghe\n@software: PyCharm\n@file: user.py\n@time: 16-1-23 下午11:42\n\"\"\"\n\n\nfrom datetime import datetime\n\nfrom app_frontend.login import LoginUser\nfrom app_frontend.models import User, UserProfile, Wallet, BitCoin, Score, Bonus\nfrom app_frontend.tools.db import get_row, get_rows, get_row_by_id, add, edit, delete\nfrom app_frontend.lib.container import Container\n\nfrom app_common.maps.status_lock import *\nfrom app_frontend.database import db\n\n\ndef get_user_row_by_id(user_id):\n    \"\"\"\n    通过 id 获取用户信息\n    :param user_id:\n    :return: None/object\n    \"\"\"\n    return get_row_by_id(LoginUser, user_id)\n\n\ndef get_user_row(*args, **kwargs):\n    \"\"\"\n    获取用户信息\n    :param args:\n    :param kwargs:\n    :return: None/object\n    \"\"\"\n    return get_row(LoginUser, *args, **kwargs)\n\n\ndef add_user(user_data):\n    \"\"\"\n    添加用户信息\n    :param user_data:\n    :return: None/Value of user.id\n    \"\"\"\n    return add(LoginUser, user_data)\n\n\ndef edit_user(user_id, user_data):\n    \"\"\"\n    修改用户信息\n    :param user_id:\n    :param user_data:\n    :return: Number of affected rows (Example: 0/1)\n    \"\"\"\n    return edit(LoginUser, user_id, user_data)\n\n\ndef delete_user(user_id):\n    \"\"\"\n    删除用户信息\n    :param user_id:\n    :return: Number of affected rows (Example: 0/1)\n    \"\"\"\n    return delete(LoginUser, user_id)\n\n\ndef get_user_rows(page=1, per_page=10, *args, **kwargs):\n    \"\"\"\n    获取用户列表（分页）\n    Usage:\n        items: 信息列表\n        has_next: 如果本页之后还有超过一个分页，则返回True\n        has_prev: 如果本页之前还有超过一个分页，则返回True\n        next_num: 返回下一页的页码\n        prev_num: 返回上一页的页码\n        iter_pages(): 页码列表\n        iter_pages(left_edge=2, left_current=2, right_current=5, right_edge=2) 页码列表默认参数\n    :param page:\n    :param per_page:\n    :param args:\n    :param kwargs:\n    :return:\n    \"\"\"\n    rows = get_rows(LoginUser, page, per_page, *args, **kwargs)\n    return rows\n\n\ndef add_user_stat_item(stat_type, uid, blog_id):\n    \"\"\"\n    添加user统计明细\n    :param stat_type:\n    :param blog_id:\n    :param uid:\n    :return:\n    \"\"\"\n    blog_container_obj = Container('user')\n    return blog_container_obj.add_item(stat_type, uid, blog_id)\n\n\ndef get_user_team_rows(page=1, per_page=10, **kwargs):\n    \"\"\"\n    获取团队列表（分页）\n    :param page:\n    :param per_page:\n    :param kwargs:\n    :return:\n    \"\"\"\n    condition_user = []\n    condition_user_profile = []\n    if 'user_pid' in kwargs:\n        condition_user_profile.append(UserProfile.user_pid == kwargs['user_pid'])\n    if 'status_active' in kwargs:\n        condition_user.append(User.status_active == kwargs['status_active'])\n    if 'status_lock' in kwargs:\n        condition_user.append(User.status_lock == kwargs['status_lock'])\n    if 'status_delete' in kwargs:\n        condition_user.append(User.status_delete == kwargs['status_delete'])\n    try:\n        pagination = UserProfile.query. \\\n            filter(*condition_user_profile). \\\n            outerjoin(User, User.id == UserProfile.user_id). \\\n            filter(*condition_user). \\\n            add_entity(User). \\\n            paginate(page, per_page, False)\n        db.session.commit()\n        return pagination\n    except Exception as e:\n        db.session.rollback()\n        raise e\n\n\ndef lock(user_id):\n    \"\"\"\n    锁定用户\n    :param user_id:\n    :return: Number of affected rows (Example: 0/1)\n    \"\"\"\n    current_time = datetime.utcnow()\n    user_data = {\n        'status_lock': STATUS_LOCK_OK,\n        'lock_time': current_time,\n        'update_time': current_time\n    }\n    result = edit_user(user_id, user_data)\n    return result\n\n\ndef unlock(user_id):\n    \"\"\"\n    解锁用户\n    :param user_id:\n    :return: Number of affected rows (Example: 0/1)\n    \"\"\"\n    current_time = datetime.utcnow()\n    user_data = {\n        'status_lock': STATUS_LOCK_NO,\n        'update_time': current_time\n    }\n    result = edit_user(user_id, user_data)\n    return result\n\n\ndef is_active(user_id):\n    \"\"\"\n    是否激活\n    :param user_id:\n    :return:\n    \"\"\"\n    user_info = get_row_by_id(LoginUser, user_id)\n    return user_info.status_active if user_info else 0\n"
  },
  {
    "path": "app_frontend/api/user_auth.py",
    "content": "#!/usr/bin/env python\n# encoding: utf-8\n\n\"\"\"\n@author: zhanghe\n@software: PyCharm\n@file: user_auth.py\n@time: 16-4-28 上午1:04\n\"\"\"\n\n\nfrom app_frontend.models import UserAuth\nfrom app_frontend.tools.db import get_row, get_rows, get_row_by_id, add, edit, delete, update_rows\n\n\ndef get_user_auth_row_by_id(user_auth_id):\n    \"\"\"\n    通过 id 获取用户信息\n    :param user_auth_id:\n    :return: None/object\n    \"\"\"\n    return get_row_by_id(UserAuth, user_auth_id)\n\n\ndef get_user_auth_row(*args, **kwargs):\n    \"\"\"\n    获取用户信息\n    :param args:\n    :param kwargs:\n    :return: None/object\n    \"\"\"\n    return get_row(UserAuth, *args, **kwargs)\n\n\ndef add_user_auth(user_auth_data):\n    \"\"\"\n    添加用户信息\n    :param user_auth_data:\n    :return: None/Value of user.id\n    \"\"\"\n    return add(UserAuth, user_auth_data)\n\n\ndef edit_user_auth(user_auth_id, user_auth_data):\n    \"\"\"\n    修改用户信息\n    :param user_auth_id:\n    :param user_auth_data:\n    :return: Number of affected rows (Example: 0/1)\n    \"\"\"\n    return edit(UserAuth, user_auth_id, user_auth_data)\n\n\ndef delete_user_auth(user_auth_id):\n    \"\"\"\n    删除用户信息\n    :param user_auth_id:\n    :return: Number of affected rows (Example: 0/1)\n    \"\"\"\n    return delete(UserAuth, user_auth_id)\n\n\ndef get_user_auth_rows(page=1, per_page=10, *args, **kwargs):\n    \"\"\"\n    获取用户列表（分页）\n    Usage:\n        items: 信息列表\n        has_next: 如果本页之后还有超过一个分页，则返回True\n        has_prev: 如果本页之前还有超过一个分页，则返回True\n        next_num: 返回下一页的页码\n        prev_num: 返回上一页的页码\n        iter_pages(): 页码列表\n        iter_pages(left_edge=2, left_current=2, right_current=5, right_edge=2) 页码列表默认参数\n    :param page:\n    :param per_page:\n    :param args:\n    :param kwargs:\n    :return:\n    \"\"\"\n    rows = get_rows(UserAuth, page, per_page, *args, **kwargs)\n    return rows\n\n\ndef update_user_auth_rows(data, *args, **kwargs):\n    \"\"\"\n    批量更新用户信息\n    \"\"\"\n    return update_rows(UserAuth, data, *args, **kwargs)\n"
  },
  {
    "path": "app_frontend/api/user_bank.py",
    "content": "#!/usr/bin/env python\n# encoding: utf-8\n\n\"\"\"\n@author: zhanghe\n@software: PyCharm\n@file: user_bank.py\n@time: 2017/4/26 下午1:46\n\"\"\"\n\n\nfrom app_frontend.models import UserBank\nfrom app_frontend.tools.db import get_row, get_rows, get_row_by_id, add, edit, delete, update_rows\n\n\ndef get_user_bank_row_by_id(user_bank_id):\n    \"\"\"\n    通过 id 获取用户银行信息\n    :param user_bank_id:\n    :return: None/object\n    \"\"\"\n    return get_row_by_id(UserBank, user_bank_id)\n\n\ndef get_user_bank_row(*args, **kwargs):\n    \"\"\"\n    获取用户银行信息\n    :param args:\n    :param kwargs:\n    :return: None/object\n    \"\"\"\n    return get_row(UserBank, *args, **kwargs)\n\n\ndef add_user_bank(user_bank_data):\n    \"\"\"\n    添加用户银行信息\n    :param user_bank_data:\n    :return: None/Value of user.id\n    \"\"\"\n    return add(UserBank, user_bank_data)\n\n\ndef edit_user_bank(user_bank_id, user_bank_data):\n    \"\"\"\n    修改用户银行信息\n    :param user_bank_id:\n    :param user_bank_data:\n    :return: Number of affected rows (Example: 0/1)\n    \"\"\"\n    return edit(UserBank, user_bank_id, user_bank_data)\n\n\ndef delete_user_bank(user_bank_id):\n    \"\"\"\n    删除用户银行信息\n    :param user_bank_id:\n    :return: Number of affected rows (Example: 0/1)\n    \"\"\"\n    return delete(UserBank, user_bank_id)\n\n\ndef get_user_bank_rows(page=1, per_page=10, *args, **kwargs):\n    \"\"\"\n    获取用户银行列表（分页）\n    Usage:\n        items: 信息列表\n        has_next: 如果本页之后还有超过一个分页，则返回True\n        has_prev: 如果本页之前还有超过一个分页，则返回True\n        next_num: 返回下一页的页码\n        prev_num: 返回上一页的页码\n        iter_pages(): 页码列表\n        iter_pages(left_edge=2, left_current=2, right_current=5, right_edge=2) 页码列表默认参数\n    :param page:\n    :param per_page:\n    :param args:\n    :param kwargs:\n    :return:\n    \"\"\"\n    rows = get_rows(UserBank, page, per_page, *args, **kwargs)\n    return rows\n\n\ndef update_user_bank_rows(data, *args, **kwargs):\n    \"\"\"\n    批量更新用户银行信息\n    \"\"\"\n    return update_rows(UserBank, data, *args, **kwargs)\n\n\ndef user_bank_is_complete(user_id):\n    \"\"\"\n    用户银行信息是否完整\n    :param user_id:\n    :return:\n    \"\"\"\n    user_bank_info = get_row_by_id(UserBank, user_id)\n    if not user_bank_info:\n        return False\n    if user_bank_info.account_name \\\n            and user_bank_info.bank_name \\\n            and user_bank_info.bank_address \\\n            and user_bank_info.bank_account:\n        return True\n    return False\n"
  },
  {
    "path": "app_frontend/api/user_config.py",
    "content": "#!/usr/bin/env python\n# encoding: utf-8\n\n\"\"\"\n@author: zhanghe\n@software: PyCharm\n@file: user_config.py\n@time: 2017/6/29 上午11:41\n\"\"\"\n\n\nfrom app_frontend.models import UserConfig\nfrom app_frontend.tools.db import get_row, get_rows, get_row_by_id, add, edit, delete\n\n\ndef get_user_config_row_by_id(user_config_id):\n    \"\"\"\n    通过 id 获取用户配置信息\n    :param user_config_id:\n    :return: None/object\n    \"\"\"\n    return get_row_by_id(UserConfig, user_config_id)\n\n\ndef get_user_config_row(*args, **kwargs):\n    \"\"\"\n    获取用户配置信息\n    :param args:\n    :param kwargs:\n    :return: None/object\n    \"\"\"\n    return get_row(UserConfig, *args, **kwargs)\n\n\ndef add_user_config(user_config_data):\n    \"\"\"\n    添加用户配置信息\n    :param user_config_data:\n    :return: None/Value of wallet.id\n    \"\"\"\n    return add(UserConfig, user_config_data)\n\n\ndef edit_user_config(user_config_id, user_config_data):\n    \"\"\"\n    修改用户配置信息\n    :param user_config_id:\n    :param user_config_data:\n    :return: Number of affected rows (Example: 0/1)\n    \"\"\"\n    return edit(UserConfig, user_config_id, user_config_data)\n\n\ndef delete_user_config(user_config_id):\n    \"\"\"\n    删除用户配置信息\n    :param user_config_id:\n    :return: Number of affected rows (Example: 0/1)\n    \"\"\"\n    return delete(UserConfig, user_config_id)\n\n\ndef get_user_config_rows(page=1, per_page=10, *args, **kwargs):\n    \"\"\"\n    获取用户配置列表（分页）\n    Usage:\n        items: 信息列表\n        has_next: 如果本页之后还有超过一个分页，则返回True\n        has_prev: 如果本页之前还有超过一个分页，则返回True\n        next_num: 返回下一页的页码\n        prev_num: 返回上一页的页码\n        iter_pages(): 页码列表\n        iter_pages(left_edge=2, left_current=2, right_current=5, right_edge=2) 页码列表默认参数\n    :param page:\n    :param per_page:\n    :param args:\n    :param kwargs:\n    :return:\n    \"\"\"\n    rows = get_rows(UserConfig, page, per_page, *args, **kwargs)\n    return rows\n\n"
  },
  {
    "path": "app_frontend/api/user_profile.py",
    "content": "#!/usr/bin/env python\n# encoding: utf-8\n\n\"\"\"\n@user: zhanghe\n@software: PyCharm\n@file: user_profile.py\n@time: 16-1-23 下午11:42\n\"\"\"\n\n\nimport json\nfrom app_frontend.models import UserProfile\nfrom app_frontend.tools.db import get_row, get_rows, get_lists, get_row_by_id, add, edit, delete, count\n\nfrom app_common.tools.tree import tree\n\n\ndef get_user_profile_row_by_id(user_id):\n    \"\"\"\n    通过 id 获取用户信息\n    :param user_id:\n    :return: None/object\n    \"\"\"\n    return get_row_by_id(UserProfile, user_id)\n\n\ndef get_user_profile_row(*args, **kwargs):\n    \"\"\"\n    获取用户信息\n    :param args:\n    :param kwargs:\n    :return: None/object\n    \"\"\"\n    return get_row(UserProfile, *args, **kwargs)\n\n\ndef add_user_profile(user_data):\n    \"\"\"\n    添加用户信息\n    :param user_data:\n    :return: None/Value of user.id\n    \"\"\"\n    return add(UserProfile, user_data)\n\n\ndef edit_user_profile(user_id, user_data):\n    \"\"\"\n    修改用户信息\n    :param user_id:\n    :param user_data:\n    :return: Number of affected rows (Example: 0/1)\n    \"\"\"\n    return edit(UserProfile, user_id, user_data)\n\n\ndef delete_user_profile(user_id):\n    \"\"\"\n    删除用户信息\n    :param user_id:\n    :return: Number of affected rows (Example: 0/1)\n    \"\"\"\n    return delete(UserProfile, user_id)\n\n\ndef get_user_profile_rows(page=1, per_page=10, *args, **kwargs):\n    \"\"\"\n    获取用户列表（分页）\n    Usage:\n        items: 信息列表\n        has_next: 如果本页之后还有超过一个分页，则返回True\n        has_prev: 如果本页之前还有超过一个分页，则返回True\n        next_num: 返回下一页的页码\n        prev_num: 返回上一页的页码\n        iter_pages(): 页码列表\n        iter_pages(left_edge=2, left_current=2, right_current=5, right_edge=2) 页码列表默认参数\n    :param page:\n    :param per_page:\n    :param args:\n    :param kwargs:\n    :return:\n    \"\"\"\n    rows = get_rows(UserProfile, page, per_page, *args, **kwargs)\n    return rows\n\n\ndef user_profile_is_complete(user_id):\n    \"\"\"\n    用户基本信息是否完整\n    :param user_id:\n    :return:\n    \"\"\"\n    user_profile_info = get_row_by_id(UserProfile, user_id)\n    if not user_profile_info:\n        return False\n    if user_profile_info.nickname and user_profile_info.phone and user_profile_info.id_card:\n        return True\n    return False\n\n\ndef get_p_uid_list(user_id):\n    \"\"\"\n    获取父级用户id列表\n    :param user_id:\n    :return:\n    \"\"\"\n    result = []\n    # 一级\n    user_profile_info = get_row_by_id(UserProfile, user_id)\n    if not (user_profile_info and user_profile_info.user_pid):\n        return result\n\n    result.append(user_profile_info.user_pid)\n    user_id = user_profile_info.user_pid\n\n    # 二级\n    user_profile_info = get_row_by_id(UserProfile, user_id)\n    if not (user_profile_info and user_profile_info.user_pid):\n        return result\n\n    result.append(user_profile_info.user_pid)\n    user_id = user_profile_info.user_pid\n\n    # 三级\n    user_profile_info = get_row_by_id(UserProfile, user_id)\n    if not (user_profile_info and user_profile_info.user_pid):\n        return result\n\n    result.append(user_profile_info.user_pid)\n    return result\n\n\ndef get_child_users(user_id):\n    \"\"\"\n    获取一级子节点所有元素\n    :param user_id:\n    :return:\n    \"\"\"\n    condition = {\n        'user_pid': user_id\n    }\n    rows = get_lists(UserProfile, **condition)\n    return [(row.user_id, row.nickname, row.type_level) for row in rows]\n\n\ndef get_child_count(user_id):\n    \"\"\"\n    获取一级子节点元素数量\n    :param user_id:\n    :return:\n    \"\"\"\n    condition = {\n        'user_pid': user_id\n    }\n    child_count = count(UserProfile, **condition)\n    return child_count\n\n\ndef get_team_tree(user_id):\n    \"\"\"\n    获取用户团队3层树形结构\n    :param user_id:\n    :return:\n    \"\"\"\n    team = tree()\n    child_users = get_child_users(user_id)\n    for user1 in child_users:\n        team[user1] = {}\n        child_users2 = get_child_users(user1[0])\n        for user2 in child_users2:\n            team[user1][user2] = {}\n            child_users3 = get_child_users(user2[0])\n            for user3 in child_users3:\n                team[user1][user2][user3] = {}\n    # print json.dumps(team, indent=4)\n    return team\n\n\ndef get_user_id_by_name(user_name):\n    \"\"\"\n    根据用户名获取id\n    :param user_name:\n    :return:\n    \"\"\"\n    user_info = get_row(UserProfile, UserProfile.nickname == user_name)\n    return user_info.user_id if user_info else 0\n"
  },
  {
    "path": "app_frontend/api/wallet.py",
    "content": "#!/usr/bin/env python\n# encoding: utf-8\n\n\"\"\"\n@author: zhanghe\n@software: PyCharm\n@file: wallet.py\n@time: 2017/4/25 下午1:29\n\"\"\"\n\n\nfrom app_frontend.models import Wallet\nfrom app_frontend.tools.db import get_row, get_rows, get_row_by_id, add, edit, delete\n\n\ndef get_wallet_row_by_id(wallet_id):\n    \"\"\"\n    通过 id 获取钱包信息\n    :param wallet_id:\n    :return: None/object\n    \"\"\"\n    return get_row_by_id(Wallet, wallet_id)\n\n\ndef get_wallet_row(*args, **kwargs):\n    \"\"\"\n    获取钱包信息\n    :param args:\n    :param kwargs:\n    :return: None/object\n    \"\"\"\n    return get_row(Wallet, *args, **kwargs)\n\n\ndef add_wallet(wallet_data):\n    \"\"\"\n    添加钱包信息\n    :param wallet_data:\n    :return: None/Value of wallet.id\n    \"\"\"\n    return add(Wallet, wallet_data)\n\n\ndef edit_wallet(wallet_id, wallet_data):\n    \"\"\"\n    修改钱包信息\n    :param wallet_id:\n    :param wallet_data:\n    :return: Number of affected rows (Example: 0/1)\n    \"\"\"\n    return edit(Wallet, wallet_id, wallet_data)\n\n\ndef delete_wallet(wallet_id):\n    \"\"\"\n    删除钱包信息\n    :param wallet_id:\n    :return: Number of affected rows (Example: 0/1)\n    \"\"\"\n    return delete(Wallet, wallet_id)\n\n\ndef get_wallet_rows(page=1, per_page=10, *args, **kwargs):\n    \"\"\"\n    获取钱包列表（分页）\n    Usage:\n        items: 信息列表\n        has_next: 如果本页之后还有超过一个分页，则返回True\n        has_prev: 如果本页之前还有超过一个分页，则返回True\n        next_num: 返回下一页的页码\n        prev_num: 返回上一页的页码\n        iter_pages(): 页码列表\n        iter_pages(left_edge=2, left_current=2, right_current=5, right_edge=2) 页码列表默认参数\n    :param page:\n    :param per_page:\n    :param args:\n    :param kwargs:\n    :return:\n    \"\"\"\n    rows = get_rows(Wallet, page, per_page, *args, **kwargs)\n    return rows\n"
  },
  {
    "path": "app_frontend/api/wallet_item.py",
    "content": "#!/usr/bin/env python\n# encoding: utf-8\n\n\"\"\"\n@author: zhanghe\n@software: PyCharm\n@file: wallet_item.py\n@time: 2017/5/13 上午9:00\n\"\"\"\n\n\nfrom app_frontend.models import WalletItem\nfrom app_frontend.tools.db import get_row, get_rows, get_row_by_id, add, edit, delete\n\n\ndef get_wallet_item_row_by_id(wallet_item_id):\n    \"\"\"\n    通过 id 获取钱包信息\n    :param wallet_item_id:\n    :return: None/object\n    \"\"\"\n    return get_row_by_id(WalletItem, wallet_item_id)\n\n\ndef get_wallet_item_row(*args, **kwargs):\n    \"\"\"\n    获取钱包信息\n    :param args:\n    :param kwargs:\n    :return: None/object\n    \"\"\"\n    return get_row(WalletItem, *args, **kwargs)\n\n\ndef add_wallet_item(wallet_item_data):\n    \"\"\"\n    添加钱包信息\n    :param wallet_item_data:\n    :return: None/Value of wallet.id\n    \"\"\"\n    return add(WalletItem, wallet_item_data)\n\n\ndef edit_wallet_item(wallet_item_id, wallet_item_data):\n    \"\"\"\n    修改钱包信息\n    :param wallet_item_id:\n    :param wallet_item_data:\n    :return: Number of affected rows (Example: 0/1)\n    \"\"\"\n    return edit(WalletItem, wallet_item_id, wallet_item_data)\n\n\ndef delete_wallet_item(wallet_item_id):\n    \"\"\"\n    删除钱包信息\n    :param wallet_item_id:\n    :return: Number of affected rows (Example: 0/1)\n    \"\"\"\n    return delete(WalletItem, wallet_item_id)\n\n\ndef get_wallet_item_rows(page=1, per_page=10, *args, **kwargs):\n    \"\"\"\n    获取钱包列表（分页）\n    Usage:\n        items: 信息列表\n        has_next: 如果本页之后还有超过一个分页，则返回True\n        has_prev: 如果本页之前还有超过一个分页，则返回True\n        next_num: 返回下一页的页码\n        prev_num: 返回上一页的页码\n        iter_pages(): 页码列表\n        iter_pages(left_edge=2, left_current=2, right_current=5, right_edge=2) 页码列表默认参数\n    :param page:\n    :param per_page:\n    :param args:\n    :param kwargs:\n    :return:\n    \"\"\"\n    rows = get_rows(WalletItem, page, per_page, *args, **kwargs)\n    return rows\n"
  },
  {
    "path": "app_frontend/celery_worker.py",
    "content": "#!/usr/bin/env python\n# encoding: utf-8\n\n\"\"\"\n@author: zhanghe\n@software: PyCharm\n@file: celery_worker.py\n@time: 2016/11/17 下午2:51\n\"\"\"\n\nfrom app_frontend import app\nfrom celery import Celery\n\n\ndef make_celery(application):\n    celery = Celery(application.import_name,\n                    broker=application.config['CELERY_BROKER_URL'],\n                    backend=application.config['CELERY_RESULT_BACKEND']\n                    )\n    # celery.conf.update(application.config)\n    TaskBase = celery.Task\n\n    class ContextTask(TaskBase):\n        abstract = True\n\n        def __call__(self, *args, **kwargs):\n            with application.app_context():\n                return TaskBase.__call__(self, *args, **kwargs)\n\n    celery.Task = ContextTask\n    return celery\n\n\ncelery_app = make_celery(app)\n"
  },
  {
    "path": "app_frontend/database.py",
    "content": "#!/usr/bin/env python\n# encoding: utf-8\n\n\"\"\"\n@author: zhanghe\n@software: PyCharm\n@file: database.py\n@time: 16-1-16 下午11:44\n\"\"\"\n\n\nfrom flask_sqlalchemy import SQLAlchemy\nfrom app_frontend import app\ndb = SQLAlchemy(app)\n"
  },
  {
    "path": "app_frontend/emails.py",
    "content": "#!/usr/bin/env python\n# encoding: utf-8\n\n\"\"\"\n@author: zhanghe\n@software: PyCharm\n@file: emails.py\n@time: 16-3-11 下午2:35\n\"\"\"\n\n\nfrom app_frontend import app\nfrom flask_mail import Mail, Message\nmail = Mail(app)\n\n\ndef send_email(subject, sender, recipients, text_body=None, html_body=None):\n    \"\"\"\n    发送邮件\n    :param subject:\n    :param sender:\n    :param recipients:\n    :param text_body:\n    :param html_body:\n    :return:\n    \"\"\"\n    msg = Message(subject, sender=sender, recipients=recipients)\n    msg.body = text_body\n    msg.html = html_body\n    mail.send(msg)\n\n\n# 邮件服务调试\n# 用 python 快速开启一个 SMTP 服务\n\"\"\"\n$ python -m smtpd -n -c DebuggingServer localhost:1025\n假如想让程序运行于标准的 25 的端口上的话，必须使用 sudo 命令，因为只有 root 才能在 1-1024 端口上开启服务\n$ sudo python -m smtpd -n -c DebuggingServer localhost:25\n\"\"\"\n"
  },
  {
    "path": "app_frontend/filters.py",
    "content": "#!/usr/bin/env python\n# encoding: utf-8\n\n\"\"\"\n@author: zhanghe\n@software: PyCharm\n@file: filters.py\n@time: 2017/4/13 下午2:33\n@desc: 自定义过滤器\n\"\"\"\n\n\nfrom itsdangerous import URLSafeSerializer\nfrom datetime import timedelta\n\nfrom app_common.maps.status_active import STATUS_ACTIVE_DICT\nfrom app_common.maps.status_lock import STATUS_LOCK_DICT\nfrom app_common.maps.type_order import TYPE_ORDER_DICT\nfrom app_common.maps.type_scheduling import TYPE_SCHEDULING_DICT\nfrom app_common.tools.tree import tree\nfrom app_frontend import app\nfrom app_frontend.api.user_profile import get_user_profile_row_by_id, get_child_users\nfrom app_frontend.api.wallet import get_wallet_row_by_id\nfrom app_frontend.api.bit_coin import get_bit_coin_row_by_id\nfrom app_frontend.api.score import get_score_row_by_id\nfrom app_frontend.api.score_charity import get_score_charity_row_by_id\nfrom app_frontend.api.score_digital import get_score_digital_row_by_id\nfrom app_frontend.api.score_expense import get_score_expense_row_by_id\nfrom app_frontend.api.bonus import get_bonus_row_by_id\nfrom app_frontend.api.active import get_active_row_by_id\nfrom app_frontend.api.scheduling import get_scheduling_row_by_id\nfrom app_common.maps.type_level import TYPE_LEVEL_DICT\nfrom app_common.maps.type_apply import TYPE_APPLY_DICT\nfrom app_common.maps.type_auth import TYPE_AUTH_DICT\nfrom app_common.maps.type_active import TYPE_ACTIVE_DICT\nfrom app_common.maps.type_score import TYPE_SCORE_DICT\nfrom app_common.maps.type_payment import TYPE_PAYMENT_DICT\nfrom app_common.maps.status_audit import STATUS_AUDIT_DICT\nfrom app_common.maps.status_apply import STATUS_APPLY_DICT\nfrom app_common.maps.status_order import STATUS_ORDER_DICT\nfrom app_common.maps.status_delete import STATUS_DEL_DICT\nfrom app_common.maps.status_pay import STATUS_PAY_DICT\nfrom app_common.maps.status_rec import STATUS_REC_DICT\nimport time\n\n\n@app.template_filter('project_name')\ndef project_name_filter(s):\n    \"\"\"\n    显示项目名称\n    :param s:\n    :return:\n    \"\"\"\n    return app.config.get('PROJECT_NAME', s)\n\n\n@app.template_filter('icp_code')\ndef icp_code_filter(s):\n    \"\"\"\n    显示ICP备案号\n    :param s:\n    :return:\n    \"\"\"\n    return app.config.get('ICP_CODE', s)\n\n\n@app.template_filter('reverse')\ndef reverse_filter(s):\n    return s[::-1]\n\n\n@app.template_filter('url_t')\ndef url_t_filter(s):\n    return '%s?t=%s' % (s, time.time())\n\n\n@app.template_filter('time_diff_pretty')\ndef time_diff_pretty_filter(delta_s):\n    \"\"\"\n    时间差友好显示\n    {{ 1234 | time_diff_pretty }} >> 2分34秒\n    :param delta_s:\n    :return:\n    \"\"\"\n    delta_s *= 1.00\n    result = u''\n    if delta_s >= (365 * 24 * 60 * 60):\n        count = int(delta_s / (365 * 24 * 60 * 60))\n        result += u'%s年' % count\n        delta_s -= count * 365 * 24 * 60 * 60\n    if delta_s >= (30 * 24 * 60 * 60):\n        count = int(delta_s / (30 * 24 * 60 * 60))\n        result += u'%s月' % count\n        delta_s -= count * 30 * 24 * 60 * 60\n    if delta_s >= (24 * 60 * 60):\n        count = int(delta_s / (24 * 60 * 60))\n        result += u'%s天' % count\n        delta_s -= count * 24 * 60 * 60\n    if delta_s >= (60 * 60):\n        count = int(delta_s / (60 * 60))\n        result += u'%s小时' % count\n        delta_s -= count * 60 * 60\n    if delta_s >= 60:\n        count = int(delta_s / 60)\n        result += u'%s分' % count\n        delta_s -= count * 60\n    if delta_s > 0:\n        count = int(delta_s)\n        result += u'%s秒' % count\n    return result\n\n\n@app.template_filter('time_delta')\ndef filter_time_delta(last_time, delta=0):\n    \"\"\"\n    获取偏移后的时间\n    :param last_time:\n    :param delta:\n    :return:\n    \"\"\"\n    current_time = last_time + timedelta(seconds=delta)\n    return current_time\n\n\n@app.template_filter('user_name_level')\ndef filter_user_name_level(user_id):\n    \"\"\"\n    用户中心显示用户名和等级\n    :param user_id:\n    :return:\n    \"\"\"\n    row = get_user_profile_row_by_id(user_id)\n    return u'%s(%s)' % (row.nickname, TYPE_LEVEL_DICT.get(row.type_level, u'普通')) if row else u'游客'\n\n\n@app.template_filter('nickname')\ndef filter_nickname(user_id):\n    \"\"\"\n    显示用户名称\n    :param user_id:\n    :return:\n    \"\"\"\n    user_info = get_user_profile_row_by_id(user_id)\n    return user_info.nickname if user_info else u'系统用户'\n\n\n@app.template_filter('user_wallet')\ndef filter_user_wallet(user_id):\n    \"\"\"\n    用户钱包余额\n    :param user_id:\n    :return:\n    \"\"\"\n    row = get_wallet_row_by_id(user_id)\n    return row.amount_current if row else 0\n\n\n@app.template_filter('user_bit_coin')\ndef filter_user_bit_coin(user_id):\n    \"\"\"\n    用户数字货币\n    :param user_id:\n    :return:\n    \"\"\"\n    row = get_bit_coin_row_by_id(user_id)\n    return row.amount if row else 0\n\n\n@app.template_filter('user_score')\ndef filter_user_score(user_id):\n    \"\"\"\n    用户积分余额\n    :param user_id:\n    :return:\n    \"\"\"\n    row = get_score_row_by_id(user_id)\n    return row.amount if row else 0\n\n\n@app.template_filter('user_bonus')\ndef filter_user_bonus(user_id):\n    \"\"\"\n    用户奖金余额\n    :param user_id:\n    :return:\n    \"\"\"\n    row = get_bonus_row_by_id(user_id)\n    return row.amount if row else 0\n\n\n@app.template_filter('user_active')\ndef filter_user_active(user_id):\n    \"\"\"\n    用户激活码量\n    :param user_id:\n    :return:\n    \"\"\"\n    if not user_id:\n        return 0\n    row = get_active_row_by_id(user_id)\n    return row.amount if row else 0\n\n\n@app.template_filter('user_invite_link')\ndef filter_user_invite_link(user_id):\n    \"\"\"\n    用户邀请链接参数\n    :param user_id:\n    :return:\n    \"\"\"\n    s = URLSafeSerializer(app.config.get('USER_INVITE_LINK_SIGN_KEY', ''))\n    link_param = s.dumps({'user_id': user_id})\n    return link_param\n\n\n@app.template_filter('type_level')\ndef filter_type_level(type_level_id):\n    \"\"\"\n    用户等级\n    :param type_level_id:\n    :return:\n    \"\"\"\n    return TYPE_LEVEL_DICT.get(type_level_id, u'')\n\n\n@app.template_filter('type_apply')\ndef filter_type_apply(type_apply_id):\n    \"\"\"\n    申请类型\n    :param type_apply_id:\n    :return:\n    \"\"\"\n    return TYPE_APPLY_DICT.get(type_apply_id, u'')\n\n\n@app.template_filter('type_order')\ndef filter_type_order(type_order_id):\n    \"\"\"\n    订单类型\n    :param type_order_id:\n    :return:\n    \"\"\"\n    return TYPE_ORDER_DICT.get(type_order_id, u'')\n\n\n@app.template_filter('type_auth')\ndef filter_type_auth(type_auth_id):\n    \"\"\"\n    认证类型\n    :param type_auth_id:\n    :return:\n    \"\"\"\n    return TYPE_AUTH_DICT.get(type_auth_id, u'')\n\n\n@app.template_filter('type_active')\ndef filter_type_active(type_active_id):\n    \"\"\"\n    激活类型\n    :param type_active_id:\n    :return:\n    \"\"\"\n    return TYPE_ACTIVE_DICT.get(type_active_id, u'')\n\n\n@app.template_filter('type_score')\ndef filter_type_score(type_score_id):\n    \"\"\"\n    积分类型\n    :param type_score_id:\n    :return:\n    \"\"\"\n    return TYPE_SCORE_DICT.get(type_score_id, u'')\n\n\n@app.template_filter('type_payment')\ndef filter_type_payment(type_payment_id):\n    \"\"\"\n    收支类型\n    :param type_payment_id:\n    :return:\n    \"\"\"\n    return TYPE_PAYMENT_DICT.get(type_payment_id, u'')\n\n\n@app.template_filter('type_scheduling')\ndef filter_type_scheduling(type_scheduling_id):\n    \"\"\"\n    排单类型\n    :param type_scheduling_id:\n    :return:\n    \"\"\"\n    return TYPE_SCHEDULING_DICT.get(type_scheduling_id, u'')\n\n\n@app.template_filter('status_apply')\ndef filter_status_apply(status_apply_id):\n    \"\"\"\n    申请状态\n    :param status_apply_id:\n    :return:\n    \"\"\"\n    return STATUS_APPLY_DICT.get(status_apply_id, u'')\n\n\n@app.template_filter('status_audit')\ndef filter_status_audit(status_audit_id):\n    \"\"\"\n    审核状态\n    :param status_audit_id:\n    :return:\n    \"\"\"\n    return STATUS_AUDIT_DICT.get(status_audit_id, u'')\n\n\n@app.template_filter('status_order')\ndef filter_status_order(status_order_id):\n    \"\"\"\n    订单状态\n    :param status_order_id:\n    :return:\n    \"\"\"\n    return STATUS_ORDER_DICT.get(status_order_id, u'')\n\n\n@app.template_filter('status_delete')\ndef filter_status_delete(status_delete_id):\n    \"\"\"\n    删除状态\n    :param status_delete_id:\n    :return:\n    \"\"\"\n    return STATUS_DEL_DICT.get(status_delete_id, u'')\n\n\n@app.template_filter('status_pay')\ndef filter_status_pay(status_pay_id):\n    \"\"\"\n    支付状态\n    :param status_pay_id:\n    :return:\n    \"\"\"\n    return STATUS_PAY_DICT.get(status_pay_id, u'')\n\n\n@app.template_filter('status_rec')\ndef filter_status_rec(status_rec_id):\n    \"\"\"\n    收款状态\n    :param status_rec_id:\n    :return:\n    \"\"\"\n    return STATUS_REC_DICT.get(status_rec_id, u'')\n\n\n@app.template_filter('status_active')\ndef filter_status_active(status_active_id):\n    \"\"\"\n    激活状态\n    :param status_active_id:\n    :return:\n    \"\"\"\n    return STATUS_ACTIVE_DICT.get(status_active_id, u'')\n\n\n@app.template_filter('status_lock')\ndef filter_status_lock(status_lock_id):\n    \"\"\"\n    锁定状态\n    :param status_lock_id:\n    :return:\n    \"\"\"\n    return STATUS_LOCK_DICT.get(status_lock_id, u'')\n\n\n@app.template_filter('score_charity')\ndef filter_score_charity(user_id):\n    \"\"\"\n    慈善积分\n    :param user_id:\n    :return:\n    \"\"\"\n    row = get_score_charity_row_by_id(user_id)\n    return row.amount if row else 0\n\n\n@app.template_filter('score_digital')\ndef filter_score_digital(user_id):\n    \"\"\"\n    数字积分\n    :param user_id:\n    :return:\n    \"\"\"\n    row = get_score_digital_row_by_id(user_id)\n    return row.amount if row else 0\n\n\n@app.template_filter('score_expense')\ndef filter_score_expense(user_id):\n    \"\"\"\n    消费积分\n    :param user_id:\n    :return:\n    \"\"\"\n    row = get_score_expense_row_by_id(user_id)\n    return row.amount if row else 0\n\n\n@app.template_filter('scheduling_amount')\ndef filter_scheduling_amount(user_id):\n    \"\"\"\n    排单剩余次数\n    :param user_id:\n    :return:\n    \"\"\"\n    row = get_scheduling_row_by_id(user_id)\n    return row.amount if row else 0\n\n\n@app.template_filter('team_tree')\ndef filter_team_tree(user_id):\n    \"\"\"\n    获取用户团队3层树形结构\n    :param user_id:\n    :return:\n    \"\"\"\n    team = tree()\n    child_users = get_child_users(user_id)\n    for user1 in child_users:\n        team[user1] = {}\n        child_users2 = get_child_users(user1[0])\n        for user2 in child_users2:\n            team[user1][user2] = {}\n            child_users3 = get_child_users(user2[0])\n            for user3 in child_users3:\n                team[user1][user2][user3] = {}\n    # print json.dumps(team, indent=4)\n    return team\n"
  },
  {
    "path": "app_frontend/forms/__init__.py",
    "content": "#!/usr/bin/env python\n# encoding: utf-8\n\n\"\"\"\n@author: zhanghe\n@software: PyCharm\n@file: __init__.py.py\n@time: 2017/3/10 下午10:48\n\"\"\"\n\nfrom wtforms import SelectField, BooleanField, RadioField\nfrom wtforms.widgets import HTMLString\nfrom wtforms.compat import text_type, iteritems\nfrom wtforms.widgets import html_params\n\n\ndef select_multi_checkbox(field, ul_class='', **kwargs):\n    \"\"\"\n    多选框控件\n    :param field:\n    :param ul_class:\n    :param kwargs:\n    :return:\n    \"\"\"\n    kwargs.setdefault('type', 'checkbox')\n    field_id = kwargs.pop('id', field.id)\n    html = [u'<ul %s>' % html_params(id=field_id, class_=ul_class)]\n    for value, label, checked in field.iter_choices():\n        choice_id = u'%s-%s' % (field_id, value)\n        options = dict(kwargs, name=field.name, value=value, id=choice_id)\n        if checked:\n            options['checked'] = 'checked'\n        html.append(u'<li><input %s /> ' % html_params(**options))\n        html.append(u'<label for=\"%s\">%s</label></li>' % (field_id, label))\n    html.append(u'</ul>')\n    return u''.join(html)\n\n\nclass SelectBSWidget(object):\n    \"\"\"\n    自定义选择组件\n    \"\"\"\n    def __call__(self, field, **kwargs):\n        params = {\n            'id': field.id,\n            'name': field.id,\n            'class': 'selectpicker show-tick',\n            # 'data-live-search': 'true',\n            'title': kwargs.pop('placeholder', 'Choose one of the following...'),\n            'data-header': kwargs.pop('data_header', 'Select a condiment'),\n            'data-width': kwargs.pop('data_width', 'auto')\n        }\n        html = ['<select %s>' % html_params(**params)]\n        for k, v in field.choices:\n            html.append('<option value=\"%s\" data-subtext=\"[%s]\">%s</option>' % (k, k, v))\n        html.append('</select>')\n        return HTMLString('\\n'.join(html))\n\n\nclass SelectBS(SelectField):\n    \"\"\"\n    自定义选择表单控件\n    \"\"\"\n    widget = SelectBSWidget()\n\n    def pre_validate(self, form):\n        \"\"\"\n        校验表单传值是否合法\n        \"\"\"\n        for v, _ in self.choices:\n            # print self.data, v, type(self.data), type(v)\n            if str(self.data) == str(v):\n                break\n        else:\n            raise ValueError(self.gettext('Not a valid choice'))\n\n\nclass CheckBoxBSWidget(object):\n    \"\"\"\n    自定义复选框组件\n    \"\"\"\n    input_type = 'checkbox'\n\n    def __call__(self, field, **kwargs):\n        if getattr(field, 'checked', field.data):\n            kwargs['checked'] = True\n        kwargs.setdefault('id', field.id)\n        kwargs.setdefault('type', self.input_type)\n        if 'value' not in kwargs:\n            kwargs['value'] = 1\n        html = [\n            '<div class=\"checkbox\">',\n            '<label>',\n            '<input %s>' % html_params(name=field.name, **kwargs),\n            '</label>',\n            '</div>'\n        ]\n        return HTMLString('\\n'.join(html))\n\n\nclass CheckBoxBS(BooleanField):\n    \"\"\"\n    自定义复选框控件\n    \"\"\"\n    widget = CheckBoxBSWidget()\n\n\nclass SelectAreaCodeWidget(object):\n    \"\"\"\n    自定义选择组件 - 区号\n    \"\"\"\n    def __call__(self, field, **kwargs):\n        params = {\n            'id': field.id,\n            'name': field.id,\n            'class': 'selectpicker show-tick',\n            'data-live-search': 'true',\n            'title': kwargs.pop('title', 'Choose one of the following...'),\n            'data-header': kwargs.pop('data_header', 'Select a condiment'),\n        }\n        html = ['<select %s>' % html_params(**params)]\n        for _, area_data in field.choices:\n            for area_name, area_list in area_data.items():\n                html.append('\\t<optgroup label=\"%s\">' % area_name)\n                for country_data in area_list:\n                    # html.append('\\t\\t<option value=\"%s\" data-subtext=\"%s(%s)\">[%s] %s</option>' % (country_data['id'], country_data['name_c'], country_data['name_e'], country_data['short_code'], country_data['phone_pre']))\n                    html.append('\\t\\t<option value=\"%s\" data-subtext=\"%s\">[%s] %s</option>' % (country_data['id'], country_data['name_c'], country_data['short_code'], country_data['phone_pre']))\n                html.append('\\t</optgroup>')\n        html.append('</select>')\n        return HTMLString('\\n'.join(html))\n\n\nclass SelectAreaCode(SelectField):\n    \"\"\"\n    自定义选择表单控件\n    \"\"\"\n    widget = SelectAreaCodeWidget()\n\n    def pre_validate(self, form):\n        \"\"\"\n        校验表单传值是否合法\n        \"\"\"\n        is_find = False\n        for _, area_data in self.choices:\n            for area_list in area_data.values():\n                if self.data in [str(i['id']) for i in area_list]:\n                    is_find = True\n                    break\n            if is_find:\n                break\n        else:\n            raise ValueError(self.gettext('Not a valid choice'))\n\n\nclass RadioInlineWidget(object):\n    \"\"\"\n    自定义内联单选框组件\n    \"\"\"\n    input_type = 'radio'\n\n    def __call__(self, field, **kwargs):\n\n        html = []\n        default = kwargs.pop('default', None)\n        for k, v in field.choices:\n            params = {\n                'type': self.input_type,\n                'id': '%s_%s' % (field.id, k),\n                'name': field.id,\n                'value': k,\n            }\n            if default == k:\n                params['checked'] = True\n\n            html.append('<label class=\"radio-inline\">')\n            html.append('<input %s> %s' % (html_params(**params), v))\n            html.append('</label>')\n        return HTMLString('\\n'.join(html))\n\n\nclass RadioInlineBS(RadioField):\n    \"\"\"\n    自定义内联单选框控件\n    \"\"\"\n\n    widget = RadioInlineWidget()\n\n    def pre_validate(self, form):\n        \"\"\"\n        校验表单传值是否合法\n        \"\"\"\n        if self.data not in [str(i) for i in dict(self.choices).keys()]:\n            # raise ValueError(self.gettext('Not a valid choice'))\n            raise ValueError(u'选择不能为空')\n"
  },
  {
    "path": "app_frontend/forms/active.py",
    "content": "#!/usr/bin/env python\n# encoding: utf-8\n\n\"\"\"\n@author: zhanghe\n@software: PyCharm\n@file: active.py\n@time: 2017/6/1 下午2:42\n\"\"\"\n\n\nfrom flask_login import current_user\nfrom flask_wtf import FlaskForm\nfrom wtforms import StringField, PasswordField, BooleanField, DateField, DateTimeField, DecimalField, IntegerField\nfrom wtforms.validators import DataRequired, Length, NumberRange, EqualTo, Email, ValidationError, IPAddress\n\nfrom app_common.maps.status_delete import *\nfrom app_common.maps.type_auth import *\nfrom app_frontend.api.user import get_user_row_by_id\nfrom app_frontend.api.user_auth import get_user_auth_row\nfrom app_frontend.api.user_profile import get_user_profile_row\n\n\nclass UserRightValidate(object):\n    \"\"\"\n    用户权限校验\n    \"\"\"\n    def __init__(self, message=None):\n        self.message = message\n\n    def __call__(self, form, field):\n        # 用户异常处理\n        user_profile_info = get_user_profile_row(**{'nickname': field.data})\n        if not user_profile_info:\n            raise ValidationError(u'异常操作，此用户不存在')\n        if user_profile_info.user_pid != current_user.id:\n            raise ValidationError(u'异常操作，无此用户权限')\n\n        user_info = get_user_row_by_id(user_profile_info.user_id)\n\n        if not user_info:\n            raise ValidationError(u'异常操作，此用户不存在')\n        if user_info.status_delete == int(STATUS_DEL_OK):\n            raise ValidationError(u'异常操作，此用户已删除')\n\n\nclass ActiveAddForm(FlaskForm):\n    \"\"\"\n    激活添加表单\n    \"\"\"\n    user_name = StringField(u'赠送用户', validators=[\n        DataRequired(message=u'赠送用户不能为空'),\n        UserRightValidate()\n    ])\n    amount = IntegerField(u'赠送数量', validators=[\n        DataRequired(message=u'赠送数量必须为整数'),\n        NumberRange(min=1, message=u'赠送数量必须为整数')\n    ])\n\n\n"
  },
  {
    "path": "app_frontend/forms/apply_get.py",
    "content": "#!/usr/bin/env python\n# encoding: utf-8\n\n\"\"\"\n@author: zhanghe\n@software: PyCharm\n@file: apply_get.py\n@time: 2017/4/13 下午9:31\n\"\"\"\n\n\nfrom datetime import datetime\n\nfrom decimal import Decimal\nfrom flask_login import current_user\nfrom flask_wtf import FlaskForm\nfrom wtforms import StringField, PasswordField, BooleanField, DateField, DateTimeField, DecimalField, IntegerField\nfrom wtforms.validators import DataRequired, Length, NumberRange, EqualTo, Email, ValidationError, IPAddress\n\nfrom app_frontend import app\nfrom app_frontend.api.apply_get import get_current_month_get_amount, get_current_day_get_amount, \\\n    get_get_processing_amount, get_get_processing_count\nfrom app_frontend.api.user_auth import get_user_auth_row\nfrom app_frontend.api.wallet import get_wallet_row_by_id\nfrom app_frontend.api.bit_coin import get_bit_coin_row_by_id\nfrom app_frontend.forms import SelectBS, RadioInlineBS\nfrom app_common.maps import type_apply_list, type_pay_list, type_withdraw_list\nfrom app_common.maps.type_withdraw import *\nfrom app_frontend.tools.config_manage import get_conf\n\n\nclass ApplyGetMoneyValidate(object):\n    \"\"\"\n    提现申请金额校验\n    \"\"\"\n    def __init__(self, message=None):\n        self.message = message\n\n    def __call__(self, form, field):\n        # 提现时间配置\n        APPLY_GET_TIME_START = get_conf('APPLY_GET_TIME_START')  # 每天提现申请开始时间\n        APPLY_GET_TIME_END = get_conf('APPLY_GET_TIME_END')  # 每天提现申请结束时间\n        current_time = datetime.now().strftime('%H:%M:%S')\n        if current_time < APPLY_GET_TIME_START or current_time > APPLY_GET_TIME_END:\n            raise ValidationError(u'为了您的资金安全，请在%s~%s时间段提现' % (APPLY_GET_TIME_START, APPLY_GET_TIME_END))\n\n        # # 当天次数限制（一天只能提现一次）\n        # if not app.config.get('TEST') and get_current_day_get_amount(user_id=current_user.id) > 0:\n        #     raise ValidationError(u'超出当天提现次数限制')\n\n        # 单次提现金额范围\n        APPLY_GET_MIN_EACH = Decimal(get_conf('APPLY_GET_MIN_EACH'))  # 最小值\n        APPLY_GET_MAX_EACH = Decimal(get_conf('APPLY_GET_MAX_EACH'))  # 最大值\n        APPLY_GET_STEP = Decimal(get_conf('APPLY_GET_STEP'))  # 提现金额步长（基数）\n\n        if field.data < APPLY_GET_MIN_EACH:\n            raise ValidationError(u'提现金额最小为%s' % APPLY_GET_MIN_EACH)\n        if field.data > APPLY_GET_MAX_EACH:\n            raise ValidationError(u'提现金额最大为%s' % APPLY_GET_MAX_EACH)\n        if (field.data / APPLY_GET_STEP) * APPLY_GET_STEP != field.data:\n            raise ValidationError(u'金额必须为%s的倍数' % APPLY_GET_STEP)\n\n        # 单个用户提现限制\n        # 金额限制\n        get_processing_amount = get_get_processing_amount(user_id=current_user.id)\n        # 单个用户提现最大交易中金额\n        APPLY_GET_USER_MAX_AMOUNT = Decimal(get_conf('APPLY_GET_USER_MAX_AMOUNT'))\n        if field.data + get_processing_amount >= APPLY_GET_USER_MAX_AMOUNT:\n            raise ValidationError(u'超出提现处理中金额限制')\n\n        # 单数限制（处理中的申请单数）\n        # 单个用户提现最大交易中单数(0 表示不限制)\n        APPLY_GET_USER_MAX_COUNT = Decimal(get_conf('APPLY_GET_USER_MAX_COUNT'))\n        if APPLY_GET_USER_MAX_COUNT > 0:\n            get_processing_count = get_get_processing_count(user_id=current_user.id)\n            if get_processing_count >= APPLY_GET_USER_MAX_COUNT:\n                raise ValidationError(u'超出提现处理中数量限制')\n\n        # 每日提现限制\n        current_day_get_amount = get_current_day_get_amount()\n        if current_day_get_amount > Decimal(get_conf('APPLY_GET_MAX_AMOUNT_DAILY')):\n            raise ValidationError(u'超出当天提现最大金额限制')\n\n        # 每月提现限制\n        current_month_get_amount = get_current_month_get_amount()\n        if current_month_get_amount > Decimal(get_conf('APPLY_GET_MAX_AMOUNT_MONTHLY')):\n            raise ValidationError(u'超出当月提现最大金额限制')\n        \n        # 钱包余额不够\n        if form.type_withdraw.data == TYPE_WITHDRAW_WALLET:\n            wallet_info = get_wallet_row_by_id(current_user.id)\n            if not wallet_info or wallet_info.amount_current < field.data:\n                raise ValidationError(u'钱包余额不够')\n        # 数字货币余额不够\n        if form.type_withdraw.data == TYPE_WITHDRAW_BIT_COIN:\n            bit_coin_info = get_bit_coin_row_by_id(current_user.id)\n            if not bit_coin_info or bit_coin_info.amount < field.data:\n                raise ValidationError(u'数字货币余额不够')\n\n\nclass ApplyGetAddForm(FlaskForm):\n    \"\"\"\n    提现申请添加表单\n    \"\"\"\n    # type_pay_list.pop(0)\n    type_pay = RadioInlineBS(u'收款方式',\n                             choices=type_pay_list,\n                             validators=[DataRequired(message=u'收款方式不能为空')]\n                             )\n\n    type_withdraw_list.pop(0)\n    type_withdraw = RadioInlineBS(u'提现类型',\n                                  choices=type_withdraw_list,\n                                  validators=[DataRequired(message=u'提现类型不能为空')]\n                                  )\n    money_apply = IntegerField(u'申请金额', validators=[\n        DataRequired(message=u'金额必须为整数'),\n        NumberRange(min=100, message=u'金额必须为100的倍数'),\n        ApplyGetMoneyValidate()\n    ])\n\n\nclass ApplyGetEditForm(FlaskForm):\n    \"\"\"\n    提现申请编辑表单\n    \"\"\"\n    apply_put_id = StringField('Apply Put Id')\n    money_apply = StringField('Money Apply')\n    status_apply = StringField('Status Apply')\n    status_order = StringField('Status Order')\n    status_delete = StringField('Status Delete')\n    create_time = DateTimeField('Create Time')\n    update_time = DateTimeField('Update Time')\n"
  },
  {
    "path": "app_frontend/forms/apply_put.py",
    "content": "#!/usr/bin/env python\n# encoding: utf-8\n\n\"\"\"\n@author: zhanghe\n@software: PyCharm\n@file: apply_put.py\n@time: 2017/4/13 下午9:31\n\"\"\"\n\n\nfrom decimal import Decimal\nfrom flask_wtf import FlaskForm\nfrom wtforms import StringField, PasswordField, BooleanField, DateField, DateTimeField, DecimalField, IntegerField\nfrom wtforms.validators import DataRequired, Length, NumberRange, EqualTo, Email, ValidationError, IPAddress\n\nfrom flask_login import current_user\n\nfrom app_frontend import app\nfrom app_frontend.api.apply_put import get_current_day_put_amount, get_current_month_put_amount, \\\n    get_put_processing_amount, get_put_processing_count\nfrom app_frontend.api.scheduling import get_scheduling_row_by_id\nfrom app_frontend.forms import SelectBS, RadioInlineBS\nfrom app_common.maps import type_apply_list, type_pay_list\nfrom app_frontend.tools.config_manage import get_conf\nfrom datetime import datetime\n\n\nclass ApplyPutMoneyValidate(object):\n    \"\"\"\n    投资申请金额校验\n    \"\"\"\n    def __init__(self, message=None):\n        self.message = message\n\n    def __call__(self, form, field):\n        # 投资时间配置\n        APPLY_PUT_TIME_START = get_conf('APPLY_PUT_TIME_START')  # 每天投资申请开始时间\n        APPLY_PUT_TIME_END = get_conf('APPLY_PUT_TIME_END')  # 每天投资申请结束时间\n        current_time = datetime.now().strftime('%H:%M:%S')\n        if current_time < APPLY_PUT_TIME_START or current_time > APPLY_PUT_TIME_END:\n            raise ValidationError(u'为了您的资金安全，请在%s~%s时间段投资' % (APPLY_PUT_TIME_START, APPLY_PUT_TIME_END))\n\n        # # 当天次数限制（一天只能投资一次）\n        # if not app.config.get('TEST') and get_current_day_put_amount(user_id=current_user.id) > 0:\n        #     raise ValidationError(u'超出当天投资次数限制')\n\n        # 单次投资金额范围\n        APPLY_PUT_MIN_EACH = Decimal(get_conf('APPLY_PUT_MIN_EACH'))  # 最小值\n        APPLY_PUT_MAX_EACH = Decimal(get_conf('APPLY_PUT_MAX_EACH'))  # 最大值\n        APPLY_PUT_STEP = Decimal(get_conf('APPLY_PUT_STEP'))  # 投资金额步长（基数）\n\n        if field.data < APPLY_PUT_MIN_EACH:\n            raise ValidationError(u'投资金额最小为%s' % APPLY_PUT_MIN_EACH)\n        if field.data > APPLY_PUT_MAX_EACH:\n            raise ValidationError(u'投资金额最大为%s' % APPLY_PUT_MAX_EACH)\n        if (field.data/APPLY_PUT_STEP)*APPLY_PUT_STEP != field.data:\n            raise ValidationError(u'金额必须为%s的倍数' % APPLY_PUT_STEP)\n\n        # 单个用户投资限制\n        # 金额限制\n        put_processing_amount = get_put_processing_amount(user_id=current_user.id)\n        # 单个用户投资最大交易中金额\n        APPLY_PUT_USER_MAX_AMOUNT = Decimal(get_conf('APPLY_PUT_USER_MAX_AMOUNT'))\n        if field.data + put_processing_amount >= APPLY_PUT_USER_MAX_AMOUNT:\n            raise ValidationError(u'超出投资处理中金额限制')\n\n        # 单数限制（处理中的申请单数）\n        # 单个用户投资最大交易中单数(0 表示不限制)\n        APPLY_PUT_USER_MAX_COUNT = Decimal(get_conf('APPLY_PUT_USER_MAX_COUNT'))\n        if APPLY_PUT_USER_MAX_COUNT > 0:\n            put_processing_count = get_put_processing_count(user_id=current_user.id)\n            if put_processing_count >= APPLY_PUT_USER_MAX_COUNT:\n                raise ValidationError(u'超出投资处理中数量限制')\n\n        # 每日投资限制\n        current_day_put_amount = get_current_day_put_amount()\n        if current_day_put_amount > Decimal(get_conf('APPLY_PUT_MAX_AMOUNT_DAILY')):\n            raise ValidationError(u'超出当天投资最大金额限制')\n\n        # 每月投资限制\n        current_month_put_amount = get_current_month_put_amount()\n        if current_month_put_amount > Decimal(get_conf('APPLY_PUT_MAX_AMOUNT_MONTHLY')):\n            raise ValidationError(u'超出当月投资最大金额限制')\n\n        # 检查排单币是否足够\n        scheduling_row = get_scheduling_row_by_id(current_user.id)\n        if not scheduling_row or scheduling_row.amount <= 0 or scheduling_row.amount < (field.data/100):\n            raise ValidationError(u'排单币不足，请及时充值')\n\n\nclass ApplyPutAddForm(FlaskForm):\n    \"\"\"\n    投资申请添加表单\n    \"\"\"\n    type_pay_list.pop(0)\n    type_pay = RadioInlineBS(u'支付方式',\n                             choices=type_pay_list,\n                             validators=[DataRequired(message=u'支付方式不能为空')]\n                             )\n    money_apply = IntegerField(u'申请金额', validators=[\n        DataRequired(message=u'金额必须为整数'),\n        NumberRange(min=100, message=u'金额必须为100的倍数'),\n        ApplyPutMoneyValidate()\n    ])\n\n\nclass ApplyPutEditForm(FlaskForm):\n    \"\"\"\n    投资申请编辑表单\n    \"\"\"\n    apply_get_id = StringField('Apply Get Id')\n    money_apply = StringField('Money Apply')\n    status_apply = StringField('Status Apply')\n    status_order = StringField('Status Order')\n    status_delete = StringField('Status Delete')\n    create_time = DateTimeField('Create Time')\n    update_time = DateTimeField('Update Time')\n"
  },
  {
    "path": "app_frontend/forms/blog.py",
    "content": "#!/usr/bin/env python\n# encoding: utf-8\n\n\"\"\"\n@author: zhanghe\n@software: PyCharm\n@file: blog.py\n@time: 2017/3/10 下午11:00\n\"\"\"\n\n\nfrom flask_wtf import FlaskForm\nfrom wtforms import StringField, PasswordField, BooleanField, DateField, DateTimeField\nfrom wtforms.validators import DataRequired, Length, NumberRange, EqualTo, Email, ValidationError, IPAddress\n\n\nclass BlogAddForm(FlaskForm):\n    \"\"\"\n    Blog 添加表单\n    \"\"\"\n    author = StringField('Author', validators=[DataRequired()])\n    title = StringField('Title', validators=[DataRequired(), Length(max=40)])\n    pub_date = DateField('Pub Date', validators=[DataRequired()])\n\n\nclass BlogEditForm(FlaskForm):\n    \"\"\"\n    Blog 编辑表单\n    \"\"\"\n    author = StringField('Author', validators=[DataRequired()])\n    title = StringField('Title', validators=[DataRequired(), Length(max=40)])\n    pub_date = DateField('Pub Date', validators=[DataRequired()])\n"
  },
  {
    "path": "app_frontend/forms/complaint.py",
    "content": "#!/usr/bin/env python\n# encoding: utf-8\n\n\"\"\"\n@author: zhanghe\n@software: PyCharm\n@file: complaint.py\n@time: 2017/6/24 下午11:13\n\"\"\"\n\n\nfrom flask_login import current_user\nfrom flask_wtf import FlaskForm\nfrom wtforms import StringField, TextAreaField, PasswordField, BooleanField, DateField, DateTimeField, DecimalField, IntegerField, HiddenField\nfrom wtforms.validators import DataRequired, Length, NumberRange, EqualTo, Email, ValidationError, IPAddress\n\n\nclass ComplaintAddForm(FlaskForm):\n    \"\"\"\n    投诉添加表单\n    \"\"\"\n    user_id = StringField(u'被投诉用户')\n    content = TextAreaField(u'投诉内容', validators=[\n        DataRequired(message=u'投诉内容不能为空'),\n        Length(min=2, message=u'请输入有效的投诉内容'),\n        Length(max=512, message=u'投诉内容超出长度限制'),\n    ])\n"
  },
  {
    "path": "app_frontend/forms/login.py",
    "content": "#!/usr/bin/env python\n# encoding: utf-8\n\n\"\"\"\n@author: zhanghe\n@software: PyCharm\n@file: login.py\n@time: 2017/3/10 下午10:49\n\"\"\"\n\n\nfrom flask import session\nimport re\n\nfrom flask_wtf import FlaskForm\nfrom wtforms import StringField, PasswordField, BooleanField, DateField, DateTimeField\nfrom wtforms.validators import DataRequired, Length, NumberRange, EqualTo, Email, ValidationError, IPAddress\nfrom app_frontend.api.user_auth import get_user_auth_row\nfrom app_frontend.forms import SelectAreaCode\nfrom app_common.maps import area_code_list\n\n\nclass CaptchaValidate(object):\n    \"\"\"\n    图形验证码校验\n    \"\"\"\n    def __init__(self, message=None):\n        self.message = message\n\n        self._reg = re.compile(ur'^\\w{4}$')\n\n    def __call__(self, form, field):\n        data = field.data\n        if not self._reg.match(data):\n            raise ValidationError(self.message or u\"图形验证码格式错误\")\n\n        code_key = '%s:%s' % ('code_str', 'login')\n        code_str = session.get(code_key)\n        if not code_str:\n            raise ValidationError(self.message or u\"图形验证码过期失效\")\n        # print session.get(code_key), type(session.get(code_key)), data, type(data)\n        if session.get(code_key).upper() != data.upper():\n            raise ValidationError(self.message or u\"图形验证码校验错误\")\n\n\nclass LoginForm(FlaskForm):\n    \"\"\"\n    账号登录表单\n    \"\"\"\n    account = StringField(u'登录账号', validators=[\n        DataRequired(u'登录账号不能为空'),\n        Length(min=2, max=20, message=u'登录账号长度不符'),\n    ])\n    password = PasswordField(u'登录密码', validators=[\n        DataRequired(u'登录密码不能为空'),\n        Length(min=6, max=20, message=u'登录密码长度不符'),\n    ])\n    captcha = StringField(u'图形验证码', validators=[\n        DataRequired(u'图形验证码不能为空'),\n        Length(min=4, max=4, message=u'图形验证码长度不符'),\n        CaptchaValidate()\n    ])\n    remember = BooleanField(u'记住登录状态', default=False)\n\n\nclass LoginPhoneForm(FlaskForm):\n    \"\"\"\n    手机登录表单\n    \"\"\"\n    area_code_choices = []\n    for m, n in enumerate(area_code_list):\n        area_code_choices.append((m, n))\n\n    area_id = SelectAreaCode(u'手机区号', default='0', choices=area_code_choices, validators=[DataRequired()])\n    phone = StringField(u'登录手机', validators=[DataRequired(u'登录手机不能为空')])\n    password = PasswordField(u'登录密码', validators=[\n        DataRequired(u'登录密码不能为空'),\n        Length(min=6, max=20, message=u'登录密码长度不符'),\n    ])\n    remember = BooleanField(u'记住登录状态', default=False)\n\n\nclass LoginEmailForm(FlaskForm):\n    \"\"\"\n    邮箱登录表单\n    \"\"\"\n    email = StringField(u'登录邮箱', validators=[\n        DataRequired(u'登录邮箱不能为空'),\n        Email(u'登录邮箱格式不符')\n    ])\n    password = PasswordField(u'登录密码', validators=[\n        DataRequired(u'登录密码不能为空'),\n        Length(min=6, max=20, message=u'登录密码长度不符'),\n    ])\n    remember = BooleanField(u'记住登录状态', default=False)\n"
  },
  {
    "path": "app_frontend/forms/message.py",
    "content": "#!/usr/bin/env python\n# encoding: utf-8\n\n\"\"\"\n@author: zhanghe\n@software: PyCharm\n@file: message.py\n@time: 2017/6/24 下午10:45\n\"\"\"\n\n\nfrom flask_login import current_user\nfrom flask_wtf import FlaskForm\nfrom wtforms import StringField, TextAreaField, PasswordField, BooleanField, DateField, DateTimeField, DecimalField, IntegerField, HiddenField\nfrom wtforms.validators import DataRequired, Length, NumberRange, EqualTo, Email, ValidationError, IPAddress\n\n\nclass MessageAddForm(FlaskForm):\n    \"\"\"\n    留言添加表单\n    \"\"\"\n    user_id = StringField(u'留言给用户')\n    content = TextAreaField(u'留言内容', validators=[\n        DataRequired(message=u'留言内容不能为空'),\n        Length(min=2, message=u'请输入有效的留言内容'),\n        Length(max=512, message=u'留言内容超出长度限制'),\n    ])\n"
  },
  {
    "path": "app_frontend/forms/order.py",
    "content": "#!/usr/bin/env python\n# encoding: utf-8\n\n\"\"\"\n@author: zhanghe\n@software: PyCharm\n@file: order.py\n@time: 2017/4/13 下午9:32\n\"\"\"\n\n\ndef func():\n    pass\n\n\nclass Main(object):\n    def __init__(self):\n        pass\n\n\nif __name__ == '__main__':\n    pass\n"
  },
  {
    "path": "app_frontend/forms/pay.py",
    "content": "#!/usr/bin/env python\n# encoding: utf-8\n\n\"\"\"\n@author: zhanghe\n@software: PyCharm\n@file: pay.py\n@time: 2017/3/18 上午12:29\n\"\"\"\n\n\ndef func():\n    pass\n\n\nclass Main(object):\n    def __init__(self):\n        pass\n\n\nif __name__ == '__main__':\n    pass\n"
  },
  {
    "path": "app_frontend/forms/reg.py",
    "content": "#!/usr/bin/env python\n# encoding: utf-8\n\n\"\"\"\n@author: zhanghe\n@software: PyCharm\n@file: reg.py\n@time: 2017/3/10 下午10:49\n\"\"\"\n\n\nfrom flask import session\nfrom flask_wtf import FlaskForm\nfrom wtforms import StringField, PasswordField, BooleanField, DateField, DateTimeField, SelectField, HiddenField\nfrom wtforms.validators import DataRequired, Length, NumberRange, EqualTo, Email, ValidationError, IPAddress, Regexp, AnyOf\nfrom app_frontend.forms import SelectAreaCode\n\nfrom app_frontend import app\nfrom app_frontend.api.user_auth import get_user_auth_row\n\n\ntry:\n    from html import escape\nexcept ImportError:\n    from cgi import escape\nimport re\nfrom app_common.maps import area_code_list, area_code_map\n\nfrom app_common.maps.type_auth import *\n# 认证类型（0未知，1邮箱，2手机，3qq，4微信，5微博）\n\n\nclass UserNameValidate(object):\n    \"\"\"\n    用户名称校验\n    \"\"\"\n    def __init__(self, message=None):\n        self.message = message\n        self._reg = re.compile(ur'^[a-zA-Z0-9\\u4e00-\\u9fa5\\s]+$')\n\n    def __call__(self, form, field):\n        data = field.data\n        if not self._reg.match(data):\n            raise ValidationError(self.message or u\"用户名称只能包含中文和英文\")\n\n\nclass ChineseNameValidate(object):\n    \"\"\"\n    中文姓名校验\n    \"\"\"\n    def __init__(self, message=None):\n        self.message = message\n        self._reg = re.compile(ur'^[\\u4e00-\\u9fa5]+$')\n\n    def __call__(self, form, field):\n        data = field.data\n        if not self._reg.match(data):\n            raise ValidationError(self.message or u\"请输入正确的中文姓名\")\n\n\nclass CaptchaValidate(object):\n    \"\"\"\n    图形验证码校验\n    \"\"\"\n    def __init__(self, message=None):\n        self.message = message\n\n        self._reg = re.compile(ur'^\\w{4}$')\n\n    def __call__(self, form, field):\n        data = field.data\n        if not self._reg.match(data):\n            raise ValidationError(self.message or u\"图形验证码格式错误\")\n\n        code_key = '%s:%s' % ('code_str', 'reg')\n        code_str = session.get(code_key)\n        if not code_str:\n            raise ValidationError(self.message or u\"图形验证码过期失效\")\n        # print session.get(code_key), type(session.get(code_key)), data, type(data)\n        if session.get(code_key).upper() != data.upper():\n            raise ValidationError(self.message or u\"图形验证码校验错误\")\n\n\nclass SmsCodeValidate(object):\n    \"\"\"\n    短信验证码校验\n    \"\"\"\n    def __init__(self, message=None):\n        self.message = message\n\n        self._reg = re.compile(ur'^\\d{6}$')\n\n    def __call__(self, form, field):\n        data = field.data\n        if not self._reg.match(data):\n            raise ValidationError(self.message or u\"短信验证码格式错误\")\n\n        code_key = '%s:%s' % ('sms_code', 'reg')\n        # print session.get(code_key), type(session.get(code_key)), data, type(data)\n        if not app.config.get('TEST') and session.get(code_key) != data:\n            raise ValidationError(self.message or u\"短信验证码校验错误\")\n\n\nclass RegAccountRepeatValidate(object):\n    \"\"\"\n    注册账号重复校验\n    \"\"\"\n    def __init__(self, message=None):\n        self.message = message\n\n    def __call__(self, form, field):\n        condition = {\n            'type_auth': TYPE_AUTH_ACCOUNT,\n            'auth_key': field.data\n        }\n        row = get_user_auth_row(**condition)\n        if row:\n            raise ValidationError(self.message or u'注册账号重复')\n\n\nclass RegEmailRepeatValidate(object):\n    \"\"\"\n    注册邮箱重复校验\n    \"\"\"\n    def __init__(self, message=None):\n        self.message = message\n\n    def __call__(self, form, field):\n        condition = {\n            'type_auth': TYPE_AUTH_EMAIL,\n            'auth_key': field.data\n        }\n        row = get_user_auth_row(**condition)\n        if row:\n            raise ValidationError(self.message or u'注册邮箱重复')\n\n\nclass RegPhoneRepeatValidate(object):\n    \"\"\"\n    注册手机重复校验\n    \"\"\"\n    def __init__(self, message=None):\n        self.message = message\n\n    def __call__(self, form, field):\n        # 手机号码国际化\n        area_id = form['area_id'].data\n        area_code = area_code_map.get(area_id, '86')\n        mobile_iso = '%s%s' % (area_code, field.data)\n\n        condition = {\n            'type_auth': TYPE_AUTH_PHONE,\n            'auth_key': mobile_iso\n        }\n        row = get_user_auth_row(**condition)\n\n        if row:\n            raise ValidationError(self.message or u'注册手机重复')\n\n\nclass PhoneFormatValidate(object):\n    \"\"\"\n    手机号码格式校验\n    \"\"\"\n    def __init__(self, message=None):\n        self.message = message\n\n    def __call__(self, form, field):\n        phone_len = len(field.data)\n        if phone_len < 6 or phone_len > 11:\n            raise ValidationError(u'手机号码长度不符')\n        # 中国手机号码格式校验\n        if form.area_id.data == '0' and phone_len != 11:\n            raise ValidationError(u'手机号码长度不符')\n        if field.data.startswith('0'):\n            raise ValidationError(u'手机号码格式不符')\n\n\nclass RegForm(FlaskForm):\n    \"\"\"\n    注册表单\n    \"\"\"\n    user_pid = HiddenField(u'推荐人')\n    account = StringField(u'登录账号', validators=[\n        DataRequired(u'登录账号不能为空'),\n        Length(min=2, max=20, message=u'登录账号长度不符'),\n        RegAccountRepeatValidate()\n    ])\n    password = PasswordField(u'登录密码', validators=[\n        DataRequired(message=u'密码不能为空'),\n        Length(min=6, max=20, message=u'密码长度不符'),\n        EqualTo('confirm', message=u'两次输入的密码不一致')\n    ])\n    confirm = PasswordField(u'确认密码', validators=[\n        DataRequired(message=u'密码不能为空'),\n        Length(min=6, max=20, message=u'密码长度不符'),\n    ])\n    captcha = StringField(u'图形验证码', validators=[\n        DataRequired(u'图形验证码不能为空'),\n        Length(min=4, max=4, message=u'图形验证码长度不符'),\n        CaptchaValidate()\n    ])\n    accept_agreement = BooleanField('I accept the agreement', validators=[\n        DataRequired(message=u'请阅读并同意注册协议')\n    ], default=True)\n\n\nclass RegPhoneForm(FlaskForm):\n    \"\"\"\n    手机注册表单\n    \"\"\"\n    user_pid = HiddenField(u'推荐人')\n    area_code_choices = []\n    for m, n in enumerate(area_code_list):\n        area_code_choices.append((m, n))\n\n    area_id = SelectAreaCode(u'手机区号', default='0', choices=area_code_choices, validators=[DataRequired()])\n    phone = StringField(u'手机号码', validators=[\n        DataRequired(u'手机号码不能为空'),\n        RegPhoneRepeatValidate(u'手机已被注册'),\n        PhoneFormatValidate()\n    ])\n    captcha = StringField(u'图形验证码', validators=[\n        DataRequired(u'图形验证码不能为空'),\n        Length(min=4, max=4, message=u'图形验证码长度不符')\n    ])\n    sms = StringField(u'短信验证码', validators=[\n        DataRequired(u'短信验证码不能为空'),\n        Length(min=6, max=6, message=u'短信验证码长度不符'),\n        SmsCodeValidate()\n    ])\n    password = PasswordField(u'登录密码', validators=[\n        DataRequired(u'密码不能为空'),\n        Length(min=6, max=20, message=u'密码长度不符'),\n        EqualTo('confirm', message=u'两次输入的密码不一致')\n    ])\n    confirm = PasswordField(u'确认密码', validators=[\n        DataRequired(u'密码不能为空'),\n        Length(min=6, max=20, message=u'密码长度不符')\n    ])\n    accept_agreement = BooleanField(u'我已阅读并同意注册协议', validators=[DataRequired(u'请阅读并同意注册协议')], default=True)\n\n\nclass RegEmailForm(FlaskForm):\n    \"\"\"\n    邮箱注册表单\n    \"\"\"\n    user_pid = HiddenField(u'推荐人')\n    email = StringField(u'登录邮箱', validators=[\n        DataRequired(u'登录邮箱不能为空'),\n        Email(u'邮箱格式不对'),\n        RegEmailRepeatValidate(u'邮箱已被注册')\n    ])\n    password = PasswordField(u'登录密码', validators=[\n        DataRequired(u'密码不能为空'),\n        Length(min=6, max=20, message=u'密码长度不符'),\n        EqualTo('confirm', message=u'两次输入的密码不一致')\n    ])\n    confirm = PasswordField(u'确认密码', validators=[\n        DataRequired(u'密码不能为空'),\n        Length(min=6, max=20, message=u'密码长度不符')\n    ])\n    accept_agreement = BooleanField(u'我已阅读并同意注册协议', validators=[DataRequired(u'请阅读并同意注册协议')], default=True)\n"
  },
  {
    "path": "app_frontend/forms/scheduling.py",
    "content": "#!/usr/bin/env python\n# encoding: utf-8\n\n\"\"\"\n@author: zhanghe\n@software: PyCharm\n@file: scheduling.py\n@time: 2017/6/29 下午8:46\n\"\"\"\n\n\ndef func():\n    pass\n\n\nclass Main(object):\n    def __init__(self):\n        pass\n\n\nif __name__ == '__main__':\n    pass\n"
  },
  {
    "path": "app_frontend/forms/user.py",
    "content": "#!/usr/bin/env python\n# encoding: utf-8\n\n\"\"\"\n@author: zhanghe\n@software: PyCharm\n@file: user.py\n@time: 2017/3/17 下午11:49\n\"\"\"\n\n\nfrom flask import session\nimport re\nfrom flask_wtf import FlaskForm\nfrom wtforms import StringField, PasswordField, BooleanField, DateField, DateTimeField, HiddenField\nfrom wtforms.validators import DataRequired, InputRequired, Length, NumberRange, EqualTo, Email, ValidationError, IPAddress\nfrom flask_login import current_user\nfrom app_frontend.models import UserProfile\nfrom app_common.maps import area_code_list\nfrom app_frontend.api.user_auth import get_user_auth_row\nfrom app_frontend.api.user_profile import get_user_profile_row\nfrom app_frontend.forms import SelectAreaCode, CheckBoxBS\nfrom app_frontend import app\n\n\nclass EmailRepeatValidate(object):\n    \"\"\"\n    邮箱重复校验\n    \"\"\"\n    def __init__(self, message=None):\n        self.message = message\n\n    def __call__(self, form, field):\n        condition = [\n            UserProfile.email == field.data,\n            UserProfile.user_id != current_user.get_id()\n        ]\n        row = get_user_profile_row(*condition)\n\n        if row:\n            raise ValidationError(self.message or u'电子邮箱重复')\n\n\nclass PhoneFormatValidate(object):\n    \"\"\"\n    手机号码格式校验\n    \"\"\"\n    def __init__(self, message=None):\n        self.message = message\n\n    def __call__(self, form, field):\n        phone_len = len(field.data)\n        if phone_len < 6 or phone_len > 11:\n            raise ValidationError(u'手机号码长度不符')\n        # 中国手机号码格式校验\n        if form.area_id.data == '0' and phone_len != 11:\n            raise ValidationError(u'手机号码长度不符')\n        if field.data.startswith('0'):\n            raise ValidationError(u'手机号码格式不符')\n\n\nclass PhoneRepeatValidate(object):\n    \"\"\"\n    手机重复校验\n    (编辑重复校验排除当前用户)\n    \"\"\"\n    def __init__(self, message=None):\n        self.message = message\n\n    def __call__(self, form, field):\n        condition = [\n            UserProfile.area_id == form.area_id.data,\n            UserProfile.phone == field.data,\n            UserProfile.user_id != current_user.get_id()\n        ]\n        row = get_user_profile_row(*condition)\n\n        if row:\n            raise ValidationError(self.message or u'手机号码重复')\n\n\nclass IdCardRepeatValidate(object):\n    \"\"\"\n    身份证号重复校验\n    (编辑重复校验排除当前用户)\n    \"\"\"\n    def __init__(self, message=None):\n        self.message = message\n\n    def __call__(self, form, field):\n        condition = [\n            UserProfile.area_id == form.area_id.data,\n            UserProfile.id_card == field.data,\n            UserProfile.user_id != current_user.get_id()\n        ]\n        row = get_user_profile_row(*condition)\n\n        if row:\n            raise ValidationError(self.message or u'身份证号重复')\n\n\nclass PasswordFormatValidate(object):\n    \"\"\"\n    密码格式校验\n    \"\"\"\n    def __init__(self, message=None):\n        self.message = message\n\n    def __call__(self, form, field):\n        password_len = len(field.data)\n        if password_len > 0 and (password_len < 6 or password_len > 20):\n            raise ValidationError(self.message or u'密码长度不符')\n\n\nclass SmsCodeValidate(object):\n    \"\"\"\n    短信验证码校验\n    \"\"\"\n    def __init__(self, message=None):\n        self.message = message\n\n        self._reg = re.compile(ur'^\\d{6}$')\n\n    def __call__(self, form, field):\n        data = field.data\n        if not self._reg.match(data):\n            raise ValidationError(self.message or u\"短信验证码格式错误\")\n\n        code_key = '%s:%s' % ('sms_code', 'edit')\n        # print session.get(code_key), type(session.get(code_key)), data, type(data)\n        # if session.get(code_key) != data:\n        if not app.config.get('TEST') and session.get(code_key) != data:\n            raise ValidationError(self.message or u\"短信验证码校验错误\")\n\n\nclass UserProfileForm(FlaskForm):\n    \"\"\"\n    用户基本信息表单\n    \"\"\"\n    user_pid = StringField(u'推荐人')\n    nickname = StringField(u'用户名称')\n    avatar_url = StringField(u'用户头像')\n    email = StringField(u'电子邮箱', validators=[\n        DataRequired(u'邮箱不能为空'),\n        Email(u'邮箱格式不对'),\n        EmailRepeatValidate()\n    ])\n    area_code_choices = []\n    for m, n in enumerate(area_code_list):\n        area_code_choices.append((m, n))\n    area_id = SelectAreaCode(u'手机区号',\n                             default='0',\n                             choices=area_code_choices,\n                             validators=[InputRequired(u'请选择手机区号')]\n                             )\n    area_code = StringField('Area Code')\n    phone = StringField(u'手机号码', validators=[\n        DataRequired(u'手机号码不能为空'),\n        PhoneFormatValidate(),\n        PhoneRepeatValidate()\n    ])\n    sms = StringField(u'短信验证码', validators=[\n        DataRequired(u'短信验证码不能为空'),\n        Length(min=6, max=6, message=u'短信验证码长度不符'),\n        SmsCodeValidate()\n    ])\n    birthday = DateField(u'出生日期')\n    real_name = StringField(u'真实姓名', validators=[\n        DataRequired(u'真实姓名不能为空'),\n        Length(min=2, max=20, message=u'真实姓名长度不符')\n    ])\n    id_card = StringField(u'身份证号', validators=[\n        DataRequired(u'身份证号不能为空'),\n        Length(min=18, max=18, message=u'身份证号长度不符'),\n        IdCardRepeatValidate()\n    ])\n    create_time = DateTimeField(u'创建时间')\n    update_time = DateTimeField(u'修改时间')\n\n\nclass UserAuthForm(FlaskForm):\n    \"\"\"\n    用户登录认证信息表单\n    \"\"\"\n    id = HiddenField('Id', validators=[DataRequired()])\n    type_auth = StringField(u'账号类型')\n    auth_key = StringField(u'登录账号')\n    auth_secret = PasswordField(u'登录密码', validators=[\n        PasswordFormatValidate()\n    ])\n    status_verified = CheckBoxBS(u'认证状态')\n    create_time = DateTimeField(u'创建时间')\n    update_time = DateTimeField(u'更新时间')\n\n\nclass UserBankForm(FlaskForm):\n    \"\"\"\n    用户基本银行信息表单\n    \"\"\"\n    account_name = StringField(u'账户姓名', validators=[\n        DataRequired(u'账户姓名不能为空'),\n        Length(min=2, max=20, message=u'账户姓名长度不符'),\n    ])\n    bank_name = StringField(u'银行名称', validators=[DataRequired(u'银行名称不能为空')])\n    bank_address = StringField(u'支行名称', validators=[DataRequired(u'支行名称不能为空')])\n    bank_account = StringField(u'银行卡号', validators=[DataRequired(u'银行卡号不能为空')])\n    status_verified = CheckBoxBS(u'认证状态')\n    status_delete = StringField(u'删除状态')\n    create_time = DateTimeField(u'创建时间')\n    update_time = DateTimeField(u'更新时间')\n\n\nclass EditPassword(FlaskForm):\n    \"\"\"\n    修改用户密码\n    \"\"\"\n    password = PasswordField('New Password', validators=[\n        DataRequired(),\n        Length(min=6, max=40),\n        EqualTo('confirm', message='Passwords must match')\n    ])\n    confirm = PasswordField('Repeat Password', validators=[\n        DataRequired(),\n        Length(min=6, max=40)\n    ])\n\n"
  },
  {
    "path": "app_frontend/lib/__init__.py",
    "content": "#!/usr/bin/env python\n# encoding: utf-8\n\n\"\"\"\n@author: zhanghe\n@software: PyCharm\n@file: __init__.py\n@time: 16-1-27 上午10:26\n\"\"\"\n\n\ndef func():\n    pass\n\n\nclass Main(object):\n    def __init__(self):\n        pass\n\n\nif __name__ == '__main__':\n    pass\n"
  },
  {
    "path": "app_frontend/lib/captcha.py",
    "content": "#!/usr/bin/env python\n# encoding: utf-8\n\n\"\"\"\n@author: zhanghe\n@software: PyCharm\n@file: captcha.py\n@time: 16-4-11 下午9:23\n\"\"\"\n\n\nimport random\nfrom os.path import abspath\nfrom PIL import Image, ImageDraw, ImageFont, ImageFilter\n\n\nclass Captcha(object):\n    \"\"\"\n    验证码（生成）\n    \"\"\"\n    # map:将str函数作用于后面序列的每一个元素\n    _letter_cases = \"abcdefghjkmnpqrstuvwxy\"  # 小写字母, 去除可能干扰的i, l, o, z\n    _upper_cases = _letter_cases.upper()  # 大写字母\n    _numbers = ''.join(map(str, range(3, 10)))  # 数字, 去除可能干扰的0, 1, 2\n    init_chars = ''.join((_upper_cases, _numbers))\n\n    def __init__(self,\n                 size=(120, 30),\n                 chars=init_chars,\n                 mode=\"RGB\",\n                 bg_color=(255, 255, 255),\n                 fg_color=(255, 0, 0),\n                 line_color=(255, 0, 0),\n                 point_color=(255, 0, 0),\n                 font_type=abspath('app_frontend/static/fonts/Ubuntu-B.ttf'),\n                 font_size=18,\n                 length=4,\n                 draw_lines=True,\n                 n_lines=(1, 2),\n                 draw_points=True,\n                 point_chance=2):\n        \"\"\"\n        :param size: 图片的大小，格式（宽，高），默认为(120, 30)\n        :param chars: 允许的字符集合，格式字符串\n        :param mode: 图片模式，默认为RGB\n        :param bg_color: 背景颜色，默认为白色\n        :param fg_color: 前景色，验证码字符颜色\n        :param font_type: 验证码字体\n        :param font_size: 验证码字体大小\n        :param length: 验证码字符个数\n        :param draw_lines: 是否划干扰线\n        :param n_lines: 干扰线的条数范围，格式元组，默认为(1, 2)，只有draw_lines为True时有效\n        :param draw_points: 是否画干扰点\n        :param point_chance: 干扰点出现的概率，大小范围[0, 50]\n        :return:\n        \"\"\"\n        self.size = size\n        self.width, self.height = size\n        self.chars = chars\n        self.bg_color, self.fg_color, self.line_color, self.point_color = bg_color, fg_color, line_color, point_color\n        self.font_type, self.font_size = font_type, font_size\n        self.length = length\n        self.draw_lines, self.n_lines, self.draw_points = draw_lines, n_lines, draw_points\n        self.point_chance = point_chance\n        self.img = Image.new(mode, size, bg_color)  # 创建图形\n        self.draw = ImageDraw.Draw(self.img)  # 创建画笔\n\n    def _get_chars(self):\n        \"\"\"\n        生成给定长度的字符串，返回列表格式\n        \"\"\"\n        return random.sample(self.chars, self.length)\n\n    def _create_lines(self):\n        \"\"\"\n        绘制干扰线\n        \"\"\"\n        line_num = random.randint(*self.n_lines)  # 干扰线条数\n\n        for i in range(line_num):\n            # 起始点\n            begin = (random.randint(0, self.size[0]), random.randint(0, self.size[1]))\n            # 结束点\n            end = (random.randint(0, self.size[0]), random.randint(0, self.size[1]))\n            self.draw.line([begin, end], fill=self.line_color)\n\n    def _create_points(self):\n        \"\"\"\n        绘制干扰点\n        \"\"\"\n        chance = min(50, max(0, int(self.point_chance)))  # 大小限制在[0, 50]\n\n        for w in xrange(self.width):\n            for h in xrange(self.height):\n                tmp = random.randint(0, 50)\n                if tmp > 50 - chance:\n                    self.draw.point((w, h), fill=self.point_color)\n\n    def _create_code_str(self):\n        \"\"\"\n        绘制验证码字符\n        \"\"\"\n        c_chars = self._get_chars()\n        c_str = '%s' % ''.join(c_chars)\n\n        font = ImageFont.truetype(self.font_type, self.font_size)\n        font_width, font_height = font.getsize(c_str)\n\n        self.draw.text(((self.width - font_width) / 3, (self.height - font_height) / 4),\n                       c_str, font=font, fill=self.fg_color)\n        return c_str\n\n    def get(self):\n        if self.draw_lines:\n            self._create_lines()\n        if self.draw_points:\n            self._create_points()\n        code_str = self._create_code_str()\n\n        # 图形扭曲参数\n        params = [1 - float(random.randint(1, 2)) / 100,\n                  0,\n                  0,\n                  0,\n                  1 - float(random.randint(1, 10)) / 100,\n                  float(random.randint(1, 2)) / 500,\n                  0.001,\n                  float(random.randint(1, 2)) / 500\n                  ]\n        img = self.img.transform(self.size, Image.PERSPECTIVE, params)  # 创建扭曲\n\n        img = img.filter(ImageFilter.EDGE_ENHANCE_MORE)  # 滤镜，边界加强（阈值更大）\n\n        return img, code_str\n\n\nif __name__ == '__main__':\n    pass\n"
  },
  {
    "path": "app_frontend/lib/cart.py",
    "content": "#!/usr/bin/env python\n# encoding: utf-8\n\n\"\"\"\n@author: zhanghe\n@software: PyCharm\n@file: cart.py\n@time: 16-1-27 上午10:27\n\"\"\"\n\n\nimport redis\n\n\nredis_client = redis.StrictRedis(host='localhost', port=6379, db=0)\n\n\nclass Cart(object):\n    \"\"\"\n    购物车\n    \"\"\"\n    uid = ''\n    prefix = ''\n\n    def __init__(self, uid, prefix='cart'):\n        self.uid = uid\n        self.prefix = prefix\n\n    def add_item(self, pid, num=1):\n        \"\"\"\n        添加物品\n        :param pid:\n        :param num:\n        :return:\n        \"\"\"\n        key = \"%s:%s:%s\" % (self.prefix, self.uid, pid)\n        # 判断物品是否存在\n        if redis_client.exists(key):\n            redis_client.hincrby(key, 'num', num)\n        else:\n            # 如果不存在，添加物品至购物车\n            redis_client.hmset(key, {'pid': pid, 'num': num})\n        return True\n\n    def del_item(self, pid):\n        \"\"\"\n        删除物品\n        :param pid:\n        :return:\n        \"\"\"\n        key = \"%s:%s:%s\" % (self.prefix, self.uid, pid)\n        # 判断物品是否存在\n        if redis_client.exists(key):\n            redis_client.delete(key)\n        return True\n\n    def edit_item(self, pid, num):\n        \"\"\"\n        编辑物品\n        :param pid:\n        :param num:\n        :return: True/False\n        \"\"\"\n        key = \"%s:%s:%s\" % (self.prefix, self.uid, pid)\n        # 判断物品是否存在\n        if redis_client.exists(key):\n            redis_client.hmset(key, {'pid': pid, 'num': num})\n            return True\n        return False\n\n    def increase(self, pid, num=1):\n        \"\"\"\n        增加物品数量\n        :param pid:\n        :param num:\n        :return:\n        \"\"\"\n        key = \"%s:%s:%s\" % (self.prefix, self.uid, pid)\n        # 判断物品是否存在\n        if redis_client.exists(key):\n            redis_client.hincrby(key, 'num', num)\n        else:\n            # 如果不存在，添加物品至购物车\n            redis_client.hmset(key, {'pid': pid, 'num': num})\n        return True\n\n    def decrease(self, pid, num=1):\n        \"\"\"\n        减少物品数量\n        :param pid:\n        :param num:\n        :return:\n        \"\"\"\n        key = \"%s:%s:%s\" % (self.prefix, self.uid, pid)\n        # 判断物品是否存在\n        if redis_client.exists(key):\n            if num >= int(redis_client.hget(key, 'num')):\n                # 如果超过，设置默认最小数量\n                redis_client.hmset(key, {'num': 1})\n            else:\n                redis_client.hincrby(key, 'num', -num)\n        return True\n\n    def cart_list(self):\n        \"\"\"\n        显示购物车\n        :return: list\n        \"\"\"\n        key = \"%s:%s:*\" % (self.prefix, self.uid)\n        car_key_list = redis_client.keys(key)\n        return [redis_client.hgetall(item) for item in car_key_list]\n\n    def clean(self):\n        \"\"\"\n        清空购物车\n        :return: 0/int\n        \"\"\"\n        key = \"%s:%s:*\" % (self.prefix, self.uid)\n        car_key_list = redis_client.keys(key)\n        return redis_client.delete(*car_key_list) if car_key_list else 0\n\n\ndef test():\n    obj = Cart('02')\n    print obj.cart_list()\n    obj.add_item('3')\n    print obj.cart_list()\n    obj.del_item('4')\n    print obj.cart_list()\n    obj.increase('3')\n    print obj.cart_list()\n    obj.decrease('3')\n    print obj.cart_list()\n    obj.add_item('4')\n    print obj.cart_list()\n    obj.add_item('5', 10)\n    print obj.cart_list()\n    obj.edit_item('5', 9)\n    print obj.cart_list()\n    obj.decrease('4', 10)\n    print obj.cart_list()\n\n\nif __name__ == '__main__':\n    test()\n\n\n\"\"\"\n测试结果\n[]\n[{'num': '1', 'pid': '3'}]\n[{'num': '1', 'pid': '3'}]\n[{'num': '2', 'pid': '3'}]\n[{'num': '1', 'pid': '3'}]\n[{'num': '1', 'pid': '4'}, {'num': '1', 'pid': '3'}]\n[{'num': '10', 'pid': '5'}, {'num': '1', 'pid': '4'}, {'num': '1', 'pid': '3'}]\n[{'num': '10', 'pid': '5'}, {'num': '1', 'pid': '4'}, {'num': '1', 'pid': '3'}]\n\"\"\"\n"
  },
  {
    "path": "app_frontend/lib/container.py",
    "content": "#!/usr/bin/env python\n# encoding: utf-8\n\n\"\"\"\n@author: zhanghe\n@software: PyCharm\n@file: container.py\n@time: 16-2-17 下午3:46\n\"\"\"\n\n\nimport redis\nimport time\nfrom copy import deepcopy\n\n\nredis_client = redis.StrictRedis(host='localhost', port=6379, db=0)\n\n\nclass Container(object):\n    \"\"\"\n    容器（数据结构：有序集合）\n    \"\"\"\n    # 定义支持的实体类型\n    entity_name_list = ['user', 'blog', 'topic', 'subject', 'product']\n\n    # 定义支持的统计类型\n    stat_type_list = [\n        'favor',  # 支持数\n        'decry',  # 反对数\n        'follow',  # 关注数\n        'fans',  # 粉丝数\n        'view',  # 点击数\n        'collect',  # 收藏数\n        'flag'  # 举报数\n    ]\n\n    # 定义项目容器状态结构\n    container_status_dict = {\n        'favor': False,  # 支持\n        'flag': False,  # 举报\n        'collect': False  # 收藏\n    }\n\n    def __init__(self, entity_name, prefix='container'):\n        if entity_name not in self.entity_name_list:\n            raise TypeError(u'类型错误')\n        self.entity_name = entity_name\n        self.prefix = prefix\n\n    def add_item(self, stat_type, key_id, item_id):\n        \"\"\"\n        添加统计项目\n        :param stat_type:\n        :param key_id:\n        :param item_id:\n        :return:0/1\n        \"\"\"\n        key = \"%s:%s:%s:%s\" % (self.prefix, self.entity_name, stat_type, key_id)\n        return redis_client.zadd(key, time.time(), item_id)\n\n    def del_item(self, stat_type, key_id, item_id):\n        \"\"\"\n        删除统计项目\n        :param stat_type:\n        :param key_id:\n        :param item_id:\n        :return:0/1\n        \"\"\"\n        key = \"%s:%s:%s:%s\" % (self.prefix, self.entity_name, stat_type, key_id)\n        return redis_client.zrem(key, item_id)\n\n    def count_item(self, stat_type, key_id):\n        \"\"\"\n        统计相关项目的总数\n        :param stat_type:\n        :param key_id:\n        :return:\n        \"\"\"\n        key = \"%s:%s:%s:%s\" % (self.prefix, self.entity_name, stat_type, key_id)\n        return redis_client.zcount(key, 0, time.time())\n\n    def get_items(self, stat_type, key_id, page=1, pagesize=10):\n        \"\"\"\n        分页获取相关项目列表(根据时间降序)\n        :param stat_type:\n        :param key_id:\n        :param page:\n        :param pagesize:\n        :return:[]\n        \"\"\"\n        offset = 0\n        if page > 1:\n            offset = (page - 1) * pagesize\n        max_count = (page * pagesize) - 1\n        key = \"%s:%s:%s:%s\" % (self.prefix, self.entity_name, stat_type, key_id)\n        item_ids = redis_client.zrevrange(key, offset, max_count)  # 倒序取值\n        # item_ids = redis_client.zrange(key, offset, max_count)  # 顺序取值\n        return item_ids\n\n    def get_all_items(self, stat_type, key_id):\n        \"\"\"\n        获取所有相关项目列表\n        :param stat_type:\n        :param key_id:\n        :return:[]\n        \"\"\"\n        key = \"%s:%s:%s:%s\" % (self.prefix, self.entity_name, stat_type, key_id)\n        total = redis_client.zcard(key)\n        item_ids = redis_client.zrevrange(key, 0, total - 1, True)\n        return item_ids\n\n    def get_item_container_status(self, key_id, item_id):\n        \"\"\"\n        获取容器状态\n        :param key_id:\n        :param item_id:\n        :return:\n        \"\"\"\n        container_status = deepcopy(self.container_status_dict)\n        for stat_type in container_status.keys():\n            key = \"%s:%s:%s:%s\" % (self.prefix, self.entity_name, stat_type, key_id)\n            # 无序集合sismember； 有序用 zscore 返回值：None\n            if redis_client.zscore(key, item_id):\n                container_status[stat_type] = True\n        return container_status\n\n    def get_item_list_container_status(self, key_ids, item_id):\n        \"\"\"\n        显示列表容器状态\n        按原 item_ids 列表顺序返回结果\n        :param key_ids:\n        :param item_id:\n        :return:\n        \"\"\"\n        container_list = []\n        for key_id in key_ids:\n            container_status = self.get_item_container_status(key_id, item_id)\n            container_list.append(container_status)\n        return container_list\n\n\ndef test_blog_favor():\n    \"\"\"\n    测试 blog favor\n    \"\"\"\n    obj = Container('blog')\n    print obj.add_item('favor', 2, 5)  # 1\n    print obj.add_item('favor', 2, 5)  # 0\n    print obj.add_item('favor', 2, 6)  # 1\n    print obj.get_items('favor', 2)  # ['6', '5']\n    print obj.get_items('favor', 3)  # []\n    print obj.count_item('favor', 2)  # 2\n    print obj.del_item('favor', 3, 5)  # 0\n    print obj.count_item('favor', 3)  # 0\n    print obj.del_item('favor', 2, 5)  # 1\n    print obj.count_item('favor', 2)  # 1\n    print obj.del_item('favor', 2, 6)  # 1\n    print obj.count_item('favor', 2)  # 0\n\n\nif __name__ == '__main__':\n    test_blog_favor()\n"
  },
  {
    "path": "app_frontend/lib/counter.py",
    "content": "#!/usr/bin/env python\n# encoding: utf-8\n\n\"\"\"\n@author: zhanghe\n@software: PyCharm\n@file: count.py\n@time: 16-1-27 下午3:03\n\"\"\"\n\n\nimport redis\nfrom copy import deepcopy\n\n\nredis_client = redis.StrictRedis(host='localhost', port=6379, db=0)\nredis_pipeline = redis_client.pipeline()\n\n\nclass Counter(object):\n    \"\"\"\n    计数器\n    \"\"\"\n    # 定义支持的实体类型\n    entity_name_list = ['user', 'blog', 'topic', 'subject', 'product']\n\n    # 定义支持的统计类型\n    stat_type_list = [\n        'favor',  # 支持\n        'decry',  # 反对\n        'follow',  # 关注\n        'fans',  # 粉丝\n        'view',  # 点击\n        'collect',  # 收藏\n        'flag'  # 举报\n    ]\n\n    # 定义用户计数器结构\n    user_counter_dict = {\n        'favor': '0',  # 支持数\n        'decry': '0',  # 反对数\n        'follow': '0',  # 关注数\n        'fans': '0'  # 粉丝数\n    }\n\n    # 定义话题计数器结构\n    topic_counter_dict = {\n        'favor': '0',  # 支持数\n        'decry': '0',  # 反对数\n        'view': '0',  # 点击数\n        'collect': '0'  # 收藏数\n    }\n\n    # 定义博客计数器结构\n    blog_counter_dict = {\n        'favor': '0',  # 支持数\n        'flag': '0',  # 举报数\n        'view': '0',  # 点击数\n        'collect': '0'  # 收藏数\n    }\n\n    def __init__(self, entity_name, prefix='counter'):\n        if entity_name not in self.entity_name_list:\n            raise TypeError(u'类型错误')\n        self.entity_name = entity_name\n        self.prefix = prefix\n\n    def increase(self, item_id, stat_type, num=1):\n        \"\"\"\n        增加次数\n        :param item_id:\n        :param stat_type:\n        :param num:\n        :return:\n        \"\"\"\n        if stat_type not in self.stat_type_list:\n            raise TypeError(u'类型错误')\n        key = \"%s:%s:%s\" % (self.prefix, self.entity_name, item_id)\n        # 判断物品是否存在\n        if redis_client.exists(key):\n            redis_client.hincrby(key, stat_type, num)\n        else:\n            # 如果不存在，添加物品至购物车\n            redis_client.hmset(key, {stat_type: num})\n        return True\n\n    def decrease(self, item_id, stat_type, num=1):\n        \"\"\"\n        减少次数\n        :param item_id:\n        :param stat_type:\n        :param num:\n        :return:\n        \"\"\"\n        key = \"%s:%s:%s\" % (self.prefix, self.entity_name, item_id)\n        # 判断物品是否存在\n        if redis_client.exists(key):\n            if num >= int(redis_client.hget(key, stat_type)):\n                # 如果超过，设置默认最小数量\n                redis_client.hmset(key, {stat_type: 1})\n            else:\n                redis_client.hincrby(key, stat_type, -num)\n        return True\n\n    def del_item(self, item_id):\n        \"\"\"\n        删除物品\n        :param item_id:\n        :return:\n        \"\"\"\n        key = \"%s:%s:%s\" % (self.prefix, self.entity_name, item_id)\n        # 判断物品是否存在\n        if redis_client.exists(key):\n            redis_client.delete(key)\n        return True\n\n    def counter_blog_item(self, blog_id):\n        \"\"\"\n        显示 blog 计数器\n        :param blog_id:\n        :return:\n        \"\"\"\n        key = \"%s:%s:%s\" % (self.prefix, self.entity_name, blog_id)\n        # 判断物品是否存在\n        blog_dict = deepcopy(self.blog_counter_dict)\n        if redis_client.exists(key):\n            redis_result = redis_client.hgetall(key)\n            blog_dict.update(redis_result)\n        return blog_dict\n\n    def counter_user_list_all(self):\n        \"\"\"\n        显示全部用户计数器\n        :return:\n        \"\"\"\n        key = \"%s:%s:*\" % (self.prefix, self.entity_name)\n        cnt_key_list = redis_client.keys(key)\n        cnt_list = []\n        for item in cnt_key_list:\n            user_dict = deepcopy(self.user_counter_dict)  # 注意是深度复制，不能写成 user_dict = self.user_counter_dict\n            user_dict.update(redis_client.hgetall(item))\n            cnt_list.append(user_dict)\n        return cnt_list\n\n    def counter_user_list(self, uid_list):\n        \"\"\"\n        显示用户计数器\n        按原 uid_list 列表顺序返回结果\n        :param uid_list:\n        :return:\n        \"\"\"\n        cnt_list = []\n        for uid in uid_list:\n            key = \"%s:%s:%s\" % (self.prefix, self.entity_name, uid)\n            if redis_client.exists(key):\n                user_dict = deepcopy(self.user_counter_dict)\n                redis_result = redis_client.hgetall(key)\n                user_dict.update(redis_result)\n                cnt_list.append(user_dict)\n        return cnt_list\n\n    def counter_topic_list(self, topic_list):\n        \"\"\"\n        显示话题计数器\n        按原 uid_list 列表顺序返回结果\n        :param topic_list:\n        :return:\n        \"\"\"\n        cnt_list = []\n        for topic in topic_list:\n            key = \"%s:%s:%s\" % (self.prefix, self.entity_name, topic)\n            user_dict = deepcopy(self.topic_counter_dict)\n            if redis_client.exists(key):\n                redis_result = redis_client.hgetall(key)\n                user_dict.update(redis_result)\n            cnt_list.append(user_dict)\n        return cnt_list\n\n    def counter_blog_list(self, blog_list):\n        \"\"\"\n        显示 blog 计数器\n        按原 blog_list 列表顺序返回结果\n        :param blog_list:\n        :return:\n        \"\"\"\n        cnt_list = []\n        for blog in blog_list:\n            key = \"%s:%s:%s\" % (self.prefix, self.entity_name, blog)\n            blog_dict = deepcopy(self.blog_counter_dict)\n            if redis_client.exists(key):\n                redis_result = redis_client.hgetall(key)\n                blog_dict.update(redis_result)\n            cnt_list.append(blog_dict)\n        return cnt_list\n\n    def set_blog_counter(self, blog_id, stat_type, num=1):\n        \"\"\"\n        设置 blog 计数器\n        :param blog_id:\n        :param stat_type:\n        :param num:\n        :return:\n        \"\"\"\n        self.increase(blog_id, stat_type, num)\n        return self.counter_blog_item(blog_id)\n\n\ndef test_user():\n    import json\n    user_cnt_obj = Counter('user')\n    user_cnt_obj.del_item(12)\n    user_cnt_obj.del_item(13)\n    user_cnt_obj.increase(12, 'favor')\n    user_cnt_obj.increase(13, 'fans', 5)\n    user_cnt_obj.increase(14, 'fans', 4)\n    user_cnt_obj.increase(14, 'follow', 3)\n    print json.dumps(user_cnt_obj.counter_user_list(['12', '13']), indent=4, ensure_ascii=False)\n    print json.dumps(user_cnt_obj.counter_user_list_all(), indent=4, ensure_ascii=False)\n\n\ndef test_topic():\n    import json\n    topic_cnt_obj = Counter('topic')\n    print json.dumps(topic_cnt_obj.counter_topic_list(['1', '2', '3']), indent=4, ensure_ascii=False)\n    topic_cnt_obj.increase(4, 'fans', 4)\n    print topic_cnt_obj.counter_blog_item(4)\n    print topic_cnt_obj.set_blog_counter(4, 'flag')\n\n\nif __name__ == '__main__':\n    # test_user()\n    test_topic()\n"
  },
  {
    "path": "app_frontend/lib/mongo.py",
    "content": "#!/usr/bin/env python\n# encoding: utf-8\n\n\"\"\"\n@author: zhanghe\n@software: PyCharm\n@file: mongo.py\n@time: 2017/4/10 下午11:44\n\"\"\"\n\n\nfrom pymongo import MongoClient\nfrom pymongo import errors\nimport json\nfrom datetime import date, datetime\nimport logging\n\nlogger = logging.getLogger(__name__)\n\n\nclass Mongodb(object):\n    \"\"\"\n    自定义mongodb工具\n    \"\"\"\n    def __init__(self, db_config, db_name=None):\n        self.db_config = db_config\n        if db_name is not None:\n            self.db_config['database'] = db_name\n        try:\n            # 实例化mongodb\n            self.conn = MongoClient(self.db_config['host'], self.db_config['port'])\n            # 获取数据库对象(选择/切换)\n            self.db = self.conn.get_database(self.db_config['database'])\n        except errors.ServerSelectionTimeoutError, e:\n            logger.error('连接超时：%s' % e)\n        except Exception, e:\n            logger.error(e)\n\n    @staticmethod\n    def __default(obj):\n        \"\"\"\n        支持datetime的json encode\n        TypeError: datetime.datetime(2015, 10, 21, 8, 42, 54) is not JSON serializable\n        :param obj:\n        :return:\n        \"\"\"\n        if isinstance(obj, datetime):\n            return obj.strftime('%Y-%m-%d %H:%M:%S')\n        elif isinstance(obj, date):\n            return obj.strftime('%Y-%m-%d')\n        else:\n            raise TypeError('%r is not JSON serializable' % obj)\n\n    def close_conn(self):\n        \"\"\"\n        关闭连接\n        关闭所有套接字的连接池和停止监控线程。\n        如果这个实例再次使用它将自动重启和重新启动线程\n        \"\"\"\n        self.conn.close()\n\n    def find_one(self, table_name, condition=None):\n        \"\"\"\n        查询单条记录\n        :param table_name:\n        :param condition:\n        :return:\n        \"\"\"\n        return self.db.get_collection(table_name).find_one(condition)\n\n    def find_all(self, table_name, condition=None):\n        \"\"\"\n        查询多条记录\n        :param table_name:\n        :param condition:\n        :return:\n        \"\"\"\n        return self.db.get_collection(table_name).find(condition)\n\n    def count(self, table_name, condition=None):\n        \"\"\"\n        查询记录总数\n        :param table_name:\n        :param condition:\n        :return:\n        \"\"\"\n        return self.db.get_collection(table_name).count(condition)\n\n    def distinct(self, table_name, field_name):\n        \"\"\"\n        查询某字段去重后值的范围\n        :param table_name:\n        :param field_name:\n        :return:\n        \"\"\"\n        return self.db.get_collection(table_name).distinct(field_name)\n\n    def insert(self, table_name, data):\n        \"\"\"\n        插入数据\n        :param table_name:\n        :param data:\n        :return:\n        \"\"\"\n        try:\n            ids = self.db.get_collection(table_name).insert(data)\n            return ids\n        except Exception, e:\n            logger.error('插入失败：%s' % e)\n            return None\n\n    def update(self, table_name, condition, update_data, update_type='set'):\n        \"\"\"\n        批量更新数据\n        upsert : 如果不存在update的记录，是否插入；true为插入，默认是false，不插入。\n        :param table_name:\n        :param condition:\n        :param update_data:\n        :param update_type: 范围：['inc', 'set', 'unset', 'push', 'pushAll', 'addToSet', 'pop', 'pull', 'pullAll', 'rename']\n        :return:\n        \"\"\"\n        if update_type not in ['inc', 'set', 'unset', 'push', 'pushAll', 'addToSet', 'pop', 'pull', 'pullAll', 'rename']:\n            logger.error('更新失败，类型错误：%s' % update_type)\n            return None\n        try:\n            result = self.db.get_collection(table_name).update_many(condition, {'$%s' % update_type: update_data})\n            logger.info('更新成功，匹配数量：%s；更新数量：%s' % (result.matched_count, result.modified_count))\n            return result.modified_count  # 返回更新数量，仅支持MongoDB 2.6及以上版本\n        except Exception, e:\n            logger.error('更新失败：%s' % e)\n            return None\n\n    def remove(self, table_name, condition=None):\n        \"\"\"\n        删除文档记录\n        :param table_name:\n        :param condition:\n        :return:\n        \"\"\"\n        result = self.db.get_collection(table_name).remove(condition)\n        if result.get('err') is None:\n            logger.info('删除成功，删除行数%s' % result.get('n', 0))\n            return result.get('n', 0)\n        else:\n            logger.error('删除失败：%s' % result.get('err'))\n            return None\n\n    def output_row(self, table_name, condition=None, style=0):\n        \"\"\"\n        格式化输出单个记录\n        style=0 键值对齐风格\n        style=1 JSON缩进风格\n        :param table_name:\n        :param condition:\n        :param style:\n        :return:\n        \"\"\"\n        row = self.find_one(table_name, condition)\n        if style == 0:\n            # 获取KEY最大的长度作为缩进依据\n            max_len_key = max([len(each_key) for each_key in row.keys()])\n            str_format = '{0: >%s}' % max_len_key\n            keys = [str_format.format(each_key) for each_key in row.keys()]\n            result = dict(zip(keys, row.values()))\n            print '**********  表名[%s]  **********' % table_name\n            for key, item in result.items():\n                print key, ':', item\n        else:\n            print json.dumps(row, indent=4, ensure_ascii=False, default=self.__default)\n\n    def output_rows(self, table_name, condition=None, style=0):\n        \"\"\"\n        格式化输出批量记录\n        style=0 键值对齐风格\n        style=1 JSON缩进风格\n        :param table_name:\n        :param condition:\n        :param style:\n        :return:\n        \"\"\"\n        rows = self.find_all(table_name, condition)\n        total = self.count(table_name, condition)\n        if style == 0:\n            count = 0\n            for row in rows:\n                # 获取KEY最大的长度作为缩进依据\n                max_len_key = max([len(each_key) for each_key in row.keys()])\n                str_format = '{0: >%s}' % max_len_key\n                keys = [str_format.format(each_key) for each_key in row.keys()]\n                result = dict(zip(keys, row.values()))\n                count += 1\n                print '**********  表名[%s]  [%d/%d]  **********' % (table_name, count, total)\n                for key, item in result.items():\n                    print key, ':', item\n        else:\n            for row in rows:\n                print json.dumps(row, indent=4, ensure_ascii=False, default=self.__default)\n\n"
  },
  {
    "path": "app_frontend/lib/qiniu_store.py",
    "content": "#!/usr/bin/env python\n# encoding: utf-8\n\n\"\"\"\n@author: zhanghe\n@software: PyCharm\n@file: qiniu.py\n@time: 16-5-2 下午1:41\n\"\"\"\n\n\nfrom urlparse import urljoin\nimport qiniu\n\n\nclass QiNiuClient(object):\n    \"\"\"\n    七牛云存储\n    \"\"\"\n    def __init__(self, app=None):\n        \"\"\"\n        初始化应用\n        \"\"\"\n        if app is not None:\n            self._access_key = app.config.get('QINIU_ACCESS_KEY', '')\n            self._secret_key = app.config.get('QINIU_SECRET_KEY', '')\n            self._bucket_name = app.config.get('QINIU_BUCKET_NAME', '')\n            domain = app.config.get('QINIU_BUCKET_DOMAIN')\n            if not domain:\n                self._base_url = 'http://' + self._bucket_name + '.qiniudn.com'\n            else:\n                self._base_url = 'http://' + domain\n\n    def save(self, data, filename=None):\n        \"\"\"\n        保存\n        \"\"\"\n        auth = qiniu.Auth(self._access_key, self._secret_key)\n        token = auth.upload_token(self._bucket_name)\n        return qiniu.put_data(token, filename, data)\n\n    def delete(self, filename):\n        \"\"\"\n        删除\n        \"\"\"\n        auth = qiniu.Auth(self._access_key, self._secret_key)\n        bucket = qiniu.BucketManager(auth)\n        return bucket.delete(self._bucket_name, filename)\n\n    def url(self, filename):\n        \"\"\"\n        链接\n        \"\"\"\n        return urljoin(self._base_url, filename)\n\n\nif __name__ == '__main__':\n    pass\n"
  },
  {
    "path": "app_frontend/lib/rabbit_mq.py",
    "content": "#!/usr/bin/env python\n# encoding: utf-8\n\n\"\"\"\n@author: zhanghe\n@software: PyCharm\n@file: rabbit_mq.py\n@time: 2017/4/1 上午9:55\n\"\"\"\n\n\nimport pika\nimport json\nimport traceback\n\n\nfrom config import current_config\n\nRABBIT_MQ = current_config.RABBIT_MQ\n\n_client_conn = {'conn': None}\n\n\ndef get_conn():\n    \"\"\"\n    获取连接\n    :return:\n    \"\"\"\n    if not _client_conn.get('conn'):\n        conn_mq = pika.BlockingConnection(\n            pika.ConnectionParameters(\n                host=RABBIT_MQ.get('host', '127.0.0.1'),\n                port=RABBIT_MQ.get('port', 5672),\n                virtual_host=RABBIT_MQ.get('virtual_host', '/'),\n                heartbeat_interval=RABBIT_MQ.get('heartbeat_interval', 0),\n                retry_delay=RABBIT_MQ.get('retry_delay', 3)\n            )\n        )\n        _client_conn['conn'] = conn_mq\n        return conn_mq\n    else:\n        return _client_conn['conn']\n\n\nclass RabbitQueue(object):\n    \"\"\"\n    队列\n    \"\"\"\n    def __init__(self, exchange, queue_name, exchange_type='direct', durable=True, **arguments):\n        self.exchange = exchange\n        self.queue_name = queue_name\n        self.exchange_type = exchange_type\n        self.durable = durable\n        self.arguments = arguments\n        print u'实例化附加参数:', arguments\n        self.conn = get_conn()\n        self.channel = self.conn.channel()\n        self.declare()\n\n    def close_conn(self):\n        \"\"\"\n        关闭连接\n        :return:\n        \"\"\"\n        if _client_conn.get('conn'):\n            self.conn.close()\n            _client_conn.pop('conn')\n\n    def declare(self):\n        \"\"\"\n        声明队列\n        \"\"\"\n        self.channel.exchange_declare(exchange=self.exchange, exchange_type=self.exchange_type, durable=self.durable)\n        self.channel.queue_declare(queue=self.queue_name, durable=self.durable, arguments=self.arguments)\n        self.channel.queue_bind(exchange=self.exchange,\n                                queue=self.queue_name,\n                                routing_key=self.queue_name)\n        self.channel.basic_qos(prefetch_count=1)\n\n    def put(self, message):\n        \"\"\"\n        推送队列消息\n        :param message:\n        :return:\n        \"\"\"\n        if isinstance(message, dict):\n            message = json.dumps(message)\n        self.channel.basic_publish(exchange=self.exchange,\n                                   routing_key=self.queue_name,\n                                   body=message,\n                                   properties=pika.BasicProperties(\n                                       delivery_mode=2 if self.durable else 1,  # make message persistent\n                                   ))\n        print \" [x] Sent %r\" % (message,)\n\n    def get(self):\n        \"\"\"\n        获取队列消息\n        :return:\n        \"\"\"\n        # data = self.channel.basic_get(self.queue_name)\n        # print data\n        method_frame, header_frame, body = self.channel.basic_get(self.queue_name)\n        if method_frame:\n            print \" [x]  Get %r\" % (body,)\n            print method_frame, header_frame, body\n            self.channel.basic_ack(method_frame.delivery_tag)\n        else:\n            print('No message returned')\n\n    def get_block(self):\n        \"\"\"\n        获取队列消息(阻塞)\n        direct 模式下多进程消费，进程轮流获取单个消息\n        :return:\n        \"\"\"\n        def callback(ch, method, properties, body):\n            try:\n                print \" [x]  Get %r\" % (body,)\n                # raise Exception('test')\n                ch.basic_ack(delivery_tag=method.delivery_tag)\n            except Exception as e:\n                print traceback.print_exc()\n                raise e\n\n        self.consume(callback)\n\n    def consume(self, callback):\n        \"\"\"\n        消费\n        \"\"\"\n        # 处理队列\n        self.channel.basic_consume(consumer_callback=callback, queue=self.queue_name)\n        try:\n            self.channel.start_consuming()\n        except KeyboardInterrupt:\n            self.channel.stop_consuming()\n        self.close_conn()\n\n\nclass RabbitPubSub(object):\n    \"\"\"\n    订阅\n    \"\"\"\n    def __init__(self, exchange, exchange_type='fanout', durable=True, **arguments):\n        self.exchange = exchange\n        self.exchange_type = exchange_type\n        self.durable = durable\n        self.arguments = arguments\n        print u'实例化附加参数:', arguments\n        self.conn = get_conn()\n        self.channel = self.conn.channel()\n        self.channel.exchange_declare(exchange=self.exchange, exchange_type=self.exchange_type, durable=self.durable)\n\n    def close_conn(self):\n        \"\"\"\n        关闭连接\n        :return:\n        \"\"\"\n        if _client_conn.get('conn'):\n            self.conn.close()\n            _client_conn.pop('conn')\n\n    def pub(self, message):\n        \"\"\"\n        推送队列消息\n        :param message:\n        :return:\n        \"\"\"\n        if isinstance(message, dict):\n            message = json.dumps(message)\n        self.channel.basic_publish(exchange=self.exchange,\n                                   body=message,\n                                   routing_key='',\n                                   properties=pika.BasicProperties(\n                                       delivery_mode=2 if self.durable else 1,  # make message persistent\n                                   ))\n        print \" [x] Pub %r\" % (message,)\n\n    def sub(self):\n        \"\"\"\n        订阅队列消息\n        exchange_type='fanout'\n        fanout 模式下多进程消费，进程同时同步获取消息\n        :return:\n        \"\"\"\n        result = self.channel.queue_declare(exclusive=True)\n        queue_name = result.method.queue\n\n        self.channel.queue_bind(exchange=self.exchange, queue=queue_name)\n\n        print ' [*] Waiting for logs. To exit press CTRL+C'\n\n        def callback(ch, method, properties, body):\n            print \" [x] Sub %r\" % (body,)\n\n        self.channel.basic_consume(callback,\n                                   queue=queue_name,\n                                   no_ack=True\n                                   )\n\n        self.channel.start_consuming()\n\n\nclass RabbitDelayQueue(object):\n    \"\"\"\n    延时队列\n    q_d_client = RabbitDelayQueue('amq.direct', q_name, ttl=3600*24)\n    \"\"\"\n    def __init__(self, exchange, queue_name, exchange_type='direct', durable=True, **arguments):\n        self.exchange = exchange\n        self.queue_name = queue_name\n        self.delay_queue_name = '%s_delay' % queue_name\n        self.exchange_type = exchange_type\n        self.durable = durable\n        self.arguments = arguments\n        print u'实例化附加参数:', arguments\n        self.conn = get_conn()\n\n        self.channel = self.conn.channel()\n        self.channel.confirm_delivery()\n        self.channel.queue_declare(queue=queue_name, durable=durable)\n\n        # We need to bind this channel to an exchange, that will be used to transfer\n        # messages from our delay queue.\n        self.channel.queue_bind(exchange=self.exchange,\n                                queue=queue_name)\n\n        # 延时队列定义\n        self.delay_channel = self.conn.channel()\n        self.delay_channel.confirm_delivery()\n\n        # This is where we declare the delay, and routing for our delay channel.\n        self.delay_channel.queue_declare(queue=self.delay_queue_name, durable=durable, arguments={\n            'x-message-ttl': arguments.get('ttl', 5)*1000,  # Delay until the message is transferred in milliseconds.\n            'x-dead-letter-exchange': self.exchange,  # Exchange used to transfer the message from A to B.\n            'x-dead-letter-routing-key': self.queue_name  # Name of the queue we want the message transferred to.\n        })\n\n    def close_conn(self):\n        \"\"\"\n        关闭连接\n        :return:\n        \"\"\"\n        if _client_conn.get('conn'):\n            self.conn.close()\n            _client_conn.pop('conn')\n\n    def put(self, message):\n        \"\"\"\n        推送队列消息\n        :param message:\n        :return:\n        \"\"\"\n        if isinstance(message, dict):\n            message = json.dumps(message)\n        self.delay_channel.basic_publish(exchange='',\n                                         routing_key=self.delay_queue_name,\n                                         body=message,\n                                         properties=pika.BasicProperties(\n                                             delivery_mode=2 if self.durable else 1,  # make message persistent\n                                         ))\n        print \" [x] Sent %r\" % (message,)\n\n    def get(self):\n        \"\"\"\n        获取队列消息\n        :return:\n        \"\"\"\n        # data = self.channel.basic_get(self.queue_name)\n        # print data\n        method_frame, header_frame, body = self.channel.basic_get(self.queue_name)\n        if method_frame:\n            print \" [x]  Get %r\" % (body,)\n            print method_frame, header_frame, body\n            self.channel.basic_ack(method_frame.delivery_tag)\n        else:\n            print('No message returned')\n\n    def get_block(self):\n        \"\"\"\n        获取队列消息(阻塞)\n        direct 模式下多进程消费，进程轮流获取单个消息\n        :return:\n        \"\"\"\n        def callback(ch, method, properties, body):\n            try:\n                print \" [x]  Get %r\" % (body,)\n                # raise Exception('test')\n                ch.basic_ack(delivery_tag=method.delivery_tag)\n            except Exception as e:\n                print traceback.print_exc()\n                raise e\n\n        self.consume(callback)\n\n    def consume(self, callback):\n        \"\"\"\n        消费\n        \"\"\"\n        # 处理队列\n        self.channel.basic_consume(consumer_callback=callback, queue=self.queue_name)\n        try:\n            self.channel.start_consuming()\n        except KeyboardInterrupt:\n            self.channel.stop_consuming()\n        self.close_conn()\n\n\nclass RabbitPriorityQueue(RabbitQueue):\n    \"\"\"\n    优先级队列\n    max_priority=255\n    \"\"\"\n    def __init__(self, exchange, queue_name, exchange_type='direct', durable=True, **arguments):\n        super(RabbitPriorityQueue, self).__init__(exchange, queue_name, exchange_type, durable, **arguments)\n\n    def declare(self):\n        \"\"\"\n        声明队列\n        \"\"\"\n        self.channel.exchange_declare(exchange=self.exchange, exchange_type=self.exchange_type, durable=self.durable)\n        self.channel.queue_declare(\n            queue=self.queue_name,\n            durable=self.durable,\n            arguments={\n                'x-max-priority': self.arguments.get('max_priority', 255)\n            }\n        )\n        self.channel.queue_bind(exchange=self.exchange,\n                                queue=self.queue_name,\n                                routing_key=self.queue_name)\n        self.channel.basic_qos(prefetch_count=1)\n\n    def put(self, message, priority=0):\n        \"\"\"\n        推送队列消息\n        :param message:\n        :param priority:\n        :return:\n        \"\"\"\n        print '--priority:', priority\n        if isinstance(message, dict):\n            message = json.dumps(message)\n        self.channel.basic_publish(exchange=self.exchange,\n                                   routing_key=self.queue_name,\n                                   body=message,\n                                   properties=pika.BasicProperties(\n                                       delivery_mode=2 if self.durable else 1,  # make message persistent\n                                       priority=priority\n                                   ))\n        print \" [x] Sent %r\" % (message,)\n\n\ndef test_queue():\n    \"\"\"\n    队列测试\n    参数：方法 队列名称 消息\n    :return:\n    \"\"\"\n    import sys\n    print sys.argv\n    if len(sys.argv) < 3:\n        print u'参数：方法 队列名称 消息'\n        print u'python rabbit_mq.py put q_task 123456'\n        print u'python rabbit_mq.py get q_task'\n        return\n    method, q_name, msg = sys.argv[1], sys.argv[2], ''.join(sys.argv[3:4])\n    q_client = RabbitQueue('e_test', q_name)\n    print u'连接id:%s' % id(q_client.conn)\n    # 获取消息\n    if method == 'get':\n        q_client.get()\n    # 推送消息\n    if method == 'put':\n        q_client.put(msg)\n    # 阻塞获取消息\n    if method == 'get_block':\n        q_client.get_block()\n    q_client.close_conn()\n\n\ndef test_pub_sub():\n    \"\"\"\n    队列pub/sub\n    参数：方法 队列名称 消息\n    :return:\n    \"\"\"\n    import sys\n    print sys.argv\n    if len(sys.argv) < 3:\n        print u'参数：方法 队列名称 消息'\n        print u'python rabbit_mq.py pub q_task 123456'\n        print u'python rabbit_mq.py sub q_task'\n        return\n    method, q_name, msg = sys.argv[1], sys.argv[2], ''.join(sys.argv[3:4])\n    q_client = RabbitPubSub(q_name)\n    print u'连接id:%s' % id(q_client.conn)\n    # 获取消息\n    if method == 'sub':\n        q_client.sub()\n    # 推送消息\n    if method == 'pub':\n        q_client.pub(msg)\n    q_client.close_conn()\n\n\ndef test_delay_queue():\n    \"\"\"\n    延时队列测试\n    参数：方法 队列名称 消息\n    :return:\n    \"\"\"\n    import sys\n    print sys.argv\n    if len(sys.argv) < 3:\n        print u'参数：方法 队列名称 消息'\n        print u'python rabbit_mq.py put q_delay_task 123456'\n        print u'python rabbit_mq.py get q_delay_task'\n        return\n    method, q_name, msg = sys.argv[1], sys.argv[2], ''.join(sys.argv[3:4])\n    q_client = RabbitDelayQueue('amq.direct', q_name)\n    print u'连接id:%s' % id(q_client.conn)\n    # 获取消息\n    if method == 'get':\n        q_client.get()\n    # 推送消息\n    if method == 'put':\n        q_client.put(msg)\n    # 阻塞获取消息\n    if method == 'get_block':\n        q_client.get_block()\n    q_client.close_conn()\n\n\ndef test_priority_queue():\n    \"\"\"\n    优先级队列测试\n    参数：方法 队列名称 消息\n    :return:\n    \"\"\"\n    import sys\n    print sys.argv\n    if len(sys.argv) < 3:\n        print u'参数：方法 队列名称 消息'\n        print u'python rabbit_mq.py put q_priority_task 111 100'\n        print u'python rabbit_mq.py put q_priority_task 222 200'\n        print u'python rabbit_mq.py put q_priority_task 333 150'\n        print u'python rabbit_mq.py get q_priority_task'  # 222\n        print u'python rabbit_mq.py get q_priority_task'  # 333\n        print u'python rabbit_mq.py get q_priority_task'  # 111\n        return\n    method, q_name, msg, priority = sys.argv[1], sys.argv[2], ''.join(sys.argv[3:4]), ''.join(sys.argv[4:5])\n    q_client = RabbitPriorityQueue('amq.direct', q_name)\n    print u'连接id:%s' % id(q_client.conn)\n    # 获取消息\n    if method == 'get':\n        q_client.get()\n    # 推送消息\n    if method == 'put':\n        q_client.put(msg, int(priority) if priority else 0)\n    # 阻塞获取消息\n    if method == 'get_block':\n        q_client.get_block()\n    q_client.close_conn()\n\n\nif __name__ == '__main__':\n    # test_queue()\n    # test_pub_sub()\n    # test_delay_queue()\n    test_priority_queue()\n\n"
  },
  {
    "path": "app_frontend/lib/redis_session.py",
    "content": "#!/usr/bin/env python\n# encoding: utf-8\n\n\"\"\"\n@author: zhanghe\n@software: PyCharm\n@file: redis_session.py\n@time: 2017/3/7 上午12:41\n\"\"\"\n\n\n# import pickle\nimport json\nfrom datetime import timedelta\nfrom uuid import uuid4\nfrom redis import Redis\nfrom werkzeug.datastructures import CallbackDict\nfrom flask.sessions import SessionInterface, SessionMixin\n\n\nclass RedisSession(CallbackDict, SessionMixin):\n\n    def __init__(self, initial=None, sid=None, new=False):\n        def on_update(self):\n            self.modified = True\n        CallbackDict.__init__(self, initial, on_update)\n        self.sid = sid\n        self.new = new\n        self.modified = False\n\n\nclass RedisSessionInterface(SessionInterface):\n    # serializer = pickle\n    serializer = json\n    session_class = RedisSession\n\n    def __init__(self, redis=None, prefix='session:', **kwargs):\n        if redis is None:\n            redis = Redis(**kwargs)\n        self.redis = redis\n        self.prefix = prefix\n\n    @staticmethod\n    def generate_sid():\n        return str(uuid4())\n\n    @staticmethod\n    def get_redis_expiration_time(app, session):\n        if session.permanent:\n            return app.permanent_session_lifetime\n        # return timedelta(days=1)\n        return timedelta(minutes=20)\n\n    def open_session(self, app, request):\n        sid = request.cookies.get(app.session_cookie_name)\n        if not sid:\n            sid = self.generate_sid()\n            return self.session_class(sid=sid, new=True)\n        val = self.redis.get(self.prefix + sid)\n        if val is not None:\n            data = self.serializer.loads(val)\n            return self.session_class(data, sid=sid)\n        return self.session_class(sid=sid, new=True)\n\n    def save_session(self, app, session, response):\n        domain = self.get_cookie_domain(app)\n        if not session:\n            self.redis.delete(self.prefix + session.sid)\n            if session.modified:\n                response.delete_cookie(app.session_cookie_name,\n                                       domain=domain)\n            return\n        redis_exp = self.get_redis_expiration_time(app, session)\n        cookie_exp = self.get_expiration_time(app, session)\n        val = self.serializer.dumps(dict(session))\n        self.redis.setex(self.prefix + session.sid, val,\n                         int(redis_exp.total_seconds()))\n        response.set_cookie(app.session_cookie_name, session.sid,\n                            expires=cookie_exp, httponly=True,\n                            domain=domain)\n\n\nif __name__ == '__main__':\n    pass\n"
  },
  {
    "path": "app_frontend/lib/sendcloud.py",
    "content": "#!/usr/bin/env python\n# encoding: utf-8\n\n\"\"\"\n@author: zhanghe\n@software: PyCharm\n@file: sendcloud.py\n@time: 16-5-2 下午12:30\n\"\"\"\n\n\nimport requests\nimport json\n\n\nclass SendCloudClient(object):\n    \"\"\"\n    SendCloud 邮件发送平台\n    以下方法采用 API v2 (区别：请求地址，参数命名规则)\n    link: http://sendcloud.sohu.com/doc/email_v2/\n    仅列出常用接口，实际使用中定制\n    \"\"\"\n    def __init__(self, app=None):\n        \"\"\"\n        初始化应用\n        \"\"\"\n        if app is not None:\n            self._api_key = app.config.get('SENDCLOUD_API_KEY', '')\n            self._api_user = app.config.get('SENDCLOUD_API_USER', '')\n\n    def userinfo_get(self):\n        \"\"\"\n        用户信息 查询\n        \"\"\"\n        api_url = 'http://api.sendcloud.net/apiv2/userinfo/get'\n        params = {\n            'apiUser': self._api_user,\n            'apiKey': self._api_key\n        }\n        return requests.get(api_url, params=params).json()\n\n    def mail_send(self, mail_from, mail_to, mail_subject, mail_html):\n        \"\"\"\n        普通发送\n        \"\"\"\n        api_url = 'http://api.sendcloud.net/apiv2/mail/send'\n        params = {\n            'apiUser': self._api_user,      # API_USER\n            'apiKey': self._api_key,        # API_KEY\n            'from': mail_from,              # 发件人地址\n            'to': mail_to,                  # 收件人地址. 多个地址使用';'分隔\n            'subject': mail_subject,        # 邮件标题\n            'html': mail_html,              # 邮件的内容. 邮件格式为 text/html\n        }\n        return requests.post(api_url, data=params).json()\n\n    def mail_sendtemplate(self, mail_from, xsmtpapi, mail_subject, template_name):\n        \"\"\"\n        模板发送 不用地址列表\n        xsmtpapi = {\n            'to': ['test1@ifaxin.com', 'test2@ifaxin.com'],\n            'sub': {\n                '%name%': ['user1', 'user2'],\n                '%money%': ['1000', '2000'],\n            }\n        }\n        \"\"\"\n        api_url = 'http://api.sendcloud.net/apiv2/mail/sendtemplate'\n        params = {\n            'apiUser': self._api_user,              # API_USER\n            'apiKey': self._api_key,                # API_KEY\n            'from': mail_from,                      # 发件人地址\n            'xsmtpapi': json.dumps(xsmtpapi),       # SMTP 扩展字段\n            'subject': mail_subject,                # 邮件标题\n            'templateInvokeName': template_name,    # 邮件模板调用名称\n        }\n        return requests.post(api_url, data=params).json()\n\n    def label_list(self, query, start=0, limit=100):\n        \"\"\"\n        邮件标签 查询 ( 批量查询 )\n        \"\"\"\n        api_url = 'http://api.sendcloud.net/apiv2/label/list'\n        params = {\n            'apiUser': self._api_user,\n            'apiKey': self._api_key,\n            'query': query,\n            'start': start,\n            'limit': limit\n        }\n        return requests.get(api_url, params=params).json()\n\n    def addresslist_list(self, address, start=0, limit=100):\n        \"\"\"\n        查询地址列表 ( 批量查询 )\n        \"\"\"\n        api_url = 'http://api.sendcloud.net/apiv2/addresslist/list'\n        params = {\n            'apiUser': self._api_user,\n            'apiKey': self._api_key,\n            'address': address,\n            'start': start,\n            'limit': limit\n        }\n        return requests.get(api_url, params=params).json()\n\n\nif __name__ == '__main__':\n    pass\n"
  },
  {
    "path": "app_frontend/lib/session.py",
    "content": "#!/usr/bin/env python\n# encoding: utf-8\n\n\"\"\"\n@author: zhanghe\n@software: PyCharm\n@file: session.py\n@time: 16-8-3 下午5:56\n\"\"\"\n\n\nimport redis\nimport json\nfrom datetime import timedelta\nfrom itsdangerous import TimestampSigner, SignatureExpired, BadTimeSignature\n\n\nredis_client = redis.StrictRedis(host='localhost', port=6379, db=0)\n\n\nclass Session(object):\n    \"\"\"\n    基于redis的会话管理 数据结构：字符串（用户信息序列化）\n    \"\"\"\n    # 定义支持的实体类型\n    entity_name_list = ['web', 'app']\n    # 设置 key 生命周期\n    time_out = 7200\n    ttl = timedelta(seconds=time_out)\n    # 设置签名密钥\n    _sign_key = '121e65bfbc1012625643b21b0a5cecdd'\n\n    def __init__(self, entity_name, prefix='session'):\n        if entity_name not in self.entity_name_list:\n            raise TypeError(u'类型错误')\n        self.entity_name = entity_name\n        self.prefix = prefix\n\n    @staticmethod\n    def generate_sign_key(length=32):\n        \"\"\"\n        生成签名密钥\n        121e65bfbc1012625643b21b0a5cecdd\n        \"\"\"\n        import os\n        import binascii\n        sk = os.urandom(length/2)\n        # print sk\n        # print binascii.b2a_hex(sk)\n        return binascii.b2a_hex(sk)\n\n    def sign(self, session_id):\n        \"\"\"\n        签名 session_id\n        :param session_id: 通常是uuid\n        :return:\n        \"\"\"\n        s = TimestampSigner(self._sign_key)\n        return s.sign(session_id)\n\n    def un_sign(self, sign_session_id):\n        \"\"\"\n        校验签名 session_id\n        :param sign_session_id:\n        :return:\n        \"\"\"\n        s = TimestampSigner(self._sign_key)\n        try:\n            session_id = s.unsign(sign_session_id, max_age=self.time_out)\n            return session_id\n        except SignatureExpired as e:\n            # 处理签名超时\n            raise Exception(e.message)\n        except BadTimeSignature as e:\n            # 处理签名错误\n            raise Exception(e.message)\n\n    def add_item(self, key_id, item):\n        \"\"\"\n        添加 item\n        :param key_id:\n        :param item:\n        :return:0/1\n        \"\"\"\n        key = \"%s:%s:%s\" % (self.prefix, self.entity_name, key_id)\n        return redis_client.set(key, item, ex=self.ttl)\n\n    def get_item(self, key_id):\n        \"\"\"\n        获取 item\n        :param key_id:\n        :return:None/String\n        \"\"\"\n        key = \"%s:%s:%s\" % (self.prefix, self.entity_name, key_id)\n        return redis_client.get(key)\n\n    def del_item(self, key_id):\n        \"\"\"\n        删除 item\n        :param key_id:\n        :return:0/1\n        \"\"\"\n        key = \"%s:%s:%s\" % (self.prefix, self.entity_name, key_id)\n        return redis_client.delete(key)\n\n\ndef test_session():\n    \"\"\"\n    测试\n    a1282b2e1e2791b639f99417e7bbfe74\n    sdf54657dry0wetwete34.CoNfJA.LafZyL4wc77gmry9P7PPjgLGMlw\n    sdf54657dry0wetwete34\n    True\n    {\"province\": \"\\u4e0a\\u6d77\", \"openid\": \"o9XD1weif6-0g_5MvZa7Bx6OkwxA\", \"headimgurl\": \"http://wx.qlogo.cn/mmopen/ALImIJLVKZtPiaaVkcKFR58xpgibiaxabiaStZYcwVNIfz4Tl8VkqzqpV5fKiaibbRGfkY2lDR9SlibQvVm2ClHD6AIhBYQeuy32qaj/0\", \"language\": \"zh_CN\", \"city\": \"\\u95f8\\u5317\", \"privilege\": [], \"country\": \"\\u4e2d\\u56fd\", \"nickname\": \"\\u788eping\\u5b50\", \"sex\": 1}\n    碎ping子\n    \"\"\"\n    session_app = Session('app')\n    print session_app.generate_sign_key()\n    session_id = 'sdf54657dry0wetwete34'\n    session_id_sign = session_app.sign(session_id)\n    print session_id_sign\n    print session_app.un_sign(session_id_sign)\n    user_info = {\n        \"province\": \"上海\",\n        \"openid\": \"o9XD1weif6-0g_5MvZa7Bx6OkwxA\",\n        \"headimgurl\": \"http://wx.qlogo.cn/mmopen/ALImIJLVKZtPiaaVkcKFR58xpgibiaxabiaStZYcwVNIfz4Tl8VkqzqpV5fKiaibbRGfkY2lDR9SlibQvVm2ClHD6AIhBYQeuy32qaj/0\",\n        \"language\": \"zh_CN\",\n        \"city\": \"闸北\",\n        \"privilege\": [],\n        \"country\": \"中国\",\n        \"nickname\": \"碎ping子\",\n        \"sex\": 1\n    }\n    user_info_str = json.dumps(user_info)\n    print session_app.add_item(session_id, user_info_str)\n    user_info_str = session_app.get_item(session_id)\n    print user_info_str\n    print json.loads(user_info_str).get('nickname')\n\n\nif __name__ == '__main__':\n    test_session()\n"
  },
  {
    "path": "app_frontend/lib/sms_chuanglan.py",
    "content": "#!/usr/bin/env python\r\n# encoding: utf-8\r\n\r\n\"\"\"\r\n@author: zhanghe\r\n@software: PyCharm\r\n@file: cart.py\r\n@time: 16-1-27 上午10:27\r\n\"\"\"\r\n\r\n\r\nimport requests\r\n\r\n\r\n# 服务地址\r\nhost = \"sms.253.com\"\r\n\r\n# 端口号\r\nport = 80\r\n\r\n# 版本号\r\nversion = \"v1.1\"\r\n\r\n# 查账户信息的URI\r\nbalance_get_uri = \"/msg/balance\"\r\n\r\n# 智能匹配模版短信接口的URI\r\nsms_send_uri = \"/msg/send\"\r\n\r\n# 创蓝账号\r\nun = \"xxxx\"\r\n\r\n# 创蓝密码\r\npw = \"xxxx\"\r\n\r\n\r\ndef get_user_balance():\r\n    \"\"\"\r\n    取账户余额\r\n    \"\"\"\r\n    url = 'http://%s%s' % (host, balance_get_uri)\r\n    params = {\r\n        'un': un,  # 账号\r\n        'pw': pw,  # 密码\r\n    }\r\n    return requests.get(url, params).text\r\n\r\n\r\ndef send_sms(msg, phone):\r\n    \"\"\"\r\n    接口发短信\r\n    \"\"\"\r\n    url = 'http://%s%s' % (host, sms_send_uri)\r\n    params = {\r\n        'un': un,           # 账号\r\n        'pw': pw,           # 密码\r\n        'msg': msg,         # 消息\r\n        'phone': phone,     # 手机\r\n        'rd': 1,            # 是否需要状态报告\r\n    }\r\n    headers = {\"Content-type\": \"application/x-www-form-urlencoded\", \"Accept\": \"text/plain\"}\r\n    return requests.post(url, data=params, headers=headers, timeout=30).text\r\n\r\n\r\nif __name__ == '__main__':\r\n    user_phone = \"188xxxxxxxx\"\r\n    user_msg = \"【您的签名】您的验证码是1234\"\r\n\r\n    # 查账户余额\r\n    print(get_user_balance())\r\n\r\n    # 调用智能匹配模版接口发短信\r\n    print(send_sms(user_msg, user_phone))\r\n"
  },
  {
    "path": "app_frontend/lib/sms_chuanglan_iso.py",
    "content": "#!/usr/bin/env python\n# encoding: utf-8\n\n\"\"\"\n@author: zhanghe\n@software: PyCharm\n@file: sms_chuanglan_iso.py.py\n@time: 2017/3/3 下午10:03\n\"\"\"\n\n\nimport requests\n\n\nfrom config import current_config\n\nREQUESTS_TIME_OUT = current_config.REQUESTS_TIME_OUT\n\n\nclass SmsChuangLanIsoApi(object):\n    \"\"\"\n    创蓝国际短信接口\n    \"\"\"\n    ISENDURL = 'http://222.73.117.140:8044/mt'  # 单发接口\n    IQUERYURL = 'http://222.73.117.140:8044/bi'  # 查询余额接口\n    BAT_SENDURL = 'http://222.73.117.140:8044/batchmt'  # 群发接口\n\n    ERROR_DICT = {\n        '0': u'提交成功',\n        '101': u'无此用户',\n        '102': u'密码错',\n        '103': u'提交过快（提交速度超过流速限制）',\n        '104': u'系统忙（因平台侧原因，暂时无法处理提交的短信）',\n        '105': u'敏感短信（短信内容包含敏感词）',\n        '106': u'消息长度错（>536或<=0）',\n        '107': u'包含错误的手机号码',\n        '108': u'手机号码个数错（群发>50000或<=0）',\n        '109': u'无发送额度（该用户可用短信数已使用完）',\n        '110': u'不在发送时间内',\n        '113': u'extno格式错（非数字或者长度不对）',\n        '116': u'签名不合法或未带签名（用户必须带签名的前提下）',\n        '117': u'IP地址认证错,请求调用的IP地址不是系统登记的IP地址',\n        '118': u'用户没有相应的发送权限（账号被禁止发送）',\n        '119': u'用户已过期',\n        '120': u'违反放盗用策略(日发限制) --自定义添加',\n        '121': u'必填参数。是否需要状态报告，取值true或false',\n        '122': u'5分钟内相同账号提交相同消息内容过多',\n        '123': u'发送类型错误',\n        '124': u'白模板匹配错误',\n        '125': u'匹配驳回模板，提交失败',\n        '126': u'审核通过模板匹配错误',\n    }\n\n    def __init__(self, account, password):\n        self._sendUrl = ''  # 发送短信接口url\n        self._queryBalanceUrl = ''  # 查询余额接口url\n        self._un = account  # 接口账号\n        self._pw = password  # 接口密码\n\n    def send_international(self, phone, content, is_report=0):\n        \"\"\"\n        发送国际短信\n        :param phone:\n        :param content:\n        :param is_report:\n        :return:\n        \"\"\"\n        params = {\n            'un': self._un,\n            'pw': self._pw,\n            'sm': content,\n            'da': phone,\n            'rd': is_report,\n            'rf': 2,\n            'tf': 3,\n        }\n        result = requests.get(self.ISENDURL, params, timeout=REQUESTS_TIME_OUT or 30).json()\n        return result\n\n    def query_balance_international(self):\n        \"\"\"\n        查询余额\n        :return:\n        \"\"\"\n        params = {\n            'un': self._un,\n            'pw': self._pw,\n            'rf': 2,\n        }\n        result = requests.get(self.IQUERYURL, params, timeout=REQUESTS_TIME_OUT or 30).json()\n        return result\n\n\nif __name__ == '__main__':\n    sms_client = SmsChuangLanIsoApi('接口账号', '接口账号')\n    # print sms_client.send_international('8613800000000', '欢迎您注册九重天会员，此次注册验证码为1234，请在2分钟内进入验证。【九重天】', 1)\n    print sms_client.query_balance_international()\n\n\n\"\"\"\n账号错误：\n{u'r': u'101', u'success': False}\n密码错误：\n{u'r': u'102', u'success': False}\n国内号码不加86，收不到短信，但是返回True\n{u'id': u'17030322181000000859', u'success': True}\n国内号码添加86，收到短信，也返回True\n{u'id': u'17030322211000000868', u'success': True}\n国内错误号码\n\"\"\"\n"
  },
  {
    "path": "app_frontend/lib/token.py",
    "content": "#!/usr/bin/env python\n# encoding: utf-8\n\n\"\"\"\n@author: zhanghe\n@software: PyCharm\n@file: token.py\n@time: 16-4-4 下午9:31\n\"\"\"\n\n\nimport redis\nimport hashlib\nfrom base64 import urlsafe_b64encode, urlsafe_b64decode\nfrom datetime import timedelta\n\n\nredis_client = redis.StrictRedis(host='localhost', port=6379, db=0)\n\n\nclass Token(object):\n    \"\"\"\n    token（数据结构：字符串）\n    应用场景：\n    1）用户id为key, 存储token为值\n    2）用户id为key, 存储验证码为值\n    \"\"\"\n    # 定义支持的实体类型\n    entity_name_list = ['reg', 'login']\n    # 设置 key 生命周期\n    ttl = timedelta(seconds=60)\n    # 设置签名密钥\n    _sign_key = '05bed70ae968e133a86e3ce388f4509838bd7cbf753f01c3'\n\n    def __init__(self, entity_name, prefix='token'):\n        if entity_name not in self.entity_name_list:\n            raise TypeError(u'类型错误')\n        self.entity_name = entity_name\n        self.prefix = prefix\n\n    @staticmethod\n    def generate_sign_key():\n        \"\"\"\n        生成签名密钥\n        05bed70ae968e133a86e3ce388f4509838bd7cbf753f01c3\n        \"\"\"\n        import os\n        import binascii\n        sk = os.urandom(24)\n        # print sk\n        # print binascii.b2a_hex(sk)\n        return binascii.b2a_hex(sk)\n\n    def create_token(self):\n        \"\"\"\n        生成 token (基于 uuid)\n        \"\"\"\n        from uuid import uuid1\n        from itsdangerous import TimestampSigner\n        s = TimestampSigner(self._sign_key)\n        return s.sign(str(uuid1()))\n\n    def check_token(self, token_sign):\n        \"\"\"\n        校验 token, 返回解密后的 token\n        \"\"\"\n        from itsdangerous import TimestampSigner, SignatureExpired, BadTimeSignature\n        s = TimestampSigner(self._sign_key)\n        try:\n            token = s.unsign(token_sign, max_age=60)  # 60秒过期\n            return {'success': token}\n        except SignatureExpired as e:\n            # 处理签名超时\n            return {'error': e.message}\n        except BadTimeSignature as e:\n            # 处理签名错误\n            return {'error': e.message}\n\n    def add_item(self, key_id, item):\n        \"\"\"\n        添加 item\n        :param key_id:\n        :param item:\n        :return:0/1\n        \"\"\"\n        key = \"%s:%s:%s\" % (self.prefix, self.entity_name, key_id)\n        return redis_client.set(key, item, ex=self.ttl)\n\n    def get_item(self, key_id):\n        \"\"\"\n        获取 item\n        :param key_id:\n        :return:None/String\n        \"\"\"\n        key = \"%s:%s:%s\" % (self.prefix, self.entity_name, key_id)\n        return redis_client.get(key)\n\n    def del_item(self, key_id):\n        \"\"\"\n        删除 item\n        :param key_id:\n        :return:0/1\n        \"\"\"\n        key = \"%s:%s:%s\" % (self.prefix, self.entity_name, key_id)\n        return redis_client.delete(key)\n\n\ndef test_token():\n    \"\"\"\n    测试\n    127.0.0.1:6379> get \"token:reg:0020\"\n    \"9B6E\"\n    \"\"\"\n    token_reg = Token('reg')\n    # print token_reg.add_item('0020', '9B6E')\n    print token_reg.get_item('0020')\n    print token_reg.del_item('0021')\n    # print token_reg.del_item('0020')\n\nif __name__ == '__main__':\n    test_token()\n    # print urlsafe_b64encode('05bed70ae968e133a86e3ce388f4509838bd7cbf753f01c3')\n"
  },
  {
    "path": "app_frontend/log_test.py",
    "content": "#!/usr/bin/env python\n# encoding: utf-8\n\n\"\"\"\n@author: zhanghe\n@software: PyCharm\n@file: log_test.py\n@time: 16-4-10 上午12:24\n\"\"\"\n\nfrom config import LOG_CONFIG\nimport logging\nfrom logging.config import dictConfig\n\n# 配置日志\ndictConfig(LOG_CONFIG)\n\n\ndef test_app():\n    \"\"\"\n    测试日志_app\n    \"\"\"\n    log = logging.getLogger('app')\n    log.info('This is a app info!')\n    log.error('This is a app error!')\n\n\ndef test_db():\n    \"\"\"\n    测试日志_db\n    \"\"\"\n    log = logging.getLogger('db')\n    log.info('This is a db info!')\n    log.error('This is a db error!')\n\n\nif __name__ == '__main__':\n    test_app()\n    test_db()\n"
  },
  {
    "path": "app_frontend/login.py",
    "content": "#!/usr/bin/env python\n# encoding: utf-8\n\n\"\"\"\n@author: zhanghe\n@software: PyCharm\n@file: login.py\n@time: 16-1-26 下午6:46\n\"\"\"\n\n\nfrom app_frontend.models import User\nfrom flask_login import UserMixin\n\n\nclass LoginUser(User, UserMixin):\n    \"\"\"\n    用户登录类\n    \"\"\"\n"
  },
  {
    "path": "app_frontend/middlewares.py",
    "content": "#!/usr/bin/env python\n# encoding: utf-8\n\n\"\"\"\n@author: zhanghe\n@software: PyCharm\n@file: middlewares.py\n@time: 2017/4/28 下午1:33\n\"\"\"\n\n\nclass HTTPMethodOverrideMiddleware(object):\n    \"\"\"\n    HTTP Method Middleware\n    http://docs.jinkan.org/docs/flask/patterns/methodoverrides.html\n    \"\"\"\n    allowed_methods = frozenset([\n        'GET',\n        'HEAD',\n        'POST',\n        'DELETE',\n        'PUT',\n        'PATCH',\n        'OPTIONS'\n    ])\n    bodyless_methods = frozenset(['GET', 'HEAD', 'OPTIONS', 'DELETE'])\n\n    def __init__(self, app):\n        self.app = app\n\n    def __call__(self, environ, start_response):\n        method = environ.get('HTTP_X_HTTP_METHOD_OVERRIDE', '').upper()\n        if method in self.allowed_methods:\n            method = method.encode('ascii', 'replace')\n            environ['REQUEST_METHOD'] = method\n        if method in self.bodyless_methods:\n            environ['CONTENT_LENGTH'] = '0'\n        return self.app(environ, start_response)\n"
  },
  {
    "path": "app_frontend/models.py",
    "content": "# coding: utf-8\nfrom sqlalchemy import Column, Date, DateTime, Index, Integer, Numeric, String, text\nfrom database import db\n\n\nBase = db.Model\nmetadata = Base.metadata\n\n\ndef to_dict(self):\n    \"\"\"\n    model 对象转 字典\n    model_obj.to_dict()\n    \"\"\"\n    return {c.name: getattr(self, c.name, None) for c in self.__table__.columns}\n\nBase.to_dict = to_dict\n\n\nclass Active(Base):\n    __tablename__ = 'active'\n\n    user_id = Column(Integer, primary_key=True)\n    amount = Column(Numeric(10, 0), nullable=False, server_default=text(\"'0'\"))\n    create_time = Column(DateTime, nullable=False, server_default=text(\"CURRENT_TIMESTAMP\"))\n    update_time = Column(DateTime, nullable=False, server_default=text(\"CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP\"))\n\n\nclass ActiveItem(Base):\n    __tablename__ = 'active_item'\n\n    id = Column(Integer, primary_key=True)\n    user_id = Column(Integer, nullable=False, index=True)\n    type = Column(Integer, nullable=False, server_default=text(\"'0'\"))\n    amount = Column(Numeric(8, 0), nullable=False, server_default=text(\"'0'\"))\n    sc_id = Column(Integer, nullable=False, index=True, server_default=text(\"'0'\"))\n    note = Column(String(256), nullable=False, server_default=text(\"''\"))\n    status_audit = Column(Integer, nullable=False, server_default=text(\"'0'\"))\n    status_delete = Column(Integer, nullable=False, server_default=text(\"'0'\"))\n    audit_time = Column(DateTime)\n    delete_time = Column(DateTime)\n    create_time = Column(DateTime, nullable=False, server_default=text(\"CURRENT_TIMESTAMP\"))\n    update_time = Column(DateTime, nullable=False, server_default=text(\"CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP\"))\n\n\nclass Admin(Base):\n    __tablename__ = 'admin'\n\n    id = Column(Integer, primary_key=True)\n    username = Column(String(20), nullable=False, unique=True, server_default=text(\"''\"))\n    password = Column(String(60), nullable=False, server_default=text(\"''\"))\n    area_id = Column(Integer, nullable=False, server_default=text(\"'0'\"))\n    area_code = Column(String(4), nullable=False, server_default=text(\"''\"))\n    phone = Column(String(20), nullable=False, server_default=text(\"''\"))\n    role_id = Column(Integer, nullable=False, server_default=text(\"'1'\"))\n    status_delete = Column(Integer, nullable=False, server_default=text(\"'0'\"))\n    delete_time = Column(DateTime)\n    login_time = Column(DateTime)\n    login_ip = Column(String(20))\n    create_time = Column(DateTime, nullable=False, server_default=text(\"CURRENT_TIMESTAMP\"))\n    update_time = Column(DateTime, nullable=False, server_default=text(\"CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP\"))\n\n\nclass AdminRole(Base):\n    __tablename__ = 'admin_role'\n\n    id = Column(Integer, primary_key=True)\n    name = Column(String(20), nullable=False, unique=True, server_default=text(\"''\"))\n    note = Column(String(256), nullable=False, server_default=text(\"''\"))\n    module = Column(String(256), nullable=False, server_default=text(\"''\"))\n    create_time = Column(DateTime, nullable=False, server_default=text(\"CURRENT_TIMESTAMP\"))\n    update_time = Column(DateTime, nullable=False, server_default=text(\"CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP\"))\n\n\nclass ApplyGet(Base):\n    __tablename__ = 'apply_get'\n\n    id = Column(Integer, primary_key=True)\n    user_id = Column(Integer, nullable=False, index=True)\n    type_apply = Column(Integer, nullable=False, server_default=text(\"'0'\"))\n    type_pay = Column(Integer, nullable=False, server_default=text(\"'0'\"))\n    type_withdraw = Column(Integer, nullable=False, server_default=text(\"'0'\"))\n    money_apply = Column(Numeric(8, 2), nullable=False, server_default=text(\"'0.00'\"))\n    money_order = Column(Numeric(8, 2), nullable=False, server_default=text(\"'0.00'\"))\n    status_apply = Column(Integer, nullable=False, server_default=text(\"'0'\"))\n    status_order = Column(Integer, nullable=False, server_default=text(\"'0'\"))\n    status_delete = Column(Integer, nullable=False, server_default=text(\"'0'\"))\n    delete_time = Column(DateTime)\n    create_time = Column(DateTime, nullable=False, server_default=text(\"CURRENT_TIMESTAMP\"))\n    update_time = Column(DateTime, nullable=False, server_default=text(\"CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP\"))\n\n\nclass ApplyPut(Base):\n    __tablename__ = 'apply_put'\n\n    id = Column(Integer, primary_key=True)\n    user_id = Column(Integer, nullable=False, index=True)\n    type_apply = Column(Integer, nullable=False, server_default=text(\"'0'\"))\n    type_pay = Column(Integer, nullable=False, server_default=text(\"'0'\"))\n    money_apply = Column(Numeric(8, 2), nullable=False, server_default=text(\"'0.00'\"))\n    money_order = Column(Numeric(8, 2), nullable=False, server_default=text(\"'0.00'\"))\n    status_apply = Column(Integer, nullable=False, server_default=text(\"'0'\"))\n    status_order = Column(Integer, nullable=False, server_default=text(\"'0'\"))\n    status_delete = Column(Integer, nullable=False, server_default=text(\"'0'\"))\n    delete_time = Column(DateTime)\n    create_time = Column(DateTime, nullable=False, server_default=text(\"CURRENT_TIMESTAMP\"))\n    update_time = Column(DateTime, nullable=False, server_default=text(\"CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP\"))\n\n\nclass AreaCode(Base):\n    __tablename__ = 'area_code'\n\n    id = Column(Integer, primary_key=True)\n    short_code = Column(String(2), nullable=False, server_default=text(\"''\"))\n    area_code = Column(String(4), nullable=False, server_default=text(\"''\"))\n    phone_pre = Column(String(7), nullable=False, server_default=text(\"''\"))\n    name_c = Column(String(20), nullable=False, server_default=text(\"''\"))\n    name_e = Column(String(20), nullable=False, server_default=text(\"''\"))\n    country_area = Column(String(20), nullable=False, server_default=text(\"''\"))\n    create_time = Column(DateTime, nullable=False, server_default=text(\"CURRENT_TIMESTAMP\"))\n    update_time = Column(DateTime, nullable=False, server_default=text(\"CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP\"))\n\n\nclass BitCoin(Base):\n    __tablename__ = 'bit_coin'\n\n    user_id = Column(Integer, primary_key=True)\n    amount = Column(Numeric(10, 2), nullable=False, server_default=text(\"'0.00'\"))\n    create_time = Column(DateTime, nullable=False, server_default=text(\"CURRENT_TIMESTAMP\"))\n    update_time = Column(DateTime, nullable=False, server_default=text(\"CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP\"))\n\n\nclass BitCoinItem(Base):\n    __tablename__ = 'bit_coin_item'\n\n    id = Column(Integer, primary_key=True)\n    user_id = Column(Integer, nullable=False, index=True)\n    type = Column(Integer, nullable=False, server_default=text(\"'0'\"))\n    amount = Column(Numeric(8, 2), nullable=False, server_default=text(\"'0.00'\"))\n    sc_id = Column(Integer, nullable=False, index=True, server_default=text(\"'0'\"))\n    note = Column(String(256), nullable=False, server_default=text(\"''\"))\n    status_audit = Column(Integer, nullable=False, server_default=text(\"'0'\"))\n    status_delete = Column(Integer, nullable=False, server_default=text(\"'0'\"))\n    audit_time = Column(DateTime)\n    delete_time = Column(DateTime)\n    create_time = Column(DateTime, nullable=False, server_default=text(\"CURRENT_TIMESTAMP\"))\n    update_time = Column(DateTime, nullable=False, server_default=text(\"CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP\"))\n\n\nclass Bonus(Base):\n    __tablename__ = 'bonus'\n\n    user_id = Column(Integer, primary_key=True)\n    amount = Column(Numeric(10, 2), nullable=False, server_default=text(\"'0.00'\"))\n    create_time = Column(DateTime, nullable=False, server_default=text(\"CURRENT_TIMESTAMP\"))\n    update_time = Column(DateTime, nullable=False, server_default=text(\"CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP\"))\n\n\nclass BonusItem(Base):\n    __tablename__ = 'bonus_item'\n\n    id = Column(Integer, primary_key=True)\n    user_id = Column(Integer, nullable=False, index=True)\n    type = Column(Integer, nullable=False, server_default=text(\"'0'\"))\n    amount = Column(Numeric(8, 2), nullable=False, server_default=text(\"'0.00'\"))\n    sc_id = Column(Integer, nullable=False, index=True, server_default=text(\"'0'\"))\n    note = Column(String(256), nullable=False, server_default=text(\"''\"))\n    status_audit = Column(Integer, nullable=False, server_default=text(\"'0'\"))\n    status_delete = Column(Integer, nullable=False, server_default=text(\"'0'\"))\n    audit_time = Column(DateTime)\n    delete_time = Column(DateTime)\n    create_time = Column(DateTime, nullable=False, server_default=text(\"CURRENT_TIMESTAMP\"))\n    update_time = Column(DateTime, nullable=False, server_default=text(\"CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP\"))\n\n\nclass Complaint(Base):\n    __tablename__ = 'complaint'\n\n    id = Column(Integer, primary_key=True)\n    send_user_id = Column(Integer, nullable=False, index=True)\n    receive_user_id = Column(Integer, nullable=False, index=True)\n    reply_admin_id = Column(Integer, nullable=False, index=True, server_default=text(\"'0'\"))\n    content = Column(String(512), nullable=False, server_default=text(\"''\"))\n    content_reply = Column(String(512), nullable=False, server_default=text(\"''\"))\n    status_reply = Column(Integer, nullable=False, server_default=text(\"'0'\"))\n    reply_time = Column(DateTime)\n    status_delete = Column(Integer, nullable=False, server_default=text(\"'0'\"))\n    delete_time = Column(DateTime)\n    create_time = Column(DateTime, nullable=False, server_default=text(\"CURRENT_TIMESTAMP\"))\n    update_time = Column(DateTime, nullable=False, server_default=text(\"CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP\"))\n\n\nclass Credit(Base):\n    __tablename__ = 'credit'\n\n    user_id = Column(Integer, primary_key=True)\n    behavior = Column(Numeric(3, 0), nullable=False, server_default=text(\"'0'\"))\n    characteristics = Column(Numeric(3, 0), nullable=False, server_default=text(\"'0'\"))\n    connections = Column(Numeric(3, 0), nullable=False, server_default=text(\"'0'\"))\n    history = Column(Numeric(3, 0), nullable=False, server_default=text(\"'0'\"))\n    performance = Column(Numeric(3, 0), nullable=False, server_default=text(\"'0'\"))\n    credit = Column(Numeric(3, 0), nullable=False, server_default=text(\"'0'\"))\n    create_time = Column(DateTime, nullable=False, server_default=text(\"CURRENT_TIMESTAMP\"))\n    update_time = Column(DateTime, nullable=False, server_default=text(\"CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP\"))\n\n\nclass Message(Base):\n    __tablename__ = 'message'\n\n    id = Column(Integer, primary_key=True)\n    send_user_id = Column(Integer, nullable=False, index=True)\n    receive_user_id = Column(Integer, nullable=False, index=True)\n    content = Column(String(512), nullable=False, server_default=text(\"''\"))\n    status_delete = Column(Integer, nullable=False, server_default=text(\"'0'\"))\n    delete_time = Column(DateTime)\n    create_time = Column(DateTime, nullable=False, server_default=text(\"CURRENT_TIMESTAMP\"))\n    update_time = Column(DateTime, nullable=False, server_default=text(\"CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP\"))\n\n\nclass Order(Base):\n    __tablename__ = 'order'\n\n    id = Column(Integer, primary_key=True)\n    apply_put_id = Column(Integer, nullable=False, index=True)\n    apply_get_id = Column(Integer, nullable=False, index=True)\n    apply_put_uid = Column(Integer, nullable=False, index=True)\n    apply_get_uid = Column(Integer, nullable=False, index=True)\n    type = Column(Integer, nullable=False, server_default=text(\"'0'\"))\n    money = Column(Numeric(8, 2), nullable=False, server_default=text(\"'0.00'\"))\n    status_audit = Column(Integer, nullable=False, server_default=text(\"'0'\"))\n    status_flow = Column(Integer, nullable=False, server_default=text(\"'0'\"))\n    status_pay = Column(Integer, nullable=False, server_default=text(\"'0'\"))\n    status_rec = Column(Integer, nullable=False, server_default=text(\"'0'\"))\n    status_delete = Column(Integer, nullable=False, server_default=text(\"'0'\"))\n    audit_time = Column(DateTime)\n    pay_time = Column(DateTime)\n    rec_time = Column(DateTime)\n    delete_time = Column(DateTime)\n    create_time = Column(DateTime, nullable=False, server_default=text(\"CURRENT_TIMESTAMP\"))\n    update_time = Column(DateTime, nullable=False, server_default=text(\"CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP\"))\n\n\nclass OrderBill(Base):\n    __tablename__ = 'order_bill'\n\n    id = Column(Integer, primary_key=True)\n    order_id = Column(Integer, nullable=False, index=True)\n    bill_img = Column(String(255))\n    status_audit = Column(Integer, nullable=False, server_default=text(\"'0'\"))\n    status_delete = Column(Integer, nullable=False, server_default=text(\"'0'\"))\n    audit_time = Column(DateTime)\n    delete_time = Column(DateTime)\n    create_time = Column(DateTime, nullable=False, server_default=text(\"CURRENT_TIMESTAMP\"))\n    update_time = Column(DateTime, nullable=False, server_default=text(\"CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP\"))\n\n\nclass OrderFlow(Base):\n    __tablename__ = 'order_flow'\n\n    order_id = Column(Integer, primary_key=True)\n    flow_order_id = Column(Integer, nullable=False, index=True)\n    apply_put_id = Column(Integer, nullable=False, index=True)\n    apply_get_id = Column(Integer, nullable=False, index=True)\n    apply_put_uid = Column(Integer, nullable=False, index=True)\n    apply_get_uid = Column(Integer, nullable=False, index=True)\n    create_time = Column(DateTime, nullable=False, server_default=text(\"CURRENT_TIMESTAMP\"))\n    update_time = Column(DateTime, nullable=False, server_default=text(\"CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP\"))\n\n\nclass Scheduling(Base):\n    __tablename__ = 'scheduling'\n\n    user_id = Column(Integer, primary_key=True)\n    amount = Column(Numeric(10, 2), nullable=False, server_default=text(\"'0.00'\"))\n    create_time = Column(DateTime, nullable=False, server_default=text(\"CURRENT_TIMESTAMP\"))\n    update_time = Column(DateTime, nullable=False, server_default=text(\"CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP\"))\n\n\nclass SchedulingItem(Base):\n    __tablename__ = 'scheduling_item'\n\n    id = Column(Integer, primary_key=True)\n    user_id = Column(Integer, nullable=False, index=True)\n    type = Column(Integer, nullable=False, server_default=text(\"'0'\"))\n    amount = Column(Numeric(8, 2), nullable=False, server_default=text(\"'0.00'\"))\n    sc_id = Column(Integer, nullable=False, index=True, server_default=text(\"'0'\"))\n    note = Column(String(256), nullable=False, server_default=text(\"''\"))\n    status_audit = Column(Integer, nullable=False, server_default=text(\"'0'\"))\n    status_delete = Column(Integer, nullable=False, server_default=text(\"'0'\"))\n    audit_time = Column(DateTime)\n    delete_time = Column(DateTime)\n    create_time = Column(DateTime, nullable=False, server_default=text(\"CURRENT_TIMESTAMP\"))\n    update_time = Column(DateTime, nullable=False, server_default=text(\"CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP\"))\n\n\nclass Score(Base):\n    __tablename__ = 'score'\n\n    user_id = Column(Integer, primary_key=True)\n    amount = Column(Numeric(10, 2), nullable=False, server_default=text(\"'0.00'\"))\n    create_time = Column(DateTime, nullable=False, server_default=text(\"CURRENT_TIMESTAMP\"))\n    update_time = Column(DateTime, nullable=False, server_default=text(\"CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP\"))\n\n\nclass ScoreCharity(Base):\n    __tablename__ = 'score_charity'\n\n    user_id = Column(Integer, primary_key=True)\n    amount = Column(Numeric(10, 2), nullable=False, server_default=text(\"'0.00'\"))\n    create_time = Column(DateTime, nullable=False, server_default=text(\"CURRENT_TIMESTAMP\"))\n    update_time = Column(DateTime, nullable=False, server_default=text(\"CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP\"))\n\n\nclass ScoreCharityItem(Base):\n    __tablename__ = 'score_charity_item'\n\n    id = Column(Integer, primary_key=True)\n    user_id = Column(Integer, nullable=False, index=True)\n    type = Column(Integer, nullable=False, server_default=text(\"'0'\"))\n    amount = Column(Numeric(8, 2), nullable=False, server_default=text(\"'0.00'\"))\n    sc_id = Column(Integer, nullable=False, index=True, server_default=text(\"'0'\"))\n    note = Column(String(256), nullable=False, server_default=text(\"''\"))\n    status_audit = Column(Integer, nullable=False, server_default=text(\"'0'\"))\n    status_delete = Column(Integer, nullable=False, server_default=text(\"'0'\"))\n    audit_time = Column(DateTime)\n    delete_time = Column(DateTime)\n    create_time = Column(DateTime, nullable=False, server_default=text(\"CURRENT_TIMESTAMP\"))\n    update_time = Column(DateTime, nullable=False, server_default=text(\"CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP\"))\n\n\nclass ScoreDigital(Base):\n    __tablename__ = 'score_digital'\n\n    user_id = Column(Integer, primary_key=True)\n    amount = Column(Numeric(10, 2), nullable=False, server_default=text(\"'0.00'\"))\n    create_time = Column(DateTime, nullable=False, server_default=text(\"CURRENT_TIMESTAMP\"))\n    update_time = Column(DateTime, nullable=False, server_default=text(\"CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP\"))\n\n\nclass ScoreDigitalItem(Base):\n    __tablename__ = 'score_digital_item'\n\n    id = Column(Integer, primary_key=True)\n    user_id = Column(Integer, nullable=False, index=True)\n    type = Column(Integer, nullable=False, server_default=text(\"'0'\"))\n    amount = Column(Numeric(8, 2), nullable=False, server_default=text(\"'0.00'\"))\n    sc_id = Column(Integer, nullable=False, index=True, server_default=text(\"'0'\"))\n    note = Column(String(256), nullable=False, server_default=text(\"''\"))\n    status_audit = Column(Integer, nullable=False, server_default=text(\"'0'\"))\n    status_delete = Column(Integer, nullable=False, server_default=text(\"'0'\"))\n    audit_time = Column(DateTime)\n    delete_time = Column(DateTime)\n    create_time = Column(DateTime, nullable=False, server_default=text(\"CURRENT_TIMESTAMP\"))\n    update_time = Column(DateTime, nullable=False, server_default=text(\"CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP\"))\n\n\nclass ScoreExpense(Base):\n    __tablename__ = 'score_expense'\n\n    user_id = Column(Integer, primary_key=True)\n    amount = Column(Numeric(10, 2), nullable=False, server_default=text(\"'0.00'\"))\n    create_time = Column(DateTime, nullable=False, server_default=text(\"CURRENT_TIMESTAMP\"))\n    update_time = Column(DateTime, nullable=False, server_default=text(\"CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP\"))\n\n\nclass ScoreExpenseItem(Base):\n    __tablename__ = 'score_expense_item'\n\n    id = Column(Integer, primary_key=True)\n    user_id = Column(Integer, nullable=False, index=True)\n    type = Column(Integer, nullable=False, server_default=text(\"'0'\"))\n    amount = Column(Numeric(8, 2), nullable=False, server_default=text(\"'0.00'\"))\n    sc_id = Column(Integer, nullable=False, index=True, server_default=text(\"'0'\"))\n    note = Column(String(256), nullable=False, server_default=text(\"''\"))\n    status_audit = Column(Integer, nullable=False, server_default=text(\"'0'\"))\n    status_delete = Column(Integer, nullable=False, server_default=text(\"'0'\"))\n    audit_time = Column(DateTime)\n    delete_time = Column(DateTime)\n    create_time = Column(DateTime, nullable=False, server_default=text(\"CURRENT_TIMESTAMP\"))\n    update_time = Column(DateTime, nullable=False, server_default=text(\"CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP\"))\n\n\nclass ScoreItem(Base):\n    __tablename__ = 'score_item'\n\n    id = Column(Integer, primary_key=True)\n    user_id = Column(Integer, nullable=False, index=True)\n    type = Column(Integer, nullable=False, server_default=text(\"'0'\"))\n    amount = Column(Numeric(8, 2), nullable=False, server_default=text(\"'0.00'\"))\n    sc_id = Column(Integer, nullable=False, index=True, server_default=text(\"'0'\"))\n    note = Column(String(256), nullable=False, server_default=text(\"''\"))\n    status_audit = Column(Integer, nullable=False, server_default=text(\"'0'\"))\n    status_delete = Column(Integer, nullable=False, server_default=text(\"'0'\"))\n    audit_time = Column(DateTime)\n    delete_time = Column(DateTime)\n    create_time = Column(DateTime, nullable=False, server_default=text(\"CURRENT_TIMESTAMP\"))\n    update_time = Column(DateTime, nullable=False, server_default=text(\"CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP\"))\n\n\nclass User(Base):\n    __tablename__ = 'user'\n\n    id = Column(Integer, primary_key=True)\n    status_active = Column(Integer, nullable=False, server_default=text(\"'0'\"))\n    status_lock = Column(Integer, nullable=False, server_default=text(\"'0'\"))\n    status_real_name = Column(Integer, nullable=False, server_default=text(\"'0'\"))\n    status_delete = Column(Integer, nullable=False, server_default=text(\"'0'\"))\n    active_time = Column(DateTime)\n    lock_time = Column(DateTime)\n    delete_time = Column(DateTime)\n    reg_ip = Column(String(20))\n    login_ip = Column(String(20))\n    login_time = Column(DateTime)\n    create_time = Column(DateTime, nullable=False, server_default=text(\"CURRENT_TIMESTAMP\"))\n    update_time = Column(DateTime, nullable=False, server_default=text(\"CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP\"))\n\n\nclass UserAuth(Base):\n    __tablename__ = 'user_auth'\n    __table_args__ = (\n        Index('type_auth', 'type_auth', 'auth_key', unique=True),\n    )\n\n    id = Column(Integer, primary_key=True)\n    user_id = Column(Integer, nullable=False, index=True, server_default=text(\"'0'\"))\n    type_auth = Column(Integer, nullable=False, server_default=text(\"'0'\"))\n    auth_key = Column(String(60), nullable=False, server_default=text(\"''\"))\n    auth_secret = Column(String(60), nullable=False, server_default=text(\"''\"))\n    status_verified = Column(Integer, nullable=False, server_default=text(\"'0'\"))\n    create_time = Column(DateTime, nullable=False, server_default=text(\"CURRENT_TIMESTAMP\"))\n    update_time = Column(DateTime, nullable=False, server_default=text(\"CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP\"))\n\n\nclass UserBank(Base):\n    __tablename__ = 'user_bank'\n\n    user_id = Column(Integer, primary_key=True)\n    account_name = Column(String(60), nullable=False, server_default=text(\"'0'\"))\n    bank_name = Column(String(60), nullable=False, server_default=text(\"''\"))\n    bank_address = Column(String(60), nullable=False, server_default=text(\"''\"))\n    bank_account = Column(String(32), nullable=False, server_default=text(\"''\"))\n    status_verified = Column(Integer, nullable=False, server_default=text(\"'0'\"))\n    status_delete = Column(Integer, nullable=False, server_default=text(\"'0'\"))\n    create_time = Column(DateTime, nullable=False, server_default=text(\"CURRENT_TIMESTAMP\"))\n    update_time = Column(DateTime, nullable=False, server_default=text(\"CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP\"))\n\n\nclass UserConfig(Base):\n    __tablename__ = 'user_config'\n\n    user_id = Column(Integer, primary_key=True)\n    team_bonus = Column(String(100), server_default=text(\"''\"))\n    create_time = Column(DateTime, nullable=False, server_default=text(\"CURRENT_TIMESTAMP\"))\n    update_time = Column(DateTime, nullable=False, server_default=text(\"CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP\"))\n\n\nclass UserProfile(Base):\n    __tablename__ = 'user_profile'\n    __table_args__ = (\n        Index('ind_phone', 'area_id', 'phone'),\n        Index('ind_id_card', 'area_id', 'id_card')\n    )\n\n    user_id = Column(Integer, primary_key=True)\n    user_pid = Column(Integer, nullable=False, server_default=text(\"'0'\"))\n    nickname = Column(String(20), nullable=False, server_default=text(\"''\"))\n    type_level = Column(Integer, nullable=False, server_default=text(\"'0'\"))\n    avatar_url = Column(String(60))\n    email = Column(String(60), nullable=False, server_default=text(\"''\"))\n    area_id = Column(Integer, nullable=False, server_default=text(\"'0'\"))\n    area_code = Column(String(4), nullable=False, server_default=text(\"''\"))\n    phone = Column(String(20), nullable=False, server_default=text(\"''\"))\n    birthday = Column(Date, nullable=False, server_default=text(\"'1900-01-01'\"))\n    real_name = Column(String(20), nullable=False, server_default=text(\"''\"))\n    id_card = Column(String(32), nullable=False, server_default=text(\"''\"))\n    create_time = Column(DateTime, nullable=False, server_default=text(\"CURRENT_TIMESTAMP\"))\n    update_time = Column(DateTime, nullable=False, server_default=text(\"CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP\"))\n\n\nclass Wallet(Base):\n    __tablename__ = 'wallet'\n\n    user_id = Column(Integer, primary_key=True)\n    amount_initial = Column(Numeric(10, 2), nullable=False, server_default=text(\"'0.00'\"))\n    amount_current = Column(Numeric(10, 2), nullable=False, server_default=text(\"'0.00'\"))\n    amount_lock = Column(Numeric(10, 2), nullable=False, server_default=text(\"'0.00'\"))\n    create_time = Column(DateTime, nullable=False, server_default=text(\"CURRENT_TIMESTAMP\"))\n    update_time = Column(DateTime, nullable=False, server_default=text(\"CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP\"))\n\n\nclass WalletItem(Base):\n    __tablename__ = 'wallet_item'\n\n    id = Column(Integer, primary_key=True)\n    user_id = Column(Integer, nullable=False, index=True)\n    type = Column(Integer, nullable=False, server_default=text(\"'0'\"))\n    amount = Column(Numeric(8, 2), nullable=False, server_default=text(\"'0.00'\"))\n    sc_id = Column(Integer, nullable=False, index=True, server_default=text(\"'0'\"))\n    note = Column(String(256), nullable=False, server_default=text(\"''\"))\n    status_audit = Column(Integer, nullable=False, server_default=text(\"'0'\"))\n    status_delete = Column(Integer, nullable=False, server_default=text(\"'0'\"))\n    audit_time = Column(DateTime)\n    delete_time = Column(DateTime)\n    create_time = Column(DateTime, nullable=False, server_default=text(\"CURRENT_TIMESTAMP\"))\n    update_time = Column(DateTime, nullable=False, server_default=text(\"CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP\"))\n"
  },
  {
    "path": "app_frontend/models_sqlite.py",
    "content": "# coding: utf-8\nfrom sqlalchemy import Column, Date, DateTime, Integer, String, Table, text\nfrom sqlalchemy.sql.sqltypes import NullType\nfrom database import db\n\n\nBase = db.Model\nmetadata = Base.metadata\n\n\ndef to_dict(self):\n    \"\"\"\n    model 对象转 字典\n    model_obj.to_dict()\n    \"\"\"\n    return {c.name: getattr(self, c.name, None) for c in self.__table__.columns}\n\nBase.to_dict = to_dict\n\n\nclass Author(Base):\n    __tablename__ = 'author'\n\n    id = Column(Integer, primary_key=True)\n    name = Column(String(20), nullable=False)\n    email = Column(String(20), nullable=False)\n\n\nclass Blog(Base):\n    __tablename__ = 'blog'\n\n    id = Column(Integer, primary_key=True)\n    author = Column(String(20), nullable=False)\n    title = Column(String(40), nullable=False)\n    pub_date = Column(Date)\n    add_time = Column(DateTime, server_default=text(\"CURRENT_TIMESTAMP\"))\n    edit_time = Column(DateTime, server_default=text(\"CURRENT_TIMESTAMP\"))\n\n\nt_sqlite_sequence = Table(\n    'sqlite_sequence', metadata,\n    Column('name', NullType),\n    Column('seq', NullType)\n)\n\n\nclass User(Base):\n    __tablename__ = 'user'\n\n    id = Column(Integer, primary_key=True)\n    nickname = Column(String(20))\n    avatar_url = Column(String(80))\n    email = Column(String(20))\n    phone = Column(String(20))\n    birthday = Column(Date)\n    create_time = Column(DateTime, nullable=False, server_default=text(\"CURRENT_TIMESTAMP\"))\n    update_time = Column(DateTime, nullable=False, server_default=text(\"CURRENT_TIMESTAMP\"))\n    last_ip = Column(String(15))\n\n\nclass UserAuth(Base):\n    __tablename__ = 'user_auth'\n\n    id = Column(Integer, primary_key=True)\n    user_id = Column(Integer, nullable=False)\n    auth_type = Column(String(20), nullable=False)\n    auth_key = Column(String(64), nullable=False)\n    auth_secret = Column(String(256), nullable=False)\n    verified = Column(Integer, server_default=text(\"0\"))\n"
  },
  {
    "path": "app_frontend/static/css/bootstrap-select.css",
    "content": "/*!\r\n * Bootstrap-select v1.12.2 (http://silviomoreto.github.io/bootstrap-select)\r\n *\r\n * Copyright 2013-2017 bootstrap-select\r\n * Licensed under MIT (https://github.com/silviomoreto/bootstrap-select/blob/master/LICENSE)\r\n */\r\n\r\nselect.bs-select-hidden,\nselect.selectpicker {\n  display: none !important;\n}\n.bootstrap-select {\n  width: 220px \\0;\n  /*IE9 and below*/\n}\n.bootstrap-select > .dropdown-toggle {\n  width: 100%;\n  padding-right: 25px;\n  z-index: 1;\n}\n.bootstrap-select > .dropdown-toggle.bs-placeholder,\n.bootstrap-select > .dropdown-toggle.bs-placeholder:hover,\n.bootstrap-select > .dropdown-toggle.bs-placeholder:focus,\n.bootstrap-select > .dropdown-toggle.bs-placeholder:active {\n  color: #999;\n}\n.bootstrap-select > select {\n  position: absolute !important;\n  bottom: 0;\n  left: 50%;\n  display: block !important;\n  width: 0.5px !important;\n  height: 100% !important;\n  padding: 0 !important;\n  opacity: 0 !important;\n  border: none;\n}\n.bootstrap-select > select.mobile-device {\n  top: 0;\n  left: 0;\n  display: block !important;\n  width: 100% !important;\n  z-index: 2;\n}\n.has-error .bootstrap-select .dropdown-toggle,\n.error .bootstrap-select .dropdown-toggle {\n  border-color: #b94a48;\n}\n.bootstrap-select.fit-width {\n  width: auto !important;\n}\n.bootstrap-select:not([class*=\"col-\"]):not([class*=\"form-control\"]):not(.input-group-btn) {\n  width: 220px;\n}\n.bootstrap-select .dropdown-toggle:focus {\n  outline: thin dotted #333333 !important;\n  outline: 5px auto -webkit-focus-ring-color !important;\n  outline-offset: -2px;\n}\n.bootstrap-select.form-control {\n  margin-bottom: 0;\n  padding: 0;\n  border: none;\n}\n.bootstrap-select.form-control:not([class*=\"col-\"]) {\n  width: 100%;\n}\n.bootstrap-select.form-control.input-group-btn {\n  z-index: auto;\n}\n.bootstrap-select.form-control.input-group-btn:not(:first-child):not(:last-child) > .btn {\n  border-radius: 0;\n}\n.bootstrap-select.btn-group:not(.input-group-btn),\n.bootstrap-select.btn-group[class*=\"col-\"] {\n  float: none;\n  display: inline-block;\n  margin-left: 0;\n}\n.bootstrap-select.btn-group.dropdown-menu-right,\n.bootstrap-select.btn-group[class*=\"col-\"].dropdown-menu-right,\n.row .bootstrap-select.btn-group[class*=\"col-\"].dropdown-menu-right {\n  float: right;\n}\n.form-inline .bootstrap-select.btn-group,\n.form-horizontal .bootstrap-select.btn-group,\n.form-group .bootstrap-select.btn-group {\n  margin-bottom: 0;\n}\n.form-group-lg .bootstrap-select.btn-group.form-control,\n.form-group-sm .bootstrap-select.btn-group.form-control {\n  padding: 0;\n}\n.form-group-lg .bootstrap-select.btn-group.form-control .dropdown-toggle,\n.form-group-sm .bootstrap-select.btn-group.form-control .dropdown-toggle {\n  height: 100%;\n  font-size: inherit;\n  line-height: inherit;\n  border-radius: inherit;\n}\n.form-inline .bootstrap-select.btn-group .form-control {\n  width: 100%;\n}\n.bootstrap-select.btn-group.disabled,\n.bootstrap-select.btn-group > .disabled {\n  cursor: not-allowed;\n}\n.bootstrap-select.btn-group.disabled:focus,\n.bootstrap-select.btn-group > .disabled:focus {\n  outline: none !important;\n}\n.bootstrap-select.btn-group.bs-container {\n  position: absolute;\n  height: 0 !important;\n  padding: 0 !important;\n}\n.bootstrap-select.btn-group.bs-container .dropdown-menu {\n  z-index: 1060;\n}\n.bootstrap-select.btn-group .dropdown-toggle .filter-option {\n  display: inline-block;\n  overflow: hidden;\n  width: 100%;\n  text-align: left;\n}\n.bootstrap-select.btn-group .dropdown-toggle .caret {\n  position: absolute;\n  top: 50%;\n  right: 12px;\n  margin-top: -2px;\n  vertical-align: middle;\n}\n.bootstrap-select.btn-group[class*=\"col-\"] .dropdown-toggle {\n  width: 100%;\n}\n.bootstrap-select.btn-group .dropdown-menu {\n  min-width: 100%;\n  -webkit-box-sizing: border-box;\n     -moz-box-sizing: border-box;\n          box-sizing: border-box;\n}\n.bootstrap-select.btn-group .dropdown-menu.inner {\n  position: static;\n  float: none;\n  border: 0;\n  padding: 0;\n  margin: 0;\n  border-radius: 0;\n  -webkit-box-shadow: none;\n          box-shadow: none;\n}\n.bootstrap-select.btn-group .dropdown-menu li {\n  position: relative;\n}\n.bootstrap-select.btn-group .dropdown-menu li.active small {\n  color: #fff;\n}\n.bootstrap-select.btn-group .dropdown-menu li.disabled a {\n  cursor: not-allowed;\n}\n.bootstrap-select.btn-group .dropdown-menu li a {\n  cursor: pointer;\n  -webkit-user-select: none;\n     -moz-user-select: none;\n      -ms-user-select: none;\n          user-select: none;\n}\n.bootstrap-select.btn-group .dropdown-menu li a.opt {\n  position: relative;\n  padding-left: 2.25em;\n}\n.bootstrap-select.btn-group .dropdown-menu li a span.check-mark {\n  display: none;\n}\n.bootstrap-select.btn-group .dropdown-menu li a span.text {\n  display: inline-block;\n}\n.bootstrap-select.btn-group .dropdown-menu li small {\n  padding-left: 0.5em;\n}\n.bootstrap-select.btn-group .dropdown-menu .notify {\n  position: absolute;\n  bottom: 5px;\n  width: 96%;\n  margin: 0 2%;\n  min-height: 26px;\n  padding: 3px 5px;\n  background: #f5f5f5;\n  border: 1px solid #e3e3e3;\n  -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.05);\n          box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.05);\n  pointer-events: none;\n  opacity: 0.9;\n  -webkit-box-sizing: border-box;\n     -moz-box-sizing: border-box;\n          box-sizing: border-box;\n}\n.bootstrap-select.btn-group .no-results {\n  padding: 3px;\n  background: #f5f5f5;\n  margin: 0 5px;\n  white-space: nowrap;\n}\n.bootstrap-select.btn-group.fit-width .dropdown-toggle .filter-option {\n  position: static;\n}\n.bootstrap-select.btn-group.fit-width .dropdown-toggle .caret {\n  position: static;\n  top: auto;\n  margin-top: -1px;\n}\n.bootstrap-select.btn-group.show-tick .dropdown-menu li.selected a span.check-mark {\n  position: absolute;\n  display: inline-block;\n  right: 15px;\n  margin-top: 5px;\n}\n.bootstrap-select.btn-group.show-tick .dropdown-menu li a span.text {\n  margin-right: 34px;\n}\n.bootstrap-select.show-menu-arrow.open > .dropdown-toggle {\n  z-index: 1061;\n}\n.bootstrap-select.show-menu-arrow .dropdown-toggle:before {\n  content: '';\n  border-left: 7px solid transparent;\n  border-right: 7px solid transparent;\n  border-bottom: 7px solid rgba(204, 204, 204, 0.2);\n  position: absolute;\n  bottom: -4px;\n  left: 9px;\n  display: none;\n}\n.bootstrap-select.show-menu-arrow .dropdown-toggle:after {\n  content: '';\n  border-left: 6px solid transparent;\n  border-right: 6px solid transparent;\n  border-bottom: 6px solid white;\n  position: absolute;\n  bottom: -4px;\n  left: 10px;\n  display: none;\n}\n.bootstrap-select.show-menu-arrow.dropup .dropdown-toggle:before {\n  bottom: auto;\n  top: -3px;\n  border-top: 7px solid rgba(204, 204, 204, 0.2);\n  border-bottom: 0;\n}\n.bootstrap-select.show-menu-arrow.dropup .dropdown-toggle:after {\n  bottom: auto;\n  top: -3px;\n  border-top: 6px solid white;\n  border-bottom: 0;\n}\n.bootstrap-select.show-menu-arrow.pull-right .dropdown-toggle:before {\n  right: 12px;\n  left: auto;\n}\n.bootstrap-select.show-menu-arrow.pull-right .dropdown-toggle:after {\n  right: 13px;\n  left: auto;\n}\n.bootstrap-select.show-menu-arrow.open > .dropdown-toggle:before,\n.bootstrap-select.show-menu-arrow.open > .dropdown-toggle:after {\n  display: block;\n}\n.bs-searchbox,\n.bs-actionsbox,\n.bs-donebutton {\n  padding: 4px 8px;\n}\n.bs-actionsbox {\n  width: 100%;\n  -webkit-box-sizing: border-box;\n     -moz-box-sizing: border-box;\n          box-sizing: border-box;\n}\n.bs-actionsbox .btn-group button {\n  width: 50%;\n}\n.bs-donebutton {\n  float: left;\n  width: 100%;\n  -webkit-box-sizing: border-box;\n     -moz-box-sizing: border-box;\n          box-sizing: border-box;\n}\n.bs-donebutton .btn-group button {\n  width: 100%;\n}\n.bs-searchbox + .bs-actionsbox {\n  padding: 0 8px 4px;\n}\n.bs-searchbox .form-control {\n  margin-bottom: 0;\n  width: 100%;\n  float: none;\n}\n/*# sourceMappingURL=bootstrap-select.css.map */"
  },
  {
    "path": "app_frontend/static/css/bootstrap-theme.css",
    "content": "/*!\n * Bootstrap v3.3.5 (http://getbootstrap.com)\n * Copyright 2011-2015 Twitter, Inc.\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)\n */\n.btn-default,\n.btn-primary,\n.btn-success,\n.btn-info,\n.btn-warning,\n.btn-danger {\n  text-shadow: 0 -1px 0 rgba(0, 0, 0, .2);\n  -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, .15), 0 1px 1px rgba(0, 0, 0, .075);\n          box-shadow: inset 0 1px 0 rgba(255, 255, 255, .15), 0 1px 1px rgba(0, 0, 0, .075);\n}\n.btn-default:active,\n.btn-primary:active,\n.btn-success:active,\n.btn-info:active,\n.btn-warning:active,\n.btn-danger:active,\n.btn-default.active,\n.btn-primary.active,\n.btn-success.active,\n.btn-info.active,\n.btn-warning.active,\n.btn-danger.active {\n  -webkit-box-shadow: inset 0 3px 5px rgba(0, 0, 0, .125);\n          box-shadow: inset 0 3px 5px rgba(0, 0, 0, .125);\n}\n.btn-default.disabled,\n.btn-primary.disabled,\n.btn-success.disabled,\n.btn-info.disabled,\n.btn-warning.disabled,\n.btn-danger.disabled,\n.btn-default[disabled],\n.btn-primary[disabled],\n.btn-success[disabled],\n.btn-info[disabled],\n.btn-warning[disabled],\n.btn-danger[disabled],\nfieldset[disabled] .btn-default,\nfieldset[disabled] .btn-primary,\nfieldset[disabled] .btn-success,\nfieldset[disabled] .btn-info,\nfieldset[disabled] .btn-warning,\nfieldset[disabled] .btn-danger {\n  -webkit-box-shadow: none;\n          box-shadow: none;\n}\n.btn-default .badge,\n.btn-primary .badge,\n.btn-success .badge,\n.btn-info .badge,\n.btn-warning .badge,\n.btn-danger .badge {\n  text-shadow: none;\n}\n.btn:active,\n.btn.active {\n  background-image: none;\n}\n.btn-default {\n  text-shadow: 0 1px 0 #fff;\n  background-image: -webkit-linear-gradient(top, #fff 0%, #e0e0e0 100%);\n  background-image:      -o-linear-gradient(top, #fff 0%, #e0e0e0 100%);\n  background-image: -webkit-gradient(linear, left top, left bottom, from(#fff), to(#e0e0e0));\n  background-image:         linear-gradient(to bottom, #fff 0%, #e0e0e0 100%);\n  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#ffe0e0e0', GradientType=0);\n  filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);\n  background-repeat: repeat-x;\n  border-color: #dbdbdb;\n  border-color: #ccc;\n}\n.btn-default:hover,\n.btn-default:focus {\n  background-color: #e0e0e0;\n  background-position: 0 -15px;\n}\n.btn-default:active,\n.btn-default.active {\n  background-color: #e0e0e0;\n  border-color: #dbdbdb;\n}\n.btn-default.disabled,\n.btn-default[disabled],\nfieldset[disabled] .btn-default,\n.btn-default.disabled:hover,\n.btn-default[disabled]:hover,\nfieldset[disabled] .btn-default:hover,\n.btn-default.disabled:focus,\n.btn-default[disabled]:focus,\nfieldset[disabled] .btn-default:focus,\n.btn-default.disabled.focus,\n.btn-default[disabled].focus,\nfieldset[disabled] .btn-default.focus,\n.btn-default.disabled:active,\n.btn-default[disabled]:active,\nfieldset[disabled] .btn-default:active,\n.btn-default.disabled.active,\n.btn-default[disabled].active,\nfieldset[disabled] .btn-default.active {\n  background-color: #e0e0e0;\n  background-image: none;\n}\n.btn-primary {\n  background-image: -webkit-linear-gradient(top, #337ab7 0%, #265a88 100%);\n  background-image:      -o-linear-gradient(top, #337ab7 0%, #265a88 100%);\n  background-image: -webkit-gradient(linear, left top, left bottom, from(#337ab7), to(#265a88));\n  background-image:         linear-gradient(to bottom, #337ab7 0%, #265a88 100%);\n  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff265a88', GradientType=0);\n  filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);\n  background-repeat: repeat-x;\n  border-color: #245580;\n}\n.btn-primary:hover,\n.btn-primary:focus {\n  background-color: #265a88;\n  background-position: 0 -15px;\n}\n.btn-primary:active,\n.btn-primary.active {\n  background-color: #265a88;\n  border-color: #245580;\n}\n.btn-primary.disabled,\n.btn-primary[disabled],\nfieldset[disabled] .btn-primary,\n.btn-primary.disabled:hover,\n.btn-primary[disabled]:hover,\nfieldset[disabled] .btn-primary:hover,\n.btn-primary.disabled:focus,\n.btn-primary[disabled]:focus,\nfieldset[disabled] .btn-primary:focus,\n.btn-primary.disabled.focus,\n.btn-primary[disabled].focus,\nfieldset[disabled] .btn-primary.focus,\n.btn-primary.disabled:active,\n.btn-primary[disabled]:active,\nfieldset[disabled] .btn-primary:active,\n.btn-primary.disabled.active,\n.btn-primary[disabled].active,\nfieldset[disabled] .btn-primary.active {\n  background-color: #265a88;\n  background-image: none;\n}\n.btn-success {\n  background-image: -webkit-linear-gradient(top, #5cb85c 0%, #419641 100%);\n  background-image:      -o-linear-gradient(top, #5cb85c 0%, #419641 100%);\n  background-image: -webkit-gradient(linear, left top, left bottom, from(#5cb85c), to(#419641));\n  background-image:         linear-gradient(to bottom, #5cb85c 0%, #419641 100%);\n  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5cb85c', endColorstr='#ff419641', GradientType=0);\n  filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);\n  background-repeat: repeat-x;\n  border-color: #3e8f3e;\n}\n.btn-success:hover,\n.btn-success:focus {\n  background-color: #419641;\n  background-position: 0 -15px;\n}\n.btn-success:active,\n.btn-success.active {\n  background-color: #419641;\n  border-color: #3e8f3e;\n}\n.btn-success.disabled,\n.btn-success[disabled],\nfieldset[disabled] .btn-success,\n.btn-success.disabled:hover,\n.btn-success[disabled]:hover,\nfieldset[disabled] .btn-success:hover,\n.btn-success.disabled:focus,\n.btn-success[disabled]:focus,\nfieldset[disabled] .btn-success:focus,\n.btn-success.disabled.focus,\n.btn-success[disabled].focus,\nfieldset[disabled] .btn-success.focus,\n.btn-success.disabled:active,\n.btn-success[disabled]:active,\nfieldset[disabled] .btn-success:active,\n.btn-success.disabled.active,\n.btn-success[disabled].active,\nfieldset[disabled] .btn-success.active {\n  background-color: #419641;\n  background-image: none;\n}\n.btn-info {\n  background-image: -webkit-linear-gradient(top, #5bc0de 0%, #2aabd2 100%);\n  background-image:      -o-linear-gradient(top, #5bc0de 0%, #2aabd2 100%);\n  background-image: -webkit-gradient(linear, left top, left bottom, from(#5bc0de), to(#2aabd2));\n  background-image:         linear-gradient(to bottom, #5bc0de 0%, #2aabd2 100%);\n  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de', endColorstr='#ff2aabd2', GradientType=0);\n  filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);\n  background-repeat: repeat-x;\n  border-color: #28a4c9;\n}\n.btn-info:hover,\n.btn-info:focus {\n  background-color: #2aabd2;\n  background-position: 0 -15px;\n}\n.btn-info:active,\n.btn-info.active {\n  background-color: #2aabd2;\n  border-color: #28a4c9;\n}\n.btn-info.disabled,\n.btn-info[disabled],\nfieldset[disabled] .btn-info,\n.btn-info.disabled:hover,\n.btn-info[disabled]:hover,\nfieldset[disabled] .btn-info:hover,\n.btn-info.disabled:focus,\n.btn-info[disabled]:focus,\nfieldset[disabled] .btn-info:focus,\n.btn-info.disabled.focus,\n.btn-info[disabled].focus,\nfieldset[disabled] .btn-info.focus,\n.btn-info.disabled:active,\n.btn-info[disabled]:active,\nfieldset[disabled] .btn-info:active,\n.btn-info.disabled.active,\n.btn-info[disabled].active,\nfieldset[disabled] .btn-info.active {\n  background-color: #2aabd2;\n  background-image: none;\n}\n.btn-warning {\n  background-image: -webkit-linear-gradient(top, #f0ad4e 0%, #eb9316 100%);\n  background-image:      -o-linear-gradient(top, #f0ad4e 0%, #eb9316 100%);\n  background-image: -webkit-gradient(linear, left top, left bottom, from(#f0ad4e), to(#eb9316));\n  background-image:         linear-gradient(to bottom, #f0ad4e 0%, #eb9316 100%);\n  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff0ad4e', endColorstr='#ffeb9316', GradientType=0);\n  filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);\n  background-repeat: repeat-x;\n  border-color: #e38d13;\n}\n.btn-warning:hover,\n.btn-warning:focus {\n  background-color: #eb9316;\n  background-position: 0 -15px;\n}\n.btn-warning:active,\n.btn-warning.active {\n  background-color: #eb9316;\n  border-color: #e38d13;\n}\n.btn-warning.disabled,\n.btn-warning[disabled],\nfieldset[disabled] .btn-warning,\n.btn-warning.disabled:hover,\n.btn-warning[disabled]:hover,\nfieldset[disabled] .btn-warning:hover,\n.btn-warning.disabled:focus,\n.btn-warning[disabled]:focus,\nfieldset[disabled] .btn-warning:focus,\n.btn-warning.disabled.focus,\n.btn-warning[disabled].focus,\nfieldset[disabled] .btn-warning.focus,\n.btn-warning.disabled:active,\n.btn-warning[disabled]:active,\nfieldset[disabled] .btn-warning:active,\n.btn-warning.disabled.active,\n.btn-warning[disabled].active,\nfieldset[disabled] .btn-warning.active {\n  background-color: #eb9316;\n  background-image: none;\n}\n.btn-danger {\n  background-image: -webkit-linear-gradient(top, #d9534f 0%, #c12e2a 100%);\n  background-image:      -o-linear-gradient(top, #d9534f 0%, #c12e2a 100%);\n  background-image: -webkit-gradient(linear, left top, left bottom, from(#d9534f), to(#c12e2a));\n  background-image:         linear-gradient(to bottom, #d9534f 0%, #c12e2a 100%);\n  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9534f', endColorstr='#ffc12e2a', GradientType=0);\n  filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);\n  background-repeat: repeat-x;\n  border-color: #b92c28;\n}\n.btn-danger:hover,\n.btn-danger:focus {\n  background-color: #c12e2a;\n  background-position: 0 -15px;\n}\n.btn-danger:active,\n.btn-danger.active {\n  background-color: #c12e2a;\n  border-color: #b92c28;\n}\n.btn-danger.disabled,\n.btn-danger[disabled],\nfieldset[disabled] .btn-danger,\n.btn-danger.disabled:hover,\n.btn-danger[disabled]:hover,\nfieldset[disabled] .btn-danger:hover,\n.btn-danger.disabled:focus,\n.btn-danger[disabled]:focus,\nfieldset[disabled] .btn-danger:focus,\n.btn-danger.disabled.focus,\n.btn-danger[disabled].focus,\nfieldset[disabled] .btn-danger.focus,\n.btn-danger.disabled:active,\n.btn-danger[disabled]:active,\nfieldset[disabled] .btn-danger:active,\n.btn-danger.disabled.active,\n.btn-danger[disabled].active,\nfieldset[disabled] .btn-danger.active {\n  background-color: #c12e2a;\n  background-image: none;\n}\n.thumbnail,\n.img-thumbnail {\n  -webkit-box-shadow: 0 1px 2px rgba(0, 0, 0, .075);\n          box-shadow: 0 1px 2px rgba(0, 0, 0, .075);\n}\n.dropdown-menu > li > a:hover,\n.dropdown-menu > li > a:focus {\n  background-color: #e8e8e8;\n  background-image: -webkit-linear-gradient(top, #f5f5f5 0%, #e8e8e8 100%);\n  background-image:      -o-linear-gradient(top, #f5f5f5 0%, #e8e8e8 100%);\n  background-image: -webkit-gradient(linear, left top, left bottom, from(#f5f5f5), to(#e8e8e8));\n  background-image:         linear-gradient(to bottom, #f5f5f5 0%, #e8e8e8 100%);\n  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff5f5f5', endColorstr='#ffe8e8e8', GradientType=0);\n  background-repeat: repeat-x;\n}\n.dropdown-menu > .active > a,\n.dropdown-menu > .active > a:hover,\n.dropdown-menu > .active > a:focus {\n  background-color: #2e6da4;\n  background-image: -webkit-linear-gradient(top, #337ab7 0%, #2e6da4 100%);\n  background-image:      -o-linear-gradient(top, #337ab7 0%, #2e6da4 100%);\n  background-image: -webkit-gradient(linear, left top, left bottom, from(#337ab7), to(#2e6da4));\n  background-image:         linear-gradient(to bottom, #337ab7 0%, #2e6da4 100%);\n  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2e6da4', GradientType=0);\n  background-repeat: repeat-x;\n}\n.navbar-default {\n  background-image: -webkit-linear-gradient(top, #fff 0%, #f8f8f8 100%);\n  background-image:      -o-linear-gradient(top, #fff 0%, #f8f8f8 100%);\n  background-image: -webkit-gradient(linear, left top, left bottom, from(#fff), to(#f8f8f8));\n  background-image:         linear-gradient(to bottom, #fff 0%, #f8f8f8 100%);\n  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#fff8f8f8', GradientType=0);\n  filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);\n  background-repeat: repeat-x;\n  border-radius: 4px;\n  -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, .15), 0 1px 5px rgba(0, 0, 0, .075);\n          box-shadow: inset 0 1px 0 rgba(255, 255, 255, .15), 0 1px 5px rgba(0, 0, 0, .075);\n}\n.navbar-default .navbar-nav > .open > a,\n.navbar-default .navbar-nav > .active > a {\n  background-image: -webkit-linear-gradient(top, #dbdbdb 0%, #e2e2e2 100%);\n  background-image:      -o-linear-gradient(top, #dbdbdb 0%, #e2e2e2 100%);\n  background-image: -webkit-gradient(linear, left top, left bottom, from(#dbdbdb), to(#e2e2e2));\n  background-image:         linear-gradient(to bottom, #dbdbdb 0%, #e2e2e2 100%);\n  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdbdbdb', endColorstr='#ffe2e2e2', GradientType=0);\n  background-repeat: repeat-x;\n  -webkit-box-shadow: inset 0 3px 9px rgba(0, 0, 0, .075);\n          box-shadow: inset 0 3px 9px rgba(0, 0, 0, .075);\n}\n.navbar-brand,\n.navbar-nav > li > a {\n  text-shadow: 0 1px 0 rgba(255, 255, 255, .25);\n}\n.navbar-inverse {\n  background-image: -webkit-linear-gradient(top, #3c3c3c 0%, #222 100%);\n  background-image:      -o-linear-gradient(top, #3c3c3c 0%, #222 100%);\n  background-image: -webkit-gradient(linear, left top, left bottom, from(#3c3c3c), to(#222));\n  background-image:         linear-gradient(to bottom, #3c3c3c 0%, #222 100%);\n  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff3c3c3c', endColorstr='#ff222222', GradientType=0);\n  filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);\n  background-repeat: repeat-x;\n  border-radius: 4px;\n}\n.navbar-inverse .navbar-nav > .open > a,\n.navbar-inverse .navbar-nav > .active > a {\n  background-image: -webkit-linear-gradient(top, #080808 0%, #0f0f0f 100%);\n  background-image:      -o-linear-gradient(top, #080808 0%, #0f0f0f 100%);\n  background-image: -webkit-gradient(linear, left top, left bottom, from(#080808), to(#0f0f0f));\n  background-image:         linear-gradient(to bottom, #080808 0%, #0f0f0f 100%);\n  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff080808', endColorstr='#ff0f0f0f', GradientType=0);\n  background-repeat: repeat-x;\n  -webkit-box-shadow: inset 0 3px 9px rgba(0, 0, 0, .25);\n          box-shadow: inset 0 3px 9px rgba(0, 0, 0, .25);\n}\n.navbar-inverse .navbar-brand,\n.navbar-inverse .navbar-nav > li > a {\n  text-shadow: 0 -1px 0 rgba(0, 0, 0, .25);\n}\n.navbar-static-top,\n.navbar-fixed-top,\n.navbar-fixed-bottom {\n  border-radius: 0;\n}\n@media (max-width: 767px) {\n  .navbar .navbar-nav .open .dropdown-menu > .active > a,\n  .navbar .navbar-nav .open .dropdown-menu > .active > a:hover,\n  .navbar .navbar-nav .open .dropdown-menu > .active > a:focus {\n    color: #fff;\n    background-image: -webkit-linear-gradient(top, #337ab7 0%, #2e6da4 100%);\n    background-image:      -o-linear-gradient(top, #337ab7 0%, #2e6da4 100%);\n    background-image: -webkit-gradient(linear, left top, left bottom, from(#337ab7), to(#2e6da4));\n    background-image:         linear-gradient(to bottom, #337ab7 0%, #2e6da4 100%);\n    filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2e6da4', GradientType=0);\n    background-repeat: repeat-x;\n  }\n}\n.alert {\n  text-shadow: 0 1px 0 rgba(255, 255, 255, .2);\n  -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, .25), 0 1px 2px rgba(0, 0, 0, .05);\n          box-shadow: inset 0 1px 0 rgba(255, 255, 255, .25), 0 1px 2px rgba(0, 0, 0, .05);\n}\n.alert-success {\n  background-image: -webkit-linear-gradient(top, #dff0d8 0%, #c8e5bc 100%);\n  background-image:      -o-linear-gradient(top, #dff0d8 0%, #c8e5bc 100%);\n  background-image: -webkit-gradient(linear, left top, left bottom, from(#dff0d8), to(#c8e5bc));\n  background-image:         linear-gradient(to bottom, #dff0d8 0%, #c8e5bc 100%);\n  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdff0d8', endColorstr='#ffc8e5bc', GradientType=0);\n  background-repeat: repeat-x;\n  border-color: #b2dba1;\n}\n.alert-info {\n  background-image: -webkit-linear-gradient(top, #d9edf7 0%, #b9def0 100%);\n  background-image:      -o-linear-gradient(top, #d9edf7 0%, #b9def0 100%);\n  background-image: -webkit-gradient(linear, left top, left bottom, from(#d9edf7), to(#b9def0));\n  background-image:         linear-gradient(to bottom, #d9edf7 0%, #b9def0 100%);\n  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9edf7', endColorstr='#ffb9def0', GradientType=0);\n  background-repeat: repeat-x;\n  border-color: #9acfea;\n}\n.alert-warning {\n  background-image: -webkit-linear-gradient(top, #fcf8e3 0%, #f8efc0 100%);\n  background-image:      -o-linear-gradient(top, #fcf8e3 0%, #f8efc0 100%);\n  background-image: -webkit-gradient(linear, left top, left bottom, from(#fcf8e3), to(#f8efc0));\n  background-image:         linear-gradient(to bottom, #fcf8e3 0%, #f8efc0 100%);\n  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffcf8e3', endColorstr='#fff8efc0', GradientType=0);\n  background-repeat: repeat-x;\n  border-color: #f5e79e;\n}\n.alert-danger {\n  background-image: -webkit-linear-gradient(top, #f2dede 0%, #e7c3c3 100%);\n  background-image:      -o-linear-gradient(top, #f2dede 0%, #e7c3c3 100%);\n  background-image: -webkit-gradient(linear, left top, left bottom, from(#f2dede), to(#e7c3c3));\n  background-image:         linear-gradient(to bottom, #f2dede 0%, #e7c3c3 100%);\n  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff2dede', endColorstr='#ffe7c3c3', GradientType=0);\n  background-repeat: repeat-x;\n  border-color: #dca7a7;\n}\n.progress {\n  background-image: -webkit-linear-gradient(top, #ebebeb 0%, #f5f5f5 100%);\n  background-image:      -o-linear-gradient(top, #ebebeb 0%, #f5f5f5 100%);\n  background-image: -webkit-gradient(linear, left top, left bottom, from(#ebebeb), to(#f5f5f5));\n  background-image:         linear-gradient(to bottom, #ebebeb 0%, #f5f5f5 100%);\n  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffebebeb', endColorstr='#fff5f5f5', GradientType=0);\n  background-repeat: repeat-x;\n}\n.progress-bar {\n  background-image: -webkit-linear-gradient(top, #337ab7 0%, #286090 100%);\n  background-image:      -o-linear-gradient(top, #337ab7 0%, #286090 100%);\n  background-image: -webkit-gradient(linear, left top, left bottom, from(#337ab7), to(#286090));\n  background-image:         linear-gradient(to bottom, #337ab7 0%, #286090 100%);\n  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff286090', GradientType=0);\n  background-repeat: repeat-x;\n}\n.progress-bar-success {\n  background-image: -webkit-linear-gradient(top, #5cb85c 0%, #449d44 100%);\n  background-image:      -o-linear-gradient(top, #5cb85c 0%, #449d44 100%);\n  background-image: -webkit-gradient(linear, left top, left bottom, from(#5cb85c), to(#449d44));\n  background-image:         linear-gradient(to bottom, #5cb85c 0%, #449d44 100%);\n  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5cb85c', endColorstr='#ff449d44', GradientType=0);\n  background-repeat: repeat-x;\n}\n.progress-bar-info {\n  background-image: -webkit-linear-gradient(top, #5bc0de 0%, #31b0d5 100%);\n  background-image:      -o-linear-gradient(top, #5bc0de 0%, #31b0d5 100%);\n  background-image: -webkit-gradient(linear, left top, left bottom, from(#5bc0de), to(#31b0d5));\n  background-image:         linear-gradient(to bottom, #5bc0de 0%, #31b0d5 100%);\n  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de', endColorstr='#ff31b0d5', GradientType=0);\n  background-repeat: repeat-x;\n}\n.progress-bar-warning {\n  background-image: -webkit-linear-gradient(top, #f0ad4e 0%, #ec971f 100%);\n  background-image:      -o-linear-gradient(top, #f0ad4e 0%, #ec971f 100%);\n  background-image: -webkit-gradient(linear, left top, left bottom, from(#f0ad4e), to(#ec971f));\n  background-image:         linear-gradient(to bottom, #f0ad4e 0%, #ec971f 100%);\n  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff0ad4e', endColorstr='#ffec971f', GradientType=0);\n  background-repeat: repeat-x;\n}\n.progress-bar-danger {\n  background-image: -webkit-linear-gradient(top, #d9534f 0%, #c9302c 100%);\n  background-image:      -o-linear-gradient(top, #d9534f 0%, #c9302c 100%);\n  background-image: -webkit-gradient(linear, left top, left bottom, from(#d9534f), to(#c9302c));\n  background-image:         linear-gradient(to bottom, #d9534f 0%, #c9302c 100%);\n  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9534f', endColorstr='#ffc9302c', GradientType=0);\n  background-repeat: repeat-x;\n}\n.progress-bar-striped {\n  background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);\n  background-image:      -o-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);\n  background-image:         linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);\n}\n.list-group {\n  border-radius: 4px;\n  -webkit-box-shadow: 0 1px 2px rgba(0, 0, 0, .075);\n          box-shadow: 0 1px 2px rgba(0, 0, 0, .075);\n}\n.list-group-item.active,\n.list-group-item.active:hover,\n.list-group-item.active:focus {\n  text-shadow: 0 -1px 0 #286090;\n  background-image: -webkit-linear-gradient(top, #337ab7 0%, #2b669a 100%);\n  background-image:      -o-linear-gradient(top, #337ab7 0%, #2b669a 100%);\n  background-image: -webkit-gradient(linear, left top, left bottom, from(#337ab7), to(#2b669a));\n  background-image:         linear-gradient(to bottom, #337ab7 0%, #2b669a 100%);\n  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2b669a', GradientType=0);\n  background-repeat: repeat-x;\n  border-color: #2b669a;\n}\n.list-group-item.active .badge,\n.list-group-item.active:hover .badge,\n.list-group-item.active:focus .badge {\n  text-shadow: none;\n}\n.panel {\n  -webkit-box-shadow: 0 1px 2px rgba(0, 0, 0, .05);\n          box-shadow: 0 1px 2px rgba(0, 0, 0, .05);\n}\n.panel-default > .panel-heading {\n  background-image: -webkit-linear-gradient(top, #f5f5f5 0%, #e8e8e8 100%);\n  background-image:      -o-linear-gradient(top, #f5f5f5 0%, #e8e8e8 100%);\n  background-image: -webkit-gradient(linear, left top, left bottom, from(#f5f5f5), to(#e8e8e8));\n  background-image:         linear-gradient(to bottom, #f5f5f5 0%, #e8e8e8 100%);\n  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff5f5f5', endColorstr='#ffe8e8e8', GradientType=0);\n  background-repeat: repeat-x;\n}\n.panel-primary > .panel-heading {\n  background-image: -webkit-linear-gradient(top, #337ab7 0%, #2e6da4 100%);\n  background-image:      -o-linear-gradient(top, #337ab7 0%, #2e6da4 100%);\n  background-image: -webkit-gradient(linear, left top, left bottom, from(#337ab7), to(#2e6da4));\n  background-image:         linear-gradient(to bottom, #337ab7 0%, #2e6da4 100%);\n  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2e6da4', GradientType=0);\n  background-repeat: repeat-x;\n}\n.panel-success > .panel-heading {\n  background-image: -webkit-linear-gradient(top, #dff0d8 0%, #d0e9c6 100%);\n  background-image:      -o-linear-gradient(top, #dff0d8 0%, #d0e9c6 100%);\n  background-image: -webkit-gradient(linear, left top, left bottom, from(#dff0d8), to(#d0e9c6));\n  background-image:         linear-gradient(to bottom, #dff0d8 0%, #d0e9c6 100%);\n  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdff0d8', endColorstr='#ffd0e9c6', GradientType=0);\n  background-repeat: repeat-x;\n}\n.panel-info > .panel-heading {\n  background-image: -webkit-linear-gradient(top, #d9edf7 0%, #c4e3f3 100%);\n  background-image:      -o-linear-gradient(top, #d9edf7 0%, #c4e3f3 100%);\n  background-image: -webkit-gradient(linear, left top, left bottom, from(#d9edf7), to(#c4e3f3));\n  background-image:         linear-gradient(to bottom, #d9edf7 0%, #c4e3f3 100%);\n  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9edf7', endColorstr='#ffc4e3f3', GradientType=0);\n  background-repeat: repeat-x;\n}\n.panel-warning > .panel-heading {\n  background-image: -webkit-linear-gradient(top, #fcf8e3 0%, #faf2cc 100%);\n  background-image:      -o-linear-gradient(top, #fcf8e3 0%, #faf2cc 100%);\n  background-image: -webkit-gradient(linear, left top, left bottom, from(#fcf8e3), to(#faf2cc));\n  background-image:         linear-gradient(to bottom, #fcf8e3 0%, #faf2cc 100%);\n  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffcf8e3', endColorstr='#fffaf2cc', GradientType=0);\n  background-repeat: repeat-x;\n}\n.panel-danger > .panel-heading {\n  background-image: -webkit-linear-gradient(top, #f2dede 0%, #ebcccc 100%);\n  background-image:      -o-linear-gradient(top, #f2dede 0%, #ebcccc 100%);\n  background-image: -webkit-gradient(linear, left top, left bottom, from(#f2dede), to(#ebcccc));\n  background-image:         linear-gradient(to bottom, #f2dede 0%, #ebcccc 100%);\n  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff2dede', endColorstr='#ffebcccc', GradientType=0);\n  background-repeat: repeat-x;\n}\n.well {\n  background-image: -webkit-linear-gradient(top, #e8e8e8 0%, #f5f5f5 100%);\n  background-image:      -o-linear-gradient(top, #e8e8e8 0%, #f5f5f5 100%);\n  background-image: -webkit-gradient(linear, left top, left bottom, from(#e8e8e8), to(#f5f5f5));\n  background-image:         linear-gradient(to bottom, #e8e8e8 0%, #f5f5f5 100%);\n  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffe8e8e8', endColorstr='#fff5f5f5', GradientType=0);\n  background-repeat: repeat-x;\n  border-color: #dcdcdc;\n  -webkit-box-shadow: inset 0 1px 3px rgba(0, 0, 0, .05), 0 1px 0 rgba(255, 255, 255, .1);\n          box-shadow: inset 0 1px 3px rgba(0, 0, 0, .05), 0 1px 0 rgba(255, 255, 255, .1);\n}\n/*# sourceMappingURL=bootstrap-theme.css.map */\n"
  },
  {
    "path": "app_frontend/static/css/bootstrap.css",
    "content": "/*!\n * Bootstrap v3.3.5 (http://getbootstrap.com)\n * Copyright 2011-2015 Twitter, Inc.\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)\n */\n/*! normalize.css v3.0.3 | MIT License | github.com/necolas/normalize.css */\nhtml {\n  font-family: sans-serif;\n  -webkit-text-size-adjust: 100%;\n      -ms-text-size-adjust: 100%;\n}\nbody {\n  margin: 0;\n}\narticle,\naside,\ndetails,\nfigcaption,\nfigure,\nfooter,\nheader,\nhgroup,\nmain,\nmenu,\nnav,\nsection,\nsummary {\n  display: block;\n}\naudio,\ncanvas,\nprogress,\nvideo {\n  display: inline-block;\n  vertical-align: baseline;\n}\naudio:not([controls]) {\n  display: none;\n  height: 0;\n}\n[hidden],\ntemplate {\n  display: none;\n}\na {\n  background-color: transparent;\n}\na:active,\na:hover {\n  outline: 0;\n}\nabbr[title] {\n  border-bottom: 1px dotted;\n}\nb,\nstrong {\n  font-weight: bold;\n}\ndfn {\n  font-style: italic;\n}\nh1 {\n  margin: .67em 0;\n  font-size: 2em;\n}\nmark {\n  color: #000;\n  background: #ff0;\n}\nsmall {\n  font-size: 80%;\n}\nsub,\nsup {\n  position: relative;\n  font-size: 75%;\n  line-height: 0;\n  vertical-align: baseline;\n}\nsup {\n  top: -.5em;\n}\nsub {\n  bottom: -.25em;\n}\nimg {\n  border: 0;\n}\nsvg:not(:root) {\n  overflow: hidden;\n}\nfigure {\n  margin: 1em 40px;\n}\nhr {\n  height: 0;\n  -webkit-box-sizing: content-box;\n     -moz-box-sizing: content-box;\n          box-sizing: content-box;\n}\npre {\n  overflow: auto;\n}\ncode,\nkbd,\npre,\nsamp {\n  font-family: monospace, monospace;\n  font-size: 1em;\n}\nbutton,\ninput,\noptgroup,\nselect,\ntextarea {\n  margin: 0;\n  font: inherit;\n  color: inherit;\n}\nbutton {\n  overflow: visible;\n}\nbutton,\nselect {\n  text-transform: none;\n}\nbutton,\nhtml input[type=\"button\"],\ninput[type=\"reset\"],\ninput[type=\"submit\"] {\n  -webkit-appearance: button;\n  cursor: pointer;\n}\nbutton[disabled],\nhtml input[disabled] {\n  cursor: default;\n}\nbutton::-moz-focus-inner,\ninput::-moz-focus-inner {\n  padding: 0;\n  border: 0;\n}\ninput {\n  line-height: normal;\n}\ninput[type=\"checkbox\"],\ninput[type=\"radio\"] {\n  -webkit-box-sizing: border-box;\n     -moz-box-sizing: border-box;\n          box-sizing: border-box;\n  padding: 0;\n}\ninput[type=\"number\"]::-webkit-inner-spin-button,\ninput[type=\"number\"]::-webkit-outer-spin-button {\n  height: auto;\n}\ninput[type=\"search\"] {\n  -webkit-box-sizing: content-box;\n     -moz-box-sizing: content-box;\n          box-sizing: content-box;\n  -webkit-appearance: textfield;\n}\ninput[type=\"search\"]::-webkit-search-cancel-button,\ninput[type=\"search\"]::-webkit-search-decoration {\n  -webkit-appearance: none;\n}\nfieldset {\n  padding: .35em .625em .75em;\n  margin: 0 2px;\n  border: 1px solid #c0c0c0;\n}\nlegend {\n  padding: 0;\n  border: 0;\n}\ntextarea {\n  overflow: auto;\n}\noptgroup {\n  font-weight: bold;\n}\ntable {\n  border-spacing: 0;\n  border-collapse: collapse;\n}\ntd,\nth {\n  padding: 0;\n}\n/*! Source: https://github.com/h5bp/html5-boilerplate/blob/master/src/css/main.css */\n@media print {\n  *,\n  *:before,\n  *:after {\n    color: #000 !important;\n    text-shadow: none !important;\n    background: transparent !important;\n    -webkit-box-shadow: none !important;\n            box-shadow: none !important;\n  }\n  a,\n  a:visited {\n    text-decoration: underline;\n  }\n  a[href]:after {\n    content: \" (\" attr(href) \")\";\n  }\n  abbr[title]:after {\n    content: \" (\" attr(title) \")\";\n  }\n  a[href^=\"#\"]:after,\n  a[href^=\"javascript:\"]:after {\n    content: \"\";\n  }\n  pre,\n  blockquote {\n    border: 1px solid #999;\n\n    page-break-inside: avoid;\n  }\n  thead {\n    display: table-header-group;\n  }\n  tr,\n  img {\n    page-break-inside: avoid;\n  }\n  img {\n    max-width: 100% !important;\n  }\n  p,\n  h2,\n  h3 {\n    orphans: 3;\n    widows: 3;\n  }\n  h2,\n  h3 {\n    page-break-after: avoid;\n  }\n  .navbar {\n    display: none;\n  }\n  .btn > .caret,\n  .dropup > .btn > .caret {\n    border-top-color: #000 !important;\n  }\n  .label {\n    border: 1px solid #000;\n  }\n  .table {\n    border-collapse: collapse !important;\n  }\n  .table td,\n  .table th {\n    background-color: #fff !important;\n  }\n  .table-bordered th,\n  .table-bordered td {\n    border: 1px solid #ddd !important;\n  }\n}\n@font-face {\n  font-family: 'Glyphicons Halflings';\n\n  src: url('../fonts/glyphicons-halflings-regular.eot');\n  src: url('../fonts/glyphicons-halflings-regular.eot?#iefix') format('embedded-opentype'), url('../fonts/glyphicons-halflings-regular.woff2') format('woff2'), url('../fonts/glyphicons-halflings-regular.woff') format('woff'), url('../fonts/glyphicons-halflings-regular.ttf') format('truetype'), url('../fonts/glyphicons-halflings-regular.svg#glyphicons_halflingsregular') format('svg');\n}\n.glyphicon {\n  position: relative;\n  top: 1px;\n  display: inline-block;\n  font-family: 'Glyphicons Halflings';\n  font-style: normal;\n  font-weight: normal;\n  line-height: 1;\n\n  -webkit-font-smoothing: antialiased;\n  -moz-osx-font-smoothing: grayscale;\n}\n.glyphicon-asterisk:before {\n  content: \"\\2a\";\n}\n.glyphicon-plus:before {\n  content: \"\\2b\";\n}\n.glyphicon-euro:before,\n.glyphicon-eur:before {\n  content: \"\\20ac\";\n}\n.glyphicon-minus:before {\n  content: \"\\2212\";\n}\n.glyphicon-cloud:before {\n  content: \"\\2601\";\n}\n.glyphicon-envelope:before {\n  content: \"\\2709\";\n}\n.glyphicon-pencil:before {\n  content: \"\\270f\";\n}\n.glyphicon-glass:before {\n  content: \"\\e001\";\n}\n.glyphicon-music:before {\n  content: \"\\e002\";\n}\n.glyphicon-search:before {\n  content: \"\\e003\";\n}\n.glyphicon-heart:before {\n  content: \"\\e005\";\n}\n.glyphicon-star:before {\n  content: \"\\e006\";\n}\n.glyphicon-star-empty:before {\n  content: \"\\e007\";\n}\n.glyphicon-user:before {\n  content: \"\\e008\";\n}\n.glyphicon-film:before {\n  content: \"\\e009\";\n}\n.glyphicon-th-large:before {\n  content: \"\\e010\";\n}\n.glyphicon-th:before {\n  content: \"\\e011\";\n}\n.glyphicon-th-list:before {\n  content: \"\\e012\";\n}\n.glyphicon-ok:before {\n  content: \"\\e013\";\n}\n.glyphicon-remove:before {\n  content: \"\\e014\";\n}\n.glyphicon-zoom-in:before {\n  content: \"\\e015\";\n}\n.glyphicon-zoom-out:before {\n  content: \"\\e016\";\n}\n.glyphicon-off:before {\n  content: \"\\e017\";\n}\n.glyphicon-signal:before {\n  content: \"\\e018\";\n}\n.glyphicon-cog:before {\n  content: \"\\e019\";\n}\n.glyphicon-trash:before {\n  content: \"\\e020\";\n}\n.glyphicon-home:before {\n  content: \"\\e021\";\n}\n.glyphicon-file:before {\n  content: \"\\e022\";\n}\n.glyphicon-time:before {\n  content: \"\\e023\";\n}\n.glyphicon-road:before {\n  content: \"\\e024\";\n}\n.glyphicon-download-alt:before {\n  content: \"\\e025\";\n}\n.glyphicon-download:before {\n  content: \"\\e026\";\n}\n.glyphicon-upload:before {\n  content: \"\\e027\";\n}\n.glyphicon-inbox:before {\n  content: \"\\e028\";\n}\n.glyphicon-play-circle:before {\n  content: \"\\e029\";\n}\n.glyphicon-repeat:before {\n  content: \"\\e030\";\n}\n.glyphicon-refresh:before {\n  content: \"\\e031\";\n}\n.glyphicon-list-alt:before {\n  content: \"\\e032\";\n}\n.glyphicon-lock:before {\n  content: \"\\e033\";\n}\n.glyphicon-flag:before {\n  content: \"\\e034\";\n}\n.glyphicon-headphones:before {\n  content: \"\\e035\";\n}\n.glyphicon-volume-off:before {\n  content: \"\\e036\";\n}\n.glyphicon-volume-down:before {\n  content: \"\\e037\";\n}\n.glyphicon-volume-up:before {\n  content: \"\\e038\";\n}\n.glyphicon-qrcode:before {\n  content: \"\\e039\";\n}\n.glyphicon-barcode:before {\n  content: \"\\e040\";\n}\n.glyphicon-tag:before {\n  content: \"\\e041\";\n}\n.glyphicon-tags:before {\n  content: \"\\e042\";\n}\n.glyphicon-book:before {\n  content: \"\\e043\";\n}\n.glyphicon-bookmark:before {\n  content: \"\\e044\";\n}\n.glyphicon-print:before {\n  content: \"\\e045\";\n}\n.glyphicon-camera:before {\n  content: \"\\e046\";\n}\n.glyphicon-font:before {\n  content: \"\\e047\";\n}\n.glyphicon-bold:before {\n  content: \"\\e048\";\n}\n.glyphicon-italic:before {\n  content: \"\\e049\";\n}\n.glyphicon-text-height:before {\n  content: \"\\e050\";\n}\n.glyphicon-text-width:before {\n  content: \"\\e051\";\n}\n.glyphicon-align-left:before {\n  content: \"\\e052\";\n}\n.glyphicon-align-center:before {\n  content: \"\\e053\";\n}\n.glyphicon-align-right:before {\n  content: \"\\e054\";\n}\n.glyphicon-align-justify:before {\n  content: \"\\e055\";\n}\n.glyphicon-list:before {\n  content: \"\\e056\";\n}\n.glyphicon-indent-left:before {\n  content: \"\\e057\";\n}\n.glyphicon-indent-right:before {\n  content: \"\\e058\";\n}\n.glyphicon-facetime-video:before {\n  content: \"\\e059\";\n}\n.glyphicon-picture:before {\n  content: \"\\e060\";\n}\n.glyphicon-map-marker:before {\n  content: \"\\e062\";\n}\n.glyphicon-adjust:before {\n  content: \"\\e063\";\n}\n.glyphicon-tint:before {\n  content: \"\\e064\";\n}\n.glyphicon-edit:before {\n  content: \"\\e065\";\n}\n.glyphicon-share:before {\n  content: \"\\e066\";\n}\n.glyphicon-check:before {\n  content: \"\\e067\";\n}\n.glyphicon-move:before {\n  content: \"\\e068\";\n}\n.glyphicon-step-backward:before {\n  content: \"\\e069\";\n}\n.glyphicon-fast-backward:before {\n  content: \"\\e070\";\n}\n.glyphicon-backward:before {\n  content: \"\\e071\";\n}\n.glyphicon-play:before {\n  content: \"\\e072\";\n}\n.glyphicon-pause:before {\n  content: \"\\e073\";\n}\n.glyphicon-stop:before {\n  content: \"\\e074\";\n}\n.glyphicon-forward:before {\n  content: \"\\e075\";\n}\n.glyphicon-fast-forward:before {\n  content: \"\\e076\";\n}\n.glyphicon-step-forward:before {\n  content: \"\\e077\";\n}\n.glyphicon-eject:before {\n  content: \"\\e078\";\n}\n.glyphicon-chevron-left:before {\n  content: \"\\e079\";\n}\n.glyphicon-chevron-right:before {\n  content: \"\\e080\";\n}\n.glyphicon-plus-sign:before {\n  content: \"\\e081\";\n}\n.glyphicon-minus-sign:before {\n  content: \"\\e082\";\n}\n.glyphicon-remove-sign:before {\n  content: \"\\e083\";\n}\n.glyphicon-ok-sign:before {\n  content: \"\\e084\";\n}\n.glyphicon-question-sign:before {\n  content: \"\\e085\";\n}\n.glyphicon-info-sign:before {\n  content: \"\\e086\";\n}\n.glyphicon-screenshot:before {\n  content: \"\\e087\";\n}\n.glyphicon-remove-circle:before {\n  content: \"\\e088\";\n}\n.glyphicon-ok-circle:before {\n  content: \"\\e089\";\n}\n.glyphicon-ban-circle:before {\n  content: \"\\e090\";\n}\n.glyphicon-arrow-left:before {\n  content: \"\\e091\";\n}\n.glyphicon-arrow-right:before {\n  content: \"\\e092\";\n}\n.glyphicon-arrow-up:before {\n  content: \"\\e093\";\n}\n.glyphicon-arrow-down:before {\n  content: \"\\e094\";\n}\n.glyphicon-share-alt:before {\n  content: \"\\e095\";\n}\n.glyphicon-resize-full:before {\n  content: \"\\e096\";\n}\n.glyphicon-resize-small:before {\n  content: \"\\e097\";\n}\n.glyphicon-exclamation-sign:before {\n  content: \"\\e101\";\n}\n.glyphicon-gift:before {\n  content: \"\\e102\";\n}\n.glyphicon-leaf:before {\n  content: \"\\e103\";\n}\n.glyphicon-fire:before {\n  content: \"\\e104\";\n}\n.glyphicon-eye-open:before {\n  content: \"\\e105\";\n}\n.glyphicon-eye-close:before {\n  content: \"\\e106\";\n}\n.glyphicon-warning-sign:before {\n  content: \"\\e107\";\n}\n.glyphicon-plane:before {\n  content: \"\\e108\";\n}\n.glyphicon-calendar:before {\n  content: \"\\e109\";\n}\n.glyphicon-random:before {\n  content: \"\\e110\";\n}\n.glyphicon-comment:before {\n  content: \"\\e111\";\n}\n.glyphicon-magnet:before {\n  content: \"\\e112\";\n}\n.glyphicon-chevron-up:before {\n  content: \"\\e113\";\n}\n.glyphicon-chevron-down:before {\n  content: \"\\e114\";\n}\n.glyphicon-retweet:before {\n  content: \"\\e115\";\n}\n.glyphicon-shopping-cart:before {\n  content: \"\\e116\";\n}\n.glyphicon-folder-close:before {\n  content: \"\\e117\";\n}\n.glyphicon-folder-open:before {\n  content: \"\\e118\";\n}\n.glyphicon-resize-vertical:before {\n  content: \"\\e119\";\n}\n.glyphicon-resize-horizontal:before {\n  content: \"\\e120\";\n}\n.glyphicon-hdd:before {\n  content: \"\\e121\";\n}\n.glyphicon-bullhorn:before {\n  content: \"\\e122\";\n}\n.glyphicon-bell:before {\n  content: \"\\e123\";\n}\n.glyphicon-certificate:before {\n  content: \"\\e124\";\n}\n.glyphicon-thumbs-up:before {\n  content: \"\\e125\";\n}\n.glyphicon-thumbs-down:before {\n  content: \"\\e126\";\n}\n.glyphicon-hand-right:before {\n  content: \"\\e127\";\n}\n.glyphicon-hand-left:before {\n  content: \"\\e128\";\n}\n.glyphicon-hand-up:before {\n  content: \"\\e129\";\n}\n.glyphicon-hand-down:before {\n  content: \"\\e130\";\n}\n.glyphicon-circle-arrow-right:before {\n  content: \"\\e131\";\n}\n.glyphicon-circle-arrow-left:before {\n  content: \"\\e132\";\n}\n.glyphicon-circle-arrow-up:before {\n  content: \"\\e133\";\n}\n.glyphicon-circle-arrow-down:before {\n  content: \"\\e134\";\n}\n.glyphicon-globe:before {\n  content: \"\\e135\";\n}\n.glyphicon-wrench:before {\n  content: \"\\e136\";\n}\n.glyphicon-tasks:before {\n  content: \"\\e137\";\n}\n.glyphicon-filter:before {\n  content: \"\\e138\";\n}\n.glyphicon-briefcase:before {\n  content: \"\\e139\";\n}\n.glyphicon-fullscreen:before {\n  content: \"\\e140\";\n}\n.glyphicon-dashboard:before {\n  content: \"\\e141\";\n}\n.glyphicon-paperclip:before {\n  content: \"\\e142\";\n}\n.glyphicon-heart-empty:before {\n  content: \"\\e143\";\n}\n.glyphicon-link:before {\n  content: \"\\e144\";\n}\n.glyphicon-phone:before {\n  content: \"\\e145\";\n}\n.glyphicon-pushpin:before {\n  content: \"\\e146\";\n}\n.glyphicon-usd:before {\n  content: \"\\e148\";\n}\n.glyphicon-gbp:before {\n  content: \"\\e149\";\n}\n.glyphicon-sort:before {\n  content: \"\\e150\";\n}\n.glyphicon-sort-by-alphabet:before {\n  content: \"\\e151\";\n}\n.glyphicon-sort-by-alphabet-alt:before {\n  content: \"\\e152\";\n}\n.glyphicon-sort-by-order:before {\n  content: \"\\e153\";\n}\n.glyphicon-sort-by-order-alt:before {\n  content: \"\\e154\";\n}\n.glyphicon-sort-by-attributes:before {\n  content: \"\\e155\";\n}\n.glyphicon-sort-by-attributes-alt:before {\n  content: \"\\e156\";\n}\n.glyphicon-unchecked:before {\n  content: \"\\e157\";\n}\n.glyphicon-expand:before {\n  content: \"\\e158\";\n}\n.glyphicon-collapse-down:before {\n  content: \"\\e159\";\n}\n.glyphicon-collapse-up:before {\n  content: \"\\e160\";\n}\n.glyphicon-log-in:before {\n  content: \"\\e161\";\n}\n.glyphicon-flash:before {\n  content: \"\\e162\";\n}\n.glyphicon-log-out:before {\n  content: \"\\e163\";\n}\n.glyphicon-new-window:before {\n  content: \"\\e164\";\n}\n.glyphicon-record:before {\n  content: \"\\e165\";\n}\n.glyphicon-save:before {\n  content: \"\\e166\";\n}\n.glyphicon-open:before {\n  content: \"\\e167\";\n}\n.glyphicon-saved:before {\n  content: \"\\e168\";\n}\n.glyphicon-import:before {\n  content: \"\\e169\";\n}\n.glyphicon-export:before {\n  content: \"\\e170\";\n}\n.glyphicon-send:before {\n  content: \"\\e171\";\n}\n.glyphicon-floppy-disk:before {\n  content: \"\\e172\";\n}\n.glyphicon-floppy-saved:before {\n  content: \"\\e173\";\n}\n.glyphicon-floppy-remove:before {\n  content: \"\\e174\";\n}\n.glyphicon-floppy-save:before {\n  content: \"\\e175\";\n}\n.glyphicon-floppy-open:before {\n  content: \"\\e176\";\n}\n.glyphicon-credit-card:before {\n  content: \"\\e177\";\n}\n.glyphicon-transfer:before {\n  content: \"\\e178\";\n}\n.glyphicon-cutlery:before {\n  content: \"\\e179\";\n}\n.glyphicon-header:before {\n  content: \"\\e180\";\n}\n.glyphicon-compressed:before {\n  content: \"\\e181\";\n}\n.glyphicon-earphone:before {\n  content: \"\\e182\";\n}\n.glyphicon-phone-alt:before {\n  content: \"\\e183\";\n}\n.glyphicon-tower:before {\n  content: \"\\e184\";\n}\n.glyphicon-stats:before {\n  content: \"\\e185\";\n}\n.glyphicon-sd-video:before {\n  content: \"\\e186\";\n}\n.glyphicon-hd-video:before {\n  content: \"\\e187\";\n}\n.glyphicon-subtitles:before {\n  content: \"\\e188\";\n}\n.glyphicon-sound-stereo:before {\n  content: \"\\e189\";\n}\n.glyphicon-sound-dolby:before {\n  content: \"\\e190\";\n}\n.glyphicon-sound-5-1:before {\n  content: \"\\e191\";\n}\n.glyphicon-sound-6-1:before {\n  content: \"\\e192\";\n}\n.glyphicon-sound-7-1:before {\n  content: \"\\e193\";\n}\n.glyphicon-copyright-mark:before {\n  content: \"\\e194\";\n}\n.glyphicon-registration-mark:before {\n  content: \"\\e195\";\n}\n.glyphicon-cloud-download:before {\n  content: \"\\e197\";\n}\n.glyphicon-cloud-upload:before {\n  content: \"\\e198\";\n}\n.glyphicon-tree-conifer:before {\n  content: \"\\e199\";\n}\n.glyphicon-tree-deciduous:before {\n  content: \"\\e200\";\n}\n.glyphicon-cd:before {\n  content: \"\\e201\";\n}\n.glyphicon-save-file:before {\n  content: \"\\e202\";\n}\n.glyphicon-open-file:before {\n  content: \"\\e203\";\n}\n.glyphicon-level-up:before {\n  content: \"\\e204\";\n}\n.glyphicon-copy:before {\n  content: \"\\e205\";\n}\n.glyphicon-paste:before {\n  content: \"\\e206\";\n}\n.glyphicon-alert:before {\n  content: \"\\e209\";\n}\n.glyphicon-equalizer:before {\n  content: \"\\e210\";\n}\n.glyphicon-king:before {\n  content: \"\\e211\";\n}\n.glyphicon-queen:before {\n  content: \"\\e212\";\n}\n.glyphicon-pawn:before {\n  content: \"\\e213\";\n}\n.glyphicon-bishop:before {\n  content: \"\\e214\";\n}\n.glyphicon-knight:before {\n  content: \"\\e215\";\n}\n.glyphicon-baby-formula:before {\n  content: \"\\e216\";\n}\n.glyphicon-tent:before {\n  content: \"\\26fa\";\n}\n.glyphicon-blackboard:before {\n  content: \"\\e218\";\n}\n.glyphicon-bed:before {\n  content: \"\\e219\";\n}\n.glyphicon-apple:before {\n  content: \"\\f8ff\";\n}\n.glyphicon-erase:before {\n  content: \"\\e221\";\n}\n.glyphicon-hourglass:before {\n  content: \"\\231b\";\n}\n.glyphicon-lamp:before {\n  content: \"\\e223\";\n}\n.glyphicon-duplicate:before {\n  content: \"\\e224\";\n}\n.glyphicon-piggy-bank:before {\n  content: \"\\e225\";\n}\n.glyphicon-scissors:before {\n  content: \"\\e226\";\n}\n.glyphicon-bitcoin:before {\n  content: \"\\e227\";\n}\n.glyphicon-btc:before {\n  content: \"\\e227\";\n}\n.glyphicon-xbt:before {\n  content: \"\\e227\";\n}\n.glyphicon-yen:before {\n  content: \"\\00a5\";\n}\n.glyphicon-jpy:before {\n  content: \"\\00a5\";\n}\n.glyphicon-ruble:before {\n  content: \"\\20bd\";\n}\n.glyphicon-rub:before {\n  content: \"\\20bd\";\n}\n.glyphicon-scale:before {\n  content: \"\\e230\";\n}\n.glyphicon-ice-lolly:before {\n  content: \"\\e231\";\n}\n.glyphicon-ice-lolly-tasted:before {\n  content: \"\\e232\";\n}\n.glyphicon-education:before {\n  content: \"\\e233\";\n}\n.glyphicon-option-horizontal:before {\n  content: \"\\e234\";\n}\n.glyphicon-option-vertical:before {\n  content: \"\\e235\";\n}\n.glyphicon-menu-hamburger:before {\n  content: \"\\e236\";\n}\n.glyphicon-modal-window:before {\n  content: \"\\e237\";\n}\n.glyphicon-oil:before {\n  content: \"\\e238\";\n}\n.glyphicon-grain:before {\n  content: \"\\e239\";\n}\n.glyphicon-sunglasses:before {\n  content: \"\\e240\";\n}\n.glyphicon-text-size:before {\n  content: \"\\e241\";\n}\n.glyphicon-text-color:before {\n  content: \"\\e242\";\n}\n.glyphicon-text-background:before {\n  content: \"\\e243\";\n}\n.glyphicon-object-align-top:before {\n  content: \"\\e244\";\n}\n.glyphicon-object-align-bottom:before {\n  content: \"\\e245\";\n}\n.glyphicon-object-align-horizontal:before {\n  content: \"\\e246\";\n}\n.glyphicon-object-align-left:before {\n  content: \"\\e247\";\n}\n.glyphicon-object-align-vertical:before {\n  content: \"\\e248\";\n}\n.glyphicon-object-align-right:before {\n  content: \"\\e249\";\n}\n.glyphicon-triangle-right:before {\n  content: \"\\e250\";\n}\n.glyphicon-triangle-left:before {\n  content: \"\\e251\";\n}\n.glyphicon-triangle-bottom:before {\n  content: \"\\e252\";\n}\n.glyphicon-triangle-top:before {\n  content: \"\\e253\";\n}\n.glyphicon-console:before {\n  content: \"\\e254\";\n}\n.glyphicon-superscript:before {\n  content: \"\\e255\";\n}\n.glyphicon-subscript:before {\n  content: \"\\e256\";\n}\n.glyphicon-menu-left:before {\n  content: \"\\e257\";\n}\n.glyphicon-menu-right:before {\n  content: \"\\e258\";\n}\n.glyphicon-menu-down:before {\n  content: \"\\e259\";\n}\n.glyphicon-menu-up:before {\n  content: \"\\e260\";\n}\n* {\n  -webkit-box-sizing: border-box;\n     -moz-box-sizing: border-box;\n          box-sizing: border-box;\n}\n*:before,\n*:after {\n  -webkit-box-sizing: border-box;\n     -moz-box-sizing: border-box;\n          box-sizing: border-box;\n}\nhtml {\n  font-size: 10px;\n\n  -webkit-tap-highlight-color: rgba(0, 0, 0, 0);\n}\nbody {\n  font-family: \"Helvetica Neue\", Helvetica, Arial, sans-serif;\n  font-size: 14px;\n  line-height: 1.42857143;\n  color: #333;\n  background-color: #fff;\n}\ninput,\nbutton,\nselect,\ntextarea {\n  font-family: inherit;\n  font-size: inherit;\n  line-height: inherit;\n}\na {\n  color: #337ab7;\n  text-decoration: none;\n}\na:hover,\na:focus {\n  color: #23527c;\n  text-decoration: underline;\n}\na:focus {\n  outline: thin dotted;\n  outline: 5px auto -webkit-focus-ring-color;\n  outline-offset: -2px;\n}\nfigure {\n  margin: 0;\n}\nimg {\n  vertical-align: middle;\n}\n.img-responsive,\n.thumbnail > img,\n.thumbnail a > img,\n.carousel-inner > .item > img,\n.carousel-inner > .item > a > img {\n  display: block;\n  max-width: 100%;\n  height: auto;\n}\n.img-rounded {\n  border-radius: 6px;\n}\n.img-thumbnail {\n  display: inline-block;\n  max-width: 100%;\n  height: auto;\n  padding: 4px;\n  line-height: 1.42857143;\n  background-color: #fff;\n  border: 1px solid #ddd;\n  border-radius: 4px;\n  -webkit-transition: all .2s ease-in-out;\n       -o-transition: all .2s ease-in-out;\n          transition: all .2s ease-in-out;\n}\n.img-circle {\n  border-radius: 50%;\n}\nhr {\n  margin-top: 20px;\n  margin-bottom: 20px;\n  border: 0;\n  border-top: 1px solid #eee;\n}\n.sr-only {\n  position: absolute;\n  width: 1px;\n  height: 1px;\n  padding: 0;\n  margin: -1px;\n  overflow: hidden;\n  clip: rect(0, 0, 0, 0);\n  border: 0;\n}\n.sr-only-focusable:active,\n.sr-only-focusable:focus {\n  position: static;\n  width: auto;\n  height: auto;\n  margin: 0;\n  overflow: visible;\n  clip: auto;\n}\n[role=\"button\"] {\n  cursor: pointer;\n}\nh1,\nh2,\nh3,\nh4,\nh5,\nh6,\n.h1,\n.h2,\n.h3,\n.h4,\n.h5,\n.h6 {\n  font-family: inherit;\n  font-weight: 500;\n  line-height: 1.1;\n  color: inherit;\n}\nh1 small,\nh2 small,\nh3 small,\nh4 small,\nh5 small,\nh6 small,\n.h1 small,\n.h2 small,\n.h3 small,\n.h4 small,\n.h5 small,\n.h6 small,\nh1 .small,\nh2 .small,\nh3 .small,\nh4 .small,\nh5 .small,\nh6 .small,\n.h1 .small,\n.h2 .small,\n.h3 .small,\n.h4 .small,\n.h5 .small,\n.h6 .small {\n  font-weight: normal;\n  line-height: 1;\n  color: #777;\n}\nh1,\n.h1,\nh2,\n.h2,\nh3,\n.h3 {\n  margin-top: 20px;\n  margin-bottom: 10px;\n}\nh1 small,\n.h1 small,\nh2 small,\n.h2 small,\nh3 small,\n.h3 small,\nh1 .small,\n.h1 .small,\nh2 .small,\n.h2 .small,\nh3 .small,\n.h3 .small {\n  font-size: 65%;\n}\nh4,\n.h4,\nh5,\n.h5,\nh6,\n.h6 {\n  margin-top: 10px;\n  margin-bottom: 10px;\n}\nh4 small,\n.h4 small,\nh5 small,\n.h5 small,\nh6 small,\n.h6 small,\nh4 .small,\n.h4 .small,\nh5 .small,\n.h5 .small,\nh6 .small,\n.h6 .small {\n  font-size: 75%;\n}\nh1,\n.h1 {\n  font-size: 36px;\n}\nh2,\n.h2 {\n  font-size: 30px;\n}\nh3,\n.h3 {\n  font-size: 24px;\n}\nh4,\n.h4 {\n  font-size: 18px;\n}\nh5,\n.h5 {\n  font-size: 14px;\n}\nh6,\n.h6 {\n  font-size: 12px;\n}\np {\n  margin: 0 0 10px;\n}\n.lead {\n  margin-bottom: 20px;\n  font-size: 16px;\n  font-weight: 300;\n  line-height: 1.4;\n}\n@media (min-width: 768px) {\n  .lead {\n    font-size: 21px;\n  }\n}\nsmall,\n.small {\n  font-size: 85%;\n}\nmark,\n.mark {\n  padding: .2em;\n  background-color: #fcf8e3;\n}\n.text-left {\n  text-align: left;\n}\n.text-right {\n  text-align: right;\n}\n.text-center {\n  text-align: center;\n}\n.text-justify {\n  text-align: justify;\n}\n.text-nowrap {\n  white-space: nowrap;\n}\n.text-lowercase {\n  text-transform: lowercase;\n}\n.text-uppercase {\n  text-transform: uppercase;\n}\n.text-capitalize {\n  text-transform: capitalize;\n}\n.text-muted {\n  color: #777;\n}\n.text-primary {\n  color: #337ab7;\n}\na.text-primary:hover,\na.text-primary:focus {\n  color: #286090;\n}\n.text-success {\n  color: #3c763d;\n}\na.text-success:hover,\na.text-success:focus {\n  color: #2b542c;\n}\n.text-info {\n  color: #31708f;\n}\na.text-info:hover,\na.text-info:focus {\n  color: #245269;\n}\n.text-warning {\n  color: #8a6d3b;\n}\na.text-warning:hover,\na.text-warning:focus {\n  color: #66512c;\n}\n.text-danger {\n  color: #a94442;\n}\na.text-danger:hover,\na.text-danger:focus {\n  color: #843534;\n}\n.bg-primary {\n  color: #fff;\n  background-color: #337ab7;\n}\na.bg-primary:hover,\na.bg-primary:focus {\n  background-color: #286090;\n}\n.bg-success {\n  background-color: #dff0d8;\n}\na.bg-success:hover,\na.bg-success:focus {\n  background-color: #c1e2b3;\n}\n.bg-info {\n  background-color: #d9edf7;\n}\na.bg-info:hover,\na.bg-info:focus {\n  background-color: #afd9ee;\n}\n.bg-warning {\n  background-color: #fcf8e3;\n}\na.bg-warning:hover,\na.bg-warning:focus {\n  background-color: #f7ecb5;\n}\n.bg-danger {\n  background-color: #f2dede;\n}\na.bg-danger:hover,\na.bg-danger:focus {\n  background-color: #e4b9b9;\n}\n.page-header {\n  padding-bottom: 9px;\n  margin: 40px 0 20px;\n  border-bottom: 1px solid #eee;\n}\nul,\nol {\n  margin-top: 0;\n  margin-bottom: 10px;\n}\nul ul,\nol ul,\nul ol,\nol ol {\n  margin-bottom: 0;\n}\n.list-unstyled {\n  padding-left: 0;\n  list-style: none;\n}\n.list-inline {\n  padding-left: 0;\n  margin-left: -5px;\n  list-style: none;\n}\n.list-inline > li {\n  display: inline-block;\n  padding-right: 5px;\n  padding-left: 5px;\n}\ndl {\n  margin-top: 0;\n  margin-bottom: 20px;\n}\ndt,\ndd {\n  line-height: 1.42857143;\n}\ndt {\n  font-weight: bold;\n}\ndd {\n  margin-left: 0;\n}\n@media (min-width: 768px) {\n  .dl-horizontal dt {\n    float: left;\n    width: 160px;\n    overflow: hidden;\n    clear: left;\n    text-align: right;\n    text-overflow: ellipsis;\n    white-space: nowrap;\n  }\n  .dl-horizontal dd {\n    margin-left: 180px;\n  }\n}\nabbr[title],\nabbr[data-original-title] {\n  cursor: help;\n  border-bottom: 1px dotted #777;\n}\n.initialism {\n  font-size: 90%;\n  text-transform: uppercase;\n}\nblockquote {\n  padding: 10px 20px;\n  margin: 0 0 20px;\n  font-size: 17.5px;\n  border-left: 5px solid #eee;\n}\nblockquote p:last-child,\nblockquote ul:last-child,\nblockquote ol:last-child {\n  margin-bottom: 0;\n}\nblockquote footer,\nblockquote small,\nblockquote .small {\n  display: block;\n  font-size: 80%;\n  line-height: 1.42857143;\n  color: #777;\n}\nblockquote footer:before,\nblockquote small:before,\nblockquote .small:before {\n  content: '\\2014 \\00A0';\n}\n.blockquote-reverse,\nblockquote.pull-right {\n  padding-right: 15px;\n  padding-left: 0;\n  text-align: right;\n  border-right: 5px solid #eee;\n  border-left: 0;\n}\n.blockquote-reverse footer:before,\nblockquote.pull-right footer:before,\n.blockquote-reverse small:before,\nblockquote.pull-right small:before,\n.blockquote-reverse .small:before,\nblockquote.pull-right .small:before {\n  content: '';\n}\n.blockquote-reverse footer:after,\nblockquote.pull-right footer:after,\n.blockquote-reverse small:after,\nblockquote.pull-right small:after,\n.blockquote-reverse .small:after,\nblockquote.pull-right .small:after {\n  content: '\\00A0 \\2014';\n}\naddress {\n  margin-bottom: 20px;\n  font-style: normal;\n  line-height: 1.42857143;\n}\ncode,\nkbd,\npre,\nsamp {\n  font-family: Menlo, Monaco, Consolas, \"Courier New\", monospace;\n}\ncode {\n  padding: 2px 4px;\n  font-size: 90%;\n  color: #c7254e;\n  background-color: #f9f2f4;\n  border-radius: 4px;\n}\nkbd {\n  padding: 2px 4px;\n  font-size: 90%;\n  color: #fff;\n  background-color: #333;\n  border-radius: 3px;\n  -webkit-box-shadow: inset 0 -1px 0 rgba(0, 0, 0, .25);\n          box-shadow: inset 0 -1px 0 rgba(0, 0, 0, .25);\n}\nkbd kbd {\n  padding: 0;\n  font-size: 100%;\n  font-weight: bold;\n  -webkit-box-shadow: none;\n          box-shadow: none;\n}\npre {\n  display: block;\n  padding: 9.5px;\n  margin: 0 0 10px;\n  font-size: 13px;\n  line-height: 1.42857143;\n  color: #333;\n  word-break: break-all;\n  word-wrap: break-word;\n  background-color: #f5f5f5;\n  border: 1px solid #ccc;\n  border-radius: 4px;\n}\npre code {\n  padding: 0;\n  font-size: inherit;\n  color: inherit;\n  white-space: pre-wrap;\n  background-color: transparent;\n  border-radius: 0;\n}\n.pre-scrollable {\n  max-height: 340px;\n  overflow-y: scroll;\n}\n.container {\n  padding-right: 15px;\n  padding-left: 15px;\n  margin-right: auto;\n  margin-left: auto;\n}\n@media (min-width: 768px) {\n  .container {\n    width: 750px;\n  }\n}\n@media (min-width: 992px) {\n  .container {\n    width: 970px;\n  }\n}\n@media (min-width: 1200px) {\n  .container {\n    width: 1170px;\n  }\n}\n.container-fluid {\n  padding-right: 15px;\n  padding-left: 15px;\n  margin-right: auto;\n  margin-left: auto;\n}\n.row {\n  margin-right: -15px;\n  margin-left: -15px;\n}\n.col-xs-1, .col-sm-1, .col-md-1, .col-lg-1, .col-xs-2, .col-sm-2, .col-md-2, .col-lg-2, .col-xs-3, .col-sm-3, .col-md-3, .col-lg-3, .col-xs-4, .col-sm-4, .col-md-4, .col-lg-4, .col-xs-5, .col-sm-5, .col-md-5, .col-lg-5, .col-xs-6, .col-sm-6, .col-md-6, .col-lg-6, .col-xs-7, .col-sm-7, .col-md-7, .col-lg-7, .col-xs-8, .col-sm-8, .col-md-8, .col-lg-8, .col-xs-9, .col-sm-9, .col-md-9, .col-lg-9, .col-xs-10, .col-sm-10, .col-md-10, .col-lg-10, .col-xs-11, .col-sm-11, .col-md-11, .col-lg-11, .col-xs-12, .col-sm-12, .col-md-12, .col-lg-12 {\n  position: relative;\n  min-height: 1px;\n  padding-right: 15px;\n  padding-left: 15px;\n}\n.col-xs-1, .col-xs-2, .col-xs-3, .col-xs-4, .col-xs-5, .col-xs-6, .col-xs-7, .col-xs-8, .col-xs-9, .col-xs-10, .col-xs-11, .col-xs-12 {\n  float: left;\n}\n.col-xs-12 {\n  width: 100%;\n}\n.col-xs-11 {\n  width: 91.66666667%;\n}\n.col-xs-10 {\n  width: 83.33333333%;\n}\n.col-xs-9 {\n  width: 75%;\n}\n.col-xs-8 {\n  width: 66.66666667%;\n}\n.col-xs-7 {\n  width: 58.33333333%;\n}\n.col-xs-6 {\n  width: 50%;\n}\n.col-xs-5 {\n  width: 41.66666667%;\n}\n.col-xs-4 {\n  width: 33.33333333%;\n}\n.col-xs-3 {\n  width: 25%;\n}\n.col-xs-2 {\n  width: 16.66666667%;\n}\n.col-xs-1 {\n  width: 8.33333333%;\n}\n.col-xs-pull-12 {\n  right: 100%;\n}\n.col-xs-pull-11 {\n  right: 91.66666667%;\n}\n.col-xs-pull-10 {\n  right: 83.33333333%;\n}\n.col-xs-pull-9 {\n  right: 75%;\n}\n.col-xs-pull-8 {\n  right: 66.66666667%;\n}\n.col-xs-pull-7 {\n  right: 58.33333333%;\n}\n.col-xs-pull-6 {\n  right: 50%;\n}\n.col-xs-pull-5 {\n  right: 41.66666667%;\n}\n.col-xs-pull-4 {\n  right: 33.33333333%;\n}\n.col-xs-pull-3 {\n  right: 25%;\n}\n.col-xs-pull-2 {\n  right: 16.66666667%;\n}\n.col-xs-pull-1 {\n  right: 8.33333333%;\n}\n.col-xs-pull-0 {\n  right: auto;\n}\n.col-xs-push-12 {\n  left: 100%;\n}\n.col-xs-push-11 {\n  left: 91.66666667%;\n}\n.col-xs-push-10 {\n  left: 83.33333333%;\n}\n.col-xs-push-9 {\n  left: 75%;\n}\n.col-xs-push-8 {\n  left: 66.66666667%;\n}\n.col-xs-push-7 {\n  left: 58.33333333%;\n}\n.col-xs-push-6 {\n  left: 50%;\n}\n.col-xs-push-5 {\n  left: 41.66666667%;\n}\n.col-xs-push-4 {\n  left: 33.33333333%;\n}\n.col-xs-push-3 {\n  left: 25%;\n}\n.col-xs-push-2 {\n  left: 16.66666667%;\n}\n.col-xs-push-1 {\n  left: 8.33333333%;\n}\n.col-xs-push-0 {\n  left: auto;\n}\n.col-xs-offset-12 {\n  margin-left: 100%;\n}\n.col-xs-offset-11 {\n  margin-left: 91.66666667%;\n}\n.col-xs-offset-10 {\n  margin-left: 83.33333333%;\n}\n.col-xs-offset-9 {\n  margin-left: 75%;\n}\n.col-xs-offset-8 {\n  margin-left: 66.66666667%;\n}\n.col-xs-offset-7 {\n  margin-left: 58.33333333%;\n}\n.col-xs-offset-6 {\n  margin-left: 50%;\n}\n.col-xs-offset-5 {\n  margin-left: 41.66666667%;\n}\n.col-xs-offset-4 {\n  margin-left: 33.33333333%;\n}\n.col-xs-offset-3 {\n  margin-left: 25%;\n}\n.col-xs-offset-2 {\n  margin-left: 16.66666667%;\n}\n.col-xs-offset-1 {\n  margin-left: 8.33333333%;\n}\n.col-xs-offset-0 {\n  margin-left: 0;\n}\n@media (min-width: 768px) {\n  .col-sm-1, .col-sm-2, .col-sm-3, .col-sm-4, .col-sm-5, .col-sm-6, .col-sm-7, .col-sm-8, .col-sm-9, .col-sm-10, .col-sm-11, .col-sm-12 {\n    float: left;\n  }\n  .col-sm-12 {\n    width: 100%;\n  }\n  .col-sm-11 {\n    width: 91.66666667%;\n  }\n  .col-sm-10 {\n    width: 83.33333333%;\n  }\n  .col-sm-9 {\n    width: 75%;\n  }\n  .col-sm-8 {\n    width: 66.66666667%;\n  }\n  .col-sm-7 {\n    width: 58.33333333%;\n  }\n  .col-sm-6 {\n    width: 50%;\n  }\n  .col-sm-5 {\n    width: 41.66666667%;\n  }\n  .col-sm-4 {\n    width: 33.33333333%;\n  }\n  .col-sm-3 {\n    width: 25%;\n  }\n  .col-sm-2 {\n    width: 16.66666667%;\n  }\n  .col-sm-1 {\n    width: 8.33333333%;\n  }\n  .col-sm-pull-12 {\n    right: 100%;\n  }\n  .col-sm-pull-11 {\n    right: 91.66666667%;\n  }\n  .col-sm-pull-10 {\n    right: 83.33333333%;\n  }\n  .col-sm-pull-9 {\n    right: 75%;\n  }\n  .col-sm-pull-8 {\n    right: 66.66666667%;\n  }\n  .col-sm-pull-7 {\n    right: 58.33333333%;\n  }\n  .col-sm-pull-6 {\n    right: 50%;\n  }\n  .col-sm-pull-5 {\n    right: 41.66666667%;\n  }\n  .col-sm-pull-4 {\n    right: 33.33333333%;\n  }\n  .col-sm-pull-3 {\n    right: 25%;\n  }\n  .col-sm-pull-2 {\n    right: 16.66666667%;\n  }\n  .col-sm-pull-1 {\n    right: 8.33333333%;\n  }\n  .col-sm-pull-0 {\n    right: auto;\n  }\n  .col-sm-push-12 {\n    left: 100%;\n  }\n  .col-sm-push-11 {\n    left: 91.66666667%;\n  }\n  .col-sm-push-10 {\n    left: 83.33333333%;\n  }\n  .col-sm-push-9 {\n    left: 75%;\n  }\n  .col-sm-push-8 {\n    left: 66.66666667%;\n  }\n  .col-sm-push-7 {\n    left: 58.33333333%;\n  }\n  .col-sm-push-6 {\n    left: 50%;\n  }\n  .col-sm-push-5 {\n    left: 41.66666667%;\n  }\n  .col-sm-push-4 {\n    left: 33.33333333%;\n  }\n  .col-sm-push-3 {\n    left: 25%;\n  }\n  .col-sm-push-2 {\n    left: 16.66666667%;\n  }\n  .col-sm-push-1 {\n    left: 8.33333333%;\n  }\n  .col-sm-push-0 {\n    left: auto;\n  }\n  .col-sm-offset-12 {\n    margin-left: 100%;\n  }\n  .col-sm-offset-11 {\n    margin-left: 91.66666667%;\n  }\n  .col-sm-offset-10 {\n    margin-left: 83.33333333%;\n  }\n  .col-sm-offset-9 {\n    margin-left: 75%;\n  }\n  .col-sm-offset-8 {\n    margin-left: 66.66666667%;\n  }\n  .col-sm-offset-7 {\n    margin-left: 58.33333333%;\n  }\n  .col-sm-offset-6 {\n    margin-left: 50%;\n  }\n  .col-sm-offset-5 {\n    margin-left: 41.66666667%;\n  }\n  .col-sm-offset-4 {\n    margin-left: 33.33333333%;\n  }\n  .col-sm-offset-3 {\n    margin-left: 25%;\n  }\n  .col-sm-offset-2 {\n    margin-left: 16.66666667%;\n  }\n  .col-sm-offset-1 {\n    margin-left: 8.33333333%;\n  }\n  .col-sm-offset-0 {\n    margin-left: 0;\n  }\n}\n@media (min-width: 992px) {\n  .col-md-1, .col-md-2, .col-md-3, .col-md-4, .col-md-5, .col-md-6, .col-md-7, .col-md-8, .col-md-9, .col-md-10, .col-md-11, .col-md-12 {\n    float: left;\n  }\n  .col-md-12 {\n    width: 100%;\n  }\n  .col-md-11 {\n    width: 91.66666667%;\n  }\n  .col-md-10 {\n    width: 83.33333333%;\n  }\n  .col-md-9 {\n    width: 75%;\n  }\n  .col-md-8 {\n    width: 66.66666667%;\n  }\n  .col-md-7 {\n    width: 58.33333333%;\n  }\n  .col-md-6 {\n    width: 50%;\n  }\n  .col-md-5 {\n    width: 41.66666667%;\n  }\n  .col-md-4 {\n    width: 33.33333333%;\n  }\n  .col-md-3 {\n    width: 25%;\n  }\n  .col-md-2 {\n    width: 16.66666667%;\n  }\n  .col-md-1 {\n    width: 8.33333333%;\n  }\n  .col-md-pull-12 {\n    right: 100%;\n  }\n  .col-md-pull-11 {\n    right: 91.66666667%;\n  }\n  .col-md-pull-10 {\n    right: 83.33333333%;\n  }\n  .col-md-pull-9 {\n    right: 75%;\n  }\n  .col-md-pull-8 {\n    right: 66.66666667%;\n  }\n  .col-md-pull-7 {\n    right: 58.33333333%;\n  }\n  .col-md-pull-6 {\n    right: 50%;\n  }\n  .col-md-pull-5 {\n    right: 41.66666667%;\n  }\n  .col-md-pull-4 {\n    right: 33.33333333%;\n  }\n  .col-md-pull-3 {\n    right: 25%;\n  }\n  .col-md-pull-2 {\n    right: 16.66666667%;\n  }\n  .col-md-pull-1 {\n    right: 8.33333333%;\n  }\n  .col-md-pull-0 {\n    right: auto;\n  }\n  .col-md-push-12 {\n    left: 100%;\n  }\n  .col-md-push-11 {\n    left: 91.66666667%;\n  }\n  .col-md-push-10 {\n    left: 83.33333333%;\n  }\n  .col-md-push-9 {\n    left: 75%;\n  }\n  .col-md-push-8 {\n    left: 66.66666667%;\n  }\n  .col-md-push-7 {\n    left: 58.33333333%;\n  }\n  .col-md-push-6 {\n    left: 50%;\n  }\n  .col-md-push-5 {\n    left: 41.66666667%;\n  }\n  .col-md-push-4 {\n    left: 33.33333333%;\n  }\n  .col-md-push-3 {\n    left: 25%;\n  }\n  .col-md-push-2 {\n    left: 16.66666667%;\n  }\n  .col-md-push-1 {\n    left: 8.33333333%;\n  }\n  .col-md-push-0 {\n    left: auto;\n  }\n  .col-md-offset-12 {\n    margin-left: 100%;\n  }\n  .col-md-offset-11 {\n    margin-left: 91.66666667%;\n  }\n  .col-md-offset-10 {\n    margin-left: 83.33333333%;\n  }\n  .col-md-offset-9 {\n    margin-left: 75%;\n  }\n  .col-md-offset-8 {\n    margin-left: 66.66666667%;\n  }\n  .col-md-offset-7 {\n    margin-left: 58.33333333%;\n  }\n  .col-md-offset-6 {\n    margin-left: 50%;\n  }\n  .col-md-offset-5 {\n    margin-left: 41.66666667%;\n  }\n  .col-md-offset-4 {\n    margin-left: 33.33333333%;\n  }\n  .col-md-offset-3 {\n    margin-left: 25%;\n  }\n  .col-md-offset-2 {\n    margin-left: 16.66666667%;\n  }\n  .col-md-offset-1 {\n    margin-left: 8.33333333%;\n  }\n  .col-md-offset-0 {\n    margin-left: 0;\n  }\n}\n@media (min-width: 1200px) {\n  .col-lg-1, .col-lg-2, .col-lg-3, .col-lg-4, .col-lg-5, .col-lg-6, .col-lg-7, .col-lg-8, .col-lg-9, .col-lg-10, .col-lg-11, .col-lg-12 {\n    float: left;\n  }\n  .col-lg-12 {\n    width: 100%;\n  }\n  .col-lg-11 {\n    width: 91.66666667%;\n  }\n  .col-lg-10 {\n    width: 83.33333333%;\n  }\n  .col-lg-9 {\n    width: 75%;\n  }\n  .col-lg-8 {\n    width: 66.66666667%;\n  }\n  .col-lg-7 {\n    width: 58.33333333%;\n  }\n  .col-lg-6 {\n    width: 50%;\n  }\n  .col-lg-5 {\n    width: 41.66666667%;\n  }\n  .col-lg-4 {\n    width: 33.33333333%;\n  }\n  .col-lg-3 {\n    width: 25%;\n  }\n  .col-lg-2 {\n    width: 16.66666667%;\n  }\n  .col-lg-1 {\n    width: 8.33333333%;\n  }\n  .col-lg-pull-12 {\n    right: 100%;\n  }\n  .col-lg-pull-11 {\n    right: 91.66666667%;\n  }\n  .col-lg-pull-10 {\n    right: 83.33333333%;\n  }\n  .col-lg-pull-9 {\n    right: 75%;\n  }\n  .col-lg-pull-8 {\n    right: 66.66666667%;\n  }\n  .col-lg-pull-7 {\n    right: 58.33333333%;\n  }\n  .col-lg-pull-6 {\n    right: 50%;\n  }\n  .col-lg-pull-5 {\n    right: 41.66666667%;\n  }\n  .col-lg-pull-4 {\n    right: 33.33333333%;\n  }\n  .col-lg-pull-3 {\n    right: 25%;\n  }\n  .col-lg-pull-2 {\n    right: 16.66666667%;\n  }\n  .col-lg-pull-1 {\n    right: 8.33333333%;\n  }\n  .col-lg-pull-0 {\n    right: auto;\n  }\n  .col-lg-push-12 {\n    left: 100%;\n  }\n  .col-lg-push-11 {\n    left: 91.66666667%;\n  }\n  .col-lg-push-10 {\n    left: 83.33333333%;\n  }\n  .col-lg-push-9 {\n    left: 75%;\n  }\n  .col-lg-push-8 {\n    left: 66.66666667%;\n  }\n  .col-lg-push-7 {\n    left: 58.33333333%;\n  }\n  .col-lg-push-6 {\n    left: 50%;\n  }\n  .col-lg-push-5 {\n    left: 41.66666667%;\n  }\n  .col-lg-push-4 {\n    left: 33.33333333%;\n  }\n  .col-lg-push-3 {\n    left: 25%;\n  }\n  .col-lg-push-2 {\n    left: 16.66666667%;\n  }\n  .col-lg-push-1 {\n    left: 8.33333333%;\n  }\n  .col-lg-push-0 {\n    left: auto;\n  }\n  .col-lg-offset-12 {\n    margin-left: 100%;\n  }\n  .col-lg-offset-11 {\n    margin-left: 91.66666667%;\n  }\n  .col-lg-offset-10 {\n    margin-left: 83.33333333%;\n  }\n  .col-lg-offset-9 {\n    margin-left: 75%;\n  }\n  .col-lg-offset-8 {\n    margin-left: 66.66666667%;\n  }\n  .col-lg-offset-7 {\n    margin-left: 58.33333333%;\n  }\n  .col-lg-offset-6 {\n    margin-left: 50%;\n  }\n  .col-lg-offset-5 {\n    margin-left: 41.66666667%;\n  }\n  .col-lg-offset-4 {\n    margin-left: 33.33333333%;\n  }\n  .col-lg-offset-3 {\n    margin-left: 25%;\n  }\n  .col-lg-offset-2 {\n    margin-left: 16.66666667%;\n  }\n  .col-lg-offset-1 {\n    margin-left: 8.33333333%;\n  }\n  .col-lg-offset-0 {\n    margin-left: 0;\n  }\n}\ntable {\n  background-color: transparent;\n}\ncaption {\n  padding-top: 8px;\n  padding-bottom: 8px;\n  color: #777;\n  text-align: left;\n}\nth {\n  text-align: left;\n}\n.table {\n  width: 100%;\n  max-width: 100%;\n  margin-bottom: 20px;\n}\n.table > thead > tr > th,\n.table > tbody > tr > th,\n.table > tfoot > tr > th,\n.table > thead > tr > td,\n.table > tbody > tr > td,\n.table > tfoot > tr > td {\n  padding: 8px;\n  line-height: 1.42857143;\n  vertical-align: top;\n  border-top: 1px solid #ddd;\n}\n.table > thead > tr > th {\n  vertical-align: bottom;\n  border-bottom: 2px solid #ddd;\n}\n.table > caption + thead > tr:first-child > th,\n.table > colgroup + thead > tr:first-child > th,\n.table > thead:first-child > tr:first-child > th,\n.table > caption + thead > tr:first-child > td,\n.table > colgroup + thead > tr:first-child > td,\n.table > thead:first-child > tr:first-child > td {\n  border-top: 0;\n}\n.table > tbody + tbody {\n  border-top: 2px solid #ddd;\n}\n.table .table {\n  background-color: #fff;\n}\n.table-condensed > thead > tr > th,\n.table-condensed > tbody > tr > th,\n.table-condensed > tfoot > tr > th,\n.table-condensed > thead > tr > td,\n.table-condensed > tbody > tr > td,\n.table-condensed > tfoot > tr > td {\n  padding: 5px;\n}\n.table-bordered {\n  border: 1px solid #ddd;\n}\n.table-bordered > thead > tr > th,\n.table-bordered > tbody > tr > th,\n.table-bordered > tfoot > tr > th,\n.table-bordered > thead > tr > td,\n.table-bordered > tbody > tr > td,\n.table-bordered > tfoot > tr > td {\n  border: 1px solid #ddd;\n}\n.table-bordered > thead > tr > th,\n.table-bordered > thead > tr > td {\n  border-bottom-width: 2px;\n}\n.table-striped > tbody > tr:nth-of-type(odd) {\n  background-color: #f9f9f9;\n}\n.table-hover > tbody > tr:hover {\n  background-color: #f5f5f5;\n}\ntable col[class*=\"col-\"] {\n  position: static;\n  display: table-column;\n  float: none;\n}\ntable td[class*=\"col-\"],\ntable th[class*=\"col-\"] {\n  position: static;\n  display: table-cell;\n  float: none;\n}\n.table > thead > tr > td.active,\n.table > tbody > tr > td.active,\n.table > tfoot > tr > td.active,\n.table > thead > tr > th.active,\n.table > tbody > tr > th.active,\n.table > tfoot > tr > th.active,\n.table > thead > tr.active > td,\n.table > tbody > tr.active > td,\n.table > tfoot > tr.active > td,\n.table > thead > tr.active > th,\n.table > tbody > tr.active > th,\n.table > tfoot > tr.active > th {\n  background-color: #f5f5f5;\n}\n.table-hover > tbody > tr > td.active:hover,\n.table-hover > tbody > tr > th.active:hover,\n.table-hover > tbody > tr.active:hover > td,\n.table-hover > tbody > tr:hover > .active,\n.table-hover > tbody > tr.active:hover > th {\n  background-color: #e8e8e8;\n}\n.table > thead > tr > td.success,\n.table > tbody > tr > td.success,\n.table > tfoot > tr > td.success,\n.table > thead > tr > th.success,\n.table > tbody > tr > th.success,\n.table > tfoot > tr > th.success,\n.table > thead > tr.success > td,\n.table > tbody > tr.success > td,\n.table > tfoot > tr.success > td,\n.table > thead > tr.success > th,\n.table > tbody > tr.success > th,\n.table > tfoot > tr.success > th {\n  background-color: #dff0d8;\n}\n.table-hover > tbody > tr > td.success:hover,\n.table-hover > tbody > tr > th.success:hover,\n.table-hover > tbody > tr.success:hover > td,\n.table-hover > tbody > tr:hover > .success,\n.table-hover > tbody > tr.success:hover > th {\n  background-color: #d0e9c6;\n}\n.table > thead > tr > td.info,\n.table > tbody > tr > td.info,\n.table > tfoot > tr > td.info,\n.table > thead > tr > th.info,\n.table > tbody > tr > th.info,\n.table > tfoot > tr > th.info,\n.table > thead > tr.info > td,\n.table > tbody > tr.info > td,\n.table > tfoot > tr.info > td,\n.table > thead > tr.info > th,\n.table > tbody > tr.info > th,\n.table > tfoot > tr.info > th {\n  background-color: #d9edf7;\n}\n.table-hover > tbody > tr > td.info:hover,\n.table-hover > tbody > tr > th.info:hover,\n.table-hover > tbody > tr.info:hover > td,\n.table-hover > tbody > tr:hover > .info,\n.table-hover > tbody > tr.info:hover > th {\n  background-color: #c4e3f3;\n}\n.table > thead > tr > td.warning,\n.table > tbody > tr > td.warning,\n.table > tfoot > tr > td.warning,\n.table > thead > tr > th.warning,\n.table > tbody > tr > th.warning,\n.table > tfoot > tr > th.warning,\n.table > thead > tr.warning > td,\n.table > tbody > tr.warning > td,\n.table > tfoot > tr.warning > td,\n.table > thead > tr.warning > th,\n.table > tbody > tr.warning > th,\n.table > tfoot > tr.warning > th {\n  background-color: #fcf8e3;\n}\n.table-hover > tbody > tr > td.warning:hover,\n.table-hover > tbody > tr > th.warning:hover,\n.table-hover > tbody > tr.warning:hover > td,\n.table-hover > tbody > tr:hover > .warning,\n.table-hover > tbody > tr.warning:hover > th {\n  background-color: #faf2cc;\n}\n.table > thead > tr > td.danger,\n.table > tbody > tr > td.danger,\n.table > tfoot > tr > td.danger,\n.table > thead > tr > th.danger,\n.table > tbody > tr > th.danger,\n.table > tfoot > tr > th.danger,\n.table > thead > tr.danger > td,\n.table > tbody > tr.danger > td,\n.table > tfoot > tr.danger > td,\n.table > thead > tr.danger > th,\n.table > tbody > tr.danger > th,\n.table > tfoot > tr.danger > th {\n  background-color: #f2dede;\n}\n.table-hover > tbody > tr > td.danger:hover,\n.table-hover > tbody > tr > th.danger:hover,\n.table-hover > tbody > tr.danger:hover > td,\n.table-hover > tbody > tr:hover > .danger,\n.table-hover > tbody > tr.danger:hover > th {\n  background-color: #ebcccc;\n}\n.table-responsive {\n  min-height: .01%;\n  overflow-x: auto;\n}\n@media screen and (max-width: 767px) {\n  .table-responsive {\n    width: 100%;\n    margin-bottom: 15px;\n    overflow-y: hidden;\n    -ms-overflow-style: -ms-autohiding-scrollbar;\n    border: 1px solid #ddd;\n  }\n  .table-responsive > .table {\n    margin-bottom: 0;\n  }\n  .table-responsive > .table > thead > tr > th,\n  .table-responsive > .table > tbody > tr > th,\n  .table-responsive > .table > tfoot > tr > th,\n  .table-responsive > .table > thead > tr > td,\n  .table-responsive > .table > tbody > tr > td,\n  .table-responsive > .table > tfoot > tr > td {\n    white-space: nowrap;\n  }\n  .table-responsive > .table-bordered {\n    border: 0;\n  }\n  .table-responsive > .table-bordered > thead > tr > th:first-child,\n  .table-responsive > .table-bordered > tbody > tr > th:first-child,\n  .table-responsive > .table-bordered > tfoot > tr > th:first-child,\n  .table-responsive > .table-bordered > thead > tr > td:first-child,\n  .table-responsive > .table-bordered > tbody > tr > td:first-child,\n  .table-responsive > .table-bordered > tfoot > tr > td:first-child {\n    border-left: 0;\n  }\n  .table-responsive > .table-bordered > thead > tr > th:last-child,\n  .table-responsive > .table-bordered > tbody > tr > th:last-child,\n  .table-responsive > .table-bordered > tfoot > tr > th:last-child,\n  .table-responsive > .table-bordered > thead > tr > td:last-child,\n  .table-responsive > .table-bordered > tbody > tr > td:last-child,\n  .table-responsive > .table-bordered > tfoot > tr > td:last-child {\n    border-right: 0;\n  }\n  .table-responsive > .table-bordered > tbody > tr:last-child > th,\n  .table-responsive > .table-bordered > tfoot > tr:last-child > th,\n  .table-responsive > .table-bordered > tbody > tr:last-child > td,\n  .table-responsive > .table-bordered > tfoot > tr:last-child > td {\n    border-bottom: 0;\n  }\n}\nfieldset {\n  min-width: 0;\n  padding: 0;\n  margin: 0;\n  border: 0;\n}\nlegend {\n  display: block;\n  width: 100%;\n  padding: 0;\n  margin-bottom: 20px;\n  font-size: 21px;\n  line-height: inherit;\n  color: #333;\n  border: 0;\n  border-bottom: 1px solid #e5e5e5;\n}\nlabel {\n  display: inline-block;\n  max-width: 100%;\n  margin-bottom: 5px;\n  font-weight: bold;\n}\ninput[type=\"search\"] {\n  -webkit-box-sizing: border-box;\n     -moz-box-sizing: border-box;\n          box-sizing: border-box;\n}\ninput[type=\"radio\"],\ninput[type=\"checkbox\"] {\n  margin: 4px 0 0;\n  margin-top: 1px \\9;\n  line-height: normal;\n}\ninput[type=\"file\"] {\n  display: block;\n}\ninput[type=\"range\"] {\n  display: block;\n  width: 100%;\n}\nselect[multiple],\nselect[size] {\n  height: auto;\n}\ninput[type=\"file\"]:focus,\ninput[type=\"radio\"]:focus,\ninput[type=\"checkbox\"]:focus {\n  outline: thin dotted;\n  outline: 5px auto -webkit-focus-ring-color;\n  outline-offset: -2px;\n}\noutput {\n  display: block;\n  padding-top: 7px;\n  font-size: 14px;\n  line-height: 1.42857143;\n  color: #555;\n}\n.form-control {\n  display: block;\n  width: 100%;\n  height: 34px;\n  padding: 6px 12px;\n  font-size: 14px;\n  line-height: 1.42857143;\n  color: #555;\n  background-color: #fff;\n  background-image: none;\n  border: 1px solid #ccc;\n  border-radius: 4px;\n  -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075);\n          box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075);\n  -webkit-transition: border-color ease-in-out .15s, -webkit-box-shadow ease-in-out .15s;\n       -o-transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s;\n          transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s;\n}\n.form-control:focus {\n  border-color: #66afe9;\n  outline: 0;\n  -webkit-box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(102, 175, 233, .6);\n          box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(102, 175, 233, .6);\n}\n.form-control::-moz-placeholder {\n  color: #999;\n  opacity: 1;\n}\n.form-control:-ms-input-placeholder {\n  color: #999;\n}\n.form-control::-webkit-input-placeholder {\n  color: #999;\n}\n.form-control[disabled],\n.form-control[readonly],\nfieldset[disabled] .form-control {\n  background-color: #eee;\n  opacity: 1;\n}\n.form-control[disabled],\nfieldset[disabled] .form-control {\n  cursor: not-allowed;\n}\ntextarea.form-control {\n  height: auto;\n}\ninput[type=\"search\"] {\n  -webkit-appearance: none;\n}\n@media screen and (-webkit-min-device-pixel-ratio: 0) {\n  input[type=\"date\"].form-control,\n  input[type=\"time\"].form-control,\n  input[type=\"datetime-local\"].form-control,\n  input[type=\"month\"].form-control {\n    line-height: 34px;\n  }\n  input[type=\"date\"].input-sm,\n  input[type=\"time\"].input-sm,\n  input[type=\"datetime-local\"].input-sm,\n  input[type=\"month\"].input-sm,\n  .input-group-sm input[type=\"date\"],\n  .input-group-sm input[type=\"time\"],\n  .input-group-sm input[type=\"datetime-local\"],\n  .input-group-sm input[type=\"month\"] {\n    line-height: 30px;\n  }\n  input[type=\"date\"].input-lg,\n  input[type=\"time\"].input-lg,\n  input[type=\"datetime-local\"].input-lg,\n  input[type=\"month\"].input-lg,\n  .input-group-lg input[type=\"date\"],\n  .input-group-lg input[type=\"time\"],\n  .input-group-lg input[type=\"datetime-local\"],\n  .input-group-lg input[type=\"month\"] {\n    line-height: 46px;\n  }\n}\n.form-group {\n  margin-bottom: 15px;\n}\n.radio,\n.checkbox {\n  position: relative;\n  display: block;\n  margin-top: 10px;\n  margin-bottom: 10px;\n}\n.radio label,\n.checkbox label {\n  min-height: 20px;\n  padding-left: 20px;\n  margin-bottom: 0;\n  font-weight: normal;\n  cursor: pointer;\n}\n.radio input[type=\"radio\"],\n.radio-inline input[type=\"radio\"],\n.checkbox input[type=\"checkbox\"],\n.checkbox-inline input[type=\"checkbox\"] {\n  position: absolute;\n  margin-top: 4px \\9;\n  margin-left: -20px;\n}\n.radio + .radio,\n.checkbox + .checkbox {\n  margin-top: -5px;\n}\n.radio-inline,\n.checkbox-inline {\n  position: relative;\n  display: inline-block;\n  padding-left: 20px;\n  margin-bottom: 0;\n  font-weight: normal;\n  vertical-align: middle;\n  cursor: pointer;\n}\n.radio-inline + .radio-inline,\n.checkbox-inline + .checkbox-inline {\n  margin-top: 0;\n  margin-left: 10px;\n}\ninput[type=\"radio\"][disabled],\ninput[type=\"checkbox\"][disabled],\ninput[type=\"radio\"].disabled,\ninput[type=\"checkbox\"].disabled,\nfieldset[disabled] input[type=\"radio\"],\nfieldset[disabled] input[type=\"checkbox\"] {\n  cursor: not-allowed;\n}\n.radio-inline.disabled,\n.checkbox-inline.disabled,\nfieldset[disabled] .radio-inline,\nfieldset[disabled] .checkbox-inline {\n  cursor: not-allowed;\n}\n.radio.disabled label,\n.checkbox.disabled label,\nfieldset[disabled] .radio label,\nfieldset[disabled] .checkbox label {\n  cursor: not-allowed;\n}\n.form-control-static {\n  min-height: 34px;\n  padding-top: 7px;\n  padding-bottom: 7px;\n  margin-bottom: 0;\n}\n.form-control-static.input-lg,\n.form-control-static.input-sm {\n  padding-right: 0;\n  padding-left: 0;\n}\n.input-sm {\n  height: 30px;\n  padding: 5px 10px;\n  font-size: 12px;\n  line-height: 1.5;\n  border-radius: 3px;\n}\nselect.input-sm {\n  height: 30px;\n  line-height: 30px;\n}\ntextarea.input-sm,\nselect[multiple].input-sm {\n  height: auto;\n}\n.form-group-sm .form-control {\n  height: 30px;\n  padding: 5px 10px;\n  font-size: 12px;\n  line-height: 1.5;\n  border-radius: 3px;\n}\n.form-group-sm select.form-control {\n  height: 30px;\n  line-height: 30px;\n}\n.form-group-sm textarea.form-control,\n.form-group-sm select[multiple].form-control {\n  height: auto;\n}\n.form-group-sm .form-control-static {\n  height: 30px;\n  min-height: 32px;\n  padding: 6px 10px;\n  font-size: 12px;\n  line-height: 1.5;\n}\n.input-lg {\n  height: 46px;\n  padding: 10px 16px;\n  font-size: 18px;\n  line-height: 1.3333333;\n  border-radius: 6px;\n}\nselect.input-lg {\n  height: 46px;\n  line-height: 46px;\n}\ntextarea.input-lg,\nselect[multiple].input-lg {\n  height: auto;\n}\n.form-group-lg .form-control {\n  height: 46px;\n  padding: 10px 16px;\n  font-size: 18px;\n  line-height: 1.3333333;\n  border-radius: 6px;\n}\n.form-group-lg select.form-control {\n  height: 46px;\n  line-height: 46px;\n}\n.form-group-lg textarea.form-control,\n.form-group-lg select[multiple].form-control {\n  height: auto;\n}\n.form-group-lg .form-control-static {\n  height: 46px;\n  min-height: 38px;\n  padding: 11px 16px;\n  font-size: 18px;\n  line-height: 1.3333333;\n}\n.has-feedback {\n  position: relative;\n}\n.has-feedback .form-control {\n  padding-right: 42.5px;\n}\n.form-control-feedback {\n  position: absolute;\n  top: 0;\n  right: 0;\n  z-index: 2;\n  display: block;\n  width: 34px;\n  height: 34px;\n  line-height: 34px;\n  text-align: center;\n  pointer-events: none;\n}\n.input-lg + .form-control-feedback,\n.input-group-lg + .form-control-feedback,\n.form-group-lg .form-control + .form-control-feedback {\n  width: 46px;\n  height: 46px;\n  line-height: 46px;\n}\n.input-sm + .form-control-feedback,\n.input-group-sm + .form-control-feedback,\n.form-group-sm .form-control + .form-control-feedback {\n  width: 30px;\n  height: 30px;\n  line-height: 30px;\n}\n.has-success .help-block,\n.has-success .control-label,\n.has-success .radio,\n.has-success .checkbox,\n.has-success .radio-inline,\n.has-success .checkbox-inline,\n.has-success.radio label,\n.has-success.checkbox label,\n.has-success.radio-inline label,\n.has-success.checkbox-inline label {\n  color: #3c763d;\n}\n.has-success .form-control {\n  border-color: #3c763d;\n  -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075);\n          box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075);\n}\n.has-success .form-control:focus {\n  border-color: #2b542c;\n  -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 6px #67b168;\n          box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 6px #67b168;\n}\n.has-success .input-group-addon {\n  color: #3c763d;\n  background-color: #dff0d8;\n  border-color: #3c763d;\n}\n.has-success .form-control-feedback {\n  color: #3c763d;\n}\n.has-warning .help-block,\n.has-warning .control-label,\n.has-warning .radio,\n.has-warning .checkbox,\n.has-warning .radio-inline,\n.has-warning .checkbox-inline,\n.has-warning.radio label,\n.has-warning.checkbox label,\n.has-warning.radio-inline label,\n.has-warning.checkbox-inline label {\n  color: #8a6d3b;\n}\n.has-warning .form-control {\n  border-color: #8a6d3b;\n  -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075);\n          box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075);\n}\n.has-warning .form-control:focus {\n  border-color: #66512c;\n  -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 6px #c0a16b;\n          box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 6px #c0a16b;\n}\n.has-warning .input-group-addon {\n  color: #8a6d3b;\n  background-color: #fcf8e3;\n  border-color: #8a6d3b;\n}\n.has-warning .form-control-feedback {\n  color: #8a6d3b;\n}\n.has-error .help-block,\n.has-error .control-label,\n.has-error .radio,\n.has-error .checkbox,\n.has-error .radio-inline,\n.has-error .checkbox-inline,\n.has-error.radio label,\n.has-error.checkbox label,\n.has-error.radio-inline label,\n.has-error.checkbox-inline label {\n  color: #a94442;\n}\n.has-error .form-control {\n  border-color: #a94442;\n  -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075);\n          box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075);\n}\n.has-error .form-control:focus {\n  border-color: #843534;\n  -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 6px #ce8483;\n          box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 6px #ce8483;\n}\n.has-error .input-group-addon {\n  color: #a94442;\n  background-color: #f2dede;\n  border-color: #a94442;\n}\n.has-error .form-control-feedback {\n  color: #a94442;\n}\n.has-feedback label ~ .form-control-feedback {\n  top: 25px;\n}\n.has-feedback label.sr-only ~ .form-control-feedback {\n  top: 0;\n}\n.help-block {\n  display: block;\n  margin-top: 5px;\n  margin-bottom: 10px;\n  color: #737373;\n}\n@media (min-width: 768px) {\n  .form-inline .form-group {\n    display: inline-block;\n    margin-bottom: 0;\n    vertical-align: middle;\n  }\n  .form-inline .form-control {\n    display: inline-block;\n    width: auto;\n    vertical-align: middle;\n  }\n  .form-inline .form-control-static {\n    display: inline-block;\n  }\n  .form-inline .input-group {\n    display: inline-table;\n    vertical-align: middle;\n  }\n  .form-inline .input-group .input-group-addon,\n  .form-inline .input-group .input-group-btn,\n  .form-inline .input-group .form-control {\n    width: auto;\n  }\n  .form-inline .input-group > .form-control {\n    width: 100%;\n  }\n  .form-inline .control-label {\n    margin-bottom: 0;\n    vertical-align: middle;\n  }\n  .form-inline .radio,\n  .form-inline .checkbox {\n    display: inline-block;\n    margin-top: 0;\n    margin-bottom: 0;\n    vertical-align: middle;\n  }\n  .form-inline .radio label,\n  .form-inline .checkbox label {\n    padding-left: 0;\n  }\n  .form-inline .radio input[type=\"radio\"],\n  .form-inline .checkbox input[type=\"checkbox\"] {\n    position: relative;\n    margin-left: 0;\n  }\n  .form-inline .has-feedback .form-control-feedback {\n    top: 0;\n  }\n}\n.form-horizontal .radio,\n.form-horizontal .checkbox,\n.form-horizontal .radio-inline,\n.form-horizontal .checkbox-inline {\n  padding-top: 7px;\n  margin-top: 0;\n  margin-bottom: 0;\n}\n.form-horizontal .radio,\n.form-horizontal .checkbox {\n  min-height: 27px;\n}\n.form-horizontal .form-group {\n  margin-right: -15px;\n  margin-left: -15px;\n}\n@media (min-width: 768px) {\n  .form-horizontal .control-label {\n    padding-top: 7px;\n    margin-bottom: 0;\n    text-align: right;\n  }\n}\n.form-horizontal .has-feedback .form-control-feedback {\n  right: 15px;\n}\n@media (min-width: 768px) {\n  .form-horizontal .form-group-lg .control-label {\n    padding-top: 14.333333px;\n    font-size: 18px;\n  }\n}\n@media (min-width: 768px) {\n  .form-horizontal .form-group-sm .control-label {\n    padding-top: 6px;\n    font-size: 12px;\n  }\n}\n.btn {\n  display: inline-block;\n  padding: 6px 12px;\n  margin-bottom: 0;\n  font-size: 14px;\n  font-weight: normal;\n  line-height: 1.42857143;\n  text-align: center;\n  white-space: nowrap;\n  vertical-align: middle;\n  -ms-touch-action: manipulation;\n      touch-action: manipulation;\n  cursor: pointer;\n  -webkit-user-select: none;\n     -moz-user-select: none;\n      -ms-user-select: none;\n          user-select: none;\n  background-image: none;\n  border: 1px solid transparent;\n  border-radius: 4px;\n}\n.btn:focus,\n.btn:active:focus,\n.btn.active:focus,\n.btn.focus,\n.btn:active.focus,\n.btn.active.focus {\n  outline: thin dotted;\n  outline: 5px auto -webkit-focus-ring-color;\n  outline-offset: -2px;\n}\n.btn:hover,\n.btn:focus,\n.btn.focus {\n  color: #333;\n  text-decoration: none;\n}\n.btn:active,\n.btn.active {\n  background-image: none;\n  outline: 0;\n  -webkit-box-shadow: inset 0 3px 5px rgba(0, 0, 0, .125);\n          box-shadow: inset 0 3px 5px rgba(0, 0, 0, .125);\n}\n.btn.disabled,\n.btn[disabled],\nfieldset[disabled] .btn {\n  cursor: not-allowed;\n  filter: alpha(opacity=65);\n  -webkit-box-shadow: none;\n          box-shadow: none;\n  opacity: .65;\n}\na.btn.disabled,\nfieldset[disabled] a.btn {\n  pointer-events: none;\n}\n.btn-default {\n  color: #333;\n  background-color: #fff;\n  border-color: #ccc;\n}\n.btn-default:focus,\n.btn-default.focus {\n  color: #333;\n  background-color: #e6e6e6;\n  border-color: #8c8c8c;\n}\n.btn-default:hover {\n  color: #333;\n  background-color: #e6e6e6;\n  border-color: #adadad;\n}\n.btn-default:active,\n.btn-default.active,\n.open > .dropdown-toggle.btn-default {\n  color: #333;\n  background-color: #e6e6e6;\n  border-color: #adadad;\n}\n.btn-default:active:hover,\n.btn-default.active:hover,\n.open > .dropdown-toggle.btn-default:hover,\n.btn-default:active:focus,\n.btn-default.active:focus,\n.open > .dropdown-toggle.btn-default:focus,\n.btn-default:active.focus,\n.btn-default.active.focus,\n.open > .dropdown-toggle.btn-default.focus {\n  color: #333;\n  background-color: #d4d4d4;\n  border-color: #8c8c8c;\n}\n.btn-default:active,\n.btn-default.active,\n.open > .dropdown-toggle.btn-default {\n  background-image: none;\n}\n.btn-default.disabled,\n.btn-default[disabled],\nfieldset[disabled] .btn-default,\n.btn-default.disabled:hover,\n.btn-default[disabled]:hover,\nfieldset[disabled] .btn-default:hover,\n.btn-default.disabled:focus,\n.btn-default[disabled]:focus,\nfieldset[disabled] .btn-default:focus,\n.btn-default.disabled.focus,\n.btn-default[disabled].focus,\nfieldset[disabled] .btn-default.focus,\n.btn-default.disabled:active,\n.btn-default[disabled]:active,\nfieldset[disabled] .btn-default:active,\n.btn-default.disabled.active,\n.btn-default[disabled].active,\nfieldset[disabled] .btn-default.active {\n  background-color: #fff;\n  border-color: #ccc;\n}\n.btn-default .badge {\n  color: #fff;\n  background-color: #333;\n}\n.btn-primary {\n  color: #fff;\n  background-color: #337ab7;\n  border-color: #2e6da4;\n}\n.btn-primary:focus,\n.btn-primary.focus {\n  color: #fff;\n  background-color: #286090;\n  border-color: #122b40;\n}\n.btn-primary:hover {\n  color: #fff;\n  background-color: #286090;\n  border-color: #204d74;\n}\n.btn-primary:active,\n.btn-primary.active,\n.open > .dropdown-toggle.btn-primary {\n  color: #fff;\n  background-color: #286090;\n  border-color: #204d74;\n}\n.btn-primary:active:hover,\n.btn-primary.active:hover,\n.open > .dropdown-toggle.btn-primary:hover,\n.btn-primary:active:focus,\n.btn-primary.active:focus,\n.open > .dropdown-toggle.btn-primary:focus,\n.btn-primary:active.focus,\n.btn-primary.active.focus,\n.open > .dropdown-toggle.btn-primary.focus {\n  color: #fff;\n  background-color: #204d74;\n  border-color: #122b40;\n}\n.btn-primary:active,\n.btn-primary.active,\n.open > .dropdown-toggle.btn-primary {\n  background-image: none;\n}\n.btn-primary.disabled,\n.btn-primary[disabled],\nfieldset[disabled] .btn-primary,\n.btn-primary.disabled:hover,\n.btn-primary[disabled]:hover,\nfieldset[disabled] .btn-primary:hover,\n.btn-primary.disabled:focus,\n.btn-primary[disabled]:focus,\nfieldset[disabled] .btn-primary:focus,\n.btn-primary.disabled.focus,\n.btn-primary[disabled].focus,\nfieldset[disabled] .btn-primary.focus,\n.btn-primary.disabled:active,\n.btn-primary[disabled]:active,\nfieldset[disabled] .btn-primary:active,\n.btn-primary.disabled.active,\n.btn-primary[disabled].active,\nfieldset[disabled] .btn-primary.active {\n  background-color: #337ab7;\n  border-color: #2e6da4;\n}\n.btn-primary .badge {\n  color: #337ab7;\n  background-color: #fff;\n}\n.btn-success {\n  color: #fff;\n  background-color: #5cb85c;\n  border-color: #4cae4c;\n}\n.btn-success:focus,\n.btn-success.focus {\n  color: #fff;\n  background-color: #449d44;\n  border-color: #255625;\n}\n.btn-success:hover {\n  color: #fff;\n  background-color: #449d44;\n  border-color: #398439;\n}\n.btn-success:active,\n.btn-success.active,\n.open > .dropdown-toggle.btn-success {\n  color: #fff;\n  background-color: #449d44;\n  border-color: #398439;\n}\n.btn-success:active:hover,\n.btn-success.active:hover,\n.open > .dropdown-toggle.btn-success:hover,\n.btn-success:active:focus,\n.btn-success.active:focus,\n.open > .dropdown-toggle.btn-success:focus,\n.btn-success:active.focus,\n.btn-success.active.focus,\n.open > .dropdown-toggle.btn-success.focus {\n  color: #fff;\n  background-color: #398439;\n  border-color: #255625;\n}\n.btn-success:active,\n.btn-success.active,\n.open > .dropdown-toggle.btn-success {\n  background-image: none;\n}\n.btn-success.disabled,\n.btn-success[disabled],\nfieldset[disabled] .btn-success,\n.btn-success.disabled:hover,\n.btn-success[disabled]:hover,\nfieldset[disabled] .btn-success:hover,\n.btn-success.disabled:focus,\n.btn-success[disabled]:focus,\nfieldset[disabled] .btn-success:focus,\n.btn-success.disabled.focus,\n.btn-success[disabled].focus,\nfieldset[disabled] .btn-success.focus,\n.btn-success.disabled:active,\n.btn-success[disabled]:active,\nfieldset[disabled] .btn-success:active,\n.btn-success.disabled.active,\n.btn-success[disabled].active,\nfieldset[disabled] .btn-success.active {\n  background-color: #5cb85c;\n  border-color: #4cae4c;\n}\n.btn-success .badge {\n  color: #5cb85c;\n  background-color: #fff;\n}\n.btn-info {\n  color: #fff;\n  background-color: #5bc0de;\n  border-color: #46b8da;\n}\n.btn-info:focus,\n.btn-info.focus {\n  color: #fff;\n  background-color: #31b0d5;\n  border-color: #1b6d85;\n}\n.btn-info:hover {\n  color: #fff;\n  background-color: #31b0d5;\n  border-color: #269abc;\n}\n.btn-info:active,\n.btn-info.active,\n.open > .dropdown-toggle.btn-info {\n  color: #fff;\n  background-color: #31b0d5;\n  border-color: #269abc;\n}\n.btn-info:active:hover,\n.btn-info.active:hover,\n.open > .dropdown-toggle.btn-info:hover,\n.btn-info:active:focus,\n.btn-info.active:focus,\n.open > .dropdown-toggle.btn-info:focus,\n.btn-info:active.focus,\n.btn-info.active.focus,\n.open > .dropdown-toggle.btn-info.focus {\n  color: #fff;\n  background-color: #269abc;\n  border-color: #1b6d85;\n}\n.btn-info:active,\n.btn-info.active,\n.open > .dropdown-toggle.btn-info {\n  background-image: none;\n}\n.btn-info.disabled,\n.btn-info[disabled],\nfieldset[disabled] .btn-info,\n.btn-info.disabled:hover,\n.btn-info[disabled]:hover,\nfieldset[disabled] .btn-info:hover,\n.btn-info.disabled:focus,\n.btn-info[disabled]:focus,\nfieldset[disabled] .btn-info:focus,\n.btn-info.disabled.focus,\n.btn-info[disabled].focus,\nfieldset[disabled] .btn-info.focus,\n.btn-info.disabled:active,\n.btn-info[disabled]:active,\nfieldset[disabled] .btn-info:active,\n.btn-info.disabled.active,\n.btn-info[disabled].active,\nfieldset[disabled] .btn-info.active {\n  background-color: #5bc0de;\n  border-color: #46b8da;\n}\n.btn-info .badge {\n  color: #5bc0de;\n  background-color: #fff;\n}\n.btn-warning {\n  color: #fff;\n  background-color: #f0ad4e;\n  border-color: #eea236;\n}\n.btn-warning:focus,\n.btn-warning.focus {\n  color: #fff;\n  background-color: #ec971f;\n  border-color: #985f0d;\n}\n.btn-warning:hover {\n  color: #fff;\n  background-color: #ec971f;\n  border-color: #d58512;\n}\n.btn-warning:active,\n.btn-warning.active,\n.open > .dropdown-toggle.btn-warning {\n  color: #fff;\n  background-color: #ec971f;\n  border-color: #d58512;\n}\n.btn-warning:active:hover,\n.btn-warning.active:hover,\n.open > .dropdown-toggle.btn-warning:hover,\n.btn-warning:active:focus,\n.btn-warning.active:focus,\n.open > .dropdown-toggle.btn-warning:focus,\n.btn-warning:active.focus,\n.btn-warning.active.focus,\n.open > .dropdown-toggle.btn-warning.focus {\n  color: #fff;\n  background-color: #d58512;\n  border-color: #985f0d;\n}\n.btn-warning:active,\n.btn-warning.active,\n.open > .dropdown-toggle.btn-warning {\n  background-image: none;\n}\n.btn-warning.disabled,\n.btn-warning[disabled],\nfieldset[disabled] .btn-warning,\n.btn-warning.disabled:hover,\n.btn-warning[disabled]:hover,\nfieldset[disabled] .btn-warning:hover,\n.btn-warning.disabled:focus,\n.btn-warning[disabled]:focus,\nfieldset[disabled] .btn-warning:focus,\n.btn-warning.disabled.focus,\n.btn-warning[disabled].focus,\nfieldset[disabled] .btn-warning.focus,\n.btn-warning.disabled:active,\n.btn-warning[disabled]:active,\nfieldset[disabled] .btn-warning:active,\n.btn-warning.disabled.active,\n.btn-warning[disabled].active,\nfieldset[disabled] .btn-warning.active {\n  background-color: #f0ad4e;\n  border-color: #eea236;\n}\n.btn-warning .badge {\n  color: #f0ad4e;\n  background-color: #fff;\n}\n.btn-danger {\n  color: #fff;\n  background-color: #d9534f;\n  border-color: #d43f3a;\n}\n.btn-danger:focus,\n.btn-danger.focus {\n  color: #fff;\n  background-color: #c9302c;\n  border-color: #761c19;\n}\n.btn-danger:hover {\n  color: #fff;\n  background-color: #c9302c;\n  border-color: #ac2925;\n}\n.btn-danger:active,\n.btn-danger.active,\n.open > .dropdown-toggle.btn-danger {\n  color: #fff;\n  background-color: #c9302c;\n  border-color: #ac2925;\n}\n.btn-danger:active:hover,\n.btn-danger.active:hover,\n.open > .dropdown-toggle.btn-danger:hover,\n.btn-danger:active:focus,\n.btn-danger.active:focus,\n.open > .dropdown-toggle.btn-danger:focus,\n.btn-danger:active.focus,\n.btn-danger.active.focus,\n.open > .dropdown-toggle.btn-danger.focus {\n  color: #fff;\n  background-color: #ac2925;\n  border-color: #761c19;\n}\n.btn-danger:active,\n.btn-danger.active,\n.open > .dropdown-toggle.btn-danger {\n  background-image: none;\n}\n.btn-danger.disabled,\n.btn-danger[disabled],\nfieldset[disabled] .btn-danger,\n.btn-danger.disabled:hover,\n.btn-danger[disabled]:hover,\nfieldset[disabled] .btn-danger:hover,\n.btn-danger.disabled:focus,\n.btn-danger[disabled]:focus,\nfieldset[disabled] .btn-danger:focus,\n.btn-danger.disabled.focus,\n.btn-danger[disabled].focus,\nfieldset[disabled] .btn-danger.focus,\n.btn-danger.disabled:active,\n.btn-danger[disabled]:active,\nfieldset[disabled] .btn-danger:active,\n.btn-danger.disabled.active,\n.btn-danger[disabled].active,\nfieldset[disabled] .btn-danger.active {\n  background-color: #d9534f;\n  border-color: #d43f3a;\n}\n.btn-danger .badge {\n  color: #d9534f;\n  background-color: #fff;\n}\n.btn-link {\n  font-weight: normal;\n  color: #337ab7;\n  border-radius: 0;\n}\n.btn-link,\n.btn-link:active,\n.btn-link.active,\n.btn-link[disabled],\nfieldset[disabled] .btn-link {\n  background-color: transparent;\n  -webkit-box-shadow: none;\n          box-shadow: none;\n}\n.btn-link,\n.btn-link:hover,\n.btn-link:focus,\n.btn-link:active {\n  border-color: transparent;\n}\n.btn-link:hover,\n.btn-link:focus {\n  color: #23527c;\n  text-decoration: underline;\n  background-color: transparent;\n}\n.btn-link[disabled]:hover,\nfieldset[disabled] .btn-link:hover,\n.btn-link[disabled]:focus,\nfieldset[disabled] .btn-link:focus {\n  color: #777;\n  text-decoration: none;\n}\n.btn-lg,\n.btn-group-lg > .btn {\n  padding: 10px 16px;\n  font-size: 18px;\n  line-height: 1.3333333;\n  border-radius: 6px;\n}\n.btn-sm,\n.btn-group-sm > .btn {\n  padding: 5px 10px;\n  font-size: 12px;\n  line-height: 1.5;\n  border-radius: 3px;\n}\n.btn-xs,\n.btn-group-xs > .btn {\n  padding: 1px 5px;\n  font-size: 12px;\n  line-height: 1.5;\n  border-radius: 3px;\n}\n.btn-block {\n  display: block;\n  width: 100%;\n}\n.btn-block + .btn-block {\n  margin-top: 5px;\n}\ninput[type=\"submit\"].btn-block,\ninput[type=\"reset\"].btn-block,\ninput[type=\"button\"].btn-block {\n  width: 100%;\n}\n.fade {\n  opacity: 0;\n  -webkit-transition: opacity .15s linear;\n       -o-transition: opacity .15s linear;\n          transition: opacity .15s linear;\n}\n.fade.in {\n  opacity: 1;\n}\n.collapse {\n  display: none;\n}\n.collapse.in {\n  display: block;\n}\ntr.collapse.in {\n  display: table-row;\n}\ntbody.collapse.in {\n  display: table-row-group;\n}\n.collapsing {\n  position: relative;\n  height: 0;\n  overflow: hidden;\n  -webkit-transition-timing-function: ease;\n       -o-transition-timing-function: ease;\n          transition-timing-function: ease;\n  -webkit-transition-duration: .35s;\n       -o-transition-duration: .35s;\n          transition-duration: .35s;\n  -webkit-transition-property: height, visibility;\n       -o-transition-property: height, visibility;\n          transition-property: height, visibility;\n}\n.caret {\n  display: inline-block;\n  width: 0;\n  height: 0;\n  margin-left: 2px;\n  vertical-align: middle;\n  border-top: 4px dashed;\n  border-top: 4px solid \\9;\n  border-right: 4px solid transparent;\n  border-left: 4px solid transparent;\n}\n.dropup,\n.dropdown {\n  position: relative;\n}\n.dropdown-toggle:focus {\n  outline: 0;\n}\n.dropdown-menu {\n  position: absolute;\n  top: 100%;\n  left: 0;\n  z-index: 1000;\n  display: none;\n  float: left;\n  min-width: 160px;\n  padding: 5px 0;\n  margin: 2px 0 0;\n  font-size: 14px;\n  text-align: left;\n  list-style: none;\n  background-color: #fff;\n  -webkit-background-clip: padding-box;\n          background-clip: padding-box;\n  border: 1px solid #ccc;\n  border: 1px solid rgba(0, 0, 0, .15);\n  border-radius: 4px;\n  -webkit-box-shadow: 0 6px 12px rgba(0, 0, 0, .175);\n          box-shadow: 0 6px 12px rgba(0, 0, 0, .175);\n}\n.dropdown-menu.pull-right {\n  right: 0;\n  left: auto;\n}\n.dropdown-menu .divider {\n  height: 1px;\n  margin: 9px 0;\n  overflow: hidden;\n  background-color: #e5e5e5;\n}\n.dropdown-menu > li > a {\n  display: block;\n  padding: 3px 20px;\n  clear: both;\n  font-weight: normal;\n  line-height: 1.42857143;\n  color: #333;\n  white-space: nowrap;\n}\n.dropdown-menu > li > a:hover,\n.dropdown-menu > li > a:focus {\n  color: #262626;\n  text-decoration: none;\n  background-color: #f5f5f5;\n}\n.dropdown-menu > .active > a,\n.dropdown-menu > .active > a:hover,\n.dropdown-menu > .active > a:focus {\n  color: #fff;\n  text-decoration: none;\n  background-color: #337ab7;\n  outline: 0;\n}\n.dropdown-menu > .disabled > a,\n.dropdown-menu > .disabled > a:hover,\n.dropdown-menu > .disabled > a:focus {\n  color: #777;\n}\n.dropdown-menu > .disabled > a:hover,\n.dropdown-menu > .disabled > a:focus {\n  text-decoration: none;\n  cursor: not-allowed;\n  background-color: transparent;\n  background-image: none;\n  filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);\n}\n.open > .dropdown-menu {\n  display: block;\n}\n.open > a {\n  outline: 0;\n}\n.dropdown-menu-right {\n  right: 0;\n  left: auto;\n}\n.dropdown-menu-left {\n  right: auto;\n  left: 0;\n}\n.dropdown-header {\n  display: block;\n  padding: 3px 20px;\n  font-size: 12px;\n  line-height: 1.42857143;\n  color: #777;\n  white-space: nowrap;\n}\n.dropdown-backdrop {\n  position: fixed;\n  top: 0;\n  right: 0;\n  bottom: 0;\n  left: 0;\n  z-index: 990;\n}\n.pull-right > .dropdown-menu {\n  right: 0;\n  left: auto;\n}\n.dropup .caret,\n.navbar-fixed-bottom .dropdown .caret {\n  content: \"\";\n  border-top: 0;\n  border-bottom: 4px dashed;\n  border-bottom: 4px solid \\9;\n}\n.dropup .dropdown-menu,\n.navbar-fixed-bottom .dropdown .dropdown-menu {\n  top: auto;\n  bottom: 100%;\n  margin-bottom: 2px;\n}\n@media (min-width: 768px) {\n  .navbar-right .dropdown-menu {\n    right: 0;\n    left: auto;\n  }\n  .navbar-right .dropdown-menu-left {\n    right: auto;\n    left: 0;\n  }\n}\n.btn-group,\n.btn-group-vertical {\n  position: relative;\n  display: inline-block;\n  vertical-align: middle;\n}\n.btn-group > .btn,\n.btn-group-vertical > .btn {\n  position: relative;\n  float: left;\n}\n.btn-group > .btn:hover,\n.btn-group-vertical > .btn:hover,\n.btn-group > .btn:focus,\n.btn-group-vertical > .btn:focus,\n.btn-group > .btn:active,\n.btn-group-vertical > .btn:active,\n.btn-group > .btn.active,\n.btn-group-vertical > .btn.active {\n  z-index: 2;\n}\n.btn-group .btn + .btn,\n.btn-group .btn + .btn-group,\n.btn-group .btn-group + .btn,\n.btn-group .btn-group + .btn-group {\n  margin-left: -1px;\n}\n.btn-toolbar {\n  margin-left: -5px;\n}\n.btn-toolbar .btn,\n.btn-toolbar .btn-group,\n.btn-toolbar .input-group {\n  float: left;\n}\n.btn-toolbar > .btn,\n.btn-toolbar > .btn-group,\n.btn-toolbar > .input-group {\n  margin-left: 5px;\n}\n.btn-group > .btn:not(:first-child):not(:last-child):not(.dropdown-toggle) {\n  border-radius: 0;\n}\n.btn-group > .btn:first-child {\n  margin-left: 0;\n}\n.btn-group > .btn:first-child:not(:last-child):not(.dropdown-toggle) {\n  border-top-right-radius: 0;\n  border-bottom-right-radius: 0;\n}\n.btn-group > .btn:last-child:not(:first-child),\n.btn-group > .dropdown-toggle:not(:first-child) {\n  border-top-left-radius: 0;\n  border-bottom-left-radius: 0;\n}\n.btn-group > .btn-group {\n  float: left;\n}\n.btn-group > .btn-group:not(:first-child):not(:last-child) > .btn {\n  border-radius: 0;\n}\n.btn-group > .btn-group:first-child:not(:last-child) > .btn:last-child,\n.btn-group > .btn-group:first-child:not(:last-child) > .dropdown-toggle {\n  border-top-right-radius: 0;\n  border-bottom-right-radius: 0;\n}\n.btn-group > .btn-group:last-child:not(:first-child) > .btn:first-child {\n  border-top-left-radius: 0;\n  border-bottom-left-radius: 0;\n}\n.btn-group .dropdown-toggle:active,\n.btn-group.open .dropdown-toggle {\n  outline: 0;\n}\n.btn-group > .btn + .dropdown-toggle {\n  padding-right: 8px;\n  padding-left: 8px;\n}\n.btn-group > .btn-lg + .dropdown-toggle {\n  padding-right: 12px;\n  padding-left: 12px;\n}\n.btn-group.open .dropdown-toggle {\n  -webkit-box-shadow: inset 0 3px 5px rgba(0, 0, 0, .125);\n          box-shadow: inset 0 3px 5px rgba(0, 0, 0, .125);\n}\n.btn-group.open .dropdown-toggle.btn-link {\n  -webkit-box-shadow: none;\n          box-shadow: none;\n}\n.btn .caret {\n  margin-left: 0;\n}\n.btn-lg .caret {\n  border-width: 5px 5px 0;\n  border-bottom-width: 0;\n}\n.dropup .btn-lg .caret {\n  border-width: 0 5px 5px;\n}\n.btn-group-vertical > .btn,\n.btn-group-vertical > .btn-group,\n.btn-group-vertical > .btn-group > .btn {\n  display: block;\n  float: none;\n  width: 100%;\n  max-width: 100%;\n}\n.btn-group-vertical > .btn-group > .btn {\n  float: none;\n}\n.btn-group-vertical > .btn + .btn,\n.btn-group-vertical > .btn + .btn-group,\n.btn-group-vertical > .btn-group + .btn,\n.btn-group-vertical > .btn-group + .btn-group {\n  margin-top: -1px;\n  margin-left: 0;\n}\n.btn-group-vertical > .btn:not(:first-child):not(:last-child) {\n  border-radius: 0;\n}\n.btn-group-vertical > .btn:first-child:not(:last-child) {\n  border-top-right-radius: 4px;\n  border-bottom-right-radius: 0;\n  border-bottom-left-radius: 0;\n}\n.btn-group-vertical > .btn:last-child:not(:first-child) {\n  border-top-left-radius: 0;\n  border-top-right-radius: 0;\n  border-bottom-left-radius: 4px;\n}\n.btn-group-vertical > .btn-group:not(:first-child):not(:last-child) > .btn {\n  border-radius: 0;\n}\n.btn-group-vertical > .btn-group:first-child:not(:last-child) > .btn:last-child,\n.btn-group-vertical > .btn-group:first-child:not(:last-child) > .dropdown-toggle {\n  border-bottom-right-radius: 0;\n  border-bottom-left-radius: 0;\n}\n.btn-group-vertical > .btn-group:last-child:not(:first-child) > .btn:first-child {\n  border-top-left-radius: 0;\n  border-top-right-radius: 0;\n}\n.btn-group-justified {\n  display: table;\n  width: 100%;\n  table-layout: fixed;\n  border-collapse: separate;\n}\n.btn-group-justified > .btn,\n.btn-group-justified > .btn-group {\n  display: table-cell;\n  float: none;\n  width: 1%;\n}\n.btn-group-justified > .btn-group .btn {\n  width: 100%;\n}\n.btn-group-justified > .btn-group .dropdown-menu {\n  left: auto;\n}\n[data-toggle=\"buttons\"] > .btn input[type=\"radio\"],\n[data-toggle=\"buttons\"] > .btn-group > .btn input[type=\"radio\"],\n[data-toggle=\"buttons\"] > .btn input[type=\"checkbox\"],\n[data-toggle=\"buttons\"] > .btn-group > .btn input[type=\"checkbox\"] {\n  position: absolute;\n  clip: rect(0, 0, 0, 0);\n  pointer-events: none;\n}\n.input-group {\n  position: relative;\n  display: table;\n  border-collapse: separate;\n}\n.input-group[class*=\"col-\"] {\n  float: none;\n  padding-right: 0;\n  padding-left: 0;\n}\n.input-group .form-control {\n  position: relative;\n  z-index: 2;\n  float: left;\n  width: 100%;\n  margin-bottom: 0;\n}\n.input-group-lg > .form-control,\n.input-group-lg > .input-group-addon,\n.input-group-lg > .input-group-btn > .btn {\n  height: 46px;\n  padding: 10px 16px;\n  font-size: 18px;\n  line-height: 1.3333333;\n  border-radius: 6px;\n}\nselect.input-group-lg > .form-control,\nselect.input-group-lg > .input-group-addon,\nselect.input-group-lg > .input-group-btn > .btn {\n  height: 46px;\n  line-height: 46px;\n}\ntextarea.input-group-lg > .form-control,\ntextarea.input-group-lg > .input-group-addon,\ntextarea.input-group-lg > .input-group-btn > .btn,\nselect[multiple].input-group-lg > .form-control,\nselect[multiple].input-group-lg > .input-group-addon,\nselect[multiple].input-group-lg > .input-group-btn > .btn {\n  height: auto;\n}\n.input-group-sm > .form-control,\n.input-group-sm > .input-group-addon,\n.input-group-sm > .input-group-btn > .btn {\n  height: 30px;\n  padding: 5px 10px;\n  font-size: 12px;\n  line-height: 1.5;\n  border-radius: 3px;\n}\nselect.input-group-sm > .form-control,\nselect.input-group-sm > .input-group-addon,\nselect.input-group-sm > .input-group-btn > .btn {\n  height: 30px;\n  line-height: 30px;\n}\ntextarea.input-group-sm > .form-control,\ntextarea.input-group-sm > .input-group-addon,\ntextarea.input-group-sm > .input-group-btn > .btn,\nselect[multiple].input-group-sm > .form-control,\nselect[multiple].input-group-sm > .input-group-addon,\nselect[multiple].input-group-sm > .input-group-btn > .btn {\n  height: auto;\n}\n.input-group-addon,\n.input-group-btn,\n.input-group .form-control {\n  display: table-cell;\n}\n.input-group-addon:not(:first-child):not(:last-child),\n.input-group-btn:not(:first-child):not(:last-child),\n.input-group .form-control:not(:first-child):not(:last-child) {\n  border-radius: 0;\n}\n.input-group-addon,\n.input-group-btn {\n  width: 1%;\n  white-space: nowrap;\n  vertical-align: middle;\n}\n.input-group-addon {\n  padding: 6px 12px;\n  font-size: 14px;\n  font-weight: normal;\n  line-height: 1;\n  color: #555;\n  text-align: center;\n  background-color: #eee;\n  border: 1px solid #ccc;\n  border-radius: 4px;\n}\n.input-group-addon.input-sm {\n  padding: 5px 10px;\n  font-size: 12px;\n  border-radius: 3px;\n}\n.input-group-addon.input-lg {\n  padding: 10px 16px;\n  font-size: 18px;\n  border-radius: 6px;\n}\n.input-group-addon input[type=\"radio\"],\n.input-group-addon input[type=\"checkbox\"] {\n  margin-top: 0;\n}\n.input-group .form-control:first-child,\n.input-group-addon:first-child,\n.input-group-btn:first-child > .btn,\n.input-group-btn:first-child > .btn-group > .btn,\n.input-group-btn:first-child > .dropdown-toggle,\n.input-group-btn:last-child > .btn:not(:last-child):not(.dropdown-toggle),\n.input-group-btn:last-child > .btn-group:not(:last-child) > .btn {\n  border-top-right-radius: 0;\n  border-bottom-right-radius: 0;\n}\n.input-group-addon:first-child {\n  border-right: 0;\n}\n.input-group .form-control:last-child,\n.input-group-addon:last-child,\n.input-group-btn:last-child > .btn,\n.input-group-btn:last-child > .btn-group > .btn,\n.input-group-btn:last-child > .dropdown-toggle,\n.input-group-btn:first-child > .btn:not(:first-child),\n.input-group-btn:first-child > .btn-group:not(:first-child) > .btn {\n  border-top-left-radius: 0;\n  border-bottom-left-radius: 0;\n}\n.input-group-addon:last-child {\n  border-left: 0;\n}\n.input-group-btn {\n  position: relative;\n  font-size: 0;\n  white-space: nowrap;\n}\n.input-group-btn > .btn {\n  position: relative;\n}\n.input-group-btn > .btn + .btn {\n  margin-left: -1px;\n}\n.input-group-btn > .btn:hover,\n.input-group-btn > .btn:focus,\n.input-group-btn > .btn:active {\n  z-index: 2;\n}\n.input-group-btn:first-child > .btn,\n.input-group-btn:first-child > .btn-group {\n  margin-right: -1px;\n}\n.input-group-btn:last-child > .btn,\n.input-group-btn:last-child > .btn-group {\n  z-index: 2;\n  margin-left: -1px;\n}\n.nav {\n  padding-left: 0;\n  margin-bottom: 0;\n  list-style: none;\n}\n.nav > li {\n  position: relative;\n  display: block;\n}\n.nav > li > a {\n  position: relative;\n  display: block;\n  padding: 10px 15px;\n}\n.nav > li > a:hover,\n.nav > li > a:focus {\n  text-decoration: none;\n  background-color: #eee;\n}\n.nav > li.disabled > a {\n  color: #777;\n}\n.nav > li.disabled > a:hover,\n.nav > li.disabled > a:focus {\n  color: #777;\n  text-decoration: none;\n  cursor: not-allowed;\n  background-color: transparent;\n}\n.nav .open > a,\n.nav .open > a:hover,\n.nav .open > a:focus {\n  background-color: #eee;\n  border-color: #337ab7;\n}\n.nav .nav-divider {\n  height: 1px;\n  margin: 9px 0;\n  overflow: hidden;\n  background-color: #e5e5e5;\n}\n.nav > li > a > img {\n  max-width: none;\n}\n.nav-tabs {\n  border-bottom: 1px solid #ddd;\n}\n.nav-tabs > li {\n  float: left;\n  margin-bottom: -1px;\n}\n.nav-tabs > li > a {\n  margin-right: 2px;\n  line-height: 1.42857143;\n  border: 1px solid transparent;\n  border-radius: 4px 4px 0 0;\n}\n.nav-tabs > li > a:hover {\n  border-color: #eee #eee #ddd;\n}\n.nav-tabs > li.active > a,\n.nav-tabs > li.active > a:hover,\n.nav-tabs > li.active > a:focus {\n  color: #555;\n  cursor: default;\n  background-color: #fff;\n  border: 1px solid #ddd;\n  border-bottom-color: transparent;\n}\n.nav-tabs.nav-justified {\n  width: 100%;\n  border-bottom: 0;\n}\n.nav-tabs.nav-justified > li {\n  float: none;\n}\n.nav-tabs.nav-justified > li > a {\n  margin-bottom: 5px;\n  text-align: center;\n}\n.nav-tabs.nav-justified > .dropdown .dropdown-menu {\n  top: auto;\n  left: auto;\n}\n@media (min-width: 768px) {\n  .nav-tabs.nav-justified > li {\n    display: table-cell;\n    width: 1%;\n  }\n  .nav-tabs.nav-justified > li > a {\n    margin-bottom: 0;\n  }\n}\n.nav-tabs.nav-justified > li > a {\n  margin-right: 0;\n  border-radius: 4px;\n}\n.nav-tabs.nav-justified > .active > a,\n.nav-tabs.nav-justified > .active > a:hover,\n.nav-tabs.nav-justified > .active > a:focus {\n  border: 1px solid #ddd;\n}\n@media (min-width: 768px) {\n  .nav-tabs.nav-justified > li > a {\n    border-bottom: 1px solid #ddd;\n    border-radius: 4px 4px 0 0;\n  }\n  .nav-tabs.nav-justified > .active > a,\n  .nav-tabs.nav-justified > .active > a:hover,\n  .nav-tabs.nav-justified > .active > a:focus {\n    border-bottom-color: #fff;\n  }\n}\n.nav-pills > li {\n  float: left;\n}\n.nav-pills > li > a {\n  border-radius: 4px;\n}\n.nav-pills > li + li {\n  margin-left: 2px;\n}\n.nav-pills > li.active > a,\n.nav-pills > li.active > a:hover,\n.nav-pills > li.active > a:focus {\n  color: #fff;\n  background-color: #337ab7;\n}\n.nav-stacked > li {\n  float: none;\n}\n.nav-stacked > li + li {\n  margin-top: 2px;\n  margin-left: 0;\n}\n.nav-justified {\n  width: 100%;\n}\n.nav-justified > li {\n  float: none;\n}\n.nav-justified > li > a {\n  margin-bottom: 5px;\n  text-align: center;\n}\n.nav-justified > .dropdown .dropdown-menu {\n  top: auto;\n  left: auto;\n}\n@media (min-width: 768px) {\n  .nav-justified > li {\n    display: table-cell;\n    width: 1%;\n  }\n  .nav-justified > li > a {\n    margin-bottom: 0;\n  }\n}\n.nav-tabs-justified {\n  border-bottom: 0;\n}\n.nav-tabs-justified > li > a {\n  margin-right: 0;\n  border-radius: 4px;\n}\n.nav-tabs-justified > .active > a,\n.nav-tabs-justified > .active > a:hover,\n.nav-tabs-justified > .active > a:focus {\n  border: 1px solid #ddd;\n}\n@media (min-width: 768px) {\n  .nav-tabs-justified > li > a {\n    border-bottom: 1px solid #ddd;\n    border-radius: 4px 4px 0 0;\n  }\n  .nav-tabs-justified > .active > a,\n  .nav-tabs-justified > .active > a:hover,\n  .nav-tabs-justified > .active > a:focus {\n    border-bottom-color: #fff;\n  }\n}\n.tab-content > .tab-pane {\n  display: none;\n}\n.tab-content > .active {\n  display: block;\n}\n.nav-tabs .dropdown-menu {\n  margin-top: -1px;\n  border-top-left-radius: 0;\n  border-top-right-radius: 0;\n}\n.navbar {\n  position: relative;\n  min-height: 50px;\n  margin-bottom: 20px;\n  border: 1px solid transparent;\n}\n@media (min-width: 768px) {\n  .navbar {\n    border-radius: 4px;\n  }\n}\n@media (min-width: 768px) {\n  .navbar-header {\n    float: left;\n  }\n}\n.navbar-collapse {\n  padding-right: 15px;\n  padding-left: 15px;\n  overflow-x: visible;\n  -webkit-overflow-scrolling: touch;\n  border-top: 1px solid transparent;\n  -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, .1);\n          box-shadow: inset 0 1px 0 rgba(255, 255, 255, .1);\n}\n.navbar-collapse.in {\n  overflow-y: auto;\n}\n@media (min-width: 768px) {\n  .navbar-collapse {\n    width: auto;\n    border-top: 0;\n    -webkit-box-shadow: none;\n            box-shadow: none;\n  }\n  .navbar-collapse.collapse {\n    display: block !important;\n    height: auto !important;\n    padding-bottom: 0;\n    overflow: visible !important;\n  }\n  .navbar-collapse.in {\n    overflow-y: visible;\n  }\n  .navbar-fixed-top .navbar-collapse,\n  .navbar-static-top .navbar-collapse,\n  .navbar-fixed-bottom .navbar-collapse {\n    padding-right: 0;\n    padding-left: 0;\n  }\n}\n.navbar-fixed-top .navbar-collapse,\n.navbar-fixed-bottom .navbar-collapse {\n  max-height: 340px;\n}\n@media (max-device-width: 480px) and (orientation: landscape) {\n  .navbar-fixed-top .navbar-collapse,\n  .navbar-fixed-bottom .navbar-collapse {\n    max-height: 200px;\n  }\n}\n.container > .navbar-header,\n.container-fluid > .navbar-header,\n.container > .navbar-collapse,\n.container-fluid > .navbar-collapse {\n  margin-right: -15px;\n  margin-left: -15px;\n}\n@media (min-width: 768px) {\n  .container > .navbar-header,\n  .container-fluid > .navbar-header,\n  .container > .navbar-collapse,\n  .container-fluid > .navbar-collapse {\n    margin-right: 0;\n    margin-left: 0;\n  }\n}\n.navbar-static-top {\n  z-index: 1000;\n  border-width: 0 0 1px;\n}\n@media (min-width: 768px) {\n  .navbar-static-top {\n    border-radius: 0;\n  }\n}\n.navbar-fixed-top,\n.navbar-fixed-bottom {\n  position: fixed;\n  right: 0;\n  left: 0;\n  z-index: 1030;\n}\n@media (min-width: 768px) {\n  .navbar-fixed-top,\n  .navbar-fixed-bottom {\n    border-radius: 0;\n  }\n}\n.navbar-fixed-top {\n  top: 0;\n  border-width: 0 0 1px;\n}\n.navbar-fixed-bottom {\n  bottom: 0;\n  margin-bottom: 0;\n  border-width: 1px 0 0;\n}\n.navbar-brand {\n  float: left;\n  height: 50px;\n  padding: 15px 15px;\n  font-size: 18px;\n  line-height: 20px;\n}\n.navbar-brand:hover,\n.navbar-brand:focus {\n  text-decoration: none;\n}\n.navbar-brand > img {\n  display: block;\n}\n@media (min-width: 768px) {\n  .navbar > .container .navbar-brand,\n  .navbar > .container-fluid .navbar-brand {\n    margin-left: -15px;\n  }\n}\n.navbar-toggle {\n  position: relative;\n  float: right;\n  padding: 9px 10px;\n  margin-top: 8px;\n  margin-right: 15px;\n  margin-bottom: 8px;\n  background-color: transparent;\n  background-image: none;\n  border: 1px solid transparent;\n  border-radius: 4px;\n}\n.navbar-toggle:focus {\n  outline: 0;\n}\n.navbar-toggle .icon-bar {\n  display: block;\n  width: 22px;\n  height: 2px;\n  border-radius: 1px;\n}\n.navbar-toggle .icon-bar + .icon-bar {\n  margin-top: 4px;\n}\n@media (min-width: 768px) {\n  .navbar-toggle {\n    display: none;\n  }\n}\n.navbar-nav {\n  margin: 7.5px -15px;\n}\n.navbar-nav > li > a {\n  padding-top: 10px;\n  padding-bottom: 10px;\n  line-height: 20px;\n}\n@media (max-width: 767px) {\n  .navbar-nav .open .dropdown-menu {\n    position: static;\n    float: none;\n    width: auto;\n    margin-top: 0;\n    background-color: transparent;\n    border: 0;\n    -webkit-box-shadow: none;\n            box-shadow: none;\n  }\n  .navbar-nav .open .dropdown-menu > li > a,\n  .navbar-nav .open .dropdown-menu .dropdown-header {\n    padding: 5px 15px 5px 25px;\n  }\n  .navbar-nav .open .dropdown-menu > li > a {\n    line-height: 20px;\n  }\n  .navbar-nav .open .dropdown-menu > li > a:hover,\n  .navbar-nav .open .dropdown-menu > li > a:focus {\n    background-image: none;\n  }\n}\n@media (min-width: 768px) {\n  .navbar-nav {\n    float: left;\n    margin: 0;\n  }\n  .navbar-nav > li {\n    float: left;\n  }\n  .navbar-nav > li > a {\n    padding-top: 15px;\n    padding-bottom: 15px;\n  }\n}\n.navbar-form {\n  padding: 10px 15px;\n  margin-top: 8px;\n  margin-right: -15px;\n  margin-bottom: 8px;\n  margin-left: -15px;\n  border-top: 1px solid transparent;\n  border-bottom: 1px solid transparent;\n  -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, .1), 0 1px 0 rgba(255, 255, 255, .1);\n          box-shadow: inset 0 1px 0 rgba(255, 255, 255, .1), 0 1px 0 rgba(255, 255, 255, .1);\n}\n@media (min-width: 768px) {\n  .navbar-form .form-group {\n    display: inline-block;\n    margin-bottom: 0;\n    vertical-align: middle;\n  }\n  .navbar-form .form-control {\n    display: inline-block;\n    width: auto;\n    vertical-align: middle;\n  }\n  .navbar-form .form-control-static {\n    display: inline-block;\n  }\n  .navbar-form .input-group {\n    display: inline-table;\n    vertical-align: middle;\n  }\n  .navbar-form .input-group .input-group-addon,\n  .navbar-form .input-group .input-group-btn,\n  .navbar-form .input-group .form-control {\n    width: auto;\n  }\n  .navbar-form .input-group > .form-control {\n    width: 100%;\n  }\n  .navbar-form .control-label {\n    margin-bottom: 0;\n    vertical-align: middle;\n  }\n  .navbar-form .radio,\n  .navbar-form .checkbox {\n    display: inline-block;\n    margin-top: 0;\n    margin-bottom: 0;\n    vertical-align: middle;\n  }\n  .navbar-form .radio label,\n  .navbar-form .checkbox label {\n    padding-left: 0;\n  }\n  .navbar-form .radio input[type=\"radio\"],\n  .navbar-form .checkbox input[type=\"checkbox\"] {\n    position: relative;\n    margin-left: 0;\n  }\n  .navbar-form .has-feedback .form-control-feedback {\n    top: 0;\n  }\n}\n@media (max-width: 767px) {\n  .navbar-form .form-group {\n    margin-bottom: 5px;\n  }\n  .navbar-form .form-group:last-child {\n    margin-bottom: 0;\n  }\n}\n@media (min-width: 768px) {\n  .navbar-form {\n    width: auto;\n    padding-top: 0;\n    padding-bottom: 0;\n    margin-right: 0;\n    margin-left: 0;\n    border: 0;\n    -webkit-box-shadow: none;\n            box-shadow: none;\n  }\n}\n.navbar-nav > li > .dropdown-menu {\n  margin-top: 0;\n  border-top-left-radius: 0;\n  border-top-right-radius: 0;\n}\n.navbar-fixed-bottom .navbar-nav > li > .dropdown-menu {\n  margin-bottom: 0;\n  border-top-left-radius: 4px;\n  border-top-right-radius: 4px;\n  border-bottom-right-radius: 0;\n  border-bottom-left-radius: 0;\n}\n.navbar-btn {\n  margin-top: 8px;\n  margin-bottom: 8px;\n}\n.navbar-btn.btn-sm {\n  margin-top: 10px;\n  margin-bottom: 10px;\n}\n.navbar-btn.btn-xs {\n  margin-top: 14px;\n  margin-bottom: 14px;\n}\n.navbar-text {\n  margin-top: 15px;\n  margin-bottom: 15px;\n}\n@media (min-width: 768px) {\n  .navbar-text {\n    float: left;\n    margin-right: 15px;\n    margin-left: 15px;\n  }\n}\n@media (min-width: 768px) {\n  .navbar-left {\n    float: left !important;\n  }\n  .navbar-right {\n    float: right !important;\n    margin-right: -15px;\n  }\n  .navbar-right ~ .navbar-right {\n    margin-right: 0;\n  }\n}\n.navbar-default {\n  background-color: #f8f8f8;\n  border-color: #e7e7e7;\n}\n.navbar-default .navbar-brand {\n  color: #777;\n}\n.navbar-default .navbar-brand:hover,\n.navbar-default .navbar-brand:focus {\n  color: #5e5e5e;\n  background-color: transparent;\n}\n.navbar-default .navbar-text {\n  color: #777;\n}\n.navbar-default .navbar-nav > li > a {\n  color: #777;\n}\n.navbar-default .navbar-nav > li > a:hover,\n.navbar-default .navbar-nav > li > a:focus {\n  color: #333;\n  background-color: transparent;\n}\n.navbar-default .navbar-nav > .active > a,\n.navbar-default .navbar-nav > .active > a:hover,\n.navbar-default .navbar-nav > .active > a:focus {\n  color: #555;\n  background-color: #e7e7e7;\n}\n.navbar-default .navbar-nav > .disabled > a,\n.navbar-default .navbar-nav > .disabled > a:hover,\n.navbar-default .navbar-nav > .disabled > a:focus {\n  color: #ccc;\n  background-color: transparent;\n}\n.navbar-default .navbar-toggle {\n  border-color: #ddd;\n}\n.navbar-default .navbar-toggle:hover,\n.navbar-default .navbar-toggle:focus {\n  background-color: #ddd;\n}\n.navbar-default .navbar-toggle .icon-bar {\n  background-color: #888;\n}\n.navbar-default .navbar-collapse,\n.navbar-default .navbar-form {\n  border-color: #e7e7e7;\n}\n.navbar-default .navbar-nav > .open > a,\n.navbar-default .navbar-nav > .open > a:hover,\n.navbar-default .navbar-nav > .open > a:focus {\n  color: #555;\n  background-color: #e7e7e7;\n}\n@media (max-width: 767px) {\n  .navbar-default .navbar-nav .open .dropdown-menu > li > a {\n    color: #777;\n  }\n  .navbar-default .navbar-nav .open .dropdown-menu > li > a:hover,\n  .navbar-default .navbar-nav .open .dropdown-menu > li > a:focus {\n    color: #333;\n    background-color: transparent;\n  }\n  .navbar-default .navbar-nav .open .dropdown-menu > .active > a,\n  .navbar-default .navbar-nav .open .dropdown-menu > .active > a:hover,\n  .navbar-default .navbar-nav .open .dropdown-menu > .active > a:focus {\n    color: #555;\n    background-color: #e7e7e7;\n  }\n  .navbar-default .navbar-nav .open .dropdown-menu > .disabled > a,\n  .navbar-default .navbar-nav .open .dropdown-menu > .disabled > a:hover,\n  .navbar-default .navbar-nav .open .dropdown-menu > .disabled > a:focus {\n    color: #ccc;\n    background-color: transparent;\n  }\n}\n.navbar-default .navbar-link {\n  color: #777;\n}\n.navbar-default .navbar-link:hover {\n  color: #333;\n}\n.navbar-default .btn-link {\n  color: #777;\n}\n.navbar-default .btn-link:hover,\n.navbar-default .btn-link:focus {\n  color: #333;\n}\n.navbar-default .btn-link[disabled]:hover,\nfieldset[disabled] .navbar-default .btn-link:hover,\n.navbar-default .btn-link[disabled]:focus,\nfieldset[disabled] .navbar-default .btn-link:focus {\n  color: #ccc;\n}\n.navbar-inverse {\n  background-color: #222;\n  border-color: #080808;\n}\n.navbar-inverse .navbar-brand {\n  color: #9d9d9d;\n}\n.navbar-inverse .navbar-brand:hover,\n.navbar-inverse .navbar-brand:focus {\n  color: #fff;\n  background-color: transparent;\n}\n.navbar-inverse .navbar-text {\n  color: #9d9d9d;\n}\n.navbar-inverse .navbar-nav > li > a {\n  color: #9d9d9d;\n}\n.navbar-inverse .navbar-nav > li > a:hover,\n.navbar-inverse .navbar-nav > li > a:focus {\n  color: #fff;\n  background-color: transparent;\n}\n.navbar-inverse .navbar-nav > .active > a,\n.navbar-inverse .navbar-nav > .active > a:hover,\n.navbar-inverse .navbar-nav > .active > a:focus {\n  color: #fff;\n  background-color: #080808;\n}\n.navbar-inverse .navbar-nav > .disabled > a,\n.navbar-inverse .navbar-nav > .disabled > a:hover,\n.navbar-inverse .navbar-nav > .disabled > a:focus {\n  color: #444;\n  background-color: transparent;\n}\n.navbar-inverse .navbar-toggle {\n  border-color: #333;\n}\n.navbar-inverse .navbar-toggle:hover,\n.navbar-inverse .navbar-toggle:focus {\n  background-color: #333;\n}\n.navbar-inverse .navbar-toggle .icon-bar {\n  background-color: #fff;\n}\n.navbar-inverse .navbar-collapse,\n.navbar-inverse .navbar-form {\n  border-color: #101010;\n}\n.navbar-inverse .navbar-nav > .open > a,\n.navbar-inverse .navbar-nav > .open > a:hover,\n.navbar-inverse .navbar-nav > .open > a:focus {\n  color: #fff;\n  background-color: #080808;\n}\n@media (max-width: 767px) {\n  .navbar-inverse .navbar-nav .open .dropdown-menu > .dropdown-header {\n    border-color: #080808;\n  }\n  .navbar-inverse .navbar-nav .open .dropdown-menu .divider {\n    background-color: #080808;\n  }\n  .navbar-inverse .navbar-nav .open .dropdown-menu > li > a {\n    color: #9d9d9d;\n  }\n  .navbar-inverse .navbar-nav .open .dropdown-menu > li > a:hover,\n  .navbar-inverse .navbar-nav .open .dropdown-menu > li > a:focus {\n    color: #fff;\n    background-color: transparent;\n  }\n  .navbar-inverse .navbar-nav .open .dropdown-menu > .active > a,\n  .navbar-inverse .navbar-nav .open .dropdown-menu > .active > a:hover,\n  .navbar-inverse .navbar-nav .open .dropdown-menu > .active > a:focus {\n    color: #fff;\n    background-color: #080808;\n  }\n  .navbar-inverse .navbar-nav .open .dropdown-menu > .disabled > a,\n  .navbar-inverse .navbar-nav .open .dropdown-menu > .disabled > a:hover,\n  .navbar-inverse .navbar-nav .open .dropdown-menu > .disabled > a:focus {\n    color: #444;\n    background-color: transparent;\n  }\n}\n.navbar-inverse .navbar-link {\n  color: #9d9d9d;\n}\n.navbar-inverse .navbar-link:hover {\n  color: #fff;\n}\n.navbar-inverse .btn-link {\n  color: #9d9d9d;\n}\n.navbar-inverse .btn-link:hover,\n.navbar-inverse .btn-link:focus {\n  color: #fff;\n}\n.navbar-inverse .btn-link[disabled]:hover,\nfieldset[disabled] .navbar-inverse .btn-link:hover,\n.navbar-inverse .btn-link[disabled]:focus,\nfieldset[disabled] .navbar-inverse .btn-link:focus {\n  color: #444;\n}\n.breadcrumb {\n  padding: 8px 15px;\n  margin-bottom: 20px;\n  list-style: none;\n  background-color: #f5f5f5;\n  border-radius: 4px;\n}\n.breadcrumb > li {\n  display: inline-block;\n}\n.breadcrumb > li + li:before {\n  padding: 0 5px;\n  color: #ccc;\n  content: \"/\\00a0\";\n}\n.breadcrumb > .active {\n  color: #777;\n}\n.pagination {\n  display: inline-block;\n  padding-left: 0;\n  margin: 20px 0;\n  border-radius: 4px;\n}\n.pagination > li {\n  display: inline;\n}\n.pagination > li > a,\n.pagination > li > span {\n  position: relative;\n  float: left;\n  padding: 6px 12px;\n  margin-left: -1px;\n  line-height: 1.42857143;\n  color: #337ab7;\n  text-decoration: none;\n  background-color: #fff;\n  border: 1px solid #ddd;\n}\n.pagination > li:first-child > a,\n.pagination > li:first-child > span {\n  margin-left: 0;\n  border-top-left-radius: 4px;\n  border-bottom-left-radius: 4px;\n}\n.pagination > li:last-child > a,\n.pagination > li:last-child > span {\n  border-top-right-radius: 4px;\n  border-bottom-right-radius: 4px;\n}\n.pagination > li > a:hover,\n.pagination > li > span:hover,\n.pagination > li > a:focus,\n.pagination > li > span:focus {\n  z-index: 3;\n  color: #23527c;\n  background-color: #eee;\n  border-color: #ddd;\n}\n.pagination > .active > a,\n.pagination > .active > span,\n.pagination > .active > a:hover,\n.pagination > .active > span:hover,\n.pagination > .active > a:focus,\n.pagination > .active > span:focus {\n  z-index: 2;\n  color: #fff;\n  cursor: default;\n  background-color: #337ab7;\n  border-color: #337ab7;\n}\n.pagination > .disabled > span,\n.pagination > .disabled > span:hover,\n.pagination > .disabled > span:focus,\n.pagination > .disabled > a,\n.pagination > .disabled > a:hover,\n.pagination > .disabled > a:focus {\n  color: #777;\n  cursor: not-allowed;\n  background-color: #fff;\n  border-color: #ddd;\n}\n.pagination-lg > li > a,\n.pagination-lg > li > span {\n  padding: 10px 16px;\n  font-size: 18px;\n  line-height: 1.3333333;\n}\n.pagination-lg > li:first-child > a,\n.pagination-lg > li:first-child > span {\n  border-top-left-radius: 6px;\n  border-bottom-left-radius: 6px;\n}\n.pagination-lg > li:last-child > a,\n.pagination-lg > li:last-child > span {\n  border-top-right-radius: 6px;\n  border-bottom-right-radius: 6px;\n}\n.pagination-sm > li > a,\n.pagination-sm > li > span {\n  padding: 5px 10px;\n  font-size: 12px;\n  line-height: 1.5;\n}\n.pagination-sm > li:first-child > a,\n.pagination-sm > li:first-child > span {\n  border-top-left-radius: 3px;\n  border-bottom-left-radius: 3px;\n}\n.pagination-sm > li:last-child > a,\n.pagination-sm > li:last-child > span {\n  border-top-right-radius: 3px;\n  border-bottom-right-radius: 3px;\n}\n.pager {\n  padding-left: 0;\n  margin: 20px 0;\n  text-align: center;\n  list-style: none;\n}\n.pager li {\n  display: inline;\n}\n.pager li > a,\n.pager li > span {\n  display: inline-block;\n  padding: 5px 14px;\n  background-color: #fff;\n  border: 1px solid #ddd;\n  border-radius: 15px;\n}\n.pager li > a:hover,\n.pager li > a:focus {\n  text-decoration: none;\n  background-color: #eee;\n}\n.pager .next > a,\n.pager .next > span {\n  float: right;\n}\n.pager .previous > a,\n.pager .previous > span {\n  float: left;\n}\n.pager .disabled > a,\n.pager .disabled > a:hover,\n.pager .disabled > a:focus,\n.pager .disabled > span {\n  color: #777;\n  cursor: not-allowed;\n  background-color: #fff;\n}\n.label {\n  display: inline;\n  padding: .2em .6em .3em;\n  font-size: 75%;\n  font-weight: bold;\n  line-height: 1;\n  color: #fff;\n  text-align: center;\n  white-space: nowrap;\n  vertical-align: baseline;\n  border-radius: .25em;\n}\na.label:hover,\na.label:focus {\n  color: #fff;\n  text-decoration: none;\n  cursor: pointer;\n}\n.label:empty {\n  display: none;\n}\n.btn .label {\n  position: relative;\n  top: -1px;\n}\n.label-default {\n  background-color: #777;\n}\n.label-default[href]:hover,\n.label-default[href]:focus {\n  background-color: #5e5e5e;\n}\n.label-primary {\n  background-color: #337ab7;\n}\n.label-primary[href]:hover,\n.label-primary[href]:focus {\n  background-color: #286090;\n}\n.label-success {\n  background-color: #5cb85c;\n}\n.label-success[href]:hover,\n.label-success[href]:focus {\n  background-color: #449d44;\n}\n.label-info {\n  background-color: #5bc0de;\n}\n.label-info[href]:hover,\n.label-info[href]:focus {\n  background-color: #31b0d5;\n}\n.label-warning {\n  background-color: #f0ad4e;\n}\n.label-warning[href]:hover,\n.label-warning[href]:focus {\n  background-color: #ec971f;\n}\n.label-danger {\n  background-color: #d9534f;\n}\n.label-danger[href]:hover,\n.label-danger[href]:focus {\n  background-color: #c9302c;\n}\n.badge {\n  display: inline-block;\n  min-width: 10px;\n  padding: 3px 7px;\n  font-size: 12px;\n  font-weight: bold;\n  line-height: 1;\n  color: #fff;\n  text-align: center;\n  white-space: nowrap;\n  vertical-align: middle;\n  background-color: #777;\n  border-radius: 10px;\n}\n.badge:empty {\n  display: none;\n}\n.btn .badge {\n  position: relative;\n  top: -1px;\n}\n.btn-xs .badge,\n.btn-group-xs > .btn .badge {\n  top: 0;\n  padding: 1px 5px;\n}\na.badge:hover,\na.badge:focus {\n  color: #fff;\n  text-decoration: none;\n  cursor: pointer;\n}\n.list-group-item.active > .badge,\n.nav-pills > .active > a > .badge {\n  color: #337ab7;\n  background-color: #fff;\n}\n.list-group-item > .badge {\n  float: right;\n}\n.list-group-item > .badge + .badge {\n  margin-right: 5px;\n}\n.nav-pills > li > a > .badge {\n  margin-left: 3px;\n}\n.jumbotron {\n  padding-top: 30px;\n  padding-bottom: 30px;\n  margin-bottom: 30px;\n  color: inherit;\n  background-color: #eee;\n}\n.jumbotron h1,\n.jumbotron .h1 {\n  color: inherit;\n}\n.jumbotron p {\n  margin-bottom: 15px;\n  font-size: 21px;\n  font-weight: 200;\n}\n.jumbotron > hr {\n  border-top-color: #d5d5d5;\n}\n.container .jumbotron,\n.container-fluid .jumbotron {\n  border-radius: 6px;\n}\n.jumbotron .container {\n  max-width: 100%;\n}\n@media screen and (min-width: 768px) {\n  .jumbotron {\n    padding-top: 48px;\n    padding-bottom: 48px;\n  }\n  .container .jumbotron,\n  .container-fluid .jumbotron {\n    padding-right: 60px;\n    padding-left: 60px;\n  }\n  .jumbotron h1,\n  .jumbotron .h1 {\n    font-size: 63px;\n  }\n}\n.thumbnail {\n  display: block;\n  padding: 4px;\n  margin-bottom: 20px;\n  line-height: 1.42857143;\n  background-color: #fff;\n  border: 1px solid #ddd;\n  border-radius: 4px;\n  -webkit-transition: border .2s ease-in-out;\n       -o-transition: border .2s ease-in-out;\n          transition: border .2s ease-in-out;\n}\n.thumbnail > img,\n.thumbnail a > img {\n  margin-right: auto;\n  margin-left: auto;\n}\na.thumbnail:hover,\na.thumbnail:focus,\na.thumbnail.active {\n  border-color: #337ab7;\n}\n.thumbnail .caption {\n  padding: 9px;\n  color: #333;\n}\n.alert {\n  padding: 15px;\n  margin-bottom: 20px;\n  border: 1px solid transparent;\n  border-radius: 4px;\n}\n.alert h4 {\n  margin-top: 0;\n  color: inherit;\n}\n.alert .alert-link {\n  font-weight: bold;\n}\n.alert > p,\n.alert > ul {\n  margin-bottom: 0;\n}\n.alert > p + p {\n  margin-top: 5px;\n}\n.alert-dismissable,\n.alert-dismissible {\n  padding-right: 35px;\n}\n.alert-dismissable .close,\n.alert-dismissible .close {\n  position: relative;\n  top: -2px;\n  right: -21px;\n  color: inherit;\n}\n.alert-success {\n  color: #3c763d;\n  background-color: #dff0d8;\n  border-color: #d6e9c6;\n}\n.alert-success hr {\n  border-top-color: #c9e2b3;\n}\n.alert-success .alert-link {\n  color: #2b542c;\n}\n.alert-info {\n  color: #31708f;\n  background-color: #d9edf7;\n  border-color: #bce8f1;\n}\n.alert-info hr {\n  border-top-color: #a6e1ec;\n}\n.alert-info .alert-link {\n  color: #245269;\n}\n.alert-warning {\n  color: #8a6d3b;\n  background-color: #fcf8e3;\n  border-color: #faebcc;\n}\n.alert-warning hr {\n  border-top-color: #f7e1b5;\n}\n.alert-warning .alert-link {\n  color: #66512c;\n}\n.alert-danger {\n  color: #a94442;\n  background-color: #f2dede;\n  border-color: #ebccd1;\n}\n.alert-danger hr {\n  border-top-color: #e4b9c0;\n}\n.alert-danger .alert-link {\n  color: #843534;\n}\n@-webkit-keyframes progress-bar-stripes {\n  from {\n    background-position: 40px 0;\n  }\n  to {\n    background-position: 0 0;\n  }\n}\n@-o-keyframes progress-bar-stripes {\n  from {\n    background-position: 40px 0;\n  }\n  to {\n    background-position: 0 0;\n  }\n}\n@keyframes progress-bar-stripes {\n  from {\n    background-position: 40px 0;\n  }\n  to {\n    background-position: 0 0;\n  }\n}\n.progress {\n  height: 20px;\n  margin-bottom: 20px;\n  overflow: hidden;\n  background-color: #f5f5f5;\n  border-radius: 4px;\n  -webkit-box-shadow: inset 0 1px 2px rgba(0, 0, 0, .1);\n          box-shadow: inset 0 1px 2px rgba(0, 0, 0, .1);\n}\n.progress-bar {\n  float: left;\n  width: 0;\n  height: 100%;\n  font-size: 12px;\n  line-height: 20px;\n  color: #fff;\n  text-align: center;\n  background-color: #337ab7;\n  -webkit-box-shadow: inset 0 -1px 0 rgba(0, 0, 0, .15);\n          box-shadow: inset 0 -1px 0 rgba(0, 0, 0, .15);\n  -webkit-transition: width .6s ease;\n       -o-transition: width .6s ease;\n          transition: width .6s ease;\n}\n.progress-striped .progress-bar,\n.progress-bar-striped {\n  background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);\n  background-image:      -o-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);\n  background-image:         linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);\n  -webkit-background-size: 40px 40px;\n          background-size: 40px 40px;\n}\n.progress.active .progress-bar,\n.progress-bar.active {\n  -webkit-animation: progress-bar-stripes 2s linear infinite;\n       -o-animation: progress-bar-stripes 2s linear infinite;\n          animation: progress-bar-stripes 2s linear infinite;\n}\n.progress-bar-success {\n  background-color: #5cb85c;\n}\n.progress-striped .progress-bar-success {\n  background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);\n  background-image:      -o-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);\n  background-image:         linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);\n}\n.progress-bar-info {\n  background-color: #5bc0de;\n}\n.progress-striped .progress-bar-info {\n  background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);\n  background-image:      -o-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);\n  background-image:         linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);\n}\n.progress-bar-warning {\n  background-color: #f0ad4e;\n}\n.progress-striped .progress-bar-warning {\n  background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);\n  background-image:      -o-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);\n  background-image:         linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);\n}\n.progress-bar-danger {\n  background-color: #d9534f;\n}\n.progress-striped .progress-bar-danger {\n  background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);\n  background-image:      -o-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);\n  background-image:         linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);\n}\n.media {\n  margin-top: 15px;\n}\n.media:first-child {\n  margin-top: 0;\n}\n.media,\n.media-body {\n  overflow: hidden;\n  zoom: 1;\n}\n.media-body {\n  width: 10000px;\n}\n.media-object {\n  display: block;\n}\n.media-object.img-thumbnail {\n  max-width: none;\n}\n.media-right,\n.media > .pull-right {\n  padding-left: 10px;\n}\n.media-left,\n.media > .pull-left {\n  padding-right: 10px;\n}\n.media-left,\n.media-right,\n.media-body {\n  display: table-cell;\n  vertical-align: top;\n}\n.media-middle {\n  vertical-align: middle;\n}\n.media-bottom {\n  vertical-align: bottom;\n}\n.media-heading {\n  margin-top: 0;\n  margin-bottom: 5px;\n}\n.media-list {\n  padding-left: 0;\n  list-style: none;\n}\n.list-group {\n  padding-left: 0;\n  margin-bottom: 20px;\n}\n.list-group-item {\n  position: relative;\n  display: block;\n  padding: 10px 15px;\n  margin-bottom: -1px;\n  background-color: #fff;\n  border: 1px solid #ddd;\n}\n.list-group-item:first-child {\n  border-top-left-radius: 4px;\n  border-top-right-radius: 4px;\n}\n.list-group-item:last-child {\n  margin-bottom: 0;\n  border-bottom-right-radius: 4px;\n  border-bottom-left-radius: 4px;\n}\na.list-group-item,\nbutton.list-group-item {\n  color: #555;\n}\na.list-group-item .list-group-item-heading,\nbutton.list-group-item .list-group-item-heading {\n  color: #333;\n}\na.list-group-item:hover,\nbutton.list-group-item:hover,\na.list-group-item:focus,\nbutton.list-group-item:focus {\n  color: #555;\n  text-decoration: none;\n  background-color: #f5f5f5;\n}\nbutton.list-group-item {\n  width: 100%;\n  text-align: left;\n}\n.list-group-item.disabled,\n.list-group-item.disabled:hover,\n.list-group-item.disabled:focus {\n  color: #777;\n  cursor: not-allowed;\n  background-color: #eee;\n}\n.list-group-item.disabled .list-group-item-heading,\n.list-group-item.disabled:hover .list-group-item-heading,\n.list-group-item.disabled:focus .list-group-item-heading {\n  color: inherit;\n}\n.list-group-item.disabled .list-group-item-text,\n.list-group-item.disabled:hover .list-group-item-text,\n.list-group-item.disabled:focus .list-group-item-text {\n  color: #777;\n}\n.list-group-item.active,\n.list-group-item.active:hover,\n.list-group-item.active:focus {\n  z-index: 2;\n  color: #fff;\n  background-color: #337ab7;\n  border-color: #337ab7;\n}\n.list-group-item.active .list-group-item-heading,\n.list-group-item.active:hover .list-group-item-heading,\n.list-group-item.active:focus .list-group-item-heading,\n.list-group-item.active .list-group-item-heading > small,\n.list-group-item.active:hover .list-group-item-heading > small,\n.list-group-item.active:focus .list-group-item-heading > small,\n.list-group-item.active .list-group-item-heading > .small,\n.list-group-item.active:hover .list-group-item-heading > .small,\n.list-group-item.active:focus .list-group-item-heading > .small {\n  color: inherit;\n}\n.list-group-item.active .list-group-item-text,\n.list-group-item.active:hover .list-group-item-text,\n.list-group-item.active:focus .list-group-item-text {\n  color: #c7ddef;\n}\n.list-group-item-success {\n  color: #3c763d;\n  background-color: #dff0d8;\n}\na.list-group-item-success,\nbutton.list-group-item-success {\n  color: #3c763d;\n}\na.list-group-item-success .list-group-item-heading,\nbutton.list-group-item-success .list-group-item-heading {\n  color: inherit;\n}\na.list-group-item-success:hover,\nbutton.list-group-item-success:hover,\na.list-group-item-success:focus,\nbutton.list-group-item-success:focus {\n  color: #3c763d;\n  background-color: #d0e9c6;\n}\na.list-group-item-success.active,\nbutton.list-group-item-success.active,\na.list-group-item-success.active:hover,\nbutton.list-group-item-success.active:hover,\na.list-group-item-success.active:focus,\nbutton.list-group-item-success.active:focus {\n  color: #fff;\n  background-color: #3c763d;\n  border-color: #3c763d;\n}\n.list-group-item-info {\n  color: #31708f;\n  background-color: #d9edf7;\n}\na.list-group-item-info,\nbutton.list-group-item-info {\n  color: #31708f;\n}\na.list-group-item-info .list-group-item-heading,\nbutton.list-group-item-info .list-group-item-heading {\n  color: inherit;\n}\na.list-group-item-info:hover,\nbutton.list-group-item-info:hover,\na.list-group-item-info:focus,\nbutton.list-group-item-info:focus {\n  color: #31708f;\n  background-color: #c4e3f3;\n}\na.list-group-item-info.active,\nbutton.list-group-item-info.active,\na.list-group-item-info.active:hover,\nbutton.list-group-item-info.active:hover,\na.list-group-item-info.active:focus,\nbutton.list-group-item-info.active:focus {\n  color: #fff;\n  background-color: #31708f;\n  border-color: #31708f;\n}\n.list-group-item-warning {\n  color: #8a6d3b;\n  background-color: #fcf8e3;\n}\na.list-group-item-warning,\nbutton.list-group-item-warning {\n  color: #8a6d3b;\n}\na.list-group-item-warning .list-group-item-heading,\nbutton.list-group-item-warning .list-group-item-heading {\n  color: inherit;\n}\na.list-group-item-warning:hover,\nbutton.list-group-item-warning:hover,\na.list-group-item-warning:focus,\nbutton.list-group-item-warning:focus {\n  color: #8a6d3b;\n  background-color: #faf2cc;\n}\na.list-group-item-warning.active,\nbutton.list-group-item-warning.active,\na.list-group-item-warning.active:hover,\nbutton.list-group-item-warning.active:hover,\na.list-group-item-warning.active:focus,\nbutton.list-group-item-warning.active:focus {\n  color: #fff;\n  background-color: #8a6d3b;\n  border-color: #8a6d3b;\n}\n.list-group-item-danger {\n  color: #a94442;\n  background-color: #f2dede;\n}\na.list-group-item-danger,\nbutton.list-group-item-danger {\n  color: #a94442;\n}\na.list-group-item-danger .list-group-item-heading,\nbutton.list-group-item-danger .list-group-item-heading {\n  color: inherit;\n}\na.list-group-item-danger:hover,\nbutton.list-group-item-danger:hover,\na.list-group-item-danger:focus,\nbutton.list-group-item-danger:focus {\n  color: #a94442;\n  background-color: #ebcccc;\n}\na.list-group-item-danger.active,\nbutton.list-group-item-danger.active,\na.list-group-item-danger.active:hover,\nbutton.list-group-item-danger.active:hover,\na.list-group-item-danger.active:focus,\nbutton.list-group-item-danger.active:focus {\n  color: #fff;\n  background-color: #a94442;\n  border-color: #a94442;\n}\n.list-group-item-heading {\n  margin-top: 0;\n  margin-bottom: 5px;\n}\n.list-group-item-text {\n  margin-bottom: 0;\n  line-height: 1.3;\n}\n.panel {\n  margin-bottom: 20px;\n  background-color: #fff;\n  border: 1px solid transparent;\n  border-radius: 4px;\n  -webkit-box-shadow: 0 1px 1px rgba(0, 0, 0, .05);\n          box-shadow: 0 1px 1px rgba(0, 0, 0, .05);\n}\n.panel-body {\n  padding: 15px;\n}\n.panel-heading {\n  padding: 10px 15px;\n  border-bottom: 1px solid transparent;\n  border-top-left-radius: 3px;\n  border-top-right-radius: 3px;\n}\n.panel-heading > .dropdown .dropdown-toggle {\n  color: inherit;\n}\n.panel-title {\n  margin-top: 0;\n  margin-bottom: 0;\n  font-size: 16px;\n  color: inherit;\n}\n.panel-title > a,\n.panel-title > small,\n.panel-title > .small,\n.panel-title > small > a,\n.panel-title > .small > a {\n  color: inherit;\n}\n.panel-footer {\n  padding: 10px 15px;\n  background-color: #f5f5f5;\n  border-top: 1px solid #ddd;\n  border-bottom-right-radius: 3px;\n  border-bottom-left-radius: 3px;\n}\n.panel > .list-group,\n.panel > .panel-collapse > .list-group {\n  margin-bottom: 0;\n}\n.panel > .list-group .list-group-item,\n.panel > .panel-collapse > .list-group .list-group-item {\n  border-width: 1px 0;\n  border-radius: 0;\n}\n.panel > .list-group:first-child .list-group-item:first-child,\n.panel > .panel-collapse > .list-group:first-child .list-group-item:first-child {\n  border-top: 0;\n  border-top-left-radius: 3px;\n  border-top-right-radius: 3px;\n}\n.panel > .list-group:last-child .list-group-item:last-child,\n.panel > .panel-collapse > .list-group:last-child .list-group-item:last-child {\n  border-bottom: 0;\n  border-bottom-right-radius: 3px;\n  border-bottom-left-radius: 3px;\n}\n.panel > .panel-heading + .panel-collapse > .list-group .list-group-item:first-child {\n  border-top-left-radius: 0;\n  border-top-right-radius: 0;\n}\n.panel-heading + .list-group .list-group-item:first-child {\n  border-top-width: 0;\n}\n.list-group + .panel-footer {\n  border-top-width: 0;\n}\n.panel > .table,\n.panel > .table-responsive > .table,\n.panel > .panel-collapse > .table {\n  margin-bottom: 0;\n}\n.panel > .table caption,\n.panel > .table-responsive > .table caption,\n.panel > .panel-collapse > .table caption {\n  padding-right: 15px;\n  padding-left: 15px;\n}\n.panel > .table:first-child,\n.panel > .table-responsive:first-child > .table:first-child {\n  border-top-left-radius: 3px;\n  border-top-right-radius: 3px;\n}\n.panel > .table:first-child > thead:first-child > tr:first-child,\n.panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child,\n.panel > .table:first-child > tbody:first-child > tr:first-child,\n.panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child {\n  border-top-left-radius: 3px;\n  border-top-right-radius: 3px;\n}\n.panel > .table:first-child > thead:first-child > tr:first-child td:first-child,\n.panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child td:first-child,\n.panel > .table:first-child > tbody:first-child > tr:first-child td:first-child,\n.panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child td:first-child,\n.panel > .table:first-child > thead:first-child > tr:first-child th:first-child,\n.panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child th:first-child,\n.panel > .table:first-child > tbody:first-child > tr:first-child th:first-child,\n.panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child th:first-child {\n  border-top-left-radius: 3px;\n}\n.panel > .table:first-child > thead:first-child > tr:first-child td:last-child,\n.panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child td:last-child,\n.panel > .table:first-child > tbody:first-child > tr:first-child td:last-child,\n.panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child td:last-child,\n.panel > .table:first-child > thead:first-child > tr:first-child th:last-child,\n.panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child th:last-child,\n.panel > .table:first-child > tbody:first-child > tr:first-child th:last-child,\n.panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child th:last-child {\n  border-top-right-radius: 3px;\n}\n.panel > .table:last-child,\n.panel > .table-responsive:last-child > .table:last-child {\n  border-bottom-right-radius: 3px;\n  border-bottom-left-radius: 3px;\n}\n.panel > .table:last-child > tbody:last-child > tr:last-child,\n.panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child,\n.panel > .table:last-child > tfoot:last-child > tr:last-child,\n.panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child {\n  border-bottom-right-radius: 3px;\n  border-bottom-left-radius: 3px;\n}\n.panel > .table:last-child > tbody:last-child > tr:last-child td:first-child,\n.panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child td:first-child,\n.panel > .table:last-child > tfoot:last-child > tr:last-child td:first-child,\n.panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child td:first-child,\n.panel > .table:last-child > tbody:last-child > tr:last-child th:first-child,\n.panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child th:first-child,\n.panel > .table:last-child > tfoot:last-child > tr:last-child th:first-child,\n.panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child th:first-child {\n  border-bottom-left-radius: 3px;\n}\n.panel > .table:last-child > tbody:last-child > tr:last-child td:last-child,\n.panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child td:last-child,\n.panel > .table:last-child > tfoot:last-child > tr:last-child td:last-child,\n.panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child td:last-child,\n.panel > .table:last-child > tbody:last-child > tr:last-child th:last-child,\n.panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child th:last-child,\n.panel > .table:last-child > tfoot:last-child > tr:last-child th:last-child,\n.panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child th:last-child {\n  border-bottom-right-radius: 3px;\n}\n.panel > .panel-body + .table,\n.panel > .panel-body + .table-responsive,\n.panel > .table + .panel-body,\n.panel > .table-responsive + .panel-body {\n  border-top: 1px solid #ddd;\n}\n.panel > .table > tbody:first-child > tr:first-child th,\n.panel > .table > tbody:first-child > tr:first-child td {\n  border-top: 0;\n}\n.panel > .table-bordered,\n.panel > .table-responsive > .table-bordered {\n  border: 0;\n}\n.panel > .table-bordered > thead > tr > th:first-child,\n.panel > .table-responsive > .table-bordered > thead > tr > th:first-child,\n.panel > .table-bordered > tbody > tr > th:first-child,\n.panel > .table-responsive > .table-bordered > tbody > tr > th:first-child,\n.panel > .table-bordered > tfoot > tr > th:first-child,\n.panel > .table-responsive > .table-bordered > tfoot > tr > th:first-child,\n.panel > .table-bordered > thead > tr > td:first-child,\n.panel > .table-responsive > .table-bordered > thead > tr > td:first-child,\n.panel > .table-bordered > tbody > tr > td:first-child,\n.panel > .table-responsive > .table-bordered > tbody > tr > td:first-child,\n.panel > .table-bordered > tfoot > tr > td:first-child,\n.panel > .table-responsive > .table-bordered > tfoot > tr > td:first-child {\n  border-left: 0;\n}\n.panel > .table-bordered > thead > tr > th:last-child,\n.panel > .table-responsive > .table-bordered > thead > tr > th:last-child,\n.panel > .table-bordered > tbody > tr > th:last-child,\n.panel > .table-responsive > .table-bordered > tbody > tr > th:last-child,\n.panel > .table-bordered > tfoot > tr > th:last-child,\n.panel > .table-responsive > .table-bordered > tfoot > tr > th:last-child,\n.panel > .table-bordered > thead > tr > td:last-child,\n.panel > .table-responsive > .table-bordered > thead > tr > td:last-child,\n.panel > .table-bordered > tbody > tr > td:last-child,\n.panel > .table-responsive > .table-bordered > tbody > tr > td:last-child,\n.panel > .table-bordered > tfoot > tr > td:last-child,\n.panel > .table-responsive > .table-bordered > tfoot > tr > td:last-child {\n  border-right: 0;\n}\n.panel > .table-bordered > thead > tr:first-child > td,\n.panel > .table-responsive > .table-bordered > thead > tr:first-child > td,\n.panel > .table-bordered > tbody > tr:first-child > td,\n.panel > .table-responsive > .table-bordered > tbody > tr:first-child > td,\n.panel > .table-bordered > thead > tr:first-child > th,\n.panel > .table-responsive > .table-bordered > thead > tr:first-child > th,\n.panel > .table-bordered > tbody > tr:first-child > th,\n.panel > .table-responsive > .table-bordered > tbody > tr:first-child > th {\n  border-bottom: 0;\n}\n.panel > .table-bordered > tbody > tr:last-child > td,\n.panel > .table-responsive > .table-bordered > tbody > tr:last-child > td,\n.panel > .table-bordered > tfoot > tr:last-child > td,\n.panel > .table-responsive > .table-bordered > tfoot > tr:last-child > td,\n.panel > .table-bordered > tbody > tr:last-child > th,\n.panel > .table-responsive > .table-bordered > tbody > tr:last-child > th,\n.panel > .table-bordered > tfoot > tr:last-child > th,\n.panel > .table-responsive > .table-bordered > tfoot > tr:last-child > th {\n  border-bottom: 0;\n}\n.panel > .table-responsive {\n  margin-bottom: 0;\n  border: 0;\n}\n.panel-group {\n  margin-bottom: 20px;\n}\n.panel-group .panel {\n  margin-bottom: 0;\n  border-radius: 4px;\n}\n.panel-group .panel + .panel {\n  margin-top: 5px;\n}\n.panel-group .panel-heading {\n  border-bottom: 0;\n}\n.panel-group .panel-heading + .panel-collapse > .panel-body,\n.panel-group .panel-heading + .panel-collapse > .list-group {\n  border-top: 1px solid #ddd;\n}\n.panel-group .panel-footer {\n  border-top: 0;\n}\n.panel-group .panel-footer + .panel-collapse .panel-body {\n  border-bottom: 1px solid #ddd;\n}\n.panel-default {\n  border-color: #ddd;\n}\n.panel-default > .panel-heading {\n  color: #333;\n  background-color: #f5f5f5;\n  border-color: #ddd;\n}\n.panel-default > .panel-heading + .panel-collapse > .panel-body {\n  border-top-color: #ddd;\n}\n.panel-default > .panel-heading .badge {\n  color: #f5f5f5;\n  background-color: #333;\n}\n.panel-default > .panel-footer + .panel-collapse > .panel-body {\n  border-bottom-color: #ddd;\n}\n.panel-primary {\n  border-color: #337ab7;\n}\n.panel-primary > .panel-heading {\n  color: #fff;\n  background-color: #337ab7;\n  border-color: #337ab7;\n}\n.panel-primary > .panel-heading + .panel-collapse > .panel-body {\n  border-top-color: #337ab7;\n}\n.panel-primary > .panel-heading .badge {\n  color: #337ab7;\n  background-color: #fff;\n}\n.panel-primary > .panel-footer + .panel-collapse > .panel-body {\n  border-bottom-color: #337ab7;\n}\n.panel-success {\n  border-color: #d6e9c6;\n}\n.panel-success > .panel-heading {\n  color: #3c763d;\n  background-color: #dff0d8;\n  border-color: #d6e9c6;\n}\n.panel-success > .panel-heading + .panel-collapse > .panel-body {\n  border-top-color: #d6e9c6;\n}\n.panel-success > .panel-heading .badge {\n  color: #dff0d8;\n  background-color: #3c763d;\n}\n.panel-success > .panel-footer + .panel-collapse > .panel-body {\n  border-bottom-color: #d6e9c6;\n}\n.panel-info {\n  border-color: #bce8f1;\n}\n.panel-info > .panel-heading {\n  color: #31708f;\n  background-color: #d9edf7;\n  border-color: #bce8f1;\n}\n.panel-info > .panel-heading + .panel-collapse > .panel-body {\n  border-top-color: #bce8f1;\n}\n.panel-info > .panel-heading .badge {\n  color: #d9edf7;\n  background-color: #31708f;\n}\n.panel-info > .panel-footer + .panel-collapse > .panel-body {\n  border-bottom-color: #bce8f1;\n}\n.panel-warning {\n  border-color: #faebcc;\n}\n.panel-warning > .panel-heading {\n  color: #8a6d3b;\n  background-color: #fcf8e3;\n  border-color: #faebcc;\n}\n.panel-warning > .panel-heading + .panel-collapse > .panel-body {\n  border-top-color: #faebcc;\n}\n.panel-warning > .panel-heading .badge {\n  color: #fcf8e3;\n  background-color: #8a6d3b;\n}\n.panel-warning > .panel-footer + .panel-collapse > .panel-body {\n  border-bottom-color: #faebcc;\n}\n.panel-danger {\n  border-color: #ebccd1;\n}\n.panel-danger > .panel-heading {\n  color: #a94442;\n  background-color: #f2dede;\n  border-color: #ebccd1;\n}\n.panel-danger > .panel-heading + .panel-collapse > .panel-body {\n  border-top-color: #ebccd1;\n}\n.panel-danger > .panel-heading .badge {\n  color: #f2dede;\n  background-color: #a94442;\n}\n.panel-danger > .panel-footer + .panel-collapse > .panel-body {\n  border-bottom-color: #ebccd1;\n}\n.embed-responsive {\n  position: relative;\n  display: block;\n  height: 0;\n  padding: 0;\n  overflow: hidden;\n}\n.embed-responsive .embed-responsive-item,\n.embed-responsive iframe,\n.embed-responsive embed,\n.embed-responsive object,\n.embed-responsive video {\n  position: absolute;\n  top: 0;\n  bottom: 0;\n  left: 0;\n  width: 100%;\n  height: 100%;\n  border: 0;\n}\n.embed-responsive-16by9 {\n  padding-bottom: 56.25%;\n}\n.embed-responsive-4by3 {\n  padding-bottom: 75%;\n}\n.well {\n  min-height: 20px;\n  padding: 19px;\n  margin-bottom: 20px;\n  background-color: #f5f5f5;\n  border: 1px solid #e3e3e3;\n  border-radius: 4px;\n  -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .05);\n          box-shadow: inset 0 1px 1px rgba(0, 0, 0, .05);\n}\n.well blockquote {\n  border-color: #ddd;\n  border-color: rgba(0, 0, 0, .15);\n}\n.well-lg {\n  padding: 24px;\n  border-radius: 6px;\n}\n.well-sm {\n  padding: 9px;\n  border-radius: 3px;\n}\n.close {\n  float: right;\n  font-size: 21px;\n  font-weight: bold;\n  line-height: 1;\n  color: #000;\n  text-shadow: 0 1px 0 #fff;\n  filter: alpha(opacity=20);\n  opacity: .2;\n}\n.close:hover,\n.close:focus {\n  color: #000;\n  text-decoration: none;\n  cursor: pointer;\n  filter: alpha(opacity=50);\n  opacity: .5;\n}\nbutton.close {\n  -webkit-appearance: none;\n  padding: 0;\n  cursor: pointer;\n  background: transparent;\n  border: 0;\n}\n.modal-open {\n  overflow: hidden;\n}\n.modal {\n  position: fixed;\n  top: 0;\n  right: 0;\n  bottom: 0;\n  left: 0;\n  z-index: 1050;\n  display: none;\n  overflow: hidden;\n  -webkit-overflow-scrolling: touch;\n  outline: 0;\n}\n.modal.fade .modal-dialog {\n  -webkit-transition: -webkit-transform .3s ease-out;\n       -o-transition:      -o-transform .3s ease-out;\n          transition:         transform .3s ease-out;\n  -webkit-transform: translate(0, -25%);\n      -ms-transform: translate(0, -25%);\n       -o-transform: translate(0, -25%);\n          transform: translate(0, -25%);\n}\n.modal.in .modal-dialog {\n  -webkit-transform: translate(0, 0);\n      -ms-transform: translate(0, 0);\n       -o-transform: translate(0, 0);\n          transform: translate(0, 0);\n}\n.modal-open .modal {\n  overflow-x: hidden;\n  overflow-y: auto;\n}\n.modal-dialog {\n  position: relative;\n  width: auto;\n  margin: 10px;\n}\n.modal-content {\n  position: relative;\n  background-color: #fff;\n  -webkit-background-clip: padding-box;\n          background-clip: padding-box;\n  border: 1px solid #999;\n  border: 1px solid rgba(0, 0, 0, .2);\n  border-radius: 6px;\n  outline: 0;\n  -webkit-box-shadow: 0 3px 9px rgba(0, 0, 0, .5);\n          box-shadow: 0 3px 9px rgba(0, 0, 0, .5);\n}\n.modal-backdrop {\n  position: fixed;\n  top: 0;\n  right: 0;\n  bottom: 0;\n  left: 0;\n  z-index: 1040;\n  background-color: #000;\n}\n.modal-backdrop.fade {\n  filter: alpha(opacity=0);\n  opacity: 0;\n}\n.modal-backdrop.in {\n  filter: alpha(opacity=50);\n  opacity: .5;\n}\n.modal-header {\n  min-height: 16.42857143px;\n  padding: 15px;\n  border-bottom: 1px solid #e5e5e5;\n}\n.modal-header .close {\n  margin-top: -2px;\n}\n.modal-title {\n  margin: 0;\n  line-height: 1.42857143;\n}\n.modal-body {\n  position: relative;\n  padding: 15px;\n}\n.modal-footer {\n  padding: 15px;\n  text-align: right;\n  border-top: 1px solid #e5e5e5;\n}\n.modal-footer .btn + .btn {\n  margin-bottom: 0;\n  margin-left: 5px;\n}\n.modal-footer .btn-group .btn + .btn {\n  margin-left: -1px;\n}\n.modal-footer .btn-block + .btn-block {\n  margin-left: 0;\n}\n.modal-scrollbar-measure {\n  position: absolute;\n  top: -9999px;\n  width: 50px;\n  height: 50px;\n  overflow: scroll;\n}\n@media (min-width: 768px) {\n  .modal-dialog {\n    width: 600px;\n    margin: 30px auto;\n  }\n  .modal-content {\n    -webkit-box-shadow: 0 5px 15px rgba(0, 0, 0, .5);\n            box-shadow: 0 5px 15px rgba(0, 0, 0, .5);\n  }\n  .modal-sm {\n    width: 300px;\n  }\n}\n@media (min-width: 992px) {\n  .modal-lg {\n    width: 900px;\n  }\n}\n.tooltip {\n  position: absolute;\n  z-index: 1070;\n  display: block;\n  font-family: \"Helvetica Neue\", Helvetica, Arial, sans-serif;\n  font-size: 12px;\n  font-style: normal;\n  font-weight: normal;\n  line-height: 1.42857143;\n  text-align: left;\n  text-align: start;\n  text-decoration: none;\n  text-shadow: none;\n  text-transform: none;\n  letter-spacing: normal;\n  word-break: normal;\n  word-spacing: normal;\n  word-wrap: normal;\n  white-space: normal;\n  filter: alpha(opacity=0);\n  opacity: 0;\n\n  line-break: auto;\n}\n.tooltip.in {\n  filter: alpha(opacity=90);\n  opacity: .9;\n}\n.tooltip.top {\n  padding: 5px 0;\n  margin-top: -3px;\n}\n.tooltip.right {\n  padding: 0 5px;\n  margin-left: 3px;\n}\n.tooltip.bottom {\n  padding: 5px 0;\n  margin-top: 3px;\n}\n.tooltip.left {\n  padding: 0 5px;\n  margin-left: -3px;\n}\n.tooltip-inner {\n  max-width: 200px;\n  padding: 3px 8px;\n  color: #fff;\n  text-align: center;\n  background-color: #000;\n  border-radius: 4px;\n}\n.tooltip-arrow {\n  position: absolute;\n  width: 0;\n  height: 0;\n  border-color: transparent;\n  border-style: solid;\n}\n.tooltip.top .tooltip-arrow {\n  bottom: 0;\n  left: 50%;\n  margin-left: -5px;\n  border-width: 5px 5px 0;\n  border-top-color: #000;\n}\n.tooltip.top-left .tooltip-arrow {\n  right: 5px;\n  bottom: 0;\n  margin-bottom: -5px;\n  border-width: 5px 5px 0;\n  border-top-color: #000;\n}\n.tooltip.top-right .tooltip-arrow {\n  bottom: 0;\n  left: 5px;\n  margin-bottom: -5px;\n  border-width: 5px 5px 0;\n  border-top-color: #000;\n}\n.tooltip.right .tooltip-arrow {\n  top: 50%;\n  left: 0;\n  margin-top: -5px;\n  border-width: 5px 5px 5px 0;\n  border-right-color: #000;\n}\n.tooltip.left .tooltip-arrow {\n  top: 50%;\n  right: 0;\n  margin-top: -5px;\n  border-width: 5px 0 5px 5px;\n  border-left-color: #000;\n}\n.tooltip.bottom .tooltip-arrow {\n  top: 0;\n  left: 50%;\n  margin-left: -5px;\n  border-width: 0 5px 5px;\n  border-bottom-color: #000;\n}\n.tooltip.bottom-left .tooltip-arrow {\n  top: 0;\n  right: 5px;\n  margin-top: -5px;\n  border-width: 0 5px 5px;\n  border-bottom-color: #000;\n}\n.tooltip.bottom-right .tooltip-arrow {\n  top: 0;\n  left: 5px;\n  margin-top: -5px;\n  border-width: 0 5px 5px;\n  border-bottom-color: #000;\n}\n.popover {\n  position: absolute;\n  top: 0;\n  left: 0;\n  z-index: 1060;\n  display: none;\n  max-width: 276px;\n  padding: 1px;\n  font-family: \"Helvetica Neue\", Helvetica, Arial, sans-serif;\n  font-size: 14px;\n  font-style: normal;\n  font-weight: normal;\n  line-height: 1.42857143;\n  text-align: left;\n  text-align: start;\n  text-decoration: none;\n  text-shadow: none;\n  text-transform: none;\n  letter-spacing: normal;\n  word-break: normal;\n  word-spacing: normal;\n  word-wrap: normal;\n  white-space: normal;\n  background-color: #fff;\n  -webkit-background-clip: padding-box;\n          background-clip: padding-box;\n  border: 1px solid #ccc;\n  border: 1px solid rgba(0, 0, 0, .2);\n  border-radius: 6px;\n  -webkit-box-shadow: 0 5px 10px rgba(0, 0, 0, .2);\n          box-shadow: 0 5px 10px rgba(0, 0, 0, .2);\n\n  line-break: auto;\n}\n.popover.top {\n  margin-top: -10px;\n}\n.popover.right {\n  margin-left: 10px;\n}\n.popover.bottom {\n  margin-top: 10px;\n}\n.popover.left {\n  margin-left: -10px;\n}\n.popover-title {\n  padding: 8px 14px;\n  margin: 0;\n  font-size: 14px;\n  background-color: #f7f7f7;\n  border-bottom: 1px solid #ebebeb;\n  border-radius: 5px 5px 0 0;\n}\n.popover-content {\n  padding: 9px 14px;\n}\n.popover > .arrow,\n.popover > .arrow:after {\n  position: absolute;\n  display: block;\n  width: 0;\n  height: 0;\n  border-color: transparent;\n  border-style: solid;\n}\n.popover > .arrow {\n  border-width: 11px;\n}\n.popover > .arrow:after {\n  content: \"\";\n  border-width: 10px;\n}\n.popover.top > .arrow {\n  bottom: -11px;\n  left: 50%;\n  margin-left: -11px;\n  border-top-color: #999;\n  border-top-color: rgba(0, 0, 0, .25);\n  border-bottom-width: 0;\n}\n.popover.top > .arrow:after {\n  bottom: 1px;\n  margin-left: -10px;\n  content: \" \";\n  border-top-color: #fff;\n  border-bottom-width: 0;\n}\n.popover.right > .arrow {\n  top: 50%;\n  left: -11px;\n  margin-top: -11px;\n  border-right-color: #999;\n  border-right-color: rgba(0, 0, 0, .25);\n  border-left-width: 0;\n}\n.popover.right > .arrow:after {\n  bottom: -10px;\n  left: 1px;\n  content: \" \";\n  border-right-color: #fff;\n  border-left-width: 0;\n}\n.popover.bottom > .arrow {\n  top: -11px;\n  left: 50%;\n  margin-left: -11px;\n  border-top-width: 0;\n  border-bottom-color: #999;\n  border-bottom-color: rgba(0, 0, 0, .25);\n}\n.popover.bottom > .arrow:after {\n  top: 1px;\n  margin-left: -10px;\n  content: \" \";\n  border-top-width: 0;\n  border-bottom-color: #fff;\n}\n.popover.left > .arrow {\n  top: 50%;\n  right: -11px;\n  margin-top: -11px;\n  border-right-width: 0;\n  border-left-color: #999;\n  border-left-color: rgba(0, 0, 0, .25);\n}\n.popover.left > .arrow:after {\n  right: 1px;\n  bottom: -10px;\n  content: \" \";\n  border-right-width: 0;\n  border-left-color: #fff;\n}\n.carousel {\n  position: relative;\n}\n.carousel-inner {\n  position: relative;\n  width: 100%;\n  overflow: hidden;\n}\n.carousel-inner > .item {\n  position: relative;\n  display: none;\n  -webkit-transition: .6s ease-in-out left;\n       -o-transition: .6s ease-in-out left;\n          transition: .6s ease-in-out left;\n}\n.carousel-inner > .item > img,\n.carousel-inner > .item > a > img {\n  line-height: 1;\n}\n@media all and (transform-3d), (-webkit-transform-3d) {\n  .carousel-inner > .item {\n    -webkit-transition: -webkit-transform .6s ease-in-out;\n         -o-transition:      -o-transform .6s ease-in-out;\n            transition:         transform .6s ease-in-out;\n\n    -webkit-backface-visibility: hidden;\n            backface-visibility: hidden;\n    -webkit-perspective: 1000px;\n            perspective: 1000px;\n  }\n  .carousel-inner > .item.next,\n  .carousel-inner > .item.active.right {\n    left: 0;\n    -webkit-transform: translate3d(100%, 0, 0);\n            transform: translate3d(100%, 0, 0);\n  }\n  .carousel-inner > .item.prev,\n  .carousel-inner > .item.active.left {\n    left: 0;\n    -webkit-transform: translate3d(-100%, 0, 0);\n            transform: translate3d(-100%, 0, 0);\n  }\n  .carousel-inner > .item.next.left,\n  .carousel-inner > .item.prev.right,\n  .carousel-inner > .item.active {\n    left: 0;\n    -webkit-transform: translate3d(0, 0, 0);\n            transform: translate3d(0, 0, 0);\n  }\n}\n.carousel-inner > .active,\n.carousel-inner > .next,\n.carousel-inner > .prev {\n  display: block;\n}\n.carousel-inner > .active {\n  left: 0;\n}\n.carousel-inner > .next,\n.carousel-inner > .prev {\n  position: absolute;\n  top: 0;\n  width: 100%;\n}\n.carousel-inner > .next {\n  left: 100%;\n}\n.carousel-inner > .prev {\n  left: -100%;\n}\n.carousel-inner > .next.left,\n.carousel-inner > .prev.right {\n  left: 0;\n}\n.carousel-inner > .active.left {\n  left: -100%;\n}\n.carousel-inner > .active.right {\n  left: 100%;\n}\n.carousel-control {\n  position: absolute;\n  top: 0;\n  bottom: 0;\n  left: 0;\n  width: 15%;\n  font-size: 20px;\n  color: #fff;\n  text-align: center;\n  text-shadow: 0 1px 2px rgba(0, 0, 0, .6);\n  filter: alpha(opacity=50);\n  opacity: .5;\n}\n.carousel-control.left {\n  background-image: -webkit-linear-gradient(left, rgba(0, 0, 0, .5) 0%, rgba(0, 0, 0, .0001) 100%);\n  background-image:      -o-linear-gradient(left, rgba(0, 0, 0, .5) 0%, rgba(0, 0, 0, .0001) 100%);\n  background-image: -webkit-gradient(linear, left top, right top, from(rgba(0, 0, 0, .5)), to(rgba(0, 0, 0, .0001)));\n  background-image:         linear-gradient(to right, rgba(0, 0, 0, .5) 0%, rgba(0, 0, 0, .0001) 100%);\n  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#80000000', endColorstr='#00000000', GradientType=1);\n  background-repeat: repeat-x;\n}\n.carousel-control.right {\n  right: 0;\n  left: auto;\n  background-image: -webkit-linear-gradient(left, rgba(0, 0, 0, .0001) 0%, rgba(0, 0, 0, .5) 100%);\n  background-image:      -o-linear-gradient(left, rgba(0, 0, 0, .0001) 0%, rgba(0, 0, 0, .5) 100%);\n  background-image: -webkit-gradient(linear, left top, right top, from(rgba(0, 0, 0, .0001)), to(rgba(0, 0, 0, .5)));\n  background-image:         linear-gradient(to right, rgba(0, 0, 0, .0001) 0%, rgba(0, 0, 0, .5) 100%);\n  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#00000000', endColorstr='#80000000', GradientType=1);\n  background-repeat: repeat-x;\n}\n.carousel-control:hover,\n.carousel-control:focus {\n  color: #fff;\n  text-decoration: none;\n  filter: alpha(opacity=90);\n  outline: 0;\n  opacity: .9;\n}\n.carousel-control .icon-prev,\n.carousel-control .icon-next,\n.carousel-control .glyphicon-chevron-left,\n.carousel-control .glyphicon-chevron-right {\n  position: absolute;\n  top: 50%;\n  z-index: 5;\n  display: inline-block;\n  margin-top: -10px;\n}\n.carousel-control .icon-prev,\n.carousel-control .glyphicon-chevron-left {\n  left: 50%;\n  margin-left: -10px;\n}\n.carousel-control .icon-next,\n.carousel-control .glyphicon-chevron-right {\n  right: 50%;\n  margin-right: -10px;\n}\n.carousel-control .icon-prev,\n.carousel-control .icon-next {\n  width: 20px;\n  height: 20px;\n  font-family: serif;\n  line-height: 1;\n}\n.carousel-control .icon-prev:before {\n  content: '\\2039';\n}\n.carousel-control .icon-next:before {\n  content: '\\203a';\n}\n.carousel-indicators {\n  position: absolute;\n  bottom: 10px;\n  left: 50%;\n  z-index: 15;\n  width: 60%;\n  padding-left: 0;\n  margin-left: -30%;\n  text-align: center;\n  list-style: none;\n}\n.carousel-indicators li {\n  display: inline-block;\n  width: 10px;\n  height: 10px;\n  margin: 1px;\n  text-indent: -999px;\n  cursor: pointer;\n  background-color: #000 \\9;\n  background-color: rgba(0, 0, 0, 0);\n  border: 1px solid #fff;\n  border-radius: 10px;\n}\n.carousel-indicators .active {\n  width: 12px;\n  height: 12px;\n  margin: 0;\n  background-color: #fff;\n}\n.carousel-caption {\n  position: absolute;\n  right: 15%;\n  bottom: 20px;\n  left: 15%;\n  z-index: 10;\n  padding-top: 20px;\n  padding-bottom: 20px;\n  color: #fff;\n  text-align: center;\n  text-shadow: 0 1px 2px rgba(0, 0, 0, .6);\n}\n.carousel-caption .btn {\n  text-shadow: none;\n}\n@media screen and (min-width: 768px) {\n  .carousel-control .glyphicon-chevron-left,\n  .carousel-control .glyphicon-chevron-right,\n  .carousel-control .icon-prev,\n  .carousel-control .icon-next {\n    width: 30px;\n    height: 30px;\n    margin-top: -15px;\n    font-size: 30px;\n  }\n  .carousel-control .glyphicon-chevron-left,\n  .carousel-control .icon-prev {\n    margin-left: -15px;\n  }\n  .carousel-control .glyphicon-chevron-right,\n  .carousel-control .icon-next {\n    margin-right: -15px;\n  }\n  .carousel-caption {\n    right: 20%;\n    left: 20%;\n    padding-bottom: 30px;\n  }\n  .carousel-indicators {\n    bottom: 20px;\n  }\n}\n.clearfix:before,\n.clearfix:after,\n.dl-horizontal dd:before,\n.dl-horizontal dd:after,\n.container:before,\n.container:after,\n.container-fluid:before,\n.container-fluid:after,\n.row:before,\n.row:after,\n.form-horizontal .form-group:before,\n.form-horizontal .form-group:after,\n.btn-toolbar:before,\n.btn-toolbar:after,\n.btn-group-vertical > .btn-group:before,\n.btn-group-vertical > .btn-group:after,\n.nav:before,\n.nav:after,\n.navbar:before,\n.navbar:after,\n.navbar-header:before,\n.navbar-header:after,\n.navbar-collapse:before,\n.navbar-collapse:after,\n.pager:before,\n.pager:after,\n.panel-body:before,\n.panel-body:after,\n.modal-footer:before,\n.modal-footer:after {\n  display: table;\n  content: \" \";\n}\n.clearfix:after,\n.dl-horizontal dd:after,\n.container:after,\n.container-fluid:after,\n.row:after,\n.form-horizontal .form-group:after,\n.btn-toolbar:after,\n.btn-group-vertical > .btn-group:after,\n.nav:after,\n.navbar:after,\n.navbar-header:after,\n.navbar-collapse:after,\n.pager:after,\n.panel-body:after,\n.modal-footer:after {\n  clear: both;\n}\n.center-block {\n  display: block;\n  margin-right: auto;\n  margin-left: auto;\n}\n.pull-right {\n  float: right !important;\n}\n.pull-left {\n  float: left !important;\n}\n.hide {\n  display: none !important;\n}\n.show {\n  display: block !important;\n}\n.invisible {\n  visibility: hidden;\n}\n.text-hide {\n  font: 0/0 a;\n  color: transparent;\n  text-shadow: none;\n  background-color: transparent;\n  border: 0;\n}\n.hidden {\n  display: none !important;\n}\n.affix {\n  position: fixed;\n}\n@-ms-viewport {\n  width: device-width;\n}\n.visible-xs,\n.visible-sm,\n.visible-md,\n.visible-lg {\n  display: none !important;\n}\n.visible-xs-block,\n.visible-xs-inline,\n.visible-xs-inline-block,\n.visible-sm-block,\n.visible-sm-inline,\n.visible-sm-inline-block,\n.visible-md-block,\n.visible-md-inline,\n.visible-md-inline-block,\n.visible-lg-block,\n.visible-lg-inline,\n.visible-lg-inline-block {\n  display: none !important;\n}\n@media (max-width: 767px) {\n  .visible-xs {\n    display: block !important;\n  }\n  table.visible-xs {\n    display: table !important;\n  }\n  tr.visible-xs {\n    display: table-row !important;\n  }\n  th.visible-xs,\n  td.visible-xs {\n    display: table-cell !important;\n  }\n}\n@media (max-width: 767px) {\n  .visible-xs-block {\n    display: block !important;\n  }\n}\n@media (max-width: 767px) {\n  .visible-xs-inline {\n    display: inline !important;\n  }\n}\n@media (max-width: 767px) {\n  .visible-xs-inline-block {\n    display: inline-block !important;\n  }\n}\n@media (min-width: 768px) and (max-width: 991px) {\n  .visible-sm {\n    display: block !important;\n  }\n  table.visible-sm {\n    display: table !important;\n  }\n  tr.visible-sm {\n    display: table-row !important;\n  }\n  th.visible-sm,\n  td.visible-sm {\n    display: table-cell !important;\n  }\n}\n@media (min-width: 768px) and (max-width: 991px) {\n  .visible-sm-block {\n    display: block !important;\n  }\n}\n@media (min-width: 768px) and (max-width: 991px) {\n  .visible-sm-inline {\n    display: inline !important;\n  }\n}\n@media (min-width: 768px) and (max-width: 991px) {\n  .visible-sm-inline-block {\n    display: inline-block !important;\n  }\n}\n@media (min-width: 992px) and (max-width: 1199px) {\n  .visible-md {\n    display: block !important;\n  }\n  table.visible-md {\n    display: table !important;\n  }\n  tr.visible-md {\n    display: table-row !important;\n  }\n  th.visible-md,\n  td.visible-md {\n    display: table-cell !important;\n  }\n}\n@media (min-width: 992px) and (max-width: 1199px) {\n  .visible-md-block {\n    display: block !important;\n  }\n}\n@media (min-width: 992px) and (max-width: 1199px) {\n  .visible-md-inline {\n    display: inline !important;\n  }\n}\n@media (min-width: 992px) and (max-width: 1199px) {\n  .visible-md-inline-block {\n    display: inline-block !important;\n  }\n}\n@media (min-width: 1200px) {\n  .visible-lg {\n    display: block !important;\n  }\n  table.visible-lg {\n    display: table !important;\n  }\n  tr.visible-lg {\n    display: table-row !important;\n  }\n  th.visible-lg,\n  td.visible-lg {\n    display: table-cell !important;\n  }\n}\n@media (min-width: 1200px) {\n  .visible-lg-block {\n    display: block !important;\n  }\n}\n@media (min-width: 1200px) {\n  .visible-lg-inline {\n    display: inline !important;\n  }\n}\n@media (min-width: 1200px) {\n  .visible-lg-inline-block {\n    display: inline-block !important;\n  }\n}\n@media (max-width: 767px) {\n  .hidden-xs {\n    display: none !important;\n  }\n}\n@media (min-width: 768px) and (max-width: 991px) {\n  .hidden-sm {\n    display: none !important;\n  }\n}\n@media (min-width: 992px) and (max-width: 1199px) {\n  .hidden-md {\n    display: none !important;\n  }\n}\n@media (min-width: 1200px) {\n  .hidden-lg {\n    display: none !important;\n  }\n}\n.visible-print {\n  display: none !important;\n}\n@media print {\n  .visible-print {\n    display: block !important;\n  }\n  table.visible-print {\n    display: table !important;\n  }\n  tr.visible-print {\n    display: table-row !important;\n  }\n  th.visible-print,\n  td.visible-print {\n    display: table-cell !important;\n  }\n}\n.visible-print-block {\n  display: none !important;\n}\n@media print {\n  .visible-print-block {\n    display: block !important;\n  }\n}\n.visible-print-inline {\n  display: none !important;\n}\n@media print {\n  .visible-print-inline {\n    display: inline !important;\n  }\n}\n.visible-print-inline-block {\n  display: none !important;\n}\n@media print {\n  .visible-print-inline-block {\n    display: inline-block !important;\n  }\n}\n@media print {\n  .hidden-print {\n    display: none !important;\n  }\n}\n/*# sourceMappingURL=bootstrap.css.map */\n"
  },
  {
    "path": "app_frontend/static/css/custom.css",
    "content": "body {\n    padding-top: 50px;\n    /*padding-bottom: 61px;*/\n    background-color: #f9f9f9\n}\n\nbody, html {\n    height: 100%;\n}\n\n.full_height {\n  margin: 0 0 -61px 0;\n  min-height: 100%;\n}\n\nfooter {\n    margin-top: 54px !important;\n    clear: both;\n}\n\n\n.body_img::after {\n    background: rgba(0, 0, 0, 0.8) none repeat scroll 0 0;\n}\n\n.body_img {\n    background: rgba(0, 0, 0, 0) url(\"../img/cat.jpg\") no-repeat fixed center center / cover ;\n}\n\nul#affix_nav_ul.affix {\n    top: 70px; /* Set the top position of pinned element */\n}\n\n.translucent {\n    background: rgba(0, 0, 0, 0.8) none repeat scroll 0 0;\n}\n\n/* 防止id定位起始位置被顶部固定导航条遮住 */\n/*section {*/\n    /*padding-top: 70px;*/\n    /*margin-top: -70px;*/\n/*}*/\n\n/* 返回顶部 */\na#top-link {\n    text-decoration: none;\n}\n\na#top-link:hover {\n    color: #55acee;\n    text-decoration: none;\n}\n\n#top-link-block.affix-top {\n    position: absolute; /* allows it to \"slide\" up into view */\n    bottom: -82px;\n    right: 10px;\n}\n\n#top-link-block.affix {\n    position: fixed; /* keeps it on the bottom once in view */\n    bottom: 21px;\n    right: 10px;\n}\n\n.btn-time-bar {\n    padding: 0 12px;\n}\n\n.input-copy\n{\n    padding: 6px 10px;\n}\n\n/*活动标签顶部色条*/\n.nav-tabs>li.active>a.selected,.nav-tabs>li.active>a.selected:focus,.nav-tabs>li.active>a.selected:hover {\n    color: #555;\n    cursor: default;\n    background-color: #fff;\n    border: solid;\n    border-width: 3px 1px 0 1px;\n    border-radius: 3px 3px 0 0;\n    border-color: #e36209 #e1e4e8 transparent;\n}\n\n/*闪现消息顶部固定*/\n.alert-fixed-top {\n    position: fixed;\n    top: 50px;\n    z-index: 1040;\n}\n"
  },
  {
    "path": "app_frontend/static/css/lightbox.css",
    "content": "/* Preload images */\nbody:after {\n  content: url(../images/close.png) url(../images/loading.gif) url(../images/prev.png) url(../images/next.png);\n  display: none;\n}\n\nbody.lb-disable-scrolling {\n  overflow: hidden;\n}\n\n.lightboxOverlay {\n  position: absolute;\n  top: 0;\n  left: 0;\n  z-index: 9999;\n  background-color: black;\n  filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=80);\n  opacity: 0.8;\n  display: none;\n}\n\n.lightbox {\n  position: absolute;\n  left: 0;\n  width: 100%;\n  z-index: 10000;\n  text-align: center;\n  line-height: 0;\n  font-weight: normal;\n}\n\n.lightbox .lb-image {\n  display: block;\n  height: auto;\n  max-width: inherit;\n  border-radius: 3px;\n}\n\n.lightbox a img {\n  border: none;\n}\n\n.lb-outerContainer {\n  position: relative;\n  background-color: white;\n  *zoom: 1;\n  width: 250px;\n  height: 250px;\n  margin: 0 auto;\n  border-radius: 4px;\n}\n\n.lb-outerContainer:after {\n  content: \"\";\n  display: table;\n  clear: both;\n}\n\n.lb-container {\n  padding: 4px;\n}\n\n.lb-loader {\n  position: absolute;\n  top: 43%;\n  left: 0;\n  height: 25%;\n  width: 100%;\n  text-align: center;\n  line-height: 0;\n}\n\n.lb-cancel {\n  display: block;\n  width: 32px;\n  height: 32px;\n  margin: 0 auto;\n  background: url(../images/loading.gif) no-repeat;\n}\n\n.lb-nav {\n  position: absolute;\n  top: 0;\n  left: 0;\n  height: 100%;\n  width: 100%;\n  z-index: 10;\n}\n\n.lb-container > .nav {\n  left: 0;\n}\n\n.lb-nav a {\n  outline: none;\n  background-image: url('data:image/gif;base64,R0lGODlhAQABAPAAAP///wAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw==');\n}\n\n.lb-prev, .lb-next {\n  height: 100%;\n  cursor: pointer;\n  display: block;\n}\n\n.lb-nav a.lb-prev {\n  width: 34%;\n  left: 0;\n  float: left;\n  background: url(../images/prev.png) left 48% no-repeat;\n  filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=0);\n  opacity: 0;\n  -webkit-transition: opacity 0.6s;\n  -moz-transition: opacity 0.6s;\n  -o-transition: opacity 0.6s;\n  transition: opacity 0.6s;\n}\n\n.lb-nav a.lb-prev:hover {\n  filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=100);\n  opacity: 1;\n}\n\n.lb-nav a.lb-next {\n  width: 64%;\n  right: 0;\n  float: right;\n  background: url(../images/next.png) right 48% no-repeat;\n  filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=0);\n  opacity: 0;\n  -webkit-transition: opacity 0.6s;\n  -moz-transition: opacity 0.6s;\n  -o-transition: opacity 0.6s;\n  transition: opacity 0.6s;\n}\n\n.lb-nav a.lb-next:hover {\n  filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=100);\n  opacity: 1;\n}\n\n.lb-dataContainer {\n  margin: 0 auto;\n  padding-top: 5px;\n  *zoom: 1;\n  width: 100%;\n  -moz-border-radius-bottomleft: 4px;\n  -webkit-border-bottom-left-radius: 4px;\n  border-bottom-left-radius: 4px;\n  -moz-border-radius-bottomright: 4px;\n  -webkit-border-bottom-right-radius: 4px;\n  border-bottom-right-radius: 4px;\n}\n\n.lb-dataContainer:after {\n  content: \"\";\n  display: table;\n  clear: both;\n}\n\n.lb-data {\n  padding: 0 4px;\n  color: #ccc;\n}\n\n.lb-data .lb-details {\n  width: 85%;\n  float: left;\n  text-align: left;\n  line-height: 1.1em;\n}\n\n.lb-data .lb-caption {\n  font-size: 13px;\n  font-weight: bold;\n  line-height: 1em;\n}\n\n.lb-data .lb-number {\n  display: block;\n  clear: left;\n  padding-bottom: 1em;\n  font-size: 12px;\n  color: #999999;\n}\n\n.lb-data .lb-close {\n  display: block;\n  float: right;\n  width: 30px;\n  height: 30px;\n  background: url(../images/close.png) top right no-repeat;\n  text-align: right;\n  outline: none;\n  filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=70);\n  opacity: 0.7;\n  -webkit-transition: opacity 0.2s;\n  -moz-transition: opacity 0.2s;\n  -o-transition: opacity 0.2s;\n  transition: opacity 0.2s;\n}\n\n.lb-data .lb-close:hover {\n  cursor: pointer;\n  filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=100);\n  opacity: 1;\n}\n"
  },
  {
    "path": "app_frontend/static/css/slideout.css",
    "content": ".page-menu {\n    background-image: linear-gradient(90deg, #eeeeee 90%, #bbbbbb 100%);\n}\n\n.page-menu .container {\n    margin-right: 10%;\n}\n\n.page-panel {\n    background-color: #fff;\n    margin-bottom: 0;\n}\n\n.slideout-menu {\n    position: fixed;\n    left: 0;\n    top: 0;\n    bottom: 0;\n    right: 0;\n    z-index: 0;\n    width: 256px;\n    overflow-y: auto;\n    -webkit-overflow-scrolling: touch;\n    display: none;\n}\n\n.slideout-panel {\n    position: relative;\n    z-index: 1;\n    /*will-change: transform;*/\n}\n\n.slideout-open,\n.slideout-open body,\n.slideout-open .slideout-panel {\n    overflow: hidden;\n}\n\n.slideout-open .slideout-menu {\n    display: block;\n}\n"
  },
  {
    "path": "app_frontend/static/js/bootstrap-select.js",
    "content": "/*!\n * Bootstrap-select v1.12.2 (http://silviomoreto.github.io/bootstrap-select)\n *\n * Copyright 2013-2017 bootstrap-select\n * Licensed under MIT (https://github.com/silviomoreto/bootstrap-select/blob/master/LICENSE)\n */\n\n(function (root, factory) {\n  if (typeof define === 'function' && define.amd) {\n    // AMD. Register as an anonymous module unless amdModuleId is set\n    define([\"jquery\"], function (a0) {\n      return (factory(a0));\n    });\n  } else if (typeof module === 'object' && module.exports) {\n    // Node. Does not work with strict CommonJS, but\n    // only CommonJS-like environments that support module.exports,\n    // like Node.\n    module.exports = factory(require(\"jquery\"));\n  } else {\n    factory(root[\"jQuery\"]);\n  }\n}(this, function (jQuery) {\n\n(function ($) {\n  'use strict';\n\n  //<editor-fold desc=\"Shims\">\n  if (!String.prototype.includes) {\n    (function () {\n      'use strict'; // needed to support `apply`/`call` with `undefined`/`null`\n      var toString = {}.toString;\n      var defineProperty = (function () {\n        // IE 8 only supports `Object.defineProperty` on DOM elements\n        try {\n          var object = {};\n          var $defineProperty = Object.defineProperty;\n          var result = $defineProperty(object, object, object) && $defineProperty;\n        } catch (error) {\n        }\n        return result;\n      }());\n      var indexOf = ''.indexOf;\n      var includes = function (search) {\n        if (this == null) {\n          throw new TypeError();\n        }\n        var string = String(this);\n        if (search && toString.call(search) == '[object RegExp]') {\n          throw new TypeError();\n        }\n        var stringLength = string.length;\n        var searchString = String(search);\n        var searchLength = searchString.length;\n        var position = arguments.length > 1 ? arguments[1] : undefined;\n        // `ToInteger`\n        var pos = position ? Number(position) : 0;\n        if (pos != pos) { // better `isNaN`\n          pos = 0;\n        }\n        var start = Math.min(Math.max(pos, 0), stringLength);\n        // Avoid the `indexOf` call if no match is possible\n        if (searchLength + start > stringLength) {\n          return false;\n        }\n        return indexOf.call(string, searchString, pos) != -1;\n      };\n      if (defineProperty) {\n        defineProperty(String.prototype, 'includes', {\n          'value': includes,\n          'configurable': true,\n          'writable': true\n        });\n      } else {\n        String.prototype.includes = includes;\n      }\n    }());\n  }\n\n  if (!String.prototype.startsWith) {\n    (function () {\n      'use strict'; // needed to support `apply`/`call` with `undefined`/`null`\n      var defineProperty = (function () {\n        // IE 8 only supports `Object.defineProperty` on DOM elements\n        try {\n          var object = {};\n          var $defineProperty = Object.defineProperty;\n          var result = $defineProperty(object, object, object) && $defineProperty;\n        } catch (error) {\n        }\n        return result;\n      }());\n      var toString = {}.toString;\n      var startsWith = function (search) {\n        if (this == null) {\n          throw new TypeError();\n        }\n        var string = String(this);\n        if (search && toString.call(search) == '[object RegExp]') {\n          throw new TypeError();\n        }\n        var stringLength = string.length;\n        var searchString = String(search);\n        var searchLength = searchString.length;\n        var position = arguments.length > 1 ? arguments[1] : undefined;\n        // `ToInteger`\n        var pos = position ? Number(position) : 0;\n        if (pos != pos) { // better `isNaN`\n          pos = 0;\n        }\n        var start = Math.min(Math.max(pos, 0), stringLength);\n        // Avoid the `indexOf` call if no match is possible\n        if (searchLength + start > stringLength) {\n          return false;\n        }\n        var index = -1;\n        while (++index < searchLength) {\n          if (string.charCodeAt(start + index) != searchString.charCodeAt(index)) {\n            return false;\n          }\n        }\n        return true;\n      };\n      if (defineProperty) {\n        defineProperty(String.prototype, 'startsWith', {\n          'value': startsWith,\n          'configurable': true,\n          'writable': true\n        });\n      } else {\n        String.prototype.startsWith = startsWith;\n      }\n    }());\n  }\n\n  if (!Object.keys) {\n    Object.keys = function (\n      o, // object\n      k, // key\n      r  // result array\n      ){\n      // initialize object and result\n      r=[];\n      // iterate over object keys\n      for (k in o)\n          // fill result array with non-prototypical keys\n        r.hasOwnProperty.call(o, k) && r.push(k);\n      // return result\n      return r;\n    };\n  }\n\n  // set data-selected on select element if the value has been programmatically selected\n  // prior to initialization of bootstrap-select\n  // * consider removing or replacing an alternative method *\n  var valHooks = {\n    useDefault: false,\n    _set: $.valHooks.select.set\n  };\n\n  $.valHooks.select.set = function(elem, value) {\n    if (value && !valHooks.useDefault) $(elem).data('selected', true);\n\n    return valHooks._set.apply(this, arguments);\n  };\n\n  var changed_arguments = null;\n  $.fn.triggerNative = function (eventName) {\n    var el = this[0],\n        event;\n\n    if (el.dispatchEvent) { // for modern browsers & IE9+\n      if (typeof Event === 'function') {\n        // For modern browsers\n        event = new Event(eventName, {\n          bubbles: true\n        });\n      } else {\n        // For IE since it doesn't support Event constructor\n        event = document.createEvent('Event');\n        event.initEvent(eventName, true, false);\n      }\n\n      el.dispatchEvent(event);\n    } else if (el.fireEvent) { // for IE8\n      event = document.createEventObject();\n      event.eventType = eventName;\n      el.fireEvent('on' + eventName, event);\n    } else {\n      // fall back to jQuery.trigger\n      this.trigger(eventName);\n    }\n  };\n  //</editor-fold>\n\n  // Case insensitive contains search\n  $.expr.pseudos.icontains = function (obj, index, meta) {\n    var $obj = $(obj);\n    var haystack = ($obj.data('tokens') || $obj.text()).toString().toUpperCase();\n    return haystack.includes(meta[3].toUpperCase());\n  };\n\n  // Case insensitive begins search\n  $.expr.pseudos.ibegins = function (obj, index, meta) {\n    var $obj = $(obj);\n    var haystack = ($obj.data('tokens') || $obj.text()).toString().toUpperCase();\n    return haystack.startsWith(meta[3].toUpperCase());\n  };\n\n  // Case and accent insensitive contains search\n  $.expr.pseudos.aicontains = function (obj, index, meta) {\n    var $obj = $(obj);\n    var haystack = ($obj.data('tokens') || $obj.data('normalizedText') || $obj.text()).toString().toUpperCase();\n    return haystack.includes(meta[3].toUpperCase());\n  };\n\n  // Case and accent insensitive begins search\n  $.expr.pseudos.aibegins = function (obj, index, meta) {\n    var $obj = $(obj);\n    var haystack = ($obj.data('tokens') || $obj.data('normalizedText') || $obj.text()).toString().toUpperCase();\n    return haystack.startsWith(meta[3].toUpperCase());\n  };\n\n  /**\n   * Remove all diatrics from the given text.\n   * @access private\n   * @param {String} text\n   * @returns {String}\n   */\n  function normalizeToBase(text) {\n    var rExps = [\n      {re: /[\\xC0-\\xC6]/g, ch: \"A\"},\n      {re: /[\\xE0-\\xE6]/g, ch: \"a\"},\n      {re: /[\\xC8-\\xCB]/g, ch: \"E\"},\n      {re: /[\\xE8-\\xEB]/g, ch: \"e\"},\n      {re: /[\\xCC-\\xCF]/g, ch: \"I\"},\n      {re: /[\\xEC-\\xEF]/g, ch: \"i\"},\n      {re: /[\\xD2-\\xD6]/g, ch: \"O\"},\n      {re: /[\\xF2-\\xF6]/g, ch: \"o\"},\n      {re: /[\\xD9-\\xDC]/g, ch: \"U\"},\n      {re: /[\\xF9-\\xFC]/g, ch: \"u\"},\n      {re: /[\\xC7-\\xE7]/g, ch: \"c\"},\n      {re: /[\\xD1]/g, ch: \"N\"},\n      {re: /[\\xF1]/g, ch: \"n\"}\n    ];\n    $.each(rExps, function () {\n      text = text ? text.replace(this.re, this.ch) : '';\n    });\n    return text;\n  }\n\n\n  // List of HTML entities for escaping.\n  var escapeMap = {\n    '&': '&amp;',\n    '<': '&lt;',\n    '>': '&gt;',\n    '\"': '&quot;',\n    \"'\": '&#x27;',\n    '`': '&#x60;'\n  };\n  \n  var unescapeMap = {\n    '&amp;': '&',\n    '&lt;': '<',\n    '&gt;': '>',\n    '&quot;': '\"',\n    '&#x27;': \"'\",\n    '&#x60;': '`'\n  };\n\n  // Functions for escaping and unescaping strings to/from HTML interpolation.\n  var createEscaper = function(map) {\n    var escaper = function(match) {\n      return map[match];\n    };\n    // Regexes for identifying a key that needs to be escaped.\n    var source = '(?:' + Object.keys(map).join('|') + ')';\n    var testRegexp = RegExp(source);\n    var replaceRegexp = RegExp(source, 'g');\n    return function(string) {\n      string = string == null ? '' : '' + string;\n      return testRegexp.test(string) ? string.replace(replaceRegexp, escaper) : string;\n    };\n  };\n\n  var htmlEscape = createEscaper(escapeMap);\n  var htmlUnescape = createEscaper(unescapeMap);\n\n  var Selectpicker = function (element, options) {\n    // bootstrap-select has been initialized - revert valHooks.select.set back to its original function\n    if (!valHooks.useDefault) {\n      $.valHooks.select.set = valHooks._set;\n      valHooks.useDefault = true;\n    }\n\n    this.$element = $(element);\n    this.$newElement = null;\n    this.$button = null;\n    this.$menu = null;\n    this.$lis = null;\n    this.options = options;\n\n    // If we have no title yet, try to pull it from the html title attribute (jQuery doesnt' pick it up as it's not a\n    // data-attribute)\n    if (this.options.title === null) {\n      this.options.title = this.$element.attr('title');\n    }\n\n    // Format window padding\n    var winPad = this.options.windowPadding;\n    if (typeof winPad === 'number') {\n      this.options.windowPadding = [winPad, winPad, winPad, winPad];\n    }\n\n    //Expose public methods\n    this.val = Selectpicker.prototype.val;\n    this.render = Selectpicker.prototype.render;\n    this.refresh = Selectpicker.prototype.refresh;\n    this.setStyle = Selectpicker.prototype.setStyle;\n    this.selectAll = Selectpicker.prototype.selectAll;\n    this.deselectAll = Selectpicker.prototype.deselectAll;\n    this.destroy = Selectpicker.prototype.destroy;\n    this.remove = Selectpicker.prototype.remove;\n    this.show = Selectpicker.prototype.show;\n    this.hide = Selectpicker.prototype.hide;\n\n    this.init();\n  };\n\n  Selectpicker.VERSION = '1.12.2';\n\n  // part of this is duplicated in i18n/defaults-en_US.js. Make sure to update both.\n  Selectpicker.DEFAULTS = {\n    noneSelectedText: 'Nothing selected',\n    noneResultsText: 'No results matched {0}',\n    countSelectedText: function (numSelected, numTotal) {\n      return (numSelected == 1) ? \"{0} item selected\" : \"{0} items selected\";\n    },\n    maxOptionsText: function (numAll, numGroup) {\n      return [\n        (numAll == 1) ? 'Limit reached ({n} item max)' : 'Limit reached ({n} items max)',\n        (numGroup == 1) ? 'Group limit reached ({n} item max)' : 'Group limit reached ({n} items max)'\n      ];\n    },\n    selectAllText: 'Select All',\n    deselectAllText: 'Deselect All',\n    doneButton: false,\n    doneButtonText: 'Close',\n    multipleSeparator: ', ',\n    styleBase: 'btn',\n    style: 'btn-default',\n    size: 'auto',\n    title: null,\n    selectedTextFormat: 'values',\n    width: false,\n    container: false,\n    hideDisabled: false,\n    showSubtext: false,\n    showIcon: true,\n    showContent: true,\n    dropupAuto: true,\n    header: false,\n    liveSearch: false,\n    liveSearchPlaceholder: null,\n    liveSearchNormalize: false,\n    liveSearchStyle: 'contains',\n    actionsBox: false,\n    iconBase: 'glyphicon',\n    tickIcon: 'glyphicon-ok',\n    showTick: false,\n    template: {\n      caret: '<span class=\"caret\"></span>'\n    },\n    maxOptions: false,\n    mobile: false,\n    selectOnTab: false,\n    dropdownAlignRight: false,\n    windowPadding: 0\n  };\n\n  Selectpicker.prototype = {\n\n    constructor: Selectpicker,\n\n    init: function () {\n      var that = this,\n          id = this.$element.attr('id');\n\n      this.$element.addClass('bs-select-hidden');\n\n      // store originalIndex (key) and newIndex (value) in this.liObj for fast accessibility\n      // allows us to do this.$lis.eq(that.liObj[index]) instead of this.$lis.filter('[data-original-index=\"' + index + '\"]')\n      this.liObj = {};\n      this.multiple = this.$element.prop('multiple');\n      this.autofocus = this.$element.prop('autofocus');\n      this.$newElement = this.createView();\n      this.$element\n        .after(this.$newElement)\n        .appendTo(this.$newElement);\n      this.$button = this.$newElement.children('button');\n      this.$menu = this.$newElement.children('.dropdown-menu');\n      this.$menuInner = this.$menu.children('.inner');\n      this.$searchbox = this.$menu.find('input');\n\n      this.$element.removeClass('bs-select-hidden');\n\n      if (this.options.dropdownAlignRight === true) this.$menu.addClass('dropdown-menu-right');\n\n      if (typeof id !== 'undefined') {\n        this.$button.attr('data-id', id);\n        $('label[for=\"' + id + '\"]').click(function (e) {\n          e.preventDefault();\n          that.$button.focus();\n        });\n      }\n\n      this.checkDisabled();\n      this.clickListener();\n      if (this.options.liveSearch) this.liveSearchListener();\n      this.render();\n      this.setStyle();\n      this.setWidth();\n      if (this.options.container) this.selectPosition();\n      this.$menu.data('this', this);\n      this.$newElement.data('this', this);\n      if (this.options.mobile) this.mobile();\n\n      this.$newElement.on({\n        'hide.bs.dropdown': function (e) {\n          that.$menuInner.attr('aria-expanded', false);\n          that.$element.trigger('hide.bs.select', e);\n        },\n        'hidden.bs.dropdown': function (e) {\n          that.$element.trigger('hidden.bs.select', e);\n        },\n        'show.bs.dropdown': function (e) {\n          that.$menuInner.attr('aria-expanded', true);\n          that.$element.trigger('show.bs.select', e);\n        },\n        'shown.bs.dropdown': function (e) {\n          that.$element.trigger('shown.bs.select', e);\n        }\n      });\n\n      if (that.$element[0].hasAttribute('required')) {\n        this.$element.on('invalid', function () {\n          that.$button\n            .addClass('bs-invalid')\n            .focus();\n\n          that.$element.on({\n            'focus.bs.select': function () {\n              that.$button.focus();\n              that.$element.off('focus.bs.select');\n            },\n            'shown.bs.select': function () {\n              that.$element\n                .val(that.$element.val()) // set the value to hide the validation message in Chrome when menu is opened\n                .off('shown.bs.select');\n            },\n            'rendered.bs.select': function () {\n              // if select is no longer invalid, remove the bs-invalid class\n              if (this.validity.valid) that.$button.removeClass('bs-invalid');\n              that.$element.off('rendered.bs.select');\n            }\n          });\n        });\n      }\n\n      setTimeout(function () {\n        that.$element.trigger('loaded.bs.select');\n      });\n    },\n\n    createDropdown: function () {\n      // Options\n      // If we are multiple or showTick option is set, then add the show-tick class\n      var showTick = (this.multiple || this.options.showTick) ? ' show-tick' : '',\n          inputGroup = this.$element.parent().hasClass('input-group') ? ' input-group-btn' : '',\n          autofocus = this.autofocus ? ' autofocus' : '';\n      // Elements\n      var header = this.options.header ? '<div class=\"popover-title\"><button type=\"button\" class=\"close\" aria-hidden=\"true\">&times;</button>' + this.options.header + '</div>' : '';\n      var searchbox = this.options.liveSearch ?\n      '<div class=\"bs-searchbox\">' +\n      '<input type=\"text\" class=\"form-control\" autocomplete=\"off\"' +\n      (null === this.options.liveSearchPlaceholder ? '' : ' placeholder=\"' + htmlEscape(this.options.liveSearchPlaceholder) + '\"') + ' role=\"textbox\" aria-label=\"Search\">' +\n      '</div>'\n          : '';\n      var actionsbox = this.multiple && this.options.actionsBox ?\n      '<div class=\"bs-actionsbox\">' +\n      '<div class=\"btn-group btn-group-sm btn-block\">' +\n      '<button type=\"button\" class=\"actions-btn bs-select-all btn btn-default\">' +\n      this.options.selectAllText +\n      '</button>' +\n      '<button type=\"button\" class=\"actions-btn bs-deselect-all btn btn-default\">' +\n      this.options.deselectAllText +\n      '</button>' +\n      '</div>' +\n      '</div>'\n          : '';\n      var donebutton = this.multiple && this.options.doneButton ?\n      '<div class=\"bs-donebutton\">' +\n      '<div class=\"btn-group btn-block\">' +\n      '<button type=\"button\" class=\"btn btn-sm btn-default\">' +\n      this.options.doneButtonText +\n      '</button>' +\n      '</div>' +\n      '</div>'\n          : '';\n      var drop =\n          '<div class=\"btn-group bootstrap-select' + showTick + inputGroup + '\">' +\n          '<button type=\"button\" class=\"' + this.options.styleBase + ' dropdown-toggle\" data-toggle=\"dropdown\"' + autofocus + ' role=\"button\">' +\n          '<span class=\"filter-option pull-left\"></span>&nbsp;' +\n          '<span class=\"bs-caret\">' +\n          this.options.template.caret +\n          '</span>' +\n          '</button>' +\n          '<div class=\"dropdown-menu open\" role=\"combobox\">' +\n          header +\n          searchbox +\n          actionsbox +\n          '<ul class=\"dropdown-menu inner\" role=\"listbox\" aria-expanded=\"false\">' +\n          '</ul>' +\n          donebutton +\n          '</div>' +\n          '</div>';\n\n      return $(drop);\n    },\n\n    createView: function () {\n      var $drop = this.createDropdown(),\n          li = this.createLi();\n\n      $drop.find('ul')[0].innerHTML = li;\n      return $drop;\n    },\n\n    reloadLi: function () {\n      // rebuild\n      var li = this.createLi();\n      this.$menuInner[0].innerHTML = li;\n    },\n\n    createLi: function () {\n      var that = this,\n          _li = [],\n          optID = 0,\n          titleOption = document.createElement('option'),\n          liIndex = -1; // increment liIndex whenever a new <li> element is created to ensure liObj is correct\n\n      // Helper functions\n      /**\n       * @param content\n       * @param [index]\n       * @param [classes]\n       * @param [optgroup]\n       * @returns {string}\n       */\n      var generateLI = function (content, index, classes, optgroup) {\n        return '<li' +\n            ((typeof classes !== 'undefined' & '' !== classes) ? ' class=\"' + classes + '\"' : '') +\n            ((typeof index !== 'undefined' & null !== index) ? ' data-original-index=\"' + index + '\"' : '') +\n            ((typeof optgroup !== 'undefined' & null !== optgroup) ? 'data-optgroup=\"' + optgroup + '\"' : '') +\n            '>' + content + '</li>';\n      };\n\n      /**\n       * @param text\n       * @param [classes]\n       * @param [inline]\n       * @param [tokens]\n       * @returns {string}\n       */\n      var generateA = function (text, classes, inline, tokens) {\n        return '<a tabindex=\"0\"' +\n            (typeof classes !== 'undefined' ? ' class=\"' + classes + '\"' : '') +\n            (inline ? ' style=\"' + inline + '\"' : '') +\n            (that.options.liveSearchNormalize ? ' data-normalized-text=\"' + normalizeToBase(htmlEscape($(text).html())) + '\"' : '') +\n            (typeof tokens !== 'undefined' || tokens !== null ? ' data-tokens=\"' + tokens + '\"' : '') +\n            ' role=\"option\">' + text +\n            '<span class=\"' + that.options.iconBase + ' ' + that.options.tickIcon + ' check-mark\"></span>' +\n            '</a>';\n      };\n\n      if (this.options.title && !this.multiple) {\n        // this option doesn't create a new <li> element, but does add a new option, so liIndex is decreased\n        // since liObj is recalculated on every refresh, liIndex needs to be decreased even if the titleOption is already appended\n        liIndex--;\n\n        if (!this.$element.find('.bs-title-option').length) {\n          // Use native JS to prepend option (faster)\n          var element = this.$element[0];\n          titleOption.className = 'bs-title-option';\n          titleOption.innerHTML = this.options.title;\n          titleOption.value = '';\n          element.insertBefore(titleOption, element.firstChild);\n          // Check if selected or data-selected attribute is already set on an option. If not, select the titleOption option.\n          // the selected item may have been changed by user or programmatically before the bootstrap select plugin runs,\n          // if so, the select will have the data-selected attribute\n          var $opt = $(element.options[element.selectedIndex]);\n          if ($opt.attr('selected') === undefined && this.$element.data('selected') === undefined) {\n            titleOption.selected = true;\n          }\n        }\n      }\n\n      this.$element.find('option').each(function (index) {\n        var $this = $(this);\n\n        liIndex++;\n\n        if ($this.hasClass('bs-title-option')) return;\n\n        // Get the class and text for the option\n        var optionClass = this.className || '',\n            inline = this.style.cssText,\n            text = $this.data('content') ? $this.data('content') : $this.html(),\n            tokens = $this.data('tokens') ? $this.data('tokens') : null,\n            subtext = typeof $this.data('subtext') !== 'undefined' ? '<small class=\"text-muted\">' + $this.data('subtext') + '</small>' : '',\n            icon = typeof $this.data('icon') !== 'undefined' ? '<span class=\"' + that.options.iconBase + ' ' + $this.data('icon') + '\"></span> ' : '',\n            $parent = $this.parent(),\n            isOptgroup = $parent[0].tagName === 'OPTGROUP',\n            isOptgroupDisabled = isOptgroup && $parent[0].disabled,\n            isDisabled = this.disabled || isOptgroupDisabled;\n\n        if (icon !== '' && isDisabled) {\n          icon = '<span>' + icon + '</span>';\n        }\n\n        if (that.options.hideDisabled && (isDisabled && !isOptgroup || isOptgroupDisabled)) {\n          liIndex--;\n          return;\n        }\n\n        if (!$this.data('content')) {\n          // Prepend any icon and append any subtext to the main text.\n          text = icon + '<span class=\"text\">' + text + subtext + '</span>';\n        }\n\n        if (isOptgroup && $this.data('divider') !== true) {\n          if (that.options.hideDisabled && isDisabled) {\n            if ($parent.data('allOptionsDisabled') === undefined) {\n              var $options = $parent.children();\n              $parent.data('allOptionsDisabled', $options.filter(':disabled').length === $options.length);\n            }\n\n            if ($parent.data('allOptionsDisabled')) {\n              liIndex--;\n              return;\n            }\n          }\n\n          var optGroupClass = ' ' + $parent[0].className || '';\n\n          if ($this.index() === 0) { // Is it the first option of the optgroup?\n            optID += 1;\n\n            // Get the opt group label\n            var label = $parent[0].label,\n                labelSubtext = typeof $parent.data('subtext') !== 'undefined' ? '<small class=\"text-muted\">' + $parent.data('subtext') + '</small>' : '',\n                labelIcon = $parent.data('icon') ? '<span class=\"' + that.options.iconBase + ' ' + $parent.data('icon') + '\"></span> ' : '';\n\n            label = labelIcon + '<span class=\"text\">' + htmlEscape(label) + labelSubtext + '</span>';\n\n            if (index !== 0 && _li.length > 0) { // Is it NOT the first option of the select && are there elements in the dropdown?\n              liIndex++;\n              _li.push(generateLI('', null, 'divider', optID + 'div'));\n            }\n            liIndex++;\n            _li.push(generateLI(label, null, 'dropdown-header' + optGroupClass, optID));\n          }\n\n          if (that.options.hideDisabled && isDisabled) {\n            liIndex--;\n            return;\n          }\n\n          _li.push(generateLI(generateA(text, 'opt ' + optionClass + optGroupClass, inline, tokens), index, '', optID));\n        } else if ($this.data('divider') === true) {\n          _li.push(generateLI('', index, 'divider'));\n        } else if ($this.data('hidden') === true) {\n          _li.push(generateLI(generateA(text, optionClass, inline, tokens), index, 'hidden is-hidden'));\n        } else {\n          var showDivider = this.previousElementSibling && this.previousElementSibling.tagName === 'OPTGROUP';\n\n          // if previous element is not an optgroup and hideDisabled is true\n          if (!showDivider && that.options.hideDisabled) {\n            // get previous elements\n            var $prev = $(this).prevAll();\n\n            for (var i = 0; i < $prev.length; i++) {\n              // find the first element in the previous elements that is an optgroup\n              if ($prev[i].tagName === 'OPTGROUP') {\n                var optGroupDistance = 0;\n\n                // loop through the options in between the current option and the optgroup\n                // and check if they are hidden or disabled\n                for (var d = 0; d < i; d++) {\n                  var prevOption = $prev[d];\n                  if (prevOption.disabled || $(prevOption).data('hidden') === true) optGroupDistance++;\n                }\n\n                // if all of the options between the current option and the optgroup are hidden or disabled, show the divider\n                if (optGroupDistance === i) showDivider = true;\n\n                break;\n              }\n            }\n          }\n\n          if (showDivider) {\n            liIndex++;\n            _li.push(generateLI('', null, 'divider', optID + 'div'));\n          }\n          _li.push(generateLI(generateA(text, optionClass, inline, tokens), index));\n        }\n\n        that.liObj[index] = liIndex;\n      });\n\n      //If we are not multiple, we don't have a selected item, and we don't have a title, select the first element so something is set in the button\n      if (!this.multiple && this.$element.find('option:selected').length === 0 && !this.options.title) {\n        this.$element.find('option').eq(0).prop('selected', true).attr('selected', 'selected');\n      }\n\n      return _li.join('');\n    },\n\n    findLis: function () {\n      if (this.$lis == null) this.$lis = this.$menu.find('li');\n      return this.$lis;\n    },\n\n    /**\n     * @param [updateLi] defaults to true\n     */\n    render: function (updateLi) {\n      var that = this,\n          notDisabled;\n\n      //Update the LI to match the SELECT\n      if (updateLi !== false) {\n        this.$element.find('option').each(function (index) {\n          var $lis = that.findLis().eq(that.liObj[index]);\n\n          that.setDisabled(index, this.disabled || this.parentNode.tagName === 'OPTGROUP' && this.parentNode.disabled, $lis);\n          that.setSelected(index, this.selected, $lis);\n        });\n      }\n\n      this.togglePlaceholder();\n\n      this.tabIndex();\n\n      var selectedItems = this.$element.find('option').map(function () {\n        if (this.selected) {\n          if (that.options.hideDisabled && (this.disabled || this.parentNode.tagName === 'OPTGROUP' && this.parentNode.disabled)) return;\n\n          var $this = $(this),\n              icon = $this.data('icon') && that.options.showIcon ? '<i class=\"' + that.options.iconBase + ' ' + $this.data('icon') + '\"></i> ' : '',\n              subtext;\n\n          if (that.options.showSubtext && $this.data('subtext') && !that.multiple) {\n            subtext = ' <small class=\"text-muted\">' + $this.data('subtext') + '</small>';\n          } else {\n            subtext = '';\n          }\n          if (typeof $this.attr('title') !== 'undefined') {\n            return $this.attr('title');\n          } else if ($this.data('content') && that.options.showContent) {\n            return $this.data('content').toString();\n          } else {\n            return icon + $this.html() + subtext;\n          }\n        }\n      }).toArray();\n\n      //Fixes issue in IE10 occurring when no default option is selected and at least one option is disabled\n      //Convert all the values into a comma delimited string\n      var title = !this.multiple ? selectedItems[0] : selectedItems.join(this.options.multipleSeparator);\n\n      //If this is multi select, and the selectText type is count, the show 1 of 2 selected etc..\n      if (this.multiple && this.options.selectedTextFormat.indexOf('count') > -1) {\n        var max = this.options.selectedTextFormat.split('>');\n        if ((max.length > 1 && selectedItems.length > max[1]) || (max.length == 1 && selectedItems.length >= 2)) {\n          notDisabled = this.options.hideDisabled ? ', [disabled]' : '';\n          var totalCount = this.$element.find('option').not('[data-divider=\"true\"], [data-hidden=\"true\"]' + notDisabled).length,\n              tr8nText = (typeof this.options.countSelectedText === 'function') ? this.options.countSelectedText(selectedItems.length, totalCount) : this.options.countSelectedText;\n          title = tr8nText.replace('{0}', selectedItems.length.toString()).replace('{1}', totalCount.toString());\n        }\n      }\n\n      if (this.options.title == undefined) {\n        this.options.title = this.$element.attr('title');\n      }\n\n      if (this.options.selectedTextFormat == 'static') {\n        title = this.options.title;\n      }\n\n      //If we dont have a title, then use the default, or if nothing is set at all, use the not selected text\n      if (!title) {\n        title = typeof this.options.title !== 'undefined' ? this.options.title : this.options.noneSelectedText;\n      }\n\n      //strip all HTML tags and trim the result, then unescape any escaped tags\n      this.$button.attr('title', htmlUnescape($.trim(title.replace(/<[^>]*>?/g, ''))));\n      this.$button.children('.filter-option').html(title);\n\n      this.$element.trigger('rendered.bs.select');\n    },\n\n    /**\n     * @param [style]\n     * @param [status]\n     */\n    setStyle: function (style, status) {\n      if (this.$element.attr('class')) {\n        this.$newElement.addClass(this.$element.attr('class').replace(/selectpicker|mobile-device|bs-select-hidden|validate\\[.*\\]/gi, ''));\n      }\n\n      var buttonClass = style ? style : this.options.style;\n\n      if (status == 'add') {\n        this.$button.addClass(buttonClass);\n      } else if (status == 'remove') {\n        this.$button.removeClass(buttonClass);\n      } else {\n        this.$button.removeClass(this.options.style);\n        this.$button.addClass(buttonClass);\n      }\n    },\n\n    liHeight: function (refresh) {\n      if (!refresh && (this.options.size === false || this.sizeInfo)) return;\n\n      var newElement = document.createElement('div'),\n          menu = document.createElement('div'),\n          menuInner = document.createElement('ul'),\n          divider = document.createElement('li'),\n          li = document.createElement('li'),\n          a = document.createElement('a'),\n          text = document.createElement('span'),\n          header = this.options.header && this.$menu.find('.popover-title').length > 0 ? this.$menu.find('.popover-title')[0].cloneNode(true) : null,\n          search = this.options.liveSearch ? document.createElement('div') : null,\n          actions = this.options.actionsBox && this.multiple && this.$menu.find('.bs-actionsbox').length > 0 ? this.$menu.find('.bs-actionsbox')[0].cloneNode(true) : null,\n          doneButton = this.options.doneButton && this.multiple && this.$menu.find('.bs-donebutton').length > 0 ? this.$menu.find('.bs-donebutton')[0].cloneNode(true) : null;\n\n      text.className = 'text';\n      newElement.className = this.$menu[0].parentNode.className + ' open';\n      menu.className = 'dropdown-menu open';\n      menuInner.className = 'dropdown-menu inner';\n      divider.className = 'divider';\n\n      text.appendChild(document.createTextNode('Inner text'));\n      a.appendChild(text);\n      li.appendChild(a);\n      menuInner.appendChild(li);\n      menuInner.appendChild(divider);\n      if (header) menu.appendChild(header);\n      if (search) {\n        var input = document.createElement('input');\n        search.className = 'bs-searchbox';\n        input.className = 'form-control';\n        search.appendChild(input);\n        menu.appendChild(search);\n      }\n      if (actions) menu.appendChild(actions);\n      menu.appendChild(menuInner);\n      if (doneButton) menu.appendChild(doneButton);\n      newElement.appendChild(menu);\n\n      document.body.appendChild(newElement);\n\n      var liHeight = a.offsetHeight,\n          headerHeight = header ? header.offsetHeight : 0,\n          searchHeight = search ? search.offsetHeight : 0,\n          actionsHeight = actions ? actions.offsetHeight : 0,\n          doneButtonHeight = doneButton ? doneButton.offsetHeight : 0,\n          dividerHeight = $(divider).outerHeight(true),\n          // fall back to jQuery if getComputedStyle is not supported\n          menuStyle = typeof getComputedStyle === 'function' ? getComputedStyle(menu) : false,\n          $menu = menuStyle ? null : $(menu),\n          menuPadding = {\n            vert: parseInt(menuStyle ? menuStyle.paddingTop : $menu.css('paddingTop')) +\n                  parseInt(menuStyle ? menuStyle.paddingBottom : $menu.css('paddingBottom')) +\n                  parseInt(menuStyle ? menuStyle.borderTopWidth : $menu.css('borderTopWidth')) +\n                  parseInt(menuStyle ? menuStyle.borderBottomWidth : $menu.css('borderBottomWidth')),\n            horiz: parseInt(menuStyle ? menuStyle.paddingLeft : $menu.css('paddingLeft')) +\n                  parseInt(menuStyle ? menuStyle.paddingRight : $menu.css('paddingRight')) +\n                  parseInt(menuStyle ? menuStyle.borderLeftWidth : $menu.css('borderLeftWidth')) +\n                  parseInt(menuStyle ? menuStyle.borderRightWidth : $menu.css('borderRightWidth'))\n          },\n          menuExtras =  {\n            vert: menuPadding.vert +\n                  parseInt(menuStyle ? menuStyle.marginTop : $menu.css('marginTop')) +\n                  parseInt(menuStyle ? menuStyle.marginBottom : $menu.css('marginBottom')) + 2,\n            horiz: menuPadding.horiz +\n                  parseInt(menuStyle ? menuStyle.marginLeft : $menu.css('marginLeft')) +\n                  parseInt(menuStyle ? menuStyle.marginRight : $menu.css('marginRight')) + 2\n          }\n\n      document.body.removeChild(newElement);\n\n      this.sizeInfo = {\n        liHeight: liHeight,\n        headerHeight: headerHeight,\n        searchHeight: searchHeight,\n        actionsHeight: actionsHeight,\n        doneButtonHeight: doneButtonHeight,\n        dividerHeight: dividerHeight,\n        menuPadding: menuPadding,\n        menuExtras: menuExtras\n      };\n    },\n\n    setSize: function () {\n      this.findLis();\n      this.liHeight();\n\n      if (this.options.header) this.$menu.css('padding-top', 0);\n      if (this.options.size === false) return;\n\n      var that = this,\n          $menu = this.$menu,\n          $menuInner = this.$menuInner,\n          $window = $(window),\n          selectHeight = this.$newElement[0].offsetHeight,\n          selectWidth = this.$newElement[0].offsetWidth,\n          liHeight = this.sizeInfo['liHeight'],\n          headerHeight = this.sizeInfo['headerHeight'],\n          searchHeight = this.sizeInfo['searchHeight'],\n          actionsHeight = this.sizeInfo['actionsHeight'],\n          doneButtonHeight = this.sizeInfo['doneButtonHeight'],\n          divHeight = this.sizeInfo['dividerHeight'],\n          menuPadding = this.sizeInfo['menuPadding'],\n          menuExtras = this.sizeInfo['menuExtras'],\n          notDisabled = this.options.hideDisabled ? '.disabled' : '',\n          menuHeight,\n          menuWidth,\n          getHeight,\n          getWidth,\n          selectOffsetTop,\n          selectOffsetBot,\n          selectOffsetLeft,\n          selectOffsetRight,\n          getPos = function() {\n            var pos = that.$newElement.offset(),\n                $container = $(that.options.container),\n                containerPos;\n\n            if (that.options.container && !$container.is('body')) {\n              containerPos = $container.offset();\n              containerPos.top += parseInt($container.css('borderTopWidth'));\n              containerPos.left += parseInt($container.css('borderLeftWidth'));\n            } else {\n              containerPos = { top: 0, left: 0 };\n            }\n\n            var winPad = that.options.windowPadding;\n            selectOffsetTop = pos.top - containerPos.top - $window.scrollTop();\n            selectOffsetBot = $window.height() - selectOffsetTop - selectHeight - containerPos.top - winPad[2];\n            selectOffsetLeft = pos.left - containerPos.left - $window.scrollLeft();\n            selectOffsetRight = $window.width() - selectOffsetLeft - selectWidth - containerPos.left - winPad[1];\n            selectOffsetTop -= winPad[0];\n            selectOffsetLeft -= winPad[3];\n          };\n\n      getPos();\n\n      if (this.options.size === 'auto') {\n        var getSize = function () {\n          var minHeight,\n              hasClass = function (className, include) {\n                return function (element) {\n                    if (include) {\n                        return (element.classList ? element.classList.contains(className) : $(element).hasClass(className));\n                    } else {\n                        return !(element.classList ? element.classList.contains(className) : $(element).hasClass(className));\n                    }\n                };\n              },\n              lis = that.$menuInner[0].getElementsByTagName('li'),\n              lisVisible = Array.prototype.filter ? Array.prototype.filter.call(lis, hasClass('hidden', false)) : that.$lis.not('.hidden'),\n              optGroup = Array.prototype.filter ? Array.prototype.filter.call(lisVisible, hasClass('dropdown-header', true)) : lisVisible.filter('.dropdown-header');\n\n          getPos();\n          menuHeight = selectOffsetBot - menuExtras.vert;\n          menuWidth = selectOffsetRight - menuExtras.horiz;\n\n          if (that.options.container) {\n            if (!$menu.data('height')) $menu.data('height', $menu.height());\n            getHeight = $menu.data('height');\n\n            if (!$menu.data('width')) $menu.data('width', $menu.width());\n            getWidth = $menu.data('width');\n          } else {\n            getHeight = $menu.height();\n            getWidth = $menu.width();\n          }\n\n          if (that.options.dropupAuto) {\n            that.$newElement.toggleClass('dropup', selectOffsetTop > selectOffsetBot && (menuHeight - menuExtras.vert) < getHeight);\n          }\n\n          if (that.$newElement.hasClass('dropup')) {\n            menuHeight = selectOffsetTop - menuExtras.vert;\n          }\n\n          if (that.options.dropdownAlignRight === 'auto') {\n            $menu.toggleClass('dropdown-menu-right', selectOffsetLeft > selectOffsetRight && (menuWidth - menuExtras.horiz) < (getWidth - selectWidth));\n          }\n\n          if ((lisVisible.length + optGroup.length) > 3) {\n            minHeight = liHeight * 3 + menuExtras.vert - 2;\n          } else {\n            minHeight = 0;\n          }\n\n          $menu.css({\n            'max-height': menuHeight + 'px',\n            'overflow': 'hidden',\n            'min-height': minHeight + headerHeight + searchHeight + actionsHeight + doneButtonHeight + 'px'\n          });\n          $menuInner.css({\n            'max-height': menuHeight - headerHeight - searchHeight - actionsHeight - doneButtonHeight - menuPadding.vert + 'px',\n            'overflow-y': 'auto',\n            'min-height': Math.max(minHeight - menuPadding.vert, 0) + 'px'\n          });\n        };\n        getSize();\n        this.$searchbox.off('input.getSize propertychange.getSize').on('input.getSize propertychange.getSize', getSize);\n        $window.off('resize.getSize scroll.getSize').on('resize.getSize scroll.getSize', getSize);\n      } else if (this.options.size && this.options.size != 'auto' && this.$lis.not(notDisabled).length > this.options.size) {\n        var optIndex = this.$lis.not('.divider').not(notDisabled).children().slice(0, this.options.size).last().parent().index(),\n            divLength = this.$lis.slice(0, optIndex + 1).filter('.divider').length;\n        menuHeight = liHeight * this.options.size + divLength * divHeight + menuPadding.vert;\n\n        if (that.options.container) {\n          if (!$menu.data('height')) $menu.data('height', $menu.height());\n          getHeight = $menu.data('height');\n        } else {\n          getHeight = $menu.height();\n        }\n\n        if (that.options.dropupAuto) {\n          //noinspection JSUnusedAssignment\n          this.$newElement.toggleClass('dropup', selectOffsetTop > selectOffsetBot && (menuHeight - menuExtras.vert) < getHeight);\n        }\n        $menu.css({\n          'max-height': menuHeight + headerHeight + searchHeight + actionsHeight + doneButtonHeight + 'px',\n          'overflow': 'hidden',\n          'min-height': ''\n        });\n        $menuInner.css({\n          'max-height': menuHeight - menuPadding.vert + 'px',\n          'overflow-y': 'auto',\n          'min-height': ''\n        });\n      }\n    },\n\n    setWidth: function () {\n      if (this.options.width === 'auto') {\n        this.$menu.css('min-width', '0');\n\n        // Get correct width if element is hidden\n        var $selectClone = this.$menu.parent().clone().appendTo('body'),\n            $selectClone2 = this.options.container ? this.$newElement.clone().appendTo('body') : $selectClone,\n            ulWidth = $selectClone.children('.dropdown-menu').outerWidth(),\n            btnWidth = $selectClone2.css('width', 'auto').children('button').outerWidth();\n\n        $selectClone.remove();\n        $selectClone2.remove();\n\n        // Set width to whatever's larger, button title or longest option\n        this.$newElement.css('width', Math.max(ulWidth, btnWidth) + 'px');\n      } else if (this.options.width === 'fit') {\n        // Remove inline min-width so width can be changed from 'auto'\n        this.$menu.css('min-width', '');\n        this.$newElement.css('width', '').addClass('fit-width');\n      } else if (this.options.width) {\n        // Remove inline min-width so width can be changed from 'auto'\n        this.$menu.css('min-width', '');\n        this.$newElement.css('width', this.options.width);\n      } else {\n        // Remove inline min-width/width so width can be changed\n        this.$menu.css('min-width', '');\n        this.$newElement.css('width', '');\n      }\n      // Remove fit-width class if width is changed programmatically\n      if (this.$newElement.hasClass('fit-width') && this.options.width !== 'fit') {\n        this.$newElement.removeClass('fit-width');\n      }\n    },\n\n    selectPosition: function () {\n      this.$bsContainer = $('<div class=\"bs-container\" />');\n\n      var that = this,\n          $container = $(this.options.container),\n          pos,\n          containerPos,\n          actualHeight,\n          getPlacement = function ($element) {\n            that.$bsContainer.addClass($element.attr('class').replace(/form-control|fit-width/gi, '')).toggleClass('dropup', $element.hasClass('dropup'));\n            pos = $element.offset();\n\n            if (!$container.is('body')) {\n              containerPos = $container.offset();\n              containerPos.top += parseInt($container.css('borderTopWidth')) - $container.scrollTop();\n              containerPos.left += parseInt($container.css('borderLeftWidth')) - $container.scrollLeft();\n            } else {\n              containerPos = { top: 0, left: 0 };\n            }\n\n            actualHeight = $element.hasClass('dropup') ? 0 : $element[0].offsetHeight;\n\n            that.$bsContainer.css({\n              'top': pos.top - containerPos.top + actualHeight,\n              'left': pos.left - containerPos.left,\n              'width': $element[0].offsetWidth\n            });\n          };\n\n      this.$button.on('click', function () {\n        var $this = $(this);\n\n        if (that.isDisabled()) {\n          return;\n        }\n\n        getPlacement(that.$newElement);\n\n        that.$bsContainer\n          .appendTo(that.options.container)\n          .toggleClass('open', !$this.hasClass('open'))\n          .append(that.$menu);\n      });\n\n      $(window).on('resize scroll', function () {\n        getPlacement(that.$newElement);\n      });\n\n      this.$element.on('hide.bs.select', function () {\n        that.$menu.data('height', that.$menu.height());\n        that.$bsContainer.detach();\n      });\n    },\n\n    /**\n     * @param {number} index - the index of the option that is being changed\n     * @param {boolean} selected - true if the option is being selected, false if being deselected\n     * @param {JQuery} $lis - the 'li' element that is being modified\n     */\n    setSelected: function (index, selected, $lis) {\n      if (!$lis) {\n        this.togglePlaceholder(); // check if setSelected is being called by changing the value of the select\n        $lis = this.findLis().eq(this.liObj[index]);\n      }\n\n      $lis.toggleClass('selected', selected).find('a').attr('aria-selected', selected);\n    },\n\n    /**\n     * @param {number} index - the index of the option that is being disabled\n     * @param {boolean} disabled - true if the option is being disabled, false if being enabled\n     * @param {JQuery} $lis - the 'li' element that is being modified\n     */\n    setDisabled: function (index, disabled, $lis) {\n      if (!$lis) {\n        $lis = this.findLis().eq(this.liObj[index]);\n      }\n\n      if (disabled) {\n        $lis.addClass('disabled').children('a').attr('href', '#').attr('tabindex', -1).attr('aria-disabled', true);\n      } else {\n        $lis.removeClass('disabled').children('a').removeAttr('href').attr('tabindex', 0).attr('aria-disabled', false);\n      }\n    },\n\n    isDisabled: function () {\n      return this.$element[0].disabled;\n    },\n\n    checkDisabled: function () {\n      var that = this;\n\n      if (this.isDisabled()) {\n        this.$newElement.addClass('disabled');\n        this.$button.addClass('disabled').attr('tabindex', -1).attr('aria-disabled', true);\n      } else {\n        if (this.$button.hasClass('disabled')) {\n          this.$newElement.removeClass('disabled');\n          this.$button.removeClass('disabled').attr('aria-disabled', false);\n        }\n\n        if (this.$button.attr('tabindex') == -1 && !this.$element.data('tabindex')) {\n          this.$button.removeAttr('tabindex');\n        }\n      }\n\n      this.$button.click(function () {\n        return !that.isDisabled();\n      });\n    },\n\n    togglePlaceholder: function () {\n      var value = this.$element.val();\n      this.$button.toggleClass('bs-placeholder', value === null || value === '' || (value.constructor === Array && value.length === 0));\n    },\n\n    tabIndex: function () {\n      if (this.$element.data('tabindex') !== this.$element.attr('tabindex') && \n        (this.$element.attr('tabindex') !== -98 && this.$element.attr('tabindex') !== '-98')) {\n        this.$element.data('tabindex', this.$element.attr('tabindex'));\n        this.$button.attr('tabindex', this.$element.data('tabindex'));\n      }\n\n      this.$element.attr('tabindex', -98);\n    },\n\n    clickListener: function () {\n      var that = this,\n          $document = $(document);\n\n      $document.data('spaceSelect', false);\n\n      this.$button.on('keyup', function (e) {\n        if (/(32)/.test(e.keyCode.toString(10)) && $document.data('spaceSelect')) {\n            e.preventDefault();\n            $document.data('spaceSelect', false);\n        }\n      });\n\n      this.$button.on('click', function () {\n        that.setSize();\n      });\n\n      this.$element.on('shown.bs.select', function () {\n        if (!that.options.liveSearch && !that.multiple) {\n          that.$menuInner.find('.selected a').focus();\n        } else if (!that.multiple) {\n          var selectedIndex = that.liObj[that.$element[0].selectedIndex];\n\n          if (typeof selectedIndex !== 'number' || that.options.size === false) return;\n\n          // scroll to selected option\n          var offset = that.$lis.eq(selectedIndex)[0].offsetTop - that.$menuInner[0].offsetTop;\n          offset = offset - that.$menuInner[0].offsetHeight/2 + that.sizeInfo.liHeight/2;\n          that.$menuInner[0].scrollTop = offset;\n        }\n      });\n\n      this.$menuInner.on('click', 'li a', function (e) {\n        var $this = $(this),\n            clickedIndex = $this.parent().data('originalIndex'),\n            prevValue = that.$element.val(),\n            prevIndex = that.$element.prop('selectedIndex'),\n            triggerChange = true;\n\n        // Don't close on multi choice menu\n        if (that.multiple && that.options.maxOptions !== 1) {\n          e.stopPropagation();\n        }\n\n        e.preventDefault();\n\n        //Don't run if we have been disabled\n        if (!that.isDisabled() && !$this.parent().hasClass('disabled')) {\n          var $options = that.$element.find('option'),\n              $option = $options.eq(clickedIndex),\n              state = $option.prop('selected'),\n              $optgroup = $option.parent('optgroup'),\n              maxOptions = that.options.maxOptions,\n              maxOptionsGrp = $optgroup.data('maxOptions') || false;\n\n          if (!that.multiple) { // Deselect all others if not multi select box\n            $options.prop('selected', false);\n            $option.prop('selected', true);\n            that.$menuInner.find('.selected').removeClass('selected').find('a').attr('aria-selected', false);\n            that.setSelected(clickedIndex, true);\n          } else { // Toggle the one we have chosen if we are multi select.\n            $option.prop('selected', !state);\n            that.setSelected(clickedIndex, !state);\n            $this.blur();\n\n            if (maxOptions !== false || maxOptionsGrp !== false) {\n              var maxReached = maxOptions < $options.filter(':selected').length,\n                  maxReachedGrp = maxOptionsGrp < $optgroup.find('option:selected').length;\n\n              if ((maxOptions && maxReached) || (maxOptionsGrp && maxReachedGrp)) {\n                if (maxOptions && maxOptions == 1) {\n                  $options.prop('selected', false);\n                  $option.prop('selected', true);\n                  that.$menuInner.find('.selected').removeClass('selected');\n                  that.setSelected(clickedIndex, true);\n                } else if (maxOptionsGrp && maxOptionsGrp == 1) {\n                  $optgroup.find('option:selected').prop('selected', false);\n                  $option.prop('selected', true);\n                  var optgroupID = $this.parent().data('optgroup');\n                  that.$menuInner.find('[data-optgroup=\"' + optgroupID + '\"]').removeClass('selected');\n                  that.setSelected(clickedIndex, true);\n                } else {\n                  var maxOptionsText = typeof that.options.maxOptionsText === 'string' ? [that.options.maxOptionsText, that.options.maxOptionsText] : that.options.maxOptionsText,\n                      maxOptionsArr = typeof maxOptionsText === 'function' ? maxOptionsText(maxOptions, maxOptionsGrp) : maxOptionsText,\n                      maxTxt = maxOptionsArr[0].replace('{n}', maxOptions),\n                      maxTxtGrp = maxOptionsArr[1].replace('{n}', maxOptionsGrp),\n                      $notify = $('<div class=\"notify\"></div>');\n                  // If {var} is set in array, replace it\n                  /** @deprecated */\n                  if (maxOptionsArr[2]) {\n                    maxTxt = maxTxt.replace('{var}', maxOptionsArr[2][maxOptions > 1 ? 0 : 1]);\n                    maxTxtGrp = maxTxtGrp.replace('{var}', maxOptionsArr[2][maxOptionsGrp > 1 ? 0 : 1]);\n                  }\n\n                  $option.prop('selected', false);\n\n                  that.$menu.append($notify);\n\n                  if (maxOptions && maxReached) {\n                    $notify.append($('<div>' + maxTxt + '</div>'));\n                    triggerChange = false;\n                    that.$element.trigger('maxReached.bs.select');\n                  }\n\n                  if (maxOptionsGrp && maxReachedGrp) {\n                    $notify.append($('<div>' + maxTxtGrp + '</div>'));\n                    triggerChange = false;\n                    that.$element.trigger('maxReachedGrp.bs.select');\n                  }\n\n                  setTimeout(function () {\n                    that.setSelected(clickedIndex, false);\n                  }, 10);\n\n                  $notify.delay(750).fadeOut(300, function () {\n                    $(this).remove();\n                  });\n                }\n              }\n            }\n          }\n\n          if (!that.multiple || (that.multiple && that.options.maxOptions === 1)) {\n            that.$button.focus();\n          } else if (that.options.liveSearch) {\n            that.$searchbox.focus();\n          }\n\n          // Trigger select 'change'\n          if (triggerChange) {\n            if ((prevValue != that.$element.val() && that.multiple) || (prevIndex != that.$element.prop('selectedIndex') && !that.multiple)) {\n              // $option.prop('selected') is current option state (selected/unselected). state is previous option state.\n              changed_arguments = [clickedIndex, $option.prop('selected'), state];\n              that.$element\n                .triggerNative('change');\n            }\n          }\n        }\n      });\n\n      this.$menu.on('click', 'li.disabled a, .popover-title, .popover-title :not(.close)', function (e) {\n        if (e.currentTarget == this) {\n          e.preventDefault();\n          e.stopPropagation();\n          if (that.options.liveSearch && !$(e.target).hasClass('close')) {\n            that.$searchbox.focus();\n          } else {\n            that.$button.focus();\n          }\n        }\n      });\n\n      this.$menuInner.on('click', '.divider, .dropdown-header', function (e) {\n        e.preventDefault();\n        e.stopPropagation();\n        if (that.options.liveSearch) {\n          that.$searchbox.focus();\n        } else {\n          that.$button.focus();\n        }\n      });\n\n      this.$menu.on('click', '.popover-title .close', function () {\n        that.$button.click();\n      });\n\n      this.$searchbox.on('click', function (e) {\n        e.stopPropagation();\n      });\n\n      this.$menu.on('click', '.actions-btn', function (e) {\n        if (that.options.liveSearch) {\n          that.$searchbox.focus();\n        } else {\n          that.$button.focus();\n        }\n\n        e.preventDefault();\n        e.stopPropagation();\n\n        if ($(this).hasClass('bs-select-all')) {\n          that.selectAll();\n        } else {\n          that.deselectAll();\n        }\n      });\n\n      this.$element.change(function () {\n        that.render(false);\n        that.$element.trigger('changed.bs.select', changed_arguments);\n        changed_arguments = null;\n      });\n    },\n\n    liveSearchListener: function () {\n      var that = this,\n          $no_results = $('<li class=\"no-results\"></li>');\n\n      this.$button.on('click.dropdown.data-api', function () {\n        that.$menuInner.find('.active').removeClass('active');\n        if (!!that.$searchbox.val()) {\n          that.$searchbox.val('');\n          that.$lis.not('.is-hidden').removeClass('hidden');\n          if (!!$no_results.parent().length) $no_results.remove();\n        }\n        if (!that.multiple) that.$menuInner.find('.selected').addClass('active');\n        setTimeout(function () {\n          that.$searchbox.focus();\n        }, 10);\n      });\n\n      this.$searchbox.on('click.dropdown.data-api focus.dropdown.data-api touchend.dropdown.data-api', function (e) {\n        e.stopPropagation();\n      });\n\n      this.$searchbox.on('input propertychange', function () {\n        that.$lis.not('.is-hidden').removeClass('hidden');\n        that.$lis.filter('.active').removeClass('active');\n        $no_results.remove();\n\n        if (that.$searchbox.val()) {\n          var $searchBase = that.$lis.not('.is-hidden, .divider, .dropdown-header'),\n              $hideItems;\n          if (that.options.liveSearchNormalize) {\n            $hideItems = $searchBase.find('a').not(':a' + that._searchStyle() + '(\"' + normalizeToBase(that.$searchbox.val()) + '\")');\n          } else {\n            $hideItems = $searchBase.find('a').not(':' + that._searchStyle() + '(\"' + that.$searchbox.val() + '\")');\n          }\n\n          if ($hideItems.length === $searchBase.length) {\n            $no_results.html(that.options.noneResultsText.replace('{0}', '\"' + htmlEscape(that.$searchbox.val()) + '\"'));\n            that.$menuInner.append($no_results);\n            that.$lis.addClass('hidden');\n          } else {\n            $hideItems.parent().addClass('hidden');\n\n            var $lisVisible = that.$lis.not('.hidden'),\n                $foundDiv;\n\n            // hide divider if first or last visible, or if followed by another divider\n            $lisVisible.each(function (index) {\n              var $this = $(this);\n\n              if ($this.hasClass('divider')) {\n                if ($foundDiv === undefined) {\n                  $this.addClass('hidden');\n                } else {\n                  if ($foundDiv) $foundDiv.addClass('hidden');\n                  $foundDiv = $this;\n                }\n              } else if ($this.hasClass('dropdown-header') && $lisVisible.eq(index + 1).data('optgroup') !== $this.data('optgroup')) {\n                $this.addClass('hidden');\n              } else {\n                $foundDiv = null;\n              }\n            });\n            if ($foundDiv) $foundDiv.addClass('hidden');\n\n            $searchBase.not('.hidden').first().addClass('active');\n          }\n        }\n      });\n    },\n\n    _searchStyle: function () {\n      var styles = {\n        begins: 'ibegins',\n        startsWith: 'ibegins'\n      };\n\n      return styles[this.options.liveSearchStyle] || 'icontains';\n    },\n\n    val: function (value) {\n      if (typeof value !== 'undefined') {\n        this.$element.val(value);\n        this.render();\n\n        return this.$element;\n      } else {\n        return this.$element.val();\n      }\n    },\n\n    changeAll: function (status) {\n      if (!this.multiple) return;\n      if (typeof status === 'undefined') status = true;\n\n      this.findLis();\n\n      var $options = this.$element.find('option'),\n          $lisVisible = this.$lis.not('.divider, .dropdown-header, .disabled, .hidden'),\n          lisVisLen = $lisVisible.length,\n          selectedOptions = [];\n          \n      if (status) {\n        if ($lisVisible.filter('.selected').length === $lisVisible.length) return;\n      } else {\n        if ($lisVisible.filter('.selected').length === 0) return;\n      }\n          \n      $lisVisible.toggleClass('selected', status);\n\n      for (var i = 0; i < lisVisLen; i++) {\n        var origIndex = $lisVisible[i].getAttribute('data-original-index');\n        selectedOptions[selectedOptions.length] = $options.eq(origIndex)[0];\n      }\n\n      $(selectedOptions).prop('selected', status);\n\n      this.render(false);\n\n      this.togglePlaceholder();\n\n      this.$element\n        .triggerNative('change');\n    },\n\n    selectAll: function () {\n      return this.changeAll(true);\n    },\n\n    deselectAll: function () {\n      return this.changeAll(false);\n    },\n\n    toggle: function (e) {\n      e = e || window.event;\n\n      if (e) e.stopPropagation();\n\n      this.$button.trigger('click');\n    },\n\n    keydown: function (e) {\n      var $this = $(this),\n          $parent = $this.is('input') ? $this.parent().parent() : $this.parent(),\n          $items,\n          that = $parent.data('this'),\n          index,\n          next,\n          first,\n          last,\n          prev,\n          nextPrev,\n          prevIndex,\n          isActive,\n          selector = ':not(.disabled, .hidden, .dropdown-header, .divider)',\n          keyCodeMap = {\n            32: ' ',\n            48: '0',\n            49: '1',\n            50: '2',\n            51: '3',\n            52: '4',\n            53: '5',\n            54: '6',\n            55: '7',\n            56: '8',\n            57: '9',\n            59: ';',\n            65: 'a',\n            66: 'b',\n            67: 'c',\n            68: 'd',\n            69: 'e',\n            70: 'f',\n            71: 'g',\n            72: 'h',\n            73: 'i',\n            74: 'j',\n            75: 'k',\n            76: 'l',\n            77: 'm',\n            78: 'n',\n            79: 'o',\n            80: 'p',\n            81: 'q',\n            82: 'r',\n            83: 's',\n            84: 't',\n            85: 'u',\n            86: 'v',\n            87: 'w',\n            88: 'x',\n            89: 'y',\n            90: 'z',\n            96: '0',\n            97: '1',\n            98: '2',\n            99: '3',\n            100: '4',\n            101: '5',\n            102: '6',\n            103: '7',\n            104: '8',\n            105: '9'\n          };\n\n      if (that.options.liveSearch) $parent = $this.parent().parent();\n\n      if (that.options.container) $parent = that.$menu;\n\n      $items = $('[role=\"listbox\"] li', $parent);\n\n      isActive = that.$newElement.hasClass('open');\n\n      if (!isActive && (e.keyCode >= 48 && e.keyCode <= 57 || e.keyCode >= 96 && e.keyCode <= 105 || e.keyCode >= 65 && e.keyCode <= 90)) {\n        if (!that.options.container) {\n          that.setSize();\n          that.$menu.parent().addClass('open');\n          isActive = true;\n        } else {\n          that.$button.trigger('click');\n        }\n        that.$searchbox.focus();\n        return;\n      }\n\n      if (that.options.liveSearch) {\n        if (/(^9$|27)/.test(e.keyCode.toString(10)) && isActive) {\n          e.preventDefault();\n          e.stopPropagation();\n          that.$menuInner.click();\n          that.$button.focus();\n        }\n        // $items contains li elements when liveSearch is enabled\n        $items = $('[role=\"listbox\"] li' + selector, $parent);\n        if (!$this.val() && !/(38|40)/.test(e.keyCode.toString(10))) {\n          if ($items.filter('.active').length === 0) {\n            $items = that.$menuInner.find('li');\n            if (that.options.liveSearchNormalize) {\n              $items = $items.filter(':a' + that._searchStyle() + '(' + normalizeToBase(keyCodeMap[e.keyCode]) + ')');\n            } else {\n              $items = $items.filter(':' + that._searchStyle() + '(' + keyCodeMap[e.keyCode] + ')');\n            }\n          }\n        }\n      }\n\n      if (!$items.length) return;\n\n      if (/(38|40)/.test(e.keyCode.toString(10))) {\n        index = $items.index($items.find('a').filter(':focus').parent());\n        first = $items.filter(selector).first().index();\n        last = $items.filter(selector).last().index();\n        next = $items.eq(index).nextAll(selector).eq(0).index();\n        prev = $items.eq(index).prevAll(selector).eq(0).index();\n        nextPrev = $items.eq(next).prevAll(selector).eq(0).index();\n\n        if (that.options.liveSearch) {\n          $items.each(function (i) {\n            if (!$(this).hasClass('disabled')) {\n              $(this).data('index', i);\n            }\n          });\n          index = $items.index($items.filter('.active'));\n          first = $items.first().data('index');\n          last = $items.last().data('index');\n          next = $items.eq(index).nextAll().eq(0).data('index');\n          prev = $items.eq(index).prevAll().eq(0).data('index');\n          nextPrev = $items.eq(next).prevAll().eq(0).data('index');\n        }\n\n        prevIndex = $this.data('prevIndex');\n\n        if (e.keyCode == 38) {\n          if (that.options.liveSearch) index--;\n          if (index != nextPrev && index > prev) index = prev;\n          if (index < first) index = first;\n          if (index == prevIndex) index = last;\n        } else if (e.keyCode == 40) {\n          if (that.options.liveSearch) index++;\n          if (index == -1) index = 0;\n          if (index != nextPrev && index < next) index = next;\n          if (index > last) index = last;\n          if (index == prevIndex) index = first;\n        }\n\n        $this.data('prevIndex', index);\n\n        if (!that.options.liveSearch) {\n          $items.eq(index).children('a').focus();\n        } else {\n          e.preventDefault();\n          if (!$this.hasClass('dropdown-toggle')) {\n            $items.removeClass('active').eq(index).addClass('active').children('a').focus();\n            $this.focus();\n          }\n        }\n\n      } else if (!$this.is('input')) {\n        var keyIndex = [],\n            count,\n            prevKey;\n\n        $items.each(function () {\n          if (!$(this).hasClass('disabled')) {\n            if ($.trim($(this).children('a').text().toLowerCase()).substring(0, 1) == keyCodeMap[e.keyCode]) {\n              keyIndex.push($(this).index());\n            }\n          }\n        });\n\n        count = $(document).data('keycount');\n        count++;\n        $(document).data('keycount', count);\n\n        prevKey = $.trim($(':focus').text().toLowerCase()).substring(0, 1);\n\n        if (prevKey != keyCodeMap[e.keyCode]) {\n          count = 1;\n          $(document).data('keycount', count);\n        } else if (count >= keyIndex.length) {\n          $(document).data('keycount', 0);\n          if (count > keyIndex.length) count = 1;\n        }\n\n        $items.eq(keyIndex[count - 1]).children('a').focus();\n      }\n\n      // Select focused option if \"Enter\", \"Spacebar\" or \"Tab\" (when selectOnTab is true) are pressed inside the menu.\n      if ((/(13|32)/.test(e.keyCode.toString(10)) || (/(^9$)/.test(e.keyCode.toString(10)) && that.options.selectOnTab)) && isActive) {\n        if (!/(32)/.test(e.keyCode.toString(10))) e.preventDefault();\n        if (!that.options.liveSearch) {\n          var elem = $(':focus');\n          elem.click();\n          // Bring back focus for multiselects\n          elem.focus();\n          // Prevent screen from scrolling if the user hit the spacebar\n          e.preventDefault();\n          // Fixes spacebar selection of dropdown items in FF & IE\n          $(document).data('spaceSelect', true);\n        } else if (!/(32)/.test(e.keyCode.toString(10))) {\n          that.$menuInner.find('.active a').click();\n          $this.focus();\n        }\n        $(document).data('keycount', 0);\n      }\n\n      if ((/(^9$|27)/.test(e.keyCode.toString(10)) && isActive && (that.multiple || that.options.liveSearch)) || (/(27)/.test(e.keyCode.toString(10)) && !isActive)) {\n        that.$menu.parent().removeClass('open');\n        if (that.options.container) that.$newElement.removeClass('open');\n        that.$button.focus();\n      }\n    },\n\n    mobile: function () {\n      this.$element.addClass('mobile-device');\n    },\n\n    refresh: function () {\n      this.$lis = null;\n      this.liObj = {};\n      this.reloadLi();\n      this.render();\n      this.checkDisabled();\n      this.liHeight(true);\n      this.setStyle();\n      this.setWidth();\n      if (this.$lis) this.$searchbox.trigger('propertychange');\n\n      this.$element.trigger('refreshed.bs.select');\n    },\n\n    hide: function () {\n      this.$newElement.hide();\n    },\n\n    show: function () {\n      this.$newElement.show();\n    },\n\n    remove: function () {\n      this.$newElement.remove();\n      this.$element.remove();\n    },\n\n    destroy: function () {\n      this.$newElement.before(this.$element).remove();\n\n      if (this.$bsContainer) {\n        this.$bsContainer.remove();\n      } else {\n        this.$menu.remove();\n      }\n\n      this.$element\n        .off('.bs.select')\n        .removeData('selectpicker')\n        .removeClass('bs-select-hidden selectpicker');\n    }\n  };\n\n  // SELECTPICKER PLUGIN DEFINITION\n  // ==============================\n  function Plugin(option) {\n    // get the args of the outer function..\n    var args = arguments;\n    // The arguments of the function are explicitly re-defined from the argument list, because the shift causes them\n    // to get lost/corrupted in android 2.3 and IE9 #715 #775\n    var _option = option;\n\n    [].shift.apply(args);\n\n    var value;\n    var chain = this.each(function () {\n      var $this = $(this);\n      if ($this.is('select')) {\n        var data = $this.data('selectpicker'),\n            options = typeof _option == 'object' && _option;\n\n        if (!data) {\n          var config = $.extend({}, Selectpicker.DEFAULTS, $.fn.selectpicker.defaults || {}, $this.data(), options);\n          config.template = $.extend({}, Selectpicker.DEFAULTS.template, ($.fn.selectpicker.defaults ? $.fn.selectpicker.defaults.template : {}), $this.data().template, options.template);\n          $this.data('selectpicker', (data = new Selectpicker(this, config)));\n        } else if (options) {\n          for (var i in options) {\n            if (options.hasOwnProperty(i)) {\n              data.options[i] = options[i];\n            }\n          }\n        }\n\n        if (typeof _option == 'string') {\n          if (data[_option] instanceof Function) {\n            value = data[_option].apply(data, args);\n          } else {\n            value = data.options[_option];\n          }\n        }\n      }\n    });\n\n    if (typeof value !== 'undefined') {\n      //noinspection JSUnusedAssignment\n      return value;\n    } else {\n      return chain;\n    }\n  }\n\n  var old = $.fn.selectpicker;\n  $.fn.selectpicker = Plugin;\n  $.fn.selectpicker.Constructor = Selectpicker;\n\n  // SELECTPICKER NO CONFLICT\n  // ========================\n  $.fn.selectpicker.noConflict = function () {\n    $.fn.selectpicker = old;\n    return this;\n  };\n\n  $(document)\n      .data('keycount', 0)\n      .on('keydown.bs.select', '.bootstrap-select [data-toggle=dropdown], .bootstrap-select [role=\"listbox\"], .bs-searchbox input', Selectpicker.prototype.keydown)\n      .on('focusin.modal', '.bootstrap-select [data-toggle=dropdown], .bootstrap-select [role=\"listbox\"], .bs-searchbox input', function (e) {\n        e.stopPropagation();\n      });\n\n  // SELECTPICKER DATA-API\n  // =====================\n  $(window).on('load.bs.select.data-api', function () {\n    $('.selectpicker').each(function () {\n      var $selectpicker = $(this);\n      Plugin.call($selectpicker, $selectpicker.data());\n    })\n  });\n})(jQuery);\n\n\n}));\n"
  },
  {
    "path": "app_frontend/static/js/bootstrap.js",
    "content": "/*!\n * Bootstrap v3.3.5 (http://getbootstrap.com)\n * Copyright 2011-2015 Twitter, Inc.\n * Licensed under the MIT license\n */\n\nif (typeof jQuery === 'undefined') {\n  throw new Error('Bootstrap\\'s JavaScript requires jQuery')\n}\n\n+function ($) {\n  'use strict';\n  var version = $.fn.jquery.split(' ')[0].split('.')\n  if ((version[0] < 2 && version[1] < 9) || (version[0] == 1 && version[1] == 9 && version[2] < 1)) {\n    throw new Error('Bootstrap\\'s JavaScript requires jQuery version 1.9.1 or higher')\n  }\n}(jQuery);\n\n/* ========================================================================\n * Bootstrap: transition.js v3.3.5\n * http://getbootstrap.com/javascript/#transitions\n * ========================================================================\n * Copyright 2011-2015 Twitter, Inc.\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)\n * ======================================================================== */\n\n\n+function ($) {\n  'use strict';\n\n  // CSS TRANSITION SUPPORT (Shoutout: http://www.modernizr.com/)\n  // ============================================================\n\n  function transitionEnd() {\n    var el = document.createElement('bootstrap')\n\n    var transEndEventNames = {\n      WebkitTransition : 'webkitTransitionEnd',\n      MozTransition    : 'transitionend',\n      OTransition      : 'oTransitionEnd otransitionend',\n      transition       : 'transitionend'\n    }\n\n    for (var name in transEndEventNames) {\n      if (el.style[name] !== undefined) {\n        return { end: transEndEventNames[name] }\n      }\n    }\n\n    return false // explicit for ie8 (  ._.)\n  }\n\n  // http://blog.alexmaccaw.com/css-transitions\n  $.fn.emulateTransitionEnd = function (duration) {\n    var called = false\n    var $el = this\n    $(this).one('bsTransitionEnd', function () { called = true })\n    var callback = function () { if (!called) $($el).trigger($.support.transition.end) }\n    setTimeout(callback, duration)\n    return this\n  }\n\n  $(function () {\n    $.support.transition = transitionEnd()\n\n    if (!$.support.transition) return\n\n    $.event.special.bsTransitionEnd = {\n      bindType: $.support.transition.end,\n      delegateType: $.support.transition.end,\n      handle: function (e) {\n        if ($(e.target).is(this)) return e.handleObj.handler.apply(this, arguments)\n      }\n    }\n  })\n\n}(jQuery);\n\n/* ========================================================================\n * Bootstrap: alert.js v3.3.5\n * http://getbootstrap.com/javascript/#alerts\n * ========================================================================\n * Copyright 2011-2015 Twitter, Inc.\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)\n * ======================================================================== */\n\n\n+function ($) {\n  'use strict';\n\n  // ALERT CLASS DEFINITION\n  // ======================\n\n  var dismiss = '[data-dismiss=\"alert\"]'\n  var Alert   = function (el) {\n    $(el).on('click', dismiss, this.close)\n  }\n\n  Alert.VERSION = '3.3.5'\n\n  Alert.TRANSITION_DURATION = 150\n\n  Alert.prototype.close = function (e) {\n    var $this    = $(this)\n    var selector = $this.attr('data-target')\n\n    if (!selector) {\n      selector = $this.attr('href')\n      selector = selector && selector.replace(/.*(?=#[^\\s]*$)/, '') // strip for ie7\n    }\n\n    var $parent = $(selector)\n\n    if (e) e.preventDefault()\n\n    if (!$parent.length) {\n      $parent = $this.closest('.alert')\n    }\n\n    $parent.trigger(e = $.Event('close.bs.alert'))\n\n    if (e.isDefaultPrevented()) return\n\n    $parent.removeClass('in')\n\n    function removeElement() {\n      // detach from parent, fire event then clean up data\n      $parent.detach().trigger('closed.bs.alert').remove()\n    }\n\n    $.support.transition && $parent.hasClass('fade') ?\n      $parent\n        .one('bsTransitionEnd', removeElement)\n        .emulateTransitionEnd(Alert.TRANSITION_DURATION) :\n      removeElement()\n  }\n\n\n  // ALERT PLUGIN DEFINITION\n  // =======================\n\n  function Plugin(option) {\n    return this.each(function () {\n      var $this = $(this)\n      var data  = $this.data('bs.alert')\n\n      if (!data) $this.data('bs.alert', (data = new Alert(this)))\n      if (typeof option == 'string') data[option].call($this)\n    })\n  }\n\n  var old = $.fn.alert\n\n  $.fn.alert             = Plugin\n  $.fn.alert.Constructor = Alert\n\n\n  // ALERT NO CONFLICT\n  // =================\n\n  $.fn.alert.noConflict = function () {\n    $.fn.alert = old\n    return this\n  }\n\n\n  // ALERT DATA-API\n  // ==============\n\n  $(document).on('click.bs.alert.data-api', dismiss, Alert.prototype.close)\n\n}(jQuery);\n\n/* ========================================================================\n * Bootstrap: button.js v3.3.5\n * http://getbootstrap.com/javascript/#buttons\n * ========================================================================\n * Copyright 2011-2015 Twitter, Inc.\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)\n * ======================================================================== */\n\n\n+function ($) {\n  'use strict';\n\n  // BUTTON PUBLIC CLASS DEFINITION\n  // ==============================\n\n  var Button = function (element, options) {\n    this.$element  = $(element)\n    this.options   = $.extend({}, Button.DEFAULTS, options)\n    this.isLoading = false\n  }\n\n  Button.VERSION  = '3.3.5'\n\n  Button.DEFAULTS = {\n    loadingText: 'loading...'\n  }\n\n  Button.prototype.setState = function (state) {\n    var d    = 'disabled'\n    var $el  = this.$element\n    var val  = $el.is('input') ? 'val' : 'html'\n    var data = $el.data()\n\n    state += 'Text'\n\n    if (data.resetText == null) $el.data('resetText', $el[val]())\n\n    // push to event loop to allow forms to submit\n    setTimeout($.proxy(function () {\n      $el[val](data[state] == null ? this.options[state] : data[state])\n\n      if (state == 'loadingText') {\n        this.isLoading = true\n        $el.addClass(d).attr(d, d)\n      } else if (this.isLoading) {\n        this.isLoading = false\n        $el.removeClass(d).removeAttr(d)\n      }\n    }, this), 0)\n  }\n\n  Button.prototype.toggle = function () {\n    var changed = true\n    var $parent = this.$element.closest('[data-toggle=\"buttons\"]')\n\n    if ($parent.length) {\n      var $input = this.$element.find('input')\n      if ($input.prop('type') == 'radio') {\n        if ($input.prop('checked')) changed = false\n        $parent.find('.active').removeClass('active')\n        this.$element.addClass('active')\n      } else if ($input.prop('type') == 'checkbox') {\n        if (($input.prop('checked')) !== this.$element.hasClass('active')) changed = false\n        this.$element.toggleClass('active')\n      }\n      $input.prop('checked', this.$element.hasClass('active'))\n      if (changed) $input.trigger('change')\n    } else {\n      this.$element.attr('aria-pressed', !this.$element.hasClass('active'))\n      this.$element.toggleClass('active')\n    }\n  }\n\n\n  // BUTTON PLUGIN DEFINITION\n  // ========================\n\n  function Plugin(option) {\n    return this.each(function () {\n      var $this   = $(this)\n      var data    = $this.data('bs.button')\n      var options = typeof option == 'object' && option\n\n      if (!data) $this.data('bs.button', (data = new Button(this, options)))\n\n      if (option == 'toggle') data.toggle()\n      else if (option) data.setState(option)\n    })\n  }\n\n  var old = $.fn.button\n\n  $.fn.button             = Plugin\n  $.fn.button.Constructor = Button\n\n\n  // BUTTON NO CONFLICT\n  // ==================\n\n  $.fn.button.noConflict = function () {\n    $.fn.button = old\n    return this\n  }\n\n\n  // BUTTON DATA-API\n  // ===============\n\n  $(document)\n    .on('click.bs.button.data-api', '[data-toggle^=\"button\"]', function (e) {\n      var $btn = $(e.target)\n      if (!$btn.hasClass('btn')) $btn = $btn.closest('.btn')\n      Plugin.call($btn, 'toggle')\n      if (!($(e.target).is('input[type=\"radio\"]') || $(e.target).is('input[type=\"checkbox\"]'))) e.preventDefault()\n    })\n    .on('focus.bs.button.data-api blur.bs.button.data-api', '[data-toggle^=\"button\"]', function (e) {\n      $(e.target).closest('.btn').toggleClass('focus', /^focus(in)?$/.test(e.type))\n    })\n\n}(jQuery);\n\n/* ========================================================================\n * Bootstrap: carousel.js v3.3.5\n * http://getbootstrap.com/javascript/#carousel\n * ========================================================================\n * Copyright 2011-2015 Twitter, Inc.\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)\n * ======================================================================== */\n\n\n+function ($) {\n  'use strict';\n\n  // CAROUSEL CLASS DEFINITION\n  // =========================\n\n  var Carousel = function (element, options) {\n    this.$element    = $(element)\n    this.$indicators = this.$element.find('.carousel-indicators')\n    this.options     = options\n    this.paused      = null\n    this.sliding     = null\n    this.interval    = null\n    this.$active     = null\n    this.$items      = null\n\n    this.options.keyboard && this.$element.on('keydown.bs.carousel', $.proxy(this.keydown, this))\n\n    this.options.pause == 'hover' && !('ontouchstart' in document.documentElement) && this.$element\n      .on('mouseenter.bs.carousel', $.proxy(this.pause, this))\n      .on('mouseleave.bs.carousel', $.proxy(this.cycle, this))\n  }\n\n  Carousel.VERSION  = '3.3.5'\n\n  Carousel.TRANSITION_DURATION = 600\n\n  Carousel.DEFAULTS = {\n    interval: 5000,\n    pause: 'hover',\n    wrap: true,\n    keyboard: true\n  }\n\n  Carousel.prototype.keydown = function (e) {\n    if (/input|textarea/i.test(e.target.tagName)) return\n    switch (e.which) {\n      case 37: this.prev(); break\n      case 39: this.next(); break\n      default: return\n    }\n\n    e.preventDefault()\n  }\n\n  Carousel.prototype.cycle = function (e) {\n    e || (this.paused = false)\n\n    this.interval && clearInterval(this.interval)\n\n    this.options.interval\n      && !this.paused\n      && (this.interval = setInterval($.proxy(this.next, this), this.options.interval))\n\n    return this\n  }\n\n  Carousel.prototype.getItemIndex = function (item) {\n    this.$items = item.parent().children('.item')\n    return this.$items.index(item || this.$active)\n  }\n\n  Carousel.prototype.getItemForDirection = function (direction, active) {\n    var activeIndex = this.getItemIndex(active)\n    var willWrap = (direction == 'prev' && activeIndex === 0)\n                || (direction == 'next' && activeIndex == (this.$items.length - 1))\n    if (willWrap && !this.options.wrap) return active\n    var delta = direction == 'prev' ? -1 : 1\n    var itemIndex = (activeIndex + delta) % this.$items.length\n    return this.$items.eq(itemIndex)\n  }\n\n  Carousel.prototype.to = function (pos) {\n    var that        = this\n    var activeIndex = this.getItemIndex(this.$active = this.$element.find('.item.active'))\n\n    if (pos > (this.$items.length - 1) || pos < 0) return\n\n    if (this.sliding)       return this.$element.one('slid.bs.carousel', function () { that.to(pos) }) // yes, \"slid\"\n    if (activeIndex == pos) return this.pause().cycle()\n\n    return this.slide(pos > activeIndex ? 'next' : 'prev', this.$items.eq(pos))\n  }\n\n  Carousel.prototype.pause = function (e) {\n    e || (this.paused = true)\n\n    if (this.$element.find('.next, .prev').length && $.support.transition) {\n      this.$element.trigger($.support.transition.end)\n      this.cycle(true)\n    }\n\n    this.interval = clearInterval(this.interval)\n\n    return this\n  }\n\n  Carousel.prototype.next = function () {\n    if (this.sliding) return\n    return this.slide('next')\n  }\n\n  Carousel.prototype.prev = function () {\n    if (this.sliding) return\n    return this.slide('prev')\n  }\n\n  Carousel.prototype.slide = function (type, next) {\n    var $active   = this.$element.find('.item.active')\n    var $next     = next || this.getItemForDirection(type, $active)\n    var isCycling = this.interval\n    var direction = type == 'next' ? 'left' : 'right'\n    var that      = this\n\n    if ($next.hasClass('active')) return (this.sliding = false)\n\n    var relatedTarget = $next[0]\n    var slideEvent = $.Event('slide.bs.carousel', {\n      relatedTarget: relatedTarget,\n      direction: direction\n    })\n    this.$element.trigger(slideEvent)\n    if (slideEvent.isDefaultPrevented()) return\n\n    this.sliding = true\n\n    isCycling && this.pause()\n\n    if (this.$indicators.length) {\n      this.$indicators.find('.active').removeClass('active')\n      var $nextIndicator = $(this.$indicators.children()[this.getItemIndex($next)])\n      $nextIndicator && $nextIndicator.addClass('active')\n    }\n\n    var slidEvent = $.Event('slid.bs.carousel', { relatedTarget: relatedTarget, direction: direction }) // yes, \"slid\"\n    if ($.support.transition && this.$element.hasClass('slide')) {\n      $next.addClass(type)\n      $next[0].offsetWidth // force reflow\n      $active.addClass(direction)\n      $next.addClass(direction)\n      $active\n        .one('bsTransitionEnd', function () {\n          $next.removeClass([type, direction].join(' ')).addClass('active')\n          $active.removeClass(['active', direction].join(' '))\n          that.sliding = false\n          setTimeout(function () {\n            that.$element.trigger(slidEvent)\n          }, 0)\n        })\n        .emulateTransitionEnd(Carousel.TRANSITION_DURATION)\n    } else {\n      $active.removeClass('active')\n      $next.addClass('active')\n      this.sliding = false\n      this.$element.trigger(slidEvent)\n    }\n\n    isCycling && this.cycle()\n\n    return this\n  }\n\n\n  // CAROUSEL PLUGIN DEFINITION\n  // ==========================\n\n  function Plugin(option) {\n    return this.each(function () {\n      var $this   = $(this)\n      var data    = $this.data('bs.carousel')\n      var options = $.extend({}, Carousel.DEFAULTS, $this.data(), typeof option == 'object' && option)\n      var action  = typeof option == 'string' ? option : options.slide\n\n      if (!data) $this.data('bs.carousel', (data = new Carousel(this, options)))\n      if (typeof option == 'number') data.to(option)\n      else if (action) data[action]()\n      else if (options.interval) data.pause().cycle()\n    })\n  }\n\n  var old = $.fn.carousel\n\n  $.fn.carousel             = Plugin\n  $.fn.carousel.Constructor = Carousel\n\n\n  // CAROUSEL NO CONFLICT\n  // ====================\n\n  $.fn.carousel.noConflict = function () {\n    $.fn.carousel = old\n    return this\n  }\n\n\n  // CAROUSEL DATA-API\n  // =================\n\n  var clickHandler = function (e) {\n    var href\n    var $this   = $(this)\n    var $target = $($this.attr('data-target') || (href = $this.attr('href')) && href.replace(/.*(?=#[^\\s]+$)/, '')) // strip for ie7\n    if (!$target.hasClass('carousel')) return\n    var options = $.extend({}, $target.data(), $this.data())\n    var slideIndex = $this.attr('data-slide-to')\n    if (slideIndex) options.interval = false\n\n    Plugin.call($target, options)\n\n    if (slideIndex) {\n      $target.data('bs.carousel').to(slideIndex)\n    }\n\n    e.preventDefault()\n  }\n\n  $(document)\n    .on('click.bs.carousel.data-api', '[data-slide]', clickHandler)\n    .on('click.bs.carousel.data-api', '[data-slide-to]', clickHandler)\n\n  $(window).on('load', function () {\n    $('[data-ride=\"carousel\"]').each(function () {\n      var $carousel = $(this)\n      Plugin.call($carousel, $carousel.data())\n    })\n  })\n\n}(jQuery);\n\n/* ========================================================================\n * Bootstrap: collapse.js v3.3.5\n * http://getbootstrap.com/javascript/#collapse\n * ========================================================================\n * Copyright 2011-2015 Twitter, Inc.\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)\n * ======================================================================== */\n\n\n+function ($) {\n  'use strict';\n\n  // COLLAPSE PUBLIC CLASS DEFINITION\n  // ================================\n\n  var Collapse = function (element, options) {\n    this.$element      = $(element)\n    this.options       = $.extend({}, Collapse.DEFAULTS, options)\n    this.$trigger      = $('[data-toggle=\"collapse\"][href=\"#' + element.id + '\"],' +\n                           '[data-toggle=\"collapse\"][data-target=\"#' + element.id + '\"]')\n    this.transitioning = null\n\n    if (this.options.parent) {\n      this.$parent = this.getParent()\n    } else {\n      this.addAriaAndCollapsedClass(this.$element, this.$trigger)\n    }\n\n    if (this.options.toggle) this.toggle()\n  }\n\n  Collapse.VERSION  = '3.3.5'\n\n  Collapse.TRANSITION_DURATION = 350\n\n  Collapse.DEFAULTS = {\n    toggle: true\n  }\n\n  Collapse.prototype.dimension = function () {\n    var hasWidth = this.$element.hasClass('width')\n    return hasWidth ? 'width' : 'height'\n  }\n\n  Collapse.prototype.show = function () {\n    if (this.transitioning || this.$element.hasClass('in')) return\n\n    var activesData\n    var actives = this.$parent && this.$parent.children('.panel').children('.in, .collapsing')\n\n    if (actives && actives.length) {\n      activesData = actives.data('bs.collapse')\n      if (activesData && activesData.transitioning) return\n    }\n\n    var startEvent = $.Event('show.bs.collapse')\n    this.$element.trigger(startEvent)\n    if (startEvent.isDefaultPrevented()) return\n\n    if (actives && actives.length) {\n      Plugin.call(actives, 'hide')\n      activesData || actives.data('bs.collapse', null)\n    }\n\n    var dimension = this.dimension()\n\n    this.$element\n      .removeClass('collapse')\n      .addClass('collapsing')[dimension](0)\n      .attr('aria-expanded', true)\n\n    this.$trigger\n      .removeClass('collapsed')\n      .attr('aria-expanded', true)\n\n    this.transitioning = 1\n\n    var complete = function () {\n      this.$element\n        .removeClass('collapsing')\n        .addClass('collapse in')[dimension]('')\n      this.transitioning = 0\n      this.$element\n        .trigger('shown.bs.collapse')\n    }\n\n    if (!$.support.transition) return complete.call(this)\n\n    var scrollSize = $.camelCase(['scroll', dimension].join('-'))\n\n    this.$element\n      .one('bsTransitionEnd', $.proxy(complete, this))\n      .emulateTransitionEnd(Collapse.TRANSITION_DURATION)[dimension](this.$element[0][scrollSize])\n  }\n\n  Collapse.prototype.hide = function () {\n    if (this.transitioning || !this.$element.hasClass('in')) return\n\n    var startEvent = $.Event('hide.bs.collapse')\n    this.$element.trigger(startEvent)\n    if (startEvent.isDefaultPrevented()) return\n\n    var dimension = this.dimension()\n\n    this.$element[dimension](this.$element[dimension]())[0].offsetHeight\n\n    this.$element\n      .addClass('collapsing')\n      .removeClass('collapse in')\n      .attr('aria-expanded', false)\n\n    this.$trigger\n      .addClass('collapsed')\n      .attr('aria-expanded', false)\n\n    this.transitioning = 1\n\n    var complete = function () {\n      this.transitioning = 0\n      this.$element\n        .removeClass('collapsing')\n        .addClass('collapse')\n        .trigger('hidden.bs.collapse')\n    }\n\n    if (!$.support.transition) return complete.call(this)\n\n    this.$element\n      [dimension](0)\n      .one('bsTransitionEnd', $.proxy(complete, this))\n      .emulateTransitionEnd(Collapse.TRANSITION_DURATION)\n  }\n\n  Collapse.prototype.toggle = function () {\n    this[this.$element.hasClass('in') ? 'hide' : 'show']()\n  }\n\n  Collapse.prototype.getParent = function () {\n    return $(this.options.parent)\n      .find('[data-toggle=\"collapse\"][data-parent=\"' + this.options.parent + '\"]')\n      .each($.proxy(function (i, element) {\n        var $element = $(element)\n        this.addAriaAndCollapsedClass(getTargetFromTrigger($element), $element)\n      }, this))\n      .end()\n  }\n\n  Collapse.prototype.addAriaAndCollapsedClass = function ($element, $trigger) {\n    var isOpen = $element.hasClass('in')\n\n    $element.attr('aria-expanded', isOpen)\n    $trigger\n      .toggleClass('collapsed', !isOpen)\n      .attr('aria-expanded', isOpen)\n  }\n\n  function getTargetFromTrigger($trigger) {\n    var href\n    var target = $trigger.attr('data-target')\n      || (href = $trigger.attr('href')) && href.replace(/.*(?=#[^\\s]+$)/, '') // strip for ie7\n\n    return $(target)\n  }\n\n\n  // COLLAPSE PLUGIN DEFINITION\n  // ==========================\n\n  function Plugin(option) {\n    return this.each(function () {\n      var $this   = $(this)\n      var data    = $this.data('bs.collapse')\n      var options = $.extend({}, Collapse.DEFAULTS, $this.data(), typeof option == 'object' && option)\n\n      if (!data && options.toggle && /show|hide/.test(option)) options.toggle = false\n      if (!data) $this.data('bs.collapse', (data = new Collapse(this, options)))\n      if (typeof option == 'string') data[option]()\n    })\n  }\n\n  var old = $.fn.collapse\n\n  $.fn.collapse             = Plugin\n  $.fn.collapse.Constructor = Collapse\n\n\n  // COLLAPSE NO CONFLICT\n  // ====================\n\n  $.fn.collapse.noConflict = function () {\n    $.fn.collapse = old\n    return this\n  }\n\n\n  // COLLAPSE DATA-API\n  // =================\n\n  $(document).on('click.bs.collapse.data-api', '[data-toggle=\"collapse\"]', function (e) {\n    var $this   = $(this)\n\n    if (!$this.attr('data-target')) e.preventDefault()\n\n    var $target = getTargetFromTrigger($this)\n    var data    = $target.data('bs.collapse')\n    var option  = data ? 'toggle' : $this.data()\n\n    Plugin.call($target, option)\n  })\n\n}(jQuery);\n\n/* ========================================================================\n * Bootstrap: dropdown.js v3.3.5\n * http://getbootstrap.com/javascript/#dropdowns\n * ========================================================================\n * Copyright 2011-2015 Twitter, Inc.\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)\n * ======================================================================== */\n\n\n+function ($) {\n  'use strict';\n\n  // DROPDOWN CLASS DEFINITION\n  // =========================\n\n  var backdrop = '.dropdown-backdrop'\n  var toggle   = '[data-toggle=\"dropdown\"]'\n  var Dropdown = function (element) {\n    $(element).on('click.bs.dropdown', this.toggle)\n  }\n\n  Dropdown.VERSION = '3.3.5'\n\n  function getParent($this) {\n    var selector = $this.attr('data-target')\n\n    if (!selector) {\n      selector = $this.attr('href')\n      selector = selector && /#[A-Za-z]/.test(selector) && selector.replace(/.*(?=#[^\\s]*$)/, '') // strip for ie7\n    }\n\n    var $parent = selector && $(selector)\n\n    return $parent && $parent.length ? $parent : $this.parent()\n  }\n\n  function clearMenus(e) {\n    if (e && e.which === 3) return\n    $(backdrop).remove()\n    $(toggle).each(function () {\n      var $this         = $(this)\n      var $parent       = getParent($this)\n      var relatedTarget = { relatedTarget: this }\n\n      if (!$parent.hasClass('open')) return\n\n      if (e && e.type == 'click' && /input|textarea/i.test(e.target.tagName) && $.contains($parent[0], e.target)) return\n\n      $parent.trigger(e = $.Event('hide.bs.dropdown', relatedTarget))\n\n      if (e.isDefaultPrevented()) return\n\n      $this.attr('aria-expanded', 'false')\n      $parent.removeClass('open').trigger('hidden.bs.dropdown', relatedTarget)\n    })\n  }\n\n  Dropdown.prototype.toggle = function (e) {\n    var $this = $(this)\n\n    if ($this.is('.disabled, :disabled')) return\n\n    var $parent  = getParent($this)\n    var isActive = $parent.hasClass('open')\n\n    clearMenus()\n\n    if (!isActive) {\n      if ('ontouchstart' in document.documentElement && !$parent.closest('.navbar-nav').length) {\n        // if mobile we use a backdrop because click events don't delegate\n        $(document.createElement('div'))\n          .addClass('dropdown-backdrop')\n          .insertAfter($(this))\n          .on('click', clearMenus)\n      }\n\n      var relatedTarget = { relatedTarget: this }\n      $parent.trigger(e = $.Event('show.bs.dropdown', relatedTarget))\n\n      if (e.isDefaultPrevented()) return\n\n      $this\n        .trigger('focus')\n        .attr('aria-expanded', 'true')\n\n      $parent\n        .toggleClass('open')\n        .trigger('shown.bs.dropdown', relatedTarget)\n    }\n\n    return false\n  }\n\n  Dropdown.prototype.keydown = function (e) {\n    if (!/(38|40|27|32)/.test(e.which) || /input|textarea/i.test(e.target.tagName)) return\n\n    var $this = $(this)\n\n    e.preventDefault()\n    e.stopPropagation()\n\n    if ($this.is('.disabled, :disabled')) return\n\n    var $parent  = getParent($this)\n    var isActive = $parent.hasClass('open')\n\n    if (!isActive && e.which != 27 || isActive && e.which == 27) {\n      if (e.which == 27) $parent.find(toggle).trigger('focus')\n      return $this.trigger('click')\n    }\n\n    var desc = ' li:not(.disabled):visible a'\n    var $items = $parent.find('.dropdown-menu' + desc)\n\n    if (!$items.length) return\n\n    var index = $items.index(e.target)\n\n    if (e.which == 38 && index > 0)                 index--         // up\n    if (e.which == 40 && index < $items.length - 1) index++         // down\n    if (!~index)                                    index = 0\n\n    $items.eq(index).trigger('focus')\n  }\n\n\n  // DROPDOWN PLUGIN DEFINITION\n  // ==========================\n\n  function Plugin(option) {\n    return this.each(function () {\n      var $this = $(this)\n      var data  = $this.data('bs.dropdown')\n\n      if (!data) $this.data('bs.dropdown', (data = new Dropdown(this)))\n      if (typeof option == 'string') data[option].call($this)\n    })\n  }\n\n  var old = $.fn.dropdown\n\n  $.fn.dropdown             = Plugin\n  $.fn.dropdown.Constructor = Dropdown\n\n\n  // DROPDOWN NO CONFLICT\n  // ====================\n\n  $.fn.dropdown.noConflict = function () {\n    $.fn.dropdown = old\n    return this\n  }\n\n\n  // APPLY TO STANDARD DROPDOWN ELEMENTS\n  // ===================================\n\n  $(document)\n    .on('click.bs.dropdown.data-api', clearMenus)\n    .on('click.bs.dropdown.data-api', '.dropdown form', function (e) { e.stopPropagation() })\n    .on('click.bs.dropdown.data-api', toggle, Dropdown.prototype.toggle)\n    .on('keydown.bs.dropdown.data-api', toggle, Dropdown.prototype.keydown)\n    .on('keydown.bs.dropdown.data-api', '.dropdown-menu', Dropdown.prototype.keydown)\n\n}(jQuery);\n\n/* ========================================================================\n * Bootstrap: modal.js v3.3.5\n * http://getbootstrap.com/javascript/#modals\n * ========================================================================\n * Copyright 2011-2015 Twitter, Inc.\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)\n * ======================================================================== */\n\n\n+function ($) {\n  'use strict';\n\n  // MODAL CLASS DEFINITION\n  // ======================\n\n  var Modal = function (element, options) {\n    this.options             = options\n    this.$body               = $(document.body)\n    this.$element            = $(element)\n    this.$dialog             = this.$element.find('.modal-dialog')\n    this.$backdrop           = null\n    this.isShown             = null\n    this.originalBodyPad     = null\n    this.scrollbarWidth      = 0\n    this.ignoreBackdropClick = false\n\n    if (this.options.remote) {\n      this.$element\n        .find('.modal-content')\n        .load(this.options.remote, $.proxy(function () {\n          this.$element.trigger('loaded.bs.modal')\n        }, this))\n    }\n  }\n\n  Modal.VERSION  = '3.3.5'\n\n  Modal.TRANSITION_DURATION = 300\n  Modal.BACKDROP_TRANSITION_DURATION = 150\n\n  Modal.DEFAULTS = {\n    backdrop: true,\n    keyboard: true,\n    show: true\n  }\n\n  Modal.prototype.toggle = function (_relatedTarget) {\n    return this.isShown ? this.hide() : this.show(_relatedTarget)\n  }\n\n  Modal.prototype.show = function (_relatedTarget) {\n    var that = this\n    var e    = $.Event('show.bs.modal', { relatedTarget: _relatedTarget })\n\n    this.$element.trigger(e)\n\n    if (this.isShown || e.isDefaultPrevented()) return\n\n    this.isShown = true\n\n    this.checkScrollbar()\n    this.setScrollbar()\n    this.$body.addClass('modal-open')\n\n    this.escape()\n    this.resize()\n\n    this.$element.on('click.dismiss.bs.modal', '[data-dismiss=\"modal\"]', $.proxy(this.hide, this))\n\n    this.$dialog.on('mousedown.dismiss.bs.modal', function () {\n      that.$element.one('mouseup.dismiss.bs.modal', function (e) {\n        if ($(e.target).is(that.$element)) that.ignoreBackdropClick = true\n      })\n    })\n\n    this.backdrop(function () {\n      var transition = $.support.transition && that.$element.hasClass('fade')\n\n      if (!that.$element.parent().length) {\n        that.$element.appendTo(that.$body) // don't move modals dom position\n      }\n\n      that.$element\n        .show()\n        .scrollTop(0)\n\n      that.adjustDialog()\n\n      if (transition) {\n        that.$element[0].offsetWidth // force reflow\n      }\n\n      that.$element.addClass('in')\n\n      that.enforceFocus()\n\n      var e = $.Event('shown.bs.modal', { relatedTarget: _relatedTarget })\n\n      transition ?\n        that.$dialog // wait for modal to slide in\n          .one('bsTransitionEnd', function () {\n            that.$element.trigger('focus').trigger(e)\n          })\n          .emulateTransitionEnd(Modal.TRANSITION_DURATION) :\n        that.$element.trigger('focus').trigger(e)\n    })\n  }\n\n  Modal.prototype.hide = function (e) {\n    if (e) e.preventDefault()\n\n    e = $.Event('hide.bs.modal')\n\n    this.$element.trigger(e)\n\n    if (!this.isShown || e.isDefaultPrevented()) return\n\n    this.isShown = false\n\n    this.escape()\n    this.resize()\n\n    $(document).off('focusin.bs.modal')\n\n    this.$element\n      .removeClass('in')\n      .off('click.dismiss.bs.modal')\n      .off('mouseup.dismiss.bs.modal')\n\n    this.$dialog.off('mousedown.dismiss.bs.modal')\n\n    $.support.transition && this.$element.hasClass('fade') ?\n      this.$element\n        .one('bsTransitionEnd', $.proxy(this.hideModal, this))\n        .emulateTransitionEnd(Modal.TRANSITION_DURATION) :\n      this.hideModal()\n  }\n\n  Modal.prototype.enforceFocus = function () {\n    $(document)\n      .off('focusin.bs.modal') // guard against infinite focus loop\n      .on('focusin.bs.modal', $.proxy(function (e) {\n        if (this.$element[0] !== e.target && !this.$element.has(e.target).length) {\n          this.$element.trigger('focus')\n        }\n      }, this))\n  }\n\n  Modal.prototype.escape = function () {\n    if (this.isShown && this.options.keyboard) {\n      this.$element.on('keydown.dismiss.bs.modal', $.proxy(function (e) {\n        e.which == 27 && this.hide()\n      }, this))\n    } else if (!this.isShown) {\n      this.$element.off('keydown.dismiss.bs.modal')\n    }\n  }\n\n  Modal.prototype.resize = function () {\n    if (this.isShown) {\n      $(window).on('resize.bs.modal', $.proxy(this.handleUpdate, this))\n    } else {\n      $(window).off('resize.bs.modal')\n    }\n  }\n\n  Modal.prototype.hideModal = function () {\n    var that = this\n    this.$element.hide()\n    this.backdrop(function () {\n      that.$body.removeClass('modal-open')\n      that.resetAdjustments()\n      that.resetScrollbar()\n      that.$element.trigger('hidden.bs.modal')\n    })\n  }\n\n  Modal.prototype.removeBackdrop = function () {\n    this.$backdrop && this.$backdrop.remove()\n    this.$backdrop = null\n  }\n\n  Modal.prototype.backdrop = function (callback) {\n    var that = this\n    var animate = this.$element.hasClass('fade') ? 'fade' : ''\n\n    if (this.isShown && this.options.backdrop) {\n      var doAnimate = $.support.transition && animate\n\n      this.$backdrop = $(document.createElement('div'))\n        .addClass('modal-backdrop ' + animate)\n        .appendTo(this.$body)\n\n      this.$element.on('click.dismiss.bs.modal', $.proxy(function (e) {\n        if (this.ignoreBackdropClick) {\n          this.ignoreBackdropClick = false\n          return\n        }\n        if (e.target !== e.currentTarget) return\n        this.options.backdrop == 'static'\n          ? this.$element[0].focus()\n          : this.hide()\n      }, this))\n\n      if (doAnimate) this.$backdrop[0].offsetWidth // force reflow\n\n      this.$backdrop.addClass('in')\n\n      if (!callback) return\n\n      doAnimate ?\n        this.$backdrop\n          .one('bsTransitionEnd', callback)\n          .emulateTransitionEnd(Modal.BACKDROP_TRANSITION_DURATION) :\n        callback()\n\n    } else if (!this.isShown && this.$backdrop) {\n      this.$backdrop.removeClass('in')\n\n      var callbackRemove = function () {\n        that.removeBackdrop()\n        callback && callback()\n      }\n      $.support.transition && this.$element.hasClass('fade') ?\n        this.$backdrop\n          .one('bsTransitionEnd', callbackRemove)\n          .emulateTransitionEnd(Modal.BACKDROP_TRANSITION_DURATION) :\n        callbackRemove()\n\n    } else if (callback) {\n      callback()\n    }\n  }\n\n  // these following methods are used to handle overflowing modals\n\n  Modal.prototype.handleUpdate = function () {\n    this.adjustDialog()\n  }\n\n  Modal.prototype.adjustDialog = function () {\n    var modalIsOverflowing = this.$element[0].scrollHeight > document.documentElement.clientHeight\n\n    this.$element.css({\n      paddingLeft:  !this.bodyIsOverflowing && modalIsOverflowing ? this.scrollbarWidth : '',\n      paddingRight: this.bodyIsOverflowing && !modalIsOverflowing ? this.scrollbarWidth : ''\n    })\n  }\n\n  Modal.prototype.resetAdjustments = function () {\n    this.$element.css({\n      paddingLeft: '',\n      paddingRight: ''\n    })\n  }\n\n  Modal.prototype.checkScrollbar = function () {\n    var fullWindowWidth = window.innerWidth\n    if (!fullWindowWidth) { // workaround for missing window.innerWidth in IE8\n      var documentElementRect = document.documentElement.getBoundingClientRect()\n      fullWindowWidth = documentElementRect.right - Math.abs(documentElementRect.left)\n    }\n    this.bodyIsOverflowing = document.body.clientWidth < fullWindowWidth\n    this.scrollbarWidth = this.measureScrollbar()\n  }\n\n  Modal.prototype.setScrollbar = function () {\n    var bodyPad = parseInt((this.$body.css('padding-right') || 0), 10)\n    this.originalBodyPad = document.body.style.paddingRight || ''\n    if (this.bodyIsOverflowing) this.$body.css('padding-right', bodyPad + this.scrollbarWidth)\n  }\n\n  Modal.prototype.resetScrollbar = function () {\n    this.$body.css('padding-right', this.originalBodyPad)\n  }\n\n  Modal.prototype.measureScrollbar = function () { // thx walsh\n    var scrollDiv = document.createElement('div')\n    scrollDiv.className = 'modal-scrollbar-measure'\n    this.$body.append(scrollDiv)\n    var scrollbarWidth = scrollDiv.offsetWidth - scrollDiv.clientWidth\n    this.$body[0].removeChild(scrollDiv)\n    return scrollbarWidth\n  }\n\n\n  // MODAL PLUGIN DEFINITION\n  // =======================\n\n  function Plugin(option, _relatedTarget) {\n    return this.each(function () {\n      var $this   = $(this)\n      var data    = $this.data('bs.modal')\n      var options = $.extend({}, Modal.DEFAULTS, $this.data(), typeof option == 'object' && option)\n\n      if (!data) $this.data('bs.modal', (data = new Modal(this, options)))\n      if (typeof option == 'string') data[option](_relatedTarget)\n      else if (options.show) data.show(_relatedTarget)\n    })\n  }\n\n  var old = $.fn.modal\n\n  $.fn.modal             = Plugin\n  $.fn.modal.Constructor = Modal\n\n\n  // MODAL NO CONFLICT\n  // =================\n\n  $.fn.modal.noConflict = function () {\n    $.fn.modal = old\n    return this\n  }\n\n\n  // MODAL DATA-API\n  // ==============\n\n  $(document).on('click.bs.modal.data-api', '[data-toggle=\"modal\"]', function (e) {\n    var $this   = $(this)\n    var href    = $this.attr('href')\n    var $target = $($this.attr('data-target') || (href && href.replace(/.*(?=#[^\\s]+$)/, ''))) // strip for ie7\n    var option  = $target.data('bs.modal') ? 'toggle' : $.extend({ remote: !/#/.test(href) && href }, $target.data(), $this.data())\n\n    if ($this.is('a')) e.preventDefault()\n\n    $target.one('show.bs.modal', function (showEvent) {\n      if (showEvent.isDefaultPrevented()) return // only register focus restorer if modal will actually get shown\n      $target.one('hidden.bs.modal', function () {\n        $this.is(':visible') && $this.trigger('focus')\n      })\n    })\n    Plugin.call($target, option, this)\n  })\n\n}(jQuery);\n\n/* ========================================================================\n * Bootstrap: tooltip.js v3.3.5\n * http://getbootstrap.com/javascript/#tooltip\n * Inspired by the original jQuery.tipsy by Jason Frame\n * ========================================================================\n * Copyright 2011-2015 Twitter, Inc.\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)\n * ======================================================================== */\n\n\n+function ($) {\n  'use strict';\n\n  // TOOLTIP PUBLIC CLASS DEFINITION\n  // ===============================\n\n  var Tooltip = function (element, options) {\n    this.type       = null\n    this.options    = null\n    this.enabled    = null\n    this.timeout    = null\n    this.hoverState = null\n    this.$element   = null\n    this.inState    = null\n\n    this.init('tooltip', element, options)\n  }\n\n  Tooltip.VERSION  = '3.3.5'\n\n  Tooltip.TRANSITION_DURATION = 150\n\n  Tooltip.DEFAULTS = {\n    animation: true,\n    placement: 'top',\n    selector: false,\n    template: '<div class=\"tooltip\" role=\"tooltip\"><div class=\"tooltip-arrow\"></div><div class=\"tooltip-inner\"></div></div>',\n    trigger: 'hover focus',\n    title: '',\n    delay: 0,\n    html: false,\n    container: false,\n    viewport: {\n      selector: 'body',\n      padding: 0\n    }\n  }\n\n  Tooltip.prototype.init = function (type, element, options) {\n    this.enabled   = true\n    this.type      = type\n    this.$element  = $(element)\n    this.options   = this.getOptions(options)\n    this.$viewport = this.options.viewport && $($.isFunction(this.options.viewport) ? this.options.viewport.call(this, this.$element) : (this.options.viewport.selector || this.options.viewport))\n    this.inState   = { click: false, hover: false, focus: false }\n\n    if (this.$element[0] instanceof document.constructor && !this.options.selector) {\n      throw new Error('`selector` option must be specified when initializing ' + this.type + ' on the window.document object!')\n    }\n\n    var triggers = this.options.trigger.split(' ')\n\n    for (var i = triggers.length; i--;) {\n      var trigger = triggers[i]\n\n      if (trigger == 'click') {\n        this.$element.on('click.' + this.type, this.options.selector, $.proxy(this.toggle, this))\n      } else if (trigger != 'manual') {\n        var eventIn  = trigger == 'hover' ? 'mouseenter' : 'focusin'\n        var eventOut = trigger == 'hover' ? 'mouseleave' : 'focusout'\n\n        this.$element.on(eventIn  + '.' + this.type, this.options.selector, $.proxy(this.enter, this))\n        this.$element.on(eventOut + '.' + this.type, this.options.selector, $.proxy(this.leave, this))\n      }\n    }\n\n    this.options.selector ?\n      (this._options = $.extend({}, this.options, { trigger: 'manual', selector: '' })) :\n      this.fixTitle()\n  }\n\n  Tooltip.prototype.getDefaults = function () {\n    return Tooltip.DEFAULTS\n  }\n\n  Tooltip.prototype.getOptions = function (options) {\n    options = $.extend({}, this.getDefaults(), this.$element.data(), options)\n\n    if (options.delay && typeof options.delay == 'number') {\n      options.delay = {\n        show: options.delay,\n        hide: options.delay\n      }\n    }\n\n    return options\n  }\n\n  Tooltip.prototype.getDelegateOptions = function () {\n    var options  = {}\n    var defaults = this.getDefaults()\n\n    this._options && $.each(this._options, function (key, value) {\n      if (defaults[key] != value) options[key] = value\n    })\n\n    return options\n  }\n\n  Tooltip.prototype.enter = function (obj) {\n    var self = obj instanceof this.constructor ?\n      obj : $(obj.currentTarget).data('bs.' + this.type)\n\n    if (!self) {\n      self = new this.constructor(obj.currentTarget, this.getDelegateOptions())\n      $(obj.currentTarget).data('bs.' + this.type, self)\n    }\n\n    if (obj instanceof $.Event) {\n      self.inState[obj.type == 'focusin' ? 'focus' : 'hover'] = true\n    }\n\n    if (self.tip().hasClass('in') || self.hoverState == 'in') {\n      self.hoverState = 'in'\n      return\n    }\n\n    clearTimeout(self.timeout)\n\n    self.hoverState = 'in'\n\n    if (!self.options.delay || !self.options.delay.show) return self.show()\n\n    self.timeout = setTimeout(function () {\n      if (self.hoverState == 'in') self.show()\n    }, self.options.delay.show)\n  }\n\n  Tooltip.prototype.isInStateTrue = function () {\n    for (var key in this.inState) {\n      if (this.inState[key]) return true\n    }\n\n    return false\n  }\n\n  Tooltip.prototype.leave = function (obj) {\n    var self = obj instanceof this.constructor ?\n      obj : $(obj.currentTarget).data('bs.' + this.type)\n\n    if (!self) {\n      self = new this.constructor(obj.currentTarget, this.getDelegateOptions())\n      $(obj.currentTarget).data('bs.' + this.type, self)\n    }\n\n    if (obj instanceof $.Event) {\n      self.inState[obj.type == 'focusout' ? 'focus' : 'hover'] = false\n    }\n\n    if (self.isInStateTrue()) return\n\n    clearTimeout(self.timeout)\n\n    self.hoverState = 'out'\n\n    if (!self.options.delay || !self.options.delay.hide) return self.hide()\n\n    self.timeout = setTimeout(function () {\n      if (self.hoverState == 'out') self.hide()\n    }, self.options.delay.hide)\n  }\n\n  Tooltip.prototype.show = function () {\n    var e = $.Event('show.bs.' + this.type)\n\n    if (this.hasContent() && this.enabled) {\n      this.$element.trigger(e)\n\n      var inDom = $.contains(this.$element[0].ownerDocument.documentElement, this.$element[0])\n      if (e.isDefaultPrevented() || !inDom) return\n      var that = this\n\n      var $tip = this.tip()\n\n      var tipId = this.getUID(this.type)\n\n      this.setContent()\n      $tip.attr('id', tipId)\n      this.$element.attr('aria-describedby', tipId)\n\n      if (this.options.animation) $tip.addClass('fade')\n\n      var placement = typeof this.options.placement == 'function' ?\n        this.options.placement.call(this, $tip[0], this.$element[0]) :\n        this.options.placement\n\n      var autoToken = /\\s?auto?\\s?/i\n      var autoPlace = autoToken.test(placement)\n      if (autoPlace) placement = placement.replace(autoToken, '') || 'top'\n\n      $tip\n        .detach()\n        .css({ top: 0, left: 0, display: 'block' })\n        .addClass(placement)\n        .data('bs.' + this.type, this)\n\n      this.options.container ? $tip.appendTo(this.options.container) : $tip.insertAfter(this.$element)\n      this.$element.trigger('inserted.bs.' + this.type)\n\n      var pos          = this.getPosition()\n      var actualWidth  = $tip[0].offsetWidth\n      var actualHeight = $tip[0].offsetHeight\n\n      if (autoPlace) {\n        var orgPlacement = placement\n        var viewportDim = this.getPosition(this.$viewport)\n\n        placement = placement == 'bottom' && pos.bottom + actualHeight > viewportDim.bottom ? 'top'    :\n                    placement == 'top'    && pos.top    - actualHeight < viewportDim.top    ? 'bottom' :\n                    placement == 'right'  && pos.right  + actualWidth  > viewportDim.width  ? 'left'   :\n                    placement == 'left'   && pos.left   - actualWidth  < viewportDim.left   ? 'right'  :\n                    placement\n\n        $tip\n          .removeClass(orgPlacement)\n          .addClass(placement)\n      }\n\n      var calculatedOffset = this.getCalculatedOffset(placement, pos, actualWidth, actualHeight)\n\n      this.applyPlacement(calculatedOffset, placement)\n\n      var complete = function () {\n        var prevHoverState = that.hoverState\n        that.$element.trigger('shown.bs.' + that.type)\n        that.hoverState = null\n\n        if (prevHoverState == 'out') that.leave(that)\n      }\n\n      $.support.transition && this.$tip.hasClass('fade') ?\n        $tip\n          .one('bsTransitionEnd', complete)\n          .emulateTransitionEnd(Tooltip.TRANSITION_DURATION) :\n        complete()\n    }\n  }\n\n  Tooltip.prototype.applyPlacement = function (offset, placement) {\n    var $tip   = this.tip()\n    var width  = $tip[0].offsetWidth\n    var height = $tip[0].offsetHeight\n\n    // manually read margins because getBoundingClientRect includes difference\n    var marginTop = parseInt($tip.css('margin-top'), 10)\n    var marginLeft = parseInt($tip.css('margin-left'), 10)\n\n    // we must check for NaN for ie 8/9\n    if (isNaN(marginTop))  marginTop  = 0\n    if (isNaN(marginLeft)) marginLeft = 0\n\n    offset.top  += marginTop\n    offset.left += marginLeft\n\n    // $.fn.offset doesn't round pixel values\n    // so we use setOffset directly with our own function B-0\n    $.offset.setOffset($tip[0], $.extend({\n      using: function (props) {\n        $tip.css({\n          top: Math.round(props.top),\n          left: Math.round(props.left)\n        })\n      }\n    }, offset), 0)\n\n    $tip.addClass('in')\n\n    // check to see if placing tip in new offset caused the tip to resize itself\n    var actualWidth  = $tip[0].offsetWidth\n    var actualHeight = $tip[0].offsetHeight\n\n    if (placement == 'top' && actualHeight != height) {\n      offset.top = offset.top + height - actualHeight\n    }\n\n    var delta = this.getViewportAdjustedDelta(placement, offset, actualWidth, actualHeight)\n\n    if (delta.left) offset.left += delta.left\n    else offset.top += delta.top\n\n    var isVertical          = /top|bottom/.test(placement)\n    var arrowDelta          = isVertical ? delta.left * 2 - width + actualWidth : delta.top * 2 - height + actualHeight\n    var arrowOffsetPosition = isVertical ? 'offsetWidth' : 'offsetHeight'\n\n    $tip.offset(offset)\n    this.replaceArrow(arrowDelta, $tip[0][arrowOffsetPosition], isVertical)\n  }\n\n  Tooltip.prototype.replaceArrow = function (delta, dimension, isVertical) {\n    this.arrow()\n      .css(isVertical ? 'left' : 'top', 50 * (1 - delta / dimension) + '%')\n      .css(isVertical ? 'top' : 'left', '')\n  }\n\n  Tooltip.prototype.setContent = function () {\n    var $tip  = this.tip()\n    var title = this.getTitle()\n\n    $tip.find('.tooltip-inner')[this.options.html ? 'html' : 'text'](title)\n    $tip.removeClass('fade in top bottom left right')\n  }\n\n  Tooltip.prototype.hide = function (callback) {\n    var that = this\n    var $tip = $(this.$tip)\n    var e    = $.Event('hide.bs.' + this.type)\n\n    function complete() {\n      if (that.hoverState != 'in') $tip.detach()\n      that.$element\n        .removeAttr('aria-describedby')\n        .trigger('hidden.bs.' + that.type)\n      callback && callback()\n    }\n\n    this.$element.trigger(e)\n\n    if (e.isDefaultPrevented()) return\n\n    $tip.removeClass('in')\n\n    $.support.transition && $tip.hasClass('fade') ?\n      $tip\n        .one('bsTransitionEnd', complete)\n        .emulateTransitionEnd(Tooltip.TRANSITION_DURATION) :\n      complete()\n\n    this.hoverState = null\n\n    return this\n  }\n\n  Tooltip.prototype.fixTitle = function () {\n    var $e = this.$element\n    if ($e.attr('title') || typeof $e.attr('data-original-title') != 'string') {\n      $e.attr('data-original-title', $e.attr('title') || '').attr('title', '')\n    }\n  }\n\n  Tooltip.prototype.hasContent = function () {\n    return this.getTitle()\n  }\n\n  Tooltip.prototype.getPosition = function ($element) {\n    $element   = $element || this.$element\n\n    var el     = $element[0]\n    var isBody = el.tagName == 'BODY'\n\n    var elRect    = el.getBoundingClientRect()\n    if (elRect.width == null) {\n      // width and height are missing in IE8, so compute them manually; see https://github.com/twbs/bootstrap/issues/14093\n      elRect = $.extend({}, elRect, { width: elRect.right - elRect.left, height: elRect.bottom - elRect.top })\n    }\n    var elOffset  = isBody ? { top: 0, left: 0 } : $element.offset()\n    var scroll    = { scroll: isBody ? document.documentElement.scrollTop || document.body.scrollTop : $element.scrollTop() }\n    var outerDims = isBody ? { width: $(window).width(), height: $(window).height() } : null\n\n    return $.extend({}, elRect, scroll, outerDims, elOffset)\n  }\n\n  Tooltip.prototype.getCalculatedOffset = function (placement, pos, actualWidth, actualHeight) {\n    return placement == 'bottom' ? { top: pos.top + pos.height,   left: pos.left + pos.width / 2 - actualWidth / 2 } :\n           placement == 'top'    ? { top: pos.top - actualHeight, left: pos.left + pos.width / 2 - actualWidth / 2 } :\n           placement == 'left'   ? { top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left - actualWidth } :\n        /* placement == 'right' */ { top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left + pos.width }\n\n  }\n\n  Tooltip.prototype.getViewportAdjustedDelta = function (placement, pos, actualWidth, actualHeight) {\n    var delta = { top: 0, left: 0 }\n    if (!this.$viewport) return delta\n\n    var viewportPadding = this.options.viewport && this.options.viewport.padding || 0\n    var viewportDimensions = this.getPosition(this.$viewport)\n\n    if (/right|left/.test(placement)) {\n      var topEdgeOffset    = pos.top - viewportPadding - viewportDimensions.scroll\n      var bottomEdgeOffset = pos.top + viewportPadding - viewportDimensions.scroll + actualHeight\n      if (topEdgeOffset < viewportDimensions.top) { // top overflow\n        delta.top = viewportDimensions.top - topEdgeOffset\n      } else if (bottomEdgeOffset > viewportDimensions.top + viewportDimensions.height) { // bottom overflow\n        delta.top = viewportDimensions.top + viewportDimensions.height - bottomEdgeOffset\n      }\n    } else {\n      var leftEdgeOffset  = pos.left - viewportPadding\n      var rightEdgeOffset = pos.left + viewportPadding + actualWidth\n      if (leftEdgeOffset < viewportDimensions.left) { // left overflow\n        delta.left = viewportDimensions.left - leftEdgeOffset\n      } else if (rightEdgeOffset > viewportDimensions.right) { // right overflow\n        delta.left = viewportDimensions.left + viewportDimensions.width - rightEdgeOffset\n      }\n    }\n\n    return delta\n  }\n\n  Tooltip.prototype.getTitle = function () {\n    var title\n    var $e = this.$element\n    var o  = this.options\n\n    title = $e.attr('data-original-title')\n      || (typeof o.title == 'function' ? o.title.call($e[0]) :  o.title)\n\n    return title\n  }\n\n  Tooltip.prototype.getUID = function (prefix) {\n    do prefix += ~~(Math.random() * 1000000)\n    while (document.getElementById(prefix))\n    return prefix\n  }\n\n  Tooltip.prototype.tip = function () {\n    if (!this.$tip) {\n      this.$tip = $(this.options.template)\n      if (this.$tip.length != 1) {\n        throw new Error(this.type + ' `template` option must consist of exactly 1 top-level element!')\n      }\n    }\n    return this.$tip\n  }\n\n  Tooltip.prototype.arrow = function () {\n    return (this.$arrow = this.$arrow || this.tip().find('.tooltip-arrow'))\n  }\n\n  Tooltip.prototype.enable = function () {\n    this.enabled = true\n  }\n\n  Tooltip.prototype.disable = function () {\n    this.enabled = false\n  }\n\n  Tooltip.prototype.toggleEnabled = function () {\n    this.enabled = !this.enabled\n  }\n\n  Tooltip.prototype.toggle = function (e) {\n    var self = this\n    if (e) {\n      self = $(e.currentTarget).data('bs.' + this.type)\n      if (!self) {\n        self = new this.constructor(e.currentTarget, this.getDelegateOptions())\n        $(e.currentTarget).data('bs.' + this.type, self)\n      }\n    }\n\n    if (e) {\n      self.inState.click = !self.inState.click\n      if (self.isInStateTrue()) self.enter(self)\n      else self.leave(self)\n    } else {\n      self.tip().hasClass('in') ? self.leave(self) : self.enter(self)\n    }\n  }\n\n  Tooltip.prototype.destroy = function () {\n    var that = this\n    clearTimeout(this.timeout)\n    this.hide(function () {\n      that.$element.off('.' + that.type).removeData('bs.' + that.type)\n      if (that.$tip) {\n        that.$tip.detach()\n      }\n      that.$tip = null\n      that.$arrow = null\n      that.$viewport = null\n    })\n  }\n\n\n  // TOOLTIP PLUGIN DEFINITION\n  // =========================\n\n  function Plugin(option) {\n    return this.each(function () {\n      var $this   = $(this)\n      var data    = $this.data('bs.tooltip')\n      var options = typeof option == 'object' && option\n\n      if (!data && /destroy|hide/.test(option)) return\n      if (!data) $this.data('bs.tooltip', (data = new Tooltip(this, options)))\n      if (typeof option == 'string') data[option]()\n    })\n  }\n\n  var old = $.fn.tooltip\n\n  $.fn.tooltip             = Plugin\n  $.fn.tooltip.Constructor = Tooltip\n\n\n  // TOOLTIP NO CONFLICT\n  // ===================\n\n  $.fn.tooltip.noConflict = function () {\n    $.fn.tooltip = old\n    return this\n  }\n\n}(jQuery);\n\n/* ========================================================================\n * Bootstrap: popover.js v3.3.5\n * http://getbootstrap.com/javascript/#popovers\n * ========================================================================\n * Copyright 2011-2015 Twitter, Inc.\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)\n * ======================================================================== */\n\n\n+function ($) {\n  'use strict';\n\n  // POPOVER PUBLIC CLASS DEFINITION\n  // ===============================\n\n  var Popover = function (element, options) {\n    this.init('popover', element, options)\n  }\n\n  if (!$.fn.tooltip) throw new Error('Popover requires tooltip.js')\n\n  Popover.VERSION  = '3.3.5'\n\n  Popover.DEFAULTS = $.extend({}, $.fn.tooltip.Constructor.DEFAULTS, {\n    placement: 'right',\n    trigger: 'click',\n    content: '',\n    template: '<div class=\"popover\" role=\"tooltip\"><div class=\"arrow\"></div><h3 class=\"popover-title\"></h3><div class=\"popover-content\"></div></div>'\n  })\n\n\n  // NOTE: POPOVER EXTENDS tooltip.js\n  // ================================\n\n  Popover.prototype = $.extend({}, $.fn.tooltip.Constructor.prototype)\n\n  Popover.prototype.constructor = Popover\n\n  Popover.prototype.getDefaults = function () {\n    return Popover.DEFAULTS\n  }\n\n  Popover.prototype.setContent = function () {\n    var $tip    = this.tip()\n    var title   = this.getTitle()\n    var content = this.getContent()\n\n    $tip.find('.popover-title')[this.options.html ? 'html' : 'text'](title)\n    $tip.find('.popover-content').children().detach().end()[ // we use append for html objects to maintain js events\n      this.options.html ? (typeof content == 'string' ? 'html' : 'append') : 'text'\n    ](content)\n\n    $tip.removeClass('fade top bottom left right in')\n\n    // IE8 doesn't accept hiding via the `:empty` pseudo selector, we have to do\n    // this manually by checking the contents.\n    if (!$tip.find('.popover-title').html()) $tip.find('.popover-title').hide()\n  }\n\n  Popover.prototype.hasContent = function () {\n    return this.getTitle() || this.getContent()\n  }\n\n  Popover.prototype.getContent = function () {\n    var $e = this.$element\n    var o  = this.options\n\n    return $e.attr('data-content')\n      || (typeof o.content == 'function' ?\n            o.content.call($e[0]) :\n            o.content)\n  }\n\n  Popover.prototype.arrow = function () {\n    return (this.$arrow = this.$arrow || this.tip().find('.arrow'))\n  }\n\n\n  // POPOVER PLUGIN DEFINITION\n  // =========================\n\n  function Plugin(option) {\n    return this.each(function () {\n      var $this   = $(this)\n      var data    = $this.data('bs.popover')\n      var options = typeof option == 'object' && option\n\n      if (!data && /destroy|hide/.test(option)) return\n      if (!data) $this.data('bs.popover', (data = new Popover(this, options)))\n      if (typeof option == 'string') data[option]()\n    })\n  }\n\n  var old = $.fn.popover\n\n  $.fn.popover             = Plugin\n  $.fn.popover.Constructor = Popover\n\n\n  // POPOVER NO CONFLICT\n  // ===================\n\n  $.fn.popover.noConflict = function () {\n    $.fn.popover = old\n    return this\n  }\n\n}(jQuery);\n\n/* ========================================================================\n * Bootstrap: scrollspy.js v3.3.5\n * http://getbootstrap.com/javascript/#scrollspy\n * ========================================================================\n * Copyright 2011-2015 Twitter, Inc.\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)\n * ======================================================================== */\n\n\n+function ($) {\n  'use strict';\n\n  // SCROLLSPY CLASS DEFINITION\n  // ==========================\n\n  function ScrollSpy(element, options) {\n    this.$body          = $(document.body)\n    this.$scrollElement = $(element).is(document.body) ? $(window) : $(element)\n    this.options        = $.extend({}, ScrollSpy.DEFAULTS, options)\n    this.selector       = (this.options.target || '') + ' .nav li > a'\n    this.offsets        = []\n    this.targets        = []\n    this.activeTarget   = null\n    this.scrollHeight   = 0\n\n    this.$scrollElement.on('scroll.bs.scrollspy', $.proxy(this.process, this))\n    this.refresh()\n    this.process()\n  }\n\n  ScrollSpy.VERSION  = '3.3.5'\n\n  ScrollSpy.DEFAULTS = {\n    offset: 10\n  }\n\n  ScrollSpy.prototype.getScrollHeight = function () {\n    return this.$scrollElement[0].scrollHeight || Math.max(this.$body[0].scrollHeight, document.documentElement.scrollHeight)\n  }\n\n  ScrollSpy.prototype.refresh = function () {\n    var that          = this\n    var offsetMethod  = 'offset'\n    var offsetBase    = 0\n\n    this.offsets      = []\n    this.targets      = []\n    this.scrollHeight = this.getScrollHeight()\n\n    if (!$.isWindow(this.$scrollElement[0])) {\n      offsetMethod = 'position'\n      offsetBase   = this.$scrollElement.scrollTop()\n    }\n\n    this.$body\n      .find(this.selector)\n      .map(function () {\n        var $el   = $(this)\n        var href  = $el.data('target') || $el.attr('href')\n        var $href = /^#./.test(href) && $(href)\n\n        return ($href\n          && $href.length\n          && $href.is(':visible')\n          && [[$href[offsetMethod]().top + offsetBase, href]]) || null\n      })\n      .sort(function (a, b) { return a[0] - b[0] })\n      .each(function () {\n        that.offsets.push(this[0])\n        that.targets.push(this[1])\n      })\n  }\n\n  ScrollSpy.prototype.process = function () {\n    var scrollTop    = this.$scrollElement.scrollTop() + this.options.offset\n    var scrollHeight = this.getScrollHeight()\n    var maxScroll    = this.options.offset + scrollHeight - this.$scrollElement.height()\n    var offsets      = this.offsets\n    var targets      = this.targets\n    var activeTarget = this.activeTarget\n    var i\n\n    if (this.scrollHeight != scrollHeight) {\n      this.refresh()\n    }\n\n    if (scrollTop >= maxScroll) {\n      return activeTarget != (i = targets[targets.length - 1]) && this.activate(i)\n    }\n\n    if (activeTarget && scrollTop < offsets[0]) {\n      this.activeTarget = null\n      return this.clear()\n    }\n\n    for (i = offsets.length; i--;) {\n      activeTarget != targets[i]\n        && scrollTop >= offsets[i]\n        && (offsets[i + 1] === undefined || scrollTop < offsets[i + 1])\n        && this.activate(targets[i])\n    }\n  }\n\n  ScrollSpy.prototype.activate = function (target) {\n    this.activeTarget = target\n\n    this.clear()\n\n    var selector = this.selector +\n      '[data-target=\"' + target + '\"],' +\n      this.selector + '[href=\"' + target + '\"]'\n\n    var active = $(selector)\n      .parents('li')\n      .addClass('active')\n\n    if (active.parent('.dropdown-menu').length) {\n      active = active\n        .closest('li.dropdown')\n        .addClass('active')\n    }\n\n    active.trigger('activate.bs.scrollspy')\n  }\n\n  ScrollSpy.prototype.clear = function () {\n    $(this.selector)\n      .parentsUntil(this.options.target, '.active')\n      .removeClass('active')\n  }\n\n\n  // SCROLLSPY PLUGIN DEFINITION\n  // ===========================\n\n  function Plugin(option) {\n    return this.each(function () {\n      var $this   = $(this)\n      var data    = $this.data('bs.scrollspy')\n      var options = typeof option == 'object' && option\n\n      if (!data) $this.data('bs.scrollspy', (data = new ScrollSpy(this, options)))\n      if (typeof option == 'string') data[option]()\n    })\n  }\n\n  var old = $.fn.scrollspy\n\n  $.fn.scrollspy             = Plugin\n  $.fn.scrollspy.Constructor = ScrollSpy\n\n\n  // SCROLLSPY NO CONFLICT\n  // =====================\n\n  $.fn.scrollspy.noConflict = function () {\n    $.fn.scrollspy = old\n    return this\n  }\n\n\n  // SCROLLSPY DATA-API\n  // ==================\n\n  $(window).on('load.bs.scrollspy.data-api', function () {\n    $('[data-spy=\"scroll\"]').each(function () {\n      var $spy = $(this)\n      Plugin.call($spy, $spy.data())\n    })\n  })\n\n}(jQuery);\n\n/* ========================================================================\n * Bootstrap: tab.js v3.3.5\n * http://getbootstrap.com/javascript/#tabs\n * ========================================================================\n * Copyright 2011-2015 Twitter, Inc.\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)\n * ======================================================================== */\n\n\n+function ($) {\n  'use strict';\n\n  // TAB CLASS DEFINITION\n  // ====================\n\n  var Tab = function (element) {\n    // jscs:disable requireDollarBeforejQueryAssignment\n    this.element = $(element)\n    // jscs:enable requireDollarBeforejQueryAssignment\n  }\n\n  Tab.VERSION = '3.3.5'\n\n  Tab.TRANSITION_DURATION = 150\n\n  Tab.prototype.show = function () {\n    var $this    = this.element\n    var $ul      = $this.closest('ul:not(.dropdown-menu)')\n    var selector = $this.data('target')\n\n    if (!selector) {\n      selector = $this.attr('href')\n      selector = selector && selector.replace(/.*(?=#[^\\s]*$)/, '') // strip for ie7\n    }\n\n    if ($this.parent('li').hasClass('active')) return\n\n    var $previous = $ul.find('.active:last a')\n    var hideEvent = $.Event('hide.bs.tab', {\n      relatedTarget: $this[0]\n    })\n    var showEvent = $.Event('show.bs.tab', {\n      relatedTarget: $previous[0]\n    })\n\n    $previous.trigger(hideEvent)\n    $this.trigger(showEvent)\n\n    if (showEvent.isDefaultPrevented() || hideEvent.isDefaultPrevented()) return\n\n    var $target = $(selector)\n\n    this.activate($this.closest('li'), $ul)\n    this.activate($target, $target.parent(), function () {\n      $previous.trigger({\n        type: 'hidden.bs.tab',\n        relatedTarget: $this[0]\n      })\n      $this.trigger({\n        type: 'shown.bs.tab',\n        relatedTarget: $previous[0]\n      })\n    })\n  }\n\n  Tab.prototype.activate = function (element, container, callback) {\n    var $active    = container.find('> .active')\n    var transition = callback\n      && $.support.transition\n      && ($active.length && $active.hasClass('fade') || !!container.find('> .fade').length)\n\n    function next() {\n      $active\n        .removeClass('active')\n        .find('> .dropdown-menu > .active')\n          .removeClass('active')\n        .end()\n        .find('[data-toggle=\"tab\"]')\n          .attr('aria-expanded', false)\n\n      element\n        .addClass('active')\n        .find('[data-toggle=\"tab\"]')\n          .attr('aria-expanded', true)\n\n      if (transition) {\n        element[0].offsetWidth // reflow for transition\n        element.addClass('in')\n      } else {\n        element.removeClass('fade')\n      }\n\n      if (element.parent('.dropdown-menu').length) {\n        element\n          .closest('li.dropdown')\n            .addClass('active')\n          .end()\n          .find('[data-toggle=\"tab\"]')\n            .attr('aria-expanded', true)\n      }\n\n      callback && callback()\n    }\n\n    $active.length && transition ?\n      $active\n        .one('bsTransitionEnd', next)\n        .emulateTransitionEnd(Tab.TRANSITION_DURATION) :\n      next()\n\n    $active.removeClass('in')\n  }\n\n\n  // TAB PLUGIN DEFINITION\n  // =====================\n\n  function Plugin(option) {\n    return this.each(function () {\n      var $this = $(this)\n      var data  = $this.data('bs.tab')\n\n      if (!data) $this.data('bs.tab', (data = new Tab(this)))\n      if (typeof option == 'string') data[option]()\n    })\n  }\n\n  var old = $.fn.tab\n\n  $.fn.tab             = Plugin\n  $.fn.tab.Constructor = Tab\n\n\n  // TAB NO CONFLICT\n  // ===============\n\n  $.fn.tab.noConflict = function () {\n    $.fn.tab = old\n    return this\n  }\n\n\n  // TAB DATA-API\n  // ============\n\n  var clickHandler = function (e) {\n    e.preventDefault()\n    Plugin.call($(this), 'show')\n  }\n\n  $(document)\n    .on('click.bs.tab.data-api', '[data-toggle=\"tab\"]', clickHandler)\n    .on('click.bs.tab.data-api', '[data-toggle=\"pill\"]', clickHandler)\n\n}(jQuery);\n\n/* ========================================================================\n * Bootstrap: affix.js v3.3.5\n * http://getbootstrap.com/javascript/#affix\n * ========================================================================\n * Copyright 2011-2015 Twitter, Inc.\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)\n * ======================================================================== */\n\n\n+function ($) {\n  'use strict';\n\n  // AFFIX CLASS DEFINITION\n  // ======================\n\n  var Affix = function (element, options) {\n    this.options = $.extend({}, Affix.DEFAULTS, options)\n\n    this.$target = $(this.options.target)\n      .on('scroll.bs.affix.data-api', $.proxy(this.checkPosition, this))\n      .on('click.bs.affix.data-api',  $.proxy(this.checkPositionWithEventLoop, this))\n\n    this.$element     = $(element)\n    this.affixed      = null\n    this.unpin        = null\n    this.pinnedOffset = null\n\n    this.checkPosition()\n  }\n\n  Affix.VERSION  = '3.3.5'\n\n  Affix.RESET    = 'affix affix-top affix-bottom'\n\n  Affix.DEFAULTS = {\n    offset: 0,\n    target: window\n  }\n\n  Affix.prototype.getState = function (scrollHeight, height, offsetTop, offsetBottom) {\n    var scrollTop    = this.$target.scrollTop()\n    var position     = this.$element.offset()\n    var targetHeight = this.$target.height()\n\n    if (offsetTop != null && this.affixed == 'top') return scrollTop < offsetTop ? 'top' : false\n\n    if (this.affixed == 'bottom') {\n      if (offsetTop != null) return (scrollTop + this.unpin <= position.top) ? false : 'bottom'\n      return (scrollTop + targetHeight <= scrollHeight - offsetBottom) ? false : 'bottom'\n    }\n\n    var initializing   = this.affixed == null\n    var colliderTop    = initializing ? scrollTop : position.top\n    var colliderHeight = initializing ? targetHeight : height\n\n    if (offsetTop != null && scrollTop <= offsetTop) return 'top'\n    if (offsetBottom != null && (colliderTop + colliderHeight >= scrollHeight - offsetBottom)) return 'bottom'\n\n    return false\n  }\n\n  Affix.prototype.getPinnedOffset = function () {\n    if (this.pinnedOffset) return this.pinnedOffset\n    this.$element.removeClass(Affix.RESET).addClass('affix')\n    var scrollTop = this.$target.scrollTop()\n    var position  = this.$element.offset()\n    return (this.pinnedOffset = position.top - scrollTop)\n  }\n\n  Affix.prototype.checkPositionWithEventLoop = function () {\n    setTimeout($.proxy(this.checkPosition, this), 1)\n  }\n\n  Affix.prototype.checkPosition = function () {\n    if (!this.$element.is(':visible')) return\n\n    var height       = this.$element.height()\n    var offset       = this.options.offset\n    var offsetTop    = offset.top\n    var offsetBottom = offset.bottom\n    var scrollHeight = Math.max($(document).height(), $(document.body).height())\n\n    if (typeof offset != 'object')         offsetBottom = offsetTop = offset\n    if (typeof offsetTop == 'function')    offsetTop    = offset.top(this.$element)\n    if (typeof offsetBottom == 'function') offsetBottom = offset.bottom(this.$element)\n\n    var affix = this.getState(scrollHeight, height, offsetTop, offsetBottom)\n\n    if (this.affixed != affix) {\n      if (this.unpin != null) this.$element.css('top', '')\n\n      var affixType = 'affix' + (affix ? '-' + affix : '')\n      var e         = $.Event(affixType + '.bs.affix')\n\n      this.$element.trigger(e)\n\n      if (e.isDefaultPrevented()) return\n\n      this.affixed = affix\n      this.unpin = affix == 'bottom' ? this.getPinnedOffset() : null\n\n      this.$element\n        .removeClass(Affix.RESET)\n        .addClass(affixType)\n        .trigger(affixType.replace('affix', 'affixed') + '.bs.affix')\n    }\n\n    if (affix == 'bottom') {\n      this.$element.offset({\n        top: scrollHeight - height - offsetBottom\n      })\n    }\n  }\n\n\n  // AFFIX PLUGIN DEFINITION\n  // =======================\n\n  function Plugin(option) {\n    return this.each(function () {\n      var $this   = $(this)\n      var data    = $this.data('bs.affix')\n      var options = typeof option == 'object' && option\n\n      if (!data) $this.data('bs.affix', (data = new Affix(this, options)))\n      if (typeof option == 'string') data[option]()\n    })\n  }\n\n  var old = $.fn.affix\n\n  $.fn.affix             = Plugin\n  $.fn.affix.Constructor = Affix\n\n\n  // AFFIX NO CONFLICT\n  // =================\n\n  $.fn.affix.noConflict = function () {\n    $.fn.affix = old\n    return this\n  }\n\n\n  // AFFIX DATA-API\n  // ==============\n\n  $(window).on('load', function () {\n    $('[data-spy=\"affix\"]').each(function () {\n      var $spy = $(this)\n      var data = $spy.data()\n\n      data.offset = data.offset || {}\n\n      if (data.offsetBottom != null) data.offset.bottom = data.offsetBottom\n      if (data.offsetTop    != null) data.offset.top    = data.offsetTop\n\n      Plugin.call($spy, data)\n    })\n  })\n\n}(jQuery);\n"
  },
  {
    "path": "app_frontend/static/js/custom.js",
    "content": "/**\n * Created by zhanghe on 16-1-31.\n */\n\n/* 轮播大图延时加载 */\nfunction lazyContainer(searchNode) {\n    $(searchNode).find('.active').find('img.lazy').each(function () {\n        var imgSrc = $(this).attr('data-src');\n        if (imgSrc) {\n            $(this).attr('src', imgSrc);\n            $(this).attr('data-src', '');\n        }\n    });\n}\n\n$('#myCarousel').bind('slid.bs.carousel', function () {\n    lazyContainer(this);\n});\n\nlazyContainer('#myCarousel');\n\n\n/* 生成工具提示 */\n$('[rel=\"tooltip\"]').tooltip();\n\n\n/* 附加导航 */\n$(function () {\n    // 滚动页面侧边悬浮动态导航宽度控制\n    $(window).resize(function () {\n        $('#affix_nav_ul').width($('#affix_nav_ul').parent().width());\n        //console.log($('.container').width());\n        // 如果屏幕宽度小于940px 隐藏侧边导航\n        if ($('.container').width() <= 940) {\n            $('#affix_nav_ul').hide();\n        } else {\n            $('#affix_nav_ul').show();\n        }\n    });\n    $(window).resize();\n});\n\n\n/* 按钮加载状态 */\n// html button 标签其中 autocomplete=\"off\" 属性是针对FF浏览器在页面加载之后，禁用状态不会自动解除用的。\n$(function () {\n    $(\".btn-load\").click(function () {\n        $(this).button('loading').delay(1000).queue(function () {\n            $(this).button('reset').dequeue();\n        });\n    });\n});\n\n\n/* 返回顶部 */\n$('#top-link').click(function () {\n    $('html,body').animate({scrollTop: 0}, 'slow');\n    return false;\n});\nif (($(window).height() + 100) < $(document).height()) {\n    $('#top-link-block').removeClass('hidden').affix({\n        // how far to scroll down before link \"slides\" into view\n        offset: {top: 100}\n    });\n}\n\n/* 侧滑插件 */\n/*\nvar slideout = new Slideout({\n    'panel': document.getElementById('panel'),\n    'menu': document.getElementById('menu'),\n    'padding': 256,\n    'tolerance': 70\n});\n */\n\n\n/**\n * Vertically center Bootstrap 3 modals so they aren't always stuck at the top\n */\n$(function() {\n    function reposition() {\n        var modal = $(this),\n            dialog = modal.find('.modal-dialog');\n        modal.css('display', 'block');\n\n        // Dividing by two centers the modal exactly, but dividing by three\n        // or four works better for larger screens.\n        dialog.css(\"margin-top\", Math.max(0, ($(window).height() - dialog.height()) / 2));\n    }\n    // Reposition when a modal is shown\n    $('.modal').on('show.bs.modal', reposition);\n    // Reposition when the window is resized\n    $(window).on('resize', function() {\n        $('.modal:visible').each(reposition);\n    });\n});\n\n\n/**\n * 闪现消息自动关闭\n */\n$(\".alert\").fadeTo(2000, 500).slideUp(500, function(){\n    $(\".alert\").slideUp(500);\n});\n"
  },
  {
    "path": "app_frontend/static/js/i18n/defaults-ar_AR.js",
    "content": "/*!\n * Bootstrap-select v1.12.2 (http://silviomoreto.github.io/bootstrap-select)\n *\n * Copyright 2013-2017 bootstrap-select\n * Licensed under MIT (https://github.com/silviomoreto/bootstrap-select/blob/master/LICENSE)\n */\n\n(function (root, factory) {\n  if (typeof define === 'function' && define.amd) {\n    // AMD. Register as an anonymous module unless amdModuleId is set\n    define([\"jquery\"], function (a0) {\n      return (factory(a0));\n    });\n  } else if (typeof module === 'object' && module.exports) {\n    // Node. Does not work with strict CommonJS, but\n    // only CommonJS-like environments that support module.exports,\n    // like Node.\n    module.exports = factory(require(\"jquery\"));\n  } else {\n    factory(root[\"jQuery\"]);\n  }\n}(this, function (jQuery) {\n\n/*!\n * Translated default messages for bootstrap-select.\n * Locale: AR (Arabic)\n * Author: Yasser Lotfy <y_l@alive.com>\n */\n(function ($) {\n  $.fn.selectpicker.defaults = {\n    noneSelectedText: 'لم يتم إختيار شئ',\n    noneResultsText: 'لا توجد نتائج مطابقة لـ {0}',\n    countSelectedText: function (numSelected, numTotal) {\n      return (numSelected == 1) ? \"{0} خيار تم إختياره\" : \"{0} خيارات تمت إختيارها\";\n    },\n    maxOptionsText: function (numAll, numGroup) {\n      return [\n        (numAll == 1) ? 'تخطى الحد المسموح ({n} خيار بحد أقصى)' : 'تخطى الحد المسموح ({n} خيارات بحد أقصى)',\n        (numGroup == 1) ? 'تخطى الحد المسموح للمجموعة ({n} خيار بحد أقصى)' : 'تخطى الحد المسموح للمجموعة ({n} خيارات بحد أقصى)'\n      ];\n    },\n    selectAllText: 'إختيار الجميع',\n    deselectAllText: 'إلغاء إختيار الجميع',\n    multipleSeparator: '، '\n  };\n})(jQuery);\n\n\n}));\n"
  },
  {
    "path": "app_frontend/static/js/i18n/defaults-bg_BG.js",
    "content": "/*!\n * Bootstrap-select v1.12.2 (http://silviomoreto.github.io/bootstrap-select)\n *\n * Copyright 2013-2017 bootstrap-select\n * Licensed under MIT (https://github.com/silviomoreto/bootstrap-select/blob/master/LICENSE)\n */\n\n(function (root, factory) {\n  if (typeof define === 'function' && define.amd) {\n    // AMD. Register as an anonymous module unless amdModuleId is set\n    define([\"jquery\"], function (a0) {\n      return (factory(a0));\n    });\n  } else if (typeof module === 'object' && module.exports) {\n    // Node. Does not work with strict CommonJS, but\n    // only CommonJS-like environments that support module.exports,\n    // like Node.\n    module.exports = factory(require(\"jquery\"));\n  } else {\n    factory(root[\"jQuery\"]);\n  }\n}(this, function (jQuery) {\n\n(function ($) {\n  $.fn.selectpicker.defaults = {\n    noneSelectedText: 'Нищо избрано',\n    noneResultsText: 'Няма резултат за {0}',\n    countSelectedText: function (numSelected, numTotal) {\n      return (numSelected == 1) ? \"{0} избран елемент\" : \"{0} избрани елемента\";\n    },\n    maxOptionsText: function (numAll, numGroup) {\n      return [\n        (numAll == 1) ? 'Лимита е достигнат ({n} елемент максимум)' : 'Лимита е достигнат ({n} елемента максимум)',\n        (numGroup == 1) ? 'Груповия лимит е достигнат ({n} елемент максимум)' : 'Груповия лимит е достигнат ({n} елемента максимум)'\n      ];\n    },\n    selectAllText: 'Избери всички',\n    deselectAllText: 'Размаркирай всички',\n    multipleSeparator: ', '\n  };\n})(jQuery);\n\n\n}));\n"
  },
  {
    "path": "app_frontend/static/js/i18n/defaults-cro_CRO.js",
    "content": "/*!\n * Bootstrap-select v1.12.2 (http://silviomoreto.github.io/bootstrap-select)\n *\n * Copyright 2013-2017 bootstrap-select\n * Licensed under MIT (https://github.com/silviomoreto/bootstrap-select/blob/master/LICENSE)\n */\n\n(function (root, factory) {\n  if (typeof define === 'function' && define.amd) {\n    // AMD. Register as an anonymous module unless amdModuleId is set\n    define([\"jquery\"], function (a0) {\n      return (factory(a0));\n    });\n  } else if (typeof module === 'object' && module.exports) {\n    // Node. Does not work with strict CommonJS, but\n    // only CommonJS-like environments that support module.exports,\n    // like Node.\n    module.exports = factory(require(\"jquery\"));\n  } else {\n    factory(root[\"jQuery\"]);\n  }\n}(this, function (jQuery) {\n\n(function ($) {\n  $.fn.selectpicker.defaults = {\n    noneSelectedText: 'Odaberite stavku',\n    noneResultsText: 'Nema rezultata pretrage {0}',\n    countSelectedText: function (numSelected, numTotal) {\n      return (numSelected == 1) ? \"{0} stavka selektirana\" : \"{0} stavke selektirane\";\n    },\n    maxOptionsText: function (numAll, numGroup) {\n      return [\n        (numAll == 1) ? 'Limit je postignut ({n} stvar maximalno)' : 'Limit je postignut ({n} stavke maksimalno)',\n        (numGroup == 1) ? 'Grupni limit je postignut ({n} stvar maksimalno)' : 'Grupni limit je postignut ({n} stavke maksimalno)'\n      ];\n    },\n    selectAllText: 'Selektiraj sve',\n    deselectAllText: 'Deselektiraj sve',\n    multipleSeparator: ', '\n  };\n})(jQuery);\n\n\n}));\n"
  },
  {
    "path": "app_frontend/static/js/i18n/defaults-cs_CZ.js",
    "content": "/*!\n * Bootstrap-select v1.12.2 (http://silviomoreto.github.io/bootstrap-select)\n *\n * Copyright 2013-2017 bootstrap-select\n * Licensed under MIT (https://github.com/silviomoreto/bootstrap-select/blob/master/LICENSE)\n */\n\n(function (root, factory) {\n  if (typeof define === 'function' && define.amd) {\n    // AMD. Register as an anonymous module unless amdModuleId is set\n    define([\"jquery\"], function (a0) {\n      return (factory(a0));\n    });\n  } else if (typeof module === 'object' && module.exports) {\n    // Node. Does not work with strict CommonJS, but\n    // only CommonJS-like environments that support module.exports,\n    // like Node.\n    module.exports = factory(require(\"jquery\"));\n  } else {\n    factory(root[\"jQuery\"]);\n  }\n}(this, function (jQuery) {\n\n(function ($) {\n  $.fn.selectpicker.defaults = {\n    noneSelectedText: 'Nic není vybráno',\n    noneResultsText: 'Žádné výsledky {0}',\n    countSelectedText: 'Označeno {0} z {1}',\n    maxOptionsText: ['Limit překročen ({n} {var} max)', 'Limit skupiny překročen ({n} {var} max)', ['položek', 'položka']],\n    multipleSeparator: ', '\n  };\n})(jQuery);\n\n\n}));\n"
  },
  {
    "path": "app_frontend/static/js/i18n/defaults-da_DK.js",
    "content": "/*!\n * Bootstrap-select v1.12.2 (http://silviomoreto.github.io/bootstrap-select)\n *\n * Copyright 2013-2017 bootstrap-select\n * Licensed under MIT (https://github.com/silviomoreto/bootstrap-select/blob/master/LICENSE)\n */\n\n(function (root, factory) {\n  if (typeof define === 'function' && define.amd) {\n    // AMD. Register as an anonymous module unless amdModuleId is set\n    define([\"jquery\"], function (a0) {\n      return (factory(a0));\n    });\n  } else if (typeof module === 'object' && module.exports) {\n    // Node. Does not work with strict CommonJS, but\n    // only CommonJS-like environments that support module.exports,\n    // like Node.\n    module.exports = factory(require(\"jquery\"));\n  } else {\n    factory(root[\"jQuery\"]);\n  }\n}(this, function (jQuery) {\n\n(function ($) {\n  $.fn.selectpicker.defaults = {\n    noneSelectedText: 'Intet valgt',\n    noneResultsText: 'Ingen resultater fundet {0}',\n    countSelectedText: function (numSelected, numTotal) {\n      return (numSelected == 1) ? \"{0} valgt\" : \"{0} valgt\";\n    },\n    maxOptionsText: function (numAll, numGroup) {\n      return [\n        (numAll == 1) ? 'Begrænsning nået (max {n} valgt)' : 'Begrænsning nået (max {n} valgte)',\n        (numGroup == 1) ? 'Gruppe-begrænsning nået (max {n} valgt)' : 'Gruppe-begrænsning nået (max {n} valgte)'\n      ];\n    },\n    selectAllText: 'Markér alle',\n    deselectAllText: 'Afmarkér alle',\n    multipleSeparator: ', '\n  };\n})(jQuery);\n\n\n}));\n"
  },
  {
    "path": "app_frontend/static/js/i18n/defaults-de_DE.js",
    "content": "/*!\n * Bootstrap-select v1.12.2 (http://silviomoreto.github.io/bootstrap-select)\n *\n * Copyright 2013-2017 bootstrap-select\n * Licensed under MIT (https://github.com/silviomoreto/bootstrap-select/blob/master/LICENSE)\n */\n\n(function (root, factory) {\n  if (typeof define === 'function' && define.amd) {\n    // AMD. Register as an anonymous module unless amdModuleId is set\n    define([\"jquery\"], function (a0) {\n      return (factory(a0));\n    });\n  } else if (typeof module === 'object' && module.exports) {\n    // Node. Does not work with strict CommonJS, but\n    // only CommonJS-like environments that support module.exports,\n    // like Node.\n    module.exports = factory(require(\"jquery\"));\n  } else {\n    factory(root[\"jQuery\"]);\n  }\n}(this, function (jQuery) {\n\n(function ($) {\n  $.fn.selectpicker.defaults = {\n    noneSelectedText: 'Bitte wählen...',\n    noneResultsText: 'Keine Ergebnisse für {0}',\n    countSelectedText: function (numSelected, numTotal) {\n      return (numSelected == 1) ? \"{0} Element ausgewählt\" : \"{0} Elemente ausgewählt\";\n    },\n    maxOptionsText: function (numAll, numGroup) {\n      return [\n        (numAll == 1) ? 'Limit erreicht ({n} Element max.)' : 'Limit erreicht ({n} Elemente max.)',\n        (numGroup == 1) ? 'Gruppen-Limit erreicht ({n} Element max.)' : 'Gruppen-Limit erreicht ({n} Elemente max.)'\n      ];\n    },\n    selectAllText: 'Alles auswählen',\n    deselectAllText: 'Nichts auswählen',\n    multipleSeparator: ', '\n  };\n})(jQuery);\n\n\n}));\n"
  },
  {
    "path": "app_frontend/static/js/i18n/defaults-en_US.js",
    "content": "/*!\n * Bootstrap-select v1.12.2 (http://silviomoreto.github.io/bootstrap-select)\n *\n * Copyright 2013-2017 bootstrap-select\n * Licensed under MIT (https://github.com/silviomoreto/bootstrap-select/blob/master/LICENSE)\n */\n\n(function (root, factory) {\n  if (typeof define === 'function' && define.amd) {\n    // AMD. Register as an anonymous module unless amdModuleId is set\n    define([\"jquery\"], function (a0) {\n      return (factory(a0));\n    });\n  } else if (typeof module === 'object' && module.exports) {\n    // Node. Does not work with strict CommonJS, but\n    // only CommonJS-like environments that support module.exports,\n    // like Node.\n    module.exports = factory(require(\"jquery\"));\n  } else {\n    factory(root[\"jQuery\"]);\n  }\n}(this, function (jQuery) {\n\n(function ($) {\n  $.fn.selectpicker.defaults = {\n    noneSelectedText: 'Nothing selected',\n    noneResultsText: 'No results match {0}',\n    countSelectedText: function (numSelected, numTotal) {\n      return (numSelected == 1) ? \"{0} item selected\" : \"{0} items selected\";\n    },\n    maxOptionsText: function (numAll, numGroup) {\n      return [\n        (numAll == 1) ? 'Limit reached ({n} item max)' : 'Limit reached ({n} items max)',\n        (numGroup == 1) ? 'Group limit reached ({n} item max)' : 'Group limit reached ({n} items max)'\n      ];\n    },\n    selectAllText: 'Select All',\n    deselectAllText: 'Deselect All',\n    multipleSeparator: ', '\n  };\n})(jQuery);\n\n\n}));\n"
  },
  {
    "path": "app_frontend/static/js/i18n/defaults-es_CL.js",
    "content": "/*!\n * Bootstrap-select v1.12.2 (http://silviomoreto.github.io/bootstrap-select)\n *\n * Copyright 2013-2017 bootstrap-select\n * Licensed under MIT (https://github.com/silviomoreto/bootstrap-select/blob/master/LICENSE)\n */\n\n(function (root, factory) {\n  if (typeof define === 'function' && define.amd) {\n    // AMD. Register as an anonymous module unless amdModuleId is set\n    define([\"jquery\"], function (a0) {\n      return (factory(a0));\n    });\n  } else if (typeof module === 'object' && module.exports) {\n    // Node. Does not work with strict CommonJS, but\n    // only CommonJS-like environments that support module.exports,\n    // like Node.\n    module.exports = factory(require(\"jquery\"));\n  } else {\n    factory(root[\"jQuery\"]);\n  }\n}(this, function (jQuery) {\n\n(function ($) {\n  $.fn.selectpicker.defaults = {\n    noneSelectedText: 'No hay selección',\n    noneResultsText: 'No hay resultados {0}',\n    countSelectedText: 'Seleccionados {0} de {1}',\n    maxOptionsText: ['Límite alcanzado ({n} {var} max)', 'Límite del grupo alcanzado({n} {var} max)', ['elementos', 'element']],\n    multipleSeparator: ', ',\n    selectAllText: 'Seleccionar Todos',\n    deselectAllText: 'Desmarcar Todos'\n  };\n})(jQuery);\n\n\n}));\n"
  },
  {
    "path": "app_frontend/static/js/i18n/defaults-es_ES.js",
    "content": "/*!\n * Bootstrap-select v1.12.2 (http://silviomoreto.github.io/bootstrap-select)\n *\n * Copyright 2013-2017 bootstrap-select\n * Licensed under MIT (https://github.com/silviomoreto/bootstrap-select/blob/master/LICENSE)\n */\n\n(function (root, factory) {\n  if (typeof define === 'function' && define.amd) {\n    // AMD. Register as an anonymous module unless amdModuleId is set\n    define([\"jquery\"], function (a0) {\n      return (factory(a0));\n    });\n  } else if (typeof module === 'object' && module.exports) {\n    // Node. Does not work with strict CommonJS, but\n    // only CommonJS-like environments that support module.exports,\n    // like Node.\n    module.exports = factory(require(\"jquery\"));\n  } else {\n    factory(root[\"jQuery\"]);\n  }\n}(this, function (jQuery) {\n\n(function ($) {\n  $.fn.selectpicker.defaults = {\n    noneSelectedText: 'No hay selección',\n    noneResultsText: 'No hay resultados {0}',\n    countSelectedText: 'Seleccionados {0} de {1}',\n    maxOptionsText: ['Límite alcanzado ({n} {var} max)', 'Límite del grupo alcanzado({n} {var} max)', ['elementos', 'element']],\n    multipleSeparator: ', ',\n    selectAllText: 'Seleccionar Todos',\n    deselectAllText: 'Desmarcar Todos'\n  };\n})(jQuery);\n\n\n}));\n"
  },
  {
    "path": "app_frontend/static/js/i18n/defaults-eu.js",
    "content": "/*!\n * Bootstrap-select v1.12.2 (http://silviomoreto.github.io/bootstrap-select)\n *\n * Copyright 2013-2017 bootstrap-select\n * Licensed under MIT (https://github.com/silviomoreto/bootstrap-select/blob/master/LICENSE)\n */\n\n(function (root, factory) {\n  if (typeof define === 'function' && define.amd) {\n    // AMD. Register as an anonymous module unless amdModuleId is set\n    define([\"jquery\"], function (a0) {\n      return (factory(a0));\n    });\n  } else if (typeof module === 'object' && module.exports) {\n    // Node. Does not work with strict CommonJS, but\n    // only CommonJS-like environments that support module.exports,\n    // like Node.\n    module.exports = factory(require(\"jquery\"));\n  } else {\n    factory(root[\"jQuery\"]);\n  }\n}(this, function (jQuery) {\n\n(function ($) {\n  $.fn.selectpicker.defaults = {\n    noneSelectedText: 'Hautapenik ez',\n    noneResultsText: 'Emaitzarik ez {0}',\n    countSelectedText: '{1}(e)tik {0} hautatuta',\n    maxOptionsText: ['Mugara iritsita ({n} {var} gehienez)', 'Taldearen mugara iritsita ({n} {var} gehienez)', ['elementu', 'elementu']],\n    multipleSeparator: ', '\n  };\n})(jQuery);\n\n\n}));\n"
  },
  {
    "path": "app_frontend/static/js/i18n/defaults-fa_IR.js",
    "content": "/*!\n * Bootstrap-select v1.12.2 (http://silviomoreto.github.io/bootstrap-select)\n *\n * Copyright 2013-2017 bootstrap-select\n * Licensed under MIT (https://github.com/silviomoreto/bootstrap-select/blob/master/LICENSE)\n */\n\n(function (root, factory) {\n  if (typeof define === 'function' && define.amd) {\n    // AMD. Register as an anonymous module unless amdModuleId is set\n    define([\"jquery\"], function (a0) {\n      return (factory(a0));\n    });\n  } else if (typeof module === 'object' && module.exports) {\n    // Node. Does not work with strict CommonJS, but\n    // only CommonJS-like environments that support module.exports,\n    // like Node.\n    module.exports = factory(require(\"jquery\"));\n  } else {\n    factory(root[\"jQuery\"]);\n  }\n}(this, function (jQuery) {\n\n(function ($) {\n    $.fn.selectpicker.defaults = {\n        noneSelectedText: 'چیزی انتخاب نشده است',\n        noneResultsText: 'هیج مشابهی برای {0} پیدا نشد',\n        countSelectedText: \"{0} از {1} مورد انتخاب شده\",\n        maxOptionsText: ['بیشتر ممکن نیست {حداکثر {n} عدد}', 'بیشتر ممکن نیست {حداکثر {n} عدد}'],\n        selectAllText: 'انتخاب همه',\n        deselectAllText: 'انتخاب هیچ کدام',\n        multipleSeparator: ', '\n    };\n})(jQuery);\n\n\n}));\n"
  },
  {
    "path": "app_frontend/static/js/i18n/defaults-fi_FI.js",
    "content": "/*!\n * Bootstrap-select v1.12.2 (http://silviomoreto.github.io/bootstrap-select)\n *\n * Copyright 2013-2017 bootstrap-select\n * Licensed under MIT (https://github.com/silviomoreto/bootstrap-select/blob/master/LICENSE)\n */\n\n(function (root, factory) {\n  if (typeof define === 'function' && define.amd) {\n    // AMD. Register as an anonymous module unless amdModuleId is set\n    define([\"jquery\"], function (a0) {\n      return (factory(a0));\n    });\n  } else if (typeof module === 'object' && module.exports) {\n    // Node. Does not work with strict CommonJS, but\n    // only CommonJS-like environments that support module.exports,\n    // like Node.\n    module.exports = factory(require(\"jquery\"));\n  } else {\n    factory(root[\"jQuery\"]);\n  }\n}(this, function (jQuery) {\n\n(function ($) {\n  $.fn.selectpicker.defaults = {\n    noneSelectedText: 'Ei valintoja',\n    noneResultsText: 'Ei hakutuloksia {0}',\n    countSelectedText: function (numSelected, numTotal) {\n      return (numSelected == 1) ? \"{0} valittu\" : \"{0} valitut\";\n    },\n    maxOptionsText: function (numAll, numGroup) {\n      return [\n        (numAll == 1) ? 'Valintojen maksimimäärä ({n} saavutettu)' : 'Valintojen maksimimäärä ({n} saavutettu)',\n        (numGroup == 1) ? 'Ryhmän maksimimäärä ({n} saavutettu)' : 'Ryhmän maksimimäärä ({n} saavutettu)'\n      ];\n    },\n    selectAllText: 'Valitse kaikki',\n    deselectAllText: 'Poista kaikki',\n    multipleSeparator: ', '\n  };\n})(jQuery);\n\n\n}));\n"
  },
  {
    "path": "app_frontend/static/js/i18n/defaults-fr_FR.js",
    "content": "/*!\n * Bootstrap-select v1.12.2 (http://silviomoreto.github.io/bootstrap-select)\n *\n * Copyright 2013-2017 bootstrap-select\n * Licensed under MIT (https://github.com/silviomoreto/bootstrap-select/blob/master/LICENSE)\n */\n\n(function (root, factory) {\n  if (typeof define === 'function' && define.amd) {\n    // AMD. Register as an anonymous module unless amdModuleId is set\n    define([\"jquery\"], function (a0) {\n      return (factory(a0));\n    });\n  } else if (typeof module === 'object' && module.exports) {\n    // Node. Does not work with strict CommonJS, but\n    // only CommonJS-like environments that support module.exports,\n    // like Node.\n    module.exports = factory(require(\"jquery\"));\n  } else {\n    factory(root[\"jQuery\"]);\n  }\n}(this, function (jQuery) {\n\n(function ($) {\n  $.fn.selectpicker.defaults = {\n    noneSelectedText: 'Aucune sélection',\n    noneResultsText: 'Aucun résultat pour {0}',\n    countSelectedText: function (numSelected, numTotal) {\n      return (numSelected > 1) ? \"{0} éléments sélectionnés\" : \"{0} élément sélectionné\";\n    },\n    maxOptionsText: function (numAll, numGroup) {\n      return [\n        (numAll > 1) ? 'Limite atteinte ({n} éléments max)' : 'Limite atteinte ({n} élément max)',\n        (numGroup > 1) ? 'Limite du groupe atteinte ({n} éléments max)' : 'Limite du groupe atteinte ({n} élément max)'\n      ];\n    },\n    multipleSeparator: ', ',\n    selectAllText: 'Tout Sélectionner',\n    deselectAllText: 'Tout Dé-selectionner',\n  };\n})(jQuery);\n\n\n}));\n"
  },
  {
    "path": "app_frontend/static/js/i18n/defaults-hu_HU.js",
    "content": "/*!\n * Bootstrap-select v1.12.2 (http://silviomoreto.github.io/bootstrap-select)\n *\n * Copyright 2013-2017 bootstrap-select\n * Licensed under MIT (https://github.com/silviomoreto/bootstrap-select/blob/master/LICENSE)\n */\n\n(function (root, factory) {\n  if (typeof define === 'function' && define.amd) {\n    // AMD. Register as an anonymous module unless amdModuleId is set\n    define([\"jquery\"], function (a0) {\n      return (factory(a0));\n    });\n  } else if (typeof module === 'object' && module.exports) {\n    // Node. Does not work with strict CommonJS, but\n    // only CommonJS-like environments that support module.exports,\n    // like Node.\n    module.exports = factory(require(\"jquery\"));\n  } else {\n    factory(root[\"jQuery\"]);\n  }\n}(this, function (jQuery) {\n\n(function ($) {\n  $.fn.selectpicker.defaults = {\n    noneSelectedText: 'Válasszon!',\n    noneResultsText: 'Nincs találat {0}',\n    countSelectedText: function (numSelected, numTotal) {\n      return '{0} elem kiválasztva';\n    },\n    maxOptionsText: function (numAll, numGroup) {\n      return [\n        'Legfeljebb {n} elem választható',\n        'A csoportban legfeljebb {n} elem választható'\n      ];\n    },\n    selectAllText: 'Mind',\n    deselectAllText: 'Egyik sem',\n    multipleSeparator: ', '\n  };\n})(jQuery);\n\n\n}));\n"
  },
  {
    "path": "app_frontend/static/js/i18n/defaults-id_ID.js",
    "content": "/*!\n * Bootstrap-select v1.12.2 (http://silviomoreto.github.io/bootstrap-select)\n *\n * Copyright 2013-2017 bootstrap-select\n * Licensed under MIT (https://github.com/silviomoreto/bootstrap-select/blob/master/LICENSE)\n */\n\n(function (root, factory) {\n  if (typeof define === 'function' && define.amd) {\n    // AMD. Register as an anonymous module unless amdModuleId is set\n    define([\"jquery\"], function (a0) {\n      return (factory(a0));\n    });\n  } else if (typeof module === 'object' && module.exports) {\n    // Node. Does not work with strict CommonJS, but\n    // only CommonJS-like environments that support module.exports,\n    // like Node.\n    module.exports = factory(require(\"jquery\"));\n  } else {\n    factory(root[\"jQuery\"]);\n  }\n}(this, function (jQuery) {\n\n(function ($) {\n  $.fn.selectpicker.defaults = {\n    noneSelectedText: 'Tidak ada yang dipilih',\n    noneResultsText: 'Tidak ada yang cocok {0}',\n    countSelectedText: '{0} terpilih',\n    maxOptionsText: ['Mencapai batas (maksimum {n})', 'Mencapai batas grup (maksimum {n})'],\n    selectAllText: 'Pilih Semua',\n    deselectAllText: 'Hapus Semua',\n    multipleSeparator: ', '\n  };\n})(jQuery);\n\n\n}));\n"
  },
  {
    "path": "app_frontend/static/js/i18n/defaults-it_IT.js",
    "content": "/*!\n * Bootstrap-select v1.12.2 (http://silviomoreto.github.io/bootstrap-select)\n *\n * Copyright 2013-2017 bootstrap-select\n * Licensed under MIT (https://github.com/silviomoreto/bootstrap-select/blob/master/LICENSE)\n */\n\n(function (root, factory) {\n  if (typeof define === 'function' && define.amd) {\n    // AMD. Register as an anonymous module unless amdModuleId is set\n    define([\"jquery\"], function (a0) {\n      return (factory(a0));\n    });\n  } else if (typeof module === 'object' && module.exports) {\n    // Node. Does not work with strict CommonJS, but\n    // only CommonJS-like environments that support module.exports,\n    // like Node.\n    module.exports = factory(require(\"jquery\"));\n  } else {\n    factory(root[\"jQuery\"]);\n  }\n}(this, function (jQuery) {\n\n(function ($) {\n  $.fn.selectpicker.defaults = {\n    noneSelectedText: 'Nessuna selezione',\n    noneResultsText: 'Nessun risultato per {0}',\n    countSelectedText: function (numSelected, numTotal){\n      return (numSelected == 1) ? 'Selezionato {0} di {1}' : 'Selezionati {0} di {1}';\n    },\n    maxOptionsText: ['Limite raggiunto ({n} {var} max)', 'Limite del gruppo raggiunto ({n} {var} max)', ['elementi', 'elemento']],\n    multipleSeparator: ', ',\n    selectAllText: 'Seleziona Tutto',\n    deselectAllText: 'Deseleziona Tutto'\n  };\n})(jQuery);\n\n\n}));\n"
  },
  {
    "path": "app_frontend/static/js/i18n/defaults-ko_KR.js",
    "content": "/*!\n * Bootstrap-select v1.12.2 (http://silviomoreto.github.io/bootstrap-select)\n *\n * Copyright 2013-2017 bootstrap-select\n * Licensed under MIT (https://github.com/silviomoreto/bootstrap-select/blob/master/LICENSE)\n */\n\n(function (root, factory) {\n  if (typeof define === 'function' && define.amd) {\n    // AMD. Register as an anonymous module unless amdModuleId is set\n    define([\"jquery\"], function (a0) {\n      return (factory(a0));\n    });\n  } else if (typeof module === 'object' && module.exports) {\n    // Node. Does not work with strict CommonJS, but\n    // only CommonJS-like environments that support module.exports,\n    // like Node.\n    module.exports = factory(require(\"jquery\"));\n  } else {\n    factory(root[\"jQuery\"]);\n  }\n}(this, function (jQuery) {\n\n(function ($) {\n  $.fn.selectpicker.defaults = {\n    noneSelectedText: '항목을 선택해주세요',\n    noneResultsText: '{0} 검색 결과가 없습니다',\n    countSelectedText: function (numSelected, numTotal) {\n      return \"{0}개를 선택하였습니다\";\n    },\n    maxOptionsText: function (numAll, numGroup) {\n      return [\n        '{n}개까지 선택 가능합니다',\n        '해당 그룹은 {n}개까지 선택 가능합니다'\n      ];\n    },\n    selectAllText: '전체선택',\n    deselectAllText: '전체해제',\n    multipleSeparator: ', '\n  };\n})(jQuery);\n\n\n}));\n"
  },
  {
    "path": "app_frontend/static/js/i18n/defaults-lt_LT.js",
    "content": "/*!\n * Bootstrap-select v1.12.2 (http://silviomoreto.github.io/bootstrap-select)\n *\n * Copyright 2013-2017 bootstrap-select\n * Licensed under MIT (https://github.com/silviomoreto/bootstrap-select/blob/master/LICENSE)\n */\n\n(function (root, factory) {\n  if (typeof define === 'function' && define.amd) {\n    // AMD. Register as an anonymous module unless amdModuleId is set\n    define([\"jquery\"], function (a0) {\n      return (factory(a0));\n    });\n  } else if (typeof module === 'object' && module.exports) {\n    // Node. Does not work with strict CommonJS, but\n    // only CommonJS-like environments that support module.exports,\n    // like Node.\n    module.exports = factory(require(\"jquery\"));\n  } else {\n    factory(root[\"jQuery\"]);\n  }\n}(this, function (jQuery) {\n\n(function ($) {\n  $.fn.selectpicker.defaults = {\n    noneSelectedText: 'Niekas nepasirinkta',\n    noneResultsText: 'Niekas nesutapo su {0}',\n    countSelectedText: function (numSelected, numTotal) {\n      return (numSelected == 1) ? \"{0} elementas pasirinktas\" : \"{0} elementai(-ų) pasirinkta\";\n    },\n    maxOptionsText: function (numAll, numGroup) {\n      return [\n        (numAll == 1) ? 'Pasiekta riba ({n} elementas daugiausiai)' : 'Riba pasiekta ({n} elementai(-ų) daugiausiai)',\n        (numGroup == 1) ? 'Grupės riba pasiekta ({n} elementas daugiausiai)' : 'Grupės riba pasiekta ({n} elementai(-ų) daugiausiai)'\n      ];\n    },\n    selectAllText: 'Pasirinkti visus',\n    deselectAllText: 'Atmesti visus',\n    multipleSeparator: ', '\n  };\n})(jQuery);\n\n\n}));\n"
  },
  {
    "path": "app_frontend/static/js/i18n/defaults-nb_NO.js",
    "content": "/*!\n * Bootstrap-select v1.12.2 (http://silviomoreto.github.io/bootstrap-select)\n *\n * Copyright 2013-2017 bootstrap-select\n * Licensed under MIT (https://github.com/silviomoreto/bootstrap-select/blob/master/LICENSE)\n */\n\n(function (root, factory) {\n  if (typeof define === 'function' && define.amd) {\n    // AMD. Register as an anonymous module unless amdModuleId is set\n    define([\"jquery\"], function (a0) {\n      return (factory(a0));\n    });\n  } else if (typeof module === 'object' && module.exports) {\n    // Node. Does not work with strict CommonJS, but\n    // only CommonJS-like environments that support module.exports,\n    // like Node.\n    module.exports = factory(require(\"jquery\"));\n  } else {\n    factory(root[\"jQuery\"]);\n  }\n}(this, function (jQuery) {\n\n(function ($) {\n  $.fn.selectpicker.defaults = {\n    noneSelectedText: 'Ingen valgt',\n    noneResultsText: 'Søket gir ingen treff {0}',\n    countSelectedText: function (numSelected, numTotal) {\n      return (numSelected == 1) ? \"{0} alternativ valgt\" : \"{0} alternativer valgt\";\n    },\n    maxOptionsText: function (numAll, numGroup) {\n      return [\n        (numAll == 1) ? 'Grense nådd (maks {n} valg)' : 'Grense nådd (maks {n} valg)',\n        (numGroup == 1) ? 'Grense for grupper nådd (maks {n} grupper)' : 'Grense for grupper nådd (maks {n} grupper)'\n      ];\n    },\n    selectAllText: 'Merk alle',\n    deselectAllText: 'Fjern alle',\n    multipleSeparator: ', '\n  };\n})(jQuery);\n\n\n}));\n"
  },
  {
    "path": "app_frontend/static/js/i18n/defaults-nl_NL.js",
    "content": "/*!\n * Bootstrap-select v1.12.2 (http://silviomoreto.github.io/bootstrap-select)\n *\n * Copyright 2013-2017 bootstrap-select\n * Licensed under MIT (https://github.com/silviomoreto/bootstrap-select/blob/master/LICENSE)\n */\n\n(function (root, factory) {\n  if (typeof define === 'function' && define.amd) {\n    // AMD. Register as an anonymous module unless amdModuleId is set\n    define([\"jquery\"], function (a0) {\n      return (factory(a0));\n    });\n  } else if (typeof module === 'object' && module.exports) {\n    // Node. Does not work with strict CommonJS, but\n    // only CommonJS-like environments that support module.exports,\n    // like Node.\n    module.exports = factory(require(\"jquery\"));\n  } else {\n    factory(root[\"jQuery\"]);\n  }\n}(this, function (jQuery) {\n\n(function ($) {\n  $.fn.selectpicker.defaults = {\n    noneSelectedText: 'Niets geselecteerd',\n    noneResultsText: 'Geen resultaten gevonden voor {0}',\n    countSelectedText: '{0} van {1} geselecteerd',\n    maxOptionsText: ['Limiet bereikt ({n} {var} max)', 'Groep limiet bereikt ({n} {var} max)', ['items', 'item']],\n    multipleSeparator: ', '\n  };\n})(jQuery);\n\n\n}));\n"
  },
  {
    "path": "app_frontend/static/js/i18n/defaults-pl_PL.js",
    "content": "/*!\n * Bootstrap-select v1.12.2 (http://silviomoreto.github.io/bootstrap-select)\n *\n * Copyright 2013-2017 bootstrap-select\n * Licensed under MIT (https://github.com/silviomoreto/bootstrap-select/blob/master/LICENSE)\n */\n\n(function (root, factory) {\n  if (typeof define === 'function' && define.amd) {\n    // AMD. Register as an anonymous module unless amdModuleId is set\n    define([\"jquery\"], function (a0) {\n      return (factory(a0));\n    });\n  } else if (typeof module === 'object' && module.exports) {\n    // Node. Does not work with strict CommonJS, but\n    // only CommonJS-like environments that support module.exports,\n    // like Node.\n    module.exports = factory(require(\"jquery\"));\n  } else {\n    factory(root[\"jQuery\"]);\n  }\n}(this, function (jQuery) {\n\n(function ($) {\n  $.fn.selectpicker.defaults = {\n    noneSelectedText: 'Nic nie zaznaczono',\n    noneResultsText: 'Brak wyników wyszukiwania {0}',\n    countSelectedText: 'Zaznaczono {0} z {1}',\n    maxOptionsText: ['Osiągnięto limit ({n} {var} max)', 'Limit grupy osiągnięty ({n} {var} max)', ['elementy', 'element']],\n    selectAll: 'Zaznacz wszystkie',\n    deselectAll: 'Odznacz wszystkie',\n    multipleSeparator: ', '\n  };\n})(jQuery);\n\n\n}));\n"
  },
  {
    "path": "app_frontend/static/js/i18n/defaults-pt_BR.js",
    "content": "/*!\n * Bootstrap-select v1.12.2 (http://silviomoreto.github.io/bootstrap-select)\n *\n * Copyright 2013-2017 bootstrap-select\n * Licensed under MIT (https://github.com/silviomoreto/bootstrap-select/blob/master/LICENSE)\n */\n\n(function (root, factory) {\n  if (typeof define === 'function' && define.amd) {\n    // AMD. Register as an anonymous module unless amdModuleId is set\n    define([\"jquery\"], function (a0) {\n      return (factory(a0));\n    });\n  } else if (typeof module === 'object' && module.exports) {\n    // Node. Does not work with strict CommonJS, but\n    // only CommonJS-like environments that support module.exports,\n    // like Node.\n    module.exports = factory(require(\"jquery\"));\n  } else {\n    factory(root[\"jQuery\"]);\n  }\n}(this, function (jQuery) {\n\n(function ($) {\n  $.fn.selectpicker.defaults = {\n    noneSelectedText: 'Nada selecionado',\n    noneResultsText: 'Nada encontrado contendo {0}',\n    countSelectedText: 'Selecionado {0} de {1}',\n    maxOptionsText: ['Limite excedido (máx. {n} {var})', 'Limite do grupo excedido (máx. {n} {var})', ['itens', 'item']],\n    multipleSeparator: ', '\n  };\n})(jQuery);\n\n\n}));\n"
  },
  {
    "path": "app_frontend/static/js/i18n/defaults-pt_PT.js",
    "content": "/*!\n * Bootstrap-select v1.12.2 (http://silviomoreto.github.io/bootstrap-select)\n *\n * Copyright 2013-2017 bootstrap-select\n * Licensed under MIT (https://github.com/silviomoreto/bootstrap-select/blob/master/LICENSE)\n */\n\n(function (root, factory) {\n  if (typeof define === 'function' && define.amd) {\n    // AMD. Register as an anonymous module unless amdModuleId is set\n    define([\"jquery\"], function (a0) {\n      return (factory(a0));\n    });\n  } else if (typeof module === 'object' && module.exports) {\n    // Node. Does not work with strict CommonJS, but\n    // only CommonJS-like environments that support module.exports,\n    // like Node.\n    module.exports = factory(require(\"jquery\"));\n  } else {\n    factory(root[\"jQuery\"]);\n  }\n}(this, function (jQuery) {\n\n(function ($) {\n$.fn.selectpicker.defaults = {\nnoneSelectedText: 'Nenhum seleccionado',\nnoneResultsText: 'Sem resultados contendo {0}',\ncountSelectedText: 'Selecionado {0} de {1}',\nmaxOptionsText: ['Limite ultrapassado (máx. {n} {var})', 'Limite de seleções ultrapassado (máx. {n} {var})', ['itens', 'item']],\nmultipleSeparator: ', '\n};\n})(jQuery);\n\n\n}));\n"
  },
  {
    "path": "app_frontend/static/js/i18n/defaults-ro_RO.js",
    "content": "/*!\n * Bootstrap-select v1.12.2 (http://silviomoreto.github.io/bootstrap-select)\n *\n * Copyright 2013-2017 bootstrap-select\n * Licensed under MIT (https://github.com/silviomoreto/bootstrap-select/blob/master/LICENSE)\n */\n\n(function (root, factory) {\n  if (typeof define === 'function' && define.amd) {\n    // AMD. Register as an anonymous module unless amdModuleId is set\n    define([\"jquery\"], function (a0) {\n      return (factory(a0));\n    });\n  } else if (typeof module === 'object' && module.exports) {\n    // Node. Does not work with strict CommonJS, but\n    // only CommonJS-like environments that support module.exports,\n    // like Node.\n    module.exports = factory(require(\"jquery\"));\n  } else {\n    factory(root[\"jQuery\"]);\n  }\n}(this, function (jQuery) {\n\n(function ($) {\n  $.fn.selectpicker.defaults = {\n    noneSelectedText: 'Nu a fost selectat nimic',\n    noneResultsText: 'Nu exista niciun rezultat {0}',\n    countSelectedText: '{0} din {1} selectat(e)',\n    maxOptionsText: ['Limita a fost atinsa ({n} {var} max)', 'Limita de grup a fost atinsa ({n} {var} max)', ['iteme', 'item']],\n    multipleSeparator: ', '\n  };\n})(jQuery);\n\n\n}));\n"
  },
  {
    "path": "app_frontend/static/js/i18n/defaults-ru_RU.js",
    "content": "/*!\n * Bootstrap-select v1.12.2 (http://silviomoreto.github.io/bootstrap-select)\n *\n * Copyright 2013-2017 bootstrap-select\n * Licensed under MIT (https://github.com/silviomoreto/bootstrap-select/blob/master/LICENSE)\n */\n\n(function (root, factory) {\n  if (typeof define === 'function' && define.amd) {\n    // AMD. Register as an anonymous module unless amdModuleId is set\n    define([\"jquery\"], function (a0) {\n      return (factory(a0));\n    });\n  } else if (typeof module === 'object' && module.exports) {\n    // Node. Does not work with strict CommonJS, but\n    // only CommonJS-like environments that support module.exports,\n    // like Node.\n    module.exports = factory(require(\"jquery\"));\n  } else {\n    factory(root[\"jQuery\"]);\n  }\n}(this, function (jQuery) {\n\n(function ($) {\n  $.fn.selectpicker.defaults = {\n    noneSelectedText: 'Ничего не выбрано',\n    noneResultsText: 'Совпадений не найдено {0}',\n    countSelectedText: 'Выбрано {0} из {1}',\n    maxOptionsText: ['Достигнут предел ({n} {var} максимум)', 'Достигнут предел в группе ({n} {var} максимум)', ['шт.', 'шт.']],\n    doneButtonText: 'Закрыть',\n    selectAllText: 'Выбрать все',\n    deselectAllText: 'Отменить все',    \n    multipleSeparator: ', '\n  };\n})(jQuery);\n\n\n}));\n"
  },
  {
    "path": "app_frontend/static/js/i18n/defaults-sk_SK.js",
    "content": "/*!\n * Bootstrap-select v1.12.2 (http://silviomoreto.github.io/bootstrap-select)\n *\n * Copyright 2013-2017 bootstrap-select\n * Licensed under MIT (https://github.com/silviomoreto/bootstrap-select/blob/master/LICENSE)\n */\n\n(function (root, factory) {\n  if (typeof define === 'function' && define.amd) {\n    // AMD. Register as an anonymous module unless amdModuleId is set\n    define([\"jquery\"], function (a0) {\n      return (factory(a0));\n    });\n  } else if (typeof module === 'object' && module.exports) {\n    // Node. Does not work with strict CommonJS, but\n    // only CommonJS-like environments that support module.exports,\n    // like Node.\n    module.exports = factory(require(\"jquery\"));\n  } else {\n    factory(root[\"jQuery\"]);\n  }\n}(this, function (jQuery) {\n\n(function ($) {\n  $.fn.selectpicker.defaults = {\n    noneSelectedText: 'Vyberte zo zoznamu',\n    noneResultsText: 'Pre výraz {0} neboli nájdené žiadne výsledky',\n    countSelectedText: 'Vybrané {0} z {1}',\n    maxOptionsText: ['Limit prekročený ({n} {var} max)', 'Limit skupiny prekročený ({n} {var} max)', ['položiek', 'položka']],\n    selectAllText: 'Vybrať všetky',\n    deselectAllText: 'Zrušiť výber',\n    multipleSeparator: ', '\n  };\n})(jQuery);\n\n\n}));\n"
  },
  {
    "path": "app_frontend/static/js/i18n/defaults-sl_SI.js",
    "content": "/*!\n * Bootstrap-select v1.12.2 (http://silviomoreto.github.io/bootstrap-select)\n *\n * Copyright 2013-2017 bootstrap-select\n * Licensed under MIT (https://github.com/silviomoreto/bootstrap-select/blob/master/LICENSE)\n */\n\n(function (root, factory) {\n  if (typeof define === 'function' && define.amd) {\n    // AMD. Register as an anonymous module unless amdModuleId is set\n    define([\"jquery\"], function (a0) {\n      return (factory(a0));\n    });\n  } else if (typeof module === 'object' && module.exports) {\n    // Node. Does not work with strict CommonJS, but\n    // only CommonJS-like environments that support module.exports,\n    // like Node.\n    module.exports = factory(require(\"jquery\"));\n  } else {\n    factory(root[\"jQuery\"]);\n  }\n}(this, function (jQuery) {\n\n(function ($) {\n  $.fn.selectpicker.defaults = {\n    noneSelectedText: 'Nič izbranega',\n    noneResultsText: 'Ni zadetkov za {0}',\n    countSelectedText: function (numSelected, numTotal) {\n      \"Število izbranih: {0}\";\n    },\n    maxOptionsText: function (numAll, numGroup) {\n      return [\n        'Omejitev dosežena (max. izbranih: {n})',\n        'Omejitev skupine dosežena (max. izbranih: {n})'\n      ];\n    },\n    selectAllText: 'Izberi vse',\n    deselectAllText: 'Počisti izbor',\n    multipleSeparator: ', '\n  };\n})(jQuery);\n\n\n}));\n"
  },
  {
    "path": "app_frontend/static/js/i18n/defaults-sv_SE.js",
    "content": "/*!\n * Bootstrap-select v1.12.2 (http://silviomoreto.github.io/bootstrap-select)\n *\n * Copyright 2013-2017 bootstrap-select\n * Licensed under MIT (https://github.com/silviomoreto/bootstrap-select/blob/master/LICENSE)\n */\n\n(function (root, factory) {\n  if (typeof define === 'function' && define.amd) {\n    // AMD. Register as an anonymous module unless amdModuleId is set\n    define([\"jquery\"], function (a0) {\n      return (factory(a0));\n    });\n  } else if (typeof module === 'object' && module.exports) {\n    // Node. Does not work with strict CommonJS, but\n    // only CommonJS-like environments that support module.exports,\n    // like Node.\n    module.exports = factory(require(\"jquery\"));\n  } else {\n    factory(root[\"jQuery\"]);\n  }\n}(this, function (jQuery) {\n\n(function ($) {\n  $.fn.selectpicker.defaults = {\n    noneSelectedText: 'Inget valt',\n    noneResultsText: 'Inget sökresultat matchar {0}',\n    countSelectedText: function (numSelected, numTotal) {\n      return (numSelected === 1) ? \"{0} alternativ valt\" : \"{0} alternativ valda\";\n    },\n    maxOptionsText: function (numAll, numGroup) {\n      return [\n        'Gräns uppnåd (max {n} alternativ)',\n        'Gräns uppnåd (max {n} gruppalternativ)'\n      ];\n    },\n    selectAllText: 'Markera alla',\n    deselectAllText: 'Avmarkera alla',\n    multipleSeparator: ', '\n  };\n})(jQuery);\n\n\n}));\n"
  },
  {
    "path": "app_frontend/static/js/i18n/defaults-tr_TR.js",
    "content": "/*!\n * Bootstrap-select v1.12.2 (http://silviomoreto.github.io/bootstrap-select)\n *\n * Copyright 2013-2017 bootstrap-select\n * Licensed under MIT (https://github.com/silviomoreto/bootstrap-select/blob/master/LICENSE)\n */\n\n(function (root, factory) {\n  if (typeof define === 'function' && define.amd) {\n    // AMD. Register as an anonymous module unless amdModuleId is set\n    define([\"jquery\"], function (a0) {\n      return (factory(a0));\n    });\n  } else if (typeof module === 'object' && module.exports) {\n    // Node. Does not work with strict CommonJS, but\n    // only CommonJS-like environments that support module.exports,\n    // like Node.\n    module.exports = factory(require(\"jquery\"));\n  } else {\n    factory(root[\"jQuery\"]);\n  }\n}(this, function (jQuery) {\n\n(function ($) {\n  $.fn.selectpicker.defaults = {\n    noneSelectedText: 'Hiçbiri seçilmedi',\n    noneResultsText: 'Hiçbir sonuç bulunamadı {0}',\n    countSelectedText: function (numSelected, numTotal) {\n      return (numSelected == 1) ? \"{0} öğe seçildi\" : \"{0} öğe seçildi\";\n    },\n    maxOptionsText: function (numAll, numGroup) {\n      return [\n        (numAll == 1) ? 'Limit aşıldı (maksimum {n} sayıda öğe )' : 'Limit aşıldı (maksimum {n} sayıda öğe)',\n        (numGroup == 1) ? 'Grup limiti aşıldı (maksimum {n} sayıda öğe)' : 'Grup limiti aşıldı (maksimum {n} sayıda öğe)'\n      ];\n    },\n    selectAllText: 'Tümünü Seç',\n    deselectAllText: 'Seçiniz',\n    multipleSeparator: ', '\n  };\n})(jQuery);\n\n\n}));\n"
  },
  {
    "path": "app_frontend/static/js/i18n/defaults-ua_UA.js",
    "content": "/*!\n * Bootstrap-select v1.12.2 (http://silviomoreto.github.io/bootstrap-select)\n *\n * Copyright 2013-2017 bootstrap-select\n * Licensed under MIT (https://github.com/silviomoreto/bootstrap-select/blob/master/LICENSE)\n */\n\n(function (root, factory) {\n  if (typeof define === 'function' && define.amd) {\n    // AMD. Register as an anonymous module unless amdModuleId is set\n    define([\"jquery\"], function (a0) {\n      return (factory(a0));\n    });\n  } else if (typeof module === 'object' && module.exports) {\n    // Node. Does not work with strict CommonJS, but\n    // only CommonJS-like environments that support module.exports,\n    // like Node.\n    module.exports = factory(require(\"jquery\"));\n  } else {\n    factory(root[\"jQuery\"]);\n  }\n}(this, function (jQuery) {\n\n(function ($) {\n  $.fn.selectpicker.defaults = {\n    noneSelectedText: 'Нічого не вибрано',\n    noneResultsText: 'Збігів не знайдено {0}',\n    countSelectedText: 'Вибрано {0} із {1}',\n    maxOptionsText: ['Досягнута межа ({n} {var} максимум)', 'Досягнута межа в групі ({n} {var} максимум)', ['items', 'item']],\n    multipleSeparator: ', '\n  };\n})(jQuery);\n\n\n}));\n"
  },
  {
    "path": "app_frontend/static/js/i18n/defaults-zh_CN.js",
    "content": "/*!\n * Bootstrap-select v1.12.2 (http://silviomoreto.github.io/bootstrap-select)\n *\n * Copyright 2013-2017 bootstrap-select\n * Licensed under MIT (https://github.com/silviomoreto/bootstrap-select/blob/master/LICENSE)\n */\n\n(function (root, factory) {\n  if (typeof define === 'function' && define.amd) {\n    // AMD. Register as an anonymous module unless amdModuleId is set\n    define([\"jquery\"], function (a0) {\n      return (factory(a0));\n    });\n  } else if (typeof module === 'object' && module.exports) {\n    // Node. Does not work with strict CommonJS, but\n    // only CommonJS-like environments that support module.exports,\n    // like Node.\n    module.exports = factory(require(\"jquery\"));\n  } else {\n    factory(root[\"jQuery\"]);\n  }\n}(this, function (jQuery) {\n\n(function ($) {\n  $.fn.selectpicker.defaults = {\n    noneSelectedText: '没有选中任何项',\n    noneResultsText: '没有找到匹配项',\n    countSelectedText: '选中{1}中的{0}项',\n    maxOptionsText: ['超出限制 (最多选择{n}项)', '组选择超出限制(最多选择{n}组)'],\n    multipleSeparator: ', '\n  };\n})(jQuery);\n\n\n}));\n"
  },
  {
    "path": "app_frontend/static/js/i18n/defaults-zh_TW.js",
    "content": "/*!\n * Bootstrap-select v1.12.2 (http://silviomoreto.github.io/bootstrap-select)\n *\n * Copyright 2013-2017 bootstrap-select\n * Licensed under MIT (https://github.com/silviomoreto/bootstrap-select/blob/master/LICENSE)\n */\n\n(function (root, factory) {\n  if (typeof define === 'function' && define.amd) {\n    // AMD. Register as an anonymous module unless amdModuleId is set\n    define([\"jquery\"], function (a0) {\n      return (factory(a0));\n    });\n  } else if (typeof module === 'object' && module.exports) {\n    // Node. Does not work with strict CommonJS, but\n    // only CommonJS-like environments that support module.exports,\n    // like Node.\n    module.exports = factory(require(\"jquery\"));\n  } else {\n    factory(root[\"jQuery\"]);\n  }\n}(this, function (jQuery) {\n\n(function ($) {\n  $.fn.selectpicker.defaults = {\n    noneSelectedText: '沒有選取任何項目',\n    noneResultsText: '沒有找到符合的結果',\n    countSelectedText: '已經選取{0}個項目',\n    maxOptionsText: ['超過限制 (最多選擇{n}項)', '超過限制(最多選擇{n}組)'],\n    selectAllText: '選取全部',\n    deselectAllText: '全部取消',\n    multipleSeparator: ', '\n  };\n})(jQuery);\n\n\n}));\n"
  },
  {
    "path": "app_frontend/static/js/npm.js",
    "content": "// This file is autogenerated via the `commonjs` Grunt task. You can require() this file in a CommonJS environment.\nrequire('../../js/transition.js')\nrequire('../../js/alert.js')\nrequire('../../js/button.js')\nrequire('../../js/carousel.js')\nrequire('../../js/collapse.js')\nrequire('../../js/dropdown.js')\nrequire('../../js/modal.js')\nrequire('../../js/tooltip.js')\nrequire('../../js/popover.js')\nrequire('../../js/scrollspy.js')\nrequire('../../js/tab.js')\nrequire('../../js/affix.js')"
  },
  {
    "path": "app_frontend/static/plugin/Chart/Chart.js",
    "content": "/*!\n * Chart.js\n * http://chartjs.org/\n * Version: 1.0.2\n *\n * Copyright 2015 Nick Downie\n * Released under the MIT license\n * https://github.com/nnnick/Chart.js/blob/master/LICENSE.md\n */\n\n\n(function(){\n\n\t\"use strict\";\n\n\t//Declare root variable - window in the browser, global on the server\n\tvar root = this,\n\t\tprevious = root.Chart;\n\n\t//Occupy the global variable of Chart, and create a simple base class\n\tvar Chart = function(context){\n\t\tvar chart = this;\n\t\tthis.canvas = context.canvas;\n\n\t\tthis.ctx = context;\n\n\t\t//Variables global to the chart\n\t\tvar computeDimension = function(element,dimension)\n\t\t{\n\t\t\tif (element['offset'+dimension])\n\t\t\t{\n\t\t\t\treturn element['offset'+dimension];\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\treturn document.defaultView.getComputedStyle(element).getPropertyValue(dimension);\n\t\t\t}\n\t\t};\n\n\t\tvar width = this.width = computeDimension(context.canvas,'Width') || context.canvas.width;\n\t\tvar height = this.height = computeDimension(context.canvas,'Height') || context.canvas.height;\n\n\t\twidth = this.width = context.canvas.width;\n\t\theight = this.height = context.canvas.height;\n\t\tthis.aspectRatio = this.width / this.height;\n\t\t//High pixel density displays - multiply the size of the canvas height/width by the device pixel ratio, then scale.\n\t\thelpers.retinaScale(this);\n\n\t\treturn this;\n\t};\n\t//Globally expose the defaults to allow for user updating/changing\n\tChart.defaults = {\n\t\tglobal: {\n\t\t\t// Boolean - Whether to animate the chart\n\t\t\tanimation: true,\n\n\t\t\t// Number - Number of animation steps\n\t\t\tanimationSteps: 60,\n\n\t\t\t// String - Animation easing effect\n\t\t\tanimationEasing: \"easeOutQuart\",\n\n\t\t\t// Boolean - If we should show the scale at all\n\t\t\tshowScale: true,\n\n\t\t\t// Boolean - If we want to override with a hard coded scale\n\t\t\tscaleOverride: false,\n\n\t\t\t// ** Required if scaleOverride is true **\n\t\t\t// Number - The number of steps in a hard coded scale\n\t\t\tscaleSteps: null,\n\t\t\t// Number - The value jump in the hard coded scale\n\t\t\tscaleStepWidth: null,\n\t\t\t// Number - The scale starting value\n\t\t\tscaleStartValue: null,\n\n\t\t\t// String - Colour of the scale line\n\t\t\tscaleLineColor: \"rgba(0,0,0,.1)\",\n\n\t\t\t// Number - Pixel width of the scale line\n\t\t\tscaleLineWidth: 1,\n\n\t\t\t// Boolean - Whether to show labels on the scale\n\t\t\tscaleShowLabels: true,\n\n\t\t\t// Interpolated JS string - can access value\n\t\t\tscaleLabel: \"<%=value%>\",\n\n\t\t\t// Boolean - Whether the scale should stick to integers, and not show any floats even if drawing space is there\n\t\t\tscaleIntegersOnly: true,\n\n\t\t\t// Boolean - Whether the scale should start at zero, or an order of magnitude down from the lowest value\n\t\t\tscaleBeginAtZero: false,\n\n\t\t\t// String - Scale label font declaration for the scale label\n\t\t\tscaleFontFamily: \"'Helvetica Neue', 'Helvetica', 'Arial', sans-serif\",\n\n\t\t\t// Number - Scale label font size in pixels\n\t\t\tscaleFontSize: 12,\n\n\t\t\t// String - Scale label font weight style\n\t\t\tscaleFontStyle: \"normal\",\n\n\t\t\t// String - Scale label font colour\n\t\t\tscaleFontColor: \"#666\",\n\n\t\t\t// Boolean - whether or not the chart should be responsive and resize when the browser does.\n\t\t\tresponsive: false,\n\n\t\t\t// Boolean - whether to maintain the starting aspect ratio or not when responsive, if set to false, will take up entire container\n\t\t\tmaintainAspectRatio: true,\n\n\t\t\t// Boolean - Determines whether to draw tooltips on the canvas or not - attaches events to touchmove & mousemove\n\t\t\tshowTooltips: true,\n\n\t\t\t// Boolean - Determines whether to draw built-in tooltip or call custom tooltip function\n\t\t\tcustomTooltips: false,\n\n\t\t\t// Array - Array of string names to attach tooltip events\n\t\t\ttooltipEvents: [\"mousemove\", \"touchstart\", \"touchmove\", \"mouseout\"],\n\n\t\t\t// String - Tooltip background colour\n\t\t\ttooltipFillColor: \"rgba(0,0,0,0.8)\",\n\n\t\t\t// String - Tooltip label font declaration for the scale label\n\t\t\ttooltipFontFamily: \"'Helvetica Neue', 'Helvetica', 'Arial', sans-serif\",\n\n\t\t\t// Number - Tooltip label font size in pixels\n\t\t\ttooltipFontSize: 14,\n\n\t\t\t// String - Tooltip font weight style\n\t\t\ttooltipFontStyle: \"normal\",\n\n\t\t\t// String - Tooltip label font colour\n\t\t\ttooltipFontColor: \"#fff\",\n\n\t\t\t// String - Tooltip title font declaration for the scale label\n\t\t\ttooltipTitleFontFamily: \"'Helvetica Neue', 'Helvetica', 'Arial', sans-serif\",\n\n\t\t\t// Number - Tooltip title font size in pixels\n\t\t\ttooltipTitleFontSize: 14,\n\n\t\t\t// String - Tooltip title font weight style\n\t\t\ttooltipTitleFontStyle: \"bold\",\n\n\t\t\t// String - Tooltip title font colour\n\t\t\ttooltipTitleFontColor: \"#fff\",\n\n\t\t\t// String - Tooltip title template\n\t\t\ttooltipTitleTemplate: \"<%= label%>\",\n\n\t\t\t// Number - pixel width of padding around tooltip text\n\t\t\ttooltipYPadding: 6,\n\n\t\t\t// Number - pixel width of padding around tooltip text\n\t\t\ttooltipXPadding: 6,\n\n\t\t\t// Number - Size of the caret on the tooltip\n\t\t\ttooltipCaretSize: 8,\n\n\t\t\t// Number - Pixel radius of the tooltip border\n\t\t\ttooltipCornerRadius: 6,\n\n\t\t\t// Number - Pixel offset from point x to tooltip edge\n\t\t\ttooltipXOffset: 10,\n\n\t\t\t// String - Template string for single tooltips\n\t\t\ttooltipTemplate: \"<%if (label){%><%=label%>: <%}%><%= value %>\",\n\n\t\t\t// String - Template string for single tooltips\n\t\t\tmultiTooltipTemplate: \"<%= datasetLabel %>: <%= value %>\",\n\n\t\t\t// String - Colour behind the legend colour block\n\t\t\tmultiTooltipKeyBackground: '#fff',\n\n\t\t\t// Array - A list of colors to use as the defaults\n\t\t\tsegmentColorDefault: [\"#A6CEE3\", \"#1F78B4\", \"#B2DF8A\", \"#33A02C\", \"#FB9A99\", \"#E31A1C\", \"#FDBF6F\", \"#FF7F00\", \"#CAB2D6\", \"#6A3D9A\", \"#B4B482\", \"#B15928\" ],\n\n\t\t\t// Array - A list of highlight colors to use as the defaults\n\t\t\tsegmentHighlightColorDefaults: [ \"#CEF6FF\", \"#47A0DC\", \"#DAFFB2\", \"#5BC854\", \"#FFC2C1\", \"#FF4244\", \"#FFE797\", \"#FFA728\", \"#F2DAFE\", \"#9265C2\", \"#DCDCAA\", \"#D98150\" ],\n\n\t\t\t// Function - Will fire on animation progression.\n\t\t\tonAnimationProgress: function(){},\n\n\t\t\t// Function - Will fire on animation completion.\n\t\t\tonAnimationComplete: function(){}\n\n\t\t}\n\t};\n\n\t//Create a dictionary of chart types, to allow for extension of existing types\n\tChart.types = {};\n\n\t//Global Chart helpers object for utility methods and classes\n\tvar helpers = Chart.helpers = {};\n\n\t\t//-- Basic js utility methods\n\tvar each = helpers.each = function(loopable,callback,self){\n\t\t\tvar additionalArgs = Array.prototype.slice.call(arguments, 3);\n\t\t\t// Check to see if null or undefined firstly.\n\t\t\tif (loopable){\n\t\t\t\tif (loopable.length === +loopable.length){\n\t\t\t\t\tvar i;\n\t\t\t\t\tfor (i=0; i<loopable.length; i++){\n\t\t\t\t\t\tcallback.apply(self,[loopable[i], i].concat(additionalArgs));\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\telse{\n\t\t\t\t\tfor (var item in loopable){\n\t\t\t\t\t\tcallback.apply(self,[loopable[item],item].concat(additionalArgs));\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\tclone = helpers.clone = function(obj){\n\t\t\tvar objClone = {};\n\t\t\teach(obj,function(value,key){\n\t\t\t\tif (obj.hasOwnProperty(key)){\n\t\t\t\t\tobjClone[key] = value;\n\t\t\t\t}\n\t\t\t});\n\t\t\treturn objClone;\n\t\t},\n\t\textend = helpers.extend = function(base){\n\t\t\teach(Array.prototype.slice.call(arguments,1), function(extensionObject) {\n\t\t\t\teach(extensionObject,function(value,key){\n\t\t\t\t\tif (extensionObject.hasOwnProperty(key)){\n\t\t\t\t\t\tbase[key] = value;\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t});\n\t\t\treturn base;\n\t\t},\n\t\tmerge = helpers.merge = function(base,master){\n\t\t\t//Merge properties in left object over to a shallow clone of object right.\n\t\t\tvar args = Array.prototype.slice.call(arguments,0);\n\t\t\targs.unshift({});\n\t\t\treturn extend.apply(null, args);\n\t\t},\n\t\tindexOf = helpers.indexOf = function(arrayToSearch, item){\n\t\t\tif (Array.prototype.indexOf) {\n\t\t\t\treturn arrayToSearch.indexOf(item);\n\t\t\t}\n\t\t\telse{\n\t\t\t\tfor (var i = 0; i < arrayToSearch.length; i++) {\n\t\t\t\t\tif (arrayToSearch[i] === item) return i;\n\t\t\t\t}\n\t\t\t\treturn -1;\n\t\t\t}\n\t\t},\n\t\twhere = helpers.where = function(collection, filterCallback){\n\t\t\tvar filtered = [];\n\n\t\t\thelpers.each(collection, function(item){\n\t\t\t\tif (filterCallback(item)){\n\t\t\t\t\tfiltered.push(item);\n\t\t\t\t}\n\t\t\t});\n\n\t\t\treturn filtered;\n\t\t},\n\t\tfindNextWhere = helpers.findNextWhere = function(arrayToSearch, filterCallback, startIndex){\n\t\t\t// Default to start of the array\n\t\t\tif (!startIndex){\n\t\t\t\tstartIndex = -1;\n\t\t\t}\n\t\t\tfor (var i = startIndex + 1; i < arrayToSearch.length; i++) {\n\t\t\t\tvar currentItem = arrayToSearch[i];\n\t\t\t\tif (filterCallback(currentItem)){\n\t\t\t\t\treturn currentItem;\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\tfindPreviousWhere = helpers.findPreviousWhere = function(arrayToSearch, filterCallback, startIndex){\n\t\t\t// Default to end of the array\n\t\t\tif (!startIndex){\n\t\t\t\tstartIndex = arrayToSearch.length;\n\t\t\t}\n\t\t\tfor (var i = startIndex - 1; i >= 0; i--) {\n\t\t\t\tvar currentItem = arrayToSearch[i];\n\t\t\t\tif (filterCallback(currentItem)){\n\t\t\t\t\treturn currentItem;\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\tinherits = helpers.inherits = function(extensions){\n\t\t\t//Basic javascript inheritance based on the model created in Backbone.js\n\t\t\tvar parent = this;\n\t\t\tvar ChartElement = (extensions && extensions.hasOwnProperty(\"constructor\")) ? extensions.constructor : function(){ return parent.apply(this, arguments); };\n\n\t\t\tvar Surrogate = function(){ this.constructor = ChartElement;};\n\t\t\tSurrogate.prototype = parent.prototype;\n\t\t\tChartElement.prototype = new Surrogate();\n\n\t\t\tChartElement.extend = inherits;\n\n\t\t\tif (extensions) extend(ChartElement.prototype, extensions);\n\n\t\t\tChartElement.__super__ = parent.prototype;\n\n\t\t\treturn ChartElement;\n\t\t},\n\t\tnoop = helpers.noop = function(){},\n\t\tuid = helpers.uid = (function(){\n\t\t\tvar id=0;\n\t\t\treturn function(){\n\t\t\t\treturn \"chart-\" + id++;\n\t\t\t};\n\t\t})(),\n\t\twarn = helpers.warn = function(str){\n\t\t\t//Method for warning of errors\n\t\t\tif (window.console && typeof window.console.warn === \"function\") console.warn(str);\n\t\t},\n\t\tamd = helpers.amd = (typeof define === 'function' && define.amd),\n\t\t//-- Math methods\n\t\tisNumber = helpers.isNumber = function(n){\n\t\t\treturn !isNaN(parseFloat(n)) && isFinite(n);\n\t\t},\n\t\tmax = helpers.max = function(array){\n\t\t\treturn Math.max.apply( Math, array );\n\t\t},\n\t\tmin = helpers.min = function(array){\n\t\t\treturn Math.min.apply( Math, array );\n\t\t},\n\t\tcap = helpers.cap = function(valueToCap,maxValue,minValue){\n\t\t\tif(isNumber(maxValue)) {\n\t\t\t\tif( valueToCap > maxValue ) {\n\t\t\t\t\treturn maxValue;\n\t\t\t\t}\n\t\t\t}\n\t\t\telse if(isNumber(minValue)){\n\t\t\t\tif ( valueToCap < minValue ){\n\t\t\t\t\treturn minValue;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn valueToCap;\n\t\t},\n\t\tgetDecimalPlaces = helpers.getDecimalPlaces = function(num){\n\t\t\tif (num%1!==0 && isNumber(num)){\n\t\t\t\tvar s = num.toString();\n\t\t\t\tif(s.indexOf(\"e-\") < 0){\n\t\t\t\t\t// no exponent, e.g. 0.01\n\t\t\t\t\treturn s.split(\".\")[1].length;\n\t\t\t\t}\n\t\t\t\telse if(s.indexOf(\".\") < 0) {\n\t\t\t\t\t// no decimal point, e.g. 1e-9\n\t\t\t\t\treturn parseInt(s.split(\"e-\")[1]);\n\t\t\t\t}\n\t\t\t\telse {\n\t\t\t\t\t// exponent and decimal point, e.g. 1.23e-9\n\t\t\t\t\tvar parts = s.split(\".\")[1].split(\"e-\");\n\t\t\t\t\treturn parts[0].length + parseInt(parts[1]);\n\t\t\t\t}\n\t\t\t}\n\t\t\telse {\n\t\t\t\treturn 0;\n\t\t\t}\n\t\t},\n\t\ttoRadians = helpers.radians = function(degrees){\n\t\t\treturn degrees * (Math.PI/180);\n\t\t},\n\t\t// Gets the angle from vertical upright to the point about a centre.\n\t\tgetAngleFromPoint = helpers.getAngleFromPoint = function(centrePoint, anglePoint){\n\t\t\tvar distanceFromXCenter = anglePoint.x - centrePoint.x,\n\t\t\t\tdistanceFromYCenter = anglePoint.y - centrePoint.y,\n\t\t\t\tradialDistanceFromCenter = Math.sqrt( distanceFromXCenter * distanceFromXCenter + distanceFromYCenter * distanceFromYCenter);\n\n\n\t\t\tvar angle = Math.PI * 2 + Math.atan2(distanceFromYCenter, distanceFromXCenter);\n\n\t\t\t//If the segment is in the top left quadrant, we need to add another rotation to the angle\n\t\t\tif (distanceFromXCenter < 0 && distanceFromYCenter < 0){\n\t\t\t\tangle += Math.PI*2;\n\t\t\t}\n\n\t\t\treturn {\n\t\t\t\tangle: angle,\n\t\t\t\tdistance: radialDistanceFromCenter\n\t\t\t};\n\t\t},\n\t\taliasPixel = helpers.aliasPixel = function(pixelWidth){\n\t\t\treturn (pixelWidth % 2 === 0) ? 0 : 0.5;\n\t\t},\n\t\tsplineCurve = helpers.splineCurve = function(FirstPoint,MiddlePoint,AfterPoint,t){\n\t\t\t//Props to Rob Spencer at scaled innovation for his post on splining between points\n\t\t\t//http://scaledinnovation.com/analytics/splines/aboutSplines.html\n\t\t\tvar d01=Math.sqrt(Math.pow(MiddlePoint.x-FirstPoint.x,2)+Math.pow(MiddlePoint.y-FirstPoint.y,2)),\n\t\t\t\td12=Math.sqrt(Math.pow(AfterPoint.x-MiddlePoint.x,2)+Math.pow(AfterPoint.y-MiddlePoint.y,2)),\n\t\t\t\tfa=t*d01/(d01+d12),// scaling factor for triangle Ta\n\t\t\t\tfb=t*d12/(d01+d12);\n\t\t\treturn {\n\t\t\t\tinner : {\n\t\t\t\t\tx : MiddlePoint.x-fa*(AfterPoint.x-FirstPoint.x),\n\t\t\t\t\ty : MiddlePoint.y-fa*(AfterPoint.y-FirstPoint.y)\n\t\t\t\t},\n\t\t\t\touter : {\n\t\t\t\t\tx: MiddlePoint.x+fb*(AfterPoint.x-FirstPoint.x),\n\t\t\t\t\ty : MiddlePoint.y+fb*(AfterPoint.y-FirstPoint.y)\n\t\t\t\t}\n\t\t\t};\n\t\t},\n\t\tcalculateOrderOfMagnitude = helpers.calculateOrderOfMagnitude = function(val){\n\t\t\treturn Math.floor(Math.log(val) / Math.LN10);\n\t\t},\n\t\tcalculateScaleRange = helpers.calculateScaleRange = function(valuesArray, drawingSize, textSize, startFromZero, integersOnly){\n\n\t\t\t//Set a minimum step of two - a point at the top of the graph, and a point at the base\n\t\t\tvar minSteps = 2,\n\t\t\t\tmaxSteps = Math.floor(drawingSize/(textSize * 1.5)),\n\t\t\t\tskipFitting = (minSteps >= maxSteps);\n\n\t\t\t// Filter out null values since these would min() to zero\n\t\t\tvar values = [];\n\t\t\teach(valuesArray, function( v ){\n\t\t\t\tv == null || values.push( v );\n\t\t\t});\n\t\t\tvar minValue = min(values),\n\t\t\t    maxValue = max(values);\n\n\t\t\t// We need some degree of separation here to calculate the scales if all the values are the same\n\t\t\t// Adding/minusing 0.5 will give us a range of 1.\n\t\t\tif (maxValue === minValue){\n\t\t\t\tmaxValue += 0.5;\n\t\t\t\t// So we don't end up with a graph with a negative start value if we've said always start from zero\n\t\t\t\tif (minValue >= 0.5 && !startFromZero){\n\t\t\t\t\tminValue -= 0.5;\n\t\t\t\t}\n\t\t\t\telse{\n\t\t\t\t\t// Make up a whole number above the values\n\t\t\t\t\tmaxValue += 0.5;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tvar\tvalueRange = Math.abs(maxValue - minValue),\n\t\t\t\trangeOrderOfMagnitude = calculateOrderOfMagnitude(valueRange),\n\t\t\t\tgraphMax = Math.ceil(maxValue / (1 * Math.pow(10, rangeOrderOfMagnitude))) * Math.pow(10, rangeOrderOfMagnitude),\n\t\t\t\tgraphMin = (startFromZero) ? 0 : Math.floor(minValue / (1 * Math.pow(10, rangeOrderOfMagnitude))) * Math.pow(10, rangeOrderOfMagnitude),\n\t\t\t\tgraphRange = graphMax - graphMin,\n\t\t\t\tstepValue = Math.pow(10, rangeOrderOfMagnitude),\n\t\t\t\tnumberOfSteps = Math.round(graphRange / stepValue);\n\n\t\t\t//If we have more space on the graph we'll use it to give more definition to the data\n\t\t\twhile((numberOfSteps > maxSteps || (numberOfSteps * 2) < maxSteps) && !skipFitting) {\n\t\t\t\tif(numberOfSteps > maxSteps){\n\t\t\t\t\tstepValue *=2;\n\t\t\t\t\tnumberOfSteps = Math.round(graphRange/stepValue);\n\t\t\t\t\t// Don't ever deal with a decimal number of steps - cancel fitting and just use the minimum number of steps.\n\t\t\t\t\tif (numberOfSteps % 1 !== 0){\n\t\t\t\t\t\tskipFitting = true;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\t//We can fit in double the amount of scale points on the scale\n\t\t\t\telse{\n\t\t\t\t\t//If user has declared ints only, and the step value isn't a decimal\n\t\t\t\t\tif (integersOnly && rangeOrderOfMagnitude >= 0){\n\t\t\t\t\t\t//If the user has said integers only, we need to check that making the scale more granular wouldn't make it a float\n\t\t\t\t\t\tif(stepValue/2 % 1 === 0){\n\t\t\t\t\t\t\tstepValue /=2;\n\t\t\t\t\t\t\tnumberOfSteps = Math.round(graphRange/stepValue);\n\t\t\t\t\t\t}\n\t\t\t\t\t\t//If it would make it a float break out of the loop\n\t\t\t\t\t\telse{\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\t//If the scale doesn't have to be an int, make the scale more granular anyway.\n\t\t\t\t\telse{\n\t\t\t\t\t\tstepValue /=2;\n\t\t\t\t\t\tnumberOfSteps = Math.round(graphRange/stepValue);\n\t\t\t\t\t}\n\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (skipFitting){\n\t\t\t\tnumberOfSteps = minSteps;\n\t\t\t\tstepValue = graphRange / numberOfSteps;\n\t\t\t}\n\n\t\t\treturn {\n\t\t\t\tsteps : numberOfSteps,\n\t\t\t\tstepValue : stepValue,\n\t\t\t\tmin : graphMin,\n\t\t\t\tmax\t: graphMin + (numberOfSteps * stepValue)\n\t\t\t};\n\n\t\t},\n\t\t/* jshint ignore:start */\n\t\t// Blows up jshint errors based on the new Function constructor\n\t\t//Templating methods\n\t\t//Javascript micro templating by John Resig - source at http://ejohn.org/blog/javascript-micro-templating/\n\t\ttemplate = helpers.template = function(templateString, valuesObject){\n\n\t\t\t// If templateString is function rather than string-template - call the function for valuesObject\n\n\t\t\tif(templateString instanceof Function){\n\t\t\t \treturn templateString(valuesObject);\n\t\t \t}\n\n\t\t\tvar cache = {};\n\t\t\tfunction tmpl(str, data){\n\t\t\t\t// Figure out if we're getting a template, or if we need to\n\t\t\t\t// load the template - and be sure to cache the result.\n\t\t\t\tvar fn = !/\\W/.test(str) ?\n\t\t\t\tcache[str] = cache[str] :\n\n\t\t\t\t// Generate a reusable function that will serve as a template\n\t\t\t\t// generator (and which will be cached).\n\t\t\t\tnew Function(\"obj\",\n\t\t\t\t\t\"var p=[],print=function(){p.push.apply(p,arguments);};\" +\n\n\t\t\t\t\t// Introduce the data as local variables using with(){}\n\t\t\t\t\t\"with(obj){p.push('\" +\n\n\t\t\t\t\t// Convert the template into pure JavaScript\n\t\t\t\t\tstr\n\t\t\t\t\t\t.replace(/[\\r\\t\\n]/g, \" \")\n\t\t\t\t\t\t.split(\"<%\").join(\"\\t\")\n\t\t\t\t\t\t.replace(/((^|%>)[^\\t]*)'/g, \"$1\\r\")\n\t\t\t\t\t\t.replace(/\\t=(.*?)%>/g, \"',$1,'\")\n\t\t\t\t\t\t.split(\"\\t\").join(\"');\")\n\t\t\t\t\t\t.split(\"%>\").join(\"p.push('\")\n\t\t\t\t\t\t.split(\"\\r\").join(\"\\\\'\") +\n\t\t\t\t\t\"');}return p.join('');\"\n\t\t\t\t);\n\n\t\t\t\t// Provide some basic currying to the user\n\t\t\t\treturn data ? fn( data ) : fn;\n\t\t\t}\n\t\t\treturn tmpl(templateString,valuesObject);\n\t\t},\n\t\t/* jshint ignore:end */\n\t\tgenerateLabels = helpers.generateLabels = function(templateString,numberOfSteps,graphMin,stepValue){\n\t\t\tvar labelsArray = new Array(numberOfSteps);\n\t\t\tif (templateString){\n\t\t\t\teach(labelsArray,function(val,index){\n\t\t\t\t\tlabelsArray[index] = template(templateString,{value: (graphMin + (stepValue*(index+1)))});\n\t\t\t\t});\n\t\t\t}\n\t\t\treturn labelsArray;\n\t\t},\n\t\t//--Animation methods\n\t\t//Easing functions adapted from Robert Penner's easing equations\n\t\t//http://www.robertpenner.com/easing/\n\t\teasingEffects = helpers.easingEffects = {\n\t\t\tlinear: function (t) {\n\t\t\t\treturn t;\n\t\t\t},\n\t\t\teaseInQuad: function (t) {\n\t\t\t\treturn t * t;\n\t\t\t},\n\t\t\teaseOutQuad: function (t) {\n\t\t\t\treturn -1 * t * (t - 2);\n\t\t\t},\n\t\t\teaseInOutQuad: function (t) {\n\t\t\t\tif ((t /= 1 / 2) < 1){\n\t\t\t\t\treturn 1 / 2 * t * t;\n\t\t\t\t}\n\t\t\t\treturn -1 / 2 * ((--t) * (t - 2) - 1);\n\t\t\t},\n\t\t\teaseInCubic: function (t) {\n\t\t\t\treturn t * t * t;\n\t\t\t},\n\t\t\teaseOutCubic: function (t) {\n\t\t\t\treturn 1 * ((t = t / 1 - 1) * t * t + 1);\n\t\t\t},\n\t\t\teaseInOutCubic: function (t) {\n\t\t\t\tif ((t /= 1 / 2) < 1){\n\t\t\t\t\treturn 1 / 2 * t * t * t;\n\t\t\t\t}\n\t\t\t\treturn 1 / 2 * ((t -= 2) * t * t + 2);\n\t\t\t},\n\t\t\teaseInQuart: function (t) {\n\t\t\t\treturn t * t * t * t;\n\t\t\t},\n\t\t\teaseOutQuart: function (t) {\n\t\t\t\treturn -1 * ((t = t / 1 - 1) * t * t * t - 1);\n\t\t\t},\n\t\t\teaseInOutQuart: function (t) {\n\t\t\t\tif ((t /= 1 / 2) < 1){\n\t\t\t\t\treturn 1 / 2 * t * t * t * t;\n\t\t\t\t}\n\t\t\t\treturn -1 / 2 * ((t -= 2) * t * t * t - 2);\n\t\t\t},\n\t\t\teaseInQuint: function (t) {\n\t\t\t\treturn 1 * (t /= 1) * t * t * t * t;\n\t\t\t},\n\t\t\teaseOutQuint: function (t) {\n\t\t\t\treturn 1 * ((t = t / 1 - 1) * t * t * t * t + 1);\n\t\t\t},\n\t\t\teaseInOutQuint: function (t) {\n\t\t\t\tif ((t /= 1 / 2) < 1){\n\t\t\t\t\treturn 1 / 2 * t * t * t * t * t;\n\t\t\t\t}\n\t\t\t\treturn 1 / 2 * ((t -= 2) * t * t * t * t + 2);\n\t\t\t},\n\t\t\teaseInSine: function (t) {\n\t\t\t\treturn -1 * Math.cos(t / 1 * (Math.PI / 2)) + 1;\n\t\t\t},\n\t\t\teaseOutSine: function (t) {\n\t\t\t\treturn 1 * Math.sin(t / 1 * (Math.PI / 2));\n\t\t\t},\n\t\t\teaseInOutSine: function (t) {\n\t\t\t\treturn -1 / 2 * (Math.cos(Math.PI * t / 1) - 1);\n\t\t\t},\n\t\t\teaseInExpo: function (t) {\n\t\t\t\treturn (t === 0) ? 1 : 1 * Math.pow(2, 10 * (t / 1 - 1));\n\t\t\t},\n\t\t\teaseOutExpo: function (t) {\n\t\t\t\treturn (t === 1) ? 1 : 1 * (-Math.pow(2, -10 * t / 1) + 1);\n\t\t\t},\n\t\t\teaseInOutExpo: function (t) {\n\t\t\t\tif (t === 0){\n\t\t\t\t\treturn 0;\n\t\t\t\t}\n\t\t\t\tif (t === 1){\n\t\t\t\t\treturn 1;\n\t\t\t\t}\n\t\t\t\tif ((t /= 1 / 2) < 1){\n\t\t\t\t\treturn 1 / 2 * Math.pow(2, 10 * (t - 1));\n\t\t\t\t}\n\t\t\t\treturn 1 / 2 * (-Math.pow(2, -10 * --t) + 2);\n\t\t\t},\n\t\t\teaseInCirc: function (t) {\n\t\t\t\tif (t >= 1){\n\t\t\t\t\treturn t;\n\t\t\t\t}\n\t\t\t\treturn -1 * (Math.sqrt(1 - (t /= 1) * t) - 1);\n\t\t\t},\n\t\t\teaseOutCirc: function (t) {\n\t\t\t\treturn 1 * Math.sqrt(1 - (t = t / 1 - 1) * t);\n\t\t\t},\n\t\t\teaseInOutCirc: function (t) {\n\t\t\t\tif ((t /= 1 / 2) < 1){\n\t\t\t\t\treturn -1 / 2 * (Math.sqrt(1 - t * t) - 1);\n\t\t\t\t}\n\t\t\t\treturn 1 / 2 * (Math.sqrt(1 - (t -= 2) * t) + 1);\n\t\t\t},\n\t\t\teaseInElastic: function (t) {\n\t\t\t\tvar s = 1.70158;\n\t\t\t\tvar p = 0;\n\t\t\t\tvar a = 1;\n\t\t\t\tif (t === 0){\n\t\t\t\t\treturn 0;\n\t\t\t\t}\n\t\t\t\tif ((t /= 1) == 1){\n\t\t\t\t\treturn 1;\n\t\t\t\t}\n\t\t\t\tif (!p){\n\t\t\t\t\tp = 1 * 0.3;\n\t\t\t\t}\n\t\t\t\tif (a < Math.abs(1)) {\n\t\t\t\t\ta = 1;\n\t\t\t\t\ts = p / 4;\n\t\t\t\t} else{\n\t\t\t\t\ts = p / (2 * Math.PI) * Math.asin(1 / a);\n\t\t\t\t}\n\t\t\t\treturn -(a * Math.pow(2, 10 * (t -= 1)) * Math.sin((t * 1 - s) * (2 * Math.PI) / p));\n\t\t\t},\n\t\t\teaseOutElastic: function (t) {\n\t\t\t\tvar s = 1.70158;\n\t\t\t\tvar p = 0;\n\t\t\t\tvar a = 1;\n\t\t\t\tif (t === 0){\n\t\t\t\t\treturn 0;\n\t\t\t\t}\n\t\t\t\tif ((t /= 1) == 1){\n\t\t\t\t\treturn 1;\n\t\t\t\t}\n\t\t\t\tif (!p){\n\t\t\t\t\tp = 1 * 0.3;\n\t\t\t\t}\n\t\t\t\tif (a < Math.abs(1)) {\n\t\t\t\t\ta = 1;\n\t\t\t\t\ts = p / 4;\n\t\t\t\t} else{\n\t\t\t\t\ts = p / (2 * Math.PI) * Math.asin(1 / a);\n\t\t\t\t}\n\t\t\t\treturn a * Math.pow(2, -10 * t) * Math.sin((t * 1 - s) * (2 * Math.PI) / p) + 1;\n\t\t\t},\n\t\t\teaseInOutElastic: function (t) {\n\t\t\t\tvar s = 1.70158;\n\t\t\t\tvar p = 0;\n\t\t\t\tvar a = 1;\n\t\t\t\tif (t === 0){\n\t\t\t\t\treturn 0;\n\t\t\t\t}\n\t\t\t\tif ((t /= 1 / 2) == 2){\n\t\t\t\t\treturn 1;\n\t\t\t\t}\n\t\t\t\tif (!p){\n\t\t\t\t\tp = 1 * (0.3 * 1.5);\n\t\t\t\t}\n\t\t\t\tif (a < Math.abs(1)) {\n\t\t\t\t\ta = 1;\n\t\t\t\t\ts = p / 4;\n\t\t\t\t} else {\n\t\t\t\t\ts = p / (2 * Math.PI) * Math.asin(1 / a);\n\t\t\t\t}\n\t\t\t\tif (t < 1){\n\t\t\t\t\treturn -0.5 * (a * Math.pow(2, 10 * (t -= 1)) * Math.sin((t * 1 - s) * (2 * Math.PI) / p));}\n\t\t\t\treturn a * Math.pow(2, -10 * (t -= 1)) * Math.sin((t * 1 - s) * (2 * Math.PI) / p) * 0.5 + 1;\n\t\t\t},\n\t\t\teaseInBack: function (t) {\n\t\t\t\tvar s = 1.70158;\n\t\t\t\treturn 1 * (t /= 1) * t * ((s + 1) * t - s);\n\t\t\t},\n\t\t\teaseOutBack: function (t) {\n\t\t\t\tvar s = 1.70158;\n\t\t\t\treturn 1 * ((t = t / 1 - 1) * t * ((s + 1) * t + s) + 1);\n\t\t\t},\n\t\t\teaseInOutBack: function (t) {\n\t\t\t\tvar s = 1.70158;\n\t\t\t\tif ((t /= 1 / 2) < 1){\n\t\t\t\t\treturn 1 / 2 * (t * t * (((s *= (1.525)) + 1) * t - s));\n\t\t\t\t}\n\t\t\t\treturn 1 / 2 * ((t -= 2) * t * (((s *= (1.525)) + 1) * t + s) + 2);\n\t\t\t},\n\t\t\teaseInBounce: function (t) {\n\t\t\t\treturn 1 - easingEffects.easeOutBounce(1 - t);\n\t\t\t},\n\t\t\teaseOutBounce: function (t) {\n\t\t\t\tif ((t /= 1) < (1 / 2.75)) {\n\t\t\t\t\treturn 1 * (7.5625 * t * t);\n\t\t\t\t} else if (t < (2 / 2.75)) {\n\t\t\t\t\treturn 1 * (7.5625 * (t -= (1.5 / 2.75)) * t + 0.75);\n\t\t\t\t} else if (t < (2.5 / 2.75)) {\n\t\t\t\t\treturn 1 * (7.5625 * (t -= (2.25 / 2.75)) * t + 0.9375);\n\t\t\t\t} else {\n\t\t\t\t\treturn 1 * (7.5625 * (t -= (2.625 / 2.75)) * t + 0.984375);\n\t\t\t\t}\n\t\t\t},\n\t\t\teaseInOutBounce: function (t) {\n\t\t\t\tif (t < 1 / 2){\n\t\t\t\t\treturn easingEffects.easeInBounce(t * 2) * 0.5;\n\t\t\t\t}\n\t\t\t\treturn easingEffects.easeOutBounce(t * 2 - 1) * 0.5 + 1 * 0.5;\n\t\t\t}\n\t\t},\n\t\t//Request animation polyfill - http://www.paulirish.com/2011/requestanimationframe-for-smart-animating/\n\t\trequestAnimFrame = helpers.requestAnimFrame = (function(){\n\t\t\treturn window.requestAnimationFrame ||\n\t\t\t\twindow.webkitRequestAnimationFrame ||\n\t\t\t\twindow.mozRequestAnimationFrame ||\n\t\t\t\twindow.oRequestAnimationFrame ||\n\t\t\t\twindow.msRequestAnimationFrame ||\n\t\t\t\tfunction(callback) {\n\t\t\t\t\treturn window.setTimeout(callback, 1000 / 60);\n\t\t\t\t};\n\t\t})(),\n\t\tcancelAnimFrame = helpers.cancelAnimFrame = (function(){\n\t\t\treturn window.cancelAnimationFrame ||\n\t\t\t\twindow.webkitCancelAnimationFrame ||\n\t\t\t\twindow.mozCancelAnimationFrame ||\n\t\t\t\twindow.oCancelAnimationFrame ||\n\t\t\t\twindow.msCancelAnimationFrame ||\n\t\t\t\tfunction(callback) {\n\t\t\t\t\treturn window.clearTimeout(callback, 1000 / 60);\n\t\t\t\t};\n\t\t})(),\n\t\tanimationLoop = helpers.animationLoop = function(callback,totalSteps,easingString,onProgress,onComplete,chartInstance){\n\n\t\t\tvar currentStep = 0,\n\t\t\t\teasingFunction = easingEffects[easingString] || easingEffects.linear;\n\n\t\t\tvar animationFrame = function(){\n\t\t\t\tcurrentStep++;\n\t\t\t\tvar stepDecimal = currentStep/totalSteps;\n\t\t\t\tvar easeDecimal = easingFunction(stepDecimal);\n\n\t\t\t\tcallback.call(chartInstance,easeDecimal,stepDecimal, currentStep);\n\t\t\t\tonProgress.call(chartInstance,easeDecimal,stepDecimal);\n\t\t\t\tif (currentStep < totalSteps){\n\t\t\t\t\tchartInstance.animationFrame = requestAnimFrame(animationFrame);\n\t\t\t\t} else{\n\t\t\t\t\tonComplete.apply(chartInstance);\n\t\t\t\t}\n\t\t\t};\n\t\t\trequestAnimFrame(animationFrame);\n\t\t},\n\t\t//-- DOM methods\n\t\tgetRelativePosition = helpers.getRelativePosition = function(evt){\n\t\t\tvar mouseX, mouseY;\n\t\t\tvar e = evt.originalEvent || evt,\n\t\t\t\tcanvas = evt.currentTarget || evt.srcElement,\n\t\t\t\tboundingRect = canvas.getBoundingClientRect();\n\n\t\t\tif (e.touches){\n\t\t\t\tmouseX = e.touches[0].clientX - boundingRect.left;\n\t\t\t\tmouseY = e.touches[0].clientY - boundingRect.top;\n\n\t\t\t}\n\t\t\telse{\n\t\t\t\tmouseX = e.clientX - boundingRect.left;\n\t\t\t\tmouseY = e.clientY - boundingRect.top;\n\t\t\t}\n\n\t\t\treturn {\n\t\t\t\tx : mouseX,\n\t\t\t\ty : mouseY\n\t\t\t};\n\n\t\t},\n\t\taddEvent = helpers.addEvent = function(node,eventType,method){\n\t\t\tif (node.addEventListener){\n\t\t\t\tnode.addEventListener(eventType,method);\n\t\t\t} else if (node.attachEvent){\n\t\t\t\tnode.attachEvent(\"on\"+eventType, method);\n\t\t\t} else {\n\t\t\t\tnode[\"on\"+eventType] = method;\n\t\t\t}\n\t\t},\n\t\tremoveEvent = helpers.removeEvent = function(node, eventType, handler){\n\t\t\tif (node.removeEventListener){\n\t\t\t\tnode.removeEventListener(eventType, handler, false);\n\t\t\t} else if (node.detachEvent){\n\t\t\t\tnode.detachEvent(\"on\"+eventType,handler);\n\t\t\t} else{\n\t\t\t\tnode[\"on\" + eventType] = noop;\n\t\t\t}\n\t\t},\n\t\tbindEvents = helpers.bindEvents = function(chartInstance, arrayOfEvents, handler){\n\t\t\t// Create the events object if it's not already present\n\t\t\tif (!chartInstance.events) chartInstance.events = {};\n\n\t\t\teach(arrayOfEvents,function(eventName){\n\t\t\t\tchartInstance.events[eventName] = function(){\n\t\t\t\t\thandler.apply(chartInstance, arguments);\n\t\t\t\t};\n\t\t\t\taddEvent(chartInstance.chart.canvas,eventName,chartInstance.events[eventName]);\n\t\t\t});\n\t\t},\n\t\tunbindEvents = helpers.unbindEvents = function (chartInstance, arrayOfEvents) {\n\t\t\teach(arrayOfEvents, function(handler,eventName){\n\t\t\t\tremoveEvent(chartInstance.chart.canvas, eventName, handler);\n\t\t\t});\n\t\t},\n\t\tgetMaximumWidth = helpers.getMaximumWidth = function(domNode){\n\t\t\tvar container = domNode.parentNode,\n\t\t\t    padding = parseInt(getStyle(container, 'padding-left')) + parseInt(getStyle(container, 'padding-right'));\n\t\t\t// TODO = check cross browser stuff with this.\n\t\t\treturn container ? container.clientWidth - padding : 0;\n\t\t},\n\t\tgetMaximumHeight = helpers.getMaximumHeight = function(domNode){\n\t\t\tvar container = domNode.parentNode,\n\t\t\t    padding = parseInt(getStyle(container, 'padding-bottom')) + parseInt(getStyle(container, 'padding-top'));\n\t\t\t// TODO = check cross browser stuff with this.\n\t\t\treturn container ? container.clientHeight - padding : 0;\n\t\t},\n\t\tgetStyle = helpers.getStyle = function (el, property) {\n\t\t\treturn el.currentStyle ?\n\t\t\t\tel.currentStyle[property] :\n\t\t\t\tdocument.defaultView.getComputedStyle(el, null).getPropertyValue(property);\n\t\t},\n\t\tgetMaximumSize = helpers.getMaximumSize = helpers.getMaximumWidth, // legacy support\n\t\tretinaScale = helpers.retinaScale = function(chart){\n\t\t\tvar ctx = chart.ctx,\n\t\t\t\twidth = chart.canvas.width,\n\t\t\t\theight = chart.canvas.height;\n\n\t\t\tif (window.devicePixelRatio) {\n\t\t\t\tctx.canvas.style.width = width + \"px\";\n\t\t\t\tctx.canvas.style.height = height + \"px\";\n\t\t\t\tctx.canvas.height = height * window.devicePixelRatio;\n\t\t\t\tctx.canvas.width = width * window.devicePixelRatio;\n\t\t\t\tctx.scale(window.devicePixelRatio, window.devicePixelRatio);\n\t\t\t}\n\t\t},\n\t\t//-- Canvas methods\n\t\tclear = helpers.clear = function(chart){\n\t\t\tchart.ctx.clearRect(0,0,chart.width,chart.height);\n\t\t},\n\t\tfontString = helpers.fontString = function(pixelSize,fontStyle,fontFamily){\n\t\t\treturn fontStyle + \" \" + pixelSize+\"px \" + fontFamily;\n\t\t},\n\t\tlongestText = helpers.longestText = function(ctx,font,arrayOfStrings){\n\t\t\tctx.font = font;\n\t\t\tvar longest = 0;\n\t\t\teach(arrayOfStrings,function(string){\n\t\t\t\tvar textWidth = ctx.measureText(string).width;\n\t\t\t\tlongest = (textWidth > longest) ? textWidth : longest;\n\t\t\t});\n\t\t\treturn longest;\n\t\t},\n\t\tdrawRoundedRectangle = helpers.drawRoundedRectangle = function(ctx,x,y,width,height,radius){\n\t\t\tctx.beginPath();\n\t\t\tctx.moveTo(x + radius, y);\n\t\t\tctx.lineTo(x + width - radius, y);\n\t\t\tctx.quadraticCurveTo(x + width, y, x + width, y + radius);\n\t\t\tctx.lineTo(x + width, y + height - radius);\n\t\t\tctx.quadraticCurveTo(x + width, y + height, x + width - radius, y + height);\n\t\t\tctx.lineTo(x + radius, y + height);\n\t\t\tctx.quadraticCurveTo(x, y + height, x, y + height - radius);\n\t\t\tctx.lineTo(x, y + radius);\n\t\t\tctx.quadraticCurveTo(x, y, x + radius, y);\n\t\t\tctx.closePath();\n\t\t};\n\n\n\t//Store a reference to each instance - allowing us to globally resize chart instances on window resize.\n\t//Destroy method on the chart will remove the instance of the chart from this reference.\n\tChart.instances = {};\n\n\tChart.Type = function(data,options,chart){\n\t\tthis.options = options;\n\t\tthis.chart = chart;\n\t\tthis.id = uid();\n\t\t//Add the chart instance to the global namespace\n\t\tChart.instances[this.id] = this;\n\n\t\t// Initialize is always called when a chart type is created\n\t\t// By default it is a no op, but it should be extended\n\t\tif (options.responsive){\n\t\t\tthis.resize();\n\t\t}\n\t\tthis.initialize.call(this,data);\n\t};\n\n\t//Core methods that'll be a part of every chart type\n\textend(Chart.Type.prototype,{\n\t\tinitialize : function(){return this;},\n\t\tclear : function(){\n\t\t\tclear(this.chart);\n\t\t\treturn this;\n\t\t},\n\t\tstop : function(){\n\t\t\t// Stops any current animation loop occuring\n\t\t\tChart.animationService.cancelAnimation(this);\n\t\t\treturn this;\n\t\t},\n\t\tresize : function(callback){\n\t\t\tthis.stop();\n\t\t\tvar canvas = this.chart.canvas,\n\t\t\t\tnewWidth = getMaximumWidth(this.chart.canvas),\n\t\t\t\tnewHeight = this.options.maintainAspectRatio ? newWidth / this.chart.aspectRatio : getMaximumHeight(this.chart.canvas);\n\n\t\t\tcanvas.width = this.chart.width = newWidth;\n\t\t\tcanvas.height = this.chart.height = newHeight;\n\n\t\t\tretinaScale(this.chart);\n\n\t\t\tif (typeof callback === \"function\"){\n\t\t\t\tcallback.apply(this, Array.prototype.slice.call(arguments, 1));\n\t\t\t}\n\t\t\treturn this;\n\t\t},\n\t\treflow : noop,\n\t\trender : function(reflow){\n\t\t\tif (reflow){\n\t\t\t\tthis.reflow();\n\t\t\t}\n\t\t\t\n\t\t\tif (this.options.animation && !reflow){\n\t\t\t\tvar animation = new Chart.Animation();\n\t\t\t\tanimation.numSteps = this.options.animationSteps;\n\t\t\t\tanimation.easing = this.options.animationEasing;\n\t\t\t\t\n\t\t\t\t// render function\n\t\t\t\tanimation.render = function(chartInstance, animationObject) {\n\t\t\t\t\tvar easingFunction = helpers.easingEffects[animationObject.easing];\n\t\t\t\t\tvar stepDecimal = animationObject.currentStep / animationObject.numSteps;\n\t\t\t\t\tvar easeDecimal = easingFunction(stepDecimal);\n\t\t\t\t\t\n\t\t\t\t\tchartInstance.draw(easeDecimal, stepDecimal, animationObject.currentStep);\n\t\t\t\t};\n\t\t\t\t\n\t\t\t\t// user events\n\t\t\t\tanimation.onAnimationProgress = this.options.onAnimationProgress;\n\t\t\t\tanimation.onAnimationComplete = this.options.onAnimationComplete;\n\t\t\t\t\n\t\t\t\tChart.animationService.addAnimation(this, animation);\n\t\t\t}\n\t\t\telse{\n\t\t\t\tthis.draw();\n\t\t\t\tthis.options.onAnimationComplete.call(this);\n\t\t\t}\n\t\t\treturn this;\n\t\t},\n\t\tgenerateLegend : function(){\n\t\t\treturn template(this.options.legendTemplate,this);\n\t\t},\n\t\tdestroy : function(){\n\t\t\tthis.clear();\n\t\t\tunbindEvents(this, this.events);\n\t\t\tvar canvas = this.chart.canvas;\n\n\t\t\t// Reset canvas height/width attributes starts a fresh with the canvas context\n\t\t\tcanvas.width = this.chart.width;\n\t\t\tcanvas.height = this.chart.height;\n\n\t\t\t// < IE9 doesn't support removeProperty\n\t\t\tif (canvas.style.removeProperty) {\n\t\t\t\tcanvas.style.removeProperty('width');\n\t\t\t\tcanvas.style.removeProperty('height');\n\t\t\t} else {\n\t\t\t\tcanvas.style.removeAttribute('width');\n\t\t\t\tcanvas.style.removeAttribute('height');\n\t\t\t}\n\n\t\t\tdelete Chart.instances[this.id];\n\t\t},\n\t\tshowTooltip : function(ChartElements, forceRedraw){\n\t\t\t// Only redraw the chart if we've actually changed what we're hovering on.\n\t\t\tif (typeof this.activeElements === 'undefined') this.activeElements = [];\n\n\t\t\tvar isChanged = (function(Elements){\n\t\t\t\tvar changed = false;\n\n\t\t\t\tif (Elements.length !== this.activeElements.length){\n\t\t\t\t\tchanged = true;\n\t\t\t\t\treturn changed;\n\t\t\t\t}\n\n\t\t\t\teach(Elements, function(element, index){\n\t\t\t\t\tif (element !== this.activeElements[index]){\n\t\t\t\t\t\tchanged = true;\n\t\t\t\t\t}\n\t\t\t\t}, this);\n\t\t\t\treturn changed;\n\t\t\t}).call(this, ChartElements);\n\n\t\t\tif (!isChanged && !forceRedraw){\n\t\t\t\treturn;\n\t\t\t}\n\t\t\telse{\n\t\t\t\tthis.activeElements = ChartElements;\n\t\t\t}\n\t\t\tthis.draw();\n\t\t\tif(this.options.customTooltips){\n\t\t\t\tthis.options.customTooltips(false);\n\t\t\t}\n\t\t\tif (ChartElements.length > 0){\n\t\t\t\t// If we have multiple datasets, show a MultiTooltip for all of the data points at that index\n\t\t\t\tif (this.datasets && this.datasets.length > 1) {\n\t\t\t\t\tvar dataArray,\n\t\t\t\t\t\tdataIndex;\n\n\t\t\t\t\tfor (var i = this.datasets.length - 1; i >= 0; i--) {\n\t\t\t\t\t\tdataArray = this.datasets[i].points || this.datasets[i].bars || this.datasets[i].segments;\n\t\t\t\t\t\tdataIndex = indexOf(dataArray, ChartElements[0]);\n\t\t\t\t\t\tif (dataIndex !== -1){\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tvar tooltipLabels = [],\n\t\t\t\t\t\ttooltipColors = [],\n\t\t\t\t\t\tmedianPosition = (function(index) {\n\n\t\t\t\t\t\t\t// Get all the points at that particular index\n\t\t\t\t\t\t\tvar Elements = [],\n\t\t\t\t\t\t\t\tdataCollection,\n\t\t\t\t\t\t\t\txPositions = [],\n\t\t\t\t\t\t\t\tyPositions = [],\n\t\t\t\t\t\t\t\txMax,\n\t\t\t\t\t\t\t\tyMax,\n\t\t\t\t\t\t\t\txMin,\n\t\t\t\t\t\t\t\tyMin;\n\t\t\t\t\t\t\thelpers.each(this.datasets, function(dataset){\n\t\t\t\t\t\t\t\tdataCollection = dataset.points || dataset.bars || dataset.segments;\n\t\t\t\t\t\t\t\tif (dataCollection[dataIndex] && dataCollection[dataIndex].hasValue()){\n\t\t\t\t\t\t\t\t\tElements.push(dataCollection[dataIndex]);\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t});\n\n\t\t\t\t\t\t\thelpers.each(Elements, function(element) {\n\t\t\t\t\t\t\t\txPositions.push(element.x);\n\t\t\t\t\t\t\t\tyPositions.push(element.y);\n\n\n\t\t\t\t\t\t\t\t//Include any colour information about the element\n\t\t\t\t\t\t\t\ttooltipLabels.push(helpers.template(this.options.multiTooltipTemplate, element));\n\t\t\t\t\t\t\t\ttooltipColors.push({\n\t\t\t\t\t\t\t\t\tfill: element._saved.fillColor || element.fillColor,\n\t\t\t\t\t\t\t\t\tstroke: element._saved.strokeColor || element.strokeColor\n\t\t\t\t\t\t\t\t});\n\n\t\t\t\t\t\t\t}, this);\n\n\t\t\t\t\t\t\tyMin = min(yPositions);\n\t\t\t\t\t\t\tyMax = max(yPositions);\n\n\t\t\t\t\t\t\txMin = min(xPositions);\n\t\t\t\t\t\t\txMax = max(xPositions);\n\n\t\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\t\tx: (xMin > this.chart.width/2) ? xMin : xMax,\n\t\t\t\t\t\t\t\ty: (yMin + yMax)/2\n\t\t\t\t\t\t\t};\n\t\t\t\t\t\t}).call(this, dataIndex);\n\n\t\t\t\t\tnew Chart.MultiTooltip({\n\t\t\t\t\t\tx: medianPosition.x,\n\t\t\t\t\t\ty: medianPosition.y,\n\t\t\t\t\t\txPadding: this.options.tooltipXPadding,\n\t\t\t\t\t\tyPadding: this.options.tooltipYPadding,\n\t\t\t\t\t\txOffset: this.options.tooltipXOffset,\n\t\t\t\t\t\tfillColor: this.options.tooltipFillColor,\n\t\t\t\t\t\ttextColor: this.options.tooltipFontColor,\n\t\t\t\t\t\tfontFamily: this.options.tooltipFontFamily,\n\t\t\t\t\t\tfontStyle: this.options.tooltipFontStyle,\n\t\t\t\t\t\tfontSize: this.options.tooltipFontSize,\n\t\t\t\t\t\ttitleTextColor: this.options.tooltipTitleFontColor,\n\t\t\t\t\t\ttitleFontFamily: this.options.tooltipTitleFontFamily,\n\t\t\t\t\t\ttitleFontStyle: this.options.tooltipTitleFontStyle,\n\t\t\t\t\t\ttitleFontSize: this.options.tooltipTitleFontSize,\n\t\t\t\t\t\tcornerRadius: this.options.tooltipCornerRadius,\n\t\t\t\t\t\tlabels: tooltipLabels,\n\t\t\t\t\t\tlegendColors: tooltipColors,\n\t\t\t\t\t\tlegendColorBackground : this.options.multiTooltipKeyBackground,\n\t\t\t\t\t\ttitle: template(this.options.tooltipTitleTemplate,ChartElements[0]),\n\t\t\t\t\t\tchart: this.chart,\n\t\t\t\t\t\tctx: this.chart.ctx,\n\t\t\t\t\t\tcustom: this.options.customTooltips\n\t\t\t\t\t}).draw();\n\n\t\t\t\t} else {\n\t\t\t\t\teach(ChartElements, function(Element) {\n\t\t\t\t\t\tvar tooltipPosition = Element.tooltipPosition();\n\t\t\t\t\t\tnew Chart.Tooltip({\n\t\t\t\t\t\t\tx: Math.round(tooltipPosition.x),\n\t\t\t\t\t\t\ty: Math.round(tooltipPosition.y),\n\t\t\t\t\t\t\txPadding: this.options.tooltipXPadding,\n\t\t\t\t\t\t\tyPadding: this.options.tooltipYPadding,\n\t\t\t\t\t\t\tfillColor: this.options.tooltipFillColor,\n\t\t\t\t\t\t\ttextColor: this.options.tooltipFontColor,\n\t\t\t\t\t\t\tfontFamily: this.options.tooltipFontFamily,\n\t\t\t\t\t\t\tfontStyle: this.options.tooltipFontStyle,\n\t\t\t\t\t\t\tfontSize: this.options.tooltipFontSize,\n\t\t\t\t\t\t\tcaretHeight: this.options.tooltipCaretSize,\n\t\t\t\t\t\t\tcornerRadius: this.options.tooltipCornerRadius,\n\t\t\t\t\t\t\ttext: template(this.options.tooltipTemplate, Element),\n\t\t\t\t\t\t\tchart: this.chart,\n\t\t\t\t\t\t\tcustom: this.options.customTooltips\n\t\t\t\t\t\t}).draw();\n\t\t\t\t\t}, this);\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn this;\n\t\t},\n\t\ttoBase64Image : function(){\n\t\t\treturn this.chart.canvas.toDataURL.apply(this.chart.canvas, arguments);\n\t\t}\n\t});\n\n\tChart.Type.extend = function(extensions){\n\n\t\tvar parent = this;\n\n\t\tvar ChartType = function(){\n\t\t\treturn parent.apply(this,arguments);\n\t\t};\n\n\t\t//Copy the prototype object of the this class\n\t\tChartType.prototype = clone(parent.prototype);\n\t\t//Now overwrite some of the properties in the base class with the new extensions\n\t\textend(ChartType.prototype, extensions);\n\n\t\tChartType.extend = Chart.Type.extend;\n\n\t\tif (extensions.name || parent.prototype.name){\n\n\t\t\tvar chartName = extensions.name || parent.prototype.name;\n\t\t\t//Assign any potential default values of the new chart type\n\n\t\t\t//If none are defined, we'll use a clone of the chart type this is being extended from.\n\t\t\t//I.e. if we extend a line chart, we'll use the defaults from the line chart if our new chart\n\t\t\t//doesn't define some defaults of their own.\n\n\t\t\tvar baseDefaults = (Chart.defaults[parent.prototype.name]) ? clone(Chart.defaults[parent.prototype.name]) : {};\n\n\t\t\tChart.defaults[chartName] = extend(baseDefaults,extensions.defaults);\n\n\t\t\tChart.types[chartName] = ChartType;\n\n\t\t\t//Register this new chart type in the Chart prototype\n\t\t\tChart.prototype[chartName] = function(data,options){\n\t\t\t\tvar config = merge(Chart.defaults.global, Chart.defaults[chartName], options || {});\n\t\t\t\treturn new ChartType(data,config,this);\n\t\t\t};\n\t\t} else{\n\t\t\twarn(\"Name not provided for this chart, so it hasn't been registered\");\n\t\t}\n\t\treturn parent;\n\t};\n\n\tChart.Element = function(configuration){\n\t\textend(this,configuration);\n\t\tthis.initialize.apply(this,arguments);\n\t\tthis.save();\n\t};\n\textend(Chart.Element.prototype,{\n\t\tinitialize : function(){},\n\t\trestore : function(props){\n\t\t\tif (!props){\n\t\t\t\textend(this,this._saved);\n\t\t\t} else {\n\t\t\t\teach(props,function(key){\n\t\t\t\t\tthis[key] = this._saved[key];\n\t\t\t\t},this);\n\t\t\t}\n\t\t\treturn this;\n\t\t},\n\t\tsave : function(){\n\t\t\tthis._saved = clone(this);\n\t\t\tdelete this._saved._saved;\n\t\t\treturn this;\n\t\t},\n\t\tupdate : function(newProps){\n\t\t\teach(newProps,function(value,key){\n\t\t\t\tthis._saved[key] = this[key];\n\t\t\t\tthis[key] = value;\n\t\t\t},this);\n\t\t\treturn this;\n\t\t},\n\t\ttransition : function(props,ease){\n\t\t\teach(props,function(value,key){\n\t\t\t\tthis[key] = ((value - this._saved[key]) * ease) + this._saved[key];\n\t\t\t},this);\n\t\t\treturn this;\n\t\t},\n\t\ttooltipPosition : function(){\n\t\t\treturn {\n\t\t\t\tx : this.x,\n\t\t\t\ty : this.y\n\t\t\t};\n\t\t},\n\t\thasValue: function(){\n\t\t\treturn isNumber(this.value);\n\t\t}\n\t});\n\n\tChart.Element.extend = inherits;\n\n\n\tChart.Point = Chart.Element.extend({\n\t\tdisplay: true,\n\t\tinRange: function(chartX,chartY){\n\t\t\tvar hitDetectionRange = this.hitDetectionRadius + this.radius;\n\t\t\treturn ((Math.pow(chartX-this.x, 2)+Math.pow(chartY-this.y, 2)) < Math.pow(hitDetectionRange,2));\n\t\t},\n\t\tdraw : function(){\n\t\t\tif (this.display){\n\t\t\t\tvar ctx = this.ctx;\n\t\t\t\tctx.beginPath();\n\n\t\t\t\tctx.arc(this.x, this.y, this.radius, 0, Math.PI*2);\n\t\t\t\tctx.closePath();\n\n\t\t\t\tctx.strokeStyle = this.strokeColor;\n\t\t\t\tctx.lineWidth = this.strokeWidth;\n\n\t\t\t\tctx.fillStyle = this.fillColor;\n\n\t\t\t\tctx.fill();\n\t\t\t\tctx.stroke();\n\t\t\t}\n\n\n\t\t\t//Quick debug for bezier curve splining\n\t\t\t//Highlights control points and the line between them.\n\t\t\t//Handy for dev - stripped in the min version.\n\n\t\t\t// ctx.save();\n\t\t\t// ctx.fillStyle = \"black\";\n\t\t\t// ctx.strokeStyle = \"black\"\n\t\t\t// ctx.beginPath();\n\t\t\t// ctx.arc(this.controlPoints.inner.x,this.controlPoints.inner.y, 2, 0, Math.PI*2);\n\t\t\t// ctx.fill();\n\n\t\t\t// ctx.beginPath();\n\t\t\t// ctx.arc(this.controlPoints.outer.x,this.controlPoints.outer.y, 2, 0, Math.PI*2);\n\t\t\t// ctx.fill();\n\n\t\t\t// ctx.moveTo(this.controlPoints.inner.x,this.controlPoints.inner.y);\n\t\t\t// ctx.lineTo(this.x, this.y);\n\t\t\t// ctx.lineTo(this.controlPoints.outer.x,this.controlPoints.outer.y);\n\t\t\t// ctx.stroke();\n\n\t\t\t// ctx.restore();\n\n\n\n\t\t}\n\t});\n\n\tChart.Arc = Chart.Element.extend({\n\t\tinRange : function(chartX,chartY){\n\n\t\t\tvar pointRelativePosition = helpers.getAngleFromPoint(this, {\n\t\t\t\tx: chartX,\n\t\t\t\ty: chartY\n\t\t\t});\n\n\t\t\t// Normalize all angles to 0 - 2*PI (0 - 360°)\n\t\t\tvar pointRelativeAngle = pointRelativePosition.angle % (Math.PI * 2),\n\t\t\t    startAngle = (Math.PI * 2 + this.startAngle) % (Math.PI * 2),\n\t\t\t    endAngle = (Math.PI * 2 + this.endAngle) % (Math.PI * 2) || 360;\n\n\t\t\t// Calculate wether the pointRelativeAngle is between the start and the end angle\n\t\t\tvar betweenAngles = (endAngle < startAngle) ?\n\t\t\t\tpointRelativeAngle <= endAngle || pointRelativeAngle >= startAngle:\n\t\t\t\tpointRelativeAngle >= startAngle && pointRelativeAngle <= endAngle;\n\n\t\t\t//Check if within the range of the open/close angle\n\t\t\tvar withinRadius = (pointRelativePosition.distance >= this.innerRadius && pointRelativePosition.distance <= this.outerRadius);\n\n\t\t\treturn (betweenAngles && withinRadius);\n\t\t\t//Ensure within the outside of the arc centre, but inside arc outer\n\t\t},\n\t\ttooltipPosition : function(){\n\t\t\tvar centreAngle = this.startAngle + ((this.endAngle - this.startAngle) / 2),\n\t\t\t\trangeFromCentre = (this.outerRadius - this.innerRadius) / 2 + this.innerRadius;\n\t\t\treturn {\n\t\t\t\tx : this.x + (Math.cos(centreAngle) * rangeFromCentre),\n\t\t\t\ty : this.y + (Math.sin(centreAngle) * rangeFromCentre)\n\t\t\t};\n\t\t},\n\t\tdraw : function(animationPercent){\n\n\t\t\tvar easingDecimal = animationPercent || 1;\n\n\t\t\tvar ctx = this.ctx;\n\n\t\t\tctx.beginPath();\n\n\t\t\tctx.arc(this.x, this.y, this.outerRadius < 0 ? 0 : this.outerRadius, this.startAngle, this.endAngle);\n\n            ctx.arc(this.x, this.y, this.innerRadius < 0 ? 0 : this.innerRadius, this.endAngle, this.startAngle, true);\n\n\t\t\tctx.closePath();\n\t\t\tctx.strokeStyle = this.strokeColor;\n\t\t\tctx.lineWidth = this.strokeWidth;\n\n\t\t\tctx.fillStyle = this.fillColor;\n\n\t\t\tctx.fill();\n\t\t\tctx.lineJoin = 'bevel';\n\n\t\t\tif (this.showStroke){\n\t\t\t\tctx.stroke();\n\t\t\t}\n\t\t}\n\t});\n\n\tChart.Rectangle = Chart.Element.extend({\n\t\tdraw : function(){\n\t\t\tvar ctx = this.ctx,\n\t\t\t\thalfWidth = this.width/2,\n\t\t\t\tleftX = this.x - halfWidth,\n\t\t\t\trightX = this.x + halfWidth,\n\t\t\t\ttop = this.base - (this.base - this.y),\n\t\t\t\thalfStroke = this.strokeWidth / 2;\n\n\t\t\t// Canvas doesn't allow us to stroke inside the width so we can\n\t\t\t// adjust the sizes to fit if we're setting a stroke on the line\n\t\t\tif (this.showStroke){\n\t\t\t\tleftX += halfStroke;\n\t\t\t\trightX -= halfStroke;\n\t\t\t\ttop += halfStroke;\n\t\t\t}\n\n\t\t\tctx.beginPath();\n\n\t\t\tctx.fillStyle = this.fillColor;\n\t\t\tctx.strokeStyle = this.strokeColor;\n\t\t\tctx.lineWidth = this.strokeWidth;\n\n\t\t\t// It'd be nice to keep this class totally generic to any rectangle\n\t\t\t// and simply specify which border to miss out.\n\t\t\tctx.moveTo(leftX, this.base);\n\t\t\tctx.lineTo(leftX, top);\n\t\t\tctx.lineTo(rightX, top);\n\t\t\tctx.lineTo(rightX, this.base);\n\t\t\tctx.fill();\n\t\t\tif (this.showStroke){\n\t\t\t\tctx.stroke();\n\t\t\t}\n\t\t},\n\t\theight : function(){\n\t\t\treturn this.base - this.y;\n\t\t},\n\t\tinRange : function(chartX,chartY){\n\t\t\treturn (chartX >= this.x - this.width/2 && chartX <= this.x + this.width/2) && (chartY >= this.y && chartY <= this.base);\n\t\t}\n\t});\n\n\tChart.Animation = Chart.Element.extend({\n\t\tcurrentStep: null, // the current animation step\n\t\tnumSteps: 60, // default number of steps\n\t\teasing: \"\", // the easing to use for this animation\n\t\trender: null, // render function used by the animation service\n\t\t\n\t\tonAnimationProgress: null, // user specified callback to fire on each step of the animation \n\t\tonAnimationComplete: null, // user specified callback to fire when the animation finishes\n\t});\n\t\n\tChart.Tooltip = Chart.Element.extend({\n\t\tdraw : function(){\n\n\t\t\tvar ctx = this.chart.ctx;\n\n\t\t\tctx.font = fontString(this.fontSize,this.fontStyle,this.fontFamily);\n\n\t\t\tthis.xAlign = \"center\";\n\t\t\tthis.yAlign = \"above\";\n\n\t\t\t//Distance between the actual element.y position and the start of the tooltip caret\n\t\t\tvar caretPadding = this.caretPadding = 2;\n\n\t\t\tvar tooltipWidth = ctx.measureText(this.text).width + 2*this.xPadding,\n\t\t\t\ttooltipRectHeight = this.fontSize + 2*this.yPadding,\n\t\t\t\ttooltipHeight = tooltipRectHeight + this.caretHeight + caretPadding;\n\n\t\t\tif (this.x + tooltipWidth/2 >this.chart.width){\n\t\t\t\tthis.xAlign = \"left\";\n\t\t\t} else if (this.x - tooltipWidth/2 < 0){\n\t\t\t\tthis.xAlign = \"right\";\n\t\t\t}\n\n\t\t\tif (this.y - tooltipHeight < 0){\n\t\t\t\tthis.yAlign = \"below\";\n\t\t\t}\n\n\n\t\t\tvar tooltipX = this.x - tooltipWidth/2,\n\t\t\t\ttooltipY = this.y - tooltipHeight;\n\n\t\t\tctx.fillStyle = this.fillColor;\n\n\t\t\t// Custom Tooltips\n\t\t\tif(this.custom){\n\t\t\t\tthis.custom(this);\n\t\t\t}\n\t\t\telse{\n\t\t\t\tswitch(this.yAlign)\n\t\t\t\t{\n\t\t\t\tcase \"above\":\n\t\t\t\t\t//Draw a caret above the x/y\n\t\t\t\t\tctx.beginPath();\n\t\t\t\t\tctx.moveTo(this.x,this.y - caretPadding);\n\t\t\t\t\tctx.lineTo(this.x + this.caretHeight, this.y - (caretPadding + this.caretHeight));\n\t\t\t\t\tctx.lineTo(this.x - this.caretHeight, this.y - (caretPadding + this.caretHeight));\n\t\t\t\t\tctx.closePath();\n\t\t\t\t\tctx.fill();\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"below\":\n\t\t\t\t\ttooltipY = this.y + caretPadding + this.caretHeight;\n\t\t\t\t\t//Draw a caret below the x/y\n\t\t\t\t\tctx.beginPath();\n\t\t\t\t\tctx.moveTo(this.x, this.y + caretPadding);\n\t\t\t\t\tctx.lineTo(this.x + this.caretHeight, this.y + caretPadding + this.caretHeight);\n\t\t\t\t\tctx.lineTo(this.x - this.caretHeight, this.y + caretPadding + this.caretHeight);\n\t\t\t\t\tctx.closePath();\n\t\t\t\t\tctx.fill();\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\n\t\t\t\tswitch(this.xAlign)\n\t\t\t\t{\n\t\t\t\tcase \"left\":\n\t\t\t\t\ttooltipX = this.x - tooltipWidth + (this.cornerRadius + this.caretHeight);\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"right\":\n\t\t\t\t\ttooltipX = this.x - (this.cornerRadius + this.caretHeight);\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\n\t\t\t\tdrawRoundedRectangle(ctx,tooltipX,tooltipY,tooltipWidth,tooltipRectHeight,this.cornerRadius);\n\n\t\t\t\tctx.fill();\n\n\t\t\t\tctx.fillStyle = this.textColor;\n\t\t\t\tctx.textAlign = \"center\";\n\t\t\t\tctx.textBaseline = \"middle\";\n\t\t\t\tctx.fillText(this.text, tooltipX + tooltipWidth/2, tooltipY + tooltipRectHeight/2);\n\t\t\t}\n\t\t}\n\t});\n\n\tChart.MultiTooltip = Chart.Element.extend({\n\t\tinitialize : function(){\n\t\t\tthis.font = fontString(this.fontSize,this.fontStyle,this.fontFamily);\n\n\t\t\tthis.titleFont = fontString(this.titleFontSize,this.titleFontStyle,this.titleFontFamily);\n\n\t\t\tthis.titleHeight = this.title ? this.titleFontSize * 1.5 : 0;\n\t\t\tthis.height = (this.labels.length * this.fontSize) + ((this.labels.length-1) * (this.fontSize/2)) + (this.yPadding*2) + this.titleHeight;\n\n\t\t\tthis.ctx.font = this.titleFont;\n\n\t\t\tvar titleWidth = this.ctx.measureText(this.title).width,\n\t\t\t\t//Label has a legend square as well so account for this.\n\t\t\t\tlabelWidth = longestText(this.ctx,this.font,this.labels) + this.fontSize + 3,\n\t\t\t\tlongestTextWidth = max([labelWidth,titleWidth]);\n\n\t\t\tthis.width = longestTextWidth + (this.xPadding*2);\n\n\n\t\t\tvar halfHeight = this.height/2;\n\n\t\t\t//Check to ensure the height will fit on the canvas\n\t\t\tif (this.y - halfHeight < 0 ){\n\t\t\t\tthis.y = halfHeight;\n\t\t\t} else if (this.y + halfHeight > this.chart.height){\n\t\t\t\tthis.y = this.chart.height - halfHeight;\n\t\t\t}\n\n\t\t\t//Decide whether to align left or right based on position on canvas\n\t\t\tif (this.x > this.chart.width/2){\n\t\t\t\tthis.x -= this.xOffset + this.width;\n\t\t\t} else {\n\t\t\t\tthis.x += this.xOffset;\n\t\t\t}\n\n\n\t\t},\n\t\tgetLineHeight : function(index){\n\t\t\tvar baseLineHeight = this.y - (this.height/2) + this.yPadding,\n\t\t\t\tafterTitleIndex = index-1;\n\n\t\t\t//If the index is zero, we're getting the title\n\t\t\tif (index === 0){\n\t\t\t\treturn baseLineHeight + this.titleHeight / 3;\n\t\t\t} else{\n\t\t\t\treturn baseLineHeight + ((this.fontSize * 1.5 * afterTitleIndex) + this.fontSize / 2) + this.titleHeight;\n\t\t\t}\n\n\t\t},\n\t\tdraw : function(){\n\t\t\t// Custom Tooltips\n\t\t\tif(this.custom){\n\t\t\t\tthis.custom(this);\n\t\t\t}\n\t\t\telse{\n\t\t\t\tdrawRoundedRectangle(this.ctx,this.x,this.y - this.height/2,this.width,this.height,this.cornerRadius);\n\t\t\t\tvar ctx = this.ctx;\n\t\t\t\tctx.fillStyle = this.fillColor;\n\t\t\t\tctx.fill();\n\t\t\t\tctx.closePath();\n\n\t\t\t\tctx.textAlign = \"left\";\n\t\t\t\tctx.textBaseline = \"middle\";\n\t\t\t\tctx.fillStyle = this.titleTextColor;\n\t\t\t\tctx.font = this.titleFont;\n\n\t\t\t\tctx.fillText(this.title,this.x + this.xPadding, this.getLineHeight(0));\n\n\t\t\t\tctx.font = this.font;\n\t\t\t\thelpers.each(this.labels,function(label,index){\n\t\t\t\t\tctx.fillStyle = this.textColor;\n\t\t\t\t\tctx.fillText(label,this.x + this.xPadding + this.fontSize + 3, this.getLineHeight(index + 1));\n\n\t\t\t\t\t//A bit gnarly, but clearing this rectangle breaks when using explorercanvas (clears whole canvas)\n\t\t\t\t\t//ctx.clearRect(this.x + this.xPadding, this.getLineHeight(index + 1) - this.fontSize/2, this.fontSize, this.fontSize);\n\t\t\t\t\t//Instead we'll make a white filled block to put the legendColour palette over.\n\n\t\t\t\t\tctx.fillStyle = this.legendColorBackground;\n\t\t\t\t\tctx.fillRect(this.x + this.xPadding, this.getLineHeight(index + 1) - this.fontSize/2, this.fontSize, this.fontSize);\n\n\t\t\t\t\tctx.fillStyle = this.legendColors[index].fill;\n\t\t\t\t\tctx.fillRect(this.x + this.xPadding, this.getLineHeight(index + 1) - this.fontSize/2, this.fontSize, this.fontSize);\n\n\n\t\t\t\t},this);\n\t\t\t}\n\t\t}\n\t});\n\n\tChart.Scale = Chart.Element.extend({\n\t\tinitialize : function(){\n\t\t\tthis.fit();\n\t\t},\n\t\tbuildYLabels : function(){\n\t\t\tthis.yLabels = [];\n\n\t\t\tvar stepDecimalPlaces = getDecimalPlaces(this.stepValue);\n\n\t\t\tfor (var i=0; i<=this.steps; i++){\n\t\t\t\tthis.yLabels.push(template(this.templateString,{value:(this.min + (i * this.stepValue)).toFixed(stepDecimalPlaces)}));\n\t\t\t}\n\t\t\tthis.yLabelWidth = (this.display && this.showLabels) ? longestText(this.ctx,this.font,this.yLabels) + 10 : 0;\n\t\t},\n\t\taddXLabel : function(label){\n\t\t\tthis.xLabels.push(label);\n\t\t\tthis.valuesCount++;\n\t\t\tthis.fit();\n\t\t},\n\t\tremoveXLabel : function(){\n\t\t\tthis.xLabels.shift();\n\t\t\tthis.valuesCount--;\n\t\t\tthis.fit();\n\t\t},\n\t\t// Fitting loop to rotate x Labels and figure out what fits there, and also calculate how many Y steps to use\n\t\tfit: function(){\n\t\t\t// First we need the width of the yLabels, assuming the xLabels aren't rotated\n\n\t\t\t// To do that we need the base line at the top and base of the chart, assuming there is no x label rotation\n\t\t\tthis.startPoint = (this.display) ? this.fontSize : 0;\n\t\t\tthis.endPoint = (this.display) ? this.height - (this.fontSize * 1.5) - 5 : this.height; // -5 to pad labels\n\n\t\t\t// Apply padding settings to the start and end point.\n\t\t\tthis.startPoint += this.padding;\n\t\t\tthis.endPoint -= this.padding;\n\n\t\t\t// Cache the starting endpoint, excluding the space for x labels\n\t\t\tvar cachedEndPoint = this.endPoint;\n\n\t\t\t// Cache the starting height, so can determine if we need to recalculate the scale yAxis\n\t\t\tvar cachedHeight = this.endPoint - this.startPoint,\n\t\t\t\tcachedYLabelWidth;\n\n\t\t\t// Build the current yLabels so we have an idea of what size they'll be to start\n\t\t\t/*\n\t\t\t *\tThis sets what is returned from calculateScaleRange as static properties of this class:\n\t\t\t *\n\t\t\t\tthis.steps;\n\t\t\t\tthis.stepValue;\n\t\t\t\tthis.min;\n\t\t\t\tthis.max;\n\t\t\t *\n\t\t\t */\n\t\t\tthis.calculateYRange(cachedHeight);\n\n\t\t\t// With these properties set we can now build the array of yLabels\n\t\t\t// and also the width of the largest yLabel\n\t\t\tthis.buildYLabels();\n\n\t\t\tthis.calculateXLabelRotation();\n\n\t\t\twhile((cachedHeight > this.endPoint - this.startPoint)){\n\t\t\t\tcachedHeight = this.endPoint - this.startPoint;\n\t\t\t\tcachedYLabelWidth = this.yLabelWidth;\n\n\t\t\t\tthis.calculateYRange(cachedHeight);\n\t\t\t\tthis.buildYLabels();\n\n\t\t\t\t// Only go through the xLabel loop again if the yLabel width has changed\n\t\t\t\tif (cachedYLabelWidth < this.yLabelWidth){\n\t\t\t\t\tthis.endPoint = cachedEndPoint;\n\t\t\t\t\tthis.calculateXLabelRotation();\n\t\t\t\t}\n\t\t\t}\n\n\t\t},\n\t\tcalculateXLabelRotation : function(){\n\t\t\t//Get the width of each grid by calculating the difference\n\t\t\t//between x offsets between 0 and 1.\n\n\t\t\tthis.ctx.font = this.font;\n\n\t\t\tvar firstWidth = this.ctx.measureText(this.xLabels[0]).width,\n\t\t\t\tlastWidth = this.ctx.measureText(this.xLabels[this.xLabels.length - 1]).width,\n\t\t\t\tfirstRotated,\n\t\t\t\tlastRotated;\n\n\n\t\t\tthis.xScalePaddingRight = lastWidth/2 + 3;\n\t\t\tthis.xScalePaddingLeft = (firstWidth/2 > this.yLabelWidth) ? firstWidth/2 : this.yLabelWidth;\n\n\t\t\tthis.xLabelRotation = 0;\n\t\t\tif (this.display){\n\t\t\t\tvar originalLabelWidth = longestText(this.ctx,this.font,this.xLabels),\n\t\t\t\t\tcosRotation,\n\t\t\t\t\tfirstRotatedWidth;\n\t\t\t\tthis.xLabelWidth = originalLabelWidth;\n\t\t\t\t//Allow 3 pixels x2 padding either side for label readability\n\t\t\t\tvar xGridWidth = Math.floor(this.calculateX(1) - this.calculateX(0)) - 6;\n\n\t\t\t\t//Max label rotate should be 90 - also act as a loop counter\n\t\t\t\twhile ((this.xLabelWidth > xGridWidth && this.xLabelRotation === 0) || (this.xLabelWidth > xGridWidth && this.xLabelRotation <= 90 && this.xLabelRotation > 0)){\n\t\t\t\t\tcosRotation = Math.cos(toRadians(this.xLabelRotation));\n\n\t\t\t\t\tfirstRotated = cosRotation * firstWidth;\n\t\t\t\t\tlastRotated = cosRotation * lastWidth;\n\n\t\t\t\t\t// We're right aligning the text now.\n\t\t\t\t\tif (firstRotated + this.fontSize / 2 > this.yLabelWidth){\n\t\t\t\t\t\tthis.xScalePaddingLeft = firstRotated + this.fontSize / 2;\n\t\t\t\t\t}\n\t\t\t\t\tthis.xScalePaddingRight = this.fontSize/2;\n\n\n\t\t\t\t\tthis.xLabelRotation++;\n\t\t\t\t\tthis.xLabelWidth = cosRotation * originalLabelWidth;\n\n\t\t\t\t}\n\t\t\t\tif (this.xLabelRotation > 0){\n\t\t\t\t\tthis.endPoint -= Math.sin(toRadians(this.xLabelRotation))*originalLabelWidth + 3;\n\t\t\t\t}\n\t\t\t}\n\t\t\telse{\n\t\t\t\tthis.xLabelWidth = 0;\n\t\t\t\tthis.xScalePaddingRight = this.padding;\n\t\t\t\tthis.xScalePaddingLeft = this.padding;\n\t\t\t}\n\n\t\t},\n\t\t// Needs to be overidden in each Chart type\n\t\t// Otherwise we need to pass all the data into the scale class\n\t\tcalculateYRange: noop,\n\t\tdrawingArea: function(){\n\t\t\treturn this.startPoint - this.endPoint;\n\t\t},\n\t\tcalculateY : function(value){\n\t\t\tvar scalingFactor = this.drawingArea() / (this.min - this.max);\n\t\t\treturn this.endPoint - (scalingFactor * (value - this.min));\n\t\t},\n\t\tcalculateX : function(index){\n\t\t\tvar isRotated = (this.xLabelRotation > 0),\n\t\t\t\t// innerWidth = (this.offsetGridLines) ? this.width - offsetLeft - this.padding : this.width - (offsetLeft + halfLabelWidth * 2) - this.padding,\n\t\t\t\tinnerWidth = this.width - (this.xScalePaddingLeft + this.xScalePaddingRight),\n\t\t\t\tvalueWidth = innerWidth/Math.max((this.valuesCount - ((this.offsetGridLines) ? 0 : 1)), 1),\n\t\t\t\tvalueOffset = (valueWidth * index) + this.xScalePaddingLeft;\n\n\t\t\tif (this.offsetGridLines){\n\t\t\t\tvalueOffset += (valueWidth/2);\n\t\t\t}\n\n\t\t\treturn Math.round(valueOffset);\n\t\t},\n\t\tupdate : function(newProps){\n\t\t\thelpers.extend(this, newProps);\n\t\t\tthis.fit();\n\t\t},\n\t\tdraw : function(){\n\t\t\tvar ctx = this.ctx,\n\t\t\t\tyLabelGap = (this.endPoint - this.startPoint) / this.steps,\n\t\t\t\txStart = Math.round(this.xScalePaddingLeft);\n\t\t\tif (this.display){\n\t\t\t\tctx.fillStyle = this.textColor;\n\t\t\t\tctx.font = this.font;\n\t\t\t\teach(this.yLabels,function(labelString,index){\n\t\t\t\t\tvar yLabelCenter = this.endPoint - (yLabelGap * index),\n\t\t\t\t\t\tlinePositionY = Math.round(yLabelCenter),\n\t\t\t\t\t\tdrawHorizontalLine = this.showHorizontalLines;\n\n\t\t\t\t\tctx.textAlign = \"right\";\n\t\t\t\t\tctx.textBaseline = \"middle\";\n\t\t\t\t\tif (this.showLabels){\n\t\t\t\t\t\tctx.fillText(labelString,xStart - 10,yLabelCenter);\n\t\t\t\t\t}\n\n\t\t\t\t\t// This is X axis, so draw it\n\t\t\t\t\tif (index === 0 && !drawHorizontalLine){\n\t\t\t\t\t\tdrawHorizontalLine = true;\n\t\t\t\t\t}\n\n\t\t\t\t\tif (drawHorizontalLine){\n\t\t\t\t\t\tctx.beginPath();\n\t\t\t\t\t}\n\n\t\t\t\t\tif (index > 0){\n\t\t\t\t\t\t// This is a grid line in the centre, so drop that\n\t\t\t\t\t\tctx.lineWidth = this.gridLineWidth;\n\t\t\t\t\t\tctx.strokeStyle = this.gridLineColor;\n\t\t\t\t\t} else {\n\t\t\t\t\t\t// This is the first line on the scale\n\t\t\t\t\t\tctx.lineWidth = this.lineWidth;\n\t\t\t\t\t\tctx.strokeStyle = this.lineColor;\n\t\t\t\t\t}\n\n\t\t\t\t\tlinePositionY += helpers.aliasPixel(ctx.lineWidth);\n\n\t\t\t\t\tif(drawHorizontalLine){\n\t\t\t\t\t\tctx.moveTo(xStart, linePositionY);\n\t\t\t\t\t\tctx.lineTo(this.width, linePositionY);\n\t\t\t\t\t\tctx.stroke();\n\t\t\t\t\t\tctx.closePath();\n\t\t\t\t\t}\n\n\t\t\t\t\tctx.lineWidth = this.lineWidth;\n\t\t\t\t\tctx.strokeStyle = this.lineColor;\n\t\t\t\t\tctx.beginPath();\n\t\t\t\t\tctx.moveTo(xStart - 5, linePositionY);\n\t\t\t\t\tctx.lineTo(xStart, linePositionY);\n\t\t\t\t\tctx.stroke();\n\t\t\t\t\tctx.closePath();\n\n\t\t\t\t},this);\n\n\t\t\t\teach(this.xLabels,function(label,index){\n\t\t\t\t\tvar xPos = this.calculateX(index) + aliasPixel(this.lineWidth),\n\t\t\t\t\t\t// Check to see if line/bar here and decide where to place the line\n\t\t\t\t\t\tlinePos = this.calculateX(index - (this.offsetGridLines ? 0.5 : 0)) + aliasPixel(this.lineWidth),\n\t\t\t\t\t\tisRotated = (this.xLabelRotation > 0),\n\t\t\t\t\t\tdrawVerticalLine = this.showVerticalLines;\n\n\t\t\t\t\t// This is Y axis, so draw it\n\t\t\t\t\tif (index === 0 && !drawVerticalLine){\n\t\t\t\t\t\tdrawVerticalLine = true;\n\t\t\t\t\t}\n\n\t\t\t\t\tif (drawVerticalLine){\n\t\t\t\t\t\tctx.beginPath();\n\t\t\t\t\t}\n\n\t\t\t\t\tif (index > 0){\n\t\t\t\t\t\t// This is a grid line in the centre, so drop that\n\t\t\t\t\t\tctx.lineWidth = this.gridLineWidth;\n\t\t\t\t\t\tctx.strokeStyle = this.gridLineColor;\n\t\t\t\t\t} else {\n\t\t\t\t\t\t// This is the first line on the scale\n\t\t\t\t\t\tctx.lineWidth = this.lineWidth;\n\t\t\t\t\t\tctx.strokeStyle = this.lineColor;\n\t\t\t\t\t}\n\n\t\t\t\t\tif (drawVerticalLine){\n\t\t\t\t\t\tctx.moveTo(linePos,this.endPoint);\n\t\t\t\t\t\tctx.lineTo(linePos,this.startPoint - 3);\n\t\t\t\t\t\tctx.stroke();\n\t\t\t\t\t\tctx.closePath();\n\t\t\t\t\t}\n\n\n\t\t\t\t\tctx.lineWidth = this.lineWidth;\n\t\t\t\t\tctx.strokeStyle = this.lineColor;\n\n\n\t\t\t\t\t// Small lines at the bottom of the base grid line\n\t\t\t\t\tctx.beginPath();\n\t\t\t\t\tctx.moveTo(linePos,this.endPoint);\n\t\t\t\t\tctx.lineTo(linePos,this.endPoint + 5);\n\t\t\t\t\tctx.stroke();\n\t\t\t\t\tctx.closePath();\n\n\t\t\t\t\tctx.save();\n\t\t\t\t\tctx.translate(xPos,(isRotated) ? this.endPoint + 12 : this.endPoint + 8);\n\t\t\t\t\tctx.rotate(toRadians(this.xLabelRotation)*-1);\n\t\t\t\t\tctx.font = this.font;\n\t\t\t\t\tctx.textAlign = (isRotated) ? \"right\" : \"center\";\n\t\t\t\t\tctx.textBaseline = (isRotated) ? \"middle\" : \"top\";\n\t\t\t\t\tctx.fillText(label, 0, 0);\n\t\t\t\t\tctx.restore();\n\t\t\t\t},this);\n\n\t\t\t}\n\t\t}\n\n\t});\n\n\tChart.RadialScale = Chart.Element.extend({\n\t\tinitialize: function(){\n\t\t\tthis.size = min([this.height, this.width]);\n\t\t\tthis.drawingArea = (this.display) ? (this.size/2) - (this.fontSize/2 + this.backdropPaddingY) : (this.size/2);\n\t\t},\n\t\tcalculateCenterOffset: function(value){\n\t\t\t// Take into account half font size + the yPadding of the top value\n\t\t\tvar scalingFactor = this.drawingArea / (this.max - this.min);\n\n\t\t\treturn (value - this.min) * scalingFactor;\n\t\t},\n\t\tupdate : function(){\n\t\t\tif (!this.lineArc){\n\t\t\t\tthis.setScaleSize();\n\t\t\t} else {\n\t\t\t\tthis.drawingArea = (this.display) ? (this.size/2) - (this.fontSize/2 + this.backdropPaddingY) : (this.size/2);\n\t\t\t}\n\t\t\tthis.buildYLabels();\n\t\t},\n\t\tbuildYLabels: function(){\n\t\t\tthis.yLabels = [];\n\n\t\t\tvar stepDecimalPlaces = getDecimalPlaces(this.stepValue);\n\n\t\t\tfor (var i=0; i<=this.steps; i++){\n\t\t\t\tthis.yLabels.push(template(this.templateString,{value:(this.min + (i * this.stepValue)).toFixed(stepDecimalPlaces)}));\n\t\t\t}\n\t\t},\n\t\tgetCircumference : function(){\n\t\t\treturn ((Math.PI*2) / this.valuesCount);\n\t\t},\n\t\tsetScaleSize: function(){\n\t\t\t/*\n\t\t\t * Right, this is really confusing and there is a lot of maths going on here\n\t\t\t * The gist of the problem is here: https://gist.github.com/nnnick/696cc9c55f4b0beb8fe9\n\t\t\t *\n\t\t\t * Reaction: https://dl.dropboxusercontent.com/u/34601363/toomuchscience.gif\n\t\t\t *\n\t\t\t * Solution:\n\t\t\t *\n\t\t\t * We assume the radius of the polygon is half the size of the canvas at first\n\t\t\t * at each index we check if the text overlaps.\n\t\t\t *\n\t\t\t * Where it does, we store that angle and that index.\n\t\t\t *\n\t\t\t * After finding the largest index and angle we calculate how much we need to remove\n\t\t\t * from the shape radius to move the point inwards by that x.\n\t\t\t *\n\t\t\t * We average the left and right distances to get the maximum shape radius that can fit in the box\n\t\t\t * along with labels.\n\t\t\t *\n\t\t\t * Once we have that, we can find the centre point for the chart, by taking the x text protrusion\n\t\t\t * on each side, removing that from the size, halving it and adding the left x protrusion width.\n\t\t\t *\n\t\t\t * This will mean we have a shape fitted to the canvas, as large as it can be with the labels\n\t\t\t * and position it in the most space efficient manner\n\t\t\t *\n\t\t\t * https://dl.dropboxusercontent.com/u/34601363/yeahscience.gif\n\t\t\t */\n\n\n\t\t\t// Get maximum radius of the polygon. Either half the height (minus the text width) or half the width.\n\t\t\t// Use this to calculate the offset + change. - Make sure L/R protrusion is at least 0 to stop issues with centre points\n\t\t\tvar largestPossibleRadius = min([(this.height/2 - this.pointLabelFontSize - 5), this.width/2]),\n\t\t\t\tpointPosition,\n\t\t\t\ti,\n\t\t\t\ttextWidth,\n\t\t\t\thalfTextWidth,\n\t\t\t\tfurthestRight = this.width,\n\t\t\t\tfurthestRightIndex,\n\t\t\t\tfurthestRightAngle,\n\t\t\t\tfurthestLeft = 0,\n\t\t\t\tfurthestLeftIndex,\n\t\t\t\tfurthestLeftAngle,\n\t\t\t\txProtrusionLeft,\n\t\t\t\txProtrusionRight,\n\t\t\t\tradiusReductionRight,\n\t\t\t\tradiusReductionLeft,\n\t\t\t\tmaxWidthRadius;\n\t\t\tthis.ctx.font = fontString(this.pointLabelFontSize,this.pointLabelFontStyle,this.pointLabelFontFamily);\n\t\t\tfor (i=0;i<this.valuesCount;i++){\n\t\t\t\t// 5px to space the text slightly out - similar to what we do in the draw function.\n\t\t\t\tpointPosition = this.getPointPosition(i, largestPossibleRadius);\n\t\t\t\ttextWidth = this.ctx.measureText(template(this.templateString, { value: this.labels[i] })).width + 5;\n\t\t\t\tif (i === 0 || i === this.valuesCount/2){\n\t\t\t\t\t// If we're at index zero, or exactly the middle, we're at exactly the top/bottom\n\t\t\t\t\t// of the radar chart, so text will be aligned centrally, so we'll half it and compare\n\t\t\t\t\t// w/left and right text sizes\n\t\t\t\t\thalfTextWidth = textWidth/2;\n\t\t\t\t\tif (pointPosition.x + halfTextWidth > furthestRight) {\n\t\t\t\t\t\tfurthestRight = pointPosition.x + halfTextWidth;\n\t\t\t\t\t\tfurthestRightIndex = i;\n\t\t\t\t\t}\n\t\t\t\t\tif (pointPosition.x - halfTextWidth < furthestLeft) {\n\t\t\t\t\t\tfurthestLeft = pointPosition.x - halfTextWidth;\n\t\t\t\t\t\tfurthestLeftIndex = i;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\telse if (i < this.valuesCount/2) {\n\t\t\t\t\t// Less than half the values means we'll left align the text\n\t\t\t\t\tif (pointPosition.x + textWidth > furthestRight) {\n\t\t\t\t\t\tfurthestRight = pointPosition.x + textWidth;\n\t\t\t\t\t\tfurthestRightIndex = i;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\telse if (i > this.valuesCount/2){\n\t\t\t\t\t// More than half the values means we'll right align the text\n\t\t\t\t\tif (pointPosition.x - textWidth < furthestLeft) {\n\t\t\t\t\t\tfurthestLeft = pointPosition.x - textWidth;\n\t\t\t\t\t\tfurthestLeftIndex = i;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\txProtrusionLeft = furthestLeft;\n\n\t\t\txProtrusionRight = Math.ceil(furthestRight - this.width);\n\n\t\t\tfurthestRightAngle = this.getIndexAngle(furthestRightIndex);\n\n\t\t\tfurthestLeftAngle = this.getIndexAngle(furthestLeftIndex);\n\n\t\t\tradiusReductionRight = xProtrusionRight / Math.sin(furthestRightAngle + Math.PI/2);\n\n\t\t\tradiusReductionLeft = xProtrusionLeft / Math.sin(furthestLeftAngle + Math.PI/2);\n\n\t\t\t// Ensure we actually need to reduce the size of the chart\n\t\t\tradiusReductionRight = (isNumber(radiusReductionRight)) ? radiusReductionRight : 0;\n\t\t\tradiusReductionLeft = (isNumber(radiusReductionLeft)) ? radiusReductionLeft : 0;\n\n\t\t\tthis.drawingArea = largestPossibleRadius - (radiusReductionLeft + radiusReductionRight)/2;\n\n\t\t\t//this.drawingArea = min([maxWidthRadius, (this.height - (2 * (this.pointLabelFontSize + 5)))/2])\n\t\t\tthis.setCenterPoint(radiusReductionLeft, radiusReductionRight);\n\n\t\t},\n\t\tsetCenterPoint: function(leftMovement, rightMovement){\n\n\t\t\tvar maxRight = this.width - rightMovement - this.drawingArea,\n\t\t\t\tmaxLeft = leftMovement + this.drawingArea;\n\n\t\t\tthis.xCenter = (maxLeft + maxRight)/2;\n\t\t\t// Always vertically in the centre as the text height doesn't change\n\t\t\tthis.yCenter = (this.height/2);\n\t\t},\n\n\t\tgetIndexAngle : function(index){\n\t\t\tvar angleMultiplier = (Math.PI * 2) / this.valuesCount;\n\t\t\t// Start from the top instead of right, so remove a quarter of the circle\n\n\t\t\treturn index * angleMultiplier - (Math.PI/2);\n\t\t},\n\t\tgetPointPosition : function(index, distanceFromCenter){\n\t\t\tvar thisAngle = this.getIndexAngle(index);\n\t\t\treturn {\n\t\t\t\tx : (Math.cos(thisAngle) * distanceFromCenter) + this.xCenter,\n\t\t\t\ty : (Math.sin(thisAngle) * distanceFromCenter) + this.yCenter\n\t\t\t};\n\t\t},\n\t\tdraw: function(){\n\t\t\tif (this.display){\n\t\t\t\tvar ctx = this.ctx;\n\t\t\t\teach(this.yLabels, function(label, index){\n\t\t\t\t\t// Don't draw a centre value\n\t\t\t\t\tif (index > 0){\n\t\t\t\t\t\tvar yCenterOffset = index * (this.drawingArea/this.steps),\n\t\t\t\t\t\t\tyHeight = this.yCenter - yCenterOffset,\n\t\t\t\t\t\t\tpointPosition;\n\n\t\t\t\t\t\t// Draw circular lines around the scale\n\t\t\t\t\t\tif (this.lineWidth > 0){\n\t\t\t\t\t\t\tctx.strokeStyle = this.lineColor;\n\t\t\t\t\t\t\tctx.lineWidth = this.lineWidth;\n\n\t\t\t\t\t\t\tif(this.lineArc){\n\t\t\t\t\t\t\t\tctx.beginPath();\n\t\t\t\t\t\t\t\tctx.arc(this.xCenter, this.yCenter, yCenterOffset, 0, Math.PI*2);\n\t\t\t\t\t\t\t\tctx.closePath();\n\t\t\t\t\t\t\t\tctx.stroke();\n\t\t\t\t\t\t\t} else{\n\t\t\t\t\t\t\t\tctx.beginPath();\n\t\t\t\t\t\t\t\tfor (var i=0;i<this.valuesCount;i++)\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\tpointPosition = this.getPointPosition(i, this.calculateCenterOffset(this.min + (index * this.stepValue)));\n\t\t\t\t\t\t\t\t\tif (i === 0){\n\t\t\t\t\t\t\t\t\t\tctx.moveTo(pointPosition.x, pointPosition.y);\n\t\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\t\tctx.lineTo(pointPosition.x, pointPosition.y);\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tctx.closePath();\n\t\t\t\t\t\t\t\tctx.stroke();\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif(this.showLabels){\n\t\t\t\t\t\t\tctx.font = fontString(this.fontSize,this.fontStyle,this.fontFamily);\n\t\t\t\t\t\t\tif (this.showLabelBackdrop){\n\t\t\t\t\t\t\t\tvar labelWidth = ctx.measureText(label).width;\n\t\t\t\t\t\t\t\tctx.fillStyle = this.backdropColor;\n\t\t\t\t\t\t\t\tctx.fillRect(\n\t\t\t\t\t\t\t\t\tthis.xCenter - labelWidth/2 - this.backdropPaddingX,\n\t\t\t\t\t\t\t\t\tyHeight - this.fontSize/2 - this.backdropPaddingY,\n\t\t\t\t\t\t\t\t\tlabelWidth + this.backdropPaddingX*2,\n\t\t\t\t\t\t\t\t\tthis.fontSize + this.backdropPaddingY*2\n\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tctx.textAlign = 'center';\n\t\t\t\t\t\t\tctx.textBaseline = \"middle\";\n\t\t\t\t\t\t\tctx.fillStyle = this.fontColor;\n\t\t\t\t\t\t\tctx.fillText(label, this.xCenter, yHeight);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}, this);\n\n\t\t\t\tif (!this.lineArc){\n\t\t\t\t\tctx.lineWidth = this.angleLineWidth;\n\t\t\t\t\tctx.strokeStyle = this.angleLineColor;\n\t\t\t\t\tfor (var i = this.valuesCount - 1; i >= 0; i--) {\n\t\t\t\t\t\tvar centerOffset = null, outerPosition = null;\n\n\t\t\t\t\t\tif (this.angleLineWidth > 0){\n\t\t\t\t\t\t\tcenterOffset = this.calculateCenterOffset(this.max);\n\t\t\t\t\t\t\touterPosition = this.getPointPosition(i, centerOffset);\n\t\t\t\t\t\t\tctx.beginPath();\n\t\t\t\t\t\t\tctx.moveTo(this.xCenter, this.yCenter);\n\t\t\t\t\t\t\tctx.lineTo(outerPosition.x, outerPosition.y);\n\t\t\t\t\t\t\tctx.stroke();\n\t\t\t\t\t\t\tctx.closePath();\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif (this.backgroundColors && this.backgroundColors.length == this.valuesCount) {\n\t\t\t\t\t\t\tif (centerOffset == null)\n\t\t\t\t\t\t\t\tcenterOffset = this.calculateCenterOffset(this.max);\n\n\t\t\t\t\t\t\tif (outerPosition == null)\n\t\t\t\t\t\t\t\touterPosition = this.getPointPosition(i, centerOffset);\n\n\t\t\t\t\t\t\tvar previousOuterPosition = this.getPointPosition(i === 0 ? this.valuesCount - 1 : i - 1, centerOffset);\n\t\t\t\t\t\t\tvar nextOuterPosition = this.getPointPosition(i === this.valuesCount - 1 ? 0 : i + 1, centerOffset);\n\n\t\t\t\t\t\t\tvar previousOuterHalfway = { x: (previousOuterPosition.x + outerPosition.x) / 2, y: (previousOuterPosition.y + outerPosition.y) / 2 };\n\t\t\t\t\t\t\tvar nextOuterHalfway = { x: (outerPosition.x + nextOuterPosition.x) / 2, y: (outerPosition.y + nextOuterPosition.y) / 2 };\n\n\t\t\t\t\t\t\tctx.beginPath();\n\t\t\t\t\t\t\tctx.moveTo(this.xCenter, this.yCenter);\n\t\t\t\t\t\t\tctx.lineTo(previousOuterHalfway.x, previousOuterHalfway.y);\n\t\t\t\t\t\t\tctx.lineTo(outerPosition.x, outerPosition.y);\n\t\t\t\t\t\t\tctx.lineTo(nextOuterHalfway.x, nextOuterHalfway.y);\n\t\t\t\t\t\t\tctx.fillStyle = this.backgroundColors[i];\n\t\t\t\t\t\t\tctx.fill();\n\t\t\t\t\t\t\tctx.closePath();\n\t\t\t\t\t\t}\n\t\t\t\t\t\t// Extra 3px out for some label spacing\n\t\t\t\t\t\tvar pointLabelPosition = this.getPointPosition(i, this.calculateCenterOffset(this.max) + 5);\n\t\t\t\t\t\tctx.font = fontString(this.pointLabelFontSize,this.pointLabelFontStyle,this.pointLabelFontFamily);\n\t\t\t\t\t\tctx.fillStyle = this.pointLabelFontColor;\n\n\t\t\t\t\t\tvar labelsCount = this.labels.length,\n\t\t\t\t\t\t\thalfLabelsCount = this.labels.length/2,\n\t\t\t\t\t\t\tquarterLabelsCount = halfLabelsCount/2,\n\t\t\t\t\t\t\tupperHalf = (i < quarterLabelsCount || i > labelsCount - quarterLabelsCount),\n\t\t\t\t\t\t\texactQuarter = (i === quarterLabelsCount || i === labelsCount - quarterLabelsCount);\n\t\t\t\t\t\tif (i === 0){\n\t\t\t\t\t\t\tctx.textAlign = 'center';\n\t\t\t\t\t\t} else if(i === halfLabelsCount){\n\t\t\t\t\t\t\tctx.textAlign = 'center';\n\t\t\t\t\t\t} else if (i < halfLabelsCount){\n\t\t\t\t\t\t\tctx.textAlign = 'left';\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tctx.textAlign = 'right';\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// Set the correct text baseline based on outer positioning\n\t\t\t\t\t\tif (exactQuarter){\n\t\t\t\t\t\t\tctx.textBaseline = 'middle';\n\t\t\t\t\t\t} else if (upperHalf){\n\t\t\t\t\t\t\tctx.textBaseline = 'bottom';\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tctx.textBaseline = 'top';\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tctx.fillText(this.labels[i], pointLabelPosition.x, pointLabelPosition.y);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t});\n\n\tChart.animationService = {\n\t\tframeDuration: 17,\n\t\tanimations: [],\n\t\tdropFrames: 0,\n\t\taddAnimation: function(chartInstance, animationObject) {\n\t\t\tfor (var index = 0; index < this.animations.length; ++ index){\n\t\t\t\tif (this.animations[index].chartInstance === chartInstance){\n\t\t\t\t\t// replacing an in progress animation\n\t\t\t\t\tthis.animations[index].animationObject = animationObject;\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t}\n\t\t\t\n\t\t\tthis.animations.push({\n\t\t\t\tchartInstance: chartInstance,\n\t\t\t\tanimationObject: animationObject\n\t\t\t});\n\n\t\t\t// If there are no animations queued, manually kickstart a digest, for lack of a better word\n\t\t\tif (this.animations.length == 1) {\n\t\t\t\thelpers.requestAnimFrame.call(window, this.digestWrapper);\n\t\t\t}\n\t\t},\n\t\t// Cancel the animation for a given chart instance\n\t\tcancelAnimation: function(chartInstance) {\n\t\t\tvar index = helpers.findNextWhere(this.animations, function(animationWrapper) {\n\t\t\t\treturn animationWrapper.chartInstance === chartInstance;\n\t\t\t});\n\t\t\t\n\t\t\tif (index)\n\t\t\t{\n\t\t\t\tthis.animations.splice(index, 1);\n\t\t\t}\n\t\t},\n\t\t// calls startDigest with the proper context\n\t\tdigestWrapper: function() {\n\t\t\tChart.animationService.startDigest.call(Chart.animationService);\n\t\t},\n\t\tstartDigest: function() {\n\n\t\t\tvar startTime = Date.now();\n\t\t\tvar framesToDrop = 0;\n\n\t\t\tif(this.dropFrames > 1){\n\t\t\t\tframesToDrop = Math.floor(this.dropFrames);\n\t\t\t\tthis.dropFrames -= framesToDrop;\n\t\t\t}\n\n\t\t\tfor (var i = 0; i < this.animations.length; i++) {\n\n\t\t\t\tif (this.animations[i].animationObject.currentStep === null){\n\t\t\t\t\tthis.animations[i].animationObject.currentStep = 0;\n\t\t\t\t}\n\n\t\t\t\tthis.animations[i].animationObject.currentStep += 1 + framesToDrop;\n\t\t\t\tif(this.animations[i].animationObject.currentStep > this.animations[i].animationObject.numSteps){\n\t\t\t\t\tthis.animations[i].animationObject.currentStep = this.animations[i].animationObject.numSteps;\n\t\t\t\t}\n\t\t\t\t\n\t\t\t\tthis.animations[i].animationObject.render(this.animations[i].chartInstance, this.animations[i].animationObject);\n\t\t\t\t\n\t\t\t\t// Check if executed the last frame.\n\t\t\t\tif (this.animations[i].animationObject.currentStep == this.animations[i].animationObject.numSteps){\n\t\t\t\t\t// Call onAnimationComplete\n\t\t\t\t\tthis.animations[i].animationObject.onAnimationComplete.call(this.animations[i].chartInstance);\n\t\t\t\t\t// Remove the animation.\n\t\t\t\t\tthis.animations.splice(i, 1);\n\t\t\t\t\t// Keep the index in place to offset the splice\n\t\t\t\t\ti--;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tvar endTime = Date.now();\n\t\t\tvar delay = endTime - startTime - this.frameDuration;\n\t\t\tvar frameDelay = delay / this.frameDuration;\n\n\t\t\tif(frameDelay > 1){\n\t\t\t\tthis.dropFrames += frameDelay;\n\t\t\t}\n\n\t\t\t// Do we have more stuff to animate?\n\t\t\tif (this.animations.length > 0){\n\t\t\t\thelpers.requestAnimFrame.call(window, this.digestWrapper);\n\t\t\t}\n\t\t}\n\t};\n\n\t// Attach global event to resize each chart instance when the browser resizes\n\thelpers.addEvent(window, \"resize\", (function(){\n\t\t// Basic debounce of resize function so it doesn't hurt performance when resizing browser.\n\t\tvar timeout;\n\t\treturn function(){\n\t\t\tclearTimeout(timeout);\n\t\t\ttimeout = setTimeout(function(){\n\t\t\t\teach(Chart.instances,function(instance){\n\t\t\t\t\t// If the responsive flag is set in the chart instance config\n\t\t\t\t\t// Cascade the resize event down to the chart.\n\t\t\t\t\tif (instance.options.responsive){\n\t\t\t\t\t\tinstance.resize(instance.render, true);\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t}, 50);\n\t\t};\n\t})());\n\n\n\tif (amd) {\n\t\tdefine('Chart', [], function(){\n\t\t\treturn Chart;\n\t\t});\n\t} else if (typeof module === 'object' && module.exports) {\n\t\tmodule.exports = Chart;\n\t}\n\n\troot.Chart = Chart;\n\n\tChart.noConflict = function(){\n\t\troot.Chart = previous;\n\t\treturn Chart;\n\t};\n\n}).call(this);\n\n(function(){\n\t\"use strict\";\n\n\tvar root = this,\n\t\tChart = root.Chart,\n\t\thelpers = Chart.helpers;\n\n\n\tvar defaultConfig = {\n\t\t//Boolean - Whether the scale should start at zero, or an order of magnitude down from the lowest value\n\t\tscaleBeginAtZero : true,\n\n\t\t//Boolean - Whether grid lines are shown across the chart\n\t\tscaleShowGridLines : true,\n\n\t\t//String - Colour of the grid lines\n\t\tscaleGridLineColor : \"rgba(0,0,0,.05)\",\n\n\t\t//Number - Width of the grid lines\n\t\tscaleGridLineWidth : 1,\n\n\t\t//Boolean - Whether to show horizontal lines (except X axis)\n\t\tscaleShowHorizontalLines: true,\n\n\t\t//Boolean - Whether to show vertical lines (except Y axis)\n\t\tscaleShowVerticalLines: true,\n\n\t\t//Boolean - If there is a stroke on each bar\n\t\tbarShowStroke : true,\n\n\t\t//Number - Pixel width of the bar stroke\n\t\tbarStrokeWidth : 2,\n\n\t\t//Number - Spacing between each of the X value sets\n\t\tbarValueSpacing : 5,\n\n\t\t//Number - Spacing between data sets within X values\n\t\tbarDatasetSpacing : 1,\n\n\t\t//String - A legend template\n\t\tlegendTemplate : \"<ul class=\\\"<%=name.toLowerCase()%>-legend\\\"><% for (var i=0; i<datasets.length; i++){%><li><span style=\\\"background-color:<%=datasets[i].fillColor%>\\\"><%if(datasets[i].label){%><%=datasets[i].label%><%}%></span></li><%}%></ul>\"\n\n\t};\n\n\n\tChart.Type.extend({\n\t\tname: \"Bar\",\n\t\tdefaults : defaultConfig,\n\t\tinitialize:  function(data){\n\n\t\t\t//Expose options as a scope variable here so we can access it in the ScaleClass\n\t\t\tvar options = this.options;\n\n\t\t\tthis.ScaleClass = Chart.Scale.extend({\n\t\t\t\toffsetGridLines : true,\n\t\t\t\tcalculateBarX : function(datasetCount, datasetIndex, barIndex){\n\t\t\t\t\t//Reusable method for calculating the xPosition of a given bar based on datasetIndex & width of the bar\n\t\t\t\t\tvar xWidth = this.calculateBaseWidth(),\n\t\t\t\t\t\txAbsolute = this.calculateX(barIndex) - (xWidth/2),\n\t\t\t\t\t\tbarWidth = this.calculateBarWidth(datasetCount);\n\n\t\t\t\t\treturn xAbsolute + (barWidth * datasetIndex) + (datasetIndex * options.barDatasetSpacing) + barWidth/2;\n\t\t\t\t},\n\t\t\t\tcalculateBaseWidth : function(){\n\t\t\t\t\treturn (this.calculateX(1) - this.calculateX(0)) - (2*options.barValueSpacing);\n\t\t\t\t},\n\t\t\t\tcalculateBarWidth : function(datasetCount){\n\t\t\t\t\t//The padding between datasets is to the right of each bar, providing that there are more than 1 dataset\n\t\t\t\t\tvar baseWidth = this.calculateBaseWidth() - ((datasetCount - 1) * options.barDatasetSpacing);\n\n\t\t\t\t\treturn (baseWidth / datasetCount);\n\t\t\t\t}\n\t\t\t});\n\n\t\t\tthis.datasets = [];\n\n\t\t\t//Set up tooltip events on the chart\n\t\t\tif (this.options.showTooltips){\n\t\t\t\thelpers.bindEvents(this, this.options.tooltipEvents, function(evt){\n\t\t\t\t\tvar activeBars = (evt.type !== 'mouseout') ? this.getBarsAtEvent(evt) : [];\n\n\t\t\t\t\tthis.eachBars(function(bar){\n\t\t\t\t\t\tbar.restore(['fillColor', 'strokeColor']);\n\t\t\t\t\t});\n\t\t\t\t\thelpers.each(activeBars, function(activeBar){\n\t\t\t\t\t\tactiveBar.fillColor = activeBar.highlightFill;\n\t\t\t\t\t\tactiveBar.strokeColor = activeBar.highlightStroke;\n\t\t\t\t\t});\n\t\t\t\t\tthis.showTooltip(activeBars);\n\t\t\t\t});\n\t\t\t}\n\n\t\t\t//Declare the extension of the default point, to cater for the options passed in to the constructor\n\t\t\tthis.BarClass = Chart.Rectangle.extend({\n\t\t\t\tstrokeWidth : this.options.barStrokeWidth,\n\t\t\t\tshowStroke : this.options.barShowStroke,\n\t\t\t\tctx : this.chart.ctx\n\t\t\t});\n\n\t\t\t//Iterate through each of the datasets, and build this into a property of the chart\n\t\t\thelpers.each(data.datasets,function(dataset,datasetIndex){\n\n\t\t\t\tvar datasetObject = {\n\t\t\t\t\tlabel : dataset.label || null,\n\t\t\t\t\tfillColor : dataset.fillColor,\n\t\t\t\t\tstrokeColor : dataset.strokeColor,\n\t\t\t\t\tbars : []\n\t\t\t\t};\n\n\t\t\t\tthis.datasets.push(datasetObject);\n\n\t\t\t\thelpers.each(dataset.data,function(dataPoint,index){\n\t\t\t\t\t//Add a new point for each piece of data, passing any required data to draw.\n\t\t\t\t\tdatasetObject.bars.push(new this.BarClass({\n\t\t\t\t\t\tvalue : dataPoint,\n\t\t\t\t\t\tlabel : data.labels[index],\n\t\t\t\t\t\tdatasetLabel: dataset.label,\n\t\t\t\t\t\tstrokeColor : dataset.strokeColor,\n\t\t\t\t\t\tfillColor : dataset.fillColor,\n\t\t\t\t\t\thighlightFill : dataset.highlightFill || dataset.fillColor,\n\t\t\t\t\t\thighlightStroke : dataset.highlightStroke || dataset.strokeColor\n\t\t\t\t\t}));\n\t\t\t\t},this);\n\n\t\t\t},this);\n\n\t\t\tthis.buildScale(data.labels);\n\n\t\t\tthis.BarClass.prototype.base = this.scale.endPoint;\n\n\t\t\tthis.eachBars(function(bar, index, datasetIndex){\n\t\t\t\thelpers.extend(bar, {\n\t\t\t\t\twidth : this.scale.calculateBarWidth(this.datasets.length),\n\t\t\t\t\tx: this.scale.calculateBarX(this.datasets.length, datasetIndex, index),\n\t\t\t\t\ty: this.scale.endPoint\n\t\t\t\t});\n\t\t\t\tbar.save();\n\t\t\t}, this);\n\n\t\t\tthis.render();\n\t\t},\n\t\tupdate : function(){\n\t\t\tthis.scale.update();\n\t\t\t// Reset any highlight colours before updating.\n\t\t\thelpers.each(this.activeElements, function(activeElement){\n\t\t\t\tactiveElement.restore(['fillColor', 'strokeColor']);\n\t\t\t});\n\n\t\t\tthis.eachBars(function(bar){\n\t\t\t\tbar.save();\n\t\t\t});\n\t\t\tthis.render();\n\t\t},\n\t\teachBars : function(callback){\n\t\t\thelpers.each(this.datasets,function(dataset, datasetIndex){\n\t\t\t\thelpers.each(dataset.bars, callback, this, datasetIndex);\n\t\t\t},this);\n\t\t},\n\t\tgetBarsAtEvent : function(e){\n\t\t\tvar barsArray = [],\n\t\t\t\teventPosition = helpers.getRelativePosition(e),\n\t\t\t\tdatasetIterator = function(dataset){\n\t\t\t\t\tbarsArray.push(dataset.bars[barIndex]);\n\t\t\t\t},\n\t\t\t\tbarIndex;\n\n\t\t\tfor (var datasetIndex = 0; datasetIndex < this.datasets.length; datasetIndex++) {\n\t\t\t\tfor (barIndex = 0; barIndex < this.datasets[datasetIndex].bars.length; barIndex++) {\n\t\t\t\t\tif (this.datasets[datasetIndex].bars[barIndex].inRange(eventPosition.x,eventPosition.y)){\n\t\t\t\t\t\thelpers.each(this.datasets, datasetIterator);\n\t\t\t\t\t\treturn barsArray;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn barsArray;\n\t\t},\n\t\tbuildScale : function(labels){\n\t\t\tvar self = this;\n\n\t\t\tvar dataTotal = function(){\n\t\t\t\tvar values = [];\n\t\t\t\tself.eachBars(function(bar){\n\t\t\t\t\tvalues.push(bar.value);\n\t\t\t\t});\n\t\t\t\treturn values;\n\t\t\t};\n\n\t\t\tvar scaleOptions = {\n\t\t\t\ttemplateString : this.options.scaleLabel,\n\t\t\t\theight : this.chart.height,\n\t\t\t\twidth : this.chart.width,\n\t\t\t\tctx : this.chart.ctx,\n\t\t\t\ttextColor : this.options.scaleFontColor,\n\t\t\t\tfontSize : this.options.scaleFontSize,\n\t\t\t\tfontStyle : this.options.scaleFontStyle,\n\t\t\t\tfontFamily : this.options.scaleFontFamily,\n\t\t\t\tvaluesCount : labels.length,\n\t\t\t\tbeginAtZero : this.options.scaleBeginAtZero,\n\t\t\t\tintegersOnly : this.options.scaleIntegersOnly,\n\t\t\t\tcalculateYRange: function(currentHeight){\n\t\t\t\t\tvar updatedRanges = helpers.calculateScaleRange(\n\t\t\t\t\t\tdataTotal(),\n\t\t\t\t\t\tcurrentHeight,\n\t\t\t\t\t\tthis.fontSize,\n\t\t\t\t\t\tthis.beginAtZero,\n\t\t\t\t\t\tthis.integersOnly\n\t\t\t\t\t);\n\t\t\t\t\thelpers.extend(this, updatedRanges);\n\t\t\t\t},\n\t\t\t\txLabels : labels,\n\t\t\t\tfont : helpers.fontString(this.options.scaleFontSize, this.options.scaleFontStyle, this.options.scaleFontFamily),\n\t\t\t\tlineWidth : this.options.scaleLineWidth,\n\t\t\t\tlineColor : this.options.scaleLineColor,\n\t\t\t\tshowHorizontalLines : this.options.scaleShowHorizontalLines,\n\t\t\t\tshowVerticalLines : this.options.scaleShowVerticalLines,\n\t\t\t\tgridLineWidth : (this.options.scaleShowGridLines) ? this.options.scaleGridLineWidth : 0,\n\t\t\t\tgridLineColor : (this.options.scaleShowGridLines) ? this.options.scaleGridLineColor : \"rgba(0,0,0,0)\",\n\t\t\t\tpadding : (this.options.showScale) ? 0 : (this.options.barShowStroke) ? this.options.barStrokeWidth : 0,\n\t\t\t\tshowLabels : this.options.scaleShowLabels,\n\t\t\t\tdisplay : this.options.showScale\n\t\t\t};\n\n\t\t\tif (this.options.scaleOverride){\n\t\t\t\thelpers.extend(scaleOptions, {\n\t\t\t\t\tcalculateYRange: helpers.noop,\n\t\t\t\t\tsteps: this.options.scaleSteps,\n\t\t\t\t\tstepValue: this.options.scaleStepWidth,\n\t\t\t\t\tmin: this.options.scaleStartValue,\n\t\t\t\t\tmax: this.options.scaleStartValue + (this.options.scaleSteps * this.options.scaleStepWidth)\n\t\t\t\t});\n\t\t\t}\n\n\t\t\tthis.scale = new this.ScaleClass(scaleOptions);\n\t\t},\n\t\taddData : function(valuesArray,label){\n\t\t\t//Map the values array for each of the datasets\n\t\t\thelpers.each(valuesArray,function(value,datasetIndex){\n\t\t\t\t//Add a new point for each piece of data, passing any required data to draw.\n\t\t\t\tthis.datasets[datasetIndex].bars.push(new this.BarClass({\n\t\t\t\t\tvalue : value,\n\t\t\t\t\tlabel : label,\n\t\t\t\t\tdatasetLabel: this.datasets[datasetIndex].label,\n\t\t\t\t\tx: this.scale.calculateBarX(this.datasets.length, datasetIndex, this.scale.valuesCount+1),\n\t\t\t\t\ty: this.scale.endPoint,\n\t\t\t\t\twidth : this.scale.calculateBarWidth(this.datasets.length),\n\t\t\t\t\tbase : this.scale.endPoint,\n\t\t\t\t\tstrokeColor : this.datasets[datasetIndex].strokeColor,\n\t\t\t\t\tfillColor : this.datasets[datasetIndex].fillColor\n\t\t\t\t}));\n\t\t\t},this);\n\n\t\t\tthis.scale.addXLabel(label);\n\t\t\t//Then re-render the chart.\n\t\t\tthis.update();\n\t\t},\n\t\tremoveData : function(){\n\t\t\tthis.scale.removeXLabel();\n\t\t\t//Then re-render the chart.\n\t\t\thelpers.each(this.datasets,function(dataset){\n\t\t\t\tdataset.bars.shift();\n\t\t\t},this);\n\t\t\tthis.update();\n\t\t},\n\t\treflow : function(){\n\t\t\thelpers.extend(this.BarClass.prototype,{\n\t\t\t\ty: this.scale.endPoint,\n\t\t\t\tbase : this.scale.endPoint\n\t\t\t});\n\t\t\tvar newScaleProps = helpers.extend({\n\t\t\t\theight : this.chart.height,\n\t\t\t\twidth : this.chart.width\n\t\t\t});\n\t\t\tthis.scale.update(newScaleProps);\n\t\t},\n\t\tdraw : function(ease){\n\t\t\tvar easingDecimal = ease || 1;\n\t\t\tthis.clear();\n\n\t\t\tvar ctx = this.chart.ctx;\n\n\t\t\tthis.scale.draw(easingDecimal);\n\n\t\t\t//Draw all the bars for each dataset\n\t\t\thelpers.each(this.datasets,function(dataset,datasetIndex){\n\t\t\t\thelpers.each(dataset.bars,function(bar,index){\n\t\t\t\t\tif (bar.hasValue()){\n\t\t\t\t\t\tbar.base = this.scale.endPoint;\n\t\t\t\t\t\t//Transition then draw\n\t\t\t\t\t\tbar.transition({\n\t\t\t\t\t\t\tx : this.scale.calculateBarX(this.datasets.length, datasetIndex, index),\n\t\t\t\t\t\t\ty : this.scale.calculateY(bar.value),\n\t\t\t\t\t\t\twidth : this.scale.calculateBarWidth(this.datasets.length)\n\t\t\t\t\t\t}, easingDecimal).draw();\n\t\t\t\t\t}\n\t\t\t\t},this);\n\n\t\t\t},this);\n\t\t}\n\t});\n\n\n}).call(this);\n\n(function(){\n\t\"use strict\";\n\n\tvar root = this,\n\t\tChart = root.Chart,\n\t\t//Cache a local reference to Chart.helpers\n\t\thelpers = Chart.helpers;\n\n\tvar defaultConfig = {\n\t\t//Boolean - Whether we should show a stroke on each segment\n\t\tsegmentShowStroke : true,\n\n\t\t//String - The colour of each segment stroke\n\t\tsegmentStrokeColor : \"#fff\",\n\n\t\t//Number - The width of each segment stroke\n\t\tsegmentStrokeWidth : 2,\n\n\t\t//The percentage of the chart that we cut out of the middle.\n\t\tpercentageInnerCutout : 50,\n\n\t\t//Number - Amount of animation steps\n\t\tanimationSteps : 100,\n\n\t\t//String - Animation easing effect\n\t\tanimationEasing : \"easeOutBounce\",\n\n\t\t//Boolean - Whether we animate the rotation of the Doughnut\n\t\tanimateRotate : true,\n\n\t\t//Boolean - Whether we animate scaling the Doughnut from the centre\n\t\tanimateScale : false,\n\n\t\t//String - A legend template\n\t\tlegendTemplate : \"<ul class=\\\"<%=name.toLowerCase()%>-legend\\\"><% for (var i=0; i<segments.length; i++){%><li><span style=\\\"background-color:<%=segments[i].fillColor%>\\\"><%if(segments[i].label){%><%=segments[i].label%><%}%></span></li><%}%></ul>\"\n\n\t};\n\n\tChart.Type.extend({\n\t\t//Passing in a name registers this chart in the Chart namespace\n\t\tname: \"Doughnut\",\n\t\t//Providing a defaults will also register the deafults in the chart namespace\n\t\tdefaults : defaultConfig,\n\t\t//Initialize is fired when the chart is initialized - Data is passed in as a parameter\n\t\t//Config is automatically merged by the core of Chart.js, and is available at this.options\n\t\tinitialize:  function(data){\n\n\t\t\t//Declare segments as a static property to prevent inheriting across the Chart type prototype\n\t\t\tthis.segments = [];\n\t\t\tthis.outerRadius = (helpers.min([this.chart.width,this.chart.height]) -\tthis.options.segmentStrokeWidth/2)/2;\n\n\t\t\tthis.SegmentArc = Chart.Arc.extend({\n\t\t\t\tctx : this.chart.ctx,\n\t\t\t\tx : this.chart.width/2,\n\t\t\t\ty : this.chart.height/2\n\t\t\t});\n\n\t\t\t//Set up tooltip events on the chart\n\t\t\tif (this.options.showTooltips){\n\t\t\t\thelpers.bindEvents(this, this.options.tooltipEvents, function(evt){\n\t\t\t\t\tvar activeSegments = (evt.type !== 'mouseout') ? this.getSegmentsAtEvent(evt) : [];\n\n\t\t\t\t\thelpers.each(this.segments,function(segment){\n\t\t\t\t\t\tsegment.restore([\"fillColor\"]);\n\t\t\t\t\t});\n\t\t\t\t\thelpers.each(activeSegments,function(activeSegment){\n\t\t\t\t\t\tactiveSegment.fillColor = activeSegment.highlightColor;\n\t\t\t\t\t});\n\t\t\t\t\tthis.showTooltip(activeSegments);\n\t\t\t\t});\n\t\t\t}\n\t\t\tthis.calculateTotal(data);\n\n\t\t\thelpers.each(data,function(datapoint, index){\n\t\t\t\tif (!datapoint.color) {\n\t\t\t\t\tdatapoint.color = 'hsl(' + (360 * index / data.length) + ', 100%, 50%)';\n\t\t\t\t}\n\t\t\t\tthis.addData(datapoint, index, true);\n\t\t\t},this);\n\n\t\t\tthis.render();\n\t\t},\n\t\tgetSegmentsAtEvent : function(e){\n\t\t\tvar segmentsArray = [];\n\n\t\t\tvar location = helpers.getRelativePosition(e);\n\n\t\t\thelpers.each(this.segments,function(segment){\n\t\t\t\tif (segment.inRange(location.x,location.y)) segmentsArray.push(segment);\n\t\t\t},this);\n\t\t\treturn segmentsArray;\n\t\t},\n\t\taddData : function(segment, atIndex, silent){\n\t\t\tvar index = atIndex !== undefined ? atIndex : this.segments.length;\n\t\t\tif ( typeof(segment.color) === \"undefined\" ) {\n\t\t\t\tsegment.color = Chart.defaults.global.segmentColorDefault[index % Chart.defaults.global.segmentColorDefault.length];\n\t\t\t\tsegment.highlight = Chart.defaults.global.segmentHighlightColorDefaults[index % Chart.defaults.global.segmentHighlightColorDefaults.length];\t\t\t\t\n\t\t\t}\n\t\t\tthis.segments.splice(index, 0, new this.SegmentArc({\n\t\t\t\tvalue : segment.value,\n\t\t\t\touterRadius : (this.options.animateScale) ? 0 : this.outerRadius,\n\t\t\t\tinnerRadius : (this.options.animateScale) ? 0 : (this.outerRadius/100) * this.options.percentageInnerCutout,\n\t\t\t\tfillColor : segment.color,\n\t\t\t\thighlightColor : segment.highlight || segment.color,\n\t\t\t\tshowStroke : this.options.segmentShowStroke,\n\t\t\t\tstrokeWidth : this.options.segmentStrokeWidth,\n\t\t\t\tstrokeColor : this.options.segmentStrokeColor,\n\t\t\t\tstartAngle : Math.PI * 1.5,\n\t\t\t\tcircumference : (this.options.animateRotate) ? 0 : this.calculateCircumference(segment.value),\n\t\t\t\tlabel : segment.label\n\t\t\t}));\n\t\t\tif (!silent){\n\t\t\t\tthis.reflow();\n\t\t\t\tthis.update();\n\t\t\t}\n\t\t},\n\t\tcalculateCircumference : function(value) {\n\t\t\tif ( this.total > 0 ) {\n\t\t\t\treturn (Math.PI*2)*(value / this.total);\n\t\t\t} else {\n\t\t\t\treturn 0;\n\t\t\t}\n\t\t},\n\t\tcalculateTotal : function(data){\n\t\t\tthis.total = 0;\n\t\t\thelpers.each(data,function(segment){\n\t\t\t\tthis.total += Math.abs(segment.value);\n\t\t\t},this);\n\t\t},\n\t\tupdate : function(){\n\t\t\tthis.calculateTotal(this.segments);\n\n\t\t\t// Reset any highlight colours before updating.\n\t\t\thelpers.each(this.activeElements, function(activeElement){\n\t\t\t\tactiveElement.restore(['fillColor']);\n\t\t\t});\n\n\t\t\thelpers.each(this.segments,function(segment){\n\t\t\t\tsegment.save();\n\t\t\t});\n\t\t\tthis.render();\n\t\t},\n\n\t\tremoveData: function(atIndex){\n\t\t\tvar indexToDelete = (helpers.isNumber(atIndex)) ? atIndex : this.segments.length-1;\n\t\t\tthis.segments.splice(indexToDelete, 1);\n\t\t\tthis.reflow();\n\t\t\tthis.update();\n\t\t},\n\n\t\treflow : function(){\n\t\t\thelpers.extend(this.SegmentArc.prototype,{\n\t\t\t\tx : this.chart.width/2,\n\t\t\t\ty : this.chart.height/2\n\t\t\t});\n\t\t\tthis.outerRadius = (helpers.min([this.chart.width,this.chart.height]) -\tthis.options.segmentStrokeWidth/2)/2;\n\t\t\thelpers.each(this.segments, function(segment){\n\t\t\t\tsegment.update({\n\t\t\t\t\touterRadius : this.outerRadius,\n\t\t\t\t\tinnerRadius : (this.outerRadius/100) * this.options.percentageInnerCutout\n\t\t\t\t});\n\t\t\t}, this);\n\t\t},\n\t\tdraw : function(easeDecimal){\n\t\t\tvar animDecimal = (easeDecimal) ? easeDecimal : 1;\n\t\t\tthis.clear();\n\t\t\thelpers.each(this.segments,function(segment,index){\n\t\t\t\tsegment.transition({\n\t\t\t\t\tcircumference : this.calculateCircumference(segment.value),\n\t\t\t\t\touterRadius : this.outerRadius,\n\t\t\t\t\tinnerRadius : (this.outerRadius/100) * this.options.percentageInnerCutout\n\t\t\t\t},animDecimal);\n\n\t\t\t\tsegment.endAngle = segment.startAngle + segment.circumference;\n\n\t\t\t\tsegment.draw();\n\t\t\t\tif (index === 0){\n\t\t\t\t\tsegment.startAngle = Math.PI * 1.5;\n\t\t\t\t}\n\t\t\t\t//Check to see if it's the last segment, if not get the next and update the start angle\n\t\t\t\tif (index < this.segments.length-1){\n\t\t\t\t\tthis.segments[index+1].startAngle = segment.endAngle;\n\t\t\t\t}\n\t\t\t},this);\n\n\t\t}\n\t});\n\n\tChart.types.Doughnut.extend({\n\t\tname : \"Pie\",\n\t\tdefaults : helpers.merge(defaultConfig,{percentageInnerCutout : 0})\n\t});\n\n}).call(this);\n\n(function(){\n\t\"use strict\";\n\n\tvar root = this,\n\t\tChart = root.Chart,\n\t\thelpers = Chart.helpers;\n\n\tvar defaultConfig = {\n\n\t\t///Boolean - Whether grid lines are shown across the chart\n\t\tscaleShowGridLines : true,\n\n\t\t//String - Colour of the grid lines\n\t\tscaleGridLineColor : \"rgba(0,0,0,.05)\",\n\n\t\t//Number - Width of the grid lines\n\t\tscaleGridLineWidth : 1,\n\n\t\t//Boolean - Whether to show horizontal lines (except X axis)\n\t\tscaleShowHorizontalLines: true,\n\n\t\t//Boolean - Whether to show vertical lines (except Y axis)\n\t\tscaleShowVerticalLines: true,\n\n\t\t//Boolean - Whether the line is curved between points\n\t\tbezierCurve : true,\n\n\t\t//Number - Tension of the bezier curve between points\n\t\tbezierCurveTension : 0.4,\n\n\t\t//Boolean - Whether to show a dot for each point\n\t\tpointDot : true,\n\n\t\t//Number - Radius of each point dot in pixels\n\t\tpointDotRadius : 4,\n\n\t\t//Number - Pixel width of point dot stroke\n\t\tpointDotStrokeWidth : 1,\n\n\t\t//Number - amount extra to add to the radius to cater for hit detection outside the drawn point\n\t\tpointHitDetectionRadius : 20,\n\n\t\t//Boolean - Whether to show a stroke for datasets\n\t\tdatasetStroke : true,\n\n\t\t//Number - Pixel width of dataset stroke\n\t\tdatasetStrokeWidth : 2,\n\n\t\t//Boolean - Whether to fill the dataset with a colour\n\t\tdatasetFill : true,\n\n\t\t//String - A legend template\n\t\tlegendTemplate : \"<ul class=\\\"<%=name.toLowerCase()%>-legend\\\"><% for (var i=0; i<datasets.length; i++){%><li><span style=\\\"background-color:<%=datasets[i].strokeColor%>\\\"><%if(datasets[i].label){%><%=datasets[i].label%><%}%></span></li><%}%></ul>\",\n\n\t\t//Boolean - Whether to horizontally center the label and point dot inside the grid\n\t\toffsetGridLines : false\n\n\t};\n\n\n\tChart.Type.extend({\n\t\tname: \"Line\",\n\t\tdefaults : defaultConfig,\n\t\tinitialize:  function(data){\n\t\t\t//Declare the extension of the default point, to cater for the options passed in to the constructor\n\t\t\tthis.PointClass = Chart.Point.extend({\n\t\t\t\toffsetGridLines : this.options.offsetGridLines,\n\t\t\t\tstrokeWidth : this.options.pointDotStrokeWidth,\n\t\t\t\tradius : this.options.pointDotRadius,\n\t\t\t\tdisplay: this.options.pointDot,\n\t\t\t\thitDetectionRadius : this.options.pointHitDetectionRadius,\n\t\t\t\tctx : this.chart.ctx,\n\t\t\t\tinRange : function(mouseX){\n\t\t\t\t\treturn (Math.pow(mouseX-this.x, 2) < Math.pow(this.radius + this.hitDetectionRadius,2));\n\t\t\t\t}\n\t\t\t});\n\n\t\t\tthis.datasets = [];\n\n\t\t\t//Set up tooltip events on the chart\n\t\t\tif (this.options.showTooltips){\n\t\t\t\thelpers.bindEvents(this, this.options.tooltipEvents, function(evt){\n\t\t\t\t\tvar activePoints = (evt.type !== 'mouseout') ? this.getPointsAtEvent(evt) : [];\n\t\t\t\t\tthis.eachPoints(function(point){\n\t\t\t\t\t\tpoint.restore(['fillColor', 'strokeColor']);\n\t\t\t\t\t});\n\t\t\t\t\thelpers.each(activePoints, function(activePoint){\n\t\t\t\t\t\tactivePoint.fillColor = activePoint.highlightFill;\n\t\t\t\t\t\tactivePoint.strokeColor = activePoint.highlightStroke;\n\t\t\t\t\t});\n\t\t\t\t\tthis.showTooltip(activePoints);\n\t\t\t\t});\n\t\t\t}\n\n\t\t\t//Iterate through each of the datasets, and build this into a property of the chart\n\t\t\thelpers.each(data.datasets,function(dataset){\n\n\t\t\t\tvar datasetObject = {\n\t\t\t\t\tlabel : dataset.label || null,\n\t\t\t\t\tfillColor : dataset.fillColor,\n\t\t\t\t\tstrokeColor : dataset.strokeColor,\n\t\t\t\t\tpointColor : dataset.pointColor,\n\t\t\t\t\tpointStrokeColor : dataset.pointStrokeColor,\n\t\t\t\t\tpoints : []\n\t\t\t\t};\n\n\t\t\t\tthis.datasets.push(datasetObject);\n\n\n\t\t\t\thelpers.each(dataset.data,function(dataPoint,index){\n\t\t\t\t\t//Add a new point for each piece of data, passing any required data to draw.\n\t\t\t\t\tdatasetObject.points.push(new this.PointClass({\n\t\t\t\t\t\tvalue : dataPoint,\n\t\t\t\t\t\tlabel : data.labels[index],\n\t\t\t\t\t\tdatasetLabel: dataset.label,\n\t\t\t\t\t\tstrokeColor : dataset.pointStrokeColor,\n\t\t\t\t\t\tfillColor : dataset.pointColor,\n\t\t\t\t\t\thighlightFill : dataset.pointHighlightFill || dataset.pointColor,\n\t\t\t\t\t\thighlightStroke : dataset.pointHighlightStroke || dataset.pointStrokeColor\n\t\t\t\t\t}));\n\t\t\t\t},this);\n\n\t\t\t\tthis.buildScale(data.labels);\n\n\n\t\t\t\tthis.eachPoints(function(point, index){\n\t\t\t\t\thelpers.extend(point, {\n\t\t\t\t\t\tx: this.scale.calculateX(index),\n\t\t\t\t\t\ty: this.scale.endPoint\n\t\t\t\t\t});\n\t\t\t\t\tpoint.save();\n\t\t\t\t}, this);\n\n\t\t\t},this);\n\n\n\t\t\tthis.render();\n\t\t},\n\t\tupdate : function(){\n\t\t\tthis.scale.update();\n\t\t\t// Reset any highlight colours before updating.\n\t\t\thelpers.each(this.activeElements, function(activeElement){\n\t\t\t\tactiveElement.restore(['fillColor', 'strokeColor']);\n\t\t\t});\n\t\t\tthis.eachPoints(function(point){\n\t\t\t\tpoint.save();\n\t\t\t});\n\t\t\tthis.render();\n\t\t},\n\t\teachPoints : function(callback){\n\t\t\thelpers.each(this.datasets,function(dataset){\n\t\t\t\thelpers.each(dataset.points,callback,this);\n\t\t\t},this);\n\t\t},\n\t\tgetPointsAtEvent : function(e){\n\t\t\tvar pointsArray = [],\n\t\t\t\teventPosition = helpers.getRelativePosition(e);\n\t\t\thelpers.each(this.datasets,function(dataset){\n\t\t\t\thelpers.each(dataset.points,function(point){\n\t\t\t\t\tif (point.inRange(eventPosition.x,eventPosition.y)) pointsArray.push(point);\n\t\t\t\t});\n\t\t\t},this);\n\t\t\treturn pointsArray;\n\t\t},\n\t\tbuildScale : function(labels){\n\t\t\tvar self = this;\n\n\t\t\tvar dataTotal = function(){\n\t\t\t\tvar values = [];\n\t\t\t\tself.eachPoints(function(point){\n\t\t\t\t\tvalues.push(point.value);\n\t\t\t\t});\n\n\t\t\t\treturn values;\n\t\t\t};\n\n\t\t\tvar scaleOptions = {\n\t\t\t\ttemplateString : this.options.scaleLabel,\n\t\t\t\theight : this.chart.height,\n\t\t\t\twidth : this.chart.width,\n\t\t\t\tctx : this.chart.ctx,\n\t\t\t\ttextColor : this.options.scaleFontColor,\n\t\t\t\toffsetGridLines : this.options.offsetGridLines,\n\t\t\t\tfontSize : this.options.scaleFontSize,\n\t\t\t\tfontStyle : this.options.scaleFontStyle,\n\t\t\t\tfontFamily : this.options.scaleFontFamily,\n\t\t\t\tvaluesCount : labels.length,\n\t\t\t\tbeginAtZero : this.options.scaleBeginAtZero,\n\t\t\t\tintegersOnly : this.options.scaleIntegersOnly,\n\t\t\t\tcalculateYRange : function(currentHeight){\n\t\t\t\t\tvar updatedRanges = helpers.calculateScaleRange(\n\t\t\t\t\t\tdataTotal(),\n\t\t\t\t\t\tcurrentHeight,\n\t\t\t\t\t\tthis.fontSize,\n\t\t\t\t\t\tthis.beginAtZero,\n\t\t\t\t\t\tthis.integersOnly\n\t\t\t\t\t);\n\t\t\t\t\thelpers.extend(this, updatedRanges);\n\t\t\t\t},\n\t\t\t\txLabels : labels,\n\t\t\t\tfont : helpers.fontString(this.options.scaleFontSize, this.options.scaleFontStyle, this.options.scaleFontFamily),\n\t\t\t\tlineWidth : this.options.scaleLineWidth,\n\t\t\t\tlineColor : this.options.scaleLineColor,\n\t\t\t\tshowHorizontalLines : this.options.scaleShowHorizontalLines,\n\t\t\t\tshowVerticalLines : this.options.scaleShowVerticalLines,\n\t\t\t\tgridLineWidth : (this.options.scaleShowGridLines) ? this.options.scaleGridLineWidth : 0,\n\t\t\t\tgridLineColor : (this.options.scaleShowGridLines) ? this.options.scaleGridLineColor : \"rgba(0,0,0,0)\",\n\t\t\t\tpadding: (this.options.showScale) ? 0 : this.options.pointDotRadius + this.options.pointDotStrokeWidth,\n\t\t\t\tshowLabels : this.options.scaleShowLabels,\n\t\t\t\tdisplay : this.options.showScale\n\t\t\t};\n\n\t\t\tif (this.options.scaleOverride){\n\t\t\t\thelpers.extend(scaleOptions, {\n\t\t\t\t\tcalculateYRange: helpers.noop,\n\t\t\t\t\tsteps: this.options.scaleSteps,\n\t\t\t\t\tstepValue: this.options.scaleStepWidth,\n\t\t\t\t\tmin: this.options.scaleStartValue,\n\t\t\t\t\tmax: this.options.scaleStartValue + (this.options.scaleSteps * this.options.scaleStepWidth)\n\t\t\t\t});\n\t\t\t}\n\n\n\t\t\tthis.scale = new Chart.Scale(scaleOptions);\n\t\t},\n\t\taddData : function(valuesArray,label){\n\t\t\t//Map the values array for each of the datasets\n\n\t\t\thelpers.each(valuesArray,function(value,datasetIndex){\n\t\t\t\t//Add a new point for each piece of data, passing any required data to draw.\n\t\t\t\tthis.datasets[datasetIndex].points.push(new this.PointClass({\n\t\t\t\t\tvalue : value,\n\t\t\t\t\tlabel : label,\n\t\t\t\t\tdatasetLabel: this.datasets[datasetIndex].label,\n\t\t\t\t\tx: this.scale.calculateX(this.scale.valuesCount+1),\n\t\t\t\t\ty: this.scale.endPoint,\n\t\t\t\t\tstrokeColor : this.datasets[datasetIndex].pointStrokeColor,\n\t\t\t\t\tfillColor : this.datasets[datasetIndex].pointColor\n\t\t\t\t}));\n\t\t\t},this);\n\n\t\t\tthis.scale.addXLabel(label);\n\t\t\t//Then re-render the chart.\n\t\t\tthis.update();\n\t\t},\n\t\tremoveData : function(){\n\t\t\tthis.scale.removeXLabel();\n\t\t\t//Then re-render the chart.\n\t\t\thelpers.each(this.datasets,function(dataset){\n\t\t\t\tdataset.points.shift();\n\t\t\t},this);\n\t\t\tthis.update();\n\t\t},\n\t\treflow : function(){\n\t\t\tvar newScaleProps = helpers.extend({\n\t\t\t\theight : this.chart.height,\n\t\t\t\twidth : this.chart.width\n\t\t\t});\n\t\t\tthis.scale.update(newScaleProps);\n\t\t},\n\t\tdraw : function(ease){\n\t\t\tvar easingDecimal = ease || 1;\n\t\t\tthis.clear();\n\n\t\t\tvar ctx = this.chart.ctx;\n\n\t\t\t// Some helper methods for getting the next/prev points\n\t\t\tvar hasValue = function(item){\n\t\t\t\treturn item.value !== null;\n\t\t\t},\n\t\t\tnextPoint = function(point, collection, index){\n\t\t\t\treturn helpers.findNextWhere(collection, hasValue, index) || point;\n\t\t\t},\n\t\t\tpreviousPoint = function(point, collection, index){\n\t\t\t\treturn helpers.findPreviousWhere(collection, hasValue, index) || point;\n\t\t\t};\n\n\t\t\tif (!this.scale) return;\n\t\t\tthis.scale.draw(easingDecimal);\n\n\n\t\t\thelpers.each(this.datasets,function(dataset){\n\t\t\t\tvar pointsWithValues = helpers.where(dataset.points, hasValue);\n\n\t\t\t\t//Transition each point first so that the line and point drawing isn't out of sync\n\t\t\t\t//We can use this extra loop to calculate the control points of this dataset also in this loop\n\n\t\t\t\thelpers.each(dataset.points, function(point, index){\n\t\t\t\t\tif (point.hasValue()){\n\t\t\t\t\t\tpoint.transition({\n\t\t\t\t\t\t\ty : this.scale.calculateY(point.value),\n\t\t\t\t\t\t\tx : this.scale.calculateX(index)\n\t\t\t\t\t\t}, easingDecimal);\n\t\t\t\t\t}\n\t\t\t\t},this);\n\n\n\t\t\t\t// Control points need to be calculated in a separate loop, because we need to know the current x/y of the point\n\t\t\t\t// This would cause issues when there is no animation, because the y of the next point would be 0, so beziers would be skewed\n\t\t\t\tif (this.options.bezierCurve){\n\t\t\t\t\thelpers.each(pointsWithValues, function(point, index){\n\t\t\t\t\t\tvar tension = (index > 0 && index < pointsWithValues.length - 1) ? this.options.bezierCurveTension : 0;\n\t\t\t\t\t\tpoint.controlPoints = helpers.splineCurve(\n\t\t\t\t\t\t\tpreviousPoint(point, pointsWithValues, index),\n\t\t\t\t\t\t\tpoint,\n\t\t\t\t\t\t\tnextPoint(point, pointsWithValues, index),\n\t\t\t\t\t\t\ttension\n\t\t\t\t\t\t);\n\n\t\t\t\t\t\t// Prevent the bezier going outside of the bounds of the graph\n\n\t\t\t\t\t\t// Cap puter bezier handles to the upper/lower scale bounds\n\t\t\t\t\t\tif (point.controlPoints.outer.y > this.scale.endPoint){\n\t\t\t\t\t\t\tpoint.controlPoints.outer.y = this.scale.endPoint;\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse if (point.controlPoints.outer.y < this.scale.startPoint){\n\t\t\t\t\t\t\tpoint.controlPoints.outer.y = this.scale.startPoint;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// Cap inner bezier handles to the upper/lower scale bounds\n\t\t\t\t\t\tif (point.controlPoints.inner.y > this.scale.endPoint){\n\t\t\t\t\t\t\tpoint.controlPoints.inner.y = this.scale.endPoint;\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse if (point.controlPoints.inner.y < this.scale.startPoint){\n\t\t\t\t\t\t\tpoint.controlPoints.inner.y = this.scale.startPoint;\n\t\t\t\t\t\t}\n\t\t\t\t\t},this);\n\t\t\t\t}\n\n\n\t\t\t\t//Draw the line between all the points\n\t\t\t\tctx.lineWidth = this.options.datasetStrokeWidth;\n\t\t\t\tctx.strokeStyle = dataset.strokeColor;\n\t\t\t\tctx.beginPath();\n\n\t\t\t\thelpers.each(pointsWithValues, function(point, index){\n\t\t\t\t\tif (index === 0){\n\t\t\t\t\t\tctx.moveTo(point.x, point.y);\n\t\t\t\t\t}\n\t\t\t\t\telse{\n\t\t\t\t\t\tif(this.options.bezierCurve){\n\t\t\t\t\t\t\tvar previous = previousPoint(point, pointsWithValues, index);\n\n\t\t\t\t\t\t\tctx.bezierCurveTo(\n\t\t\t\t\t\t\t\tprevious.controlPoints.outer.x,\n\t\t\t\t\t\t\t\tprevious.controlPoints.outer.y,\n\t\t\t\t\t\t\t\tpoint.controlPoints.inner.x,\n\t\t\t\t\t\t\t\tpoint.controlPoints.inner.y,\n\t\t\t\t\t\t\t\tpoint.x,\n\t\t\t\t\t\t\t\tpoint.y\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse{\n\t\t\t\t\t\t\tctx.lineTo(point.x,point.y);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}, this);\n\n\t\t\t\tif (this.options.datasetStroke) {\n\t\t\t\t\tctx.stroke();\n\t\t\t\t}\n\n\t\t\t\tif (this.options.datasetFill && pointsWithValues.length > 0){\n\t\t\t\t\t//Round off the line by going to the base of the chart, back to the start, then fill.\n\t\t\t\t\tctx.lineTo(pointsWithValues[pointsWithValues.length - 1].x, this.scale.endPoint);\n\t\t\t\t\tctx.lineTo(pointsWithValues[0].x, this.scale.endPoint);\n\t\t\t\t\tctx.fillStyle = dataset.fillColor;\n\t\t\t\t\tctx.closePath();\n\t\t\t\t\tctx.fill();\n\t\t\t\t}\n\n\t\t\t\t//Now draw the points over the line\n\t\t\t\t//A little inefficient double looping, but better than the line\n\t\t\t\t//lagging behind the point positions\n\t\t\t\thelpers.each(pointsWithValues,function(point){\n\t\t\t\t\tpoint.draw();\n\t\t\t\t});\n\t\t\t},this);\n\t\t}\n\t});\n\n\n}).call(this);\n\n(function(){\n\t\"use strict\";\n\n\tvar root = this,\n\t\tChart = root.Chart,\n\t\t//Cache a local reference to Chart.helpers\n\t\thelpers = Chart.helpers;\n\n\tvar defaultConfig = {\n\t\t//Boolean - Show a backdrop to the scale label\n\t\tscaleShowLabelBackdrop : true,\n\n\t\t//String - The colour of the label backdrop\n\t\tscaleBackdropColor : \"rgba(255,255,255,0.75)\",\n\n\t\t// Boolean - Whether the scale should begin at zero\n\t\tscaleBeginAtZero : true,\n\n\t\t//Number - The backdrop padding above & below the label in pixels\n\t\tscaleBackdropPaddingY : 2,\n\n\t\t//Number - The backdrop padding to the side of the label in pixels\n\t\tscaleBackdropPaddingX : 2,\n\n\t\t//Boolean - Show line for each value in the scale\n\t\tscaleShowLine : true,\n\n\t\t//Boolean - Stroke a line around each segment in the chart\n\t\tsegmentShowStroke : true,\n\n\t\t//String - The colour of the stroke on each segment.\n\t\tsegmentStrokeColor : \"#fff\",\n\n\t\t//Number - The width of the stroke value in pixels\n\t\tsegmentStrokeWidth : 2,\n\n\t\t//Number - Amount of animation steps\n\t\tanimationSteps : 100,\n\n\t\t//String - Animation easing effect.\n\t\tanimationEasing : \"easeOutBounce\",\n\n\t\t//Boolean - Whether to animate the rotation of the chart\n\t\tanimateRotate : true,\n\n\t\t//Boolean - Whether to animate scaling the chart from the centre\n\t\tanimateScale : false,\n\n\t\t//String - A legend template\n\t\tlegendTemplate : \"<ul class=\\\"<%=name.toLowerCase()%>-legend\\\"><% for (var i=0; i<segments.length; i++){%><li><span style=\\\"background-color:<%=segments[i].fillColor%>\\\"><%if(segments[i].label){%><%=segments[i].label%><%}%></span></li><%}%></ul>\"\n\t};\n\n\n\tChart.Type.extend({\n\t\t//Passing in a name registers this chart in the Chart namespace\n\t\tname: \"PolarArea\",\n\t\t//Providing a defaults will also register the deafults in the chart namespace\n\t\tdefaults : defaultConfig,\n\t\t//Initialize is fired when the chart is initialized - Data is passed in as a parameter\n\t\t//Config is automatically merged by the core of Chart.js, and is available at this.options\n\t\tinitialize:  function(data){\n\t\t\tthis.segments = [];\n\t\t\t//Declare segment class as a chart instance specific class, so it can share props for this instance\n\t\t\tthis.SegmentArc = Chart.Arc.extend({\n\t\t\t\tshowStroke : this.options.segmentShowStroke,\n\t\t\t\tstrokeWidth : this.options.segmentStrokeWidth,\n\t\t\t\tstrokeColor : this.options.segmentStrokeColor,\n\t\t\t\tctx : this.chart.ctx,\n\t\t\t\tinnerRadius : 0,\n\t\t\t\tx : this.chart.width/2,\n\t\t\t\ty : this.chart.height/2\n\t\t\t});\n\t\t\tthis.scale = new Chart.RadialScale({\n\t\t\t\tdisplay: this.options.showScale,\n\t\t\t\tfontStyle: this.options.scaleFontStyle,\n\t\t\t\tfontSize: this.options.scaleFontSize,\n\t\t\t\tfontFamily: this.options.scaleFontFamily,\n\t\t\t\tfontColor: this.options.scaleFontColor,\n\t\t\t\tshowLabels: this.options.scaleShowLabels,\n\t\t\t\tshowLabelBackdrop: this.options.scaleShowLabelBackdrop,\n\t\t\t\tbackdropColor: this.options.scaleBackdropColor,\n\t\t\t\tbackdropPaddingY : this.options.scaleBackdropPaddingY,\n\t\t\t\tbackdropPaddingX: this.options.scaleBackdropPaddingX,\n\t\t\t\tlineWidth: (this.options.scaleShowLine) ? this.options.scaleLineWidth : 0,\n\t\t\t\tlineColor: this.options.scaleLineColor,\n\t\t\t\tlineArc: true,\n\t\t\t\twidth: this.chart.width,\n\t\t\t\theight: this.chart.height,\n\t\t\t\txCenter: this.chart.width/2,\n\t\t\t\tyCenter: this.chart.height/2,\n\t\t\t\tctx : this.chart.ctx,\n\t\t\t\ttemplateString: this.options.scaleLabel,\n\t\t\t\tvaluesCount: data.length\n\t\t\t});\n\n\t\t\tthis.updateScaleRange(data);\n\n\t\t\tthis.scale.update();\n\n\t\t\thelpers.each(data,function(segment,index){\n\t\t\t\tthis.addData(segment,index,true);\n\t\t\t},this);\n\n\t\t\t//Set up tooltip events on the chart\n\t\t\tif (this.options.showTooltips){\n\t\t\t\thelpers.bindEvents(this, this.options.tooltipEvents, function(evt){\n\t\t\t\t\tvar activeSegments = (evt.type !== 'mouseout') ? this.getSegmentsAtEvent(evt) : [];\n\t\t\t\t\thelpers.each(this.segments,function(segment){\n\t\t\t\t\t\tsegment.restore([\"fillColor\"]);\n\t\t\t\t\t});\n\t\t\t\t\thelpers.each(activeSegments,function(activeSegment){\n\t\t\t\t\t\tactiveSegment.fillColor = activeSegment.highlightColor;\n\t\t\t\t\t});\n\t\t\t\t\tthis.showTooltip(activeSegments);\n\t\t\t\t});\n\t\t\t}\n\n\t\t\tthis.render();\n\t\t},\n\t\tgetSegmentsAtEvent : function(e){\n\t\t\tvar segmentsArray = [];\n\n\t\t\tvar location = helpers.getRelativePosition(e);\n\n\t\t\thelpers.each(this.segments,function(segment){\n\t\t\t\tif (segment.inRange(location.x,location.y)) segmentsArray.push(segment);\n\t\t\t},this);\n\t\t\treturn segmentsArray;\n\t\t},\n\t\taddData : function(segment, atIndex, silent){\n\t\t\tvar index = atIndex || this.segments.length;\n\n\t\t\tthis.segments.splice(index, 0, new this.SegmentArc({\n\t\t\t\tfillColor: segment.color,\n\t\t\t\thighlightColor: segment.highlight || segment.color,\n\t\t\t\tlabel: segment.label,\n\t\t\t\tvalue: segment.value,\n\t\t\t\touterRadius: (this.options.animateScale) ? 0 : this.scale.calculateCenterOffset(segment.value),\n\t\t\t\tcircumference: (this.options.animateRotate) ? 0 : this.scale.getCircumference(),\n\t\t\t\tstartAngle: Math.PI * 1.5\n\t\t\t}));\n\t\t\tif (!silent){\n\t\t\t\tthis.reflow();\n\t\t\t\tthis.update();\n\t\t\t}\n\t\t},\n\t\tremoveData: function(atIndex){\n\t\t\tvar indexToDelete = (helpers.isNumber(atIndex)) ? atIndex : this.segments.length-1;\n\t\t\tthis.segments.splice(indexToDelete, 1);\n\t\t\tthis.reflow();\n\t\t\tthis.update();\n\t\t},\n\t\tcalculateTotal: function(data){\n\t\t\tthis.total = 0;\n\t\t\thelpers.each(data,function(segment){\n\t\t\t\tthis.total += segment.value;\n\t\t\t},this);\n\t\t\tthis.scale.valuesCount = this.segments.length;\n\t\t},\n\t\tupdateScaleRange: function(datapoints){\n\t\t\tvar valuesArray = [];\n\t\t\thelpers.each(datapoints,function(segment){\n\t\t\t\tvaluesArray.push(segment.value);\n\t\t\t});\n\n\t\t\tvar scaleSizes = (this.options.scaleOverride) ?\n\t\t\t\t{\n\t\t\t\t\tsteps: this.options.scaleSteps,\n\t\t\t\t\tstepValue: this.options.scaleStepWidth,\n\t\t\t\t\tmin: this.options.scaleStartValue,\n\t\t\t\t\tmax: this.options.scaleStartValue + (this.options.scaleSteps * this.options.scaleStepWidth)\n\t\t\t\t} :\n\t\t\t\thelpers.calculateScaleRange(\n\t\t\t\t\tvaluesArray,\n\t\t\t\t\thelpers.min([this.chart.width, this.chart.height])/2,\n\t\t\t\t\tthis.options.scaleFontSize,\n\t\t\t\t\tthis.options.scaleBeginAtZero,\n\t\t\t\t\tthis.options.scaleIntegersOnly\n\t\t\t\t);\n\n\t\t\thelpers.extend(\n\t\t\t\tthis.scale,\n\t\t\t\tscaleSizes,\n\t\t\t\t{\n\t\t\t\t\tsize: helpers.min([this.chart.width, this.chart.height]),\n\t\t\t\t\txCenter: this.chart.width/2,\n\t\t\t\t\tyCenter: this.chart.height/2\n\t\t\t\t}\n\t\t\t);\n\n\t\t},\n\t\tupdate : function(){\n\t\t\tthis.calculateTotal(this.segments);\n\n\t\t\thelpers.each(this.segments,function(segment){\n\t\t\t\tsegment.save();\n\t\t\t});\n\t\t\t\n\t\t\tthis.reflow();\n\t\t\tthis.render();\n\t\t},\n\t\treflow : function(){\n\t\t\thelpers.extend(this.SegmentArc.prototype,{\n\t\t\t\tx : this.chart.width/2,\n\t\t\t\ty : this.chart.height/2\n\t\t\t});\n\t\t\tthis.updateScaleRange(this.segments);\n\t\t\tthis.scale.update();\n\n\t\t\thelpers.extend(this.scale,{\n\t\t\t\txCenter: this.chart.width/2,\n\t\t\t\tyCenter: this.chart.height/2\n\t\t\t});\n\n\t\t\thelpers.each(this.segments, function(segment){\n\t\t\t\tsegment.update({\n\t\t\t\t\touterRadius : this.scale.calculateCenterOffset(segment.value)\n\t\t\t\t});\n\t\t\t}, this);\n\n\t\t},\n\t\tdraw : function(ease){\n\t\t\tvar easingDecimal = ease || 1;\n\t\t\t//Clear & draw the canvas\n\t\t\tthis.clear();\n\t\t\thelpers.each(this.segments,function(segment, index){\n\t\t\t\tsegment.transition({\n\t\t\t\t\tcircumference : this.scale.getCircumference(),\n\t\t\t\t\touterRadius : this.scale.calculateCenterOffset(segment.value)\n\t\t\t\t},easingDecimal);\n\n\t\t\t\tsegment.endAngle = segment.startAngle + segment.circumference;\n\n\t\t\t\t// If we've removed the first segment we need to set the first one to\n\t\t\t\t// start at the top.\n\t\t\t\tif (index === 0){\n\t\t\t\t\tsegment.startAngle = Math.PI * 1.5;\n\t\t\t\t}\n\n\t\t\t\t//Check to see if it's the last segment, if not get the next and update the start angle\n\t\t\t\tif (index < this.segments.length - 1){\n\t\t\t\t\tthis.segments[index+1].startAngle = segment.endAngle;\n\t\t\t\t}\n\t\t\t\tsegment.draw();\n\t\t\t}, this);\n\t\t\tthis.scale.draw();\n\t\t}\n\t});\n\n}).call(this);\n\n(function(){\n\t\"use strict\";\n\n\tvar root = this,\n\t\tChart = root.Chart,\n\t\thelpers = Chart.helpers;\n\n\n\n\tChart.Type.extend({\n\t\tname: \"Radar\",\n\t\tdefaults:{\n\t\t\t//Boolean - Whether to show lines for each scale point\n\t\t\tscaleShowLine : true,\n\n\t\t\t//Boolean - Whether we show the angle lines out of the radar\n\t\t\tangleShowLineOut : true,\n\n\t\t\t//Boolean - Whether to show labels on the scale\n\t\t\tscaleShowLabels : false,\n\n\t\t\t// Boolean - Whether the scale should begin at zero\n\t\t\tscaleBeginAtZero : true,\n\n\t\t\t//String - Colour of the angle line\n\t\t\tangleLineColor : \"rgba(0,0,0,.1)\",\n\n\t\t\t//Number - Pixel width of the angle line\n\t\t\tangleLineWidth : 1,\n\n\t\t\t//String - Point label font declaration\n\t\t\tpointLabelFontFamily : \"'Arial'\",\n\n\t\t\t//String - Point label font weight\n\t\t\tpointLabelFontStyle : \"normal\",\n\n\t\t\t//Number - Point label font size in pixels\n\t\t\tpointLabelFontSize : 10,\n\n\t\t\t//String - Point label font colour\n\t\t\tpointLabelFontColor : \"#666\",\n\n\t\t\t//Boolean - Whether to show a dot for each point\n\t\t\tpointDot : true,\n\n\t\t\t//Number - Radius of each point dot in pixels\n\t\t\tpointDotRadius : 3,\n\n\t\t\t//Number - Pixel width of point dot stroke\n\t\t\tpointDotStrokeWidth : 1,\n\n\t\t\t//Number - amount extra to add to the radius to cater for hit detection outside the drawn point\n\t\t\tpointHitDetectionRadius : 20,\n\n\t\t\t//Boolean - Whether to show a stroke for datasets\n\t\t\tdatasetStroke : true,\n\n\t\t\t//Number - Pixel width of dataset stroke\n\t\t\tdatasetStrokeWidth : 2,\n\n\t\t\t//Boolean - Whether to fill the dataset with a colour\n\t\t\tdatasetFill : true,\n\n\t\t\t//String - A legend template\n\t\t\tlegendTemplate : \"<ul class=\\\"<%=name.toLowerCase()%>-legend\\\"><% for (var i=0; i<datasets.length; i++){%><li><span style=\\\"background-color:<%=datasets[i].strokeColor%>\\\"><%if(datasets[i].label){%><%=datasets[i].label%><%}%></span></li><%}%></ul>\"\n\n\t\t},\n\n\t\tinitialize: function(data){\n\t\t\tthis.PointClass = Chart.Point.extend({\n\t\t\t\tstrokeWidth : this.options.pointDotStrokeWidth,\n\t\t\t\tradius : this.options.pointDotRadius,\n\t\t\t\tdisplay: this.options.pointDot,\n\t\t\t\thitDetectionRadius : this.options.pointHitDetectionRadius,\n\t\t\t\tctx : this.chart.ctx\n\t\t\t});\n\n\t\t\tthis.datasets = [];\n\n\t\t\tthis.buildScale(data);\n\n\t\t\t//Set up tooltip events on the chart\n\t\t\tif (this.options.showTooltips){\n\t\t\t\thelpers.bindEvents(this, this.options.tooltipEvents, function(evt){\n\t\t\t\t\tvar activePointsCollection = (evt.type !== 'mouseout') ? this.getPointsAtEvent(evt) : [];\n\n\t\t\t\t\tthis.eachPoints(function(point){\n\t\t\t\t\t\tpoint.restore(['fillColor', 'strokeColor']);\n\t\t\t\t\t});\n\t\t\t\t\thelpers.each(activePointsCollection, function(activePoint){\n\t\t\t\t\t\tactivePoint.fillColor = activePoint.highlightFill;\n\t\t\t\t\t\tactivePoint.strokeColor = activePoint.highlightStroke;\n\t\t\t\t\t});\n\n\t\t\t\t\tthis.showTooltip(activePointsCollection);\n\t\t\t\t});\n\t\t\t}\n\n\t\t\t//Iterate through each of the datasets, and build this into a property of the chart\n\t\t\thelpers.each(data.datasets,function(dataset){\n\n\t\t\t\tvar datasetObject = {\n\t\t\t\t\tlabel: dataset.label || null,\n\t\t\t\t\tfillColor : dataset.fillColor,\n\t\t\t\t\tstrokeColor : dataset.strokeColor,\n\t\t\t\t\tpointColor : dataset.pointColor,\n\t\t\t\t\tpointStrokeColor : dataset.pointStrokeColor,\n\t\t\t\t\tpoints : []\n\t\t\t\t};\n\n\t\t\t\tthis.datasets.push(datasetObject);\n\n\t\t\t\thelpers.each(dataset.data,function(dataPoint,index){\n\t\t\t\t\t//Add a new point for each piece of data, passing any required data to draw.\n\t\t\t\t\tvar pointPosition;\n\t\t\t\t\tif (!this.scale.animation){\n\t\t\t\t\t\tpointPosition = this.scale.getPointPosition(index, this.scale.calculateCenterOffset(dataPoint));\n\t\t\t\t\t}\n\t\t\t\t\tdatasetObject.points.push(new this.PointClass({\n\t\t\t\t\t\tvalue : dataPoint,\n\t\t\t\t\t\tlabel : data.labels[index],\n\t\t\t\t\t\tdatasetLabel: dataset.label,\n\t\t\t\t\t\tx: (this.options.animation) ? this.scale.xCenter : pointPosition.x,\n\t\t\t\t\t\ty: (this.options.animation) ? this.scale.yCenter : pointPosition.y,\n\t\t\t\t\t\tstrokeColor : dataset.pointStrokeColor,\n\t\t\t\t\t\tfillColor : dataset.pointColor,\n\t\t\t\t\t\thighlightFill : dataset.pointHighlightFill || dataset.pointColor,\n\t\t\t\t\t\thighlightStroke : dataset.pointHighlightStroke || dataset.pointStrokeColor\n\t\t\t\t\t}));\n\t\t\t\t},this);\n\n\t\t\t},this);\n\n\t\t\tthis.render();\n\t\t},\n\t\teachPoints : function(callback){\n\t\t\thelpers.each(this.datasets,function(dataset){\n\t\t\t\thelpers.each(dataset.points,callback,this);\n\t\t\t},this);\n\t\t},\n\n\t\tgetPointsAtEvent : function(evt){\n\t\t\tvar mousePosition = helpers.getRelativePosition(evt),\n\t\t\t\tfromCenter = helpers.getAngleFromPoint({\n\t\t\t\t\tx: this.scale.xCenter,\n\t\t\t\t\ty: this.scale.yCenter\n\t\t\t\t}, mousePosition);\n\n\t\t\tvar anglePerIndex = (Math.PI * 2) /this.scale.valuesCount,\n\t\t\t\tpointIndex = Math.round((fromCenter.angle - Math.PI * 1.5) / anglePerIndex),\n\t\t\t\tactivePointsCollection = [];\n\n\t\t\t// If we're at the top, make the pointIndex 0 to get the first of the array.\n\t\t\tif (pointIndex >= this.scale.valuesCount || pointIndex < 0){\n\t\t\t\tpointIndex = 0;\n\t\t\t}\n\n\t\t\tif (fromCenter.distance <= this.scale.drawingArea){\n\t\t\t\thelpers.each(this.datasets, function(dataset){\n\t\t\t\t\tactivePointsCollection.push(dataset.points[pointIndex]);\n\t\t\t\t});\n\t\t\t}\n\n\t\t\treturn activePointsCollection;\n\t\t},\n\n\t\tbuildScale : function(data){\n\t\t\tthis.scale = new Chart.RadialScale({\n\t\t\t\tdisplay: this.options.showScale,\n\t\t\t\tfontStyle: this.options.scaleFontStyle,\n\t\t\t\tfontSize: this.options.scaleFontSize,\n\t\t\t\tfontFamily: this.options.scaleFontFamily,\n\t\t\t\tfontColor: this.options.scaleFontColor,\n\t\t\t\tshowLabels: this.options.scaleShowLabels,\n\t\t\t\tshowLabelBackdrop: this.options.scaleShowLabelBackdrop,\n\t\t\t\tbackdropColor: this.options.scaleBackdropColor,\n\t\t\t\tbackgroundColors: this.options.scaleBackgroundColors,\n\t\t\t\tbackdropPaddingY : this.options.scaleBackdropPaddingY,\n\t\t\t\tbackdropPaddingX: this.options.scaleBackdropPaddingX,\n\t\t\t\tlineWidth: (this.options.scaleShowLine) ? this.options.scaleLineWidth : 0,\n\t\t\t\tlineColor: this.options.scaleLineColor,\n\t\t\t\tangleLineColor : this.options.angleLineColor,\n\t\t\t\tangleLineWidth : (this.options.angleShowLineOut) ? this.options.angleLineWidth : 0,\n\t\t\t\t// Point labels at the edge of each line\n\t\t\t\tpointLabelFontColor : this.options.pointLabelFontColor,\n\t\t\t\tpointLabelFontSize : this.options.pointLabelFontSize,\n\t\t\t\tpointLabelFontFamily : this.options.pointLabelFontFamily,\n\t\t\t\tpointLabelFontStyle : this.options.pointLabelFontStyle,\n\t\t\t\theight : this.chart.height,\n\t\t\t\twidth: this.chart.width,\n\t\t\t\txCenter: this.chart.width/2,\n\t\t\t\tyCenter: this.chart.height/2,\n\t\t\t\tctx : this.chart.ctx,\n\t\t\t\ttemplateString: this.options.scaleLabel,\n\t\t\t\tlabels: data.labels,\n\t\t\t\tvaluesCount: data.datasets[0].data.length\n\t\t\t});\n\n\t\t\tthis.scale.setScaleSize();\n\t\t\tthis.updateScaleRange(data.datasets);\n\t\t\tthis.scale.buildYLabels();\n\t\t},\n\t\tupdateScaleRange: function(datasets){\n\t\t\tvar valuesArray = (function(){\n\t\t\t\tvar totalDataArray = [];\n\t\t\t\thelpers.each(datasets,function(dataset){\n\t\t\t\t\tif (dataset.data){\n\t\t\t\t\t\ttotalDataArray = totalDataArray.concat(dataset.data);\n\t\t\t\t\t}\n\t\t\t\t\telse {\n\t\t\t\t\t\thelpers.each(dataset.points, function(point){\n\t\t\t\t\t\t\ttotalDataArray.push(point.value);\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t\treturn totalDataArray;\n\t\t\t})();\n\n\n\t\t\tvar scaleSizes = (this.options.scaleOverride) ?\n\t\t\t\t{\n\t\t\t\t\tsteps: this.options.scaleSteps,\n\t\t\t\t\tstepValue: this.options.scaleStepWidth,\n\t\t\t\t\tmin: this.options.scaleStartValue,\n\t\t\t\t\tmax: this.options.scaleStartValue + (this.options.scaleSteps * this.options.scaleStepWidth)\n\t\t\t\t} :\n\t\t\t\thelpers.calculateScaleRange(\n\t\t\t\t\tvaluesArray,\n\t\t\t\t\thelpers.min([this.chart.width, this.chart.height])/2,\n\t\t\t\t\tthis.options.scaleFontSize,\n\t\t\t\t\tthis.options.scaleBeginAtZero,\n\t\t\t\t\tthis.options.scaleIntegersOnly\n\t\t\t\t);\n\n\t\t\thelpers.extend(\n\t\t\t\tthis.scale,\n\t\t\t\tscaleSizes\n\t\t\t);\n\n\t\t},\n\t\taddData : function(valuesArray,label){\n\t\t\t//Map the values array for each of the datasets\n\t\t\tthis.scale.valuesCount++;\n\t\t\thelpers.each(valuesArray,function(value,datasetIndex){\n\t\t\t\tvar pointPosition = this.scale.getPointPosition(this.scale.valuesCount, this.scale.calculateCenterOffset(value));\n\t\t\t\tthis.datasets[datasetIndex].points.push(new this.PointClass({\n\t\t\t\t\tvalue : value,\n\t\t\t\t\tlabel : label,\n\t\t\t\t\tdatasetLabel: this.datasets[datasetIndex].label,\n\t\t\t\t\tx: pointPosition.x,\n\t\t\t\t\ty: pointPosition.y,\n\t\t\t\t\tstrokeColor : this.datasets[datasetIndex].pointStrokeColor,\n\t\t\t\t\tfillColor : this.datasets[datasetIndex].pointColor\n\t\t\t\t}));\n\t\t\t},this);\n\n\t\t\tthis.scale.labels.push(label);\n\n\t\t\tthis.reflow();\n\n\t\t\tthis.update();\n\t\t},\n\t\tremoveData : function(){\n\t\t\tthis.scale.valuesCount--;\n\t\t\tthis.scale.labels.shift();\n\t\t\thelpers.each(this.datasets,function(dataset){\n\t\t\t\tdataset.points.shift();\n\t\t\t},this);\n\t\t\tthis.reflow();\n\t\t\tthis.update();\n\t\t},\n\t\tupdate : function(){\n\t\t\tthis.eachPoints(function(point){\n\t\t\t\tpoint.save();\n\t\t\t});\n\t\t\tthis.reflow();\n\t\t\tthis.render();\n\t\t},\n\t\treflow: function(){\n\t\t\thelpers.extend(this.scale, {\n\t\t\t\twidth : this.chart.width,\n\t\t\t\theight: this.chart.height,\n\t\t\t\tsize : helpers.min([this.chart.width, this.chart.height]),\n\t\t\t\txCenter: this.chart.width/2,\n\t\t\t\tyCenter: this.chart.height/2\n\t\t\t});\n\t\t\tthis.updateScaleRange(this.datasets);\n\t\t\tthis.scale.setScaleSize();\n\t\t\tthis.scale.buildYLabels();\n\t\t},\n\t\tdraw : function(ease){\n\t\t\tvar easeDecimal = ease || 1,\n\t\t\t\tctx = this.chart.ctx;\n\t\t\tthis.clear();\n\t\t\tthis.scale.draw();\n\n\t\t\thelpers.each(this.datasets,function(dataset){\n\n\t\t\t\t//Transition each point first so that the line and point drawing isn't out of sync\n\t\t\t\thelpers.each(dataset.points,function(point,index){\n\t\t\t\t\tif (point.hasValue()){\n\t\t\t\t\t\tpoint.transition(this.scale.getPointPosition(index, this.scale.calculateCenterOffset(point.value)), easeDecimal);\n\t\t\t\t\t}\n\t\t\t\t},this);\n\n\n\n\t\t\t\t//Draw the line between all the points\n\t\t\t\tctx.lineWidth = this.options.datasetStrokeWidth;\n\t\t\t\tctx.strokeStyle = dataset.strokeColor;\n\t\t\t\tctx.beginPath();\n\t\t\t\thelpers.each(dataset.points,function(point,index){\n\t\t\t\t\tif (index === 0){\n\t\t\t\t\t\tctx.moveTo(point.x,point.y);\n\t\t\t\t\t}\n\t\t\t\t\telse{\n\t\t\t\t\t\tctx.lineTo(point.x,point.y);\n\t\t\t\t\t}\n\t\t\t\t},this);\n\t\t\t\tctx.closePath();\n\t\t\t\tctx.stroke();\n\n\t\t\t\tctx.fillStyle = dataset.fillColor;\n\t\t\t\tif(this.options.datasetFill){\n\t\t\t\t\tctx.fill();\n\t\t\t\t}\n\t\t\t\t//Now draw the points over the line\n\t\t\t\t//A little inefficient double looping, but better than the line\n\t\t\t\t//lagging behind the point positions\n\t\t\t\thelpers.each(dataset.points,function(point){\n\t\t\t\t\tif (point.hasValue()){\n\t\t\t\t\t\tpoint.draw();\n\t\t\t\t\t}\n\t\t\t\t});\n\n\t\t\t},this);\n\n\t\t}\n\n\t});\n\n\n\n\n\n}).call(this);\n"
  },
  {
    "path": "app_frontend/static/plugin/Gallery-2.25.0/.gitignore",
    "content": ".DS_Store\nnode_modules\n"
  },
  {
    "path": "app_frontend/static/plugin/Gallery-2.25.0/.npmignore",
    "content": "*\n!css/*.css\n!css/*.css.map\n!img/*.gif\n!img/*.png\n!img/*.svg\n!js/*.js\n!js/*.js.map\n"
  },
  {
    "path": "app_frontend/static/plugin/Gallery-2.25.0/LICENSE.txt",
    "content": "Copyright (C) 2013, 2016 Sebastian Tschan, https://blueimp.net\n\nThe Swipe implementation is based on https://github.com/bradbirdsall/Swipe, \nlicensed also under the MIT license.\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n"
  },
  {
    "path": "app_frontend/static/plugin/Gallery-2.25.0/README.md",
    "content": "# blueimp Gallery\n\n- [Demo](#demo)\n- [Description](#description)\n- [Setup](#setup)\n    - [Lightbox setup](#lightbox-setup)\n    - [Controls](#controls)\n    - [Carousel setup](#carousel-setup)\n- [Keyboard shortcuts](#keyboard-shortcuts)\n- [Options](#options)\n    - [Default options](#default-options)\n    - [Event callbacks](#event-callbacks)\n    - [Carousel options](#carousel-options)\n    - [Indicator options](#indicator-options)\n    - [Fullscreen options](#fullscreen-options)\n    - [Video options](#video-options)\n        - [Video factory options](#video-factory-options)\n        - [YouTube options](#youtube-options)\n        - [Vimeo options](#vimeo-options)\n    - [Container and element options](#container-and-element-options)\n    - [Property options](#property-options)\n- [API](#api)\n    - [Initialization](#initialization)\n    - [API methods](#api-methods)\n    - [Videos](#videos)\n        - [HTML5 video player](#html5-video-player)\n        - [Multiple video sources](#multiple-video-sources)\n        - [YouTube](#youtube)\n        - [Vimeo](#vimeo)\n    - [Additional Gallery elements](#additional-gallery-elements)\n    - [Additional content types](#additional-content-types)\n        - [Example HTML text factory implementation](#example-html-text-factory-implementation)\n    - [jQuery plugin](#jquery-plugin)\n        - [jQuery plugin setup](#jquery-plugin-setup)\n        - [HTML5 data-attributes](#html5-data-attributes)\n        - [Container ids and link grouping](#container-ids-and-link-grouping)\n        - [Gallery object](#gallery-object)\n        - [jQuery events](#jquery-events)\n- [Requirements](#requirements)\n- [Browsers](#browsers)\n    - [Desktop browsers](#desktop-browsers)\n    - [Mobile browsers](#mobile-browsers)\n- [License](#license)\n- [Credits](#credits)\n\n## Demo\n[blueimp Gallery Demo](https://blueimp.github.io/Gallery/)\n\n## Description\nblueimp Gallery is a touch-enabled, responsive and customizable image and video\ngallery, carousel and lightbox, optimized for both mobile and desktop web\nbrowsers.  \nIt features swipe, mouse and keyboard navigation, transition effects, slideshow\nfunctionality, fullscreen support and on-demand content loading and can be\nextended to display additional content types.\n\n## Setup\n\n### Lightbox setup\nCopy the **css**, **img** and **js** directories to your website.\n\nInclude the Gallery stylesheet in the head section of your webpage:\n\n```html\n<link rel=\"stylesheet\" href=\"css/blueimp-gallery.min.css\">\n```\n\nAdd the following HTML snippet with the Gallery widget to the body of your\nwebpage:\n\n```html\n<!-- The Gallery as lightbox dialog, should be a child element of the document body -->\n<div id=\"blueimp-gallery\" class=\"blueimp-gallery\">\n    <div class=\"slides\"></div>\n    <h3 class=\"title\"></h3>\n    <a class=\"prev\">‹</a>\n    <a class=\"next\">›</a>\n    <a class=\"close\">×</a>\n    <a class=\"play-pause\"></a>\n    <ol class=\"indicator\"></ol>\n</div>\n```\n\nInclude the Gallery script at the bottom of the body of your webpage:\n\n```html\n<script src=\"js/blueimp-gallery.min.js\"></script>\n```\n\nCreate a list of links to image files, optionally with enclosed thumbnails and\nadd them to the body of your webpage, before including the Gallery script:\n\n```html\n<div id=\"links\">\n    <a href=\"images/banana.jpg\" title=\"Banana\">\n        <img src=\"images/thumbnails/banana.jpg\" alt=\"Banana\">\n    </a>\n    <a href=\"images/apple.jpg\" title=\"Apple\">\n        <img src=\"images/thumbnails/apple.jpg\" alt=\"Apple\">\n    </a>\n    <a href=\"images/orange.jpg\" title=\"Orange\">\n        <img src=\"images/thumbnails/orange.jpg\" alt=\"Orange\">\n    </a>\n</div>\n```\n\nAdd the following JavaScript code after including the Gallery script, to display\nthe images in the Gallery lightbox on click of the links:\n\n```html\n<script>\ndocument.getElementById('links').onclick = function (event) {\n    event = event || window.event;\n    var target = event.target || event.srcElement,\n        link = target.src ? target.parentNode : target,\n        options = {index: link, event: event},\n        links = this.getElementsByTagName('a');\n    blueimp.Gallery(links, options);\n};\n</script>\n```\n\n### Controls\nTo initialize the Gallery with visible controls, add the CSS class\n**blueimp-gallery-controls** to the Gallery widget:\n\n```html\n<div id=\"blueimp-gallery\" class=\"blueimp-gallery blueimp-gallery-controls\">\n    <div class=\"slides\"></div>\n    <h3 class=\"title\"></h3>\n    <a class=\"prev\">‹</a>\n    <a class=\"next\">›</a>\n    <a class=\"close\">×</a>\n    <a class=\"play-pause\"></a>\n    <ol class=\"indicator\"></ol>\n</div>\n```\n\n### Carousel setup\nTo display the images in an inline carousel instead of a lightbox, follow the\n[lightbox setup](#lightbox-setup) and add the CSS class\n**blueimp-gallery-carousel** to the Gallery widget and remove the child element\nwith the **close** class, or add a new Gallery widget with a different **id**\nto your webpage:\n\n```html\n<!-- The Gallery as inline carousel, can be positioned anywhere on the page -->\n<div id=\"blueimp-gallery-carousel\" class=\"blueimp-gallery blueimp-gallery-carousel\">\n    <div class=\"slides\"></div>\n    <h3 class=\"title\"></h3>\n    <a class=\"prev\">‹</a>\n    <a class=\"next\">›</a>\n    <a class=\"play-pause\"></a>\n    <ol class=\"indicator\"></ol>\n</div>\n```\n\nAdd the following JavaScript code after including the Gallery script to\ninitialize the carousel:\n\n```html\n<script>\nblueimp.Gallery(\n    document.getElementById('links').getElementsByTagName('a'),\n    {\n        container: '#blueimp-gallery-carousel',\n        carousel: true\n    }\n);\n</script>\n```\n\n## Keyboard shortcuts\nThe Gallery can be controlled with the following keyboard shortcuts:\n\n* **Return**: Toggle controls visibility.\n* **Esc**: Close the Gallery lightbox.\n* **Space**: Toggle the slideshow (play/pause).\n* **Left**: Move to the previous slide.\n* **Right**: Move to the next slide.\n\nPlease note that setting the **carousel** option to **true** disables the\nkeyboard shortcuts by default.\n\n## Options\n\n### Default options\nThe following are the default options set by the core Gallery library:\n\n```js\nvar options = {\n    // The Id, element or querySelector of the gallery widget:\n    container: '#blueimp-gallery',\n    // The tag name, Id, element or querySelector of the slides container:\n    slidesContainer: 'div',\n    // The tag name, Id, element or querySelector of the title element:\n    titleElement: 'h3',\n    // The class to add when the gallery is visible:\n    displayClass: 'blueimp-gallery-display',\n    // The class to add when the gallery controls are visible:\n    controlsClass: 'blueimp-gallery-controls',\n    // The class to add when the gallery only displays one element:\n    singleClass: 'blueimp-gallery-single',\n    // The class to add when the left edge has been reached:\n    leftEdgeClass: 'blueimp-gallery-left',\n    // The class to add when the right edge has been reached:\n    rightEdgeClass: 'blueimp-gallery-right',\n    // The class to add when the automatic slideshow is active:\n    playingClass: 'blueimp-gallery-playing',\n    // The class for all slides:\n    slideClass: 'slide',\n    // The slide class for loading elements:\n    slideLoadingClass: 'slide-loading',\n    // The slide class for elements that failed to load:\n    slideErrorClass: 'slide-error',\n    // The class for the content element loaded into each slide:\n    slideContentClass: 'slide-content',\n    // The class for the \"toggle\" control:\n    toggleClass: 'toggle',\n    // The class for the \"prev\" control:\n    prevClass: 'prev',\n    // The class for the \"next\" control:\n    nextClass: 'next',\n    // The class for the \"close\" control:\n    closeClass: 'close',\n    // The class for the \"play-pause\" toggle control:\n    playPauseClass: 'play-pause',\n    // The list object property (or data attribute) with the object type:\n    typeProperty: 'type',\n    // The list object property (or data attribute) with the object title:\n    titleProperty: 'title',\n    // The list object property (or data attribute) with the object URL:\n    urlProperty: 'href',\n    // The list object property (or data attribute) with the object srcset URL(s):\n    srcsetProperty: 'urlset',\n    // The gallery listens for transitionend events before triggering the\n    // opened and closed events, unless the following option is set to false:\n    displayTransition: true,\n    // Defines if the gallery slides are cleared from the gallery modal,\n    // or reused for the next gallery initialization:\n    clearSlides: true,\n    // Defines if images should be stretched to fill the available space,\n    // while maintaining their aspect ratio (will only be enabled for browsers\n    // supporting background-size=\"contain\", which excludes IE < 9).\n    // Set to \"cover\", to make images cover all available space (requires\n    // support for background-size=\"cover\", which excludes IE < 9):\n    stretchImages: false,\n    // Toggle the controls on pressing the Return key:\n    toggleControlsOnReturn: true,\n    // Toggle the controls on slide click:\n    toggleControlsOnSlideClick: true,\n    // Toggle the automatic slideshow interval on pressing the Space key:\n    toggleSlideshowOnSpace: true,\n    // Navigate the gallery by pressing left and right on the keyboard:\n    enableKeyboardNavigation: true,\n    // Close the gallery on pressing the ESC key:\n    closeOnEscape: true,\n    // Close the gallery when clicking on an empty slide area:\n    closeOnSlideClick: true,\n    // Close the gallery by swiping up or down:\n    closeOnSwipeUpOrDown: true,\n    // Emulate touch events on mouse-pointer devices such as desktop browsers:\n    emulateTouchEvents: true,\n    // Stop touch events from bubbling up to ancestor elements of the Gallery:\n    stopTouchEventsPropagation: false,\n    // Hide the page scrollbars:\n    hidePageScrollbars: true,\n    // Stops any touches on the container from scrolling the page:\n    disableScroll: true,\n    // Carousel mode (shortcut for carousel specific options):\n    carousel: false,\n    // Allow continuous navigation, moving from last to first\n    // and from first to last slide:\n    continuous: true,\n    // Remove elements outside of the preload range from the DOM:\n    unloadElements: true,\n    // Start with the automatic slideshow:\n    startSlideshow: false,\n    // Delay in milliseconds between slides for the automatic slideshow:\n    slideshowInterval: 5000,\n    // The starting index as integer.\n    // Can also be an object of the given list,\n    // or an equal object with the same url property:\n    index: 0,\n    // The number of elements to load around the current index:\n    preloadRange: 2,\n    // The transition speed between slide changes in milliseconds:\n    transitionSpeed: 400,\n    // The transition speed for automatic slide changes, set to an integer\n    // greater 0 to override the default transition speed:\n    slideshowTransitionSpeed: undefined,\n    // The event object for which the default action will be canceled\n    // on Gallery initialization (e.g. the click event to open the Gallery):\n    event: undefined,\n    // Callback function executed when the Gallery is initialized.\n    // Is called with the gallery instance as \"this\" object:\n    onopen: undefined,\n    // Callback function executed when the Gallery has been initialized\n    // and the initialization transition has been completed.\n    // Is called with the gallery instance as \"this\" object:\n    onopened: undefined,\n    // Callback function executed on slide change.\n    // Is called with the gallery instance as \"this\" object and the\n    // current index and slide as arguments:\n    onslide: undefined,\n    // Callback function executed after the slide change transition.\n    // Is called with the gallery instance as \"this\" object and the\n    // current index and slide as arguments:\n    onslideend: undefined,\n    // Callback function executed on slide content load.\n    // Is called with the gallery instance as \"this\" object and the\n    // slide index and slide element as arguments:\n    onslidecomplete: undefined,\n    // Callback function executed when the Gallery is about to be closed.\n    // Is called with the gallery instance as \"this\" object:\n    onclose: undefined,\n    // Callback function executed when the Gallery has been closed\n    // and the closing transition has been completed.\n    // Is called with the gallery instance as \"this\" object:\n    onclosed: undefined\n};\n```\n\n### Event callbacks\nEvent callbacks can be set as function properties of the options object passed\nto the Gallery initialization function:\n\n```js\nvar gallery = blueimp.Gallery(\n    linkList,\n    {\n        onopen: function () {\n            // Callback function executed when the Gallery is initialized.\n        },\n        onopened: function () {\n            // Callback function executed when the Gallery has been initialized\n            // and the initialization transition has been completed.\n        },\n        onslide: function (index, slide) {\n            // Callback function executed on slide change.\n        },\n        onslideend: function (index, slide) {\n            // Callback function executed after the slide change transition.\n        },\n        onslidecomplete: function (index, slide) {\n            // Callback function executed on slide content load.\n        },\n        onclose: function () {\n            // Callback function executed when the Gallery is about to be closed.\n        },\n        onclosed: function () {\n            // Callback function executed when the Gallery has been closed\n            // and the closing transition has been completed.\n        }\n    }\n);\n```\n\n### Carousel options\nIf the **carousel** option is **true**, the following options are set to\ndifferent default values:\n\n```js\nvar carouselOptions = {\n    hidePageScrollbars: false,\n    toggleControlsOnReturn: false,\n    toggleSlideshowOnSpace: false,\n    enableKeyboardNavigation: false,\n    closeOnEscape: false,\n    closeOnSlideClick: false,\n    closeOnSwipeUpOrDown: false,\n    disableScroll: false,\n    startSlideshow: true\n};\n```\n\nThe options object passed to the Gallery function extends the default options\nand also those options set via **carousel** mode.\n\n### Indicator options\nThe following are the additional default options set for the slide position\nindicator:\n\n```js\nvar indicatorOptions = {\n    // The tag name, Id, element or querySelector of the indicator container:\n    indicatorContainer: 'ol',\n    // The class for the active indicator:\n    activeIndicatorClass: 'active',\n    // The list object property (or data attribute) with the thumbnail URL,\n    // used as alternative to a thumbnail child element:\n    thumbnailProperty: 'thumbnail',\n    // Defines if the gallery indicators should display a thumbnail:\n    thumbnailIndicators: true\n};\n```\n\n### Fullscreen options\nThe following are the additional default options set for the fullscreen mode:\n\n```js\nvar fullscreenOptions = {\n    // Defines if the gallery should open in fullscreen mode:\n    fullScreen: false\n};\n```\n\n### Video options\n\n#### Video factory options\nThe following are the additional default options set for the video factory:\n\n```js\nvar videoFactoryOptions = {\n    // The class for video content elements:\n    videoContentClass: 'video-content',\n    // The class for video when it is loading:\n    videoLoadingClass: 'video-loading',\n    // The class for video when it is playing:\n    videoPlayingClass: 'video-playing',\n    // The list object property (or data attribute) for the video poster URL:\n    videoPosterProperty: 'poster',\n    // The list object property (or data attribute) for the video sources array:\n    videoSourcesProperty: 'sources'\n};\n```\n#### YouTube options\nOptions for [YouTube](https://www.youtube.com/) videos:\n\n```js\nvar youTubeOptions = {\n    // The list object property (or data attribute) with the YouTube video id:\n    youTubeVideoIdProperty: 'youtube',\n    // Optional object with parameters passed to the YouTube video player:\n    // https://developers.google.com/youtube/player_parameters\n    youTubePlayerVars: undefined,\n    // Require a click on the native YouTube player for the initial playback:\n    youTubeClickToPlay: true\n};\n```\n\n#### Vimeo options\nOptions for [Vimeo](https://vimeo.com/) videos:\n\n```js\nvar vimeoOptions = {\n    // The list object property (or data attribute) with the Vimeo video id:\n    vimeoVideoIdProperty: 'vimeo',\n    // The URL for the Vimeo video player, can be extended with custom parameters:\n    // https://developer.vimeo.com/player/embedding\n    vimeoPlayerUrl: '//player.vimeo.com/video/VIDEO_ID?api=1&player_id=PLAYER_ID',\n    // The prefix for the Vimeo video player ID:\n    vimeoPlayerIdPrefix: 'vimeo-player-',\n    // Require a click on the native Vimeo player for the initial playback:\n    vimeoClickToPlay: true\n};\n```\n\n### Container and element options\nThe widget **container** option can be set as id string (with \"#\" as prefix) or\nelement node, so the following are equivalent:\n\n```js\nvar options = {\n    container: '#blueimp-gallery'\n};\n```\n\n```js\nvar options = {\n    container: document.getElementById('blueimp-gallery')\n};\n```\n\nThe **slidesContainer**, **titleElement** and **indicatorContainer** options can\nalso be defined using a tag name, which selects the first tag of this kind found\ninside of the widget container:\n\n```js\nvar options = {\n    slidesContainer: 'div',\n    titleElement: 'h3',\n    indicatorContainer: 'ol'\n};\n```\n\nIt is also possible to define the container and element options with a more\ncomplex\n[querySelector](https://developer.mozilla.org/en-US/docs/Web/API/document.querySelector),\nwhich is supported by IE8+ and all modern web browsers.\n\nIf the helper script is replaced with [jQuery](https://jquery.com/),\nthe container and element options can be any valid jQuery selector.\n\n### Property options\nThe options ending with \"Property\" define how the properties of each link\nelement are accessed.  \nFor example, the **urlProperty** is by default set to **href**. This allows to\ndefine link elements with **href** or **data-href** attributes:\n\n```html\n<div id=\"links\">\n    <a href=\"images/banana.jpg\">Banana</a>\n    <a data-href=\"images/apple.jpg\">Apple</a>\n</div>\n```\n\nIf the links are passed as JavaScript array, it is also possible to define\nnested property names, by using the native JavaScript accessor syntax for the\nproperty string:\n\n```js\nblueimp.Gallery(\n    [\n        {\n            data: {urls: ['https://example.org/images/banana.jpg']}\n        },\n        {\n            data: {urls: ['https://example.org/images/apple.jpg']}\n        }\n    ],\n    {\n        urlProperty: 'data.urls[0]'\n    }\n);\n```\n\n## API\n\n### Initialization\nThe blueimp Gallery can be initialized by simply calling it as a function with\nan array of links as first argument and an optional options object as second\nargument:\n\n```js\nvar gallery = blueimp.Gallery(links, options);\n```\n\nThe links array can be a list of URL strings or a list of objects with URL\nproperties:\n\n```js\nvar gallery = blueimp.Gallery([\n    'https://example.org/images/banana.jpg',\n    'https://example.org/images/apple.jpg',\n    'https://example.org/images/orange.jpg'\n]);\n```\n\n```js\nvar gallery = blueimp.Gallery([\n    {\n        title: 'Banana',\n        href: 'https://example.org/images/banana.jpg',\n        type: 'image/jpeg',\n        thumbnail: 'https://example.org/thumbnails/banana.jpg'\n    },\n    {\n        title: 'Apple',\n        href: 'https://example.org/images/apple.jpg',\n        type: 'image/jpeg',\n        thumbnail: 'https://example.org/thumbnails/apple.jpg'\n    }\n]);\n```\n\nThe URL property name defined by each list object can be configured via the\n**urlProperty** option. By default, it is set to **href**, which allows to pass\na list of HTML link elements as first argument.\n\nFor images, the **thumbnail** property defines the URL of the image thumbnail,\nwhich is used for the indicator navigation displayed at the bottom of the\nGallery, if the controls are visible.\n\nThe object returned by executing the Gallery function (the **gallery** variable\nin the example code above) is a new instance of the Gallery and allows to access\nthe public [API methods](#api-methods) provided by the Gallery.  \nThe Gallery initialization function returns **false** if the given list was\nempty, the Gallery widget is missing, or the browser doesn't pass the\nfunctionality test.\n\n### API methods\nThe Gallery object returned by executing the Gallery function provides the\nfollowing public API methods:\n\n```js\n// Return the current slide index position:\nvar pos = gallery.getIndex();\n\n// Return the total number of slides:\nvar count = gallery.getNumber();\n\n// Move to the previous slide:\ngallery.prev();\n\n// Move to the next slide:\ngallery.next();\n\n// Move to the given slide index with the (optional) given duraction speed in milliseconds:\ngallery.slide(index, duration);\n\n// Start an automatic slideshow with the given interval in milliseconds (optional):\ngallery.play(interval);\n\n// Stop the automatic slideshow:\ngallery.pause();\n\n// Add additional slides after Gallery initialization:\ngallery.add(list);\n\n// Close and deinitialize the Gallery:\ngallery.close();\n```\n\n### Videos\n\n#### HTML5 video player\n\nThe Gallery can be initialized with a list of videos instead of images, or a\ncombination of both:\n\n```js\nblueimp.Gallery([\n    {\n        title: 'Fruits',\n        href: 'https://example.org/videos/fruits.mp4',\n        type: 'video/mp4',\n        poster: 'https://example.org/images/fruits.jpg'\n    },\n    {\n        title: 'Banana',\n        href: 'https://example.org/images/banana.jpg',\n        type: 'image/jpeg',\n        thumbnail: 'https://example.org/thumbnails/banana.jpg'\n    }\n]);\n```\n\nThe Gallery uses the **type** property to determine the content type of the\nobject to display.  \nIf the type property is empty or doesn't exist, the default type **image** is\nassumed.  \nObjects with a video type will be displayed in a\n[HTML5 video element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/video)\nif the browser supports the video content type.\n\nFor videos, the **poster** property defines the URL of the poster image to\ndisplay, before the video is started.\n\n#### Multiple video sources\nTo provide multiple video formats, the **sources** property of a list object can\nbe set to an array of objects with **href** and **type** properties for each\nvideo source. The first video format in the list that the browser can play will\nbe displayed:\n\n```js\nblueimp.Gallery([\n    {\n        title: 'Fruits',\n        type: 'video/*',\n        poster: 'https://example.org/images/fruits.jpg',\n        sources: [\n            {\n                href: 'https://example.org/videos/fruits.mp4',\n                type: 'video/mp4'\n            },\n            {\n                href: 'https://example.org/videos/fruits.ogg',\n                type: 'video/ogg'\n            }\n        ]\n    }\n]);\n```\n\nIt is also possible to define the video sources as data-attribute on a link\nelement in [JSON](https://developer.mozilla.org/en-US/docs/JSON) array format:\n\n```html\n<div id=\"links\">\n    <a\n        href=\"https://example.org/videos/fruits.mp4\"\n        title=\"Fruits\"\n        type=\"video/mp4\"\n        data-poster=\"https://example.org/images/fruits.jpg\"\n        data-sources='[{\"href\": \"https://example.org/videos/fruits.mp4\", \"type\": \"video/mp4\"}, {\"href\": \"https://example.org/videos/fruits.ogg\", \"type\": \"video/ogg\"}]'\n    >Fruits</a>\n</div>\n```\n\n#### YouTube\nThe Gallery can display [YouTube](https://www.youtube.com/) videos for Gallery\nitems with a **type** of **text/html** and a **youtube** property\n(configurable via [YouTube options](#youtube-options)) with the YouTube\nvideo-ID:\n\n```js\nblueimp.Gallery([\n    {\n        title: 'A YouYube video',\n        href: 'https://www.youtube.com/watch?v=VIDEO_ID',\n        type: 'text/html',\n        youtube: 'VIDEO_ID',\n        poster: 'https://img.youtube.com/vi/VIDEO_ID/maxresdefault.jpg'\n    },\n    {\n        title: 'Banana',\n        href: 'https://example.org/images/banana.jpg',\n        type: 'image/jpeg',\n        thumbnail: 'https://example.org/thumbnails/banana.jpg'\n    }\n]);\n```\n\nIf the `href` and `poster` properties are undefined, they are set automatically\nbased on the video ID.\n\nPlease note that the Gallery YouTube integration requires a browser with\n[postMessage](https://developer.mozilla.org/en-US/docs/Web/API/window.postMessage)\nsupport, which excludes IE7.\n\n#### Vimeo\nThe Gallery can display [Vimeo](https://vimeo.com/) videos for Gallery items\nwith a **type** of **text/html** and a **vimeo** property\n(configurable via [Vimeo options](#vimeo-options)) with the Vimeo video-ID:\n\n```js\nblueimp.Gallery([\n    {\n        title: 'A Vimeo video',\n        href: 'https://vimeo.com/VIDEO_ID',\n        type: 'text/html',\n        vimeo: 'VIDEO_ID',\n        poster: 'https://secure-b.vimeocdn.com/ts/POSTER_ID.jpg'\n    },\n    {\n        title: 'Banana',\n        href: 'https://example.org/images/banana.jpg',\n        type: 'image/jpeg',\n        thumbnail: 'https://example.org/thumbnails/banana.jpg'\n    }\n]);\n```\n\nIf the `href` property is undefined, it is set automatically based on the\nvideo ID.\n\nPlease note that the Gallery Vimeo integration requires a browser with\n[postMessage](https://developer.mozilla.org/en-US/docs/Web/API/window.postMessage)\nsupport, which excludes IE7.\n\n### Additional Gallery elements\nIt is possible to add additional elements to the Gallery widget, e.g. a\ndescription label.\n\nFirst, add the desired HTML element to the Gallery widget:\n\n```html\n<div id=\"blueimp-gallery\" class=\"blueimp-gallery\">\n    <div class=\"slides\"></div>\n    <h3 class=\"title\"></h3>\n    <!-- The placeholder for the description label: -->\n    <p class=\"description\"></p>\n    <a class=\"prev\">‹</a>\n    <a class=\"next\">›</a>\n    <a class=\"close\">×</a>\n    <a class=\"play-pause\"></a>\n    <ol class=\"indicator\"></ol>\n</div>\n```\n\nNext, add the desired element styles to your CSS file:\n\n```css\n.blueimp-gallery > .description {\n  position: absolute;\n  top: 30px;\n  left: 15px;\n  color: #fff;\n  display: none;\n}\n.blueimp-gallery-controls > .description {\n  display: block;\n}\n```\n\nThen, add the additional element information to each of your links:\n\n```html\n<div id=\"links\">\n    <a href=\"images/banana.jpg\" title=\"Banana\" data-description=\"This is a banana.\">Banana</a>\n    <a href=\"images/apple.jpg\" title=\"Apple\" data-description=\"This is an apple.\">Apple</a>\n</div>\n```\n\nFinally, initialize the Gallery with an onslide callback option, to set the\nelement content based on the information from the current link:\n\n```js\nblueimp.Gallery(\n    document.getElementById('links'),\n    {\n        onslide: function (index, slide) {\n            var text = this.list[index].getAttribute('data-description'),\n                node = this.container.find('.description');\n            node.empty();\n            if (text) {\n                node[0].appendChild(document.createTextNode(text));\n            }\n        }\n    }\n);\n```\n\n### Additional content types\nBy extending the Gallery prototype with new factory methods, additional content\ntypes can be displayed.  By default, blueimp Gallery provides the\n**imageFactory** and **videoFactory** methods for **image** and **video**\ncontent types respectively.  \n\nThe Gallery uses the **type** property of each content object to determine which\nfactory method to use.  The **type** defines the\n[Internet media type](https://en.wikipedia.org/wiki/Internet_media_type) of the\ncontent object and is composed of two or more parts: A type, a subtype, and zero\nor more optional parameters, e.g. **text/html; charset=UTF-8** for an HTML\ndocument with UTF-8 encoding.  \nThe main type (the string in front of the slash, **text** in the example above)\nis concatenated with the string **Factory** to create the factory method name,\ne.g. **textFactory**.\n\n#### Example HTML text factory implementation\nPlease note that the textFactory script has to be included after the core\nGallery script, but before including the [YouTube](#youtube) and [Vimeo](#vimeo)\nintegration plugins, which extend the textFactory implementation to handle\nYouTube and Vimeo video links.\n\nPlease also note that although blueimp Gallery doesn't require\n[jQuery](https://jquery.com/), the following example uses it for convenience.\n\nExtend the Gallery prototype with the **textFactory** method:\n\n```js\nblueimp.Gallery.prototype.textFactory = function (obj, callback) {\n    var $element = $('<div>')\n            .addClass('text-content')\n            .attr('title', obj.title);\n    $.get(obj.href)\n        .done(function (result) {\n            $element.html(result);\n            callback({\n                type: 'load',\n                target: $element[0]\n            });\n        })\n        .fail(function () {\n            callback({\n                type: 'error',\n                target: $element[0]\n            });\n        });\n    return $element[0];\n};\n```\n\nNext, add the **text-content** class to the Gallery CSS:\n\n```css\n.blueimp-gallery > .slides > .slide > .text-content {\n    overflow: auto;\n    margin: 60px auto;\n    padding: 0 60px;\n    max-width: 920px;\n    text-align: left;\n}\n```\n\nWith the previous changes in place, the Gallery can now handle HTML content\ntypes:\n\n```js\nblueimp.Gallery([\n    {\n        title: 'Noodle soup',\n        href: 'https://example.org/text/noodle-soup.html',\n        type: 'text/html'\n    },\n    {\n        title: 'Tomato salad',\n        href: 'https://example.org/text/tomato-salad.html',\n        type: 'text/html'\n    }\n]);\n```\n\n### jQuery plugin\n\n#### jQuery plugin setup\nThe blueimp Gallery jQuery plugin registers a global click handler to open links\nwith **data-gallery** attribute in the Gallery lightbox.\n\nTo use it, follow the [lightbox setup](#lightbox-setup) guide, but replace the\nminified Gallery script with the jQuery plugin version and include it after\nincluding [jQuery](https://jquery.com/):\n\n```html\n<script src=\"//ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js\"></script>\n<script src=\"js/jquery.blueimp-gallery.min.js\"></script>\n```\n\nNext, add the attribute **data-gallery** to your Gallery links:\n\n```html\n<div id=\"links\">\n    <a href=\"images/banana.jpg\" title=\"Banana\" data-gallery>\n        <img src=\"images/thumbnails/banana.jpg\" alt=\"Banana\">\n    </a>\n    <a href=\"images/apple.jpg\" title=\"Apple\" data-gallery>\n        <img src=\"images/thumbnails/apple.jpg\" alt=\"Apple\">\n    </a>\n    <a href=\"images/orange.jpg\" title=\"Orange\" data-gallery>\n        <img src=\"images/thumbnails/orange.jpg\" alt=\"Orange\">\n    </a>\n</div>\n```\n\nThe onclick handler from the [lightbox setup](#lightbox-setup) guide is not\nrequired and can be removed.\n\n#### HTML5 data-attributes\nOptions for the Gallery lightbox opened via the jQuery plugin can be defined as\n[HTML5 data-attributes](https://api.jquery.com/data/#data-html5) on the Gallery\nwidget container.\n\nThe jQuery plugin also introduces the additional **filter** option, which is\napplied to the Gallery links via\n[jQuery's filter method](https://api.jquery.com/filter/) and allows to remove\nduplicates from the list:\n\n```html\n<div id=\"blueimp-gallery\" class=\"blueimp-gallery\" data-start-slideshow=\"true\" data-filter=\":even\">\n    <div class=\"slides\"></div>\n    <h3 class=\"title\"></h3>\n    <a class=\"prev\">‹</a>\n    <a class=\"next\">›</a>\n    <a class=\"close\">×</a>\n    <a class=\"play-pause\"></a>\n    <ol class=\"indicator\"></ol>\n</div>\n```\n\nThis will initialize the Gallery with the option **startSlideshow** set to\n**true**.  \nIt will also filter the Gallery links so that only links with an even index\nnumber will be included.\n\n#### Container ids and link grouping\nIf the **data-gallery** attribute value is a valid id string\n(e.g. \"#blueimp-gallery\"), it is used as container option.  \nSetting **data-gallery** to a non-empty string also allows to group links into\ndifferent sets of Gallery images:\n\n```html\n<div id=\"fruits\">\n    <a href=\"images/banana.jpg\" title=\"Banana\" data-gallery=\"#blueimp-gallery-fruits\">\n        <img src=\"images/thumbnails/banana.jpg\" alt=\"Banana\">\n    </a>\n    <a href=\"images/apple.jpg\" title=\"Apple\" data-gallery=\"#blueimp-gallery-fruits\">\n        <img src=\"images/thumbnails/apple.jpg\" alt=\"Apple\">\n    </a>\n</div>\n<div id=\"vegetables\">\n    <a href=\"images/tomato.jpg\" title=\"Tomato\" data-gallery=\"#blueimp-gallery-vegetables\">\n        <img src=\"images/thumbnails/tomato.jpg\" alt=\"Tomato\">\n    </a>\n    <a href=\"images/onion.jpg\" title=\"Onion\" data-gallery=\"#blueimp-gallery-vegetables\">\n        <img src=\"images/thumbnails/onion.jpg\" alt=\"Onion\">\n    </a>\n</div>\n```\n\nThis will open the links with the **data-gallery** attribute\n**#blueimp-gallery-fruits** in the Gallery widget with the id\n**blueimp-gallery-fruits**, and the links with the **data-gallery** attribute\n**#blueimp-gallery-vegetables**  in the Gallery widget with the id\n**blueimp-gallery-vegetables**.\n\n#### Gallery object\nThe gallery object is stored via\n[jQuery data storage](https://api.jquery.com/category/miscellaneous/data-storage/)\non the Gallery widget when the Gallery is opened and can be retrieved the\nfollowing way:\n\n```js\nvar gallery = $('#blueimp-gallery').data('gallery');\n```\n\nThis gallery object provides all methods outlined in the API methods section.\n\n#### jQuery events\nThe jQuery plugin triggers Gallery events on the widget container, with event\nnames equivalent to the gallery [event callbacks](#event-callbacks):\n\n```js\n$('#blueimp-gallery')\n    .on('open', function (event) {\n        // Gallery open event handler\n    })\n    .on('opened', function (event) {\n        // Gallery opened event handler\n    })\n    .on('slide', function (event, index, slide) {\n        // Gallery slide event handler\n    })\n    .on('slideend', function (event, index, slide) {\n        // Gallery slideend event handler\n    })\n    .on('slidecomplete', function (event, index, slide) {\n        // Gallery slidecomplete event handler\n    })\n    .on('close', function (event) {\n        // Gallery close event handler\n    })\n    .on('closed', function (event) {\n        // Gallery closed event handler\n    });\n```\n\n## Requirements\nblueimp Gallery doesn't require any other libraries and can be used standalone\nwithout any dependencies.\n\nYou can also use the individual source files instead of the standalone minified\nversion:\n\n```html\n<link rel=\"stylesheet\" href=\"css/blueimp-gallery.css\">\n<link rel=\"stylesheet\" href=\"css/blueimp-gallery-indicator.css\">\n<link rel=\"stylesheet\" href=\"css/blueimp-gallery-video.css\">\n<!-- ... -->\n<script src=\"js/blueimp-helper.js\"></script>\n<script src=\"js/blueimp-gallery.js\"></script>\n<script src=\"js/blueimp-gallery-fullscreen.js\"></script>\n<script src=\"js/blueimp-gallery-indicator.js\"></script>\n<script src=\"js/blueimp-gallery-video.js\"></script>\n<script src=\"js/blueimp-gallery-youtube.js\"></script>\n<script src=\"js/blueimp-gallery-vimeo.js\"></script>\n```\n\nThe helper script can be replaced by [jQuery](https://jquery.com/) v. 1.7+.  \nThe fullscreen, indicator, video, youtube and vimeo source files are optional if\ntheir functionality is not required.\n\nThe [jQuery plugin](#jquery-plugin) requires\n[jQuery](https://jquery.com/) v. 1.7+ and the basic Gallery script, while the\nfullscreen, indicator, video, youtube and vimeo source files are also optional:\n\n```html\n<script src=\"//ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js\"></script>\n<script src=\"js/blueimp-gallery.js\"></script>\n<script src=\"js/blueimp-gallery-fullscreen.js\"></script>\n<script src=\"js/blueimp-gallery-indicator.js\"></script>\n<script src=\"js/blueimp-gallery-video.js\"></script>\n<script src=\"js/blueimp-gallery-youtube.js\"></script>\n<script src=\"js/blueimp-gallery-vimeo.js\"></script>\n<script src=\"js/jquery.blueimp-gallery.js\"></script>\n```\n\nPlease note that the jQuery plugin is an optional extension and not required for\nthe Gallery functionality.\n\n## Browsers\nblueimp Gallery has been tested with and supports the following browsers:\n\n### Desktop browsers\n\n* Google Chrome 14.0+\n* Apple Safari 4.0+\n* Mozilla Firefox 4.0+\n* Opera 10.0+\n* Microsoft Internet Explorer 7.0+\n\n### Mobile browsers\n\n* Apple Safari on iOS 6.0+\n* Google Chrome on iOS 6.0+\n* Google Chrome on Android 4.0+\n* Default Browser on Android 2.3+\n* Opera Mobile 12.0+\n\n## License\nReleased under the [MIT license](https://opensource.org/licenses/MIT).\n\n## Credits\nThe swipe implementation is based on code from the\n[Swipe](http://swipejs.com/) library.\n"
  },
  {
    "path": "app_frontend/static/plugin/Gallery-2.25.0/css/blueimp-gallery-indicator.css",
    "content": "@charset \"UTF-8\";\n/*\n * blueimp Gallery Indicator CSS\n * https://github.com/blueimp/Gallery\n *\n * Copyright 2013, Sebastian Tschan\n * https://blueimp.net\n *\n * Licensed under the MIT license:\n * https://opensource.org/licenses/MIT\n */\n\n.blueimp-gallery > .indicator {\n  position: absolute;\n  top: auto;\n  right: 15px;\n  bottom: 15px;\n  left: 15px;\n  margin: 0 40px;\n  padding: 0;\n  list-style: none;\n  text-align: center;\n  line-height: 10px;\n  display: none;\n}\n.blueimp-gallery > .indicator > li {\n  display: inline-block;\n  width: 9px;\n  height: 9px;\n  margin: 6px 3px 0 3px;\n  -webkit-box-sizing: content-box;\n     -moz-box-sizing: content-box;\n          box-sizing: content-box;\n  border: 1px solid transparent;\n  background: #ccc;\n  background: rgba(255, 255, 255, 0.25) center no-repeat;\n  border-radius: 5px;\n  box-shadow: 0 0 2px #000;\n  opacity: 0.5;\n  cursor: pointer;\n}\n.blueimp-gallery > .indicator > li:hover,\n.blueimp-gallery > .indicator > .active {\n  background-color: #fff;\n  border-color: #fff;\n  opacity: 1;\n}\n.blueimp-gallery-controls > .indicator {\n  display: block;\n  /* Fix z-index issues (controls behind slide element) on Android: */\n  -webkit-transform: translateZ(0);\n     -moz-transform: translateZ(0);\n      -ms-transform: translateZ(0);\n       -o-transform: translateZ(0);\n          transform: translateZ(0);\n}\n.blueimp-gallery-single > .indicator {\n  display: none;\n}\n.blueimp-gallery > .indicator {\n  -webkit-user-select: none;\n   -khtml-user-select: none;\n     -moz-user-select: none;\n      -ms-user-select: none;\n          user-select: none;\n}\n\n/* IE7 fixes */\n*+html .blueimp-gallery > .indicator > li {\n  display: inline;\n}\n"
  },
  {
    "path": "app_frontend/static/plugin/Gallery-2.25.0/css/blueimp-gallery-video.css",
    "content": "@charset \"UTF-8\";\n/*\n * blueimp Gallery Video Factory CSS\n * https://github.com/blueimp/Gallery\n *\n * Copyright 2013, Sebastian Tschan\n * https://blueimp.net\n *\n * Licensed under the MIT license:\n * https://opensource.org/licenses/MIT\n */\n\n.blueimp-gallery > .slides > .slide > .video-content > img {\n  position: absolute;\n  top: 0;\n  right: 0;\n  bottom: 0;\n  left: 0;\n  margin: auto;\n  width: auto;\n  height: auto;\n  max-width: 100%;\n  max-height: 100%;\n  /* Prevent artifacts in Mozilla Firefox: */\n  -moz-backface-visibility: hidden;\n}\n.blueimp-gallery > .slides > .slide > .video-content > video {\n  position: absolute;\n  top: 0;\n  left: 0;\n  width: 100%;\n  height: 100%;\n}\n.blueimp-gallery > .slides > .slide > .video-content > iframe {\n  position: absolute;\n  top: 100%;\n  left: 0;\n  width: 100%;\n  height: 100%;\n  border: none;\n}\n.blueimp-gallery > .slides > .slide > .video-playing > iframe {\n  top: 0;\n}\n.blueimp-gallery > .slides > .slide > .video-content > a {\n  position: absolute;\n  top: 50%;\n  right: 0;\n  left: 0;\n  margin: -64px auto 0;\n  width: 128px;\n  height: 128px;\n  background: url(../img/video-play.png) center no-repeat;\n  opacity: 0.8;\n  cursor: pointer;\n}\n.blueimp-gallery > .slides > .slide > .video-content > a:hover {\n  opacity: 1;\n}\n.blueimp-gallery > .slides > .slide > .video-playing > a,\n.blueimp-gallery > .slides > .slide > .video-playing > img {\n  display: none;\n}\n.blueimp-gallery > .slides > .slide > .video-content > video {\n  display: none;\n}\n.blueimp-gallery > .slides > .slide > .video-playing > video {\n  display: block;\n}\n.blueimp-gallery > .slides > .slide > .video-loading > a {\n  background: url(../img/loading.gif) center no-repeat;\n  background-size: 64px 64px;\n}\n\n/* Replace PNGs with SVGs for capable browsers (excluding IE<9) */\nbody:last-child .blueimp-gallery > .slides > .slide > .video-content:not(.video-loading) > a {\n  background-image: url(../img/video-play.svg);\n}\n\n/* IE7 fixes */\n*+html .blueimp-gallery > .slides > .slide > .video-content {\n  height: 100%;\n}\n*+html .blueimp-gallery > .slides > .slide > .video-content > a {\n  left: 50%;\n  margin-left: -64px;\n}\n"
  },
  {
    "path": "app_frontend/static/plugin/Gallery-2.25.0/css/blueimp-gallery.css",
    "content": "@charset \"UTF-8\";\n/*\n * blueimp Gallery CSS\n * https://github.com/blueimp/Gallery\n *\n * Copyright 2013, Sebastian Tschan\n * https://blueimp.net\n *\n * Licensed under the MIT license:\n * https://opensource.org/licenses/MIT\n */\n\n.blueimp-gallery,\n.blueimp-gallery > .slides > .slide > .slide-content {\n  position: absolute;\n  top: 0;\n  right: 0;\n  bottom: 0;\n  left: 0;\n  /* Prevent artifacts in Mozilla Firefox: */\n  -moz-backface-visibility: hidden;\n}\n.blueimp-gallery > .slides > .slide > .slide-content {\n  margin: auto;\n  width: auto;\n  height: auto;\n  max-width: 100%;\n  max-height: 100%;\n  opacity: 1;\n}\n.blueimp-gallery {\n  position: fixed;\n  z-index: 999999;\n  overflow: hidden;\n  background: #000;\n  background: rgba(0, 0, 0, 0.9);\n  opacity: 0;\n  display: none;\n  direction: ltr;\n  -ms-touch-action: none;\n  touch-action: none;\n}\n.blueimp-gallery-carousel {\n  position: relative;\n  z-index: auto;\n  margin: 1em auto;\n  /* Set the carousel width/height ratio to 16/9: */\n  padding-bottom: 56.25%;\n  box-shadow: 0 0 10px #000;\n  -ms-touch-action: pan-y;\n  touch-action: pan-y;\n}\n.blueimp-gallery-display {\n  display: block;\n  opacity: 1;\n}\n.blueimp-gallery > .slides {\n  position: relative;\n  height: 100%;\n  overflow: hidden;\n}\n.blueimp-gallery-carousel > .slides {\n  position: absolute;\n}\n.blueimp-gallery > .slides > .slide {\n  position: relative;\n  float: left;\n  height: 100%;\n  text-align: center;\n  -webkit-transition-timing-function: cubic-bezier(0.645, 0.045, 0.355, 1.000);\n     -moz-transition-timing-function: cubic-bezier(0.645, 0.045, 0.355, 1.000);\n      -ms-transition-timing-function: cubic-bezier(0.645, 0.045, 0.355, 1.000);\n       -o-transition-timing-function: cubic-bezier(0.645, 0.045, 0.355, 1.000);\n          transition-timing-function: cubic-bezier(0.645, 0.045, 0.355, 1.000);\n}\n.blueimp-gallery,\n.blueimp-gallery > .slides > .slide > .slide-content {\n  -webkit-transition: opacity 0.2s linear;\n     -moz-transition: opacity 0.2s linear;\n      -ms-transition: opacity 0.2s linear;\n       -o-transition: opacity 0.2s linear;\n          transition: opacity 0.2s linear;\n}\n.blueimp-gallery > .slides > .slide-loading {\n  background: url(../img/loading.gif) center no-repeat;\n  background-size: 64px 64px;\n}\n.blueimp-gallery > .slides > .slide-loading > .slide-content {\n  opacity: 0;\n}\n.blueimp-gallery > .slides > .slide-error {\n  background: url(../img/error.png) center no-repeat;\n}\n.blueimp-gallery > .slides > .slide-error > .slide-content {\n  display: none;\n}\n.blueimp-gallery > .prev,\n.blueimp-gallery > .next {\n  position: absolute;\n  top: 50%;\n  left: 15px;\n  width: 40px;\n  height: 40px;\n  margin-top: -23px;\n  font-family: \"Helvetica Neue\", Helvetica, Arial, sans-serif;\n  font-size: 60px;\n  font-weight: 100;\n  line-height: 30px;\n  color: #fff;\n  text-decoration: none;\n  text-shadow: 0 0 2px #000;\n  text-align: center;\n  background: #222;\n  background: rgba(0, 0, 0, 0.5);\n  -webkit-box-sizing: content-box;\n     -moz-box-sizing: content-box;\n          box-sizing: content-box;\n  border: 3px solid #fff;\n  -webkit-border-radius: 23px;\n     -moz-border-radius: 23px;\n          border-radius: 23px;\n  opacity: 0.5;\n  cursor: pointer;\n  display: none;\n}\n.blueimp-gallery > .next {\n  left: auto;\n  right: 15px;\n}\n.blueimp-gallery > .close,\n.blueimp-gallery > .title {\n  position: absolute;\n  top: 15px;\n  left: 15px;\n  margin: 0 40px 0 0;\n  font-size: 20px;\n  line-height: 30px;\n  color: #fff;\n  text-shadow: 0 0 2px #000;\n  opacity: 0.8;\n  display: none;\n}\n.blueimp-gallery > .close {\n  padding: 15px;\n  right: 15px;\n  left: auto;\n  margin: -15px;\n  font-size: 30px;\n  text-decoration: none;\n  cursor: pointer;\n}\n.blueimp-gallery > .play-pause {\n  position: absolute;\n  right: 15px;\n  bottom: 15px;\n  width: 15px;\n  height: 15px;\n  background: url(../img/play-pause.png) 0 0 no-repeat;\n  cursor: pointer;\n  opacity: 0.5;\n  display: none;\n}\n.blueimp-gallery-playing > .play-pause {\n  background-position: -15px 0;\n}\n.blueimp-gallery > .prev:hover,\n.blueimp-gallery > .next:hover,\n.blueimp-gallery > .close:hover,\n.blueimp-gallery > .title:hover,\n.blueimp-gallery > .play-pause:hover {\n  color: #fff;\n  opacity: 1;\n}\n.blueimp-gallery-controls > .prev,\n.blueimp-gallery-controls > .next,\n.blueimp-gallery-controls > .close,\n.blueimp-gallery-controls > .title,\n.blueimp-gallery-controls > .play-pause {\n  display: block;\n  /* Fix z-index issues (controls behind slide element) on Android: */\n  -webkit-transform: translateZ(0);\n     -moz-transform: translateZ(0);\n      -ms-transform: translateZ(0);\n       -o-transform: translateZ(0);\n          transform: translateZ(0);\n}\n.blueimp-gallery-single > .prev,\n.blueimp-gallery-left > .prev,\n.blueimp-gallery-single > .next,\n.blueimp-gallery-right > .next,\n.blueimp-gallery-single > .play-pause {\n  display: none;\n}\n.blueimp-gallery > .slides > .slide > .slide-content,\n.blueimp-gallery > .prev,\n.blueimp-gallery > .next,\n.blueimp-gallery > .close,\n.blueimp-gallery > .play-pause {\n  -webkit-user-select: none;\n   -khtml-user-select: none;\n     -moz-user-select: none;\n      -ms-user-select: none;\n          user-select: none;\n}\n\n/* Replace PNGs with SVGs for capable browsers (excluding IE<9) */\nbody:last-child .blueimp-gallery > .slides > .slide-error {\n  background-image: url(../img/error.svg);\n}\nbody:last-child .blueimp-gallery > .play-pause {\n  width: 20px;\n  height: 20px;\n  background-size: 40px 20px;\n  background-image: url(../img/play-pause.svg);\n}\nbody:last-child .blueimp-gallery-playing > .play-pause {\n  background-position: -20px 0;\n}\n\n/* IE7 fixes */\n*+html .blueimp-gallery > .slides > .slide {\n  min-height: 300px;\n}\n*+html .blueimp-gallery > .slides > .slide > .slide-content {\n  position: relative;\n}\n"
  },
  {
    "path": "app_frontend/static/plugin/Gallery-2.25.0/css/demo/demo.css",
    "content": "/*\n * blueimp Gallery Demo CSS\n * https://github.com/blueimp/Gallery\n *\n * Copyright 2013, Sebastian Tschan\n * https://blueimp.net\n *\n * Licensed under the MIT license:\n * https://opensource.org/licenses/MIT\n */\n\nbody {\n  max-width: 750px;\n  margin: 0 auto;\n  padding: 1em;\n  font-family: 'Lucida Grande', 'Lucida Sans Unicode', Arial, sans-serif;\n  font-size: 1em;\n  line-height: 1.4em;\n  background: #222;\n  color: #fff;\n  -webkit-text-size-adjust: 100%;\n      -ms-text-size-adjust: 100%;\n}\na {\n  color: orange;\n  text-decoration: none;\n}\nimg {\n  border: 0;\n  vertical-align: middle;\n}\nh1 {\n  line-height: 1em;\n}\nh2,\n.links {\n  text-align: center;\n}\n\n@media (min-width: 481px) {\n  .navigation {\n    list-style: none;\n    padding: 0;\n  }\n  .navigation li {\n    display: inline-block;\n  }\n  .navigation li:not(:first-child):before {\n    content: '| ';\n  }\n}\n"
  },
  {
    "path": "app_frontend/static/plugin/Gallery-2.25.0/index.html",
    "content": "<!DOCTYPE HTML>\n<!--\n/*\n * blueimp Gallery Demo\n * https://github.com/blueimp/Gallery\n *\n * Copyright 2013, Sebastian Tschan\n * https://blueimp.net\n *\n * Licensed under the MIT license:\n * https://opensource.org/licenses/MIT\n */\n-->\n<html lang=\"en\">\n<head>\n<!--[if IE]>\n<meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge,chrome=1\">\n<![endif]-->\n<meta charset=\"utf-8\">\n<title>blueimp Gallery</title>\n<meta name=\"description\" content=\"blueimp Gallery is a touch-enabled, responsive and customizable image and video gallery, carousel and lightbox, optimized for both mobile and desktop web browsers. It features swipe, mouse and keyboard navigation, transition effects, slideshow functionality, fullscreen support and on-demand content loading and can be extended to display additional content types.\">\n<meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n<link rel=\"stylesheet\" href=\"css/blueimp-gallery.css\">\n<link rel=\"stylesheet\" href=\"css/blueimp-gallery-indicator.css\">\n<link rel=\"stylesheet\" href=\"css/blueimp-gallery-video.css\">\n<link rel=\"stylesheet\" href=\"css/demo/demo.css\">\n</head>\n<body>\n<h1>blueimp Gallery</h1>\n<p><a href=\"https://github.com/blueimp/Gallery\">blueimp Gallery</a> is a touch-enabled, responsive and customizable image &amp; video gallery, carousel and lightbox, optimized for both mobile and desktop web browsers.<br>\nIt features swipe, mouse and keyboard navigation, transition effects, slideshow functionality, fullscreen support and on-demand content loading and can be extended to display additional content types.</p>\n<ul class=\"navigation\">\n    <li><a href=\"https://github.com/blueimp/Gallery/tags\">Download</a></li>\n    <li><a href=\"https://github.com/blueimp/Gallery\">Source Code</a></li>\n    <li><a href=\"https://github.com/blueimp/Gallery/blob/master/README.md\">Documentation</a></li>\n    <li><a href=\"https://blueimp.net\">&copy; Sebastian Tschan</a></li>\n</ul>\n<p><a href=\"https://github.com/blueimp/Gallery\">blueimp Gallery</a> is based on <a href=\"http://swipejs.com/\">Swipe</a>.</p>\n<br>\n<h2>Carousel image gallery</h2>\n<!-- The Gallery as inline carousel, can be positioned anywhere on the page -->\n<div id=\"blueimp-image-carousel\" class=\"blueimp-gallery blueimp-gallery-carousel\">\n    <div class=\"slides\"></div>\n    <h3 class=\"title\"></h3>\n    <a class=\"prev\">‹</a>\n    <a class=\"next\">›</a>\n    <a class=\"play-pause\"></a>\n</div>\n<br>\n<h2>Carousel video gallery</h2>\n<!-- The Gallery as inline carousel, can be positioned anywhere on the page -->\n<div id=\"blueimp-video-carousel\" class=\"blueimp-gallery blueimp-gallery-controls blueimp-gallery-carousel\">\n    <div class=\"slides\"></div>\n    <h3 class=\"title\"></h3>\n    <a class=\"prev\">‹</a>\n    <a class=\"next\">›</a>\n    <a class=\"play-pause\"></a>\n</div>\n<br>\n<h2>Lightbox image gallery</h2>\n<!-- The container for the list of example images -->\n<div id=\"links\" class=\"links\"></div>\n<!-- The Gallery as lightbox dialog, should be a child element of the document body -->\n<div id=\"blueimp-gallery\" class=\"blueimp-gallery\">\n    <div class=\"slides\"></div>\n    <h3 class=\"title\"></h3>\n    <a class=\"prev\">‹</a>\n    <a class=\"next\">›</a>\n    <a class=\"close\">×</a>\n    <a class=\"play-pause\"></a>\n    <ol class=\"indicator\"></ol>\n</div>\n<script src=\"js/blueimp-helper.js\"></script>\n<script src=\"js/blueimp-gallery.js\"></script>\n<script src=\"js/blueimp-gallery-fullscreen.js\"></script>\n<script src=\"js/blueimp-gallery-indicator.js\"></script>\n<script src=\"js/blueimp-gallery-video.js\"></script>\n<script src=\"js/blueimp-gallery-vimeo.js\"></script>\n<script src=\"js/blueimp-gallery-youtube.js\"></script>\n<script src=\"js/vendor/jquery.js\"></script>\n<script src=\"js/jquery.blueimp-gallery.js\"></script>\n<script src=\"js/demo/demo.js\"></script>\n</body>\n</html>\n"
  },
  {
    "path": "app_frontend/static/plugin/Gallery-2.25.0/js/blueimp-gallery-fullscreen.js",
    "content": "/*\n * blueimp Gallery Fullscreen JS\n * https://github.com/blueimp/Gallery\n *\n * Copyright 2013, Sebastian Tschan\n * https://blueimp.net\n *\n * Licensed under the MIT license:\n * https://opensource.org/licenses/MIT\n */\n\n/* global define, window, document */\n\n;(function (factory) {\n  'use strict'\n  if (typeof define === 'function' && define.amd) {\n    // Register as an anonymous AMD module:\n    define([\n      './blueimp-helper',\n      './blueimp-gallery'\n    ], factory)\n  } else {\n    // Browser globals:\n    factory(\n      window.blueimp.helper || window.jQuery,\n      window.blueimp.Gallery\n    )\n  }\n}(function ($, Gallery) {\n  'use strict'\n\n  $.extend(Gallery.prototype.options, {\n    // Defines if the gallery should open in fullscreen mode:\n    fullScreen: false\n  })\n\n  var initialize = Gallery.prototype.initialize\n  var close = Gallery.prototype.close\n\n  $.extend(Gallery.prototype, {\n    getFullScreenElement: function () {\n      return document.fullscreenElement ||\n      document.webkitFullscreenElement ||\n      document.mozFullScreenElement ||\n      document.msFullscreenElement\n    },\n\n    requestFullScreen: function (element) {\n      if (element.requestFullscreen) {\n        element.requestFullscreen()\n      } else if (element.webkitRequestFullscreen) {\n        element.webkitRequestFullscreen()\n      } else if (element.mozRequestFullScreen) {\n        element.mozRequestFullScreen()\n      } else if (element.msRequestFullscreen) {\n        element.msRequestFullscreen()\n      }\n    },\n\n    exitFullScreen: function () {\n      if (document.exitFullscreen) {\n        document.exitFullscreen()\n      } else if (document.webkitCancelFullScreen) {\n        document.webkitCancelFullScreen()\n      } else if (document.mozCancelFullScreen) {\n        document.mozCancelFullScreen()\n      } else if (document.msExitFullscreen) {\n        document.msExitFullscreen()\n      }\n    },\n\n    initialize: function () {\n      initialize.call(this)\n      if (this.options.fullScreen && !this.getFullScreenElement()) {\n        this.requestFullScreen(this.container[0])\n      }\n    },\n\n    close: function () {\n      if (this.getFullScreenElement() === this.container[0]) {\n        this.exitFullScreen()\n      }\n      close.call(this)\n    }\n\n  })\n\n  return Gallery\n}))\n"
  },
  {
    "path": "app_frontend/static/plugin/Gallery-2.25.0/js/blueimp-gallery-indicator.js",
    "content": "/*\n * blueimp Gallery Indicator JS\n * https://github.com/blueimp/Gallery\n *\n * Copyright 2013, Sebastian Tschan\n * https://blueimp.net\n *\n * Licensed under the MIT license:\n * https://opensource.org/licenses/MIT\n */\n\n/* global define, window, document */\n\n;(function (factory) {\n  'use strict'\n  if (typeof define === 'function' && define.amd) {\n    // Register as an anonymous AMD module:\n    define([\n      './blueimp-helper',\n      './blueimp-gallery'\n    ], factory)\n  } else {\n    // Browser globals:\n    factory(\n      window.blueimp.helper || window.jQuery,\n      window.blueimp.Gallery\n    )\n  }\n}(function ($, Gallery) {\n  'use strict'\n\n  $.extend(Gallery.prototype.options, {\n    // The tag name, Id, element or querySelector of the indicator container:\n    indicatorContainer: 'ol',\n    // The class for the active indicator:\n    activeIndicatorClass: 'active',\n    // The list object property (or data attribute) with the thumbnail URL,\n    // used as alternative to a thumbnail child element:\n    thumbnailProperty: 'thumbnail',\n    // Defines if the gallery indicators should display a thumbnail:\n    thumbnailIndicators: true\n  })\n\n  var initSlides = Gallery.prototype.initSlides\n  var addSlide = Gallery.prototype.addSlide\n  var resetSlides = Gallery.prototype.resetSlides\n  var handleClick = Gallery.prototype.handleClick\n  var handleSlide = Gallery.prototype.handleSlide\n  var handleClose = Gallery.prototype.handleClose\n\n  $.extend(Gallery.prototype, {\n    createIndicator: function (obj) {\n      var indicator = this.indicatorPrototype.cloneNode(false)\n      var title = this.getItemProperty(obj, this.options.titleProperty)\n      var thumbnailProperty = this.options.thumbnailProperty\n      var thumbnailUrl\n      var thumbnail\n      if (this.options.thumbnailIndicators) {\n        if (thumbnailProperty) {\n          thumbnailUrl = this.getItemProperty(obj, thumbnailProperty)\n        }\n        if (thumbnailUrl === undefined) {\n          thumbnail = obj.getElementsByTagName && $(obj).find('img')[0]\n          if (thumbnail) {\n            thumbnailUrl = thumbnail.src\n          }\n        }\n        if (thumbnailUrl) {\n          indicator.style.backgroundImage = 'url(\"' + thumbnailUrl + '\")'\n        }\n      }\n      if (title) {\n        indicator.title = title\n      }\n      return indicator\n    },\n\n    addIndicator: function (index) {\n      if (this.indicatorContainer.length) {\n        var indicator = this.createIndicator(this.list[index])\n        indicator.setAttribute('data-index', index)\n        this.indicatorContainer[0].appendChild(indicator)\n        this.indicators.push(indicator)\n      }\n    },\n\n    setActiveIndicator: function (index) {\n      if (this.indicators) {\n        if (this.activeIndicator) {\n          this.activeIndicator\n            .removeClass(this.options.activeIndicatorClass)\n        }\n        this.activeIndicator = $(this.indicators[index])\n        this.activeIndicator\n          .addClass(this.options.activeIndicatorClass)\n      }\n    },\n\n    initSlides: function (reload) {\n      if (!reload) {\n        this.indicatorContainer = this.container.find(\n          this.options.indicatorContainer\n        )\n        if (this.indicatorContainer.length) {\n          this.indicatorPrototype = document.createElement('li')\n          this.indicators = this.indicatorContainer[0].children\n        }\n      }\n      initSlides.call(this, reload)\n    },\n\n    addSlide: function (index) {\n      addSlide.call(this, index)\n      this.addIndicator(index)\n    },\n\n    resetSlides: function () {\n      resetSlides.call(this)\n      this.indicatorContainer.empty()\n      this.indicators = []\n    },\n\n    handleClick: function (event) {\n      var target = event.target || event.srcElement\n      var parent = target.parentNode\n      if (parent === this.indicatorContainer[0]) {\n        // Click on indicator element\n        this.preventDefault(event)\n        this.slide(this.getNodeIndex(target))\n      } else if (parent.parentNode === this.indicatorContainer[0]) {\n        // Click on indicator child element\n        this.preventDefault(event)\n        this.slide(this.getNodeIndex(parent))\n      } else {\n        return handleClick.call(this, event)\n      }\n    },\n\n    handleSlide: function (index) {\n      handleSlide.call(this, index)\n      this.setActiveIndicator(index)\n    },\n\n    handleClose: function () {\n      if (this.activeIndicator) {\n        this.activeIndicator\n          .removeClass(this.options.activeIndicatorClass)\n      }\n      handleClose.call(this)\n    }\n\n  })\n\n  return Gallery\n}))\n"
  },
  {
    "path": "app_frontend/static/plugin/Gallery-2.25.0/js/blueimp-gallery-video.js",
    "content": "/*\n * blueimp Gallery Video Factory JS\n * https://github.com/blueimp/Gallery\n *\n * Copyright 2013, Sebastian Tschan\n * https://blueimp.net\n *\n * Licensed under the MIT license:\n * https://opensource.org/licenses/MIT\n */\n\n/* global define, window, document */\n\n;(function (factory) {\n  'use strict'\n  if (typeof define === 'function' && define.amd) {\n    // Register as an anonymous AMD module:\n    define([\n      './blueimp-helper',\n      './blueimp-gallery'\n    ], factory)\n  } else {\n    // Browser globals:\n    factory(\n      window.blueimp.helper || window.jQuery,\n      window.blueimp.Gallery\n    )\n  }\n}(function ($, Gallery) {\n  'use strict'\n\n  $.extend(Gallery.prototype.options, {\n    // The class for video content elements:\n    videoContentClass: 'video-content',\n    // The class for video when it is loading:\n    videoLoadingClass: 'video-loading',\n    // The class for video when it is playing:\n    videoPlayingClass: 'video-playing',\n    // The list object property (or data attribute) for the video poster URL:\n    videoPosterProperty: 'poster',\n    // The list object property (or data attribute) for the video sources array:\n    videoSourcesProperty: 'sources'\n  })\n\n  var handleSlide = Gallery.prototype.handleSlide\n\n  $.extend(Gallery.prototype, {\n    handleSlide: function (index) {\n      handleSlide.call(this, index)\n      if (this.playingVideo) {\n        this.playingVideo.pause()\n      }\n    },\n\n    videoFactory: function (obj, callback, videoInterface) {\n      var that = this\n      var options = this.options\n      var videoContainerNode = this.elementPrototype.cloneNode(false)\n      var videoContainer = $(videoContainerNode)\n      var errorArgs = [{\n        type: 'error',\n        target: videoContainerNode\n      }]\n      var video = videoInterface || document.createElement('video')\n      var url = this.getItemProperty(obj, options.urlProperty)\n      var type = this.getItemProperty(obj, options.typeProperty)\n      var title = this.getItemProperty(obj, options.titleProperty)\n      var posterUrl = this.getItemProperty(obj, options.videoPosterProperty)\n      var posterImage\n      var sources = this.getItemProperty(\n        obj,\n        options.videoSourcesProperty\n      )\n      var source\n      var playMediaControl\n      var isLoading\n      var hasControls\n      videoContainer.addClass(options.videoContentClass)\n      if (title) {\n        videoContainerNode.title = title\n      }\n      if (video.canPlayType) {\n        if (url && type && video.canPlayType(type)) {\n          video.src = url\n        } else if (sources) {\n          while (sources.length) {\n            source = sources.shift()\n            url = this.getItemProperty(source, options.urlProperty)\n            type = this.getItemProperty(source, options.typeProperty)\n            if (url && type && video.canPlayType(type)) {\n              video.src = url\n              break\n            }\n          }\n        }\n      }\n      if (posterUrl) {\n        video.poster = posterUrl\n        posterImage = this.imagePrototype.cloneNode(false)\n        $(posterImage).addClass(options.toggleClass)\n        posterImage.src = posterUrl\n        posterImage.draggable = false\n        videoContainerNode.appendChild(posterImage)\n      }\n      playMediaControl = document.createElement('a')\n      playMediaControl.setAttribute('target', '_blank')\n      if (!videoInterface) {\n        playMediaControl.setAttribute('download', title)\n      }\n      playMediaControl.href = url\n      if (video.src) {\n        video.controls = true\n        ;(videoInterface || $(video))\n          .on('error', function () {\n            that.setTimeout(callback, errorArgs)\n          })\n          .on('pause', function () {\n            if (video.seeking) return\n            isLoading = false\n            videoContainer\n              .removeClass(that.options.videoLoadingClass)\n              .removeClass(that.options.videoPlayingClass)\n            if (hasControls) {\n              that.container.addClass(that.options.controlsClass)\n            }\n            delete that.playingVideo\n            if (that.interval) {\n              that.play()\n            }\n          })\n          .on('playing', function () {\n            isLoading = false\n            videoContainer\n              .removeClass(that.options.videoLoadingClass)\n              .addClass(that.options.videoPlayingClass)\n            if (that.container.hasClass(that.options.controlsClass)) {\n              hasControls = true\n              that.container.removeClass(that.options.controlsClass)\n            } else {\n              hasControls = false\n            }\n          })\n          .on('play', function () {\n            window.clearTimeout(that.timeout)\n            isLoading = true\n            videoContainer.addClass(that.options.videoLoadingClass)\n            that.playingVideo = video\n          })\n        $(playMediaControl).on('click', function (event) {\n          that.preventDefault(event)\n          if (isLoading) {\n            video.pause()\n          } else {\n            video.play()\n          }\n        })\n        videoContainerNode.appendChild(\n          (videoInterface && videoInterface.element) || video\n        )\n      }\n      videoContainerNode.appendChild(playMediaControl)\n      this.setTimeout(callback, [{\n        type: 'load',\n        target: videoContainerNode\n      }])\n      return videoContainerNode\n    }\n  })\n\n  return Gallery\n}))\n"
  },
  {
    "path": "app_frontend/static/plugin/Gallery-2.25.0/js/blueimp-gallery-vimeo.js",
    "content": "/*\n * blueimp Gallery Vimeo Video Factory JS\n * https://github.com/blueimp/Gallery\n *\n * Copyright 2013, Sebastian Tschan\n * https://blueimp.net\n *\n * Licensed under the MIT license:\n * https://opensource.org/licenses/MIT\n */\n\n/* global define, window, document, $f */\n\n;(function (factory) {\n  'use strict'\n  if (typeof define === 'function' && define.amd) {\n    // Register as an anonymous AMD module:\n    define([\n      './blueimp-helper',\n      './blueimp-gallery-video'\n    ], factory)\n  } else {\n    // Browser globals:\n    factory(\n      window.blueimp.helper || window.jQuery,\n      window.blueimp.Gallery\n    )\n  }\n}(function ($, Gallery) {\n  'use strict'\n\n  if (!window.postMessage) {\n    return Gallery\n  }\n\n  $.extend(Gallery.prototype.options, {\n    // The list object property (or data attribute) with the Vimeo video id:\n    vimeoVideoIdProperty: 'vimeo',\n    // The URL for the Vimeo video player, can be extended with custom parameters:\n    // https://developer.vimeo.com/player/embedding\n    vimeoPlayerUrl: '//player.vimeo.com/video/VIDEO_ID?api=1&player_id=PLAYER_ID',\n    // The prefix for the Vimeo video player ID:\n    vimeoPlayerIdPrefix: 'vimeo-player-',\n    // Require a click on the native Vimeo player for the initial playback:\n    vimeoClickToPlay: true\n  })\n\n  var textFactory = Gallery.prototype.textFactory ||\n                      Gallery.prototype.imageFactory\n  var VimeoPlayer = function (url, videoId, playerId, clickToPlay) {\n    this.url = url\n    this.videoId = videoId\n    this.playerId = playerId\n    this.clickToPlay = clickToPlay\n    this.element = document.createElement('div')\n    this.listeners = {}\n  }\n  var counter = 0\n\n  $.extend(VimeoPlayer.prototype, {\n    canPlayType: function () {\n      return true\n    },\n\n    on: function (type, func) {\n      this.listeners[type] = func\n      return this\n    },\n\n    loadAPI: function () {\n      var that = this\n      var apiUrl = '//f.vimeocdn.com/js/froogaloop2.min.js'\n      var scriptTags = document.getElementsByTagName('script')\n      var i = scriptTags.length\n      var scriptTag\n      var called\n      function callback () {\n        if (!called && that.playOnReady) {\n          that.play()\n        }\n        called = true\n      }\n      while (i) {\n        i -= 1\n        if (scriptTags[i].src === apiUrl) {\n          scriptTag = scriptTags[i]\n          break\n        }\n      }\n      if (!scriptTag) {\n        scriptTag = document.createElement('script')\n        scriptTag.src = apiUrl\n      }\n      $(scriptTag).on('load', callback)\n      scriptTags[0].parentNode.insertBefore(scriptTag, scriptTags[0])\n      // Fix for cached scripts on IE 8:\n      if (/loaded|complete/.test(scriptTag.readyState)) {\n        callback()\n      }\n    },\n\n    onReady: function () {\n      var that = this\n      this.ready = true\n      this.player.addEvent('play', function () {\n        that.hasPlayed = true\n        that.onPlaying()\n      })\n      this.player.addEvent('pause', function () {\n        that.onPause()\n      })\n      this.player.addEvent('finish', function () {\n        that.onPause()\n      })\n      if (this.playOnReady) {\n        this.play()\n      }\n    },\n\n    onPlaying: function () {\n      if (this.playStatus < 2) {\n        this.listeners.playing()\n        this.playStatus = 2\n      }\n    },\n\n    onPause: function () {\n      this.listeners.pause()\n      delete this.playStatus\n    },\n\n    insertIframe: function () {\n      var iframe = document.createElement('iframe')\n      iframe.src = this.url\n        .replace('VIDEO_ID', this.videoId)\n        .replace('PLAYER_ID', this.playerId)\n      iframe.id = this.playerId\n      this.element.parentNode.replaceChild(iframe, this.element)\n      this.element = iframe\n    },\n\n    play: function () {\n      var that = this\n      if (!this.playStatus) {\n        this.listeners.play()\n        this.playStatus = 1\n      }\n      if (this.ready) {\n        if (!this.hasPlayed && (this.clickToPlay || (window.navigator &&\n          /iP(hone|od|ad)/.test(window.navigator.platform)))) {\n          // Manually trigger the playing callback if clickToPlay\n          // is enabled and to workaround a limitation in iOS,\n          // which requires synchronous user interaction to start\n          // the video playback:\n          this.onPlaying()\n        } else {\n          this.player.api('play')\n        }\n      } else {\n        this.playOnReady = true\n        if (!window.$f) {\n          this.loadAPI()\n        } else if (!this.player) {\n          this.insertIframe()\n          this.player = $f(this.element)\n          this.player.addEvent('ready', function () {\n            that.onReady()\n          })\n        }\n      }\n    },\n\n    pause: function () {\n      if (this.ready) {\n        this.player.api('pause')\n      } else if (this.playStatus) {\n        delete this.playOnReady\n        this.listeners.pause()\n        delete this.playStatus\n      }\n    }\n\n  })\n\n  $.extend(Gallery.prototype, {\n    VimeoPlayer: VimeoPlayer,\n\n    textFactory: function (obj, callback) {\n      var options = this.options\n      var videoId = this.getItemProperty(obj, options.vimeoVideoIdProperty)\n      if (videoId) {\n        if (this.getItemProperty(obj, options.urlProperty) === undefined) {\n          obj[options.urlProperty] = '//vimeo.com/' + videoId\n        }\n        counter += 1\n        return this.videoFactory(\n          obj,\n          callback,\n          new VimeoPlayer(\n            options.vimeoPlayerUrl,\n            videoId,\n            options.vimeoPlayerIdPrefix + counter,\n            options.vimeoClickToPlay\n          )\n        )\n      }\n      return textFactory.call(this, obj, callback)\n    }\n\n  })\n\n  return Gallery\n}))\n"
  },
  {
    "path": "app_frontend/static/plugin/Gallery-2.25.0/js/blueimp-gallery-youtube.js",
    "content": "/*\n * blueimp Gallery YouTube Video Factory JS\n * https://github.com/blueimp/Gallery\n *\n * Copyright 2013, Sebastian Tschan\n * https://blueimp.net\n *\n * Licensed under the MIT license:\n * https://opensource.org/licenses/MIT\n */\n\n/* global define, window, document, YT */\n\n;(function (factory) {\n  'use strict'\n  if (typeof define === 'function' && define.amd) {\n    // Register as an anonymous AMD module:\n    define([\n      './blueimp-helper',\n      './blueimp-gallery-video'\n    ], factory)\n  } else {\n    // Browser globals:\n    factory(\n      window.blueimp.helper || window.jQuery,\n      window.blueimp.Gallery\n    )\n  }\n}(function ($, Gallery) {\n  'use strict'\n\n  if (!window.postMessage) {\n    return Gallery\n  }\n\n  $.extend(Gallery.prototype.options, {\n    // The list object property (or data attribute) with the YouTube video id:\n    youTubeVideoIdProperty: 'youtube',\n    // Optional object with parameters passed to the YouTube video player:\n    // https://developers.google.com/youtube/player_parameters\n    youTubePlayerVars: {\n      wmode: 'transparent'\n    },\n    // Require a click on the native YouTube player for the initial playback:\n    youTubeClickToPlay: true\n  })\n\n  var textFactory = Gallery.prototype.textFactory ||\n                      Gallery.prototype.imageFactory\n  var YouTubePlayer = function (videoId, playerVars, clickToPlay) {\n    this.videoId = videoId\n    this.playerVars = playerVars\n    this.clickToPlay = clickToPlay\n    this.element = document.createElement('div')\n    this.listeners = {}\n  }\n\n  $.extend(YouTubePlayer.prototype, {\n    canPlayType: function () {\n      return true\n    },\n\n    on: function (type, func) {\n      this.listeners[type] = func\n      return this\n    },\n\n    loadAPI: function () {\n      var that = this\n      var onYouTubeIframeAPIReady = window.onYouTubeIframeAPIReady\n      var apiUrl = '//www.youtube.com/iframe_api'\n      var scriptTags = document.getElementsByTagName('script')\n      var i = scriptTags.length\n      var scriptTag\n      window.onYouTubeIframeAPIReady = function () {\n        if (onYouTubeIframeAPIReady) {\n          onYouTubeIframeAPIReady.apply(this)\n        }\n        if (that.playOnReady) {\n          that.play()\n        }\n      }\n      while (i) {\n        i -= 1\n        if (scriptTags[i].src === apiUrl) {\n          return\n        }\n      }\n      scriptTag = document.createElement('script')\n      scriptTag.src = apiUrl\n      scriptTags[0].parentNode.insertBefore(scriptTag, scriptTags[0])\n    },\n\n    onReady: function () {\n      this.ready = true\n      if (this.playOnReady) {\n        this.play()\n      }\n    },\n\n    onPlaying: function () {\n      if (this.playStatus < 2) {\n        this.listeners.playing()\n        this.playStatus = 2\n      }\n    },\n\n    onPause: function () {\n      Gallery.prototype.setTimeout.call(\n        this,\n        this.checkSeek,\n        null,\n        2000\n      )\n    },\n\n    checkSeek: function () {\n      if (this.stateChange === YT.PlayerState.PAUSED ||\n        this.stateChange === YT.PlayerState.ENDED) {\n        // check if current state change is actually paused\n        this.listeners.pause()\n        delete this.playStatus\n      }\n    },\n\n    onStateChange: function (event) {\n      switch (event.data) {\n        case YT.PlayerState.PLAYING:\n          this.hasPlayed = true\n          this.onPlaying()\n          break\n        case YT.PlayerState.PAUSED:\n        case YT.PlayerState.ENDED:\n          this.onPause()\n          break\n      }\n      // Save most recent state change to this.stateChange\n      this.stateChange = event.data\n    },\n\n    onError: function (event) {\n      this.listeners.error(event)\n    },\n\n    play: function () {\n      var that = this\n      if (!this.playStatus) {\n        this.listeners.play()\n        this.playStatus = 1\n      }\n      if (this.ready) {\n        if (!this.hasPlayed && (this.clickToPlay || (window.navigator &&\n          /iP(hone|od|ad)/.test(window.navigator.platform)))) {\n          // Manually trigger the playing callback if clickToPlay\n          // is enabled and to workaround a limitation in iOS,\n          // which requires synchronous user interaction to start\n          // the video playback:\n          this.onPlaying()\n        } else {\n          this.player.playVideo()\n        }\n      } else {\n        this.playOnReady = true\n        if (!(window.YT && YT.Player)) {\n          this.loadAPI()\n        } else if (!this.player) {\n          this.player = new YT.Player(this.element, {\n            videoId: this.videoId,\n            playerVars: this.playerVars,\n            events: {\n              onReady: function () {\n                that.onReady()\n              },\n              onStateChange: function (event) {\n                that.onStateChange(event)\n              },\n              onError: function (event) {\n                that.onError(event)\n              }\n            }\n          })\n        }\n      }\n    },\n\n    pause: function () {\n      if (this.ready) {\n        this.player.pauseVideo()\n      } else if (this.playStatus) {\n        delete this.playOnReady\n        this.listeners.pause()\n        delete this.playStatus\n      }\n    }\n\n  })\n\n  $.extend(Gallery.prototype, {\n    YouTubePlayer: YouTubePlayer,\n\n    textFactory: function (obj, callback) {\n      var options = this.options\n      var videoId = this.getItemProperty(obj, options.youTubeVideoIdProperty)\n      if (videoId) {\n        if (this.getItemProperty(obj, options.urlProperty) === undefined) {\n          obj[options.urlProperty] = '//www.youtube.com/watch?v=' + videoId\n        }\n        if (this.getItemProperty(obj, options.videoPosterProperty) === undefined) {\n          obj[options.videoPosterProperty] = '//img.youtube.com/vi/' + videoId +\n            '/maxresdefault.jpg'\n        }\n        return this.videoFactory(\n          obj,\n          callback,\n          new YouTubePlayer(\n            videoId,\n            options.youTubePlayerVars,\n            options.youTubeClickToPlay\n          )\n        )\n      }\n      return textFactory.call(this, obj, callback)\n    }\n\n  })\n\n  return Gallery\n}))\n"
  },
  {
    "path": "app_frontend/static/plugin/Gallery-2.25.0/js/blueimp-gallery.js",
    "content": "/*\n * blueimp Gallery JS\n * https://github.com/blueimp/Gallery\n *\n * Copyright 2013, Sebastian Tschan\n * https://blueimp.net\n *\n * Swipe implementation based on\n * https://github.com/bradbirdsall/Swipe\n *\n * Licensed under the MIT license:\n * https://opensource.org/licenses/MIT\n */\n\n/* global define, window, document, DocumentTouch */\n\n;(function (factory) {\n  'use strict'\n  if (typeof define === 'function' && define.amd) {\n    // Register as an anonymous AMD module:\n    define(['./blueimp-helper'], factory)\n  } else {\n    // Browser globals:\n    window.blueimp = window.blueimp || {}\n    window.blueimp.Gallery = factory(\n      window.blueimp.helper || window.jQuery\n    )\n  }\n}(function ($) {\n  'use strict'\n\n  function Gallery (list, options) {\n    if (document.body.style.maxHeight === undefined) {\n      // document.body.style.maxHeight is undefined on IE6 and lower\n      return null\n    }\n    if (!this || this.options !== Gallery.prototype.options) {\n      // Called as function instead of as constructor,\n      // so we simply return a new instance:\n      return new Gallery(list, options)\n    }\n    if (!list || !list.length) {\n      this.console.log(\n        'blueimp Gallery: No or empty list provided as first argument.',\n        list\n      )\n      return\n    }\n    this.list = list\n    this.num = list.length\n    this.initOptions(options)\n    this.initialize()\n  }\n\n  $.extend(Gallery.prototype, {\n    options: {\n      // The Id, element or querySelector of the gallery widget:\n      container: '#blueimp-gallery',\n      // The tag name, Id, element or querySelector of the slides container:\n      slidesContainer: 'div',\n      // The tag name, Id, element or querySelector of the title element:\n      titleElement: 'h3',\n      // The class to add when the gallery is visible:\n      displayClass: 'blueimp-gallery-display',\n      // The class to add when the gallery controls are visible:\n      controlsClass: 'blueimp-gallery-controls',\n      // The class to add when the gallery only displays one element:\n      singleClass: 'blueimp-gallery-single',\n      // The class to add when the left edge has been reached:\n      leftEdgeClass: 'blueimp-gallery-left',\n      // The class to add when the right edge has been reached:\n      rightEdgeClass: 'blueimp-gallery-right',\n      // The class to add when the automatic slideshow is active:\n      playingClass: 'blueimp-gallery-playing',\n      // The class for all slides:\n      slideClass: 'slide',\n      // The slide class for loading elements:\n      slideLoadingClass: 'slide-loading',\n      // The slide class for elements that failed to load:\n      slideErrorClass: 'slide-error',\n      // The class for the content element loaded into each slide:\n      slideContentClass: 'slide-content',\n      // The class for the \"toggle\" control:\n      toggleClass: 'toggle',\n      // The class for the \"prev\" control:\n      prevClass: 'prev',\n      // The class for the \"next\" control:\n      nextClass: 'next',\n      // The class for the \"close\" control:\n      closeClass: 'close',\n      // The class for the \"play-pause\" toggle control:\n      playPauseClass: 'play-pause',\n      // The list object property (or data attribute) with the object type:\n      typeProperty: 'type',\n      // The list object property (or data attribute) with the object title:\n      titleProperty: 'title',\n      // The list object property (or data attribute) with the object URL:\n      urlProperty: 'href',\n      // The list object property (or data attribute) with the object srcset URL(s):\n      srcsetProperty: 'urlset',\n      // The gallery listens for transitionend events before triggering the\n      // opened and closed events, unless the following option is set to false:\n      displayTransition: true,\n      // Defines if the gallery slides are cleared from the gallery modal,\n      // or reused for the next gallery initialization:\n      clearSlides: true,\n      // Defines if images should be stretched to fill the available space,\n      // while maintaining their aspect ratio (will only be enabled for browsers\n      // supporting background-size=\"contain\", which excludes IE < 9).\n      // Set to \"cover\", to make images cover all available space (requires\n      // support for background-size=\"cover\", which excludes IE < 9):\n      stretchImages: false,\n      // Toggle the controls on pressing the Return key:\n      toggleControlsOnReturn: true,\n      // Toggle the controls on slide click:\n      toggleControlsOnSlideClick: true,\n      // Toggle the automatic slideshow interval on pressing the Space key:\n      toggleSlideshowOnSpace: true,\n      // Navigate the gallery by pressing left and right on the keyboard:\n      enableKeyboardNavigation: true,\n      // Close the gallery on pressing the Esc key:\n      closeOnEscape: true,\n      // Close the gallery when clicking on an empty slide area:\n      closeOnSlideClick: true,\n      // Close the gallery by swiping up or down:\n      closeOnSwipeUpOrDown: true,\n      // Emulate touch events on mouse-pointer devices such as desktop browsers:\n      emulateTouchEvents: true,\n      // Stop touch events from bubbling up to ancestor elements of the Gallery:\n      stopTouchEventsPropagation: false,\n      // Hide the page scrollbars:\n      hidePageScrollbars: true,\n      // Stops any touches on the container from scrolling the page:\n      disableScroll: true,\n      // Carousel mode (shortcut for carousel specific options):\n      carousel: false,\n      // Allow continuous navigation, moving from last to first\n      // and from first to last slide:\n      continuous: true,\n      // Remove elements outside of the preload range from the DOM:\n      unloadElements: true,\n      // Start with the automatic slideshow:\n      startSlideshow: false,\n      // Delay in milliseconds between slides for the automatic slideshow:\n      slideshowInterval: 5000,\n      // The starting index as integer.\n      // Can also be an object of the given list,\n      // or an equal object with the same url property:\n      index: 0,\n      // The number of elements to load around the current index:\n      preloadRange: 2,\n      // The transition speed between slide changes in milliseconds:\n      transitionSpeed: 400,\n      // The transition speed for automatic slide changes, set to an integer\n      // greater 0 to override the default transition speed:\n      slideshowTransitionSpeed: undefined,\n      // The event object for which the default action will be canceled\n      // on Gallery initialization (e.g. the click event to open the Gallery):\n      event: undefined,\n      // Callback function executed when the Gallery is initialized.\n      // Is called with the gallery instance as \"this\" object:\n      onopen: undefined,\n      // Callback function executed when the Gallery has been initialized\n      // and the initialization transition has been completed.\n      // Is called with the gallery instance as \"this\" object:\n      onopened: undefined,\n      // Callback function executed on slide change.\n      // Is called with the gallery instance as \"this\" object and the\n      // current index and slide as arguments:\n      onslide: undefined,\n      // Callback function executed after the slide change transition.\n      // Is called with the gallery instance as \"this\" object and the\n      // current index and slide as arguments:\n      onslideend: undefined,\n      // Callback function executed on slide content load.\n      // Is called with the gallery instance as \"this\" object and the\n      // slide index and slide element as arguments:\n      onslidecomplete: undefined,\n      // Callback function executed when the Gallery is about to be closed.\n      // Is called with the gallery instance as \"this\" object:\n      onclose: undefined,\n      // Callback function executed when the Gallery has been closed\n      // and the closing transition has been completed.\n      // Is called with the gallery instance as \"this\" object:\n      onclosed: undefined\n    },\n\n    carouselOptions: {\n      hidePageScrollbars: false,\n      toggleControlsOnReturn: false,\n      toggleSlideshowOnSpace: false,\n      enableKeyboardNavigation: false,\n      closeOnEscape: false,\n      closeOnSlideClick: false,\n      closeOnSwipeUpOrDown: false,\n      disableScroll: false,\n      startSlideshow: true\n    },\n\n    console: window.console && typeof window.console.log === 'function'\n      ? window.console\n      : {log: function () {}},\n\n    // Detect touch, transition, transform and background-size support:\n    support: (function (element) {\n      var support = {\n        touch: window.ontouchstart !== undefined ||\n          (window.DocumentTouch && document instanceof DocumentTouch)\n      }\n      var transitions = {\n        webkitTransition: {\n          end: 'webkitTransitionEnd',\n          prefix: '-webkit-'\n        },\n        MozTransition: {\n          end: 'transitionend',\n          prefix: '-moz-'\n        },\n        OTransition: {\n          end: 'otransitionend',\n          prefix: '-o-'\n        },\n        transition: {\n          end: 'transitionend',\n          prefix: ''\n        }\n      }\n      var prop\n      for (prop in transitions) {\n        if (transitions.hasOwnProperty(prop) &&\n          element.style[prop] !== undefined) {\n          support.transition = transitions[prop]\n          support.transition.name = prop\n          break\n        }\n      }\n      function elementTests () {\n        var transition = support.transition\n        var prop\n        var translateZ\n        document.body.appendChild(element)\n        if (transition) {\n          prop = transition.name.slice(0, -9) + 'ransform'\n          if (element.style[prop] !== undefined) {\n            element.style[prop] = 'translateZ(0)'\n            translateZ = window.getComputedStyle(element)\n              .getPropertyValue(transition.prefix + 'transform')\n            support.transform = {\n              prefix: transition.prefix,\n              name: prop,\n              translate: true,\n              translateZ: !!translateZ && translateZ !== 'none'\n            }\n          }\n        }\n        if (element.style.backgroundSize !== undefined) {\n          support.backgroundSize = {}\n          element.style.backgroundSize = 'contain'\n          support.backgroundSize.contain = window\n            .getComputedStyle(element)\n            .getPropertyValue('background-size') === 'contain'\n          element.style.backgroundSize = 'cover'\n          support.backgroundSize.cover = window\n            .getComputedStyle(element)\n            .getPropertyValue('background-size') === 'cover'\n        }\n        document.body.removeChild(element)\n      }\n      if (document.body) {\n        elementTests()\n      } else {\n        $(document).on('DOMContentLoaded', elementTests)\n      }\n      return support\n    // Test element, has to be standard HTML and must not be hidden\n    // for the CSS3 tests using window.getComputedStyle to be applicable:\n    }(document.createElement('div'))),\n\n    requestAnimationFrame: window.requestAnimationFrame ||\n      window.webkitRequestAnimationFrame ||\n      window.mozRequestAnimationFrame,\n\n    initialize: function () {\n      this.initStartIndex()\n      if (this.initWidget() === false) {\n        return false\n      }\n      this.initEventListeners()\n      // Load the slide at the given index:\n      this.onslide(this.index)\n      // Manually trigger the slideend event for the initial slide:\n      this.ontransitionend()\n      // Start the automatic slideshow if applicable:\n      if (this.options.startSlideshow) {\n        this.play()\n      }\n    },\n\n    slide: function (to, speed) {\n      window.clearTimeout(this.timeout)\n      var index = this.index\n      var direction\n      var naturalDirection\n      var diff\n      if (index === to || this.num === 1) {\n        return\n      }\n      if (!speed) {\n        speed = this.options.transitionSpeed\n      }\n      if (this.support.transform) {\n        if (!this.options.continuous) {\n          to = this.circle(to)\n        }\n        // 1: backward, -1: forward:\n        direction = Math.abs(index - to) / (index - to)\n        // Get the actual position of the slide:\n        if (this.options.continuous) {\n          naturalDirection = direction\n          direction = -this.positions[this.circle(to)] / this.slideWidth\n          // If going forward but to < index, use to = slides.length + to\n          // If going backward but to > index, use to = -slides.length + to\n          if (direction !== naturalDirection) {\n            to = -direction * this.num + to\n          }\n        }\n        diff = Math.abs(index - to) - 1\n        // Move all the slides between index and to in the right direction:\n        while (diff) {\n          diff -= 1\n          this.move(\n            this.circle((to > index ? to : index) - diff - 1),\n            this.slideWidth * direction,\n            0\n          )\n        }\n        to = this.circle(to)\n        this.move(index, this.slideWidth * direction, speed)\n        this.move(to, 0, speed)\n        if (this.options.continuous) {\n          this.move(\n            this.circle(to - direction),\n            -(this.slideWidth * direction),\n            0\n          )\n        }\n      } else {\n        to = this.circle(to)\n        this.animate(index * -this.slideWidth, to * -this.slideWidth, speed)\n      }\n      this.onslide(to)\n    },\n\n    getIndex: function () {\n      return this.index\n    },\n\n    getNumber: function () {\n      return this.num\n    },\n\n    prev: function () {\n      if (this.options.continuous || this.index) {\n        this.slide(this.index - 1)\n      }\n    },\n\n    next: function () {\n      if (this.options.continuous || this.index < this.num - 1) {\n        this.slide(this.index + 1)\n      }\n    },\n\n    play: function (time) {\n      var that = this\n      window.clearTimeout(this.timeout)\n      this.interval = time || this.options.slideshowInterval\n      if (this.elements[this.index] > 1) {\n        this.timeout = this.setTimeout(\n          (!this.requestAnimationFrame && this.slide) || function (to, speed) {\n            that.animationFrameId = that.requestAnimationFrame.call(\n              window,\n              function () {\n                that.slide(to, speed)\n              }\n            )\n          },\n          [this.index + 1, this.options.slideshowTransitionSpeed],\n          this.interval\n        )\n      }\n      this.container.addClass(this.options.playingClass)\n    },\n\n    pause: function () {\n      window.clearTimeout(this.timeout)\n      this.interval = null\n      this.container.removeClass(this.options.playingClass)\n    },\n\n    add: function (list) {\n      var i\n      if (!list.concat) {\n        // Make a real array out of the list to add:\n        list = Array.prototype.slice.call(list)\n      }\n      if (!this.list.concat) {\n        // Make a real array out of the Gallery list:\n        this.list = Array.prototype.slice.call(this.list)\n      }\n      this.list = this.list.concat(list)\n      this.num = this.list.length\n      if (this.num > 2 && this.options.continuous === null) {\n        this.options.continuous = true\n        this.container.removeClass(this.options.leftEdgeClass)\n      }\n      this.container\n        .removeClass(this.options.rightEdgeClass)\n        .removeClass(this.options.singleClass)\n      for (i = this.num - list.length; i < this.num; i += 1) {\n        this.addSlide(i)\n        this.positionSlide(i)\n      }\n      this.positions.length = this.num\n      this.initSlides(true)\n    },\n\n    resetSlides: function () {\n      this.slidesContainer.empty()\n      this.unloadAllSlides()\n      this.slides = []\n    },\n\n    handleClose: function () {\n      var options = this.options\n      this.destroyEventListeners()\n      // Cancel the slideshow:\n      this.pause()\n      this.container[0].style.display = 'none'\n      this.container\n        .removeClass(options.displayClass)\n        .removeClass(options.singleClass)\n        .removeClass(options.leftEdgeClass)\n        .removeClass(options.rightEdgeClass)\n      if (options.hidePageScrollbars) {\n        document.body.style.overflow = this.bodyOverflowStyle\n      }\n      if (this.options.clearSlides) {\n        this.resetSlides()\n      }\n      if (this.options.onclosed) {\n        this.options.onclosed.call(this)\n      }\n    },\n\n    close: function () {\n      var that = this\n      function closeHandler (event) {\n        if (event.target === that.container[0]) {\n          that.container.off(\n            that.support.transition.end,\n            closeHandler\n          )\n          that.handleClose()\n        }\n      }\n      if (this.options.onclose) {\n        this.options.onclose.call(this)\n      }\n      if (this.support.transition && this.options.displayTransition) {\n        this.container.on(\n          this.support.transition.end,\n          closeHandler\n        )\n        this.container.removeClass(this.options.displayClass)\n      } else {\n        this.handleClose()\n      }\n    },\n\n    circle: function (index) {\n      // Always return a number inside of the slides index range:\n      return (this.num + (index % this.num)) % this.num\n    },\n\n    move: function (index, dist, speed) {\n      this.translateX(index, dist, speed)\n      this.positions[index] = dist\n    },\n\n    translate: function (index, x, y, speed) {\n      var style = this.slides[index].style\n      var transition = this.support.transition\n      var transform = this.support.transform\n      style[transition.name + 'Duration'] = speed + 'ms'\n      style[transform.name] = 'translate(' + x + 'px, ' + y + 'px)' +\n      (transform.translateZ ? ' translateZ(0)' : '')\n    },\n\n    translateX: function (index, x, speed) {\n      this.translate(index, x, 0, speed)\n    },\n\n    translateY: function (index, y, speed) {\n      this.translate(index, 0, y, speed)\n    },\n\n    animate: function (from, to, speed) {\n      if (!speed) {\n        this.slidesContainer[0].style.left = to + 'px'\n        return\n      }\n      var that = this\n      var start = new Date().getTime()\n      var timer = window.setInterval(function () {\n        var timeElap = new Date().getTime() - start\n        if (timeElap > speed) {\n          that.slidesContainer[0].style.left = to + 'px'\n          that.ontransitionend()\n          window.clearInterval(timer)\n          return\n        }\n        that.slidesContainer[0].style.left = (((to - from) *\n          (Math.floor((timeElap / speed) * 100) / 100)) +\n          from) + 'px'\n      }, 4)\n    },\n\n    preventDefault: function (event) {\n      if (event.preventDefault) {\n        event.preventDefault()\n      } else {\n        event.returnValue = false\n      }\n    },\n\n    stopPropagation: function (event) {\n      if (event.stopPropagation) {\n        event.stopPropagation()\n      } else {\n        event.cancelBubble = true\n      }\n    },\n\n    onresize: function () {\n      this.initSlides(true)\n    },\n\n    onmousedown: function (event) {\n      // Trigger on clicks of the left mouse button only\n      // and exclude video elements:\n      if (event.which && event.which === 1 &&\n        event.target.nodeName !== 'VIDEO') {\n        // Preventing the default mousedown action is required\n        // to make touch emulation work with Firefox:\n        event.preventDefault()\n        ;(event.originalEvent || event).touches = [{\n          pageX: event.pageX,\n          pageY: event.pageY\n        }]\n        this.ontouchstart(event)\n      }\n    },\n\n    onmousemove: function (event) {\n      if (this.touchStart) {\n        (event.originalEvent || event).touches = [{\n          pageX: event.pageX,\n          pageY: event.pageY\n        }]\n        this.ontouchmove(event)\n      }\n    },\n\n    onmouseup: function (event) {\n      if (this.touchStart) {\n        this.ontouchend(event)\n        delete this.touchStart\n      }\n    },\n\n    onmouseout: function (event) {\n      if (this.touchStart) {\n        var target = event.target\n        var related = event.relatedTarget\n        if (!related || (related !== target &&\n          !$.contains(target, related))) {\n          this.onmouseup(event)\n        }\n      }\n    },\n\n    ontouchstart: function (event) {\n      if (this.options.stopTouchEventsPropagation) {\n        this.stopPropagation(event)\n      }\n      // jQuery doesn't copy touch event properties by default,\n      // so we have to access the originalEvent object:\n      var touches = (event.originalEvent || event).touches[0]\n      this.touchStart = {\n        // Remember the initial touch coordinates:\n        x: touches.pageX,\n        y: touches.pageY,\n        // Store the time to determine touch duration:\n        time: Date.now()\n      }\n      // Helper variable to detect scroll movement:\n      this.isScrolling = undefined\n      // Reset delta values:\n      this.touchDelta = {}\n    },\n\n    ontouchmove: function (event) {\n      if (this.options.stopTouchEventsPropagation) {\n        this.stopPropagation(event)\n      }\n      // jQuery doesn't copy touch event properties by default,\n      // so we have to access the originalEvent object:\n      var touches = (event.originalEvent || event).touches[0]\n      var scale = (event.originalEvent || event).scale\n      var index = this.index\n      var touchDeltaX\n      var indices\n      // Ensure this is a one touch swipe and not, e.g. a pinch:\n      if (touches.length > 1 || (scale && scale !== 1)) {\n        return\n      }\n      if (this.options.disableScroll) {\n        event.preventDefault()\n      }\n      // Measure change in x and y coordinates:\n      this.touchDelta = {\n        x: touches.pageX - this.touchStart.x,\n        y: touches.pageY - this.touchStart.y\n      }\n      touchDeltaX = this.touchDelta.x\n      // Detect if this is a vertical scroll movement (run only once per touch):\n      if (this.isScrolling === undefined) {\n        this.isScrolling = this.isScrolling ||\n        Math.abs(touchDeltaX) < Math.abs(this.touchDelta.y)\n      }\n      if (!this.isScrolling) {\n        // Always prevent horizontal scroll:\n        event.preventDefault()\n        // Stop the slideshow:\n        window.clearTimeout(this.timeout)\n        if (this.options.continuous) {\n          indices = [\n            this.circle(index + 1),\n            index,\n            this.circle(index - 1)\n          ]\n        } else {\n          // Increase resistance if first slide and sliding left\n          // or last slide and sliding right:\n          this.touchDelta.x = touchDeltaX =\n            touchDeltaX /\n            (\n            ((!index && touchDeltaX > 0) ||\n            (index === this.num - 1 && touchDeltaX < 0))\n              ? (Math.abs(touchDeltaX) / this.slideWidth + 1)\n              : 1\n          )\n          indices = [index]\n          if (index) {\n            indices.push(index - 1)\n          }\n          if (index < this.num - 1) {\n            indices.unshift(index + 1)\n          }\n        }\n        while (indices.length) {\n          index = indices.pop()\n          this.translateX(index, touchDeltaX + this.positions[index], 0)\n        }\n      } else {\n        this.translateY(index, this.touchDelta.y + this.positions[index], 0)\n      }\n    },\n\n    ontouchend: function (event) {\n      if (this.options.stopTouchEventsPropagation) {\n        this.stopPropagation(event)\n      }\n      var index = this.index\n      var speed = this.options.transitionSpeed\n      var slideWidth = this.slideWidth\n      var isShortDuration = Number(Date.now() - this.touchStart.time) < 250\n      // Determine if slide attempt triggers next/prev slide:\n      var isValidSlide =\n      (isShortDuration && Math.abs(this.touchDelta.x) > 20) ||\n        Math.abs(this.touchDelta.x) > slideWidth / 2\n      // Determine if slide attempt is past start or end:\n      var isPastBounds = (!index && this.touchDelta.x > 0) ||\n        (index === this.num - 1 && this.touchDelta.x < 0)\n      var isValidClose = !isValidSlide && this.options.closeOnSwipeUpOrDown &&\n        ((isShortDuration && Math.abs(this.touchDelta.y) > 20) ||\n        Math.abs(this.touchDelta.y) > this.slideHeight / 2)\n      var direction\n      var indexForward\n      var indexBackward\n      var distanceForward\n      var distanceBackward\n      if (this.options.continuous) {\n        isPastBounds = false\n      }\n      // Determine direction of swipe (true: right, false: left):\n      direction = this.touchDelta.x < 0 ? -1 : 1\n      if (!this.isScrolling) {\n        if (isValidSlide && !isPastBounds) {\n          indexForward = index + direction\n          indexBackward = index - direction\n          distanceForward = slideWidth * direction\n          distanceBackward = -slideWidth * direction\n          if (this.options.continuous) {\n            this.move(this.circle(indexForward), distanceForward, 0)\n            this.move(this.circle(index - 2 * direction), distanceBackward, 0)\n          } else if (indexForward >= 0 &&\n            indexForward < this.num) {\n            this.move(indexForward, distanceForward, 0)\n          }\n          this.move(index, this.positions[index] + distanceForward, speed)\n          this.move(\n            this.circle(indexBackward),\n            this.positions[this.circle(indexBackward)] + distanceForward,\n            speed\n          )\n          index = this.circle(indexBackward)\n          this.onslide(index)\n        } else {\n          // Move back into position\n          if (this.options.continuous) {\n            this.move(this.circle(index - 1), -slideWidth, speed)\n            this.move(index, 0, speed)\n            this.move(this.circle(index + 1), slideWidth, speed)\n          } else {\n            if (index) {\n              this.move(index - 1, -slideWidth, speed)\n            }\n            this.move(index, 0, speed)\n            if (index < this.num - 1) {\n              this.move(index + 1, slideWidth, speed)\n            }\n          }\n        }\n      } else {\n        if (isValidClose) {\n          this.close()\n        } else {\n          // Move back into position\n          this.translateY(index, 0, speed)\n        }\n      }\n    },\n\n    ontouchcancel: function (event) {\n      if (this.touchStart) {\n        this.ontouchend(event)\n        delete this.touchStart\n      }\n    },\n\n    ontransitionend: function (event) {\n      var slide = this.slides[this.index]\n      if (!event || slide === event.target) {\n        if (this.interval) {\n          this.play()\n        }\n        this.setTimeout(\n          this.options.onslideend,\n          [this.index, slide]\n        )\n      }\n    },\n\n    oncomplete: function (event) {\n      var target = event.target || event.srcElement\n      var parent = target && target.parentNode\n      var index\n      if (!target || !parent) {\n        return\n      }\n      index = this.getNodeIndex(parent)\n      $(parent).removeClass(this.options.slideLoadingClass)\n      if (event.type === 'error') {\n        $(parent).addClass(this.options.slideErrorClass)\n        this.elements[index] = 3 // Fail\n      } else {\n        this.elements[index] = 2 // Done\n      }\n      // Fix for IE7's lack of support for percentage max-height:\n      if (target.clientHeight > this.container[0].clientHeight) {\n        target.style.maxHeight = this.container[0].clientHeight\n      }\n      if (this.interval && this.slides[this.index] === parent) {\n        this.play()\n      }\n      this.setTimeout(\n        this.options.onslidecomplete,\n        [index, parent]\n      )\n    },\n\n    onload: function (event) {\n      this.oncomplete(event)\n    },\n\n    onerror: function (event) {\n      this.oncomplete(event)\n    },\n\n    onkeydown: function (event) {\n      switch (event.which || event.keyCode) {\n        case 13: // Return\n          if (this.options.toggleControlsOnReturn) {\n            this.preventDefault(event)\n            this.toggleControls()\n          }\n          break\n        case 27: // Esc\n          if (this.options.closeOnEscape) {\n            this.close()\n            // prevent Esc from closing other things\n            event.stopImmediatePropagation()\n          }\n          break\n        case 32: // Space\n          if (this.options.toggleSlideshowOnSpace) {\n            this.preventDefault(event)\n            this.toggleSlideshow()\n          }\n          break\n        case 37: // Left\n          if (this.options.enableKeyboardNavigation) {\n            this.preventDefault(event)\n            this.prev()\n          }\n          break\n        case 39: // Right\n          if (this.options.enableKeyboardNavigation) {\n            this.preventDefault(event)\n            this.next()\n          }\n          break\n      }\n    },\n\n    handleClick: function (event) {\n      var options = this.options\n      var target = event.target || event.srcElement\n      var parent = target.parentNode\n      function isTarget (className) {\n        return $(target).hasClass(className) ||\n        $(parent).hasClass(className)\n      }\n      if (isTarget(options.toggleClass)) {\n        // Click on \"toggle\" control\n        this.preventDefault(event)\n        this.toggleControls()\n      } else if (isTarget(options.prevClass)) {\n        // Click on \"prev\" control\n        this.preventDefault(event)\n        this.prev()\n      } else if (isTarget(options.nextClass)) {\n        // Click on \"next\" control\n        this.preventDefault(event)\n        this.next()\n      } else if (isTarget(options.closeClass)) {\n        // Click on \"close\" control\n        this.preventDefault(event)\n        this.close()\n      } else if (isTarget(options.playPauseClass)) {\n        // Click on \"play-pause\" control\n        this.preventDefault(event)\n        this.toggleSlideshow()\n      } else if (parent === this.slidesContainer[0]) {\n        // Click on slide background\n        if (options.closeOnSlideClick) {\n          this.preventDefault(event)\n          this.close()\n        } else if (options.toggleControlsOnSlideClick) {\n          this.preventDefault(event)\n          this.toggleControls()\n        }\n      } else if (parent.parentNode &&\n        parent.parentNode === this.slidesContainer[0]) {\n        // Click on displayed element\n        if (options.toggleControlsOnSlideClick) {\n          this.preventDefault(event)\n          this.toggleControls()\n        }\n      }\n    },\n\n    onclick: function (event) {\n      if (this.options.emulateTouchEvents &&\n        this.touchDelta && (Math.abs(this.touchDelta.x) > 20 ||\n        Math.abs(this.touchDelta.y) > 20)) {\n        delete this.touchDelta\n        return\n      }\n      return this.handleClick(event)\n    },\n\n    updateEdgeClasses: function (index) {\n      if (!index) {\n        this.container.addClass(this.options.leftEdgeClass)\n      } else {\n        this.container.removeClass(this.options.leftEdgeClass)\n      }\n      if (index === this.num - 1) {\n        this.container.addClass(this.options.rightEdgeClass)\n      } else {\n        this.container.removeClass(this.options.rightEdgeClass)\n      }\n    },\n\n    handleSlide: function (index) {\n      if (!this.options.continuous) {\n        this.updateEdgeClasses(index)\n      }\n      this.loadElements(index)\n      if (this.options.unloadElements) {\n        this.unloadElements(index)\n      }\n      this.setTitle(index)\n    },\n\n    onslide: function (index) {\n      this.index = index\n      this.handleSlide(index)\n      this.setTimeout(this.options.onslide, [index, this.slides[index]])\n    },\n\n    setTitle: function (index) {\n      var text = this.slides[index].firstChild.title\n      var titleElement = this.titleElement\n      if (titleElement.length) {\n        this.titleElement.empty()\n        if (text) {\n          titleElement[0].appendChild(document.createTextNode(text))\n        }\n      }\n    },\n\n    setTimeout: function (func, args, wait) {\n      var that = this\n      return func && window.setTimeout(function () {\n        func.apply(that, args || [])\n      }, wait || 0)\n    },\n\n    imageFactory: function (obj, callback) {\n      var that = this\n      var img = this.imagePrototype.cloneNode(false)\n      var url = obj\n      var backgroundSize = this.options.stretchImages\n      var called\n      var element\n      var title\n      function callbackWrapper (event) {\n        if (!called) {\n          event = {\n            type: event.type,\n            target: element\n          }\n          if (!element.parentNode) {\n            // Fix for IE7 firing the load event for\n            // cached images before the element could\n            // be added to the DOM:\n            return that.setTimeout(callbackWrapper, [event])\n          }\n          called = true\n          $(img).off('load error', callbackWrapper)\n          if (backgroundSize) {\n            if (event.type === 'load') {\n              element.style.background = 'url(\"' + url +\n                '\") center no-repeat'\n              element.style.backgroundSize = backgroundSize\n            }\n          }\n          callback(event)\n        }\n      }\n      if (typeof url !== 'string') {\n        url = this.getItemProperty(obj, this.options.urlProperty)\n        title = this.getItemProperty(obj, this.options.titleProperty)\n      }\n      if (backgroundSize === true) {\n        backgroundSize = 'contain'\n      }\n      backgroundSize = this.support.backgroundSize &&\n        this.support.backgroundSize[backgroundSize] && backgroundSize\n      if (backgroundSize) {\n        element = this.elementPrototype.cloneNode(false)\n      } else {\n        element = img\n        img.draggable = false\n      }\n      if (title) {\n        element.title = title\n      }\n      $(img).on('load error', callbackWrapper)\n      img.src = url\n      return element\n    },\n\n    createElement: function (obj, callback) {\n      var type = obj && this.getItemProperty(obj, this.options.typeProperty)\n      var factory = (type && this[type.split('/')[0] + 'Factory']) ||\n        this.imageFactory\n      var element = obj && factory.call(this, obj, callback)\n      var srcset = this.getItemProperty(obj, this.options.srcsetProperty)\n      if (!element) {\n        element = this.elementPrototype.cloneNode(false)\n        this.setTimeout(callback, [{\n          type: 'error',\n          target: element\n        }])\n      }\n      if (srcset) {\n        element.setAttribute('srcset', srcset)\n      }\n      $(element).addClass(this.options.slideContentClass)\n      return element\n    },\n\n    loadElement: function (index) {\n      if (!this.elements[index]) {\n        if (this.slides[index].firstChild) {\n          this.elements[index] = $(this.slides[index])\n            .hasClass(this.options.slideErrorClass) ? 3 : 2\n        } else {\n          this.elements[index] = 1 // Loading\n          $(this.slides[index]).addClass(this.options.slideLoadingClass)\n          this.slides[index].appendChild(this.createElement(\n            this.list[index],\n            this.proxyListener\n          ))\n        }\n      }\n    },\n\n    loadElements: function (index) {\n      var limit = Math.min(this.num, this.options.preloadRange * 2 + 1)\n      var j = index\n      var i\n      for (i = 0; i < limit; i += 1) {\n        // First load the current slide element (0),\n        // then the next one (+1),\n        // then the previous one (-2),\n        // then the next after next (+2), etc.:\n        j += i * (i % 2 === 0 ? -1 : 1)\n        // Connect the ends of the list to load slide elements for\n        // continuous navigation:\n        j = this.circle(j)\n        this.loadElement(j)\n      }\n    },\n\n    unloadElements: function (index) {\n      var i,\n        diff\n      for (i in this.elements) {\n        if (this.elements.hasOwnProperty(i)) {\n          diff = Math.abs(index - i)\n          if (diff > this.options.preloadRange &&\n            diff + this.options.preloadRange < this.num) {\n            this.unloadSlide(i)\n            delete this.elements[i]\n          }\n        }\n      }\n    },\n\n    addSlide: function (index) {\n      var slide = this.slidePrototype.cloneNode(false)\n      slide.setAttribute('data-index', index)\n      this.slidesContainer[0].appendChild(slide)\n      this.slides.push(slide)\n    },\n\n    positionSlide: function (index) {\n      var slide = this.slides[index]\n      slide.style.width = this.slideWidth + 'px'\n      if (this.support.transform) {\n        slide.style.left = (index * -this.slideWidth) + 'px'\n        this.move(\n          index, this.index > index\n            ? -this.slideWidth\n            : (this.index < index ? this.slideWidth : 0),\n          0\n        )\n      }\n    },\n\n    initSlides: function (reload) {\n      var clearSlides,\n        i\n      if (!reload) {\n        this.positions = []\n        this.positions.length = this.num\n        this.elements = {}\n        this.imagePrototype = document.createElement('img')\n        this.elementPrototype = document.createElement('div')\n        this.slidePrototype = document.createElement('div')\n        $(this.slidePrototype).addClass(this.options.slideClass)\n        this.slides = this.slidesContainer[0].children\n        clearSlides = this.options.clearSlides ||\n        this.slides.length !== this.num\n      }\n      this.slideWidth = this.container[0].offsetWidth\n      this.slideHeight = this.container[0].offsetHeight\n      this.slidesContainer[0].style.width =\n        (this.num * this.slideWidth) + 'px'\n      if (clearSlides) {\n        this.resetSlides()\n      }\n      for (i = 0; i < this.num; i += 1) {\n        if (clearSlides) {\n          this.addSlide(i)\n        }\n        this.positionSlide(i)\n      }\n      // Reposition the slides before and after the given index:\n      if (this.options.continuous && this.support.transform) {\n        this.move(this.circle(this.index - 1), -this.slideWidth, 0)\n        this.move(this.circle(this.index + 1), this.slideWidth, 0)\n      }\n      if (!this.support.transform) {\n        this.slidesContainer[0].style.left =\n          (this.index * -this.slideWidth) + 'px'\n      }\n    },\n\n    unloadSlide: function (index) {\n      var slide,\n        firstChild\n      slide = this.slides[index]\n      firstChild = slide.firstChild\n      if (firstChild !== null) {\n        slide.removeChild(firstChild)\n      }\n    },\n\n    unloadAllSlides: function () {\n      var i,\n        len\n      for (i = 0, len = this.slides.length; i < len; i++) {\n        this.unloadSlide(i)\n      }\n    },\n\n    toggleControls: function () {\n      var controlsClass = this.options.controlsClass\n      if (this.container.hasClass(controlsClass)) {\n        this.container.removeClass(controlsClass)\n      } else {\n        this.container.addClass(controlsClass)\n      }\n    },\n\n    toggleSlideshow: function () {\n      if (!this.interval) {\n        this.play()\n      } else {\n        this.pause()\n      }\n    },\n\n    getNodeIndex: function (element) {\n      return parseInt(element.getAttribute('data-index'), 10)\n    },\n\n    getNestedProperty: function (obj, property) {\n      property.replace(\n        // Matches native JavaScript notation in a String,\n        // e.g. '[\"doubleQuoteProp\"].dotProp[2]'\n        // eslint-disable-next-line no-useless-escape\n        /\\[(?:'([^']+)'|\"([^\"]+)\"|(\\d+))\\]|(?:(?:^|\\.)([^\\.\\[]+))/g,\n        function (str, singleQuoteProp, doubleQuoteProp, arrayIndex, dotProp) {\n          var prop = dotProp || singleQuoteProp || doubleQuoteProp ||\n            (arrayIndex && parseInt(arrayIndex, 10))\n          if (str && obj) {\n            obj = obj[prop]\n          }\n        }\n      )\n      return obj\n    },\n\n    getDataProperty: function (obj, property) {\n      if (obj.getAttribute) {\n        var prop = obj.getAttribute('data-' +\n          property.replace(/([A-Z])/g, '-$1').toLowerCase())\n        if (typeof prop === 'string') {\n          // eslint-disable-next-line no-useless-escape\n          if (/^(true|false|null|-?\\d+(\\.\\d+)?|\\{[\\s\\S]*\\}|\\[[\\s\\S]*\\])$/\n              .test(prop)) {\n            try {\n              return $.parseJSON(prop)\n            } catch (ignore) {}\n          }\n          return prop\n        }\n      }\n    },\n\n    getItemProperty: function (obj, property) {\n      var prop = obj[property]\n      if (prop === undefined) {\n        prop = this.getDataProperty(obj, property)\n        if (prop === undefined) {\n          prop = this.getNestedProperty(obj, property)\n        }\n      }\n      return prop\n    },\n\n    initStartIndex: function () {\n      var index = this.options.index\n      var urlProperty = this.options.urlProperty\n      var i\n      // Check if the index is given as a list object:\n      if (index && typeof index !== 'number') {\n        for (i = 0; i < this.num; i += 1) {\n          if (this.list[i] === index ||\n            this.getItemProperty(this.list[i], urlProperty) ===\n            this.getItemProperty(index, urlProperty)) {\n            index = i\n            break\n          }\n        }\n      }\n      // Make sure the index is in the list range:\n      this.index = this.circle(parseInt(index, 10) || 0)\n    },\n\n    initEventListeners: function () {\n      var that = this\n      var slidesContainer = this.slidesContainer\n      function proxyListener (event) {\n        var type = that.support.transition &&\n        that.support.transition.end === event.type\n          ? 'transitionend'\n          : event.type\n        that['on' + type](event)\n      }\n      $(window).on('resize', proxyListener)\n      $(document.body).on('keydown', proxyListener)\n      this.container.on('click', proxyListener)\n      if (this.support.touch) {\n        slidesContainer\n          .on('touchstart touchmove touchend touchcancel', proxyListener)\n      } else if (this.options.emulateTouchEvents &&\n        this.support.transition) {\n        slidesContainer\n          .on('mousedown mousemove mouseup mouseout', proxyListener)\n      }\n      if (this.support.transition) {\n        slidesContainer.on(\n          this.support.transition.end,\n          proxyListener\n        )\n      }\n      this.proxyListener = proxyListener\n    },\n\n    destroyEventListeners: function () {\n      var slidesContainer = this.slidesContainer\n      var proxyListener = this.proxyListener\n      $(window).off('resize', proxyListener)\n      $(document.body).off('keydown', proxyListener)\n      this.container.off('click', proxyListener)\n      if (this.support.touch) {\n        slidesContainer\n          .off('touchstart touchmove touchend touchcancel', proxyListener)\n      } else if (this.options.emulateTouchEvents &&\n        this.support.transition) {\n        slidesContainer\n          .off('mousedown mousemove mouseup mouseout', proxyListener)\n      }\n      if (this.support.transition) {\n        slidesContainer.off(\n          this.support.transition.end,\n          proxyListener\n        )\n      }\n    },\n\n    handleOpen: function () {\n      if (this.options.onopened) {\n        this.options.onopened.call(this)\n      }\n    },\n\n    initWidget: function () {\n      var that = this\n      function openHandler (event) {\n        if (event.target === that.container[0]) {\n          that.container.off(\n            that.support.transition.end,\n            openHandler\n          )\n          that.handleOpen()\n        }\n      }\n      this.container = $(this.options.container)\n      if (!this.container.length) {\n        this.console.log(\n          'blueimp Gallery: Widget container not found.',\n          this.options.container\n        )\n        return false\n      }\n      this.slidesContainer = this.container.find(\n        this.options.slidesContainer\n      ).first()\n      if (!this.slidesContainer.length) {\n        this.console.log(\n          'blueimp Gallery: Slides container not found.',\n          this.options.slidesContainer\n        )\n        return false\n      }\n      this.titleElement = this.container.find(\n        this.options.titleElement\n      ).first()\n      if (this.num === 1) {\n        this.container.addClass(this.options.singleClass)\n      }\n      if (this.options.onopen) {\n        this.options.onopen.call(this)\n      }\n      if (this.support.transition && this.options.displayTransition) {\n        this.container.on(\n          this.support.transition.end,\n          openHandler\n        )\n      } else {\n        this.handleOpen()\n      }\n      if (this.options.hidePageScrollbars) {\n        // Hide the page scrollbars:\n        this.bodyOverflowStyle = document.body.style.overflow\n        document.body.style.overflow = 'hidden'\n      }\n      this.container[0].style.display = 'block'\n      this.initSlides()\n      this.container.addClass(this.options.displayClass)\n    },\n\n    initOptions: function (options) {\n      // Create a copy of the prototype options:\n      this.options = $.extend({}, this.options)\n      // Check if carousel mode is enabled:\n      if ((options && options.carousel) ||\n        (this.options.carousel && (!options || options.carousel !== false))) {\n        $.extend(this.options, this.carouselOptions)\n      }\n      // Override any given options:\n      $.extend(this.options, options)\n      if (this.num < 3) {\n        // 1 or 2 slides cannot be displayed continuous,\n        // remember the original option by setting to null instead of false:\n        this.options.continuous = this.options.continuous ? null : false\n      }\n      if (!this.support.transition) {\n        this.options.emulateTouchEvents = false\n      }\n      if (this.options.event) {\n        this.preventDefault(this.options.event)\n      }\n    }\n\n  })\n\n  return Gallery\n}))\n"
  },
  {
    "path": "app_frontend/static/plugin/Gallery-2.25.0/js/blueimp-helper.js",
    "content": "/*\n * blueimp helper JS\n * https://github.com/blueimp/Gallery\n *\n * Copyright 2013, Sebastian Tschan\n * https://blueimp.net\n *\n * Licensed under the MIT license:\n * https://opensource.org/licenses/MIT\n */\n\n/* global define, window, document */\n\n;(function () {\n  'use strict'\n\n  function extend (obj1, obj2) {\n    var prop\n    for (prop in obj2) {\n      if (obj2.hasOwnProperty(prop)) {\n        obj1[prop] = obj2[prop]\n      }\n    }\n    return obj1\n  }\n\n  function Helper (query) {\n    if (!this || this.find !== Helper.prototype.find) {\n      // Called as function instead of as constructor,\n      // so we simply return a new instance:\n      return new Helper(query)\n    }\n    this.length = 0\n    if (query) {\n      if (typeof query === 'string') {\n        query = this.find(query)\n      }\n      if (query.nodeType || query === query.window) {\n        // Single HTML element\n        this.length = 1\n        this[0] = query\n      } else {\n        // HTML element collection\n        var i = query.length\n        this.length = i\n        while (i) {\n          i -= 1\n          this[i] = query[i]\n        }\n      }\n    }\n  }\n\n  Helper.extend = extend\n\n  Helper.contains = function (container, element) {\n    do {\n      element = element.parentNode\n      if (element === container) {\n        return true\n      }\n    } while (element)\n    return false\n  }\n\n  Helper.parseJSON = function (string) {\n    return window.JSON && JSON.parse(string)\n  }\n\n  extend(Helper.prototype, {\n    find: function (query) {\n      var container = this[0] || document\n      if (typeof query === 'string') {\n        if (container.querySelectorAll) {\n          query = container.querySelectorAll(query)\n        } else if (query.charAt(0) === '#') {\n          query = container.getElementById(query.slice(1))\n        } else {\n          query = container.getElementsByTagName(query)\n        }\n      }\n      return new Helper(query)\n    },\n\n    hasClass: function (className) {\n      if (!this[0]) {\n        return false\n      }\n      return new RegExp('(^|\\\\s+)' + className +\n        '(\\\\s+|$)').test(this[0].className)\n    },\n\n    addClass: function (className) {\n      var i = this.length\n      var element\n      while (i) {\n        i -= 1\n        element = this[i]\n        if (!element.className) {\n          element.className = className\n          return this\n        }\n        if (this.hasClass(className)) {\n          return this\n        }\n        element.className += ' ' + className\n      }\n      return this\n    },\n\n    removeClass: function (className) {\n      var regexp = new RegExp('(^|\\\\s+)' + className + '(\\\\s+|$)')\n      var i = this.length\n      var element\n      while (i) {\n        i -= 1\n        element = this[i]\n        element.className = element.className.replace(regexp, ' ')\n      }\n      return this\n    },\n\n    on: function (eventName, handler) {\n      var eventNames = eventName.split(/\\s+/)\n      var i\n      var element\n      while (eventNames.length) {\n        eventName = eventNames.shift()\n        i = this.length\n        while (i) {\n          i -= 1\n          element = this[i]\n          if (element.addEventListener) {\n            element.addEventListener(eventName, handler, false)\n          } else if (element.attachEvent) {\n            element.attachEvent('on' + eventName, handler)\n          }\n        }\n      }\n      return this\n    },\n\n    off: function (eventName, handler) {\n      var eventNames = eventName.split(/\\s+/)\n      var i\n      var element\n      while (eventNames.length) {\n        eventName = eventNames.shift()\n        i = this.length\n        while (i) {\n          i -= 1\n          element = this[i]\n          if (element.removeEventListener) {\n            element.removeEventListener(eventName, handler, false)\n          } else if (element.detachEvent) {\n            element.detachEvent('on' + eventName, handler)\n          }\n        }\n      }\n      return this\n    },\n\n    empty: function () {\n      var i = this.length\n      var element\n      while (i) {\n        i -= 1\n        element = this[i]\n        while (element.hasChildNodes()) {\n          element.removeChild(element.lastChild)\n        }\n      }\n      return this\n    },\n\n    first: function () {\n      return new Helper(this[0])\n    }\n\n  })\n\n  if (typeof define === 'function' && define.amd) {\n    define(function () {\n      return Helper\n    })\n  } else {\n    window.blueimp = window.blueimp || {}\n    window.blueimp.helper = Helper\n  }\n}())\n"
  },
  {
    "path": "app_frontend/static/plugin/Gallery-2.25.0/js/demo/demo.js",
    "content": "/*\n * blueimp Gallery Demo JS\n * https://github.com/blueimp/Gallery\n *\n * Copyright 2013, Sebastian Tschan\n * https://blueimp.net\n *\n * Licensed under the MIT license:\n * https://opensource.org/licenses/MIT\n */\n\n/* global blueimp, $ */\n\n$(function () {\n  'use strict'\n\n  // Load demo images from flickr:\n  $.ajax({\n    url: 'https://api.flickr.com/services/rest/',\n    data: {\n      format: 'json',\n      method: 'flickr.interestingness.getList',\n      api_key: '7617adae70159d09ba78cfec73c13be3' // jshint ignore:line\n    },\n    dataType: 'jsonp',\n    jsonp: 'jsoncallback'\n  }).done(function (result) {\n    var carouselLinks = []\n    var linksContainer = $('#links')\n    var baseUrl\n    // Add the demo images as links with thumbnails to the page:\n    $.each(result.photos.photo, function (index, photo) {\n      baseUrl = 'https://farm' + photo.farm + '.static.flickr.com/' +\n      photo.server + '/' + photo.id + '_' + photo.secret\n      $('<a/>')\n        .append($('<img>').prop('src', baseUrl + '_s.jpg'))\n        .prop('href', baseUrl + '_b.jpg')\n        .prop('title', photo.title)\n        .attr('data-gallery', '')\n        .appendTo(linksContainer)\n      carouselLinks.push({\n        href: baseUrl + '_c.jpg',\n        title: photo.title\n      })\n    })\n    // Initialize the Gallery as image carousel:\n    blueimp.Gallery(carouselLinks, {\n      container: '#blueimp-image-carousel',\n      carousel: true\n    })\n  })\n\n  // Initialize the Gallery as video carousel:\n  blueimp.Gallery([\n    {\n      title: 'Sintel',\n      href: 'https://archive.org/download/Sintel/' +\n        'sintel-2048-surround.mp4',\n      type: 'video/mp4',\n      poster: 'https://i.imgur.com/MUSw4Zu.jpg'\n    },\n    {\n      title: 'Big Buck Bunny',\n      href: 'https://upload.wikimedia.org/wikipedia/commons/c/c0/' +\n        'Big_Buck_Bunny_4K.webm',\n      type: 'video/webm',\n      poster: 'https://upload.wikimedia.org/wikipedia/commons/thumb/c/c0/' +\n        'Big_Buck_Bunny_4K.webm/4000px--Big_Buck_Bunny_4K.webm.jpg'\n    },\n    {\n      title: 'Elephants Dream',\n      href: 'https://upload.wikimedia.org/wikipedia/commons/8/83/' +\n        'Elephants_Dream_%28high_quality%29.ogv',\n      type: 'video/ogg',\n      poster: 'https://upload.wikimedia.org/wikipedia/commons/thumb/9/90/' +\n        'Elephants_Dream_s1_proog.jpg/800px-Elephants_Dream_s1_proog.jpg'\n    },\n    {\n      title: 'LES TWINS - An Industry Ahead',\n      type: 'text/html',\n      youtube: 'zi4CIXpx7Bg'\n    },\n    {\n      title: 'KN1GHT - Last Moon',\n      type: 'text/html',\n      vimeo: '73686146',\n      poster: 'https://secure-a.vimeocdn.com/ts/448/835/448835699_960.jpg'\n    }\n  ], {\n    container: '#blueimp-video-carousel',\n    carousel: true\n  })\n})\n"
  },
  {
    "path": "app_frontend/static/plugin/Gallery-2.25.0/js/jquery.blueimp-gallery.js",
    "content": "/*\n * blueimp Gallery jQuery plugin\n * https://github.com/blueimp/Gallery\n *\n * Copyright 2013, Sebastian Tschan\n * https://blueimp.net\n *\n * Licensed under the MIT license:\n * https://opensource.org/licenses/MIT\n */\n\n/* global define, window, document */\n\n;(function (factory) {\n  'use strict'\n  if (typeof define === 'function' && define.amd) {\n    define([\n      'jquery',\n      './blueimp-gallery'\n    ], factory)\n  } else {\n    factory(\n      window.jQuery,\n      window.blueimp.Gallery\n    )\n  }\n}(function ($, Gallery) {\n  'use strict'\n\n  // Global click handler to open links with data-gallery attribute\n  // in the Gallery lightbox:\n  $(document).on('click', '[data-gallery]', function (event) {\n    // Get the container id from the data-gallery attribute:\n    var id = $(this).data('gallery')\n    var widget = $(id)\n    var container = (widget.length && widget) ||\n          $(Gallery.prototype.options.container)\n    var callbacks = {\n      onopen: function () {\n        container\n          .data('gallery', this)\n          .trigger('open')\n      },\n      onopened: function () {\n        container.trigger('opened')\n      },\n      onslide: function () {\n        container.trigger('slide', arguments)\n      },\n      onslideend: function () {\n        container.trigger('slideend', arguments)\n      },\n      onslidecomplete: function () {\n        container.trigger('slidecomplete', arguments)\n      },\n      onclose: function () {\n        container.trigger('close')\n      },\n      onclosed: function () {\n        container\n          .trigger('closed')\n          .removeData('gallery')\n      }\n    }\n    var options = $.extend(\n      // Retrieve custom options from data-attributes\n      // on the Gallery widget:\n      container.data(),\n      {\n        container: container[0],\n        index: this,\n        event: event\n      },\n      callbacks\n    )\n    // Select all links with the same data-gallery attribute:\n    var links = $('[data-gallery=\"' + id + '\"]')\n    if (options.filter) {\n      links = links.filter(options.filter)\n    }\n    return new Gallery(links, options)\n  })\n}))\n"
  },
  {
    "path": "app_frontend/static/plugin/Gallery-2.25.0/js/vendor/jquery.js",
    "content": "/*!\n * jQuery JavaScript Library v1.11.3\n * http://jquery.com/\n *\n * Includes Sizzle.js\n * http://sizzlejs.com/\n *\n * Copyright 2005, 2014 jQuery Foundation, Inc. and other contributors\n * Released under the MIT license\n * http://jquery.org/license\n *\n * Date: 2015-04-28T16:19Z\n */\n\n(function( global, factory ) {\n\n\tif ( typeof module === \"object\" && typeof module.exports === \"object\" ) {\n\t\t// For CommonJS and CommonJS-like environments where a proper window is present,\n\t\t// execute the factory and get jQuery\n\t\t// For environments that do not inherently posses a window with a document\n\t\t// (such as Node.js), expose a jQuery-making factory as module.exports\n\t\t// This accentuates the need for the creation of a real window\n\t\t// e.g. var jQuery = require(\"jquery\")(window);\n\t\t// See ticket #14549 for more info\n\t\tmodule.exports = global.document ?\n\t\t\tfactory( global, true ) :\n\t\t\tfunction( w ) {\n\t\t\t\tif ( !w.document ) {\n\t\t\t\t\tthrow new Error( \"jQuery requires a window with a document\" );\n\t\t\t\t}\n\t\t\t\treturn factory( w );\n\t\t\t};\n\t} else {\n\t\tfactory( global );\n\t}\n\n// Pass this if window is not defined yet\n}(typeof window !== \"undefined\" ? window : this, function( window, noGlobal ) {\n\n// Can't do this because several apps including ASP.NET trace\n// the stack via arguments.caller.callee and Firefox dies if\n// you try to trace through \"use strict\" call chains. (#13335)\n// Support: Firefox 18+\n//\n\nvar deletedIds = [];\n\nvar slice = deletedIds.slice;\n\nvar concat = deletedIds.concat;\n\nvar push = deletedIds.push;\n\nvar indexOf = deletedIds.indexOf;\n\nvar class2type = {};\n\nvar toString = class2type.toString;\n\nvar hasOwn = class2type.hasOwnProperty;\n\nvar support = {};\n\n\n\nvar\n\tversion = \"1.11.3\",\n\n\t// Define a local copy of jQuery\n\tjQuery = function( selector, context ) {\n\t\t// The jQuery object is actually just the init constructor 'enhanced'\n\t\t// Need init if jQuery is called (just allow error to be thrown if not included)\n\t\treturn new jQuery.fn.init( selector, context );\n\t},\n\n\t// Support: Android<4.1, IE<9\n\t// Make sure we trim BOM and NBSP\n\trtrim = /^[\\s\\uFEFF\\xA0]+|[\\s\\uFEFF\\xA0]+$/g,\n\n\t// Matches dashed string for camelizing\n\trmsPrefix = /^-ms-/,\n\trdashAlpha = /-([\\da-z])/gi,\n\n\t// Used by jQuery.camelCase as callback to replace()\n\tfcamelCase = function( all, letter ) {\n\t\treturn letter.toUpperCase();\n\t};\n\njQuery.fn = jQuery.prototype = {\n\t// The current version of jQuery being used\n\tjquery: version,\n\n\tconstructor: jQuery,\n\n\t// Start with an empty selector\n\tselector: \"\",\n\n\t// The default length of a jQuery object is 0\n\tlength: 0,\n\n\ttoArray: function() {\n\t\treturn slice.call( this );\n\t},\n\n\t// Get the Nth element in the matched element set OR\n\t// Get the whole matched element set as a clean array\n\tget: function( num ) {\n\t\treturn num != null ?\n\n\t\t\t// Return just the one element from the set\n\t\t\t( num < 0 ? this[ num + this.length ] : this[ num ] ) :\n\n\t\t\t// Return all the elements in a clean array\n\t\t\tslice.call( this );\n\t},\n\n\t// Take an array of elements and push it onto the stack\n\t// (returning the new matched element set)\n\tpushStack: function( elems ) {\n\n\t\t// Build a new jQuery matched element set\n\t\tvar ret = jQuery.merge( this.constructor(), elems );\n\n\t\t// Add the old object onto the stack (as a reference)\n\t\tret.prevObject = this;\n\t\tret.context = this.context;\n\n\t\t// Return the newly-formed element set\n\t\treturn ret;\n\t},\n\n\t// Execute a callback for every element in the matched set.\n\t// (You can seed the arguments with an array of args, but this is\n\t// only used internally.)\n\teach: function( callback, args ) {\n\t\treturn jQuery.each( this, callback, args );\n\t},\n\n\tmap: function( callback ) {\n\t\treturn this.pushStack( jQuery.map(this, function( elem, i ) {\n\t\t\treturn callback.call( elem, i, elem );\n\t\t}));\n\t},\n\n\tslice: function() {\n\t\treturn this.pushStack( slice.apply( this, arguments ) );\n\t},\n\n\tfirst: function() {\n\t\treturn this.eq( 0 );\n\t},\n\n\tlast: function() {\n\t\treturn this.eq( -1 );\n\t},\n\n\teq: function( i ) {\n\t\tvar len = this.length,\n\t\t\tj = +i + ( i < 0 ? len : 0 );\n\t\treturn this.pushStack( j >= 0 && j < len ? [ this[j] ] : [] );\n\t},\n\n\tend: function() {\n\t\treturn this.prevObject || this.constructor(null);\n\t},\n\n\t// For internal use only.\n\t// Behaves like an Array's method, not like a jQuery method.\n\tpush: push,\n\tsort: deletedIds.sort,\n\tsplice: deletedIds.splice\n};\n\njQuery.extend = jQuery.fn.extend = function() {\n\tvar src, copyIsArray, copy, name, options, clone,\n\t\ttarget = arguments[0] || {},\n\t\ti = 1,\n\t\tlength = arguments.length,\n\t\tdeep = false;\n\n\t// Handle a deep copy situation\n\tif ( typeof target === \"boolean\" ) {\n\t\tdeep = target;\n\n\t\t// skip the boolean and the target\n\t\ttarget = arguments[ i ] || {};\n\t\ti++;\n\t}\n\n\t// Handle case when target is a string or something (possible in deep copy)\n\tif ( typeof target !== \"object\" && !jQuery.isFunction(target) ) {\n\t\ttarget = {};\n\t}\n\n\t// extend jQuery itself if only one argument is passed\n\tif ( i === length ) {\n\t\ttarget = this;\n\t\ti--;\n\t}\n\n\tfor ( ; i < length; i++ ) {\n\t\t// Only deal with non-null/undefined values\n\t\tif ( (options = arguments[ i ]) != null ) {\n\t\t\t// Extend the base object\n\t\t\tfor ( name in options ) {\n\t\t\t\tsrc = target[ name ];\n\t\t\t\tcopy = options[ name ];\n\n\t\t\t\t// Prevent never-ending loop\n\t\t\t\tif ( target === copy ) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\t// Recurse if we're merging plain objects or arrays\n\t\t\t\tif ( deep && copy && ( jQuery.isPlainObject(copy) || (copyIsArray = jQuery.isArray(copy)) ) ) {\n\t\t\t\t\tif ( copyIsArray ) {\n\t\t\t\t\t\tcopyIsArray = false;\n\t\t\t\t\t\tclone = src && jQuery.isArray(src) ? src : [];\n\n\t\t\t\t\t} else {\n\t\t\t\t\t\tclone = src && jQuery.isPlainObject(src) ? src : {};\n\t\t\t\t\t}\n\n\t\t\t\t\t// Never move original objects, clone them\n\t\t\t\t\ttarget[ name ] = jQuery.extend( deep, clone, copy );\n\n\t\t\t\t// Don't bring in undefined values\n\t\t\t\t} else if ( copy !== undefined ) {\n\t\t\t\t\ttarget[ name ] = copy;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t// Return the modified object\n\treturn target;\n};\n\njQuery.extend({\n\t// Unique for each copy of jQuery on the page\n\texpando: \"jQuery\" + ( version + Math.random() ).replace( /\\D/g, \"\" ),\n\n\t// Assume jQuery is ready without the ready module\n\tisReady: true,\n\n\terror: function( msg ) {\n\t\tthrow new Error( msg );\n\t},\n\n\tnoop: function() {},\n\n\t// See test/unit/core.js for details concerning isFunction.\n\t// Since version 1.3, DOM methods and functions like alert\n\t// aren't supported. They return false on IE (#2968).\n\tisFunction: function( obj ) {\n\t\treturn jQuery.type(obj) === \"function\";\n\t},\n\n\tisArray: Array.isArray || function( obj ) {\n\t\treturn jQuery.type(obj) === \"array\";\n\t},\n\n\tisWindow: function( obj ) {\n\t\t/* jshint eqeqeq: false */\n\t\treturn obj != null && obj == obj.window;\n\t},\n\n\tisNumeric: function( obj ) {\n\t\t// parseFloat NaNs numeric-cast false positives (null|true|false|\"\")\n\t\t// ...but misinterprets leading-number strings, particularly hex literals (\"0x...\")\n\t\t// subtraction forces infinities to NaN\n\t\t// adding 1 corrects loss of precision from parseFloat (#15100)\n\t\treturn !jQuery.isArray( obj ) && (obj - parseFloat( obj ) + 1) >= 0;\n\t},\n\n\tisEmptyObject: function( obj ) {\n\t\tvar name;\n\t\tfor ( name in obj ) {\n\t\t\treturn false;\n\t\t}\n\t\treturn true;\n\t},\n\n\tisPlainObject: function( obj ) {\n\t\tvar key;\n\n\t\t// Must be an Object.\n\t\t// Because of IE, we also have to check the presence of the constructor property.\n\t\t// Make sure that DOM nodes and window objects don't pass through, as well\n\t\tif ( !obj || jQuery.type(obj) !== \"object\" || obj.nodeType || jQuery.isWindow( obj ) ) {\n\t\t\treturn false;\n\t\t}\n\n\t\ttry {\n\t\t\t// Not own constructor property must be Object\n\t\t\tif ( obj.constructor &&\n\t\t\t\t!hasOwn.call(obj, \"constructor\") &&\n\t\t\t\t!hasOwn.call(obj.constructor.prototype, \"isPrototypeOf\") ) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t} catch ( e ) {\n\t\t\t// IE8,9 Will throw exceptions on certain host objects #9897\n\t\t\treturn false;\n\t\t}\n\n\t\t// Support: IE<9\n\t\t// Handle iteration over inherited properties before own properties.\n\t\tif ( support.ownLast ) {\n\t\t\tfor ( key in obj ) {\n\t\t\t\treturn hasOwn.call( obj, key );\n\t\t\t}\n\t\t}\n\n\t\t// Own properties are enumerated firstly, so to speed up,\n\t\t// if last one is own, then all properties are own.\n\t\tfor ( key in obj ) {}\n\n\t\treturn key === undefined || hasOwn.call( obj, key );\n\t},\n\n\ttype: function( obj ) {\n\t\tif ( obj == null ) {\n\t\t\treturn obj + \"\";\n\t\t}\n\t\treturn typeof obj === \"object\" || typeof obj === \"function\" ?\n\t\t\tclass2type[ toString.call(obj) ] || \"object\" :\n\t\t\ttypeof obj;\n\t},\n\n\t// Evaluates a script in a global context\n\t// Workarounds based on findings by Jim Driscoll\n\t// http://weblogs.java.net/blog/driscoll/archive/2009/09/08/eval-javascript-global-context\n\tglobalEval: function( data ) {\n\t\tif ( data && jQuery.trim( data ) ) {\n\t\t\t// We use execScript on Internet Explorer\n\t\t\t// We use an anonymous function so that context is window\n\t\t\t// rather than jQuery in Firefox\n\t\t\t( window.execScript || function( data ) {\n\t\t\t\twindow[ \"eval\" ].call( window, data );\n\t\t\t} )( data );\n\t\t}\n\t},\n\n\t// Convert dashed to camelCase; used by the css and data modules\n\t// Microsoft forgot to hump their vendor prefix (#9572)\n\tcamelCase: function( string ) {\n\t\treturn string.replace( rmsPrefix, \"ms-\" ).replace( rdashAlpha, fcamelCase );\n\t},\n\n\tnodeName: function( elem, name ) {\n\t\treturn elem.nodeName && elem.nodeName.toLowerCase() === name.toLowerCase();\n\t},\n\n\t// args is for internal usage only\n\teach: function( obj, callback, args ) {\n\t\tvar value,\n\t\t\ti = 0,\n\t\t\tlength = obj.length,\n\t\t\tisArray = isArraylike( obj );\n\n\t\tif ( args ) {\n\t\t\tif ( isArray ) {\n\t\t\t\tfor ( ; i < length; i++ ) {\n\t\t\t\t\tvalue = callback.apply( obj[ i ], args );\n\n\t\t\t\t\tif ( value === false ) {\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tfor ( i in obj ) {\n\t\t\t\t\tvalue = callback.apply( obj[ i ], args );\n\n\t\t\t\t\tif ( value === false ) {\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t// A special, fast, case for the most common use of each\n\t\t} else {\n\t\t\tif ( isArray ) {\n\t\t\t\tfor ( ; i < length; i++ ) {\n\t\t\t\t\tvalue = callback.call( obj[ i ], i, obj[ i ] );\n\n\t\t\t\t\tif ( value === false ) {\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tfor ( i in obj ) {\n\t\t\t\t\tvalue = callback.call( obj[ i ], i, obj[ i ] );\n\n\t\t\t\t\tif ( value === false ) {\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn obj;\n\t},\n\n\t// Support: Android<4.1, IE<9\n\ttrim: function( text ) {\n\t\treturn text == null ?\n\t\t\t\"\" :\n\t\t\t( text + \"\" ).replace( rtrim, \"\" );\n\t},\n\n\t// results is for internal usage only\n\tmakeArray: function( arr, results ) {\n\t\tvar ret = results || [];\n\n\t\tif ( arr != null ) {\n\t\t\tif ( isArraylike( Object(arr) ) ) {\n\t\t\t\tjQuery.merge( ret,\n\t\t\t\t\ttypeof arr === \"string\" ?\n\t\t\t\t\t[ arr ] : arr\n\t\t\t\t);\n\t\t\t} else {\n\t\t\t\tpush.call( ret, arr );\n\t\t\t}\n\t\t}\n\n\t\treturn ret;\n\t},\n\n\tinArray: function( elem, arr, i ) {\n\t\tvar len;\n\n\t\tif ( arr ) {\n\t\t\tif ( indexOf ) {\n\t\t\t\treturn indexOf.call( arr, elem, i );\n\t\t\t}\n\n\t\t\tlen = arr.length;\n\t\t\ti = i ? i < 0 ? Math.max( 0, len + i ) : i : 0;\n\n\t\t\tfor ( ; i < len; i++ ) {\n\t\t\t\t// Skip accessing in sparse arrays\n\t\t\t\tif ( i in arr && arr[ i ] === elem ) {\n\t\t\t\t\treturn i;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn -1;\n\t},\n\n\tmerge: function( first, second ) {\n\t\tvar len = +second.length,\n\t\t\tj = 0,\n\t\t\ti = first.length;\n\n\t\twhile ( j < len ) {\n\t\t\tfirst[ i++ ] = second[ j++ ];\n\t\t}\n\n\t\t// Support: IE<9\n\t\t// Workaround casting of .length to NaN on otherwise arraylike objects (e.g., NodeLists)\n\t\tif ( len !== len ) {\n\t\t\twhile ( second[j] !== undefined ) {\n\t\t\t\tfirst[ i++ ] = second[ j++ ];\n\t\t\t}\n\t\t}\n\n\t\tfirst.length = i;\n\n\t\treturn first;\n\t},\n\n\tgrep: function( elems, callback, invert ) {\n\t\tvar callbackInverse,\n\t\t\tmatches = [],\n\t\t\ti = 0,\n\t\t\tlength = elems.length,\n\t\t\tcallbackExpect = !invert;\n\n\t\t// Go through the array, only saving the items\n\t\t// that pass the validator function\n\t\tfor ( ; i < length; i++ ) {\n\t\t\tcallbackInverse = !callback( elems[ i ], i );\n\t\t\tif ( callbackInverse !== callbackExpect ) {\n\t\t\t\tmatches.push( elems[ i ] );\n\t\t\t}\n\t\t}\n\n\t\treturn matches;\n\t},\n\n\t// arg is for internal usage only\n\tmap: function( elems, callback, arg ) {\n\t\tvar value,\n\t\t\ti = 0,\n\t\t\tlength = elems.length,\n\t\t\tisArray = isArraylike( elems ),\n\t\t\tret = [];\n\n\t\t// Go through the array, translating each of the items to their new values\n\t\tif ( isArray ) {\n\t\t\tfor ( ; i < length; i++ ) {\n\t\t\t\tvalue = callback( elems[ i ], i, arg );\n\n\t\t\t\tif ( value != null ) {\n\t\t\t\t\tret.push( value );\n\t\t\t\t}\n\t\t\t}\n\n\t\t// Go through every key on the object,\n\t\t} else {\n\t\t\tfor ( i in elems ) {\n\t\t\t\tvalue = callback( elems[ i ], i, arg );\n\n\t\t\t\tif ( value != null ) {\n\t\t\t\t\tret.push( value );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Flatten any nested arrays\n\t\treturn concat.apply( [], ret );\n\t},\n\n\t// A global GUID counter for objects\n\tguid: 1,\n\n\t// Bind a function to a context, optionally partially applying any\n\t// arguments.\n\tproxy: function( fn, context ) {\n\t\tvar args, proxy, tmp;\n\n\t\tif ( typeof context === \"string\" ) {\n\t\t\ttmp = fn[ context ];\n\t\t\tcontext = fn;\n\t\t\tfn = tmp;\n\t\t}\n\n\t\t// Quick check to determine if target is callable, in the spec\n\t\t// this throws a TypeError, but we will just return undefined.\n\t\tif ( !jQuery.isFunction( fn ) ) {\n\t\t\treturn undefined;\n\t\t}\n\n\t\t// Simulated bind\n\t\targs = slice.call( arguments, 2 );\n\t\tproxy = function() {\n\t\t\treturn fn.apply( context || this, args.concat( slice.call( arguments ) ) );\n\t\t};\n\n\t\t// Set the guid of unique handler to the same of original handler, so it can be removed\n\t\tproxy.guid = fn.guid = fn.guid || jQuery.guid++;\n\n\t\treturn proxy;\n\t},\n\n\tnow: function() {\n\t\treturn +( new Date() );\n\t},\n\n\t// jQuery.support is not used in Core but other projects attach their\n\t// properties to it so it needs to exist.\n\tsupport: support\n});\n\n// Populate the class2type map\njQuery.each(\"Boolean Number String Function Array Date RegExp Object Error\".split(\" \"), function(i, name) {\n\tclass2type[ \"[object \" + name + \"]\" ] = name.toLowerCase();\n});\n\nfunction isArraylike( obj ) {\n\n\t// Support: iOS 8.2 (not reproducible in simulator)\n\t// `in` check used to prevent JIT error (gh-2145)\n\t// hasOwn isn't used here due to false negatives\n\t// regarding Nodelist length in IE\n\tvar length = \"length\" in obj && obj.length,\n\t\ttype = jQuery.type( obj );\n\n\tif ( type === \"function\" || jQuery.isWindow( obj ) ) {\n\t\treturn false;\n\t}\n\n\tif ( obj.nodeType === 1 && length ) {\n\t\treturn true;\n\t}\n\n\treturn type === \"array\" || length === 0 ||\n\t\ttypeof length === \"number\" && length > 0 && ( length - 1 ) in obj;\n}\nvar Sizzle =\n/*!\n * Sizzle CSS Selector Engine v2.2.0-pre\n * http://sizzlejs.com/\n *\n * Copyright 2008, 2014 jQuery Foundation, Inc. and other contributors\n * Released under the MIT license\n * http://jquery.org/license\n *\n * Date: 2014-12-16\n */\n(function( window ) {\n\nvar i,\n\tsupport,\n\tExpr,\n\tgetText,\n\tisXML,\n\ttokenize,\n\tcompile,\n\tselect,\n\toutermostContext,\n\tsortInput,\n\thasDuplicate,\n\n\t// Local document vars\n\tsetDocument,\n\tdocument,\n\tdocElem,\n\tdocumentIsHTML,\n\trbuggyQSA,\n\trbuggyMatches,\n\tmatches,\n\tcontains,\n\n\t// Instance-specific data\n\texpando = \"sizzle\" + 1 * new Date(),\n\tpreferredDoc = window.document,\n\tdirruns = 0,\n\tdone = 0,\n\tclassCache = createCache(),\n\ttokenCache = createCache(),\n\tcompilerCache = createCache(),\n\tsortOrder = function( a, b ) {\n\t\tif ( a === b ) {\n\t\t\thasDuplicate = true;\n\t\t}\n\t\treturn 0;\n\t},\n\n\t// General-purpose constants\n\tMAX_NEGATIVE = 1 << 31,\n\n\t// Instance methods\n\thasOwn = ({}).hasOwnProperty,\n\tarr = [],\n\tpop = arr.pop,\n\tpush_native = arr.push,\n\tpush = arr.push,\n\tslice = arr.slice,\n\t// Use a stripped-down indexOf as it's faster than native\n\t// http://jsperf.com/thor-indexof-vs-for/5\n\tindexOf = function( list, elem ) {\n\t\tvar i = 0,\n\t\t\tlen = list.length;\n\t\tfor ( ; i < len; i++ ) {\n\t\t\tif ( list[i] === elem ) {\n\t\t\t\treturn i;\n\t\t\t}\n\t\t}\n\t\treturn -1;\n\t},\n\n\tbooleans = \"checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped\",\n\n\t// Regular expressions\n\n\t// Whitespace characters http://www.w3.org/TR/css3-selectors/#whitespace\n\twhitespace = \"[\\\\x20\\\\t\\\\r\\\\n\\\\f]\",\n\t// http://www.w3.org/TR/css3-syntax/#characters\n\tcharacterEncoding = \"(?:\\\\\\\\.|[\\\\w-]|[^\\\\x00-\\\\xa0])+\",\n\n\t// Loosely modeled on CSS identifier characters\n\t// An unquoted value should be a CSS identifier http://www.w3.org/TR/css3-selectors/#attribute-selectors\n\t// Proper syntax: http://www.w3.org/TR/CSS21/syndata.html#value-def-identifier\n\tidentifier = characterEncoding.replace( \"w\", \"w#\" ),\n\n\t// Attribute selectors: http://www.w3.org/TR/selectors/#attribute-selectors\n\tattributes = \"\\\\[\" + whitespace + \"*(\" + characterEncoding + \")(?:\" + whitespace +\n\t\t// Operator (capture 2)\n\t\t\"*([*^$|!~]?=)\" + whitespace +\n\t\t// \"Attribute values must be CSS identifiers [capture 5] or strings [capture 3 or capture 4]\"\n\t\t\"*(?:'((?:\\\\\\\\.|[^\\\\\\\\'])*)'|\\\"((?:\\\\\\\\.|[^\\\\\\\\\\\"])*)\\\"|(\" + identifier + \"))|)\" + whitespace +\n\t\t\"*\\\\]\",\n\n\tpseudos = \":(\" + characterEncoding + \")(?:\\\\((\" +\n\t\t// To reduce the number of selectors needing tokenize in the preFilter, prefer arguments:\n\t\t// 1. quoted (capture 3; capture 4 or capture 5)\n\t\t\"('((?:\\\\\\\\.|[^\\\\\\\\'])*)'|\\\"((?:\\\\\\\\.|[^\\\\\\\\\\\"])*)\\\")|\" +\n\t\t// 2. simple (capture 6)\n\t\t\"((?:\\\\\\\\.|[^\\\\\\\\()[\\\\]]|\" + attributes + \")*)|\" +\n\t\t// 3. anything else (capture 2)\n\t\t\".*\" +\n\t\t\")\\\\)|)\",\n\n\t// Leading and non-escaped trailing whitespace, capturing some non-whitespace characters preceding the latter\n\trwhitespace = new RegExp( whitespace + \"+\", \"g\" ),\n\trtrim = new RegExp( \"^\" + whitespace + \"+|((?:^|[^\\\\\\\\])(?:\\\\\\\\.)*)\" + whitespace + \"+$\", \"g\" ),\n\n\trcomma = new RegExp( \"^\" + whitespace + \"*,\" + whitespace + \"*\" ),\n\trcombinators = new RegExp( \"^\" + whitespace + \"*([>+~]|\" + whitespace + \")\" + whitespace + \"*\" ),\n\n\trattributeQuotes = new RegExp( \"=\" + whitespace + \"*([^\\\\]'\\\"]*?)\" + whitespace + \"*\\\\]\", \"g\" ),\n\n\trpseudo = new RegExp( pseudos ),\n\tridentifier = new RegExp( \"^\" + identifier + \"$\" ),\n\n\tmatchExpr = {\n\t\t\"ID\": new RegExp( \"^#(\" + characterEncoding + \")\" ),\n\t\t\"CLASS\": new RegExp( \"^\\\\.(\" + characterEncoding + \")\" ),\n\t\t\"TAG\": new RegExp( \"^(\" + characterEncoding.replace( \"w\", \"w*\" ) + \")\" ),\n\t\t\"ATTR\": new RegExp( \"^\" + attributes ),\n\t\t\"PSEUDO\": new RegExp( \"^\" + pseudos ),\n\t\t\"CHILD\": new RegExp( \"^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\\\(\" + whitespace +\n\t\t\t\"*(even|odd|(([+-]|)(\\\\d*)n|)\" + whitespace + \"*(?:([+-]|)\" + whitespace +\n\t\t\t\"*(\\\\d+)|))\" + whitespace + \"*\\\\)|)\", \"i\" ),\n\t\t\"bool\": new RegExp( \"^(?:\" + booleans + \")$\", \"i\" ),\n\t\t// For use in libraries implementing .is()\n\t\t// We use this for POS matching in `select`\n\t\t\"needsContext\": new RegExp( \"^\" + whitespace + \"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\\\(\" +\n\t\t\twhitespace + \"*((?:-\\\\d)?\\\\d*)\" + whitespace + \"*\\\\)|)(?=[^-]|$)\", \"i\" )\n\t},\n\n\trinputs = /^(?:input|select|textarea|button)$/i,\n\trheader = /^h\\d$/i,\n\n\trnative = /^[^{]+\\{\\s*\\[native \\w/,\n\n\t// Easily-parseable/retrievable ID or TAG or CLASS selectors\n\trquickExpr = /^(?:#([\\w-]+)|(\\w+)|\\.([\\w-]+))$/,\n\n\trsibling = /[+~]/,\n\trescape = /'|\\\\/g,\n\n\t// CSS escapes http://www.w3.org/TR/CSS21/syndata.html#escaped-characters\n\trunescape = new RegExp( \"\\\\\\\\([\\\\da-f]{1,6}\" + whitespace + \"?|(\" + whitespace + \")|.)\", \"ig\" ),\n\tfunescape = function( _, escaped, escapedWhitespace ) {\n\t\tvar high = \"0x\" + escaped - 0x10000;\n\t\t// NaN means non-codepoint\n\t\t// Support: Firefox<24\n\t\t// Workaround erroneous numeric interpretation of +\"0x\"\n\t\treturn high !== high || escapedWhitespace ?\n\t\t\tescaped :\n\t\t\thigh < 0 ?\n\t\t\t\t// BMP codepoint\n\t\t\t\tString.fromCharCode( high + 0x10000 ) :\n\t\t\t\t// Supplemental Plane codepoint (surrogate pair)\n\t\t\t\tString.fromCharCode( high >> 10 | 0xD800, high & 0x3FF | 0xDC00 );\n\t},\n\n\t// Used for iframes\n\t// See setDocument()\n\t// Removing the function wrapper causes a \"Permission Denied\"\n\t// error in IE\n\tunloadHandler = function() {\n\t\tsetDocument();\n\t};\n\n// Optimize for push.apply( _, NodeList )\ntry {\n\tpush.apply(\n\t\t(arr = slice.call( preferredDoc.childNodes )),\n\t\tpreferredDoc.childNodes\n\t);\n\t// Support: Android<4.0\n\t// Detect silently failing push.apply\n\tarr[ preferredDoc.childNodes.length ].nodeType;\n} catch ( e ) {\n\tpush = { apply: arr.length ?\n\n\t\t// Leverage slice if possible\n\t\tfunction( target, els ) {\n\t\t\tpush_native.apply( target, slice.call(els) );\n\t\t} :\n\n\t\t// Support: IE<9\n\t\t// Otherwise append directly\n\t\tfunction( target, els ) {\n\t\t\tvar j = target.length,\n\t\t\t\ti = 0;\n\t\t\t// Can't trust NodeList.length\n\t\t\twhile ( (target[j++] = els[i++]) ) {}\n\t\t\ttarget.length = j - 1;\n\t\t}\n\t};\n}\n\nfunction Sizzle( selector, context, results, seed ) {\n\tvar match, elem, m, nodeType,\n\t\t// QSA vars\n\t\ti, groups, old, nid, newContext, newSelector;\n\n\tif ( ( context ? context.ownerDocument || context : preferredDoc ) !== document ) {\n\t\tsetDocument( context );\n\t}\n\n\tcontext = context || document;\n\tresults = results || [];\n\tnodeType = context.nodeType;\n\n\tif ( typeof selector !== \"string\" || !selector ||\n\t\tnodeType !== 1 && nodeType !== 9 && nodeType !== 11 ) {\n\n\t\treturn results;\n\t}\n\n\tif ( !seed && documentIsHTML ) {\n\n\t\t// Try to shortcut find operations when possible (e.g., not under DocumentFragment)\n\t\tif ( nodeType !== 11 && (match = rquickExpr.exec( selector )) ) {\n\t\t\t// Speed-up: Sizzle(\"#ID\")\n\t\t\tif ( (m = match[1]) ) {\n\t\t\t\tif ( nodeType === 9 ) {\n\t\t\t\t\telem = context.getElementById( m );\n\t\t\t\t\t// Check parentNode to catch when Blackberry 4.6 returns\n\t\t\t\t\t// nodes that are no longer in the document (jQuery #6963)\n\t\t\t\t\tif ( elem && elem.parentNode ) {\n\t\t\t\t\t\t// Handle the case where IE, Opera, and Webkit return items\n\t\t\t\t\t\t// by name instead of ID\n\t\t\t\t\t\tif ( elem.id === m ) {\n\t\t\t\t\t\t\tresults.push( elem );\n\t\t\t\t\t\t\treturn results;\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\treturn results;\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\t// Context is not a document\n\t\t\t\t\tif ( context.ownerDocument && (elem = context.ownerDocument.getElementById( m )) &&\n\t\t\t\t\t\tcontains( context, elem ) && elem.id === m ) {\n\t\t\t\t\t\tresults.push( elem );\n\t\t\t\t\t\treturn results;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t// Speed-up: Sizzle(\"TAG\")\n\t\t\t} else if ( match[2] ) {\n\t\t\t\tpush.apply( results, context.getElementsByTagName( selector ) );\n\t\t\t\treturn results;\n\n\t\t\t// Speed-up: Sizzle(\".CLASS\")\n\t\t\t} else if ( (m = match[3]) && support.getElementsByClassName ) {\n\t\t\t\tpush.apply( results, context.getElementsByClassName( m ) );\n\t\t\t\treturn results;\n\t\t\t}\n\t\t}\n\n\t\t// QSA path\n\t\tif ( support.qsa && (!rbuggyQSA || !rbuggyQSA.test( selector )) ) {\n\t\t\tnid = old = expando;\n\t\t\tnewContext = context;\n\t\t\tnewSelector = nodeType !== 1 && selector;\n\n\t\t\t// qSA works strangely on Element-rooted queries\n\t\t\t// We can work around this by specifying an extra ID on the root\n\t\t\t// and working up from there (Thanks to Andrew Dupont for the technique)\n\t\t\t// IE 8 doesn't work on object elements\n\t\t\tif ( nodeType === 1 && context.nodeName.toLowerCase() !== \"object\" ) {\n\t\t\t\tgroups = tokenize( selector );\n\n\t\t\t\tif ( (old = context.getAttribute(\"id\")) ) {\n\t\t\t\t\tnid = old.replace( rescape, \"\\\\$&\" );\n\t\t\t\t} else {\n\t\t\t\t\tcontext.setAttribute( \"id\", nid );\n\t\t\t\t}\n\t\t\t\tnid = \"[id='\" + nid + \"'] \";\n\n\t\t\t\ti = groups.length;\n\t\t\t\twhile ( i-- ) {\n\t\t\t\t\tgroups[i] = nid + toSelector( groups[i] );\n\t\t\t\t}\n\t\t\t\tnewContext = rsibling.test( selector ) && testContext( context.parentNode ) || context;\n\t\t\t\tnewSelector = groups.join(\",\");\n\t\t\t}\n\n\t\t\tif ( newSelector ) {\n\t\t\t\ttry {\n\t\t\t\t\tpush.apply( results,\n\t\t\t\t\t\tnewContext.querySelectorAll( newSelector )\n\t\t\t\t\t);\n\t\t\t\t\treturn results;\n\t\t\t\t} catch(qsaError) {\n\t\t\t\t} finally {\n\t\t\t\t\tif ( !old ) {\n\t\t\t\t\t\tcontext.removeAttribute(\"id\");\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t// All others\n\treturn select( selector.replace( rtrim, \"$1\" ), context, results, seed );\n}\n\n/**\n * Create key-value caches of limited size\n * @returns {Function(string, Object)} Returns the Object data after storing it on itself with\n *\tproperty name the (space-suffixed) string and (if the cache is larger than Expr.cacheLength)\n *\tdeleting the oldest entry\n */\nfunction createCache() {\n\tvar keys = [];\n\n\tfunction cache( key, value ) {\n\t\t// Use (key + \" \") to avoid collision with native prototype properties (see Issue #157)\n\t\tif ( keys.push( key + \" \" ) > Expr.cacheLength ) {\n\t\t\t// Only keep the most recent entries\n\t\t\tdelete cache[ keys.shift() ];\n\t\t}\n\t\treturn (cache[ key + \" \" ] = value);\n\t}\n\treturn cache;\n}\n\n/**\n * Mark a function for special use by Sizzle\n * @param {Function} fn The function to mark\n */\nfunction markFunction( fn ) {\n\tfn[ expando ] = true;\n\treturn fn;\n}\n\n/**\n * Support testing using an element\n * @param {Function} fn Passed the created div and expects a boolean result\n */\nfunction assert( fn ) {\n\tvar div = document.createElement(\"div\");\n\n\ttry {\n\t\treturn !!fn( div );\n\t} catch (e) {\n\t\treturn false;\n\t} finally {\n\t\t// Remove from its parent by default\n\t\tif ( div.parentNode ) {\n\t\t\tdiv.parentNode.removeChild( div );\n\t\t}\n\t\t// release memory in IE\n\t\tdiv = null;\n\t}\n}\n\n/**\n * Adds the same handler for all of the specified attrs\n * @param {String} attrs Pipe-separated list of attributes\n * @param {Function} handler The method that will be applied\n */\nfunction addHandle( attrs, handler ) {\n\tvar arr = attrs.split(\"|\"),\n\t\ti = attrs.length;\n\n\twhile ( i-- ) {\n\t\tExpr.attrHandle[ arr[i] ] = handler;\n\t}\n}\n\n/**\n * Checks document order of two siblings\n * @param {Element} a\n * @param {Element} b\n * @returns {Number} Returns less than 0 if a precedes b, greater than 0 if a follows b\n */\nfunction siblingCheck( a, b ) {\n\tvar cur = b && a,\n\t\tdiff = cur && a.nodeType === 1 && b.nodeType === 1 &&\n\t\t\t( ~b.sourceIndex || MAX_NEGATIVE ) -\n\t\t\t( ~a.sourceIndex || MAX_NEGATIVE );\n\n\t// Use IE sourceIndex if available on both nodes\n\tif ( diff ) {\n\t\treturn diff;\n\t}\n\n\t// Check if b follows a\n\tif ( cur ) {\n\t\twhile ( (cur = cur.nextSibling) ) {\n\t\t\tif ( cur === b ) {\n\t\t\t\treturn -1;\n\t\t\t}\n\t\t}\n\t}\n\n\treturn a ? 1 : -1;\n}\n\n/**\n * Returns a function to use in pseudos for input types\n * @param {String} type\n */\nfunction createInputPseudo( type ) {\n\treturn function( elem ) {\n\t\tvar name = elem.nodeName.toLowerCase();\n\t\treturn name === \"input\" && elem.type === type;\n\t};\n}\n\n/**\n * Returns a function to use in pseudos for buttons\n * @param {String} type\n */\nfunction createButtonPseudo( type ) {\n\treturn function( elem ) {\n\t\tvar name = elem.nodeName.toLowerCase();\n\t\treturn (name === \"input\" || name === \"button\") && elem.type === type;\n\t};\n}\n\n/**\n * Returns a function to use in pseudos for positionals\n * @param {Function} fn\n */\nfunction createPositionalPseudo( fn ) {\n\treturn markFunction(function( argument ) {\n\t\targument = +argument;\n\t\treturn markFunction(function( seed, matches ) {\n\t\t\tvar j,\n\t\t\t\tmatchIndexes = fn( [], seed.length, argument ),\n\t\t\t\ti = matchIndexes.length;\n\n\t\t\t// Match elements found at the specified indexes\n\t\t\twhile ( i-- ) {\n\t\t\t\tif ( seed[ (j = matchIndexes[i]) ] ) {\n\t\t\t\t\tseed[j] = !(matches[j] = seed[j]);\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\t});\n}\n\n/**\n * Checks a node for validity as a Sizzle context\n * @param {Element|Object=} context\n * @returns {Element|Object|Boolean} The input node if acceptable, otherwise a falsy value\n */\nfunction testContext( context ) {\n\treturn context && typeof context.getElementsByTagName !== \"undefined\" && context;\n}\n\n// Expose support vars for convenience\nsupport = Sizzle.support = {};\n\n/**\n * Detects XML nodes\n * @param {Element|Object} elem An element or a document\n * @returns {Boolean} True iff elem is a non-HTML XML node\n */\nisXML = Sizzle.isXML = function( elem ) {\n\t// documentElement is verified for cases where it doesn't yet exist\n\t// (such as loading iframes in IE - #4833)\n\tvar documentElement = elem && (elem.ownerDocument || elem).documentElement;\n\treturn documentElement ? documentElement.nodeName !== \"HTML\" : false;\n};\n\n/**\n * Sets document-related variables once based on the current document\n * @param {Element|Object} [doc] An element or document object to use to set the document\n * @returns {Object} Returns the current document\n */\nsetDocument = Sizzle.setDocument = function( node ) {\n\tvar hasCompare, parent,\n\t\tdoc = node ? node.ownerDocument || node : preferredDoc;\n\n\t// If no document and documentElement is available, return\n\tif ( doc === document || doc.nodeType !== 9 || !doc.documentElement ) {\n\t\treturn document;\n\t}\n\n\t// Set our document\n\tdocument = doc;\n\tdocElem = doc.documentElement;\n\tparent = doc.defaultView;\n\n\t// Support: IE>8\n\t// If iframe document is assigned to \"document\" variable and if iframe has been reloaded,\n\t// IE will throw \"permission denied\" error when accessing \"document\" variable, see jQuery #13936\n\t// IE6-8 do not support the defaultView property so parent will be undefined\n\tif ( parent && parent !== parent.top ) {\n\t\t// IE11 does not have attachEvent, so all must suffer\n\t\tif ( parent.addEventListener ) {\n\t\t\tparent.addEventListener( \"unload\", unloadHandler, false );\n\t\t} else if ( parent.attachEvent ) {\n\t\t\tparent.attachEvent( \"onunload\", unloadHandler );\n\t\t}\n\t}\n\n\t/* Support tests\n\t---------------------------------------------------------------------- */\n\tdocumentIsHTML = !isXML( doc );\n\n\t/* Attributes\n\t---------------------------------------------------------------------- */\n\n\t// Support: IE<8\n\t// Verify that getAttribute really returns attributes and not properties\n\t// (excepting IE8 booleans)\n\tsupport.attributes = assert(function( div ) {\n\t\tdiv.className = \"i\";\n\t\treturn !div.getAttribute(\"className\");\n\t});\n\n\t/* getElement(s)By*\n\t---------------------------------------------------------------------- */\n\n\t// Check if getElementsByTagName(\"*\") returns only elements\n\tsupport.getElementsByTagName = assert(function( div ) {\n\t\tdiv.appendChild( doc.createComment(\"\") );\n\t\treturn !div.getElementsByTagName(\"*\").length;\n\t});\n\n\t// Support: IE<9\n\tsupport.getElementsByClassName = rnative.test( doc.getElementsByClassName );\n\n\t// Support: IE<10\n\t// Check if getElementById returns elements by name\n\t// The broken getElementById methods don't pick up programatically-set names,\n\t// so use a roundabout getElementsByName test\n\tsupport.getById = assert(function( div ) {\n\t\tdocElem.appendChild( div ).id = expando;\n\t\treturn !doc.getElementsByName || !doc.getElementsByName( expando ).length;\n\t});\n\n\t// ID find and filter\n\tif ( support.getById ) {\n\t\tExpr.find[\"ID\"] = function( id, context ) {\n\t\t\tif ( typeof context.getElementById !== \"undefined\" && documentIsHTML ) {\n\t\t\t\tvar m = context.getElementById( id );\n\t\t\t\t// Check parentNode to catch when Blackberry 4.6 returns\n\t\t\t\t// nodes that are no longer in the document #6963\n\t\t\t\treturn m && m.parentNode ? [ m ] : [];\n\t\t\t}\n\t\t};\n\t\tExpr.filter[\"ID\"] = function( id ) {\n\t\t\tvar attrId = id.replace( runescape, funescape );\n\t\t\treturn function( elem ) {\n\t\t\t\treturn elem.getAttribute(\"id\") === attrId;\n\t\t\t};\n\t\t};\n\t} else {\n\t\t// Support: IE6/7\n\t\t// getElementById is not reliable as a find shortcut\n\t\tdelete Expr.find[\"ID\"];\n\n\t\tExpr.filter[\"ID\"] =  function( id ) {\n\t\t\tvar attrId = id.replace( runescape, funescape );\n\t\t\treturn function( elem ) {\n\t\t\t\tvar node = typeof elem.getAttributeNode !== \"undefined\" && elem.getAttributeNode(\"id\");\n\t\t\t\treturn node && node.value === attrId;\n\t\t\t};\n\t\t};\n\t}\n\n\t// Tag\n\tExpr.find[\"TAG\"] = support.getElementsByTagName ?\n\t\tfunction( tag, context ) {\n\t\t\tif ( typeof context.getElementsByTagName !== \"undefined\" ) {\n\t\t\t\treturn context.getElementsByTagName( tag );\n\n\t\t\t// DocumentFragment nodes don't have gEBTN\n\t\t\t} else if ( support.qsa ) {\n\t\t\t\treturn context.querySelectorAll( tag );\n\t\t\t}\n\t\t} :\n\n\t\tfunction( tag, context ) {\n\t\t\tvar elem,\n\t\t\t\ttmp = [],\n\t\t\t\ti = 0,\n\t\t\t\t// By happy coincidence, a (broken) gEBTN appears on DocumentFragment nodes too\n\t\t\t\tresults = context.getElementsByTagName( tag );\n\n\t\t\t// Filter out possible comments\n\t\t\tif ( tag === \"*\" ) {\n\t\t\t\twhile ( (elem = results[i++]) ) {\n\t\t\t\t\tif ( elem.nodeType === 1 ) {\n\t\t\t\t\t\ttmp.push( elem );\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\treturn tmp;\n\t\t\t}\n\t\t\treturn results;\n\t\t};\n\n\t// Class\n\tExpr.find[\"CLASS\"] = support.getElementsByClassName && function( className, context ) {\n\t\tif ( documentIsHTML ) {\n\t\t\treturn context.getElementsByClassName( className );\n\t\t}\n\t};\n\n\t/* QSA/matchesSelector\n\t---------------------------------------------------------------------- */\n\n\t// QSA and matchesSelector support\n\n\t// matchesSelector(:active) reports false when true (IE9/Opera 11.5)\n\trbuggyMatches = [];\n\n\t// qSa(:focus) reports false when true (Chrome 21)\n\t// We allow this because of a bug in IE8/9 that throws an error\n\t// whenever `document.activeElement` is accessed on an iframe\n\t// So, we allow :focus to pass through QSA all the time to avoid the IE error\n\t// See http://bugs.jquery.com/ticket/13378\n\trbuggyQSA = [];\n\n\tif ( (support.qsa = rnative.test( doc.querySelectorAll )) ) {\n\t\t// Build QSA regex\n\t\t// Regex strategy adopted from Diego Perini\n\t\tassert(function( div ) {\n\t\t\t// Select is set to empty string on purpose\n\t\t\t// This is to test IE's treatment of not explicitly\n\t\t\t// setting a boolean content attribute,\n\t\t\t// since its presence should be enough\n\t\t\t// http://bugs.jquery.com/ticket/12359\n\t\t\tdocElem.appendChild( div ).innerHTML = \"<a id='\" + expando + \"'></a>\" +\n\t\t\t\t\"<select id='\" + expando + \"-\\f]' msallowcapture=''>\" +\n\t\t\t\t\"<option selected=''></option></select>\";\n\n\t\t\t// Support: IE8, Opera 11-12.16\n\t\t\t// Nothing should be selected when empty strings follow ^= or $= or *=\n\t\t\t// The test attribute must be unknown in Opera but \"safe\" for WinRT\n\t\t\t// http://msdn.microsoft.com/en-us/library/ie/hh465388.aspx#attribute_section\n\t\t\tif ( div.querySelectorAll(\"[msallowcapture^='']\").length ) {\n\t\t\t\trbuggyQSA.push( \"[*^$]=\" + whitespace + \"*(?:''|\\\"\\\")\" );\n\t\t\t}\n\n\t\t\t// Support: IE8\n\t\t\t// Boolean attributes and \"value\" are not treated correctly\n\t\t\tif ( !div.querySelectorAll(\"[selected]\").length ) {\n\t\t\t\trbuggyQSA.push( \"\\\\[\" + whitespace + \"*(?:value|\" + booleans + \")\" );\n\t\t\t}\n\n\t\t\t// Support: Chrome<29, Android<4.2+, Safari<7.0+, iOS<7.0+, PhantomJS<1.9.7+\n\t\t\tif ( !div.querySelectorAll( \"[id~=\" + expando + \"-]\" ).length ) {\n\t\t\t\trbuggyQSA.push(\"~=\");\n\t\t\t}\n\n\t\t\t// Webkit/Opera - :checked should return selected option elements\n\t\t\t// http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked\n\t\t\t// IE8 throws error here and will not see later tests\n\t\t\tif ( !div.querySelectorAll(\":checked\").length ) {\n\t\t\t\trbuggyQSA.push(\":checked\");\n\t\t\t}\n\n\t\t\t// Support: Safari 8+, iOS 8+\n\t\t\t// https://bugs.webkit.org/show_bug.cgi?id=136851\n\t\t\t// In-page `selector#id sibing-combinator selector` fails\n\t\t\tif ( !div.querySelectorAll( \"a#\" + expando + \"+*\" ).length ) {\n\t\t\t\trbuggyQSA.push(\".#.+[+~]\");\n\t\t\t}\n\t\t});\n\n\t\tassert(function( div ) {\n\t\t\t// Support: Windows 8 Native Apps\n\t\t\t// The type and name attributes are restricted during .innerHTML assignment\n\t\t\tvar input = doc.createElement(\"input\");\n\t\t\tinput.setAttribute( \"type\", \"hidden\" );\n\t\t\tdiv.appendChild( input ).setAttribute( \"name\", \"D\" );\n\n\t\t\t// Support: IE8\n\t\t\t// Enforce case-sensitivity of name attribute\n\t\t\tif ( div.querySelectorAll(\"[name=d]\").length ) {\n\t\t\t\trbuggyQSA.push( \"name\" + whitespace + \"*[*^$|!~]?=\" );\n\t\t\t}\n\n\t\t\t// FF 3.5 - :enabled/:disabled and hidden elements (hidden elements are still enabled)\n\t\t\t// IE8 throws error here and will not see later tests\n\t\t\tif ( !div.querySelectorAll(\":enabled\").length ) {\n\t\t\t\trbuggyQSA.push( \":enabled\", \":disabled\" );\n\t\t\t}\n\n\t\t\t// Opera 10-11 does not throw on post-comma invalid pseudos\n\t\t\tdiv.querySelectorAll(\"*,:x\");\n\t\t\trbuggyQSA.push(\",.*:\");\n\t\t});\n\t}\n\n\tif ( (support.matchesSelector = rnative.test( (matches = docElem.matches ||\n\t\tdocElem.webkitMatchesSelector ||\n\t\tdocElem.mozMatchesSelector ||\n\t\tdocElem.oMatchesSelector ||\n\t\tdocElem.msMatchesSelector) )) ) {\n\n\t\tassert(function( div ) {\n\t\t\t// Check to see if it's possible to do matchesSelector\n\t\t\t// on a disconnected node (IE 9)\n\t\t\tsupport.disconnectedMatch = matches.call( div, \"div\" );\n\n\t\t\t// This should fail with an exception\n\t\t\t// Gecko does not error, returns false instead\n\t\t\tmatches.call( div, \"[s!='']:x\" );\n\t\t\trbuggyMatches.push( \"!=\", pseudos );\n\t\t});\n\t}\n\n\trbuggyQSA = rbuggyQSA.length && new RegExp( rbuggyQSA.join(\"|\") );\n\trbuggyMatches = rbuggyMatches.length && new RegExp( rbuggyMatches.join(\"|\") );\n\n\t/* Contains\n\t---------------------------------------------------------------------- */\n\thasCompare = rnative.test( docElem.compareDocumentPosition );\n\n\t// Element contains another\n\t// Purposefully does not implement inclusive descendent\n\t// As in, an element does not contain itself\n\tcontains = hasCompare || rnative.test( docElem.contains ) ?\n\t\tfunction( a, b ) {\n\t\t\tvar adown = a.nodeType === 9 ? a.documentElement : a,\n\t\t\t\tbup = b && b.parentNode;\n\t\t\treturn a === bup || !!( bup && bup.nodeType === 1 && (\n\t\t\t\tadown.contains ?\n\t\t\t\t\tadown.contains( bup ) :\n\t\t\t\t\ta.compareDocumentPosition && a.compareDocumentPosition( bup ) & 16\n\t\t\t));\n\t\t} :\n\t\tfunction( a, b ) {\n\t\t\tif ( b ) {\n\t\t\t\twhile ( (b = b.parentNode) ) {\n\t\t\t\t\tif ( b === a ) {\n\t\t\t\t\t\treturn true;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn false;\n\t\t};\n\n\t/* Sorting\n\t---------------------------------------------------------------------- */\n\n\t// Document order sorting\n\tsortOrder = hasCompare ?\n\tfunction( a, b ) {\n\n\t\t// Flag for duplicate removal\n\t\tif ( a === b ) {\n\t\t\thasDuplicate = true;\n\t\t\treturn 0;\n\t\t}\n\n\t\t// Sort on method existence if only one input has compareDocumentPosition\n\t\tvar compare = !a.compareDocumentPosition - !b.compareDocumentPosition;\n\t\tif ( compare ) {\n\t\t\treturn compare;\n\t\t}\n\n\t\t// Calculate position if both inputs belong to the same document\n\t\tcompare = ( a.ownerDocument || a ) === ( b.ownerDocument || b ) ?\n\t\t\ta.compareDocumentPosition( b ) :\n\n\t\t\t// Otherwise we know they are disconnected\n\t\t\t1;\n\n\t\t// Disconnected nodes\n\t\tif ( compare & 1 ||\n\t\t\t(!support.sortDetached && b.compareDocumentPosition( a ) === compare) ) {\n\n\t\t\t// Choose the first element that is related to our preferred document\n\t\t\tif ( a === doc || a.ownerDocument === preferredDoc && contains(preferredDoc, a) ) {\n\t\t\t\treturn -1;\n\t\t\t}\n\t\t\tif ( b === doc || b.ownerDocument === preferredDoc && contains(preferredDoc, b) ) {\n\t\t\t\treturn 1;\n\t\t\t}\n\n\t\t\t// Maintain original order\n\t\t\treturn sortInput ?\n\t\t\t\t( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) :\n\t\t\t\t0;\n\t\t}\n\n\t\treturn compare & 4 ? -1 : 1;\n\t} :\n\tfunction( a, b ) {\n\t\t// Exit early if the nodes are identical\n\t\tif ( a === b ) {\n\t\t\thasDuplicate = true;\n\t\t\treturn 0;\n\t\t}\n\n\t\tvar cur,\n\t\t\ti = 0,\n\t\t\taup = a.parentNode,\n\t\t\tbup = b.parentNode,\n\t\t\tap = [ a ],\n\t\t\tbp = [ b ];\n\n\t\t// Parentless nodes are either documents or disconnected\n\t\tif ( !aup || !bup ) {\n\t\t\treturn a === doc ? -1 :\n\t\t\t\tb === doc ? 1 :\n\t\t\t\taup ? -1 :\n\t\t\t\tbup ? 1 :\n\t\t\t\tsortInput ?\n\t\t\t\t( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) :\n\t\t\t\t0;\n\n\t\t// If the nodes are siblings, we can do a quick check\n\t\t} else if ( aup === bup ) {\n\t\t\treturn siblingCheck( a, b );\n\t\t}\n\n\t\t// Otherwise we need full lists of their ancestors for comparison\n\t\tcur = a;\n\t\twhile ( (cur = cur.parentNode) ) {\n\t\t\tap.unshift( cur );\n\t\t}\n\t\tcur = b;\n\t\twhile ( (cur = cur.parentNode) ) {\n\t\t\tbp.unshift( cur );\n\t\t}\n\n\t\t// Walk down the tree looking for a discrepancy\n\t\twhile ( ap[i] === bp[i] ) {\n\t\t\ti++;\n\t\t}\n\n\t\treturn i ?\n\t\t\t// Do a sibling check if the nodes have a common ancestor\n\t\t\tsiblingCheck( ap[i], bp[i] ) :\n\n\t\t\t// Otherwise nodes in our document sort first\n\t\t\tap[i] === preferredDoc ? -1 :\n\t\t\tbp[i] === preferredDoc ? 1 :\n\t\t\t0;\n\t};\n\n\treturn doc;\n};\n\nSizzle.matches = function( expr, elements ) {\n\treturn Sizzle( expr, null, null, elements );\n};\n\nSizzle.matchesSelector = function( elem, expr ) {\n\t// Set document vars if needed\n\tif ( ( elem.ownerDocument || elem ) !== document ) {\n\t\tsetDocument( elem );\n\t}\n\n\t// Make sure that attribute selectors are quoted\n\texpr = expr.replace( rattributeQuotes, \"='$1']\" );\n\n\tif ( support.matchesSelector && documentIsHTML &&\n\t\t( !rbuggyMatches || !rbuggyMatches.test( expr ) ) &&\n\t\t( !rbuggyQSA     || !rbuggyQSA.test( expr ) ) ) {\n\n\t\ttry {\n\t\t\tvar ret = matches.call( elem, expr );\n\n\t\t\t// IE 9's matchesSelector returns false on disconnected nodes\n\t\t\tif ( ret || support.disconnectedMatch ||\n\t\t\t\t\t// As well, disconnected nodes are said to be in a document\n\t\t\t\t\t// fragment in IE 9\n\t\t\t\t\telem.document && elem.document.nodeType !== 11 ) {\n\t\t\t\treturn ret;\n\t\t\t}\n\t\t} catch (e) {}\n\t}\n\n\treturn Sizzle( expr, document, null, [ elem ] ).length > 0;\n};\n\nSizzle.contains = function( context, elem ) {\n\t// Set document vars if needed\n\tif ( ( context.ownerDocument || context ) !== document ) {\n\t\tsetDocument( context );\n\t}\n\treturn contains( context, elem );\n};\n\nSizzle.attr = function( elem, name ) {\n\t// Set document vars if needed\n\tif ( ( elem.ownerDocument || elem ) !== document ) {\n\t\tsetDocument( elem );\n\t}\n\n\tvar fn = Expr.attrHandle[ name.toLowerCase() ],\n\t\t// Don't get fooled by Object.prototype properties (jQuery #13807)\n\t\tval = fn && hasOwn.call( Expr.attrHandle, name.toLowerCase() ) ?\n\t\t\tfn( elem, name, !documentIsHTML ) :\n\t\t\tundefined;\n\n\treturn val !== undefined ?\n\t\tval :\n\t\tsupport.attributes || !documentIsHTML ?\n\t\t\telem.getAttribute( name ) :\n\t\t\t(val = elem.getAttributeNode(name)) && val.specified ?\n\t\t\t\tval.value :\n\t\t\t\tnull;\n};\n\nSizzle.error = function( msg ) {\n\tthrow new Error( \"Syntax error, unrecognized expression: \" + msg );\n};\n\n/**\n * Document sorting and removing duplicates\n * @param {ArrayLike} results\n */\nSizzle.uniqueSort = function( results ) {\n\tvar elem,\n\t\tduplicates = [],\n\t\tj = 0,\n\t\ti = 0;\n\n\t// Unless we *know* we can detect duplicates, assume their presence\n\thasDuplicate = !support.detectDuplicates;\n\tsortInput = !support.sortStable && results.slice( 0 );\n\tresults.sort( sortOrder );\n\n\tif ( hasDuplicate ) {\n\t\twhile ( (elem = results[i++]) ) {\n\t\t\tif ( elem === results[ i ] ) {\n\t\t\t\tj = duplicates.push( i );\n\t\t\t}\n\t\t}\n\t\twhile ( j-- ) {\n\t\t\tresults.splice( duplicates[ j ], 1 );\n\t\t}\n\t}\n\n\t// Clear input after sorting to release objects\n\t// See https://github.com/jquery/sizzle/pull/225\n\tsortInput = null;\n\n\treturn results;\n};\n\n/**\n * Utility function for retrieving the text value of an array of DOM nodes\n * @param {Array|Element} elem\n */\ngetText = Sizzle.getText = function( elem ) {\n\tvar node,\n\t\tret = \"\",\n\t\ti = 0,\n\t\tnodeType = elem.nodeType;\n\n\tif ( !nodeType ) {\n\t\t// If no nodeType, this is expected to be an array\n\t\twhile ( (node = elem[i++]) ) {\n\t\t\t// Do not traverse comment nodes\n\t\t\tret += getText( node );\n\t\t}\n\t} else if ( nodeType === 1 || nodeType === 9 || nodeType === 11 ) {\n\t\t// Use textContent for elements\n\t\t// innerText usage removed for consistency of new lines (jQuery #11153)\n\t\tif ( typeof elem.textContent === \"string\" ) {\n\t\t\treturn elem.textContent;\n\t\t} else {\n\t\t\t// Traverse its children\n\t\t\tfor ( elem = elem.firstChild; elem; elem = elem.nextSibling ) {\n\t\t\t\tret += getText( elem );\n\t\t\t}\n\t\t}\n\t} else if ( nodeType === 3 || nodeType === 4 ) {\n\t\treturn elem.nodeValue;\n\t}\n\t// Do not include comment or processing instruction nodes\n\n\treturn ret;\n};\n\nExpr = Sizzle.selectors = {\n\n\t// Can be adjusted by the user\n\tcacheLength: 50,\n\n\tcreatePseudo: markFunction,\n\n\tmatch: matchExpr,\n\n\tattrHandle: {},\n\n\tfind: {},\n\n\trelative: {\n\t\t\">\": { dir: \"parentNode\", first: true },\n\t\t\" \": { dir: \"parentNode\" },\n\t\t\"+\": { dir: \"previousSibling\", first: true },\n\t\t\"~\": { dir: \"previousSibling\" }\n\t},\n\n\tpreFilter: {\n\t\t\"ATTR\": function( match ) {\n\t\t\tmatch[1] = match[1].replace( runescape, funescape );\n\n\t\t\t// Move the given value to match[3] whether quoted or unquoted\n\t\t\tmatch[3] = ( match[3] || match[4] || match[5] || \"\" ).replace( runescape, funescape );\n\n\t\t\tif ( match[2] === \"~=\" ) {\n\t\t\t\tmatch[3] = \" \" + match[3] + \" \";\n\t\t\t}\n\n\t\t\treturn match.slice( 0, 4 );\n\t\t},\n\n\t\t\"CHILD\": function( match ) {\n\t\t\t/* matches from matchExpr[\"CHILD\"]\n\t\t\t\t1 type (only|nth|...)\n\t\t\t\t2 what (child|of-type)\n\t\t\t\t3 argument (even|odd|\\d*|\\d*n([+-]\\d+)?|...)\n\t\t\t\t4 xn-component of xn+y argument ([+-]?\\d*n|)\n\t\t\t\t5 sign of xn-component\n\t\t\t\t6 x of xn-component\n\t\t\t\t7 sign of y-component\n\t\t\t\t8 y of y-component\n\t\t\t*/\n\t\t\tmatch[1] = match[1].toLowerCase();\n\n\t\t\tif ( match[1].slice( 0, 3 ) === \"nth\" ) {\n\t\t\t\t// nth-* requires argument\n\t\t\t\tif ( !match[3] ) {\n\t\t\t\t\tSizzle.error( match[0] );\n\t\t\t\t}\n\n\t\t\t\t// numeric x and y parameters for Expr.filter.CHILD\n\t\t\t\t// remember that false/true cast respectively to 0/1\n\t\t\t\tmatch[4] = +( match[4] ? match[5] + (match[6] || 1) : 2 * ( match[3] === \"even\" || match[3] === \"odd\" ) );\n\t\t\t\tmatch[5] = +( ( match[7] + match[8] ) || match[3] === \"odd\" );\n\n\t\t\t// other types prohibit arguments\n\t\t\t} else if ( match[3] ) {\n\t\t\t\tSizzle.error( match[0] );\n\t\t\t}\n\n\t\t\treturn match;\n\t\t},\n\n\t\t\"PSEUDO\": function( match ) {\n\t\t\tvar excess,\n\t\t\t\tunquoted = !match[6] && match[2];\n\n\t\t\tif ( matchExpr[\"CHILD\"].test( match[0] ) ) {\n\t\t\t\treturn null;\n\t\t\t}\n\n\t\t\t// Accept quoted arguments as-is\n\t\t\tif ( match[3] ) {\n\t\t\t\tmatch[2] = match[4] || match[5] || \"\";\n\n\t\t\t// Strip excess characters from unquoted arguments\n\t\t\t} else if ( unquoted && rpseudo.test( unquoted ) &&\n\t\t\t\t// Get excess from tokenize (recursively)\n\t\t\t\t(excess = tokenize( unquoted, true )) &&\n\t\t\t\t// advance to the next closing parenthesis\n\t\t\t\t(excess = unquoted.indexOf( \")\", unquoted.length - excess ) - unquoted.length) ) {\n\n\t\t\t\t// excess is a negative index\n\t\t\t\tmatch[0] = match[0].slice( 0, excess );\n\t\t\t\tmatch[2] = unquoted.slice( 0, excess );\n\t\t\t}\n\n\t\t\t// Return only captures needed by the pseudo filter method (type and argument)\n\t\t\treturn match.slice( 0, 3 );\n\t\t}\n\t},\n\n\tfilter: {\n\n\t\t\"TAG\": function( nodeNameSelector ) {\n\t\t\tvar nodeName = nodeNameSelector.replace( runescape, funescape ).toLowerCase();\n\t\t\treturn nodeNameSelector === \"*\" ?\n\t\t\t\tfunction() { return true; } :\n\t\t\t\tfunction( elem ) {\n\t\t\t\t\treturn elem.nodeName && elem.nodeName.toLowerCase() === nodeName;\n\t\t\t\t};\n\t\t},\n\n\t\t\"CLASS\": function( className ) {\n\t\t\tvar pattern = classCache[ className + \" \" ];\n\n\t\t\treturn pattern ||\n\t\t\t\t(pattern = new RegExp( \"(^|\" + whitespace + \")\" + className + \"(\" + whitespace + \"|$)\" )) &&\n\t\t\t\tclassCache( className, function( elem ) {\n\t\t\t\t\treturn pattern.test( typeof elem.className === \"string\" && elem.className || typeof elem.getAttribute !== \"undefined\" && elem.getAttribute(\"class\") || \"\" );\n\t\t\t\t});\n\t\t},\n\n\t\t\"ATTR\": function( name, operator, check ) {\n\t\t\treturn function( elem ) {\n\t\t\t\tvar result = Sizzle.attr( elem, name );\n\n\t\t\t\tif ( result == null ) {\n\t\t\t\t\treturn operator === \"!=\";\n\t\t\t\t}\n\t\t\t\tif ( !operator ) {\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\n\t\t\t\tresult += \"\";\n\n\t\t\t\treturn operator === \"=\" ? result === check :\n\t\t\t\t\toperator === \"!=\" ? result !== check :\n\t\t\t\t\toperator === \"^=\" ? check && result.indexOf( check ) === 0 :\n\t\t\t\t\toperator === \"*=\" ? check && result.indexOf( check ) > -1 :\n\t\t\t\t\toperator === \"$=\" ? check && result.slice( -check.length ) === check :\n\t\t\t\t\toperator === \"~=\" ? ( \" \" + result.replace( rwhitespace, \" \" ) + \" \" ).indexOf( check ) > -1 :\n\t\t\t\t\toperator === \"|=\" ? result === check || result.slice( 0, check.length + 1 ) === check + \"-\" :\n\t\t\t\t\tfalse;\n\t\t\t};\n\t\t},\n\n\t\t\"CHILD\": function( type, what, argument, first, last ) {\n\t\t\tvar simple = type.slice( 0, 3 ) !== \"nth\",\n\t\t\t\tforward = type.slice( -4 ) !== \"last\",\n\t\t\t\tofType = what === \"of-type\";\n\n\t\t\treturn first === 1 && last === 0 ?\n\n\t\t\t\t// Shortcut for :nth-*(n)\n\t\t\t\tfunction( elem ) {\n\t\t\t\t\treturn !!elem.parentNode;\n\t\t\t\t} :\n\n\t\t\t\tfunction( elem, context, xml ) {\n\t\t\t\t\tvar cache, outerCache, node, diff, nodeIndex, start,\n\t\t\t\t\t\tdir = simple !== forward ? \"nextSibling\" : \"previousSibling\",\n\t\t\t\t\t\tparent = elem.parentNode,\n\t\t\t\t\t\tname = ofType && elem.nodeName.toLowerCase(),\n\t\t\t\t\t\tuseCache = !xml && !ofType;\n\n\t\t\t\t\tif ( parent ) {\n\n\t\t\t\t\t\t// :(first|last|only)-(child|of-type)\n\t\t\t\t\t\tif ( simple ) {\n\t\t\t\t\t\t\twhile ( dir ) {\n\t\t\t\t\t\t\t\tnode = elem;\n\t\t\t\t\t\t\t\twhile ( (node = node[ dir ]) ) {\n\t\t\t\t\t\t\t\t\tif ( ofType ? node.nodeName.toLowerCase() === name : node.nodeType === 1 ) {\n\t\t\t\t\t\t\t\t\t\treturn false;\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t// Reverse direction for :only-* (if we haven't yet done so)\n\t\t\t\t\t\t\t\tstart = dir = type === \"only\" && !start && \"nextSibling\";\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\treturn true;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tstart = [ forward ? parent.firstChild : parent.lastChild ];\n\n\t\t\t\t\t\t// non-xml :nth-child(...) stores cache data on `parent`\n\t\t\t\t\t\tif ( forward && useCache ) {\n\t\t\t\t\t\t\t// Seek `elem` from a previously-cached index\n\t\t\t\t\t\t\touterCache = parent[ expando ] || (parent[ expando ] = {});\n\t\t\t\t\t\t\tcache = outerCache[ type ] || [];\n\t\t\t\t\t\t\tnodeIndex = cache[0] === dirruns && cache[1];\n\t\t\t\t\t\t\tdiff = cache[0] === dirruns && cache[2];\n\t\t\t\t\t\t\tnode = nodeIndex && parent.childNodes[ nodeIndex ];\n\n\t\t\t\t\t\t\twhile ( (node = ++nodeIndex && node && node[ dir ] ||\n\n\t\t\t\t\t\t\t\t// Fallback to seeking `elem` from the start\n\t\t\t\t\t\t\t\t(diff = nodeIndex = 0) || start.pop()) ) {\n\n\t\t\t\t\t\t\t\t// When found, cache indexes on `parent` and break\n\t\t\t\t\t\t\t\tif ( node.nodeType === 1 && ++diff && node === elem ) {\n\t\t\t\t\t\t\t\t\touterCache[ type ] = [ dirruns, nodeIndex, diff ];\n\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// Use previously-cached element index if available\n\t\t\t\t\t\t} else if ( useCache && (cache = (elem[ expando ] || (elem[ expando ] = {}))[ type ]) && cache[0] === dirruns ) {\n\t\t\t\t\t\t\tdiff = cache[1];\n\n\t\t\t\t\t\t// xml :nth-child(...) or :nth-last-child(...) or :nth(-last)?-of-type(...)\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t// Use the same loop as above to seek `elem` from the start\n\t\t\t\t\t\t\twhile ( (node = ++nodeIndex && node && node[ dir ] ||\n\t\t\t\t\t\t\t\t(diff = nodeIndex = 0) || start.pop()) ) {\n\n\t\t\t\t\t\t\t\tif ( ( ofType ? node.nodeName.toLowerCase() === name : node.nodeType === 1 ) && ++diff ) {\n\t\t\t\t\t\t\t\t\t// Cache the index of each encountered element\n\t\t\t\t\t\t\t\t\tif ( useCache ) {\n\t\t\t\t\t\t\t\t\t\t(node[ expando ] || (node[ expando ] = {}))[ type ] = [ dirruns, diff ];\n\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t\tif ( node === elem ) {\n\t\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// Incorporate the offset, then check against cycle size\n\t\t\t\t\t\tdiff -= last;\n\t\t\t\t\t\treturn diff === first || ( diff % first === 0 && diff / first >= 0 );\n\t\t\t\t\t}\n\t\t\t\t};\n\t\t},\n\n\t\t\"PSEUDO\": function( pseudo, argument ) {\n\t\t\t// pseudo-class names are case-insensitive\n\t\t\t// http://www.w3.org/TR/selectors/#pseudo-classes\n\t\t\t// Prioritize by case sensitivity in case custom pseudos are added with uppercase letters\n\t\t\t// Remember that setFilters inherits from pseudos\n\t\t\tvar args,\n\t\t\t\tfn = Expr.pseudos[ pseudo ] || Expr.setFilters[ pseudo.toLowerCase() ] ||\n\t\t\t\t\tSizzle.error( \"unsupported pseudo: \" + pseudo );\n\n\t\t\t// The user may use createPseudo to indicate that\n\t\t\t// arguments are needed to create the filter function\n\t\t\t// just as Sizzle does\n\t\t\tif ( fn[ expando ] ) {\n\t\t\t\treturn fn( argument );\n\t\t\t}\n\n\t\t\t// But maintain support for old signatures\n\t\t\tif ( fn.length > 1 ) {\n\t\t\t\targs = [ pseudo, pseudo, \"\", argument ];\n\t\t\t\treturn Expr.setFilters.hasOwnProperty( pseudo.toLowerCase() ) ?\n\t\t\t\t\tmarkFunction(function( seed, matches ) {\n\t\t\t\t\t\tvar idx,\n\t\t\t\t\t\t\tmatched = fn( seed, argument ),\n\t\t\t\t\t\t\ti = matched.length;\n\t\t\t\t\t\twhile ( i-- ) {\n\t\t\t\t\t\t\tidx = indexOf( seed, matched[i] );\n\t\t\t\t\t\t\tseed[ idx ] = !( matches[ idx ] = matched[i] );\n\t\t\t\t\t\t}\n\t\t\t\t\t}) :\n\t\t\t\t\tfunction( elem ) {\n\t\t\t\t\t\treturn fn( elem, 0, args );\n\t\t\t\t\t};\n\t\t\t}\n\n\t\t\treturn fn;\n\t\t}\n\t},\n\n\tpseudos: {\n\t\t// Potentially complex pseudos\n\t\t\"not\": markFunction(function( selector ) {\n\t\t\t// Trim the selector passed to compile\n\t\t\t// to avoid treating leading and trailing\n\t\t\t// spaces as combinators\n\t\t\tvar input = [],\n\t\t\t\tresults = [],\n\t\t\t\tmatcher = compile( selector.replace( rtrim, \"$1\" ) );\n\n\t\t\treturn matcher[ expando ] ?\n\t\t\t\tmarkFunction(function( seed, matches, context, xml ) {\n\t\t\t\t\tvar elem,\n\t\t\t\t\t\tunmatched = matcher( seed, null, xml, [] ),\n\t\t\t\t\t\ti = seed.length;\n\n\t\t\t\t\t// Match elements unmatched by `matcher`\n\t\t\t\t\twhile ( i-- ) {\n\t\t\t\t\t\tif ( (elem = unmatched[i]) ) {\n\t\t\t\t\t\t\tseed[i] = !(matches[i] = elem);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}) :\n\t\t\t\tfunction( elem, context, xml ) {\n\t\t\t\t\tinput[0] = elem;\n\t\t\t\t\tmatcher( input, null, xml, results );\n\t\t\t\t\t// Don't keep the element (issue #299)\n\t\t\t\t\tinput[0] = null;\n\t\t\t\t\treturn !results.pop();\n\t\t\t\t};\n\t\t}),\n\n\t\t\"has\": markFunction(function( selector ) {\n\t\t\treturn function( elem ) {\n\t\t\t\treturn Sizzle( selector, elem ).length > 0;\n\t\t\t};\n\t\t}),\n\n\t\t\"contains\": markFunction(function( text ) {\n\t\t\ttext = text.replace( runescape, funescape );\n\t\t\treturn function( elem ) {\n\t\t\t\treturn ( elem.textContent || elem.innerText || getText( elem ) ).indexOf( text ) > -1;\n\t\t\t};\n\t\t}),\n\n\t\t// \"Whether an element is represented by a :lang() selector\n\t\t// is based solely on the element's language value\n\t\t// being equal to the identifier C,\n\t\t// or beginning with the identifier C immediately followed by \"-\".\n\t\t// The matching of C against the element's language value is performed case-insensitively.\n\t\t// The identifier C does not have to be a valid language name.\"\n\t\t// http://www.w3.org/TR/selectors/#lang-pseudo\n\t\t\"lang\": markFunction( function( lang ) {\n\t\t\t// lang value must be a valid identifier\n\t\t\tif ( !ridentifier.test(lang || \"\") ) {\n\t\t\t\tSizzle.error( \"unsupported lang: \" + lang );\n\t\t\t}\n\t\t\tlang = lang.replace( runescape, funescape ).toLowerCase();\n\t\t\treturn function( elem ) {\n\t\t\t\tvar elemLang;\n\t\t\t\tdo {\n\t\t\t\t\tif ( (elemLang = documentIsHTML ?\n\t\t\t\t\t\telem.lang :\n\t\t\t\t\t\telem.getAttribute(\"xml:lang\") || elem.getAttribute(\"lang\")) ) {\n\n\t\t\t\t\t\telemLang = elemLang.toLowerCase();\n\t\t\t\t\t\treturn elemLang === lang || elemLang.indexOf( lang + \"-\" ) === 0;\n\t\t\t\t\t}\n\t\t\t\t} while ( (elem = elem.parentNode) && elem.nodeType === 1 );\n\t\t\t\treturn false;\n\t\t\t};\n\t\t}),\n\n\t\t// Miscellaneous\n\t\t\"target\": function( elem ) {\n\t\t\tvar hash = window.location && window.location.hash;\n\t\t\treturn hash && hash.slice( 1 ) === elem.id;\n\t\t},\n\n\t\t\"root\": function( elem ) {\n\t\t\treturn elem === docElem;\n\t\t},\n\n\t\t\"focus\": function( elem ) {\n\t\t\treturn elem === document.activeElement && (!document.hasFocus || document.hasFocus()) && !!(elem.type || elem.href || ~elem.tabIndex);\n\t\t},\n\n\t\t// Boolean properties\n\t\t\"enabled\": function( elem ) {\n\t\t\treturn elem.disabled === false;\n\t\t},\n\n\t\t\"disabled\": function( elem ) {\n\t\t\treturn elem.disabled === true;\n\t\t},\n\n\t\t\"checked\": function( elem ) {\n\t\t\t// In CSS3, :checked should return both checked and selected elements\n\t\t\t// http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked\n\t\t\tvar nodeName = elem.nodeName.toLowerCase();\n\t\t\treturn (nodeName === \"input\" && !!elem.checked) || (nodeName === \"option\" && !!elem.selected);\n\t\t},\n\n\t\t\"selected\": function( elem ) {\n\t\t\t// Accessing this property makes selected-by-default\n\t\t\t// options in Safari work properly\n\t\t\tif ( elem.parentNode ) {\n\t\t\t\telem.parentNode.selectedIndex;\n\t\t\t}\n\n\t\t\treturn elem.selected === true;\n\t\t},\n\n\t\t// Contents\n\t\t\"empty\": function( elem ) {\n\t\t\t// http://www.w3.org/TR/selectors/#empty-pseudo\n\t\t\t// :empty is negated by element (1) or content nodes (text: 3; cdata: 4; entity ref: 5),\n\t\t\t//   but not by others (comment: 8; processing instruction: 7; etc.)\n\t\t\t// nodeType < 6 works because attributes (2) do not appear as children\n\t\t\tfor ( elem = elem.firstChild; elem; elem = elem.nextSibling ) {\n\t\t\t\tif ( elem.nodeType < 6 ) {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn true;\n\t\t},\n\n\t\t\"parent\": function( elem ) {\n\t\t\treturn !Expr.pseudos[\"empty\"]( elem );\n\t\t},\n\n\t\t// Element/input types\n\t\t\"header\": function( elem ) {\n\t\t\treturn rheader.test( elem.nodeName );\n\t\t},\n\n\t\t\"input\": function( elem ) {\n\t\t\treturn rinputs.test( elem.nodeName );\n\t\t},\n\n\t\t\"button\": function( elem ) {\n\t\t\tvar name = elem.nodeName.toLowerCase();\n\t\t\treturn name === \"input\" && elem.type === \"button\" || name === \"button\";\n\t\t},\n\n\t\t\"text\": function( elem ) {\n\t\t\tvar attr;\n\t\t\treturn elem.nodeName.toLowerCase() === \"input\" &&\n\t\t\t\telem.type === \"text\" &&\n\n\t\t\t\t// Support: IE<8\n\t\t\t\t// New HTML5 attribute values (e.g., \"search\") appear with elem.type === \"text\"\n\t\t\t\t( (attr = elem.getAttribute(\"type\")) == null || attr.toLowerCase() === \"text\" );\n\t\t},\n\n\t\t// Position-in-collection\n\t\t\"first\": createPositionalPseudo(function() {\n\t\t\treturn [ 0 ];\n\t\t}),\n\n\t\t\"last\": createPositionalPseudo(function( matchIndexes, length ) {\n\t\t\treturn [ length - 1 ];\n\t\t}),\n\n\t\t\"eq\": createPositionalPseudo(function( matchIndexes, length, argument ) {\n\t\t\treturn [ argument < 0 ? argument + length : argument ];\n\t\t}),\n\n\t\t\"even\": createPositionalPseudo(function( matchIndexes, length ) {\n\t\t\tvar i = 0;\n\t\t\tfor ( ; i < length; i += 2 ) {\n\t\t\t\tmatchIndexes.push( i );\n\t\t\t}\n\t\t\treturn matchIndexes;\n\t\t}),\n\n\t\t\"odd\": createPositionalPseudo(function( matchIndexes, length ) {\n\t\t\tvar i = 1;\n\t\t\tfor ( ; i < length; i += 2 ) {\n\t\t\t\tmatchIndexes.push( i );\n\t\t\t}\n\t\t\treturn matchIndexes;\n\t\t}),\n\n\t\t\"lt\": createPositionalPseudo(function( matchIndexes, length, argument ) {\n\t\t\tvar i = argument < 0 ? argument + length : argument;\n\t\t\tfor ( ; --i >= 0; ) {\n\t\t\t\tmatchIndexes.push( i );\n\t\t\t}\n\t\t\treturn matchIndexes;\n\t\t}),\n\n\t\t\"gt\": createPositionalPseudo(function( matchIndexes, length, argument ) {\n\t\t\tvar i = argument < 0 ? argument + length : argument;\n\t\t\tfor ( ; ++i < length; ) {\n\t\t\t\tmatchIndexes.push( i );\n\t\t\t}\n\t\t\treturn matchIndexes;\n\t\t})\n\t}\n};\n\nExpr.pseudos[\"nth\"] = Expr.pseudos[\"eq\"];\n\n// Add button/input type pseudos\nfor ( i in { radio: true, checkbox: true, file: true, password: true, image: true } ) {\n\tExpr.pseudos[ i ] = createInputPseudo( i );\n}\nfor ( i in { submit: true, reset: true } ) {\n\tExpr.pseudos[ i ] = createButtonPseudo( i );\n}\n\n// Easy API for creating new setFilters\nfunction setFilters() {}\nsetFilters.prototype = Expr.filters = Expr.pseudos;\nExpr.setFilters = new setFilters();\n\ntokenize = Sizzle.tokenize = function( selector, parseOnly ) {\n\tvar matched, match, tokens, type,\n\t\tsoFar, groups, preFilters,\n\t\tcached = tokenCache[ selector + \" \" ];\n\n\tif ( cached ) {\n\t\treturn parseOnly ? 0 : cached.slice( 0 );\n\t}\n\n\tsoFar = selector;\n\tgroups = [];\n\tpreFilters = Expr.preFilter;\n\n\twhile ( soFar ) {\n\n\t\t// Comma and first run\n\t\tif ( !matched || (match = rcomma.exec( soFar )) ) {\n\t\t\tif ( match ) {\n\t\t\t\t// Don't consume trailing commas as valid\n\t\t\t\tsoFar = soFar.slice( match[0].length ) || soFar;\n\t\t\t}\n\t\t\tgroups.push( (tokens = []) );\n\t\t}\n\n\t\tmatched = false;\n\n\t\t// Combinators\n\t\tif ( (match = rcombinators.exec( soFar )) ) {\n\t\t\tmatched = match.shift();\n\t\t\ttokens.push({\n\t\t\t\tvalue: matched,\n\t\t\t\t// Cast descendant combinators to space\n\t\t\t\ttype: match[0].replace( rtrim, \" \" )\n\t\t\t});\n\t\t\tsoFar = soFar.slice( matched.length );\n\t\t}\n\n\t\t// Filters\n\t\tfor ( type in Expr.filter ) {\n\t\t\tif ( (match = matchExpr[ type ].exec( soFar )) && (!preFilters[ type ] ||\n\t\t\t\t(match = preFilters[ type ]( match ))) ) {\n\t\t\t\tmatched = match.shift();\n\t\t\t\ttokens.push({\n\t\t\t\t\tvalue: matched,\n\t\t\t\t\ttype: type,\n\t\t\t\t\tmatches: match\n\t\t\t\t});\n\t\t\t\tsoFar = soFar.slice( matched.length );\n\t\t\t}\n\t\t}\n\n\t\tif ( !matched ) {\n\t\t\tbreak;\n\t\t}\n\t}\n\n\t// Return the length of the invalid excess\n\t// if we're just parsing\n\t// Otherwise, throw an error or return tokens\n\treturn parseOnly ?\n\t\tsoFar.length :\n\t\tsoFar ?\n\t\t\tSizzle.error( selector ) :\n\t\t\t// Cache the tokens\n\t\t\ttokenCache( selector, groups ).slice( 0 );\n};\n\nfunction toSelector( tokens ) {\n\tvar i = 0,\n\t\tlen = tokens.length,\n\t\tselector = \"\";\n\tfor ( ; i < len; i++ ) {\n\t\tselector += tokens[i].value;\n\t}\n\treturn selector;\n}\n\nfunction addCombinator( matcher, combinator, base ) {\n\tvar dir = combinator.dir,\n\t\tcheckNonElements = base && dir === \"parentNode\",\n\t\tdoneName = done++;\n\n\treturn combinator.first ?\n\t\t// Check against closest ancestor/preceding element\n\t\tfunction( elem, context, xml ) {\n\t\t\twhile ( (elem = elem[ dir ]) ) {\n\t\t\t\tif ( elem.nodeType === 1 || checkNonElements ) {\n\t\t\t\t\treturn matcher( elem, context, xml );\n\t\t\t\t}\n\t\t\t}\n\t\t} :\n\n\t\t// Check against all ancestor/preceding elements\n\t\tfunction( elem, context, xml ) {\n\t\t\tvar oldCache, outerCache,\n\t\t\t\tnewCache = [ dirruns, doneName ];\n\n\t\t\t// We can't set arbitrary data on XML nodes, so they don't benefit from dir caching\n\t\t\tif ( xml ) {\n\t\t\t\twhile ( (elem = elem[ dir ]) ) {\n\t\t\t\t\tif ( elem.nodeType === 1 || checkNonElements ) {\n\t\t\t\t\t\tif ( matcher( elem, context, xml ) ) {\n\t\t\t\t\t\t\treturn true;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\twhile ( (elem = elem[ dir ]) ) {\n\t\t\t\t\tif ( elem.nodeType === 1 || checkNonElements ) {\n\t\t\t\t\t\touterCache = elem[ expando ] || (elem[ expando ] = {});\n\t\t\t\t\t\tif ( (oldCache = outerCache[ dir ]) &&\n\t\t\t\t\t\t\toldCache[ 0 ] === dirruns && oldCache[ 1 ] === doneName ) {\n\n\t\t\t\t\t\t\t// Assign to newCache so results back-propagate to previous elements\n\t\t\t\t\t\t\treturn (newCache[ 2 ] = oldCache[ 2 ]);\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t// Reuse newcache so results back-propagate to previous elements\n\t\t\t\t\t\t\touterCache[ dir ] = newCache;\n\n\t\t\t\t\t\t\t// A match means we're done; a fail means we have to keep checking\n\t\t\t\t\t\t\tif ( (newCache[ 2 ] = matcher( elem, context, xml )) ) {\n\t\t\t\t\t\t\t\treturn true;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t};\n}\n\nfunction elementMatcher( matchers ) {\n\treturn matchers.length > 1 ?\n\t\tfunction( elem, context, xml ) {\n\t\t\tvar i = matchers.length;\n\t\t\twhile ( i-- ) {\n\t\t\t\tif ( !matchers[i]( elem, context, xml ) ) {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn true;\n\t\t} :\n\t\tmatchers[0];\n}\n\nfunction multipleContexts( selector, contexts, results ) {\n\tvar i = 0,\n\t\tlen = contexts.length;\n\tfor ( ; i < len; i++ ) {\n\t\tSizzle( selector, contexts[i], results );\n\t}\n\treturn results;\n}\n\nfunction condense( unmatched, map, filter, context, xml ) {\n\tvar elem,\n\t\tnewUnmatched = [],\n\t\ti = 0,\n\t\tlen = unmatched.length,\n\t\tmapped = map != null;\n\n\tfor ( ; i < len; i++ ) {\n\t\tif ( (elem = unmatched[i]) ) {\n\t\t\tif ( !filter || filter( elem, context, xml ) ) {\n\t\t\t\tnewUnmatched.push( elem );\n\t\t\t\tif ( mapped ) {\n\t\t\t\t\tmap.push( i );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\treturn newUnmatched;\n}\n\nfunction setMatcher( preFilter, selector, matcher, postFilter, postFinder, postSelector ) {\n\tif ( postFilter && !postFilter[ expando ] ) {\n\t\tpostFilter = setMatcher( postFilter );\n\t}\n\tif ( postFinder && !postFinder[ expando ] ) {\n\t\tpostFinder = setMatcher( postFinder, postSelector );\n\t}\n\treturn markFunction(function( seed, results, context, xml ) {\n\t\tvar temp, i, elem,\n\t\t\tpreMap = [],\n\t\t\tpostMap = [],\n\t\t\tpreexisting = results.length,\n\n\t\t\t// Get initial elements from seed or context\n\t\t\telems = seed || multipleContexts( selector || \"*\", context.nodeType ? [ context ] : context, [] ),\n\n\t\t\t// Prefilter to get matcher input, preserving a map for seed-results synchronization\n\t\t\tmatcherIn = preFilter && ( seed || !selector ) ?\n\t\t\t\tcondense( elems, preMap, preFilter, context, xml ) :\n\t\t\t\telems,\n\n\t\t\tmatcherOut = matcher ?\n\t\t\t\t// If we have a postFinder, or filtered seed, or non-seed postFilter or preexisting results,\n\t\t\t\tpostFinder || ( seed ? preFilter : preexisting || postFilter ) ?\n\n\t\t\t\t\t// ...intermediate processing is necessary\n\t\t\t\t\t[] :\n\n\t\t\t\t\t// ...otherwise use results directly\n\t\t\t\t\tresults :\n\t\t\t\tmatcherIn;\n\n\t\t// Find primary matches\n\t\tif ( matcher ) {\n\t\t\tmatcher( matcherIn, matcherOut, context, xml );\n\t\t}\n\n\t\t// Apply postFilter\n\t\tif ( postFilter ) {\n\t\t\ttemp = condense( matcherOut, postMap );\n\t\t\tpostFilter( temp, [], context, xml );\n\n\t\t\t// Un-match failing elements by moving them back to matcherIn\n\t\t\ti = temp.length;\n\t\t\twhile ( i-- ) {\n\t\t\t\tif ( (elem = temp[i]) ) {\n\t\t\t\t\tmatcherOut[ postMap[i] ] = !(matcherIn[ postMap[i] ] = elem);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif ( seed ) {\n\t\t\tif ( postFinder || preFilter ) {\n\t\t\t\tif ( postFinder ) {\n\t\t\t\t\t// Get the final matcherOut by condensing this intermediate into postFinder contexts\n\t\t\t\t\ttemp = [];\n\t\t\t\t\ti = matcherOut.length;\n\t\t\t\t\twhile ( i-- ) {\n\t\t\t\t\t\tif ( (elem = matcherOut[i]) ) {\n\t\t\t\t\t\t\t// Restore matcherIn since elem is not yet a final match\n\t\t\t\t\t\t\ttemp.push( (matcherIn[i] = elem) );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tpostFinder( null, (matcherOut = []), temp, xml );\n\t\t\t\t}\n\n\t\t\t\t// Move matched elements from seed to results to keep them synchronized\n\t\t\t\ti = matcherOut.length;\n\t\t\t\twhile ( i-- ) {\n\t\t\t\t\tif ( (elem = matcherOut[i]) &&\n\t\t\t\t\t\t(temp = postFinder ? indexOf( seed, elem ) : preMap[i]) > -1 ) {\n\n\t\t\t\t\t\tseed[temp] = !(results[temp] = elem);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t// Add elements to results, through postFinder if defined\n\t\t} else {\n\t\t\tmatcherOut = condense(\n\t\t\t\tmatcherOut === results ?\n\t\t\t\t\tmatcherOut.splice( preexisting, matcherOut.length ) :\n\t\t\t\t\tmatcherOut\n\t\t\t);\n\t\t\tif ( postFinder ) {\n\t\t\t\tpostFinder( null, results, matcherOut, xml );\n\t\t\t} else {\n\t\t\t\tpush.apply( results, matcherOut );\n\t\t\t}\n\t\t}\n\t});\n}\n\nfunction matcherFromTokens( tokens ) {\n\tvar checkContext, matcher, j,\n\t\tlen = tokens.length,\n\t\tleadingRelative = Expr.relative[ tokens[0].type ],\n\t\timplicitRelative = leadingRelative || Expr.relative[\" \"],\n\t\ti = leadingRelative ? 1 : 0,\n\n\t\t// The foundational matcher ensures that elements are reachable from top-level context(s)\n\t\tmatchContext = addCombinator( function( elem ) {\n\t\t\treturn elem === checkContext;\n\t\t}, implicitRelative, true ),\n\t\tmatchAnyContext = addCombinator( function( elem ) {\n\t\t\treturn indexOf( checkContext, elem ) > -1;\n\t\t}, implicitRelative, true ),\n\t\tmatchers = [ function( elem, context, xml ) {\n\t\t\tvar ret = ( !leadingRelative && ( xml || context !== outermostContext ) ) || (\n\t\t\t\t(checkContext = context).nodeType ?\n\t\t\t\t\tmatchContext( elem, context, xml ) :\n\t\t\t\t\tmatchAnyContext( elem, context, xml ) );\n\t\t\t// Avoid hanging onto element (issue #299)\n\t\t\tcheckContext = null;\n\t\t\treturn ret;\n\t\t} ];\n\n\tfor ( ; i < len; i++ ) {\n\t\tif ( (matcher = Expr.relative[ tokens[i].type ]) ) {\n\t\t\tmatchers = [ addCombinator(elementMatcher( matchers ), matcher) ];\n\t\t} else {\n\t\t\tmatcher = Expr.filter[ tokens[i].type ].apply( null, tokens[i].matches );\n\n\t\t\t// Return special upon seeing a positional matcher\n\t\t\tif ( matcher[ expando ] ) {\n\t\t\t\t// Find the next relative operator (if any) for proper handling\n\t\t\t\tj = ++i;\n\t\t\t\tfor ( ; j < len; j++ ) {\n\t\t\t\t\tif ( Expr.relative[ tokens[j].type ] ) {\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn setMatcher(\n\t\t\t\t\ti > 1 && elementMatcher( matchers ),\n\t\t\t\t\ti > 1 && toSelector(\n\t\t\t\t\t\t// If the preceding token was a descendant combinator, insert an implicit any-element `*`\n\t\t\t\t\t\ttokens.slice( 0, i - 1 ).concat({ value: tokens[ i - 2 ].type === \" \" ? \"*\" : \"\" })\n\t\t\t\t\t).replace( rtrim, \"$1\" ),\n\t\t\t\t\tmatcher,\n\t\t\t\t\ti < j && matcherFromTokens( tokens.slice( i, j ) ),\n\t\t\t\t\tj < len && matcherFromTokens( (tokens = tokens.slice( j )) ),\n\t\t\t\t\tj < len && toSelector( tokens )\n\t\t\t\t);\n\t\t\t}\n\t\t\tmatchers.push( matcher );\n\t\t}\n\t}\n\n\treturn elementMatcher( matchers );\n}\n\nfunction matcherFromGroupMatchers( elementMatchers, setMatchers ) {\n\tvar bySet = setMatchers.length > 0,\n\t\tbyElement = elementMatchers.length > 0,\n\t\tsuperMatcher = function( seed, context, xml, results, outermost ) {\n\t\t\tvar elem, j, matcher,\n\t\t\t\tmatchedCount = 0,\n\t\t\t\ti = \"0\",\n\t\t\t\tunmatched = seed && [],\n\t\t\t\tsetMatched = [],\n\t\t\t\tcontextBackup = outermostContext,\n\t\t\t\t// We must always have either seed elements or outermost context\n\t\t\t\telems = seed || byElement && Expr.find[\"TAG\"]( \"*\", outermost ),\n\t\t\t\t// Use integer dirruns iff this is the outermost matcher\n\t\t\t\tdirrunsUnique = (dirruns += contextBackup == null ? 1 : Math.random() || 0.1),\n\t\t\t\tlen = elems.length;\n\n\t\t\tif ( outermost ) {\n\t\t\t\toutermostContext = context !== document && context;\n\t\t\t}\n\n\t\t\t// Add elements passing elementMatchers directly to results\n\t\t\t// Keep `i` a string if there are no elements so `matchedCount` will be \"00\" below\n\t\t\t// Support: IE<9, Safari\n\t\t\t// Tolerate NodeList properties (IE: \"length\"; Safari: <number>) matching elements by id\n\t\t\tfor ( ; i !== len && (elem = elems[i]) != null; i++ ) {\n\t\t\t\tif ( byElement && elem ) {\n\t\t\t\t\tj = 0;\n\t\t\t\t\twhile ( (matcher = elementMatchers[j++]) ) {\n\t\t\t\t\t\tif ( matcher( elem, context, xml ) ) {\n\t\t\t\t\t\t\tresults.push( elem );\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tif ( outermost ) {\n\t\t\t\t\t\tdirruns = dirrunsUnique;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// Track unmatched elements for set filters\n\t\t\t\tif ( bySet ) {\n\t\t\t\t\t// They will have gone through all possible matchers\n\t\t\t\t\tif ( (elem = !matcher && elem) ) {\n\t\t\t\t\t\tmatchedCount--;\n\t\t\t\t\t}\n\n\t\t\t\t\t// Lengthen the array for every element, matched or not\n\t\t\t\t\tif ( seed ) {\n\t\t\t\t\t\tunmatched.push( elem );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Apply set filters to unmatched elements\n\t\t\tmatchedCount += i;\n\t\t\tif ( bySet && i !== matchedCount ) {\n\t\t\t\tj = 0;\n\t\t\t\twhile ( (matcher = setMatchers[j++]) ) {\n\t\t\t\t\tmatcher( unmatched, setMatched, context, xml );\n\t\t\t\t}\n\n\t\t\t\tif ( seed ) {\n\t\t\t\t\t// Reintegrate element matches to eliminate the need for sorting\n\t\t\t\t\tif ( matchedCount > 0 ) {\n\t\t\t\t\t\twhile ( i-- ) {\n\t\t\t\t\t\t\tif ( !(unmatched[i] || setMatched[i]) ) {\n\t\t\t\t\t\t\t\tsetMatched[i] = pop.call( results );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\t// Discard index placeholder values to get only actual matches\n\t\t\t\t\tsetMatched = condense( setMatched );\n\t\t\t\t}\n\n\t\t\t\t// Add matches to results\n\t\t\t\tpush.apply( results, setMatched );\n\n\t\t\t\t// Seedless set matches succeeding multiple successful matchers stipulate sorting\n\t\t\t\tif ( outermost && !seed && setMatched.length > 0 &&\n\t\t\t\t\t( matchedCount + setMatchers.length ) > 1 ) {\n\n\t\t\t\t\tSizzle.uniqueSort( results );\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Override manipulation of globals by nested matchers\n\t\t\tif ( outermost ) {\n\t\t\t\tdirruns = dirrunsUnique;\n\t\t\t\toutermostContext = contextBackup;\n\t\t\t}\n\n\t\t\treturn unmatched;\n\t\t};\n\n\treturn bySet ?\n\t\tmarkFunction( superMatcher ) :\n\t\tsuperMatcher;\n}\n\ncompile = Sizzle.compile = function( selector, match /* Internal Use Only */ ) {\n\tvar i,\n\t\tsetMatchers = [],\n\t\telementMatchers = [],\n\t\tcached = compilerCache[ selector + \" \" ];\n\n\tif ( !cached ) {\n\t\t// Generate a function of recursive functions that can be used to check each element\n\t\tif ( !match ) {\n\t\t\tmatch = tokenize( selector );\n\t\t}\n\t\ti = match.length;\n\t\twhile ( i-- ) {\n\t\t\tcached = matcherFromTokens( match[i] );\n\t\t\tif ( cached[ expando ] ) {\n\t\t\t\tsetMatchers.push( cached );\n\t\t\t} else {\n\t\t\t\telementMatchers.push( cached );\n\t\t\t}\n\t\t}\n\n\t\t// Cache the compiled function\n\t\tcached = compilerCache( selector, matcherFromGroupMatchers( elementMatchers, setMatchers ) );\n\n\t\t// Save selector and tokenization\n\t\tcached.selector = selector;\n\t}\n\treturn cached;\n};\n\n/**\n * A low-level selection function that works with Sizzle's compiled\n *  selector functions\n * @param {String|Function} selector A selector or a pre-compiled\n *  selector function built with Sizzle.compile\n * @param {Element} context\n * @param {Array} [results]\n * @param {Array} [seed] A set of elements to match against\n */\nselect = Sizzle.select = function( selector, context, results, seed ) {\n\tvar i, tokens, token, type, find,\n\t\tcompiled = typeof selector === \"function\" && selector,\n\t\tmatch = !seed && tokenize( (selector = compiled.selector || selector) );\n\n\tresults = results || [];\n\n\t// Try to minimize operations if there is no seed and only one group\n\tif ( match.length === 1 ) {\n\n\t\t// Take a shortcut and set the context if the root selector is an ID\n\t\ttokens = match[0] = match[0].slice( 0 );\n\t\tif ( tokens.length > 2 && (token = tokens[0]).type === \"ID\" &&\n\t\t\t\tsupport.getById && context.nodeType === 9 && documentIsHTML &&\n\t\t\t\tExpr.relative[ tokens[1].type ] ) {\n\n\t\t\tcontext = ( Expr.find[\"ID\"]( token.matches[0].replace(runescape, funescape), context ) || [] )[0];\n\t\t\tif ( !context ) {\n\t\t\t\treturn results;\n\n\t\t\t// Precompiled matchers will still verify ancestry, so step up a level\n\t\t\t} else if ( compiled ) {\n\t\t\t\tcontext = context.parentNode;\n\t\t\t}\n\n\t\t\tselector = selector.slice( tokens.shift().value.length );\n\t\t}\n\n\t\t// Fetch a seed set for right-to-left matching\n\t\ti = matchExpr[\"needsContext\"].test( selector ) ? 0 : tokens.length;\n\t\twhile ( i-- ) {\n\t\t\ttoken = tokens[i];\n\n\t\t\t// Abort if we hit a combinator\n\t\t\tif ( Expr.relative[ (type = token.type) ] ) {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tif ( (find = Expr.find[ type ]) ) {\n\t\t\t\t// Search, expanding context for leading sibling combinators\n\t\t\t\tif ( (seed = find(\n\t\t\t\t\ttoken.matches[0].replace( runescape, funescape ),\n\t\t\t\t\trsibling.test( tokens[0].type ) && testContext( context.parentNode ) || context\n\t\t\t\t)) ) {\n\n\t\t\t\t\t// If seed is empty or no tokens remain, we can return early\n\t\t\t\t\ttokens.splice( i, 1 );\n\t\t\t\t\tselector = seed.length && toSelector( tokens );\n\t\t\t\t\tif ( !selector ) {\n\t\t\t\t\t\tpush.apply( results, seed );\n\t\t\t\t\t\treturn results;\n\t\t\t\t\t}\n\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t// Compile and execute a filtering function if one is not provided\n\t// Provide `match` to avoid retokenization if we modified the selector above\n\t( compiled || compile( selector, match ) )(\n\t\tseed,\n\t\tcontext,\n\t\t!documentIsHTML,\n\t\tresults,\n\t\trsibling.test( selector ) && testContext( context.parentNode ) || context\n\t);\n\treturn results;\n};\n\n// One-time assignments\n\n// Sort stability\nsupport.sortStable = expando.split(\"\").sort( sortOrder ).join(\"\") === expando;\n\n// Support: Chrome 14-35+\n// Always assume duplicates if they aren't passed to the comparison function\nsupport.detectDuplicates = !!hasDuplicate;\n\n// Initialize against the default document\nsetDocument();\n\n// Support: Webkit<537.32 - Safari 6.0.3/Chrome 25 (fixed in Chrome 27)\n// Detached nodes confoundingly follow *each other*\nsupport.sortDetached = assert(function( div1 ) {\n\t// Should return 1, but returns 4 (following)\n\treturn div1.compareDocumentPosition( document.createElement(\"div\") ) & 1;\n});\n\n// Support: IE<8\n// Prevent attribute/property \"interpolation\"\n// http://msdn.microsoft.com/en-us/library/ms536429%28VS.85%29.aspx\nif ( !assert(function( div ) {\n\tdiv.innerHTML = \"<a href='#'></a>\";\n\treturn div.firstChild.getAttribute(\"href\") === \"#\" ;\n}) ) {\n\taddHandle( \"type|href|height|width\", function( elem, name, isXML ) {\n\t\tif ( !isXML ) {\n\t\t\treturn elem.getAttribute( name, name.toLowerCase() === \"type\" ? 1 : 2 );\n\t\t}\n\t});\n}\n\n// Support: IE<9\n// Use defaultValue in place of getAttribute(\"value\")\nif ( !support.attributes || !assert(function( div ) {\n\tdiv.innerHTML = \"<input/>\";\n\tdiv.firstChild.setAttribute( \"value\", \"\" );\n\treturn div.firstChild.getAttribute( \"value\" ) === \"\";\n}) ) {\n\taddHandle( \"value\", function( elem, name, isXML ) {\n\t\tif ( !isXML && elem.nodeName.toLowerCase() === \"input\" ) {\n\t\t\treturn elem.defaultValue;\n\t\t}\n\t});\n}\n\n// Support: IE<9\n// Use getAttributeNode to fetch booleans when getAttribute lies\nif ( !assert(function( div ) {\n\treturn div.getAttribute(\"disabled\") == null;\n}) ) {\n\taddHandle( booleans, function( elem, name, isXML ) {\n\t\tvar val;\n\t\tif ( !isXML ) {\n\t\t\treturn elem[ name ] === true ? name.toLowerCase() :\n\t\t\t\t\t(val = elem.getAttributeNode( name )) && val.specified ?\n\t\t\t\t\tval.value :\n\t\t\t\tnull;\n\t\t}\n\t});\n}\n\nreturn Sizzle;\n\n})( window );\n\n\n\njQuery.find = Sizzle;\njQuery.expr = Sizzle.selectors;\njQuery.expr[\":\"] = jQuery.expr.pseudos;\njQuery.unique = Sizzle.uniqueSort;\njQuery.text = Sizzle.getText;\njQuery.isXMLDoc = Sizzle.isXML;\njQuery.contains = Sizzle.contains;\n\n\n\nvar rneedsContext = jQuery.expr.match.needsContext;\n\nvar rsingleTag = (/^<(\\w+)\\s*\\/?>(?:<\\/\\1>|)$/);\n\n\n\nvar risSimple = /^.[^:#\\[\\.,]*$/;\n\n// Implement the identical functionality for filter and not\nfunction winnow( elements, qualifier, not ) {\n\tif ( jQuery.isFunction( qualifier ) ) {\n\t\treturn jQuery.grep( elements, function( elem, i ) {\n\t\t\t/* jshint -W018 */\n\t\t\treturn !!qualifier.call( elem, i, elem ) !== not;\n\t\t});\n\n\t}\n\n\tif ( qualifier.nodeType ) {\n\t\treturn jQuery.grep( elements, function( elem ) {\n\t\t\treturn ( elem === qualifier ) !== not;\n\t\t});\n\n\t}\n\n\tif ( typeof qualifier === \"string\" ) {\n\t\tif ( risSimple.test( qualifier ) ) {\n\t\t\treturn jQuery.filter( qualifier, elements, not );\n\t\t}\n\n\t\tqualifier = jQuery.filter( qualifier, elements );\n\t}\n\n\treturn jQuery.grep( elements, function( elem ) {\n\t\treturn ( jQuery.inArray( elem, qualifier ) >= 0 ) !== not;\n\t});\n}\n\njQuery.filter = function( expr, elems, not ) {\n\tvar elem = elems[ 0 ];\n\n\tif ( not ) {\n\t\texpr = \":not(\" + expr + \")\";\n\t}\n\n\treturn elems.length === 1 && elem.nodeType === 1 ?\n\t\tjQuery.find.matchesSelector( elem, expr ) ? [ elem ] : [] :\n\t\tjQuery.find.matches( expr, jQuery.grep( elems, function( elem ) {\n\t\t\treturn elem.nodeType === 1;\n\t\t}));\n};\n\njQuery.fn.extend({\n\tfind: function( selector ) {\n\t\tvar i,\n\t\t\tret = [],\n\t\t\tself = this,\n\t\t\tlen = self.length;\n\n\t\tif ( typeof selector !== \"string\" ) {\n\t\t\treturn this.pushStack( jQuery( selector ).filter(function() {\n\t\t\t\tfor ( i = 0; i < len; i++ ) {\n\t\t\t\t\tif ( jQuery.contains( self[ i ], this ) ) {\n\t\t\t\t\t\treturn true;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}) );\n\t\t}\n\n\t\tfor ( i = 0; i < len; i++ ) {\n\t\t\tjQuery.find( selector, self[ i ], ret );\n\t\t}\n\n\t\t// Needed because $( selector, context ) becomes $( context ).find( selector )\n\t\tret = this.pushStack( len > 1 ? jQuery.unique( ret ) : ret );\n\t\tret.selector = this.selector ? this.selector + \" \" + selector : selector;\n\t\treturn ret;\n\t},\n\tfilter: function( selector ) {\n\t\treturn this.pushStack( winnow(this, selector || [], false) );\n\t},\n\tnot: function( selector ) {\n\t\treturn this.pushStack( winnow(this, selector || [], true) );\n\t},\n\tis: function( selector ) {\n\t\treturn !!winnow(\n\t\t\tthis,\n\n\t\t\t// If this is a positional/relative selector, check membership in the returned set\n\t\t\t// so $(\"p:first\").is(\"p:last\") won't return true for a doc with two \"p\".\n\t\t\ttypeof selector === \"string\" && rneedsContext.test( selector ) ?\n\t\t\t\tjQuery( selector ) :\n\t\t\t\tselector || [],\n\t\t\tfalse\n\t\t).length;\n\t}\n});\n\n\n// Initialize a jQuery object\n\n\n// A central reference to the root jQuery(document)\nvar rootjQuery,\n\n\t// Use the correct document accordingly with window argument (sandbox)\n\tdocument = window.document,\n\n\t// A simple way to check for HTML strings\n\t// Prioritize #id over <tag> to avoid XSS via location.hash (#9521)\n\t// Strict HTML recognition (#11290: must start with <)\n\trquickExpr = /^(?:\\s*(<[\\w\\W]+>)[^>]*|#([\\w-]*))$/,\n\n\tinit = jQuery.fn.init = function( selector, context ) {\n\t\tvar match, elem;\n\n\t\t// HANDLE: $(\"\"), $(null), $(undefined), $(false)\n\t\tif ( !selector ) {\n\t\t\treturn this;\n\t\t}\n\n\t\t// Handle HTML strings\n\t\tif ( typeof selector === \"string\" ) {\n\t\t\tif ( selector.charAt(0) === \"<\" && selector.charAt( selector.length - 1 ) === \">\" && selector.length >= 3 ) {\n\t\t\t\t// Assume that strings that start and end with <> are HTML and skip the regex check\n\t\t\t\tmatch = [ null, selector, null ];\n\n\t\t\t} else {\n\t\t\t\tmatch = rquickExpr.exec( selector );\n\t\t\t}\n\n\t\t\t// Match html or make sure no context is specified for #id\n\t\t\tif ( match && (match[1] || !context) ) {\n\n\t\t\t\t// HANDLE: $(html) -> $(array)\n\t\t\t\tif ( match[1] ) {\n\t\t\t\t\tcontext = context instanceof jQuery ? context[0] : context;\n\n\t\t\t\t\t// scripts is true for back-compat\n\t\t\t\t\t// Intentionally let the error be thrown if parseHTML is not present\n\t\t\t\t\tjQuery.merge( this, jQuery.parseHTML(\n\t\t\t\t\t\tmatch[1],\n\t\t\t\t\t\tcontext && context.nodeType ? context.ownerDocument || context : document,\n\t\t\t\t\t\ttrue\n\t\t\t\t\t) );\n\n\t\t\t\t\t// HANDLE: $(html, props)\n\t\t\t\t\tif ( rsingleTag.test( match[1] ) && jQuery.isPlainObject( context ) ) {\n\t\t\t\t\t\tfor ( match in context ) {\n\t\t\t\t\t\t\t// Properties of context are called as methods if possible\n\t\t\t\t\t\t\tif ( jQuery.isFunction( this[ match ] ) ) {\n\t\t\t\t\t\t\t\tthis[ match ]( context[ match ] );\n\n\t\t\t\t\t\t\t// ...and otherwise set as attributes\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tthis.attr( match, context[ match ] );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\treturn this;\n\n\t\t\t\t// HANDLE: $(#id)\n\t\t\t\t} else {\n\t\t\t\t\telem = document.getElementById( match[2] );\n\n\t\t\t\t\t// Check parentNode to catch when Blackberry 4.6 returns\n\t\t\t\t\t// nodes that are no longer in the document #6963\n\t\t\t\t\tif ( elem && elem.parentNode ) {\n\t\t\t\t\t\t// Handle the case where IE and Opera return items\n\t\t\t\t\t\t// by name instead of ID\n\t\t\t\t\t\tif ( elem.id !== match[2] ) {\n\t\t\t\t\t\t\treturn rootjQuery.find( selector );\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// Otherwise, we inject the element directly into the jQuery object\n\t\t\t\t\t\tthis.length = 1;\n\t\t\t\t\t\tthis[0] = elem;\n\t\t\t\t\t}\n\n\t\t\t\t\tthis.context = document;\n\t\t\t\t\tthis.selector = selector;\n\t\t\t\t\treturn this;\n\t\t\t\t}\n\n\t\t\t// HANDLE: $(expr, $(...))\n\t\t\t} else if ( !context || context.jquery ) {\n\t\t\t\treturn ( context || rootjQuery ).find( selector );\n\n\t\t\t// HANDLE: $(expr, context)\n\t\t\t// (which is just equivalent to: $(context).find(expr)\n\t\t\t} else {\n\t\t\t\treturn this.constructor( context ).find( selector );\n\t\t\t}\n\n\t\t// HANDLE: $(DOMElement)\n\t\t} else if ( selector.nodeType ) {\n\t\t\tthis.context = this[0] = selector;\n\t\t\tthis.length = 1;\n\t\t\treturn this;\n\n\t\t// HANDLE: $(function)\n\t\t// Shortcut for document ready\n\t\t} else if ( jQuery.isFunction( selector ) ) {\n\t\t\treturn typeof rootjQuery.ready !== \"undefined\" ?\n\t\t\t\trootjQuery.ready( selector ) :\n\t\t\t\t// Execute immediately if ready is not present\n\t\t\t\tselector( jQuery );\n\t\t}\n\n\t\tif ( selector.selector !== undefined ) {\n\t\t\tthis.selector = selector.selector;\n\t\t\tthis.context = selector.context;\n\t\t}\n\n\t\treturn jQuery.makeArray( selector, this );\n\t};\n\n// Give the init function the jQuery prototype for later instantiation\ninit.prototype = jQuery.fn;\n\n// Initialize central reference\nrootjQuery = jQuery( document );\n\n\nvar rparentsprev = /^(?:parents|prev(?:Until|All))/,\n\t// methods guaranteed to produce a unique set when starting from a unique set\n\tguaranteedUnique = {\n\t\tchildren: true,\n\t\tcontents: true,\n\t\tnext: true,\n\t\tprev: true\n\t};\n\njQuery.extend({\n\tdir: function( elem, dir, until ) {\n\t\tvar matched = [],\n\t\t\tcur = elem[ dir ];\n\n\t\twhile ( cur && cur.nodeType !== 9 && (until === undefined || cur.nodeType !== 1 || !jQuery( cur ).is( until )) ) {\n\t\t\tif ( cur.nodeType === 1 ) {\n\t\t\t\tmatched.push( cur );\n\t\t\t}\n\t\t\tcur = cur[dir];\n\t\t}\n\t\treturn matched;\n\t},\n\n\tsibling: function( n, elem ) {\n\t\tvar r = [];\n\n\t\tfor ( ; n; n = n.nextSibling ) {\n\t\t\tif ( n.nodeType === 1 && n !== elem ) {\n\t\t\t\tr.push( n );\n\t\t\t}\n\t\t}\n\n\t\treturn r;\n\t}\n});\n\njQuery.fn.extend({\n\thas: function( target ) {\n\t\tvar i,\n\t\t\ttargets = jQuery( target, this ),\n\t\t\tlen = targets.length;\n\n\t\treturn this.filter(function() {\n\t\t\tfor ( i = 0; i < len; i++ ) {\n\t\t\t\tif ( jQuery.contains( this, targets[i] ) ) {\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\t},\n\n\tclosest: function( selectors, context ) {\n\t\tvar cur,\n\t\t\ti = 0,\n\t\t\tl = this.length,\n\t\t\tmatched = [],\n\t\t\tpos = rneedsContext.test( selectors ) || typeof selectors !== \"string\" ?\n\t\t\t\tjQuery( selectors, context || this.context ) :\n\t\t\t\t0;\n\n\t\tfor ( ; i < l; i++ ) {\n\t\t\tfor ( cur = this[i]; cur && cur !== context; cur = cur.parentNode ) {\n\t\t\t\t// Always skip document fragments\n\t\t\t\tif ( cur.nodeType < 11 && (pos ?\n\t\t\t\t\tpos.index(cur) > -1 :\n\n\t\t\t\t\t// Don't pass non-elements to Sizzle\n\t\t\t\t\tcur.nodeType === 1 &&\n\t\t\t\t\t\tjQuery.find.matchesSelector(cur, selectors)) ) {\n\n\t\t\t\t\tmatched.push( cur );\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn this.pushStack( matched.length > 1 ? jQuery.unique( matched ) : matched );\n\t},\n\n\t// Determine the position of an element within\n\t// the matched set of elements\n\tindex: function( elem ) {\n\n\t\t// No argument, return index in parent\n\t\tif ( !elem ) {\n\t\t\treturn ( this[0] && this[0].parentNode ) ? this.first().prevAll().length : -1;\n\t\t}\n\n\t\t// index in selector\n\t\tif ( typeof elem === \"string\" ) {\n\t\t\treturn jQuery.inArray( this[0], jQuery( elem ) );\n\t\t}\n\n\t\t// Locate the position of the desired element\n\t\treturn jQuery.inArray(\n\t\t\t// If it receives a jQuery object, the first element is used\n\t\t\telem.jquery ? elem[0] : elem, this );\n\t},\n\n\tadd: function( selector, context ) {\n\t\treturn this.pushStack(\n\t\t\tjQuery.unique(\n\t\t\t\tjQuery.merge( this.get(), jQuery( selector, context ) )\n\t\t\t)\n\t\t);\n\t},\n\n\taddBack: function( selector ) {\n\t\treturn this.add( selector == null ?\n\t\t\tthis.prevObject : this.prevObject.filter(selector)\n\t\t);\n\t}\n});\n\nfunction sibling( cur, dir ) {\n\tdo {\n\t\tcur = cur[ dir ];\n\t} while ( cur && cur.nodeType !== 1 );\n\n\treturn cur;\n}\n\njQuery.each({\n\tparent: function( elem ) {\n\t\tvar parent = elem.parentNode;\n\t\treturn parent && parent.nodeType !== 11 ? parent : null;\n\t},\n\tparents: function( elem ) {\n\t\treturn jQuery.dir( elem, \"parentNode\" );\n\t},\n\tparentsUntil: function( elem, i, until ) {\n\t\treturn jQuery.dir( elem, \"parentNode\", until );\n\t},\n\tnext: function( elem ) {\n\t\treturn sibling( elem, \"nextSibling\" );\n\t},\n\tprev: function( elem ) {\n\t\treturn sibling( elem, \"previousSibling\" );\n\t},\n\tnextAll: function( elem ) {\n\t\treturn jQuery.dir( elem, \"nextSibling\" );\n\t},\n\tprevAll: function( elem ) {\n\t\treturn jQuery.dir( elem, \"previousSibling\" );\n\t},\n\tnextUntil: function( elem, i, until ) {\n\t\treturn jQuery.dir( elem, \"nextSibling\", until );\n\t},\n\tprevUntil: function( elem, i, until ) {\n\t\treturn jQuery.dir( elem, \"previousSibling\", until );\n\t},\n\tsiblings: function( elem ) {\n\t\treturn jQuery.sibling( ( elem.parentNode || {} ).firstChild, elem );\n\t},\n\tchildren: function( elem ) {\n\t\treturn jQuery.sibling( elem.firstChild );\n\t},\n\tcontents: function( elem ) {\n\t\treturn jQuery.nodeName( elem, \"iframe\" ) ?\n\t\t\telem.contentDocument || elem.contentWindow.document :\n\t\t\tjQuery.merge( [], elem.childNodes );\n\t}\n}, function( name, fn ) {\n\tjQuery.fn[ name ] = function( until, selector ) {\n\t\tvar ret = jQuery.map( this, fn, until );\n\n\t\tif ( name.slice( -5 ) !== \"Until\" ) {\n\t\t\tselector = until;\n\t\t}\n\n\t\tif ( selector && typeof selector === \"string\" ) {\n\t\t\tret = jQuery.filter( selector, ret );\n\t\t}\n\n\t\tif ( this.length > 1 ) {\n\t\t\t// Remove duplicates\n\t\t\tif ( !guaranteedUnique[ name ] ) {\n\t\t\t\tret = jQuery.unique( ret );\n\t\t\t}\n\n\t\t\t// Reverse order for parents* and prev-derivatives\n\t\t\tif ( rparentsprev.test( name ) ) {\n\t\t\t\tret = ret.reverse();\n\t\t\t}\n\t\t}\n\n\t\treturn this.pushStack( ret );\n\t};\n});\nvar rnotwhite = (/\\S+/g);\n\n\n\n// String to Object options format cache\nvar optionsCache = {};\n\n// Convert String-formatted options into Object-formatted ones and store in cache\nfunction createOptions( options ) {\n\tvar object = optionsCache[ options ] = {};\n\tjQuery.each( options.match( rnotwhite ) || [], function( _, flag ) {\n\t\tobject[ flag ] = true;\n\t});\n\treturn object;\n}\n\n/*\n * Create a callback list using the following parameters:\n *\n *\toptions: an optional list of space-separated options that will change how\n *\t\t\tthe callback list behaves or a more traditional option object\n *\n * By default a callback list will act like an event callback list and can be\n * \"fired\" multiple times.\n *\n * Possible options:\n *\n *\tonce:\t\t\twill ensure the callback list can only be fired once (like a Deferred)\n *\n *\tmemory:\t\t\twill keep track of previous values and will call any callback added\n *\t\t\t\t\tafter the list has been fired right away with the latest \"memorized\"\n *\t\t\t\t\tvalues (like a Deferred)\n *\n *\tunique:\t\t\twill ensure a callback can only be added once (no duplicate in the list)\n *\n *\tstopOnFalse:\tinterrupt callings when a callback returns false\n *\n */\njQuery.Callbacks = function( options ) {\n\n\t// Convert options from String-formatted to Object-formatted if needed\n\t// (we check in cache first)\n\toptions = typeof options === \"string\" ?\n\t\t( optionsCache[ options ] || createOptions( options ) ) :\n\t\tjQuery.extend( {}, options );\n\n\tvar // Flag to know if list is currently firing\n\t\tfiring,\n\t\t// Last fire value (for non-forgettable lists)\n\t\tmemory,\n\t\t// Flag to know if list was already fired\n\t\tfired,\n\t\t// End of the loop when firing\n\t\tfiringLength,\n\t\t// Index of currently firing callback (modified by remove if needed)\n\t\tfiringIndex,\n\t\t// First callback to fire (used internally by add and fireWith)\n\t\tfiringStart,\n\t\t// Actual callback list\n\t\tlist = [],\n\t\t// Stack of fire calls for repeatable lists\n\t\tstack = !options.once && [],\n\t\t// Fire callbacks\n\t\tfire = function( data ) {\n\t\t\tmemory = options.memory && data;\n\t\t\tfired = true;\n\t\t\tfiringIndex = firingStart || 0;\n\t\t\tfiringStart = 0;\n\t\t\tfiringLength = list.length;\n\t\t\tfiring = true;\n\t\t\tfor ( ; list && firingIndex < firingLength; firingIndex++ ) {\n\t\t\t\tif ( list[ firingIndex ].apply( data[ 0 ], data[ 1 ] ) === false && options.stopOnFalse ) {\n\t\t\t\t\tmemory = false; // To prevent further calls using add\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t\tfiring = false;\n\t\t\tif ( list ) {\n\t\t\t\tif ( stack ) {\n\t\t\t\t\tif ( stack.length ) {\n\t\t\t\t\t\tfire( stack.shift() );\n\t\t\t\t\t}\n\t\t\t\t} else if ( memory ) {\n\t\t\t\t\tlist = [];\n\t\t\t\t} else {\n\t\t\t\t\tself.disable();\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\t// Actual Callbacks object\n\t\tself = {\n\t\t\t// Add a callback or a collection of callbacks to the list\n\t\t\tadd: function() {\n\t\t\t\tif ( list ) {\n\t\t\t\t\t// First, we save the current length\n\t\t\t\t\tvar start = list.length;\n\t\t\t\t\t(function add( args ) {\n\t\t\t\t\t\tjQuery.each( args, function( _, arg ) {\n\t\t\t\t\t\t\tvar type = jQuery.type( arg );\n\t\t\t\t\t\t\tif ( type === \"function\" ) {\n\t\t\t\t\t\t\t\tif ( !options.unique || !self.has( arg ) ) {\n\t\t\t\t\t\t\t\t\tlist.push( arg );\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t} else if ( arg && arg.length && type !== \"string\" ) {\n\t\t\t\t\t\t\t\t// Inspect recursively\n\t\t\t\t\t\t\t\tadd( arg );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t});\n\t\t\t\t\t})( arguments );\n\t\t\t\t\t// Do we need to add the callbacks to the\n\t\t\t\t\t// current firing batch?\n\t\t\t\t\tif ( firing ) {\n\t\t\t\t\t\tfiringLength = list.length;\n\t\t\t\t\t// With memory, if we're not firing then\n\t\t\t\t\t// we should call right away\n\t\t\t\t\t} else if ( memory ) {\n\t\t\t\t\t\tfiringStart = start;\n\t\t\t\t\t\tfire( memory );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn this;\n\t\t\t},\n\t\t\t// Remove a callback from the list\n\t\t\tremove: function() {\n\t\t\t\tif ( list ) {\n\t\t\t\t\tjQuery.each( arguments, function( _, arg ) {\n\t\t\t\t\t\tvar index;\n\t\t\t\t\t\twhile ( ( index = jQuery.inArray( arg, list, index ) ) > -1 ) {\n\t\t\t\t\t\t\tlist.splice( index, 1 );\n\t\t\t\t\t\t\t// Handle firing indexes\n\t\t\t\t\t\t\tif ( firing ) {\n\t\t\t\t\t\t\t\tif ( index <= firingLength ) {\n\t\t\t\t\t\t\t\t\tfiringLength--;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tif ( index <= firingIndex ) {\n\t\t\t\t\t\t\t\t\tfiringIndex--;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t\treturn this;\n\t\t\t},\n\t\t\t// Check if a given callback is in the list.\n\t\t\t// If no argument is given, return whether or not list has callbacks attached.\n\t\t\thas: function( fn ) {\n\t\t\t\treturn fn ? jQuery.inArray( fn, list ) > -1 : !!( list && list.length );\n\t\t\t},\n\t\t\t// Remove all callbacks from the list\n\t\t\tempty: function() {\n\t\t\t\tlist = [];\n\t\t\t\tfiringLength = 0;\n\t\t\t\treturn this;\n\t\t\t},\n\t\t\t// Have the list do nothing anymore\n\t\t\tdisable: function() {\n\t\t\t\tlist = stack = memory = undefined;\n\t\t\t\treturn this;\n\t\t\t},\n\t\t\t// Is it disabled?\n\t\t\tdisabled: function() {\n\t\t\t\treturn !list;\n\t\t\t},\n\t\t\t// Lock the list in its current state\n\t\t\tlock: function() {\n\t\t\t\tstack = undefined;\n\t\t\t\tif ( !memory ) {\n\t\t\t\t\tself.disable();\n\t\t\t\t}\n\t\t\t\treturn this;\n\t\t\t},\n\t\t\t// Is it locked?\n\t\t\tlocked: function() {\n\t\t\t\treturn !stack;\n\t\t\t},\n\t\t\t// Call all callbacks with the given context and arguments\n\t\t\tfireWith: function( context, args ) {\n\t\t\t\tif ( list && ( !fired || stack ) ) {\n\t\t\t\t\targs = args || [];\n\t\t\t\t\targs = [ context, args.slice ? args.slice() : args ];\n\t\t\t\t\tif ( firing ) {\n\t\t\t\t\t\tstack.push( args );\n\t\t\t\t\t} else {\n\t\t\t\t\t\tfire( args );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn this;\n\t\t\t},\n\t\t\t// Call all the callbacks with the given arguments\n\t\t\tfire: function() {\n\t\t\t\tself.fireWith( this, arguments );\n\t\t\t\treturn this;\n\t\t\t},\n\t\t\t// To know if the callbacks have already been called at least once\n\t\t\tfired: function() {\n\t\t\t\treturn !!fired;\n\t\t\t}\n\t\t};\n\n\treturn self;\n};\n\n\njQuery.extend({\n\n\tDeferred: function( func ) {\n\t\tvar tuples = [\n\t\t\t\t// action, add listener, listener list, final state\n\t\t\t\t[ \"resolve\", \"done\", jQuery.Callbacks(\"once memory\"), \"resolved\" ],\n\t\t\t\t[ \"reject\", \"fail\", jQuery.Callbacks(\"once memory\"), \"rejected\" ],\n\t\t\t\t[ \"notify\", \"progress\", jQuery.Callbacks(\"memory\") ]\n\t\t\t],\n\t\t\tstate = \"pending\",\n\t\t\tpromise = {\n\t\t\t\tstate: function() {\n\t\t\t\t\treturn state;\n\t\t\t\t},\n\t\t\t\talways: function() {\n\t\t\t\t\tdeferred.done( arguments ).fail( arguments );\n\t\t\t\t\treturn this;\n\t\t\t\t},\n\t\t\t\tthen: function( /* fnDone, fnFail, fnProgress */ ) {\n\t\t\t\t\tvar fns = arguments;\n\t\t\t\t\treturn jQuery.Deferred(function( newDefer ) {\n\t\t\t\t\t\tjQuery.each( tuples, function( i, tuple ) {\n\t\t\t\t\t\t\tvar fn = jQuery.isFunction( fns[ i ] ) && fns[ i ];\n\t\t\t\t\t\t\t// deferred[ done | fail | progress ] for forwarding actions to newDefer\n\t\t\t\t\t\t\tdeferred[ tuple[1] ](function() {\n\t\t\t\t\t\t\t\tvar returned = fn && fn.apply( this, arguments );\n\t\t\t\t\t\t\t\tif ( returned && jQuery.isFunction( returned.promise ) ) {\n\t\t\t\t\t\t\t\t\treturned.promise()\n\t\t\t\t\t\t\t\t\t\t.done( newDefer.resolve )\n\t\t\t\t\t\t\t\t\t\t.fail( newDefer.reject )\n\t\t\t\t\t\t\t\t\t\t.progress( newDefer.notify );\n\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\tnewDefer[ tuple[ 0 ] + \"With\" ]( this === promise ? newDefer.promise() : this, fn ? [ returned ] : arguments );\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t});\n\t\t\t\t\t\tfns = null;\n\t\t\t\t\t}).promise();\n\t\t\t\t},\n\t\t\t\t// Get a promise for this deferred\n\t\t\t\t// If obj is provided, the promise aspect is added to the object\n\t\t\t\tpromise: function( obj ) {\n\t\t\t\t\treturn obj != null ? jQuery.extend( obj, promise ) : promise;\n\t\t\t\t}\n\t\t\t},\n\t\t\tdeferred = {};\n\n\t\t// Keep pipe for back-compat\n\t\tpromise.pipe = promise.then;\n\n\t\t// Add list-specific methods\n\t\tjQuery.each( tuples, function( i, tuple ) {\n\t\t\tvar list = tuple[ 2 ],\n\t\t\t\tstateString = tuple[ 3 ];\n\n\t\t\t// promise[ done | fail | progress ] = list.add\n\t\t\tpromise[ tuple[1] ] = list.add;\n\n\t\t\t// Handle state\n\t\t\tif ( stateString ) {\n\t\t\t\tlist.add(function() {\n\t\t\t\t\t// state = [ resolved | rejected ]\n\t\t\t\t\tstate = stateString;\n\n\t\t\t\t// [ reject_list | resolve_list ].disable; progress_list.lock\n\t\t\t\t}, tuples[ i ^ 1 ][ 2 ].disable, tuples[ 2 ][ 2 ].lock );\n\t\t\t}\n\n\t\t\t// deferred[ resolve | reject | notify ]\n\t\t\tdeferred[ tuple[0] ] = function() {\n\t\t\t\tdeferred[ tuple[0] + \"With\" ]( this === deferred ? promise : this, arguments );\n\t\t\t\treturn this;\n\t\t\t};\n\t\t\tdeferred[ tuple[0] + \"With\" ] = list.fireWith;\n\t\t});\n\n\t\t// Make the deferred a promise\n\t\tpromise.promise( deferred );\n\n\t\t// Call given func if any\n\t\tif ( func ) {\n\t\t\tfunc.call( deferred, deferred );\n\t\t}\n\n\t\t// All done!\n\t\treturn deferred;\n\t},\n\n\t// Deferred helper\n\twhen: function( subordinate /* , ..., subordinateN */ ) {\n\t\tvar i = 0,\n\t\t\tresolveValues = slice.call( arguments ),\n\t\t\tlength = resolveValues.length,\n\n\t\t\t// the count of uncompleted subordinates\n\t\t\tremaining = length !== 1 || ( subordinate && jQuery.isFunction( subordinate.promise ) ) ? length : 0,\n\n\t\t\t// the master Deferred. If resolveValues consist of only a single Deferred, just use that.\n\t\t\tdeferred = remaining === 1 ? subordinate : jQuery.Deferred(),\n\n\t\t\t// Update function for both resolve and progress values\n\t\t\tupdateFunc = function( i, contexts, values ) {\n\t\t\t\treturn function( value ) {\n\t\t\t\t\tcontexts[ i ] = this;\n\t\t\t\t\tvalues[ i ] = arguments.length > 1 ? slice.call( arguments ) : value;\n\t\t\t\t\tif ( values === progressValues ) {\n\t\t\t\t\t\tdeferred.notifyWith( contexts, values );\n\n\t\t\t\t\t} else if ( !(--remaining) ) {\n\t\t\t\t\t\tdeferred.resolveWith( contexts, values );\n\t\t\t\t\t}\n\t\t\t\t};\n\t\t\t},\n\n\t\t\tprogressValues, progressContexts, resolveContexts;\n\n\t\t// add listeners to Deferred subordinates; treat others as resolved\n\t\tif ( length > 1 ) {\n\t\t\tprogressValues = new Array( length );\n\t\t\tprogressContexts = new Array( length );\n\t\t\tresolveContexts = new Array( length );\n\t\t\tfor ( ; i < length; i++ ) {\n\t\t\t\tif ( resolveValues[ i ] && jQuery.isFunction( resolveValues[ i ].promise ) ) {\n\t\t\t\t\tresolveValues[ i ].promise()\n\t\t\t\t\t\t.done( updateFunc( i, resolveContexts, resolveValues ) )\n\t\t\t\t\t\t.fail( deferred.reject )\n\t\t\t\t\t\t.progress( updateFunc( i, progressContexts, progressValues ) );\n\t\t\t\t} else {\n\t\t\t\t\t--remaining;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// if we're not waiting on anything, resolve the master\n\t\tif ( !remaining ) {\n\t\t\tdeferred.resolveWith( resolveContexts, resolveValues );\n\t\t}\n\n\t\treturn deferred.promise();\n\t}\n});\n\n\n// The deferred used on DOM ready\nvar readyList;\n\njQuery.fn.ready = function( fn ) {\n\t// Add the callback\n\tjQuery.ready.promise().done( fn );\n\n\treturn this;\n};\n\njQuery.extend({\n\t// Is the DOM ready to be used? Set to true once it occurs.\n\tisReady: false,\n\n\t// A counter to track how many items to wait for before\n\t// the ready event fires. See #6781\n\treadyWait: 1,\n\n\t// Hold (or release) the ready event\n\tholdReady: function( hold ) {\n\t\tif ( hold ) {\n\t\t\tjQuery.readyWait++;\n\t\t} else {\n\t\t\tjQuery.ready( true );\n\t\t}\n\t},\n\n\t// Handle when the DOM is ready\n\tready: function( wait ) {\n\n\t\t// Abort if there are pending holds or we're already ready\n\t\tif ( wait === true ? --jQuery.readyWait : jQuery.isReady ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443).\n\t\tif ( !document.body ) {\n\t\t\treturn setTimeout( jQuery.ready );\n\t\t}\n\n\t\t// Remember that the DOM is ready\n\t\tjQuery.isReady = true;\n\n\t\t// If a normal DOM Ready event fired, decrement, and wait if need be\n\t\tif ( wait !== true && --jQuery.readyWait > 0 ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// If there are functions bound, to execute\n\t\treadyList.resolveWith( document, [ jQuery ] );\n\n\t\t// Trigger any bound ready events\n\t\tif ( jQuery.fn.triggerHandler ) {\n\t\t\tjQuery( document ).triggerHandler( \"ready\" );\n\t\t\tjQuery( document ).off( \"ready\" );\n\t\t}\n\t}\n});\n\n/**\n * Clean-up method for dom ready events\n */\nfunction detach() {\n\tif ( document.addEventListener ) {\n\t\tdocument.removeEventListener( \"DOMContentLoaded\", completed, false );\n\t\twindow.removeEventListener( \"load\", completed, false );\n\n\t} else {\n\t\tdocument.detachEvent( \"onreadystatechange\", completed );\n\t\twindow.detachEvent( \"onload\", completed );\n\t}\n}\n\n/**\n * The ready event handler and self cleanup method\n */\nfunction completed() {\n\t// readyState === \"complete\" is good enough for us to call the dom ready in oldIE\n\tif ( document.addEventListener || event.type === \"load\" || document.readyState === \"complete\" ) {\n\t\tdetach();\n\t\tjQuery.ready();\n\t}\n}\n\njQuery.ready.promise = function( obj ) {\n\tif ( !readyList ) {\n\n\t\treadyList = jQuery.Deferred();\n\n\t\t// Catch cases where $(document).ready() is called after the browser event has already occurred.\n\t\t// we once tried to use readyState \"interactive\" here, but it caused issues like the one\n\t\t// discovered by ChrisS here: http://bugs.jquery.com/ticket/12282#comment:15\n\t\tif ( document.readyState === \"complete\" ) {\n\t\t\t// Handle it asynchronously to allow scripts the opportunity to delay ready\n\t\t\tsetTimeout( jQuery.ready );\n\n\t\t// Standards-based browsers support DOMContentLoaded\n\t\t} else if ( document.addEventListener ) {\n\t\t\t// Use the handy event callback\n\t\t\tdocument.addEventListener( \"DOMContentLoaded\", completed, false );\n\n\t\t\t// A fallback to window.onload, that will always work\n\t\t\twindow.addEventListener( \"load\", completed, false );\n\n\t\t// If IE event model is used\n\t\t} else {\n\t\t\t// Ensure firing before onload, maybe late but safe also for iframes\n\t\t\tdocument.attachEvent( \"onreadystatechange\", completed );\n\n\t\t\t// A fallback to window.onload, that will always work\n\t\t\twindow.attachEvent( \"onload\", completed );\n\n\t\t\t// If IE and not a frame\n\t\t\t// continually check to see if the document is ready\n\t\t\tvar top = false;\n\n\t\t\ttry {\n\t\t\t\ttop = window.frameElement == null && document.documentElement;\n\t\t\t} catch(e) {}\n\n\t\t\tif ( top && top.doScroll ) {\n\t\t\t\t(function doScrollCheck() {\n\t\t\t\t\tif ( !jQuery.isReady ) {\n\n\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t// Use the trick by Diego Perini\n\t\t\t\t\t\t\t// http://javascript.nwbox.com/IEContentLoaded/\n\t\t\t\t\t\t\ttop.doScroll(\"left\");\n\t\t\t\t\t\t} catch(e) {\n\t\t\t\t\t\t\treturn setTimeout( doScrollCheck, 50 );\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// detach all dom ready events\n\t\t\t\t\t\tdetach();\n\n\t\t\t\t\t\t// and execute any waiting functions\n\t\t\t\t\t\tjQuery.ready();\n\t\t\t\t\t}\n\t\t\t\t})();\n\t\t\t}\n\t\t}\n\t}\n\treturn readyList.promise( obj );\n};\n\n\nvar strundefined = typeof undefined;\n\n\n\n// Support: IE<9\n// Iteration over object's inherited properties before its own\nvar i;\nfor ( i in jQuery( support ) ) {\n\tbreak;\n}\nsupport.ownLast = i !== \"0\";\n\n// Note: most support tests are defined in their respective modules.\n// false until the test is run\nsupport.inlineBlockNeedsLayout = false;\n\n// Execute ASAP in case we need to set body.style.zoom\njQuery(function() {\n\t// Minified: var a,b,c,d\n\tvar val, div, body, container;\n\n\tbody = document.getElementsByTagName( \"body\" )[ 0 ];\n\tif ( !body || !body.style ) {\n\t\t// Return for frameset docs that don't have a body\n\t\treturn;\n\t}\n\n\t// Setup\n\tdiv = document.createElement( \"div\" );\n\tcontainer = document.createElement( \"div\" );\n\tcontainer.style.cssText = \"position:absolute;border:0;width:0;height:0;top:0;left:-9999px\";\n\tbody.appendChild( container ).appendChild( div );\n\n\tif ( typeof div.style.zoom !== strundefined ) {\n\t\t// Support: IE<8\n\t\t// Check if natively block-level elements act like inline-block\n\t\t// elements when setting their display to 'inline' and giving\n\t\t// them layout\n\t\tdiv.style.cssText = \"display:inline;margin:0;border:0;padding:1px;width:1px;zoom:1\";\n\n\t\tsupport.inlineBlockNeedsLayout = val = div.offsetWidth === 3;\n\t\tif ( val ) {\n\t\t\t// Prevent IE 6 from affecting layout for positioned elements #11048\n\t\t\t// Prevent IE from shrinking the body in IE 7 mode #12869\n\t\t\t// Support: IE<8\n\t\t\tbody.style.zoom = 1;\n\t\t}\n\t}\n\n\tbody.removeChild( container );\n});\n\n\n\n\n(function() {\n\tvar div = document.createElement( \"div\" );\n\n\t// Execute the test only if not already executed in another module.\n\tif (support.deleteExpando == null) {\n\t\t// Support: IE<9\n\t\tsupport.deleteExpando = true;\n\t\ttry {\n\t\t\tdelete div.test;\n\t\t} catch( e ) {\n\t\t\tsupport.deleteExpando = false;\n\t\t}\n\t}\n\n\t// Null elements to avoid leaks in IE.\n\tdiv = null;\n})();\n\n\n/**\n * Determines whether an object can have data\n */\njQuery.acceptData = function( elem ) {\n\tvar noData = jQuery.noData[ (elem.nodeName + \" \").toLowerCase() ],\n\t\tnodeType = +elem.nodeType || 1;\n\n\t// Do not set data on non-element DOM nodes because it will not be cleared (#8335).\n\treturn nodeType !== 1 && nodeType !== 9 ?\n\t\tfalse :\n\n\t\t// Nodes accept data unless otherwise specified; rejection can be conditional\n\t\t!noData || noData !== true && elem.getAttribute(\"classid\") === noData;\n};\n\n\nvar rbrace = /^(?:\\{[\\w\\W]*\\}|\\[[\\w\\W]*\\])$/,\n\trmultiDash = /([A-Z])/g;\n\nfunction dataAttr( elem, key, data ) {\n\t// If nothing was found internally, try to fetch any\n\t// data from the HTML5 data-* attribute\n\tif ( data === undefined && elem.nodeType === 1 ) {\n\n\t\tvar name = \"data-\" + key.replace( rmultiDash, \"-$1\" ).toLowerCase();\n\n\t\tdata = elem.getAttribute( name );\n\n\t\tif ( typeof data === \"string\" ) {\n\t\t\ttry {\n\t\t\t\tdata = data === \"true\" ? true :\n\t\t\t\t\tdata === \"false\" ? false :\n\t\t\t\t\tdata === \"null\" ? null :\n\t\t\t\t\t// Only convert to a number if it doesn't change the string\n\t\t\t\t\t+data + \"\" === data ? +data :\n\t\t\t\t\trbrace.test( data ) ? jQuery.parseJSON( data ) :\n\t\t\t\t\tdata;\n\t\t\t} catch( e ) {}\n\n\t\t\t// Make sure we set the data so it isn't changed later\n\t\t\tjQuery.data( elem, key, data );\n\n\t\t} else {\n\t\t\tdata = undefined;\n\t\t}\n\t}\n\n\treturn data;\n}\n\n// checks a cache object for emptiness\nfunction isEmptyDataObject( obj ) {\n\tvar name;\n\tfor ( name in obj ) {\n\n\t\t// if the public data object is empty, the private is still empty\n\t\tif ( name === \"data\" && jQuery.isEmptyObject( obj[name] ) ) {\n\t\t\tcontinue;\n\t\t}\n\t\tif ( name !== \"toJSON\" ) {\n\t\t\treturn false;\n\t\t}\n\t}\n\n\treturn true;\n}\n\nfunction internalData( elem, name, data, pvt /* Internal Use Only */ ) {\n\tif ( !jQuery.acceptData( elem ) ) {\n\t\treturn;\n\t}\n\n\tvar ret, thisCache,\n\t\tinternalKey = jQuery.expando,\n\n\t\t// We have to handle DOM nodes and JS objects differently because IE6-7\n\t\t// can't GC object references properly across the DOM-JS boundary\n\t\tisNode = elem.nodeType,\n\n\t\t// Only DOM nodes need the global jQuery cache; JS object data is\n\t\t// attached directly to the object so GC can occur automatically\n\t\tcache = isNode ? jQuery.cache : elem,\n\n\t\t// Only defining an ID for JS objects if its cache already exists allows\n\t\t// the code to shortcut on the same path as a DOM node with no cache\n\t\tid = isNode ? elem[ internalKey ] : elem[ internalKey ] && internalKey;\n\n\t// Avoid doing any more work than we need to when trying to get data on an\n\t// object that has no data at all\n\tif ( (!id || !cache[id] || (!pvt && !cache[id].data)) && data === undefined && typeof name === \"string\" ) {\n\t\treturn;\n\t}\n\n\tif ( !id ) {\n\t\t// Only DOM nodes need a new unique ID for each element since their data\n\t\t// ends up in the global cache\n\t\tif ( isNode ) {\n\t\t\tid = elem[ internalKey ] = deletedIds.pop() || jQuery.guid++;\n\t\t} else {\n\t\t\tid = internalKey;\n\t\t}\n\t}\n\n\tif ( !cache[ id ] ) {\n\t\t// Avoid exposing jQuery metadata on plain JS objects when the object\n\t\t// is serialized using JSON.stringify\n\t\tcache[ id ] = isNode ? {} : { toJSON: jQuery.noop };\n\t}\n\n\t// An object can be passed to jQuery.data instead of a key/value pair; this gets\n\t// shallow copied over onto the existing cache\n\tif ( typeof name === \"object\" || typeof name === \"function\" ) {\n\t\tif ( pvt ) {\n\t\t\tcache[ id ] = jQuery.extend( cache[ id ], name );\n\t\t} else {\n\t\t\tcache[ id ].data = jQuery.extend( cache[ id ].data, name );\n\t\t}\n\t}\n\n\tthisCache = cache[ id ];\n\n\t// jQuery data() is stored in a separate object inside the object's internal data\n\t// cache in order to avoid key collisions between internal data and user-defined\n\t// data.\n\tif ( !pvt ) {\n\t\tif ( !thisCache.data ) {\n\t\t\tthisCache.data = {};\n\t\t}\n\n\t\tthisCache = thisCache.data;\n\t}\n\n\tif ( data !== undefined ) {\n\t\tthisCache[ jQuery.camelCase( name ) ] = data;\n\t}\n\n\t// Check for both converted-to-camel and non-converted data property names\n\t// If a data property was specified\n\tif ( typeof name === \"string\" ) {\n\n\t\t// First Try to find as-is property data\n\t\tret = thisCache[ name ];\n\n\t\t// Test for null|undefined property data\n\t\tif ( ret == null ) {\n\n\t\t\t// Try to find the camelCased property\n\t\t\tret = thisCache[ jQuery.camelCase( name ) ];\n\t\t}\n\t} else {\n\t\tret = thisCache;\n\t}\n\n\treturn ret;\n}\n\nfunction internalRemoveData( elem, name, pvt ) {\n\tif ( !jQuery.acceptData( elem ) ) {\n\t\treturn;\n\t}\n\n\tvar thisCache, i,\n\t\tisNode = elem.nodeType,\n\n\t\t// See jQuery.data for more information\n\t\tcache = isNode ? jQuery.cache : elem,\n\t\tid = isNode ? elem[ jQuery.expando ] : jQuery.expando;\n\n\t// If there is already no cache entry for this object, there is no\n\t// purpose in continuing\n\tif ( !cache[ id ] ) {\n\t\treturn;\n\t}\n\n\tif ( name ) {\n\n\t\tthisCache = pvt ? cache[ id ] : cache[ id ].data;\n\n\t\tif ( thisCache ) {\n\n\t\t\t// Support array or space separated string names for data keys\n\t\t\tif ( !jQuery.isArray( name ) ) {\n\n\t\t\t\t// try the string as a key before any manipulation\n\t\t\t\tif ( name in thisCache ) {\n\t\t\t\t\tname = [ name ];\n\t\t\t\t} else {\n\n\t\t\t\t\t// split the camel cased version by spaces unless a key with the spaces exists\n\t\t\t\t\tname = jQuery.camelCase( name );\n\t\t\t\t\tif ( name in thisCache ) {\n\t\t\t\t\t\tname = [ name ];\n\t\t\t\t\t} else {\n\t\t\t\t\t\tname = name.split(\" \");\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t// If \"name\" is an array of keys...\n\t\t\t\t// When data is initially created, via (\"key\", \"val\") signature,\n\t\t\t\t// keys will be converted to camelCase.\n\t\t\t\t// Since there is no way to tell _how_ a key was added, remove\n\t\t\t\t// both plain key and camelCase key. #12786\n\t\t\t\t// This will only penalize the array argument path.\n\t\t\t\tname = name.concat( jQuery.map( name, jQuery.camelCase ) );\n\t\t\t}\n\n\t\t\ti = name.length;\n\t\t\twhile ( i-- ) {\n\t\t\t\tdelete thisCache[ name[i] ];\n\t\t\t}\n\n\t\t\t// If there is no data left in the cache, we want to continue\n\t\t\t// and let the cache object itself get destroyed\n\t\t\tif ( pvt ? !isEmptyDataObject(thisCache) : !jQuery.isEmptyObject(thisCache) ) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\t}\n\n\t// See jQuery.data for more information\n\tif ( !pvt ) {\n\t\tdelete cache[ id ].data;\n\n\t\t// Don't destroy the parent cache unless the internal data object\n\t\t// had been the only thing left in it\n\t\tif ( !isEmptyDataObject( cache[ id ] ) ) {\n\t\t\treturn;\n\t\t}\n\t}\n\n\t// Destroy the cache\n\tif ( isNode ) {\n\t\tjQuery.cleanData( [ elem ], true );\n\n\t// Use delete when supported for expandos or `cache` is not a window per isWindow (#10080)\n\t/* jshint eqeqeq: false */\n\t} else if ( support.deleteExpando || cache != cache.window ) {\n\t\t/* jshint eqeqeq: true */\n\t\tdelete cache[ id ];\n\n\t// When all else fails, null\n\t} else {\n\t\tcache[ id ] = null;\n\t}\n}\n\njQuery.extend({\n\tcache: {},\n\n\t// The following elements (space-suffixed to avoid Object.prototype collisions)\n\t// throw uncatchable exceptions if you attempt to set expando properties\n\tnoData: {\n\t\t\"applet \": true,\n\t\t\"embed \": true,\n\t\t// ...but Flash objects (which have this classid) *can* handle expandos\n\t\t\"object \": \"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000\"\n\t},\n\n\thasData: function( elem ) {\n\t\telem = elem.nodeType ? jQuery.cache[ elem[jQuery.expando] ] : elem[ jQuery.expando ];\n\t\treturn !!elem && !isEmptyDataObject( elem );\n\t},\n\n\tdata: function( elem, name, data ) {\n\t\treturn internalData( elem, name, data );\n\t},\n\n\tremoveData: function( elem, name ) {\n\t\treturn internalRemoveData( elem, name );\n\t},\n\n\t// For internal use only.\n\t_data: function( elem, name, data ) {\n\t\treturn internalData( elem, name, data, true );\n\t},\n\n\t_removeData: function( elem, name ) {\n\t\treturn internalRemoveData( elem, name, true );\n\t}\n});\n\njQuery.fn.extend({\n\tdata: function( key, value ) {\n\t\tvar i, name, data,\n\t\t\telem = this[0],\n\t\t\tattrs = elem && elem.attributes;\n\n\t\t// Special expections of .data basically thwart jQuery.access,\n\t\t// so implement the relevant behavior ourselves\n\n\t\t// Gets all values\n\t\tif ( key === undefined ) {\n\t\t\tif ( this.length ) {\n\t\t\t\tdata = jQuery.data( elem );\n\n\t\t\t\tif ( elem.nodeType === 1 && !jQuery._data( elem, \"parsedAttrs\" ) ) {\n\t\t\t\t\ti = attrs.length;\n\t\t\t\t\twhile ( i-- ) {\n\n\t\t\t\t\t\t// Support: IE11+\n\t\t\t\t\t\t// The attrs elements can be null (#14894)\n\t\t\t\t\t\tif ( attrs[ i ] ) {\n\t\t\t\t\t\t\tname = attrs[ i ].name;\n\t\t\t\t\t\t\tif ( name.indexOf( \"data-\" ) === 0 ) {\n\t\t\t\t\t\t\t\tname = jQuery.camelCase( name.slice(5) );\n\t\t\t\t\t\t\t\tdataAttr( elem, name, data[ name ] );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tjQuery._data( elem, \"parsedAttrs\", true );\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn data;\n\t\t}\n\n\t\t// Sets multiple values\n\t\tif ( typeof key === \"object\" ) {\n\t\t\treturn this.each(function() {\n\t\t\t\tjQuery.data( this, key );\n\t\t\t});\n\t\t}\n\n\t\treturn arguments.length > 1 ?\n\n\t\t\t// Sets one value\n\t\t\tthis.each(function() {\n\t\t\t\tjQuery.data( this, key, value );\n\t\t\t}) :\n\n\t\t\t// Gets one value\n\t\t\t// Try to fetch any internally stored data first\n\t\t\telem ? dataAttr( elem, key, jQuery.data( elem, key ) ) : undefined;\n\t},\n\n\tremoveData: function( key ) {\n\t\treturn this.each(function() {\n\t\t\tjQuery.removeData( this, key );\n\t\t});\n\t}\n});\n\n\njQuery.extend({\n\tqueue: function( elem, type, data ) {\n\t\tvar queue;\n\n\t\tif ( elem ) {\n\t\t\ttype = ( type || \"fx\" ) + \"queue\";\n\t\t\tqueue = jQuery._data( elem, type );\n\n\t\t\t// Speed up dequeue by getting out quickly if this is just a lookup\n\t\t\tif ( data ) {\n\t\t\t\tif ( !queue || jQuery.isArray(data) ) {\n\t\t\t\t\tqueue = jQuery._data( elem, type, jQuery.makeArray(data) );\n\t\t\t\t} else {\n\t\t\t\t\tqueue.push( data );\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn queue || [];\n\t\t}\n\t},\n\n\tdequeue: function( elem, type ) {\n\t\ttype = type || \"fx\";\n\n\t\tvar queue = jQuery.queue( elem, type ),\n\t\t\tstartLength = queue.length,\n\t\t\tfn = queue.shift(),\n\t\t\thooks = jQuery._queueHooks( elem, type ),\n\t\t\tnext = function() {\n\t\t\t\tjQuery.dequeue( elem, type );\n\t\t\t};\n\n\t\t// If the fx queue is dequeued, always remove the progress sentinel\n\t\tif ( fn === \"inprogress\" ) {\n\t\t\tfn = queue.shift();\n\t\t\tstartLength--;\n\t\t}\n\n\t\tif ( fn ) {\n\n\t\t\t// Add a progress sentinel to prevent the fx queue from being\n\t\t\t// automatically dequeued\n\t\t\tif ( type === \"fx\" ) {\n\t\t\t\tqueue.unshift( \"inprogress\" );\n\t\t\t}\n\n\t\t\t// clear up the last queue stop function\n\t\t\tdelete hooks.stop;\n\t\t\tfn.call( elem, next, hooks );\n\t\t}\n\n\t\tif ( !startLength && hooks ) {\n\t\t\thooks.empty.fire();\n\t\t}\n\t},\n\n\t// not intended for public consumption - generates a queueHooks object, or returns the current one\n\t_queueHooks: function( elem, type ) {\n\t\tvar key = type + \"queueHooks\";\n\t\treturn jQuery._data( elem, key ) || jQuery._data( elem, key, {\n\t\t\tempty: jQuery.Callbacks(\"once memory\").add(function() {\n\t\t\t\tjQuery._removeData( elem, type + \"queue\" );\n\t\t\t\tjQuery._removeData( elem, key );\n\t\t\t})\n\t\t});\n\t}\n});\n\njQuery.fn.extend({\n\tqueue: function( type, data ) {\n\t\tvar setter = 2;\n\n\t\tif ( typeof type !== \"string\" ) {\n\t\t\tdata = type;\n\t\t\ttype = \"fx\";\n\t\t\tsetter--;\n\t\t}\n\n\t\tif ( arguments.length < setter ) {\n\t\t\treturn jQuery.queue( this[0], type );\n\t\t}\n\n\t\treturn data === undefined ?\n\t\t\tthis :\n\t\t\tthis.each(function() {\n\t\t\t\tvar queue = jQuery.queue( this, type, data );\n\n\t\t\t\t// ensure a hooks for this queue\n\t\t\t\tjQuery._queueHooks( this, type );\n\n\t\t\t\tif ( type === \"fx\" && queue[0] !== \"inprogress\" ) {\n\t\t\t\t\tjQuery.dequeue( this, type );\n\t\t\t\t}\n\t\t\t});\n\t},\n\tdequeue: function( type ) {\n\t\treturn this.each(function() {\n\t\t\tjQuery.dequeue( this, type );\n\t\t});\n\t},\n\tclearQueue: function( type ) {\n\t\treturn this.queue( type || \"fx\", [] );\n\t},\n\t// Get a promise resolved when queues of a certain type\n\t// are emptied (fx is the type by default)\n\tpromise: function( type, obj ) {\n\t\tvar tmp,\n\t\t\tcount = 1,\n\t\t\tdefer = jQuery.Deferred(),\n\t\t\telements = this,\n\t\t\ti = this.length,\n\t\t\tresolve = function() {\n\t\t\t\tif ( !( --count ) ) {\n\t\t\t\t\tdefer.resolveWith( elements, [ elements ] );\n\t\t\t\t}\n\t\t\t};\n\n\t\tif ( typeof type !== \"string\" ) {\n\t\t\tobj = type;\n\t\t\ttype = undefined;\n\t\t}\n\t\ttype = type || \"fx\";\n\n\t\twhile ( i-- ) {\n\t\t\ttmp = jQuery._data( elements[ i ], type + \"queueHooks\" );\n\t\t\tif ( tmp && tmp.empty ) {\n\t\t\t\tcount++;\n\t\t\t\ttmp.empty.add( resolve );\n\t\t\t}\n\t\t}\n\t\tresolve();\n\t\treturn defer.promise( obj );\n\t}\n});\nvar pnum = (/[+-]?(?:\\d*\\.|)\\d+(?:[eE][+-]?\\d+|)/).source;\n\nvar cssExpand = [ \"Top\", \"Right\", \"Bottom\", \"Left\" ];\n\nvar isHidden = function( elem, el ) {\n\t\t// isHidden might be called from jQuery#filter function;\n\t\t// in that case, element will be second argument\n\t\telem = el || elem;\n\t\treturn jQuery.css( elem, \"display\" ) === \"none\" || !jQuery.contains( elem.ownerDocument, elem );\n\t};\n\n\n\n// Multifunctional method to get and set values of a collection\n// The value/s can optionally be executed if it's a function\nvar access = jQuery.access = function( elems, fn, key, value, chainable, emptyGet, raw ) {\n\tvar i = 0,\n\t\tlength = elems.length,\n\t\tbulk = key == null;\n\n\t// Sets many values\n\tif ( jQuery.type( key ) === \"object\" ) {\n\t\tchainable = true;\n\t\tfor ( i in key ) {\n\t\t\tjQuery.access( elems, fn, i, key[i], true, emptyGet, raw );\n\t\t}\n\n\t// Sets one value\n\t} else if ( value !== undefined ) {\n\t\tchainable = true;\n\n\t\tif ( !jQuery.isFunction( value ) ) {\n\t\t\traw = true;\n\t\t}\n\n\t\tif ( bulk ) {\n\t\t\t// Bulk operations run against the entire set\n\t\t\tif ( raw ) {\n\t\t\t\tfn.call( elems, value );\n\t\t\t\tfn = null;\n\n\t\t\t// ...except when executing function values\n\t\t\t} else {\n\t\t\t\tbulk = fn;\n\t\t\t\tfn = function( elem, key, value ) {\n\t\t\t\t\treturn bulk.call( jQuery( elem ), value );\n\t\t\t\t};\n\t\t\t}\n\t\t}\n\n\t\tif ( fn ) {\n\t\t\tfor ( ; i < length; i++ ) {\n\t\t\t\tfn( elems[i], key, raw ? value : value.call( elems[i], i, fn( elems[i], key ) ) );\n\t\t\t}\n\t\t}\n\t}\n\n\treturn chainable ?\n\t\telems :\n\n\t\t// Gets\n\t\tbulk ?\n\t\t\tfn.call( elems ) :\n\t\t\tlength ? fn( elems[0], key ) : emptyGet;\n};\nvar rcheckableType = (/^(?:checkbox|radio)$/i);\n\n\n\n(function() {\n\t// Minified: var a,b,c\n\tvar input = document.createElement( \"input\" ),\n\t\tdiv = document.createElement( \"div\" ),\n\t\tfragment = document.createDocumentFragment();\n\n\t// Setup\n\tdiv.innerHTML = \"  <link/><table></table><a href='/a'>a</a><input type='checkbox'/>\";\n\n\t// IE strips leading whitespace when .innerHTML is used\n\tsupport.leadingWhitespace = div.firstChild.nodeType === 3;\n\n\t// Make sure that tbody elements aren't automatically inserted\n\t// IE will insert them into empty tables\n\tsupport.tbody = !div.getElementsByTagName( \"tbody\" ).length;\n\n\t// Make sure that link elements get serialized correctly by innerHTML\n\t// This requires a wrapper element in IE\n\tsupport.htmlSerialize = !!div.getElementsByTagName( \"link\" ).length;\n\n\t// Makes sure cloning an html5 element does not cause problems\n\t// Where outerHTML is undefined, this still works\n\tsupport.html5Clone =\n\t\tdocument.createElement( \"nav\" ).cloneNode( true ).outerHTML !== \"<:nav></:nav>\";\n\n\t// Check if a disconnected checkbox will retain its checked\n\t// value of true after appended to the DOM (IE6/7)\n\tinput.type = \"checkbox\";\n\tinput.checked = true;\n\tfragment.appendChild( input );\n\tsupport.appendChecked = input.checked;\n\n\t// Make sure textarea (and checkbox) defaultValue is properly cloned\n\t// Support: IE6-IE11+\n\tdiv.innerHTML = \"<textarea>x</textarea>\";\n\tsupport.noCloneChecked = !!div.cloneNode( true ).lastChild.defaultValue;\n\n\t// #11217 - WebKit loses check when the name is after the checked attribute\n\tfragment.appendChild( div );\n\tdiv.innerHTML = \"<input type='radio' checked='checked' name='t'/>\";\n\n\t// Support: Safari 5.1, iOS 5.1, Android 4.x, Android 2.3\n\t// old WebKit doesn't clone checked state correctly in fragments\n\tsupport.checkClone = div.cloneNode( true ).cloneNode( true ).lastChild.checked;\n\n\t// Support: IE<9\n\t// Opera does not clone events (and typeof div.attachEvent === undefined).\n\t// IE9-10 clones events bound via attachEvent, but they don't trigger with .click()\n\tsupport.noCloneEvent = true;\n\tif ( div.attachEvent ) {\n\t\tdiv.attachEvent( \"onclick\", function() {\n\t\t\tsupport.noCloneEvent = false;\n\t\t});\n\n\t\tdiv.cloneNode( true ).click();\n\t}\n\n\t// Execute the test only if not already executed in another module.\n\tif (support.deleteExpando == null) {\n\t\t// Support: IE<9\n\t\tsupport.deleteExpando = true;\n\t\ttry {\n\t\t\tdelete div.test;\n\t\t} catch( e ) {\n\t\t\tsupport.deleteExpando = false;\n\t\t}\n\t}\n})();\n\n\n(function() {\n\tvar i, eventName,\n\t\tdiv = document.createElement( \"div\" );\n\n\t// Support: IE<9 (lack submit/change bubble), Firefox 23+ (lack focusin event)\n\tfor ( i in { submit: true, change: true, focusin: true }) {\n\t\teventName = \"on\" + i;\n\n\t\tif ( !(support[ i + \"Bubbles\" ] = eventName in window) ) {\n\t\t\t// Beware of CSP restrictions (https://developer.mozilla.org/en/Security/CSP)\n\t\t\tdiv.setAttribute( eventName, \"t\" );\n\t\t\tsupport[ i + \"Bubbles\" ] = div.attributes[ eventName ].expando === false;\n\t\t}\n\t}\n\n\t// Null elements to avoid leaks in IE.\n\tdiv = null;\n})();\n\n\nvar rformElems = /^(?:input|select|textarea)$/i,\n\trkeyEvent = /^key/,\n\trmouseEvent = /^(?:mouse|pointer|contextmenu)|click/,\n\trfocusMorph = /^(?:focusinfocus|focusoutblur)$/,\n\trtypenamespace = /^([^.]*)(?:\\.(.+)|)$/;\n\nfunction returnTrue() {\n\treturn true;\n}\n\nfunction returnFalse() {\n\treturn false;\n}\n\nfunction safeActiveElement() {\n\ttry {\n\t\treturn document.activeElement;\n\t} catch ( err ) { }\n}\n\n/*\n * Helper functions for managing events -- not part of the public interface.\n * Props to Dean Edwards' addEvent library for many of the ideas.\n */\njQuery.event = {\n\n\tglobal: {},\n\n\tadd: function( elem, types, handler, data, selector ) {\n\t\tvar tmp, events, t, handleObjIn,\n\t\t\tspecial, eventHandle, handleObj,\n\t\t\thandlers, type, namespaces, origType,\n\t\t\telemData = jQuery._data( elem );\n\n\t\t// Don't attach events to noData or text/comment nodes (but allow plain objects)\n\t\tif ( !elemData ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Caller can pass in an object of custom data in lieu of the handler\n\t\tif ( handler.handler ) {\n\t\t\thandleObjIn = handler;\n\t\t\thandler = handleObjIn.handler;\n\t\t\tselector = handleObjIn.selector;\n\t\t}\n\n\t\t// Make sure that the handler has a unique ID, used to find/remove it later\n\t\tif ( !handler.guid ) {\n\t\t\thandler.guid = jQuery.guid++;\n\t\t}\n\n\t\t// Init the element's event structure and main handler, if this is the first\n\t\tif ( !(events = elemData.events) ) {\n\t\t\tevents = elemData.events = {};\n\t\t}\n\t\tif ( !(eventHandle = elemData.handle) ) {\n\t\t\teventHandle = elemData.handle = function( e ) {\n\t\t\t\t// Discard the second event of a jQuery.event.trigger() and\n\t\t\t\t// when an event is called after a page has unloaded\n\t\t\t\treturn typeof jQuery !== strundefined && (!e || jQuery.event.triggered !== e.type) ?\n\t\t\t\t\tjQuery.event.dispatch.apply( eventHandle.elem, arguments ) :\n\t\t\t\t\tundefined;\n\t\t\t};\n\t\t\t// Add elem as a property of the handle fn to prevent a memory leak with IE non-native events\n\t\t\teventHandle.elem = elem;\n\t\t}\n\n\t\t// Handle multiple events separated by a space\n\t\ttypes = ( types || \"\" ).match( rnotwhite ) || [ \"\" ];\n\t\tt = types.length;\n\t\twhile ( t-- ) {\n\t\t\ttmp = rtypenamespace.exec( types[t] ) || [];\n\t\t\ttype = origType = tmp[1];\n\t\t\tnamespaces = ( tmp[2] || \"\" ).split( \".\" ).sort();\n\n\t\t\t// There *must* be a type, no attaching namespace-only handlers\n\t\t\tif ( !type ) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\t// If event changes its type, use the special event handlers for the changed type\n\t\t\tspecial = jQuery.event.special[ type ] || {};\n\n\t\t\t// If selector defined, determine special event api type, otherwise given type\n\t\t\ttype = ( selector ? special.delegateType : special.bindType ) || type;\n\n\t\t\t// Update special based on newly reset type\n\t\t\tspecial = jQuery.event.special[ type ] || {};\n\n\t\t\t// handleObj is passed to all event handlers\n\t\t\thandleObj = jQuery.extend({\n\t\t\t\ttype: type,\n\t\t\t\torigType: origType,\n\t\t\t\tdata: data,\n\t\t\t\thandler: handler,\n\t\t\t\tguid: handler.guid,\n\t\t\t\tselector: selector,\n\t\t\t\tneedsContext: selector && jQuery.expr.match.needsContext.test( selector ),\n\t\t\t\tnamespace: namespaces.join(\".\")\n\t\t\t}, handleObjIn );\n\n\t\t\t// Init the event handler queue if we're the first\n\t\t\tif ( !(handlers = events[ type ]) ) {\n\t\t\t\thandlers = events[ type ] = [];\n\t\t\t\thandlers.delegateCount = 0;\n\n\t\t\t\t// Only use addEventListener/attachEvent if the special events handler returns false\n\t\t\t\tif ( !special.setup || special.setup.call( elem, data, namespaces, eventHandle ) === false ) {\n\t\t\t\t\t// Bind the global event handler to the element\n\t\t\t\t\tif ( elem.addEventListener ) {\n\t\t\t\t\t\telem.addEventListener( type, eventHandle, false );\n\n\t\t\t\t\t} else if ( elem.attachEvent ) {\n\t\t\t\t\t\telem.attachEvent( \"on\" + type, eventHandle );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif ( special.add ) {\n\t\t\t\tspecial.add.call( elem, handleObj );\n\n\t\t\t\tif ( !handleObj.handler.guid ) {\n\t\t\t\t\thandleObj.handler.guid = handler.guid;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Add to the element's handler list, delegates in front\n\t\t\tif ( selector ) {\n\t\t\t\thandlers.splice( handlers.delegateCount++, 0, handleObj );\n\t\t\t} else {\n\t\t\t\thandlers.push( handleObj );\n\t\t\t}\n\n\t\t\t// Keep track of which events have ever been used, for event optimization\n\t\t\tjQuery.event.global[ type ] = true;\n\t\t}\n\n\t\t// Nullify elem to prevent memory leaks in IE\n\t\telem = null;\n\t},\n\n\t// Detach an event or set of events from an element\n\tremove: function( elem, types, handler, selector, mappedTypes ) {\n\t\tvar j, handleObj, tmp,\n\t\t\torigCount, t, events,\n\t\t\tspecial, handlers, type,\n\t\t\tnamespaces, origType,\n\t\t\telemData = jQuery.hasData( elem ) && jQuery._data( elem );\n\n\t\tif ( !elemData || !(events = elemData.events) ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Once for each type.namespace in types; type may be omitted\n\t\ttypes = ( types || \"\" ).match( rnotwhite ) || [ \"\" ];\n\t\tt = types.length;\n\t\twhile ( t-- ) {\n\t\t\ttmp = rtypenamespace.exec( types[t] ) || [];\n\t\t\ttype = origType = tmp[1];\n\t\t\tnamespaces = ( tmp[2] || \"\" ).split( \".\" ).sort();\n\n\t\t\t// Unbind all events (on this namespace, if provided) for the element\n\t\t\tif ( !type ) {\n\t\t\t\tfor ( type in events ) {\n\t\t\t\t\tjQuery.event.remove( elem, type + types[ t ], handler, selector, true );\n\t\t\t\t}\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tspecial = jQuery.event.special[ type ] || {};\n\t\t\ttype = ( selector ? special.delegateType : special.bindType ) || type;\n\t\t\thandlers = events[ type ] || [];\n\t\t\ttmp = tmp[2] && new RegExp( \"(^|\\\\.)\" + namespaces.join(\"\\\\.(?:.*\\\\.|)\") + \"(\\\\.|$)\" );\n\n\t\t\t// Remove matching events\n\t\t\torigCount = j = handlers.length;\n\t\t\twhile ( j-- ) {\n\t\t\t\thandleObj = handlers[ j ];\n\n\t\t\t\tif ( ( mappedTypes || origType === handleObj.origType ) &&\n\t\t\t\t\t( !handler || handler.guid === handleObj.guid ) &&\n\t\t\t\t\t( !tmp || tmp.test( handleObj.namespace ) ) &&\n\t\t\t\t\t( !selector || selector === handleObj.selector || selector === \"**\" && handleObj.selector ) ) {\n\t\t\t\t\thandlers.splice( j, 1 );\n\n\t\t\t\t\tif ( handleObj.selector ) {\n\t\t\t\t\t\thandlers.delegateCount--;\n\t\t\t\t\t}\n\t\t\t\t\tif ( special.remove ) {\n\t\t\t\t\t\tspecial.remove.call( elem, handleObj );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Remove generic event handler if we removed something and no more handlers exist\n\t\t\t// (avoids potential for endless recursion during removal of special event handlers)\n\t\t\tif ( origCount && !handlers.length ) {\n\t\t\t\tif ( !special.teardown || special.teardown.call( elem, namespaces, elemData.handle ) === false ) {\n\t\t\t\t\tjQuery.removeEvent( elem, type, elemData.handle );\n\t\t\t\t}\n\n\t\t\t\tdelete events[ type ];\n\t\t\t}\n\t\t}\n\n\t\t// Remove the expando if it's no longer used\n\t\tif ( jQuery.isEmptyObject( events ) ) {\n\t\t\tdelete elemData.handle;\n\n\t\t\t// removeData also checks for emptiness and clears the expando if empty\n\t\t\t// so use it instead of delete\n\t\t\tjQuery._removeData( elem, \"events\" );\n\t\t}\n\t},\n\n\ttrigger: function( event, data, elem, onlyHandlers ) {\n\t\tvar handle, ontype, cur,\n\t\t\tbubbleType, special, tmp, i,\n\t\t\teventPath = [ elem || document ],\n\t\t\ttype = hasOwn.call( event, \"type\" ) ? event.type : event,\n\t\t\tnamespaces = hasOwn.call( event, \"namespace\" ) ? event.namespace.split(\".\") : [];\n\n\t\tcur = tmp = elem = elem || document;\n\n\t\t// Don't do events on text and comment nodes\n\t\tif ( elem.nodeType === 3 || elem.nodeType === 8 ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// focus/blur morphs to focusin/out; ensure we're not firing them right now\n\t\tif ( rfocusMorph.test( type + jQuery.event.triggered ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\tif ( type.indexOf(\".\") >= 0 ) {\n\t\t\t// Namespaced trigger; create a regexp to match event type in handle()\n\t\t\tnamespaces = type.split(\".\");\n\t\t\ttype = namespaces.shift();\n\t\t\tnamespaces.sort();\n\t\t}\n\t\tontype = type.indexOf(\":\") < 0 && \"on\" + type;\n\n\t\t// Caller can pass in a jQuery.Event object, Object, or just an event type string\n\t\tevent = event[ jQuery.expando ] ?\n\t\t\tevent :\n\t\t\tnew jQuery.Event( type, typeof event === \"object\" && event );\n\n\t\t// Trigger bitmask: & 1 for native handlers; & 2 for jQuery (always true)\n\t\tevent.isTrigger = onlyHandlers ? 2 : 3;\n\t\tevent.namespace = namespaces.join(\".\");\n\t\tevent.namespace_re = event.namespace ?\n\t\t\tnew RegExp( \"(^|\\\\.)\" + namespaces.join(\"\\\\.(?:.*\\\\.|)\") + \"(\\\\.|$)\" ) :\n\t\t\tnull;\n\n\t\t// Clean up the event in case it is being reused\n\t\tevent.result = undefined;\n\t\tif ( !event.target ) {\n\t\t\tevent.target = elem;\n\t\t}\n\n\t\t// Clone any incoming data and prepend the event, creating the handler arg list\n\t\tdata = data == null ?\n\t\t\t[ event ] :\n\t\t\tjQuery.makeArray( data, [ event ] );\n\n\t\t// Allow special events to draw outside the lines\n\t\tspecial = jQuery.event.special[ type ] || {};\n\t\tif ( !onlyHandlers && special.trigger && special.trigger.apply( elem, data ) === false ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Determine event propagation path in advance, per W3C events spec (#9951)\n\t\t// Bubble up to document, then to window; watch for a global ownerDocument var (#9724)\n\t\tif ( !onlyHandlers && !special.noBubble && !jQuery.isWindow( elem ) ) {\n\n\t\t\tbubbleType = special.delegateType || type;\n\t\t\tif ( !rfocusMorph.test( bubbleType + type ) ) {\n\t\t\t\tcur = cur.parentNode;\n\t\t\t}\n\t\t\tfor ( ; cur; cur = cur.parentNode ) {\n\t\t\t\teventPath.push( cur );\n\t\t\t\ttmp = cur;\n\t\t\t}\n\n\t\t\t// Only add window if we got to document (e.g., not plain obj or detached DOM)\n\t\t\tif ( tmp === (elem.ownerDocument || document) ) {\n\t\t\t\teventPath.push( tmp.defaultView || tmp.parentWindow || window );\n\t\t\t}\n\t\t}\n\n\t\t// Fire handlers on the event path\n\t\ti = 0;\n\t\twhile ( (cur = eventPath[i++]) && !event.isPropagationStopped() ) {\n\n\t\t\tevent.type = i > 1 ?\n\t\t\t\tbubbleType :\n\t\t\t\tspecial.bindType || type;\n\n\t\t\t// jQuery handler\n\t\t\thandle = ( jQuery._data( cur, \"events\" ) || {} )[ event.type ] && jQuery._data( cur, \"handle\" );\n\t\t\tif ( handle ) {\n\t\t\t\thandle.apply( cur, data );\n\t\t\t}\n\n\t\t\t// Native handler\n\t\t\thandle = ontype && cur[ ontype ];\n\t\t\tif ( handle && handle.apply && jQuery.acceptData( cur ) ) {\n\t\t\t\tevent.result = handle.apply( cur, data );\n\t\t\t\tif ( event.result === false ) {\n\t\t\t\t\tevent.preventDefault();\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tevent.type = type;\n\n\t\t// If nobody prevented the default action, do it now\n\t\tif ( !onlyHandlers && !event.isDefaultPrevented() ) {\n\n\t\t\tif ( (!special._default || special._default.apply( eventPath.pop(), data ) === false) &&\n\t\t\t\tjQuery.acceptData( elem ) ) {\n\n\t\t\t\t// Call a native DOM method on the target with the same name name as the event.\n\t\t\t\t// Can't use an .isFunction() check here because IE6/7 fails that test.\n\t\t\t\t// Don't do default actions on window, that's where global variables be (#6170)\n\t\t\t\tif ( ontype && elem[ type ] && !jQuery.isWindow( elem ) ) {\n\n\t\t\t\t\t// Don't re-trigger an onFOO event when we call its FOO() method\n\t\t\t\t\ttmp = elem[ ontype ];\n\n\t\t\t\t\tif ( tmp ) {\n\t\t\t\t\t\telem[ ontype ] = null;\n\t\t\t\t\t}\n\n\t\t\t\t\t// Prevent re-triggering of the same event, since we already bubbled it above\n\t\t\t\t\tjQuery.event.triggered = type;\n\t\t\t\t\ttry {\n\t\t\t\t\t\telem[ type ]();\n\t\t\t\t\t} catch ( e ) {\n\t\t\t\t\t\t// IE<9 dies on focus/blur to hidden element (#1486,#12518)\n\t\t\t\t\t\t// only reproducible on winXP IE8 native, not IE9 in IE8 mode\n\t\t\t\t\t}\n\t\t\t\t\tjQuery.event.triggered = undefined;\n\n\t\t\t\t\tif ( tmp ) {\n\t\t\t\t\t\telem[ ontype ] = tmp;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn event.result;\n\t},\n\n\tdispatch: function( event ) {\n\n\t\t// Make a writable jQuery.Event from the native event object\n\t\tevent = jQuery.event.fix( event );\n\n\t\tvar i, ret, handleObj, matched, j,\n\t\t\thandlerQueue = [],\n\t\t\targs = slice.call( arguments ),\n\t\t\thandlers = ( jQuery._data( this, \"events\" ) || {} )[ event.type ] || [],\n\t\t\tspecial = jQuery.event.special[ event.type ] || {};\n\n\t\t// Use the fix-ed jQuery.Event rather than the (read-only) native event\n\t\targs[0] = event;\n\t\tevent.delegateTarget = this;\n\n\t\t// Call the preDispatch hook for the mapped type, and let it bail if desired\n\t\tif ( special.preDispatch && special.preDispatch.call( this, event ) === false ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Determine handlers\n\t\thandlerQueue = jQuery.event.handlers.call( this, event, handlers );\n\n\t\t// Run delegates first; they may want to stop propagation beneath us\n\t\ti = 0;\n\t\twhile ( (matched = handlerQueue[ i++ ]) && !event.isPropagationStopped() ) {\n\t\t\tevent.currentTarget = matched.elem;\n\n\t\t\tj = 0;\n\t\t\twhile ( (handleObj = matched.handlers[ j++ ]) && !event.isImmediatePropagationStopped() ) {\n\n\t\t\t\t// Triggered event must either 1) have no namespace, or\n\t\t\t\t// 2) have namespace(s) a subset or equal to those in the bound event (both can have no namespace).\n\t\t\t\tif ( !event.namespace_re || event.namespace_re.test( handleObj.namespace ) ) {\n\n\t\t\t\t\tevent.handleObj = handleObj;\n\t\t\t\t\tevent.data = handleObj.data;\n\n\t\t\t\t\tret = ( (jQuery.event.special[ handleObj.origType ] || {}).handle || handleObj.handler )\n\t\t\t\t\t\t\t.apply( matched.elem, args );\n\n\t\t\t\t\tif ( ret !== undefined ) {\n\t\t\t\t\t\tif ( (event.result = ret) === false ) {\n\t\t\t\t\t\t\tevent.preventDefault();\n\t\t\t\t\t\t\tevent.stopPropagation();\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Call the postDispatch hook for the mapped type\n\t\tif ( special.postDispatch ) {\n\t\t\tspecial.postDispatch.call( this, event );\n\t\t}\n\n\t\treturn event.result;\n\t},\n\n\thandlers: function( event, handlers ) {\n\t\tvar sel, handleObj, matches, i,\n\t\t\thandlerQueue = [],\n\t\t\tdelegateCount = handlers.delegateCount,\n\t\t\tcur = event.target;\n\n\t\t// Find delegate handlers\n\t\t// Black-hole SVG <use> instance trees (#13180)\n\t\t// Avoid non-left-click bubbling in Firefox (#3861)\n\t\tif ( delegateCount && cur.nodeType && (!event.button || event.type !== \"click\") ) {\n\n\t\t\t/* jshint eqeqeq: false */\n\t\t\tfor ( ; cur != this; cur = cur.parentNode || this ) {\n\t\t\t\t/* jshint eqeqeq: true */\n\n\t\t\t\t// Don't check non-elements (#13208)\n\t\t\t\t// Don't process clicks on disabled elements (#6911, #8165, #11382, #11764)\n\t\t\t\tif ( cur.nodeType === 1 && (cur.disabled !== true || event.type !== \"click\") ) {\n\t\t\t\t\tmatches = [];\n\t\t\t\t\tfor ( i = 0; i < delegateCount; i++ ) {\n\t\t\t\t\t\thandleObj = handlers[ i ];\n\n\t\t\t\t\t\t// Don't conflict with Object.prototype properties (#13203)\n\t\t\t\t\t\tsel = handleObj.selector + \" \";\n\n\t\t\t\t\t\tif ( matches[ sel ] === undefined ) {\n\t\t\t\t\t\t\tmatches[ sel ] = handleObj.needsContext ?\n\t\t\t\t\t\t\t\tjQuery( sel, this ).index( cur ) >= 0 :\n\t\t\t\t\t\t\t\tjQuery.find( sel, this, null, [ cur ] ).length;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif ( matches[ sel ] ) {\n\t\t\t\t\t\t\tmatches.push( handleObj );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tif ( matches.length ) {\n\t\t\t\t\t\thandlerQueue.push({ elem: cur, handlers: matches });\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Add the remaining (directly-bound) handlers\n\t\tif ( delegateCount < handlers.length ) {\n\t\t\thandlerQueue.push({ elem: this, handlers: handlers.slice( delegateCount ) });\n\t\t}\n\n\t\treturn handlerQueue;\n\t},\n\n\tfix: function( event ) {\n\t\tif ( event[ jQuery.expando ] ) {\n\t\t\treturn event;\n\t\t}\n\n\t\t// Create a writable copy of the event object and normalize some properties\n\t\tvar i, prop, copy,\n\t\t\ttype = event.type,\n\t\t\toriginalEvent = event,\n\t\t\tfixHook = this.fixHooks[ type ];\n\n\t\tif ( !fixHook ) {\n\t\t\tthis.fixHooks[ type ] = fixHook =\n\t\t\t\trmouseEvent.test( type ) ? this.mouseHooks :\n\t\t\t\trkeyEvent.test( type ) ? this.keyHooks :\n\t\t\t\t{};\n\t\t}\n\t\tcopy = fixHook.props ? this.props.concat( fixHook.props ) : this.props;\n\n\t\tevent = new jQuery.Event( originalEvent );\n\n\t\ti = copy.length;\n\t\twhile ( i-- ) {\n\t\t\tprop = copy[ i ];\n\t\t\tevent[ prop ] = originalEvent[ prop ];\n\t\t}\n\n\t\t// Support: IE<9\n\t\t// Fix target property (#1925)\n\t\tif ( !event.target ) {\n\t\t\tevent.target = originalEvent.srcElement || document;\n\t\t}\n\n\t\t// Support: Chrome 23+, Safari?\n\t\t// Target should not be a text node (#504, #13143)\n\t\tif ( event.target.nodeType === 3 ) {\n\t\t\tevent.target = event.target.parentNode;\n\t\t}\n\n\t\t// Support: IE<9\n\t\t// For mouse/key events, metaKey==false if it's undefined (#3368, #11328)\n\t\tevent.metaKey = !!event.metaKey;\n\n\t\treturn fixHook.filter ? fixHook.filter( event, originalEvent ) : event;\n\t},\n\n\t// Includes some event props shared by KeyEvent and MouseEvent\n\tprops: \"altKey bubbles cancelable ctrlKey currentTarget eventPhase metaKey relatedTarget shiftKey target timeStamp view which\".split(\" \"),\n\n\tfixHooks: {},\n\n\tkeyHooks: {\n\t\tprops: \"char charCode key keyCode\".split(\" \"),\n\t\tfilter: function( event, original ) {\n\n\t\t\t// Add which for key events\n\t\t\tif ( event.which == null ) {\n\t\t\t\tevent.which = original.charCode != null ? original.charCode : original.keyCode;\n\t\t\t}\n\n\t\t\treturn event;\n\t\t}\n\t},\n\n\tmouseHooks: {\n\t\tprops: \"button buttons clientX clientY fromElement offsetX offsetY pageX pageY screenX screenY toElement\".split(\" \"),\n\t\tfilter: function( event, original ) {\n\t\t\tvar body, eventDoc, doc,\n\t\t\t\tbutton = original.button,\n\t\t\t\tfromElement = original.fromElement;\n\n\t\t\t// Calculate pageX/Y if missing and clientX/Y available\n\t\t\tif ( event.pageX == null && original.clientX != null ) {\n\t\t\t\teventDoc = event.target.ownerDocument || document;\n\t\t\t\tdoc = eventDoc.documentElement;\n\t\t\t\tbody = eventDoc.body;\n\n\t\t\t\tevent.pageX = original.clientX + ( doc && doc.scrollLeft || body && body.scrollLeft || 0 ) - ( doc && doc.clientLeft || body && body.clientLeft || 0 );\n\t\t\t\tevent.pageY = original.clientY + ( doc && doc.scrollTop  || body && body.scrollTop  || 0 ) - ( doc && doc.clientTop  || body && body.clientTop  || 0 );\n\t\t\t}\n\n\t\t\t// Add relatedTarget, if necessary\n\t\t\tif ( !event.relatedTarget && fromElement ) {\n\t\t\t\tevent.relatedTarget = fromElement === event.target ? original.toElement : fromElement;\n\t\t\t}\n\n\t\t\t// Add which for click: 1 === left; 2 === middle; 3 === right\n\t\t\t// Note: button is not normalized, so don't use it\n\t\t\tif ( !event.which && button !== undefined ) {\n\t\t\t\tevent.which = ( button & 1 ? 1 : ( button & 2 ? 3 : ( button & 4 ? 2 : 0 ) ) );\n\t\t\t}\n\n\t\t\treturn event;\n\t\t}\n\t},\n\n\tspecial: {\n\t\tload: {\n\t\t\t// Prevent triggered image.load events from bubbling to window.load\n\t\t\tnoBubble: true\n\t\t},\n\t\tfocus: {\n\t\t\t// Fire native event if possible so blur/focus sequence is correct\n\t\t\ttrigger: function() {\n\t\t\t\tif ( this !== safeActiveElement() && this.focus ) {\n\t\t\t\t\ttry {\n\t\t\t\t\t\tthis.focus();\n\t\t\t\t\t\treturn false;\n\t\t\t\t\t} catch ( e ) {\n\t\t\t\t\t\t// Support: IE<9\n\t\t\t\t\t\t// If we error on focus to hidden element (#1486, #12518),\n\t\t\t\t\t\t// let .trigger() run the handlers\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t},\n\t\t\tdelegateType: \"focusin\"\n\t\t},\n\t\tblur: {\n\t\t\ttrigger: function() {\n\t\t\t\tif ( this === safeActiveElement() && this.blur ) {\n\t\t\t\t\tthis.blur();\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t},\n\t\t\tdelegateType: \"focusout\"\n\t\t},\n\t\tclick: {\n\t\t\t// For checkbox, fire native event so checked state will be right\n\t\t\ttrigger: function() {\n\t\t\t\tif ( jQuery.nodeName( this, \"input\" ) && this.type === \"checkbox\" && this.click ) {\n\t\t\t\t\tthis.click();\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t},\n\n\t\t\t// For cross-browser consistency, don't fire native .click() on links\n\t\t\t_default: function( event ) {\n\t\t\t\treturn jQuery.nodeName( event.target, \"a\" );\n\t\t\t}\n\t\t},\n\n\t\tbeforeunload: {\n\t\t\tpostDispatch: function( event ) {\n\n\t\t\t\t// Support: Firefox 20+\n\t\t\t\t// Firefox doesn't alert if the returnValue field is not set.\n\t\t\t\tif ( event.result !== undefined && event.originalEvent ) {\n\t\t\t\t\tevent.originalEvent.returnValue = event.result;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t},\n\n\tsimulate: function( type, elem, event, bubble ) {\n\t\t// Piggyback on a donor event to simulate a different one.\n\t\t// Fake originalEvent to avoid donor's stopPropagation, but if the\n\t\t// simulated event prevents default then we do the same on the donor.\n\t\tvar e = jQuery.extend(\n\t\t\tnew jQuery.Event(),\n\t\t\tevent,\n\t\t\t{\n\t\t\t\ttype: type,\n\t\t\t\tisSimulated: true,\n\t\t\t\toriginalEvent: {}\n\t\t\t}\n\t\t);\n\t\tif ( bubble ) {\n\t\t\tjQuery.event.trigger( e, null, elem );\n\t\t} else {\n\t\t\tjQuery.event.dispatch.call( elem, e );\n\t\t}\n\t\tif ( e.isDefaultPrevented() ) {\n\t\t\tevent.preventDefault();\n\t\t}\n\t}\n};\n\njQuery.removeEvent = document.removeEventListener ?\n\tfunction( elem, type, handle ) {\n\t\tif ( elem.removeEventListener ) {\n\t\t\telem.removeEventListener( type, handle, false );\n\t\t}\n\t} :\n\tfunction( elem, type, handle ) {\n\t\tvar name = \"on\" + type;\n\n\t\tif ( elem.detachEvent ) {\n\n\t\t\t// #8545, #7054, preventing memory leaks for custom events in IE6-8\n\t\t\t// detachEvent needed property on element, by name of that event, to properly expose it to GC\n\t\t\tif ( typeof elem[ name ] === strundefined ) {\n\t\t\t\telem[ name ] = null;\n\t\t\t}\n\n\t\t\telem.detachEvent( name, handle );\n\t\t}\n\t};\n\njQuery.Event = function( src, props ) {\n\t// Allow instantiation without the 'new' keyword\n\tif ( !(this instanceof jQuery.Event) ) {\n\t\treturn new jQuery.Event( src, props );\n\t}\n\n\t// Event object\n\tif ( src && src.type ) {\n\t\tthis.originalEvent = src;\n\t\tthis.type = src.type;\n\n\t\t// Events bubbling up the document may have been marked as prevented\n\t\t// by a handler lower down the tree; reflect the correct value.\n\t\tthis.isDefaultPrevented = src.defaultPrevented ||\n\t\t\t\tsrc.defaultPrevented === undefined &&\n\t\t\t\t// Support: IE < 9, Android < 4.0\n\t\t\t\tsrc.returnValue === false ?\n\t\t\treturnTrue :\n\t\t\treturnFalse;\n\n\t// Event type\n\t} else {\n\t\tthis.type = src;\n\t}\n\n\t// Put explicitly provided properties onto the event object\n\tif ( props ) {\n\t\tjQuery.extend( this, props );\n\t}\n\n\t// Create a timestamp if incoming event doesn't have one\n\tthis.timeStamp = src && src.timeStamp || jQuery.now();\n\n\t// Mark it as fixed\n\tthis[ jQuery.expando ] = true;\n};\n\n// jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding\n// http://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html\njQuery.Event.prototype = {\n\tisDefaultPrevented: returnFalse,\n\tisPropagationStopped: returnFalse,\n\tisImmediatePropagationStopped: returnFalse,\n\n\tpreventDefault: function() {\n\t\tvar e = this.originalEvent;\n\n\t\tthis.isDefaultPrevented = returnTrue;\n\t\tif ( !e ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// If preventDefault exists, run it on the original event\n\t\tif ( e.preventDefault ) {\n\t\t\te.preventDefault();\n\n\t\t// Support: IE\n\t\t// Otherwise set the returnValue property of the original event to false\n\t\t} else {\n\t\t\te.returnValue = false;\n\t\t}\n\t},\n\tstopPropagation: function() {\n\t\tvar e = this.originalEvent;\n\n\t\tthis.isPropagationStopped = returnTrue;\n\t\tif ( !e ) {\n\t\t\treturn;\n\t\t}\n\t\t// If stopPropagation exists, run it on the original event\n\t\tif ( e.stopPropagation ) {\n\t\t\te.stopPropagation();\n\t\t}\n\n\t\t// Support: IE\n\t\t// Set the cancelBubble property of the original event to true\n\t\te.cancelBubble = true;\n\t},\n\tstopImmediatePropagation: function() {\n\t\tvar e = this.originalEvent;\n\n\t\tthis.isImmediatePropagationStopped = returnTrue;\n\n\t\tif ( e && e.stopImmediatePropagation ) {\n\t\t\te.stopImmediatePropagation();\n\t\t}\n\n\t\tthis.stopPropagation();\n\t}\n};\n\n// Create mouseenter/leave events using mouseover/out and event-time checks\njQuery.each({\n\tmouseenter: \"mouseover\",\n\tmouseleave: \"mouseout\",\n\tpointerenter: \"pointerover\",\n\tpointerleave: \"pointerout\"\n}, function( orig, fix ) {\n\tjQuery.event.special[ orig ] = {\n\t\tdelegateType: fix,\n\t\tbindType: fix,\n\n\t\thandle: function( event ) {\n\t\t\tvar ret,\n\t\t\t\ttarget = this,\n\t\t\t\trelated = event.relatedTarget,\n\t\t\t\thandleObj = event.handleObj;\n\n\t\t\t// For mousenter/leave call the handler if related is outside the target.\n\t\t\t// NB: No relatedTarget if the mouse left/entered the browser window\n\t\t\tif ( !related || (related !== target && !jQuery.contains( target, related )) ) {\n\t\t\t\tevent.type = handleObj.origType;\n\t\t\t\tret = handleObj.handler.apply( this, arguments );\n\t\t\t\tevent.type = fix;\n\t\t\t}\n\t\t\treturn ret;\n\t\t}\n\t};\n});\n\n// IE submit delegation\nif ( !support.submitBubbles ) {\n\n\tjQuery.event.special.submit = {\n\t\tsetup: function() {\n\t\t\t// Only need this for delegated form submit events\n\t\t\tif ( jQuery.nodeName( this, \"form\" ) ) {\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\t// Lazy-add a submit handler when a descendant form may potentially be submitted\n\t\t\tjQuery.event.add( this, \"click._submit keypress._submit\", function( e ) {\n\t\t\t\t// Node name check avoids a VML-related crash in IE (#9807)\n\t\t\t\tvar elem = e.target,\n\t\t\t\t\tform = jQuery.nodeName( elem, \"input\" ) || jQuery.nodeName( elem, \"button\" ) ? elem.form : undefined;\n\t\t\t\tif ( form && !jQuery._data( form, \"submitBubbles\" ) ) {\n\t\t\t\t\tjQuery.event.add( form, \"submit._submit\", function( event ) {\n\t\t\t\t\t\tevent._submit_bubble = true;\n\t\t\t\t\t});\n\t\t\t\t\tjQuery._data( form, \"submitBubbles\", true );\n\t\t\t\t}\n\t\t\t});\n\t\t\t// return undefined since we don't need an event listener\n\t\t},\n\n\t\tpostDispatch: function( event ) {\n\t\t\t// If form was submitted by the user, bubble the event up the tree\n\t\t\tif ( event._submit_bubble ) {\n\t\t\t\tdelete event._submit_bubble;\n\t\t\t\tif ( this.parentNode && !event.isTrigger ) {\n\t\t\t\t\tjQuery.event.simulate( \"submit\", this.parentNode, event, true );\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\n\t\tteardown: function() {\n\t\t\t// Only need this for delegated form submit events\n\t\t\tif ( jQuery.nodeName( this, \"form\" ) ) {\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\t// Remove delegated handlers; cleanData eventually reaps submit handlers attached above\n\t\t\tjQuery.event.remove( this, \"._submit\" );\n\t\t}\n\t};\n}\n\n// IE change delegation and checkbox/radio fix\nif ( !support.changeBubbles ) {\n\n\tjQuery.event.special.change = {\n\n\t\tsetup: function() {\n\n\t\t\tif ( rformElems.test( this.nodeName ) ) {\n\t\t\t\t// IE doesn't fire change on a check/radio until blur; trigger it on click\n\t\t\t\t// after a propertychange. Eat the blur-change in special.change.handle.\n\t\t\t\t// This still fires onchange a second time for check/radio after blur.\n\t\t\t\tif ( this.type === \"checkbox\" || this.type === \"radio\" ) {\n\t\t\t\t\tjQuery.event.add( this, \"propertychange._change\", function( event ) {\n\t\t\t\t\t\tif ( event.originalEvent.propertyName === \"checked\" ) {\n\t\t\t\t\t\t\tthis._just_changed = true;\n\t\t\t\t\t\t}\n\t\t\t\t\t});\n\t\t\t\t\tjQuery.event.add( this, \"click._change\", function( event ) {\n\t\t\t\t\t\tif ( this._just_changed && !event.isTrigger ) {\n\t\t\t\t\t\t\tthis._just_changed = false;\n\t\t\t\t\t\t}\n\t\t\t\t\t\t// Allow triggered, simulated change events (#11500)\n\t\t\t\t\t\tjQuery.event.simulate( \"change\", this, event, true );\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\t// Delegated event; lazy-add a change handler on descendant inputs\n\t\t\tjQuery.event.add( this, \"beforeactivate._change\", function( e ) {\n\t\t\t\tvar elem = e.target;\n\n\t\t\t\tif ( rformElems.test( elem.nodeName ) && !jQuery._data( elem, \"changeBubbles\" ) ) {\n\t\t\t\t\tjQuery.event.add( elem, \"change._change\", function( event ) {\n\t\t\t\t\t\tif ( this.parentNode && !event.isSimulated && !event.isTrigger ) {\n\t\t\t\t\t\t\tjQuery.event.simulate( \"change\", this.parentNode, event, true );\n\t\t\t\t\t\t}\n\t\t\t\t\t});\n\t\t\t\t\tjQuery._data( elem, \"changeBubbles\", true );\n\t\t\t\t}\n\t\t\t});\n\t\t},\n\n\t\thandle: function( event ) {\n\t\t\tvar elem = event.target;\n\n\t\t\t// Swallow native change events from checkbox/radio, we already triggered them above\n\t\t\tif ( this !== elem || event.isSimulated || event.isTrigger || (elem.type !== \"radio\" && elem.type !== \"checkbox\") ) {\n\t\t\t\treturn event.handleObj.handler.apply( this, arguments );\n\t\t\t}\n\t\t},\n\n\t\tteardown: function() {\n\t\t\tjQuery.event.remove( this, \"._change\" );\n\n\t\t\treturn !rformElems.test( this.nodeName );\n\t\t}\n\t};\n}\n\n// Create \"bubbling\" focus and blur events\nif ( !support.focusinBubbles ) {\n\tjQuery.each({ focus: \"focusin\", blur: \"focusout\" }, function( orig, fix ) {\n\n\t\t// Attach a single capturing handler on the document while someone wants focusin/focusout\n\t\tvar handler = function( event ) {\n\t\t\t\tjQuery.event.simulate( fix, event.target, jQuery.event.fix( event ), true );\n\t\t\t};\n\n\t\tjQuery.event.special[ fix ] = {\n\t\t\tsetup: function() {\n\t\t\t\tvar doc = this.ownerDocument || this,\n\t\t\t\t\tattaches = jQuery._data( doc, fix );\n\n\t\t\t\tif ( !attaches ) {\n\t\t\t\t\tdoc.addEventListener( orig, handler, true );\n\t\t\t\t}\n\t\t\t\tjQuery._data( doc, fix, ( attaches || 0 ) + 1 );\n\t\t\t},\n\t\t\tteardown: function() {\n\t\t\t\tvar doc = this.ownerDocument || this,\n\t\t\t\t\tattaches = jQuery._data( doc, fix ) - 1;\n\n\t\t\t\tif ( !attaches ) {\n\t\t\t\t\tdoc.removeEventListener( orig, handler, true );\n\t\t\t\t\tjQuery._removeData( doc, fix );\n\t\t\t\t} else {\n\t\t\t\t\tjQuery._data( doc, fix, attaches );\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\t});\n}\n\njQuery.fn.extend({\n\n\ton: function( types, selector, data, fn, /*INTERNAL*/ one ) {\n\t\tvar type, origFn;\n\n\t\t// Types can be a map of types/handlers\n\t\tif ( typeof types === \"object\" ) {\n\t\t\t// ( types-Object, selector, data )\n\t\t\tif ( typeof selector !== \"string\" ) {\n\t\t\t\t// ( types-Object, data )\n\t\t\t\tdata = data || selector;\n\t\t\t\tselector = undefined;\n\t\t\t}\n\t\t\tfor ( type in types ) {\n\t\t\t\tthis.on( type, selector, data, types[ type ], one );\n\t\t\t}\n\t\t\treturn this;\n\t\t}\n\n\t\tif ( data == null && fn == null ) {\n\t\t\t// ( types, fn )\n\t\t\tfn = selector;\n\t\t\tdata = selector = undefined;\n\t\t} else if ( fn == null ) {\n\t\t\tif ( typeof selector === \"string\" ) {\n\t\t\t\t// ( types, selector, fn )\n\t\t\t\tfn = data;\n\t\t\t\tdata = undefined;\n\t\t\t} else {\n\t\t\t\t// ( types, data, fn )\n\t\t\t\tfn = data;\n\t\t\t\tdata = selector;\n\t\t\t\tselector = undefined;\n\t\t\t}\n\t\t}\n\t\tif ( fn === false ) {\n\t\t\tfn = returnFalse;\n\t\t} else if ( !fn ) {\n\t\t\treturn this;\n\t\t}\n\n\t\tif ( one === 1 ) {\n\t\t\torigFn = fn;\n\t\t\tfn = function( event ) {\n\t\t\t\t// Can use an empty set, since event contains the info\n\t\t\t\tjQuery().off( event );\n\t\t\t\treturn origFn.apply( this, arguments );\n\t\t\t};\n\t\t\t// Use same guid so caller can remove using origFn\n\t\t\tfn.guid = origFn.guid || ( origFn.guid = jQuery.guid++ );\n\t\t}\n\t\treturn this.each( function() {\n\t\t\tjQuery.event.add( this, types, fn, data, selector );\n\t\t});\n\t},\n\tone: function( types, selector, data, fn ) {\n\t\treturn this.on( types, selector, data, fn, 1 );\n\t},\n\toff: function( types, selector, fn ) {\n\t\tvar handleObj, type;\n\t\tif ( types && types.preventDefault && types.handleObj ) {\n\t\t\t// ( event )  dispatched jQuery.Event\n\t\t\thandleObj = types.handleObj;\n\t\t\tjQuery( types.delegateTarget ).off(\n\t\t\t\thandleObj.namespace ? handleObj.origType + \".\" + handleObj.namespace : handleObj.origType,\n\t\t\t\thandleObj.selector,\n\t\t\t\thandleObj.handler\n\t\t\t);\n\t\t\treturn this;\n\t\t}\n\t\tif ( typeof types === \"object\" ) {\n\t\t\t// ( types-object [, selector] )\n\t\t\tfor ( type in types ) {\n\t\t\t\tthis.off( type, selector, types[ type ] );\n\t\t\t}\n\t\t\treturn this;\n\t\t}\n\t\tif ( selector === false || typeof selector === \"function\" ) {\n\t\t\t// ( types [, fn] )\n\t\t\tfn = selector;\n\t\t\tselector = undefined;\n\t\t}\n\t\tif ( fn === false ) {\n\t\t\tfn = returnFalse;\n\t\t}\n\t\treturn this.each(function() {\n\t\t\tjQuery.event.remove( this, types, fn, selector );\n\t\t});\n\t},\n\n\ttrigger: function( type, data ) {\n\t\treturn this.each(function() {\n\t\t\tjQuery.event.trigger( type, data, this );\n\t\t});\n\t},\n\ttriggerHandler: function( type, data ) {\n\t\tvar elem = this[0];\n\t\tif ( elem ) {\n\t\t\treturn jQuery.event.trigger( type, data, elem, true );\n\t\t}\n\t}\n});\n\n\nfunction createSafeFragment( document ) {\n\tvar list = nodeNames.split( \"|\" ),\n\t\tsafeFrag = document.createDocumentFragment();\n\n\tif ( safeFrag.createElement ) {\n\t\twhile ( list.length ) {\n\t\t\tsafeFrag.createElement(\n\t\t\t\tlist.pop()\n\t\t\t);\n\t\t}\n\t}\n\treturn safeFrag;\n}\n\nvar nodeNames = \"abbr|article|aside|audio|bdi|canvas|data|datalist|details|figcaption|figure|footer|\" +\n\t\t\"header|hgroup|mark|meter|nav|output|progress|section|summary|time|video\",\n\trinlinejQuery = / jQuery\\d+=\"(?:null|\\d+)\"/g,\n\trnoshimcache = new RegExp(\"<(?:\" + nodeNames + \")[\\\\s/>]\", \"i\"),\n\trleadingWhitespace = /^\\s+/,\n\trxhtmlTag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\\w:]+)[^>]*)\\/>/gi,\n\trtagName = /<([\\w:]+)/,\n\trtbody = /<tbody/i,\n\trhtml = /<|&#?\\w+;/,\n\trnoInnerhtml = /<(?:script|style|link)/i,\n\t// checked=\"checked\" or checked\n\trchecked = /checked\\s*(?:[^=]|=\\s*.checked.)/i,\n\trscriptType = /^$|\\/(?:java|ecma)script/i,\n\trscriptTypeMasked = /^true\\/(.*)/,\n\trcleanScript = /^\\s*<!(?:\\[CDATA\\[|--)|(?:\\]\\]|--)>\\s*$/g,\n\n\t// We have to close these tags to support XHTML (#13200)\n\twrapMap = {\n\t\toption: [ 1, \"<select multiple='multiple'>\", \"</select>\" ],\n\t\tlegend: [ 1, \"<fieldset>\", \"</fieldset>\" ],\n\t\tarea: [ 1, \"<map>\", \"</map>\" ],\n\t\tparam: [ 1, \"<object>\", \"</object>\" ],\n\t\tthead: [ 1, \"<table>\", \"</table>\" ],\n\t\ttr: [ 2, \"<table><tbody>\", \"</tbody></table>\" ],\n\t\tcol: [ 2, \"<table><tbody></tbody><colgroup>\", \"</colgroup></table>\" ],\n\t\ttd: [ 3, \"<table><tbody><tr>\", \"</tr></tbody></table>\" ],\n\n\t\t// IE6-8 can't serialize link, script, style, or any html5 (NoScope) tags,\n\t\t// unless wrapped in a div with non-breaking characters in front of it.\n\t\t_default: support.htmlSerialize ? [ 0, \"\", \"\" ] : [ 1, \"X<div>\", \"</div>\"  ]\n\t},\n\tsafeFragment = createSafeFragment( document ),\n\tfragmentDiv = safeFragment.appendChild( document.createElement(\"div\") );\n\nwrapMap.optgroup = wrapMap.option;\nwrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead;\nwrapMap.th = wrapMap.td;\n\nfunction getAll( context, tag ) {\n\tvar elems, elem,\n\t\ti = 0,\n\t\tfound = typeof context.getElementsByTagName !== strundefined ? context.getElementsByTagName( tag || \"*\" ) :\n\t\t\ttypeof context.querySelectorAll !== strundefined ? context.querySelectorAll( tag || \"*\" ) :\n\t\t\tundefined;\n\n\tif ( !found ) {\n\t\tfor ( found = [], elems = context.childNodes || context; (elem = elems[i]) != null; i++ ) {\n\t\t\tif ( !tag || jQuery.nodeName( elem, tag ) ) {\n\t\t\t\tfound.push( elem );\n\t\t\t} else {\n\t\t\t\tjQuery.merge( found, getAll( elem, tag ) );\n\t\t\t}\n\t\t}\n\t}\n\n\treturn tag === undefined || tag && jQuery.nodeName( context, tag ) ?\n\t\tjQuery.merge( [ context ], found ) :\n\t\tfound;\n}\n\n// Used in buildFragment, fixes the defaultChecked property\nfunction fixDefaultChecked( elem ) {\n\tif ( rcheckableType.test( elem.type ) ) {\n\t\telem.defaultChecked = elem.checked;\n\t}\n}\n\n// Support: IE<8\n// Manipulating tables requires a tbody\nfunction manipulationTarget( elem, content ) {\n\treturn jQuery.nodeName( elem, \"table\" ) &&\n\t\tjQuery.nodeName( content.nodeType !== 11 ? content : content.firstChild, \"tr\" ) ?\n\n\t\telem.getElementsByTagName(\"tbody\")[0] ||\n\t\t\telem.appendChild( elem.ownerDocument.createElement(\"tbody\") ) :\n\t\telem;\n}\n\n// Replace/restore the type attribute of script elements for safe DOM manipulation\nfunction disableScript( elem ) {\n\telem.type = (jQuery.find.attr( elem, \"type\" ) !== null) + \"/\" + elem.type;\n\treturn elem;\n}\nfunction restoreScript( elem ) {\n\tvar match = rscriptTypeMasked.exec( elem.type );\n\tif ( match ) {\n\t\telem.type = match[1];\n\t} else {\n\t\telem.removeAttribute(\"type\");\n\t}\n\treturn elem;\n}\n\n// Mark scripts as having already been evaluated\nfunction setGlobalEval( elems, refElements ) {\n\tvar elem,\n\t\ti = 0;\n\tfor ( ; (elem = elems[i]) != null; i++ ) {\n\t\tjQuery._data( elem, \"globalEval\", !refElements || jQuery._data( refElements[i], \"globalEval\" ) );\n\t}\n}\n\nfunction cloneCopyEvent( src, dest ) {\n\n\tif ( dest.nodeType !== 1 || !jQuery.hasData( src ) ) {\n\t\treturn;\n\t}\n\n\tvar type, i, l,\n\t\toldData = jQuery._data( src ),\n\t\tcurData = jQuery._data( dest, oldData ),\n\t\tevents = oldData.events;\n\n\tif ( events ) {\n\t\tdelete curData.handle;\n\t\tcurData.events = {};\n\n\t\tfor ( type in events ) {\n\t\t\tfor ( i = 0, l = events[ type ].length; i < l; i++ ) {\n\t\t\t\tjQuery.event.add( dest, type, events[ type ][ i ] );\n\t\t\t}\n\t\t}\n\t}\n\n\t// make the cloned public data object a copy from the original\n\tif ( curData.data ) {\n\t\tcurData.data = jQuery.extend( {}, curData.data );\n\t}\n}\n\nfunction fixCloneNodeIssues( src, dest ) {\n\tvar nodeName, e, data;\n\n\t// We do not need to do anything for non-Elements\n\tif ( dest.nodeType !== 1 ) {\n\t\treturn;\n\t}\n\n\tnodeName = dest.nodeName.toLowerCase();\n\n\t// IE6-8 copies events bound via attachEvent when using cloneNode.\n\tif ( !support.noCloneEvent && dest[ jQuery.expando ] ) {\n\t\tdata = jQuery._data( dest );\n\n\t\tfor ( e in data.events ) {\n\t\t\tjQuery.removeEvent( dest, e, data.handle );\n\t\t}\n\n\t\t// Event data gets referenced instead of copied if the expando gets copied too\n\t\tdest.removeAttribute( jQuery.expando );\n\t}\n\n\t// IE blanks contents when cloning scripts, and tries to evaluate newly-set text\n\tif ( nodeName === \"script\" && dest.text !== src.text ) {\n\t\tdisableScript( dest ).text = src.text;\n\t\trestoreScript( dest );\n\n\t// IE6-10 improperly clones children of object elements using classid.\n\t// IE10 throws NoModificationAllowedError if parent is null, #12132.\n\t} else if ( nodeName === \"object\" ) {\n\t\tif ( dest.parentNode ) {\n\t\t\tdest.outerHTML = src.outerHTML;\n\t\t}\n\n\t\t// This path appears unavoidable for IE9. When cloning an object\n\t\t// element in IE9, the outerHTML strategy above is not sufficient.\n\t\t// If the src has innerHTML and the destination does not,\n\t\t// copy the src.innerHTML into the dest.innerHTML. #10324\n\t\tif ( support.html5Clone && ( src.innerHTML && !jQuery.trim(dest.innerHTML) ) ) {\n\t\t\tdest.innerHTML = src.innerHTML;\n\t\t}\n\n\t} else if ( nodeName === \"input\" && rcheckableType.test( src.type ) ) {\n\t\t// IE6-8 fails to persist the checked state of a cloned checkbox\n\t\t// or radio button. Worse, IE6-7 fail to give the cloned element\n\t\t// a checked appearance if the defaultChecked value isn't also set\n\n\t\tdest.defaultChecked = dest.checked = src.checked;\n\n\t\t// IE6-7 get confused and end up setting the value of a cloned\n\t\t// checkbox/radio button to an empty string instead of \"on\"\n\t\tif ( dest.value !== src.value ) {\n\t\t\tdest.value = src.value;\n\t\t}\n\n\t// IE6-8 fails to return the selected option to the default selected\n\t// state when cloning options\n\t} else if ( nodeName === \"option\" ) {\n\t\tdest.defaultSelected = dest.selected = src.defaultSelected;\n\n\t// IE6-8 fails to set the defaultValue to the correct value when\n\t// cloning other types of input fields\n\t} else if ( nodeName === \"input\" || nodeName === \"textarea\" ) {\n\t\tdest.defaultValue = src.defaultValue;\n\t}\n}\n\njQuery.extend({\n\tclone: function( elem, dataAndEvents, deepDataAndEvents ) {\n\t\tvar destElements, node, clone, i, srcElements,\n\t\t\tinPage = jQuery.contains( elem.ownerDocument, elem );\n\n\t\tif ( support.html5Clone || jQuery.isXMLDoc(elem) || !rnoshimcache.test( \"<\" + elem.nodeName + \">\" ) ) {\n\t\t\tclone = elem.cloneNode( true );\n\n\t\t// IE<=8 does not properly clone detached, unknown element nodes\n\t\t} else {\n\t\t\tfragmentDiv.innerHTML = elem.outerHTML;\n\t\t\tfragmentDiv.removeChild( clone = fragmentDiv.firstChild );\n\t\t}\n\n\t\tif ( (!support.noCloneEvent || !support.noCloneChecked) &&\n\t\t\t\t(elem.nodeType === 1 || elem.nodeType === 11) && !jQuery.isXMLDoc(elem) ) {\n\n\t\t\t// We eschew Sizzle here for performance reasons: http://jsperf.com/getall-vs-sizzle/2\n\t\t\tdestElements = getAll( clone );\n\t\t\tsrcElements = getAll( elem );\n\n\t\t\t// Fix all IE cloning issues\n\t\t\tfor ( i = 0; (node = srcElements[i]) != null; ++i ) {\n\t\t\t\t// Ensure that the destination node is not null; Fixes #9587\n\t\t\t\tif ( destElements[i] ) {\n\t\t\t\t\tfixCloneNodeIssues( node, destElements[i] );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Copy the events from the original to the clone\n\t\tif ( dataAndEvents ) {\n\t\t\tif ( deepDataAndEvents ) {\n\t\t\t\tsrcElements = srcElements || getAll( elem );\n\t\t\t\tdestElements = destElements || getAll( clone );\n\n\t\t\t\tfor ( i = 0; (node = srcElements[i]) != null; i++ ) {\n\t\t\t\t\tcloneCopyEvent( node, destElements[i] );\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tcloneCopyEvent( elem, clone );\n\t\t\t}\n\t\t}\n\n\t\t// Preserve script evaluation history\n\t\tdestElements = getAll( clone, \"script\" );\n\t\tif ( destElements.length > 0 ) {\n\t\t\tsetGlobalEval( destElements, !inPage && getAll( elem, \"script\" ) );\n\t\t}\n\n\t\tdestElements = srcElements = node = null;\n\n\t\t// Return the cloned set\n\t\treturn clone;\n\t},\n\n\tbuildFragment: function( elems, context, scripts, selection ) {\n\t\tvar j, elem, contains,\n\t\t\ttmp, tag, tbody, wrap,\n\t\t\tl = elems.length,\n\n\t\t\t// Ensure a safe fragment\n\t\t\tsafe = createSafeFragment( context ),\n\n\t\t\tnodes = [],\n\t\t\ti = 0;\n\n\t\tfor ( ; i < l; i++ ) {\n\t\t\telem = elems[ i ];\n\n\t\t\tif ( elem || elem === 0 ) {\n\n\t\t\t\t// Add nodes directly\n\t\t\t\tif ( jQuery.type( elem ) === \"object\" ) {\n\t\t\t\t\tjQuery.merge( nodes, elem.nodeType ? [ elem ] : elem );\n\n\t\t\t\t// Convert non-html into a text node\n\t\t\t\t} else if ( !rhtml.test( elem ) ) {\n\t\t\t\t\tnodes.push( context.createTextNode( elem ) );\n\n\t\t\t\t// Convert html into DOM nodes\n\t\t\t\t} else {\n\t\t\t\t\ttmp = tmp || safe.appendChild( context.createElement(\"div\") );\n\n\t\t\t\t\t// Deserialize a standard representation\n\t\t\t\t\ttag = (rtagName.exec( elem ) || [ \"\", \"\" ])[ 1 ].toLowerCase();\n\t\t\t\t\twrap = wrapMap[ tag ] || wrapMap._default;\n\n\t\t\t\t\ttmp.innerHTML = wrap[1] + elem.replace( rxhtmlTag, \"<$1></$2>\" ) + wrap[2];\n\n\t\t\t\t\t// Descend through wrappers to the right content\n\t\t\t\t\tj = wrap[0];\n\t\t\t\t\twhile ( j-- ) {\n\t\t\t\t\t\ttmp = tmp.lastChild;\n\t\t\t\t\t}\n\n\t\t\t\t\t// Manually add leading whitespace removed by IE\n\t\t\t\t\tif ( !support.leadingWhitespace && rleadingWhitespace.test( elem ) ) {\n\t\t\t\t\t\tnodes.push( context.createTextNode( rleadingWhitespace.exec( elem )[0] ) );\n\t\t\t\t\t}\n\n\t\t\t\t\t// Remove IE's autoinserted <tbody> from table fragments\n\t\t\t\t\tif ( !support.tbody ) {\n\n\t\t\t\t\t\t// String was a <table>, *may* have spurious <tbody>\n\t\t\t\t\t\telem = tag === \"table\" && !rtbody.test( elem ) ?\n\t\t\t\t\t\t\ttmp.firstChild :\n\n\t\t\t\t\t\t\t// String was a bare <thead> or <tfoot>\n\t\t\t\t\t\t\twrap[1] === \"<table>\" && !rtbody.test( elem ) ?\n\t\t\t\t\t\t\t\ttmp :\n\t\t\t\t\t\t\t\t0;\n\n\t\t\t\t\t\tj = elem && elem.childNodes.length;\n\t\t\t\t\t\twhile ( j-- ) {\n\t\t\t\t\t\t\tif ( jQuery.nodeName( (tbody = elem.childNodes[j]), \"tbody\" ) && !tbody.childNodes.length ) {\n\t\t\t\t\t\t\t\telem.removeChild( tbody );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tjQuery.merge( nodes, tmp.childNodes );\n\n\t\t\t\t\t// Fix #12392 for WebKit and IE > 9\n\t\t\t\t\ttmp.textContent = \"\";\n\n\t\t\t\t\t// Fix #12392 for oldIE\n\t\t\t\t\twhile ( tmp.firstChild ) {\n\t\t\t\t\t\ttmp.removeChild( tmp.firstChild );\n\t\t\t\t\t}\n\n\t\t\t\t\t// Remember the top-level container for proper cleanup\n\t\t\t\t\ttmp = safe.lastChild;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Fix #11356: Clear elements from fragment\n\t\tif ( tmp ) {\n\t\t\tsafe.removeChild( tmp );\n\t\t}\n\n\t\t// Reset defaultChecked for any radios and checkboxes\n\t\t// about to be appended to the DOM in IE 6/7 (#8060)\n\t\tif ( !support.appendChecked ) {\n\t\t\tjQuery.grep( getAll( nodes, \"input\" ), fixDefaultChecked );\n\t\t}\n\n\t\ti = 0;\n\t\twhile ( (elem = nodes[ i++ ]) ) {\n\n\t\t\t// #4087 - If origin and destination elements are the same, and this is\n\t\t\t// that element, do not do anything\n\t\t\tif ( selection && jQuery.inArray( elem, selection ) !== -1 ) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tcontains = jQuery.contains( elem.ownerDocument, elem );\n\n\t\t\t// Append to fragment\n\t\t\ttmp = getAll( safe.appendChild( elem ), \"script\" );\n\n\t\t\t// Preserve script evaluation history\n\t\t\tif ( contains ) {\n\t\t\t\tsetGlobalEval( tmp );\n\t\t\t}\n\n\t\t\t// Capture executables\n\t\t\tif ( scripts ) {\n\t\t\t\tj = 0;\n\t\t\t\twhile ( (elem = tmp[ j++ ]) ) {\n\t\t\t\t\tif ( rscriptType.test( elem.type || \"\" ) ) {\n\t\t\t\t\t\tscripts.push( elem );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\ttmp = null;\n\n\t\treturn safe;\n\t},\n\n\tcleanData: function( elems, /* internal */ acceptData ) {\n\t\tvar elem, type, id, data,\n\t\t\ti = 0,\n\t\t\tinternalKey = jQuery.expando,\n\t\t\tcache = jQuery.cache,\n\t\t\tdeleteExpando = support.deleteExpando,\n\t\t\tspecial = jQuery.event.special;\n\n\t\tfor ( ; (elem = elems[i]) != null; i++ ) {\n\t\t\tif ( acceptData || jQuery.acceptData( elem ) ) {\n\n\t\t\t\tid = elem[ internalKey ];\n\t\t\t\tdata = id && cache[ id ];\n\n\t\t\t\tif ( data ) {\n\t\t\t\t\tif ( data.events ) {\n\t\t\t\t\t\tfor ( type in data.events ) {\n\t\t\t\t\t\t\tif ( special[ type ] ) {\n\t\t\t\t\t\t\t\tjQuery.event.remove( elem, type );\n\n\t\t\t\t\t\t\t// This is a shortcut to avoid jQuery.event.remove's overhead\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tjQuery.removeEvent( elem, type, data.handle );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\t// Remove cache only if it was not already removed by jQuery.event.remove\n\t\t\t\t\tif ( cache[ id ] ) {\n\n\t\t\t\t\t\tdelete cache[ id ];\n\n\t\t\t\t\t\t// IE does not allow us to delete expando properties from nodes,\n\t\t\t\t\t\t// nor does it have a removeAttribute function on Document nodes;\n\t\t\t\t\t\t// we must handle all of these cases\n\t\t\t\t\t\tif ( deleteExpando ) {\n\t\t\t\t\t\t\tdelete elem[ internalKey ];\n\n\t\t\t\t\t\t} else if ( typeof elem.removeAttribute !== strundefined ) {\n\t\t\t\t\t\t\telem.removeAttribute( internalKey );\n\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\telem[ internalKey ] = null;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tdeletedIds.push( id );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n});\n\njQuery.fn.extend({\n\ttext: function( value ) {\n\t\treturn access( this, function( value ) {\n\t\t\treturn value === undefined ?\n\t\t\t\tjQuery.text( this ) :\n\t\t\t\tthis.empty().append( ( this[0] && this[0].ownerDocument || document ).createTextNode( value ) );\n\t\t}, null, value, arguments.length );\n\t},\n\n\tappend: function() {\n\t\treturn this.domManip( arguments, function( elem ) {\n\t\t\tif ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) {\n\t\t\t\tvar target = manipulationTarget( this, elem );\n\t\t\t\ttarget.appendChild( elem );\n\t\t\t}\n\t\t});\n\t},\n\n\tprepend: function() {\n\t\treturn this.domManip( arguments, function( elem ) {\n\t\t\tif ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) {\n\t\t\t\tvar target = manipulationTarget( this, elem );\n\t\t\t\ttarget.insertBefore( elem, target.firstChild );\n\t\t\t}\n\t\t});\n\t},\n\n\tbefore: function() {\n\t\treturn this.domManip( arguments, function( elem ) {\n\t\t\tif ( this.parentNode ) {\n\t\t\t\tthis.parentNode.insertBefore( elem, this );\n\t\t\t}\n\t\t});\n\t},\n\n\tafter: function() {\n\t\treturn this.domManip( arguments, function( elem ) {\n\t\t\tif ( this.parentNode ) {\n\t\t\t\tthis.parentNode.insertBefore( elem, this.nextSibling );\n\t\t\t}\n\t\t});\n\t},\n\n\tremove: function( selector, keepData /* Internal Use Only */ ) {\n\t\tvar elem,\n\t\t\telems = selector ? jQuery.filter( selector, this ) : this,\n\t\t\ti = 0;\n\n\t\tfor ( ; (elem = elems[i]) != null; i++ ) {\n\n\t\t\tif ( !keepData && elem.nodeType === 1 ) {\n\t\t\t\tjQuery.cleanData( getAll( elem ) );\n\t\t\t}\n\n\t\t\tif ( elem.parentNode ) {\n\t\t\t\tif ( keepData && jQuery.contains( elem.ownerDocument, elem ) ) {\n\t\t\t\t\tsetGlobalEval( getAll( elem, \"script\" ) );\n\t\t\t\t}\n\t\t\t\telem.parentNode.removeChild( elem );\n\t\t\t}\n\t\t}\n\n\t\treturn this;\n\t},\n\n\tempty: function() {\n\t\tvar elem,\n\t\t\ti = 0;\n\n\t\tfor ( ; (elem = this[i]) != null; i++ ) {\n\t\t\t// Remove element nodes and prevent memory leaks\n\t\t\tif ( elem.nodeType === 1 ) {\n\t\t\t\tjQuery.cleanData( getAll( elem, false ) );\n\t\t\t}\n\n\t\t\t// Remove any remaining nodes\n\t\t\twhile ( elem.firstChild ) {\n\t\t\t\telem.removeChild( elem.firstChild );\n\t\t\t}\n\n\t\t\t// If this is a select, ensure that it displays empty (#12336)\n\t\t\t// Support: IE<9\n\t\t\tif ( elem.options && jQuery.nodeName( elem, \"select\" ) ) {\n\t\t\t\telem.options.length = 0;\n\t\t\t}\n\t\t}\n\n\t\treturn this;\n\t},\n\n\tclone: function( dataAndEvents, deepDataAndEvents ) {\n\t\tdataAndEvents = dataAndEvents == null ? false : dataAndEvents;\n\t\tdeepDataAndEvents = deepDataAndEvents == null ? dataAndEvents : deepDataAndEvents;\n\n\t\treturn this.map(function() {\n\t\t\treturn jQuery.clone( this, dataAndEvents, deepDataAndEvents );\n\t\t});\n\t},\n\n\thtml: function( value ) {\n\t\treturn access( this, function( value ) {\n\t\t\tvar elem = this[ 0 ] || {},\n\t\t\t\ti = 0,\n\t\t\t\tl = this.length;\n\n\t\t\tif ( value === undefined ) {\n\t\t\t\treturn elem.nodeType === 1 ?\n\t\t\t\t\telem.innerHTML.replace( rinlinejQuery, \"\" ) :\n\t\t\t\t\tundefined;\n\t\t\t}\n\n\t\t\t// See if we can take a shortcut and just use innerHTML\n\t\t\tif ( typeof value === \"string\" && !rnoInnerhtml.test( value ) &&\n\t\t\t\t( support.htmlSerialize || !rnoshimcache.test( value )  ) &&\n\t\t\t\t( support.leadingWhitespace || !rleadingWhitespace.test( value ) ) &&\n\t\t\t\t!wrapMap[ (rtagName.exec( value ) || [ \"\", \"\" ])[ 1 ].toLowerCase() ] ) {\n\n\t\t\t\tvalue = value.replace( rxhtmlTag, \"<$1></$2>\" );\n\n\t\t\t\ttry {\n\t\t\t\t\tfor (; i < l; i++ ) {\n\t\t\t\t\t\t// Remove element nodes and prevent memory leaks\n\t\t\t\t\t\telem = this[i] || {};\n\t\t\t\t\t\tif ( elem.nodeType === 1 ) {\n\t\t\t\t\t\t\tjQuery.cleanData( getAll( elem, false ) );\n\t\t\t\t\t\t\telem.innerHTML = value;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\telem = 0;\n\n\t\t\t\t// If using innerHTML throws an exception, use the fallback method\n\t\t\t\t} catch(e) {}\n\t\t\t}\n\n\t\t\tif ( elem ) {\n\t\t\t\tthis.empty().append( value );\n\t\t\t}\n\t\t}, null, value, arguments.length );\n\t},\n\n\treplaceWith: function() {\n\t\tvar arg = arguments[ 0 ];\n\n\t\t// Make the changes, replacing each context element with the new content\n\t\tthis.domManip( arguments, function( elem ) {\n\t\t\targ = this.parentNode;\n\n\t\t\tjQuery.cleanData( getAll( this ) );\n\n\t\t\tif ( arg ) {\n\t\t\t\targ.replaceChild( elem, this );\n\t\t\t}\n\t\t});\n\n\t\t// Force removal if there was no new content (e.g., from empty arguments)\n\t\treturn arg && (arg.length || arg.nodeType) ? this : this.remove();\n\t},\n\n\tdetach: function( selector ) {\n\t\treturn this.remove( selector, true );\n\t},\n\n\tdomManip: function( args, callback ) {\n\n\t\t// Flatten any nested arrays\n\t\targs = concat.apply( [], args );\n\n\t\tvar first, node, hasScripts,\n\t\t\tscripts, doc, fragment,\n\t\t\ti = 0,\n\t\t\tl = this.length,\n\t\t\tset = this,\n\t\t\tiNoClone = l - 1,\n\t\t\tvalue = args[0],\n\t\t\tisFunction = jQuery.isFunction( value );\n\n\t\t// We can't cloneNode fragments that contain checked, in WebKit\n\t\tif ( isFunction ||\n\t\t\t\t( l > 1 && typeof value === \"string\" &&\n\t\t\t\t\t!support.checkClone && rchecked.test( value ) ) ) {\n\t\t\treturn this.each(function( index ) {\n\t\t\t\tvar self = set.eq( index );\n\t\t\t\tif ( isFunction ) {\n\t\t\t\t\targs[0] = value.call( this, index, self.html() );\n\t\t\t\t}\n\t\t\t\tself.domManip( args, callback );\n\t\t\t});\n\t\t}\n\n\t\tif ( l ) {\n\t\t\tfragment = jQuery.buildFragment( args, this[ 0 ].ownerDocument, false, this );\n\t\t\tfirst = fragment.firstChild;\n\n\t\t\tif ( fragment.childNodes.length === 1 ) {\n\t\t\t\tfragment = first;\n\t\t\t}\n\n\t\t\tif ( first ) {\n\t\t\t\tscripts = jQuery.map( getAll( fragment, \"script\" ), disableScript );\n\t\t\t\thasScripts = scripts.length;\n\n\t\t\t\t// Use the original fragment for the last item instead of the first because it can end up\n\t\t\t\t// being emptied incorrectly in certain situations (#8070).\n\t\t\t\tfor ( ; i < l; i++ ) {\n\t\t\t\t\tnode = fragment;\n\n\t\t\t\t\tif ( i !== iNoClone ) {\n\t\t\t\t\t\tnode = jQuery.clone( node, true, true );\n\n\t\t\t\t\t\t// Keep references to cloned scripts for later restoration\n\t\t\t\t\t\tif ( hasScripts ) {\n\t\t\t\t\t\t\tjQuery.merge( scripts, getAll( node, \"script\" ) );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tcallback.call( this[i], node, i );\n\t\t\t\t}\n\n\t\t\t\tif ( hasScripts ) {\n\t\t\t\t\tdoc = scripts[ scripts.length - 1 ].ownerDocument;\n\n\t\t\t\t\t// Reenable scripts\n\t\t\t\t\tjQuery.map( scripts, restoreScript );\n\n\t\t\t\t\t// Evaluate executable scripts on first document insertion\n\t\t\t\t\tfor ( i = 0; i < hasScripts; i++ ) {\n\t\t\t\t\t\tnode = scripts[ i ];\n\t\t\t\t\t\tif ( rscriptType.test( node.type || \"\" ) &&\n\t\t\t\t\t\t\t!jQuery._data( node, \"globalEval\" ) && jQuery.contains( doc, node ) ) {\n\n\t\t\t\t\t\t\tif ( node.src ) {\n\t\t\t\t\t\t\t\t// Optional AJAX dependency, but won't run scripts if not present\n\t\t\t\t\t\t\t\tif ( jQuery._evalUrl ) {\n\t\t\t\t\t\t\t\t\tjQuery._evalUrl( node.src );\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tjQuery.globalEval( ( node.text || node.textContent || node.innerHTML || \"\" ).replace( rcleanScript, \"\" ) );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// Fix #11809: Avoid leaking memory\n\t\t\t\tfragment = first = null;\n\t\t\t}\n\t\t}\n\n\t\treturn this;\n\t}\n});\n\njQuery.each({\n\tappendTo: \"append\",\n\tprependTo: \"prepend\",\n\tinsertBefore: \"before\",\n\tinsertAfter: \"after\",\n\treplaceAll: \"replaceWith\"\n}, function( name, original ) {\n\tjQuery.fn[ name ] = function( selector ) {\n\t\tvar elems,\n\t\t\ti = 0,\n\t\t\tret = [],\n\t\t\tinsert = jQuery( selector ),\n\t\t\tlast = insert.length - 1;\n\n\t\tfor ( ; i <= last; i++ ) {\n\t\t\telems = i === last ? this : this.clone(true);\n\t\t\tjQuery( insert[i] )[ original ]( elems );\n\n\t\t\t// Modern browsers can apply jQuery collections as arrays, but oldIE needs a .get()\n\t\t\tpush.apply( ret, elems.get() );\n\t\t}\n\n\t\treturn this.pushStack( ret );\n\t};\n});\n\n\nvar iframe,\n\telemdisplay = {};\n\n/**\n * Retrieve the actual display of a element\n * @param {String} name nodeName of the element\n * @param {Object} doc Document object\n */\n// Called only from within defaultDisplay\nfunction actualDisplay( name, doc ) {\n\tvar style,\n\t\telem = jQuery( doc.createElement( name ) ).appendTo( doc.body ),\n\n\t\t// getDefaultComputedStyle might be reliably used only on attached element\n\t\tdisplay = window.getDefaultComputedStyle && ( style = window.getDefaultComputedStyle( elem[ 0 ] ) ) ?\n\n\t\t\t// Use of this method is a temporary fix (more like optmization) until something better comes along,\n\t\t\t// since it was removed from specification and supported only in FF\n\t\t\tstyle.display : jQuery.css( elem[ 0 ], \"display\" );\n\n\t// We don't have any data stored on the element,\n\t// so use \"detach\" method as fast way to get rid of the element\n\telem.detach();\n\n\treturn display;\n}\n\n/**\n * Try to determine the default display value of an element\n * @param {String} nodeName\n */\nfunction defaultDisplay( nodeName ) {\n\tvar doc = document,\n\t\tdisplay = elemdisplay[ nodeName ];\n\n\tif ( !display ) {\n\t\tdisplay = actualDisplay( nodeName, doc );\n\n\t\t// If the simple way fails, read from inside an iframe\n\t\tif ( display === \"none\" || !display ) {\n\n\t\t\t// Use the already-created iframe if possible\n\t\t\tiframe = (iframe || jQuery( \"<iframe frameborder='0' width='0' height='0'/>\" )).appendTo( doc.documentElement );\n\n\t\t\t// Always write a new HTML skeleton so Webkit and Firefox don't choke on reuse\n\t\t\tdoc = ( iframe[ 0 ].contentWindow || iframe[ 0 ].contentDocument ).document;\n\n\t\t\t// Support: IE\n\t\t\tdoc.write();\n\t\t\tdoc.close();\n\n\t\t\tdisplay = actualDisplay( nodeName, doc );\n\t\t\tiframe.detach();\n\t\t}\n\n\t\t// Store the correct default display\n\t\telemdisplay[ nodeName ] = display;\n\t}\n\n\treturn display;\n}\n\n\n(function() {\n\tvar shrinkWrapBlocksVal;\n\n\tsupport.shrinkWrapBlocks = function() {\n\t\tif ( shrinkWrapBlocksVal != null ) {\n\t\t\treturn shrinkWrapBlocksVal;\n\t\t}\n\n\t\t// Will be changed later if needed.\n\t\tshrinkWrapBlocksVal = false;\n\n\t\t// Minified: var b,c,d\n\t\tvar div, body, container;\n\n\t\tbody = document.getElementsByTagName( \"body\" )[ 0 ];\n\t\tif ( !body || !body.style ) {\n\t\t\t// Test fired too early or in an unsupported environment, exit.\n\t\t\treturn;\n\t\t}\n\n\t\t// Setup\n\t\tdiv = document.createElement( \"div\" );\n\t\tcontainer = document.createElement( \"div\" );\n\t\tcontainer.style.cssText = \"position:absolute;border:0;width:0;height:0;top:0;left:-9999px\";\n\t\tbody.appendChild( container ).appendChild( div );\n\n\t\t// Support: IE6\n\t\t// Check if elements with layout shrink-wrap their children\n\t\tif ( typeof div.style.zoom !== strundefined ) {\n\t\t\t// Reset CSS: box-sizing; display; margin; border\n\t\t\tdiv.style.cssText =\n\t\t\t\t// Support: Firefox<29, Android 2.3\n\t\t\t\t// Vendor-prefix box-sizing\n\t\t\t\t\"-webkit-box-sizing:content-box;-moz-box-sizing:content-box;\" +\n\t\t\t\t\"box-sizing:content-box;display:block;margin:0;border:0;\" +\n\t\t\t\t\"padding:1px;width:1px;zoom:1\";\n\t\t\tdiv.appendChild( document.createElement( \"div\" ) ).style.width = \"5px\";\n\t\t\tshrinkWrapBlocksVal = div.offsetWidth !== 3;\n\t\t}\n\n\t\tbody.removeChild( container );\n\n\t\treturn shrinkWrapBlocksVal;\n\t};\n\n})();\nvar rmargin = (/^margin/);\n\nvar rnumnonpx = new RegExp( \"^(\" + pnum + \")(?!px)[a-z%]+$\", \"i\" );\n\n\n\nvar getStyles, curCSS,\n\trposition = /^(top|right|bottom|left)$/;\n\nif ( window.getComputedStyle ) {\n\tgetStyles = function( elem ) {\n\t\t// Support: IE<=11+, Firefox<=30+ (#15098, #14150)\n\t\t// IE throws on elements created in popups\n\t\t// FF meanwhile throws on frame elements through \"defaultView.getComputedStyle\"\n\t\tif ( elem.ownerDocument.defaultView.opener ) {\n\t\t\treturn elem.ownerDocument.defaultView.getComputedStyle( elem, null );\n\t\t}\n\n\t\treturn window.getComputedStyle( elem, null );\n\t};\n\n\tcurCSS = function( elem, name, computed ) {\n\t\tvar width, minWidth, maxWidth, ret,\n\t\t\tstyle = elem.style;\n\n\t\tcomputed = computed || getStyles( elem );\n\n\t\t// getPropertyValue is only needed for .css('filter') in IE9, see #12537\n\t\tret = computed ? computed.getPropertyValue( name ) || computed[ name ] : undefined;\n\n\t\tif ( computed ) {\n\n\t\t\tif ( ret === \"\" && !jQuery.contains( elem.ownerDocument, elem ) ) {\n\t\t\t\tret = jQuery.style( elem, name );\n\t\t\t}\n\n\t\t\t// A tribute to the \"awesome hack by Dean Edwards\"\n\t\t\t// Chrome < 17 and Safari 5.0 uses \"computed value\" instead of \"used value\" for margin-right\n\t\t\t// Safari 5.1.7 (at least) returns percentage for a larger set of values, but width seems to be reliably pixels\n\t\t\t// this is against the CSSOM draft spec: http://dev.w3.org/csswg/cssom/#resolved-values\n\t\t\tif ( rnumnonpx.test( ret ) && rmargin.test( name ) ) {\n\n\t\t\t\t// Remember the original values\n\t\t\t\twidth = style.width;\n\t\t\t\tminWidth = style.minWidth;\n\t\t\t\tmaxWidth = style.maxWidth;\n\n\t\t\t\t// Put in the new values to get a computed value out\n\t\t\t\tstyle.minWidth = style.maxWidth = style.width = ret;\n\t\t\t\tret = computed.width;\n\n\t\t\t\t// Revert the changed values\n\t\t\t\tstyle.width = width;\n\t\t\t\tstyle.minWidth = minWidth;\n\t\t\t\tstyle.maxWidth = maxWidth;\n\t\t\t}\n\t\t}\n\n\t\t// Support: IE\n\t\t// IE returns zIndex value as an integer.\n\t\treturn ret === undefined ?\n\t\t\tret :\n\t\t\tret + \"\";\n\t};\n} else if ( document.documentElement.currentStyle ) {\n\tgetStyles = function( elem ) {\n\t\treturn elem.currentStyle;\n\t};\n\n\tcurCSS = function( elem, name, computed ) {\n\t\tvar left, rs, rsLeft, ret,\n\t\t\tstyle = elem.style;\n\n\t\tcomputed = computed || getStyles( elem );\n\t\tret = computed ? computed[ name ] : undefined;\n\n\t\t// Avoid setting ret to empty string here\n\t\t// so we don't default to auto\n\t\tif ( ret == null && style && style[ name ] ) {\n\t\t\tret = style[ name ];\n\t\t}\n\n\t\t// From the awesome hack by Dean Edwards\n\t\t// http://erik.eae.net/archives/2007/07/27/18.54.15/#comment-102291\n\n\t\t// If we're not dealing with a regular pixel number\n\t\t// but a number that has a weird ending, we need to convert it to pixels\n\t\t// but not position css attributes, as those are proportional to the parent element instead\n\t\t// and we can't measure the parent instead because it might trigger a \"stacking dolls\" problem\n\t\tif ( rnumnonpx.test( ret ) && !rposition.test( name ) ) {\n\n\t\t\t// Remember the original values\n\t\t\tleft = style.left;\n\t\t\trs = elem.runtimeStyle;\n\t\t\trsLeft = rs && rs.left;\n\n\t\t\t// Put in the new values to get a computed value out\n\t\t\tif ( rsLeft ) {\n\t\t\t\trs.left = elem.currentStyle.left;\n\t\t\t}\n\t\t\tstyle.left = name === \"fontSize\" ? \"1em\" : ret;\n\t\t\tret = style.pixelLeft + \"px\";\n\n\t\t\t// Revert the changed values\n\t\t\tstyle.left = left;\n\t\t\tif ( rsLeft ) {\n\t\t\t\trs.left = rsLeft;\n\t\t\t}\n\t\t}\n\n\t\t// Support: IE\n\t\t// IE returns zIndex value as an integer.\n\t\treturn ret === undefined ?\n\t\t\tret :\n\t\t\tret + \"\" || \"auto\";\n\t};\n}\n\n\n\n\nfunction addGetHookIf( conditionFn, hookFn ) {\n\t// Define the hook, we'll check on the first run if it's really needed.\n\treturn {\n\t\tget: function() {\n\t\t\tvar condition = conditionFn();\n\n\t\t\tif ( condition == null ) {\n\t\t\t\t// The test was not ready at this point; screw the hook this time\n\t\t\t\t// but check again when needed next time.\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif ( condition ) {\n\t\t\t\t// Hook not needed (or it's not possible to use it due to missing dependency),\n\t\t\t\t// remove it.\n\t\t\t\t// Since there are no other hooks for marginRight, remove the whole object.\n\t\t\t\tdelete this.get;\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// Hook needed; redefine it so that the support test is not executed again.\n\n\t\t\treturn (this.get = hookFn).apply( this, arguments );\n\t\t}\n\t};\n}\n\n\n(function() {\n\t// Minified: var b,c,d,e,f,g, h,i\n\tvar div, style, a, pixelPositionVal, boxSizingReliableVal,\n\t\treliableHiddenOffsetsVal, reliableMarginRightVal;\n\n\t// Setup\n\tdiv = document.createElement( \"div\" );\n\tdiv.innerHTML = \"  <link/><table></table><a href='/a'>a</a><input type='checkbox'/>\";\n\ta = div.getElementsByTagName( \"a\" )[ 0 ];\n\tstyle = a && a.style;\n\n\t// Finish early in limited (non-browser) environments\n\tif ( !style ) {\n\t\treturn;\n\t}\n\n\tstyle.cssText = \"float:left;opacity:.5\";\n\n\t// Support: IE<9\n\t// Make sure that element opacity exists (as opposed to filter)\n\tsupport.opacity = style.opacity === \"0.5\";\n\n\t// Verify style float existence\n\t// (IE uses styleFloat instead of cssFloat)\n\tsupport.cssFloat = !!style.cssFloat;\n\n\tdiv.style.backgroundClip = \"content-box\";\n\tdiv.cloneNode( true ).style.backgroundClip = \"\";\n\tsupport.clearCloneStyle = div.style.backgroundClip === \"content-box\";\n\n\t// Support: Firefox<29, Android 2.3\n\t// Vendor-prefix box-sizing\n\tsupport.boxSizing = style.boxSizing === \"\" || style.MozBoxSizing === \"\" ||\n\t\tstyle.WebkitBoxSizing === \"\";\n\n\tjQuery.extend(support, {\n\t\treliableHiddenOffsets: function() {\n\t\t\tif ( reliableHiddenOffsetsVal == null ) {\n\t\t\t\tcomputeStyleTests();\n\t\t\t}\n\t\t\treturn reliableHiddenOffsetsVal;\n\t\t},\n\n\t\tboxSizingReliable: function() {\n\t\t\tif ( boxSizingReliableVal == null ) {\n\t\t\t\tcomputeStyleTests();\n\t\t\t}\n\t\t\treturn boxSizingReliableVal;\n\t\t},\n\n\t\tpixelPosition: function() {\n\t\t\tif ( pixelPositionVal == null ) {\n\t\t\t\tcomputeStyleTests();\n\t\t\t}\n\t\t\treturn pixelPositionVal;\n\t\t},\n\n\t\t// Support: Android 2.3\n\t\treliableMarginRight: function() {\n\t\t\tif ( reliableMarginRightVal == null ) {\n\t\t\t\tcomputeStyleTests();\n\t\t\t}\n\t\t\treturn reliableMarginRightVal;\n\t\t}\n\t});\n\n\tfunction computeStyleTests() {\n\t\t// Minified: var b,c,d,j\n\t\tvar div, body, container, contents;\n\n\t\tbody = document.getElementsByTagName( \"body\" )[ 0 ];\n\t\tif ( !body || !body.style ) {\n\t\t\t// Test fired too early or in an unsupported environment, exit.\n\t\t\treturn;\n\t\t}\n\n\t\t// Setup\n\t\tdiv = document.createElement( \"div\" );\n\t\tcontainer = document.createElement( \"div\" );\n\t\tcontainer.style.cssText = \"position:absolute;border:0;width:0;height:0;top:0;left:-9999px\";\n\t\tbody.appendChild( container ).appendChild( div );\n\n\t\tdiv.style.cssText =\n\t\t\t// Support: Firefox<29, Android 2.3\n\t\t\t// Vendor-prefix box-sizing\n\t\t\t\"-webkit-box-sizing:border-box;-moz-box-sizing:border-box;\" +\n\t\t\t\"box-sizing:border-box;display:block;margin-top:1%;top:1%;\" +\n\t\t\t\"border:1px;padding:1px;width:4px;position:absolute\";\n\n\t\t// Support: IE<9\n\t\t// Assume reasonable values in the absence of getComputedStyle\n\t\tpixelPositionVal = boxSizingReliableVal = false;\n\t\treliableMarginRightVal = true;\n\n\t\t// Check for getComputedStyle so that this code is not run in IE<9.\n\t\tif ( window.getComputedStyle ) {\n\t\t\tpixelPositionVal = ( window.getComputedStyle( div, null ) || {} ).top !== \"1%\";\n\t\t\tboxSizingReliableVal =\n\t\t\t\t( window.getComputedStyle( div, null ) || { width: \"4px\" } ).width === \"4px\";\n\n\t\t\t// Support: Android 2.3\n\t\t\t// Div with explicit width and no margin-right incorrectly\n\t\t\t// gets computed margin-right based on width of container (#3333)\n\t\t\t// WebKit Bug 13343 - getComputedStyle returns wrong value for margin-right\n\t\t\tcontents = div.appendChild( document.createElement( \"div\" ) );\n\n\t\t\t// Reset CSS: box-sizing; display; margin; border; padding\n\t\t\tcontents.style.cssText = div.style.cssText =\n\t\t\t\t// Support: Firefox<29, Android 2.3\n\t\t\t\t// Vendor-prefix box-sizing\n\t\t\t\t\"-webkit-box-sizing:content-box;-moz-box-sizing:content-box;\" +\n\t\t\t\t\"box-sizing:content-box;display:block;margin:0;border:0;padding:0\";\n\t\t\tcontents.style.marginRight = contents.style.width = \"0\";\n\t\t\tdiv.style.width = \"1px\";\n\n\t\t\treliableMarginRightVal =\n\t\t\t\t!parseFloat( ( window.getComputedStyle( contents, null ) || {} ).marginRight );\n\n\t\t\tdiv.removeChild( contents );\n\t\t}\n\n\t\t// Support: IE8\n\t\t// Check if table cells still have offsetWidth/Height when they are set\n\t\t// to display:none and there are still other visible table cells in a\n\t\t// table row; if so, offsetWidth/Height are not reliable for use when\n\t\t// determining if an element has been hidden directly using\n\t\t// display:none (it is still safe to use offsets if a parent element is\n\t\t// hidden; don safety goggles and see bug #4512 for more information).\n\t\tdiv.innerHTML = \"<table><tr><td></td><td>t</td></tr></table>\";\n\t\tcontents = div.getElementsByTagName( \"td\" );\n\t\tcontents[ 0 ].style.cssText = \"margin:0;border:0;padding:0;display:none\";\n\t\treliableHiddenOffsetsVal = contents[ 0 ].offsetHeight === 0;\n\t\tif ( reliableHiddenOffsetsVal ) {\n\t\t\tcontents[ 0 ].style.display = \"\";\n\t\t\tcontents[ 1 ].style.display = \"none\";\n\t\t\treliableHiddenOffsetsVal = contents[ 0 ].offsetHeight === 0;\n\t\t}\n\n\t\tbody.removeChild( container );\n\t}\n\n})();\n\n\n// A method for quickly swapping in/out CSS properties to get correct calculations.\njQuery.swap = function( elem, options, callback, args ) {\n\tvar ret, name,\n\t\told = {};\n\n\t// Remember the old values, and insert the new ones\n\tfor ( name in options ) {\n\t\told[ name ] = elem.style[ name ];\n\t\telem.style[ name ] = options[ name ];\n\t}\n\n\tret = callback.apply( elem, args || [] );\n\n\t// Revert the old values\n\tfor ( name in options ) {\n\t\telem.style[ name ] = old[ name ];\n\t}\n\n\treturn ret;\n};\n\n\nvar\n\t\tralpha = /alpha\\([^)]*\\)/i,\n\tropacity = /opacity\\s*=\\s*([^)]*)/,\n\n\t// swappable if display is none or starts with table except \"table\", \"table-cell\", or \"table-caption\"\n\t// see here for display values: https://developer.mozilla.org/en-US/docs/CSS/display\n\trdisplayswap = /^(none|table(?!-c[ea]).+)/,\n\trnumsplit = new RegExp( \"^(\" + pnum + \")(.*)$\", \"i\" ),\n\trrelNum = new RegExp( \"^([+-])=(\" + pnum + \")\", \"i\" ),\n\n\tcssShow = { position: \"absolute\", visibility: \"hidden\", display: \"block\" },\n\tcssNormalTransform = {\n\t\tletterSpacing: \"0\",\n\t\tfontWeight: \"400\"\n\t},\n\n\tcssPrefixes = [ \"Webkit\", \"O\", \"Moz\", \"ms\" ];\n\n\n// return a css property mapped to a potentially vendor prefixed property\nfunction vendorPropName( style, name ) {\n\n\t// shortcut for names that are not vendor prefixed\n\tif ( name in style ) {\n\t\treturn name;\n\t}\n\n\t// check for vendor prefixed names\n\tvar capName = name.charAt(0).toUpperCase() + name.slice(1),\n\t\torigName = name,\n\t\ti = cssPrefixes.length;\n\n\twhile ( i-- ) {\n\t\tname = cssPrefixes[ i ] + capName;\n\t\tif ( name in style ) {\n\t\t\treturn name;\n\t\t}\n\t}\n\n\treturn origName;\n}\n\nfunction showHide( elements, show ) {\n\tvar display, elem, hidden,\n\t\tvalues = [],\n\t\tindex = 0,\n\t\tlength = elements.length;\n\n\tfor ( ; index < length; index++ ) {\n\t\telem = elements[ index ];\n\t\tif ( !elem.style ) {\n\t\t\tcontinue;\n\t\t}\n\n\t\tvalues[ index ] = jQuery._data( elem, \"olddisplay\" );\n\t\tdisplay = elem.style.display;\n\t\tif ( show ) {\n\t\t\t// Reset the inline display of this element to learn if it is\n\t\t\t// being hidden by cascaded rules or not\n\t\t\tif ( !values[ index ] && display === \"none\" ) {\n\t\t\t\telem.style.display = \"\";\n\t\t\t}\n\n\t\t\t// Set elements which have been overridden with display: none\n\t\t\t// in a stylesheet to whatever the default browser style is\n\t\t\t// for such an element\n\t\t\tif ( elem.style.display === \"\" && isHidden( elem ) ) {\n\t\t\t\tvalues[ index ] = jQuery._data( elem, \"olddisplay\", defaultDisplay(elem.nodeName) );\n\t\t\t}\n\t\t} else {\n\t\t\thidden = isHidden( elem );\n\n\t\t\tif ( display && display !== \"none\" || !hidden ) {\n\t\t\t\tjQuery._data( elem, \"olddisplay\", hidden ? display : jQuery.css( elem, \"display\" ) );\n\t\t\t}\n\t\t}\n\t}\n\n\t// Set the display of most of the elements in a second loop\n\t// to avoid the constant reflow\n\tfor ( index = 0; index < length; index++ ) {\n\t\telem = elements[ index ];\n\t\tif ( !elem.style ) {\n\t\t\tcontinue;\n\t\t}\n\t\tif ( !show || elem.style.display === \"none\" || elem.style.display === \"\" ) {\n\t\t\telem.style.display = show ? values[ index ] || \"\" : \"none\";\n\t\t}\n\t}\n\n\treturn elements;\n}\n\nfunction setPositiveNumber( elem, value, subtract ) {\n\tvar matches = rnumsplit.exec( value );\n\treturn matches ?\n\t\t// Guard against undefined \"subtract\", e.g., when used as in cssHooks\n\t\tMath.max( 0, matches[ 1 ] - ( subtract || 0 ) ) + ( matches[ 2 ] || \"px\" ) :\n\t\tvalue;\n}\n\nfunction augmentWidthOrHeight( elem, name, extra, isBorderBox, styles ) {\n\tvar i = extra === ( isBorderBox ? \"border\" : \"content\" ) ?\n\t\t// If we already have the right measurement, avoid augmentation\n\t\t4 :\n\t\t// Otherwise initialize for horizontal or vertical properties\n\t\tname === \"width\" ? 1 : 0,\n\n\t\tval = 0;\n\n\tfor ( ; i < 4; i += 2 ) {\n\t\t// both box models exclude margin, so add it if we want it\n\t\tif ( extra === \"margin\" ) {\n\t\t\tval += jQuery.css( elem, extra + cssExpand[ i ], true, styles );\n\t\t}\n\n\t\tif ( isBorderBox ) {\n\t\t\t// border-box includes padding, so remove it if we want content\n\t\t\tif ( extra === \"content\" ) {\n\t\t\t\tval -= jQuery.css( elem, \"padding\" + cssExpand[ i ], true, styles );\n\t\t\t}\n\n\t\t\t// at this point, extra isn't border nor margin, so remove border\n\t\t\tif ( extra !== \"margin\" ) {\n\t\t\t\tval -= jQuery.css( elem, \"border\" + cssExpand[ i ] + \"Width\", true, styles );\n\t\t\t}\n\t\t} else {\n\t\t\t// at this point, extra isn't content, so add padding\n\t\t\tval += jQuery.css( elem, \"padding\" + cssExpand[ i ], true, styles );\n\n\t\t\t// at this point, extra isn't content nor padding, so add border\n\t\t\tif ( extra !== \"padding\" ) {\n\t\t\t\tval += jQuery.css( elem, \"border\" + cssExpand[ i ] + \"Width\", true, styles );\n\t\t\t}\n\t\t}\n\t}\n\n\treturn val;\n}\n\nfunction getWidthOrHeight( elem, name, extra ) {\n\n\t// Start with offset property, which is equivalent to the border-box value\n\tvar valueIsBorderBox = true,\n\t\tval = name === \"width\" ? elem.offsetWidth : elem.offsetHeight,\n\t\tstyles = getStyles( elem ),\n\t\tisBorderBox = support.boxSizing && jQuery.css( elem, \"boxSizing\", false, styles ) === \"border-box\";\n\n\t// some non-html elements return undefined for offsetWidth, so check for null/undefined\n\t// svg - https://bugzilla.mozilla.org/show_bug.cgi?id=649285\n\t// MathML - https://bugzilla.mozilla.org/show_bug.cgi?id=491668\n\tif ( val <= 0 || val == null ) {\n\t\t// Fall back to computed then uncomputed css if necessary\n\t\tval = curCSS( elem, name, styles );\n\t\tif ( val < 0 || val == null ) {\n\t\t\tval = elem.style[ name ];\n\t\t}\n\n\t\t// Computed unit is not pixels. Stop here and return.\n\t\tif ( rnumnonpx.test(val) ) {\n\t\t\treturn val;\n\t\t}\n\n\t\t// we need the check for style in case a browser which returns unreliable values\n\t\t// for getComputedStyle silently falls back to the reliable elem.style\n\t\tvalueIsBorderBox = isBorderBox && ( support.boxSizingReliable() || val === elem.style[ name ] );\n\n\t\t// Normalize \"\", auto, and prepare for extra\n\t\tval = parseFloat( val ) || 0;\n\t}\n\n\t// use the active box-sizing model to add/subtract irrelevant styles\n\treturn ( val +\n\t\taugmentWidthOrHeight(\n\t\t\telem,\n\t\t\tname,\n\t\t\textra || ( isBorderBox ? \"border\" : \"content\" ),\n\t\t\tvalueIsBorderBox,\n\t\t\tstyles\n\t\t)\n\t) + \"px\";\n}\n\njQuery.extend({\n\t// Add in style property hooks for overriding the default\n\t// behavior of getting and setting a style property\n\tcssHooks: {\n\t\topacity: {\n\t\t\tget: function( elem, computed ) {\n\t\t\t\tif ( computed ) {\n\t\t\t\t\t// We should always get a number back from opacity\n\t\t\t\t\tvar ret = curCSS( elem, \"opacity\" );\n\t\t\t\t\treturn ret === \"\" ? \"1\" : ret;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t},\n\n\t// Don't automatically add \"px\" to these possibly-unitless properties\n\tcssNumber: {\n\t\t\"columnCount\": true,\n\t\t\"fillOpacity\": true,\n\t\t\"flexGrow\": true,\n\t\t\"flexShrink\": true,\n\t\t\"fontWeight\": true,\n\t\t\"lineHeight\": true,\n\t\t\"opacity\": true,\n\t\t\"order\": true,\n\t\t\"orphans\": true,\n\t\t\"widows\": true,\n\t\t\"zIndex\": true,\n\t\t\"zoom\": true\n\t},\n\n\t// Add in properties whose names you wish to fix before\n\t// setting or getting the value\n\tcssProps: {\n\t\t// normalize float css property\n\t\t\"float\": support.cssFloat ? \"cssFloat\" : \"styleFloat\"\n\t},\n\n\t// Get and set the style property on a DOM Node\n\tstyle: function( elem, name, value, extra ) {\n\t\t// Don't set styles on text and comment nodes\n\t\tif ( !elem || elem.nodeType === 3 || elem.nodeType === 8 || !elem.style ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Make sure that we're working with the right name\n\t\tvar ret, type, hooks,\n\t\t\torigName = jQuery.camelCase( name ),\n\t\t\tstyle = elem.style;\n\n\t\tname = jQuery.cssProps[ origName ] || ( jQuery.cssProps[ origName ] = vendorPropName( style, origName ) );\n\n\t\t// gets hook for the prefixed version\n\t\t// followed by the unprefixed version\n\t\thooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ];\n\n\t\t// Check if we're setting a value\n\t\tif ( value !== undefined ) {\n\t\t\ttype = typeof value;\n\n\t\t\t// convert relative number strings (+= or -=) to relative numbers. #7345\n\t\t\tif ( type === \"string\" && (ret = rrelNum.exec( value )) ) {\n\t\t\t\tvalue = ( ret[1] + 1 ) * ret[2] + parseFloat( jQuery.css( elem, name ) );\n\t\t\t\t// Fixes bug #9237\n\t\t\t\ttype = \"number\";\n\t\t\t}\n\n\t\t\t// Make sure that null and NaN values aren't set. See: #7116\n\t\t\tif ( value == null || value !== value ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// If a number was passed in, add 'px' to the (except for certain CSS properties)\n\t\t\tif ( type === \"number\" && !jQuery.cssNumber[ origName ] ) {\n\t\t\t\tvalue += \"px\";\n\t\t\t}\n\n\t\t\t// Fixes #8908, it can be done more correctly by specifing setters in cssHooks,\n\t\t\t// but it would mean to define eight (for every problematic property) identical functions\n\t\t\tif ( !support.clearCloneStyle && value === \"\" && name.indexOf(\"background\") === 0 ) {\n\t\t\t\tstyle[ name ] = \"inherit\";\n\t\t\t}\n\n\t\t\t// If a hook was provided, use that value, otherwise just set the specified value\n\t\t\tif ( !hooks || !(\"set\" in hooks) || (value = hooks.set( elem, value, extra )) !== undefined ) {\n\n\t\t\t\t// Support: IE\n\t\t\t\t// Swallow errors from 'invalid' CSS values (#5509)\n\t\t\t\ttry {\n\t\t\t\t\tstyle[ name ] = value;\n\t\t\t\t} catch(e) {}\n\t\t\t}\n\n\t\t} else {\n\t\t\t// If a hook was provided get the non-computed value from there\n\t\t\tif ( hooks && \"get\" in hooks && (ret = hooks.get( elem, false, extra )) !== undefined ) {\n\t\t\t\treturn ret;\n\t\t\t}\n\n\t\t\t// Otherwise just get the value from the style object\n\t\t\treturn style[ name ];\n\t\t}\n\t},\n\n\tcss: function( elem, name, extra, styles ) {\n\t\tvar num, val, hooks,\n\t\t\torigName = jQuery.camelCase( name );\n\n\t\t// Make sure that we're working with the right name\n\t\tname = jQuery.cssProps[ origName ] || ( jQuery.cssProps[ origName ] = vendorPropName( elem.style, origName ) );\n\n\t\t// gets hook for the prefixed version\n\t\t// followed by the unprefixed version\n\t\thooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ];\n\n\t\t// If a hook was provided get the computed value from there\n\t\tif ( hooks && \"get\" in hooks ) {\n\t\t\tval = hooks.get( elem, true, extra );\n\t\t}\n\n\t\t// Otherwise, if a way to get the computed value exists, use that\n\t\tif ( val === undefined ) {\n\t\t\tval = curCSS( elem, name, styles );\n\t\t}\n\n\t\t//convert \"normal\" to computed value\n\t\tif ( val === \"normal\" && name in cssNormalTransform ) {\n\t\t\tval = cssNormalTransform[ name ];\n\t\t}\n\n\t\t// Return, converting to number if forced or a qualifier was provided and val looks numeric\n\t\tif ( extra === \"\" || extra ) {\n\t\t\tnum = parseFloat( val );\n\t\t\treturn extra === true || jQuery.isNumeric( num ) ? num || 0 : val;\n\t\t}\n\t\treturn val;\n\t}\n});\n\njQuery.each([ \"height\", \"width\" ], function( i, name ) {\n\tjQuery.cssHooks[ name ] = {\n\t\tget: function( elem, computed, extra ) {\n\t\t\tif ( computed ) {\n\t\t\t\t// certain elements can have dimension info if we invisibly show them\n\t\t\t\t// however, it must have a current display style that would benefit from this\n\t\t\t\treturn rdisplayswap.test( jQuery.css( elem, \"display\" ) ) && elem.offsetWidth === 0 ?\n\t\t\t\t\tjQuery.swap( elem, cssShow, function() {\n\t\t\t\t\t\treturn getWidthOrHeight( elem, name, extra );\n\t\t\t\t\t}) :\n\t\t\t\t\tgetWidthOrHeight( elem, name, extra );\n\t\t\t}\n\t\t},\n\n\t\tset: function( elem, value, extra ) {\n\t\t\tvar styles = extra && getStyles( elem );\n\t\t\treturn setPositiveNumber( elem, value, extra ?\n\t\t\t\taugmentWidthOrHeight(\n\t\t\t\t\telem,\n\t\t\t\t\tname,\n\t\t\t\t\textra,\n\t\t\t\t\tsupport.boxSizing && jQuery.css( elem, \"boxSizing\", false, styles ) === \"border-box\",\n\t\t\t\t\tstyles\n\t\t\t\t) : 0\n\t\t\t);\n\t\t}\n\t};\n});\n\nif ( !support.opacity ) {\n\tjQuery.cssHooks.opacity = {\n\t\tget: function( elem, computed ) {\n\t\t\t// IE uses filters for opacity\n\t\t\treturn ropacity.test( (computed && elem.currentStyle ? elem.currentStyle.filter : elem.style.filter) || \"\" ) ?\n\t\t\t\t( 0.01 * parseFloat( RegExp.$1 ) ) + \"\" :\n\t\t\t\tcomputed ? \"1\" : \"\";\n\t\t},\n\n\t\tset: function( elem, value ) {\n\t\t\tvar style = elem.style,\n\t\t\t\tcurrentStyle = elem.currentStyle,\n\t\t\t\topacity = jQuery.isNumeric( value ) ? \"alpha(opacity=\" + value * 100 + \")\" : \"\",\n\t\t\t\tfilter = currentStyle && currentStyle.filter || style.filter || \"\";\n\n\t\t\t// IE has trouble with opacity if it does not have layout\n\t\t\t// Force it by setting the zoom level\n\t\t\tstyle.zoom = 1;\n\n\t\t\t// if setting opacity to 1, and no other filters exist - attempt to remove filter attribute #6652\n\t\t\t// if value === \"\", then remove inline opacity #12685\n\t\t\tif ( ( value >= 1 || value === \"\" ) &&\n\t\t\t\t\tjQuery.trim( filter.replace( ralpha, \"\" ) ) === \"\" &&\n\t\t\t\t\tstyle.removeAttribute ) {\n\n\t\t\t\t// Setting style.filter to null, \"\" & \" \" still leave \"filter:\" in the cssText\n\t\t\t\t// if \"filter:\" is present at all, clearType is disabled, we want to avoid this\n\t\t\t\t// style.removeAttribute is IE Only, but so apparently is this code path...\n\t\t\t\tstyle.removeAttribute( \"filter\" );\n\n\t\t\t\t// if there is no filter style applied in a css rule or unset inline opacity, we are done\n\t\t\t\tif ( value === \"\" || currentStyle && !currentStyle.filter ) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// otherwise, set new filter values\n\t\t\tstyle.filter = ralpha.test( filter ) ?\n\t\t\t\tfilter.replace( ralpha, opacity ) :\n\t\t\t\tfilter + \" \" + opacity;\n\t\t}\n\t};\n}\n\njQuery.cssHooks.marginRight = addGetHookIf( support.reliableMarginRight,\n\tfunction( elem, computed ) {\n\t\tif ( computed ) {\n\t\t\t// WebKit Bug 13343 - getComputedStyle returns wrong value for margin-right\n\t\t\t// Work around by temporarily setting element display to inline-block\n\t\t\treturn jQuery.swap( elem, { \"display\": \"inline-block\" },\n\t\t\t\tcurCSS, [ elem, \"marginRight\" ] );\n\t\t}\n\t}\n);\n\n// These hooks are used by animate to expand properties\njQuery.each({\n\tmargin: \"\",\n\tpadding: \"\",\n\tborder: \"Width\"\n}, function( prefix, suffix ) {\n\tjQuery.cssHooks[ prefix + suffix ] = {\n\t\texpand: function( value ) {\n\t\t\tvar i = 0,\n\t\t\t\texpanded = {},\n\n\t\t\t\t// assumes a single number if not a string\n\t\t\t\tparts = typeof value === \"string\" ? value.split(\" \") : [ value ];\n\n\t\t\tfor ( ; i < 4; i++ ) {\n\t\t\t\texpanded[ prefix + cssExpand[ i ] + suffix ] =\n\t\t\t\t\tparts[ i ] || parts[ i - 2 ] || parts[ 0 ];\n\t\t\t}\n\n\t\t\treturn expanded;\n\t\t}\n\t};\n\n\tif ( !rmargin.test( prefix ) ) {\n\t\tjQuery.cssHooks[ prefix + suffix ].set = setPositiveNumber;\n\t}\n});\n\njQuery.fn.extend({\n\tcss: function( name, value ) {\n\t\treturn access( this, function( elem, name, value ) {\n\t\t\tvar styles, len,\n\t\t\t\tmap = {},\n\t\t\t\ti = 0;\n\n\t\t\tif ( jQuery.isArray( name ) ) {\n\t\t\t\tstyles = getStyles( elem );\n\t\t\t\tlen = name.length;\n\n\t\t\t\tfor ( ; i < len; i++ ) {\n\t\t\t\t\tmap[ name[ i ] ] = jQuery.css( elem, name[ i ], false, styles );\n\t\t\t\t}\n\n\t\t\t\treturn map;\n\t\t\t}\n\n\t\t\treturn value !== undefined ?\n\t\t\t\tjQuery.style( elem, name, value ) :\n\t\t\t\tjQuery.css( elem, name );\n\t\t}, name, value, arguments.length > 1 );\n\t},\n\tshow: function() {\n\t\treturn showHide( this, true );\n\t},\n\thide: function() {\n\t\treturn showHide( this );\n\t},\n\ttoggle: function( state ) {\n\t\tif ( typeof state === \"boolean\" ) {\n\t\t\treturn state ? this.show() : this.hide();\n\t\t}\n\n\t\treturn this.each(function() {\n\t\t\tif ( isHidden( this ) ) {\n\t\t\t\tjQuery( this ).show();\n\t\t\t} else {\n\t\t\t\tjQuery( this ).hide();\n\t\t\t}\n\t\t});\n\t}\n});\n\n\nfunction Tween( elem, options, prop, end, easing ) {\n\treturn new Tween.prototype.init( elem, options, prop, end, easing );\n}\njQuery.Tween = Tween;\n\nTween.prototype = {\n\tconstructor: Tween,\n\tinit: function( elem, options, prop, end, easing, unit ) {\n\t\tthis.elem = elem;\n\t\tthis.prop = prop;\n\t\tthis.easing = easing || \"swing\";\n\t\tthis.options = options;\n\t\tthis.start = this.now = this.cur();\n\t\tthis.end = end;\n\t\tthis.unit = unit || ( jQuery.cssNumber[ prop ] ? \"\" : \"px\" );\n\t},\n\tcur: function() {\n\t\tvar hooks = Tween.propHooks[ this.prop ];\n\n\t\treturn hooks && hooks.get ?\n\t\t\thooks.get( this ) :\n\t\t\tTween.propHooks._default.get( this );\n\t},\n\trun: function( percent ) {\n\t\tvar eased,\n\t\t\thooks = Tween.propHooks[ this.prop ];\n\n\t\tif ( this.options.duration ) {\n\t\t\tthis.pos = eased = jQuery.easing[ this.easing ](\n\t\t\t\tpercent, this.options.duration * percent, 0, 1, this.options.duration\n\t\t\t);\n\t\t} else {\n\t\t\tthis.pos = eased = percent;\n\t\t}\n\t\tthis.now = ( this.end - this.start ) * eased + this.start;\n\n\t\tif ( this.options.step ) {\n\t\t\tthis.options.step.call( this.elem, this.now, this );\n\t\t}\n\n\t\tif ( hooks && hooks.set ) {\n\t\t\thooks.set( this );\n\t\t} else {\n\t\t\tTween.propHooks._default.set( this );\n\t\t}\n\t\treturn this;\n\t}\n};\n\nTween.prototype.init.prototype = Tween.prototype;\n\nTween.propHooks = {\n\t_default: {\n\t\tget: function( tween ) {\n\t\t\tvar result;\n\n\t\t\tif ( tween.elem[ tween.prop ] != null &&\n\t\t\t\t(!tween.elem.style || tween.elem.style[ tween.prop ] == null) ) {\n\t\t\t\treturn tween.elem[ tween.prop ];\n\t\t\t}\n\n\t\t\t// passing an empty string as a 3rd parameter to .css will automatically\n\t\t\t// attempt a parseFloat and fallback to a string if the parse fails\n\t\t\t// so, simple values such as \"10px\" are parsed to Float.\n\t\t\t// complex values such as \"rotate(1rad)\" are returned as is.\n\t\t\tresult = jQuery.css( tween.elem, tween.prop, \"\" );\n\t\t\t// Empty strings, null, undefined and \"auto\" are converted to 0.\n\t\t\treturn !result || result === \"auto\" ? 0 : result;\n\t\t},\n\t\tset: function( tween ) {\n\t\t\t// use step hook for back compat - use cssHook if its there - use .style if its\n\t\t\t// available and use plain properties where available\n\t\t\tif ( jQuery.fx.step[ tween.prop ] ) {\n\t\t\t\tjQuery.fx.step[ tween.prop ]( tween );\n\t\t\t} else if ( tween.elem.style && ( tween.elem.style[ jQuery.cssProps[ tween.prop ] ] != null || jQuery.cssHooks[ tween.prop ] ) ) {\n\t\t\t\tjQuery.style( tween.elem, tween.prop, tween.now + tween.unit );\n\t\t\t} else {\n\t\t\t\ttween.elem[ tween.prop ] = tween.now;\n\t\t\t}\n\t\t}\n\t}\n};\n\n// Support: IE <=9\n// Panic based approach to setting things on disconnected nodes\n\nTween.propHooks.scrollTop = Tween.propHooks.scrollLeft = {\n\tset: function( tween ) {\n\t\tif ( tween.elem.nodeType && tween.elem.parentNode ) {\n\t\t\ttween.elem[ tween.prop ] = tween.now;\n\t\t}\n\t}\n};\n\njQuery.easing = {\n\tlinear: function( p ) {\n\t\treturn p;\n\t},\n\tswing: function( p ) {\n\t\treturn 0.5 - Math.cos( p * Math.PI ) / 2;\n\t}\n};\n\njQuery.fx = Tween.prototype.init;\n\n// Back Compat <1.8 extension point\njQuery.fx.step = {};\n\n\n\n\nvar\n\tfxNow, timerId,\n\trfxtypes = /^(?:toggle|show|hide)$/,\n\trfxnum = new RegExp( \"^(?:([+-])=|)(\" + pnum + \")([a-z%]*)$\", \"i\" ),\n\trrun = /queueHooks$/,\n\tanimationPrefilters = [ defaultPrefilter ],\n\ttweeners = {\n\t\t\"*\": [ function( prop, value ) {\n\t\t\tvar tween = this.createTween( prop, value ),\n\t\t\t\ttarget = tween.cur(),\n\t\t\t\tparts = rfxnum.exec( value ),\n\t\t\t\tunit = parts && parts[ 3 ] || ( jQuery.cssNumber[ prop ] ? \"\" : \"px\" ),\n\n\t\t\t\t// Starting value computation is required for potential unit mismatches\n\t\t\t\tstart = ( jQuery.cssNumber[ prop ] || unit !== \"px\" && +target ) &&\n\t\t\t\t\trfxnum.exec( jQuery.css( tween.elem, prop ) ),\n\t\t\t\tscale = 1,\n\t\t\t\tmaxIterations = 20;\n\n\t\t\tif ( start && start[ 3 ] !== unit ) {\n\t\t\t\t// Trust units reported by jQuery.css\n\t\t\t\tunit = unit || start[ 3 ];\n\n\t\t\t\t// Make sure we update the tween properties later on\n\t\t\t\tparts = parts || [];\n\n\t\t\t\t// Iteratively approximate from a nonzero starting point\n\t\t\t\tstart = +target || 1;\n\n\t\t\t\tdo {\n\t\t\t\t\t// If previous iteration zeroed out, double until we get *something*\n\t\t\t\t\t// Use a string for doubling factor so we don't accidentally see scale as unchanged below\n\t\t\t\t\tscale = scale || \".5\";\n\n\t\t\t\t\t// Adjust and apply\n\t\t\t\t\tstart = start / scale;\n\t\t\t\t\tjQuery.style( tween.elem, prop, start + unit );\n\n\t\t\t\t// Update scale, tolerating zero or NaN from tween.cur()\n\t\t\t\t// And breaking the loop if scale is unchanged or perfect, or if we've just had enough\n\t\t\t\t} while ( scale !== (scale = tween.cur() / target) && scale !== 1 && --maxIterations );\n\t\t\t}\n\n\t\t\t// Update tween properties\n\t\t\tif ( parts ) {\n\t\t\t\tstart = tween.start = +start || +target || 0;\n\t\t\t\ttween.unit = unit;\n\t\t\t\t// If a +=/-= token was provided, we're doing a relative animation\n\t\t\t\ttween.end = parts[ 1 ] ?\n\t\t\t\t\tstart + ( parts[ 1 ] + 1 ) * parts[ 2 ] :\n\t\t\t\t\t+parts[ 2 ];\n\t\t\t}\n\n\t\t\treturn tween;\n\t\t} ]\n\t};\n\n// Animations created synchronously will run synchronously\nfunction createFxNow() {\n\tsetTimeout(function() {\n\t\tfxNow = undefined;\n\t});\n\treturn ( fxNow = jQuery.now() );\n}\n\n// Generate parameters to create a standard animation\nfunction genFx( type, includeWidth ) {\n\tvar which,\n\t\tattrs = { height: type },\n\t\ti = 0;\n\n\t// if we include width, step value is 1 to do all cssExpand values,\n\t// if we don't include width, step value is 2 to skip over Left and Right\n\tincludeWidth = includeWidth ? 1 : 0;\n\tfor ( ; i < 4 ; i += 2 - includeWidth ) {\n\t\twhich = cssExpand[ i ];\n\t\tattrs[ \"margin\" + which ] = attrs[ \"padding\" + which ] = type;\n\t}\n\n\tif ( includeWidth ) {\n\t\tattrs.opacity = attrs.width = type;\n\t}\n\n\treturn attrs;\n}\n\nfunction createTween( value, prop, animation ) {\n\tvar tween,\n\t\tcollection = ( tweeners[ prop ] || [] ).concat( tweeners[ \"*\" ] ),\n\t\tindex = 0,\n\t\tlength = collection.length;\n\tfor ( ; index < length; index++ ) {\n\t\tif ( (tween = collection[ index ].call( animation, prop, value )) ) {\n\n\t\t\t// we're done with this property\n\t\t\treturn tween;\n\t\t}\n\t}\n}\n\nfunction defaultPrefilter( elem, props, opts ) {\n\t/* jshint validthis: true */\n\tvar prop, value, toggle, tween, hooks, oldfire, display, checkDisplay,\n\t\tanim = this,\n\t\torig = {},\n\t\tstyle = elem.style,\n\t\thidden = elem.nodeType && isHidden( elem ),\n\t\tdataShow = jQuery._data( elem, \"fxshow\" );\n\n\t// handle queue: false promises\n\tif ( !opts.queue ) {\n\t\thooks = jQuery._queueHooks( elem, \"fx\" );\n\t\tif ( hooks.unqueued == null ) {\n\t\t\thooks.unqueued = 0;\n\t\t\toldfire = hooks.empty.fire;\n\t\t\thooks.empty.fire = function() {\n\t\t\t\tif ( !hooks.unqueued ) {\n\t\t\t\t\toldfire();\n\t\t\t\t}\n\t\t\t};\n\t\t}\n\t\thooks.unqueued++;\n\n\t\tanim.always(function() {\n\t\t\t// doing this makes sure that the complete handler will be called\n\t\t\t// before this completes\n\t\t\tanim.always(function() {\n\t\t\t\thooks.unqueued--;\n\t\t\t\tif ( !jQuery.queue( elem, \"fx\" ).length ) {\n\t\t\t\t\thooks.empty.fire();\n\t\t\t\t}\n\t\t\t});\n\t\t});\n\t}\n\n\t// height/width overflow pass\n\tif ( elem.nodeType === 1 && ( \"height\" in props || \"width\" in props ) ) {\n\t\t// Make sure that nothing sneaks out\n\t\t// Record all 3 overflow attributes because IE does not\n\t\t// change the overflow attribute when overflowX and\n\t\t// overflowY are set to the same value\n\t\topts.overflow = [ style.overflow, style.overflowX, style.overflowY ];\n\n\t\t// Set display property to inline-block for height/width\n\t\t// animations on inline elements that are having width/height animated\n\t\tdisplay = jQuery.css( elem, \"display\" );\n\n\t\t// Test default display if display is currently \"none\"\n\t\tcheckDisplay = display === \"none\" ?\n\t\t\tjQuery._data( elem, \"olddisplay\" ) || defaultDisplay( elem.nodeName ) : display;\n\n\t\tif ( checkDisplay === \"inline\" && jQuery.css( elem, \"float\" ) === \"none\" ) {\n\n\t\t\t// inline-level elements accept inline-block;\n\t\t\t// block-level elements need to be inline with layout\n\t\t\tif ( !support.inlineBlockNeedsLayout || defaultDisplay( elem.nodeName ) === \"inline\" ) {\n\t\t\t\tstyle.display = \"inline-block\";\n\t\t\t} else {\n\t\t\t\tstyle.zoom = 1;\n\t\t\t}\n\t\t}\n\t}\n\n\tif ( opts.overflow ) {\n\t\tstyle.overflow = \"hidden\";\n\t\tif ( !support.shrinkWrapBlocks() ) {\n\t\t\tanim.always(function() {\n\t\t\t\tstyle.overflow = opts.overflow[ 0 ];\n\t\t\t\tstyle.overflowX = opts.overflow[ 1 ];\n\t\t\t\tstyle.overflowY = opts.overflow[ 2 ];\n\t\t\t});\n\t\t}\n\t}\n\n\t// show/hide pass\n\tfor ( prop in props ) {\n\t\tvalue = props[ prop ];\n\t\tif ( rfxtypes.exec( value ) ) {\n\t\t\tdelete props[ prop ];\n\t\t\ttoggle = toggle || value === \"toggle\";\n\t\t\tif ( value === ( hidden ? \"hide\" : \"show\" ) ) {\n\n\t\t\t\t// If there is dataShow left over from a stopped hide or show and we are going to proceed with show, we should pretend to be hidden\n\t\t\t\tif ( value === \"show\" && dataShow && dataShow[ prop ] !== undefined ) {\n\t\t\t\t\thidden = true;\n\t\t\t\t} else {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t}\n\t\t\torig[ prop ] = dataShow && dataShow[ prop ] || jQuery.style( elem, prop );\n\n\t\t// Any non-fx value stops us from restoring the original display value\n\t\t} else {\n\t\t\tdisplay = undefined;\n\t\t}\n\t}\n\n\tif ( !jQuery.isEmptyObject( orig ) ) {\n\t\tif ( dataShow ) {\n\t\t\tif ( \"hidden\" in dataShow ) {\n\t\t\t\thidden = dataShow.hidden;\n\t\t\t}\n\t\t} else {\n\t\t\tdataShow = jQuery._data( elem, \"fxshow\", {} );\n\t\t}\n\n\t\t// store state if its toggle - enables .stop().toggle() to \"reverse\"\n\t\tif ( toggle ) {\n\t\t\tdataShow.hidden = !hidden;\n\t\t}\n\t\tif ( hidden ) {\n\t\t\tjQuery( elem ).show();\n\t\t} else {\n\t\t\tanim.done(function() {\n\t\t\t\tjQuery( elem ).hide();\n\t\t\t});\n\t\t}\n\t\tanim.done(function() {\n\t\t\tvar prop;\n\t\t\tjQuery._removeData( elem, \"fxshow\" );\n\t\t\tfor ( prop in orig ) {\n\t\t\t\tjQuery.style( elem, prop, orig[ prop ] );\n\t\t\t}\n\t\t});\n\t\tfor ( prop in orig ) {\n\t\t\ttween = createTween( hidden ? dataShow[ prop ] : 0, prop, anim );\n\n\t\t\tif ( !( prop in dataShow ) ) {\n\t\t\t\tdataShow[ prop ] = tween.start;\n\t\t\t\tif ( hidden ) {\n\t\t\t\t\ttween.end = tween.start;\n\t\t\t\t\ttween.start = prop === \"width\" || prop === \"height\" ? 1 : 0;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t// If this is a noop like .hide().hide(), restore an overwritten display value\n\t} else if ( (display === \"none\" ? defaultDisplay( elem.nodeName ) : display) === \"inline\" ) {\n\t\tstyle.display = display;\n\t}\n}\n\nfunction propFilter( props, specialEasing ) {\n\tvar index, name, easing, value, hooks;\n\n\t// camelCase, specialEasing and expand cssHook pass\n\tfor ( index in props ) {\n\t\tname = jQuery.camelCase( index );\n\t\teasing = specialEasing[ name ];\n\t\tvalue = props[ index ];\n\t\tif ( jQuery.isArray( value ) ) {\n\t\t\teasing = value[ 1 ];\n\t\t\tvalue = props[ index ] = value[ 0 ];\n\t\t}\n\n\t\tif ( index !== name ) {\n\t\t\tprops[ name ] = value;\n\t\t\tdelete props[ index ];\n\t\t}\n\n\t\thooks = jQuery.cssHooks[ name ];\n\t\tif ( hooks && \"expand\" in hooks ) {\n\t\t\tvalue = hooks.expand( value );\n\t\t\tdelete props[ name ];\n\n\t\t\t// not quite $.extend, this wont overwrite keys already present.\n\t\t\t// also - reusing 'index' from above because we have the correct \"name\"\n\t\t\tfor ( index in value ) {\n\t\t\t\tif ( !( index in props ) ) {\n\t\t\t\t\tprops[ index ] = value[ index ];\n\t\t\t\t\tspecialEasing[ index ] = easing;\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\tspecialEasing[ name ] = easing;\n\t\t}\n\t}\n}\n\nfunction Animation( elem, properties, options ) {\n\tvar result,\n\t\tstopped,\n\t\tindex = 0,\n\t\tlength = animationPrefilters.length,\n\t\tdeferred = jQuery.Deferred().always( function() {\n\t\t\t// don't match elem in the :animated selector\n\t\t\tdelete tick.elem;\n\t\t}),\n\t\ttick = function() {\n\t\t\tif ( stopped ) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\tvar currentTime = fxNow || createFxNow(),\n\t\t\t\tremaining = Math.max( 0, animation.startTime + animation.duration - currentTime ),\n\t\t\t\t// archaic crash bug won't allow us to use 1 - ( 0.5 || 0 ) (#12497)\n\t\t\t\ttemp = remaining / animation.duration || 0,\n\t\t\t\tpercent = 1 - temp,\n\t\t\t\tindex = 0,\n\t\t\t\tlength = animation.tweens.length;\n\n\t\t\tfor ( ; index < length ; index++ ) {\n\t\t\t\tanimation.tweens[ index ].run( percent );\n\t\t\t}\n\n\t\t\tdeferred.notifyWith( elem, [ animation, percent, remaining ]);\n\n\t\t\tif ( percent < 1 && length ) {\n\t\t\t\treturn remaining;\n\t\t\t} else {\n\t\t\t\tdeferred.resolveWith( elem, [ animation ] );\n\t\t\t\treturn false;\n\t\t\t}\n\t\t},\n\t\tanimation = deferred.promise({\n\t\t\telem: elem,\n\t\t\tprops: jQuery.extend( {}, properties ),\n\t\t\topts: jQuery.extend( true, { specialEasing: {} }, options ),\n\t\t\toriginalProperties: properties,\n\t\t\toriginalOptions: options,\n\t\t\tstartTime: fxNow || createFxNow(),\n\t\t\tduration: options.duration,\n\t\t\ttweens: [],\n\t\t\tcreateTween: function( prop, end ) {\n\t\t\t\tvar tween = jQuery.Tween( elem, animation.opts, prop, end,\n\t\t\t\t\t\tanimation.opts.specialEasing[ prop ] || animation.opts.easing );\n\t\t\t\tanimation.tweens.push( tween );\n\t\t\t\treturn tween;\n\t\t\t},\n\t\t\tstop: function( gotoEnd ) {\n\t\t\t\tvar index = 0,\n\t\t\t\t\t// if we are going to the end, we want to run all the tweens\n\t\t\t\t\t// otherwise we skip this part\n\t\t\t\t\tlength = gotoEnd ? animation.tweens.length : 0;\n\t\t\t\tif ( stopped ) {\n\t\t\t\t\treturn this;\n\t\t\t\t}\n\t\t\t\tstopped = true;\n\t\t\t\tfor ( ; index < length ; index++ ) {\n\t\t\t\t\tanimation.tweens[ index ].run( 1 );\n\t\t\t\t}\n\n\t\t\t\t// resolve when we played the last frame\n\t\t\t\t// otherwise, reject\n\t\t\t\tif ( gotoEnd ) {\n\t\t\t\t\tdeferred.resolveWith( elem, [ animation, gotoEnd ] );\n\t\t\t\t} else {\n\t\t\t\t\tdeferred.rejectWith( elem, [ animation, gotoEnd ] );\n\t\t\t\t}\n\t\t\t\treturn this;\n\t\t\t}\n\t\t}),\n\t\tprops = animation.props;\n\n\tpropFilter( props, animation.opts.specialEasing );\n\n\tfor ( ; index < length ; index++ ) {\n\t\tresult = animationPrefilters[ index ].call( animation, elem, props, animation.opts );\n\t\tif ( result ) {\n\t\t\treturn result;\n\t\t}\n\t}\n\n\tjQuery.map( props, createTween, animation );\n\n\tif ( jQuery.isFunction( animation.opts.start ) ) {\n\t\tanimation.opts.start.call( elem, animation );\n\t}\n\n\tjQuery.fx.timer(\n\t\tjQuery.extend( tick, {\n\t\t\telem: elem,\n\t\t\tanim: animation,\n\t\t\tqueue: animation.opts.queue\n\t\t})\n\t);\n\n\t// attach callbacks from options\n\treturn animation.progress( animation.opts.progress )\n\t\t.done( animation.opts.done, animation.opts.complete )\n\t\t.fail( animation.opts.fail )\n\t\t.always( animation.opts.always );\n}\n\njQuery.Animation = jQuery.extend( Animation, {\n\ttweener: function( props, callback ) {\n\t\tif ( jQuery.isFunction( props ) ) {\n\t\t\tcallback = props;\n\t\t\tprops = [ \"*\" ];\n\t\t} else {\n\t\t\tprops = props.split(\" \");\n\t\t}\n\n\t\tvar prop,\n\t\t\tindex = 0,\n\t\t\tlength = props.length;\n\n\t\tfor ( ; index < length ; index++ ) {\n\t\t\tprop = props[ index ];\n\t\t\ttweeners[ prop ] = tweeners[ prop ] || [];\n\t\t\ttweeners[ prop ].unshift( callback );\n\t\t}\n\t},\n\n\tprefilter: function( callback, prepend ) {\n\t\tif ( prepend ) {\n\t\t\tanimationPrefilters.unshift( callback );\n\t\t} else {\n\t\t\tanimationPrefilters.push( callback );\n\t\t}\n\t}\n});\n\njQuery.speed = function( speed, easing, fn ) {\n\tvar opt = speed && typeof speed === \"object\" ? jQuery.extend( {}, speed ) : {\n\t\tcomplete: fn || !fn && easing ||\n\t\t\tjQuery.isFunction( speed ) && speed,\n\t\tduration: speed,\n\t\teasing: fn && easing || easing && !jQuery.isFunction( easing ) && easing\n\t};\n\n\topt.duration = jQuery.fx.off ? 0 : typeof opt.duration === \"number\" ? opt.duration :\n\t\topt.duration in jQuery.fx.speeds ? jQuery.fx.speeds[ opt.duration ] : jQuery.fx.speeds._default;\n\n\t// normalize opt.queue - true/undefined/null -> \"fx\"\n\tif ( opt.queue == null || opt.queue === true ) {\n\t\topt.queue = \"fx\";\n\t}\n\n\t// Queueing\n\topt.old = opt.complete;\n\n\topt.complete = function() {\n\t\tif ( jQuery.isFunction( opt.old ) ) {\n\t\t\topt.old.call( this );\n\t\t}\n\n\t\tif ( opt.queue ) {\n\t\t\tjQuery.dequeue( this, opt.queue );\n\t\t}\n\t};\n\n\treturn opt;\n};\n\njQuery.fn.extend({\n\tfadeTo: function( speed, to, easing, callback ) {\n\n\t\t// show any hidden elements after setting opacity to 0\n\t\treturn this.filter( isHidden ).css( \"opacity\", 0 ).show()\n\n\t\t\t// animate to the value specified\n\t\t\t.end().animate({ opacity: to }, speed, easing, callback );\n\t},\n\tanimate: function( prop, speed, easing, callback ) {\n\t\tvar empty = jQuery.isEmptyObject( prop ),\n\t\t\toptall = jQuery.speed( speed, easing, callback ),\n\t\t\tdoAnimation = function() {\n\t\t\t\t// Operate on a copy of prop so per-property easing won't be lost\n\t\t\t\tvar anim = Animation( this, jQuery.extend( {}, prop ), optall );\n\n\t\t\t\t// Empty animations, or finishing resolves immediately\n\t\t\t\tif ( empty || jQuery._data( this, \"finish\" ) ) {\n\t\t\t\t\tanim.stop( true );\n\t\t\t\t}\n\t\t\t};\n\t\t\tdoAnimation.finish = doAnimation;\n\n\t\treturn empty || optall.queue === false ?\n\t\t\tthis.each( doAnimation ) :\n\t\t\tthis.queue( optall.queue, doAnimation );\n\t},\n\tstop: function( type, clearQueue, gotoEnd ) {\n\t\tvar stopQueue = function( hooks ) {\n\t\t\tvar stop = hooks.stop;\n\t\t\tdelete hooks.stop;\n\t\t\tstop( gotoEnd );\n\t\t};\n\n\t\tif ( typeof type !== \"string\" ) {\n\t\t\tgotoEnd = clearQueue;\n\t\t\tclearQueue = type;\n\t\t\ttype = undefined;\n\t\t}\n\t\tif ( clearQueue && type !== false ) {\n\t\t\tthis.queue( type || \"fx\", [] );\n\t\t}\n\n\t\treturn this.each(function() {\n\t\t\tvar dequeue = true,\n\t\t\t\tindex = type != null && type + \"queueHooks\",\n\t\t\t\ttimers = jQuery.timers,\n\t\t\t\tdata = jQuery._data( this );\n\n\t\t\tif ( index ) {\n\t\t\t\tif ( data[ index ] && data[ index ].stop ) {\n\t\t\t\t\tstopQueue( data[ index ] );\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tfor ( index in data ) {\n\t\t\t\t\tif ( data[ index ] && data[ index ].stop && rrun.test( index ) ) {\n\t\t\t\t\t\tstopQueue( data[ index ] );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tfor ( index = timers.length; index--; ) {\n\t\t\t\tif ( timers[ index ].elem === this && (type == null || timers[ index ].queue === type) ) {\n\t\t\t\t\ttimers[ index ].anim.stop( gotoEnd );\n\t\t\t\t\tdequeue = false;\n\t\t\t\t\ttimers.splice( index, 1 );\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// start the next in the queue if the last step wasn't forced\n\t\t\t// timers currently will call their complete callbacks, which will dequeue\n\t\t\t// but only if they were gotoEnd\n\t\t\tif ( dequeue || !gotoEnd ) {\n\t\t\t\tjQuery.dequeue( this, type );\n\t\t\t}\n\t\t});\n\t},\n\tfinish: function( type ) {\n\t\tif ( type !== false ) {\n\t\t\ttype = type || \"fx\";\n\t\t}\n\t\treturn this.each(function() {\n\t\t\tvar index,\n\t\t\t\tdata = jQuery._data( this ),\n\t\t\t\tqueue = data[ type + \"queue\" ],\n\t\t\t\thooks = data[ type + \"queueHooks\" ],\n\t\t\t\ttimers = jQuery.timers,\n\t\t\t\tlength = queue ? queue.length : 0;\n\n\t\t\t// enable finishing flag on private data\n\t\t\tdata.finish = true;\n\n\t\t\t// empty the queue first\n\t\t\tjQuery.queue( this, type, [] );\n\n\t\t\tif ( hooks && hooks.stop ) {\n\t\t\t\thooks.stop.call( this, true );\n\t\t\t}\n\n\t\t\t// look for any active animations, and finish them\n\t\t\tfor ( index = timers.length; index--; ) {\n\t\t\t\tif ( timers[ index ].elem === this && timers[ index ].queue === type ) {\n\t\t\t\t\ttimers[ index ].anim.stop( true );\n\t\t\t\t\ttimers.splice( index, 1 );\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// look for any animations in the old queue and finish them\n\t\t\tfor ( index = 0; index < length; index++ ) {\n\t\t\t\tif ( queue[ index ] && queue[ index ].finish ) {\n\t\t\t\t\tqueue[ index ].finish.call( this );\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// turn off finishing flag\n\t\t\tdelete data.finish;\n\t\t});\n\t}\n});\n\njQuery.each([ \"toggle\", \"show\", \"hide\" ], function( i, name ) {\n\tvar cssFn = jQuery.fn[ name ];\n\tjQuery.fn[ name ] = function( speed, easing, callback ) {\n\t\treturn speed == null || typeof speed === \"boolean\" ?\n\t\t\tcssFn.apply( this, arguments ) :\n\t\t\tthis.animate( genFx( name, true ), speed, easing, callback );\n\t};\n});\n\n// Generate shortcuts for custom animations\njQuery.each({\n\tslideDown: genFx(\"show\"),\n\tslideUp: genFx(\"hide\"),\n\tslideToggle: genFx(\"toggle\"),\n\tfadeIn: { opacity: \"show\" },\n\tfadeOut: { opacity: \"hide\" },\n\tfadeToggle: { opacity: \"toggle\" }\n}, function( name, props ) {\n\tjQuery.fn[ name ] = function( speed, easing, callback ) {\n\t\treturn this.animate( props, speed, easing, callback );\n\t};\n});\n\njQuery.timers = [];\njQuery.fx.tick = function() {\n\tvar timer,\n\t\ttimers = jQuery.timers,\n\t\ti = 0;\n\n\tfxNow = jQuery.now();\n\n\tfor ( ; i < timers.length; i++ ) {\n\t\ttimer = timers[ i ];\n\t\t// Checks the timer has not already been removed\n\t\tif ( !timer() && timers[ i ] === timer ) {\n\t\t\ttimers.splice( i--, 1 );\n\t\t}\n\t}\n\n\tif ( !timers.length ) {\n\t\tjQuery.fx.stop();\n\t}\n\tfxNow = undefined;\n};\n\njQuery.fx.timer = function( timer ) {\n\tjQuery.timers.push( timer );\n\tif ( timer() ) {\n\t\tjQuery.fx.start();\n\t} else {\n\t\tjQuery.timers.pop();\n\t}\n};\n\njQuery.fx.interval = 13;\n\njQuery.fx.start = function() {\n\tif ( !timerId ) {\n\t\ttimerId = setInterval( jQuery.fx.tick, jQuery.fx.interval );\n\t}\n};\n\njQuery.fx.stop = function() {\n\tclearInterval( timerId );\n\ttimerId = null;\n};\n\njQuery.fx.speeds = {\n\tslow: 600,\n\tfast: 200,\n\t// Default speed\n\t_default: 400\n};\n\n\n// Based off of the plugin by Clint Helfers, with permission.\n// http://blindsignals.com/index.php/2009/07/jquery-delay/\njQuery.fn.delay = function( time, type ) {\n\ttime = jQuery.fx ? jQuery.fx.speeds[ time ] || time : time;\n\ttype = type || \"fx\";\n\n\treturn this.queue( type, function( next, hooks ) {\n\t\tvar timeout = setTimeout( next, time );\n\t\thooks.stop = function() {\n\t\t\tclearTimeout( timeout );\n\t\t};\n\t});\n};\n\n\n(function() {\n\t// Minified: var a,b,c,d,e\n\tvar input, div, select, a, opt;\n\n\t// Setup\n\tdiv = document.createElement( \"div\" );\n\tdiv.setAttribute( \"className\", \"t\" );\n\tdiv.innerHTML = \"  <link/><table></table><a href='/a'>a</a><input type='checkbox'/>\";\n\ta = div.getElementsByTagName(\"a\")[ 0 ];\n\n\t// First batch of tests.\n\tselect = document.createElement(\"select\");\n\topt = select.appendChild( document.createElement(\"option\") );\n\tinput = div.getElementsByTagName(\"input\")[ 0 ];\n\n\ta.style.cssText = \"top:1px\";\n\n\t// Test setAttribute on camelCase class. If it works, we need attrFixes when doing get/setAttribute (ie6/7)\n\tsupport.getSetAttribute = div.className !== \"t\";\n\n\t// Get the style information from getAttribute\n\t// (IE uses .cssText instead)\n\tsupport.style = /top/.test( a.getAttribute(\"style\") );\n\n\t// Make sure that URLs aren't manipulated\n\t// (IE normalizes it by default)\n\tsupport.hrefNormalized = a.getAttribute(\"href\") === \"/a\";\n\n\t// Check the default checkbox/radio value (\"\" on WebKit; \"on\" elsewhere)\n\tsupport.checkOn = !!input.value;\n\n\t// Make sure that a selected-by-default option has a working selected property.\n\t// (WebKit defaults to false instead of true, IE too, if it's in an optgroup)\n\tsupport.optSelected = opt.selected;\n\n\t// Tests for enctype support on a form (#6743)\n\tsupport.enctype = !!document.createElement(\"form\").enctype;\n\n\t// Make sure that the options inside disabled selects aren't marked as disabled\n\t// (WebKit marks them as disabled)\n\tselect.disabled = true;\n\tsupport.optDisabled = !opt.disabled;\n\n\t// Support: IE8 only\n\t// Check if we can trust getAttribute(\"value\")\n\tinput = document.createElement( \"input\" );\n\tinput.setAttribute( \"value\", \"\" );\n\tsupport.input = input.getAttribute( \"value\" ) === \"\";\n\n\t// Check if an input maintains its value after becoming a radio\n\tinput.value = \"t\";\n\tinput.setAttribute( \"type\", \"radio\" );\n\tsupport.radioValue = input.value === \"t\";\n})();\n\n\nvar rreturn = /\\r/g;\n\njQuery.fn.extend({\n\tval: function( value ) {\n\t\tvar hooks, ret, isFunction,\n\t\t\telem = this[0];\n\n\t\tif ( !arguments.length ) {\n\t\t\tif ( elem ) {\n\t\t\t\thooks = jQuery.valHooks[ elem.type ] || jQuery.valHooks[ elem.nodeName.toLowerCase() ];\n\n\t\t\t\tif ( hooks && \"get\" in hooks && (ret = hooks.get( elem, \"value\" )) !== undefined ) {\n\t\t\t\t\treturn ret;\n\t\t\t\t}\n\n\t\t\t\tret = elem.value;\n\n\t\t\t\treturn typeof ret === \"string\" ?\n\t\t\t\t\t// handle most common string cases\n\t\t\t\t\tret.replace(rreturn, \"\") :\n\t\t\t\t\t// handle cases where value is null/undef or number\n\t\t\t\t\tret == null ? \"\" : ret;\n\t\t\t}\n\n\t\t\treturn;\n\t\t}\n\n\t\tisFunction = jQuery.isFunction( value );\n\n\t\treturn this.each(function( i ) {\n\t\t\tvar val;\n\n\t\t\tif ( this.nodeType !== 1 ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif ( isFunction ) {\n\t\t\t\tval = value.call( this, i, jQuery( this ).val() );\n\t\t\t} else {\n\t\t\t\tval = value;\n\t\t\t}\n\n\t\t\t// Treat null/undefined as \"\"; convert numbers to string\n\t\t\tif ( val == null ) {\n\t\t\t\tval = \"\";\n\t\t\t} else if ( typeof val === \"number\" ) {\n\t\t\t\tval += \"\";\n\t\t\t} else if ( jQuery.isArray( val ) ) {\n\t\t\t\tval = jQuery.map( val, function( value ) {\n\t\t\t\t\treturn value == null ? \"\" : value + \"\";\n\t\t\t\t});\n\t\t\t}\n\n\t\t\thooks = jQuery.valHooks[ this.type ] || jQuery.valHooks[ this.nodeName.toLowerCase() ];\n\n\t\t\t// If set returns undefined, fall back to normal setting\n\t\t\tif ( !hooks || !(\"set\" in hooks) || hooks.set( this, val, \"value\" ) === undefined ) {\n\t\t\t\tthis.value = val;\n\t\t\t}\n\t\t});\n\t}\n});\n\njQuery.extend({\n\tvalHooks: {\n\t\toption: {\n\t\t\tget: function( elem ) {\n\t\t\t\tvar val = jQuery.find.attr( elem, \"value\" );\n\t\t\t\treturn val != null ?\n\t\t\t\t\tval :\n\t\t\t\t\t// Support: IE10-11+\n\t\t\t\t\t// option.text throws exceptions (#14686, #14858)\n\t\t\t\t\tjQuery.trim( jQuery.text( elem ) );\n\t\t\t}\n\t\t},\n\t\tselect: {\n\t\t\tget: function( elem ) {\n\t\t\t\tvar value, option,\n\t\t\t\t\toptions = elem.options,\n\t\t\t\t\tindex = elem.selectedIndex,\n\t\t\t\t\tone = elem.type === \"select-one\" || index < 0,\n\t\t\t\t\tvalues = one ? null : [],\n\t\t\t\t\tmax = one ? index + 1 : options.length,\n\t\t\t\t\ti = index < 0 ?\n\t\t\t\t\t\tmax :\n\t\t\t\t\t\tone ? index : 0;\n\n\t\t\t\t// Loop through all the selected options\n\t\t\t\tfor ( ; i < max; i++ ) {\n\t\t\t\t\toption = options[ i ];\n\n\t\t\t\t\t// oldIE doesn't update selected after form reset (#2551)\n\t\t\t\t\tif ( ( option.selected || i === index ) &&\n\t\t\t\t\t\t\t// Don't return options that are disabled or in a disabled optgroup\n\t\t\t\t\t\t\t( support.optDisabled ? !option.disabled : option.getAttribute(\"disabled\") === null ) &&\n\t\t\t\t\t\t\t( !option.parentNode.disabled || !jQuery.nodeName( option.parentNode, \"optgroup\" ) ) ) {\n\n\t\t\t\t\t\t// Get the specific value for the option\n\t\t\t\t\t\tvalue = jQuery( option ).val();\n\n\t\t\t\t\t\t// We don't need an array for one selects\n\t\t\t\t\t\tif ( one ) {\n\t\t\t\t\t\t\treturn value;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// Multi-Selects return an array\n\t\t\t\t\t\tvalues.push( value );\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\treturn values;\n\t\t\t},\n\n\t\t\tset: function( elem, value ) {\n\t\t\t\tvar optionSet, option,\n\t\t\t\t\toptions = elem.options,\n\t\t\t\t\tvalues = jQuery.makeArray( value ),\n\t\t\t\t\ti = options.length;\n\n\t\t\t\twhile ( i-- ) {\n\t\t\t\t\toption = options[ i ];\n\n\t\t\t\t\tif ( jQuery.inArray( jQuery.valHooks.option.get( option ), values ) >= 0 ) {\n\n\t\t\t\t\t\t// Support: IE6\n\t\t\t\t\t\t// When new option element is added to select box we need to\n\t\t\t\t\t\t// force reflow of newly added node in order to workaround delay\n\t\t\t\t\t\t// of initialization properties\n\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\toption.selected = optionSet = true;\n\n\t\t\t\t\t\t} catch ( _ ) {\n\n\t\t\t\t\t\t\t// Will be executed only in IE6\n\t\t\t\t\t\t\toption.scrollHeight;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t} else {\n\t\t\t\t\t\toption.selected = false;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// Force browsers to behave consistently when non-matching value is set\n\t\t\t\tif ( !optionSet ) {\n\t\t\t\t\telem.selectedIndex = -1;\n\t\t\t\t}\n\n\t\t\t\treturn options;\n\t\t\t}\n\t\t}\n\t}\n});\n\n// Radios and checkboxes getter/setter\njQuery.each([ \"radio\", \"checkbox\" ], function() {\n\tjQuery.valHooks[ this ] = {\n\t\tset: function( elem, value ) {\n\t\t\tif ( jQuery.isArray( value ) ) {\n\t\t\t\treturn ( elem.checked = jQuery.inArray( jQuery(elem).val(), value ) >= 0 );\n\t\t\t}\n\t\t}\n\t};\n\tif ( !support.checkOn ) {\n\t\tjQuery.valHooks[ this ].get = function( elem ) {\n\t\t\t// Support: Webkit\n\t\t\t// \"\" is returned instead of \"on\" if a value isn't specified\n\t\t\treturn elem.getAttribute(\"value\") === null ? \"on\" : elem.value;\n\t\t};\n\t}\n});\n\n\n\n\nvar nodeHook, boolHook,\n\tattrHandle = jQuery.expr.attrHandle,\n\truseDefault = /^(?:checked|selected)$/i,\n\tgetSetAttribute = support.getSetAttribute,\n\tgetSetInput = support.input;\n\njQuery.fn.extend({\n\tattr: function( name, value ) {\n\t\treturn access( this, jQuery.attr, name, value, arguments.length > 1 );\n\t},\n\n\tremoveAttr: function( name ) {\n\t\treturn this.each(function() {\n\t\t\tjQuery.removeAttr( this, name );\n\t\t});\n\t}\n});\n\njQuery.extend({\n\tattr: function( elem, name, value ) {\n\t\tvar hooks, ret,\n\t\t\tnType = elem.nodeType;\n\n\t\t// don't get/set attributes on text, comment and attribute nodes\n\t\tif ( !elem || nType === 3 || nType === 8 || nType === 2 ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Fallback to prop when attributes are not supported\n\t\tif ( typeof elem.getAttribute === strundefined ) {\n\t\t\treturn jQuery.prop( elem, name, value );\n\t\t}\n\n\t\t// All attributes are lowercase\n\t\t// Grab necessary hook if one is defined\n\t\tif ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) {\n\t\t\tname = name.toLowerCase();\n\t\t\thooks = jQuery.attrHooks[ name ] ||\n\t\t\t\t( jQuery.expr.match.bool.test( name ) ? boolHook : nodeHook );\n\t\t}\n\n\t\tif ( value !== undefined ) {\n\n\t\t\tif ( value === null ) {\n\t\t\t\tjQuery.removeAttr( elem, name );\n\n\t\t\t} else if ( hooks && \"set\" in hooks && (ret = hooks.set( elem, value, name )) !== undefined ) {\n\t\t\t\treturn ret;\n\n\t\t\t} else {\n\t\t\t\telem.setAttribute( name, value + \"\" );\n\t\t\t\treturn value;\n\t\t\t}\n\n\t\t} else if ( hooks && \"get\" in hooks && (ret = hooks.get( elem, name )) !== null ) {\n\t\t\treturn ret;\n\n\t\t} else {\n\t\t\tret = jQuery.find.attr( elem, name );\n\n\t\t\t// Non-existent attributes return null, we normalize to undefined\n\t\t\treturn ret == null ?\n\t\t\t\tundefined :\n\t\t\t\tret;\n\t\t}\n\t},\n\n\tremoveAttr: function( elem, value ) {\n\t\tvar name, propName,\n\t\t\ti = 0,\n\t\t\tattrNames = value && value.match( rnotwhite );\n\n\t\tif ( attrNames && elem.nodeType === 1 ) {\n\t\t\twhile ( (name = attrNames[i++]) ) {\n\t\t\t\tpropName = jQuery.propFix[ name ] || name;\n\n\t\t\t\t// Boolean attributes get special treatment (#10870)\n\t\t\t\tif ( jQuery.expr.match.bool.test( name ) ) {\n\t\t\t\t\t// Set corresponding property to false\n\t\t\t\t\tif ( getSetInput && getSetAttribute || !ruseDefault.test( name ) ) {\n\t\t\t\t\t\telem[ propName ] = false;\n\t\t\t\t\t// Support: IE<9\n\t\t\t\t\t// Also clear defaultChecked/defaultSelected (if appropriate)\n\t\t\t\t\t} else {\n\t\t\t\t\t\telem[ jQuery.camelCase( \"default-\" + name ) ] =\n\t\t\t\t\t\t\telem[ propName ] = false;\n\t\t\t\t\t}\n\n\t\t\t\t// See #9699 for explanation of this approach (setting first, then removal)\n\t\t\t\t} else {\n\t\t\t\t\tjQuery.attr( elem, name, \"\" );\n\t\t\t\t}\n\n\t\t\t\telem.removeAttribute( getSetAttribute ? name : propName );\n\t\t\t}\n\t\t}\n\t},\n\n\tattrHooks: {\n\t\ttype: {\n\t\t\tset: function( elem, value ) {\n\t\t\t\tif ( !support.radioValue && value === \"radio\" && jQuery.nodeName(elem, \"input\") ) {\n\t\t\t\t\t// Setting the type on a radio button after the value resets the value in IE6-9\n\t\t\t\t\t// Reset value to default in case type is set after value during creation\n\t\t\t\t\tvar val = elem.value;\n\t\t\t\t\telem.setAttribute( \"type\", value );\n\t\t\t\t\tif ( val ) {\n\t\t\t\t\t\telem.value = val;\n\t\t\t\t\t}\n\t\t\t\t\treturn value;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n});\n\n// Hook for boolean attributes\nboolHook = {\n\tset: function( elem, value, name ) {\n\t\tif ( value === false ) {\n\t\t\t// Remove boolean attributes when set to false\n\t\t\tjQuery.removeAttr( elem, name );\n\t\t} else if ( getSetInput && getSetAttribute || !ruseDefault.test( name ) ) {\n\t\t\t// IE<8 needs the *property* name\n\t\t\telem.setAttribute( !getSetAttribute && jQuery.propFix[ name ] || name, name );\n\n\t\t// Use defaultChecked and defaultSelected for oldIE\n\t\t} else {\n\t\t\telem[ jQuery.camelCase( \"default-\" + name ) ] = elem[ name ] = true;\n\t\t}\n\n\t\treturn name;\n\t}\n};\n\n// Retrieve booleans specially\njQuery.each( jQuery.expr.match.bool.source.match( /\\w+/g ), function( i, name ) {\n\n\tvar getter = attrHandle[ name ] || jQuery.find.attr;\n\n\tattrHandle[ name ] = getSetInput && getSetAttribute || !ruseDefault.test( name ) ?\n\t\tfunction( elem, name, isXML ) {\n\t\t\tvar ret, handle;\n\t\t\tif ( !isXML ) {\n\t\t\t\t// Avoid an infinite loop by temporarily removing this function from the getter\n\t\t\t\thandle = attrHandle[ name ];\n\t\t\t\tattrHandle[ name ] = ret;\n\t\t\t\tret = getter( elem, name, isXML ) != null ?\n\t\t\t\t\tname.toLowerCase() :\n\t\t\t\t\tnull;\n\t\t\t\tattrHandle[ name ] = handle;\n\t\t\t}\n\t\t\treturn ret;\n\t\t} :\n\t\tfunction( elem, name, isXML ) {\n\t\t\tif ( !isXML ) {\n\t\t\t\treturn elem[ jQuery.camelCase( \"default-\" + name ) ] ?\n\t\t\t\t\tname.toLowerCase() :\n\t\t\t\t\tnull;\n\t\t\t}\n\t\t};\n});\n\n// fix oldIE attroperties\nif ( !getSetInput || !getSetAttribute ) {\n\tjQuery.attrHooks.value = {\n\t\tset: function( elem, value, name ) {\n\t\t\tif ( jQuery.nodeName( elem, \"input\" ) ) {\n\t\t\t\t// Does not return so that setAttribute is also used\n\t\t\t\telem.defaultValue = value;\n\t\t\t} else {\n\t\t\t\t// Use nodeHook if defined (#1954); otherwise setAttribute is fine\n\t\t\t\treturn nodeHook && nodeHook.set( elem, value, name );\n\t\t\t}\n\t\t}\n\t};\n}\n\n// IE6/7 do not support getting/setting some attributes with get/setAttribute\nif ( !getSetAttribute ) {\n\n\t// Use this for any attribute in IE6/7\n\t// This fixes almost every IE6/7 issue\n\tnodeHook = {\n\t\tset: function( elem, value, name ) {\n\t\t\t// Set the existing or create a new attribute node\n\t\t\tvar ret = elem.getAttributeNode( name );\n\t\t\tif ( !ret ) {\n\t\t\t\telem.setAttributeNode(\n\t\t\t\t\t(ret = elem.ownerDocument.createAttribute( name ))\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tret.value = value += \"\";\n\n\t\t\t// Break association with cloned elements by also using setAttribute (#9646)\n\t\t\tif ( name === \"value\" || value === elem.getAttribute( name ) ) {\n\t\t\t\treturn value;\n\t\t\t}\n\t\t}\n\t};\n\n\t// Some attributes are constructed with empty-string values when not defined\n\tattrHandle.id = attrHandle.name = attrHandle.coords =\n\t\tfunction( elem, name, isXML ) {\n\t\t\tvar ret;\n\t\t\tif ( !isXML ) {\n\t\t\t\treturn (ret = elem.getAttributeNode( name )) && ret.value !== \"\" ?\n\t\t\t\t\tret.value :\n\t\t\t\t\tnull;\n\t\t\t}\n\t\t};\n\n\t// Fixing value retrieval on a button requires this module\n\tjQuery.valHooks.button = {\n\t\tget: function( elem, name ) {\n\t\t\tvar ret = elem.getAttributeNode( name );\n\t\t\tif ( ret && ret.specified ) {\n\t\t\t\treturn ret.value;\n\t\t\t}\n\t\t},\n\t\tset: nodeHook.set\n\t};\n\n\t// Set contenteditable to false on removals(#10429)\n\t// Setting to empty string throws an error as an invalid value\n\tjQuery.attrHooks.contenteditable = {\n\t\tset: function( elem, value, name ) {\n\t\t\tnodeHook.set( elem, value === \"\" ? false : value, name );\n\t\t}\n\t};\n\n\t// Set width and height to auto instead of 0 on empty string( Bug #8150 )\n\t// This is for removals\n\tjQuery.each([ \"width\", \"height\" ], function( i, name ) {\n\t\tjQuery.attrHooks[ name ] = {\n\t\t\tset: function( elem, value ) {\n\t\t\t\tif ( value === \"\" ) {\n\t\t\t\t\telem.setAttribute( name, \"auto\" );\n\t\t\t\t\treturn value;\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\t});\n}\n\nif ( !support.style ) {\n\tjQuery.attrHooks.style = {\n\t\tget: function( elem ) {\n\t\t\t// Return undefined in the case of empty string\n\t\t\t// Note: IE uppercases css property names, but if we were to .toLowerCase()\n\t\t\t// .cssText, that would destroy case senstitivity in URL's, like in \"background\"\n\t\t\treturn elem.style.cssText || undefined;\n\t\t},\n\t\tset: function( elem, value ) {\n\t\t\treturn ( elem.style.cssText = value + \"\" );\n\t\t}\n\t};\n}\n\n\n\n\nvar rfocusable = /^(?:input|select|textarea|button|object)$/i,\n\trclickable = /^(?:a|area)$/i;\n\njQuery.fn.extend({\n\tprop: function( name, value ) {\n\t\treturn access( this, jQuery.prop, name, value, arguments.length > 1 );\n\t},\n\n\tremoveProp: function( name ) {\n\t\tname = jQuery.propFix[ name ] || name;\n\t\treturn this.each(function() {\n\t\t\t// try/catch handles cases where IE balks (such as removing a property on window)\n\t\t\ttry {\n\t\t\t\tthis[ name ] = undefined;\n\t\t\t\tdelete this[ name ];\n\t\t\t} catch( e ) {}\n\t\t});\n\t}\n});\n\njQuery.extend({\n\tpropFix: {\n\t\t\"for\": \"htmlFor\",\n\t\t\"class\": \"className\"\n\t},\n\n\tprop: function( elem, name, value ) {\n\t\tvar ret, hooks, notxml,\n\t\t\tnType = elem.nodeType;\n\n\t\t// don't get/set properties on text, comment and attribute nodes\n\t\tif ( !elem || nType === 3 || nType === 8 || nType === 2 ) {\n\t\t\treturn;\n\t\t}\n\n\t\tnotxml = nType !== 1 || !jQuery.isXMLDoc( elem );\n\n\t\tif ( notxml ) {\n\t\t\t// Fix name and attach hooks\n\t\t\tname = jQuery.propFix[ name ] || name;\n\t\t\thooks = jQuery.propHooks[ name ];\n\t\t}\n\n\t\tif ( value !== undefined ) {\n\t\t\treturn hooks && \"set\" in hooks && (ret = hooks.set( elem, value, name )) !== undefined ?\n\t\t\t\tret :\n\t\t\t\t( elem[ name ] = value );\n\n\t\t} else {\n\t\t\treturn hooks && \"get\" in hooks && (ret = hooks.get( elem, name )) !== null ?\n\t\t\t\tret :\n\t\t\t\telem[ name ];\n\t\t}\n\t},\n\n\tpropHooks: {\n\t\ttabIndex: {\n\t\t\tget: function( elem ) {\n\t\t\t\t// elem.tabIndex doesn't always return the correct value when it hasn't been explicitly set\n\t\t\t\t// http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/\n\t\t\t\t// Use proper attribute retrieval(#12072)\n\t\t\t\tvar tabindex = jQuery.find.attr( elem, \"tabindex\" );\n\n\t\t\t\treturn tabindex ?\n\t\t\t\t\tparseInt( tabindex, 10 ) :\n\t\t\t\t\trfocusable.test( elem.nodeName ) || rclickable.test( elem.nodeName ) && elem.href ?\n\t\t\t\t\t\t0 :\n\t\t\t\t\t\t-1;\n\t\t\t}\n\t\t}\n\t}\n});\n\n// Some attributes require a special call on IE\n// http://msdn.microsoft.com/en-us/library/ms536429%28VS.85%29.aspx\nif ( !support.hrefNormalized ) {\n\t// href/src property should get the full normalized URL (#10299/#12915)\n\tjQuery.each([ \"href\", \"src\" ], function( i, name ) {\n\t\tjQuery.propHooks[ name ] = {\n\t\t\tget: function( elem ) {\n\t\t\t\treturn elem.getAttribute( name, 4 );\n\t\t\t}\n\t\t};\n\t});\n}\n\n// Support: Safari, IE9+\n// mis-reports the default selected property of an option\n// Accessing the parent's selectedIndex property fixes it\nif ( !support.optSelected ) {\n\tjQuery.propHooks.selected = {\n\t\tget: function( elem ) {\n\t\t\tvar parent = elem.parentNode;\n\n\t\t\tif ( parent ) {\n\t\t\t\tparent.selectedIndex;\n\n\t\t\t\t// Make sure that it also works with optgroups, see #5701\n\t\t\t\tif ( parent.parentNode ) {\n\t\t\t\t\tparent.parentNode.selectedIndex;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn null;\n\t\t}\n\t};\n}\n\njQuery.each([\n\t\"tabIndex\",\n\t\"readOnly\",\n\t\"maxLength\",\n\t\"cellSpacing\",\n\t\"cellPadding\",\n\t\"rowSpan\",\n\t\"colSpan\",\n\t\"useMap\",\n\t\"frameBorder\",\n\t\"contentEditable\"\n], function() {\n\tjQuery.propFix[ this.toLowerCase() ] = this;\n});\n\n// IE6/7 call enctype encoding\nif ( !support.enctype ) {\n\tjQuery.propFix.enctype = \"encoding\";\n}\n\n\n\n\nvar rclass = /[\\t\\r\\n\\f]/g;\n\njQuery.fn.extend({\n\taddClass: function( value ) {\n\t\tvar classes, elem, cur, clazz, j, finalValue,\n\t\t\ti = 0,\n\t\t\tlen = this.length,\n\t\t\tproceed = typeof value === \"string\" && value;\n\n\t\tif ( jQuery.isFunction( value ) ) {\n\t\t\treturn this.each(function( j ) {\n\t\t\t\tjQuery( this ).addClass( value.call( this, j, this.className ) );\n\t\t\t});\n\t\t}\n\n\t\tif ( proceed ) {\n\t\t\t// The disjunction here is for better compressibility (see removeClass)\n\t\t\tclasses = ( value || \"\" ).match( rnotwhite ) || [];\n\n\t\t\tfor ( ; i < len; i++ ) {\n\t\t\t\telem = this[ i ];\n\t\t\t\tcur = elem.nodeType === 1 && ( elem.className ?\n\t\t\t\t\t( \" \" + elem.className + \" \" ).replace( rclass, \" \" ) :\n\t\t\t\t\t\" \"\n\t\t\t\t);\n\n\t\t\t\tif ( cur ) {\n\t\t\t\t\tj = 0;\n\t\t\t\t\twhile ( (clazz = classes[j++]) ) {\n\t\t\t\t\t\tif ( cur.indexOf( \" \" + clazz + \" \" ) < 0 ) {\n\t\t\t\t\t\t\tcur += clazz + \" \";\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\t// only assign if different to avoid unneeded rendering.\n\t\t\t\t\tfinalValue = jQuery.trim( cur );\n\t\t\t\t\tif ( elem.className !== finalValue ) {\n\t\t\t\t\t\telem.className = finalValue;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn this;\n\t},\n\n\tremoveClass: function( value ) {\n\t\tvar classes, elem, cur, clazz, j, finalValue,\n\t\t\ti = 0,\n\t\t\tlen = this.length,\n\t\t\tproceed = arguments.length === 0 || typeof value === \"string\" && value;\n\n\t\tif ( jQuery.isFunction( value ) ) {\n\t\t\treturn this.each(function( j ) {\n\t\t\t\tjQuery( this ).removeClass( value.call( this, j, this.className ) );\n\t\t\t});\n\t\t}\n\t\tif ( proceed ) {\n\t\t\tclasses = ( value || \"\" ).match( rnotwhite ) || [];\n\n\t\t\tfor ( ; i < len; i++ ) {\n\t\t\t\telem = this[ i ];\n\t\t\t\t// This expression is here for better compressibility (see addClass)\n\t\t\t\tcur = elem.nodeType === 1 && ( elem.className ?\n\t\t\t\t\t( \" \" + elem.className + \" \" ).replace( rclass, \" \" ) :\n\t\t\t\t\t\"\"\n\t\t\t\t);\n\n\t\t\t\tif ( cur ) {\n\t\t\t\t\tj = 0;\n\t\t\t\t\twhile ( (clazz = classes[j++]) ) {\n\t\t\t\t\t\t// Remove *all* instances\n\t\t\t\t\t\twhile ( cur.indexOf( \" \" + clazz + \" \" ) >= 0 ) {\n\t\t\t\t\t\t\tcur = cur.replace( \" \" + clazz + \" \", \" \" );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\t// only assign if different to avoid unneeded rendering.\n\t\t\t\t\tfinalValue = value ? jQuery.trim( cur ) : \"\";\n\t\t\t\t\tif ( elem.className !== finalValue ) {\n\t\t\t\t\t\telem.className = finalValue;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn this;\n\t},\n\n\ttoggleClass: function( value, stateVal ) {\n\t\tvar type = typeof value;\n\n\t\tif ( typeof stateVal === \"boolean\" && type === \"string\" ) {\n\t\t\treturn stateVal ? this.addClass( value ) : this.removeClass( value );\n\t\t}\n\n\t\tif ( jQuery.isFunction( value ) ) {\n\t\t\treturn this.each(function( i ) {\n\t\t\t\tjQuery( this ).toggleClass( value.call(this, i, this.className, stateVal), stateVal );\n\t\t\t});\n\t\t}\n\n\t\treturn this.each(function() {\n\t\t\tif ( type === \"string\" ) {\n\t\t\t\t// toggle individual class names\n\t\t\t\tvar className,\n\t\t\t\t\ti = 0,\n\t\t\t\t\tself = jQuery( this ),\n\t\t\t\t\tclassNames = value.match( rnotwhite ) || [];\n\n\t\t\t\twhile ( (className = classNames[ i++ ]) ) {\n\t\t\t\t\t// check each className given, space separated list\n\t\t\t\t\tif ( self.hasClass( className ) ) {\n\t\t\t\t\t\tself.removeClass( className );\n\t\t\t\t\t} else {\n\t\t\t\t\t\tself.addClass( className );\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t// Toggle whole class name\n\t\t\t} else if ( type === strundefined || type === \"boolean\" ) {\n\t\t\t\tif ( this.className ) {\n\t\t\t\t\t// store className if set\n\t\t\t\t\tjQuery._data( this, \"__className__\", this.className );\n\t\t\t\t}\n\n\t\t\t\t// If the element has a class name or if we're passed \"false\",\n\t\t\t\t// then remove the whole classname (if there was one, the above saved it).\n\t\t\t\t// Otherwise bring back whatever was previously saved (if anything),\n\t\t\t\t// falling back to the empty string if nothing was stored.\n\t\t\t\tthis.className = this.className || value === false ? \"\" : jQuery._data( this, \"__className__\" ) || \"\";\n\t\t\t}\n\t\t});\n\t},\n\n\thasClass: function( selector ) {\n\t\tvar className = \" \" + selector + \" \",\n\t\t\ti = 0,\n\t\t\tl = this.length;\n\t\tfor ( ; i < l; i++ ) {\n\t\t\tif ( this[i].nodeType === 1 && (\" \" + this[i].className + \" \").replace(rclass, \" \").indexOf( className ) >= 0 ) {\n\t\t\t\treturn true;\n\t\t\t}\n\t\t}\n\n\t\treturn false;\n\t}\n});\n\n\n\n\n// Return jQuery for attributes-only inclusion\n\n\njQuery.each( (\"blur focus focusin focusout load resize scroll unload click dblclick \" +\n\t\"mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave \" +\n\t\"change select submit keydown keypress keyup error contextmenu\").split(\" \"), function( i, name ) {\n\n\t// Handle event binding\n\tjQuery.fn[ name ] = function( data, fn ) {\n\t\treturn arguments.length > 0 ?\n\t\t\tthis.on( name, null, data, fn ) :\n\t\t\tthis.trigger( name );\n\t};\n});\n\njQuery.fn.extend({\n\thover: function( fnOver, fnOut ) {\n\t\treturn this.mouseenter( fnOver ).mouseleave( fnOut || fnOver );\n\t},\n\n\tbind: function( types, data, fn ) {\n\t\treturn this.on( types, null, data, fn );\n\t},\n\tunbind: function( types, fn ) {\n\t\treturn this.off( types, null, fn );\n\t},\n\n\tdelegate: function( selector, types, data, fn ) {\n\t\treturn this.on( types, selector, data, fn );\n\t},\n\tundelegate: function( selector, types, fn ) {\n\t\t// ( namespace ) or ( selector, types [, fn] )\n\t\treturn arguments.length === 1 ? this.off( selector, \"**\" ) : this.off( types, selector || \"**\", fn );\n\t}\n});\n\n\nvar nonce = jQuery.now();\n\nvar rquery = (/\\?/);\n\n\n\nvar rvalidtokens = /(,)|(\\[|{)|(}|])|\"(?:[^\"\\\\\\r\\n]|\\\\[\"\\\\\\/bfnrt]|\\\\u[\\da-fA-F]{4})*\"\\s*:?|true|false|null|-?(?!0\\d)\\d+(?:\\.\\d+|)(?:[eE][+-]?\\d+|)/g;\n\njQuery.parseJSON = function( data ) {\n\t// Attempt to parse using the native JSON parser first\n\tif ( window.JSON && window.JSON.parse ) {\n\t\t// Support: Android 2.3\n\t\t// Workaround failure to string-cast null input\n\t\treturn window.JSON.parse( data + \"\" );\n\t}\n\n\tvar requireNonComma,\n\t\tdepth = null,\n\t\tstr = jQuery.trim( data + \"\" );\n\n\t// Guard against invalid (and possibly dangerous) input by ensuring that nothing remains\n\t// after removing valid tokens\n\treturn str && !jQuery.trim( str.replace( rvalidtokens, function( token, comma, open, close ) {\n\n\t\t// Force termination if we see a misplaced comma\n\t\tif ( requireNonComma && comma ) {\n\t\t\tdepth = 0;\n\t\t}\n\n\t\t// Perform no more replacements after returning to outermost depth\n\t\tif ( depth === 0 ) {\n\t\t\treturn token;\n\t\t}\n\n\t\t// Commas must not follow \"[\", \"{\", or \",\"\n\t\trequireNonComma = open || comma;\n\n\t\t// Determine new depth\n\t\t// array/object open (\"[\" or \"{\"): depth += true - false (increment)\n\t\t// array/object close (\"]\" or \"}\"): depth += false - true (decrement)\n\t\t// other cases (\",\" or primitive): depth += true - true (numeric cast)\n\t\tdepth += !close - !open;\n\n\t\t// Remove this token\n\t\treturn \"\";\n\t}) ) ?\n\t\t( Function( \"return \" + str ) )() :\n\t\tjQuery.error( \"Invalid JSON: \" + data );\n};\n\n\n// Cross-browser xml parsing\njQuery.parseXML = function( data ) {\n\tvar xml, tmp;\n\tif ( !data || typeof data !== \"string\" ) {\n\t\treturn null;\n\t}\n\ttry {\n\t\tif ( window.DOMParser ) { // Standard\n\t\t\ttmp = new DOMParser();\n\t\t\txml = tmp.parseFromString( data, \"text/xml\" );\n\t\t} else { // IE\n\t\t\txml = new ActiveXObject( \"Microsoft.XMLDOM\" );\n\t\t\txml.async = \"false\";\n\t\t\txml.loadXML( data );\n\t\t}\n\t} catch( e ) {\n\t\txml = undefined;\n\t}\n\tif ( !xml || !xml.documentElement || xml.getElementsByTagName( \"parsererror\" ).length ) {\n\t\tjQuery.error( \"Invalid XML: \" + data );\n\t}\n\treturn xml;\n};\n\n\nvar\n\t// Document location\n\tajaxLocParts,\n\tajaxLocation,\n\n\trhash = /#.*$/,\n\trts = /([?&])_=[^&]*/,\n\trheaders = /^(.*?):[ \\t]*([^\\r\\n]*)\\r?$/mg, // IE leaves an \\r character at EOL\n\t// #7653, #8125, #8152: local protocol detection\n\trlocalProtocol = /^(?:about|app|app-storage|.+-extension|file|res|widget):$/,\n\trnoContent = /^(?:GET|HEAD)$/,\n\trprotocol = /^\\/\\//,\n\trurl = /^([\\w.+-]+:)(?:\\/\\/(?:[^\\/?#]*@|)([^\\/?#:]*)(?::(\\d+)|)|)/,\n\n\t/* Prefilters\n\t * 1) They are useful to introduce custom dataTypes (see ajax/jsonp.js for an example)\n\t * 2) These are called:\n\t *    - BEFORE asking for a transport\n\t *    - AFTER param serialization (s.data is a string if s.processData is true)\n\t * 3) key is the dataType\n\t * 4) the catchall symbol \"*\" can be used\n\t * 5) execution will start with transport dataType and THEN continue down to \"*\" if needed\n\t */\n\tprefilters = {},\n\n\t/* Transports bindings\n\t * 1) key is the dataType\n\t * 2) the catchall symbol \"*\" can be used\n\t * 3) selection will start with transport dataType and THEN go to \"*\" if needed\n\t */\n\ttransports = {},\n\n\t// Avoid comment-prolog char sequence (#10098); must appease lint and evade compression\n\tallTypes = \"*/\".concat(\"*\");\n\n// #8138, IE may throw an exception when accessing\n// a field from window.location if document.domain has been set\ntry {\n\tajaxLocation = location.href;\n} catch( e ) {\n\t// Use the href attribute of an A element\n\t// since IE will modify it given document.location\n\tajaxLocation = document.createElement( \"a\" );\n\tajaxLocation.href = \"\";\n\tajaxLocation = ajaxLocation.href;\n}\n\n// Segment location into parts\najaxLocParts = rurl.exec( ajaxLocation.toLowerCase() ) || [];\n\n// Base \"constructor\" for jQuery.ajaxPrefilter and jQuery.ajaxTransport\nfunction addToPrefiltersOrTransports( structure ) {\n\n\t// dataTypeExpression is optional and defaults to \"*\"\n\treturn function( dataTypeExpression, func ) {\n\n\t\tif ( typeof dataTypeExpression !== \"string\" ) {\n\t\t\tfunc = dataTypeExpression;\n\t\t\tdataTypeExpression = \"*\";\n\t\t}\n\n\t\tvar dataType,\n\t\t\ti = 0,\n\t\t\tdataTypes = dataTypeExpression.toLowerCase().match( rnotwhite ) || [];\n\n\t\tif ( jQuery.isFunction( func ) ) {\n\t\t\t// For each dataType in the dataTypeExpression\n\t\t\twhile ( (dataType = dataTypes[i++]) ) {\n\t\t\t\t// Prepend if requested\n\t\t\t\tif ( dataType.charAt( 0 ) === \"+\" ) {\n\t\t\t\t\tdataType = dataType.slice( 1 ) || \"*\";\n\t\t\t\t\t(structure[ dataType ] = structure[ dataType ] || []).unshift( func );\n\n\t\t\t\t// Otherwise append\n\t\t\t\t} else {\n\t\t\t\t\t(structure[ dataType ] = structure[ dataType ] || []).push( func );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t};\n}\n\n// Base inspection function for prefilters and transports\nfunction inspectPrefiltersOrTransports( structure, options, originalOptions, jqXHR ) {\n\n\tvar inspected = {},\n\t\tseekingTransport = ( structure === transports );\n\n\tfunction inspect( dataType ) {\n\t\tvar selected;\n\t\tinspected[ dataType ] = true;\n\t\tjQuery.each( structure[ dataType ] || [], function( _, prefilterOrFactory ) {\n\t\t\tvar dataTypeOrTransport = prefilterOrFactory( options, originalOptions, jqXHR );\n\t\t\tif ( typeof dataTypeOrTransport === \"string\" && !seekingTransport && !inspected[ dataTypeOrTransport ] ) {\n\t\t\t\toptions.dataTypes.unshift( dataTypeOrTransport );\n\t\t\t\tinspect( dataTypeOrTransport );\n\t\t\t\treturn false;\n\t\t\t} else if ( seekingTransport ) {\n\t\t\t\treturn !( selected = dataTypeOrTransport );\n\t\t\t}\n\t\t});\n\t\treturn selected;\n\t}\n\n\treturn inspect( options.dataTypes[ 0 ] ) || !inspected[ \"*\" ] && inspect( \"*\" );\n}\n\n// A special extend for ajax options\n// that takes \"flat\" options (not to be deep extended)\n// Fixes #9887\nfunction ajaxExtend( target, src ) {\n\tvar deep, key,\n\t\tflatOptions = jQuery.ajaxSettings.flatOptions || {};\n\n\tfor ( key in src ) {\n\t\tif ( src[ key ] !== undefined ) {\n\t\t\t( flatOptions[ key ] ? target : ( deep || (deep = {}) ) )[ key ] = src[ key ];\n\t\t}\n\t}\n\tif ( deep ) {\n\t\tjQuery.extend( true, target, deep );\n\t}\n\n\treturn target;\n}\n\n/* Handles responses to an ajax request:\n * - finds the right dataType (mediates between content-type and expected dataType)\n * - returns the corresponding response\n */\nfunction ajaxHandleResponses( s, jqXHR, responses ) {\n\tvar firstDataType, ct, finalDataType, type,\n\t\tcontents = s.contents,\n\t\tdataTypes = s.dataTypes;\n\n\t// Remove auto dataType and get content-type in the process\n\twhile ( dataTypes[ 0 ] === \"*\" ) {\n\t\tdataTypes.shift();\n\t\tif ( ct === undefined ) {\n\t\t\tct = s.mimeType || jqXHR.getResponseHeader(\"Content-Type\");\n\t\t}\n\t}\n\n\t// Check if we're dealing with a known content-type\n\tif ( ct ) {\n\t\tfor ( type in contents ) {\n\t\t\tif ( contents[ type ] && contents[ type ].test( ct ) ) {\n\t\t\t\tdataTypes.unshift( type );\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t}\n\n\t// Check to see if we have a response for the expected dataType\n\tif ( dataTypes[ 0 ] in responses ) {\n\t\tfinalDataType = dataTypes[ 0 ];\n\t} else {\n\t\t// Try convertible dataTypes\n\t\tfor ( type in responses ) {\n\t\t\tif ( !dataTypes[ 0 ] || s.converters[ type + \" \" + dataTypes[0] ] ) {\n\t\t\t\tfinalDataType = type;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tif ( !firstDataType ) {\n\t\t\t\tfirstDataType = type;\n\t\t\t}\n\t\t}\n\t\t// Or just use first one\n\t\tfinalDataType = finalDataType || firstDataType;\n\t}\n\n\t// If we found a dataType\n\t// We add the dataType to the list if needed\n\t// and return the corresponding response\n\tif ( finalDataType ) {\n\t\tif ( finalDataType !== dataTypes[ 0 ] ) {\n\t\t\tdataTypes.unshift( finalDataType );\n\t\t}\n\t\treturn responses[ finalDataType ];\n\t}\n}\n\n/* Chain conversions given the request and the original response\n * Also sets the responseXXX fields on the jqXHR instance\n */\nfunction ajaxConvert( s, response, jqXHR, isSuccess ) {\n\tvar conv2, current, conv, tmp, prev,\n\t\tconverters = {},\n\t\t// Work with a copy of dataTypes in case we need to modify it for conversion\n\t\tdataTypes = s.dataTypes.slice();\n\n\t// Create converters map with lowercased keys\n\tif ( dataTypes[ 1 ] ) {\n\t\tfor ( conv in s.converters ) {\n\t\t\tconverters[ conv.toLowerCase() ] = s.converters[ conv ];\n\t\t}\n\t}\n\n\tcurrent = dataTypes.shift();\n\n\t// Convert to each sequential dataType\n\twhile ( current ) {\n\n\t\tif ( s.responseFields[ current ] ) {\n\t\t\tjqXHR[ s.responseFields[ current ] ] = response;\n\t\t}\n\n\t\t// Apply the dataFilter if provided\n\t\tif ( !prev && isSuccess && s.dataFilter ) {\n\t\t\tresponse = s.dataFilter( response, s.dataType );\n\t\t}\n\n\t\tprev = current;\n\t\tcurrent = dataTypes.shift();\n\n\t\tif ( current ) {\n\n\t\t\t// There's only work to do if current dataType is non-auto\n\t\t\tif ( current === \"*\" ) {\n\n\t\t\t\tcurrent = prev;\n\n\t\t\t// Convert response if prev dataType is non-auto and differs from current\n\t\t\t} else if ( prev !== \"*\" && prev !== current ) {\n\n\t\t\t\t// Seek a direct converter\n\t\t\t\tconv = converters[ prev + \" \" + current ] || converters[ \"* \" + current ];\n\n\t\t\t\t// If none found, seek a pair\n\t\t\t\tif ( !conv ) {\n\t\t\t\t\tfor ( conv2 in converters ) {\n\n\t\t\t\t\t\t// If conv2 outputs current\n\t\t\t\t\t\ttmp = conv2.split( \" \" );\n\t\t\t\t\t\tif ( tmp[ 1 ] === current ) {\n\n\t\t\t\t\t\t\t// If prev can be converted to accepted input\n\t\t\t\t\t\t\tconv = converters[ prev + \" \" + tmp[ 0 ] ] ||\n\t\t\t\t\t\t\t\tconverters[ \"* \" + tmp[ 0 ] ];\n\t\t\t\t\t\t\tif ( conv ) {\n\t\t\t\t\t\t\t\t// Condense equivalence converters\n\t\t\t\t\t\t\t\tif ( conv === true ) {\n\t\t\t\t\t\t\t\t\tconv = converters[ conv2 ];\n\n\t\t\t\t\t\t\t\t// Otherwise, insert the intermediate dataType\n\t\t\t\t\t\t\t\t} else if ( converters[ conv2 ] !== true ) {\n\t\t\t\t\t\t\t\t\tcurrent = tmp[ 0 ];\n\t\t\t\t\t\t\t\t\tdataTypes.unshift( tmp[ 1 ] );\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// Apply converter (if not an equivalence)\n\t\t\t\tif ( conv !== true ) {\n\n\t\t\t\t\t// Unless errors are allowed to bubble, catch and return them\n\t\t\t\t\tif ( conv && s[ \"throws\" ] ) {\n\t\t\t\t\t\tresponse = conv( response );\n\t\t\t\t\t} else {\n\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\tresponse = conv( response );\n\t\t\t\t\t\t} catch ( e ) {\n\t\t\t\t\t\t\treturn { state: \"parsererror\", error: conv ? e : \"No conversion from \" + prev + \" to \" + current };\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\treturn { state: \"success\", data: response };\n}\n\njQuery.extend({\n\n\t// Counter for holding the number of active queries\n\tactive: 0,\n\n\t// Last-Modified header cache for next request\n\tlastModified: {},\n\tetag: {},\n\n\tajaxSettings: {\n\t\turl: ajaxLocation,\n\t\ttype: \"GET\",\n\t\tisLocal: rlocalProtocol.test( ajaxLocParts[ 1 ] ),\n\t\tglobal: true,\n\t\tprocessData: true,\n\t\tasync: true,\n\t\tcontentType: \"application/x-www-form-urlencoded; charset=UTF-8\",\n\t\t/*\n\t\ttimeout: 0,\n\t\tdata: null,\n\t\tdataType: null,\n\t\tusername: null,\n\t\tpassword: null,\n\t\tcache: null,\n\t\tthrows: false,\n\t\ttraditional: false,\n\t\theaders: {},\n\t\t*/\n\n\t\taccepts: {\n\t\t\t\"*\": allTypes,\n\t\t\ttext: \"text/plain\",\n\t\t\thtml: \"text/html\",\n\t\t\txml: \"application/xml, text/xml\",\n\t\t\tjson: \"application/json, text/javascript\"\n\t\t},\n\n\t\tcontents: {\n\t\t\txml: /xml/,\n\t\t\thtml: /html/,\n\t\t\tjson: /json/\n\t\t},\n\n\t\tresponseFields: {\n\t\t\txml: \"responseXML\",\n\t\t\ttext: \"responseText\",\n\t\t\tjson: \"responseJSON\"\n\t\t},\n\n\t\t// Data converters\n\t\t// Keys separate source (or catchall \"*\") and destination types with a single space\n\t\tconverters: {\n\n\t\t\t// Convert anything to text\n\t\t\t\"* text\": String,\n\n\t\t\t// Text to html (true = no transformation)\n\t\t\t\"text html\": true,\n\n\t\t\t// Evaluate text as a json expression\n\t\t\t\"text json\": jQuery.parseJSON,\n\n\t\t\t// Parse text as xml\n\t\t\t\"text xml\": jQuery.parseXML\n\t\t},\n\n\t\t// For options that shouldn't be deep extended:\n\t\t// you can add your own custom options here if\n\t\t// and when you create one that shouldn't be\n\t\t// deep extended (see ajaxExtend)\n\t\tflatOptions: {\n\t\t\turl: true,\n\t\t\tcontext: true\n\t\t}\n\t},\n\n\t// Creates a full fledged settings object into target\n\t// with both ajaxSettings and settings fields.\n\t// If target is omitted, writes into ajaxSettings.\n\tajaxSetup: function( target, settings ) {\n\t\treturn settings ?\n\n\t\t\t// Building a settings object\n\t\t\tajaxExtend( ajaxExtend( target, jQuery.ajaxSettings ), settings ) :\n\n\t\t\t// Extending ajaxSettings\n\t\t\tajaxExtend( jQuery.ajaxSettings, target );\n\t},\n\n\tajaxPrefilter: addToPrefiltersOrTransports( prefilters ),\n\tajaxTransport: addToPrefiltersOrTransports( transports ),\n\n\t// Main method\n\tajax: function( url, options ) {\n\n\t\t// If url is an object, simulate pre-1.5 signature\n\t\tif ( typeof url === \"object\" ) {\n\t\t\toptions = url;\n\t\t\turl = undefined;\n\t\t}\n\n\t\t// Force options to be an object\n\t\toptions = options || {};\n\n\t\tvar // Cross-domain detection vars\n\t\t\tparts,\n\t\t\t// Loop variable\n\t\t\ti,\n\t\t\t// URL without anti-cache param\n\t\t\tcacheURL,\n\t\t\t// Response headers as string\n\t\t\tresponseHeadersString,\n\t\t\t// timeout handle\n\t\t\ttimeoutTimer,\n\n\t\t\t// To know if global events are to be dispatched\n\t\t\tfireGlobals,\n\n\t\t\ttransport,\n\t\t\t// Response headers\n\t\t\tresponseHeaders,\n\t\t\t// Create the final options object\n\t\t\ts = jQuery.ajaxSetup( {}, options ),\n\t\t\t// Callbacks context\n\t\t\tcallbackContext = s.context || s,\n\t\t\t// Context for global events is callbackContext if it is a DOM node or jQuery collection\n\t\t\tglobalEventContext = s.context && ( callbackContext.nodeType || callbackContext.jquery ) ?\n\t\t\t\tjQuery( callbackContext ) :\n\t\t\t\tjQuery.event,\n\t\t\t// Deferreds\n\t\t\tdeferred = jQuery.Deferred(),\n\t\t\tcompleteDeferred = jQuery.Callbacks(\"once memory\"),\n\t\t\t// Status-dependent callbacks\n\t\t\tstatusCode = s.statusCode || {},\n\t\t\t// Headers (they are sent all at once)\n\t\t\trequestHeaders = {},\n\t\t\trequestHeadersNames = {},\n\t\t\t// The jqXHR state\n\t\t\tstate = 0,\n\t\t\t// Default abort message\n\t\t\tstrAbort = \"canceled\",\n\t\t\t// Fake xhr\n\t\t\tjqXHR = {\n\t\t\t\treadyState: 0,\n\n\t\t\t\t// Builds headers hashtable if needed\n\t\t\t\tgetResponseHeader: function( key ) {\n\t\t\t\t\tvar match;\n\t\t\t\t\tif ( state === 2 ) {\n\t\t\t\t\t\tif ( !responseHeaders ) {\n\t\t\t\t\t\t\tresponseHeaders = {};\n\t\t\t\t\t\t\twhile ( (match = rheaders.exec( responseHeadersString )) ) {\n\t\t\t\t\t\t\t\tresponseHeaders[ match[1].toLowerCase() ] = match[ 2 ];\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\tmatch = responseHeaders[ key.toLowerCase() ];\n\t\t\t\t\t}\n\t\t\t\t\treturn match == null ? null : match;\n\t\t\t\t},\n\n\t\t\t\t// Raw string\n\t\t\t\tgetAllResponseHeaders: function() {\n\t\t\t\t\treturn state === 2 ? responseHeadersString : null;\n\t\t\t\t},\n\n\t\t\t\t// Caches the header\n\t\t\t\tsetRequestHeader: function( name, value ) {\n\t\t\t\t\tvar lname = name.toLowerCase();\n\t\t\t\t\tif ( !state ) {\n\t\t\t\t\t\tname = requestHeadersNames[ lname ] = requestHeadersNames[ lname ] || name;\n\t\t\t\t\t\trequestHeaders[ name ] = value;\n\t\t\t\t\t}\n\t\t\t\t\treturn this;\n\t\t\t\t},\n\n\t\t\t\t// Overrides response content-type header\n\t\t\t\toverrideMimeType: function( type ) {\n\t\t\t\t\tif ( !state ) {\n\t\t\t\t\t\ts.mimeType = type;\n\t\t\t\t\t}\n\t\t\t\t\treturn this;\n\t\t\t\t},\n\n\t\t\t\t// Status-dependent callbacks\n\t\t\t\tstatusCode: function( map ) {\n\t\t\t\t\tvar code;\n\t\t\t\t\tif ( map ) {\n\t\t\t\t\t\tif ( state < 2 ) {\n\t\t\t\t\t\t\tfor ( code in map ) {\n\t\t\t\t\t\t\t\t// Lazy-add the new callback in a way that preserves old ones\n\t\t\t\t\t\t\t\tstatusCode[ code ] = [ statusCode[ code ], map[ code ] ];\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t// Execute the appropriate callbacks\n\t\t\t\t\t\t\tjqXHR.always( map[ jqXHR.status ] );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\treturn this;\n\t\t\t\t},\n\n\t\t\t\t// Cancel the request\n\t\t\t\tabort: function( statusText ) {\n\t\t\t\t\tvar finalText = statusText || strAbort;\n\t\t\t\t\tif ( transport ) {\n\t\t\t\t\t\ttransport.abort( finalText );\n\t\t\t\t\t}\n\t\t\t\t\tdone( 0, finalText );\n\t\t\t\t\treturn this;\n\t\t\t\t}\n\t\t\t};\n\n\t\t// Attach deferreds\n\t\tdeferred.promise( jqXHR ).complete = completeDeferred.add;\n\t\tjqXHR.success = jqXHR.done;\n\t\tjqXHR.error = jqXHR.fail;\n\n\t\t// Remove hash character (#7531: and string promotion)\n\t\t// Add protocol if not provided (#5866: IE7 issue with protocol-less urls)\n\t\t// Handle falsy url in the settings object (#10093: consistency with old signature)\n\t\t// We also use the url parameter if available\n\t\ts.url = ( ( url || s.url || ajaxLocation ) + \"\" ).replace( rhash, \"\" ).replace( rprotocol, ajaxLocParts[ 1 ] + \"//\" );\n\n\t\t// Alias method option to type as per ticket #12004\n\t\ts.type = options.method || options.type || s.method || s.type;\n\n\t\t// Extract dataTypes list\n\t\ts.dataTypes = jQuery.trim( s.dataType || \"*\" ).toLowerCase().match( rnotwhite ) || [ \"\" ];\n\n\t\t// A cross-domain request is in order when we have a protocol:host:port mismatch\n\t\tif ( s.crossDomain == null ) {\n\t\t\tparts = rurl.exec( s.url.toLowerCase() );\n\t\t\ts.crossDomain = !!( parts &&\n\t\t\t\t( parts[ 1 ] !== ajaxLocParts[ 1 ] || parts[ 2 ] !== ajaxLocParts[ 2 ] ||\n\t\t\t\t\t( parts[ 3 ] || ( parts[ 1 ] === \"http:\" ? \"80\" : \"443\" ) ) !==\n\t\t\t\t\t\t( ajaxLocParts[ 3 ] || ( ajaxLocParts[ 1 ] === \"http:\" ? \"80\" : \"443\" ) ) )\n\t\t\t);\n\t\t}\n\n\t\t// Convert data if not already a string\n\t\tif ( s.data && s.processData && typeof s.data !== \"string\" ) {\n\t\t\ts.data = jQuery.param( s.data, s.traditional );\n\t\t}\n\n\t\t// Apply prefilters\n\t\tinspectPrefiltersOrTransports( prefilters, s, options, jqXHR );\n\n\t\t// If request was aborted inside a prefilter, stop there\n\t\tif ( state === 2 ) {\n\t\t\treturn jqXHR;\n\t\t}\n\n\t\t// We can fire global events as of now if asked to\n\t\t// Don't fire events if jQuery.event is undefined in an AMD-usage scenario (#15118)\n\t\tfireGlobals = jQuery.event && s.global;\n\n\t\t// Watch for a new set of requests\n\t\tif ( fireGlobals && jQuery.active++ === 0 ) {\n\t\t\tjQuery.event.trigger(\"ajaxStart\");\n\t\t}\n\n\t\t// Uppercase the type\n\t\ts.type = s.type.toUpperCase();\n\n\t\t// Determine if request has content\n\t\ts.hasContent = !rnoContent.test( s.type );\n\n\t\t// Save the URL in case we're toying with the If-Modified-Since\n\t\t// and/or If-None-Match header later on\n\t\tcacheURL = s.url;\n\n\t\t// More options handling for requests with no content\n\t\tif ( !s.hasContent ) {\n\n\t\t\t// If data is available, append data to url\n\t\t\tif ( s.data ) {\n\t\t\t\tcacheURL = ( s.url += ( rquery.test( cacheURL ) ? \"&\" : \"?\" ) + s.data );\n\t\t\t\t// #9682: remove data so that it's not used in an eventual retry\n\t\t\t\tdelete s.data;\n\t\t\t}\n\n\t\t\t// Add anti-cache in url if needed\n\t\t\tif ( s.cache === false ) {\n\t\t\t\ts.url = rts.test( cacheURL ) ?\n\n\t\t\t\t\t// If there is already a '_' parameter, set its value\n\t\t\t\t\tcacheURL.replace( rts, \"$1_=\" + nonce++ ) :\n\n\t\t\t\t\t// Otherwise add one to the end\n\t\t\t\t\tcacheURL + ( rquery.test( cacheURL ) ? \"&\" : \"?\" ) + \"_=\" + nonce++;\n\t\t\t}\n\t\t}\n\n\t\t// Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.\n\t\tif ( s.ifModified ) {\n\t\t\tif ( jQuery.lastModified[ cacheURL ] ) {\n\t\t\t\tjqXHR.setRequestHeader( \"If-Modified-Since\", jQuery.lastModified[ cacheURL ] );\n\t\t\t}\n\t\t\tif ( jQuery.etag[ cacheURL ] ) {\n\t\t\t\tjqXHR.setRequestHeader( \"If-None-Match\", jQuery.etag[ cacheURL ] );\n\t\t\t}\n\t\t}\n\n\t\t// Set the correct header, if data is being sent\n\t\tif ( s.data && s.hasContent && s.contentType !== false || options.contentType ) {\n\t\t\tjqXHR.setRequestHeader( \"Content-Type\", s.contentType );\n\t\t}\n\n\t\t// Set the Accepts header for the server, depending on the dataType\n\t\tjqXHR.setRequestHeader(\n\t\t\t\"Accept\",\n\t\t\ts.dataTypes[ 0 ] && s.accepts[ s.dataTypes[0] ] ?\n\t\t\t\ts.accepts[ s.dataTypes[0] ] + ( s.dataTypes[ 0 ] !== \"*\" ? \", \" + allTypes + \"; q=0.01\" : \"\" ) :\n\t\t\t\ts.accepts[ \"*\" ]\n\t\t);\n\n\t\t// Check for headers option\n\t\tfor ( i in s.headers ) {\n\t\t\tjqXHR.setRequestHeader( i, s.headers[ i ] );\n\t\t}\n\n\t\t// Allow custom headers/mimetypes and early abort\n\t\tif ( s.beforeSend && ( s.beforeSend.call( callbackContext, jqXHR, s ) === false || state === 2 ) ) {\n\t\t\t// Abort if not done already and return\n\t\t\treturn jqXHR.abort();\n\t\t}\n\n\t\t// aborting is no longer a cancellation\n\t\tstrAbort = \"abort\";\n\n\t\t// Install callbacks on deferreds\n\t\tfor ( i in { success: 1, error: 1, complete: 1 } ) {\n\t\t\tjqXHR[ i ]( s[ i ] );\n\t\t}\n\n\t\t// Get transport\n\t\ttransport = inspectPrefiltersOrTransports( transports, s, options, jqXHR );\n\n\t\t// If no transport, we auto-abort\n\t\tif ( !transport ) {\n\t\t\tdone( -1, \"No Transport\" );\n\t\t} else {\n\t\t\tjqXHR.readyState = 1;\n\n\t\t\t// Send global event\n\t\t\tif ( fireGlobals ) {\n\t\t\t\tglobalEventContext.trigger( \"ajaxSend\", [ jqXHR, s ] );\n\t\t\t}\n\t\t\t// Timeout\n\t\t\tif ( s.async && s.timeout > 0 ) {\n\t\t\t\ttimeoutTimer = setTimeout(function() {\n\t\t\t\t\tjqXHR.abort(\"timeout\");\n\t\t\t\t}, s.timeout );\n\t\t\t}\n\n\t\t\ttry {\n\t\t\t\tstate = 1;\n\t\t\t\ttransport.send( requestHeaders, done );\n\t\t\t} catch ( e ) {\n\t\t\t\t// Propagate exception as error if not done\n\t\t\t\tif ( state < 2 ) {\n\t\t\t\t\tdone( -1, e );\n\t\t\t\t// Simply rethrow otherwise\n\t\t\t\t} else {\n\t\t\t\t\tthrow e;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Callback for when everything is done\n\t\tfunction done( status, nativeStatusText, responses, headers ) {\n\t\t\tvar isSuccess, success, error, response, modified,\n\t\t\t\tstatusText = nativeStatusText;\n\n\t\t\t// Called once\n\t\t\tif ( state === 2 ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// State is \"done\" now\n\t\t\tstate = 2;\n\n\t\t\t// Clear timeout if it exists\n\t\t\tif ( timeoutTimer ) {\n\t\t\t\tclearTimeout( timeoutTimer );\n\t\t\t}\n\n\t\t\t// Dereference transport for early garbage collection\n\t\t\t// (no matter how long the jqXHR object will be used)\n\t\t\ttransport = undefined;\n\n\t\t\t// Cache response headers\n\t\t\tresponseHeadersString = headers || \"\";\n\n\t\t\t// Set readyState\n\t\t\tjqXHR.readyState = status > 0 ? 4 : 0;\n\n\t\t\t// Determine if successful\n\t\t\tisSuccess = status >= 200 && status < 300 || status === 304;\n\n\t\t\t// Get response data\n\t\t\tif ( responses ) {\n\t\t\t\tresponse = ajaxHandleResponses( s, jqXHR, responses );\n\t\t\t}\n\n\t\t\t// Convert no matter what (that way responseXXX fields are always set)\n\t\t\tresponse = ajaxConvert( s, response, jqXHR, isSuccess );\n\n\t\t\t// If successful, handle type chaining\n\t\t\tif ( isSuccess ) {\n\n\t\t\t\t// Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.\n\t\t\t\tif ( s.ifModified ) {\n\t\t\t\t\tmodified = jqXHR.getResponseHeader(\"Last-Modified\");\n\t\t\t\t\tif ( modified ) {\n\t\t\t\t\t\tjQuery.lastModified[ cacheURL ] = modified;\n\t\t\t\t\t}\n\t\t\t\t\tmodified = jqXHR.getResponseHeader(\"etag\");\n\t\t\t\t\tif ( modified ) {\n\t\t\t\t\t\tjQuery.etag[ cacheURL ] = modified;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// if no content\n\t\t\t\tif ( status === 204 || s.type === \"HEAD\" ) {\n\t\t\t\t\tstatusText = \"nocontent\";\n\n\t\t\t\t// if not modified\n\t\t\t\t} else if ( status === 304 ) {\n\t\t\t\t\tstatusText = \"notmodified\";\n\n\t\t\t\t// If we have data, let's convert it\n\t\t\t\t} else {\n\t\t\t\t\tstatusText = response.state;\n\t\t\t\t\tsuccess = response.data;\n\t\t\t\t\terror = response.error;\n\t\t\t\t\tisSuccess = !error;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t// We extract error from statusText\n\t\t\t\t// then normalize statusText and status for non-aborts\n\t\t\t\terror = statusText;\n\t\t\t\tif ( status || !statusText ) {\n\t\t\t\t\tstatusText = \"error\";\n\t\t\t\t\tif ( status < 0 ) {\n\t\t\t\t\t\tstatus = 0;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Set data for the fake xhr object\n\t\t\tjqXHR.status = status;\n\t\t\tjqXHR.statusText = ( nativeStatusText || statusText ) + \"\";\n\n\t\t\t// Success/Error\n\t\t\tif ( isSuccess ) {\n\t\t\t\tdeferred.resolveWith( callbackContext, [ success, statusText, jqXHR ] );\n\t\t\t} else {\n\t\t\t\tdeferred.rejectWith( callbackContext, [ jqXHR, statusText, error ] );\n\t\t\t}\n\n\t\t\t// Status-dependent callbacks\n\t\t\tjqXHR.statusCode( statusCode );\n\t\t\tstatusCode = undefined;\n\n\t\t\tif ( fireGlobals ) {\n\t\t\t\tglobalEventContext.trigger( isSuccess ? \"ajaxSuccess\" : \"ajaxError\",\n\t\t\t\t\t[ jqXHR, s, isSuccess ? success : error ] );\n\t\t\t}\n\n\t\t\t// Complete\n\t\t\tcompleteDeferred.fireWith( callbackContext, [ jqXHR, statusText ] );\n\n\t\t\tif ( fireGlobals ) {\n\t\t\t\tglobalEventContext.trigger( \"ajaxComplete\", [ jqXHR, s ] );\n\t\t\t\t// Handle the global AJAX counter\n\t\t\t\tif ( !( --jQuery.active ) ) {\n\t\t\t\t\tjQuery.event.trigger(\"ajaxStop\");\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn jqXHR;\n\t},\n\n\tgetJSON: function( url, data, callback ) {\n\t\treturn jQuery.get( url, data, callback, \"json\" );\n\t},\n\n\tgetScript: function( url, callback ) {\n\t\treturn jQuery.get( url, undefined, callback, \"script\" );\n\t}\n});\n\njQuery.each( [ \"get\", \"post\" ], function( i, method ) {\n\tjQuery[ method ] = function( url, data, callback, type ) {\n\t\t// shift arguments if data argument was omitted\n\t\tif ( jQuery.isFunction( data ) ) {\n\t\t\ttype = type || callback;\n\t\t\tcallback = data;\n\t\t\tdata = undefined;\n\t\t}\n\n\t\treturn jQuery.ajax({\n\t\t\turl: url,\n\t\t\ttype: method,\n\t\t\tdataType: type,\n\t\t\tdata: data,\n\t\t\tsuccess: callback\n\t\t});\n\t};\n});\n\n\njQuery._evalUrl = function( url ) {\n\treturn jQuery.ajax({\n\t\turl: url,\n\t\ttype: \"GET\",\n\t\tdataType: \"script\",\n\t\tasync: false,\n\t\tglobal: false,\n\t\t\"throws\": true\n\t});\n};\n\n\njQuery.fn.extend({\n\twrapAll: function( html ) {\n\t\tif ( jQuery.isFunction( html ) ) {\n\t\t\treturn this.each(function(i) {\n\t\t\t\tjQuery(this).wrapAll( html.call(this, i) );\n\t\t\t});\n\t\t}\n\n\t\tif ( this[0] ) {\n\t\t\t// The elements to wrap the target around\n\t\t\tvar wrap = jQuery( html, this[0].ownerDocument ).eq(0).clone(true);\n\n\t\t\tif ( this[0].parentNode ) {\n\t\t\t\twrap.insertBefore( this[0] );\n\t\t\t}\n\n\t\t\twrap.map(function() {\n\t\t\t\tvar elem = this;\n\n\t\t\t\twhile ( elem.firstChild && elem.firstChild.nodeType === 1 ) {\n\t\t\t\t\telem = elem.firstChild;\n\t\t\t\t}\n\n\t\t\t\treturn elem;\n\t\t\t}).append( this );\n\t\t}\n\n\t\treturn this;\n\t},\n\n\twrapInner: function( html ) {\n\t\tif ( jQuery.isFunction( html ) ) {\n\t\t\treturn this.each(function(i) {\n\t\t\t\tjQuery(this).wrapInner( html.call(this, i) );\n\t\t\t});\n\t\t}\n\n\t\treturn this.each(function() {\n\t\t\tvar self = jQuery( this ),\n\t\t\t\tcontents = self.contents();\n\n\t\t\tif ( contents.length ) {\n\t\t\t\tcontents.wrapAll( html );\n\n\t\t\t} else {\n\t\t\t\tself.append( html );\n\t\t\t}\n\t\t});\n\t},\n\n\twrap: function( html ) {\n\t\tvar isFunction = jQuery.isFunction( html );\n\n\t\treturn this.each(function(i) {\n\t\t\tjQuery( this ).wrapAll( isFunction ? html.call(this, i) : html );\n\t\t});\n\t},\n\n\tunwrap: function() {\n\t\treturn this.parent().each(function() {\n\t\t\tif ( !jQuery.nodeName( this, \"body\" ) ) {\n\t\t\t\tjQuery( this ).replaceWith( this.childNodes );\n\t\t\t}\n\t\t}).end();\n\t}\n});\n\n\njQuery.expr.filters.hidden = function( elem ) {\n\t// Support: Opera <= 12.12\n\t// Opera reports offsetWidths and offsetHeights less than zero on some elements\n\treturn elem.offsetWidth <= 0 && elem.offsetHeight <= 0 ||\n\t\t(!support.reliableHiddenOffsets() &&\n\t\t\t((elem.style && elem.style.display) || jQuery.css( elem, \"display\" )) === \"none\");\n};\n\njQuery.expr.filters.visible = function( elem ) {\n\treturn !jQuery.expr.filters.hidden( elem );\n};\n\n\n\n\nvar r20 = /%20/g,\n\trbracket = /\\[\\]$/,\n\trCRLF = /\\r?\\n/g,\n\trsubmitterTypes = /^(?:submit|button|image|reset|file)$/i,\n\trsubmittable = /^(?:input|select|textarea|keygen)/i;\n\nfunction buildParams( prefix, obj, traditional, add ) {\n\tvar name;\n\n\tif ( jQuery.isArray( obj ) ) {\n\t\t// Serialize array item.\n\t\tjQuery.each( obj, function( i, v ) {\n\t\t\tif ( traditional || rbracket.test( prefix ) ) {\n\t\t\t\t// Treat each array item as a scalar.\n\t\t\t\tadd( prefix, v );\n\n\t\t\t} else {\n\t\t\t\t// Item is non-scalar (array or object), encode its numeric index.\n\t\t\t\tbuildParams( prefix + \"[\" + ( typeof v === \"object\" ? i : \"\" ) + \"]\", v, traditional, add );\n\t\t\t}\n\t\t});\n\n\t} else if ( !traditional && jQuery.type( obj ) === \"object\" ) {\n\t\t// Serialize object item.\n\t\tfor ( name in obj ) {\n\t\t\tbuildParams( prefix + \"[\" + name + \"]\", obj[ name ], traditional, add );\n\t\t}\n\n\t} else {\n\t\t// Serialize scalar item.\n\t\tadd( prefix, obj );\n\t}\n}\n\n// Serialize an array of form elements or a set of\n// key/values into a query string\njQuery.param = function( a, traditional ) {\n\tvar prefix,\n\t\ts = [],\n\t\tadd = function( key, value ) {\n\t\t\t// If value is a function, invoke it and return its value\n\t\t\tvalue = jQuery.isFunction( value ) ? value() : ( value == null ? \"\" : value );\n\t\t\ts[ s.length ] = encodeURIComponent( key ) + \"=\" + encodeURIComponent( value );\n\t\t};\n\n\t// Set traditional to true for jQuery <= 1.3.2 behavior.\n\tif ( traditional === undefined ) {\n\t\ttraditional = jQuery.ajaxSettings && jQuery.ajaxSettings.traditional;\n\t}\n\n\t// If an array was passed in, assume that it is an array of form elements.\n\tif ( jQuery.isArray( a ) || ( a.jquery && !jQuery.isPlainObject( a ) ) ) {\n\t\t// Serialize the form elements\n\t\tjQuery.each( a, function() {\n\t\t\tadd( this.name, this.value );\n\t\t});\n\n\t} else {\n\t\t// If traditional, encode the \"old\" way (the way 1.3.2 or older\n\t\t// did it), otherwise encode params recursively.\n\t\tfor ( prefix in a ) {\n\t\t\tbuildParams( prefix, a[ prefix ], traditional, add );\n\t\t}\n\t}\n\n\t// Return the resulting serialization\n\treturn s.join( \"&\" ).replace( r20, \"+\" );\n};\n\njQuery.fn.extend({\n\tserialize: function() {\n\t\treturn jQuery.param( this.serializeArray() );\n\t},\n\tserializeArray: function() {\n\t\treturn this.map(function() {\n\t\t\t// Can add propHook for \"elements\" to filter or add form elements\n\t\t\tvar elements = jQuery.prop( this, \"elements\" );\n\t\t\treturn elements ? jQuery.makeArray( elements ) : this;\n\t\t})\n\t\t.filter(function() {\n\t\t\tvar type = this.type;\n\t\t\t// Use .is(\":disabled\") so that fieldset[disabled] works\n\t\t\treturn this.name && !jQuery( this ).is( \":disabled\" ) &&\n\t\t\t\trsubmittable.test( this.nodeName ) && !rsubmitterTypes.test( type ) &&\n\t\t\t\t( this.checked || !rcheckableType.test( type ) );\n\t\t})\n\t\t.map(function( i, elem ) {\n\t\t\tvar val = jQuery( this ).val();\n\n\t\t\treturn val == null ?\n\t\t\t\tnull :\n\t\t\t\tjQuery.isArray( val ) ?\n\t\t\t\t\tjQuery.map( val, function( val ) {\n\t\t\t\t\t\treturn { name: elem.name, value: val.replace( rCRLF, \"\\r\\n\" ) };\n\t\t\t\t\t}) :\n\t\t\t\t\t{ name: elem.name, value: val.replace( rCRLF, \"\\r\\n\" ) };\n\t\t}).get();\n\t}\n});\n\n\n// Create the request object\n// (This is still attached to ajaxSettings for backward compatibility)\njQuery.ajaxSettings.xhr = window.ActiveXObject !== undefined ?\n\t// Support: IE6+\n\tfunction() {\n\n\t\t// XHR cannot access local files, always use ActiveX for that case\n\t\treturn !this.isLocal &&\n\n\t\t\t// Support: IE7-8\n\t\t\t// oldIE XHR does not support non-RFC2616 methods (#13240)\n\t\t\t// See http://msdn.microsoft.com/en-us/library/ie/ms536648(v=vs.85).aspx\n\t\t\t// and http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html#sec9\n\t\t\t// Although this check for six methods instead of eight\n\t\t\t// since IE also does not support \"trace\" and \"connect\"\n\t\t\t/^(get|post|head|put|delete|options)$/i.test( this.type ) &&\n\n\t\t\tcreateStandardXHR() || createActiveXHR();\n\t} :\n\t// For all other browsers, use the standard XMLHttpRequest object\n\tcreateStandardXHR;\n\nvar xhrId = 0,\n\txhrCallbacks = {},\n\txhrSupported = jQuery.ajaxSettings.xhr();\n\n// Support: IE<10\n// Open requests must be manually aborted on unload (#5280)\n// See https://support.microsoft.com/kb/2856746 for more info\nif ( window.attachEvent ) {\n\twindow.attachEvent( \"onunload\", function() {\n\t\tfor ( var key in xhrCallbacks ) {\n\t\t\txhrCallbacks[ key ]( undefined, true );\n\t\t}\n\t});\n}\n\n// Determine support properties\nsupport.cors = !!xhrSupported && ( \"withCredentials\" in xhrSupported );\nxhrSupported = support.ajax = !!xhrSupported;\n\n// Create transport if the browser can provide an xhr\nif ( xhrSupported ) {\n\n\tjQuery.ajaxTransport(function( options ) {\n\t\t// Cross domain only allowed if supported through XMLHttpRequest\n\t\tif ( !options.crossDomain || support.cors ) {\n\n\t\t\tvar callback;\n\n\t\t\treturn {\n\t\t\t\tsend: function( headers, complete ) {\n\t\t\t\t\tvar i,\n\t\t\t\t\t\txhr = options.xhr(),\n\t\t\t\t\t\tid = ++xhrId;\n\n\t\t\t\t\t// Open the socket\n\t\t\t\t\txhr.open( options.type, options.url, options.async, options.username, options.password );\n\n\t\t\t\t\t// Apply custom fields if provided\n\t\t\t\t\tif ( options.xhrFields ) {\n\t\t\t\t\t\tfor ( i in options.xhrFields ) {\n\t\t\t\t\t\t\txhr[ i ] = options.xhrFields[ i ];\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\t// Override mime type if needed\n\t\t\t\t\tif ( options.mimeType && xhr.overrideMimeType ) {\n\t\t\t\t\t\txhr.overrideMimeType( options.mimeType );\n\t\t\t\t\t}\n\n\t\t\t\t\t// X-Requested-With header\n\t\t\t\t\t// For cross-domain requests, seeing as conditions for a preflight are\n\t\t\t\t\t// akin to a jigsaw puzzle, we simply never set it to be sure.\n\t\t\t\t\t// (it can always be set on a per-request basis or even using ajaxSetup)\n\t\t\t\t\t// For same-domain requests, won't change header if already provided.\n\t\t\t\t\tif ( !options.crossDomain && !headers[\"X-Requested-With\"] ) {\n\t\t\t\t\t\theaders[\"X-Requested-With\"] = \"XMLHttpRequest\";\n\t\t\t\t\t}\n\n\t\t\t\t\t// Set headers\n\t\t\t\t\tfor ( i in headers ) {\n\t\t\t\t\t\t// Support: IE<9\n\t\t\t\t\t\t// IE's ActiveXObject throws a 'Type Mismatch' exception when setting\n\t\t\t\t\t\t// request header to a null-value.\n\t\t\t\t\t\t//\n\t\t\t\t\t\t// To keep consistent with other XHR implementations, cast the value\n\t\t\t\t\t\t// to string and ignore `undefined`.\n\t\t\t\t\t\tif ( headers[ i ] !== undefined ) {\n\t\t\t\t\t\t\txhr.setRequestHeader( i, headers[ i ] + \"\" );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\t// Do send the request\n\t\t\t\t\t// This may raise an exception which is actually\n\t\t\t\t\t// handled in jQuery.ajax (so no try/catch here)\n\t\t\t\t\txhr.send( ( options.hasContent && options.data ) || null );\n\n\t\t\t\t\t// Listener\n\t\t\t\t\tcallback = function( _, isAbort ) {\n\t\t\t\t\t\tvar status, statusText, responses;\n\n\t\t\t\t\t\t// Was never called and is aborted or complete\n\t\t\t\t\t\tif ( callback && ( isAbort || xhr.readyState === 4 ) ) {\n\t\t\t\t\t\t\t// Clean up\n\t\t\t\t\t\t\tdelete xhrCallbacks[ id ];\n\t\t\t\t\t\t\tcallback = undefined;\n\t\t\t\t\t\t\txhr.onreadystatechange = jQuery.noop;\n\n\t\t\t\t\t\t\t// Abort manually if needed\n\t\t\t\t\t\t\tif ( isAbort ) {\n\t\t\t\t\t\t\t\tif ( xhr.readyState !== 4 ) {\n\t\t\t\t\t\t\t\t\txhr.abort();\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tresponses = {};\n\t\t\t\t\t\t\t\tstatus = xhr.status;\n\n\t\t\t\t\t\t\t\t// Support: IE<10\n\t\t\t\t\t\t\t\t// Accessing binary-data responseText throws an exception\n\t\t\t\t\t\t\t\t// (#11426)\n\t\t\t\t\t\t\t\tif ( typeof xhr.responseText === \"string\" ) {\n\t\t\t\t\t\t\t\t\tresponses.text = xhr.responseText;\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t// Firefox throws an exception when accessing\n\t\t\t\t\t\t\t\t// statusText for faulty cross-domain requests\n\t\t\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t\t\tstatusText = xhr.statusText;\n\t\t\t\t\t\t\t\t} catch( e ) {\n\t\t\t\t\t\t\t\t\t// We normalize with Webkit giving an empty statusText\n\t\t\t\t\t\t\t\t\tstatusText = \"\";\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t// Filter status for non standard behaviors\n\n\t\t\t\t\t\t\t\t// If the request is local and we have data: assume a success\n\t\t\t\t\t\t\t\t// (success with no data won't get notified, that's the best we\n\t\t\t\t\t\t\t\t// can do given current implementations)\n\t\t\t\t\t\t\t\tif ( !status && options.isLocal && !options.crossDomain ) {\n\t\t\t\t\t\t\t\t\tstatus = responses.text ? 200 : 404;\n\t\t\t\t\t\t\t\t// IE - #1450: sometimes returns 1223 when it should be 204\n\t\t\t\t\t\t\t\t} else if ( status === 1223 ) {\n\t\t\t\t\t\t\t\t\tstatus = 204;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// Call complete if needed\n\t\t\t\t\t\tif ( responses ) {\n\t\t\t\t\t\t\tcomplete( status, statusText, responses, xhr.getAllResponseHeaders() );\n\t\t\t\t\t\t}\n\t\t\t\t\t};\n\n\t\t\t\t\tif ( !options.async ) {\n\t\t\t\t\t\t// if we're in sync mode we fire the callback\n\t\t\t\t\t\tcallback();\n\t\t\t\t\t} else if ( xhr.readyState === 4 ) {\n\t\t\t\t\t\t// (IE6 & IE7) if it's in cache and has been\n\t\t\t\t\t\t// retrieved directly we need to fire the callback\n\t\t\t\t\t\tsetTimeout( callback );\n\t\t\t\t\t} else {\n\t\t\t\t\t\t// Add to the list of active xhr callbacks\n\t\t\t\t\t\txhr.onreadystatechange = xhrCallbacks[ id ] = callback;\n\t\t\t\t\t}\n\t\t\t\t},\n\n\t\t\t\tabort: function() {\n\t\t\t\t\tif ( callback ) {\n\t\t\t\t\t\tcallback( undefined, true );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t};\n\t\t}\n\t});\n}\n\n// Functions to create xhrs\nfunction createStandardXHR() {\n\ttry {\n\t\treturn new window.XMLHttpRequest();\n\t} catch( e ) {}\n}\n\nfunction createActiveXHR() {\n\ttry {\n\t\treturn new window.ActiveXObject( \"Microsoft.XMLHTTP\" );\n\t} catch( e ) {}\n}\n\n\n\n\n// Install script dataType\njQuery.ajaxSetup({\n\taccepts: {\n\t\tscript: \"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript\"\n\t},\n\tcontents: {\n\t\tscript: /(?:java|ecma)script/\n\t},\n\tconverters: {\n\t\t\"text script\": function( text ) {\n\t\t\tjQuery.globalEval( text );\n\t\t\treturn text;\n\t\t}\n\t}\n});\n\n// Handle cache's special case and global\njQuery.ajaxPrefilter( \"script\", function( s ) {\n\tif ( s.cache === undefined ) {\n\t\ts.cache = false;\n\t}\n\tif ( s.crossDomain ) {\n\t\ts.type = \"GET\";\n\t\ts.global = false;\n\t}\n});\n\n// Bind script tag hack transport\njQuery.ajaxTransport( \"script\", function(s) {\n\n\t// This transport only deals with cross domain requests\n\tif ( s.crossDomain ) {\n\n\t\tvar script,\n\t\t\thead = document.head || jQuery(\"head\")[0] || document.documentElement;\n\n\t\treturn {\n\n\t\t\tsend: function( _, callback ) {\n\n\t\t\t\tscript = document.createElement(\"script\");\n\n\t\t\t\tscript.async = true;\n\n\t\t\t\tif ( s.scriptCharset ) {\n\t\t\t\t\tscript.charset = s.scriptCharset;\n\t\t\t\t}\n\n\t\t\t\tscript.src = s.url;\n\n\t\t\t\t// Attach handlers for all browsers\n\t\t\t\tscript.onload = script.onreadystatechange = function( _, isAbort ) {\n\n\t\t\t\t\tif ( isAbort || !script.readyState || /loaded|complete/.test( script.readyState ) ) {\n\n\t\t\t\t\t\t// Handle memory leak in IE\n\t\t\t\t\t\tscript.onload = script.onreadystatechange = null;\n\n\t\t\t\t\t\t// Remove the script\n\t\t\t\t\t\tif ( script.parentNode ) {\n\t\t\t\t\t\t\tscript.parentNode.removeChild( script );\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// Dereference the script\n\t\t\t\t\t\tscript = null;\n\n\t\t\t\t\t\t// Callback if not abort\n\t\t\t\t\t\tif ( !isAbort ) {\n\t\t\t\t\t\t\tcallback( 200, \"success\" );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t};\n\n\t\t\t\t// Circumvent IE6 bugs with base elements (#2709 and #4378) by prepending\n\t\t\t\t// Use native DOM manipulation to avoid our domManip AJAX trickery\n\t\t\t\thead.insertBefore( script, head.firstChild );\n\t\t\t},\n\n\t\t\tabort: function() {\n\t\t\t\tif ( script ) {\n\t\t\t\t\tscript.onload( undefined, true );\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\t}\n});\n\n\n\n\nvar oldCallbacks = [],\n\trjsonp = /(=)\\?(?=&|$)|\\?\\?/;\n\n// Default jsonp settings\njQuery.ajaxSetup({\n\tjsonp: \"callback\",\n\tjsonpCallback: function() {\n\t\tvar callback = oldCallbacks.pop() || ( jQuery.expando + \"_\" + ( nonce++ ) );\n\t\tthis[ callback ] = true;\n\t\treturn callback;\n\t}\n});\n\n// Detect, normalize options and install callbacks for jsonp requests\njQuery.ajaxPrefilter( \"json jsonp\", function( s, originalSettings, jqXHR ) {\n\n\tvar callbackName, overwritten, responseContainer,\n\t\tjsonProp = s.jsonp !== false && ( rjsonp.test( s.url ) ?\n\t\t\t\"url\" :\n\t\t\ttypeof s.data === \"string\" && !( s.contentType || \"\" ).indexOf(\"application/x-www-form-urlencoded\") && rjsonp.test( s.data ) && \"data\"\n\t\t);\n\n\t// Handle iff the expected data type is \"jsonp\" or we have a parameter to set\n\tif ( jsonProp || s.dataTypes[ 0 ] === \"jsonp\" ) {\n\n\t\t// Get callback name, remembering preexisting value associated with it\n\t\tcallbackName = s.jsonpCallback = jQuery.isFunction( s.jsonpCallback ) ?\n\t\t\ts.jsonpCallback() :\n\t\t\ts.jsonpCallback;\n\n\t\t// Insert callback into url or form data\n\t\tif ( jsonProp ) {\n\t\t\ts[ jsonProp ] = s[ jsonProp ].replace( rjsonp, \"$1\" + callbackName );\n\t\t} else if ( s.jsonp !== false ) {\n\t\t\ts.url += ( rquery.test( s.url ) ? \"&\" : \"?\" ) + s.jsonp + \"=\" + callbackName;\n\t\t}\n\n\t\t// Use data converter to retrieve json after script execution\n\t\ts.converters[\"script json\"] = function() {\n\t\t\tif ( !responseContainer ) {\n\t\t\t\tjQuery.error( callbackName + \" was not called\" );\n\t\t\t}\n\t\t\treturn responseContainer[ 0 ];\n\t\t};\n\n\t\t// force json dataType\n\t\ts.dataTypes[ 0 ] = \"json\";\n\n\t\t// Install callback\n\t\toverwritten = window[ callbackName ];\n\t\twindow[ callbackName ] = function() {\n\t\t\tresponseContainer = arguments;\n\t\t};\n\n\t\t// Clean-up function (fires after converters)\n\t\tjqXHR.always(function() {\n\t\t\t// Restore preexisting value\n\t\t\twindow[ callbackName ] = overwritten;\n\n\t\t\t// Save back as free\n\t\t\tif ( s[ callbackName ] ) {\n\t\t\t\t// make sure that re-using the options doesn't screw things around\n\t\t\t\ts.jsonpCallback = originalSettings.jsonpCallback;\n\n\t\t\t\t// save the callback name for future use\n\t\t\t\toldCallbacks.push( callbackName );\n\t\t\t}\n\n\t\t\t// Call if it was a function and we have a response\n\t\t\tif ( responseContainer && jQuery.isFunction( overwritten ) ) {\n\t\t\t\toverwritten( responseContainer[ 0 ] );\n\t\t\t}\n\n\t\t\tresponseContainer = overwritten = undefined;\n\t\t});\n\n\t\t// Delegate to script\n\t\treturn \"script\";\n\t}\n});\n\n\n\n\n// data: string of html\n// context (optional): If specified, the fragment will be created in this context, defaults to document\n// keepScripts (optional): If true, will include scripts passed in the html string\njQuery.parseHTML = function( data, context, keepScripts ) {\n\tif ( !data || typeof data !== \"string\" ) {\n\t\treturn null;\n\t}\n\tif ( typeof context === \"boolean\" ) {\n\t\tkeepScripts = context;\n\t\tcontext = false;\n\t}\n\tcontext = context || document;\n\n\tvar parsed = rsingleTag.exec( data ),\n\t\tscripts = !keepScripts && [];\n\n\t// Single tag\n\tif ( parsed ) {\n\t\treturn [ context.createElement( parsed[1] ) ];\n\t}\n\n\tparsed = jQuery.buildFragment( [ data ], context, scripts );\n\n\tif ( scripts && scripts.length ) {\n\t\tjQuery( scripts ).remove();\n\t}\n\n\treturn jQuery.merge( [], parsed.childNodes );\n};\n\n\n// Keep a copy of the old load method\nvar _load = jQuery.fn.load;\n\n/**\n * Load a url into a page\n */\njQuery.fn.load = function( url, params, callback ) {\n\tif ( typeof url !== \"string\" && _load ) {\n\t\treturn _load.apply( this, arguments );\n\t}\n\n\tvar selector, response, type,\n\t\tself = this,\n\t\toff = url.indexOf(\" \");\n\n\tif ( off >= 0 ) {\n\t\tselector = jQuery.trim( url.slice( off, url.length ) );\n\t\turl = url.slice( 0, off );\n\t}\n\n\t// If it's a function\n\tif ( jQuery.isFunction( params ) ) {\n\n\t\t// We assume that it's the callback\n\t\tcallback = params;\n\t\tparams = undefined;\n\n\t// Otherwise, build a param string\n\t} else if ( params && typeof params === \"object\" ) {\n\t\ttype = \"POST\";\n\t}\n\n\t// If we have elements to modify, make the request\n\tif ( self.length > 0 ) {\n\t\tjQuery.ajax({\n\t\t\turl: url,\n\n\t\t\t// if \"type\" variable is undefined, then \"GET\" method will be used\n\t\t\ttype: type,\n\t\t\tdataType: \"html\",\n\t\t\tdata: params\n\t\t}).done(function( responseText ) {\n\n\t\t\t// Save response for use in complete callback\n\t\t\tresponse = arguments;\n\n\t\t\tself.html( selector ?\n\n\t\t\t\t// If a selector was specified, locate the right elements in a dummy div\n\t\t\t\t// Exclude scripts to avoid IE 'Permission Denied' errors\n\t\t\t\tjQuery(\"<div>\").append( jQuery.parseHTML( responseText ) ).find( selector ) :\n\n\t\t\t\t// Otherwise use the full result\n\t\t\t\tresponseText );\n\n\t\t}).complete( callback && function( jqXHR, status ) {\n\t\t\tself.each( callback, response || [ jqXHR.responseText, status, jqXHR ] );\n\t\t});\n\t}\n\n\treturn this;\n};\n\n\n\n\n// Attach a bunch of functions for handling common AJAX events\njQuery.each( [ \"ajaxStart\", \"ajaxStop\", \"ajaxComplete\", \"ajaxError\", \"ajaxSuccess\", \"ajaxSend\" ], function( i, type ) {\n\tjQuery.fn[ type ] = function( fn ) {\n\t\treturn this.on( type, fn );\n\t};\n});\n\n\n\n\njQuery.expr.filters.animated = function( elem ) {\n\treturn jQuery.grep(jQuery.timers, function( fn ) {\n\t\treturn elem === fn.elem;\n\t}).length;\n};\n\n\n\n\n\nvar docElem = window.document.documentElement;\n\n/**\n * Gets a window from an element\n */\nfunction getWindow( elem ) {\n\treturn jQuery.isWindow( elem ) ?\n\t\telem :\n\t\telem.nodeType === 9 ?\n\t\t\telem.defaultView || elem.parentWindow :\n\t\t\tfalse;\n}\n\njQuery.offset = {\n\tsetOffset: function( elem, options, i ) {\n\t\tvar curPosition, curLeft, curCSSTop, curTop, curOffset, curCSSLeft, calculatePosition,\n\t\t\tposition = jQuery.css( elem, \"position\" ),\n\t\t\tcurElem = jQuery( elem ),\n\t\t\tprops = {};\n\n\t\t// set position first, in-case top/left are set even on static elem\n\t\tif ( position === \"static\" ) {\n\t\t\telem.style.position = \"relative\";\n\t\t}\n\n\t\tcurOffset = curElem.offset();\n\t\tcurCSSTop = jQuery.css( elem, \"top\" );\n\t\tcurCSSLeft = jQuery.css( elem, \"left\" );\n\t\tcalculatePosition = ( position === \"absolute\" || position === \"fixed\" ) &&\n\t\t\tjQuery.inArray(\"auto\", [ curCSSTop, curCSSLeft ] ) > -1;\n\n\t\t// need to be able to calculate position if either top or left is auto and position is either absolute or fixed\n\t\tif ( calculatePosition ) {\n\t\t\tcurPosition = curElem.position();\n\t\t\tcurTop = curPosition.top;\n\t\t\tcurLeft = curPosition.left;\n\t\t} else {\n\t\t\tcurTop = parseFloat( curCSSTop ) || 0;\n\t\t\tcurLeft = parseFloat( curCSSLeft ) || 0;\n\t\t}\n\n\t\tif ( jQuery.isFunction( options ) ) {\n\t\t\toptions = options.call( elem, i, curOffset );\n\t\t}\n\n\t\tif ( options.top != null ) {\n\t\t\tprops.top = ( options.top - curOffset.top ) + curTop;\n\t\t}\n\t\tif ( options.left != null ) {\n\t\t\tprops.left = ( options.left - curOffset.left ) + curLeft;\n\t\t}\n\n\t\tif ( \"using\" in options ) {\n\t\t\toptions.using.call( elem, props );\n\t\t} else {\n\t\t\tcurElem.css( props );\n\t\t}\n\t}\n};\n\njQuery.fn.extend({\n\toffset: function( options ) {\n\t\tif ( arguments.length ) {\n\t\t\treturn options === undefined ?\n\t\t\t\tthis :\n\t\t\t\tthis.each(function( i ) {\n\t\t\t\t\tjQuery.offset.setOffset( this, options, i );\n\t\t\t\t});\n\t\t}\n\n\t\tvar docElem, win,\n\t\t\tbox = { top: 0, left: 0 },\n\t\t\telem = this[ 0 ],\n\t\t\tdoc = elem && elem.ownerDocument;\n\n\t\tif ( !doc ) {\n\t\t\treturn;\n\t\t}\n\n\t\tdocElem = doc.documentElement;\n\n\t\t// Make sure it's not a disconnected DOM node\n\t\tif ( !jQuery.contains( docElem, elem ) ) {\n\t\t\treturn box;\n\t\t}\n\n\t\t// If we don't have gBCR, just use 0,0 rather than error\n\t\t// BlackBerry 5, iOS 3 (original iPhone)\n\t\tif ( typeof elem.getBoundingClientRect !== strundefined ) {\n\t\t\tbox = elem.getBoundingClientRect();\n\t\t}\n\t\twin = getWindow( doc );\n\t\treturn {\n\t\t\ttop: box.top  + ( win.pageYOffset || docElem.scrollTop )  - ( docElem.clientTop  || 0 ),\n\t\t\tleft: box.left + ( win.pageXOffset || docElem.scrollLeft ) - ( docElem.clientLeft || 0 )\n\t\t};\n\t},\n\n\tposition: function() {\n\t\tif ( !this[ 0 ] ) {\n\t\t\treturn;\n\t\t}\n\n\t\tvar offsetParent, offset,\n\t\t\tparentOffset = { top: 0, left: 0 },\n\t\t\telem = this[ 0 ];\n\n\t\t// fixed elements are offset from window (parentOffset = {top:0, left: 0}, because it is its only offset parent\n\t\tif ( jQuery.css( elem, \"position\" ) === \"fixed\" ) {\n\t\t\t// we assume that getBoundingClientRect is available when computed position is fixed\n\t\t\toffset = elem.getBoundingClientRect();\n\t\t} else {\n\t\t\t// Get *real* offsetParent\n\t\t\toffsetParent = this.offsetParent();\n\n\t\t\t// Get correct offsets\n\t\t\toffset = this.offset();\n\t\t\tif ( !jQuery.nodeName( offsetParent[ 0 ], \"html\" ) ) {\n\t\t\t\tparentOffset = offsetParent.offset();\n\t\t\t}\n\n\t\t\t// Add offsetParent borders\n\t\t\tparentOffset.top  += jQuery.css( offsetParent[ 0 ], \"borderTopWidth\", true );\n\t\t\tparentOffset.left += jQuery.css( offsetParent[ 0 ], \"borderLeftWidth\", true );\n\t\t}\n\n\t\t// Subtract parent offsets and element margins\n\t\t// note: when an element has margin: auto the offsetLeft and marginLeft\n\t\t// are the same in Safari causing offset.left to incorrectly be 0\n\t\treturn {\n\t\t\ttop:  offset.top  - parentOffset.top - jQuery.css( elem, \"marginTop\", true ),\n\t\t\tleft: offset.left - parentOffset.left - jQuery.css( elem, \"marginLeft\", true)\n\t\t};\n\t},\n\n\toffsetParent: function() {\n\t\treturn this.map(function() {\n\t\t\tvar offsetParent = this.offsetParent || docElem;\n\n\t\t\twhile ( offsetParent && ( !jQuery.nodeName( offsetParent, \"html\" ) && jQuery.css( offsetParent, \"position\" ) === \"static\" ) ) {\n\t\t\t\toffsetParent = offsetParent.offsetParent;\n\t\t\t}\n\t\t\treturn offsetParent || docElem;\n\t\t});\n\t}\n});\n\n// Create scrollLeft and scrollTop methods\njQuery.each( { scrollLeft: \"pageXOffset\", scrollTop: \"pageYOffset\" }, function( method, prop ) {\n\tvar top = /Y/.test( prop );\n\n\tjQuery.fn[ method ] = function( val ) {\n\t\treturn access( this, function( elem, method, val ) {\n\t\t\tvar win = getWindow( elem );\n\n\t\t\tif ( val === undefined ) {\n\t\t\t\treturn win ? (prop in win) ? win[ prop ] :\n\t\t\t\t\twin.document.documentElement[ method ] :\n\t\t\t\t\telem[ method ];\n\t\t\t}\n\n\t\t\tif ( win ) {\n\t\t\t\twin.scrollTo(\n\t\t\t\t\t!top ? val : jQuery( win ).scrollLeft(),\n\t\t\t\t\ttop ? val : jQuery( win ).scrollTop()\n\t\t\t\t);\n\n\t\t\t} else {\n\t\t\t\telem[ method ] = val;\n\t\t\t}\n\t\t}, method, val, arguments.length, null );\n\t};\n});\n\n// Add the top/left cssHooks using jQuery.fn.position\n// Webkit bug: https://bugs.webkit.org/show_bug.cgi?id=29084\n// getComputedStyle returns percent when specified for top/left/bottom/right\n// rather than make the css module depend on the offset module, we just check for it here\njQuery.each( [ \"top\", \"left\" ], function( i, prop ) {\n\tjQuery.cssHooks[ prop ] = addGetHookIf( support.pixelPosition,\n\t\tfunction( elem, computed ) {\n\t\t\tif ( computed ) {\n\t\t\t\tcomputed = curCSS( elem, prop );\n\t\t\t\t// if curCSS returns percentage, fallback to offset\n\t\t\t\treturn rnumnonpx.test( computed ) ?\n\t\t\t\t\tjQuery( elem ).position()[ prop ] + \"px\" :\n\t\t\t\t\tcomputed;\n\t\t\t}\n\t\t}\n\t);\n});\n\n\n// Create innerHeight, innerWidth, height, width, outerHeight and outerWidth methods\njQuery.each( { Height: \"height\", Width: \"width\" }, function( name, type ) {\n\tjQuery.each( { padding: \"inner\" + name, content: type, \"\": \"outer\" + name }, function( defaultExtra, funcName ) {\n\t\t// margin is only for outerHeight, outerWidth\n\t\tjQuery.fn[ funcName ] = function( margin, value ) {\n\t\t\tvar chainable = arguments.length && ( defaultExtra || typeof margin !== \"boolean\" ),\n\t\t\t\textra = defaultExtra || ( margin === true || value === true ? \"margin\" : \"border\" );\n\n\t\t\treturn access( this, function( elem, type, value ) {\n\t\t\t\tvar doc;\n\n\t\t\t\tif ( jQuery.isWindow( elem ) ) {\n\t\t\t\t\t// As of 5/8/2012 this will yield incorrect results for Mobile Safari, but there\n\t\t\t\t\t// isn't a whole lot we can do. See pull request at this URL for discussion:\n\t\t\t\t\t// https://github.com/jquery/jquery/pull/764\n\t\t\t\t\treturn elem.document.documentElement[ \"client\" + name ];\n\t\t\t\t}\n\n\t\t\t\t// Get document width or height\n\t\t\t\tif ( elem.nodeType === 9 ) {\n\t\t\t\t\tdoc = elem.documentElement;\n\n\t\t\t\t\t// Either scroll[Width/Height] or offset[Width/Height] or client[Width/Height], whichever is greatest\n\t\t\t\t\t// unfortunately, this causes bug #3838 in IE6/8 only, but there is currently no good, small way to fix it.\n\t\t\t\t\treturn Math.max(\n\t\t\t\t\t\telem.body[ \"scroll\" + name ], doc[ \"scroll\" + name ],\n\t\t\t\t\t\telem.body[ \"offset\" + name ], doc[ \"offset\" + name ],\n\t\t\t\t\t\tdoc[ \"client\" + name ]\n\t\t\t\t\t);\n\t\t\t\t}\n\n\t\t\t\treturn value === undefined ?\n\t\t\t\t\t// Get width or height on the element, requesting but not forcing parseFloat\n\t\t\t\t\tjQuery.css( elem, type, extra ) :\n\n\t\t\t\t\t// Set width or height on the element\n\t\t\t\t\tjQuery.style( elem, type, value, extra );\n\t\t\t}, type, chainable ? margin : undefined, chainable, null );\n\t\t};\n\t});\n});\n\n\n// The number of elements contained in the matched element set\njQuery.fn.size = function() {\n\treturn this.length;\n};\n\njQuery.fn.andSelf = jQuery.fn.addBack;\n\n\n\n\n// Register as a named AMD module, since jQuery can be concatenated with other\n// files that may use define, but not via a proper concatenation script that\n// understands anonymous AMD modules. A named AMD is safest and most robust\n// way to register. Lowercase jquery is used because AMD module names are\n// derived from file names, and jQuery is normally delivered in a lowercase\n// file name. Do this after creating the global so that if an AMD module wants\n// to call noConflict to hide this version of jQuery, it will work.\n\n// Note that for maximum portability, libraries that are not jQuery should\n// declare themselves as anonymous modules, and avoid setting a global if an\n// AMD loader is present. jQuery is a special case. For more information, see\n// https://github.com/jrburke/requirejs/wiki/Updating-existing-libraries#wiki-anon\n\nif ( typeof define === \"function\" && define.amd ) {\n\tdefine( \"jquery\", [], function() {\n\t\treturn jQuery;\n\t});\n}\n\n\n\n\nvar\n\t// Map over jQuery in case of overwrite\n\t_jQuery = window.jQuery,\n\n\t// Map over the $ in case of overwrite\n\t_$ = window.$;\n\njQuery.noConflict = function( deep ) {\n\tif ( window.$ === jQuery ) {\n\t\twindow.$ = _$;\n\t}\n\n\tif ( deep && window.jQuery === jQuery ) {\n\t\twindow.jQuery = _jQuery;\n\t}\n\n\treturn jQuery;\n};\n\n// Expose jQuery and $ identifiers, even in\n// AMD (#7102#comment:10, https://github.com/jquery/jquery/pull/557)\n// and CommonJS for browser emulators (#13566)\nif ( typeof noGlobal === strundefined ) {\n\twindow.jQuery = window.$ = jQuery;\n}\n\n\n\n\nreturn jQuery;\n\n}));\n"
  },
  {
    "path": "app_frontend/static/plugin/Gallery-2.25.0/package.json",
    "content": "{\n  \"name\": \"blueimp-gallery\",\n  \"version\": \"2.25.0\",\n  \"title\": \"blueimp Gallery\",\n  \"description\": \"blueimp Gallery is a touch-enabled, responsive and customizable image and video gallery, carousel and lightbox, optimized for both mobile and desktop web browsers. It features swipe, mouse and keyboard navigation, transition effects, slideshow functionality, fullscreen support and on-demand content loading and can be extended to display additional content types.\",\n  \"keywords\": [\n    \"image\",\n    \"video\",\n    \"gallery\",\n    \"carousel\",\n    \"lightbox\",\n    \"mobile\",\n    \"desktop\",\n    \"touch\",\n    \"responsive\",\n    \"swipe\",\n    \"mouse\",\n    \"keyboard\",\n    \"navigation\",\n    \"transition\",\n    \"effects\",\n    \"slideshow\",\n    \"fullscreen\"\n  ],\n  \"homepage\": \"https://github.com/blueimp/Gallery\",\n  \"author\": {\n    \"name\": \"Sebastian Tschan\",\n    \"url\": \"https://blueimp.net\"\n  },\n  \"repository\": {\n    \"type\": \"git\",\n    \"url\": \"git://github.com/blueimp/Gallery.git\"\n  },\n  \"license\": \"MIT\",\n  \"devDependencies\": {\n    \"clean-css\": \"3.4.21\",\n    \"standard\": \"8.6.0\",\n    \"uglify-js\": \"2.7.4\"\n  },\n  \"scripts\": {\n    \"test\": \"standard js/*.js\",\n    \"build:js\": \"cd js && uglifyjs blueimp-helper.js blueimp-gallery.js blueimp-gallery-fullscreen.js blueimp-gallery-indicator.js blueimp-gallery-video.js blueimp-gallery-vimeo.js blueimp-gallery-youtube.js -c -m -o blueimp-gallery.min.js --source-map blueimp-gallery.min.js.map\",\n    \"build:jquery\": \"cd js && uglifyjs blueimp-gallery.js blueimp-gallery-fullscreen.js blueimp-gallery-indicator.js blueimp-gallery-video.js blueimp-gallery-vimeo.js blueimp-gallery-youtube.js jquery.blueimp-gallery.js -c -m -o jquery.blueimp-gallery.min.js --source-map jquery.blueimp-gallery.min.js.map\",\n    \"build:css\": \"cd css && cleancss -c ie7 --source-map -o blueimp-gallery.min.css blueimp-gallery.css blueimp-gallery-indicator.css blueimp-gallery-video.css\",\n    \"build\": \"npm run build:js && npm run build:jquery && npm run build:css\",\n    \"preversion\": \"npm test\",\n    \"version\": \"npm run build && git add -A js css\",\n    \"postversion\": \"git push --tags origin master master:gh-pages && npm publish\"\n  },\n  \"main\": \"js/blueimp-gallery.js\"\n}\n"
  },
  {
    "path": "app_frontend/static/plugin/JavaScript-Canvas-to-Blob-3.7.0/.gitignore",
    "content": ".DS_Store\nnode_modules\n"
  },
  {
    "path": "app_frontend/static/plugin/JavaScript-Canvas-to-Blob-3.7.0/.npmignore",
    "content": "*\n!js/*.js\n!js/*.js.map\n"
  },
  {
    "path": "app_frontend/static/plugin/JavaScript-Canvas-to-Blob-3.7.0/.travis.yml",
    "content": "language: node_js\nnode_js:\n  - \"stable\"\n"
  },
  {
    "path": "app_frontend/static/plugin/JavaScript-Canvas-to-Blob-3.7.0/README.md",
    "content": "# JavaScript Canvas to Blob\n\n## Description\nCanvas to Blob is a polyfill for the standard JavaScript\n[canvas.toBlob](http://www.w3.org/TR/html5/scripting-1.html#dom-canvas-toblob)\nmethod.\n\nIt can be used to create\n[Blob](https://developer.mozilla.org/en-US/docs/Web/API/Blob)\nobjects from an HTML\n[canvas](https://developer.mozilla.org/en-US/docs/HTML/Canvas) element.\n\n## Usage\nInclude the (minified) JavaScript Canvas to Blob script in your HTML markup:\n\n```html\n<script src=\"js/canvas-to-blob.min.js\"></script>\n```\n\nThen use the *canvas.toBlob()* method in the same way as the native\nimplementation:\n\n```js\nvar canvas = document.createElement('canvas');\n/* ... your canvas manipulations ... */\nif (canvas.toBlob) {\n    canvas.toBlob(\n        function (blob) {\n            // Do something with the blob object,\n            // e.g. creating a multipart form for file uploads:\n            var formData = new FormData();\n            formData.append('file', blob, fileName);\n            /* ... */\n        },\n        'image/jpeg'\n    );\n}\n```\n\n## Requirements\nThe JavaScript Canvas to Blob function has zero dependencies.\n\nHowever, Canvas to Blob is a very suitable complement to the\n[JavaScript Load Image](https://github.com/blueimp/JavaScript-Load-Image)\nfunction.\n\n## API\nIn addition to the **canvas.toBlob** polyfill, the JavaScript Canvas to Blob\nscript provides one additional function called **dataURLtoBlob**, which is added\nto the global window object, unless the library is loaded via a module loader\nlike RequireJS, Browserify or webpack:\n\n```js\n// 80x60px GIF image (color black, base64 data):\nvar b64Data = 'R0lGODdhUAA8AIABAAAAAP///ywAAAAAUAA8AAACS4SPqcvtD6' +\n        'OctNqLs968+w+G4kiW5omm6sq27gvH8kzX9o3n+s73/g8MCofE' +\n        'ovGITCqXzKbzCY1Kp9Sq9YrNarfcrvcLDovH5PKsAAA7',\n    imageUrl = 'data:image/gif;base64,' + b64Data,\n    blob = window.dataURLtoBlob && window.dataURLtoBlob(imageUrl);\n```\n\n## Browsers\nThe following browsers support either the native or the polyfill\n*canvas.toBlob()* method:\n\n### Desktop browsers\n\n* Google Chrome (see [Chromium issue #67587](https://code.google.com/p/chromium/issues/detail?id=67587))\n* Apple Safari 6.0+ (see [Mozilla issue #648610](https://bugzilla.mozilla.org/show_bug.cgi?id=648610))\n* Mozilla Firefox 4.0+\n* Microsoft Internet Explorer 10.0+\n\n### Mobile browsers\n\n* Apple Safari Mobile on iOS 6.0+\n* Google Chrome on iOS 6.0+\n* Google Chrome on Android 4.0+\n\n## Test\n[JavaScript Canvas to Blob Test](https://blueimp.github.io/JavaScript-Canvas-to-Blob/test/)\n\n## License\nThe JavaScript Canvas to Blob script is released under the\n[MIT license](https://opensource.org/licenses/MIT).\n"
  },
  {
    "path": "app_frontend/static/plugin/JavaScript-Canvas-to-Blob-3.7.0/js/canvas-to-blob.js",
    "content": "/*\n * JavaScript Canvas to Blob\n * https://github.com/blueimp/JavaScript-Canvas-to-Blob\n *\n * Copyright 2012, Sebastian Tschan\n * https://blueimp.net\n *\n * Licensed under the MIT license:\n * https://opensource.org/licenses/MIT\n *\n * Based on stackoverflow user Stoive's code snippet:\n * http://stackoverflow.com/q/4998908\n */\n\n/* global atob, Blob, define */\n\n;(function (window) {\n  'use strict'\n\n  var CanvasPrototype = window.HTMLCanvasElement &&\n                          window.HTMLCanvasElement.prototype\n  var hasBlobConstructor = window.Blob && (function () {\n    try {\n      return Boolean(new Blob())\n    } catch (e) {\n      return false\n    }\n  }())\n  var hasArrayBufferViewSupport = hasBlobConstructor && window.Uint8Array &&\n    (function () {\n      try {\n        return new Blob([new Uint8Array(100)]).size === 100\n      } catch (e) {\n        return false\n      }\n    }())\n  var BlobBuilder = window.BlobBuilder || window.WebKitBlobBuilder ||\n                      window.MozBlobBuilder || window.MSBlobBuilder\n  var dataURIPattern = /^data:((.*?)(;charset=.*?)?)(;base64)?,/\n  var dataURLtoBlob = (hasBlobConstructor || BlobBuilder) && window.atob &&\n    window.ArrayBuffer && window.Uint8Array &&\n    function (dataURI) {\n      var matches,\n        mediaType,\n        isBase64,\n        dataString,\n        byteString,\n        arrayBuffer,\n        intArray,\n        i,\n        bb\n      // Parse the dataURI components as per RFC 2397\n      matches = dataURI.match(dataURIPattern)\n      if (!matches) {\n        throw new Error('invalid data URI')\n      }\n      // Default to text/plain;charset=US-ASCII\n      mediaType = matches[2]\n        ? matches[1]\n        : 'text/plain' + (matches[3] || ';charset=US-ASCII')\n      isBase64 = !!matches[4]\n      dataString = dataURI.slice(matches[0].length)\n      if (isBase64) {\n        // Convert base64 to raw binary data held in a string:\n        byteString = atob(dataString)\n      } else {\n        // Convert base64/URLEncoded data component to raw binary:\n        byteString = decodeURIComponent(dataString)\n      }\n      // Write the bytes of the string to an ArrayBuffer:\n      arrayBuffer = new ArrayBuffer(byteString.length)\n      intArray = new Uint8Array(arrayBuffer)\n      for (i = 0; i < byteString.length; i += 1) {\n        intArray[i] = byteString.charCodeAt(i)\n      }\n      // Write the ArrayBuffer (or ArrayBufferView) to a blob:\n      if (hasBlobConstructor) {\n        return new Blob(\n          [hasArrayBufferViewSupport ? intArray : arrayBuffer],\n          {type: mediaType}\n        )\n      }\n      bb = new BlobBuilder()\n      bb.append(arrayBuffer)\n      return bb.getBlob(mediaType)\n    }\n  if (window.HTMLCanvasElement && !CanvasPrototype.toBlob) {\n    if (CanvasPrototype.mozGetAsFile) {\n      CanvasPrototype.toBlob = function (callback, type, quality) {\n        if (quality && CanvasPrototype.toDataURL && dataURLtoBlob) {\n          callback(dataURLtoBlob(this.toDataURL(type, quality)))\n        } else {\n          callback(this.mozGetAsFile('blob', type))\n        }\n      }\n    } else if (CanvasPrototype.toDataURL && dataURLtoBlob) {\n      CanvasPrototype.toBlob = function (callback, type, quality) {\n        callback(dataURLtoBlob(this.toDataURL(type, quality)))\n      }\n    }\n  }\n  if (typeof define === 'function' && define.amd) {\n    define(function () {\n      return dataURLtoBlob\n    })\n  } else if (typeof module === 'object' && module.exports) {\n    module.exports = dataURLtoBlob\n  } else {\n    window.dataURLtoBlob = dataURLtoBlob\n  }\n}(window))\n"
  },
  {
    "path": "app_frontend/static/plugin/JavaScript-Canvas-to-Blob-3.7.0/package.json",
    "content": "{\n  \"name\": \"blueimp-canvas-to-blob\",\n  \"version\": \"3.7.0\",\n  \"title\": \"JavaScript Canvas to Blob\",\n  \"description\": \"Canvas to Blob is a polyfill for the standard JavaScript canvas.toBlob method. It can be used to create Blob objects from an HTML canvas element.\",\n  \"keywords\": [\n    \"javascript\",\n    \"canvas\",\n    \"blob\",\n    \"convert\",\n    \"conversion\"\n  ],\n  \"homepage\": \"https://github.com/blueimp/JavaScript-Canvas-to-Blob\",\n  \"author\": {\n    \"name\": \"Sebastian Tschan\",\n    \"url\": \"https://blueimp.net\"\n  },\n  \"repository\": {\n    \"type\": \"git\",\n    \"url\": \"git://github.com/blueimp/JavaScript-Canvas-to-Blob.git\"\n  },\n  \"license\": \"MIT\",\n  \"main\": \"./js/canvas-to-blob.js\",\n  \"devDependencies\": {\n    \"phantomjs-prebuilt\": \"2.1.13\",\n    \"mocha-phantomjs-core\": \"1.3.1\",\n    \"standard\": \"8.3.0\",\n    \"uglify-js\": \"2.7.3\"\n  },\n  \"scripts\": {\n    \"lint\": \"standard js/*.js test/*.js\",\n    \"unit\": \"phantomjs node_modules/mocha-phantomjs-core/mocha-phantomjs-core.js test/index.html\",\n    \"test\": \"npm run lint && npm run unit\",\n    \"build\": \"cd js && uglifyjs canvas-to-blob.js -c -m -o canvas-to-blob.min.js --source-map canvas-to-blob.min.js.map\",\n    \"preversion\": \"npm test\",\n    \"version\": \"npm run build && git add -A js\",\n    \"postversion\": \"git push --tags origin master master:gh-pages && npm publish\"\n  }\n}\n"
  },
  {
    "path": "app_frontend/static/plugin/JavaScript-Canvas-to-Blob-3.7.0/test/index.html",
    "content": "<!DOCTYPE HTML>\n<!--\n/*\n * JavaScript Canvas to Blob Test\n * https://github.com/blueimp/JavaScript-Canvas-to-Blob\n *\n * Copyright 2012, Sebastian Tschan\n * https://blueimp.net\n *\n * Licensed under the MIT license:\n * https://opensource.org/licenses/MIT\n */\n-->\n<html lang=\"en\">\n<head>\n<!--[if IE]>\n<meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge,chrome=1\">\n<![endif]-->\n<meta charset=\"utf-8\">\n<title>JavaScript Canvas to Blob Test</title>\n<meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n<link rel=\"stylesheet\" href=\"vendor/mocha.css\">\n</head>\n<body>\n<div id=\"mocha\"></div>\n<script src=\"vendor/mocha.js\"></script>\n<script src=\"vendor/chai.js\"></script>\n<script>\nwindow.initMochaPhantomJS && initMochaPhantomJS();\nmocha.setup('bdd');\n</script>\n<script src=\"vendor/load-image.js\"></script>\n<script src=\"../js/canvas-to-blob.js\"></script>\n<script src=\"test.js\"></script>\n<script>\nmocha.checkLeaks();\nmocha.run();\n</script>\n</body>\n</html>\n"
  },
  {
    "path": "app_frontend/static/plugin/JavaScript-Canvas-to-Blob-3.7.0/test/test.js",
    "content": "/*\n * JavaScript Canvas to Blob Test\n * https://github.com/blueimp/JavaScript-Canvas-to-Blob\n *\n * Copyright 2012, Sebastian Tschan\n * https://blueimp.net\n *\n * Licensed under the MIT license:\n * https://opensource.org/licenses/MIT\n */\n\n/* global describe, it, Blob */\n\n;(function (expect) {\n  'use strict'\n\n  // 80x60px GIF image (color black, base64 data):\n  var b64Data = 'R0lGODdhUAA8AIABAAAAAP///ywAAAAAUAA8AAACS4SPqcvtD6' +\n      'OctNqLs968+w+G4kiW5omm6sq27gvH8kzX9o3n+s73/g8MCofE' +\n      'ovGITCqXzKbzCY1Kp9Sq9YrNarfcrvcLDovH5PKsAAA7'\n  var imageUrl = 'data:image/gif;base64,' + b64Data\n  var blob = window.dataURLtoBlob && window.dataURLtoBlob(imageUrl)\n\n  describe('canvas.toBlob', function () {\n    it('Converts a canvas element to a blob and passes it to the callback function', function (done) {\n      window.loadImage(blob, function (canvas) {\n        canvas.toBlob(\n          function (newBlob) {\n            expect(newBlob).to.be.a.instanceOf(Blob)\n            done()\n          }\n        )\n      }, {canvas: true})\n    })\n\n    it('Converts a canvas element to a PNG blob', function (done) {\n      window.loadImage(blob, function (canvas) {\n        canvas.toBlob(\n          function (newBlob) {\n            expect(newBlob.type).to.equal('image/png')\n            done()\n          },\n          'image/png'\n        )\n      }, {canvas: true})\n    })\n\n    it('Converts a canvas element to a JPG blob', function (done) {\n      window.loadImage(blob, function (canvas) {\n        canvas.toBlob(\n          function (newBlob) {\n            expect(newBlob.type).to.equal('image/jpeg')\n            done()\n          },\n          'image/jpeg'\n        )\n      }, {canvas: true})\n    })\n\n    it('Keeps the aspect ratio of the canvas image', function (done) {\n      window.loadImage(blob, function (canvas) {\n        canvas.toBlob(\n          function (newBlob) {\n            window.loadImage(newBlob, function (img) {\n              expect(img.width).to.equal(canvas.width)\n              expect(img.height).to.equal(canvas.height)\n              done()\n            })\n          }\n        )\n      }, {canvas: true})\n    })\n\n    it('Keeps the image data of the canvas image', function (done) {\n      window.loadImage(blob, function (canvas) {\n        canvas.toBlob(\n          function (newBlob) {\n            window.loadImage(newBlob, function (newCanvas) {\n              var canvasData = canvas.getContext('2d')\n                  .getImageData(0, 0, canvas.width, canvas.height)\n              var newCanvasData = newCanvas.getContext('2d')\n                  .getImageData(0, 0, newCanvas.width, newCanvas.height)\n              expect(canvasData.width).to.equal(newCanvasData.width)\n              expect(canvasData.height).to.equal(newCanvasData.height)\n              done()\n            }, {canvas: true})\n          }\n        )\n      }, {canvas: true})\n    })\n  })\n}(this.chai.expect))\n"
  },
  {
    "path": "app_frontend/static/plugin/JavaScript-Canvas-to-Blob-3.7.0/test/vendor/chai.js",
    "content": "(function(f){if(typeof exports===\"object\"&&typeof module!==\"undefined\"){module.exports=f()}else if(typeof define===\"function\"&&define.amd){define([],f)}else{var g;if(typeof window!==\"undefined\"){g=window}else if(typeof global!==\"undefined\"){g=global}else if(typeof self!==\"undefined\"){g=self}else{g=this}g.chai = f()}})(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require==\"function\"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error(\"Cannot find module '\"+o+\"'\");throw f.code=\"MODULE_NOT_FOUND\",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require==\"function\"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){\nmodule.exports = require('./lib/chai');\n\n},{\"./lib/chai\":2}],2:[function(require,module,exports){\n/*!\n * chai\n * Copyright(c) 2011-2014 Jake Luer <jake@alogicalparadox.com>\n * MIT Licensed\n */\n\nvar used = []\n  , exports = module.exports = {};\n\n/*!\n * Chai version\n */\n\nexports.version = '3.5.0';\n\n/*!\n * Assertion Error\n */\n\nexports.AssertionError = require('assertion-error');\n\n/*!\n * Utils for plugins (not exported)\n */\n\nvar util = require('./chai/utils');\n\n/**\n * # .use(function)\n *\n * Provides a way to extend the internals of Chai\n *\n * @param {Function}\n * @returns {this} for chaining\n * @api public\n */\n\nexports.use = function (fn) {\n  if (!~used.indexOf(fn)) {\n    fn(this, util);\n    used.push(fn);\n  }\n\n  return this;\n};\n\n/*!\n * Utility Functions\n */\n\nexports.util = util;\n\n/*!\n * Configuration\n */\n\nvar config = require('./chai/config');\nexports.config = config;\n\n/*!\n * Primary `Assertion` prototype\n */\n\nvar assertion = require('./chai/assertion');\nexports.use(assertion);\n\n/*!\n * Core Assertions\n */\n\nvar core = require('./chai/core/assertions');\nexports.use(core);\n\n/*!\n * Expect interface\n */\n\nvar expect = require('./chai/interface/expect');\nexports.use(expect);\n\n/*!\n * Should interface\n */\n\nvar should = require('./chai/interface/should');\nexports.use(should);\n\n/*!\n * Assert interface\n */\n\nvar assert = require('./chai/interface/assert');\nexports.use(assert);\n\n},{\"./chai/assertion\":3,\"./chai/config\":4,\"./chai/core/assertions\":5,\"./chai/interface/assert\":6,\"./chai/interface/expect\":7,\"./chai/interface/should\":8,\"./chai/utils\":22,\"assertion-error\":30}],3:[function(require,module,exports){\n/*!\n * chai\n * http://chaijs.com\n * Copyright(c) 2011-2014 Jake Luer <jake@alogicalparadox.com>\n * MIT Licensed\n */\n\nvar config = require('./config');\n\nmodule.exports = function (_chai, util) {\n  /*!\n   * Module dependencies.\n   */\n\n  var AssertionError = _chai.AssertionError\n    , flag = util.flag;\n\n  /*!\n   * Module export.\n   */\n\n  _chai.Assertion = Assertion;\n\n  /*!\n   * Assertion Constructor\n   *\n   * Creates object for chaining.\n   *\n   * @api private\n   */\n\n  function Assertion (obj, msg, stack) {\n    flag(this, 'ssfi', stack || arguments.callee);\n    flag(this, 'object', obj);\n    flag(this, 'message', msg);\n  }\n\n  Object.defineProperty(Assertion, 'includeStack', {\n    get: function() {\n      console.warn('Assertion.includeStack is deprecated, use chai.config.includeStack instead.');\n      return config.includeStack;\n    },\n    set: function(value) {\n      console.warn('Assertion.includeStack is deprecated, use chai.config.includeStack instead.');\n      config.includeStack = value;\n    }\n  });\n\n  Object.defineProperty(Assertion, 'showDiff', {\n    get: function() {\n      console.warn('Assertion.showDiff is deprecated, use chai.config.showDiff instead.');\n      return config.showDiff;\n    },\n    set: function(value) {\n      console.warn('Assertion.showDiff is deprecated, use chai.config.showDiff instead.');\n      config.showDiff = value;\n    }\n  });\n\n  Assertion.addProperty = function (name, fn) {\n    util.addProperty(this.prototype, name, fn);\n  };\n\n  Assertion.addMethod = function (name, fn) {\n    util.addMethod(this.prototype, name, fn);\n  };\n\n  Assertion.addChainableMethod = function (name, fn, chainingBehavior) {\n    util.addChainableMethod(this.prototype, name, fn, chainingBehavior);\n  };\n\n  Assertion.overwriteProperty = function (name, fn) {\n    util.overwriteProperty(this.prototype, name, fn);\n  };\n\n  Assertion.overwriteMethod = function (name, fn) {\n    util.overwriteMethod(this.prototype, name, fn);\n  };\n\n  Assertion.overwriteChainableMethod = function (name, fn, chainingBehavior) {\n    util.overwriteChainableMethod(this.prototype, name, fn, chainingBehavior);\n  };\n\n  /**\n   * ### .assert(expression, message, negateMessage, expected, actual, showDiff)\n   *\n   * Executes an expression and check expectations. Throws AssertionError for reporting if test doesn't pass.\n   *\n   * @name assert\n   * @param {Philosophical} expression to be tested\n   * @param {String|Function} message or function that returns message to display if expression fails\n   * @param {String|Function} negatedMessage or function that returns negatedMessage to display if negated expression fails\n   * @param {Mixed} expected value (remember to check for negation)\n   * @param {Mixed} actual (optional) will default to `this.obj`\n   * @param {Boolean} showDiff (optional) when set to `true`, assert will display a diff in addition to the message if expression fails\n   * @api private\n   */\n\n  Assertion.prototype.assert = function (expr, msg, negateMsg, expected, _actual, showDiff) {\n    var ok = util.test(this, arguments);\n    if (true !== showDiff) showDiff = false;\n    if (true !== config.showDiff) showDiff = false;\n\n    if (!ok) {\n      var msg = util.getMessage(this, arguments)\n        , actual = util.getActual(this, arguments);\n      throw new AssertionError(msg, {\n          actual: actual\n        , expected: expected\n        , showDiff: showDiff\n      }, (config.includeStack) ? this.assert : flag(this, 'ssfi'));\n    }\n  };\n\n  /*!\n   * ### ._obj\n   *\n   * Quick reference to stored `actual` value for plugin developers.\n   *\n   * @api private\n   */\n\n  Object.defineProperty(Assertion.prototype, '_obj',\n    { get: function () {\n        return flag(this, 'object');\n      }\n    , set: function (val) {\n        flag(this, 'object', val);\n      }\n  });\n};\n\n},{\"./config\":4}],4:[function(require,module,exports){\nmodule.exports = {\n\n  /**\n   * ### config.includeStack\n   *\n   * User configurable property, influences whether stack trace\n   * is included in Assertion error message. Default of false\n   * suppresses stack trace in the error message.\n   *\n   *     chai.config.includeStack = true;  // enable stack on error\n   *\n   * @param {Boolean}\n   * @api public\n   */\n\n   includeStack: false,\n\n  /**\n   * ### config.showDiff\n   *\n   * User configurable property, influences whether or not\n   * the `showDiff` flag should be included in the thrown\n   * AssertionErrors. `false` will always be `false`; `true`\n   * will be true when the assertion has requested a diff\n   * be shown.\n   *\n   * @param {Boolean}\n   * @api public\n   */\n\n  showDiff: true,\n\n  /**\n   * ### config.truncateThreshold\n   *\n   * User configurable property, sets length threshold for actual and\n   * expected values in assertion errors. If this threshold is exceeded, for\n   * example for large data structures, the value is replaced with something\n   * like `[ Array(3) ]` or `{ Object (prop1, prop2) }`.\n   *\n   * Set it to zero if you want to disable truncating altogether.\n   *\n   * This is especially userful when doing assertions on arrays: having this\n   * set to a reasonable large value makes the failure messages readily\n   * inspectable.\n   *\n   *     chai.config.truncateThreshold = 0;  // disable truncating\n   *\n   * @param {Number}\n   * @api public\n   */\n\n  truncateThreshold: 40\n\n};\n\n},{}],5:[function(require,module,exports){\n/*!\n * chai\n * http://chaijs.com\n * Copyright(c) 2011-2014 Jake Luer <jake@alogicalparadox.com>\n * MIT Licensed\n */\n\nmodule.exports = function (chai, _) {\n  var Assertion = chai.Assertion\n    , toString = Object.prototype.toString\n    , flag = _.flag;\n\n  /**\n   * ### Language Chains\n   *\n   * The following are provided as chainable getters to\n   * improve the readability of your assertions. They\n   * do not provide testing capabilities unless they\n   * have been overwritten by a plugin.\n   *\n   * **Chains**\n   *\n   * - to\n   * - be\n   * - been\n   * - is\n   * - that\n   * - which\n   * - and\n   * - has\n   * - have\n   * - with\n   * - at\n   * - of\n   * - same\n   *\n   * @name language chains\n   * @namespace BDD\n   * @api public\n   */\n\n  [ 'to', 'be', 'been'\n  , 'is', 'and', 'has', 'have'\n  , 'with', 'that', 'which', 'at'\n  , 'of', 'same' ].forEach(function (chain) {\n    Assertion.addProperty(chain, function () {\n      return this;\n    });\n  });\n\n  /**\n   * ### .not\n   *\n   * Negates any of assertions following in the chain.\n   *\n   *     expect(foo).to.not.equal('bar');\n   *     expect(goodFn).to.not.throw(Error);\n   *     expect({ foo: 'baz' }).to.have.property('foo')\n   *       .and.not.equal('bar');\n   *\n   * @name not\n   * @namespace BDD\n   * @api public\n   */\n\n  Assertion.addProperty('not', function () {\n    flag(this, 'negate', true);\n  });\n\n  /**\n   * ### .deep\n   *\n   * Sets the `deep` flag, later used by the `equal` and\n   * `property` assertions.\n   *\n   *     expect(foo).to.deep.equal({ bar: 'baz' });\n   *     expect({ foo: { bar: { baz: 'quux' } } })\n   *       .to.have.deep.property('foo.bar.baz', 'quux');\n   *\n   * `.deep.property` special characters can be escaped\n   * by adding two slashes before the `.` or `[]`.\n   *\n   *     var deepCss = { '.link': { '[target]': 42 }};\n   *     expect(deepCss).to.have.deep.property('\\\\.link.\\\\[target\\\\]', 42);\n   *\n   * @name deep\n   * @namespace BDD\n   * @api public\n   */\n\n  Assertion.addProperty('deep', function () {\n    flag(this, 'deep', true);\n  });\n\n  /**\n   * ### .any\n   *\n   * Sets the `any` flag, (opposite of the `all` flag)\n   * later used in the `keys` assertion.\n   *\n   *     expect(foo).to.have.any.keys('bar', 'baz');\n   *\n   * @name any\n   * @namespace BDD\n   * @api public\n   */\n\n  Assertion.addProperty('any', function () {\n    flag(this, 'any', true);\n    flag(this, 'all', false)\n  });\n\n\n  /**\n   * ### .all\n   *\n   * Sets the `all` flag (opposite of the `any` flag)\n   * later used by the `keys` assertion.\n   *\n   *     expect(foo).to.have.all.keys('bar', 'baz');\n   *\n   * @name all\n   * @namespace BDD\n   * @api public\n   */\n\n  Assertion.addProperty('all', function () {\n    flag(this, 'all', true);\n    flag(this, 'any', false);\n  });\n\n  /**\n   * ### .a(type)\n   *\n   * The `a` and `an` assertions are aliases that can be\n   * used either as language chains or to assert a value's\n   * type.\n   *\n   *     // typeof\n   *     expect('test').to.be.a('string');\n   *     expect({ foo: 'bar' }).to.be.an('object');\n   *     expect(null).to.be.a('null');\n   *     expect(undefined).to.be.an('undefined');\n   *     expect(new Error).to.be.an('error');\n   *     expect(new Promise).to.be.a('promise');\n   *     expect(new Float32Array()).to.be.a('float32array');\n   *     expect(Symbol()).to.be.a('symbol');\n   *\n   *     // es6 overrides\n   *     expect({[Symbol.toStringTag]:()=>'foo'}).to.be.a('foo');\n   *\n   *     // language chain\n   *     expect(foo).to.be.an.instanceof(Foo);\n   *\n   * @name a\n   * @alias an\n   * @param {String} type\n   * @param {String} message _optional_\n   * @namespace BDD\n   * @api public\n   */\n\n  function an (type, msg) {\n    if (msg) flag(this, 'message', msg);\n    type = type.toLowerCase();\n    var obj = flag(this, 'object')\n      , article = ~[ 'a', 'e', 'i', 'o', 'u' ].indexOf(type.charAt(0)) ? 'an ' : 'a ';\n\n    this.assert(\n        type === _.type(obj)\n      , 'expected #{this} to be ' + article + type\n      , 'expected #{this} not to be ' + article + type\n    );\n  }\n\n  Assertion.addChainableMethod('an', an);\n  Assertion.addChainableMethod('a', an);\n\n  /**\n   * ### .include(value)\n   *\n   * The `include` and `contain` assertions can be used as either property\n   * based language chains or as methods to assert the inclusion of an object\n   * in an array or a substring in a string. When used as language chains,\n   * they toggle the `contains` flag for the `keys` assertion.\n   *\n   *     expect([1,2,3]).to.include(2);\n   *     expect('foobar').to.contain('foo');\n   *     expect({ foo: 'bar', hello: 'universe' }).to.include.keys('foo');\n   *\n   * @name include\n   * @alias contain\n   * @alias includes\n   * @alias contains\n   * @param {Object|String|Number} obj\n   * @param {String} message _optional_\n   * @namespace BDD\n   * @api public\n   */\n\n  function includeChainingBehavior () {\n    flag(this, 'contains', true);\n  }\n\n  function include (val, msg) {\n    _.expectTypes(this, ['array', 'object', 'string']);\n\n    if (msg) flag(this, 'message', msg);\n    var obj = flag(this, 'object');\n    var expected = false;\n\n    if (_.type(obj) === 'array' && _.type(val) === 'object') {\n      for (var i in obj) {\n        if (_.eql(obj[i], val)) {\n          expected = true;\n          break;\n        }\n      }\n    } else if (_.type(val) === 'object') {\n      if (!flag(this, 'negate')) {\n        for (var k in val) new Assertion(obj).property(k, val[k]);\n        return;\n      }\n      var subset = {};\n      for (var k in val) subset[k] = obj[k];\n      expected = _.eql(subset, val);\n    } else {\n      expected = (obj != undefined) && ~obj.indexOf(val);\n    }\n    this.assert(\n        expected\n      , 'expected #{this} to include ' + _.inspect(val)\n      , 'expected #{this} to not include ' + _.inspect(val));\n  }\n\n  Assertion.addChainableMethod('include', include, includeChainingBehavior);\n  Assertion.addChainableMethod('contain', include, includeChainingBehavior);\n  Assertion.addChainableMethod('contains', include, includeChainingBehavior);\n  Assertion.addChainableMethod('includes', include, includeChainingBehavior);\n\n  /**\n   * ### .ok\n   *\n   * Asserts that the target is truthy.\n   *\n   *     expect('everything').to.be.ok;\n   *     expect(1).to.be.ok;\n   *     expect(false).to.not.be.ok;\n   *     expect(undefined).to.not.be.ok;\n   *     expect(null).to.not.be.ok;\n   *\n   * @name ok\n   * @namespace BDD\n   * @api public\n   */\n\n  Assertion.addProperty('ok', function () {\n    this.assert(\n        flag(this, 'object')\n      , 'expected #{this} to be truthy'\n      , 'expected #{this} to be falsy');\n  });\n\n  /**\n   * ### .true\n   *\n   * Asserts that the target is `true`.\n   *\n   *     expect(true).to.be.true;\n   *     expect(1).to.not.be.true;\n   *\n   * @name true\n   * @namespace BDD\n   * @api public\n   */\n\n  Assertion.addProperty('true', function () {\n    this.assert(\n        true === flag(this, 'object')\n      , 'expected #{this} to be true'\n      , 'expected #{this} to be false'\n      , this.negate ? false : true\n    );\n  });\n\n  /**\n   * ### .false\n   *\n   * Asserts that the target is `false`.\n   *\n   *     expect(false).to.be.false;\n   *     expect(0).to.not.be.false;\n   *\n   * @name false\n   * @namespace BDD\n   * @api public\n   */\n\n  Assertion.addProperty('false', function () {\n    this.assert(\n        false === flag(this, 'object')\n      , 'expected #{this} to be false'\n      , 'expected #{this} to be true'\n      , this.negate ? true : false\n    );\n  });\n\n  /**\n   * ### .null\n   *\n   * Asserts that the target is `null`.\n   *\n   *     expect(null).to.be.null;\n   *     expect(undefined).to.not.be.null;\n   *\n   * @name null\n   * @namespace BDD\n   * @api public\n   */\n\n  Assertion.addProperty('null', function () {\n    this.assert(\n        null === flag(this, 'object')\n      , 'expected #{this} to be null'\n      , 'expected #{this} not to be null'\n    );\n  });\n\n  /**\n   * ### .undefined\n   *\n   * Asserts that the target is `undefined`.\n   *\n   *     expect(undefined).to.be.undefined;\n   *     expect(null).to.not.be.undefined;\n   *\n   * @name undefined\n   * @namespace BDD\n   * @api public\n   */\n\n  Assertion.addProperty('undefined', function () {\n    this.assert(\n        undefined === flag(this, 'object')\n      , 'expected #{this} to be undefined'\n      , 'expected #{this} not to be undefined'\n    );\n  });\n\n  /**\n   * ### .NaN\n   * Asserts that the target is `NaN`.\n   *\n   *     expect('foo').to.be.NaN;\n   *     expect(4).not.to.be.NaN;\n   *\n   * @name NaN\n   * @namespace BDD\n   * @api public\n   */\n\n  Assertion.addProperty('NaN', function () {\n    this.assert(\n        isNaN(flag(this, 'object'))\n        , 'expected #{this} to be NaN'\n        , 'expected #{this} not to be NaN'\n    );\n  });\n\n  /**\n   * ### .exist\n   *\n   * Asserts that the target is neither `null` nor `undefined`.\n   *\n   *     var foo = 'hi'\n   *       , bar = null\n   *       , baz;\n   *\n   *     expect(foo).to.exist;\n   *     expect(bar).to.not.exist;\n   *     expect(baz).to.not.exist;\n   *\n   * @name exist\n   * @namespace BDD\n   * @api public\n   */\n\n  Assertion.addProperty('exist', function () {\n    this.assert(\n        null != flag(this, 'object')\n      , 'expected #{this} to exist'\n      , 'expected #{this} to not exist'\n    );\n  });\n\n\n  /**\n   * ### .empty\n   *\n   * Asserts that the target's length is `0`. For arrays and strings, it checks\n   * the `length` property. For objects, it gets the count of\n   * enumerable keys.\n   *\n   *     expect([]).to.be.empty;\n   *     expect('').to.be.empty;\n   *     expect({}).to.be.empty;\n   *\n   * @name empty\n   * @namespace BDD\n   * @api public\n   */\n\n  Assertion.addProperty('empty', function () {\n    var obj = flag(this, 'object')\n      , expected = obj;\n\n    if (Array.isArray(obj) || 'string' === typeof object) {\n      expected = obj.length;\n    } else if (typeof obj === 'object') {\n      expected = Object.keys(obj).length;\n    }\n\n    this.assert(\n        !expected\n      , 'expected #{this} to be empty'\n      , 'expected #{this} not to be empty'\n    );\n  });\n\n  /**\n   * ### .arguments\n   *\n   * Asserts that the target is an arguments object.\n   *\n   *     function test () {\n   *       expect(arguments).to.be.arguments;\n   *     }\n   *\n   * @name arguments\n   * @alias Arguments\n   * @namespace BDD\n   * @api public\n   */\n\n  function checkArguments () {\n    var obj = flag(this, 'object')\n      , type = Object.prototype.toString.call(obj);\n    this.assert(\n        '[object Arguments]' === type\n      , 'expected #{this} to be arguments but got ' + type\n      , 'expected #{this} to not be arguments'\n    );\n  }\n\n  Assertion.addProperty('arguments', checkArguments);\n  Assertion.addProperty('Arguments', checkArguments);\n\n  /**\n   * ### .equal(value)\n   *\n   * Asserts that the target is strictly equal (`===`) to `value`.\n   * Alternately, if the `deep` flag is set, asserts that\n   * the target is deeply equal to `value`.\n   *\n   *     expect('hello').to.equal('hello');\n   *     expect(42).to.equal(42);\n   *     expect(1).to.not.equal(true);\n   *     expect({ foo: 'bar' }).to.not.equal({ foo: 'bar' });\n   *     expect({ foo: 'bar' }).to.deep.equal({ foo: 'bar' });\n   *\n   * @name equal\n   * @alias equals\n   * @alias eq\n   * @alias deep.equal\n   * @param {Mixed} value\n   * @param {String} message _optional_\n   * @namespace BDD\n   * @api public\n   */\n\n  function assertEqual (val, msg) {\n    if (msg) flag(this, 'message', msg);\n    var obj = flag(this, 'object');\n    if (flag(this, 'deep')) {\n      return this.eql(val);\n    } else {\n      this.assert(\n          val === obj\n        , 'expected #{this} to equal #{exp}'\n        , 'expected #{this} to not equal #{exp}'\n        , val\n        , this._obj\n        , true\n      );\n    }\n  }\n\n  Assertion.addMethod('equal', assertEqual);\n  Assertion.addMethod('equals', assertEqual);\n  Assertion.addMethod('eq', assertEqual);\n\n  /**\n   * ### .eql(value)\n   *\n   * Asserts that the target is deeply equal to `value`.\n   *\n   *     expect({ foo: 'bar' }).to.eql({ foo: 'bar' });\n   *     expect([ 1, 2, 3 ]).to.eql([ 1, 2, 3 ]);\n   *\n   * @name eql\n   * @alias eqls\n   * @param {Mixed} value\n   * @param {String} message _optional_\n   * @namespace BDD\n   * @api public\n   */\n\n  function assertEql(obj, msg) {\n    if (msg) flag(this, 'message', msg);\n    this.assert(\n        _.eql(obj, flag(this, 'object'))\n      , 'expected #{this} to deeply equal #{exp}'\n      , 'expected #{this} to not deeply equal #{exp}'\n      , obj\n      , this._obj\n      , true\n    );\n  }\n\n  Assertion.addMethod('eql', assertEql);\n  Assertion.addMethod('eqls', assertEql);\n\n  /**\n   * ### .above(value)\n   *\n   * Asserts that the target is greater than `value`.\n   *\n   *     expect(10).to.be.above(5);\n   *\n   * Can also be used in conjunction with `length` to\n   * assert a minimum length. The benefit being a\n   * more informative error message than if the length\n   * was supplied directly.\n   *\n   *     expect('foo').to.have.length.above(2);\n   *     expect([ 1, 2, 3 ]).to.have.length.above(2);\n   *\n   * @name above\n   * @alias gt\n   * @alias greaterThan\n   * @param {Number} value\n   * @param {String} message _optional_\n   * @namespace BDD\n   * @api public\n   */\n\n  function assertAbove (n, msg) {\n    if (msg) flag(this, 'message', msg);\n    var obj = flag(this, 'object');\n    if (flag(this, 'doLength')) {\n      new Assertion(obj, msg).to.have.property('length');\n      var len = obj.length;\n      this.assert(\n          len > n\n        , 'expected #{this} to have a length above #{exp} but got #{act}'\n        , 'expected #{this} to not have a length above #{exp}'\n        , n\n        , len\n      );\n    } else {\n      this.assert(\n          obj > n\n        , 'expected #{this} to be above ' + n\n        , 'expected #{this} to be at most ' + n\n      );\n    }\n  }\n\n  Assertion.addMethod('above', assertAbove);\n  Assertion.addMethod('gt', assertAbove);\n  Assertion.addMethod('greaterThan', assertAbove);\n\n  /**\n   * ### .least(value)\n   *\n   * Asserts that the target is greater than or equal to `value`.\n   *\n   *     expect(10).to.be.at.least(10);\n   *\n   * Can also be used in conjunction with `length` to\n   * assert a minimum length. The benefit being a\n   * more informative error message than if the length\n   * was supplied directly.\n   *\n   *     expect('foo').to.have.length.of.at.least(2);\n   *     expect([ 1, 2, 3 ]).to.have.length.of.at.least(3);\n   *\n   * @name least\n   * @alias gte\n   * @param {Number} value\n   * @param {String} message _optional_\n   * @namespace BDD\n   * @api public\n   */\n\n  function assertLeast (n, msg) {\n    if (msg) flag(this, 'message', msg);\n    var obj = flag(this, 'object');\n    if (flag(this, 'doLength')) {\n      new Assertion(obj, msg).to.have.property('length');\n      var len = obj.length;\n      this.assert(\n          len >= n\n        , 'expected #{this} to have a length at least #{exp} but got #{act}'\n        , 'expected #{this} to have a length below #{exp}'\n        , n\n        , len\n      );\n    } else {\n      this.assert(\n          obj >= n\n        , 'expected #{this} to be at least ' + n\n        , 'expected #{this} to be below ' + n\n      );\n    }\n  }\n\n  Assertion.addMethod('least', assertLeast);\n  Assertion.addMethod('gte', assertLeast);\n\n  /**\n   * ### .below(value)\n   *\n   * Asserts that the target is less than `value`.\n   *\n   *     expect(5).to.be.below(10);\n   *\n   * Can also be used in conjunction with `length` to\n   * assert a maximum length. The benefit being a\n   * more informative error message than if the length\n   * was supplied directly.\n   *\n   *     expect('foo').to.have.length.below(4);\n   *     expect([ 1, 2, 3 ]).to.have.length.below(4);\n   *\n   * @name below\n   * @alias lt\n   * @alias lessThan\n   * @param {Number} value\n   * @param {String} message _optional_\n   * @namespace BDD\n   * @api public\n   */\n\n  function assertBelow (n, msg) {\n    if (msg) flag(this, 'message', msg);\n    var obj = flag(this, 'object');\n    if (flag(this, 'doLength')) {\n      new Assertion(obj, msg).to.have.property('length');\n      var len = obj.length;\n      this.assert(\n          len < n\n        , 'expected #{this} to have a length below #{exp} but got #{act}'\n        , 'expected #{this} to not have a length below #{exp}'\n        , n\n        , len\n      );\n    } else {\n      this.assert(\n          obj < n\n        , 'expected #{this} to be below ' + n\n        , 'expected #{this} to be at least ' + n\n      );\n    }\n  }\n\n  Assertion.addMethod('below', assertBelow);\n  Assertion.addMethod('lt', assertBelow);\n  Assertion.addMethod('lessThan', assertBelow);\n\n  /**\n   * ### .most(value)\n   *\n   * Asserts that the target is less than or equal to `value`.\n   *\n   *     expect(5).to.be.at.most(5);\n   *\n   * Can also be used in conjunction with `length` to\n   * assert a maximum length. The benefit being a\n   * more informative error message than if the length\n   * was supplied directly.\n   *\n   *     expect('foo').to.have.length.of.at.most(4);\n   *     expect([ 1, 2, 3 ]).to.have.length.of.at.most(3);\n   *\n   * @name most\n   * @alias lte\n   * @param {Number} value\n   * @param {String} message _optional_\n   * @namespace BDD\n   * @api public\n   */\n\n  function assertMost (n, msg) {\n    if (msg) flag(this, 'message', msg);\n    var obj = flag(this, 'object');\n    if (flag(this, 'doLength')) {\n      new Assertion(obj, msg).to.have.property('length');\n      var len = obj.length;\n      this.assert(\n          len <= n\n        , 'expected #{this} to have a length at most #{exp} but got #{act}'\n        , 'expected #{this} to have a length above #{exp}'\n        , n\n        , len\n      );\n    } else {\n      this.assert(\n          obj <= n\n        , 'expected #{this} to be at most ' + n\n        , 'expected #{this} to be above ' + n\n      );\n    }\n  }\n\n  Assertion.addMethod('most', assertMost);\n  Assertion.addMethod('lte', assertMost);\n\n  /**\n   * ### .within(start, finish)\n   *\n   * Asserts that the target is within a range.\n   *\n   *     expect(7).to.be.within(5,10);\n   *\n   * Can also be used in conjunction with `length` to\n   * assert a length range. The benefit being a\n   * more informative error message than if the length\n   * was supplied directly.\n   *\n   *     expect('foo').to.have.length.within(2,4);\n   *     expect([ 1, 2, 3 ]).to.have.length.within(2,4);\n   *\n   * @name within\n   * @param {Number} start lowerbound inclusive\n   * @param {Number} finish upperbound inclusive\n   * @param {String} message _optional_\n   * @namespace BDD\n   * @api public\n   */\n\n  Assertion.addMethod('within', function (start, finish, msg) {\n    if (msg) flag(this, 'message', msg);\n    var obj = flag(this, 'object')\n      , range = start + '..' + finish;\n    if (flag(this, 'doLength')) {\n      new Assertion(obj, msg).to.have.property('length');\n      var len = obj.length;\n      this.assert(\n          len >= start && len <= finish\n        , 'expected #{this} to have a length within ' + range\n        , 'expected #{this} to not have a length within ' + range\n      );\n    } else {\n      this.assert(\n          obj >= start && obj <= finish\n        , 'expected #{this} to be within ' + range\n        , 'expected #{this} to not be within ' + range\n      );\n    }\n  });\n\n  /**\n   * ### .instanceof(constructor)\n   *\n   * Asserts that the target is an instance of `constructor`.\n   *\n   *     var Tea = function (name) { this.name = name; }\n   *       , Chai = new Tea('chai');\n   *\n   *     expect(Chai).to.be.an.instanceof(Tea);\n   *     expect([ 1, 2, 3 ]).to.be.instanceof(Array);\n   *\n   * @name instanceof\n   * @param {Constructor} constructor\n   * @param {String} message _optional_\n   * @alias instanceOf\n   * @namespace BDD\n   * @api public\n   */\n\n  function assertInstanceOf (constructor, msg) {\n    if (msg) flag(this, 'message', msg);\n    var name = _.getName(constructor);\n    this.assert(\n        flag(this, 'object') instanceof constructor\n      , 'expected #{this} to be an instance of ' + name\n      , 'expected #{this} to not be an instance of ' + name\n    );\n  };\n\n  Assertion.addMethod('instanceof', assertInstanceOf);\n  Assertion.addMethod('instanceOf', assertInstanceOf);\n\n  /**\n   * ### .property(name, [value])\n   *\n   * Asserts that the target has a property `name`, optionally asserting that\n   * the value of that property is strictly equal to  `value`.\n   * If the `deep` flag is set, you can use dot- and bracket-notation for deep\n   * references into objects and arrays.\n   *\n   *     // simple referencing\n   *     var obj = { foo: 'bar' };\n   *     expect(obj).to.have.property('foo');\n   *     expect(obj).to.have.property('foo', 'bar');\n   *\n   *     // deep referencing\n   *     var deepObj = {\n   *         green: { tea: 'matcha' }\n   *       , teas: [ 'chai', 'matcha', { tea: 'konacha' } ]\n   *     };\n   *\n   *     expect(deepObj).to.have.deep.property('green.tea', 'matcha');\n   *     expect(deepObj).to.have.deep.property('teas[1]', 'matcha');\n   *     expect(deepObj).to.have.deep.property('teas[2].tea', 'konacha');\n   *\n   * You can also use an array as the starting point of a `deep.property`\n   * assertion, or traverse nested arrays.\n   *\n   *     var arr = [\n   *         [ 'chai', 'matcha', 'konacha' ]\n   *       , [ { tea: 'chai' }\n   *         , { tea: 'matcha' }\n   *         , { tea: 'konacha' } ]\n   *     ];\n   *\n   *     expect(arr).to.have.deep.property('[0][1]', 'matcha');\n   *     expect(arr).to.have.deep.property('[1][2].tea', 'konacha');\n   *\n   * Furthermore, `property` changes the subject of the assertion\n   * to be the value of that property from the original object. This\n   * permits for further chainable assertions on that property.\n   *\n   *     expect(obj).to.have.property('foo')\n   *       .that.is.a('string');\n   *     expect(deepObj).to.have.property('green')\n   *       .that.is.an('object')\n   *       .that.deep.equals({ tea: 'matcha' });\n   *     expect(deepObj).to.have.property('teas')\n   *       .that.is.an('array')\n   *       .with.deep.property('[2]')\n   *         .that.deep.equals({ tea: 'konacha' });\n   *\n   * Note that dots and bracket in `name` must be backslash-escaped when\n   * the `deep` flag is set, while they must NOT be escaped when the `deep`\n   * flag is not set.\n   *\n   *     // simple referencing\n   *     var css = { '.link[target]': 42 };\n   *     expect(css).to.have.property('.link[target]', 42);\n   *\n   *     // deep referencing\n   *     var deepCss = { '.link': { '[target]': 42 }};\n   *     expect(deepCss).to.have.deep.property('\\\\.link.\\\\[target\\\\]', 42);\n   *\n   * @name property\n   * @alias deep.property\n   * @param {String} name\n   * @param {Mixed} value (optional)\n   * @param {String} message _optional_\n   * @returns value of property for chaining\n   * @namespace BDD\n   * @api public\n   */\n\n  Assertion.addMethod('property', function (name, val, msg) {\n    if (msg) flag(this, 'message', msg);\n\n    var isDeep = !!flag(this, 'deep')\n      , descriptor = isDeep ? 'deep property ' : 'property '\n      , negate = flag(this, 'negate')\n      , obj = flag(this, 'object')\n      , pathInfo = isDeep ? _.getPathInfo(name, obj) : null\n      , hasProperty = isDeep\n        ? pathInfo.exists\n        : _.hasProperty(name, obj)\n      , value = isDeep\n        ? pathInfo.value\n        : obj[name];\n\n    if (negate && arguments.length > 1) {\n      if (undefined === value) {\n        msg = (msg != null) ? msg + ': ' : '';\n        throw new Error(msg + _.inspect(obj) + ' has no ' + descriptor + _.inspect(name));\n      }\n    } else {\n      this.assert(\n          hasProperty\n        , 'expected #{this} to have a ' + descriptor + _.inspect(name)\n        , 'expected #{this} to not have ' + descriptor + _.inspect(name));\n    }\n\n    if (arguments.length > 1) {\n      this.assert(\n          val === value\n        , 'expected #{this} to have a ' + descriptor + _.inspect(name) + ' of #{exp}, but got #{act}'\n        , 'expected #{this} to not have a ' + descriptor + _.inspect(name) + ' of #{act}'\n        , val\n        , value\n      );\n    }\n\n    flag(this, 'object', value);\n  });\n\n\n  /**\n   * ### .ownProperty(name)\n   *\n   * Asserts that the target has an own property `name`.\n   *\n   *     expect('test').to.have.ownProperty('length');\n   *\n   * @name ownProperty\n   * @alias haveOwnProperty\n   * @param {String} name\n   * @param {String} message _optional_\n   * @namespace BDD\n   * @api public\n   */\n\n  function assertOwnProperty (name, msg) {\n    if (msg) flag(this, 'message', msg);\n    var obj = flag(this, 'object');\n    this.assert(\n        obj.hasOwnProperty(name)\n      , 'expected #{this} to have own property ' + _.inspect(name)\n      , 'expected #{this} to not have own property ' + _.inspect(name)\n    );\n  }\n\n  Assertion.addMethod('ownProperty', assertOwnProperty);\n  Assertion.addMethod('haveOwnProperty', assertOwnProperty);\n\n  /**\n   * ### .ownPropertyDescriptor(name[, descriptor[, message]])\n   *\n   * Asserts that the target has an own property descriptor `name`, that optionally matches `descriptor`.\n   *\n   *     expect('test').to.have.ownPropertyDescriptor('length');\n   *     expect('test').to.have.ownPropertyDescriptor('length', { enumerable: false, configurable: false, writable: false, value: 4 });\n   *     expect('test').not.to.have.ownPropertyDescriptor('length', { enumerable: false, configurable: false, writable: false, value: 3 });\n   *     expect('test').ownPropertyDescriptor('length').to.have.property('enumerable', false);\n   *     expect('test').ownPropertyDescriptor('length').to.have.keys('value');\n   *\n   * @name ownPropertyDescriptor\n   * @alias haveOwnPropertyDescriptor\n   * @param {String} name\n   * @param {Object} descriptor _optional_\n   * @param {String} message _optional_\n   * @namespace BDD\n   * @api public\n   */\n\n  function assertOwnPropertyDescriptor (name, descriptor, msg) {\n    if (typeof descriptor === 'string') {\n      msg = descriptor;\n      descriptor = null;\n    }\n    if (msg) flag(this, 'message', msg);\n    var obj = flag(this, 'object');\n    var actualDescriptor = Object.getOwnPropertyDescriptor(Object(obj), name);\n    if (actualDescriptor && descriptor) {\n      this.assert(\n          _.eql(descriptor, actualDescriptor)\n        , 'expected the own property descriptor for ' + _.inspect(name) + ' on #{this} to match ' + _.inspect(descriptor) + ', got ' + _.inspect(actualDescriptor)\n        , 'expected the own property descriptor for ' + _.inspect(name) + ' on #{this} to not match ' + _.inspect(descriptor)\n        , descriptor\n        , actualDescriptor\n        , true\n      );\n    } else {\n      this.assert(\n          actualDescriptor\n        , 'expected #{this} to have an own property descriptor for ' + _.inspect(name)\n        , 'expected #{this} to not have an own property descriptor for ' + _.inspect(name)\n      );\n    }\n    flag(this, 'object', actualDescriptor);\n  }\n\n  Assertion.addMethod('ownPropertyDescriptor', assertOwnPropertyDescriptor);\n  Assertion.addMethod('haveOwnPropertyDescriptor', assertOwnPropertyDescriptor);\n\n  /**\n   * ### .length\n   *\n   * Sets the `doLength` flag later used as a chain precursor to a value\n   * comparison for the `length` property.\n   *\n   *     expect('foo').to.have.length.above(2);\n   *     expect([ 1, 2, 3 ]).to.have.length.above(2);\n   *     expect('foo').to.have.length.below(4);\n   *     expect([ 1, 2, 3 ]).to.have.length.below(4);\n   *     expect('foo').to.have.length.within(2,4);\n   *     expect([ 1, 2, 3 ]).to.have.length.within(2,4);\n   *\n   * *Deprecation notice:* Using `length` as an assertion will be deprecated\n   * in version 2.4.0 and removed in 3.0.0. Code using the old style of\n   * asserting for `length` property value using `length(value)` should be\n   * switched to use `lengthOf(value)` instead.\n   *\n   * @name length\n   * @namespace BDD\n   * @api public\n   */\n\n  /**\n   * ### .lengthOf(value[, message])\n   *\n   * Asserts that the target's `length` property has\n   * the expected value.\n   *\n   *     expect([ 1, 2, 3]).to.have.lengthOf(3);\n   *     expect('foobar').to.have.lengthOf(6);\n   *\n   * @name lengthOf\n   * @param {Number} length\n   * @param {String} message _optional_\n   * @namespace BDD\n   * @api public\n   */\n\n  function assertLengthChain () {\n    flag(this, 'doLength', true);\n  }\n\n  function assertLength (n, msg) {\n    if (msg) flag(this, 'message', msg);\n    var obj = flag(this, 'object');\n    new Assertion(obj, msg).to.have.property('length');\n    var len = obj.length;\n\n    this.assert(\n        len == n\n      , 'expected #{this} to have a length of #{exp} but got #{act}'\n      , 'expected #{this} to not have a length of #{act}'\n      , n\n      , len\n    );\n  }\n\n  Assertion.addChainableMethod('length', assertLength, assertLengthChain);\n  Assertion.addMethod('lengthOf', assertLength);\n\n  /**\n   * ### .match(regexp)\n   *\n   * Asserts that the target matches a regular expression.\n   *\n   *     expect('foobar').to.match(/^foo/);\n   *\n   * @name match\n   * @alias matches\n   * @param {RegExp} RegularExpression\n   * @param {String} message _optional_\n   * @namespace BDD\n   * @api public\n   */\n  function assertMatch(re, msg) {\n    if (msg) flag(this, 'message', msg);\n    var obj = flag(this, 'object');\n    this.assert(\n        re.exec(obj)\n      , 'expected #{this} to match ' + re\n      , 'expected #{this} not to match ' + re\n    );\n  }\n\n  Assertion.addMethod('match', assertMatch);\n  Assertion.addMethod('matches', assertMatch);\n\n  /**\n   * ### .string(string)\n   *\n   * Asserts that the string target contains another string.\n   *\n   *     expect('foobar').to.have.string('bar');\n   *\n   * @name string\n   * @param {String} string\n   * @param {String} message _optional_\n   * @namespace BDD\n   * @api public\n   */\n\n  Assertion.addMethod('string', function (str, msg) {\n    if (msg) flag(this, 'message', msg);\n    var obj = flag(this, 'object');\n    new Assertion(obj, msg).is.a('string');\n\n    this.assert(\n        ~obj.indexOf(str)\n      , 'expected #{this} to contain ' + _.inspect(str)\n      , 'expected #{this} to not contain ' + _.inspect(str)\n    );\n  });\n\n\n  /**\n   * ### .keys(key1, [key2], [...])\n   *\n   * Asserts that the target contains any or all of the passed-in keys.\n   * Use in combination with `any`, `all`, `contains`, or `have` will affect\n   * what will pass.\n   *\n   * When used in conjunction with `any`, at least one key that is passed\n   * in must exist in the target object. This is regardless whether or not\n   * the `have` or `contain` qualifiers are used. Note, either `any` or `all`\n   * should be used in the assertion. If neither are used, the assertion is\n   * defaulted to `all`.\n   *\n   * When both `all` and `contain` are used, the target object must have at\n   * least all of the passed-in keys but may have more keys not listed.\n   *\n   * When both `all` and `have` are used, the target object must both contain\n   * all of the passed-in keys AND the number of keys in the target object must\n   * match the number of keys passed in (in other words, a target object must\n   * have all and only all of the passed-in keys).\n   *\n   *     expect({ foo: 1, bar: 2 }).to.have.any.keys('foo', 'baz');\n   *     expect({ foo: 1, bar: 2 }).to.have.any.keys('foo');\n   *     expect({ foo: 1, bar: 2 }).to.contain.any.keys('bar', 'baz');\n   *     expect({ foo: 1, bar: 2 }).to.contain.any.keys(['foo']);\n   *     expect({ foo: 1, bar: 2 }).to.contain.any.keys({'foo': 6});\n   *     expect({ foo: 1, bar: 2 }).to.have.all.keys(['bar', 'foo']);\n   *     expect({ foo: 1, bar: 2 }).to.have.all.keys({'bar': 6, 'foo': 7});\n   *     expect({ foo: 1, bar: 2, baz: 3 }).to.contain.all.keys(['bar', 'foo']);\n   *     expect({ foo: 1, bar: 2, baz: 3 }).to.contain.all.keys({'bar': 6});\n   *\n   *\n   * @name keys\n   * @alias key\n   * @param {...String|Array|Object} keys\n   * @namespace BDD\n   * @api public\n   */\n\n  function assertKeys (keys) {\n    var obj = flag(this, 'object')\n      , str\n      , ok = true\n      , mixedArgsMsg = 'keys must be given single argument of Array|Object|String, or multiple String arguments';\n\n    switch (_.type(keys)) {\n      case \"array\":\n        if (arguments.length > 1) throw (new Error(mixedArgsMsg));\n        break;\n      case \"object\":\n        if (arguments.length > 1) throw (new Error(mixedArgsMsg));\n        keys = Object.keys(keys);\n        break;\n      default:\n        keys = Array.prototype.slice.call(arguments);\n    }\n\n    if (!keys.length) throw new Error('keys required');\n\n    var actual = Object.keys(obj)\n      , expected = keys\n      , len = keys.length\n      , any = flag(this, 'any')\n      , all = flag(this, 'all');\n\n    if (!any && !all) {\n      all = true;\n    }\n\n    // Has any\n    if (any) {\n      var intersection = expected.filter(function(key) {\n        return ~actual.indexOf(key);\n      });\n      ok = intersection.length > 0;\n    }\n\n    // Has all\n    if (all) {\n      ok = keys.every(function(key){\n        return ~actual.indexOf(key);\n      });\n      if (!flag(this, 'negate') && !flag(this, 'contains')) {\n        ok = ok && keys.length == actual.length;\n      }\n    }\n\n    // Key string\n    if (len > 1) {\n      keys = keys.map(function(key){\n        return _.inspect(key);\n      });\n      var last = keys.pop();\n      if (all) {\n        str = keys.join(', ') + ', and ' + last;\n      }\n      if (any) {\n        str = keys.join(', ') + ', or ' + last;\n      }\n    } else {\n      str = _.inspect(keys[0]);\n    }\n\n    // Form\n    str = (len > 1 ? 'keys ' : 'key ') + str;\n\n    // Have / include\n    str = (flag(this, 'contains') ? 'contain ' : 'have ') + str;\n\n    // Assertion\n    this.assert(\n        ok\n      , 'expected #{this} to ' + str\n      , 'expected #{this} to not ' + str\n      , expected.slice(0).sort()\n      , actual.sort()\n      , true\n    );\n  }\n\n  Assertion.addMethod('keys', assertKeys);\n  Assertion.addMethod('key', assertKeys);\n\n  /**\n   * ### .throw(constructor)\n   *\n   * Asserts that the function target will throw a specific error, or specific type of error\n   * (as determined using `instanceof`), optionally with a RegExp or string inclusion test\n   * for the error's message.\n   *\n   *     var err = new ReferenceError('This is a bad function.');\n   *     var fn = function () { throw err; }\n   *     expect(fn).to.throw(ReferenceError);\n   *     expect(fn).to.throw(Error);\n   *     expect(fn).to.throw(/bad function/);\n   *     expect(fn).to.not.throw('good function');\n   *     expect(fn).to.throw(ReferenceError, /bad function/);\n   *     expect(fn).to.throw(err);\n   *\n   * Please note that when a throw expectation is negated, it will check each\n   * parameter independently, starting with error constructor type. The appropriate way\n   * to check for the existence of a type of error but for a message that does not match\n   * is to use `and`.\n   *\n   *     expect(fn).to.throw(ReferenceError)\n   *        .and.not.throw(/good function/);\n   *\n   * @name throw\n   * @alias throws\n   * @alias Throw\n   * @param {ErrorConstructor} constructor\n   * @param {String|RegExp} expected error message\n   * @param {String} message _optional_\n   * @see https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Error#Error_types\n   * @returns error for chaining (null if no error)\n   * @namespace BDD\n   * @api public\n   */\n\n  function assertThrows (constructor, errMsg, msg) {\n    if (msg) flag(this, 'message', msg);\n    var obj = flag(this, 'object');\n    new Assertion(obj, msg).is.a('function');\n\n    var thrown = false\n      , desiredError = null\n      , name = null\n      , thrownError = null;\n\n    if (arguments.length === 0) {\n      errMsg = null;\n      constructor = null;\n    } else if (constructor && (constructor instanceof RegExp || 'string' === typeof constructor)) {\n      errMsg = constructor;\n      constructor = null;\n    } else if (constructor && constructor instanceof Error) {\n      desiredError = constructor;\n      constructor = null;\n      errMsg = null;\n    } else if (typeof constructor === 'function') {\n      name = constructor.prototype.name;\n      if (!name || (name === 'Error' && constructor !== Error)) {\n        name = constructor.name || (new constructor()).name;\n      }\n    } else {\n      constructor = null;\n    }\n\n    try {\n      obj();\n    } catch (err) {\n      // first, check desired error\n      if (desiredError) {\n        this.assert(\n            err === desiredError\n          , 'expected #{this} to throw #{exp} but #{act} was thrown'\n          , 'expected #{this} to not throw #{exp}'\n          , (desiredError instanceof Error ? desiredError.toString() : desiredError)\n          , (err instanceof Error ? err.toString() : err)\n        );\n\n        flag(this, 'object', err);\n        return this;\n      }\n\n      // next, check constructor\n      if (constructor) {\n        this.assert(\n            err instanceof constructor\n          , 'expected #{this} to throw #{exp} but #{act} was thrown'\n          , 'expected #{this} to not throw #{exp} but #{act} was thrown'\n          , name\n          , (err instanceof Error ? err.toString() : err)\n        );\n\n        if (!errMsg) {\n          flag(this, 'object', err);\n          return this;\n        }\n      }\n\n      // next, check message\n      var message = 'error' === _.type(err) && \"message\" in err\n        ? err.message\n        : '' + err;\n\n      if ((message != null) && errMsg && errMsg instanceof RegExp) {\n        this.assert(\n            errMsg.exec(message)\n          , 'expected #{this} to throw error matching #{exp} but got #{act}'\n          , 'expected #{this} to throw error not matching #{exp}'\n          , errMsg\n          , message\n        );\n\n        flag(this, 'object', err);\n        return this;\n      } else if ((message != null) && errMsg && 'string' === typeof errMsg) {\n        this.assert(\n            ~message.indexOf(errMsg)\n          , 'expected #{this} to throw error including #{exp} but got #{act}'\n          , 'expected #{this} to throw error not including #{act}'\n          , errMsg\n          , message\n        );\n\n        flag(this, 'object', err);\n        return this;\n      } else {\n        thrown = true;\n        thrownError = err;\n      }\n    }\n\n    var actuallyGot = ''\n      , expectedThrown = name !== null\n        ? name\n        : desiredError\n          ? '#{exp}' //_.inspect(desiredError)\n          : 'an error';\n\n    if (thrown) {\n      actuallyGot = ' but #{act} was thrown'\n    }\n\n    this.assert(\n        thrown === true\n      , 'expected #{this} to throw ' + expectedThrown + actuallyGot\n      , 'expected #{this} to not throw ' + expectedThrown + actuallyGot\n      , (desiredError instanceof Error ? desiredError.toString() : desiredError)\n      , (thrownError instanceof Error ? thrownError.toString() : thrownError)\n    );\n\n    flag(this, 'object', thrownError);\n  };\n\n  Assertion.addMethod('throw', assertThrows);\n  Assertion.addMethod('throws', assertThrows);\n  Assertion.addMethod('Throw', assertThrows);\n\n  /**\n   * ### .respondTo(method)\n   *\n   * Asserts that the object or class target will respond to a method.\n   *\n   *     Klass.prototype.bar = function(){};\n   *     expect(Klass).to.respondTo('bar');\n   *     expect(obj).to.respondTo('bar');\n   *\n   * To check if a constructor will respond to a static function,\n   * set the `itself` flag.\n   *\n   *     Klass.baz = function(){};\n   *     expect(Klass).itself.to.respondTo('baz');\n   *\n   * @name respondTo\n   * @alias respondsTo\n   * @param {String} method\n   * @param {String} message _optional_\n   * @namespace BDD\n   * @api public\n   */\n\n  function respondTo (method, msg) {\n    if (msg) flag(this, 'message', msg);\n    var obj = flag(this, 'object')\n      , itself = flag(this, 'itself')\n      , context = ('function' === _.type(obj) && !itself)\n        ? obj.prototype[method]\n        : obj[method];\n\n    this.assert(\n        'function' === typeof context\n      , 'expected #{this} to respond to ' + _.inspect(method)\n      , 'expected #{this} to not respond to ' + _.inspect(method)\n    );\n  }\n\n  Assertion.addMethod('respondTo', respondTo);\n  Assertion.addMethod('respondsTo', respondTo);\n\n  /**\n   * ### .itself\n   *\n   * Sets the `itself` flag, later used by the `respondTo` assertion.\n   *\n   *     function Foo() {}\n   *     Foo.bar = function() {}\n   *     Foo.prototype.baz = function() {}\n   *\n   *     expect(Foo).itself.to.respondTo('bar');\n   *     expect(Foo).itself.not.to.respondTo('baz');\n   *\n   * @name itself\n   * @namespace BDD\n   * @api public\n   */\n\n  Assertion.addProperty('itself', function () {\n    flag(this, 'itself', true);\n  });\n\n  /**\n   * ### .satisfy(method)\n   *\n   * Asserts that the target passes a given truth test.\n   *\n   *     expect(1).to.satisfy(function(num) { return num > 0; });\n   *\n   * @name satisfy\n   * @alias satisfies\n   * @param {Function} matcher\n   * @param {String} message _optional_\n   * @namespace BDD\n   * @api public\n   */\n\n  function satisfy (matcher, msg) {\n    if (msg) flag(this, 'message', msg);\n    var obj = flag(this, 'object');\n    var result = matcher(obj);\n    this.assert(\n        result\n      , 'expected #{this} to satisfy ' + _.objDisplay(matcher)\n      , 'expected #{this} to not satisfy' + _.objDisplay(matcher)\n      , this.negate ? false : true\n      , result\n    );\n  }\n\n  Assertion.addMethod('satisfy', satisfy);\n  Assertion.addMethod('satisfies', satisfy);\n\n  /**\n   * ### .closeTo(expected, delta)\n   *\n   * Asserts that the target is equal `expected`, to within a +/- `delta` range.\n   *\n   *     expect(1.5).to.be.closeTo(1, 0.5);\n   *\n   * @name closeTo\n   * @alias approximately\n   * @param {Number} expected\n   * @param {Number} delta\n   * @param {String} message _optional_\n   * @namespace BDD\n   * @api public\n   */\n\n  function closeTo(expected, delta, msg) {\n    if (msg) flag(this, 'message', msg);\n    var obj = flag(this, 'object');\n\n    new Assertion(obj, msg).is.a('number');\n    if (_.type(expected) !== 'number' || _.type(delta) !== 'number') {\n      throw new Error('the arguments to closeTo or approximately must be numbers');\n    }\n\n    this.assert(\n        Math.abs(obj - expected) <= delta\n      , 'expected #{this} to be close to ' + expected + ' +/- ' + delta\n      , 'expected #{this} not to be close to ' + expected + ' +/- ' + delta\n    );\n  }\n\n  Assertion.addMethod('closeTo', closeTo);\n  Assertion.addMethod('approximately', closeTo);\n\n  function isSubsetOf(subset, superset, cmp) {\n    return subset.every(function(elem) {\n      if (!cmp) return superset.indexOf(elem) !== -1;\n\n      return superset.some(function(elem2) {\n        return cmp(elem, elem2);\n      });\n    })\n  }\n\n  /**\n   * ### .members(set)\n   *\n   * Asserts that the target is a superset of `set`,\n   * or that the target and `set` have the same strictly-equal (===) members.\n   * Alternately, if the `deep` flag is set, set members are compared for deep\n   * equality.\n   *\n   *     expect([1, 2, 3]).to.include.members([3, 2]);\n   *     expect([1, 2, 3]).to.not.include.members([3, 2, 8]);\n   *\n   *     expect([4, 2]).to.have.members([2, 4]);\n   *     expect([5, 2]).to.not.have.members([5, 2, 1]);\n   *\n   *     expect([{ id: 1 }]).to.deep.include.members([{ id: 1 }]);\n   *\n   * @name members\n   * @param {Array} set\n   * @param {String} message _optional_\n   * @namespace BDD\n   * @api public\n   */\n\n  Assertion.addMethod('members', function (subset, msg) {\n    if (msg) flag(this, 'message', msg);\n    var obj = flag(this, 'object');\n\n    new Assertion(obj).to.be.an('array');\n    new Assertion(subset).to.be.an('array');\n\n    var cmp = flag(this, 'deep') ? _.eql : undefined;\n\n    if (flag(this, 'contains')) {\n      return this.assert(\n          isSubsetOf(subset, obj, cmp)\n        , 'expected #{this} to be a superset of #{act}'\n        , 'expected #{this} to not be a superset of #{act}'\n        , obj\n        , subset\n      );\n    }\n\n    this.assert(\n        isSubsetOf(obj, subset, cmp) && isSubsetOf(subset, obj, cmp)\n        , 'expected #{this} to have the same members as #{act}'\n        , 'expected #{this} to not have the same members as #{act}'\n        , obj\n        , subset\n    );\n  });\n\n  /**\n   * ### .oneOf(list)\n   *\n   * Assert that a value appears somewhere in the top level of array `list`.\n   *\n   *     expect('a').to.be.oneOf(['a', 'b', 'c']);\n   *     expect(9).to.not.be.oneOf(['z']);\n   *     expect([3]).to.not.be.oneOf([1, 2, [3]]);\n   *\n   *     var three = [3];\n   *     // for object-types, contents are not compared\n   *     expect(three).to.not.be.oneOf([1, 2, [3]]);\n   *     // comparing references works\n   *     expect(three).to.be.oneOf([1, 2, three]);\n   *\n   * @name oneOf\n   * @param {Array<*>} list\n   * @param {String} message _optional_\n   * @namespace BDD\n   * @api public\n   */\n\n  function oneOf (list, msg) {\n    if (msg) flag(this, 'message', msg);\n    var expected = flag(this, 'object');\n    new Assertion(list).to.be.an('array');\n\n    this.assert(\n        list.indexOf(expected) > -1\n      , 'expected #{this} to be one of #{exp}'\n      , 'expected #{this} to not be one of #{exp}'\n      , list\n      , expected\n    );\n  }\n\n  Assertion.addMethod('oneOf', oneOf);\n\n\n  /**\n   * ### .change(function)\n   *\n   * Asserts that a function changes an object property\n   *\n   *     var obj = { val: 10 };\n   *     var fn = function() { obj.val += 3 };\n   *     var noChangeFn = function() { return 'foo' + 'bar'; }\n   *     expect(fn).to.change(obj, 'val');\n   *     expect(noChangeFn).to.not.change(obj, 'val')\n   *\n   * @name change\n   * @alias changes\n   * @alias Change\n   * @param {String} object\n   * @param {String} property name\n   * @param {String} message _optional_\n   * @namespace BDD\n   * @api public\n   */\n\n  function assertChanges (object, prop, msg) {\n    if (msg) flag(this, 'message', msg);\n    var fn = flag(this, 'object');\n    new Assertion(object, msg).to.have.property(prop);\n    new Assertion(fn).is.a('function');\n\n    var initial = object[prop];\n    fn();\n\n    this.assert(\n      initial !== object[prop]\n      , 'expected .' + prop + ' to change'\n      , 'expected .' + prop + ' to not change'\n    );\n  }\n\n  Assertion.addChainableMethod('change', assertChanges);\n  Assertion.addChainableMethod('changes', assertChanges);\n\n  /**\n   * ### .increase(function)\n   *\n   * Asserts that a function increases an object property\n   *\n   *     var obj = { val: 10 };\n   *     var fn = function() { obj.val = 15 };\n   *     expect(fn).to.increase(obj, 'val');\n   *\n   * @name increase\n   * @alias increases\n   * @alias Increase\n   * @param {String} object\n   * @param {String} property name\n   * @param {String} message _optional_\n   * @namespace BDD\n   * @api public\n   */\n\n  function assertIncreases (object, prop, msg) {\n    if (msg) flag(this, 'message', msg);\n    var fn = flag(this, 'object');\n    new Assertion(object, msg).to.have.property(prop);\n    new Assertion(fn).is.a('function');\n\n    var initial = object[prop];\n    fn();\n\n    this.assert(\n      object[prop] - initial > 0\n      , 'expected .' + prop + ' to increase'\n      , 'expected .' + prop + ' to not increase'\n    );\n  }\n\n  Assertion.addChainableMethod('increase', assertIncreases);\n  Assertion.addChainableMethod('increases', assertIncreases);\n\n  /**\n   * ### .decrease(function)\n   *\n   * Asserts that a function decreases an object property\n   *\n   *     var obj = { val: 10 };\n   *     var fn = function() { obj.val = 5 };\n   *     expect(fn).to.decrease(obj, 'val');\n   *\n   * @name decrease\n   * @alias decreases\n   * @alias Decrease\n   * @param {String} object\n   * @param {String} property name\n   * @param {String} message _optional_\n   * @namespace BDD\n   * @api public\n   */\n\n  function assertDecreases (object, prop, msg) {\n    if (msg) flag(this, 'message', msg);\n    var fn = flag(this, 'object');\n    new Assertion(object, msg).to.have.property(prop);\n    new Assertion(fn).is.a('function');\n\n    var initial = object[prop];\n    fn();\n\n    this.assert(\n      object[prop] - initial < 0\n      , 'expected .' + prop + ' to decrease'\n      , 'expected .' + prop + ' to not decrease'\n    );\n  }\n\n  Assertion.addChainableMethod('decrease', assertDecreases);\n  Assertion.addChainableMethod('decreases', assertDecreases);\n\n  /**\n   * ### .extensible\n   *\n   * Asserts that the target is extensible (can have new properties added to\n   * it).\n   *\n   *     var nonExtensibleObject = Object.preventExtensions({});\n   *     var sealedObject = Object.seal({});\n   *     var frozenObject = Object.freeze({});\n   *\n   *     expect({}).to.be.extensible;\n   *     expect(nonExtensibleObject).to.not.be.extensible;\n   *     expect(sealedObject).to.not.be.extensible;\n   *     expect(frozenObject).to.not.be.extensible;\n   *\n   * @name extensible\n   * @namespace BDD\n   * @api public\n   */\n\n  Assertion.addProperty('extensible', function() {\n    var obj = flag(this, 'object');\n\n    // In ES5, if the argument to this method is not an object (a primitive), then it will cause a TypeError.\n    // In ES6, a non-object argument will be treated as if it was a non-extensible ordinary object, simply return false.\n    // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/isExtensible\n    // The following provides ES6 behavior when a TypeError is thrown under ES5.\n\n    var isExtensible;\n\n    try {\n      isExtensible = Object.isExtensible(obj);\n    } catch (err) {\n      if (err instanceof TypeError) isExtensible = false;\n      else throw err;\n    }\n\n    this.assert(\n      isExtensible\n      , 'expected #{this} to be extensible'\n      , 'expected #{this} to not be extensible'\n    );\n  });\n\n  /**\n   * ### .sealed\n   *\n   * Asserts that the target is sealed (cannot have new properties added to it\n   * and its existing properties cannot be removed).\n   *\n   *     var sealedObject = Object.seal({});\n   *     var frozenObject = Object.freeze({});\n   *\n   *     expect(sealedObject).to.be.sealed;\n   *     expect(frozenObject).to.be.sealed;\n   *     expect({}).to.not.be.sealed;\n   *\n   * @name sealed\n   * @namespace BDD\n   * @api public\n   */\n\n  Assertion.addProperty('sealed', function() {\n    var obj = flag(this, 'object');\n\n    // In ES5, if the argument to this method is not an object (a primitive), then it will cause a TypeError.\n    // In ES6, a non-object argument will be treated as if it was a sealed ordinary object, simply return true.\n    // See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/isSealed\n    // The following provides ES6 behavior when a TypeError is thrown under ES5.\n\n    var isSealed;\n\n    try {\n      isSealed = Object.isSealed(obj);\n    } catch (err) {\n      if (err instanceof TypeError) isSealed = true;\n      else throw err;\n    }\n\n    this.assert(\n      isSealed\n      , 'expected #{this} to be sealed'\n      , 'expected #{this} to not be sealed'\n    );\n  });\n\n  /**\n   * ### .frozen\n   *\n   * Asserts that the target is frozen (cannot have new properties added to it\n   * and its existing properties cannot be modified).\n   *\n   *     var frozenObject = Object.freeze({});\n   *\n   *     expect(frozenObject).to.be.frozen;\n   *     expect({}).to.not.be.frozen;\n   *\n   * @name frozen\n   * @namespace BDD\n   * @api public\n   */\n\n  Assertion.addProperty('frozen', function() {\n    var obj = flag(this, 'object');\n\n    // In ES5, if the argument to this method is not an object (a primitive), then it will cause a TypeError.\n    // In ES6, a non-object argument will be treated as if it was a frozen ordinary object, simply return true.\n    // See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/isFrozen\n    // The following provides ES6 behavior when a TypeError is thrown under ES5.\n\n    var isFrozen;\n\n    try {\n      isFrozen = Object.isFrozen(obj);\n    } catch (err) {\n      if (err instanceof TypeError) isFrozen = true;\n      else throw err;\n    }\n\n    this.assert(\n      isFrozen\n      , 'expected #{this} to be frozen'\n      , 'expected #{this} to not be frozen'\n    );\n  });\n};\n\n},{}],6:[function(require,module,exports){\n/*!\n * chai\n * Copyright(c) 2011-2014 Jake Luer <jake@alogicalparadox.com>\n * MIT Licensed\n */\n\n\nmodule.exports = function (chai, util) {\n\n  /*!\n   * Chai dependencies.\n   */\n\n  var Assertion = chai.Assertion\n    , flag = util.flag;\n\n  /*!\n   * Module export.\n   */\n\n  /**\n   * ### assert(expression, message)\n   *\n   * Write your own test expressions.\n   *\n   *     assert('foo' !== 'bar', 'foo is not bar');\n   *     assert(Array.isArray([]), 'empty arrays are arrays');\n   *\n   * @param {Mixed} expression to test for truthiness\n   * @param {String} message to display on error\n   * @name assert\n   * @namespace Assert\n   * @api public\n   */\n\n  var assert = chai.assert = function (express, errmsg) {\n    var test = new Assertion(null, null, chai.assert);\n    test.assert(\n        express\n      , errmsg\n      , '[ negation message unavailable ]'\n    );\n  };\n\n  /**\n   * ### .fail(actual, expected, [message], [operator])\n   *\n   * Throw a failure. Node.js `assert` module-compatible.\n   *\n   * @name fail\n   * @param {Mixed} actual\n   * @param {Mixed} expected\n   * @param {String} message\n   * @param {String} operator\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.fail = function (actual, expected, message, operator) {\n    message = message || 'assert.fail()';\n    throw new chai.AssertionError(message, {\n        actual: actual\n      , expected: expected\n      , operator: operator\n    }, assert.fail);\n  };\n\n  /**\n   * ### .isOk(object, [message])\n   *\n   * Asserts that `object` is truthy.\n   *\n   *     assert.isOk('everything', 'everything is ok');\n   *     assert.isOk(false, 'this will fail');\n   *\n   * @name isOk\n   * @alias ok\n   * @param {Mixed} object to test\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.isOk = function (val, msg) {\n    new Assertion(val, msg).is.ok;\n  };\n\n  /**\n   * ### .isNotOk(object, [message])\n   *\n   * Asserts that `object` is falsy.\n   *\n   *     assert.isNotOk('everything', 'this will fail');\n   *     assert.isNotOk(false, 'this will pass');\n   *\n   * @name isNotOk\n   * @alias notOk\n   * @param {Mixed} object to test\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.isNotOk = function (val, msg) {\n    new Assertion(val, msg).is.not.ok;\n  };\n\n  /**\n   * ### .equal(actual, expected, [message])\n   *\n   * Asserts non-strict equality (`==`) of `actual` and `expected`.\n   *\n   *     assert.equal(3, '3', '== coerces values to strings');\n   *\n   * @name equal\n   * @param {Mixed} actual\n   * @param {Mixed} expected\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.equal = function (act, exp, msg) {\n    var test = new Assertion(act, msg, assert.equal);\n\n    test.assert(\n        exp == flag(test, 'object')\n      , 'expected #{this} to equal #{exp}'\n      , 'expected #{this} to not equal #{act}'\n      , exp\n      , act\n    );\n  };\n\n  /**\n   * ### .notEqual(actual, expected, [message])\n   *\n   * Asserts non-strict inequality (`!=`) of `actual` and `expected`.\n   *\n   *     assert.notEqual(3, 4, 'these numbers are not equal');\n   *\n   * @name notEqual\n   * @param {Mixed} actual\n   * @param {Mixed} expected\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.notEqual = function (act, exp, msg) {\n    var test = new Assertion(act, msg, assert.notEqual);\n\n    test.assert(\n        exp != flag(test, 'object')\n      , 'expected #{this} to not equal #{exp}'\n      , 'expected #{this} to equal #{act}'\n      , exp\n      , act\n    );\n  };\n\n  /**\n   * ### .strictEqual(actual, expected, [message])\n   *\n   * Asserts strict equality (`===`) of `actual` and `expected`.\n   *\n   *     assert.strictEqual(true, true, 'these booleans are strictly equal');\n   *\n   * @name strictEqual\n   * @param {Mixed} actual\n   * @param {Mixed} expected\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.strictEqual = function (act, exp, msg) {\n    new Assertion(act, msg).to.equal(exp);\n  };\n\n  /**\n   * ### .notStrictEqual(actual, expected, [message])\n   *\n   * Asserts strict inequality (`!==`) of `actual` and `expected`.\n   *\n   *     assert.notStrictEqual(3, '3', 'no coercion for strict equality');\n   *\n   * @name notStrictEqual\n   * @param {Mixed} actual\n   * @param {Mixed} expected\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.notStrictEqual = function (act, exp, msg) {\n    new Assertion(act, msg).to.not.equal(exp);\n  };\n\n  /**\n   * ### .deepEqual(actual, expected, [message])\n   *\n   * Asserts that `actual` is deeply equal to `expected`.\n   *\n   *     assert.deepEqual({ tea: 'green' }, { tea: 'green' });\n   *\n   * @name deepEqual\n   * @param {Mixed} actual\n   * @param {Mixed} expected\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.deepEqual = function (act, exp, msg) {\n    new Assertion(act, msg).to.eql(exp);\n  };\n\n  /**\n   * ### .notDeepEqual(actual, expected, [message])\n   *\n   * Assert that `actual` is not deeply equal to `expected`.\n   *\n   *     assert.notDeepEqual({ tea: 'green' }, { tea: 'jasmine' });\n   *\n   * @name notDeepEqual\n   * @param {Mixed} actual\n   * @param {Mixed} expected\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.notDeepEqual = function (act, exp, msg) {\n    new Assertion(act, msg).to.not.eql(exp);\n  };\n\n   /**\n   * ### .isAbove(valueToCheck, valueToBeAbove, [message])\n   *\n   * Asserts `valueToCheck` is strictly greater than (>) `valueToBeAbove`\n   *\n   *     assert.isAbove(5, 2, '5 is strictly greater than 2');\n   *\n   * @name isAbove\n   * @param {Mixed} valueToCheck\n   * @param {Mixed} valueToBeAbove\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.isAbove = function (val, abv, msg) {\n    new Assertion(val, msg).to.be.above(abv);\n  };\n\n   /**\n   * ### .isAtLeast(valueToCheck, valueToBeAtLeast, [message])\n   *\n   * Asserts `valueToCheck` is greater than or equal to (>=) `valueToBeAtLeast`\n   *\n   *     assert.isAtLeast(5, 2, '5 is greater or equal to 2');\n   *     assert.isAtLeast(3, 3, '3 is greater or equal to 3');\n   *\n   * @name isAtLeast\n   * @param {Mixed} valueToCheck\n   * @param {Mixed} valueToBeAtLeast\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.isAtLeast = function (val, atlst, msg) {\n    new Assertion(val, msg).to.be.least(atlst);\n  };\n\n   /**\n   * ### .isBelow(valueToCheck, valueToBeBelow, [message])\n   *\n   * Asserts `valueToCheck` is strictly less than (<) `valueToBeBelow`\n   *\n   *     assert.isBelow(3, 6, '3 is strictly less than 6');\n   *\n   * @name isBelow\n   * @param {Mixed} valueToCheck\n   * @param {Mixed} valueToBeBelow\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.isBelow = function (val, blw, msg) {\n    new Assertion(val, msg).to.be.below(blw);\n  };\n\n   /**\n   * ### .isAtMost(valueToCheck, valueToBeAtMost, [message])\n   *\n   * Asserts `valueToCheck` is less than or equal to (<=) `valueToBeAtMost`\n   *\n   *     assert.isAtMost(3, 6, '3 is less than or equal to 6');\n   *     assert.isAtMost(4, 4, '4 is less than or equal to 4');\n   *\n   * @name isAtMost\n   * @param {Mixed} valueToCheck\n   * @param {Mixed} valueToBeAtMost\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.isAtMost = function (val, atmst, msg) {\n    new Assertion(val, msg).to.be.most(atmst);\n  };\n\n  /**\n   * ### .isTrue(value, [message])\n   *\n   * Asserts that `value` is true.\n   *\n   *     var teaServed = true;\n   *     assert.isTrue(teaServed, 'the tea has been served');\n   *\n   * @name isTrue\n   * @param {Mixed} value\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.isTrue = function (val, msg) {\n    new Assertion(val, msg).is['true'];\n  };\n\n  /**\n   * ### .isNotTrue(value, [message])\n   *\n   * Asserts that `value` is not true.\n   *\n   *     var tea = 'tasty chai';\n   *     assert.isNotTrue(tea, 'great, time for tea!');\n   *\n   * @name isNotTrue\n   * @param {Mixed} value\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.isNotTrue = function (val, msg) {\n    new Assertion(val, msg).to.not.equal(true);\n  };\n\n  /**\n   * ### .isFalse(value, [message])\n   *\n   * Asserts that `value` is false.\n   *\n   *     var teaServed = false;\n   *     assert.isFalse(teaServed, 'no tea yet? hmm...');\n   *\n   * @name isFalse\n   * @param {Mixed} value\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.isFalse = function (val, msg) {\n    new Assertion(val, msg).is['false'];\n  };\n\n  /**\n   * ### .isNotFalse(value, [message])\n   *\n   * Asserts that `value` is not false.\n   *\n   *     var tea = 'tasty chai';\n   *     assert.isNotFalse(tea, 'great, time for tea!');\n   *\n   * @name isNotFalse\n   * @param {Mixed} value\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.isNotFalse = function (val, msg) {\n    new Assertion(val, msg).to.not.equal(false);\n  };\n\n  /**\n   * ### .isNull(value, [message])\n   *\n   * Asserts that `value` is null.\n   *\n   *     assert.isNull(err, 'there was no error');\n   *\n   * @name isNull\n   * @param {Mixed} value\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.isNull = function (val, msg) {\n    new Assertion(val, msg).to.equal(null);\n  };\n\n  /**\n   * ### .isNotNull(value, [message])\n   *\n   * Asserts that `value` is not null.\n   *\n   *     var tea = 'tasty chai';\n   *     assert.isNotNull(tea, 'great, time for tea!');\n   *\n   * @name isNotNull\n   * @param {Mixed} value\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.isNotNull = function (val, msg) {\n    new Assertion(val, msg).to.not.equal(null);\n  };\n\n  /**\n   * ### .isNaN\n   * Asserts that value is NaN\n   *\n   *    assert.isNaN('foo', 'foo is NaN');\n   *\n   * @name isNaN\n   * @param {Mixed} value\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.isNaN = function (val, msg) {\n    new Assertion(val, msg).to.be.NaN;\n  };\n\n  /**\n   * ### .isNotNaN\n   * Asserts that value is not NaN\n   *\n   *    assert.isNotNaN(4, '4 is not NaN');\n   *\n   * @name isNotNaN\n   * @param {Mixed} value\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n  assert.isNotNaN = function (val, msg) {\n    new Assertion(val, msg).not.to.be.NaN;\n  };\n\n  /**\n   * ### .isUndefined(value, [message])\n   *\n   * Asserts that `value` is `undefined`.\n   *\n   *     var tea;\n   *     assert.isUndefined(tea, 'no tea defined');\n   *\n   * @name isUndefined\n   * @param {Mixed} value\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.isUndefined = function (val, msg) {\n    new Assertion(val, msg).to.equal(undefined);\n  };\n\n  /**\n   * ### .isDefined(value, [message])\n   *\n   * Asserts that `value` is not `undefined`.\n   *\n   *     var tea = 'cup of chai';\n   *     assert.isDefined(tea, 'tea has been defined');\n   *\n   * @name isDefined\n   * @param {Mixed} value\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.isDefined = function (val, msg) {\n    new Assertion(val, msg).to.not.equal(undefined);\n  };\n\n  /**\n   * ### .isFunction(value, [message])\n   *\n   * Asserts that `value` is a function.\n   *\n   *     function serveTea() { return 'cup of tea'; };\n   *     assert.isFunction(serveTea, 'great, we can have tea now');\n   *\n   * @name isFunction\n   * @param {Mixed} value\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.isFunction = function (val, msg) {\n    new Assertion(val, msg).to.be.a('function');\n  };\n\n  /**\n   * ### .isNotFunction(value, [message])\n   *\n   * Asserts that `value` is _not_ a function.\n   *\n   *     var serveTea = [ 'heat', 'pour', 'sip' ];\n   *     assert.isNotFunction(serveTea, 'great, we have listed the steps');\n   *\n   * @name isNotFunction\n   * @param {Mixed} value\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.isNotFunction = function (val, msg) {\n    new Assertion(val, msg).to.not.be.a('function');\n  };\n\n  /**\n   * ### .isObject(value, [message])\n   *\n   * Asserts that `value` is an object of type 'Object' (as revealed by `Object.prototype.toString`).\n   * _The assertion does not match subclassed objects._\n   *\n   *     var selection = { name: 'Chai', serve: 'with spices' };\n   *     assert.isObject(selection, 'tea selection is an object');\n   *\n   * @name isObject\n   * @param {Mixed} value\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.isObject = function (val, msg) {\n    new Assertion(val, msg).to.be.a('object');\n  };\n\n  /**\n   * ### .isNotObject(value, [message])\n   *\n   * Asserts that `value` is _not_ an object of type 'Object' (as revealed by `Object.prototype.toString`).\n   *\n   *     var selection = 'chai'\n   *     assert.isNotObject(selection, 'tea selection is not an object');\n   *     assert.isNotObject(null, 'null is not an object');\n   *\n   * @name isNotObject\n   * @param {Mixed} value\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.isNotObject = function (val, msg) {\n    new Assertion(val, msg).to.not.be.a('object');\n  };\n\n  /**\n   * ### .isArray(value, [message])\n   *\n   * Asserts that `value` is an array.\n   *\n   *     var menu = [ 'green', 'chai', 'oolong' ];\n   *     assert.isArray(menu, 'what kind of tea do we want?');\n   *\n   * @name isArray\n   * @param {Mixed} value\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.isArray = function (val, msg) {\n    new Assertion(val, msg).to.be.an('array');\n  };\n\n  /**\n   * ### .isNotArray(value, [message])\n   *\n   * Asserts that `value` is _not_ an array.\n   *\n   *     var menu = 'green|chai|oolong';\n   *     assert.isNotArray(menu, 'what kind of tea do we want?');\n   *\n   * @name isNotArray\n   * @param {Mixed} value\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.isNotArray = function (val, msg) {\n    new Assertion(val, msg).to.not.be.an('array');\n  };\n\n  /**\n   * ### .isString(value, [message])\n   *\n   * Asserts that `value` is a string.\n   *\n   *     var teaOrder = 'chai';\n   *     assert.isString(teaOrder, 'order placed');\n   *\n   * @name isString\n   * @param {Mixed} value\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.isString = function (val, msg) {\n    new Assertion(val, msg).to.be.a('string');\n  };\n\n  /**\n   * ### .isNotString(value, [message])\n   *\n   * Asserts that `value` is _not_ a string.\n   *\n   *     var teaOrder = 4;\n   *     assert.isNotString(teaOrder, 'order placed');\n   *\n   * @name isNotString\n   * @param {Mixed} value\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.isNotString = function (val, msg) {\n    new Assertion(val, msg).to.not.be.a('string');\n  };\n\n  /**\n   * ### .isNumber(value, [message])\n   *\n   * Asserts that `value` is a number.\n   *\n   *     var cups = 2;\n   *     assert.isNumber(cups, 'how many cups');\n   *\n   * @name isNumber\n   * @param {Number} value\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.isNumber = function (val, msg) {\n    new Assertion(val, msg).to.be.a('number');\n  };\n\n  /**\n   * ### .isNotNumber(value, [message])\n   *\n   * Asserts that `value` is _not_ a number.\n   *\n   *     var cups = '2 cups please';\n   *     assert.isNotNumber(cups, 'how many cups');\n   *\n   * @name isNotNumber\n   * @param {Mixed} value\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.isNotNumber = function (val, msg) {\n    new Assertion(val, msg).to.not.be.a('number');\n  };\n\n  /**\n   * ### .isBoolean(value, [message])\n   *\n   * Asserts that `value` is a boolean.\n   *\n   *     var teaReady = true\n   *       , teaServed = false;\n   *\n   *     assert.isBoolean(teaReady, 'is the tea ready');\n   *     assert.isBoolean(teaServed, 'has tea been served');\n   *\n   * @name isBoolean\n   * @param {Mixed} value\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.isBoolean = function (val, msg) {\n    new Assertion(val, msg).to.be.a('boolean');\n  };\n\n  /**\n   * ### .isNotBoolean(value, [message])\n   *\n   * Asserts that `value` is _not_ a boolean.\n   *\n   *     var teaReady = 'yep'\n   *       , teaServed = 'nope';\n   *\n   *     assert.isNotBoolean(teaReady, 'is the tea ready');\n   *     assert.isNotBoolean(teaServed, 'has tea been served');\n   *\n   * @name isNotBoolean\n   * @param {Mixed} value\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.isNotBoolean = function (val, msg) {\n    new Assertion(val, msg).to.not.be.a('boolean');\n  };\n\n  /**\n   * ### .typeOf(value, name, [message])\n   *\n   * Asserts that `value`'s type is `name`, as determined by\n   * `Object.prototype.toString`.\n   *\n   *     assert.typeOf({ tea: 'chai' }, 'object', 'we have an object');\n   *     assert.typeOf(['chai', 'jasmine'], 'array', 'we have an array');\n   *     assert.typeOf('tea', 'string', 'we have a string');\n   *     assert.typeOf(/tea/, 'regexp', 'we have a regular expression');\n   *     assert.typeOf(null, 'null', 'we have a null');\n   *     assert.typeOf(undefined, 'undefined', 'we have an undefined');\n   *\n   * @name typeOf\n   * @param {Mixed} value\n   * @param {String} name\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.typeOf = function (val, type, msg) {\n    new Assertion(val, msg).to.be.a(type);\n  };\n\n  /**\n   * ### .notTypeOf(value, name, [message])\n   *\n   * Asserts that `value`'s type is _not_ `name`, as determined by\n   * `Object.prototype.toString`.\n   *\n   *     assert.notTypeOf('tea', 'number', 'strings are not numbers');\n   *\n   * @name notTypeOf\n   * @param {Mixed} value\n   * @param {String} typeof name\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.notTypeOf = function (val, type, msg) {\n    new Assertion(val, msg).to.not.be.a(type);\n  };\n\n  /**\n   * ### .instanceOf(object, constructor, [message])\n   *\n   * Asserts that `value` is an instance of `constructor`.\n   *\n   *     var Tea = function (name) { this.name = name; }\n   *       , chai = new Tea('chai');\n   *\n   *     assert.instanceOf(chai, Tea, 'chai is an instance of tea');\n   *\n   * @name instanceOf\n   * @param {Object} object\n   * @param {Constructor} constructor\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.instanceOf = function (val, type, msg) {\n    new Assertion(val, msg).to.be.instanceOf(type);\n  };\n\n  /**\n   * ### .notInstanceOf(object, constructor, [message])\n   *\n   * Asserts `value` is not an instance of `constructor`.\n   *\n   *     var Tea = function (name) { this.name = name; }\n   *       , chai = new String('chai');\n   *\n   *     assert.notInstanceOf(chai, Tea, 'chai is not an instance of tea');\n   *\n   * @name notInstanceOf\n   * @param {Object} object\n   * @param {Constructor} constructor\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.notInstanceOf = function (val, type, msg) {\n    new Assertion(val, msg).to.not.be.instanceOf(type);\n  };\n\n  /**\n   * ### .include(haystack, needle, [message])\n   *\n   * Asserts that `haystack` includes `needle`. Works\n   * for strings and arrays.\n   *\n   *     assert.include('foobar', 'bar', 'foobar contains string \"bar\"');\n   *     assert.include([ 1, 2, 3 ], 3, 'array contains value');\n   *\n   * @name include\n   * @param {Array|String} haystack\n   * @param {Mixed} needle\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.include = function (exp, inc, msg) {\n    new Assertion(exp, msg, assert.include).include(inc);\n  };\n\n  /**\n   * ### .notInclude(haystack, needle, [message])\n   *\n   * Asserts that `haystack` does not include `needle`. Works\n   * for strings and arrays.\n   *\n   *     assert.notInclude('foobar', 'baz', 'string not include substring');\n   *     assert.notInclude([ 1, 2, 3 ], 4, 'array not include contain value');\n   *\n   * @name notInclude\n   * @param {Array|String} haystack\n   * @param {Mixed} needle\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.notInclude = function (exp, inc, msg) {\n    new Assertion(exp, msg, assert.notInclude).not.include(inc);\n  };\n\n  /**\n   * ### .match(value, regexp, [message])\n   *\n   * Asserts that `value` matches the regular expression `regexp`.\n   *\n   *     assert.match('foobar', /^foo/, 'regexp matches');\n   *\n   * @name match\n   * @param {Mixed} value\n   * @param {RegExp} regexp\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.match = function (exp, re, msg) {\n    new Assertion(exp, msg).to.match(re);\n  };\n\n  /**\n   * ### .notMatch(value, regexp, [message])\n   *\n   * Asserts that `value` does not match the regular expression `regexp`.\n   *\n   *     assert.notMatch('foobar', /^foo/, 'regexp does not match');\n   *\n   * @name notMatch\n   * @param {Mixed} value\n   * @param {RegExp} regexp\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.notMatch = function (exp, re, msg) {\n    new Assertion(exp, msg).to.not.match(re);\n  };\n\n  /**\n   * ### .property(object, property, [message])\n   *\n   * Asserts that `object` has a property named by `property`.\n   *\n   *     assert.property({ tea: { green: 'matcha' }}, 'tea');\n   *\n   * @name property\n   * @param {Object} object\n   * @param {String} property\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.property = function (obj, prop, msg) {\n    new Assertion(obj, msg).to.have.property(prop);\n  };\n\n  /**\n   * ### .notProperty(object, property, [message])\n   *\n   * Asserts that `object` does _not_ have a property named by `property`.\n   *\n   *     assert.notProperty({ tea: { green: 'matcha' }}, 'coffee');\n   *\n   * @name notProperty\n   * @param {Object} object\n   * @param {String} property\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.notProperty = function (obj, prop, msg) {\n    new Assertion(obj, msg).to.not.have.property(prop);\n  };\n\n  /**\n   * ### .deepProperty(object, property, [message])\n   *\n   * Asserts that `object` has a property named by `property`, which can be a\n   * string using dot- and bracket-notation for deep reference.\n   *\n   *     assert.deepProperty({ tea: { green: 'matcha' }}, 'tea.green');\n   *\n   * @name deepProperty\n   * @param {Object} object\n   * @param {String} property\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.deepProperty = function (obj, prop, msg) {\n    new Assertion(obj, msg).to.have.deep.property(prop);\n  };\n\n  /**\n   * ### .notDeepProperty(object, property, [message])\n   *\n   * Asserts that `object` does _not_ have a property named by `property`, which\n   * can be a string using dot- and bracket-notation for deep reference.\n   *\n   *     assert.notDeepProperty({ tea: { green: 'matcha' }}, 'tea.oolong');\n   *\n   * @name notDeepProperty\n   * @param {Object} object\n   * @param {String} property\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.notDeepProperty = function (obj, prop, msg) {\n    new Assertion(obj, msg).to.not.have.deep.property(prop);\n  };\n\n  /**\n   * ### .propertyVal(object, property, value, [message])\n   *\n   * Asserts that `object` has a property named by `property` with value given\n   * by `value`.\n   *\n   *     assert.propertyVal({ tea: 'is good' }, 'tea', 'is good');\n   *\n   * @name propertyVal\n   * @param {Object} object\n   * @param {String} property\n   * @param {Mixed} value\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.propertyVal = function (obj, prop, val, msg) {\n    new Assertion(obj, msg).to.have.property(prop, val);\n  };\n\n  /**\n   * ### .propertyNotVal(object, property, value, [message])\n   *\n   * Asserts that `object` has a property named by `property`, but with a value\n   * different from that given by `value`.\n   *\n   *     assert.propertyNotVal({ tea: 'is good' }, 'tea', 'is bad');\n   *\n   * @name propertyNotVal\n   * @param {Object} object\n   * @param {String} property\n   * @param {Mixed} value\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.propertyNotVal = function (obj, prop, val, msg) {\n    new Assertion(obj, msg).to.not.have.property(prop, val);\n  };\n\n  /**\n   * ### .deepPropertyVal(object, property, value, [message])\n   *\n   * Asserts that `object` has a property named by `property` with value given\n   * by `value`. `property` can use dot- and bracket-notation for deep\n   * reference.\n   *\n   *     assert.deepPropertyVal({ tea: { green: 'matcha' }}, 'tea.green', 'matcha');\n   *\n   * @name deepPropertyVal\n   * @param {Object} object\n   * @param {String} property\n   * @param {Mixed} value\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.deepPropertyVal = function (obj, prop, val, msg) {\n    new Assertion(obj, msg).to.have.deep.property(prop, val);\n  };\n\n  /**\n   * ### .deepPropertyNotVal(object, property, value, [message])\n   *\n   * Asserts that `object` has a property named by `property`, but with a value\n   * different from that given by `value`. `property` can use dot- and\n   * bracket-notation for deep reference.\n   *\n   *     assert.deepPropertyNotVal({ tea: { green: 'matcha' }}, 'tea.green', 'konacha');\n   *\n   * @name deepPropertyNotVal\n   * @param {Object} object\n   * @param {String} property\n   * @param {Mixed} value\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.deepPropertyNotVal = function (obj, prop, val, msg) {\n    new Assertion(obj, msg).to.not.have.deep.property(prop, val);\n  };\n\n  /**\n   * ### .lengthOf(object, length, [message])\n   *\n   * Asserts that `object` has a `length` property with the expected value.\n   *\n   *     assert.lengthOf([1,2,3], 3, 'array has length of 3');\n   *     assert.lengthOf('foobar', 6, 'string has length of 6');\n   *\n   * @name lengthOf\n   * @param {Mixed} object\n   * @param {Number} length\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.lengthOf = function (exp, len, msg) {\n    new Assertion(exp, msg).to.have.length(len);\n  };\n\n  /**\n   * ### .throws(function, [constructor/string/regexp], [string/regexp], [message])\n   *\n   * Asserts that `function` will throw an error that is an instance of\n   * `constructor`, or alternately that it will throw an error with message\n   * matching `regexp`.\n   *\n   *     assert.throws(fn, 'function throws a reference error');\n   *     assert.throws(fn, /function throws a reference error/);\n   *     assert.throws(fn, ReferenceError);\n   *     assert.throws(fn, ReferenceError, 'function throws a reference error');\n   *     assert.throws(fn, ReferenceError, /function throws a reference error/);\n   *\n   * @name throws\n   * @alias throw\n   * @alias Throw\n   * @param {Function} function\n   * @param {ErrorConstructor} constructor\n   * @param {RegExp} regexp\n   * @param {String} message\n   * @see https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Error#Error_types\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.throws = function (fn, errt, errs, msg) {\n    if ('string' === typeof errt || errt instanceof RegExp) {\n      errs = errt;\n      errt = null;\n    }\n\n    var assertErr = new Assertion(fn, msg).to.throw(errt, errs);\n    return flag(assertErr, 'object');\n  };\n\n  /**\n   * ### .doesNotThrow(function, [constructor/regexp], [message])\n   *\n   * Asserts that `function` will _not_ throw an error that is an instance of\n   * `constructor`, or alternately that it will not throw an error with message\n   * matching `regexp`.\n   *\n   *     assert.doesNotThrow(fn, Error, 'function does not throw');\n   *\n   * @name doesNotThrow\n   * @param {Function} function\n   * @param {ErrorConstructor} constructor\n   * @param {RegExp} regexp\n   * @param {String} message\n   * @see https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Error#Error_types\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.doesNotThrow = function (fn, type, msg) {\n    if ('string' === typeof type) {\n      msg = type;\n      type = null;\n    }\n\n    new Assertion(fn, msg).to.not.Throw(type);\n  };\n\n  /**\n   * ### .operator(val1, operator, val2, [message])\n   *\n   * Compares two values using `operator`.\n   *\n   *     assert.operator(1, '<', 2, 'everything is ok');\n   *     assert.operator(1, '>', 2, 'this will fail');\n   *\n   * @name operator\n   * @param {Mixed} val1\n   * @param {String} operator\n   * @param {Mixed} val2\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.operator = function (val, operator, val2, msg) {\n    var ok;\n    switch(operator) {\n      case '==':\n        ok = val == val2;\n        break;\n      case '===':\n        ok = val === val2;\n        break;\n      case '>':\n        ok = val > val2;\n        break;\n      case '>=':\n        ok = val >= val2;\n        break;\n      case '<':\n        ok = val < val2;\n        break;\n      case '<=':\n        ok = val <= val2;\n        break;\n      case '!=':\n        ok = val != val2;\n        break;\n      case '!==':\n        ok = val !== val2;\n        break;\n      default:\n        throw new Error('Invalid operator \"' + operator + '\"');\n    }\n    var test = new Assertion(ok, msg);\n    test.assert(\n        true === flag(test, 'object')\n      , 'expected ' + util.inspect(val) + ' to be ' + operator + ' ' + util.inspect(val2)\n      , 'expected ' + util.inspect(val) + ' to not be ' + operator + ' ' + util.inspect(val2) );\n  };\n\n  /**\n   * ### .closeTo(actual, expected, delta, [message])\n   *\n   * Asserts that the target is equal `expected`, to within a +/- `delta` range.\n   *\n   *     assert.closeTo(1.5, 1, 0.5, 'numbers are close');\n   *\n   * @name closeTo\n   * @param {Number} actual\n   * @param {Number} expected\n   * @param {Number} delta\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.closeTo = function (act, exp, delta, msg) {\n    new Assertion(act, msg).to.be.closeTo(exp, delta);\n  };\n\n  /**\n   * ### .approximately(actual, expected, delta, [message])\n   *\n   * Asserts that the target is equal `expected`, to within a +/- `delta` range.\n   *\n   *     assert.approximately(1.5, 1, 0.5, 'numbers are close');\n   *\n   * @name approximately\n   * @param {Number} actual\n   * @param {Number} expected\n   * @param {Number} delta\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.approximately = function (act, exp, delta, msg) {\n    new Assertion(act, msg).to.be.approximately(exp, delta);\n  };\n\n  /**\n   * ### .sameMembers(set1, set2, [message])\n   *\n   * Asserts that `set1` and `set2` have the same members.\n   * Order is not taken into account.\n   *\n   *     assert.sameMembers([ 1, 2, 3 ], [ 2, 1, 3 ], 'same members');\n   *\n   * @name sameMembers\n   * @param {Array} set1\n   * @param {Array} set2\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.sameMembers = function (set1, set2, msg) {\n    new Assertion(set1, msg).to.have.same.members(set2);\n  }\n\n  /**\n   * ### .sameDeepMembers(set1, set2, [message])\n   *\n   * Asserts that `set1` and `set2` have the same members - using a deep equality checking.\n   * Order is not taken into account.\n   *\n   *     assert.sameDeepMembers([ {b: 3}, {a: 2}, {c: 5} ], [ {c: 5}, {b: 3}, {a: 2} ], 'same deep members');\n   *\n   * @name sameDeepMembers\n   * @param {Array} set1\n   * @param {Array} set2\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.sameDeepMembers = function (set1, set2, msg) {\n    new Assertion(set1, msg).to.have.same.deep.members(set2);\n  }\n\n  /**\n   * ### .includeMembers(superset, subset, [message])\n   *\n   * Asserts that `subset` is included in `superset`.\n   * Order is not taken into account.\n   *\n   *     assert.includeMembers([ 1, 2, 3 ], [ 2, 1 ], 'include members');\n   *\n   * @name includeMembers\n   * @param {Array} superset\n   * @param {Array} subset\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.includeMembers = function (superset, subset, msg) {\n    new Assertion(superset, msg).to.include.members(subset);\n  }\n\n  /**\n   * ### .includeDeepMembers(superset, subset, [message])\n   *\n   * Asserts that `subset` is included in `superset` - using deep equality checking.\n   * Order is not taken into account.\n   * Duplicates are ignored.\n   *\n   *     assert.includeDeepMembers([ {a: 1}, {b: 2}, {c: 3} ], [ {b: 2}, {a: 1}, {b: 2} ], 'include deep members');\n   *\n   * @name includeDeepMembers\n   * @param {Array} superset\n   * @param {Array} subset\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.includeDeepMembers = function (superset, subset, msg) {\n    new Assertion(superset, msg).to.include.deep.members(subset);\n  }\n\n  /**\n   * ### .oneOf(inList, list, [message])\n   *\n   * Asserts that non-object, non-array value `inList` appears in the flat array `list`.\n   *\n   *     assert.oneOf(1, [ 2, 1 ], 'Not found in list');\n   *\n   * @name oneOf\n   * @param {*} inList\n   * @param {Array<*>} list\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.oneOf = function (inList, list, msg) {\n    new Assertion(inList, msg).to.be.oneOf(list);\n  }\n\n   /**\n   * ### .changes(function, object, property)\n   *\n   * Asserts that a function changes the value of a property\n   *\n   *     var obj = { val: 10 };\n   *     var fn = function() { obj.val = 22 };\n   *     assert.changes(fn, obj, 'val');\n   *\n   * @name changes\n   * @param {Function} modifier function\n   * @param {Object} object\n   * @param {String} property name\n   * @param {String} message _optional_\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.changes = function (fn, obj, prop) {\n    new Assertion(fn).to.change(obj, prop);\n  }\n\n   /**\n   * ### .doesNotChange(function, object, property)\n   *\n   * Asserts that a function does not changes the value of a property\n   *\n   *     var obj = { val: 10 };\n   *     var fn = function() { console.log('foo'); };\n   *     assert.doesNotChange(fn, obj, 'val');\n   *\n   * @name doesNotChange\n   * @param {Function} modifier function\n   * @param {Object} object\n   * @param {String} property name\n   * @param {String} message _optional_\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.doesNotChange = function (fn, obj, prop) {\n    new Assertion(fn).to.not.change(obj, prop);\n  }\n\n   /**\n   * ### .increases(function, object, property)\n   *\n   * Asserts that a function increases an object property\n   *\n   *     var obj = { val: 10 };\n   *     var fn = function() { obj.val = 13 };\n   *     assert.increases(fn, obj, 'val');\n   *\n   * @name increases\n   * @param {Function} modifier function\n   * @param {Object} object\n   * @param {String} property name\n   * @param {String} message _optional_\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.increases = function (fn, obj, prop) {\n    new Assertion(fn).to.increase(obj, prop);\n  }\n\n   /**\n   * ### .doesNotIncrease(function, object, property)\n   *\n   * Asserts that a function does not increase object property\n   *\n   *     var obj = { val: 10 };\n   *     var fn = function() { obj.val = 8 };\n   *     assert.doesNotIncrease(fn, obj, 'val');\n   *\n   * @name doesNotIncrease\n   * @param {Function} modifier function\n   * @param {Object} object\n   * @param {String} property name\n   * @param {String} message _optional_\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.doesNotIncrease = function (fn, obj, prop) {\n    new Assertion(fn).to.not.increase(obj, prop);\n  }\n\n   /**\n   * ### .decreases(function, object, property)\n   *\n   * Asserts that a function decreases an object property\n   *\n   *     var obj = { val: 10 };\n   *     var fn = function() { obj.val = 5 };\n   *     assert.decreases(fn, obj, 'val');\n   *\n   * @name decreases\n   * @param {Function} modifier function\n   * @param {Object} object\n   * @param {String} property name\n   * @param {String} message _optional_\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.decreases = function (fn, obj, prop) {\n    new Assertion(fn).to.decrease(obj, prop);\n  }\n\n   /**\n   * ### .doesNotDecrease(function, object, property)\n   *\n   * Asserts that a function does not decreases an object property\n   *\n   *     var obj = { val: 10 };\n   *     var fn = function() { obj.val = 15 };\n   *     assert.doesNotDecrease(fn, obj, 'val');\n   *\n   * @name doesNotDecrease\n   * @param {Function} modifier function\n   * @param {Object} object\n   * @param {String} property name\n   * @param {String} message _optional_\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.doesNotDecrease = function (fn, obj, prop) {\n    new Assertion(fn).to.not.decrease(obj, prop);\n  }\n\n  /*!\n   * ### .ifError(object)\n   *\n   * Asserts if value is not a false value, and throws if it is a true value.\n   * This is added to allow for chai to be a drop-in replacement for Node's\n   * assert class.\n   *\n   *     var err = new Error('I am a custom error');\n   *     assert.ifError(err); // Rethrows err!\n   *\n   * @name ifError\n   * @param {Object} object\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.ifError = function (val) {\n    if (val) {\n      throw(val);\n    }\n  };\n\n  /**\n   * ### .isExtensible(object)\n   *\n   * Asserts that `object` is extensible (can have new properties added to it).\n   *\n   *     assert.isExtensible({});\n   *\n   * @name isExtensible\n   * @alias extensible\n   * @param {Object} object\n   * @param {String} message _optional_\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.isExtensible = function (obj, msg) {\n    new Assertion(obj, msg).to.be.extensible;\n  };\n\n  /**\n   * ### .isNotExtensible(object)\n   *\n   * Asserts that `object` is _not_ extensible.\n   *\n   *     var nonExtensibleObject = Object.preventExtensions({});\n   *     var sealedObject = Object.seal({});\n   *     var frozenObject = Object.freese({});\n   *\n   *     assert.isNotExtensible(nonExtensibleObject);\n   *     assert.isNotExtensible(sealedObject);\n   *     assert.isNotExtensible(frozenObject);\n   *\n   * @name isNotExtensible\n   * @alias notExtensible\n   * @param {Object} object\n   * @param {String} message _optional_\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.isNotExtensible = function (obj, msg) {\n    new Assertion(obj, msg).to.not.be.extensible;\n  };\n\n  /**\n   * ### .isSealed(object)\n   *\n   * Asserts that `object` is sealed (cannot have new properties added to it\n   * and its existing properties cannot be removed).\n   *\n   *     var sealedObject = Object.seal({});\n   *     var frozenObject = Object.seal({});\n   *\n   *     assert.isSealed(sealedObject);\n   *     assert.isSealed(frozenObject);\n   *\n   * @name isSealed\n   * @alias sealed\n   * @param {Object} object\n   * @param {String} message _optional_\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.isSealed = function (obj, msg) {\n    new Assertion(obj, msg).to.be.sealed;\n  };\n\n  /**\n   * ### .isNotSealed(object)\n   *\n   * Asserts that `object` is _not_ sealed.\n   *\n   *     assert.isNotSealed({});\n   *\n   * @name isNotSealed\n   * @alias notSealed\n   * @param {Object} object\n   * @param {String} message _optional_\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.isNotSealed = function (obj, msg) {\n    new Assertion(obj, msg).to.not.be.sealed;\n  };\n\n  /**\n   * ### .isFrozen(object)\n   *\n   * Asserts that `object` is frozen (cannot have new properties added to it\n   * and its existing properties cannot be modified).\n   *\n   *     var frozenObject = Object.freeze({});\n   *     assert.frozen(frozenObject);\n   *\n   * @name isFrozen\n   * @alias frozen\n   * @param {Object} object\n   * @param {String} message _optional_\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.isFrozen = function (obj, msg) {\n    new Assertion(obj, msg).to.be.frozen;\n  };\n\n  /**\n   * ### .isNotFrozen(object)\n   *\n   * Asserts that `object` is _not_ frozen.\n   *\n   *     assert.isNotFrozen({});\n   *\n   * @name isNotFrozen\n   * @alias notFrozen\n   * @param {Object} object\n   * @param {String} message _optional_\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.isNotFrozen = function (obj, msg) {\n    new Assertion(obj, msg).to.not.be.frozen;\n  };\n\n  /*!\n   * Aliases.\n   */\n\n  (function alias(name, as){\n    assert[as] = assert[name];\n    return alias;\n  })\n  ('isOk', 'ok')\n  ('isNotOk', 'notOk')\n  ('throws', 'throw')\n  ('throws', 'Throw')\n  ('isExtensible', 'extensible')\n  ('isNotExtensible', 'notExtensible')\n  ('isSealed', 'sealed')\n  ('isNotSealed', 'notSealed')\n  ('isFrozen', 'frozen')\n  ('isNotFrozen', 'notFrozen');\n};\n\n},{}],7:[function(require,module,exports){\n/*!\n * chai\n * Copyright(c) 2011-2014 Jake Luer <jake@alogicalparadox.com>\n * MIT Licensed\n */\n\nmodule.exports = function (chai, util) {\n  chai.expect = function (val, message) {\n    return new chai.Assertion(val, message);\n  };\n\n  /**\n   * ### .fail(actual, expected, [message], [operator])\n   *\n   * Throw a failure.\n   *\n   * @name fail\n   * @param {Mixed} actual\n   * @param {Mixed} expected\n   * @param {String} message\n   * @param {String} operator\n   * @namespace Expect\n   * @api public\n   */\n\n  chai.expect.fail = function (actual, expected, message, operator) {\n    message = message || 'expect.fail()';\n    throw new chai.AssertionError(message, {\n        actual: actual\n      , expected: expected\n      , operator: operator\n    }, chai.expect.fail);\n  };\n};\n\n},{}],8:[function(require,module,exports){\n/*!\n * chai\n * Copyright(c) 2011-2014 Jake Luer <jake@alogicalparadox.com>\n * MIT Licensed\n */\n\nmodule.exports = function (chai, util) {\n  var Assertion = chai.Assertion;\n\n  function loadShould () {\n    // explicitly define this method as function as to have it's name to include as `ssfi`\n    function shouldGetter() {\n      if (this instanceof String || this instanceof Number || this instanceof Boolean ) {\n        return new Assertion(this.valueOf(), null, shouldGetter);\n      }\n      return new Assertion(this, null, shouldGetter);\n    }\n    function shouldSetter(value) {\n      // See https://github.com/chaijs/chai/issues/86: this makes\n      // `whatever.should = someValue` actually set `someValue`, which is\n      // especially useful for `global.should = require('chai').should()`.\n      //\n      // Note that we have to use [[DefineProperty]] instead of [[Put]]\n      // since otherwise we would trigger this very setter!\n      Object.defineProperty(this, 'should', {\n        value: value,\n        enumerable: true,\n        configurable: true,\n        writable: true\n      });\n    }\n    // modify Object.prototype to have `should`\n    Object.defineProperty(Object.prototype, 'should', {\n      set: shouldSetter\n      , get: shouldGetter\n      , configurable: true\n    });\n\n    var should = {};\n\n    /**\n     * ### .fail(actual, expected, [message], [operator])\n     *\n     * Throw a failure.\n     *\n     * @name fail\n     * @param {Mixed} actual\n     * @param {Mixed} expected\n     * @param {String} message\n     * @param {String} operator\n     * @namespace Should\n     * @api public\n     */\n\n    should.fail = function (actual, expected, message, operator) {\n      message = message || 'should.fail()';\n      throw new chai.AssertionError(message, {\n          actual: actual\n        , expected: expected\n        , operator: operator\n      }, should.fail);\n    };\n\n    /**\n     * ### .equal(actual, expected, [message])\n     *\n     * Asserts non-strict equality (`==`) of `actual` and `expected`.\n     *\n     *     should.equal(3, '3', '== coerces values to strings');\n     *\n     * @name equal\n     * @param {Mixed} actual\n     * @param {Mixed} expected\n     * @param {String} message\n     * @namespace Should\n     * @api public\n     */\n\n    should.equal = function (val1, val2, msg) {\n      new Assertion(val1, msg).to.equal(val2);\n    };\n\n    /**\n     * ### .throw(function, [constructor/string/regexp], [string/regexp], [message])\n     *\n     * Asserts that `function` will throw an error that is an instance of\n     * `constructor`, or alternately that it will throw an error with message\n     * matching `regexp`.\n     *\n     *     should.throw(fn, 'function throws a reference error');\n     *     should.throw(fn, /function throws a reference error/);\n     *     should.throw(fn, ReferenceError);\n     *     should.throw(fn, ReferenceError, 'function throws a reference error');\n     *     should.throw(fn, ReferenceError, /function throws a reference error/);\n     *\n     * @name throw\n     * @alias Throw\n     * @param {Function} function\n     * @param {ErrorConstructor} constructor\n     * @param {RegExp} regexp\n     * @param {String} message\n     * @see https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Error#Error_types\n     * @namespace Should\n     * @api public\n     */\n\n    should.Throw = function (fn, errt, errs, msg) {\n      new Assertion(fn, msg).to.Throw(errt, errs);\n    };\n\n    /**\n     * ### .exist\n     *\n     * Asserts that the target is neither `null` nor `undefined`.\n     *\n     *     var foo = 'hi';\n     *\n     *     should.exist(foo, 'foo exists');\n     *\n     * @name exist\n     * @namespace Should\n     * @api public\n     */\n\n    should.exist = function (val, msg) {\n      new Assertion(val, msg).to.exist;\n    }\n\n    // negation\n    should.not = {}\n\n    /**\n     * ### .not.equal(actual, expected, [message])\n     *\n     * Asserts non-strict inequality (`!=`) of `actual` and `expected`.\n     *\n     *     should.not.equal(3, 4, 'these numbers are not equal');\n     *\n     * @name not.equal\n     * @param {Mixed} actual\n     * @param {Mixed} expected\n     * @param {String} message\n     * @namespace Should\n     * @api public\n     */\n\n    should.not.equal = function (val1, val2, msg) {\n      new Assertion(val1, msg).to.not.equal(val2);\n    };\n\n    /**\n     * ### .throw(function, [constructor/regexp], [message])\n     *\n     * Asserts that `function` will _not_ throw an error that is an instance of\n     * `constructor`, or alternately that it will not throw an error with message\n     * matching `regexp`.\n     *\n     *     should.not.throw(fn, Error, 'function does not throw');\n     *\n     * @name not.throw\n     * @alias not.Throw\n     * @param {Function} function\n     * @param {ErrorConstructor} constructor\n     * @param {RegExp} regexp\n     * @param {String} message\n     * @see https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Error#Error_types\n     * @namespace Should\n     * @api public\n     */\n\n    should.not.Throw = function (fn, errt, errs, msg) {\n      new Assertion(fn, msg).to.not.Throw(errt, errs);\n    };\n\n    /**\n     * ### .not.exist\n     *\n     * Asserts that the target is neither `null` nor `undefined`.\n     *\n     *     var bar = null;\n     *\n     *     should.not.exist(bar, 'bar does not exist');\n     *\n     * @name not.exist\n     * @namespace Should\n     * @api public\n     */\n\n    should.not.exist = function (val, msg) {\n      new Assertion(val, msg).to.not.exist;\n    }\n\n    should['throw'] = should['Throw'];\n    should.not['throw'] = should.not['Throw'];\n\n    return should;\n  };\n\n  chai.should = loadShould;\n  chai.Should = loadShould;\n};\n\n},{}],9:[function(require,module,exports){\n/*!\n * Chai - addChainingMethod utility\n * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com>\n * MIT Licensed\n */\n\n/*!\n * Module dependencies\n */\n\nvar transferFlags = require('./transferFlags');\nvar flag = require('./flag');\nvar config = require('../config');\n\n/*!\n * Module variables\n */\n\n// Check whether `__proto__` is supported\nvar hasProtoSupport = '__proto__' in Object;\n\n// Without `__proto__` support, this module will need to add properties to a function.\n// However, some Function.prototype methods cannot be overwritten,\n// and there seems no easy cross-platform way to detect them (@see chaijs/chai/issues/69).\nvar excludeNames = /^(?:length|name|arguments|caller)$/;\n\n// Cache `Function` properties\nvar call  = Function.prototype.call,\n    apply = Function.prototype.apply;\n\n/**\n * ### addChainableMethod (ctx, name, method, chainingBehavior)\n *\n * Adds a method to an object, such that the method can also be chained.\n *\n *     utils.addChainableMethod(chai.Assertion.prototype, 'foo', function (str) {\n *       var obj = utils.flag(this, 'object');\n *       new chai.Assertion(obj).to.be.equal(str);\n *     });\n *\n * Can also be accessed directly from `chai.Assertion`.\n *\n *     chai.Assertion.addChainableMethod('foo', fn, chainingBehavior);\n *\n * The result can then be used as both a method assertion, executing both `method` and\n * `chainingBehavior`, or as a language chain, which only executes `chainingBehavior`.\n *\n *     expect(fooStr).to.be.foo('bar');\n *     expect(fooStr).to.be.foo.equal('foo');\n *\n * @param {Object} ctx object to which the method is added\n * @param {String} name of method to add\n * @param {Function} method function to be used for `name`, when called\n * @param {Function} chainingBehavior function to be called every time the property is accessed\n * @namespace Utils\n * @name addChainableMethod\n * @api public\n */\n\nmodule.exports = function (ctx, name, method, chainingBehavior) {\n  if (typeof chainingBehavior !== 'function') {\n    chainingBehavior = function () { };\n  }\n\n  var chainableBehavior = {\n      method: method\n    , chainingBehavior: chainingBehavior\n  };\n\n  // save the methods so we can overwrite them later, if we need to.\n  if (!ctx.__methods) {\n    ctx.__methods = {};\n  }\n  ctx.__methods[name] = chainableBehavior;\n\n  Object.defineProperty(ctx, name,\n    { get: function () {\n        chainableBehavior.chainingBehavior.call(this);\n\n        var assert = function assert() {\n          var old_ssfi = flag(this, 'ssfi');\n          if (old_ssfi && config.includeStack === false)\n            flag(this, 'ssfi', assert);\n          var result = chainableBehavior.method.apply(this, arguments);\n          return result === undefined ? this : result;\n        };\n\n        // Use `__proto__` if available\n        if (hasProtoSupport) {\n          // Inherit all properties from the object by replacing the `Function` prototype\n          var prototype = assert.__proto__ = Object.create(this);\n          // Restore the `call` and `apply` methods from `Function`\n          prototype.call = call;\n          prototype.apply = apply;\n        }\n        // Otherwise, redefine all properties (slow!)\n        else {\n          var asserterNames = Object.getOwnPropertyNames(ctx);\n          asserterNames.forEach(function (asserterName) {\n            if (!excludeNames.test(asserterName)) {\n              var pd = Object.getOwnPropertyDescriptor(ctx, asserterName);\n              Object.defineProperty(assert, asserterName, pd);\n            }\n          });\n        }\n\n        transferFlags(this, assert);\n        return assert;\n      }\n    , configurable: true\n  });\n};\n\n},{\"../config\":4,\"./flag\":13,\"./transferFlags\":29}],10:[function(require,module,exports){\n/*!\n * Chai - addMethod utility\n * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com>\n * MIT Licensed\n */\n\nvar config = require('../config');\n\n/**\n * ### .addMethod (ctx, name, method)\n *\n * Adds a method to the prototype of an object.\n *\n *     utils.addMethod(chai.Assertion.prototype, 'foo', function (str) {\n *       var obj = utils.flag(this, 'object');\n *       new chai.Assertion(obj).to.be.equal(str);\n *     });\n *\n * Can also be accessed directly from `chai.Assertion`.\n *\n *     chai.Assertion.addMethod('foo', fn);\n *\n * Then can be used as any other assertion.\n *\n *     expect(fooStr).to.be.foo('bar');\n *\n * @param {Object} ctx object to which the method is added\n * @param {String} name of method to add\n * @param {Function} method function to be used for name\n * @namespace Utils\n * @name addMethod\n * @api public\n */\nvar flag = require('./flag');\n\nmodule.exports = function (ctx, name, method) {\n  ctx[name] = function () {\n    var old_ssfi = flag(this, 'ssfi');\n    if (old_ssfi && config.includeStack === false)\n      flag(this, 'ssfi', ctx[name]);\n    var result = method.apply(this, arguments);\n    return result === undefined ? this : result;\n  };\n};\n\n},{\"../config\":4,\"./flag\":13}],11:[function(require,module,exports){\n/*!\n * Chai - addProperty utility\n * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com>\n * MIT Licensed\n */\n\nvar config = require('../config');\nvar flag = require('./flag');\n\n/**\n * ### addProperty (ctx, name, getter)\n *\n * Adds a property to the prototype of an object.\n *\n *     utils.addProperty(chai.Assertion.prototype, 'foo', function () {\n *       var obj = utils.flag(this, 'object');\n *       new chai.Assertion(obj).to.be.instanceof(Foo);\n *     });\n *\n * Can also be accessed directly from `chai.Assertion`.\n *\n *     chai.Assertion.addProperty('foo', fn);\n *\n * Then can be used as any other assertion.\n *\n *     expect(myFoo).to.be.foo;\n *\n * @param {Object} ctx object to which the property is added\n * @param {String} name of property to add\n * @param {Function} getter function to be used for name\n * @namespace Utils\n * @name addProperty\n * @api public\n */\n\nmodule.exports = function (ctx, name, getter) {\n  Object.defineProperty(ctx, name,\n    { get: function addProperty() {\n        var old_ssfi = flag(this, 'ssfi');\n        if (old_ssfi && config.includeStack === false)\n          flag(this, 'ssfi', addProperty);\n\n        var result = getter.call(this);\n        return result === undefined ? this : result;\n      }\n    , configurable: true\n  });\n};\n\n},{\"../config\":4,\"./flag\":13}],12:[function(require,module,exports){\n/*!\n * Chai - expectTypes utility\n * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com>\n * MIT Licensed\n */\n\n/**\n * ### expectTypes(obj, types)\n *\n * Ensures that the object being tested against is of a valid type.\n *\n *     utils.expectTypes(this, ['array', 'object', 'string']);\n *\n * @param {Mixed} obj constructed Assertion\n * @param {Array} type A list of allowed types for this assertion\n * @namespace Utils\n * @name expectTypes\n * @api public\n */\n\nvar AssertionError = require('assertion-error');\nvar flag = require('./flag');\nvar type = require('type-detect');\n\nmodule.exports = function (obj, types) {\n  var obj = flag(obj, 'object');\n  types = types.map(function (t) { return t.toLowerCase(); });\n  types.sort();\n\n  // Transforms ['lorem', 'ipsum'] into 'a lirum, or an ipsum'\n  var str = types.map(function (t, index) {\n    var art = ~[ 'a', 'e', 'i', 'o', 'u' ].indexOf(t.charAt(0)) ? 'an' : 'a';\n    var or = types.length > 1 && index === types.length - 1 ? 'or ' : '';\n    return or + art + ' ' + t;\n  }).join(', ');\n\n  if (!types.some(function (expected) { return type(obj) === expected; })) {\n    throw new AssertionError(\n      'object tested must be ' + str + ', but ' + type(obj) + ' given'\n    );\n  }\n};\n\n},{\"./flag\":13,\"assertion-error\":30,\"type-detect\":35}],13:[function(require,module,exports){\n/*!\n * Chai - flag utility\n * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com>\n * MIT Licensed\n */\n\n/**\n * ### flag(object, key, [value])\n *\n * Get or set a flag value on an object. If a\n * value is provided it will be set, else it will\n * return the currently set value or `undefined` if\n * the value is not set.\n *\n *     utils.flag(this, 'foo', 'bar'); // setter\n *     utils.flag(this, 'foo'); // getter, returns `bar`\n *\n * @param {Object} object constructed Assertion\n * @param {String} key\n * @param {Mixed} value (optional)\n * @namespace Utils\n * @name flag\n * @api private\n */\n\nmodule.exports = function (obj, key, value) {\n  var flags = obj.__flags || (obj.__flags = Object.create(null));\n  if (arguments.length === 3) {\n    flags[key] = value;\n  } else {\n    return flags[key];\n  }\n};\n\n},{}],14:[function(require,module,exports){\n/*!\n * Chai - getActual utility\n * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com>\n * MIT Licensed\n */\n\n/**\n * # getActual(object, [actual])\n *\n * Returns the `actual` value for an Assertion\n *\n * @param {Object} object (constructed Assertion)\n * @param {Arguments} chai.Assertion.prototype.assert arguments\n * @namespace Utils\n * @name getActual\n */\n\nmodule.exports = function (obj, args) {\n  return args.length > 4 ? args[4] : obj._obj;\n};\n\n},{}],15:[function(require,module,exports){\n/*!\n * Chai - getEnumerableProperties utility\n * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com>\n * MIT Licensed\n */\n\n/**\n * ### .getEnumerableProperties(object)\n *\n * This allows the retrieval of enumerable property names of an object,\n * inherited or not.\n *\n * @param {Object} object\n * @returns {Array}\n * @namespace Utils\n * @name getEnumerableProperties\n * @api public\n */\n\nmodule.exports = function getEnumerableProperties(object) {\n  var result = [];\n  for (var name in object) {\n    result.push(name);\n  }\n  return result;\n};\n\n},{}],16:[function(require,module,exports){\n/*!\n * Chai - message composition utility\n * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com>\n * MIT Licensed\n */\n\n/*!\n * Module dependancies\n */\n\nvar flag = require('./flag')\n  , getActual = require('./getActual')\n  , inspect = require('./inspect')\n  , objDisplay = require('./objDisplay');\n\n/**\n * ### .getMessage(object, message, negateMessage)\n *\n * Construct the error message based on flags\n * and template tags. Template tags will return\n * a stringified inspection of the object referenced.\n *\n * Message template tags:\n * - `#{this}` current asserted object\n * - `#{act}` actual value\n * - `#{exp}` expected value\n *\n * @param {Object} object (constructed Assertion)\n * @param {Arguments} chai.Assertion.prototype.assert arguments\n * @namespace Utils\n * @name getMessage\n * @api public\n */\n\nmodule.exports = function (obj, args) {\n  var negate = flag(obj, 'negate')\n    , val = flag(obj, 'object')\n    , expected = args[3]\n    , actual = getActual(obj, args)\n    , msg = negate ? args[2] : args[1]\n    , flagMsg = flag(obj, 'message');\n\n  if(typeof msg === \"function\") msg = msg();\n  msg = msg || '';\n  msg = msg\n    .replace(/#\\{this\\}/g, function () { return objDisplay(val); })\n    .replace(/#\\{act\\}/g, function () { return objDisplay(actual); })\n    .replace(/#\\{exp\\}/g, function () { return objDisplay(expected); });\n\n  return flagMsg ? flagMsg + ': ' + msg : msg;\n};\n\n},{\"./flag\":13,\"./getActual\":14,\"./inspect\":23,\"./objDisplay\":24}],17:[function(require,module,exports){\n/*!\n * Chai - getName utility\n * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com>\n * MIT Licensed\n */\n\n/**\n * # getName(func)\n *\n * Gets the name of a function, in a cross-browser way.\n *\n * @param {Function} a function (usually a constructor)\n * @namespace Utils\n * @name getName\n */\n\nmodule.exports = function (func) {\n  if (func.name) return func.name;\n\n  var match = /^\\s?function ([^(]*)\\(/.exec(func);\n  return match && match[1] ? match[1] : \"\";\n};\n\n},{}],18:[function(require,module,exports){\n/*!\n * Chai - getPathInfo utility\n * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com>\n * MIT Licensed\n */\n\nvar hasProperty = require('./hasProperty');\n\n/**\n * ### .getPathInfo(path, object)\n *\n * This allows the retrieval of property info in an\n * object given a string path.\n *\n * The path info consists of an object with the\n * following properties:\n *\n * * parent - The parent object of the property referenced by `path`\n * * name - The name of the final property, a number if it was an array indexer\n * * value - The value of the property, if it exists, otherwise `undefined`\n * * exists - Whether the property exists or not\n *\n * @param {String} path\n * @param {Object} object\n * @returns {Object} info\n * @namespace Utils\n * @name getPathInfo\n * @api public\n */\n\nmodule.exports = function getPathInfo(path, obj) {\n  var parsed = parsePath(path),\n      last = parsed[parsed.length - 1];\n\n  var info = {\n    parent: parsed.length > 1 ? _getPathValue(parsed, obj, parsed.length - 1) : obj,\n    name: last.p || last.i,\n    value: _getPathValue(parsed, obj)\n  };\n  info.exists = hasProperty(info.name, info.parent);\n\n  return info;\n};\n\n\n/*!\n * ## parsePath(path)\n *\n * Helper function used to parse string object\n * paths. Use in conjunction with `_getPathValue`.\n *\n *      var parsed = parsePath('myobject.property.subprop');\n *\n * ### Paths:\n *\n * * Can be as near infinitely deep and nested\n * * Arrays are also valid using the formal `myobject.document[3].property`.\n * * Literal dots and brackets (not delimiter) must be backslash-escaped.\n *\n * @param {String} path\n * @returns {Object} parsed\n * @api private\n */\n\nfunction parsePath (path) {\n  var str = path.replace(/([^\\\\])\\[/g, '$1.[')\n    , parts = str.match(/(\\\\\\.|[^.]+?)+/g);\n  return parts.map(function (value) {\n    var re = /^\\[(\\d+)\\]$/\n      , mArr = re.exec(value);\n    if (mArr) return { i: parseFloat(mArr[1]) };\n    else return { p: value.replace(/\\\\([.\\[\\]])/g, '$1') };\n  });\n}\n\n\n/*!\n * ## _getPathValue(parsed, obj)\n *\n * Helper companion function for `.parsePath` that returns\n * the value located at the parsed address.\n *\n *      var value = getPathValue(parsed, obj);\n *\n * @param {Object} parsed definition from `parsePath`.\n * @param {Object} object to search against\n * @param {Number} object to search against\n * @returns {Object|Undefined} value\n * @api private\n */\n\nfunction _getPathValue (parsed, obj, index) {\n  var tmp = obj\n    , res;\n\n  index = (index === undefined ? parsed.length : index);\n\n  for (var i = 0, l = index; i < l; i++) {\n    var part = parsed[i];\n    if (tmp) {\n      if ('undefined' !== typeof part.p)\n        tmp = tmp[part.p];\n      else if ('undefined' !== typeof part.i)\n        tmp = tmp[part.i];\n      if (i == (l - 1)) res = tmp;\n    } else {\n      res = undefined;\n    }\n  }\n  return res;\n}\n\n},{\"./hasProperty\":21}],19:[function(require,module,exports){\n/*!\n * Chai - getPathValue utility\n * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com>\n * @see https://github.com/logicalparadox/filtr\n * MIT Licensed\n */\n\nvar getPathInfo = require('./getPathInfo');\n\n/**\n * ### .getPathValue(path, object)\n *\n * This allows the retrieval of values in an\n * object given a string path.\n *\n *     var obj = {\n *         prop1: {\n *             arr: ['a', 'b', 'c']\n *           , str: 'Hello'\n *         }\n *       , prop2: {\n *             arr: [ { nested: 'Universe' } ]\n *           , str: 'Hello again!'\n *         }\n *     }\n *\n * The following would be the results.\n *\n *     getPathValue('prop1.str', obj); // Hello\n *     getPathValue('prop1.att[2]', obj); // b\n *     getPathValue('prop2.arr[0].nested', obj); // Universe\n *\n * @param {String} path\n * @param {Object} object\n * @returns {Object} value or `undefined`\n * @namespace Utils\n * @name getPathValue\n * @api public\n */\nmodule.exports = function(path, obj) {\n  var info = getPathInfo(path, obj);\n  return info.value;\n};\n\n},{\"./getPathInfo\":18}],20:[function(require,module,exports){\n/*!\n * Chai - getProperties utility\n * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com>\n * MIT Licensed\n */\n\n/**\n * ### .getProperties(object)\n *\n * This allows the retrieval of property names of an object, enumerable or not,\n * inherited or not.\n *\n * @param {Object} object\n * @returns {Array}\n * @namespace Utils\n * @name getProperties\n * @api public\n */\n\nmodule.exports = function getProperties(object) {\n  var result = Object.getOwnPropertyNames(object);\n\n  function addProperty(property) {\n    if (result.indexOf(property) === -1) {\n      result.push(property);\n    }\n  }\n\n  var proto = Object.getPrototypeOf(object);\n  while (proto !== null) {\n    Object.getOwnPropertyNames(proto).forEach(addProperty);\n    proto = Object.getPrototypeOf(proto);\n  }\n\n  return result;\n};\n\n},{}],21:[function(require,module,exports){\n/*!\n * Chai - hasProperty utility\n * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com>\n * MIT Licensed\n */\n\nvar type = require('type-detect');\n\n/**\n * ### .hasProperty(object, name)\n *\n * This allows checking whether an object has\n * named property or numeric array index.\n *\n * Basically does the same thing as the `in`\n * operator but works properly with natives\n * and null/undefined values.\n *\n *     var obj = {\n *         arr: ['a', 'b', 'c']\n *       , str: 'Hello'\n *     }\n *\n * The following would be the results.\n *\n *     hasProperty('str', obj);  // true\n *     hasProperty('constructor', obj);  // true\n *     hasProperty('bar', obj);  // false\n *\n *     hasProperty('length', obj.str); // true\n *     hasProperty(1, obj.str);  // true\n *     hasProperty(5, obj.str);  // false\n *\n *     hasProperty('length', obj.arr);  // true\n *     hasProperty(2, obj.arr);  // true\n *     hasProperty(3, obj.arr);  // false\n *\n * @param {Objuect} object\n * @param {String|Number} name\n * @returns {Boolean} whether it exists\n * @namespace Utils\n * @name getPathInfo\n * @api public\n */\n\nvar literals = {\n    'number': Number\n  , 'string': String\n};\n\nmodule.exports = function hasProperty(name, obj) {\n  var ot = type(obj);\n\n  // Bad Object, obviously no props at all\n  if(ot === 'null' || ot === 'undefined')\n    return false;\n\n  // The `in` operator does not work with certain literals\n  // box these before the check\n  if(literals[ot] && typeof obj !== 'object')\n    obj = new literals[ot](obj);\n\n  return name in obj;\n};\n\n},{\"type-detect\":35}],22:[function(require,module,exports){\n/*!\n * chai\n * Copyright(c) 2011 Jake Luer <jake@alogicalparadox.com>\n * MIT Licensed\n */\n\n/*!\n * Main exports\n */\n\nvar exports = module.exports = {};\n\n/*!\n * test utility\n */\n\nexports.test = require('./test');\n\n/*!\n * type utility\n */\n\nexports.type = require('type-detect');\n\n/*!\n * expectTypes utility\n */\nexports.expectTypes = require('./expectTypes');\n\n/*!\n * message utility\n */\n\nexports.getMessage = require('./getMessage');\n\n/*!\n * actual utility\n */\n\nexports.getActual = require('./getActual');\n\n/*!\n * Inspect util\n */\n\nexports.inspect = require('./inspect');\n\n/*!\n * Object Display util\n */\n\nexports.objDisplay = require('./objDisplay');\n\n/*!\n * Flag utility\n */\n\nexports.flag = require('./flag');\n\n/*!\n * Flag transferring utility\n */\n\nexports.transferFlags = require('./transferFlags');\n\n/*!\n * Deep equal utility\n */\n\nexports.eql = require('deep-eql');\n\n/*!\n * Deep path value\n */\n\nexports.getPathValue = require('./getPathValue');\n\n/*!\n * Deep path info\n */\n\nexports.getPathInfo = require('./getPathInfo');\n\n/*!\n * Check if a property exists\n */\n\nexports.hasProperty = require('./hasProperty');\n\n/*!\n * Function name\n */\n\nexports.getName = require('./getName');\n\n/*!\n * add Property\n */\n\nexports.addProperty = require('./addProperty');\n\n/*!\n * add Method\n */\n\nexports.addMethod = require('./addMethod');\n\n/*!\n * overwrite Property\n */\n\nexports.overwriteProperty = require('./overwriteProperty');\n\n/*!\n * overwrite Method\n */\n\nexports.overwriteMethod = require('./overwriteMethod');\n\n/*!\n * Add a chainable method\n */\n\nexports.addChainableMethod = require('./addChainableMethod');\n\n/*!\n * Overwrite chainable method\n */\n\nexports.overwriteChainableMethod = require('./overwriteChainableMethod');\n\n},{\"./addChainableMethod\":9,\"./addMethod\":10,\"./addProperty\":11,\"./expectTypes\":12,\"./flag\":13,\"./getActual\":14,\"./getMessage\":16,\"./getName\":17,\"./getPathInfo\":18,\"./getPathValue\":19,\"./hasProperty\":21,\"./inspect\":23,\"./objDisplay\":24,\"./overwriteChainableMethod\":25,\"./overwriteMethod\":26,\"./overwriteProperty\":27,\"./test\":28,\"./transferFlags\":29,\"deep-eql\":31,\"type-detect\":35}],23:[function(require,module,exports){\n// This is (almost) directly from Node.js utils\n// https://github.com/joyent/node/blob/f8c335d0caf47f16d31413f89aa28eda3878e3aa/lib/util.js\n\nvar getName = require('./getName');\nvar getProperties = require('./getProperties');\nvar getEnumerableProperties = require('./getEnumerableProperties');\n\nmodule.exports = inspect;\n\n/**\n * Echos the value of a value. Trys to print the value out\n * in the best way possible given the different types.\n *\n * @param {Object} obj The object to print out.\n * @param {Boolean} showHidden Flag that shows hidden (not enumerable)\n *    properties of objects.\n * @param {Number} depth Depth in which to descend in object. Default is 2.\n * @param {Boolean} colors Flag to turn on ANSI escape codes to color the\n *    output. Default is false (no coloring).\n * @namespace Utils\n * @name inspect\n */\nfunction inspect(obj, showHidden, depth, colors) {\n  var ctx = {\n    showHidden: showHidden,\n    seen: [],\n    stylize: function (str) { return str; }\n  };\n  return formatValue(ctx, obj, (typeof depth === 'undefined' ? 2 : depth));\n}\n\n// Returns true if object is a DOM element.\nvar isDOMElement = function (object) {\n  if (typeof HTMLElement === 'object') {\n    return object instanceof HTMLElement;\n  } else {\n    return object &&\n      typeof object === 'object' &&\n      object.nodeType === 1 &&\n      typeof object.nodeName === 'string';\n  }\n};\n\nfunction formatValue(ctx, value, recurseTimes) {\n  // Provide a hook for user-specified inspect functions.\n  // Check that value is an object with an inspect function on it\n  if (value && typeof value.inspect === 'function' &&\n      // Filter out the util module, it's inspect function is special\n      value.inspect !== exports.inspect &&\n      // Also filter out any prototype objects using the circular check.\n      !(value.constructor && value.constructor.prototype === value)) {\n    var ret = value.inspect(recurseTimes);\n    if (typeof ret !== 'string') {\n      ret = formatValue(ctx, ret, recurseTimes);\n    }\n    return ret;\n  }\n\n  // Primitive types cannot have properties\n  var primitive = formatPrimitive(ctx, value);\n  if (primitive) {\n    return primitive;\n  }\n\n  // If this is a DOM element, try to get the outer HTML.\n  if (isDOMElement(value)) {\n    if ('outerHTML' in value) {\n      return value.outerHTML;\n      // This value does not have an outerHTML attribute,\n      //   it could still be an XML element\n    } else {\n      // Attempt to serialize it\n      try {\n        if (document.xmlVersion) {\n          var xmlSerializer = new XMLSerializer();\n          return xmlSerializer.serializeToString(value);\n        } else {\n          // Firefox 11- do not support outerHTML\n          //   It does, however, support innerHTML\n          //   Use the following to render the element\n          var ns = \"http://www.w3.org/1999/xhtml\";\n          var container = document.createElementNS(ns, '_');\n\n          container.appendChild(value.cloneNode(false));\n          html = container.innerHTML\n            .replace('><', '>' + value.innerHTML + '<');\n          container.innerHTML = '';\n          return html;\n        }\n      } catch (err) {\n        // This could be a non-native DOM implementation,\n        //   continue with the normal flow:\n        //   printing the element as if it is an object.\n      }\n    }\n  }\n\n  // Look up the keys of the object.\n  var visibleKeys = getEnumerableProperties(value);\n  var keys = ctx.showHidden ? getProperties(value) : visibleKeys;\n\n  // Some type of object without properties can be shortcutted.\n  // In IE, errors have a single `stack` property, or if they are vanilla `Error`,\n  // a `stack` plus `description` property; ignore those for consistency.\n  if (keys.length === 0 || (isError(value) && (\n      (keys.length === 1 && keys[0] === 'stack') ||\n      (keys.length === 2 && keys[0] === 'description' && keys[1] === 'stack')\n     ))) {\n    if (typeof value === 'function') {\n      var name = getName(value);\n      var nameSuffix = name ? ': ' + name : '';\n      return ctx.stylize('[Function' + nameSuffix + ']', 'special');\n    }\n    if (isRegExp(value)) {\n      return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp');\n    }\n    if (isDate(value)) {\n      return ctx.stylize(Date.prototype.toUTCString.call(value), 'date');\n    }\n    if (isError(value)) {\n      return formatError(value);\n    }\n  }\n\n  var base = '', array = false, braces = ['{', '}'];\n\n  // Make Array say that they are Array\n  if (isArray(value)) {\n    array = true;\n    braces = ['[', ']'];\n  }\n\n  // Make functions say that they are functions\n  if (typeof value === 'function') {\n    var name = getName(value);\n    var nameSuffix = name ? ': ' + name : '';\n    base = ' [Function' + nameSuffix + ']';\n  }\n\n  // Make RegExps say that they are RegExps\n  if (isRegExp(value)) {\n    base = ' ' + RegExp.prototype.toString.call(value);\n  }\n\n  // Make dates with properties first say the date\n  if (isDate(value)) {\n    base = ' ' + Date.prototype.toUTCString.call(value);\n  }\n\n  // Make error with message first say the error\n  if (isError(value)) {\n    return formatError(value);\n  }\n\n  if (keys.length === 0 && (!array || value.length == 0)) {\n    return braces[0] + base + braces[1];\n  }\n\n  if (recurseTimes < 0) {\n    if (isRegExp(value)) {\n      return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp');\n    } else {\n      return ctx.stylize('[Object]', 'special');\n    }\n  }\n\n  ctx.seen.push(value);\n\n  var output;\n  if (array) {\n    output = formatArray(ctx, value, recurseTimes, visibleKeys, keys);\n  } else {\n    output = keys.map(function(key) {\n      return formatProperty(ctx, value, recurseTimes, visibleKeys, key, array);\n    });\n  }\n\n  ctx.seen.pop();\n\n  return reduceToSingleString(output, base, braces);\n}\n\n\nfunction formatPrimitive(ctx, value) {\n  switch (typeof value) {\n    case 'undefined':\n      return ctx.stylize('undefined', 'undefined');\n\n    case 'string':\n      var simple = '\\'' + JSON.stringify(value).replace(/^\"|\"$/g, '')\n                                               .replace(/'/g, \"\\\\'\")\n                                               .replace(/\\\\\"/g, '\"') + '\\'';\n      return ctx.stylize(simple, 'string');\n\n    case 'number':\n      if (value === 0 && (1/value) === -Infinity) {\n        return ctx.stylize('-0', 'number');\n      }\n      return ctx.stylize('' + value, 'number');\n\n    case 'boolean':\n      return ctx.stylize('' + value, 'boolean');\n  }\n  // For some reason typeof null is \"object\", so special case here.\n  if (value === null) {\n    return ctx.stylize('null', 'null');\n  }\n}\n\n\nfunction formatError(value) {\n  return '[' + Error.prototype.toString.call(value) + ']';\n}\n\n\nfunction formatArray(ctx, value, recurseTimes, visibleKeys, keys) {\n  var output = [];\n  for (var i = 0, l = value.length; i < l; ++i) {\n    if (Object.prototype.hasOwnProperty.call(value, String(i))) {\n      output.push(formatProperty(ctx, value, recurseTimes, visibleKeys,\n          String(i), true));\n    } else {\n      output.push('');\n    }\n  }\n  keys.forEach(function(key) {\n    if (!key.match(/^\\d+$/)) {\n      output.push(formatProperty(ctx, value, recurseTimes, visibleKeys,\n          key, true));\n    }\n  });\n  return output;\n}\n\n\nfunction formatProperty(ctx, value, recurseTimes, visibleKeys, key, array) {\n  var name, str;\n  if (value.__lookupGetter__) {\n    if (value.__lookupGetter__(key)) {\n      if (value.__lookupSetter__(key)) {\n        str = ctx.stylize('[Getter/Setter]', 'special');\n      } else {\n        str = ctx.stylize('[Getter]', 'special');\n      }\n    } else {\n      if (value.__lookupSetter__(key)) {\n        str = ctx.stylize('[Setter]', 'special');\n      }\n    }\n  }\n  if (visibleKeys.indexOf(key) < 0) {\n    name = '[' + key + ']';\n  }\n  if (!str) {\n    if (ctx.seen.indexOf(value[key]) < 0) {\n      if (recurseTimes === null) {\n        str = formatValue(ctx, value[key], null);\n      } else {\n        str = formatValue(ctx, value[key], recurseTimes - 1);\n      }\n      if (str.indexOf('\\n') > -1) {\n        if (array) {\n          str = str.split('\\n').map(function(line) {\n            return '  ' + line;\n          }).join('\\n').substr(2);\n        } else {\n          str = '\\n' + str.split('\\n').map(function(line) {\n            return '   ' + line;\n          }).join('\\n');\n        }\n      }\n    } else {\n      str = ctx.stylize('[Circular]', 'special');\n    }\n  }\n  if (typeof name === 'undefined') {\n    if (array && key.match(/^\\d+$/)) {\n      return str;\n    }\n    name = JSON.stringify('' + key);\n    if (name.match(/^\"([a-zA-Z_][a-zA-Z_0-9]*)\"$/)) {\n      name = name.substr(1, name.length - 2);\n      name = ctx.stylize(name, 'name');\n    } else {\n      name = name.replace(/'/g, \"\\\\'\")\n                 .replace(/\\\\\"/g, '\"')\n                 .replace(/(^\"|\"$)/g, \"'\");\n      name = ctx.stylize(name, 'string');\n    }\n  }\n\n  return name + ': ' + str;\n}\n\n\nfunction reduceToSingleString(output, base, braces) {\n  var numLinesEst = 0;\n  var length = output.reduce(function(prev, cur) {\n    numLinesEst++;\n    if (cur.indexOf('\\n') >= 0) numLinesEst++;\n    return prev + cur.length + 1;\n  }, 0);\n\n  if (length > 60) {\n    return braces[0] +\n           (base === '' ? '' : base + '\\n ') +\n           ' ' +\n           output.join(',\\n  ') +\n           ' ' +\n           braces[1];\n  }\n\n  return braces[0] + base + ' ' + output.join(', ') + ' ' + braces[1];\n}\n\nfunction isArray(ar) {\n  return Array.isArray(ar) ||\n         (typeof ar === 'object' && objectToString(ar) === '[object Array]');\n}\n\nfunction isRegExp(re) {\n  return typeof re === 'object' && objectToString(re) === '[object RegExp]';\n}\n\nfunction isDate(d) {\n  return typeof d === 'object' && objectToString(d) === '[object Date]';\n}\n\nfunction isError(e) {\n  return typeof e === 'object' && objectToString(e) === '[object Error]';\n}\n\nfunction objectToString(o) {\n  return Object.prototype.toString.call(o);\n}\n\n},{\"./getEnumerableProperties\":15,\"./getName\":17,\"./getProperties\":20}],24:[function(require,module,exports){\n/*!\n * Chai - flag utility\n * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com>\n * MIT Licensed\n */\n\n/*!\n * Module dependancies\n */\n\nvar inspect = require('./inspect');\nvar config = require('../config');\n\n/**\n * ### .objDisplay (object)\n *\n * Determines if an object or an array matches\n * criteria to be inspected in-line for error\n * messages or should be truncated.\n *\n * @param {Mixed} javascript object to inspect\n * @name objDisplay\n * @namespace Utils\n * @api public\n */\n\nmodule.exports = function (obj) {\n  var str = inspect(obj)\n    , type = Object.prototype.toString.call(obj);\n\n  if (config.truncateThreshold && str.length >= config.truncateThreshold) {\n    if (type === '[object Function]') {\n      return !obj.name || obj.name === ''\n        ? '[Function]'\n        : '[Function: ' + obj.name + ']';\n    } else if (type === '[object Array]') {\n      return '[ Array(' + obj.length + ') ]';\n    } else if (type === '[object Object]') {\n      var keys = Object.keys(obj)\n        , kstr = keys.length > 2\n          ? keys.splice(0, 2).join(', ') + ', ...'\n          : keys.join(', ');\n      return '{ Object (' + kstr + ') }';\n    } else {\n      return str;\n    }\n  } else {\n    return str;\n  }\n};\n\n},{\"../config\":4,\"./inspect\":23}],25:[function(require,module,exports){\n/*!\n * Chai - overwriteChainableMethod utility\n * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com>\n * MIT Licensed\n */\n\n/**\n * ### overwriteChainableMethod (ctx, name, method, chainingBehavior)\n *\n * Overwites an already existing chainable method\n * and provides access to the previous function or\n * property.  Must return functions to be used for\n * name.\n *\n *     utils.overwriteChainableMethod(chai.Assertion.prototype, 'length',\n *       function (_super) {\n *       }\n *     , function (_super) {\n *       }\n *     );\n *\n * Can also be accessed directly from `chai.Assertion`.\n *\n *     chai.Assertion.overwriteChainableMethod('foo', fn, fn);\n *\n * Then can be used as any other assertion.\n *\n *     expect(myFoo).to.have.length(3);\n *     expect(myFoo).to.have.length.above(3);\n *\n * @param {Object} ctx object whose method / property is to be overwritten\n * @param {String} name of method / property to overwrite\n * @param {Function} method function that returns a function to be used for name\n * @param {Function} chainingBehavior function that returns a function to be used for property\n * @namespace Utils\n * @name overwriteChainableMethod\n * @api public\n */\n\nmodule.exports = function (ctx, name, method, chainingBehavior) {\n  var chainableBehavior = ctx.__methods[name];\n\n  var _chainingBehavior = chainableBehavior.chainingBehavior;\n  chainableBehavior.chainingBehavior = function () {\n    var result = chainingBehavior(_chainingBehavior).call(this);\n    return result === undefined ? this : result;\n  };\n\n  var _method = chainableBehavior.method;\n  chainableBehavior.method = function () {\n    var result = method(_method).apply(this, arguments);\n    return result === undefined ? this : result;\n  };\n};\n\n},{}],26:[function(require,module,exports){\n/*!\n * Chai - overwriteMethod utility\n * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com>\n * MIT Licensed\n */\n\n/**\n * ### overwriteMethod (ctx, name, fn)\n *\n * Overwites an already existing method and provides\n * access to previous function. Must return function\n * to be used for name.\n *\n *     utils.overwriteMethod(chai.Assertion.prototype, 'equal', function (_super) {\n *       return function (str) {\n *         var obj = utils.flag(this, 'object');\n *         if (obj instanceof Foo) {\n *           new chai.Assertion(obj.value).to.equal(str);\n *         } else {\n *           _super.apply(this, arguments);\n *         }\n *       }\n *     });\n *\n * Can also be accessed directly from `chai.Assertion`.\n *\n *     chai.Assertion.overwriteMethod('foo', fn);\n *\n * Then can be used as any other assertion.\n *\n *     expect(myFoo).to.equal('bar');\n *\n * @param {Object} ctx object whose method is to be overwritten\n * @param {String} name of method to overwrite\n * @param {Function} method function that returns a function to be used for name\n * @namespace Utils\n * @name overwriteMethod\n * @api public\n */\n\nmodule.exports = function (ctx, name, method) {\n  var _method = ctx[name]\n    , _super = function () { return this; };\n\n  if (_method && 'function' === typeof _method)\n    _super = _method;\n\n  ctx[name] = function () {\n    var result = method(_super).apply(this, arguments);\n    return result === undefined ? this : result;\n  }\n};\n\n},{}],27:[function(require,module,exports){\n/*!\n * Chai - overwriteProperty utility\n * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com>\n * MIT Licensed\n */\n\n/**\n * ### overwriteProperty (ctx, name, fn)\n *\n * Overwites an already existing property getter and provides\n * access to previous value. Must return function to use as getter.\n *\n *     utils.overwriteProperty(chai.Assertion.prototype, 'ok', function (_super) {\n *       return function () {\n *         var obj = utils.flag(this, 'object');\n *         if (obj instanceof Foo) {\n *           new chai.Assertion(obj.name).to.equal('bar');\n *         } else {\n *           _super.call(this);\n *         }\n *       }\n *     });\n *\n *\n * Can also be accessed directly from `chai.Assertion`.\n *\n *     chai.Assertion.overwriteProperty('foo', fn);\n *\n * Then can be used as any other assertion.\n *\n *     expect(myFoo).to.be.ok;\n *\n * @param {Object} ctx object whose property is to be overwritten\n * @param {String} name of property to overwrite\n * @param {Function} getter function that returns a getter function to be used for name\n * @namespace Utils\n * @name overwriteProperty\n * @api public\n */\n\nmodule.exports = function (ctx, name, getter) {\n  var _get = Object.getOwnPropertyDescriptor(ctx, name)\n    , _super = function () {};\n\n  if (_get && 'function' === typeof _get.get)\n    _super = _get.get\n\n  Object.defineProperty(ctx, name,\n    { get: function () {\n        var result = getter(_super).call(this);\n        return result === undefined ? this : result;\n      }\n    , configurable: true\n  });\n};\n\n},{}],28:[function(require,module,exports){\n/*!\n * Chai - test utility\n * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com>\n * MIT Licensed\n */\n\n/*!\n * Module dependancies\n */\n\nvar flag = require('./flag');\n\n/**\n * # test(object, expression)\n *\n * Test and object for expression.\n *\n * @param {Object} object (constructed Assertion)\n * @param {Arguments} chai.Assertion.prototype.assert arguments\n * @namespace Utils\n * @name test\n */\n\nmodule.exports = function (obj, args) {\n  var negate = flag(obj, 'negate')\n    , expr = args[0];\n  return negate ? !expr : expr;\n};\n\n},{\"./flag\":13}],29:[function(require,module,exports){\n/*!\n * Chai - transferFlags utility\n * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com>\n * MIT Licensed\n */\n\n/**\n * ### transferFlags(assertion, object, includeAll = true)\n *\n * Transfer all the flags for `assertion` to `object`. If\n * `includeAll` is set to `false`, then the base Chai\n * assertion flags (namely `object`, `ssfi`, and `message`)\n * will not be transferred.\n *\n *\n *     var newAssertion = new Assertion();\n *     utils.transferFlags(assertion, newAssertion);\n *\n *     var anotherAsseriton = new Assertion(myObj);\n *     utils.transferFlags(assertion, anotherAssertion, false);\n *\n * @param {Assertion} assertion the assertion to transfer the flags from\n * @param {Object} object the object to transfer the flags to; usually a new assertion\n * @param {Boolean} includeAll\n * @namespace Utils\n * @name transferFlags\n * @api private\n */\n\nmodule.exports = function (assertion, object, includeAll) {\n  var flags = assertion.__flags || (assertion.__flags = Object.create(null));\n\n  if (!object.__flags) {\n    object.__flags = Object.create(null);\n  }\n\n  includeAll = arguments.length === 3 ? includeAll : true;\n\n  for (var flag in flags) {\n    if (includeAll ||\n        (flag !== 'object' && flag !== 'ssfi' && flag != 'message')) {\n      object.__flags[flag] = flags[flag];\n    }\n  }\n};\n\n},{}],30:[function(require,module,exports){\n/*!\n * assertion-error\n * Copyright(c) 2013 Jake Luer <jake@qualiancy.com>\n * MIT Licensed\n */\n\n/*!\n * Return a function that will copy properties from\n * one object to another excluding any originally\n * listed. Returned function will create a new `{}`.\n *\n * @param {String} excluded properties ...\n * @return {Function}\n */\n\nfunction exclude () {\n  var excludes = [].slice.call(arguments);\n\n  function excludeProps (res, obj) {\n    Object.keys(obj).forEach(function (key) {\n      if (!~excludes.indexOf(key)) res[key] = obj[key];\n    });\n  }\n\n  return function extendExclude () {\n    var args = [].slice.call(arguments)\n      , i = 0\n      , res = {};\n\n    for (; i < args.length; i++) {\n      excludeProps(res, args[i]);\n    }\n\n    return res;\n  };\n};\n\n/*!\n * Primary Exports\n */\n\nmodule.exports = AssertionError;\n\n/**\n * ### AssertionError\n *\n * An extension of the JavaScript `Error` constructor for\n * assertion and validation scenarios.\n *\n * @param {String} message\n * @param {Object} properties to include (optional)\n * @param {callee} start stack function (optional)\n */\n\nfunction AssertionError (message, _props, ssf) {\n  var extend = exclude('name', 'message', 'stack', 'constructor', 'toJSON')\n    , props = extend(_props || {});\n\n  // default values\n  this.message = message || 'Unspecified AssertionError';\n  this.showDiff = false;\n\n  // copy from properties\n  for (var key in props) {\n    this[key] = props[key];\n  }\n\n  // capture stack trace\n  ssf = ssf || arguments.callee;\n  if (ssf && Error.captureStackTrace) {\n    Error.captureStackTrace(this, ssf);\n  } else {\n    this.stack = new Error().stack;\n  }\n}\n\n/*!\n * Inherit from Error.prototype\n */\n\nAssertionError.prototype = Object.create(Error.prototype);\n\n/*!\n * Statically set name\n */\n\nAssertionError.prototype.name = 'AssertionError';\n\n/*!\n * Ensure correct constructor\n */\n\nAssertionError.prototype.constructor = AssertionError;\n\n/**\n * Allow errors to be converted to JSON for static transfer.\n *\n * @param {Boolean} include stack (default: `true`)\n * @return {Object} object that can be `JSON.stringify`\n */\n\nAssertionError.prototype.toJSON = function (stack) {\n  var extend = exclude('constructor', 'toJSON', 'stack')\n    , props = extend({ name: this.name }, this);\n\n  // include stack if exists and not turned off\n  if (false !== stack && this.stack) {\n    props.stack = this.stack;\n  }\n\n  return props;\n};\n\n},{}],31:[function(require,module,exports){\nmodule.exports = require('./lib/eql');\n\n},{\"./lib/eql\":32}],32:[function(require,module,exports){\n/*!\n * deep-eql\n * Copyright(c) 2013 Jake Luer <jake@alogicalparadox.com>\n * MIT Licensed\n */\n\n/*!\n * Module dependencies\n */\n\nvar type = require('type-detect');\n\n/*!\n * Buffer.isBuffer browser shim\n */\n\nvar Buffer;\ntry { Buffer = require('buffer').Buffer; }\ncatch(ex) {\n  Buffer = {};\n  Buffer.isBuffer = function() { return false; }\n}\n\n/*!\n * Primary Export\n */\n\nmodule.exports = deepEqual;\n\n/**\n * Assert super-strict (egal) equality between\n * two objects of any type.\n *\n * @param {Mixed} a\n * @param {Mixed} b\n * @param {Array} memoised (optional)\n * @return {Boolean} equal match\n */\n\nfunction deepEqual(a, b, m) {\n  if (sameValue(a, b)) {\n    return true;\n  } else if ('date' === type(a)) {\n    return dateEqual(a, b);\n  } else if ('regexp' === type(a)) {\n    return regexpEqual(a, b);\n  } else if (Buffer.isBuffer(a)) {\n    return bufferEqual(a, b);\n  } else if ('arguments' === type(a)) {\n    return argumentsEqual(a, b, m);\n  } else if (!typeEqual(a, b)) {\n    return false;\n  } else if (('object' !== type(a) && 'object' !== type(b))\n  && ('array' !== type(a) && 'array' !== type(b))) {\n    return sameValue(a, b);\n  } else {\n    return objectEqual(a, b, m);\n  }\n}\n\n/*!\n * Strict (egal) equality test. Ensures that NaN always\n * equals NaN and `-0` does not equal `+0`.\n *\n * @param {Mixed} a\n * @param {Mixed} b\n * @return {Boolean} equal match\n */\n\nfunction sameValue(a, b) {\n  if (a === b) return a !== 0 || 1 / a === 1 / b;\n  return a !== a && b !== b;\n}\n\n/*!\n * Compare the types of two given objects and\n * return if they are equal. Note that an Array\n * has a type of `array` (not `object`) and arguments\n * have a type of `arguments` (not `array`/`object`).\n *\n * @param {Mixed} a\n * @param {Mixed} b\n * @return {Boolean} result\n */\n\nfunction typeEqual(a, b) {\n  return type(a) === type(b);\n}\n\n/*!\n * Compare two Date objects by asserting that\n * the time values are equal using `saveValue`.\n *\n * @param {Date} a\n * @param {Date} b\n * @return {Boolean} result\n */\n\nfunction dateEqual(a, b) {\n  if ('date' !== type(b)) return false;\n  return sameValue(a.getTime(), b.getTime());\n}\n\n/*!\n * Compare two regular expressions by converting them\n * to string and checking for `sameValue`.\n *\n * @param {RegExp} a\n * @param {RegExp} b\n * @return {Boolean} result\n */\n\nfunction regexpEqual(a, b) {\n  if ('regexp' !== type(b)) return false;\n  return sameValue(a.toString(), b.toString());\n}\n\n/*!\n * Assert deep equality of two `arguments` objects.\n * Unfortunately, these must be sliced to arrays\n * prior to test to ensure no bad behavior.\n *\n * @param {Arguments} a\n * @param {Arguments} b\n * @param {Array} memoize (optional)\n * @return {Boolean} result\n */\n\nfunction argumentsEqual(a, b, m) {\n  if ('arguments' !== type(b)) return false;\n  a = [].slice.call(a);\n  b = [].slice.call(b);\n  return deepEqual(a, b, m);\n}\n\n/*!\n * Get enumerable properties of a given object.\n *\n * @param {Object} a\n * @return {Array} property names\n */\n\nfunction enumerable(a) {\n  var res = [];\n  for (var key in a) res.push(key);\n  return res;\n}\n\n/*!\n * Simple equality for flat iterable objects\n * such as Arrays or Node.js buffers.\n *\n * @param {Iterable} a\n * @param {Iterable} b\n * @return {Boolean} result\n */\n\nfunction iterableEqual(a, b) {\n  if (a.length !==  b.length) return false;\n\n  var i = 0;\n  var match = true;\n\n  for (; i < a.length; i++) {\n    if (a[i] !== b[i]) {\n      match = false;\n      break;\n    }\n  }\n\n  return match;\n}\n\n/*!\n * Extension to `iterableEqual` specifically\n * for Node.js Buffers.\n *\n * @param {Buffer} a\n * @param {Mixed} b\n * @return {Boolean} result\n */\n\nfunction bufferEqual(a, b) {\n  if (!Buffer.isBuffer(b)) return false;\n  return iterableEqual(a, b);\n}\n\n/*!\n * Block for `objectEqual` ensuring non-existing\n * values don't get in.\n *\n * @param {Mixed} object\n * @return {Boolean} result\n */\n\nfunction isValue(a) {\n  return a !== null && a !== undefined;\n}\n\n/*!\n * Recursively check the equality of two objects.\n * Once basic sameness has been established it will\n * defer to `deepEqual` for each enumerable key\n * in the object.\n *\n * @param {Mixed} a\n * @param {Mixed} b\n * @return {Boolean} result\n */\n\nfunction objectEqual(a, b, m) {\n  if (!isValue(a) || !isValue(b)) {\n    return false;\n  }\n\n  if (a.prototype !== b.prototype) {\n    return false;\n  }\n\n  var i;\n  if (m) {\n    for (i = 0; i < m.length; i++) {\n      if ((m[i][0] === a && m[i][1] === b)\n      ||  (m[i][0] === b && m[i][1] === a)) {\n        return true;\n      }\n    }\n  } else {\n    m = [];\n  }\n\n  try {\n    var ka = enumerable(a);\n    var kb = enumerable(b);\n  } catch (ex) {\n    return false;\n  }\n\n  ka.sort();\n  kb.sort();\n\n  if (!iterableEqual(ka, kb)) {\n    return false;\n  }\n\n  m.push([ a, b ]);\n\n  var key;\n  for (i = ka.length - 1; i >= 0; i--) {\n    key = ka[i];\n    if (!deepEqual(a[key], b[key], m)) {\n      return false;\n    }\n  }\n\n  return true;\n}\n\n},{\"buffer\":undefined,\"type-detect\":33}],33:[function(require,module,exports){\nmodule.exports = require('./lib/type');\n\n},{\"./lib/type\":34}],34:[function(require,module,exports){\n/*!\n * type-detect\n * Copyright(c) 2013 jake luer <jake@alogicalparadox.com>\n * MIT Licensed\n */\n\n/*!\n * Primary Exports\n */\n\nvar exports = module.exports = getType;\n\n/*!\n * Detectable javascript natives\n */\n\nvar natives = {\n    '[object Array]': 'array'\n  , '[object RegExp]': 'regexp'\n  , '[object Function]': 'function'\n  , '[object Arguments]': 'arguments'\n  , '[object Date]': 'date'\n};\n\n/**\n * ### typeOf (obj)\n *\n * Use several different techniques to determine\n * the type of object being tested.\n *\n *\n * @param {Mixed} object\n * @return {String} object type\n * @api public\n */\n\nfunction getType (obj) {\n  var str = Object.prototype.toString.call(obj);\n  if (natives[str]) return natives[str];\n  if (obj === null) return 'null';\n  if (obj === undefined) return 'undefined';\n  if (obj === Object(obj)) return 'object';\n  return typeof obj;\n}\n\nexports.Library = Library;\n\n/**\n * ### Library\n *\n * Create a repository for custom type detection.\n *\n * ```js\n * var lib = new type.Library;\n * ```\n *\n */\n\nfunction Library () {\n  this.tests = {};\n}\n\n/**\n * #### .of (obj)\n *\n * Expose replacement `typeof` detection to the library.\n *\n * ```js\n * if ('string' === lib.of('hello world')) {\n *   // ...\n * }\n * ```\n *\n * @param {Mixed} object to test\n * @return {String} type\n */\n\nLibrary.prototype.of = getType;\n\n/**\n * #### .define (type, test)\n *\n * Add a test to for the `.test()` assertion.\n *\n * Can be defined as a regular expression:\n *\n * ```js\n * lib.define('int', /^[0-9]+$/);\n * ```\n *\n * ... or as a function:\n *\n * ```js\n * lib.define('bln', function (obj) {\n *   if ('boolean' === lib.of(obj)) return true;\n *   var blns = [ 'yes', 'no', 'true', 'false', 1, 0 ];\n *   if ('string' === lib.of(obj)) obj = obj.toLowerCase();\n *   return !! ~blns.indexOf(obj);\n * });\n * ```\n *\n * @param {String} type\n * @param {RegExp|Function} test\n * @api public\n */\n\nLibrary.prototype.define = function (type, test) {\n  if (arguments.length === 1) return this.tests[type];\n  this.tests[type] = test;\n  return this;\n};\n\n/**\n * #### .test (obj, test)\n *\n * Assert that an object is of type. Will first\n * check natives, and if that does not pass it will\n * use the user defined custom tests.\n *\n * ```js\n * assert(lib.test('1', 'int'));\n * assert(lib.test('yes', 'bln'));\n * ```\n *\n * @param {Mixed} object\n * @param {String} type\n * @return {Boolean} result\n * @api public\n */\n\nLibrary.prototype.test = function (obj, type) {\n  if (type === getType(obj)) return true;\n  var test = this.tests[type];\n\n  if (test && 'regexp' === getType(test)) {\n    return test.test(obj);\n  } else if (test && 'function' === getType(test)) {\n    return test(obj);\n  } else {\n    throw new ReferenceError('Type test \"' + type + '\" not defined or invalid.');\n  }\n};\n\n},{}],35:[function(require,module,exports){\narguments[4][33][0].apply(exports,arguments)\n},{\"./lib/type\":36,\"dup\":33}],36:[function(require,module,exports){\n/*!\n * type-detect\n * Copyright(c) 2013 jake luer <jake@alogicalparadox.com>\n * MIT Licensed\n */\n\n/*!\n * Primary Exports\n */\n\nvar exports = module.exports = getType;\n\n/**\n * ### typeOf (obj)\n *\n * Use several different techniques to determine\n * the type of object being tested.\n *\n *\n * @param {Mixed} object\n * @return {String} object type\n * @api public\n */\nvar objectTypeRegexp = /^\\[object (.*)\\]$/;\n\nfunction getType(obj) {\n  var type = Object.prototype.toString.call(obj).match(objectTypeRegexp)[1].toLowerCase();\n  // Let \"new String('')\" return 'object'\n  if (typeof Promise === 'function' && obj instanceof Promise) return 'promise';\n  // PhantomJS has type \"DOMWindow\" for null\n  if (obj === null) return 'null';\n  // PhantomJS has type \"DOMWindow\" for undefined\n  if (obj === undefined) return 'undefined';\n  return type;\n}\n\nexports.Library = Library;\n\n/**\n * ### Library\n *\n * Create a repository for custom type detection.\n *\n * ```js\n * var lib = new type.Library;\n * ```\n *\n */\n\nfunction Library() {\n  if (!(this instanceof Library)) return new Library();\n  this.tests = {};\n}\n\n/**\n * #### .of (obj)\n *\n * Expose replacement `typeof` detection to the library.\n *\n * ```js\n * if ('string' === lib.of('hello world')) {\n *   // ...\n * }\n * ```\n *\n * @param {Mixed} object to test\n * @return {String} type\n */\n\nLibrary.prototype.of = getType;\n\n/**\n * #### .define (type, test)\n *\n * Add a test to for the `.test()` assertion.\n *\n * Can be defined as a regular expression:\n *\n * ```js\n * lib.define('int', /^[0-9]+$/);\n * ```\n *\n * ... or as a function:\n *\n * ```js\n * lib.define('bln', function (obj) {\n *   if ('boolean' === lib.of(obj)) return true;\n *   var blns = [ 'yes', 'no', 'true', 'false', 1, 0 ];\n *   if ('string' === lib.of(obj)) obj = obj.toLowerCase();\n *   return !! ~blns.indexOf(obj);\n * });\n * ```\n *\n * @param {String} type\n * @param {RegExp|Function} test\n * @api public\n */\n\nLibrary.prototype.define = function(type, test) {\n  if (arguments.length === 1) return this.tests[type];\n  this.tests[type] = test;\n  return this;\n};\n\n/**\n * #### .test (obj, test)\n *\n * Assert that an object is of type. Will first\n * check natives, and if that does not pass it will\n * use the user defined custom tests.\n *\n * ```js\n * assert(lib.test('1', 'int'));\n * assert(lib.test('yes', 'bln'));\n * ```\n *\n * @param {Mixed} object\n * @param {String} type\n * @return {Boolean} result\n * @api public\n */\n\nLibrary.prototype.test = function(obj, type) {\n  if (type === getType(obj)) return true;\n  var test = this.tests[type];\n\n  if (test && 'regexp' === getType(test)) {\n    return test.test(obj);\n  } else if (test && 'function' === getType(test)) {\n    return test(obj);\n  } else {\n    throw new ReferenceError('Type test \"' + type + '\" not defined or invalid.');\n  }\n};\n\n},{}]},{},[1])(1)\n});\n"
  },
  {
    "path": "app_frontend/static/plugin/JavaScript-Canvas-to-Blob-3.7.0/test/vendor/load-image.js",
    "content": "/*\n * JavaScript Load Image\n * https://github.com/blueimp/JavaScript-Load-Image\n *\n * Copyright 2011, Sebastian Tschan\n * https://blueimp.net\n *\n * Licensed under the MIT license:\n * https://opensource.org/licenses/MIT\n */\n\n/* global define, URL, webkitURL, FileReader */\n\n;(function ($) {\n  'use strict'\n\n  // Loads an image for a given File object.\n  // Invokes the callback with an img or optional canvas\n  // element (if supported by the browser) as parameter:\n  function loadImage (file, callback, options) {\n    var img = document.createElement('img')\n    var url\n    img.onerror = function (event) {\n      return loadImage.onerror(img, event, file, callback, options)\n    }\n    img.onload = function (event) {\n      return loadImage.onload(img, event, file, callback, options)\n    }\n    if (loadImage.isInstanceOf('Blob', file) ||\n      // Files are also Blob instances, but some browsers\n      // (Firefox 3.6) support the File API but not Blobs:\n      loadImage.isInstanceOf('File', file)) {\n      url = img._objectURL = loadImage.createObjectURL(file)\n    } else if (typeof file === 'string') {\n      url = file\n      if (options && options.crossOrigin) {\n        img.crossOrigin = options.crossOrigin\n      }\n    } else {\n      return false\n    }\n    if (url) {\n      img.src = url\n      return img\n    }\n    return loadImage.readFile(file, function (e) {\n      var target = e.target\n      if (target && target.result) {\n        img.src = target.result\n      } else if (callback) {\n        callback(e)\n      }\n    })\n  }\n  // The check for URL.revokeObjectURL fixes an issue with Opera 12,\n  // which provides URL.createObjectURL but doesn't properly implement it:\n  var urlAPI = (window.createObjectURL && window) ||\n                (window.URL && URL.revokeObjectURL && URL) ||\n                (window.webkitURL && webkitURL)\n\n  function revokeHelper (img, options) {\n    if (img._objectURL && !(options && options.noRevoke)) {\n      loadImage.revokeObjectURL(img._objectURL)\n      delete img._objectURL\n    }\n  }\n\n  loadImage.isInstanceOf = function (type, obj) {\n    // Cross-frame instanceof check\n    return Object.prototype.toString.call(obj) === '[object ' + type + ']'\n  }\n\n  loadImage.transform = function (img, options, callback, file, data) {\n    callback(loadImage.scale(img, options, data), data)\n  }\n\n  loadImage.onerror = function (img, event, file, callback, options) {\n    revokeHelper(img, options)\n    if (callback) {\n      callback.call(img, event)\n    }\n  }\n\n  loadImage.onload = function (img, event, file, callback, options) {\n    revokeHelper(img, options)\n    if (callback) {\n      loadImage.transform(img, options, callback, file, {})\n    }\n  }\n\n  // Transform image coordinates, allows to override e.g.\n  // the canvas orientation based on the orientation option,\n  // gets canvas, options passed as arguments:\n  loadImage.transformCoordinates = function () {\n    return\n  }\n\n  // Returns transformed options, allows to override e.g.\n  // maxWidth, maxHeight and crop options based on the aspectRatio.\n  // gets img, options passed as arguments:\n  loadImage.getTransformedOptions = function (img, options) {\n    var aspectRatio = options.aspectRatio\n    var newOptions\n    var i\n    var width\n    var height\n    if (!aspectRatio) {\n      return options\n    }\n    newOptions = {}\n    for (i in options) {\n      if (options.hasOwnProperty(i)) {\n        newOptions[i] = options[i]\n      }\n    }\n    newOptions.crop = true\n    width = img.naturalWidth || img.width\n    height = img.naturalHeight || img.height\n    if (width / height > aspectRatio) {\n      newOptions.maxWidth = height * aspectRatio\n      newOptions.maxHeight = height\n    } else {\n      newOptions.maxWidth = width\n      newOptions.maxHeight = width / aspectRatio\n    }\n    return newOptions\n  }\n\n  // Canvas render method, allows to implement a different rendering algorithm:\n  loadImage.renderImageToCanvas = function (\n    canvas,\n    img,\n    sourceX,\n    sourceY,\n    sourceWidth,\n    sourceHeight,\n    destX,\n    destY,\n    destWidth,\n    destHeight\n  ) {\n    canvas.getContext('2d').drawImage(\n      img,\n      sourceX,\n      sourceY,\n      sourceWidth,\n      sourceHeight,\n      destX,\n      destY,\n      destWidth,\n      destHeight\n    )\n    return canvas\n  }\n\n  // Determines if the target image should be a canvas element:\n  loadImage.hasCanvasOption = function (options) {\n    return options.canvas || options.crop || !!options.aspectRatio\n  }\n\n  // Scales and/or crops the given image (img or canvas HTML element)\n  // using the given options.\n  // Returns a canvas object if the browser supports canvas\n  // and the hasCanvasOption method returns true or a canvas\n  // object is passed as image, else the scaled image:\n  loadImage.scale = function (img, options, data) {\n    options = options || {}\n    var canvas = document.createElement('canvas')\n    var useCanvas = img.getContext ||\n                    (loadImage.hasCanvasOption(options) && canvas.getContext)\n    var width = img.naturalWidth || img.width\n    var height = img.naturalHeight || img.height\n    var destWidth = width\n    var destHeight = height\n    var maxWidth\n    var maxHeight\n    var minWidth\n    var minHeight\n    var sourceWidth\n    var sourceHeight\n    var sourceX\n    var sourceY\n    var pixelRatio\n    var downsamplingRatio\n    var tmp\n    function scaleUp () {\n      var scale = Math.max(\n        (minWidth || destWidth) / destWidth,\n        (minHeight || destHeight) / destHeight\n      )\n      if (scale > 1) {\n        destWidth *= scale\n        destHeight *= scale\n      }\n    }\n    function scaleDown () {\n      var scale = Math.min(\n        (maxWidth || destWidth) / destWidth,\n        (maxHeight || destHeight) / destHeight\n      )\n      if (scale < 1) {\n        destWidth *= scale\n        destHeight *= scale\n      }\n    }\n    if (useCanvas) {\n      options = loadImage.getTransformedOptions(img, options, data)\n      sourceX = options.left || 0\n      sourceY = options.top || 0\n      if (options.sourceWidth) {\n        sourceWidth = options.sourceWidth\n        if (options.right !== undefined && options.left === undefined) {\n          sourceX = width - sourceWidth - options.right\n        }\n      } else {\n        sourceWidth = width - sourceX - (options.right || 0)\n      }\n      if (options.sourceHeight) {\n        sourceHeight = options.sourceHeight\n        if (options.bottom !== undefined && options.top === undefined) {\n          sourceY = height - sourceHeight - options.bottom\n        }\n      } else {\n        sourceHeight = height - sourceY - (options.bottom || 0)\n      }\n      destWidth = sourceWidth\n      destHeight = sourceHeight\n    }\n    maxWidth = options.maxWidth\n    maxHeight = options.maxHeight\n    minWidth = options.minWidth\n    minHeight = options.minHeight\n    if (useCanvas && maxWidth && maxHeight && options.crop) {\n      destWidth = maxWidth\n      destHeight = maxHeight\n      tmp = sourceWidth / sourceHeight - maxWidth / maxHeight\n      if (tmp < 0) {\n        sourceHeight = maxHeight * sourceWidth / maxWidth\n        if (options.top === undefined && options.bottom === undefined) {\n          sourceY = (height - sourceHeight) / 2\n        }\n      } else if (tmp > 0) {\n        sourceWidth = maxWidth * sourceHeight / maxHeight\n        if (options.left === undefined && options.right === undefined) {\n          sourceX = (width - sourceWidth) / 2\n        }\n      }\n    } else {\n      if (options.contain || options.cover) {\n        minWidth = maxWidth = maxWidth || minWidth\n        minHeight = maxHeight = maxHeight || minHeight\n      }\n      if (options.cover) {\n        scaleDown()\n        scaleUp()\n      } else {\n        scaleUp()\n        scaleDown()\n      }\n    }\n    if (useCanvas) {\n      pixelRatio = options.pixelRatio\n      if (pixelRatio > 1) {\n        canvas.style.width = destWidth + 'px'\n        canvas.style.height = destHeight + 'px'\n        destWidth *= pixelRatio\n        destHeight *= pixelRatio\n        canvas.getContext('2d').scale(pixelRatio, pixelRatio)\n      }\n      downsamplingRatio = options.downsamplingRatio\n      if (downsamplingRatio > 0 && downsamplingRatio < 1 &&\n            destWidth < sourceWidth && destHeight < sourceHeight) {\n        while (sourceWidth * downsamplingRatio > destWidth) {\n          canvas.width = sourceWidth * downsamplingRatio\n          canvas.height = sourceHeight * downsamplingRatio\n          loadImage.renderImageToCanvas(\n            canvas,\n            img,\n            sourceX,\n            sourceY,\n            sourceWidth,\n            sourceHeight,\n            0,\n            0,\n            canvas.width,\n            canvas.height\n          )\n          sourceX = 0\n          sourceY = 0\n          sourceWidth = canvas.width\n          sourceHeight = canvas.height\n          img = document.createElement('canvas')\n          img.width = sourceWidth\n          img.height = sourceHeight\n          loadImage.renderImageToCanvas(\n            img,\n            canvas,\n            0,\n            0,\n            sourceWidth,\n            sourceHeight,\n            0,\n            0,\n            sourceWidth,\n            sourceHeight\n          )\n        }\n      }\n      canvas.width = destWidth\n      canvas.height = destHeight\n      loadImage.transformCoordinates(\n        canvas,\n        options\n      )\n      return loadImage.renderImageToCanvas(\n        canvas,\n        img,\n        sourceX,\n        sourceY,\n        sourceWidth,\n        sourceHeight,\n        0,\n        0,\n        destWidth,\n        destHeight\n      )\n    }\n    img.width = destWidth\n    img.height = destHeight\n    return img\n  }\n\n  loadImage.createObjectURL = function (file) {\n    return urlAPI ? urlAPI.createObjectURL(file) : false\n  }\n\n  loadImage.revokeObjectURL = function (url) {\n    return urlAPI ? urlAPI.revokeObjectURL(url) : false\n  }\n\n  // Loads a given File object via FileReader interface,\n  // invokes the callback with the event object (load or error).\n  // The result can be read via event.target.result:\n  loadImage.readFile = function (file, callback, method) {\n    if (window.FileReader) {\n      var fileReader = new FileReader()\n      fileReader.onload = fileReader.onerror = callback\n      method = method || 'readAsDataURL'\n      if (fileReader[method]) {\n        fileReader[method](file)\n        return fileReader\n      }\n    }\n    return false\n  }\n\n  if (typeof define === 'function' && define.amd) {\n    define(function () {\n      return loadImage\n    })\n  } else if (typeof module === 'object' && module.exports) {\n    module.exports = loadImage\n  } else {\n    $.loadImage = loadImage\n  }\n}(window))\n"
  },
  {
    "path": "app_frontend/static/plugin/JavaScript-Canvas-to-Blob-3.7.0/test/vendor/mocha.css",
    "content": "@charset \"utf-8\";\n\nbody {\n  margin:0;\n}\n\n#mocha {\n  font: 20px/1.5 \"Helvetica Neue\", Helvetica, Arial, sans-serif;\n  margin: 60px 50px;\n}\n\n#mocha ul,\n#mocha li {\n  margin: 0;\n  padding: 0;\n}\n\n#mocha ul {\n  list-style: none;\n}\n\n#mocha h1,\n#mocha h2 {\n  margin: 0;\n}\n\n#mocha h1 {\n  margin-top: 15px;\n  font-size: 1em;\n  font-weight: 200;\n}\n\n#mocha h1 a {\n  text-decoration: none;\n  color: inherit;\n}\n\n#mocha h1 a:hover {\n  text-decoration: underline;\n}\n\n#mocha .suite .suite h1 {\n  margin-top: 0;\n  font-size: .8em;\n}\n\n#mocha .hidden {\n  display: none;\n}\n\n#mocha h2 {\n  font-size: 12px;\n  font-weight: normal;\n  cursor: pointer;\n}\n\n#mocha .suite {\n  margin-left: 15px;\n}\n\n#mocha .test {\n  margin-left: 15px;\n  overflow: hidden;\n}\n\n#mocha .test.pending:hover h2::after {\n  content: '(pending)';\n  font-family: arial, sans-serif;\n}\n\n#mocha .test.pass.medium .duration {\n  background: #c09853;\n}\n\n#mocha .test.pass.slow .duration {\n  background: #b94a48;\n}\n\n#mocha .test.pass::before {\n  content: '✓';\n  font-size: 12px;\n  display: block;\n  float: left;\n  margin-right: 5px;\n  color: #00d6b2;\n}\n\n#mocha .test.pass .duration {\n  font-size: 9px;\n  margin-left: 5px;\n  padding: 2px 5px;\n  color: #fff;\n  -webkit-box-shadow: inset 0 1px 1px rgba(0,0,0,.2);\n  -moz-box-shadow: inset 0 1px 1px rgba(0,0,0,.2);\n  box-shadow: inset 0 1px 1px rgba(0,0,0,.2);\n  -webkit-border-radius: 5px;\n  -moz-border-radius: 5px;\n  -ms-border-radius: 5px;\n  -o-border-radius: 5px;\n  border-radius: 5px;\n}\n\n#mocha .test.pass.fast .duration {\n  display: none;\n}\n\n#mocha .test.pending {\n  color: #0b97c4;\n}\n\n#mocha .test.pending::before {\n  content: '◦';\n  color: #0b97c4;\n}\n\n#mocha .test.fail {\n  color: #c00;\n}\n\n#mocha .test.fail pre {\n  color: black;\n}\n\n#mocha .test.fail::before {\n  content: '✖';\n  font-size: 12px;\n  display: block;\n  float: left;\n  margin-right: 5px;\n  color: #c00;\n}\n\n#mocha .test pre.error {\n  color: #c00;\n  max-height: 300px;\n  overflow: auto;\n}\n\n#mocha .test .html-error {\n  overflow: auto;\n  color: black;\n  line-height: 1.5;\n  display: block;\n  float: left;\n  clear: left;\n  font: 12px/1.5 monaco, monospace;\n  margin: 5px;\n  padding: 15px;\n  border: 1px solid #eee;\n  max-width: 85%; /*(1)*/\n  max-width: -webkit-calc(100% - 42px);\n  max-width: -moz-calc(100% - 42px);\n  max-width: calc(100% - 42px); /*(2)*/\n  max-height: 300px;\n  word-wrap: break-word;\n  border-bottom-color: #ddd;\n  -webkit-box-shadow: 0 1px 3px #eee;\n  -moz-box-shadow: 0 1px 3px #eee;\n  box-shadow: 0 1px 3px #eee;\n  -webkit-border-radius: 3px;\n  -moz-border-radius: 3px;\n  border-radius: 3px;\n}\n\n#mocha .test .html-error pre.error {\n  border: none;\n  -webkit-border-radius: 0;\n  -moz-border-radius: 0;\n  border-radius: 0;\n  -webkit-box-shadow: 0;\n  -moz-box-shadow: 0;\n  box-shadow: 0;\n  padding: 0;\n  margin: 0;\n  margin-top: 18px;\n  max-height: none;\n}\n\n/**\n * (1): approximate for browsers not supporting calc\n * (2): 42 = 2*15 + 2*10 + 2*1 (padding + margin + border)\n *      ^^ seriously\n */\n#mocha .test pre {\n  display: block;\n  float: left;\n  clear: left;\n  font: 12px/1.5 monaco, monospace;\n  margin: 5px;\n  padding: 15px;\n  border: 1px solid #eee;\n  max-width: 85%; /*(1)*/\n  max-width: -webkit-calc(100% - 42px);\n  max-width: -moz-calc(100% - 42px);\n  max-width: calc(100% - 42px); /*(2)*/\n  word-wrap: break-word;\n  border-bottom-color: #ddd;\n  -webkit-box-shadow: 0 1px 3px #eee;\n  -moz-box-shadow: 0 1px 3px #eee;\n  box-shadow: 0 1px 3px #eee;\n  -webkit-border-radius: 3px;\n  -moz-border-radius: 3px;\n  border-radius: 3px;\n}\n\n#mocha .test h2 {\n  position: relative;\n}\n\n#mocha .test a.replay {\n  position: absolute;\n  top: 3px;\n  right: 0;\n  text-decoration: none;\n  vertical-align: middle;\n  display: block;\n  width: 15px;\n  height: 15px;\n  line-height: 15px;\n  text-align: center;\n  background: #eee;\n  font-size: 15px;\n  -webkit-border-radius: 15px;\n  -moz-border-radius: 15px;\n  border-radius: 15px;\n  -webkit-transition:opacity 200ms;\n  -moz-transition:opacity 200ms;\n  -o-transition:opacity 200ms;\n  transition: opacity 200ms;\n  opacity: 0.3;\n  color: #888;\n}\n\n#mocha .test:hover a.replay {\n  opacity: 1;\n}\n\n#mocha-report.pass .test.fail {\n  display: none;\n}\n\n#mocha-report.fail .test.pass {\n  display: none;\n}\n\n#mocha-report.pending .test.pass,\n#mocha-report.pending .test.fail {\n  display: none;\n}\n#mocha-report.pending .test.pass.pending {\n  display: block;\n}\n\n#mocha-error {\n  color: #c00;\n  font-size: 1.5em;\n  font-weight: 100;\n  letter-spacing: 1px;\n}\n\n#mocha-stats {\n  position: fixed;\n  top: 15px;\n  right: 10px;\n  font-size: 12px;\n  margin: 0;\n  color: #888;\n  z-index: 1;\n}\n\n#mocha-stats .progress {\n  float: right;\n  padding-top: 0;\n\n  /**\n   * Set safe initial values, so mochas .progress does not inherit these\n   * properties from Bootstrap .progress (which causes .progress height to\n   * equal line height set in Bootstrap).\n   */\n  height: auto;\n  -webkit-box-shadow: none;\n  -moz-box-shadow: none;\n  box-shadow: none;\n  background-color: initial;\n}\n\n#mocha-stats em {\n  color: black;\n}\n\n#mocha-stats a {\n  text-decoration: none;\n  color: inherit;\n}\n\n#mocha-stats a:hover {\n  border-bottom: 1px solid #eee;\n}\n\n#mocha-stats li {\n  display: inline-block;\n  margin: 0 5px;\n  list-style: none;\n  padding-top: 11px;\n}\n\n#mocha-stats canvas {\n  width: 40px;\n  height: 40px;\n}\n\n#mocha code .comment { color: #ddd; }\n#mocha code .init { color: #2f6fad; }\n#mocha code .string { color: #5890ad; }\n#mocha code .keyword { color: #8a6343; }\n#mocha code .number { color: #2f6fad; }\n\n@media screen and (max-device-width: 480px) {\n  #mocha {\n    margin: 60px 0px;\n  }\n\n  #mocha #stats {\n    position: absolute;\n  }\n}\n"
  },
  {
    "path": "app_frontend/static/plugin/JavaScript-Canvas-to-Blob-3.7.0/test/vendor/mocha.js",
    "content": "(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require==\"function\"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error(\"Cannot find module '\"+o+\"'\");throw f.code=\"MODULE_NOT_FOUND\",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require==\"function\"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){\n(function (process,global){\n/* eslint no-unused-vars: off */\n\n/**\n * Shim process.stdout.\n */\n\nprocess.stdout = require('browser-stdout')();\n\nvar Mocha = require('./lib/mocha');\n\n/**\n * Create a Mocha instance.\n *\n * @return {undefined}\n */\n\nvar mocha = new Mocha({ reporter: 'html' });\n\n/**\n * Save timer references to avoid Sinon interfering (see GH-237).\n */\n\nvar Date = global.Date;\nvar setTimeout = global.setTimeout;\nvar setInterval = global.setInterval;\nvar clearTimeout = global.clearTimeout;\nvar clearInterval = global.clearInterval;\n\nvar uncaughtExceptionHandlers = [];\n\nvar originalOnerrorHandler = global.onerror;\n\n/**\n * Remove uncaughtException listener.\n * Revert to original onerror handler if previously defined.\n */\n\nprocess.removeListener = function(e, fn) {\n  if (e === 'uncaughtException') {\n    if (originalOnerrorHandler) {\n      global.onerror = originalOnerrorHandler;\n    } else {\n      global.onerror = function() {};\n    }\n    var i = Mocha.utils.indexOf(uncaughtExceptionHandlers, fn);\n    if (i !== -1) {\n      uncaughtExceptionHandlers.splice(i, 1);\n    }\n  }\n};\n\n/**\n * Implements uncaughtException listener.\n */\n\nprocess.on = function(e, fn) {\n  if (e === 'uncaughtException') {\n    global.onerror = function(err, url, line) {\n      fn(new Error(err + ' (' + url + ':' + line + ')'));\n      return !mocha.allowUncaught;\n    };\n    uncaughtExceptionHandlers.push(fn);\n  }\n};\n\n// The BDD UI is registered by default, but no UI will be functional in the\n// browser without an explicit call to the overridden `mocha.ui` (see below).\n// Ensure that this default UI does not expose its methods to the global scope.\nmocha.suite.removeAllListeners('pre-require');\n\nvar immediateQueue = [];\nvar immediateTimeout;\n\nfunction timeslice() {\n  var immediateStart = new Date().getTime();\n  while (immediateQueue.length && (new Date().getTime() - immediateStart) < 100) {\n    immediateQueue.shift()();\n  }\n  if (immediateQueue.length) {\n    immediateTimeout = setTimeout(timeslice, 0);\n  } else {\n    immediateTimeout = null;\n  }\n}\n\n/**\n * High-performance override of Runner.immediately.\n */\n\nMocha.Runner.immediately = function(callback) {\n  immediateQueue.push(callback);\n  if (!immediateTimeout) {\n    immediateTimeout = setTimeout(timeslice, 0);\n  }\n};\n\n/**\n * Function to allow assertion libraries to throw errors directly into mocha.\n * This is useful when running tests in a browser because window.onerror will\n * only receive the 'message' attribute of the Error.\n */\nmocha.throwError = function(err) {\n  Mocha.utils.forEach(uncaughtExceptionHandlers, function(fn) {\n    fn(err);\n  });\n  throw err;\n};\n\n/**\n * Override ui to ensure that the ui functions are initialized.\n * Normally this would happen in Mocha.prototype.loadFiles.\n */\n\nmocha.ui = function(ui) {\n  Mocha.prototype.ui.call(this, ui);\n  this.suite.emit('pre-require', global, null, this);\n  return this;\n};\n\n/**\n * Setup mocha with the given setting options.\n */\n\nmocha.setup = function(opts) {\n  if (typeof opts === 'string') {\n    opts = { ui: opts };\n  }\n  for (var opt in opts) {\n    if (opts.hasOwnProperty(opt)) {\n      this[opt](opts[opt]);\n    }\n  }\n  return this;\n};\n\n/**\n * Run mocha, returning the Runner.\n */\n\nmocha.run = function(fn) {\n  var options = mocha.options;\n  mocha.globals('location');\n\n  var query = Mocha.utils.parseQuery(global.location.search || '');\n  if (query.grep) {\n    mocha.grep(query.grep);\n  }\n  if (query.fgrep) {\n    mocha.fgrep(query.fgrep);\n  }\n  if (query.invert) {\n    mocha.invert();\n  }\n\n  return Mocha.prototype.run.call(mocha, function(err) {\n    // The DOM Document is not available in Web Workers.\n    var document = global.document;\n    if (document && document.getElementById('mocha') && options.noHighlighting !== true) {\n      Mocha.utils.highlightTags('code');\n    }\n    if (fn) {\n      fn(err);\n    }\n  });\n};\n\n/**\n * Expose the process shim.\n * https://github.com/mochajs/mocha/pull/916\n */\n\nMocha.process = process;\n\n/**\n * Expose mocha.\n */\n\nglobal.Mocha = Mocha;\nglobal.mocha = mocha;\n\n// this allows test/acceptance/required-tokens.js to pass; thus,\n// you can now do `const describe = require('mocha').describe` in a\n// browser context (assuming browserification).  should fix #880\nmodule.exports = global;\n\n}).call(this,require('_process'),typeof global !== \"undefined\" ? global : typeof self !== \"undefined\" ? self : typeof window !== \"undefined\" ? window : {})\n},{\"./lib/mocha\":14,\"_process\":67,\"browser-stdout\":41}],2:[function(require,module,exports){\n/* eslint-disable no-unused-vars */\nmodule.exports = function(type) {\n  return function() {};\n};\n\n},{}],3:[function(require,module,exports){\n/**\n * Module exports.\n */\n\nexports.EventEmitter = EventEmitter;\n\n/**\n * Object#toString reference.\n */\nvar objToString = Object.prototype.toString;\n\n/**\n * Check if a value is an array.\n *\n * @api private\n * @param {*} val The value to test.\n * @return {boolean} true if the value is an array, otherwise false.\n */\nfunction isArray(val) {\n  return objToString.call(val) === '[object Array]';\n}\n\n/**\n * Event emitter constructor.\n *\n * @api public\n */\nfunction EventEmitter() {}\n\n/**\n * Add a listener.\n *\n * @api public\n * @param {string} name Event name.\n * @param {Function} fn Event handler.\n * @return {EventEmitter} Emitter instance.\n */\nEventEmitter.prototype.on = function(name, fn) {\n  if (!this.$events) {\n    this.$events = {};\n  }\n\n  if (!this.$events[name]) {\n    this.$events[name] = fn;\n  } else if (isArray(this.$events[name])) {\n    this.$events[name].push(fn);\n  } else {\n    this.$events[name] = [this.$events[name], fn];\n  }\n\n  return this;\n};\n\nEventEmitter.prototype.addListener = EventEmitter.prototype.on;\n\n/**\n * Adds a volatile listener.\n *\n * @api public\n * @param {string} name Event name.\n * @param {Function} fn Event handler.\n * @return {EventEmitter} Emitter instance.\n */\nEventEmitter.prototype.once = function(name, fn) {\n  var self = this;\n\n  function on() {\n    self.removeListener(name, on);\n    fn.apply(this, arguments);\n  }\n\n  on.listener = fn;\n  this.on(name, on);\n\n  return this;\n};\n\n/**\n * Remove a listener.\n *\n * @api public\n * @param {string} name Event name.\n * @param {Function} fn Event handler.\n * @return {EventEmitter} Emitter instance.\n */\nEventEmitter.prototype.removeListener = function(name, fn) {\n  if (this.$events && this.$events[name]) {\n    var list = this.$events[name];\n\n    if (isArray(list)) {\n      var pos = -1;\n\n      for (var i = 0, l = list.length; i < l; i++) {\n        if (list[i] === fn || (list[i].listener && list[i].listener === fn)) {\n          pos = i;\n          break;\n        }\n      }\n\n      if (pos < 0) {\n        return this;\n      }\n\n      list.splice(pos, 1);\n\n      if (!list.length) {\n        delete this.$events[name];\n      }\n    } else if (list === fn || (list.listener && list.listener === fn)) {\n      delete this.$events[name];\n    }\n  }\n\n  return this;\n};\n\n/**\n * Remove all listeners for an event.\n *\n * @api public\n * @param {string} name Event name.\n * @return {EventEmitter} Emitter instance.\n */\nEventEmitter.prototype.removeAllListeners = function(name) {\n  if (name === undefined) {\n    this.$events = {};\n    return this;\n  }\n\n  if (this.$events && this.$events[name]) {\n    this.$events[name] = null;\n  }\n\n  return this;\n};\n\n/**\n * Get all listeners for a given event.\n *\n * @api public\n * @param {string} name Event name.\n * @return {EventEmitter} Emitter instance.\n */\nEventEmitter.prototype.listeners = function(name) {\n  if (!this.$events) {\n    this.$events = {};\n  }\n\n  if (!this.$events[name]) {\n    this.$events[name] = [];\n  }\n\n  if (!isArray(this.$events[name])) {\n    this.$events[name] = [this.$events[name]];\n  }\n\n  return this.$events[name];\n};\n\n/**\n * Emit an event.\n *\n * @api public\n * @param {string} name Event name.\n * @return {boolean} true if at least one handler was invoked, else false.\n */\nEventEmitter.prototype.emit = function(name) {\n  if (!this.$events) {\n    return false;\n  }\n\n  var handler = this.$events[name];\n\n  if (!handler) {\n    return false;\n  }\n\n  var args = Array.prototype.slice.call(arguments, 1);\n\n  if (typeof handler === 'function') {\n    handler.apply(this, args);\n  } else if (isArray(handler)) {\n    var listeners = handler.slice();\n\n    for (var i = 0, l = listeners.length; i < l; i++) {\n      listeners[i].apply(this, args);\n    }\n  } else {\n    return false;\n  }\n\n  return true;\n};\n\n},{}],4:[function(require,module,exports){\n/**\n * Expose `Progress`.\n */\n\nmodule.exports = Progress;\n\n/**\n * Initialize a new `Progress` indicator.\n */\nfunction Progress() {\n  this.percent = 0;\n  this.size(0);\n  this.fontSize(11);\n  this.font('helvetica, arial, sans-serif');\n}\n\n/**\n * Set progress size to `size`.\n *\n * @api public\n * @param {number} size\n * @return {Progress} Progress instance.\n */\nProgress.prototype.size = function(size) {\n  this._size = size;\n  return this;\n};\n\n/**\n * Set text to `text`.\n *\n * @api public\n * @param {string} text\n * @return {Progress} Progress instance.\n */\nProgress.prototype.text = function(text) {\n  this._text = text;\n  return this;\n};\n\n/**\n * Set font size to `size`.\n *\n * @api public\n * @param {number} size\n * @return {Progress} Progress instance.\n */\nProgress.prototype.fontSize = function(size) {\n  this._fontSize = size;\n  return this;\n};\n\n/**\n * Set font to `family`.\n *\n * @param {string} family\n * @return {Progress} Progress instance.\n */\nProgress.prototype.font = function(family) {\n  this._font = family;\n  return this;\n};\n\n/**\n * Update percentage to `n`.\n *\n * @param {number} n\n * @return {Progress} Progress instance.\n */\nProgress.prototype.update = function(n) {\n  this.percent = n;\n  return this;\n};\n\n/**\n * Draw on `ctx`.\n *\n * @param {CanvasRenderingContext2d} ctx\n * @return {Progress} Progress instance.\n */\nProgress.prototype.draw = function(ctx) {\n  try {\n    var percent = Math.min(this.percent, 100);\n    var size = this._size;\n    var half = size / 2;\n    var x = half;\n    var y = half;\n    var rad = half - 1;\n    var fontSize = this._fontSize;\n\n    ctx.font = fontSize + 'px ' + this._font;\n\n    var angle = Math.PI * 2 * (percent / 100);\n    ctx.clearRect(0, 0, size, size);\n\n    // outer circle\n    ctx.strokeStyle = '#9f9f9f';\n    ctx.beginPath();\n    ctx.arc(x, y, rad, 0, angle, false);\n    ctx.stroke();\n\n    // inner circle\n    ctx.strokeStyle = '#eee';\n    ctx.beginPath();\n    ctx.arc(x, y, rad - 1, 0, angle, true);\n    ctx.stroke();\n\n    // text\n    var text = this._text || (percent | 0) + '%';\n    var w = ctx.measureText(text).width;\n\n    ctx.fillText(text, x - w / 2 + 1, y + fontSize / 2 - 1);\n  } catch (err) {\n    // don't fail if we can't render progress\n  }\n  return this;\n};\n\n},{}],5:[function(require,module,exports){\n(function (global){\nexports.isatty = function isatty() {\n  return true;\n};\n\nexports.getWindowSize = function getWindowSize() {\n  if ('innerHeight' in global) {\n    return [global.innerHeight, global.innerWidth];\n  }\n  // In a Web Worker, the DOM Window is not available.\n  return [640, 480];\n};\n\n}).call(this,typeof global !== \"undefined\" ? global : typeof self !== \"undefined\" ? self : typeof window !== \"undefined\" ? window : {})\n},{}],6:[function(require,module,exports){\n/**\n * Module dependencies.\n */\n\nvar JSON = require('json3');\n\n/**\n * Expose `Context`.\n */\n\nmodule.exports = Context;\n\n/**\n * Initialize a new `Context`.\n *\n * @api private\n */\nfunction Context() {}\n\n/**\n * Set or get the context `Runnable` to `runnable`.\n *\n * @api private\n * @param {Runnable} runnable\n * @return {Context}\n */\nContext.prototype.runnable = function(runnable) {\n  if (!arguments.length) {\n    return this._runnable;\n  }\n  this.test = this._runnable = runnable;\n  return this;\n};\n\n/**\n * Set test timeout `ms`.\n *\n * @api private\n * @param {number} ms\n * @return {Context} self\n */\nContext.prototype.timeout = function(ms) {\n  if (!arguments.length) {\n    return this.runnable().timeout();\n  }\n  this.runnable().timeout(ms);\n  return this;\n};\n\n/**\n * Set test timeout `enabled`.\n *\n * @api private\n * @param {boolean} enabled\n * @return {Context} self\n */\nContext.prototype.enableTimeouts = function(enabled) {\n  this.runnable().enableTimeouts(enabled);\n  return this;\n};\n\n/**\n * Set test slowness threshold `ms`.\n *\n * @api private\n * @param {number} ms\n * @return {Context} self\n */\nContext.prototype.slow = function(ms) {\n  this.runnable().slow(ms);\n  return this;\n};\n\n/**\n * Mark a test as skipped.\n *\n * @api private\n * @return {Context} self\n */\nContext.prototype.skip = function() {\n  this.runnable().skip();\n  return this;\n};\n\n/**\n * Allow a number of retries on failed tests\n *\n * @api private\n * @param {number} n\n * @return {Context} self\n */\nContext.prototype.retries = function(n) {\n  if (!arguments.length) {\n    return this.runnable().retries();\n  }\n  this.runnable().retries(n);\n  return this;\n};\n\n/**\n * Inspect the context void of `._runnable`.\n *\n * @api private\n * @return {string}\n */\nContext.prototype.inspect = function() {\n  return JSON.stringify(this, function(key, val) {\n    return key === 'runnable' || key === 'test' ? undefined : val;\n  }, 2);\n};\n\n},{\"json3\":54}],7:[function(require,module,exports){\n/**\n * Module dependencies.\n */\n\nvar Runnable = require('./runnable');\nvar inherits = require('./utils').inherits;\n\n/**\n * Expose `Hook`.\n */\n\nmodule.exports = Hook;\n\n/**\n * Initialize a new `Hook` with the given `title` and callback `fn`.\n *\n * @param {String} title\n * @param {Function} fn\n * @api private\n */\nfunction Hook(title, fn) {\n  Runnable.call(this, title, fn);\n  this.type = 'hook';\n}\n\n/**\n * Inherit from `Runnable.prototype`.\n */\ninherits(Hook, Runnable);\n\n/**\n * Get or set the test `err`.\n *\n * @param {Error} err\n * @return {Error}\n * @api public\n */\nHook.prototype.error = function(err) {\n  if (!arguments.length) {\n    err = this._error;\n    this._error = null;\n    return err;\n  }\n\n  this._error = err;\n};\n\n},{\"./runnable\":33,\"./utils\":38}],8:[function(require,module,exports){\n/**\n * Module dependencies.\n */\n\nvar Test = require('../test');\n\n/**\n * BDD-style interface:\n *\n *      describe('Array', function() {\n *        describe('#indexOf()', function() {\n *          it('should return -1 when not present', function() {\n *            // ...\n *          });\n *\n *          it('should return the index when present', function() {\n *            // ...\n *          });\n *        });\n *      });\n *\n * @param {Suite} suite Root suite.\n */\nmodule.exports = function(suite) {\n  var suites = [suite];\n\n  suite.on('pre-require', function(context, file, mocha) {\n    var common = require('./common')(suites, context, mocha);\n\n    context.before = common.before;\n    context.after = common.after;\n    context.beforeEach = common.beforeEach;\n    context.afterEach = common.afterEach;\n    context.run = mocha.options.delay && common.runWithSuite(suite);\n    /**\n     * Describe a \"suite\" with the given `title`\n     * and callback `fn` containing nested suites\n     * and/or tests.\n     */\n\n    context.describe = context.context = function(title, fn) {\n      return common.suite.create({\n        title: title,\n        file: file,\n        fn: fn\n      });\n    };\n\n    /**\n     * Pending describe.\n     */\n\n    context.xdescribe = context.xcontext = context.describe.skip = function(title, fn) {\n      return common.suite.skip({\n        title: title,\n        file: file,\n        fn: fn\n      });\n    };\n\n    /**\n     * Exclusive suite.\n     */\n\n    context.describe.only = function(title, fn) {\n      return common.suite.only({\n        title: title,\n        file: file,\n        fn: fn\n      });\n    };\n\n    /**\n     * Describe a specification or test-case\n     * with the given `title` and callback `fn`\n     * acting as a thunk.\n     */\n\n    context.it = context.specify = function(title, fn) {\n      var suite = suites[0];\n      if (suite.isPending()) {\n        fn = null;\n      }\n      var test = new Test(title, fn);\n      test.file = file;\n      suite.addTest(test);\n      return test;\n    };\n\n    /**\n     * Exclusive test-case.\n     */\n\n    context.it.only = function(title, fn) {\n      return common.test.only(mocha, context.it(title, fn));\n    };\n\n    /**\n     * Pending test case.\n     */\n\n    context.xit = context.xspecify = context.it.skip = function(title) {\n      context.it(title);\n    };\n\n    /**\n     * Number of attempts to retry.\n     */\n    context.it.retries = function(n) {\n      context.retries(n);\n    };\n  });\n};\n\n},{\"../test\":36,\"./common\":9}],9:[function(require,module,exports){\n'use strict';\n\nvar Suite = require('../suite');\n\n/**\n * Functions common to more than one interface.\n *\n * @param {Suite[]} suites\n * @param {Context} context\n * @param {Mocha} mocha\n * @return {Object} An object containing common functions.\n */\nmodule.exports = function(suites, context, mocha) {\n  return {\n    /**\n     * This is only present if flag --delay is passed into Mocha. It triggers\n     * root suite execution.\n     *\n     * @param {Suite} suite The root wuite.\n     * @return {Function} A function which runs the root suite\n     */\n    runWithSuite: function runWithSuite(suite) {\n      return function run() {\n        suite.run();\n      };\n    },\n\n    /**\n     * Execute before running tests.\n     *\n     * @param {string} name\n     * @param {Function} fn\n     */\n    before: function(name, fn) {\n      suites[0].beforeAll(name, fn);\n    },\n\n    /**\n     * Execute after running tests.\n     *\n     * @param {string} name\n     * @param {Function} fn\n     */\n    after: function(name, fn) {\n      suites[0].afterAll(name, fn);\n    },\n\n    /**\n     * Execute before each test case.\n     *\n     * @param {string} name\n     * @param {Function} fn\n     */\n    beforeEach: function(name, fn) {\n      suites[0].beforeEach(name, fn);\n    },\n\n    /**\n     * Execute after each test case.\n     *\n     * @param {string} name\n     * @param {Function} fn\n     */\n    afterEach: function(name, fn) {\n      suites[0].afterEach(name, fn);\n    },\n\n    suite: {\n      /**\n       * Create an exclusive Suite; convenience function\n       * See docstring for create() below.\n       *\n       * @param {Object} opts\n       * @returns {Suite}\n       */\n      only: function only(opts) {\n        mocha.options.hasOnly = true;\n        opts.isOnly = true;\n        return this.create(opts);\n      },\n\n      /**\n       * Create a Suite, but skip it; convenience function\n       * See docstring for create() below.\n       *\n       * @param {Object} opts\n       * @returns {Suite}\n       */\n      skip: function skip(opts) {\n        opts.pending = true;\n        return this.create(opts);\n      },\n\n      /**\n       * Creates a suite.\n       * @param {Object} opts Options\n       * @param {string} opts.title Title of Suite\n       * @param {Function} [opts.fn] Suite Function (not always applicable)\n       * @param {boolean} [opts.pending] Is Suite pending?\n       * @param {string} [opts.file] Filepath where this Suite resides\n       * @param {boolean} [opts.isOnly] Is Suite exclusive?\n       * @returns {Suite}\n       */\n      create: function create(opts) {\n        var suite = Suite.create(suites[0], opts.title);\n        suite.pending = Boolean(opts.pending);\n        suite.file = opts.file;\n        suites.unshift(suite);\n        if (opts.isOnly) {\n          suite.parent._onlySuites = suite.parent._onlySuites.concat(suite);\n          mocha.options.hasOnly = true;\n        }\n        if (typeof opts.fn === 'function') {\n          opts.fn.call(suite);\n          suites.shift();\n        } else if (typeof opts.fn === 'undefined' && !suite.pending) {\n          throw new Error('Suite \"' + suite.fullTitle() + '\" was defined but no callback was supplied. Supply a callback or explicitly skip the suite.');\n        }\n\n        return suite;\n      }\n    },\n\n    test: {\n\n      /**\n       * Exclusive test-case.\n       *\n       * @param {Object} mocha\n       * @param {Function} test\n       * @returns {*}\n       */\n      only: function(mocha, test) {\n        test.parent._onlyTests = test.parent._onlyTests.concat(test);\n        mocha.options.hasOnly = true;\n        return test;\n      },\n\n      /**\n       * Pending test case.\n       *\n       * @param {string} title\n       */\n      skip: function(title) {\n        context.test(title);\n      },\n\n      /**\n       * Number of retry attempts\n       *\n       * @param {number} n\n       */\n      retries: function(n) {\n        context.retries(n);\n      }\n    }\n  };\n};\n\n},{\"../suite\":35}],10:[function(require,module,exports){\n/**\n * Module dependencies.\n */\n\nvar Suite = require('../suite');\nvar Test = require('../test');\n\n/**\n * Exports-style (as Node.js module) interface:\n *\n *     exports.Array = {\n *       '#indexOf()': {\n *         'should return -1 when the value is not present': function() {\n *\n *         },\n *\n *         'should return the correct index when the value is present': function() {\n *\n *         }\n *       }\n *     };\n *\n * @param {Suite} suite Root suite.\n */\nmodule.exports = function(suite) {\n  var suites = [suite];\n\n  suite.on('require', visit);\n\n  function visit(obj, file) {\n    var suite;\n    for (var key in obj) {\n      if (typeof obj[key] === 'function') {\n        var fn = obj[key];\n        switch (key) {\n          case 'before':\n            suites[0].beforeAll(fn);\n            break;\n          case 'after':\n            suites[0].afterAll(fn);\n            break;\n          case 'beforeEach':\n            suites[0].beforeEach(fn);\n            break;\n          case 'afterEach':\n            suites[0].afterEach(fn);\n            break;\n          default:\n            var test = new Test(key, fn);\n            test.file = file;\n            suites[0].addTest(test);\n        }\n      } else {\n        suite = Suite.create(suites[0], key);\n        suites.unshift(suite);\n        visit(obj[key], file);\n        suites.shift();\n      }\n    }\n  }\n};\n\n},{\"../suite\":35,\"../test\":36}],11:[function(require,module,exports){\nexports.bdd = require('./bdd');\nexports.tdd = require('./tdd');\nexports.qunit = require('./qunit');\nexports.exports = require('./exports');\n\n},{\"./bdd\":8,\"./exports\":10,\"./qunit\":12,\"./tdd\":13}],12:[function(require,module,exports){\n/**\n * Module dependencies.\n */\n\nvar Test = require('../test');\n\n/**\n * QUnit-style interface:\n *\n *     suite('Array');\n *\n *     test('#length', function() {\n *       var arr = [1,2,3];\n *       ok(arr.length == 3);\n *     });\n *\n *     test('#indexOf()', function() {\n *       var arr = [1,2,3];\n *       ok(arr.indexOf(1) == 0);\n *       ok(arr.indexOf(2) == 1);\n *       ok(arr.indexOf(3) == 2);\n *     });\n *\n *     suite('String');\n *\n *     test('#length', function() {\n *       ok('foo'.length == 3);\n *     });\n *\n * @param {Suite} suite Root suite.\n */\nmodule.exports = function(suite) {\n  var suites = [suite];\n\n  suite.on('pre-require', function(context, file, mocha) {\n    var common = require('./common')(suites, context, mocha);\n\n    context.before = common.before;\n    context.after = common.after;\n    context.beforeEach = common.beforeEach;\n    context.afterEach = common.afterEach;\n    context.run = mocha.options.delay && common.runWithSuite(suite);\n    /**\n     * Describe a \"suite\" with the given `title`.\n     */\n\n    context.suite = function(title) {\n      if (suites.length > 1) {\n        suites.shift();\n      }\n      return common.suite.create({\n        title: title,\n        file: file,\n        fn: false\n      });\n    };\n\n    /**\n     * Exclusive Suite.\n     */\n\n    context.suite.only = function(title) {\n      if (suites.length > 1) {\n        suites.shift();\n      }\n      return common.suite.only({\n        title: title,\n        file: file,\n        fn: false\n      });\n    };\n\n    /**\n     * Describe a specification or test-case\n     * with the given `title` and callback `fn`\n     * acting as a thunk.\n     */\n\n    context.test = function(title, fn) {\n      var test = new Test(title, fn);\n      test.file = file;\n      suites[0].addTest(test);\n      return test;\n    };\n\n    /**\n     * Exclusive test-case.\n     */\n\n    context.test.only = function(title, fn) {\n      return common.test.only(mocha, context.test(title, fn));\n    };\n\n    context.test.skip = common.test.skip;\n    context.test.retries = common.test.retries;\n  });\n};\n\n},{\"../test\":36,\"./common\":9}],13:[function(require,module,exports){\n/**\n * Module dependencies.\n */\n\nvar Test = require('../test');\n\n/**\n * TDD-style interface:\n *\n *      suite('Array', function() {\n *        suite('#indexOf()', function() {\n *          suiteSetup(function() {\n *\n *          });\n *\n *          test('should return -1 when not present', function() {\n *\n *          });\n *\n *          test('should return the index when present', function() {\n *\n *          });\n *\n *          suiteTeardown(function() {\n *\n *          });\n *        });\n *      });\n *\n * @param {Suite} suite Root suite.\n */\nmodule.exports = function(suite) {\n  var suites = [suite];\n\n  suite.on('pre-require', function(context, file, mocha) {\n    var common = require('./common')(suites, context, mocha);\n\n    context.setup = common.beforeEach;\n    context.teardown = common.afterEach;\n    context.suiteSetup = common.before;\n    context.suiteTeardown = common.after;\n    context.run = mocha.options.delay && common.runWithSuite(suite);\n\n    /**\n     * Describe a \"suite\" with the given `title` and callback `fn` containing\n     * nested suites and/or tests.\n     */\n    context.suite = function(title, fn) {\n      return common.suite.create({\n        title: title,\n        file: file,\n        fn: fn\n      });\n    };\n\n    /**\n     * Pending suite.\n     */\n    context.suite.skip = function(title, fn) {\n      return common.suite.skip({\n        title: title,\n        file: file,\n        fn: fn\n      });\n    };\n\n    /**\n     * Exclusive test-case.\n     */\n    context.suite.only = function(title, fn) {\n      return common.suite.only({\n        title: title,\n        file: file,\n        fn: fn\n      });\n    };\n\n    /**\n     * Describe a specification or test-case with the given `title` and\n     * callback `fn` acting as a thunk.\n     */\n    context.test = function(title, fn) {\n      var suite = suites[0];\n      if (suite.isPending()) {\n        fn = null;\n      }\n      var test = new Test(title, fn);\n      test.file = file;\n      suite.addTest(test);\n      return test;\n    };\n\n    /**\n     * Exclusive test-case.\n     */\n\n    context.test.only = function(title, fn) {\n      return common.test.only(mocha, context.test(title, fn));\n    };\n\n    context.test.skip = common.test.skip;\n    context.test.retries = common.test.retries;\n  });\n};\n\n},{\"../test\":36,\"./common\":9}],14:[function(require,module,exports){\n(function (process,global,__dirname){\n/*!\n * mocha\n * Copyright(c) 2011 TJ Holowaychuk <tj@vision-media.ca>\n * MIT Licensed\n */\n\n/**\n * Module dependencies.\n */\n\nvar escapeRe = require('escape-string-regexp');\nvar path = require('path');\nvar reporters = require('./reporters');\nvar utils = require('./utils');\n\n/**\n * Expose `Mocha`.\n */\n\nexports = module.exports = Mocha;\n\n/**\n * To require local UIs and reporters when running in node.\n */\n\nif (!process.browser) {\n  var cwd = process.cwd();\n  module.paths.push(cwd, path.join(cwd, 'node_modules'));\n}\n\n/**\n * Expose internals.\n */\n\nexports.utils = utils;\nexports.interfaces = require('./interfaces');\nexports.reporters = reporters;\nexports.Runnable = require('./runnable');\nexports.Context = require('./context');\nexports.Runner = require('./runner');\nexports.Suite = require('./suite');\nexports.Hook = require('./hook');\nexports.Test = require('./test');\n\n/**\n * Return image `name` path.\n *\n * @api private\n * @param {string} name\n * @return {string}\n */\nfunction image(name) {\n  return path.join(__dirname, '../images', name + '.png');\n}\n\n/**\n * Set up mocha with `options`.\n *\n * Options:\n *\n *   - `ui` name \"bdd\", \"tdd\", \"exports\" etc\n *   - `reporter` reporter instance, defaults to `mocha.reporters.spec`\n *   - `globals` array of accepted globals\n *   - `timeout` timeout in milliseconds\n *   - `retries` number of times to retry failed tests\n *   - `bail` bail on the first test failure\n *   - `slow` milliseconds to wait before considering a test slow\n *   - `ignoreLeaks` ignore global leaks\n *   - `fullTrace` display the full stack-trace on failing\n *   - `grep` string or regexp to filter tests with\n *\n * @param {Object} options\n * @api public\n */\nfunction Mocha(options) {\n  options = options || {};\n  this.files = [];\n  this.options = options;\n  if (options.grep) {\n    this.grep(new RegExp(options.grep));\n  }\n  if (options.fgrep) {\n    this.fgrep(options.fgrep);\n  }\n  this.suite = new exports.Suite('', new exports.Context());\n  this.ui(options.ui);\n  this.bail(options.bail);\n  this.reporter(options.reporter, options.reporterOptions);\n  if (typeof options.timeout !== 'undefined' && options.timeout !== null) {\n    this.timeout(options.timeout);\n  }\n  if (typeof options.retries !== 'undefined' && options.retries !== null) {\n    this.retries(options.retries);\n  }\n  this.useColors(options.useColors);\n  if (options.enableTimeouts !== null) {\n    this.enableTimeouts(options.enableTimeouts);\n  }\n  if (options.slow) {\n    this.slow(options.slow);\n  }\n}\n\n/**\n * Enable or disable bailing on the first failure.\n *\n * @api public\n * @param {boolean} [bail]\n */\nMocha.prototype.bail = function(bail) {\n  if (!arguments.length) {\n    bail = true;\n  }\n  this.suite.bail(bail);\n  return this;\n};\n\n/**\n * Add test `file`.\n *\n * @api public\n * @param {string} file\n */\nMocha.prototype.addFile = function(file) {\n  this.files.push(file);\n  return this;\n};\n\n/**\n * Set reporter to `reporter`, defaults to \"spec\".\n *\n * @param {String|Function} reporter name or constructor\n * @param {Object} reporterOptions optional options\n * @api public\n * @param {string|Function} reporter name or constructor\n * @param {Object} reporterOptions optional options\n */\nMocha.prototype.reporter = function(reporter, reporterOptions) {\n  if (typeof reporter === 'function') {\n    this._reporter = reporter;\n  } else {\n    reporter = reporter || 'spec';\n    var _reporter;\n    // Try to load a built-in reporter.\n    if (reporters[reporter]) {\n      _reporter = reporters[reporter];\n    }\n    // Try to load reporters from process.cwd() and node_modules\n    if (!_reporter) {\n      try {\n        _reporter = require(reporter);\n      } catch (err) {\n        err.message.indexOf('Cannot find module') !== -1\n          ? console.warn('\"' + reporter + '\" reporter not found')\n          : console.warn('\"' + reporter + '\" reporter blew up with error:\\n' + err.stack);\n      }\n    }\n    if (!_reporter && reporter === 'teamcity') {\n      console.warn('The Teamcity reporter was moved to a package named '\n        + 'mocha-teamcity-reporter '\n        + '(https://npmjs.org/package/mocha-teamcity-reporter).');\n    }\n    if (!_reporter) {\n      throw new Error('invalid reporter \"' + reporter + '\"');\n    }\n    this._reporter = _reporter;\n  }\n  this.options.reporterOptions = reporterOptions;\n  return this;\n};\n\n/**\n * Set test UI `name`, defaults to \"bdd\".\n *\n * @api public\n * @param {string} bdd\n */\nMocha.prototype.ui = function(name) {\n  name = name || 'bdd';\n  this._ui = exports.interfaces[name];\n  if (!this._ui) {\n    try {\n      this._ui = require(name);\n    } catch (err) {\n      throw new Error('invalid interface \"' + name + '\"');\n    }\n  }\n  this._ui = this._ui(this.suite);\n\n  this.suite.on('pre-require', function(context) {\n    exports.afterEach = context.afterEach || context.teardown;\n    exports.after = context.after || context.suiteTeardown;\n    exports.beforeEach = context.beforeEach || context.setup;\n    exports.before = context.before || context.suiteSetup;\n    exports.describe = context.describe || context.suite;\n    exports.it = context.it || context.test;\n    exports.setup = context.setup || context.beforeEach;\n    exports.suiteSetup = context.suiteSetup || context.before;\n    exports.suiteTeardown = context.suiteTeardown || context.after;\n    exports.suite = context.suite || context.describe;\n    exports.teardown = context.teardown || context.afterEach;\n    exports.test = context.test || context.it;\n    exports.run = context.run;\n  });\n\n  return this;\n};\n\n/**\n * Load registered files.\n *\n * @api private\n */\nMocha.prototype.loadFiles = function(fn) {\n  var self = this;\n  var suite = this.suite;\n  this.files.forEach(function(file) {\n    file = path.resolve(file);\n    suite.emit('pre-require', global, file, self);\n    suite.emit('require', require(file), file, self);\n    suite.emit('post-require', global, file, self);\n  });\n  fn && fn();\n};\n\n/**\n * Enable growl support.\n *\n * @api private\n */\nMocha.prototype._growl = function(runner, reporter) {\n  var notify = require('growl');\n\n  runner.on('end', function() {\n    var stats = reporter.stats;\n    if (stats.failures) {\n      var msg = stats.failures + ' of ' + runner.total + ' tests failed';\n      notify(msg, { name: 'mocha', title: 'Failed', image: image('error') });\n    } else {\n      notify(stats.passes + ' tests passed in ' + stats.duration + 'ms', {\n        name: 'mocha',\n        title: 'Passed',\n        image: image('ok')\n      });\n    }\n  });\n};\n\n/**\n * Escape string and add it to grep as a regexp.\n *\n * @api public\n * @param str\n * @returns {Mocha}\n */\nMocha.prototype.fgrep = function(str) {\n  return this.grep(new RegExp(escapeRe(str)));\n};\n\n/**\n * Add regexp to grep, if `re` is a string it is escaped.\n *\n * @param {RegExp|String} re\n * @return {Mocha}\n * @api public\n * @param {RegExp|string} re\n * @return {Mocha}\n */\nMocha.prototype.grep = function(re) {\n  if (utils.isString(re)) {\n    // extract args if it's regex-like, i.e: [string, pattern, flag]\n    var arg = re.match(/^\\/(.*)\\/(g|i|)$|.*/);\n    this.options.grep = new RegExp(arg[1] || arg[0], arg[2]);\n  } else {\n    this.options.grep = re;\n  }\n  return this;\n};\n/**\n * Invert `.grep()` matches.\n *\n * @return {Mocha}\n * @api public\n */\nMocha.prototype.invert = function() {\n  this.options.invert = true;\n  return this;\n};\n\n/**\n * Ignore global leaks.\n *\n * @param {Boolean} ignore\n * @return {Mocha}\n * @api public\n * @param {boolean} ignore\n * @return {Mocha}\n */\nMocha.prototype.ignoreLeaks = function(ignore) {\n  this.options.ignoreLeaks = Boolean(ignore);\n  return this;\n};\n\n/**\n * Enable global leak checking.\n *\n * @return {Mocha}\n * @api public\n */\nMocha.prototype.checkLeaks = function() {\n  this.options.ignoreLeaks = false;\n  return this;\n};\n\n/**\n * Display long stack-trace on failing\n *\n * @return {Mocha}\n * @api public\n */\nMocha.prototype.fullTrace = function() {\n  this.options.fullStackTrace = true;\n  return this;\n};\n\n/**\n * Enable growl support.\n *\n * @return {Mocha}\n * @api public\n */\nMocha.prototype.growl = function() {\n  this.options.growl = true;\n  return this;\n};\n\n/**\n * Ignore `globals` array or string.\n *\n * @param {Array|String} globals\n * @return {Mocha}\n * @api public\n * @param {Array|string} globals\n * @return {Mocha}\n */\nMocha.prototype.globals = function(globals) {\n  this.options.globals = (this.options.globals || []).concat(globals);\n  return this;\n};\n\n/**\n * Emit color output.\n *\n * @param {Boolean} colors\n * @return {Mocha}\n * @api public\n * @param {boolean} colors\n * @return {Mocha}\n */\nMocha.prototype.useColors = function(colors) {\n  if (colors !== undefined) {\n    this.options.useColors = colors;\n  }\n  return this;\n};\n\n/**\n * Use inline diffs rather than +/-.\n *\n * @param {Boolean} inlineDiffs\n * @return {Mocha}\n * @api public\n * @param {boolean} inlineDiffs\n * @return {Mocha}\n */\nMocha.prototype.useInlineDiffs = function(inlineDiffs) {\n  this.options.useInlineDiffs = inlineDiffs !== undefined && inlineDiffs;\n  return this;\n};\n\n/**\n * Set the timeout in milliseconds.\n *\n * @param {Number} timeout\n * @return {Mocha}\n * @api public\n * @param {number} timeout\n * @return {Mocha}\n */\nMocha.prototype.timeout = function(timeout) {\n  this.suite.timeout(timeout);\n  return this;\n};\n\n/**\n * Set the number of times to retry failed tests.\n *\n * @param {Number} retry times\n * @return {Mocha}\n * @api public\n */\nMocha.prototype.retries = function(n) {\n  this.suite.retries(n);\n  return this;\n};\n\n/**\n * Set slowness threshold in milliseconds.\n *\n * @param {Number} slow\n * @return {Mocha}\n * @api public\n * @param {number} slow\n * @return {Mocha}\n */\nMocha.prototype.slow = function(slow) {\n  this.suite.slow(slow);\n  return this;\n};\n\n/**\n * Enable timeouts.\n *\n * @param {Boolean} enabled\n * @return {Mocha}\n * @api public\n * @param {boolean} enabled\n * @return {Mocha}\n */\nMocha.prototype.enableTimeouts = function(enabled) {\n  this.suite.enableTimeouts(arguments.length && enabled !== undefined ? enabled : true);\n  return this;\n};\n\n/**\n * Makes all tests async (accepting a callback)\n *\n * @return {Mocha}\n * @api public\n */\nMocha.prototype.asyncOnly = function() {\n  this.options.asyncOnly = true;\n  return this;\n};\n\n/**\n * Disable syntax highlighting (in browser).\n *\n * @api public\n */\nMocha.prototype.noHighlighting = function() {\n  this.options.noHighlighting = true;\n  return this;\n};\n\n/**\n * Enable uncaught errors to propagate (in browser).\n *\n * @return {Mocha}\n * @api public\n */\nMocha.prototype.allowUncaught = function() {\n  this.options.allowUncaught = true;\n  return this;\n};\n\n/**\n * Delay root suite execution.\n * @returns {Mocha}\n */\nMocha.prototype.delay = function delay() {\n  this.options.delay = true;\n  return this;\n};\n\n/**\n * Run tests and invoke `fn()` when complete.\n *\n * @api public\n * @param {Function} fn\n * @return {Runner}\n */\nMocha.prototype.run = function(fn) {\n  if (this.files.length) {\n    this.loadFiles();\n  }\n  var suite = this.suite;\n  var options = this.options;\n  options.files = this.files;\n  var runner = new exports.Runner(suite, options.delay);\n  var reporter = new this._reporter(runner, options);\n  runner.ignoreLeaks = options.ignoreLeaks !== false;\n  runner.fullStackTrace = options.fullStackTrace;\n  runner.hasOnly = options.hasOnly;\n  runner.asyncOnly = options.asyncOnly;\n  runner.allowUncaught = options.allowUncaught;\n  if (options.grep) {\n    runner.grep(options.grep, options.invert);\n  }\n  if (options.globals) {\n    runner.globals(options.globals);\n  }\n  if (options.growl) {\n    this._growl(runner, reporter);\n  }\n  if (options.useColors !== undefined) {\n    exports.reporters.Base.useColors = options.useColors;\n  }\n  exports.reporters.Base.inlineDiffs = options.useInlineDiffs;\n\n  function done(failures) {\n    if (reporter.done) {\n      reporter.done(failures, fn);\n    } else {\n      fn && fn(failures);\n    }\n  }\n\n  return runner.run(done);\n};\n\n}).call(this,require('_process'),typeof global !== \"undefined\" ? global : typeof self !== \"undefined\" ? self : typeof window !== \"undefined\" ? window : {},\"/lib\")\n},{\"./context\":6,\"./hook\":7,\"./interfaces\":11,\"./reporters\":21,\"./runnable\":33,\"./runner\":34,\"./suite\":35,\"./test\":36,\"./utils\":38,\"_process\":67,\"escape-string-regexp\":47,\"growl\":49,\"path\":42}],15:[function(require,module,exports){\n/**\n * Helpers.\n */\n\nvar s = 1000;\nvar m = s * 60;\nvar h = m * 60;\nvar d = h * 24;\nvar y = d * 365.25;\n\n/**\n * Parse or format the given `val`.\n *\n * Options:\n *\n *  - `long` verbose formatting [false]\n *\n * @api public\n * @param {string|number} val\n * @param {Object} options\n * @return {string|number}\n */\nmodule.exports = function(val, options) {\n  options = options || {};\n  if (typeof val === 'string') {\n    return parse(val);\n  }\n  // https://github.com/mochajs/mocha/pull/1035\n  return options['long'] ? longFormat(val) : shortFormat(val);\n};\n\n/**\n * Parse the given `str` and return milliseconds.\n *\n * @api private\n * @param {string} str\n * @return {number}\n */\nfunction parse(str) {\n  var match = (/^((?:\\d+)?\\.?\\d+) *(ms|seconds?|s|minutes?|m|hours?|h|days?|d|years?|y)?$/i).exec(str);\n  if (!match) {\n    return;\n  }\n  var n = parseFloat(match[1]);\n  var type = (match[2] || 'ms').toLowerCase();\n  switch (type) {\n    case 'years':\n    case 'year':\n    case 'y':\n      return n * y;\n    case 'days':\n    case 'day':\n    case 'd':\n      return n * d;\n    case 'hours':\n    case 'hour':\n    case 'h':\n      return n * h;\n    case 'minutes':\n    case 'minute':\n    case 'm':\n      return n * m;\n    case 'seconds':\n    case 'second':\n    case 's':\n      return n * s;\n    case 'ms':\n      return n;\n    default:\n      // No default case\n  }\n}\n\n/**\n * Short format for `ms`.\n *\n * @api private\n * @param {number} ms\n * @return {string}\n */\nfunction shortFormat(ms) {\n  if (ms >= d) {\n    return Math.round(ms / d) + 'd';\n  }\n  if (ms >= h) {\n    return Math.round(ms / h) + 'h';\n  }\n  if (ms >= m) {\n    return Math.round(ms / m) + 'm';\n  }\n  if (ms >= s) {\n    return Math.round(ms / s) + 's';\n  }\n  return ms + 'ms';\n}\n\n/**\n * Long format for `ms`.\n *\n * @api private\n * @param {number} ms\n * @return {string}\n */\nfunction longFormat(ms) {\n  return plural(ms, d, 'day')\n    || plural(ms, h, 'hour')\n    || plural(ms, m, 'minute')\n    || plural(ms, s, 'second')\n    || ms + ' ms';\n}\n\n/**\n * Pluralization helper.\n *\n * @api private\n * @param {number} ms\n * @param {number} n\n * @param {string} name\n */\nfunction plural(ms, n, name) {\n  if (ms < n) {\n    return;\n  }\n  if (ms < n * 1.5) {\n    return Math.floor(ms / n) + ' ' + name;\n  }\n  return Math.ceil(ms / n) + ' ' + name + 's';\n}\n\n},{}],16:[function(require,module,exports){\n\n/**\n * Expose `Pending`.\n */\n\nmodule.exports = Pending;\n\n/**\n * Initialize a new `Pending` error with the given message.\n *\n * @param {string} message\n */\nfunction Pending(message) {\n  this.message = message;\n}\n\n},{}],17:[function(require,module,exports){\n(function (process,global){\n/**\n * Module dependencies.\n */\n\nvar tty = require('tty');\nvar diff = require('diff');\nvar ms = require('../ms');\nvar utils = require('../utils');\nvar supportsColor = process.browser ? null : require('supports-color');\n\n/**\n * Expose `Base`.\n */\n\nexports = module.exports = Base;\n\n/**\n * Save timer references to avoid Sinon interfering.\n * See: https://github.com/mochajs/mocha/issues/237\n */\n\n/* eslint-disable no-unused-vars, no-native-reassign */\nvar Date = global.Date;\nvar setTimeout = global.setTimeout;\nvar setInterval = global.setInterval;\nvar clearTimeout = global.clearTimeout;\nvar clearInterval = global.clearInterval;\n/* eslint-enable no-unused-vars, no-native-reassign */\n\n/**\n * Check if both stdio streams are associated with a tty.\n */\n\nvar isatty = tty.isatty(1) && tty.isatty(2);\n\n/**\n * Enable coloring by default, except in the browser interface.\n */\n\nexports.useColors = !process.browser && (supportsColor || (process.env.MOCHA_COLORS !== undefined));\n\n/**\n * Inline diffs instead of +/-\n */\n\nexports.inlineDiffs = false;\n\n/**\n * Default color map.\n */\n\nexports.colors = {\n  pass: 90,\n  fail: 31,\n  'bright pass': 92,\n  'bright fail': 91,\n  'bright yellow': 93,\n  pending: 36,\n  suite: 0,\n  'error title': 0,\n  'error message': 31,\n  'error stack': 90,\n  checkmark: 32,\n  fast: 90,\n  medium: 33,\n  slow: 31,\n  green: 32,\n  light: 90,\n  'diff gutter': 90,\n  'diff added': 32,\n  'diff removed': 31\n};\n\n/**\n * Default symbol map.\n */\n\nexports.symbols = {\n  ok: '✓',\n  err: '✖',\n  dot: '․',\n  comma: ',',\n  bang: '!'\n};\n\n// With node.js on Windows: use symbols available in terminal default fonts\nif (process.platform === 'win32') {\n  exports.symbols.ok = '\\u221A';\n  exports.symbols.err = '\\u00D7';\n  exports.symbols.dot = '.';\n}\n\n/**\n * Color `str` with the given `type`,\n * allowing colors to be disabled,\n * as well as user-defined color\n * schemes.\n *\n * @param {string} type\n * @param {string} str\n * @return {string}\n * @api private\n */\nvar color = exports.color = function(type, str) {\n  if (!exports.useColors) {\n    return String(str);\n  }\n  return '\\u001b[' + exports.colors[type] + 'm' + str + '\\u001b[0m';\n};\n\n/**\n * Expose term window size, with some defaults for when stderr is not a tty.\n */\n\nexports.window = {\n  width: 75\n};\n\nif (isatty) {\n  exports.window.width = process.stdout.getWindowSize\n      ? process.stdout.getWindowSize(1)[0]\n      : tty.getWindowSize()[1];\n}\n\n/**\n * Expose some basic cursor interactions that are common among reporters.\n */\n\nexports.cursor = {\n  hide: function() {\n    isatty && process.stdout.write('\\u001b[?25l');\n  },\n\n  show: function() {\n    isatty && process.stdout.write('\\u001b[?25h');\n  },\n\n  deleteLine: function() {\n    isatty && process.stdout.write('\\u001b[2K');\n  },\n\n  beginningOfLine: function() {\n    isatty && process.stdout.write('\\u001b[0G');\n  },\n\n  CR: function() {\n    if (isatty) {\n      exports.cursor.deleteLine();\n      exports.cursor.beginningOfLine();\n    } else {\n      process.stdout.write('\\r');\n    }\n  }\n};\n\n/**\n * Outut the given `failures` as a list.\n *\n * @param {Array} failures\n * @api public\n */\n\nexports.list = function(failures) {\n  console.log();\n  failures.forEach(function(test, i) {\n    // format\n    var fmt = color('error title', '  %s) %s:\\n')\n      + color('error message', '     %s')\n      + color('error stack', '\\n%s\\n');\n\n    // msg\n    var msg;\n    var err = test.err;\n    var message;\n    if (err.message && typeof err.message.toString === 'function') {\n      message = err.message + '';\n    } else if (typeof err.inspect === 'function') {\n      message = err.inspect() + '';\n    } else {\n      message = '';\n    }\n    var stack = err.stack || message;\n    var index = message ? stack.indexOf(message) : -1;\n    var actual = err.actual;\n    var expected = err.expected;\n    var escape = true;\n\n    if (index === -1) {\n      msg = message;\n    } else {\n      index += message.length;\n      msg = stack.slice(0, index);\n      // remove msg from stack\n      stack = stack.slice(index + 1);\n    }\n\n    // uncaught\n    if (err.uncaught) {\n      msg = 'Uncaught ' + msg;\n    }\n    // explicitly show diff\n    if (err.showDiff !== false && sameType(actual, expected) && expected !== undefined) {\n      escape = false;\n      if (!(utils.isString(actual) && utils.isString(expected))) {\n        err.actual = actual = utils.stringify(actual);\n        err.expected = expected = utils.stringify(expected);\n      }\n\n      fmt = color('error title', '  %s) %s:\\n%s') + color('error stack', '\\n%s\\n');\n      var match = message.match(/^([^:]+): expected/);\n      msg = '\\n      ' + color('error message', match ? match[1] : msg);\n\n      if (exports.inlineDiffs) {\n        msg += inlineDiff(err, escape);\n      } else {\n        msg += unifiedDiff(err, escape);\n      }\n    }\n\n    // indent stack trace\n    stack = stack.replace(/^/gm, '  ');\n\n    console.log(fmt, (i + 1), test.fullTitle(), msg, stack);\n  });\n};\n\n/**\n * Initialize a new `Base` reporter.\n *\n * All other reporters generally\n * inherit from this reporter, providing\n * stats such as test duration, number\n * of tests passed / failed etc.\n *\n * @param {Runner} runner\n * @api public\n */\n\nfunction Base(runner) {\n  var stats = this.stats = { suites: 0, tests: 0, passes: 0, pending: 0, failures: 0 };\n  var failures = this.failures = [];\n\n  if (!runner) {\n    return;\n  }\n  this.runner = runner;\n\n  runner.stats = stats;\n\n  runner.on('start', function() {\n    stats.start = new Date();\n  });\n\n  runner.on('suite', function(suite) {\n    stats.suites = stats.suites || 0;\n    suite.root || stats.suites++;\n  });\n\n  runner.on('test end', function() {\n    stats.tests = stats.tests || 0;\n    stats.tests++;\n  });\n\n  runner.on('pass', function(test) {\n    stats.passes = stats.passes || 0;\n\n    if (test.duration > test.slow()) {\n      test.speed = 'slow';\n    } else if (test.duration > test.slow() / 2) {\n      test.speed = 'medium';\n    } else {\n      test.speed = 'fast';\n    }\n\n    stats.passes++;\n  });\n\n  runner.on('fail', function(test, err) {\n    stats.failures = stats.failures || 0;\n    stats.failures++;\n    test.err = err;\n    failures.push(test);\n  });\n\n  runner.on('end', function() {\n    stats.end = new Date();\n    stats.duration = new Date() - stats.start;\n  });\n\n  runner.on('pending', function() {\n    stats.pending++;\n  });\n}\n\n/**\n * Output common epilogue used by many of\n * the bundled reporters.\n *\n * @api public\n */\nBase.prototype.epilogue = function() {\n  var stats = this.stats;\n  var fmt;\n\n  console.log();\n\n  // passes\n  fmt = color('bright pass', ' ')\n    + color('green', ' %d passing')\n    + color('light', ' (%s)');\n\n  console.log(fmt,\n    stats.passes || 0,\n    ms(stats.duration));\n\n  // pending\n  if (stats.pending) {\n    fmt = color('pending', ' ')\n      + color('pending', ' %d pending');\n\n    console.log(fmt, stats.pending);\n  }\n\n  // failures\n  if (stats.failures) {\n    fmt = color('fail', '  %d failing');\n\n    console.log(fmt, stats.failures);\n\n    Base.list(this.failures);\n    console.log();\n  }\n\n  console.log();\n};\n\n/**\n * Pad the given `str` to `len`.\n *\n * @api private\n * @param {string} str\n * @param {string} len\n * @return {string}\n */\nfunction pad(str, len) {\n  str = String(str);\n  return Array(len - str.length + 1).join(' ') + str;\n}\n\n/**\n * Returns an inline diff between 2 strings with coloured ANSI output\n *\n * @api private\n * @param {Error} err with actual/expected\n * @param {boolean} escape\n * @return {string} Diff\n */\nfunction inlineDiff(err, escape) {\n  var msg = errorDiff(err, 'WordsWithSpace', escape);\n\n  // linenos\n  var lines = msg.split('\\n');\n  if (lines.length > 4) {\n    var width = String(lines.length).length;\n    msg = lines.map(function(str, i) {\n      return pad(++i, width) + ' |' + ' ' + str;\n    }).join('\\n');\n  }\n\n  // legend\n  msg = '\\n'\n    + color('diff removed', 'actual')\n    + ' '\n    + color('diff added', 'expected')\n    + '\\n\\n'\n    + msg\n    + '\\n';\n\n  // indent\n  msg = msg.replace(/^/gm, '      ');\n  return msg;\n}\n\n/**\n * Returns a unified diff between two strings.\n *\n * @api private\n * @param {Error} err with actual/expected\n * @param {boolean} escape\n * @return {string} The diff.\n */\nfunction unifiedDiff(err, escape) {\n  var indent = '      ';\n  function cleanUp(line) {\n    if (escape) {\n      line = escapeInvisibles(line);\n    }\n    if (line[0] === '+') {\n      return indent + colorLines('diff added', line);\n    }\n    if (line[0] === '-') {\n      return indent + colorLines('diff removed', line);\n    }\n    if (line.match(/\\@\\@/)) {\n      return null;\n    }\n    if (line.match(/\\\\ No newline/)) {\n      return null;\n    }\n    return indent + line;\n  }\n  function notBlank(line) {\n    return typeof line !== 'undefined' && line !== null;\n  }\n  var msg = diff.createPatch('string', err.actual, err.expected);\n  var lines = msg.split('\\n').splice(4);\n  return '\\n      '\n    + colorLines('diff added', '+ expected') + ' '\n    + colorLines('diff removed', '- actual')\n    + '\\n\\n'\n    + lines.map(cleanUp).filter(notBlank).join('\\n');\n}\n\n/**\n * Return a character diff for `err`.\n *\n * @api private\n * @param {Error} err\n * @param {string} type\n * @param {boolean} escape\n * @return {string}\n */\nfunction errorDiff(err, type, escape) {\n  var actual = escape ? escapeInvisibles(err.actual) : err.actual;\n  var expected = escape ? escapeInvisibles(err.expected) : err.expected;\n  return diff['diff' + type](actual, expected).map(function(str) {\n    if (str.added) {\n      return colorLines('diff added', str.value);\n    }\n    if (str.removed) {\n      return colorLines('diff removed', str.value);\n    }\n    return str.value;\n  }).join('');\n}\n\n/**\n * Returns a string with all invisible characters in plain text\n *\n * @api private\n * @param {string} line\n * @return {string}\n */\nfunction escapeInvisibles(line) {\n  return line.replace(/\\t/g, '<tab>')\n    .replace(/\\r/g, '<CR>')\n    .replace(/\\n/g, '<LF>\\n');\n}\n\n/**\n * Color lines for `str`, using the color `name`.\n *\n * @api private\n * @param {string} name\n * @param {string} str\n * @return {string}\n */\nfunction colorLines(name, str) {\n  return str.split('\\n').map(function(str) {\n    return color(name, str);\n  }).join('\\n');\n}\n\n/**\n * Object#toString reference.\n */\nvar objToString = Object.prototype.toString;\n\n/**\n * Check that a / b have the same type.\n *\n * @api private\n * @param {Object} a\n * @param {Object} b\n * @return {boolean}\n */\nfunction sameType(a, b) {\n  return objToString.call(a) === objToString.call(b);\n}\n\n}).call(this,require('_process'),typeof global !== \"undefined\" ? global : typeof self !== \"undefined\" ? self : typeof window !== \"undefined\" ? window : {})\n},{\"../ms\":15,\"../utils\":38,\"_process\":67,\"diff\":46,\"supports-color\":42,\"tty\":5}],18:[function(require,module,exports){\n/**\n * Module dependencies.\n */\n\nvar Base = require('./base');\nvar utils = require('../utils');\n\n/**\n * Expose `Doc`.\n */\n\nexports = module.exports = Doc;\n\n/**\n * Initialize a new `Doc` reporter.\n *\n * @param {Runner} runner\n * @api public\n */\nfunction Doc(runner) {\n  Base.call(this, runner);\n\n  var indents = 2;\n\n  function indent() {\n    return Array(indents).join('  ');\n  }\n\n  runner.on('suite', function(suite) {\n    if (suite.root) {\n      return;\n    }\n    ++indents;\n    console.log('%s<section class=\"suite\">', indent());\n    ++indents;\n    console.log('%s<h1>%s</h1>', indent(), utils.escape(suite.title));\n    console.log('%s<dl>', indent());\n  });\n\n  runner.on('suite end', function(suite) {\n    if (suite.root) {\n      return;\n    }\n    console.log('%s</dl>', indent());\n    --indents;\n    console.log('%s</section>', indent());\n    --indents;\n  });\n\n  runner.on('pass', function(test) {\n    console.log('%s  <dt>%s</dt>', indent(), utils.escape(test.title));\n    var code = utils.escape(utils.clean(test.body));\n    console.log('%s  <dd><pre><code>%s</code></pre></dd>', indent(), code);\n  });\n\n  runner.on('fail', function(test, err) {\n    console.log('%s  <dt class=\"error\">%s</dt>', indent(), utils.escape(test.title));\n    var code = utils.escape(utils.clean(test.body));\n    console.log('%s  <dd class=\"error\"><pre><code>%s</code></pre></dd>', indent(), code);\n    console.log('%s  <dd class=\"error\">%s</dd>', indent(), utils.escape(err));\n  });\n}\n\n},{\"../utils\":38,\"./base\":17}],19:[function(require,module,exports){\n(function (process){\n/**\n * Module dependencies.\n */\n\nvar Base = require('./base');\nvar inherits = require('../utils').inherits;\nvar color = Base.color;\n\n/**\n * Expose `Dot`.\n */\n\nexports = module.exports = Dot;\n\n/**\n * Initialize a new `Dot` matrix test reporter.\n *\n * @api public\n * @param {Runner} runner\n */\nfunction Dot(runner) {\n  Base.call(this, runner);\n\n  var self = this;\n  var width = Base.window.width * .75 | 0;\n  var n = -1;\n\n  runner.on('start', function() {\n    process.stdout.write('\\n');\n  });\n\n  runner.on('pending', function() {\n    if (++n % width === 0) {\n      process.stdout.write('\\n  ');\n    }\n    process.stdout.write(color('pending', Base.symbols.comma));\n  });\n\n  runner.on('pass', function(test) {\n    if (++n % width === 0) {\n      process.stdout.write('\\n  ');\n    }\n    if (test.speed === 'slow') {\n      process.stdout.write(color('bright yellow', Base.symbols.dot));\n    } else {\n      process.stdout.write(color(test.speed, Base.symbols.dot));\n    }\n  });\n\n  runner.on('fail', function() {\n    if (++n % width === 0) {\n      process.stdout.write('\\n  ');\n    }\n    process.stdout.write(color('fail', Base.symbols.bang));\n  });\n\n  runner.on('end', function() {\n    console.log();\n    self.epilogue();\n  });\n}\n\n/**\n * Inherit from `Base.prototype`.\n */\ninherits(Dot, Base);\n\n}).call(this,require('_process'))\n},{\"../utils\":38,\"./base\":17,\"_process\":67}],20:[function(require,module,exports){\n(function (global){\n/* eslint-env browser */\n\n/**\n * Module dependencies.\n */\n\nvar Base = require('./base');\nvar utils = require('../utils');\nvar Progress = require('../browser/progress');\nvar escapeRe = require('escape-string-regexp');\nvar escape = utils.escape;\n\n/**\n * Save timer references to avoid Sinon interfering (see GH-237).\n */\n\n/* eslint-disable no-unused-vars, no-native-reassign */\nvar Date = global.Date;\nvar setTimeout = global.setTimeout;\nvar setInterval = global.setInterval;\nvar clearTimeout = global.clearTimeout;\nvar clearInterval = global.clearInterval;\n/* eslint-enable no-unused-vars, no-native-reassign */\n\n/**\n * Expose `HTML`.\n */\n\nexports = module.exports = HTML;\n\n/**\n * Stats template.\n */\n\nvar statsTemplate = '<ul id=\"mocha-stats\">'\n  + '<li class=\"progress\"><canvas width=\"40\" height=\"40\"></canvas></li>'\n  + '<li class=\"passes\"><a href=\"javascript:void(0);\">passes:</a> <em>0</em></li>'\n  + '<li class=\"failures\"><a href=\"javascript:void(0);\">failures:</a> <em>0</em></li>'\n  + '<li class=\"duration\">duration: <em>0</em>s</li>'\n  + '</ul>';\n\n/**\n * Initialize a new `HTML` reporter.\n *\n * @api public\n * @param {Runner} runner\n */\nfunction HTML(runner) {\n  Base.call(this, runner);\n\n  var self = this;\n  var stats = this.stats;\n  var stat = fragment(statsTemplate);\n  var items = stat.getElementsByTagName('li');\n  var passes = items[1].getElementsByTagName('em')[0];\n  var passesLink = items[1].getElementsByTagName('a')[0];\n  var failures = items[2].getElementsByTagName('em')[0];\n  var failuresLink = items[2].getElementsByTagName('a')[0];\n  var duration = items[3].getElementsByTagName('em')[0];\n  var canvas = stat.getElementsByTagName('canvas')[0];\n  var report = fragment('<ul id=\"mocha-report\"></ul>');\n  var stack = [report];\n  var progress;\n  var ctx;\n  var root = document.getElementById('mocha');\n\n  if (canvas.getContext) {\n    var ratio = window.devicePixelRatio || 1;\n    canvas.style.width = canvas.width;\n    canvas.style.height = canvas.height;\n    canvas.width *= ratio;\n    canvas.height *= ratio;\n    ctx = canvas.getContext('2d');\n    ctx.scale(ratio, ratio);\n    progress = new Progress();\n  }\n\n  if (!root) {\n    return error('#mocha div missing, add it to your document');\n  }\n\n  // pass toggle\n  on(passesLink, 'click', function(evt) {\n    evt.preventDefault();\n    unhide();\n    var name = (/pass/).test(report.className) ? '' : ' pass';\n    report.className = report.className.replace(/fail|pass/g, '') + name;\n    if (report.className.trim()) {\n      hideSuitesWithout('test pass');\n    }\n  });\n\n  // failure toggle\n  on(failuresLink, 'click', function(evt) {\n    evt.preventDefault();\n    unhide();\n    var name = (/fail/).test(report.className) ? '' : ' fail';\n    report.className = report.className.replace(/fail|pass/g, '') + name;\n    if (report.className.trim()) {\n      hideSuitesWithout('test fail');\n    }\n  });\n\n  root.appendChild(stat);\n  root.appendChild(report);\n\n  if (progress) {\n    progress.size(40);\n  }\n\n  runner.on('suite', function(suite) {\n    if (suite.root) {\n      return;\n    }\n\n    // suite\n    var url = self.suiteURL(suite);\n    var el = fragment('<li class=\"suite\"><h1><a href=\"%s\">%s</a></h1></li>', url, escape(suite.title));\n\n    // container\n    stack[0].appendChild(el);\n    stack.unshift(document.createElement('ul'));\n    el.appendChild(stack[0]);\n  });\n\n  runner.on('suite end', function(suite) {\n    if (suite.root) {\n      updateStats();\n      return;\n    }\n    stack.shift();\n  });\n\n  runner.on('pass', function(test) {\n    var url = self.testURL(test);\n    var markup = '<li class=\"test pass %e\"><h2>%e<span class=\"duration\">%ems</span> '\n      + '<a href=\"%s\" class=\"replay\">‣</a></h2></li>';\n    var el = fragment(markup, test.speed, test.title, test.duration, url);\n    self.addCodeToggle(el, test.body);\n    appendToStack(el);\n    updateStats();\n  });\n\n  runner.on('fail', function(test) {\n    var el = fragment('<li class=\"test fail\"><h2>%e <a href=\"%e\" class=\"replay\">‣</a></h2></li>',\n      test.title, self.testURL(test));\n    var stackString; // Note: Includes leading newline\n    var message = test.err.toString();\n\n    // <=IE7 stringifies to [Object Error]. Since it can be overloaded, we\n    // check for the result of the stringifying.\n    if (message === '[object Error]') {\n      message = test.err.message;\n    }\n\n    if (test.err.stack) {\n      var indexOfMessage = test.err.stack.indexOf(test.err.message);\n      if (indexOfMessage === -1) {\n        stackString = test.err.stack;\n      } else {\n        stackString = test.err.stack.substr(test.err.message.length + indexOfMessage);\n      }\n    } else if (test.err.sourceURL && test.err.line !== undefined) {\n      // Safari doesn't give you a stack. Let's at least provide a source line.\n      stackString = '\\n(' + test.err.sourceURL + ':' + test.err.line + ')';\n    }\n\n    stackString = stackString || '';\n\n    if (test.err.htmlMessage && stackString) {\n      el.appendChild(fragment('<div class=\"html-error\">%s\\n<pre class=\"error\">%e</pre></div>',\n        test.err.htmlMessage, stackString));\n    } else if (test.err.htmlMessage) {\n      el.appendChild(fragment('<div class=\"html-error\">%s</div>', test.err.htmlMessage));\n    } else {\n      el.appendChild(fragment('<pre class=\"error\">%e%e</pre>', message, stackString));\n    }\n\n    self.addCodeToggle(el, test.body);\n    appendToStack(el);\n    updateStats();\n  });\n\n  runner.on('pending', function(test) {\n    var el = fragment('<li class=\"test pass pending\"><h2>%e</h2></li>', test.title);\n    appendToStack(el);\n    updateStats();\n  });\n\n  function appendToStack(el) {\n    // Don't call .appendChild if #mocha-report was already .shift()'ed off the stack.\n    if (stack[0]) {\n      stack[0].appendChild(el);\n    }\n  }\n\n  function updateStats() {\n    // TODO: add to stats\n    var percent = stats.tests / runner.total * 100 | 0;\n    if (progress) {\n      progress.update(percent).draw(ctx);\n    }\n\n    // update stats\n    var ms = new Date() - stats.start;\n    text(passes, stats.passes);\n    text(failures, stats.failures);\n    text(duration, (ms / 1000).toFixed(2));\n  }\n}\n\n/**\n * Makes a URL, preserving querystring (\"search\") parameters.\n *\n * @param {string} s\n * @return {string} A new URL.\n */\nfunction makeUrl(s) {\n  var search = window.location.search;\n\n  // Remove previous grep query parameter if present\n  if (search) {\n    search = search.replace(/[?&]grep=[^&\\s]*/g, '').replace(/^&/, '?');\n  }\n\n  return window.location.pathname + (search ? search + '&' : '?') + 'grep=' + encodeURIComponent(escapeRe(s));\n}\n\n/**\n * Provide suite URL.\n *\n * @param {Object} [suite]\n */\nHTML.prototype.suiteURL = function(suite) {\n  return makeUrl(suite.fullTitle());\n};\n\n/**\n * Provide test URL.\n *\n * @param {Object} [test]\n */\nHTML.prototype.testURL = function(test) {\n  return makeUrl(test.fullTitle());\n};\n\n/**\n * Adds code toggle functionality for the provided test's list element.\n *\n * @param {HTMLLIElement} el\n * @param {string} contents\n */\nHTML.prototype.addCodeToggle = function(el, contents) {\n  var h2 = el.getElementsByTagName('h2')[0];\n\n  on(h2, 'click', function() {\n    pre.style.display = pre.style.display === 'none' ? 'block' : 'none';\n  });\n\n  var pre = fragment('<pre><code>%e</code></pre>', utils.clean(contents));\n  el.appendChild(pre);\n  pre.style.display = 'none';\n};\n\n/**\n * Display error `msg`.\n *\n * @param {string} msg\n */\nfunction error(msg) {\n  document.body.appendChild(fragment('<div id=\"mocha-error\">%s</div>', msg));\n}\n\n/**\n * Return a DOM fragment from `html`.\n *\n * @param {string} html\n */\nfunction fragment(html) {\n  var args = arguments;\n  var div = document.createElement('div');\n  var i = 1;\n\n  div.innerHTML = html.replace(/%([se])/g, function(_, type) {\n    switch (type) {\n      case 's': return String(args[i++]);\n      case 'e': return escape(args[i++]);\n      // no default\n    }\n  });\n\n  return div.firstChild;\n}\n\n/**\n * Check for suites that do not have elements\n * with `classname`, and hide them.\n *\n * @param {text} classname\n */\nfunction hideSuitesWithout(classname) {\n  var suites = document.getElementsByClassName('suite');\n  for (var i = 0; i < suites.length; i++) {\n    var els = suites[i].getElementsByClassName(classname);\n    if (!els.length) {\n      suites[i].className += ' hidden';\n    }\n  }\n}\n\n/**\n * Unhide .hidden suites.\n */\nfunction unhide() {\n  var els = document.getElementsByClassName('suite hidden');\n  for (var i = 0; i < els.length; ++i) {\n    els[i].className = els[i].className.replace('suite hidden', 'suite');\n  }\n}\n\n/**\n * Set an element's text contents.\n *\n * @param {HTMLElement} el\n * @param {string} contents\n */\nfunction text(el, contents) {\n  if (el.textContent) {\n    el.textContent = contents;\n  } else {\n    el.innerText = contents;\n  }\n}\n\n/**\n * Listen on `event` with callback `fn`.\n */\nfunction on(el, event, fn) {\n  if (el.addEventListener) {\n    el.addEventListener(event, fn, false);\n  } else {\n    el.attachEvent('on' + event, fn);\n  }\n}\n\n}).call(this,typeof global !== \"undefined\" ? global : typeof self !== \"undefined\" ? self : typeof window !== \"undefined\" ? window : {})\n},{\"../browser/progress\":4,\"../utils\":38,\"./base\":17,\"escape-string-regexp\":47}],21:[function(require,module,exports){\n// Alias exports to a their normalized format Mocha#reporter to prevent a need\n// for dynamic (try/catch) requires, which Browserify doesn't handle.\nexports.Base = exports.base = require('./base');\nexports.Dot = exports.dot = require('./dot');\nexports.Doc = exports.doc = require('./doc');\nexports.TAP = exports.tap = require('./tap');\nexports.JSON = exports.json = require('./json');\nexports.HTML = exports.html = require('./html');\nexports.List = exports.list = require('./list');\nexports.Min = exports.min = require('./min');\nexports.Spec = exports.spec = require('./spec');\nexports.Nyan = exports.nyan = require('./nyan');\nexports.XUnit = exports.xunit = require('./xunit');\nexports.Markdown = exports.markdown = require('./markdown');\nexports.Progress = exports.progress = require('./progress');\nexports.Landing = exports.landing = require('./landing');\nexports.JSONStream = exports['json-stream'] = require('./json-stream');\n\n},{\"./base\":17,\"./doc\":18,\"./dot\":19,\"./html\":20,\"./json\":23,\"./json-stream\":22,\"./landing\":24,\"./list\":25,\"./markdown\":26,\"./min\":27,\"./nyan\":28,\"./progress\":29,\"./spec\":30,\"./tap\":31,\"./xunit\":32}],22:[function(require,module,exports){\n(function (process){\n/**\n * Module dependencies.\n */\n\nvar Base = require('./base');\nvar JSON = require('json3');\n\n/**\n * Expose `List`.\n */\n\nexports = module.exports = List;\n\n/**\n * Initialize a new `List` test reporter.\n *\n * @api public\n * @param {Runner} runner\n */\nfunction List(runner) {\n  Base.call(this, runner);\n\n  var self = this;\n  var total = runner.total;\n\n  runner.on('start', function() {\n    console.log(JSON.stringify(['start', { total: total }]));\n  });\n\n  runner.on('pass', function(test) {\n    console.log(JSON.stringify(['pass', clean(test)]));\n  });\n\n  runner.on('fail', function(test, err) {\n    test = clean(test);\n    test.err = err.message;\n    test.stack = err.stack || null;\n    console.log(JSON.stringify(['fail', test]));\n  });\n\n  runner.on('end', function() {\n    process.stdout.write(JSON.stringify(['end', self.stats]));\n  });\n}\n\n/**\n * Return a plain-object representation of `test`\n * free of cyclic properties etc.\n *\n * @api private\n * @param {Object} test\n * @return {Object}\n */\nfunction clean(test) {\n  return {\n    title: test.title,\n    fullTitle: test.fullTitle(),\n    duration: test.duration,\n    currentRetry: test.currentRetry()\n  };\n}\n\n}).call(this,require('_process'))\n},{\"./base\":17,\"_process\":67,\"json3\":54}],23:[function(require,module,exports){\n(function (process){\n/**\n * Module dependencies.\n */\n\nvar Base = require('./base');\n\n/**\n * Expose `JSON`.\n */\n\nexports = module.exports = JSONReporter;\n\n/**\n * Initialize a new `JSON` reporter.\n *\n * @api public\n * @param {Runner} runner\n */\nfunction JSONReporter(runner) {\n  Base.call(this, runner);\n\n  var self = this;\n  var tests = [];\n  var pending = [];\n  var failures = [];\n  var passes = [];\n\n  runner.on('test end', function(test) {\n    tests.push(test);\n  });\n\n  runner.on('pass', function(test) {\n    passes.push(test);\n  });\n\n  runner.on('fail', function(test) {\n    failures.push(test);\n  });\n\n  runner.on('pending', function(test) {\n    pending.push(test);\n  });\n\n  runner.on('end', function() {\n    var obj = {\n      stats: self.stats,\n      tests: tests.map(clean),\n      pending: pending.map(clean),\n      failures: failures.map(clean),\n      passes: passes.map(clean)\n    };\n\n    runner.testResults = obj;\n\n    process.stdout.write(JSON.stringify(obj, null, 2));\n  });\n}\n\n/**\n * Return a plain-object representation of `test`\n * free of cyclic properties etc.\n *\n * @api private\n * @param {Object} test\n * @return {Object}\n */\nfunction clean(test) {\n  return {\n    title: test.title,\n    fullTitle: test.fullTitle(),\n    duration: test.duration,\n    currentRetry: test.currentRetry(),\n    err: errorJSON(test.err || {})\n  };\n}\n\n/**\n * Transform `error` into a JSON object.\n *\n * @api private\n * @param {Error} err\n * @return {Object}\n */\nfunction errorJSON(err) {\n  var res = {};\n  Object.getOwnPropertyNames(err).forEach(function(key) {\n    res[key] = err[key];\n  }, err);\n  return res;\n}\n\n}).call(this,require('_process'))\n},{\"./base\":17,\"_process\":67}],24:[function(require,module,exports){\n(function (process){\n/**\n * Module dependencies.\n */\n\nvar Base = require('./base');\nvar inherits = require('../utils').inherits;\nvar cursor = Base.cursor;\nvar color = Base.color;\n\n/**\n * Expose `Landing`.\n */\n\nexports = module.exports = Landing;\n\n/**\n * Airplane color.\n */\n\nBase.colors.plane = 0;\n\n/**\n * Airplane crash color.\n */\n\nBase.colors['plane crash'] = 31;\n\n/**\n * Runway color.\n */\n\nBase.colors.runway = 90;\n\n/**\n * Initialize a new `Landing` reporter.\n *\n * @api public\n * @param {Runner} runner\n */\nfunction Landing(runner) {\n  Base.call(this, runner);\n\n  var self = this;\n  var width = Base.window.width * .75 | 0;\n  var total = runner.total;\n  var stream = process.stdout;\n  var plane = color('plane', '✈');\n  var crashed = -1;\n  var n = 0;\n\n  function runway() {\n    var buf = Array(width).join('-');\n    return '  ' + color('runway', buf);\n  }\n\n  runner.on('start', function() {\n    stream.write('\\n\\n\\n  ');\n    cursor.hide();\n  });\n\n  runner.on('test end', function(test) {\n    // check if the plane crashed\n    var col = crashed === -1 ? width * ++n / total | 0 : crashed;\n\n    // show the crash\n    if (test.state === 'failed') {\n      plane = color('plane crash', '✈');\n      crashed = col;\n    }\n\n    // render landing strip\n    stream.write('\\u001b[' + (width + 1) + 'D\\u001b[2A');\n    stream.write(runway());\n    stream.write('\\n  ');\n    stream.write(color('runway', Array(col).join('⋅')));\n    stream.write(plane);\n    stream.write(color('runway', Array(width - col).join('⋅') + '\\n'));\n    stream.write(runway());\n    stream.write('\\u001b[0m');\n  });\n\n  runner.on('end', function() {\n    cursor.show();\n    console.log();\n    self.epilogue();\n  });\n}\n\n/**\n * Inherit from `Base.prototype`.\n */\ninherits(Landing, Base);\n\n}).call(this,require('_process'))\n},{\"../utils\":38,\"./base\":17,\"_process\":67}],25:[function(require,module,exports){\n(function (process){\n/**\n * Module dependencies.\n */\n\nvar Base = require('./base');\nvar inherits = require('../utils').inherits;\nvar color = Base.color;\nvar cursor = Base.cursor;\n\n/**\n * Expose `List`.\n */\n\nexports = module.exports = List;\n\n/**\n * Initialize a new `List` test reporter.\n *\n * @api public\n * @param {Runner} runner\n */\nfunction List(runner) {\n  Base.call(this, runner);\n\n  var self = this;\n  var n = 0;\n\n  runner.on('start', function() {\n    console.log();\n  });\n\n  runner.on('test', function(test) {\n    process.stdout.write(color('pass', '    ' + test.fullTitle() + ': '));\n  });\n\n  runner.on('pending', function(test) {\n    var fmt = color('checkmark', '  -')\n      + color('pending', ' %s');\n    console.log(fmt, test.fullTitle());\n  });\n\n  runner.on('pass', function(test) {\n    var fmt = color('checkmark', '  ' + Base.symbols.dot)\n      + color('pass', ' %s: ')\n      + color(test.speed, '%dms');\n    cursor.CR();\n    console.log(fmt, test.fullTitle(), test.duration);\n  });\n\n  runner.on('fail', function(test) {\n    cursor.CR();\n    console.log(color('fail', '  %d) %s'), ++n, test.fullTitle());\n  });\n\n  runner.on('end', self.epilogue.bind(self));\n}\n\n/**\n * Inherit from `Base.prototype`.\n */\ninherits(List, Base);\n\n}).call(this,require('_process'))\n},{\"../utils\":38,\"./base\":17,\"_process\":67}],26:[function(require,module,exports){\n(function (process){\n/**\n * Module dependencies.\n */\n\nvar Base = require('./base');\nvar utils = require('../utils');\n\n/**\n * Constants\n */\n\nvar SUITE_PREFIX = '$';\n\n/**\n * Expose `Markdown`.\n */\n\nexports = module.exports = Markdown;\n\n/**\n * Initialize a new `Markdown` reporter.\n *\n * @api public\n * @param {Runner} runner\n */\nfunction Markdown(runner) {\n  Base.call(this, runner);\n\n  var level = 0;\n  var buf = '';\n\n  function title(str) {\n    return Array(level).join('#') + ' ' + str;\n  }\n\n  function mapTOC(suite, obj) {\n    var ret = obj;\n    var key = SUITE_PREFIX + suite.title;\n\n    obj = obj[key] = obj[key] || { suite: suite };\n    suite.suites.forEach(function(suite) {\n      mapTOC(suite, obj);\n    });\n\n    return ret;\n  }\n\n  function stringifyTOC(obj, level) {\n    ++level;\n    var buf = '';\n    var link;\n    for (var key in obj) {\n      if (key === 'suite') {\n        continue;\n      }\n      if (key !== SUITE_PREFIX) {\n        link = ' - [' + key.substring(1) + ']';\n        link += '(#' + utils.slug(obj[key].suite.fullTitle()) + ')\\n';\n        buf += Array(level).join('  ') + link;\n      }\n      buf += stringifyTOC(obj[key], level);\n    }\n    return buf;\n  }\n\n  function generateTOC(suite) {\n    var obj = mapTOC(suite, {});\n    return stringifyTOC(obj, 0);\n  }\n\n  generateTOC(runner.suite);\n\n  runner.on('suite', function(suite) {\n    ++level;\n    var slug = utils.slug(suite.fullTitle());\n    buf += '<a name=\"' + slug + '\"></a>' + '\\n';\n    buf += title(suite.title) + '\\n';\n  });\n\n  runner.on('suite end', function() {\n    --level;\n  });\n\n  runner.on('pass', function(test) {\n    var code = utils.clean(test.body);\n    buf += test.title + '.\\n';\n    buf += '\\n```js\\n';\n    buf += code + '\\n';\n    buf += '```\\n\\n';\n  });\n\n  runner.on('end', function() {\n    process.stdout.write('# TOC\\n');\n    process.stdout.write(generateTOC(runner.suite));\n    process.stdout.write(buf);\n  });\n}\n\n}).call(this,require('_process'))\n},{\"../utils\":38,\"./base\":17,\"_process\":67}],27:[function(require,module,exports){\n(function (process){\n/**\n * Module dependencies.\n */\n\nvar Base = require('./base');\nvar inherits = require('../utils').inherits;\n\n/**\n * Expose `Min`.\n */\n\nexports = module.exports = Min;\n\n/**\n * Initialize a new `Min` minimal test reporter (best used with --watch).\n *\n * @api public\n * @param {Runner} runner\n */\nfunction Min(runner) {\n  Base.call(this, runner);\n\n  runner.on('start', function() {\n    // clear screen\n    process.stdout.write('\\u001b[2J');\n    // set cursor position\n    process.stdout.write('\\u001b[1;3H');\n  });\n\n  runner.on('end', this.epilogue.bind(this));\n}\n\n/**\n * Inherit from `Base.prototype`.\n */\ninherits(Min, Base);\n\n}).call(this,require('_process'))\n},{\"../utils\":38,\"./base\":17,\"_process\":67}],28:[function(require,module,exports){\n(function (process){\n/**\n * Module dependencies.\n */\n\nvar Base = require('./base');\nvar inherits = require('../utils').inherits;\n\n/**\n * Expose `Dot`.\n */\n\nexports = module.exports = NyanCat;\n\n/**\n * Initialize a new `Dot` matrix test reporter.\n *\n * @param {Runner} runner\n * @api public\n */\n\nfunction NyanCat(runner) {\n  Base.call(this, runner);\n\n  var self = this;\n  var width = Base.window.width * .75 | 0;\n  var nyanCatWidth = this.nyanCatWidth = 11;\n\n  this.colorIndex = 0;\n  this.numberOfLines = 4;\n  this.rainbowColors = self.generateColors();\n  this.scoreboardWidth = 5;\n  this.tick = 0;\n  this.trajectories = [[], [], [], []];\n  this.trajectoryWidthMax = (width - nyanCatWidth);\n\n  runner.on('start', function() {\n    Base.cursor.hide();\n    self.draw();\n  });\n\n  runner.on('pending', function() {\n    self.draw();\n  });\n\n  runner.on('pass', function() {\n    self.draw();\n  });\n\n  runner.on('fail', function() {\n    self.draw();\n  });\n\n  runner.on('end', function() {\n    Base.cursor.show();\n    for (var i = 0; i < self.numberOfLines; i++) {\n      write('\\n');\n    }\n    self.epilogue();\n  });\n}\n\n/**\n * Inherit from `Base.prototype`.\n */\ninherits(NyanCat, Base);\n\n/**\n * Draw the nyan cat\n *\n * @api private\n */\n\nNyanCat.prototype.draw = function() {\n  this.appendRainbow();\n  this.drawScoreboard();\n  this.drawRainbow();\n  this.drawNyanCat();\n  this.tick = !this.tick;\n};\n\n/**\n * Draw the \"scoreboard\" showing the number\n * of passes, failures and pending tests.\n *\n * @api private\n */\n\nNyanCat.prototype.drawScoreboard = function() {\n  var stats = this.stats;\n\n  function draw(type, n) {\n    write(' ');\n    write(Base.color(type, n));\n    write('\\n');\n  }\n\n  draw('green', stats.passes);\n  draw('fail', stats.failures);\n  draw('pending', stats.pending);\n  write('\\n');\n\n  this.cursorUp(this.numberOfLines);\n};\n\n/**\n * Append the rainbow.\n *\n * @api private\n */\n\nNyanCat.prototype.appendRainbow = function() {\n  var segment = this.tick ? '_' : '-';\n  var rainbowified = this.rainbowify(segment);\n\n  for (var index = 0; index < this.numberOfLines; index++) {\n    var trajectory = this.trajectories[index];\n    if (trajectory.length >= this.trajectoryWidthMax) {\n      trajectory.shift();\n    }\n    trajectory.push(rainbowified);\n  }\n};\n\n/**\n * Draw the rainbow.\n *\n * @api private\n */\n\nNyanCat.prototype.drawRainbow = function() {\n  var self = this;\n\n  this.trajectories.forEach(function(line) {\n    write('\\u001b[' + self.scoreboardWidth + 'C');\n    write(line.join(''));\n    write('\\n');\n  });\n\n  this.cursorUp(this.numberOfLines);\n};\n\n/**\n * Draw the nyan cat\n *\n * @api private\n */\nNyanCat.prototype.drawNyanCat = function() {\n  var self = this;\n  var startWidth = this.scoreboardWidth + this.trajectories[0].length;\n  var dist = '\\u001b[' + startWidth + 'C';\n  var padding = '';\n\n  write(dist);\n  write('_,------,');\n  write('\\n');\n\n  write(dist);\n  padding = self.tick ? '  ' : '   ';\n  write('_|' + padding + '/\\\\_/\\\\ ');\n  write('\\n');\n\n  write(dist);\n  padding = self.tick ? '_' : '__';\n  var tail = self.tick ? '~' : '^';\n  write(tail + '|' + padding + this.face() + ' ');\n  write('\\n');\n\n  write(dist);\n  padding = self.tick ? ' ' : '  ';\n  write(padding + '\"\"  \"\" ');\n  write('\\n');\n\n  this.cursorUp(this.numberOfLines);\n};\n\n/**\n * Draw nyan cat face.\n *\n * @api private\n * @return {string}\n */\n\nNyanCat.prototype.face = function() {\n  var stats = this.stats;\n  if (stats.failures) {\n    return '( x .x)';\n  } else if (stats.pending) {\n    return '( o .o)';\n  } else if (stats.passes) {\n    return '( ^ .^)';\n  }\n  return '( - .-)';\n};\n\n/**\n * Move cursor up `n`.\n *\n * @api private\n * @param {number} n\n */\n\nNyanCat.prototype.cursorUp = function(n) {\n  write('\\u001b[' + n + 'A');\n};\n\n/**\n * Move cursor down `n`.\n *\n * @api private\n * @param {number} n\n */\n\nNyanCat.prototype.cursorDown = function(n) {\n  write('\\u001b[' + n + 'B');\n};\n\n/**\n * Generate rainbow colors.\n *\n * @api private\n * @return {Array}\n */\nNyanCat.prototype.generateColors = function() {\n  var colors = [];\n\n  for (var i = 0; i < (6 * 7); i++) {\n    var pi3 = Math.floor(Math.PI / 3);\n    var n = (i * (1.0 / 6));\n    var r = Math.floor(3 * Math.sin(n) + 3);\n    var g = Math.floor(3 * Math.sin(n + 2 * pi3) + 3);\n    var b = Math.floor(3 * Math.sin(n + 4 * pi3) + 3);\n    colors.push(36 * r + 6 * g + b + 16);\n  }\n\n  return colors;\n};\n\n/**\n * Apply rainbow to the given `str`.\n *\n * @api private\n * @param {string} str\n * @return {string}\n */\nNyanCat.prototype.rainbowify = function(str) {\n  if (!Base.useColors) {\n    return str;\n  }\n  var color = this.rainbowColors[this.colorIndex % this.rainbowColors.length];\n  this.colorIndex += 1;\n  return '\\u001b[38;5;' + color + 'm' + str + '\\u001b[0m';\n};\n\n/**\n * Stdout helper.\n *\n * @param {string} string A message to write to stdout.\n */\nfunction write(string) {\n  process.stdout.write(string);\n}\n\n}).call(this,require('_process'))\n},{\"../utils\":38,\"./base\":17,\"_process\":67}],29:[function(require,module,exports){\n(function (process){\n/**\n * Module dependencies.\n */\n\nvar Base = require('./base');\nvar inherits = require('../utils').inherits;\nvar color = Base.color;\nvar cursor = Base.cursor;\n\n/**\n * Expose `Progress`.\n */\n\nexports = module.exports = Progress;\n\n/**\n * General progress bar color.\n */\n\nBase.colors.progress = 90;\n\n/**\n * Initialize a new `Progress` bar test reporter.\n *\n * @api public\n * @param {Runner} runner\n * @param {Object} options\n */\nfunction Progress(runner, options) {\n  Base.call(this, runner);\n\n  var self = this;\n  var width = Base.window.width * .50 | 0;\n  var total = runner.total;\n  var complete = 0;\n  var lastN = -1;\n\n  // default chars\n  options = options || {};\n  options.open = options.open || '[';\n  options.complete = options.complete || '▬';\n  options.incomplete = options.incomplete || Base.symbols.dot;\n  options.close = options.close || ']';\n  options.verbose = false;\n\n  // tests started\n  runner.on('start', function() {\n    console.log();\n    cursor.hide();\n  });\n\n  // tests complete\n  runner.on('test end', function() {\n    complete++;\n\n    var percent = complete / total;\n    var n = width * percent | 0;\n    var i = width - n;\n\n    if (n === lastN && !options.verbose) {\n      // Don't re-render the line if it hasn't changed\n      return;\n    }\n    lastN = n;\n\n    cursor.CR();\n    process.stdout.write('\\u001b[J');\n    process.stdout.write(color('progress', '  ' + options.open));\n    process.stdout.write(Array(n).join(options.complete));\n    process.stdout.write(Array(i).join(options.incomplete));\n    process.stdout.write(color('progress', options.close));\n    if (options.verbose) {\n      process.stdout.write(color('progress', ' ' + complete + ' of ' + total));\n    }\n  });\n\n  // tests are complete, output some stats\n  // and the failures if any\n  runner.on('end', function() {\n    cursor.show();\n    console.log();\n    self.epilogue();\n  });\n}\n\n/**\n * Inherit from `Base.prototype`.\n */\ninherits(Progress, Base);\n\n}).call(this,require('_process'))\n},{\"../utils\":38,\"./base\":17,\"_process\":67}],30:[function(require,module,exports){\n/**\n * Module dependencies.\n */\n\nvar Base = require('./base');\nvar inherits = require('../utils').inherits;\nvar color = Base.color;\n\n/**\n * Expose `Spec`.\n */\n\nexports = module.exports = Spec;\n\n/**\n * Initialize a new `Spec` test reporter.\n *\n * @api public\n * @param {Runner} runner\n */\nfunction Spec(runner) {\n  Base.call(this, runner);\n\n  var self = this;\n  var indents = 0;\n  var n = 0;\n\n  function indent() {\n    return Array(indents).join('  ');\n  }\n\n  runner.on('start', function() {\n    console.log();\n  });\n\n  runner.on('suite', function(suite) {\n    ++indents;\n    console.log(color('suite', '%s%s'), indent(), suite.title);\n  });\n\n  runner.on('suite end', function() {\n    --indents;\n    if (indents === 1) {\n      console.log();\n    }\n  });\n\n  runner.on('pending', function(test) {\n    var fmt = indent() + color('pending', '  - %s');\n    console.log(fmt, test.title);\n  });\n\n  runner.on('pass', function(test) {\n    var fmt;\n    if (test.speed === 'fast') {\n      fmt = indent()\n        + color('checkmark', '  ' + Base.symbols.ok)\n        + color('pass', ' %s');\n      console.log(fmt, test.title);\n    } else {\n      fmt = indent()\n        + color('checkmark', '  ' + Base.symbols.ok)\n        + color('pass', ' %s')\n        + color(test.speed, ' (%dms)');\n      console.log(fmt, test.title, test.duration);\n    }\n  });\n\n  runner.on('fail', function(test) {\n    console.log(indent() + color('fail', '  %d) %s'), ++n, test.title);\n  });\n\n  runner.on('end', self.epilogue.bind(self));\n}\n\n/**\n * Inherit from `Base.prototype`.\n */\ninherits(Spec, Base);\n\n},{\"../utils\":38,\"./base\":17}],31:[function(require,module,exports){\n/**\n * Module dependencies.\n */\n\nvar Base = require('./base');\n\n/**\n * Expose `TAP`.\n */\n\nexports = module.exports = TAP;\n\n/**\n * Initialize a new `TAP` reporter.\n *\n * @api public\n * @param {Runner} runner\n */\nfunction TAP(runner) {\n  Base.call(this, runner);\n\n  var n = 1;\n  var passes = 0;\n  var failures = 0;\n\n  runner.on('start', function() {\n    var total = runner.grepTotal(runner.suite);\n    console.log('%d..%d', 1, total);\n  });\n\n  runner.on('test end', function() {\n    ++n;\n  });\n\n  runner.on('pending', function(test) {\n    console.log('ok %d %s # SKIP -', n, title(test));\n  });\n\n  runner.on('pass', function(test) {\n    passes++;\n    console.log('ok %d %s', n, title(test));\n  });\n\n  runner.on('fail', function(test, err) {\n    failures++;\n    console.log('not ok %d %s', n, title(test));\n    if (err.stack) {\n      console.log(err.stack.replace(/^/gm, '  '));\n    }\n  });\n\n  runner.on('end', function() {\n    console.log('# tests ' + (passes + failures));\n    console.log('# pass ' + passes);\n    console.log('# fail ' + failures);\n  });\n}\n\n/**\n * Return a TAP-safe title of `test`\n *\n * @api private\n * @param {Object} test\n * @return {String}\n */\nfunction title(test) {\n  return test.fullTitle().replace(/#/g, '');\n}\n\n},{\"./base\":17}],32:[function(require,module,exports){\n(function (process,global){\n/**\n * Module dependencies.\n */\n\nvar Base = require('./base');\nvar utils = require('../utils');\nvar inherits = utils.inherits;\nvar fs = require('fs');\nvar escape = utils.escape;\nvar mkdirp = require('mkdirp');\nvar path = require('path');\n\n/**\n * Save timer references to avoid Sinon interfering (see GH-237).\n */\n\n/* eslint-disable no-unused-vars, no-native-reassign */\nvar Date = global.Date;\nvar setTimeout = global.setTimeout;\nvar setInterval = global.setInterval;\nvar clearTimeout = global.clearTimeout;\nvar clearInterval = global.clearInterval;\n/* eslint-enable no-unused-vars, no-native-reassign */\n\n/**\n * Expose `XUnit`.\n */\n\nexports = module.exports = XUnit;\n\n/**\n * Initialize a new `XUnit` reporter.\n *\n * @api public\n * @param {Runner} runner\n */\nfunction XUnit(runner, options) {\n  Base.call(this, runner);\n\n  var stats = this.stats;\n  var tests = [];\n  var self = this;\n\n  if (options.reporterOptions && options.reporterOptions.output) {\n    if (!fs.createWriteStream) {\n      throw new Error('file output not supported in browser');\n    }\n    mkdirp.sync(path.dirname(options.reporterOptions.output));\n    self.fileStream = fs.createWriteStream(options.reporterOptions.output);\n  }\n\n  runner.on('pending', function(test) {\n    tests.push(test);\n  });\n\n  runner.on('pass', function(test) {\n    tests.push(test);\n  });\n\n  runner.on('fail', function(test) {\n    tests.push(test);\n  });\n\n  runner.on('end', function() {\n    self.write(tag('testsuite', {\n      name: 'Mocha Tests',\n      tests: stats.tests,\n      failures: stats.failures,\n      errors: stats.failures,\n      skipped: stats.tests - stats.failures - stats.passes,\n      timestamp: (new Date()).toUTCString(),\n      time: (stats.duration / 1000) || 0\n    }, false));\n\n    tests.forEach(function(t) {\n      self.test(t);\n    });\n\n    self.write('</testsuite>');\n  });\n}\n\n/**\n * Inherit from `Base.prototype`.\n */\ninherits(XUnit, Base);\n\n/**\n * Override done to close the stream (if it's a file).\n *\n * @param failures\n * @param {Function} fn\n */\nXUnit.prototype.done = function(failures, fn) {\n  if (this.fileStream) {\n    this.fileStream.end(function() {\n      fn(failures);\n    });\n  } else {\n    fn(failures);\n  }\n};\n\n/**\n * Write out the given line.\n *\n * @param {string} line\n */\nXUnit.prototype.write = function(line) {\n  if (this.fileStream) {\n    this.fileStream.write(line + '\\n');\n  } else if (typeof process === 'object' && process.stdout) {\n    process.stdout.write(line + '\\n');\n  } else {\n    console.log(line);\n  }\n};\n\n/**\n * Output tag for the given `test.`\n *\n * @param {Test} test\n */\nXUnit.prototype.test = function(test) {\n  var attrs = {\n    classname: test.parent.fullTitle(),\n    name: test.title,\n    time: (test.duration / 1000) || 0\n  };\n\n  if (test.state === 'failed') {\n    var err = test.err;\n    this.write(tag('testcase', attrs, false, tag('failure', {}, false, escape(err.message) + '\\n' + escape(err.stack))));\n  } else if (test.isPending()) {\n    this.write(tag('testcase', attrs, false, tag('skipped', {}, true)));\n  } else {\n    this.write(tag('testcase', attrs, true));\n  }\n};\n\n/**\n * HTML tag helper.\n *\n * @param name\n * @param attrs\n * @param close\n * @param content\n * @return {string}\n */\nfunction tag(name, attrs, close, content) {\n  var end = close ? '/>' : '>';\n  var pairs = [];\n  var tag;\n\n  for (var key in attrs) {\n    if (Object.prototype.hasOwnProperty.call(attrs, key)) {\n      pairs.push(key + '=\"' + escape(attrs[key]) + '\"');\n    }\n  }\n\n  tag = '<' + name + (pairs.length ? ' ' + pairs.join(' ') : '') + end;\n  if (content) {\n    tag += content + '</' + name + end;\n  }\n  return tag;\n}\n\n}).call(this,require('_process'),typeof global !== \"undefined\" ? global : typeof self !== \"undefined\" ? self : typeof window !== \"undefined\" ? window : {})\n},{\"../utils\":38,\"./base\":17,\"_process\":67,\"fs\":42,\"mkdirp\":64,\"path\":42}],33:[function(require,module,exports){\n(function (global){\n/**\n * Module dependencies.\n */\n\nvar EventEmitter = require('events').EventEmitter;\nvar JSON = require('json3');\nvar Pending = require('./pending');\nvar debug = require('debug')('mocha:runnable');\nvar milliseconds = require('./ms');\nvar utils = require('./utils');\nvar create = require('lodash.create');\n\n/**\n * Save timer references to avoid Sinon interfering (see GH-237).\n */\n\n/* eslint-disable no-unused-vars, no-native-reassign */\nvar Date = global.Date;\nvar setTimeout = global.setTimeout;\nvar setInterval = global.setInterval;\nvar clearTimeout = global.clearTimeout;\nvar clearInterval = global.clearInterval;\n/* eslint-enable no-unused-vars, no-native-reassign */\n\n/**\n * Object#toString().\n */\n\nvar toString = Object.prototype.toString;\n\n/**\n * Expose `Runnable`.\n */\n\nmodule.exports = Runnable;\n\n/**\n * Initialize a new `Runnable` with the given `title` and callback `fn`.\n *\n * @param {String} title\n * @param {Function} fn\n * @api private\n * @param {string} title\n * @param {Function} fn\n */\nfunction Runnable(title, fn) {\n  this.title = title;\n  this.fn = fn;\n  this.body = (fn || '').toString();\n  this.async = fn && fn.length;\n  this.sync = !this.async;\n  this._timeout = 2000;\n  this._slow = 75;\n  this._enableTimeouts = true;\n  this.timedOut = false;\n  this._trace = new Error('done() called multiple times');\n  this._retries = -1;\n  this._currentRetry = 0;\n  this.pending = false;\n}\n\n/**\n * Inherit from `EventEmitter.prototype`.\n */\nRunnable.prototype = create(EventEmitter.prototype, {\n  constructor: Runnable\n});\n\n/**\n * Set & get timeout `ms`.\n *\n * @api private\n * @param {number|string} ms\n * @return {Runnable|number} ms or Runnable instance.\n */\nRunnable.prototype.timeout = function(ms) {\n  if (!arguments.length) {\n    return this._timeout;\n  }\n  // see #1652 for reasoning\n  if (ms === 0 || ms > Math.pow(2, 31)) {\n    this._enableTimeouts = false;\n  }\n  if (typeof ms === 'string') {\n    ms = milliseconds(ms);\n  }\n  debug('timeout %d', ms);\n  this._timeout = ms;\n  if (this.timer) {\n    this.resetTimeout();\n  }\n  return this;\n};\n\n/**\n * Set & get slow `ms`.\n *\n * @api private\n * @param {number|string} ms\n * @return {Runnable|number} ms or Runnable instance.\n */\nRunnable.prototype.slow = function(ms) {\n  if (typeof ms === 'undefined') {\n    return this._slow;\n  }\n  if (typeof ms === 'string') {\n    ms = milliseconds(ms);\n  }\n  debug('timeout %d', ms);\n  this._slow = ms;\n  return this;\n};\n\n/**\n * Set and get whether timeout is `enabled`.\n *\n * @api private\n * @param {boolean} enabled\n * @return {Runnable|boolean} enabled or Runnable instance.\n */\nRunnable.prototype.enableTimeouts = function(enabled) {\n  if (!arguments.length) {\n    return this._enableTimeouts;\n  }\n  debug('enableTimeouts %s', enabled);\n  this._enableTimeouts = enabled;\n  return this;\n};\n\n/**\n * Halt and mark as pending.\n *\n * @api public\n */\nRunnable.prototype.skip = function() {\n  throw new Pending('sync skip');\n};\n\n/**\n * Check if this runnable or its parent suite is marked as pending.\n *\n * @api private\n */\nRunnable.prototype.isPending = function() {\n  return this.pending || (this.parent && this.parent.isPending());\n};\n\n/**\n * Set number of retries.\n *\n * @api private\n */\nRunnable.prototype.retries = function(n) {\n  if (!arguments.length) {\n    return this._retries;\n  }\n  this._retries = n;\n};\n\n/**\n * Get current retry\n *\n * @api private\n */\nRunnable.prototype.currentRetry = function(n) {\n  if (!arguments.length) {\n    return this._currentRetry;\n  }\n  this._currentRetry = n;\n};\n\n/**\n * Return the full title generated by recursively concatenating the parent's\n * full title.\n *\n * @api public\n * @return {string}\n */\nRunnable.prototype.fullTitle = function() {\n  return this.parent.fullTitle() + ' ' + this.title;\n};\n\n/**\n * Clear the timeout.\n *\n * @api private\n */\nRunnable.prototype.clearTimeout = function() {\n  clearTimeout(this.timer);\n};\n\n/**\n * Inspect the runnable void of private properties.\n *\n * @api private\n * @return {string}\n */\nRunnable.prototype.inspect = function() {\n  return JSON.stringify(this, function(key, val) {\n    if (key[0] === '_') {\n      return;\n    }\n    if (key === 'parent') {\n      return '#<Suite>';\n    }\n    if (key === 'ctx') {\n      return '#<Context>';\n    }\n    return val;\n  }, 2);\n};\n\n/**\n * Reset the timeout.\n *\n * @api private\n */\nRunnable.prototype.resetTimeout = function() {\n  var self = this;\n  var ms = this.timeout() || 1e9;\n\n  if (!this._enableTimeouts) {\n    return;\n  }\n  this.clearTimeout();\n  this.timer = setTimeout(function() {\n    if (!self._enableTimeouts) {\n      return;\n    }\n    self.callback(new Error('timeout of ' + ms + 'ms exceeded. Ensure the done() callback is being called in this test.'));\n    self.timedOut = true;\n  }, ms);\n};\n\n/**\n * Whitelist a list of globals for this test run.\n *\n * @api private\n * @param {string[]} globals\n */\nRunnable.prototype.globals = function(globals) {\n  if (!arguments.length) {\n    return this._allowedGlobals;\n  }\n  this._allowedGlobals = globals;\n};\n\n/**\n * Run the test and invoke `fn(err)`.\n *\n * @param {Function} fn\n * @api private\n */\nRunnable.prototype.run = function(fn) {\n  var self = this;\n  var start = new Date();\n  var ctx = this.ctx;\n  var finished;\n  var emitted;\n\n  // Sometimes the ctx exists, but it is not runnable\n  if (ctx && ctx.runnable) {\n    ctx.runnable(this);\n  }\n\n  // called multiple times\n  function multiple(err) {\n    if (emitted) {\n      return;\n    }\n    emitted = true;\n    self.emit('error', err || new Error('done() called multiple times; stacktrace may be inaccurate'));\n  }\n\n  // finished\n  function done(err) {\n    var ms = self.timeout();\n    if (self.timedOut) {\n      return;\n    }\n    if (finished) {\n      return multiple(err || self._trace);\n    }\n\n    self.clearTimeout();\n    self.duration = new Date() - start;\n    finished = true;\n    if (!err && self.duration > ms && self._enableTimeouts) {\n      err = new Error('timeout of ' + ms + 'ms exceeded. Ensure the done() callback is being called in this test.');\n    }\n    fn(err);\n  }\n\n  // for .resetTimeout()\n  this.callback = done;\n\n  // explicit async with `done` argument\n  if (this.async) {\n    this.resetTimeout();\n\n    // allows skip() to be used in an explicit async context\n    this.skip = function asyncSkip() {\n      done(new Pending('async skip call'));\n      // halt execution.  the Runnable will be marked pending\n      // by the previous call, and the uncaught handler will ignore\n      // the failure.\n      throw new Pending('async skip; aborting execution');\n    };\n\n    if (this.allowUncaught) {\n      return callFnAsync(this.fn);\n    }\n    try {\n      callFnAsync(this.fn);\n    } catch (err) {\n      done(utils.getError(err));\n    }\n    return;\n  }\n\n  if (this.allowUncaught) {\n    callFn(this.fn);\n    done();\n    return;\n  }\n\n  // sync or promise-returning\n  try {\n    if (this.isPending()) {\n      done();\n    } else {\n      callFn(this.fn);\n    }\n  } catch (err) {\n    done(utils.getError(err));\n  }\n\n  function callFn(fn) {\n    var result = fn.call(ctx);\n    if (result && typeof result.then === 'function') {\n      self.resetTimeout();\n      result\n        .then(function() {\n          done();\n          // Return null so libraries like bluebird do not warn about\n          // subsequently constructed Promises.\n          return null;\n        },\n        function(reason) {\n          done(reason || new Error('Promise rejected with no or falsy reason'));\n        });\n    } else {\n      if (self.asyncOnly) {\n        return done(new Error('--async-only option in use without declaring `done()` or returning a promise'));\n      }\n\n      done();\n    }\n  }\n\n  function callFnAsync(fn) {\n    var result = fn.call(ctx, function(err) {\n      if (err instanceof Error || toString.call(err) === '[object Error]') {\n        return done(err);\n      }\n      if (err) {\n        if (Object.prototype.toString.call(err) === '[object Object]') {\n          return done(new Error('done() invoked with non-Error: '\n            + JSON.stringify(err)));\n        }\n        return done(new Error('done() invoked with non-Error: ' + err));\n      }\n      if (result && utils.isPromise(result)) {\n        return done(new Error('Resolution method is overspecified. Specify a callback *or* return a Promise; not both.'));\n      }\n\n      done();\n    });\n  }\n};\n\n}).call(this,typeof global !== \"undefined\" ? global : typeof self !== \"undefined\" ? self : typeof window !== \"undefined\" ? window : {})\n},{\"./ms\":15,\"./pending\":16,\"./utils\":38,\"debug\":2,\"events\":3,\"json3\":54,\"lodash.create\":60}],34:[function(require,module,exports){\n(function (process,global){\n/**\n * Module dependencies.\n */\n\nvar EventEmitter = require('events').EventEmitter;\nvar Pending = require('./pending');\nvar utils = require('./utils');\nvar inherits = utils.inherits;\nvar debug = require('debug')('mocha:runner');\nvar Runnable = require('./runnable');\nvar filter = utils.filter;\nvar indexOf = utils.indexOf;\nvar some = utils.some;\nvar keys = utils.keys;\nvar stackFilter = utils.stackTraceFilter();\nvar stringify = utils.stringify;\nvar type = utils.type;\nvar undefinedError = utils.undefinedError;\nvar isArray = utils.isArray;\n\n/**\n * Non-enumerable globals.\n */\n\nvar globals = [\n  'setTimeout',\n  'clearTimeout',\n  'setInterval',\n  'clearInterval',\n  'XMLHttpRequest',\n  'Date',\n  'setImmediate',\n  'clearImmediate'\n];\n\n/**\n * Expose `Runner`.\n */\n\nmodule.exports = Runner;\n\n/**\n * Initialize a `Runner` for the given `suite`.\n *\n * Events:\n *\n *   - `start`  execution started\n *   - `end`  execution complete\n *   - `suite`  (suite) test suite execution started\n *   - `suite end`  (suite) all tests (and sub-suites) have finished\n *   - `test`  (test) test execution started\n *   - `test end`  (test) test completed\n *   - `hook`  (hook) hook execution started\n *   - `hook end`  (hook) hook complete\n *   - `pass`  (test) test passed\n *   - `fail`  (test, err) test failed\n *   - `pending`  (test) test pending\n *\n * @api public\n * @param {Suite} suite Root suite\n * @param {boolean} [delay] Whether or not to delay execution of root suite\n * until ready.\n */\nfunction Runner(suite, delay) {\n  var self = this;\n  this._globals = [];\n  this._abort = false;\n  this._delay = delay;\n  this.suite = suite;\n  this.started = false;\n  this.total = suite.total();\n  this.failures = 0;\n  this.on('test end', function(test) {\n    self.checkGlobals(test);\n  });\n  this.on('hook end', function(hook) {\n    self.checkGlobals(hook);\n  });\n  this._defaultGrep = /.*/;\n  this.grep(this._defaultGrep);\n  this.globals(this.globalProps().concat(extraGlobals()));\n}\n\n/**\n * Wrapper for setImmediate, process.nextTick, or browser polyfill.\n *\n * @param {Function} fn\n * @api private\n */\nRunner.immediately = global.setImmediate || process.nextTick;\n\n/**\n * Inherit from `EventEmitter.prototype`.\n */\ninherits(Runner, EventEmitter);\n\n/**\n * Run tests with full titles matching `re`. Updates runner.total\n * with number of tests matched.\n *\n * @param {RegExp} re\n * @param {Boolean} invert\n * @return {Runner} for chaining\n * @api public\n * @param {RegExp} re\n * @param {boolean} invert\n * @return {Runner} Runner instance.\n */\nRunner.prototype.grep = function(re, invert) {\n  debug('grep %s', re);\n  this._grep = re;\n  this._invert = invert;\n  this.total = this.grepTotal(this.suite);\n  return this;\n};\n\n/**\n * Returns the number of tests matching the grep search for the\n * given suite.\n *\n * @param {Suite} suite\n * @return {Number}\n * @api public\n * @param {Suite} suite\n * @return {number}\n */\nRunner.prototype.grepTotal = function(suite) {\n  var self = this;\n  var total = 0;\n\n  suite.eachTest(function(test) {\n    var match = self._grep.test(test.fullTitle());\n    if (self._invert) {\n      match = !match;\n    }\n    if (match) {\n      total++;\n    }\n  });\n\n  return total;\n};\n\n/**\n * Return a list of global properties.\n *\n * @return {Array}\n * @api private\n */\nRunner.prototype.globalProps = function() {\n  var props = keys(global);\n\n  // non-enumerables\n  for (var i = 0; i < globals.length; ++i) {\n    if (~indexOf(props, globals[i])) {\n      continue;\n    }\n    props.push(globals[i]);\n  }\n\n  return props;\n};\n\n/**\n * Allow the given `arr` of globals.\n *\n * @param {Array} arr\n * @return {Runner} for chaining\n * @api public\n * @param {Array} arr\n * @return {Runner} Runner instance.\n */\nRunner.prototype.globals = function(arr) {\n  if (!arguments.length) {\n    return this._globals;\n  }\n  debug('globals %j', arr);\n  this._globals = this._globals.concat(arr);\n  return this;\n};\n\n/**\n * Check for global variable leaks.\n *\n * @api private\n */\nRunner.prototype.checkGlobals = function(test) {\n  if (this.ignoreLeaks) {\n    return;\n  }\n  var ok = this._globals;\n\n  var globals = this.globalProps();\n  var leaks;\n\n  if (test) {\n    ok = ok.concat(test._allowedGlobals || []);\n  }\n\n  if (this.prevGlobalsLength === globals.length) {\n    return;\n  }\n  this.prevGlobalsLength = globals.length;\n\n  leaks = filterLeaks(ok, globals);\n  this._globals = this._globals.concat(leaks);\n\n  if (leaks.length > 1) {\n    this.fail(test, new Error('global leaks detected: ' + leaks.join(', ') + ''));\n  } else if (leaks.length) {\n    this.fail(test, new Error('global leak detected: ' + leaks[0]));\n  }\n};\n\n/**\n * Fail the given `test`.\n *\n * @api private\n * @param {Test} test\n * @param {Error} err\n */\nRunner.prototype.fail = function(test, err) {\n  if (test.isPending()) {\n    return;\n  }\n\n  ++this.failures;\n  test.state = 'failed';\n\n  if (!(err instanceof Error || err && typeof err.message === 'string')) {\n    err = new Error('the ' + type(err) + ' ' + stringify(err) + ' was thrown, throw an Error :)');\n  }\n\n  err.stack = (this.fullStackTrace || !err.stack)\n    ? err.stack\n    : stackFilter(err.stack);\n\n  this.emit('fail', test, err);\n};\n\n/**\n * Fail the given `hook` with `err`.\n *\n * Hook failures work in the following pattern:\n * - If bail, then exit\n * - Failed `before` hook skips all tests in a suite and subsuites,\n *   but jumps to corresponding `after` hook\n * - Failed `before each` hook skips remaining tests in a\n *   suite and jumps to corresponding `after each` hook,\n *   which is run only once\n * - Failed `after` hook does not alter\n *   execution order\n * - Failed `after each` hook skips remaining tests in a\n *   suite and subsuites, but executes other `after each`\n *   hooks\n *\n * @api private\n * @param {Hook} hook\n * @param {Error} err\n */\nRunner.prototype.failHook = function(hook, err) {\n  if (hook.ctx && hook.ctx.currentTest) {\n    hook.originalTitle = hook.originalTitle || hook.title;\n    hook.title = hook.originalTitle + ' for \"' + hook.ctx.currentTest.title + '\"';\n  }\n\n  this.fail(hook, err);\n  if (this.suite.bail()) {\n    this.emit('end');\n  }\n};\n\n/**\n * Run hook `name` callbacks and then invoke `fn()`.\n *\n * @api private\n * @param {string} name\n * @param {Function} fn\n */\n\nRunner.prototype.hook = function(name, fn) {\n  var suite = this.suite;\n  var hooks = suite['_' + name];\n  var self = this;\n\n  function next(i) {\n    var hook = hooks[i];\n    if (!hook) {\n      return fn();\n    }\n    self.currentRunnable = hook;\n\n    hook.ctx.currentTest = self.test;\n\n    self.emit('hook', hook);\n\n    if (!hook.listeners('error').length) {\n      hook.on('error', function(err) {\n        self.failHook(hook, err);\n      });\n    }\n\n    hook.run(function(err) {\n      var testError = hook.error();\n      if (testError) {\n        self.fail(self.test, testError);\n      }\n      if (err) {\n        if (err instanceof Pending) {\n          if (name === 'beforeEach' || name === 'afterEach') {\n            self.test.pending = true;\n          } else {\n            utils.forEach(suite.tests, function(test) {\n              test.pending = true;\n            });\n            // a pending hook won't be executed twice.\n            hook.pending = true;\n          }\n        } else {\n          self.failHook(hook, err);\n\n          // stop executing hooks, notify callee of hook err\n          return fn(err);\n        }\n      }\n      self.emit('hook end', hook);\n      delete hook.ctx.currentTest;\n      next(++i);\n    });\n  }\n\n  Runner.immediately(function() {\n    next(0);\n  });\n};\n\n/**\n * Run hook `name` for the given array of `suites`\n * in order, and callback `fn(err, errSuite)`.\n *\n * @api private\n * @param {string} name\n * @param {Array} suites\n * @param {Function} fn\n */\nRunner.prototype.hooks = function(name, suites, fn) {\n  var self = this;\n  var orig = this.suite;\n\n  function next(suite) {\n    self.suite = suite;\n\n    if (!suite) {\n      self.suite = orig;\n      return fn();\n    }\n\n    self.hook(name, function(err) {\n      if (err) {\n        var errSuite = self.suite;\n        self.suite = orig;\n        return fn(err, errSuite);\n      }\n\n      next(suites.pop());\n    });\n  }\n\n  next(suites.pop());\n};\n\n/**\n * Run hooks from the top level down.\n *\n * @param {String} name\n * @param {Function} fn\n * @api private\n */\nRunner.prototype.hookUp = function(name, fn) {\n  var suites = [this.suite].concat(this.parents()).reverse();\n  this.hooks(name, suites, fn);\n};\n\n/**\n * Run hooks from the bottom up.\n *\n * @param {String} name\n * @param {Function} fn\n * @api private\n */\nRunner.prototype.hookDown = function(name, fn) {\n  var suites = [this.suite].concat(this.parents());\n  this.hooks(name, suites, fn);\n};\n\n/**\n * Return an array of parent Suites from\n * closest to furthest.\n *\n * @return {Array}\n * @api private\n */\nRunner.prototype.parents = function() {\n  var suite = this.suite;\n  var suites = [];\n  while (suite.parent) {\n    suite = suite.parent;\n    suites.push(suite);\n  }\n  return suites;\n};\n\n/**\n * Run the current test and callback `fn(err)`.\n *\n * @param {Function} fn\n * @api private\n */\nRunner.prototype.runTest = function(fn) {\n  var self = this;\n  var test = this.test;\n\n  if (!test) {\n    return;\n  }\n  if (this.asyncOnly) {\n    test.asyncOnly = true;\n  }\n\n  if (this.allowUncaught) {\n    test.allowUncaught = true;\n    return test.run(fn);\n  }\n  try {\n    test.on('error', function(err) {\n      self.fail(test, err);\n    });\n    test.run(fn);\n  } catch (err) {\n    fn(err);\n  }\n};\n\n/**\n * Run tests in the given `suite` and invoke the callback `fn()` when complete.\n *\n * @api private\n * @param {Suite} suite\n * @param {Function} fn\n */\nRunner.prototype.runTests = function(suite, fn) {\n  var self = this;\n  var tests = suite.tests.slice();\n  var test;\n\n  function hookErr(_, errSuite, after) {\n    // before/after Each hook for errSuite failed:\n    var orig = self.suite;\n\n    // for failed 'after each' hook start from errSuite parent,\n    // otherwise start from errSuite itself\n    self.suite = after ? errSuite.parent : errSuite;\n\n    if (self.suite) {\n      // call hookUp afterEach\n      self.hookUp('afterEach', function(err2, errSuite2) {\n        self.suite = orig;\n        // some hooks may fail even now\n        if (err2) {\n          return hookErr(err2, errSuite2, true);\n        }\n        // report error suite\n        fn(errSuite);\n      });\n    } else {\n      // there is no need calling other 'after each' hooks\n      self.suite = orig;\n      fn(errSuite);\n    }\n  }\n\n  function next(err, errSuite) {\n    // if we bail after first err\n    if (self.failures && suite._bail) {\n      return fn();\n    }\n\n    if (self._abort) {\n      return fn();\n    }\n\n    if (err) {\n      return hookErr(err, errSuite, true);\n    }\n\n    // next test\n    test = tests.shift();\n\n    // all done\n    if (!test) {\n      return fn();\n    }\n\n    // grep\n    var match = self._grep.test(test.fullTitle());\n    if (self._invert) {\n      match = !match;\n    }\n    if (!match) {\n      // Run immediately only if we have defined a grep. When we\n      // define a grep — It can cause maximum callstack error if\n      // the grep is doing a large recursive loop by neglecting\n      // all tests. The run immediately function also comes with\n      // a performance cost. So we don't want to run immediately\n      // if we run the whole test suite, because running the whole\n      // test suite don't do any immediate recursive loops. Thus,\n      // allowing a JS runtime to breathe.\n      if (self._grep !== self._defaultGrep) {\n        Runner.immediately(next);\n      } else {\n        next();\n      }\n      return;\n    }\n\n    if (test.isPending()) {\n      self.emit('pending', test);\n      self.emit('test end', test);\n      return next();\n    }\n\n    // execute test and hook(s)\n    self.emit('test', self.test = test);\n    self.hookDown('beforeEach', function(err, errSuite) {\n      if (test.isPending()) {\n        self.emit('pending', test);\n        self.emit('test end', test);\n        return next();\n      }\n      if (err) {\n        return hookErr(err, errSuite, false);\n      }\n      self.currentRunnable = self.test;\n      self.runTest(function(err) {\n        test = self.test;\n        if (err) {\n          var retry = test.currentRetry();\n          if (err instanceof Pending) {\n            test.pending = true;\n            self.emit('pending', test);\n          } else if (retry < test.retries()) {\n            var clonedTest = test.clone();\n            clonedTest.currentRetry(retry + 1);\n            tests.unshift(clonedTest);\n\n            // Early return + hook trigger so that it doesn't\n            // increment the count wrong\n            return self.hookUp('afterEach', next);\n          } else {\n            self.fail(test, err);\n          }\n          self.emit('test end', test);\n\n          if (err instanceof Pending) {\n            return next();\n          }\n\n          return self.hookUp('afterEach', next);\n        }\n\n        test.state = 'passed';\n        self.emit('pass', test);\n        self.emit('test end', test);\n        self.hookUp('afterEach', next);\n      });\n    });\n  }\n\n  this.next = next;\n  this.hookErr = hookErr;\n  next();\n};\n\n/**\n * Run the given `suite` and invoke the callback `fn()` when complete.\n *\n * @api private\n * @param {Suite} suite\n * @param {Function} fn\n */\nRunner.prototype.runSuite = function(suite, fn) {\n  var i = 0;\n  var self = this;\n  var total = this.grepTotal(suite);\n  var afterAllHookCalled = false;\n\n  debug('run suite %s', suite.fullTitle());\n\n  if (!total || (self.failures && suite._bail)) {\n    return fn();\n  }\n\n  this.emit('suite', this.suite = suite);\n\n  function next(errSuite) {\n    if (errSuite) {\n      // current suite failed on a hook from errSuite\n      if (errSuite === suite) {\n        // if errSuite is current suite\n        // continue to the next sibling suite\n        return done();\n      }\n      // errSuite is among the parents of current suite\n      // stop execution of errSuite and all sub-suites\n      return done(errSuite);\n    }\n\n    if (self._abort) {\n      return done();\n    }\n\n    var curr = suite.suites[i++];\n    if (!curr) {\n      return done();\n    }\n\n    // Avoid grep neglecting large number of tests causing a\n    // huge recursive loop and thus a maximum call stack error.\n    // See comment in `this.runTests()` for more information.\n    if (self._grep !== self._defaultGrep) {\n      Runner.immediately(function() {\n        self.runSuite(curr, next);\n      });\n    } else {\n      self.runSuite(curr, next);\n    }\n  }\n\n  function done(errSuite) {\n    self.suite = suite;\n    self.nextSuite = next;\n\n    if (afterAllHookCalled) {\n      fn(errSuite);\n    } else {\n      // mark that the afterAll block has been called once\n      // and so can be skipped if there is an error in it.\n      afterAllHookCalled = true;\n\n      // remove reference to test\n      delete self.test;\n\n      self.hook('afterAll', function() {\n        self.emit('suite end', suite);\n        fn(errSuite);\n      });\n    }\n  }\n\n  this.nextSuite = next;\n\n  this.hook('beforeAll', function(err) {\n    if (err) {\n      return done();\n    }\n    self.runTests(suite, next);\n  });\n};\n\n/**\n * Handle uncaught exceptions.\n *\n * @param {Error} err\n * @api private\n */\nRunner.prototype.uncaught = function(err) {\n  if (err) {\n    debug('uncaught exception %s', err !== function() {\n      return this;\n    }.call(err) ? err : (err.message || err));\n  } else {\n    debug('uncaught undefined exception');\n    err = undefinedError();\n  }\n  err.uncaught = true;\n\n  var runnable = this.currentRunnable;\n\n  if (!runnable) {\n    runnable = new Runnable('Uncaught error outside test suite');\n    runnable.parent = this.suite;\n\n    if (this.started) {\n      this.fail(runnable, err);\n    } else {\n      // Can't recover from this failure\n      this.emit('start');\n      this.fail(runnable, err);\n      this.emit('end');\n    }\n\n    return;\n  }\n\n  runnable.clearTimeout();\n\n  // Ignore errors if complete or pending\n  if (runnable.state || runnable.isPending()) {\n    return;\n  }\n  this.fail(runnable, err);\n\n  // recover from test\n  if (runnable.type === 'test') {\n    this.emit('test end', runnable);\n    this.hookUp('afterEach', this.next);\n    return;\n  }\n\n // recover from hooks\n  if (runnable.type === 'hook') {\n    var errSuite = this.suite;\n    // if hook failure is in afterEach block\n    if (runnable.fullTitle().indexOf('after each') > -1) {\n      return this.hookErr(err, errSuite, true);\n    }\n    // if hook failure is in beforeEach block\n    if (runnable.fullTitle().indexOf('before each') > -1) {\n      return this.hookErr(err, errSuite, false);\n    }\n    // if hook failure is in after or before blocks\n    return this.nextSuite(errSuite);\n  }\n\n  // bail\n  this.emit('end');\n};\n\n/**\n * Cleans up the references to all the deferred functions\n * (before/after/beforeEach/afterEach) and tests of a Suite.\n * These must be deleted otherwise a memory leak can happen,\n * as those functions may reference variables from closures,\n * thus those variables can never be garbage collected as long\n * as the deferred functions exist.\n *\n * @param {Suite} suite\n */\nfunction cleanSuiteReferences(suite) {\n  function cleanArrReferences(arr) {\n    for (var i = 0; i < arr.length; i++) {\n      delete arr[i].fn;\n    }\n  }\n\n  if (isArray(suite._beforeAll)) {\n    cleanArrReferences(suite._beforeAll);\n  }\n\n  if (isArray(suite._beforeEach)) {\n    cleanArrReferences(suite._beforeEach);\n  }\n\n  if (isArray(suite._afterAll)) {\n    cleanArrReferences(suite._afterAll);\n  }\n\n  if (isArray(suite._afterEach)) {\n    cleanArrReferences(suite._afterEach);\n  }\n\n  for (var i = 0; i < suite.tests.length; i++) {\n    delete suite.tests[i].fn;\n  }\n}\n\n/**\n * Run the root suite and invoke `fn(failures)`\n * on completion.\n *\n * @param {Function} fn\n * @return {Runner} for chaining\n * @api public\n * @param {Function} fn\n * @return {Runner} Runner instance.\n */\nRunner.prototype.run = function(fn) {\n  var self = this;\n  var rootSuite = this.suite;\n\n  // If there is an `only` filter\n  if (this.hasOnly) {\n    filterOnly(rootSuite);\n  }\n\n  fn = fn || function() {};\n\n  function uncaught(err) {\n    self.uncaught(err);\n  }\n\n  function start() {\n    self.started = true;\n    self.emit('start');\n    self.runSuite(rootSuite, function() {\n      debug('finished running');\n      self.emit('end');\n    });\n  }\n\n  debug('start');\n\n  // references cleanup to avoid memory leaks\n  this.on('suite end', cleanSuiteReferences);\n\n  // callback\n  this.on('end', function() {\n    debug('end');\n    process.removeListener('uncaughtException', uncaught);\n    fn(self.failures);\n  });\n\n  // uncaught exception\n  process.on('uncaughtException', uncaught);\n\n  if (this._delay) {\n    // for reporters, I guess.\n    // might be nice to debounce some dots while we wait.\n    this.emit('waiting', rootSuite);\n    rootSuite.once('run', start);\n  } else {\n    start();\n  }\n\n  return this;\n};\n\n/**\n * Cleanly abort execution.\n *\n * @api public\n * @return {Runner} Runner instance.\n */\nRunner.prototype.abort = function() {\n  debug('aborting');\n  this._abort = true;\n\n  return this;\n};\n\n/**\n * Filter suites based on `isOnly` logic.\n *\n * @param {Array} suite\n * @returns {Boolean}\n * @api private\n */\nfunction filterOnly(suite) {\n  if (suite._onlyTests.length) {\n    // If the suite contains `only` tests, run those and ignore any nested suites.\n    suite.tests = suite._onlyTests;\n    suite.suites = [];\n  } else {\n    // Otherwise, do not run any of the tests in this suite.\n    suite.tests = [];\n    utils.forEach(suite._onlySuites, function(onlySuite) {\n      // If there are other `only` tests/suites nested in the current `only` suite, then filter that `only` suite.\n      // Otherwise, all of the tests on this `only` suite should be run, so don't filter it.\n      if (hasOnly(onlySuite)) {\n        filterOnly(onlySuite);\n      }\n    });\n    // Run the `only` suites, as well as any other suites that have `only` tests/suites as descendants.\n    suite.suites = filter(suite.suites, function(childSuite) {\n      return indexOf(suite._onlySuites, childSuite) !== -1 || filterOnly(childSuite);\n    });\n  }\n  // Keep the suite only if there is something to run\n  return suite.tests.length || suite.suites.length;\n}\n\n/**\n * Determines whether a suite has an `only` test or suite as a descendant.\n *\n * @param {Array} suite\n * @returns {Boolean}\n * @api private\n */\nfunction hasOnly(suite) {\n  return suite._onlyTests.length || suite._onlySuites.length || some(suite.suites, hasOnly);\n}\n\n/**\n * Filter leaks with the given globals flagged as `ok`.\n *\n * @api private\n * @param {Array} ok\n * @param {Array} globals\n * @return {Array}\n */\nfunction filterLeaks(ok, globals) {\n  return filter(globals, function(key) {\n    // Firefox and Chrome exposes iframes as index inside the window object\n    if (/^\\d+/.test(key)) {\n      return false;\n    }\n\n    // in firefox\n    // if runner runs in an iframe, this iframe's window.getInterface method\n    // not init at first it is assigned in some seconds\n    if (global.navigator && (/^getInterface/).test(key)) {\n      return false;\n    }\n\n    // an iframe could be approached by window[iframeIndex]\n    // in ie6,7,8 and opera, iframeIndex is enumerable, this could cause leak\n    if (global.navigator && (/^\\d+/).test(key)) {\n      return false;\n    }\n\n    // Opera and IE expose global variables for HTML element IDs (issue #243)\n    if (/^mocha-/.test(key)) {\n      return false;\n    }\n\n    var matched = filter(ok, function(ok) {\n      if (~ok.indexOf('*')) {\n        return key.indexOf(ok.split('*')[0]) === 0;\n      }\n      return key === ok;\n    });\n    return !matched.length && (!global.navigator || key !== 'onerror');\n  });\n}\n\n/**\n * Array of globals dependent on the environment.\n *\n * @return {Array}\n * @api private\n */\nfunction extraGlobals() {\n  if (typeof process === 'object' && typeof process.version === 'string') {\n    var parts = process.version.split('.');\n    var nodeVersion = utils.reduce(parts, function(a, v) {\n      return a << 8 | v;\n    });\n\n    // 'errno' was renamed to process._errno in v0.9.11.\n\n    if (nodeVersion < 0x00090B) {\n      return ['errno'];\n    }\n  }\n\n  return [];\n}\n\n}).call(this,require('_process'),typeof global !== \"undefined\" ? global : typeof self !== \"undefined\" ? self : typeof window !== \"undefined\" ? window : {})\n},{\"./pending\":16,\"./runnable\":33,\"./utils\":38,\"_process\":67,\"debug\":2,\"events\":3}],35:[function(require,module,exports){\n/**\n * Module dependencies.\n */\n\nvar EventEmitter = require('events').EventEmitter;\nvar Hook = require('./hook');\nvar utils = require('./utils');\nvar inherits = utils.inherits;\nvar debug = require('debug')('mocha:suite');\nvar milliseconds = require('./ms');\n\n/**\n * Expose `Suite`.\n */\n\nexports = module.exports = Suite;\n\n/**\n * Create a new `Suite` with the given `title` and parent `Suite`. When a suite\n * with the same title is already present, that suite is returned to provide\n * nicer reporter and more flexible meta-testing.\n *\n * @api public\n * @param {Suite} parent\n * @param {string} title\n * @return {Suite}\n */\nexports.create = function(parent, title) {\n  var suite = new Suite(title, parent.ctx);\n  suite.parent = parent;\n  title = suite.fullTitle();\n  parent.addSuite(suite);\n  return suite;\n};\n\n/**\n * Initialize a new `Suite` with the given `title` and `ctx`.\n *\n * @api private\n * @param {string} title\n * @param {Context} parentContext\n */\nfunction Suite(title, parentContext) {\n  if (!utils.isString(title)) {\n    throw new Error('Suite `title` should be a \"string\" but \"' + typeof title + '\" was given instead.');\n  }\n  this.title = title;\n  function Context() {}\n  Context.prototype = parentContext;\n  this.ctx = new Context();\n  this.suites = [];\n  this.tests = [];\n  this.pending = false;\n  this._beforeEach = [];\n  this._beforeAll = [];\n  this._afterEach = [];\n  this._afterAll = [];\n  this.root = !title;\n  this._timeout = 2000;\n  this._enableTimeouts = true;\n  this._slow = 75;\n  this._bail = false;\n  this._retries = -1;\n  this._onlyTests = [];\n  this._onlySuites = [];\n  this.delayed = false;\n}\n\n/**\n * Inherit from `EventEmitter.prototype`.\n */\ninherits(Suite, EventEmitter);\n\n/**\n * Return a clone of this `Suite`.\n *\n * @api private\n * @return {Suite}\n */\nSuite.prototype.clone = function() {\n  var suite = new Suite(this.title);\n  debug('clone');\n  suite.ctx = this.ctx;\n  suite.timeout(this.timeout());\n  suite.retries(this.retries());\n  suite.enableTimeouts(this.enableTimeouts());\n  suite.slow(this.slow());\n  suite.bail(this.bail());\n  return suite;\n};\n\n/**\n * Set timeout `ms` or short-hand such as \"2s\".\n *\n * @api private\n * @param {number|string} ms\n * @return {Suite|number} for chaining\n */\nSuite.prototype.timeout = function(ms) {\n  if (!arguments.length) {\n    return this._timeout;\n  }\n  if (ms.toString() === '0') {\n    this._enableTimeouts = false;\n  }\n  if (typeof ms === 'string') {\n    ms = milliseconds(ms);\n  }\n  debug('timeout %d', ms);\n  this._timeout = parseInt(ms, 10);\n  return this;\n};\n\n/**\n * Set number of times to retry a failed test.\n *\n * @api private\n * @param {number|string} n\n * @return {Suite|number} for chaining\n */\nSuite.prototype.retries = function(n) {\n  if (!arguments.length) {\n    return this._retries;\n  }\n  debug('retries %d', n);\n  this._retries = parseInt(n, 10) || 0;\n  return this;\n};\n\n/**\n  * Set timeout to `enabled`.\n  *\n  * @api private\n  * @param {boolean} enabled\n  * @return {Suite|boolean} self or enabled\n  */\nSuite.prototype.enableTimeouts = function(enabled) {\n  if (!arguments.length) {\n    return this._enableTimeouts;\n  }\n  debug('enableTimeouts %s', enabled);\n  this._enableTimeouts = enabled;\n  return this;\n};\n\n/**\n * Set slow `ms` or short-hand such as \"2s\".\n *\n * @api private\n * @param {number|string} ms\n * @return {Suite|number} for chaining\n */\nSuite.prototype.slow = function(ms) {\n  if (!arguments.length) {\n    return this._slow;\n  }\n  if (typeof ms === 'string') {\n    ms = milliseconds(ms);\n  }\n  debug('slow %d', ms);\n  this._slow = ms;\n  return this;\n};\n\n/**\n * Sets whether to bail after first error.\n *\n * @api private\n * @param {boolean} bail\n * @return {Suite|number} for chaining\n */\nSuite.prototype.bail = function(bail) {\n  if (!arguments.length) {\n    return this._bail;\n  }\n  debug('bail %s', bail);\n  this._bail = bail;\n  return this;\n};\n\n/**\n * Check if this suite or its parent suite is marked as pending.\n *\n * @api private\n */\nSuite.prototype.isPending = function() {\n  return this.pending || (this.parent && this.parent.isPending());\n};\n\n/**\n * Run `fn(test[, done])` before running tests.\n *\n * @api private\n * @param {string} title\n * @param {Function} fn\n * @return {Suite} for chaining\n */\nSuite.prototype.beforeAll = function(title, fn) {\n  if (this.isPending()) {\n    return this;\n  }\n  if (typeof title === 'function') {\n    fn = title;\n    title = fn.name;\n  }\n  title = '\"before all\" hook' + (title ? ': ' + title : '');\n\n  var hook = new Hook(title, fn);\n  hook.parent = this;\n  hook.timeout(this.timeout());\n  hook.retries(this.retries());\n  hook.enableTimeouts(this.enableTimeouts());\n  hook.slow(this.slow());\n  hook.ctx = this.ctx;\n  this._beforeAll.push(hook);\n  this.emit('beforeAll', hook);\n  return this;\n};\n\n/**\n * Run `fn(test[, done])` after running tests.\n *\n * @api private\n * @param {string} title\n * @param {Function} fn\n * @return {Suite} for chaining\n */\nSuite.prototype.afterAll = function(title, fn) {\n  if (this.isPending()) {\n    return this;\n  }\n  if (typeof title === 'function') {\n    fn = title;\n    title = fn.name;\n  }\n  title = '\"after all\" hook' + (title ? ': ' + title : '');\n\n  var hook = new Hook(title, fn);\n  hook.parent = this;\n  hook.timeout(this.timeout());\n  hook.retries(this.retries());\n  hook.enableTimeouts(this.enableTimeouts());\n  hook.slow(this.slow());\n  hook.ctx = this.ctx;\n  this._afterAll.push(hook);\n  this.emit('afterAll', hook);\n  return this;\n};\n\n/**\n * Run `fn(test[, done])` before each test case.\n *\n * @api private\n * @param {string} title\n * @param {Function} fn\n * @return {Suite} for chaining\n */\nSuite.prototype.beforeEach = function(title, fn) {\n  if (this.isPending()) {\n    return this;\n  }\n  if (typeof title === 'function') {\n    fn = title;\n    title = fn.name;\n  }\n  title = '\"before each\" hook' + (title ? ': ' + title : '');\n\n  var hook = new Hook(title, fn);\n  hook.parent = this;\n  hook.timeout(this.timeout());\n  hook.retries(this.retries());\n  hook.enableTimeouts(this.enableTimeouts());\n  hook.slow(this.slow());\n  hook.ctx = this.ctx;\n  this._beforeEach.push(hook);\n  this.emit('beforeEach', hook);\n  return this;\n};\n\n/**\n * Run `fn(test[, done])` after each test case.\n *\n * @api private\n * @param {string} title\n * @param {Function} fn\n * @return {Suite} for chaining\n */\nSuite.prototype.afterEach = function(title, fn) {\n  if (this.isPending()) {\n    return this;\n  }\n  if (typeof title === 'function') {\n    fn = title;\n    title = fn.name;\n  }\n  title = '\"after each\" hook' + (title ? ': ' + title : '');\n\n  var hook = new Hook(title, fn);\n  hook.parent = this;\n  hook.timeout(this.timeout());\n  hook.retries(this.retries());\n  hook.enableTimeouts(this.enableTimeouts());\n  hook.slow(this.slow());\n  hook.ctx = this.ctx;\n  this._afterEach.push(hook);\n  this.emit('afterEach', hook);\n  return this;\n};\n\n/**\n * Add a test `suite`.\n *\n * @api private\n * @param {Suite} suite\n * @return {Suite} for chaining\n */\nSuite.prototype.addSuite = function(suite) {\n  suite.parent = this;\n  suite.timeout(this.timeout());\n  suite.retries(this.retries());\n  suite.enableTimeouts(this.enableTimeouts());\n  suite.slow(this.slow());\n  suite.bail(this.bail());\n  this.suites.push(suite);\n  this.emit('suite', suite);\n  return this;\n};\n\n/**\n * Add a `test` to this suite.\n *\n * @api private\n * @param {Test} test\n * @return {Suite} for chaining\n */\nSuite.prototype.addTest = function(test) {\n  test.parent = this;\n  test.timeout(this.timeout());\n  test.retries(this.retries());\n  test.enableTimeouts(this.enableTimeouts());\n  test.slow(this.slow());\n  test.ctx = this.ctx;\n  this.tests.push(test);\n  this.emit('test', test);\n  return this;\n};\n\n/**\n * Return the full title generated by recursively concatenating the parent's\n * full title.\n *\n * @api public\n * @return {string}\n */\nSuite.prototype.fullTitle = function() {\n  if (this.parent) {\n    var full = this.parent.fullTitle();\n    if (full) {\n      return full + ' ' + this.title;\n    }\n  }\n  return this.title;\n};\n\n/**\n * Return the total number of tests.\n *\n * @api public\n * @return {number}\n */\nSuite.prototype.total = function() {\n  return utils.reduce(this.suites, function(sum, suite) {\n    return sum + suite.total();\n  }, 0) + this.tests.length;\n};\n\n/**\n * Iterates through each suite recursively to find all tests. Applies a\n * function in the format `fn(test)`.\n *\n * @api private\n * @param {Function} fn\n * @return {Suite}\n */\nSuite.prototype.eachTest = function(fn) {\n  utils.forEach(this.tests, fn);\n  utils.forEach(this.suites, function(suite) {\n    suite.eachTest(fn);\n  });\n  return this;\n};\n\n/**\n * This will run the root suite if we happen to be running in delayed mode.\n */\nSuite.prototype.run = function run() {\n  if (this.root) {\n    this.emit('run');\n  }\n};\n\n},{\"./hook\":7,\"./ms\":15,\"./utils\":38,\"debug\":2,\"events\":3}],36:[function(require,module,exports){\n/**\n * Module dependencies.\n */\n\nvar Runnable = require('./runnable');\nvar create = require('lodash.create');\nvar isString = require('./utils').isString;\n\n/**\n * Expose `Test`.\n */\n\nmodule.exports = Test;\n\n/**\n * Initialize a new `Test` with the given `title` and callback `fn`.\n *\n * @api private\n * @param {String} title\n * @param {Function} fn\n */\nfunction Test(title, fn) {\n  if (!isString(title)) {\n    throw new Error('Test `title` should be a \"string\" but \"' + typeof title + '\" was given instead.');\n  }\n  Runnable.call(this, title, fn);\n  this.pending = !fn;\n  this.type = 'test';\n}\n\n/**\n * Inherit from `Runnable.prototype`.\n */\nTest.prototype = create(Runnable.prototype, {\n  constructor: Test\n});\n\nTest.prototype.clone = function() {\n  var test = new Test(this.title, this.fn);\n  test.timeout(this.timeout());\n  test.slow(this.slow());\n  test.enableTimeouts(this.enableTimeouts());\n  test.retries(this.retries());\n  test.currentRetry(this.currentRetry());\n  test.globals(this.globals());\n  test.parent = this.parent;\n  test.file = this.file;\n  test.ctx = this.ctx;\n  return test;\n};\n\n},{\"./runnable\":33,\"./utils\":38,\"lodash.create\":60}],37:[function(require,module,exports){\n'use strict';\n\n/**\n * Pad a `number` with a ten's place zero.\n *\n * @param {number} number\n * @return {string}\n */\nfunction pad(number) {\n  var n = number.toString();\n  return n.length === 1 ? '0' + n : n;\n}\n\n/**\n * Turn a `date` into an ISO string.\n *\n * https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/toISOString\n *\n * @param {Date} date\n * @return {string}\n */\nfunction toISOString(date) {\n  return date.getUTCFullYear()\n    + '-' + pad(date.getUTCMonth() + 1)\n    + '-' + pad(date.getUTCDate())\n    + 'T' + pad(date.getUTCHours())\n    + ':' + pad(date.getUTCMinutes())\n    + ':' + pad(date.getUTCSeconds())\n    + '.' + String((date.getUTCMilliseconds()/1000).toFixed(3)).slice(2, 5)\n    + 'Z';\n}\n\n/*\n * Exports.\n */\n\nmodule.exports = toISOString;\n\n},{}],38:[function(require,module,exports){\n(function (process,Buffer){\n/* eslint-env browser */\n\n/**\n * Module dependencies.\n */\n\nvar JSON = require('json3');\nvar basename = require('path').basename;\nvar debug = require('debug')('mocha:watch');\nvar exists = require('fs').existsSync || require('path').existsSync;\nvar glob = require('glob');\nvar path = require('path');\nvar join = path.join;\nvar readdirSync = require('fs').readdirSync;\nvar statSync = require('fs').statSync;\nvar watchFile = require('fs').watchFile;\nvar toISOString = require('./to-iso-string');\n\n/**\n * Ignored directories.\n */\n\nvar ignore = ['node_modules', '.git'];\n\nexports.inherits = require('util').inherits;\n\n/**\n * Escape special characters in the given string of html.\n *\n * @api private\n * @param  {string} html\n * @return {string}\n */\nexports.escape = function(html) {\n  return String(html)\n    .replace(/&/g, '&amp;')\n    .replace(/\"/g, '&quot;')\n    .replace(/</g, '&lt;')\n    .replace(/>/g, '&gt;');\n};\n\n/**\n * Array#forEach (<=IE8)\n *\n * @api private\n * @param {Array} arr\n * @param {Function} fn\n * @param {Object} scope\n */\nexports.forEach = function(arr, fn, scope) {\n  for (var i = 0, l = arr.length; i < l; i++) {\n    fn.call(scope, arr[i], i);\n  }\n};\n\n/**\n * Test if the given obj is type of string.\n *\n * @api private\n * @param {Object} obj\n * @return {boolean}\n */\nexports.isString = function(obj) {\n  return typeof obj === 'string';\n};\n\n/**\n * Array#map (<=IE8)\n *\n * @api private\n * @param {Array} arr\n * @param {Function} fn\n * @param {Object} scope\n * @return {Array}\n */\nexports.map = function(arr, fn, scope) {\n  var result = [];\n  for (var i = 0, l = arr.length; i < l; i++) {\n    result.push(fn.call(scope, arr[i], i, arr));\n  }\n  return result;\n};\n\n/**\n * Array#indexOf (<=IE8)\n *\n * @api private\n * @param {Array} arr\n * @param {Object} obj to find index of\n * @param {number} start\n * @return {number}\n */\nvar indexOf = exports.indexOf = function(arr, obj, start) {\n  for (var i = start || 0, l = arr.length; i < l; i++) {\n    if (arr[i] === obj) {\n      return i;\n    }\n  }\n  return -1;\n};\n\n/**\n * Array#reduce (<=IE8)\n *\n * @api private\n * @param {Array} arr\n * @param {Function} fn\n * @param {Object} val Initial value.\n * @return {*}\n */\nvar reduce = exports.reduce = function(arr, fn, val) {\n  var rval = val;\n\n  for (var i = 0, l = arr.length; i < l; i++) {\n    rval = fn(rval, arr[i], i, arr);\n  }\n\n  return rval;\n};\n\n/**\n * Array#filter (<=IE8)\n *\n * @api private\n * @param {Array} arr\n * @param {Function} fn\n * @return {Array}\n */\nexports.filter = function(arr, fn) {\n  var ret = [];\n\n  for (var i = 0, l = arr.length; i < l; i++) {\n    var val = arr[i];\n    if (fn(val, i, arr)) {\n      ret.push(val);\n    }\n  }\n\n  return ret;\n};\n\n/**\n * Array#some (<=IE8)\n *\n * @api private\n * @param {Array} arr\n * @param {Function} fn\n * @return {Array}\n */\nexports.some = function(arr, fn) {\n  for (var i = 0, l = arr.length; i < l; i++) {\n    if (fn(arr[i])) {\n      return true;\n    }\n  }\n  return false;\n};\n\n/**\n * Object.keys (<=IE8)\n *\n * @api private\n * @param {Object} obj\n * @return {Array} keys\n */\nexports.keys = typeof Object.keys === 'function' ? Object.keys : function(obj) {\n  var keys = [];\n  var has = Object.prototype.hasOwnProperty; // for `window` on <=IE8\n\n  for (var key in obj) {\n    if (has.call(obj, key)) {\n      keys.push(key);\n    }\n  }\n\n  return keys;\n};\n\n/**\n * Watch the given `files` for changes\n * and invoke `fn(file)` on modification.\n *\n * @api private\n * @param {Array} files\n * @param {Function} fn\n */\nexports.watch = function(files, fn) {\n  var options = { interval: 100 };\n  files.forEach(function(file) {\n    debug('file %s', file);\n    watchFile(file, options, function(curr, prev) {\n      if (prev.mtime < curr.mtime) {\n        fn(file);\n      }\n    });\n  });\n};\n\n/**\n * Array.isArray (<=IE8)\n *\n * @api private\n * @param {Object} obj\n * @return {Boolean}\n */\nvar isArray = typeof Array.isArray === 'function' ? Array.isArray : function(obj) {\n  return Object.prototype.toString.call(obj) === '[object Array]';\n};\n\nexports.isArray = isArray;\n\n/**\n * Buffer.prototype.toJSON polyfill.\n *\n * @type {Function}\n */\nif (typeof Buffer !== 'undefined' && Buffer.prototype) {\n  Buffer.prototype.toJSON = Buffer.prototype.toJSON || function() {\n    return Array.prototype.slice.call(this, 0);\n  };\n}\n\n/**\n * Ignored files.\n *\n * @api private\n * @param {string} path\n * @return {boolean}\n */\nfunction ignored(path) {\n  return !~ignore.indexOf(path);\n}\n\n/**\n * Lookup files in the given `dir`.\n *\n * @api private\n * @param {string} dir\n * @param {string[]} [ext=['.js']]\n * @param {Array} [ret=[]]\n * @return {Array}\n */\nexports.files = function(dir, ext, ret) {\n  ret = ret || [];\n  ext = ext || ['js'];\n\n  var re = new RegExp('\\\\.(' + ext.join('|') + ')$');\n\n  readdirSync(dir)\n    .filter(ignored)\n    .forEach(function(path) {\n      path = join(dir, path);\n      if (statSync(path).isDirectory()) {\n        exports.files(path, ext, ret);\n      } else if (path.match(re)) {\n        ret.push(path);\n      }\n    });\n\n  return ret;\n};\n\n/**\n * Compute a slug from the given `str`.\n *\n * @api private\n * @param {string} str\n * @return {string}\n */\nexports.slug = function(str) {\n  return str\n    .toLowerCase()\n    .replace(/ +/g, '-')\n    .replace(/[^-\\w]/g, '');\n};\n\n/**\n * Strip the function definition from `str`, and re-indent for pre whitespace.\n *\n * @param {string} str\n * @return {string}\n */\nexports.clean = function(str) {\n  str = str\n    .replace(/\\r\\n?|[\\n\\u2028\\u2029]/g, '\\n').replace(/^\\uFEFF/, '')\n    // (traditional)->  space/name     parameters    body     (lambda)-> parameters       body   multi-statement/single          keep body content\n    .replace(/^function(?:\\s*|\\s+[^(]*)\\([^)]*\\)\\s*\\{((?:.|\\n)*?)\\s*\\}$|^\\([^)]*\\)\\s*=>\\s*(?:\\{((?:.|\\n)*?)\\s*\\}|((?:.|\\n)*))$/, '$1$2$3');\n\n  var spaces = str.match(/^\\n?( *)/)[1].length;\n  var tabs = str.match(/^\\n?(\\t*)/)[1].length;\n  var re = new RegExp('^\\n?' + (tabs ? '\\t' : ' ') + '{' + (tabs ? tabs : spaces) + '}', 'gm');\n\n  str = str.replace(re, '');\n\n  return exports.trim(str);\n};\n\n/**\n * Trim the given `str`.\n *\n * @api private\n * @param {string} str\n * @return {string}\n */\nexports.trim = function(str) {\n  return str.replace(/^\\s+|\\s+$/g, '');\n};\n\n/**\n * Parse the given `qs`.\n *\n * @api private\n * @param {string} qs\n * @return {Object}\n */\nexports.parseQuery = function(qs) {\n  return reduce(qs.replace('?', '').split('&'), function(obj, pair) {\n    var i = pair.indexOf('=');\n    var key = pair.slice(0, i);\n    var val = pair.slice(++i);\n\n    obj[key] = decodeURIComponent(val);\n    return obj;\n  }, {});\n};\n\n/**\n * Highlight the given string of `js`.\n *\n * @api private\n * @param {string} js\n * @return {string}\n */\nfunction highlight(js) {\n  return js\n    .replace(/</g, '&lt;')\n    .replace(/>/g, '&gt;')\n    .replace(/\\/\\/(.*)/gm, '<span class=\"comment\">//$1</span>')\n    .replace(/('.*?')/gm, '<span class=\"string\">$1</span>')\n    .replace(/(\\d+\\.\\d+)/gm, '<span class=\"number\">$1</span>')\n    .replace(/(\\d+)/gm, '<span class=\"number\">$1</span>')\n    .replace(/\\bnew[ \\t]+(\\w+)/gm, '<span class=\"keyword\">new</span> <span class=\"init\">$1</span>')\n    .replace(/\\b(function|new|throw|return|var|if|else)\\b/gm, '<span class=\"keyword\">$1</span>');\n}\n\n/**\n * Highlight the contents of tag `name`.\n *\n * @api private\n * @param {string} name\n */\nexports.highlightTags = function(name) {\n  var code = document.getElementById('mocha').getElementsByTagName(name);\n  for (var i = 0, len = code.length; i < len; ++i) {\n    code[i].innerHTML = highlight(code[i].innerHTML);\n  }\n};\n\n/**\n * If a value could have properties, and has none, this function is called,\n * which returns a string representation of the empty value.\n *\n * Functions w/ no properties return `'[Function]'`\n * Arrays w/ length === 0 return `'[]'`\n * Objects w/ no properties return `'{}'`\n * All else: return result of `value.toString()`\n *\n * @api private\n * @param {*} value The value to inspect.\n * @param {string} typeHint The type of the value\n * @returns {string}\n */\nfunction emptyRepresentation(value, typeHint) {\n  switch (typeHint) {\n    case 'function':\n      return '[Function]';\n    case 'object':\n      return '{}';\n    case 'array':\n      return '[]';\n    default:\n      return value.toString();\n  }\n}\n\n/**\n * Takes some variable and asks `Object.prototype.toString()` what it thinks it\n * is.\n *\n * @api private\n * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/toString\n * @param {*} value The value to test.\n * @returns {string} Computed type\n * @example\n * type({}) // 'object'\n * type([]) // 'array'\n * type(1) // 'number'\n * type(false) // 'boolean'\n * type(Infinity) // 'number'\n * type(null) // 'null'\n * type(new Date()) // 'date'\n * type(/foo/) // 'regexp'\n * type('type') // 'string'\n * type(global) // 'global'\n * type(new String('foo') // 'object'\n */\nvar type = exports.type = function type(value) {\n  if (value === undefined) {\n    return 'undefined';\n  } else if (value === null) {\n    return 'null';\n  } else if (typeof Buffer !== 'undefined' && Buffer.isBuffer(value)) {\n    return 'buffer';\n  }\n  return Object.prototype.toString.call(value)\n    .replace(/^\\[.+\\s(.+?)\\]$/, '$1')\n    .toLowerCase();\n};\n\n/**\n * Stringify `value`. Different behavior depending on type of value:\n *\n * - If `value` is undefined or null, return `'[undefined]'` or `'[null]'`, respectively.\n * - If `value` is not an object, function or array, return result of `value.toString()` wrapped in double-quotes.\n * - If `value` is an *empty* object, function, or array, return result of function\n *   {@link emptyRepresentation}.\n * - If `value` has properties, call {@link exports.canonicalize} on it, then return result of\n *   JSON.stringify().\n *\n * @api private\n * @see exports.type\n * @param {*} value\n * @return {string}\n */\nexports.stringify = function(value) {\n  var typeHint = type(value);\n\n  if (!~indexOf(['object', 'array', 'function'], typeHint)) {\n    if (typeHint === 'buffer') {\n      var json = value.toJSON();\n      // Based on the toJSON result\n      return jsonStringify(json.data && json.type ? json.data : json, 2)\n        .replace(/,(\\n|$)/g, '$1');\n    }\n\n    // IE7/IE8 has a bizarre String constructor; needs to be coerced\n    // into an array and back to obj.\n    if (typeHint === 'string' && typeof value === 'object') {\n      value = reduce(value.split(''), function(acc, char, idx) {\n        acc[idx] = char;\n        return acc;\n      }, {});\n      typeHint = 'object';\n    } else {\n      return jsonStringify(value);\n    }\n  }\n\n  for (var prop in value) {\n    if (Object.prototype.hasOwnProperty.call(value, prop)) {\n      return jsonStringify(exports.canonicalize(value, null, typeHint), 2).replace(/,(\\n|$)/g, '$1');\n    }\n  }\n\n  return emptyRepresentation(value, typeHint);\n};\n\n/**\n * like JSON.stringify but more sense.\n *\n * @api private\n * @param {Object}  object\n * @param {number=} spaces\n * @param {number=} depth\n * @returns {*}\n */\nfunction jsonStringify(object, spaces, depth) {\n  if (typeof spaces === 'undefined') {\n    // primitive types\n    return _stringify(object);\n  }\n\n  depth = depth || 1;\n  var space = spaces * depth;\n  var str = isArray(object) ? '[' : '{';\n  var end = isArray(object) ? ']' : '}';\n  var length = typeof object.length === 'number' ? object.length : exports.keys(object).length;\n  // `.repeat()` polyfill\n  function repeat(s, n) {\n    return new Array(n).join(s);\n  }\n\n  function _stringify(val) {\n    switch (type(val)) {\n      case 'null':\n      case 'undefined':\n        val = '[' + val + ']';\n        break;\n      case 'array':\n      case 'object':\n        val = jsonStringify(val, spaces, depth + 1);\n        break;\n      case 'boolean':\n      case 'regexp':\n      case 'symbol':\n      case 'number':\n        val = val === 0 && (1 / val) === -Infinity // `-0`\n          ? '-0'\n          : val.toString();\n        break;\n      case 'date':\n        var sDate;\n        if (isNaN(val.getTime())) { // Invalid date\n          sDate = val.toString();\n        } else {\n          sDate = val.toISOString ? val.toISOString() : toISOString(val);\n        }\n        val = '[Date: ' + sDate + ']';\n        break;\n      case 'buffer':\n        var json = val.toJSON();\n        // Based on the toJSON result\n        json = json.data && json.type ? json.data : json;\n        val = '[Buffer: ' + jsonStringify(json, 2, depth + 1) + ']';\n        break;\n      default:\n        val = (val === '[Function]' || val === '[Circular]')\n          ? val\n          : JSON.stringify(val); // string\n    }\n    return val;\n  }\n\n  for (var i in object) {\n    if (!Object.prototype.hasOwnProperty.call(object, i)) {\n      continue; // not my business\n    }\n    --length;\n    str += '\\n ' + repeat(' ', space)\n      + (isArray(object) ? '' : '\"' + i + '\": ') // key\n      + _stringify(object[i])                     // value\n      + (length ? ',' : '');                     // comma\n  }\n\n  return str\n    // [], {}\n    + (str.length !== 1 ? '\\n' + repeat(' ', --space) + end : end);\n}\n\n/**\n * Test if a value is a buffer.\n *\n * @api private\n * @param {*} value The value to test.\n * @return {boolean} True if `value` is a buffer, otherwise false\n */\nexports.isBuffer = function(value) {\n  return typeof Buffer !== 'undefined' && Buffer.isBuffer(value);\n};\n\n/**\n * Return a new Thing that has the keys in sorted order. Recursive.\n *\n * If the Thing...\n * - has already been seen, return string `'[Circular]'`\n * - is `undefined`, return string `'[undefined]'`\n * - is `null`, return value `null`\n * - is some other primitive, return the value\n * - is not a primitive or an `Array`, `Object`, or `Function`, return the value of the Thing's `toString()` method\n * - is a non-empty `Array`, `Object`, or `Function`, return the result of calling this function again.\n * - is an empty `Array`, `Object`, or `Function`, return the result of calling `emptyRepresentation()`\n *\n * @api private\n * @see {@link exports.stringify}\n * @param {*} value Thing to inspect.  May or may not have properties.\n * @param {Array} [stack=[]] Stack of seen values\n * @param {string} [typeHint] Type hint\n * @return {(Object|Array|Function|string|undefined)}\n */\nexports.canonicalize = function canonicalize(value, stack, typeHint) {\n  var canonicalizedObj;\n  /* eslint-disable no-unused-vars */\n  var prop;\n  /* eslint-enable no-unused-vars */\n  typeHint = typeHint || type(value);\n  function withStack(value, fn) {\n    stack.push(value);\n    fn();\n    stack.pop();\n  }\n\n  stack = stack || [];\n\n  if (indexOf(stack, value) !== -1) {\n    return '[Circular]';\n  }\n\n  switch (typeHint) {\n    case 'undefined':\n    case 'buffer':\n    case 'null':\n      canonicalizedObj = value;\n      break;\n    case 'array':\n      withStack(value, function() {\n        canonicalizedObj = exports.map(value, function(item) {\n          return exports.canonicalize(item, stack);\n        });\n      });\n      break;\n    case 'function':\n      /* eslint-disable guard-for-in */\n      for (prop in value) {\n        canonicalizedObj = {};\n        break;\n      }\n      /* eslint-enable guard-for-in */\n      if (!canonicalizedObj) {\n        canonicalizedObj = emptyRepresentation(value, typeHint);\n        break;\n      }\n    /* falls through */\n    case 'object':\n      canonicalizedObj = canonicalizedObj || {};\n      withStack(value, function() {\n        exports.forEach(exports.keys(value).sort(), function(key) {\n          canonicalizedObj[key] = exports.canonicalize(value[key], stack);\n        });\n      });\n      break;\n    case 'date':\n    case 'number':\n    case 'regexp':\n    case 'boolean':\n    case 'symbol':\n      canonicalizedObj = value;\n      break;\n    default:\n      canonicalizedObj = value + '';\n  }\n\n  return canonicalizedObj;\n};\n\n/**\n * Lookup file names at the given `path`.\n *\n * @api public\n * @param {string} path Base path to start searching from.\n * @param {string[]} extensions File extensions to look for.\n * @param {boolean} recursive Whether or not to recurse into subdirectories.\n * @return {string[]} An array of paths.\n */\nexports.lookupFiles = function lookupFiles(path, extensions, recursive) {\n  var files = [];\n  var re = new RegExp('\\\\.(' + extensions.join('|') + ')$');\n\n  if (!exists(path)) {\n    if (exists(path + '.js')) {\n      path += '.js';\n    } else {\n      files = glob.sync(path);\n      if (!files.length) {\n        throw new Error(\"cannot resolve path (or pattern) '\" + path + \"'\");\n      }\n      return files;\n    }\n  }\n\n  try {\n    var stat = statSync(path);\n    if (stat.isFile()) {\n      return path;\n    }\n  } catch (err) {\n    // ignore error\n    return;\n  }\n\n  readdirSync(path).forEach(function(file) {\n    file = join(path, file);\n    try {\n      var stat = statSync(file);\n      if (stat.isDirectory()) {\n        if (recursive) {\n          files = files.concat(lookupFiles(file, extensions, recursive));\n        }\n        return;\n      }\n    } catch (err) {\n      // ignore error\n      return;\n    }\n    if (!stat.isFile() || !re.test(file) || basename(file)[0] === '.') {\n      return;\n    }\n    files.push(file);\n  });\n\n  return files;\n};\n\n/**\n * Generate an undefined error with a message warning the user.\n *\n * @return {Error}\n */\n\nexports.undefinedError = function() {\n  return new Error('Caught undefined error, did you throw without specifying what?');\n};\n\n/**\n * Generate an undefined error if `err` is not defined.\n *\n * @param {Error} err\n * @return {Error}\n */\n\nexports.getError = function(err) {\n  return err || exports.undefinedError();\n};\n\n/**\n * @summary\n * This Filter based on `mocha-clean` module.(see: `github.com/rstacruz/mocha-clean`)\n * @description\n * When invoking this function you get a filter function that get the Error.stack as an input,\n * and return a prettify output.\n * (i.e: strip Mocha and internal node functions from stack trace).\n * @returns {Function}\n */\nexports.stackTraceFilter = function() {\n  // TODO: Replace with `process.browser`\n  var is = typeof document === 'undefined' ? { node: true } : { browser: true };\n  var slash = path.sep;\n  var cwd;\n  if (is.node) {\n    cwd = process.cwd() + slash;\n  } else {\n    cwd = (typeof location === 'undefined' ? window.location : location).href.replace(/\\/[^\\/]*$/, '/');\n    slash = '/';\n  }\n\n  function isMochaInternal(line) {\n    return (~line.indexOf('node_modules' + slash + 'mocha' + slash))\n      || (~line.indexOf('node_modules' + slash + 'mocha.js'))\n      || (~line.indexOf('bower_components' + slash + 'mocha.js'))\n      || (~line.indexOf(slash + 'mocha.js'));\n  }\n\n  function isNodeInternal(line) {\n    return (~line.indexOf('(timers.js:'))\n      || (~line.indexOf('(events.js:'))\n      || (~line.indexOf('(node.js:'))\n      || (~line.indexOf('(module.js:'))\n      || (~line.indexOf('GeneratorFunctionPrototype.next (native)'))\n      || false;\n  }\n\n  return function(stack) {\n    stack = stack.split('\\n');\n\n    stack = reduce(stack, function(list, line) {\n      if (isMochaInternal(line)) {\n        return list;\n      }\n\n      if (is.node && isNodeInternal(line)) {\n        return list;\n      }\n\n      // Clean up cwd(absolute)\n      if (/\\(?.+:\\d+:\\d+\\)?$/.test(line)) {\n        line = line.replace(cwd, '');\n      }\n\n      list.push(line);\n      return list;\n    }, []);\n\n    return stack.join('\\n');\n  };\n};\n\n/**\n * Crude, but effective.\n * @api\n * @param {*} value\n * @returns {boolean} Whether or not `value` is a Promise\n */\nexports.isPromise = function isPromise(value) {\n  return typeof value === 'object' && typeof value.then === 'function';\n};\n\n}).call(this,require('_process'),require(\"buffer\").Buffer)\n},{\"./to-iso-string\":37,\"_process\":67,\"buffer\":44,\"debug\":2,\"fs\":42,\"glob\":42,\"json3\":54,\"path\":42,\"util\":84}],39:[function(require,module,exports){\n'use strict'\n\nexports.toByteArray = toByteArray\nexports.fromByteArray = fromByteArray\n\nvar lookup = []\nvar revLookup = []\nvar Arr = typeof Uint8Array !== 'undefined' ? Uint8Array : Array\n\nfunction init () {\n  var code = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'\n  for (var i = 0, len = code.length; i < len; ++i) {\n    lookup[i] = code[i]\n    revLookup[code.charCodeAt(i)] = i\n  }\n\n  revLookup['-'.charCodeAt(0)] = 62\n  revLookup['_'.charCodeAt(0)] = 63\n}\n\ninit()\n\nfunction toByteArray (b64) {\n  var i, j, l, tmp, placeHolders, arr\n  var len = b64.length\n\n  if (len % 4 > 0) {\n    throw new Error('Invalid string. Length must be a multiple of 4')\n  }\n\n  // the number of equal signs (place holders)\n  // if there are two placeholders, than the two characters before it\n  // represent one byte\n  // if there is only one, then the three characters before it represent 2 bytes\n  // this is just a cheap hack to not do indexOf twice\n  placeHolders = b64[len - 2] === '=' ? 2 : b64[len - 1] === '=' ? 1 : 0\n\n  // base64 is 4/3 + up to two characters of the original data\n  arr = new Arr(len * 3 / 4 - placeHolders)\n\n  // if there are placeholders, only get up to the last complete 4 chars\n  l = placeHolders > 0 ? len - 4 : len\n\n  var L = 0\n\n  for (i = 0, j = 0; i < l; i += 4, j += 3) {\n    tmp = (revLookup[b64.charCodeAt(i)] << 18) | (revLookup[b64.charCodeAt(i + 1)] << 12) | (revLookup[b64.charCodeAt(i + 2)] << 6) | revLookup[b64.charCodeAt(i + 3)]\n    arr[L++] = (tmp >> 16) & 0xFF\n    arr[L++] = (tmp >> 8) & 0xFF\n    arr[L++] = tmp & 0xFF\n  }\n\n  if (placeHolders === 2) {\n    tmp = (revLookup[b64.charCodeAt(i)] << 2) | (revLookup[b64.charCodeAt(i + 1)] >> 4)\n    arr[L++] = tmp & 0xFF\n  } else if (placeHolders === 1) {\n    tmp = (revLookup[b64.charCodeAt(i)] << 10) | (revLookup[b64.charCodeAt(i + 1)] << 4) | (revLookup[b64.charCodeAt(i + 2)] >> 2)\n    arr[L++] = (tmp >> 8) & 0xFF\n    arr[L++] = tmp & 0xFF\n  }\n\n  return arr\n}\n\nfunction tripletToBase64 (num) {\n  return lookup[num >> 18 & 0x3F] + lookup[num >> 12 & 0x3F] + lookup[num >> 6 & 0x3F] + lookup[num & 0x3F]\n}\n\nfunction encodeChunk (uint8, start, end) {\n  var tmp\n  var output = []\n  for (var i = start; i < end; i += 3) {\n    tmp = (uint8[i] << 16) + (uint8[i + 1] << 8) + (uint8[i + 2])\n    output.push(tripletToBase64(tmp))\n  }\n  return output.join('')\n}\n\nfunction fromByteArray (uint8) {\n  var tmp\n  var len = uint8.length\n  var extraBytes = len % 3 // if we have 1 byte left, pad 2 bytes\n  var output = ''\n  var parts = []\n  var maxChunkLength = 16383 // must be multiple of 3\n\n  // go through the array every three bytes, we'll deal with trailing stuff later\n  for (var i = 0, len2 = len - extraBytes; i < len2; i += maxChunkLength) {\n    parts.push(encodeChunk(uint8, i, (i + maxChunkLength) > len2 ? len2 : (i + maxChunkLength)))\n  }\n\n  // pad the end with zeros, but make sure to not forget the extra bytes\n  if (extraBytes === 1) {\n    tmp = uint8[len - 1]\n    output += lookup[tmp >> 2]\n    output += lookup[(tmp << 4) & 0x3F]\n    output += '=='\n  } else if (extraBytes === 2) {\n    tmp = (uint8[len - 2] << 8) + (uint8[len - 1])\n    output += lookup[tmp >> 10]\n    output += lookup[(tmp >> 4) & 0x3F]\n    output += lookup[(tmp << 2) & 0x3F]\n    output += '='\n  }\n\n  parts.push(output)\n\n  return parts.join('')\n}\n\n},{}],40:[function(require,module,exports){\n\n},{}],41:[function(require,module,exports){\n(function (process){\nvar WritableStream = require('stream').Writable\nvar inherits = require('util').inherits\n\nmodule.exports = BrowserStdout\n\n\ninherits(BrowserStdout, WritableStream)\n\nfunction BrowserStdout(opts) {\n  if (!(this instanceof BrowserStdout)) return new BrowserStdout(opts)\n\n  opts = opts || {}\n  WritableStream.call(this, opts)\n  this.label = (opts.label !== undefined) ? opts.label : 'stdout'\n}\n\nBrowserStdout.prototype._write = function(chunks, encoding, cb) {\n  var output = chunks.toString ? chunks.toString() : chunks\n  if (this.label === false) {\n    console.log(output)\n  } else {\n    console.log(this.label+':', output)\n  }\n  process.nextTick(cb)\n}\n\n}).call(this,require('_process'))\n},{\"_process\":67,\"stream\":79,\"util\":84}],42:[function(require,module,exports){\narguments[4][40][0].apply(exports,arguments)\n},{\"dup\":40}],43:[function(require,module,exports){\n(function (global){\n'use strict';\n\nvar buffer = require('buffer');\nvar Buffer = buffer.Buffer;\nvar SlowBuffer = buffer.SlowBuffer;\nvar MAX_LEN = buffer.kMaxLength || 2147483647;\nexports.alloc = function alloc(size, fill, encoding) {\n  if (typeof Buffer.alloc === 'function') {\n    return Buffer.alloc(size, fill, encoding);\n  }\n  if (typeof encoding === 'number') {\n    throw new TypeError('encoding must not be number');\n  }\n  if (typeof size !== 'number') {\n    throw new TypeError('size must be a number');\n  }\n  if (size > MAX_LEN) {\n    throw new RangeError('size is too large');\n  }\n  var enc = encoding;\n  var _fill = fill;\n  if (_fill === undefined) {\n    enc = undefined;\n    _fill = 0;\n  }\n  var buf = new Buffer(size);\n  if (typeof _fill === 'string') {\n    var fillBuf = new Buffer(_fill, enc);\n    var flen = fillBuf.length;\n    var i = -1;\n    while (++i < size) {\n      buf[i] = fillBuf[i % flen];\n    }\n  } else {\n    buf.fill(_fill);\n  }\n  return buf;\n}\nexports.allocUnsafe = function allocUnsafe(size) {\n  if (typeof Buffer.allocUnsafe === 'function') {\n    return Buffer.allocUnsafe(size);\n  }\n  if (typeof size !== 'number') {\n    throw new TypeError('size must be a number');\n  }\n  if (size > MAX_LEN) {\n    throw new RangeError('size is too large');\n  }\n  return new Buffer(size);\n}\nexports.from = function from(value, encodingOrOffset, length) {\n  if (typeof Buffer.from === 'function' && (!global.Uint8Array || Uint8Array.from !== Buffer.from)) {\n    return Buffer.from(value, encodingOrOffset, length);\n  }\n  if (typeof value === 'number') {\n    throw new TypeError('\"value\" argument must not be a number');\n  }\n  if (typeof value === 'string') {\n    return new Buffer(value, encodingOrOffset);\n  }\n  if (typeof ArrayBuffer !== 'undefined' && value instanceof ArrayBuffer) {\n    var offset = encodingOrOffset;\n    if (arguments.length === 1) {\n      return new Buffer(value);\n    }\n    if (typeof offset === 'undefined') {\n      offset = 0;\n    }\n    var len = length;\n    if (typeof len === 'undefined') {\n      len = value.byteLength - offset;\n    }\n    if (offset >= value.byteLength) {\n      throw new RangeError('\\'offset\\' is out of bounds');\n    }\n    if (len > value.byteLength - offset) {\n      throw new RangeError('\\'length\\' is out of bounds');\n    }\n    return new Buffer(value.slice(offset, offset + len));\n  }\n  if (Buffer.isBuffer(value)) {\n    var out = new Buffer(value.length);\n    value.copy(out, 0, 0, value.length);\n    return out;\n  }\n  if (value) {\n    if (Array.isArray(value) || (typeof ArrayBuffer !== 'undefined' && value.buffer instanceof ArrayBuffer) || 'length' in value) {\n      return new Buffer(value);\n    }\n    if (value.type === 'Buffer' && Array.isArray(value.data)) {\n      return new Buffer(value.data);\n    }\n  }\n\n  throw new TypeError('First argument must be a string, Buffer, ' + 'ArrayBuffer, Array, or array-like object.');\n}\nexports.allocUnsafeSlow = function allocUnsafeSlow(size) {\n  if (typeof Buffer.allocUnsafeSlow === 'function') {\n    return Buffer.allocUnsafeSlow(size);\n  }\n  if (typeof size !== 'number') {\n    throw new TypeError('size must be a number');\n  }\n  if (size >= MAX_LEN) {\n    throw new RangeError('size is too large');\n  }\n  return new SlowBuffer(size);\n}\n\n}).call(this,typeof global !== \"undefined\" ? global : typeof self !== \"undefined\" ? self : typeof window !== \"undefined\" ? window : {})\n},{\"buffer\":44}],44:[function(require,module,exports){\n(function (global){\n/*!\n * The buffer module from node.js, for the browser.\n *\n * @author   Feross Aboukhadijeh <feross@feross.org> <http://feross.org>\n * @license  MIT\n */\n/* eslint-disable no-proto */\n\n'use strict'\n\nvar base64 = require('base64-js')\nvar ieee754 = require('ieee754')\nvar isArray = require('isarray')\n\nexports.Buffer = Buffer\nexports.SlowBuffer = SlowBuffer\nexports.INSPECT_MAX_BYTES = 50\n\n/**\n * If `Buffer.TYPED_ARRAY_SUPPORT`:\n *   === true    Use Uint8Array implementation (fastest)\n *   === false   Use Object implementation (most compatible, even IE6)\n *\n * Browsers that support typed arrays are IE 10+, Firefox 4+, Chrome 7+, Safari 5.1+,\n * Opera 11.6+, iOS 4.2+.\n *\n * Due to various browser bugs, sometimes the Object implementation will be used even\n * when the browser supports typed arrays.\n *\n * Note:\n *\n *   - Firefox 4-29 lacks support for adding new properties to `Uint8Array` instances,\n *     See: https://bugzilla.mozilla.org/show_bug.cgi?id=695438.\n *\n *   - Chrome 9-10 is missing the `TypedArray.prototype.subarray` function.\n *\n *   - IE10 has a broken `TypedArray.prototype.subarray` function which returns arrays of\n *     incorrect length in some situations.\n\n * We detect these buggy browsers and set `Buffer.TYPED_ARRAY_SUPPORT` to `false` so they\n * get the Object implementation, which is slower but behaves correctly.\n */\nBuffer.TYPED_ARRAY_SUPPORT = global.TYPED_ARRAY_SUPPORT !== undefined\n  ? global.TYPED_ARRAY_SUPPORT\n  : typedArraySupport()\n\n/*\n * Export kMaxLength after typed array support is determined.\n */\nexports.kMaxLength = kMaxLength()\n\nfunction typedArraySupport () {\n  try {\n    var arr = new Uint8Array(1)\n    arr.__proto__ = {__proto__: Uint8Array.prototype, foo: function () { return 42 }}\n    return arr.foo() === 42 && // typed array instances can be augmented\n        typeof arr.subarray === 'function' && // chrome 9-10 lack `subarray`\n        arr.subarray(1, 1).byteLength === 0 // ie10 has broken `subarray`\n  } catch (e) {\n    return false\n  }\n}\n\nfunction kMaxLength () {\n  return Buffer.TYPED_ARRAY_SUPPORT\n    ? 0x7fffffff\n    : 0x3fffffff\n}\n\nfunction createBuffer (that, length) {\n  if (kMaxLength() < length) {\n    throw new RangeError('Invalid typed array length')\n  }\n  if (Buffer.TYPED_ARRAY_SUPPORT) {\n    // Return an augmented `Uint8Array` instance, for best performance\n    that = new Uint8Array(length)\n    that.__proto__ = Buffer.prototype\n  } else {\n    // Fallback: Return an object instance of the Buffer class\n    if (that === null) {\n      that = new Buffer(length)\n    }\n    that.length = length\n  }\n\n  return that\n}\n\n/**\n * The Buffer constructor returns instances of `Uint8Array` that have their\n * prototype changed to `Buffer.prototype`. Furthermore, `Buffer` is a subclass of\n * `Uint8Array`, so the returned instances will have all the node `Buffer` methods\n * and the `Uint8Array` methods. Square bracket notation works as expected -- it\n * returns a single octet.\n *\n * The `Uint8Array` prototype remains unmodified.\n */\n\nfunction Buffer (arg, encodingOrOffset, length) {\n  if (!Buffer.TYPED_ARRAY_SUPPORT && !(this instanceof Buffer)) {\n    return new Buffer(arg, encodingOrOffset, length)\n  }\n\n  // Common case.\n  if (typeof arg === 'number') {\n    if (typeof encodingOrOffset === 'string') {\n      throw new Error(\n        'If encoding is specified then the first argument must be a string'\n      )\n    }\n    return allocUnsafe(this, arg)\n  }\n  return from(this, arg, encodingOrOffset, length)\n}\n\nBuffer.poolSize = 8192 // not used by this implementation\n\n// TODO: Legacy, not needed anymore. Remove in next major version.\nBuffer._augment = function (arr) {\n  arr.__proto__ = Buffer.prototype\n  return arr\n}\n\nfunction from (that, value, encodingOrOffset, length) {\n  if (typeof value === 'number') {\n    throw new TypeError('\"value\" argument must not be a number')\n  }\n\n  if (typeof ArrayBuffer !== 'undefined' && value instanceof ArrayBuffer) {\n    return fromArrayBuffer(that, value, encodingOrOffset, length)\n  }\n\n  if (typeof value === 'string') {\n    return fromString(that, value, encodingOrOffset)\n  }\n\n  return fromObject(that, value)\n}\n\n/**\n * Functionally equivalent to Buffer(arg, encoding) but throws a TypeError\n * if value is a number.\n * Buffer.from(str[, encoding])\n * Buffer.from(array)\n * Buffer.from(buffer)\n * Buffer.from(arrayBuffer[, byteOffset[, length]])\n **/\nBuffer.from = function (value, encodingOrOffset, length) {\n  return from(null, value, encodingOrOffset, length)\n}\n\nif (Buffer.TYPED_ARRAY_SUPPORT) {\n  Buffer.prototype.__proto__ = Uint8Array.prototype\n  Buffer.__proto__ = Uint8Array\n  if (typeof Symbol !== 'undefined' && Symbol.species &&\n      Buffer[Symbol.species] === Buffer) {\n    // Fix subarray() in ES2016. See: https://github.com/feross/buffer/pull/97\n    Object.defineProperty(Buffer, Symbol.species, {\n      value: null,\n      configurable: true\n    })\n  }\n}\n\nfunction assertSize (size) {\n  if (typeof size !== 'number') {\n    throw new TypeError('\"size\" argument must be a number')\n  } else if (size < 0) {\n    throw new RangeError('\"size\" argument must not be negative')\n  }\n}\n\nfunction alloc (that, size, fill, encoding) {\n  assertSize(size)\n  if (size <= 0) {\n    return createBuffer(that, size)\n  }\n  if (fill !== undefined) {\n    // Only pay attention to encoding if it's a string. This\n    // prevents accidentally sending in a number that would\n    // be interpretted as a start offset.\n    return typeof encoding === 'string'\n      ? createBuffer(that, size).fill(fill, encoding)\n      : createBuffer(that, size).fill(fill)\n  }\n  return createBuffer(that, size)\n}\n\n/**\n * Creates a new filled Buffer instance.\n * alloc(size[, fill[, encoding]])\n **/\nBuffer.alloc = function (size, fill, encoding) {\n  return alloc(null, size, fill, encoding)\n}\n\nfunction allocUnsafe (that, size) {\n  assertSize(size)\n  that = createBuffer(that, size < 0 ? 0 : checked(size) | 0)\n  if (!Buffer.TYPED_ARRAY_SUPPORT) {\n    for (var i = 0; i < size; ++i) {\n      that[i] = 0\n    }\n  }\n  return that\n}\n\n/**\n * Equivalent to Buffer(num), by default creates a non-zero-filled Buffer instance.\n * */\nBuffer.allocUnsafe = function (size) {\n  return allocUnsafe(null, size)\n}\n/**\n * Equivalent to SlowBuffer(num), by default creates a non-zero-filled Buffer instance.\n */\nBuffer.allocUnsafeSlow = function (size) {\n  return allocUnsafe(null, size)\n}\n\nfunction fromString (that, string, encoding) {\n  if (typeof encoding !== 'string' || encoding === '') {\n    encoding = 'utf8'\n  }\n\n  if (!Buffer.isEncoding(encoding)) {\n    throw new TypeError('\"encoding\" must be a valid string encoding')\n  }\n\n  var length = byteLength(string, encoding) | 0\n  that = createBuffer(that, length)\n\n  var actual = that.write(string, encoding)\n\n  if (actual !== length) {\n    // Writing a hex string, for example, that contains invalid characters will\n    // cause everything after the first invalid character to be ignored. (e.g.\n    // 'abxxcd' will be treated as 'ab')\n    that = that.slice(0, actual)\n  }\n\n  return that\n}\n\nfunction fromArrayLike (that, array) {\n  var length = array.length < 0 ? 0 : checked(array.length) | 0\n  that = createBuffer(that, length)\n  for (var i = 0; i < length; i += 1) {\n    that[i] = array[i] & 255\n  }\n  return that\n}\n\nfunction fromArrayBuffer (that, array, byteOffset, length) {\n  array.byteLength // this throws if `array` is not a valid ArrayBuffer\n\n  if (byteOffset < 0 || array.byteLength < byteOffset) {\n    throw new RangeError('\\'offset\\' is out of bounds')\n  }\n\n  if (array.byteLength < byteOffset + (length || 0)) {\n    throw new RangeError('\\'length\\' is out of bounds')\n  }\n\n  if (byteOffset === undefined && length === undefined) {\n    array = new Uint8Array(array)\n  } else if (length === undefined) {\n    array = new Uint8Array(array, byteOffset)\n  } else {\n    array = new Uint8Array(array, byteOffset, length)\n  }\n\n  if (Buffer.TYPED_ARRAY_SUPPORT) {\n    // Return an augmented `Uint8Array` instance, for best performance\n    that = array\n    that.__proto__ = Buffer.prototype\n  } else {\n    // Fallback: Return an object instance of the Buffer class\n    that = fromArrayLike(that, array)\n  }\n  return that\n}\n\nfunction fromObject (that, obj) {\n  if (Buffer.isBuffer(obj)) {\n    var len = checked(obj.length) | 0\n    that = createBuffer(that, len)\n\n    if (that.length === 0) {\n      return that\n    }\n\n    obj.copy(that, 0, 0, len)\n    return that\n  }\n\n  if (obj) {\n    if ((typeof ArrayBuffer !== 'undefined' &&\n        obj.buffer instanceof ArrayBuffer) || 'length' in obj) {\n      if (typeof obj.length !== 'number' || isnan(obj.length)) {\n        return createBuffer(that, 0)\n      }\n      return fromArrayLike(that, obj)\n    }\n\n    if (obj.type === 'Buffer' && isArray(obj.data)) {\n      return fromArrayLike(that, obj.data)\n    }\n  }\n\n  throw new TypeError('First argument must be a string, Buffer, ArrayBuffer, Array, or array-like object.')\n}\n\nfunction checked (length) {\n  // Note: cannot use `length < kMaxLength()` here because that fails when\n  // length is NaN (which is otherwise coerced to zero.)\n  if (length >= kMaxLength()) {\n    throw new RangeError('Attempt to allocate Buffer larger than maximum ' +\n                         'size: 0x' + kMaxLength().toString(16) + ' bytes')\n  }\n  return length | 0\n}\n\nfunction SlowBuffer (length) {\n  if (+length != length) { // eslint-disable-line eqeqeq\n    length = 0\n  }\n  return Buffer.alloc(+length)\n}\n\nBuffer.isBuffer = function isBuffer (b) {\n  return !!(b != null && b._isBuffer)\n}\n\nBuffer.compare = function compare (a, b) {\n  if (!Buffer.isBuffer(a) || !Buffer.isBuffer(b)) {\n    throw new TypeError('Arguments must be Buffers')\n  }\n\n  if (a === b) return 0\n\n  var x = a.length\n  var y = b.length\n\n  for (var i = 0, len = Math.min(x, y); i < len; ++i) {\n    if (a[i] !== b[i]) {\n      x = a[i]\n      y = b[i]\n      break\n    }\n  }\n\n  if (x < y) return -1\n  if (y < x) return 1\n  return 0\n}\n\nBuffer.isEncoding = function isEncoding (encoding) {\n  switch (String(encoding).toLowerCase()) {\n    case 'hex':\n    case 'utf8':\n    case 'utf-8':\n    case 'ascii':\n    case 'latin1':\n    case 'binary':\n    case 'base64':\n    case 'ucs2':\n    case 'ucs-2':\n    case 'utf16le':\n    case 'utf-16le':\n      return true\n    default:\n      return false\n  }\n}\n\nBuffer.concat = function concat (list, length) {\n  if (!isArray(list)) {\n    throw new TypeError('\"list\" argument must be an Array of Buffers')\n  }\n\n  if (list.length === 0) {\n    return Buffer.alloc(0)\n  }\n\n  var i\n  if (length === undefined) {\n    length = 0\n    for (i = 0; i < list.length; ++i) {\n      length += list[i].length\n    }\n  }\n\n  var buffer = Buffer.allocUnsafe(length)\n  var pos = 0\n  for (i = 0; i < list.length; ++i) {\n    var buf = list[i]\n    if (!Buffer.isBuffer(buf)) {\n      throw new TypeError('\"list\" argument must be an Array of Buffers')\n    }\n    buf.copy(buffer, pos)\n    pos += buf.length\n  }\n  return buffer\n}\n\nfunction byteLength (string, encoding) {\n  if (Buffer.isBuffer(string)) {\n    return string.length\n  }\n  if (typeof ArrayBuffer !== 'undefined' && typeof ArrayBuffer.isView === 'function' &&\n      (ArrayBuffer.isView(string) || string instanceof ArrayBuffer)) {\n    return string.byteLength\n  }\n  if (typeof string !== 'string') {\n    string = '' + string\n  }\n\n  var len = string.length\n  if (len === 0) return 0\n\n  // Use a for loop to avoid recursion\n  var loweredCase = false\n  for (;;) {\n    switch (encoding) {\n      case 'ascii':\n      case 'latin1':\n      case 'binary':\n        return len\n      case 'utf8':\n      case 'utf-8':\n      case undefined:\n        return utf8ToBytes(string).length\n      case 'ucs2':\n      case 'ucs-2':\n      case 'utf16le':\n      case 'utf-16le':\n        return len * 2\n      case 'hex':\n        return len >>> 1\n      case 'base64':\n        return base64ToBytes(string).length\n      default:\n        if (loweredCase) return utf8ToBytes(string).length // assume utf8\n        encoding = ('' + encoding).toLowerCase()\n        loweredCase = true\n    }\n  }\n}\nBuffer.byteLength = byteLength\n\nfunction slowToString (encoding, start, end) {\n  var loweredCase = false\n\n  // No need to verify that \"this.length <= MAX_UINT32\" since it's a read-only\n  // property of a typed array.\n\n  // This behaves neither like String nor Uint8Array in that we set start/end\n  // to their upper/lower bounds if the value passed is out of range.\n  // undefined is handled specially as per ECMA-262 6th Edition,\n  // Section 13.3.3.7 Runtime Semantics: KeyedBindingInitialization.\n  if (start === undefined || start < 0) {\n    start = 0\n  }\n  // Return early if start > this.length. Done here to prevent potential uint32\n  // coercion fail below.\n  if (start > this.length) {\n    return ''\n  }\n\n  if (end === undefined || end > this.length) {\n    end = this.length\n  }\n\n  if (end <= 0) {\n    return ''\n  }\n\n  // Force coersion to uint32. This will also coerce falsey/NaN values to 0.\n  end >>>= 0\n  start >>>= 0\n\n  if (end <= start) {\n    return ''\n  }\n\n  if (!encoding) encoding = 'utf8'\n\n  while (true) {\n    switch (encoding) {\n      case 'hex':\n        return hexSlice(this, start, end)\n\n      case 'utf8':\n      case 'utf-8':\n        return utf8Slice(this, start, end)\n\n      case 'ascii':\n        return asciiSlice(this, start, end)\n\n      case 'latin1':\n      case 'binary':\n        return latin1Slice(this, start, end)\n\n      case 'base64':\n        return base64Slice(this, start, end)\n\n      case 'ucs2':\n      case 'ucs-2':\n      case 'utf16le':\n      case 'utf-16le':\n        return utf16leSlice(this, start, end)\n\n      default:\n        if (loweredCase) throw new TypeError('Unknown encoding: ' + encoding)\n        encoding = (encoding + '').toLowerCase()\n        loweredCase = true\n    }\n  }\n}\n\n// The property is used by `Buffer.isBuffer` and `is-buffer` (in Safari 5-7) to detect\n// Buffer instances.\nBuffer.prototype._isBuffer = true\n\nfunction swap (b, n, m) {\n  var i = b[n]\n  b[n] = b[m]\n  b[m] = i\n}\n\nBuffer.prototype.swap16 = function swap16 () {\n  var len = this.length\n  if (len % 2 !== 0) {\n    throw new RangeError('Buffer size must be a multiple of 16-bits')\n  }\n  for (var i = 0; i < len; i += 2) {\n    swap(this, i, i + 1)\n  }\n  return this\n}\n\nBuffer.prototype.swap32 = function swap32 () {\n  var len = this.length\n  if (len % 4 !== 0) {\n    throw new RangeError('Buffer size must be a multiple of 32-bits')\n  }\n  for (var i = 0; i < len; i += 4) {\n    swap(this, i, i + 3)\n    swap(this, i + 1, i + 2)\n  }\n  return this\n}\n\nBuffer.prototype.swap64 = function swap64 () {\n  var len = this.length\n  if (len % 8 !== 0) {\n    throw new RangeError('Buffer size must be a multiple of 64-bits')\n  }\n  for (var i = 0; i < len; i += 8) {\n    swap(this, i, i + 7)\n    swap(this, i + 1, i + 6)\n    swap(this, i + 2, i + 5)\n    swap(this, i + 3, i + 4)\n  }\n  return this\n}\n\nBuffer.prototype.toString = function toString () {\n  var length = this.length | 0\n  if (length === 0) return ''\n  if (arguments.length === 0) return utf8Slice(this, 0, length)\n  return slowToString.apply(this, arguments)\n}\n\nBuffer.prototype.equals = function equals (b) {\n  if (!Buffer.isBuffer(b)) throw new TypeError('Argument must be a Buffer')\n  if (this === b) return true\n  return Buffer.compare(this, b) === 0\n}\n\nBuffer.prototype.inspect = function inspect () {\n  var str = ''\n  var max = exports.INSPECT_MAX_BYTES\n  if (this.length > 0) {\n    str = this.toString('hex', 0, max).match(/.{2}/g).join(' ')\n    if (this.length > max) str += ' ... '\n  }\n  return '<Buffer ' + str + '>'\n}\n\nBuffer.prototype.compare = function compare (target, start, end, thisStart, thisEnd) {\n  if (!Buffer.isBuffer(target)) {\n    throw new TypeError('Argument must be a Buffer')\n  }\n\n  if (start === undefined) {\n    start = 0\n  }\n  if (end === undefined) {\n    end = target ? target.length : 0\n  }\n  if (thisStart === undefined) {\n    thisStart = 0\n  }\n  if (thisEnd === undefined) {\n    thisEnd = this.length\n  }\n\n  if (start < 0 || end > target.length || thisStart < 0 || thisEnd > this.length) {\n    throw new RangeError('out of range index')\n  }\n\n  if (thisStart >= thisEnd && start >= end) {\n    return 0\n  }\n  if (thisStart >= thisEnd) {\n    return -1\n  }\n  if (start >= end) {\n    return 1\n  }\n\n  start >>>= 0\n  end >>>= 0\n  thisStart >>>= 0\n  thisEnd >>>= 0\n\n  if (this === target) return 0\n\n  var x = thisEnd - thisStart\n  var y = end - start\n  var len = Math.min(x, y)\n\n  var thisCopy = this.slice(thisStart, thisEnd)\n  var targetCopy = target.slice(start, end)\n\n  for (var i = 0; i < len; ++i) {\n    if (thisCopy[i] !== targetCopy[i]) {\n      x = thisCopy[i]\n      y = targetCopy[i]\n      break\n    }\n  }\n\n  if (x < y) return -1\n  if (y < x) return 1\n  return 0\n}\n\n// Finds either the first index of `val` in `buffer` at offset >= `byteOffset`,\n// OR the last index of `val` in `buffer` at offset <= `byteOffset`.\n//\n// Arguments:\n// - buffer - a Buffer to search\n// - val - a string, Buffer, or number\n// - byteOffset - an index into `buffer`; will be clamped to an int32\n// - encoding - an optional encoding, relevant is val is a string\n// - dir - true for indexOf, false for lastIndexOf\nfunction bidirectionalIndexOf (buffer, val, byteOffset, encoding, dir) {\n  // Empty buffer means no match\n  if (buffer.length === 0) return -1\n\n  // Normalize byteOffset\n  if (typeof byteOffset === 'string') {\n    encoding = byteOffset\n    byteOffset = 0\n  } else if (byteOffset > 0x7fffffff) {\n    byteOffset = 0x7fffffff\n  } else if (byteOffset < -0x80000000) {\n    byteOffset = -0x80000000\n  }\n  byteOffset = +byteOffset  // Coerce to Number.\n  if (isNaN(byteOffset)) {\n    // byteOffset: it it's undefined, null, NaN, \"foo\", etc, search whole buffer\n    byteOffset = dir ? 0 : (buffer.length - 1)\n  }\n\n  // Normalize byteOffset: negative offsets start from the end of the buffer\n  if (byteOffset < 0) byteOffset = buffer.length + byteOffset\n  if (byteOffset >= buffer.length) {\n    if (dir) return -1\n    else byteOffset = buffer.length - 1\n  } else if (byteOffset < 0) {\n    if (dir) byteOffset = 0\n    else return -1\n  }\n\n  // Normalize val\n  if (typeof val === 'string') {\n    val = Buffer.from(val, encoding)\n  }\n\n  // Finally, search either indexOf (if dir is true) or lastIndexOf\n  if (Buffer.isBuffer(val)) {\n    // Special case: looking for empty string/buffer always fails\n    if (val.length === 0) {\n      return -1\n    }\n    return arrayIndexOf(buffer, val, byteOffset, encoding, dir)\n  } else if (typeof val === 'number') {\n    val = val & 0xFF // Search for a byte value [0-255]\n    if (Buffer.TYPED_ARRAY_SUPPORT &&\n        typeof Uint8Array.prototype.indexOf === 'function') {\n      if (dir) {\n        return Uint8Array.prototype.indexOf.call(buffer, val, byteOffset)\n      } else {\n        return Uint8Array.prototype.lastIndexOf.call(buffer, val, byteOffset)\n      }\n    }\n    return arrayIndexOf(buffer, [ val ], byteOffset, encoding, dir)\n  }\n\n  throw new TypeError('val must be string, number or Buffer')\n}\n\nfunction arrayIndexOf (arr, val, byteOffset, encoding, dir) {\n  var indexSize = 1\n  var arrLength = arr.length\n  var valLength = val.length\n\n  if (encoding !== undefined) {\n    encoding = String(encoding).toLowerCase()\n    if (encoding === 'ucs2' || encoding === 'ucs-2' ||\n        encoding === 'utf16le' || encoding === 'utf-16le') {\n      if (arr.length < 2 || val.length < 2) {\n        return -1\n      }\n      indexSize = 2\n      arrLength /= 2\n      valLength /= 2\n      byteOffset /= 2\n    }\n  }\n\n  function read (buf, i) {\n    if (indexSize === 1) {\n      return buf[i]\n    } else {\n      return buf.readUInt16BE(i * indexSize)\n    }\n  }\n\n  var i\n  if (dir) {\n    var foundIndex = -1\n    for (i = byteOffset; i < arrLength; i++) {\n      if (read(arr, i) === read(val, foundIndex === -1 ? 0 : i - foundIndex)) {\n        if (foundIndex === -1) foundIndex = i\n        if (i - foundIndex + 1 === valLength) return foundIndex * indexSize\n      } else {\n        if (foundIndex !== -1) i -= i - foundIndex\n        foundIndex = -1\n      }\n    }\n  } else {\n    if (byteOffset + valLength > arrLength) byteOffset = arrLength - valLength\n    for (i = byteOffset; i >= 0; i--) {\n      var found = true\n      for (var j = 0; j < valLength; j++) {\n        if (read(arr, i + j) !== read(val, j)) {\n          found = false\n          break\n        }\n      }\n      if (found) return i\n    }\n  }\n\n  return -1\n}\n\nBuffer.prototype.includes = function includes (val, byteOffset, encoding) {\n  return this.indexOf(val, byteOffset, encoding) !== -1\n}\n\nBuffer.prototype.indexOf = function indexOf (val, byteOffset, encoding) {\n  return bidirectionalIndexOf(this, val, byteOffset, encoding, true)\n}\n\nBuffer.prototype.lastIndexOf = function lastIndexOf (val, byteOffset, encoding) {\n  return bidirectionalIndexOf(this, val, byteOffset, encoding, false)\n}\n\nfunction hexWrite (buf, string, offset, length) {\n  offset = Number(offset) || 0\n  var remaining = buf.length - offset\n  if (!length) {\n    length = remaining\n  } else {\n    length = Number(length)\n    if (length > remaining) {\n      length = remaining\n    }\n  }\n\n  // must be an even number of digits\n  var strLen = string.length\n  if (strLen % 2 !== 0) throw new TypeError('Invalid hex string')\n\n  if (length > strLen / 2) {\n    length = strLen / 2\n  }\n  for (var i = 0; i < length; ++i) {\n    var parsed = parseInt(string.substr(i * 2, 2), 16)\n    if (isNaN(parsed)) return i\n    buf[offset + i] = parsed\n  }\n  return i\n}\n\nfunction utf8Write (buf, string, offset, length) {\n  return blitBuffer(utf8ToBytes(string, buf.length - offset), buf, offset, length)\n}\n\nfunction asciiWrite (buf, string, offset, length) {\n  return blitBuffer(asciiToBytes(string), buf, offset, length)\n}\n\nfunction latin1Write (buf, string, offset, length) {\n  return asciiWrite(buf, string, offset, length)\n}\n\nfunction base64Write (buf, string, offset, length) {\n  return blitBuffer(base64ToBytes(string), buf, offset, length)\n}\n\nfunction ucs2Write (buf, string, offset, length) {\n  return blitBuffer(utf16leToBytes(string, buf.length - offset), buf, offset, length)\n}\n\nBuffer.prototype.write = function write (string, offset, length, encoding) {\n  // Buffer#write(string)\n  if (offset === undefined) {\n    encoding = 'utf8'\n    length = this.length\n    offset = 0\n  // Buffer#write(string, encoding)\n  } else if (length === undefined && typeof offset === 'string') {\n    encoding = offset\n    length = this.length\n    offset = 0\n  // Buffer#write(string, offset[, length][, encoding])\n  } else if (isFinite(offset)) {\n    offset = offset | 0\n    if (isFinite(length)) {\n      length = length | 0\n      if (encoding === undefined) encoding = 'utf8'\n    } else {\n      encoding = length\n      length = undefined\n    }\n  // legacy write(string, encoding, offset, length) - remove in v0.13\n  } else {\n    throw new Error(\n      'Buffer.write(string, encoding, offset[, length]) is no longer supported'\n    )\n  }\n\n  var remaining = this.length - offset\n  if (length === undefined || length > remaining) length = remaining\n\n  if ((string.length > 0 && (length < 0 || offset < 0)) || offset > this.length) {\n    throw new RangeError('Attempt to write outside buffer bounds')\n  }\n\n  if (!encoding) encoding = 'utf8'\n\n  var loweredCase = false\n  for (;;) {\n    switch (encoding) {\n      case 'hex':\n        return hexWrite(this, string, offset, length)\n\n      case 'utf8':\n      case 'utf-8':\n        return utf8Write(this, string, offset, length)\n\n      case 'ascii':\n        return asciiWrite(this, string, offset, length)\n\n      case 'latin1':\n      case 'binary':\n        return latin1Write(this, string, offset, length)\n\n      case 'base64':\n        // Warning: maxLength not taken into account in base64Write\n        return base64Write(this, string, offset, length)\n\n      case 'ucs2':\n      case 'ucs-2':\n      case 'utf16le':\n      case 'utf-16le':\n        return ucs2Write(this, string, offset, length)\n\n      default:\n        if (loweredCase) throw new TypeError('Unknown encoding: ' + encoding)\n        encoding = ('' + encoding).toLowerCase()\n        loweredCase = true\n    }\n  }\n}\n\nBuffer.prototype.toJSON = function toJSON () {\n  return {\n    type: 'Buffer',\n    data: Array.prototype.slice.call(this._arr || this, 0)\n  }\n}\n\nfunction base64Slice (buf, start, end) {\n  if (start === 0 && end === buf.length) {\n    return base64.fromByteArray(buf)\n  } else {\n    return base64.fromByteArray(buf.slice(start, end))\n  }\n}\n\nfunction utf8Slice (buf, start, end) {\n  end = Math.min(buf.length, end)\n  var res = []\n\n  var i = start\n  while (i < end) {\n    var firstByte = buf[i]\n    var codePoint = null\n    var bytesPerSequence = (firstByte > 0xEF) ? 4\n      : (firstByte > 0xDF) ? 3\n      : (firstByte > 0xBF) ? 2\n      : 1\n\n    if (i + bytesPerSequence <= end) {\n      var secondByte, thirdByte, fourthByte, tempCodePoint\n\n      switch (bytesPerSequence) {\n        case 1:\n          if (firstByte < 0x80) {\n            codePoint = firstByte\n          }\n          break\n        case 2:\n          secondByte = buf[i + 1]\n          if ((secondByte & 0xC0) === 0x80) {\n            tempCodePoint = (firstByte & 0x1F) << 0x6 | (secondByte & 0x3F)\n            if (tempCodePoint > 0x7F) {\n              codePoint = tempCodePoint\n            }\n          }\n          break\n        case 3:\n          secondByte = buf[i + 1]\n          thirdByte = buf[i + 2]\n          if ((secondByte & 0xC0) === 0x80 && (thirdByte & 0xC0) === 0x80) {\n            tempCodePoint = (firstByte & 0xF) << 0xC | (secondByte & 0x3F) << 0x6 | (thirdByte & 0x3F)\n            if (tempCodePoint > 0x7FF && (tempCodePoint < 0xD800 || tempCodePoint > 0xDFFF)) {\n              codePoint = tempCodePoint\n            }\n          }\n          break\n        case 4:\n          secondByte = buf[i + 1]\n          thirdByte = buf[i + 2]\n          fourthByte = buf[i + 3]\n          if ((secondByte & 0xC0) === 0x80 && (thirdByte & 0xC0) === 0x80 && (fourthByte & 0xC0) === 0x80) {\n            tempCodePoint = (firstByte & 0xF) << 0x12 | (secondByte & 0x3F) << 0xC | (thirdByte & 0x3F) << 0x6 | (fourthByte & 0x3F)\n            if (tempCodePoint > 0xFFFF && tempCodePoint < 0x110000) {\n              codePoint = tempCodePoint\n            }\n          }\n      }\n    }\n\n    if (codePoint === null) {\n      // we did not generate a valid codePoint so insert a\n      // replacement char (U+FFFD) and advance only 1 byte\n      codePoint = 0xFFFD\n      bytesPerSequence = 1\n    } else if (codePoint > 0xFFFF) {\n      // encode to utf16 (surrogate pair dance)\n      codePoint -= 0x10000\n      res.push(codePoint >>> 10 & 0x3FF | 0xD800)\n      codePoint = 0xDC00 | codePoint & 0x3FF\n    }\n\n    res.push(codePoint)\n    i += bytesPerSequence\n  }\n\n  return decodeCodePointsArray(res)\n}\n\n// Based on http://stackoverflow.com/a/22747272/680742, the browser with\n// the lowest limit is Chrome, with 0x10000 args.\n// We go 1 magnitude less, for safety\nvar MAX_ARGUMENTS_LENGTH = 0x1000\n\nfunction decodeCodePointsArray (codePoints) {\n  var len = codePoints.length\n  if (len <= MAX_ARGUMENTS_LENGTH) {\n    return String.fromCharCode.apply(String, codePoints) // avoid extra slice()\n  }\n\n  // Decode in chunks to avoid \"call stack size exceeded\".\n  var res = ''\n  var i = 0\n  while (i < len) {\n    res += String.fromCharCode.apply(\n      String,\n      codePoints.slice(i, i += MAX_ARGUMENTS_LENGTH)\n    )\n  }\n  return res\n}\n\nfunction asciiSlice (buf, start, end) {\n  var ret = ''\n  end = Math.min(buf.length, end)\n\n  for (var i = start; i < end; ++i) {\n    ret += String.fromCharCode(buf[i] & 0x7F)\n  }\n  return ret\n}\n\nfunction latin1Slice (buf, start, end) {\n  var ret = ''\n  end = Math.min(buf.length, end)\n\n  for (var i = start; i < end; ++i) {\n    ret += String.fromCharCode(buf[i])\n  }\n  return ret\n}\n\nfunction hexSlice (buf, start, end) {\n  var len = buf.length\n\n  if (!start || start < 0) start = 0\n  if (!end || end < 0 || end > len) end = len\n\n  var out = ''\n  for (var i = start; i < end; ++i) {\n    out += toHex(buf[i])\n  }\n  return out\n}\n\nfunction utf16leSlice (buf, start, end) {\n  var bytes = buf.slice(start, end)\n  var res = ''\n  for (var i = 0; i < bytes.length; i += 2) {\n    res += String.fromCharCode(bytes[i] + bytes[i + 1] * 256)\n  }\n  return res\n}\n\nBuffer.prototype.slice = function slice (start, end) {\n  var len = this.length\n  start = ~~start\n  end = end === undefined ? len : ~~end\n\n  if (start < 0) {\n    start += len\n    if (start < 0) start = 0\n  } else if (start > len) {\n    start = len\n  }\n\n  if (end < 0) {\n    end += len\n    if (end < 0) end = 0\n  } else if (end > len) {\n    end = len\n  }\n\n  if (end < start) end = start\n\n  var newBuf\n  if (Buffer.TYPED_ARRAY_SUPPORT) {\n    newBuf = this.subarray(start, end)\n    newBuf.__proto__ = Buffer.prototype\n  } else {\n    var sliceLen = end - start\n    newBuf = new Buffer(sliceLen, undefined)\n    for (var i = 0; i < sliceLen; ++i) {\n      newBuf[i] = this[i + start]\n    }\n  }\n\n  return newBuf\n}\n\n/*\n * Need to make sure that buffer isn't trying to write out of bounds.\n */\nfunction checkOffset (offset, ext, length) {\n  if ((offset % 1) !== 0 || offset < 0) throw new RangeError('offset is not uint')\n  if (offset + ext > length) throw new RangeError('Trying to access beyond buffer length')\n}\n\nBuffer.prototype.readUIntLE = function readUIntLE (offset, byteLength, noAssert) {\n  offset = offset | 0\n  byteLength = byteLength | 0\n  if (!noAssert) checkOffset(offset, byteLength, this.length)\n\n  var val = this[offset]\n  var mul = 1\n  var i = 0\n  while (++i < byteLength && (mul *= 0x100)) {\n    val += this[offset + i] * mul\n  }\n\n  return val\n}\n\nBuffer.prototype.readUIntBE = function readUIntBE (offset, byteLength, noAssert) {\n  offset = offset | 0\n  byteLength = byteLength | 0\n  if (!noAssert) {\n    checkOffset(offset, byteLength, this.length)\n  }\n\n  var val = this[offset + --byteLength]\n  var mul = 1\n  while (byteLength > 0 && (mul *= 0x100)) {\n    val += this[offset + --byteLength] * mul\n  }\n\n  return val\n}\n\nBuffer.prototype.readUInt8 = function readUInt8 (offset, noAssert) {\n  if (!noAssert) checkOffset(offset, 1, this.length)\n  return this[offset]\n}\n\nBuffer.prototype.readUInt16LE = function readUInt16LE (offset, noAssert) {\n  if (!noAssert) checkOffset(offset, 2, this.length)\n  return this[offset] | (this[offset + 1] << 8)\n}\n\nBuffer.prototype.readUInt16BE = function readUInt16BE (offset, noAssert) {\n  if (!noAssert) checkOffset(offset, 2, this.length)\n  return (this[offset] << 8) | this[offset + 1]\n}\n\nBuffer.prototype.readUInt32LE = function readUInt32LE (offset, noAssert) {\n  if (!noAssert) checkOffset(offset, 4, this.length)\n\n  return ((this[offset]) |\n      (this[offset + 1] << 8) |\n      (this[offset + 2] << 16)) +\n      (this[offset + 3] * 0x1000000)\n}\n\nBuffer.prototype.readUInt32BE = function readUInt32BE (offset, noAssert) {\n  if (!noAssert) checkOffset(offset, 4, this.length)\n\n  return (this[offset] * 0x1000000) +\n    ((this[offset + 1] << 16) |\n    (this[offset + 2] << 8) |\n    this[offset + 3])\n}\n\nBuffer.prototype.readIntLE = function readIntLE (offset, byteLength, noAssert) {\n  offset = offset | 0\n  byteLength = byteLength | 0\n  if (!noAssert) checkOffset(offset, byteLength, this.length)\n\n  var val = this[offset]\n  var mul = 1\n  var i = 0\n  while (++i < byteLength && (mul *= 0x100)) {\n    val += this[offset + i] * mul\n  }\n  mul *= 0x80\n\n  if (val >= mul) val -= Math.pow(2, 8 * byteLength)\n\n  return val\n}\n\nBuffer.prototype.readIntBE = function readIntBE (offset, byteLength, noAssert) {\n  offset = offset | 0\n  byteLength = byteLength | 0\n  if (!noAssert) checkOffset(offset, byteLength, this.length)\n\n  var i = byteLength\n  var mul = 1\n  var val = this[offset + --i]\n  while (i > 0 && (mul *= 0x100)) {\n    val += this[offset + --i] * mul\n  }\n  mul *= 0x80\n\n  if (val >= mul) val -= Math.pow(2, 8 * byteLength)\n\n  return val\n}\n\nBuffer.prototype.readInt8 = function readInt8 (offset, noAssert) {\n  if (!noAssert) checkOffset(offset, 1, this.length)\n  if (!(this[offset] & 0x80)) return (this[offset])\n  return ((0xff - this[offset] + 1) * -1)\n}\n\nBuffer.prototype.readInt16LE = function readInt16LE (offset, noAssert) {\n  if (!noAssert) checkOffset(offset, 2, this.length)\n  var val = this[offset] | (this[offset + 1] << 8)\n  return (val & 0x8000) ? val | 0xFFFF0000 : val\n}\n\nBuffer.prototype.readInt16BE = function readInt16BE (offset, noAssert) {\n  if (!noAssert) checkOffset(offset, 2, this.length)\n  var val = this[offset + 1] | (this[offset] << 8)\n  return (val & 0x8000) ? val | 0xFFFF0000 : val\n}\n\nBuffer.prototype.readInt32LE = function readInt32LE (offset, noAssert) {\n  if (!noAssert) checkOffset(offset, 4, this.length)\n\n  return (this[offset]) |\n    (this[offset + 1] << 8) |\n    (this[offset + 2] << 16) |\n    (this[offset + 3] << 24)\n}\n\nBuffer.prototype.readInt32BE = function readInt32BE (offset, noAssert) {\n  if (!noAssert) checkOffset(offset, 4, this.length)\n\n  return (this[offset] << 24) |\n    (this[offset + 1] << 16) |\n    (this[offset + 2] << 8) |\n    (this[offset + 3])\n}\n\nBuffer.prototype.readFloatLE = function readFloatLE (offset, noAssert) {\n  if (!noAssert) checkOffset(offset, 4, this.length)\n  return ieee754.read(this, offset, true, 23, 4)\n}\n\nBuffer.prototype.readFloatBE = function readFloatBE (offset, noAssert) {\n  if (!noAssert) checkOffset(offset, 4, this.length)\n  return ieee754.read(this, offset, false, 23, 4)\n}\n\nBuffer.prototype.readDoubleLE = function readDoubleLE (offset, noAssert) {\n  if (!noAssert) checkOffset(offset, 8, this.length)\n  return ieee754.read(this, offset, true, 52, 8)\n}\n\nBuffer.prototype.readDoubleBE = function readDoubleBE (offset, noAssert) {\n  if (!noAssert) checkOffset(offset, 8, this.length)\n  return ieee754.read(this, offset, false, 52, 8)\n}\n\nfunction checkInt (buf, value, offset, ext, max, min) {\n  if (!Buffer.isBuffer(buf)) throw new TypeError('\"buffer\" argument must be a Buffer instance')\n  if (value > max || value < min) throw new RangeError('\"value\" argument is out of bounds')\n  if (offset + ext > buf.length) throw new RangeError('Index out of range')\n}\n\nBuffer.prototype.writeUIntLE = function writeUIntLE (value, offset, byteLength, noAssert) {\n  value = +value\n  offset = offset | 0\n  byteLength = byteLength | 0\n  if (!noAssert) {\n    var maxBytes = Math.pow(2, 8 * byteLength) - 1\n    checkInt(this, value, offset, byteLength, maxBytes, 0)\n  }\n\n  var mul = 1\n  var i = 0\n  this[offset] = value & 0xFF\n  while (++i < byteLength && (mul *= 0x100)) {\n    this[offset + i] = (value / mul) & 0xFF\n  }\n\n  return offset + byteLength\n}\n\nBuffer.prototype.writeUIntBE = function writeUIntBE (value, offset, byteLength, noAssert) {\n  value = +value\n  offset = offset | 0\n  byteLength = byteLength | 0\n  if (!noAssert) {\n    var maxBytes = Math.pow(2, 8 * byteLength) - 1\n    checkInt(this, value, offset, byteLength, maxBytes, 0)\n  }\n\n  var i = byteLength - 1\n  var mul = 1\n  this[offset + i] = value & 0xFF\n  while (--i >= 0 && (mul *= 0x100)) {\n    this[offset + i] = (value / mul) & 0xFF\n  }\n\n  return offset + byteLength\n}\n\nBuffer.prototype.writeUInt8 = function writeUInt8 (value, offset, noAssert) {\n  value = +value\n  offset = offset | 0\n  if (!noAssert) checkInt(this, value, offset, 1, 0xff, 0)\n  if (!Buffer.TYPED_ARRAY_SUPPORT) value = Math.floor(value)\n  this[offset] = (value & 0xff)\n  return offset + 1\n}\n\nfunction objectWriteUInt16 (buf, value, offset, littleEndian) {\n  if (value < 0) value = 0xffff + value + 1\n  for (var i = 0, j = Math.min(buf.length - offset, 2); i < j; ++i) {\n    buf[offset + i] = (value & (0xff << (8 * (littleEndian ? i : 1 - i)))) >>>\n      (littleEndian ? i : 1 - i) * 8\n  }\n}\n\nBuffer.prototype.writeUInt16LE = function writeUInt16LE (value, offset, noAssert) {\n  value = +value\n  offset = offset | 0\n  if (!noAssert) checkInt(this, value, offset, 2, 0xffff, 0)\n  if (Buffer.TYPED_ARRAY_SUPPORT) {\n    this[offset] = (value & 0xff)\n    this[offset + 1] = (value >>> 8)\n  } else {\n    objectWriteUInt16(this, value, offset, true)\n  }\n  return offset + 2\n}\n\nBuffer.prototype.writeUInt16BE = function writeUInt16BE (value, offset, noAssert) {\n  value = +value\n  offset = offset | 0\n  if (!noAssert) checkInt(this, value, offset, 2, 0xffff, 0)\n  if (Buffer.TYPED_ARRAY_SUPPORT) {\n    this[offset] = (value >>> 8)\n    this[offset + 1] = (value & 0xff)\n  } else {\n    objectWriteUInt16(this, value, offset, false)\n  }\n  return offset + 2\n}\n\nfunction objectWriteUInt32 (buf, value, offset, littleEndian) {\n  if (value < 0) value = 0xffffffff + value + 1\n  for (var i = 0, j = Math.min(buf.length - offset, 4); i < j; ++i) {\n    buf[offset + i] = (value >>> (littleEndian ? i : 3 - i) * 8) & 0xff\n  }\n}\n\nBuffer.prototype.writeUInt32LE = function writeUInt32LE (value, offset, noAssert) {\n  value = +value\n  offset = offset | 0\n  if (!noAssert) checkInt(this, value, offset, 4, 0xffffffff, 0)\n  if (Buffer.TYPED_ARRAY_SUPPORT) {\n    this[offset + 3] = (value >>> 24)\n    this[offset + 2] = (value >>> 16)\n    this[offset + 1] = (value >>> 8)\n    this[offset] = (value & 0xff)\n  } else {\n    objectWriteUInt32(this, value, offset, true)\n  }\n  return offset + 4\n}\n\nBuffer.prototype.writeUInt32BE = function writeUInt32BE (value, offset, noAssert) {\n  value = +value\n  offset = offset | 0\n  if (!noAssert) checkInt(this, value, offset, 4, 0xffffffff, 0)\n  if (Buffer.TYPED_ARRAY_SUPPORT) {\n    this[offset] = (value >>> 24)\n    this[offset + 1] = (value >>> 16)\n    this[offset + 2] = (value >>> 8)\n    this[offset + 3] = (value & 0xff)\n  } else {\n    objectWriteUInt32(this, value, offset, false)\n  }\n  return offset + 4\n}\n\nBuffer.prototype.writeIntLE = function writeIntLE (value, offset, byteLength, noAssert) {\n  value = +value\n  offset = offset | 0\n  if (!noAssert) {\n    var limit = Math.pow(2, 8 * byteLength - 1)\n\n    checkInt(this, value, offset, byteLength, limit - 1, -limit)\n  }\n\n  var i = 0\n  var mul = 1\n  var sub = 0\n  this[offset] = value & 0xFF\n  while (++i < byteLength && (mul *= 0x100)) {\n    if (value < 0 && sub === 0 && this[offset + i - 1] !== 0) {\n      sub = 1\n    }\n    this[offset + i] = ((value / mul) >> 0) - sub & 0xFF\n  }\n\n  return offset + byteLength\n}\n\nBuffer.prototype.writeIntBE = function writeIntBE (value, offset, byteLength, noAssert) {\n  value = +value\n  offset = offset | 0\n  if (!noAssert) {\n    var limit = Math.pow(2, 8 * byteLength - 1)\n\n    checkInt(this, value, offset, byteLength, limit - 1, -limit)\n  }\n\n  var i = byteLength - 1\n  var mul = 1\n  var sub = 0\n  this[offset + i] = value & 0xFF\n  while (--i >= 0 && (mul *= 0x100)) {\n    if (value < 0 && sub === 0 && this[offset + i + 1] !== 0) {\n      sub = 1\n    }\n    this[offset + i] = ((value / mul) >> 0) - sub & 0xFF\n  }\n\n  return offset + byteLength\n}\n\nBuffer.prototype.writeInt8 = function writeInt8 (value, offset, noAssert) {\n  value = +value\n  offset = offset | 0\n  if (!noAssert) checkInt(this, value, offset, 1, 0x7f, -0x80)\n  if (!Buffer.TYPED_ARRAY_SUPPORT) value = Math.floor(value)\n  if (value < 0) value = 0xff + value + 1\n  this[offset] = (value & 0xff)\n  return offset + 1\n}\n\nBuffer.prototype.writeInt16LE = function writeInt16LE (value, offset, noAssert) {\n  value = +value\n  offset = offset | 0\n  if (!noAssert) checkInt(this, value, offset, 2, 0x7fff, -0x8000)\n  if (Buffer.TYPED_ARRAY_SUPPORT) {\n    this[offset] = (value & 0xff)\n    this[offset + 1] = (value >>> 8)\n  } else {\n    objectWriteUInt16(this, value, offset, true)\n  }\n  return offset + 2\n}\n\nBuffer.prototype.writeInt16BE = function writeInt16BE (value, offset, noAssert) {\n  value = +value\n  offset = offset | 0\n  if (!noAssert) checkInt(this, value, offset, 2, 0x7fff, -0x8000)\n  if (Buffer.TYPED_ARRAY_SUPPORT) {\n    this[offset] = (value >>> 8)\n    this[offset + 1] = (value & 0xff)\n  } else {\n    objectWriteUInt16(this, value, offset, false)\n  }\n  return offset + 2\n}\n\nBuffer.prototype.writeInt32LE = function writeInt32LE (value, offset, noAssert) {\n  value = +value\n  offset = offset | 0\n  if (!noAssert) checkInt(this, value, offset, 4, 0x7fffffff, -0x80000000)\n  if (Buffer.TYPED_ARRAY_SUPPORT) {\n    this[offset] = (value & 0xff)\n    this[offset + 1] = (value >>> 8)\n    this[offset + 2] = (value >>> 16)\n    this[offset + 3] = (value >>> 24)\n  } else {\n    objectWriteUInt32(this, value, offset, true)\n  }\n  return offset + 4\n}\n\nBuffer.prototype.writeInt32BE = function writeInt32BE (value, offset, noAssert) {\n  value = +value\n  offset = offset | 0\n  if (!noAssert) checkInt(this, value, offset, 4, 0x7fffffff, -0x80000000)\n  if (value < 0) value = 0xffffffff + value + 1\n  if (Buffer.TYPED_ARRAY_SUPPORT) {\n    this[offset] = (value >>> 24)\n    this[offset + 1] = (value >>> 16)\n    this[offset + 2] = (value >>> 8)\n    this[offset + 3] = (value & 0xff)\n  } else {\n    objectWriteUInt32(this, value, offset, false)\n  }\n  return offset + 4\n}\n\nfunction checkIEEE754 (buf, value, offset, ext, max, min) {\n  if (offset + ext > buf.length) throw new RangeError('Index out of range')\n  if (offset < 0) throw new RangeError('Index out of range')\n}\n\nfunction writeFloat (buf, value, offset, littleEndian, noAssert) {\n  if (!noAssert) {\n    checkIEEE754(buf, value, offset, 4, 3.4028234663852886e+38, -3.4028234663852886e+38)\n  }\n  ieee754.write(buf, value, offset, littleEndian, 23, 4)\n  return offset + 4\n}\n\nBuffer.prototype.writeFloatLE = function writeFloatLE (value, offset, noAssert) {\n  return writeFloat(this, value, offset, true, noAssert)\n}\n\nBuffer.prototype.writeFloatBE = function writeFloatBE (value, offset, noAssert) {\n  return writeFloat(this, value, offset, false, noAssert)\n}\n\nfunction writeDouble (buf, value, offset, littleEndian, noAssert) {\n  if (!noAssert) {\n    checkIEEE754(buf, value, offset, 8, 1.7976931348623157E+308, -1.7976931348623157E+308)\n  }\n  ieee754.write(buf, value, offset, littleEndian, 52, 8)\n  return offset + 8\n}\n\nBuffer.prototype.writeDoubleLE = function writeDoubleLE (value, offset, noAssert) {\n  return writeDouble(this, value, offset, true, noAssert)\n}\n\nBuffer.prototype.writeDoubleBE = function writeDoubleBE (value, offset, noAssert) {\n  return writeDouble(this, value, offset, false, noAssert)\n}\n\n// copy(targetBuffer, targetStart=0, sourceStart=0, sourceEnd=buffer.length)\nBuffer.prototype.copy = function copy (target, targetStart, start, end) {\n  if (!start) start = 0\n  if (!end && end !== 0) end = this.length\n  if (targetStart >= target.length) targetStart = target.length\n  if (!targetStart) targetStart = 0\n  if (end > 0 && end < start) end = start\n\n  // Copy 0 bytes; we're done\n  if (end === start) return 0\n  if (target.length === 0 || this.length === 0) return 0\n\n  // Fatal error conditions\n  if (targetStart < 0) {\n    throw new RangeError('targetStart out of bounds')\n  }\n  if (start < 0 || start >= this.length) throw new RangeError('sourceStart out of bounds')\n  if (end < 0) throw new RangeError('sourceEnd out of bounds')\n\n  // Are we oob?\n  if (end > this.length) end = this.length\n  if (target.length - targetStart < end - start) {\n    end = target.length - targetStart + start\n  }\n\n  var len = end - start\n  var i\n\n  if (this === target && start < targetStart && targetStart < end) {\n    // descending copy from end\n    for (i = len - 1; i >= 0; --i) {\n      target[i + targetStart] = this[i + start]\n    }\n  } else if (len < 1000 || !Buffer.TYPED_ARRAY_SUPPORT) {\n    // ascending copy from start\n    for (i = 0; i < len; ++i) {\n      target[i + targetStart] = this[i + start]\n    }\n  } else {\n    Uint8Array.prototype.set.call(\n      target,\n      this.subarray(start, start + len),\n      targetStart\n    )\n  }\n\n  return len\n}\n\n// Usage:\n//    buffer.fill(number[, offset[, end]])\n//    buffer.fill(buffer[, offset[, end]])\n//    buffer.fill(string[, offset[, end]][, encoding])\nBuffer.prototype.fill = function fill (val, start, end, encoding) {\n  // Handle string cases:\n  if (typeof val === 'string') {\n    if (typeof start === 'string') {\n      encoding = start\n      start = 0\n      end = this.length\n    } else if (typeof end === 'string') {\n      encoding = end\n      end = this.length\n    }\n    if (val.length === 1) {\n      var code = val.charCodeAt(0)\n      if (code < 256) {\n        val = code\n      }\n    }\n    if (encoding !== undefined && typeof encoding !== 'string') {\n      throw new TypeError('encoding must be a string')\n    }\n    if (typeof encoding === 'string' && !Buffer.isEncoding(encoding)) {\n      throw new TypeError('Unknown encoding: ' + encoding)\n    }\n  } else if (typeof val === 'number') {\n    val = val & 255\n  }\n\n  // Invalid ranges are not set to a default, so can range check early.\n  if (start < 0 || this.length < start || this.length < end) {\n    throw new RangeError('Out of range index')\n  }\n\n  if (end <= start) {\n    return this\n  }\n\n  start = start >>> 0\n  end = end === undefined ? this.length : end >>> 0\n\n  if (!val) val = 0\n\n  var i\n  if (typeof val === 'number') {\n    for (i = start; i < end; ++i) {\n      this[i] = val\n    }\n  } else {\n    var bytes = Buffer.isBuffer(val)\n      ? val\n      : utf8ToBytes(new Buffer(val, encoding).toString())\n    var len = bytes.length\n    for (i = 0; i < end - start; ++i) {\n      this[i + start] = bytes[i % len]\n    }\n  }\n\n  return this\n}\n\n// HELPER FUNCTIONS\n// ================\n\nvar INVALID_BASE64_RE = /[^+\\/0-9A-Za-z-_]/g\n\nfunction base64clean (str) {\n  // Node strips out invalid characters like \\n and \\t from the string, base64-js does not\n  str = stringtrim(str).replace(INVALID_BASE64_RE, '')\n  // Node converts strings with length < 2 to ''\n  if (str.length < 2) return ''\n  // Node allows for non-padded base64 strings (missing trailing ===), base64-js does not\n  while (str.length % 4 !== 0) {\n    str = str + '='\n  }\n  return str\n}\n\nfunction stringtrim (str) {\n  if (str.trim) return str.trim()\n  return str.replace(/^\\s+|\\s+$/g, '')\n}\n\nfunction toHex (n) {\n  if (n < 16) return '0' + n.toString(16)\n  return n.toString(16)\n}\n\nfunction utf8ToBytes (string, units) {\n  units = units || Infinity\n  var codePoint\n  var length = string.length\n  var leadSurrogate = null\n  var bytes = []\n\n  for (var i = 0; i < length; ++i) {\n    codePoint = string.charCodeAt(i)\n\n    // is surrogate component\n    if (codePoint > 0xD7FF && codePoint < 0xE000) {\n      // last char was a lead\n      if (!leadSurrogate) {\n        // no lead yet\n        if (codePoint > 0xDBFF) {\n          // unexpected trail\n          if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD)\n          continue\n        } else if (i + 1 === length) {\n          // unpaired lead\n          if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD)\n          continue\n        }\n\n        // valid lead\n        leadSurrogate = codePoint\n\n        continue\n      }\n\n      // 2 leads in a row\n      if (codePoint < 0xDC00) {\n        if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD)\n        leadSurrogate = codePoint\n        continue\n      }\n\n      // valid surrogate pair\n      codePoint = (leadSurrogate - 0xD800 << 10 | codePoint - 0xDC00) + 0x10000\n    } else if (leadSurrogate) {\n      // valid bmp char, but last char was a lead\n      if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD)\n    }\n\n    leadSurrogate = null\n\n    // encode utf8\n    if (codePoint < 0x80) {\n      if ((units -= 1) < 0) break\n      bytes.push(codePoint)\n    } else if (codePoint < 0x800) {\n      if ((units -= 2) < 0) break\n      bytes.push(\n        codePoint >> 0x6 | 0xC0,\n        codePoint & 0x3F | 0x80\n      )\n    } else if (codePoint < 0x10000) {\n      if ((units -= 3) < 0) break\n      bytes.push(\n        codePoint >> 0xC | 0xE0,\n        codePoint >> 0x6 & 0x3F | 0x80,\n        codePoint & 0x3F | 0x80\n      )\n    } else if (codePoint < 0x110000) {\n      if ((units -= 4) < 0) break\n      bytes.push(\n        codePoint >> 0x12 | 0xF0,\n        codePoint >> 0xC & 0x3F | 0x80,\n        codePoint >> 0x6 & 0x3F | 0x80,\n        codePoint & 0x3F | 0x80\n      )\n    } else {\n      throw new Error('Invalid code point')\n    }\n  }\n\n  return bytes\n}\n\nfunction asciiToBytes (str) {\n  var byteArray = []\n  for (var i = 0; i < str.length; ++i) {\n    // Node's code seems to be doing this and not & 0x7F..\n    byteArray.push(str.charCodeAt(i) & 0xFF)\n  }\n  return byteArray\n}\n\nfunction utf16leToBytes (str, units) {\n  var c, hi, lo\n  var byteArray = []\n  for (var i = 0; i < str.length; ++i) {\n    if ((units -= 2) < 0) break\n\n    c = str.charCodeAt(i)\n    hi = c >> 8\n    lo = c % 256\n    byteArray.push(lo)\n    byteArray.push(hi)\n  }\n\n  return byteArray\n}\n\nfunction base64ToBytes (str) {\n  return base64.toByteArray(base64clean(str))\n}\n\nfunction blitBuffer (src, dst, offset, length) {\n  for (var i = 0; i < length; ++i) {\n    if ((i + offset >= dst.length) || (i >= src.length)) break\n    dst[i + offset] = src[i]\n  }\n  return i\n}\n\nfunction isnan (val) {\n  return val !== val // eslint-disable-line no-self-compare\n}\n\n}).call(this,typeof global !== \"undefined\" ? global : typeof self !== \"undefined\" ? self : typeof window !== \"undefined\" ? window : {})\n},{\"base64-js\":39,\"ieee754\":50,\"isarray\":53}],45:[function(require,module,exports){\n(function (Buffer){\n// Copyright Joyent, Inc. and other Node contributors.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a\n// copy of this software and associated documentation files (the\n// \"Software\"), to deal in the Software without restriction, including\n// without limitation the rights to use, copy, modify, merge, publish,\n// distribute, sublicense, and/or sell copies of the Software, and to permit\n// persons to whom the Software is furnished to do so, subject to the\n// following conditions:\n//\n// The above copyright notice and this permission notice shall be included\n// in all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS\n// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN\n// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,\n// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE\n// USE OR OTHER DEALINGS IN THE SOFTWARE.\n\n// NOTE: These type checking functions intentionally don't use `instanceof`\n// because it is fragile and can be easily faked with `Object.create()`.\n\nfunction isArray(arg) {\n  if (Array.isArray) {\n    return Array.isArray(arg);\n  }\n  return objectToString(arg) === '[object Array]';\n}\nexports.isArray = isArray;\n\nfunction isBoolean(arg) {\n  return typeof arg === 'boolean';\n}\nexports.isBoolean = isBoolean;\n\nfunction isNull(arg) {\n  return arg === null;\n}\nexports.isNull = isNull;\n\nfunction isNullOrUndefined(arg) {\n  return arg == null;\n}\nexports.isNullOrUndefined = isNullOrUndefined;\n\nfunction isNumber(arg) {\n  return typeof arg === 'number';\n}\nexports.isNumber = isNumber;\n\nfunction isString(arg) {\n  return typeof arg === 'string';\n}\nexports.isString = isString;\n\nfunction isSymbol(arg) {\n  return typeof arg === 'symbol';\n}\nexports.isSymbol = isSymbol;\n\nfunction isUndefined(arg) {\n  return arg === void 0;\n}\nexports.isUndefined = isUndefined;\n\nfunction isRegExp(re) {\n  return objectToString(re) === '[object RegExp]';\n}\nexports.isRegExp = isRegExp;\n\nfunction isObject(arg) {\n  return typeof arg === 'object' && arg !== null;\n}\nexports.isObject = isObject;\n\nfunction isDate(d) {\n  return objectToString(d) === '[object Date]';\n}\nexports.isDate = isDate;\n\nfunction isError(e) {\n  return (objectToString(e) === '[object Error]' || e instanceof Error);\n}\nexports.isError = isError;\n\nfunction isFunction(arg) {\n  return typeof arg === 'function';\n}\nexports.isFunction = isFunction;\n\nfunction isPrimitive(arg) {\n  return arg === null ||\n         typeof arg === 'boolean' ||\n         typeof arg === 'number' ||\n         typeof arg === 'string' ||\n         typeof arg === 'symbol' ||  // ES6 symbol\n         typeof arg === 'undefined';\n}\nexports.isPrimitive = isPrimitive;\n\nexports.isBuffer = Buffer.isBuffer;\n\nfunction objectToString(o) {\n  return Object.prototype.toString.call(o);\n}\n\n}).call(this,{\"isBuffer\":require(\"../../is-buffer/index.js\")})\n},{\"../../is-buffer/index.js\":52}],46:[function(require,module,exports){\n/* See LICENSE file for terms of use */\n\n/*\n * Text diff implementation.\n *\n * This library supports the following APIS:\n * JsDiff.diffChars: Character by character diff\n * JsDiff.diffWords: Word (as defined by \\b regex) diff which ignores whitespace\n * JsDiff.diffLines: Line based diff\n *\n * JsDiff.diffCss: Diff targeted at CSS content\n *\n * These methods are based on the implementation proposed in\n * \"An O(ND) Difference Algorithm and its Variations\" (Myers, 1986).\n * http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.4.6927\n */\n(function(global, undefined) {\n  var objectPrototypeToString = Object.prototype.toString;\n\n  /*istanbul ignore next*/\n  function map(arr, mapper, that) {\n    if (Array.prototype.map) {\n      return Array.prototype.map.call(arr, mapper, that);\n    }\n\n    var other = new Array(arr.length);\n\n    for (var i = 0, n = arr.length; i < n; i++) {\n      other[i] = mapper.call(that, arr[i], i, arr);\n    }\n    return other;\n  }\n  function clonePath(path) {\n    return { newPos: path.newPos, components: path.components.slice(0) };\n  }\n  function removeEmpty(array) {\n    var ret = [];\n    for (var i = 0; i < array.length; i++) {\n      if (array[i]) {\n        ret.push(array[i]);\n      }\n    }\n    return ret;\n  }\n  function escapeHTML(s) {\n    var n = s;\n    n = n.replace(/&/g, '&amp;');\n    n = n.replace(/</g, '&lt;');\n    n = n.replace(/>/g, '&gt;');\n    n = n.replace(/\"/g, '&quot;');\n\n    return n;\n  }\n\n  // This function handles the presence of circular references by bailing out when encountering an\n  // object that is already on the \"stack\" of items being processed.\n  function canonicalize(obj, stack, replacementStack) {\n    stack = stack || [];\n    replacementStack = replacementStack || [];\n\n    var i;\n\n    for (i = 0; i < stack.length; i += 1) {\n      if (stack[i] === obj) {\n        return replacementStack[i];\n      }\n    }\n\n    var canonicalizedObj;\n\n    if ('[object Array]' === objectPrototypeToString.call(obj)) {\n      stack.push(obj);\n      canonicalizedObj = new Array(obj.length);\n      replacementStack.push(canonicalizedObj);\n      for (i = 0; i < obj.length; i += 1) {\n        canonicalizedObj[i] = canonicalize(obj[i], stack, replacementStack);\n      }\n      stack.pop();\n      replacementStack.pop();\n    } else if (typeof obj === 'object' && obj !== null) {\n      stack.push(obj);\n      canonicalizedObj = {};\n      replacementStack.push(canonicalizedObj);\n      var sortedKeys = [],\n          key;\n      for (key in obj) {\n        sortedKeys.push(key);\n      }\n      sortedKeys.sort();\n      for (i = 0; i < sortedKeys.length; i += 1) {\n        key = sortedKeys[i];\n        canonicalizedObj[key] = canonicalize(obj[key], stack, replacementStack);\n      }\n      stack.pop();\n      replacementStack.pop();\n    } else {\n      canonicalizedObj = obj;\n    }\n    return canonicalizedObj;\n  }\n\n  function buildValues(components, newString, oldString, useLongestToken) {\n    var componentPos = 0,\n        componentLen = components.length,\n        newPos = 0,\n        oldPos = 0;\n\n    for (; componentPos < componentLen; componentPos++) {\n      var component = components[componentPos];\n      if (!component.removed) {\n        if (!component.added && useLongestToken) {\n          var value = newString.slice(newPos, newPos + component.count);\n          value = map(value, function(value, i) {\n            var oldValue = oldString[oldPos + i];\n            return oldValue.length > value.length ? oldValue : value;\n          });\n\n          component.value = value.join('');\n        } else {\n          component.value = newString.slice(newPos, newPos + component.count).join('');\n        }\n        newPos += component.count;\n\n        // Common case\n        if (!component.added) {\n          oldPos += component.count;\n        }\n      } else {\n        component.value = oldString.slice(oldPos, oldPos + component.count).join('');\n        oldPos += component.count;\n\n        // Reverse add and remove so removes are output first to match common convention\n        // The diffing algorithm is tied to add then remove output and this is the simplest\n        // route to get the desired output with minimal overhead.\n        if (componentPos && components[componentPos - 1].added) {\n          var tmp = components[componentPos - 1];\n          components[componentPos - 1] = components[componentPos];\n          components[componentPos] = tmp;\n        }\n      }\n    }\n\n    return components;\n  }\n\n  function Diff(ignoreWhitespace) {\n    this.ignoreWhitespace = ignoreWhitespace;\n  }\n  Diff.prototype = {\n    diff: function(oldString, newString, callback) {\n      var self = this;\n\n      function done(value) {\n        if (callback) {\n          setTimeout(function() { callback(undefined, value); }, 0);\n          return true;\n        } else {\n          return value;\n        }\n      }\n\n      // Handle the identity case (this is due to unrolling editLength == 0\n      if (newString === oldString) {\n        return done([{ value: newString }]);\n      }\n      if (!newString) {\n        return done([{ value: oldString, removed: true }]);\n      }\n      if (!oldString) {\n        return done([{ value: newString, added: true }]);\n      }\n\n      newString = this.tokenize(newString);\n      oldString = this.tokenize(oldString);\n\n      var newLen = newString.length, oldLen = oldString.length;\n      var editLength = 1;\n      var maxEditLength = newLen + oldLen;\n      var bestPath = [{ newPos: -1, components: [] }];\n\n      // Seed editLength = 0, i.e. the content starts with the same values\n      var oldPos = this.extractCommon(bestPath[0], newString, oldString, 0);\n      if (bestPath[0].newPos + 1 >= newLen && oldPos + 1 >= oldLen) {\n        // Identity per the equality and tokenizer\n        return done([{value: newString.join('')}]);\n      }\n\n      // Main worker method. checks all permutations of a given edit length for acceptance.\n      function execEditLength() {\n        for (var diagonalPath = -1 * editLength; diagonalPath <= editLength; diagonalPath += 2) {\n          var basePath;\n          var addPath = bestPath[diagonalPath - 1],\n              removePath = bestPath[diagonalPath + 1],\n              oldPos = (removePath ? removePath.newPos : 0) - diagonalPath;\n          if (addPath) {\n            // No one else is going to attempt to use this value, clear it\n            bestPath[diagonalPath - 1] = undefined;\n          }\n\n          var canAdd = addPath && addPath.newPos + 1 < newLen,\n              canRemove = removePath && 0 <= oldPos && oldPos < oldLen;\n          if (!canAdd && !canRemove) {\n            // If this path is a terminal then prune\n            bestPath[diagonalPath] = undefined;\n            continue;\n          }\n\n          // Select the diagonal that we want to branch from. We select the prior\n          // path whose position in the new string is the farthest from the origin\n          // and does not pass the bounds of the diff graph\n          if (!canAdd || (canRemove && addPath.newPos < removePath.newPos)) {\n            basePath = clonePath(removePath);\n            self.pushComponent(basePath.components, undefined, true);\n          } else {\n            basePath = addPath;   // No need to clone, we've pulled it from the list\n            basePath.newPos++;\n            self.pushComponent(basePath.components, true, undefined);\n          }\n\n          oldPos = self.extractCommon(basePath, newString, oldString, diagonalPath);\n\n          // If we have hit the end of both strings, then we are done\n          if (basePath.newPos + 1 >= newLen && oldPos + 1 >= oldLen) {\n            return done(buildValues(basePath.components, newString, oldString, self.useLongestToken));\n          } else {\n            // Otherwise track this path as a potential candidate and continue.\n            bestPath[diagonalPath] = basePath;\n          }\n        }\n\n        editLength++;\n      }\n\n      // Performs the length of edit iteration. Is a bit fugly as this has to support the\n      // sync and async mode which is never fun. Loops over execEditLength until a value\n      // is produced.\n      if (callback) {\n        (function exec() {\n          setTimeout(function() {\n            // This should not happen, but we want to be safe.\n            /*istanbul ignore next */\n            if (editLength > maxEditLength) {\n              return callback();\n            }\n\n            if (!execEditLength()) {\n              exec();\n            }\n          }, 0);\n        }());\n      } else {\n        while (editLength <= maxEditLength) {\n          var ret = execEditLength();\n          if (ret) {\n            return ret;\n          }\n        }\n      }\n    },\n\n    pushComponent: function(components, added, removed) {\n      var last = components[components.length - 1];\n      if (last && last.added === added && last.removed === removed) {\n        // We need to clone here as the component clone operation is just\n        // as shallow array clone\n        components[components.length - 1] = {count: last.count + 1, added: added, removed: removed };\n      } else {\n        components.push({count: 1, added: added, removed: removed });\n      }\n    },\n    extractCommon: function(basePath, newString, oldString, diagonalPath) {\n      var newLen = newString.length,\n          oldLen = oldString.length,\n          newPos = basePath.newPos,\n          oldPos = newPos - diagonalPath,\n\n          commonCount = 0;\n      while (newPos + 1 < newLen && oldPos + 1 < oldLen && this.equals(newString[newPos + 1], oldString[oldPos + 1])) {\n        newPos++;\n        oldPos++;\n        commonCount++;\n      }\n\n      if (commonCount) {\n        basePath.components.push({count: commonCount});\n      }\n\n      basePath.newPos = newPos;\n      return oldPos;\n    },\n\n    equals: function(left, right) {\n      var reWhitespace = /\\S/;\n      return left === right || (this.ignoreWhitespace && !reWhitespace.test(left) && !reWhitespace.test(right));\n    },\n    tokenize: function(value) {\n      return value.split('');\n    }\n  };\n\n  var CharDiff = new Diff();\n\n  var WordDiff = new Diff(true);\n  var WordWithSpaceDiff = new Diff();\n  WordDiff.tokenize = WordWithSpaceDiff.tokenize = function(value) {\n    return removeEmpty(value.split(/(\\s+|\\b)/));\n  };\n\n  var CssDiff = new Diff(true);\n  CssDiff.tokenize = function(value) {\n    return removeEmpty(value.split(/([{}:;,]|\\s+)/));\n  };\n\n  var LineDiff = new Diff();\n\n  var TrimmedLineDiff = new Diff();\n  TrimmedLineDiff.ignoreTrim = true;\n\n  LineDiff.tokenize = TrimmedLineDiff.tokenize = function(value) {\n    var retLines = [],\n        lines = value.split(/^/m);\n    for (var i = 0; i < lines.length; i++) {\n      var line = lines[i],\n          lastLine = lines[i - 1],\n          lastLineLastChar = lastLine && lastLine[lastLine.length - 1];\n\n      // Merge lines that may contain windows new lines\n      if (line === '\\n' && lastLineLastChar === '\\r') {\n          retLines[retLines.length - 1] = retLines[retLines.length - 1].slice(0, -1) + '\\r\\n';\n      } else {\n        if (this.ignoreTrim) {\n          line = line.trim();\n          // add a newline unless this is the last line.\n          if (i < lines.length - 1) {\n            line += '\\n';\n          }\n        }\n        retLines.push(line);\n      }\n    }\n\n    return retLines;\n  };\n\n  var PatchDiff = new Diff();\n  PatchDiff.tokenize = function(value) {\n    var ret = [],\n        linesAndNewlines = value.split(/(\\n|\\r\\n)/);\n\n    // Ignore the final empty token that occurs if the string ends with a new line\n    if (!linesAndNewlines[linesAndNewlines.length - 1]) {\n      linesAndNewlines.pop();\n    }\n\n    // Merge the content and line separators into single tokens\n    for (var i = 0; i < linesAndNewlines.length; i++) {\n      var line = linesAndNewlines[i];\n\n      if (i % 2) {\n        ret[ret.length - 1] += line;\n      } else {\n        ret.push(line);\n      }\n    }\n    return ret;\n  };\n\n  var SentenceDiff = new Diff();\n  SentenceDiff.tokenize = function(value) {\n    return removeEmpty(value.split(/(\\S.+?[.!?])(?=\\s+|$)/));\n  };\n\n  var JsonDiff = new Diff();\n  // Discriminate between two lines of pretty-printed, serialized JSON where one of them has a\n  // dangling comma and the other doesn't. Turns out including the dangling comma yields the nicest output:\n  JsonDiff.useLongestToken = true;\n  JsonDiff.tokenize = LineDiff.tokenize;\n  JsonDiff.equals = function(left, right) {\n    return LineDiff.equals(left.replace(/,([\\r\\n])/g, '$1'), right.replace(/,([\\r\\n])/g, '$1'));\n  };\n\n  var JsDiff = {\n    Diff: Diff,\n\n    diffChars: function(oldStr, newStr, callback) { return CharDiff.diff(oldStr, newStr, callback); },\n    diffWords: function(oldStr, newStr, callback) { return WordDiff.diff(oldStr, newStr, callback); },\n    diffWordsWithSpace: function(oldStr, newStr, callback) { return WordWithSpaceDiff.diff(oldStr, newStr, callback); },\n    diffLines: function(oldStr, newStr, callback) { return LineDiff.diff(oldStr, newStr, callback); },\n    diffTrimmedLines: function(oldStr, newStr, callback) { return TrimmedLineDiff.diff(oldStr, newStr, callback); },\n\n    diffSentences: function(oldStr, newStr, callback) { return SentenceDiff.diff(oldStr, newStr, callback); },\n\n    diffCss: function(oldStr, newStr, callback) { return CssDiff.diff(oldStr, newStr, callback); },\n    diffJson: function(oldObj, newObj, callback) {\n      return JsonDiff.diff(\n        typeof oldObj === 'string' ? oldObj : JSON.stringify(canonicalize(oldObj), undefined, '  '),\n        typeof newObj === 'string' ? newObj : JSON.stringify(canonicalize(newObj), undefined, '  '),\n        callback\n      );\n    },\n\n    createTwoFilesPatch: function(oldFileName, newFileName, oldStr, newStr, oldHeader, newHeader) {\n      var ret = [];\n\n      if (oldFileName == newFileName) {\n        ret.push('Index: ' + oldFileName);\n      }\n      ret.push('===================================================================');\n      ret.push('--- ' + oldFileName + (typeof oldHeader === 'undefined' ? '' : '\\t' + oldHeader));\n      ret.push('+++ ' + newFileName + (typeof newHeader === 'undefined' ? '' : '\\t' + newHeader));\n\n      var diff = PatchDiff.diff(oldStr, newStr);\n      diff.push({value: '', lines: []});   // Append an empty value to make cleanup easier\n\n      // Formats a given set of lines for printing as context lines in a patch\n      function contextLines(lines) {\n        return map(lines, function(entry) { return ' ' + entry; });\n      }\n\n      // Outputs the no newline at end of file warning if needed\n      function eofNL(curRange, i, current) {\n        var last = diff[diff.length - 2],\n            isLast = i === diff.length - 2,\n            isLastOfType = i === diff.length - 3 && current.added !== last.added;\n\n        // Figure out if this is the last line for the given file and missing NL\n        if (!(/\\n$/.test(current.value)) && (isLast || isLastOfType)) {\n          curRange.push('\\\\ No newline at end of file');\n        }\n      }\n\n      var oldRangeStart = 0, newRangeStart = 0, curRange = [],\n          oldLine = 1, newLine = 1;\n      for (var i = 0; i < diff.length; i++) {\n        var current = diff[i],\n            lines = current.lines || current.value.replace(/\\n$/, '').split('\\n');\n        current.lines = lines;\n\n        if (current.added || current.removed) {\n          // If we have previous context, start with that\n          if (!oldRangeStart) {\n            var prev = diff[i - 1];\n            oldRangeStart = oldLine;\n            newRangeStart = newLine;\n\n            if (prev) {\n              curRange = contextLines(prev.lines.slice(-4));\n              oldRangeStart -= curRange.length;\n              newRangeStart -= curRange.length;\n            }\n          }\n\n          // Output our changes\n          curRange.push.apply(curRange, map(lines, function(entry) {\n            return (current.added ? '+' : '-') + entry;\n          }));\n          eofNL(curRange, i, current);\n\n          // Track the updated file position\n          if (current.added) {\n            newLine += lines.length;\n          } else {\n            oldLine += lines.length;\n          }\n        } else {\n          // Identical context lines. Track line changes\n          if (oldRangeStart) {\n            // Close out any changes that have been output (or join overlapping)\n            if (lines.length <= 8 && i < diff.length - 2) {\n              // Overlapping\n              curRange.push.apply(curRange, contextLines(lines));\n            } else {\n              // end the range and output\n              var contextSize = Math.min(lines.length, 4);\n              ret.push(\n                  '@@ -' + oldRangeStart + ',' + (oldLine - oldRangeStart + contextSize)\n                  + ' +' + newRangeStart + ',' + (newLine - newRangeStart + contextSize)\n                  + ' @@');\n              ret.push.apply(ret, curRange);\n              ret.push.apply(ret, contextLines(lines.slice(0, contextSize)));\n              if (lines.length <= 4) {\n                eofNL(ret, i, current);\n              }\n\n              oldRangeStart = 0;\n              newRangeStart = 0;\n              curRange = [];\n            }\n          }\n          oldLine += lines.length;\n          newLine += lines.length;\n        }\n      }\n\n      return ret.join('\\n') + '\\n';\n    },\n\n    createPatch: function(fileName, oldStr, newStr, oldHeader, newHeader) {\n      return JsDiff.createTwoFilesPatch(fileName, fileName, oldStr, newStr, oldHeader, newHeader);\n    },\n\n    applyPatch: function(oldStr, uniDiff) {\n      var diffstr = uniDiff.split('\\n'),\n          hunks = [],\n          i = 0,\n          remEOFNL = false,\n          addEOFNL = false;\n\n      // Skip to the first change hunk\n      while (i < diffstr.length && !(/^@@/.test(diffstr[i]))) {\n        i++;\n      }\n\n      // Parse the unified diff\n      for (; i < diffstr.length; i++) {\n        if (diffstr[i][0] === '@') {\n          var chnukHeader = diffstr[i].split(/@@ -(\\d+),(\\d+) \\+(\\d+),(\\d+) @@/);\n          hunks.unshift({\n            start: chnukHeader[3],\n            oldlength: +chnukHeader[2],\n            removed: [],\n            newlength: chnukHeader[4],\n            added: []\n          });\n        } else if (diffstr[i][0] === '+') {\n          hunks[0].added.push(diffstr[i].substr(1));\n        } else if (diffstr[i][0] === '-') {\n          hunks[0].removed.push(diffstr[i].substr(1));\n        } else if (diffstr[i][0] === ' ') {\n          hunks[0].added.push(diffstr[i].substr(1));\n          hunks[0].removed.push(diffstr[i].substr(1));\n        } else if (diffstr[i][0] === '\\\\') {\n          if (diffstr[i - 1][0] === '+') {\n            remEOFNL = true;\n          } else if (diffstr[i - 1][0] === '-') {\n            addEOFNL = true;\n          }\n        }\n      }\n\n      // Apply the diff to the input\n      var lines = oldStr.split('\\n');\n      for (i = hunks.length - 1; i >= 0; i--) {\n        var hunk = hunks[i];\n        // Sanity check the input string. Bail if we don't match.\n        for (var j = 0; j < hunk.oldlength; j++) {\n          if (lines[hunk.start - 1 + j] !== hunk.removed[j]) {\n            return false;\n          }\n        }\n        Array.prototype.splice.apply(lines, [hunk.start - 1, hunk.oldlength].concat(hunk.added));\n      }\n\n      // Handle EOFNL insertion/removal\n      if (remEOFNL) {\n        while (!lines[lines.length - 1]) {\n          lines.pop();\n        }\n      } else if (addEOFNL) {\n        lines.push('');\n      }\n      return lines.join('\\n');\n    },\n\n    convertChangesToXML: function(changes) {\n      var ret = [];\n      for (var i = 0; i < changes.length; i++) {\n        var change = changes[i];\n        if (change.added) {\n          ret.push('<ins>');\n        } else if (change.removed) {\n          ret.push('<del>');\n        }\n\n        ret.push(escapeHTML(change.value));\n\n        if (change.added) {\n          ret.push('</ins>');\n        } else if (change.removed) {\n          ret.push('</del>');\n        }\n      }\n      return ret.join('');\n    },\n\n    // See: http://code.google.com/p/google-diff-match-patch/wiki/API\n    convertChangesToDMP: function(changes) {\n      var ret = [],\n          change,\n          operation;\n      for (var i = 0; i < changes.length; i++) {\n        change = changes[i];\n        if (change.added) {\n          operation = 1;\n        } else if (change.removed) {\n          operation = -1;\n        } else {\n          operation = 0;\n        }\n\n        ret.push([operation, change.value]);\n      }\n      return ret;\n    },\n\n    canonicalize: canonicalize\n  };\n\n  /*istanbul ignore next */\n  /*global module */\n  if (typeof module !== 'undefined' && module.exports) {\n    module.exports = JsDiff;\n  } else if (false) {\n    /*global define */\n    define([], function() { return JsDiff; });\n  } else if (typeof global.JsDiff === 'undefined') {\n    global.JsDiff = JsDiff;\n  }\n}(this));\n\n},{}],47:[function(require,module,exports){\n'use strict';\n\nvar matchOperatorsRe = /[|\\\\{}()[\\]^$+*?.]/g;\n\nmodule.exports = function (str) {\n\tif (typeof str !== 'string') {\n\t\tthrow new TypeError('Expected a string');\n\t}\n\n\treturn str.replace(matchOperatorsRe, '\\\\$&');\n};\n\n},{}],48:[function(require,module,exports){\n// Copyright Joyent, Inc. and other Node contributors.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a\n// copy of this software and associated documentation files (the\n// \"Software\"), to deal in the Software without restriction, including\n// without limitation the rights to use, copy, modify, merge, publish,\n// distribute, sublicense, and/or sell copies of the Software, and to permit\n// persons to whom the Software is furnished to do so, subject to the\n// following conditions:\n//\n// The above copyright notice and this permission notice shall be included\n// in all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS\n// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN\n// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,\n// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE\n// USE OR OTHER DEALINGS IN THE SOFTWARE.\n\nfunction EventEmitter() {\n  this._events = this._events || {};\n  this._maxListeners = this._maxListeners || undefined;\n}\nmodule.exports = EventEmitter;\n\n// Backwards-compat with node 0.10.x\nEventEmitter.EventEmitter = EventEmitter;\n\nEventEmitter.prototype._events = undefined;\nEventEmitter.prototype._maxListeners = undefined;\n\n// By default EventEmitters will print a warning if more than 10 listeners are\n// added to it. This is a useful default which helps finding memory leaks.\nEventEmitter.defaultMaxListeners = 10;\n\n// Obviously not all Emitters should be limited to 10. This function allows\n// that to be increased. Set to zero for unlimited.\nEventEmitter.prototype.setMaxListeners = function(n) {\n  if (!isNumber(n) || n < 0 || isNaN(n))\n    throw TypeError('n must be a positive number');\n  this._maxListeners = n;\n  return this;\n};\n\nEventEmitter.prototype.emit = function(type) {\n  var er, handler, len, args, i, listeners;\n\n  if (!this._events)\n    this._events = {};\n\n  // If there is no 'error' event listener then throw.\n  if (type === 'error') {\n    if (!this._events.error ||\n        (isObject(this._events.error) && !this._events.error.length)) {\n      er = arguments[1];\n      if (er instanceof Error) {\n        throw er; // Unhandled 'error' event\n      } else {\n        // At least give some kind of context to the user\n        var err = new Error('Uncaught, unspecified \"error\" event. (' + er + ')');\n        err.context = er;\n        throw err;\n      }\n    }\n  }\n\n  handler = this._events[type];\n\n  if (isUndefined(handler))\n    return false;\n\n  if (isFunction(handler)) {\n    switch (arguments.length) {\n      // fast cases\n      case 1:\n        handler.call(this);\n        break;\n      case 2:\n        handler.call(this, arguments[1]);\n        break;\n      case 3:\n        handler.call(this, arguments[1], arguments[2]);\n        break;\n      // slower\n      default:\n        args = Array.prototype.slice.call(arguments, 1);\n        handler.apply(this, args);\n    }\n  } else if (isObject(handler)) {\n    args = Array.prototype.slice.call(arguments, 1);\n    listeners = handler.slice();\n    len = listeners.length;\n    for (i = 0; i < len; i++)\n      listeners[i].apply(this, args);\n  }\n\n  return true;\n};\n\nEventEmitter.prototype.addListener = function(type, listener) {\n  var m;\n\n  if (!isFunction(listener))\n    throw TypeError('listener must be a function');\n\n  if (!this._events)\n    this._events = {};\n\n  // To avoid recursion in the case that type === \"newListener\"! Before\n  // adding it to the listeners, first emit \"newListener\".\n  if (this._events.newListener)\n    this.emit('newListener', type,\n              isFunction(listener.listener) ?\n              listener.listener : listener);\n\n  if (!this._events[type])\n    // Optimize the case of one listener. Don't need the extra array object.\n    this._events[type] = listener;\n  else if (isObject(this._events[type]))\n    // If we've already got an array, just append.\n    this._events[type].push(listener);\n  else\n    // Adding the second element, need to change to array.\n    this._events[type] = [this._events[type], listener];\n\n  // Check for listener leak\n  if (isObject(this._events[type]) && !this._events[type].warned) {\n    if (!isUndefined(this._maxListeners)) {\n      m = this._maxListeners;\n    } else {\n      m = EventEmitter.defaultMaxListeners;\n    }\n\n    if (m && m > 0 && this._events[type].length > m) {\n      this._events[type].warned = true;\n      console.error('(node) warning: possible EventEmitter memory ' +\n                    'leak detected. %d listeners added. ' +\n                    'Use emitter.setMaxListeners() to increase limit.',\n                    this._events[type].length);\n      if (typeof console.trace === 'function') {\n        // not supported in IE 10\n        console.trace();\n      }\n    }\n  }\n\n  return this;\n};\n\nEventEmitter.prototype.on = EventEmitter.prototype.addListener;\n\nEventEmitter.prototype.once = function(type, listener) {\n  if (!isFunction(listener))\n    throw TypeError('listener must be a function');\n\n  var fired = false;\n\n  function g() {\n    this.removeListener(type, g);\n\n    if (!fired) {\n      fired = true;\n      listener.apply(this, arguments);\n    }\n  }\n\n  g.listener = listener;\n  this.on(type, g);\n\n  return this;\n};\n\n// emits a 'removeListener' event iff the listener was removed\nEventEmitter.prototype.removeListener = function(type, listener) {\n  var list, position, length, i;\n\n  if (!isFunction(listener))\n    throw TypeError('listener must be a function');\n\n  if (!this._events || !this._events[type])\n    return this;\n\n  list = this._events[type];\n  length = list.length;\n  position = -1;\n\n  if (list === listener ||\n      (isFunction(list.listener) && list.listener === listener)) {\n    delete this._events[type];\n    if (this._events.removeListener)\n      this.emit('removeListener', type, listener);\n\n  } else if (isObject(list)) {\n    for (i = length; i-- > 0;) {\n      if (list[i] === listener ||\n          (list[i].listener && list[i].listener === listener)) {\n        position = i;\n        break;\n      }\n    }\n\n    if (position < 0)\n      return this;\n\n    if (list.length === 1) {\n      list.length = 0;\n      delete this._events[type];\n    } else {\n      list.splice(position, 1);\n    }\n\n    if (this._events.removeListener)\n      this.emit('removeListener', type, listener);\n  }\n\n  return this;\n};\n\nEventEmitter.prototype.removeAllListeners = function(type) {\n  var key, listeners;\n\n  if (!this._events)\n    return this;\n\n  // not listening for removeListener, no need to emit\n  if (!this._events.removeListener) {\n    if (arguments.length === 0)\n      this._events = {};\n    else if (this._events[type])\n      delete this._events[type];\n    return this;\n  }\n\n  // emit removeListener for all listeners on all events\n  if (arguments.length === 0) {\n    for (key in this._events) {\n      if (key === 'removeListener') continue;\n      this.removeAllListeners(key);\n    }\n    this.removeAllListeners('removeListener');\n    this._events = {};\n    return this;\n  }\n\n  listeners = this._events[type];\n\n  if (isFunction(listeners)) {\n    this.removeListener(type, listeners);\n  } else if (listeners) {\n    // LIFO order\n    while (listeners.length)\n      this.removeListener(type, listeners[listeners.length - 1]);\n  }\n  delete this._events[type];\n\n  return this;\n};\n\nEventEmitter.prototype.listeners = function(type) {\n  var ret;\n  if (!this._events || !this._events[type])\n    ret = [];\n  else if (isFunction(this._events[type]))\n    ret = [this._events[type]];\n  else\n    ret = this._events[type].slice();\n  return ret;\n};\n\nEventEmitter.prototype.listenerCount = function(type) {\n  if (this._events) {\n    var evlistener = this._events[type];\n\n    if (isFunction(evlistener))\n      return 1;\n    else if (evlistener)\n      return evlistener.length;\n  }\n  return 0;\n};\n\nEventEmitter.listenerCount = function(emitter, type) {\n  return emitter.listenerCount(type);\n};\n\nfunction isFunction(arg) {\n  return typeof arg === 'function';\n}\n\nfunction isNumber(arg) {\n  return typeof arg === 'number';\n}\n\nfunction isObject(arg) {\n  return typeof arg === 'object' && arg !== null;\n}\n\nfunction isUndefined(arg) {\n  return arg === void 0;\n}\n\n},{}],49:[function(require,module,exports){\n(function (process){\n// Growl - Copyright TJ Holowaychuk <tj@vision-media.ca> (MIT Licensed)\n\n/**\n * Module dependencies.\n */\n\nvar exec = require('child_process').exec\n  , fs = require('fs')\n  , path = require('path')\n  , exists = fs.existsSync || path.existsSync\n  , os = require('os')\n  , quote = JSON.stringify\n  , cmd;\n\nfunction which(name) {\n  var paths = process.env.PATH.split(':');\n  var loc;\n\n  for (var i = 0, len = paths.length; i < len; ++i) {\n    loc = path.join(paths[i], name);\n    if (exists(loc)) return loc;\n  }\n}\n\nswitch(os.type()) {\n  case 'Darwin':\n    if (which('terminal-notifier')) {\n      cmd = {\n          type: \"Darwin-NotificationCenter\"\n        , pkg: \"terminal-notifier\"\n        , msg: '-message'\n        , title: '-title'\n        , subtitle: '-subtitle'\n        , icon: '-appIcon'\n        , sound:  '-sound'\n        , url: '-open'\n        , priority: {\n              cmd: '-execute'\n            , range: []\n          }\n      };\n    } else {\n      cmd = {\n          type: \"Darwin-Growl\"\n        , pkg: \"growlnotify\"\n        , msg: '-m'\n        , sticky: '--sticky'\n        , priority: {\n              cmd: '--priority'\n            , range: [\n                -2\n              , -1\n              , 0\n              , 1\n              , 2\n              , \"Very Low\"\n              , \"Moderate\"\n              , \"Normal\"\n              , \"High\"\n              , \"Emergency\"\n            ]\n          }\n      };\n    }\n    break;\n  case 'Linux':\n    if (which('growl')) {\n      cmd = {\n          type: \"Linux-Growl\"\n        , pkg: \"growl\"\n        , msg: '-m'\n        , title: '-title'\n        , subtitle: '-subtitle'\n        , host: {\n            cmd: '-H'\n          , hostname: '192.168.33.1'\n        }\n      };\n    } else {\n      cmd = {\n          type: \"Linux\"\n        , pkg: \"notify-send\"\n        , msg: ''\n        , sticky: '-t 0'\n        , icon: '-i'\n        , priority: {\n            cmd: '-u'\n          , range: [\n              \"low\"\n            , \"normal\"\n            , \"critical\"\n          ]\n        }\n      };\n    }\n    break;\n  case 'Windows_NT':\n    cmd = {\n        type: \"Windows\"\n      , pkg: \"growlnotify\"\n      , msg: ''\n      , sticky: '/s:true'\n      , title: '/t:'\n      , icon: '/i:'\n      , url: '/cu:'\n      , priority: {\n            cmd: '/p:'\n          , range: [\n              -2\n            , -1\n            , 0\n            , 1\n            , 2\n          ]\n        }\n    };\n    break;\n}\n\n/**\n * Expose `growl`.\n */\n\nexports = module.exports = growl;\n\n/**\n * Node-growl version.\n */\n\nexports.version = '1.4.1'\n\n/**\n * Send growl notification _msg_ with _options_.\n *\n * Options:\n *\n *  - title   Notification title\n *  - sticky  Make the notification stick (defaults to false)\n *  - priority  Specify an int or named key (default is 0)\n *  - name    Application name (defaults to growlnotify)\n *  - sound   Sound efect ( in OSx defined in preferences -> sound -> effects) * works only in OSX > 10.8x\n *  - image\n *    - path to an icon sets --iconpath\n *    - path to an image sets --image\n *    - capitalized word sets --appIcon\n *    - filename uses extname as --icon\n *    - otherwise treated as --icon\n *\n * Examples:\n *\n *   growl('New email')\n *   growl('5 new emails', { title: 'Thunderbird' })\n *   growl('5 new emails', { title: 'Thunderbird', sound: 'Purr' })\n *   growl('Email sent', function(){\n *     // ... notification sent\n *   })\n *\n * @param {string} msg\n * @param {object} options\n * @param {function} fn\n * @api public\n */\n\nfunction growl(msg, options, fn) {\n  var image\n    , args\n    , options = options || {}\n    , fn = fn || function(){};\n\n  if (options.exec) {\n    cmd = {\n        type: \"Custom\"\n      , pkg: options.exec\n      , range: []\n    };\n  }\n\n  // noop\n  if (!cmd) return fn(new Error('growl not supported on this platform'));\n  args = [cmd.pkg];\n\n  // image\n  if (image = options.image) {\n    switch(cmd.type) {\n      case 'Darwin-Growl':\n        var flag, ext = path.extname(image).substr(1)\n        flag = flag || ext == 'icns' && 'iconpath'\n        flag = flag || /^[A-Z]/.test(image) && 'appIcon'\n        flag = flag || /^png|gif|jpe?g$/.test(ext) && 'image'\n        flag = flag || ext && (image = ext) && 'icon'\n        flag = flag || 'icon'\n        args.push('--' + flag, quote(image))\n        break;\n      case 'Darwin-NotificationCenter':\n        args.push(cmd.icon, quote(image));\n        break;\n      case 'Linux':\n        args.push(cmd.icon, quote(image));\n        // libnotify defaults to sticky, set a hint for transient notifications\n        if (!options.sticky) args.push('--hint=int:transient:1');\n        break;\n      case 'Windows':\n        args.push(cmd.icon + quote(image));\n        break;\n    }\n  }\n\n  // sticky\n  if (options.sticky) args.push(cmd.sticky);\n\n  // priority\n  if (options.priority) {\n    var priority = options.priority + '';\n    var checkindexOf = cmd.priority.range.indexOf(priority);\n    if (~cmd.priority.range.indexOf(priority)) {\n      args.push(cmd.priority, options.priority);\n    }\n  }\n\n  //sound\n  if(options.sound && cmd.type === 'Darwin-NotificationCenter'){\n    args.push(cmd.sound, options.sound)\n  }\n\n  // name\n  if (options.name && cmd.type === \"Darwin-Growl\") {\n    args.push('--name', options.name);\n  }\n\n  switch(cmd.type) {\n    case 'Darwin-Growl':\n      args.push(cmd.msg);\n      args.push(quote(msg).replace(/\\\\n/g, '\\n'));\n      if (options.title) args.push(quote(options.title));\n      break;\n    case 'Darwin-NotificationCenter':\n      args.push(cmd.msg);\n      var stringifiedMsg = quote(msg);\n      var escapedMsg = stringifiedMsg.replace(/\\\\n/g, '\\n');\n      args.push(escapedMsg);\n      if (options.title) {\n        args.push(cmd.title);\n        args.push(quote(options.title));\n      }\n      if (options.subtitle) {\n        args.push(cmd.subtitle);\n        args.push(quote(options.subtitle));\n      }\n      if (options.url) {\n        args.push(cmd.url);\n        args.push(quote(options.url));\n      }\n      break;\n    case 'Linux-Growl':\n      args.push(cmd.msg);\n      args.push(quote(msg).replace(/\\\\n/g, '\\n'));\n      if (options.title) args.push(quote(options.title));\n      if (cmd.host) {\n        args.push(cmd.host.cmd, cmd.host.hostname)\n      }\n      break;\n    case 'Linux':\n      if (options.title) {\n        args.push(quote(options.title));\n        args.push(cmd.msg);\n        args.push(quote(msg).replace(/\\\\n/g, '\\n'));\n      } else {\n        args.push(quote(msg).replace(/\\\\n/g, '\\n'));\n      }\n      break;\n    case 'Windows':\n      args.push(quote(msg).replace(/\\\\n/g, '\\n'));\n      if (options.title) args.push(cmd.title + quote(options.title));\n      if (options.url) args.push(cmd.url + quote(options.url));\n      break;\n    case 'Custom':\n      args[0] = (function(origCommand) {\n        var message = options.title\n          ? options.title + ': ' + msg\n          : msg;\n        var command = origCommand.replace(/(^|[^%])%s/g, '$1' + quote(message));\n        if (command === origCommand) args.push(quote(message));\n        return command;\n      })(args[0]);\n      break;\n  }\n\n  // execute\n  exec(args.join(' '), fn);\n};\n\n}).call(this,require('_process'))\n},{\"_process\":67,\"child_process\":42,\"fs\":42,\"os\":65,\"path\":42}],50:[function(require,module,exports){\nexports.read = function (buffer, offset, isLE, mLen, nBytes) {\n  var e, m\n  var eLen = nBytes * 8 - mLen - 1\n  var eMax = (1 << eLen) - 1\n  var eBias = eMax >> 1\n  var nBits = -7\n  var i = isLE ? (nBytes - 1) : 0\n  var d = isLE ? -1 : 1\n  var s = buffer[offset + i]\n\n  i += d\n\n  e = s & ((1 << (-nBits)) - 1)\n  s >>= (-nBits)\n  nBits += eLen\n  for (; nBits > 0; e = e * 256 + buffer[offset + i], i += d, nBits -= 8) {}\n\n  m = e & ((1 << (-nBits)) - 1)\n  e >>= (-nBits)\n  nBits += mLen\n  for (; nBits > 0; m = m * 256 + buffer[offset + i], i += d, nBits -= 8) {}\n\n  if (e === 0) {\n    e = 1 - eBias\n  } else if (e === eMax) {\n    return m ? NaN : ((s ? -1 : 1) * Infinity)\n  } else {\n    m = m + Math.pow(2, mLen)\n    e = e - eBias\n  }\n  return (s ? -1 : 1) * m * Math.pow(2, e - mLen)\n}\n\nexports.write = function (buffer, value, offset, isLE, mLen, nBytes) {\n  var e, m, c\n  var eLen = nBytes * 8 - mLen - 1\n  var eMax = (1 << eLen) - 1\n  var eBias = eMax >> 1\n  var rt = (mLen === 23 ? Math.pow(2, -24) - Math.pow(2, -77) : 0)\n  var i = isLE ? 0 : (nBytes - 1)\n  var d = isLE ? 1 : -1\n  var s = value < 0 || (value === 0 && 1 / value < 0) ? 1 : 0\n\n  value = Math.abs(value)\n\n  if (isNaN(value) || value === Infinity) {\n    m = isNaN(value) ? 1 : 0\n    e = eMax\n  } else {\n    e = Math.floor(Math.log(value) / Math.LN2)\n    if (value * (c = Math.pow(2, -e)) < 1) {\n      e--\n      c *= 2\n    }\n    if (e + eBias >= 1) {\n      value += rt / c\n    } else {\n      value += rt * Math.pow(2, 1 - eBias)\n    }\n    if (value * c >= 2) {\n      e++\n      c /= 2\n    }\n\n    if (e + eBias >= eMax) {\n      m = 0\n      e = eMax\n    } else if (e + eBias >= 1) {\n      m = (value * c - 1) * Math.pow(2, mLen)\n      e = e + eBias\n    } else {\n      m = value * Math.pow(2, eBias - 1) * Math.pow(2, mLen)\n      e = 0\n    }\n  }\n\n  for (; mLen >= 8; buffer[offset + i] = m & 0xff, i += d, m /= 256, mLen -= 8) {}\n\n  e = (e << mLen) | m\n  eLen += mLen\n  for (; eLen > 0; buffer[offset + i] = e & 0xff, i += d, e /= 256, eLen -= 8) {}\n\n  buffer[offset + i - d] |= s * 128\n}\n\n},{}],51:[function(require,module,exports){\nif (typeof Object.create === 'function') {\n  // implementation from standard node.js 'util' module\n  module.exports = function inherits(ctor, superCtor) {\n    ctor.super_ = superCtor\n    ctor.prototype = Object.create(superCtor.prototype, {\n      constructor: {\n        value: ctor,\n        enumerable: false,\n        writable: true,\n        configurable: true\n      }\n    });\n  };\n} else {\n  // old school shim for old browsers\n  module.exports = function inherits(ctor, superCtor) {\n    ctor.super_ = superCtor\n    var TempCtor = function () {}\n    TempCtor.prototype = superCtor.prototype\n    ctor.prototype = new TempCtor()\n    ctor.prototype.constructor = ctor\n  }\n}\n\n},{}],52:[function(require,module,exports){\n/*!\n * Determine if an object is a Buffer\n *\n * @author   Feross Aboukhadijeh <feross@feross.org> <http://feross.org>\n * @license  MIT\n */\n\n// The _isBuffer check is for Safari 5-7 support, because it's missing\n// Object.prototype.constructor. Remove this eventually\nmodule.exports = function (obj) {\n  return obj != null && (isBuffer(obj) || isSlowBuffer(obj) || !!obj._isBuffer)\n}\n\nfunction isBuffer (obj) {\n  return !!obj.constructor && typeof obj.constructor.isBuffer === 'function' && obj.constructor.isBuffer(obj)\n}\n\n// For Node v0.10 support. Remove this eventually.\nfunction isSlowBuffer (obj) {\n  return typeof obj.readFloatLE === 'function' && typeof obj.slice === 'function' && isBuffer(obj.slice(0, 0))\n}\n\n},{}],53:[function(require,module,exports){\nvar toString = {}.toString;\n\nmodule.exports = Array.isArray || function (arr) {\n  return toString.call(arr) == '[object Array]';\n};\n\n},{}],54:[function(require,module,exports){\n(function (global){\n/*! JSON v3.3.2 | http://bestiejs.github.io/json3 | Copyright 2012-2014, Kit Cambridge | http://kit.mit-license.org */\n;(function () {\n  // Detect the `define` function exposed by asynchronous module loaders. The\n  // strict `define` check is necessary for compatibility with `r.js`.\n  var isLoader = false;\n\n  // A set of types used to distinguish objects from primitives.\n  var objectTypes = {\n    \"function\": true,\n    \"object\": true\n  };\n\n  // Detect the `exports` object exposed by CommonJS implementations.\n  var freeExports = objectTypes[typeof exports] && exports && !exports.nodeType && exports;\n\n  // Use the `global` object exposed by Node (including Browserify via\n  // `insert-module-globals`), Narwhal, and Ringo as the default context,\n  // and the `window` object in browsers. Rhino exports a `global` function\n  // instead.\n  var root = objectTypes[typeof window] && window || this,\n      freeGlobal = freeExports && objectTypes[typeof module] && module && !module.nodeType && typeof global == \"object\" && global;\n\n  if (freeGlobal && (freeGlobal[\"global\"] === freeGlobal || freeGlobal[\"window\"] === freeGlobal || freeGlobal[\"self\"] === freeGlobal)) {\n    root = freeGlobal;\n  }\n\n  // Public: Initializes JSON 3 using the given `context` object, attaching the\n  // `stringify` and `parse` functions to the specified `exports` object.\n  function runInContext(context, exports) {\n    context || (context = root[\"Object\"]());\n    exports || (exports = root[\"Object\"]());\n\n    // Native constructor aliases.\n    var Number = context[\"Number\"] || root[\"Number\"],\n        String = context[\"String\"] || root[\"String\"],\n        Object = context[\"Object\"] || root[\"Object\"],\n        Date = context[\"Date\"] || root[\"Date\"],\n        SyntaxError = context[\"SyntaxError\"] || root[\"SyntaxError\"],\n        TypeError = context[\"TypeError\"] || root[\"TypeError\"],\n        Math = context[\"Math\"] || root[\"Math\"],\n        nativeJSON = context[\"JSON\"] || root[\"JSON\"];\n\n    // Delegate to the native `stringify` and `parse` implementations.\n    if (typeof nativeJSON == \"object\" && nativeJSON) {\n      exports.stringify = nativeJSON.stringify;\n      exports.parse = nativeJSON.parse;\n    }\n\n    // Convenience aliases.\n    var objectProto = Object.prototype,\n        getClass = objectProto.toString,\n        isProperty, forEach, undef;\n\n    // Test the `Date#getUTC*` methods. Based on work by @Yaffle.\n    var isExtended = new Date(-3509827334573292);\n    try {\n      // The `getUTCFullYear`, `Month`, and `Date` methods return nonsensical\n      // results for certain dates in Opera >= 10.53.\n      isExtended = isExtended.getUTCFullYear() == -109252 && isExtended.getUTCMonth() === 0 && isExtended.getUTCDate() === 1 &&\n        // Safari < 2.0.2 stores the internal millisecond time value correctly,\n        // but clips the values returned by the date methods to the range of\n        // signed 32-bit integers ([-2 ** 31, 2 ** 31 - 1]).\n        isExtended.getUTCHours() == 10 && isExtended.getUTCMinutes() == 37 && isExtended.getUTCSeconds() == 6 && isExtended.getUTCMilliseconds() == 708;\n    } catch (exception) {}\n\n    // Internal: Determines whether the native `JSON.stringify` and `parse`\n    // implementations are spec-compliant. Based on work by Ken Snyder.\n    function has(name) {\n      if (has[name] !== undef) {\n        // Return cached feature test result.\n        return has[name];\n      }\n      var isSupported;\n      if (name == \"bug-string-char-index\") {\n        // IE <= 7 doesn't support accessing string characters using square\n        // bracket notation. IE 8 only supports this for primitives.\n        isSupported = \"a\"[0] != \"a\";\n      } else if (name == \"json\") {\n        // Indicates whether both `JSON.stringify` and `JSON.parse` are\n        // supported.\n        isSupported = has(\"json-stringify\") && has(\"json-parse\");\n      } else {\n        var value, serialized = '{\"a\":[1,true,false,null,\"\\\\u0000\\\\b\\\\n\\\\f\\\\r\\\\t\"]}';\n        // Test `JSON.stringify`.\n        if (name == \"json-stringify\") {\n          var stringify = exports.stringify, stringifySupported = typeof stringify == \"function\" && isExtended;\n          if (stringifySupported) {\n            // A test function object with a custom `toJSON` method.\n            (value = function () {\n              return 1;\n            }).toJSON = value;\n            try {\n              stringifySupported =\n                // Firefox 3.1b1 and b2 serialize string, number, and boolean\n                // primitives as object literals.\n                stringify(0) === \"0\" &&\n                // FF 3.1b1, b2, and JSON 2 serialize wrapped primitives as object\n                // literals.\n                stringify(new Number()) === \"0\" &&\n                stringify(new String()) == '\"\"' &&\n                // FF 3.1b1, 2 throw an error if the value is `null`, `undefined`, or\n                // does not define a canonical JSON representation (this applies to\n                // objects with `toJSON` properties as well, *unless* they are nested\n                // within an object or array).\n                stringify(getClass) === undef &&\n                // IE 8 serializes `undefined` as `\"undefined\"`. Safari <= 5.1.7 and\n                // FF 3.1b3 pass this test.\n                stringify(undef) === undef &&\n                // Safari <= 5.1.7 and FF 3.1b3 throw `Error`s and `TypeError`s,\n                // respectively, if the value is omitted entirely.\n                stringify() === undef &&\n                // FF 3.1b1, 2 throw an error if the given value is not a number,\n                // string, array, object, Boolean, or `null` literal. This applies to\n                // objects with custom `toJSON` methods as well, unless they are nested\n                // inside object or array literals. YUI 3.0.0b1 ignores custom `toJSON`\n                // methods entirely.\n                stringify(value) === \"1\" &&\n                stringify([value]) == \"[1]\" &&\n                // Prototype <= 1.6.1 serializes `[undefined]` as `\"[]\"` instead of\n                // `\"[null]\"`.\n                stringify([undef]) == \"[null]\" &&\n                // YUI 3.0.0b1 fails to serialize `null` literals.\n                stringify(null) == \"null\" &&\n                // FF 3.1b1, 2 halts serialization if an array contains a function:\n                // `[1, true, getClass, 1]` serializes as \"[1,true,],\". FF 3.1b3\n                // elides non-JSON values from objects and arrays, unless they\n                // define custom `toJSON` methods.\n                stringify([undef, getClass, null]) == \"[null,null,null]\" &&\n                // Simple serialization test. FF 3.1b1 uses Unicode escape sequences\n                // where character escape codes are expected (e.g., `\\b` => `\\u0008`).\n                stringify({ \"a\": [value, true, false, null, \"\\x00\\b\\n\\f\\r\\t\"] }) == serialized &&\n                // FF 3.1b1 and b2 ignore the `filter` and `width` arguments.\n                stringify(null, value) === \"1\" &&\n                stringify([1, 2], null, 1) == \"[\\n 1,\\n 2\\n]\" &&\n                // JSON 2, Prototype <= 1.7, and older WebKit builds incorrectly\n                // serialize extended years.\n                stringify(new Date(-8.64e15)) == '\"-271821-04-20T00:00:00.000Z\"' &&\n                // The milliseconds are optional in ES 5, but required in 5.1.\n                stringify(new Date(8.64e15)) == '\"+275760-09-13T00:00:00.000Z\"' &&\n                // Firefox <= 11.0 incorrectly serializes years prior to 0 as negative\n                // four-digit years instead of six-digit years. Credits: @Yaffle.\n                stringify(new Date(-621987552e5)) == '\"-000001-01-01T00:00:00.000Z\"' &&\n                // Safari <= 5.1.5 and Opera >= 10.53 incorrectly serialize millisecond\n                // values less than 1000. Credits: @Yaffle.\n                stringify(new Date(-1)) == '\"1969-12-31T23:59:59.999Z\"';\n            } catch (exception) {\n              stringifySupported = false;\n            }\n          }\n          isSupported = stringifySupported;\n        }\n        // Test `JSON.parse`.\n        if (name == \"json-parse\") {\n          var parse = exports.parse;\n          if (typeof parse == \"function\") {\n            try {\n              // FF 3.1b1, b2 will throw an exception if a bare literal is provided.\n              // Conforming implementations should also coerce the initial argument to\n              // a string prior to parsing.\n              if (parse(\"0\") === 0 && !parse(false)) {\n                // Simple parsing test.\n                value = parse(serialized);\n                var parseSupported = value[\"a\"].length == 5 && value[\"a\"][0] === 1;\n                if (parseSupported) {\n                  try {\n                    // Safari <= 5.1.2 and FF 3.1b1 allow unescaped tabs in strings.\n                    parseSupported = !parse('\"\\t\"');\n                  } catch (exception) {}\n                  if (parseSupported) {\n                    try {\n                      // FF 4.0 and 4.0.1 allow leading `+` signs and leading\n                      // decimal points. FF 4.0, 4.0.1, and IE 9-10 also allow\n                      // certain octal literals.\n                      parseSupported = parse(\"01\") !== 1;\n                    } catch (exception) {}\n                  }\n                  if (parseSupported) {\n                    try {\n                      // FF 4.0, 4.0.1, and Rhino 1.7R3-R4 allow trailing decimal\n                      // points. These environments, along with FF 3.1b1 and 2,\n                      // also allow trailing commas in JSON objects and arrays.\n                      parseSupported = parse(\"1.\") !== 1;\n                    } catch (exception) {}\n                  }\n                }\n              }\n            } catch (exception) {\n              parseSupported = false;\n            }\n          }\n          isSupported = parseSupported;\n        }\n      }\n      return has[name] = !!isSupported;\n    }\n\n    if (!has(\"json\")) {\n      // Common `[[Class]]` name aliases.\n      var functionClass = \"[object Function]\",\n          dateClass = \"[object Date]\",\n          numberClass = \"[object Number]\",\n          stringClass = \"[object String]\",\n          arrayClass = \"[object Array]\",\n          booleanClass = \"[object Boolean]\";\n\n      // Detect incomplete support for accessing string characters by index.\n      var charIndexBuggy = has(\"bug-string-char-index\");\n\n      // Define additional utility methods if the `Date` methods are buggy.\n      if (!isExtended) {\n        var floor = Math.floor;\n        // A mapping between the months of the year and the number of days between\n        // January 1st and the first of the respective month.\n        var Months = [0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334];\n        // Internal: Calculates the number of days between the Unix epoch and the\n        // first day of the given month.\n        var getDay = function (year, month) {\n          return Months[month] + 365 * (year - 1970) + floor((year - 1969 + (month = +(month > 1))) / 4) - floor((year - 1901 + month) / 100) + floor((year - 1601 + month) / 400);\n        };\n      }\n\n      // Internal: Determines if a property is a direct property of the given\n      // object. Delegates to the native `Object#hasOwnProperty` method.\n      if (!(isProperty = objectProto.hasOwnProperty)) {\n        isProperty = function (property) {\n          var members = {}, constructor;\n          if ((members.__proto__ = null, members.__proto__ = {\n            // The *proto* property cannot be set multiple times in recent\n            // versions of Firefox and SeaMonkey.\n            \"toString\": 1\n          }, members).toString != getClass) {\n            // Safari <= 2.0.3 doesn't implement `Object#hasOwnProperty`, but\n            // supports the mutable *proto* property.\n            isProperty = function (property) {\n              // Capture and break the object's prototype chain (see section 8.6.2\n              // of the ES 5.1 spec). The parenthesized expression prevents an\n              // unsafe transformation by the Closure Compiler.\n              var original = this.__proto__, result = property in (this.__proto__ = null, this);\n              // Restore the original prototype chain.\n              this.__proto__ = original;\n              return result;\n            };\n          } else {\n            // Capture a reference to the top-level `Object` constructor.\n            constructor = members.constructor;\n            // Use the `constructor` property to simulate `Object#hasOwnProperty` in\n            // other environments.\n            isProperty = function (property) {\n              var parent = (this.constructor || constructor).prototype;\n              return property in this && !(property in parent && this[property] === parent[property]);\n            };\n          }\n          members = null;\n          return isProperty.call(this, property);\n        };\n      }\n\n      // Internal: Normalizes the `for...in` iteration algorithm across\n      // environments. Each enumerated key is yielded to a `callback` function.\n      forEach = function (object, callback) {\n        var size = 0, Properties, members, property;\n\n        // Tests for bugs in the current environment's `for...in` algorithm. The\n        // `valueOf` property inherits the non-enumerable flag from\n        // `Object.prototype` in older versions of IE, Netscape, and Mozilla.\n        (Properties = function () {\n          this.valueOf = 0;\n        }).prototype.valueOf = 0;\n\n        // Iterate over a new instance of the `Properties` class.\n        members = new Properties();\n        for (property in members) {\n          // Ignore all properties inherited from `Object.prototype`.\n          if (isProperty.call(members, property)) {\n            size++;\n          }\n        }\n        Properties = members = null;\n\n        // Normalize the iteration algorithm.\n        if (!size) {\n          // A list of non-enumerable properties inherited from `Object.prototype`.\n          members = [\"valueOf\", \"toString\", \"toLocaleString\", \"propertyIsEnumerable\", \"isPrototypeOf\", \"hasOwnProperty\", \"constructor\"];\n          // IE <= 8, Mozilla 1.0, and Netscape 6.2 ignore shadowed non-enumerable\n          // properties.\n          forEach = function (object, callback) {\n            var isFunction = getClass.call(object) == functionClass, property, length;\n            var hasProperty = !isFunction && typeof object.constructor != \"function\" && objectTypes[typeof object.hasOwnProperty] && object.hasOwnProperty || isProperty;\n            for (property in object) {\n              // Gecko <= 1.0 enumerates the `prototype` property of functions under\n              // certain conditions; IE does not.\n              if (!(isFunction && property == \"prototype\") && hasProperty.call(object, property)) {\n                callback(property);\n              }\n            }\n            // Manually invoke the callback for each non-enumerable property.\n            for (length = members.length; property = members[--length]; hasProperty.call(object, property) && callback(property));\n          };\n        } else if (size == 2) {\n          // Safari <= 2.0.4 enumerates shadowed properties twice.\n          forEach = function (object, callback) {\n            // Create a set of iterated properties.\n            var members = {}, isFunction = getClass.call(object) == functionClass, property;\n            for (property in object) {\n              // Store each property name to prevent double enumeration. The\n              // `prototype` property of functions is not enumerated due to cross-\n              // environment inconsistencies.\n              if (!(isFunction && property == \"prototype\") && !isProperty.call(members, property) && (members[property] = 1) && isProperty.call(object, property)) {\n                callback(property);\n              }\n            }\n          };\n        } else {\n          // No bugs detected; use the standard `for...in` algorithm.\n          forEach = function (object, callback) {\n            var isFunction = getClass.call(object) == functionClass, property, isConstructor;\n            for (property in object) {\n              if (!(isFunction && property == \"prototype\") && isProperty.call(object, property) && !(isConstructor = property === \"constructor\")) {\n                callback(property);\n              }\n            }\n            // Manually invoke the callback for the `constructor` property due to\n            // cross-environment inconsistencies.\n            if (isConstructor || isProperty.call(object, (property = \"constructor\"))) {\n              callback(property);\n            }\n          };\n        }\n        return forEach(object, callback);\n      };\n\n      // Public: Serializes a JavaScript `value` as a JSON string. The optional\n      // `filter` argument may specify either a function that alters how object and\n      // array members are serialized, or an array of strings and numbers that\n      // indicates which properties should be serialized. The optional `width`\n      // argument may be either a string or number that specifies the indentation\n      // level of the output.\n      if (!has(\"json-stringify\")) {\n        // Internal: A map of control characters and their escaped equivalents.\n        var Escapes = {\n          92: \"\\\\\\\\\",\n          34: '\\\\\"',\n          8: \"\\\\b\",\n          12: \"\\\\f\",\n          10: \"\\\\n\",\n          13: \"\\\\r\",\n          9: \"\\\\t\"\n        };\n\n        // Internal: Converts `value` into a zero-padded string such that its\n        // length is at least equal to `width`. The `width` must be <= 6.\n        var leadingZeroes = \"000000\";\n        var toPaddedString = function (width, value) {\n          // The `|| 0` expression is necessary to work around a bug in\n          // Opera <= 7.54u2 where `0 == -0`, but `String(-0) !== \"0\"`.\n          return (leadingZeroes + (value || 0)).slice(-width);\n        };\n\n        // Internal: Double-quotes a string `value`, replacing all ASCII control\n        // characters (characters with code unit values between 0 and 31) with\n        // their escaped equivalents. This is an implementation of the\n        // `Quote(value)` operation defined in ES 5.1 section 15.12.3.\n        var unicodePrefix = \"\\\\u00\";\n        var quote = function (value) {\n          var result = '\"', index = 0, length = value.length, useCharIndex = !charIndexBuggy || length > 10;\n          var symbols = useCharIndex && (charIndexBuggy ? value.split(\"\") : value);\n          for (; index < length; index++) {\n            var charCode = value.charCodeAt(index);\n            // If the character is a control character, append its Unicode or\n            // shorthand escape sequence; otherwise, append the character as-is.\n            switch (charCode) {\n              case 8: case 9: case 10: case 12: case 13: case 34: case 92:\n                result += Escapes[charCode];\n                break;\n              default:\n                if (charCode < 32) {\n                  result += unicodePrefix + toPaddedString(2, charCode.toString(16));\n                  break;\n                }\n                result += useCharIndex ? symbols[index] : value.charAt(index);\n            }\n          }\n          return result + '\"';\n        };\n\n        // Internal: Recursively serializes an object. Implements the\n        // `Str(key, holder)`, `JO(value)`, and `JA(value)` operations.\n        var serialize = function (property, object, callback, properties, whitespace, indentation, stack) {\n          var value, className, year, month, date, time, hours, minutes, seconds, milliseconds, results, element, index, length, prefix, result;\n          try {\n            // Necessary for host object support.\n            value = object[property];\n          } catch (exception) {}\n          if (typeof value == \"object\" && value) {\n            className = getClass.call(value);\n            if (className == dateClass && !isProperty.call(value, \"toJSON\")) {\n              if (value > -1 / 0 && value < 1 / 0) {\n                // Dates are serialized according to the `Date#toJSON` method\n                // specified in ES 5.1 section 15.9.5.44. See section 15.9.1.15\n                // for the ISO 8601 date time string format.\n                if (getDay) {\n                  // Manually compute the year, month, date, hours, minutes,\n                  // seconds, and milliseconds if the `getUTC*` methods are\n                  // buggy. Adapted from @Yaffle's `date-shim` project.\n                  date = floor(value / 864e5);\n                  for (year = floor(date / 365.2425) + 1970 - 1; getDay(year + 1, 0) <= date; year++);\n                  for (month = floor((date - getDay(year, 0)) / 30.42); getDay(year, month + 1) <= date; month++);\n                  date = 1 + date - getDay(year, month);\n                  // The `time` value specifies the time within the day (see ES\n                  // 5.1 section 15.9.1.2). The formula `(A % B + B) % B` is used\n                  // to compute `A modulo B`, as the `%` operator does not\n                  // correspond to the `modulo` operation for negative numbers.\n                  time = (value % 864e5 + 864e5) % 864e5;\n                  // The hours, minutes, seconds, and milliseconds are obtained by\n                  // decomposing the time within the day. See section 15.9.1.10.\n                  hours = floor(time / 36e5) % 24;\n                  minutes = floor(time / 6e4) % 60;\n                  seconds = floor(time / 1e3) % 60;\n                  milliseconds = time % 1e3;\n                } else {\n                  year = value.getUTCFullYear();\n                  month = value.getUTCMonth();\n                  date = value.getUTCDate();\n                  hours = value.getUTCHours();\n                  minutes = value.getUTCMinutes();\n                  seconds = value.getUTCSeconds();\n                  milliseconds = value.getUTCMilliseconds();\n                }\n                // Serialize extended years correctly.\n                value = (year <= 0 || year >= 1e4 ? (year < 0 ? \"-\" : \"+\") + toPaddedString(6, year < 0 ? -year : year) : toPaddedString(4, year)) +\n                  \"-\" + toPaddedString(2, month + 1) + \"-\" + toPaddedString(2, date) +\n                  // Months, dates, hours, minutes, and seconds should have two\n                  // digits; milliseconds should have three.\n                  \"T\" + toPaddedString(2, hours) + \":\" + toPaddedString(2, minutes) + \":\" + toPaddedString(2, seconds) +\n                  // Milliseconds are optional in ES 5.0, but required in 5.1.\n                  \".\" + toPaddedString(3, milliseconds) + \"Z\";\n              } else {\n                value = null;\n              }\n            } else if (typeof value.toJSON == \"function\" && ((className != numberClass && className != stringClass && className != arrayClass) || isProperty.call(value, \"toJSON\"))) {\n              // Prototype <= 1.6.1 adds non-standard `toJSON` methods to the\n              // `Number`, `String`, `Date`, and `Array` prototypes. JSON 3\n              // ignores all `toJSON` methods on these objects unless they are\n              // defined directly on an instance.\n              value = value.toJSON(property);\n            }\n          }\n          if (callback) {\n            // If a replacement function was provided, call it to obtain the value\n            // for serialization.\n            value = callback.call(object, property, value);\n          }\n          if (value === null) {\n            return \"null\";\n          }\n          className = getClass.call(value);\n          if (className == booleanClass) {\n            // Booleans are represented literally.\n            return \"\" + value;\n          } else if (className == numberClass) {\n            // JSON numbers must be finite. `Infinity` and `NaN` are serialized as\n            // `\"null\"`.\n            return value > -1 / 0 && value < 1 / 0 ? \"\" + value : \"null\";\n          } else if (className == stringClass) {\n            // Strings are double-quoted and escaped.\n            return quote(\"\" + value);\n          }\n          // Recursively serialize objects and arrays.\n          if (typeof value == \"object\") {\n            // Check for cyclic structures. This is a linear search; performance\n            // is inversely proportional to the number of unique nested objects.\n            for (length = stack.length; length--;) {\n              if (stack[length] === value) {\n                // Cyclic structures cannot be serialized by `JSON.stringify`.\n                throw TypeError();\n              }\n            }\n            // Add the object to the stack of traversed objects.\n            stack.push(value);\n            results = [];\n            // Save the current indentation level and indent one additional level.\n            prefix = indentation;\n            indentation += whitespace;\n            if (className == arrayClass) {\n              // Recursively serialize array elements.\n              for (index = 0, length = value.length; index < length; index++) {\n                element = serialize(index, value, callback, properties, whitespace, indentation, stack);\n                results.push(element === undef ? \"null\" : element);\n              }\n              result = results.length ? (whitespace ? \"[\\n\" + indentation + results.join(\",\\n\" + indentation) + \"\\n\" + prefix + \"]\" : (\"[\" + results.join(\",\") + \"]\")) : \"[]\";\n            } else {\n              // Recursively serialize object members. Members are selected from\n              // either a user-specified list of property names, or the object\n              // itself.\n              forEach(properties || value, function (property) {\n                var element = serialize(property, value, callback, properties, whitespace, indentation, stack);\n                if (element !== undef) {\n                  // According to ES 5.1 section 15.12.3: \"If `gap` {whitespace}\n                  // is not the empty string, let `member` {quote(property) + \":\"}\n                  // be the concatenation of `member` and the `space` character.\"\n                  // The \"`space` character\" refers to the literal space\n                  // character, not the `space` {width} argument provided to\n                  // `JSON.stringify`.\n                  results.push(quote(property) + \":\" + (whitespace ? \" \" : \"\") + element);\n                }\n              });\n              result = results.length ? (whitespace ? \"{\\n\" + indentation + results.join(\",\\n\" + indentation) + \"\\n\" + prefix + \"}\" : (\"{\" + results.join(\",\") + \"}\")) : \"{}\";\n            }\n            // Remove the object from the traversed object stack.\n            stack.pop();\n            return result;\n          }\n        };\n\n        // Public: `JSON.stringify`. See ES 5.1 section 15.12.3.\n        exports.stringify = function (source, filter, width) {\n          var whitespace, callback, properties, className;\n          if (objectTypes[typeof filter] && filter) {\n            if ((className = getClass.call(filter)) == functionClass) {\n              callback = filter;\n            } else if (className == arrayClass) {\n              // Convert the property names array into a makeshift set.\n              properties = {};\n              for (var index = 0, length = filter.length, value; index < length; value = filter[index++], ((className = getClass.call(value)), className == stringClass || className == numberClass) && (properties[value] = 1));\n            }\n          }\n          if (width) {\n            if ((className = getClass.call(width)) == numberClass) {\n              // Convert the `width` to an integer and create a string containing\n              // `width` number of space characters.\n              if ((width -= width % 1) > 0) {\n                for (whitespace = \"\", width > 10 && (width = 10); whitespace.length < width; whitespace += \" \");\n              }\n            } else if (className == stringClass) {\n              whitespace = width.length <= 10 ? width : width.slice(0, 10);\n            }\n          }\n          // Opera <= 7.54u2 discards the values associated with empty string keys\n          // (`\"\"`) only if they are used directly within an object member list\n          // (e.g., `!(\"\" in { \"\": 1})`).\n          return serialize(\"\", (value = {}, value[\"\"] = source, value), callback, properties, whitespace, \"\", []);\n        };\n      }\n\n      // Public: Parses a JSON source string.\n      if (!has(\"json-parse\")) {\n        var fromCharCode = String.fromCharCode;\n\n        // Internal: A map of escaped control characters and their unescaped\n        // equivalents.\n        var Unescapes = {\n          92: \"\\\\\",\n          34: '\"',\n          47: \"/\",\n          98: \"\\b\",\n          116: \"\\t\",\n          110: \"\\n\",\n          102: \"\\f\",\n          114: \"\\r\"\n        };\n\n        // Internal: Stores the parser state.\n        var Index, Source;\n\n        // Internal: Resets the parser state and throws a `SyntaxError`.\n        var abort = function () {\n          Index = Source = null;\n          throw SyntaxError();\n        };\n\n        // Internal: Returns the next token, or `\"$\"` if the parser has reached\n        // the end of the source string. A token may be a string, number, `null`\n        // literal, or Boolean literal.\n        var lex = function () {\n          var source = Source, length = source.length, value, begin, position, isSigned, charCode;\n          while (Index < length) {\n            charCode = source.charCodeAt(Index);\n            switch (charCode) {\n              case 9: case 10: case 13: case 32:\n                // Skip whitespace tokens, including tabs, carriage returns, line\n                // feeds, and space characters.\n                Index++;\n                break;\n              case 123: case 125: case 91: case 93: case 58: case 44:\n                // Parse a punctuator token (`{`, `}`, `[`, `]`, `:`, or `,`) at\n                // the current position.\n                value = charIndexBuggy ? source.charAt(Index) : source[Index];\n                Index++;\n                return value;\n              case 34:\n                // `\"` delimits a JSON string; advance to the next character and\n                // begin parsing the string. String tokens are prefixed with the\n                // sentinel `@` character to distinguish them from punctuators and\n                // end-of-string tokens.\n                for (value = \"@\", Index++; Index < length;) {\n                  charCode = source.charCodeAt(Index);\n                  if (charCode < 32) {\n                    // Unescaped ASCII control characters (those with a code unit\n                    // less than the space character) are not permitted.\n                    abort();\n                  } else if (charCode == 92) {\n                    // A reverse solidus (`\\`) marks the beginning of an escaped\n                    // control character (including `\"`, `\\`, and `/`) or Unicode\n                    // escape sequence.\n                    charCode = source.charCodeAt(++Index);\n                    switch (charCode) {\n                      case 92: case 34: case 47: case 98: case 116: case 110: case 102: case 114:\n                        // Revive escaped control characters.\n                        value += Unescapes[charCode];\n                        Index++;\n                        break;\n                      case 117:\n                        // `\\u` marks the beginning of a Unicode escape sequence.\n                        // Advance to the first character and validate the\n                        // four-digit code point.\n                        begin = ++Index;\n                        for (position = Index + 4; Index < position; Index++) {\n                          charCode = source.charCodeAt(Index);\n                          // A valid sequence comprises four hexdigits (case-\n                          // insensitive) that form a single hexadecimal value.\n                          if (!(charCode >= 48 && charCode <= 57 || charCode >= 97 && charCode <= 102 || charCode >= 65 && charCode <= 70)) {\n                            // Invalid Unicode escape sequence.\n                            abort();\n                          }\n                        }\n                        // Revive the escaped character.\n                        value += fromCharCode(\"0x\" + source.slice(begin, Index));\n                        break;\n                      default:\n                        // Invalid escape sequence.\n                        abort();\n                    }\n                  } else {\n                    if (charCode == 34) {\n                      // An unescaped double-quote character marks the end of the\n                      // string.\n                      break;\n                    }\n                    charCode = source.charCodeAt(Index);\n                    begin = Index;\n                    // Optimize for the common case where a string is valid.\n                    while (charCode >= 32 && charCode != 92 && charCode != 34) {\n                      charCode = source.charCodeAt(++Index);\n                    }\n                    // Append the string as-is.\n                    value += source.slice(begin, Index);\n                  }\n                }\n                if (source.charCodeAt(Index) == 34) {\n                  // Advance to the next character and return the revived string.\n                  Index++;\n                  return value;\n                }\n                // Unterminated string.\n                abort();\n              default:\n                // Parse numbers and literals.\n                begin = Index;\n                // Advance past the negative sign, if one is specified.\n                if (charCode == 45) {\n                  isSigned = true;\n                  charCode = source.charCodeAt(++Index);\n                }\n                // Parse an integer or floating-point value.\n                if (charCode >= 48 && charCode <= 57) {\n                  // Leading zeroes are interpreted as octal literals.\n                  if (charCode == 48 && ((charCode = source.charCodeAt(Index + 1)), charCode >= 48 && charCode <= 57)) {\n                    // Illegal octal literal.\n                    abort();\n                  }\n                  isSigned = false;\n                  // Parse the integer component.\n                  for (; Index < length && ((charCode = source.charCodeAt(Index)), charCode >= 48 && charCode <= 57); Index++);\n                  // Floats cannot contain a leading decimal point; however, this\n                  // case is already accounted for by the parser.\n                  if (source.charCodeAt(Index) == 46) {\n                    position = ++Index;\n                    // Parse the decimal component.\n                    for (; position < length && ((charCode = source.charCodeAt(position)), charCode >= 48 && charCode <= 57); position++);\n                    if (position == Index) {\n                      // Illegal trailing decimal.\n                      abort();\n                    }\n                    Index = position;\n                  }\n                  // Parse exponents. The `e` denoting the exponent is\n                  // case-insensitive.\n                  charCode = source.charCodeAt(Index);\n                  if (charCode == 101 || charCode == 69) {\n                    charCode = source.charCodeAt(++Index);\n                    // Skip past the sign following the exponent, if one is\n                    // specified.\n                    if (charCode == 43 || charCode == 45) {\n                      Index++;\n                    }\n                    // Parse the exponential component.\n                    for (position = Index; position < length && ((charCode = source.charCodeAt(position)), charCode >= 48 && charCode <= 57); position++);\n                    if (position == Index) {\n                      // Illegal empty exponent.\n                      abort();\n                    }\n                    Index = position;\n                  }\n                  // Coerce the parsed value to a JavaScript number.\n                  return +source.slice(begin, Index);\n                }\n                // A negative sign may only precede numbers.\n                if (isSigned) {\n                  abort();\n                }\n                // `true`, `false`, and `null` literals.\n                if (source.slice(Index, Index + 4) == \"true\") {\n                  Index += 4;\n                  return true;\n                } else if (source.slice(Index, Index + 5) == \"false\") {\n                  Index += 5;\n                  return false;\n                } else if (source.slice(Index, Index + 4) == \"null\") {\n                  Index += 4;\n                  return null;\n                }\n                // Unrecognized token.\n                abort();\n            }\n          }\n          // Return the sentinel `$` character if the parser has reached the end\n          // of the source string.\n          return \"$\";\n        };\n\n        // Internal: Parses a JSON `value` token.\n        var get = function (value) {\n          var results, hasMembers;\n          if (value == \"$\") {\n            // Unexpected end of input.\n            abort();\n          }\n          if (typeof value == \"string\") {\n            if ((charIndexBuggy ? value.charAt(0) : value[0]) == \"@\") {\n              // Remove the sentinel `@` character.\n              return value.slice(1);\n            }\n            // Parse object and array literals.\n            if (value == \"[\") {\n              // Parses a JSON array, returning a new JavaScript array.\n              results = [];\n              for (;; hasMembers || (hasMembers = true)) {\n                value = lex();\n                // A closing square bracket marks the end of the array literal.\n                if (value == \"]\") {\n                  break;\n                }\n                // If the array literal contains elements, the current token\n                // should be a comma separating the previous element from the\n                // next.\n                if (hasMembers) {\n                  if (value == \",\") {\n                    value = lex();\n                    if (value == \"]\") {\n                      // Unexpected trailing `,` in array literal.\n                      abort();\n                    }\n                  } else {\n                    // A `,` must separate each array element.\n                    abort();\n                  }\n                }\n                // Elisions and leading commas are not permitted.\n                if (value == \",\") {\n                  abort();\n                }\n                results.push(get(value));\n              }\n              return results;\n            } else if (value == \"{\") {\n              // Parses a JSON object, returning a new JavaScript object.\n              results = {};\n              for (;; hasMembers || (hasMembers = true)) {\n                value = lex();\n                // A closing curly brace marks the end of the object literal.\n                if (value == \"}\") {\n                  break;\n                }\n                // If the object literal contains members, the current token\n                // should be a comma separator.\n                if (hasMembers) {\n                  if (value == \",\") {\n                    value = lex();\n                    if (value == \"}\") {\n                      // Unexpected trailing `,` in object literal.\n                      abort();\n                    }\n                  } else {\n                    // A `,` must separate each object member.\n                    abort();\n                  }\n                }\n                // Leading commas are not permitted, object property names must be\n                // double-quoted strings, and a `:` must separate each property\n                // name and value.\n                if (value == \",\" || typeof value != \"string\" || (charIndexBuggy ? value.charAt(0) : value[0]) != \"@\" || lex() != \":\") {\n                  abort();\n                }\n                results[value.slice(1)] = get(lex());\n              }\n              return results;\n            }\n            // Unexpected token encountered.\n            abort();\n          }\n          return value;\n        };\n\n        // Internal: Updates a traversed object member.\n        var update = function (source, property, callback) {\n          var element = walk(source, property, callback);\n          if (element === undef) {\n            delete source[property];\n          } else {\n            source[property] = element;\n          }\n        };\n\n        // Internal: Recursively traverses a parsed JSON object, invoking the\n        // `callback` function for each value. This is an implementation of the\n        // `Walk(holder, name)` operation defined in ES 5.1 section 15.12.2.\n        var walk = function (source, property, callback) {\n          var value = source[property], length;\n          if (typeof value == \"object\" && value) {\n            // `forEach` can't be used to traverse an array in Opera <= 8.54\n            // because its `Object#hasOwnProperty` implementation returns `false`\n            // for array indices (e.g., `![1, 2, 3].hasOwnProperty(\"0\")`).\n            if (getClass.call(value) == arrayClass) {\n              for (length = value.length; length--;) {\n                update(value, length, callback);\n              }\n            } else {\n              forEach(value, function (property) {\n                update(value, property, callback);\n              });\n            }\n          }\n          return callback.call(source, property, value);\n        };\n\n        // Public: `JSON.parse`. See ES 5.1 section 15.12.2.\n        exports.parse = function (source, callback) {\n          var result, value;\n          Index = 0;\n          Source = \"\" + source;\n          result = get(lex());\n          // If a JSON string contains multiple tokens, it is invalid.\n          if (lex() != \"$\") {\n            abort();\n          }\n          // Reset the parser state.\n          Index = Source = null;\n          return callback && getClass.call(callback) == functionClass ? walk((value = {}, value[\"\"] = result, value), \"\", callback) : result;\n        };\n      }\n    }\n\n    exports[\"runInContext\"] = runInContext;\n    return exports;\n  }\n\n  if (freeExports && !isLoader) {\n    // Export for CommonJS environments.\n    runInContext(root, freeExports);\n  } else {\n    // Export for web browsers and JavaScript engines.\n    var nativeJSON = root.JSON,\n        previousJSON = root[\"JSON3\"],\n        isRestored = false;\n\n    var JSON3 = runInContext(root, (root[\"JSON3\"] = {\n      // Public: Restores the original value of the global `JSON` object and\n      // returns a reference to the `JSON3` object.\n      \"noConflict\": function () {\n        if (!isRestored) {\n          isRestored = true;\n          root.JSON = nativeJSON;\n          root[\"JSON3\"] = previousJSON;\n          nativeJSON = previousJSON = null;\n        }\n        return JSON3;\n      }\n    }));\n\n    root.JSON = {\n      \"parse\": JSON3.parse,\n      \"stringify\": JSON3.stringify\n    };\n  }\n\n  // Export for asynchronous module loaders.\n  if (isLoader) {\n    define(function () {\n      return JSON3;\n    });\n  }\n}).call(this);\n\n}).call(this,typeof global !== \"undefined\" ? global : typeof self !== \"undefined\" ? self : typeof window !== \"undefined\" ? window : {})\n},{}],55:[function(require,module,exports){\n/**\n * lodash 3.2.0 (Custom Build) <https://lodash.com/>\n * Build: `lodash modern modularize exports=\"npm\" -o ./`\n * Copyright 2012-2015 The Dojo Foundation <http://dojofoundation.org/>\n * Based on Underscore.js 1.8.3 <http://underscorejs.org/LICENSE>\n * Copyright 2009-2015 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors\n * Available under MIT license <https://lodash.com/license>\n */\nvar baseCopy = require('lodash._basecopy'),\n    keys = require('lodash.keys');\n\n/**\n * The base implementation of `_.assign` without support for argument juggling,\n * multiple sources, and `customizer` functions.\n *\n * @private\n * @param {Object} object The destination object.\n * @param {Object} source The source object.\n * @returns {Object} Returns `object`.\n */\nfunction baseAssign(object, source) {\n  return source == null\n    ? object\n    : baseCopy(source, keys(source), object);\n}\n\nmodule.exports = baseAssign;\n\n},{\"lodash._basecopy\":56,\"lodash.keys\":63}],56:[function(require,module,exports){\n/**\n * lodash 3.0.1 (Custom Build) <https://lodash.com/>\n * Build: `lodash modern modularize exports=\"npm\" -o ./`\n * Copyright 2012-2015 The Dojo Foundation <http://dojofoundation.org/>\n * Based on Underscore.js 1.8.3 <http://underscorejs.org/LICENSE>\n * Copyright 2009-2015 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors\n * Available under MIT license <https://lodash.com/license>\n */\n\n/**\n * Copies properties of `source` to `object`.\n *\n * @private\n * @param {Object} source The object to copy properties from.\n * @param {Array} props The property names to copy.\n * @param {Object} [object={}] The object to copy properties to.\n * @returns {Object} Returns `object`.\n */\nfunction baseCopy(source, props, object) {\n  object || (object = {});\n\n  var index = -1,\n      length = props.length;\n\n  while (++index < length) {\n    var key = props[index];\n    object[key] = source[key];\n  }\n  return object;\n}\n\nmodule.exports = baseCopy;\n\n},{}],57:[function(require,module,exports){\n/**\n * lodash 3.0.3 (Custom Build) <https://lodash.com/>\n * Build: `lodash modern modularize exports=\"npm\" -o ./`\n * Copyright 2012-2015 The Dojo Foundation <http://dojofoundation.org/>\n * Based on Underscore.js 1.8.3 <http://underscorejs.org/LICENSE>\n * Copyright 2009-2015 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors\n * Available under MIT license <https://lodash.com/license>\n */\n\n/**\n * The base implementation of `_.create` without support for assigning\n * properties to the created object.\n *\n * @private\n * @param {Object} prototype The object to inherit from.\n * @returns {Object} Returns the new object.\n */\nvar baseCreate = (function() {\n  function object() {}\n  return function(prototype) {\n    if (isObject(prototype)) {\n      object.prototype = prototype;\n      var result = new object;\n      object.prototype = undefined;\n    }\n    return result || {};\n  };\n}());\n\n/**\n * Checks if `value` is the [language type](https://es5.github.io/#x8) of `Object`.\n * (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)\n *\n * @static\n * @memberOf _\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is an object, else `false`.\n * @example\n *\n * _.isObject({});\n * // => true\n *\n * _.isObject([1, 2, 3]);\n * // => true\n *\n * _.isObject(1);\n * // => false\n */\nfunction isObject(value) {\n  // Avoid a V8 JIT bug in Chrome 19-20.\n  // See https://code.google.com/p/v8/issues/detail?id=2291 for more details.\n  var type = typeof value;\n  return !!value && (type == 'object' || type == 'function');\n}\n\nmodule.exports = baseCreate;\n\n},{}],58:[function(require,module,exports){\n/**\n * lodash 3.9.1 (Custom Build) <https://lodash.com/>\n * Build: `lodash modern modularize exports=\"npm\" -o ./`\n * Copyright 2012-2015 The Dojo Foundation <http://dojofoundation.org/>\n * Based on Underscore.js 1.8.3 <http://underscorejs.org/LICENSE>\n * Copyright 2009-2015 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors\n * Available under MIT license <https://lodash.com/license>\n */\n\n/** `Object#toString` result references. */\nvar funcTag = '[object Function]';\n\n/** Used to detect host constructors (Safari > 5). */\nvar reIsHostCtor = /^\\[object .+?Constructor\\]$/;\n\n/**\n * Checks if `value` is object-like.\n *\n * @private\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is object-like, else `false`.\n */\nfunction isObjectLike(value) {\n  return !!value && typeof value == 'object';\n}\n\n/** Used for native method references. */\nvar objectProto = Object.prototype;\n\n/** Used to resolve the decompiled source of functions. */\nvar fnToString = Function.prototype.toString;\n\n/** Used to check objects for own properties. */\nvar hasOwnProperty = objectProto.hasOwnProperty;\n\n/**\n * Used to resolve the [`toStringTag`](http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring)\n * of values.\n */\nvar objToString = objectProto.toString;\n\n/** Used to detect if a method is native. */\nvar reIsNative = RegExp('^' +\n  fnToString.call(hasOwnProperty).replace(/[\\\\^$.*+?()[\\]{}|]/g, '\\\\$&')\n  .replace(/hasOwnProperty|(function).*?(?=\\\\\\()| for .+?(?=\\\\\\])/g, '$1.*?') + '$'\n);\n\n/**\n * Gets the native function at `key` of `object`.\n *\n * @private\n * @param {Object} object The object to query.\n * @param {string} key The key of the method to get.\n * @returns {*} Returns the function if it's native, else `undefined`.\n */\nfunction getNative(object, key) {\n  var value = object == null ? undefined : object[key];\n  return isNative(value) ? value : undefined;\n}\n\n/**\n * Checks if `value` is classified as a `Function` object.\n *\n * @static\n * @memberOf _\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`.\n * @example\n *\n * _.isFunction(_);\n * // => true\n *\n * _.isFunction(/abc/);\n * // => false\n */\nfunction isFunction(value) {\n  // The use of `Object#toString` avoids issues with the `typeof` operator\n  // in older versions of Chrome and Safari which return 'function' for regexes\n  // and Safari 8 equivalents which return 'object' for typed array constructors.\n  return isObject(value) && objToString.call(value) == funcTag;\n}\n\n/**\n * Checks if `value` is the [language type](https://es5.github.io/#x8) of `Object`.\n * (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)\n *\n * @static\n * @memberOf _\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is an object, else `false`.\n * @example\n *\n * _.isObject({});\n * // => true\n *\n * _.isObject([1, 2, 3]);\n * // => true\n *\n * _.isObject(1);\n * // => false\n */\nfunction isObject(value) {\n  // Avoid a V8 JIT bug in Chrome 19-20.\n  // See https://code.google.com/p/v8/issues/detail?id=2291 for more details.\n  var type = typeof value;\n  return !!value && (type == 'object' || type == 'function');\n}\n\n/**\n * Checks if `value` is a native function.\n *\n * @static\n * @memberOf _\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a native function, else `false`.\n * @example\n *\n * _.isNative(Array.prototype.push);\n * // => true\n *\n * _.isNative(_);\n * // => false\n */\nfunction isNative(value) {\n  if (value == null) {\n    return false;\n  }\n  if (isFunction(value)) {\n    return reIsNative.test(fnToString.call(value));\n  }\n  return isObjectLike(value) && reIsHostCtor.test(value);\n}\n\nmodule.exports = getNative;\n\n},{}],59:[function(require,module,exports){\n/**\n * lodash 3.0.9 (Custom Build) <https://lodash.com/>\n * Build: `lodash modern modularize exports=\"npm\" -o ./`\n * Copyright 2012-2015 The Dojo Foundation <http://dojofoundation.org/>\n * Based on Underscore.js 1.8.3 <http://underscorejs.org/LICENSE>\n * Copyright 2009-2015 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors\n * Available under MIT license <https://lodash.com/license>\n */\n\n/** Used to detect unsigned integer values. */\nvar reIsUint = /^\\d+$/;\n\n/**\n * Used as the [maximum length](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-number.max_safe_integer)\n * of an array-like value.\n */\nvar MAX_SAFE_INTEGER = 9007199254740991;\n\n/**\n * The base implementation of `_.property` without support for deep paths.\n *\n * @private\n * @param {string} key The key of the property to get.\n * @returns {Function} Returns the new function.\n */\nfunction baseProperty(key) {\n  return function(object) {\n    return object == null ? undefined : object[key];\n  };\n}\n\n/**\n * Gets the \"length\" property value of `object`.\n *\n * **Note:** This function is used to avoid a [JIT bug](https://bugs.webkit.org/show_bug.cgi?id=142792)\n * that affects Safari on at least iOS 8.1-8.3 ARM64.\n *\n * @private\n * @param {Object} object The object to query.\n * @returns {*} Returns the \"length\" value.\n */\nvar getLength = baseProperty('length');\n\n/**\n * Checks if `value` is array-like.\n *\n * @private\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is array-like, else `false`.\n */\nfunction isArrayLike(value) {\n  return value != null && isLength(getLength(value));\n}\n\n/**\n * Checks if `value` is a valid array-like index.\n *\n * @private\n * @param {*} value The value to check.\n * @param {number} [length=MAX_SAFE_INTEGER] The upper bounds of a valid index.\n * @returns {boolean} Returns `true` if `value` is a valid index, else `false`.\n */\nfunction isIndex(value, length) {\n  value = (typeof value == 'number' || reIsUint.test(value)) ? +value : -1;\n  length = length == null ? MAX_SAFE_INTEGER : length;\n  return value > -1 && value % 1 == 0 && value < length;\n}\n\n/**\n * Checks if the provided arguments are from an iteratee call.\n *\n * @private\n * @param {*} value The potential iteratee value argument.\n * @param {*} index The potential iteratee index or key argument.\n * @param {*} object The potential iteratee object argument.\n * @returns {boolean} Returns `true` if the arguments are from an iteratee call, else `false`.\n */\nfunction isIterateeCall(value, index, object) {\n  if (!isObject(object)) {\n    return false;\n  }\n  var type = typeof index;\n  if (type == 'number'\n      ? (isArrayLike(object) && isIndex(index, object.length))\n      : (type == 'string' && index in object)) {\n    var other = object[index];\n    return value === value ? (value === other) : (other !== other);\n  }\n  return false;\n}\n\n/**\n * Checks if `value` is a valid array-like length.\n *\n * **Note:** This function is based on [`ToLength`](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-tolength).\n *\n * @private\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a valid length, else `false`.\n */\nfunction isLength(value) {\n  return typeof value == 'number' && value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER;\n}\n\n/**\n * Checks if `value` is the [language type](https://es5.github.io/#x8) of `Object`.\n * (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)\n *\n * @static\n * @memberOf _\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is an object, else `false`.\n * @example\n *\n * _.isObject({});\n * // => true\n *\n * _.isObject([1, 2, 3]);\n * // => true\n *\n * _.isObject(1);\n * // => false\n */\nfunction isObject(value) {\n  // Avoid a V8 JIT bug in Chrome 19-20.\n  // See https://code.google.com/p/v8/issues/detail?id=2291 for more details.\n  var type = typeof value;\n  return !!value && (type == 'object' || type == 'function');\n}\n\nmodule.exports = isIterateeCall;\n\n},{}],60:[function(require,module,exports){\n/**\n * lodash 3.1.1 (Custom Build) <https://lodash.com/>\n * Build: `lodash modern modularize exports=\"npm\" -o ./`\n * Copyright 2012-2015 The Dojo Foundation <http://dojofoundation.org/>\n * Based on Underscore.js 1.8.3 <http://underscorejs.org/LICENSE>\n * Copyright 2009-2015 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors\n * Available under MIT license <https://lodash.com/license>\n */\nvar baseAssign = require('lodash._baseassign'),\n    baseCreate = require('lodash._basecreate'),\n    isIterateeCall = require('lodash._isiterateecall');\n\n/**\n * Creates an object that inherits from the given `prototype` object. If a\n * `properties` object is provided its own enumerable properties are assigned\n * to the created object.\n *\n * @static\n * @memberOf _\n * @category Object\n * @param {Object} prototype The object to inherit from.\n * @param {Object} [properties] The properties to assign to the object.\n * @param- {Object} [guard] Enables use as a callback for functions like `_.map`.\n * @returns {Object} Returns the new object.\n * @example\n *\n * function Shape() {\n *   this.x = 0;\n *   this.y = 0;\n * }\n *\n * function Circle() {\n *   Shape.call(this);\n * }\n *\n * Circle.prototype = _.create(Shape.prototype, {\n *   'constructor': Circle\n * });\n *\n * var circle = new Circle;\n * circle instanceof Circle;\n * // => true\n *\n * circle instanceof Shape;\n * // => true\n */\nfunction create(prototype, properties, guard) {\n  var result = baseCreate(prototype);\n  if (guard && isIterateeCall(prototype, properties, guard)) {\n    properties = undefined;\n  }\n  return properties ? baseAssign(result, properties) : result;\n}\n\nmodule.exports = create;\n\n},{\"lodash._baseassign\":55,\"lodash._basecreate\":57,\"lodash._isiterateecall\":59}],61:[function(require,module,exports){\n/**\n * lodash (Custom Build) <https://lodash.com/>\n * Build: `lodash modularize exports=\"npm\" -o ./`\n * Copyright jQuery Foundation and other contributors <https://jquery.org/>\n * Released under MIT license <https://lodash.com/license>\n * Based on Underscore.js 1.8.3 <http://underscorejs.org/LICENSE>\n * Copyright Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors\n */\n\n/** Used as references for various `Number` constants. */\nvar MAX_SAFE_INTEGER = 9007199254740991;\n\n/** `Object#toString` result references. */\nvar argsTag = '[object Arguments]',\n    funcTag = '[object Function]',\n    genTag = '[object GeneratorFunction]';\n\n/** Used for built-in method references. */\nvar objectProto = Object.prototype;\n\n/** Used to check objects for own properties. */\nvar hasOwnProperty = objectProto.hasOwnProperty;\n\n/**\n * Used to resolve the\n * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring)\n * of values.\n */\nvar objectToString = objectProto.toString;\n\n/** Built-in value references. */\nvar propertyIsEnumerable = objectProto.propertyIsEnumerable;\n\n/**\n * Checks if `value` is likely an `arguments` object.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is an `arguments` object,\n *  else `false`.\n * @example\n *\n * _.isArguments(function() { return arguments; }());\n * // => true\n *\n * _.isArguments([1, 2, 3]);\n * // => false\n */\nfunction isArguments(value) {\n  // Safari 8.1 makes `arguments.callee` enumerable in strict mode.\n  return isArrayLikeObject(value) && hasOwnProperty.call(value, 'callee') &&\n    (!propertyIsEnumerable.call(value, 'callee') || objectToString.call(value) == argsTag);\n}\n\n/**\n * Checks if `value` is array-like. A value is considered array-like if it's\n * not a function and has a `value.length` that's an integer greater than or\n * equal to `0` and less than or equal to `Number.MAX_SAFE_INTEGER`.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is array-like, else `false`.\n * @example\n *\n * _.isArrayLike([1, 2, 3]);\n * // => true\n *\n * _.isArrayLike(document.body.children);\n * // => true\n *\n * _.isArrayLike('abc');\n * // => true\n *\n * _.isArrayLike(_.noop);\n * // => false\n */\nfunction isArrayLike(value) {\n  return value != null && isLength(value.length) && !isFunction(value);\n}\n\n/**\n * This method is like `_.isArrayLike` except that it also checks if `value`\n * is an object.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is an array-like object,\n *  else `false`.\n * @example\n *\n * _.isArrayLikeObject([1, 2, 3]);\n * // => true\n *\n * _.isArrayLikeObject(document.body.children);\n * // => true\n *\n * _.isArrayLikeObject('abc');\n * // => false\n *\n * _.isArrayLikeObject(_.noop);\n * // => false\n */\nfunction isArrayLikeObject(value) {\n  return isObjectLike(value) && isArrayLike(value);\n}\n\n/**\n * Checks if `value` is classified as a `Function` object.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a function, else `false`.\n * @example\n *\n * _.isFunction(_);\n * // => true\n *\n * _.isFunction(/abc/);\n * // => false\n */\nfunction isFunction(value) {\n  // The use of `Object#toString` avoids issues with the `typeof` operator\n  // in Safari 8-9 which returns 'object' for typed array and other constructors.\n  var tag = isObject(value) ? objectToString.call(value) : '';\n  return tag == funcTag || tag == genTag;\n}\n\n/**\n * Checks if `value` is a valid array-like length.\n *\n * **Note:** This method is loosely based on\n * [`ToLength`](http://ecma-international.org/ecma-262/7.0/#sec-tolength).\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a valid length, else `false`.\n * @example\n *\n * _.isLength(3);\n * // => true\n *\n * _.isLength(Number.MIN_VALUE);\n * // => false\n *\n * _.isLength(Infinity);\n * // => false\n *\n * _.isLength('3');\n * // => false\n */\nfunction isLength(value) {\n  return typeof value == 'number' &&\n    value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER;\n}\n\n/**\n * Checks if `value` is the\n * [language type](http://www.ecma-international.org/ecma-262/7.0/#sec-ecmascript-language-types)\n * of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is an object, else `false`.\n * @example\n *\n * _.isObject({});\n * // => true\n *\n * _.isObject([1, 2, 3]);\n * // => true\n *\n * _.isObject(_.noop);\n * // => true\n *\n * _.isObject(null);\n * // => false\n */\nfunction isObject(value) {\n  var type = typeof value;\n  return !!value && (type == 'object' || type == 'function');\n}\n\n/**\n * Checks if `value` is object-like. A value is object-like if it's not `null`\n * and has a `typeof` result of \"object\".\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is object-like, else `false`.\n * @example\n *\n * _.isObjectLike({});\n * // => true\n *\n * _.isObjectLike([1, 2, 3]);\n * // => true\n *\n * _.isObjectLike(_.noop);\n * // => false\n *\n * _.isObjectLike(null);\n * // => false\n */\nfunction isObjectLike(value) {\n  return !!value && typeof value == 'object';\n}\n\nmodule.exports = isArguments;\n\n},{}],62:[function(require,module,exports){\n/**\n * lodash 3.0.4 (Custom Build) <https://lodash.com/>\n * Build: `lodash modern modularize exports=\"npm\" -o ./`\n * Copyright 2012-2015 The Dojo Foundation <http://dojofoundation.org/>\n * Based on Underscore.js 1.8.3 <http://underscorejs.org/LICENSE>\n * Copyright 2009-2015 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors\n * Available under MIT license <https://lodash.com/license>\n */\n\n/** `Object#toString` result references. */\nvar arrayTag = '[object Array]',\n    funcTag = '[object Function]';\n\n/** Used to detect host constructors (Safari > 5). */\nvar reIsHostCtor = /^\\[object .+?Constructor\\]$/;\n\n/**\n * Checks if `value` is object-like.\n *\n * @private\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is object-like, else `false`.\n */\nfunction isObjectLike(value) {\n  return !!value && typeof value == 'object';\n}\n\n/** Used for native method references. */\nvar objectProto = Object.prototype;\n\n/** Used to resolve the decompiled source of functions. */\nvar fnToString = Function.prototype.toString;\n\n/** Used to check objects for own properties. */\nvar hasOwnProperty = objectProto.hasOwnProperty;\n\n/**\n * Used to resolve the [`toStringTag`](http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring)\n * of values.\n */\nvar objToString = objectProto.toString;\n\n/** Used to detect if a method is native. */\nvar reIsNative = RegExp('^' +\n  fnToString.call(hasOwnProperty).replace(/[\\\\^$.*+?()[\\]{}|]/g, '\\\\$&')\n  .replace(/hasOwnProperty|(function).*?(?=\\\\\\()| for .+?(?=\\\\\\])/g, '$1.*?') + '$'\n);\n\n/* Native method references for those with the same name as other `lodash` methods. */\nvar nativeIsArray = getNative(Array, 'isArray');\n\n/**\n * Used as the [maximum length](http://ecma-international.org/ecma-262/6.0/#sec-number.max_safe_integer)\n * of an array-like value.\n */\nvar MAX_SAFE_INTEGER = 9007199254740991;\n\n/**\n * Gets the native function at `key` of `object`.\n *\n * @private\n * @param {Object} object The object to query.\n * @param {string} key The key of the method to get.\n * @returns {*} Returns the function if it's native, else `undefined`.\n */\nfunction getNative(object, key) {\n  var value = object == null ? undefined : object[key];\n  return isNative(value) ? value : undefined;\n}\n\n/**\n * Checks if `value` is a valid array-like length.\n *\n * **Note:** This function is based on [`ToLength`](http://ecma-international.org/ecma-262/6.0/#sec-tolength).\n *\n * @private\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a valid length, else `false`.\n */\nfunction isLength(value) {\n  return typeof value == 'number' && value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER;\n}\n\n/**\n * Checks if `value` is classified as an `Array` object.\n *\n * @static\n * @memberOf _\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`.\n * @example\n *\n * _.isArray([1, 2, 3]);\n * // => true\n *\n * _.isArray(function() { return arguments; }());\n * // => false\n */\nvar isArray = nativeIsArray || function(value) {\n  return isObjectLike(value) && isLength(value.length) && objToString.call(value) == arrayTag;\n};\n\n/**\n * Checks if `value` is classified as a `Function` object.\n *\n * @static\n * @memberOf _\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`.\n * @example\n *\n * _.isFunction(_);\n * // => true\n *\n * _.isFunction(/abc/);\n * // => false\n */\nfunction isFunction(value) {\n  // The use of `Object#toString` avoids issues with the `typeof` operator\n  // in older versions of Chrome and Safari which return 'function' for regexes\n  // and Safari 8 equivalents which return 'object' for typed array constructors.\n  return isObject(value) && objToString.call(value) == funcTag;\n}\n\n/**\n * Checks if `value` is the [language type](https://es5.github.io/#x8) of `Object`.\n * (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)\n *\n * @static\n * @memberOf _\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is an object, else `false`.\n * @example\n *\n * _.isObject({});\n * // => true\n *\n * _.isObject([1, 2, 3]);\n * // => true\n *\n * _.isObject(1);\n * // => false\n */\nfunction isObject(value) {\n  // Avoid a V8 JIT bug in Chrome 19-20.\n  // See https://code.google.com/p/v8/issues/detail?id=2291 for more details.\n  var type = typeof value;\n  return !!value && (type == 'object' || type == 'function');\n}\n\n/**\n * Checks if `value` is a native function.\n *\n * @static\n * @memberOf _\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a native function, else `false`.\n * @example\n *\n * _.isNative(Array.prototype.push);\n * // => true\n *\n * _.isNative(_);\n * // => false\n */\nfunction isNative(value) {\n  if (value == null) {\n    return false;\n  }\n  if (isFunction(value)) {\n    return reIsNative.test(fnToString.call(value));\n  }\n  return isObjectLike(value) && reIsHostCtor.test(value);\n}\n\nmodule.exports = isArray;\n\n},{}],63:[function(require,module,exports){\n/**\n * lodash 3.1.2 (Custom Build) <https://lodash.com/>\n * Build: `lodash modern modularize exports=\"npm\" -o ./`\n * Copyright 2012-2015 The Dojo Foundation <http://dojofoundation.org/>\n * Based on Underscore.js 1.8.3 <http://underscorejs.org/LICENSE>\n * Copyright 2009-2015 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors\n * Available under MIT license <https://lodash.com/license>\n */\nvar getNative = require('lodash._getnative'),\n    isArguments = require('lodash.isarguments'),\n    isArray = require('lodash.isarray');\n\n/** Used to detect unsigned integer values. */\nvar reIsUint = /^\\d+$/;\n\n/** Used for native method references. */\nvar objectProto = Object.prototype;\n\n/** Used to check objects for own properties. */\nvar hasOwnProperty = objectProto.hasOwnProperty;\n\n/* Native method references for those with the same name as other `lodash` methods. */\nvar nativeKeys = getNative(Object, 'keys');\n\n/**\n * Used as the [maximum length](http://ecma-international.org/ecma-262/6.0/#sec-number.max_safe_integer)\n * of an array-like value.\n */\nvar MAX_SAFE_INTEGER = 9007199254740991;\n\n/**\n * The base implementation of `_.property` without support for deep paths.\n *\n * @private\n * @param {string} key The key of the property to get.\n * @returns {Function} Returns the new function.\n */\nfunction baseProperty(key) {\n  return function(object) {\n    return object == null ? undefined : object[key];\n  };\n}\n\n/**\n * Gets the \"length\" property value of `object`.\n *\n * **Note:** This function is used to avoid a [JIT bug](https://bugs.webkit.org/show_bug.cgi?id=142792)\n * that affects Safari on at least iOS 8.1-8.3 ARM64.\n *\n * @private\n * @param {Object} object The object to query.\n * @returns {*} Returns the \"length\" value.\n */\nvar getLength = baseProperty('length');\n\n/**\n * Checks if `value` is array-like.\n *\n * @private\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is array-like, else `false`.\n */\nfunction isArrayLike(value) {\n  return value != null && isLength(getLength(value));\n}\n\n/**\n * Checks if `value` is a valid array-like index.\n *\n * @private\n * @param {*} value The value to check.\n * @param {number} [length=MAX_SAFE_INTEGER] The upper bounds of a valid index.\n * @returns {boolean} Returns `true` if `value` is a valid index, else `false`.\n */\nfunction isIndex(value, length) {\n  value = (typeof value == 'number' || reIsUint.test(value)) ? +value : -1;\n  length = length == null ? MAX_SAFE_INTEGER : length;\n  return value > -1 && value % 1 == 0 && value < length;\n}\n\n/**\n * Checks if `value` is a valid array-like length.\n *\n * **Note:** This function is based on [`ToLength`](http://ecma-international.org/ecma-262/6.0/#sec-tolength).\n *\n * @private\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a valid length, else `false`.\n */\nfunction isLength(value) {\n  return typeof value == 'number' && value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER;\n}\n\n/**\n * A fallback implementation of `Object.keys` which creates an array of the\n * own enumerable property names of `object`.\n *\n * @private\n * @param {Object} object The object to query.\n * @returns {Array} Returns the array of property names.\n */\nfunction shimKeys(object) {\n  var props = keysIn(object),\n      propsLength = props.length,\n      length = propsLength && object.length;\n\n  var allowIndexes = !!length && isLength(length) &&\n    (isArray(object) || isArguments(object));\n\n  var index = -1,\n      result = [];\n\n  while (++index < propsLength) {\n    var key = props[index];\n    if ((allowIndexes && isIndex(key, length)) || hasOwnProperty.call(object, key)) {\n      result.push(key);\n    }\n  }\n  return result;\n}\n\n/**\n * Checks if `value` is the [language type](https://es5.github.io/#x8) of `Object`.\n * (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)\n *\n * @static\n * @memberOf _\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is an object, else `false`.\n * @example\n *\n * _.isObject({});\n * // => true\n *\n * _.isObject([1, 2, 3]);\n * // => true\n *\n * _.isObject(1);\n * // => false\n */\nfunction isObject(value) {\n  // Avoid a V8 JIT bug in Chrome 19-20.\n  // See https://code.google.com/p/v8/issues/detail?id=2291 for more details.\n  var type = typeof value;\n  return !!value && (type == 'object' || type == 'function');\n}\n\n/**\n * Creates an array of the own enumerable property names of `object`.\n *\n * **Note:** Non-object values are coerced to objects. See the\n * [ES spec](http://ecma-international.org/ecma-262/6.0/#sec-object.keys)\n * for more details.\n *\n * @static\n * @memberOf _\n * @category Object\n * @param {Object} object The object to query.\n * @returns {Array} Returns the array of property names.\n * @example\n *\n * function Foo() {\n *   this.a = 1;\n *   this.b = 2;\n * }\n *\n * Foo.prototype.c = 3;\n *\n * _.keys(new Foo);\n * // => ['a', 'b'] (iteration order is not guaranteed)\n *\n * _.keys('hi');\n * // => ['0', '1']\n */\nvar keys = !nativeKeys ? shimKeys : function(object) {\n  var Ctor = object == null ? undefined : object.constructor;\n  if ((typeof Ctor == 'function' && Ctor.prototype === object) ||\n      (typeof object != 'function' && isArrayLike(object))) {\n    return shimKeys(object);\n  }\n  return isObject(object) ? nativeKeys(object) : [];\n};\n\n/**\n * Creates an array of the own and inherited enumerable property names of `object`.\n *\n * **Note:** Non-object values are coerced to objects.\n *\n * @static\n * @memberOf _\n * @category Object\n * @param {Object} object The object to query.\n * @returns {Array} Returns the array of property names.\n * @example\n *\n * function Foo() {\n *   this.a = 1;\n *   this.b = 2;\n * }\n *\n * Foo.prototype.c = 3;\n *\n * _.keysIn(new Foo);\n * // => ['a', 'b', 'c'] (iteration order is not guaranteed)\n */\nfunction keysIn(object) {\n  if (object == null) {\n    return [];\n  }\n  if (!isObject(object)) {\n    object = Object(object);\n  }\n  var length = object.length;\n  length = (length && isLength(length) &&\n    (isArray(object) || isArguments(object)) && length) || 0;\n\n  var Ctor = object.constructor,\n      index = -1,\n      isProto = typeof Ctor == 'function' && Ctor.prototype === object,\n      result = Array(length),\n      skipIndexes = length > 0;\n\n  while (++index < length) {\n    result[index] = (index + '');\n  }\n  for (var key in object) {\n    if (!(skipIndexes && isIndex(key, length)) &&\n        !(key == 'constructor' && (isProto || !hasOwnProperty.call(object, key)))) {\n      result.push(key);\n    }\n  }\n  return result;\n}\n\nmodule.exports = keys;\n\n},{\"lodash._getnative\":58,\"lodash.isarguments\":61,\"lodash.isarray\":62}],64:[function(require,module,exports){\n(function (process){\nvar path = require('path');\nvar fs = require('fs');\nvar _0777 = parseInt('0777', 8);\n\nmodule.exports = mkdirP.mkdirp = mkdirP.mkdirP = mkdirP;\n\nfunction mkdirP (p, opts, f, made) {\n    if (typeof opts === 'function') {\n        f = opts;\n        opts = {};\n    }\n    else if (!opts || typeof opts !== 'object') {\n        opts = { mode: opts };\n    }\n\n    var mode = opts.mode;\n    var xfs = opts.fs || fs;\n\n    if (mode === undefined) {\n        mode = _0777 & (~process.umask());\n    }\n    if (!made) made = null;\n\n    var cb = f || function () {};\n    p = path.resolve(p);\n\n    xfs.mkdir(p, mode, function (er) {\n        if (!er) {\n            made = made || p;\n            return cb(null, made);\n        }\n        switch (er.code) {\n            case 'ENOENT':\n                mkdirP(path.dirname(p), opts, function (er, made) {\n                    if (er) cb(er, made);\n                    else mkdirP(p, opts, cb, made);\n                });\n                break;\n\n            // In the case of any other error, just see if there's a dir\n            // there already.  If so, then hooray!  If not, then something\n            // is borked.\n            default:\n                xfs.stat(p, function (er2, stat) {\n                    // if the stat fails, then that's super weird.\n                    // let the original error be the failure reason.\n                    if (er2 || !stat.isDirectory()) cb(er, made)\n                    else cb(null, made);\n                });\n                break;\n        }\n    });\n}\n\nmkdirP.sync = function sync (p, opts, made) {\n    if (!opts || typeof opts !== 'object') {\n        opts = { mode: opts };\n    }\n\n    var mode = opts.mode;\n    var xfs = opts.fs || fs;\n\n    if (mode === undefined) {\n        mode = _0777 & (~process.umask());\n    }\n    if (!made) made = null;\n\n    p = path.resolve(p);\n\n    try {\n        xfs.mkdirSync(p, mode);\n        made = made || p;\n    }\n    catch (err0) {\n        switch (err0.code) {\n            case 'ENOENT' :\n                made = sync(path.dirname(p), opts, made);\n                sync(p, opts, made);\n                break;\n\n            // In the case of any other error, just see if there's a dir\n            // there already.  If so, then hooray!  If not, then something\n            // is borked.\n            default:\n                var stat;\n                try {\n                    stat = xfs.statSync(p);\n                }\n                catch (err1) {\n                    throw err0;\n                }\n                if (!stat.isDirectory()) throw err0;\n                break;\n        }\n    }\n\n    return made;\n};\n\n}).call(this,require('_process'))\n},{\"_process\":67,\"fs\":42,\"path\":42}],65:[function(require,module,exports){\nexports.endianness = function () { return 'LE' };\n\nexports.hostname = function () {\n    if (typeof location !== 'undefined') {\n        return location.hostname\n    }\n    else return '';\n};\n\nexports.loadavg = function () { return [] };\n\nexports.uptime = function () { return 0 };\n\nexports.freemem = function () {\n    return Number.MAX_VALUE;\n};\n\nexports.totalmem = function () {\n    return Number.MAX_VALUE;\n};\n\nexports.cpus = function () { return [] };\n\nexports.type = function () { return 'Browser' };\n\nexports.release = function () {\n    if (typeof navigator !== 'undefined') {\n        return navigator.appVersion;\n    }\n    return '';\n};\n\nexports.networkInterfaces\n= exports.getNetworkInterfaces\n= function () { return {} };\n\nexports.arch = function () { return 'javascript' };\n\nexports.platform = function () { return 'browser' };\n\nexports.tmpdir = exports.tmpDir = function () {\n    return '/tmp';\n};\n\nexports.EOL = '\\n';\n\n},{}],66:[function(require,module,exports){\n(function (process){\n'use strict';\n\nif (!process.version ||\n    process.version.indexOf('v0.') === 0 ||\n    process.version.indexOf('v1.') === 0 && process.version.indexOf('v1.8.') !== 0) {\n  module.exports = nextTick;\n} else {\n  module.exports = process.nextTick;\n}\n\nfunction nextTick(fn, arg1, arg2, arg3) {\n  if (typeof fn !== 'function') {\n    throw new TypeError('\"callback\" argument must be a function');\n  }\n  var len = arguments.length;\n  var args, i;\n  switch (len) {\n  case 0:\n  case 1:\n    return process.nextTick(fn);\n  case 2:\n    return process.nextTick(function afterTickOne() {\n      fn.call(null, arg1);\n    });\n  case 3:\n    return process.nextTick(function afterTickTwo() {\n      fn.call(null, arg1, arg2);\n    });\n  case 4:\n    return process.nextTick(function afterTickThree() {\n      fn.call(null, arg1, arg2, arg3);\n    });\n  default:\n    args = new Array(len - 1);\n    i = 0;\n    while (i < args.length) {\n      args[i++] = arguments[i];\n    }\n    return process.nextTick(function afterTick() {\n      fn.apply(null, args);\n    });\n  }\n}\n\n}).call(this,require('_process'))\n},{\"_process\":67}],67:[function(require,module,exports){\n// shim for using process in browser\nvar process = module.exports = {};\n\n// cached from whatever global is present so that test runners that stub it\n// don't break things.  But we need to wrap it in a try catch in case it is\n// wrapped in strict mode code which doesn't define any globals.  It's inside a\n// function because try/catches deoptimize in certain engines.\n\nvar cachedSetTimeout;\nvar cachedClearTimeout;\n\nfunction defaultSetTimout() {\n    throw new Error('setTimeout has not been defined');\n}\nfunction defaultClearTimeout () {\n    throw new Error('clearTimeout has not been defined');\n}\n(function () {\n    try {\n        if (typeof setTimeout === 'function') {\n            cachedSetTimeout = setTimeout;\n        } else {\n            cachedSetTimeout = defaultSetTimout;\n        }\n    } catch (e) {\n        cachedSetTimeout = defaultSetTimout;\n    }\n    try {\n        if (typeof clearTimeout === 'function') {\n            cachedClearTimeout = clearTimeout;\n        } else {\n            cachedClearTimeout = defaultClearTimeout;\n        }\n    } catch (e) {\n        cachedClearTimeout = defaultClearTimeout;\n    }\n} ())\nfunction runTimeout(fun) {\n    if (cachedSetTimeout === setTimeout) {\n        //normal enviroments in sane situations\n        return setTimeout(fun, 0);\n    }\n    // if setTimeout wasn't available but was latter defined\n    if ((cachedSetTimeout === defaultSetTimout || !cachedSetTimeout) && setTimeout) {\n        cachedSetTimeout = setTimeout;\n        return setTimeout(fun, 0);\n    }\n    try {\n        // when when somebody has screwed with setTimeout but no I.E. maddness\n        return cachedSetTimeout(fun, 0);\n    } catch(e){\n        try {\n            // When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally\n            return cachedSetTimeout.call(null, fun, 0);\n        } catch(e){\n            // same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error\n            return cachedSetTimeout.call(this, fun, 0);\n        }\n    }\n\n\n}\nfunction runClearTimeout(marker) {\n    if (cachedClearTimeout === clearTimeout) {\n        //normal enviroments in sane situations\n        return clearTimeout(marker);\n    }\n    // if clearTimeout wasn't available but was latter defined\n    if ((cachedClearTimeout === defaultClearTimeout || !cachedClearTimeout) && clearTimeout) {\n        cachedClearTimeout = clearTimeout;\n        return clearTimeout(marker);\n    }\n    try {\n        // when when somebody has screwed with setTimeout but no I.E. maddness\n        return cachedClearTimeout(marker);\n    } catch (e){\n        try {\n            // When we are in I.E. but the script has been evaled so I.E. doesn't  trust the global object when called normally\n            return cachedClearTimeout.call(null, marker);\n        } catch (e){\n            // same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error.\n            // Some versions of I.E. have different rules for clearTimeout vs setTimeout\n            return cachedClearTimeout.call(this, marker);\n        }\n    }\n\n\n\n}\nvar queue = [];\nvar draining = false;\nvar currentQueue;\nvar queueIndex = -1;\n\nfunction cleanUpNextTick() {\n    if (!draining || !currentQueue) {\n        return;\n    }\n    draining = false;\n    if (currentQueue.length) {\n        queue = currentQueue.concat(queue);\n    } else {\n        queueIndex = -1;\n    }\n    if (queue.length) {\n        drainQueue();\n    }\n}\n\nfunction drainQueue() {\n    if (draining) {\n        return;\n    }\n    var timeout = runTimeout(cleanUpNextTick);\n    draining = true;\n\n    var len = queue.length;\n    while(len) {\n        currentQueue = queue;\n        queue = [];\n        while (++queueIndex < len) {\n            if (currentQueue) {\n                currentQueue[queueIndex].run();\n            }\n        }\n        queueIndex = -1;\n        len = queue.length;\n    }\n    currentQueue = null;\n    draining = false;\n    runClearTimeout(timeout);\n}\n\nprocess.nextTick = function (fun) {\n    var args = new Array(arguments.length - 1);\n    if (arguments.length > 1) {\n        for (var i = 1; i < arguments.length; i++) {\n            args[i - 1] = arguments[i];\n        }\n    }\n    queue.push(new Item(fun, args));\n    if (queue.length === 1 && !draining) {\n        runTimeout(drainQueue);\n    }\n};\n\n// v8 likes predictible objects\nfunction Item(fun, array) {\n    this.fun = fun;\n    this.array = array;\n}\nItem.prototype.run = function () {\n    this.fun.apply(null, this.array);\n};\nprocess.title = 'browser';\nprocess.browser = true;\nprocess.env = {};\nprocess.argv = [];\nprocess.version = ''; // empty string to avoid regexp issues\nprocess.versions = {};\n\nfunction noop() {}\n\nprocess.on = noop;\nprocess.addListener = noop;\nprocess.once = noop;\nprocess.off = noop;\nprocess.removeListener = noop;\nprocess.removeAllListeners = noop;\nprocess.emit = noop;\n\nprocess.binding = function (name) {\n    throw new Error('process.binding is not supported');\n};\n\nprocess.cwd = function () { return '/' };\nprocess.chdir = function (dir) {\n    throw new Error('process.chdir is not supported');\n};\nprocess.umask = function() { return 0; };\n\n},{}],68:[function(require,module,exports){\nmodule.exports = require(\"./lib/_stream_duplex.js\")\n\n},{\"./lib/_stream_duplex.js\":69}],69:[function(require,module,exports){\n// a duplex stream is just a stream that is both readable and writable.\n// Since JS doesn't have multiple prototypal inheritance, this class\n// prototypally inherits from Readable, and then parasitically from\n// Writable.\n\n'use strict';\n\n/*<replacement>*/\n\nvar objectKeys = Object.keys || function (obj) {\n  var keys = [];\n  for (var key in obj) {\n    keys.push(key);\n  }return keys;\n};\n/*</replacement>*/\n\nmodule.exports = Duplex;\n\n/*<replacement>*/\nvar processNextTick = require('process-nextick-args');\n/*</replacement>*/\n\n/*<replacement>*/\nvar util = require('core-util-is');\nutil.inherits = require('inherits');\n/*</replacement>*/\n\nvar Readable = require('./_stream_readable');\nvar Writable = require('./_stream_writable');\n\nutil.inherits(Duplex, Readable);\n\nvar keys = objectKeys(Writable.prototype);\nfor (var v = 0; v < keys.length; v++) {\n  var method = keys[v];\n  if (!Duplex.prototype[method]) Duplex.prototype[method] = Writable.prototype[method];\n}\n\nfunction Duplex(options) {\n  if (!(this instanceof Duplex)) return new Duplex(options);\n\n  Readable.call(this, options);\n  Writable.call(this, options);\n\n  if (options && options.readable === false) this.readable = false;\n\n  if (options && options.writable === false) this.writable = false;\n\n  this.allowHalfOpen = true;\n  if (options && options.allowHalfOpen === false) this.allowHalfOpen = false;\n\n  this.once('end', onend);\n}\n\n// the no-half-open enforcer\nfunction onend() {\n  // if we allow half-open state, or if the writable side ended,\n  // then we're ok.\n  if (this.allowHalfOpen || this._writableState.ended) return;\n\n  // no more data can be written.\n  // But allow more writes to happen in this tick.\n  processNextTick(onEndNT, this);\n}\n\nfunction onEndNT(self) {\n  self.end();\n}\n\nfunction forEach(xs, f) {\n  for (var i = 0, l = xs.length; i < l; i++) {\n    f(xs[i], i);\n  }\n}\n},{\"./_stream_readable\":71,\"./_stream_writable\":73,\"core-util-is\":45,\"inherits\":51,\"process-nextick-args\":66}],70:[function(require,module,exports){\n// a passthrough stream.\n// basically just the most minimal sort of Transform stream.\n// Every written chunk gets output as-is.\n\n'use strict';\n\nmodule.exports = PassThrough;\n\nvar Transform = require('./_stream_transform');\n\n/*<replacement>*/\nvar util = require('core-util-is');\nutil.inherits = require('inherits');\n/*</replacement>*/\n\nutil.inherits(PassThrough, Transform);\n\nfunction PassThrough(options) {\n  if (!(this instanceof PassThrough)) return new PassThrough(options);\n\n  Transform.call(this, options);\n}\n\nPassThrough.prototype._transform = function (chunk, encoding, cb) {\n  cb(null, chunk);\n};\n},{\"./_stream_transform\":72,\"core-util-is\":45,\"inherits\":51}],71:[function(require,module,exports){\n(function (process){\n'use strict';\n\nmodule.exports = Readable;\n\n/*<replacement>*/\nvar processNextTick = require('process-nextick-args');\n/*</replacement>*/\n\n/*<replacement>*/\nvar isArray = require('isarray');\n/*</replacement>*/\n\nReadable.ReadableState = ReadableState;\n\n/*<replacement>*/\nvar EE = require('events').EventEmitter;\n\nvar EElistenerCount = function (emitter, type) {\n  return emitter.listeners(type).length;\n};\n/*</replacement>*/\n\n/*<replacement>*/\nvar Stream;\n(function () {\n  try {\n    Stream = require('st' + 'ream');\n  } catch (_) {} finally {\n    if (!Stream) Stream = require('events').EventEmitter;\n  }\n})();\n/*</replacement>*/\n\nvar Buffer = require('buffer').Buffer;\n/*<replacement>*/\nvar bufferShim = require('buffer-shims');\n/*</replacement>*/\n\n/*<replacement>*/\nvar util = require('core-util-is');\nutil.inherits = require('inherits');\n/*</replacement>*/\n\n/*<replacement>*/\nvar debugUtil = require('util');\nvar debug = void 0;\nif (debugUtil && debugUtil.debuglog) {\n  debug = debugUtil.debuglog('stream');\n} else {\n  debug = function () {};\n}\n/*</replacement>*/\n\nvar BufferList = require('./internal/streams/BufferList');\nvar StringDecoder;\n\nutil.inherits(Readable, Stream);\n\nfunction prependListener(emitter, event, fn) {\n  if (typeof emitter.prependListener === 'function') {\n    return emitter.prependListener(event, fn);\n  } else {\n    // This is a hack to make sure that our error handler is attached before any\n    // userland ones.  NEVER DO THIS. This is here only because this code needs\n    // to continue to work with older versions of Node.js that do not include\n    // the prependListener() method. The goal is to eventually remove this hack.\n    if (!emitter._events || !emitter._events[event]) emitter.on(event, fn);else if (isArray(emitter._events[event])) emitter._events[event].unshift(fn);else emitter._events[event] = [fn, emitter._events[event]];\n  }\n}\n\nvar Duplex;\nfunction ReadableState(options, stream) {\n  Duplex = Duplex || require('./_stream_duplex');\n\n  options = options || {};\n\n  // object stream flag. Used to make read(n) ignore n and to\n  // make all the buffer merging and length checks go away\n  this.objectMode = !!options.objectMode;\n\n  if (stream instanceof Duplex) this.objectMode = this.objectMode || !!options.readableObjectMode;\n\n  // the point at which it stops calling _read() to fill the buffer\n  // Note: 0 is a valid value, means \"don't call _read preemptively ever\"\n  var hwm = options.highWaterMark;\n  var defaultHwm = this.objectMode ? 16 : 16 * 1024;\n  this.highWaterMark = hwm || hwm === 0 ? hwm : defaultHwm;\n\n  // cast to ints.\n  this.highWaterMark = ~ ~this.highWaterMark;\n\n  // A linked list is used to store data chunks instead of an array because the\n  // linked list can remove elements from the beginning faster than\n  // array.shift()\n  this.buffer = new BufferList();\n  this.length = 0;\n  this.pipes = null;\n  this.pipesCount = 0;\n  this.flowing = null;\n  this.ended = false;\n  this.endEmitted = false;\n  this.reading = false;\n\n  // a flag to be able to tell if the onwrite cb is called immediately,\n  // or on a later tick.  We set this to true at first, because any\n  // actions that shouldn't happen until \"later\" should generally also\n  // not happen before the first write call.\n  this.sync = true;\n\n  // whenever we return null, then we set a flag to say\n  // that we're awaiting a 'readable' event emission.\n  this.needReadable = false;\n  this.emittedReadable = false;\n  this.readableListening = false;\n  this.resumeScheduled = false;\n\n  // Crypto is kind of old and crusty.  Historically, its default string\n  // encoding is 'binary' so we have to make this configurable.\n  // Everything else in the universe uses 'utf8', though.\n  this.defaultEncoding = options.defaultEncoding || 'utf8';\n\n  // when piping, we only care about 'readable' events that happen\n  // after read()ing all the bytes and not getting any pushback.\n  this.ranOut = false;\n\n  // the number of writers that are awaiting a drain event in .pipe()s\n  this.awaitDrain = 0;\n\n  // if true, a maybeReadMore has been scheduled\n  this.readingMore = false;\n\n  this.decoder = null;\n  this.encoding = null;\n  if (options.encoding) {\n    if (!StringDecoder) StringDecoder = require('string_decoder/').StringDecoder;\n    this.decoder = new StringDecoder(options.encoding);\n    this.encoding = options.encoding;\n  }\n}\n\nvar Duplex;\nfunction Readable(options) {\n  Duplex = Duplex || require('./_stream_duplex');\n\n  if (!(this instanceof Readable)) return new Readable(options);\n\n  this._readableState = new ReadableState(options, this);\n\n  // legacy\n  this.readable = true;\n\n  if (options && typeof options.read === 'function') this._read = options.read;\n\n  Stream.call(this);\n}\n\n// Manually shove something into the read() buffer.\n// This returns true if the highWaterMark has not been hit yet,\n// similar to how Writable.write() returns true if you should\n// write() some more.\nReadable.prototype.push = function (chunk, encoding) {\n  var state = this._readableState;\n\n  if (!state.objectMode && typeof chunk === 'string') {\n    encoding = encoding || state.defaultEncoding;\n    if (encoding !== state.encoding) {\n      chunk = bufferShim.from(chunk, encoding);\n      encoding = '';\n    }\n  }\n\n  return readableAddChunk(this, state, chunk, encoding, false);\n};\n\n// Unshift should *always* be something directly out of read()\nReadable.prototype.unshift = function (chunk) {\n  var state = this._readableState;\n  return readableAddChunk(this, state, chunk, '', true);\n};\n\nReadable.prototype.isPaused = function () {\n  return this._readableState.flowing === false;\n};\n\nfunction readableAddChunk(stream, state, chunk, encoding, addToFront) {\n  var er = chunkInvalid(state, chunk);\n  if (er) {\n    stream.emit('error', er);\n  } else if (chunk === null) {\n    state.reading = false;\n    onEofChunk(stream, state);\n  } else if (state.objectMode || chunk && chunk.length > 0) {\n    if (state.ended && !addToFront) {\n      var e = new Error('stream.push() after EOF');\n      stream.emit('error', e);\n    } else if (state.endEmitted && addToFront) {\n      var _e = new Error('stream.unshift() after end event');\n      stream.emit('error', _e);\n    } else {\n      var skipAdd;\n      if (state.decoder && !addToFront && !encoding) {\n        chunk = state.decoder.write(chunk);\n        skipAdd = !state.objectMode && chunk.length === 0;\n      }\n\n      if (!addToFront) state.reading = false;\n\n      // Don't add to the buffer if we've decoded to an empty string chunk and\n      // we're not in object mode\n      if (!skipAdd) {\n        // if we want the data now, just emit it.\n        if (state.flowing && state.length === 0 && !state.sync) {\n          stream.emit('data', chunk);\n          stream.read(0);\n        } else {\n          // update the buffer info.\n          state.length += state.objectMode ? 1 : chunk.length;\n          if (addToFront) state.buffer.unshift(chunk);else state.buffer.push(chunk);\n\n          if (state.needReadable) emitReadable(stream);\n        }\n      }\n\n      maybeReadMore(stream, state);\n    }\n  } else if (!addToFront) {\n    state.reading = false;\n  }\n\n  return needMoreData(state);\n}\n\n// if it's past the high water mark, we can push in some more.\n// Also, if we have no data yet, we can stand some\n// more bytes.  This is to work around cases where hwm=0,\n// such as the repl.  Also, if the push() triggered a\n// readable event, and the user called read(largeNumber) such that\n// needReadable was set, then we ought to push more, so that another\n// 'readable' event will be triggered.\nfunction needMoreData(state) {\n  return !state.ended && (state.needReadable || state.length < state.highWaterMark || state.length === 0);\n}\n\n// backwards compatibility.\nReadable.prototype.setEncoding = function (enc) {\n  if (!StringDecoder) StringDecoder = require('string_decoder/').StringDecoder;\n  this._readableState.decoder = new StringDecoder(enc);\n  this._readableState.encoding = enc;\n  return this;\n};\n\n// Don't raise the hwm > 8MB\nvar MAX_HWM = 0x800000;\nfunction computeNewHighWaterMark(n) {\n  if (n >= MAX_HWM) {\n    n = MAX_HWM;\n  } else {\n    // Get the next highest power of 2 to prevent increasing hwm excessively in\n    // tiny amounts\n    n--;\n    n |= n >>> 1;\n    n |= n >>> 2;\n    n |= n >>> 4;\n    n |= n >>> 8;\n    n |= n >>> 16;\n    n++;\n  }\n  return n;\n}\n\n// This function is designed to be inlinable, so please take care when making\n// changes to the function body.\nfunction howMuchToRead(n, state) {\n  if (n <= 0 || state.length === 0 && state.ended) return 0;\n  if (state.objectMode) return 1;\n  if (n !== n) {\n    // Only flow one buffer at a time\n    if (state.flowing && state.length) return state.buffer.head.data.length;else return state.length;\n  }\n  // If we're asking for more than the current hwm, then raise the hwm.\n  if (n > state.highWaterMark) state.highWaterMark = computeNewHighWaterMark(n);\n  if (n <= state.length) return n;\n  // Don't have enough\n  if (!state.ended) {\n    state.needReadable = true;\n    return 0;\n  }\n  return state.length;\n}\n\n// you can override either this method, or the async _read(n) below.\nReadable.prototype.read = function (n) {\n  debug('read', n);\n  n = parseInt(n, 10);\n  var state = this._readableState;\n  var nOrig = n;\n\n  if (n !== 0) state.emittedReadable = false;\n\n  // if we're doing read(0) to trigger a readable event, but we\n  // already have a bunch of data in the buffer, then just trigger\n  // the 'readable' event and move on.\n  if (n === 0 && state.needReadable && (state.length >= state.highWaterMark || state.ended)) {\n    debug('read: emitReadable', state.length, state.ended);\n    if (state.length === 0 && state.ended) endReadable(this);else emitReadable(this);\n    return null;\n  }\n\n  n = howMuchToRead(n, state);\n\n  // if we've ended, and we're now clear, then finish it up.\n  if (n === 0 && state.ended) {\n    if (state.length === 0) endReadable(this);\n    return null;\n  }\n\n  // All the actual chunk generation logic needs to be\n  // *below* the call to _read.  The reason is that in certain\n  // synthetic stream cases, such as passthrough streams, _read\n  // may be a completely synchronous operation which may change\n  // the state of the read buffer, providing enough data when\n  // before there was *not* enough.\n  //\n  // So, the steps are:\n  // 1. Figure out what the state of things will be after we do\n  // a read from the buffer.\n  //\n  // 2. If that resulting state will trigger a _read, then call _read.\n  // Note that this may be asynchronous, or synchronous.  Yes, it is\n  // deeply ugly to write APIs this way, but that still doesn't mean\n  // that the Readable class should behave improperly, as streams are\n  // designed to be sync/async agnostic.\n  // Take note if the _read call is sync or async (ie, if the read call\n  // has returned yet), so that we know whether or not it's safe to emit\n  // 'readable' etc.\n  //\n  // 3. Actually pull the requested chunks out of the buffer and return.\n\n  // if we need a readable event, then we need to do some reading.\n  var doRead = state.needReadable;\n  debug('need readable', doRead);\n\n  // if we currently have less than the highWaterMark, then also read some\n  if (state.length === 0 || state.length - n < state.highWaterMark) {\n    doRead = true;\n    debug('length less than watermark', doRead);\n  }\n\n  // however, if we've ended, then there's no point, and if we're already\n  // reading, then it's unnecessary.\n  if (state.ended || state.reading) {\n    doRead = false;\n    debug('reading or ended', doRead);\n  } else if (doRead) {\n    debug('do read');\n    state.reading = true;\n    state.sync = true;\n    // if the length is currently zero, then we *need* a readable event.\n    if (state.length === 0) state.needReadable = true;\n    // call internal read method\n    this._read(state.highWaterMark);\n    state.sync = false;\n    // If _read pushed data synchronously, then `reading` will be false,\n    // and we need to re-evaluate how much data we can return to the user.\n    if (!state.reading) n = howMuchToRead(nOrig, state);\n  }\n\n  var ret;\n  if (n > 0) ret = fromList(n, state);else ret = null;\n\n  if (ret === null) {\n    state.needReadable = true;\n    n = 0;\n  } else {\n    state.length -= n;\n  }\n\n  if (state.length === 0) {\n    // If we have nothing in the buffer, then we want to know\n    // as soon as we *do* get something into the buffer.\n    if (!state.ended) state.needReadable = true;\n\n    // If we tried to read() past the EOF, then emit end on the next tick.\n    if (nOrig !== n && state.ended) endReadable(this);\n  }\n\n  if (ret !== null) this.emit('data', ret);\n\n  return ret;\n};\n\nfunction chunkInvalid(state, chunk) {\n  var er = null;\n  if (!Buffer.isBuffer(chunk) && typeof chunk !== 'string' && chunk !== null && chunk !== undefined && !state.objectMode) {\n    er = new TypeError('Invalid non-string/buffer chunk');\n  }\n  return er;\n}\n\nfunction onEofChunk(stream, state) {\n  if (state.ended) return;\n  if (state.decoder) {\n    var chunk = state.decoder.end();\n    if (chunk && chunk.length) {\n      state.buffer.push(chunk);\n      state.length += state.objectMode ? 1 : chunk.length;\n    }\n  }\n  state.ended = true;\n\n  // emit 'readable' now to make sure it gets picked up.\n  emitReadable(stream);\n}\n\n// Don't emit readable right away in sync mode, because this can trigger\n// another read() call => stack overflow.  This way, it might trigger\n// a nextTick recursion warning, but that's not so bad.\nfunction emitReadable(stream) {\n  var state = stream._readableState;\n  state.needReadable = false;\n  if (!state.emittedReadable) {\n    debug('emitReadable', state.flowing);\n    state.emittedReadable = true;\n    if (state.sync) processNextTick(emitReadable_, stream);else emitReadable_(stream);\n  }\n}\n\nfunction emitReadable_(stream) {\n  debug('emit readable');\n  stream.emit('readable');\n  flow(stream);\n}\n\n// at this point, the user has presumably seen the 'readable' event,\n// and called read() to consume some data.  that may have triggered\n// in turn another _read(n) call, in which case reading = true if\n// it's in progress.\n// However, if we're not ended, or reading, and the length < hwm,\n// then go ahead and try to read some more preemptively.\nfunction maybeReadMore(stream, state) {\n  if (!state.readingMore) {\n    state.readingMore = true;\n    processNextTick(maybeReadMore_, stream, state);\n  }\n}\n\nfunction maybeReadMore_(stream, state) {\n  var len = state.length;\n  while (!state.reading && !state.flowing && !state.ended && state.length < state.highWaterMark) {\n    debug('maybeReadMore read 0');\n    stream.read(0);\n    if (len === state.length)\n      // didn't get any data, stop spinning.\n      break;else len = state.length;\n  }\n  state.readingMore = false;\n}\n\n// abstract method.  to be overridden in specific implementation classes.\n// call cb(er, data) where data is <= n in length.\n// for virtual (non-string, non-buffer) streams, \"length\" is somewhat\n// arbitrary, and perhaps not very meaningful.\nReadable.prototype._read = function (n) {\n  this.emit('error', new Error('not implemented'));\n};\n\nReadable.prototype.pipe = function (dest, pipeOpts) {\n  var src = this;\n  var state = this._readableState;\n\n  switch (state.pipesCount) {\n    case 0:\n      state.pipes = dest;\n      break;\n    case 1:\n      state.pipes = [state.pipes, dest];\n      break;\n    default:\n      state.pipes.push(dest);\n      break;\n  }\n  state.pipesCount += 1;\n  debug('pipe count=%d opts=%j', state.pipesCount, pipeOpts);\n\n  var doEnd = (!pipeOpts || pipeOpts.end !== false) && dest !== process.stdout && dest !== process.stderr;\n\n  var endFn = doEnd ? onend : cleanup;\n  if (state.endEmitted) processNextTick(endFn);else src.once('end', endFn);\n\n  dest.on('unpipe', onunpipe);\n  function onunpipe(readable) {\n    debug('onunpipe');\n    if (readable === src) {\n      cleanup();\n    }\n  }\n\n  function onend() {\n    debug('onend');\n    dest.end();\n  }\n\n  // when the dest drains, it reduces the awaitDrain counter\n  // on the source.  This would be more elegant with a .once()\n  // handler in flow(), but adding and removing repeatedly is\n  // too slow.\n  var ondrain = pipeOnDrain(src);\n  dest.on('drain', ondrain);\n\n  var cleanedUp = false;\n  function cleanup() {\n    debug('cleanup');\n    // cleanup event handlers once the pipe is broken\n    dest.removeListener('close', onclose);\n    dest.removeListener('finish', onfinish);\n    dest.removeListener('drain', ondrain);\n    dest.removeListener('error', onerror);\n    dest.removeListener('unpipe', onunpipe);\n    src.removeListener('end', onend);\n    src.removeListener('end', cleanup);\n    src.removeListener('data', ondata);\n\n    cleanedUp = true;\n\n    // if the reader is waiting for a drain event from this\n    // specific writer, then it would cause it to never start\n    // flowing again.\n    // So, if this is awaiting a drain, then we just call it now.\n    // If we don't know, then assume that we are waiting for one.\n    if (state.awaitDrain && (!dest._writableState || dest._writableState.needDrain)) ondrain();\n  }\n\n  // If the user pushes more data while we're writing to dest then we'll end up\n  // in ondata again. However, we only want to increase awaitDrain once because\n  // dest will only emit one 'drain' event for the multiple writes.\n  // => Introduce a guard on increasing awaitDrain.\n  var increasedAwaitDrain = false;\n  src.on('data', ondata);\n  function ondata(chunk) {\n    debug('ondata');\n    increasedAwaitDrain = false;\n    var ret = dest.write(chunk);\n    if (false === ret && !increasedAwaitDrain) {\n      // If the user unpiped during `dest.write()`, it is possible\n      // to get stuck in a permanently paused state if that write\n      // also returned false.\n      // => Check whether `dest` is still a piping destination.\n      if ((state.pipesCount === 1 && state.pipes === dest || state.pipesCount > 1 && indexOf(state.pipes, dest) !== -1) && !cleanedUp) {\n        debug('false write response, pause', src._readableState.awaitDrain);\n        src._readableState.awaitDrain++;\n        increasedAwaitDrain = true;\n      }\n      src.pause();\n    }\n  }\n\n  // if the dest has an error, then stop piping into it.\n  // however, don't suppress the throwing behavior for this.\n  function onerror(er) {\n    debug('onerror', er);\n    unpipe();\n    dest.removeListener('error', onerror);\n    if (EElistenerCount(dest, 'error') === 0) dest.emit('error', er);\n  }\n\n  // Make sure our error handler is attached before userland ones.\n  prependListener(dest, 'error', onerror);\n\n  // Both close and finish should trigger unpipe, but only once.\n  function onclose() {\n    dest.removeListener('finish', onfinish);\n    unpipe();\n  }\n  dest.once('close', onclose);\n  function onfinish() {\n    debug('onfinish');\n    dest.removeListener('close', onclose);\n    unpipe();\n  }\n  dest.once('finish', onfinish);\n\n  function unpipe() {\n    debug('unpipe');\n    src.unpipe(dest);\n  }\n\n  // tell the dest that it's being piped to\n  dest.emit('pipe', src);\n\n  // start the flow if it hasn't been started already.\n  if (!state.flowing) {\n    debug('pipe resume');\n    src.resume();\n  }\n\n  return dest;\n};\n\nfunction pipeOnDrain(src) {\n  return function () {\n    var state = src._readableState;\n    debug('pipeOnDrain', state.awaitDrain);\n    if (state.awaitDrain) state.awaitDrain--;\n    if (state.awaitDrain === 0 && EElistenerCount(src, 'data')) {\n      state.flowing = true;\n      flow(src);\n    }\n  };\n}\n\nReadable.prototype.unpipe = function (dest) {\n  var state = this._readableState;\n\n  // if we're not piping anywhere, then do nothing.\n  if (state.pipesCount === 0) return this;\n\n  // just one destination.  most common case.\n  if (state.pipesCount === 1) {\n    // passed in one, but it's not the right one.\n    if (dest && dest !== state.pipes) return this;\n\n    if (!dest) dest = state.pipes;\n\n    // got a match.\n    state.pipes = null;\n    state.pipesCount = 0;\n    state.flowing = false;\n    if (dest) dest.emit('unpipe', this);\n    return this;\n  }\n\n  // slow case. multiple pipe destinations.\n\n  if (!dest) {\n    // remove all.\n    var dests = state.pipes;\n    var len = state.pipesCount;\n    state.pipes = null;\n    state.pipesCount = 0;\n    state.flowing = false;\n\n    for (var _i = 0; _i < len; _i++) {\n      dests[_i].emit('unpipe', this);\n    }return this;\n  }\n\n  // try to find the right one.\n  var i = indexOf(state.pipes, dest);\n  if (i === -1) return this;\n\n  state.pipes.splice(i, 1);\n  state.pipesCount -= 1;\n  if (state.pipesCount === 1) state.pipes = state.pipes[0];\n\n  dest.emit('unpipe', this);\n\n  return this;\n};\n\n// set up data events if they are asked for\n// Ensure readable listeners eventually get something\nReadable.prototype.on = function (ev, fn) {\n  var res = Stream.prototype.on.call(this, ev, fn);\n\n  if (ev === 'data') {\n    // Start flowing on next tick if stream isn't explicitly paused\n    if (this._readableState.flowing !== false) this.resume();\n  } else if (ev === 'readable') {\n    var state = this._readableState;\n    if (!state.endEmitted && !state.readableListening) {\n      state.readableListening = state.needReadable = true;\n      state.emittedReadable = false;\n      if (!state.reading) {\n        processNextTick(nReadingNextTick, this);\n      } else if (state.length) {\n        emitReadable(this, state);\n      }\n    }\n  }\n\n  return res;\n};\nReadable.prototype.addListener = Readable.prototype.on;\n\nfunction nReadingNextTick(self) {\n  debug('readable nexttick read 0');\n  self.read(0);\n}\n\n// pause() and resume() are remnants of the legacy readable stream API\n// If the user uses them, then switch into old mode.\nReadable.prototype.resume = function () {\n  var state = this._readableState;\n  if (!state.flowing) {\n    debug('resume');\n    state.flowing = true;\n    resume(this, state);\n  }\n  return this;\n};\n\nfunction resume(stream, state) {\n  if (!state.resumeScheduled) {\n    state.resumeScheduled = true;\n    processNextTick(resume_, stream, state);\n  }\n}\n\nfunction resume_(stream, state) {\n  if (!state.reading) {\n    debug('resume read 0');\n    stream.read(0);\n  }\n\n  state.resumeScheduled = false;\n  state.awaitDrain = 0;\n  stream.emit('resume');\n  flow(stream);\n  if (state.flowing && !state.reading) stream.read(0);\n}\n\nReadable.prototype.pause = function () {\n  debug('call pause flowing=%j', this._readableState.flowing);\n  if (false !== this._readableState.flowing) {\n    debug('pause');\n    this._readableState.flowing = false;\n    this.emit('pause');\n  }\n  return this;\n};\n\nfunction flow(stream) {\n  var state = stream._readableState;\n  debug('flow', state.flowing);\n  while (state.flowing && stream.read() !== null) {}\n}\n\n// wrap an old-style stream as the async data source.\n// This is *not* part of the readable stream interface.\n// It is an ugly unfortunate mess of history.\nReadable.prototype.wrap = function (stream) {\n  var state = this._readableState;\n  var paused = false;\n\n  var self = this;\n  stream.on('end', function () {\n    debug('wrapped end');\n    if (state.decoder && !state.ended) {\n      var chunk = state.decoder.end();\n      if (chunk && chunk.length) self.push(chunk);\n    }\n\n    self.push(null);\n  });\n\n  stream.on('data', function (chunk) {\n    debug('wrapped data');\n    if (state.decoder) chunk = state.decoder.write(chunk);\n\n    // don't skip over falsy values in objectMode\n    if (state.objectMode && (chunk === null || chunk === undefined)) return;else if (!state.objectMode && (!chunk || !chunk.length)) return;\n\n    var ret = self.push(chunk);\n    if (!ret) {\n      paused = true;\n      stream.pause();\n    }\n  });\n\n  // proxy all the other methods.\n  // important when wrapping filters and duplexes.\n  for (var i in stream) {\n    if (this[i] === undefined && typeof stream[i] === 'function') {\n      this[i] = function (method) {\n        return function () {\n          return stream[method].apply(stream, arguments);\n        };\n      }(i);\n    }\n  }\n\n  // proxy certain important events.\n  var events = ['error', 'close', 'destroy', 'pause', 'resume'];\n  forEach(events, function (ev) {\n    stream.on(ev, self.emit.bind(self, ev));\n  });\n\n  // when we try to consume some more bytes, simply unpause the\n  // underlying stream.\n  self._read = function (n) {\n    debug('wrapped _read', n);\n    if (paused) {\n      paused = false;\n      stream.resume();\n    }\n  };\n\n  return self;\n};\n\n// exposed for testing purposes only.\nReadable._fromList = fromList;\n\n// Pluck off n bytes from an array of buffers.\n// Length is the combined lengths of all the buffers in the list.\n// This function is designed to be inlinable, so please take care when making\n// changes to the function body.\nfunction fromList(n, state) {\n  // nothing buffered\n  if (state.length === 0) return null;\n\n  var ret;\n  if (state.objectMode) ret = state.buffer.shift();else if (!n || n >= state.length) {\n    // read it all, truncate the list\n    if (state.decoder) ret = state.buffer.join('');else if (state.buffer.length === 1) ret = state.buffer.head.data;else ret = state.buffer.concat(state.length);\n    state.buffer.clear();\n  } else {\n    // read part of list\n    ret = fromListPartial(n, state.buffer, state.decoder);\n  }\n\n  return ret;\n}\n\n// Extracts only enough buffered data to satisfy the amount requested.\n// This function is designed to be inlinable, so please take care when making\n// changes to the function body.\nfunction fromListPartial(n, list, hasStrings) {\n  var ret;\n  if (n < list.head.data.length) {\n    // slice is the same for buffers and strings\n    ret = list.head.data.slice(0, n);\n    list.head.data = list.head.data.slice(n);\n  } else if (n === list.head.data.length) {\n    // first chunk is a perfect match\n    ret = list.shift();\n  } else {\n    // result spans more than one buffer\n    ret = hasStrings ? copyFromBufferString(n, list) : copyFromBuffer(n, list);\n  }\n  return ret;\n}\n\n// Copies a specified amount of characters from the list of buffered data\n// chunks.\n// This function is designed to be inlinable, so please take care when making\n// changes to the function body.\nfunction copyFromBufferString(n, list) {\n  var p = list.head;\n  var c = 1;\n  var ret = p.data;\n  n -= ret.length;\n  while (p = p.next) {\n    var str = p.data;\n    var nb = n > str.length ? str.length : n;\n    if (nb === str.length) ret += str;else ret += str.slice(0, n);\n    n -= nb;\n    if (n === 0) {\n      if (nb === str.length) {\n        ++c;\n        if (p.next) list.head = p.next;else list.head = list.tail = null;\n      } else {\n        list.head = p;\n        p.data = str.slice(nb);\n      }\n      break;\n    }\n    ++c;\n  }\n  list.length -= c;\n  return ret;\n}\n\n// Copies a specified amount of bytes from the list of buffered data chunks.\n// This function is designed to be inlinable, so please take care when making\n// changes to the function body.\nfunction copyFromBuffer(n, list) {\n  var ret = bufferShim.allocUnsafe(n);\n  var p = list.head;\n  var c = 1;\n  p.data.copy(ret);\n  n -= p.data.length;\n  while (p = p.next) {\n    var buf = p.data;\n    var nb = n > buf.length ? buf.length : n;\n    buf.copy(ret, ret.length - n, 0, nb);\n    n -= nb;\n    if (n === 0) {\n      if (nb === buf.length) {\n        ++c;\n        if (p.next) list.head = p.next;else list.head = list.tail = null;\n      } else {\n        list.head = p;\n        p.data = buf.slice(nb);\n      }\n      break;\n    }\n    ++c;\n  }\n  list.length -= c;\n  return ret;\n}\n\nfunction endReadable(stream) {\n  var state = stream._readableState;\n\n  // If we get here before consuming all the bytes, then that is a\n  // bug in node.  Should never happen.\n  if (state.length > 0) throw new Error('\"endReadable()\" called on non-empty stream');\n\n  if (!state.endEmitted) {\n    state.ended = true;\n    processNextTick(endReadableNT, state, stream);\n  }\n}\n\nfunction endReadableNT(state, stream) {\n  // Check that we didn't get one last unshift.\n  if (!state.endEmitted && state.length === 0) {\n    state.endEmitted = true;\n    stream.readable = false;\n    stream.emit('end');\n  }\n}\n\nfunction forEach(xs, f) {\n  for (var i = 0, l = xs.length; i < l; i++) {\n    f(xs[i], i);\n  }\n}\n\nfunction indexOf(xs, x) {\n  for (var i = 0, l = xs.length; i < l; i++) {\n    if (xs[i] === x) return i;\n  }\n  return -1;\n}\n}).call(this,require('_process'))\n},{\"./_stream_duplex\":69,\"./internal/streams/BufferList\":74,\"_process\":67,\"buffer\":44,\"buffer-shims\":43,\"core-util-is\":45,\"events\":48,\"inherits\":51,\"isarray\":53,\"process-nextick-args\":66,\"string_decoder/\":80,\"util\":40}],72:[function(require,module,exports){\n// a transform stream is a readable/writable stream where you do\n// something with the data.  Sometimes it's called a \"filter\",\n// but that's not a great name for it, since that implies a thing where\n// some bits pass through, and others are simply ignored.  (That would\n// be a valid example of a transform, of course.)\n//\n// While the output is causally related to the input, it's not a\n// necessarily symmetric or synchronous transformation.  For example,\n// a zlib stream might take multiple plain-text writes(), and then\n// emit a single compressed chunk some time in the future.\n//\n// Here's how this works:\n//\n// The Transform stream has all the aspects of the readable and writable\n// stream classes.  When you write(chunk), that calls _write(chunk,cb)\n// internally, and returns false if there's a lot of pending writes\n// buffered up.  When you call read(), that calls _read(n) until\n// there's enough pending readable data buffered up.\n//\n// In a transform stream, the written data is placed in a buffer.  When\n// _read(n) is called, it transforms the queued up data, calling the\n// buffered _write cb's as it consumes chunks.  If consuming a single\n// written chunk would result in multiple output chunks, then the first\n// outputted bit calls the readcb, and subsequent chunks just go into\n// the read buffer, and will cause it to emit 'readable' if necessary.\n//\n// This way, back-pressure is actually determined by the reading side,\n// since _read has to be called to start processing a new chunk.  However,\n// a pathological inflate type of transform can cause excessive buffering\n// here.  For example, imagine a stream where every byte of input is\n// interpreted as an integer from 0-255, and then results in that many\n// bytes of output.  Writing the 4 bytes {ff,ff,ff,ff} would result in\n// 1kb of data being output.  In this case, you could write a very small\n// amount of input, and end up with a very large amount of output.  In\n// such a pathological inflating mechanism, there'd be no way to tell\n// the system to stop doing the transform.  A single 4MB write could\n// cause the system to run out of memory.\n//\n// However, even in such a pathological case, only a single written chunk\n// would be consumed, and then the rest would wait (un-transformed) until\n// the results of the previous transformed chunk were consumed.\n\n'use strict';\n\nmodule.exports = Transform;\n\nvar Duplex = require('./_stream_duplex');\n\n/*<replacement>*/\nvar util = require('core-util-is');\nutil.inherits = require('inherits');\n/*</replacement>*/\n\nutil.inherits(Transform, Duplex);\n\nfunction TransformState(stream) {\n  this.afterTransform = function (er, data) {\n    return afterTransform(stream, er, data);\n  };\n\n  this.needTransform = false;\n  this.transforming = false;\n  this.writecb = null;\n  this.writechunk = null;\n  this.writeencoding = null;\n}\n\nfunction afterTransform(stream, er, data) {\n  var ts = stream._transformState;\n  ts.transforming = false;\n\n  var cb = ts.writecb;\n\n  if (!cb) return stream.emit('error', new Error('no writecb in Transform class'));\n\n  ts.writechunk = null;\n  ts.writecb = null;\n\n  if (data !== null && data !== undefined) stream.push(data);\n\n  cb(er);\n\n  var rs = stream._readableState;\n  rs.reading = false;\n  if (rs.needReadable || rs.length < rs.highWaterMark) {\n    stream._read(rs.highWaterMark);\n  }\n}\n\nfunction Transform(options) {\n  if (!(this instanceof Transform)) return new Transform(options);\n\n  Duplex.call(this, options);\n\n  this._transformState = new TransformState(this);\n\n  // when the writable side finishes, then flush out anything remaining.\n  var stream = this;\n\n  // start out asking for a readable event once data is transformed.\n  this._readableState.needReadable = true;\n\n  // we have implemented the _read method, and done the other things\n  // that Readable wants before the first _read call, so unset the\n  // sync guard flag.\n  this._readableState.sync = false;\n\n  if (options) {\n    if (typeof options.transform === 'function') this._transform = options.transform;\n\n    if (typeof options.flush === 'function') this._flush = options.flush;\n  }\n\n  this.once('prefinish', function () {\n    if (typeof this._flush === 'function') this._flush(function (er) {\n      done(stream, er);\n    });else done(stream);\n  });\n}\n\nTransform.prototype.push = function (chunk, encoding) {\n  this._transformState.needTransform = false;\n  return Duplex.prototype.push.call(this, chunk, encoding);\n};\n\n// This is the part where you do stuff!\n// override this function in implementation classes.\n// 'chunk' is an input chunk.\n//\n// Call `push(newChunk)` to pass along transformed output\n// to the readable side.  You may call 'push' zero or more times.\n//\n// Call `cb(err)` when you are done with this chunk.  If you pass\n// an error, then that'll put the hurt on the whole operation.  If you\n// never call cb(), then you'll never get another chunk.\nTransform.prototype._transform = function (chunk, encoding, cb) {\n  throw new Error('Not implemented');\n};\n\nTransform.prototype._write = function (chunk, encoding, cb) {\n  var ts = this._transformState;\n  ts.writecb = cb;\n  ts.writechunk = chunk;\n  ts.writeencoding = encoding;\n  if (!ts.transforming) {\n    var rs = this._readableState;\n    if (ts.needTransform || rs.needReadable || rs.length < rs.highWaterMark) this._read(rs.highWaterMark);\n  }\n};\n\n// Doesn't matter what the args are here.\n// _transform does all the work.\n// That we got here means that the readable side wants more data.\nTransform.prototype._read = function (n) {\n  var ts = this._transformState;\n\n  if (ts.writechunk !== null && ts.writecb && !ts.transforming) {\n    ts.transforming = true;\n    this._transform(ts.writechunk, ts.writeencoding, ts.afterTransform);\n  } else {\n    // mark that we need a transform, so that any data that comes in\n    // will get processed, now that we've asked for it.\n    ts.needTransform = true;\n  }\n};\n\nfunction done(stream, er) {\n  if (er) return stream.emit('error', er);\n\n  // if there's nothing in the write buffer, then that means\n  // that nothing more will ever be provided\n  var ws = stream._writableState;\n  var ts = stream._transformState;\n\n  if (ws.length) throw new Error('Calling transform done when ws.length != 0');\n\n  if (ts.transforming) throw new Error('Calling transform done when still transforming');\n\n  return stream.push(null);\n}\n},{\"./_stream_duplex\":69,\"core-util-is\":45,\"inherits\":51}],73:[function(require,module,exports){\n(function (process){\n// A bit simpler than readable streams.\n// Implement an async ._write(chunk, encoding, cb), and it'll handle all\n// the drain event emission and buffering.\n\n'use strict';\n\nmodule.exports = Writable;\n\n/*<replacement>*/\nvar processNextTick = require('process-nextick-args');\n/*</replacement>*/\n\n/*<replacement>*/\nvar asyncWrite = !process.browser && ['v0.10', 'v0.9.'].indexOf(process.version.slice(0, 5)) > -1 ? setImmediate : processNextTick;\n/*</replacement>*/\n\nWritable.WritableState = WritableState;\n\n/*<replacement>*/\nvar util = require('core-util-is');\nutil.inherits = require('inherits');\n/*</replacement>*/\n\n/*<replacement>*/\nvar internalUtil = {\n  deprecate: require('util-deprecate')\n};\n/*</replacement>*/\n\n/*<replacement>*/\nvar Stream;\n(function () {\n  try {\n    Stream = require('st' + 'ream');\n  } catch (_) {} finally {\n    if (!Stream) Stream = require('events').EventEmitter;\n  }\n})();\n/*</replacement>*/\n\nvar Buffer = require('buffer').Buffer;\n/*<replacement>*/\nvar bufferShim = require('buffer-shims');\n/*</replacement>*/\n\nutil.inherits(Writable, Stream);\n\nfunction nop() {}\n\nfunction WriteReq(chunk, encoding, cb) {\n  this.chunk = chunk;\n  this.encoding = encoding;\n  this.callback = cb;\n  this.next = null;\n}\n\nvar Duplex;\nfunction WritableState(options, stream) {\n  Duplex = Duplex || require('./_stream_duplex');\n\n  options = options || {};\n\n  // object stream flag to indicate whether or not this stream\n  // contains buffers or objects.\n  this.objectMode = !!options.objectMode;\n\n  if (stream instanceof Duplex) this.objectMode = this.objectMode || !!options.writableObjectMode;\n\n  // the point at which write() starts returning false\n  // Note: 0 is a valid value, means that we always return false if\n  // the entire buffer is not flushed immediately on write()\n  var hwm = options.highWaterMark;\n  var defaultHwm = this.objectMode ? 16 : 16 * 1024;\n  this.highWaterMark = hwm || hwm === 0 ? hwm : defaultHwm;\n\n  // cast to ints.\n  this.highWaterMark = ~ ~this.highWaterMark;\n\n  this.needDrain = false;\n  // at the start of calling end()\n  this.ending = false;\n  // when end() has been called, and returned\n  this.ended = false;\n  // when 'finish' is emitted\n  this.finished = false;\n\n  // should we decode strings into buffers before passing to _write?\n  // this is here so that some node-core streams can optimize string\n  // handling at a lower level.\n  var noDecode = options.decodeStrings === false;\n  this.decodeStrings = !noDecode;\n\n  // Crypto is kind of old and crusty.  Historically, its default string\n  // encoding is 'binary' so we have to make this configurable.\n  // Everything else in the universe uses 'utf8', though.\n  this.defaultEncoding = options.defaultEncoding || 'utf8';\n\n  // not an actual buffer we keep track of, but a measurement\n  // of how much we're waiting to get pushed to some underlying\n  // socket or file.\n  this.length = 0;\n\n  // a flag to see when we're in the middle of a write.\n  this.writing = false;\n\n  // when true all writes will be buffered until .uncork() call\n  this.corked = 0;\n\n  // a flag to be able to tell if the onwrite cb is called immediately,\n  // or on a later tick.  We set this to true at first, because any\n  // actions that shouldn't happen until \"later\" should generally also\n  // not happen before the first write call.\n  this.sync = true;\n\n  // a flag to know if we're processing previously buffered items, which\n  // may call the _write() callback in the same tick, so that we don't\n  // end up in an overlapped onwrite situation.\n  this.bufferProcessing = false;\n\n  // the callback that's passed to _write(chunk,cb)\n  this.onwrite = function (er) {\n    onwrite(stream, er);\n  };\n\n  // the callback that the user supplies to write(chunk,encoding,cb)\n  this.writecb = null;\n\n  // the amount that is being written when _write is called.\n  this.writelen = 0;\n\n  this.bufferedRequest = null;\n  this.lastBufferedRequest = null;\n\n  // number of pending user-supplied write callbacks\n  // this must be 0 before 'finish' can be emitted\n  this.pendingcb = 0;\n\n  // emit prefinish if the only thing we're waiting for is _write cbs\n  // This is relevant for synchronous Transform streams\n  this.prefinished = false;\n\n  // True if the error was already emitted and should not be thrown again\n  this.errorEmitted = false;\n\n  // count buffered requests\n  this.bufferedRequestCount = 0;\n\n  // allocate the first CorkedRequest, there is always\n  // one allocated and free to use, and we maintain at most two\n  this.corkedRequestsFree = new CorkedRequest(this);\n}\n\nWritableState.prototype.getBuffer = function writableStateGetBuffer() {\n  var current = this.bufferedRequest;\n  var out = [];\n  while (current) {\n    out.push(current);\n    current = current.next;\n  }\n  return out;\n};\n\n(function () {\n  try {\n    Object.defineProperty(WritableState.prototype, 'buffer', {\n      get: internalUtil.deprecate(function () {\n        return this.getBuffer();\n      }, '_writableState.buffer is deprecated. Use _writableState.getBuffer ' + 'instead.')\n    });\n  } catch (_) {}\n})();\n\nvar Duplex;\nfunction Writable(options) {\n  Duplex = Duplex || require('./_stream_duplex');\n\n  // Writable ctor is applied to Duplexes, though they're not\n  // instanceof Writable, they're instanceof Readable.\n  if (!(this instanceof Writable) && !(this instanceof Duplex)) return new Writable(options);\n\n  this._writableState = new WritableState(options, this);\n\n  // legacy.\n  this.writable = true;\n\n  if (options) {\n    if (typeof options.write === 'function') this._write = options.write;\n\n    if (typeof options.writev === 'function') this._writev = options.writev;\n  }\n\n  Stream.call(this);\n}\n\n// Otherwise people can pipe Writable streams, which is just wrong.\nWritable.prototype.pipe = function () {\n  this.emit('error', new Error('Cannot pipe, not readable'));\n};\n\nfunction writeAfterEnd(stream, cb) {\n  var er = new Error('write after end');\n  // TODO: defer error events consistently everywhere, not just the cb\n  stream.emit('error', er);\n  processNextTick(cb, er);\n}\n\n// If we get something that is not a buffer, string, null, or undefined,\n// and we're not in objectMode, then that's an error.\n// Otherwise stream chunks are all considered to be of length=1, and the\n// watermarks determine how many objects to keep in the buffer, rather than\n// how many bytes or characters.\nfunction validChunk(stream, state, chunk, cb) {\n  var valid = true;\n  var er = false;\n  // Always throw error if a null is written\n  // if we are not in object mode then throw\n  // if it is not a buffer, string, or undefined.\n  if (chunk === null) {\n    er = new TypeError('May not write null values to stream');\n  } else if (!Buffer.isBuffer(chunk) && typeof chunk !== 'string' && chunk !== undefined && !state.objectMode) {\n    er = new TypeError('Invalid non-string/buffer chunk');\n  }\n  if (er) {\n    stream.emit('error', er);\n    processNextTick(cb, er);\n    valid = false;\n  }\n  return valid;\n}\n\nWritable.prototype.write = function (chunk, encoding, cb) {\n  var state = this._writableState;\n  var ret = false;\n\n  if (typeof encoding === 'function') {\n    cb = encoding;\n    encoding = null;\n  }\n\n  if (Buffer.isBuffer(chunk)) encoding = 'buffer';else if (!encoding) encoding = state.defaultEncoding;\n\n  if (typeof cb !== 'function') cb = nop;\n\n  if (state.ended) writeAfterEnd(this, cb);else if (validChunk(this, state, chunk, cb)) {\n    state.pendingcb++;\n    ret = writeOrBuffer(this, state, chunk, encoding, cb);\n  }\n\n  return ret;\n};\n\nWritable.prototype.cork = function () {\n  var state = this._writableState;\n\n  state.corked++;\n};\n\nWritable.prototype.uncork = function () {\n  var state = this._writableState;\n\n  if (state.corked) {\n    state.corked--;\n\n    if (!state.writing && !state.corked && !state.finished && !state.bufferProcessing && state.bufferedRequest) clearBuffer(this, state);\n  }\n};\n\nWritable.prototype.setDefaultEncoding = function setDefaultEncoding(encoding) {\n  // node::ParseEncoding() requires lower case.\n  if (typeof encoding === 'string') encoding = encoding.toLowerCase();\n  if (!(['hex', 'utf8', 'utf-8', 'ascii', 'binary', 'base64', 'ucs2', 'ucs-2', 'utf16le', 'utf-16le', 'raw'].indexOf((encoding + '').toLowerCase()) > -1)) throw new TypeError('Unknown encoding: ' + encoding);\n  this._writableState.defaultEncoding = encoding;\n  return this;\n};\n\nfunction decodeChunk(state, chunk, encoding) {\n  if (!state.objectMode && state.decodeStrings !== false && typeof chunk === 'string') {\n    chunk = bufferShim.from(chunk, encoding);\n  }\n  return chunk;\n}\n\n// if we're already writing something, then just put this\n// in the queue, and wait our turn.  Otherwise, call _write\n// If we return false, then we need a drain event, so set that flag.\nfunction writeOrBuffer(stream, state, chunk, encoding, cb) {\n  chunk = decodeChunk(state, chunk, encoding);\n\n  if (Buffer.isBuffer(chunk)) encoding = 'buffer';\n  var len = state.objectMode ? 1 : chunk.length;\n\n  state.length += len;\n\n  var ret = state.length < state.highWaterMark;\n  // we must ensure that previous needDrain will not be reset to false.\n  if (!ret) state.needDrain = true;\n\n  if (state.writing || state.corked) {\n    var last = state.lastBufferedRequest;\n    state.lastBufferedRequest = new WriteReq(chunk, encoding, cb);\n    if (last) {\n      last.next = state.lastBufferedRequest;\n    } else {\n      state.bufferedRequest = state.lastBufferedRequest;\n    }\n    state.bufferedRequestCount += 1;\n  } else {\n    doWrite(stream, state, false, len, chunk, encoding, cb);\n  }\n\n  return ret;\n}\n\nfunction doWrite(stream, state, writev, len, chunk, encoding, cb) {\n  state.writelen = len;\n  state.writecb = cb;\n  state.writing = true;\n  state.sync = true;\n  if (writev) stream._writev(chunk, state.onwrite);else stream._write(chunk, encoding, state.onwrite);\n  state.sync = false;\n}\n\nfunction onwriteError(stream, state, sync, er, cb) {\n  --state.pendingcb;\n  if (sync) processNextTick(cb, er);else cb(er);\n\n  stream._writableState.errorEmitted = true;\n  stream.emit('error', er);\n}\n\nfunction onwriteStateUpdate(state) {\n  state.writing = false;\n  state.writecb = null;\n  state.length -= state.writelen;\n  state.writelen = 0;\n}\n\nfunction onwrite(stream, er) {\n  var state = stream._writableState;\n  var sync = state.sync;\n  var cb = state.writecb;\n\n  onwriteStateUpdate(state);\n\n  if (er) onwriteError(stream, state, sync, er, cb);else {\n    // Check if we're actually ready to finish, but don't emit yet\n    var finished = needFinish(state);\n\n    if (!finished && !state.corked && !state.bufferProcessing && state.bufferedRequest) {\n      clearBuffer(stream, state);\n    }\n\n    if (sync) {\n      /*<replacement>*/\n      asyncWrite(afterWrite, stream, state, finished, cb);\n      /*</replacement>*/\n    } else {\n        afterWrite(stream, state, finished, cb);\n      }\n  }\n}\n\nfunction afterWrite(stream, state, finished, cb) {\n  if (!finished) onwriteDrain(stream, state);\n  state.pendingcb--;\n  cb();\n  finishMaybe(stream, state);\n}\n\n// Must force callback to be called on nextTick, so that we don't\n// emit 'drain' before the write() consumer gets the 'false' return\n// value, and has a chance to attach a 'drain' listener.\nfunction onwriteDrain(stream, state) {\n  if (state.length === 0 && state.needDrain) {\n    state.needDrain = false;\n    stream.emit('drain');\n  }\n}\n\n// if there's something in the buffer waiting, then process it\nfunction clearBuffer(stream, state) {\n  state.bufferProcessing = true;\n  var entry = state.bufferedRequest;\n\n  if (stream._writev && entry && entry.next) {\n    // Fast case, write everything using _writev()\n    var l = state.bufferedRequestCount;\n    var buffer = new Array(l);\n    var holder = state.corkedRequestsFree;\n    holder.entry = entry;\n\n    var count = 0;\n    while (entry) {\n      buffer[count] = entry;\n      entry = entry.next;\n      count += 1;\n    }\n\n    doWrite(stream, state, true, state.length, buffer, '', holder.finish);\n\n    // doWrite is almost always async, defer these to save a bit of time\n    // as the hot path ends with doWrite\n    state.pendingcb++;\n    state.lastBufferedRequest = null;\n    if (holder.next) {\n      state.corkedRequestsFree = holder.next;\n      holder.next = null;\n    } else {\n      state.corkedRequestsFree = new CorkedRequest(state);\n    }\n  } else {\n    // Slow case, write chunks one-by-one\n    while (entry) {\n      var chunk = entry.chunk;\n      var encoding = entry.encoding;\n      var cb = entry.callback;\n      var len = state.objectMode ? 1 : chunk.length;\n\n      doWrite(stream, state, false, len, chunk, encoding, cb);\n      entry = entry.next;\n      // if we didn't call the onwrite immediately, then\n      // it means that we need to wait until it does.\n      // also, that means that the chunk and cb are currently\n      // being processed, so move the buffer counter past them.\n      if (state.writing) {\n        break;\n      }\n    }\n\n    if (entry === null) state.lastBufferedRequest = null;\n  }\n\n  state.bufferedRequestCount = 0;\n  state.bufferedRequest = entry;\n  state.bufferProcessing = false;\n}\n\nWritable.prototype._write = function (chunk, encoding, cb) {\n  cb(new Error('not implemented'));\n};\n\nWritable.prototype._writev = null;\n\nWritable.prototype.end = function (chunk, encoding, cb) {\n  var state = this._writableState;\n\n  if (typeof chunk === 'function') {\n    cb = chunk;\n    chunk = null;\n    encoding = null;\n  } else if (typeof encoding === 'function') {\n    cb = encoding;\n    encoding = null;\n  }\n\n  if (chunk !== null && chunk !== undefined) this.write(chunk, encoding);\n\n  // .end() fully uncorks\n  if (state.corked) {\n    state.corked = 1;\n    this.uncork();\n  }\n\n  // ignore unnecessary end() calls.\n  if (!state.ending && !state.finished) endWritable(this, state, cb);\n};\n\nfunction needFinish(state) {\n  return state.ending && state.length === 0 && state.bufferedRequest === null && !state.finished && !state.writing;\n}\n\nfunction prefinish(stream, state) {\n  if (!state.prefinished) {\n    state.prefinished = true;\n    stream.emit('prefinish');\n  }\n}\n\nfunction finishMaybe(stream, state) {\n  var need = needFinish(state);\n  if (need) {\n    if (state.pendingcb === 0) {\n      prefinish(stream, state);\n      state.finished = true;\n      stream.emit('finish');\n    } else {\n      prefinish(stream, state);\n    }\n  }\n  return need;\n}\n\nfunction endWritable(stream, state, cb) {\n  state.ending = true;\n  finishMaybe(stream, state);\n  if (cb) {\n    if (state.finished) processNextTick(cb);else stream.once('finish', cb);\n  }\n  state.ended = true;\n  stream.writable = false;\n}\n\n// It seems a linked list but it is not\n// there will be only 2 of these for each stream\nfunction CorkedRequest(state) {\n  var _this = this;\n\n  this.next = null;\n  this.entry = null;\n\n  this.finish = function (err) {\n    var entry = _this.entry;\n    _this.entry = null;\n    while (entry) {\n      var cb = entry.callback;\n      state.pendingcb--;\n      cb(err);\n      entry = entry.next;\n    }\n    if (state.corkedRequestsFree) {\n      state.corkedRequestsFree.next = _this;\n    } else {\n      state.corkedRequestsFree = _this;\n    }\n  };\n}\n}).call(this,require('_process'))\n},{\"./_stream_duplex\":69,\"_process\":67,\"buffer\":44,\"buffer-shims\":43,\"core-util-is\":45,\"events\":48,\"inherits\":51,\"process-nextick-args\":66,\"util-deprecate\":81}],74:[function(require,module,exports){\n'use strict';\n\nvar Buffer = require('buffer').Buffer;\n/*<replacement>*/\nvar bufferShim = require('buffer-shims');\n/*</replacement>*/\n\nmodule.exports = BufferList;\n\nfunction BufferList() {\n  this.head = null;\n  this.tail = null;\n  this.length = 0;\n}\n\nBufferList.prototype.push = function (v) {\n  var entry = { data: v, next: null };\n  if (this.length > 0) this.tail.next = entry;else this.head = entry;\n  this.tail = entry;\n  ++this.length;\n};\n\nBufferList.prototype.unshift = function (v) {\n  var entry = { data: v, next: this.head };\n  if (this.length === 0) this.tail = entry;\n  this.head = entry;\n  ++this.length;\n};\n\nBufferList.prototype.shift = function () {\n  if (this.length === 0) return;\n  var ret = this.head.data;\n  if (this.length === 1) this.head = this.tail = null;else this.head = this.head.next;\n  --this.length;\n  return ret;\n};\n\nBufferList.prototype.clear = function () {\n  this.head = this.tail = null;\n  this.length = 0;\n};\n\nBufferList.prototype.join = function (s) {\n  if (this.length === 0) return '';\n  var p = this.head;\n  var ret = '' + p.data;\n  while (p = p.next) {\n    ret += s + p.data;\n  }return ret;\n};\n\nBufferList.prototype.concat = function (n) {\n  if (this.length === 0) return bufferShim.alloc(0);\n  if (this.length === 1) return this.head.data;\n  var ret = bufferShim.allocUnsafe(n >>> 0);\n  var p = this.head;\n  var i = 0;\n  while (p) {\n    p.data.copy(ret, i);\n    i += p.data.length;\n    p = p.next;\n  }\n  return ret;\n};\n},{\"buffer\":44,\"buffer-shims\":43}],75:[function(require,module,exports){\nmodule.exports = require(\"./lib/_stream_passthrough.js\")\n\n},{\"./lib/_stream_passthrough.js\":70}],76:[function(require,module,exports){\n(function (process){\nvar Stream = (function (){\n  try {\n    return require('st' + 'ream'); // hack to fix a circular dependency issue when used with browserify\n  } catch(_){}\n}());\nexports = module.exports = require('./lib/_stream_readable.js');\nexports.Stream = Stream || exports;\nexports.Readable = exports;\nexports.Writable = require('./lib/_stream_writable.js');\nexports.Duplex = require('./lib/_stream_duplex.js');\nexports.Transform = require('./lib/_stream_transform.js');\nexports.PassThrough = require('./lib/_stream_passthrough.js');\n\nif (!process.browser && process.env.READABLE_STREAM === 'disable' && Stream) {\n  module.exports = Stream;\n}\n\n}).call(this,require('_process'))\n},{\"./lib/_stream_duplex.js\":69,\"./lib/_stream_passthrough.js\":70,\"./lib/_stream_readable.js\":71,\"./lib/_stream_transform.js\":72,\"./lib/_stream_writable.js\":73,\"_process\":67}],77:[function(require,module,exports){\nmodule.exports = require(\"./lib/_stream_transform.js\")\n\n},{\"./lib/_stream_transform.js\":72}],78:[function(require,module,exports){\nmodule.exports = require(\"./lib/_stream_writable.js\")\n\n},{\"./lib/_stream_writable.js\":73}],79:[function(require,module,exports){\n// Copyright Joyent, Inc. and other Node contributors.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a\n// copy of this software and associated documentation files (the\n// \"Software\"), to deal in the Software without restriction, including\n// without limitation the rights to use, copy, modify, merge, publish,\n// distribute, sublicense, and/or sell copies of the Software, and to permit\n// persons to whom the Software is furnished to do so, subject to the\n// following conditions:\n//\n// The above copyright notice and this permission notice shall be included\n// in all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS\n// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN\n// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,\n// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE\n// USE OR OTHER DEALINGS IN THE SOFTWARE.\n\nmodule.exports = Stream;\n\nvar EE = require('events').EventEmitter;\nvar inherits = require('inherits');\n\ninherits(Stream, EE);\nStream.Readable = require('readable-stream/readable.js');\nStream.Writable = require('readable-stream/writable.js');\nStream.Duplex = require('readable-stream/duplex.js');\nStream.Transform = require('readable-stream/transform.js');\nStream.PassThrough = require('readable-stream/passthrough.js');\n\n// Backwards-compat with node 0.4.x\nStream.Stream = Stream;\n\n\n\n// old-style streams.  Note that the pipe method (the only relevant\n// part of this class) is overridden in the Readable class.\n\nfunction Stream() {\n  EE.call(this);\n}\n\nStream.prototype.pipe = function(dest, options) {\n  var source = this;\n\n  function ondata(chunk) {\n    if (dest.writable) {\n      if (false === dest.write(chunk) && source.pause) {\n        source.pause();\n      }\n    }\n  }\n\n  source.on('data', ondata);\n\n  function ondrain() {\n    if (source.readable && source.resume) {\n      source.resume();\n    }\n  }\n\n  dest.on('drain', ondrain);\n\n  // If the 'end' option is not supplied, dest.end() will be called when\n  // source gets the 'end' or 'close' events.  Only dest.end() once.\n  if (!dest._isStdio && (!options || options.end !== false)) {\n    source.on('end', onend);\n    source.on('close', onclose);\n  }\n\n  var didOnEnd = false;\n  function onend() {\n    if (didOnEnd) return;\n    didOnEnd = true;\n\n    dest.end();\n  }\n\n\n  function onclose() {\n    if (didOnEnd) return;\n    didOnEnd = true;\n\n    if (typeof dest.destroy === 'function') dest.destroy();\n  }\n\n  // don't leave dangling pipes when there are errors.\n  function onerror(er) {\n    cleanup();\n    if (EE.listenerCount(this, 'error') === 0) {\n      throw er; // Unhandled stream error in pipe.\n    }\n  }\n\n  source.on('error', onerror);\n  dest.on('error', onerror);\n\n  // remove all the event listeners that were added.\n  function cleanup() {\n    source.removeListener('data', ondata);\n    dest.removeListener('drain', ondrain);\n\n    source.removeListener('end', onend);\n    source.removeListener('close', onclose);\n\n    source.removeListener('error', onerror);\n    dest.removeListener('error', onerror);\n\n    source.removeListener('end', cleanup);\n    source.removeListener('close', cleanup);\n\n    dest.removeListener('close', cleanup);\n  }\n\n  source.on('end', cleanup);\n  source.on('close', cleanup);\n\n  dest.on('close', cleanup);\n\n  dest.emit('pipe', source);\n\n  // Allow for unix-like usage: A.pipe(B).pipe(C)\n  return dest;\n};\n\n},{\"events\":48,\"inherits\":51,\"readable-stream/duplex.js\":68,\"readable-stream/passthrough.js\":75,\"readable-stream/readable.js\":76,\"readable-stream/transform.js\":77,\"readable-stream/writable.js\":78}],80:[function(require,module,exports){\n// Copyright Joyent, Inc. and other Node contributors.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a\n// copy of this software and associated documentation files (the\n// \"Software\"), to deal in the Software without restriction, including\n// without limitation the rights to use, copy, modify, merge, publish,\n// distribute, sublicense, and/or sell copies of the Software, and to permit\n// persons to whom the Software is furnished to do so, subject to the\n// following conditions:\n//\n// The above copyright notice and this permission notice shall be included\n// in all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS\n// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN\n// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,\n// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE\n// USE OR OTHER DEALINGS IN THE SOFTWARE.\n\nvar Buffer = require('buffer').Buffer;\n\nvar isBufferEncoding = Buffer.isEncoding\n  || function(encoding) {\n       switch (encoding && encoding.toLowerCase()) {\n         case 'hex': case 'utf8': case 'utf-8': case 'ascii': case 'binary': case 'base64': case 'ucs2': case 'ucs-2': case 'utf16le': case 'utf-16le': case 'raw': return true;\n         default: return false;\n       }\n     }\n\n\nfunction assertEncoding(encoding) {\n  if (encoding && !isBufferEncoding(encoding)) {\n    throw new Error('Unknown encoding: ' + encoding);\n  }\n}\n\n// StringDecoder provides an interface for efficiently splitting a series of\n// buffers into a series of JS strings without breaking apart multi-byte\n// characters. CESU-8 is handled as part of the UTF-8 encoding.\n//\n// @TODO Handling all encodings inside a single object makes it very difficult\n// to reason about this code, so it should be split up in the future.\n// @TODO There should be a utf8-strict encoding that rejects invalid UTF-8 code\n// points as used by CESU-8.\nvar StringDecoder = exports.StringDecoder = function(encoding) {\n  this.encoding = (encoding || 'utf8').toLowerCase().replace(/[-_]/, '');\n  assertEncoding(encoding);\n  switch (this.encoding) {\n    case 'utf8':\n      // CESU-8 represents each of Surrogate Pair by 3-bytes\n      this.surrogateSize = 3;\n      break;\n    case 'ucs2':\n    case 'utf16le':\n      // UTF-16 represents each of Surrogate Pair by 2-bytes\n      this.surrogateSize = 2;\n      this.detectIncompleteChar = utf16DetectIncompleteChar;\n      break;\n    case 'base64':\n      // Base-64 stores 3 bytes in 4 chars, and pads the remainder.\n      this.surrogateSize = 3;\n      this.detectIncompleteChar = base64DetectIncompleteChar;\n      break;\n    default:\n      this.write = passThroughWrite;\n      return;\n  }\n\n  // Enough space to store all bytes of a single character. UTF-8 needs 4\n  // bytes, but CESU-8 may require up to 6 (3 bytes per surrogate).\n  this.charBuffer = new Buffer(6);\n  // Number of bytes received for the current incomplete multi-byte character.\n  this.charReceived = 0;\n  // Number of bytes expected for the current incomplete multi-byte character.\n  this.charLength = 0;\n};\n\n\n// write decodes the given buffer and returns it as JS string that is\n// guaranteed to not contain any partial multi-byte characters. Any partial\n// character found at the end of the buffer is buffered up, and will be\n// returned when calling write again with the remaining bytes.\n//\n// Note: Converting a Buffer containing an orphan surrogate to a String\n// currently works, but converting a String to a Buffer (via `new Buffer`, or\n// Buffer#write) will replace incomplete surrogates with the unicode\n// replacement character. See https://codereview.chromium.org/121173009/ .\nStringDecoder.prototype.write = function(buffer) {\n  var charStr = '';\n  // if our last write ended with an incomplete multibyte character\n  while (this.charLength) {\n    // determine how many remaining bytes this buffer has to offer for this char\n    var available = (buffer.length >= this.charLength - this.charReceived) ?\n        this.charLength - this.charReceived :\n        buffer.length;\n\n    // add the new bytes to the char buffer\n    buffer.copy(this.charBuffer, this.charReceived, 0, available);\n    this.charReceived += available;\n\n    if (this.charReceived < this.charLength) {\n      // still not enough chars in this buffer? wait for more ...\n      return '';\n    }\n\n    // remove bytes belonging to the current character from the buffer\n    buffer = buffer.slice(available, buffer.length);\n\n    // get the character that was split\n    charStr = this.charBuffer.slice(0, this.charLength).toString(this.encoding);\n\n    // CESU-8: lead surrogate (D800-DBFF) is also the incomplete character\n    var charCode = charStr.charCodeAt(charStr.length - 1);\n    if (charCode >= 0xD800 && charCode <= 0xDBFF) {\n      this.charLength += this.surrogateSize;\n      charStr = '';\n      continue;\n    }\n    this.charReceived = this.charLength = 0;\n\n    // if there are no more bytes in this buffer, just emit our char\n    if (buffer.length === 0) {\n      return charStr;\n    }\n    break;\n  }\n\n  // determine and set charLength / charReceived\n  this.detectIncompleteChar(buffer);\n\n  var end = buffer.length;\n  if (this.charLength) {\n    // buffer the incomplete character bytes we got\n    buffer.copy(this.charBuffer, 0, buffer.length - this.charReceived, end);\n    end -= this.charReceived;\n  }\n\n  charStr += buffer.toString(this.encoding, 0, end);\n\n  var end = charStr.length - 1;\n  var charCode = charStr.charCodeAt(end);\n  // CESU-8: lead surrogate (D800-DBFF) is also the incomplete character\n  if (charCode >= 0xD800 && charCode <= 0xDBFF) {\n    var size = this.surrogateSize;\n    this.charLength += size;\n    this.charReceived += size;\n    this.charBuffer.copy(this.charBuffer, size, 0, size);\n    buffer.copy(this.charBuffer, 0, 0, size);\n    return charStr.substring(0, end);\n  }\n\n  // or just emit the charStr\n  return charStr;\n};\n\n// detectIncompleteChar determines if there is an incomplete UTF-8 character at\n// the end of the given buffer. If so, it sets this.charLength to the byte\n// length that character, and sets this.charReceived to the number of bytes\n// that are available for this character.\nStringDecoder.prototype.detectIncompleteChar = function(buffer) {\n  // determine how many bytes we have to check at the end of this buffer\n  var i = (buffer.length >= 3) ? 3 : buffer.length;\n\n  // Figure out if one of the last i bytes of our buffer announces an\n  // incomplete char.\n  for (; i > 0; i--) {\n    var c = buffer[buffer.length - i];\n\n    // See http://en.wikipedia.org/wiki/UTF-8#Description\n\n    // 110XXXXX\n    if (i == 1 && c >> 5 == 0x06) {\n      this.charLength = 2;\n      break;\n    }\n\n    // 1110XXXX\n    if (i <= 2 && c >> 4 == 0x0E) {\n      this.charLength = 3;\n      break;\n    }\n\n    // 11110XXX\n    if (i <= 3 && c >> 3 == 0x1E) {\n      this.charLength = 4;\n      break;\n    }\n  }\n  this.charReceived = i;\n};\n\nStringDecoder.prototype.end = function(buffer) {\n  var res = '';\n  if (buffer && buffer.length)\n    res = this.write(buffer);\n\n  if (this.charReceived) {\n    var cr = this.charReceived;\n    var buf = this.charBuffer;\n    var enc = this.encoding;\n    res += buf.slice(0, cr).toString(enc);\n  }\n\n  return res;\n};\n\nfunction passThroughWrite(buffer) {\n  return buffer.toString(this.encoding);\n}\n\nfunction utf16DetectIncompleteChar(buffer) {\n  this.charReceived = buffer.length % 2;\n  this.charLength = this.charReceived ? 2 : 0;\n}\n\nfunction base64DetectIncompleteChar(buffer) {\n  this.charReceived = buffer.length % 3;\n  this.charLength = this.charReceived ? 3 : 0;\n}\n\n},{\"buffer\":44}],81:[function(require,module,exports){\n(function (global){\n\n/**\n * Module exports.\n */\n\nmodule.exports = deprecate;\n\n/**\n * Mark that a method should not be used.\n * Returns a modified function which warns once by default.\n *\n * If `localStorage.noDeprecation = true` is set, then it is a no-op.\n *\n * If `localStorage.throwDeprecation = true` is set, then deprecated functions\n * will throw an Error when invoked.\n *\n * If `localStorage.traceDeprecation = true` is set, then deprecated functions\n * will invoke `console.trace()` instead of `console.error()`.\n *\n * @param {Function} fn - the function to deprecate\n * @param {String} msg - the string to print to the console when `fn` is invoked\n * @returns {Function} a new \"deprecated\" version of `fn`\n * @api public\n */\n\nfunction deprecate (fn, msg) {\n  if (config('noDeprecation')) {\n    return fn;\n  }\n\n  var warned = false;\n  function deprecated() {\n    if (!warned) {\n      if (config('throwDeprecation')) {\n        throw new Error(msg);\n      } else if (config('traceDeprecation')) {\n        console.trace(msg);\n      } else {\n        console.warn(msg);\n      }\n      warned = true;\n    }\n    return fn.apply(this, arguments);\n  }\n\n  return deprecated;\n}\n\n/**\n * Checks `localStorage` for boolean values for the given `name`.\n *\n * @param {String} name\n * @returns {Boolean}\n * @api private\n */\n\nfunction config (name) {\n  // accessing global.localStorage can trigger a DOMException in sandboxed iframes\n  try {\n    if (!global.localStorage) return false;\n  } catch (_) {\n    return false;\n  }\n  var val = global.localStorage[name];\n  if (null == val) return false;\n  return String(val).toLowerCase() === 'true';\n}\n\n}).call(this,typeof global !== \"undefined\" ? global : typeof self !== \"undefined\" ? self : typeof window !== \"undefined\" ? window : {})\n},{}],82:[function(require,module,exports){\narguments[4][51][0].apply(exports,arguments)\n},{\"dup\":51}],83:[function(require,module,exports){\nmodule.exports = function isBuffer(arg) {\n  return arg && typeof arg === 'object'\n    && typeof arg.copy === 'function'\n    && typeof arg.fill === 'function'\n    && typeof arg.readUInt8 === 'function';\n}\n},{}],84:[function(require,module,exports){\n(function (process,global){\n// Copyright Joyent, Inc. and other Node contributors.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a\n// copy of this software and associated documentation files (the\n// \"Software\"), to deal in the Software without restriction, including\n// without limitation the rights to use, copy, modify, merge, publish,\n// distribute, sublicense, and/or sell copies of the Software, and to permit\n// persons to whom the Software is furnished to do so, subject to the\n// following conditions:\n//\n// The above copyright notice and this permission notice shall be included\n// in all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS\n// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN\n// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,\n// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE\n// USE OR OTHER DEALINGS IN THE SOFTWARE.\n\nvar formatRegExp = /%[sdj%]/g;\nexports.format = function(f) {\n  if (!isString(f)) {\n    var objects = [];\n    for (var i = 0; i < arguments.length; i++) {\n      objects.push(inspect(arguments[i]));\n    }\n    return objects.join(' ');\n  }\n\n  var i = 1;\n  var args = arguments;\n  var len = args.length;\n  var str = String(f).replace(formatRegExp, function(x) {\n    if (x === '%%') return '%';\n    if (i >= len) return x;\n    switch (x) {\n      case '%s': return String(args[i++]);\n      case '%d': return Number(args[i++]);\n      case '%j':\n        try {\n          return JSON.stringify(args[i++]);\n        } catch (_) {\n          return '[Circular]';\n        }\n      default:\n        return x;\n    }\n  });\n  for (var x = args[i]; i < len; x = args[++i]) {\n    if (isNull(x) || !isObject(x)) {\n      str += ' ' + x;\n    } else {\n      str += ' ' + inspect(x);\n    }\n  }\n  return str;\n};\n\n\n// Mark that a method should not be used.\n// Returns a modified function which warns once by default.\n// If --no-deprecation is set, then it is a no-op.\nexports.deprecate = function(fn, msg) {\n  // Allow for deprecating things in the process of starting up.\n  if (isUndefined(global.process)) {\n    return function() {\n      return exports.deprecate(fn, msg).apply(this, arguments);\n    };\n  }\n\n  if (process.noDeprecation === true) {\n    return fn;\n  }\n\n  var warned = false;\n  function deprecated() {\n    if (!warned) {\n      if (process.throwDeprecation) {\n        throw new Error(msg);\n      } else if (process.traceDeprecation) {\n        console.trace(msg);\n      } else {\n        console.error(msg);\n      }\n      warned = true;\n    }\n    return fn.apply(this, arguments);\n  }\n\n  return deprecated;\n};\n\n\nvar debugs = {};\nvar debugEnviron;\nexports.debuglog = function(set) {\n  if (isUndefined(debugEnviron))\n    debugEnviron = process.env.NODE_DEBUG || '';\n  set = set.toUpperCase();\n  if (!debugs[set]) {\n    if (new RegExp('\\\\b' + set + '\\\\b', 'i').test(debugEnviron)) {\n      var pid = process.pid;\n      debugs[set] = function() {\n        var msg = exports.format.apply(exports, arguments);\n        console.error('%s %d: %s', set, pid, msg);\n      };\n    } else {\n      debugs[set] = function() {};\n    }\n  }\n  return debugs[set];\n};\n\n\n/**\n * Echos the value of a value. Trys to print the value out\n * in the best way possible given the different types.\n *\n * @param {Object} obj The object to print out.\n * @param {Object} opts Optional options object that alters the output.\n */\n/* legacy: obj, showHidden, depth, colors*/\nfunction inspect(obj, opts) {\n  // default options\n  var ctx = {\n    seen: [],\n    stylize: stylizeNoColor\n  };\n  // legacy...\n  if (arguments.length >= 3) ctx.depth = arguments[2];\n  if (arguments.length >= 4) ctx.colors = arguments[3];\n  if (isBoolean(opts)) {\n    // legacy...\n    ctx.showHidden = opts;\n  } else if (opts) {\n    // got an \"options\" object\n    exports._extend(ctx, opts);\n  }\n  // set default options\n  if (isUndefined(ctx.showHidden)) ctx.showHidden = false;\n  if (isUndefined(ctx.depth)) ctx.depth = 2;\n  if (isUndefined(ctx.colors)) ctx.colors = false;\n  if (isUndefined(ctx.customInspect)) ctx.customInspect = true;\n  if (ctx.colors) ctx.stylize = stylizeWithColor;\n  return formatValue(ctx, obj, ctx.depth);\n}\nexports.inspect = inspect;\n\n\n// http://en.wikipedia.org/wiki/ANSI_escape_code#graphics\ninspect.colors = {\n  'bold' : [1, 22],\n  'italic' : [3, 23],\n  'underline' : [4, 24],\n  'inverse' : [7, 27],\n  'white' : [37, 39],\n  'grey' : [90, 39],\n  'black' : [30, 39],\n  'blue' : [34, 39],\n  'cyan' : [36, 39],\n  'green' : [32, 39],\n  'magenta' : [35, 39],\n  'red' : [31, 39],\n  'yellow' : [33, 39]\n};\n\n// Don't use 'blue' not visible on cmd.exe\ninspect.styles = {\n  'special': 'cyan',\n  'number': 'yellow',\n  'boolean': 'yellow',\n  'undefined': 'grey',\n  'null': 'bold',\n  'string': 'green',\n  'date': 'magenta',\n  // \"name\": intentionally not styling\n  'regexp': 'red'\n};\n\n\nfunction stylizeWithColor(str, styleType) {\n  var style = inspect.styles[styleType];\n\n  if (style) {\n    return '\\u001b[' + inspect.colors[style][0] + 'm' + str +\n           '\\u001b[' + inspect.colors[style][1] + 'm';\n  } else {\n    return str;\n  }\n}\n\n\nfunction stylizeNoColor(str, styleType) {\n  return str;\n}\n\n\nfunction arrayToHash(array) {\n  var hash = {};\n\n  array.forEach(function(val, idx) {\n    hash[val] = true;\n  });\n\n  return hash;\n}\n\n\nfunction formatValue(ctx, value, recurseTimes) {\n  // Provide a hook for user-specified inspect functions.\n  // Check that value is an object with an inspect function on it\n  if (ctx.customInspect &&\n      value &&\n      isFunction(value.inspect) &&\n      // Filter out the util module, it's inspect function is special\n      value.inspect !== exports.inspect &&\n      // Also filter out any prototype objects using the circular check.\n      !(value.constructor && value.constructor.prototype === value)) {\n    var ret = value.inspect(recurseTimes, ctx);\n    if (!isString(ret)) {\n      ret = formatValue(ctx, ret, recurseTimes);\n    }\n    return ret;\n  }\n\n  // Primitive types cannot have properties\n  var primitive = formatPrimitive(ctx, value);\n  if (primitive) {\n    return primitive;\n  }\n\n  // Look up the keys of the object.\n  var keys = Object.keys(value);\n  var visibleKeys = arrayToHash(keys);\n\n  if (ctx.showHidden) {\n    keys = Object.getOwnPropertyNames(value);\n  }\n\n  // IE doesn't make error fields non-enumerable\n  // http://msdn.microsoft.com/en-us/library/ie/dww52sbt(v=vs.94).aspx\n  if (isError(value)\n      && (keys.indexOf('message') >= 0 || keys.indexOf('description') >= 0)) {\n    return formatError(value);\n  }\n\n  // Some type of object without properties can be shortcutted.\n  if (keys.length === 0) {\n    if (isFunction(value)) {\n      var name = value.name ? ': ' + value.name : '';\n      return ctx.stylize('[Function' + name + ']', 'special');\n    }\n    if (isRegExp(value)) {\n      return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp');\n    }\n    if (isDate(value)) {\n      return ctx.stylize(Date.prototype.toString.call(value), 'date');\n    }\n    if (isError(value)) {\n      return formatError(value);\n    }\n  }\n\n  var base = '', array = false, braces = ['{', '}'];\n\n  // Make Array say that they are Array\n  if (isArray(value)) {\n    array = true;\n    braces = ['[', ']'];\n  }\n\n  // Make functions say that they are functions\n  if (isFunction(value)) {\n    var n = value.name ? ': ' + value.name : '';\n    base = ' [Function' + n + ']';\n  }\n\n  // Make RegExps say that they are RegExps\n  if (isRegExp(value)) {\n    base = ' ' + RegExp.prototype.toString.call(value);\n  }\n\n  // Make dates with properties first say the date\n  if (isDate(value)) {\n    base = ' ' + Date.prototype.toUTCString.call(value);\n  }\n\n  // Make error with message first say the error\n  if (isError(value)) {\n    base = ' ' + formatError(value);\n  }\n\n  if (keys.length === 0 && (!array || value.length == 0)) {\n    return braces[0] + base + braces[1];\n  }\n\n  if (recurseTimes < 0) {\n    if (isRegExp(value)) {\n      return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp');\n    } else {\n      return ctx.stylize('[Object]', 'special');\n    }\n  }\n\n  ctx.seen.push(value);\n\n  var output;\n  if (array) {\n    output = formatArray(ctx, value, recurseTimes, visibleKeys, keys);\n  } else {\n    output = keys.map(function(key) {\n      return formatProperty(ctx, value, recurseTimes, visibleKeys, key, array);\n    });\n  }\n\n  ctx.seen.pop();\n\n  return reduceToSingleString(output, base, braces);\n}\n\n\nfunction formatPrimitive(ctx, value) {\n  if (isUndefined(value))\n    return ctx.stylize('undefined', 'undefined');\n  if (isString(value)) {\n    var simple = '\\'' + JSON.stringify(value).replace(/^\"|\"$/g, '')\n                                             .replace(/'/g, \"\\\\'\")\n                                             .replace(/\\\\\"/g, '\"') + '\\'';\n    return ctx.stylize(simple, 'string');\n  }\n  if (isNumber(value))\n    return ctx.stylize('' + value, 'number');\n  if (isBoolean(value))\n    return ctx.stylize('' + value, 'boolean');\n  // For some reason typeof null is \"object\", so special case here.\n  if (isNull(value))\n    return ctx.stylize('null', 'null');\n}\n\n\nfunction formatError(value) {\n  return '[' + Error.prototype.toString.call(value) + ']';\n}\n\n\nfunction formatArray(ctx, value, recurseTimes, visibleKeys, keys) {\n  var output = [];\n  for (var i = 0, l = value.length; i < l; ++i) {\n    if (hasOwnProperty(value, String(i))) {\n      output.push(formatProperty(ctx, value, recurseTimes, visibleKeys,\n          String(i), true));\n    } else {\n      output.push('');\n    }\n  }\n  keys.forEach(function(key) {\n    if (!key.match(/^\\d+$/)) {\n      output.push(formatProperty(ctx, value, recurseTimes, visibleKeys,\n          key, true));\n    }\n  });\n  return output;\n}\n\n\nfunction formatProperty(ctx, value, recurseTimes, visibleKeys, key, array) {\n  var name, str, desc;\n  desc = Object.getOwnPropertyDescriptor(value, key) || { value: value[key] };\n  if (desc.get) {\n    if (desc.set) {\n      str = ctx.stylize('[Getter/Setter]', 'special');\n    } else {\n      str = ctx.stylize('[Getter]', 'special');\n    }\n  } else {\n    if (desc.set) {\n      str = ctx.stylize('[Setter]', 'special');\n    }\n  }\n  if (!hasOwnProperty(visibleKeys, key)) {\n    name = '[' + key + ']';\n  }\n  if (!str) {\n    if (ctx.seen.indexOf(desc.value) < 0) {\n      if (isNull(recurseTimes)) {\n        str = formatValue(ctx, desc.value, null);\n      } else {\n        str = formatValue(ctx, desc.value, recurseTimes - 1);\n      }\n      if (str.indexOf('\\n') > -1) {\n        if (array) {\n          str = str.split('\\n').map(function(line) {\n            return '  ' + line;\n          }).join('\\n').substr(2);\n        } else {\n          str = '\\n' + str.split('\\n').map(function(line) {\n            return '   ' + line;\n          }).join('\\n');\n        }\n      }\n    } else {\n      str = ctx.stylize('[Circular]', 'special');\n    }\n  }\n  if (isUndefined(name)) {\n    if (array && key.match(/^\\d+$/)) {\n      return str;\n    }\n    name = JSON.stringify('' + key);\n    if (name.match(/^\"([a-zA-Z_][a-zA-Z_0-9]*)\"$/)) {\n      name = name.substr(1, name.length - 2);\n      name = ctx.stylize(name, 'name');\n    } else {\n      name = name.replace(/'/g, \"\\\\'\")\n                 .replace(/\\\\\"/g, '\"')\n                 .replace(/(^\"|\"$)/g, \"'\");\n      name = ctx.stylize(name, 'string');\n    }\n  }\n\n  return name + ': ' + str;\n}\n\n\nfunction reduceToSingleString(output, base, braces) {\n  var numLinesEst = 0;\n  var length = output.reduce(function(prev, cur) {\n    numLinesEst++;\n    if (cur.indexOf('\\n') >= 0) numLinesEst++;\n    return prev + cur.replace(/\\u001b\\[\\d\\d?m/g, '').length + 1;\n  }, 0);\n\n  if (length > 60) {\n    return braces[0] +\n           (base === '' ? '' : base + '\\n ') +\n           ' ' +\n           output.join(',\\n  ') +\n           ' ' +\n           braces[1];\n  }\n\n  return braces[0] + base + ' ' + output.join(', ') + ' ' + braces[1];\n}\n\n\n// NOTE: These type checking functions intentionally don't use `instanceof`\n// because it is fragile and can be easily faked with `Object.create()`.\nfunction isArray(ar) {\n  return Array.isArray(ar);\n}\nexports.isArray = isArray;\n\nfunction isBoolean(arg) {\n  return typeof arg === 'boolean';\n}\nexports.isBoolean = isBoolean;\n\nfunction isNull(arg) {\n  return arg === null;\n}\nexports.isNull = isNull;\n\nfunction isNullOrUndefined(arg) {\n  return arg == null;\n}\nexports.isNullOrUndefined = isNullOrUndefined;\n\nfunction isNumber(arg) {\n  return typeof arg === 'number';\n}\nexports.isNumber = isNumber;\n\nfunction isString(arg) {\n  return typeof arg === 'string';\n}\nexports.isString = isString;\n\nfunction isSymbol(arg) {\n  return typeof arg === 'symbol';\n}\nexports.isSymbol = isSymbol;\n\nfunction isUndefined(arg) {\n  return arg === void 0;\n}\nexports.isUndefined = isUndefined;\n\nfunction isRegExp(re) {\n  return isObject(re) && objectToString(re) === '[object RegExp]';\n}\nexports.isRegExp = isRegExp;\n\nfunction isObject(arg) {\n  return typeof arg === 'object' && arg !== null;\n}\nexports.isObject = isObject;\n\nfunction isDate(d) {\n  return isObject(d) && objectToString(d) === '[object Date]';\n}\nexports.isDate = isDate;\n\nfunction isError(e) {\n  return isObject(e) &&\n      (objectToString(e) === '[object Error]' || e instanceof Error);\n}\nexports.isError = isError;\n\nfunction isFunction(arg) {\n  return typeof arg === 'function';\n}\nexports.isFunction = isFunction;\n\nfunction isPrimitive(arg) {\n  return arg === null ||\n         typeof arg === 'boolean' ||\n         typeof arg === 'number' ||\n         typeof arg === 'string' ||\n         typeof arg === 'symbol' ||  // ES6 symbol\n         typeof arg === 'undefined';\n}\nexports.isPrimitive = isPrimitive;\n\nexports.isBuffer = require('./support/isBuffer');\n\nfunction objectToString(o) {\n  return Object.prototype.toString.call(o);\n}\n\n\nfunction pad(n) {\n  return n < 10 ? '0' + n.toString(10) : n.toString(10);\n}\n\n\nvar months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep',\n              'Oct', 'Nov', 'Dec'];\n\n// 26 Feb 16:19:34\nfunction timestamp() {\n  var d = new Date();\n  var time = [pad(d.getHours()),\n              pad(d.getMinutes()),\n              pad(d.getSeconds())].join(':');\n  return [d.getDate(), months[d.getMonth()], time].join(' ');\n}\n\n\n// log is just a thin wrapper to console.log that prepends a timestamp\nexports.log = function() {\n  console.log('%s - %s', timestamp(), exports.format.apply(exports, arguments));\n};\n\n\n/**\n * Inherit the prototype methods from one constructor into another.\n *\n * The Function.prototype.inherits from lang.js rewritten as a standalone\n * function (not on Function.prototype). NOTE: If this file is to be loaded\n * during bootstrapping this function needs to be rewritten using some native\n * functions as prototype setup using normal JavaScript does not work as\n * expected during bootstrapping (see mirror.js in r114903).\n *\n * @param {function} ctor Constructor function which needs to inherit the\n *     prototype.\n * @param {function} superCtor Constructor function to inherit prototype from.\n */\nexports.inherits = require('inherits');\n\nexports._extend = function(origin, add) {\n  // Don't do anything if add isn't an object\n  if (!add || !isObject(add)) return origin;\n\n  var keys = Object.keys(add);\n  var i = keys.length;\n  while (i--) {\n    origin[keys[i]] = add[keys[i]];\n  }\n  return origin;\n};\n\nfunction hasOwnProperty(obj, prop) {\n  return Object.prototype.hasOwnProperty.call(obj, prop);\n}\n\n}).call(this,require('_process'),typeof global !== \"undefined\" ? global : typeof self !== \"undefined\" ? self : typeof window !== \"undefined\" ? window : {})\n},{\"./support/isBuffer\":83,\"_process\":67,\"inherits\":82}]},{},[1]);\n"
  },
  {
    "path": "app_frontend/static/plugin/JavaScript-Load-Image-2.12.2/.gitignore",
    "content": ".DS_Store\nnode_modules\n"
  },
  {
    "path": "app_frontend/static/plugin/JavaScript-Load-Image-2.12.2/.npmignore",
    "content": "*\n!js/*.js\n!js/*.js.map\n"
  },
  {
    "path": "app_frontend/static/plugin/JavaScript-Load-Image-2.12.2/.travis.yml",
    "content": "language: node_js\nnode_js:\n  - \"stable\"\n"
  },
  {
    "path": "app_frontend/static/plugin/JavaScript-Load-Image-2.12.2/README.md",
    "content": "# JavaScript Load Image\n\n> A JavaScript library to load and transform image files.\n\n## Table of contents\n\n- [Demo](#demo)\n- [Description](#description)\n- [Setup](#setup)\n- [Usage](#usage)\n- [Image loading](#image-loading)\n- [Image scaling](#image-scaling)\n- [Requirements](#requirements)\n- [API](#api)\n- [Options](#options)\n- [Meta data parsing](#meta-data-parsing)\n- [Exif parser](#exif-parser)\n- [License](#license)\n- [Credits](#credits)\n\n## Demo\n[JavaScript Load Image Demo](https://blueimp.github.io/JavaScript-Load-Image/)\n\n## Description\nJavaScript Load Image is a library to load images provided as File or Blob\nobjects or via URL.  \nIt returns an optionally scaled and/or cropped HTML img or canvas element via an\nasynchronous callback.  \nIt also provides a method to parse image meta data to extract Exif tags and\nthumbnails and to restore the complete image header after resizing.\n\n## Setup\nInclude the (combined and minified) JavaScript Load Image script in your HTML\nmarkup:\n\n```html\n<script src=\"js/load-image.all.min.js\"></script>\n```\n\nOr alternatively, choose which components you want to include:\n\n```html\n<script src=\"js/load-image.js\"></script>\n<script src=\"js/load-image-scale.js\"></script>\n<script src=\"js/load-image-meta.js\"></script>\n<script src=\"js/load-image-fetch.js\"></script>\n<script src=\"js/load-image-exif.js\"></script>\n<script src=\"js/load-image-exif-map.js\"></script>\n<script src=\"js/load-image-orientation.js\"></script>\n```\n\n## Usage\n\n### Image loading\nIn your application code, use the **loadImage()** function like this:\n\n```js\ndocument.getElementById('file-input').onchange = function (e) {\n    loadImage(\n        e.target.files[0],\n        function (img) {\n            document.body.appendChild(img);\n        },\n        {maxWidth: 600} // Options\n    );\n};\n```\n\n### Image scaling\nIt is also possible to use the image scaling functionality with an existing\nimage:\n\n```js\nvar scaledImage = loadImage.scale(\n    img, // img or canvas element\n    {maxWidth: 600}\n);\n```\n\n## Requirements\nThe JavaScript Load Image library has zero dependencies.\n\nHowever, JavaScript Load Image is a very suitable complement to the\n[Canvas to Blob](https://github.com/blueimp/JavaScript-Canvas-to-Blob) library.\n\n## API\nThe **loadImage()** function accepts a\n[File](https://developer.mozilla.org/en/DOM/File) or\n[Blob](https://developer.mozilla.org/en/DOM/Blob) object or a simple image URL\n(e.g. `'https://example.org/image.png'`) as first argument.\n\nIf a [File](https://developer.mozilla.org/en/DOM/File) or\n[Blob](https://developer.mozilla.org/en/DOM/Blob) is passed as parameter, it\nreturns a HTML **img** element if the browser supports the\n[URL](https://developer.mozilla.org/en/DOM/window.URL) API or a\n[FileReader](https://developer.mozilla.org/en/DOM/FileReader) object if\nsupported, or **false**.  \nIt always returns a HTML\n[img](https://developer.mozilla.org/en/docs/HTML/Element/Img) element when\npassing an image URL:\n\n```js\ndocument.getElementById('file-input').onchange = function (e) {\n    var loadingImage = loadImage(\n        e.target.files[0],\n        function (img) {\n            document.body.appendChild(img);\n        },\n        {maxWidth: 600}\n    );\n    if (!loadingImage) {\n        // Alternative code ...\n    }\n};\n```\n\nThe **img** element or\n[FileReader](https://developer.mozilla.org/en/DOM/FileReader) object returned by\nthe **loadImage()** function allows to abort the loading process by setting the\n**onload** and **onerror** event handlers to null:\n\n```js\ndocument.getElementById('file-input').onchange = function (e) {\n    var loadingImage = loadImage(\n        e.target.files[0],\n        function (img) {\n            document.body.appendChild(img);\n        },\n        {maxWidth: 600}\n    );\n    loadingImage.onload = loadingImage.onerror = null;\n};\n```\n\nThe second argument must be a **callback** function, which is called when the\nimage has been loaded or an error occurred while loading the image. The callback\nfunction is passed one argument, which is either a HTML **img** element, a\n[canvas](https://developer.mozilla.org/en/HTML/Canvas) element, or an\n[Event](https://developer.mozilla.org/en/DOM/event) object of type **error**:\n\n```js\nvar imageUrl = \"https://example.org/image.png\";\nloadImage(\n    imageUrl,\n    function (img) {\n        if(img.type === \"error\") {\n            console.log(\"Error loading image \" + imageUrl);\n        } else {\n            document.body.appendChild(img);\n        }\n    },\n    {maxWidth: 600}\n);\n```\n\n## Options\nThe optional third argument to **loadImage()** is a map of options:\n\n* **maxWidth**: Defines the maximum width of the img/canvas element.\n* **maxHeight**: Defines the maximum height of the img/canvas element.\n* **minWidth**: Defines the minimum width of the img/canvas element.\n* **minHeight**: Defines the minimum height of the img/canvas element.\n* **sourceWidth**: The width of the sub-rectangle of the source image to draw\ninto the destination canvas.  \nDefaults to the source image width and requires `canvas: true`.\n* **sourceHeight**: The height of the sub-rectangle of the source image to draw\ninto the destination canvas.  \nDefaults to the source image height and requires `canvas: true`.\n* **top**: The top margin of the sub-rectangle of the source image.  \nDefaults to `0` and requires `canvas: true`.\n* **right**: The right margin of the sub-rectangle of the source image.  \nDefaults to `0` and requires `canvas: true`.\n* **bottom**: The bottom margin of the sub-rectangle of the source image.  \nDefaults to `0` and requires `canvas: true`.\n* **left**: The left margin of the sub-rectangle of the source image.  \nDefaults to `0` and requires `canvas: true`.\n* **contain**: Scales the image up/down to contain it in the max dimensions if\nset to `true`.  \nThis emulates the CSS feature\n[background-image: contain](https://developer.mozilla.org/en-US/docs/Web/Guide/CSS/Scaling_background_images#contain).\n* **cover**: Scales the image up/down to cover the max dimensions with the image\ndimensions if set to `true`.  \nThis emulates the CSS feature\n[background-image: cover](https://developer.mozilla.org/en-US/docs/Web/Guide/CSS/Scaling_background_images#cover).\n* **aspectRatio**: Crops the image to the given aspect ratio (e.g. `16/9`).  \nSetting the `aspectRatio` also enables the `crop` option.\n* **pixelRatio**: Defines the ratio of the canvas pixels to the physical image\npixels on the screen.  \nShould be set to `window.devicePixelRatio` unless the scaled image is not\nrendered on screen.  \nDefaults to `1` and requires `canvas: true`.\n* **downsamplingRatio**: Defines the ratio in which the image is downsampled.  \nBy default, images are downsampled in one step. With a ratio of `0.5`, each step\nscales the image to half the size, before reaching the target dimensions.  \nRequires `canvas: true`.\n* **crop**: Crops the image to the maxWidth/maxHeight constraints if set to\n`true`.  \nEnabling the `crop` option also enables the `canvas` option.\n* **orientation**: Transform the canvas according to the specified Exif\norientation, which can be an `integer` in the range of `1` to `8` or the boolean\nvalue `true`.  \nWhen set to `true`, it will set the orientation value based on the EXIF data of\nthe image, which will be parsed automatically if the exif library is available.  \nSetting the `orientation` also enables the `canvas` option.  \nSetting `orientation` to `true` also enables the `meta` option.\n* **meta**: Automatically parses the image meta data if set to `true`.  \nThe meta data is passed to the callback as second argument.  \nIf the file is given as URL and the browser supports the\n[fetch API](https://developer.mozilla.org/en/docs/Web/API/Fetch_API), fetches\nthe file as Blob to be able to parse the meta data.\n* **canvas**: Returns the image as\n[canvas](https://developer.mozilla.org/en/HTML/Canvas) element if set to `true`.\n* **crossOrigin**: Sets the crossOrigin property on the img element for loading\n[CORS enabled images](https://developer.mozilla.org/en-US/docs/HTML/CORS_Enabled_Image).\n* **noRevoke**: By default, the\n[created object URL](https://developer.mozilla.org/en/DOM/window.URL.createObjectURL)\nis revoked after the image has been loaded, except when this option is set to\n`true`.\n\nThey can be used the following way:\n\n```js\nloadImage(\n    fileOrBlobOrUrl,\n    function (img) {\n        document.body.appendChild(img);\n    },\n    {\n        maxWidth: 600,\n        maxHeight: 300,\n        minWidth: 100,\n        minHeight: 50,\n        canvas: true\n    }\n);\n```\n\nAll settings are optional. By default, the image is returned as HTML **img**\nelement without any image size restrictions.\n\n## Meta data parsing\nIf the Load Image Meta extension is included, it is also possible to parse image\nmeta data.  \nThe extension provides the method **loadImage.parseMetaData**, which can be used\nthe following way:\n\n```js\nloadImage.parseMetaData(\n    fileOrBlob,\n    function (data) {\n        if (!data.imageHead) {\n            return;\n        }\n        // Combine data.imageHead with the image body of a resized file\n        // to create scaled images with the original image meta data, e.g.:\n        var blob = new Blob([\n            data.imageHead,\n            // Resized images always have a head size of 20 bytes,\n            // including the JPEG marker and a minimal JFIF header:\n            loadImage.blobSlice.call(resizedImage, 20)\n        ], {type: resizedImage.type});\n    },\n    {\n        maxMetaDataSize: 262144,\n        disableImageHead: false\n    }\n);\n```\n\nThe third argument is an options object which defines the maximum number of\nbytes to parse for the image meta data, allows to disable the imageHead creation\nand is also passed along to segment parsers registered via loadImage extensions,\ne.g. the Exif parser.\n\n**Note:**  \nBlob objects of resized images can be created via\n[canvas.toBlob()](https://github.com/blueimp/JavaScript-Canvas-to-Blob).\n\n### Exif parser\nIf you include the Load Image Exif Parser extension, the argument passed to the\ncallback for **parseMetaData** will contain the additional property **exif** if\nExif data could be found in the given image.  \nThe **exif** object stores the parsed Exif tags:\n\n```js\nvar orientation = data.exif[0x0112];\n```\n\nIt also provides an **exif.get()** method to retrieve the tag value via the\ntag's mapped name:\n\n```js\nvar orientation = data.exif.get('Orientation');\n```\n\nBy default, the only available mapped names are **Orientation** and\n**Thumbnail**.  \nIf you also include the Load Image Exif Map library, additional tag mappings\nbecome available, as well as two additional methods, **exif.getText()** and\n**exif.getAll()**:\n\n```js\nvar flashText = data.exif.getText('Flash'); // e.g.: 'Flash fired, auto mode',\n\n// A map of all parsed tags with their mapped names as keys and their text values:\nvar allTags = data.exif.getAll();\n```\n\nThe Exif parser also adds additional options for the parseMetaData method, to\ndisable certain aspects of the parser:\n\n* **disableExif**: Disables Exif parsing.\n* **disableExifThumbnail**: Disables parsing of the Exif Thumbnail.\n* **disableExifSub**: Disables parsing of the Exif Sub IFD.\n* **disableExifGps**: Disables parsing of the Exif GPS Info IFD.\n\n## License\nThe JavaScript Load Image script is released under the\n[MIT license](https://opensource.org/licenses/MIT).\n\n## Credits\n\n* Image meta data handling implementation based on the help and contribution of\nAchim Stöhr.\n* Exif tags mapping based on Jacob Seidelin's\n[exif-js](https://github.com/jseidelin/exif-js).\n"
  },
  {
    "path": "app_frontend/static/plugin/JavaScript-Load-Image-2.12.2/css/demo.css",
    "content": "/*\n * JavaScript Load Image Demo CSS\n * https://github.com/blueimp/JavaScript-Load-Image\n *\n * Copyright 2013, Sebastian Tschan\n * https://blueimp.net\n *\n * Licensed under the MIT license:\n * https://opensource.org/licenses/MIT\n */\n\nbody {\n  max-width: 750px;\n  margin: 0 auto;\n  padding: 1em;\n  font-family: 'Lucida Grande', 'Lucida Sans Unicode', Arial, sans-serif;\n  font-size: 1em;\n  line-height: 1.4em;\n  background: #222;\n  color: #fff;\n  -webkit-text-size-adjust: 100%;\n      -ms-text-size-adjust: 100%;\n}\na {\n  color: orange;\n  text-decoration: none;\n}\nimg {\n  border: 0;\n  vertical-align: middle;\n}\nh1 {\n  line-height: 1em;\n}\ntable {\n  width: 100%;\n  word-wrap: break-word;\n  table-layout: fixed;\n  border-collapse: collapse;\n}\ntr {\n  background: #fff;\n  color: #222;\n}\ntr:nth-child(odd) {\n  background: #eee;\n  color: #222;\n}\ntd {\n  padding: 10px;\n}\n.result,\n.thumbnail {\n  padding: 20px;\n  background: #fff;\n  color: #222;\n  text-align: center;\n}\n.jcrop-holder {\n  margin: 0 auto;\n}\n\n@media (min-width: 481px) {\n  .navigation {\n    list-style: none;\n    padding: 0;\n  }\n  .navigation li {\n    display: inline-block;\n  }\n  .navigation li:not(:first-child):before {\n    content: '| ';\n  }\n}\n"
  },
  {
    "path": "app_frontend/static/plugin/JavaScript-Load-Image-2.12.2/css/vendor/jquery.Jcrop.css",
    "content": "/* jquery.Jcrop.css v0.9.12 - MIT License */\n/*\n  The outer-most container in a typical Jcrop instance\n  If you are having difficulty with formatting related to styles\n  on a parent element, place any fixes here or in a like selector\n\n  You can also style this element if you want to add a border, etc\n  A better method for styling can be seen below with .jcrop-light\n  (Add a class to the holder and style elements for that extended class)\n*/\n.jcrop-holder {\n  direction: ltr;\n  text-align: left;\n}\n/* Selection Border */\n.jcrop-vline,\n.jcrop-hline {\n  background: #ffffff url(\"Jcrop.gif\");\n  font-size: 0;\n  position: absolute;\n}\n.jcrop-vline {\n  height: 100%;\n  width: 1px !important;\n}\n.jcrop-vline.right {\n  right: 0;\n}\n.jcrop-hline {\n  height: 1px !important;\n  width: 100%;\n}\n.jcrop-hline.bottom {\n  bottom: 0;\n}\n/* Invisible click targets */\n.jcrop-tracker {\n  height: 100%;\n  width: 100%;\n  /* \"turn off\" link highlight */\n  -webkit-tap-highlight-color: transparent;\n  /* disable callout, image save panel */\n  -webkit-touch-callout: none;\n  /* disable cut copy paste */\n  -webkit-user-select: none;\n}\n/* Selection Handles */\n.jcrop-handle {\n  background-color: #333333;\n  border: 1px #eeeeee solid;\n  width: 7px;\n  height: 7px;\n  font-size: 1px;\n}\n.jcrop-handle.ord-n {\n  left: 50%;\n  margin-left: -4px;\n  margin-top: -4px;\n  top: 0;\n}\n.jcrop-handle.ord-s {\n  bottom: 0;\n  left: 50%;\n  margin-bottom: -4px;\n  margin-left: -4px;\n}\n.jcrop-handle.ord-e {\n  margin-right: -4px;\n  margin-top: -4px;\n  right: 0;\n  top: 50%;\n}\n.jcrop-handle.ord-w {\n  left: 0;\n  margin-left: -4px;\n  margin-top: -4px;\n  top: 50%;\n}\n.jcrop-handle.ord-nw {\n  left: 0;\n  margin-left: -4px;\n  margin-top: -4px;\n  top: 0;\n}\n.jcrop-handle.ord-ne {\n  margin-right: -4px;\n  margin-top: -4px;\n  right: 0;\n  top: 0;\n}\n.jcrop-handle.ord-se {\n  bottom: 0;\n  margin-bottom: -4px;\n  margin-right: -4px;\n  right: 0;\n}\n.jcrop-handle.ord-sw {\n  bottom: 0;\n  left: 0;\n  margin-bottom: -4px;\n  margin-left: -4px;\n}\n/* Dragbars */\n.jcrop-dragbar.ord-n,\n.jcrop-dragbar.ord-s {\n  height: 7px;\n  width: 100%;\n}\n.jcrop-dragbar.ord-e,\n.jcrop-dragbar.ord-w {\n  height: 100%;\n  width: 7px;\n}\n.jcrop-dragbar.ord-n {\n  margin-top: -4px;\n}\n.jcrop-dragbar.ord-s {\n  bottom: 0;\n  margin-bottom: -4px;\n}\n.jcrop-dragbar.ord-e {\n  margin-right: -4px;\n  right: 0;\n}\n.jcrop-dragbar.ord-w {\n  margin-left: -4px;\n}\n/* The \"jcrop-light\" class/extension */\n.jcrop-light .jcrop-vline,\n.jcrop-light .jcrop-hline {\n  background: #ffffff;\n  filter: alpha(opacity=70) !important;\n  opacity: .70!important;\n}\n.jcrop-light .jcrop-handle {\n  -moz-border-radius: 3px;\n  -webkit-border-radius: 3px;\n  background-color: #000000;\n  border-color: #ffffff;\n  border-radius: 3px;\n}\n/* The \"jcrop-dark\" class/extension */\n.jcrop-dark .jcrop-vline,\n.jcrop-dark .jcrop-hline {\n  background: #000000;\n  filter: alpha(opacity=70) !important;\n  opacity: 0.7 !important;\n}\n.jcrop-dark .jcrop-handle {\n  -moz-border-radius: 3px;\n  -webkit-border-radius: 3px;\n  background-color: #ffffff;\n  border-color: #000000;\n  border-radius: 3px;\n}\n/* Simple macro to turn off the antlines */\n.solid-line .jcrop-vline,\n.solid-line .jcrop-hline {\n  background: #ffffff;\n}\n/* Fix for twitter bootstrap et al. */\n.jcrop-holder img,\nimg.jcrop-preview {\n  max-width: none;\n}\n"
  },
  {
    "path": "app_frontend/static/plugin/JavaScript-Load-Image-2.12.2/index.html",
    "content": "<!DOCTYPE HTML>\n<!--\n/*\n * JavaScript Load Image Demo\n * https://github.com/blueimp/JavaScript-Load-Image\n *\n * Copyright 2011, Sebastian Tschan\n * https://blueimp.net\n *\n * Licensed under the MIT license:\n * https://opensource.org/licenses/MIT\n */\n-->\n<html lang=\"en\">\n<head>\n<!--[if IE]>\n<meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge,chrome=1\">\n<![endif]-->\n<meta charset=\"utf-8\">\n<title>JavaScript Load Image</title>\n<meta name=\"description\" content=\"JavaScript Load Image is a library to load images provided as File or Blob objects or via URL. It returns an optionally scaled and/or cropped HTML img or canvas element. It also provides a method to parse image meta data to extract Exif tags and thumbnails and to restore the complete image header after resizing.\">\n<meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n<!-- Jcrop is not required by JavaScript Load Image, but included for the demo -->\n<link rel=\"stylesheet\" href=\"css/vendor/jquery.Jcrop.css\">\n<link rel=\"stylesheet\" href=\"css/demo.css\">\n</head>\n<body>\n<h1>JavaScript Load Image Demo</h1>\n<p><a href=\"https://github.com/blueimp/JavaScript-Load-Image\">JavaScript Load Image</a> is a library to load images provided as <a href=\"https://developer.mozilla.org/en/DOM/File\">File</a> or <a href=\"https://developer.mozilla.org/en/DOM/Blob\">Blob</a> objects or via URL.<br>\nIt returns an optionally <strong>scaled</strong> and/or <strong>cropped</strong> HTML <a href=\"https://developer.mozilla.org/en/docs/HTML/Element/Img\">img</a> or <a href=\"https://developer.mozilla.org/en/docs/HTML/Canvas\">canvas</a> element.<br>\nIt also provides a method to parse image meta data to extract <a href=\"https://en.wikipedia.org/wiki/Exif\">Exif</a> tags and thumbnails and to restore the complete image header after resizing.</p>\n<ul class=\"navigation\">\n    <li><a href=\"https://github.com/blueimp/JavaScript-Load-Image/tags\">Download</a></li>\n    <li><a href=\"https://github.com/blueimp/JavaScript-Load-Image\">Source Code</a></li>\n    <li><a href=\"https://github.com/blueimp/JavaScript-Load-Image/blob/master/README.md\">Documentation</a></li>\n    <li><a href=\"test/\">Test</a></li>\n    <li><a href=\"https://blueimp.net\">&copy; Sebastian Tschan</a></li>\n</ul>\n<br>\n<h2>Select an image file</h2>\n<p><input type=\"file\" id=\"file-input\"></p>\n<p>Or <strong>drag &amp; drop</strong> an image file onto this webpage.</p>\n<br>\n<h2>Result</h2>\n<p id=\"actions\" style=\"display:none;\">\n\t<button type=\"button\" id=\"edit\">Edit</button>\n\t<button type=\"button\" id=\"crop\">Crop</button>\n</p>\n<div id=\"result\" class=\"result\">\n    <p>This demo works only in browsers with support for the <a href=\"https://developer.mozilla.org/en/DOM/window.URL\">URL</a> or <a href=\"https://developer.mozilla.org/en/DOM/FileReader\">FileReader</a> API.</p>\n</div>\n<br>\n<div id=\"exif\" class=\"exif\" style=\"display:none;\">\n    <h2>Exif meta data</h2>\n    <p id=\"thumbnail\" class=\"thumbnail\" style=\"display:none;\"></p>\n    <table></table>\n</div>\n<br>\n<script src=\"js/load-image.js\"></script>\n<script src=\"js/load-image-scale.js\"></script>\n<script src=\"js/load-image-meta.js\"></script>\n<script src=\"js/load-image-fetch.js\"></script>\n<script src=\"js/load-image-exif.js\"></script>\n<script src=\"js/load-image-exif-map.js\"></script>\n<script src=\"js/load-image-orientation.js\"></script>\n<!-- jQuery and Jcrop are not required by JavaScript Load Image, but included for the demo -->\n<script src=\"js/vendor/jquery.js\"></script>\n<script src=\"js/vendor/jquery.Jcrop.js\"></script>\n<script src=\"js/demo/demo.js\"></script>\n</body>\n</html>\n"
  },
  {
    "path": "app_frontend/static/plugin/JavaScript-Load-Image-2.12.2/js/demo/demo.js",
    "content": "/*\n * JavaScript Load Image Demo JS\n * https://github.com/blueimp/JavaScript-Load-Image\n *\n * Copyright 2013, Sebastian Tschan\n * https://blueimp.net\n *\n * Licensed under the MIT license:\n * https://opensource.org/licenses/MIT\n */\n\n/* global loadImage, HTMLCanvasElement, $ */\n\n$(function () {\n  'use strict'\n\n  var result = $('#result')\n  var exifNode = $('#exif')\n  var thumbNode = $('#thumbnail')\n  var actionsNode = $('#actions')\n  var currentFile\n  var coordinates\n\n  function displayExifData (exif) {\n    var thumbnail = exif.get('Thumbnail')\n    var tags = exif.getAll()\n    var table = exifNode.find('table').empty()\n    var row = $('<tr></tr>')\n    var cell = $('<td></td>')\n    var prop\n    if (thumbnail) {\n      thumbNode.empty()\n      loadImage(thumbnail, function (img) {\n        thumbNode.append(img).show()\n      }, {orientation: exif.get('Orientation')})\n    }\n    for (prop in tags) {\n      if (tags.hasOwnProperty(prop)) {\n        table.append(\n          row.clone()\n            .append(cell.clone().text(prop))\n            .append(cell.clone().text(tags[prop]))\n        )\n      }\n    }\n    exifNode.show()\n  }\n\n  function updateResults (img, data) {\n    var content\n    if (!(img.src || img instanceof HTMLCanvasElement)) {\n      content = $('<span>Loading image file failed</span>')\n    } else {\n      content = $('<a target=\"_blank\">').append(img)\n        .attr('download', currentFile.name)\n        .attr('href', img.src || img.toDataURL())\n    }\n    result.children().replaceWith(content)\n    if (img.getContext) {\n      actionsNode.show()\n    }\n    if (data && data.exif) {\n      displayExifData(data.exif)\n    }\n  }\n\n  function displayImage (file, options) {\n    currentFile = file\n    if (!loadImage(\n        file,\n        updateResults,\n        options\n      )) {\n      result.children().replaceWith(\n        $('<span>' +\n          'Your browser does not support the URL or FileReader API.' +\n          '</span>')\n      )\n    }\n  }\n\n  function dropChangeHandler (e) {\n    e.preventDefault()\n    e = e.originalEvent\n    var target = e.dataTransfer || e.target\n    var file = target && target.files && target.files[0]\n    var options = {\n      maxWidth: result.width(),\n      canvas: true,\n      pixelRatio: window.devicePixelRatio,\n      downsamplingRatio: 0.5,\n      orientation: true\n    }\n    if (!file) {\n      return\n    }\n    exifNode.hide()\n    thumbNode.hide()\n    displayImage(file, options)\n  }\n\n  // Hide URL/FileReader API requirement message in capable browsers:\n  if (window.createObjectURL || window.URL || window.webkitURL ||\n      window.FileReader) {\n    result.children().hide()\n  }\n\n  $(document)\n    .on('dragover', function (e) {\n      e.preventDefault()\n      e = e.originalEvent\n      e.dataTransfer.dropEffect = 'copy'\n    })\n    .on('drop', dropChangeHandler)\n\n  $('#file-input')\n    .on('change', dropChangeHandler)\n\n  $('#edit')\n    .on('click', function (event) {\n      event.preventDefault()\n      var imgNode = result.find('img, canvas')\n      var img = imgNode[0]\n      var pixelRatio = window.devicePixelRatio || 1\n      imgNode.Jcrop({\n        setSelect: [\n          40,\n          40,\n          (img.width / pixelRatio) - 40,\n          (img.height / pixelRatio) - 40\n        ],\n        onSelect: function (coords) {\n          coordinates = coords\n        },\n        onRelease: function () {\n          coordinates = null\n        }\n      }).parent().on('click', function (event) {\n        event.preventDefault()\n      })\n    })\n\n  $('#crop')\n    .on('click', function (event) {\n      event.preventDefault()\n      var img = result.find('img, canvas')[0]\n      var pixelRatio = window.devicePixelRatio || 1\n      if (img && coordinates) {\n        updateResults(loadImage.scale(img, {\n          left: coordinates.x * pixelRatio,\n          top: coordinates.y * pixelRatio,\n          sourceWidth: coordinates.w * pixelRatio,\n          sourceHeight: coordinates.h * pixelRatio,\n          minWidth: result.width(),\n          maxWidth: result.width(),\n          pixelRatio: pixelRatio,\n          downsamplingRatio: 0.5\n        }))\n        coordinates = null\n      }\n    })\n})\n"
  },
  {
    "path": "app_frontend/static/plugin/JavaScript-Load-Image-2.12.2/js/index.js",
    "content": "module.exports = require('./load-image')\n\nrequire('./load-image-scale')\nrequire('./load-image-meta')\nrequire('./load-image-fetch')\nrequire('./load-image-exif')\nrequire('./load-image-exif-map')\nrequire('./load-image-orientation')\n"
  },
  {
    "path": "app_frontend/static/plugin/JavaScript-Load-Image-2.12.2/js/load-image-exif-map.js",
    "content": "/*\n * JavaScript Load Image Exif Map\n * https://github.com/blueimp/JavaScript-Load-Image\n *\n * Copyright 2013, Sebastian Tschan\n * https://blueimp.net\n *\n * Exif tags mapping based on\n * https://github.com/jseidelin/exif-js\n *\n * Licensed under the MIT license:\n * https://opensource.org/licenses/MIT\n */\n\n/* global define */\n\n;(function (factory) {\n  'use strict'\n  if (typeof define === 'function' && define.amd) {\n    // Register as an anonymous AMD module:\n    define(['./load-image', './load-image-exif'], factory)\n  } else if (typeof module === 'object' && module.exports) {\n    factory(require('./load-image'), require('./load-image-exif'))\n  } else {\n    // Browser globals:\n    factory(window.loadImage)\n  }\n}(function (loadImage) {\n  'use strict'\n\n  loadImage.ExifMap.prototype.tags = {\n    // =================\n    // TIFF tags (IFD0):\n    // =================\n    0x0100: 'ImageWidth',\n    0x0101: 'ImageHeight',\n    0x8769: 'ExifIFDPointer',\n    0x8825: 'GPSInfoIFDPointer',\n    0xA005: 'InteroperabilityIFDPointer',\n    0x0102: 'BitsPerSample',\n    0x0103: 'Compression',\n    0x0106: 'PhotometricInterpretation',\n    0x0112: 'Orientation',\n    0x0115: 'SamplesPerPixel',\n    0x011C: 'PlanarConfiguration',\n    0x0212: 'YCbCrSubSampling',\n    0x0213: 'YCbCrPositioning',\n    0x011A: 'XResolution',\n    0x011B: 'YResolution',\n    0x0128: 'ResolutionUnit',\n    0x0111: 'StripOffsets',\n    0x0116: 'RowsPerStrip',\n    0x0117: 'StripByteCounts',\n    0x0201: 'JPEGInterchangeFormat',\n    0x0202: 'JPEGInterchangeFormatLength',\n    0x012D: 'TransferFunction',\n    0x013E: 'WhitePoint',\n    0x013F: 'PrimaryChromaticities',\n    0x0211: 'YCbCrCoefficients',\n    0x0214: 'ReferenceBlackWhite',\n    0x0132: 'DateTime',\n    0x010E: 'ImageDescription',\n    0x010F: 'Make',\n    0x0110: 'Model',\n    0x0131: 'Software',\n    0x013B: 'Artist',\n    0x8298: 'Copyright',\n    // ==================\n    // Exif Sub IFD tags:\n    // ==================\n    0x9000: 'ExifVersion', // EXIF version\n    0xA000: 'FlashpixVersion', // Flashpix format version\n    0xA001: 'ColorSpace', // Color space information tag\n    0xA002: 'PixelXDimension', // Valid width of meaningful image\n    0xA003: 'PixelYDimension', // Valid height of meaningful image\n    0xA500: 'Gamma',\n    0x9101: 'ComponentsConfiguration', // Information about channels\n    0x9102: 'CompressedBitsPerPixel', // Compressed bits per pixel\n    0x927C: 'MakerNote', // Any desired information written by the manufacturer\n    0x9286: 'UserComment', // Comments by user\n    0xA004: 'RelatedSoundFile', // Name of related sound file\n    0x9003: 'DateTimeOriginal', // Date and time when the original image was generated\n    0x9004: 'DateTimeDigitized', // Date and time when the image was stored digitally\n    0x9290: 'SubSecTime', // Fractions of seconds for DateTime\n    0x9291: 'SubSecTimeOriginal', // Fractions of seconds for DateTimeOriginal\n    0x9292: 'SubSecTimeDigitized', // Fractions of seconds for DateTimeDigitized\n    0x829A: 'ExposureTime', // Exposure time (in seconds)\n    0x829D: 'FNumber',\n    0x8822: 'ExposureProgram', // Exposure program\n    0x8824: 'SpectralSensitivity', // Spectral sensitivity\n    0x8827: 'PhotographicSensitivity', // EXIF 2.3, ISOSpeedRatings in EXIF 2.2\n    0x8828: 'OECF', // Optoelectric conversion factor\n    0x8830: 'SensitivityType',\n    0x8831: 'StandardOutputSensitivity',\n    0x8832: 'RecommendedExposureIndex',\n    0x8833: 'ISOSpeed',\n    0x8834: 'ISOSpeedLatitudeyyy',\n    0x8835: 'ISOSpeedLatitudezzz',\n    0x9201: 'ShutterSpeedValue', // Shutter speed\n    0x9202: 'ApertureValue', // Lens aperture\n    0x9203: 'BrightnessValue', // Value of brightness\n    0x9204: 'ExposureBias', // Exposure bias\n    0x9205: 'MaxApertureValue', // Smallest F number of lens\n    0x9206: 'SubjectDistance', // Distance to subject in meters\n    0x9207: 'MeteringMode', // Metering mode\n    0x9208: 'LightSource', // Kind of light source\n    0x9209: 'Flash', // Flash status\n    0x9214: 'SubjectArea', // Location and area of main subject\n    0x920A: 'FocalLength', // Focal length of the lens in mm\n    0xA20B: 'FlashEnergy', // Strobe energy in BCPS\n    0xA20C: 'SpatialFrequencyResponse',\n    0xA20E: 'FocalPlaneXResolution', // Number of pixels in width direction per FPRUnit\n    0xA20F: 'FocalPlaneYResolution', // Number of pixels in height direction per FPRUnit\n    0xA210: 'FocalPlaneResolutionUnit', // Unit for measuring the focal plane resolution\n    0xA214: 'SubjectLocation', // Location of subject in image\n    0xA215: 'ExposureIndex', // Exposure index selected on camera\n    0xA217: 'SensingMethod', // Image sensor type\n    0xA300: 'FileSource', // Image source (3 == DSC)\n    0xA301: 'SceneType', // Scene type (1 == directly photographed)\n    0xA302: 'CFAPattern', // Color filter array geometric pattern\n    0xA401: 'CustomRendered', // Special processing\n    0xA402: 'ExposureMode', // Exposure mode\n    0xA403: 'WhiteBalance', // 1 = auto white balance, 2 = manual\n    0xA404: 'DigitalZoomRatio', // Digital zoom ratio\n    0xA405: 'FocalLengthIn35mmFilm',\n    0xA406: 'SceneCaptureType', // Type of scene\n    0xA407: 'GainControl', // Degree of overall image gain adjustment\n    0xA408: 'Contrast', // Direction of contrast processing applied by camera\n    0xA409: 'Saturation', // Direction of saturation processing applied by camera\n    0xA40A: 'Sharpness', // Direction of sharpness processing applied by camera\n    0xA40B: 'DeviceSettingDescription',\n    0xA40C: 'SubjectDistanceRange', // Distance to subject\n    0xA420: 'ImageUniqueID', // Identifier assigned uniquely to each image\n    0xA430: 'CameraOwnerName',\n    0xA431: 'BodySerialNumber',\n    0xA432: 'LensSpecification',\n    0xA433: 'LensMake',\n    0xA434: 'LensModel',\n    0xA435: 'LensSerialNumber',\n    // ==============\n    // GPS Info tags:\n    // ==============\n    0x0000: 'GPSVersionID',\n    0x0001: 'GPSLatitudeRef',\n    0x0002: 'GPSLatitude',\n    0x0003: 'GPSLongitudeRef',\n    0x0004: 'GPSLongitude',\n    0x0005: 'GPSAltitudeRef',\n    0x0006: 'GPSAltitude',\n    0x0007: 'GPSTimeStamp',\n    0x0008: 'GPSSatellites',\n    0x0009: 'GPSStatus',\n    0x000A: 'GPSMeasureMode',\n    0x000B: 'GPSDOP',\n    0x000C: 'GPSSpeedRef',\n    0x000D: 'GPSSpeed',\n    0x000E: 'GPSTrackRef',\n    0x000F: 'GPSTrack',\n    0x0010: 'GPSImgDirectionRef',\n    0x0011: 'GPSImgDirection',\n    0x0012: 'GPSMapDatum',\n    0x0013: 'GPSDestLatitudeRef',\n    0x0014: 'GPSDestLatitude',\n    0x0015: 'GPSDestLongitudeRef',\n    0x0016: 'GPSDestLongitude',\n    0x0017: 'GPSDestBearingRef',\n    0x0018: 'GPSDestBearing',\n    0x0019: 'GPSDestDistanceRef',\n    0x001A: 'GPSDestDistance',\n    0x001B: 'GPSProcessingMethod',\n    0x001C: 'GPSAreaInformation',\n    0x001D: 'GPSDateStamp',\n    0x001E: 'GPSDifferential',\n    0x001F: 'GPSHPositioningError'\n  }\n\n  loadImage.ExifMap.prototype.stringValues = {\n    ExposureProgram: {\n      0: 'Undefined',\n      1: 'Manual',\n      2: 'Normal program',\n      3: 'Aperture priority',\n      4: 'Shutter priority',\n      5: 'Creative program',\n      6: 'Action program',\n      7: 'Portrait mode',\n      8: 'Landscape mode'\n    },\n    MeteringMode: {\n      0: 'Unknown',\n      1: 'Average',\n      2: 'CenterWeightedAverage',\n      3: 'Spot',\n      4: 'MultiSpot',\n      5: 'Pattern',\n      6: 'Partial',\n      255: 'Other'\n    },\n    LightSource: {\n      0: 'Unknown',\n      1: 'Daylight',\n      2: 'Fluorescent',\n      3: 'Tungsten (incandescent light)',\n      4: 'Flash',\n      9: 'Fine weather',\n      10: 'Cloudy weather',\n      11: 'Shade',\n      12: 'Daylight fluorescent (D 5700 - 7100K)',\n      13: 'Day white fluorescent (N 4600 - 5400K)',\n      14: 'Cool white fluorescent (W 3900 - 4500K)',\n      15: 'White fluorescent (WW 3200 - 3700K)',\n      17: 'Standard light A',\n      18: 'Standard light B',\n      19: 'Standard light C',\n      20: 'D55',\n      21: 'D65',\n      22: 'D75',\n      23: 'D50',\n      24: 'ISO studio tungsten',\n      255: 'Other'\n    },\n    Flash: {\n      0x0000: 'Flash did not fire',\n      0x0001: 'Flash fired',\n      0x0005: 'Strobe return light not detected',\n      0x0007: 'Strobe return light detected',\n      0x0009: 'Flash fired, compulsory flash mode',\n      0x000D: 'Flash fired, compulsory flash mode, return light not detected',\n      0x000F: 'Flash fired, compulsory flash mode, return light detected',\n      0x0010: 'Flash did not fire, compulsory flash mode',\n      0x0018: 'Flash did not fire, auto mode',\n      0x0019: 'Flash fired, auto mode',\n      0x001D: 'Flash fired, auto mode, return light not detected',\n      0x001F: 'Flash fired, auto mode, return light detected',\n      0x0020: 'No flash function',\n      0x0041: 'Flash fired, red-eye reduction mode',\n      0x0045: 'Flash fired, red-eye reduction mode, return light not detected',\n      0x0047: 'Flash fired, red-eye reduction mode, return light detected',\n      0x0049: 'Flash fired, compulsory flash mode, red-eye reduction mode',\n      0x004D: 'Flash fired, compulsory flash mode, red-eye reduction mode, return light not detected',\n      0x004F: 'Flash fired, compulsory flash mode, red-eye reduction mode, return light detected',\n      0x0059: 'Flash fired, auto mode, red-eye reduction mode',\n      0x005D: 'Flash fired, auto mode, return light not detected, red-eye reduction mode',\n      0x005F: 'Flash fired, auto mode, return light detected, red-eye reduction mode'\n    },\n    SensingMethod: {\n      1: 'Undefined',\n      2: 'One-chip color area sensor',\n      3: 'Two-chip color area sensor',\n      4: 'Three-chip color area sensor',\n      5: 'Color sequential area sensor',\n      7: 'Trilinear sensor',\n      8: 'Color sequential linear sensor'\n    },\n    SceneCaptureType: {\n      0: 'Standard',\n      1: 'Landscape',\n      2: 'Portrait',\n      3: 'Night scene'\n    },\n    SceneType: {\n      1: 'Directly photographed'\n    },\n    CustomRendered: {\n      0: 'Normal process',\n      1: 'Custom process'\n    },\n    WhiteBalance: {\n      0: 'Auto white balance',\n      1: 'Manual white balance'\n    },\n    GainControl: {\n      0: 'None',\n      1: 'Low gain up',\n      2: 'High gain up',\n      3: 'Low gain down',\n      4: 'High gain down'\n    },\n    Contrast: {\n      0: 'Normal',\n      1: 'Soft',\n      2: 'Hard'\n    },\n    Saturation: {\n      0: 'Normal',\n      1: 'Low saturation',\n      2: 'High saturation'\n    },\n    Sharpness: {\n      0: 'Normal',\n      1: 'Soft',\n      2: 'Hard'\n    },\n    SubjectDistanceRange: {\n      0: 'Unknown',\n      1: 'Macro',\n      2: 'Close view',\n      3: 'Distant view'\n    },\n    FileSource: {\n      3: 'DSC'\n    },\n    ComponentsConfiguration: {\n      0: '',\n      1: 'Y',\n      2: 'Cb',\n      3: 'Cr',\n      4: 'R',\n      5: 'G',\n      6: 'B'\n    },\n    Orientation: {\n      1: 'top-left',\n      2: 'top-right',\n      3: 'bottom-right',\n      4: 'bottom-left',\n      5: 'left-top',\n      6: 'right-top',\n      7: 'right-bottom',\n      8: 'left-bottom'\n    }\n  }\n\n  loadImage.ExifMap.prototype.getText = function (id) {\n    var value = this.get(id)\n    switch (id) {\n      case 'LightSource':\n      case 'Flash':\n      case 'MeteringMode':\n      case 'ExposureProgram':\n      case 'SensingMethod':\n      case 'SceneCaptureType':\n      case 'SceneType':\n      case 'CustomRendered':\n      case 'WhiteBalance':\n      case 'GainControl':\n      case 'Contrast':\n      case 'Saturation':\n      case 'Sharpness':\n      case 'SubjectDistanceRange':\n      case 'FileSource':\n      case 'Orientation':\n        return this.stringValues[id][value]\n      case 'ExifVersion':\n      case 'FlashpixVersion':\n        if (!value) return\n        return String.fromCharCode(value[0], value[1], value[2], value[3])\n      case 'ComponentsConfiguration':\n        if (!value) return\n        return this.stringValues[id][value[0]] +\n        this.stringValues[id][value[1]] +\n        this.stringValues[id][value[2]] +\n        this.stringValues[id][value[3]]\n      case 'GPSVersionID':\n        if (!value) return\n        return value[0] + '.' + value[1] + '.' + value[2] + '.' + value[3]\n    }\n    return String(value)\n  }\n\n  ;(function (exifMapPrototype) {\n    var tags = exifMapPrototype.tags\n    var map = exifMapPrototype.map\n    var prop\n    // Map the tag names to tags:\n    for (prop in tags) {\n      if (tags.hasOwnProperty(prop)) {\n        map[tags[prop]] = prop\n      }\n    }\n  }(loadImage.ExifMap.prototype))\n\n  loadImage.ExifMap.prototype.getAll = function () {\n    var map = {}\n    var prop\n    var id\n    for (prop in this) {\n      if (this.hasOwnProperty(prop)) {\n        id = this.tags[prop]\n        if (id) {\n          map[id] = this.getText(id)\n        }\n      }\n    }\n    return map\n  }\n}))\n"
  },
  {
    "path": "app_frontend/static/plugin/JavaScript-Load-Image-2.12.2/js/load-image-exif.js",
    "content": "/*\n * JavaScript Load Image Exif Parser\n * https://github.com/blueimp/JavaScript-Load-Image\n *\n * Copyright 2013, Sebastian Tschan\n * https://blueimp.net\n *\n * Licensed under the MIT license:\n * https://opensource.org/licenses/MIT\n */\n\n/* global define */\n\n;(function (factory) {\n  'use strict'\n  if (typeof define === 'function' && define.amd) {\n    // Register as an anonymous AMD module:\n    define(['./load-image', './load-image-meta'], factory)\n  } else if (typeof module === 'object' && module.exports) {\n    factory(require('./load-image'), require('./load-image-meta'))\n  } else {\n    // Browser globals:\n    factory(window.loadImage)\n  }\n}(function (loadImage) {\n  'use strict'\n\n  loadImage.ExifMap = function () {\n    return this\n  }\n\n  loadImage.ExifMap.prototype.map = {\n    'Orientation': 0x0112\n  }\n\n  loadImage.ExifMap.prototype.get = function (id) {\n    return this[id] || this[this.map[id]]\n  }\n\n  loadImage.getExifThumbnail = function (dataView, offset, length) {\n    var hexData,\n      i,\n      b\n    if (!length || offset + length > dataView.byteLength) {\n      console.log('Invalid Exif data: Invalid thumbnail data.')\n      return\n    }\n    hexData = []\n    for (i = 0; i < length; i += 1) {\n      b = dataView.getUint8(offset + i)\n      hexData.push((b < 16 ? '0' : '') + b.toString(16))\n    }\n    return 'data:image/jpeg,%' + hexData.join('%')\n  }\n\n  loadImage.exifTagTypes = {\n    // byte, 8-bit unsigned int:\n    1: {\n      getValue: function (dataView, dataOffset) {\n        return dataView.getUint8(dataOffset)\n      },\n      size: 1\n    },\n    // ascii, 8-bit byte:\n    2: {\n      getValue: function (dataView, dataOffset) {\n        return String.fromCharCode(dataView.getUint8(dataOffset))\n      },\n      size: 1,\n      ascii: true\n    },\n    // short, 16 bit int:\n    3: {\n      getValue: function (dataView, dataOffset, littleEndian) {\n        return dataView.getUint16(dataOffset, littleEndian)\n      },\n      size: 2\n    },\n    // long, 32 bit int:\n    4: {\n      getValue: function (dataView, dataOffset, littleEndian) {\n        return dataView.getUint32(dataOffset, littleEndian)\n      },\n      size: 4\n    },\n    // rational = two long values, first is numerator, second is denominator:\n    5: {\n      getValue: function (dataView, dataOffset, littleEndian) {\n        return dataView.getUint32(dataOffset, littleEndian) /\n        dataView.getUint32(dataOffset + 4, littleEndian)\n      },\n      size: 8\n    },\n    // slong, 32 bit signed int:\n    9: {\n      getValue: function (dataView, dataOffset, littleEndian) {\n        return dataView.getInt32(dataOffset, littleEndian)\n      },\n      size: 4\n    },\n    // srational, two slongs, first is numerator, second is denominator:\n    10: {\n      getValue: function (dataView, dataOffset, littleEndian) {\n        return dataView.getInt32(dataOffset, littleEndian) /\n        dataView.getInt32(dataOffset + 4, littleEndian)\n      },\n      size: 8\n    }\n  }\n  // undefined, 8-bit byte, value depending on field:\n  loadImage.exifTagTypes[7] = loadImage.exifTagTypes[1]\n\n  loadImage.getExifValue = function (dataView, tiffOffset, offset, type, length, littleEndian) {\n    var tagType = loadImage.exifTagTypes[type]\n    var tagSize\n    var dataOffset\n    var values\n    var i\n    var str\n    var c\n    if (!tagType) {\n      console.log('Invalid Exif data: Invalid tag type.')\n      return\n    }\n    tagSize = tagType.size * length\n    // Determine if the value is contained in the dataOffset bytes,\n    // or if the value at the dataOffset is a pointer to the actual data:\n    dataOffset = tagSize > 4\n      ? tiffOffset + dataView.getUint32(offset + 8, littleEndian)\n      : (offset + 8)\n    if (dataOffset + tagSize > dataView.byteLength) {\n      console.log('Invalid Exif data: Invalid data offset.')\n      return\n    }\n    if (length === 1) {\n      return tagType.getValue(dataView, dataOffset, littleEndian)\n    }\n    values = []\n    for (i = 0; i < length; i += 1) {\n      values[i] = tagType.getValue(dataView, dataOffset + i * tagType.size, littleEndian)\n    }\n    if (tagType.ascii) {\n      str = ''\n      // Concatenate the chars:\n      for (i = 0; i < values.length; i += 1) {\n        c = values[i]\n        // Ignore the terminating NULL byte(s):\n        if (c === '\\u0000') {\n          break\n        }\n        str += c\n      }\n      return str\n    }\n    return values\n  }\n\n  loadImage.parseExifTag = function (dataView, tiffOffset, offset, littleEndian, data) {\n    var tag = dataView.getUint16(offset, littleEndian)\n    data.exif[tag] = loadImage.getExifValue(\n      dataView,\n      tiffOffset,\n      offset,\n      dataView.getUint16(offset + 2, littleEndian), // tag type\n      dataView.getUint32(offset + 4, littleEndian), // tag length\n      littleEndian\n    )\n  }\n\n  loadImage.parseExifTags = function (dataView, tiffOffset, dirOffset, littleEndian, data) {\n    var tagsNumber,\n      dirEndOffset,\n      i\n    if (dirOffset + 6 > dataView.byteLength) {\n      console.log('Invalid Exif data: Invalid directory offset.')\n      return\n    }\n    tagsNumber = dataView.getUint16(dirOffset, littleEndian)\n    dirEndOffset = dirOffset + 2 + 12 * tagsNumber\n    if (dirEndOffset + 4 > dataView.byteLength) {\n      console.log('Invalid Exif data: Invalid directory size.')\n      return\n    }\n    for (i = 0; i < tagsNumber; i += 1) {\n      this.parseExifTag(\n        dataView,\n        tiffOffset,\n        dirOffset + 2 + 12 * i, // tag offset\n        littleEndian,\n        data\n      )\n    }\n    // Return the offset to the next directory:\n    return dataView.getUint32(dirEndOffset, littleEndian)\n  }\n\n  loadImage.parseExifData = function (dataView, offset, length, data, options) {\n    if (options.disableExif) {\n      return\n    }\n    var tiffOffset = offset + 10\n    var littleEndian\n    var dirOffset\n    var thumbnailData\n    // Check for the ASCII code for \"Exif\" (0x45786966):\n    if (dataView.getUint32(offset + 4) !== 0x45786966) {\n      // No Exif data, might be XMP data instead\n      return\n    }\n    if (tiffOffset + 8 > dataView.byteLength) {\n      console.log('Invalid Exif data: Invalid segment size.')\n      return\n    }\n    // Check for the two null bytes:\n    if (dataView.getUint16(offset + 8) !== 0x0000) {\n      console.log('Invalid Exif data: Missing byte alignment offset.')\n      return\n    }\n    // Check the byte alignment:\n    switch (dataView.getUint16(tiffOffset)) {\n      case 0x4949:\n        littleEndian = true\n        break\n      case 0x4D4D:\n        littleEndian = false\n        break\n      default:\n        console.log('Invalid Exif data: Invalid byte alignment marker.')\n        return\n    }\n    // Check for the TIFF tag marker (0x002A):\n    if (dataView.getUint16(tiffOffset + 2, littleEndian) !== 0x002A) {\n      console.log('Invalid Exif data: Missing TIFF marker.')\n      return\n    }\n    // Retrieve the directory offset bytes, usually 0x00000008 or 8 decimal:\n    dirOffset = dataView.getUint32(tiffOffset + 4, littleEndian)\n    // Create the exif object to store the tags:\n    data.exif = new loadImage.ExifMap()\n    // Parse the tags of the main image directory and retrieve the\n    // offset to the next directory, usually the thumbnail directory:\n    dirOffset = loadImage.parseExifTags(\n      dataView,\n      tiffOffset,\n      tiffOffset + dirOffset,\n      littleEndian,\n      data\n    )\n    if (dirOffset && !options.disableExifThumbnail) {\n      thumbnailData = {exif: {}}\n      dirOffset = loadImage.parseExifTags(\n        dataView,\n        tiffOffset,\n        tiffOffset + dirOffset,\n        littleEndian,\n        thumbnailData\n      )\n      // Check for JPEG Thumbnail offset:\n      if (thumbnailData.exif[0x0201]) {\n        data.exif.Thumbnail = loadImage.getExifThumbnail(\n          dataView,\n          tiffOffset + thumbnailData.exif[0x0201],\n          thumbnailData.exif[0x0202] // Thumbnail data length\n        )\n      }\n    }\n    // Check for Exif Sub IFD Pointer:\n    if (data.exif[0x8769] && !options.disableExifSub) {\n      loadImage.parseExifTags(\n        dataView,\n        tiffOffset,\n        tiffOffset + data.exif[0x8769], // directory offset\n        littleEndian,\n        data\n      )\n    }\n    // Check for GPS Info IFD Pointer:\n    if (data.exif[0x8825] && !options.disableExifGps) {\n      loadImage.parseExifTags(\n        dataView,\n        tiffOffset,\n        tiffOffset + data.exif[0x8825], // directory offset\n        littleEndian,\n        data\n      )\n    }\n  }\n\n  // Registers the Exif parser for the APP1 JPEG meta data segment:\n  loadImage.metaDataParsers.jpeg[0xffe1].push(loadImage.parseExifData)\n\n  // Adds the following properties to the parseMetaData callback data:\n  // * exif: The exif tags, parsed by the parseExifData method\n\n  // Adds the following options to the parseMetaData method:\n  // * disableExif: Disables Exif parsing.\n  // * disableExifThumbnail: Disables parsing of the Exif Thumbnail.\n  // * disableExifSub: Disables parsing of the Exif Sub IFD.\n  // * disableExifGps: Disables parsing of the Exif GPS Info IFD.\n}))\n"
  },
  {
    "path": "app_frontend/static/plugin/JavaScript-Load-Image-2.12.2/js/load-image-fetch.js",
    "content": "/*\n * JavaScript Load Image Fetch\n * https://github.com/blueimp/JavaScript-Load-Image\n *\n * Copyright 2017, Sebastian Tschan\n * https://blueimp.net\n *\n * Licensed under the MIT license:\n * https://opensource.org/licenses/MIT\n */\n\n/* global define, fetch, Request */\n\n;(function (factory) {\n  'use strict'\n  if (typeof define === 'function' && define.amd) {\n    // Register as an anonymous AMD module:\n    define(['./load-image', './load-image-meta'], factory)\n  } else if (typeof module === 'object' && module.exports) {\n    factory(require('./load-image'), require('./load-image-meta'))\n  } else {\n    // Browser globals:\n    factory(window.loadImage)\n  }\n}(function (loadImage) {\n  'use strict'\n\n  if ('fetch' in window && 'Request' in window) {\n    loadImage.fetchBlob = function (url, callback, options) {\n      if (loadImage.hasMetaOption(options)) {\n        return fetch(new Request(url, options)).then(function (response) {\n          return response.blob()\n        }).then(callback).catch(function (err) {\n          console.log(err)\n          callback()\n        })\n      } else {\n        callback()\n      }\n    }\n  }\n}))\n"
  },
  {
    "path": "app_frontend/static/plugin/JavaScript-Load-Image-2.12.2/js/load-image-meta.js",
    "content": "/*\n * JavaScript Load Image Meta\n * https://github.com/blueimp/JavaScript-Load-Image\n *\n * Copyright 2013, Sebastian Tschan\n * https://blueimp.net\n *\n * Image meta data handling implementation\n * based on the help and contribution of\n * Achim Stöhr.\n *\n * Licensed under the MIT license:\n * https://opensource.org/licenses/MIT\n */\n\n/* global define, Blob */\n\n;(function (factory) {\n  'use strict'\n  if (typeof define === 'function' && define.amd) {\n    // Register as an anonymous AMD module:\n    define(['./load-image'], factory)\n  } else if (typeof module === 'object' && module.exports) {\n    factory(require('./load-image'))\n  } else {\n    // Browser globals:\n    factory(window.loadImage)\n  }\n}(function (loadImage) {\n  'use strict'\n\n  var hasblobSlice = window.Blob && (Blob.prototype.slice ||\n  Blob.prototype.webkitSlice || Blob.prototype.mozSlice)\n\n  loadImage.blobSlice = hasblobSlice && function () {\n    var slice = this.slice || this.webkitSlice || this.mozSlice\n    return slice.apply(this, arguments)\n  }\n\n  loadImage.metaDataParsers = {\n    jpeg: {\n      0xffe1: [] // APP1 marker\n    }\n  }\n\n  // Parses image meta data and calls the callback with an object argument\n  // with the following properties:\n  // * imageHead: The complete image head as ArrayBuffer (Uint8Array for IE10)\n  // The options arguments accepts an object and supports the following properties:\n  // * maxMetaDataSize: Defines the maximum number of bytes to parse.\n  // * disableImageHead: Disables creating the imageHead property.\n  loadImage.parseMetaData = function (file, callback, options, data) {\n    options = options || {}\n    data = data || {}\n    var that = this\n    // 256 KiB should contain all EXIF/ICC/IPTC segments:\n    var maxMetaDataSize = options.maxMetaDataSize || 262144\n    var noMetaData = !(window.DataView && file && file.size >= 12 &&\n                      file.type === 'image/jpeg' && loadImage.blobSlice)\n    if (noMetaData || !loadImage.readFile(\n        loadImage.blobSlice.call(file, 0, maxMetaDataSize),\n        function (e) {\n          if (e.target.error) {\n            // FileReader error\n            console.log(e.target.error)\n            callback(data)\n            return\n          }\n          // Note on endianness:\n          // Since the marker and length bytes in JPEG files are always\n          // stored in big endian order, we can leave the endian parameter\n          // of the DataView methods undefined, defaulting to big endian.\n          var buffer = e.target.result\n          var dataView = new DataView(buffer)\n          var offset = 2\n          var maxOffset = dataView.byteLength - 4\n          var headLength = offset\n          var markerBytes\n          var markerLength\n          var parsers\n          var i\n          // Check for the JPEG marker (0xffd8):\n          if (dataView.getUint16(0) === 0xffd8) {\n            while (offset < maxOffset) {\n              markerBytes = dataView.getUint16(offset)\n              // Search for APPn (0xffeN) and COM (0xfffe) markers,\n              // which contain application-specific meta-data like\n              // Exif, ICC and IPTC data and text comments:\n              if ((markerBytes >= 0xffe0 && markerBytes <= 0xffef) ||\n                markerBytes === 0xfffe) {\n                // The marker bytes (2) are always followed by\n                // the length bytes (2), indicating the length of the\n                // marker segment, which includes the length bytes,\n                // but not the marker bytes, so we add 2:\n                markerLength = dataView.getUint16(offset + 2) + 2\n                if (offset + markerLength > dataView.byteLength) {\n                  console.log('Invalid meta data: Invalid segment size.')\n                  break\n                }\n                parsers = loadImage.metaDataParsers.jpeg[markerBytes]\n                if (parsers) {\n                  for (i = 0; i < parsers.length; i += 1) {\n                    parsers[i].call(\n                      that,\n                      dataView,\n                      offset,\n                      markerLength,\n                      data,\n                      options\n                    )\n                  }\n                }\n                offset += markerLength\n                headLength = offset\n              } else {\n                // Not an APPn or COM marker, probably safe to\n                // assume that this is the end of the meta data\n                break\n              }\n            }\n            // Meta length must be longer than JPEG marker (2)\n            // plus APPn marker (2), followed by length bytes (2):\n            if (!options.disableImageHead && headLength > 6) {\n              if (buffer.slice) {\n                data.imageHead = buffer.slice(0, headLength)\n              } else {\n                // Workaround for IE10, which does not yet\n                // support ArrayBuffer.slice:\n                data.imageHead = new Uint8Array(buffer)\n                  .subarray(0, headLength)\n              }\n            }\n          } else {\n            console.log('Invalid JPEG file: Missing JPEG marker.')\n          }\n          callback(data)\n        },\n        'readAsArrayBuffer'\n      )) {\n      callback(data)\n    }\n  }\n\n  // Determines if meta data should be loaded automatically:\n  loadImage.hasMetaOption = function (options) {\n    return options && options.meta\n  }\n\n  var originalTransform = loadImage.transform\n  loadImage.transform = function (img, options, callback, file, data) {\n    if (loadImage.hasMetaOption(options)) {\n      loadImage.parseMetaData(file, function (data) {\n        originalTransform.call(loadImage, img, options, callback, file, data)\n      }, options, data)\n    } else {\n      originalTransform.apply(loadImage, arguments)\n    }\n  }\n}))\n"
  },
  {
    "path": "app_frontend/static/plugin/JavaScript-Load-Image-2.12.2/js/load-image-orientation.js",
    "content": "/*\n * JavaScript Load Image Orientation\n * https://github.com/blueimp/JavaScript-Load-Image\n *\n * Copyright 2013, Sebastian Tschan\n * https://blueimp.net\n *\n * Licensed under the MIT license:\n * https://opensource.org/licenses/MIT\n */\n\n/* global define */\n\n;(function (factory) {\n  'use strict'\n  if (typeof define === 'function' && define.amd) {\n    // Register as an anonymous AMD module:\n    define(['./load-image', './load-image-scale', './load-image-meta'], factory)\n  } else if (typeof module === 'object' && module.exports) {\n    factory(\n      require('./load-image'),\n      require('./load-image-scale'),\n      require('./load-image-meta')\n    )\n  } else {\n    // Browser globals:\n    factory(window.loadImage)\n  }\n}(function (loadImage) {\n  'use strict'\n\n  var originalHasCanvasOption = loadImage.hasCanvasOption\n  var originalHasMetaOption = loadImage.hasMetaOption\n  var originalTransformCoordinates = loadImage.transformCoordinates\n  var originalGetTransformedOptions = loadImage.getTransformedOptions\n\n  // Determines if the target image should be a canvas element:\n  loadImage.hasCanvasOption = function (options) {\n    return !!options.orientation ||\n      originalHasCanvasOption.call(loadImage, options)\n  }\n\n  // Determines if meta data should be loaded automatically:\n  loadImage.hasMetaOption = function (options) {\n    return options && options.orientation === true ||\n      originalHasMetaOption.call(loadImage, options)\n  }\n\n  // Transform image orientation based on\n  // the given EXIF orientation option:\n  loadImage.transformCoordinates = function (canvas, options) {\n    originalTransformCoordinates.call(loadImage, canvas, options)\n    var ctx = canvas.getContext('2d')\n    var width = canvas.width\n    var height = canvas.height\n    var styleWidth = canvas.style.width\n    var styleHeight = canvas.style.height\n    var orientation = options.orientation\n    if (!orientation || orientation > 8) {\n      return\n    }\n    if (orientation > 4) {\n      canvas.width = height\n      canvas.height = width\n      canvas.style.width = styleHeight\n      canvas.style.height = styleWidth\n    }\n    switch (orientation) {\n      case 2:\n        // horizontal flip\n        ctx.translate(width, 0)\n        ctx.scale(-1, 1)\n        break\n      case 3:\n        // 180° rotate left\n        ctx.translate(width, height)\n        ctx.rotate(Math.PI)\n        break\n      case 4:\n        // vertical flip\n        ctx.translate(0, height)\n        ctx.scale(1, -1)\n        break\n      case 5:\n        // vertical flip + 90 rotate right\n        ctx.rotate(0.5 * Math.PI)\n        ctx.scale(1, -1)\n        break\n      case 6:\n        // 90° rotate right\n        ctx.rotate(0.5 * Math.PI)\n        ctx.translate(0, -height)\n        break\n      case 7:\n        // horizontal flip + 90 rotate right\n        ctx.rotate(0.5 * Math.PI)\n        ctx.translate(width, -height)\n        ctx.scale(-1, 1)\n        break\n      case 8:\n        // 90° rotate left\n        ctx.rotate(-0.5 * Math.PI)\n        ctx.translate(-width, 0)\n        break\n    }\n  }\n\n  // Transforms coordinate and dimension options\n  // based on the given orientation option:\n  loadImage.getTransformedOptions = function (img, opts, data) {\n    var options = originalGetTransformedOptions.call(loadImage, img, opts)\n    var orientation = options.orientation\n    var newOptions\n    var i\n    if (orientation === true && data && data.exif) {\n      orientation = data.exif.get('Orientation')\n    }\n    if (!orientation || orientation > 8 || orientation === 1) {\n      return options\n    }\n    newOptions = {}\n    for (i in options) {\n      if (options.hasOwnProperty(i)) {\n        newOptions[i] = options[i]\n      }\n    }\n    newOptions.orientation = orientation\n    switch (orientation) {\n      case 2:\n        // horizontal flip\n        newOptions.left = options.right\n        newOptions.right = options.left\n        break\n      case 3:\n        // 180° rotate left\n        newOptions.left = options.right\n        newOptions.top = options.bottom\n        newOptions.right = options.left\n        newOptions.bottom = options.top\n        break\n      case 4:\n        // vertical flip\n        newOptions.top = options.bottom\n        newOptions.bottom = options.top\n        break\n      case 5:\n        // vertical flip + 90 rotate right\n        newOptions.left = options.top\n        newOptions.top = options.left\n        newOptions.right = options.bottom\n        newOptions.bottom = options.right\n        break\n      case 6:\n        // 90° rotate right\n        newOptions.left = options.top\n        newOptions.top = options.right\n        newOptions.right = options.bottom\n        newOptions.bottom = options.left\n        break\n      case 7:\n        // horizontal flip + 90 rotate right\n        newOptions.left = options.bottom\n        newOptions.top = options.right\n        newOptions.right = options.top\n        newOptions.bottom = options.left\n        break\n      case 8:\n        // 90° rotate left\n        newOptions.left = options.bottom\n        newOptions.top = options.left\n        newOptions.right = options.top\n        newOptions.bottom = options.right\n        break\n    }\n    if (newOptions.orientation > 4) {\n      newOptions.maxWidth = options.maxHeight\n      newOptions.maxHeight = options.maxWidth\n      newOptions.minWidth = options.minHeight\n      newOptions.minHeight = options.minWidth\n      newOptions.sourceWidth = options.sourceHeight\n      newOptions.sourceHeight = options.sourceWidth\n    }\n    return newOptions\n  }\n}))\n"
  },
  {
    "path": "app_frontend/static/plugin/JavaScript-Load-Image-2.12.2/js/load-image-scale.js",
    "content": "/*\n * JavaScript Load Image Scaling\n * https://github.com/blueimp/JavaScript-Load-Image\n *\n * Copyright 2011, Sebastian Tschan\n * https://blueimp.net\n *\n * Licensed under the MIT license:\n * https://opensource.org/licenses/MIT\n */\n\n/* global define */\n\n;(function (factory) {\n  'use strict'\n  if (typeof define === 'function' && define.amd) {\n    // Register as an anonymous AMD module:\n    define(['./load-image'], factory)\n  } else if (typeof module === 'object' && module.exports) {\n    factory(require('./load-image'))\n  } else {\n    // Browser globals:\n    factory(window.loadImage)\n  }\n}(function (loadImage) {\n  'use strict'\n\n  var originalTransform = loadImage.transform\n\n  loadImage.transform = function (img, options, callback, file, data) {\n    originalTransform.call(\n      loadImage,\n      loadImage.scale(img, options, data),\n      options,\n      callback,\n      file,\n      data\n    )\n  }\n\n  // Transform image coordinates, allows to override e.g.\n  // the canvas orientation based on the orientation option,\n  // gets canvas, options passed as arguments:\n  loadImage.transformCoordinates = function () {\n    return\n  }\n\n  // Returns transformed options, allows to override e.g.\n  // maxWidth, maxHeight and crop options based on the aspectRatio.\n  // gets img, options passed as arguments:\n  loadImage.getTransformedOptions = function (img, options) {\n    var aspectRatio = options.aspectRatio\n    var newOptions\n    var i\n    var width\n    var height\n    if (!aspectRatio) {\n      return options\n    }\n    newOptions = {}\n    for (i in options) {\n      if (options.hasOwnProperty(i)) {\n        newOptions[i] = options[i]\n      }\n    }\n    newOptions.crop = true\n    width = img.naturalWidth || img.width\n    height = img.naturalHeight || img.height\n    if (width / height > aspectRatio) {\n      newOptions.maxWidth = height * aspectRatio\n      newOptions.maxHeight = height\n    } else {\n      newOptions.maxWidth = width\n      newOptions.maxHeight = width / aspectRatio\n    }\n    return newOptions\n  }\n\n  // Canvas render method, allows to implement a different rendering algorithm:\n  loadImage.renderImageToCanvas = function (\n    canvas,\n    img,\n    sourceX,\n    sourceY,\n    sourceWidth,\n    sourceHeight,\n    destX,\n    destY,\n    destWidth,\n    destHeight\n  ) {\n    canvas.getContext('2d').drawImage(\n      img,\n      sourceX,\n      sourceY,\n      sourceWidth,\n      sourceHeight,\n      destX,\n      destY,\n      destWidth,\n      destHeight\n    )\n    return canvas\n  }\n\n  // Determines if the target image should be a canvas element:\n  loadImage.hasCanvasOption = function (options) {\n    return options.canvas || options.crop || !!options.aspectRatio\n  }\n\n  // Scales and/or crops the given image (img or canvas HTML element)\n  // using the given options.\n  // Returns a canvas object if the browser supports canvas\n  // and the hasCanvasOption method returns true or a canvas\n  // object is passed as image, else the scaled image:\n  loadImage.scale = function (img, options, data) {\n    options = options || {}\n    var canvas = document.createElement('canvas')\n    var useCanvas = img.getContext ||\n                    (loadImage.hasCanvasOption(options) && canvas.getContext)\n    var width = img.naturalWidth || img.width\n    var height = img.naturalHeight || img.height\n    var destWidth = width\n    var destHeight = height\n    var maxWidth\n    var maxHeight\n    var minWidth\n    var minHeight\n    var sourceWidth\n    var sourceHeight\n    var sourceX\n    var sourceY\n    var pixelRatio\n    var downsamplingRatio\n    var tmp\n    function scaleUp () {\n      var scale = Math.max(\n        (minWidth || destWidth) / destWidth,\n        (minHeight || destHeight) / destHeight\n      )\n      if (scale > 1) {\n        destWidth *= scale\n        destHeight *= scale\n      }\n    }\n    function scaleDown () {\n      var scale = Math.min(\n        (maxWidth || destWidth) / destWidth,\n        (maxHeight || destHeight) / destHeight\n      )\n      if (scale < 1) {\n        destWidth *= scale\n        destHeight *= scale\n      }\n    }\n    if (useCanvas) {\n      options = loadImage.getTransformedOptions(img, options, data)\n      sourceX = options.left || 0\n      sourceY = options.top || 0\n      if (options.sourceWidth) {\n        sourceWidth = options.sourceWidth\n        if (options.right !== undefined && options.left === undefined) {\n          sourceX = width - sourceWidth - options.right\n        }\n      } else {\n        sourceWidth = width - sourceX - (options.right || 0)\n      }\n      if (options.sourceHeight) {\n        sourceHeight = options.sourceHeight\n        if (options.bottom !== undefined && options.top === undefined) {\n          sourceY = height - sourceHeight - options.bottom\n        }\n      } else {\n        sourceHeight = height - sourceY - (options.bottom || 0)\n      }\n      destWidth = sourceWidth\n      destHeight = sourceHeight\n    }\n    maxWidth = options.maxWidth\n    maxHeight = options.maxHeight\n    minWidth = options.minWidth\n    minHeight = options.minHeight\n    if (useCanvas && maxWidth && maxHeight && options.crop) {\n      destWidth = maxWidth\n      destHeight = maxHeight\n      tmp = sourceWidth / sourceHeight - maxWidth / maxHeight\n      if (tmp < 0) {\n        sourceHeight = maxHeight * sourceWidth / maxWidth\n        if (options.top === undefined && options.bottom === undefined) {\n          sourceY = (height - sourceHeight) / 2\n        }\n      } else if (tmp > 0) {\n        sourceWidth = maxWidth * sourceHeight / maxHeight\n        if (options.left === undefined && options.right === undefined) {\n          sourceX = (width - sourceWidth) / 2\n        }\n      }\n    } else {\n      if (options.contain || options.cover) {\n        minWidth = maxWidth = maxWidth || minWidth\n        minHeight = maxHeight = maxHeight || minHeight\n      }\n      if (options.cover) {\n        scaleDown()\n        scaleUp()\n      } else {\n        scaleUp()\n        scaleDown()\n      }\n    }\n    if (useCanvas) {\n      pixelRatio = options.pixelRatio\n      if (pixelRatio > 1) {\n        canvas.style.width = destWidth + 'px'\n        canvas.style.height = destHeight + 'px'\n        destWidth *= pixelRatio\n        destHeight *= pixelRatio\n        canvas.getContext('2d').scale(pixelRatio, pixelRatio)\n      }\n      downsamplingRatio = options.downsamplingRatio\n      if (downsamplingRatio > 0 && downsamplingRatio < 1 &&\n            destWidth < sourceWidth && destHeight < sourceHeight) {\n        while (sourceWidth * downsamplingRatio > destWidth) {\n          canvas.width = sourceWidth * downsamplingRatio\n          canvas.height = sourceHeight * downsamplingRatio\n          loadImage.renderImageToCanvas(\n            canvas,\n            img,\n            sourceX,\n            sourceY,\n            sourceWidth,\n            sourceHeight,\n            0,\n            0,\n            canvas.width,\n            canvas.height\n          )\n          sourceX = 0\n          sourceY = 0\n          sourceWidth = canvas.width\n          sourceHeight = canvas.height\n          img = document.createElement('canvas')\n          img.width = sourceWidth\n          img.height = sourceHeight\n          loadImage.renderImageToCanvas(\n            img,\n            canvas,\n            0,\n            0,\n            sourceWidth,\n            sourceHeight,\n            0,\n            0,\n            sourceWidth,\n            sourceHeight\n          )\n        }\n      }\n      canvas.width = destWidth\n      canvas.height = destHeight\n      loadImage.transformCoordinates(\n        canvas,\n        options\n      )\n      return loadImage.renderImageToCanvas(\n        canvas,\n        img,\n        sourceX,\n        sourceY,\n        sourceWidth,\n        sourceHeight,\n        0,\n        0,\n        destWidth,\n        destHeight\n      )\n    }\n    img.width = destWidth\n    img.height = destHeight\n    return img\n  }\n}))\n"
  },
  {
    "path": "app_frontend/static/plugin/JavaScript-Load-Image-2.12.2/js/load-image.js",
    "content": "/*\n * JavaScript Load Image\n * https://github.com/blueimp/JavaScript-Load-Image\n *\n * Copyright 2011, Sebastian Tschan\n * https://blueimp.net\n *\n * Licensed under the MIT license:\n * https://opensource.org/licenses/MIT\n */\n\n/* global define, URL, webkitURL, FileReader */\n\n;(function ($) {\n  'use strict'\n\n  // Loads an image for a given File object.\n  // Invokes the callback with an img or optional canvas\n  // element (if supported by the browser) as parameter:\n  function loadImage (file, callback, options) {\n    var img = document.createElement('img')\n    var url\n    img.onerror = function (event) {\n      return loadImage.onerror(img, event, file, callback, options)\n    }\n    img.onload = function (event) {\n      return loadImage.onload(img, event, file, callback, options)\n    }\n    if (typeof file === 'string') {\n      loadImage.fetchBlob(file, function (blob) {\n        if (blob) {\n          file = blob\n          url = loadImage.createObjectURL(file)\n        } else {\n          url = file\n          if (options && options.crossOrigin) {\n            img.crossOrigin = options.crossOrigin\n          }\n        }\n        img.src = url\n      }, options)\n      return img\n    } else if (loadImage.isInstanceOf('Blob', file) ||\n        // Files are also Blob instances, but some browsers\n        // (Firefox 3.6) support the File API but not Blobs:\n        loadImage.isInstanceOf('File', file)) {\n      url = img._objectURL = loadImage.createObjectURL(file)\n      if (url) {\n        img.src = url\n        return img\n      }\n      return loadImage.readFile(file, function (e) {\n        var target = e.target\n        if (target && target.result) {\n          img.src = target.result\n        } else if (callback) {\n          callback(e)\n        }\n      })\n    }\n  }\n  // The check for URL.revokeObjectURL fixes an issue with Opera 12,\n  // which provides URL.createObjectURL but doesn't properly implement it:\n  var urlAPI = (window.createObjectURL && window) ||\n                (window.URL && URL.revokeObjectURL && URL) ||\n                (window.webkitURL && webkitURL)\n\n  function revokeHelper (img, options) {\n    if (img._objectURL && !(options && options.noRevoke)) {\n      loadImage.revokeObjectURL(img._objectURL)\n      delete img._objectURL\n    }\n  }\n\n  // If the callback given to this function returns a blob, it is used as image\n  // source instead of the original url and overrides the file argument used in\n  // the onload and onerror event callbacks:\n  loadImage.fetchBlob = function (url, callback, options) {\n    callback()\n  }\n\n  loadImage.isInstanceOf = function (type, obj) {\n    // Cross-frame instanceof check\n    return Object.prototype.toString.call(obj) === '[object ' + type + ']'\n  }\n\n  loadImage.transform = function (img, options, callback, file, data) {\n    callback(img, data)\n  }\n\n  loadImage.onerror = function (img, event, file, callback, options) {\n    revokeHelper(img, options)\n    if (callback) {\n      callback.call(img, event)\n    }\n  }\n\n  loadImage.onload = function (img, event, file, callback, options) {\n    revokeHelper(img, options)\n    if (callback) {\n      loadImage.transform(img, options, callback, file, {})\n    }\n  }\n\n  loadImage.createObjectURL = function (file) {\n    return urlAPI ? urlAPI.createObjectURL(file) : false\n  }\n\n  loadImage.revokeObjectURL = function (url) {\n    return urlAPI ? urlAPI.revokeObjectURL(url) : false\n  }\n\n  // Loads a given File object via FileReader interface,\n  // invokes the callback with the event object (load or error).\n  // The result can be read via event.target.result:\n  loadImage.readFile = function (file, callback, method) {\n    if (window.FileReader) {\n      var fileReader = new FileReader()\n      fileReader.onload = fileReader.onerror = callback\n      method = method || 'readAsDataURL'\n      if (fileReader[method]) {\n        fileReader[method](file)\n        return fileReader\n      }\n    }\n    return false\n  }\n\n  if (typeof define === 'function' && define.amd) {\n    define(function () {\n      return loadImage\n    })\n  } else if (typeof module === 'object' && module.exports) {\n    module.exports = loadImage\n  } else {\n    $.loadImage = loadImage\n  }\n}(window))\n"
  },
  {
    "path": "app_frontend/static/plugin/JavaScript-Load-Image-2.12.2/js/vendor/jquery.Jcrop.js",
    "content": "/**\n * jquery.Jcrop.js v0.9.12\n * jQuery Image Cropping Plugin - released under MIT License \n * Author: Kelly Hallman <khallman@gmail.com>\n * http://github.com/tapmodo/Jcrop\n * Copyright (c) 2008-2013 Tapmodo Interactive LLC {{{\n *\n * Permission is hereby granted, free of charge, to any person\n * obtaining a copy of this software and associated documentation\n * files (the \"Software\"), to deal in the Software without\n * restriction, including without limitation the rights to use,\n * copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the\n * Software is furnished to do so, subject to the following\n * conditions:\n *\n * The above copyright notice and this permission notice shall be\n * included in all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\n * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES\n * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\n * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT\n * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,\n * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR\n * OTHER DEALINGS IN THE SOFTWARE.\n *\n * }}}\n */\n\n(function ($) {\n\n  $.Jcrop = function (obj, opt) {\n    var options = $.extend({}, $.Jcrop.defaults),\n        docOffset,\n        _ua = navigator.userAgent.toLowerCase(),\n        is_msie = /msie/.test(_ua),\n        ie6mode = /msie [1-6]\\./.test(_ua);\n\n    // Internal Methods {{{\n    function px(n) {\n      return Math.round(n) + 'px';\n    }\n    function cssClass(cl) {\n      return options.baseClass + '-' + cl;\n    }\n    function supportsColorFade() {\n      return $.fx.step.hasOwnProperty('backgroundColor');\n    }\n    function getPos(obj) //{{{\n    {\n      var pos = $(obj).offset();\n      return [pos.left, pos.top];\n    }\n    //}}}\n    function mouseAbs(e) //{{{\n    {\n      return [(e.pageX - docOffset[0]), (e.pageY - docOffset[1])];\n    }\n    //}}}\n    function setOptions(opt) //{{{\n    {\n      if (typeof(opt) !== 'object') opt = {};\n      options = $.extend(options, opt);\n\n      $.each(['onChange','onSelect','onRelease','onDblClick'],function(i,e) {\n        if (typeof(options[e]) !== 'function') options[e] = function () {};\n      });\n    }\n    //}}}\n    function startDragMode(mode, pos, touch) //{{{\n    {\n      docOffset = getPos($img);\n      Tracker.setCursor(mode === 'move' ? mode : mode + '-resize');\n\n      if (mode === 'move') {\n        return Tracker.activateHandlers(createMover(pos), doneSelect, touch);\n      }\n\n      var fc = Coords.getFixed();\n      var opp = oppLockCorner(mode);\n      var opc = Coords.getCorner(oppLockCorner(opp));\n\n      Coords.setPressed(Coords.getCorner(opp));\n      Coords.setCurrent(opc);\n\n      Tracker.activateHandlers(dragmodeHandler(mode, fc), doneSelect, touch);\n    }\n    //}}}\n    function dragmodeHandler(mode, f) //{{{\n    {\n      return function (pos) {\n        if (!options.aspectRatio) {\n          switch (mode) {\n          case 'e':\n            pos[1] = f.y2;\n            break;\n          case 'w':\n            pos[1] = f.y2;\n            break;\n          case 'n':\n            pos[0] = f.x2;\n            break;\n          case 's':\n            pos[0] = f.x2;\n            break;\n          }\n        } else {\n          switch (mode) {\n          case 'e':\n            pos[1] = f.y + 1;\n            break;\n          case 'w':\n            pos[1] = f.y + 1;\n            break;\n          case 'n':\n            pos[0] = f.x + 1;\n            break;\n          case 's':\n            pos[0] = f.x + 1;\n            break;\n          }\n        }\n        Coords.setCurrent(pos);\n        Selection.update();\n      };\n    }\n    //}}}\n    function createMover(pos) //{{{\n    {\n      var lloc = pos;\n      KeyManager.watchKeys();\n\n      return function (pos) {\n        Coords.moveOffset([pos[0] - lloc[0], pos[1] - lloc[1]]);\n        lloc = pos;\n\n        Selection.update();\n      };\n    }\n    //}}}\n    function oppLockCorner(ord) //{{{\n    {\n      switch (ord) {\n      case 'n':\n        return 'sw';\n      case 's':\n        return 'nw';\n      case 'e':\n        return 'nw';\n      case 'w':\n        return 'ne';\n      case 'ne':\n        return 'sw';\n      case 'nw':\n        return 'se';\n      case 'se':\n        return 'nw';\n      case 'sw':\n        return 'ne';\n      }\n    }\n    //}}}\n    function createDragger(ord) //{{{\n    {\n      return function (e) {\n        if (options.disabled) {\n          return false;\n        }\n        if ((ord === 'move') && !options.allowMove) {\n          return false;\n        }\n        \n        // Fix position of crop area when dragged the very first time.\n        // Necessary when crop image is in a hidden element when page is loaded.\n        docOffset = getPos($img);\n\n        btndown = true;\n        startDragMode(ord, mouseAbs(e));\n        e.stopPropagation();\n        e.preventDefault();\n        return false;\n      };\n    }\n    //}}}\n    function presize($obj, w, h) //{{{\n    {\n      var nw = $obj.width(),\n          nh = $obj.height();\n      if ((nw > w) && w > 0) {\n        nw = w;\n        nh = (w / $obj.width()) * $obj.height();\n      }\n      if ((nh > h) && h > 0) {\n        nh = h;\n        nw = (h / $obj.height()) * $obj.width();\n      }\n      xscale = $obj.width() / nw;\n      yscale = $obj.height() / nh;\n      $obj.width(nw).height(nh);\n    }\n    //}}}\n    function unscale(c) //{{{\n    {\n      return {\n        x: c.x * xscale,\n        y: c.y * yscale,\n        x2: c.x2 * xscale,\n        y2: c.y2 * yscale,\n        w: c.w * xscale,\n        h: c.h * yscale\n      };\n    }\n    //}}}\n    function doneSelect(pos) //{{{\n    {\n      var c = Coords.getFixed();\n      if ((c.w > options.minSelect[0]) && (c.h > options.minSelect[1])) {\n        Selection.enableHandles();\n        Selection.done();\n      } else {\n        Selection.release();\n      }\n      Tracker.setCursor(options.allowSelect ? 'crosshair' : 'default');\n    }\n    //}}}\n    function newSelection(e) //{{{\n    {\n      if (options.disabled) {\n        return false;\n      }\n      if (!options.allowSelect) {\n        return false;\n      }\n      btndown = true;\n      docOffset = getPos($img);\n      Selection.disableHandles();\n      Tracker.setCursor('crosshair');\n      var pos = mouseAbs(e);\n      Coords.setPressed(pos);\n      Selection.update();\n      Tracker.activateHandlers(selectDrag, doneSelect, e.type.substring(0,5)==='touch');\n      KeyManager.watchKeys();\n\n      e.stopPropagation();\n      e.preventDefault();\n      return false;\n    }\n    //}}}\n    function selectDrag(pos) //{{{\n    {\n      Coords.setCurrent(pos);\n      Selection.update();\n    }\n    //}}}\n    function newTracker() //{{{\n    {\n      var trk = $('<div></div>').addClass(cssClass('tracker'));\n      if (is_msie) {\n        trk.css({\n          opacity: 0,\n          backgroundColor: 'white'\n        });\n      }\n      return trk;\n    }\n    //}}}\n\n    // }}}\n    // Initialization {{{\n    // Sanitize some options {{{\n    if (typeof(obj) !== 'object') {\n      obj = $(obj)[0];\n    }\n    if (typeof(opt) !== 'object') {\n      opt = {};\n    }\n    // }}}\n    setOptions(opt);\n    // Initialize some jQuery objects {{{\n    // The values are SET on the image(s) for the interface\n    // If the original image has any of these set, they will be reset\n    // However, if you destroy() the Jcrop instance the original image's\n    // character in the DOM will be as you left it.\n    var img_css = {\n      border: 'none',\n      visibility: 'visible',\n      margin: 0,\n      padding: 0,\n      position: 'absolute',\n      top: 0,\n      left: 0\n    };\n\n    var $origimg = $(obj),\n      img_mode = true;\n\n    if (obj.tagName == 'IMG') {\n      // Fix size of crop image.\n      // Necessary when crop image is within a hidden element when page is loaded.\n      if ($origimg[0].width != 0 && $origimg[0].height != 0) {\n        // Obtain dimensions from contained img element.\n        $origimg.width($origimg[0].width);\n        $origimg.height($origimg[0].height);\n      } else {\n        // Obtain dimensions from temporary image in case the original is not loaded yet (e.g. IE 7.0). \n        var tempImage = new Image();\n        tempImage.src = $origimg[0].src;\n        $origimg.width(tempImage.width);\n        $origimg.height(tempImage.height);\n      } \n\n      var $img = $origimg.clone().removeAttr('id').css(img_css).show();\n\n      $img.width($origimg.width());\n      $img.height($origimg.height());\n      $origimg.after($img).hide();\n\n    } else {\n      $img = $origimg.css(img_css).show();\n      img_mode = false;\n      if (options.shade === null) { options.shade = true; }\n    }\n\n    presize($img, options.boxWidth, options.boxHeight);\n\n    var boundx = $img.width(),\n        boundy = $img.height(),\n        \n        \n        $div = $('<div />').width(boundx).height(boundy).addClass(cssClass('holder')).css({\n        position: 'relative',\n        backgroundColor: options.bgColor\n      }).insertAfter($origimg).append($img);\n\n    if (options.addClass) {\n      $div.addClass(options.addClass);\n    }\n\n    var $img2 = $('<div />'),\n\n        $img_holder = $('<div />') \n        .width('100%').height('100%').css({\n          zIndex: 310,\n          position: 'absolute',\n          overflow: 'hidden'\n        }),\n\n        $hdl_holder = $('<div />') \n        .width('100%').height('100%').css('zIndex', 320), \n\n        $sel = $('<div />') \n        .css({\n          position: 'absolute',\n          zIndex: 600\n        }).dblclick(function(){\n          var c = Coords.getFixed();\n          options.onDblClick.call(api,c);\n        }).insertBefore($img).append($img_holder, $hdl_holder); \n\n    if (img_mode) {\n\n      $img2 = $('<img />')\n          .attr('src', $img.attr('src')).css(img_css).width(boundx).height(boundy),\n\n      $img_holder.append($img2);\n\n    }\n\n    if (ie6mode) {\n      $sel.css({\n        overflowY: 'hidden'\n      });\n    }\n\n    var bound = options.boundary;\n    var $trk = newTracker().width(boundx + (bound * 2)).height(boundy + (bound * 2)).css({\n      position: 'absolute',\n      top: px(-bound),\n      left: px(-bound),\n      zIndex: 290\n    }).mousedown(newSelection);\n\n    /* }}} */\n    // Set more variables {{{\n    var bgcolor = options.bgColor,\n        bgopacity = options.bgOpacity,\n        xlimit, ylimit, xmin, ymin, xscale, yscale, enabled = true,\n        btndown, animating, shift_down;\n\n    docOffset = getPos($img);\n    // }}}\n    // }}}\n    // Internal Modules {{{\n    // Touch Module {{{ \n    var Touch = (function () {\n      // Touch support detection function adapted (under MIT License)\n      // from code by Jeffrey Sambells - http://github.com/iamamused/\n      function hasTouchSupport() {\n        var support = {}, events = ['touchstart', 'touchmove', 'touchend'],\n            el = document.createElement('div'), i;\n\n        try {\n          for(i=0; i<events.length; i++) {\n            var eventName = events[i];\n            eventName = 'on' + eventName;\n            var isSupported = (eventName in el);\n            if (!isSupported) {\n              el.setAttribute(eventName, 'return;');\n              isSupported = typeof el[eventName] == 'function';\n            }\n            support[events[i]] = isSupported;\n          }\n          return support.touchstart && support.touchend && support.touchmove;\n        }\n        catch(err) {\n          return false;\n        }\n      }\n\n      function detectSupport() {\n        if ((options.touchSupport === true) || (options.touchSupport === false)) return options.touchSupport;\n          else return hasTouchSupport();\n      }\n      return {\n        createDragger: function (ord) {\n          return function (e) {\n            if (options.disabled) {\n              return false;\n            }\n            if ((ord === 'move') && !options.allowMove) {\n              return false;\n            }\n            docOffset = getPos($img);\n            btndown = true;\n            startDragMode(ord, mouseAbs(Touch.cfilter(e)), true);\n            e.stopPropagation();\n            e.preventDefault();\n            return false;\n          };\n        },\n        newSelection: function (e) {\n          return newSelection(Touch.cfilter(e));\n        },\n        cfilter: function (e){\n          e.pageX = e.originalEvent.changedTouches[0].pageX;\n          e.pageY = e.originalEvent.changedTouches[0].pageY;\n          return e;\n        },\n        isSupported: hasTouchSupport,\n        support: detectSupport()\n      };\n    }());\n    // }}}\n    // Coords Module {{{\n    var Coords = (function () {\n      var x1 = 0,\n          y1 = 0,\n          x2 = 0,\n          y2 = 0,\n          ox, oy;\n\n      function setPressed(pos) //{{{\n      {\n        pos = rebound(pos);\n        x2 = x1 = pos[0];\n        y2 = y1 = pos[1];\n      }\n      //}}}\n      function setCurrent(pos) //{{{\n      {\n        pos = rebound(pos);\n        ox = pos[0] - x2;\n        oy = pos[1] - y2;\n        x2 = pos[0];\n        y2 = pos[1];\n      }\n      //}}}\n      function getOffset() //{{{\n      {\n        return [ox, oy];\n      }\n      //}}}\n      function moveOffset(offset) //{{{\n      {\n        var ox = offset[0],\n            oy = offset[1];\n\n        if (0 > x1 + ox) {\n          ox -= ox + x1;\n        }\n        if (0 > y1 + oy) {\n          oy -= oy + y1;\n        }\n\n        if (boundy < y2 + oy) {\n          oy += boundy - (y2 + oy);\n        }\n        if (boundx < x2 + ox) {\n          ox += boundx - (x2 + ox);\n        }\n\n        x1 += ox;\n        x2 += ox;\n        y1 += oy;\n        y2 += oy;\n      }\n      //}}}\n      function getCorner(ord) //{{{\n      {\n        var c = getFixed();\n        switch (ord) {\n        case 'ne':\n          return [c.x2, c.y];\n        case 'nw':\n          return [c.x, c.y];\n        case 'se':\n          return [c.x2, c.y2];\n        case 'sw':\n          return [c.x, c.y2];\n        }\n      }\n      //}}}\n      function getFixed() //{{{\n      {\n        if (!options.aspectRatio) {\n          return getRect();\n        }\n        // This function could use some optimization I think...\n        var aspect = options.aspectRatio,\n            min_x = options.minSize[0] / xscale,\n            \n            \n            //min_y = options.minSize[1]/yscale,\n            max_x = options.maxSize[0] / xscale,\n            max_y = options.maxSize[1] / yscale,\n            rw = x2 - x1,\n            rh = y2 - y1,\n            rwa = Math.abs(rw),\n            rha = Math.abs(rh),\n            real_ratio = rwa / rha,\n            xx, yy, w, h;\n\n        if (max_x === 0) {\n          max_x = boundx * 10;\n        }\n        if (max_y === 0) {\n          max_y = boundy * 10;\n        }\n        if (real_ratio < aspect) {\n          yy = y2;\n          w = rha * aspect;\n          xx = rw < 0 ? x1 - w : w + x1;\n\n          if (xx < 0) {\n            xx = 0;\n            h = Math.abs((xx - x1) / aspect);\n            yy = rh < 0 ? y1 - h : h + y1;\n          } else if (xx > boundx) {\n            xx = boundx;\n            h = Math.abs((xx - x1) / aspect);\n            yy = rh < 0 ? y1 - h : h + y1;\n          }\n        } else {\n          xx = x2;\n          h = rwa / aspect;\n          yy = rh < 0 ? y1 - h : y1 + h;\n          if (yy < 0) {\n            yy = 0;\n            w = Math.abs((yy - y1) * aspect);\n            xx = rw < 0 ? x1 - w : w + x1;\n          } else if (yy > boundy) {\n            yy = boundy;\n            w = Math.abs(yy - y1) * aspect;\n            xx = rw < 0 ? x1 - w : w + x1;\n          }\n        }\n\n        // Magic %-)\n        if (xx > x1) { // right side\n          if (xx - x1 < min_x) {\n            xx = x1 + min_x;\n          } else if (xx - x1 > max_x) {\n            xx = x1 + max_x;\n          }\n          if (yy > y1) {\n            yy = y1 + (xx - x1) / aspect;\n          } else {\n            yy = y1 - (xx - x1) / aspect;\n          }\n        } else if (xx < x1) { // left side\n          if (x1 - xx < min_x) {\n            xx = x1 - min_x;\n          } else if (x1 - xx > max_x) {\n            xx = x1 - max_x;\n          }\n          if (yy > y1) {\n            yy = y1 + (x1 - xx) / aspect;\n          } else {\n            yy = y1 - (x1 - xx) / aspect;\n          }\n        }\n\n        if (xx < 0) {\n          x1 -= xx;\n          xx = 0;\n        } else if (xx > boundx) {\n          x1 -= xx - boundx;\n          xx = boundx;\n        }\n\n        if (yy < 0) {\n          y1 -= yy;\n          yy = 0;\n        } else if (yy > boundy) {\n          y1 -= yy - boundy;\n          yy = boundy;\n        }\n\n        return makeObj(flipCoords(x1, y1, xx, yy));\n      }\n      //}}}\n      function rebound(p) //{{{\n      {\n        if (p[0] < 0) p[0] = 0;\n        if (p[1] < 0) p[1] = 0;\n\n        if (p[0] > boundx) p[0] = boundx;\n        if (p[1] > boundy) p[1] = boundy;\n\n        return [Math.round(p[0]), Math.round(p[1])];\n      }\n      //}}}\n      function flipCoords(x1, y1, x2, y2) //{{{\n      {\n        var xa = x1,\n            xb = x2,\n            ya = y1,\n            yb = y2;\n        if (x2 < x1) {\n          xa = x2;\n          xb = x1;\n        }\n        if (y2 < y1) {\n          ya = y2;\n          yb = y1;\n        }\n        return [xa, ya, xb, yb];\n      }\n      //}}}\n      function getRect() //{{{\n      {\n        var xsize = x2 - x1,\n            ysize = y2 - y1,\n            delta;\n\n        if (xlimit && (Math.abs(xsize) > xlimit)) {\n          x2 = (xsize > 0) ? (x1 + xlimit) : (x1 - xlimit);\n        }\n        if (ylimit && (Math.abs(ysize) > ylimit)) {\n          y2 = (ysize > 0) ? (y1 + ylimit) : (y1 - ylimit);\n        }\n\n        if (ymin / yscale && (Math.abs(ysize) < ymin / yscale)) {\n          y2 = (ysize > 0) ? (y1 + ymin / yscale) : (y1 - ymin / yscale);\n        }\n        if (xmin / xscale && (Math.abs(xsize) < xmin / xscale)) {\n          x2 = (xsize > 0) ? (x1 + xmin / xscale) : (x1 - xmin / xscale);\n        }\n\n        if (x1 < 0) {\n          x2 -= x1;\n          x1 -= x1;\n        }\n        if (y1 < 0) {\n          y2 -= y1;\n          y1 -= y1;\n        }\n        if (x2 < 0) {\n          x1 -= x2;\n          x2 -= x2;\n        }\n        if (y2 < 0) {\n          y1 -= y2;\n          y2 -= y2;\n        }\n        if (x2 > boundx) {\n          delta = x2 - boundx;\n          x1 -= delta;\n          x2 -= delta;\n        }\n        if (y2 > boundy) {\n          delta = y2 - boundy;\n          y1 -= delta;\n          y2 -= delta;\n        }\n        if (x1 > boundx) {\n          delta = x1 - boundy;\n          y2 -= delta;\n          y1 -= delta;\n        }\n        if (y1 > boundy) {\n          delta = y1 - boundy;\n          y2 -= delta;\n          y1 -= delta;\n        }\n\n        return makeObj(flipCoords(x1, y1, x2, y2));\n      }\n      //}}}\n      function makeObj(a) //{{{\n      {\n        return {\n          x: a[0],\n          y: a[1],\n          x2: a[2],\n          y2: a[3],\n          w: a[2] - a[0],\n          h: a[3] - a[1]\n        };\n      }\n      //}}}\n\n      return {\n        flipCoords: flipCoords,\n        setPressed: setPressed,\n        setCurrent: setCurrent,\n        getOffset: getOffset,\n        moveOffset: moveOffset,\n        getCorner: getCorner,\n        getFixed: getFixed\n      };\n    }());\n\n    //}}}\n    // Shade Module {{{\n    var Shade = (function() {\n      var enabled = false,\n          holder = $('<div />').css({\n            position: 'absolute',\n            zIndex: 240,\n            opacity: 0\n          }),\n          shades = {\n            top: createShade(),\n            left: createShade().height(boundy),\n            right: createShade().height(boundy),\n            bottom: createShade()\n          };\n\n      function resizeShades(w,h) {\n        shades.left.css({ height: px(h) });\n        shades.right.css({ height: px(h) });\n      }\n      function updateAuto()\n      {\n        return updateShade(Coords.getFixed());\n      }\n      function updateShade(c)\n      {\n        shades.top.css({\n          left: px(c.x),\n          width: px(c.w),\n          height: px(c.y)\n        });\n        shades.bottom.css({\n          top: px(c.y2),\n          left: px(c.x),\n          width: px(c.w),\n          height: px(boundy-c.y2)\n        });\n        shades.right.css({\n          left: px(c.x2),\n          width: px(boundx-c.x2)\n        });\n        shades.left.css({\n          width: px(c.x)\n        });\n      }\n      function createShade() {\n        return $('<div />').css({\n          position: 'absolute',\n          backgroundColor: options.shadeColor||options.bgColor\n        }).appendTo(holder);\n      }\n      function enableShade() {\n        if (!enabled) {\n          enabled = true;\n          holder.insertBefore($img);\n          updateAuto();\n          Selection.setBgOpacity(1,0,1);\n          $img2.hide();\n\n          setBgColor(options.shadeColor||options.bgColor,1);\n          if (Selection.isAwake())\n          {\n            setOpacity(options.bgOpacity,1);\n          }\n            else setOpacity(1,1);\n        }\n      }\n      function setBgColor(color,now) {\n        colorChangeMacro(getShades(),color,now);\n      }\n      function disableShade() {\n        if (enabled) {\n          holder.remove();\n          $img2.show();\n          enabled = false;\n          if (Selection.isAwake()) {\n            Selection.setBgOpacity(options.bgOpacity,1,1);\n          } else {\n            Selection.setBgOpacity(1,1,1);\n            Selection.disableHandles();\n          }\n          colorChangeMacro($div,0,1);\n        }\n      }\n      function setOpacity(opacity,now) {\n        if (enabled) {\n          if (options.bgFade && !now) {\n            holder.animate({\n              opacity: 1-opacity\n            },{\n              queue: false,\n              duration: options.fadeTime\n            });\n          }\n          else holder.css({opacity:1-opacity});\n        }\n      }\n      function refreshAll() {\n        options.shade ? enableShade() : disableShade();\n        if (Selection.isAwake()) setOpacity(options.bgOpacity);\n      }\n      function getShades() {\n        return holder.children();\n      }\n\n      return {\n        update: updateAuto,\n        updateRaw: updateShade,\n        getShades: getShades,\n        setBgColor: setBgColor,\n        enable: enableShade,\n        disable: disableShade,\n        resize: resizeShades,\n        refresh: refreshAll,\n        opacity: setOpacity\n      };\n    }());\n    // }}}\n    // Selection Module {{{\n    var Selection = (function () {\n      var awake,\n          hdep = 370,\n          borders = {},\n          handle = {},\n          dragbar = {},\n          seehandles = false;\n\n      // Private Methods\n      function insertBorder(type) //{{{\n      {\n        var jq = $('<div />').css({\n          position: 'absolute',\n          opacity: options.borderOpacity\n        }).addClass(cssClass(type));\n        $img_holder.append(jq);\n        return jq;\n      }\n      //}}}\n      function dragDiv(ord, zi) //{{{\n      {\n        var jq = $('<div />').mousedown(createDragger(ord)).css({\n          cursor: ord + '-resize',\n          position: 'absolute',\n          zIndex: zi\n        }).addClass('ord-'+ord);\n\n        if (Touch.support) {\n          jq.bind('touchstart.jcrop', Touch.createDragger(ord));\n        }\n\n        $hdl_holder.append(jq);\n        return jq;\n      }\n      //}}}\n      function insertHandle(ord) //{{{\n      {\n        var hs = options.handleSize,\n\n          div = dragDiv(ord, hdep++).css({\n            opacity: options.handleOpacity\n          }).addClass(cssClass('handle'));\n\n        if (hs) { div.width(hs).height(hs); }\n\n        return div;\n      }\n      //}}}\n      function insertDragbar(ord) //{{{\n      {\n        return dragDiv(ord, hdep++).addClass('jcrop-dragbar');\n      }\n      //}}}\n      function createDragbars(li) //{{{\n      {\n        var i;\n        for (i = 0; i < li.length; i++) {\n          dragbar[li[i]] = insertDragbar(li[i]);\n        }\n      }\n      //}}}\n      function createBorders(li) //{{{\n      {\n        var cl,i;\n        for (i = 0; i < li.length; i++) {\n          switch(li[i]){\n            case'n': cl='hline'; break;\n            case's': cl='hline bottom'; break;\n            case'e': cl='vline right'; break;\n            case'w': cl='vline'; break;\n          }\n          borders[li[i]] = insertBorder(cl);\n        }\n      }\n      //}}}\n      function createHandles(li) //{{{\n      {\n        var i;\n        for (i = 0; i < li.length; i++) {\n          handle[li[i]] = insertHandle(li[i]);\n        }\n      }\n      //}}}\n      function moveto(x, y) //{{{\n      {\n        if (!options.shade) {\n          $img2.css({\n            top: px(-y),\n            left: px(-x)\n          });\n        }\n        $sel.css({\n          top: px(y),\n          left: px(x)\n        });\n      }\n      //}}}\n      function resize(w, h) //{{{\n      {\n        $sel.width(Math.round(w)).height(Math.round(h));\n      }\n      //}}}\n      function refresh() //{{{\n      {\n        var c = Coords.getFixed();\n\n        Coords.setPressed([c.x, c.y]);\n        Coords.setCurrent([c.x2, c.y2]);\n\n        updateVisible();\n      }\n      //}}}\n\n      // Internal Methods\n      function updateVisible(select) //{{{\n      {\n        if (awake) {\n          return update(select);\n        }\n      }\n      //}}}\n      function update(select) //{{{\n      {\n        var c = Coords.getFixed();\n\n        resize(c.w, c.h);\n        moveto(c.x, c.y);\n        if (options.shade) Shade.updateRaw(c);\n\n        awake || show();\n\n        if (select) {\n          options.onSelect.call(api, unscale(c));\n        } else {\n          options.onChange.call(api, unscale(c));\n        }\n      }\n      //}}}\n      function setBgOpacity(opacity,force,now) //{{{\n      {\n        if (!awake && !force) return;\n        if (options.bgFade && !now) {\n          $img.animate({\n            opacity: opacity\n          },{\n            queue: false,\n            duration: options.fadeTime\n          });\n        } else {\n          $img.css('opacity', opacity);\n        }\n      }\n      //}}}\n      function show() //{{{\n      {\n        $sel.show();\n\n        if (options.shade) Shade.opacity(bgopacity);\n          else setBgOpacity(bgopacity,true);\n\n        awake = true;\n      }\n      //}}}\n      function release() //{{{\n      {\n        disableHandles();\n        $sel.hide();\n\n        if (options.shade) Shade.opacity(1);\n          else setBgOpacity(1);\n\n        awake = false;\n        options.onRelease.call(api);\n      }\n      //}}}\n      function showHandles() //{{{\n      {\n        if (seehandles) {\n          $hdl_holder.show();\n        }\n      }\n      //}}}\n      function enableHandles() //{{{\n      {\n        seehandles = true;\n        if (options.allowResize) {\n          $hdl_holder.show();\n          return true;\n        }\n      }\n      //}}}\n      function disableHandles() //{{{\n      {\n        seehandles = false;\n        $hdl_holder.hide();\n      } \n      //}}}\n      function animMode(v) //{{{\n      {\n        if (v) {\n          animating = true;\n          disableHandles();\n        } else {\n          animating = false;\n          enableHandles();\n        }\n      } \n      //}}}\n      function done() //{{{\n      {\n        animMode(false);\n        refresh();\n      } \n      //}}}\n      // Insert draggable elements {{{\n      // Insert border divs for outline\n\n      if (options.dragEdges && $.isArray(options.createDragbars))\n        createDragbars(options.createDragbars);\n\n      if ($.isArray(options.createHandles))\n        createHandles(options.createHandles);\n\n      if (options.drawBorders && $.isArray(options.createBorders))\n        createBorders(options.createBorders);\n\n      //}}}\n\n      // This is a hack for iOS5 to support drag/move touch functionality\n      $(document).bind('touchstart.jcrop-ios',function(e) {\n        if ($(e.currentTarget).hasClass('jcrop-tracker')) e.stopPropagation();\n      });\n\n      var $track = newTracker().mousedown(createDragger('move')).css({\n        cursor: 'move',\n        position: 'absolute',\n        zIndex: 360\n      });\n\n      if (Touch.support) {\n        $track.bind('touchstart.jcrop', Touch.createDragger('move'));\n      }\n\n      $img_holder.append($track);\n      disableHandles();\n\n      return {\n        updateVisible: updateVisible,\n        update: update,\n        release: release,\n        refresh: refresh,\n        isAwake: function () {\n          return awake;\n        },\n        setCursor: function (cursor) {\n          $track.css('cursor', cursor);\n        },\n        enableHandles: enableHandles,\n        enableOnly: function () {\n          seehandles = true;\n        },\n        showHandles: showHandles,\n        disableHandles: disableHandles,\n        animMode: animMode,\n        setBgOpacity: setBgOpacity,\n        done: done\n      };\n    }());\n    \n    //}}}\n    // Tracker Module {{{\n    var Tracker = (function () {\n      var onMove = function () {},\n          onDone = function () {},\n          trackDoc = options.trackDocument;\n\n      function toFront(touch) //{{{\n      {\n        $trk.css({\n          zIndex: 450\n        });\n\n        if (touch)\n          $(document)\n            .bind('touchmove.jcrop', trackTouchMove)\n            .bind('touchend.jcrop', trackTouchEnd);\n\n        else if (trackDoc)\n          $(document)\n            .bind('mousemove.jcrop',trackMove)\n            .bind('mouseup.jcrop',trackUp);\n      } \n      //}}}\n      function toBack() //{{{\n      {\n        $trk.css({\n          zIndex: 290\n        });\n        $(document).unbind('.jcrop');\n      } \n      //}}}\n      function trackMove(e) //{{{\n      {\n        onMove(mouseAbs(e));\n        return false;\n      } \n      //}}}\n      function trackUp(e) //{{{\n      {\n        e.preventDefault();\n        e.stopPropagation();\n\n        if (btndown) {\n          btndown = false;\n\n          onDone(mouseAbs(e));\n\n          if (Selection.isAwake()) {\n            options.onSelect.call(api, unscale(Coords.getFixed()));\n          }\n\n          toBack();\n          onMove = function () {};\n          onDone = function () {};\n        }\n\n        return false;\n      }\n      //}}}\n      function activateHandlers(move, done, touch) //{{{\n      {\n        btndown = true;\n        onMove = move;\n        onDone = done;\n        toFront(touch);\n        return false;\n      }\n      //}}}\n      function trackTouchMove(e) //{{{\n      {\n        onMove(mouseAbs(Touch.cfilter(e)));\n        return false;\n      }\n      //}}}\n      function trackTouchEnd(e) //{{{\n      {\n        return trackUp(Touch.cfilter(e));\n      }\n      //}}}\n      function setCursor(t) //{{{\n      {\n        $trk.css('cursor', t);\n      }\n      //}}}\n\n      if (!trackDoc) {\n        $trk.mousemove(trackMove).mouseup(trackUp).mouseout(trackUp);\n      }\n\n      $img.before($trk);\n      return {\n        activateHandlers: activateHandlers,\n        setCursor: setCursor\n      };\n    }());\n    //}}}\n    // KeyManager Module {{{\n    var KeyManager = (function () {\n      var $keymgr = $('<input type=\"radio\" />').css({\n        position: 'fixed',\n        left: '-120px',\n        width: '12px'\n      }).addClass('jcrop-keymgr'),\n\n        $keywrap = $('<div />').css({\n          position: 'absolute',\n          overflow: 'hidden'\n        }).append($keymgr);\n\n      function watchKeys() //{{{\n      {\n        if (options.keySupport) {\n          $keymgr.show();\n          $keymgr.focus();\n        }\n      }\n      //}}}\n      function onBlur(e) //{{{\n      {\n        $keymgr.hide();\n      }\n      //}}}\n      function doNudge(e, x, y) //{{{\n      {\n        if (options.allowMove) {\n          Coords.moveOffset([x, y]);\n          Selection.updateVisible(true);\n        }\n        e.preventDefault();\n        e.stopPropagation();\n      }\n      //}}}\n      function parseKey(e) //{{{\n      {\n        if (e.ctrlKey || e.metaKey) {\n          return true;\n        }\n        shift_down = e.shiftKey ? true : false;\n        var nudge = shift_down ? 10 : 1;\n\n        switch (e.keyCode) {\n        case 37:\n          doNudge(e, -nudge, 0);\n          break;\n        case 39:\n          doNudge(e, nudge, 0);\n          break;\n        case 38:\n          doNudge(e, 0, -nudge);\n          break;\n        case 40:\n          doNudge(e, 0, nudge);\n          break;\n        case 27:\n          if (options.allowSelect) Selection.release();\n          break;\n        case 9:\n          return true;\n        }\n\n        return false;\n      }\n      //}}}\n\n      if (options.keySupport) {\n        $keymgr.keydown(parseKey).blur(onBlur);\n        if (ie6mode || !options.fixedSupport) {\n          $keymgr.css({\n            position: 'absolute',\n            left: '-20px'\n          });\n          $keywrap.append($keymgr).insertBefore($img);\n        } else {\n          $keymgr.insertBefore($img);\n        }\n      }\n\n\n      return {\n        watchKeys: watchKeys\n      };\n    }());\n    //}}}\n    // }}}\n    // API methods {{{\n    function setClass(cname) //{{{\n    {\n      $div.removeClass().addClass(cssClass('holder')).addClass(cname);\n    }\n    //}}}\n    function animateTo(a, callback) //{{{\n    {\n      var x1 = a[0] / xscale,\n          y1 = a[1] / yscale,\n          x2 = a[2] / xscale,\n          y2 = a[3] / yscale;\n\n      if (animating) {\n        return;\n      }\n\n      var animto = Coords.flipCoords(x1, y1, x2, y2),\n          c = Coords.getFixed(),\n          initcr = [c.x, c.y, c.x2, c.y2],\n          animat = initcr,\n          interv = options.animationDelay,\n          ix1 = animto[0] - initcr[0],\n          iy1 = animto[1] - initcr[1],\n          ix2 = animto[2] - initcr[2],\n          iy2 = animto[3] - initcr[3],\n          pcent = 0,\n          velocity = options.swingSpeed;\n\n      x1 = animat[0];\n      y1 = animat[1];\n      x2 = animat[2];\n      y2 = animat[3];\n\n      Selection.animMode(true);\n      var anim_timer;\n\n      function queueAnimator() {\n        window.setTimeout(animator, interv);\n      }\n      var animator = (function () {\n        return function () {\n          pcent += (100 - pcent) / velocity;\n\n          animat[0] = Math.round(x1 + ((pcent / 100) * ix1));\n          animat[1] = Math.round(y1 + ((pcent / 100) * iy1));\n          animat[2] = Math.round(x2 + ((pcent / 100) * ix2));\n          animat[3] = Math.round(y2 + ((pcent / 100) * iy2));\n\n          if (pcent >= 99.8) {\n            pcent = 100;\n          }\n          if (pcent < 100) {\n            setSelectRaw(animat);\n            queueAnimator();\n          } else {\n            Selection.done();\n            Selection.animMode(false);\n            if (typeof(callback) === 'function') {\n              callback.call(api);\n            }\n          }\n        };\n      }());\n      queueAnimator();\n    }\n    //}}}\n    function setSelect(rect) //{{{\n    {\n      setSelectRaw([rect[0] / xscale, rect[1] / yscale, rect[2] / xscale, rect[3] / yscale]);\n      options.onSelect.call(api, unscale(Coords.getFixed()));\n      Selection.enableHandles();\n    }\n    //}}}\n    function setSelectRaw(l) //{{{\n    {\n      Coords.setPressed([l[0], l[1]]);\n      Coords.setCurrent([l[2], l[3]]);\n      Selection.update();\n    }\n    //}}}\n    function tellSelect() //{{{\n    {\n      return unscale(Coords.getFixed());\n    }\n    //}}}\n    function tellScaled() //{{{\n    {\n      return Coords.getFixed();\n    }\n    //}}}\n    function setOptionsNew(opt) //{{{\n    {\n      setOptions(opt);\n      interfaceUpdate();\n    }\n    //}}}\n    function disableCrop() //{{{\n    {\n      options.disabled = true;\n      Selection.disableHandles();\n      Selection.setCursor('default');\n      Tracker.setCursor('default');\n    }\n    //}}}\n    function enableCrop() //{{{\n    {\n      options.disabled = false;\n      interfaceUpdate();\n    }\n    //}}}\n    function cancelCrop() //{{{\n    {\n      Selection.done();\n      Tracker.activateHandlers(null, null);\n    }\n    //}}}\n    function destroy() //{{{\n    {\n      $div.remove();\n      $origimg.show();\n      $origimg.css('visibility','visible');\n      $(obj).removeData('Jcrop');\n    }\n    //}}}\n    function setImage(src, callback) //{{{\n    {\n      Selection.release();\n      disableCrop();\n      var img = new Image();\n      img.onload = function () {\n        var iw = img.width;\n        var ih = img.height;\n        var bw = options.boxWidth;\n        var bh = options.boxHeight;\n        $img.width(iw).height(ih);\n        $img.attr('src', src);\n        $img2.attr('src', src);\n        presize($img, bw, bh);\n        boundx = $img.width();\n        boundy = $img.height();\n        $img2.width(boundx).height(boundy);\n        $trk.width(boundx + (bound * 2)).height(boundy + (bound * 2));\n        $div.width(boundx).height(boundy);\n        Shade.resize(boundx,boundy);\n        enableCrop();\n\n        if (typeof(callback) === 'function') {\n          callback.call(api);\n        }\n      };\n      img.src = src;\n    }\n    //}}}\n    function colorChangeMacro($obj,color,now) {\n      var mycolor = color || options.bgColor;\n      if (options.bgFade && supportsColorFade() && options.fadeTime && !now) {\n        $obj.animate({\n          backgroundColor: mycolor\n        }, {\n          queue: false,\n          duration: options.fadeTime\n        });\n      } else {\n        $obj.css('backgroundColor', mycolor);\n      }\n    }\n    function interfaceUpdate(alt) //{{{\n    // This method tweaks the interface based on options object.\n    // Called when options are changed and at end of initialization.\n    {\n      if (options.allowResize) {\n        if (alt) {\n          Selection.enableOnly();\n        } else {\n          Selection.enableHandles();\n        }\n      } else {\n        Selection.disableHandles();\n      }\n\n      Tracker.setCursor(options.allowSelect ? 'crosshair' : 'default');\n      Selection.setCursor(options.allowMove ? 'move' : 'default');\n\n      if (options.hasOwnProperty('trueSize')) {\n        xscale = options.trueSize[0] / boundx;\n        yscale = options.trueSize[1] / boundy;\n      }\n\n      if (options.hasOwnProperty('setSelect')) {\n        setSelect(options.setSelect);\n        Selection.done();\n        delete(options.setSelect);\n      }\n\n      Shade.refresh();\n\n      if (options.bgColor != bgcolor) {\n        colorChangeMacro(\n          options.shade? Shade.getShades(): $div,\n          options.shade?\n            (options.shadeColor || options.bgColor):\n            options.bgColor\n        );\n        bgcolor = options.bgColor;\n      }\n\n      if (bgopacity != options.bgOpacity) {\n        bgopacity = options.bgOpacity;\n        if (options.shade) Shade.refresh();\n          else Selection.setBgOpacity(bgopacity);\n      }\n\n      xlimit = options.maxSize[0] || 0;\n      ylimit = options.maxSize[1] || 0;\n      xmin = options.minSize[0] || 0;\n      ymin = options.minSize[1] || 0;\n\n      if (options.hasOwnProperty('outerImage')) {\n        $img.attr('src', options.outerImage);\n        delete(options.outerImage);\n      }\n\n      Selection.refresh();\n    }\n    //}}}\n    //}}}\n\n    if (Touch.support) $trk.bind('touchstart.jcrop', Touch.newSelection);\n\n    $hdl_holder.hide();\n    interfaceUpdate(true);\n\n    var api = {\n      setImage: setImage,\n      animateTo: animateTo,\n      setSelect: setSelect,\n      setOptions: setOptionsNew,\n      tellSelect: tellSelect,\n      tellScaled: tellScaled,\n      setClass: setClass,\n\n      disable: disableCrop,\n      enable: enableCrop,\n      cancel: cancelCrop,\n      release: Selection.release,\n      destroy: destroy,\n\n      focus: KeyManager.watchKeys,\n\n      getBounds: function () {\n        return [boundx * xscale, boundy * yscale];\n      },\n      getWidgetSize: function () {\n        return [boundx, boundy];\n      },\n      getScaleFactor: function () {\n        return [xscale, yscale];\n      },\n      getOptions: function() {\n        // careful: internal values are returned\n        return options;\n      },\n\n      ui: {\n        holder: $div,\n        selection: $sel\n      }\n    };\n\n    if (is_msie) $div.bind('selectstart', function () { return false; });\n\n    $origimg.data('Jcrop', api);\n    return api;\n  };\n  $.fn.Jcrop = function (options, callback) //{{{\n  {\n    var api;\n    // Iterate over each object, attach Jcrop\n    this.each(function () {\n      // If we've already attached to this object\n      if ($(this).data('Jcrop')) {\n        // The API can be requested this way (undocumented)\n        if (options === 'api') return $(this).data('Jcrop');\n        // Otherwise, we just reset the options...\n        else $(this).data('Jcrop').setOptions(options);\n      }\n      // If we haven't been attached, preload and attach\n      else {\n        if (this.tagName == 'IMG')\n          $.Jcrop.Loader(this,function(){\n            $(this).css({display:'block',visibility:'hidden'});\n            api = $.Jcrop(this, options);\n            if ($.isFunction(callback)) callback.call(api);\n          });\n        else {\n          $(this).css({display:'block',visibility:'hidden'});\n          api = $.Jcrop(this, options);\n          if ($.isFunction(callback)) callback.call(api);\n        }\n      }\n    });\n\n    // Return \"this\" so the object is chainable (jQuery-style)\n    return this;\n  };\n  //}}}\n  // $.Jcrop.Loader - basic image loader {{{\n\n  $.Jcrop.Loader = function(imgobj,success,error){\n    var $img = $(imgobj), img = $img[0];\n\n    function completeCheck(){\n      if (img.complete) {\n        $img.unbind('.jcloader');\n        if ($.isFunction(success)) success.call(img);\n      }\n      else window.setTimeout(completeCheck,50);\n    }\n\n    $img\n      .bind('load.jcloader',completeCheck)\n      .bind('error.jcloader',function(e){\n        $img.unbind('.jcloader');\n        if ($.isFunction(error)) error.call(img);\n      });\n\n    if (img.complete && $.isFunction(success)){\n      $img.unbind('.jcloader');\n      success.call(img);\n    }\n  };\n\n  //}}}\n  // Global Defaults {{{\n  $.Jcrop.defaults = {\n\n    // Basic Settings\n    allowSelect: true,\n    allowMove: true,\n    allowResize: true,\n\n    trackDocument: true,\n\n    // Styling Options\n    baseClass: 'jcrop',\n    addClass: null,\n    bgColor: 'black',\n    bgOpacity: 0.6,\n    bgFade: false,\n    borderOpacity: 0.4,\n    handleOpacity: 0.5,\n    handleSize: null,\n\n    aspectRatio: 0,\n    keySupport: true,\n    createHandles: ['n','s','e','w','nw','ne','se','sw'],\n    createDragbars: ['n','s','e','w'],\n    createBorders: ['n','s','e','w'],\n    drawBorders: true,\n    dragEdges: true,\n    fixedSupport: true,\n    touchSupport: null,\n\n    shade: null,\n\n    boxWidth: 0,\n    boxHeight: 0,\n    boundary: 2,\n    fadeTime: 400,\n    animationDelay: 20,\n    swingSpeed: 3,\n\n    minSelect: [0, 0],\n    maxSize: [0, 0],\n    minSize: [0, 0],\n\n    // Callbacks / Event Handlers\n    onChange: function () {},\n    onSelect: function () {},\n    onDblClick: function () {},\n    onRelease: function () {}\n  };\n\n  // }}}\n}(jQuery));\n"
  },
  {
    "path": "app_frontend/static/plugin/JavaScript-Load-Image-2.12.2/js/vendor/jquery.js",
    "content": "/*!\n * jQuery JavaScript Library v1.11.3\n * http://jquery.com/\n *\n * Includes Sizzle.js\n * http://sizzlejs.com/\n *\n * Copyright 2005, 2014 jQuery Foundation, Inc. and other contributors\n * Released under the MIT license\n * http://jquery.org/license\n *\n * Date: 2015-04-28T16:19Z\n */\n\n(function( global, factory ) {\n\n\tif ( typeof module === \"object\" && typeof module.exports === \"object\" ) {\n\t\t// For CommonJS and CommonJS-like environments where a proper window is present,\n\t\t// execute the factory and get jQuery\n\t\t// For environments that do not inherently posses a window with a document\n\t\t// (such as Node.js), expose a jQuery-making factory as module.exports\n\t\t// This accentuates the need for the creation of a real window\n\t\t// e.g. var jQuery = require(\"jquery\")(window);\n\t\t// See ticket #14549 for more info\n\t\tmodule.exports = global.document ?\n\t\t\tfactory( global, true ) :\n\t\t\tfunction( w ) {\n\t\t\t\tif ( !w.document ) {\n\t\t\t\t\tthrow new Error( \"jQuery requires a window with a document\" );\n\t\t\t\t}\n\t\t\t\treturn factory( w );\n\t\t\t};\n\t} else {\n\t\tfactory( global );\n\t}\n\n// Pass this if window is not defined yet\n}(typeof window !== \"undefined\" ? window : this, function( window, noGlobal ) {\n\n// Can't do this because several apps including ASP.NET trace\n// the stack via arguments.caller.callee and Firefox dies if\n// you try to trace through \"use strict\" call chains. (#13335)\n// Support: Firefox 18+\n//\n\nvar deletedIds = [];\n\nvar slice = deletedIds.slice;\n\nvar concat = deletedIds.concat;\n\nvar push = deletedIds.push;\n\nvar indexOf = deletedIds.indexOf;\n\nvar class2type = {};\n\nvar toString = class2type.toString;\n\nvar hasOwn = class2type.hasOwnProperty;\n\nvar support = {};\n\n\n\nvar\n\tversion = \"1.11.3\",\n\n\t// Define a local copy of jQuery\n\tjQuery = function( selector, context ) {\n\t\t// The jQuery object is actually just the init constructor 'enhanced'\n\t\t// Need init if jQuery is called (just allow error to be thrown if not included)\n\t\treturn new jQuery.fn.init( selector, context );\n\t},\n\n\t// Support: Android<4.1, IE<9\n\t// Make sure we trim BOM and NBSP\n\trtrim = /^[\\s\\uFEFF\\xA0]+|[\\s\\uFEFF\\xA0]+$/g,\n\n\t// Matches dashed string for camelizing\n\trmsPrefix = /^-ms-/,\n\trdashAlpha = /-([\\da-z])/gi,\n\n\t// Used by jQuery.camelCase as callback to replace()\n\tfcamelCase = function( all, letter ) {\n\t\treturn letter.toUpperCase();\n\t};\n\njQuery.fn = jQuery.prototype = {\n\t// The current version of jQuery being used\n\tjquery: version,\n\n\tconstructor: jQuery,\n\n\t// Start with an empty selector\n\tselector: \"\",\n\n\t// The default length of a jQuery object is 0\n\tlength: 0,\n\n\ttoArray: function() {\n\t\treturn slice.call( this );\n\t},\n\n\t// Get the Nth element in the matched element set OR\n\t// Get the whole matched element set as a clean array\n\tget: function( num ) {\n\t\treturn num != null ?\n\n\t\t\t// Return just the one element from the set\n\t\t\t( num < 0 ? this[ num + this.length ] : this[ num ] ) :\n\n\t\t\t// Return all the elements in a clean array\n\t\t\tslice.call( this );\n\t},\n\n\t// Take an array of elements and push it onto the stack\n\t// (returning the new matched element set)\n\tpushStack: function( elems ) {\n\n\t\t// Build a new jQuery matched element set\n\t\tvar ret = jQuery.merge( this.constructor(), elems );\n\n\t\t// Add the old object onto the stack (as a reference)\n\t\tret.prevObject = this;\n\t\tret.context = this.context;\n\n\t\t// Return the newly-formed element set\n\t\treturn ret;\n\t},\n\n\t// Execute a callback for every element in the matched set.\n\t// (You can seed the arguments with an array of args, but this is\n\t// only used internally.)\n\teach: function( callback, args ) {\n\t\treturn jQuery.each( this, callback, args );\n\t},\n\n\tmap: function( callback ) {\n\t\treturn this.pushStack( jQuery.map(this, function( elem, i ) {\n\t\t\treturn callback.call( elem, i, elem );\n\t\t}));\n\t},\n\n\tslice: function() {\n\t\treturn this.pushStack( slice.apply( this, arguments ) );\n\t},\n\n\tfirst: function() {\n\t\treturn this.eq( 0 );\n\t},\n\n\tlast: function() {\n\t\treturn this.eq( -1 );\n\t},\n\n\teq: function( i ) {\n\t\tvar len = this.length,\n\t\t\tj = +i + ( i < 0 ? len : 0 );\n\t\treturn this.pushStack( j >= 0 && j < len ? [ this[j] ] : [] );\n\t},\n\n\tend: function() {\n\t\treturn this.prevObject || this.constructor(null);\n\t},\n\n\t// For internal use only.\n\t// Behaves like an Array's method, not like a jQuery method.\n\tpush: push,\n\tsort: deletedIds.sort,\n\tsplice: deletedIds.splice\n};\n\njQuery.extend = jQuery.fn.extend = function() {\n\tvar src, copyIsArray, copy, name, options, clone,\n\t\ttarget = arguments[0] || {},\n\t\ti = 1,\n\t\tlength = arguments.length,\n\t\tdeep = false;\n\n\t// Handle a deep copy situation\n\tif ( typeof target === \"boolean\" ) {\n\t\tdeep = target;\n\n\t\t// skip the boolean and the target\n\t\ttarget = arguments[ i ] || {};\n\t\ti++;\n\t}\n\n\t// Handle case when target is a string or something (possible in deep copy)\n\tif ( typeof target !== \"object\" && !jQuery.isFunction(target) ) {\n\t\ttarget = {};\n\t}\n\n\t// extend jQuery itself if only one argument is passed\n\tif ( i === length ) {\n\t\ttarget = this;\n\t\ti--;\n\t}\n\n\tfor ( ; i < length; i++ ) {\n\t\t// Only deal with non-null/undefined values\n\t\tif ( (options = arguments[ i ]) != null ) {\n\t\t\t// Extend the base object\n\t\t\tfor ( name in options ) {\n\t\t\t\tsrc = target[ name ];\n\t\t\t\tcopy = options[ name ];\n\n\t\t\t\t// Prevent never-ending loop\n\t\t\t\tif ( target === copy ) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\t// Recurse if we're merging plain objects or arrays\n\t\t\t\tif ( deep && copy && ( jQuery.isPlainObject(copy) || (copyIsArray = jQuery.isArray(copy)) ) ) {\n\t\t\t\t\tif ( copyIsArray ) {\n\t\t\t\t\t\tcopyIsArray = false;\n\t\t\t\t\t\tclone = src && jQuery.isArray(src) ? src : [];\n\n\t\t\t\t\t} else {\n\t\t\t\t\t\tclone = src && jQuery.isPlainObject(src) ? src : {};\n\t\t\t\t\t}\n\n\t\t\t\t\t// Never move original objects, clone them\n\t\t\t\t\ttarget[ name ] = jQuery.extend( deep, clone, copy );\n\n\t\t\t\t// Don't bring in undefined values\n\t\t\t\t} else if ( copy !== undefined ) {\n\t\t\t\t\ttarget[ name ] = copy;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t// Return the modified object\n\treturn target;\n};\n\njQuery.extend({\n\t// Unique for each copy of jQuery on the page\n\texpando: \"jQuery\" + ( version + Math.random() ).replace( /\\D/g, \"\" ),\n\n\t// Assume jQuery is ready without the ready module\n\tisReady: true,\n\n\terror: function( msg ) {\n\t\tthrow new Error( msg );\n\t},\n\n\tnoop: function() {},\n\n\t// See test/unit/core.js for details concerning isFunction.\n\t// Since version 1.3, DOM methods and functions like alert\n\t// aren't supported. They return false on IE (#2968).\n\tisFunction: function( obj ) {\n\t\treturn jQuery.type(obj) === \"function\";\n\t},\n\n\tisArray: Array.isArray || function( obj ) {\n\t\treturn jQuery.type(obj) === \"array\";\n\t},\n\n\tisWindow: function( obj ) {\n\t\t/* jshint eqeqeq: false */\n\t\treturn obj != null && obj == obj.window;\n\t},\n\n\tisNumeric: function( obj ) {\n\t\t// parseFloat NaNs numeric-cast false positives (null|true|false|\"\")\n\t\t// ...but misinterprets leading-number strings, particularly hex literals (\"0x...\")\n\t\t// subtraction forces infinities to NaN\n\t\t// adding 1 corrects loss of precision from parseFloat (#15100)\n\t\treturn !jQuery.isArray( obj ) && (obj - parseFloat( obj ) + 1) >= 0;\n\t},\n\n\tisEmptyObject: function( obj ) {\n\t\tvar name;\n\t\tfor ( name in obj ) {\n\t\t\treturn false;\n\t\t}\n\t\treturn true;\n\t},\n\n\tisPlainObject: function( obj ) {\n\t\tvar key;\n\n\t\t// Must be an Object.\n\t\t// Because of IE, we also have to check the presence of the constructor property.\n\t\t// Make sure that DOM nodes and window objects don't pass through, as well\n\t\tif ( !obj || jQuery.type(obj) !== \"object\" || obj.nodeType || jQuery.isWindow( obj ) ) {\n\t\t\treturn false;\n\t\t}\n\n\t\ttry {\n\t\t\t// Not own constructor property must be Object\n\t\t\tif ( obj.constructor &&\n\t\t\t\t!hasOwn.call(obj, \"constructor\") &&\n\t\t\t\t!hasOwn.call(obj.constructor.prototype, \"isPrototypeOf\") ) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t} catch ( e ) {\n\t\t\t// IE8,9 Will throw exceptions on certain host objects #9897\n\t\t\treturn false;\n\t\t}\n\n\t\t// Support: IE<9\n\t\t// Handle iteration over inherited properties before own properties.\n\t\tif ( support.ownLast ) {\n\t\t\tfor ( key in obj ) {\n\t\t\t\treturn hasOwn.call( obj, key );\n\t\t\t}\n\t\t}\n\n\t\t// Own properties are enumerated firstly, so to speed up,\n\t\t// if last one is own, then all properties are own.\n\t\tfor ( key in obj ) {}\n\n\t\treturn key === undefined || hasOwn.call( obj, key );\n\t},\n\n\ttype: function( obj ) {\n\t\tif ( obj == null ) {\n\t\t\treturn obj + \"\";\n\t\t}\n\t\treturn typeof obj === \"object\" || typeof obj === \"function\" ?\n\t\t\tclass2type[ toString.call(obj) ] || \"object\" :\n\t\t\ttypeof obj;\n\t},\n\n\t// Evaluates a script in a global context\n\t// Workarounds based on findings by Jim Driscoll\n\t// http://weblogs.java.net/blog/driscoll/archive/2009/09/08/eval-javascript-global-context\n\tglobalEval: function( data ) {\n\t\tif ( data && jQuery.trim( data ) ) {\n\t\t\t// We use execScript on Internet Explorer\n\t\t\t// We use an anonymous function so that context is window\n\t\t\t// rather than jQuery in Firefox\n\t\t\t( window.execScript || function( data ) {\n\t\t\t\twindow[ \"eval\" ].call( window, data );\n\t\t\t} )( data );\n\t\t}\n\t},\n\n\t// Convert dashed to camelCase; used by the css and data modules\n\t// Microsoft forgot to hump their vendor prefix (#9572)\n\tcamelCase: function( string ) {\n\t\treturn string.replace( rmsPrefix, \"ms-\" ).replace( rdashAlpha, fcamelCase );\n\t},\n\n\tnodeName: function( elem, name ) {\n\t\treturn elem.nodeName && elem.nodeName.toLowerCase() === name.toLowerCase();\n\t},\n\n\t// args is for internal usage only\n\teach: function( obj, callback, args ) {\n\t\tvar value,\n\t\t\ti = 0,\n\t\t\tlength = obj.length,\n\t\t\tisArray = isArraylike( obj );\n\n\t\tif ( args ) {\n\t\t\tif ( isArray ) {\n\t\t\t\tfor ( ; i < length; i++ ) {\n\t\t\t\t\tvalue = callback.apply( obj[ i ], args );\n\n\t\t\t\t\tif ( value === false ) {\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tfor ( i in obj ) {\n\t\t\t\t\tvalue = callback.apply( obj[ i ], args );\n\n\t\t\t\t\tif ( value === false ) {\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t// A special, fast, case for the most common use of each\n\t\t} else {\n\t\t\tif ( isArray ) {\n\t\t\t\tfor ( ; i < length; i++ ) {\n\t\t\t\t\tvalue = callback.call( obj[ i ], i, obj[ i ] );\n\n\t\t\t\t\tif ( value === false ) {\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tfor ( i in obj ) {\n\t\t\t\t\tvalue = callback.call( obj[ i ], i, obj[ i ] );\n\n\t\t\t\t\tif ( value === false ) {\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn obj;\n\t},\n\n\t// Support: Android<4.1, IE<9\n\ttrim: function( text ) {\n\t\treturn text == null ?\n\t\t\t\"\" :\n\t\t\t( text + \"\" ).replace( rtrim, \"\" );\n\t},\n\n\t// results is for internal usage only\n\tmakeArray: function( arr, results ) {\n\t\tvar ret = results || [];\n\n\t\tif ( arr != null ) {\n\t\t\tif ( isArraylike( Object(arr) ) ) {\n\t\t\t\tjQuery.merge( ret,\n\t\t\t\t\ttypeof arr === \"string\" ?\n\t\t\t\t\t[ arr ] : arr\n\t\t\t\t);\n\t\t\t} else {\n\t\t\t\tpush.call( ret, arr );\n\t\t\t}\n\t\t}\n\n\t\treturn ret;\n\t},\n\n\tinArray: function( elem, arr, i ) {\n\t\tvar len;\n\n\t\tif ( arr ) {\n\t\t\tif ( indexOf ) {\n\t\t\t\treturn indexOf.call( arr, elem, i );\n\t\t\t}\n\n\t\t\tlen = arr.length;\n\t\t\ti = i ? i < 0 ? Math.max( 0, len + i ) : i : 0;\n\n\t\t\tfor ( ; i < len; i++ ) {\n\t\t\t\t// Skip accessing in sparse arrays\n\t\t\t\tif ( i in arr && arr[ i ] === elem ) {\n\t\t\t\t\treturn i;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn -1;\n\t},\n\n\tmerge: function( first, second ) {\n\t\tvar len = +second.length,\n\t\t\tj = 0,\n\t\t\ti = first.length;\n\n\t\twhile ( j < len ) {\n\t\t\tfirst[ i++ ] = second[ j++ ];\n\t\t}\n\n\t\t// Support: IE<9\n\t\t// Workaround casting of .length to NaN on otherwise arraylike objects (e.g., NodeLists)\n\t\tif ( len !== len ) {\n\t\t\twhile ( second[j] !== undefined ) {\n\t\t\t\tfirst[ i++ ] = second[ j++ ];\n\t\t\t}\n\t\t}\n\n\t\tfirst.length = i;\n\n\t\treturn first;\n\t},\n\n\tgrep: function( elems, callback, invert ) {\n\t\tvar callbackInverse,\n\t\t\tmatches = [],\n\t\t\ti = 0,\n\t\t\tlength = elems.length,\n\t\t\tcallbackExpect = !invert;\n\n\t\t// Go through the array, only saving the items\n\t\t// that pass the validator function\n\t\tfor ( ; i < length; i++ ) {\n\t\t\tcallbackInverse = !callback( elems[ i ], i );\n\t\t\tif ( callbackInverse !== callbackExpect ) {\n\t\t\t\tmatches.push( elems[ i ] );\n\t\t\t}\n\t\t}\n\n\t\treturn matches;\n\t},\n\n\t// arg is for internal usage only\n\tmap: function( elems, callback, arg ) {\n\t\tvar value,\n\t\t\ti = 0,\n\t\t\tlength = elems.length,\n\t\t\tisArray = isArraylike( elems ),\n\t\t\tret = [];\n\n\t\t// Go through the array, translating each of the items to their new values\n\t\tif ( isArray ) {\n\t\t\tfor ( ; i < length; i++ ) {\n\t\t\t\tvalue = callback( elems[ i ], i, arg );\n\n\t\t\t\tif ( value != null ) {\n\t\t\t\t\tret.push( value );\n\t\t\t\t}\n\t\t\t}\n\n\t\t// Go through every key on the object,\n\t\t} else {\n\t\t\tfor ( i in elems ) {\n\t\t\t\tvalue = callback( elems[ i ], i, arg );\n\n\t\t\t\tif ( value != null ) {\n\t\t\t\t\tret.push( value );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Flatten any nested arrays\n\t\treturn concat.apply( [], ret );\n\t},\n\n\t// A global GUID counter for objects\n\tguid: 1,\n\n\t// Bind a function to a context, optionally partially applying any\n\t// arguments.\n\tproxy: function( fn, context ) {\n\t\tvar args, proxy, tmp;\n\n\t\tif ( typeof context === \"string\" ) {\n\t\t\ttmp = fn[ context ];\n\t\t\tcontext = fn;\n\t\t\tfn = tmp;\n\t\t}\n\n\t\t// Quick check to determine if target is callable, in the spec\n\t\t// this throws a TypeError, but we will just return undefined.\n\t\tif ( !jQuery.isFunction( fn ) ) {\n\t\t\treturn undefined;\n\t\t}\n\n\t\t// Simulated bind\n\t\targs = slice.call( arguments, 2 );\n\t\tproxy = function() {\n\t\t\treturn fn.apply( context || this, args.concat( slice.call( arguments ) ) );\n\t\t};\n\n\t\t// Set the guid of unique handler to the same of original handler, so it can be removed\n\t\tproxy.guid = fn.guid = fn.guid || jQuery.guid++;\n\n\t\treturn proxy;\n\t},\n\n\tnow: function() {\n\t\treturn +( new Date() );\n\t},\n\n\t// jQuery.support is not used in Core but other projects attach their\n\t// properties to it so it needs to exist.\n\tsupport: support\n});\n\n// Populate the class2type map\njQuery.each(\"Boolean Number String Function Array Date RegExp Object Error\".split(\" \"), function(i, name) {\n\tclass2type[ \"[object \" + name + \"]\" ] = name.toLowerCase();\n});\n\nfunction isArraylike( obj ) {\n\n\t// Support: iOS 8.2 (not reproducible in simulator)\n\t// `in` check used to prevent JIT error (gh-2145)\n\t// hasOwn isn't used here due to false negatives\n\t// regarding Nodelist length in IE\n\tvar length = \"length\" in obj && obj.length,\n\t\ttype = jQuery.type( obj );\n\n\tif ( type === \"function\" || jQuery.isWindow( obj ) ) {\n\t\treturn false;\n\t}\n\n\tif ( obj.nodeType === 1 && length ) {\n\t\treturn true;\n\t}\n\n\treturn type === \"array\" || length === 0 ||\n\t\ttypeof length === \"number\" && length > 0 && ( length - 1 ) in obj;\n}\nvar Sizzle =\n/*!\n * Sizzle CSS Selector Engine v2.2.0-pre\n * http://sizzlejs.com/\n *\n * Copyright 2008, 2014 jQuery Foundation, Inc. and other contributors\n * Released under the MIT license\n * http://jquery.org/license\n *\n * Date: 2014-12-16\n */\n(function( window ) {\n\nvar i,\n\tsupport,\n\tExpr,\n\tgetText,\n\tisXML,\n\ttokenize,\n\tcompile,\n\tselect,\n\toutermostContext,\n\tsortInput,\n\thasDuplicate,\n\n\t// Local document vars\n\tsetDocument,\n\tdocument,\n\tdocElem,\n\tdocumentIsHTML,\n\trbuggyQSA,\n\trbuggyMatches,\n\tmatches,\n\tcontains,\n\n\t// Instance-specific data\n\texpando = \"sizzle\" + 1 * new Date(),\n\tpreferredDoc = window.document,\n\tdirruns = 0,\n\tdone = 0,\n\tclassCache = createCache(),\n\ttokenCache = createCache(),\n\tcompilerCache = createCache(),\n\tsortOrder = function( a, b ) {\n\t\tif ( a === b ) {\n\t\t\thasDuplicate = true;\n\t\t}\n\t\treturn 0;\n\t},\n\n\t// General-purpose constants\n\tMAX_NEGATIVE = 1 << 31,\n\n\t// Instance methods\n\thasOwn = ({}).hasOwnProperty,\n\tarr = [],\n\tpop = arr.pop,\n\tpush_native = arr.push,\n\tpush = arr.push,\n\tslice = arr.slice,\n\t// Use a stripped-down indexOf as it's faster than native\n\t// http://jsperf.com/thor-indexof-vs-for/5\n\tindexOf = function( list, elem ) {\n\t\tvar i = 0,\n\t\t\tlen = list.length;\n\t\tfor ( ; i < len; i++ ) {\n\t\t\tif ( list[i] === elem ) {\n\t\t\t\treturn i;\n\t\t\t}\n\t\t}\n\t\treturn -1;\n\t},\n\n\tbooleans = \"checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped\",\n\n\t// Regular expressions\n\n\t// Whitespace characters http://www.w3.org/TR/css3-selectors/#whitespace\n\twhitespace = \"[\\\\x20\\\\t\\\\r\\\\n\\\\f]\",\n\t// http://www.w3.org/TR/css3-syntax/#characters\n\tcharacterEncoding = \"(?:\\\\\\\\.|[\\\\w-]|[^\\\\x00-\\\\xa0])+\",\n\n\t// Loosely modeled on CSS identifier characters\n\t// An unquoted value should be a CSS identifier http://www.w3.org/TR/css3-selectors/#attribute-selectors\n\t// Proper syntax: http://www.w3.org/TR/CSS21/syndata.html#value-def-identifier\n\tidentifier = characterEncoding.replace( \"w\", \"w#\" ),\n\n\t// Attribute selectors: http://www.w3.org/TR/selectors/#attribute-selectors\n\tattributes = \"\\\\[\" + whitespace + \"*(\" + characterEncoding + \")(?:\" + whitespace +\n\t\t// Operator (capture 2)\n\t\t\"*([*^$|!~]?=)\" + whitespace +\n\t\t// \"Attribute values must be CSS identifiers [capture 5] or strings [capture 3 or capture 4]\"\n\t\t\"*(?:'((?:\\\\\\\\.|[^\\\\\\\\'])*)'|\\\"((?:\\\\\\\\.|[^\\\\\\\\\\\"])*)\\\"|(\" + identifier + \"))|)\" + whitespace +\n\t\t\"*\\\\]\",\n\n\tpseudos = \":(\" + characterEncoding + \")(?:\\\\((\" +\n\t\t// To reduce the number of selectors needing tokenize in the preFilter, prefer arguments:\n\t\t// 1. quoted (capture 3; capture 4 or capture 5)\n\t\t\"('((?:\\\\\\\\.|[^\\\\\\\\'])*)'|\\\"((?:\\\\\\\\.|[^\\\\\\\\\\\"])*)\\\")|\" +\n\t\t// 2. simple (capture 6)\n\t\t\"((?:\\\\\\\\.|[^\\\\\\\\()[\\\\]]|\" + attributes + \")*)|\" +\n\t\t// 3. anything else (capture 2)\n\t\t\".*\" +\n\t\t\")\\\\)|)\",\n\n\t// Leading and non-escaped trailing whitespace, capturing some non-whitespace characters preceding the latter\n\trwhitespace = new RegExp( whitespace + \"+\", \"g\" ),\n\trtrim = new RegExp( \"^\" + whitespace + \"+|((?:^|[^\\\\\\\\])(?:\\\\\\\\.)*)\" + whitespace + \"+$\", \"g\" ),\n\n\trcomma = new RegExp( \"^\" + whitespace + \"*,\" + whitespace + \"*\" ),\n\trcombinators = new RegExp( \"^\" + whitespace + \"*([>+~]|\" + whitespace + \")\" + whitespace + \"*\" ),\n\n\trattributeQuotes = new RegExp( \"=\" + whitespace + \"*([^\\\\]'\\\"]*?)\" + whitespace + \"*\\\\]\", \"g\" ),\n\n\trpseudo = new RegExp( pseudos ),\n\tridentifier = new RegExp( \"^\" + identifier + \"$\" ),\n\n\tmatchExpr = {\n\t\t\"ID\": new RegExp( \"^#(\" + characterEncoding + \")\" ),\n\t\t\"CLASS\": new RegExp( \"^\\\\.(\" + characterEncoding + \")\" ),\n\t\t\"TAG\": new RegExp( \"^(\" + characterEncoding.replace( \"w\", \"w*\" ) + \")\" ),\n\t\t\"ATTR\": new RegExp( \"^\" + attributes ),\n\t\t\"PSEUDO\": new RegExp( \"^\" + pseudos ),\n\t\t\"CHILD\": new RegExp( \"^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\\\(\" + whitespace +\n\t\t\t\"*(even|odd|(([+-]|)(\\\\d*)n|)\" + whitespace + \"*(?:([+-]|)\" + whitespace +\n\t\t\t\"*(\\\\d+)|))\" + whitespace + \"*\\\\)|)\", \"i\" ),\n\t\t\"bool\": new RegExp( \"^(?:\" + booleans + \")$\", \"i\" ),\n\t\t// For use in libraries implementing .is()\n\t\t// We use this for POS matching in `select`\n\t\t\"needsContext\": new RegExp( \"^\" + whitespace + \"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\\\(\" +\n\t\t\twhitespace + \"*((?:-\\\\d)?\\\\d*)\" + whitespace + \"*\\\\)|)(?=[^-]|$)\", \"i\" )\n\t},\n\n\trinputs = /^(?:input|select|textarea|button)$/i,\n\trheader = /^h\\d$/i,\n\n\trnative = /^[^{]+\\{\\s*\\[native \\w/,\n\n\t// Easily-parseable/retrievable ID or TAG or CLASS selectors\n\trquickExpr = /^(?:#([\\w-]+)|(\\w+)|\\.([\\w-]+))$/,\n\n\trsibling = /[+~]/,\n\trescape = /'|\\\\/g,\n\n\t// CSS escapes http://www.w3.org/TR/CSS21/syndata.html#escaped-characters\n\trunescape = new RegExp( \"\\\\\\\\([\\\\da-f]{1,6}\" + whitespace + \"?|(\" + whitespace + \")|.)\", \"ig\" ),\n\tfunescape = function( _, escaped, escapedWhitespace ) {\n\t\tvar high = \"0x\" + escaped - 0x10000;\n\t\t// NaN means non-codepoint\n\t\t// Support: Firefox<24\n\t\t// Workaround erroneous numeric interpretation of +\"0x\"\n\t\treturn high !== high || escapedWhitespace ?\n\t\t\tescaped :\n\t\t\thigh < 0 ?\n\t\t\t\t// BMP codepoint\n\t\t\t\tString.fromCharCode( high + 0x10000 ) :\n\t\t\t\t// Supplemental Plane codepoint (surrogate pair)\n\t\t\t\tString.fromCharCode( high >> 10 | 0xD800, high & 0x3FF | 0xDC00 );\n\t},\n\n\t// Used for iframes\n\t// See setDocument()\n\t// Removing the function wrapper causes a \"Permission Denied\"\n\t// error in IE\n\tunloadHandler = function() {\n\t\tsetDocument();\n\t};\n\n// Optimize for push.apply( _, NodeList )\ntry {\n\tpush.apply(\n\t\t(arr = slice.call( preferredDoc.childNodes )),\n\t\tpreferredDoc.childNodes\n\t);\n\t// Support: Android<4.0\n\t// Detect silently failing push.apply\n\tarr[ preferredDoc.childNodes.length ].nodeType;\n} catch ( e ) {\n\tpush = { apply: arr.length ?\n\n\t\t// Leverage slice if possible\n\t\tfunction( target, els ) {\n\t\t\tpush_native.apply( target, slice.call(els) );\n\t\t} :\n\n\t\t// Support: IE<9\n\t\t// Otherwise append directly\n\t\tfunction( target, els ) {\n\t\t\tvar j = target.length,\n\t\t\t\ti = 0;\n\t\t\t// Can't trust NodeList.length\n\t\t\twhile ( (target[j++] = els[i++]) ) {}\n\t\t\ttarget.length = j - 1;\n\t\t}\n\t};\n}\n\nfunction Sizzle( selector, context, results, seed ) {\n\tvar match, elem, m, nodeType,\n\t\t// QSA vars\n\t\ti, groups, old, nid, newContext, newSelector;\n\n\tif ( ( context ? context.ownerDocument || context : preferredDoc ) !== document ) {\n\t\tsetDocument( context );\n\t}\n\n\tcontext = context || document;\n\tresults = results || [];\n\tnodeType = context.nodeType;\n\n\tif ( typeof selector !== \"string\" || !selector ||\n\t\tnodeType !== 1 && nodeType !== 9 && nodeType !== 11 ) {\n\n\t\treturn results;\n\t}\n\n\tif ( !seed && documentIsHTML ) {\n\n\t\t// Try to shortcut find operations when possible (e.g., not under DocumentFragment)\n\t\tif ( nodeType !== 11 && (match = rquickExpr.exec( selector )) ) {\n\t\t\t// Speed-up: Sizzle(\"#ID\")\n\t\t\tif ( (m = match[1]) ) {\n\t\t\t\tif ( nodeType === 9 ) {\n\t\t\t\t\telem = context.getElementById( m );\n\t\t\t\t\t// Check parentNode to catch when Blackberry 4.6 returns\n\t\t\t\t\t// nodes that are no longer in the document (jQuery #6963)\n\t\t\t\t\tif ( elem && elem.parentNode ) {\n\t\t\t\t\t\t// Handle the case where IE, Opera, and Webkit return items\n\t\t\t\t\t\t// by name instead of ID\n\t\t\t\t\t\tif ( elem.id === m ) {\n\t\t\t\t\t\t\tresults.push( elem );\n\t\t\t\t\t\t\treturn results;\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\treturn results;\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\t// Context is not a document\n\t\t\t\t\tif ( context.ownerDocument && (elem = context.ownerDocument.getElementById( m )) &&\n\t\t\t\t\t\tcontains( context, elem ) && elem.id === m ) {\n\t\t\t\t\t\tresults.push( elem );\n\t\t\t\t\t\treturn results;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t// Speed-up: Sizzle(\"TAG\")\n\t\t\t} else if ( match[2] ) {\n\t\t\t\tpush.apply( results, context.getElementsByTagName( selector ) );\n\t\t\t\treturn results;\n\n\t\t\t// Speed-up: Sizzle(\".CLASS\")\n\t\t\t} else if ( (m = match[3]) && support.getElementsByClassName ) {\n\t\t\t\tpush.apply( results, context.getElementsByClassName( m ) );\n\t\t\t\treturn results;\n\t\t\t}\n\t\t}\n\n\t\t// QSA path\n\t\tif ( support.qsa && (!rbuggyQSA || !rbuggyQSA.test( selector )) ) {\n\t\t\tnid = old = expando;\n\t\t\tnewContext = context;\n\t\t\tnewSelector = nodeType !== 1 && selector;\n\n\t\t\t// qSA works strangely on Element-rooted queries\n\t\t\t// We can work around this by specifying an extra ID on the root\n\t\t\t// and working up from there (Thanks to Andrew Dupont for the technique)\n\t\t\t// IE 8 doesn't work on object elements\n\t\t\tif ( nodeType === 1 && context.nodeName.toLowerCase() !== \"object\" ) {\n\t\t\t\tgroups = tokenize( selector );\n\n\t\t\t\tif ( (old = context.getAttribute(\"id\")) ) {\n\t\t\t\t\tnid = old.replace( rescape, \"\\\\$&\" );\n\t\t\t\t} else {\n\t\t\t\t\tcontext.setAttribute( \"id\", nid );\n\t\t\t\t}\n\t\t\t\tnid = \"[id='\" + nid + \"'] \";\n\n\t\t\t\ti = groups.length;\n\t\t\t\twhile ( i-- ) {\n\t\t\t\t\tgroups[i] = nid + toSelector( groups[i] );\n\t\t\t\t}\n\t\t\t\tnewContext = rsibling.test( selector ) && testContext( context.parentNode ) || context;\n\t\t\t\tnewSelector = groups.join(\",\");\n\t\t\t}\n\n\t\t\tif ( newSelector ) {\n\t\t\t\ttry {\n\t\t\t\t\tpush.apply( results,\n\t\t\t\t\t\tnewContext.querySelectorAll( newSelector )\n\t\t\t\t\t);\n\t\t\t\t\treturn results;\n\t\t\t\t} catch(qsaError) {\n\t\t\t\t} finally {\n\t\t\t\t\tif ( !old ) {\n\t\t\t\t\t\tcontext.removeAttribute(\"id\");\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t// All others\n\treturn select( selector.replace( rtrim, \"$1\" ), context, results, seed );\n}\n\n/**\n * Create key-value caches of limited size\n * @returns {Function(string, Object)} Returns the Object data after storing it on itself with\n *\tproperty name the (space-suffixed) string and (if the cache is larger than Expr.cacheLength)\n *\tdeleting the oldest entry\n */\nfunction createCache() {\n\tvar keys = [];\n\n\tfunction cache( key, value ) {\n\t\t// Use (key + \" \") to avoid collision with native prototype properties (see Issue #157)\n\t\tif ( keys.push( key + \" \" ) > Expr.cacheLength ) {\n\t\t\t// Only keep the most recent entries\n\t\t\tdelete cache[ keys.shift() ];\n\t\t}\n\t\treturn (cache[ key + \" \" ] = value);\n\t}\n\treturn cache;\n}\n\n/**\n * Mark a function for special use by Sizzle\n * @param {Function} fn The function to mark\n */\nfunction markFunction( fn ) {\n\tfn[ expando ] = true;\n\treturn fn;\n}\n\n/**\n * Support testing using an element\n * @param {Function} fn Passed the created div and expects a boolean result\n */\nfunction assert( fn ) {\n\tvar div = document.createElement(\"div\");\n\n\ttry {\n\t\treturn !!fn( div );\n\t} catch (e) {\n\t\treturn false;\n\t} finally {\n\t\t// Remove from its parent by default\n\t\tif ( div.parentNode ) {\n\t\t\tdiv.parentNode.removeChild( div );\n\t\t}\n\t\t// release memory in IE\n\t\tdiv = null;\n\t}\n}\n\n/**\n * Adds the same handler for all of the specified attrs\n * @param {String} attrs Pipe-separated list of attributes\n * @param {Function} handler The method that will be applied\n */\nfunction addHandle( attrs, handler ) {\n\tvar arr = attrs.split(\"|\"),\n\t\ti = attrs.length;\n\n\twhile ( i-- ) {\n\t\tExpr.attrHandle[ arr[i] ] = handler;\n\t}\n}\n\n/**\n * Checks document order of two siblings\n * @param {Element} a\n * @param {Element} b\n * @returns {Number} Returns less than 0 if a precedes b, greater than 0 if a follows b\n */\nfunction siblingCheck( a, b ) {\n\tvar cur = b && a,\n\t\tdiff = cur && a.nodeType === 1 && b.nodeType === 1 &&\n\t\t\t( ~b.sourceIndex || MAX_NEGATIVE ) -\n\t\t\t( ~a.sourceIndex || MAX_NEGATIVE );\n\n\t// Use IE sourceIndex if available on both nodes\n\tif ( diff ) {\n\t\treturn diff;\n\t}\n\n\t// Check if b follows a\n\tif ( cur ) {\n\t\twhile ( (cur = cur.nextSibling) ) {\n\t\t\tif ( cur === b ) {\n\t\t\t\treturn -1;\n\t\t\t}\n\t\t}\n\t}\n\n\treturn a ? 1 : -1;\n}\n\n/**\n * Returns a function to use in pseudos for input types\n * @param {String} type\n */\nfunction createInputPseudo( type ) {\n\treturn function( elem ) {\n\t\tvar name = elem.nodeName.toLowerCase();\n\t\treturn name === \"input\" && elem.type === type;\n\t};\n}\n\n/**\n * Returns a function to use in pseudos for buttons\n * @param {String} type\n */\nfunction createButtonPseudo( type ) {\n\treturn function( elem ) {\n\t\tvar name = elem.nodeName.toLowerCase();\n\t\treturn (name === \"input\" || name === \"button\") && elem.type === type;\n\t};\n}\n\n/**\n * Returns a function to use in pseudos for positionals\n * @param {Function} fn\n */\nfunction createPositionalPseudo( fn ) {\n\treturn markFunction(function( argument ) {\n\t\targument = +argument;\n\t\treturn markFunction(function( seed, matches ) {\n\t\t\tvar j,\n\t\t\t\tmatchIndexes = fn( [], seed.length, argument ),\n\t\t\t\ti = matchIndexes.length;\n\n\t\t\t// Match elements found at the specified indexes\n\t\t\twhile ( i-- ) {\n\t\t\t\tif ( seed[ (j = matchIndexes[i]) ] ) {\n\t\t\t\t\tseed[j] = !(matches[j] = seed[j]);\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\t});\n}\n\n/**\n * Checks a node for validity as a Sizzle context\n * @param {Element|Object=} context\n * @returns {Element|Object|Boolean} The input node if acceptable, otherwise a falsy value\n */\nfunction testContext( context ) {\n\treturn context && typeof context.getElementsByTagName !== \"undefined\" && context;\n}\n\n// Expose support vars for convenience\nsupport = Sizzle.support = {};\n\n/**\n * Detects XML nodes\n * @param {Element|Object} elem An element or a document\n * @returns {Boolean} True iff elem is a non-HTML XML node\n */\nisXML = Sizzle.isXML = function( elem ) {\n\t// documentElement is verified for cases where it doesn't yet exist\n\t// (such as loading iframes in IE - #4833)\n\tvar documentElement = elem && (elem.ownerDocument || elem).documentElement;\n\treturn documentElement ? documentElement.nodeName !== \"HTML\" : false;\n};\n\n/**\n * Sets document-related variables once based on the current document\n * @param {Element|Object} [doc] An element or document object to use to set the document\n * @returns {Object} Returns the current document\n */\nsetDocument = Sizzle.setDocument = function( node ) {\n\tvar hasCompare, parent,\n\t\tdoc = node ? node.ownerDocument || node : preferredDoc;\n\n\t// If no document and documentElement is available, return\n\tif ( doc === document || doc.nodeType !== 9 || !doc.documentElement ) {\n\t\treturn document;\n\t}\n\n\t// Set our document\n\tdocument = doc;\n\tdocElem = doc.documentElement;\n\tparent = doc.defaultView;\n\n\t// Support: IE>8\n\t// If iframe document is assigned to \"document\" variable and if iframe has been reloaded,\n\t// IE will throw \"permission denied\" error when accessing \"document\" variable, see jQuery #13936\n\t// IE6-8 do not support the defaultView property so parent will be undefined\n\tif ( parent && parent !== parent.top ) {\n\t\t// IE11 does not have attachEvent, so all must suffer\n\t\tif ( parent.addEventListener ) {\n\t\t\tparent.addEventListener( \"unload\", unloadHandler, false );\n\t\t} else if ( parent.attachEvent ) {\n\t\t\tparent.attachEvent( \"onunload\", unloadHandler );\n\t\t}\n\t}\n\n\t/* Support tests\n\t---------------------------------------------------------------------- */\n\tdocumentIsHTML = !isXML( doc );\n\n\t/* Attributes\n\t---------------------------------------------------------------------- */\n\n\t// Support: IE<8\n\t// Verify that getAttribute really returns attributes and not properties\n\t// (excepting IE8 booleans)\n\tsupport.attributes = assert(function( div ) {\n\t\tdiv.className = \"i\";\n\t\treturn !div.getAttribute(\"className\");\n\t});\n\n\t/* getElement(s)By*\n\t---------------------------------------------------------------------- */\n\n\t// Check if getElementsByTagName(\"*\") returns only elements\n\tsupport.getElementsByTagName = assert(function( div ) {\n\t\tdiv.appendChild( doc.createComment(\"\") );\n\t\treturn !div.getElementsByTagName(\"*\").length;\n\t});\n\n\t// Support: IE<9\n\tsupport.getElementsByClassName = rnative.test( doc.getElementsByClassName );\n\n\t// Support: IE<10\n\t// Check if getElementById returns elements by name\n\t// The broken getElementById methods don't pick up programatically-set names,\n\t// so use a roundabout getElementsByName test\n\tsupport.getById = assert(function( div ) {\n\t\tdocElem.appendChild( div ).id = expando;\n\t\treturn !doc.getElementsByName || !doc.getElementsByName( expando ).length;\n\t});\n\n\t// ID find and filter\n\tif ( support.getById ) {\n\t\tExpr.find[\"ID\"] = function( id, context ) {\n\t\t\tif ( typeof context.getElementById !== \"undefined\" && documentIsHTML ) {\n\t\t\t\tvar m = context.getElementById( id );\n\t\t\t\t// Check parentNode to catch when Blackberry 4.6 returns\n\t\t\t\t// nodes that are no longer in the document #6963\n\t\t\t\treturn m && m.parentNode ? [ m ] : [];\n\t\t\t}\n\t\t};\n\t\tExpr.filter[\"ID\"] = function( id ) {\n\t\t\tvar attrId = id.replace( runescape, funescape );\n\t\t\treturn function( elem ) {\n\t\t\t\treturn elem.getAttribute(\"id\") === attrId;\n\t\t\t};\n\t\t};\n\t} else {\n\t\t// Support: IE6/7\n\t\t// getElementById is not reliable as a find shortcut\n\t\tdelete Expr.find[\"ID\"];\n\n\t\tExpr.filter[\"ID\"] =  function( id ) {\n\t\t\tvar attrId = id.replace( runescape, funescape );\n\t\t\treturn function( elem ) {\n\t\t\t\tvar node = typeof elem.getAttributeNode !== \"undefined\" && elem.getAttributeNode(\"id\");\n\t\t\t\treturn node && node.value === attrId;\n\t\t\t};\n\t\t};\n\t}\n\n\t// Tag\n\tExpr.find[\"TAG\"] = support.getElementsByTagName ?\n\t\tfunction( tag, context ) {\n\t\t\tif ( typeof context.getElementsByTagName !== \"undefined\" ) {\n\t\t\t\treturn context.getElementsByTagName( tag );\n\n\t\t\t// DocumentFragment nodes don't have gEBTN\n\t\t\t} else if ( support.qsa ) {\n\t\t\t\treturn context.querySelectorAll( tag );\n\t\t\t}\n\t\t} :\n\n\t\tfunction( tag, context ) {\n\t\t\tvar elem,\n\t\t\t\ttmp = [],\n\t\t\t\ti = 0,\n\t\t\t\t// By happy coincidence, a (broken) gEBTN appears on DocumentFragment nodes too\n\t\t\t\tresults = context.getElementsByTagName( tag );\n\n\t\t\t// Filter out possible comments\n\t\t\tif ( tag === \"*\" ) {\n\t\t\t\twhile ( (elem = results[i++]) ) {\n\t\t\t\t\tif ( elem.nodeType === 1 ) {\n\t\t\t\t\t\ttmp.push( elem );\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\treturn tmp;\n\t\t\t}\n\t\t\treturn results;\n\t\t};\n\n\t// Class\n\tExpr.find[\"CLASS\"] = support.getElementsByClassName && function( className, context ) {\n\t\tif ( documentIsHTML ) {\n\t\t\treturn context.getElementsByClassName( className );\n\t\t}\n\t};\n\n\t/* QSA/matchesSelector\n\t---------------------------------------------------------------------- */\n\n\t// QSA and matchesSelector support\n\n\t// matchesSelector(:active) reports false when true (IE9/Opera 11.5)\n\trbuggyMatches = [];\n\n\t// qSa(:focus) reports false when true (Chrome 21)\n\t// We allow this because of a bug in IE8/9 that throws an error\n\t// whenever `document.activeElement` is accessed on an iframe\n\t// So, we allow :focus to pass through QSA all the time to avoid the IE error\n\t// See http://bugs.jquery.com/ticket/13378\n\trbuggyQSA = [];\n\n\tif ( (support.qsa = rnative.test( doc.querySelectorAll )) ) {\n\t\t// Build QSA regex\n\t\t// Regex strategy adopted from Diego Perini\n\t\tassert(function( div ) {\n\t\t\t// Select is set to empty string on purpose\n\t\t\t// This is to test IE's treatment of not explicitly\n\t\t\t// setting a boolean content attribute,\n\t\t\t// since its presence should be enough\n\t\t\t// http://bugs.jquery.com/ticket/12359\n\t\t\tdocElem.appendChild( div ).innerHTML = \"<a id='\" + expando + \"'></a>\" +\n\t\t\t\t\"<select id='\" + expando + \"-\\f]' msallowcapture=''>\" +\n\t\t\t\t\"<option selected=''></option></select>\";\n\n\t\t\t// Support: IE8, Opera 11-12.16\n\t\t\t// Nothing should be selected when empty strings follow ^= or $= or *=\n\t\t\t// The test attribute must be unknown in Opera but \"safe\" for WinRT\n\t\t\t// http://msdn.microsoft.com/en-us/library/ie/hh465388.aspx#attribute_section\n\t\t\tif ( div.querySelectorAll(\"[msallowcapture^='']\").length ) {\n\t\t\t\trbuggyQSA.push( \"[*^$]=\" + whitespace + \"*(?:''|\\\"\\\")\" );\n\t\t\t}\n\n\t\t\t// Support: IE8\n\t\t\t// Boolean attributes and \"value\" are not treated correctly\n\t\t\tif ( !div.querySelectorAll(\"[selected]\").length ) {\n\t\t\t\trbuggyQSA.push( \"\\\\[\" + whitespace + \"*(?:value|\" + booleans + \")\" );\n\t\t\t}\n\n\t\t\t// Support: Chrome<29, Android<4.2+, Safari<7.0+, iOS<7.0+, PhantomJS<1.9.7+\n\t\t\tif ( !div.querySelectorAll( \"[id~=\" + expando + \"-]\" ).length ) {\n\t\t\t\trbuggyQSA.push(\"~=\");\n\t\t\t}\n\n\t\t\t// Webkit/Opera - :checked should return selected option elements\n\t\t\t// http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked\n\t\t\t// IE8 throws error here and will not see later tests\n\t\t\tif ( !div.querySelectorAll(\":checked\").length ) {\n\t\t\t\trbuggyQSA.push(\":checked\");\n\t\t\t}\n\n\t\t\t// Support: Safari 8+, iOS 8+\n\t\t\t// https://bugs.webkit.org/show_bug.cgi?id=136851\n\t\t\t// In-page `selector#id sibing-combinator selector` fails\n\t\t\tif ( !div.querySelectorAll( \"a#\" + expando + \"+*\" ).length ) {\n\t\t\t\trbuggyQSA.push(\".#.+[+~]\");\n\t\t\t}\n\t\t});\n\n\t\tassert(function( div ) {\n\t\t\t// Support: Windows 8 Native Apps\n\t\t\t// The type and name attributes are restricted during .innerHTML assignment\n\t\t\tvar input = doc.createElement(\"input\");\n\t\t\tinput.setAttribute( \"type\", \"hidden\" );\n\t\t\tdiv.appendChild( input ).setAttribute( \"name\", \"D\" );\n\n\t\t\t// Support: IE8\n\t\t\t// Enforce case-sensitivity of name attribute\n\t\t\tif ( div.querySelectorAll(\"[name=d]\").length ) {\n\t\t\t\trbuggyQSA.push( \"name\" + whitespace + \"*[*^$|!~]?=\" );\n\t\t\t}\n\n\t\t\t// FF 3.5 - :enabled/:disabled and hidden elements (hidden elements are still enabled)\n\t\t\t// IE8 throws error here and will not see later tests\n\t\t\tif ( !div.querySelectorAll(\":enabled\").length ) {\n\t\t\t\trbuggyQSA.push( \":enabled\", \":disabled\" );\n\t\t\t}\n\n\t\t\t// Opera 10-11 does not throw on post-comma invalid pseudos\n\t\t\tdiv.querySelectorAll(\"*,:x\");\n\t\t\trbuggyQSA.push(\",.*:\");\n\t\t});\n\t}\n\n\tif ( (support.matchesSelector = rnative.test( (matches = docElem.matches ||\n\t\tdocElem.webkitMatchesSelector ||\n\t\tdocElem.mozMatchesSelector ||\n\t\tdocElem.oMatchesSelector ||\n\t\tdocElem.msMatchesSelector) )) ) {\n\n\t\tassert(function( div ) {\n\t\t\t// Check to see if it's possible to do matchesSelector\n\t\t\t// on a disconnected node (IE 9)\n\t\t\tsupport.disconnectedMatch = matches.call( div, \"div\" );\n\n\t\t\t// This should fail with an exception\n\t\t\t// Gecko does not error, returns false instead\n\t\t\tmatches.call( div, \"[s!='']:x\" );\n\t\t\trbuggyMatches.push( \"!=\", pseudos );\n\t\t});\n\t}\n\n\trbuggyQSA = rbuggyQSA.length && new RegExp( rbuggyQSA.join(\"|\") );\n\trbuggyMatches = rbuggyMatches.length && new RegExp( rbuggyMatches.join(\"|\") );\n\n\t/* Contains\n\t---------------------------------------------------------------------- */\n\thasCompare = rnative.test( docElem.compareDocumentPosition );\n\n\t// Element contains another\n\t// Purposefully does not implement inclusive descendent\n\t// As in, an element does not contain itself\n\tcontains = hasCompare || rnative.test( docElem.contains ) ?\n\t\tfunction( a, b ) {\n\t\t\tvar adown = a.nodeType === 9 ? a.documentElement : a,\n\t\t\t\tbup = b && b.parentNode;\n\t\t\treturn a === bup || !!( bup && bup.nodeType === 1 && (\n\t\t\t\tadown.contains ?\n\t\t\t\t\tadown.contains( bup ) :\n\t\t\t\t\ta.compareDocumentPosition && a.compareDocumentPosition( bup ) & 16\n\t\t\t));\n\t\t} :\n\t\tfunction( a, b ) {\n\t\t\tif ( b ) {\n\t\t\t\twhile ( (b = b.parentNode) ) {\n\t\t\t\t\tif ( b === a ) {\n\t\t\t\t\t\treturn true;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn false;\n\t\t};\n\n\t/* Sorting\n\t---------------------------------------------------------------------- */\n\n\t// Document order sorting\n\tsortOrder = hasCompare ?\n\tfunction( a, b ) {\n\n\t\t// Flag for duplicate removal\n\t\tif ( a === b ) {\n\t\t\thasDuplicate = true;\n\t\t\treturn 0;\n\t\t}\n\n\t\t// Sort on method existence if only one input has compareDocumentPosition\n\t\tvar compare = !a.compareDocumentPosition - !b.compareDocumentPosition;\n\t\tif ( compare ) {\n\t\t\treturn compare;\n\t\t}\n\n\t\t// Calculate position if both inputs belong to the same document\n\t\tcompare = ( a.ownerDocument || a ) === ( b.ownerDocument || b ) ?\n\t\t\ta.compareDocumentPosition( b ) :\n\n\t\t\t// Otherwise we know they are disconnected\n\t\t\t1;\n\n\t\t// Disconnected nodes\n\t\tif ( compare & 1 ||\n\t\t\t(!support.sortDetached && b.compareDocumentPosition( a ) === compare) ) {\n\n\t\t\t// Choose the first element that is related to our preferred document\n\t\t\tif ( a === doc || a.ownerDocument === preferredDoc && contains(preferredDoc, a) ) {\n\t\t\t\treturn -1;\n\t\t\t}\n\t\t\tif ( b === doc || b.ownerDocument === preferredDoc && contains(preferredDoc, b) ) {\n\t\t\t\treturn 1;\n\t\t\t}\n\n\t\t\t// Maintain original order\n\t\t\treturn sortInput ?\n\t\t\t\t( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) :\n\t\t\t\t0;\n\t\t}\n\n\t\treturn compare & 4 ? -1 : 1;\n\t} :\n\tfunction( a, b ) {\n\t\t// Exit early if the nodes are identical\n\t\tif ( a === b ) {\n\t\t\thasDuplicate = true;\n\t\t\treturn 0;\n\t\t}\n\n\t\tvar cur,\n\t\t\ti = 0,\n\t\t\taup = a.parentNode,\n\t\t\tbup = b.parentNode,\n\t\t\tap = [ a ],\n\t\t\tbp = [ b ];\n\n\t\t// Parentless nodes are either documents or disconnected\n\t\tif ( !aup || !bup ) {\n\t\t\treturn a === doc ? -1 :\n\t\t\t\tb === doc ? 1 :\n\t\t\t\taup ? -1 :\n\t\t\t\tbup ? 1 :\n\t\t\t\tsortInput ?\n\t\t\t\t( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) :\n\t\t\t\t0;\n\n\t\t// If the nodes are siblings, we can do a quick check\n\t\t} else if ( aup === bup ) {\n\t\t\treturn siblingCheck( a, b );\n\t\t}\n\n\t\t// Otherwise we need full lists of their ancestors for comparison\n\t\tcur = a;\n\t\twhile ( (cur = cur.parentNode) ) {\n\t\t\tap.unshift( cur );\n\t\t}\n\t\tcur = b;\n\t\twhile ( (cur = cur.parentNode) ) {\n\t\t\tbp.unshift( cur );\n\t\t}\n\n\t\t// Walk down the tree looking for a discrepancy\n\t\twhile ( ap[i] === bp[i] ) {\n\t\t\ti++;\n\t\t}\n\n\t\treturn i ?\n\t\t\t// Do a sibling check if the nodes have a common ancestor\n\t\t\tsiblingCheck( ap[i], bp[i] ) :\n\n\t\t\t// Otherwise nodes in our document sort first\n\t\t\tap[i] === preferredDoc ? -1 :\n\t\t\tbp[i] === preferredDoc ? 1 :\n\t\t\t0;\n\t};\n\n\treturn doc;\n};\n\nSizzle.matches = function( expr, elements ) {\n\treturn Sizzle( expr, null, null, elements );\n};\n\nSizzle.matchesSelector = function( elem, expr ) {\n\t// Set document vars if needed\n\tif ( ( elem.ownerDocument || elem ) !== document ) {\n\t\tsetDocument( elem );\n\t}\n\n\t// Make sure that attribute selectors are quoted\n\texpr = expr.replace( rattributeQuotes, \"='$1']\" );\n\n\tif ( support.matchesSelector && documentIsHTML &&\n\t\t( !rbuggyMatches || !rbuggyMatches.test( expr ) ) &&\n\t\t( !rbuggyQSA     || !rbuggyQSA.test( expr ) ) ) {\n\n\t\ttry {\n\t\t\tvar ret = matches.call( elem, expr );\n\n\t\t\t// IE 9's matchesSelector returns false on disconnected nodes\n\t\t\tif ( ret || support.disconnectedMatch ||\n\t\t\t\t\t// As well, disconnected nodes are said to be in a document\n\t\t\t\t\t// fragment in IE 9\n\t\t\t\t\telem.document && elem.document.nodeType !== 11 ) {\n\t\t\t\treturn ret;\n\t\t\t}\n\t\t} catch (e) {}\n\t}\n\n\treturn Sizzle( expr, document, null, [ elem ] ).length > 0;\n};\n\nSizzle.contains = function( context, elem ) {\n\t// Set document vars if needed\n\tif ( ( context.ownerDocument || context ) !== document ) {\n\t\tsetDocument( context );\n\t}\n\treturn contains( context, elem );\n};\n\nSizzle.attr = function( elem, name ) {\n\t// Set document vars if needed\n\tif ( ( elem.ownerDocument || elem ) !== document ) {\n\t\tsetDocument( elem );\n\t}\n\n\tvar fn = Expr.attrHandle[ name.toLowerCase() ],\n\t\t// Don't get fooled by Object.prototype properties (jQuery #13807)\n\t\tval = fn && hasOwn.call( Expr.attrHandle, name.toLowerCase() ) ?\n\t\t\tfn( elem, name, !documentIsHTML ) :\n\t\t\tundefined;\n\n\treturn val !== undefined ?\n\t\tval :\n\t\tsupport.attributes || !documentIsHTML ?\n\t\t\telem.getAttribute( name ) :\n\t\t\t(val = elem.getAttributeNode(name)) && val.specified ?\n\t\t\t\tval.value :\n\t\t\t\tnull;\n};\n\nSizzle.error = function( msg ) {\n\tthrow new Error( \"Syntax error, unrecognized expression: \" + msg );\n};\n\n/**\n * Document sorting and removing duplicates\n * @param {ArrayLike} results\n */\nSizzle.uniqueSort = function( results ) {\n\tvar elem,\n\t\tduplicates = [],\n\t\tj = 0,\n\t\ti = 0;\n\n\t// Unless we *know* we can detect duplicates, assume their presence\n\thasDuplicate = !support.detectDuplicates;\n\tsortInput = !support.sortStable && results.slice( 0 );\n\tresults.sort( sortOrder );\n\n\tif ( hasDuplicate ) {\n\t\twhile ( (elem = results[i++]) ) {\n\t\t\tif ( elem === results[ i ] ) {\n\t\t\t\tj = duplicates.push( i );\n\t\t\t}\n\t\t}\n\t\twhile ( j-- ) {\n\t\t\tresults.splice( duplicates[ j ], 1 );\n\t\t}\n\t}\n\n\t// Clear input after sorting to release objects\n\t// See https://github.com/jquery/sizzle/pull/225\n\tsortInput = null;\n\n\treturn results;\n};\n\n/**\n * Utility function for retrieving the text value of an array of DOM nodes\n * @param {Array|Element} elem\n */\ngetText = Sizzle.getText = function( elem ) {\n\tvar node,\n\t\tret = \"\",\n\t\ti = 0,\n\t\tnodeType = elem.nodeType;\n\n\tif ( !nodeType ) {\n\t\t// If no nodeType, this is expected to be an array\n\t\twhile ( (node = elem[i++]) ) {\n\t\t\t// Do not traverse comment nodes\n\t\t\tret += getText( node );\n\t\t}\n\t} else if ( nodeType === 1 || nodeType === 9 || nodeType === 11 ) {\n\t\t// Use textContent for elements\n\t\t// innerText usage removed for consistency of new lines (jQuery #11153)\n\t\tif ( typeof elem.textContent === \"string\" ) {\n\t\t\treturn elem.textContent;\n\t\t} else {\n\t\t\t// Traverse its children\n\t\t\tfor ( elem = elem.firstChild; elem; elem = elem.nextSibling ) {\n\t\t\t\tret += getText( elem );\n\t\t\t}\n\t\t}\n\t} else if ( nodeType === 3 || nodeType === 4 ) {\n\t\treturn elem.nodeValue;\n\t}\n\t// Do not include comment or processing instruction nodes\n\n\treturn ret;\n};\n\nExpr = Sizzle.selectors = {\n\n\t// Can be adjusted by the user\n\tcacheLength: 50,\n\n\tcreatePseudo: markFunction,\n\n\tmatch: matchExpr,\n\n\tattrHandle: {},\n\n\tfind: {},\n\n\trelative: {\n\t\t\">\": { dir: \"parentNode\", first: true },\n\t\t\" \": { dir: \"parentNode\" },\n\t\t\"+\": { dir: \"previousSibling\", first: true },\n\t\t\"~\": { dir: \"previousSibling\" }\n\t},\n\n\tpreFilter: {\n\t\t\"ATTR\": function( match ) {\n\t\t\tmatch[1] = match[1].replace( runescape, funescape );\n\n\t\t\t// Move the given value to match[3] whether quoted or unquoted\n\t\t\tmatch[3] = ( match[3] || match[4] || match[5] || \"\" ).replace( runescape, funescape );\n\n\t\t\tif ( match[2] === \"~=\" ) {\n\t\t\t\tmatch[3] = \" \" + match[3] + \" \";\n\t\t\t}\n\n\t\t\treturn match.slice( 0, 4 );\n\t\t},\n\n\t\t\"CHILD\": function( match ) {\n\t\t\t/* matches from matchExpr[\"CHILD\"]\n\t\t\t\t1 type (only|nth|...)\n\t\t\t\t2 what (child|of-type)\n\t\t\t\t3 argument (even|odd|\\d*|\\d*n([+-]\\d+)?|...)\n\t\t\t\t4 xn-component of xn+y argument ([+-]?\\d*n|)\n\t\t\t\t5 sign of xn-component\n\t\t\t\t6 x of xn-component\n\t\t\t\t7 sign of y-component\n\t\t\t\t8 y of y-component\n\t\t\t*/\n\t\t\tmatch[1] = match[1].toLowerCase();\n\n\t\t\tif ( match[1].slice( 0, 3 ) === \"nth\" ) {\n\t\t\t\t// nth-* requires argument\n\t\t\t\tif ( !match[3] ) {\n\t\t\t\t\tSizzle.error( match[0] );\n\t\t\t\t}\n\n\t\t\t\t// numeric x and y parameters for Expr.filter.CHILD\n\t\t\t\t// remember that false/true cast respectively to 0/1\n\t\t\t\tmatch[4] = +( match[4] ? match[5] + (match[6] || 1) : 2 * ( match[3] === \"even\" || match[3] === \"odd\" ) );\n\t\t\t\tmatch[5] = +( ( match[7] + match[8] ) || match[3] === \"odd\" );\n\n\t\t\t// other types prohibit arguments\n\t\t\t} else if ( match[3] ) {\n\t\t\t\tSizzle.error( match[0] );\n\t\t\t}\n\n\t\t\treturn match;\n\t\t},\n\n\t\t\"PSEUDO\": function( match ) {\n\t\t\tvar excess,\n\t\t\t\tunquoted = !match[6] && match[2];\n\n\t\t\tif ( matchExpr[\"CHILD\"].test( match[0] ) ) {\n\t\t\t\treturn null;\n\t\t\t}\n\n\t\t\t// Accept quoted arguments as-is\n\t\t\tif ( match[3] ) {\n\t\t\t\tmatch[2] = match[4] || match[5] || \"\";\n\n\t\t\t// Strip excess characters from unquoted arguments\n\t\t\t} else if ( unquoted && rpseudo.test( unquoted ) &&\n\t\t\t\t// Get excess from tokenize (recursively)\n\t\t\t\t(excess = tokenize( unquoted, true )) &&\n\t\t\t\t// advance to the next closing parenthesis\n\t\t\t\t(excess = unquoted.indexOf( \")\", unquoted.length - excess ) - unquoted.length) ) {\n\n\t\t\t\t// excess is a negative index\n\t\t\t\tmatch[0] = match[0].slice( 0, excess );\n\t\t\t\tmatch[2] = unquoted.slice( 0, excess );\n\t\t\t}\n\n\t\t\t// Return only captures needed by the pseudo filter method (type and argument)\n\t\t\treturn match.slice( 0, 3 );\n\t\t}\n\t},\n\n\tfilter: {\n\n\t\t\"TAG\": function( nodeNameSelector ) {\n\t\t\tvar nodeName = nodeNameSelector.replace( runescape, funescape ).toLowerCase();\n\t\t\treturn nodeNameSelector === \"*\" ?\n\t\t\t\tfunction() { return true; } :\n\t\t\t\tfunction( elem ) {\n\t\t\t\t\treturn elem.nodeName && elem.nodeName.toLowerCase() === nodeName;\n\t\t\t\t};\n\t\t},\n\n\t\t\"CLASS\": function( className ) {\n\t\t\tvar pattern = classCache[ className + \" \" ];\n\n\t\t\treturn pattern ||\n\t\t\t\t(pattern = new RegExp( \"(^|\" + whitespace + \")\" + className + \"(\" + whitespace + \"|$)\" )) &&\n\t\t\t\tclassCache( className, function( elem ) {\n\t\t\t\t\treturn pattern.test( typeof elem.className === \"string\" && elem.className || typeof elem.getAttribute !== \"undefined\" && elem.getAttribute(\"class\") || \"\" );\n\t\t\t\t});\n\t\t},\n\n\t\t\"ATTR\": function( name, operator, check ) {\n\t\t\treturn function( elem ) {\n\t\t\t\tvar result = Sizzle.attr( elem, name );\n\n\t\t\t\tif ( result == null ) {\n\t\t\t\t\treturn operator === \"!=\";\n\t\t\t\t}\n\t\t\t\tif ( !operator ) {\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\n\t\t\t\tresult += \"\";\n\n\t\t\t\treturn operator === \"=\" ? result === check :\n\t\t\t\t\toperator === \"!=\" ? result !== check :\n\t\t\t\t\toperator === \"^=\" ? check && result.indexOf( check ) === 0 :\n\t\t\t\t\toperator === \"*=\" ? check && result.indexOf( check ) > -1 :\n\t\t\t\t\toperator === \"$=\" ? check && result.slice( -check.length ) === check :\n\t\t\t\t\toperator === \"~=\" ? ( \" \" + result.replace( rwhitespace, \" \" ) + \" \" ).indexOf( check ) > -1 :\n\t\t\t\t\toperator === \"|=\" ? result === check || result.slice( 0, check.length + 1 ) === check + \"-\" :\n\t\t\t\t\tfalse;\n\t\t\t};\n\t\t},\n\n\t\t\"CHILD\": function( type, what, argument, first, last ) {\n\t\t\tvar simple = type.slice( 0, 3 ) !== \"nth\",\n\t\t\t\tforward = type.slice( -4 ) !== \"last\",\n\t\t\t\tofType = what === \"of-type\";\n\n\t\t\treturn first === 1 && last === 0 ?\n\n\t\t\t\t// Shortcut for :nth-*(n)\n\t\t\t\tfunction( elem ) {\n\t\t\t\t\treturn !!elem.parentNode;\n\t\t\t\t} :\n\n\t\t\t\tfunction( elem, context, xml ) {\n\t\t\t\t\tvar cache, outerCache, node, diff, nodeIndex, start,\n\t\t\t\t\t\tdir = simple !== forward ? \"nextSibling\" : \"previousSibling\",\n\t\t\t\t\t\tparent = elem.parentNode,\n\t\t\t\t\t\tname = ofType && elem.nodeName.toLowerCase(),\n\t\t\t\t\t\tuseCache = !xml && !ofType;\n\n\t\t\t\t\tif ( parent ) {\n\n\t\t\t\t\t\t// :(first|last|only)-(child|of-type)\n\t\t\t\t\t\tif ( simple ) {\n\t\t\t\t\t\t\twhile ( dir ) {\n\t\t\t\t\t\t\t\tnode = elem;\n\t\t\t\t\t\t\t\twhile ( (node = node[ dir ]) ) {\n\t\t\t\t\t\t\t\t\tif ( ofType ? node.nodeName.toLowerCase() === name : node.nodeType === 1 ) {\n\t\t\t\t\t\t\t\t\t\treturn false;\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t// Reverse direction for :only-* (if we haven't yet done so)\n\t\t\t\t\t\t\t\tstart = dir = type === \"only\" && !start && \"nextSibling\";\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\treturn true;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tstart = [ forward ? parent.firstChild : parent.lastChild ];\n\n\t\t\t\t\t\t// non-xml :nth-child(...) stores cache data on `parent`\n\t\t\t\t\t\tif ( forward && useCache ) {\n\t\t\t\t\t\t\t// Seek `elem` from a previously-cached index\n\t\t\t\t\t\t\touterCache = parent[ expando ] || (parent[ expando ] = {});\n\t\t\t\t\t\t\tcache = outerCache[ type ] || [];\n\t\t\t\t\t\t\tnodeIndex = cache[0] === dirruns && cache[1];\n\t\t\t\t\t\t\tdiff = cache[0] === dirruns && cache[2];\n\t\t\t\t\t\t\tnode = nodeIndex && parent.childNodes[ nodeIndex ];\n\n\t\t\t\t\t\t\twhile ( (node = ++nodeIndex && node && node[ dir ] ||\n\n\t\t\t\t\t\t\t\t// Fallback to seeking `elem` from the start\n\t\t\t\t\t\t\t\t(diff = nodeIndex = 0) || start.pop()) ) {\n\n\t\t\t\t\t\t\t\t// When found, cache indexes on `parent` and break\n\t\t\t\t\t\t\t\tif ( node.nodeType === 1 && ++diff && node === elem ) {\n\t\t\t\t\t\t\t\t\touterCache[ type ] = [ dirruns, nodeIndex, diff ];\n\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// Use previously-cached element index if available\n\t\t\t\t\t\t} else if ( useCache && (cache = (elem[ expando ] || (elem[ expando ] = {}))[ type ]) && cache[0] === dirruns ) {\n\t\t\t\t\t\t\tdiff = cache[1];\n\n\t\t\t\t\t\t// xml :nth-child(...) or :nth-last-child(...) or :nth(-last)?-of-type(...)\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t// Use the same loop as above to seek `elem` from the start\n\t\t\t\t\t\t\twhile ( (node = ++nodeIndex && node && node[ dir ] ||\n\t\t\t\t\t\t\t\t(diff = nodeIndex = 0) || start.pop()) ) {\n\n\t\t\t\t\t\t\t\tif ( ( ofType ? node.nodeName.toLowerCase() === name : node.nodeType === 1 ) && ++diff ) {\n\t\t\t\t\t\t\t\t\t// Cache the index of each encountered element\n\t\t\t\t\t\t\t\t\tif ( useCache ) {\n\t\t\t\t\t\t\t\t\t\t(node[ expando ] || (node[ expando ] = {}))[ type ] = [ dirruns, diff ];\n\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t\tif ( node === elem ) {\n\t\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// Incorporate the offset, then check against cycle size\n\t\t\t\t\t\tdiff -= last;\n\t\t\t\t\t\treturn diff === first || ( diff % first === 0 && diff / first >= 0 );\n\t\t\t\t\t}\n\t\t\t\t};\n\t\t},\n\n\t\t\"PSEUDO\": function( pseudo, argument ) {\n\t\t\t// pseudo-class names are case-insensitive\n\t\t\t// http://www.w3.org/TR/selectors/#pseudo-classes\n\t\t\t// Prioritize by case sensitivity in case custom pseudos are added with uppercase letters\n\t\t\t// Remember that setFilters inherits from pseudos\n\t\t\tvar args,\n\t\t\t\tfn = Expr.pseudos[ pseudo ] || Expr.setFilters[ pseudo.toLowerCase() ] ||\n\t\t\t\t\tSizzle.error( \"unsupported pseudo: \" + pseudo );\n\n\t\t\t// The user may use createPseudo to indicate that\n\t\t\t// arguments are needed to create the filter function\n\t\t\t// just as Sizzle does\n\t\t\tif ( fn[ expando ] ) {\n\t\t\t\treturn fn( argument );\n\t\t\t}\n\n\t\t\t// But maintain support for old signatures\n\t\t\tif ( fn.length > 1 ) {\n\t\t\t\targs = [ pseudo, pseudo, \"\", argument ];\n\t\t\t\treturn Expr.setFilters.hasOwnProperty( pseudo.toLowerCase() ) ?\n\t\t\t\t\tmarkFunction(function( seed, matches ) {\n\t\t\t\t\t\tvar idx,\n\t\t\t\t\t\t\tmatched = fn( seed, argument ),\n\t\t\t\t\t\t\ti = matched.length;\n\t\t\t\t\t\twhile ( i-- ) {\n\t\t\t\t\t\t\tidx = indexOf( seed, matched[i] );\n\t\t\t\t\t\t\tseed[ idx ] = !( matches[ idx ] = matched[i] );\n\t\t\t\t\t\t}\n\t\t\t\t\t}) :\n\t\t\t\t\tfunction( elem ) {\n\t\t\t\t\t\treturn fn( elem, 0, args );\n\t\t\t\t\t};\n\t\t\t}\n\n\t\t\treturn fn;\n\t\t}\n\t},\n\n\tpseudos: {\n\t\t// Potentially complex pseudos\n\t\t\"not\": markFunction(function( selector ) {\n\t\t\t// Trim the selector passed to compile\n\t\t\t// to avoid treating leading and trailing\n\t\t\t// spaces as combinators\n\t\t\tvar input = [],\n\t\t\t\tresults = [],\n\t\t\t\tmatcher = compile( selector.replace( rtrim, \"$1\" ) );\n\n\t\t\treturn matcher[ expando ] ?\n\t\t\t\tmarkFunction(function( seed, matches, context, xml ) {\n\t\t\t\t\tvar elem,\n\t\t\t\t\t\tunmatched = matcher( seed, null, xml, [] ),\n\t\t\t\t\t\ti = seed.length;\n\n\t\t\t\t\t// Match elements unmatched by `matcher`\n\t\t\t\t\twhile ( i-- ) {\n\t\t\t\t\t\tif ( (elem = unmatched[i]) ) {\n\t\t\t\t\t\t\tseed[i] = !(matches[i] = elem);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}) :\n\t\t\t\tfunction( elem, context, xml ) {\n\t\t\t\t\tinput[0] = elem;\n\t\t\t\t\tmatcher( input, null, xml, results );\n\t\t\t\t\t// Don't keep the element (issue #299)\n\t\t\t\t\tinput[0] = null;\n\t\t\t\t\treturn !results.pop();\n\t\t\t\t};\n\t\t}),\n\n\t\t\"has\": markFunction(function( selector ) {\n\t\t\treturn function( elem ) {\n\t\t\t\treturn Sizzle( selector, elem ).length > 0;\n\t\t\t};\n\t\t}),\n\n\t\t\"contains\": markFunction(function( text ) {\n\t\t\ttext = text.replace( runescape, funescape );\n\t\t\treturn function( elem ) {\n\t\t\t\treturn ( elem.textContent || elem.innerText || getText( elem ) ).indexOf( text ) > -1;\n\t\t\t};\n\t\t}),\n\n\t\t// \"Whether an element is represented by a :lang() selector\n\t\t// is based solely on the element's language value\n\t\t// being equal to the identifier C,\n\t\t// or beginning with the identifier C immediately followed by \"-\".\n\t\t// The matching of C against the element's language value is performed case-insensitively.\n\t\t// The identifier C does not have to be a valid language name.\"\n\t\t// http://www.w3.org/TR/selectors/#lang-pseudo\n\t\t\"lang\": markFunction( function( lang ) {\n\t\t\t// lang value must be a valid identifier\n\t\t\tif ( !ridentifier.test(lang || \"\") ) {\n\t\t\t\tSizzle.error( \"unsupported lang: \" + lang );\n\t\t\t}\n\t\t\tlang = lang.replace( runescape, funescape ).toLowerCase();\n\t\t\treturn function( elem ) {\n\t\t\t\tvar elemLang;\n\t\t\t\tdo {\n\t\t\t\t\tif ( (elemLang = documentIsHTML ?\n\t\t\t\t\t\telem.lang :\n\t\t\t\t\t\telem.getAttribute(\"xml:lang\") || elem.getAttribute(\"lang\")) ) {\n\n\t\t\t\t\t\telemLang = elemLang.toLowerCase();\n\t\t\t\t\t\treturn elemLang === lang || elemLang.indexOf( lang + \"-\" ) === 0;\n\t\t\t\t\t}\n\t\t\t\t} while ( (elem = elem.parentNode) && elem.nodeType === 1 );\n\t\t\t\treturn false;\n\t\t\t};\n\t\t}),\n\n\t\t// Miscellaneous\n\t\t\"target\": function( elem ) {\n\t\t\tvar hash = window.location && window.location.hash;\n\t\t\treturn hash && hash.slice( 1 ) === elem.id;\n\t\t},\n\n\t\t\"root\": function( elem ) {\n\t\t\treturn elem === docElem;\n\t\t},\n\n\t\t\"focus\": function( elem ) {\n\t\t\treturn elem === document.activeElement && (!document.hasFocus || document.hasFocus()) && !!(elem.type || elem.href || ~elem.tabIndex);\n\t\t},\n\n\t\t// Boolean properties\n\t\t\"enabled\": function( elem ) {\n\t\t\treturn elem.disabled === false;\n\t\t},\n\n\t\t\"disabled\": function( elem ) {\n\t\t\treturn elem.disabled === true;\n\t\t},\n\n\t\t\"checked\": function( elem ) {\n\t\t\t// In CSS3, :checked should return both checked and selected elements\n\t\t\t// http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked\n\t\t\tvar nodeName = elem.nodeName.toLowerCase();\n\t\t\treturn (nodeName === \"input\" && !!elem.checked) || (nodeName === \"option\" && !!elem.selected);\n\t\t},\n\n\t\t\"selected\": function( elem ) {\n\t\t\t// Accessing this property makes selected-by-default\n\t\t\t// options in Safari work properly\n\t\t\tif ( elem.parentNode ) {\n\t\t\t\telem.parentNode.selectedIndex;\n\t\t\t}\n\n\t\t\treturn elem.selected === true;\n\t\t},\n\n\t\t// Contents\n\t\t\"empty\": function( elem ) {\n\t\t\t// http://www.w3.org/TR/selectors/#empty-pseudo\n\t\t\t// :empty is negated by element (1) or content nodes (text: 3; cdata: 4; entity ref: 5),\n\t\t\t//   but not by others (comment: 8; processing instruction: 7; etc.)\n\t\t\t// nodeType < 6 works because attributes (2) do not appear as children\n\t\t\tfor ( elem = elem.firstChild; elem; elem = elem.nextSibling ) {\n\t\t\t\tif ( elem.nodeType < 6 ) {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn true;\n\t\t},\n\n\t\t\"parent\": function( elem ) {\n\t\t\treturn !Expr.pseudos[\"empty\"]( elem );\n\t\t},\n\n\t\t// Element/input types\n\t\t\"header\": function( elem ) {\n\t\t\treturn rheader.test( elem.nodeName );\n\t\t},\n\n\t\t\"input\": function( elem ) {\n\t\t\treturn rinputs.test( elem.nodeName );\n\t\t},\n\n\t\t\"button\": function( elem ) {\n\t\t\tvar name = elem.nodeName.toLowerCase();\n\t\t\treturn name === \"input\" && elem.type === \"button\" || name === \"button\";\n\t\t},\n\n\t\t\"text\": function( elem ) {\n\t\t\tvar attr;\n\t\t\treturn elem.nodeName.toLowerCase() === \"input\" &&\n\t\t\t\telem.type === \"text\" &&\n\n\t\t\t\t// Support: IE<8\n\t\t\t\t// New HTML5 attribute values (e.g., \"search\") appear with elem.type === \"text\"\n\t\t\t\t( (attr = elem.getAttribute(\"type\")) == null || attr.toLowerCase() === \"text\" );\n\t\t},\n\n\t\t// Position-in-collection\n\t\t\"first\": createPositionalPseudo(function() {\n\t\t\treturn [ 0 ];\n\t\t}),\n\n\t\t\"last\": createPositionalPseudo(function( matchIndexes, length ) {\n\t\t\treturn [ length - 1 ];\n\t\t}),\n\n\t\t\"eq\": createPositionalPseudo(function( matchIndexes, length, argument ) {\n\t\t\treturn [ argument < 0 ? argument + length : argument ];\n\t\t}),\n\n\t\t\"even\": createPositionalPseudo(function( matchIndexes, length ) {\n\t\t\tvar i = 0;\n\t\t\tfor ( ; i < length; i += 2 ) {\n\t\t\t\tmatchIndexes.push( i );\n\t\t\t}\n\t\t\treturn matchIndexes;\n\t\t}),\n\n\t\t\"odd\": createPositionalPseudo(function( matchIndexes, length ) {\n\t\t\tvar i = 1;\n\t\t\tfor ( ; i < length; i += 2 ) {\n\t\t\t\tmatchIndexes.push( i );\n\t\t\t}\n\t\t\treturn matchIndexes;\n\t\t}),\n\n\t\t\"lt\": createPositionalPseudo(function( matchIndexes, length, argument ) {\n\t\t\tvar i = argument < 0 ? argument + length : argument;\n\t\t\tfor ( ; --i >= 0; ) {\n\t\t\t\tmatchIndexes.push( i );\n\t\t\t}\n\t\t\treturn matchIndexes;\n\t\t}),\n\n\t\t\"gt\": createPositionalPseudo(function( matchIndexes, length, argument ) {\n\t\t\tvar i = argument < 0 ? argument + length : argument;\n\t\t\tfor ( ; ++i < length; ) {\n\t\t\t\tmatchIndexes.push( i );\n\t\t\t}\n\t\t\treturn matchIndexes;\n\t\t})\n\t}\n};\n\nExpr.pseudos[\"nth\"] = Expr.pseudos[\"eq\"];\n\n// Add button/input type pseudos\nfor ( i in { radio: true, checkbox: true, file: true, password: true, image: true } ) {\n\tExpr.pseudos[ i ] = createInputPseudo( i );\n}\nfor ( i in { submit: true, reset: true } ) {\n\tExpr.pseudos[ i ] = createButtonPseudo( i );\n}\n\n// Easy API for creating new setFilters\nfunction setFilters() {}\nsetFilters.prototype = Expr.filters = Expr.pseudos;\nExpr.setFilters = new setFilters();\n\ntokenize = Sizzle.tokenize = function( selector, parseOnly ) {\n\tvar matched, match, tokens, type,\n\t\tsoFar, groups, preFilters,\n\t\tcached = tokenCache[ selector + \" \" ];\n\n\tif ( cached ) {\n\t\treturn parseOnly ? 0 : cached.slice( 0 );\n\t}\n\n\tsoFar = selector;\n\tgroups = [];\n\tpreFilters = Expr.preFilter;\n\n\twhile ( soFar ) {\n\n\t\t// Comma and first run\n\t\tif ( !matched || (match = rcomma.exec( soFar )) ) {\n\t\t\tif ( match ) {\n\t\t\t\t// Don't consume trailing commas as valid\n\t\t\t\tsoFar = soFar.slice( match[0].length ) || soFar;\n\t\t\t}\n\t\t\tgroups.push( (tokens = []) );\n\t\t}\n\n\t\tmatched = false;\n\n\t\t// Combinators\n\t\tif ( (match = rcombinators.exec( soFar )) ) {\n\t\t\tmatched = match.shift();\n\t\t\ttokens.push({\n\t\t\t\tvalue: matched,\n\t\t\t\t// Cast descendant combinators to space\n\t\t\t\ttype: match[0].replace( rtrim, \" \" )\n\t\t\t});\n\t\t\tsoFar = soFar.slice( matched.length );\n\t\t}\n\n\t\t// Filters\n\t\tfor ( type in Expr.filter ) {\n\t\t\tif ( (match = matchExpr[ type ].exec( soFar )) && (!preFilters[ type ] ||\n\t\t\t\t(match = preFilters[ type ]( match ))) ) {\n\t\t\t\tmatched = match.shift();\n\t\t\t\ttokens.push({\n\t\t\t\t\tvalue: matched,\n\t\t\t\t\ttype: type,\n\t\t\t\t\tmatches: match\n\t\t\t\t});\n\t\t\t\tsoFar = soFar.slice( matched.length );\n\t\t\t}\n\t\t}\n\n\t\tif ( !matched ) {\n\t\t\tbreak;\n\t\t}\n\t}\n\n\t// Return the length of the invalid excess\n\t// if we're just parsing\n\t// Otherwise, throw an error or return tokens\n\treturn parseOnly ?\n\t\tsoFar.length :\n\t\tsoFar ?\n\t\t\tSizzle.error( selector ) :\n\t\t\t// Cache the tokens\n\t\t\ttokenCache( selector, groups ).slice( 0 );\n};\n\nfunction toSelector( tokens ) {\n\tvar i = 0,\n\t\tlen = tokens.length,\n\t\tselector = \"\";\n\tfor ( ; i < len; i++ ) {\n\t\tselector += tokens[i].value;\n\t}\n\treturn selector;\n}\n\nfunction addCombinator( matcher, combinator, base ) {\n\tvar dir = combinator.dir,\n\t\tcheckNonElements = base && dir === \"parentNode\",\n\t\tdoneName = done++;\n\n\treturn combinator.first ?\n\t\t// Check against closest ancestor/preceding element\n\t\tfunction( elem, context, xml ) {\n\t\t\twhile ( (elem = elem[ dir ]) ) {\n\t\t\t\tif ( elem.nodeType === 1 || checkNonElements ) {\n\t\t\t\t\treturn matcher( elem, context, xml );\n\t\t\t\t}\n\t\t\t}\n\t\t} :\n\n\t\t// Check against all ancestor/preceding elements\n\t\tfunction( elem, context, xml ) {\n\t\t\tvar oldCache, outerCache,\n\t\t\t\tnewCache = [ dirruns, doneName ];\n\n\t\t\t// We can't set arbitrary data on XML nodes, so they don't benefit from dir caching\n\t\t\tif ( xml ) {\n\t\t\t\twhile ( (elem = elem[ dir ]) ) {\n\t\t\t\t\tif ( elem.nodeType === 1 || checkNonElements ) {\n\t\t\t\t\t\tif ( matcher( elem, context, xml ) ) {\n\t\t\t\t\t\t\treturn true;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\twhile ( (elem = elem[ dir ]) ) {\n\t\t\t\t\tif ( elem.nodeType === 1 || checkNonElements ) {\n\t\t\t\t\t\touterCache = elem[ expando ] || (elem[ expando ] = {});\n\t\t\t\t\t\tif ( (oldCache = outerCache[ dir ]) &&\n\t\t\t\t\t\t\toldCache[ 0 ] === dirruns && oldCache[ 1 ] === doneName ) {\n\n\t\t\t\t\t\t\t// Assign to newCache so results back-propagate to previous elements\n\t\t\t\t\t\t\treturn (newCache[ 2 ] = oldCache[ 2 ]);\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t// Reuse newcache so results back-propagate to previous elements\n\t\t\t\t\t\t\touterCache[ dir ] = newCache;\n\n\t\t\t\t\t\t\t// A match means we're done; a fail means we have to keep checking\n\t\t\t\t\t\t\tif ( (newCache[ 2 ] = matcher( elem, context, xml )) ) {\n\t\t\t\t\t\t\t\treturn true;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t};\n}\n\nfunction elementMatcher( matchers ) {\n\treturn matchers.length > 1 ?\n\t\tfunction( elem, context, xml ) {\n\t\t\tvar i = matchers.length;\n\t\t\twhile ( i-- ) {\n\t\t\t\tif ( !matchers[i]( elem, context, xml ) ) {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn true;\n\t\t} :\n\t\tmatchers[0];\n}\n\nfunction multipleContexts( selector, contexts, results ) {\n\tvar i = 0,\n\t\tlen = contexts.length;\n\tfor ( ; i < len; i++ ) {\n\t\tSizzle( selector, contexts[i], results );\n\t}\n\treturn results;\n}\n\nfunction condense( unmatched, map, filter, context, xml ) {\n\tvar elem,\n\t\tnewUnmatched = [],\n\t\ti = 0,\n\t\tlen = unmatched.length,\n\t\tmapped = map != null;\n\n\tfor ( ; i < len; i++ ) {\n\t\tif ( (elem = unmatched[i]) ) {\n\t\t\tif ( !filter || filter( elem, context, xml ) ) {\n\t\t\t\tnewUnmatched.push( elem );\n\t\t\t\tif ( mapped ) {\n\t\t\t\t\tmap.push( i );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\treturn newUnmatched;\n}\n\nfunction setMatcher( preFilter, selector, matcher, postFilter, postFinder, postSelector ) {\n\tif ( postFilter && !postFilter[ expando ] ) {\n\t\tpostFilter = setMatcher( postFilter );\n\t}\n\tif ( postFinder && !postFinder[ expando ] ) {\n\t\tpostFinder = setMatcher( postFinder, postSelector );\n\t}\n\treturn markFunction(function( seed, results, context, xml ) {\n\t\tvar temp, i, elem,\n\t\t\tpreMap = [],\n\t\t\tpostMap = [],\n\t\t\tpreexisting = results.length,\n\n\t\t\t// Get initial elements from seed or context\n\t\t\telems = seed || multipleContexts( selector || \"*\", context.nodeType ? [ context ] : context, [] ),\n\n\t\t\t// Prefilter to get matcher input, preserving a map for seed-results synchronization\n\t\t\tmatcherIn = preFilter && ( seed || !selector ) ?\n\t\t\t\tcondense( elems, preMap, preFilter, context, xml ) :\n\t\t\t\telems,\n\n\t\t\tmatcherOut = matcher ?\n\t\t\t\t// If we have a postFinder, or filtered seed, or non-seed postFilter or preexisting results,\n\t\t\t\tpostFinder || ( seed ? preFilter : preexisting || postFilter ) ?\n\n\t\t\t\t\t// ...intermediate processing is necessary\n\t\t\t\t\t[] :\n\n\t\t\t\t\t// ...otherwise use results directly\n\t\t\t\t\tresults :\n\t\t\t\tmatcherIn;\n\n\t\t// Find primary matches\n\t\tif ( matcher ) {\n\t\t\tmatcher( matcherIn, matcherOut, context, xml );\n\t\t}\n\n\t\t// Apply postFilter\n\t\tif ( postFilter ) {\n\t\t\ttemp = condense( matcherOut, postMap );\n\t\t\tpostFilter( temp, [], context, xml );\n\n\t\t\t// Un-match failing elements by moving them back to matcherIn\n\t\t\ti = temp.length;\n\t\t\twhile ( i-- ) {\n\t\t\t\tif ( (elem = temp[i]) ) {\n\t\t\t\t\tmatcherOut[ postMap[i] ] = !(matcherIn[ postMap[i] ] = elem);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif ( seed ) {\n\t\t\tif ( postFinder || preFilter ) {\n\t\t\t\tif ( postFinder ) {\n\t\t\t\t\t// Get the final matcherOut by condensing this intermediate into postFinder contexts\n\t\t\t\t\ttemp = [];\n\t\t\t\t\ti = matcherOut.length;\n\t\t\t\t\twhile ( i-- ) {\n\t\t\t\t\t\tif ( (elem = matcherOut[i]) ) {\n\t\t\t\t\t\t\t// Restore matcherIn since elem is not yet a final match\n\t\t\t\t\t\t\ttemp.push( (matcherIn[i] = elem) );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tpostFinder( null, (matcherOut = []), temp, xml );\n\t\t\t\t}\n\n\t\t\t\t// Move matched elements from seed to results to keep them synchronized\n\t\t\t\ti = matcherOut.length;\n\t\t\t\twhile ( i-- ) {\n\t\t\t\t\tif ( (elem = matcherOut[i]) &&\n\t\t\t\t\t\t(temp = postFinder ? indexOf( seed, elem ) : preMap[i]) > -1 ) {\n\n\t\t\t\t\t\tseed[temp] = !(results[temp] = elem);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t// Add elements to results, through postFinder if defined\n\t\t} else {\n\t\t\tmatcherOut = condense(\n\t\t\t\tmatcherOut === results ?\n\t\t\t\t\tmatcherOut.splice( preexisting, matcherOut.length ) :\n\t\t\t\t\tmatcherOut\n\t\t\t);\n\t\t\tif ( postFinder ) {\n\t\t\t\tpostFinder( null, results, matcherOut, xml );\n\t\t\t} else {\n\t\t\t\tpush.apply( results, matcherOut );\n\t\t\t}\n\t\t}\n\t});\n}\n\nfunction matcherFromTokens( tokens ) {\n\tvar checkContext, matcher, j,\n\t\tlen = tokens.length,\n\t\tleadingRelative = Expr.relative[ tokens[0].type ],\n\t\timplicitRelative = leadingRelative || Expr.relative[\" \"],\n\t\ti = leadingRelative ? 1 : 0,\n\n\t\t// The foundational matcher ensures that elements are reachable from top-level context(s)\n\t\tmatchContext = addCombinator( function( elem ) {\n\t\t\treturn elem === checkContext;\n\t\t}, implicitRelative, true ),\n\t\tmatchAnyContext = addCombinator( function( elem ) {\n\t\t\treturn indexOf( checkContext, elem ) > -1;\n\t\t}, implicitRelative, true ),\n\t\tmatchers = [ function( elem, context, xml ) {\n\t\t\tvar ret = ( !leadingRelative && ( xml || context !== outermostContext ) ) || (\n\t\t\t\t(checkContext = context).nodeType ?\n\t\t\t\t\tmatchContext( elem, context, xml ) :\n\t\t\t\t\tmatchAnyContext( elem, context, xml ) );\n\t\t\t// Avoid hanging onto element (issue #299)\n\t\t\tcheckContext = null;\n\t\t\treturn ret;\n\t\t} ];\n\n\tfor ( ; i < len; i++ ) {\n\t\tif ( (matcher = Expr.relative[ tokens[i].type ]) ) {\n\t\t\tmatchers = [ addCombinator(elementMatcher( matchers ), matcher) ];\n\t\t} else {\n\t\t\tmatcher = Expr.filter[ tokens[i].type ].apply( null, tokens[i].matches );\n\n\t\t\t// Return special upon seeing a positional matcher\n\t\t\tif ( matcher[ expando ] ) {\n\t\t\t\t// Find the next relative operator (if any) for proper handling\n\t\t\t\tj = ++i;\n\t\t\t\tfor ( ; j < len; j++ ) {\n\t\t\t\t\tif ( Expr.relative[ tokens[j].type ] ) {\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn setMatcher(\n\t\t\t\t\ti > 1 && elementMatcher( matchers ),\n\t\t\t\t\ti > 1 && toSelector(\n\t\t\t\t\t\t// If the preceding token was a descendant combinator, insert an implicit any-element `*`\n\t\t\t\t\t\ttokens.slice( 0, i - 1 ).concat({ value: tokens[ i - 2 ].type === \" \" ? \"*\" : \"\" })\n\t\t\t\t\t).replace( rtrim, \"$1\" ),\n\t\t\t\t\tmatcher,\n\t\t\t\t\ti < j && matcherFromTokens( tokens.slice( i, j ) ),\n\t\t\t\t\tj < len && matcherFromTokens( (tokens = tokens.slice( j )) ),\n\t\t\t\t\tj < len && toSelector( tokens )\n\t\t\t\t);\n\t\t\t}\n\t\t\tmatchers.push( matcher );\n\t\t}\n\t}\n\n\treturn elementMatcher( matchers );\n}\n\nfunction matcherFromGroupMatchers( elementMatchers, setMatchers ) {\n\tvar bySet = setMatchers.length > 0,\n\t\tbyElement = elementMatchers.length > 0,\n\t\tsuperMatcher = function( seed, context, xml, results, outermost ) {\n\t\t\tvar elem, j, matcher,\n\t\t\t\tmatchedCount = 0,\n\t\t\t\ti = \"0\",\n\t\t\t\tunmatched = seed && [],\n\t\t\t\tsetMatched = [],\n\t\t\t\tcontextBackup = outermostContext,\n\t\t\t\t// We must always have either seed elements or outermost context\n\t\t\t\telems = seed || byElement && Expr.find[\"TAG\"]( \"*\", outermost ),\n\t\t\t\t// Use integer dirruns iff this is the outermost matcher\n\t\t\t\tdirrunsUnique = (dirruns += contextBackup == null ? 1 : Math.random() || 0.1),\n\t\t\t\tlen = elems.length;\n\n\t\t\tif ( outermost ) {\n\t\t\t\toutermostContext = context !== document && context;\n\t\t\t}\n\n\t\t\t// Add elements passing elementMatchers directly to results\n\t\t\t// Keep `i` a string if there are no elements so `matchedCount` will be \"00\" below\n\t\t\t// Support: IE<9, Safari\n\t\t\t// Tolerate NodeList properties (IE: \"length\"; Safari: <number>) matching elements by id\n\t\t\tfor ( ; i !== len && (elem = elems[i]) != null; i++ ) {\n\t\t\t\tif ( byElement && elem ) {\n\t\t\t\t\tj = 0;\n\t\t\t\t\twhile ( (matcher = elementMatchers[j++]) ) {\n\t\t\t\t\t\tif ( matcher( elem, context, xml ) ) {\n\t\t\t\t\t\t\tresults.push( elem );\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tif ( outermost ) {\n\t\t\t\t\t\tdirruns = dirrunsUnique;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// Track unmatched elements for set filters\n\t\t\t\tif ( bySet ) {\n\t\t\t\t\t// They will have gone through all possible matchers\n\t\t\t\t\tif ( (elem = !matcher && elem) ) {\n\t\t\t\t\t\tmatchedCount--;\n\t\t\t\t\t}\n\n\t\t\t\t\t// Lengthen the array for every element, matched or not\n\t\t\t\t\tif ( seed ) {\n\t\t\t\t\t\tunmatched.push( elem );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Apply set filters to unmatched elements\n\t\t\tmatchedCount += i;\n\t\t\tif ( bySet && i !== matchedCount ) {\n\t\t\t\tj = 0;\n\t\t\t\twhile ( (matcher = setMatchers[j++]) ) {\n\t\t\t\t\tmatcher( unmatched, setMatched, context, xml );\n\t\t\t\t}\n\n\t\t\t\tif ( seed ) {\n\t\t\t\t\t// Reintegrate element matches to eliminate the need for sorting\n\t\t\t\t\tif ( matchedCount > 0 ) {\n\t\t\t\t\t\twhile ( i-- ) {\n\t\t\t\t\t\t\tif ( !(unmatched[i] || setMatched[i]) ) {\n\t\t\t\t\t\t\t\tsetMatched[i] = pop.call( results );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\t// Discard index placeholder values to get only actual matches\n\t\t\t\t\tsetMatched = condense( setMatched );\n\t\t\t\t}\n\n\t\t\t\t// Add matches to results\n\t\t\t\tpush.apply( results, setMatched );\n\n\t\t\t\t// Seedless set matches succeeding multiple successful matchers stipulate sorting\n\t\t\t\tif ( outermost && !seed && setMatched.length > 0 &&\n\t\t\t\t\t( matchedCount + setMatchers.length ) > 1 ) {\n\n\t\t\t\t\tSizzle.uniqueSort( results );\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Override manipulation of globals by nested matchers\n\t\t\tif ( outermost ) {\n\t\t\t\tdirruns = dirrunsUnique;\n\t\t\t\toutermostContext = contextBackup;\n\t\t\t}\n\n\t\t\treturn unmatched;\n\t\t};\n\n\treturn bySet ?\n\t\tmarkFunction( superMatcher ) :\n\t\tsuperMatcher;\n}\n\ncompile = Sizzle.compile = function( selector, match /* Internal Use Only */ ) {\n\tvar i,\n\t\tsetMatchers = [],\n\t\telementMatchers = [],\n\t\tcached = compilerCache[ selector + \" \" ];\n\n\tif ( !cached ) {\n\t\t// Generate a function of recursive functions that can be used to check each element\n\t\tif ( !match ) {\n\t\t\tmatch = tokenize( selector );\n\t\t}\n\t\ti = match.length;\n\t\twhile ( i-- ) {\n\t\t\tcached = matcherFromTokens( match[i] );\n\t\t\tif ( cached[ expando ] ) {\n\t\t\t\tsetMatchers.push( cached );\n\t\t\t} else {\n\t\t\t\telementMatchers.push( cached );\n\t\t\t}\n\t\t}\n\n\t\t// Cache the compiled function\n\t\tcached = compilerCache( selector, matcherFromGroupMatchers( elementMatchers, setMatchers ) );\n\n\t\t// Save selector and tokenization\n\t\tcached.selector = selector;\n\t}\n\treturn cached;\n};\n\n/**\n * A low-level selection function that works with Sizzle's compiled\n *  selector functions\n * @param {String|Function} selector A selector or a pre-compiled\n *  selector function built with Sizzle.compile\n * @param {Element} context\n * @param {Array} [results]\n * @param {Array} [seed] A set of elements to match against\n */\nselect = Sizzle.select = function( selector, context, results, seed ) {\n\tvar i, tokens, token, type, find,\n\t\tcompiled = typeof selector === \"function\" && selector,\n\t\tmatch = !seed && tokenize( (selector = compiled.selector || selector) );\n\n\tresults = results || [];\n\n\t// Try to minimize operations if there is no seed and only one group\n\tif ( match.length === 1 ) {\n\n\t\t// Take a shortcut and set the context if the root selector is an ID\n\t\ttokens = match[0] = match[0].slice( 0 );\n\t\tif ( tokens.length > 2 && (token = tokens[0]).type === \"ID\" &&\n\t\t\t\tsupport.getById && context.nodeType === 9 && documentIsHTML &&\n\t\t\t\tExpr.relative[ tokens[1].type ] ) {\n\n\t\t\tcontext = ( Expr.find[\"ID\"]( token.matches[0].replace(runescape, funescape), context ) || [] )[0];\n\t\t\tif ( !context ) {\n\t\t\t\treturn results;\n\n\t\t\t// Precompiled matchers will still verify ancestry, so step up a level\n\t\t\t} else if ( compiled ) {\n\t\t\t\tcontext = context.parentNode;\n\t\t\t}\n\n\t\t\tselector = selector.slice( tokens.shift().value.length );\n\t\t}\n\n\t\t// Fetch a seed set for right-to-left matching\n\t\ti = matchExpr[\"needsContext\"].test( selector ) ? 0 : tokens.length;\n\t\twhile ( i-- ) {\n\t\t\ttoken = tokens[i];\n\n\t\t\t// Abort if we hit a combinator\n\t\t\tif ( Expr.relative[ (type = token.type) ] ) {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tif ( (find = Expr.find[ type ]) ) {\n\t\t\t\t// Search, expanding context for leading sibling combinators\n\t\t\t\tif ( (seed = find(\n\t\t\t\t\ttoken.matches[0].replace( runescape, funescape ),\n\t\t\t\t\trsibling.test( tokens[0].type ) && testContext( context.parentNode ) || context\n\t\t\t\t)) ) {\n\n\t\t\t\t\t// If seed is empty or no tokens remain, we can return early\n\t\t\t\t\ttokens.splice( i, 1 );\n\t\t\t\t\tselector = seed.length && toSelector( tokens );\n\t\t\t\t\tif ( !selector ) {\n\t\t\t\t\t\tpush.apply( results, seed );\n\t\t\t\t\t\treturn results;\n\t\t\t\t\t}\n\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t// Compile and execute a filtering function if one is not provided\n\t// Provide `match` to avoid retokenization if we modified the selector above\n\t( compiled || compile( selector, match ) )(\n\t\tseed,\n\t\tcontext,\n\t\t!documentIsHTML,\n\t\tresults,\n\t\trsibling.test( selector ) && testContext( context.parentNode ) || context\n\t);\n\treturn results;\n};\n\n// One-time assignments\n\n// Sort stability\nsupport.sortStable = expando.split(\"\").sort( sortOrder ).join(\"\") === expando;\n\n// Support: Chrome 14-35+\n// Always assume duplicates if they aren't passed to the comparison function\nsupport.detectDuplicates = !!hasDuplicate;\n\n// Initialize against the default document\nsetDocument();\n\n// Support: Webkit<537.32 - Safari 6.0.3/Chrome 25 (fixed in Chrome 27)\n// Detached nodes confoundingly follow *each other*\nsupport.sortDetached = assert(function( div1 ) {\n\t// Should return 1, but returns 4 (following)\n\treturn div1.compareDocumentPosition( document.createElement(\"div\") ) & 1;\n});\n\n// Support: IE<8\n// Prevent attribute/property \"interpolation\"\n// http://msdn.microsoft.com/en-us/library/ms536429%28VS.85%29.aspx\nif ( !assert(function( div ) {\n\tdiv.innerHTML = \"<a href='#'></a>\";\n\treturn div.firstChild.getAttribute(\"href\") === \"#\" ;\n}) ) {\n\taddHandle( \"type|href|height|width\", function( elem, name, isXML ) {\n\t\tif ( !isXML ) {\n\t\t\treturn elem.getAttribute( name, name.toLowerCase() === \"type\" ? 1 : 2 );\n\t\t}\n\t});\n}\n\n// Support: IE<9\n// Use defaultValue in place of getAttribute(\"value\")\nif ( !support.attributes || !assert(function( div ) {\n\tdiv.innerHTML = \"<input/>\";\n\tdiv.firstChild.setAttribute( \"value\", \"\" );\n\treturn div.firstChild.getAttribute( \"value\" ) === \"\";\n}) ) {\n\taddHandle( \"value\", function( elem, name, isXML ) {\n\t\tif ( !isXML && elem.nodeName.toLowerCase() === \"input\" ) {\n\t\t\treturn elem.defaultValue;\n\t\t}\n\t});\n}\n\n// Support: IE<9\n// Use getAttributeNode to fetch booleans when getAttribute lies\nif ( !assert(function( div ) {\n\treturn div.getAttribute(\"disabled\") == null;\n}) ) {\n\taddHandle( booleans, function( elem, name, isXML ) {\n\t\tvar val;\n\t\tif ( !isXML ) {\n\t\t\treturn elem[ name ] === true ? name.toLowerCase() :\n\t\t\t\t\t(val = elem.getAttributeNode( name )) && val.specified ?\n\t\t\t\t\tval.value :\n\t\t\t\tnull;\n\t\t}\n\t});\n}\n\nreturn Sizzle;\n\n})( window );\n\n\n\njQuery.find = Sizzle;\njQuery.expr = Sizzle.selectors;\njQuery.expr[\":\"] = jQuery.expr.pseudos;\njQuery.unique = Sizzle.uniqueSort;\njQuery.text = Sizzle.getText;\njQuery.isXMLDoc = Sizzle.isXML;\njQuery.contains = Sizzle.contains;\n\n\n\nvar rneedsContext = jQuery.expr.match.needsContext;\n\nvar rsingleTag = (/^<(\\w+)\\s*\\/?>(?:<\\/\\1>|)$/);\n\n\n\nvar risSimple = /^.[^:#\\[\\.,]*$/;\n\n// Implement the identical functionality for filter and not\nfunction winnow( elements, qualifier, not ) {\n\tif ( jQuery.isFunction( qualifier ) ) {\n\t\treturn jQuery.grep( elements, function( elem, i ) {\n\t\t\t/* jshint -W018 */\n\t\t\treturn !!qualifier.call( elem, i, elem ) !== not;\n\t\t});\n\n\t}\n\n\tif ( qualifier.nodeType ) {\n\t\treturn jQuery.grep( elements, function( elem ) {\n\t\t\treturn ( elem === qualifier ) !== not;\n\t\t});\n\n\t}\n\n\tif ( typeof qualifier === \"string\" ) {\n\t\tif ( risSimple.test( qualifier ) ) {\n\t\t\treturn jQuery.filter( qualifier, elements, not );\n\t\t}\n\n\t\tqualifier = jQuery.filter( qualifier, elements );\n\t}\n\n\treturn jQuery.grep( elements, function( elem ) {\n\t\treturn ( jQuery.inArray( elem, qualifier ) >= 0 ) !== not;\n\t});\n}\n\njQuery.filter = function( expr, elems, not ) {\n\tvar elem = elems[ 0 ];\n\n\tif ( not ) {\n\t\texpr = \":not(\" + expr + \")\";\n\t}\n\n\treturn elems.length === 1 && elem.nodeType === 1 ?\n\t\tjQuery.find.matchesSelector( elem, expr ) ? [ elem ] : [] :\n\t\tjQuery.find.matches( expr, jQuery.grep( elems, function( elem ) {\n\t\t\treturn elem.nodeType === 1;\n\t\t}));\n};\n\njQuery.fn.extend({\n\tfind: function( selector ) {\n\t\tvar i,\n\t\t\tret = [],\n\t\t\tself = this,\n\t\t\tlen = self.length;\n\n\t\tif ( typeof selector !== \"string\" ) {\n\t\t\treturn this.pushStack( jQuery( selector ).filter(function() {\n\t\t\t\tfor ( i = 0; i < len; i++ ) {\n\t\t\t\t\tif ( jQuery.contains( self[ i ], this ) ) {\n\t\t\t\t\t\treturn true;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}) );\n\t\t}\n\n\t\tfor ( i = 0; i < len; i++ ) {\n\t\t\tjQuery.find( selector, self[ i ], ret );\n\t\t}\n\n\t\t// Needed because $( selector, context ) becomes $( context ).find( selector )\n\t\tret = this.pushStack( len > 1 ? jQuery.unique( ret ) : ret );\n\t\tret.selector = this.selector ? this.selector + \" \" + selector : selector;\n\t\treturn ret;\n\t},\n\tfilter: function( selector ) {\n\t\treturn this.pushStack( winnow(this, selector || [], false) );\n\t},\n\tnot: function( selector ) {\n\t\treturn this.pushStack( winnow(this, selector || [], true) );\n\t},\n\tis: function( selector ) {\n\t\treturn !!winnow(\n\t\t\tthis,\n\n\t\t\t// If this is a positional/relative selector, check membership in the returned set\n\t\t\t// so $(\"p:first\").is(\"p:last\") won't return true for a doc with two \"p\".\n\t\t\ttypeof selector === \"string\" && rneedsContext.test( selector ) ?\n\t\t\t\tjQuery( selector ) :\n\t\t\t\tselector || [],\n\t\t\tfalse\n\t\t).length;\n\t}\n});\n\n\n// Initialize a jQuery object\n\n\n// A central reference to the root jQuery(document)\nvar rootjQuery,\n\n\t// Use the correct document accordingly with window argument (sandbox)\n\tdocument = window.document,\n\n\t// A simple way to check for HTML strings\n\t// Prioritize #id over <tag> to avoid XSS via location.hash (#9521)\n\t// Strict HTML recognition (#11290: must start with <)\n\trquickExpr = /^(?:\\s*(<[\\w\\W]+>)[^>]*|#([\\w-]*))$/,\n\n\tinit = jQuery.fn.init = function( selector, context ) {\n\t\tvar match, elem;\n\n\t\t// HANDLE: $(\"\"), $(null), $(undefined), $(false)\n\t\tif ( !selector ) {\n\t\t\treturn this;\n\t\t}\n\n\t\t// Handle HTML strings\n\t\tif ( typeof selector === \"string\" ) {\n\t\t\tif ( selector.charAt(0) === \"<\" && selector.charAt( selector.length - 1 ) === \">\" && selector.length >= 3 ) {\n\t\t\t\t// Assume that strings that start and end with <> are HTML and skip the regex check\n\t\t\t\tmatch = [ null, selector, null ];\n\n\t\t\t} else {\n\t\t\t\tmatch = rquickExpr.exec( selector );\n\t\t\t}\n\n\t\t\t// Match html or make sure no context is specified for #id\n\t\t\tif ( match && (match[1] || !context) ) {\n\n\t\t\t\t// HANDLE: $(html) -> $(array)\n\t\t\t\tif ( match[1] ) {\n\t\t\t\t\tcontext = context instanceof jQuery ? context[0] : context;\n\n\t\t\t\t\t// scripts is true for back-compat\n\t\t\t\t\t// Intentionally let the error be thrown if parseHTML is not present\n\t\t\t\t\tjQuery.merge( this, jQuery.parseHTML(\n\t\t\t\t\t\tmatch[1],\n\t\t\t\t\t\tcontext && context.nodeType ? context.ownerDocument || context : document,\n\t\t\t\t\t\ttrue\n\t\t\t\t\t) );\n\n\t\t\t\t\t// HANDLE: $(html, props)\n\t\t\t\t\tif ( rsingleTag.test( match[1] ) && jQuery.isPlainObject( context ) ) {\n\t\t\t\t\t\tfor ( match in context ) {\n\t\t\t\t\t\t\t// Properties of context are called as methods if possible\n\t\t\t\t\t\t\tif ( jQuery.isFunction( this[ match ] ) ) {\n\t\t\t\t\t\t\t\tthis[ match ]( context[ match ] );\n\n\t\t\t\t\t\t\t// ...and otherwise set as attributes\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tthis.attr( match, context[ match ] );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\treturn this;\n\n\t\t\t\t// HANDLE: $(#id)\n\t\t\t\t} else {\n\t\t\t\t\telem = document.getElementById( match[2] );\n\n\t\t\t\t\t// Check parentNode to catch when Blackberry 4.6 returns\n\t\t\t\t\t// nodes that are no longer in the document #6963\n\t\t\t\t\tif ( elem && elem.parentNode ) {\n\t\t\t\t\t\t// Handle the case where IE and Opera return items\n\t\t\t\t\t\t// by name instead of ID\n\t\t\t\t\t\tif ( elem.id !== match[2] ) {\n\t\t\t\t\t\t\treturn rootjQuery.find( selector );\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// Otherwise, we inject the element directly into the jQuery object\n\t\t\t\t\t\tthis.length = 1;\n\t\t\t\t\t\tthis[0] = elem;\n\t\t\t\t\t}\n\n\t\t\t\t\tthis.context = document;\n\t\t\t\t\tthis.selector = selector;\n\t\t\t\t\treturn this;\n\t\t\t\t}\n\n\t\t\t// HANDLE: $(expr, $(...))\n\t\t\t} else if ( !context || context.jquery ) {\n\t\t\t\treturn ( context || rootjQuery ).find( selector );\n\n\t\t\t// HANDLE: $(expr, context)\n\t\t\t// (which is just equivalent to: $(context).find(expr)\n\t\t\t} else {\n\t\t\t\treturn this.constructor( context ).find( selector );\n\t\t\t}\n\n\t\t// HANDLE: $(DOMElement)\n\t\t} else if ( selector.nodeType ) {\n\t\t\tthis.context = this[0] = selector;\n\t\t\tthis.length = 1;\n\t\t\treturn this;\n\n\t\t// HANDLE: $(function)\n\t\t// Shortcut for document ready\n\t\t} else if ( jQuery.isFunction( selector ) ) {\n\t\t\treturn typeof rootjQuery.ready !== \"undefined\" ?\n\t\t\t\trootjQuery.ready( selector ) :\n\t\t\t\t// Execute immediately if ready is not present\n\t\t\t\tselector( jQuery );\n\t\t}\n\n\t\tif ( selector.selector !== undefined ) {\n\t\t\tthis.selector = selector.selector;\n\t\t\tthis.context = selector.context;\n\t\t}\n\n\t\treturn jQuery.makeArray( selector, this );\n\t};\n\n// Give the init function the jQuery prototype for later instantiation\ninit.prototype = jQuery.fn;\n\n// Initialize central reference\nrootjQuery = jQuery( document );\n\n\nvar rparentsprev = /^(?:parents|prev(?:Until|All))/,\n\t// methods guaranteed to produce a unique set when starting from a unique set\n\tguaranteedUnique = {\n\t\tchildren: true,\n\t\tcontents: true,\n\t\tnext: true,\n\t\tprev: true\n\t};\n\njQuery.extend({\n\tdir: function( elem, dir, until ) {\n\t\tvar matched = [],\n\t\t\tcur = elem[ dir ];\n\n\t\twhile ( cur && cur.nodeType !== 9 && (until === undefined || cur.nodeType !== 1 || !jQuery( cur ).is( until )) ) {\n\t\t\tif ( cur.nodeType === 1 ) {\n\t\t\t\tmatched.push( cur );\n\t\t\t}\n\t\t\tcur = cur[dir];\n\t\t}\n\t\treturn matched;\n\t},\n\n\tsibling: function( n, elem ) {\n\t\tvar r = [];\n\n\t\tfor ( ; n; n = n.nextSibling ) {\n\t\t\tif ( n.nodeType === 1 && n !== elem ) {\n\t\t\t\tr.push( n );\n\t\t\t}\n\t\t}\n\n\t\treturn r;\n\t}\n});\n\njQuery.fn.extend({\n\thas: function( target ) {\n\t\tvar i,\n\t\t\ttargets = jQuery( target, this ),\n\t\t\tlen = targets.length;\n\n\t\treturn this.filter(function() {\n\t\t\tfor ( i = 0; i < len; i++ ) {\n\t\t\t\tif ( jQuery.contains( this, targets[i] ) ) {\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\t},\n\n\tclosest: function( selectors, context ) {\n\t\tvar cur,\n\t\t\ti = 0,\n\t\t\tl = this.length,\n\t\t\tmatched = [],\n\t\t\tpos = rneedsContext.test( selectors ) || typeof selectors !== \"string\" ?\n\t\t\t\tjQuery( selectors, context || this.context ) :\n\t\t\t\t0;\n\n\t\tfor ( ; i < l; i++ ) {\n\t\t\tfor ( cur = this[i]; cur && cur !== context; cur = cur.parentNode ) {\n\t\t\t\t// Always skip document fragments\n\t\t\t\tif ( cur.nodeType < 11 && (pos ?\n\t\t\t\t\tpos.index(cur) > -1 :\n\n\t\t\t\t\t// Don't pass non-elements to Sizzle\n\t\t\t\t\tcur.nodeType === 1 &&\n\t\t\t\t\t\tjQuery.find.matchesSelector(cur, selectors)) ) {\n\n\t\t\t\t\tmatched.push( cur );\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn this.pushStack( matched.length > 1 ? jQuery.unique( matched ) : matched );\n\t},\n\n\t// Determine the position of an element within\n\t// the matched set of elements\n\tindex: function( elem ) {\n\n\t\t// No argument, return index in parent\n\t\tif ( !elem ) {\n\t\t\treturn ( this[0] && this[0].parentNode ) ? this.first().prevAll().length : -1;\n\t\t}\n\n\t\t// index in selector\n\t\tif ( typeof elem === \"string\" ) {\n\t\t\treturn jQuery.inArray( this[0], jQuery( elem ) );\n\t\t}\n\n\t\t// Locate the position of the desired element\n\t\treturn jQuery.inArray(\n\t\t\t// If it receives a jQuery object, the first element is used\n\t\t\telem.jquery ? elem[0] : elem, this );\n\t},\n\n\tadd: function( selector, context ) {\n\t\treturn this.pushStack(\n\t\t\tjQuery.unique(\n\t\t\t\tjQuery.merge( this.get(), jQuery( selector, context ) )\n\t\t\t)\n\t\t);\n\t},\n\n\taddBack: function( selector ) {\n\t\treturn this.add( selector == null ?\n\t\t\tthis.prevObject : this.prevObject.filter(selector)\n\t\t);\n\t}\n});\n\nfunction sibling( cur, dir ) {\n\tdo {\n\t\tcur = cur[ dir ];\n\t} while ( cur && cur.nodeType !== 1 );\n\n\treturn cur;\n}\n\njQuery.each({\n\tparent: function( elem ) {\n\t\tvar parent = elem.parentNode;\n\t\treturn parent && parent.nodeType !== 11 ? parent : null;\n\t},\n\tparents: function( elem ) {\n\t\treturn jQuery.dir( elem, \"parentNode\" );\n\t},\n\tparentsUntil: function( elem, i, until ) {\n\t\treturn jQuery.dir( elem, \"parentNode\", until );\n\t},\n\tnext: function( elem ) {\n\t\treturn sibling( elem, \"nextSibling\" );\n\t},\n\tprev: function( elem ) {\n\t\treturn sibling( elem, \"previousSibling\" );\n\t},\n\tnextAll: function( elem ) {\n\t\treturn jQuery.dir( elem, \"nextSibling\" );\n\t},\n\tprevAll: function( elem ) {\n\t\treturn jQuery.dir( elem, \"previousSibling\" );\n\t},\n\tnextUntil: function( elem, i, until ) {\n\t\treturn jQuery.dir( elem, \"nextSibling\", until );\n\t},\n\tprevUntil: function( elem, i, until ) {\n\t\treturn jQuery.dir( elem, \"previousSibling\", until );\n\t},\n\tsiblings: function( elem ) {\n\t\treturn jQuery.sibling( ( elem.parentNode || {} ).firstChild, elem );\n\t},\n\tchildren: function( elem ) {\n\t\treturn jQuery.sibling( elem.firstChild );\n\t},\n\tcontents: function( elem ) {\n\t\treturn jQuery.nodeName( elem, \"iframe\" ) ?\n\t\t\telem.contentDocument || elem.contentWindow.document :\n\t\t\tjQuery.merge( [], elem.childNodes );\n\t}\n}, function( name, fn ) {\n\tjQuery.fn[ name ] = function( until, selector ) {\n\t\tvar ret = jQuery.map( this, fn, until );\n\n\t\tif ( name.slice( -5 ) !== \"Until\" ) {\n\t\t\tselector = until;\n\t\t}\n\n\t\tif ( selector && typeof selector === \"string\" ) {\n\t\t\tret = jQuery.filter( selector, ret );\n\t\t}\n\n\t\tif ( this.length > 1 ) {\n\t\t\t// Remove duplicates\n\t\t\tif ( !guaranteedUnique[ name ] ) {\n\t\t\t\tret = jQuery.unique( ret );\n\t\t\t}\n\n\t\t\t// Reverse order for parents* and prev-derivatives\n\t\t\tif ( rparentsprev.test( name ) ) {\n\t\t\t\tret = ret.reverse();\n\t\t\t}\n\t\t}\n\n\t\treturn this.pushStack( ret );\n\t};\n});\nvar rnotwhite = (/\\S+/g);\n\n\n\n// String to Object options format cache\nvar optionsCache = {};\n\n// Convert String-formatted options into Object-formatted ones and store in cache\nfunction createOptions( options ) {\n\tvar object = optionsCache[ options ] = {};\n\tjQuery.each( options.match( rnotwhite ) || [], function( _, flag ) {\n\t\tobject[ flag ] = true;\n\t});\n\treturn object;\n}\n\n/*\n * Create a callback list using the following parameters:\n *\n *\toptions: an optional list of space-separated options that will change how\n *\t\t\tthe callback list behaves or a more traditional option object\n *\n * By default a callback list will act like an event callback list and can be\n * \"fired\" multiple times.\n *\n * Possible options:\n *\n *\tonce:\t\t\twill ensure the callback list can only be fired once (like a Deferred)\n *\n *\tmemory:\t\t\twill keep track of previous values and will call any callback added\n *\t\t\t\t\tafter the list has been fired right away with the latest \"memorized\"\n *\t\t\t\t\tvalues (like a Deferred)\n *\n *\tunique:\t\t\twill ensure a callback can only be added once (no duplicate in the list)\n *\n *\tstopOnFalse:\tinterrupt callings when a callback returns false\n *\n */\njQuery.Callbacks = function( options ) {\n\n\t// Convert options from String-formatted to Object-formatted if needed\n\t// (we check in cache first)\n\toptions = typeof options === \"string\" ?\n\t\t( optionsCache[ options ] || createOptions( options ) ) :\n\t\tjQuery.extend( {}, options );\n\n\tvar // Flag to know if list is currently firing\n\t\tfiring,\n\t\t// Last fire value (for non-forgettable lists)\n\t\tmemory,\n\t\t// Flag to know if list was already fired\n\t\tfired,\n\t\t// End of the loop when firing\n\t\tfiringLength,\n\t\t// Index of currently firing callback (modified by remove if needed)\n\t\tfiringIndex,\n\t\t// First callback to fire (used internally by add and fireWith)\n\t\tfiringStart,\n\t\t// Actual callback list\n\t\tlist = [],\n\t\t// Stack of fire calls for repeatable lists\n\t\tstack = !options.once && [],\n\t\t// Fire callbacks\n\t\tfire = function( data ) {\n\t\t\tmemory = options.memory && data;\n\t\t\tfired = true;\n\t\t\tfiringIndex = firingStart || 0;\n\t\t\tfiringStart = 0;\n\t\t\tfiringLength = list.length;\n\t\t\tfiring = true;\n\t\t\tfor ( ; list && firingIndex < firingLength; firingIndex++ ) {\n\t\t\t\tif ( list[ firingIndex ].apply( data[ 0 ], data[ 1 ] ) === false && options.stopOnFalse ) {\n\t\t\t\t\tmemory = false; // To prevent further calls using add\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t\tfiring = false;\n\t\t\tif ( list ) {\n\t\t\t\tif ( stack ) {\n\t\t\t\t\tif ( stack.length ) {\n\t\t\t\t\t\tfire( stack.shift() );\n\t\t\t\t\t}\n\t\t\t\t} else if ( memory ) {\n\t\t\t\t\tlist = [];\n\t\t\t\t} else {\n\t\t\t\t\tself.disable();\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\t// Actual Callbacks object\n\t\tself = {\n\t\t\t// Add a callback or a collection of callbacks to the list\n\t\t\tadd: function() {\n\t\t\t\tif ( list ) {\n\t\t\t\t\t// First, we save the current length\n\t\t\t\t\tvar start = list.length;\n\t\t\t\t\t(function add( args ) {\n\t\t\t\t\t\tjQuery.each( args, function( _, arg ) {\n\t\t\t\t\t\t\tvar type = jQuery.type( arg );\n\t\t\t\t\t\t\tif ( type === \"function\" ) {\n\t\t\t\t\t\t\t\tif ( !options.unique || !self.has( arg ) ) {\n\t\t\t\t\t\t\t\t\tlist.push( arg );\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t} else if ( arg && arg.length && type !== \"string\" ) {\n\t\t\t\t\t\t\t\t// Inspect recursively\n\t\t\t\t\t\t\t\tadd( arg );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t});\n\t\t\t\t\t})( arguments );\n\t\t\t\t\t// Do we need to add the callbacks to the\n\t\t\t\t\t// current firing batch?\n\t\t\t\t\tif ( firing ) {\n\t\t\t\t\t\tfiringLength = list.length;\n\t\t\t\t\t// With memory, if we're not firing then\n\t\t\t\t\t// we should call right away\n\t\t\t\t\t} else if ( memory ) {\n\t\t\t\t\t\tfiringStart = start;\n\t\t\t\t\t\tfire( memory );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn this;\n\t\t\t},\n\t\t\t// Remove a callback from the list\n\t\t\tremove: function() {\n\t\t\t\tif ( list ) {\n\t\t\t\t\tjQuery.each( arguments, function( _, arg ) {\n\t\t\t\t\t\tvar index;\n\t\t\t\t\t\twhile ( ( index = jQuery.inArray( arg, list, index ) ) > -1 ) {\n\t\t\t\t\t\t\tlist.splice( index, 1 );\n\t\t\t\t\t\t\t// Handle firing indexes\n\t\t\t\t\t\t\tif ( firing ) {\n\t\t\t\t\t\t\t\tif ( index <= firingLength ) {\n\t\t\t\t\t\t\t\t\tfiringLength--;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tif ( index <= firingIndex ) {\n\t\t\t\t\t\t\t\t\tfiringIndex--;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t\treturn this;\n\t\t\t},\n\t\t\t// Check if a given callback is in the list.\n\t\t\t// If no argument is given, return whether or not list has callbacks attached.\n\t\t\thas: function( fn ) {\n\t\t\t\treturn fn ? jQuery.inArray( fn, list ) > -1 : !!( list && list.length );\n\t\t\t},\n\t\t\t// Remove all callbacks from the list\n\t\t\tempty: function() {\n\t\t\t\tlist = [];\n\t\t\t\tfiringLength = 0;\n\t\t\t\treturn this;\n\t\t\t},\n\t\t\t// Have the list do nothing anymore\n\t\t\tdisable: function() {\n\t\t\t\tlist = stack = memory = undefined;\n\t\t\t\treturn this;\n\t\t\t},\n\t\t\t// Is it disabled?\n\t\t\tdisabled: function() {\n\t\t\t\treturn !list;\n\t\t\t},\n\t\t\t// Lock the list in its current state\n\t\t\tlock: function() {\n\t\t\t\tstack = undefined;\n\t\t\t\tif ( !memory ) {\n\t\t\t\t\tself.disable();\n\t\t\t\t}\n\t\t\t\treturn this;\n\t\t\t},\n\t\t\t// Is it locked?\n\t\t\tlocked: function() {\n\t\t\t\treturn !stack;\n\t\t\t},\n\t\t\t// Call all callbacks with the given context and arguments\n\t\t\tfireWith: function( context, args ) {\n\t\t\t\tif ( list && ( !fired || stack ) ) {\n\t\t\t\t\targs = args || [];\n\t\t\t\t\targs = [ context, args.slice ? args.slice() : args ];\n\t\t\t\t\tif ( firing ) {\n\t\t\t\t\t\tstack.push( args );\n\t\t\t\t\t} else {\n\t\t\t\t\t\tfire( args );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn this;\n\t\t\t},\n\t\t\t// Call all the callbacks with the given arguments\n\t\t\tfire: function() {\n\t\t\t\tself.fireWith( this, arguments );\n\t\t\t\treturn this;\n\t\t\t},\n\t\t\t// To know if the callbacks have already been called at least once\n\t\t\tfired: function() {\n\t\t\t\treturn !!fired;\n\t\t\t}\n\t\t};\n\n\treturn self;\n};\n\n\njQuery.extend({\n\n\tDeferred: function( func ) {\n\t\tvar tuples = [\n\t\t\t\t// action, add listener, listener list, final state\n\t\t\t\t[ \"resolve\", \"done\", jQuery.Callbacks(\"once memory\"), \"resolved\" ],\n\t\t\t\t[ \"reject\", \"fail\", jQuery.Callbacks(\"once memory\"), \"rejected\" ],\n\t\t\t\t[ \"notify\", \"progress\", jQuery.Callbacks(\"memory\") ]\n\t\t\t],\n\t\t\tstate = \"pending\",\n\t\t\tpromise = {\n\t\t\t\tstate: function() {\n\t\t\t\t\treturn state;\n\t\t\t\t},\n\t\t\t\talways: function() {\n\t\t\t\t\tdeferred.done( arguments ).fail( arguments );\n\t\t\t\t\treturn this;\n\t\t\t\t},\n\t\t\t\tthen: function( /* fnDone, fnFail, fnProgress */ ) {\n\t\t\t\t\tvar fns = arguments;\n\t\t\t\t\treturn jQuery.Deferred(function( newDefer ) {\n\t\t\t\t\t\tjQuery.each( tuples, function( i, tuple ) {\n\t\t\t\t\t\t\tvar fn = jQuery.isFunction( fns[ i ] ) && fns[ i ];\n\t\t\t\t\t\t\t// deferred[ done | fail | progress ] for forwarding actions to newDefer\n\t\t\t\t\t\t\tdeferred[ tuple[1] ](function() {\n\t\t\t\t\t\t\t\tvar returned = fn && fn.apply( this, arguments );\n\t\t\t\t\t\t\t\tif ( returned && jQuery.isFunction( returned.promise ) ) {\n\t\t\t\t\t\t\t\t\treturned.promise()\n\t\t\t\t\t\t\t\t\t\t.done( newDefer.resolve )\n\t\t\t\t\t\t\t\t\t\t.fail( newDefer.reject )\n\t\t\t\t\t\t\t\t\t\t.progress( newDefer.notify );\n\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\tnewDefer[ tuple[ 0 ] + \"With\" ]( this === promise ? newDefer.promise() : this, fn ? [ returned ] : arguments );\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t});\n\t\t\t\t\t\tfns = null;\n\t\t\t\t\t}).promise();\n\t\t\t\t},\n\t\t\t\t// Get a promise for this deferred\n\t\t\t\t// If obj is provided, the promise aspect is added to the object\n\t\t\t\tpromise: function( obj ) {\n\t\t\t\t\treturn obj != null ? jQuery.extend( obj, promise ) : promise;\n\t\t\t\t}\n\t\t\t},\n\t\t\tdeferred = {};\n\n\t\t// Keep pipe for back-compat\n\t\tpromise.pipe = promise.then;\n\n\t\t// Add list-specific methods\n\t\tjQuery.each( tuples, function( i, tuple ) {\n\t\t\tvar list = tuple[ 2 ],\n\t\t\t\tstateString = tuple[ 3 ];\n\n\t\t\t// promise[ done | fail | progress ] = list.add\n\t\t\tpromise[ tuple[1] ] = list.add;\n\n\t\t\t// Handle state\n\t\t\tif ( stateString ) {\n\t\t\t\tlist.add(function() {\n\t\t\t\t\t// state = [ resolved | rejected ]\n\t\t\t\t\tstate = stateString;\n\n\t\t\t\t// [ reject_list | resolve_list ].disable; progress_list.lock\n\t\t\t\t}, tuples[ i ^ 1 ][ 2 ].disable, tuples[ 2 ][ 2 ].lock );\n\t\t\t}\n\n\t\t\t// deferred[ resolve | reject | notify ]\n\t\t\tdeferred[ tuple[0] ] = function() {\n\t\t\t\tdeferred[ tuple[0] + \"With\" ]( this === deferred ? promise : this, arguments );\n\t\t\t\treturn this;\n\t\t\t};\n\t\t\tdeferred[ tuple[0] + \"With\" ] = list.fireWith;\n\t\t});\n\n\t\t// Make the deferred a promise\n\t\tpromise.promise( deferred );\n\n\t\t// Call given func if any\n\t\tif ( func ) {\n\t\t\tfunc.call( deferred, deferred );\n\t\t}\n\n\t\t// All done!\n\t\treturn deferred;\n\t},\n\n\t// Deferred helper\n\twhen: function( subordinate /* , ..., subordinateN */ ) {\n\t\tvar i = 0,\n\t\t\tresolveValues = slice.call( arguments ),\n\t\t\tlength = resolveValues.length,\n\n\t\t\t// the count of uncompleted subordinates\n\t\t\tremaining = length !== 1 || ( subordinate && jQuery.isFunction( subordinate.promise ) ) ? length : 0,\n\n\t\t\t// the master Deferred. If resolveValues consist of only a single Deferred, just use that.\n\t\t\tdeferred = remaining === 1 ? subordinate : jQuery.Deferred(),\n\n\t\t\t// Update function for both resolve and progress values\n\t\t\tupdateFunc = function( i, contexts, values ) {\n\t\t\t\treturn function( value ) {\n\t\t\t\t\tcontexts[ i ] = this;\n\t\t\t\t\tvalues[ i ] = arguments.length > 1 ? slice.call( arguments ) : value;\n\t\t\t\t\tif ( values === progressValues ) {\n\t\t\t\t\t\tdeferred.notifyWith( contexts, values );\n\n\t\t\t\t\t} else if ( !(--remaining) ) {\n\t\t\t\t\t\tdeferred.resolveWith( contexts, values );\n\t\t\t\t\t}\n\t\t\t\t};\n\t\t\t},\n\n\t\t\tprogressValues, progressContexts, resolveContexts;\n\n\t\t// add listeners to Deferred subordinates; treat others as resolved\n\t\tif ( length > 1 ) {\n\t\t\tprogressValues = new Array( length );\n\t\t\tprogressContexts = new Array( length );\n\t\t\tresolveContexts = new Array( length );\n\t\t\tfor ( ; i < length; i++ ) {\n\t\t\t\tif ( resolveValues[ i ] && jQuery.isFunction( resolveValues[ i ].promise ) ) {\n\t\t\t\t\tresolveValues[ i ].promise()\n\t\t\t\t\t\t.done( updateFunc( i, resolveContexts, resolveValues ) )\n\t\t\t\t\t\t.fail( deferred.reject )\n\t\t\t\t\t\t.progress( updateFunc( i, progressContexts, progressValues ) );\n\t\t\t\t} else {\n\t\t\t\t\t--remaining;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// if we're not waiting on anything, resolve the master\n\t\tif ( !remaining ) {\n\t\t\tdeferred.resolveWith( resolveContexts, resolveValues );\n\t\t}\n\n\t\treturn deferred.promise();\n\t}\n});\n\n\n// The deferred used on DOM ready\nvar readyList;\n\njQuery.fn.ready = function( fn ) {\n\t// Add the callback\n\tjQuery.ready.promise().done( fn );\n\n\treturn this;\n};\n\njQuery.extend({\n\t// Is the DOM ready to be used? Set to true once it occurs.\n\tisReady: false,\n\n\t// A counter to track how many items to wait for before\n\t// the ready event fires. See #6781\n\treadyWait: 1,\n\n\t// Hold (or release) the ready event\n\tholdReady: function( hold ) {\n\t\tif ( hold ) {\n\t\t\tjQuery.readyWait++;\n\t\t} else {\n\t\t\tjQuery.ready( true );\n\t\t}\n\t},\n\n\t// Handle when the DOM is ready\n\tready: function( wait ) {\n\n\t\t// Abort if there are pending holds or we're already ready\n\t\tif ( wait === true ? --jQuery.readyWait : jQuery.isReady ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443).\n\t\tif ( !document.body ) {\n\t\t\treturn setTimeout( jQuery.ready );\n\t\t}\n\n\t\t// Remember that the DOM is ready\n\t\tjQuery.isReady = true;\n\n\t\t// If a normal DOM Ready event fired, decrement, and wait if need be\n\t\tif ( wait !== true && --jQuery.readyWait > 0 ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// If there are functions bound, to execute\n\t\treadyList.resolveWith( document, [ jQuery ] );\n\n\t\t// Trigger any bound ready events\n\t\tif ( jQuery.fn.triggerHandler ) {\n\t\t\tjQuery( document ).triggerHandler( \"ready\" );\n\t\t\tjQuery( document ).off( \"ready\" );\n\t\t}\n\t}\n});\n\n/**\n * Clean-up method for dom ready events\n */\nfunction detach() {\n\tif ( document.addEventListener ) {\n\t\tdocument.removeEventListener( \"DOMContentLoaded\", completed, false );\n\t\twindow.removeEventListener( \"load\", completed, false );\n\n\t} else {\n\t\tdocument.detachEvent( \"onreadystatechange\", completed );\n\t\twindow.detachEvent( \"onload\", completed );\n\t}\n}\n\n/**\n * The ready event handler and self cleanup method\n */\nfunction completed() {\n\t// readyState === \"complete\" is good enough for us to call the dom ready in oldIE\n\tif ( document.addEventListener || event.type === \"load\" || document.readyState === \"complete\" ) {\n\t\tdetach();\n\t\tjQuery.ready();\n\t}\n}\n\njQuery.ready.promise = function( obj ) {\n\tif ( !readyList ) {\n\n\t\treadyList = jQuery.Deferred();\n\n\t\t// Catch cases where $(document).ready() is called after the browser event has already occurred.\n\t\t// we once tried to use readyState \"interactive\" here, but it caused issues like the one\n\t\t// discovered by ChrisS here: http://bugs.jquery.com/ticket/12282#comment:15\n\t\tif ( document.readyState === \"complete\" ) {\n\t\t\t// Handle it asynchronously to allow scripts the opportunity to delay ready\n\t\t\tsetTimeout( jQuery.ready );\n\n\t\t// Standards-based browsers support DOMContentLoaded\n\t\t} else if ( document.addEventListener ) {\n\t\t\t// Use the handy event callback\n\t\t\tdocument.addEventListener( \"DOMContentLoaded\", completed, false );\n\n\t\t\t// A fallback to window.onload, that will always work\n\t\t\twindow.addEventListener( \"load\", completed, false );\n\n\t\t// If IE event model is used\n\t\t} else {\n\t\t\t// Ensure firing before onload, maybe late but safe also for iframes\n\t\t\tdocument.attachEvent( \"onreadystatechange\", completed );\n\n\t\t\t// A fallback to window.onload, that will always work\n\t\t\twindow.attachEvent( \"onload\", completed );\n\n\t\t\t// If IE and not a frame\n\t\t\t// continually check to see if the document is ready\n\t\t\tvar top = false;\n\n\t\t\ttry {\n\t\t\t\ttop = window.frameElement == null && document.documentElement;\n\t\t\t} catch(e) {}\n\n\t\t\tif ( top && top.doScroll ) {\n\t\t\t\t(function doScrollCheck() {\n\t\t\t\t\tif ( !jQuery.isReady ) {\n\n\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t// Use the trick by Diego Perini\n\t\t\t\t\t\t\t// http://javascript.nwbox.com/IEContentLoaded/\n\t\t\t\t\t\t\ttop.doScroll(\"left\");\n\t\t\t\t\t\t} catch(e) {\n\t\t\t\t\t\t\treturn setTimeout( doScrollCheck, 50 );\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// detach all dom ready events\n\t\t\t\t\t\tdetach();\n\n\t\t\t\t\t\t// and execute any waiting functions\n\t\t\t\t\t\tjQuery.ready();\n\t\t\t\t\t}\n\t\t\t\t})();\n\t\t\t}\n\t\t}\n\t}\n\treturn readyList.promise( obj );\n};\n\n\nvar strundefined = typeof undefined;\n\n\n\n// Support: IE<9\n// Iteration over object's inherited properties before its own\nvar i;\nfor ( i in jQuery( support ) ) {\n\tbreak;\n}\nsupport.ownLast = i !== \"0\";\n\n// Note: most support tests are defined in their respective modules.\n// false until the test is run\nsupport.inlineBlockNeedsLayout = false;\n\n// Execute ASAP in case we need to set body.style.zoom\njQuery(function() {\n\t// Minified: var a,b,c,d\n\tvar val, div, body, container;\n\n\tbody = document.getElementsByTagName( \"body\" )[ 0 ];\n\tif ( !body || !body.style ) {\n\t\t// Return for frameset docs that don't have a body\n\t\treturn;\n\t}\n\n\t// Setup\n\tdiv = document.createElement( \"div\" );\n\tcontainer = document.createElement( \"div\" );\n\tcontainer.style.cssText = \"position:absolute;border:0;width:0;height:0;top:0;left:-9999px\";\n\tbody.appendChild( container ).appendChild( div );\n\n\tif ( typeof div.style.zoom !== strundefined ) {\n\t\t// Support: IE<8\n\t\t// Check if natively block-level elements act like inline-block\n\t\t// elements when setting their display to 'inline' and giving\n\t\t// them layout\n\t\tdiv.style.cssText = \"display:inline;margin:0;border:0;padding:1px;width:1px;zoom:1\";\n\n\t\tsupport.inlineBlockNeedsLayout = val = div.offsetWidth === 3;\n\t\tif ( val ) {\n\t\t\t// Prevent IE 6 from affecting layout for positioned elements #11048\n\t\t\t// Prevent IE from shrinking the body in IE 7 mode #12869\n\t\t\t// Support: IE<8\n\t\t\tbody.style.zoom = 1;\n\t\t}\n\t}\n\n\tbody.removeChild( container );\n});\n\n\n\n\n(function() {\n\tvar div = document.createElement( \"div\" );\n\n\t// Execute the test only if not already executed in another module.\n\tif (support.deleteExpando == null) {\n\t\t// Support: IE<9\n\t\tsupport.deleteExpando = true;\n\t\ttry {\n\t\t\tdelete div.test;\n\t\t} catch( e ) {\n\t\t\tsupport.deleteExpando = false;\n\t\t}\n\t}\n\n\t// Null elements to avoid leaks in IE.\n\tdiv = null;\n})();\n\n\n/**\n * Determines whether an object can have data\n */\njQuery.acceptData = function( elem ) {\n\tvar noData = jQuery.noData[ (elem.nodeName + \" \").toLowerCase() ],\n\t\tnodeType = +elem.nodeType || 1;\n\n\t// Do not set data on non-element DOM nodes because it will not be cleared (#8335).\n\treturn nodeType !== 1 && nodeType !== 9 ?\n\t\tfalse :\n\n\t\t// Nodes accept data unless otherwise specified; rejection can be conditional\n\t\t!noData || noData !== true && elem.getAttribute(\"classid\") === noData;\n};\n\n\nvar rbrace = /^(?:\\{[\\w\\W]*\\}|\\[[\\w\\W]*\\])$/,\n\trmultiDash = /([A-Z])/g;\n\nfunction dataAttr( elem, key, data ) {\n\t// If nothing was found internally, try to fetch any\n\t// data from the HTML5 data-* attribute\n\tif ( data === undefined && elem.nodeType === 1 ) {\n\n\t\tvar name = \"data-\" + key.replace( rmultiDash, \"-$1\" ).toLowerCase();\n\n\t\tdata = elem.getAttribute( name );\n\n\t\tif ( typeof data === \"string\" ) {\n\t\t\ttry {\n\t\t\t\tdata = data === \"true\" ? true :\n\t\t\t\t\tdata === \"false\" ? false :\n\t\t\t\t\tdata === \"null\" ? null :\n\t\t\t\t\t// Only convert to a number if it doesn't change the string\n\t\t\t\t\t+data + \"\" === data ? +data :\n\t\t\t\t\trbrace.test( data ) ? jQuery.parseJSON( data ) :\n\t\t\t\t\tdata;\n\t\t\t} catch( e ) {}\n\n\t\t\t// Make sure we set the data so it isn't changed later\n\t\t\tjQuery.data( elem, key, data );\n\n\t\t} else {\n\t\t\tdata = undefined;\n\t\t}\n\t}\n\n\treturn data;\n}\n\n// checks a cache object for emptiness\nfunction isEmptyDataObject( obj ) {\n\tvar name;\n\tfor ( name in obj ) {\n\n\t\t// if the public data object is empty, the private is still empty\n\t\tif ( name === \"data\" && jQuery.isEmptyObject( obj[name] ) ) {\n\t\t\tcontinue;\n\t\t}\n\t\tif ( name !== \"toJSON\" ) {\n\t\t\treturn false;\n\t\t}\n\t}\n\n\treturn true;\n}\n\nfunction internalData( elem, name, data, pvt /* Internal Use Only */ ) {\n\tif ( !jQuery.acceptData( elem ) ) {\n\t\treturn;\n\t}\n\n\tvar ret, thisCache,\n\t\tinternalKey = jQuery.expando,\n\n\t\t// We have to handle DOM nodes and JS objects differently because IE6-7\n\t\t// can't GC object references properly across the DOM-JS boundary\n\t\tisNode = elem.nodeType,\n\n\t\t// Only DOM nodes need the global jQuery cache; JS object data is\n\t\t// attached directly to the object so GC can occur automatically\n\t\tcache = isNode ? jQuery.cache : elem,\n\n\t\t// Only defining an ID for JS objects if its cache already exists allows\n\t\t// the code to shortcut on the same path as a DOM node with no cache\n\t\tid = isNode ? elem[ internalKey ] : elem[ internalKey ] && internalKey;\n\n\t// Avoid doing any more work than we need to when trying to get data on an\n\t// object that has no data at all\n\tif ( (!id || !cache[id] || (!pvt && !cache[id].data)) && data === undefined && typeof name === \"string\" ) {\n\t\treturn;\n\t}\n\n\tif ( !id ) {\n\t\t// Only DOM nodes need a new unique ID for each element since their data\n\t\t// ends up in the global cache\n\t\tif ( isNode ) {\n\t\t\tid = elem[ internalKey ] = deletedIds.pop() || jQuery.guid++;\n\t\t} else {\n\t\t\tid = internalKey;\n\t\t}\n\t}\n\n\tif ( !cache[ id ] ) {\n\t\t// Avoid exposing jQuery metadata on plain JS objects when the object\n\t\t// is serialized using JSON.stringify\n\t\tcache[ id ] = isNode ? {} : { toJSON: jQuery.noop };\n\t}\n\n\t// An object can be passed to jQuery.data instead of a key/value pair; this gets\n\t// shallow copied over onto the existing cache\n\tif ( typeof name === \"object\" || typeof name === \"function\" ) {\n\t\tif ( pvt ) {\n\t\t\tcache[ id ] = jQuery.extend( cache[ id ], name );\n\t\t} else {\n\t\t\tcache[ id ].data = jQuery.extend( cache[ id ].data, name );\n\t\t}\n\t}\n\n\tthisCache = cache[ id ];\n\n\t// jQuery data() is stored in a separate object inside the object's internal data\n\t// cache in order to avoid key collisions between internal data and user-defined\n\t// data.\n\tif ( !pvt ) {\n\t\tif ( !thisCache.data ) {\n\t\t\tthisCache.data = {};\n\t\t}\n\n\t\tthisCache = thisCache.data;\n\t}\n\n\tif ( data !== undefined ) {\n\t\tthisCache[ jQuery.camelCase( name ) ] = data;\n\t}\n\n\t// Check for both converted-to-camel and non-converted data property names\n\t// If a data property was specified\n\tif ( typeof name === \"string\" ) {\n\n\t\t// First Try to find as-is property data\n\t\tret = thisCache[ name ];\n\n\t\t// Test for null|undefined property data\n\t\tif ( ret == null ) {\n\n\t\t\t// Try to find the camelCased property\n\t\t\tret = thisCache[ jQuery.camelCase( name ) ];\n\t\t}\n\t} else {\n\t\tret = thisCache;\n\t}\n\n\treturn ret;\n}\n\nfunction internalRemoveData( elem, name, pvt ) {\n\tif ( !jQuery.acceptData( elem ) ) {\n\t\treturn;\n\t}\n\n\tvar thisCache, i,\n\t\tisNode = elem.nodeType,\n\n\t\t// See jQuery.data for more information\n\t\tcache = isNode ? jQuery.cache : elem,\n\t\tid = isNode ? elem[ jQuery.expando ] : jQuery.expando;\n\n\t// If there is already no cache entry for this object, there is no\n\t// purpose in continuing\n\tif ( !cache[ id ] ) {\n\t\treturn;\n\t}\n\n\tif ( name ) {\n\n\t\tthisCache = pvt ? cache[ id ] : cache[ id ].data;\n\n\t\tif ( thisCache ) {\n\n\t\t\t// Support array or space separated string names for data keys\n\t\t\tif ( !jQuery.isArray( name ) ) {\n\n\t\t\t\t// try the string as a key before any manipulation\n\t\t\t\tif ( name in thisCache ) {\n\t\t\t\t\tname = [ name ];\n\t\t\t\t} else {\n\n\t\t\t\t\t// split the camel cased version by spaces unless a key with the spaces exists\n\t\t\t\t\tname = jQuery.camelCase( name );\n\t\t\t\t\tif ( name in thisCache ) {\n\t\t\t\t\t\tname = [ name ];\n\t\t\t\t\t} else {\n\t\t\t\t\t\tname = name.split(\" \");\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t// If \"name\" is an array of keys...\n\t\t\t\t// When data is initially created, via (\"key\", \"val\") signature,\n\t\t\t\t// keys will be converted to camelCase.\n\t\t\t\t// Since there is no way to tell _how_ a key was added, remove\n\t\t\t\t// both plain key and camelCase key. #12786\n\t\t\t\t// This will only penalize the array argument path.\n\t\t\t\tname = name.concat( jQuery.map( name, jQuery.camelCase ) );\n\t\t\t}\n\n\t\t\ti = name.length;\n\t\t\twhile ( i-- ) {\n\t\t\t\tdelete thisCache[ name[i] ];\n\t\t\t}\n\n\t\t\t// If there is no data left in the cache, we want to continue\n\t\t\t// and let the cache object itself get destroyed\n\t\t\tif ( pvt ? !isEmptyDataObject(thisCache) : !jQuery.isEmptyObject(thisCache) ) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\t}\n\n\t// See jQuery.data for more information\n\tif ( !pvt ) {\n\t\tdelete cache[ id ].data;\n\n\t\t// Don't destroy the parent cache unless the internal data object\n\t\t// had been the only thing left in it\n\t\tif ( !isEmptyDataObject( cache[ id ] ) ) {\n\t\t\treturn;\n\t\t}\n\t}\n\n\t// Destroy the cache\n\tif ( isNode ) {\n\t\tjQuery.cleanData( [ elem ], true );\n\n\t// Use delete when supported for expandos or `cache` is not a window per isWindow (#10080)\n\t/* jshint eqeqeq: false */\n\t} else if ( support.deleteExpando || cache != cache.window ) {\n\t\t/* jshint eqeqeq: true */\n\t\tdelete cache[ id ];\n\n\t// When all else fails, null\n\t} else {\n\t\tcache[ id ] = null;\n\t}\n}\n\njQuery.extend({\n\tcache: {},\n\n\t// The following elements (space-suffixed to avoid Object.prototype collisions)\n\t// throw uncatchable exceptions if you attempt to set expando properties\n\tnoData: {\n\t\t\"applet \": true,\n\t\t\"embed \": true,\n\t\t// ...but Flash objects (which have this classid) *can* handle expandos\n\t\t\"object \": \"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000\"\n\t},\n\n\thasData: function( elem ) {\n\t\telem = elem.nodeType ? jQuery.cache[ elem[jQuery.expando] ] : elem[ jQuery.expando ];\n\t\treturn !!elem && !isEmptyDataObject( elem );\n\t},\n\n\tdata: function( elem, name, data ) {\n\t\treturn internalData( elem, name, data );\n\t},\n\n\tremoveData: function( elem, name ) {\n\t\treturn internalRemoveData( elem, name );\n\t},\n\n\t// For internal use only.\n\t_data: function( elem, name, data ) {\n\t\treturn internalData( elem, name, data, true );\n\t},\n\n\t_removeData: function( elem, name ) {\n\t\treturn internalRemoveData( elem, name, true );\n\t}\n});\n\njQuery.fn.extend({\n\tdata: function( key, value ) {\n\t\tvar i, name, data,\n\t\t\telem = this[0],\n\t\t\tattrs = elem && elem.attributes;\n\n\t\t// Special expections of .data basically thwart jQuery.access,\n\t\t// so implement the relevant behavior ourselves\n\n\t\t// Gets all values\n\t\tif ( key === undefined ) {\n\t\t\tif ( this.length ) {\n\t\t\t\tdata = jQuery.data( elem );\n\n\t\t\t\tif ( elem.nodeType === 1 && !jQuery._data( elem, \"parsedAttrs\" ) ) {\n\t\t\t\t\ti = attrs.length;\n\t\t\t\t\twhile ( i-- ) {\n\n\t\t\t\t\t\t// Support: IE11+\n\t\t\t\t\t\t// The attrs elements can be null (#14894)\n\t\t\t\t\t\tif ( attrs[ i ] ) {\n\t\t\t\t\t\t\tname = attrs[ i ].name;\n\t\t\t\t\t\t\tif ( name.indexOf( \"data-\" ) === 0 ) {\n\t\t\t\t\t\t\t\tname = jQuery.camelCase( name.slice(5) );\n\t\t\t\t\t\t\t\tdataAttr( elem, name, data[ name ] );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tjQuery._data( elem, \"parsedAttrs\", true );\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn data;\n\t\t}\n\n\t\t// Sets multiple values\n\t\tif ( typeof key === \"object\" ) {\n\t\t\treturn this.each(function() {\n\t\t\t\tjQuery.data( this, key );\n\t\t\t});\n\t\t}\n\n\t\treturn arguments.length > 1 ?\n\n\t\t\t// Sets one value\n\t\t\tthis.each(function() {\n\t\t\t\tjQuery.data( this, key, value );\n\t\t\t}) :\n\n\t\t\t// Gets one value\n\t\t\t// Try to fetch any internally stored data first\n\t\t\telem ? dataAttr( elem, key, jQuery.data( elem, key ) ) : undefined;\n\t},\n\n\tremoveData: function( key ) {\n\t\treturn this.each(function() {\n\t\t\tjQuery.removeData( this, key );\n\t\t});\n\t}\n});\n\n\njQuery.extend({\n\tqueue: function( elem, type, data ) {\n\t\tvar queue;\n\n\t\tif ( elem ) {\n\t\t\ttype = ( type || \"fx\" ) + \"queue\";\n\t\t\tqueue = jQuery._data( elem, type );\n\n\t\t\t// Speed up dequeue by getting out quickly if this is just a lookup\n\t\t\tif ( data ) {\n\t\t\t\tif ( !queue || jQuery.isArray(data) ) {\n\t\t\t\t\tqueue = jQuery._data( elem, type, jQuery.makeArray(data) );\n\t\t\t\t} else {\n\t\t\t\t\tqueue.push( data );\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn queue || [];\n\t\t}\n\t},\n\n\tdequeue: function( elem, type ) {\n\t\ttype = type || \"fx\";\n\n\t\tvar queue = jQuery.queue( elem, type ),\n\t\t\tstartLength = queue.length,\n\t\t\tfn = queue.shift(),\n\t\t\thooks = jQuery._queueHooks( elem, type ),\n\t\t\tnext = function() {\n\t\t\t\tjQuery.dequeue( elem, type );\n\t\t\t};\n\n\t\t// If the fx queue is dequeued, always remove the progress sentinel\n\t\tif ( fn === \"inprogress\" ) {\n\t\t\tfn = queue.shift();\n\t\t\tstartLength--;\n\t\t}\n\n\t\tif ( fn ) {\n\n\t\t\t// Add a progress sentinel to prevent the fx queue from being\n\t\t\t// automatically dequeued\n\t\t\tif ( type === \"fx\" ) {\n\t\t\t\tqueue.unshift( \"inprogress\" );\n\t\t\t}\n\n\t\t\t// clear up the last queue stop function\n\t\t\tdelete hooks.stop;\n\t\t\tfn.call( elem, next, hooks );\n\t\t}\n\n\t\tif ( !startLength && hooks ) {\n\t\t\thooks.empty.fire();\n\t\t}\n\t},\n\n\t// not intended for public consumption - generates a queueHooks object, or returns the current one\n\t_queueHooks: function( elem, type ) {\n\t\tvar key = type + \"queueHooks\";\n\t\treturn jQuery._data( elem, key ) || jQuery._data( elem, key, {\n\t\t\tempty: jQuery.Callbacks(\"once memory\").add(function() {\n\t\t\t\tjQuery._removeData( elem, type + \"queue\" );\n\t\t\t\tjQuery._removeData( elem, key );\n\t\t\t})\n\t\t});\n\t}\n});\n\njQuery.fn.extend({\n\tqueue: function( type, data ) {\n\t\tvar setter = 2;\n\n\t\tif ( typeof type !== \"string\" ) {\n\t\t\tdata = type;\n\t\t\ttype = \"fx\";\n\t\t\tsetter--;\n\t\t}\n\n\t\tif ( arguments.length < setter ) {\n\t\t\treturn jQuery.queue( this[0], type );\n\t\t}\n\n\t\treturn data === undefined ?\n\t\t\tthis :\n\t\t\tthis.each(function() {\n\t\t\t\tvar queue = jQuery.queue( this, type, data );\n\n\t\t\t\t// ensure a hooks for this queue\n\t\t\t\tjQuery._queueHooks( this, type );\n\n\t\t\t\tif ( type === \"fx\" && queue[0] !== \"inprogress\" ) {\n\t\t\t\t\tjQuery.dequeue( this, type );\n\t\t\t\t}\n\t\t\t});\n\t},\n\tdequeue: function( type ) {\n\t\treturn this.each(function() {\n\t\t\tjQuery.dequeue( this, type );\n\t\t});\n\t},\n\tclearQueue: function( type ) {\n\t\treturn this.queue( type || \"fx\", [] );\n\t},\n\t// Get a promise resolved when queues of a certain type\n\t// are emptied (fx is the type by default)\n\tpromise: function( type, obj ) {\n\t\tvar tmp,\n\t\t\tcount = 1,\n\t\t\tdefer = jQuery.Deferred(),\n\t\t\telements = this,\n\t\t\ti = this.length,\n\t\t\tresolve = function() {\n\t\t\t\tif ( !( --count ) ) {\n\t\t\t\t\tdefer.resolveWith( elements, [ elements ] );\n\t\t\t\t}\n\t\t\t};\n\n\t\tif ( typeof type !== \"string\" ) {\n\t\t\tobj = type;\n\t\t\ttype = undefined;\n\t\t}\n\t\ttype = type || \"fx\";\n\n\t\twhile ( i-- ) {\n\t\t\ttmp = jQuery._data( elements[ i ], type + \"queueHooks\" );\n\t\t\tif ( tmp && tmp.empty ) {\n\t\t\t\tcount++;\n\t\t\t\ttmp.empty.add( resolve );\n\t\t\t}\n\t\t}\n\t\tresolve();\n\t\treturn defer.promise( obj );\n\t}\n});\nvar pnum = (/[+-]?(?:\\d*\\.|)\\d+(?:[eE][+-]?\\d+|)/).source;\n\nvar cssExpand = [ \"Top\", \"Right\", \"Bottom\", \"Left\" ];\n\nvar isHidden = function( elem, el ) {\n\t\t// isHidden might be called from jQuery#filter function;\n\t\t// in that case, element will be second argument\n\t\telem = el || elem;\n\t\treturn jQuery.css( elem, \"display\" ) === \"none\" || !jQuery.contains( elem.ownerDocument, elem );\n\t};\n\n\n\n// Multifunctional method to get and set values of a collection\n// The value/s can optionally be executed if it's a function\nvar access = jQuery.access = function( elems, fn, key, value, chainable, emptyGet, raw ) {\n\tvar i = 0,\n\t\tlength = elems.length,\n\t\tbulk = key == null;\n\n\t// Sets many values\n\tif ( jQuery.type( key ) === \"object\" ) {\n\t\tchainable = true;\n\t\tfor ( i in key ) {\n\t\t\tjQuery.access( elems, fn, i, key[i], true, emptyGet, raw );\n\t\t}\n\n\t// Sets one value\n\t} else if ( value !== undefined ) {\n\t\tchainable = true;\n\n\t\tif ( !jQuery.isFunction( value ) ) {\n\t\t\traw = true;\n\t\t}\n\n\t\tif ( bulk ) {\n\t\t\t// Bulk operations run against the entire set\n\t\t\tif ( raw ) {\n\t\t\t\tfn.call( elems, value );\n\t\t\t\tfn = null;\n\n\t\t\t// ...except when executing function values\n\t\t\t} else {\n\t\t\t\tbulk = fn;\n\t\t\t\tfn = function( elem, key, value ) {\n\t\t\t\t\treturn bulk.call( jQuery( elem ), value );\n\t\t\t\t};\n\t\t\t}\n\t\t}\n\n\t\tif ( fn ) {\n\t\t\tfor ( ; i < length; i++ ) {\n\t\t\t\tfn( elems[i], key, raw ? value : value.call( elems[i], i, fn( elems[i], key ) ) );\n\t\t\t}\n\t\t}\n\t}\n\n\treturn chainable ?\n\t\telems :\n\n\t\t// Gets\n\t\tbulk ?\n\t\t\tfn.call( elems ) :\n\t\t\tlength ? fn( elems[0], key ) : emptyGet;\n};\nvar rcheckableType = (/^(?:checkbox|radio)$/i);\n\n\n\n(function() {\n\t// Minified: var a,b,c\n\tvar input = document.createElement( \"input\" ),\n\t\tdiv = document.createElement( \"div\" ),\n\t\tfragment = document.createDocumentFragment();\n\n\t// Setup\n\tdiv.innerHTML = \"  <link/><table></table><a href='/a'>a</a><input type='checkbox'/>\";\n\n\t// IE strips leading whitespace when .innerHTML is used\n\tsupport.leadingWhitespace = div.firstChild.nodeType === 3;\n\n\t// Make sure that tbody elements aren't automatically inserted\n\t// IE will insert them into empty tables\n\tsupport.tbody = !div.getElementsByTagName( \"tbody\" ).length;\n\n\t// Make sure that link elements get serialized correctly by innerHTML\n\t// This requires a wrapper element in IE\n\tsupport.htmlSerialize = !!div.getElementsByTagName( \"link\" ).length;\n\n\t// Makes sure cloning an html5 element does not cause problems\n\t// Where outerHTML is undefined, this still works\n\tsupport.html5Clone =\n\t\tdocument.createElement( \"nav\" ).cloneNode( true ).outerHTML !== \"<:nav></:nav>\";\n\n\t// Check if a disconnected checkbox will retain its checked\n\t// value of true after appended to the DOM (IE6/7)\n\tinput.type = \"checkbox\";\n\tinput.checked = true;\n\tfragment.appendChild( input );\n\tsupport.appendChecked = input.checked;\n\n\t// Make sure textarea (and checkbox) defaultValue is properly cloned\n\t// Support: IE6-IE11+\n\tdiv.innerHTML = \"<textarea>x</textarea>\";\n\tsupport.noCloneChecked = !!div.cloneNode( true ).lastChild.defaultValue;\n\n\t// #11217 - WebKit loses check when the name is after the checked attribute\n\tfragment.appendChild( div );\n\tdiv.innerHTML = \"<input type='radio' checked='checked' name='t'/>\";\n\n\t// Support: Safari 5.1, iOS 5.1, Android 4.x, Android 2.3\n\t// old WebKit doesn't clone checked state correctly in fragments\n\tsupport.checkClone = div.cloneNode( true ).cloneNode( true ).lastChild.checked;\n\n\t// Support: IE<9\n\t// Opera does not clone events (and typeof div.attachEvent === undefined).\n\t// IE9-10 clones events bound via attachEvent, but they don't trigger with .click()\n\tsupport.noCloneEvent = true;\n\tif ( div.attachEvent ) {\n\t\tdiv.attachEvent( \"onclick\", function() {\n\t\t\tsupport.noCloneEvent = false;\n\t\t});\n\n\t\tdiv.cloneNode( true ).click();\n\t}\n\n\t// Execute the test only if not already executed in another module.\n\tif (support.deleteExpando == null) {\n\t\t// Support: IE<9\n\t\tsupport.deleteExpando = true;\n\t\ttry {\n\t\t\tdelete div.test;\n\t\t} catch( e ) {\n\t\t\tsupport.deleteExpando = false;\n\t\t}\n\t}\n})();\n\n\n(function() {\n\tvar i, eventName,\n\t\tdiv = document.createElement( \"div\" );\n\n\t// Support: IE<9 (lack submit/change bubble), Firefox 23+ (lack focusin event)\n\tfor ( i in { submit: true, change: true, focusin: true }) {\n\t\teventName = \"on\" + i;\n\n\t\tif ( !(support[ i + \"Bubbles\" ] = eventName in window) ) {\n\t\t\t// Beware of CSP restrictions (https://developer.mozilla.org/en/Security/CSP)\n\t\t\tdiv.setAttribute( eventName, \"t\" );\n\t\t\tsupport[ i + \"Bubbles\" ] = div.attributes[ eventName ].expando === false;\n\t\t}\n\t}\n\n\t// Null elements to avoid leaks in IE.\n\tdiv = null;\n})();\n\n\nvar rformElems = /^(?:input|select|textarea)$/i,\n\trkeyEvent = /^key/,\n\trmouseEvent = /^(?:mouse|pointer|contextmenu)|click/,\n\trfocusMorph = /^(?:focusinfocus|focusoutblur)$/,\n\trtypenamespace = /^([^.]*)(?:\\.(.+)|)$/;\n\nfunction returnTrue() {\n\treturn true;\n}\n\nfunction returnFalse() {\n\treturn false;\n}\n\nfunction safeActiveElement() {\n\ttry {\n\t\treturn document.activeElement;\n\t} catch ( err ) { }\n}\n\n/*\n * Helper functions for managing events -- not part of the public interface.\n * Props to Dean Edwards' addEvent library for many of the ideas.\n */\njQuery.event = {\n\n\tglobal: {},\n\n\tadd: function( elem, types, handler, data, selector ) {\n\t\tvar tmp, events, t, handleObjIn,\n\t\t\tspecial, eventHandle, handleObj,\n\t\t\thandlers, type, namespaces, origType,\n\t\t\telemData = jQuery._data( elem );\n\n\t\t// Don't attach events to noData or text/comment nodes (but allow plain objects)\n\t\tif ( !elemData ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Caller can pass in an object of custom data in lieu of the handler\n\t\tif ( handler.handler ) {\n\t\t\thandleObjIn = handler;\n\t\t\thandler = handleObjIn.handler;\n\t\t\tselector = handleObjIn.selector;\n\t\t}\n\n\t\t// Make sure that the handler has a unique ID, used to find/remove it later\n\t\tif ( !handler.guid ) {\n\t\t\thandler.guid = jQuery.guid++;\n\t\t}\n\n\t\t// Init the element's event structure and main handler, if this is the first\n\t\tif ( !(events = elemData.events) ) {\n\t\t\tevents = elemData.events = {};\n\t\t}\n\t\tif ( !(eventHandle = elemData.handle) ) {\n\t\t\teventHandle = elemData.handle = function( e ) {\n\t\t\t\t// Discard the second event of a jQuery.event.trigger() and\n\t\t\t\t// when an event is called after a page has unloaded\n\t\t\t\treturn typeof jQuery !== strundefined && (!e || jQuery.event.triggered !== e.type) ?\n\t\t\t\t\tjQuery.event.dispatch.apply( eventHandle.elem, arguments ) :\n\t\t\t\t\tundefined;\n\t\t\t};\n\t\t\t// Add elem as a property of the handle fn to prevent a memory leak with IE non-native events\n\t\t\teventHandle.elem = elem;\n\t\t}\n\n\t\t// Handle multiple events separated by a space\n\t\ttypes = ( types || \"\" ).match( rnotwhite ) || [ \"\" ];\n\t\tt = types.length;\n\t\twhile ( t-- ) {\n\t\t\ttmp = rtypenamespace.exec( types[t] ) || [];\n\t\t\ttype = origType = tmp[1];\n\t\t\tnamespaces = ( tmp[2] || \"\" ).split( \".\" ).sort();\n\n\t\t\t// There *must* be a type, no attaching namespace-only handlers\n\t\t\tif ( !type ) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\t// If event changes its type, use the special event handlers for the changed type\n\t\t\tspecial = jQuery.event.special[ type ] || {};\n\n\t\t\t// If selector defined, determine special event api type, otherwise given type\n\t\t\ttype = ( selector ? special.delegateType : special.bindType ) || type;\n\n\t\t\t// Update special based on newly reset type\n\t\t\tspecial = jQuery.event.special[ type ] || {};\n\n\t\t\t// handleObj is passed to all event handlers\n\t\t\thandleObj = jQuery.extend({\n\t\t\t\ttype: type,\n\t\t\t\torigType: origType,\n\t\t\t\tdata: data,\n\t\t\t\thandler: handler,\n\t\t\t\tguid: handler.guid,\n\t\t\t\tselector: selector,\n\t\t\t\tneedsContext: selector && jQuery.expr.match.needsContext.test( selector ),\n\t\t\t\tnamespace: namespaces.join(\".\")\n\t\t\t}, handleObjIn );\n\n\t\t\t// Init the event handler queue if we're the first\n\t\t\tif ( !(handlers = events[ type ]) ) {\n\t\t\t\thandlers = events[ type ] = [];\n\t\t\t\thandlers.delegateCount = 0;\n\n\t\t\t\t// Only use addEventListener/attachEvent if the special events handler returns false\n\t\t\t\tif ( !special.setup || special.setup.call( elem, data, namespaces, eventHandle ) === false ) {\n\t\t\t\t\t// Bind the global event handler to the element\n\t\t\t\t\tif ( elem.addEventListener ) {\n\t\t\t\t\t\telem.addEventListener( type, eventHandle, false );\n\n\t\t\t\t\t} else if ( elem.attachEvent ) {\n\t\t\t\t\t\telem.attachEvent( \"on\" + type, eventHandle );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif ( special.add ) {\n\t\t\t\tspecial.add.call( elem, handleObj );\n\n\t\t\t\tif ( !handleObj.handler.guid ) {\n\t\t\t\t\thandleObj.handler.guid = handler.guid;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Add to the element's handler list, delegates in front\n\t\t\tif ( selector ) {\n\t\t\t\thandlers.splice( handlers.delegateCount++, 0, handleObj );\n\t\t\t} else {\n\t\t\t\thandlers.push( handleObj );\n\t\t\t}\n\n\t\t\t// Keep track of which events have ever been used, for event optimization\n\t\t\tjQuery.event.global[ type ] = true;\n\t\t}\n\n\t\t// Nullify elem to prevent memory leaks in IE\n\t\telem = null;\n\t},\n\n\t// Detach an event or set of events from an element\n\tremove: function( elem, types, handler, selector, mappedTypes ) {\n\t\tvar j, handleObj, tmp,\n\t\t\torigCount, t, events,\n\t\t\tspecial, handlers, type,\n\t\t\tnamespaces, origType,\n\t\t\telemData = jQuery.hasData( elem ) && jQuery._data( elem );\n\n\t\tif ( !elemData || !(events = elemData.events) ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Once for each type.namespace in types; type may be omitted\n\t\ttypes = ( types || \"\" ).match( rnotwhite ) || [ \"\" ];\n\t\tt = types.length;\n\t\twhile ( t-- ) {\n\t\t\ttmp = rtypenamespace.exec( types[t] ) || [];\n\t\t\ttype = origType = tmp[1];\n\t\t\tnamespaces = ( tmp[2] || \"\" ).split( \".\" ).sort();\n\n\t\t\t// Unbind all events (on this namespace, if provided) for the element\n\t\t\tif ( !type ) {\n\t\t\t\tfor ( type in events ) {\n\t\t\t\t\tjQuery.event.remove( elem, type + types[ t ], handler, selector, true );\n\t\t\t\t}\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tspecial = jQuery.event.special[ type ] || {};\n\t\t\ttype = ( selector ? special.delegateType : special.bindType ) || type;\n\t\t\thandlers = events[ type ] || [];\n\t\t\ttmp = tmp[2] && new RegExp( \"(^|\\\\.)\" + namespaces.join(\"\\\\.(?:.*\\\\.|)\") + \"(\\\\.|$)\" );\n\n\t\t\t// Remove matching events\n\t\t\torigCount = j = handlers.length;\n\t\t\twhile ( j-- ) {\n\t\t\t\thandleObj = handlers[ j ];\n\n\t\t\t\tif ( ( mappedTypes || origType === handleObj.origType ) &&\n\t\t\t\t\t( !handler || handler.guid === handleObj.guid ) &&\n\t\t\t\t\t( !tmp || tmp.test( handleObj.namespace ) ) &&\n\t\t\t\t\t( !selector || selector === handleObj.selector || selector === \"**\" && handleObj.selector ) ) {\n\t\t\t\t\thandlers.splice( j, 1 );\n\n\t\t\t\t\tif ( handleObj.selector ) {\n\t\t\t\t\t\thandlers.delegateCount--;\n\t\t\t\t\t}\n\t\t\t\t\tif ( special.remove ) {\n\t\t\t\t\t\tspecial.remove.call( elem, handleObj );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Remove generic event handler if we removed something and no more handlers exist\n\t\t\t// (avoids potential for endless recursion during removal of special event handlers)\n\t\t\tif ( origCount && !handlers.length ) {\n\t\t\t\tif ( !special.teardown || special.teardown.call( elem, namespaces, elemData.handle ) === false ) {\n\t\t\t\t\tjQuery.removeEvent( elem, type, elemData.handle );\n\t\t\t\t}\n\n\t\t\t\tdelete events[ type ];\n\t\t\t}\n\t\t}\n\n\t\t// Remove the expando if it's no longer used\n\t\tif ( jQuery.isEmptyObject( events ) ) {\n\t\t\tdelete elemData.handle;\n\n\t\t\t// removeData also checks for emptiness and clears the expando if empty\n\t\t\t// so use it instead of delete\n\t\t\tjQuery._removeData( elem, \"events\" );\n\t\t}\n\t},\n\n\ttrigger: function( event, data, elem, onlyHandlers ) {\n\t\tvar handle, ontype, cur,\n\t\t\tbubbleType, special, tmp, i,\n\t\t\teventPath = [ elem || document ],\n\t\t\ttype = hasOwn.call( event, \"type\" ) ? event.type : event,\n\t\t\tnamespaces = hasOwn.call( event, \"namespace\" ) ? event.namespace.split(\".\") : [];\n\n\t\tcur = tmp = elem = elem || document;\n\n\t\t// Don't do events on text and comment nodes\n\t\tif ( elem.nodeType === 3 || elem.nodeType === 8 ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// focus/blur morphs to focusin/out; ensure we're not firing them right now\n\t\tif ( rfocusMorph.test( type + jQuery.event.triggered ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\tif ( type.indexOf(\".\") >= 0 ) {\n\t\t\t// Namespaced trigger; create a regexp to match event type in handle()\n\t\t\tnamespaces = type.split(\".\");\n\t\t\ttype = namespaces.shift();\n\t\t\tnamespaces.sort();\n\t\t}\n\t\tontype = type.indexOf(\":\") < 0 && \"on\" + type;\n\n\t\t// Caller can pass in a jQuery.Event object, Object, or just an event type string\n\t\tevent = event[ jQuery.expando ] ?\n\t\t\tevent :\n\t\t\tnew jQuery.Event( type, typeof event === \"object\" && event );\n\n\t\t// Trigger bitmask: & 1 for native handlers; & 2 for jQuery (always true)\n\t\tevent.isTrigger = onlyHandlers ? 2 : 3;\n\t\tevent.namespace = namespaces.join(\".\");\n\t\tevent.namespace_re = event.namespace ?\n\t\t\tnew RegExp( \"(^|\\\\.)\" + namespaces.join(\"\\\\.(?:.*\\\\.|)\") + \"(\\\\.|$)\" ) :\n\t\t\tnull;\n\n\t\t// Clean up the event in case it is being reused\n\t\tevent.result = undefined;\n\t\tif ( !event.target ) {\n\t\t\tevent.target = elem;\n\t\t}\n\n\t\t// Clone any incoming data and prepend the event, creating the handler arg list\n\t\tdata = data == null ?\n\t\t\t[ event ] :\n\t\t\tjQuery.makeArray( data, [ event ] );\n\n\t\t// Allow special events to draw outside the lines\n\t\tspecial = jQuery.event.special[ type ] || {};\n\t\tif ( !onlyHandlers && special.trigger && special.trigger.apply( elem, data ) === false ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Determine event propagation path in advance, per W3C events spec (#9951)\n\t\t// Bubble up to document, then to window; watch for a global ownerDocument var (#9724)\n\t\tif ( !onlyHandlers && !special.noBubble && !jQuery.isWindow( elem ) ) {\n\n\t\t\tbubbleType = special.delegateType || type;\n\t\t\tif ( !rfocusMorph.test( bubbleType + type ) ) {\n\t\t\t\tcur = cur.parentNode;\n\t\t\t}\n\t\t\tfor ( ; cur; cur = cur.parentNode ) {\n\t\t\t\teventPath.push( cur );\n\t\t\t\ttmp = cur;\n\t\t\t}\n\n\t\t\t// Only add window if we got to document (e.g., not plain obj or detached DOM)\n\t\t\tif ( tmp === (elem.ownerDocument || document) ) {\n\t\t\t\teventPath.push( tmp.defaultView || tmp.parentWindow || window );\n\t\t\t}\n\t\t}\n\n\t\t// Fire handlers on the event path\n\t\ti = 0;\n\t\twhile ( (cur = eventPath[i++]) && !event.isPropagationStopped() ) {\n\n\t\t\tevent.type = i > 1 ?\n\t\t\t\tbubbleType :\n\t\t\t\tspecial.bindType || type;\n\n\t\t\t// jQuery handler\n\t\t\thandle = ( jQuery._data( cur, \"events\" ) || {} )[ event.type ] && jQuery._data( cur, \"handle\" );\n\t\t\tif ( handle ) {\n\t\t\t\thandle.apply( cur, data );\n\t\t\t}\n\n\t\t\t// Native handler\n\t\t\thandle = ontype && cur[ ontype ];\n\t\t\tif ( handle && handle.apply && jQuery.acceptData( cur ) ) {\n\t\t\t\tevent.result = handle.apply( cur, data );\n\t\t\t\tif ( event.result === false ) {\n\t\t\t\t\tevent.preventDefault();\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tevent.type = type;\n\n\t\t// If nobody prevented the default action, do it now\n\t\tif ( !onlyHandlers && !event.isDefaultPrevented() ) {\n\n\t\t\tif ( (!special._default || special._default.apply( eventPath.pop(), data ) === false) &&\n\t\t\t\tjQuery.acceptData( elem ) ) {\n\n\t\t\t\t// Call a native DOM method on the target with the same name name as the event.\n\t\t\t\t// Can't use an .isFunction() check here because IE6/7 fails that test.\n\t\t\t\t// Don't do default actions on window, that's where global variables be (#6170)\n\t\t\t\tif ( ontype && elem[ type ] && !jQuery.isWindow( elem ) ) {\n\n\t\t\t\t\t// Don't re-trigger an onFOO event when we call its FOO() method\n\t\t\t\t\ttmp = elem[ ontype ];\n\n\t\t\t\t\tif ( tmp ) {\n\t\t\t\t\t\telem[ ontype ] = null;\n\t\t\t\t\t}\n\n\t\t\t\t\t// Prevent re-triggering of the same event, since we already bubbled it above\n\t\t\t\t\tjQuery.event.triggered = type;\n\t\t\t\t\ttry {\n\t\t\t\t\t\telem[ type ]();\n\t\t\t\t\t} catch ( e ) {\n\t\t\t\t\t\t// IE<9 dies on focus/blur to hidden element (#1486,#12518)\n\t\t\t\t\t\t// only reproducible on winXP IE8 native, not IE9 in IE8 mode\n\t\t\t\t\t}\n\t\t\t\t\tjQuery.event.triggered = undefined;\n\n\t\t\t\t\tif ( tmp ) {\n\t\t\t\t\t\telem[ ontype ] = tmp;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn event.result;\n\t},\n\n\tdispatch: function( event ) {\n\n\t\t// Make a writable jQuery.Event from the native event object\n\t\tevent = jQuery.event.fix( event );\n\n\t\tvar i, ret, handleObj, matched, j,\n\t\t\thandlerQueue = [],\n\t\t\targs = slice.call( arguments ),\n\t\t\thandlers = ( jQuery._data( this, \"events\" ) || {} )[ event.type ] || [],\n\t\t\tspecial = jQuery.event.special[ event.type ] || {};\n\n\t\t// Use the fix-ed jQuery.Event rather than the (read-only) native event\n\t\targs[0] = event;\n\t\tevent.delegateTarget = this;\n\n\t\t// Call the preDispatch hook for the mapped type, and let it bail if desired\n\t\tif ( special.preDispatch && special.preDispatch.call( this, event ) === false ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Determine handlers\n\t\thandlerQueue = jQuery.event.handlers.call( this, event, handlers );\n\n\t\t// Run delegates first; they may want to stop propagation beneath us\n\t\ti = 0;\n\t\twhile ( (matched = handlerQueue[ i++ ]) && !event.isPropagationStopped() ) {\n\t\t\tevent.currentTarget = matched.elem;\n\n\t\t\tj = 0;\n\t\t\twhile ( (handleObj = matched.handlers[ j++ ]) && !event.isImmediatePropagationStopped() ) {\n\n\t\t\t\t// Triggered event must either 1) have no namespace, or\n\t\t\t\t// 2) have namespace(s) a subset or equal to those in the bound event (both can have no namespace).\n\t\t\t\tif ( !event.namespace_re || event.namespace_re.test( handleObj.namespace ) ) {\n\n\t\t\t\t\tevent.handleObj = handleObj;\n\t\t\t\t\tevent.data = handleObj.data;\n\n\t\t\t\t\tret = ( (jQuery.event.special[ handleObj.origType ] || {}).handle || handleObj.handler )\n\t\t\t\t\t\t\t.apply( matched.elem, args );\n\n\t\t\t\t\tif ( ret !== undefined ) {\n\t\t\t\t\t\tif ( (event.result = ret) === false ) {\n\t\t\t\t\t\t\tevent.preventDefault();\n\t\t\t\t\t\t\tevent.stopPropagation();\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Call the postDispatch hook for the mapped type\n\t\tif ( special.postDispatch ) {\n\t\t\tspecial.postDispatch.call( this, event );\n\t\t}\n\n\t\treturn event.result;\n\t},\n\n\thandlers: function( event, handlers ) {\n\t\tvar sel, handleObj, matches, i,\n\t\t\thandlerQueue = [],\n\t\t\tdelegateCount = handlers.delegateCount,\n\t\t\tcur = event.target;\n\n\t\t// Find delegate handlers\n\t\t// Black-hole SVG <use> instance trees (#13180)\n\t\t// Avoid non-left-click bubbling in Firefox (#3861)\n\t\tif ( delegateCount && cur.nodeType && (!event.button || event.type !== \"click\") ) {\n\n\t\t\t/* jshint eqeqeq: false */\n\t\t\tfor ( ; cur != this; cur = cur.parentNode || this ) {\n\t\t\t\t/* jshint eqeqeq: true */\n\n\t\t\t\t// Don't check non-elements (#13208)\n\t\t\t\t// Don't process clicks on disabled elements (#6911, #8165, #11382, #11764)\n\t\t\t\tif ( cur.nodeType === 1 && (cur.disabled !== true || event.type !== \"click\") ) {\n\t\t\t\t\tmatches = [];\n\t\t\t\t\tfor ( i = 0; i < delegateCount; i++ ) {\n\t\t\t\t\t\thandleObj = handlers[ i ];\n\n\t\t\t\t\t\t// Don't conflict with Object.prototype properties (#13203)\n\t\t\t\t\t\tsel = handleObj.selector + \" \";\n\n\t\t\t\t\t\tif ( matches[ sel ] === undefined ) {\n\t\t\t\t\t\t\tmatches[ sel ] = handleObj.needsContext ?\n\t\t\t\t\t\t\t\tjQuery( sel, this ).index( cur ) >= 0 :\n\t\t\t\t\t\t\t\tjQuery.find( sel, this, null, [ cur ] ).length;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif ( matches[ sel ] ) {\n\t\t\t\t\t\t\tmatches.push( handleObj );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tif ( matches.length ) {\n\t\t\t\t\t\thandlerQueue.push({ elem: cur, handlers: matches });\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Add the remaining (directly-bound) handlers\n\t\tif ( delegateCount < handlers.length ) {\n\t\t\thandlerQueue.push({ elem: this, handlers: handlers.slice( delegateCount ) });\n\t\t}\n\n\t\treturn handlerQueue;\n\t},\n\n\tfix: function( event ) {\n\t\tif ( event[ jQuery.expando ] ) {\n\t\t\treturn event;\n\t\t}\n\n\t\t// Create a writable copy of the event object and normalize some properties\n\t\tvar i, prop, copy,\n\t\t\ttype = event.type,\n\t\t\toriginalEvent = event,\n\t\t\tfixHook = this.fixHooks[ type ];\n\n\t\tif ( !fixHook ) {\n\t\t\tthis.fixHooks[ type ] = fixHook =\n\t\t\t\trmouseEvent.test( type ) ? this.mouseHooks :\n\t\t\t\trkeyEvent.test( type ) ? this.keyHooks :\n\t\t\t\t{};\n\t\t}\n\t\tcopy = fixHook.props ? this.props.concat( fixHook.props ) : this.props;\n\n\t\tevent = new jQuery.Event( originalEvent );\n\n\t\ti = copy.length;\n\t\twhile ( i-- ) {\n\t\t\tprop = copy[ i ];\n\t\t\tevent[ prop ] = originalEvent[ prop ];\n\t\t}\n\n\t\t// Support: IE<9\n\t\t// Fix target property (#1925)\n\t\tif ( !event.target ) {\n\t\t\tevent.target = originalEvent.srcElement || document;\n\t\t}\n\n\t\t// Support: Chrome 23+, Safari?\n\t\t// Target should not be a text node (#504, #13143)\n\t\tif ( event.target.nodeType === 3 ) {\n\t\t\tevent.target = event.target.parentNode;\n\t\t}\n\n\t\t// Support: IE<9\n\t\t// For mouse/key events, metaKey==false if it's undefined (#3368, #11328)\n\t\tevent.metaKey = !!event.metaKey;\n\n\t\treturn fixHook.filter ? fixHook.filter( event, originalEvent ) : event;\n\t},\n\n\t// Includes some event props shared by KeyEvent and MouseEvent\n\tprops: \"altKey bubbles cancelable ctrlKey currentTarget eventPhase metaKey relatedTarget shiftKey target timeStamp view which\".split(\" \"),\n\n\tfixHooks: {},\n\n\tkeyHooks: {\n\t\tprops: \"char charCode key keyCode\".split(\" \"),\n\t\tfilter: function( event, original ) {\n\n\t\t\t// Add which for key events\n\t\t\tif ( event.which == null ) {\n\t\t\t\tevent.which = original.charCode != null ? original.charCode : original.keyCode;\n\t\t\t}\n\n\t\t\treturn event;\n\t\t}\n\t},\n\n\tmouseHooks: {\n\t\tprops: \"button buttons clientX clientY fromElement offsetX offsetY pageX pageY screenX screenY toElement\".split(\" \"),\n\t\tfilter: function( event, original ) {\n\t\t\tvar body, eventDoc, doc,\n\t\t\t\tbutton = original.button,\n\t\t\t\tfromElement = original.fromElement;\n\n\t\t\t// Calculate pageX/Y if missing and clientX/Y available\n\t\t\tif ( event.pageX == null && original.clientX != null ) {\n\t\t\t\teventDoc = event.target.ownerDocument || document;\n\t\t\t\tdoc = eventDoc.documentElement;\n\t\t\t\tbody = eventDoc.body;\n\n\t\t\t\tevent.pageX = original.clientX + ( doc && doc.scrollLeft || body && body.scrollLeft || 0 ) - ( doc && doc.clientLeft || body && body.clientLeft || 0 );\n\t\t\t\tevent.pageY = original.clientY + ( doc && doc.scrollTop  || body && body.scrollTop  || 0 ) - ( doc && doc.clientTop  || body && body.clientTop  || 0 );\n\t\t\t}\n\n\t\t\t// Add relatedTarget, if necessary\n\t\t\tif ( !event.relatedTarget && fromElement ) {\n\t\t\t\tevent.relatedTarget = fromElement === event.target ? original.toElement : fromElement;\n\t\t\t}\n\n\t\t\t// Add which for click: 1 === left; 2 === middle; 3 === right\n\t\t\t// Note: button is not normalized, so don't use it\n\t\t\tif ( !event.which && button !== undefined ) {\n\t\t\t\tevent.which = ( button & 1 ? 1 : ( button & 2 ? 3 : ( button & 4 ? 2 : 0 ) ) );\n\t\t\t}\n\n\t\t\treturn event;\n\t\t}\n\t},\n\n\tspecial: {\n\t\tload: {\n\t\t\t// Prevent triggered image.load events from bubbling to window.load\n\t\t\tnoBubble: true\n\t\t},\n\t\tfocus: {\n\t\t\t// Fire native event if possible so blur/focus sequence is correct\n\t\t\ttrigger: function() {\n\t\t\t\tif ( this !== safeActiveElement() && this.focus ) {\n\t\t\t\t\ttry {\n\t\t\t\t\t\tthis.focus();\n\t\t\t\t\t\treturn false;\n\t\t\t\t\t} catch ( e ) {\n\t\t\t\t\t\t// Support: IE<9\n\t\t\t\t\t\t// If we error on focus to hidden element (#1486, #12518),\n\t\t\t\t\t\t// let .trigger() run the handlers\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t},\n\t\t\tdelegateType: \"focusin\"\n\t\t},\n\t\tblur: {\n\t\t\ttrigger: function() {\n\t\t\t\tif ( this === safeActiveElement() && this.blur ) {\n\t\t\t\t\tthis.blur();\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t},\n\t\t\tdelegateType: \"focusout\"\n\t\t},\n\t\tclick: {\n\t\t\t// For checkbox, fire native event so checked state will be right\n\t\t\ttrigger: function() {\n\t\t\t\tif ( jQuery.nodeName( this, \"input\" ) && this.type === \"checkbox\" && this.click ) {\n\t\t\t\t\tthis.click();\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t},\n\n\t\t\t// For cross-browser consistency, don't fire native .click() on links\n\t\t\t_default: function( event ) {\n\t\t\t\treturn jQuery.nodeName( event.target, \"a\" );\n\t\t\t}\n\t\t},\n\n\t\tbeforeunload: {\n\t\t\tpostDispatch: function( event ) {\n\n\t\t\t\t// Support: Firefox 20+\n\t\t\t\t// Firefox doesn't alert if the returnValue field is not set.\n\t\t\t\tif ( event.result !== undefined && event.originalEvent ) {\n\t\t\t\t\tevent.originalEvent.returnValue = event.result;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t},\n\n\tsimulate: function( type, elem, event, bubble ) {\n\t\t// Piggyback on a donor event to simulate a different one.\n\t\t// Fake originalEvent to avoid donor's stopPropagation, but if the\n\t\t// simulated event prevents default then we do the same on the donor.\n\t\tvar e = jQuery.extend(\n\t\t\tnew jQuery.Event(),\n\t\t\tevent,\n\t\t\t{\n\t\t\t\ttype: type,\n\t\t\t\tisSimulated: true,\n\t\t\t\toriginalEvent: {}\n\t\t\t}\n\t\t);\n\t\tif ( bubble ) {\n\t\t\tjQuery.event.trigger( e, null, elem );\n\t\t} else {\n\t\t\tjQuery.event.dispatch.call( elem, e );\n\t\t}\n\t\tif ( e.isDefaultPrevented() ) {\n\t\t\tevent.preventDefault();\n\t\t}\n\t}\n};\n\njQuery.removeEvent = document.removeEventListener ?\n\tfunction( elem, type, handle ) {\n\t\tif ( elem.removeEventListener ) {\n\t\t\telem.removeEventListener( type, handle, false );\n\t\t}\n\t} :\n\tfunction( elem, type, handle ) {\n\t\tvar name = \"on\" + type;\n\n\t\tif ( elem.detachEvent ) {\n\n\t\t\t// #8545, #7054, preventing memory leaks for custom events in IE6-8\n\t\t\t// detachEvent needed property on element, by name of that event, to properly expose it to GC\n\t\t\tif ( typeof elem[ name ] === strundefined ) {\n\t\t\t\telem[ name ] = null;\n\t\t\t}\n\n\t\t\telem.detachEvent( name, handle );\n\t\t}\n\t};\n\njQuery.Event = function( src, props ) {\n\t// Allow instantiation without the 'new' keyword\n\tif ( !(this instanceof jQuery.Event) ) {\n\t\treturn new jQuery.Event( src, props );\n\t}\n\n\t// Event object\n\tif ( src && src.type ) {\n\t\tthis.originalEvent = src;\n\t\tthis.type = src.type;\n\n\t\t// Events bubbling up the document may have been marked as prevented\n\t\t// by a handler lower down the tree; reflect the correct value.\n\t\tthis.isDefaultPrevented = src.defaultPrevented ||\n\t\t\t\tsrc.defaultPrevented === undefined &&\n\t\t\t\t// Support: IE < 9, Android < 4.0\n\t\t\t\tsrc.returnValue === false ?\n\t\t\treturnTrue :\n\t\t\treturnFalse;\n\n\t// Event type\n\t} else {\n\t\tthis.type = src;\n\t}\n\n\t// Put explicitly provided properties onto the event object\n\tif ( props ) {\n\t\tjQuery.extend( this, props );\n\t}\n\n\t// Create a timestamp if incoming event doesn't have one\n\tthis.timeStamp = src && src.timeStamp || jQuery.now();\n\n\t// Mark it as fixed\n\tthis[ jQuery.expando ] = true;\n};\n\n// jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding\n// http://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html\njQuery.Event.prototype = {\n\tisDefaultPrevented: returnFalse,\n\tisPropagationStopped: returnFalse,\n\tisImmediatePropagationStopped: returnFalse,\n\n\tpreventDefault: function() {\n\t\tvar e = this.originalEvent;\n\n\t\tthis.isDefaultPrevented = returnTrue;\n\t\tif ( !e ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// If preventDefault exists, run it on the original event\n\t\tif ( e.preventDefault ) {\n\t\t\te.preventDefault();\n\n\t\t// Support: IE\n\t\t// Otherwise set the returnValue property of the original event to false\n\t\t} else {\n\t\t\te.returnValue = false;\n\t\t}\n\t},\n\tstopPropagation: function() {\n\t\tvar e = this.originalEvent;\n\n\t\tthis.isPropagationStopped = returnTrue;\n\t\tif ( !e ) {\n\t\t\treturn;\n\t\t}\n\t\t// If stopPropagation exists, run it on the original event\n\t\tif ( e.stopPropagation ) {\n\t\t\te.stopPropagation();\n\t\t}\n\n\t\t// Support: IE\n\t\t// Set the cancelBubble property of the original event to true\n\t\te.cancelBubble = true;\n\t},\n\tstopImmediatePropagation: function() {\n\t\tvar e = this.originalEvent;\n\n\t\tthis.isImmediatePropagationStopped = returnTrue;\n\n\t\tif ( e && e.stopImmediatePropagation ) {\n\t\t\te.stopImmediatePropagation();\n\t\t}\n\n\t\tthis.stopPropagation();\n\t}\n};\n\n// Create mouseenter/leave events using mouseover/out and event-time checks\njQuery.each({\n\tmouseenter: \"mouseover\",\n\tmouseleave: \"mouseout\",\n\tpointerenter: \"pointerover\",\n\tpointerleave: \"pointerout\"\n}, function( orig, fix ) {\n\tjQuery.event.special[ orig ] = {\n\t\tdelegateType: fix,\n\t\tbindType: fix,\n\n\t\thandle: function( event ) {\n\t\t\tvar ret,\n\t\t\t\ttarget = this,\n\t\t\t\trelated = event.relatedTarget,\n\t\t\t\thandleObj = event.handleObj;\n\n\t\t\t// For mousenter/leave call the handler if related is outside the target.\n\t\t\t// NB: No relatedTarget if the mouse left/entered the browser window\n\t\t\tif ( !related || (related !== target && !jQuery.contains( target, related )) ) {\n\t\t\t\tevent.type = handleObj.origType;\n\t\t\t\tret = handleObj.handler.apply( this, arguments );\n\t\t\t\tevent.type = fix;\n\t\t\t}\n\t\t\treturn ret;\n\t\t}\n\t};\n});\n\n// IE submit delegation\nif ( !support.submitBubbles ) {\n\n\tjQuery.event.special.submit = {\n\t\tsetup: function() {\n\t\t\t// Only need this for delegated form submit events\n\t\t\tif ( jQuery.nodeName( this, \"form\" ) ) {\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\t// Lazy-add a submit handler when a descendant form may potentially be submitted\n\t\t\tjQuery.event.add( this, \"click._submit keypress._submit\", function( e ) {\n\t\t\t\t// Node name check avoids a VML-related crash in IE (#9807)\n\t\t\t\tvar elem = e.target,\n\t\t\t\t\tform = jQuery.nodeName( elem, \"input\" ) || jQuery.nodeName( elem, \"button\" ) ? elem.form : undefined;\n\t\t\t\tif ( form && !jQuery._data( form, \"submitBubbles\" ) ) {\n\t\t\t\t\tjQuery.event.add( form, \"submit._submit\", function( event ) {\n\t\t\t\t\t\tevent._submit_bubble = true;\n\t\t\t\t\t});\n\t\t\t\t\tjQuery._data( form, \"submitBubbles\", true );\n\t\t\t\t}\n\t\t\t});\n\t\t\t// return undefined since we don't need an event listener\n\t\t},\n\n\t\tpostDispatch: function( event ) {\n\t\t\t// If form was submitted by the user, bubble the event up the tree\n\t\t\tif ( event._submit_bubble ) {\n\t\t\t\tdelete event._submit_bubble;\n\t\t\t\tif ( this.parentNode && !event.isTrigger ) {\n\t\t\t\t\tjQuery.event.simulate( \"submit\", this.parentNode, event, true );\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\n\t\tteardown: function() {\n\t\t\t// Only need this for delegated form submit events\n\t\t\tif ( jQuery.nodeName( this, \"form\" ) ) {\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\t// Remove delegated handlers; cleanData eventually reaps submit handlers attached above\n\t\t\tjQuery.event.remove( this, \"._submit\" );\n\t\t}\n\t};\n}\n\n// IE change delegation and checkbox/radio fix\nif ( !support.changeBubbles ) {\n\n\tjQuery.event.special.change = {\n\n\t\tsetup: function() {\n\n\t\t\tif ( rformElems.test( this.nodeName ) ) {\n\t\t\t\t// IE doesn't fire change on a check/radio until blur; trigger it on click\n\t\t\t\t// after a propertychange. Eat the blur-change in special.change.handle.\n\t\t\t\t// This still fires onchange a second time for check/radio after blur.\n\t\t\t\tif ( this.type === \"checkbox\" || this.type === \"radio\" ) {\n\t\t\t\t\tjQuery.event.add( this, \"propertychange._change\", function( event ) {\n\t\t\t\t\t\tif ( event.originalEvent.propertyName === \"checked\" ) {\n\t\t\t\t\t\t\tthis._just_changed = true;\n\t\t\t\t\t\t}\n\t\t\t\t\t});\n\t\t\t\t\tjQuery.event.add( this, \"click._change\", function( event ) {\n\t\t\t\t\t\tif ( this._just_changed && !event.isTrigger ) {\n\t\t\t\t\t\t\tthis._just_changed = false;\n\t\t\t\t\t\t}\n\t\t\t\t\t\t// Allow triggered, simulated change events (#11500)\n\t\t\t\t\t\tjQuery.event.simulate( \"change\", this, event, true );\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\t// Delegated event; lazy-add a change handler on descendant inputs\n\t\t\tjQuery.event.add( this, \"beforeactivate._change\", function( e ) {\n\t\t\t\tvar elem = e.target;\n\n\t\t\t\tif ( rformElems.test( elem.nodeName ) && !jQuery._data( elem, \"changeBubbles\" ) ) {\n\t\t\t\t\tjQuery.event.add( elem, \"change._change\", function( event ) {\n\t\t\t\t\t\tif ( this.parentNode && !event.isSimulated && !event.isTrigger ) {\n\t\t\t\t\t\t\tjQuery.event.simulate( \"change\", this.parentNode, event, true );\n\t\t\t\t\t\t}\n\t\t\t\t\t});\n\t\t\t\t\tjQuery._data( elem, \"changeBubbles\", true );\n\t\t\t\t}\n\t\t\t});\n\t\t},\n\n\t\thandle: function( event ) {\n\t\t\tvar elem = event.target;\n\n\t\t\t// Swallow native change events from checkbox/radio, we already triggered them above\n\t\t\tif ( this !== elem || event.isSimulated || event.isTrigger || (elem.type !== \"radio\" && elem.type !== \"checkbox\") ) {\n\t\t\t\treturn event.handleObj.handler.apply( this, arguments );\n\t\t\t}\n\t\t},\n\n\t\tteardown: function() {\n\t\t\tjQuery.event.remove( this, \"._change\" );\n\n\t\t\treturn !rformElems.test( this.nodeName );\n\t\t}\n\t};\n}\n\n// Create \"bubbling\" focus and blur events\nif ( !support.focusinBubbles ) {\n\tjQuery.each({ focus: \"focusin\", blur: \"focusout\" }, function( orig, fix ) {\n\n\t\t// Attach a single capturing handler on the document while someone wants focusin/focusout\n\t\tvar handler = function( event ) {\n\t\t\t\tjQuery.event.simulate( fix, event.target, jQuery.event.fix( event ), true );\n\t\t\t};\n\n\t\tjQuery.event.special[ fix ] = {\n\t\t\tsetup: function() {\n\t\t\t\tvar doc = this.ownerDocument || this,\n\t\t\t\t\tattaches = jQuery._data( doc, fix );\n\n\t\t\t\tif ( !attaches ) {\n\t\t\t\t\tdoc.addEventListener( orig, handler, true );\n\t\t\t\t}\n\t\t\t\tjQuery._data( doc, fix, ( attaches || 0 ) + 1 );\n\t\t\t},\n\t\t\tteardown: function() {\n\t\t\t\tvar doc = this.ownerDocument || this,\n\t\t\t\t\tattaches = jQuery._data( doc, fix ) - 1;\n\n\t\t\t\tif ( !attaches ) {\n\t\t\t\t\tdoc.removeEventListener( orig, handler, true );\n\t\t\t\t\tjQuery._removeData( doc, fix );\n\t\t\t\t} else {\n\t\t\t\t\tjQuery._data( doc, fix, attaches );\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\t});\n}\n\njQuery.fn.extend({\n\n\ton: function( types, selector, data, fn, /*INTERNAL*/ one ) {\n\t\tvar type, origFn;\n\n\t\t// Types can be a map of types/handlers\n\t\tif ( typeof types === \"object\" ) {\n\t\t\t// ( types-Object, selector, data )\n\t\t\tif ( typeof selector !== \"string\" ) {\n\t\t\t\t// ( types-Object, data )\n\t\t\t\tdata = data || selector;\n\t\t\t\tselector = undefined;\n\t\t\t}\n\t\t\tfor ( type in types ) {\n\t\t\t\tthis.on( type, selector, data, types[ type ], one );\n\t\t\t}\n\t\t\treturn this;\n\t\t}\n\n\t\tif ( data == null && fn == null ) {\n\t\t\t// ( types, fn )\n\t\t\tfn = selector;\n\t\t\tdata = selector = undefined;\n\t\t} else if ( fn == null ) {\n\t\t\tif ( typeof selector === \"string\" ) {\n\t\t\t\t// ( types, selector, fn )\n\t\t\t\tfn = data;\n\t\t\t\tdata = undefined;\n\t\t\t} else {\n\t\t\t\t// ( types, data, fn )\n\t\t\t\tfn = data;\n\t\t\t\tdata = selector;\n\t\t\t\tselector = undefined;\n\t\t\t}\n\t\t}\n\t\tif ( fn === false ) {\n\t\t\tfn = returnFalse;\n\t\t} else if ( !fn ) {\n\t\t\treturn this;\n\t\t}\n\n\t\tif ( one === 1 ) {\n\t\t\torigFn = fn;\n\t\t\tfn = function( event ) {\n\t\t\t\t// Can use an empty set, since event contains the info\n\t\t\t\tjQuery().off( event );\n\t\t\t\treturn origFn.apply( this, arguments );\n\t\t\t};\n\t\t\t// Use same guid so caller can remove using origFn\n\t\t\tfn.guid = origFn.guid || ( origFn.guid = jQuery.guid++ );\n\t\t}\n\t\treturn this.each( function() {\n\t\t\tjQuery.event.add( this, types, fn, data, selector );\n\t\t});\n\t},\n\tone: function( types, selector, data, fn ) {\n\t\treturn this.on( types, selector, data, fn, 1 );\n\t},\n\toff: function( types, selector, fn ) {\n\t\tvar handleObj, type;\n\t\tif ( types && types.preventDefault && types.handleObj ) {\n\t\t\t// ( event )  dispatched jQuery.Event\n\t\t\thandleObj = types.handleObj;\n\t\t\tjQuery( types.delegateTarget ).off(\n\t\t\t\thandleObj.namespace ? handleObj.origType + \".\" + handleObj.namespace : handleObj.origType,\n\t\t\t\thandleObj.selector,\n\t\t\t\thandleObj.handler\n\t\t\t);\n\t\t\treturn this;\n\t\t}\n\t\tif ( typeof types === \"object\" ) {\n\t\t\t// ( types-object [, selector] )\n\t\t\tfor ( type in types ) {\n\t\t\t\tthis.off( type, selector, types[ type ] );\n\t\t\t}\n\t\t\treturn this;\n\t\t}\n\t\tif ( selector === false || typeof selector === \"function\" ) {\n\t\t\t// ( types [, fn] )\n\t\t\tfn = selector;\n\t\t\tselector = undefined;\n\t\t}\n\t\tif ( fn === false ) {\n\t\t\tfn = returnFalse;\n\t\t}\n\t\treturn this.each(function() {\n\t\t\tjQuery.event.remove( this, types, fn, selector );\n\t\t});\n\t},\n\n\ttrigger: function( type, data ) {\n\t\treturn this.each(function() {\n\t\t\tjQuery.event.trigger( type, data, this );\n\t\t});\n\t},\n\ttriggerHandler: function( type, data ) {\n\t\tvar elem = this[0];\n\t\tif ( elem ) {\n\t\t\treturn jQuery.event.trigger( type, data, elem, true );\n\t\t}\n\t}\n});\n\n\nfunction createSafeFragment( document ) {\n\tvar list = nodeNames.split( \"|\" ),\n\t\tsafeFrag = document.createDocumentFragment();\n\n\tif ( safeFrag.createElement ) {\n\t\twhile ( list.length ) {\n\t\t\tsafeFrag.createElement(\n\t\t\t\tlist.pop()\n\t\t\t);\n\t\t}\n\t}\n\treturn safeFrag;\n}\n\nvar nodeNames = \"abbr|article|aside|audio|bdi|canvas|data|datalist|details|figcaption|figure|footer|\" +\n\t\t\"header|hgroup|mark|meter|nav|output|progress|section|summary|time|video\",\n\trinlinejQuery = / jQuery\\d+=\"(?:null|\\d+)\"/g,\n\trnoshimcache = new RegExp(\"<(?:\" + nodeNames + \")[\\\\s/>]\", \"i\"),\n\trleadingWhitespace = /^\\s+/,\n\trxhtmlTag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\\w:]+)[^>]*)\\/>/gi,\n\trtagName = /<([\\w:]+)/,\n\trtbody = /<tbody/i,\n\trhtml = /<|&#?\\w+;/,\n\trnoInnerhtml = /<(?:script|style|link)/i,\n\t// checked=\"checked\" or checked\n\trchecked = /checked\\s*(?:[^=]|=\\s*.checked.)/i,\n\trscriptType = /^$|\\/(?:java|ecma)script/i,\n\trscriptTypeMasked = /^true\\/(.*)/,\n\trcleanScript = /^\\s*<!(?:\\[CDATA\\[|--)|(?:\\]\\]|--)>\\s*$/g,\n\n\t// We have to close these tags to support XHTML (#13200)\n\twrapMap = {\n\t\toption: [ 1, \"<select multiple='multiple'>\", \"</select>\" ],\n\t\tlegend: [ 1, \"<fieldset>\", \"</fieldset>\" ],\n\t\tarea: [ 1, \"<map>\", \"</map>\" ],\n\t\tparam: [ 1, \"<object>\", \"</object>\" ],\n\t\tthead: [ 1, \"<table>\", \"</table>\" ],\n\t\ttr: [ 2, \"<table><tbody>\", \"</tbody></table>\" ],\n\t\tcol: [ 2, \"<table><tbody></tbody><colgroup>\", \"</colgroup></table>\" ],\n\t\ttd: [ 3, \"<table><tbody><tr>\", \"</tr></tbody></table>\" ],\n\n\t\t// IE6-8 can't serialize link, script, style, or any html5 (NoScope) tags,\n\t\t// unless wrapped in a div with non-breaking characters in front of it.\n\t\t_default: support.htmlSerialize ? [ 0, \"\", \"\" ] : [ 1, \"X<div>\", \"</div>\"  ]\n\t},\n\tsafeFragment = createSafeFragment( document ),\n\tfragmentDiv = safeFragment.appendChild( document.createElement(\"div\") );\n\nwrapMap.optgroup = wrapMap.option;\nwrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead;\nwrapMap.th = wrapMap.td;\n\nfunction getAll( context, tag ) {\n\tvar elems, elem,\n\t\ti = 0,\n\t\tfound = typeof context.getElementsByTagName !== strundefined ? context.getElementsByTagName( tag || \"*\" ) :\n\t\t\ttypeof context.querySelectorAll !== strundefined ? context.querySelectorAll( tag || \"*\" ) :\n\t\t\tundefined;\n\n\tif ( !found ) {\n\t\tfor ( found = [], elems = context.childNodes || context; (elem = elems[i]) != null; i++ ) {\n\t\t\tif ( !tag || jQuery.nodeName( elem, tag ) ) {\n\t\t\t\tfound.push( elem );\n\t\t\t} else {\n\t\t\t\tjQuery.merge( found, getAll( elem, tag ) );\n\t\t\t}\n\t\t}\n\t}\n\n\treturn tag === undefined || tag && jQuery.nodeName( context, tag ) ?\n\t\tjQuery.merge( [ context ], found ) :\n\t\tfound;\n}\n\n// Used in buildFragment, fixes the defaultChecked property\nfunction fixDefaultChecked( elem ) {\n\tif ( rcheckableType.test( elem.type ) ) {\n\t\telem.defaultChecked = elem.checked;\n\t}\n}\n\n// Support: IE<8\n// Manipulating tables requires a tbody\nfunction manipulationTarget( elem, content ) {\n\treturn jQuery.nodeName( elem, \"table\" ) &&\n\t\tjQuery.nodeName( content.nodeType !== 11 ? content : content.firstChild, \"tr\" ) ?\n\n\t\telem.getElementsByTagName(\"tbody\")[0] ||\n\t\t\telem.appendChild( elem.ownerDocument.createElement(\"tbody\") ) :\n\t\telem;\n}\n\n// Replace/restore the type attribute of script elements for safe DOM manipulation\nfunction disableScript( elem ) {\n\telem.type = (jQuery.find.attr( elem, \"type\" ) !== null) + \"/\" + elem.type;\n\treturn elem;\n}\nfunction restoreScript( elem ) {\n\tvar match = rscriptTypeMasked.exec( elem.type );\n\tif ( match ) {\n\t\telem.type = match[1];\n\t} else {\n\t\telem.removeAttribute(\"type\");\n\t}\n\treturn elem;\n}\n\n// Mark scripts as having already been evaluated\nfunction setGlobalEval( elems, refElements ) {\n\tvar elem,\n\t\ti = 0;\n\tfor ( ; (elem = elems[i]) != null; i++ ) {\n\t\tjQuery._data( elem, \"globalEval\", !refElements || jQuery._data( refElements[i], \"globalEval\" ) );\n\t}\n}\n\nfunction cloneCopyEvent( src, dest ) {\n\n\tif ( dest.nodeType !== 1 || !jQuery.hasData( src ) ) {\n\t\treturn;\n\t}\n\n\tvar type, i, l,\n\t\toldData = jQuery._data( src ),\n\t\tcurData = jQuery._data( dest, oldData ),\n\t\tevents = oldData.events;\n\n\tif ( events ) {\n\t\tdelete curData.handle;\n\t\tcurData.events = {};\n\n\t\tfor ( type in events ) {\n\t\t\tfor ( i = 0, l = events[ type ].length; i < l; i++ ) {\n\t\t\t\tjQuery.event.add( dest, type, events[ type ][ i ] );\n\t\t\t}\n\t\t}\n\t}\n\n\t// make the cloned public data object a copy from the original\n\tif ( curData.data ) {\n\t\tcurData.data = jQuery.extend( {}, curData.data );\n\t}\n}\n\nfunction fixCloneNodeIssues( src, dest ) {\n\tvar nodeName, e, data;\n\n\t// We do not need to do anything for non-Elements\n\tif ( dest.nodeType !== 1 ) {\n\t\treturn;\n\t}\n\n\tnodeName = dest.nodeName.toLowerCase();\n\n\t// IE6-8 copies events bound via attachEvent when using cloneNode.\n\tif ( !support.noCloneEvent && dest[ jQuery.expando ] ) {\n\t\tdata = jQuery._data( dest );\n\n\t\tfor ( e in data.events ) {\n\t\t\tjQuery.removeEvent( dest, e, data.handle );\n\t\t}\n\n\t\t// Event data gets referenced instead of copied if the expando gets copied too\n\t\tdest.removeAttribute( jQuery.expando );\n\t}\n\n\t// IE blanks contents when cloning scripts, and tries to evaluate newly-set text\n\tif ( nodeName === \"script\" && dest.text !== src.text ) {\n\t\tdisableScript( dest ).text = src.text;\n\t\trestoreScript( dest );\n\n\t// IE6-10 improperly clones children of object elements using classid.\n\t// IE10 throws NoModificationAllowedError if parent is null, #12132.\n\t} else if ( nodeName === \"object\" ) {\n\t\tif ( dest.parentNode ) {\n\t\t\tdest.outerHTML = src.outerHTML;\n\t\t}\n\n\t\t// This path appears unavoidable for IE9. When cloning an object\n\t\t// element in IE9, the outerHTML strategy above is not sufficient.\n\t\t// If the src has innerHTML and the destination does not,\n\t\t// copy the src.innerHTML into the dest.innerHTML. #10324\n\t\tif ( support.html5Clone && ( src.innerHTML && !jQuery.trim(dest.innerHTML) ) ) {\n\t\t\tdest.innerHTML = src.innerHTML;\n\t\t}\n\n\t} else if ( nodeName === \"input\" && rcheckableType.test( src.type ) ) {\n\t\t// IE6-8 fails to persist the checked state of a cloned checkbox\n\t\t// or radio button. Worse, IE6-7 fail to give the cloned element\n\t\t// a checked appearance if the defaultChecked value isn't also set\n\n\t\tdest.defaultChecked = dest.checked = src.checked;\n\n\t\t// IE6-7 get confused and end up setting the value of a cloned\n\t\t// checkbox/radio button to an empty string instead of \"on\"\n\t\tif ( dest.value !== src.value ) {\n\t\t\tdest.value = src.value;\n\t\t}\n\n\t// IE6-8 fails to return the selected option to the default selected\n\t// state when cloning options\n\t} else if ( nodeName === \"option\" ) {\n\t\tdest.defaultSelected = dest.selected = src.defaultSelected;\n\n\t// IE6-8 fails to set the defaultValue to the correct value when\n\t// cloning other types of input fields\n\t} else if ( nodeName === \"input\" || nodeName === \"textarea\" ) {\n\t\tdest.defaultValue = src.defaultValue;\n\t}\n}\n\njQuery.extend({\n\tclone: function( elem, dataAndEvents, deepDataAndEvents ) {\n\t\tvar destElements, node, clone, i, srcElements,\n\t\t\tinPage = jQuery.contains( elem.ownerDocument, elem );\n\n\t\tif ( support.html5Clone || jQuery.isXMLDoc(elem) || !rnoshimcache.test( \"<\" + elem.nodeName + \">\" ) ) {\n\t\t\tclone = elem.cloneNode( true );\n\n\t\t// IE<=8 does not properly clone detached, unknown element nodes\n\t\t} else {\n\t\t\tfragmentDiv.innerHTML = elem.outerHTML;\n\t\t\tfragmentDiv.removeChild( clone = fragmentDiv.firstChild );\n\t\t}\n\n\t\tif ( (!support.noCloneEvent || !support.noCloneChecked) &&\n\t\t\t\t(elem.nodeType === 1 || elem.nodeType === 11) && !jQuery.isXMLDoc(elem) ) {\n\n\t\t\t// We eschew Sizzle here for performance reasons: http://jsperf.com/getall-vs-sizzle/2\n\t\t\tdestElements = getAll( clone );\n\t\t\tsrcElements = getAll( elem );\n\n\t\t\t// Fix all IE cloning issues\n\t\t\tfor ( i = 0; (node = srcElements[i]) != null; ++i ) {\n\t\t\t\t// Ensure that the destination node is not null; Fixes #9587\n\t\t\t\tif ( destElements[i] ) {\n\t\t\t\t\tfixCloneNodeIssues( node, destElements[i] );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Copy the events from the original to the clone\n\t\tif ( dataAndEvents ) {\n\t\t\tif ( deepDataAndEvents ) {\n\t\t\t\tsrcElements = srcElements || getAll( elem );\n\t\t\t\tdestElements = destElements || getAll( clone );\n\n\t\t\t\tfor ( i = 0; (node = srcElements[i]) != null; i++ ) {\n\t\t\t\t\tcloneCopyEvent( node, destElements[i] );\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tcloneCopyEvent( elem, clone );\n\t\t\t}\n\t\t}\n\n\t\t// Preserve script evaluation history\n\t\tdestElements = getAll( clone, \"script\" );\n\t\tif ( destElements.length > 0 ) {\n\t\t\tsetGlobalEval( destElements, !inPage && getAll( elem, \"script\" ) );\n\t\t}\n\n\t\tdestElements = srcElements = node = null;\n\n\t\t// Return the cloned set\n\t\treturn clone;\n\t},\n\n\tbuildFragment: function( elems, context, scripts, selection ) {\n\t\tvar j, elem, contains,\n\t\t\ttmp, tag, tbody, wrap,\n\t\t\tl = elems.length,\n\n\t\t\t// Ensure a safe fragment\n\t\t\tsafe = createSafeFragment( context ),\n\n\t\t\tnodes = [],\n\t\t\ti = 0;\n\n\t\tfor ( ; i < l; i++ ) {\n\t\t\telem = elems[ i ];\n\n\t\t\tif ( elem || elem === 0 ) {\n\n\t\t\t\t// Add nodes directly\n\t\t\t\tif ( jQuery.type( elem ) === \"object\" ) {\n\t\t\t\t\tjQuery.merge( nodes, elem.nodeType ? [ elem ] : elem );\n\n\t\t\t\t// Convert non-html into a text node\n\t\t\t\t} else if ( !rhtml.test( elem ) ) {\n\t\t\t\t\tnodes.push( context.createTextNode( elem ) );\n\n\t\t\t\t// Convert html into DOM nodes\n\t\t\t\t} else {\n\t\t\t\t\ttmp = tmp || safe.appendChild( context.createElement(\"div\") );\n\n\t\t\t\t\t// Deserialize a standard representation\n\t\t\t\t\ttag = (rtagName.exec( elem ) || [ \"\", \"\" ])[ 1 ].toLowerCase();\n\t\t\t\t\twrap = wrapMap[ tag ] || wrapMap._default;\n\n\t\t\t\t\ttmp.innerHTML = wrap[1] + elem.replace( rxhtmlTag, \"<$1></$2>\" ) + wrap[2];\n\n\t\t\t\t\t// Descend through wrappers to the right content\n\t\t\t\t\tj = wrap[0];\n\t\t\t\t\twhile ( j-- ) {\n\t\t\t\t\t\ttmp = tmp.lastChild;\n\t\t\t\t\t}\n\n\t\t\t\t\t// Manually add leading whitespace removed by IE\n\t\t\t\t\tif ( !support.leadingWhitespace && rleadingWhitespace.test( elem ) ) {\n\t\t\t\t\t\tnodes.push( context.createTextNode( rleadingWhitespace.exec( elem )[0] ) );\n\t\t\t\t\t}\n\n\t\t\t\t\t// Remove IE's autoinserted <tbody> from table fragments\n\t\t\t\t\tif ( !support.tbody ) {\n\n\t\t\t\t\t\t// String was a <table>, *may* have spurious <tbody>\n\t\t\t\t\t\telem = tag === \"table\" && !rtbody.test( elem ) ?\n\t\t\t\t\t\t\ttmp.firstChild :\n\n\t\t\t\t\t\t\t// String was a bare <thead> or <tfoot>\n\t\t\t\t\t\t\twrap[1] === \"<table>\" && !rtbody.test( elem ) ?\n\t\t\t\t\t\t\t\ttmp :\n\t\t\t\t\t\t\t\t0;\n\n\t\t\t\t\t\tj = elem && elem.childNodes.length;\n\t\t\t\t\t\twhile ( j-- ) {\n\t\t\t\t\t\t\tif ( jQuery.nodeName( (tbody = elem.childNodes[j]), \"tbody\" ) && !tbody.childNodes.length ) {\n\t\t\t\t\t\t\t\telem.removeChild( tbody );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tjQuery.merge( nodes, tmp.childNodes );\n\n\t\t\t\t\t// Fix #12392 for WebKit and IE > 9\n\t\t\t\t\ttmp.textContent = \"\";\n\n\t\t\t\t\t// Fix #12392 for oldIE\n\t\t\t\t\twhile ( tmp.firstChild ) {\n\t\t\t\t\t\ttmp.removeChild( tmp.firstChild );\n\t\t\t\t\t}\n\n\t\t\t\t\t// Remember the top-level container for proper cleanup\n\t\t\t\t\ttmp = safe.lastChild;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Fix #11356: Clear elements from fragment\n\t\tif ( tmp ) {\n\t\t\tsafe.removeChild( tmp );\n\t\t}\n\n\t\t// Reset defaultChecked for any radios and checkboxes\n\t\t// about to be appended to the DOM in IE 6/7 (#8060)\n\t\tif ( !support.appendChecked ) {\n\t\t\tjQuery.grep( getAll( nodes, \"input\" ), fixDefaultChecked );\n\t\t}\n\n\t\ti = 0;\n\t\twhile ( (elem = nodes[ i++ ]) ) {\n\n\t\t\t// #4087 - If origin and destination elements are the same, and this is\n\t\t\t// that element, do not do anything\n\t\t\tif ( selection && jQuery.inArray( elem, selection ) !== -1 ) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tcontains = jQuery.contains( elem.ownerDocument, elem );\n\n\t\t\t// Append to fragment\n\t\t\ttmp = getAll( safe.appendChild( elem ), \"script\" );\n\n\t\t\t// Preserve script evaluation history\n\t\t\tif ( contains ) {\n\t\t\t\tsetGlobalEval( tmp );\n\t\t\t}\n\n\t\t\t// Capture executables\n\t\t\tif ( scripts ) {\n\t\t\t\tj = 0;\n\t\t\t\twhile ( (elem = tmp[ j++ ]) ) {\n\t\t\t\t\tif ( rscriptType.test( elem.type || \"\" ) ) {\n\t\t\t\t\t\tscripts.push( elem );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\ttmp = null;\n\n\t\treturn safe;\n\t},\n\n\tcleanData: function( elems, /* internal */ acceptData ) {\n\t\tvar elem, type, id, data,\n\t\t\ti = 0,\n\t\t\tinternalKey = jQuery.expando,\n\t\t\tcache = jQuery.cache,\n\t\t\tdeleteExpando = support.deleteExpando,\n\t\t\tspecial = jQuery.event.special;\n\n\t\tfor ( ; (elem = elems[i]) != null; i++ ) {\n\t\t\tif ( acceptData || jQuery.acceptData( elem ) ) {\n\n\t\t\t\tid = elem[ internalKey ];\n\t\t\t\tdata = id && cache[ id ];\n\n\t\t\t\tif ( data ) {\n\t\t\t\t\tif ( data.events ) {\n\t\t\t\t\t\tfor ( type in data.events ) {\n\t\t\t\t\t\t\tif ( special[ type ] ) {\n\t\t\t\t\t\t\t\tjQuery.event.remove( elem, type );\n\n\t\t\t\t\t\t\t// This is a shortcut to avoid jQuery.event.remove's overhead\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tjQuery.removeEvent( elem, type, data.handle );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\t// Remove cache only if it was not already removed by jQuery.event.remove\n\t\t\t\t\tif ( cache[ id ] ) {\n\n\t\t\t\t\t\tdelete cache[ id ];\n\n\t\t\t\t\t\t// IE does not allow us to delete expando properties from nodes,\n\t\t\t\t\t\t// nor does it have a removeAttribute function on Document nodes;\n\t\t\t\t\t\t// we must handle all of these cases\n\t\t\t\t\t\tif ( deleteExpando ) {\n\t\t\t\t\t\t\tdelete elem[ internalKey ];\n\n\t\t\t\t\t\t} else if ( typeof elem.removeAttribute !== strundefined ) {\n\t\t\t\t\t\t\telem.removeAttribute( internalKey );\n\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\telem[ internalKey ] = null;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tdeletedIds.push( id );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n});\n\njQuery.fn.extend({\n\ttext: function( value ) {\n\t\treturn access( this, function( value ) {\n\t\t\treturn value === undefined ?\n\t\t\t\tjQuery.text( this ) :\n\t\t\t\tthis.empty().append( ( this[0] && this[0].ownerDocument || document ).createTextNode( value ) );\n\t\t}, null, value, arguments.length );\n\t},\n\n\tappend: function() {\n\t\treturn this.domManip( arguments, function( elem ) {\n\t\t\tif ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) {\n\t\t\t\tvar target = manipulationTarget( this, elem );\n\t\t\t\ttarget.appendChild( elem );\n\t\t\t}\n\t\t});\n\t},\n\n\tprepend: function() {\n\t\treturn this.domManip( arguments, function( elem ) {\n\t\t\tif ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) {\n\t\t\t\tvar target = manipulationTarget( this, elem );\n\t\t\t\ttarget.insertBefore( elem, target.firstChild );\n\t\t\t}\n\t\t});\n\t},\n\n\tbefore: function() {\n\t\treturn this.domManip( arguments, function( elem ) {\n\t\t\tif ( this.parentNode ) {\n\t\t\t\tthis.parentNode.insertBefore( elem, this );\n\t\t\t}\n\t\t});\n\t},\n\n\tafter: function() {\n\t\treturn this.domManip( arguments, function( elem ) {\n\t\t\tif ( this.parentNode ) {\n\t\t\t\tthis.parentNode.insertBefore( elem, this.nextSibling );\n\t\t\t}\n\t\t});\n\t},\n\n\tremove: function( selector, keepData /* Internal Use Only */ ) {\n\t\tvar elem,\n\t\t\telems = selector ? jQuery.filter( selector, this ) : this,\n\t\t\ti = 0;\n\n\t\tfor ( ; (elem = elems[i]) != null; i++ ) {\n\n\t\t\tif ( !keepData && elem.nodeType === 1 ) {\n\t\t\t\tjQuery.cleanData( getAll( elem ) );\n\t\t\t}\n\n\t\t\tif ( elem.parentNode ) {\n\t\t\t\tif ( keepData && jQuery.contains( elem.ownerDocument, elem ) ) {\n\t\t\t\t\tsetGlobalEval( getAll( elem, \"script\" ) );\n\t\t\t\t}\n\t\t\t\telem.parentNode.removeChild( elem );\n\t\t\t}\n\t\t}\n\n\t\treturn this;\n\t},\n\n\tempty: function() {\n\t\tvar elem,\n\t\t\ti = 0;\n\n\t\tfor ( ; (elem = this[i]) != null; i++ ) {\n\t\t\t// Remove element nodes and prevent memory leaks\n\t\t\tif ( elem.nodeType === 1 ) {\n\t\t\t\tjQuery.cleanData( getAll( elem, false ) );\n\t\t\t}\n\n\t\t\t// Remove any remaining nodes\n\t\t\twhile ( elem.firstChild ) {\n\t\t\t\telem.removeChild( elem.firstChild );\n\t\t\t}\n\n\t\t\t// If this is a select, ensure that it displays empty (#12336)\n\t\t\t// Support: IE<9\n\t\t\tif ( elem.options && jQuery.nodeName( elem, \"select\" ) ) {\n\t\t\t\telem.options.length = 0;\n\t\t\t}\n\t\t}\n\n\t\treturn this;\n\t},\n\n\tclone: function( dataAndEvents, deepDataAndEvents ) {\n\t\tdataAndEvents = dataAndEvents == null ? false : dataAndEvents;\n\t\tdeepDataAndEvents = deepDataAndEvents == null ? dataAndEvents : deepDataAndEvents;\n\n\t\treturn this.map(function() {\n\t\t\treturn jQuery.clone( this, dataAndEvents, deepDataAndEvents );\n\t\t});\n\t},\n\n\thtml: function( value ) {\n\t\treturn access( this, function( value ) {\n\t\t\tvar elem = this[ 0 ] || {},\n\t\t\t\ti = 0,\n\t\t\t\tl = this.length;\n\n\t\t\tif ( value === undefined ) {\n\t\t\t\treturn elem.nodeType === 1 ?\n\t\t\t\t\telem.innerHTML.replace( rinlinejQuery, \"\" ) :\n\t\t\t\t\tundefined;\n\t\t\t}\n\n\t\t\t// See if we can take a shortcut and just use innerHTML\n\t\t\tif ( typeof value === \"string\" && !rnoInnerhtml.test( value ) &&\n\t\t\t\t( support.htmlSerialize || !rnoshimcache.test( value )  ) &&\n\t\t\t\t( support.leadingWhitespace || !rleadingWhitespace.test( value ) ) &&\n\t\t\t\t!wrapMap[ (rtagName.exec( value ) || [ \"\", \"\" ])[ 1 ].toLowerCase() ] ) {\n\n\t\t\t\tvalue = value.replace( rxhtmlTag, \"<$1></$2>\" );\n\n\t\t\t\ttry {\n\t\t\t\t\tfor (; i < l; i++ ) {\n\t\t\t\t\t\t// Remove element nodes and prevent memory leaks\n\t\t\t\t\t\telem = this[i] || {};\n\t\t\t\t\t\tif ( elem.nodeType === 1 ) {\n\t\t\t\t\t\t\tjQuery.cleanData( getAll( elem, false ) );\n\t\t\t\t\t\t\telem.innerHTML = value;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\telem = 0;\n\n\t\t\t\t// If using innerHTML throws an exception, use the fallback method\n\t\t\t\t} catch(e) {}\n\t\t\t}\n\n\t\t\tif ( elem ) {\n\t\t\t\tthis.empty().append( value );\n\t\t\t}\n\t\t}, null, value, arguments.length );\n\t},\n\n\treplaceWith: function() {\n\t\tvar arg = arguments[ 0 ];\n\n\t\t// Make the changes, replacing each context element with the new content\n\t\tthis.domManip( arguments, function( elem ) {\n\t\t\targ = this.parentNode;\n\n\t\t\tjQuery.cleanData( getAll( this ) );\n\n\t\t\tif ( arg ) {\n\t\t\t\targ.replaceChild( elem, this );\n\t\t\t}\n\t\t});\n\n\t\t// Force removal if there was no new content (e.g., from empty arguments)\n\t\treturn arg && (arg.length || arg.nodeType) ? this : this.remove();\n\t},\n\n\tdetach: function( selector ) {\n\t\treturn this.remove( selector, true );\n\t},\n\n\tdomManip: function( args, callback ) {\n\n\t\t// Flatten any nested arrays\n\t\targs = concat.apply( [], args );\n\n\t\tvar first, node, hasScripts,\n\t\t\tscripts, doc, fragment,\n\t\t\ti = 0,\n\t\t\tl = this.length,\n\t\t\tset = this,\n\t\t\tiNoClone = l - 1,\n\t\t\tvalue = args[0],\n\t\t\tisFunction = jQuery.isFunction( value );\n\n\t\t// We can't cloneNode fragments that contain checked, in WebKit\n\t\tif ( isFunction ||\n\t\t\t\t( l > 1 && typeof value === \"string\" &&\n\t\t\t\t\t!support.checkClone && rchecked.test( value ) ) ) {\n\t\t\treturn this.each(function( index ) {\n\t\t\t\tvar self = set.eq( index );\n\t\t\t\tif ( isFunction ) {\n\t\t\t\t\targs[0] = value.call( this, index, self.html() );\n\t\t\t\t}\n\t\t\t\tself.domManip( args, callback );\n\t\t\t});\n\t\t}\n\n\t\tif ( l ) {\n\t\t\tfragment = jQuery.buildFragment( args, this[ 0 ].ownerDocument, false, this );\n\t\t\tfirst = fragment.firstChild;\n\n\t\t\tif ( fragment.childNodes.length === 1 ) {\n\t\t\t\tfragment = first;\n\t\t\t}\n\n\t\t\tif ( first ) {\n\t\t\t\tscripts = jQuery.map( getAll( fragment, \"script\" ), disableScript );\n\t\t\t\thasScripts = scripts.length;\n\n\t\t\t\t// Use the original fragment for the last item instead of the first because it can end up\n\t\t\t\t// being emptied incorrectly in certain situations (#8070).\n\t\t\t\tfor ( ; i < l; i++ ) {\n\t\t\t\t\tnode = fragment;\n\n\t\t\t\t\tif ( i !== iNoClone ) {\n\t\t\t\t\t\tnode = jQuery.clone( node, true, true );\n\n\t\t\t\t\t\t// Keep references to cloned scripts for later restoration\n\t\t\t\t\t\tif ( hasScripts ) {\n\t\t\t\t\t\t\tjQuery.merge( scripts, getAll( node, \"script\" ) );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tcallback.call( this[i], node, i );\n\t\t\t\t}\n\n\t\t\t\tif ( hasScripts ) {\n\t\t\t\t\tdoc = scripts[ scripts.length - 1 ].ownerDocument;\n\n\t\t\t\t\t// Reenable scripts\n\t\t\t\t\tjQuery.map( scripts, restoreScript );\n\n\t\t\t\t\t// Evaluate executable scripts on first document insertion\n\t\t\t\t\tfor ( i = 0; i < hasScripts; i++ ) {\n\t\t\t\t\t\tnode = scripts[ i ];\n\t\t\t\t\t\tif ( rscriptType.test( node.type || \"\" ) &&\n\t\t\t\t\t\t\t!jQuery._data( node, \"globalEval\" ) && jQuery.contains( doc, node ) ) {\n\n\t\t\t\t\t\t\tif ( node.src ) {\n\t\t\t\t\t\t\t\t// Optional AJAX dependency, but won't run scripts if not present\n\t\t\t\t\t\t\t\tif ( jQuery._evalUrl ) {\n\t\t\t\t\t\t\t\t\tjQuery._evalUrl( node.src );\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tjQuery.globalEval( ( node.text || node.textContent || node.innerHTML || \"\" ).replace( rcleanScript, \"\" ) );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// Fix #11809: Avoid leaking memory\n\t\t\t\tfragment = first = null;\n\t\t\t}\n\t\t}\n\n\t\treturn this;\n\t}\n});\n\njQuery.each({\n\tappendTo: \"append\",\n\tprependTo: \"prepend\",\n\tinsertBefore: \"before\",\n\tinsertAfter: \"after\",\n\treplaceAll: \"replaceWith\"\n}, function( name, original ) {\n\tjQuery.fn[ name ] = function( selector ) {\n\t\tvar elems,\n\t\t\ti = 0,\n\t\t\tret = [],\n\t\t\tinsert = jQuery( selector ),\n\t\t\tlast = insert.length - 1;\n\n\t\tfor ( ; i <= last; i++ ) {\n\t\t\telems = i === last ? this : this.clone(true);\n\t\t\tjQuery( insert[i] )[ original ]( elems );\n\n\t\t\t// Modern browsers can apply jQuery collections as arrays, but oldIE needs a .get()\n\t\t\tpush.apply( ret, elems.get() );\n\t\t}\n\n\t\treturn this.pushStack( ret );\n\t};\n});\n\n\nvar iframe,\n\telemdisplay = {};\n\n/**\n * Retrieve the actual display of a element\n * @param {String} name nodeName of the element\n * @param {Object} doc Document object\n */\n// Called only from within defaultDisplay\nfunction actualDisplay( name, doc ) {\n\tvar style,\n\t\telem = jQuery( doc.createElement( name ) ).appendTo( doc.body ),\n\n\t\t// getDefaultComputedStyle might be reliably used only on attached element\n\t\tdisplay = window.getDefaultComputedStyle && ( style = window.getDefaultComputedStyle( elem[ 0 ] ) ) ?\n\n\t\t\t// Use of this method is a temporary fix (more like optmization) until something better comes along,\n\t\t\t// since it was removed from specification and supported only in FF\n\t\t\tstyle.display : jQuery.css( elem[ 0 ], \"display\" );\n\n\t// We don't have any data stored on the element,\n\t// so use \"detach\" method as fast way to get rid of the element\n\telem.detach();\n\n\treturn display;\n}\n\n/**\n * Try to determine the default display value of an element\n * @param {String} nodeName\n */\nfunction defaultDisplay( nodeName ) {\n\tvar doc = document,\n\t\tdisplay = elemdisplay[ nodeName ];\n\n\tif ( !display ) {\n\t\tdisplay = actualDisplay( nodeName, doc );\n\n\t\t// If the simple way fails, read from inside an iframe\n\t\tif ( display === \"none\" || !display ) {\n\n\t\t\t// Use the already-created iframe if possible\n\t\t\tiframe = (iframe || jQuery( \"<iframe frameborder='0' width='0' height='0'/>\" )).appendTo( doc.documentElement );\n\n\t\t\t// Always write a new HTML skeleton so Webkit and Firefox don't choke on reuse\n\t\t\tdoc = ( iframe[ 0 ].contentWindow || iframe[ 0 ].contentDocument ).document;\n\n\t\t\t// Support: IE\n\t\t\tdoc.write();\n\t\t\tdoc.close();\n\n\t\t\tdisplay = actualDisplay( nodeName, doc );\n\t\t\tiframe.detach();\n\t\t}\n\n\t\t// Store the correct default display\n\t\telemdisplay[ nodeName ] = display;\n\t}\n\n\treturn display;\n}\n\n\n(function() {\n\tvar shrinkWrapBlocksVal;\n\n\tsupport.shrinkWrapBlocks = function() {\n\t\tif ( shrinkWrapBlocksVal != null ) {\n\t\t\treturn shrinkWrapBlocksVal;\n\t\t}\n\n\t\t// Will be changed later if needed.\n\t\tshrinkWrapBlocksVal = false;\n\n\t\t// Minified: var b,c,d\n\t\tvar div, body, container;\n\n\t\tbody = document.getElementsByTagName( \"body\" )[ 0 ];\n\t\tif ( !body || !body.style ) {\n\t\t\t// Test fired too early or in an unsupported environment, exit.\n\t\t\treturn;\n\t\t}\n\n\t\t// Setup\n\t\tdiv = document.createElement( \"div\" );\n\t\tcontainer = document.createElement( \"div\" );\n\t\tcontainer.style.cssText = \"position:absolute;border:0;width:0;height:0;top:0;left:-9999px\";\n\t\tbody.appendChild( container ).appendChild( div );\n\n\t\t// Support: IE6\n\t\t// Check if elements with layout shrink-wrap their children\n\t\tif ( typeof div.style.zoom !== strundefined ) {\n\t\t\t// Reset CSS: box-sizing; display; margin; border\n\t\t\tdiv.style.cssText =\n\t\t\t\t// Support: Firefox<29, Android 2.3\n\t\t\t\t// Vendor-prefix box-sizing\n\t\t\t\t\"-webkit-box-sizing:content-box;-moz-box-sizing:content-box;\" +\n\t\t\t\t\"box-sizing:content-box;display:block;margin:0;border:0;\" +\n\t\t\t\t\"padding:1px;width:1px;zoom:1\";\n\t\t\tdiv.appendChild( document.createElement( \"div\" ) ).style.width = \"5px\";\n\t\t\tshrinkWrapBlocksVal = div.offsetWidth !== 3;\n\t\t}\n\n\t\tbody.removeChild( container );\n\n\t\treturn shrinkWrapBlocksVal;\n\t};\n\n})();\nvar rmargin = (/^margin/);\n\nvar rnumnonpx = new RegExp( \"^(\" + pnum + \")(?!px)[a-z%]+$\", \"i\" );\n\n\n\nvar getStyles, curCSS,\n\trposition = /^(top|right|bottom|left)$/;\n\nif ( window.getComputedStyle ) {\n\tgetStyles = function( elem ) {\n\t\t// Support: IE<=11+, Firefox<=30+ (#15098, #14150)\n\t\t// IE throws on elements created in popups\n\t\t// FF meanwhile throws on frame elements through \"defaultView.getComputedStyle\"\n\t\tif ( elem.ownerDocument.defaultView.opener ) {\n\t\t\treturn elem.ownerDocument.defaultView.getComputedStyle( elem, null );\n\t\t}\n\n\t\treturn window.getComputedStyle( elem, null );\n\t};\n\n\tcurCSS = function( elem, name, computed ) {\n\t\tvar width, minWidth, maxWidth, ret,\n\t\t\tstyle = elem.style;\n\n\t\tcomputed = computed || getStyles( elem );\n\n\t\t// getPropertyValue is only needed for .css('filter') in IE9, see #12537\n\t\tret = computed ? computed.getPropertyValue( name ) || computed[ name ] : undefined;\n\n\t\tif ( computed ) {\n\n\t\t\tif ( ret === \"\" && !jQuery.contains( elem.ownerDocument, elem ) ) {\n\t\t\t\tret = jQuery.style( elem, name );\n\t\t\t}\n\n\t\t\t// A tribute to the \"awesome hack by Dean Edwards\"\n\t\t\t// Chrome < 17 and Safari 5.0 uses \"computed value\" instead of \"used value\" for margin-right\n\t\t\t// Safari 5.1.7 (at least) returns percentage for a larger set of values, but width seems to be reliably pixels\n\t\t\t// this is against the CSSOM draft spec: http://dev.w3.org/csswg/cssom/#resolved-values\n\t\t\tif ( rnumnonpx.test( ret ) && rmargin.test( name ) ) {\n\n\t\t\t\t// Remember the original values\n\t\t\t\twidth = style.width;\n\t\t\t\tminWidth = style.minWidth;\n\t\t\t\tmaxWidth = style.maxWidth;\n\n\t\t\t\t// Put in the new values to get a computed value out\n\t\t\t\tstyle.minWidth = style.maxWidth = style.width = ret;\n\t\t\t\tret = computed.width;\n\n\t\t\t\t// Revert the changed values\n\t\t\t\tstyle.width = width;\n\t\t\t\tstyle.minWidth = minWidth;\n\t\t\t\tstyle.maxWidth = maxWidth;\n\t\t\t}\n\t\t}\n\n\t\t// Support: IE\n\t\t// IE returns zIndex value as an integer.\n\t\treturn ret === undefined ?\n\t\t\tret :\n\t\t\tret + \"\";\n\t};\n} else if ( document.documentElement.currentStyle ) {\n\tgetStyles = function( elem ) {\n\t\treturn elem.currentStyle;\n\t};\n\n\tcurCSS = function( elem, name, computed ) {\n\t\tvar left, rs, rsLeft, ret,\n\t\t\tstyle = elem.style;\n\n\t\tcomputed = computed || getStyles( elem );\n\t\tret = computed ? computed[ name ] : undefined;\n\n\t\t// Avoid setting ret to empty string here\n\t\t// so we don't default to auto\n\t\tif ( ret == null && style && style[ name ] ) {\n\t\t\tret = style[ name ];\n\t\t}\n\n\t\t// From the awesome hack by Dean Edwards\n\t\t// http://erik.eae.net/archives/2007/07/27/18.54.15/#comment-102291\n\n\t\t// If we're not dealing with a regular pixel number\n\t\t// but a number that has a weird ending, we need to convert it to pixels\n\t\t// but not position css attributes, as those are proportional to the parent element instead\n\t\t// and we can't measure the parent instead because it might trigger a \"stacking dolls\" problem\n\t\tif ( rnumnonpx.test( ret ) && !rposition.test( name ) ) {\n\n\t\t\t// Remember the original values\n\t\t\tleft = style.left;\n\t\t\trs = elem.runtimeStyle;\n\t\t\trsLeft = rs && rs.left;\n\n\t\t\t// Put in the new values to get a computed value out\n\t\t\tif ( rsLeft ) {\n\t\t\t\trs.left = elem.currentStyle.left;\n\t\t\t}\n\t\t\tstyle.left = name === \"fontSize\" ? \"1em\" : ret;\n\t\t\tret = style.pixelLeft + \"px\";\n\n\t\t\t// Revert the changed values\n\t\t\tstyle.left = left;\n\t\t\tif ( rsLeft ) {\n\t\t\t\trs.left = rsLeft;\n\t\t\t}\n\t\t}\n\n\t\t// Support: IE\n\t\t// IE returns zIndex value as an integer.\n\t\treturn ret === undefined ?\n\t\t\tret :\n\t\t\tret + \"\" || \"auto\";\n\t};\n}\n\n\n\n\nfunction addGetHookIf( conditionFn, hookFn ) {\n\t// Define the hook, we'll check on the first run if it's really needed.\n\treturn {\n\t\tget: function() {\n\t\t\tvar condition = conditionFn();\n\n\t\t\tif ( condition == null ) {\n\t\t\t\t// The test was not ready at this point; screw the hook this time\n\t\t\t\t// but check again when needed next time.\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif ( condition ) {\n\t\t\t\t// Hook not needed (or it's not possible to use it due to missing dependency),\n\t\t\t\t// remove it.\n\t\t\t\t// Since there are no other hooks for marginRight, remove the whole object.\n\t\t\t\tdelete this.get;\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// Hook needed; redefine it so that the support test is not executed again.\n\n\t\t\treturn (this.get = hookFn).apply( this, arguments );\n\t\t}\n\t};\n}\n\n\n(function() {\n\t// Minified: var b,c,d,e,f,g, h,i\n\tvar div, style, a, pixelPositionVal, boxSizingReliableVal,\n\t\treliableHiddenOffsetsVal, reliableMarginRightVal;\n\n\t// Setup\n\tdiv = document.createElement( \"div\" );\n\tdiv.innerHTML = \"  <link/><table></table><a href='/a'>a</a><input type='checkbox'/>\";\n\ta = div.getElementsByTagName( \"a\" )[ 0 ];\n\tstyle = a && a.style;\n\n\t// Finish early in limited (non-browser) environments\n\tif ( !style ) {\n\t\treturn;\n\t}\n\n\tstyle.cssText = \"float:left;opacity:.5\";\n\n\t// Support: IE<9\n\t// Make sure that element opacity exists (as opposed to filter)\n\tsupport.opacity = style.opacity === \"0.5\";\n\n\t// Verify style float existence\n\t// (IE uses styleFloat instead of cssFloat)\n\tsupport.cssFloat = !!style.cssFloat;\n\n\tdiv.style.backgroundClip = \"content-box\";\n\tdiv.cloneNode( true ).style.backgroundClip = \"\";\n\tsupport.clearCloneStyle = div.style.backgroundClip === \"content-box\";\n\n\t// Support: Firefox<29, Android 2.3\n\t// Vendor-prefix box-sizing\n\tsupport.boxSizing = style.boxSizing === \"\" || style.MozBoxSizing === \"\" ||\n\t\tstyle.WebkitBoxSizing === \"\";\n\n\tjQuery.extend(support, {\n\t\treliableHiddenOffsets: function() {\n\t\t\tif ( reliableHiddenOffsetsVal == null ) {\n\t\t\t\tcomputeStyleTests();\n\t\t\t}\n\t\t\treturn reliableHiddenOffsetsVal;\n\t\t},\n\n\t\tboxSizingReliable: function() {\n\t\t\tif ( boxSizingReliableVal == null ) {\n\t\t\t\tcomputeStyleTests();\n\t\t\t}\n\t\t\treturn boxSizingReliableVal;\n\t\t},\n\n\t\tpixelPosition: function() {\n\t\t\tif ( pixelPositionVal == null ) {\n\t\t\t\tcomputeStyleTests();\n\t\t\t}\n\t\t\treturn pixelPositionVal;\n\t\t},\n\n\t\t// Support: Android 2.3\n\t\treliableMarginRight: function() {\n\t\t\tif ( reliableMarginRightVal == null ) {\n\t\t\t\tcomputeStyleTests();\n\t\t\t}\n\t\t\treturn reliableMarginRightVal;\n\t\t}\n\t});\n\n\tfunction computeStyleTests() {\n\t\t// Minified: var b,c,d,j\n\t\tvar div, body, container, contents;\n\n\t\tbody = document.getElementsByTagName( \"body\" )[ 0 ];\n\t\tif ( !body || !body.style ) {\n\t\t\t// Test fired too early or in an unsupported environment, exit.\n\t\t\treturn;\n\t\t}\n\n\t\t// Setup\n\t\tdiv = document.createElement( \"div\" );\n\t\tcontainer = document.createElement( \"div\" );\n\t\tcontainer.style.cssText = \"position:absolute;border:0;width:0;height:0;top:0;left:-9999px\";\n\t\tbody.appendChild( container ).appendChild( div );\n\n\t\tdiv.style.cssText =\n\t\t\t// Support: Firefox<29, Android 2.3\n\t\t\t// Vendor-prefix box-sizing\n\t\t\t\"-webkit-box-sizing:border-box;-moz-box-sizing:border-box;\" +\n\t\t\t\"box-sizing:border-box;display:block;margin-top:1%;top:1%;\" +\n\t\t\t\"border:1px;padding:1px;width:4px;position:absolute\";\n\n\t\t// Support: IE<9\n\t\t// Assume reasonable values in the absence of getComputedStyle\n\t\tpixelPositionVal = boxSizingReliableVal = false;\n\t\treliableMarginRightVal = true;\n\n\t\t// Check for getComputedStyle so that this code is not run in IE<9.\n\t\tif ( window.getComputedStyle ) {\n\t\t\tpixelPositionVal = ( window.getComputedStyle( div, null ) || {} ).top !== \"1%\";\n\t\t\tboxSizingReliableVal =\n\t\t\t\t( window.getComputedStyle( div, null ) || { width: \"4px\" } ).width === \"4px\";\n\n\t\t\t// Support: Android 2.3\n\t\t\t// Div with explicit width and no margin-right incorrectly\n\t\t\t// gets computed margin-right based on width of container (#3333)\n\t\t\t// WebKit Bug 13343 - getComputedStyle returns wrong value for margin-right\n\t\t\tcontents = div.appendChild( document.createElement( \"div\" ) );\n\n\t\t\t// Reset CSS: box-sizing; display; margin; border; padding\n\t\t\tcontents.style.cssText = div.style.cssText =\n\t\t\t\t// Support: Firefox<29, Android 2.3\n\t\t\t\t// Vendor-prefix box-sizing\n\t\t\t\t\"-webkit-box-sizing:content-box;-moz-box-sizing:content-box;\" +\n\t\t\t\t\"box-sizing:content-box;display:block;margin:0;border:0;padding:0\";\n\t\t\tcontents.style.marginRight = contents.style.width = \"0\";\n\t\t\tdiv.style.width = \"1px\";\n\n\t\t\treliableMarginRightVal =\n\t\t\t\t!parseFloat( ( window.getComputedStyle( contents, null ) || {} ).marginRight );\n\n\t\t\tdiv.removeChild( contents );\n\t\t}\n\n\t\t// Support: IE8\n\t\t// Check if table cells still have offsetWidth/Height when they are set\n\t\t// to display:none and there are still other visible table cells in a\n\t\t// table row; if so, offsetWidth/Height are not reliable for use when\n\t\t// determining if an element has been hidden directly using\n\t\t// display:none (it is still safe to use offsets if a parent element is\n\t\t// hidden; don safety goggles and see bug #4512 for more information).\n\t\tdiv.innerHTML = \"<table><tr><td></td><td>t</td></tr></table>\";\n\t\tcontents = div.getElementsByTagName( \"td\" );\n\t\tcontents[ 0 ].style.cssText = \"margin:0;border:0;padding:0;display:none\";\n\t\treliableHiddenOffsetsVal = contents[ 0 ].offsetHeight === 0;\n\t\tif ( reliableHiddenOffsetsVal ) {\n\t\t\tcontents[ 0 ].style.display = \"\";\n\t\t\tcontents[ 1 ].style.display = \"none\";\n\t\t\treliableHiddenOffsetsVal = contents[ 0 ].offsetHeight === 0;\n\t\t}\n\n\t\tbody.removeChild( container );\n\t}\n\n})();\n\n\n// A method for quickly swapping in/out CSS properties to get correct calculations.\njQuery.swap = function( elem, options, callback, args ) {\n\tvar ret, name,\n\t\told = {};\n\n\t// Remember the old values, and insert the new ones\n\tfor ( name in options ) {\n\t\told[ name ] = elem.style[ name ];\n\t\telem.style[ name ] = options[ name ];\n\t}\n\n\tret = callback.apply( elem, args || [] );\n\n\t// Revert the old values\n\tfor ( name in options ) {\n\t\telem.style[ name ] = old[ name ];\n\t}\n\n\treturn ret;\n};\n\n\nvar\n\t\tralpha = /alpha\\([^)]*\\)/i,\n\tropacity = /opacity\\s*=\\s*([^)]*)/,\n\n\t// swappable if display is none or starts with table except \"table\", \"table-cell\", or \"table-caption\"\n\t// see here for display values: https://developer.mozilla.org/en-US/docs/CSS/display\n\trdisplayswap = /^(none|table(?!-c[ea]).+)/,\n\trnumsplit = new RegExp( \"^(\" + pnum + \")(.*)$\", \"i\" ),\n\trrelNum = new RegExp( \"^([+-])=(\" + pnum + \")\", \"i\" ),\n\n\tcssShow = { position: \"absolute\", visibility: \"hidden\", display: \"block\" },\n\tcssNormalTransform = {\n\t\tletterSpacing: \"0\",\n\t\tfontWeight: \"400\"\n\t},\n\n\tcssPrefixes = [ \"Webkit\", \"O\", \"Moz\", \"ms\" ];\n\n\n// return a css property mapped to a potentially vendor prefixed property\nfunction vendorPropName( style, name ) {\n\n\t// shortcut for names that are not vendor prefixed\n\tif ( name in style ) {\n\t\treturn name;\n\t}\n\n\t// check for vendor prefixed names\n\tvar capName = name.charAt(0).toUpperCase() + name.slice(1),\n\t\torigName = name,\n\t\ti = cssPrefixes.length;\n\n\twhile ( i-- ) {\n\t\tname = cssPrefixes[ i ] + capName;\n\t\tif ( name in style ) {\n\t\t\treturn name;\n\t\t}\n\t}\n\n\treturn origName;\n}\n\nfunction showHide( elements, show ) {\n\tvar display, elem, hidden,\n\t\tvalues = [],\n\t\tindex = 0,\n\t\tlength = elements.length;\n\n\tfor ( ; index < length; index++ ) {\n\t\telem = elements[ index ];\n\t\tif ( !elem.style ) {\n\t\t\tcontinue;\n\t\t}\n\n\t\tvalues[ index ] = jQuery._data( elem, \"olddisplay\" );\n\t\tdisplay = elem.style.display;\n\t\tif ( show ) {\n\t\t\t// Reset the inline display of this element to learn if it is\n\t\t\t// being hidden by cascaded rules or not\n\t\t\tif ( !values[ index ] && display === \"none\" ) {\n\t\t\t\telem.style.display = \"\";\n\t\t\t}\n\n\t\t\t// Set elements which have been overridden with display: none\n\t\t\t// in a stylesheet to whatever the default browser style is\n\t\t\t// for such an element\n\t\t\tif ( elem.style.display === \"\" && isHidden( elem ) ) {\n\t\t\t\tvalues[ index ] = jQuery._data( elem, \"olddisplay\", defaultDisplay(elem.nodeName) );\n\t\t\t}\n\t\t} else {\n\t\t\thidden = isHidden( elem );\n\n\t\t\tif ( display && display !== \"none\" || !hidden ) {\n\t\t\t\tjQuery._data( elem, \"olddisplay\", hidden ? display : jQuery.css( elem, \"display\" ) );\n\t\t\t}\n\t\t}\n\t}\n\n\t// Set the display of most of the elements in a second loop\n\t// to avoid the constant reflow\n\tfor ( index = 0; index < length; index++ ) {\n\t\telem = elements[ index ];\n\t\tif ( !elem.style ) {\n\t\t\tcontinue;\n\t\t}\n\t\tif ( !show || elem.style.display === \"none\" || elem.style.display === \"\" ) {\n\t\t\telem.style.display = show ? values[ index ] || \"\" : \"none\";\n\t\t}\n\t}\n\n\treturn elements;\n}\n\nfunction setPositiveNumber( elem, value, subtract ) {\n\tvar matches = rnumsplit.exec( value );\n\treturn matches ?\n\t\t// Guard against undefined \"subtract\", e.g., when used as in cssHooks\n\t\tMath.max( 0, matches[ 1 ] - ( subtract || 0 ) ) + ( matches[ 2 ] || \"px\" ) :\n\t\tvalue;\n}\n\nfunction augmentWidthOrHeight( elem, name, extra, isBorderBox, styles ) {\n\tvar i = extra === ( isBorderBox ? \"border\" : \"content\" ) ?\n\t\t// If we already have the right measurement, avoid augmentation\n\t\t4 :\n\t\t// Otherwise initialize for horizontal or vertical properties\n\t\tname === \"width\" ? 1 : 0,\n\n\t\tval = 0;\n\n\tfor ( ; i < 4; i += 2 ) {\n\t\t// both box models exclude margin, so add it if we want it\n\t\tif ( extra === \"margin\" ) {\n\t\t\tval += jQuery.css( elem, extra + cssExpand[ i ], true, styles );\n\t\t}\n\n\t\tif ( isBorderBox ) {\n\t\t\t// border-box includes padding, so remove it if we want content\n\t\t\tif ( extra === \"content\" ) {\n\t\t\t\tval -= jQuery.css( elem, \"padding\" + cssExpand[ i ], true, styles );\n\t\t\t}\n\n\t\t\t// at this point, extra isn't border nor margin, so remove border\n\t\t\tif ( extra !== \"margin\" ) {\n\t\t\t\tval -= jQuery.css( elem, \"border\" + cssExpand[ i ] + \"Width\", true, styles );\n\t\t\t}\n\t\t} else {\n\t\t\t// at this point, extra isn't content, so add padding\n\t\t\tval += jQuery.css( elem, \"padding\" + cssExpand[ i ], true, styles );\n\n\t\t\t// at this point, extra isn't content nor padding, so add border\n\t\t\tif ( extra !== \"padding\" ) {\n\t\t\t\tval += jQuery.css( elem, \"border\" + cssExpand[ i ] + \"Width\", true, styles );\n\t\t\t}\n\t\t}\n\t}\n\n\treturn val;\n}\n\nfunction getWidthOrHeight( elem, name, extra ) {\n\n\t// Start with offset property, which is equivalent to the border-box value\n\tvar valueIsBorderBox = true,\n\t\tval = name === \"width\" ? elem.offsetWidth : elem.offsetHeight,\n\t\tstyles = getStyles( elem ),\n\t\tisBorderBox = support.boxSizing && jQuery.css( elem, \"boxSizing\", false, styles ) === \"border-box\";\n\n\t// some non-html elements return undefined for offsetWidth, so check for null/undefined\n\t// svg - https://bugzilla.mozilla.org/show_bug.cgi?id=649285\n\t// MathML - https://bugzilla.mozilla.org/show_bug.cgi?id=491668\n\tif ( val <= 0 || val == null ) {\n\t\t// Fall back to computed then uncomputed css if necessary\n\t\tval = curCSS( elem, name, styles );\n\t\tif ( val < 0 || val == null ) {\n\t\t\tval = elem.style[ name ];\n\t\t}\n\n\t\t// Computed unit is not pixels. Stop here and return.\n\t\tif ( rnumnonpx.test(val) ) {\n\t\t\treturn val;\n\t\t}\n\n\t\t// we need the check for style in case a browser which returns unreliable values\n\t\t// for getComputedStyle silently falls back to the reliable elem.style\n\t\tvalueIsBorderBox = isBorderBox && ( support.boxSizingReliable() || val === elem.style[ name ] );\n\n\t\t// Normalize \"\", auto, and prepare for extra\n\t\tval = parseFloat( val ) || 0;\n\t}\n\n\t// use the active box-sizing model to add/subtract irrelevant styles\n\treturn ( val +\n\t\taugmentWidthOrHeight(\n\t\t\telem,\n\t\t\tname,\n\t\t\textra || ( isBorderBox ? \"border\" : \"content\" ),\n\t\t\tvalueIsBorderBox,\n\t\t\tstyles\n\t\t)\n\t) + \"px\";\n}\n\njQuery.extend({\n\t// Add in style property hooks for overriding the default\n\t// behavior of getting and setting a style property\n\tcssHooks: {\n\t\topacity: {\n\t\t\tget: function( elem, computed ) {\n\t\t\t\tif ( computed ) {\n\t\t\t\t\t// We should always get a number back from opacity\n\t\t\t\t\tvar ret = curCSS( elem, \"opacity\" );\n\t\t\t\t\treturn ret === \"\" ? \"1\" : ret;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t},\n\n\t// Don't automatically add \"px\" to these possibly-unitless properties\n\tcssNumber: {\n\t\t\"columnCount\": true,\n\t\t\"fillOpacity\": true,\n\t\t\"flexGrow\": true,\n\t\t\"flexShrink\": true,\n\t\t\"fontWeight\": true,\n\t\t\"lineHeight\": true,\n\t\t\"opacity\": true,\n\t\t\"order\": true,\n\t\t\"orphans\": true,\n\t\t\"widows\": true,\n\t\t\"zIndex\": true,\n\t\t\"zoom\": true\n\t},\n\n\t// Add in properties whose names you wish to fix before\n\t// setting or getting the value\n\tcssProps: {\n\t\t// normalize float css property\n\t\t\"float\": support.cssFloat ? \"cssFloat\" : \"styleFloat\"\n\t},\n\n\t// Get and set the style property on a DOM Node\n\tstyle: function( elem, name, value, extra ) {\n\t\t// Don't set styles on text and comment nodes\n\t\tif ( !elem || elem.nodeType === 3 || elem.nodeType === 8 || !elem.style ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Make sure that we're working with the right name\n\t\tvar ret, type, hooks,\n\t\t\torigName = jQuery.camelCase( name ),\n\t\t\tstyle = elem.style;\n\n\t\tname = jQuery.cssProps[ origName ] || ( jQuery.cssProps[ origName ] = vendorPropName( style, origName ) );\n\n\t\t// gets hook for the prefixed version\n\t\t// followed by the unprefixed version\n\t\thooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ];\n\n\t\t// Check if we're setting a value\n\t\tif ( value !== undefined ) {\n\t\t\ttype = typeof value;\n\n\t\t\t// convert relative number strings (+= or -=) to relative numbers. #7345\n\t\t\tif ( type === \"string\" && (ret = rrelNum.exec( value )) ) {\n\t\t\t\tvalue = ( ret[1] + 1 ) * ret[2] + parseFloat( jQuery.css( elem, name ) );\n\t\t\t\t// Fixes bug #9237\n\t\t\t\ttype = \"number\";\n\t\t\t}\n\n\t\t\t// Make sure that null and NaN values aren't set. See: #7116\n\t\t\tif ( value == null || value !== value ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// If a number was passed in, add 'px' to the (except for certain CSS properties)\n\t\t\tif ( type === \"number\" && !jQuery.cssNumber[ origName ] ) {\n\t\t\t\tvalue += \"px\";\n\t\t\t}\n\n\t\t\t// Fixes #8908, it can be done more correctly by specifing setters in cssHooks,\n\t\t\t// but it would mean to define eight (for every problematic property) identical functions\n\t\t\tif ( !support.clearCloneStyle && value === \"\" && name.indexOf(\"background\") === 0 ) {\n\t\t\t\tstyle[ name ] = \"inherit\";\n\t\t\t}\n\n\t\t\t// If a hook was provided, use that value, otherwise just set the specified value\n\t\t\tif ( !hooks || !(\"set\" in hooks) || (value = hooks.set( elem, value, extra )) !== undefined ) {\n\n\t\t\t\t// Support: IE\n\t\t\t\t// Swallow errors from 'invalid' CSS values (#5509)\n\t\t\t\ttry {\n\t\t\t\t\tstyle[ name ] = value;\n\t\t\t\t} catch(e) {}\n\t\t\t}\n\n\t\t} else {\n\t\t\t// If a hook was provided get the non-computed value from there\n\t\t\tif ( hooks && \"get\" in hooks && (ret = hooks.get( elem, false, extra )) !== undefined ) {\n\t\t\t\treturn ret;\n\t\t\t}\n\n\t\t\t// Otherwise just get the value from the style object\n\t\t\treturn style[ name ];\n\t\t}\n\t},\n\n\tcss: function( elem, name, extra, styles ) {\n\t\tvar num, val, hooks,\n\t\t\torigName = jQuery.camelCase( name );\n\n\t\t// Make sure that we're working with the right name\n\t\tname = jQuery.cssProps[ origName ] || ( jQuery.cssProps[ origName ] = vendorPropName( elem.style, origName ) );\n\n\t\t// gets hook for the prefixed version\n\t\t// followed by the unprefixed version\n\t\thooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ];\n\n\t\t// If a hook was provided get the computed value from there\n\t\tif ( hooks && \"get\" in hooks ) {\n\t\t\tval = hooks.get( elem, true, extra );\n\t\t}\n\n\t\t// Otherwise, if a way to get the computed value exists, use that\n\t\tif ( val === undefined ) {\n\t\t\tval = curCSS( elem, name, styles );\n\t\t}\n\n\t\t//convert \"normal\" to computed value\n\t\tif ( val === \"normal\" && name in cssNormalTransform ) {\n\t\t\tval = cssNormalTransform[ name ];\n\t\t}\n\n\t\t// Return, converting to number if forced or a qualifier was provided and val looks numeric\n\t\tif ( extra === \"\" || extra ) {\n\t\t\tnum = parseFloat( val );\n\t\t\treturn extra === true || jQuery.isNumeric( num ) ? num || 0 : val;\n\t\t}\n\t\treturn val;\n\t}\n});\n\njQuery.each([ \"height\", \"width\" ], function( i, name ) {\n\tjQuery.cssHooks[ name ] = {\n\t\tget: function( elem, computed, extra ) {\n\t\t\tif ( computed ) {\n\t\t\t\t// certain elements can have dimension info if we invisibly show them\n\t\t\t\t// however, it must have a current display style that would benefit from this\n\t\t\t\treturn rdisplayswap.test( jQuery.css( elem, \"display\" ) ) && elem.offsetWidth === 0 ?\n\t\t\t\t\tjQuery.swap( elem, cssShow, function() {\n\t\t\t\t\t\treturn getWidthOrHeight( elem, name, extra );\n\t\t\t\t\t}) :\n\t\t\t\t\tgetWidthOrHeight( elem, name, extra );\n\t\t\t}\n\t\t},\n\n\t\tset: function( elem, value, extra ) {\n\t\t\tvar styles = extra && getStyles( elem );\n\t\t\treturn setPositiveNumber( elem, value, extra ?\n\t\t\t\taugmentWidthOrHeight(\n\t\t\t\t\telem,\n\t\t\t\t\tname,\n\t\t\t\t\textra,\n\t\t\t\t\tsupport.boxSizing && jQuery.css( elem, \"boxSizing\", false, styles ) === \"border-box\",\n\t\t\t\t\tstyles\n\t\t\t\t) : 0\n\t\t\t);\n\t\t}\n\t};\n});\n\nif ( !support.opacity ) {\n\tjQuery.cssHooks.opacity = {\n\t\tget: function( elem, computed ) {\n\t\t\t// IE uses filters for opacity\n\t\t\treturn ropacity.test( (computed && elem.currentStyle ? elem.currentStyle.filter : elem.style.filter) || \"\" ) ?\n\t\t\t\t( 0.01 * parseFloat( RegExp.$1 ) ) + \"\" :\n\t\t\t\tcomputed ? \"1\" : \"\";\n\t\t},\n\n\t\tset: function( elem, value ) {\n\t\t\tvar style = elem.style,\n\t\t\t\tcurrentStyle = elem.currentStyle,\n\t\t\t\topacity = jQuery.isNumeric( value ) ? \"alpha(opacity=\" + value * 100 + \")\" : \"\",\n\t\t\t\tfilter = currentStyle && currentStyle.filter || style.filter || \"\";\n\n\t\t\t// IE has trouble with opacity if it does not have layout\n\t\t\t// Force it by setting the zoom level\n\t\t\tstyle.zoom = 1;\n\n\t\t\t// if setting opacity to 1, and no other filters exist - attempt to remove filter attribute #6652\n\t\t\t// if value === \"\", then remove inline opacity #12685\n\t\t\tif ( ( value >= 1 || value === \"\" ) &&\n\t\t\t\t\tjQuery.trim( filter.replace( ralpha, \"\" ) ) === \"\" &&\n\t\t\t\t\tstyle.removeAttribute ) {\n\n\t\t\t\t// Setting style.filter to null, \"\" & \" \" still leave \"filter:\" in the cssText\n\t\t\t\t// if \"filter:\" is present at all, clearType is disabled, we want to avoid this\n\t\t\t\t// style.removeAttribute is IE Only, but so apparently is this code path...\n\t\t\t\tstyle.removeAttribute( \"filter\" );\n\n\t\t\t\t// if there is no filter style applied in a css rule or unset inline opacity, we are done\n\t\t\t\tif ( value === \"\" || currentStyle && !currentStyle.filter ) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// otherwise, set new filter values\n\t\t\tstyle.filter = ralpha.test( filter ) ?\n\t\t\t\tfilter.replace( ralpha, opacity ) :\n\t\t\t\tfilter + \" \" + opacity;\n\t\t}\n\t};\n}\n\njQuery.cssHooks.marginRight = addGetHookIf( support.reliableMarginRight,\n\tfunction( elem, computed ) {\n\t\tif ( computed ) {\n\t\t\t// WebKit Bug 13343 - getComputedStyle returns wrong value for margin-right\n\t\t\t// Work around by temporarily setting element display to inline-block\n\t\t\treturn jQuery.swap( elem, { \"display\": \"inline-block\" },\n\t\t\t\tcurCSS, [ elem, \"marginRight\" ] );\n\t\t}\n\t}\n);\n\n// These hooks are used by animate to expand properties\njQuery.each({\n\tmargin: \"\",\n\tpadding: \"\",\n\tborder: \"Width\"\n}, function( prefix, suffix ) {\n\tjQuery.cssHooks[ prefix + suffix ] = {\n\t\texpand: function( value ) {\n\t\t\tvar i = 0,\n\t\t\t\texpanded = {},\n\n\t\t\t\t// assumes a single number if not a string\n\t\t\t\tparts = typeof value === \"string\" ? value.split(\" \") : [ value ];\n\n\t\t\tfor ( ; i < 4; i++ ) {\n\t\t\t\texpanded[ prefix + cssExpand[ i ] + suffix ] =\n\t\t\t\t\tparts[ i ] || parts[ i - 2 ] || parts[ 0 ];\n\t\t\t}\n\n\t\t\treturn expanded;\n\t\t}\n\t};\n\n\tif ( !rmargin.test( prefix ) ) {\n\t\tjQuery.cssHooks[ prefix + suffix ].set = setPositiveNumber;\n\t}\n});\n\njQuery.fn.extend({\n\tcss: function( name, value ) {\n\t\treturn access( this, function( elem, name, value ) {\n\t\t\tvar styles, len,\n\t\t\t\tmap = {},\n\t\t\t\ti = 0;\n\n\t\t\tif ( jQuery.isArray( name ) ) {\n\t\t\t\tstyles = getStyles( elem );\n\t\t\t\tlen = name.length;\n\n\t\t\t\tfor ( ; i < len; i++ ) {\n\t\t\t\t\tmap[ name[ i ] ] = jQuery.css( elem, name[ i ], false, styles );\n\t\t\t\t}\n\n\t\t\t\treturn map;\n\t\t\t}\n\n\t\t\treturn value !== undefined ?\n\t\t\t\tjQuery.style( elem, name, value ) :\n\t\t\t\tjQuery.css( elem, name );\n\t\t}, name, value, arguments.length > 1 );\n\t},\n\tshow: function() {\n\t\treturn showHide( this, true );\n\t},\n\thide: function() {\n\t\treturn showHide( this );\n\t},\n\ttoggle: function( state ) {\n\t\tif ( typeof state === \"boolean\" ) {\n\t\t\treturn state ? this.show() : this.hide();\n\t\t}\n\n\t\treturn this.each(function() {\n\t\t\tif ( isHidden( this ) ) {\n\t\t\t\tjQuery( this ).show();\n\t\t\t} else {\n\t\t\t\tjQuery( this ).hide();\n\t\t\t}\n\t\t});\n\t}\n});\n\n\nfunction Tween( elem, options, prop, end, easing ) {\n\treturn new Tween.prototype.init( elem, options, prop, end, easing );\n}\njQuery.Tween = Tween;\n\nTween.prototype = {\n\tconstructor: Tween,\n\tinit: function( elem, options, prop, end, easing, unit ) {\n\t\tthis.elem = elem;\n\t\tthis.prop = prop;\n\t\tthis.easing = easing || \"swing\";\n\t\tthis.options = options;\n\t\tthis.start = this.now = this.cur();\n\t\tthis.end = end;\n\t\tthis.unit = unit || ( jQuery.cssNumber[ prop ] ? \"\" : \"px\" );\n\t},\n\tcur: function() {\n\t\tvar hooks = Tween.propHooks[ this.prop ];\n\n\t\treturn hooks && hooks.get ?\n\t\t\thooks.get( this ) :\n\t\t\tTween.propHooks._default.get( this );\n\t},\n\trun: function( percent ) {\n\t\tvar eased,\n\t\t\thooks = Tween.propHooks[ this.prop ];\n\n\t\tif ( this.options.duration ) {\n\t\t\tthis.pos = eased = jQuery.easing[ this.easing ](\n\t\t\t\tpercent, this.options.duration * percent, 0, 1, this.options.duration\n\t\t\t);\n\t\t} else {\n\t\t\tthis.pos = eased = percent;\n\t\t}\n\t\tthis.now = ( this.end - this.start ) * eased + this.start;\n\n\t\tif ( this.options.step ) {\n\t\t\tthis.options.step.call( this.elem, this.now, this );\n\t\t}\n\n\t\tif ( hooks && hooks.set ) {\n\t\t\thooks.set( this );\n\t\t} else {\n\t\t\tTween.propHooks._default.set( this );\n\t\t}\n\t\treturn this;\n\t}\n};\n\nTween.prototype.init.prototype = Tween.prototype;\n\nTween.propHooks = {\n\t_default: {\n\t\tget: function( tween ) {\n\t\t\tvar result;\n\n\t\t\tif ( tween.elem[ tween.prop ] != null &&\n\t\t\t\t(!tween.elem.style || tween.elem.style[ tween.prop ] == null) ) {\n\t\t\t\treturn tween.elem[ tween.prop ];\n\t\t\t}\n\n\t\t\t// passing an empty string as a 3rd parameter to .css will automatically\n\t\t\t// attempt a parseFloat and fallback to a string if the parse fails\n\t\t\t// so, simple values such as \"10px\" are parsed to Float.\n\t\t\t// complex values such as \"rotate(1rad)\" are returned as is.\n\t\t\tresult = jQuery.css( tween.elem, tween.prop, \"\" );\n\t\t\t// Empty strings, null, undefined and \"auto\" are converted to 0.\n\t\t\treturn !result || result === \"auto\" ? 0 : result;\n\t\t},\n\t\tset: function( tween ) {\n\t\t\t// use step hook for back compat - use cssHook if its there - use .style if its\n\t\t\t// available and use plain properties where available\n\t\t\tif ( jQuery.fx.step[ tween.prop ] ) {\n\t\t\t\tjQuery.fx.step[ tween.prop ]( tween );\n\t\t\t} else if ( tween.elem.style && ( tween.elem.style[ jQuery.cssProps[ tween.prop ] ] != null || jQuery.cssHooks[ tween.prop ] ) ) {\n\t\t\t\tjQuery.style( tween.elem, tween.prop, tween.now + tween.unit );\n\t\t\t} else {\n\t\t\t\ttween.elem[ tween.prop ] = tween.now;\n\t\t\t}\n\t\t}\n\t}\n};\n\n// Support: IE <=9\n// Panic based approach to setting things on disconnected nodes\n\nTween.propHooks.scrollTop = Tween.propHooks.scrollLeft = {\n\tset: function( tween ) {\n\t\tif ( tween.elem.nodeType && tween.elem.parentNode ) {\n\t\t\ttween.elem[ tween.prop ] = tween.now;\n\t\t}\n\t}\n};\n\njQuery.easing = {\n\tlinear: function( p ) {\n\t\treturn p;\n\t},\n\tswing: function( p ) {\n\t\treturn 0.5 - Math.cos( p * Math.PI ) / 2;\n\t}\n};\n\njQuery.fx = Tween.prototype.init;\n\n// Back Compat <1.8 extension point\njQuery.fx.step = {};\n\n\n\n\nvar\n\tfxNow, timerId,\n\trfxtypes = /^(?:toggle|show|hide)$/,\n\trfxnum = new RegExp( \"^(?:([+-])=|)(\" + pnum + \")([a-z%]*)$\", \"i\" ),\n\trrun = /queueHooks$/,\n\tanimationPrefilters = [ defaultPrefilter ],\n\ttweeners = {\n\t\t\"*\": [ function( prop, value ) {\n\t\t\tvar tween = this.createTween( prop, value ),\n\t\t\t\ttarget = tween.cur(),\n\t\t\t\tparts = rfxnum.exec( value ),\n\t\t\t\tunit = parts && parts[ 3 ] || ( jQuery.cssNumber[ prop ] ? \"\" : \"px\" ),\n\n\t\t\t\t// Starting value computation is required for potential unit mismatches\n\t\t\t\tstart = ( jQuery.cssNumber[ prop ] || unit !== \"px\" && +target ) &&\n\t\t\t\t\trfxnum.exec( jQuery.css( tween.elem, prop ) ),\n\t\t\t\tscale = 1,\n\t\t\t\tmaxIterations = 20;\n\n\t\t\tif ( start && start[ 3 ] !== unit ) {\n\t\t\t\t// Trust units reported by jQuery.css\n\t\t\t\tunit = unit || start[ 3 ];\n\n\t\t\t\t// Make sure we update the tween properties later on\n\t\t\t\tparts = parts || [];\n\n\t\t\t\t// Iteratively approximate from a nonzero starting point\n\t\t\t\tstart = +target || 1;\n\n\t\t\t\tdo {\n\t\t\t\t\t// If previous iteration zeroed out, double until we get *something*\n\t\t\t\t\t// Use a string for doubling factor so we don't accidentally see scale as unchanged below\n\t\t\t\t\tscale = scale || \".5\";\n\n\t\t\t\t\t// Adjust and apply\n\t\t\t\t\tstart = start / scale;\n\t\t\t\t\tjQuery.style( tween.elem, prop, start + unit );\n\n\t\t\t\t// Update scale, tolerating zero or NaN from tween.cur()\n\t\t\t\t// And breaking the loop if scale is unchanged or perfect, or if we've just had enough\n\t\t\t\t} while ( scale !== (scale = tween.cur() / target) && scale !== 1 && --maxIterations );\n\t\t\t}\n\n\t\t\t// Update tween properties\n\t\t\tif ( parts ) {\n\t\t\t\tstart = tween.start = +start || +target || 0;\n\t\t\t\ttween.unit = unit;\n\t\t\t\t// If a +=/-= token was provided, we're doing a relative animation\n\t\t\t\ttween.end = parts[ 1 ] ?\n\t\t\t\t\tstart + ( parts[ 1 ] + 1 ) * parts[ 2 ] :\n\t\t\t\t\t+parts[ 2 ];\n\t\t\t}\n\n\t\t\treturn tween;\n\t\t} ]\n\t};\n\n// Animations created synchronously will run synchronously\nfunction createFxNow() {\n\tsetTimeout(function() {\n\t\tfxNow = undefined;\n\t});\n\treturn ( fxNow = jQuery.now() );\n}\n\n// Generate parameters to create a standard animation\nfunction genFx( type, includeWidth ) {\n\tvar which,\n\t\tattrs = { height: type },\n\t\ti = 0;\n\n\t// if we include width, step value is 1 to do all cssExpand values,\n\t// if we don't include width, step value is 2 to skip over Left and Right\n\tincludeWidth = includeWidth ? 1 : 0;\n\tfor ( ; i < 4 ; i += 2 - includeWidth ) {\n\t\twhich = cssExpand[ i ];\n\t\tattrs[ \"margin\" + which ] = attrs[ \"padding\" + which ] = type;\n\t}\n\n\tif ( includeWidth ) {\n\t\tattrs.opacity = attrs.width = type;\n\t}\n\n\treturn attrs;\n}\n\nfunction createTween( value, prop, animation ) {\n\tvar tween,\n\t\tcollection = ( tweeners[ prop ] || [] ).concat( tweeners[ \"*\" ] ),\n\t\tindex = 0,\n\t\tlength = collection.length;\n\tfor ( ; index < length; index++ ) {\n\t\tif ( (tween = collection[ index ].call( animation, prop, value )) ) {\n\n\t\t\t// we're done with this property\n\t\t\treturn tween;\n\t\t}\n\t}\n}\n\nfunction defaultPrefilter( elem, props, opts ) {\n\t/* jshint validthis: true */\n\tvar prop, value, toggle, tween, hooks, oldfire, display, checkDisplay,\n\t\tanim = this,\n\t\torig = {},\n\t\tstyle = elem.style,\n\t\thidden = elem.nodeType && isHidden( elem ),\n\t\tdataShow = jQuery._data( elem, \"fxshow\" );\n\n\t// handle queue: false promises\n\tif ( !opts.queue ) {\n\t\thooks = jQuery._queueHooks( elem, \"fx\" );\n\t\tif ( hooks.unqueued == null ) {\n\t\t\thooks.unqueued = 0;\n\t\t\toldfire = hooks.empty.fire;\n\t\t\thooks.empty.fire = function() {\n\t\t\t\tif ( !hooks.unqueued ) {\n\t\t\t\t\toldfire();\n\t\t\t\t}\n\t\t\t};\n\t\t}\n\t\thooks.unqueued++;\n\n\t\tanim.always(function() {\n\t\t\t// doing this makes sure that the complete handler will be called\n\t\t\t// before this completes\n\t\t\tanim.always(function() {\n\t\t\t\thooks.unqueued--;\n\t\t\t\tif ( !jQuery.queue( elem, \"fx\" ).length ) {\n\t\t\t\t\thooks.empty.fire();\n\t\t\t\t}\n\t\t\t});\n\t\t});\n\t}\n\n\t// height/width overflow pass\n\tif ( elem.nodeType === 1 && ( \"height\" in props || \"width\" in props ) ) {\n\t\t// Make sure that nothing sneaks out\n\t\t// Record all 3 overflow attributes because IE does not\n\t\t// change the overflow attribute when overflowX and\n\t\t// overflowY are set to the same value\n\t\topts.overflow = [ style.overflow, style.overflowX, style.overflowY ];\n\n\t\t// Set display property to inline-block for height/width\n\t\t// animations on inline elements that are having width/height animated\n\t\tdisplay = jQuery.css( elem, \"display\" );\n\n\t\t// Test default display if display is currently \"none\"\n\t\tcheckDisplay = display === \"none\" ?\n\t\t\tjQuery._data( elem, \"olddisplay\" ) || defaultDisplay( elem.nodeName ) : display;\n\n\t\tif ( checkDisplay === \"inline\" && jQuery.css( elem, \"float\" ) === \"none\" ) {\n\n\t\t\t// inline-level elements accept inline-block;\n\t\t\t// block-level elements need to be inline with layout\n\t\t\tif ( !support.inlineBlockNeedsLayout || defaultDisplay( elem.nodeName ) === \"inline\" ) {\n\t\t\t\tstyle.display = \"inline-block\";\n\t\t\t} else {\n\t\t\t\tstyle.zoom = 1;\n\t\t\t}\n\t\t}\n\t}\n\n\tif ( opts.overflow ) {\n\t\tstyle.overflow = \"hidden\";\n\t\tif ( !support.shrinkWrapBlocks() ) {\n\t\t\tanim.always(function() {\n\t\t\t\tstyle.overflow = opts.overflow[ 0 ];\n\t\t\t\tstyle.overflowX = opts.overflow[ 1 ];\n\t\t\t\tstyle.overflowY = opts.overflow[ 2 ];\n\t\t\t});\n\t\t}\n\t}\n\n\t// show/hide pass\n\tfor ( prop in props ) {\n\t\tvalue = props[ prop ];\n\t\tif ( rfxtypes.exec( value ) ) {\n\t\t\tdelete props[ prop ];\n\t\t\ttoggle = toggle || value === \"toggle\";\n\t\t\tif ( value === ( hidden ? \"hide\" : \"show\" ) ) {\n\n\t\t\t\t// If there is dataShow left over from a stopped hide or show and we are going to proceed with show, we should pretend to be hidden\n\t\t\t\tif ( value === \"show\" && dataShow && dataShow[ prop ] !== undefined ) {\n\t\t\t\t\thidden = true;\n\t\t\t\t} else {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t}\n\t\t\torig[ prop ] = dataShow && dataShow[ prop ] || jQuery.style( elem, prop );\n\n\t\t// Any non-fx value stops us from restoring the original display value\n\t\t} else {\n\t\t\tdisplay = undefined;\n\t\t}\n\t}\n\n\tif ( !jQuery.isEmptyObject( orig ) ) {\n\t\tif ( dataShow ) {\n\t\t\tif ( \"hidden\" in dataShow ) {\n\t\t\t\thidden = dataShow.hidden;\n\t\t\t}\n\t\t} else {\n\t\t\tdataShow = jQuery._data( elem, \"fxshow\", {} );\n\t\t}\n\n\t\t// store state if its toggle - enables .stop().toggle() to \"reverse\"\n\t\tif ( toggle ) {\n\t\t\tdataShow.hidden = !hidden;\n\t\t}\n\t\tif ( hidden ) {\n\t\t\tjQuery( elem ).show();\n\t\t} else {\n\t\t\tanim.done(function() {\n\t\t\t\tjQuery( elem ).hide();\n\t\t\t});\n\t\t}\n\t\tanim.done(function() {\n\t\t\tvar prop;\n\t\t\tjQuery._removeData( elem, \"fxshow\" );\n\t\t\tfor ( prop in orig ) {\n\t\t\t\tjQuery.style( elem, prop, orig[ prop ] );\n\t\t\t}\n\t\t});\n\t\tfor ( prop in orig ) {\n\t\t\ttween = createTween( hidden ? dataShow[ prop ] : 0, prop, anim );\n\n\t\t\tif ( !( prop in dataShow ) ) {\n\t\t\t\tdataShow[ prop ] = tween.start;\n\t\t\t\tif ( hidden ) {\n\t\t\t\t\ttween.end = tween.start;\n\t\t\t\t\ttween.start = prop === \"width\" || prop === \"height\" ? 1 : 0;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t// If this is a noop like .hide().hide(), restore an overwritten display value\n\t} else if ( (display === \"none\" ? defaultDisplay( elem.nodeName ) : display) === \"inline\" ) {\n\t\tstyle.display = display;\n\t}\n}\n\nfunction propFilter( props, specialEasing ) {\n\tvar index, name, easing, value, hooks;\n\n\t// camelCase, specialEasing and expand cssHook pass\n\tfor ( index in props ) {\n\t\tname = jQuery.camelCase( index );\n\t\teasing = specialEasing[ name ];\n\t\tvalue = props[ index ];\n\t\tif ( jQuery.isArray( value ) ) {\n\t\t\teasing = value[ 1 ];\n\t\t\tvalue = props[ index ] = value[ 0 ];\n\t\t}\n\n\t\tif ( index !== name ) {\n\t\t\tprops[ name ] = value;\n\t\t\tdelete props[ index ];\n\t\t}\n\n\t\thooks = jQuery.cssHooks[ name ];\n\t\tif ( hooks && \"expand\" in hooks ) {\n\t\t\tvalue = hooks.expand( value );\n\t\t\tdelete props[ name ];\n\n\t\t\t// not quite $.extend, this wont overwrite keys already present.\n\t\t\t// also - reusing 'index' from above because we have the correct \"name\"\n\t\t\tfor ( index in value ) {\n\t\t\t\tif ( !( index in props ) ) {\n\t\t\t\t\tprops[ index ] = value[ index ];\n\t\t\t\t\tspecialEasing[ index ] = easing;\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\tspecialEasing[ name ] = easing;\n\t\t}\n\t}\n}\n\nfunction Animation( elem, properties, options ) {\n\tvar result,\n\t\tstopped,\n\t\tindex = 0,\n\t\tlength = animationPrefilters.length,\n\t\tdeferred = jQuery.Deferred().always( function() {\n\t\t\t// don't match elem in the :animated selector\n\t\t\tdelete tick.elem;\n\t\t}),\n\t\ttick = function() {\n\t\t\tif ( stopped ) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\tvar currentTime = fxNow || createFxNow(),\n\t\t\t\tremaining = Math.max( 0, animation.startTime + animation.duration - currentTime ),\n\t\t\t\t// archaic crash bug won't allow us to use 1 - ( 0.5 || 0 ) (#12497)\n\t\t\t\ttemp = remaining / animation.duration || 0,\n\t\t\t\tpercent = 1 - temp,\n\t\t\t\tindex = 0,\n\t\t\t\tlength = animation.tweens.length;\n\n\t\t\tfor ( ; index < length ; index++ ) {\n\t\t\t\tanimation.tweens[ index ].run( percent );\n\t\t\t}\n\n\t\t\tdeferred.notifyWith( elem, [ animation, percent, remaining ]);\n\n\t\t\tif ( percent < 1 && length ) {\n\t\t\t\treturn remaining;\n\t\t\t} else {\n\t\t\t\tdeferred.resolveWith( elem, [ animation ] );\n\t\t\t\treturn false;\n\t\t\t}\n\t\t},\n\t\tanimation = deferred.promise({\n\t\t\telem: elem,\n\t\t\tprops: jQuery.extend( {}, properties ),\n\t\t\topts: jQuery.extend( true, { specialEasing: {} }, options ),\n\t\t\toriginalProperties: properties,\n\t\t\toriginalOptions: options,\n\t\t\tstartTime: fxNow || createFxNow(),\n\t\t\tduration: options.duration,\n\t\t\ttweens: [],\n\t\t\tcreateTween: function( prop, end ) {\n\t\t\t\tvar tween = jQuery.Tween( elem, animation.opts, prop, end,\n\t\t\t\t\t\tanimation.opts.specialEasing[ prop ] || animation.opts.easing );\n\t\t\t\tanimation.tweens.push( tween );\n\t\t\t\treturn tween;\n\t\t\t},\n\t\t\tstop: function( gotoEnd ) {\n\t\t\t\tvar index = 0,\n\t\t\t\t\t// if we are going to the end, we want to run all the tweens\n\t\t\t\t\t// otherwise we skip this part\n\t\t\t\t\tlength = gotoEnd ? animation.tweens.length : 0;\n\t\t\t\tif ( stopped ) {\n\t\t\t\t\treturn this;\n\t\t\t\t}\n\t\t\t\tstopped = true;\n\t\t\t\tfor ( ; index < length ; index++ ) {\n\t\t\t\t\tanimation.tweens[ index ].run( 1 );\n\t\t\t\t}\n\n\t\t\t\t// resolve when we played the last frame\n\t\t\t\t// otherwise, reject\n\t\t\t\tif ( gotoEnd ) {\n\t\t\t\t\tdeferred.resolveWith( elem, [ animation, gotoEnd ] );\n\t\t\t\t} else {\n\t\t\t\t\tdeferred.rejectWith( elem, [ animation, gotoEnd ] );\n\t\t\t\t}\n\t\t\t\treturn this;\n\t\t\t}\n\t\t}),\n\t\tprops = animation.props;\n\n\tpropFilter( props, animation.opts.specialEasing );\n\n\tfor ( ; index < length ; index++ ) {\n\t\tresult = animationPrefilters[ index ].call( animation, elem, props, animation.opts );\n\t\tif ( result ) {\n\t\t\treturn result;\n\t\t}\n\t}\n\n\tjQuery.map( props, createTween, animation );\n\n\tif ( jQuery.isFunction( animation.opts.start ) ) {\n\t\tanimation.opts.start.call( elem, animation );\n\t}\n\n\tjQuery.fx.timer(\n\t\tjQuery.extend( tick, {\n\t\t\telem: elem,\n\t\t\tanim: animation,\n\t\t\tqueue: animation.opts.queue\n\t\t})\n\t);\n\n\t// attach callbacks from options\n\treturn animation.progress( animation.opts.progress )\n\t\t.done( animation.opts.done, animation.opts.complete )\n\t\t.fail( animation.opts.fail )\n\t\t.always( animation.opts.always );\n}\n\njQuery.Animation = jQuery.extend( Animation, {\n\ttweener: function( props, callback ) {\n\t\tif ( jQuery.isFunction( props ) ) {\n\t\t\tcallback = props;\n\t\t\tprops = [ \"*\" ];\n\t\t} else {\n\t\t\tprops = props.split(\" \");\n\t\t}\n\n\t\tvar prop,\n\t\t\tindex = 0,\n\t\t\tlength = props.length;\n\n\t\tfor ( ; index < length ; index++ ) {\n\t\t\tprop = props[ index ];\n\t\t\ttweeners[ prop ] = tweeners[ prop ] || [];\n\t\t\ttweeners[ prop ].unshift( callback );\n\t\t}\n\t},\n\n\tprefilter: function( callback, prepend ) {\n\t\tif ( prepend ) {\n\t\t\tanimationPrefilters.unshift( callback );\n\t\t} else {\n\t\t\tanimationPrefilters.push( callback );\n\t\t}\n\t}\n});\n\njQuery.speed = function( speed, easing, fn ) {\n\tvar opt = speed && typeof speed === \"object\" ? jQuery.extend( {}, speed ) : {\n\t\tcomplete: fn || !fn && easing ||\n\t\t\tjQuery.isFunction( speed ) && speed,\n\t\tduration: speed,\n\t\teasing: fn && easing || easing && !jQuery.isFunction( easing ) && easing\n\t};\n\n\topt.duration = jQuery.fx.off ? 0 : typeof opt.duration === \"number\" ? opt.duration :\n\t\topt.duration in jQuery.fx.speeds ? jQuery.fx.speeds[ opt.duration ] : jQuery.fx.speeds._default;\n\n\t// normalize opt.queue - true/undefined/null -> \"fx\"\n\tif ( opt.queue == null || opt.queue === true ) {\n\t\topt.queue = \"fx\";\n\t}\n\n\t// Queueing\n\topt.old = opt.complete;\n\n\topt.complete = function() {\n\t\tif ( jQuery.isFunction( opt.old ) ) {\n\t\t\topt.old.call( this );\n\t\t}\n\n\t\tif ( opt.queue ) {\n\t\t\tjQuery.dequeue( this, opt.queue );\n\t\t}\n\t};\n\n\treturn opt;\n};\n\njQuery.fn.extend({\n\tfadeTo: function( speed, to, easing, callback ) {\n\n\t\t// show any hidden elements after setting opacity to 0\n\t\treturn this.filter( isHidden ).css( \"opacity\", 0 ).show()\n\n\t\t\t// animate to the value specified\n\t\t\t.end().animate({ opacity: to }, speed, easing, callback );\n\t},\n\tanimate: function( prop, speed, easing, callback ) {\n\t\tvar empty = jQuery.isEmptyObject( prop ),\n\t\t\toptall = jQuery.speed( speed, easing, callback ),\n\t\t\tdoAnimation = function() {\n\t\t\t\t// Operate on a copy of prop so per-property easing won't be lost\n\t\t\t\tvar anim = Animation( this, jQuery.extend( {}, prop ), optall );\n\n\t\t\t\t// Empty animations, or finishing resolves immediately\n\t\t\t\tif ( empty || jQuery._data( this, \"finish\" ) ) {\n\t\t\t\t\tanim.stop( true );\n\t\t\t\t}\n\t\t\t};\n\t\t\tdoAnimation.finish = doAnimation;\n\n\t\treturn empty || optall.queue === false ?\n\t\t\tthis.each( doAnimation ) :\n\t\t\tthis.queue( optall.queue, doAnimation );\n\t},\n\tstop: function( type, clearQueue, gotoEnd ) {\n\t\tvar stopQueue = function( hooks ) {\n\t\t\tvar stop = hooks.stop;\n\t\t\tdelete hooks.stop;\n\t\t\tstop( gotoEnd );\n\t\t};\n\n\t\tif ( typeof type !== \"string\" ) {\n\t\t\tgotoEnd = clearQueue;\n\t\t\tclearQueue = type;\n\t\t\ttype = undefined;\n\t\t}\n\t\tif ( clearQueue && type !== false ) {\n\t\t\tthis.queue( type || \"fx\", [] );\n\t\t}\n\n\t\treturn this.each(function() {\n\t\t\tvar dequeue = true,\n\t\t\t\tindex = type != null && type + \"queueHooks\",\n\t\t\t\ttimers = jQuery.timers,\n\t\t\t\tdata = jQuery._data( this );\n\n\t\t\tif ( index ) {\n\t\t\t\tif ( data[ index ] && data[ index ].stop ) {\n\t\t\t\t\tstopQueue( data[ index ] );\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tfor ( index in data ) {\n\t\t\t\t\tif ( data[ index ] && data[ index ].stop && rrun.test( index ) ) {\n\t\t\t\t\t\tstopQueue( data[ index ] );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tfor ( index = timers.length; index--; ) {\n\t\t\t\tif ( timers[ index ].elem === this && (type == null || timers[ index ].queue === type) ) {\n\t\t\t\t\ttimers[ index ].anim.stop( gotoEnd );\n\t\t\t\t\tdequeue = false;\n\t\t\t\t\ttimers.splice( index, 1 );\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// start the next in the queue if the last step wasn't forced\n\t\t\t// timers currently will call their complete callbacks, which will dequeue\n\t\t\t// but only if they were gotoEnd\n\t\t\tif ( dequeue || !gotoEnd ) {\n\t\t\t\tjQuery.dequeue( this, type );\n\t\t\t}\n\t\t});\n\t},\n\tfinish: function( type ) {\n\t\tif ( type !== false ) {\n\t\t\ttype = type || \"fx\";\n\t\t}\n\t\treturn this.each(function() {\n\t\t\tvar index,\n\t\t\t\tdata = jQuery._data( this ),\n\t\t\t\tqueue = data[ type + \"queue\" ],\n\t\t\t\thooks = data[ type + \"queueHooks\" ],\n\t\t\t\ttimers = jQuery.timers,\n\t\t\t\tlength = queue ? queue.length : 0;\n\n\t\t\t// enable finishing flag on private data\n\t\t\tdata.finish = true;\n\n\t\t\t// empty the queue first\n\t\t\tjQuery.queue( this, type, [] );\n\n\t\t\tif ( hooks && hooks.stop ) {\n\t\t\t\thooks.stop.call( this, true );\n\t\t\t}\n\n\t\t\t// look for any active animations, and finish them\n\t\t\tfor ( index = timers.length; index--; ) {\n\t\t\t\tif ( timers[ index ].elem === this && timers[ index ].queue === type ) {\n\t\t\t\t\ttimers[ index ].anim.stop( true );\n\t\t\t\t\ttimers.splice( index, 1 );\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// look for any animations in the old queue and finish them\n\t\t\tfor ( index = 0; index < length; index++ ) {\n\t\t\t\tif ( queue[ index ] && queue[ index ].finish ) {\n\t\t\t\t\tqueue[ index ].finish.call( this );\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// turn off finishing flag\n\t\t\tdelete data.finish;\n\t\t});\n\t}\n});\n\njQuery.each([ \"toggle\", \"show\", \"hide\" ], function( i, name ) {\n\tvar cssFn = jQuery.fn[ name ];\n\tjQuery.fn[ name ] = function( speed, easing, callback ) {\n\t\treturn speed == null || typeof speed === \"boolean\" ?\n\t\t\tcssFn.apply( this, arguments ) :\n\t\t\tthis.animate( genFx( name, true ), speed, easing, callback );\n\t};\n});\n\n// Generate shortcuts for custom animations\njQuery.each({\n\tslideDown: genFx(\"show\"),\n\tslideUp: genFx(\"hide\"),\n\tslideToggle: genFx(\"toggle\"),\n\tfadeIn: { opacity: \"show\" },\n\tfadeOut: { opacity: \"hide\" },\n\tfadeToggle: { opacity: \"toggle\" }\n}, function( name, props ) {\n\tjQuery.fn[ name ] = function( speed, easing, callback ) {\n\t\treturn this.animate( props, speed, easing, callback );\n\t};\n});\n\njQuery.timers = [];\njQuery.fx.tick = function() {\n\tvar timer,\n\t\ttimers = jQuery.timers,\n\t\ti = 0;\n\n\tfxNow = jQuery.now();\n\n\tfor ( ; i < timers.length; i++ ) {\n\t\ttimer = timers[ i ];\n\t\t// Checks the timer has not already been removed\n\t\tif ( !timer() && timers[ i ] === timer ) {\n\t\t\ttimers.splice( i--, 1 );\n\t\t}\n\t}\n\n\tif ( !timers.length ) {\n\t\tjQuery.fx.stop();\n\t}\n\tfxNow = undefined;\n};\n\njQuery.fx.timer = function( timer ) {\n\tjQuery.timers.push( timer );\n\tif ( timer() ) {\n\t\tjQuery.fx.start();\n\t} else {\n\t\tjQuery.timers.pop();\n\t}\n};\n\njQuery.fx.interval = 13;\n\njQuery.fx.start = function() {\n\tif ( !timerId ) {\n\t\ttimerId = setInterval( jQuery.fx.tick, jQuery.fx.interval );\n\t}\n};\n\njQuery.fx.stop = function() {\n\tclearInterval( timerId );\n\ttimerId = null;\n};\n\njQuery.fx.speeds = {\n\tslow: 600,\n\tfast: 200,\n\t// Default speed\n\t_default: 400\n};\n\n\n// Based off of the plugin by Clint Helfers, with permission.\n// http://blindsignals.com/index.php/2009/07/jquery-delay/\njQuery.fn.delay = function( time, type ) {\n\ttime = jQuery.fx ? jQuery.fx.speeds[ time ] || time : time;\n\ttype = type || \"fx\";\n\n\treturn this.queue( type, function( next, hooks ) {\n\t\tvar timeout = setTimeout( next, time );\n\t\thooks.stop = function() {\n\t\t\tclearTimeout( timeout );\n\t\t};\n\t});\n};\n\n\n(function() {\n\t// Minified: var a,b,c,d,e\n\tvar input, div, select, a, opt;\n\n\t// Setup\n\tdiv = document.createElement( \"div\" );\n\tdiv.setAttribute( \"className\", \"t\" );\n\tdiv.innerHTML = \"  <link/><table></table><a href='/a'>a</a><input type='checkbox'/>\";\n\ta = div.getElementsByTagName(\"a\")[ 0 ];\n\n\t// First batch of tests.\n\tselect = document.createElement(\"select\");\n\topt = select.appendChild( document.createElement(\"option\") );\n\tinput = div.getElementsByTagName(\"input\")[ 0 ];\n\n\ta.style.cssText = \"top:1px\";\n\n\t// Test setAttribute on camelCase class. If it works, we need attrFixes when doing get/setAttribute (ie6/7)\n\tsupport.getSetAttribute = div.className !== \"t\";\n\n\t// Get the style information from getAttribute\n\t// (IE uses .cssText instead)\n\tsupport.style = /top/.test( a.getAttribute(\"style\") );\n\n\t// Make sure that URLs aren't manipulated\n\t// (IE normalizes it by default)\n\tsupport.hrefNormalized = a.getAttribute(\"href\") === \"/a\";\n\n\t// Check the default checkbox/radio value (\"\" on WebKit; \"on\" elsewhere)\n\tsupport.checkOn = !!input.value;\n\n\t// Make sure that a selected-by-default option has a working selected property.\n\t// (WebKit defaults to false instead of true, IE too, if it's in an optgroup)\n\tsupport.optSelected = opt.selected;\n\n\t// Tests for enctype support on a form (#6743)\n\tsupport.enctype = !!document.createElement(\"form\").enctype;\n\n\t// Make sure that the options inside disabled selects aren't marked as disabled\n\t// (WebKit marks them as disabled)\n\tselect.disabled = true;\n\tsupport.optDisabled = !opt.disabled;\n\n\t// Support: IE8 only\n\t// Check if we can trust getAttribute(\"value\")\n\tinput = document.createElement( \"input\" );\n\tinput.setAttribute( \"value\", \"\" );\n\tsupport.input = input.getAttribute( \"value\" ) === \"\";\n\n\t// Check if an input maintains its value after becoming a radio\n\tinput.value = \"t\";\n\tinput.setAttribute( \"type\", \"radio\" );\n\tsupport.radioValue = input.value === \"t\";\n})();\n\n\nvar rreturn = /\\r/g;\n\njQuery.fn.extend({\n\tval: function( value ) {\n\t\tvar hooks, ret, isFunction,\n\t\t\telem = this[0];\n\n\t\tif ( !arguments.length ) {\n\t\t\tif ( elem ) {\n\t\t\t\thooks = jQuery.valHooks[ elem.type ] || jQuery.valHooks[ elem.nodeName.toLowerCase() ];\n\n\t\t\t\tif ( hooks && \"get\" in hooks && (ret = hooks.get( elem, \"value\" )) !== undefined ) {\n\t\t\t\t\treturn ret;\n\t\t\t\t}\n\n\t\t\t\tret = elem.value;\n\n\t\t\t\treturn typeof ret === \"string\" ?\n\t\t\t\t\t// handle most common string cases\n\t\t\t\t\tret.replace(rreturn, \"\") :\n\t\t\t\t\t// handle cases where value is null/undef or number\n\t\t\t\t\tret == null ? \"\" : ret;\n\t\t\t}\n\n\t\t\treturn;\n\t\t}\n\n\t\tisFunction = jQuery.isFunction( value );\n\n\t\treturn this.each(function( i ) {\n\t\t\tvar val;\n\n\t\t\tif ( this.nodeType !== 1 ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif ( isFunction ) {\n\t\t\t\tval = value.call( this, i, jQuery( this ).val() );\n\t\t\t} else {\n\t\t\t\tval = value;\n\t\t\t}\n\n\t\t\t// Treat null/undefined as \"\"; convert numbers to string\n\t\t\tif ( val == null ) {\n\t\t\t\tval = \"\";\n\t\t\t} else if ( typeof val === \"number\" ) {\n\t\t\t\tval += \"\";\n\t\t\t} else if ( jQuery.isArray( val ) ) {\n\t\t\t\tval = jQuery.map( val, function( value ) {\n\t\t\t\t\treturn value == null ? \"\" : value + \"\";\n\t\t\t\t});\n\t\t\t}\n\n\t\t\thooks = jQuery.valHooks[ this.type ] || jQuery.valHooks[ this.nodeName.toLowerCase() ];\n\n\t\t\t// If set returns undefined, fall back to normal setting\n\t\t\tif ( !hooks || !(\"set\" in hooks) || hooks.set( this, val, \"value\" ) === undefined ) {\n\t\t\t\tthis.value = val;\n\t\t\t}\n\t\t});\n\t}\n});\n\njQuery.extend({\n\tvalHooks: {\n\t\toption: {\n\t\t\tget: function( elem ) {\n\t\t\t\tvar val = jQuery.find.attr( elem, \"value\" );\n\t\t\t\treturn val != null ?\n\t\t\t\t\tval :\n\t\t\t\t\t// Support: IE10-11+\n\t\t\t\t\t// option.text throws exceptions (#14686, #14858)\n\t\t\t\t\tjQuery.trim( jQuery.text( elem ) );\n\t\t\t}\n\t\t},\n\t\tselect: {\n\t\t\tget: function( elem ) {\n\t\t\t\tvar value, option,\n\t\t\t\t\toptions = elem.options,\n\t\t\t\t\tindex = elem.selectedIndex,\n\t\t\t\t\tone = elem.type === \"select-one\" || index < 0,\n\t\t\t\t\tvalues = one ? null : [],\n\t\t\t\t\tmax = one ? index + 1 : options.length,\n\t\t\t\t\ti = index < 0 ?\n\t\t\t\t\t\tmax :\n\t\t\t\t\t\tone ? index : 0;\n\n\t\t\t\t// Loop through all the selected options\n\t\t\t\tfor ( ; i < max; i++ ) {\n\t\t\t\t\toption = options[ i ];\n\n\t\t\t\t\t// oldIE doesn't update selected after form reset (#2551)\n\t\t\t\t\tif ( ( option.selected || i === index ) &&\n\t\t\t\t\t\t\t// Don't return options that are disabled or in a disabled optgroup\n\t\t\t\t\t\t\t( support.optDisabled ? !option.disabled : option.getAttribute(\"disabled\") === null ) &&\n\t\t\t\t\t\t\t( !option.parentNode.disabled || !jQuery.nodeName( option.parentNode, \"optgroup\" ) ) ) {\n\n\t\t\t\t\t\t// Get the specific value for the option\n\t\t\t\t\t\tvalue = jQuery( option ).val();\n\n\t\t\t\t\t\t// We don't need an array for one selects\n\t\t\t\t\t\tif ( one ) {\n\t\t\t\t\t\t\treturn value;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// Multi-Selects return an array\n\t\t\t\t\t\tvalues.push( value );\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\treturn values;\n\t\t\t},\n\n\t\t\tset: function( elem, value ) {\n\t\t\t\tvar optionSet, option,\n\t\t\t\t\toptions = elem.options,\n\t\t\t\t\tvalues = jQuery.makeArray( value ),\n\t\t\t\t\ti = options.length;\n\n\t\t\t\twhile ( i-- ) {\n\t\t\t\t\toption = options[ i ];\n\n\t\t\t\t\tif ( jQuery.inArray( jQuery.valHooks.option.get( option ), values ) >= 0 ) {\n\n\t\t\t\t\t\t// Support: IE6\n\t\t\t\t\t\t// When new option element is added to select box we need to\n\t\t\t\t\t\t// force reflow of newly added node in order to workaround delay\n\t\t\t\t\t\t// of initialization properties\n\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\toption.selected = optionSet = true;\n\n\t\t\t\t\t\t} catch ( _ ) {\n\n\t\t\t\t\t\t\t// Will be executed only in IE6\n\t\t\t\t\t\t\toption.scrollHeight;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t} else {\n\t\t\t\t\t\toption.selected = false;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// Force browsers to behave consistently when non-matching value is set\n\t\t\t\tif ( !optionSet ) {\n\t\t\t\t\telem.selectedIndex = -1;\n\t\t\t\t}\n\n\t\t\t\treturn options;\n\t\t\t}\n\t\t}\n\t}\n});\n\n// Radios and checkboxes getter/setter\njQuery.each([ \"radio\", \"checkbox\" ], function() {\n\tjQuery.valHooks[ this ] = {\n\t\tset: function( elem, value ) {\n\t\t\tif ( jQuery.isArray( value ) ) {\n\t\t\t\treturn ( elem.checked = jQuery.inArray( jQuery(elem).val(), value ) >= 0 );\n\t\t\t}\n\t\t}\n\t};\n\tif ( !support.checkOn ) {\n\t\tjQuery.valHooks[ this ].get = function( elem ) {\n\t\t\t// Support: Webkit\n\t\t\t// \"\" is returned instead of \"on\" if a value isn't specified\n\t\t\treturn elem.getAttribute(\"value\") === null ? \"on\" : elem.value;\n\t\t};\n\t}\n});\n\n\n\n\nvar nodeHook, boolHook,\n\tattrHandle = jQuery.expr.attrHandle,\n\truseDefault = /^(?:checked|selected)$/i,\n\tgetSetAttribute = support.getSetAttribute,\n\tgetSetInput = support.input;\n\njQuery.fn.extend({\n\tattr: function( name, value ) {\n\t\treturn access( this, jQuery.attr, name, value, arguments.length > 1 );\n\t},\n\n\tremoveAttr: function( name ) {\n\t\treturn this.each(function() {\n\t\t\tjQuery.removeAttr( this, name );\n\t\t});\n\t}\n});\n\njQuery.extend({\n\tattr: function( elem, name, value ) {\n\t\tvar hooks, ret,\n\t\t\tnType = elem.nodeType;\n\n\t\t// don't get/set attributes on text, comment and attribute nodes\n\t\tif ( !elem || nType === 3 || nType === 8 || nType === 2 ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Fallback to prop when attributes are not supported\n\t\tif ( typeof elem.getAttribute === strundefined ) {\n\t\t\treturn jQuery.prop( elem, name, value );\n\t\t}\n\n\t\t// All attributes are lowercase\n\t\t// Grab necessary hook if one is defined\n\t\tif ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) {\n\t\t\tname = name.toLowerCase();\n\t\t\thooks = jQuery.attrHooks[ name ] ||\n\t\t\t\t( jQuery.expr.match.bool.test( name ) ? boolHook : nodeHook );\n\t\t}\n\n\t\tif ( value !== undefined ) {\n\n\t\t\tif ( value === null ) {\n\t\t\t\tjQuery.removeAttr( elem, name );\n\n\t\t\t} else if ( hooks && \"set\" in hooks && (ret = hooks.set( elem, value, name )) !== undefined ) {\n\t\t\t\treturn ret;\n\n\t\t\t} else {\n\t\t\t\telem.setAttribute( name, value + \"\" );\n\t\t\t\treturn value;\n\t\t\t}\n\n\t\t} else if ( hooks && \"get\" in hooks && (ret = hooks.get( elem, name )) !== null ) {\n\t\t\treturn ret;\n\n\t\t} else {\n\t\t\tret = jQuery.find.attr( elem, name );\n\n\t\t\t// Non-existent attributes return null, we normalize to undefined\n\t\t\treturn ret == null ?\n\t\t\t\tundefined :\n\t\t\t\tret;\n\t\t}\n\t},\n\n\tremoveAttr: function( elem, value ) {\n\t\tvar name, propName,\n\t\t\ti = 0,\n\t\t\tattrNames = value && value.match( rnotwhite );\n\n\t\tif ( attrNames && elem.nodeType === 1 ) {\n\t\t\twhile ( (name = attrNames[i++]) ) {\n\t\t\t\tpropName = jQuery.propFix[ name ] || name;\n\n\t\t\t\t// Boolean attributes get special treatment (#10870)\n\t\t\t\tif ( jQuery.expr.match.bool.test( name ) ) {\n\t\t\t\t\t// Set corresponding property to false\n\t\t\t\t\tif ( getSetInput && getSetAttribute || !ruseDefault.test( name ) ) {\n\t\t\t\t\t\telem[ propName ] = false;\n\t\t\t\t\t// Support: IE<9\n\t\t\t\t\t// Also clear defaultChecked/defaultSelected (if appropriate)\n\t\t\t\t\t} else {\n\t\t\t\t\t\telem[ jQuery.camelCase( \"default-\" + name ) ] =\n\t\t\t\t\t\t\telem[ propName ] = false;\n\t\t\t\t\t}\n\n\t\t\t\t// See #9699 for explanation of this approach (setting first, then removal)\n\t\t\t\t} else {\n\t\t\t\t\tjQuery.attr( elem, name, \"\" );\n\t\t\t\t}\n\n\t\t\t\telem.removeAttribute( getSetAttribute ? name : propName );\n\t\t\t}\n\t\t}\n\t},\n\n\tattrHooks: {\n\t\ttype: {\n\t\t\tset: function( elem, value ) {\n\t\t\t\tif ( !support.radioValue && value === \"radio\" && jQuery.nodeName(elem, \"input\") ) {\n\t\t\t\t\t// Setting the type on a radio button after the value resets the value in IE6-9\n\t\t\t\t\t// Reset value to default in case type is set after value during creation\n\t\t\t\t\tvar val = elem.value;\n\t\t\t\t\telem.setAttribute( \"type\", value );\n\t\t\t\t\tif ( val ) {\n\t\t\t\t\t\telem.value = val;\n\t\t\t\t\t}\n\t\t\t\t\treturn value;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n});\n\n// Hook for boolean attributes\nboolHook = {\n\tset: function( elem, value, name ) {\n\t\tif ( value === false ) {\n\t\t\t// Remove boolean attributes when set to false\n\t\t\tjQuery.removeAttr( elem, name );\n\t\t} else if ( getSetInput && getSetAttribute || !ruseDefault.test( name ) ) {\n\t\t\t// IE<8 needs the *property* name\n\t\t\telem.setAttribute( !getSetAttribute && jQuery.propFix[ name ] || name, name );\n\n\t\t// Use defaultChecked and defaultSelected for oldIE\n\t\t} else {\n\t\t\telem[ jQuery.camelCase( \"default-\" + name ) ] = elem[ name ] = true;\n\t\t}\n\n\t\treturn name;\n\t}\n};\n\n// Retrieve booleans specially\njQuery.each( jQuery.expr.match.bool.source.match( /\\w+/g ), function( i, name ) {\n\n\tvar getter = attrHandle[ name ] || jQuery.find.attr;\n\n\tattrHandle[ name ] = getSetInput && getSetAttribute || !ruseDefault.test( name ) ?\n\t\tfunction( elem, name, isXML ) {\n\t\t\tvar ret, handle;\n\t\t\tif ( !isXML ) {\n\t\t\t\t// Avoid an infinite loop by temporarily removing this function from the getter\n\t\t\t\thandle = attrHandle[ name ];\n\t\t\t\tattrHandle[ name ] = ret;\n\t\t\t\tret = getter( elem, name, isXML ) != null ?\n\t\t\t\t\tname.toLowerCase() :\n\t\t\t\t\tnull;\n\t\t\t\tattrHandle[ name ] = handle;\n\t\t\t}\n\t\t\treturn ret;\n\t\t} :\n\t\tfunction( elem, name, isXML ) {\n\t\t\tif ( !isXML ) {\n\t\t\t\treturn elem[ jQuery.camelCase( \"default-\" + name ) ] ?\n\t\t\t\t\tname.toLowerCase() :\n\t\t\t\t\tnull;\n\t\t\t}\n\t\t};\n});\n\n// fix oldIE attroperties\nif ( !getSetInput || !getSetAttribute ) {\n\tjQuery.attrHooks.value = {\n\t\tset: function( elem, value, name ) {\n\t\t\tif ( jQuery.nodeName( elem, \"input\" ) ) {\n\t\t\t\t// Does not return so that setAttribute is also used\n\t\t\t\telem.defaultValue = value;\n\t\t\t} else {\n\t\t\t\t// Use nodeHook if defined (#1954); otherwise setAttribute is fine\n\t\t\t\treturn nodeHook && nodeHook.set( elem, value, name );\n\t\t\t}\n\t\t}\n\t};\n}\n\n// IE6/7 do not support getting/setting some attributes with get/setAttribute\nif ( !getSetAttribute ) {\n\n\t// Use this for any attribute in IE6/7\n\t// This fixes almost every IE6/7 issue\n\tnodeHook = {\n\t\tset: function( elem, value, name ) {\n\t\t\t// Set the existing or create a new attribute node\n\t\t\tvar ret = elem.getAttributeNode( name );\n\t\t\tif ( !ret ) {\n\t\t\t\telem.setAttributeNode(\n\t\t\t\t\t(ret = elem.ownerDocument.createAttribute( name ))\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tret.value = value += \"\";\n\n\t\t\t// Break association with cloned elements by also using setAttribute (#9646)\n\t\t\tif ( name === \"value\" || value === elem.getAttribute( name ) ) {\n\t\t\t\treturn value;\n\t\t\t}\n\t\t}\n\t};\n\n\t// Some attributes are constructed with empty-string values when not defined\n\tattrHandle.id = attrHandle.name = attrHandle.coords =\n\t\tfunction( elem, name, isXML ) {\n\t\t\tvar ret;\n\t\t\tif ( !isXML ) {\n\t\t\t\treturn (ret = elem.getAttributeNode( name )) && ret.value !== \"\" ?\n\t\t\t\t\tret.value :\n\t\t\t\t\tnull;\n\t\t\t}\n\t\t};\n\n\t// Fixing value retrieval on a button requires this module\n\tjQuery.valHooks.button = {\n\t\tget: function( elem, name ) {\n\t\t\tvar ret = elem.getAttributeNode( name );\n\t\t\tif ( ret && ret.specified ) {\n\t\t\t\treturn ret.value;\n\t\t\t}\n\t\t},\n\t\tset: nodeHook.set\n\t};\n\n\t// Set contenteditable to false on removals(#10429)\n\t// Setting to empty string throws an error as an invalid value\n\tjQuery.attrHooks.contenteditable = {\n\t\tset: function( elem, value, name ) {\n\t\t\tnodeHook.set( elem, value === \"\" ? false : value, name );\n\t\t}\n\t};\n\n\t// Set width and height to auto instead of 0 on empty string( Bug #8150 )\n\t// This is for removals\n\tjQuery.each([ \"width\", \"height\" ], function( i, name ) {\n\t\tjQuery.attrHooks[ name ] = {\n\t\t\tset: function( elem, value ) {\n\t\t\t\tif ( value === \"\" ) {\n\t\t\t\t\telem.setAttribute( name, \"auto\" );\n\t\t\t\t\treturn value;\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\t});\n}\n\nif ( !support.style ) {\n\tjQuery.attrHooks.style = {\n\t\tget: function( elem ) {\n\t\t\t// Return undefined in the case of empty string\n\t\t\t// Note: IE uppercases css property names, but if we were to .toLowerCase()\n\t\t\t// .cssText, that would destroy case senstitivity in URL's, like in \"background\"\n\t\t\treturn elem.style.cssText || undefined;\n\t\t},\n\t\tset: function( elem, value ) {\n\t\t\treturn ( elem.style.cssText = value + \"\" );\n\t\t}\n\t};\n}\n\n\n\n\nvar rfocusable = /^(?:input|select|textarea|button|object)$/i,\n\trclickable = /^(?:a|area)$/i;\n\njQuery.fn.extend({\n\tprop: function( name, value ) {\n\t\treturn access( this, jQuery.prop, name, value, arguments.length > 1 );\n\t},\n\n\tremoveProp: function( name ) {\n\t\tname = jQuery.propFix[ name ] || name;\n\t\treturn this.each(function() {\n\t\t\t// try/catch handles cases where IE balks (such as removing a property on window)\n\t\t\ttry {\n\t\t\t\tthis[ name ] = undefined;\n\t\t\t\tdelete this[ name ];\n\t\t\t} catch( e ) {}\n\t\t});\n\t}\n});\n\njQuery.extend({\n\tpropFix: {\n\t\t\"for\": \"htmlFor\",\n\t\t\"class\": \"className\"\n\t},\n\n\tprop: function( elem, name, value ) {\n\t\tvar ret, hooks, notxml,\n\t\t\tnType = elem.nodeType;\n\n\t\t// don't get/set properties on text, comment and attribute nodes\n\t\tif ( !elem || nType === 3 || nType === 8 || nType === 2 ) {\n\t\t\treturn;\n\t\t}\n\n\t\tnotxml = nType !== 1 || !jQuery.isXMLDoc( elem );\n\n\t\tif ( notxml ) {\n\t\t\t// Fix name and attach hooks\n\t\t\tname = jQuery.propFix[ name ] || name;\n\t\t\thooks = jQuery.propHooks[ name ];\n\t\t}\n\n\t\tif ( value !== undefined ) {\n\t\t\treturn hooks && \"set\" in hooks && (ret = hooks.set( elem, value, name )) !== undefined ?\n\t\t\t\tret :\n\t\t\t\t( elem[ name ] = value );\n\n\t\t} else {\n\t\t\treturn hooks && \"get\" in hooks && (ret = hooks.get( elem, name )) !== null ?\n\t\t\t\tret :\n\t\t\t\telem[ name ];\n\t\t}\n\t},\n\n\tpropHooks: {\n\t\ttabIndex: {\n\t\t\tget: function( elem ) {\n\t\t\t\t// elem.tabIndex doesn't always return the correct value when it hasn't been explicitly set\n\t\t\t\t// http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/\n\t\t\t\t// Use proper attribute retrieval(#12072)\n\t\t\t\tvar tabindex = jQuery.find.attr( elem, \"tabindex\" );\n\n\t\t\t\treturn tabindex ?\n\t\t\t\t\tparseInt( tabindex, 10 ) :\n\t\t\t\t\trfocusable.test( elem.nodeName ) || rclickable.test( elem.nodeName ) && elem.href ?\n\t\t\t\t\t\t0 :\n\t\t\t\t\t\t-1;\n\t\t\t}\n\t\t}\n\t}\n});\n\n// Some attributes require a special call on IE\n// http://msdn.microsoft.com/en-us/library/ms536429%28VS.85%29.aspx\nif ( !support.hrefNormalized ) {\n\t// href/src property should get the full normalized URL (#10299/#12915)\n\tjQuery.each([ \"href\", \"src\" ], function( i, name ) {\n\t\tjQuery.propHooks[ name ] = {\n\t\t\tget: function( elem ) {\n\t\t\t\treturn elem.getAttribute( name, 4 );\n\t\t\t}\n\t\t};\n\t});\n}\n\n// Support: Safari, IE9+\n// mis-reports the default selected property of an option\n// Accessing the parent's selectedIndex property fixes it\nif ( !support.optSelected ) {\n\tjQuery.propHooks.selected = {\n\t\tget: function( elem ) {\n\t\t\tvar parent = elem.parentNode;\n\n\t\t\tif ( parent ) {\n\t\t\t\tparent.selectedIndex;\n\n\t\t\t\t// Make sure that it also works with optgroups, see #5701\n\t\t\t\tif ( parent.parentNode ) {\n\t\t\t\t\tparent.parentNode.selectedIndex;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn null;\n\t\t}\n\t};\n}\n\njQuery.each([\n\t\"tabIndex\",\n\t\"readOnly\",\n\t\"maxLength\",\n\t\"cellSpacing\",\n\t\"cellPadding\",\n\t\"rowSpan\",\n\t\"colSpan\",\n\t\"useMap\",\n\t\"frameBorder\",\n\t\"contentEditable\"\n], function() {\n\tjQuery.propFix[ this.toLowerCase() ] = this;\n});\n\n// IE6/7 call enctype encoding\nif ( !support.enctype ) {\n\tjQuery.propFix.enctype = \"encoding\";\n}\n\n\n\n\nvar rclass = /[\\t\\r\\n\\f]/g;\n\njQuery.fn.extend({\n\taddClass: function( value ) {\n\t\tvar classes, elem, cur, clazz, j, finalValue,\n\t\t\ti = 0,\n\t\t\tlen = this.length,\n\t\t\tproceed = typeof value === \"string\" && value;\n\n\t\tif ( jQuery.isFunction( value ) ) {\n\t\t\treturn this.each(function( j ) {\n\t\t\t\tjQuery( this ).addClass( value.call( this, j, this.className ) );\n\t\t\t});\n\t\t}\n\n\t\tif ( proceed ) {\n\t\t\t// The disjunction here is for better compressibility (see removeClass)\n\t\t\tclasses = ( value || \"\" ).match( rnotwhite ) || [];\n\n\t\t\tfor ( ; i < len; i++ ) {\n\t\t\t\telem = this[ i ];\n\t\t\t\tcur = elem.nodeType === 1 && ( elem.className ?\n\t\t\t\t\t( \" \" + elem.className + \" \" ).replace( rclass, \" \" ) :\n\t\t\t\t\t\" \"\n\t\t\t\t);\n\n\t\t\t\tif ( cur ) {\n\t\t\t\t\tj = 0;\n\t\t\t\t\twhile ( (clazz = classes[j++]) ) {\n\t\t\t\t\t\tif ( cur.indexOf( \" \" + clazz + \" \" ) < 0 ) {\n\t\t\t\t\t\t\tcur += clazz + \" \";\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\t// only assign if different to avoid unneeded rendering.\n\t\t\t\t\tfinalValue = jQuery.trim( cur );\n\t\t\t\t\tif ( elem.className !== finalValue ) {\n\t\t\t\t\t\telem.className = finalValue;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn this;\n\t},\n\n\tremoveClass: function( value ) {\n\t\tvar classes, elem, cur, clazz, j, finalValue,\n\t\t\ti = 0,\n\t\t\tlen = this.length,\n\t\t\tproceed = arguments.length === 0 || typeof value === \"string\" && value;\n\n\t\tif ( jQuery.isFunction( value ) ) {\n\t\t\treturn this.each(function( j ) {\n\t\t\t\tjQuery( this ).removeClass( value.call( this, j, this.className ) );\n\t\t\t});\n\t\t}\n\t\tif ( proceed ) {\n\t\t\tclasses = ( value || \"\" ).match( rnotwhite ) || [];\n\n\t\t\tfor ( ; i < len; i++ ) {\n\t\t\t\telem = this[ i ];\n\t\t\t\t// This expression is here for better compressibility (see addClass)\n\t\t\t\tcur = elem.nodeType === 1 && ( elem.className ?\n\t\t\t\t\t( \" \" + elem.className + \" \" ).replace( rclass, \" \" ) :\n\t\t\t\t\t\"\"\n\t\t\t\t);\n\n\t\t\t\tif ( cur ) {\n\t\t\t\t\tj = 0;\n\t\t\t\t\twhile ( (clazz = classes[j++]) ) {\n\t\t\t\t\t\t// Remove *all* instances\n\t\t\t\t\t\twhile ( cur.indexOf( \" \" + clazz + \" \" ) >= 0 ) {\n\t\t\t\t\t\t\tcur = cur.replace( \" \" + clazz + \" \", \" \" );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\t// only assign if different to avoid unneeded rendering.\n\t\t\t\t\tfinalValue = value ? jQuery.trim( cur ) : \"\";\n\t\t\t\t\tif ( elem.className !== finalValue ) {\n\t\t\t\t\t\telem.className = finalValue;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn this;\n\t},\n\n\ttoggleClass: function( value, stateVal ) {\n\t\tvar type = typeof value;\n\n\t\tif ( typeof stateVal === \"boolean\" && type === \"string\" ) {\n\t\t\treturn stateVal ? this.addClass( value ) : this.removeClass( value );\n\t\t}\n\n\t\tif ( jQuery.isFunction( value ) ) {\n\t\t\treturn this.each(function( i ) {\n\t\t\t\tjQuery( this ).toggleClass( value.call(this, i, this.className, stateVal), stateVal );\n\t\t\t});\n\t\t}\n\n\t\treturn this.each(function() {\n\t\t\tif ( type === \"string\" ) {\n\t\t\t\t// toggle individual class names\n\t\t\t\tvar className,\n\t\t\t\t\ti = 0,\n\t\t\t\t\tself = jQuery( this ),\n\t\t\t\t\tclassNames = value.match( rnotwhite ) || [];\n\n\t\t\t\twhile ( (className = classNames[ i++ ]) ) {\n\t\t\t\t\t// check each className given, space separated list\n\t\t\t\t\tif ( self.hasClass( className ) ) {\n\t\t\t\t\t\tself.removeClass( className );\n\t\t\t\t\t} else {\n\t\t\t\t\t\tself.addClass( className );\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t// Toggle whole class name\n\t\t\t} else if ( type === strundefined || type === \"boolean\" ) {\n\t\t\t\tif ( this.className ) {\n\t\t\t\t\t// store className if set\n\t\t\t\t\tjQuery._data( this, \"__className__\", this.className );\n\t\t\t\t}\n\n\t\t\t\t// If the element has a class name or if we're passed \"false\",\n\t\t\t\t// then remove the whole classname (if there was one, the above saved it).\n\t\t\t\t// Otherwise bring back whatever was previously saved (if anything),\n\t\t\t\t// falling back to the empty string if nothing was stored.\n\t\t\t\tthis.className = this.className || value === false ? \"\" : jQuery._data( this, \"__className__\" ) || \"\";\n\t\t\t}\n\t\t});\n\t},\n\n\thasClass: function( selector ) {\n\t\tvar className = \" \" + selector + \" \",\n\t\t\ti = 0,\n\t\t\tl = this.length;\n\t\tfor ( ; i < l; i++ ) {\n\t\t\tif ( this[i].nodeType === 1 && (\" \" + this[i].className + \" \").replace(rclass, \" \").indexOf( className ) >= 0 ) {\n\t\t\t\treturn true;\n\t\t\t}\n\t\t}\n\n\t\treturn false;\n\t}\n});\n\n\n\n\n// Return jQuery for attributes-only inclusion\n\n\njQuery.each( (\"blur focus focusin focusout load resize scroll unload click dblclick \" +\n\t\"mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave \" +\n\t\"change select submit keydown keypress keyup error contextmenu\").split(\" \"), function( i, name ) {\n\n\t// Handle event binding\n\tjQuery.fn[ name ] = function( data, fn ) {\n\t\treturn arguments.length > 0 ?\n\t\t\tthis.on( name, null, data, fn ) :\n\t\t\tthis.trigger( name );\n\t};\n});\n\njQuery.fn.extend({\n\thover: function( fnOver, fnOut ) {\n\t\treturn this.mouseenter( fnOver ).mouseleave( fnOut || fnOver );\n\t},\n\n\tbind: function( types, data, fn ) {\n\t\treturn this.on( types, null, data, fn );\n\t},\n\tunbind: function( types, fn ) {\n\t\treturn this.off( types, null, fn );\n\t},\n\n\tdelegate: function( selector, types, data, fn ) {\n\t\treturn this.on( types, selector, data, fn );\n\t},\n\tundelegate: function( selector, types, fn ) {\n\t\t// ( namespace ) or ( selector, types [, fn] )\n\t\treturn arguments.length === 1 ? this.off( selector, \"**\" ) : this.off( types, selector || \"**\", fn );\n\t}\n});\n\n\nvar nonce = jQuery.now();\n\nvar rquery = (/\\?/);\n\n\n\nvar rvalidtokens = /(,)|(\\[|{)|(}|])|\"(?:[^\"\\\\\\r\\n]|\\\\[\"\\\\\\/bfnrt]|\\\\u[\\da-fA-F]{4})*\"\\s*:?|true|false|null|-?(?!0\\d)\\d+(?:\\.\\d+|)(?:[eE][+-]?\\d+|)/g;\n\njQuery.parseJSON = function( data ) {\n\t// Attempt to parse using the native JSON parser first\n\tif ( window.JSON && window.JSON.parse ) {\n\t\t// Support: Android 2.3\n\t\t// Workaround failure to string-cast null input\n\t\treturn window.JSON.parse( data + \"\" );\n\t}\n\n\tvar requireNonComma,\n\t\tdepth = null,\n\t\tstr = jQuery.trim( data + \"\" );\n\n\t// Guard against invalid (and possibly dangerous) input by ensuring that nothing remains\n\t// after removing valid tokens\n\treturn str && !jQuery.trim( str.replace( rvalidtokens, function( token, comma, open, close ) {\n\n\t\t// Force termination if we see a misplaced comma\n\t\tif ( requireNonComma && comma ) {\n\t\t\tdepth = 0;\n\t\t}\n\n\t\t// Perform no more replacements after returning to outermost depth\n\t\tif ( depth === 0 ) {\n\t\t\treturn token;\n\t\t}\n\n\t\t// Commas must not follow \"[\", \"{\", or \",\"\n\t\trequireNonComma = open || comma;\n\n\t\t// Determine new depth\n\t\t// array/object open (\"[\" or \"{\"): depth += true - false (increment)\n\t\t// array/object close (\"]\" or \"}\"): depth += false - true (decrement)\n\t\t// other cases (\",\" or primitive): depth += true - true (numeric cast)\n\t\tdepth += !close - !open;\n\n\t\t// Remove this token\n\t\treturn \"\";\n\t}) ) ?\n\t\t( Function( \"return \" + str ) )() :\n\t\tjQuery.error( \"Invalid JSON: \" + data );\n};\n\n\n// Cross-browser xml parsing\njQuery.parseXML = function( data ) {\n\tvar xml, tmp;\n\tif ( !data || typeof data !== \"string\" ) {\n\t\treturn null;\n\t}\n\ttry {\n\t\tif ( window.DOMParser ) { // Standard\n\t\t\ttmp = new DOMParser();\n\t\t\txml = tmp.parseFromString( data, \"text/xml\" );\n\t\t} else { // IE\n\t\t\txml = new ActiveXObject( \"Microsoft.XMLDOM\" );\n\t\t\txml.async = \"false\";\n\t\t\txml.loadXML( data );\n\t\t}\n\t} catch( e ) {\n\t\txml = undefined;\n\t}\n\tif ( !xml || !xml.documentElement || xml.getElementsByTagName( \"parsererror\" ).length ) {\n\t\tjQuery.error( \"Invalid XML: \" + data );\n\t}\n\treturn xml;\n};\n\n\nvar\n\t// Document location\n\tajaxLocParts,\n\tajaxLocation,\n\n\trhash = /#.*$/,\n\trts = /([?&])_=[^&]*/,\n\trheaders = /^(.*?):[ \\t]*([^\\r\\n]*)\\r?$/mg, // IE leaves an \\r character at EOL\n\t// #7653, #8125, #8152: local protocol detection\n\trlocalProtocol = /^(?:about|app|app-storage|.+-extension|file|res|widget):$/,\n\trnoContent = /^(?:GET|HEAD)$/,\n\trprotocol = /^\\/\\//,\n\trurl = /^([\\w.+-]+:)(?:\\/\\/(?:[^\\/?#]*@|)([^\\/?#:]*)(?::(\\d+)|)|)/,\n\n\t/* Prefilters\n\t * 1) They are useful to introduce custom dataTypes (see ajax/jsonp.js for an example)\n\t * 2) These are called:\n\t *    - BEFORE asking for a transport\n\t *    - AFTER param serialization (s.data is a string if s.processData is true)\n\t * 3) key is the dataType\n\t * 4) the catchall symbol \"*\" can be used\n\t * 5) execution will start with transport dataType and THEN continue down to \"*\" if needed\n\t */\n\tprefilters = {},\n\n\t/* Transports bindings\n\t * 1) key is the dataType\n\t * 2) the catchall symbol \"*\" can be used\n\t * 3) selection will start with transport dataType and THEN go to \"*\" if needed\n\t */\n\ttransports = {},\n\n\t// Avoid comment-prolog char sequence (#10098); must appease lint and evade compression\n\tallTypes = \"*/\".concat(\"*\");\n\n// #8138, IE may throw an exception when accessing\n// a field from window.location if document.domain has been set\ntry {\n\tajaxLocation = location.href;\n} catch( e ) {\n\t// Use the href attribute of an A element\n\t// since IE will modify it given document.location\n\tajaxLocation = document.createElement( \"a\" );\n\tajaxLocation.href = \"\";\n\tajaxLocation = ajaxLocation.href;\n}\n\n// Segment location into parts\najaxLocParts = rurl.exec( ajaxLocation.toLowerCase() ) || [];\n\n// Base \"constructor\" for jQuery.ajaxPrefilter and jQuery.ajaxTransport\nfunction addToPrefiltersOrTransports( structure ) {\n\n\t// dataTypeExpression is optional and defaults to \"*\"\n\treturn function( dataTypeExpression, func ) {\n\n\t\tif ( typeof dataTypeExpression !== \"string\" ) {\n\t\t\tfunc = dataTypeExpression;\n\t\t\tdataTypeExpression = \"*\";\n\t\t}\n\n\t\tvar dataType,\n\t\t\ti = 0,\n\t\t\tdataTypes = dataTypeExpression.toLowerCase().match( rnotwhite ) || [];\n\n\t\tif ( jQuery.isFunction( func ) ) {\n\t\t\t// For each dataType in the dataTypeExpression\n\t\t\twhile ( (dataType = dataTypes[i++]) ) {\n\t\t\t\t// Prepend if requested\n\t\t\t\tif ( dataType.charAt( 0 ) === \"+\" ) {\n\t\t\t\t\tdataType = dataType.slice( 1 ) || \"*\";\n\t\t\t\t\t(structure[ dataType ] = structure[ dataType ] || []).unshift( func );\n\n\t\t\t\t// Otherwise append\n\t\t\t\t} else {\n\t\t\t\t\t(structure[ dataType ] = structure[ dataType ] || []).push( func );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t};\n}\n\n// Base inspection function for prefilters and transports\nfunction inspectPrefiltersOrTransports( structure, options, originalOptions, jqXHR ) {\n\n\tvar inspected = {},\n\t\tseekingTransport = ( structure === transports );\n\n\tfunction inspect( dataType ) {\n\t\tvar selected;\n\t\tinspected[ dataType ] = true;\n\t\tjQuery.each( structure[ dataType ] || [], function( _, prefilterOrFactory ) {\n\t\t\tvar dataTypeOrTransport = prefilterOrFactory( options, originalOptions, jqXHR );\n\t\t\tif ( typeof dataTypeOrTransport === \"string\" && !seekingTransport && !inspected[ dataTypeOrTransport ] ) {\n\t\t\t\toptions.dataTypes.unshift( dataTypeOrTransport );\n\t\t\t\tinspect( dataTypeOrTransport );\n\t\t\t\treturn false;\n\t\t\t} else if ( seekingTransport ) {\n\t\t\t\treturn !( selected = dataTypeOrTransport );\n\t\t\t}\n\t\t});\n\t\treturn selected;\n\t}\n\n\treturn inspect( options.dataTypes[ 0 ] ) || !inspected[ \"*\" ] && inspect( \"*\" );\n}\n\n// A special extend for ajax options\n// that takes \"flat\" options (not to be deep extended)\n// Fixes #9887\nfunction ajaxExtend( target, src ) {\n\tvar deep, key,\n\t\tflatOptions = jQuery.ajaxSettings.flatOptions || {};\n\n\tfor ( key in src ) {\n\t\tif ( src[ key ] !== undefined ) {\n\t\t\t( flatOptions[ key ] ? target : ( deep || (deep = {}) ) )[ key ] = src[ key ];\n\t\t}\n\t}\n\tif ( deep ) {\n\t\tjQuery.extend( true, target, deep );\n\t}\n\n\treturn target;\n}\n\n/* Handles responses to an ajax request:\n * - finds the right dataType (mediates between content-type and expected dataType)\n * - returns the corresponding response\n */\nfunction ajaxHandleResponses( s, jqXHR, responses ) {\n\tvar firstDataType, ct, finalDataType, type,\n\t\tcontents = s.contents,\n\t\tdataTypes = s.dataTypes;\n\n\t// Remove auto dataType and get content-type in the process\n\twhile ( dataTypes[ 0 ] === \"*\" ) {\n\t\tdataTypes.shift();\n\t\tif ( ct === undefined ) {\n\t\t\tct = s.mimeType || jqXHR.getResponseHeader(\"Content-Type\");\n\t\t}\n\t}\n\n\t// Check if we're dealing with a known content-type\n\tif ( ct ) {\n\t\tfor ( type in contents ) {\n\t\t\tif ( contents[ type ] && contents[ type ].test( ct ) ) {\n\t\t\t\tdataTypes.unshift( type );\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t}\n\n\t// Check to see if we have a response for the expected dataType\n\tif ( dataTypes[ 0 ] in responses ) {\n\t\tfinalDataType = dataTypes[ 0 ];\n\t} else {\n\t\t// Try convertible dataTypes\n\t\tfor ( type in responses ) {\n\t\t\tif ( !dataTypes[ 0 ] || s.converters[ type + \" \" + dataTypes[0] ] ) {\n\t\t\t\tfinalDataType = type;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tif ( !firstDataType ) {\n\t\t\t\tfirstDataType = type;\n\t\t\t}\n\t\t}\n\t\t// Or just use first one\n\t\tfinalDataType = finalDataType || firstDataType;\n\t}\n\n\t// If we found a dataType\n\t// We add the dataType to the list if needed\n\t// and return the corresponding response\n\tif ( finalDataType ) {\n\t\tif ( finalDataType !== dataTypes[ 0 ] ) {\n\t\t\tdataTypes.unshift( finalDataType );\n\t\t}\n\t\treturn responses[ finalDataType ];\n\t}\n}\n\n/* Chain conversions given the request and the original response\n * Also sets the responseXXX fields on the jqXHR instance\n */\nfunction ajaxConvert( s, response, jqXHR, isSuccess ) {\n\tvar conv2, current, conv, tmp, prev,\n\t\tconverters = {},\n\t\t// Work with a copy of dataTypes in case we need to modify it for conversion\n\t\tdataTypes = s.dataTypes.slice();\n\n\t// Create converters map with lowercased keys\n\tif ( dataTypes[ 1 ] ) {\n\t\tfor ( conv in s.converters ) {\n\t\t\tconverters[ conv.toLowerCase() ] = s.converters[ conv ];\n\t\t}\n\t}\n\n\tcurrent = dataTypes.shift();\n\n\t// Convert to each sequential dataType\n\twhile ( current ) {\n\n\t\tif ( s.responseFields[ current ] ) {\n\t\t\tjqXHR[ s.responseFields[ current ] ] = response;\n\t\t}\n\n\t\t// Apply the dataFilter if provided\n\t\tif ( !prev && isSuccess && s.dataFilter ) {\n\t\t\tresponse = s.dataFilter( response, s.dataType );\n\t\t}\n\n\t\tprev = current;\n\t\tcurrent = dataTypes.shift();\n\n\t\tif ( current ) {\n\n\t\t\t// There's only work to do if current dataType is non-auto\n\t\t\tif ( current === \"*\" ) {\n\n\t\t\t\tcurrent = prev;\n\n\t\t\t// Convert response if prev dataType is non-auto and differs from current\n\t\t\t} else if ( prev !== \"*\" && prev !== current ) {\n\n\t\t\t\t// Seek a direct converter\n\t\t\t\tconv = converters[ prev + \" \" + current ] || converters[ \"* \" + current ];\n\n\t\t\t\t// If none found, seek a pair\n\t\t\t\tif ( !conv ) {\n\t\t\t\t\tfor ( conv2 in converters ) {\n\n\t\t\t\t\t\t// If conv2 outputs current\n\t\t\t\t\t\ttmp = conv2.split( \" \" );\n\t\t\t\t\t\tif ( tmp[ 1 ] === current ) {\n\n\t\t\t\t\t\t\t// If prev can be converted to accepted input\n\t\t\t\t\t\t\tconv = converters[ prev + \" \" + tmp[ 0 ] ] ||\n\t\t\t\t\t\t\t\tconverters[ \"* \" + tmp[ 0 ] ];\n\t\t\t\t\t\t\tif ( conv ) {\n\t\t\t\t\t\t\t\t// Condense equivalence converters\n\t\t\t\t\t\t\t\tif ( conv === true ) {\n\t\t\t\t\t\t\t\t\tconv = converters[ conv2 ];\n\n\t\t\t\t\t\t\t\t// Otherwise, insert the intermediate dataType\n\t\t\t\t\t\t\t\t} else if ( converters[ conv2 ] !== true ) {\n\t\t\t\t\t\t\t\t\tcurrent = tmp[ 0 ];\n\t\t\t\t\t\t\t\t\tdataTypes.unshift( tmp[ 1 ] );\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// Apply converter (if not an equivalence)\n\t\t\t\tif ( conv !== true ) {\n\n\t\t\t\t\t// Unless errors are allowed to bubble, catch and return them\n\t\t\t\t\tif ( conv && s[ \"throws\" ] ) {\n\t\t\t\t\t\tresponse = conv( response );\n\t\t\t\t\t} else {\n\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\tresponse = conv( response );\n\t\t\t\t\t\t} catch ( e ) {\n\t\t\t\t\t\t\treturn { state: \"parsererror\", error: conv ? e : \"No conversion from \" + prev + \" to \" + current };\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\treturn { state: \"success\", data: response };\n}\n\njQuery.extend({\n\n\t// Counter for holding the number of active queries\n\tactive: 0,\n\n\t// Last-Modified header cache for next request\n\tlastModified: {},\n\tetag: {},\n\n\tajaxSettings: {\n\t\turl: ajaxLocation,\n\t\ttype: \"GET\",\n\t\tisLocal: rlocalProtocol.test( ajaxLocParts[ 1 ] ),\n\t\tglobal: true,\n\t\tprocessData: true,\n\t\tasync: true,\n\t\tcontentType: \"application/x-www-form-urlencoded; charset=UTF-8\",\n\t\t/*\n\t\ttimeout: 0,\n\t\tdata: null,\n\t\tdataType: null,\n\t\tusername: null,\n\t\tpassword: null,\n\t\tcache: null,\n\t\tthrows: false,\n\t\ttraditional: false,\n\t\theaders: {},\n\t\t*/\n\n\t\taccepts: {\n\t\t\t\"*\": allTypes,\n\t\t\ttext: \"text/plain\",\n\t\t\thtml: \"text/html\",\n\t\t\txml: \"application/xml, text/xml\",\n\t\t\tjson: \"application/json, text/javascript\"\n\t\t},\n\n\t\tcontents: {\n\t\t\txml: /xml/,\n\t\t\thtml: /html/,\n\t\t\tjson: /json/\n\t\t},\n\n\t\tresponseFields: {\n\t\t\txml: \"responseXML\",\n\t\t\ttext: \"responseText\",\n\t\t\tjson: \"responseJSON\"\n\t\t},\n\n\t\t// Data converters\n\t\t// Keys separate source (or catchall \"*\") and destination types with a single space\n\t\tconverters: {\n\n\t\t\t// Convert anything to text\n\t\t\t\"* text\": String,\n\n\t\t\t// Text to html (true = no transformation)\n\t\t\t\"text html\": true,\n\n\t\t\t// Evaluate text as a json expression\n\t\t\t\"text json\": jQuery.parseJSON,\n\n\t\t\t// Parse text as xml\n\t\t\t\"text xml\": jQuery.parseXML\n\t\t},\n\n\t\t// For options that shouldn't be deep extended:\n\t\t// you can add your own custom options here if\n\t\t// and when you create one that shouldn't be\n\t\t// deep extended (see ajaxExtend)\n\t\tflatOptions: {\n\t\t\turl: true,\n\t\t\tcontext: true\n\t\t}\n\t},\n\n\t// Creates a full fledged settings object into target\n\t// with both ajaxSettings and settings fields.\n\t// If target is omitted, writes into ajaxSettings.\n\tajaxSetup: function( target, settings ) {\n\t\treturn settings ?\n\n\t\t\t// Building a settings object\n\t\t\tajaxExtend( ajaxExtend( target, jQuery.ajaxSettings ), settings ) :\n\n\t\t\t// Extending ajaxSettings\n\t\t\tajaxExtend( jQuery.ajaxSettings, target );\n\t},\n\n\tajaxPrefilter: addToPrefiltersOrTransports( prefilters ),\n\tajaxTransport: addToPrefiltersOrTransports( transports ),\n\n\t// Main method\n\tajax: function( url, options ) {\n\n\t\t// If url is an object, simulate pre-1.5 signature\n\t\tif ( typeof url === \"object\" ) {\n\t\t\toptions = url;\n\t\t\turl = undefined;\n\t\t}\n\n\t\t// Force options to be an object\n\t\toptions = options || {};\n\n\t\tvar // Cross-domain detection vars\n\t\t\tparts,\n\t\t\t// Loop variable\n\t\t\ti,\n\t\t\t// URL without anti-cache param\n\t\t\tcacheURL,\n\t\t\t// Response headers as string\n\t\t\tresponseHeadersString,\n\t\t\t// timeout handle\n\t\t\ttimeoutTimer,\n\n\t\t\t// To know if global events are to be dispatched\n\t\t\tfireGlobals,\n\n\t\t\ttransport,\n\t\t\t// Response headers\n\t\t\tresponseHeaders,\n\t\t\t// Create the final options object\n\t\t\ts = jQuery.ajaxSetup( {}, options ),\n\t\t\t// Callbacks context\n\t\t\tcallbackContext = s.context || s,\n\t\t\t// Context for global events is callbackContext if it is a DOM node or jQuery collection\n\t\t\tglobalEventContext = s.context && ( callbackContext.nodeType || callbackContext.jquery ) ?\n\t\t\t\tjQuery( callbackContext ) :\n\t\t\t\tjQuery.event,\n\t\t\t// Deferreds\n\t\t\tdeferred = jQuery.Deferred(),\n\t\t\tcompleteDeferred = jQuery.Callbacks(\"once memory\"),\n\t\t\t// Status-dependent callbacks\n\t\t\tstatusCode = s.statusCode || {},\n\t\t\t// Headers (they are sent all at once)\n\t\t\trequestHeaders = {},\n\t\t\trequestHeadersNames = {},\n\t\t\t// The jqXHR state\n\t\t\tstate = 0,\n\t\t\t// Default abort message\n\t\t\tstrAbort = \"canceled\",\n\t\t\t// Fake xhr\n\t\t\tjqXHR = {\n\t\t\t\treadyState: 0,\n\n\t\t\t\t// Builds headers hashtable if needed\n\t\t\t\tgetResponseHeader: function( key ) {\n\t\t\t\t\tvar match;\n\t\t\t\t\tif ( state === 2 ) {\n\t\t\t\t\t\tif ( !responseHeaders ) {\n\t\t\t\t\t\t\tresponseHeaders = {};\n\t\t\t\t\t\t\twhile ( (match = rheaders.exec( responseHeadersString )) ) {\n\t\t\t\t\t\t\t\tresponseHeaders[ match[1].toLowerCase() ] = match[ 2 ];\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\tmatch = responseHeaders[ key.toLowerCase() ];\n\t\t\t\t\t}\n\t\t\t\t\treturn match == null ? null : match;\n\t\t\t\t},\n\n\t\t\t\t// Raw string\n\t\t\t\tgetAllResponseHeaders: function() {\n\t\t\t\t\treturn state === 2 ? responseHeadersString : null;\n\t\t\t\t},\n\n\t\t\t\t// Caches the header\n\t\t\t\tsetRequestHeader: function( name, value ) {\n\t\t\t\t\tvar lname = name.toLowerCase();\n\t\t\t\t\tif ( !state ) {\n\t\t\t\t\t\tname = requestHeadersNames[ lname ] = requestHeadersNames[ lname ] || name;\n\t\t\t\t\t\trequestHeaders[ name ] = value;\n\t\t\t\t\t}\n\t\t\t\t\treturn this;\n\t\t\t\t},\n\n\t\t\t\t// Overrides response content-type header\n\t\t\t\toverrideMimeType: function( type ) {\n\t\t\t\t\tif ( !state ) {\n\t\t\t\t\t\ts.mimeType = type;\n\t\t\t\t\t}\n\t\t\t\t\treturn this;\n\t\t\t\t},\n\n\t\t\t\t// Status-dependent callbacks\n\t\t\t\tstatusCode: function( map ) {\n\t\t\t\t\tvar code;\n\t\t\t\t\tif ( map ) {\n\t\t\t\t\t\tif ( state < 2 ) {\n\t\t\t\t\t\t\tfor ( code in map ) {\n\t\t\t\t\t\t\t\t// Lazy-add the new callback in a way that preserves old ones\n\t\t\t\t\t\t\t\tstatusCode[ code ] = [ statusCode[ code ], map[ code ] ];\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t// Execute the appropriate callbacks\n\t\t\t\t\t\t\tjqXHR.always( map[ jqXHR.status ] );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\treturn this;\n\t\t\t\t},\n\n\t\t\t\t// Cancel the request\n\t\t\t\tabort: function( statusText ) {\n\t\t\t\t\tvar finalText = statusText || strAbort;\n\t\t\t\t\tif ( transport ) {\n\t\t\t\t\t\ttransport.abort( finalText );\n\t\t\t\t\t}\n\t\t\t\t\tdone( 0, finalText );\n\t\t\t\t\treturn this;\n\t\t\t\t}\n\t\t\t};\n\n\t\t// Attach deferreds\n\t\tdeferred.promise( jqXHR ).complete = completeDeferred.add;\n\t\tjqXHR.success = jqXHR.done;\n\t\tjqXHR.error = jqXHR.fail;\n\n\t\t// Remove hash character (#7531: and string promotion)\n\t\t// Add protocol if not provided (#5866: IE7 issue with protocol-less urls)\n\t\t// Handle falsy url in the settings object (#10093: consistency with old signature)\n\t\t// We also use the url parameter if available\n\t\ts.url = ( ( url || s.url || ajaxLocation ) + \"\" ).replace( rhash, \"\" ).replace( rprotocol, ajaxLocParts[ 1 ] + \"//\" );\n\n\t\t// Alias method option to type as per ticket #12004\n\t\ts.type = options.method || options.type || s.method || s.type;\n\n\t\t// Extract dataTypes list\n\t\ts.dataTypes = jQuery.trim( s.dataType || \"*\" ).toLowerCase().match( rnotwhite ) || [ \"\" ];\n\n\t\t// A cross-domain request is in order when we have a protocol:host:port mismatch\n\t\tif ( s.crossDomain == null ) {\n\t\t\tparts = rurl.exec( s.url.toLowerCase() );\n\t\t\ts.crossDomain = !!( parts &&\n\t\t\t\t( parts[ 1 ] !== ajaxLocParts[ 1 ] || parts[ 2 ] !== ajaxLocParts[ 2 ] ||\n\t\t\t\t\t( parts[ 3 ] || ( parts[ 1 ] === \"http:\" ? \"80\" : \"443\" ) ) !==\n\t\t\t\t\t\t( ajaxLocParts[ 3 ] || ( ajaxLocParts[ 1 ] === \"http:\" ? \"80\" : \"443\" ) ) )\n\t\t\t);\n\t\t}\n\n\t\t// Convert data if not already a string\n\t\tif ( s.data && s.processData && typeof s.data !== \"string\" ) {\n\t\t\ts.data = jQuery.param( s.data, s.traditional );\n\t\t}\n\n\t\t// Apply prefilters\n\t\tinspectPrefiltersOrTransports( prefilters, s, options, jqXHR );\n\n\t\t// If request was aborted inside a prefilter, stop there\n\t\tif ( state === 2 ) {\n\t\t\treturn jqXHR;\n\t\t}\n\n\t\t// We can fire global events as of now if asked to\n\t\t// Don't fire events if jQuery.event is undefined in an AMD-usage scenario (#15118)\n\t\tfireGlobals = jQuery.event && s.global;\n\n\t\t// Watch for a new set of requests\n\t\tif ( fireGlobals && jQuery.active++ === 0 ) {\n\t\t\tjQuery.event.trigger(\"ajaxStart\");\n\t\t}\n\n\t\t// Uppercase the type\n\t\ts.type = s.type.toUpperCase();\n\n\t\t// Determine if request has content\n\t\ts.hasContent = !rnoContent.test( s.type );\n\n\t\t// Save the URL in case we're toying with the If-Modified-Since\n\t\t// and/or If-None-Match header later on\n\t\tcacheURL = s.url;\n\n\t\t// More options handling for requests with no content\n\t\tif ( !s.hasContent ) {\n\n\t\t\t// If data is available, append data to url\n\t\t\tif ( s.data ) {\n\t\t\t\tcacheURL = ( s.url += ( rquery.test( cacheURL ) ? \"&\" : \"?\" ) + s.data );\n\t\t\t\t// #9682: remove data so that it's not used in an eventual retry\n\t\t\t\tdelete s.data;\n\t\t\t}\n\n\t\t\t// Add anti-cache in url if needed\n\t\t\tif ( s.cache === false ) {\n\t\t\t\ts.url = rts.test( cacheURL ) ?\n\n\t\t\t\t\t// If there is already a '_' parameter, set its value\n\t\t\t\t\tcacheURL.replace( rts, \"$1_=\" + nonce++ ) :\n\n\t\t\t\t\t// Otherwise add one to the end\n\t\t\t\t\tcacheURL + ( rquery.test( cacheURL ) ? \"&\" : \"?\" ) + \"_=\" + nonce++;\n\t\t\t}\n\t\t}\n\n\t\t// Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.\n\t\tif ( s.ifModified ) {\n\t\t\tif ( jQuery.lastModified[ cacheURL ] ) {\n\t\t\t\tjqXHR.setRequestHeader( \"If-Modified-Since\", jQuery.lastModified[ cacheURL ] );\n\t\t\t}\n\t\t\tif ( jQuery.etag[ cacheURL ] ) {\n\t\t\t\tjqXHR.setRequestHeader( \"If-None-Match\", jQuery.etag[ cacheURL ] );\n\t\t\t}\n\t\t}\n\n\t\t// Set the correct header, if data is being sent\n\t\tif ( s.data && s.hasContent && s.contentType !== false || options.contentType ) {\n\t\t\tjqXHR.setRequestHeader( \"Content-Type\", s.contentType );\n\t\t}\n\n\t\t// Set the Accepts header for the server, depending on the dataType\n\t\tjqXHR.setRequestHeader(\n\t\t\t\"Accept\",\n\t\t\ts.dataTypes[ 0 ] && s.accepts[ s.dataTypes[0] ] ?\n\t\t\t\ts.accepts[ s.dataTypes[0] ] + ( s.dataTypes[ 0 ] !== \"*\" ? \", \" + allTypes + \"; q=0.01\" : \"\" ) :\n\t\t\t\ts.accepts[ \"*\" ]\n\t\t);\n\n\t\t// Check for headers option\n\t\tfor ( i in s.headers ) {\n\t\t\tjqXHR.setRequestHeader( i, s.headers[ i ] );\n\t\t}\n\n\t\t// Allow custom headers/mimetypes and early abort\n\t\tif ( s.beforeSend && ( s.beforeSend.call( callbackContext, jqXHR, s ) === false || state === 2 ) ) {\n\t\t\t// Abort if not done already and return\n\t\t\treturn jqXHR.abort();\n\t\t}\n\n\t\t// aborting is no longer a cancellation\n\t\tstrAbort = \"abort\";\n\n\t\t// Install callbacks on deferreds\n\t\tfor ( i in { success: 1, error: 1, complete: 1 } ) {\n\t\t\tjqXHR[ i ]( s[ i ] );\n\t\t}\n\n\t\t// Get transport\n\t\ttransport = inspectPrefiltersOrTransports( transports, s, options, jqXHR );\n\n\t\t// If no transport, we auto-abort\n\t\tif ( !transport ) {\n\t\t\tdone( -1, \"No Transport\" );\n\t\t} else {\n\t\t\tjqXHR.readyState = 1;\n\n\t\t\t// Send global event\n\t\t\tif ( fireGlobals ) {\n\t\t\t\tglobalEventContext.trigger( \"ajaxSend\", [ jqXHR, s ] );\n\t\t\t}\n\t\t\t// Timeout\n\t\t\tif ( s.async && s.timeout > 0 ) {\n\t\t\t\ttimeoutTimer = setTimeout(function() {\n\t\t\t\t\tjqXHR.abort(\"timeout\");\n\t\t\t\t}, s.timeout );\n\t\t\t}\n\n\t\t\ttry {\n\t\t\t\tstate = 1;\n\t\t\t\ttransport.send( requestHeaders, done );\n\t\t\t} catch ( e ) {\n\t\t\t\t// Propagate exception as error if not done\n\t\t\t\tif ( state < 2 ) {\n\t\t\t\t\tdone( -1, e );\n\t\t\t\t// Simply rethrow otherwise\n\t\t\t\t} else {\n\t\t\t\t\tthrow e;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Callback for when everything is done\n\t\tfunction done( status, nativeStatusText, responses, headers ) {\n\t\t\tvar isSuccess, success, error, response, modified,\n\t\t\t\tstatusText = nativeStatusText;\n\n\t\t\t// Called once\n\t\t\tif ( state === 2 ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// State is \"done\" now\n\t\t\tstate = 2;\n\n\t\t\t// Clear timeout if it exists\n\t\t\tif ( timeoutTimer ) {\n\t\t\t\tclearTimeout( timeoutTimer );\n\t\t\t}\n\n\t\t\t// Dereference transport for early garbage collection\n\t\t\t// (no matter how long the jqXHR object will be used)\n\t\t\ttransport = undefined;\n\n\t\t\t// Cache response headers\n\t\t\tresponseHeadersString = headers || \"\";\n\n\t\t\t// Set readyState\n\t\t\tjqXHR.readyState = status > 0 ? 4 : 0;\n\n\t\t\t// Determine if successful\n\t\t\tisSuccess = status >= 200 && status < 300 || status === 304;\n\n\t\t\t// Get response data\n\t\t\tif ( responses ) {\n\t\t\t\tresponse = ajaxHandleResponses( s, jqXHR, responses );\n\t\t\t}\n\n\t\t\t// Convert no matter what (that way responseXXX fields are always set)\n\t\t\tresponse = ajaxConvert( s, response, jqXHR, isSuccess );\n\n\t\t\t// If successful, handle type chaining\n\t\t\tif ( isSuccess ) {\n\n\t\t\t\t// Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.\n\t\t\t\tif ( s.ifModified ) {\n\t\t\t\t\tmodified = jqXHR.getResponseHeader(\"Last-Modified\");\n\t\t\t\t\tif ( modified ) {\n\t\t\t\t\t\tjQuery.lastModified[ cacheURL ] = modified;\n\t\t\t\t\t}\n\t\t\t\t\tmodified = jqXHR.getResponseHeader(\"etag\");\n\t\t\t\t\tif ( modified ) {\n\t\t\t\t\t\tjQuery.etag[ cacheURL ] = modified;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// if no content\n\t\t\t\tif ( status === 204 || s.type === \"HEAD\" ) {\n\t\t\t\t\tstatusText = \"nocontent\";\n\n\t\t\t\t// if not modified\n\t\t\t\t} else if ( status === 304 ) {\n\t\t\t\t\tstatusText = \"notmodified\";\n\n\t\t\t\t// If we have data, let's convert it\n\t\t\t\t} else {\n\t\t\t\t\tstatusText = response.state;\n\t\t\t\t\tsuccess = response.data;\n\t\t\t\t\terror = response.error;\n\t\t\t\t\tisSuccess = !error;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t// We extract error from statusText\n\t\t\t\t// then normalize statusText and status for non-aborts\n\t\t\t\terror = statusText;\n\t\t\t\tif ( status || !statusText ) {\n\t\t\t\t\tstatusText = \"error\";\n\t\t\t\t\tif ( status < 0 ) {\n\t\t\t\t\t\tstatus = 0;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Set data for the fake xhr object\n\t\t\tjqXHR.status = status;\n\t\t\tjqXHR.statusText = ( nativeStatusText || statusText ) + \"\";\n\n\t\t\t// Success/Error\n\t\t\tif ( isSuccess ) {\n\t\t\t\tdeferred.resolveWith( callbackContext, [ success, statusText, jqXHR ] );\n\t\t\t} else {\n\t\t\t\tdeferred.rejectWith( callbackContext, [ jqXHR, statusText, error ] );\n\t\t\t}\n\n\t\t\t// Status-dependent callbacks\n\t\t\tjqXHR.statusCode( statusCode );\n\t\t\tstatusCode = undefined;\n\n\t\t\tif ( fireGlobals ) {\n\t\t\t\tglobalEventContext.trigger( isSuccess ? \"ajaxSuccess\" : \"ajaxError\",\n\t\t\t\t\t[ jqXHR, s, isSuccess ? success : error ] );\n\t\t\t}\n\n\t\t\t// Complete\n\t\t\tcompleteDeferred.fireWith( callbackContext, [ jqXHR, statusText ] );\n\n\t\t\tif ( fireGlobals ) {\n\t\t\t\tglobalEventContext.trigger( \"ajaxComplete\", [ jqXHR, s ] );\n\t\t\t\t// Handle the global AJAX counter\n\t\t\t\tif ( !( --jQuery.active ) ) {\n\t\t\t\t\tjQuery.event.trigger(\"ajaxStop\");\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn jqXHR;\n\t},\n\n\tgetJSON: function( url, data, callback ) {\n\t\treturn jQuery.get( url, data, callback, \"json\" );\n\t},\n\n\tgetScript: function( url, callback ) {\n\t\treturn jQuery.get( url, undefined, callback, \"script\" );\n\t}\n});\n\njQuery.each( [ \"get\", \"post\" ], function( i, method ) {\n\tjQuery[ method ] = function( url, data, callback, type ) {\n\t\t// shift arguments if data argument was omitted\n\t\tif ( jQuery.isFunction( data ) ) {\n\t\t\ttype = type || callback;\n\t\t\tcallback = data;\n\t\t\tdata = undefined;\n\t\t}\n\n\t\treturn jQuery.ajax({\n\t\t\turl: url,\n\t\t\ttype: method,\n\t\t\tdataType: type,\n\t\t\tdata: data,\n\t\t\tsuccess: callback\n\t\t});\n\t};\n});\n\n\njQuery._evalUrl = function( url ) {\n\treturn jQuery.ajax({\n\t\turl: url,\n\t\ttype: \"GET\",\n\t\tdataType: \"script\",\n\t\tasync: false,\n\t\tglobal: false,\n\t\t\"throws\": true\n\t});\n};\n\n\njQuery.fn.extend({\n\twrapAll: function( html ) {\n\t\tif ( jQuery.isFunction( html ) ) {\n\t\t\treturn this.each(function(i) {\n\t\t\t\tjQuery(this).wrapAll( html.call(this, i) );\n\t\t\t});\n\t\t}\n\n\t\tif ( this[0] ) {\n\t\t\t// The elements to wrap the target around\n\t\t\tvar wrap = jQuery( html, this[0].ownerDocument ).eq(0).clone(true);\n\n\t\t\tif ( this[0].parentNode ) {\n\t\t\t\twrap.insertBefore( this[0] );\n\t\t\t}\n\n\t\t\twrap.map(function() {\n\t\t\t\tvar elem = this;\n\n\t\t\t\twhile ( elem.firstChild && elem.firstChild.nodeType === 1 ) {\n\t\t\t\t\telem = elem.firstChild;\n\t\t\t\t}\n\n\t\t\t\treturn elem;\n\t\t\t}).append( this );\n\t\t}\n\n\t\treturn this;\n\t},\n\n\twrapInner: function( html ) {\n\t\tif ( jQuery.isFunction( html ) ) {\n\t\t\treturn this.each(function(i) {\n\t\t\t\tjQuery(this).wrapInner( html.call(this, i) );\n\t\t\t});\n\t\t}\n\n\t\treturn this.each(function() {\n\t\t\tvar self = jQuery( this ),\n\t\t\t\tcontents = self.contents();\n\n\t\t\tif ( contents.length ) {\n\t\t\t\tcontents.wrapAll( html );\n\n\t\t\t} else {\n\t\t\t\tself.append( html );\n\t\t\t}\n\t\t});\n\t},\n\n\twrap: function( html ) {\n\t\tvar isFunction = jQuery.isFunction( html );\n\n\t\treturn this.each(function(i) {\n\t\t\tjQuery( this ).wrapAll( isFunction ? html.call(this, i) : html );\n\t\t});\n\t},\n\n\tunwrap: function() {\n\t\treturn this.parent().each(function() {\n\t\t\tif ( !jQuery.nodeName( this, \"body\" ) ) {\n\t\t\t\tjQuery( this ).replaceWith( this.childNodes );\n\t\t\t}\n\t\t}).end();\n\t}\n});\n\n\njQuery.expr.filters.hidden = function( elem ) {\n\t// Support: Opera <= 12.12\n\t// Opera reports offsetWidths and offsetHeights less than zero on some elements\n\treturn elem.offsetWidth <= 0 && elem.offsetHeight <= 0 ||\n\t\t(!support.reliableHiddenOffsets() &&\n\t\t\t((elem.style && elem.style.display) || jQuery.css( elem, \"display\" )) === \"none\");\n};\n\njQuery.expr.filters.visible = function( elem ) {\n\treturn !jQuery.expr.filters.hidden( elem );\n};\n\n\n\n\nvar r20 = /%20/g,\n\trbracket = /\\[\\]$/,\n\trCRLF = /\\r?\\n/g,\n\trsubmitterTypes = /^(?:submit|button|image|reset|file)$/i,\n\trsubmittable = /^(?:input|select|textarea|keygen)/i;\n\nfunction buildParams( prefix, obj, traditional, add ) {\n\tvar name;\n\n\tif ( jQuery.isArray( obj ) ) {\n\t\t// Serialize array item.\n\t\tjQuery.each( obj, function( i, v ) {\n\t\t\tif ( traditional || rbracket.test( prefix ) ) {\n\t\t\t\t// Treat each array item as a scalar.\n\t\t\t\tadd( prefix, v );\n\n\t\t\t} else {\n\t\t\t\t// Item is non-scalar (array or object), encode its numeric index.\n\t\t\t\tbuildParams( prefix + \"[\" + ( typeof v === \"object\" ? i : \"\" ) + \"]\", v, traditional, add );\n\t\t\t}\n\t\t});\n\n\t} else if ( !traditional && jQuery.type( obj ) === \"object\" ) {\n\t\t// Serialize object item.\n\t\tfor ( name in obj ) {\n\t\t\tbuildParams( prefix + \"[\" + name + \"]\", obj[ name ], traditional, add );\n\t\t}\n\n\t} else {\n\t\t// Serialize scalar item.\n\t\tadd( prefix, obj );\n\t}\n}\n\n// Serialize an array of form elements or a set of\n// key/values into a query string\njQuery.param = function( a, traditional ) {\n\tvar prefix,\n\t\ts = [],\n\t\tadd = function( key, value ) {\n\t\t\t// If value is a function, invoke it and return its value\n\t\t\tvalue = jQuery.isFunction( value ) ? value() : ( value == null ? \"\" : value );\n\t\t\ts[ s.length ] = encodeURIComponent( key ) + \"=\" + encodeURIComponent( value );\n\t\t};\n\n\t// Set traditional to true for jQuery <= 1.3.2 behavior.\n\tif ( traditional === undefined ) {\n\t\ttraditional = jQuery.ajaxSettings && jQuery.ajaxSettings.traditional;\n\t}\n\n\t// If an array was passed in, assume that it is an array of form elements.\n\tif ( jQuery.isArray( a ) || ( a.jquery && !jQuery.isPlainObject( a ) ) ) {\n\t\t// Serialize the form elements\n\t\tjQuery.each( a, function() {\n\t\t\tadd( this.name, this.value );\n\t\t});\n\n\t} else {\n\t\t// If traditional, encode the \"old\" way (the way 1.3.2 or older\n\t\t// did it), otherwise encode params recursively.\n\t\tfor ( prefix in a ) {\n\t\t\tbuildParams( prefix, a[ prefix ], traditional, add );\n\t\t}\n\t}\n\n\t// Return the resulting serialization\n\treturn s.join( \"&\" ).replace( r20, \"+\" );\n};\n\njQuery.fn.extend({\n\tserialize: function() {\n\t\treturn jQuery.param( this.serializeArray() );\n\t},\n\tserializeArray: function() {\n\t\treturn this.map(function() {\n\t\t\t// Can add propHook for \"elements\" to filter or add form elements\n\t\t\tvar elements = jQuery.prop( this, \"elements\" );\n\t\t\treturn elements ? jQuery.makeArray( elements ) : this;\n\t\t})\n\t\t.filter(function() {\n\t\t\tvar type = this.type;\n\t\t\t// Use .is(\":disabled\") so that fieldset[disabled] works\n\t\t\treturn this.name && !jQuery( this ).is( \":disabled\" ) &&\n\t\t\t\trsubmittable.test( this.nodeName ) && !rsubmitterTypes.test( type ) &&\n\t\t\t\t( this.checked || !rcheckableType.test( type ) );\n\t\t})\n\t\t.map(function( i, elem ) {\n\t\t\tvar val = jQuery( this ).val();\n\n\t\t\treturn val == null ?\n\t\t\t\tnull :\n\t\t\t\tjQuery.isArray( val ) ?\n\t\t\t\t\tjQuery.map( val, function( val ) {\n\t\t\t\t\t\treturn { name: elem.name, value: val.replace( rCRLF, \"\\r\\n\" ) };\n\t\t\t\t\t}) :\n\t\t\t\t\t{ name: elem.name, value: val.replace( rCRLF, \"\\r\\n\" ) };\n\t\t}).get();\n\t}\n});\n\n\n// Create the request object\n// (This is still attached to ajaxSettings for backward compatibility)\njQuery.ajaxSettings.xhr = window.ActiveXObject !== undefined ?\n\t// Support: IE6+\n\tfunction() {\n\n\t\t// XHR cannot access local files, always use ActiveX for that case\n\t\treturn !this.isLocal &&\n\n\t\t\t// Support: IE7-8\n\t\t\t// oldIE XHR does not support non-RFC2616 methods (#13240)\n\t\t\t// See http://msdn.microsoft.com/en-us/library/ie/ms536648(v=vs.85).aspx\n\t\t\t// and http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html#sec9\n\t\t\t// Although this check for six methods instead of eight\n\t\t\t// since IE also does not support \"trace\" and \"connect\"\n\t\t\t/^(get|post|head|put|delete|options)$/i.test( this.type ) &&\n\n\t\t\tcreateStandardXHR() || createActiveXHR();\n\t} :\n\t// For all other browsers, use the standard XMLHttpRequest object\n\tcreateStandardXHR;\n\nvar xhrId = 0,\n\txhrCallbacks = {},\n\txhrSupported = jQuery.ajaxSettings.xhr();\n\n// Support: IE<10\n// Open requests must be manually aborted on unload (#5280)\n// See https://support.microsoft.com/kb/2856746 for more info\nif ( window.attachEvent ) {\n\twindow.attachEvent( \"onunload\", function() {\n\t\tfor ( var key in xhrCallbacks ) {\n\t\t\txhrCallbacks[ key ]( undefined, true );\n\t\t}\n\t});\n}\n\n// Determine support properties\nsupport.cors = !!xhrSupported && ( \"withCredentials\" in xhrSupported );\nxhrSupported = support.ajax = !!xhrSupported;\n\n// Create transport if the browser can provide an xhr\nif ( xhrSupported ) {\n\n\tjQuery.ajaxTransport(function( options ) {\n\t\t// Cross domain only allowed if supported through XMLHttpRequest\n\t\tif ( !options.crossDomain || support.cors ) {\n\n\t\t\tvar callback;\n\n\t\t\treturn {\n\t\t\t\tsend: function( headers, complete ) {\n\t\t\t\t\tvar i,\n\t\t\t\t\t\txhr = options.xhr(),\n\t\t\t\t\t\tid = ++xhrId;\n\n\t\t\t\t\t// Open the socket\n\t\t\t\t\txhr.open( options.type, options.url, options.async, options.username, options.password );\n\n\t\t\t\t\t// Apply custom fields if provided\n\t\t\t\t\tif ( options.xhrFields ) {\n\t\t\t\t\t\tfor ( i in options.xhrFields ) {\n\t\t\t\t\t\t\txhr[ i ] = options.xhrFields[ i ];\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\t// Override mime type if needed\n\t\t\t\t\tif ( options.mimeType && xhr.overrideMimeType ) {\n\t\t\t\t\t\txhr.overrideMimeType( options.mimeType );\n\t\t\t\t\t}\n\n\t\t\t\t\t// X-Requested-With header\n\t\t\t\t\t// For cross-domain requests, seeing as conditions for a preflight are\n\t\t\t\t\t// akin to a jigsaw puzzle, we simply never set it to be sure.\n\t\t\t\t\t// (it can always be set on a per-request basis or even using ajaxSetup)\n\t\t\t\t\t// For same-domain requests, won't change header if already provided.\n\t\t\t\t\tif ( !options.crossDomain && !headers[\"X-Requested-With\"] ) {\n\t\t\t\t\t\theaders[\"X-Requested-With\"] = \"XMLHttpRequest\";\n\t\t\t\t\t}\n\n\t\t\t\t\t// Set headers\n\t\t\t\t\tfor ( i in headers ) {\n\t\t\t\t\t\t// Support: IE<9\n\t\t\t\t\t\t// IE's ActiveXObject throws a 'Type Mismatch' exception when setting\n\t\t\t\t\t\t// request header to a null-value.\n\t\t\t\t\t\t//\n\t\t\t\t\t\t// To keep consistent with other XHR implementations, cast the value\n\t\t\t\t\t\t// to string and ignore `undefined`.\n\t\t\t\t\t\tif ( headers[ i ] !== undefined ) {\n\t\t\t\t\t\t\txhr.setRequestHeader( i, headers[ i ] + \"\" );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\t// Do send the request\n\t\t\t\t\t// This may raise an exception which is actually\n\t\t\t\t\t// handled in jQuery.ajax (so no try/catch here)\n\t\t\t\t\txhr.send( ( options.hasContent && options.data ) || null );\n\n\t\t\t\t\t// Listener\n\t\t\t\t\tcallback = function( _, isAbort ) {\n\t\t\t\t\t\tvar status, statusText, responses;\n\n\t\t\t\t\t\t// Was never called and is aborted or complete\n\t\t\t\t\t\tif ( callback && ( isAbort || xhr.readyState === 4 ) ) {\n\t\t\t\t\t\t\t// Clean up\n\t\t\t\t\t\t\tdelete xhrCallbacks[ id ];\n\t\t\t\t\t\t\tcallback = undefined;\n\t\t\t\t\t\t\txhr.onreadystatechange = jQuery.noop;\n\n\t\t\t\t\t\t\t// Abort manually if needed\n\t\t\t\t\t\t\tif ( isAbort ) {\n\t\t\t\t\t\t\t\tif ( xhr.readyState !== 4 ) {\n\t\t\t\t\t\t\t\t\txhr.abort();\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tresponses = {};\n\t\t\t\t\t\t\t\tstatus = xhr.status;\n\n\t\t\t\t\t\t\t\t// Support: IE<10\n\t\t\t\t\t\t\t\t// Accessing binary-data responseText throws an exception\n\t\t\t\t\t\t\t\t// (#11426)\n\t\t\t\t\t\t\t\tif ( typeof xhr.responseText === \"string\" ) {\n\t\t\t\t\t\t\t\t\tresponses.text = xhr.responseText;\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t// Firefox throws an exception when accessing\n\t\t\t\t\t\t\t\t// statusText for faulty cross-domain requests\n\t\t\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t\t\tstatusText = xhr.statusText;\n\t\t\t\t\t\t\t\t} catch( e ) {\n\t\t\t\t\t\t\t\t\t// We normalize with Webkit giving an empty statusText\n\t\t\t\t\t\t\t\t\tstatusText = \"\";\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t// Filter status for non standard behaviors\n\n\t\t\t\t\t\t\t\t// If the request is local and we have data: assume a success\n\t\t\t\t\t\t\t\t// (success with no data won't get notified, that's the best we\n\t\t\t\t\t\t\t\t// can do given current implementations)\n\t\t\t\t\t\t\t\tif ( !status && options.isLocal && !options.crossDomain ) {\n\t\t\t\t\t\t\t\t\tstatus = responses.text ? 200 : 404;\n\t\t\t\t\t\t\t\t// IE - #1450: sometimes returns 1223 when it should be 204\n\t\t\t\t\t\t\t\t} else if ( status === 1223 ) {\n\t\t\t\t\t\t\t\t\tstatus = 204;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// Call complete if needed\n\t\t\t\t\t\tif ( responses ) {\n\t\t\t\t\t\t\tcomplete( status, statusText, responses, xhr.getAllResponseHeaders() );\n\t\t\t\t\t\t}\n\t\t\t\t\t};\n\n\t\t\t\t\tif ( !options.async ) {\n\t\t\t\t\t\t// if we're in sync mode we fire the callback\n\t\t\t\t\t\tcallback();\n\t\t\t\t\t} else if ( xhr.readyState === 4 ) {\n\t\t\t\t\t\t// (IE6 & IE7) if it's in cache and has been\n\t\t\t\t\t\t// retrieved directly we need to fire the callback\n\t\t\t\t\t\tsetTimeout( callback );\n\t\t\t\t\t} else {\n\t\t\t\t\t\t// Add to the list of active xhr callbacks\n\t\t\t\t\t\txhr.onreadystatechange = xhrCallbacks[ id ] = callback;\n\t\t\t\t\t}\n\t\t\t\t},\n\n\t\t\t\tabort: function() {\n\t\t\t\t\tif ( callback ) {\n\t\t\t\t\t\tcallback( undefined, true );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t};\n\t\t}\n\t});\n}\n\n// Functions to create xhrs\nfunction createStandardXHR() {\n\ttry {\n\t\treturn new window.XMLHttpRequest();\n\t} catch( e ) {}\n}\n\nfunction createActiveXHR() {\n\ttry {\n\t\treturn new window.ActiveXObject( \"Microsoft.XMLHTTP\" );\n\t} catch( e ) {}\n}\n\n\n\n\n// Install script dataType\njQuery.ajaxSetup({\n\taccepts: {\n\t\tscript: \"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript\"\n\t},\n\tcontents: {\n\t\tscript: /(?:java|ecma)script/\n\t},\n\tconverters: {\n\t\t\"text script\": function( text ) {\n\t\t\tjQuery.globalEval( text );\n\t\t\treturn text;\n\t\t}\n\t}\n});\n\n// Handle cache's special case and global\njQuery.ajaxPrefilter( \"script\", function( s ) {\n\tif ( s.cache === undefined ) {\n\t\ts.cache = false;\n\t}\n\tif ( s.crossDomain ) {\n\t\ts.type = \"GET\";\n\t\ts.global = false;\n\t}\n});\n\n// Bind script tag hack transport\njQuery.ajaxTransport( \"script\", function(s) {\n\n\t// This transport only deals with cross domain requests\n\tif ( s.crossDomain ) {\n\n\t\tvar script,\n\t\t\thead = document.head || jQuery(\"head\")[0] || document.documentElement;\n\n\t\treturn {\n\n\t\t\tsend: function( _, callback ) {\n\n\t\t\t\tscript = document.createElement(\"script\");\n\n\t\t\t\tscript.async = true;\n\n\t\t\t\tif ( s.scriptCharset ) {\n\t\t\t\t\tscript.charset = s.scriptCharset;\n\t\t\t\t}\n\n\t\t\t\tscript.src = s.url;\n\n\t\t\t\t// Attach handlers for all browsers\n\t\t\t\tscript.onload = script.onreadystatechange = function( _, isAbort ) {\n\n\t\t\t\t\tif ( isAbort || !script.readyState || /loaded|complete/.test( script.readyState ) ) {\n\n\t\t\t\t\t\t// Handle memory leak in IE\n\t\t\t\t\t\tscript.onload = script.onreadystatechange = null;\n\n\t\t\t\t\t\t// Remove the script\n\t\t\t\t\t\tif ( script.parentNode ) {\n\t\t\t\t\t\t\tscript.parentNode.removeChild( script );\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// Dereference the script\n\t\t\t\t\t\tscript = null;\n\n\t\t\t\t\t\t// Callback if not abort\n\t\t\t\t\t\tif ( !isAbort ) {\n\t\t\t\t\t\t\tcallback( 200, \"success\" );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t};\n\n\t\t\t\t// Circumvent IE6 bugs with base elements (#2709 and #4378) by prepending\n\t\t\t\t// Use native DOM manipulation to avoid our domManip AJAX trickery\n\t\t\t\thead.insertBefore( script, head.firstChild );\n\t\t\t},\n\n\t\t\tabort: function() {\n\t\t\t\tif ( script ) {\n\t\t\t\t\tscript.onload( undefined, true );\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\t}\n});\n\n\n\n\nvar oldCallbacks = [],\n\trjsonp = /(=)\\?(?=&|$)|\\?\\?/;\n\n// Default jsonp settings\njQuery.ajaxSetup({\n\tjsonp: \"callback\",\n\tjsonpCallback: function() {\n\t\tvar callback = oldCallbacks.pop() || ( jQuery.expando + \"_\" + ( nonce++ ) );\n\t\tthis[ callback ] = true;\n\t\treturn callback;\n\t}\n});\n\n// Detect, normalize options and install callbacks for jsonp requests\njQuery.ajaxPrefilter( \"json jsonp\", function( s, originalSettings, jqXHR ) {\n\n\tvar callbackName, overwritten, responseContainer,\n\t\tjsonProp = s.jsonp !== false && ( rjsonp.test( s.url ) ?\n\t\t\t\"url\" :\n\t\t\ttypeof s.data === \"string\" && !( s.contentType || \"\" ).indexOf(\"application/x-www-form-urlencoded\") && rjsonp.test( s.data ) && \"data\"\n\t\t);\n\n\t// Handle iff the expected data type is \"jsonp\" or we have a parameter to set\n\tif ( jsonProp || s.dataTypes[ 0 ] === \"jsonp\" ) {\n\n\t\t// Get callback name, remembering preexisting value associated with it\n\t\tcallbackName = s.jsonpCallback = jQuery.isFunction( s.jsonpCallback ) ?\n\t\t\ts.jsonpCallback() :\n\t\t\ts.jsonpCallback;\n\n\t\t// Insert callback into url or form data\n\t\tif ( jsonProp ) {\n\t\t\ts[ jsonProp ] = s[ jsonProp ].replace( rjsonp, \"$1\" + callbackName );\n\t\t} else if ( s.jsonp !== false ) {\n\t\t\ts.url += ( rquery.test( s.url ) ? \"&\" : \"?\" ) + s.jsonp + \"=\" + callbackName;\n\t\t}\n\n\t\t// Use data converter to retrieve json after script execution\n\t\ts.converters[\"script json\"] = function() {\n\t\t\tif ( !responseContainer ) {\n\t\t\t\tjQuery.error( callbackName + \" was not called\" );\n\t\t\t}\n\t\t\treturn responseContainer[ 0 ];\n\t\t};\n\n\t\t// force json dataType\n\t\ts.dataTypes[ 0 ] = \"json\";\n\n\t\t// Install callback\n\t\toverwritten = window[ callbackName ];\n\t\twindow[ callbackName ] = function() {\n\t\t\tresponseContainer = arguments;\n\t\t};\n\n\t\t// Clean-up function (fires after converters)\n\t\tjqXHR.always(function() {\n\t\t\t// Restore preexisting value\n\t\t\twindow[ callbackName ] = overwritten;\n\n\t\t\t// Save back as free\n\t\t\tif ( s[ callbackName ] ) {\n\t\t\t\t// make sure that re-using the options doesn't screw things around\n\t\t\t\ts.jsonpCallback = originalSettings.jsonpCallback;\n\n\t\t\t\t// save the callback name for future use\n\t\t\t\toldCallbacks.push( callbackName );\n\t\t\t}\n\n\t\t\t// Call if it was a function and we have a response\n\t\t\tif ( responseContainer && jQuery.isFunction( overwritten ) ) {\n\t\t\t\toverwritten( responseContainer[ 0 ] );\n\t\t\t}\n\n\t\t\tresponseContainer = overwritten = undefined;\n\t\t});\n\n\t\t// Delegate to script\n\t\treturn \"script\";\n\t}\n});\n\n\n\n\n// data: string of html\n// context (optional): If specified, the fragment will be created in this context, defaults to document\n// keepScripts (optional): If true, will include scripts passed in the html string\njQuery.parseHTML = function( data, context, keepScripts ) {\n\tif ( !data || typeof data !== \"string\" ) {\n\t\treturn null;\n\t}\n\tif ( typeof context === \"boolean\" ) {\n\t\tkeepScripts = context;\n\t\tcontext = false;\n\t}\n\tcontext = context || document;\n\n\tvar parsed = rsingleTag.exec( data ),\n\t\tscripts = !keepScripts && [];\n\n\t// Single tag\n\tif ( parsed ) {\n\t\treturn [ context.createElement( parsed[1] ) ];\n\t}\n\n\tparsed = jQuery.buildFragment( [ data ], context, scripts );\n\n\tif ( scripts && scripts.length ) {\n\t\tjQuery( scripts ).remove();\n\t}\n\n\treturn jQuery.merge( [], parsed.childNodes );\n};\n\n\n// Keep a copy of the old load method\nvar _load = jQuery.fn.load;\n\n/**\n * Load a url into a page\n */\njQuery.fn.load = function( url, params, callback ) {\n\tif ( typeof url !== \"string\" && _load ) {\n\t\treturn _load.apply( this, arguments );\n\t}\n\n\tvar selector, response, type,\n\t\tself = this,\n\t\toff = url.indexOf(\" \");\n\n\tif ( off >= 0 ) {\n\t\tselector = jQuery.trim( url.slice( off, url.length ) );\n\t\turl = url.slice( 0, off );\n\t}\n\n\t// If it's a function\n\tif ( jQuery.isFunction( params ) ) {\n\n\t\t// We assume that it's the callback\n\t\tcallback = params;\n\t\tparams = undefined;\n\n\t// Otherwise, build a param string\n\t} else if ( params && typeof params === \"object\" ) {\n\t\ttype = \"POST\";\n\t}\n\n\t// If we have elements to modify, make the request\n\tif ( self.length > 0 ) {\n\t\tjQuery.ajax({\n\t\t\turl: url,\n\n\t\t\t// if \"type\" variable is undefined, then \"GET\" method will be used\n\t\t\ttype: type,\n\t\t\tdataType: \"html\",\n\t\t\tdata: params\n\t\t}).done(function( responseText ) {\n\n\t\t\t// Save response for use in complete callback\n\t\t\tresponse = arguments;\n\n\t\t\tself.html( selector ?\n\n\t\t\t\t// If a selector was specified, locate the right elements in a dummy div\n\t\t\t\t// Exclude scripts to avoid IE 'Permission Denied' errors\n\t\t\t\tjQuery(\"<div>\").append( jQuery.parseHTML( responseText ) ).find( selector ) :\n\n\t\t\t\t// Otherwise use the full result\n\t\t\t\tresponseText );\n\n\t\t}).complete( callback && function( jqXHR, status ) {\n\t\t\tself.each( callback, response || [ jqXHR.responseText, status, jqXHR ] );\n\t\t});\n\t}\n\n\treturn this;\n};\n\n\n\n\n// Attach a bunch of functions for handling common AJAX events\njQuery.each( [ \"ajaxStart\", \"ajaxStop\", \"ajaxComplete\", \"ajaxError\", \"ajaxSuccess\", \"ajaxSend\" ], function( i, type ) {\n\tjQuery.fn[ type ] = function( fn ) {\n\t\treturn this.on( type, fn );\n\t};\n});\n\n\n\n\njQuery.expr.filters.animated = function( elem ) {\n\treturn jQuery.grep(jQuery.timers, function( fn ) {\n\t\treturn elem === fn.elem;\n\t}).length;\n};\n\n\n\n\n\nvar docElem = window.document.documentElement;\n\n/**\n * Gets a window from an element\n */\nfunction getWindow( elem ) {\n\treturn jQuery.isWindow( elem ) ?\n\t\telem :\n\t\telem.nodeType === 9 ?\n\t\t\telem.defaultView || elem.parentWindow :\n\t\t\tfalse;\n}\n\njQuery.offset = {\n\tsetOffset: function( elem, options, i ) {\n\t\tvar curPosition, curLeft, curCSSTop, curTop, curOffset, curCSSLeft, calculatePosition,\n\t\t\tposition = jQuery.css( elem, \"position\" ),\n\t\t\tcurElem = jQuery( elem ),\n\t\t\tprops = {};\n\n\t\t// set position first, in-case top/left are set even on static elem\n\t\tif ( position === \"static\" ) {\n\t\t\telem.style.position = \"relative\";\n\t\t}\n\n\t\tcurOffset = curElem.offset();\n\t\tcurCSSTop = jQuery.css( elem, \"top\" );\n\t\tcurCSSLeft = jQuery.css( elem, \"left\" );\n\t\tcalculatePosition = ( position === \"absolute\" || position === \"fixed\" ) &&\n\t\t\tjQuery.inArray(\"auto\", [ curCSSTop, curCSSLeft ] ) > -1;\n\n\t\t// need to be able to calculate position if either top or left is auto and position is either absolute or fixed\n\t\tif ( calculatePosition ) {\n\t\t\tcurPosition = curElem.position();\n\t\t\tcurTop = curPosition.top;\n\t\t\tcurLeft = curPosition.left;\n\t\t} else {\n\t\t\tcurTop = parseFloat( curCSSTop ) || 0;\n\t\t\tcurLeft = parseFloat( curCSSLeft ) || 0;\n\t\t}\n\n\t\tif ( jQuery.isFunction( options ) ) {\n\t\t\toptions = options.call( elem, i, curOffset );\n\t\t}\n\n\t\tif ( options.top != null ) {\n\t\t\tprops.top = ( options.top - curOffset.top ) + curTop;\n\t\t}\n\t\tif ( options.left != null ) {\n\t\t\tprops.left = ( options.left - curOffset.left ) + curLeft;\n\t\t}\n\n\t\tif ( \"using\" in options ) {\n\t\t\toptions.using.call( elem, props );\n\t\t} else {\n\t\t\tcurElem.css( props );\n\t\t}\n\t}\n};\n\njQuery.fn.extend({\n\toffset: function( options ) {\n\t\tif ( arguments.length ) {\n\t\t\treturn options === undefined ?\n\t\t\t\tthis :\n\t\t\t\tthis.each(function( i ) {\n\t\t\t\t\tjQuery.offset.setOffset( this, options, i );\n\t\t\t\t});\n\t\t}\n\n\t\tvar docElem, win,\n\t\t\tbox = { top: 0, left: 0 },\n\t\t\telem = this[ 0 ],\n\t\t\tdoc = elem && elem.ownerDocument;\n\n\t\tif ( !doc ) {\n\t\t\treturn;\n\t\t}\n\n\t\tdocElem = doc.documentElement;\n\n\t\t// Make sure it's not a disconnected DOM node\n\t\tif ( !jQuery.contains( docElem, elem ) ) {\n\t\t\treturn box;\n\t\t}\n\n\t\t// If we don't have gBCR, just use 0,0 rather than error\n\t\t// BlackBerry 5, iOS 3 (original iPhone)\n\t\tif ( typeof elem.getBoundingClientRect !== strundefined ) {\n\t\t\tbox = elem.getBoundingClientRect();\n\t\t}\n\t\twin = getWindow( doc );\n\t\treturn {\n\t\t\ttop: box.top  + ( win.pageYOffset || docElem.scrollTop )  - ( docElem.clientTop  || 0 ),\n\t\t\tleft: box.left + ( win.pageXOffset || docElem.scrollLeft ) - ( docElem.clientLeft || 0 )\n\t\t};\n\t},\n\n\tposition: function() {\n\t\tif ( !this[ 0 ] ) {\n\t\t\treturn;\n\t\t}\n\n\t\tvar offsetParent, offset,\n\t\t\tparentOffset = { top: 0, left: 0 },\n\t\t\telem = this[ 0 ];\n\n\t\t// fixed elements are offset from window (parentOffset = {top:0, left: 0}, because it is its only offset parent\n\t\tif ( jQuery.css( elem, \"position\" ) === \"fixed\" ) {\n\t\t\t// we assume that getBoundingClientRect is available when computed position is fixed\n\t\t\toffset = elem.getBoundingClientRect();\n\t\t} else {\n\t\t\t// Get *real* offsetParent\n\t\t\toffsetParent = this.offsetParent();\n\n\t\t\t// Get correct offsets\n\t\t\toffset = this.offset();\n\t\t\tif ( !jQuery.nodeName( offsetParent[ 0 ], \"html\" ) ) {\n\t\t\t\tparentOffset = offsetParent.offset();\n\t\t\t}\n\n\t\t\t// Add offsetParent borders\n\t\t\tparentOffset.top  += jQuery.css( offsetParent[ 0 ], \"borderTopWidth\", true );\n\t\t\tparentOffset.left += jQuery.css( offsetParent[ 0 ], \"borderLeftWidth\", true );\n\t\t}\n\n\t\t// Subtract parent offsets and element margins\n\t\t// note: when an element has margin: auto the offsetLeft and marginLeft\n\t\t// are the same in Safari causing offset.left to incorrectly be 0\n\t\treturn {\n\t\t\ttop:  offset.top  - parentOffset.top - jQuery.css( elem, \"marginTop\", true ),\n\t\t\tleft: offset.left - parentOffset.left - jQuery.css( elem, \"marginLeft\", true)\n\t\t};\n\t},\n\n\toffsetParent: function() {\n\t\treturn this.map(function() {\n\t\t\tvar offsetParent = this.offsetParent || docElem;\n\n\t\t\twhile ( offsetParent && ( !jQuery.nodeName( offsetParent, \"html\" ) && jQuery.css( offsetParent, \"position\" ) === \"static\" ) ) {\n\t\t\t\toffsetParent = offsetParent.offsetParent;\n\t\t\t}\n\t\t\treturn offsetParent || docElem;\n\t\t});\n\t}\n});\n\n// Create scrollLeft and scrollTop methods\njQuery.each( { scrollLeft: \"pageXOffset\", scrollTop: \"pageYOffset\" }, function( method, prop ) {\n\tvar top = /Y/.test( prop );\n\n\tjQuery.fn[ method ] = function( val ) {\n\t\treturn access( this, function( elem, method, val ) {\n\t\t\tvar win = getWindow( elem );\n\n\t\t\tif ( val === undefined ) {\n\t\t\t\treturn win ? (prop in win) ? win[ prop ] :\n\t\t\t\t\twin.document.documentElement[ method ] :\n\t\t\t\t\telem[ method ];\n\t\t\t}\n\n\t\t\tif ( win ) {\n\t\t\t\twin.scrollTo(\n\t\t\t\t\t!top ? val : jQuery( win ).scrollLeft(),\n\t\t\t\t\ttop ? val : jQuery( win ).scrollTop()\n\t\t\t\t);\n\n\t\t\t} else {\n\t\t\t\telem[ method ] = val;\n\t\t\t}\n\t\t}, method, val, arguments.length, null );\n\t};\n});\n\n// Add the top/left cssHooks using jQuery.fn.position\n// Webkit bug: https://bugs.webkit.org/show_bug.cgi?id=29084\n// getComputedStyle returns percent when specified for top/left/bottom/right\n// rather than make the css module depend on the offset module, we just check for it here\njQuery.each( [ \"top\", \"left\" ], function( i, prop ) {\n\tjQuery.cssHooks[ prop ] = addGetHookIf( support.pixelPosition,\n\t\tfunction( elem, computed ) {\n\t\t\tif ( computed ) {\n\t\t\t\tcomputed = curCSS( elem, prop );\n\t\t\t\t// if curCSS returns percentage, fallback to offset\n\t\t\t\treturn rnumnonpx.test( computed ) ?\n\t\t\t\t\tjQuery( elem ).position()[ prop ] + \"px\" :\n\t\t\t\t\tcomputed;\n\t\t\t}\n\t\t}\n\t);\n});\n\n\n// Create innerHeight, innerWidth, height, width, outerHeight and outerWidth methods\njQuery.each( { Height: \"height\", Width: \"width\" }, function( name, type ) {\n\tjQuery.each( { padding: \"inner\" + name, content: type, \"\": \"outer\" + name }, function( defaultExtra, funcName ) {\n\t\t// margin is only for outerHeight, outerWidth\n\t\tjQuery.fn[ funcName ] = function( margin, value ) {\n\t\t\tvar chainable = arguments.length && ( defaultExtra || typeof margin !== \"boolean\" ),\n\t\t\t\textra = defaultExtra || ( margin === true || value === true ? \"margin\" : \"border\" );\n\n\t\t\treturn access( this, function( elem, type, value ) {\n\t\t\t\tvar doc;\n\n\t\t\t\tif ( jQuery.isWindow( elem ) ) {\n\t\t\t\t\t// As of 5/8/2012 this will yield incorrect results for Mobile Safari, but there\n\t\t\t\t\t// isn't a whole lot we can do. See pull request at this URL for discussion:\n\t\t\t\t\t// https://github.com/jquery/jquery/pull/764\n\t\t\t\t\treturn elem.document.documentElement[ \"client\" + name ];\n\t\t\t\t}\n\n\t\t\t\t// Get document width or height\n\t\t\t\tif ( elem.nodeType === 9 ) {\n\t\t\t\t\tdoc = elem.documentElement;\n\n\t\t\t\t\t// Either scroll[Width/Height] or offset[Width/Height] or client[Width/Height], whichever is greatest\n\t\t\t\t\t// unfortunately, this causes bug #3838 in IE6/8 only, but there is currently no good, small way to fix it.\n\t\t\t\t\treturn Math.max(\n\t\t\t\t\t\telem.body[ \"scroll\" + name ], doc[ \"scroll\" + name ],\n\t\t\t\t\t\telem.body[ \"offset\" + name ], doc[ \"offset\" + name ],\n\t\t\t\t\t\tdoc[ \"client\" + name ]\n\t\t\t\t\t);\n\t\t\t\t}\n\n\t\t\t\treturn value === undefined ?\n\t\t\t\t\t// Get width or height on the element, requesting but not forcing parseFloat\n\t\t\t\t\tjQuery.css( elem, type, extra ) :\n\n\t\t\t\t\t// Set width or height on the element\n\t\t\t\t\tjQuery.style( elem, type, value, extra );\n\t\t\t}, type, chainable ? margin : undefined, chainable, null );\n\t\t};\n\t});\n});\n\n\n// The number of elements contained in the matched element set\njQuery.fn.size = function() {\n\treturn this.length;\n};\n\njQuery.fn.andSelf = jQuery.fn.addBack;\n\n\n\n\n// Register as a named AMD module, since jQuery can be concatenated with other\n// files that may use define, but not via a proper concatenation script that\n// understands anonymous AMD modules. A named AMD is safest and most robust\n// way to register. Lowercase jquery is used because AMD module names are\n// derived from file names, and jQuery is normally delivered in a lowercase\n// file name. Do this after creating the global so that if an AMD module wants\n// to call noConflict to hide this version of jQuery, it will work.\n\n// Note that for maximum portability, libraries that are not jQuery should\n// declare themselves as anonymous modules, and avoid setting a global if an\n// AMD loader is present. jQuery is a special case. For more information, see\n// https://github.com/jrburke/requirejs/wiki/Updating-existing-libraries#wiki-anon\n\nif ( typeof define === \"function\" && define.amd ) {\n\tdefine( \"jquery\", [], function() {\n\t\treturn jQuery;\n\t});\n}\n\n\n\n\nvar\n\t// Map over jQuery in case of overwrite\n\t_jQuery = window.jQuery,\n\n\t// Map over the $ in case of overwrite\n\t_$ = window.$;\n\njQuery.noConflict = function( deep ) {\n\tif ( window.$ === jQuery ) {\n\t\twindow.$ = _$;\n\t}\n\n\tif ( deep && window.jQuery === jQuery ) {\n\t\twindow.jQuery = _jQuery;\n\t}\n\n\treturn jQuery;\n};\n\n// Expose jQuery and $ identifiers, even in\n// AMD (#7102#comment:10, https://github.com/jquery/jquery/pull/557)\n// and CommonJS for browser emulators (#13566)\nif ( typeof noGlobal === strundefined ) {\n\twindow.jQuery = window.$ = jQuery;\n}\n\n\n\n\nreturn jQuery;\n\n}));\n"
  },
  {
    "path": "app_frontend/static/plugin/JavaScript-Load-Image-2.12.2/package.json",
    "content": "{\n  \"name\": \"blueimp-load-image\",\n  \"version\": \"2.12.2\",\n  \"title\": \"JavaScript Load Image\",\n  \"description\": \"JavaScript Load Image is a library to load images provided as File or Blob objects or via URL. It returns an optionally scaled and/or cropped HTML img or canvas element. It also provides a method to parse image meta data to extract Exif tags and thumbnails and to restore the complete image header after resizing.\",\n  \"keywords\": [\n    \"javascript\",\n    \"load\",\n    \"loading\",\n    \"image\",\n    \"file\",\n    \"blob\",\n    \"url\",\n    \"scale\",\n    \"crop\",\n    \"img\",\n    \"canvas\",\n    \"meta\",\n    \"exif\",\n    \"thumbnail\",\n    \"resizing\"\n  ],\n  \"homepage\": \"https://github.com/blueimp/JavaScript-Load-Image\",\n  \"author\": {\n    \"name\": \"Sebastian Tschan\",\n    \"url\": \"https://blueimp.net\"\n  },\n  \"repository\": {\n    \"type\": \"git\",\n    \"url\": \"git://github.com/blueimp/JavaScript-Load-Image.git\"\n  },\n  \"license\": \"MIT\",\n  \"devDependencies\": {\n    \"phantomjs-prebuilt\": \"2.1.13\",\n    \"mocha-phantomjs-core\": \"1.3.1\",\n    \"standard\": \"8.3.0\",\n    \"uglify-js\": \"2.7.3\"\n  },\n  \"scripts\": {\n    \"lint\": \"standard *.js js/*.js test/*.js\",\n    \"unit\": \"phantomjs node_modules/mocha-phantomjs-core/mocha-phantomjs-core.js test/index.html\",\n    \"test\": \"npm run lint && npm run unit\",\n    \"build\": \"cd js && uglifyjs load-image.js load-image-scale.js load-image-meta.js load-image-fetch.js load-image-exif.js load-image-exif-map.js load-image-orientation.js -c -m -o load-image.all.min.js --source-map load-image.all.min.js.map\",\n    \"preversion\": \"npm test\",\n    \"version\": \"npm run build && git add -A js\",\n    \"postversion\": \"git push --tags origin master master:gh-pages && npm publish\"\n  },\n  \"main\": \"js/index.js\"\n}\n"
  },
  {
    "path": "app_frontend/static/plugin/JavaScript-Load-Image-2.12.2/test/index.html",
    "content": "<!DOCTYPE HTML>\n<!--\n/*\n * JavaScript Load Image Test\n * https://github.com/blueimp/JavaScript-Load-Image\n *\n * Copyright 2011, Sebastian Tschan\n * https://blueimp.net\n *\n * Licensed under the MIT license:\n * https://opensource.org/licenses/MIT\n */\n-->\n<html lang=\"en\">\n<head>\n<!--[if IE]>\n<meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge,chrome=1\">\n<![endif]-->\n<meta charset=\"utf-8\">\n<title>JavaScript Load Image Test</title>\n<meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n<link rel=\"stylesheet\" href=\"vendor/mocha.css\">\n</head>\n<body>\n<div id=\"mocha\"></div>\n<script src=\"vendor/mocha.js\"></script>\n<script src=\"vendor/chai.js\"></script>\n<script>\nwindow.initMochaPhantomJS && initMochaPhantomJS();\nmocha.setup('bdd');\n</script>\n<script src=\"vendor/canvas-to-blob.js\"></script>\n<script src=\"../js/load-image.js\"></script>\n<script src=\"../js/load-image-scale.js\"></script>\n<script src=\"../js/load-image-meta.js\"></script>\n<script src=\"../js/load-image-fetch.js\"></script>\n<script src=\"../js/load-image-exif.js\"></script>\n<script src=\"../js/load-image-exif-map.js\"></script>\n<script src=\"../js/load-image-orientation.js\"></script>\n<script src=\"test.js\"></script>\n<script>\nmocha.checkLeaks();\nmocha.run();\n</script>\n</body>\n</html>\n"
  },
  {
    "path": "app_frontend/static/plugin/JavaScript-Load-Image-2.12.2/test/test.js",
    "content": "/*\n * JavaScript Load Image Test\n * https://github.com/blueimp/JavaScript-Load-Image\n *\n * Copyright 2011, Sebastian Tschan\n * https://blueimp.net\n *\n * Licensed under the MIT license:\n * https://opensource.org/licenses/MIT\n */\n\n/* global describe, it, Blob */\n\n;(function (expect, loadImage) {\n  'use strict'\n\n  var canCreateBlob = !!window.dataURLtoBlob\n  // 80x60px GIF image (color black, base64 data):\n  var b64DataGIF = 'R0lGODdhUAA8AIABAAAAAP///ywAAAAAUAA8AAACS4SPqcvtD6' +\n                    'OctNqLs968+w+G4kiW5omm6sq27gvH8kzX9o3n+s73/g8MCofE' +\n                    'ovGITCqXzKbzCY1Kp9Sq9YrNarfcrvcLDovH5PKsAAA7'\n  var imageUrlGIF = 'data:image/gif;base64,' + b64DataGIF\n  var blobGIF = canCreateBlob && window.dataURLtoBlob(imageUrlGIF)\n  // 2x1px JPEG (color white, with the Exif orientation flag set to 6):\n  var b64DataJPEG = '/9j/4AAQSkZJRgABAQEAYABgAAD/4QAiRXhpZgAASUkqAAgAAA' +\n                    'ABABIBAwABAAAABgASAAAAAAD/2wBDAAEBAQEBAQEBAQEBAQEB' +\n                    'AQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQ' +\n                    'EBAQEBAQEBAQEBAQH/2wBDAQEBAQEBAQEBAQEBAQEBAQEBAQEB' +\n                    'AQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQ' +\n                    'EBAQEBAQH/wAARCAABAAIDASIAAhEBAxEB/8QAHwAAAQUBAQEB' +\n                    'AQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUFBA' +\n                    'QAAAF9AQIDAAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAk' +\n                    'M2JyggkKFhcYGRolJicoKSo0NTY3ODk6Q0RFRkdISUpTVFVWV1' +\n                    'hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJWWl5iZmqKj' +\n                    'pKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uHi4+' +\n                    'Tl5ufo6erx8vP09fb3+Pn6/8QAHwEAAwEBAQEBAQEBAQAAAAAA' +\n                    'AAECAwQFBgcICQoL/8QAtREAAgECBAQDBAcFBAQAAQJ3AAECAx' +\n                    'EEBSExBhJBUQdhcRMiMoEIFEKRobHBCSMzUvAVYnLRChYkNOEl' +\n                    '8RcYGRomJygpKjU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2' +\n                    'hpanN0dXZ3eHl6goOEhYaHiImKkpOUlZaXmJmaoqOkpaanqKmq' +\n                    'srO0tba3uLm6wsPExcbHyMnK0tPU1dbX2Nna4uPk5ebn6Onq8v' +\n                    'P09fb3+Pn6/9oADAMBAAIRAxEAPwD+/iiiigD/2Q=='\n  var imageUrlJPEG = 'data:image/jpeg;base64,' + b64DataJPEG\n  var blobJPEG = canCreateBlob && window.dataURLtoBlob(imageUrlJPEG)\n  function createBlob (data, type) {\n    try {\n      return new Blob([data], {type: type})\n    } catch (e) {\n      var BlobBuilder = window.BlobBuilder || window.WebKitBlobBuilder ||\n      window.MozBlobBuilder || window.MSBlobBuilder\n      var builder = new BlobBuilder()\n      builder.append(data.buffer || data)\n      return builder.getBlob(type)\n    }\n  }\n\n  describe('Loading', function () {\n    it('Return the img element or FileReader object to allow aborting the image load', function () {\n      var img = loadImage(blobGIF, function () {\n        return\n      })\n      expect(img).to.be.an.instanceOf(Object)\n      expect(img.onload).to.be.a('function')\n      expect(img.onerror).to.be.a('function')\n    })\n\n    it('Load image url', function (done) {\n      expect(loadImage(imageUrlGIF, function (img) {\n        expect(img.width).to.equal(80)\n        expect(img.height).to.equal(60)\n        done()\n      })).to.be.ok\n    })\n\n    it('Load image blob', function (done) {\n      expect(loadImage(blobGIF, function (img) {\n        expect(img.width).to.equal(80)\n        expect(img.height).to.equal(60)\n        done()\n      })).to.be.ok\n    })\n\n    it('Return image loading error to callback', function (done) {\n      expect(loadImage('404', function (img) {\n        expect(img).to.be.an.instanceOf(window.Event)\n        expect(img.type).to.equal('error')\n        done()\n      })).to.be.ok\n    })\n\n    it('Keep object URL if noRevoke is true', function (done) {\n      expect(loadImage(blobGIF, function (img) {\n        loadImage(img.src, function (img2) {\n          expect(img.width).to.equal(img2.width)\n          expect(img.height).to.equal(img2.height)\n          done()\n        })\n      }, {noRevoke: true})).to.be.ok\n    })\n\n    it('Discard object URL if noRevoke is undefined or false', function (done) {\n      expect(loadImage(blobGIF, function (img) {\n        loadImage(img.src, function (img2) {\n          if (!window.callPhantom) {\n            // revokeObjectUrl doesn't seem to have an effect in PhantomJS\n            expect(img2).to.be.an.instanceOf(window.Event)\n            expect(img2.type).to.equal('error')\n          }\n          done()\n        })\n      })).to.be.ok\n    })\n  })\n\n  describe('Scaling', function () {\n    describe('max/min', function () {\n      it('Scale to maxWidth', function (done) {\n        expect(loadImage(blobGIF, function (img) {\n          expect(img.width).to.equal(40)\n          expect(img.height).to.equal(30)\n          done()\n        }, {maxWidth: 40})).to.be.ok\n      })\n\n      it('Scale to maxHeight', function (done) {\n        expect(loadImage(blobGIF, function (img) {\n          expect(img.width).to.equal(20)\n          expect(img.height).to.equal(15)\n          done()\n        }, {maxHeight: 15})).to.be.ok\n      })\n\n      it('Scale to minWidth', function (done) {\n        expect(loadImage(blobGIF, function (img) {\n          expect(img.width).to.equal(160)\n          expect(img.height).to.equal(120)\n          done()\n        }, {minWidth: 160})).to.be.ok\n      })\n\n      it('Scale to minHeight', function (done) {\n        expect(loadImage(blobGIF, function (img) {\n          expect(img.width).to.equal(320)\n          expect(img.height).to.equal(240)\n          done()\n        }, {minHeight: 240})).to.be.ok\n      })\n\n      it('Scale to minWidth but respect maxWidth', function (done) {\n        expect(loadImage(blobGIF, function (img) {\n          expect(img.width).to.equal(160)\n          expect(img.height).to.equal(120)\n          done()\n        }, {minWidth: 240, maxWidth: 160})).to.be.ok\n      })\n\n      it('Scale to minHeight but respect maxHeight', function (done) {\n        expect(loadImage(blobGIF, function (img) {\n          expect(img.width).to.equal(160)\n          expect(img.height).to.equal(120)\n          done()\n        }, {minHeight: 180, maxHeight: 120})).to.be.ok\n      })\n\n      it('Scale to minWidth but respect maxHeight', function (done) {\n        expect(loadImage(blobGIF, function (img) {\n          expect(img.width).to.equal(160)\n          expect(img.height).to.equal(120)\n          done()\n        }, {minWidth: 240, maxHeight: 120})).to.be.ok\n      })\n\n      it('Scale to minHeight but respect maxWidth', function (done) {\n        expect(loadImage(blobGIF, function (img) {\n          expect(img.width).to.equal(160)\n          expect(img.height).to.equal(120)\n          done()\n        }, {minHeight: 180, maxWidth: 160})).to.be.ok\n      })\n\n      it('Scale up with the given pixelRatio', function (done) {\n        expect(loadImage(blobGIF, function (img) {\n          expect(img.width).to.equal(320)\n          expect(img.height).to.equal(240)\n          expect(img.style.width).to.equal('160px')\n          expect(img.style.height).to.equal('120px')\n          done()\n        }, {minWidth: 160, canvas: true, pixelRatio: 2})).to.be.ok\n      })\n\n      it('Scale down with the given pixelRatio', function (done) {\n        expect(loadImage(blobGIF, function (img) {\n          expect(img.width).to.equal(80)\n          expect(img.height).to.equal(60)\n          expect(img.style.width).to.equal('40px')\n          expect(img.style.height).to.equal('30px')\n          done()\n        }, {maxWidth: 40, canvas: true, pixelRatio: 2})).to.be.ok\n      })\n\n      it('Scale down with the given downsamplingRatio', function (done) {\n        expect(loadImage(blobGIF, function (img) {\n          expect(img.width).to.equal(20)\n          expect(img.height).to.equal(15)\n          done()\n        }, {maxWidth: 20, canvas: true, downsamplingRatio: 0.5})).to.be.ok\n      })\n\n      it('Ignore max settings if image dimensions are smaller', function (done) {\n        expect(loadImage(blobGIF, function (img) {\n          expect(img.width).to.equal(80)\n          expect(img.height).to.equal(60)\n          done()\n        }, {maxWidth: 160, maxHeight: 120})).to.be.ok\n      })\n\n      it('Ignore min settings if image dimensions are larger', function (done) {\n        expect(loadImage(blobGIF, function (img) {\n          expect(img.width).to.equal(80)\n          expect(img.height).to.equal(60)\n          done()\n        }, {minWidth: 40, minHeight: 30})).to.be.ok\n      })\n    })\n\n    describe('contain', function () {\n      it('Scale up to contain image in max dimensions', function (done) {\n        expect(loadImage(blobGIF, function (img) {\n          expect(img.width).to.equal(160)\n          expect(img.height).to.equal(120)\n          done()\n        }, {maxWidth: 160, maxHeight: 160, contain: true})).to.be.ok\n      })\n\n      it('Scale down to contain image in max dimensions', function (done) {\n        expect(loadImage(blobGIF, function (img) {\n          expect(img.width).to.equal(40)\n          expect(img.height).to.equal(30)\n          done()\n        }, {maxWidth: 40, maxHeight: 40, contain: true})).to.be.ok\n      })\n    })\n\n    describe('cover', function () {\n      it('Scale up to cover max dimensions with image dimensions', function (done) {\n        expect(loadImage(blobGIF, function (img) {\n          expect(img.width).to.equal(160)\n          expect(img.height).to.equal(120)\n          done()\n        }, {maxWidth: 120, maxHeight: 120, cover: true})).to.be.ok\n      })\n\n      it('Scale down to cover max dimensions with image dimensions', function (done) {\n        expect(loadImage(blobGIF, function (img) {\n          expect(img.width).to.equal(40)\n          expect(img.height).to.equal(30)\n          done()\n        }, {maxWidth: 30, maxHeight: 30, cover: true})).to.be.ok\n      })\n    })\n  })\n\n  describe('Cropping', function () {\n    it('Crop to same values for maxWidth and maxHeight', function (done) {\n      expect(loadImage(blobGIF, function (img) {\n        expect(img.width).to.equal(40)\n        expect(img.height).to.equal(40)\n        done()\n      }, {maxWidth: 40, maxHeight: 40, crop: true})).to.be.ok\n    })\n\n    it('Crop to different values for maxWidth and maxHeight', function (done) {\n      expect(loadImage(blobGIF, function (img) {\n        expect(img.width).to.equal(40)\n        expect(img.height).to.equal(60)\n        done()\n      }, {maxWidth: 40, maxHeight: 60, crop: true})).to.be.ok\n    })\n\n    it('Crop using the given sourceWidth and sourceHeight dimensions', function (done) {\n      expect(loadImage(blobGIF, function (img) {\n        expect(img.width).to.equal(40)\n        expect(img.height).to.equal(40)\n        done()\n      }, {sourceWidth: 40, sourceHeight: 40, crop: true})).to.be.ok\n    })\n\n    it('Crop using the given left and top coordinates', function (done) {\n      expect(loadImage(blobGIF, function (img) {\n        expect(img.width).to.equal(40)\n        expect(img.height).to.equal(20)\n        done()\n      }, {left: 40, top: 40, crop: true})).to.be.ok\n    })\n\n    it('Crop using the given right and bottom coordinates', function (done) {\n      expect(loadImage(blobGIF, function (img) {\n        expect(img.width).to.equal(40)\n        expect(img.height).to.equal(20)\n        done()\n      }, {right: 40, bottom: 40, crop: true})).to.be.ok\n    })\n\n    it('Crop using the given 2:1 aspectRatio', function (done) {\n      expect(loadImage(blobGIF, function (img) {\n        expect(img.width).to.equal(80)\n        expect(img.height).to.equal(40)\n        done()\n      }, {aspectRatio: 2})).to.be.ok\n    })\n\n    it('Crop using the given 2:3 aspectRatio', function (done) {\n      expect(loadImage(blobGIF, function (img) {\n        expect(img.width).to.equal(40)\n        expect(img.height).to.equal(60)\n        done()\n      }, {aspectRatio: 2 / 3})).to.be.ok\n    })\n\n    it('Crop using maxWidth/maxHeight with the given pixelRatio', function (done) {\n      expect(loadImage(blobGIF, function (img) {\n        expect(img.width).to.equal(80)\n        expect(img.height).to.equal(80)\n        expect(img.style.width).to.equal('40px')\n        expect(img.style.height).to.equal('40px')\n        done()\n      }, {maxWidth: 40, maxHeight: 40, crop: true, pixelRatio: 2})).to.be.ok\n    })\n\n    it('Crop using sourceWidth/sourceHeight with the given pixelRatio', function (done) {\n      expect(loadImage(blobGIF, function (img) {\n        expect(img.width).to.equal(80)\n        expect(img.height).to.equal(80)\n        expect(img.style.width).to.equal('40px')\n        expect(img.style.height).to.equal('40px')\n        done()\n      }, {sourceWidth: 40, sourceHeight: 40, crop: true, pixelRatio: 2})).to.be.ok\n    })\n\n    it('Crop using maxWidth/maxHeight with the given downsamplingRatio', function (done) {\n      expect(loadImage(blobGIF, function (img) {\n        expect(img.width).to.equal(10)\n        expect(img.height).to.equal(10)\n\n        var data = img.getContext('2d').getImageData(0, 0, 10, 10).data\n        for (var i = 0; i < data.length / 4; i += 4) {\n          expect(data[i]).to.equal(0)\n          expect(data[i + 1]).to.equal(0)\n          expect(data[i + 2]).to.equal(0)\n          expect(data[i + 3]).to.equal(255)\n        }\n\n        done()\n      }, {maxWidth: 10, maxHeight: 10, crop: true, downsamplingRatio: 0.5})).to.be.ok\n    })\n  })\n\n  describe('Orientation', function () {\n    it('Should keep the orientation', function (done) {\n      expect(loadImage(blobGIF, function (img) {\n        expect(img.width).to.equal(80)\n        expect(img.height).to.equal(60)\n        done()\n      }, {orientation: 1})).to.be.ok\n    })\n\n    it('Should rotate left', function (done) {\n      expect(loadImage(blobGIF, function (img) {\n        expect(img.width).to.equal(60)\n        expect(img.height).to.equal(80)\n        done()\n      }, {orientation: 8})).to.be.ok\n    })\n\n    it('Should rotate right', function (done) {\n      expect(loadImage(blobGIF, function (img) {\n        expect(img.width).to.equal(60)\n        expect(img.height).to.equal(80)\n        done()\n      }, {orientation: 6})).to.be.ok\n    })\n\n    it('Should adjust constraints to new coordinates', function (done) {\n      expect(loadImage(blobGIF, function (img) {\n        expect(img.width).to.equal(30)\n        expect(img.height).to.equal(40)\n        done()\n      }, {orientation: 6, maxWidth: 30, maxHeight: 40})).to.be.ok\n    })\n\n    it('Should adjust left and top to new coordinates', function (done) {\n      expect(loadImage(blobGIF, function (img) {\n        expect(img.width).to.equal(30)\n        expect(img.height).to.equal(60)\n        done()\n      }, {orientation: 5, left: 30, top: 20})).to.be.ok\n    })\n\n    it('Should adjust right and bottom to new coordinates', function (done) {\n      expect(loadImage(blobGIF, function (img) {\n        expect(img.width).to.equal(30)\n        expect(img.height).to.equal(60)\n        done()\n      }, {orientation: 5, right: 30, bottom: 20})).to.be.ok\n    })\n\n    it('Should adjust left and bottom to new coordinates', function (done) {\n      expect(loadImage(blobGIF, function (img) {\n        expect(img.width).to.equal(30)\n        expect(img.height).to.equal(60)\n        done()\n      }, {orientation: 7, left: 30, bottom: 20})).to.be.ok\n    })\n\n    it('Should adjust right and top to new coordinates', function (done) {\n      expect(loadImage(blobGIF, function (img) {\n        expect(img.width).to.equal(30)\n        expect(img.height).to.equal(60)\n        done()\n      }, {orientation: 7, right: 30, top: 20})).to.be.ok\n    })\n\n    it('Should rotate left with the given pixelRatio', function (done) {\n      expect(loadImage(blobGIF, function (img) {\n        expect(img.width).to.equal(120)\n        expect(img.height).to.equal(160)\n        expect(img.style.width).to.equal('60px')\n        expect(img.style.height).to.equal('80px')\n        done()\n      }, {orientation: 8, pixelRatio: 2})).to.be.ok\n    })\n\n    it('Should rotate right with the given pixelRatio', function (done) {\n      expect(loadImage(blobGIF, function (img) {\n        expect(img.width).to.equal(120)\n        expect(img.height).to.equal(160)\n        expect(img.style.width).to.equal('60px')\n        expect(img.style.height).to.equal('80px')\n        done()\n      }, {orientation: 6, pixelRatio: 2})).to.be.ok\n    })\n\n    it('Should ignore too small orientation value', function (done) {\n      expect(loadImage(blobGIF, function (img) {\n        expect(img.width).to.equal(80)\n        expect(img.height).to.equal(60)\n        done()\n      }, {orientation: -1})).to.be.ok\n    })\n\n    it('Should ignore too large orientation value', function (done) {\n      expect(loadImage(blobGIF, function (img) {\n        expect(img.width).to.equal(80)\n        expect(img.height).to.equal(60)\n        done()\n      }, {orientation: 9})).to.be.ok\n    })\n\n    it('Should rotate right based on the exif orientation value', function (done) {\n      expect(loadImage(blobJPEG, function (img, data) {\n        expect(data).to.be.ok\n        expect(data.exif).to.be.ok\n        expect(data.exif.get('Orientation')).to.equal(6)\n        expect(img.width).to.equal(1)\n        expect(img.height).to.equal(2)\n        done()\n      }, {orientation: true})).to.be.ok\n    })\n\n    it('Should adjust constraints based on the exif orientation value', function (done) {\n      expect(loadImage(blobJPEG, function (img) {\n        expect(img.width).to.equal(10)\n        expect(img.height).to.equal(20)\n        done()\n      }, {orientation: true, minWidth: 10, minHeight: 20})).to.be.ok\n    })\n  })\n\n  describe('Canvas', function () {\n    it('Return img element to callback if canvas is not true', function (done) {\n      expect(loadImage(blobGIF, function (img) {\n        expect(img.getContext).to.be.falsy\n        expect(img.nodeName.toLowerCase()).to.equal('img')\n        done()\n      })).to.be.ok\n    })\n\n    it('Return canvas element to callback if canvas is true', function (done) {\n      expect(loadImage(blobGIF, function (img) {\n        expect(img.getContext).to.be.ok\n        expect(img.nodeName.toLowerCase()).to.equal('canvas')\n        done()\n      }, {canvas: true})).to.be.ok\n    })\n\n    it('Return scaled canvas element to callback', function (done) {\n      expect(loadImage(blobGIF, function (img) {\n        expect(img.getContext).to.be.ok\n        expect(img.nodeName.toLowerCase()).to.equal('canvas')\n        expect(img.width).to.equal(40)\n        expect(img.height).to.equal(30)\n        done()\n      }, {canvas: true, maxWidth: 40})).to.be.ok\n    })\n\n    it('Accept a canvas element as parameter for loadImage.scale', function (done) {\n      expect(loadImage(blobGIF, function (img) {\n        img = loadImage.scale(img, {\n          maxWidth: 40\n        })\n        expect(img.getContext).to.be.ok\n        expect(img.nodeName.toLowerCase()).to.equal('canvas')\n        expect(img.width).to.equal(40)\n        expect(img.height).to.equal(30)\n        done()\n      }, {canvas: true})).to.be.ok\n    })\n  })\n\n  describe('Metadata', function () {\n    it('Should parse Exif information', function (done) {\n      loadImage.parseMetaData(blobJPEG, function (data) {\n        expect(data.exif).to.be.ok\n        expect(data.exif.get('Orientation')).to.equal(6)\n        done()\n      })\n    })\n\n    it('Should parse the complete image head', function (done) {\n      loadImage.parseMetaData(blobJPEG, function (data) {\n        expect(data.imageHead).to.be.ok\n        loadImage.parseMetaData(\n          createBlob(data.imageHead, 'image/jpeg'),\n          function (data) {\n            expect(data.exif).to.be.ok\n            expect(data.exif.get('Orientation')).to.equal(6)\n            done()\n          }\n        )\n      })\n    })\n\n    it('Should parse meta data automatically', function (done) {\n      expect(loadImage(blobJPEG, function (img, data) {\n        expect(data).to.be.ok\n        expect(data.imageHead).to.be.ok\n        expect(data.exif).to.be.ok\n        expect(data.exif.get('Orientation')).to.equal(6)\n        done()\n      }, {meta: true})).to.be.ok\n    })\n  })\n\n  if ('fetch' in window && 'Request' in window) {\n    describe('Fetch', function () {\n      it('Should fetch blob from URL if meta is true', function (done) {\n        expect(loadImage(imageUrlJPEG, function (img, data) {\n          expect(data).to.be.ok\n          expect(data.imageHead).to.be.ok\n          expect(data.exif).to.be.ok\n          expect(data.exif.get('Orientation')).to.equal(6)\n          done()\n        }, {meta: true})).to.be.ok\n      })\n\n      it('Should not fetch blob from URL if meta is false', function (done) {\n        expect(loadImage(imageUrlJPEG, function (img, data) {\n          expect(data.imageHead).to.be.falsy\n          expect(data.exif).to.be.falsy\n          expect(img.width).to.equal(2)\n          expect(img.height).to.equal(1)\n          done()\n        })).to.be.ok\n      })\n    })\n  }\n}(\n  this.chai.expect,\n  this.loadImage\n))\n"
  },
  {
    "path": "app_frontend/static/plugin/JavaScript-Load-Image-2.12.2/test/vendor/canvas-to-blob.js",
    "content": "/*\n * JavaScript Canvas to Blob\n * https://github.com/blueimp/JavaScript-Canvas-to-Blob\n *\n * Copyright 2012, Sebastian Tschan\n * https://blueimp.net\n *\n * Licensed under the MIT license:\n * https://opensource.org/licenses/MIT\n *\n * Based on stackoverflow user Stoive's code snippet:\n * http://stackoverflow.com/q/4998908\n */\n\n/*global window, atob, Blob, ArrayBuffer, Uint8Array, define, module */\n\n;(function (window) {\n  'use strict'\n\n  var CanvasPrototype = window.HTMLCanvasElement &&\n                          window.HTMLCanvasElement.prototype\n  var hasBlobConstructor = window.Blob && (function () {\n    try {\n      return Boolean(new Blob())\n    } catch (e) {\n      return false\n    }\n  }())\n  var hasArrayBufferViewSupport = hasBlobConstructor && window.Uint8Array &&\n    (function () {\n      try {\n        return new Blob([new Uint8Array(100)]).size === 100\n      } catch (e) {\n        return false\n      }\n    }())\n  var BlobBuilder = window.BlobBuilder || window.WebKitBlobBuilder ||\n                      window.MozBlobBuilder || window.MSBlobBuilder\n  var dataURIPattern = /^data:((.*?)(;charset=.*?)?)(;base64)?,/\n  var dataURLtoBlob = (hasBlobConstructor || BlobBuilder) && window.atob &&\n    window.ArrayBuffer && window.Uint8Array &&\n    function (dataURI) {\n      var matches,\n        mediaType,\n        isBase64,\n        dataString,\n        byteString,\n        arrayBuffer,\n        intArray,\n        i,\n        bb\n      // Parse the dataURI components as per RFC 2397\n      matches = dataURI.match(dataURIPattern)\n      if (!matches) {\n        throw new Error('invalid data URI')\n      }\n      // Default to text/plain;charset=US-ASCII\n      mediaType = matches[2]\n        ? matches[1]\n        : 'text/plain' + (matches[3] || ';charset=US-ASCII')\n      isBase64 = !!matches[4]\n      dataString = dataURI.slice(matches[0].length)\n      if (isBase64) {\n        // Convert base64 to raw binary data held in a string:\n        byteString = atob(dataString)\n      } else {\n        // Convert base64/URLEncoded data component to raw binary:\n        byteString = decodeURIComponent(dataString)\n      }\n      // Write the bytes of the string to an ArrayBuffer:\n      arrayBuffer = new ArrayBuffer(byteString.length)\n      intArray = new Uint8Array(arrayBuffer)\n      for (i = 0; i < byteString.length; i += 1) {\n        intArray[i] = byteString.charCodeAt(i)\n      }\n      // Write the ArrayBuffer (or ArrayBufferView) to a blob:\n      if (hasBlobConstructor) {\n        return new Blob(\n          [hasArrayBufferViewSupport ? intArray : arrayBuffer],\n          {type: mediaType}\n        )\n      }\n      bb = new BlobBuilder()\n      bb.append(arrayBuffer)\n      return bb.getBlob(mediaType)\n    }\n  if (window.HTMLCanvasElement && !CanvasPrototype.toBlob) {\n    if (CanvasPrototype.mozGetAsFile) {\n      CanvasPrototype.toBlob = function (callback, type, quality) {\n        if (quality && CanvasPrototype.toDataURL && dataURLtoBlob) {\n          callback(dataURLtoBlob(this.toDataURL(type, quality)))\n        } else {\n          callback(this.mozGetAsFile('blob', type))\n        }\n      }\n    } else if (CanvasPrototype.toDataURL && dataURLtoBlob) {\n      CanvasPrototype.toBlob = function (callback, type, quality) {\n        callback(dataURLtoBlob(this.toDataURL(type, quality)))\n      }\n    }\n  }\n  if (typeof define === 'function' && define.amd) {\n    define(function () {\n      return dataURLtoBlob\n    })\n  } else if (typeof module === 'object' && module.exports) {\n    module.exports = dataURLtoBlob\n  } else {\n    window.dataURLtoBlob = dataURLtoBlob\n  }\n}(window))\n"
  },
  {
    "path": "app_frontend/static/plugin/JavaScript-Load-Image-2.12.2/test/vendor/chai.js",
    "content": "(function(f){if(typeof exports===\"object\"&&typeof module!==\"undefined\"){module.exports=f()}else if(typeof define===\"function\"&&define.amd){define([],f)}else{var g;if(typeof window!==\"undefined\"){g=window}else if(typeof global!==\"undefined\"){g=global}else if(typeof self!==\"undefined\"){g=self}else{g=this}g.chai = f()}})(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require==\"function\"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error(\"Cannot find module '\"+o+\"'\");throw f.code=\"MODULE_NOT_FOUND\",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require==\"function\"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){\nmodule.exports = require('./lib/chai');\n\n},{\"./lib/chai\":2}],2:[function(require,module,exports){\n/*!\n * chai\n * Copyright(c) 2011-2014 Jake Luer <jake@alogicalparadox.com>\n * MIT Licensed\n */\n\nvar used = []\n  , exports = module.exports = {};\n\n/*!\n * Chai version\n */\n\nexports.version = '3.5.0';\n\n/*!\n * Assertion Error\n */\n\nexports.AssertionError = require('assertion-error');\n\n/*!\n * Utils for plugins (not exported)\n */\n\nvar util = require('./chai/utils');\n\n/**\n * # .use(function)\n *\n * Provides a way to extend the internals of Chai\n *\n * @param {Function}\n * @returns {this} for chaining\n * @api public\n */\n\nexports.use = function (fn) {\n  if (!~used.indexOf(fn)) {\n    fn(this, util);\n    used.push(fn);\n  }\n\n  return this;\n};\n\n/*!\n * Utility Functions\n */\n\nexports.util = util;\n\n/*!\n * Configuration\n */\n\nvar config = require('./chai/config');\nexports.config = config;\n\n/*!\n * Primary `Assertion` prototype\n */\n\nvar assertion = require('./chai/assertion');\nexports.use(assertion);\n\n/*!\n * Core Assertions\n */\n\nvar core = require('./chai/core/assertions');\nexports.use(core);\n\n/*!\n * Expect interface\n */\n\nvar expect = require('./chai/interface/expect');\nexports.use(expect);\n\n/*!\n * Should interface\n */\n\nvar should = require('./chai/interface/should');\nexports.use(should);\n\n/*!\n * Assert interface\n */\n\nvar assert = require('./chai/interface/assert');\nexports.use(assert);\n\n},{\"./chai/assertion\":3,\"./chai/config\":4,\"./chai/core/assertions\":5,\"./chai/interface/assert\":6,\"./chai/interface/expect\":7,\"./chai/interface/should\":8,\"./chai/utils\":22,\"assertion-error\":30}],3:[function(require,module,exports){\n/*!\n * chai\n * http://chaijs.com\n * Copyright(c) 2011-2014 Jake Luer <jake@alogicalparadox.com>\n * MIT Licensed\n */\n\nvar config = require('./config');\n\nmodule.exports = function (_chai, util) {\n  /*!\n   * Module dependencies.\n   */\n\n  var AssertionError = _chai.AssertionError\n    , flag = util.flag;\n\n  /*!\n   * Module export.\n   */\n\n  _chai.Assertion = Assertion;\n\n  /*!\n   * Assertion Constructor\n   *\n   * Creates object for chaining.\n   *\n   * @api private\n   */\n\n  function Assertion (obj, msg, stack) {\n    flag(this, 'ssfi', stack || arguments.callee);\n    flag(this, 'object', obj);\n    flag(this, 'message', msg);\n  }\n\n  Object.defineProperty(Assertion, 'includeStack', {\n    get: function() {\n      console.warn('Assertion.includeStack is deprecated, use chai.config.includeStack instead.');\n      return config.includeStack;\n    },\n    set: function(value) {\n      console.warn('Assertion.includeStack is deprecated, use chai.config.includeStack instead.');\n      config.includeStack = value;\n    }\n  });\n\n  Object.defineProperty(Assertion, 'showDiff', {\n    get: function() {\n      console.warn('Assertion.showDiff is deprecated, use chai.config.showDiff instead.');\n      return config.showDiff;\n    },\n    set: function(value) {\n      console.warn('Assertion.showDiff is deprecated, use chai.config.showDiff instead.');\n      config.showDiff = value;\n    }\n  });\n\n  Assertion.addProperty = function (name, fn) {\n    util.addProperty(this.prototype, name, fn);\n  };\n\n  Assertion.addMethod = function (name, fn) {\n    util.addMethod(this.prototype, name, fn);\n  };\n\n  Assertion.addChainableMethod = function (name, fn, chainingBehavior) {\n    util.addChainableMethod(this.prototype, name, fn, chainingBehavior);\n  };\n\n  Assertion.overwriteProperty = function (name, fn) {\n    util.overwriteProperty(this.prototype, name, fn);\n  };\n\n  Assertion.overwriteMethod = function (name, fn) {\n    util.overwriteMethod(this.prototype, name, fn);\n  };\n\n  Assertion.overwriteChainableMethod = function (name, fn, chainingBehavior) {\n    util.overwriteChainableMethod(this.prototype, name, fn, chainingBehavior);\n  };\n\n  /**\n   * ### .assert(expression, message, negateMessage, expected, actual, showDiff)\n   *\n   * Executes an expression and check expectations. Throws AssertionError for reporting if test doesn't pass.\n   *\n   * @name assert\n   * @param {Philosophical} expression to be tested\n   * @param {String|Function} message or function that returns message to display if expression fails\n   * @param {String|Function} negatedMessage or function that returns negatedMessage to display if negated expression fails\n   * @param {Mixed} expected value (remember to check for negation)\n   * @param {Mixed} actual (optional) will default to `this.obj`\n   * @param {Boolean} showDiff (optional) when set to `true`, assert will display a diff in addition to the message if expression fails\n   * @api private\n   */\n\n  Assertion.prototype.assert = function (expr, msg, negateMsg, expected, _actual, showDiff) {\n    var ok = util.test(this, arguments);\n    if (true !== showDiff) showDiff = false;\n    if (true !== config.showDiff) showDiff = false;\n\n    if (!ok) {\n      var msg = util.getMessage(this, arguments)\n        , actual = util.getActual(this, arguments);\n      throw new AssertionError(msg, {\n          actual: actual\n        , expected: expected\n        , showDiff: showDiff\n      }, (config.includeStack) ? this.assert : flag(this, 'ssfi'));\n    }\n  };\n\n  /*!\n   * ### ._obj\n   *\n   * Quick reference to stored `actual` value for plugin developers.\n   *\n   * @api private\n   */\n\n  Object.defineProperty(Assertion.prototype, '_obj',\n    { get: function () {\n        return flag(this, 'object');\n      }\n    , set: function (val) {\n        flag(this, 'object', val);\n      }\n  });\n};\n\n},{\"./config\":4}],4:[function(require,module,exports){\nmodule.exports = {\n\n  /**\n   * ### config.includeStack\n   *\n   * User configurable property, influences whether stack trace\n   * is included in Assertion error message. Default of false\n   * suppresses stack trace in the error message.\n   *\n   *     chai.config.includeStack = true;  // enable stack on error\n   *\n   * @param {Boolean}\n   * @api public\n   */\n\n   includeStack: false,\n\n  /**\n   * ### config.showDiff\n   *\n   * User configurable property, influences whether or not\n   * the `showDiff` flag should be included in the thrown\n   * AssertionErrors. `false` will always be `false`; `true`\n   * will be true when the assertion has requested a diff\n   * be shown.\n   *\n   * @param {Boolean}\n   * @api public\n   */\n\n  showDiff: true,\n\n  /**\n   * ### config.truncateThreshold\n   *\n   * User configurable property, sets length threshold for actual and\n   * expected values in assertion errors. If this threshold is exceeded, for\n   * example for large data structures, the value is replaced with something\n   * like `[ Array(3) ]` or `{ Object (prop1, prop2) }`.\n   *\n   * Set it to zero if you want to disable truncating altogether.\n   *\n   * This is especially userful when doing assertions on arrays: having this\n   * set to a reasonable large value makes the failure messages readily\n   * inspectable.\n   *\n   *     chai.config.truncateThreshold = 0;  // disable truncating\n   *\n   * @param {Number}\n   * @api public\n   */\n\n  truncateThreshold: 40\n\n};\n\n},{}],5:[function(require,module,exports){\n/*!\n * chai\n * http://chaijs.com\n * Copyright(c) 2011-2014 Jake Luer <jake@alogicalparadox.com>\n * MIT Licensed\n */\n\nmodule.exports = function (chai, _) {\n  var Assertion = chai.Assertion\n    , toString = Object.prototype.toString\n    , flag = _.flag;\n\n  /**\n   * ### Language Chains\n   *\n   * The following are provided as chainable getters to\n   * improve the readability of your assertions. They\n   * do not provide testing capabilities unless they\n   * have been overwritten by a plugin.\n   *\n   * **Chains**\n   *\n   * - to\n   * - be\n   * - been\n   * - is\n   * - that\n   * - which\n   * - and\n   * - has\n   * - have\n   * - with\n   * - at\n   * - of\n   * - same\n   *\n   * @name language chains\n   * @namespace BDD\n   * @api public\n   */\n\n  [ 'to', 'be', 'been'\n  , 'is', 'and', 'has', 'have'\n  , 'with', 'that', 'which', 'at'\n  , 'of', 'same' ].forEach(function (chain) {\n    Assertion.addProperty(chain, function () {\n      return this;\n    });\n  });\n\n  /**\n   * ### .not\n   *\n   * Negates any of assertions following in the chain.\n   *\n   *     expect(foo).to.not.equal('bar');\n   *     expect(goodFn).to.not.throw(Error);\n   *     expect({ foo: 'baz' }).to.have.property('foo')\n   *       .and.not.equal('bar');\n   *\n   * @name not\n   * @namespace BDD\n   * @api public\n   */\n\n  Assertion.addProperty('not', function () {\n    flag(this, 'negate', true);\n  });\n\n  /**\n   * ### .deep\n   *\n   * Sets the `deep` flag, later used by the `equal` and\n   * `property` assertions.\n   *\n   *     expect(foo).to.deep.equal({ bar: 'baz' });\n   *     expect({ foo: { bar: { baz: 'quux' } } })\n   *       .to.have.deep.property('foo.bar.baz', 'quux');\n   *\n   * `.deep.property` special characters can be escaped\n   * by adding two slashes before the `.` or `[]`.\n   *\n   *     var deepCss = { '.link': { '[target]': 42 }};\n   *     expect(deepCss).to.have.deep.property('\\\\.link.\\\\[target\\\\]', 42);\n   *\n   * @name deep\n   * @namespace BDD\n   * @api public\n   */\n\n  Assertion.addProperty('deep', function () {\n    flag(this, 'deep', true);\n  });\n\n  /**\n   * ### .any\n   *\n   * Sets the `any` flag, (opposite of the `all` flag)\n   * later used in the `keys` assertion.\n   *\n   *     expect(foo).to.have.any.keys('bar', 'baz');\n   *\n   * @name any\n   * @namespace BDD\n   * @api public\n   */\n\n  Assertion.addProperty('any', function () {\n    flag(this, 'any', true);\n    flag(this, 'all', false)\n  });\n\n\n  /**\n   * ### .all\n   *\n   * Sets the `all` flag (opposite of the `any` flag)\n   * later used by the `keys` assertion.\n   *\n   *     expect(foo).to.have.all.keys('bar', 'baz');\n   *\n   * @name all\n   * @namespace BDD\n   * @api public\n   */\n\n  Assertion.addProperty('all', function () {\n    flag(this, 'all', true);\n    flag(this, 'any', false);\n  });\n\n  /**\n   * ### .a(type)\n   *\n   * The `a` and `an` assertions are aliases that can be\n   * used either as language chains or to assert a value's\n   * type.\n   *\n   *     // typeof\n   *     expect('test').to.be.a('string');\n   *     expect({ foo: 'bar' }).to.be.an('object');\n   *     expect(null).to.be.a('null');\n   *     expect(undefined).to.be.an('undefined');\n   *     expect(new Error).to.be.an('error');\n   *     expect(new Promise).to.be.a('promise');\n   *     expect(new Float32Array()).to.be.a('float32array');\n   *     expect(Symbol()).to.be.a('symbol');\n   *\n   *     // es6 overrides\n   *     expect({[Symbol.toStringTag]:()=>'foo'}).to.be.a('foo');\n   *\n   *     // language chain\n   *     expect(foo).to.be.an.instanceof(Foo);\n   *\n   * @name a\n   * @alias an\n   * @param {String} type\n   * @param {String} message _optional_\n   * @namespace BDD\n   * @api public\n   */\n\n  function an (type, msg) {\n    if (msg) flag(this, 'message', msg);\n    type = type.toLowerCase();\n    var obj = flag(this, 'object')\n      , article = ~[ 'a', 'e', 'i', 'o', 'u' ].indexOf(type.charAt(0)) ? 'an ' : 'a ';\n\n    this.assert(\n        type === _.type(obj)\n      , 'expected #{this} to be ' + article + type\n      , 'expected #{this} not to be ' + article + type\n    );\n  }\n\n  Assertion.addChainableMethod('an', an);\n  Assertion.addChainableMethod('a', an);\n\n  /**\n   * ### .include(value)\n   *\n   * The `include` and `contain` assertions can be used as either property\n   * based language chains or as methods to assert the inclusion of an object\n   * in an array or a substring in a string. When used as language chains,\n   * they toggle the `contains` flag for the `keys` assertion.\n   *\n   *     expect([1,2,3]).to.include(2);\n   *     expect('foobar').to.contain('foo');\n   *     expect({ foo: 'bar', hello: 'universe' }).to.include.keys('foo');\n   *\n   * @name include\n   * @alias contain\n   * @alias includes\n   * @alias contains\n   * @param {Object|String|Number} obj\n   * @param {String} message _optional_\n   * @namespace BDD\n   * @api public\n   */\n\n  function includeChainingBehavior () {\n    flag(this, 'contains', true);\n  }\n\n  function include (val, msg) {\n    _.expectTypes(this, ['array', 'object', 'string']);\n\n    if (msg) flag(this, 'message', msg);\n    var obj = flag(this, 'object');\n    var expected = false;\n\n    if (_.type(obj) === 'array' && _.type(val) === 'object') {\n      for (var i in obj) {\n        if (_.eql(obj[i], val)) {\n          expected = true;\n          break;\n        }\n      }\n    } else if (_.type(val) === 'object') {\n      if (!flag(this, 'negate')) {\n        for (var k in val) new Assertion(obj).property(k, val[k]);\n        return;\n      }\n      var subset = {};\n      for (var k in val) subset[k] = obj[k];\n      expected = _.eql(subset, val);\n    } else {\n      expected = (obj != undefined) && ~obj.indexOf(val);\n    }\n    this.assert(\n        expected\n      , 'expected #{this} to include ' + _.inspect(val)\n      , 'expected #{this} to not include ' + _.inspect(val));\n  }\n\n  Assertion.addChainableMethod('include', include, includeChainingBehavior);\n  Assertion.addChainableMethod('contain', include, includeChainingBehavior);\n  Assertion.addChainableMethod('contains', include, includeChainingBehavior);\n  Assertion.addChainableMethod('includes', include, includeChainingBehavior);\n\n  /**\n   * ### .ok\n   *\n   * Asserts that the target is truthy.\n   *\n   *     expect('everything').to.be.ok;\n   *     expect(1).to.be.ok;\n   *     expect(false).to.not.be.ok;\n   *     expect(undefined).to.not.be.ok;\n   *     expect(null).to.not.be.ok;\n   *\n   * @name ok\n   * @namespace BDD\n   * @api public\n   */\n\n  Assertion.addProperty('ok', function () {\n    this.assert(\n        flag(this, 'object')\n      , 'expected #{this} to be truthy'\n      , 'expected #{this} to be falsy');\n  });\n\n  /**\n   * ### .true\n   *\n   * Asserts that the target is `true`.\n   *\n   *     expect(true).to.be.true;\n   *     expect(1).to.not.be.true;\n   *\n   * @name true\n   * @namespace BDD\n   * @api public\n   */\n\n  Assertion.addProperty('true', function () {\n    this.assert(\n        true === flag(this, 'object')\n      , 'expected #{this} to be true'\n      , 'expected #{this} to be false'\n      , this.negate ? false : true\n    );\n  });\n\n  /**\n   * ### .false\n   *\n   * Asserts that the target is `false`.\n   *\n   *     expect(false).to.be.false;\n   *     expect(0).to.not.be.false;\n   *\n   * @name false\n   * @namespace BDD\n   * @api public\n   */\n\n  Assertion.addProperty('false', function () {\n    this.assert(\n        false === flag(this, 'object')\n      , 'expected #{this} to be false'\n      , 'expected #{this} to be true'\n      , this.negate ? true : false\n    );\n  });\n\n  /**\n   * ### .null\n   *\n   * Asserts that the target is `null`.\n   *\n   *     expect(null).to.be.null;\n   *     expect(undefined).to.not.be.null;\n   *\n   * @name null\n   * @namespace BDD\n   * @api public\n   */\n\n  Assertion.addProperty('null', function () {\n    this.assert(\n        null === flag(this, 'object')\n      , 'expected #{this} to be null'\n      , 'expected #{this} not to be null'\n    );\n  });\n\n  /**\n   * ### .undefined\n   *\n   * Asserts that the target is `undefined`.\n   *\n   *     expect(undefined).to.be.undefined;\n   *     expect(null).to.not.be.undefined;\n   *\n   * @name undefined\n   * @namespace BDD\n   * @api public\n   */\n\n  Assertion.addProperty('undefined', function () {\n    this.assert(\n        undefined === flag(this, 'object')\n      , 'expected #{this} to be undefined'\n      , 'expected #{this} not to be undefined'\n    );\n  });\n\n  /**\n   * ### .NaN\n   * Asserts that the target is `NaN`.\n   *\n   *     expect('foo').to.be.NaN;\n   *     expect(4).not.to.be.NaN;\n   *\n   * @name NaN\n   * @namespace BDD\n   * @api public\n   */\n\n  Assertion.addProperty('NaN', function () {\n    this.assert(\n        isNaN(flag(this, 'object'))\n        , 'expected #{this} to be NaN'\n        , 'expected #{this} not to be NaN'\n    );\n  });\n\n  /**\n   * ### .exist\n   *\n   * Asserts that the target is neither `null` nor `undefined`.\n   *\n   *     var foo = 'hi'\n   *       , bar = null\n   *       , baz;\n   *\n   *     expect(foo).to.exist;\n   *     expect(bar).to.not.exist;\n   *     expect(baz).to.not.exist;\n   *\n   * @name exist\n   * @namespace BDD\n   * @api public\n   */\n\n  Assertion.addProperty('exist', function () {\n    this.assert(\n        null != flag(this, 'object')\n      , 'expected #{this} to exist'\n      , 'expected #{this} to not exist'\n    );\n  });\n\n\n  /**\n   * ### .empty\n   *\n   * Asserts that the target's length is `0`. For arrays and strings, it checks\n   * the `length` property. For objects, it gets the count of\n   * enumerable keys.\n   *\n   *     expect([]).to.be.empty;\n   *     expect('').to.be.empty;\n   *     expect({}).to.be.empty;\n   *\n   * @name empty\n   * @namespace BDD\n   * @api public\n   */\n\n  Assertion.addProperty('empty', function () {\n    var obj = flag(this, 'object')\n      , expected = obj;\n\n    if (Array.isArray(obj) || 'string' === typeof object) {\n      expected = obj.length;\n    } else if (typeof obj === 'object') {\n      expected = Object.keys(obj).length;\n    }\n\n    this.assert(\n        !expected\n      , 'expected #{this} to be empty'\n      , 'expected #{this} not to be empty'\n    );\n  });\n\n  /**\n   * ### .arguments\n   *\n   * Asserts that the target is an arguments object.\n   *\n   *     function test () {\n   *       expect(arguments).to.be.arguments;\n   *     }\n   *\n   * @name arguments\n   * @alias Arguments\n   * @namespace BDD\n   * @api public\n   */\n\n  function checkArguments () {\n    var obj = flag(this, 'object')\n      , type = Object.prototype.toString.call(obj);\n    this.assert(\n        '[object Arguments]' === type\n      , 'expected #{this} to be arguments but got ' + type\n      , 'expected #{this} to not be arguments'\n    );\n  }\n\n  Assertion.addProperty('arguments', checkArguments);\n  Assertion.addProperty('Arguments', checkArguments);\n\n  /**\n   * ### .equal(value)\n   *\n   * Asserts that the target is strictly equal (`===`) to `value`.\n   * Alternately, if the `deep` flag is set, asserts that\n   * the target is deeply equal to `value`.\n   *\n   *     expect('hello').to.equal('hello');\n   *     expect(42).to.equal(42);\n   *     expect(1).to.not.equal(true);\n   *     expect({ foo: 'bar' }).to.not.equal({ foo: 'bar' });\n   *     expect({ foo: 'bar' }).to.deep.equal({ foo: 'bar' });\n   *\n   * @name equal\n   * @alias equals\n   * @alias eq\n   * @alias deep.equal\n   * @param {Mixed} value\n   * @param {String} message _optional_\n   * @namespace BDD\n   * @api public\n   */\n\n  function assertEqual (val, msg) {\n    if (msg) flag(this, 'message', msg);\n    var obj = flag(this, 'object');\n    if (flag(this, 'deep')) {\n      return this.eql(val);\n    } else {\n      this.assert(\n          val === obj\n        , 'expected #{this} to equal #{exp}'\n        , 'expected #{this} to not equal #{exp}'\n        , val\n        , this._obj\n        , true\n      );\n    }\n  }\n\n  Assertion.addMethod('equal', assertEqual);\n  Assertion.addMethod('equals', assertEqual);\n  Assertion.addMethod('eq', assertEqual);\n\n  /**\n   * ### .eql(value)\n   *\n   * Asserts that the target is deeply equal to `value`.\n   *\n   *     expect({ foo: 'bar' }).to.eql({ foo: 'bar' });\n   *     expect([ 1, 2, 3 ]).to.eql([ 1, 2, 3 ]);\n   *\n   * @name eql\n   * @alias eqls\n   * @param {Mixed} value\n   * @param {String} message _optional_\n   * @namespace BDD\n   * @api public\n   */\n\n  function assertEql(obj, msg) {\n    if (msg) flag(this, 'message', msg);\n    this.assert(\n        _.eql(obj, flag(this, 'object'))\n      , 'expected #{this} to deeply equal #{exp}'\n      , 'expected #{this} to not deeply equal #{exp}'\n      , obj\n      , this._obj\n      , true\n    );\n  }\n\n  Assertion.addMethod('eql', assertEql);\n  Assertion.addMethod('eqls', assertEql);\n\n  /**\n   * ### .above(value)\n   *\n   * Asserts that the target is greater than `value`.\n   *\n   *     expect(10).to.be.above(5);\n   *\n   * Can also be used in conjunction with `length` to\n   * assert a minimum length. The benefit being a\n   * more informative error message than if the length\n   * was supplied directly.\n   *\n   *     expect('foo').to.have.length.above(2);\n   *     expect([ 1, 2, 3 ]).to.have.length.above(2);\n   *\n   * @name above\n   * @alias gt\n   * @alias greaterThan\n   * @param {Number} value\n   * @param {String} message _optional_\n   * @namespace BDD\n   * @api public\n   */\n\n  function assertAbove (n, msg) {\n    if (msg) flag(this, 'message', msg);\n    var obj = flag(this, 'object');\n    if (flag(this, 'doLength')) {\n      new Assertion(obj, msg).to.have.property('length');\n      var len = obj.length;\n      this.assert(\n          len > n\n        , 'expected #{this} to have a length above #{exp} but got #{act}'\n        , 'expected #{this} to not have a length above #{exp}'\n        , n\n        , len\n      );\n    } else {\n      this.assert(\n          obj > n\n        , 'expected #{this} to be above ' + n\n        , 'expected #{this} to be at most ' + n\n      );\n    }\n  }\n\n  Assertion.addMethod('above', assertAbove);\n  Assertion.addMethod('gt', assertAbove);\n  Assertion.addMethod('greaterThan', assertAbove);\n\n  /**\n   * ### .least(value)\n   *\n   * Asserts that the target is greater than or equal to `value`.\n   *\n   *     expect(10).to.be.at.least(10);\n   *\n   * Can also be used in conjunction with `length` to\n   * assert a minimum length. The benefit being a\n   * more informative error message than if the length\n   * was supplied directly.\n   *\n   *     expect('foo').to.have.length.of.at.least(2);\n   *     expect([ 1, 2, 3 ]).to.have.length.of.at.least(3);\n   *\n   * @name least\n   * @alias gte\n   * @param {Number} value\n   * @param {String} message _optional_\n   * @namespace BDD\n   * @api public\n   */\n\n  function assertLeast (n, msg) {\n    if (msg) flag(this, 'message', msg);\n    var obj = flag(this, 'object');\n    if (flag(this, 'doLength')) {\n      new Assertion(obj, msg).to.have.property('length');\n      var len = obj.length;\n      this.assert(\n          len >= n\n        , 'expected #{this} to have a length at least #{exp} but got #{act}'\n        , 'expected #{this} to have a length below #{exp}'\n        , n\n        , len\n      );\n    } else {\n      this.assert(\n          obj >= n\n        , 'expected #{this} to be at least ' + n\n        , 'expected #{this} to be below ' + n\n      );\n    }\n  }\n\n  Assertion.addMethod('least', assertLeast);\n  Assertion.addMethod('gte', assertLeast);\n\n  /**\n   * ### .below(value)\n   *\n   * Asserts that the target is less than `value`.\n   *\n   *     expect(5).to.be.below(10);\n   *\n   * Can also be used in conjunction with `length` to\n   * assert a maximum length. The benefit being a\n   * more informative error message than if the length\n   * was supplied directly.\n   *\n   *     expect('foo').to.have.length.below(4);\n   *     expect([ 1, 2, 3 ]).to.have.length.below(4);\n   *\n   * @name below\n   * @alias lt\n   * @alias lessThan\n   * @param {Number} value\n   * @param {String} message _optional_\n   * @namespace BDD\n   * @api public\n   */\n\n  function assertBelow (n, msg) {\n    if (msg) flag(this, 'message', msg);\n    var obj = flag(this, 'object');\n    if (flag(this, 'doLength')) {\n      new Assertion(obj, msg).to.have.property('length');\n      var len = obj.length;\n      this.assert(\n          len < n\n        , 'expected #{this} to have a length below #{exp} but got #{act}'\n        , 'expected #{this} to not have a length below #{exp}'\n        , n\n        , len\n      );\n    } else {\n      this.assert(\n          obj < n\n        , 'expected #{this} to be below ' + n\n        , 'expected #{this} to be at least ' + n\n      );\n    }\n  }\n\n  Assertion.addMethod('below', assertBelow);\n  Assertion.addMethod('lt', assertBelow);\n  Assertion.addMethod('lessThan', assertBelow);\n\n  /**\n   * ### .most(value)\n   *\n   * Asserts that the target is less than or equal to `value`.\n   *\n   *     expect(5).to.be.at.most(5);\n   *\n   * Can also be used in conjunction with `length` to\n   * assert a maximum length. The benefit being a\n   * more informative error message than if the length\n   * was supplied directly.\n   *\n   *     expect('foo').to.have.length.of.at.most(4);\n   *     expect([ 1, 2, 3 ]).to.have.length.of.at.most(3);\n   *\n   * @name most\n   * @alias lte\n   * @param {Number} value\n   * @param {String} message _optional_\n   * @namespace BDD\n   * @api public\n   */\n\n  function assertMost (n, msg) {\n    if (msg) flag(this, 'message', msg);\n    var obj = flag(this, 'object');\n    if (flag(this, 'doLength')) {\n      new Assertion(obj, msg).to.have.property('length');\n      var len = obj.length;\n      this.assert(\n          len <= n\n        , 'expected #{this} to have a length at most #{exp} but got #{act}'\n        , 'expected #{this} to have a length above #{exp}'\n        , n\n        , len\n      );\n    } else {\n      this.assert(\n          obj <= n\n        , 'expected #{this} to be at most ' + n\n        , 'expected #{this} to be above ' + n\n      );\n    }\n  }\n\n  Assertion.addMethod('most', assertMost);\n  Assertion.addMethod('lte', assertMost);\n\n  /**\n   * ### .within(start, finish)\n   *\n   * Asserts that the target is within a range.\n   *\n   *     expect(7).to.be.within(5,10);\n   *\n   * Can also be used in conjunction with `length` to\n   * assert a length range. The benefit being a\n   * more informative error message than if the length\n   * was supplied directly.\n   *\n   *     expect('foo').to.have.length.within(2,4);\n   *     expect([ 1, 2, 3 ]).to.have.length.within(2,4);\n   *\n   * @name within\n   * @param {Number} start lowerbound inclusive\n   * @param {Number} finish upperbound inclusive\n   * @param {String} message _optional_\n   * @namespace BDD\n   * @api public\n   */\n\n  Assertion.addMethod('within', function (start, finish, msg) {\n    if (msg) flag(this, 'message', msg);\n    var obj = flag(this, 'object')\n      , range = start + '..' + finish;\n    if (flag(this, 'doLength')) {\n      new Assertion(obj, msg).to.have.property('length');\n      var len = obj.length;\n      this.assert(\n          len >= start && len <= finish\n        , 'expected #{this} to have a length within ' + range\n        , 'expected #{this} to not have a length within ' + range\n      );\n    } else {\n      this.assert(\n          obj >= start && obj <= finish\n        , 'expected #{this} to be within ' + range\n        , 'expected #{this} to not be within ' + range\n      );\n    }\n  });\n\n  /**\n   * ### .instanceof(constructor)\n   *\n   * Asserts that the target is an instance of `constructor`.\n   *\n   *     var Tea = function (name) { this.name = name; }\n   *       , Chai = new Tea('chai');\n   *\n   *     expect(Chai).to.be.an.instanceof(Tea);\n   *     expect([ 1, 2, 3 ]).to.be.instanceof(Array);\n   *\n   * @name instanceof\n   * @param {Constructor} constructor\n   * @param {String} message _optional_\n   * @alias instanceOf\n   * @namespace BDD\n   * @api public\n   */\n\n  function assertInstanceOf (constructor, msg) {\n    if (msg) flag(this, 'message', msg);\n    var name = _.getName(constructor);\n    this.assert(\n        flag(this, 'object') instanceof constructor\n      , 'expected #{this} to be an instance of ' + name\n      , 'expected #{this} to not be an instance of ' + name\n    );\n  };\n\n  Assertion.addMethod('instanceof', assertInstanceOf);\n  Assertion.addMethod('instanceOf', assertInstanceOf);\n\n  /**\n   * ### .property(name, [value])\n   *\n   * Asserts that the target has a property `name`, optionally asserting that\n   * the value of that property is strictly equal to  `value`.\n   * If the `deep` flag is set, you can use dot- and bracket-notation for deep\n   * references into objects and arrays.\n   *\n   *     // simple referencing\n   *     var obj = { foo: 'bar' };\n   *     expect(obj).to.have.property('foo');\n   *     expect(obj).to.have.property('foo', 'bar');\n   *\n   *     // deep referencing\n   *     var deepObj = {\n   *         green: { tea: 'matcha' }\n   *       , teas: [ 'chai', 'matcha', { tea: 'konacha' } ]\n   *     };\n   *\n   *     expect(deepObj).to.have.deep.property('green.tea', 'matcha');\n   *     expect(deepObj).to.have.deep.property('teas[1]', 'matcha');\n   *     expect(deepObj).to.have.deep.property('teas[2].tea', 'konacha');\n   *\n   * You can also use an array as the starting point of a `deep.property`\n   * assertion, or traverse nested arrays.\n   *\n   *     var arr = [\n   *         [ 'chai', 'matcha', 'konacha' ]\n   *       , [ { tea: 'chai' }\n   *         , { tea: 'matcha' }\n   *         , { tea: 'konacha' } ]\n   *     ];\n   *\n   *     expect(arr).to.have.deep.property('[0][1]', 'matcha');\n   *     expect(arr).to.have.deep.property('[1][2].tea', 'konacha');\n   *\n   * Furthermore, `property` changes the subject of the assertion\n   * to be the value of that property from the original object. This\n   * permits for further chainable assertions on that property.\n   *\n   *     expect(obj).to.have.property('foo')\n   *       .that.is.a('string');\n   *     expect(deepObj).to.have.property('green')\n   *       .that.is.an('object')\n   *       .that.deep.equals({ tea: 'matcha' });\n   *     expect(deepObj).to.have.property('teas')\n   *       .that.is.an('array')\n   *       .with.deep.property('[2]')\n   *         .that.deep.equals({ tea: 'konacha' });\n   *\n   * Note that dots and bracket in `name` must be backslash-escaped when\n   * the `deep` flag is set, while they must NOT be escaped when the `deep`\n   * flag is not set.\n   *\n   *     // simple referencing\n   *     var css = { '.link[target]': 42 };\n   *     expect(css).to.have.property('.link[target]', 42);\n   *\n   *     // deep referencing\n   *     var deepCss = { '.link': { '[target]': 42 }};\n   *     expect(deepCss).to.have.deep.property('\\\\.link.\\\\[target\\\\]', 42);\n   *\n   * @name property\n   * @alias deep.property\n   * @param {String} name\n   * @param {Mixed} value (optional)\n   * @param {String} message _optional_\n   * @returns value of property for chaining\n   * @namespace BDD\n   * @api public\n   */\n\n  Assertion.addMethod('property', function (name, val, msg) {\n    if (msg) flag(this, 'message', msg);\n\n    var isDeep = !!flag(this, 'deep')\n      , descriptor = isDeep ? 'deep property ' : 'property '\n      , negate = flag(this, 'negate')\n      , obj = flag(this, 'object')\n      , pathInfo = isDeep ? _.getPathInfo(name, obj) : null\n      , hasProperty = isDeep\n        ? pathInfo.exists\n        : _.hasProperty(name, obj)\n      , value = isDeep\n        ? pathInfo.value\n        : obj[name];\n\n    if (negate && arguments.length > 1) {\n      if (undefined === value) {\n        msg = (msg != null) ? msg + ': ' : '';\n        throw new Error(msg + _.inspect(obj) + ' has no ' + descriptor + _.inspect(name));\n      }\n    } else {\n      this.assert(\n          hasProperty\n        , 'expected #{this} to have a ' + descriptor + _.inspect(name)\n        , 'expected #{this} to not have ' + descriptor + _.inspect(name));\n    }\n\n    if (arguments.length > 1) {\n      this.assert(\n          val === value\n        , 'expected #{this} to have a ' + descriptor + _.inspect(name) + ' of #{exp}, but got #{act}'\n        , 'expected #{this} to not have a ' + descriptor + _.inspect(name) + ' of #{act}'\n        , val\n        , value\n      );\n    }\n\n    flag(this, 'object', value);\n  });\n\n\n  /**\n   * ### .ownProperty(name)\n   *\n   * Asserts that the target has an own property `name`.\n   *\n   *     expect('test').to.have.ownProperty('length');\n   *\n   * @name ownProperty\n   * @alias haveOwnProperty\n   * @param {String} name\n   * @param {String} message _optional_\n   * @namespace BDD\n   * @api public\n   */\n\n  function assertOwnProperty (name, msg) {\n    if (msg) flag(this, 'message', msg);\n    var obj = flag(this, 'object');\n    this.assert(\n        obj.hasOwnProperty(name)\n      , 'expected #{this} to have own property ' + _.inspect(name)\n      , 'expected #{this} to not have own property ' + _.inspect(name)\n    );\n  }\n\n  Assertion.addMethod('ownProperty', assertOwnProperty);\n  Assertion.addMethod('haveOwnProperty', assertOwnProperty);\n\n  /**\n   * ### .ownPropertyDescriptor(name[, descriptor[, message]])\n   *\n   * Asserts that the target has an own property descriptor `name`, that optionally matches `descriptor`.\n   *\n   *     expect('test').to.have.ownPropertyDescriptor('length');\n   *     expect('test').to.have.ownPropertyDescriptor('length', { enumerable: false, configurable: false, writable: false, value: 4 });\n   *     expect('test').not.to.have.ownPropertyDescriptor('length', { enumerable: false, configurable: false, writable: false, value: 3 });\n   *     expect('test').ownPropertyDescriptor('length').to.have.property('enumerable', false);\n   *     expect('test').ownPropertyDescriptor('length').to.have.keys('value');\n   *\n   * @name ownPropertyDescriptor\n   * @alias haveOwnPropertyDescriptor\n   * @param {String} name\n   * @param {Object} descriptor _optional_\n   * @param {String} message _optional_\n   * @namespace BDD\n   * @api public\n   */\n\n  function assertOwnPropertyDescriptor (name, descriptor, msg) {\n    if (typeof descriptor === 'string') {\n      msg = descriptor;\n      descriptor = null;\n    }\n    if (msg) flag(this, 'message', msg);\n    var obj = flag(this, 'object');\n    var actualDescriptor = Object.getOwnPropertyDescriptor(Object(obj), name);\n    if (actualDescriptor && descriptor) {\n      this.assert(\n          _.eql(descriptor, actualDescriptor)\n        , 'expected the own property descriptor for ' + _.inspect(name) + ' on #{this} to match ' + _.inspect(descriptor) + ', got ' + _.inspect(actualDescriptor)\n        , 'expected the own property descriptor for ' + _.inspect(name) + ' on #{this} to not match ' + _.inspect(descriptor)\n        , descriptor\n        , actualDescriptor\n        , true\n      );\n    } else {\n      this.assert(\n          actualDescriptor\n        , 'expected #{this} to have an own property descriptor for ' + _.inspect(name)\n        , 'expected #{this} to not have an own property descriptor for ' + _.inspect(name)\n      );\n    }\n    flag(this, 'object', actualDescriptor);\n  }\n\n  Assertion.addMethod('ownPropertyDescriptor', assertOwnPropertyDescriptor);\n  Assertion.addMethod('haveOwnPropertyDescriptor', assertOwnPropertyDescriptor);\n\n  /**\n   * ### .length\n   *\n   * Sets the `doLength` flag later used as a chain precursor to a value\n   * comparison for the `length` property.\n   *\n   *     expect('foo').to.have.length.above(2);\n   *     expect([ 1, 2, 3 ]).to.have.length.above(2);\n   *     expect('foo').to.have.length.below(4);\n   *     expect([ 1, 2, 3 ]).to.have.length.below(4);\n   *     expect('foo').to.have.length.within(2,4);\n   *     expect([ 1, 2, 3 ]).to.have.length.within(2,4);\n   *\n   * *Deprecation notice:* Using `length` as an assertion will be deprecated\n   * in version 2.4.0 and removed in 3.0.0. Code using the old style of\n   * asserting for `length` property value using `length(value)` should be\n   * switched to use `lengthOf(value)` instead.\n   *\n   * @name length\n   * @namespace BDD\n   * @api public\n   */\n\n  /**\n   * ### .lengthOf(value[, message])\n   *\n   * Asserts that the target's `length` property has\n   * the expected value.\n   *\n   *     expect([ 1, 2, 3]).to.have.lengthOf(3);\n   *     expect('foobar').to.have.lengthOf(6);\n   *\n   * @name lengthOf\n   * @param {Number} length\n   * @param {String} message _optional_\n   * @namespace BDD\n   * @api public\n   */\n\n  function assertLengthChain () {\n    flag(this, 'doLength', true);\n  }\n\n  function assertLength (n, msg) {\n    if (msg) flag(this, 'message', msg);\n    var obj = flag(this, 'object');\n    new Assertion(obj, msg).to.have.property('length');\n    var len = obj.length;\n\n    this.assert(\n        len == n\n      , 'expected #{this} to have a length of #{exp} but got #{act}'\n      , 'expected #{this} to not have a length of #{act}'\n      , n\n      , len\n    );\n  }\n\n  Assertion.addChainableMethod('length', assertLength, assertLengthChain);\n  Assertion.addMethod('lengthOf', assertLength);\n\n  /**\n   * ### .match(regexp)\n   *\n   * Asserts that the target matches a regular expression.\n   *\n   *     expect('foobar').to.match(/^foo/);\n   *\n   * @name match\n   * @alias matches\n   * @param {RegExp} RegularExpression\n   * @param {String} message _optional_\n   * @namespace BDD\n   * @api public\n   */\n  function assertMatch(re, msg) {\n    if (msg) flag(this, 'message', msg);\n    var obj = flag(this, 'object');\n    this.assert(\n        re.exec(obj)\n      , 'expected #{this} to match ' + re\n      , 'expected #{this} not to match ' + re\n    );\n  }\n\n  Assertion.addMethod('match', assertMatch);\n  Assertion.addMethod('matches', assertMatch);\n\n  /**\n   * ### .string(string)\n   *\n   * Asserts that the string target contains another string.\n   *\n   *     expect('foobar').to.have.string('bar');\n   *\n   * @name string\n   * @param {String} string\n   * @param {String} message _optional_\n   * @namespace BDD\n   * @api public\n   */\n\n  Assertion.addMethod('string', function (str, msg) {\n    if (msg) flag(this, 'message', msg);\n    var obj = flag(this, 'object');\n    new Assertion(obj, msg).is.a('string');\n\n    this.assert(\n        ~obj.indexOf(str)\n      , 'expected #{this} to contain ' + _.inspect(str)\n      , 'expected #{this} to not contain ' + _.inspect(str)\n    );\n  });\n\n\n  /**\n   * ### .keys(key1, [key2], [...])\n   *\n   * Asserts that the target contains any or all of the passed-in keys.\n   * Use in combination with `any`, `all`, `contains`, or `have` will affect\n   * what will pass.\n   *\n   * When used in conjunction with `any`, at least one key that is passed\n   * in must exist in the target object. This is regardless whether or not\n   * the `have` or `contain` qualifiers are used. Note, either `any` or `all`\n   * should be used in the assertion. If neither are used, the assertion is\n   * defaulted to `all`.\n   *\n   * When both `all` and `contain` are used, the target object must have at\n   * least all of the passed-in keys but may have more keys not listed.\n   *\n   * When both `all` and `have` are used, the target object must both contain\n   * all of the passed-in keys AND the number of keys in the target object must\n   * match the number of keys passed in (in other words, a target object must\n   * have all and only all of the passed-in keys).\n   *\n   *     expect({ foo: 1, bar: 2 }).to.have.any.keys('foo', 'baz');\n   *     expect({ foo: 1, bar: 2 }).to.have.any.keys('foo');\n   *     expect({ foo: 1, bar: 2 }).to.contain.any.keys('bar', 'baz');\n   *     expect({ foo: 1, bar: 2 }).to.contain.any.keys(['foo']);\n   *     expect({ foo: 1, bar: 2 }).to.contain.any.keys({'foo': 6});\n   *     expect({ foo: 1, bar: 2 }).to.have.all.keys(['bar', 'foo']);\n   *     expect({ foo: 1, bar: 2 }).to.have.all.keys({'bar': 6, 'foo': 7});\n   *     expect({ foo: 1, bar: 2, baz: 3 }).to.contain.all.keys(['bar', 'foo']);\n   *     expect({ foo: 1, bar: 2, baz: 3 }).to.contain.all.keys({'bar': 6});\n   *\n   *\n   * @name keys\n   * @alias key\n   * @param {...String|Array|Object} keys\n   * @namespace BDD\n   * @api public\n   */\n\n  function assertKeys (keys) {\n    var obj = flag(this, 'object')\n      , str\n      , ok = true\n      , mixedArgsMsg = 'keys must be given single argument of Array|Object|String, or multiple String arguments';\n\n    switch (_.type(keys)) {\n      case \"array\":\n        if (arguments.length > 1) throw (new Error(mixedArgsMsg));\n        break;\n      case \"object\":\n        if (arguments.length > 1) throw (new Error(mixedArgsMsg));\n        keys = Object.keys(keys);\n        break;\n      default:\n        keys = Array.prototype.slice.call(arguments);\n    }\n\n    if (!keys.length) throw new Error('keys required');\n\n    var actual = Object.keys(obj)\n      , expected = keys\n      , len = keys.length\n      , any = flag(this, 'any')\n      , all = flag(this, 'all');\n\n    if (!any && !all) {\n      all = true;\n    }\n\n    // Has any\n    if (any) {\n      var intersection = expected.filter(function(key) {\n        return ~actual.indexOf(key);\n      });\n      ok = intersection.length > 0;\n    }\n\n    // Has all\n    if (all) {\n      ok = keys.every(function(key){\n        return ~actual.indexOf(key);\n      });\n      if (!flag(this, 'negate') && !flag(this, 'contains')) {\n        ok = ok && keys.length == actual.length;\n      }\n    }\n\n    // Key string\n    if (len > 1) {\n      keys = keys.map(function(key){\n        return _.inspect(key);\n      });\n      var last = keys.pop();\n      if (all) {\n        str = keys.join(', ') + ', and ' + last;\n      }\n      if (any) {\n        str = keys.join(', ') + ', or ' + last;\n      }\n    } else {\n      str = _.inspect(keys[0]);\n    }\n\n    // Form\n    str = (len > 1 ? 'keys ' : 'key ') + str;\n\n    // Have / include\n    str = (flag(this, 'contains') ? 'contain ' : 'have ') + str;\n\n    // Assertion\n    this.assert(\n        ok\n      , 'expected #{this} to ' + str\n      , 'expected #{this} to not ' + str\n      , expected.slice(0).sort()\n      , actual.sort()\n      , true\n    );\n  }\n\n  Assertion.addMethod('keys', assertKeys);\n  Assertion.addMethod('key', assertKeys);\n\n  /**\n   * ### .throw(constructor)\n   *\n   * Asserts that the function target will throw a specific error, or specific type of error\n   * (as determined using `instanceof`), optionally with a RegExp or string inclusion test\n   * for the error's message.\n   *\n   *     var err = new ReferenceError('This is a bad function.');\n   *     var fn = function () { throw err; }\n   *     expect(fn).to.throw(ReferenceError);\n   *     expect(fn).to.throw(Error);\n   *     expect(fn).to.throw(/bad function/);\n   *     expect(fn).to.not.throw('good function');\n   *     expect(fn).to.throw(ReferenceError, /bad function/);\n   *     expect(fn).to.throw(err);\n   *\n   * Please note that when a throw expectation is negated, it will check each\n   * parameter independently, starting with error constructor type. The appropriate way\n   * to check for the existence of a type of error but for a message that does not match\n   * is to use `and`.\n   *\n   *     expect(fn).to.throw(ReferenceError)\n   *        .and.not.throw(/good function/);\n   *\n   * @name throw\n   * @alias throws\n   * @alias Throw\n   * @param {ErrorConstructor} constructor\n   * @param {String|RegExp} expected error message\n   * @param {String} message _optional_\n   * @see https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Error#Error_types\n   * @returns error for chaining (null if no error)\n   * @namespace BDD\n   * @api public\n   */\n\n  function assertThrows (constructor, errMsg, msg) {\n    if (msg) flag(this, 'message', msg);\n    var obj = flag(this, 'object');\n    new Assertion(obj, msg).is.a('function');\n\n    var thrown = false\n      , desiredError = null\n      , name = null\n      , thrownError = null;\n\n    if (arguments.length === 0) {\n      errMsg = null;\n      constructor = null;\n    } else if (constructor && (constructor instanceof RegExp || 'string' === typeof constructor)) {\n      errMsg = constructor;\n      constructor = null;\n    } else if (constructor && constructor instanceof Error) {\n      desiredError = constructor;\n      constructor = null;\n      errMsg = null;\n    } else if (typeof constructor === 'function') {\n      name = constructor.prototype.name;\n      if (!name || (name === 'Error' && constructor !== Error)) {\n        name = constructor.name || (new constructor()).name;\n      }\n    } else {\n      constructor = null;\n    }\n\n    try {\n      obj();\n    } catch (err) {\n      // first, check desired error\n      if (desiredError) {\n        this.assert(\n            err === desiredError\n          , 'expected #{this} to throw #{exp} but #{act} was thrown'\n          , 'expected #{this} to not throw #{exp}'\n          , (desiredError instanceof Error ? desiredError.toString() : desiredError)\n          , (err instanceof Error ? err.toString() : err)\n        );\n\n        flag(this, 'object', err);\n        return this;\n      }\n\n      // next, check constructor\n      if (constructor) {\n        this.assert(\n            err instanceof constructor\n          , 'expected #{this} to throw #{exp} but #{act} was thrown'\n          , 'expected #{this} to not throw #{exp} but #{act} was thrown'\n          , name\n          , (err instanceof Error ? err.toString() : err)\n        );\n\n        if (!errMsg) {\n          flag(this, 'object', err);\n          return this;\n        }\n      }\n\n      // next, check message\n      var message = 'error' === _.type(err) && \"message\" in err\n        ? err.message\n        : '' + err;\n\n      if ((message != null) && errMsg && errMsg instanceof RegExp) {\n        this.assert(\n            errMsg.exec(message)\n          , 'expected #{this} to throw error matching #{exp} but got #{act}'\n          , 'expected #{this} to throw error not matching #{exp}'\n          , errMsg\n          , message\n        );\n\n        flag(this, 'object', err);\n        return this;\n      } else if ((message != null) && errMsg && 'string' === typeof errMsg) {\n        this.assert(\n            ~message.indexOf(errMsg)\n          , 'expected #{this} to throw error including #{exp} but got #{act}'\n          , 'expected #{this} to throw error not including #{act}'\n          , errMsg\n          , message\n        );\n\n        flag(this, 'object', err);\n        return this;\n      } else {\n        thrown = true;\n        thrownError = err;\n      }\n    }\n\n    var actuallyGot = ''\n      , expectedThrown = name !== null\n        ? name\n        : desiredError\n          ? '#{exp}' //_.inspect(desiredError)\n          : 'an error';\n\n    if (thrown) {\n      actuallyGot = ' but #{act} was thrown'\n    }\n\n    this.assert(\n        thrown === true\n      , 'expected #{this} to throw ' + expectedThrown + actuallyGot\n      , 'expected #{this} to not throw ' + expectedThrown + actuallyGot\n      , (desiredError instanceof Error ? desiredError.toString() : desiredError)\n      , (thrownError instanceof Error ? thrownError.toString() : thrownError)\n    );\n\n    flag(this, 'object', thrownError);\n  };\n\n  Assertion.addMethod('throw', assertThrows);\n  Assertion.addMethod('throws', assertThrows);\n  Assertion.addMethod('Throw', assertThrows);\n\n  /**\n   * ### .respondTo(method)\n   *\n   * Asserts that the object or class target will respond to a method.\n   *\n   *     Klass.prototype.bar = function(){};\n   *     expect(Klass).to.respondTo('bar');\n   *     expect(obj).to.respondTo('bar');\n   *\n   * To check if a constructor will respond to a static function,\n   * set the `itself` flag.\n   *\n   *     Klass.baz = function(){};\n   *     expect(Klass).itself.to.respondTo('baz');\n   *\n   * @name respondTo\n   * @alias respondsTo\n   * @param {String} method\n   * @param {String} message _optional_\n   * @namespace BDD\n   * @api public\n   */\n\n  function respondTo (method, msg) {\n    if (msg) flag(this, 'message', msg);\n    var obj = flag(this, 'object')\n      , itself = flag(this, 'itself')\n      , context = ('function' === _.type(obj) && !itself)\n        ? obj.prototype[method]\n        : obj[method];\n\n    this.assert(\n        'function' === typeof context\n      , 'expected #{this} to respond to ' + _.inspect(method)\n      , 'expected #{this} to not respond to ' + _.inspect(method)\n    );\n  }\n\n  Assertion.addMethod('respondTo', respondTo);\n  Assertion.addMethod('respondsTo', respondTo);\n\n  /**\n   * ### .itself\n   *\n   * Sets the `itself` flag, later used by the `respondTo` assertion.\n   *\n   *     function Foo() {}\n   *     Foo.bar = function() {}\n   *     Foo.prototype.baz = function() {}\n   *\n   *     expect(Foo).itself.to.respondTo('bar');\n   *     expect(Foo).itself.not.to.respondTo('baz');\n   *\n   * @name itself\n   * @namespace BDD\n   * @api public\n   */\n\n  Assertion.addProperty('itself', function () {\n    flag(this, 'itself', true);\n  });\n\n  /**\n   * ### .satisfy(method)\n   *\n   * Asserts that the target passes a given truth test.\n   *\n   *     expect(1).to.satisfy(function(num) { return num > 0; });\n   *\n   * @name satisfy\n   * @alias satisfies\n   * @param {Function} matcher\n   * @param {String} message _optional_\n   * @namespace BDD\n   * @api public\n   */\n\n  function satisfy (matcher, msg) {\n    if (msg) flag(this, 'message', msg);\n    var obj = flag(this, 'object');\n    var result = matcher(obj);\n    this.assert(\n        result\n      , 'expected #{this} to satisfy ' + _.objDisplay(matcher)\n      , 'expected #{this} to not satisfy' + _.objDisplay(matcher)\n      , this.negate ? false : true\n      , result\n    );\n  }\n\n  Assertion.addMethod('satisfy', satisfy);\n  Assertion.addMethod('satisfies', satisfy);\n\n  /**\n   * ### .closeTo(expected, delta)\n   *\n   * Asserts that the target is equal `expected`, to within a +/- `delta` range.\n   *\n   *     expect(1.5).to.be.closeTo(1, 0.5);\n   *\n   * @name closeTo\n   * @alias approximately\n   * @param {Number} expected\n   * @param {Number} delta\n   * @param {String} message _optional_\n   * @namespace BDD\n   * @api public\n   */\n\n  function closeTo(expected, delta, msg) {\n    if (msg) flag(this, 'message', msg);\n    var obj = flag(this, 'object');\n\n    new Assertion(obj, msg).is.a('number');\n    if (_.type(expected) !== 'number' || _.type(delta) !== 'number') {\n      throw new Error('the arguments to closeTo or approximately must be numbers');\n    }\n\n    this.assert(\n        Math.abs(obj - expected) <= delta\n      , 'expected #{this} to be close to ' + expected + ' +/- ' + delta\n      , 'expected #{this} not to be close to ' + expected + ' +/- ' + delta\n    );\n  }\n\n  Assertion.addMethod('closeTo', closeTo);\n  Assertion.addMethod('approximately', closeTo);\n\n  function isSubsetOf(subset, superset, cmp) {\n    return subset.every(function(elem) {\n      if (!cmp) return superset.indexOf(elem) !== -1;\n\n      return superset.some(function(elem2) {\n        return cmp(elem, elem2);\n      });\n    })\n  }\n\n  /**\n   * ### .members(set)\n   *\n   * Asserts that the target is a superset of `set`,\n   * or that the target and `set` have the same strictly-equal (===) members.\n   * Alternately, if the `deep` flag is set, set members are compared for deep\n   * equality.\n   *\n   *     expect([1, 2, 3]).to.include.members([3, 2]);\n   *     expect([1, 2, 3]).to.not.include.members([3, 2, 8]);\n   *\n   *     expect([4, 2]).to.have.members([2, 4]);\n   *     expect([5, 2]).to.not.have.members([5, 2, 1]);\n   *\n   *     expect([{ id: 1 }]).to.deep.include.members([{ id: 1 }]);\n   *\n   * @name members\n   * @param {Array} set\n   * @param {String} message _optional_\n   * @namespace BDD\n   * @api public\n   */\n\n  Assertion.addMethod('members', function (subset, msg) {\n    if (msg) flag(this, 'message', msg);\n    var obj = flag(this, 'object');\n\n    new Assertion(obj).to.be.an('array');\n    new Assertion(subset).to.be.an('array');\n\n    var cmp = flag(this, 'deep') ? _.eql : undefined;\n\n    if (flag(this, 'contains')) {\n      return this.assert(\n          isSubsetOf(subset, obj, cmp)\n        , 'expected #{this} to be a superset of #{act}'\n        , 'expected #{this} to not be a superset of #{act}'\n        , obj\n        , subset\n      );\n    }\n\n    this.assert(\n        isSubsetOf(obj, subset, cmp) && isSubsetOf(subset, obj, cmp)\n        , 'expected #{this} to have the same members as #{act}'\n        , 'expected #{this} to not have the same members as #{act}'\n        , obj\n        , subset\n    );\n  });\n\n  /**\n   * ### .oneOf(list)\n   *\n   * Assert that a value appears somewhere in the top level of array `list`.\n   *\n   *     expect('a').to.be.oneOf(['a', 'b', 'c']);\n   *     expect(9).to.not.be.oneOf(['z']);\n   *     expect([3]).to.not.be.oneOf([1, 2, [3]]);\n   *\n   *     var three = [3];\n   *     // for object-types, contents are not compared\n   *     expect(three).to.not.be.oneOf([1, 2, [3]]);\n   *     // comparing references works\n   *     expect(three).to.be.oneOf([1, 2, three]);\n   *\n   * @name oneOf\n   * @param {Array<*>} list\n   * @param {String} message _optional_\n   * @namespace BDD\n   * @api public\n   */\n\n  function oneOf (list, msg) {\n    if (msg) flag(this, 'message', msg);\n    var expected = flag(this, 'object');\n    new Assertion(list).to.be.an('array');\n\n    this.assert(\n        list.indexOf(expected) > -1\n      , 'expected #{this} to be one of #{exp}'\n      , 'expected #{this} to not be one of #{exp}'\n      , list\n      , expected\n    );\n  }\n\n  Assertion.addMethod('oneOf', oneOf);\n\n\n  /**\n   * ### .change(function)\n   *\n   * Asserts that a function changes an object property\n   *\n   *     var obj = { val: 10 };\n   *     var fn = function() { obj.val += 3 };\n   *     var noChangeFn = function() { return 'foo' + 'bar'; }\n   *     expect(fn).to.change(obj, 'val');\n   *     expect(noChangeFn).to.not.change(obj, 'val')\n   *\n   * @name change\n   * @alias changes\n   * @alias Change\n   * @param {String} object\n   * @param {String} property name\n   * @param {String} message _optional_\n   * @namespace BDD\n   * @api public\n   */\n\n  function assertChanges (object, prop, msg) {\n    if (msg) flag(this, 'message', msg);\n    var fn = flag(this, 'object');\n    new Assertion(object, msg).to.have.property(prop);\n    new Assertion(fn).is.a('function');\n\n    var initial = object[prop];\n    fn();\n\n    this.assert(\n      initial !== object[prop]\n      , 'expected .' + prop + ' to change'\n      , 'expected .' + prop + ' to not change'\n    );\n  }\n\n  Assertion.addChainableMethod('change', assertChanges);\n  Assertion.addChainableMethod('changes', assertChanges);\n\n  /**\n   * ### .increase(function)\n   *\n   * Asserts that a function increases an object property\n   *\n   *     var obj = { val: 10 };\n   *     var fn = function() { obj.val = 15 };\n   *     expect(fn).to.increase(obj, 'val');\n   *\n   * @name increase\n   * @alias increases\n   * @alias Increase\n   * @param {String} object\n   * @param {String} property name\n   * @param {String} message _optional_\n   * @namespace BDD\n   * @api public\n   */\n\n  function assertIncreases (object, prop, msg) {\n    if (msg) flag(this, 'message', msg);\n    var fn = flag(this, 'object');\n    new Assertion(object, msg).to.have.property(prop);\n    new Assertion(fn).is.a('function');\n\n    var initial = object[prop];\n    fn();\n\n    this.assert(\n      object[prop] - initial > 0\n      , 'expected .' + prop + ' to increase'\n      , 'expected .' + prop + ' to not increase'\n    );\n  }\n\n  Assertion.addChainableMethod('increase', assertIncreases);\n  Assertion.addChainableMethod('increases', assertIncreases);\n\n  /**\n   * ### .decrease(function)\n   *\n   * Asserts that a function decreases an object property\n   *\n   *     var obj = { val: 10 };\n   *     var fn = function() { obj.val = 5 };\n   *     expect(fn).to.decrease(obj, 'val');\n   *\n   * @name decrease\n   * @alias decreases\n   * @alias Decrease\n   * @param {String} object\n   * @param {String} property name\n   * @param {String} message _optional_\n   * @namespace BDD\n   * @api public\n   */\n\n  function assertDecreases (object, prop, msg) {\n    if (msg) flag(this, 'message', msg);\n    var fn = flag(this, 'object');\n    new Assertion(object, msg).to.have.property(prop);\n    new Assertion(fn).is.a('function');\n\n    var initial = object[prop];\n    fn();\n\n    this.assert(\n      object[prop] - initial < 0\n      , 'expected .' + prop + ' to decrease'\n      , 'expected .' + prop + ' to not decrease'\n    );\n  }\n\n  Assertion.addChainableMethod('decrease', assertDecreases);\n  Assertion.addChainableMethod('decreases', assertDecreases);\n\n  /**\n   * ### .extensible\n   *\n   * Asserts that the target is extensible (can have new properties added to\n   * it).\n   *\n   *     var nonExtensibleObject = Object.preventExtensions({});\n   *     var sealedObject = Object.seal({});\n   *     var frozenObject = Object.freeze({});\n   *\n   *     expect({}).to.be.extensible;\n   *     expect(nonExtensibleObject).to.not.be.extensible;\n   *     expect(sealedObject).to.not.be.extensible;\n   *     expect(frozenObject).to.not.be.extensible;\n   *\n   * @name extensible\n   * @namespace BDD\n   * @api public\n   */\n\n  Assertion.addProperty('extensible', function() {\n    var obj = flag(this, 'object');\n\n    // In ES5, if the argument to this method is not an object (a primitive), then it will cause a TypeError.\n    // In ES6, a non-object argument will be treated as if it was a non-extensible ordinary object, simply return false.\n    // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/isExtensible\n    // The following provides ES6 behavior when a TypeError is thrown under ES5.\n\n    var isExtensible;\n\n    try {\n      isExtensible = Object.isExtensible(obj);\n    } catch (err) {\n      if (err instanceof TypeError) isExtensible = false;\n      else throw err;\n    }\n\n    this.assert(\n      isExtensible\n      , 'expected #{this} to be extensible'\n      , 'expected #{this} to not be extensible'\n    );\n  });\n\n  /**\n   * ### .sealed\n   *\n   * Asserts that the target is sealed (cannot have new properties added to it\n   * and its existing properties cannot be removed).\n   *\n   *     var sealedObject = Object.seal({});\n   *     var frozenObject = Object.freeze({});\n   *\n   *     expect(sealedObject).to.be.sealed;\n   *     expect(frozenObject).to.be.sealed;\n   *     expect({}).to.not.be.sealed;\n   *\n   * @name sealed\n   * @namespace BDD\n   * @api public\n   */\n\n  Assertion.addProperty('sealed', function() {\n    var obj = flag(this, 'object');\n\n    // In ES5, if the argument to this method is not an object (a primitive), then it will cause a TypeError.\n    // In ES6, a non-object argument will be treated as if it was a sealed ordinary object, simply return true.\n    // See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/isSealed\n    // The following provides ES6 behavior when a TypeError is thrown under ES5.\n\n    var isSealed;\n\n    try {\n      isSealed = Object.isSealed(obj);\n    } catch (err) {\n      if (err instanceof TypeError) isSealed = true;\n      else throw err;\n    }\n\n    this.assert(\n      isSealed\n      , 'expected #{this} to be sealed'\n      , 'expected #{this} to not be sealed'\n    );\n  });\n\n  /**\n   * ### .frozen\n   *\n   * Asserts that the target is frozen (cannot have new properties added to it\n   * and its existing properties cannot be modified).\n   *\n   *     var frozenObject = Object.freeze({});\n   *\n   *     expect(frozenObject).to.be.frozen;\n   *     expect({}).to.not.be.frozen;\n   *\n   * @name frozen\n   * @namespace BDD\n   * @api public\n   */\n\n  Assertion.addProperty('frozen', function() {\n    var obj = flag(this, 'object');\n\n    // In ES5, if the argument to this method is not an object (a primitive), then it will cause a TypeError.\n    // In ES6, a non-object argument will be treated as if it was a frozen ordinary object, simply return true.\n    // See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/isFrozen\n    // The following provides ES6 behavior when a TypeError is thrown under ES5.\n\n    var isFrozen;\n\n    try {\n      isFrozen = Object.isFrozen(obj);\n    } catch (err) {\n      if (err instanceof TypeError) isFrozen = true;\n      else throw err;\n    }\n\n    this.assert(\n      isFrozen\n      , 'expected #{this} to be frozen'\n      , 'expected #{this} to not be frozen'\n    );\n  });\n};\n\n},{}],6:[function(require,module,exports){\n/*!\n * chai\n * Copyright(c) 2011-2014 Jake Luer <jake@alogicalparadox.com>\n * MIT Licensed\n */\n\n\nmodule.exports = function (chai, util) {\n\n  /*!\n   * Chai dependencies.\n   */\n\n  var Assertion = chai.Assertion\n    , flag = util.flag;\n\n  /*!\n   * Module export.\n   */\n\n  /**\n   * ### assert(expression, message)\n   *\n   * Write your own test expressions.\n   *\n   *     assert('foo' !== 'bar', 'foo is not bar');\n   *     assert(Array.isArray([]), 'empty arrays are arrays');\n   *\n   * @param {Mixed} expression to test for truthiness\n   * @param {String} message to display on error\n   * @name assert\n   * @namespace Assert\n   * @api public\n   */\n\n  var assert = chai.assert = function (express, errmsg) {\n    var test = new Assertion(null, null, chai.assert);\n    test.assert(\n        express\n      , errmsg\n      , '[ negation message unavailable ]'\n    );\n  };\n\n  /**\n   * ### .fail(actual, expected, [message], [operator])\n   *\n   * Throw a failure. Node.js `assert` module-compatible.\n   *\n   * @name fail\n   * @param {Mixed} actual\n   * @param {Mixed} expected\n   * @param {String} message\n   * @param {String} operator\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.fail = function (actual, expected, message, operator) {\n    message = message || 'assert.fail()';\n    throw new chai.AssertionError(message, {\n        actual: actual\n      , expected: expected\n      , operator: operator\n    }, assert.fail);\n  };\n\n  /**\n   * ### .isOk(object, [message])\n   *\n   * Asserts that `object` is truthy.\n   *\n   *     assert.isOk('everything', 'everything is ok');\n   *     assert.isOk(false, 'this will fail');\n   *\n   * @name isOk\n   * @alias ok\n   * @param {Mixed} object to test\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.isOk = function (val, msg) {\n    new Assertion(val, msg).is.ok;\n  };\n\n  /**\n   * ### .isNotOk(object, [message])\n   *\n   * Asserts that `object` is falsy.\n   *\n   *     assert.isNotOk('everything', 'this will fail');\n   *     assert.isNotOk(false, 'this will pass');\n   *\n   * @name isNotOk\n   * @alias notOk\n   * @param {Mixed} object to test\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.isNotOk = function (val, msg) {\n    new Assertion(val, msg).is.not.ok;\n  };\n\n  /**\n   * ### .equal(actual, expected, [message])\n   *\n   * Asserts non-strict equality (`==`) of `actual` and `expected`.\n   *\n   *     assert.equal(3, '3', '== coerces values to strings');\n   *\n   * @name equal\n   * @param {Mixed} actual\n   * @param {Mixed} expected\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.equal = function (act, exp, msg) {\n    var test = new Assertion(act, msg, assert.equal);\n\n    test.assert(\n        exp == flag(test, 'object')\n      , 'expected #{this} to equal #{exp}'\n      , 'expected #{this} to not equal #{act}'\n      , exp\n      , act\n    );\n  };\n\n  /**\n   * ### .notEqual(actual, expected, [message])\n   *\n   * Asserts non-strict inequality (`!=`) of `actual` and `expected`.\n   *\n   *     assert.notEqual(3, 4, 'these numbers are not equal');\n   *\n   * @name notEqual\n   * @param {Mixed} actual\n   * @param {Mixed} expected\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.notEqual = function (act, exp, msg) {\n    var test = new Assertion(act, msg, assert.notEqual);\n\n    test.assert(\n        exp != flag(test, 'object')\n      , 'expected #{this} to not equal #{exp}'\n      , 'expected #{this} to equal #{act}'\n      , exp\n      , act\n    );\n  };\n\n  /**\n   * ### .strictEqual(actual, expected, [message])\n   *\n   * Asserts strict equality (`===`) of `actual` and `expected`.\n   *\n   *     assert.strictEqual(true, true, 'these booleans are strictly equal');\n   *\n   * @name strictEqual\n   * @param {Mixed} actual\n   * @param {Mixed} expected\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.strictEqual = function (act, exp, msg) {\n    new Assertion(act, msg).to.equal(exp);\n  };\n\n  /**\n   * ### .notStrictEqual(actual, expected, [message])\n   *\n   * Asserts strict inequality (`!==`) of `actual` and `expected`.\n   *\n   *     assert.notStrictEqual(3, '3', 'no coercion for strict equality');\n   *\n   * @name notStrictEqual\n   * @param {Mixed} actual\n   * @param {Mixed} expected\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.notStrictEqual = function (act, exp, msg) {\n    new Assertion(act, msg).to.not.equal(exp);\n  };\n\n  /**\n   * ### .deepEqual(actual, expected, [message])\n   *\n   * Asserts that `actual` is deeply equal to `expected`.\n   *\n   *     assert.deepEqual({ tea: 'green' }, { tea: 'green' });\n   *\n   * @name deepEqual\n   * @param {Mixed} actual\n   * @param {Mixed} expected\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.deepEqual = function (act, exp, msg) {\n    new Assertion(act, msg).to.eql(exp);\n  };\n\n  /**\n   * ### .notDeepEqual(actual, expected, [message])\n   *\n   * Assert that `actual` is not deeply equal to `expected`.\n   *\n   *     assert.notDeepEqual({ tea: 'green' }, { tea: 'jasmine' });\n   *\n   * @name notDeepEqual\n   * @param {Mixed} actual\n   * @param {Mixed} expected\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.notDeepEqual = function (act, exp, msg) {\n    new Assertion(act, msg).to.not.eql(exp);\n  };\n\n   /**\n   * ### .isAbove(valueToCheck, valueToBeAbove, [message])\n   *\n   * Asserts `valueToCheck` is strictly greater than (>) `valueToBeAbove`\n   *\n   *     assert.isAbove(5, 2, '5 is strictly greater than 2');\n   *\n   * @name isAbove\n   * @param {Mixed} valueToCheck\n   * @param {Mixed} valueToBeAbove\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.isAbove = function (val, abv, msg) {\n    new Assertion(val, msg).to.be.above(abv);\n  };\n\n   /**\n   * ### .isAtLeast(valueToCheck, valueToBeAtLeast, [message])\n   *\n   * Asserts `valueToCheck` is greater than or equal to (>=) `valueToBeAtLeast`\n   *\n   *     assert.isAtLeast(5, 2, '5 is greater or equal to 2');\n   *     assert.isAtLeast(3, 3, '3 is greater or equal to 3');\n   *\n   * @name isAtLeast\n   * @param {Mixed} valueToCheck\n   * @param {Mixed} valueToBeAtLeast\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.isAtLeast = function (val, atlst, msg) {\n    new Assertion(val, msg).to.be.least(atlst);\n  };\n\n   /**\n   * ### .isBelow(valueToCheck, valueToBeBelow, [message])\n   *\n   * Asserts `valueToCheck` is strictly less than (<) `valueToBeBelow`\n   *\n   *     assert.isBelow(3, 6, '3 is strictly less than 6');\n   *\n   * @name isBelow\n   * @param {Mixed} valueToCheck\n   * @param {Mixed} valueToBeBelow\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.isBelow = function (val, blw, msg) {\n    new Assertion(val, msg).to.be.below(blw);\n  };\n\n   /**\n   * ### .isAtMost(valueToCheck, valueToBeAtMost, [message])\n   *\n   * Asserts `valueToCheck` is less than or equal to (<=) `valueToBeAtMost`\n   *\n   *     assert.isAtMost(3, 6, '3 is less than or equal to 6');\n   *     assert.isAtMost(4, 4, '4 is less than or equal to 4');\n   *\n   * @name isAtMost\n   * @param {Mixed} valueToCheck\n   * @param {Mixed} valueToBeAtMost\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.isAtMost = function (val, atmst, msg) {\n    new Assertion(val, msg).to.be.most(atmst);\n  };\n\n  /**\n   * ### .isTrue(value, [message])\n   *\n   * Asserts that `value` is true.\n   *\n   *     var teaServed = true;\n   *     assert.isTrue(teaServed, 'the tea has been served');\n   *\n   * @name isTrue\n   * @param {Mixed} value\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.isTrue = function (val, msg) {\n    new Assertion(val, msg).is['true'];\n  };\n\n  /**\n   * ### .isNotTrue(value, [message])\n   *\n   * Asserts that `value` is not true.\n   *\n   *     var tea = 'tasty chai';\n   *     assert.isNotTrue(tea, 'great, time for tea!');\n   *\n   * @name isNotTrue\n   * @param {Mixed} value\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.isNotTrue = function (val, msg) {\n    new Assertion(val, msg).to.not.equal(true);\n  };\n\n  /**\n   * ### .isFalse(value, [message])\n   *\n   * Asserts that `value` is false.\n   *\n   *     var teaServed = false;\n   *     assert.isFalse(teaServed, 'no tea yet? hmm...');\n   *\n   * @name isFalse\n   * @param {Mixed} value\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.isFalse = function (val, msg) {\n    new Assertion(val, msg).is['false'];\n  };\n\n  /**\n   * ### .isNotFalse(value, [message])\n   *\n   * Asserts that `value` is not false.\n   *\n   *     var tea = 'tasty chai';\n   *     assert.isNotFalse(tea, 'great, time for tea!');\n   *\n   * @name isNotFalse\n   * @param {Mixed} value\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.isNotFalse = function (val, msg) {\n    new Assertion(val, msg).to.not.equal(false);\n  };\n\n  /**\n   * ### .isNull(value, [message])\n   *\n   * Asserts that `value` is null.\n   *\n   *     assert.isNull(err, 'there was no error');\n   *\n   * @name isNull\n   * @param {Mixed} value\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.isNull = function (val, msg) {\n    new Assertion(val, msg).to.equal(null);\n  };\n\n  /**\n   * ### .isNotNull(value, [message])\n   *\n   * Asserts that `value` is not null.\n   *\n   *     var tea = 'tasty chai';\n   *     assert.isNotNull(tea, 'great, time for tea!');\n   *\n   * @name isNotNull\n   * @param {Mixed} value\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.isNotNull = function (val, msg) {\n    new Assertion(val, msg).to.not.equal(null);\n  };\n\n  /**\n   * ### .isNaN\n   * Asserts that value is NaN\n   *\n   *    assert.isNaN('foo', 'foo is NaN');\n   *\n   * @name isNaN\n   * @param {Mixed} value\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.isNaN = function (val, msg) {\n    new Assertion(val, msg).to.be.NaN;\n  };\n\n  /**\n   * ### .isNotNaN\n   * Asserts that value is not NaN\n   *\n   *    assert.isNotNaN(4, '4 is not NaN');\n   *\n   * @name isNotNaN\n   * @param {Mixed} value\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n  assert.isNotNaN = function (val, msg) {\n    new Assertion(val, msg).not.to.be.NaN;\n  };\n\n  /**\n   * ### .isUndefined(value, [message])\n   *\n   * Asserts that `value` is `undefined`.\n   *\n   *     var tea;\n   *     assert.isUndefined(tea, 'no tea defined');\n   *\n   * @name isUndefined\n   * @param {Mixed} value\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.isUndefined = function (val, msg) {\n    new Assertion(val, msg).to.equal(undefined);\n  };\n\n  /**\n   * ### .isDefined(value, [message])\n   *\n   * Asserts that `value` is not `undefined`.\n   *\n   *     var tea = 'cup of chai';\n   *     assert.isDefined(tea, 'tea has been defined');\n   *\n   * @name isDefined\n   * @param {Mixed} value\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.isDefined = function (val, msg) {\n    new Assertion(val, msg).to.not.equal(undefined);\n  };\n\n  /**\n   * ### .isFunction(value, [message])\n   *\n   * Asserts that `value` is a function.\n   *\n   *     function serveTea() { return 'cup of tea'; };\n   *     assert.isFunction(serveTea, 'great, we can have tea now');\n   *\n   * @name isFunction\n   * @param {Mixed} value\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.isFunction = function (val, msg) {\n    new Assertion(val, msg).to.be.a('function');\n  };\n\n  /**\n   * ### .isNotFunction(value, [message])\n   *\n   * Asserts that `value` is _not_ a function.\n   *\n   *     var serveTea = [ 'heat', 'pour', 'sip' ];\n   *     assert.isNotFunction(serveTea, 'great, we have listed the steps');\n   *\n   * @name isNotFunction\n   * @param {Mixed} value\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.isNotFunction = function (val, msg) {\n    new Assertion(val, msg).to.not.be.a('function');\n  };\n\n  /**\n   * ### .isObject(value, [message])\n   *\n   * Asserts that `value` is an object of type 'Object' (as revealed by `Object.prototype.toString`).\n   * _The assertion does not match subclassed objects._\n   *\n   *     var selection = { name: 'Chai', serve: 'with spices' };\n   *     assert.isObject(selection, 'tea selection is an object');\n   *\n   * @name isObject\n   * @param {Mixed} value\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.isObject = function (val, msg) {\n    new Assertion(val, msg).to.be.a('object');\n  };\n\n  /**\n   * ### .isNotObject(value, [message])\n   *\n   * Asserts that `value` is _not_ an object of type 'Object' (as revealed by `Object.prototype.toString`).\n   *\n   *     var selection = 'chai'\n   *     assert.isNotObject(selection, 'tea selection is not an object');\n   *     assert.isNotObject(null, 'null is not an object');\n   *\n   * @name isNotObject\n   * @param {Mixed} value\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.isNotObject = function (val, msg) {\n    new Assertion(val, msg).to.not.be.a('object');\n  };\n\n  /**\n   * ### .isArray(value, [message])\n   *\n   * Asserts that `value` is an array.\n   *\n   *     var menu = [ 'green', 'chai', 'oolong' ];\n   *     assert.isArray(menu, 'what kind of tea do we want?');\n   *\n   * @name isArray\n   * @param {Mixed} value\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.isArray = function (val, msg) {\n    new Assertion(val, msg).to.be.an('array');\n  };\n\n  /**\n   * ### .isNotArray(value, [message])\n   *\n   * Asserts that `value` is _not_ an array.\n   *\n   *     var menu = 'green|chai|oolong';\n   *     assert.isNotArray(menu, 'what kind of tea do we want?');\n   *\n   * @name isNotArray\n   * @param {Mixed} value\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.isNotArray = function (val, msg) {\n    new Assertion(val, msg).to.not.be.an('array');\n  };\n\n  /**\n   * ### .isString(value, [message])\n   *\n   * Asserts that `value` is a string.\n   *\n   *     var teaOrder = 'chai';\n   *     assert.isString(teaOrder, 'order placed');\n   *\n   * @name isString\n   * @param {Mixed} value\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.isString = function (val, msg) {\n    new Assertion(val, msg).to.be.a('string');\n  };\n\n  /**\n   * ### .isNotString(value, [message])\n   *\n   * Asserts that `value` is _not_ a string.\n   *\n   *     var teaOrder = 4;\n   *     assert.isNotString(teaOrder, 'order placed');\n   *\n   * @name isNotString\n   * @param {Mixed} value\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.isNotString = function (val, msg) {\n    new Assertion(val, msg).to.not.be.a('string');\n  };\n\n  /**\n   * ### .isNumber(value, [message])\n   *\n   * Asserts that `value` is a number.\n   *\n   *     var cups = 2;\n   *     assert.isNumber(cups, 'how many cups');\n   *\n   * @name isNumber\n   * @param {Number} value\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.isNumber = function (val, msg) {\n    new Assertion(val, msg).to.be.a('number');\n  };\n\n  /**\n   * ### .isNotNumber(value, [message])\n   *\n   * Asserts that `value` is _not_ a number.\n   *\n   *     var cups = '2 cups please';\n   *     assert.isNotNumber(cups, 'how many cups');\n   *\n   * @name isNotNumber\n   * @param {Mixed} value\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.isNotNumber = function (val, msg) {\n    new Assertion(val, msg).to.not.be.a('number');\n  };\n\n  /**\n   * ### .isBoolean(value, [message])\n   *\n   * Asserts that `value` is a boolean.\n   *\n   *     var teaReady = true\n   *       , teaServed = false;\n   *\n   *     assert.isBoolean(teaReady, 'is the tea ready');\n   *     assert.isBoolean(teaServed, 'has tea been served');\n   *\n   * @name isBoolean\n   * @param {Mixed} value\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.isBoolean = function (val, msg) {\n    new Assertion(val, msg).to.be.a('boolean');\n  };\n\n  /**\n   * ### .isNotBoolean(value, [message])\n   *\n   * Asserts that `value` is _not_ a boolean.\n   *\n   *     var teaReady = 'yep'\n   *       , teaServed = 'nope';\n   *\n   *     assert.isNotBoolean(teaReady, 'is the tea ready');\n   *     assert.isNotBoolean(teaServed, 'has tea been served');\n   *\n   * @name isNotBoolean\n   * @param {Mixed} value\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.isNotBoolean = function (val, msg) {\n    new Assertion(val, msg).to.not.be.a('boolean');\n  };\n\n  /**\n   * ### .typeOf(value, name, [message])\n   *\n   * Asserts that `value`'s type is `name`, as determined by\n   * `Object.prototype.toString`.\n   *\n   *     assert.typeOf({ tea: 'chai' }, 'object', 'we have an object');\n   *     assert.typeOf(['chai', 'jasmine'], 'array', 'we have an array');\n   *     assert.typeOf('tea', 'string', 'we have a string');\n   *     assert.typeOf(/tea/, 'regexp', 'we have a regular expression');\n   *     assert.typeOf(null, 'null', 'we have a null');\n   *     assert.typeOf(undefined, 'undefined', 'we have an undefined');\n   *\n   * @name typeOf\n   * @param {Mixed} value\n   * @param {String} name\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.typeOf = function (val, type, msg) {\n    new Assertion(val, msg).to.be.a(type);\n  };\n\n  /**\n   * ### .notTypeOf(value, name, [message])\n   *\n   * Asserts that `value`'s type is _not_ `name`, as determined by\n   * `Object.prototype.toString`.\n   *\n   *     assert.notTypeOf('tea', 'number', 'strings are not numbers');\n   *\n   * @name notTypeOf\n   * @param {Mixed} value\n   * @param {String} typeof name\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.notTypeOf = function (val, type, msg) {\n    new Assertion(val, msg).to.not.be.a(type);\n  };\n\n  /**\n   * ### .instanceOf(object, constructor, [message])\n   *\n   * Asserts that `value` is an instance of `constructor`.\n   *\n   *     var Tea = function (name) { this.name = name; }\n   *       , chai = new Tea('chai');\n   *\n   *     assert.instanceOf(chai, Tea, 'chai is an instance of tea');\n   *\n   * @name instanceOf\n   * @param {Object} object\n   * @param {Constructor} constructor\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.instanceOf = function (val, type, msg) {\n    new Assertion(val, msg).to.be.instanceOf(type);\n  };\n\n  /**\n   * ### .notInstanceOf(object, constructor, [message])\n   *\n   * Asserts `value` is not an instance of `constructor`.\n   *\n   *     var Tea = function (name) { this.name = name; }\n   *       , chai = new String('chai');\n   *\n   *     assert.notInstanceOf(chai, Tea, 'chai is not an instance of tea');\n   *\n   * @name notInstanceOf\n   * @param {Object} object\n   * @param {Constructor} constructor\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.notInstanceOf = function (val, type, msg) {\n    new Assertion(val, msg).to.not.be.instanceOf(type);\n  };\n\n  /**\n   * ### .include(haystack, needle, [message])\n   *\n   * Asserts that `haystack` includes `needle`. Works\n   * for strings and arrays.\n   *\n   *     assert.include('foobar', 'bar', 'foobar contains string \"bar\"');\n   *     assert.include([ 1, 2, 3 ], 3, 'array contains value');\n   *\n   * @name include\n   * @param {Array|String} haystack\n   * @param {Mixed} needle\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.include = function (exp, inc, msg) {\n    new Assertion(exp, msg, assert.include).include(inc);\n  };\n\n  /**\n   * ### .notInclude(haystack, needle, [message])\n   *\n   * Asserts that `haystack` does not include `needle`. Works\n   * for strings and arrays.\n   *\n   *     assert.notInclude('foobar', 'baz', 'string not include substring');\n   *     assert.notInclude([ 1, 2, 3 ], 4, 'array not include contain value');\n   *\n   * @name notInclude\n   * @param {Array|String} haystack\n   * @param {Mixed} needle\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.notInclude = function (exp, inc, msg) {\n    new Assertion(exp, msg, assert.notInclude).not.include(inc);\n  };\n\n  /**\n   * ### .match(value, regexp, [message])\n   *\n   * Asserts that `value` matches the regular expression `regexp`.\n   *\n   *     assert.match('foobar', /^foo/, 'regexp matches');\n   *\n   * @name match\n   * @param {Mixed} value\n   * @param {RegExp} regexp\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.match = function (exp, re, msg) {\n    new Assertion(exp, msg).to.match(re);\n  };\n\n  /**\n   * ### .notMatch(value, regexp, [message])\n   *\n   * Asserts that `value` does not match the regular expression `regexp`.\n   *\n   *     assert.notMatch('foobar', /^foo/, 'regexp does not match');\n   *\n   * @name notMatch\n   * @param {Mixed} value\n   * @param {RegExp} regexp\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.notMatch = function (exp, re, msg) {\n    new Assertion(exp, msg).to.not.match(re);\n  };\n\n  /**\n   * ### .property(object, property, [message])\n   *\n   * Asserts that `object` has a property named by `property`.\n   *\n   *     assert.property({ tea: { green: 'matcha' }}, 'tea');\n   *\n   * @name property\n   * @param {Object} object\n   * @param {String} property\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.property = function (obj, prop, msg) {\n    new Assertion(obj, msg).to.have.property(prop);\n  };\n\n  /**\n   * ### .notProperty(object, property, [message])\n   *\n   * Asserts that `object` does _not_ have a property named by `property`.\n   *\n   *     assert.notProperty({ tea: { green: 'matcha' }}, 'coffee');\n   *\n   * @name notProperty\n   * @param {Object} object\n   * @param {String} property\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.notProperty = function (obj, prop, msg) {\n    new Assertion(obj, msg).to.not.have.property(prop);\n  };\n\n  /**\n   * ### .deepProperty(object, property, [message])\n   *\n   * Asserts that `object` has a property named by `property`, which can be a\n   * string using dot- and bracket-notation for deep reference.\n   *\n   *     assert.deepProperty({ tea: { green: 'matcha' }}, 'tea.green');\n   *\n   * @name deepProperty\n   * @param {Object} object\n   * @param {String} property\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.deepProperty = function (obj, prop, msg) {\n    new Assertion(obj, msg).to.have.deep.property(prop);\n  };\n\n  /**\n   * ### .notDeepProperty(object, property, [message])\n   *\n   * Asserts that `object` does _not_ have a property named by `property`, which\n   * can be a string using dot- and bracket-notation for deep reference.\n   *\n   *     assert.notDeepProperty({ tea: { green: 'matcha' }}, 'tea.oolong');\n   *\n   * @name notDeepProperty\n   * @param {Object} object\n   * @param {String} property\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.notDeepProperty = function (obj, prop, msg) {\n    new Assertion(obj, msg).to.not.have.deep.property(prop);\n  };\n\n  /**\n   * ### .propertyVal(object, property, value, [message])\n   *\n   * Asserts that `object` has a property named by `property` with value given\n   * by `value`.\n   *\n   *     assert.propertyVal({ tea: 'is good' }, 'tea', 'is good');\n   *\n   * @name propertyVal\n   * @param {Object} object\n   * @param {String} property\n   * @param {Mixed} value\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.propertyVal = function (obj, prop, val, msg) {\n    new Assertion(obj, msg).to.have.property(prop, val);\n  };\n\n  /**\n   * ### .propertyNotVal(object, property, value, [message])\n   *\n   * Asserts that `object` has a property named by `property`, but with a value\n   * different from that given by `value`.\n   *\n   *     assert.propertyNotVal({ tea: 'is good' }, 'tea', 'is bad');\n   *\n   * @name propertyNotVal\n   * @param {Object} object\n   * @param {String} property\n   * @param {Mixed} value\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.propertyNotVal = function (obj, prop, val, msg) {\n    new Assertion(obj, msg).to.not.have.property(prop, val);\n  };\n\n  /**\n   * ### .deepPropertyVal(object, property, value, [message])\n   *\n   * Asserts that `object` has a property named by `property` with value given\n   * by `value`. `property` can use dot- and bracket-notation for deep\n   * reference.\n   *\n   *     assert.deepPropertyVal({ tea: { green: 'matcha' }}, 'tea.green', 'matcha');\n   *\n   * @name deepPropertyVal\n   * @param {Object} object\n   * @param {String} property\n   * @param {Mixed} value\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.deepPropertyVal = function (obj, prop, val, msg) {\n    new Assertion(obj, msg).to.have.deep.property(prop, val);\n  };\n\n  /**\n   * ### .deepPropertyNotVal(object, property, value, [message])\n   *\n   * Asserts that `object` has a property named by `property`, but with a value\n   * different from that given by `value`. `property` can use dot- and\n   * bracket-notation for deep reference.\n   *\n   *     assert.deepPropertyNotVal({ tea: { green: 'matcha' }}, 'tea.green', 'konacha');\n   *\n   * @name deepPropertyNotVal\n   * @param {Object} object\n   * @param {String} property\n   * @param {Mixed} value\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.deepPropertyNotVal = function (obj, prop, val, msg) {\n    new Assertion(obj, msg).to.not.have.deep.property(prop, val);\n  };\n\n  /**\n   * ### .lengthOf(object, length, [message])\n   *\n   * Asserts that `object` has a `length` property with the expected value.\n   *\n   *     assert.lengthOf([1,2,3], 3, 'array has length of 3');\n   *     assert.lengthOf('foobar', 6, 'string has length of 6');\n   *\n   * @name lengthOf\n   * @param {Mixed} object\n   * @param {Number} length\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.lengthOf = function (exp, len, msg) {\n    new Assertion(exp, msg).to.have.length(len);\n  };\n\n  /**\n   * ### .throws(function, [constructor/string/regexp], [string/regexp], [message])\n   *\n   * Asserts that `function` will throw an error that is an instance of\n   * `constructor`, or alternately that it will throw an error with message\n   * matching `regexp`.\n   *\n   *     assert.throws(fn, 'function throws a reference error');\n   *     assert.throws(fn, /function throws a reference error/);\n   *     assert.throws(fn, ReferenceError);\n   *     assert.throws(fn, ReferenceError, 'function throws a reference error');\n   *     assert.throws(fn, ReferenceError, /function throws a reference error/);\n   *\n   * @name throws\n   * @alias throw\n   * @alias Throw\n   * @param {Function} function\n   * @param {ErrorConstructor} constructor\n   * @param {RegExp} regexp\n   * @param {String} message\n   * @see https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Error#Error_types\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.throws = function (fn, errt, errs, msg) {\n    if ('string' === typeof errt || errt instanceof RegExp) {\n      errs = errt;\n      errt = null;\n    }\n\n    var assertErr = new Assertion(fn, msg).to.throw(errt, errs);\n    return flag(assertErr, 'object');\n  };\n\n  /**\n   * ### .doesNotThrow(function, [constructor/regexp], [message])\n   *\n   * Asserts that `function` will _not_ throw an error that is an instance of\n   * `constructor`, or alternately that it will not throw an error with message\n   * matching `regexp`.\n   *\n   *     assert.doesNotThrow(fn, Error, 'function does not throw');\n   *\n   * @name doesNotThrow\n   * @param {Function} function\n   * @param {ErrorConstructor} constructor\n   * @param {RegExp} regexp\n   * @param {String} message\n   * @see https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Error#Error_types\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.doesNotThrow = function (fn, type, msg) {\n    if ('string' === typeof type) {\n      msg = type;\n      type = null;\n    }\n\n    new Assertion(fn, msg).to.not.Throw(type);\n  };\n\n  /**\n   * ### .operator(val1, operator, val2, [message])\n   *\n   * Compares two values using `operator`.\n   *\n   *     assert.operator(1, '<', 2, 'everything is ok');\n   *     assert.operator(1, '>', 2, 'this will fail');\n   *\n   * @name operator\n   * @param {Mixed} val1\n   * @param {String} operator\n   * @param {Mixed} val2\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.operator = function (val, operator, val2, msg) {\n    var ok;\n    switch(operator) {\n      case '==':\n        ok = val == val2;\n        break;\n      case '===':\n        ok = val === val2;\n        break;\n      case '>':\n        ok = val > val2;\n        break;\n      case '>=':\n        ok = val >= val2;\n        break;\n      case '<':\n        ok = val < val2;\n        break;\n      case '<=':\n        ok = val <= val2;\n        break;\n      case '!=':\n        ok = val != val2;\n        break;\n      case '!==':\n        ok = val !== val2;\n        break;\n      default:\n        throw new Error('Invalid operator \"' + operator + '\"');\n    }\n    var test = new Assertion(ok, msg);\n    test.assert(\n        true === flag(test, 'object')\n      , 'expected ' + util.inspect(val) + ' to be ' + operator + ' ' + util.inspect(val2)\n      , 'expected ' + util.inspect(val) + ' to not be ' + operator + ' ' + util.inspect(val2) );\n  };\n\n  /**\n   * ### .closeTo(actual, expected, delta, [message])\n   *\n   * Asserts that the target is equal `expected`, to within a +/- `delta` range.\n   *\n   *     assert.closeTo(1.5, 1, 0.5, 'numbers are close');\n   *\n   * @name closeTo\n   * @param {Number} actual\n   * @param {Number} expected\n   * @param {Number} delta\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.closeTo = function (act, exp, delta, msg) {\n    new Assertion(act, msg).to.be.closeTo(exp, delta);\n  };\n\n  /**\n   * ### .approximately(actual, expected, delta, [message])\n   *\n   * Asserts that the target is equal `expected`, to within a +/- `delta` range.\n   *\n   *     assert.approximately(1.5, 1, 0.5, 'numbers are close');\n   *\n   * @name approximately\n   * @param {Number} actual\n   * @param {Number} expected\n   * @param {Number} delta\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.approximately = function (act, exp, delta, msg) {\n    new Assertion(act, msg).to.be.approximately(exp, delta);\n  };\n\n  /**\n   * ### .sameMembers(set1, set2, [message])\n   *\n   * Asserts that `set1` and `set2` have the same members.\n   * Order is not taken into account.\n   *\n   *     assert.sameMembers([ 1, 2, 3 ], [ 2, 1, 3 ], 'same members');\n   *\n   * @name sameMembers\n   * @param {Array} set1\n   * @param {Array} set2\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.sameMembers = function (set1, set2, msg) {\n    new Assertion(set1, msg).to.have.same.members(set2);\n  }\n\n  /**\n   * ### .sameDeepMembers(set1, set2, [message])\n   *\n   * Asserts that `set1` and `set2` have the same members - using a deep equality checking.\n   * Order is not taken into account.\n   *\n   *     assert.sameDeepMembers([ {b: 3}, {a: 2}, {c: 5} ], [ {c: 5}, {b: 3}, {a: 2} ], 'same deep members');\n   *\n   * @name sameDeepMembers\n   * @param {Array} set1\n   * @param {Array} set2\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.sameDeepMembers = function (set1, set2, msg) {\n    new Assertion(set1, msg).to.have.same.deep.members(set2);\n  }\n\n  /**\n   * ### .includeMembers(superset, subset, [message])\n   *\n   * Asserts that `subset` is included in `superset`.\n   * Order is not taken into account.\n   *\n   *     assert.includeMembers([ 1, 2, 3 ], [ 2, 1 ], 'include members');\n   *\n   * @name includeMembers\n   * @param {Array} superset\n   * @param {Array} subset\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.includeMembers = function (superset, subset, msg) {\n    new Assertion(superset, msg).to.include.members(subset);\n  }\n\n  /**\n   * ### .includeDeepMembers(superset, subset, [message])\n   *\n   * Asserts that `subset` is included in `superset` - using deep equality checking.\n   * Order is not taken into account.\n   * Duplicates are ignored.\n   *\n   *     assert.includeDeepMembers([ {a: 1}, {b: 2}, {c: 3} ], [ {b: 2}, {a: 1}, {b: 2} ], 'include deep members');\n   *\n   * @name includeDeepMembers\n   * @param {Array} superset\n   * @param {Array} subset\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.includeDeepMembers = function (superset, subset, msg) {\n    new Assertion(superset, msg).to.include.deep.members(subset);\n  }\n\n  /**\n   * ### .oneOf(inList, list, [message])\n   *\n   * Asserts that non-object, non-array value `inList` appears in the flat array `list`.\n   *\n   *     assert.oneOf(1, [ 2, 1 ], 'Not found in list');\n   *\n   * @name oneOf\n   * @param {*} inList\n   * @param {Array<*>} list\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.oneOf = function (inList, list, msg) {\n    new Assertion(inList, msg).to.be.oneOf(list);\n  }\n\n   /**\n   * ### .changes(function, object, property)\n   *\n   * Asserts that a function changes the value of a property\n   *\n   *     var obj = { val: 10 };\n   *     var fn = function() { obj.val = 22 };\n   *     assert.changes(fn, obj, 'val');\n   *\n   * @name changes\n   * @param {Function} modifier function\n   * @param {Object} object\n   * @param {String} property name\n   * @param {String} message _optional_\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.changes = function (fn, obj, prop) {\n    new Assertion(fn).to.change(obj, prop);\n  }\n\n   /**\n   * ### .doesNotChange(function, object, property)\n   *\n   * Asserts that a function does not changes the value of a property\n   *\n   *     var obj = { val: 10 };\n   *     var fn = function() { console.log('foo'); };\n   *     assert.doesNotChange(fn, obj, 'val');\n   *\n   * @name doesNotChange\n   * @param {Function} modifier function\n   * @param {Object} object\n   * @param {String} property name\n   * @param {String} message _optional_\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.doesNotChange = function (fn, obj, prop) {\n    new Assertion(fn).to.not.change(obj, prop);\n  }\n\n   /**\n   * ### .increases(function, object, property)\n   *\n   * Asserts that a function increases an object property\n   *\n   *     var obj = { val: 10 };\n   *     var fn = function() { obj.val = 13 };\n   *     assert.increases(fn, obj, 'val');\n   *\n   * @name increases\n   * @param {Function} modifier function\n   * @param {Object} object\n   * @param {String} property name\n   * @param {String} message _optional_\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.increases = function (fn, obj, prop) {\n    new Assertion(fn).to.increase(obj, prop);\n  }\n\n   /**\n   * ### .doesNotIncrease(function, object, property)\n   *\n   * Asserts that a function does not increase object property\n   *\n   *     var obj = { val: 10 };\n   *     var fn = function() { obj.val = 8 };\n   *     assert.doesNotIncrease(fn, obj, 'val');\n   *\n   * @name doesNotIncrease\n   * @param {Function} modifier function\n   * @param {Object} object\n   * @param {String} property name\n   * @param {String} message _optional_\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.doesNotIncrease = function (fn, obj, prop) {\n    new Assertion(fn).to.not.increase(obj, prop);\n  }\n\n   /**\n   * ### .decreases(function, object, property)\n   *\n   * Asserts that a function decreases an object property\n   *\n   *     var obj = { val: 10 };\n   *     var fn = function() { obj.val = 5 };\n   *     assert.decreases(fn, obj, 'val');\n   *\n   * @name decreases\n   * @param {Function} modifier function\n   * @param {Object} object\n   * @param {String} property name\n   * @param {String} message _optional_\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.decreases = function (fn, obj, prop) {\n    new Assertion(fn).to.decrease(obj, prop);\n  }\n\n   /**\n   * ### .doesNotDecrease(function, object, property)\n   *\n   * Asserts that a function does not decreases an object property\n   *\n   *     var obj = { val: 10 };\n   *     var fn = function() { obj.val = 15 };\n   *     assert.doesNotDecrease(fn, obj, 'val');\n   *\n   * @name doesNotDecrease\n   * @param {Function} modifier function\n   * @param {Object} object\n   * @param {String} property name\n   * @param {String} message _optional_\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.doesNotDecrease = function (fn, obj, prop) {\n    new Assertion(fn).to.not.decrease(obj, prop);\n  }\n\n  /*!\n   * ### .ifError(object)\n   *\n   * Asserts if value is not a false value, and throws if it is a true value.\n   * This is added to allow for chai to be a drop-in replacement for Node's\n   * assert class.\n   *\n   *     var err = new Error('I am a custom error');\n   *     assert.ifError(err); // Rethrows err!\n   *\n   * @name ifError\n   * @param {Object} object\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.ifError = function (val) {\n    if (val) {\n      throw(val);\n    }\n  };\n\n  /**\n   * ### .isExtensible(object)\n   *\n   * Asserts that `object` is extensible (can have new properties added to it).\n   *\n   *     assert.isExtensible({});\n   *\n   * @name isExtensible\n   * @alias extensible\n   * @param {Object} object\n   * @param {String} message _optional_\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.isExtensible = function (obj, msg) {\n    new Assertion(obj, msg).to.be.extensible;\n  };\n\n  /**\n   * ### .isNotExtensible(object)\n   *\n   * Asserts that `object` is _not_ extensible.\n   *\n   *     var nonExtensibleObject = Object.preventExtensions({});\n   *     var sealedObject = Object.seal({});\n   *     var frozenObject = Object.freese({});\n   *\n   *     assert.isNotExtensible(nonExtensibleObject);\n   *     assert.isNotExtensible(sealedObject);\n   *     assert.isNotExtensible(frozenObject);\n   *\n   * @name isNotExtensible\n   * @alias notExtensible\n   * @param {Object} object\n   * @param {String} message _optional_\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.isNotExtensible = function (obj, msg) {\n    new Assertion(obj, msg).to.not.be.extensible;\n  };\n\n  /**\n   * ### .isSealed(object)\n   *\n   * Asserts that `object` is sealed (cannot have new properties added to it\n   * and its existing properties cannot be removed).\n   *\n   *     var sealedObject = Object.seal({});\n   *     var frozenObject = Object.seal({});\n   *\n   *     assert.isSealed(sealedObject);\n   *     assert.isSealed(frozenObject);\n   *\n   * @name isSealed\n   * @alias sealed\n   * @param {Object} object\n   * @param {String} message _optional_\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.isSealed = function (obj, msg) {\n    new Assertion(obj, msg).to.be.sealed;\n  };\n\n  /**\n   * ### .isNotSealed(object)\n   *\n   * Asserts that `object` is _not_ sealed.\n   *\n   *     assert.isNotSealed({});\n   *\n   * @name isNotSealed\n   * @alias notSealed\n   * @param {Object} object\n   * @param {String} message _optional_\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.isNotSealed = function (obj, msg) {\n    new Assertion(obj, msg).to.not.be.sealed;\n  };\n\n  /**\n   * ### .isFrozen(object)\n   *\n   * Asserts that `object` is frozen (cannot have new properties added to it\n   * and its existing properties cannot be modified).\n   *\n   *     var frozenObject = Object.freeze({});\n   *     assert.frozen(frozenObject);\n   *\n   * @name isFrozen\n   * @alias frozen\n   * @param {Object} object\n   * @param {String} message _optional_\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.isFrozen = function (obj, msg) {\n    new Assertion(obj, msg).to.be.frozen;\n  };\n\n  /**\n   * ### .isNotFrozen(object)\n   *\n   * Asserts that `object` is _not_ frozen.\n   *\n   *     assert.isNotFrozen({});\n   *\n   * @name isNotFrozen\n   * @alias notFrozen\n   * @param {Object} object\n   * @param {String} message _optional_\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.isNotFrozen = function (obj, msg) {\n    new Assertion(obj, msg).to.not.be.frozen;\n  };\n\n  /*!\n   * Aliases.\n   */\n\n  (function alias(name, as){\n    assert[as] = assert[name];\n    return alias;\n  })\n  ('isOk', 'ok')\n  ('isNotOk', 'notOk')\n  ('throws', 'throw')\n  ('throws', 'Throw')\n  ('isExtensible', 'extensible')\n  ('isNotExtensible', 'notExtensible')\n  ('isSealed', 'sealed')\n  ('isNotSealed', 'notSealed')\n  ('isFrozen', 'frozen')\n  ('isNotFrozen', 'notFrozen');\n};\n\n},{}],7:[function(require,module,exports){\n/*!\n * chai\n * Copyright(c) 2011-2014 Jake Luer <jake@alogicalparadox.com>\n * MIT Licensed\n */\n\nmodule.exports = function (chai, util) {\n  chai.expect = function (val, message) {\n    return new chai.Assertion(val, message);\n  };\n\n  /**\n   * ### .fail(actual, expected, [message], [operator])\n   *\n   * Throw a failure.\n   *\n   * @name fail\n   * @param {Mixed} actual\n   * @param {Mixed} expected\n   * @param {String} message\n   * @param {String} operator\n   * @namespace Expect\n   * @api public\n   */\n\n  chai.expect.fail = function (actual, expected, message, operator) {\n    message = message || 'expect.fail()';\n    throw new chai.AssertionError(message, {\n        actual: actual\n      , expected: expected\n      , operator: operator\n    }, chai.expect.fail);\n  };\n};\n\n},{}],8:[function(require,module,exports){\n/*!\n * chai\n * Copyright(c) 2011-2014 Jake Luer <jake@alogicalparadox.com>\n * MIT Licensed\n */\n\nmodule.exports = function (chai, util) {\n  var Assertion = chai.Assertion;\n\n  function loadShould () {\n    // explicitly define this method as function as to have it's name to include as `ssfi`\n    function shouldGetter() {\n      if (this instanceof String || this instanceof Number || this instanceof Boolean ) {\n        return new Assertion(this.valueOf(), null, shouldGetter);\n      }\n      return new Assertion(this, null, shouldGetter);\n    }\n    function shouldSetter(value) {\n      // See https://github.com/chaijs/chai/issues/86: this makes\n      // `whatever.should = someValue` actually set `someValue`, which is\n      // especially useful for `global.should = require('chai').should()`.\n      //\n      // Note that we have to use [[DefineProperty]] instead of [[Put]]\n      // since otherwise we would trigger this very setter!\n      Object.defineProperty(this, 'should', {\n        value: value,\n        enumerable: true,\n        configurable: true,\n        writable: true\n      });\n    }\n    // modify Object.prototype to have `should`\n    Object.defineProperty(Object.prototype, 'should', {\n      set: shouldSetter\n      , get: shouldGetter\n      , configurable: true\n    });\n\n    var should = {};\n\n    /**\n     * ### .fail(actual, expected, [message], [operator])\n     *\n     * Throw a failure.\n     *\n     * @name fail\n     * @param {Mixed} actual\n     * @param {Mixed} expected\n     * @param {String} message\n     * @param {String} operator\n     * @namespace Should\n     * @api public\n     */\n\n    should.fail = function (actual, expected, message, operator) {\n      message = message || 'should.fail()';\n      throw new chai.AssertionError(message, {\n          actual: actual\n        , expected: expected\n        , operator: operator\n      }, should.fail);\n    };\n\n    /**\n     * ### .equal(actual, expected, [message])\n     *\n     * Asserts non-strict equality (`==`) of `actual` and `expected`.\n     *\n     *     should.equal(3, '3', '== coerces values to strings');\n     *\n     * @name equal\n     * @param {Mixed} actual\n     * @param {Mixed} expected\n     * @param {String} message\n     * @namespace Should\n     * @api public\n     */\n\n    should.equal = function (val1, val2, msg) {\n      new Assertion(val1, msg).to.equal(val2);\n    };\n\n    /**\n     * ### .throw(function, [constructor/string/regexp], [string/regexp], [message])\n     *\n     * Asserts that `function` will throw an error that is an instance of\n     * `constructor`, or alternately that it will throw an error with message\n     * matching `regexp`.\n     *\n     *     should.throw(fn, 'function throws a reference error');\n     *     should.throw(fn, /function throws a reference error/);\n     *     should.throw(fn, ReferenceError);\n     *     should.throw(fn, ReferenceError, 'function throws a reference error');\n     *     should.throw(fn, ReferenceError, /function throws a reference error/);\n     *\n     * @name throw\n     * @alias Throw\n     * @param {Function} function\n     * @param {ErrorConstructor} constructor\n     * @param {RegExp} regexp\n     * @param {String} message\n     * @see https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Error#Error_types\n     * @namespace Should\n     * @api public\n     */\n\n    should.Throw = function (fn, errt, errs, msg) {\n      new Assertion(fn, msg).to.Throw(errt, errs);\n    };\n\n    /**\n     * ### .exist\n     *\n     * Asserts that the target is neither `null` nor `undefined`.\n     *\n     *     var foo = 'hi';\n     *\n     *     should.exist(foo, 'foo exists');\n     *\n     * @name exist\n     * @namespace Should\n     * @api public\n     */\n\n    should.exist = function (val, msg) {\n      new Assertion(val, msg).to.exist;\n    }\n\n    // negation\n    should.not = {}\n\n    /**\n     * ### .not.equal(actual, expected, [message])\n     *\n     * Asserts non-strict inequality (`!=`) of `actual` and `expected`.\n     *\n     *     should.not.equal(3, 4, 'these numbers are not equal');\n     *\n     * @name not.equal\n     * @param {Mixed} actual\n     * @param {Mixed} expected\n     * @param {String} message\n     * @namespace Should\n     * @api public\n     */\n\n    should.not.equal = function (val1, val2, msg) {\n      new Assertion(val1, msg).to.not.equal(val2);\n    };\n\n    /**\n     * ### .throw(function, [constructor/regexp], [message])\n     *\n     * Asserts that `function` will _not_ throw an error that is an instance of\n     * `constructor`, or alternately that it will not throw an error with message\n     * matching `regexp`.\n     *\n     *     should.not.throw(fn, Error, 'function does not throw');\n     *\n     * @name not.throw\n     * @alias not.Throw\n     * @param {Function} function\n     * @param {ErrorConstructor} constructor\n     * @param {RegExp} regexp\n     * @param {String} message\n     * @see https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Error#Error_types\n     * @namespace Should\n     * @api public\n     */\n\n    should.not.Throw = function (fn, errt, errs, msg) {\n      new Assertion(fn, msg).to.not.Throw(errt, errs);\n    };\n\n    /**\n     * ### .not.exist\n     *\n     * Asserts that the target is neither `null` nor `undefined`.\n     *\n     *     var bar = null;\n     *\n     *     should.not.exist(bar, 'bar does not exist');\n     *\n     * @name not.exist\n     * @namespace Should\n     * @api public\n     */\n\n    should.not.exist = function (val, msg) {\n      new Assertion(val, msg).to.not.exist;\n    }\n\n    should['throw'] = should['Throw'];\n    should.not['throw'] = should.not['Throw'];\n\n    return should;\n  };\n\n  chai.should = loadShould;\n  chai.Should = loadShould;\n};\n\n},{}],9:[function(require,module,exports){\n/*!\n * Chai - addChainingMethod utility\n * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com>\n * MIT Licensed\n */\n\n/*!\n * Module dependencies\n */\n\nvar transferFlags = require('./transferFlags');\nvar flag = require('./flag');\nvar config = require('../config');\n\n/*!\n * Module variables\n */\n\n// Check whether `__proto__` is supported\nvar hasProtoSupport = '__proto__' in Object;\n\n// Without `__proto__` support, this module will need to add properties to a function.\n// However, some Function.prototype methods cannot be overwritten,\n// and there seems no easy cross-platform way to detect them (@see chaijs/chai/issues/69).\nvar excludeNames = /^(?:length|name|arguments|caller)$/;\n\n// Cache `Function` properties\nvar call  = Function.prototype.call,\n    apply = Function.prototype.apply;\n\n/**\n * ### addChainableMethod (ctx, name, method, chainingBehavior)\n *\n * Adds a method to an object, such that the method can also be chained.\n *\n *     utils.addChainableMethod(chai.Assertion.prototype, 'foo', function (str) {\n *       var obj = utils.flag(this, 'object');\n *       new chai.Assertion(obj).to.be.equal(str);\n *     });\n *\n * Can also be accessed directly from `chai.Assertion`.\n *\n *     chai.Assertion.addChainableMethod('foo', fn, chainingBehavior);\n *\n * The result can then be used as both a method assertion, executing both `method` and\n * `chainingBehavior`, or as a language chain, which only executes `chainingBehavior`.\n *\n *     expect(fooStr).to.be.foo('bar');\n *     expect(fooStr).to.be.foo.equal('foo');\n *\n * @param {Object} ctx object to which the method is added\n * @param {String} name of method to add\n * @param {Function} method function to be used for `name`, when called\n * @param {Function} chainingBehavior function to be called every time the property is accessed\n * @namespace Utils\n * @name addChainableMethod\n * @api public\n */\n\nmodule.exports = function (ctx, name, method, chainingBehavior) {\n  if (typeof chainingBehavior !== 'function') {\n    chainingBehavior = function () { };\n  }\n\n  var chainableBehavior = {\n      method: method\n    , chainingBehavior: chainingBehavior\n  };\n\n  // save the methods so we can overwrite them later, if we need to.\n  if (!ctx.__methods) {\n    ctx.__methods = {};\n  }\n  ctx.__methods[name] = chainableBehavior;\n\n  Object.defineProperty(ctx, name,\n    { get: function () {\n        chainableBehavior.chainingBehavior.call(this);\n\n        var assert = function assert() {\n          var old_ssfi = flag(this, 'ssfi');\n          if (old_ssfi && config.includeStack === false)\n            flag(this, 'ssfi', assert);\n          var result = chainableBehavior.method.apply(this, arguments);\n          return result === undefined ? this : result;\n        };\n\n        // Use `__proto__` if available\n        if (hasProtoSupport) {\n          // Inherit all properties from the object by replacing the `Function` prototype\n          var prototype = assert.__proto__ = Object.create(this);\n          // Restore the `call` and `apply` methods from `Function`\n          prototype.call = call;\n          prototype.apply = apply;\n        }\n        // Otherwise, redefine all properties (slow!)\n        else {\n          var asserterNames = Object.getOwnPropertyNames(ctx);\n          asserterNames.forEach(function (asserterName) {\n            if (!excludeNames.test(asserterName)) {\n              var pd = Object.getOwnPropertyDescriptor(ctx, asserterName);\n              Object.defineProperty(assert, asserterName, pd);\n            }\n          });\n        }\n\n        transferFlags(this, assert);\n        return assert;\n      }\n    , configurable: true\n  });\n};\n\n},{\"../config\":4,\"./flag\":13,\"./transferFlags\":29}],10:[function(require,module,exports){\n/*!\n * Chai - addMethod utility\n * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com>\n * MIT Licensed\n */\n\nvar config = require('../config');\n\n/**\n * ### .addMethod (ctx, name, method)\n *\n * Adds a method to the prototype of an object.\n *\n *     utils.addMethod(chai.Assertion.prototype, 'foo', function (str) {\n *       var obj = utils.flag(this, 'object');\n *       new chai.Assertion(obj).to.be.equal(str);\n *     });\n *\n * Can also be accessed directly from `chai.Assertion`.\n *\n *     chai.Assertion.addMethod('foo', fn);\n *\n * Then can be used as any other assertion.\n *\n *     expect(fooStr).to.be.foo('bar');\n *\n * @param {Object} ctx object to which the method is added\n * @param {String} name of method to add\n * @param {Function} method function to be used for name\n * @namespace Utils\n * @name addMethod\n * @api public\n */\nvar flag = require('./flag');\n\nmodule.exports = function (ctx, name, method) {\n  ctx[name] = function () {\n    var old_ssfi = flag(this, 'ssfi');\n    if (old_ssfi && config.includeStack === false)\n      flag(this, 'ssfi', ctx[name]);\n    var result = method.apply(this, arguments);\n    return result === undefined ? this : result;\n  };\n};\n\n},{\"../config\":4,\"./flag\":13}],11:[function(require,module,exports){\n/*!\n * Chai - addProperty utility\n * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com>\n * MIT Licensed\n */\n\nvar config = require('../config');\nvar flag = require('./flag');\n\n/**\n * ### addProperty (ctx, name, getter)\n *\n * Adds a property to the prototype of an object.\n *\n *     utils.addProperty(chai.Assertion.prototype, 'foo', function () {\n *       var obj = utils.flag(this, 'object');\n *       new chai.Assertion(obj).to.be.instanceof(Foo);\n *     });\n *\n * Can also be accessed directly from `chai.Assertion`.\n *\n *     chai.Assertion.addProperty('foo', fn);\n *\n * Then can be used as any other assertion.\n *\n *     expect(myFoo).to.be.foo;\n *\n * @param {Object} ctx object to which the property is added\n * @param {String} name of property to add\n * @param {Function} getter function to be used for name\n * @namespace Utils\n * @name addProperty\n * @api public\n */\n\nmodule.exports = function (ctx, name, getter) {\n  Object.defineProperty(ctx, name,\n    { get: function addProperty() {\n        var old_ssfi = flag(this, 'ssfi');\n        if (old_ssfi && config.includeStack === false)\n          flag(this, 'ssfi', addProperty);\n\n        var result = getter.call(this);\n        return result === undefined ? this : result;\n      }\n    , configurable: true\n  });\n};\n\n},{\"../config\":4,\"./flag\":13}],12:[function(require,module,exports){\n/*!\n * Chai - expectTypes utility\n * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com>\n * MIT Licensed\n */\n\n/**\n * ### expectTypes(obj, types)\n *\n * Ensures that the object being tested against is of a valid type.\n *\n *     utils.expectTypes(this, ['array', 'object', 'string']);\n *\n * @param {Mixed} obj constructed Assertion\n * @param {Array} type A list of allowed types for this assertion\n * @namespace Utils\n * @name expectTypes\n * @api public\n */\n\nvar AssertionError = require('assertion-error');\nvar flag = require('./flag');\nvar type = require('type-detect');\n\nmodule.exports = function (obj, types) {\n  var obj = flag(obj, 'object');\n  types = types.map(function (t) { return t.toLowerCase(); });\n  types.sort();\n\n  // Transforms ['lorem', 'ipsum'] into 'a lirum, or an ipsum'\n  var str = types.map(function (t, index) {\n    var art = ~[ 'a', 'e', 'i', 'o', 'u' ].indexOf(t.charAt(0)) ? 'an' : 'a';\n    var or = types.length > 1 && index === types.length - 1 ? 'or ' : '';\n    return or + art + ' ' + t;\n  }).join(', ');\n\n  if (!types.some(function (expected) { return type(obj) === expected; })) {\n    throw new AssertionError(\n      'object tested must be ' + str + ', but ' + type(obj) + ' given'\n    );\n  }\n};\n\n},{\"./flag\":13,\"assertion-error\":30,\"type-detect\":35}],13:[function(require,module,exports){\n/*!\n * Chai - flag utility\n * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com>\n * MIT Licensed\n */\n\n/**\n * ### flag(object, key, [value])\n *\n * Get or set a flag value on an object. If a\n * value is provided it will be set, else it will\n * return the currently set value or `undefined` if\n * the value is not set.\n *\n *     utils.flag(this, 'foo', 'bar'); // setter\n *     utils.flag(this, 'foo'); // getter, returns `bar`\n *\n * @param {Object} object constructed Assertion\n * @param {String} key\n * @param {Mixed} value (optional)\n * @namespace Utils\n * @name flag\n * @api private\n */\n\nmodule.exports = function (obj, key, value) {\n  var flags = obj.__flags || (obj.__flags = Object.create(null));\n  if (arguments.length === 3) {\n    flags[key] = value;\n  } else {\n    return flags[key];\n  }\n};\n\n},{}],14:[function(require,module,exports){\n/*!\n * Chai - getActual utility\n * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com>\n * MIT Licensed\n */\n\n/**\n * # getActual(object, [actual])\n *\n * Returns the `actual` value for an Assertion\n *\n * @param {Object} object (constructed Assertion)\n * @param {Arguments} chai.Assertion.prototype.assert arguments\n * @namespace Utils\n * @name getActual\n */\n\nmodule.exports = function (obj, args) {\n  return args.length > 4 ? args[4] : obj._obj;\n};\n\n},{}],15:[function(require,module,exports){\n/*!\n * Chai - getEnumerableProperties utility\n * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com>\n * MIT Licensed\n */\n\n/**\n * ### .getEnumerableProperties(object)\n *\n * This allows the retrieval of enumerable property names of an object,\n * inherited or not.\n *\n * @param {Object} object\n * @returns {Array}\n * @namespace Utils\n * @name getEnumerableProperties\n * @api public\n */\n\nmodule.exports = function getEnumerableProperties(object) {\n  var result = [];\n  for (var name in object) {\n    result.push(name);\n  }\n  return result;\n};\n\n},{}],16:[function(require,module,exports){\n/*!\n * Chai - message composition utility\n * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com>\n * MIT Licensed\n */\n\n/*!\n * Module dependancies\n */\n\nvar flag = require('./flag')\n  , getActual = require('./getActual')\n  , inspect = require('./inspect')\n  , objDisplay = require('./objDisplay');\n\n/**\n * ### .getMessage(object, message, negateMessage)\n *\n * Construct the error message based on flags\n * and template tags. Template tags will return\n * a stringified inspection of the object referenced.\n *\n * Message template tags:\n * - `#{this}` current asserted object\n * - `#{act}` actual value\n * - `#{exp}` expected value\n *\n * @param {Object} object (constructed Assertion)\n * @param {Arguments} chai.Assertion.prototype.assert arguments\n * @namespace Utils\n * @name getMessage\n * @api public\n */\n\nmodule.exports = function (obj, args) {\n  var negate = flag(obj, 'negate')\n    , val = flag(obj, 'object')\n    , expected = args[3]\n    , actual = getActual(obj, args)\n    , msg = negate ? args[2] : args[1]\n    , flagMsg = flag(obj, 'message');\n\n  if(typeof msg === \"function\") msg = msg();\n  msg = msg || '';\n  msg = msg\n    .replace(/#\\{this\\}/g, function () { return objDisplay(val); })\n    .replace(/#\\{act\\}/g, function () { return objDisplay(actual); })\n    .replace(/#\\{exp\\}/g, function () { return objDisplay(expected); });\n\n  return flagMsg ? flagMsg + ': ' + msg : msg;\n};\n\n},{\"./flag\":13,\"./getActual\":14,\"./inspect\":23,\"./objDisplay\":24}],17:[function(require,module,exports){\n/*!\n * Chai - getName utility\n * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com>\n * MIT Licensed\n */\n\n/**\n * # getName(func)\n *\n * Gets the name of a function, in a cross-browser way.\n *\n * @param {Function} a function (usually a constructor)\n * @namespace Utils\n * @name getName\n */\n\nmodule.exports = function (func) {\n  if (func.name) return func.name;\n\n  var match = /^\\s?function ([^(]*)\\(/.exec(func);\n  return match && match[1] ? match[1] : \"\";\n};\n\n},{}],18:[function(require,module,exports){\n/*!\n * Chai - getPathInfo utility\n * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com>\n * MIT Licensed\n */\n\nvar hasProperty = require('./hasProperty');\n\n/**\n * ### .getPathInfo(path, object)\n *\n * This allows the retrieval of property info in an\n * object given a string path.\n *\n * The path info consists of an object with the\n * following properties:\n *\n * * parent - The parent object of the property referenced by `path`\n * * name - The name of the final property, a number if it was an array indexer\n * * value - The value of the property, if it exists, otherwise `undefined`\n * * exists - Whether the property exists or not\n *\n * @param {String} path\n * @param {Object} object\n * @returns {Object} info\n * @namespace Utils\n * @name getPathInfo\n * @api public\n */\n\nmodule.exports = function getPathInfo(path, obj) {\n  var parsed = parsePath(path),\n      last = parsed[parsed.length - 1];\n\n  var info = {\n    parent: parsed.length > 1 ? _getPathValue(parsed, obj, parsed.length - 1) : obj,\n    name: last.p || last.i,\n    value: _getPathValue(parsed, obj)\n  };\n  info.exists = hasProperty(info.name, info.parent);\n\n  return info;\n};\n\n\n/*!\n * ## parsePath(path)\n *\n * Helper function used to parse string object\n * paths. Use in conjunction with `_getPathValue`.\n *\n *      var parsed = parsePath('myobject.property.subprop');\n *\n * ### Paths:\n *\n * * Can be as near infinitely deep and nested\n * * Arrays are also valid using the formal `myobject.document[3].property`.\n * * Literal dots and brackets (not delimiter) must be backslash-escaped.\n *\n * @param {String} path\n * @returns {Object} parsed\n * @api private\n */\n\nfunction parsePath (path) {\n  var str = path.replace(/([^\\\\])\\[/g, '$1.[')\n    , parts = str.match(/(\\\\\\.|[^.]+?)+/g);\n  return parts.map(function (value) {\n    var re = /^\\[(\\d+)\\]$/\n      , mArr = re.exec(value);\n    if (mArr) return { i: parseFloat(mArr[1]) };\n    else return { p: value.replace(/\\\\([.\\[\\]])/g, '$1') };\n  });\n}\n\n\n/*!\n * ## _getPathValue(parsed, obj)\n *\n * Helper companion function for `.parsePath` that returns\n * the value located at the parsed address.\n *\n *      var value = getPathValue(parsed, obj);\n *\n * @param {Object} parsed definition from `parsePath`.\n * @param {Object} object to search against\n * @param {Number} object to search against\n * @returns {Object|Undefined} value\n * @api private\n */\n\nfunction _getPathValue (parsed, obj, index) {\n  var tmp = obj\n    , res;\n\n  index = (index === undefined ? parsed.length : index);\n\n  for (var i = 0, l = index; i < l; i++) {\n    var part = parsed[i];\n    if (tmp) {\n      if ('undefined' !== typeof part.p)\n        tmp = tmp[part.p];\n      else if ('undefined' !== typeof part.i)\n        tmp = tmp[part.i];\n      if (i == (l - 1)) res = tmp;\n    } else {\n      res = undefined;\n    }\n  }\n  return res;\n}\n\n},{\"./hasProperty\":21}],19:[function(require,module,exports){\n/*!\n * Chai - getPathValue utility\n * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com>\n * @see https://github.com/logicalparadox/filtr\n * MIT Licensed\n */\n\nvar getPathInfo = require('./getPathInfo');\n\n/**\n * ### .getPathValue(path, object)\n *\n * This allows the retrieval of values in an\n * object given a string path.\n *\n *     var obj = {\n *         prop1: {\n *             arr: ['a', 'b', 'c']\n *           , str: 'Hello'\n *         }\n *       , prop2: {\n *             arr: [ { nested: 'Universe' } ]\n *           , str: 'Hello again!'\n *         }\n *     }\n *\n * The following would be the results.\n *\n *     getPathValue('prop1.str', obj); // Hello\n *     getPathValue('prop1.att[2]', obj); // b\n *     getPathValue('prop2.arr[0].nested', obj); // Universe\n *\n * @param {String} path\n * @param {Object} object\n * @returns {Object} value or `undefined`\n * @namespace Utils\n * @name getPathValue\n * @api public\n */\nmodule.exports = function(path, obj) {\n  var info = getPathInfo(path, obj);\n  return info.value;\n};\n\n},{\"./getPathInfo\":18}],20:[function(require,module,exports){\n/*!\n * Chai - getProperties utility\n * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com>\n * MIT Licensed\n */\n\n/**\n * ### .getProperties(object)\n *\n * This allows the retrieval of property names of an object, enumerable or not,\n * inherited or not.\n *\n * @param {Object} object\n * @returns {Array}\n * @namespace Utils\n * @name getProperties\n * @api public\n */\n\nmodule.exports = function getProperties(object) {\n  var result = Object.getOwnPropertyNames(object);\n\n  function addProperty(property) {\n    if (result.indexOf(property) === -1) {\n      result.push(property);\n    }\n  }\n\n  var proto = Object.getPrototypeOf(object);\n  while (proto !== null) {\n    Object.getOwnPropertyNames(proto).forEach(addProperty);\n    proto = Object.getPrototypeOf(proto);\n  }\n\n  return result;\n};\n\n},{}],21:[function(require,module,exports){\n/*!\n * Chai - hasProperty utility\n * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com>\n * MIT Licensed\n */\n\nvar type = require('type-detect');\n\n/**\n * ### .hasProperty(object, name)\n *\n * This allows checking whether an object has\n * named property or numeric array index.\n *\n * Basically does the same thing as the `in`\n * operator but works properly with natives\n * and null/undefined values.\n *\n *     var obj = {\n *         arr: ['a', 'b', 'c']\n *       , str: 'Hello'\n *     }\n *\n * The following would be the results.\n *\n *     hasProperty('str', obj);  // true\n *     hasProperty('constructor', obj);  // true\n *     hasProperty('bar', obj);  // false\n *\n *     hasProperty('length', obj.str); // true\n *     hasProperty(1, obj.str);  // true\n *     hasProperty(5, obj.str);  // false\n *\n *     hasProperty('length', obj.arr);  // true\n *     hasProperty(2, obj.arr);  // true\n *     hasProperty(3, obj.arr);  // false\n *\n * @param {Objuect} object\n * @param {String|Number} name\n * @returns {Boolean} whether it exists\n * @namespace Utils\n * @name getPathInfo\n * @api public\n */\n\nvar literals = {\n    'number': Number\n  , 'string': String\n};\n\nmodule.exports = function hasProperty(name, obj) {\n  var ot = type(obj);\n\n  // Bad Object, obviously no props at all\n  if(ot === 'null' || ot === 'undefined')\n    return false;\n\n  // The `in` operator does not work with certain literals\n  // box these before the check\n  if(literals[ot] && typeof obj !== 'object')\n    obj = new literals[ot](obj);\n\n  return name in obj;\n};\n\n},{\"type-detect\":35}],22:[function(require,module,exports){\n/*!\n * chai\n * Copyright(c) 2011 Jake Luer <jake@alogicalparadox.com>\n * MIT Licensed\n */\n\n/*!\n * Main exports\n */\n\nvar exports = module.exports = {};\n\n/*!\n * test utility\n */\n\nexports.test = require('./test');\n\n/*!\n * type utility\n */\n\nexports.type = require('type-detect');\n\n/*!\n * expectTypes utility\n */\nexports.expectTypes = require('./expectTypes');\n\n/*!\n * message utility\n */\n\nexports.getMessage = require('./getMessage');\n\n/*!\n * actual utility\n */\n\nexports.getActual = require('./getActual');\n\n/*!\n * Inspect util\n */\n\nexports.inspect = require('./inspect');\n\n/*!\n * Object Display util\n */\n\nexports.objDisplay = require('./objDisplay');\n\n/*!\n * Flag utility\n */\n\nexports.flag = require('./flag');\n\n/*!\n * Flag transferring utility\n */\n\nexports.transferFlags = require('./transferFlags');\n\n/*!\n * Deep equal utility\n */\n\nexports.eql = require('deep-eql');\n\n/*!\n * Deep path value\n */\n\nexports.getPathValue = require('./getPathValue');\n\n/*!\n * Deep path info\n */\n\nexports.getPathInfo = require('./getPathInfo');\n\n/*!\n * Check if a property exists\n */\n\nexports.hasProperty = require('./hasProperty');\n\n/*!\n * Function name\n */\n\nexports.getName = require('./getName');\n\n/*!\n * add Property\n */\n\nexports.addProperty = require('./addProperty');\n\n/*!\n * add Method\n */\n\nexports.addMethod = require('./addMethod');\n\n/*!\n * overwrite Property\n */\n\nexports.overwriteProperty = require('./overwriteProperty');\n\n/*!\n * overwrite Method\n */\n\nexports.overwriteMethod = require('./overwriteMethod');\n\n/*!\n * Add a chainable method\n */\n\nexports.addChainableMethod = require('./addChainableMethod');\n\n/*!\n * Overwrite chainable method\n */\n\nexports.overwriteChainableMethod = require('./overwriteChainableMethod');\n\n},{\"./addChainableMethod\":9,\"./addMethod\":10,\"./addProperty\":11,\"./expectTypes\":12,\"./flag\":13,\"./getActual\":14,\"./getMessage\":16,\"./getName\":17,\"./getPathInfo\":18,\"./getPathValue\":19,\"./hasProperty\":21,\"./inspect\":23,\"./objDisplay\":24,\"./overwriteChainableMethod\":25,\"./overwriteMethod\":26,\"./overwriteProperty\":27,\"./test\":28,\"./transferFlags\":29,\"deep-eql\":31,\"type-detect\":35}],23:[function(require,module,exports){\n// This is (almost) directly from Node.js utils\n// https://github.com/joyent/node/blob/f8c335d0caf47f16d31413f89aa28eda3878e3aa/lib/util.js\n\nvar getName = require('./getName');\nvar getProperties = require('./getProperties');\nvar getEnumerableProperties = require('./getEnumerableProperties');\n\nmodule.exports = inspect;\n\n/**\n * Echos the value of a value. Trys to print the value out\n * in the best way possible given the different types.\n *\n * @param {Object} obj The object to print out.\n * @param {Boolean} showHidden Flag that shows hidden (not enumerable)\n *    properties of objects.\n * @param {Number} depth Depth in which to descend in object. Default is 2.\n * @param {Boolean} colors Flag to turn on ANSI escape codes to color the\n *    output. Default is false (no coloring).\n * @namespace Utils\n * @name inspect\n */\nfunction inspect(obj, showHidden, depth, colors) {\n  var ctx = {\n    showHidden: showHidden,\n    seen: [],\n    stylize: function (str) { return str; }\n  };\n  return formatValue(ctx, obj, (typeof depth === 'undefined' ? 2 : depth));\n}\n\n// Returns true if object is a DOM element.\nvar isDOMElement = function (object) {\n  if (typeof HTMLElement === 'object') {\n    return object instanceof HTMLElement;\n  } else {\n    return object &&\n      typeof object === 'object' &&\n      object.nodeType === 1 &&\n      typeof object.nodeName === 'string';\n  }\n};\n\nfunction formatValue(ctx, value, recurseTimes) {\n  // Provide a hook for user-specified inspect functions.\n  // Check that value is an object with an inspect function on it\n  if (value && typeof value.inspect === 'function' &&\n      // Filter out the util module, it's inspect function is special\n      value.inspect !== exports.inspect &&\n      // Also filter out any prototype objects using the circular check.\n      !(value.constructor && value.constructor.prototype === value)) {\n    var ret = value.inspect(recurseTimes);\n    if (typeof ret !== 'string') {\n      ret = formatValue(ctx, ret, recurseTimes);\n    }\n    return ret;\n  }\n\n  // Primitive types cannot have properties\n  var primitive = formatPrimitive(ctx, value);\n  if (primitive) {\n    return primitive;\n  }\n\n  // If this is a DOM element, try to get the outer HTML.\n  if (isDOMElement(value)) {\n    if ('outerHTML' in value) {\n      return value.outerHTML;\n      // This value does not have an outerHTML attribute,\n      //   it could still be an XML element\n    } else {\n      // Attempt to serialize it\n      try {\n        if (document.xmlVersion) {\n          var xmlSerializer = new XMLSerializer();\n          return xmlSerializer.serializeToString(value);\n        } else {\n          // Firefox 11- do not support outerHTML\n          //   It does, however, support innerHTML\n          //   Use the following to render the element\n          var ns = \"http://www.w3.org/1999/xhtml\";\n          var container = document.createElementNS(ns, '_');\n\n          container.appendChild(value.cloneNode(false));\n          html = container.innerHTML\n            .replace('><', '>' + value.innerHTML + '<');\n          container.innerHTML = '';\n          return html;\n        }\n      } catch (err) {\n        // This could be a non-native DOM implementation,\n        //   continue with the normal flow:\n        //   printing the element as if it is an object.\n      }\n    }\n  }\n\n  // Look up the keys of the object.\n  var visibleKeys = getEnumerableProperties(value);\n  var keys = ctx.showHidden ? getProperties(value) : visibleKeys;\n\n  // Some type of object without properties can be shortcutted.\n  // In IE, errors have a single `stack` property, or if they are vanilla `Error`,\n  // a `stack` plus `description` property; ignore those for consistency.\n  if (keys.length === 0 || (isError(value) && (\n      (keys.length === 1 && keys[0] === 'stack') ||\n      (keys.length === 2 && keys[0] === 'description' && keys[1] === 'stack')\n     ))) {\n    if (typeof value === 'function') {\n      var name = getName(value);\n      var nameSuffix = name ? ': ' + name : '';\n      return ctx.stylize('[Function' + nameSuffix + ']', 'special');\n    }\n    if (isRegExp(value)) {\n      return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp');\n    }\n    if (isDate(value)) {\n      return ctx.stylize(Date.prototype.toUTCString.call(value), 'date');\n    }\n    if (isError(value)) {\n      return formatError(value);\n    }\n  }\n\n  var base = '', array = false, braces = ['{', '}'];\n\n  // Make Array say that they are Array\n  if (isArray(value)) {\n    array = true;\n    braces = ['[', ']'];\n  }\n\n  // Make functions say that they are functions\n  if (typeof value === 'function') {\n    var name = getName(value);\n    var nameSuffix = name ? ': ' + name : '';\n    base = ' [Function' + nameSuffix + ']';\n  }\n\n  // Make RegExps say that they are RegExps\n  if (isRegExp(value)) {\n    base = ' ' + RegExp.prototype.toString.call(value);\n  }\n\n  // Make dates with properties first say the date\n  if (isDate(value)) {\n    base = ' ' + Date.prototype.toUTCString.call(value);\n  }\n\n  // Make error with message first say the error\n  if (isError(value)) {\n    return formatError(value);\n  }\n\n  if (keys.length === 0 && (!array || value.length == 0)) {\n    return braces[0] + base + braces[1];\n  }\n\n  if (recurseTimes < 0) {\n    if (isRegExp(value)) {\n      return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp');\n    } else {\n      return ctx.stylize('[Object]', 'special');\n    }\n  }\n\n  ctx.seen.push(value);\n\n  var output;\n  if (array) {\n    output = formatArray(ctx, value, recurseTimes, visibleKeys, keys);\n  } else {\n    output = keys.map(function(key) {\n      return formatProperty(ctx, value, recurseTimes, visibleKeys, key, array);\n    });\n  }\n\n  ctx.seen.pop();\n\n  return reduceToSingleString(output, base, braces);\n}\n\n\nfunction formatPrimitive(ctx, value) {\n  switch (typeof value) {\n    case 'undefined':\n      return ctx.stylize('undefined', 'undefined');\n\n    case 'string':\n      var simple = '\\'' + JSON.stringify(value).replace(/^\"|\"$/g, '')\n                                               .replace(/'/g, \"\\\\'\")\n                                               .replace(/\\\\\"/g, '\"') + '\\'';\n      return ctx.stylize(simple, 'string');\n\n    case 'number':\n      if (value === 0 && (1/value) === -Infinity) {\n        return ctx.stylize('-0', 'number');\n      }\n      return ctx.stylize('' + value, 'number');\n\n    case 'boolean':\n      return ctx.stylize('' + value, 'boolean');\n  }\n  // For some reason typeof null is \"object\", so special case here.\n  if (value === null) {\n    return ctx.stylize('null', 'null');\n  }\n}\n\n\nfunction formatError(value) {\n  return '[' + Error.prototype.toString.call(value) + ']';\n}\n\n\nfunction formatArray(ctx, value, recurseTimes, visibleKeys, keys) {\n  var output = [];\n  for (var i = 0, l = value.length; i < l; ++i) {\n    if (Object.prototype.hasOwnProperty.call(value, String(i))) {\n      output.push(formatProperty(ctx, value, recurseTimes, visibleKeys,\n          String(i), true));\n    } else {\n      output.push('');\n    }\n  }\n  keys.forEach(function(key) {\n    if (!key.match(/^\\d+$/)) {\n      output.push(formatProperty(ctx, value, recurseTimes, visibleKeys,\n          key, true));\n    }\n  });\n  return output;\n}\n\n\nfunction formatProperty(ctx, value, recurseTimes, visibleKeys, key, array) {\n  var name, str;\n  if (value.__lookupGetter__) {\n    if (value.__lookupGetter__(key)) {\n      if (value.__lookupSetter__(key)) {\n        str = ctx.stylize('[Getter/Setter]', 'special');\n      } else {\n        str = ctx.stylize('[Getter]', 'special');\n      }\n    } else {\n      if (value.__lookupSetter__(key)) {\n        str = ctx.stylize('[Setter]', 'special');\n      }\n    }\n  }\n  if (visibleKeys.indexOf(key) < 0) {\n    name = '[' + key + ']';\n  }\n  if (!str) {\n    if (ctx.seen.indexOf(value[key]) < 0) {\n      if (recurseTimes === null) {\n        str = formatValue(ctx, value[key], null);\n      } else {\n        str = formatValue(ctx, value[key], recurseTimes - 1);\n      }\n      if (str.indexOf('\\n') > -1) {\n        if (array) {\n          str = str.split('\\n').map(function(line) {\n            return '  ' + line;\n          }).join('\\n').substr(2);\n        } else {\n          str = '\\n' + str.split('\\n').map(function(line) {\n            return '   ' + line;\n          }).join('\\n');\n        }\n      }\n    } else {\n      str = ctx.stylize('[Circular]', 'special');\n    }\n  }\n  if (typeof name === 'undefined') {\n    if (array && key.match(/^\\d+$/)) {\n      return str;\n    }\n    name = JSON.stringify('' + key);\n    if (name.match(/^\"([a-zA-Z_][a-zA-Z_0-9]*)\"$/)) {\n      name = name.substr(1, name.length - 2);\n      name = ctx.stylize(name, 'name');\n    } else {\n      name = name.replace(/'/g, \"\\\\'\")\n                 .replace(/\\\\\"/g, '\"')\n                 .replace(/(^\"|\"$)/g, \"'\");\n      name = ctx.stylize(name, 'string');\n    }\n  }\n\n  return name + ': ' + str;\n}\n\n\nfunction reduceToSingleString(output, base, braces) {\n  var numLinesEst = 0;\n  var length = output.reduce(function(prev, cur) {\n    numLinesEst++;\n    if (cur.indexOf('\\n') >= 0) numLinesEst++;\n    return prev + cur.length + 1;\n  }, 0);\n\n  if (length > 60) {\n    return braces[0] +\n           (base === '' ? '' : base + '\\n ') +\n           ' ' +\n           output.join(',\\n  ') +\n           ' ' +\n           braces[1];\n  }\n\n  return braces[0] + base + ' ' + output.join(', ') + ' ' + braces[1];\n}\n\nfunction isArray(ar) {\n  return Array.isArray(ar) ||\n         (typeof ar === 'object' && objectToString(ar) === '[object Array]');\n}\n\nfunction isRegExp(re) {\n  return typeof re === 'object' && objectToString(re) === '[object RegExp]';\n}\n\nfunction isDate(d) {\n  return typeof d === 'object' && objectToString(d) === '[object Date]';\n}\n\nfunction isError(e) {\n  return typeof e === 'object' && objectToString(e) === '[object Error]';\n}\n\nfunction objectToString(o) {\n  return Object.prototype.toString.call(o);\n}\n\n},{\"./getEnumerableProperties\":15,\"./getName\":17,\"./getProperties\":20}],24:[function(require,module,exports){\n/*!\n * Chai - flag utility\n * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com>\n * MIT Licensed\n */\n\n/*!\n * Module dependancies\n */\n\nvar inspect = require('./inspect');\nvar config = require('../config');\n\n/**\n * ### .objDisplay (object)\n *\n * Determines if an object or an array matches\n * criteria to be inspected in-line for error\n * messages or should be truncated.\n *\n * @param {Mixed} javascript object to inspect\n * @name objDisplay\n * @namespace Utils\n * @api public\n */\n\nmodule.exports = function (obj) {\n  var str = inspect(obj)\n    , type = Object.prototype.toString.call(obj);\n\n  if (config.truncateThreshold && str.length >= config.truncateThreshold) {\n    if (type === '[object Function]') {\n      return !obj.name || obj.name === ''\n        ? '[Function]'\n        : '[Function: ' + obj.name + ']';\n    } else if (type === '[object Array]') {\n      return '[ Array(' + obj.length + ') ]';\n    } else if (type === '[object Object]') {\n      var keys = Object.keys(obj)\n        , kstr = keys.length > 2\n          ? keys.splice(0, 2).join(', ') + ', ...'\n          : keys.join(', ');\n      return '{ Object (' + kstr + ') }';\n    } else {\n      return str;\n    }\n  } else {\n    return str;\n  }\n};\n\n},{\"../config\":4,\"./inspect\":23}],25:[function(require,module,exports){\n/*!\n * Chai - overwriteChainableMethod utility\n * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com>\n * MIT Licensed\n */\n\n/**\n * ### overwriteChainableMethod (ctx, name, method, chainingBehavior)\n *\n * Overwites an already existing chainable method\n * and provides access to the previous function or\n * property.  Must return functions to be used for\n * name.\n *\n *     utils.overwriteChainableMethod(chai.Assertion.prototype, 'length',\n *       function (_super) {\n *       }\n *     , function (_super) {\n *       }\n *     );\n *\n * Can also be accessed directly from `chai.Assertion`.\n *\n *     chai.Assertion.overwriteChainableMethod('foo', fn, fn);\n *\n * Then can be used as any other assertion.\n *\n *     expect(myFoo).to.have.length(3);\n *     expect(myFoo).to.have.length.above(3);\n *\n * @param {Object} ctx object whose method / property is to be overwritten\n * @param {String} name of method / property to overwrite\n * @param {Function} method function that returns a function to be used for name\n * @param {Function} chainingBehavior function that returns a function to be used for property\n * @namespace Utils\n * @name overwriteChainableMethod\n * @api public\n */\n\nmodule.exports = function (ctx, name, method, chainingBehavior) {\n  var chainableBehavior = ctx.__methods[name];\n\n  var _chainingBehavior = chainableBehavior.chainingBehavior;\n  chainableBehavior.chainingBehavior = function () {\n    var result = chainingBehavior(_chainingBehavior).call(this);\n    return result === undefined ? this : result;\n  };\n\n  var _method = chainableBehavior.method;\n  chainableBehavior.method = function () {\n    var result = method(_method).apply(this, arguments);\n    return result === undefined ? this : result;\n  };\n};\n\n},{}],26:[function(require,module,exports){\n/*!\n * Chai - overwriteMethod utility\n * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com>\n * MIT Licensed\n */\n\n/**\n * ### overwriteMethod (ctx, name, fn)\n *\n * Overwites an already existing method and provides\n * access to previous function. Must return function\n * to be used for name.\n *\n *     utils.overwriteMethod(chai.Assertion.prototype, 'equal', function (_super) {\n *       return function (str) {\n *         var obj = utils.flag(this, 'object');\n *         if (obj instanceof Foo) {\n *           new chai.Assertion(obj.value).to.equal(str);\n *         } else {\n *           _super.apply(this, arguments);\n *         }\n *       }\n *     });\n *\n * Can also be accessed directly from `chai.Assertion`.\n *\n *     chai.Assertion.overwriteMethod('foo', fn);\n *\n * Then can be used as any other assertion.\n *\n *     expect(myFoo).to.equal('bar');\n *\n * @param {Object} ctx object whose method is to be overwritten\n * @param {String} name of method to overwrite\n * @param {Function} method function that returns a function to be used for name\n * @namespace Utils\n * @name overwriteMethod\n * @api public\n */\n\nmodule.exports = function (ctx, name, method) {\n  var _method = ctx[name]\n    , _super = function () { return this; };\n\n  if (_method && 'function' === typeof _method)\n    _super = _method;\n\n  ctx[name] = function () {\n    var result = method(_super).apply(this, arguments);\n    return result === undefined ? this : result;\n  }\n};\n\n},{}],27:[function(require,module,exports){\n/*!\n * Chai - overwriteProperty utility\n * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com>\n * MIT Licensed\n */\n\n/**\n * ### overwriteProperty (ctx, name, fn)\n *\n * Overwites an already existing property getter and provides\n * access to previous value. Must return function to use as getter.\n *\n *     utils.overwriteProperty(chai.Assertion.prototype, 'ok', function (_super) {\n *       return function () {\n *         var obj = utils.flag(this, 'object');\n *         if (obj instanceof Foo) {\n *           new chai.Assertion(obj.name).to.equal('bar');\n *         } else {\n *           _super.call(this);\n *         }\n *       }\n *     });\n *\n *\n * Can also be accessed directly from `chai.Assertion`.\n *\n *     chai.Assertion.overwriteProperty('foo', fn);\n *\n * Then can be used as any other assertion.\n *\n *     expect(myFoo).to.be.ok;\n *\n * @param {Object} ctx object whose property is to be overwritten\n * @param {String} name of property to overwrite\n * @param {Function} getter function that returns a getter function to be used for name\n * @namespace Utils\n * @name overwriteProperty\n * @api public\n */\n\nmodule.exports = function (ctx, name, getter) {\n  var _get = Object.getOwnPropertyDescriptor(ctx, name)\n    , _super = function () {};\n\n  if (_get && 'function' === typeof _get.get)\n    _super = _get.get\n\n  Object.defineProperty(ctx, name,\n    { get: function () {\n        var result = getter(_super).call(this);\n        return result === undefined ? this : result;\n      }\n    , configurable: true\n  });\n};\n\n},{}],28:[function(require,module,exports){\n/*!\n * Chai - test utility\n * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com>\n * MIT Licensed\n */\n\n/*!\n * Module dependancies\n */\n\nvar flag = require('./flag');\n\n/**\n * # test(object, expression)\n *\n * Test and object for expression.\n *\n * @param {Object} object (constructed Assertion)\n * @param {Arguments} chai.Assertion.prototype.assert arguments\n * @namespace Utils\n * @name test\n */\n\nmodule.exports = function (obj, args) {\n  var negate = flag(obj, 'negate')\n    , expr = args[0];\n  return negate ? !expr : expr;\n};\n\n},{\"./flag\":13}],29:[function(require,module,exports){\n/*!\n * Chai - transferFlags utility\n * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com>\n * MIT Licensed\n */\n\n/**\n * ### transferFlags(assertion, object, includeAll = true)\n *\n * Transfer all the flags for `assertion` to `object`. If\n * `includeAll` is set to `false`, then the base Chai\n * assertion flags (namely `object`, `ssfi`, and `message`)\n * will not be transferred.\n *\n *\n *     var newAssertion = new Assertion();\n *     utils.transferFlags(assertion, newAssertion);\n *\n *     var anotherAsseriton = new Assertion(myObj);\n *     utils.transferFlags(assertion, anotherAssertion, false);\n *\n * @param {Assertion} assertion the assertion to transfer the flags from\n * @param {Object} object the object to transfer the flags to; usually a new assertion\n * @param {Boolean} includeAll\n * @namespace Utils\n * @name transferFlags\n * @api private\n */\n\nmodule.exports = function (assertion, object, includeAll) {\n  var flags = assertion.__flags || (assertion.__flags = Object.create(null));\n\n  if (!object.__flags) {\n    object.__flags = Object.create(null);\n  }\n\n  includeAll = arguments.length === 3 ? includeAll : true;\n\n  for (var flag in flags) {\n    if (includeAll ||\n        (flag !== 'object' && flag !== 'ssfi' && flag != 'message')) {\n      object.__flags[flag] = flags[flag];\n    }\n  }\n};\n\n},{}],30:[function(require,module,exports){\n/*!\n * assertion-error\n * Copyright(c) 2013 Jake Luer <jake@qualiancy.com>\n * MIT Licensed\n */\n\n/*!\n * Return a function that will copy properties from\n * one object to another excluding any originally\n * listed. Returned function will create a new `{}`.\n *\n * @param {String} excluded properties ...\n * @return {Function}\n */\n\nfunction exclude () {\n  var excludes = [].slice.call(arguments);\n\n  function excludeProps (res, obj) {\n    Object.keys(obj).forEach(function (key) {\n      if (!~excludes.indexOf(key)) res[key] = obj[key];\n    });\n  }\n\n  return function extendExclude () {\n    var args = [].slice.call(arguments)\n      , i = 0\n      , res = {};\n\n    for (; i < args.length; i++) {\n      excludeProps(res, args[i]);\n    }\n\n    return res;\n  };\n};\n\n/*!\n * Primary Exports\n */\n\nmodule.exports = AssertionError;\n\n/**\n * ### AssertionError\n *\n * An extension of the JavaScript `Error` constructor for\n * assertion and validation scenarios.\n *\n * @param {String} message\n * @param {Object} properties to include (optional)\n * @param {callee} start stack function (optional)\n */\n\nfunction AssertionError (message, _props, ssf) {\n  var extend = exclude('name', 'message', 'stack', 'constructor', 'toJSON')\n    , props = extend(_props || {});\n\n  // default values\n  this.message = message || 'Unspecified AssertionError';\n  this.showDiff = false;\n\n  // copy from properties\n  for (var key in props) {\n    this[key] = props[key];\n  }\n\n  // capture stack trace\n  ssf = ssf || arguments.callee;\n  if (ssf && Error.captureStackTrace) {\n    Error.captureStackTrace(this, ssf);\n  } else {\n    this.stack = new Error().stack;\n  }\n}\n\n/*!\n * Inherit from Error.prototype\n */\n\nAssertionError.prototype = Object.create(Error.prototype);\n\n/*!\n * Statically set name\n */\n\nAssertionError.prototype.name = 'AssertionError';\n\n/*!\n * Ensure correct constructor\n */\n\nAssertionError.prototype.constructor = AssertionError;\n\n/**\n * Allow errors to be converted to JSON for static transfer.\n *\n * @param {Boolean} include stack (default: `true`)\n * @return {Object} object that can be `JSON.stringify`\n */\n\nAssertionError.prototype.toJSON = function (stack) {\n  var extend = exclude('constructor', 'toJSON', 'stack')\n    , props = extend({ name: this.name }, this);\n\n  // include stack if exists and not turned off\n  if (false !== stack && this.stack) {\n    props.stack = this.stack;\n  }\n\n  return props;\n};\n\n},{}],31:[function(require,module,exports){\nmodule.exports = require('./lib/eql');\n\n},{\"./lib/eql\":32}],32:[function(require,module,exports){\n/*!\n * deep-eql\n * Copyright(c) 2013 Jake Luer <jake@alogicalparadox.com>\n * MIT Licensed\n */\n\n/*!\n * Module dependencies\n */\n\nvar type = require('type-detect');\n\n/*!\n * Buffer.isBuffer browser shim\n */\n\nvar Buffer;\ntry { Buffer = require('buffer').Buffer; }\ncatch(ex) {\n  Buffer = {};\n  Buffer.isBuffer = function() { return false; }\n}\n\n/*!\n * Primary Export\n */\n\nmodule.exports = deepEqual;\n\n/**\n * Assert super-strict (egal) equality between\n * two objects of any type.\n *\n * @param {Mixed} a\n * @param {Mixed} b\n * @param {Array} memoised (optional)\n * @return {Boolean} equal match\n */\n\nfunction deepEqual(a, b, m) {\n  if (sameValue(a, b)) {\n    return true;\n  } else if ('date' === type(a)) {\n    return dateEqual(a, b);\n  } else if ('regexp' === type(a)) {\n    return regexpEqual(a, b);\n  } else if (Buffer.isBuffer(a)) {\n    return bufferEqual(a, b);\n  } else if ('arguments' === type(a)) {\n    return argumentsEqual(a, b, m);\n  } else if (!typeEqual(a, b)) {\n    return false;\n  } else if (('object' !== type(a) && 'object' !== type(b))\n  && ('array' !== type(a) && 'array' !== type(b))) {\n    return sameValue(a, b);\n  } else {\n    return objectEqual(a, b, m);\n  }\n}\n\n/*!\n * Strict (egal) equality test. Ensures that NaN always\n * equals NaN and `-0` does not equal `+0`.\n *\n * @param {Mixed} a\n * @param {Mixed} b\n * @return {Boolean} equal match\n */\n\nfunction sameValue(a, b) {\n  if (a === b) return a !== 0 || 1 / a === 1 / b;\n  return a !== a && b !== b;\n}\n\n/*!\n * Compare the types of two given objects and\n * return if they are equal. Note that an Array\n * has a type of `array` (not `object`) and arguments\n * have a type of `arguments` (not `array`/`object`).\n *\n * @param {Mixed} a\n * @param {Mixed} b\n * @return {Boolean} result\n */\n\nfunction typeEqual(a, b) {\n  return type(a) === type(b);\n}\n\n/*!\n * Compare two Date objects by asserting that\n * the time values are equal using `saveValue`.\n *\n * @param {Date} a\n * @param {Date} b\n * @return {Boolean} result\n */\n\nfunction dateEqual(a, b) {\n  if ('date' !== type(b)) return false;\n  return sameValue(a.getTime(), b.getTime());\n}\n\n/*!\n * Compare two regular expressions by converting them\n * to string and checking for `sameValue`.\n *\n * @param {RegExp} a\n * @param {RegExp} b\n * @return {Boolean} result\n */\n\nfunction regexpEqual(a, b) {\n  if ('regexp' !== type(b)) return false;\n  return sameValue(a.toString(), b.toString());\n}\n\n/*!\n * Assert deep equality of two `arguments` objects.\n * Unfortunately, these must be sliced to arrays\n * prior to test to ensure no bad behavior.\n *\n * @param {Arguments} a\n * @param {Arguments} b\n * @param {Array} memoize (optional)\n * @return {Boolean} result\n */\n\nfunction argumentsEqual(a, b, m) {\n  if ('arguments' !== type(b)) return false;\n  a = [].slice.call(a);\n  b = [].slice.call(b);\n  return deepEqual(a, b, m);\n}\n\n/*!\n * Get enumerable properties of a given object.\n *\n * @param {Object} a\n * @return {Array} property names\n */\n\nfunction enumerable(a) {\n  var res = [];\n  for (var key in a) res.push(key);\n  return res;\n}\n\n/*!\n * Simple equality for flat iterable objects\n * such as Arrays or Node.js buffers.\n *\n * @param {Iterable} a\n * @param {Iterable} b\n * @return {Boolean} result\n */\n\nfunction iterableEqual(a, b) {\n  if (a.length !==  b.length) return false;\n\n  var i = 0;\n  var match = true;\n\n  for (; i < a.length; i++) {\n    if (a[i] !== b[i]) {\n      match = false;\n      break;\n    }\n  }\n\n  return match;\n}\n\n/*!\n * Extension to `iterableEqual` specifically\n * for Node.js Buffers.\n *\n * @param {Buffer} a\n * @param {Mixed} b\n * @return {Boolean} result\n */\n\nfunction bufferEqual(a, b) {\n  if (!Buffer.isBuffer(b)) return false;\n  return iterableEqual(a, b);\n}\n\n/*!\n * Block for `objectEqual` ensuring non-existing\n * values don't get in.\n *\n * @param {Mixed} object\n * @return {Boolean} result\n */\n\nfunction isValue(a) {\n  return a !== null && a !== undefined;\n}\n\n/*!\n * Recursively check the equality of two objects.\n * Once basic sameness has been established it will\n * defer to `deepEqual` for each enumerable key\n * in the object.\n *\n * @param {Mixed} a\n * @param {Mixed} b\n * @return {Boolean} result\n */\n\nfunction objectEqual(a, b, m) {\n  if (!isValue(a) || !isValue(b)) {\n    return false;\n  }\n\n  if (a.prototype !== b.prototype) {\n    return false;\n  }\n\n  var i;\n  if (m) {\n    for (i = 0; i < m.length; i++) {\n      if ((m[i][0] === a && m[i][1] === b)\n      ||  (m[i][0] === b && m[i][1] === a)) {\n        return true;\n      }\n    }\n  } else {\n    m = [];\n  }\n\n  try {\n    var ka = enumerable(a);\n    var kb = enumerable(b);\n  } catch (ex) {\n    return false;\n  }\n\n  ka.sort();\n  kb.sort();\n\n  if (!iterableEqual(ka, kb)) {\n    return false;\n  }\n\n  m.push([ a, b ]);\n\n  var key;\n  for (i = ka.length - 1; i >= 0; i--) {\n    key = ka[i];\n    if (!deepEqual(a[key], b[key], m)) {\n      return false;\n    }\n  }\n\n  return true;\n}\n\n},{\"buffer\":undefined,\"type-detect\":33}],33:[function(require,module,exports){\nmodule.exports = require('./lib/type');\n\n},{\"./lib/type\":34}],34:[function(require,module,exports){\n/*!\n * type-detect\n * Copyright(c) 2013 jake luer <jake@alogicalparadox.com>\n * MIT Licensed\n */\n\n/*!\n * Primary Exports\n */\n\nvar exports = module.exports = getType;\n\n/*!\n * Detectable javascript natives\n */\n\nvar natives = {\n    '[object Array]': 'array'\n  , '[object RegExp]': 'regexp'\n  , '[object Function]': 'function'\n  , '[object Arguments]': 'arguments'\n  , '[object Date]': 'date'\n};\n\n/**\n * ### typeOf (obj)\n *\n * Use several different techniques to determine\n * the type of object being tested.\n *\n *\n * @param {Mixed} object\n * @return {String} object type\n * @api public\n */\n\nfunction getType (obj) {\n  var str = Object.prototype.toString.call(obj);\n  if (natives[str]) return natives[str];\n  if (obj === null) return 'null';\n  if (obj === undefined) return 'undefined';\n  if (obj === Object(obj)) return 'object';\n  return typeof obj;\n}\n\nexports.Library = Library;\n\n/**\n * ### Library\n *\n * Create a repository for custom type detection.\n *\n * ```js\n * var lib = new type.Library;\n * ```\n *\n */\n\nfunction Library () {\n  this.tests = {};\n}\n\n/**\n * #### .of (obj)\n *\n * Expose replacement `typeof` detection to the library.\n *\n * ```js\n * if ('string' === lib.of('hello world')) {\n *   // ...\n * }\n * ```\n *\n * @param {Mixed} object to test\n * @return {String} type\n */\n\nLibrary.prototype.of = getType;\n\n/**\n * #### .define (type, test)\n *\n * Add a test to for the `.test()` assertion.\n *\n * Can be defined as a regular expression:\n *\n * ```js\n * lib.define('int', /^[0-9]+$/);\n * ```\n *\n * ... or as a function:\n *\n * ```js\n * lib.define('bln', function (obj) {\n *   if ('boolean' === lib.of(obj)) return true;\n *   var blns = [ 'yes', 'no', 'true', 'false', 1, 0 ];\n *   if ('string' === lib.of(obj)) obj = obj.toLowerCase();\n *   return !! ~blns.indexOf(obj);\n * });\n * ```\n *\n * @param {String} type\n * @param {RegExp|Function} test\n * @api public\n */\n\nLibrary.prototype.define = function (type, test) {\n  if (arguments.length === 1) return this.tests[type];\n  this.tests[type] = test;\n  return this;\n};\n\n/**\n * #### .test (obj, test)\n *\n * Assert that an object is of type. Will first\n * check natives, and if that does not pass it will\n * use the user defined custom tests.\n *\n * ```js\n * assert(lib.test('1', 'int'));\n * assert(lib.test('yes', 'bln'));\n * ```\n *\n * @param {Mixed} object\n * @param {String} type\n * @return {Boolean} result\n * @api public\n */\n\nLibrary.prototype.test = function (obj, type) {\n  if (type === getType(obj)) return true;\n  var test = this.tests[type];\n\n  if (test && 'regexp' === getType(test)) {\n    return test.test(obj);\n  } else if (test && 'function' === getType(test)) {\n    return test(obj);\n  } else {\n    throw new ReferenceError('Type test \"' + type + '\" not defined or invalid.');\n  }\n};\n\n},{}],35:[function(require,module,exports){\narguments[4][33][0].apply(exports,arguments)\n},{\"./lib/type\":36,\"dup\":33}],36:[function(require,module,exports){\n/*!\n * type-detect\n * Copyright(c) 2013 jake luer <jake@alogicalparadox.com>\n * MIT Licensed\n */\n\n/*!\n * Primary Exports\n */\n\nvar exports = module.exports = getType;\n\n/**\n * ### typeOf (obj)\n *\n * Use several different techniques to determine\n * the type of object being tested.\n *\n *\n * @param {Mixed} object\n * @return {String} object type\n * @api public\n */\nvar objectTypeRegexp = /^\\[object (.*)\\]$/;\n\nfunction getType(obj) {\n  var type = Object.prototype.toString.call(obj).match(objectTypeRegexp)[1].toLowerCase();\n  // Let \"new String('')\" return 'object'\n  if (typeof Promise === 'function' && obj instanceof Promise) return 'promise';\n  // PhantomJS has type \"DOMWindow\" for null\n  if (obj === null) return 'null';\n  // PhantomJS has type \"DOMWindow\" for undefined\n  if (obj === undefined) return 'undefined';\n  return type;\n}\n\nexports.Library = Library;\n\n/**\n * ### Library\n *\n * Create a repository for custom type detection.\n *\n * ```js\n * var lib = new type.Library;\n * ```\n *\n */\n\nfunction Library() {\n  if (!(this instanceof Library)) return new Library();\n  this.tests = {};\n}\n\n/**\n * #### .of (obj)\n *\n * Expose replacement `typeof` detection to the library.\n *\n * ```js\n * if ('string' === lib.of('hello world')) {\n *   // ...\n * }\n * ```\n *\n * @param {Mixed} object to test\n * @return {String} type\n */\n\nLibrary.prototype.of = getType;\n\n/**\n * #### .define (type, test)\n *\n * Add a test to for the `.test()` assertion.\n *\n * Can be defined as a regular expression:\n *\n * ```js\n * lib.define('int', /^[0-9]+$/);\n * ```\n *\n * ... or as a function:\n *\n * ```js\n * lib.define('bln', function (obj) {\n *   if ('boolean' === lib.of(obj)) return true;\n *   var blns = [ 'yes', 'no', 'true', 'false', 1, 0 ];\n *   if ('string' === lib.of(obj)) obj = obj.toLowerCase();\n *   return !! ~blns.indexOf(obj);\n * });\n * ```\n *\n * @param {String} type\n * @param {RegExp|Function} test\n * @api public\n */\n\nLibrary.prototype.define = function(type, test) {\n  if (arguments.length === 1) return this.tests[type];\n  this.tests[type] = test;\n  return this;\n};\n\n/**\n * #### .test (obj, test)\n *\n * Assert that an object is of type. Will first\n * check natives, and if that does not pass it will\n * use the user defined custom tests.\n *\n * ```js\n * assert(lib.test('1', 'int'));\n * assert(lib.test('yes', 'bln'));\n * ```\n *\n * @param {Mixed} object\n * @param {String} type\n * @return {Boolean} result\n * @api public\n */\n\nLibrary.prototype.test = function(obj, type) {\n  if (type === getType(obj)) return true;\n  var test = this.tests[type];\n\n  if (test && 'regexp' === getType(test)) {\n    return test.test(obj);\n  } else if (test && 'function' === getType(test)) {\n    return test(obj);\n  } else {\n    throw new ReferenceError('Type test \"' + type + '\" not defined or invalid.');\n  }\n};\n\n},{}]},{},[1])(1)\n});\n"
  },
  {
    "path": "app_frontend/static/plugin/JavaScript-Load-Image-2.12.2/test/vendor/mocha.css",
    "content": "@charset \"utf-8\";\n\nbody {\n  margin:0;\n}\n\n#mocha {\n  font: 20px/1.5 \"Helvetica Neue\", Helvetica, Arial, sans-serif;\n  margin: 60px 50px;\n}\n\n#mocha ul,\n#mocha li {\n  margin: 0;\n  padding: 0;\n}\n\n#mocha ul {\n  list-style: none;\n}\n\n#mocha h1,\n#mocha h2 {\n  margin: 0;\n}\n\n#mocha h1 {\n  margin-top: 15px;\n  font-size: 1em;\n  font-weight: 200;\n}\n\n#mocha h1 a {\n  text-decoration: none;\n  color: inherit;\n}\n\n#mocha h1 a:hover {\n  text-decoration: underline;\n}\n\n#mocha .suite .suite h1 {\n  margin-top: 0;\n  font-size: .8em;\n}\n\n#mocha .hidden {\n  display: none;\n}\n\n#mocha h2 {\n  font-size: 12px;\n  font-weight: normal;\n  cursor: pointer;\n}\n\n#mocha .suite {\n  margin-left: 15px;\n}\n\n#mocha .test {\n  margin-left: 15px;\n  overflow: hidden;\n}\n\n#mocha .test.pending:hover h2::after {\n  content: '(pending)';\n  font-family: arial, sans-serif;\n}\n\n#mocha .test.pass.medium .duration {\n  background: #c09853;\n}\n\n#mocha .test.pass.slow .duration {\n  background: #b94a48;\n}\n\n#mocha .test.pass::before {\n  content: '✓';\n  font-size: 12px;\n  display: block;\n  float: left;\n  margin-right: 5px;\n  color: #00d6b2;\n}\n\n#mocha .test.pass .duration {\n  font-size: 9px;\n  margin-left: 5px;\n  padding: 2px 5px;\n  color: #fff;\n  -webkit-box-shadow: inset 0 1px 1px rgba(0,0,0,.2);\n  -moz-box-shadow: inset 0 1px 1px rgba(0,0,0,.2);\n  box-shadow: inset 0 1px 1px rgba(0,0,0,.2);\n  -webkit-border-radius: 5px;\n  -moz-border-radius: 5px;\n  -ms-border-radius: 5px;\n  -o-border-radius: 5px;\n  border-radius: 5px;\n}\n\n#mocha .test.pass.fast .duration {\n  display: none;\n}\n\n#mocha .test.pending {\n  color: #0b97c4;\n}\n\n#mocha .test.pending::before {\n  content: '◦';\n  color: #0b97c4;\n}\n\n#mocha .test.fail {\n  color: #c00;\n}\n\n#mocha .test.fail pre {\n  color: black;\n}\n\n#mocha .test.fail::before {\n  content: '✖';\n  font-size: 12px;\n  display: block;\n  float: left;\n  margin-right: 5px;\n  color: #c00;\n}\n\n#mocha .test pre.error {\n  color: #c00;\n  max-height: 300px;\n  overflow: auto;\n}\n\n#mocha .test .html-error {\n  overflow: auto;\n  color: black;\n  line-height: 1.5;\n  display: block;\n  float: left;\n  clear: left;\n  font: 12px/1.5 monaco, monospace;\n  margin: 5px;\n  padding: 15px;\n  border: 1px solid #eee;\n  max-width: 85%; /*(1)*/\n  max-width: -webkit-calc(100% - 42px);\n  max-width: -moz-calc(100% - 42px);\n  max-width: calc(100% - 42px); /*(2)*/\n  max-height: 300px;\n  word-wrap: break-word;\n  border-bottom-color: #ddd;\n  -webkit-box-shadow: 0 1px 3px #eee;\n  -moz-box-shadow: 0 1px 3px #eee;\n  box-shadow: 0 1px 3px #eee;\n  -webkit-border-radius: 3px;\n  -moz-border-radius: 3px;\n  border-radius: 3px;\n}\n\n#mocha .test .html-error pre.error {\n  border: none;\n  -webkit-border-radius: 0;\n  -moz-border-radius: 0;\n  border-radius: 0;\n  -webkit-box-shadow: 0;\n  -moz-box-shadow: 0;\n  box-shadow: 0;\n  padding: 0;\n  margin: 0;\n  margin-top: 18px;\n  max-height: none;\n}\n\n/**\n * (1): approximate for browsers not supporting calc\n * (2): 42 = 2*15 + 2*10 + 2*1 (padding + margin + border)\n *      ^^ seriously\n */\n#mocha .test pre {\n  display: block;\n  float: left;\n  clear: left;\n  font: 12px/1.5 monaco, monospace;\n  margin: 5px;\n  padding: 15px;\n  border: 1px solid #eee;\n  max-width: 85%; /*(1)*/\n  max-width: -webkit-calc(100% - 42px);\n  max-width: -moz-calc(100% - 42px);\n  max-width: calc(100% - 42px); /*(2)*/\n  word-wrap: break-word;\n  border-bottom-color: #ddd;\n  -webkit-box-shadow: 0 1px 3px #eee;\n  -moz-box-shadow: 0 1px 3px #eee;\n  box-shadow: 0 1px 3px #eee;\n  -webkit-border-radius: 3px;\n  -moz-border-radius: 3px;\n  border-radius: 3px;\n}\n\n#mocha .test h2 {\n  position: relative;\n}\n\n#mocha .test a.replay {\n  position: absolute;\n  top: 3px;\n  right: 0;\n  text-decoration: none;\n  vertical-align: middle;\n  display: block;\n  width: 15px;\n  height: 15px;\n  line-height: 15px;\n  text-align: center;\n  background: #eee;\n  font-size: 15px;\n  -webkit-border-radius: 15px;\n  -moz-border-radius: 15px;\n  border-radius: 15px;\n  -webkit-transition:opacity 200ms;\n  -moz-transition:opacity 200ms;\n  -o-transition:opacity 200ms;\n  transition: opacity 200ms;\n  opacity: 0.3;\n  color: #888;\n}\n\n#mocha .test:hover a.replay {\n  opacity: 1;\n}\n\n#mocha-report.pass .test.fail {\n  display: none;\n}\n\n#mocha-report.fail .test.pass {\n  display: none;\n}\n\n#mocha-report.pending .test.pass,\n#mocha-report.pending .test.fail {\n  display: none;\n}\n#mocha-report.pending .test.pass.pending {\n  display: block;\n}\n\n#mocha-error {\n  color: #c00;\n  font-size: 1.5em;\n  font-weight: 100;\n  letter-spacing: 1px;\n}\n\n#mocha-stats {\n  position: fixed;\n  top: 15px;\n  right: 10px;\n  font-size: 12px;\n  margin: 0;\n  color: #888;\n  z-index: 1;\n}\n\n#mocha-stats .progress {\n  float: right;\n  padding-top: 0;\n\n  /**\n   * Set safe initial values, so mochas .progress does not inherit these\n   * properties from Bootstrap .progress (which causes .progress height to\n   * equal line height set in Bootstrap).\n   */\n  height: auto;\n  -webkit-box-shadow: none;\n  -moz-box-shadow: none;\n  box-shadow: none;\n  background-color: initial;\n}\n\n#mocha-stats em {\n  color: black;\n}\n\n#mocha-stats a {\n  text-decoration: none;\n  color: inherit;\n}\n\n#mocha-stats a:hover {\n  border-bottom: 1px solid #eee;\n}\n\n#mocha-stats li {\n  display: inline-block;\n  margin: 0 5px;\n  list-style: none;\n  padding-top: 11px;\n}\n\n#mocha-stats canvas {\n  width: 40px;\n  height: 40px;\n}\n\n#mocha code .comment { color: #ddd; }\n#mocha code .init { color: #2f6fad; }\n#mocha code .string { color: #5890ad; }\n#mocha code .keyword { color: #8a6343; }\n#mocha code .number { color: #2f6fad; }\n\n@media screen and (max-device-width: 480px) {\n  #mocha {\n    margin: 60px 0px;\n  }\n\n  #mocha #stats {\n    position: absolute;\n  }\n}\n"
  },
  {
    "path": "app_frontend/static/plugin/JavaScript-Load-Image-2.12.2/test/vendor/mocha.js",
    "content": "(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require==\"function\"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error(\"Cannot find module '\"+o+\"'\");throw f.code=\"MODULE_NOT_FOUND\",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require==\"function\"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){\n(function (process,global){\n/* eslint no-unused-vars: off */\n\n/**\n * Shim process.stdout.\n */\n\nprocess.stdout = require('browser-stdout')();\n\nvar Mocha = require('./lib/mocha');\n\n/**\n * Create a Mocha instance.\n *\n * @return {undefined}\n */\n\nvar mocha = new Mocha({ reporter: 'html' });\n\n/**\n * Save timer references to avoid Sinon interfering (see GH-237).\n */\n\nvar Date = global.Date;\nvar setTimeout = global.setTimeout;\nvar setInterval = global.setInterval;\nvar clearTimeout = global.clearTimeout;\nvar clearInterval = global.clearInterval;\n\nvar uncaughtExceptionHandlers = [];\n\nvar originalOnerrorHandler = global.onerror;\n\n/**\n * Remove uncaughtException listener.\n * Revert to original onerror handler if previously defined.\n */\n\nprocess.removeListener = function(e, fn) {\n  if (e === 'uncaughtException') {\n    if (originalOnerrorHandler) {\n      global.onerror = originalOnerrorHandler;\n    } else {\n      global.onerror = function() {};\n    }\n    var i = Mocha.utils.indexOf(uncaughtExceptionHandlers, fn);\n    if (i !== -1) {\n      uncaughtExceptionHandlers.splice(i, 1);\n    }\n  }\n};\n\n/**\n * Implements uncaughtException listener.\n */\n\nprocess.on = function(e, fn) {\n  if (e === 'uncaughtException') {\n    global.onerror = function(err, url, line) {\n      fn(new Error(err + ' (' + url + ':' + line + ')'));\n      return !mocha.allowUncaught;\n    };\n    uncaughtExceptionHandlers.push(fn);\n  }\n};\n\n// The BDD UI is registered by default, but no UI will be functional in the\n// browser without an explicit call to the overridden `mocha.ui` (see below).\n// Ensure that this default UI does not expose its methods to the global scope.\nmocha.suite.removeAllListeners('pre-require');\n\nvar immediateQueue = [];\nvar immediateTimeout;\n\nfunction timeslice() {\n  var immediateStart = new Date().getTime();\n  while (immediateQueue.length && (new Date().getTime() - immediateStart) < 100) {\n    immediateQueue.shift()();\n  }\n  if (immediateQueue.length) {\n    immediateTimeout = setTimeout(timeslice, 0);\n  } else {\n    immediateTimeout = null;\n  }\n}\n\n/**\n * High-performance override of Runner.immediately.\n */\n\nMocha.Runner.immediately = function(callback) {\n  immediateQueue.push(callback);\n  if (!immediateTimeout) {\n    immediateTimeout = setTimeout(timeslice, 0);\n  }\n};\n\n/**\n * Function to allow assertion libraries to throw errors directly into mocha.\n * This is useful when running tests in a browser because window.onerror will\n * only receive the 'message' attribute of the Error.\n */\nmocha.throwError = function(err) {\n  Mocha.utils.forEach(uncaughtExceptionHandlers, function(fn) {\n    fn(err);\n  });\n  throw err;\n};\n\n/**\n * Override ui to ensure that the ui functions are initialized.\n * Normally this would happen in Mocha.prototype.loadFiles.\n */\n\nmocha.ui = function(ui) {\n  Mocha.prototype.ui.call(this, ui);\n  this.suite.emit('pre-require', global, null, this);\n  return this;\n};\n\n/**\n * Setup mocha with the given setting options.\n */\n\nmocha.setup = function(opts) {\n  if (typeof opts === 'string') {\n    opts = { ui: opts };\n  }\n  for (var opt in opts) {\n    if (opts.hasOwnProperty(opt)) {\n      this[opt](opts[opt]);\n    }\n  }\n  return this;\n};\n\n/**\n * Run mocha, returning the Runner.\n */\n\nmocha.run = function(fn) {\n  var options = mocha.options;\n  mocha.globals('location');\n\n  var query = Mocha.utils.parseQuery(global.location.search || '');\n  if (query.grep) {\n    mocha.grep(query.grep);\n  }\n  if (query.fgrep) {\n    mocha.fgrep(query.fgrep);\n  }\n  if (query.invert) {\n    mocha.invert();\n  }\n\n  return Mocha.prototype.run.call(mocha, function(err) {\n    // The DOM Document is not available in Web Workers.\n    var document = global.document;\n    if (document && document.getElementById('mocha') && options.noHighlighting !== true) {\n      Mocha.utils.highlightTags('code');\n    }\n    if (fn) {\n      fn(err);\n    }\n  });\n};\n\n/**\n * Expose the process shim.\n * https://github.com/mochajs/mocha/pull/916\n */\n\nMocha.process = process;\n\n/**\n * Expose mocha.\n */\n\nglobal.Mocha = Mocha;\nglobal.mocha = mocha;\n\n// this allows test/acceptance/required-tokens.js to pass; thus,\n// you can now do `const describe = require('mocha').describe` in a\n// browser context (assuming browserification).  should fix #880\nmodule.exports = global;\n\n}).call(this,require('_process'),typeof global !== \"undefined\" ? global : typeof self !== \"undefined\" ? self : typeof window !== \"undefined\" ? window : {})\n},{\"./lib/mocha\":14,\"_process\":67,\"browser-stdout\":41}],2:[function(require,module,exports){\n/* eslint-disable no-unused-vars */\nmodule.exports = function(type) {\n  return function() {};\n};\n\n},{}],3:[function(require,module,exports){\n/**\n * Module exports.\n */\n\nexports.EventEmitter = EventEmitter;\n\n/**\n * Object#toString reference.\n */\nvar objToString = Object.prototype.toString;\n\n/**\n * Check if a value is an array.\n *\n * @api private\n * @param {*} val The value to test.\n * @return {boolean} true if the value is an array, otherwise false.\n */\nfunction isArray(val) {\n  return objToString.call(val) === '[object Array]';\n}\n\n/**\n * Event emitter constructor.\n *\n * @api public\n */\nfunction EventEmitter() {}\n\n/**\n * Add a listener.\n *\n * @api public\n * @param {string} name Event name.\n * @param {Function} fn Event handler.\n * @return {EventEmitter} Emitter instance.\n */\nEventEmitter.prototype.on = function(name, fn) {\n  if (!this.$events) {\n    this.$events = {};\n  }\n\n  if (!this.$events[name]) {\n    this.$events[name] = fn;\n  } else if (isArray(this.$events[name])) {\n    this.$events[name].push(fn);\n  } else {\n    this.$events[name] = [this.$events[name], fn];\n  }\n\n  return this;\n};\n\nEventEmitter.prototype.addListener = EventEmitter.prototype.on;\n\n/**\n * Adds a volatile listener.\n *\n * @api public\n * @param {string} name Event name.\n * @param {Function} fn Event handler.\n * @return {EventEmitter} Emitter instance.\n */\nEventEmitter.prototype.once = function(name, fn) {\n  var self = this;\n\n  function on() {\n    self.removeListener(name, on);\n    fn.apply(this, arguments);\n  }\n\n  on.listener = fn;\n  this.on(name, on);\n\n  return this;\n};\n\n/**\n * Remove a listener.\n *\n * @api public\n * @param {string} name Event name.\n * @param {Function} fn Event handler.\n * @return {EventEmitter} Emitter instance.\n */\nEventEmitter.prototype.removeListener = function(name, fn) {\n  if (this.$events && this.$events[name]) {\n    var list = this.$events[name];\n\n    if (isArray(list)) {\n      var pos = -1;\n\n      for (var i = 0, l = list.length; i < l; i++) {\n        if (list[i] === fn || (list[i].listener && list[i].listener === fn)) {\n          pos = i;\n          break;\n        }\n      }\n\n      if (pos < 0) {\n        return this;\n      }\n\n      list.splice(pos, 1);\n\n      if (!list.length) {\n        delete this.$events[name];\n      }\n    } else if (list === fn || (list.listener && list.listener === fn)) {\n      delete this.$events[name];\n    }\n  }\n\n  return this;\n};\n\n/**\n * Remove all listeners for an event.\n *\n * @api public\n * @param {string} name Event name.\n * @return {EventEmitter} Emitter instance.\n */\nEventEmitter.prototype.removeAllListeners = function(name) {\n  if (name === undefined) {\n    this.$events = {};\n    return this;\n  }\n\n  if (this.$events && this.$events[name]) {\n    this.$events[name] = null;\n  }\n\n  return this;\n};\n\n/**\n * Get all listeners for a given event.\n *\n * @api public\n * @param {string} name Event name.\n * @return {EventEmitter} Emitter instance.\n */\nEventEmitter.prototype.listeners = function(name) {\n  if (!this.$events) {\n    this.$events = {};\n  }\n\n  if (!this.$events[name]) {\n    this.$events[name] = [];\n  }\n\n  if (!isArray(this.$events[name])) {\n    this.$events[name] = [this.$events[name]];\n  }\n\n  return this.$events[name];\n};\n\n/**\n * Emit an event.\n *\n * @api public\n * @param {string} name Event name.\n * @return {boolean} true if at least one handler was invoked, else false.\n */\nEventEmitter.prototype.emit = function(name) {\n  if (!this.$events) {\n    return false;\n  }\n\n  var handler = this.$events[name];\n\n  if (!handler) {\n    return false;\n  }\n\n  var args = Array.prototype.slice.call(arguments, 1);\n\n  if (typeof handler === 'function') {\n    handler.apply(this, args);\n  } else if (isArray(handler)) {\n    var listeners = handler.slice();\n\n    for (var i = 0, l = listeners.length; i < l; i++) {\n      listeners[i].apply(this, args);\n    }\n  } else {\n    return false;\n  }\n\n  return true;\n};\n\n},{}],4:[function(require,module,exports){\n/**\n * Expose `Progress`.\n */\n\nmodule.exports = Progress;\n\n/**\n * Initialize a new `Progress` indicator.\n */\nfunction Progress() {\n  this.percent = 0;\n  this.size(0);\n  this.fontSize(11);\n  this.font('helvetica, arial, sans-serif');\n}\n\n/**\n * Set progress size to `size`.\n *\n * @api public\n * @param {number} size\n * @return {Progress} Progress instance.\n */\nProgress.prototype.size = function(size) {\n  this._size = size;\n  return this;\n};\n\n/**\n * Set text to `text`.\n *\n * @api public\n * @param {string} text\n * @return {Progress} Progress instance.\n */\nProgress.prototype.text = function(text) {\n  this._text = text;\n  return this;\n};\n\n/**\n * Set font size to `size`.\n *\n * @api public\n * @param {number} size\n * @return {Progress} Progress instance.\n */\nProgress.prototype.fontSize = function(size) {\n  this._fontSize = size;\n  return this;\n};\n\n/**\n * Set font to `family`.\n *\n * @param {string} family\n * @return {Progress} Progress instance.\n */\nProgress.prototype.font = function(family) {\n  this._font = family;\n  return this;\n};\n\n/**\n * Update percentage to `n`.\n *\n * @param {number} n\n * @return {Progress} Progress instance.\n */\nProgress.prototype.update = function(n) {\n  this.percent = n;\n  return this;\n};\n\n/**\n * Draw on `ctx`.\n *\n * @param {CanvasRenderingContext2d} ctx\n * @return {Progress} Progress instance.\n */\nProgress.prototype.draw = function(ctx) {\n  try {\n    var percent = Math.min(this.percent, 100);\n    var size = this._size;\n    var half = size / 2;\n    var x = half;\n    var y = half;\n    var rad = half - 1;\n    var fontSize = this._fontSize;\n\n    ctx.font = fontSize + 'px ' + this._font;\n\n    var angle = Math.PI * 2 * (percent / 100);\n    ctx.clearRect(0, 0, size, size);\n\n    // outer circle\n    ctx.strokeStyle = '#9f9f9f';\n    ctx.beginPath();\n    ctx.arc(x, y, rad, 0, angle, false);\n    ctx.stroke();\n\n    // inner circle\n    ctx.strokeStyle = '#eee';\n    ctx.beginPath();\n    ctx.arc(x, y, rad - 1, 0, angle, true);\n    ctx.stroke();\n\n    // text\n    var text = this._text || (percent | 0) + '%';\n    var w = ctx.measureText(text).width;\n\n    ctx.fillText(text, x - w / 2 + 1, y + fontSize / 2 - 1);\n  } catch (err) {\n    // don't fail if we can't render progress\n  }\n  return this;\n};\n\n},{}],5:[function(require,module,exports){\n(function (global){\nexports.isatty = function isatty() {\n  return true;\n};\n\nexports.getWindowSize = function getWindowSize() {\n  if ('innerHeight' in global) {\n    return [global.innerHeight, global.innerWidth];\n  }\n  // In a Web Worker, the DOM Window is not available.\n  return [640, 480];\n};\n\n}).call(this,typeof global !== \"undefined\" ? global : typeof self !== \"undefined\" ? self : typeof window !== \"undefined\" ? window : {})\n},{}],6:[function(require,module,exports){\n/**\n * Module dependencies.\n */\n\nvar JSON = require('json3');\n\n/**\n * Expose `Context`.\n */\n\nmodule.exports = Context;\n\n/**\n * Initialize a new `Context`.\n *\n * @api private\n */\nfunction Context() {}\n\n/**\n * Set or get the context `Runnable` to `runnable`.\n *\n * @api private\n * @param {Runnable} runnable\n * @return {Context}\n */\nContext.prototype.runnable = function(runnable) {\n  if (!arguments.length) {\n    return this._runnable;\n  }\n  this.test = this._runnable = runnable;\n  return this;\n};\n\n/**\n * Set test timeout `ms`.\n *\n * @api private\n * @param {number} ms\n * @return {Context} self\n */\nContext.prototype.timeout = function(ms) {\n  if (!arguments.length) {\n    return this.runnable().timeout();\n  }\n  this.runnable().timeout(ms);\n  return this;\n};\n\n/**\n * Set test timeout `enabled`.\n *\n * @api private\n * @param {boolean} enabled\n * @return {Context} self\n */\nContext.prototype.enableTimeouts = function(enabled) {\n  this.runnable().enableTimeouts(enabled);\n  return this;\n};\n\n/**\n * Set test slowness threshold `ms`.\n *\n * @api private\n * @param {number} ms\n * @return {Context} self\n */\nContext.prototype.slow = function(ms) {\n  this.runnable().slow(ms);\n  return this;\n};\n\n/**\n * Mark a test as skipped.\n *\n * @api private\n * @return {Context} self\n */\nContext.prototype.skip = function() {\n  this.runnable().skip();\n  return this;\n};\n\n/**\n * Allow a number of retries on failed tests\n *\n * @api private\n * @param {number} n\n * @return {Context} self\n */\nContext.prototype.retries = function(n) {\n  if (!arguments.length) {\n    return this.runnable().retries();\n  }\n  this.runnable().retries(n);\n  return this;\n};\n\n/**\n * Inspect the context void of `._runnable`.\n *\n * @api private\n * @return {string}\n */\nContext.prototype.inspect = function() {\n  return JSON.stringify(this, function(key, val) {\n    return key === 'runnable' || key === 'test' ? undefined : val;\n  }, 2);\n};\n\n},{\"json3\":54}],7:[function(require,module,exports){\n/**\n * Module dependencies.\n */\n\nvar Runnable = require('./runnable');\nvar inherits = require('./utils').inherits;\n\n/**\n * Expose `Hook`.\n */\n\nmodule.exports = Hook;\n\n/**\n * Initialize a new `Hook` with the given `title` and callback `fn`.\n *\n * @param {String} title\n * @param {Function} fn\n * @api private\n */\nfunction Hook(title, fn) {\n  Runnable.call(this, title, fn);\n  this.type = 'hook';\n}\n\n/**\n * Inherit from `Runnable.prototype`.\n */\ninherits(Hook, Runnable);\n\n/**\n * Get or set the test `err`.\n *\n * @param {Error} err\n * @return {Error}\n * @api public\n */\nHook.prototype.error = function(err) {\n  if (!arguments.length) {\n    err = this._error;\n    this._error = null;\n    return err;\n  }\n\n  this._error = err;\n};\n\n},{\"./runnable\":33,\"./utils\":38}],8:[function(require,module,exports){\n/**\n * Module dependencies.\n */\n\nvar Test = require('../test');\n\n/**\n * BDD-style interface:\n *\n *      describe('Array', function() {\n *        describe('#indexOf()', function() {\n *          it('should return -1 when not present', function() {\n *            // ...\n *          });\n *\n *          it('should return the index when present', function() {\n *            // ...\n *          });\n *        });\n *      });\n *\n * @param {Suite} suite Root suite.\n */\nmodule.exports = function(suite) {\n  var suites = [suite];\n\n  suite.on('pre-require', function(context, file, mocha) {\n    var common = require('./common')(suites, context, mocha);\n\n    context.before = common.before;\n    context.after = common.after;\n    context.beforeEach = common.beforeEach;\n    context.afterEach = common.afterEach;\n    context.run = mocha.options.delay && common.runWithSuite(suite);\n    /**\n     * Describe a \"suite\" with the given `title`\n     * and callback `fn` containing nested suites\n     * and/or tests.\n     */\n\n    context.describe = context.context = function(title, fn) {\n      return common.suite.create({\n        title: title,\n        file: file,\n        fn: fn\n      });\n    };\n\n    /**\n     * Pending describe.\n     */\n\n    context.xdescribe = context.xcontext = context.describe.skip = function(title, fn) {\n      return common.suite.skip({\n        title: title,\n        file: file,\n        fn: fn\n      });\n    };\n\n    /**\n     * Exclusive suite.\n     */\n\n    context.describe.only = function(title, fn) {\n      return common.suite.only({\n        title: title,\n        file: file,\n        fn: fn\n      });\n    };\n\n    /**\n     * Describe a specification or test-case\n     * with the given `title` and callback `fn`\n     * acting as a thunk.\n     */\n\n    context.it = context.specify = function(title, fn) {\n      var suite = suites[0];\n      if (suite.isPending()) {\n        fn = null;\n      }\n      var test = new Test(title, fn);\n      test.file = file;\n      suite.addTest(test);\n      return test;\n    };\n\n    /**\n     * Exclusive test-case.\n     */\n\n    context.it.only = function(title, fn) {\n      return common.test.only(mocha, context.it(title, fn));\n    };\n\n    /**\n     * Pending test case.\n     */\n\n    context.xit = context.xspecify = context.it.skip = function(title) {\n      context.it(title);\n    };\n\n    /**\n     * Number of attempts to retry.\n     */\n    context.it.retries = function(n) {\n      context.retries(n);\n    };\n  });\n};\n\n},{\"../test\":36,\"./common\":9}],9:[function(require,module,exports){\n'use strict';\n\nvar Suite = require('../suite');\n\n/**\n * Functions common to more than one interface.\n *\n * @param {Suite[]} suites\n * @param {Context} context\n * @param {Mocha} mocha\n * @return {Object} An object containing common functions.\n */\nmodule.exports = function(suites, context, mocha) {\n  return {\n    /**\n     * This is only present if flag --delay is passed into Mocha. It triggers\n     * root suite execution.\n     *\n     * @param {Suite} suite The root wuite.\n     * @return {Function} A function which runs the root suite\n     */\n    runWithSuite: function runWithSuite(suite) {\n      return function run() {\n        suite.run();\n      };\n    },\n\n    /**\n     * Execute before running tests.\n     *\n     * @param {string} name\n     * @param {Function} fn\n     */\n    before: function(name, fn) {\n      suites[0].beforeAll(name, fn);\n    },\n\n    /**\n     * Execute after running tests.\n     *\n     * @param {string} name\n     * @param {Function} fn\n     */\n    after: function(name, fn) {\n      suites[0].afterAll(name, fn);\n    },\n\n    /**\n     * Execute before each test case.\n     *\n     * @param {string} name\n     * @param {Function} fn\n     */\n    beforeEach: function(name, fn) {\n      suites[0].beforeEach(name, fn);\n    },\n\n    /**\n     * Execute after each test case.\n     *\n     * @param {string} name\n     * @param {Function} fn\n     */\n    afterEach: function(name, fn) {\n      suites[0].afterEach(name, fn);\n    },\n\n    suite: {\n      /**\n       * Create an exclusive Suite; convenience function\n       * See docstring for create() below.\n       *\n       * @param {Object} opts\n       * @returns {Suite}\n       */\n      only: function only(opts) {\n        mocha.options.hasOnly = true;\n        opts.isOnly = true;\n        return this.create(opts);\n      },\n\n      /**\n       * Create a Suite, but skip it; convenience function\n       * See docstring for create() below.\n       *\n       * @param {Object} opts\n       * @returns {Suite}\n       */\n      skip: function skip(opts) {\n        opts.pending = true;\n        return this.create(opts);\n      },\n\n      /**\n       * Creates a suite.\n       * @param {Object} opts Options\n       * @param {string} opts.title Title of Suite\n       * @param {Function} [opts.fn] Suite Function (not always applicable)\n       * @param {boolean} [opts.pending] Is Suite pending?\n       * @param {string} [opts.file] Filepath where this Suite resides\n       * @param {boolean} [opts.isOnly] Is Suite exclusive?\n       * @returns {Suite}\n       */\n      create: function create(opts) {\n        var suite = Suite.create(suites[0], opts.title);\n        suite.pending = Boolean(opts.pending);\n        suite.file = opts.file;\n        suites.unshift(suite);\n        if (opts.isOnly) {\n          suite.parent._onlySuites = suite.parent._onlySuites.concat(suite);\n          mocha.options.hasOnly = true;\n        }\n        if (typeof opts.fn === 'function') {\n          opts.fn.call(suite);\n          suites.shift();\n        } else if (typeof opts.fn === 'undefined' && !suite.pending) {\n          throw new Error('Suite \"' + suite.fullTitle() + '\" was defined but no callback was supplied. Supply a callback or explicitly skip the suite.');\n        }\n\n        return suite;\n      }\n    },\n\n    test: {\n\n      /**\n       * Exclusive test-case.\n       *\n       * @param {Object} mocha\n       * @param {Function} test\n       * @returns {*}\n       */\n      only: function(mocha, test) {\n        test.parent._onlyTests = test.parent._onlyTests.concat(test);\n        mocha.options.hasOnly = true;\n        return test;\n      },\n\n      /**\n       * Pending test case.\n       *\n       * @param {string} title\n       */\n      skip: function(title) {\n        context.test(title);\n      },\n\n      /**\n       * Number of retry attempts\n       *\n       * @param {number} n\n       */\n      retries: function(n) {\n        context.retries(n);\n      }\n    }\n  };\n};\n\n},{\"../suite\":35}],10:[function(require,module,exports){\n/**\n * Module dependencies.\n */\n\nvar Suite = require('../suite');\nvar Test = require('../test');\n\n/**\n * Exports-style (as Node.js module) interface:\n *\n *     exports.Array = {\n *       '#indexOf()': {\n *         'should return -1 when the value is not present': function() {\n *\n *         },\n *\n *         'should return the correct index when the value is present': function() {\n *\n *         }\n *       }\n *     };\n *\n * @param {Suite} suite Root suite.\n */\nmodule.exports = function(suite) {\n  var suites = [suite];\n\n  suite.on('require', visit);\n\n  function visit(obj, file) {\n    var suite;\n    for (var key in obj) {\n      if (typeof obj[key] === 'function') {\n        var fn = obj[key];\n        switch (key) {\n          case 'before':\n            suites[0].beforeAll(fn);\n            break;\n          case 'after':\n            suites[0].afterAll(fn);\n            break;\n          case 'beforeEach':\n            suites[0].beforeEach(fn);\n            break;\n          case 'afterEach':\n            suites[0].afterEach(fn);\n            break;\n          default:\n            var test = new Test(key, fn);\n            test.file = file;\n            suites[0].addTest(test);\n        }\n      } else {\n        suite = Suite.create(suites[0], key);\n        suites.unshift(suite);\n        visit(obj[key], file);\n        suites.shift();\n      }\n    }\n  }\n};\n\n},{\"../suite\":35,\"../test\":36}],11:[function(require,module,exports){\nexports.bdd = require('./bdd');\nexports.tdd = require('./tdd');\nexports.qunit = require('./qunit');\nexports.exports = require('./exports');\n\n},{\"./bdd\":8,\"./exports\":10,\"./qunit\":12,\"./tdd\":13}],12:[function(require,module,exports){\n/**\n * Module dependencies.\n */\n\nvar Test = require('../test');\n\n/**\n * QUnit-style interface:\n *\n *     suite('Array');\n *\n *     test('#length', function() {\n *       var arr = [1,2,3];\n *       ok(arr.length == 3);\n *     });\n *\n *     test('#indexOf()', function() {\n *       var arr = [1,2,3];\n *       ok(arr.indexOf(1) == 0);\n *       ok(arr.indexOf(2) == 1);\n *       ok(arr.indexOf(3) == 2);\n *     });\n *\n *     suite('String');\n *\n *     test('#length', function() {\n *       ok('foo'.length == 3);\n *     });\n *\n * @param {Suite} suite Root suite.\n */\nmodule.exports = function(suite) {\n  var suites = [suite];\n\n  suite.on('pre-require', function(context, file, mocha) {\n    var common = require('./common')(suites, context, mocha);\n\n    context.before = common.before;\n    context.after = common.after;\n    context.beforeEach = common.beforeEach;\n    context.afterEach = common.afterEach;\n    context.run = mocha.options.delay && common.runWithSuite(suite);\n    /**\n     * Describe a \"suite\" with the given `title`.\n     */\n\n    context.suite = function(title) {\n      if (suites.length > 1) {\n        suites.shift();\n      }\n      return common.suite.create({\n        title: title,\n        file: file,\n        fn: false\n      });\n    };\n\n    /**\n     * Exclusive Suite.\n     */\n\n    context.suite.only = function(title) {\n      if (suites.length > 1) {\n        suites.shift();\n      }\n      return common.suite.only({\n        title: title,\n        file: file,\n        fn: false\n      });\n    };\n\n    /**\n     * Describe a specification or test-case\n     * with the given `title` and callback `fn`\n     * acting as a thunk.\n     */\n\n    context.test = function(title, fn) {\n      var test = new Test(title, fn);\n      test.file = file;\n      suites[0].addTest(test);\n      return test;\n    };\n\n    /**\n     * Exclusive test-case.\n     */\n\n    context.test.only = function(title, fn) {\n      return common.test.only(mocha, context.test(title, fn));\n    };\n\n    context.test.skip = common.test.skip;\n    context.test.retries = common.test.retries;\n  });\n};\n\n},{\"../test\":36,\"./common\":9}],13:[function(require,module,exports){\n/**\n * Module dependencies.\n */\n\nvar Test = require('../test');\n\n/**\n * TDD-style interface:\n *\n *      suite('Array', function() {\n *        suite('#indexOf()', function() {\n *          suiteSetup(function() {\n *\n *          });\n *\n *          test('should return -1 when not present', function() {\n *\n *          });\n *\n *          test('should return the index when present', function() {\n *\n *          });\n *\n *          suiteTeardown(function() {\n *\n *          });\n *        });\n *      });\n *\n * @param {Suite} suite Root suite.\n */\nmodule.exports = function(suite) {\n  var suites = [suite];\n\n  suite.on('pre-require', function(context, file, mocha) {\n    var common = require('./common')(suites, context, mocha);\n\n    context.setup = common.beforeEach;\n    context.teardown = common.afterEach;\n    context.suiteSetup = common.before;\n    context.suiteTeardown = common.after;\n    context.run = mocha.options.delay && common.runWithSuite(suite);\n\n    /**\n     * Describe a \"suite\" with the given `title` and callback `fn` containing\n     * nested suites and/or tests.\n     */\n    context.suite = function(title, fn) {\n      return common.suite.create({\n        title: title,\n        file: file,\n        fn: fn\n      });\n    };\n\n    /**\n     * Pending suite.\n     */\n    context.suite.skip = function(title, fn) {\n      return common.suite.skip({\n        title: title,\n        file: file,\n        fn: fn\n      });\n    };\n\n    /**\n     * Exclusive test-case.\n     */\n    context.suite.only = function(title, fn) {\n      return common.suite.only({\n        title: title,\n        file: file,\n        fn: fn\n      });\n    };\n\n    /**\n     * Describe a specification or test-case with the given `title` and\n     * callback `fn` acting as a thunk.\n     */\n    context.test = function(title, fn) {\n      var suite = suites[0];\n      if (suite.isPending()) {\n        fn = null;\n      }\n      var test = new Test(title, fn);\n      test.file = file;\n      suite.addTest(test);\n      return test;\n    };\n\n    /**\n     * Exclusive test-case.\n     */\n\n    context.test.only = function(title, fn) {\n      return common.test.only(mocha, context.test(title, fn));\n    };\n\n    context.test.skip = common.test.skip;\n    context.test.retries = common.test.retries;\n  });\n};\n\n},{\"../test\":36,\"./common\":9}],14:[function(require,module,exports){\n(function (process,global,__dirname){\n/*!\n * mocha\n * Copyright(c) 2011 TJ Holowaychuk <tj@vision-media.ca>\n * MIT Licensed\n */\n\n/**\n * Module dependencies.\n */\n\nvar escapeRe = require('escape-string-regexp');\nvar path = require('path');\nvar reporters = require('./reporters');\nvar utils = require('./utils');\n\n/**\n * Expose `Mocha`.\n */\n\nexports = module.exports = Mocha;\n\n/**\n * To require local UIs and reporters when running in node.\n */\n\nif (!process.browser) {\n  var cwd = process.cwd();\n  module.paths.push(cwd, path.join(cwd, 'node_modules'));\n}\n\n/**\n * Expose internals.\n */\n\nexports.utils = utils;\nexports.interfaces = require('./interfaces');\nexports.reporters = reporters;\nexports.Runnable = require('./runnable');\nexports.Context = require('./context');\nexports.Runner = require('./runner');\nexports.Suite = require('./suite');\nexports.Hook = require('./hook');\nexports.Test = require('./test');\n\n/**\n * Return image `name` path.\n *\n * @api private\n * @param {string} name\n * @return {string}\n */\nfunction image(name) {\n  return path.join(__dirname, '../images', name + '.png');\n}\n\n/**\n * Set up mocha with `options`.\n *\n * Options:\n *\n *   - `ui` name \"bdd\", \"tdd\", \"exports\" etc\n *   - `reporter` reporter instance, defaults to `mocha.reporters.spec`\n *   - `globals` array of accepted globals\n *   - `timeout` timeout in milliseconds\n *   - `retries` number of times to retry failed tests\n *   - `bail` bail on the first test failure\n *   - `slow` milliseconds to wait before considering a test slow\n *   - `ignoreLeaks` ignore global leaks\n *   - `fullTrace` display the full stack-trace on failing\n *   - `grep` string or regexp to filter tests with\n *\n * @param {Object} options\n * @api public\n */\nfunction Mocha(options) {\n  options = options || {};\n  this.files = [];\n  this.options = options;\n  if (options.grep) {\n    this.grep(new RegExp(options.grep));\n  }\n  if (options.fgrep) {\n    this.fgrep(options.fgrep);\n  }\n  this.suite = new exports.Suite('', new exports.Context());\n  this.ui(options.ui);\n  this.bail(options.bail);\n  this.reporter(options.reporter, options.reporterOptions);\n  if (typeof options.timeout !== 'undefined' && options.timeout !== null) {\n    this.timeout(options.timeout);\n  }\n  if (typeof options.retries !== 'undefined' && options.retries !== null) {\n    this.retries(options.retries);\n  }\n  this.useColors(options.useColors);\n  if (options.enableTimeouts !== null) {\n    this.enableTimeouts(options.enableTimeouts);\n  }\n  if (options.slow) {\n    this.slow(options.slow);\n  }\n}\n\n/**\n * Enable or disable bailing on the first failure.\n *\n * @api public\n * @param {boolean} [bail]\n */\nMocha.prototype.bail = function(bail) {\n  if (!arguments.length) {\n    bail = true;\n  }\n  this.suite.bail(bail);\n  return this;\n};\n\n/**\n * Add test `file`.\n *\n * @api public\n * @param {string} file\n */\nMocha.prototype.addFile = function(file) {\n  this.files.push(file);\n  return this;\n};\n\n/**\n * Set reporter to `reporter`, defaults to \"spec\".\n *\n * @param {String|Function} reporter name or constructor\n * @param {Object} reporterOptions optional options\n * @api public\n * @param {string|Function} reporter name or constructor\n * @param {Object} reporterOptions optional options\n */\nMocha.prototype.reporter = function(reporter, reporterOptions) {\n  if (typeof reporter === 'function') {\n    this._reporter = reporter;\n  } else {\n    reporter = reporter || 'spec';\n    var _reporter;\n    // Try to load a built-in reporter.\n    if (reporters[reporter]) {\n      _reporter = reporters[reporter];\n    }\n    // Try to load reporters from process.cwd() and node_modules\n    if (!_reporter) {\n      try {\n        _reporter = require(reporter);\n      } catch (err) {\n        err.message.indexOf('Cannot find module') !== -1\n          ? console.warn('\"' + reporter + '\" reporter not found')\n          : console.warn('\"' + reporter + '\" reporter blew up with error:\\n' + err.stack);\n      }\n    }\n    if (!_reporter && reporter === 'teamcity') {\n      console.warn('The Teamcity reporter was moved to a package named '\n        + 'mocha-teamcity-reporter '\n        + '(https://npmjs.org/package/mocha-teamcity-reporter).');\n    }\n    if (!_reporter) {\n      throw new Error('invalid reporter \"' + reporter + '\"');\n    }\n    this._reporter = _reporter;\n  }\n  this.options.reporterOptions = reporterOptions;\n  return this;\n};\n\n/**\n * Set test UI `name`, defaults to \"bdd\".\n *\n * @api public\n * @param {string} bdd\n */\nMocha.prototype.ui = function(name) {\n  name = name || 'bdd';\n  this._ui = exports.interfaces[name];\n  if (!this._ui) {\n    try {\n      this._ui = require(name);\n    } catch (err) {\n      throw new Error('invalid interface \"' + name + '\"');\n    }\n  }\n  this._ui = this._ui(this.suite);\n\n  this.suite.on('pre-require', function(context) {\n    exports.afterEach = context.afterEach || context.teardown;\n    exports.after = context.after || context.suiteTeardown;\n    exports.beforeEach = context.beforeEach || context.setup;\n    exports.before = context.before || context.suiteSetup;\n    exports.describe = context.describe || context.suite;\n    exports.it = context.it || context.test;\n    exports.setup = context.setup || context.beforeEach;\n    exports.suiteSetup = context.suiteSetup || context.before;\n    exports.suiteTeardown = context.suiteTeardown || context.after;\n    exports.suite = context.suite || context.describe;\n    exports.teardown = context.teardown || context.afterEach;\n    exports.test = context.test || context.it;\n    exports.run = context.run;\n  });\n\n  return this;\n};\n\n/**\n * Load registered files.\n *\n * @api private\n */\nMocha.prototype.loadFiles = function(fn) {\n  var self = this;\n  var suite = this.suite;\n  this.files.forEach(function(file) {\n    file = path.resolve(file);\n    suite.emit('pre-require', global, file, self);\n    suite.emit('require', require(file), file, self);\n    suite.emit('post-require', global, file, self);\n  });\n  fn && fn();\n};\n\n/**\n * Enable growl support.\n *\n * @api private\n */\nMocha.prototype._growl = function(runner, reporter) {\n  var notify = require('growl');\n\n  runner.on('end', function() {\n    var stats = reporter.stats;\n    if (stats.failures) {\n      var msg = stats.failures + ' of ' + runner.total + ' tests failed';\n      notify(msg, { name: 'mocha', title: 'Failed', image: image('error') });\n    } else {\n      notify(stats.passes + ' tests passed in ' + stats.duration + 'ms', {\n        name: 'mocha',\n        title: 'Passed',\n        image: image('ok')\n      });\n    }\n  });\n};\n\n/**\n * Escape string and add it to grep as a regexp.\n *\n * @api public\n * @param str\n * @returns {Mocha}\n */\nMocha.prototype.fgrep = function(str) {\n  return this.grep(new RegExp(escapeRe(str)));\n};\n\n/**\n * Add regexp to grep, if `re` is a string it is escaped.\n *\n * @param {RegExp|String} re\n * @return {Mocha}\n * @api public\n * @param {RegExp|string} re\n * @return {Mocha}\n */\nMocha.prototype.grep = function(re) {\n  if (utils.isString(re)) {\n    // extract args if it's regex-like, i.e: [string, pattern, flag]\n    var arg = re.match(/^\\/(.*)\\/(g|i|)$|.*/);\n    this.options.grep = new RegExp(arg[1] || arg[0], arg[2]);\n  } else {\n    this.options.grep = re;\n  }\n  return this;\n};\n/**\n * Invert `.grep()` matches.\n *\n * @return {Mocha}\n * @api public\n */\nMocha.prototype.invert = function() {\n  this.options.invert = true;\n  return this;\n};\n\n/**\n * Ignore global leaks.\n *\n * @param {Boolean} ignore\n * @return {Mocha}\n * @api public\n * @param {boolean} ignore\n * @return {Mocha}\n */\nMocha.prototype.ignoreLeaks = function(ignore) {\n  this.options.ignoreLeaks = Boolean(ignore);\n  return this;\n};\n\n/**\n * Enable global leak checking.\n *\n * @return {Mocha}\n * @api public\n */\nMocha.prototype.checkLeaks = function() {\n  this.options.ignoreLeaks = false;\n  return this;\n};\n\n/**\n * Display long stack-trace on failing\n *\n * @return {Mocha}\n * @api public\n */\nMocha.prototype.fullTrace = function() {\n  this.options.fullStackTrace = true;\n  return this;\n};\n\n/**\n * Enable growl support.\n *\n * @return {Mocha}\n * @api public\n */\nMocha.prototype.growl = function() {\n  this.options.growl = true;\n  return this;\n};\n\n/**\n * Ignore `globals` array or string.\n *\n * @param {Array|String} globals\n * @return {Mocha}\n * @api public\n * @param {Array|string} globals\n * @return {Mocha}\n */\nMocha.prototype.globals = function(globals) {\n  this.options.globals = (this.options.globals || []).concat(globals);\n  return this;\n};\n\n/**\n * Emit color output.\n *\n * @param {Boolean} colors\n * @return {Mocha}\n * @api public\n * @param {boolean} colors\n * @return {Mocha}\n */\nMocha.prototype.useColors = function(colors) {\n  if (colors !== undefined) {\n    this.options.useColors = colors;\n  }\n  return this;\n};\n\n/**\n * Use inline diffs rather than +/-.\n *\n * @param {Boolean} inlineDiffs\n * @return {Mocha}\n * @api public\n * @param {boolean} inlineDiffs\n * @return {Mocha}\n */\nMocha.prototype.useInlineDiffs = function(inlineDiffs) {\n  this.options.useInlineDiffs = inlineDiffs !== undefined && inlineDiffs;\n  return this;\n};\n\n/**\n * Set the timeout in milliseconds.\n *\n * @param {Number} timeout\n * @return {Mocha}\n * @api public\n * @param {number} timeout\n * @return {Mocha}\n */\nMocha.prototype.timeout = function(timeout) {\n  this.suite.timeout(timeout);\n  return this;\n};\n\n/**\n * Set the number of times to retry failed tests.\n *\n * @param {Number} retry times\n * @return {Mocha}\n * @api public\n */\nMocha.prototype.retries = function(n) {\n  this.suite.retries(n);\n  return this;\n};\n\n/**\n * Set slowness threshold in milliseconds.\n *\n * @param {Number} slow\n * @return {Mocha}\n * @api public\n * @param {number} slow\n * @return {Mocha}\n */\nMocha.prototype.slow = function(slow) {\n  this.suite.slow(slow);\n  return this;\n};\n\n/**\n * Enable timeouts.\n *\n * @param {Boolean} enabled\n * @return {Mocha}\n * @api public\n * @param {boolean} enabled\n * @return {Mocha}\n */\nMocha.prototype.enableTimeouts = function(enabled) {\n  this.suite.enableTimeouts(arguments.length && enabled !== undefined ? enabled : true);\n  return this;\n};\n\n/**\n * Makes all tests async (accepting a callback)\n *\n * @return {Mocha}\n * @api public\n */\nMocha.prototype.asyncOnly = function() {\n  this.options.asyncOnly = true;\n  return this;\n};\n\n/**\n * Disable syntax highlighting (in browser).\n *\n * @api public\n */\nMocha.prototype.noHighlighting = function() {\n  this.options.noHighlighting = true;\n  return this;\n};\n\n/**\n * Enable uncaught errors to propagate (in browser).\n *\n * @return {Mocha}\n * @api public\n */\nMocha.prototype.allowUncaught = function() {\n  this.options.allowUncaught = true;\n  return this;\n};\n\n/**\n * Delay root suite execution.\n * @returns {Mocha}\n */\nMocha.prototype.delay = function delay() {\n  this.options.delay = true;\n  return this;\n};\n\n/**\n * Run tests and invoke `fn()` when complete.\n *\n * @api public\n * @param {Function} fn\n * @return {Runner}\n */\nMocha.prototype.run = function(fn) {\n  if (this.files.length) {\n    this.loadFiles();\n  }\n  var suite = this.suite;\n  var options = this.options;\n  options.files = this.files;\n  var runner = new exports.Runner(suite, options.delay);\n  var reporter = new this._reporter(runner, options);\n  runner.ignoreLeaks = options.ignoreLeaks !== false;\n  runner.fullStackTrace = options.fullStackTrace;\n  runner.hasOnly = options.hasOnly;\n  runner.asyncOnly = options.asyncOnly;\n  runner.allowUncaught = options.allowUncaught;\n  if (options.grep) {\n    runner.grep(options.grep, options.invert);\n  }\n  if (options.globals) {\n    runner.globals(options.globals);\n  }\n  if (options.growl) {\n    this._growl(runner, reporter);\n  }\n  if (options.useColors !== undefined) {\n    exports.reporters.Base.useColors = options.useColors;\n  }\n  exports.reporters.Base.inlineDiffs = options.useInlineDiffs;\n\n  function done(failures) {\n    if (reporter.done) {\n      reporter.done(failures, fn);\n    } else {\n      fn && fn(failures);\n    }\n  }\n\n  return runner.run(done);\n};\n\n}).call(this,require('_process'),typeof global !== \"undefined\" ? global : typeof self !== \"undefined\" ? self : typeof window !== \"undefined\" ? window : {},\"/lib\")\n},{\"./context\":6,\"./hook\":7,\"./interfaces\":11,\"./reporters\":21,\"./runnable\":33,\"./runner\":34,\"./suite\":35,\"./test\":36,\"./utils\":38,\"_process\":67,\"escape-string-regexp\":47,\"growl\":49,\"path\":42}],15:[function(require,module,exports){\n/**\n * Helpers.\n */\n\nvar s = 1000;\nvar m = s * 60;\nvar h = m * 60;\nvar d = h * 24;\nvar y = d * 365.25;\n\n/**\n * Parse or format the given `val`.\n *\n * Options:\n *\n *  - `long` verbose formatting [false]\n *\n * @api public\n * @param {string|number} val\n * @param {Object} options\n * @return {string|number}\n */\nmodule.exports = function(val, options) {\n  options = options || {};\n  if (typeof val === 'string') {\n    return parse(val);\n  }\n  // https://github.com/mochajs/mocha/pull/1035\n  return options['long'] ? longFormat(val) : shortFormat(val);\n};\n\n/**\n * Parse the given `str` and return milliseconds.\n *\n * @api private\n * @param {string} str\n * @return {number}\n */\nfunction parse(str) {\n  var match = (/^((?:\\d+)?\\.?\\d+) *(ms|seconds?|s|minutes?|m|hours?|h|days?|d|years?|y)?$/i).exec(str);\n  if (!match) {\n    return;\n  }\n  var n = parseFloat(match[1]);\n  var type = (match[2] || 'ms').toLowerCase();\n  switch (type) {\n    case 'years':\n    case 'year':\n    case 'y':\n      return n * y;\n    case 'days':\n    case 'day':\n    case 'd':\n      return n * d;\n    case 'hours':\n    case 'hour':\n    case 'h':\n      return n * h;\n    case 'minutes':\n    case 'minute':\n    case 'm':\n      return n * m;\n    case 'seconds':\n    case 'second':\n    case 's':\n      return n * s;\n    case 'ms':\n      return n;\n    default:\n      // No default case\n  }\n}\n\n/**\n * Short format for `ms`.\n *\n * @api private\n * @param {number} ms\n * @return {string}\n */\nfunction shortFormat(ms) {\n  if (ms >= d) {\n    return Math.round(ms / d) + 'd';\n  }\n  if (ms >= h) {\n    return Math.round(ms / h) + 'h';\n  }\n  if (ms >= m) {\n    return Math.round(ms / m) + 'm';\n  }\n  if (ms >= s) {\n    return Math.round(ms / s) + 's';\n  }\n  return ms + 'ms';\n}\n\n/**\n * Long format for `ms`.\n *\n * @api private\n * @param {number} ms\n * @return {string}\n */\nfunction longFormat(ms) {\n  return plural(ms, d, 'day')\n    || plural(ms, h, 'hour')\n    || plural(ms, m, 'minute')\n    || plural(ms, s, 'second')\n    || ms + ' ms';\n}\n\n/**\n * Pluralization helper.\n *\n * @api private\n * @param {number} ms\n * @param {number} n\n * @param {string} name\n */\nfunction plural(ms, n, name) {\n  if (ms < n) {\n    return;\n  }\n  if (ms < n * 1.5) {\n    return Math.floor(ms / n) + ' ' + name;\n  }\n  return Math.ceil(ms / n) + ' ' + name + 's';\n}\n\n},{}],16:[function(require,module,exports){\n\n/**\n * Expose `Pending`.\n */\n\nmodule.exports = Pending;\n\n/**\n * Initialize a new `Pending` error with the given message.\n *\n * @param {string} message\n */\nfunction Pending(message) {\n  this.message = message;\n}\n\n},{}],17:[function(require,module,exports){\n(function (process,global){\n/**\n * Module dependencies.\n */\n\nvar tty = require('tty');\nvar diff = require('diff');\nvar ms = require('../ms');\nvar utils = require('../utils');\nvar supportsColor = process.browser ? null : require('supports-color');\n\n/**\n * Expose `Base`.\n */\n\nexports = module.exports = Base;\n\n/**\n * Save timer references to avoid Sinon interfering.\n * See: https://github.com/mochajs/mocha/issues/237\n */\n\n/* eslint-disable no-unused-vars, no-native-reassign */\nvar Date = global.Date;\nvar setTimeout = global.setTimeout;\nvar setInterval = global.setInterval;\nvar clearTimeout = global.clearTimeout;\nvar clearInterval = global.clearInterval;\n/* eslint-enable no-unused-vars, no-native-reassign */\n\n/**\n * Check if both stdio streams are associated with a tty.\n */\n\nvar isatty = tty.isatty(1) && tty.isatty(2);\n\n/**\n * Enable coloring by default, except in the browser interface.\n */\n\nexports.useColors = !process.browser && (supportsColor || (process.env.MOCHA_COLORS !== undefined));\n\n/**\n * Inline diffs instead of +/-\n */\n\nexports.inlineDiffs = false;\n\n/**\n * Default color map.\n */\n\nexports.colors = {\n  pass: 90,\n  fail: 31,\n  'bright pass': 92,\n  'bright fail': 91,\n  'bright yellow': 93,\n  pending: 36,\n  suite: 0,\n  'error title': 0,\n  'error message': 31,\n  'error stack': 90,\n  checkmark: 32,\n  fast: 90,\n  medium: 33,\n  slow: 31,\n  green: 32,\n  light: 90,\n  'diff gutter': 90,\n  'diff added': 32,\n  'diff removed': 31\n};\n\n/**\n * Default symbol map.\n */\n\nexports.symbols = {\n  ok: '✓',\n  err: '✖',\n  dot: '․',\n  comma: ',',\n  bang: '!'\n};\n\n// With node.js on Windows: use symbols available in terminal default fonts\nif (process.platform === 'win32') {\n  exports.symbols.ok = '\\u221A';\n  exports.symbols.err = '\\u00D7';\n  exports.symbols.dot = '.';\n}\n\n/**\n * Color `str` with the given `type`,\n * allowing colors to be disabled,\n * as well as user-defined color\n * schemes.\n *\n * @param {string} type\n * @param {string} str\n * @return {string}\n * @api private\n */\nvar color = exports.color = function(type, str) {\n  if (!exports.useColors) {\n    return String(str);\n  }\n  return '\\u001b[' + exports.colors[type] + 'm' + str + '\\u001b[0m';\n};\n\n/**\n * Expose term window size, with some defaults for when stderr is not a tty.\n */\n\nexports.window = {\n  width: 75\n};\n\nif (isatty) {\n  exports.window.width = process.stdout.getWindowSize\n      ? process.stdout.getWindowSize(1)[0]\n      : tty.getWindowSize()[1];\n}\n\n/**\n * Expose some basic cursor interactions that are common among reporters.\n */\n\nexports.cursor = {\n  hide: function() {\n    isatty && process.stdout.write('\\u001b[?25l');\n  },\n\n  show: function() {\n    isatty && process.stdout.write('\\u001b[?25h');\n  },\n\n  deleteLine: function() {\n    isatty && process.stdout.write('\\u001b[2K');\n  },\n\n  beginningOfLine: function() {\n    isatty && process.stdout.write('\\u001b[0G');\n  },\n\n  CR: function() {\n    if (isatty) {\n      exports.cursor.deleteLine();\n      exports.cursor.beginningOfLine();\n    } else {\n      process.stdout.write('\\r');\n    }\n  }\n};\n\n/**\n * Outut the given `failures` as a list.\n *\n * @param {Array} failures\n * @api public\n */\n\nexports.list = function(failures) {\n  console.log();\n  failures.forEach(function(test, i) {\n    // format\n    var fmt = color('error title', '  %s) %s:\\n')\n      + color('error message', '     %s')\n      + color('error stack', '\\n%s\\n');\n\n    // msg\n    var msg;\n    var err = test.err;\n    var message;\n    if (err.message && typeof err.message.toString === 'function') {\n      message = err.message + '';\n    } else if (typeof err.inspect === 'function') {\n      message = err.inspect() + '';\n    } else {\n      message = '';\n    }\n    var stack = err.stack || message;\n    var index = message ? stack.indexOf(message) : -1;\n    var actual = err.actual;\n    var expected = err.expected;\n    var escape = true;\n\n    if (index === -1) {\n      msg = message;\n    } else {\n      index += message.length;\n      msg = stack.slice(0, index);\n      // remove msg from stack\n      stack = stack.slice(index + 1);\n    }\n\n    // uncaught\n    if (err.uncaught) {\n      msg = 'Uncaught ' + msg;\n    }\n    // explicitly show diff\n    if (err.showDiff !== false && sameType(actual, expected) && expected !== undefined) {\n      escape = false;\n      if (!(utils.isString(actual) && utils.isString(expected))) {\n        err.actual = actual = utils.stringify(actual);\n        err.expected = expected = utils.stringify(expected);\n      }\n\n      fmt = color('error title', '  %s) %s:\\n%s') + color('error stack', '\\n%s\\n');\n      var match = message.match(/^([^:]+): expected/);\n      msg = '\\n      ' + color('error message', match ? match[1] : msg);\n\n      if (exports.inlineDiffs) {\n        msg += inlineDiff(err, escape);\n      } else {\n        msg += unifiedDiff(err, escape);\n      }\n    }\n\n    // indent stack trace\n    stack = stack.replace(/^/gm, '  ');\n\n    console.log(fmt, (i + 1), test.fullTitle(), msg, stack);\n  });\n};\n\n/**\n * Initialize a new `Base` reporter.\n *\n * All other reporters generally\n * inherit from this reporter, providing\n * stats such as test duration, number\n * of tests passed / failed etc.\n *\n * @param {Runner} runner\n * @api public\n */\n\nfunction Base(runner) {\n  var stats = this.stats = { suites: 0, tests: 0, passes: 0, pending: 0, failures: 0 };\n  var failures = this.failures = [];\n\n  if (!runner) {\n    return;\n  }\n  this.runner = runner;\n\n  runner.stats = stats;\n\n  runner.on('start', function() {\n    stats.start = new Date();\n  });\n\n  runner.on('suite', function(suite) {\n    stats.suites = stats.suites || 0;\n    suite.root || stats.suites++;\n  });\n\n  runner.on('test end', function() {\n    stats.tests = stats.tests || 0;\n    stats.tests++;\n  });\n\n  runner.on('pass', function(test) {\n    stats.passes = stats.passes || 0;\n\n    if (test.duration > test.slow()) {\n      test.speed = 'slow';\n    } else if (test.duration > test.slow() / 2) {\n      test.speed = 'medium';\n    } else {\n      test.speed = 'fast';\n    }\n\n    stats.passes++;\n  });\n\n  runner.on('fail', function(test, err) {\n    stats.failures = stats.failures || 0;\n    stats.failures++;\n    test.err = err;\n    failures.push(test);\n  });\n\n  runner.on('end', function() {\n    stats.end = new Date();\n    stats.duration = new Date() - stats.start;\n  });\n\n  runner.on('pending', function() {\n    stats.pending++;\n  });\n}\n\n/**\n * Output common epilogue used by many of\n * the bundled reporters.\n *\n * @api public\n */\nBase.prototype.epilogue = function() {\n  var stats = this.stats;\n  var fmt;\n\n  console.log();\n\n  // passes\n  fmt = color('bright pass', ' ')\n    + color('green', ' %d passing')\n    + color('light', ' (%s)');\n\n  console.log(fmt,\n    stats.passes || 0,\n    ms(stats.duration));\n\n  // pending\n  if (stats.pending) {\n    fmt = color('pending', ' ')\n      + color('pending', ' %d pending');\n\n    console.log(fmt, stats.pending);\n  }\n\n  // failures\n  if (stats.failures) {\n    fmt = color('fail', '  %d failing');\n\n    console.log(fmt, stats.failures);\n\n    Base.list(this.failures);\n    console.log();\n  }\n\n  console.log();\n};\n\n/**\n * Pad the given `str` to `len`.\n *\n * @api private\n * @param {string} str\n * @param {string} len\n * @return {string}\n */\nfunction pad(str, len) {\n  str = String(str);\n  return Array(len - str.length + 1).join(' ') + str;\n}\n\n/**\n * Returns an inline diff between 2 strings with coloured ANSI output\n *\n * @api private\n * @param {Error} err with actual/expected\n * @param {boolean} escape\n * @return {string} Diff\n */\nfunction inlineDiff(err, escape) {\n  var msg = errorDiff(err, 'WordsWithSpace', escape);\n\n  // linenos\n  var lines = msg.split('\\n');\n  if (lines.length > 4) {\n    var width = String(lines.length).length;\n    msg = lines.map(function(str, i) {\n      return pad(++i, width) + ' |' + ' ' + str;\n    }).join('\\n');\n  }\n\n  // legend\n  msg = '\\n'\n    + color('diff removed', 'actual')\n    + ' '\n    + color('diff added', 'expected')\n    + '\\n\\n'\n    + msg\n    + '\\n';\n\n  // indent\n  msg = msg.replace(/^/gm, '      ');\n  return msg;\n}\n\n/**\n * Returns a unified diff between two strings.\n *\n * @api private\n * @param {Error} err with actual/expected\n * @param {boolean} escape\n * @return {string} The diff.\n */\nfunction unifiedDiff(err, escape) {\n  var indent = '      ';\n  function cleanUp(line) {\n    if (escape) {\n      line = escapeInvisibles(line);\n    }\n    if (line[0] === '+') {\n      return indent + colorLines('diff added', line);\n    }\n    if (line[0] === '-') {\n      return indent + colorLines('diff removed', line);\n    }\n    if (line.match(/\\@\\@/)) {\n      return null;\n    }\n    if (line.match(/\\\\ No newline/)) {\n      return null;\n    }\n    return indent + line;\n  }\n  function notBlank(line) {\n    return typeof line !== 'undefined' && line !== null;\n  }\n  var msg = diff.createPatch('string', err.actual, err.expected);\n  var lines = msg.split('\\n').splice(4);\n  return '\\n      '\n    + colorLines('diff added', '+ expected') + ' '\n    + colorLines('diff removed', '- actual')\n    + '\\n\\n'\n    + lines.map(cleanUp).filter(notBlank).join('\\n');\n}\n\n/**\n * Return a character diff for `err`.\n *\n * @api private\n * @param {Error} err\n * @param {string} type\n * @param {boolean} escape\n * @return {string}\n */\nfunction errorDiff(err, type, escape) {\n  var actual = escape ? escapeInvisibles(err.actual) : err.actual;\n  var expected = escape ? escapeInvisibles(err.expected) : err.expected;\n  return diff['diff' + type](actual, expected).map(function(str) {\n    if (str.added) {\n      return colorLines('diff added', str.value);\n    }\n    if (str.removed) {\n      return colorLines('diff removed', str.value);\n    }\n    return str.value;\n  }).join('');\n}\n\n/**\n * Returns a string with all invisible characters in plain text\n *\n * @api private\n * @param {string} line\n * @return {string}\n */\nfunction escapeInvisibles(line) {\n  return line.replace(/\\t/g, '<tab>')\n    .replace(/\\r/g, '<CR>')\n    .replace(/\\n/g, '<LF>\\n');\n}\n\n/**\n * Color lines for `str`, using the color `name`.\n *\n * @api private\n * @param {string} name\n * @param {string} str\n * @return {string}\n */\nfunction colorLines(name, str) {\n  return str.split('\\n').map(function(str) {\n    return color(name, str);\n  }).join('\\n');\n}\n\n/**\n * Object#toString reference.\n */\nvar objToString = Object.prototype.toString;\n\n/**\n * Check that a / b have the same type.\n *\n * @api private\n * @param {Object} a\n * @param {Object} b\n * @return {boolean}\n */\nfunction sameType(a, b) {\n  return objToString.call(a) === objToString.call(b);\n}\n\n}).call(this,require('_process'),typeof global !== \"undefined\" ? global : typeof self !== \"undefined\" ? self : typeof window !== \"undefined\" ? window : {})\n},{\"../ms\":15,\"../utils\":38,\"_process\":67,\"diff\":46,\"supports-color\":42,\"tty\":5}],18:[function(require,module,exports){\n/**\n * Module dependencies.\n */\n\nvar Base = require('./base');\nvar utils = require('../utils');\n\n/**\n * Expose `Doc`.\n */\n\nexports = module.exports = Doc;\n\n/**\n * Initialize a new `Doc` reporter.\n *\n * @param {Runner} runner\n * @api public\n */\nfunction Doc(runner) {\n  Base.call(this, runner);\n\n  var indents = 2;\n\n  function indent() {\n    return Array(indents).join('  ');\n  }\n\n  runner.on('suite', function(suite) {\n    if (suite.root) {\n      return;\n    }\n    ++indents;\n    console.log('%s<section class=\"suite\">', indent());\n    ++indents;\n    console.log('%s<h1>%s</h1>', indent(), utils.escape(suite.title));\n    console.log('%s<dl>', indent());\n  });\n\n  runner.on('suite end', function(suite) {\n    if (suite.root) {\n      return;\n    }\n    console.log('%s</dl>', indent());\n    --indents;\n    console.log('%s</section>', indent());\n    --indents;\n  });\n\n  runner.on('pass', function(test) {\n    console.log('%s  <dt>%s</dt>', indent(), utils.escape(test.title));\n    var code = utils.escape(utils.clean(test.body));\n    console.log('%s  <dd><pre><code>%s</code></pre></dd>', indent(), code);\n  });\n\n  runner.on('fail', function(test, err) {\n    console.log('%s  <dt class=\"error\">%s</dt>', indent(), utils.escape(test.title));\n    var code = utils.escape(utils.clean(test.body));\n    console.log('%s  <dd class=\"error\"><pre><code>%s</code></pre></dd>', indent(), code);\n    console.log('%s  <dd class=\"error\">%s</dd>', indent(), utils.escape(err));\n  });\n}\n\n},{\"../utils\":38,\"./base\":17}],19:[function(require,module,exports){\n(function (process){\n/**\n * Module dependencies.\n */\n\nvar Base = require('./base');\nvar inherits = require('../utils').inherits;\nvar color = Base.color;\n\n/**\n * Expose `Dot`.\n */\n\nexports = module.exports = Dot;\n\n/**\n * Initialize a new `Dot` matrix test reporter.\n *\n * @api public\n * @param {Runner} runner\n */\nfunction Dot(runner) {\n  Base.call(this, runner);\n\n  var self = this;\n  var width = Base.window.width * .75 | 0;\n  var n = -1;\n\n  runner.on('start', function() {\n    process.stdout.write('\\n');\n  });\n\n  runner.on('pending', function() {\n    if (++n % width === 0) {\n      process.stdout.write('\\n  ');\n    }\n    process.stdout.write(color('pending', Base.symbols.comma));\n  });\n\n  runner.on('pass', function(test) {\n    if (++n % width === 0) {\n      process.stdout.write('\\n  ');\n    }\n    if (test.speed === 'slow') {\n      process.stdout.write(color('bright yellow', Base.symbols.dot));\n    } else {\n      process.stdout.write(color(test.speed, Base.symbols.dot));\n    }\n  });\n\n  runner.on('fail', function() {\n    if (++n % width === 0) {\n      process.stdout.write('\\n  ');\n    }\n    process.stdout.write(color('fail', Base.symbols.bang));\n  });\n\n  runner.on('end', function() {\n    console.log();\n    self.epilogue();\n  });\n}\n\n/**\n * Inherit from `Base.prototype`.\n */\ninherits(Dot, Base);\n\n}).call(this,require('_process'))\n},{\"../utils\":38,\"./base\":17,\"_process\":67}],20:[function(require,module,exports){\n(function (global){\n/* eslint-env browser */\n\n/**\n * Module dependencies.\n */\n\nvar Base = require('./base');\nvar utils = require('../utils');\nvar Progress = require('../browser/progress');\nvar escapeRe = require('escape-string-regexp');\nvar escape = utils.escape;\n\n/**\n * Save timer references to avoid Sinon interfering (see GH-237).\n */\n\n/* eslint-disable no-unused-vars, no-native-reassign */\nvar Date = global.Date;\nvar setTimeout = global.setTimeout;\nvar setInterval = global.setInterval;\nvar clearTimeout = global.clearTimeout;\nvar clearInterval = global.clearInterval;\n/* eslint-enable no-unused-vars, no-native-reassign */\n\n/**\n * Expose `HTML`.\n */\n\nexports = module.exports = HTML;\n\n/**\n * Stats template.\n */\n\nvar statsTemplate = '<ul id=\"mocha-stats\">'\n  + '<li class=\"progress\"><canvas width=\"40\" height=\"40\"></canvas></li>'\n  + '<li class=\"passes\"><a href=\"javascript:void(0);\">passes:</a> <em>0</em></li>'\n  + '<li class=\"failures\"><a href=\"javascript:void(0);\">failures:</a> <em>0</em></li>'\n  + '<li class=\"duration\">duration: <em>0</em>s</li>'\n  + '</ul>';\n\n/**\n * Initialize a new `HTML` reporter.\n *\n * @api public\n * @param {Runner} runner\n */\nfunction HTML(runner) {\n  Base.call(this, runner);\n\n  var self = this;\n  var stats = this.stats;\n  var stat = fragment(statsTemplate);\n  var items = stat.getElementsByTagName('li');\n  var passes = items[1].getElementsByTagName('em')[0];\n  var passesLink = items[1].getElementsByTagName('a')[0];\n  var failures = items[2].getElementsByTagName('em')[0];\n  var failuresLink = items[2].getElementsByTagName('a')[0];\n  var duration = items[3].getElementsByTagName('em')[0];\n  var canvas = stat.getElementsByTagName('canvas')[0];\n  var report = fragment('<ul id=\"mocha-report\"></ul>');\n  var stack = [report];\n  var progress;\n  var ctx;\n  var root = document.getElementById('mocha');\n\n  if (canvas.getContext) {\n    var ratio = window.devicePixelRatio || 1;\n    canvas.style.width = canvas.width;\n    canvas.style.height = canvas.height;\n    canvas.width *= ratio;\n    canvas.height *= ratio;\n    ctx = canvas.getContext('2d');\n    ctx.scale(ratio, ratio);\n    progress = new Progress();\n  }\n\n  if (!root) {\n    return error('#mocha div missing, add it to your document');\n  }\n\n  // pass toggle\n  on(passesLink, 'click', function(evt) {\n    evt.preventDefault();\n    unhide();\n    var name = (/pass/).test(report.className) ? '' : ' pass';\n    report.className = report.className.replace(/fail|pass/g, '') + name;\n    if (report.className.trim()) {\n      hideSuitesWithout('test pass');\n    }\n  });\n\n  // failure toggle\n  on(failuresLink, 'click', function(evt) {\n    evt.preventDefault();\n    unhide();\n    var name = (/fail/).test(report.className) ? '' : ' fail';\n    report.className = report.className.replace(/fail|pass/g, '') + name;\n    if (report.className.trim()) {\n      hideSuitesWithout('test fail');\n    }\n  });\n\n  root.appendChild(stat);\n  root.appendChild(report);\n\n  if (progress) {\n    progress.size(40);\n  }\n\n  runner.on('suite', function(suite) {\n    if (suite.root) {\n      return;\n    }\n\n    // suite\n    var url = self.suiteURL(suite);\n    var el = fragment('<li class=\"suite\"><h1><a href=\"%s\">%s</a></h1></li>', url, escape(suite.title));\n\n    // container\n    stack[0].appendChild(el);\n    stack.unshift(document.createElement('ul'));\n    el.appendChild(stack[0]);\n  });\n\n  runner.on('suite end', function(suite) {\n    if (suite.root) {\n      updateStats();\n      return;\n    }\n    stack.shift();\n  });\n\n  runner.on('pass', function(test) {\n    var url = self.testURL(test);\n    var markup = '<li class=\"test pass %e\"><h2>%e<span class=\"duration\">%ems</span> '\n      + '<a href=\"%s\" class=\"replay\">‣</a></h2></li>';\n    var el = fragment(markup, test.speed, test.title, test.duration, url);\n    self.addCodeToggle(el, test.body);\n    appendToStack(el);\n    updateStats();\n  });\n\n  runner.on('fail', function(test) {\n    var el = fragment('<li class=\"test fail\"><h2>%e <a href=\"%e\" class=\"replay\">‣</a></h2></li>',\n      test.title, self.testURL(test));\n    var stackString; // Note: Includes leading newline\n    var message = test.err.toString();\n\n    // <=IE7 stringifies to [Object Error]. Since it can be overloaded, we\n    // check for the result of the stringifying.\n    if (message === '[object Error]') {\n      message = test.err.message;\n    }\n\n    if (test.err.stack) {\n      var indexOfMessage = test.err.stack.indexOf(test.err.message);\n      if (indexOfMessage === -1) {\n        stackString = test.err.stack;\n      } else {\n        stackString = test.err.stack.substr(test.err.message.length + indexOfMessage);\n      }\n    } else if (test.err.sourceURL && test.err.line !== undefined) {\n      // Safari doesn't give you a stack. Let's at least provide a source line.\n      stackString = '\\n(' + test.err.sourceURL + ':' + test.err.line + ')';\n    }\n\n    stackString = stackString || '';\n\n    if (test.err.htmlMessage && stackString) {\n      el.appendChild(fragment('<div class=\"html-error\">%s\\n<pre class=\"error\">%e</pre></div>',\n        test.err.htmlMessage, stackString));\n    } else if (test.err.htmlMessage) {\n      el.appendChild(fragment('<div class=\"html-error\">%s</div>', test.err.htmlMessage));\n    } else {\n      el.appendChild(fragment('<pre class=\"error\">%e%e</pre>', message, stackString));\n    }\n\n    self.addCodeToggle(el, test.body);\n    appendToStack(el);\n    updateStats();\n  });\n\n  runner.on('pending', function(test) {\n    var el = fragment('<li class=\"test pass pending\"><h2>%e</h2></li>', test.title);\n    appendToStack(el);\n    updateStats();\n  });\n\n  function appendToStack(el) {\n    // Don't call .appendChild if #mocha-report was already .shift()'ed off the stack.\n    if (stack[0]) {\n      stack[0].appendChild(el);\n    }\n  }\n\n  function updateStats() {\n    // TODO: add to stats\n    var percent = stats.tests / runner.total * 100 | 0;\n    if (progress) {\n      progress.update(percent).draw(ctx);\n    }\n\n    // update stats\n    var ms = new Date() - stats.start;\n    text(passes, stats.passes);\n    text(failures, stats.failures);\n    text(duration, (ms / 1000).toFixed(2));\n  }\n}\n\n/**\n * Makes a URL, preserving querystring (\"search\") parameters.\n *\n * @param {string} s\n * @return {string} A new URL.\n */\nfunction makeUrl(s) {\n  var search = window.location.search;\n\n  // Remove previous grep query parameter if present\n  if (search) {\n    search = search.replace(/[?&]grep=[^&\\s]*/g, '').replace(/^&/, '?');\n  }\n\n  return window.location.pathname + (search ? search + '&' : '?') + 'grep=' + encodeURIComponent(escapeRe(s));\n}\n\n/**\n * Provide suite URL.\n *\n * @param {Object} [suite]\n */\nHTML.prototype.suiteURL = function(suite) {\n  return makeUrl(suite.fullTitle());\n};\n\n/**\n * Provide test URL.\n *\n * @param {Object} [test]\n */\nHTML.prototype.testURL = function(test) {\n  return makeUrl(test.fullTitle());\n};\n\n/**\n * Adds code toggle functionality for the provided test's list element.\n *\n * @param {HTMLLIElement} el\n * @param {string} contents\n */\nHTML.prototype.addCodeToggle = function(el, contents) {\n  var h2 = el.getElementsByTagName('h2')[0];\n\n  on(h2, 'click', function() {\n    pre.style.display = pre.style.display === 'none' ? 'block' : 'none';\n  });\n\n  var pre = fragment('<pre><code>%e</code></pre>', utils.clean(contents));\n  el.appendChild(pre);\n  pre.style.display = 'none';\n};\n\n/**\n * Display error `msg`.\n *\n * @param {string} msg\n */\nfunction error(msg) {\n  document.body.appendChild(fragment('<div id=\"mocha-error\">%s</div>', msg));\n}\n\n/**\n * Return a DOM fragment from `html`.\n *\n * @param {string} html\n */\nfunction fragment(html) {\n  var args = arguments;\n  var div = document.createElement('div');\n  var i = 1;\n\n  div.innerHTML = html.replace(/%([se])/g, function(_, type) {\n    switch (type) {\n      case 's': return String(args[i++]);\n      case 'e': return escape(args[i++]);\n      // no default\n    }\n  });\n\n  return div.firstChild;\n}\n\n/**\n * Check for suites that do not have elements\n * with `classname`, and hide them.\n *\n * @param {text} classname\n */\nfunction hideSuitesWithout(classname) {\n  var suites = document.getElementsByClassName('suite');\n  for (var i = 0; i < suites.length; i++) {\n    var els = suites[i].getElementsByClassName(classname);\n    if (!els.length) {\n      suites[i].className += ' hidden';\n    }\n  }\n}\n\n/**\n * Unhide .hidden suites.\n */\nfunction unhide() {\n  var els = document.getElementsByClassName('suite hidden');\n  for (var i = 0; i < els.length; ++i) {\n    els[i].className = els[i].className.replace('suite hidden', 'suite');\n  }\n}\n\n/**\n * Set an element's text contents.\n *\n * @param {HTMLElement} el\n * @param {string} contents\n */\nfunction text(el, contents) {\n  if (el.textContent) {\n    el.textContent = contents;\n  } else {\n    el.innerText = contents;\n  }\n}\n\n/**\n * Listen on `event` with callback `fn`.\n */\nfunction on(el, event, fn) {\n  if (el.addEventListener) {\n    el.addEventListener(event, fn, false);\n  } else {\n    el.attachEvent('on' + event, fn);\n  }\n}\n\n}).call(this,typeof global !== \"undefined\" ? global : typeof self !== \"undefined\" ? self : typeof window !== \"undefined\" ? window : {})\n},{\"../browser/progress\":4,\"../utils\":38,\"./base\":17,\"escape-string-regexp\":47}],21:[function(require,module,exports){\n// Alias exports to a their normalized format Mocha#reporter to prevent a need\n// for dynamic (try/catch) requires, which Browserify doesn't handle.\nexports.Base = exports.base = require('./base');\nexports.Dot = exports.dot = require('./dot');\nexports.Doc = exports.doc = require('./doc');\nexports.TAP = exports.tap = require('./tap');\nexports.JSON = exports.json = require('./json');\nexports.HTML = exports.html = require('./html');\nexports.List = exports.list = require('./list');\nexports.Min = exports.min = require('./min');\nexports.Spec = exports.spec = require('./spec');\nexports.Nyan = exports.nyan = require('./nyan');\nexports.XUnit = exports.xunit = require('./xunit');\nexports.Markdown = exports.markdown = require('./markdown');\nexports.Progress = exports.progress = require('./progress');\nexports.Landing = exports.landing = require('./landing');\nexports.JSONStream = exports['json-stream'] = require('./json-stream');\n\n},{\"./base\":17,\"./doc\":18,\"./dot\":19,\"./html\":20,\"./json\":23,\"./json-stream\":22,\"./landing\":24,\"./list\":25,\"./markdown\":26,\"./min\":27,\"./nyan\":28,\"./progress\":29,\"./spec\":30,\"./tap\":31,\"./xunit\":32}],22:[function(require,module,exports){\n(function (process){\n/**\n * Module dependencies.\n */\n\nvar Base = require('./base');\nvar JSON = require('json3');\n\n/**\n * Expose `List`.\n */\n\nexports = module.exports = List;\n\n/**\n * Initialize a new `List` test reporter.\n *\n * @api public\n * @param {Runner} runner\n */\nfunction List(runner) {\n  Base.call(this, runner);\n\n  var self = this;\n  var total = runner.total;\n\n  runner.on('start', function() {\n    console.log(JSON.stringify(['start', { total: total }]));\n  });\n\n  runner.on('pass', function(test) {\n    console.log(JSON.stringify(['pass', clean(test)]));\n  });\n\n  runner.on('fail', function(test, err) {\n    test = clean(test);\n    test.err = err.message;\n    test.stack = err.stack || null;\n    console.log(JSON.stringify(['fail', test]));\n  });\n\n  runner.on('end', function() {\n    process.stdout.write(JSON.stringify(['end', self.stats]));\n  });\n}\n\n/**\n * Return a plain-object representation of `test`\n * free of cyclic properties etc.\n *\n * @api private\n * @param {Object} test\n * @return {Object}\n */\nfunction clean(test) {\n  return {\n    title: test.title,\n    fullTitle: test.fullTitle(),\n    duration: test.duration,\n    currentRetry: test.currentRetry()\n  };\n}\n\n}).call(this,require('_process'))\n},{\"./base\":17,\"_process\":67,\"json3\":54}],23:[function(require,module,exports){\n(function (process){\n/**\n * Module dependencies.\n */\n\nvar Base = require('./base');\n\n/**\n * Expose `JSON`.\n */\n\nexports = module.exports = JSONReporter;\n\n/**\n * Initialize a new `JSON` reporter.\n *\n * @api public\n * @param {Runner} runner\n */\nfunction JSONReporter(runner) {\n  Base.call(this, runner);\n\n  var self = this;\n  var tests = [];\n  var pending = [];\n  var failures = [];\n  var passes = [];\n\n  runner.on('test end', function(test) {\n    tests.push(test);\n  });\n\n  runner.on('pass', function(test) {\n    passes.push(test);\n  });\n\n  runner.on('fail', function(test) {\n    failures.push(test);\n  });\n\n  runner.on('pending', function(test) {\n    pending.push(test);\n  });\n\n  runner.on('end', function() {\n    var obj = {\n      stats: self.stats,\n      tests: tests.map(clean),\n      pending: pending.map(clean),\n      failures: failures.map(clean),\n      passes: passes.map(clean)\n    };\n\n    runner.testResults = obj;\n\n    process.stdout.write(JSON.stringify(obj, null, 2));\n  });\n}\n\n/**\n * Return a plain-object representation of `test`\n * free of cyclic properties etc.\n *\n * @api private\n * @param {Object} test\n * @return {Object}\n */\nfunction clean(test) {\n  return {\n    title: test.title,\n    fullTitle: test.fullTitle(),\n    duration: test.duration,\n    currentRetry: test.currentRetry(),\n    err: errorJSON(test.err || {})\n  };\n}\n\n/**\n * Transform `error` into a JSON object.\n *\n * @api private\n * @param {Error} err\n * @return {Object}\n */\nfunction errorJSON(err) {\n  var res = {};\n  Object.getOwnPropertyNames(err).forEach(function(key) {\n    res[key] = err[key];\n  }, err);\n  return res;\n}\n\n}).call(this,require('_process'))\n},{\"./base\":17,\"_process\":67}],24:[function(require,module,exports){\n(function (process){\n/**\n * Module dependencies.\n */\n\nvar Base = require('./base');\nvar inherits = require('../utils').inherits;\nvar cursor = Base.cursor;\nvar color = Base.color;\n\n/**\n * Expose `Landing`.\n */\n\nexports = module.exports = Landing;\n\n/**\n * Airplane color.\n */\n\nBase.colors.plane = 0;\n\n/**\n * Airplane crash color.\n */\n\nBase.colors['plane crash'] = 31;\n\n/**\n * Runway color.\n */\n\nBase.colors.runway = 90;\n\n/**\n * Initialize a new `Landing` reporter.\n *\n * @api public\n * @param {Runner} runner\n */\nfunction Landing(runner) {\n  Base.call(this, runner);\n\n  var self = this;\n  var width = Base.window.width * .75 | 0;\n  var total = runner.total;\n  var stream = process.stdout;\n  var plane = color('plane', '✈');\n  var crashed = -1;\n  var n = 0;\n\n  function runway() {\n    var buf = Array(width).join('-');\n    return '  ' + color('runway', buf);\n  }\n\n  runner.on('start', function() {\n    stream.write('\\n\\n\\n  ');\n    cursor.hide();\n  });\n\n  runner.on('test end', function(test) {\n    // check if the plane crashed\n    var col = crashed === -1 ? width * ++n / total | 0 : crashed;\n\n    // show the crash\n    if (test.state === 'failed') {\n      plane = color('plane crash', '✈');\n      crashed = col;\n    }\n\n    // render landing strip\n    stream.write('\\u001b[' + (width + 1) + 'D\\u001b[2A');\n    stream.write(runway());\n    stream.write('\\n  ');\n    stream.write(color('runway', Array(col).join('⋅')));\n    stream.write(plane);\n    stream.write(color('runway', Array(width - col).join('⋅') + '\\n'));\n    stream.write(runway());\n    stream.write('\\u001b[0m');\n  });\n\n  runner.on('end', function() {\n    cursor.show();\n    console.log();\n    self.epilogue();\n  });\n}\n\n/**\n * Inherit from `Base.prototype`.\n */\ninherits(Landing, Base);\n\n}).call(this,require('_process'))\n},{\"../utils\":38,\"./base\":17,\"_process\":67}],25:[function(require,module,exports){\n(function (process){\n/**\n * Module dependencies.\n */\n\nvar Base = require('./base');\nvar inherits = require('../utils').inherits;\nvar color = Base.color;\nvar cursor = Base.cursor;\n\n/**\n * Expose `List`.\n */\n\nexports = module.exports = List;\n\n/**\n * Initialize a new `List` test reporter.\n *\n * @api public\n * @param {Runner} runner\n */\nfunction List(runner) {\n  Base.call(this, runner);\n\n  var self = this;\n  var n = 0;\n\n  runner.on('start', function() {\n    console.log();\n  });\n\n  runner.on('test', function(test) {\n    process.stdout.write(color('pass', '    ' + test.fullTitle() + ': '));\n  });\n\n  runner.on('pending', function(test) {\n    var fmt = color('checkmark', '  -')\n      + color('pending', ' %s');\n    console.log(fmt, test.fullTitle());\n  });\n\n  runner.on('pass', function(test) {\n    var fmt = color('checkmark', '  ' + Base.symbols.dot)\n      + color('pass', ' %s: ')\n      + color(test.speed, '%dms');\n    cursor.CR();\n    console.log(fmt, test.fullTitle(), test.duration);\n  });\n\n  runner.on('fail', function(test) {\n    cursor.CR();\n    console.log(color('fail', '  %d) %s'), ++n, test.fullTitle());\n  });\n\n  runner.on('end', self.epilogue.bind(self));\n}\n\n/**\n * Inherit from `Base.prototype`.\n */\ninherits(List, Base);\n\n}).call(this,require('_process'))\n},{\"../utils\":38,\"./base\":17,\"_process\":67}],26:[function(require,module,exports){\n(function (process){\n/**\n * Module dependencies.\n */\n\nvar Base = require('./base');\nvar utils = require('../utils');\n\n/**\n * Constants\n */\n\nvar SUITE_PREFIX = '$';\n\n/**\n * Expose `Markdown`.\n */\n\nexports = module.exports = Markdown;\n\n/**\n * Initialize a new `Markdown` reporter.\n *\n * @api public\n * @param {Runner} runner\n */\nfunction Markdown(runner) {\n  Base.call(this, runner);\n\n  var level = 0;\n  var buf = '';\n\n  function title(str) {\n    return Array(level).join('#') + ' ' + str;\n  }\n\n  function mapTOC(suite, obj) {\n    var ret = obj;\n    var key = SUITE_PREFIX + suite.title;\n\n    obj = obj[key] = obj[key] || { suite: suite };\n    suite.suites.forEach(function(suite) {\n      mapTOC(suite, obj);\n    });\n\n    return ret;\n  }\n\n  function stringifyTOC(obj, level) {\n    ++level;\n    var buf = '';\n    var link;\n    for (var key in obj) {\n      if (key === 'suite') {\n        continue;\n      }\n      if (key !== SUITE_PREFIX) {\n        link = ' - [' + key.substring(1) + ']';\n        link += '(#' + utils.slug(obj[key].suite.fullTitle()) + ')\\n';\n        buf += Array(level).join('  ') + link;\n      }\n      buf += stringifyTOC(obj[key], level);\n    }\n    return buf;\n  }\n\n  function generateTOC(suite) {\n    var obj = mapTOC(suite, {});\n    return stringifyTOC(obj, 0);\n  }\n\n  generateTOC(runner.suite);\n\n  runner.on('suite', function(suite) {\n    ++level;\n    var slug = utils.slug(suite.fullTitle());\n    buf += '<a name=\"' + slug + '\"></a>' + '\\n';\n    buf += title(suite.title) + '\\n';\n  });\n\n  runner.on('suite end', function() {\n    --level;\n  });\n\n  runner.on('pass', function(test) {\n    var code = utils.clean(test.body);\n    buf += test.title + '.\\n';\n    buf += '\\n```js\\n';\n    buf += code + '\\n';\n    buf += '```\\n\\n';\n  });\n\n  runner.on('end', function() {\n    process.stdout.write('# TOC\\n');\n    process.stdout.write(generateTOC(runner.suite));\n    process.stdout.write(buf);\n  });\n}\n\n}).call(this,require('_process'))\n},{\"../utils\":38,\"./base\":17,\"_process\":67}],27:[function(require,module,exports){\n(function (process){\n/**\n * Module dependencies.\n */\n\nvar Base = require('./base');\nvar inherits = require('../utils').inherits;\n\n/**\n * Expose `Min`.\n */\n\nexports = module.exports = Min;\n\n/**\n * Initialize a new `Min` minimal test reporter (best used with --watch).\n *\n * @api public\n * @param {Runner} runner\n */\nfunction Min(runner) {\n  Base.call(this, runner);\n\n  runner.on('start', function() {\n    // clear screen\n    process.stdout.write('\\u001b[2J');\n    // set cursor position\n    process.stdout.write('\\u001b[1;3H');\n  });\n\n  runner.on('end', this.epilogue.bind(this));\n}\n\n/**\n * Inherit from `Base.prototype`.\n */\ninherits(Min, Base);\n\n}).call(this,require('_process'))\n},{\"../utils\":38,\"./base\":17,\"_process\":67}],28:[function(require,module,exports){\n(function (process){\n/**\n * Module dependencies.\n */\n\nvar Base = require('./base');\nvar inherits = require('../utils').inherits;\n\n/**\n * Expose `Dot`.\n */\n\nexports = module.exports = NyanCat;\n\n/**\n * Initialize a new `Dot` matrix test reporter.\n *\n * @param {Runner} runner\n * @api public\n */\n\nfunction NyanCat(runner) {\n  Base.call(this, runner);\n\n  var self = this;\n  var width = Base.window.width * .75 | 0;\n  var nyanCatWidth = this.nyanCatWidth = 11;\n\n  this.colorIndex = 0;\n  this.numberOfLines = 4;\n  this.rainbowColors = self.generateColors();\n  this.scoreboardWidth = 5;\n  this.tick = 0;\n  this.trajectories = [[], [], [], []];\n  this.trajectoryWidthMax = (width - nyanCatWidth);\n\n  runner.on('start', function() {\n    Base.cursor.hide();\n    self.draw();\n  });\n\n  runner.on('pending', function() {\n    self.draw();\n  });\n\n  runner.on('pass', function() {\n    self.draw();\n  });\n\n  runner.on('fail', function() {\n    self.draw();\n  });\n\n  runner.on('end', function() {\n    Base.cursor.show();\n    for (var i = 0; i < self.numberOfLines; i++) {\n      write('\\n');\n    }\n    self.epilogue();\n  });\n}\n\n/**\n * Inherit from `Base.prototype`.\n */\ninherits(NyanCat, Base);\n\n/**\n * Draw the nyan cat\n *\n * @api private\n */\n\nNyanCat.prototype.draw = function() {\n  this.appendRainbow();\n  this.drawScoreboard();\n  this.drawRainbow();\n  this.drawNyanCat();\n  this.tick = !this.tick;\n};\n\n/**\n * Draw the \"scoreboard\" showing the number\n * of passes, failures and pending tests.\n *\n * @api private\n */\n\nNyanCat.prototype.drawScoreboard = function() {\n  var stats = this.stats;\n\n  function draw(type, n) {\n    write(' ');\n    write(Base.color(type, n));\n    write('\\n');\n  }\n\n  draw('green', stats.passes);\n  draw('fail', stats.failures);\n  draw('pending', stats.pending);\n  write('\\n');\n\n  this.cursorUp(this.numberOfLines);\n};\n\n/**\n * Append the rainbow.\n *\n * @api private\n */\n\nNyanCat.prototype.appendRainbow = function() {\n  var segment = this.tick ? '_' : '-';\n  var rainbowified = this.rainbowify(segment);\n\n  for (var index = 0; index < this.numberOfLines; index++) {\n    var trajectory = this.trajectories[index];\n    if (trajectory.length >= this.trajectoryWidthMax) {\n      trajectory.shift();\n    }\n    trajectory.push(rainbowified);\n  }\n};\n\n/**\n * Draw the rainbow.\n *\n * @api private\n */\n\nNyanCat.prototype.drawRainbow = function() {\n  var self = this;\n\n  this.trajectories.forEach(function(line) {\n    write('\\u001b[' + self.scoreboardWidth + 'C');\n    write(line.join(''));\n    write('\\n');\n  });\n\n  this.cursorUp(this.numberOfLines);\n};\n\n/**\n * Draw the nyan cat\n *\n * @api private\n */\nNyanCat.prototype.drawNyanCat = function() {\n  var self = this;\n  var startWidth = this.scoreboardWidth + this.trajectories[0].length;\n  var dist = '\\u001b[' + startWidth + 'C';\n  var padding = '';\n\n  write(dist);\n  write('_,------,');\n  write('\\n');\n\n  write(dist);\n  padding = self.tick ? '  ' : '   ';\n  write('_|' + padding + '/\\\\_/\\\\ ');\n  write('\\n');\n\n  write(dist);\n  padding = self.tick ? '_' : '__';\n  var tail = self.tick ? '~' : '^';\n  write(tail + '|' + padding + this.face() + ' ');\n  write('\\n');\n\n  write(dist);\n  padding = self.tick ? ' ' : '  ';\n  write(padding + '\"\"  \"\" ');\n  write('\\n');\n\n  this.cursorUp(this.numberOfLines);\n};\n\n/**\n * Draw nyan cat face.\n *\n * @api private\n * @return {string}\n */\n\nNyanCat.prototype.face = function() {\n  var stats = this.stats;\n  if (stats.failures) {\n    return '( x .x)';\n  } else if (stats.pending) {\n    return '( o .o)';\n  } else if (stats.passes) {\n    return '( ^ .^)';\n  }\n  return '( - .-)';\n};\n\n/**\n * Move cursor up `n`.\n *\n * @api private\n * @param {number} n\n */\n\nNyanCat.prototype.cursorUp = function(n) {\n  write('\\u001b[' + n + 'A');\n};\n\n/**\n * Move cursor down `n`.\n *\n * @api private\n * @param {number} n\n */\n\nNyanCat.prototype.cursorDown = function(n) {\n  write('\\u001b[' + n + 'B');\n};\n\n/**\n * Generate rainbow colors.\n *\n * @api private\n * @return {Array}\n */\nNyanCat.prototype.generateColors = function() {\n  var colors = [];\n\n  for (var i = 0; i < (6 * 7); i++) {\n    var pi3 = Math.floor(Math.PI / 3);\n    var n = (i * (1.0 / 6));\n    var r = Math.floor(3 * Math.sin(n) + 3);\n    var g = Math.floor(3 * Math.sin(n + 2 * pi3) + 3);\n    var b = Math.floor(3 * Math.sin(n + 4 * pi3) + 3);\n    colors.push(36 * r + 6 * g + b + 16);\n  }\n\n  return colors;\n};\n\n/**\n * Apply rainbow to the given `str`.\n *\n * @api private\n * @param {string} str\n * @return {string}\n */\nNyanCat.prototype.rainbowify = function(str) {\n  if (!Base.useColors) {\n    return str;\n  }\n  var color = this.rainbowColors[this.colorIndex % this.rainbowColors.length];\n  this.colorIndex += 1;\n  return '\\u001b[38;5;' + color + 'm' + str + '\\u001b[0m';\n};\n\n/**\n * Stdout helper.\n *\n * @param {string} string A message to write to stdout.\n */\nfunction write(string) {\n  process.stdout.write(string);\n}\n\n}).call(this,require('_process'))\n},{\"../utils\":38,\"./base\":17,\"_process\":67}],29:[function(require,module,exports){\n(function (process){\n/**\n * Module dependencies.\n */\n\nvar Base = require('./base');\nvar inherits = require('../utils').inherits;\nvar color = Base.color;\nvar cursor = Base.cursor;\n\n/**\n * Expose `Progress`.\n */\n\nexports = module.exports = Progress;\n\n/**\n * General progress bar color.\n */\n\nBase.colors.progress = 90;\n\n/**\n * Initialize a new `Progress` bar test reporter.\n *\n * @api public\n * @param {Runner} runner\n * @param {Object} options\n */\nfunction Progress(runner, options) {\n  Base.call(this, runner);\n\n  var self = this;\n  var width = Base.window.width * .50 | 0;\n  var total = runner.total;\n  var complete = 0;\n  var lastN = -1;\n\n  // default chars\n  options = options || {};\n  options.open = options.open || '[';\n  options.complete = options.complete || '▬';\n  options.incomplete = options.incomplete || Base.symbols.dot;\n  options.close = options.close || ']';\n  options.verbose = false;\n\n  // tests started\n  runner.on('start', function() {\n    console.log();\n    cursor.hide();\n  });\n\n  // tests complete\n  runner.on('test end', function() {\n    complete++;\n\n    var percent = complete / total;\n    var n = width * percent | 0;\n    var i = width - n;\n\n    if (n === lastN && !options.verbose) {\n      // Don't re-render the line if it hasn't changed\n      return;\n    }\n    lastN = n;\n\n    cursor.CR();\n    process.stdout.write('\\u001b[J');\n    process.stdout.write(color('progress', '  ' + options.open));\n    process.stdout.write(Array(n).join(options.complete));\n    process.stdout.write(Array(i).join(options.incomplete));\n    process.stdout.write(color('progress', options.close));\n    if (options.verbose) {\n      process.stdout.write(color('progress', ' ' + complete + ' of ' + total));\n    }\n  });\n\n  // tests are complete, output some stats\n  // and the failures if any\n  runner.on('end', function() {\n    cursor.show();\n    console.log();\n    self.epilogue();\n  });\n}\n\n/**\n * Inherit from `Base.prototype`.\n */\ninherits(Progress, Base);\n\n}).call(this,require('_process'))\n},{\"../utils\":38,\"./base\":17,\"_process\":67}],30:[function(require,module,exports){\n/**\n * Module dependencies.\n */\n\nvar Base = require('./base');\nvar inherits = require('../utils').inherits;\nvar color = Base.color;\n\n/**\n * Expose `Spec`.\n */\n\nexports = module.exports = Spec;\n\n/**\n * Initialize a new `Spec` test reporter.\n *\n * @api public\n * @param {Runner} runner\n */\nfunction Spec(runner) {\n  Base.call(this, runner);\n\n  var self = this;\n  var indents = 0;\n  var n = 0;\n\n  function indent() {\n    return Array(indents).join('  ');\n  }\n\n  runner.on('start', function() {\n    console.log();\n  });\n\n  runner.on('suite', function(suite) {\n    ++indents;\n    console.log(color('suite', '%s%s'), indent(), suite.title);\n  });\n\n  runner.on('suite end', function() {\n    --indents;\n    if (indents === 1) {\n      console.log();\n    }\n  });\n\n  runner.on('pending', function(test) {\n    var fmt = indent() + color('pending', '  - %s');\n    console.log(fmt, test.title);\n  });\n\n  runner.on('pass', function(test) {\n    var fmt;\n    if (test.speed === 'fast') {\n      fmt = indent()\n        + color('checkmark', '  ' + Base.symbols.ok)\n        + color('pass', ' %s');\n      console.log(fmt, test.title);\n    } else {\n      fmt = indent()\n        + color('checkmark', '  ' + Base.symbols.ok)\n        + color('pass', ' %s')\n        + color(test.speed, ' (%dms)');\n      console.log(fmt, test.title, test.duration);\n    }\n  });\n\n  runner.on('fail', function(test) {\n    console.log(indent() + color('fail', '  %d) %s'), ++n, test.title);\n  });\n\n  runner.on('end', self.epilogue.bind(self));\n}\n\n/**\n * Inherit from `Base.prototype`.\n */\ninherits(Spec, Base);\n\n},{\"../utils\":38,\"./base\":17}],31:[function(require,module,exports){\n/**\n * Module dependencies.\n */\n\nvar Base = require('./base');\n\n/**\n * Expose `TAP`.\n */\n\nexports = module.exports = TAP;\n\n/**\n * Initialize a new `TAP` reporter.\n *\n * @api public\n * @param {Runner} runner\n */\nfunction TAP(runner) {\n  Base.call(this, runner);\n\n  var n = 1;\n  var passes = 0;\n  var failures = 0;\n\n  runner.on('start', function() {\n    var total = runner.grepTotal(runner.suite);\n    console.log('%d..%d', 1, total);\n  });\n\n  runner.on('test end', function() {\n    ++n;\n  });\n\n  runner.on('pending', function(test) {\n    console.log('ok %d %s # SKIP -', n, title(test));\n  });\n\n  runner.on('pass', function(test) {\n    passes++;\n    console.log('ok %d %s', n, title(test));\n  });\n\n  runner.on('fail', function(test, err) {\n    failures++;\n    console.log('not ok %d %s', n, title(test));\n    if (err.stack) {\n      console.log(err.stack.replace(/^/gm, '  '));\n    }\n  });\n\n  runner.on('end', function() {\n    console.log('# tests ' + (passes + failures));\n    console.log('# pass ' + passes);\n    console.log('# fail ' + failures);\n  });\n}\n\n/**\n * Return a TAP-safe title of `test`\n *\n * @api private\n * @param {Object} test\n * @return {String}\n */\nfunction title(test) {\n  return test.fullTitle().replace(/#/g, '');\n}\n\n},{\"./base\":17}],32:[function(require,module,exports){\n(function (process,global){\n/**\n * Module dependencies.\n */\n\nvar Base = require('./base');\nvar utils = require('../utils');\nvar inherits = utils.inherits;\nvar fs = require('fs');\nvar escape = utils.escape;\nvar mkdirp = require('mkdirp');\nvar path = require('path');\n\n/**\n * Save timer references to avoid Sinon interfering (see GH-237).\n */\n\n/* eslint-disable no-unused-vars, no-native-reassign */\nvar Date = global.Date;\nvar setTimeout = global.setTimeout;\nvar setInterval = global.setInterval;\nvar clearTimeout = global.clearTimeout;\nvar clearInterval = global.clearInterval;\n/* eslint-enable no-unused-vars, no-native-reassign */\n\n/**\n * Expose `XUnit`.\n */\n\nexports = module.exports = XUnit;\n\n/**\n * Initialize a new `XUnit` reporter.\n *\n * @api public\n * @param {Runner} runner\n */\nfunction XUnit(runner, options) {\n  Base.call(this, runner);\n\n  var stats = this.stats;\n  var tests = [];\n  var self = this;\n\n  if (options.reporterOptions && options.reporterOptions.output) {\n    if (!fs.createWriteStream) {\n      throw new Error('file output not supported in browser');\n    }\n    mkdirp.sync(path.dirname(options.reporterOptions.output));\n    self.fileStream = fs.createWriteStream(options.reporterOptions.output);\n  }\n\n  runner.on('pending', function(test) {\n    tests.push(test);\n  });\n\n  runner.on('pass', function(test) {\n    tests.push(test);\n  });\n\n  runner.on('fail', function(test) {\n    tests.push(test);\n  });\n\n  runner.on('end', function() {\n    self.write(tag('testsuite', {\n      name: 'Mocha Tests',\n      tests: stats.tests,\n      failures: stats.failures,\n      errors: stats.failures,\n      skipped: stats.tests - stats.failures - stats.passes,\n      timestamp: (new Date()).toUTCString(),\n      time: (stats.duration / 1000) || 0\n    }, false));\n\n    tests.forEach(function(t) {\n      self.test(t);\n    });\n\n    self.write('</testsuite>');\n  });\n}\n\n/**\n * Inherit from `Base.prototype`.\n */\ninherits(XUnit, Base);\n\n/**\n * Override done to close the stream (if it's a file).\n *\n * @param failures\n * @param {Function} fn\n */\nXUnit.prototype.done = function(failures, fn) {\n  if (this.fileStream) {\n    this.fileStream.end(function() {\n      fn(failures);\n    });\n  } else {\n    fn(failures);\n  }\n};\n\n/**\n * Write out the given line.\n *\n * @param {string} line\n */\nXUnit.prototype.write = function(line) {\n  if (this.fileStream) {\n    this.fileStream.write(line + '\\n');\n  } else if (typeof process === 'object' && process.stdout) {\n    process.stdout.write(line + '\\n');\n  } else {\n    console.log(line);\n  }\n};\n\n/**\n * Output tag for the given `test.`\n *\n * @param {Test} test\n */\nXUnit.prototype.test = function(test) {\n  var attrs = {\n    classname: test.parent.fullTitle(),\n    name: test.title,\n    time: (test.duration / 1000) || 0\n  };\n\n  if (test.state === 'failed') {\n    var err = test.err;\n    this.write(tag('testcase', attrs, false, tag('failure', {}, false, escape(err.message) + '\\n' + escape(err.stack))));\n  } else if (test.isPending()) {\n    this.write(tag('testcase', attrs, false, tag('skipped', {}, true)));\n  } else {\n    this.write(tag('testcase', attrs, true));\n  }\n};\n\n/**\n * HTML tag helper.\n *\n * @param name\n * @param attrs\n * @param close\n * @param content\n * @return {string}\n */\nfunction tag(name, attrs, close, content) {\n  var end = close ? '/>' : '>';\n  var pairs = [];\n  var tag;\n\n  for (var key in attrs) {\n    if (Object.prototype.hasOwnProperty.call(attrs, key)) {\n      pairs.push(key + '=\"' + escape(attrs[key]) + '\"');\n    }\n  }\n\n  tag = '<' + name + (pairs.length ? ' ' + pairs.join(' ') : '') + end;\n  if (content) {\n    tag += content + '</' + name + end;\n  }\n  return tag;\n}\n\n}).call(this,require('_process'),typeof global !== \"undefined\" ? global : typeof self !== \"undefined\" ? self : typeof window !== \"undefined\" ? window : {})\n},{\"../utils\":38,\"./base\":17,\"_process\":67,\"fs\":42,\"mkdirp\":64,\"path\":42}],33:[function(require,module,exports){\n(function (global){\n/**\n * Module dependencies.\n */\n\nvar EventEmitter = require('events').EventEmitter;\nvar JSON = require('json3');\nvar Pending = require('./pending');\nvar debug = require('debug')('mocha:runnable');\nvar milliseconds = require('./ms');\nvar utils = require('./utils');\nvar create = require('lodash.create');\n\n/**\n * Save timer references to avoid Sinon interfering (see GH-237).\n */\n\n/* eslint-disable no-unused-vars, no-native-reassign */\nvar Date = global.Date;\nvar setTimeout = global.setTimeout;\nvar setInterval = global.setInterval;\nvar clearTimeout = global.clearTimeout;\nvar clearInterval = global.clearInterval;\n/* eslint-enable no-unused-vars, no-native-reassign */\n\n/**\n * Object#toString().\n */\n\nvar toString = Object.prototype.toString;\n\n/**\n * Expose `Runnable`.\n */\n\nmodule.exports = Runnable;\n\n/**\n * Initialize a new `Runnable` with the given `title` and callback `fn`.\n *\n * @param {String} title\n * @param {Function} fn\n * @api private\n * @param {string} title\n * @param {Function} fn\n */\nfunction Runnable(title, fn) {\n  this.title = title;\n  this.fn = fn;\n  this.body = (fn || '').toString();\n  this.async = fn && fn.length;\n  this.sync = !this.async;\n  this._timeout = 2000;\n  this._slow = 75;\n  this._enableTimeouts = true;\n  this.timedOut = false;\n  this._trace = new Error('done() called multiple times');\n  this._retries = -1;\n  this._currentRetry = 0;\n  this.pending = false;\n}\n\n/**\n * Inherit from `EventEmitter.prototype`.\n */\nRunnable.prototype = create(EventEmitter.prototype, {\n  constructor: Runnable\n});\n\n/**\n * Set & get timeout `ms`.\n *\n * @api private\n * @param {number|string} ms\n * @return {Runnable|number} ms or Runnable instance.\n */\nRunnable.prototype.timeout = function(ms) {\n  if (!arguments.length) {\n    return this._timeout;\n  }\n  // see #1652 for reasoning\n  if (ms === 0 || ms > Math.pow(2, 31)) {\n    this._enableTimeouts = false;\n  }\n  if (typeof ms === 'string') {\n    ms = milliseconds(ms);\n  }\n  debug('timeout %d', ms);\n  this._timeout = ms;\n  if (this.timer) {\n    this.resetTimeout();\n  }\n  return this;\n};\n\n/**\n * Set & get slow `ms`.\n *\n * @api private\n * @param {number|string} ms\n * @return {Runnable|number} ms or Runnable instance.\n */\nRunnable.prototype.slow = function(ms) {\n  if (typeof ms === 'undefined') {\n    return this._slow;\n  }\n  if (typeof ms === 'string') {\n    ms = milliseconds(ms);\n  }\n  debug('timeout %d', ms);\n  this._slow = ms;\n  return this;\n};\n\n/**\n * Set and get whether timeout is `enabled`.\n *\n * @api private\n * @param {boolean} enabled\n * @return {Runnable|boolean} enabled or Runnable instance.\n */\nRunnable.prototype.enableTimeouts = function(enabled) {\n  if (!arguments.length) {\n    return this._enableTimeouts;\n  }\n  debug('enableTimeouts %s', enabled);\n  this._enableTimeouts = enabled;\n  return this;\n};\n\n/**\n * Halt and mark as pending.\n *\n * @api public\n */\nRunnable.prototype.skip = function() {\n  throw new Pending('sync skip');\n};\n\n/**\n * Check if this runnable or its parent suite is marked as pending.\n *\n * @api private\n */\nRunnable.prototype.isPending = function() {\n  return this.pending || (this.parent && this.parent.isPending());\n};\n\n/**\n * Set number of retries.\n *\n * @api private\n */\nRunnable.prototype.retries = function(n) {\n  if (!arguments.length) {\n    return this._retries;\n  }\n  this._retries = n;\n};\n\n/**\n * Get current retry\n *\n * @api private\n */\nRunnable.prototype.currentRetry = function(n) {\n  if (!arguments.length) {\n    return this._currentRetry;\n  }\n  this._currentRetry = n;\n};\n\n/**\n * Return the full title generated by recursively concatenating the parent's\n * full title.\n *\n * @api public\n * @return {string}\n */\nRunnable.prototype.fullTitle = function() {\n  return this.parent.fullTitle() + ' ' + this.title;\n};\n\n/**\n * Clear the timeout.\n *\n * @api private\n */\nRunnable.prototype.clearTimeout = function() {\n  clearTimeout(this.timer);\n};\n\n/**\n * Inspect the runnable void of private properties.\n *\n * @api private\n * @return {string}\n */\nRunnable.prototype.inspect = function() {\n  return JSON.stringify(this, function(key, val) {\n    if (key[0] === '_') {\n      return;\n    }\n    if (key === 'parent') {\n      return '#<Suite>';\n    }\n    if (key === 'ctx') {\n      return '#<Context>';\n    }\n    return val;\n  }, 2);\n};\n\n/**\n * Reset the timeout.\n *\n * @api private\n */\nRunnable.prototype.resetTimeout = function() {\n  var self = this;\n  var ms = this.timeout() || 1e9;\n\n  if (!this._enableTimeouts) {\n    return;\n  }\n  this.clearTimeout();\n  this.timer = setTimeout(function() {\n    if (!self._enableTimeouts) {\n      return;\n    }\n    self.callback(new Error('timeout of ' + ms + 'ms exceeded. Ensure the done() callback is being called in this test.'));\n    self.timedOut = true;\n  }, ms);\n};\n\n/**\n * Whitelist a list of globals for this test run.\n *\n * @api private\n * @param {string[]} globals\n */\nRunnable.prototype.globals = function(globals) {\n  if (!arguments.length) {\n    return this._allowedGlobals;\n  }\n  this._allowedGlobals = globals;\n};\n\n/**\n * Run the test and invoke `fn(err)`.\n *\n * @param {Function} fn\n * @api private\n */\nRunnable.prototype.run = function(fn) {\n  var self = this;\n  var start = new Date();\n  var ctx = this.ctx;\n  var finished;\n  var emitted;\n\n  // Sometimes the ctx exists, but it is not runnable\n  if (ctx && ctx.runnable) {\n    ctx.runnable(this);\n  }\n\n  // called multiple times\n  function multiple(err) {\n    if (emitted) {\n      return;\n    }\n    emitted = true;\n    self.emit('error', err || new Error('done() called multiple times; stacktrace may be inaccurate'));\n  }\n\n  // finished\n  function done(err) {\n    var ms = self.timeout();\n    if (self.timedOut) {\n      return;\n    }\n    if (finished) {\n      return multiple(err || self._trace);\n    }\n\n    self.clearTimeout();\n    self.duration = new Date() - start;\n    finished = true;\n    if (!err && self.duration > ms && self._enableTimeouts) {\n      err = new Error('timeout of ' + ms + 'ms exceeded. Ensure the done() callback is being called in this test.');\n    }\n    fn(err);\n  }\n\n  // for .resetTimeout()\n  this.callback = done;\n\n  // explicit async with `done` argument\n  if (this.async) {\n    this.resetTimeout();\n\n    // allows skip() to be used in an explicit async context\n    this.skip = function asyncSkip() {\n      done(new Pending('async skip call'));\n      // halt execution.  the Runnable will be marked pending\n      // by the previous call, and the uncaught handler will ignore\n      // the failure.\n      throw new Pending('async skip; aborting execution');\n    };\n\n    if (this.allowUncaught) {\n      return callFnAsync(this.fn);\n    }\n    try {\n      callFnAsync(this.fn);\n    } catch (err) {\n      done(utils.getError(err));\n    }\n    return;\n  }\n\n  if (this.allowUncaught) {\n    callFn(this.fn);\n    done();\n    return;\n  }\n\n  // sync or promise-returning\n  try {\n    if (this.isPending()) {\n      done();\n    } else {\n      callFn(this.fn);\n    }\n  } catch (err) {\n    done(utils.getError(err));\n  }\n\n  function callFn(fn) {\n    var result = fn.call(ctx);\n    if (result && typeof result.then === 'function') {\n      self.resetTimeout();\n      result\n        .then(function() {\n          done();\n          // Return null so libraries like bluebird do not warn about\n          // subsequently constructed Promises.\n          return null;\n        },\n        function(reason) {\n          done(reason || new Error('Promise rejected with no or falsy reason'));\n        });\n    } else {\n      if (self.asyncOnly) {\n        return done(new Error('--async-only option in use without declaring `done()` or returning a promise'));\n      }\n\n      done();\n    }\n  }\n\n  function callFnAsync(fn) {\n    var result = fn.call(ctx, function(err) {\n      if (err instanceof Error || toString.call(err) === '[object Error]') {\n        return done(err);\n      }\n      if (err) {\n        if (Object.prototype.toString.call(err) === '[object Object]') {\n          return done(new Error('done() invoked with non-Error: '\n            + JSON.stringify(err)));\n        }\n        return done(new Error('done() invoked with non-Error: ' + err));\n      }\n      if (result && utils.isPromise(result)) {\n        return done(new Error('Resolution method is overspecified. Specify a callback *or* return a Promise; not both.'));\n      }\n\n      done();\n    });\n  }\n};\n\n}).call(this,typeof global !== \"undefined\" ? global : typeof self !== \"undefined\" ? self : typeof window !== \"undefined\" ? window : {})\n},{\"./ms\":15,\"./pending\":16,\"./utils\":38,\"debug\":2,\"events\":3,\"json3\":54,\"lodash.create\":60}],34:[function(require,module,exports){\n(function (process,global){\n/**\n * Module dependencies.\n */\n\nvar EventEmitter = require('events').EventEmitter;\nvar Pending = require('./pending');\nvar utils = require('./utils');\nvar inherits = utils.inherits;\nvar debug = require('debug')('mocha:runner');\nvar Runnable = require('./runnable');\nvar filter = utils.filter;\nvar indexOf = utils.indexOf;\nvar some = utils.some;\nvar keys = utils.keys;\nvar stackFilter = utils.stackTraceFilter();\nvar stringify = utils.stringify;\nvar type = utils.type;\nvar undefinedError = utils.undefinedError;\nvar isArray = utils.isArray;\n\n/**\n * Non-enumerable globals.\n */\n\nvar globals = [\n  'setTimeout',\n  'clearTimeout',\n  'setInterval',\n  'clearInterval',\n  'XMLHttpRequest',\n  'Date',\n  'setImmediate',\n  'clearImmediate'\n];\n\n/**\n * Expose `Runner`.\n */\n\nmodule.exports = Runner;\n\n/**\n * Initialize a `Runner` for the given `suite`.\n *\n * Events:\n *\n *   - `start`  execution started\n *   - `end`  execution complete\n *   - `suite`  (suite) test suite execution started\n *   - `suite end`  (suite) all tests (and sub-suites) have finished\n *   - `test`  (test) test execution started\n *   - `test end`  (test) test completed\n *   - `hook`  (hook) hook execution started\n *   - `hook end`  (hook) hook complete\n *   - `pass`  (test) test passed\n *   - `fail`  (test, err) test failed\n *   - `pending`  (test) test pending\n *\n * @api public\n * @param {Suite} suite Root suite\n * @param {boolean} [delay] Whether or not to delay execution of root suite\n * until ready.\n */\nfunction Runner(suite, delay) {\n  var self = this;\n  this._globals = [];\n  this._abort = false;\n  this._delay = delay;\n  this.suite = suite;\n  this.started = false;\n  this.total = suite.total();\n  this.failures = 0;\n  this.on('test end', function(test) {\n    self.checkGlobals(test);\n  });\n  this.on('hook end', function(hook) {\n    self.checkGlobals(hook);\n  });\n  this._defaultGrep = /.*/;\n  this.grep(this._defaultGrep);\n  this.globals(this.globalProps().concat(extraGlobals()));\n}\n\n/**\n * Wrapper for setImmediate, process.nextTick, or browser polyfill.\n *\n * @param {Function} fn\n * @api private\n */\nRunner.immediately = global.setImmediate || process.nextTick;\n\n/**\n * Inherit from `EventEmitter.prototype`.\n */\ninherits(Runner, EventEmitter);\n\n/**\n * Run tests with full titles matching `re`. Updates runner.total\n * with number of tests matched.\n *\n * @param {RegExp} re\n * @param {Boolean} invert\n * @return {Runner} for chaining\n * @api public\n * @param {RegExp} re\n * @param {boolean} invert\n * @return {Runner} Runner instance.\n */\nRunner.prototype.grep = function(re, invert) {\n  debug('grep %s', re);\n  this._grep = re;\n  this._invert = invert;\n  this.total = this.grepTotal(this.suite);\n  return this;\n};\n\n/**\n * Returns the number of tests matching the grep search for the\n * given suite.\n *\n * @param {Suite} suite\n * @return {Number}\n * @api public\n * @param {Suite} suite\n * @return {number}\n */\nRunner.prototype.grepTotal = function(suite) {\n  var self = this;\n  var total = 0;\n\n  suite.eachTest(function(test) {\n    var match = self._grep.test(test.fullTitle());\n    if (self._invert) {\n      match = !match;\n    }\n    if (match) {\n      total++;\n    }\n  });\n\n  return total;\n};\n\n/**\n * Return a list of global properties.\n *\n * @return {Array}\n * @api private\n */\nRunner.prototype.globalProps = function() {\n  var props = keys(global);\n\n  // non-enumerables\n  for (var i = 0; i < globals.length; ++i) {\n    if (~indexOf(props, globals[i])) {\n      continue;\n    }\n    props.push(globals[i]);\n  }\n\n  return props;\n};\n\n/**\n * Allow the given `arr` of globals.\n *\n * @param {Array} arr\n * @return {Runner} for chaining\n * @api public\n * @param {Array} arr\n * @return {Runner} Runner instance.\n */\nRunner.prototype.globals = function(arr) {\n  if (!arguments.length) {\n    return this._globals;\n  }\n  debug('globals %j', arr);\n  this._globals = this._globals.concat(arr);\n  return this;\n};\n\n/**\n * Check for global variable leaks.\n *\n * @api private\n */\nRunner.prototype.checkGlobals = function(test) {\n  if (this.ignoreLeaks) {\n    return;\n  }\n  var ok = this._globals;\n\n  var globals = this.globalProps();\n  var leaks;\n\n  if (test) {\n    ok = ok.concat(test._allowedGlobals || []);\n  }\n\n  if (this.prevGlobalsLength === globals.length) {\n    return;\n  }\n  this.prevGlobalsLength = globals.length;\n\n  leaks = filterLeaks(ok, globals);\n  this._globals = this._globals.concat(leaks);\n\n  if (leaks.length > 1) {\n    this.fail(test, new Error('global leaks detected: ' + leaks.join(', ') + ''));\n  } else if (leaks.length) {\n    this.fail(test, new Error('global leak detected: ' + leaks[0]));\n  }\n};\n\n/**\n * Fail the given `test`.\n *\n * @api private\n * @param {Test} test\n * @param {Error} err\n */\nRunner.prototype.fail = function(test, err) {\n  if (test.isPending()) {\n    return;\n  }\n\n  ++this.failures;\n  test.state = 'failed';\n\n  if (!(err instanceof Error || err && typeof err.message === 'string')) {\n    err = new Error('the ' + type(err) + ' ' + stringify(err) + ' was thrown, throw an Error :)');\n  }\n\n  err.stack = (this.fullStackTrace || !err.stack)\n    ? err.stack\n    : stackFilter(err.stack);\n\n  this.emit('fail', test, err);\n};\n\n/**\n * Fail the given `hook` with `err`.\n *\n * Hook failures work in the following pattern:\n * - If bail, then exit\n * - Failed `before` hook skips all tests in a suite and subsuites,\n *   but jumps to corresponding `after` hook\n * - Failed `before each` hook skips remaining tests in a\n *   suite and jumps to corresponding `after each` hook,\n *   which is run only once\n * - Failed `after` hook does not alter\n *   execution order\n * - Failed `after each` hook skips remaining tests in a\n *   suite and subsuites, but executes other `after each`\n *   hooks\n *\n * @api private\n * @param {Hook} hook\n * @param {Error} err\n */\nRunner.prototype.failHook = function(hook, err) {\n  if (hook.ctx && hook.ctx.currentTest) {\n    hook.originalTitle = hook.originalTitle || hook.title;\n    hook.title = hook.originalTitle + ' for \"' + hook.ctx.currentTest.title + '\"';\n  }\n\n  this.fail(hook, err);\n  if (this.suite.bail()) {\n    this.emit('end');\n  }\n};\n\n/**\n * Run hook `name` callbacks and then invoke `fn()`.\n *\n * @api private\n * @param {string} name\n * @param {Function} fn\n */\n\nRunner.prototype.hook = function(name, fn) {\n  var suite = this.suite;\n  var hooks = suite['_' + name];\n  var self = this;\n\n  function next(i) {\n    var hook = hooks[i];\n    if (!hook) {\n      return fn();\n    }\n    self.currentRunnable = hook;\n\n    hook.ctx.currentTest = self.test;\n\n    self.emit('hook', hook);\n\n    if (!hook.listeners('error').length) {\n      hook.on('error', function(err) {\n        self.failHook(hook, err);\n      });\n    }\n\n    hook.run(function(err) {\n      var testError = hook.error();\n      if (testError) {\n        self.fail(self.test, testError);\n      }\n      if (err) {\n        if (err instanceof Pending) {\n          if (name === 'beforeEach' || name === 'afterEach') {\n            self.test.pending = true;\n          } else {\n            utils.forEach(suite.tests, function(test) {\n              test.pending = true;\n            });\n            // a pending hook won't be executed twice.\n            hook.pending = true;\n          }\n        } else {\n          self.failHook(hook, err);\n\n          // stop executing hooks, notify callee of hook err\n          return fn(err);\n        }\n      }\n      self.emit('hook end', hook);\n      delete hook.ctx.currentTest;\n      next(++i);\n    });\n  }\n\n  Runner.immediately(function() {\n    next(0);\n  });\n};\n\n/**\n * Run hook `name` for the given array of `suites`\n * in order, and callback `fn(err, errSuite)`.\n *\n * @api private\n * @param {string} name\n * @param {Array} suites\n * @param {Function} fn\n */\nRunner.prototype.hooks = function(name, suites, fn) {\n  var self = this;\n  var orig = this.suite;\n\n  function next(suite) {\n    self.suite = suite;\n\n    if (!suite) {\n      self.suite = orig;\n      return fn();\n    }\n\n    self.hook(name, function(err) {\n      if (err) {\n        var errSuite = self.suite;\n        self.suite = orig;\n        return fn(err, errSuite);\n      }\n\n      next(suites.pop());\n    });\n  }\n\n  next(suites.pop());\n};\n\n/**\n * Run hooks from the top level down.\n *\n * @param {String} name\n * @param {Function} fn\n * @api private\n */\nRunner.prototype.hookUp = function(name, fn) {\n  var suites = [this.suite].concat(this.parents()).reverse();\n  this.hooks(name, suites, fn);\n};\n\n/**\n * Run hooks from the bottom up.\n *\n * @param {String} name\n * @param {Function} fn\n * @api private\n */\nRunner.prototype.hookDown = function(name, fn) {\n  var suites = [this.suite].concat(this.parents());\n  this.hooks(name, suites, fn);\n};\n\n/**\n * Return an array of parent Suites from\n * closest to furthest.\n *\n * @return {Array}\n * @api private\n */\nRunner.prototype.parents = function() {\n  var suite = this.suite;\n  var suites = [];\n  while (suite.parent) {\n    suite = suite.parent;\n    suites.push(suite);\n  }\n  return suites;\n};\n\n/**\n * Run the current test and callback `fn(err)`.\n *\n * @param {Function} fn\n * @api private\n */\nRunner.prototype.runTest = function(fn) {\n  var self = this;\n  var test = this.test;\n\n  if (!test) {\n    return;\n  }\n  if (this.asyncOnly) {\n    test.asyncOnly = true;\n  }\n\n  if (this.allowUncaught) {\n    test.allowUncaught = true;\n    return test.run(fn);\n  }\n  try {\n    test.on('error', function(err) {\n      self.fail(test, err);\n    });\n    test.run(fn);\n  } catch (err) {\n    fn(err);\n  }\n};\n\n/**\n * Run tests in the given `suite` and invoke the callback `fn()` when complete.\n *\n * @api private\n * @param {Suite} suite\n * @param {Function} fn\n */\nRunner.prototype.runTests = function(suite, fn) {\n  var self = this;\n  var tests = suite.tests.slice();\n  var test;\n\n  function hookErr(_, errSuite, after) {\n    // before/after Each hook for errSuite failed:\n    var orig = self.suite;\n\n    // for failed 'after each' hook start from errSuite parent,\n    // otherwise start from errSuite itself\n    self.suite = after ? errSuite.parent : errSuite;\n\n    if (self.suite) {\n      // call hookUp afterEach\n      self.hookUp('afterEach', function(err2, errSuite2) {\n        self.suite = orig;\n        // some hooks may fail even now\n        if (err2) {\n          return hookErr(err2, errSuite2, true);\n        }\n        // report error suite\n        fn(errSuite);\n      });\n    } else {\n      // there is no need calling other 'after each' hooks\n      self.suite = orig;\n      fn(errSuite);\n    }\n  }\n\n  function next(err, errSuite) {\n    // if we bail after first err\n    if (self.failures && suite._bail) {\n      return fn();\n    }\n\n    if (self._abort) {\n      return fn();\n    }\n\n    if (err) {\n      return hookErr(err, errSuite, true);\n    }\n\n    // next test\n    test = tests.shift();\n\n    // all done\n    if (!test) {\n      return fn();\n    }\n\n    // grep\n    var match = self._grep.test(test.fullTitle());\n    if (self._invert) {\n      match = !match;\n    }\n    if (!match) {\n      // Run immediately only if we have defined a grep. When we\n      // define a grep — It can cause maximum callstack error if\n      // the grep is doing a large recursive loop by neglecting\n      // all tests. The run immediately function also comes with\n      // a performance cost. So we don't want to run immediately\n      // if we run the whole test suite, because running the whole\n      // test suite don't do any immediate recursive loops. Thus,\n      // allowing a JS runtime to breathe.\n      if (self._grep !== self._defaultGrep) {\n        Runner.immediately(next);\n      } else {\n        next();\n      }\n      return;\n    }\n\n    if (test.isPending()) {\n      self.emit('pending', test);\n      self.emit('test end', test);\n      return next();\n    }\n\n    // execute test and hook(s)\n    self.emit('test', self.test = test);\n    self.hookDown('beforeEach', function(err, errSuite) {\n      if (test.isPending()) {\n        self.emit('pending', test);\n        self.emit('test end', test);\n        return next();\n      }\n      if (err) {\n        return hookErr(err, errSuite, false);\n      }\n      self.currentRunnable = self.test;\n      self.runTest(function(err) {\n        test = self.test;\n        if (err) {\n          var retry = test.currentRetry();\n          if (err instanceof Pending) {\n            test.pending = true;\n            self.emit('pending', test);\n          } else if (retry < test.retries()) {\n            var clonedTest = test.clone();\n            clonedTest.currentRetry(retry + 1);\n            tests.unshift(clonedTest);\n\n            // Early return + hook trigger so that it doesn't\n            // increment the count wrong\n            return self.hookUp('afterEach', next);\n          } else {\n            self.fail(test, err);\n          }\n          self.emit('test end', test);\n\n          if (err instanceof Pending) {\n            return next();\n          }\n\n          return self.hookUp('afterEach', next);\n        }\n\n        test.state = 'passed';\n        self.emit('pass', test);\n        self.emit('test end', test);\n        self.hookUp('afterEach', next);\n      });\n    });\n  }\n\n  this.next = next;\n  this.hookErr = hookErr;\n  next();\n};\n\n/**\n * Run the given `suite` and invoke the callback `fn()` when complete.\n *\n * @api private\n * @param {Suite} suite\n * @param {Function} fn\n */\nRunner.prototype.runSuite = function(suite, fn) {\n  var i = 0;\n  var self = this;\n  var total = this.grepTotal(suite);\n  var afterAllHookCalled = false;\n\n  debug('run suite %s', suite.fullTitle());\n\n  if (!total || (self.failures && suite._bail)) {\n    return fn();\n  }\n\n  this.emit('suite', this.suite = suite);\n\n  function next(errSuite) {\n    if (errSuite) {\n      // current suite failed on a hook from errSuite\n      if (errSuite === suite) {\n        // if errSuite is current suite\n        // continue to the next sibling suite\n        return done();\n      }\n      // errSuite is among the parents of current suite\n      // stop execution of errSuite and all sub-suites\n      return done(errSuite);\n    }\n\n    if (self._abort) {\n      return done();\n    }\n\n    var curr = suite.suites[i++];\n    if (!curr) {\n      return done();\n    }\n\n    // Avoid grep neglecting large number of tests causing a\n    // huge recursive loop and thus a maximum call stack error.\n    // See comment in `this.runTests()` for more information.\n    if (self._grep !== self._defaultGrep) {\n      Runner.immediately(function() {\n        self.runSuite(curr, next);\n      });\n    } else {\n      self.runSuite(curr, next);\n    }\n  }\n\n  function done(errSuite) {\n    self.suite = suite;\n    self.nextSuite = next;\n\n    if (afterAllHookCalled) {\n      fn(errSuite);\n    } else {\n      // mark that the afterAll block has been called once\n      // and so can be skipped if there is an error in it.\n      afterAllHookCalled = true;\n\n      // remove reference to test\n      delete self.test;\n\n      self.hook('afterAll', function() {\n        self.emit('suite end', suite);\n        fn(errSuite);\n      });\n    }\n  }\n\n  this.nextSuite = next;\n\n  this.hook('beforeAll', function(err) {\n    if (err) {\n      return done();\n    }\n    self.runTests(suite, next);\n  });\n};\n\n/**\n * Handle uncaught exceptions.\n *\n * @param {Error} err\n * @api private\n */\nRunner.prototype.uncaught = function(err) {\n  if (err) {\n    debug('uncaught exception %s', err !== function() {\n      return this;\n    }.call(err) ? err : (err.message || err));\n  } else {\n    debug('uncaught undefined exception');\n    err = undefinedError();\n  }\n  err.uncaught = true;\n\n  var runnable = this.currentRunnable;\n\n  if (!runnable) {\n    runnable = new Runnable('Uncaught error outside test suite');\n    runnable.parent = this.suite;\n\n    if (this.started) {\n      this.fail(runnable, err);\n    } else {\n      // Can't recover from this failure\n      this.emit('start');\n      this.fail(runnable, err);\n      this.emit('end');\n    }\n\n    return;\n  }\n\n  runnable.clearTimeout();\n\n  // Ignore errors if complete or pending\n  if (runnable.state || runnable.isPending()) {\n    return;\n  }\n  this.fail(runnable, err);\n\n  // recover from test\n  if (runnable.type === 'test') {\n    this.emit('test end', runnable);\n    this.hookUp('afterEach', this.next);\n    return;\n  }\n\n // recover from hooks\n  if (runnable.type === 'hook') {\n    var errSuite = this.suite;\n    // if hook failure is in afterEach block\n    if (runnable.fullTitle().indexOf('after each') > -1) {\n      return this.hookErr(err, errSuite, true);\n    }\n    // if hook failure is in beforeEach block\n    if (runnable.fullTitle().indexOf('before each') > -1) {\n      return this.hookErr(err, errSuite, false);\n    }\n    // if hook failure is in after or before blocks\n    return this.nextSuite(errSuite);\n  }\n\n  // bail\n  this.emit('end');\n};\n\n/**\n * Cleans up the references to all the deferred functions\n * (before/after/beforeEach/afterEach) and tests of a Suite.\n * These must be deleted otherwise a memory leak can happen,\n * as those functions may reference variables from closures,\n * thus those variables can never be garbage collected as long\n * as the deferred functions exist.\n *\n * @param {Suite} suite\n */\nfunction cleanSuiteReferences(suite) {\n  function cleanArrReferences(arr) {\n    for (var i = 0; i < arr.length; i++) {\n      delete arr[i].fn;\n    }\n  }\n\n  if (isArray(suite._beforeAll)) {\n    cleanArrReferences(suite._beforeAll);\n  }\n\n  if (isArray(suite._beforeEach)) {\n    cleanArrReferences(suite._beforeEach);\n  }\n\n  if (isArray(suite._afterAll)) {\n    cleanArrReferences(suite._afterAll);\n  }\n\n  if (isArray(suite._afterEach)) {\n    cleanArrReferences(suite._afterEach);\n  }\n\n  for (var i = 0; i < suite.tests.length; i++) {\n    delete suite.tests[i].fn;\n  }\n}\n\n/**\n * Run the root suite and invoke `fn(failures)`\n * on completion.\n *\n * @param {Function} fn\n * @return {Runner} for chaining\n * @api public\n * @param {Function} fn\n * @return {Runner} Runner instance.\n */\nRunner.prototype.run = function(fn) {\n  var self = this;\n  var rootSuite = this.suite;\n\n  // If there is an `only` filter\n  if (this.hasOnly) {\n    filterOnly(rootSuite);\n  }\n\n  fn = fn || function() {};\n\n  function uncaught(err) {\n    self.uncaught(err);\n  }\n\n  function start() {\n    self.started = true;\n    self.emit('start');\n    self.runSuite(rootSuite, function() {\n      debug('finished running');\n      self.emit('end');\n    });\n  }\n\n  debug('start');\n\n  // references cleanup to avoid memory leaks\n  this.on('suite end', cleanSuiteReferences);\n\n  // callback\n  this.on('end', function() {\n    debug('end');\n    process.removeListener('uncaughtException', uncaught);\n    fn(self.failures);\n  });\n\n  // uncaught exception\n  process.on('uncaughtException', uncaught);\n\n  if (this._delay) {\n    // for reporters, I guess.\n    // might be nice to debounce some dots while we wait.\n    this.emit('waiting', rootSuite);\n    rootSuite.once('run', start);\n  } else {\n    start();\n  }\n\n  return this;\n};\n\n/**\n * Cleanly abort execution.\n *\n * @api public\n * @return {Runner} Runner instance.\n */\nRunner.prototype.abort = function() {\n  debug('aborting');\n  this._abort = true;\n\n  return this;\n};\n\n/**\n * Filter suites based on `isOnly` logic.\n *\n * @param {Array} suite\n * @returns {Boolean}\n * @api private\n */\nfunction filterOnly(suite) {\n  if (suite._onlyTests.length) {\n    // If the suite contains `only` tests, run those and ignore any nested suites.\n    suite.tests = suite._onlyTests;\n    suite.suites = [];\n  } else {\n    // Otherwise, do not run any of the tests in this suite.\n    suite.tests = [];\n    utils.forEach(suite._onlySuites, function(onlySuite) {\n      // If there are other `only` tests/suites nested in the current `only` suite, then filter that `only` suite.\n      // Otherwise, all of the tests on this `only` suite should be run, so don't filter it.\n      if (hasOnly(onlySuite)) {\n        filterOnly(onlySuite);\n      }\n    });\n    // Run the `only` suites, as well as any other suites that have `only` tests/suites as descendants.\n    suite.suites = filter(suite.suites, function(childSuite) {\n      return indexOf(suite._onlySuites, childSuite) !== -1 || filterOnly(childSuite);\n    });\n  }\n  // Keep the suite only if there is something to run\n  return suite.tests.length || suite.suites.length;\n}\n\n/**\n * Determines whether a suite has an `only` test or suite as a descendant.\n *\n * @param {Array} suite\n * @returns {Boolean}\n * @api private\n */\nfunction hasOnly(suite) {\n  return suite._onlyTests.length || suite._onlySuites.length || some(suite.suites, hasOnly);\n}\n\n/**\n * Filter leaks with the given globals flagged as `ok`.\n *\n * @api private\n * @param {Array} ok\n * @param {Array} globals\n * @return {Array}\n */\nfunction filterLeaks(ok, globals) {\n  return filter(globals, function(key) {\n    // Firefox and Chrome exposes iframes as index inside the window object\n    if (/^\\d+/.test(key)) {\n      return false;\n    }\n\n    // in firefox\n    // if runner runs in an iframe, this iframe's window.getInterface method\n    // not init at first it is assigned in some seconds\n    if (global.navigator && (/^getInterface/).test(key)) {\n      return false;\n    }\n\n    // an iframe could be approached by window[iframeIndex]\n    // in ie6,7,8 and opera, iframeIndex is enumerable, this could cause leak\n    if (global.navigator && (/^\\d+/).test(key)) {\n      return false;\n    }\n\n    // Opera and IE expose global variables for HTML element IDs (issue #243)\n    if (/^mocha-/.test(key)) {\n      return false;\n    }\n\n    var matched = filter(ok, function(ok) {\n      if (~ok.indexOf('*')) {\n        return key.indexOf(ok.split('*')[0]) === 0;\n      }\n      return key === ok;\n    });\n    return !matched.length && (!global.navigator || key !== 'onerror');\n  });\n}\n\n/**\n * Array of globals dependent on the environment.\n *\n * @return {Array}\n * @api private\n */\nfunction extraGlobals() {\n  if (typeof process === 'object' && typeof process.version === 'string') {\n    var parts = process.version.split('.');\n    var nodeVersion = utils.reduce(parts, function(a, v) {\n      return a << 8 | v;\n    });\n\n    // 'errno' was renamed to process._errno in v0.9.11.\n\n    if (nodeVersion < 0x00090B) {\n      return ['errno'];\n    }\n  }\n\n  return [];\n}\n\n}).call(this,require('_process'),typeof global !== \"undefined\" ? global : typeof self !== \"undefined\" ? self : typeof window !== \"undefined\" ? window : {})\n},{\"./pending\":16,\"./runnable\":33,\"./utils\":38,\"_process\":67,\"debug\":2,\"events\":3}],35:[function(require,module,exports){\n/**\n * Module dependencies.\n */\n\nvar EventEmitter = require('events').EventEmitter;\nvar Hook = require('./hook');\nvar utils = require('./utils');\nvar inherits = utils.inherits;\nvar debug = require('debug')('mocha:suite');\nvar milliseconds = require('./ms');\n\n/**\n * Expose `Suite`.\n */\n\nexports = module.exports = Suite;\n\n/**\n * Create a new `Suite` with the given `title` and parent `Suite`. When a suite\n * with the same title is already present, that suite is returned to provide\n * nicer reporter and more flexible meta-testing.\n *\n * @api public\n * @param {Suite} parent\n * @param {string} title\n * @return {Suite}\n */\nexports.create = function(parent, title) {\n  var suite = new Suite(title, parent.ctx);\n  suite.parent = parent;\n  title = suite.fullTitle();\n  parent.addSuite(suite);\n  return suite;\n};\n\n/**\n * Initialize a new `Suite` with the given `title` and `ctx`.\n *\n * @api private\n * @param {string} title\n * @param {Context} parentContext\n */\nfunction Suite(title, parentContext) {\n  if (!utils.isString(title)) {\n    throw new Error('Suite `title` should be a \"string\" but \"' + typeof title + '\" was given instead.');\n  }\n  this.title = title;\n  function Context() {}\n  Context.prototype = parentContext;\n  this.ctx = new Context();\n  this.suites = [];\n  this.tests = [];\n  this.pending = false;\n  this._beforeEach = [];\n  this._beforeAll = [];\n  this._afterEach = [];\n  this._afterAll = [];\n  this.root = !title;\n  this._timeout = 2000;\n  this._enableTimeouts = true;\n  this._slow = 75;\n  this._bail = false;\n  this._retries = -1;\n  this._onlyTests = [];\n  this._onlySuites = [];\n  this.delayed = false;\n}\n\n/**\n * Inherit from `EventEmitter.prototype`.\n */\ninherits(Suite, EventEmitter);\n\n/**\n * Return a clone of this `Suite`.\n *\n * @api private\n * @return {Suite}\n */\nSuite.prototype.clone = function() {\n  var suite = new Suite(this.title);\n  debug('clone');\n  suite.ctx = this.ctx;\n  suite.timeout(this.timeout());\n  suite.retries(this.retries());\n  suite.enableTimeouts(this.enableTimeouts());\n  suite.slow(this.slow());\n  suite.bail(this.bail());\n  return suite;\n};\n\n/**\n * Set timeout `ms` or short-hand such as \"2s\".\n *\n * @api private\n * @param {number|string} ms\n * @return {Suite|number} for chaining\n */\nSuite.prototype.timeout = function(ms) {\n  if (!arguments.length) {\n    return this._timeout;\n  }\n  if (ms.toString() === '0') {\n    this._enableTimeouts = false;\n  }\n  if (typeof ms === 'string') {\n    ms = milliseconds(ms);\n  }\n  debug('timeout %d', ms);\n  this._timeout = parseInt(ms, 10);\n  return this;\n};\n\n/**\n * Set number of times to retry a failed test.\n *\n * @api private\n * @param {number|string} n\n * @return {Suite|number} for chaining\n */\nSuite.prototype.retries = function(n) {\n  if (!arguments.length) {\n    return this._retries;\n  }\n  debug('retries %d', n);\n  this._retries = parseInt(n, 10) || 0;\n  return this;\n};\n\n/**\n  * Set timeout to `enabled`.\n  *\n  * @api private\n  * @param {boolean} enabled\n  * @return {Suite|boolean} self or enabled\n  */\nSuite.prototype.enableTimeouts = function(enabled) {\n  if (!arguments.length) {\n    return this._enableTimeouts;\n  }\n  debug('enableTimeouts %s', enabled);\n  this._enableTimeouts = enabled;\n  return this;\n};\n\n/**\n * Set slow `ms` or short-hand such as \"2s\".\n *\n * @api private\n * @param {number|string} ms\n * @return {Suite|number} for chaining\n */\nSuite.prototype.slow = function(ms) {\n  if (!arguments.length) {\n    return this._slow;\n  }\n  if (typeof ms === 'string') {\n    ms = milliseconds(ms);\n  }\n  debug('slow %d', ms);\n  this._slow = ms;\n  return this;\n};\n\n/**\n * Sets whether to bail after first error.\n *\n * @api private\n * @param {boolean} bail\n * @return {Suite|number} for chaining\n */\nSuite.prototype.bail = function(bail) {\n  if (!arguments.length) {\n    return this._bail;\n  }\n  debug('bail %s', bail);\n  this._bail = bail;\n  return this;\n};\n\n/**\n * Check if this suite or its parent suite is marked as pending.\n *\n * @api private\n */\nSuite.prototype.isPending = function() {\n  return this.pending || (this.parent && this.parent.isPending());\n};\n\n/**\n * Run `fn(test[, done])` before running tests.\n *\n * @api private\n * @param {string} title\n * @param {Function} fn\n * @return {Suite} for chaining\n */\nSuite.prototype.beforeAll = function(title, fn) {\n  if (this.isPending()) {\n    return this;\n  }\n  if (typeof title === 'function') {\n    fn = title;\n    title = fn.name;\n  }\n  title = '\"before all\" hook' + (title ? ': ' + title : '');\n\n  var hook = new Hook(title, fn);\n  hook.parent = this;\n  hook.timeout(this.timeout());\n  hook.retries(this.retries());\n  hook.enableTimeouts(this.enableTimeouts());\n  hook.slow(this.slow());\n  hook.ctx = this.ctx;\n  this._beforeAll.push(hook);\n  this.emit('beforeAll', hook);\n  return this;\n};\n\n/**\n * Run `fn(test[, done])` after running tests.\n *\n * @api private\n * @param {string} title\n * @param {Function} fn\n * @return {Suite} for chaining\n */\nSuite.prototype.afterAll = function(title, fn) {\n  if (this.isPending()) {\n    return this;\n  }\n  if (typeof title === 'function') {\n    fn = title;\n    title = fn.name;\n  }\n  title = '\"after all\" hook' + (title ? ': ' + title : '');\n\n  var hook = new Hook(title, fn);\n  hook.parent = this;\n  hook.timeout(this.timeout());\n  hook.retries(this.retries());\n  hook.enableTimeouts(this.enableTimeouts());\n  hook.slow(this.slow());\n  hook.ctx = this.ctx;\n  this._afterAll.push(hook);\n  this.emit('afterAll', hook);\n  return this;\n};\n\n/**\n * Run `fn(test[, done])` before each test case.\n *\n * @api private\n * @param {string} title\n * @param {Function} fn\n * @return {Suite} for chaining\n */\nSuite.prototype.beforeEach = function(title, fn) {\n  if (this.isPending()) {\n    return this;\n  }\n  if (typeof title === 'function') {\n    fn = title;\n    title = fn.name;\n  }\n  title = '\"before each\" hook' + (title ? ': ' + title : '');\n\n  var hook = new Hook(title, fn);\n  hook.parent = this;\n  hook.timeout(this.timeout());\n  hook.retries(this.retries());\n  hook.enableTimeouts(this.enableTimeouts());\n  hook.slow(this.slow());\n  hook.ctx = this.ctx;\n  this._beforeEach.push(hook);\n  this.emit('beforeEach', hook);\n  return this;\n};\n\n/**\n * Run `fn(test[, done])` after each test case.\n *\n * @api private\n * @param {string} title\n * @param {Function} fn\n * @return {Suite} for chaining\n */\nSuite.prototype.afterEach = function(title, fn) {\n  if (this.isPending()) {\n    return this;\n  }\n  if (typeof title === 'function') {\n    fn = title;\n    title = fn.name;\n  }\n  title = '\"after each\" hook' + (title ? ': ' + title : '');\n\n  var hook = new Hook(title, fn);\n  hook.parent = this;\n  hook.timeout(this.timeout());\n  hook.retries(this.retries());\n  hook.enableTimeouts(this.enableTimeouts());\n  hook.slow(this.slow());\n  hook.ctx = this.ctx;\n  this._afterEach.push(hook);\n  this.emit('afterEach', hook);\n  return this;\n};\n\n/**\n * Add a test `suite`.\n *\n * @api private\n * @param {Suite} suite\n * @return {Suite} for chaining\n */\nSuite.prototype.addSuite = function(suite) {\n  suite.parent = this;\n  suite.timeout(this.timeout());\n  suite.retries(this.retries());\n  suite.enableTimeouts(this.enableTimeouts());\n  suite.slow(this.slow());\n  suite.bail(this.bail());\n  this.suites.push(suite);\n  this.emit('suite', suite);\n  return this;\n};\n\n/**\n * Add a `test` to this suite.\n *\n * @api private\n * @param {Test} test\n * @return {Suite} for chaining\n */\nSuite.prototype.addTest = function(test) {\n  test.parent = this;\n  test.timeout(this.timeout());\n  test.retries(this.retries());\n  test.enableTimeouts(this.enableTimeouts());\n  test.slow(this.slow());\n  test.ctx = this.ctx;\n  this.tests.push(test);\n  this.emit('test', test);\n  return this;\n};\n\n/**\n * Return the full title generated by recursively concatenating the parent's\n * full title.\n *\n * @api public\n * @return {string}\n */\nSuite.prototype.fullTitle = function() {\n  if (this.parent) {\n    var full = this.parent.fullTitle();\n    if (full) {\n      return full + ' ' + this.title;\n    }\n  }\n  return this.title;\n};\n\n/**\n * Return the total number of tests.\n *\n * @api public\n * @return {number}\n */\nSuite.prototype.total = function() {\n  return utils.reduce(this.suites, function(sum, suite) {\n    return sum + suite.total();\n  }, 0) + this.tests.length;\n};\n\n/**\n * Iterates through each suite recursively to find all tests. Applies a\n * function in the format `fn(test)`.\n *\n * @api private\n * @param {Function} fn\n * @return {Suite}\n */\nSuite.prototype.eachTest = function(fn) {\n  utils.forEach(this.tests, fn);\n  utils.forEach(this.suites, function(suite) {\n    suite.eachTest(fn);\n  });\n  return this;\n};\n\n/**\n * This will run the root suite if we happen to be running in delayed mode.\n */\nSuite.prototype.run = function run() {\n  if (this.root) {\n    this.emit('run');\n  }\n};\n\n},{\"./hook\":7,\"./ms\":15,\"./utils\":38,\"debug\":2,\"events\":3}],36:[function(require,module,exports){\n/**\n * Module dependencies.\n */\n\nvar Runnable = require('./runnable');\nvar create = require('lodash.create');\nvar isString = require('./utils').isString;\n\n/**\n * Expose `Test`.\n */\n\nmodule.exports = Test;\n\n/**\n * Initialize a new `Test` with the given `title` and callback `fn`.\n *\n * @api private\n * @param {String} title\n * @param {Function} fn\n */\nfunction Test(title, fn) {\n  if (!isString(title)) {\n    throw new Error('Test `title` should be a \"string\" but \"' + typeof title + '\" was given instead.');\n  }\n  Runnable.call(this, title, fn);\n  this.pending = !fn;\n  this.type = 'test';\n}\n\n/**\n * Inherit from `Runnable.prototype`.\n */\nTest.prototype = create(Runnable.prototype, {\n  constructor: Test\n});\n\nTest.prototype.clone = function() {\n  var test = new Test(this.title, this.fn);\n  test.timeout(this.timeout());\n  test.slow(this.slow());\n  test.enableTimeouts(this.enableTimeouts());\n  test.retries(this.retries());\n  test.currentRetry(this.currentRetry());\n  test.globals(this.globals());\n  test.parent = this.parent;\n  test.file = this.file;\n  test.ctx = this.ctx;\n  return test;\n};\n\n},{\"./runnable\":33,\"./utils\":38,\"lodash.create\":60}],37:[function(require,module,exports){\n'use strict';\n\n/**\n * Pad a `number` with a ten's place zero.\n *\n * @param {number} number\n * @return {string}\n */\nfunction pad(number) {\n  var n = number.toString();\n  return n.length === 1 ? '0' + n : n;\n}\n\n/**\n * Turn a `date` into an ISO string.\n *\n * https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/toISOString\n *\n * @param {Date} date\n * @return {string}\n */\nfunction toISOString(date) {\n  return date.getUTCFullYear()\n    + '-' + pad(date.getUTCMonth() + 1)\n    + '-' + pad(date.getUTCDate())\n    + 'T' + pad(date.getUTCHours())\n    + ':' + pad(date.getUTCMinutes())\n    + ':' + pad(date.getUTCSeconds())\n    + '.' + String((date.getUTCMilliseconds()/1000).toFixed(3)).slice(2, 5)\n    + 'Z';\n}\n\n/*\n * Exports.\n */\n\nmodule.exports = toISOString;\n\n},{}],38:[function(require,module,exports){\n(function (process,Buffer){\n/* eslint-env browser */\n\n/**\n * Module dependencies.\n */\n\nvar JSON = require('json3');\nvar basename = require('path').basename;\nvar debug = require('debug')('mocha:watch');\nvar exists = require('fs').existsSync || require('path').existsSync;\nvar glob = require('glob');\nvar path = require('path');\nvar join = path.join;\nvar readdirSync = require('fs').readdirSync;\nvar statSync = require('fs').statSync;\nvar watchFile = require('fs').watchFile;\nvar toISOString = require('./to-iso-string');\n\n/**\n * Ignored directories.\n */\n\nvar ignore = ['node_modules', '.git'];\n\nexports.inherits = require('util').inherits;\n\n/**\n * Escape special characters in the given string of html.\n *\n * @api private\n * @param  {string} html\n * @return {string}\n */\nexports.escape = function(html) {\n  return String(html)\n    .replace(/&/g, '&amp;')\n    .replace(/\"/g, '&quot;')\n    .replace(/</g, '&lt;')\n    .replace(/>/g, '&gt;');\n};\n\n/**\n * Array#forEach (<=IE8)\n *\n * @api private\n * @param {Array} arr\n * @param {Function} fn\n * @param {Object} scope\n */\nexports.forEach = function(arr, fn, scope) {\n  for (var i = 0, l = arr.length; i < l; i++) {\n    fn.call(scope, arr[i], i);\n  }\n};\n\n/**\n * Test if the given obj is type of string.\n *\n * @api private\n * @param {Object} obj\n * @return {boolean}\n */\nexports.isString = function(obj) {\n  return typeof obj === 'string';\n};\n\n/**\n * Array#map (<=IE8)\n *\n * @api private\n * @param {Array} arr\n * @param {Function} fn\n * @param {Object} scope\n * @return {Array}\n */\nexports.map = function(arr, fn, scope) {\n  var result = [];\n  for (var i = 0, l = arr.length; i < l; i++) {\n    result.push(fn.call(scope, arr[i], i, arr));\n  }\n  return result;\n};\n\n/**\n * Array#indexOf (<=IE8)\n *\n * @api private\n * @param {Array} arr\n * @param {Object} obj to find index of\n * @param {number} start\n * @return {number}\n */\nvar indexOf = exports.indexOf = function(arr, obj, start) {\n  for (var i = start || 0, l = arr.length; i < l; i++) {\n    if (arr[i] === obj) {\n      return i;\n    }\n  }\n  return -1;\n};\n\n/**\n * Array#reduce (<=IE8)\n *\n * @api private\n * @param {Array} arr\n * @param {Function} fn\n * @param {Object} val Initial value.\n * @return {*}\n */\nvar reduce = exports.reduce = function(arr, fn, val) {\n  var rval = val;\n\n  for (var i = 0, l = arr.length; i < l; i++) {\n    rval = fn(rval, arr[i], i, arr);\n  }\n\n  return rval;\n};\n\n/**\n * Array#filter (<=IE8)\n *\n * @api private\n * @param {Array} arr\n * @param {Function} fn\n * @return {Array}\n */\nexports.filter = function(arr, fn) {\n  var ret = [];\n\n  for (var i = 0, l = arr.length; i < l; i++) {\n    var val = arr[i];\n    if (fn(val, i, arr)) {\n      ret.push(val);\n    }\n  }\n\n  return ret;\n};\n\n/**\n * Array#some (<=IE8)\n *\n * @api private\n * @param {Array} arr\n * @param {Function} fn\n * @return {Array}\n */\nexports.some = function(arr, fn) {\n  for (var i = 0, l = arr.length; i < l; i++) {\n    if (fn(arr[i])) {\n      return true;\n    }\n  }\n  return false;\n};\n\n/**\n * Object.keys (<=IE8)\n *\n * @api private\n * @param {Object} obj\n * @return {Array} keys\n */\nexports.keys = typeof Object.keys === 'function' ? Object.keys : function(obj) {\n  var keys = [];\n  var has = Object.prototype.hasOwnProperty; // for `window` on <=IE8\n\n  for (var key in obj) {\n    if (has.call(obj, key)) {\n      keys.push(key);\n    }\n  }\n\n  return keys;\n};\n\n/**\n * Watch the given `files` for changes\n * and invoke `fn(file)` on modification.\n *\n * @api private\n * @param {Array} files\n * @param {Function} fn\n */\nexports.watch = function(files, fn) {\n  var options = { interval: 100 };\n  files.forEach(function(file) {\n    debug('file %s', file);\n    watchFile(file, options, function(curr, prev) {\n      if (prev.mtime < curr.mtime) {\n        fn(file);\n      }\n    });\n  });\n};\n\n/**\n * Array.isArray (<=IE8)\n *\n * @api private\n * @param {Object} obj\n * @return {Boolean}\n */\nvar isArray = typeof Array.isArray === 'function' ? Array.isArray : function(obj) {\n  return Object.prototype.toString.call(obj) === '[object Array]';\n};\n\nexports.isArray = isArray;\n\n/**\n * Buffer.prototype.toJSON polyfill.\n *\n * @type {Function}\n */\nif (typeof Buffer !== 'undefined' && Buffer.prototype) {\n  Buffer.prototype.toJSON = Buffer.prototype.toJSON || function() {\n    return Array.prototype.slice.call(this, 0);\n  };\n}\n\n/**\n * Ignored files.\n *\n * @api private\n * @param {string} path\n * @return {boolean}\n */\nfunction ignored(path) {\n  return !~ignore.indexOf(path);\n}\n\n/**\n * Lookup files in the given `dir`.\n *\n * @api private\n * @param {string} dir\n * @param {string[]} [ext=['.js']]\n * @param {Array} [ret=[]]\n * @return {Array}\n */\nexports.files = function(dir, ext, ret) {\n  ret = ret || [];\n  ext = ext || ['js'];\n\n  var re = new RegExp('\\\\.(' + ext.join('|') + ')$');\n\n  readdirSync(dir)\n    .filter(ignored)\n    .forEach(function(path) {\n      path = join(dir, path);\n      if (statSync(path).isDirectory()) {\n        exports.files(path, ext, ret);\n      } else if (path.match(re)) {\n        ret.push(path);\n      }\n    });\n\n  return ret;\n};\n\n/**\n * Compute a slug from the given `str`.\n *\n * @api private\n * @param {string} str\n * @return {string}\n */\nexports.slug = function(str) {\n  return str\n    .toLowerCase()\n    .replace(/ +/g, '-')\n    .replace(/[^-\\w]/g, '');\n};\n\n/**\n * Strip the function definition from `str`, and re-indent for pre whitespace.\n *\n * @param {string} str\n * @return {string}\n */\nexports.clean = function(str) {\n  str = str\n    .replace(/\\r\\n?|[\\n\\u2028\\u2029]/g, '\\n').replace(/^\\uFEFF/, '')\n    // (traditional)->  space/name     parameters    body     (lambda)-> parameters       body   multi-statement/single          keep body content\n    .replace(/^function(?:\\s*|\\s+[^(]*)\\([^)]*\\)\\s*\\{((?:.|\\n)*?)\\s*\\}$|^\\([^)]*\\)\\s*=>\\s*(?:\\{((?:.|\\n)*?)\\s*\\}|((?:.|\\n)*))$/, '$1$2$3');\n\n  var spaces = str.match(/^\\n?( *)/)[1].length;\n  var tabs = str.match(/^\\n?(\\t*)/)[1].length;\n  var re = new RegExp('^\\n?' + (tabs ? '\\t' : ' ') + '{' + (tabs ? tabs : spaces) + '}', 'gm');\n\n  str = str.replace(re, '');\n\n  return exports.trim(str);\n};\n\n/**\n * Trim the given `str`.\n *\n * @api private\n * @param {string} str\n * @return {string}\n */\nexports.trim = function(str) {\n  return str.replace(/^\\s+|\\s+$/g, '');\n};\n\n/**\n * Parse the given `qs`.\n *\n * @api private\n * @param {string} qs\n * @return {Object}\n */\nexports.parseQuery = function(qs) {\n  return reduce(qs.replace('?', '').split('&'), function(obj, pair) {\n    var i = pair.indexOf('=');\n    var key = pair.slice(0, i);\n    var val = pair.slice(++i);\n\n    obj[key] = decodeURIComponent(val);\n    return obj;\n  }, {});\n};\n\n/**\n * Highlight the given string of `js`.\n *\n * @api private\n * @param {string} js\n * @return {string}\n */\nfunction highlight(js) {\n  return js\n    .replace(/</g, '&lt;')\n    .replace(/>/g, '&gt;')\n    .replace(/\\/\\/(.*)/gm, '<span class=\"comment\">//$1</span>')\n    .replace(/('.*?')/gm, '<span class=\"string\">$1</span>')\n    .replace(/(\\d+\\.\\d+)/gm, '<span class=\"number\">$1</span>')\n    .replace(/(\\d+)/gm, '<span class=\"number\">$1</span>')\n    .replace(/\\bnew[ \\t]+(\\w+)/gm, '<span class=\"keyword\">new</span> <span class=\"init\">$1</span>')\n    .replace(/\\b(function|new|throw|return|var|if|else)\\b/gm, '<span class=\"keyword\">$1</span>');\n}\n\n/**\n * Highlight the contents of tag `name`.\n *\n * @api private\n * @param {string} name\n */\nexports.highlightTags = function(name) {\n  var code = document.getElementById('mocha').getElementsByTagName(name);\n  for (var i = 0, len = code.length; i < len; ++i) {\n    code[i].innerHTML = highlight(code[i].innerHTML);\n  }\n};\n\n/**\n * If a value could have properties, and has none, this function is called,\n * which returns a string representation of the empty value.\n *\n * Functions w/ no properties return `'[Function]'`\n * Arrays w/ length === 0 return `'[]'`\n * Objects w/ no properties return `'{}'`\n * All else: return result of `value.toString()`\n *\n * @api private\n * @param {*} value The value to inspect.\n * @param {string} typeHint The type of the value\n * @returns {string}\n */\nfunction emptyRepresentation(value, typeHint) {\n  switch (typeHint) {\n    case 'function':\n      return '[Function]';\n    case 'object':\n      return '{}';\n    case 'array':\n      return '[]';\n    default:\n      return value.toString();\n  }\n}\n\n/**\n * Takes some variable and asks `Object.prototype.toString()` what it thinks it\n * is.\n *\n * @api private\n * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/toString\n * @param {*} value The value to test.\n * @returns {string} Computed type\n * @example\n * type({}) // 'object'\n * type([]) // 'array'\n * type(1) // 'number'\n * type(false) // 'boolean'\n * type(Infinity) // 'number'\n * type(null) // 'null'\n * type(new Date()) // 'date'\n * type(/foo/) // 'regexp'\n * type('type') // 'string'\n * type(global) // 'global'\n * type(new String('foo') // 'object'\n */\nvar type = exports.type = function type(value) {\n  if (value === undefined) {\n    return 'undefined';\n  } else if (value === null) {\n    return 'null';\n  } else if (typeof Buffer !== 'undefined' && Buffer.isBuffer(value)) {\n    return 'buffer';\n  }\n  return Object.prototype.toString.call(value)\n    .replace(/^\\[.+\\s(.+?)\\]$/, '$1')\n    .toLowerCase();\n};\n\n/**\n * Stringify `value`. Different behavior depending on type of value:\n *\n * - If `value` is undefined or null, return `'[undefined]'` or `'[null]'`, respectively.\n * - If `value` is not an object, function or array, return result of `value.toString()` wrapped in double-quotes.\n * - If `value` is an *empty* object, function, or array, return result of function\n *   {@link emptyRepresentation}.\n * - If `value` has properties, call {@link exports.canonicalize} on it, then return result of\n *   JSON.stringify().\n *\n * @api private\n * @see exports.type\n * @param {*} value\n * @return {string}\n */\nexports.stringify = function(value) {\n  var typeHint = type(value);\n\n  if (!~indexOf(['object', 'array', 'function'], typeHint)) {\n    if (typeHint === 'buffer') {\n      var json = value.toJSON();\n      // Based on the toJSON result\n      return jsonStringify(json.data && json.type ? json.data : json, 2)\n        .replace(/,(\\n|$)/g, '$1');\n    }\n\n    // IE7/IE8 has a bizarre String constructor; needs to be coerced\n    // into an array and back to obj.\n    if (typeHint === 'string' && typeof value === 'object') {\n      value = reduce(value.split(''), function(acc, char, idx) {\n        acc[idx] = char;\n        return acc;\n      }, {});\n      typeHint = 'object';\n    } else {\n      return jsonStringify(value);\n    }\n  }\n\n  for (var prop in value) {\n    if (Object.prototype.hasOwnProperty.call(value, prop)) {\n      return jsonStringify(exports.canonicalize(value, null, typeHint), 2).replace(/,(\\n|$)/g, '$1');\n    }\n  }\n\n  return emptyRepresentation(value, typeHint);\n};\n\n/**\n * like JSON.stringify but more sense.\n *\n * @api private\n * @param {Object}  object\n * @param {number=} spaces\n * @param {number=} depth\n * @returns {*}\n */\nfunction jsonStringify(object, spaces, depth) {\n  if (typeof spaces === 'undefined') {\n    // primitive types\n    return _stringify(object);\n  }\n\n  depth = depth || 1;\n  var space = spaces * depth;\n  var str = isArray(object) ? '[' : '{';\n  var end = isArray(object) ? ']' : '}';\n  var length = typeof object.length === 'number' ? object.length : exports.keys(object).length;\n  // `.repeat()` polyfill\n  function repeat(s, n) {\n    return new Array(n).join(s);\n  }\n\n  function _stringify(val) {\n    switch (type(val)) {\n      case 'null':\n      case 'undefined':\n        val = '[' + val + ']';\n        break;\n      case 'array':\n      case 'object':\n        val = jsonStringify(val, spaces, depth + 1);\n        break;\n      case 'boolean':\n      case 'regexp':\n      case 'symbol':\n      case 'number':\n        val = val === 0 && (1 / val) === -Infinity // `-0`\n          ? '-0'\n          : val.toString();\n        break;\n      case 'date':\n        var sDate;\n        if (isNaN(val.getTime())) { // Invalid date\n          sDate = val.toString();\n        } else {\n          sDate = val.toISOString ? val.toISOString() : toISOString(val);\n        }\n        val = '[Date: ' + sDate + ']';\n        break;\n      case 'buffer':\n        var json = val.toJSON();\n        // Based on the toJSON result\n        json = json.data && json.type ? json.data : json;\n        val = '[Buffer: ' + jsonStringify(json, 2, depth + 1) + ']';\n        break;\n      default:\n        val = (val === '[Function]' || val === '[Circular]')\n          ? val\n          : JSON.stringify(val); // string\n    }\n    return val;\n  }\n\n  for (var i in object) {\n    if (!Object.prototype.hasOwnProperty.call(object, i)) {\n      continue; // not my business\n    }\n    --length;\n    str += '\\n ' + repeat(' ', space)\n      + (isArray(object) ? '' : '\"' + i + '\": ') // key\n      + _stringify(object[i])                     // value\n      + (length ? ',' : '');                     // comma\n  }\n\n  return str\n    // [], {}\n    + (str.length !== 1 ? '\\n' + repeat(' ', --space) + end : end);\n}\n\n/**\n * Test if a value is a buffer.\n *\n * @api private\n * @param {*} value The value to test.\n * @return {boolean} True if `value` is a buffer, otherwise false\n */\nexports.isBuffer = function(value) {\n  return typeof Buffer !== 'undefined' && Buffer.isBuffer(value);\n};\n\n/**\n * Return a new Thing that has the keys in sorted order. Recursive.\n *\n * If the Thing...\n * - has already been seen, return string `'[Circular]'`\n * - is `undefined`, return string `'[undefined]'`\n * - is `null`, return value `null`\n * - is some other primitive, return the value\n * - is not a primitive or an `Array`, `Object`, or `Function`, return the value of the Thing's `toString()` method\n * - is a non-empty `Array`, `Object`, or `Function`, return the result of calling this function again.\n * - is an empty `Array`, `Object`, or `Function`, return the result of calling `emptyRepresentation()`\n *\n * @api private\n * @see {@link exports.stringify}\n * @param {*} value Thing to inspect.  May or may not have properties.\n * @param {Array} [stack=[]] Stack of seen values\n * @param {string} [typeHint] Type hint\n * @return {(Object|Array|Function|string|undefined)}\n */\nexports.canonicalize = function canonicalize(value, stack, typeHint) {\n  var canonicalizedObj;\n  /* eslint-disable no-unused-vars */\n  var prop;\n  /* eslint-enable no-unused-vars */\n  typeHint = typeHint || type(value);\n  function withStack(value, fn) {\n    stack.push(value);\n    fn();\n    stack.pop();\n  }\n\n  stack = stack || [];\n\n  if (indexOf(stack, value) !== -1) {\n    return '[Circular]';\n  }\n\n  switch (typeHint) {\n    case 'undefined':\n    case 'buffer':\n    case 'null':\n      canonicalizedObj = value;\n      break;\n    case 'array':\n      withStack(value, function() {\n        canonicalizedObj = exports.map(value, function(item) {\n          return exports.canonicalize(item, stack);\n        });\n      });\n      break;\n    case 'function':\n      /* eslint-disable guard-for-in */\n      for (prop in value) {\n        canonicalizedObj = {};\n        break;\n      }\n      /* eslint-enable guard-for-in */\n      if (!canonicalizedObj) {\n        canonicalizedObj = emptyRepresentation(value, typeHint);\n        break;\n      }\n    /* falls through */\n    case 'object':\n      canonicalizedObj = canonicalizedObj || {};\n      withStack(value, function() {\n        exports.forEach(exports.keys(value).sort(), function(key) {\n          canonicalizedObj[key] = exports.canonicalize(value[key], stack);\n        });\n      });\n      break;\n    case 'date':\n    case 'number':\n    case 'regexp':\n    case 'boolean':\n    case 'symbol':\n      canonicalizedObj = value;\n      break;\n    default:\n      canonicalizedObj = value + '';\n  }\n\n  return canonicalizedObj;\n};\n\n/**\n * Lookup file names at the given `path`.\n *\n * @api public\n * @param {string} path Base path to start searching from.\n * @param {string[]} extensions File extensions to look for.\n * @param {boolean} recursive Whether or not to recurse into subdirectories.\n * @return {string[]} An array of paths.\n */\nexports.lookupFiles = function lookupFiles(path, extensions, recursive) {\n  var files = [];\n  var re = new RegExp('\\\\.(' + extensions.join('|') + ')$');\n\n  if (!exists(path)) {\n    if (exists(path + '.js')) {\n      path += '.js';\n    } else {\n      files = glob.sync(path);\n      if (!files.length) {\n        throw new Error(\"cannot resolve path (or pattern) '\" + path + \"'\");\n      }\n      return files;\n    }\n  }\n\n  try {\n    var stat = statSync(path);\n    if (stat.isFile()) {\n      return path;\n    }\n  } catch (err) {\n    // ignore error\n    return;\n  }\n\n  readdirSync(path).forEach(function(file) {\n    file = join(path, file);\n    try {\n      var stat = statSync(file);\n      if (stat.isDirectory()) {\n        if (recursive) {\n          files = files.concat(lookupFiles(file, extensions, recursive));\n        }\n        return;\n      }\n    } catch (err) {\n      // ignore error\n      return;\n    }\n    if (!stat.isFile() || !re.test(file) || basename(file)[0] === '.') {\n      return;\n    }\n    files.push(file);\n  });\n\n  return files;\n};\n\n/**\n * Generate an undefined error with a message warning the user.\n *\n * @return {Error}\n */\n\nexports.undefinedError = function() {\n  return new Error('Caught undefined error, did you throw without specifying what?');\n};\n\n/**\n * Generate an undefined error if `err` is not defined.\n *\n * @param {Error} err\n * @return {Error}\n */\n\nexports.getError = function(err) {\n  return err || exports.undefinedError();\n};\n\n/**\n * @summary\n * This Filter based on `mocha-clean` module.(see: `github.com/rstacruz/mocha-clean`)\n * @description\n * When invoking this function you get a filter function that get the Error.stack as an input,\n * and return a prettify output.\n * (i.e: strip Mocha and internal node functions from stack trace).\n * @returns {Function}\n */\nexports.stackTraceFilter = function() {\n  // TODO: Replace with `process.browser`\n  var is = typeof document === 'undefined' ? { node: true } : { browser: true };\n  var slash = path.sep;\n  var cwd;\n  if (is.node) {\n    cwd = process.cwd() + slash;\n  } else {\n    cwd = (typeof location === 'undefined' ? window.location : location).href.replace(/\\/[^\\/]*$/, '/');\n    slash = '/';\n  }\n\n  function isMochaInternal(line) {\n    return (~line.indexOf('node_modules' + slash + 'mocha' + slash))\n      || (~line.indexOf('node_modules' + slash + 'mocha.js'))\n      || (~line.indexOf('bower_components' + slash + 'mocha.js'))\n      || (~line.indexOf(slash + 'mocha.js'));\n  }\n\n  function isNodeInternal(line) {\n    return (~line.indexOf('(timers.js:'))\n      || (~line.indexOf('(events.js:'))\n      || (~line.indexOf('(node.js:'))\n      || (~line.indexOf('(module.js:'))\n      || (~line.indexOf('GeneratorFunctionPrototype.next (native)'))\n      || false;\n  }\n\n  return function(stack) {\n    stack = stack.split('\\n');\n\n    stack = reduce(stack, function(list, line) {\n      if (isMochaInternal(line)) {\n        return list;\n      }\n\n      if (is.node && isNodeInternal(line)) {\n        return list;\n      }\n\n      // Clean up cwd(absolute)\n      if (/\\(?.+:\\d+:\\d+\\)?$/.test(line)) {\n        line = line.replace(cwd, '');\n      }\n\n      list.push(line);\n      return list;\n    }, []);\n\n    return stack.join('\\n');\n  };\n};\n\n/**\n * Crude, but effective.\n * @api\n * @param {*} value\n * @returns {boolean} Whether or not `value` is a Promise\n */\nexports.isPromise = function isPromise(value) {\n  return typeof value === 'object' && typeof value.then === 'function';\n};\n\n}).call(this,require('_process'),require(\"buffer\").Buffer)\n},{\"./to-iso-string\":37,\"_process\":67,\"buffer\":44,\"debug\":2,\"fs\":42,\"glob\":42,\"json3\":54,\"path\":42,\"util\":84}],39:[function(require,module,exports){\n'use strict'\n\nexports.toByteArray = toByteArray\nexports.fromByteArray = fromByteArray\n\nvar lookup = []\nvar revLookup = []\nvar Arr = typeof Uint8Array !== 'undefined' ? Uint8Array : Array\n\nfunction init () {\n  var code = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'\n  for (var i = 0, len = code.length; i < len; ++i) {\n    lookup[i] = code[i]\n    revLookup[code.charCodeAt(i)] = i\n  }\n\n  revLookup['-'.charCodeAt(0)] = 62\n  revLookup['_'.charCodeAt(0)] = 63\n}\n\ninit()\n\nfunction toByteArray (b64) {\n  var i, j, l, tmp, placeHolders, arr\n  var len = b64.length\n\n  if (len % 4 > 0) {\n    throw new Error('Invalid string. Length must be a multiple of 4')\n  }\n\n  // the number of equal signs (place holders)\n  // if there are two placeholders, than the two characters before it\n  // represent one byte\n  // if there is only one, then the three characters before it represent 2 bytes\n  // this is just a cheap hack to not do indexOf twice\n  placeHolders = b64[len - 2] === '=' ? 2 : b64[len - 1] === '=' ? 1 : 0\n\n  // base64 is 4/3 + up to two characters of the original data\n  arr = new Arr(len * 3 / 4 - placeHolders)\n\n  // if there are placeholders, only get up to the last complete 4 chars\n  l = placeHolders > 0 ? len - 4 : len\n\n  var L = 0\n\n  for (i = 0, j = 0; i < l; i += 4, j += 3) {\n    tmp = (revLookup[b64.charCodeAt(i)] << 18) | (revLookup[b64.charCodeAt(i + 1)] << 12) | (revLookup[b64.charCodeAt(i + 2)] << 6) | revLookup[b64.charCodeAt(i + 3)]\n    arr[L++] = (tmp >> 16) & 0xFF\n    arr[L++] = (tmp >> 8) & 0xFF\n    arr[L++] = tmp & 0xFF\n  }\n\n  if (placeHolders === 2) {\n    tmp = (revLookup[b64.charCodeAt(i)] << 2) | (revLookup[b64.charCodeAt(i + 1)] >> 4)\n    arr[L++] = tmp & 0xFF\n  } else if (placeHolders === 1) {\n    tmp = (revLookup[b64.charCodeAt(i)] << 10) | (revLookup[b64.charCodeAt(i + 1)] << 4) | (revLookup[b64.charCodeAt(i + 2)] >> 2)\n    arr[L++] = (tmp >> 8) & 0xFF\n    arr[L++] = tmp & 0xFF\n  }\n\n  return arr\n}\n\nfunction tripletToBase64 (num) {\n  return lookup[num >> 18 & 0x3F] + lookup[num >> 12 & 0x3F] + lookup[num >> 6 & 0x3F] + lookup[num & 0x3F]\n}\n\nfunction encodeChunk (uint8, start, end) {\n  var tmp\n  var output = []\n  for (var i = start; i < end; i += 3) {\n    tmp = (uint8[i] << 16) + (uint8[i + 1] << 8) + (uint8[i + 2])\n    output.push(tripletToBase64(tmp))\n  }\n  return output.join('')\n}\n\nfunction fromByteArray (uint8) {\n  var tmp\n  var len = uint8.length\n  var extraBytes = len % 3 // if we have 1 byte left, pad 2 bytes\n  var output = ''\n  var parts = []\n  var maxChunkLength = 16383 // must be multiple of 3\n\n  // go through the array every three bytes, we'll deal with trailing stuff later\n  for (var i = 0, len2 = len - extraBytes; i < len2; i += maxChunkLength) {\n    parts.push(encodeChunk(uint8, i, (i + maxChunkLength) > len2 ? len2 : (i + maxChunkLength)))\n  }\n\n  // pad the end with zeros, but make sure to not forget the extra bytes\n  if (extraBytes === 1) {\n    tmp = uint8[len - 1]\n    output += lookup[tmp >> 2]\n    output += lookup[(tmp << 4) & 0x3F]\n    output += '=='\n  } else if (extraBytes === 2) {\n    tmp = (uint8[len - 2] << 8) + (uint8[len - 1])\n    output += lookup[tmp >> 10]\n    output += lookup[(tmp >> 4) & 0x3F]\n    output += lookup[(tmp << 2) & 0x3F]\n    output += '='\n  }\n\n  parts.push(output)\n\n  return parts.join('')\n}\n\n},{}],40:[function(require,module,exports){\n\n},{}],41:[function(require,module,exports){\n(function (process){\nvar WritableStream = require('stream').Writable\nvar inherits = require('util').inherits\n\nmodule.exports = BrowserStdout\n\n\ninherits(BrowserStdout, WritableStream)\n\nfunction BrowserStdout(opts) {\n  if (!(this instanceof BrowserStdout)) return new BrowserStdout(opts)\n\n  opts = opts || {}\n  WritableStream.call(this, opts)\n  this.label = (opts.label !== undefined) ? opts.label : 'stdout'\n}\n\nBrowserStdout.prototype._write = function(chunks, encoding, cb) {\n  var output = chunks.toString ? chunks.toString() : chunks\n  if (this.label === false) {\n    console.log(output)\n  } else {\n    console.log(this.label+':', output)\n  }\n  process.nextTick(cb)\n}\n\n}).call(this,require('_process'))\n},{\"_process\":67,\"stream\":79,\"util\":84}],42:[function(require,module,exports){\narguments[4][40][0].apply(exports,arguments)\n},{\"dup\":40}],43:[function(require,module,exports){\n(function (global){\n'use strict';\n\nvar buffer = require('buffer');\nvar Buffer = buffer.Buffer;\nvar SlowBuffer = buffer.SlowBuffer;\nvar MAX_LEN = buffer.kMaxLength || 2147483647;\nexports.alloc = function alloc(size, fill, encoding) {\n  if (typeof Buffer.alloc === 'function') {\n    return Buffer.alloc(size, fill, encoding);\n  }\n  if (typeof encoding === 'number') {\n    throw new TypeError('encoding must not be number');\n  }\n  if (typeof size !== 'number') {\n    throw new TypeError('size must be a number');\n  }\n  if (size > MAX_LEN) {\n    throw new RangeError('size is too large');\n  }\n  var enc = encoding;\n  var _fill = fill;\n  if (_fill === undefined) {\n    enc = undefined;\n    _fill = 0;\n  }\n  var buf = new Buffer(size);\n  if (typeof _fill === 'string') {\n    var fillBuf = new Buffer(_fill, enc);\n    var flen = fillBuf.length;\n    var i = -1;\n    while (++i < size) {\n      buf[i] = fillBuf[i % flen];\n    }\n  } else {\n    buf.fill(_fill);\n  }\n  return buf;\n}\nexports.allocUnsafe = function allocUnsafe(size) {\n  if (typeof Buffer.allocUnsafe === 'function') {\n    return Buffer.allocUnsafe(size);\n  }\n  if (typeof size !== 'number') {\n    throw new TypeError('size must be a number');\n  }\n  if (size > MAX_LEN) {\n    throw new RangeError('size is too large');\n  }\n  return new Buffer(size);\n}\nexports.from = function from(value, encodingOrOffset, length) {\n  if (typeof Buffer.from === 'function' && (!global.Uint8Array || Uint8Array.from !== Buffer.from)) {\n    return Buffer.from(value, encodingOrOffset, length);\n  }\n  if (typeof value === 'number') {\n    throw new TypeError('\"value\" argument must not be a number');\n  }\n  if (typeof value === 'string') {\n    return new Buffer(value, encodingOrOffset);\n  }\n  if (typeof ArrayBuffer !== 'undefined' && value instanceof ArrayBuffer) {\n    var offset = encodingOrOffset;\n    if (arguments.length === 1) {\n      return new Buffer(value);\n    }\n    if (typeof offset === 'undefined') {\n      offset = 0;\n    }\n    var len = length;\n    if (typeof len === 'undefined') {\n      len = value.byteLength - offset;\n    }\n    if (offset >= value.byteLength) {\n      throw new RangeError('\\'offset\\' is out of bounds');\n    }\n    if (len > value.byteLength - offset) {\n      throw new RangeError('\\'length\\' is out of bounds');\n    }\n    return new Buffer(value.slice(offset, offset + len));\n  }\n  if (Buffer.isBuffer(value)) {\n    var out = new Buffer(value.length);\n    value.copy(out, 0, 0, value.length);\n    return out;\n  }\n  if (value) {\n    if (Array.isArray(value) || (typeof ArrayBuffer !== 'undefined' && value.buffer instanceof ArrayBuffer) || 'length' in value) {\n      return new Buffer(value);\n    }\n    if (value.type === 'Buffer' && Array.isArray(value.data)) {\n      return new Buffer(value.data);\n    }\n  }\n\n  throw new TypeError('First argument must be a string, Buffer, ' + 'ArrayBuffer, Array, or array-like object.');\n}\nexports.allocUnsafeSlow = function allocUnsafeSlow(size) {\n  if (typeof Buffer.allocUnsafeSlow === 'function') {\n    return Buffer.allocUnsafeSlow(size);\n  }\n  if (typeof size !== 'number') {\n    throw new TypeError('size must be a number');\n  }\n  if (size >= MAX_LEN) {\n    throw new RangeError('size is too large');\n  }\n  return new SlowBuffer(size);\n}\n\n}).call(this,typeof global !== \"undefined\" ? global : typeof self !== \"undefined\" ? self : typeof window !== \"undefined\" ? window : {})\n},{\"buffer\":44}],44:[function(require,module,exports){\n(function (global){\n/*!\n * The buffer module from node.js, for the browser.\n *\n * @author   Feross Aboukhadijeh <feross@feross.org> <http://feross.org>\n * @license  MIT\n */\n/* eslint-disable no-proto */\n\n'use strict'\n\nvar base64 = require('base64-js')\nvar ieee754 = require('ieee754')\nvar isArray = require('isarray')\n\nexports.Buffer = Buffer\nexports.SlowBuffer = SlowBuffer\nexports.INSPECT_MAX_BYTES = 50\n\n/**\n * If `Buffer.TYPED_ARRAY_SUPPORT`:\n *   === true    Use Uint8Array implementation (fastest)\n *   === false   Use Object implementation (most compatible, even IE6)\n *\n * Browsers that support typed arrays are IE 10+, Firefox 4+, Chrome 7+, Safari 5.1+,\n * Opera 11.6+, iOS 4.2+.\n *\n * Due to various browser bugs, sometimes the Object implementation will be used even\n * when the browser supports typed arrays.\n *\n * Note:\n *\n *   - Firefox 4-29 lacks support for adding new properties to `Uint8Array` instances,\n *     See: https://bugzilla.mozilla.org/show_bug.cgi?id=695438.\n *\n *   - Chrome 9-10 is missing the `TypedArray.prototype.subarray` function.\n *\n *   - IE10 has a broken `TypedArray.prototype.subarray` function which returns arrays of\n *     incorrect length in some situations.\n\n * We detect these buggy browsers and set `Buffer.TYPED_ARRAY_SUPPORT` to `false` so they\n * get the Object implementation, which is slower but behaves correctly.\n */\nBuffer.TYPED_ARRAY_SUPPORT = global.TYPED_ARRAY_SUPPORT !== undefined\n  ? global.TYPED_ARRAY_SUPPORT\n  : typedArraySupport()\n\n/*\n * Export kMaxLength after typed array support is determined.\n */\nexports.kMaxLength = kMaxLength()\n\nfunction typedArraySupport () {\n  try {\n    var arr = new Uint8Array(1)\n    arr.__proto__ = {__proto__: Uint8Array.prototype, foo: function () { return 42 }}\n    return arr.foo() === 42 && // typed array instances can be augmented\n        typeof arr.subarray === 'function' && // chrome 9-10 lack `subarray`\n        arr.subarray(1, 1).byteLength === 0 // ie10 has broken `subarray`\n  } catch (e) {\n    return false\n  }\n}\n\nfunction kMaxLength () {\n  return Buffer.TYPED_ARRAY_SUPPORT\n    ? 0x7fffffff\n    : 0x3fffffff\n}\n\nfunction createBuffer (that, length) {\n  if (kMaxLength() < length) {\n    throw new RangeError('Invalid typed array length')\n  }\n  if (Buffer.TYPED_ARRAY_SUPPORT) {\n    // Return an augmented `Uint8Array` instance, for best performance\n    that = new Uint8Array(length)\n    that.__proto__ = Buffer.prototype\n  } else {\n    // Fallback: Return an object instance of the Buffer class\n    if (that === null) {\n      that = new Buffer(length)\n    }\n    that.length = length\n  }\n\n  return that\n}\n\n/**\n * The Buffer constructor returns instances of `Uint8Array` that have their\n * prototype changed to `Buffer.prototype`. Furthermore, `Buffer` is a subclass of\n * `Uint8Array`, so the returned instances will have all the node `Buffer` methods\n * and the `Uint8Array` methods. Square bracket notation works as expected -- it\n * returns a single octet.\n *\n * The `Uint8Array` prototype remains unmodified.\n */\n\nfunction Buffer (arg, encodingOrOffset, length) {\n  if (!Buffer.TYPED_ARRAY_SUPPORT && !(this instanceof Buffer)) {\n    return new Buffer(arg, encodingOrOffset, length)\n  }\n\n  // Common case.\n  if (typeof arg === 'number') {\n    if (typeof encodingOrOffset === 'string') {\n      throw new Error(\n        'If encoding is specified then the first argument must be a string'\n      )\n    }\n    return allocUnsafe(this, arg)\n  }\n  return from(this, arg, encodingOrOffset, length)\n}\n\nBuffer.poolSize = 8192 // not used by this implementation\n\n// TODO: Legacy, not needed anymore. Remove in next major version.\nBuffer._augment = function (arr) {\n  arr.__proto__ = Buffer.prototype\n  return arr\n}\n\nfunction from (that, value, encodingOrOffset, length) {\n  if (typeof value === 'number') {\n    throw new TypeError('\"value\" argument must not be a number')\n  }\n\n  if (typeof ArrayBuffer !== 'undefined' && value instanceof ArrayBuffer) {\n    return fromArrayBuffer(that, value, encodingOrOffset, length)\n  }\n\n  if (typeof value === 'string') {\n    return fromString(that, value, encodingOrOffset)\n  }\n\n  return fromObject(that, value)\n}\n\n/**\n * Functionally equivalent to Buffer(arg, encoding) but throws a TypeError\n * if value is a number.\n * Buffer.from(str[, encoding])\n * Buffer.from(array)\n * Buffer.from(buffer)\n * Buffer.from(arrayBuffer[, byteOffset[, length]])\n **/\nBuffer.from = function (value, encodingOrOffset, length) {\n  return from(null, value, encodingOrOffset, length)\n}\n\nif (Buffer.TYPED_ARRAY_SUPPORT) {\n  Buffer.prototype.__proto__ = Uint8Array.prototype\n  Buffer.__proto__ = Uint8Array\n  if (typeof Symbol !== 'undefined' && Symbol.species &&\n      Buffer[Symbol.species] === Buffer) {\n    // Fix subarray() in ES2016. See: https://github.com/feross/buffer/pull/97\n    Object.defineProperty(Buffer, Symbol.species, {\n      value: null,\n      configurable: true\n    })\n  }\n}\n\nfunction assertSize (size) {\n  if (typeof size !== 'number') {\n    throw new TypeError('\"size\" argument must be a number')\n  } else if (size < 0) {\n    throw new RangeError('\"size\" argument must not be negative')\n  }\n}\n\nfunction alloc (that, size, fill, encoding) {\n  assertSize(size)\n  if (size <= 0) {\n    return createBuffer(that, size)\n  }\n  if (fill !== undefined) {\n    // Only pay attention to encoding if it's a string. This\n    // prevents accidentally sending in a number that would\n    // be interpretted as a start offset.\n    return typeof encoding === 'string'\n      ? createBuffer(that, size).fill(fill, encoding)\n      : createBuffer(that, size).fill(fill)\n  }\n  return createBuffer(that, size)\n}\n\n/**\n * Creates a new filled Buffer instance.\n * alloc(size[, fill[, encoding]])\n **/\nBuffer.alloc = function (size, fill, encoding) {\n  return alloc(null, size, fill, encoding)\n}\n\nfunction allocUnsafe (that, size) {\n  assertSize(size)\n  that = createBuffer(that, size < 0 ? 0 : checked(size) | 0)\n  if (!Buffer.TYPED_ARRAY_SUPPORT) {\n    for (var i = 0; i < size; ++i) {\n      that[i] = 0\n    }\n  }\n  return that\n}\n\n/**\n * Equivalent to Buffer(num), by default creates a non-zero-filled Buffer instance.\n * */\nBuffer.allocUnsafe = function (size) {\n  return allocUnsafe(null, size)\n}\n/**\n * Equivalent to SlowBuffer(num), by default creates a non-zero-filled Buffer instance.\n */\nBuffer.allocUnsafeSlow = function (size) {\n  return allocUnsafe(null, size)\n}\n\nfunction fromString (that, string, encoding) {\n  if (typeof encoding !== 'string' || encoding === '') {\n    encoding = 'utf8'\n  }\n\n  if (!Buffer.isEncoding(encoding)) {\n    throw new TypeError('\"encoding\" must be a valid string encoding')\n  }\n\n  var length = byteLength(string, encoding) | 0\n  that = createBuffer(that, length)\n\n  var actual = that.write(string, encoding)\n\n  if (actual !== length) {\n    // Writing a hex string, for example, that contains invalid characters will\n    // cause everything after the first invalid character to be ignored. (e.g.\n    // 'abxxcd' will be treated as 'ab')\n    that = that.slice(0, actual)\n  }\n\n  return that\n}\n\nfunction fromArrayLike (that, array) {\n  var length = array.length < 0 ? 0 : checked(array.length) | 0\n  that = createBuffer(that, length)\n  for (var i = 0; i < length; i += 1) {\n    that[i] = array[i] & 255\n  }\n  return that\n}\n\nfunction fromArrayBuffer (that, array, byteOffset, length) {\n  array.byteLength // this throws if `array` is not a valid ArrayBuffer\n\n  if (byteOffset < 0 || array.byteLength < byteOffset) {\n    throw new RangeError('\\'offset\\' is out of bounds')\n  }\n\n  if (array.byteLength < byteOffset + (length || 0)) {\n    throw new RangeError('\\'length\\' is out of bounds')\n  }\n\n  if (byteOffset === undefined && length === undefined) {\n    array = new Uint8Array(array)\n  } else if (length === undefined) {\n    array = new Uint8Array(array, byteOffset)\n  } else {\n    array = new Uint8Array(array, byteOffset, length)\n  }\n\n  if (Buffer.TYPED_ARRAY_SUPPORT) {\n    // Return an augmented `Uint8Array` instance, for best performance\n    that = array\n    that.__proto__ = Buffer.prototype\n  } else {\n    // Fallback: Return an object instance of the Buffer class\n    that = fromArrayLike(that, array)\n  }\n  return that\n}\n\nfunction fromObject (that, obj) {\n  if (Buffer.isBuffer(obj)) {\n    var len = checked(obj.length) | 0\n    that = createBuffer(that, len)\n\n    if (that.length === 0) {\n      return that\n    }\n\n    obj.copy(that, 0, 0, len)\n    return that\n  }\n\n  if (obj) {\n    if ((typeof ArrayBuffer !== 'undefined' &&\n        obj.buffer instanceof ArrayBuffer) || 'length' in obj) {\n      if (typeof obj.length !== 'number' || isnan(obj.length)) {\n        return createBuffer(that, 0)\n      }\n      return fromArrayLike(that, obj)\n    }\n\n    if (obj.type === 'Buffer' && isArray(obj.data)) {\n      return fromArrayLike(that, obj.data)\n    }\n  }\n\n  throw new TypeError('First argument must be a string, Buffer, ArrayBuffer, Array, or array-like object.')\n}\n\nfunction checked (length) {\n  // Note: cannot use `length < kMaxLength()` here because that fails when\n  // length is NaN (which is otherwise coerced to zero.)\n  if (length >= kMaxLength()) {\n    throw new RangeError('Attempt to allocate Buffer larger than maximum ' +\n                         'size: 0x' + kMaxLength().toString(16) + ' bytes')\n  }\n  return length | 0\n}\n\nfunction SlowBuffer (length) {\n  if (+length != length) { // eslint-disable-line eqeqeq\n    length = 0\n  }\n  return Buffer.alloc(+length)\n}\n\nBuffer.isBuffer = function isBuffer (b) {\n  return !!(b != null && b._isBuffer)\n}\n\nBuffer.compare = function compare (a, b) {\n  if (!Buffer.isBuffer(a) || !Buffer.isBuffer(b)) {\n    throw new TypeError('Arguments must be Buffers')\n  }\n\n  if (a === b) return 0\n\n  var x = a.length\n  var y = b.length\n\n  for (var i = 0, len = Math.min(x, y); i < len; ++i) {\n    if (a[i] !== b[i]) {\n      x = a[i]\n      y = b[i]\n      break\n    }\n  }\n\n  if (x < y) return -1\n  if (y < x) return 1\n  return 0\n}\n\nBuffer.isEncoding = function isEncoding (encoding) {\n  switch (String(encoding).toLowerCase()) {\n    case 'hex':\n    case 'utf8':\n    case 'utf-8':\n    case 'ascii':\n    case 'latin1':\n    case 'binary':\n    case 'base64':\n    case 'ucs2':\n    case 'ucs-2':\n    case 'utf16le':\n    case 'utf-16le':\n      return true\n    default:\n      return false\n  }\n}\n\nBuffer.concat = function concat (list, length) {\n  if (!isArray(list)) {\n    throw new TypeError('\"list\" argument must be an Array of Buffers')\n  }\n\n  if (list.length === 0) {\n    return Buffer.alloc(0)\n  }\n\n  var i\n  if (length === undefined) {\n    length = 0\n    for (i = 0; i < list.length; ++i) {\n      length += list[i].length\n    }\n  }\n\n  var buffer = Buffer.allocUnsafe(length)\n  var pos = 0\n  for (i = 0; i < list.length; ++i) {\n    var buf = list[i]\n    if (!Buffer.isBuffer(buf)) {\n      throw new TypeError('\"list\" argument must be an Array of Buffers')\n    }\n    buf.copy(buffer, pos)\n    pos += buf.length\n  }\n  return buffer\n}\n\nfunction byteLength (string, encoding) {\n  if (Buffer.isBuffer(string)) {\n    return string.length\n  }\n  if (typeof ArrayBuffer !== 'undefined' && typeof ArrayBuffer.isView === 'function' &&\n      (ArrayBuffer.isView(string) || string instanceof ArrayBuffer)) {\n    return string.byteLength\n  }\n  if (typeof string !== 'string') {\n    string = '' + string\n  }\n\n  var len = string.length\n  if (len === 0) return 0\n\n  // Use a for loop to avoid recursion\n  var loweredCase = false\n  for (;;) {\n    switch (encoding) {\n      case 'ascii':\n      case 'latin1':\n      case 'binary':\n        return len\n      case 'utf8':\n      case 'utf-8':\n      case undefined:\n        return utf8ToBytes(string).length\n      case 'ucs2':\n      case 'ucs-2':\n      case 'utf16le':\n      case 'utf-16le':\n        return len * 2\n      case 'hex':\n        return len >>> 1\n      case 'base64':\n        return base64ToBytes(string).length\n      default:\n        if (loweredCase) return utf8ToBytes(string).length // assume utf8\n        encoding = ('' + encoding).toLowerCase()\n        loweredCase = true\n    }\n  }\n}\nBuffer.byteLength = byteLength\n\nfunction slowToString (encoding, start, end) {\n  var loweredCase = false\n\n  // No need to verify that \"this.length <= MAX_UINT32\" since it's a read-only\n  // property of a typed array.\n\n  // This behaves neither like String nor Uint8Array in that we set start/end\n  // to their upper/lower bounds if the value passed is out of range.\n  // undefined is handled specially as per ECMA-262 6th Edition,\n  // Section 13.3.3.7 Runtime Semantics: KeyedBindingInitialization.\n  if (start === undefined || start < 0) {\n    start = 0\n  }\n  // Return early if start > this.length. Done here to prevent potential uint32\n  // coercion fail below.\n  if (start > this.length) {\n    return ''\n  }\n\n  if (end === undefined || end > this.length) {\n    end = this.length\n  }\n\n  if (end <= 0) {\n    return ''\n  }\n\n  // Force coersion to uint32. This will also coerce falsey/NaN values to 0.\n  end >>>= 0\n  start >>>= 0\n\n  if (end <= start) {\n    return ''\n  }\n\n  if (!encoding) encoding = 'utf8'\n\n  while (true) {\n    switch (encoding) {\n      case 'hex':\n        return hexSlice(this, start, end)\n\n      case 'utf8':\n      case 'utf-8':\n        return utf8Slice(this, start, end)\n\n      case 'ascii':\n        return asciiSlice(this, start, end)\n\n      case 'latin1':\n      case 'binary':\n        return latin1Slice(this, start, end)\n\n      case 'base64':\n        return base64Slice(this, start, end)\n\n      case 'ucs2':\n      case 'ucs-2':\n      case 'utf16le':\n      case 'utf-16le':\n        return utf16leSlice(this, start, end)\n\n      default:\n        if (loweredCase) throw new TypeError('Unknown encoding: ' + encoding)\n        encoding = (encoding + '').toLowerCase()\n        loweredCase = true\n    }\n  }\n}\n\n// The property is used by `Buffer.isBuffer` and `is-buffer` (in Safari 5-7) to detect\n// Buffer instances.\nBuffer.prototype._isBuffer = true\n\nfunction swap (b, n, m) {\n  var i = b[n]\n  b[n] = b[m]\n  b[m] = i\n}\n\nBuffer.prototype.swap16 = function swap16 () {\n  var len = this.length\n  if (len % 2 !== 0) {\n    throw new RangeError('Buffer size must be a multiple of 16-bits')\n  }\n  for (var i = 0; i < len; i += 2) {\n    swap(this, i, i + 1)\n  }\n  return this\n}\n\nBuffer.prototype.swap32 = function swap32 () {\n  var len = this.length\n  if (len % 4 !== 0) {\n    throw new RangeError('Buffer size must be a multiple of 32-bits')\n  }\n  for (var i = 0; i < len; i += 4) {\n    swap(this, i, i + 3)\n    swap(this, i + 1, i + 2)\n  }\n  return this\n}\n\nBuffer.prototype.swap64 = function swap64 () {\n  var len = this.length\n  if (len % 8 !== 0) {\n    throw new RangeError('Buffer size must be a multiple of 64-bits')\n  }\n  for (var i = 0; i < len; i += 8) {\n    swap(this, i, i + 7)\n    swap(this, i + 1, i + 6)\n    swap(this, i + 2, i + 5)\n    swap(this, i + 3, i + 4)\n  }\n  return this\n}\n\nBuffer.prototype.toString = function toString () {\n  var length = this.length | 0\n  if (length === 0) return ''\n  if (arguments.length === 0) return utf8Slice(this, 0, length)\n  return slowToString.apply(this, arguments)\n}\n\nBuffer.prototype.equals = function equals (b) {\n  if (!Buffer.isBuffer(b)) throw new TypeError('Argument must be a Buffer')\n  if (this === b) return true\n  return Buffer.compare(this, b) === 0\n}\n\nBuffer.prototype.inspect = function inspect () {\n  var str = ''\n  var max = exports.INSPECT_MAX_BYTES\n  if (this.length > 0) {\n    str = this.toString('hex', 0, max).match(/.{2}/g).join(' ')\n    if (this.length > max) str += ' ... '\n  }\n  return '<Buffer ' + str + '>'\n}\n\nBuffer.prototype.compare = function compare (target, start, end, thisStart, thisEnd) {\n  if (!Buffer.isBuffer(target)) {\n    throw new TypeError('Argument must be a Buffer')\n  }\n\n  if (start === undefined) {\n    start = 0\n  }\n  if (end === undefined) {\n    end = target ? target.length : 0\n  }\n  if (thisStart === undefined) {\n    thisStart = 0\n  }\n  if (thisEnd === undefined) {\n    thisEnd = this.length\n  }\n\n  if (start < 0 || end > target.length || thisStart < 0 || thisEnd > this.length) {\n    throw new RangeError('out of range index')\n  }\n\n  if (thisStart >= thisEnd && start >= end) {\n    return 0\n  }\n  if (thisStart >= thisEnd) {\n    return -1\n  }\n  if (start >= end) {\n    return 1\n  }\n\n  start >>>= 0\n  end >>>= 0\n  thisStart >>>= 0\n  thisEnd >>>= 0\n\n  if (this === target) return 0\n\n  var x = thisEnd - thisStart\n  var y = end - start\n  var len = Math.min(x, y)\n\n  var thisCopy = this.slice(thisStart, thisEnd)\n  var targetCopy = target.slice(start, end)\n\n  for (var i = 0; i < len; ++i) {\n    if (thisCopy[i] !== targetCopy[i]) {\n      x = thisCopy[i]\n      y = targetCopy[i]\n      break\n    }\n  }\n\n  if (x < y) return -1\n  if (y < x) return 1\n  return 0\n}\n\n// Finds either the first index of `val` in `buffer` at offset >= `byteOffset`,\n// OR the last index of `val` in `buffer` at offset <= `byteOffset`.\n//\n// Arguments:\n// - buffer - a Buffer to search\n// - val - a string, Buffer, or number\n// - byteOffset - an index into `buffer`; will be clamped to an int32\n// - encoding - an optional encoding, relevant is val is a string\n// - dir - true for indexOf, false for lastIndexOf\nfunction bidirectionalIndexOf (buffer, val, byteOffset, encoding, dir) {\n  // Empty buffer means no match\n  if (buffer.length === 0) return -1\n\n  // Normalize byteOffset\n  if (typeof byteOffset === 'string') {\n    encoding = byteOffset\n    byteOffset = 0\n  } else if (byteOffset > 0x7fffffff) {\n    byteOffset = 0x7fffffff\n  } else if (byteOffset < -0x80000000) {\n    byteOffset = -0x80000000\n  }\n  byteOffset = +byteOffset  // Coerce to Number.\n  if (isNaN(byteOffset)) {\n    // byteOffset: it it's undefined, null, NaN, \"foo\", etc, search whole buffer\n    byteOffset = dir ? 0 : (buffer.length - 1)\n  }\n\n  // Normalize byteOffset: negative offsets start from the end of the buffer\n  if (byteOffset < 0) byteOffset = buffer.length + byteOffset\n  if (byteOffset >= buffer.length) {\n    if (dir) return -1\n    else byteOffset = buffer.length - 1\n  } else if (byteOffset < 0) {\n    if (dir) byteOffset = 0\n    else return -1\n  }\n\n  // Normalize val\n  if (typeof val === 'string') {\n    val = Buffer.from(val, encoding)\n  }\n\n  // Finally, search either indexOf (if dir is true) or lastIndexOf\n  if (Buffer.isBuffer(val)) {\n    // Special case: looking for empty string/buffer always fails\n    if (val.length === 0) {\n      return -1\n    }\n    return arrayIndexOf(buffer, val, byteOffset, encoding, dir)\n  } else if (typeof val === 'number') {\n    val = val & 0xFF // Search for a byte value [0-255]\n    if (Buffer.TYPED_ARRAY_SUPPORT &&\n        typeof Uint8Array.prototype.indexOf === 'function') {\n      if (dir) {\n        return Uint8Array.prototype.indexOf.call(buffer, val, byteOffset)\n      } else {\n        return Uint8Array.prototype.lastIndexOf.call(buffer, val, byteOffset)\n      }\n    }\n    return arrayIndexOf(buffer, [ val ], byteOffset, encoding, dir)\n  }\n\n  throw new TypeError('val must be string, number or Buffer')\n}\n\nfunction arrayIndexOf (arr, val, byteOffset, encoding, dir) {\n  var indexSize = 1\n  var arrLength = arr.length\n  var valLength = val.length\n\n  if (encoding !== undefined) {\n    encoding = String(encoding).toLowerCase()\n    if (encoding === 'ucs2' || encoding === 'ucs-2' ||\n        encoding === 'utf16le' || encoding === 'utf-16le') {\n      if (arr.length < 2 || val.length < 2) {\n        return -1\n      }\n      indexSize = 2\n      arrLength /= 2\n      valLength /= 2\n      byteOffset /= 2\n    }\n  }\n\n  function read (buf, i) {\n    if (indexSize === 1) {\n      return buf[i]\n    } else {\n      return buf.readUInt16BE(i * indexSize)\n    }\n  }\n\n  var i\n  if (dir) {\n    var foundIndex = -1\n    for (i = byteOffset; i < arrLength; i++) {\n      if (read(arr, i) === read(val, foundIndex === -1 ? 0 : i - foundIndex)) {\n        if (foundIndex === -1) foundIndex = i\n        if (i - foundIndex + 1 === valLength) return foundIndex * indexSize\n      } else {\n        if (foundIndex !== -1) i -= i - foundIndex\n        foundIndex = -1\n      }\n    }\n  } else {\n    if (byteOffset + valLength > arrLength) byteOffset = arrLength - valLength\n    for (i = byteOffset; i >= 0; i--) {\n      var found = true\n      for (var j = 0; j < valLength; j++) {\n        if (read(arr, i + j) !== read(val, j)) {\n          found = false\n          break\n        }\n      }\n      if (found) return i\n    }\n  }\n\n  return -1\n}\n\nBuffer.prototype.includes = function includes (val, byteOffset, encoding) {\n  return this.indexOf(val, byteOffset, encoding) !== -1\n}\n\nBuffer.prototype.indexOf = function indexOf (val, byteOffset, encoding) {\n  return bidirectionalIndexOf(this, val, byteOffset, encoding, true)\n}\n\nBuffer.prototype.lastIndexOf = function lastIndexOf (val, byteOffset, encoding) {\n  return bidirectionalIndexOf(this, val, byteOffset, encoding, false)\n}\n\nfunction hexWrite (buf, string, offset, length) {\n  offset = Number(offset) || 0\n  var remaining = buf.length - offset\n  if (!length) {\n    length = remaining\n  } else {\n    length = Number(length)\n    if (length > remaining) {\n      length = remaining\n    }\n  }\n\n  // must be an even number of digits\n  var strLen = string.length\n  if (strLen % 2 !== 0) throw new TypeError('Invalid hex string')\n\n  if (length > strLen / 2) {\n    length = strLen / 2\n  }\n  for (var i = 0; i < length; ++i) {\n    var parsed = parseInt(string.substr(i * 2, 2), 16)\n    if (isNaN(parsed)) return i\n    buf[offset + i] = parsed\n  }\n  return i\n}\n\nfunction utf8Write (buf, string, offset, length) {\n  return blitBuffer(utf8ToBytes(string, buf.length - offset), buf, offset, length)\n}\n\nfunction asciiWrite (buf, string, offset, length) {\n  return blitBuffer(asciiToBytes(string), buf, offset, length)\n}\n\nfunction latin1Write (buf, string, offset, length) {\n  return asciiWrite(buf, string, offset, length)\n}\n\nfunction base64Write (buf, string, offset, length) {\n  return blitBuffer(base64ToBytes(string), buf, offset, length)\n}\n\nfunction ucs2Write (buf, string, offset, length) {\n  return blitBuffer(utf16leToBytes(string, buf.length - offset), buf, offset, length)\n}\n\nBuffer.prototype.write = function write (string, offset, length, encoding) {\n  // Buffer#write(string)\n  if (offset === undefined) {\n    encoding = 'utf8'\n    length = this.length\n    offset = 0\n  // Buffer#write(string, encoding)\n  } else if (length === undefined && typeof offset === 'string') {\n    encoding = offset\n    length = this.length\n    offset = 0\n  // Buffer#write(string, offset[, length][, encoding])\n  } else if (isFinite(offset)) {\n    offset = offset | 0\n    if (isFinite(length)) {\n      length = length | 0\n      if (encoding === undefined) encoding = 'utf8'\n    } else {\n      encoding = length\n      length = undefined\n    }\n  // legacy write(string, encoding, offset, length) - remove in v0.13\n  } else {\n    throw new Error(\n      'Buffer.write(string, encoding, offset[, length]) is no longer supported'\n    )\n  }\n\n  var remaining = this.length - offset\n  if (length === undefined || length > remaining) length = remaining\n\n  if ((string.length > 0 && (length < 0 || offset < 0)) || offset > this.length) {\n    throw new RangeError('Attempt to write outside buffer bounds')\n  }\n\n  if (!encoding) encoding = 'utf8'\n\n  var loweredCase = false\n  for (;;) {\n    switch (encoding) {\n      case 'hex':\n        return hexWrite(this, string, offset, length)\n\n      case 'utf8':\n      case 'utf-8':\n        return utf8Write(this, string, offset, length)\n\n      case 'ascii':\n        return asciiWrite(this, string, offset, length)\n\n      case 'latin1':\n      case 'binary':\n        return latin1Write(this, string, offset, length)\n\n      case 'base64':\n        // Warning: maxLength not taken into account in base64Write\n        return base64Write(this, string, offset, length)\n\n      case 'ucs2':\n      case 'ucs-2':\n      case 'utf16le':\n      case 'utf-16le':\n        return ucs2Write(this, string, offset, length)\n\n      default:\n        if (loweredCase) throw new TypeError('Unknown encoding: ' + encoding)\n        encoding = ('' + encoding).toLowerCase()\n        loweredCase = true\n    }\n  }\n}\n\nBuffer.prototype.toJSON = function toJSON () {\n  return {\n    type: 'Buffer',\n    data: Array.prototype.slice.call(this._arr || this, 0)\n  }\n}\n\nfunction base64Slice (buf, start, end) {\n  if (start === 0 && end === buf.length) {\n    return base64.fromByteArray(buf)\n  } else {\n    return base64.fromByteArray(buf.slice(start, end))\n  }\n}\n\nfunction utf8Slice (buf, start, end) {\n  end = Math.min(buf.length, end)\n  var res = []\n\n  var i = start\n  while (i < end) {\n    var firstByte = buf[i]\n    var codePoint = null\n    var bytesPerSequence = (firstByte > 0xEF) ? 4\n      : (firstByte > 0xDF) ? 3\n      : (firstByte > 0xBF) ? 2\n      : 1\n\n    if (i + bytesPerSequence <= end) {\n      var secondByte, thirdByte, fourthByte, tempCodePoint\n\n      switch (bytesPerSequence) {\n        case 1:\n          if (firstByte < 0x80) {\n            codePoint = firstByte\n          }\n          break\n        case 2:\n          secondByte = buf[i + 1]\n          if ((secondByte & 0xC0) === 0x80) {\n            tempCodePoint = (firstByte & 0x1F) << 0x6 | (secondByte & 0x3F)\n            if (tempCodePoint > 0x7F) {\n              codePoint = tempCodePoint\n            }\n          }\n          break\n        case 3:\n          secondByte = buf[i + 1]\n          thirdByte = buf[i + 2]\n          if ((secondByte & 0xC0) === 0x80 && (thirdByte & 0xC0) === 0x80) {\n            tempCodePoint = (firstByte & 0xF) << 0xC | (secondByte & 0x3F) << 0x6 | (thirdByte & 0x3F)\n            if (tempCodePoint > 0x7FF && (tempCodePoint < 0xD800 || tempCodePoint > 0xDFFF)) {\n              codePoint = tempCodePoint\n            }\n          }\n          break\n        case 4:\n          secondByte = buf[i + 1]\n          thirdByte = buf[i + 2]\n          fourthByte = buf[i + 3]\n          if ((secondByte & 0xC0) === 0x80 && (thirdByte & 0xC0) === 0x80 && (fourthByte & 0xC0) === 0x80) {\n            tempCodePoint = (firstByte & 0xF) << 0x12 | (secondByte & 0x3F) << 0xC | (thirdByte & 0x3F) << 0x6 | (fourthByte & 0x3F)\n            if (tempCodePoint > 0xFFFF && tempCodePoint < 0x110000) {\n              codePoint = tempCodePoint\n            }\n          }\n      }\n    }\n\n    if (codePoint === null) {\n      // we did not generate a valid codePoint so insert a\n      // replacement char (U+FFFD) and advance only 1 byte\n      codePoint = 0xFFFD\n      bytesPerSequence = 1\n    } else if (codePoint > 0xFFFF) {\n      // encode to utf16 (surrogate pair dance)\n      codePoint -= 0x10000\n      res.push(codePoint >>> 10 & 0x3FF | 0xD800)\n      codePoint = 0xDC00 | codePoint & 0x3FF\n    }\n\n    res.push(codePoint)\n    i += bytesPerSequence\n  }\n\n  return decodeCodePointsArray(res)\n}\n\n// Based on http://stackoverflow.com/a/22747272/680742, the browser with\n// the lowest limit is Chrome, with 0x10000 args.\n// We go 1 magnitude less, for safety\nvar MAX_ARGUMENTS_LENGTH = 0x1000\n\nfunction decodeCodePointsArray (codePoints) {\n  var len = codePoints.length\n  if (len <= MAX_ARGUMENTS_LENGTH) {\n    return String.fromCharCode.apply(String, codePoints) // avoid extra slice()\n  }\n\n  // Decode in chunks to avoid \"call stack size exceeded\".\n  var res = ''\n  var i = 0\n  while (i < len) {\n    res += String.fromCharCode.apply(\n      String,\n      codePoints.slice(i, i += MAX_ARGUMENTS_LENGTH)\n    )\n  }\n  return res\n}\n\nfunction asciiSlice (buf, start, end) {\n  var ret = ''\n  end = Math.min(buf.length, end)\n\n  for (var i = start; i < end; ++i) {\n    ret += String.fromCharCode(buf[i] & 0x7F)\n  }\n  return ret\n}\n\nfunction latin1Slice (buf, start, end) {\n  var ret = ''\n  end = Math.min(buf.length, end)\n\n  for (var i = start; i < end; ++i) {\n    ret += String.fromCharCode(buf[i])\n  }\n  return ret\n}\n\nfunction hexSlice (buf, start, end) {\n  var len = buf.length\n\n  if (!start || start < 0) start = 0\n  if (!end || end < 0 || end > len) end = len\n\n  var out = ''\n  for (var i = start; i < end; ++i) {\n    out += toHex(buf[i])\n  }\n  return out\n}\n\nfunction utf16leSlice (buf, start, end) {\n  var bytes = buf.slice(start, end)\n  var res = ''\n  for (var i = 0; i < bytes.length; i += 2) {\n    res += String.fromCharCode(bytes[i] + bytes[i + 1] * 256)\n  }\n  return res\n}\n\nBuffer.prototype.slice = function slice (start, end) {\n  var len = this.length\n  start = ~~start\n  end = end === undefined ? len : ~~end\n\n  if (start < 0) {\n    start += len\n    if (start < 0) start = 0\n  } else if (start > len) {\n    start = len\n  }\n\n  if (end < 0) {\n    end += len\n    if (end < 0) end = 0\n  } else if (end > len) {\n    end = len\n  }\n\n  if (end < start) end = start\n\n  var newBuf\n  if (Buffer.TYPED_ARRAY_SUPPORT) {\n    newBuf = this.subarray(start, end)\n    newBuf.__proto__ = Buffer.prototype\n  } else {\n    var sliceLen = end - start\n    newBuf = new Buffer(sliceLen, undefined)\n    for (var i = 0; i < sliceLen; ++i) {\n      newBuf[i] = this[i + start]\n    }\n  }\n\n  return newBuf\n}\n\n/*\n * Need to make sure that buffer isn't trying to write out of bounds.\n */\nfunction checkOffset (offset, ext, length) {\n  if ((offset % 1) !== 0 || offset < 0) throw new RangeError('offset is not uint')\n  if (offset + ext > length) throw new RangeError('Trying to access beyond buffer length')\n}\n\nBuffer.prototype.readUIntLE = function readUIntLE (offset, byteLength, noAssert) {\n  offset = offset | 0\n  byteLength = byteLength | 0\n  if (!noAssert) checkOffset(offset, byteLength, this.length)\n\n  var val = this[offset]\n  var mul = 1\n  var i = 0\n  while (++i < byteLength && (mul *= 0x100)) {\n    val += this[offset + i] * mul\n  }\n\n  return val\n}\n\nBuffer.prototype.readUIntBE = function readUIntBE (offset, byteLength, noAssert) {\n  offset = offset | 0\n  byteLength = byteLength | 0\n  if (!noAssert) {\n    checkOffset(offset, byteLength, this.length)\n  }\n\n  var val = this[offset + --byteLength]\n  var mul = 1\n  while (byteLength > 0 && (mul *= 0x100)) {\n    val += this[offset + --byteLength] * mul\n  }\n\n  return val\n}\n\nBuffer.prototype.readUInt8 = function readUInt8 (offset, noAssert) {\n  if (!noAssert) checkOffset(offset, 1, this.length)\n  return this[offset]\n}\n\nBuffer.prototype.readUInt16LE = function readUInt16LE (offset, noAssert) {\n  if (!noAssert) checkOffset(offset, 2, this.length)\n  return this[offset] | (this[offset + 1] << 8)\n}\n\nBuffer.prototype.readUInt16BE = function readUInt16BE (offset, noAssert) {\n  if (!noAssert) checkOffset(offset, 2, this.length)\n  return (this[offset] << 8) | this[offset + 1]\n}\n\nBuffer.prototype.readUInt32LE = function readUInt32LE (offset, noAssert) {\n  if (!noAssert) checkOffset(offset, 4, this.length)\n\n  return ((this[offset]) |\n      (this[offset + 1] << 8) |\n      (this[offset + 2] << 16)) +\n      (this[offset + 3] * 0x1000000)\n}\n\nBuffer.prototype.readUInt32BE = function readUInt32BE (offset, noAssert) {\n  if (!noAssert) checkOffset(offset, 4, this.length)\n\n  return (this[offset] * 0x1000000) +\n    ((this[offset + 1] << 16) |\n    (this[offset + 2] << 8) |\n    this[offset + 3])\n}\n\nBuffer.prototype.readIntLE = function readIntLE (offset, byteLength, noAssert) {\n  offset = offset | 0\n  byteLength = byteLength | 0\n  if (!noAssert) checkOffset(offset, byteLength, this.length)\n\n  var val = this[offset]\n  var mul = 1\n  var i = 0\n  while (++i < byteLength && (mul *= 0x100)) {\n    val += this[offset + i] * mul\n  }\n  mul *= 0x80\n\n  if (val >= mul) val -= Math.pow(2, 8 * byteLength)\n\n  return val\n}\n\nBuffer.prototype.readIntBE = function readIntBE (offset, byteLength, noAssert) {\n  offset = offset | 0\n  byteLength = byteLength | 0\n  if (!noAssert) checkOffset(offset, byteLength, this.length)\n\n  var i = byteLength\n  var mul = 1\n  var val = this[offset + --i]\n  while (i > 0 && (mul *= 0x100)) {\n    val += this[offset + --i] * mul\n  }\n  mul *= 0x80\n\n  if (val >= mul) val -= Math.pow(2, 8 * byteLength)\n\n  return val\n}\n\nBuffer.prototype.readInt8 = function readInt8 (offset, noAssert) {\n  if (!noAssert) checkOffset(offset, 1, this.length)\n  if (!(this[offset] & 0x80)) return (this[offset])\n  return ((0xff - this[offset] + 1) * -1)\n}\n\nBuffer.prototype.readInt16LE = function readInt16LE (offset, noAssert) {\n  if (!noAssert) checkOffset(offset, 2, this.length)\n  var val = this[offset] | (this[offset + 1] << 8)\n  return (val & 0x8000) ? val | 0xFFFF0000 : val\n}\n\nBuffer.prototype.readInt16BE = function readInt16BE (offset, noAssert) {\n  if (!noAssert) checkOffset(offset, 2, this.length)\n  var val = this[offset + 1] | (this[offset] << 8)\n  return (val & 0x8000) ? val | 0xFFFF0000 : val\n}\n\nBuffer.prototype.readInt32LE = function readInt32LE (offset, noAssert) {\n  if (!noAssert) checkOffset(offset, 4, this.length)\n\n  return (this[offset]) |\n    (this[offset + 1] << 8) |\n    (this[offset + 2] << 16) |\n    (this[offset + 3] << 24)\n}\n\nBuffer.prototype.readInt32BE = function readInt32BE (offset, noAssert) {\n  if (!noAssert) checkOffset(offset, 4, this.length)\n\n  return (this[offset] << 24) |\n    (this[offset + 1] << 16) |\n    (this[offset + 2] << 8) |\n    (this[offset + 3])\n}\n\nBuffer.prototype.readFloatLE = function readFloatLE (offset, noAssert) {\n  if (!noAssert) checkOffset(offset, 4, this.length)\n  return ieee754.read(this, offset, true, 23, 4)\n}\n\nBuffer.prototype.readFloatBE = function readFloatBE (offset, noAssert) {\n  if (!noAssert) checkOffset(offset, 4, this.length)\n  return ieee754.read(this, offset, false, 23, 4)\n}\n\nBuffer.prototype.readDoubleLE = function readDoubleLE (offset, noAssert) {\n  if (!noAssert) checkOffset(offset, 8, this.length)\n  return ieee754.read(this, offset, true, 52, 8)\n}\n\nBuffer.prototype.readDoubleBE = function readDoubleBE (offset, noAssert) {\n  if (!noAssert) checkOffset(offset, 8, this.length)\n  return ieee754.read(this, offset, false, 52, 8)\n}\n\nfunction checkInt (buf, value, offset, ext, max, min) {\n  if (!Buffer.isBuffer(buf)) throw new TypeError('\"buffer\" argument must be a Buffer instance')\n  if (value > max || value < min) throw new RangeError('\"value\" argument is out of bounds')\n  if (offset + ext > buf.length) throw new RangeError('Index out of range')\n}\n\nBuffer.prototype.writeUIntLE = function writeUIntLE (value, offset, byteLength, noAssert) {\n  value = +value\n  offset = offset | 0\n  byteLength = byteLength | 0\n  if (!noAssert) {\n    var maxBytes = Math.pow(2, 8 * byteLength) - 1\n    checkInt(this, value, offset, byteLength, maxBytes, 0)\n  }\n\n  var mul = 1\n  var i = 0\n  this[offset] = value & 0xFF\n  while (++i < byteLength && (mul *= 0x100)) {\n    this[offset + i] = (value / mul) & 0xFF\n  }\n\n  return offset + byteLength\n}\n\nBuffer.prototype.writeUIntBE = function writeUIntBE (value, offset, byteLength, noAssert) {\n  value = +value\n  offset = offset | 0\n  byteLength = byteLength | 0\n  if (!noAssert) {\n    var maxBytes = Math.pow(2, 8 * byteLength) - 1\n    checkInt(this, value, offset, byteLength, maxBytes, 0)\n  }\n\n  var i = byteLength - 1\n  var mul = 1\n  this[offset + i] = value & 0xFF\n  while (--i >= 0 && (mul *= 0x100)) {\n    this[offset + i] = (value / mul) & 0xFF\n  }\n\n  return offset + byteLength\n}\n\nBuffer.prototype.writeUInt8 = function writeUInt8 (value, offset, noAssert) {\n  value = +value\n  offset = offset | 0\n  if (!noAssert) checkInt(this, value, offset, 1, 0xff, 0)\n  if (!Buffer.TYPED_ARRAY_SUPPORT) value = Math.floor(value)\n  this[offset] = (value & 0xff)\n  return offset + 1\n}\n\nfunction objectWriteUInt16 (buf, value, offset, littleEndian) {\n  if (value < 0) value = 0xffff + value + 1\n  for (var i = 0, j = Math.min(buf.length - offset, 2); i < j; ++i) {\n    buf[offset + i] = (value & (0xff << (8 * (littleEndian ? i : 1 - i)))) >>>\n      (littleEndian ? i : 1 - i) * 8\n  }\n}\n\nBuffer.prototype.writeUInt16LE = function writeUInt16LE (value, offset, noAssert) {\n  value = +value\n  offset = offset | 0\n  if (!noAssert) checkInt(this, value, offset, 2, 0xffff, 0)\n  if (Buffer.TYPED_ARRAY_SUPPORT) {\n    this[offset] = (value & 0xff)\n    this[offset + 1] = (value >>> 8)\n  } else {\n    objectWriteUInt16(this, value, offset, true)\n  }\n  return offset + 2\n}\n\nBuffer.prototype.writeUInt16BE = function writeUInt16BE (value, offset, noAssert) {\n  value = +value\n  offset = offset | 0\n  if (!noAssert) checkInt(this, value, offset, 2, 0xffff, 0)\n  if (Buffer.TYPED_ARRAY_SUPPORT) {\n    this[offset] = (value >>> 8)\n    this[offset + 1] = (value & 0xff)\n  } else {\n    objectWriteUInt16(this, value, offset, false)\n  }\n  return offset + 2\n}\n\nfunction objectWriteUInt32 (buf, value, offset, littleEndian) {\n  if (value < 0) value = 0xffffffff + value + 1\n  for (var i = 0, j = Math.min(buf.length - offset, 4); i < j; ++i) {\n    buf[offset + i] = (value >>> (littleEndian ? i : 3 - i) * 8) & 0xff\n  }\n}\n\nBuffer.prototype.writeUInt32LE = function writeUInt32LE (value, offset, noAssert) {\n  value = +value\n  offset = offset | 0\n  if (!noAssert) checkInt(this, value, offset, 4, 0xffffffff, 0)\n  if (Buffer.TYPED_ARRAY_SUPPORT) {\n    this[offset + 3] = (value >>> 24)\n    this[offset + 2] = (value >>> 16)\n    this[offset + 1] = (value >>> 8)\n    this[offset] = (value & 0xff)\n  } else {\n    objectWriteUInt32(this, value, offset, true)\n  }\n  return offset + 4\n}\n\nBuffer.prototype.writeUInt32BE = function writeUInt32BE (value, offset, noAssert) {\n  value = +value\n  offset = offset | 0\n  if (!noAssert) checkInt(this, value, offset, 4, 0xffffffff, 0)\n  if (Buffer.TYPED_ARRAY_SUPPORT) {\n    this[offset] = (value >>> 24)\n    this[offset + 1] = (value >>> 16)\n    this[offset + 2] = (value >>> 8)\n    this[offset + 3] = (value & 0xff)\n  } else {\n    objectWriteUInt32(this, value, offset, false)\n  }\n  return offset + 4\n}\n\nBuffer.prototype.writeIntLE = function writeIntLE (value, offset, byteLength, noAssert) {\n  value = +value\n  offset = offset | 0\n  if (!noAssert) {\n    var limit = Math.pow(2, 8 * byteLength - 1)\n\n    checkInt(this, value, offset, byteLength, limit - 1, -limit)\n  }\n\n  var i = 0\n  var mul = 1\n  var sub = 0\n  this[offset] = value & 0xFF\n  while (++i < byteLength && (mul *= 0x100)) {\n    if (value < 0 && sub === 0 && this[offset + i - 1] !== 0) {\n      sub = 1\n    }\n    this[offset + i] = ((value / mul) >> 0) - sub & 0xFF\n  }\n\n  return offset + byteLength\n}\n\nBuffer.prototype.writeIntBE = function writeIntBE (value, offset, byteLength, noAssert) {\n  value = +value\n  offset = offset | 0\n  if (!noAssert) {\n    var limit = Math.pow(2, 8 * byteLength - 1)\n\n    checkInt(this, value, offset, byteLength, limit - 1, -limit)\n  }\n\n  var i = byteLength - 1\n  var mul = 1\n  var sub = 0\n  this[offset + i] = value & 0xFF\n  while (--i >= 0 && (mul *= 0x100)) {\n    if (value < 0 && sub === 0 && this[offset + i + 1] !== 0) {\n      sub = 1\n    }\n    this[offset + i] = ((value / mul) >> 0) - sub & 0xFF\n  }\n\n  return offset + byteLength\n}\n\nBuffer.prototype.writeInt8 = function writeInt8 (value, offset, noAssert) {\n  value = +value\n  offset = offset | 0\n  if (!noAssert) checkInt(this, value, offset, 1, 0x7f, -0x80)\n  if (!Buffer.TYPED_ARRAY_SUPPORT) value = Math.floor(value)\n  if (value < 0) value = 0xff + value + 1\n  this[offset] = (value & 0xff)\n  return offset + 1\n}\n\nBuffer.prototype.writeInt16LE = function writeInt16LE (value, offset, noAssert) {\n  value = +value\n  offset = offset | 0\n  if (!noAssert) checkInt(this, value, offset, 2, 0x7fff, -0x8000)\n  if (Buffer.TYPED_ARRAY_SUPPORT) {\n    this[offset] = (value & 0xff)\n    this[offset + 1] = (value >>> 8)\n  } else {\n    objectWriteUInt16(this, value, offset, true)\n  }\n  return offset + 2\n}\n\nBuffer.prototype.writeInt16BE = function writeInt16BE (value, offset, noAssert) {\n  value = +value\n  offset = offset | 0\n  if (!noAssert) checkInt(this, value, offset, 2, 0x7fff, -0x8000)\n  if (Buffer.TYPED_ARRAY_SUPPORT) {\n    this[offset] = (value >>> 8)\n    this[offset + 1] = (value & 0xff)\n  } else {\n    objectWriteUInt16(this, value, offset, false)\n  }\n  return offset + 2\n}\n\nBuffer.prototype.writeInt32LE = function writeInt32LE (value, offset, noAssert) {\n  value = +value\n  offset = offset | 0\n  if (!noAssert) checkInt(this, value, offset, 4, 0x7fffffff, -0x80000000)\n  if (Buffer.TYPED_ARRAY_SUPPORT) {\n    this[offset] = (value & 0xff)\n    this[offset + 1] = (value >>> 8)\n    this[offset + 2] = (value >>> 16)\n    this[offset + 3] = (value >>> 24)\n  } else {\n    objectWriteUInt32(this, value, offset, true)\n  }\n  return offset + 4\n}\n\nBuffer.prototype.writeInt32BE = function writeInt32BE (value, offset, noAssert) {\n  value = +value\n  offset = offset | 0\n  if (!noAssert) checkInt(this, value, offset, 4, 0x7fffffff, -0x80000000)\n  if (value < 0) value = 0xffffffff + value + 1\n  if (Buffer.TYPED_ARRAY_SUPPORT) {\n    this[offset] = (value >>> 24)\n    this[offset + 1] = (value >>> 16)\n    this[offset + 2] = (value >>> 8)\n    this[offset + 3] = (value & 0xff)\n  } else {\n    objectWriteUInt32(this, value, offset, false)\n  }\n  return offset + 4\n}\n\nfunction checkIEEE754 (buf, value, offset, ext, max, min) {\n  if (offset + ext > buf.length) throw new RangeError('Index out of range')\n  if (offset < 0) throw new RangeError('Index out of range')\n}\n\nfunction writeFloat (buf, value, offset, littleEndian, noAssert) {\n  if (!noAssert) {\n    checkIEEE754(buf, value, offset, 4, 3.4028234663852886e+38, -3.4028234663852886e+38)\n  }\n  ieee754.write(buf, value, offset, littleEndian, 23, 4)\n  return offset + 4\n}\n\nBuffer.prototype.writeFloatLE = function writeFloatLE (value, offset, noAssert) {\n  return writeFloat(this, value, offset, true, noAssert)\n}\n\nBuffer.prototype.writeFloatBE = function writeFloatBE (value, offset, noAssert) {\n  return writeFloat(this, value, offset, false, noAssert)\n}\n\nfunction writeDouble (buf, value, offset, littleEndian, noAssert) {\n  if (!noAssert) {\n    checkIEEE754(buf, value, offset, 8, 1.7976931348623157E+308, -1.7976931348623157E+308)\n  }\n  ieee754.write(buf, value, offset, littleEndian, 52, 8)\n  return offset + 8\n}\n\nBuffer.prototype.writeDoubleLE = function writeDoubleLE (value, offset, noAssert) {\n  return writeDouble(this, value, offset, true, noAssert)\n}\n\nBuffer.prototype.writeDoubleBE = function writeDoubleBE (value, offset, noAssert) {\n  return writeDouble(this, value, offset, false, noAssert)\n}\n\n// copy(targetBuffer, targetStart=0, sourceStart=0, sourceEnd=buffer.length)\nBuffer.prototype.copy = function copy (target, targetStart, start, end) {\n  if (!start) start = 0\n  if (!end && end !== 0) end = this.length\n  if (targetStart >= target.length) targetStart = target.length\n  if (!targetStart) targetStart = 0\n  if (end > 0 && end < start) end = start\n\n  // Copy 0 bytes; we're done\n  if (end === start) return 0\n  if (target.length === 0 || this.length === 0) return 0\n\n  // Fatal error conditions\n  if (targetStart < 0) {\n    throw new RangeError('targetStart out of bounds')\n  }\n  if (start < 0 || start >= this.length) throw new RangeError('sourceStart out of bounds')\n  if (end < 0) throw new RangeError('sourceEnd out of bounds')\n\n  // Are we oob?\n  if (end > this.length) end = this.length\n  if (target.length - targetStart < end - start) {\n    end = target.length - targetStart + start\n  }\n\n  var len = end - start\n  var i\n\n  if (this === target && start < targetStart && targetStart < end) {\n    // descending copy from end\n    for (i = len - 1; i >= 0; --i) {\n      target[i + targetStart] = this[i + start]\n    }\n  } else if (len < 1000 || !Buffer.TYPED_ARRAY_SUPPORT) {\n    // ascending copy from start\n    for (i = 0; i < len; ++i) {\n      target[i + targetStart] = this[i + start]\n    }\n  } else {\n    Uint8Array.prototype.set.call(\n      target,\n      this.subarray(start, start + len),\n      targetStart\n    )\n  }\n\n  return len\n}\n\n// Usage:\n//    buffer.fill(number[, offset[, end]])\n//    buffer.fill(buffer[, offset[, end]])\n//    buffer.fill(string[, offset[, end]][, encoding])\nBuffer.prototype.fill = function fill (val, start, end, encoding) {\n  // Handle string cases:\n  if (typeof val === 'string') {\n    if (typeof start === 'string') {\n      encoding = start\n      start = 0\n      end = this.length\n    } else if (typeof end === 'string') {\n      encoding = end\n      end = this.length\n    }\n    if (val.length === 1) {\n      var code = val.charCodeAt(0)\n      if (code < 256) {\n        val = code\n      }\n    }\n    if (encoding !== undefined && typeof encoding !== 'string') {\n      throw new TypeError('encoding must be a string')\n    }\n    if (typeof encoding === 'string' && !Buffer.isEncoding(encoding)) {\n      throw new TypeError('Unknown encoding: ' + encoding)\n    }\n  } else if (typeof val === 'number') {\n    val = val & 255\n  }\n\n  // Invalid ranges are not set to a default, so can range check early.\n  if (start < 0 || this.length < start || this.length < end) {\n    throw new RangeError('Out of range index')\n  }\n\n  if (end <= start) {\n    return this\n  }\n\n  start = start >>> 0\n  end = end === undefined ? this.length : end >>> 0\n\n  if (!val) val = 0\n\n  var i\n  if (typeof val === 'number') {\n    for (i = start; i < end; ++i) {\n      this[i] = val\n    }\n  } else {\n    var bytes = Buffer.isBuffer(val)\n      ? val\n      : utf8ToBytes(new Buffer(val, encoding).toString())\n    var len = bytes.length\n    for (i = 0; i < end - start; ++i) {\n      this[i + start] = bytes[i % len]\n    }\n  }\n\n  return this\n}\n\n// HELPER FUNCTIONS\n// ================\n\nvar INVALID_BASE64_RE = /[^+\\/0-9A-Za-z-_]/g\n\nfunction base64clean (str) {\n  // Node strips out invalid characters like \\n and \\t from the string, base64-js does not\n  str = stringtrim(str).replace(INVALID_BASE64_RE, '')\n  // Node converts strings with length < 2 to ''\n  if (str.length < 2) return ''\n  // Node allows for non-padded base64 strings (missing trailing ===), base64-js does not\n  while (str.length % 4 !== 0) {\n    str = str + '='\n  }\n  return str\n}\n\nfunction stringtrim (str) {\n  if (str.trim) return str.trim()\n  return str.replace(/^\\s+|\\s+$/g, '')\n}\n\nfunction toHex (n) {\n  if (n < 16) return '0' + n.toString(16)\n  return n.toString(16)\n}\n\nfunction utf8ToBytes (string, units) {\n  units = units || Infinity\n  var codePoint\n  var length = string.length\n  var leadSurrogate = null\n  var bytes = []\n\n  for (var i = 0; i < length; ++i) {\n    codePoint = string.charCodeAt(i)\n\n    // is surrogate component\n    if (codePoint > 0xD7FF && codePoint < 0xE000) {\n      // last char was a lead\n      if (!leadSurrogate) {\n        // no lead yet\n        if (codePoint > 0xDBFF) {\n          // unexpected trail\n          if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD)\n          continue\n        } else if (i + 1 === length) {\n          // unpaired lead\n          if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD)\n          continue\n        }\n\n        // valid lead\n        leadSurrogate = codePoint\n\n        continue\n      }\n\n      // 2 leads in a row\n      if (codePoint < 0xDC00) {\n        if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD)\n        leadSurrogate = codePoint\n        continue\n      }\n\n      // valid surrogate pair\n      codePoint = (leadSurrogate - 0xD800 << 10 | codePoint - 0xDC00) + 0x10000\n    } else if (leadSurrogate) {\n      // valid bmp char, but last char was a lead\n      if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD)\n    }\n\n    leadSurrogate = null\n\n    // encode utf8\n    if (codePoint < 0x80) {\n      if ((units -= 1) < 0) break\n      bytes.push(codePoint)\n    } else if (codePoint < 0x800) {\n      if ((units -= 2) < 0) break\n      bytes.push(\n        codePoint >> 0x6 | 0xC0,\n        codePoint & 0x3F | 0x80\n      )\n    } else if (codePoint < 0x10000) {\n      if ((units -= 3) < 0) break\n      bytes.push(\n        codePoint >> 0xC | 0xE0,\n        codePoint >> 0x6 & 0x3F | 0x80,\n        codePoint & 0x3F | 0x80\n      )\n    } else if (codePoint < 0x110000) {\n      if ((units -= 4) < 0) break\n      bytes.push(\n        codePoint >> 0x12 | 0xF0,\n        codePoint >> 0xC & 0x3F | 0x80,\n        codePoint >> 0x6 & 0x3F | 0x80,\n        codePoint & 0x3F | 0x80\n      )\n    } else {\n      throw new Error('Invalid code point')\n    }\n  }\n\n  return bytes\n}\n\nfunction asciiToBytes (str) {\n  var byteArray = []\n  for (var i = 0; i < str.length; ++i) {\n    // Node's code seems to be doing this and not & 0x7F..\n    byteArray.push(str.charCodeAt(i) & 0xFF)\n  }\n  return byteArray\n}\n\nfunction utf16leToBytes (str, units) {\n  var c, hi, lo\n  var byteArray = []\n  for (var i = 0; i < str.length; ++i) {\n    if ((units -= 2) < 0) break\n\n    c = str.charCodeAt(i)\n    hi = c >> 8\n    lo = c % 256\n    byteArray.push(lo)\n    byteArray.push(hi)\n  }\n\n  return byteArray\n}\n\nfunction base64ToBytes (str) {\n  return base64.toByteArray(base64clean(str))\n}\n\nfunction blitBuffer (src, dst, offset, length) {\n  for (var i = 0; i < length; ++i) {\n    if ((i + offset >= dst.length) || (i >= src.length)) break\n    dst[i + offset] = src[i]\n  }\n  return i\n}\n\nfunction isnan (val) {\n  return val !== val // eslint-disable-line no-self-compare\n}\n\n}).call(this,typeof global !== \"undefined\" ? global : typeof self !== \"undefined\" ? self : typeof window !== \"undefined\" ? window : {})\n},{\"base64-js\":39,\"ieee754\":50,\"isarray\":53}],45:[function(require,module,exports){\n(function (Buffer){\n// Copyright Joyent, Inc. and other Node contributors.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a\n// copy of this software and associated documentation files (the\n// \"Software\"), to deal in the Software without restriction, including\n// without limitation the rights to use, copy, modify, merge, publish,\n// distribute, sublicense, and/or sell copies of the Software, and to permit\n// persons to whom the Software is furnished to do so, subject to the\n// following conditions:\n//\n// The above copyright notice and this permission notice shall be included\n// in all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS\n// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN\n// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,\n// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE\n// USE OR OTHER DEALINGS IN THE SOFTWARE.\n\n// NOTE: These type checking functions intentionally don't use `instanceof`\n// because it is fragile and can be easily faked with `Object.create()`.\n\nfunction isArray(arg) {\n  if (Array.isArray) {\n    return Array.isArray(arg);\n  }\n  return objectToString(arg) === '[object Array]';\n}\nexports.isArray = isArray;\n\nfunction isBoolean(arg) {\n  return typeof arg === 'boolean';\n}\nexports.isBoolean = isBoolean;\n\nfunction isNull(arg) {\n  return arg === null;\n}\nexports.isNull = isNull;\n\nfunction isNullOrUndefined(arg) {\n  return arg == null;\n}\nexports.isNullOrUndefined = isNullOrUndefined;\n\nfunction isNumber(arg) {\n  return typeof arg === 'number';\n}\nexports.isNumber = isNumber;\n\nfunction isString(arg) {\n  return typeof arg === 'string';\n}\nexports.isString = isString;\n\nfunction isSymbol(arg) {\n  return typeof arg === 'symbol';\n}\nexports.isSymbol = isSymbol;\n\nfunction isUndefined(arg) {\n  return arg === void 0;\n}\nexports.isUndefined = isUndefined;\n\nfunction isRegExp(re) {\n  return objectToString(re) === '[object RegExp]';\n}\nexports.isRegExp = isRegExp;\n\nfunction isObject(arg) {\n  return typeof arg === 'object' && arg !== null;\n}\nexports.isObject = isObject;\n\nfunction isDate(d) {\n  return objectToString(d) === '[object Date]';\n}\nexports.isDate = isDate;\n\nfunction isError(e) {\n  return (objectToString(e) === '[object Error]' || e instanceof Error);\n}\nexports.isError = isError;\n\nfunction isFunction(arg) {\n  return typeof arg === 'function';\n}\nexports.isFunction = isFunction;\n\nfunction isPrimitive(arg) {\n  return arg === null ||\n         typeof arg === 'boolean' ||\n         typeof arg === 'number' ||\n         typeof arg === 'string' ||\n         typeof arg === 'symbol' ||  // ES6 symbol\n         typeof arg === 'undefined';\n}\nexports.isPrimitive = isPrimitive;\n\nexports.isBuffer = Buffer.isBuffer;\n\nfunction objectToString(o) {\n  return Object.prototype.toString.call(o);\n}\n\n}).call(this,{\"isBuffer\":require(\"../../is-buffer/index.js\")})\n},{\"../../is-buffer/index.js\":52}],46:[function(require,module,exports){\n/* See LICENSE file for terms of use */\n\n/*\n * Text diff implementation.\n *\n * This library supports the following APIS:\n * JsDiff.diffChars: Character by character diff\n * JsDiff.diffWords: Word (as defined by \\b regex) diff which ignores whitespace\n * JsDiff.diffLines: Line based diff\n *\n * JsDiff.diffCss: Diff targeted at CSS content\n *\n * These methods are based on the implementation proposed in\n * \"An O(ND) Difference Algorithm and its Variations\" (Myers, 1986).\n * http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.4.6927\n */\n(function(global, undefined) {\n  var objectPrototypeToString = Object.prototype.toString;\n\n  /*istanbul ignore next*/\n  function map(arr, mapper, that) {\n    if (Array.prototype.map) {\n      return Array.prototype.map.call(arr, mapper, that);\n    }\n\n    var other = new Array(arr.length);\n\n    for (var i = 0, n = arr.length; i < n; i++) {\n      other[i] = mapper.call(that, arr[i], i, arr);\n    }\n    return other;\n  }\n  function clonePath(path) {\n    return { newPos: path.newPos, components: path.components.slice(0) };\n  }\n  function removeEmpty(array) {\n    var ret = [];\n    for (var i = 0; i < array.length; i++) {\n      if (array[i]) {\n        ret.push(array[i]);\n      }\n    }\n    return ret;\n  }\n  function escapeHTML(s) {\n    var n = s;\n    n = n.replace(/&/g, '&amp;');\n    n = n.replace(/</g, '&lt;');\n    n = n.replace(/>/g, '&gt;');\n    n = n.replace(/\"/g, '&quot;');\n\n    return n;\n  }\n\n  // This function handles the presence of circular references by bailing out when encountering an\n  // object that is already on the \"stack\" of items being processed.\n  function canonicalize(obj, stack, replacementStack) {\n    stack = stack || [];\n    replacementStack = replacementStack || [];\n\n    var i;\n\n    for (i = 0; i < stack.length; i += 1) {\n      if (stack[i] === obj) {\n        return replacementStack[i];\n      }\n    }\n\n    var canonicalizedObj;\n\n    if ('[object Array]' === objectPrototypeToString.call(obj)) {\n      stack.push(obj);\n      canonicalizedObj = new Array(obj.length);\n      replacementStack.push(canonicalizedObj);\n      for (i = 0; i < obj.length; i += 1) {\n        canonicalizedObj[i] = canonicalize(obj[i], stack, replacementStack);\n      }\n      stack.pop();\n      replacementStack.pop();\n    } else if (typeof obj === 'object' && obj !== null) {\n      stack.push(obj);\n      canonicalizedObj = {};\n      replacementStack.push(canonicalizedObj);\n      var sortedKeys = [],\n          key;\n      for (key in obj) {\n        sortedKeys.push(key);\n      }\n      sortedKeys.sort();\n      for (i = 0; i < sortedKeys.length; i += 1) {\n        key = sortedKeys[i];\n        canonicalizedObj[key] = canonicalize(obj[key], stack, replacementStack);\n      }\n      stack.pop();\n      replacementStack.pop();\n    } else {\n      canonicalizedObj = obj;\n    }\n    return canonicalizedObj;\n  }\n\n  function buildValues(components, newString, oldString, useLongestToken) {\n    var componentPos = 0,\n        componentLen = components.length,\n        newPos = 0,\n        oldPos = 0;\n\n    for (; componentPos < componentLen; componentPos++) {\n      var component = components[componentPos];\n      if (!component.removed) {\n        if (!component.added && useLongestToken) {\n          var value = newString.slice(newPos, newPos + component.count);\n          value = map(value, function(value, i) {\n            var oldValue = oldString[oldPos + i];\n            return oldValue.length > value.length ? oldValue : value;\n          });\n\n          component.value = value.join('');\n        } else {\n          component.value = newString.slice(newPos, newPos + component.count).join('');\n        }\n        newPos += component.count;\n\n        // Common case\n        if (!component.added) {\n          oldPos += component.count;\n        }\n      } else {\n        component.value = oldString.slice(oldPos, oldPos + component.count).join('');\n        oldPos += component.count;\n\n        // Reverse add and remove so removes are output first to match common convention\n        // The diffing algorithm is tied to add then remove output and this is the simplest\n        // route to get the desired output with minimal overhead.\n        if (componentPos && components[componentPos - 1].added) {\n          var tmp = components[componentPos - 1];\n          components[componentPos - 1] = components[componentPos];\n          components[componentPos] = tmp;\n        }\n      }\n    }\n\n    return components;\n  }\n\n  function Diff(ignoreWhitespace) {\n    this.ignoreWhitespace = ignoreWhitespace;\n  }\n  Diff.prototype = {\n    diff: function(oldString, newString, callback) {\n      var self = this;\n\n      function done(value) {\n        if (callback) {\n          setTimeout(function() { callback(undefined, value); }, 0);\n          return true;\n        } else {\n          return value;\n        }\n      }\n\n      // Handle the identity case (this is due to unrolling editLength == 0\n      if (newString === oldString) {\n        return done([{ value: newString }]);\n      }\n      if (!newString) {\n        return done([{ value: oldString, removed: true }]);\n      }\n      if (!oldString) {\n        return done([{ value: newString, added: true }]);\n      }\n\n      newString = this.tokenize(newString);\n      oldString = this.tokenize(oldString);\n\n      var newLen = newString.length, oldLen = oldString.length;\n      var editLength = 1;\n      var maxEditLength = newLen + oldLen;\n      var bestPath = [{ newPos: -1, components: [] }];\n\n      // Seed editLength = 0, i.e. the content starts with the same values\n      var oldPos = this.extractCommon(bestPath[0], newString, oldString, 0);\n      if (bestPath[0].newPos + 1 >= newLen && oldPos + 1 >= oldLen) {\n        // Identity per the equality and tokenizer\n        return done([{value: newString.join('')}]);\n      }\n\n      // Main worker method. checks all permutations of a given edit length for acceptance.\n      function execEditLength() {\n        for (var diagonalPath = -1 * editLength; diagonalPath <= editLength; diagonalPath += 2) {\n          var basePath;\n          var addPath = bestPath[diagonalPath - 1],\n              removePath = bestPath[diagonalPath + 1],\n              oldPos = (removePath ? removePath.newPos : 0) - diagonalPath;\n          if (addPath) {\n            // No one else is going to attempt to use this value, clear it\n            bestPath[diagonalPath - 1] = undefined;\n          }\n\n          var canAdd = addPath && addPath.newPos + 1 < newLen,\n              canRemove = removePath && 0 <= oldPos && oldPos < oldLen;\n          if (!canAdd && !canRemove) {\n            // If this path is a terminal then prune\n            bestPath[diagonalPath] = undefined;\n            continue;\n          }\n\n          // Select the diagonal that we want to branch from. We select the prior\n          // path whose position in the new string is the farthest from the origin\n          // and does not pass the bounds of the diff graph\n          if (!canAdd || (canRemove && addPath.newPos < removePath.newPos)) {\n            basePath = clonePath(removePath);\n            self.pushComponent(basePath.components, undefined, true);\n          } else {\n            basePath = addPath;   // No need to clone, we've pulled it from the list\n            basePath.newPos++;\n            self.pushComponent(basePath.components, true, undefined);\n          }\n\n          oldPos = self.extractCommon(basePath, newString, oldString, diagonalPath);\n\n          // If we have hit the end of both strings, then we are done\n          if (basePath.newPos + 1 >= newLen && oldPos + 1 >= oldLen) {\n            return done(buildValues(basePath.components, newString, oldString, self.useLongestToken));\n          } else {\n            // Otherwise track this path as a potential candidate and continue.\n            bestPath[diagonalPath] = basePath;\n          }\n        }\n\n        editLength++;\n      }\n\n      // Performs the length of edit iteration. Is a bit fugly as this has to support the\n      // sync and async mode which is never fun. Loops over execEditLength until a value\n      // is produced.\n      if (callback) {\n        (function exec() {\n          setTimeout(function() {\n            // This should not happen, but we want to be safe.\n            /*istanbul ignore next */\n            if (editLength > maxEditLength) {\n              return callback();\n            }\n\n            if (!execEditLength()) {\n              exec();\n            }\n          }, 0);\n        }());\n      } else {\n        while (editLength <= maxEditLength) {\n          var ret = execEditLength();\n          if (ret) {\n            return ret;\n          }\n        }\n      }\n    },\n\n    pushComponent: function(components, added, removed) {\n      var last = components[components.length - 1];\n      if (last && last.added === added && last.removed === removed) {\n        // We need to clone here as the component clone operation is just\n        // as shallow array clone\n        components[components.length - 1] = {count: last.count + 1, added: added, removed: removed };\n      } else {\n        components.push({count: 1, added: added, removed: removed });\n      }\n    },\n    extractCommon: function(basePath, newString, oldString, diagonalPath) {\n      var newLen = newString.length,\n          oldLen = oldString.length,\n          newPos = basePath.newPos,\n          oldPos = newPos - diagonalPath,\n\n          commonCount = 0;\n      while (newPos + 1 < newLen && oldPos + 1 < oldLen && this.equals(newString[newPos + 1], oldString[oldPos + 1])) {\n        newPos++;\n        oldPos++;\n        commonCount++;\n      }\n\n      if (commonCount) {\n        basePath.components.push({count: commonCount});\n      }\n\n      basePath.newPos = newPos;\n      return oldPos;\n    },\n\n    equals: function(left, right) {\n      var reWhitespace = /\\S/;\n      return left === right || (this.ignoreWhitespace && !reWhitespace.test(left) && !reWhitespace.test(right));\n    },\n    tokenize: function(value) {\n      return value.split('');\n    }\n  };\n\n  var CharDiff = new Diff();\n\n  var WordDiff = new Diff(true);\n  var WordWithSpaceDiff = new Diff();\n  WordDiff.tokenize = WordWithSpaceDiff.tokenize = function(value) {\n    return removeEmpty(value.split(/(\\s+|\\b)/));\n  };\n\n  var CssDiff = new Diff(true);\n  CssDiff.tokenize = function(value) {\n    return removeEmpty(value.split(/([{}:;,]|\\s+)/));\n  };\n\n  var LineDiff = new Diff();\n\n  var TrimmedLineDiff = new Diff();\n  TrimmedLineDiff.ignoreTrim = true;\n\n  LineDiff.tokenize = TrimmedLineDiff.tokenize = function(value) {\n    var retLines = [],\n        lines = value.split(/^/m);\n    for (var i = 0; i < lines.length; i++) {\n      var line = lines[i],\n          lastLine = lines[i - 1],\n          lastLineLastChar = lastLine && lastLine[lastLine.length - 1];\n\n      // Merge lines that may contain windows new lines\n      if (line === '\\n' && lastLineLastChar === '\\r') {\n          retLines[retLines.length - 1] = retLines[retLines.length - 1].slice(0, -1) + '\\r\\n';\n      } else {\n        if (this.ignoreTrim) {\n          line = line.trim();\n          // add a newline unless this is the last line.\n          if (i < lines.length - 1) {\n            line += '\\n';\n          }\n        }\n        retLines.push(line);\n      }\n    }\n\n    return retLines;\n  };\n\n  var PatchDiff = new Diff();\n  PatchDiff.tokenize = function(value) {\n    var ret = [],\n        linesAndNewlines = value.split(/(\\n|\\r\\n)/);\n\n    // Ignore the final empty token that occurs if the string ends with a new line\n    if (!linesAndNewlines[linesAndNewlines.length - 1]) {\n      linesAndNewlines.pop();\n    }\n\n    // Merge the content and line separators into single tokens\n    for (var i = 0; i < linesAndNewlines.length; i++) {\n      var line = linesAndNewlines[i];\n\n      if (i % 2) {\n        ret[ret.length - 1] += line;\n      } else {\n        ret.push(line);\n      }\n    }\n    return ret;\n  };\n\n  var SentenceDiff = new Diff();\n  SentenceDiff.tokenize = function(value) {\n    return removeEmpty(value.split(/(\\S.+?[.!?])(?=\\s+|$)/));\n  };\n\n  var JsonDiff = new Diff();\n  // Discriminate between two lines of pretty-printed, serialized JSON where one of them has a\n  // dangling comma and the other doesn't. Turns out including the dangling comma yields the nicest output:\n  JsonDiff.useLongestToken = true;\n  JsonDiff.tokenize = LineDiff.tokenize;\n  JsonDiff.equals = function(left, right) {\n    return LineDiff.equals(left.replace(/,([\\r\\n])/g, '$1'), right.replace(/,([\\r\\n])/g, '$1'));\n  };\n\n  var JsDiff = {\n    Diff: Diff,\n\n    diffChars: function(oldStr, newStr, callback) { return CharDiff.diff(oldStr, newStr, callback); },\n    diffWords: function(oldStr, newStr, callback) { return WordDiff.diff(oldStr, newStr, callback); },\n    diffWordsWithSpace: function(oldStr, newStr, callback) { return WordWithSpaceDiff.diff(oldStr, newStr, callback); },\n    diffLines: function(oldStr, newStr, callback) { return LineDiff.diff(oldStr, newStr, callback); },\n    diffTrimmedLines: function(oldStr, newStr, callback) { return TrimmedLineDiff.diff(oldStr, newStr, callback); },\n\n    diffSentences: function(oldStr, newStr, callback) { return SentenceDiff.diff(oldStr, newStr, callback); },\n\n    diffCss: function(oldStr, newStr, callback) { return CssDiff.diff(oldStr, newStr, callback); },\n    diffJson: function(oldObj, newObj, callback) {\n      return JsonDiff.diff(\n        typeof oldObj === 'string' ? oldObj : JSON.stringify(canonicalize(oldObj), undefined, '  '),\n        typeof newObj === 'string' ? newObj : JSON.stringify(canonicalize(newObj), undefined, '  '),\n        callback\n      );\n    },\n\n    createTwoFilesPatch: function(oldFileName, newFileName, oldStr, newStr, oldHeader, newHeader) {\n      var ret = [];\n\n      if (oldFileName == newFileName) {\n        ret.push('Index: ' + oldFileName);\n      }\n      ret.push('===================================================================');\n      ret.push('--- ' + oldFileName + (typeof oldHeader === 'undefined' ? '' : '\\t' + oldHeader));\n      ret.push('+++ ' + newFileName + (typeof newHeader === 'undefined' ? '' : '\\t' + newHeader));\n\n      var diff = PatchDiff.diff(oldStr, newStr);\n      diff.push({value: '', lines: []});   // Append an empty value to make cleanup easier\n\n      // Formats a given set of lines for printing as context lines in a patch\n      function contextLines(lines) {\n        return map(lines, function(entry) { return ' ' + entry; });\n      }\n\n      // Outputs the no newline at end of file warning if needed\n      function eofNL(curRange, i, current) {\n        var last = diff[diff.length - 2],\n            isLast = i === diff.length - 2,\n            isLastOfType = i === diff.length - 3 && current.added !== last.added;\n\n        // Figure out if this is the last line for the given file and missing NL\n        if (!(/\\n$/.test(current.value)) && (isLast || isLastOfType)) {\n          curRange.push('\\\\ No newline at end of file');\n        }\n      }\n\n      var oldRangeStart = 0, newRangeStart = 0, curRange = [],\n          oldLine = 1, newLine = 1;\n      for (var i = 0; i < diff.length; i++) {\n        var current = diff[i],\n            lines = current.lines || current.value.replace(/\\n$/, '').split('\\n');\n        current.lines = lines;\n\n        if (current.added || current.removed) {\n          // If we have previous context, start with that\n          if (!oldRangeStart) {\n            var prev = diff[i - 1];\n            oldRangeStart = oldLine;\n            newRangeStart = newLine;\n\n            if (prev) {\n              curRange = contextLines(prev.lines.slice(-4));\n              oldRangeStart -= curRange.length;\n              newRangeStart -= curRange.length;\n            }\n          }\n\n          // Output our changes\n          curRange.push.apply(curRange, map(lines, function(entry) {\n            return (current.added ? '+' : '-') + entry;\n          }));\n          eofNL(curRange, i, current);\n\n          // Track the updated file position\n          if (current.added) {\n            newLine += lines.length;\n          } else {\n            oldLine += lines.length;\n          }\n        } else {\n          // Identical context lines. Track line changes\n          if (oldRangeStart) {\n            // Close out any changes that have been output (or join overlapping)\n            if (lines.length <= 8 && i < diff.length - 2) {\n              // Overlapping\n              curRange.push.apply(curRange, contextLines(lines));\n            } else {\n              // end the range and output\n              var contextSize = Math.min(lines.length, 4);\n              ret.push(\n                  '@@ -' + oldRangeStart + ',' + (oldLine - oldRangeStart + contextSize)\n                  + ' +' + newRangeStart + ',' + (newLine - newRangeStart + contextSize)\n                  + ' @@');\n              ret.push.apply(ret, curRange);\n              ret.push.apply(ret, contextLines(lines.slice(0, contextSize)));\n              if (lines.length <= 4) {\n                eofNL(ret, i, current);\n              }\n\n              oldRangeStart = 0;\n              newRangeStart = 0;\n              curRange = [];\n            }\n          }\n          oldLine += lines.length;\n          newLine += lines.length;\n        }\n      }\n\n      return ret.join('\\n') + '\\n';\n    },\n\n    createPatch: function(fileName, oldStr, newStr, oldHeader, newHeader) {\n      return JsDiff.createTwoFilesPatch(fileName, fileName, oldStr, newStr, oldHeader, newHeader);\n    },\n\n    applyPatch: function(oldStr, uniDiff) {\n      var diffstr = uniDiff.split('\\n'),\n          hunks = [],\n          i = 0,\n          remEOFNL = false,\n          addEOFNL = false;\n\n      // Skip to the first change hunk\n      while (i < diffstr.length && !(/^@@/.test(diffstr[i]))) {\n        i++;\n      }\n\n      // Parse the unified diff\n      for (; i < diffstr.length; i++) {\n        if (diffstr[i][0] === '@') {\n          var chnukHeader = diffstr[i].split(/@@ -(\\d+),(\\d+) \\+(\\d+),(\\d+) @@/);\n          hunks.unshift({\n            start: chnukHeader[3],\n            oldlength: +chnukHeader[2],\n            removed: [],\n            newlength: chnukHeader[4],\n            added: []\n          });\n        } else if (diffstr[i][0] === '+') {\n          hunks[0].added.push(diffstr[i].substr(1));\n        } else if (diffstr[i][0] === '-') {\n          hunks[0].removed.push(diffstr[i].substr(1));\n        } else if (diffstr[i][0] === ' ') {\n          hunks[0].added.push(diffstr[i].substr(1));\n          hunks[0].removed.push(diffstr[i].substr(1));\n        } else if (diffstr[i][0] === '\\\\') {\n          if (diffstr[i - 1][0] === '+') {\n            remEOFNL = true;\n          } else if (diffstr[i - 1][0] === '-') {\n            addEOFNL = true;\n          }\n        }\n      }\n\n      // Apply the diff to the input\n      var lines = oldStr.split('\\n');\n      for (i = hunks.length - 1; i >= 0; i--) {\n        var hunk = hunks[i];\n        // Sanity check the input string. Bail if we don't match.\n        for (var j = 0; j < hunk.oldlength; j++) {\n          if (lines[hunk.start - 1 + j] !== hunk.removed[j]) {\n            return false;\n          }\n        }\n        Array.prototype.splice.apply(lines, [hunk.start - 1, hunk.oldlength].concat(hunk.added));\n      }\n\n      // Handle EOFNL insertion/removal\n      if (remEOFNL) {\n        while (!lines[lines.length - 1]) {\n          lines.pop();\n        }\n      } else if (addEOFNL) {\n        lines.push('');\n      }\n      return lines.join('\\n');\n    },\n\n    convertChangesToXML: function(changes) {\n      var ret = [];\n      for (var i = 0; i < changes.length; i++) {\n        var change = changes[i];\n        if (change.added) {\n          ret.push('<ins>');\n        } else if (change.removed) {\n          ret.push('<del>');\n        }\n\n        ret.push(escapeHTML(change.value));\n\n        if (change.added) {\n          ret.push('</ins>');\n        } else if (change.removed) {\n          ret.push('</del>');\n        }\n      }\n      return ret.join('');\n    },\n\n    // See: http://code.google.com/p/google-diff-match-patch/wiki/API\n    convertChangesToDMP: function(changes) {\n      var ret = [],\n          change,\n          operation;\n      for (var i = 0; i < changes.length; i++) {\n        change = changes[i];\n        if (change.added) {\n          operation = 1;\n        } else if (change.removed) {\n          operation = -1;\n        } else {\n          operation = 0;\n        }\n\n        ret.push([operation, change.value]);\n      }\n      return ret;\n    },\n\n    canonicalize: canonicalize\n  };\n\n  /*istanbul ignore next */\n  /*global module */\n  if (typeof module !== 'undefined' && module.exports) {\n    module.exports = JsDiff;\n  } else if (false) {\n    /*global define */\n    define([], function() { return JsDiff; });\n  } else if (typeof global.JsDiff === 'undefined') {\n    global.JsDiff = JsDiff;\n  }\n}(this));\n\n},{}],47:[function(require,module,exports){\n'use strict';\n\nvar matchOperatorsRe = /[|\\\\{}()[\\]^$+*?.]/g;\n\nmodule.exports = function (str) {\n\tif (typeof str !== 'string') {\n\t\tthrow new TypeError('Expected a string');\n\t}\n\n\treturn str.replace(matchOperatorsRe, '\\\\$&');\n};\n\n},{}],48:[function(require,module,exports){\n// Copyright Joyent, Inc. and other Node contributors.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a\n// copy of this software and associated documentation files (the\n// \"Software\"), to deal in the Software without restriction, including\n// without limitation the rights to use, copy, modify, merge, publish,\n// distribute, sublicense, and/or sell copies of the Software, and to permit\n// persons to whom the Software is furnished to do so, subject to the\n// following conditions:\n//\n// The above copyright notice and this permission notice shall be included\n// in all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS\n// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN\n// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,\n// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE\n// USE OR OTHER DEALINGS IN THE SOFTWARE.\n\nfunction EventEmitter() {\n  this._events = this._events || {};\n  this._maxListeners = this._maxListeners || undefined;\n}\nmodule.exports = EventEmitter;\n\n// Backwards-compat with node 0.10.x\nEventEmitter.EventEmitter = EventEmitter;\n\nEventEmitter.prototype._events = undefined;\nEventEmitter.prototype._maxListeners = undefined;\n\n// By default EventEmitters will print a warning if more than 10 listeners are\n// added to it. This is a useful default which helps finding memory leaks.\nEventEmitter.defaultMaxListeners = 10;\n\n// Obviously not all Emitters should be limited to 10. This function allows\n// that to be increased. Set to zero for unlimited.\nEventEmitter.prototype.setMaxListeners = function(n) {\n  if (!isNumber(n) || n < 0 || isNaN(n))\n    throw TypeError('n must be a positive number');\n  this._maxListeners = n;\n  return this;\n};\n\nEventEmitter.prototype.emit = function(type) {\n  var er, handler, len, args, i, listeners;\n\n  if (!this._events)\n    this._events = {};\n\n  // If there is no 'error' event listener then throw.\n  if (type === 'error') {\n    if (!this._events.error ||\n        (isObject(this._events.error) && !this._events.error.length)) {\n      er = arguments[1];\n      if (er instanceof Error) {\n        throw er; // Unhandled 'error' event\n      } else {\n        // At least give some kind of context to the user\n        var err = new Error('Uncaught, unspecified \"error\" event. (' + er + ')');\n        err.context = er;\n        throw err;\n      }\n    }\n  }\n\n  handler = this._events[type];\n\n  if (isUndefined(handler))\n    return false;\n\n  if (isFunction(handler)) {\n    switch (arguments.length) {\n      // fast cases\n      case 1:\n        handler.call(this);\n        break;\n      case 2:\n        handler.call(this, arguments[1]);\n        break;\n      case 3:\n        handler.call(this, arguments[1], arguments[2]);\n        break;\n      // slower\n      default:\n        args = Array.prototype.slice.call(arguments, 1);\n        handler.apply(this, args);\n    }\n  } else if (isObject(handler)) {\n    args = Array.prototype.slice.call(arguments, 1);\n    listeners = handler.slice();\n    len = listeners.length;\n    for (i = 0; i < len; i++)\n      listeners[i].apply(this, args);\n  }\n\n  return true;\n};\n\nEventEmitter.prototype.addListener = function(type, listener) {\n  var m;\n\n  if (!isFunction(listener))\n    throw TypeError('listener must be a function');\n\n  if (!this._events)\n    this._events = {};\n\n  // To avoid recursion in the case that type === \"newListener\"! Before\n  // adding it to the listeners, first emit \"newListener\".\n  if (this._events.newListener)\n    this.emit('newListener', type,\n              isFunction(listener.listener) ?\n              listener.listener : listener);\n\n  if (!this._events[type])\n    // Optimize the case of one listener. Don't need the extra array object.\n    this._events[type] = listener;\n  else if (isObject(this._events[type]))\n    // If we've already got an array, just append.\n    this._events[type].push(listener);\n  else\n    // Adding the second element, need to change to array.\n    this._events[type] = [this._events[type], listener];\n\n  // Check for listener leak\n  if (isObject(this._events[type]) && !this._events[type].warned) {\n    if (!isUndefined(this._maxListeners)) {\n      m = this._maxListeners;\n    } else {\n      m = EventEmitter.defaultMaxListeners;\n    }\n\n    if (m && m > 0 && this._events[type].length > m) {\n      this._events[type].warned = true;\n      console.error('(node) warning: possible EventEmitter memory ' +\n                    'leak detected. %d listeners added. ' +\n                    'Use emitter.setMaxListeners() to increase limit.',\n                    this._events[type].length);\n      if (typeof console.trace === 'function') {\n        // not supported in IE 10\n        console.trace();\n      }\n    }\n  }\n\n  return this;\n};\n\nEventEmitter.prototype.on = EventEmitter.prototype.addListener;\n\nEventEmitter.prototype.once = function(type, listener) {\n  if (!isFunction(listener))\n    throw TypeError('listener must be a function');\n\n  var fired = false;\n\n  function g() {\n    this.removeListener(type, g);\n\n    if (!fired) {\n      fired = true;\n      listener.apply(this, arguments);\n    }\n  }\n\n  g.listener = listener;\n  this.on(type, g);\n\n  return this;\n};\n\n// emits a 'removeListener' event iff the listener was removed\nEventEmitter.prototype.removeListener = function(type, listener) {\n  var list, position, length, i;\n\n  if (!isFunction(listener))\n    throw TypeError('listener must be a function');\n\n  if (!this._events || !this._events[type])\n    return this;\n\n  list = this._events[type];\n  length = list.length;\n  position = -1;\n\n  if (list === listener ||\n      (isFunction(list.listener) && list.listener === listener)) {\n    delete this._events[type];\n    if (this._events.removeListener)\n      this.emit('removeListener', type, listener);\n\n  } else if (isObject(list)) {\n    for (i = length; i-- > 0;) {\n      if (list[i] === listener ||\n          (list[i].listener && list[i].listener === listener)) {\n        position = i;\n        break;\n      }\n    }\n\n    if (position < 0)\n      return this;\n\n    if (list.length === 1) {\n      list.length = 0;\n      delete this._events[type];\n    } else {\n      list.splice(position, 1);\n    }\n\n    if (this._events.removeListener)\n      this.emit('removeListener', type, listener);\n  }\n\n  return this;\n};\n\nEventEmitter.prototype.removeAllListeners = function(type) {\n  var key, listeners;\n\n  if (!this._events)\n    return this;\n\n  // not listening for removeListener, no need to emit\n  if (!this._events.removeListener) {\n    if (arguments.length === 0)\n      this._events = {};\n    else if (this._events[type])\n      delete this._events[type];\n    return this;\n  }\n\n  // emit removeListener for all listeners on all events\n  if (arguments.length === 0) {\n    for (key in this._events) {\n      if (key === 'removeListener') continue;\n      this.removeAllListeners(key);\n    }\n    this.removeAllListeners('removeListener');\n    this._events = {};\n    return this;\n  }\n\n  listeners = this._events[type];\n\n  if (isFunction(listeners)) {\n    this.removeListener(type, listeners);\n  } else if (listeners) {\n    // LIFO order\n    while (listeners.length)\n      this.removeListener(type, listeners[listeners.length - 1]);\n  }\n  delete this._events[type];\n\n  return this;\n};\n\nEventEmitter.prototype.listeners = function(type) {\n  var ret;\n  if (!this._events || !this._events[type])\n    ret = [];\n  else if (isFunction(this._events[type]))\n    ret = [this._events[type]];\n  else\n    ret = this._events[type].slice();\n  return ret;\n};\n\nEventEmitter.prototype.listenerCount = function(type) {\n  if (this._events) {\n    var evlistener = this._events[type];\n\n    if (isFunction(evlistener))\n      return 1;\n    else if (evlistener)\n      return evlistener.length;\n  }\n  return 0;\n};\n\nEventEmitter.listenerCount = function(emitter, type) {\n  return emitter.listenerCount(type);\n};\n\nfunction isFunction(arg) {\n  return typeof arg === 'function';\n}\n\nfunction isNumber(arg) {\n  return typeof arg === 'number';\n}\n\nfunction isObject(arg) {\n  return typeof arg === 'object' && arg !== null;\n}\n\nfunction isUndefined(arg) {\n  return arg === void 0;\n}\n\n},{}],49:[function(require,module,exports){\n(function (process){\n// Growl - Copyright TJ Holowaychuk <tj@vision-media.ca> (MIT Licensed)\n\n/**\n * Module dependencies.\n */\n\nvar exec = require('child_process').exec\n  , fs = require('fs')\n  , path = require('path')\n  , exists = fs.existsSync || path.existsSync\n  , os = require('os')\n  , quote = JSON.stringify\n  , cmd;\n\nfunction which(name) {\n  var paths = process.env.PATH.split(':');\n  var loc;\n\n  for (var i = 0, len = paths.length; i < len; ++i) {\n    loc = path.join(paths[i], name);\n    if (exists(loc)) return loc;\n  }\n}\n\nswitch(os.type()) {\n  case 'Darwin':\n    if (which('terminal-notifier')) {\n      cmd = {\n          type: \"Darwin-NotificationCenter\"\n        , pkg: \"terminal-notifier\"\n        , msg: '-message'\n        , title: '-title'\n        , subtitle: '-subtitle'\n        , icon: '-appIcon'\n        , sound:  '-sound'\n        , url: '-open'\n        , priority: {\n              cmd: '-execute'\n            , range: []\n          }\n      };\n    } else {\n      cmd = {\n          type: \"Darwin-Growl\"\n        , pkg: \"growlnotify\"\n        , msg: '-m'\n        , sticky: '--sticky'\n        , priority: {\n              cmd: '--priority'\n            , range: [\n                -2\n              , -1\n              , 0\n              , 1\n              , 2\n              , \"Very Low\"\n              , \"Moderate\"\n              , \"Normal\"\n              , \"High\"\n              , \"Emergency\"\n            ]\n          }\n      };\n    }\n    break;\n  case 'Linux':\n    if (which('growl')) {\n      cmd = {\n          type: \"Linux-Growl\"\n        , pkg: \"growl\"\n        , msg: '-m'\n        , title: '-title'\n        , subtitle: '-subtitle'\n        , host: {\n            cmd: '-H'\n          , hostname: '192.168.33.1'\n        }\n      };\n    } else {\n      cmd = {\n          type: \"Linux\"\n        , pkg: \"notify-send\"\n        , msg: ''\n        , sticky: '-t 0'\n        , icon: '-i'\n        , priority: {\n            cmd: '-u'\n          , range: [\n              \"low\"\n            , \"normal\"\n            , \"critical\"\n          ]\n        }\n      };\n    }\n    break;\n  case 'Windows_NT':\n    cmd = {\n        type: \"Windows\"\n      , pkg: \"growlnotify\"\n      , msg: ''\n      , sticky: '/s:true'\n      , title: '/t:'\n      , icon: '/i:'\n      , url: '/cu:'\n      , priority: {\n            cmd: '/p:'\n          , range: [\n              -2\n            , -1\n            , 0\n            , 1\n            , 2\n          ]\n        }\n    };\n    break;\n}\n\n/**\n * Expose `growl`.\n */\n\nexports = module.exports = growl;\n\n/**\n * Node-growl version.\n */\n\nexports.version = '1.4.1'\n\n/**\n * Send growl notification _msg_ with _options_.\n *\n * Options:\n *\n *  - title   Notification title\n *  - sticky  Make the notification stick (defaults to false)\n *  - priority  Specify an int or named key (default is 0)\n *  - name    Application name (defaults to growlnotify)\n *  - sound   Sound efect ( in OSx defined in preferences -> sound -> effects) * works only in OSX > 10.8x\n *  - image\n *    - path to an icon sets --iconpath\n *    - path to an image sets --image\n *    - capitalized word sets --appIcon\n *    - filename uses extname as --icon\n *    - otherwise treated as --icon\n *\n * Examples:\n *\n *   growl('New email')\n *   growl('5 new emails', { title: 'Thunderbird' })\n *   growl('5 new emails', { title: 'Thunderbird', sound: 'Purr' })\n *   growl('Email sent', function(){\n *     // ... notification sent\n *   })\n *\n * @param {string} msg\n * @param {object} options\n * @param {function} fn\n * @api public\n */\n\nfunction growl(msg, options, fn) {\n  var image\n    , args\n    , options = options || {}\n    , fn = fn || function(){};\n\n  if (options.exec) {\n    cmd = {\n        type: \"Custom\"\n      , pkg: options.exec\n      , range: []\n    };\n  }\n\n  // noop\n  if (!cmd) return fn(new Error('growl not supported on this platform'));\n  args = [cmd.pkg];\n\n  // image\n  if (image = options.image) {\n    switch(cmd.type) {\n      case 'Darwin-Growl':\n        var flag, ext = path.extname(image).substr(1)\n        flag = flag || ext == 'icns' && 'iconpath'\n        flag = flag || /^[A-Z]/.test(image) && 'appIcon'\n        flag = flag || /^png|gif|jpe?g$/.test(ext) && 'image'\n        flag = flag || ext && (image = ext) && 'icon'\n        flag = flag || 'icon'\n        args.push('--' + flag, quote(image))\n        break;\n      case 'Darwin-NotificationCenter':\n        args.push(cmd.icon, quote(image));\n        break;\n      case 'Linux':\n        args.push(cmd.icon, quote(image));\n        // libnotify defaults to sticky, set a hint for transient notifications\n        if (!options.sticky) args.push('--hint=int:transient:1');\n        break;\n      case 'Windows':\n        args.push(cmd.icon + quote(image));\n        break;\n    }\n  }\n\n  // sticky\n  if (options.sticky) args.push(cmd.sticky);\n\n  // priority\n  if (options.priority) {\n    var priority = options.priority + '';\n    var checkindexOf = cmd.priority.range.indexOf(priority);\n    if (~cmd.priority.range.indexOf(priority)) {\n      args.push(cmd.priority, options.priority);\n    }\n  }\n\n  //sound\n  if(options.sound && cmd.type === 'Darwin-NotificationCenter'){\n    args.push(cmd.sound, options.sound)\n  }\n\n  // name\n  if (options.name && cmd.type === \"Darwin-Growl\") {\n    args.push('--name', options.name);\n  }\n\n  switch(cmd.type) {\n    case 'Darwin-Growl':\n      args.push(cmd.msg);\n      args.push(quote(msg).replace(/\\\\n/g, '\\n'));\n      if (options.title) args.push(quote(options.title));\n      break;\n    case 'Darwin-NotificationCenter':\n      args.push(cmd.msg);\n      var stringifiedMsg = quote(msg);\n      var escapedMsg = stringifiedMsg.replace(/\\\\n/g, '\\n');\n      args.push(escapedMsg);\n      if (options.title) {\n        args.push(cmd.title);\n        args.push(quote(options.title));\n      }\n      if (options.subtitle) {\n        args.push(cmd.subtitle);\n        args.push(quote(options.subtitle));\n      }\n      if (options.url) {\n        args.push(cmd.url);\n        args.push(quote(options.url));\n      }\n      break;\n    case 'Linux-Growl':\n      args.push(cmd.msg);\n      args.push(quote(msg).replace(/\\\\n/g, '\\n'));\n      if (options.title) args.push(quote(options.title));\n      if (cmd.host) {\n        args.push(cmd.host.cmd, cmd.host.hostname)\n      }\n      break;\n    case 'Linux':\n      if (options.title) {\n        args.push(quote(options.title));\n        args.push(cmd.msg);\n        args.push(quote(msg).replace(/\\\\n/g, '\\n'));\n      } else {\n        args.push(quote(msg).replace(/\\\\n/g, '\\n'));\n      }\n      break;\n    case 'Windows':\n      args.push(quote(msg).replace(/\\\\n/g, '\\n'));\n      if (options.title) args.push(cmd.title + quote(options.title));\n      if (options.url) args.push(cmd.url + quote(options.url));\n      break;\n    case 'Custom':\n      args[0] = (function(origCommand) {\n        var message = options.title\n          ? options.title + ': ' + msg\n          : msg;\n        var command = origCommand.replace(/(^|[^%])%s/g, '$1' + quote(message));\n        if (command === origCommand) args.push(quote(message));\n        return command;\n      })(args[0]);\n      break;\n  }\n\n  // execute\n  exec(args.join(' '), fn);\n};\n\n}).call(this,require('_process'))\n},{\"_process\":67,\"child_process\":42,\"fs\":42,\"os\":65,\"path\":42}],50:[function(require,module,exports){\nexports.read = function (buffer, offset, isLE, mLen, nBytes) {\n  var e, m\n  var eLen = nBytes * 8 - mLen - 1\n  var eMax = (1 << eLen) - 1\n  var eBias = eMax >> 1\n  var nBits = -7\n  var i = isLE ? (nBytes - 1) : 0\n  var d = isLE ? -1 : 1\n  var s = buffer[offset + i]\n\n  i += d\n\n  e = s & ((1 << (-nBits)) - 1)\n  s >>= (-nBits)\n  nBits += eLen\n  for (; nBits > 0; e = e * 256 + buffer[offset + i], i += d, nBits -= 8) {}\n\n  m = e & ((1 << (-nBits)) - 1)\n  e >>= (-nBits)\n  nBits += mLen\n  for (; nBits > 0; m = m * 256 + buffer[offset + i], i += d, nBits -= 8) {}\n\n  if (e === 0) {\n    e = 1 - eBias\n  } else if (e === eMax) {\n    return m ? NaN : ((s ? -1 : 1) * Infinity)\n  } else {\n    m = m + Math.pow(2, mLen)\n    e = e - eBias\n  }\n  return (s ? -1 : 1) * m * Math.pow(2, e - mLen)\n}\n\nexports.write = function (buffer, value, offset, isLE, mLen, nBytes) {\n  var e, m, c\n  var eLen = nBytes * 8 - mLen - 1\n  var eMax = (1 << eLen) - 1\n  var eBias = eMax >> 1\n  var rt = (mLen === 23 ? Math.pow(2, -24) - Math.pow(2, -77) : 0)\n  var i = isLE ? 0 : (nBytes - 1)\n  var d = isLE ? 1 : -1\n  var s = value < 0 || (value === 0 && 1 / value < 0) ? 1 : 0\n\n  value = Math.abs(value)\n\n  if (isNaN(value) || value === Infinity) {\n    m = isNaN(value) ? 1 : 0\n    e = eMax\n  } else {\n    e = Math.floor(Math.log(value) / Math.LN2)\n    if (value * (c = Math.pow(2, -e)) < 1) {\n      e--\n      c *= 2\n    }\n    if (e + eBias >= 1) {\n      value += rt / c\n    } else {\n      value += rt * Math.pow(2, 1 - eBias)\n    }\n    if (value * c >= 2) {\n      e++\n      c /= 2\n    }\n\n    if (e + eBias >= eMax) {\n      m = 0\n      e = eMax\n    } else if (e + eBias >= 1) {\n      m = (value * c - 1) * Math.pow(2, mLen)\n      e = e + eBias\n    } else {\n      m = value * Math.pow(2, eBias - 1) * Math.pow(2, mLen)\n      e = 0\n    }\n  }\n\n  for (; mLen >= 8; buffer[offset + i] = m & 0xff, i += d, m /= 256, mLen -= 8) {}\n\n  e = (e << mLen) | m\n  eLen += mLen\n  for (; eLen > 0; buffer[offset + i] = e & 0xff, i += d, e /= 256, eLen -= 8) {}\n\n  buffer[offset + i - d] |= s * 128\n}\n\n},{}],51:[function(require,module,exports){\nif (typeof Object.create === 'function') {\n  // implementation from standard node.js 'util' module\n  module.exports = function inherits(ctor, superCtor) {\n    ctor.super_ = superCtor\n    ctor.prototype = Object.create(superCtor.prototype, {\n      constructor: {\n        value: ctor,\n        enumerable: false,\n        writable: true,\n        configurable: true\n      }\n    });\n  };\n} else {\n  // old school shim for old browsers\n  module.exports = function inherits(ctor, superCtor) {\n    ctor.super_ = superCtor\n    var TempCtor = function () {}\n    TempCtor.prototype = superCtor.prototype\n    ctor.prototype = new TempCtor()\n    ctor.prototype.constructor = ctor\n  }\n}\n\n},{}],52:[function(require,module,exports){\n/*!\n * Determine if an object is a Buffer\n *\n * @author   Feross Aboukhadijeh <feross@feross.org> <http://feross.org>\n * @license  MIT\n */\n\n// The _isBuffer check is for Safari 5-7 support, because it's missing\n// Object.prototype.constructor. Remove this eventually\nmodule.exports = function (obj) {\n  return obj != null && (isBuffer(obj) || isSlowBuffer(obj) || !!obj._isBuffer)\n}\n\nfunction isBuffer (obj) {\n  return !!obj.constructor && typeof obj.constructor.isBuffer === 'function' && obj.constructor.isBuffer(obj)\n}\n\n// For Node v0.10 support. Remove this eventually.\nfunction isSlowBuffer (obj) {\n  return typeof obj.readFloatLE === 'function' && typeof obj.slice === 'function' && isBuffer(obj.slice(0, 0))\n}\n\n},{}],53:[function(require,module,exports){\nvar toString = {}.toString;\n\nmodule.exports = Array.isArray || function (arr) {\n  return toString.call(arr) == '[object Array]';\n};\n\n},{}],54:[function(require,module,exports){\n(function (global){\n/*! JSON v3.3.2 | http://bestiejs.github.io/json3 | Copyright 2012-2014, Kit Cambridge | http://kit.mit-license.org */\n;(function () {\n  // Detect the `define` function exposed by asynchronous module loaders. The\n  // strict `define` check is necessary for compatibility with `r.js`.\n  var isLoader = false;\n\n  // A set of types used to distinguish objects from primitives.\n  var objectTypes = {\n    \"function\": true,\n    \"object\": true\n  };\n\n  // Detect the `exports` object exposed by CommonJS implementations.\n  var freeExports = objectTypes[typeof exports] && exports && !exports.nodeType && exports;\n\n  // Use the `global` object exposed by Node (including Browserify via\n  // `insert-module-globals`), Narwhal, and Ringo as the default context,\n  // and the `window` object in browsers. Rhino exports a `global` function\n  // instead.\n  var root = objectTypes[typeof window] && window || this,\n      freeGlobal = freeExports && objectTypes[typeof module] && module && !module.nodeType && typeof global == \"object\" && global;\n\n  if (freeGlobal && (freeGlobal[\"global\"] === freeGlobal || freeGlobal[\"window\"] === freeGlobal || freeGlobal[\"self\"] === freeGlobal)) {\n    root = freeGlobal;\n  }\n\n  // Public: Initializes JSON 3 using the given `context` object, attaching the\n  // `stringify` and `parse` functions to the specified `exports` object.\n  function runInContext(context, exports) {\n    context || (context = root[\"Object\"]());\n    exports || (exports = root[\"Object\"]());\n\n    // Native constructor aliases.\n    var Number = context[\"Number\"] || root[\"Number\"],\n        String = context[\"String\"] || root[\"String\"],\n        Object = context[\"Object\"] || root[\"Object\"],\n        Date = context[\"Date\"] || root[\"Date\"],\n        SyntaxError = context[\"SyntaxError\"] || root[\"SyntaxError\"],\n        TypeError = context[\"TypeError\"] || root[\"TypeError\"],\n        Math = context[\"Math\"] || root[\"Math\"],\n        nativeJSON = context[\"JSON\"] || root[\"JSON\"];\n\n    // Delegate to the native `stringify` and `parse` implementations.\n    if (typeof nativeJSON == \"object\" && nativeJSON) {\n      exports.stringify = nativeJSON.stringify;\n      exports.parse = nativeJSON.parse;\n    }\n\n    // Convenience aliases.\n    var objectProto = Object.prototype,\n        getClass = objectProto.toString,\n        isProperty, forEach, undef;\n\n    // Test the `Date#getUTC*` methods. Based on work by @Yaffle.\n    var isExtended = new Date(-3509827334573292);\n    try {\n      // The `getUTCFullYear`, `Month`, and `Date` methods return nonsensical\n      // results for certain dates in Opera >= 10.53.\n      isExtended = isExtended.getUTCFullYear() == -109252 && isExtended.getUTCMonth() === 0 && isExtended.getUTCDate() === 1 &&\n        // Safari < 2.0.2 stores the internal millisecond time value correctly,\n        // but clips the values returned by the date methods to the range of\n        // signed 32-bit integers ([-2 ** 31, 2 ** 31 - 1]).\n        isExtended.getUTCHours() == 10 && isExtended.getUTCMinutes() == 37 && isExtended.getUTCSeconds() == 6 && isExtended.getUTCMilliseconds() == 708;\n    } catch (exception) {}\n\n    // Internal: Determines whether the native `JSON.stringify` and `parse`\n    // implementations are spec-compliant. Based on work by Ken Snyder.\n    function has(name) {\n      if (has[name] !== undef) {\n        // Return cached feature test result.\n        return has[name];\n      }\n      var isSupported;\n      if (name == \"bug-string-char-index\") {\n        // IE <= 7 doesn't support accessing string characters using square\n        // bracket notation. IE 8 only supports this for primitives.\n        isSupported = \"a\"[0] != \"a\";\n      } else if (name == \"json\") {\n        // Indicates whether both `JSON.stringify` and `JSON.parse` are\n        // supported.\n        isSupported = has(\"json-stringify\") && has(\"json-parse\");\n      } else {\n        var value, serialized = '{\"a\":[1,true,false,null,\"\\\\u0000\\\\b\\\\n\\\\f\\\\r\\\\t\"]}';\n        // Test `JSON.stringify`.\n        if (name == \"json-stringify\") {\n          var stringify = exports.stringify, stringifySupported = typeof stringify == \"function\" && isExtended;\n          if (stringifySupported) {\n            // A test function object with a custom `toJSON` method.\n            (value = function () {\n              return 1;\n            }).toJSON = value;\n            try {\n              stringifySupported =\n                // Firefox 3.1b1 and b2 serialize string, number, and boolean\n                // primitives as object literals.\n                stringify(0) === \"0\" &&\n                // FF 3.1b1, b2, and JSON 2 serialize wrapped primitives as object\n                // literals.\n                stringify(new Number()) === \"0\" &&\n                stringify(new String()) == '\"\"' &&\n                // FF 3.1b1, 2 throw an error if the value is `null`, `undefined`, or\n                // does not define a canonical JSON representation (this applies to\n                // objects with `toJSON` properties as well, *unless* they are nested\n                // within an object or array).\n                stringify(getClass) === undef &&\n                // IE 8 serializes `undefined` as `\"undefined\"`. Safari <= 5.1.7 and\n                // FF 3.1b3 pass this test.\n                stringify(undef) === undef &&\n                // Safari <= 5.1.7 and FF 3.1b3 throw `Error`s and `TypeError`s,\n                // respectively, if the value is omitted entirely.\n                stringify() === undef &&\n                // FF 3.1b1, 2 throw an error if the given value is not a number,\n                // string, array, object, Boolean, or `null` literal. This applies to\n                // objects with custom `toJSON` methods as well, unless they are nested\n                // inside object or array literals. YUI 3.0.0b1 ignores custom `toJSON`\n                // methods entirely.\n                stringify(value) === \"1\" &&\n                stringify([value]) == \"[1]\" &&\n                // Prototype <= 1.6.1 serializes `[undefined]` as `\"[]\"` instead of\n                // `\"[null]\"`.\n                stringify([undef]) == \"[null]\" &&\n                // YUI 3.0.0b1 fails to serialize `null` literals.\n                stringify(null) == \"null\" &&\n                // FF 3.1b1, 2 halts serialization if an array contains a function:\n                // `[1, true, getClass, 1]` serializes as \"[1,true,],\". FF 3.1b3\n                // elides non-JSON values from objects and arrays, unless they\n                // define custom `toJSON` methods.\n                stringify([undef, getClass, null]) == \"[null,null,null]\" &&\n                // Simple serialization test. FF 3.1b1 uses Unicode escape sequences\n                // where character escape codes are expected (e.g., `\\b` => `\\u0008`).\n                stringify({ \"a\": [value, true, false, null, \"\\x00\\b\\n\\f\\r\\t\"] }) == serialized &&\n                // FF 3.1b1 and b2 ignore the `filter` and `width` arguments.\n                stringify(null, value) === \"1\" &&\n                stringify([1, 2], null, 1) == \"[\\n 1,\\n 2\\n]\" &&\n                // JSON 2, Prototype <= 1.7, and older WebKit builds incorrectly\n                // serialize extended years.\n                stringify(new Date(-8.64e15)) == '\"-271821-04-20T00:00:00.000Z\"' &&\n                // The milliseconds are optional in ES 5, but required in 5.1.\n                stringify(new Date(8.64e15)) == '\"+275760-09-13T00:00:00.000Z\"' &&\n                // Firefox <= 11.0 incorrectly serializes years prior to 0 as negative\n                // four-digit years instead of six-digit years. Credits: @Yaffle.\n                stringify(new Date(-621987552e5)) == '\"-000001-01-01T00:00:00.000Z\"' &&\n                // Safari <= 5.1.5 and Opera >= 10.53 incorrectly serialize millisecond\n                // values less than 1000. Credits: @Yaffle.\n                stringify(new Date(-1)) == '\"1969-12-31T23:59:59.999Z\"';\n            } catch (exception) {\n              stringifySupported = false;\n            }\n          }\n          isSupported = stringifySupported;\n        }\n        // Test `JSON.parse`.\n        if (name == \"json-parse\") {\n          var parse = exports.parse;\n          if (typeof parse == \"function\") {\n            try {\n              // FF 3.1b1, b2 will throw an exception if a bare literal is provided.\n              // Conforming implementations should also coerce the initial argument to\n              // a string prior to parsing.\n              if (parse(\"0\") === 0 && !parse(false)) {\n                // Simple parsing test.\n                value = parse(serialized);\n                var parseSupported = value[\"a\"].length == 5 && value[\"a\"][0] === 1;\n                if (parseSupported) {\n                  try {\n                    // Safari <= 5.1.2 and FF 3.1b1 allow unescaped tabs in strings.\n                    parseSupported = !parse('\"\\t\"');\n                  } catch (exception) {}\n                  if (parseSupported) {\n                    try {\n                      // FF 4.0 and 4.0.1 allow leading `+` signs and leading\n                      // decimal points. FF 4.0, 4.0.1, and IE 9-10 also allow\n                      // certain octal literals.\n                      parseSupported = parse(\"01\") !== 1;\n                    } catch (exception) {}\n                  }\n                  if (parseSupported) {\n                    try {\n                      // FF 4.0, 4.0.1, and Rhino 1.7R3-R4 allow trailing decimal\n                      // points. These environments, along with FF 3.1b1 and 2,\n                      // also allow trailing commas in JSON objects and arrays.\n                      parseSupported = parse(\"1.\") !== 1;\n                    } catch (exception) {}\n                  }\n                }\n              }\n            } catch (exception) {\n              parseSupported = false;\n            }\n          }\n          isSupported = parseSupported;\n        }\n      }\n      return has[name] = !!isSupported;\n    }\n\n    if (!has(\"json\")) {\n      // Common `[[Class]]` name aliases.\n      var functionClass = \"[object Function]\",\n          dateClass = \"[object Date]\",\n          numberClass = \"[object Number]\",\n          stringClass = \"[object String]\",\n          arrayClass = \"[object Array]\",\n          booleanClass = \"[object Boolean]\";\n\n      // Detect incomplete support for accessing string characters by index.\n      var charIndexBuggy = has(\"bug-string-char-index\");\n\n      // Define additional utility methods if the `Date` methods are buggy.\n      if (!isExtended) {\n        var floor = Math.floor;\n        // A mapping between the months of the year and the number of days between\n        // January 1st and the first of the respective month.\n        var Months = [0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334];\n        // Internal: Calculates the number of days between the Unix epoch and the\n        // first day of the given month.\n        var getDay = function (year, month) {\n          return Months[month] + 365 * (year - 1970) + floor((year - 1969 + (month = +(month > 1))) / 4) - floor((year - 1901 + month) / 100) + floor((year - 1601 + month) / 400);\n        };\n      }\n\n      // Internal: Determines if a property is a direct property of the given\n      // object. Delegates to the native `Object#hasOwnProperty` method.\n      if (!(isProperty = objectProto.hasOwnProperty)) {\n        isProperty = function (property) {\n          var members = {}, constructor;\n          if ((members.__proto__ = null, members.__proto__ = {\n            // The *proto* property cannot be set multiple times in recent\n            // versions of Firefox and SeaMonkey.\n            \"toString\": 1\n          }, members).toString != getClass) {\n            // Safari <= 2.0.3 doesn't implement `Object#hasOwnProperty`, but\n            // supports the mutable *proto* property.\n            isProperty = function (property) {\n              // Capture and break the object's prototype chain (see section 8.6.2\n              // of the ES 5.1 spec). The parenthesized expression prevents an\n              // unsafe transformation by the Closure Compiler.\n              var original = this.__proto__, result = property in (this.__proto__ = null, this);\n              // Restore the original prototype chain.\n              this.__proto__ = original;\n              return result;\n            };\n          } else {\n            // Capture a reference to the top-level `Object` constructor.\n            constructor = members.constructor;\n            // Use the `constructor` property to simulate `Object#hasOwnProperty` in\n            // other environments.\n            isProperty = function (property) {\n              var parent = (this.constructor || constructor).prototype;\n              return property in this && !(property in parent && this[property] === parent[property]);\n            };\n          }\n          members = null;\n          return isProperty.call(this, property);\n        };\n      }\n\n      // Internal: Normalizes the `for...in` iteration algorithm across\n      // environments. Each enumerated key is yielded to a `callback` function.\n      forEach = function (object, callback) {\n        var size = 0, Properties, members, property;\n\n        // Tests for bugs in the current environment's `for...in` algorithm. The\n        // `valueOf` property inherits the non-enumerable flag from\n        // `Object.prototype` in older versions of IE, Netscape, and Mozilla.\n        (Properties = function () {\n          this.valueOf = 0;\n        }).prototype.valueOf = 0;\n\n        // Iterate over a new instance of the `Properties` class.\n        members = new Properties();\n        for (property in members) {\n          // Ignore all properties inherited from `Object.prototype`.\n          if (isProperty.call(members, property)) {\n            size++;\n          }\n        }\n        Properties = members = null;\n\n        // Normalize the iteration algorithm.\n        if (!size) {\n          // A list of non-enumerable properties inherited from `Object.prototype`.\n          members = [\"valueOf\", \"toString\", \"toLocaleString\", \"propertyIsEnumerable\", \"isPrototypeOf\", \"hasOwnProperty\", \"constructor\"];\n          // IE <= 8, Mozilla 1.0, and Netscape 6.2 ignore shadowed non-enumerable\n          // properties.\n          forEach = function (object, callback) {\n            var isFunction = getClass.call(object) == functionClass, property, length;\n            var hasProperty = !isFunction && typeof object.constructor != \"function\" && objectTypes[typeof object.hasOwnProperty] && object.hasOwnProperty || isProperty;\n            for (property in object) {\n              // Gecko <= 1.0 enumerates the `prototype` property of functions under\n              // certain conditions; IE does not.\n              if (!(isFunction && property == \"prototype\") && hasProperty.call(object, property)) {\n                callback(property);\n              }\n            }\n            // Manually invoke the callback for each non-enumerable property.\n            for (length = members.length; property = members[--length]; hasProperty.call(object, property) && callback(property));\n          };\n        } else if (size == 2) {\n          // Safari <= 2.0.4 enumerates shadowed properties twice.\n          forEach = function (object, callback) {\n            // Create a set of iterated properties.\n            var members = {}, isFunction = getClass.call(object) == functionClass, property;\n            for (property in object) {\n              // Store each property name to prevent double enumeration. The\n              // `prototype` property of functions is not enumerated due to cross-\n              // environment inconsistencies.\n              if (!(isFunction && property == \"prototype\") && !isProperty.call(members, property) && (members[property] = 1) && isProperty.call(object, property)) {\n                callback(property);\n              }\n            }\n          };\n        } else {\n          // No bugs detected; use the standard `for...in` algorithm.\n          forEach = function (object, callback) {\n            var isFunction = getClass.call(object) == functionClass, property, isConstructor;\n            for (property in object) {\n              if (!(isFunction && property == \"prototype\") && isProperty.call(object, property) && !(isConstructor = property === \"constructor\")) {\n                callback(property);\n              }\n            }\n            // Manually invoke the callback for the `constructor` property due to\n            // cross-environment inconsistencies.\n            if (isConstructor || isProperty.call(object, (property = \"constructor\"))) {\n              callback(property);\n            }\n          };\n        }\n        return forEach(object, callback);\n      };\n\n      // Public: Serializes a JavaScript `value` as a JSON string. The optional\n      // `filter` argument may specify either a function that alters how object and\n      // array members are serialized, or an array of strings and numbers that\n      // indicates which properties should be serialized. The optional `width`\n      // argument may be either a string or number that specifies the indentation\n      // level of the output.\n      if (!has(\"json-stringify\")) {\n        // Internal: A map of control characters and their escaped equivalents.\n        var Escapes = {\n          92: \"\\\\\\\\\",\n          34: '\\\\\"',\n          8: \"\\\\b\",\n          12: \"\\\\f\",\n          10: \"\\\\n\",\n          13: \"\\\\r\",\n          9: \"\\\\t\"\n        };\n\n        // Internal: Converts `value` into a zero-padded string such that its\n        // length is at least equal to `width`. The `width` must be <= 6.\n        var leadingZeroes = \"000000\";\n        var toPaddedString = function (width, value) {\n          // The `|| 0` expression is necessary to work around a bug in\n          // Opera <= 7.54u2 where `0 == -0`, but `String(-0) !== \"0\"`.\n          return (leadingZeroes + (value || 0)).slice(-width);\n        };\n\n        // Internal: Double-quotes a string `value`, replacing all ASCII control\n        // characters (characters with code unit values between 0 and 31) with\n        // their escaped equivalents. This is an implementation of the\n        // `Quote(value)` operation defined in ES 5.1 section 15.12.3.\n        var unicodePrefix = \"\\\\u00\";\n        var quote = function (value) {\n          var result = '\"', index = 0, length = value.length, useCharIndex = !charIndexBuggy || length > 10;\n          var symbols = useCharIndex && (charIndexBuggy ? value.split(\"\") : value);\n          for (; index < length; index++) {\n            var charCode = value.charCodeAt(index);\n            // If the character is a control character, append its Unicode or\n            // shorthand escape sequence; otherwise, append the character as-is.\n            switch (charCode) {\n              case 8: case 9: case 10: case 12: case 13: case 34: case 92:\n                result += Escapes[charCode];\n                break;\n              default:\n                if (charCode < 32) {\n                  result += unicodePrefix + toPaddedString(2, charCode.toString(16));\n                  break;\n                }\n                result += useCharIndex ? symbols[index] : value.charAt(index);\n            }\n          }\n          return result + '\"';\n        };\n\n        // Internal: Recursively serializes an object. Implements the\n        // `Str(key, holder)`, `JO(value)`, and `JA(value)` operations.\n        var serialize = function (property, object, callback, properties, whitespace, indentation, stack) {\n          var value, className, year, month, date, time, hours, minutes, seconds, milliseconds, results, element, index, length, prefix, result;\n          try {\n            // Necessary for host object support.\n            value = object[property];\n          } catch (exception) {}\n          if (typeof value == \"object\" && value) {\n            className = getClass.call(value);\n            if (className == dateClass && !isProperty.call(value, \"toJSON\")) {\n              if (value > -1 / 0 && value < 1 / 0) {\n                // Dates are serialized according to the `Date#toJSON` method\n                // specified in ES 5.1 section 15.9.5.44. See section 15.9.1.15\n                // for the ISO 8601 date time string format.\n                if (getDay) {\n                  // Manually compute the year, month, date, hours, minutes,\n                  // seconds, and milliseconds if the `getUTC*` methods are\n                  // buggy. Adapted from @Yaffle's `date-shim` project.\n                  date = floor(value / 864e5);\n                  for (year = floor(date / 365.2425) + 1970 - 1; getDay(year + 1, 0) <= date; year++);\n                  for (month = floor((date - getDay(year, 0)) / 30.42); getDay(year, month + 1) <= date; month++);\n                  date = 1 + date - getDay(year, month);\n                  // The `time` value specifies the time within the day (see ES\n                  // 5.1 section 15.9.1.2). The formula `(A % B + B) % B` is used\n                  // to compute `A modulo B`, as the `%` operator does not\n                  // correspond to the `modulo` operation for negative numbers.\n                  time = (value % 864e5 + 864e5) % 864e5;\n                  // The hours, minutes, seconds, and milliseconds are obtained by\n                  // decomposing the time within the day. See section 15.9.1.10.\n                  hours = floor(time / 36e5) % 24;\n                  minutes = floor(time / 6e4) % 60;\n                  seconds = floor(time / 1e3) % 60;\n                  milliseconds = time % 1e3;\n                } else {\n                  year = value.getUTCFullYear();\n                  month = value.getUTCMonth();\n                  date = value.getUTCDate();\n                  hours = value.getUTCHours();\n                  minutes = value.getUTCMinutes();\n                  seconds = value.getUTCSeconds();\n                  milliseconds = value.getUTCMilliseconds();\n                }\n                // Serialize extended years correctly.\n                value = (year <= 0 || year >= 1e4 ? (year < 0 ? \"-\" : \"+\") + toPaddedString(6, year < 0 ? -year : year) : toPaddedString(4, year)) +\n                  \"-\" + toPaddedString(2, month + 1) + \"-\" + toPaddedString(2, date) +\n                  // Months, dates, hours, minutes, and seconds should have two\n                  // digits; milliseconds should have three.\n                  \"T\" + toPaddedString(2, hours) + \":\" + toPaddedString(2, minutes) + \":\" + toPaddedString(2, seconds) +\n                  // Milliseconds are optional in ES 5.0, but required in 5.1.\n                  \".\" + toPaddedString(3, milliseconds) + \"Z\";\n              } else {\n                value = null;\n              }\n            } else if (typeof value.toJSON == \"function\" && ((className != numberClass && className != stringClass && className != arrayClass) || isProperty.call(value, \"toJSON\"))) {\n              // Prototype <= 1.6.1 adds non-standard `toJSON` methods to the\n              // `Number`, `String`, `Date`, and `Array` prototypes. JSON 3\n              // ignores all `toJSON` methods on these objects unless they are\n              // defined directly on an instance.\n              value = value.toJSON(property);\n            }\n          }\n          if (callback) {\n            // If a replacement function was provided, call it to obtain the value\n            // for serialization.\n            value = callback.call(object, property, value);\n          }\n          if (value === null) {\n            return \"null\";\n          }\n          className = getClass.call(value);\n          if (className == booleanClass) {\n            // Booleans are represented literally.\n            return \"\" + value;\n          } else if (className == numberClass) {\n            // JSON numbers must be finite. `Infinity` and `NaN` are serialized as\n            // `\"null\"`.\n            return value > -1 / 0 && value < 1 / 0 ? \"\" + value : \"null\";\n          } else if (className == stringClass) {\n            // Strings are double-quoted and escaped.\n            return quote(\"\" + value);\n          }\n          // Recursively serialize objects and arrays.\n          if (typeof value == \"object\") {\n            // Check for cyclic structures. This is a linear search; performance\n            // is inversely proportional to the number of unique nested objects.\n            for (length = stack.length; length--;) {\n              if (stack[length] === value) {\n                // Cyclic structures cannot be serialized by `JSON.stringify`.\n                throw TypeError();\n              }\n            }\n            // Add the object to the stack of traversed objects.\n            stack.push(value);\n            results = [];\n            // Save the current indentation level and indent one additional level.\n            prefix = indentation;\n            indentation += whitespace;\n            if (className == arrayClass) {\n              // Recursively serialize array elements.\n              for (index = 0, length = value.length; index < length; index++) {\n                element = serialize(index, value, callback, properties, whitespace, indentation, stack);\n                results.push(element === undef ? \"null\" : element);\n              }\n              result = results.length ? (whitespace ? \"[\\n\" + indentation + results.join(\",\\n\" + indentation) + \"\\n\" + prefix + \"]\" : (\"[\" + results.join(\",\") + \"]\")) : \"[]\";\n            } else {\n              // Recursively serialize object members. Members are selected from\n              // either a user-specified list of property names, or the object\n              // itself.\n              forEach(properties || value, function (property) {\n                var element = serialize(property, value, callback, properties, whitespace, indentation, stack);\n                if (element !== undef) {\n                  // According to ES 5.1 section 15.12.3: \"If `gap` {whitespace}\n                  // is not the empty string, let `member` {quote(property) + \":\"}\n                  // be the concatenation of `member` and the `space` character.\"\n                  // The \"`space` character\" refers to the literal space\n                  // character, not the `space` {width} argument provided to\n                  // `JSON.stringify`.\n                  results.push(quote(property) + \":\" + (whitespace ? \" \" : \"\") + element);\n                }\n              });\n              result = results.length ? (whitespace ? \"{\\n\" + indentation + results.join(\",\\n\" + indentation) + \"\\n\" + prefix + \"}\" : (\"{\" + results.join(\",\") + \"}\")) : \"{}\";\n            }\n            // Remove the object from the traversed object stack.\n            stack.pop();\n            return result;\n          }\n        };\n\n        // Public: `JSON.stringify`. See ES 5.1 section 15.12.3.\n        exports.stringify = function (source, filter, width) {\n          var whitespace, callback, properties, className;\n          if (objectTypes[typeof filter] && filter) {\n            if ((className = getClass.call(filter)) == functionClass) {\n              callback = filter;\n            } else if (className == arrayClass) {\n              // Convert the property names array into a makeshift set.\n              properties = {};\n              for (var index = 0, length = filter.length, value; index < length; value = filter[index++], ((className = getClass.call(value)), className == stringClass || className == numberClass) && (properties[value] = 1));\n            }\n          }\n          if (width) {\n            if ((className = getClass.call(width)) == numberClass) {\n              // Convert the `width` to an integer and create a string containing\n              // `width` number of space characters.\n              if ((width -= width % 1) > 0) {\n                for (whitespace = \"\", width > 10 && (width = 10); whitespace.length < width; whitespace += \" \");\n              }\n            } else if (className == stringClass) {\n              whitespace = width.length <= 10 ? width : width.slice(0, 10);\n            }\n          }\n          // Opera <= 7.54u2 discards the values associated with empty string keys\n          // (`\"\"`) only if they are used directly within an object member list\n          // (e.g., `!(\"\" in { \"\": 1})`).\n          return serialize(\"\", (value = {}, value[\"\"] = source, value), callback, properties, whitespace, \"\", []);\n        };\n      }\n\n      // Public: Parses a JSON source string.\n      if (!has(\"json-parse\")) {\n        var fromCharCode = String.fromCharCode;\n\n        // Internal: A map of escaped control characters and their unescaped\n        // equivalents.\n        var Unescapes = {\n          92: \"\\\\\",\n          34: '\"',\n          47: \"/\",\n          98: \"\\b\",\n          116: \"\\t\",\n          110: \"\\n\",\n          102: \"\\f\",\n          114: \"\\r\"\n        };\n\n        // Internal: Stores the parser state.\n        var Index, Source;\n\n        // Internal: Resets the parser state and throws a `SyntaxError`.\n        var abort = function () {\n          Index = Source = null;\n          throw SyntaxError();\n        };\n\n        // Internal: Returns the next token, or `\"$\"` if the parser has reached\n        // the end of the source string. A token may be a string, number, `null`\n        // literal, or Boolean literal.\n        var lex = function () {\n          var source = Source, length = source.length, value, begin, position, isSigned, charCode;\n          while (Index < length) {\n            charCode = source.charCodeAt(Index);\n            switch (charCode) {\n              case 9: case 10: case 13: case 32:\n                // Skip whitespace tokens, including tabs, carriage returns, line\n                // feeds, and space characters.\n                Index++;\n                break;\n              case 123: case 125: case 91: case 93: case 58: case 44:\n                // Parse a punctuator token (`{`, `}`, `[`, `]`, `:`, or `,`) at\n                // the current position.\n                value = charIndexBuggy ? source.charAt(Index) : source[Index];\n                Index++;\n                return value;\n              case 34:\n                // `\"` delimits a JSON string; advance to the next character and\n                // begin parsing the string. String tokens are prefixed with the\n                // sentinel `@` character to distinguish them from punctuators and\n                // end-of-string tokens.\n                for (value = \"@\", Index++; Index < length;) {\n                  charCode = source.charCodeAt(Index);\n                  if (charCode < 32) {\n                    // Unescaped ASCII control characters (those with a code unit\n                    // less than the space character) are not permitted.\n                    abort();\n                  } else if (charCode == 92) {\n                    // A reverse solidus (`\\`) marks the beginning of an escaped\n                    // control character (including `\"`, `\\`, and `/`) or Unicode\n                    // escape sequence.\n                    charCode = source.charCodeAt(++Index);\n                    switch (charCode) {\n                      case 92: case 34: case 47: case 98: case 116: case 110: case 102: case 114:\n                        // Revive escaped control characters.\n                        value += Unescapes[charCode];\n                        Index++;\n                        break;\n                      case 117:\n                        // `\\u` marks the beginning of a Unicode escape sequence.\n                        // Advance to the first character and validate the\n                        // four-digit code point.\n                        begin = ++Index;\n                        for (position = Index + 4; Index < position; Index++) {\n                          charCode = source.charCodeAt(Index);\n                          // A valid sequence comprises four hexdigits (case-\n                          // insensitive) that form a single hexadecimal value.\n                          if (!(charCode >= 48 && charCode <= 57 || charCode >= 97 && charCode <= 102 || charCode >= 65 && charCode <= 70)) {\n                            // Invalid Unicode escape sequence.\n                            abort();\n                          }\n                        }\n                        // Revive the escaped character.\n                        value += fromCharCode(\"0x\" + source.slice(begin, Index));\n                        break;\n                      default:\n                        // Invalid escape sequence.\n                        abort();\n                    }\n                  } else {\n                    if (charCode == 34) {\n                      // An unescaped double-quote character marks the end of the\n                      // string.\n                      break;\n                    }\n                    charCode = source.charCodeAt(Index);\n                    begin = Index;\n                    // Optimize for the common case where a string is valid.\n                    while (charCode >= 32 && charCode != 92 && charCode != 34) {\n                      charCode = source.charCodeAt(++Index);\n                    }\n                    // Append the string as-is.\n                    value += source.slice(begin, Index);\n                  }\n                }\n                if (source.charCodeAt(Index) == 34) {\n                  // Advance to the next character and return the revived string.\n                  Index++;\n                  return value;\n                }\n                // Unterminated string.\n                abort();\n              default:\n                // Parse numbers and literals.\n                begin = Index;\n                // Advance past the negative sign, if one is specified.\n                if (charCode == 45) {\n                  isSigned = true;\n                  charCode = source.charCodeAt(++Index);\n                }\n                // Parse an integer or floating-point value.\n                if (charCode >= 48 && charCode <= 57) {\n                  // Leading zeroes are interpreted as octal literals.\n                  if (charCode == 48 && ((charCode = source.charCodeAt(Index + 1)), charCode >= 48 && charCode <= 57)) {\n                    // Illegal octal literal.\n                    abort();\n                  }\n                  isSigned = false;\n                  // Parse the integer component.\n                  for (; Index < length && ((charCode = source.charCodeAt(Index)), charCode >= 48 && charCode <= 57); Index++);\n                  // Floats cannot contain a leading decimal point; however, this\n                  // case is already accounted for by the parser.\n                  if (source.charCodeAt(Index) == 46) {\n                    position = ++Index;\n                    // Parse the decimal component.\n                    for (; position < length && ((charCode = source.charCodeAt(position)), charCode >= 48 && charCode <= 57); position++);\n                    if (position == Index) {\n                      // Illegal trailing decimal.\n                      abort();\n                    }\n                    Index = position;\n                  }\n                  // Parse exponents. The `e` denoting the exponent is\n                  // case-insensitive.\n                  charCode = source.charCodeAt(Index);\n                  if (charCode == 101 || charCode == 69) {\n                    charCode = source.charCodeAt(++Index);\n                    // Skip past the sign following the exponent, if one is\n                    // specified.\n                    if (charCode == 43 || charCode == 45) {\n                      Index++;\n                    }\n                    // Parse the exponential component.\n                    for (position = Index; position < length && ((charCode = source.charCodeAt(position)), charCode >= 48 && charCode <= 57); position++);\n                    if (position == Index) {\n                      // Illegal empty exponent.\n                      abort();\n                    }\n                    Index = position;\n                  }\n                  // Coerce the parsed value to a JavaScript number.\n                  return +source.slice(begin, Index);\n                }\n                // A negative sign may only precede numbers.\n                if (isSigned) {\n                  abort();\n                }\n                // `true`, `false`, and `null` literals.\n                if (source.slice(Index, Index + 4) == \"true\") {\n                  Index += 4;\n                  return true;\n                } else if (source.slice(Index, Index + 5) == \"false\") {\n                  Index += 5;\n                  return false;\n                } else if (source.slice(Index, Index + 4) == \"null\") {\n                  Index += 4;\n                  return null;\n                }\n                // Unrecognized token.\n                abort();\n            }\n          }\n          // Return the sentinel `$` character if the parser has reached the end\n          // of the source string.\n          return \"$\";\n        };\n\n        // Internal: Parses a JSON `value` token.\n        var get = function (value) {\n          var results, hasMembers;\n          if (value == \"$\") {\n            // Unexpected end of input.\n            abort();\n          }\n          if (typeof value == \"string\") {\n            if ((charIndexBuggy ? value.charAt(0) : value[0]) == \"@\") {\n              // Remove the sentinel `@` character.\n              return value.slice(1);\n            }\n            // Parse object and array literals.\n            if (value == \"[\") {\n              // Parses a JSON array, returning a new JavaScript array.\n              results = [];\n              for (;; hasMembers || (hasMembers = true)) {\n                value = lex();\n                // A closing square bracket marks the end of the array literal.\n                if (value == \"]\") {\n                  break;\n                }\n                // If the array literal contains elements, the current token\n                // should be a comma separating the previous element from the\n                // next.\n                if (hasMembers) {\n                  if (value == \",\") {\n                    value = lex();\n                    if (value == \"]\") {\n                      // Unexpected trailing `,` in array literal.\n                      abort();\n                    }\n                  } else {\n                    // A `,` must separate each array element.\n                    abort();\n                  }\n                }\n                // Elisions and leading commas are not permitted.\n                if (value == \",\") {\n                  abort();\n                }\n                results.push(get(value));\n              }\n              return results;\n            } else if (value == \"{\") {\n              // Parses a JSON object, returning a new JavaScript object.\n              results = {};\n              for (;; hasMembers || (hasMembers = true)) {\n                value = lex();\n                // A closing curly brace marks the end of the object literal.\n                if (value == \"}\") {\n                  break;\n                }\n                // If the object literal contains members, the current token\n                // should be a comma separator.\n                if (hasMembers) {\n                  if (value == \",\") {\n                    value = lex();\n                    if (value == \"}\") {\n                      // Unexpected trailing `,` in object literal.\n                      abort();\n                    }\n                  } else {\n                    // A `,` must separate each object member.\n                    abort();\n                  }\n                }\n                // Leading commas are not permitted, object property names must be\n                // double-quoted strings, and a `:` must separate each property\n                // name and value.\n                if (value == \",\" || typeof value != \"string\" || (charIndexBuggy ? value.charAt(0) : value[0]) != \"@\" || lex() != \":\") {\n                  abort();\n                }\n                results[value.slice(1)] = get(lex());\n              }\n              return results;\n            }\n            // Unexpected token encountered.\n            abort();\n          }\n          return value;\n        };\n\n        // Internal: Updates a traversed object member.\n        var update = function (source, property, callback) {\n          var element = walk(source, property, callback);\n          if (element === undef) {\n            delete source[property];\n          } else {\n            source[property] = element;\n          }\n        };\n\n        // Internal: Recursively traverses a parsed JSON object, invoking the\n        // `callback` function for each value. This is an implementation of the\n        // `Walk(holder, name)` operation defined in ES 5.1 section 15.12.2.\n        var walk = function (source, property, callback) {\n          var value = source[property], length;\n          if (typeof value == \"object\" && value) {\n            // `forEach` can't be used to traverse an array in Opera <= 8.54\n            // because its `Object#hasOwnProperty` implementation returns `false`\n            // for array indices (e.g., `![1, 2, 3].hasOwnProperty(\"0\")`).\n            if (getClass.call(value) == arrayClass) {\n              for (length = value.length; length--;) {\n                update(value, length, callback);\n              }\n            } else {\n              forEach(value, function (property) {\n                update(value, property, callback);\n              });\n            }\n          }\n          return callback.call(source, property, value);\n        };\n\n        // Public: `JSON.parse`. See ES 5.1 section 15.12.2.\n        exports.parse = function (source, callback) {\n          var result, value;\n          Index = 0;\n          Source = \"\" + source;\n          result = get(lex());\n          // If a JSON string contains multiple tokens, it is invalid.\n          if (lex() != \"$\") {\n            abort();\n          }\n          // Reset the parser state.\n          Index = Source = null;\n          return callback && getClass.call(callback) == functionClass ? walk((value = {}, value[\"\"] = result, value), \"\", callback) : result;\n        };\n      }\n    }\n\n    exports[\"runInContext\"] = runInContext;\n    return exports;\n  }\n\n  if (freeExports && !isLoader) {\n    // Export for CommonJS environments.\n    runInContext(root, freeExports);\n  } else {\n    // Export for web browsers and JavaScript engines.\n    var nativeJSON = root.JSON,\n        previousJSON = root[\"JSON3\"],\n        isRestored = false;\n\n    var JSON3 = runInContext(root, (root[\"JSON3\"] = {\n      // Public: Restores the original value of the global `JSON` object and\n      // returns a reference to the `JSON3` object.\n      \"noConflict\": function () {\n        if (!isRestored) {\n          isRestored = true;\n          root.JSON = nativeJSON;\n          root[\"JSON3\"] = previousJSON;\n          nativeJSON = previousJSON = null;\n        }\n        return JSON3;\n      }\n    }));\n\n    root.JSON = {\n      \"parse\": JSON3.parse,\n      \"stringify\": JSON3.stringify\n    };\n  }\n\n  // Export for asynchronous module loaders.\n  if (isLoader) {\n    define(function () {\n      return JSON3;\n    });\n  }\n}).call(this);\n\n}).call(this,typeof global !== \"undefined\" ? global : typeof self !== \"undefined\" ? self : typeof window !== \"undefined\" ? window : {})\n},{}],55:[function(require,module,exports){\n/**\n * lodash 3.2.0 (Custom Build) <https://lodash.com/>\n * Build: `lodash modern modularize exports=\"npm\" -o ./`\n * Copyright 2012-2015 The Dojo Foundation <http://dojofoundation.org/>\n * Based on Underscore.js 1.8.3 <http://underscorejs.org/LICENSE>\n * Copyright 2009-2015 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors\n * Available under MIT license <https://lodash.com/license>\n */\nvar baseCopy = require('lodash._basecopy'),\n    keys = require('lodash.keys');\n\n/**\n * The base implementation of `_.assign` without support for argument juggling,\n * multiple sources, and `customizer` functions.\n *\n * @private\n * @param {Object} object The destination object.\n * @param {Object} source The source object.\n * @returns {Object} Returns `object`.\n */\nfunction baseAssign(object, source) {\n  return source == null\n    ? object\n    : baseCopy(source, keys(source), object);\n}\n\nmodule.exports = baseAssign;\n\n},{\"lodash._basecopy\":56,\"lodash.keys\":63}],56:[function(require,module,exports){\n/**\n * lodash 3.0.1 (Custom Build) <https://lodash.com/>\n * Build: `lodash modern modularize exports=\"npm\" -o ./`\n * Copyright 2012-2015 The Dojo Foundation <http://dojofoundation.org/>\n * Based on Underscore.js 1.8.3 <http://underscorejs.org/LICENSE>\n * Copyright 2009-2015 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors\n * Available under MIT license <https://lodash.com/license>\n */\n\n/**\n * Copies properties of `source` to `object`.\n *\n * @private\n * @param {Object} source The object to copy properties from.\n * @param {Array} props The property names to copy.\n * @param {Object} [object={}] The object to copy properties to.\n * @returns {Object} Returns `object`.\n */\nfunction baseCopy(source, props, object) {\n  object || (object = {});\n\n  var index = -1,\n      length = props.length;\n\n  while (++index < length) {\n    var key = props[index];\n    object[key] = source[key];\n  }\n  return object;\n}\n\nmodule.exports = baseCopy;\n\n},{}],57:[function(require,module,exports){\n/**\n * lodash 3.0.3 (Custom Build) <https://lodash.com/>\n * Build: `lodash modern modularize exports=\"npm\" -o ./`\n * Copyright 2012-2015 The Dojo Foundation <http://dojofoundation.org/>\n * Based on Underscore.js 1.8.3 <http://underscorejs.org/LICENSE>\n * Copyright 2009-2015 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors\n * Available under MIT license <https://lodash.com/license>\n */\n\n/**\n * The base implementation of `_.create` without support for assigning\n * properties to the created object.\n *\n * @private\n * @param {Object} prototype The object to inherit from.\n * @returns {Object} Returns the new object.\n */\nvar baseCreate = (function() {\n  function object() {}\n  return function(prototype) {\n    if (isObject(prototype)) {\n      object.prototype = prototype;\n      var result = new object;\n      object.prototype = undefined;\n    }\n    return result || {};\n  };\n}());\n\n/**\n * Checks if `value` is the [language type](https://es5.github.io/#x8) of `Object`.\n * (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)\n *\n * @static\n * @memberOf _\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is an object, else `false`.\n * @example\n *\n * _.isObject({});\n * // => true\n *\n * _.isObject([1, 2, 3]);\n * // => true\n *\n * _.isObject(1);\n * // => false\n */\nfunction isObject(value) {\n  // Avoid a V8 JIT bug in Chrome 19-20.\n  // See https://code.google.com/p/v8/issues/detail?id=2291 for more details.\n  var type = typeof value;\n  return !!value && (type == 'object' || type == 'function');\n}\n\nmodule.exports = baseCreate;\n\n},{}],58:[function(require,module,exports){\n/**\n * lodash 3.9.1 (Custom Build) <https://lodash.com/>\n * Build: `lodash modern modularize exports=\"npm\" -o ./`\n * Copyright 2012-2015 The Dojo Foundation <http://dojofoundation.org/>\n * Based on Underscore.js 1.8.3 <http://underscorejs.org/LICENSE>\n * Copyright 2009-2015 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors\n * Available under MIT license <https://lodash.com/license>\n */\n\n/** `Object#toString` result references. */\nvar funcTag = '[object Function]';\n\n/** Used to detect host constructors (Safari > 5). */\nvar reIsHostCtor = /^\\[object .+?Constructor\\]$/;\n\n/**\n * Checks if `value` is object-like.\n *\n * @private\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is object-like, else `false`.\n */\nfunction isObjectLike(value) {\n  return !!value && typeof value == 'object';\n}\n\n/** Used for native method references. */\nvar objectProto = Object.prototype;\n\n/** Used to resolve the decompiled source of functions. */\nvar fnToString = Function.prototype.toString;\n\n/** Used to check objects for own properties. */\nvar hasOwnProperty = objectProto.hasOwnProperty;\n\n/**\n * Used to resolve the [`toStringTag`](http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring)\n * of values.\n */\nvar objToString = objectProto.toString;\n\n/** Used to detect if a method is native. */\nvar reIsNative = RegExp('^' +\n  fnToString.call(hasOwnProperty).replace(/[\\\\^$.*+?()[\\]{}|]/g, '\\\\$&')\n  .replace(/hasOwnProperty|(function).*?(?=\\\\\\()| for .+?(?=\\\\\\])/g, '$1.*?') + '$'\n);\n\n/**\n * Gets the native function at `key` of `object`.\n *\n * @private\n * @param {Object} object The object to query.\n * @param {string} key The key of the method to get.\n * @returns {*} Returns the function if it's native, else `undefined`.\n */\nfunction getNative(object, key) {\n  var value = object == null ? undefined : object[key];\n  return isNative(value) ? value : undefined;\n}\n\n/**\n * Checks if `value` is classified as a `Function` object.\n *\n * @static\n * @memberOf _\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`.\n * @example\n *\n * _.isFunction(_);\n * // => true\n *\n * _.isFunction(/abc/);\n * // => false\n */\nfunction isFunction(value) {\n  // The use of `Object#toString` avoids issues with the `typeof` operator\n  // in older versions of Chrome and Safari which return 'function' for regexes\n  // and Safari 8 equivalents which return 'object' for typed array constructors.\n  return isObject(value) && objToString.call(value) == funcTag;\n}\n\n/**\n * Checks if `value` is the [language type](https://es5.github.io/#x8) of `Object`.\n * (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)\n *\n * @static\n * @memberOf _\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is an object, else `false`.\n * @example\n *\n * _.isObject({});\n * // => true\n *\n * _.isObject([1, 2, 3]);\n * // => true\n *\n * _.isObject(1);\n * // => false\n */\nfunction isObject(value) {\n  // Avoid a V8 JIT bug in Chrome 19-20.\n  // See https://code.google.com/p/v8/issues/detail?id=2291 for more details.\n  var type = typeof value;\n  return !!value && (type == 'object' || type == 'function');\n}\n\n/**\n * Checks if `value` is a native function.\n *\n * @static\n * @memberOf _\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a native function, else `false`.\n * @example\n *\n * _.isNative(Array.prototype.push);\n * // => true\n *\n * _.isNative(_);\n * // => false\n */\nfunction isNative(value) {\n  if (value == null) {\n    return false;\n  }\n  if (isFunction(value)) {\n    return reIsNative.test(fnToString.call(value));\n  }\n  return isObjectLike(value) && reIsHostCtor.test(value);\n}\n\nmodule.exports = getNative;\n\n},{}],59:[function(require,module,exports){\n/**\n * lodash 3.0.9 (Custom Build) <https://lodash.com/>\n * Build: `lodash modern modularize exports=\"npm\" -o ./`\n * Copyright 2012-2015 The Dojo Foundation <http://dojofoundation.org/>\n * Based on Underscore.js 1.8.3 <http://underscorejs.org/LICENSE>\n * Copyright 2009-2015 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors\n * Available under MIT license <https://lodash.com/license>\n */\n\n/** Used to detect unsigned integer values. */\nvar reIsUint = /^\\d+$/;\n\n/**\n * Used as the [maximum length](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-number.max_safe_integer)\n * of an array-like value.\n */\nvar MAX_SAFE_INTEGER = 9007199254740991;\n\n/**\n * The base implementation of `_.property` without support for deep paths.\n *\n * @private\n * @param {string} key The key of the property to get.\n * @returns {Function} Returns the new function.\n */\nfunction baseProperty(key) {\n  return function(object) {\n    return object == null ? undefined : object[key];\n  };\n}\n\n/**\n * Gets the \"length\" property value of `object`.\n *\n * **Note:** This function is used to avoid a [JIT bug](https://bugs.webkit.org/show_bug.cgi?id=142792)\n * that affects Safari on at least iOS 8.1-8.3 ARM64.\n *\n * @private\n * @param {Object} object The object to query.\n * @returns {*} Returns the \"length\" value.\n */\nvar getLength = baseProperty('length');\n\n/**\n * Checks if `value` is array-like.\n *\n * @private\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is array-like, else `false`.\n */\nfunction isArrayLike(value) {\n  return value != null && isLength(getLength(value));\n}\n\n/**\n * Checks if `value` is a valid array-like index.\n *\n * @private\n * @param {*} value The value to check.\n * @param {number} [length=MAX_SAFE_INTEGER] The upper bounds of a valid index.\n * @returns {boolean} Returns `true` if `value` is a valid index, else `false`.\n */\nfunction isIndex(value, length) {\n  value = (typeof value == 'number' || reIsUint.test(value)) ? +value : -1;\n  length = length == null ? MAX_SAFE_INTEGER : length;\n  return value > -1 && value % 1 == 0 && value < length;\n}\n\n/**\n * Checks if the provided arguments are from an iteratee call.\n *\n * @private\n * @param {*} value The potential iteratee value argument.\n * @param {*} index The potential iteratee index or key argument.\n * @param {*} object The potential iteratee object argument.\n * @returns {boolean} Returns `true` if the arguments are from an iteratee call, else `false`.\n */\nfunction isIterateeCall(value, index, object) {\n  if (!isObject(object)) {\n    return false;\n  }\n  var type = typeof index;\n  if (type == 'number'\n      ? (isArrayLike(object) && isIndex(index, object.length))\n      : (type == 'string' && index in object)) {\n    var other = object[index];\n    return value === value ? (value === other) : (other !== other);\n  }\n  return false;\n}\n\n/**\n * Checks if `value` is a valid array-like length.\n *\n * **Note:** This function is based on [`ToLength`](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-tolength).\n *\n * @private\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a valid length, else `false`.\n */\nfunction isLength(value) {\n  return typeof value == 'number' && value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER;\n}\n\n/**\n * Checks if `value` is the [language type](https://es5.github.io/#x8) of `Object`.\n * (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)\n *\n * @static\n * @memberOf _\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is an object, else `false`.\n * @example\n *\n * _.isObject({});\n * // => true\n *\n * _.isObject([1, 2, 3]);\n * // => true\n *\n * _.isObject(1);\n * // => false\n */\nfunction isObject(value) {\n  // Avoid a V8 JIT bug in Chrome 19-20.\n  // See https://code.google.com/p/v8/issues/detail?id=2291 for more details.\n  var type = typeof value;\n  return !!value && (type == 'object' || type == 'function');\n}\n\nmodule.exports = isIterateeCall;\n\n},{}],60:[function(require,module,exports){\n/**\n * lodash 3.1.1 (Custom Build) <https://lodash.com/>\n * Build: `lodash modern modularize exports=\"npm\" -o ./`\n * Copyright 2012-2015 The Dojo Foundation <http://dojofoundation.org/>\n * Based on Underscore.js 1.8.3 <http://underscorejs.org/LICENSE>\n * Copyright 2009-2015 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors\n * Available under MIT license <https://lodash.com/license>\n */\nvar baseAssign = require('lodash._baseassign'),\n    baseCreate = require('lodash._basecreate'),\n    isIterateeCall = require('lodash._isiterateecall');\n\n/**\n * Creates an object that inherits from the given `prototype` object. If a\n * `properties` object is provided its own enumerable properties are assigned\n * to the created object.\n *\n * @static\n * @memberOf _\n * @category Object\n * @param {Object} prototype The object to inherit from.\n * @param {Object} [properties] The properties to assign to the object.\n * @param- {Object} [guard] Enables use as a callback for functions like `_.map`.\n * @returns {Object} Returns the new object.\n * @example\n *\n * function Shape() {\n *   this.x = 0;\n *   this.y = 0;\n * }\n *\n * function Circle() {\n *   Shape.call(this);\n * }\n *\n * Circle.prototype = _.create(Shape.prototype, {\n *   'constructor': Circle\n * });\n *\n * var circle = new Circle;\n * circle instanceof Circle;\n * // => true\n *\n * circle instanceof Shape;\n * // => true\n */\nfunction create(prototype, properties, guard) {\n  var result = baseCreate(prototype);\n  if (guard && isIterateeCall(prototype, properties, guard)) {\n    properties = undefined;\n  }\n  return properties ? baseAssign(result, properties) : result;\n}\n\nmodule.exports = create;\n\n},{\"lodash._baseassign\":55,\"lodash._basecreate\":57,\"lodash._isiterateecall\":59}],61:[function(require,module,exports){\n/**\n * lodash (Custom Build) <https://lodash.com/>\n * Build: `lodash modularize exports=\"npm\" -o ./`\n * Copyright jQuery Foundation and other contributors <https://jquery.org/>\n * Released under MIT license <https://lodash.com/license>\n * Based on Underscore.js 1.8.3 <http://underscorejs.org/LICENSE>\n * Copyright Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors\n */\n\n/** Used as references for various `Number` constants. */\nvar MAX_SAFE_INTEGER = 9007199254740991;\n\n/** `Object#toString` result references. */\nvar argsTag = '[object Arguments]',\n    funcTag = '[object Function]',\n    genTag = '[object GeneratorFunction]';\n\n/** Used for built-in method references. */\nvar objectProto = Object.prototype;\n\n/** Used to check objects for own properties. */\nvar hasOwnProperty = objectProto.hasOwnProperty;\n\n/**\n * Used to resolve the\n * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring)\n * of values.\n */\nvar objectToString = objectProto.toString;\n\n/** Built-in value references. */\nvar propertyIsEnumerable = objectProto.propertyIsEnumerable;\n\n/**\n * Checks if `value` is likely an `arguments` object.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is an `arguments` object,\n *  else `false`.\n * @example\n *\n * _.isArguments(function() { return arguments; }());\n * // => true\n *\n * _.isArguments([1, 2, 3]);\n * // => false\n */\nfunction isArguments(value) {\n  // Safari 8.1 makes `arguments.callee` enumerable in strict mode.\n  return isArrayLikeObject(value) && hasOwnProperty.call(value, 'callee') &&\n    (!propertyIsEnumerable.call(value, 'callee') || objectToString.call(value) == argsTag);\n}\n\n/**\n * Checks if `value` is array-like. A value is considered array-like if it's\n * not a function and has a `value.length` that's an integer greater than or\n * equal to `0` and less than or equal to `Number.MAX_SAFE_INTEGER`.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is array-like, else `false`.\n * @example\n *\n * _.isArrayLike([1, 2, 3]);\n * // => true\n *\n * _.isArrayLike(document.body.children);\n * // => true\n *\n * _.isArrayLike('abc');\n * // => true\n *\n * _.isArrayLike(_.noop);\n * // => false\n */\nfunction isArrayLike(value) {\n  return value != null && isLength(value.length) && !isFunction(value);\n}\n\n/**\n * This method is like `_.isArrayLike` except that it also checks if `value`\n * is an object.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is an array-like object,\n *  else `false`.\n * @example\n *\n * _.isArrayLikeObject([1, 2, 3]);\n * // => true\n *\n * _.isArrayLikeObject(document.body.children);\n * // => true\n *\n * _.isArrayLikeObject('abc');\n * // => false\n *\n * _.isArrayLikeObject(_.noop);\n * // => false\n */\nfunction isArrayLikeObject(value) {\n  return isObjectLike(value) && isArrayLike(value);\n}\n\n/**\n * Checks if `value` is classified as a `Function` object.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a function, else `false`.\n * @example\n *\n * _.isFunction(_);\n * // => true\n *\n * _.isFunction(/abc/);\n * // => false\n */\nfunction isFunction(value) {\n  // The use of `Object#toString` avoids issues with the `typeof` operator\n  // in Safari 8-9 which returns 'object' for typed array and other constructors.\n  var tag = isObject(value) ? objectToString.call(value) : '';\n  return tag == funcTag || tag == genTag;\n}\n\n/**\n * Checks if `value` is a valid array-like length.\n *\n * **Note:** This method is loosely based on\n * [`ToLength`](http://ecma-international.org/ecma-262/7.0/#sec-tolength).\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a valid length, else `false`.\n * @example\n *\n * _.isLength(3);\n * // => true\n *\n * _.isLength(Number.MIN_VALUE);\n * // => false\n *\n * _.isLength(Infinity);\n * // => false\n *\n * _.isLength('3');\n * // => false\n */\nfunction isLength(value) {\n  return typeof value == 'number' &&\n    value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER;\n}\n\n/**\n * Checks if `value` is the\n * [language type](http://www.ecma-international.org/ecma-262/7.0/#sec-ecmascript-language-types)\n * of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is an object, else `false`.\n * @example\n *\n * _.isObject({});\n * // => true\n *\n * _.isObject([1, 2, 3]);\n * // => true\n *\n * _.isObject(_.noop);\n * // => true\n *\n * _.isObject(null);\n * // => false\n */\nfunction isObject(value) {\n  var type = typeof value;\n  return !!value && (type == 'object' || type == 'function');\n}\n\n/**\n * Checks if `value` is object-like. A value is object-like if it's not `null`\n * and has a `typeof` result of \"object\".\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is object-like, else `false`.\n * @example\n *\n * _.isObjectLike({});\n * // => true\n *\n * _.isObjectLike([1, 2, 3]);\n * // => true\n *\n * _.isObjectLike(_.noop);\n * // => false\n *\n * _.isObjectLike(null);\n * // => false\n */\nfunction isObjectLike(value) {\n  return !!value && typeof value == 'object';\n}\n\nmodule.exports = isArguments;\n\n},{}],62:[function(require,module,exports){\n/**\n * lodash 3.0.4 (Custom Build) <https://lodash.com/>\n * Build: `lodash modern modularize exports=\"npm\" -o ./`\n * Copyright 2012-2015 The Dojo Foundation <http://dojofoundation.org/>\n * Based on Underscore.js 1.8.3 <http://underscorejs.org/LICENSE>\n * Copyright 2009-2015 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors\n * Available under MIT license <https://lodash.com/license>\n */\n\n/** `Object#toString` result references. */\nvar arrayTag = '[object Array]',\n    funcTag = '[object Function]';\n\n/** Used to detect host constructors (Safari > 5). */\nvar reIsHostCtor = /^\\[object .+?Constructor\\]$/;\n\n/**\n * Checks if `value` is object-like.\n *\n * @private\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is object-like, else `false`.\n */\nfunction isObjectLike(value) {\n  return !!value && typeof value == 'object';\n}\n\n/** Used for native method references. */\nvar objectProto = Object.prototype;\n\n/** Used to resolve the decompiled source of functions. */\nvar fnToString = Function.prototype.toString;\n\n/** Used to check objects for own properties. */\nvar hasOwnProperty = objectProto.hasOwnProperty;\n\n/**\n * Used to resolve the [`toStringTag`](http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring)\n * of values.\n */\nvar objToString = objectProto.toString;\n\n/** Used to detect if a method is native. */\nvar reIsNative = RegExp('^' +\n  fnToString.call(hasOwnProperty).replace(/[\\\\^$.*+?()[\\]{}|]/g, '\\\\$&')\n  .replace(/hasOwnProperty|(function).*?(?=\\\\\\()| for .+?(?=\\\\\\])/g, '$1.*?') + '$'\n);\n\n/* Native method references for those with the same name as other `lodash` methods. */\nvar nativeIsArray = getNative(Array, 'isArray');\n\n/**\n * Used as the [maximum length](http://ecma-international.org/ecma-262/6.0/#sec-number.max_safe_integer)\n * of an array-like value.\n */\nvar MAX_SAFE_INTEGER = 9007199254740991;\n\n/**\n * Gets the native function at `key` of `object`.\n *\n * @private\n * @param {Object} object The object to query.\n * @param {string} key The key of the method to get.\n * @returns {*} Returns the function if it's native, else `undefined`.\n */\nfunction getNative(object, key) {\n  var value = object == null ? undefined : object[key];\n  return isNative(value) ? value : undefined;\n}\n\n/**\n * Checks if `value` is a valid array-like length.\n *\n * **Note:** This function is based on [`ToLength`](http://ecma-international.org/ecma-262/6.0/#sec-tolength).\n *\n * @private\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a valid length, else `false`.\n */\nfunction isLength(value) {\n  return typeof value == 'number' && value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER;\n}\n\n/**\n * Checks if `value` is classified as an `Array` object.\n *\n * @static\n * @memberOf _\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`.\n * @example\n *\n * _.isArray([1, 2, 3]);\n * // => true\n *\n * _.isArray(function() { return arguments; }());\n * // => false\n */\nvar isArray = nativeIsArray || function(value) {\n  return isObjectLike(value) && isLength(value.length) && objToString.call(value) == arrayTag;\n};\n\n/**\n * Checks if `value` is classified as a `Function` object.\n *\n * @static\n * @memberOf _\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`.\n * @example\n *\n * _.isFunction(_);\n * // => true\n *\n * _.isFunction(/abc/);\n * // => false\n */\nfunction isFunction(value) {\n  // The use of `Object#toString` avoids issues with the `typeof` operator\n  // in older versions of Chrome and Safari which return 'function' for regexes\n  // and Safari 8 equivalents which return 'object' for typed array constructors.\n  return isObject(value) && objToString.call(value) == funcTag;\n}\n\n/**\n * Checks if `value` is the [language type](https://es5.github.io/#x8) of `Object`.\n * (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)\n *\n * @static\n * @memberOf _\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is an object, else `false`.\n * @example\n *\n * _.isObject({});\n * // => true\n *\n * _.isObject([1, 2, 3]);\n * // => true\n *\n * _.isObject(1);\n * // => false\n */\nfunction isObject(value) {\n  // Avoid a V8 JIT bug in Chrome 19-20.\n  // See https://code.google.com/p/v8/issues/detail?id=2291 for more details.\n  var type = typeof value;\n  return !!value && (type == 'object' || type == 'function');\n}\n\n/**\n * Checks if `value` is a native function.\n *\n * @static\n * @memberOf _\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a native function, else `false`.\n * @example\n *\n * _.isNative(Array.prototype.push);\n * // => true\n *\n * _.isNative(_);\n * // => false\n */\nfunction isNative(value) {\n  if (value == null) {\n    return false;\n  }\n  if (isFunction(value)) {\n    return reIsNative.test(fnToString.call(value));\n  }\n  return isObjectLike(value) && reIsHostCtor.test(value);\n}\n\nmodule.exports = isArray;\n\n},{}],63:[function(require,module,exports){\n/**\n * lodash 3.1.2 (Custom Build) <https://lodash.com/>\n * Build: `lodash modern modularize exports=\"npm\" -o ./`\n * Copyright 2012-2015 The Dojo Foundation <http://dojofoundation.org/>\n * Based on Underscore.js 1.8.3 <http://underscorejs.org/LICENSE>\n * Copyright 2009-2015 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors\n * Available under MIT license <https://lodash.com/license>\n */\nvar getNative = require('lodash._getnative'),\n    isArguments = require('lodash.isarguments'),\n    isArray = require('lodash.isarray');\n\n/** Used to detect unsigned integer values. */\nvar reIsUint = /^\\d+$/;\n\n/** Used for native method references. */\nvar objectProto = Object.prototype;\n\n/** Used to check objects for own properties. */\nvar hasOwnProperty = objectProto.hasOwnProperty;\n\n/* Native method references for those with the same name as other `lodash` methods. */\nvar nativeKeys = getNative(Object, 'keys');\n\n/**\n * Used as the [maximum length](http://ecma-international.org/ecma-262/6.0/#sec-number.max_safe_integer)\n * of an array-like value.\n */\nvar MAX_SAFE_INTEGER = 9007199254740991;\n\n/**\n * The base implementation of `_.property` without support for deep paths.\n *\n * @private\n * @param {string} key The key of the property to get.\n * @returns {Function} Returns the new function.\n */\nfunction baseProperty(key) {\n  return function(object) {\n    return object == null ? undefined : object[key];\n  };\n}\n\n/**\n * Gets the \"length\" property value of `object`.\n *\n * **Note:** This function is used to avoid a [JIT bug](https://bugs.webkit.org/show_bug.cgi?id=142792)\n * that affects Safari on at least iOS 8.1-8.3 ARM64.\n *\n * @private\n * @param {Object} object The object to query.\n * @returns {*} Returns the \"length\" value.\n */\nvar getLength = baseProperty('length');\n\n/**\n * Checks if `value` is array-like.\n *\n * @private\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is array-like, else `false`.\n */\nfunction isArrayLike(value) {\n  return value != null && isLength(getLength(value));\n}\n\n/**\n * Checks if `value` is a valid array-like index.\n *\n * @private\n * @param {*} value The value to check.\n * @param {number} [length=MAX_SAFE_INTEGER] The upper bounds of a valid index.\n * @returns {boolean} Returns `true` if `value` is a valid index, else `false`.\n */\nfunction isIndex(value, length) {\n  value = (typeof value == 'number' || reIsUint.test(value)) ? +value : -1;\n  length = length == null ? MAX_SAFE_INTEGER : length;\n  return value > -1 && value % 1 == 0 && value < length;\n}\n\n/**\n * Checks if `value` is a valid array-like length.\n *\n * **Note:** This function is based on [`ToLength`](http://ecma-international.org/ecma-262/6.0/#sec-tolength).\n *\n * @private\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a valid length, else `false`.\n */\nfunction isLength(value) {\n  return typeof value == 'number' && value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER;\n}\n\n/**\n * A fallback implementation of `Object.keys` which creates an array of the\n * own enumerable property names of `object`.\n *\n * @private\n * @param {Object} object The object to query.\n * @returns {Array} Returns the array of property names.\n */\nfunction shimKeys(object) {\n  var props = keysIn(object),\n      propsLength = props.length,\n      length = propsLength && object.length;\n\n  var allowIndexes = !!length && isLength(length) &&\n    (isArray(object) || isArguments(object));\n\n  var index = -1,\n      result = [];\n\n  while (++index < propsLength) {\n    var key = props[index];\n    if ((allowIndexes && isIndex(key, length)) || hasOwnProperty.call(object, key)) {\n      result.push(key);\n    }\n  }\n  return result;\n}\n\n/**\n * Checks if `value` is the [language type](https://es5.github.io/#x8) of `Object`.\n * (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)\n *\n * @static\n * @memberOf _\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is an object, else `false`.\n * @example\n *\n * _.isObject({});\n * // => true\n *\n * _.isObject([1, 2, 3]);\n * // => true\n *\n * _.isObject(1);\n * // => false\n */\nfunction isObject(value) {\n  // Avoid a V8 JIT bug in Chrome 19-20.\n  // See https://code.google.com/p/v8/issues/detail?id=2291 for more details.\n  var type = typeof value;\n  return !!value && (type == 'object' || type == 'function');\n}\n\n/**\n * Creates an array of the own enumerable property names of `object`.\n *\n * **Note:** Non-object values are coerced to objects. See the\n * [ES spec](http://ecma-international.org/ecma-262/6.0/#sec-object.keys)\n * for more details.\n *\n * @static\n * @memberOf _\n * @category Object\n * @param {Object} object The object to query.\n * @returns {Array} Returns the array of property names.\n * @example\n *\n * function Foo() {\n *   this.a = 1;\n *   this.b = 2;\n * }\n *\n * Foo.prototype.c = 3;\n *\n * _.keys(new Foo);\n * // => ['a', 'b'] (iteration order is not guaranteed)\n *\n * _.keys('hi');\n * // => ['0', '1']\n */\nvar keys = !nativeKeys ? shimKeys : function(object) {\n  var Ctor = object == null ? undefined : object.constructor;\n  if ((typeof Ctor == 'function' && Ctor.prototype === object) ||\n      (typeof object != 'function' && isArrayLike(object))) {\n    return shimKeys(object);\n  }\n  return isObject(object) ? nativeKeys(object) : [];\n};\n\n/**\n * Creates an array of the own and inherited enumerable property names of `object`.\n *\n * **Note:** Non-object values are coerced to objects.\n *\n * @static\n * @memberOf _\n * @category Object\n * @param {Object} object The object to query.\n * @returns {Array} Returns the array of property names.\n * @example\n *\n * function Foo() {\n *   this.a = 1;\n *   this.b = 2;\n * }\n *\n * Foo.prototype.c = 3;\n *\n * _.keysIn(new Foo);\n * // => ['a', 'b', 'c'] (iteration order is not guaranteed)\n */\nfunction keysIn(object) {\n  if (object == null) {\n    return [];\n  }\n  if (!isObject(object)) {\n    object = Object(object);\n  }\n  var length = object.length;\n  length = (length && isLength(length) &&\n    (isArray(object) || isArguments(object)) && length) || 0;\n\n  var Ctor = object.constructor,\n      index = -1,\n      isProto = typeof Ctor == 'function' && Ctor.prototype === object,\n      result = Array(length),\n      skipIndexes = length > 0;\n\n  while (++index < length) {\n    result[index] = (index + '');\n  }\n  for (var key in object) {\n    if (!(skipIndexes && isIndex(key, length)) &&\n        !(key == 'constructor' && (isProto || !hasOwnProperty.call(object, key)))) {\n      result.push(key);\n    }\n  }\n  return result;\n}\n\nmodule.exports = keys;\n\n},{\"lodash._getnative\":58,\"lodash.isarguments\":61,\"lodash.isarray\":62}],64:[function(require,module,exports){\n(function (process){\nvar path = require('path');\nvar fs = require('fs');\nvar _0777 = parseInt('0777', 8);\n\nmodule.exports = mkdirP.mkdirp = mkdirP.mkdirP = mkdirP;\n\nfunction mkdirP (p, opts, f, made) {\n    if (typeof opts === 'function') {\n        f = opts;\n        opts = {};\n    }\n    else if (!opts || typeof opts !== 'object') {\n        opts = { mode: opts };\n    }\n\n    var mode = opts.mode;\n    var xfs = opts.fs || fs;\n\n    if (mode === undefined) {\n        mode = _0777 & (~process.umask());\n    }\n    if (!made) made = null;\n\n    var cb = f || function () {};\n    p = path.resolve(p);\n\n    xfs.mkdir(p, mode, function (er) {\n        if (!er) {\n            made = made || p;\n            return cb(null, made);\n        }\n        switch (er.code) {\n            case 'ENOENT':\n                mkdirP(path.dirname(p), opts, function (er, made) {\n                    if (er) cb(er, made);\n                    else mkdirP(p, opts, cb, made);\n                });\n                break;\n\n            // In the case of any other error, just see if there's a dir\n            // there already.  If so, then hooray!  If not, then something\n            // is borked.\n            default:\n                xfs.stat(p, function (er2, stat) {\n                    // if the stat fails, then that's super weird.\n                    // let the original error be the failure reason.\n                    if (er2 || !stat.isDirectory()) cb(er, made)\n                    else cb(null, made);\n                });\n                break;\n        }\n    });\n}\n\nmkdirP.sync = function sync (p, opts, made) {\n    if (!opts || typeof opts !== 'object') {\n        opts = { mode: opts };\n    }\n\n    var mode = opts.mode;\n    var xfs = opts.fs || fs;\n\n    if (mode === undefined) {\n        mode = _0777 & (~process.umask());\n    }\n    if (!made) made = null;\n\n    p = path.resolve(p);\n\n    try {\n        xfs.mkdirSync(p, mode);\n        made = made || p;\n    }\n    catch (err0) {\n        switch (err0.code) {\n            case 'ENOENT' :\n                made = sync(path.dirname(p), opts, made);\n                sync(p, opts, made);\n                break;\n\n            // In the case of any other error, just see if there's a dir\n            // there already.  If so, then hooray!  If not, then something\n            // is borked.\n            default:\n                var stat;\n                try {\n                    stat = xfs.statSync(p);\n                }\n                catch (err1) {\n                    throw err0;\n                }\n                if (!stat.isDirectory()) throw err0;\n                break;\n        }\n    }\n\n    return made;\n};\n\n}).call(this,require('_process'))\n},{\"_process\":67,\"fs\":42,\"path\":42}],65:[function(require,module,exports){\nexports.endianness = function () { return 'LE' };\n\nexports.hostname = function () {\n    if (typeof location !== 'undefined') {\n        return location.hostname\n    }\n    else return '';\n};\n\nexports.loadavg = function () { return [] };\n\nexports.uptime = function () { return 0 };\n\nexports.freemem = function () {\n    return Number.MAX_VALUE;\n};\n\nexports.totalmem = function () {\n    return Number.MAX_VALUE;\n};\n\nexports.cpus = function () { return [] };\n\nexports.type = function () { return 'Browser' };\n\nexports.release = function () {\n    if (typeof navigator !== 'undefined') {\n        return navigator.appVersion;\n    }\n    return '';\n};\n\nexports.networkInterfaces\n= exports.getNetworkInterfaces\n= function () { return {} };\n\nexports.arch = function () { return 'javascript' };\n\nexports.platform = function () { return 'browser' };\n\nexports.tmpdir = exports.tmpDir = function () {\n    return '/tmp';\n};\n\nexports.EOL = '\\n';\n\n},{}],66:[function(require,module,exports){\n(function (process){\n'use strict';\n\nif (!process.version ||\n    process.version.indexOf('v0.') === 0 ||\n    process.version.indexOf('v1.') === 0 && process.version.indexOf('v1.8.') !== 0) {\n  module.exports = nextTick;\n} else {\n  module.exports = process.nextTick;\n}\n\nfunction nextTick(fn, arg1, arg2, arg3) {\n  if (typeof fn !== 'function') {\n    throw new TypeError('\"callback\" argument must be a function');\n  }\n  var len = arguments.length;\n  var args, i;\n  switch (len) {\n  case 0:\n  case 1:\n    return process.nextTick(fn);\n  case 2:\n    return process.nextTick(function afterTickOne() {\n      fn.call(null, arg1);\n    });\n  case 3:\n    return process.nextTick(function afterTickTwo() {\n      fn.call(null, arg1, arg2);\n    });\n  case 4:\n    return process.nextTick(function afterTickThree() {\n      fn.call(null, arg1, arg2, arg3);\n    });\n  default:\n    args = new Array(len - 1);\n    i = 0;\n    while (i < args.length) {\n      args[i++] = arguments[i];\n    }\n    return process.nextTick(function afterTick() {\n      fn.apply(null, args);\n    });\n  }\n}\n\n}).call(this,require('_process'))\n},{\"_process\":67}],67:[function(require,module,exports){\n// shim for using process in browser\nvar process = module.exports = {};\n\n// cached from whatever global is present so that test runners that stub it\n// don't break things.  But we need to wrap it in a try catch in case it is\n// wrapped in strict mode code which doesn't define any globals.  It's inside a\n// function because try/catches deoptimize in certain engines.\n\nvar cachedSetTimeout;\nvar cachedClearTimeout;\n\nfunction defaultSetTimout() {\n    throw new Error('setTimeout has not been defined');\n}\nfunction defaultClearTimeout () {\n    throw new Error('clearTimeout has not been defined');\n}\n(function () {\n    try {\n        if (typeof setTimeout === 'function') {\n            cachedSetTimeout = setTimeout;\n        } else {\n            cachedSetTimeout = defaultSetTimout;\n        }\n    } catch (e) {\n        cachedSetTimeout = defaultSetTimout;\n    }\n    try {\n        if (typeof clearTimeout === 'function') {\n            cachedClearTimeout = clearTimeout;\n        } else {\n            cachedClearTimeout = defaultClearTimeout;\n        }\n    } catch (e) {\n        cachedClearTimeout = defaultClearTimeout;\n    }\n} ())\nfunction runTimeout(fun) {\n    if (cachedSetTimeout === setTimeout) {\n        //normal enviroments in sane situations\n        return setTimeout(fun, 0);\n    }\n    // if setTimeout wasn't available but was latter defined\n    if ((cachedSetTimeout === defaultSetTimout || !cachedSetTimeout) && setTimeout) {\n        cachedSetTimeout = setTimeout;\n        return setTimeout(fun, 0);\n    }\n    try {\n        // when when somebody has screwed with setTimeout but no I.E. maddness\n        return cachedSetTimeout(fun, 0);\n    } catch(e){\n        try {\n            // When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally\n            return cachedSetTimeout.call(null, fun, 0);\n        } catch(e){\n            // same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error\n            return cachedSetTimeout.call(this, fun, 0);\n        }\n    }\n\n\n}\nfunction runClearTimeout(marker) {\n    if (cachedClearTimeout === clearTimeout) {\n        //normal enviroments in sane situations\n        return clearTimeout(marker);\n    }\n    // if clearTimeout wasn't available but was latter defined\n    if ((cachedClearTimeout === defaultClearTimeout || !cachedClearTimeout) && clearTimeout) {\n        cachedClearTimeout = clearTimeout;\n        return clearTimeout(marker);\n    }\n    try {\n        // when when somebody has screwed with setTimeout but no I.E. maddness\n        return cachedClearTimeout(marker);\n    } catch (e){\n        try {\n            // When we are in I.E. but the script has been evaled so I.E. doesn't  trust the global object when called normally\n            return cachedClearTimeout.call(null, marker);\n        } catch (e){\n            // same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error.\n            // Some versions of I.E. have different rules for clearTimeout vs setTimeout\n            return cachedClearTimeout.call(this, marker);\n        }\n    }\n\n\n\n}\nvar queue = [];\nvar draining = false;\nvar currentQueue;\nvar queueIndex = -1;\n\nfunction cleanUpNextTick() {\n    if (!draining || !currentQueue) {\n        return;\n    }\n    draining = false;\n    if (currentQueue.length) {\n        queue = currentQueue.concat(queue);\n    } else {\n        queueIndex = -1;\n    }\n    if (queue.length) {\n        drainQueue();\n    }\n}\n\nfunction drainQueue() {\n    if (draining) {\n        return;\n    }\n    var timeout = runTimeout(cleanUpNextTick);\n    draining = true;\n\n    var len = queue.length;\n    while(len) {\n        currentQueue = queue;\n        queue = [];\n        while (++queueIndex < len) {\n            if (currentQueue) {\n                currentQueue[queueIndex].run();\n            }\n        }\n        queueIndex = -1;\n        len = queue.length;\n    }\n    currentQueue = null;\n    draining = false;\n    runClearTimeout(timeout);\n}\n\nprocess.nextTick = function (fun) {\n    var args = new Array(arguments.length - 1);\n    if (arguments.length > 1) {\n        for (var i = 1; i < arguments.length; i++) {\n            args[i - 1] = arguments[i];\n        }\n    }\n    queue.push(new Item(fun, args));\n    if (queue.length === 1 && !draining) {\n        runTimeout(drainQueue);\n    }\n};\n\n// v8 likes predictible objects\nfunction Item(fun, array) {\n    this.fun = fun;\n    this.array = array;\n}\nItem.prototype.run = function () {\n    this.fun.apply(null, this.array);\n};\nprocess.title = 'browser';\nprocess.browser = true;\nprocess.env = {};\nprocess.argv = [];\nprocess.version = ''; // empty string to avoid regexp issues\nprocess.versions = {};\n\nfunction noop() {}\n\nprocess.on = noop;\nprocess.addListener = noop;\nprocess.once = noop;\nprocess.off = noop;\nprocess.removeListener = noop;\nprocess.removeAllListeners = noop;\nprocess.emit = noop;\n\nprocess.binding = function (name) {\n    throw new Error('process.binding is not supported');\n};\n\nprocess.cwd = function () { return '/' };\nprocess.chdir = function (dir) {\n    throw new Error('process.chdir is not supported');\n};\nprocess.umask = function() { return 0; };\n\n},{}],68:[function(require,module,exports){\nmodule.exports = require(\"./lib/_stream_duplex.js\")\n\n},{\"./lib/_stream_duplex.js\":69}],69:[function(require,module,exports){\n// a duplex stream is just a stream that is both readable and writable.\n// Since JS doesn't have multiple prototypal inheritance, this class\n// prototypally inherits from Readable, and then parasitically from\n// Writable.\n\n'use strict';\n\n/*<replacement>*/\n\nvar objectKeys = Object.keys || function (obj) {\n  var keys = [];\n  for (var key in obj) {\n    keys.push(key);\n  }return keys;\n};\n/*</replacement>*/\n\nmodule.exports = Duplex;\n\n/*<replacement>*/\nvar processNextTick = require('process-nextick-args');\n/*</replacement>*/\n\n/*<replacement>*/\nvar util = require('core-util-is');\nutil.inherits = require('inherits');\n/*</replacement>*/\n\nvar Readable = require('./_stream_readable');\nvar Writable = require('./_stream_writable');\n\nutil.inherits(Duplex, Readable);\n\nvar keys = objectKeys(Writable.prototype);\nfor (var v = 0; v < keys.length; v++) {\n  var method = keys[v];\n  if (!Duplex.prototype[method]) Duplex.prototype[method] = Writable.prototype[method];\n}\n\nfunction Duplex(options) {\n  if (!(this instanceof Duplex)) return new Duplex(options);\n\n  Readable.call(this, options);\n  Writable.call(this, options);\n\n  if (options && options.readable === false) this.readable = false;\n\n  if (options && options.writable === false) this.writable = false;\n\n  this.allowHalfOpen = true;\n  if (options && options.allowHalfOpen === false) this.allowHalfOpen = false;\n\n  this.once('end', onend);\n}\n\n// the no-half-open enforcer\nfunction onend() {\n  // if we allow half-open state, or if the writable side ended,\n  // then we're ok.\n  if (this.allowHalfOpen || this._writableState.ended) return;\n\n  // no more data can be written.\n  // But allow more writes to happen in this tick.\n  processNextTick(onEndNT, this);\n}\n\nfunction onEndNT(self) {\n  self.end();\n}\n\nfunction forEach(xs, f) {\n  for (var i = 0, l = xs.length; i < l; i++) {\n    f(xs[i], i);\n  }\n}\n},{\"./_stream_readable\":71,\"./_stream_writable\":73,\"core-util-is\":45,\"inherits\":51,\"process-nextick-args\":66}],70:[function(require,module,exports){\n// a passthrough stream.\n// basically just the most minimal sort of Transform stream.\n// Every written chunk gets output as-is.\n\n'use strict';\n\nmodule.exports = PassThrough;\n\nvar Transform = require('./_stream_transform');\n\n/*<replacement>*/\nvar util = require('core-util-is');\nutil.inherits = require('inherits');\n/*</replacement>*/\n\nutil.inherits(PassThrough, Transform);\n\nfunction PassThrough(options) {\n  if (!(this instanceof PassThrough)) return new PassThrough(options);\n\n  Transform.call(this, options);\n}\n\nPassThrough.prototype._transform = function (chunk, encoding, cb) {\n  cb(null, chunk);\n};\n},{\"./_stream_transform\":72,\"core-util-is\":45,\"inherits\":51}],71:[function(require,module,exports){\n(function (process){\n'use strict';\n\nmodule.exports = Readable;\n\n/*<replacement>*/\nvar processNextTick = require('process-nextick-args');\n/*</replacement>*/\n\n/*<replacement>*/\nvar isArray = require('isarray');\n/*</replacement>*/\n\nReadable.ReadableState = ReadableState;\n\n/*<replacement>*/\nvar EE = require('events').EventEmitter;\n\nvar EElistenerCount = function (emitter, type) {\n  return emitter.listeners(type).length;\n};\n/*</replacement>*/\n\n/*<replacement>*/\nvar Stream;\n(function () {\n  try {\n    Stream = require('st' + 'ream');\n  } catch (_) {} finally {\n    if (!Stream) Stream = require('events').EventEmitter;\n  }\n})();\n/*</replacement>*/\n\nvar Buffer = require('buffer').Buffer;\n/*<replacement>*/\nvar bufferShim = require('buffer-shims');\n/*</replacement>*/\n\n/*<replacement>*/\nvar util = require('core-util-is');\nutil.inherits = require('inherits');\n/*</replacement>*/\n\n/*<replacement>*/\nvar debugUtil = require('util');\nvar debug = void 0;\nif (debugUtil && debugUtil.debuglog) {\n  debug = debugUtil.debuglog('stream');\n} else {\n  debug = function () {};\n}\n/*</replacement>*/\n\nvar BufferList = require('./internal/streams/BufferList');\nvar StringDecoder;\n\nutil.inherits(Readable, Stream);\n\nfunction prependListener(emitter, event, fn) {\n  if (typeof emitter.prependListener === 'function') {\n    return emitter.prependListener(event, fn);\n  } else {\n    // This is a hack to make sure that our error handler is attached before any\n    // userland ones.  NEVER DO THIS. This is here only because this code needs\n    // to continue to work with older versions of Node.js that do not include\n    // the prependListener() method. The goal is to eventually remove this hack.\n    if (!emitter._events || !emitter._events[event]) emitter.on(event, fn);else if (isArray(emitter._events[event])) emitter._events[event].unshift(fn);else emitter._events[event] = [fn, emitter._events[event]];\n  }\n}\n\nvar Duplex;\nfunction ReadableState(options, stream) {\n  Duplex = Duplex || require('./_stream_duplex');\n\n  options = options || {};\n\n  // object stream flag. Used to make read(n) ignore n and to\n  // make all the buffer merging and length checks go away\n  this.objectMode = !!options.objectMode;\n\n  if (stream instanceof Duplex) this.objectMode = this.objectMode || !!options.readableObjectMode;\n\n  // the point at which it stops calling _read() to fill the buffer\n  // Note: 0 is a valid value, means \"don't call _read preemptively ever\"\n  var hwm = options.highWaterMark;\n  var defaultHwm = this.objectMode ? 16 : 16 * 1024;\n  this.highWaterMark = hwm || hwm === 0 ? hwm : defaultHwm;\n\n  // cast to ints.\n  this.highWaterMark = ~ ~this.highWaterMark;\n\n  // A linked list is used to store data chunks instead of an array because the\n  // linked list can remove elements from the beginning faster than\n  // array.shift()\n  this.buffer = new BufferList();\n  this.length = 0;\n  this.pipes = null;\n  this.pipesCount = 0;\n  this.flowing = null;\n  this.ended = false;\n  this.endEmitted = false;\n  this.reading = false;\n\n  // a flag to be able to tell if the onwrite cb is called immediately,\n  // or on a later tick.  We set this to true at first, because any\n  // actions that shouldn't happen until \"later\" should generally also\n  // not happen before the first write call.\n  this.sync = true;\n\n  // whenever we return null, then we set a flag to say\n  // that we're awaiting a 'readable' event emission.\n  this.needReadable = false;\n  this.emittedReadable = false;\n  this.readableListening = false;\n  this.resumeScheduled = false;\n\n  // Crypto is kind of old and crusty.  Historically, its default string\n  // encoding is 'binary' so we have to make this configurable.\n  // Everything else in the universe uses 'utf8', though.\n  this.defaultEncoding = options.defaultEncoding || 'utf8';\n\n  // when piping, we only care about 'readable' events that happen\n  // after read()ing all the bytes and not getting any pushback.\n  this.ranOut = false;\n\n  // the number of writers that are awaiting a drain event in .pipe()s\n  this.awaitDrain = 0;\n\n  // if true, a maybeReadMore has been scheduled\n  this.readingMore = false;\n\n  this.decoder = null;\n  this.encoding = null;\n  if (options.encoding) {\n    if (!StringDecoder) StringDecoder = require('string_decoder/').StringDecoder;\n    this.decoder = new StringDecoder(options.encoding);\n    this.encoding = options.encoding;\n  }\n}\n\nvar Duplex;\nfunction Readable(options) {\n  Duplex = Duplex || require('./_stream_duplex');\n\n  if (!(this instanceof Readable)) return new Readable(options);\n\n  this._readableState = new ReadableState(options, this);\n\n  // legacy\n  this.readable = true;\n\n  if (options && typeof options.read === 'function') this._read = options.read;\n\n  Stream.call(this);\n}\n\n// Manually shove something into the read() buffer.\n// This returns true if the highWaterMark has not been hit yet,\n// similar to how Writable.write() returns true if you should\n// write() some more.\nReadable.prototype.push = function (chunk, encoding) {\n  var state = this._readableState;\n\n  if (!state.objectMode && typeof chunk === 'string') {\n    encoding = encoding || state.defaultEncoding;\n    if (encoding !== state.encoding) {\n      chunk = bufferShim.from(chunk, encoding);\n      encoding = '';\n    }\n  }\n\n  return readableAddChunk(this, state, chunk, encoding, false);\n};\n\n// Unshift should *always* be something directly out of read()\nReadable.prototype.unshift = function (chunk) {\n  var state = this._readableState;\n  return readableAddChunk(this, state, chunk, '', true);\n};\n\nReadable.prototype.isPaused = function () {\n  return this._readableState.flowing === false;\n};\n\nfunction readableAddChunk(stream, state, chunk, encoding, addToFront) {\n  var er = chunkInvalid(state, chunk);\n  if (er) {\n    stream.emit('error', er);\n  } else if (chunk === null) {\n    state.reading = false;\n    onEofChunk(stream, state);\n  } else if (state.objectMode || chunk && chunk.length > 0) {\n    if (state.ended && !addToFront) {\n      var e = new Error('stream.push() after EOF');\n      stream.emit('error', e);\n    } else if (state.endEmitted && addToFront) {\n      var _e = new Error('stream.unshift() after end event');\n      stream.emit('error', _e);\n    } else {\n      var skipAdd;\n      if (state.decoder && !addToFront && !encoding) {\n        chunk = state.decoder.write(chunk);\n        skipAdd = !state.objectMode && chunk.length === 0;\n      }\n\n      if (!addToFront) state.reading = false;\n\n      // Don't add to the buffer if we've decoded to an empty string chunk and\n      // we're not in object mode\n      if (!skipAdd) {\n        // if we want the data now, just emit it.\n        if (state.flowing && state.length === 0 && !state.sync) {\n          stream.emit('data', chunk);\n          stream.read(0);\n        } else {\n          // update the buffer info.\n          state.length += state.objectMode ? 1 : chunk.length;\n          if (addToFront) state.buffer.unshift(chunk);else state.buffer.push(chunk);\n\n          if (state.needReadable) emitReadable(stream);\n        }\n      }\n\n      maybeReadMore(stream, state);\n    }\n  } else if (!addToFront) {\n    state.reading = false;\n  }\n\n  return needMoreData(state);\n}\n\n// if it's past the high water mark, we can push in some more.\n// Also, if we have no data yet, we can stand some\n// more bytes.  This is to work around cases where hwm=0,\n// such as the repl.  Also, if the push() triggered a\n// readable event, and the user called read(largeNumber) such that\n// needReadable was set, then we ought to push more, so that another\n// 'readable' event will be triggered.\nfunction needMoreData(state) {\n  return !state.ended && (state.needReadable || state.length < state.highWaterMark || state.length === 0);\n}\n\n// backwards compatibility.\nReadable.prototype.setEncoding = function (enc) {\n  if (!StringDecoder) StringDecoder = require('string_decoder/').StringDecoder;\n  this._readableState.decoder = new StringDecoder(enc);\n  this._readableState.encoding = enc;\n  return this;\n};\n\n// Don't raise the hwm > 8MB\nvar MAX_HWM = 0x800000;\nfunction computeNewHighWaterMark(n) {\n  if (n >= MAX_HWM) {\n    n = MAX_HWM;\n  } else {\n    // Get the next highest power of 2 to prevent increasing hwm excessively in\n    // tiny amounts\n    n--;\n    n |= n >>> 1;\n    n |= n >>> 2;\n    n |= n >>> 4;\n    n |= n >>> 8;\n    n |= n >>> 16;\n    n++;\n  }\n  return n;\n}\n\n// This function is designed to be inlinable, so please take care when making\n// changes to the function body.\nfunction howMuchToRead(n, state) {\n  if (n <= 0 || state.length === 0 && state.ended) return 0;\n  if (state.objectMode) return 1;\n  if (n !== n) {\n    // Only flow one buffer at a time\n    if (state.flowing && state.length) return state.buffer.head.data.length;else return state.length;\n  }\n  // If we're asking for more than the current hwm, then raise the hwm.\n  if (n > state.highWaterMark) state.highWaterMark = computeNewHighWaterMark(n);\n  if (n <= state.length) return n;\n  // Don't have enough\n  if (!state.ended) {\n    state.needReadable = true;\n    return 0;\n  }\n  return state.length;\n}\n\n// you can override either this method, or the async _read(n) below.\nReadable.prototype.read = function (n) {\n  debug('read', n);\n  n = parseInt(n, 10);\n  var state = this._readableState;\n  var nOrig = n;\n\n  if (n !== 0) state.emittedReadable = false;\n\n  // if we're doing read(0) to trigger a readable event, but we\n  // already have a bunch of data in the buffer, then just trigger\n  // the 'readable' event and move on.\n  if (n === 0 && state.needReadable && (state.length >= state.highWaterMark || state.ended)) {\n    debug('read: emitReadable', state.length, state.ended);\n    if (state.length === 0 && state.ended) endReadable(this);else emitReadable(this);\n    return null;\n  }\n\n  n = howMuchToRead(n, state);\n\n  // if we've ended, and we're now clear, then finish it up.\n  if (n === 0 && state.ended) {\n    if (state.length === 0) endReadable(this);\n    return null;\n  }\n\n  // All the actual chunk generation logic needs to be\n  // *below* the call to _read.  The reason is that in certain\n  // synthetic stream cases, such as passthrough streams, _read\n  // may be a completely synchronous operation which may change\n  // the state of the read buffer, providing enough data when\n  // before there was *not* enough.\n  //\n  // So, the steps are:\n  // 1. Figure out what the state of things will be after we do\n  // a read from the buffer.\n  //\n  // 2. If that resulting state will trigger a _read, then call _read.\n  // Note that this may be asynchronous, or synchronous.  Yes, it is\n  // deeply ugly to write APIs this way, but that still doesn't mean\n  // that the Readable class should behave improperly, as streams are\n  // designed to be sync/async agnostic.\n  // Take note if the _read call is sync or async (ie, if the read call\n  // has returned yet), so that we know whether or not it's safe to emit\n  // 'readable' etc.\n  //\n  // 3. Actually pull the requested chunks out of the buffer and return.\n\n  // if we need a readable event, then we need to do some reading.\n  var doRead = state.needReadable;\n  debug('need readable', doRead);\n\n  // if we currently have less than the highWaterMark, then also read some\n  if (state.length === 0 || state.length - n < state.highWaterMark) {\n    doRead = true;\n    debug('length less than watermark', doRead);\n  }\n\n  // however, if we've ended, then there's no point, and if we're already\n  // reading, then it's unnecessary.\n  if (state.ended || state.reading) {\n    doRead = false;\n    debug('reading or ended', doRead);\n  } else if (doRead) {\n    debug('do read');\n    state.reading = true;\n    state.sync = true;\n    // if the length is currently zero, then we *need* a readable event.\n    if (state.length === 0) state.needReadable = true;\n    // call internal read method\n    this._read(state.highWaterMark);\n    state.sync = false;\n    // If _read pushed data synchronously, then `reading` will be false,\n    // and we need to re-evaluate how much data we can return to the user.\n    if (!state.reading) n = howMuchToRead(nOrig, state);\n  }\n\n  var ret;\n  if (n > 0) ret = fromList(n, state);else ret = null;\n\n  if (ret === null) {\n    state.needReadable = true;\n    n = 0;\n  } else {\n    state.length -= n;\n  }\n\n  if (state.length === 0) {\n    // If we have nothing in the buffer, then we want to know\n    // as soon as we *do* get something into the buffer.\n    if (!state.ended) state.needReadable = true;\n\n    // If we tried to read() past the EOF, then emit end on the next tick.\n    if (nOrig !== n && state.ended) endReadable(this);\n  }\n\n  if (ret !== null) this.emit('data', ret);\n\n  return ret;\n};\n\nfunction chunkInvalid(state, chunk) {\n  var er = null;\n  if (!Buffer.isBuffer(chunk) && typeof chunk !== 'string' && chunk !== null && chunk !== undefined && !state.objectMode) {\n    er = new TypeError('Invalid non-string/buffer chunk');\n  }\n  return er;\n}\n\nfunction onEofChunk(stream, state) {\n  if (state.ended) return;\n  if (state.decoder) {\n    var chunk = state.decoder.end();\n    if (chunk && chunk.length) {\n      state.buffer.push(chunk);\n      state.length += state.objectMode ? 1 : chunk.length;\n    }\n  }\n  state.ended = true;\n\n  // emit 'readable' now to make sure it gets picked up.\n  emitReadable(stream);\n}\n\n// Don't emit readable right away in sync mode, because this can trigger\n// another read() call => stack overflow.  This way, it might trigger\n// a nextTick recursion warning, but that's not so bad.\nfunction emitReadable(stream) {\n  var state = stream._readableState;\n  state.needReadable = false;\n  if (!state.emittedReadable) {\n    debug('emitReadable', state.flowing);\n    state.emittedReadable = true;\n    if (state.sync) processNextTick(emitReadable_, stream);else emitReadable_(stream);\n  }\n}\n\nfunction emitReadable_(stream) {\n  debug('emit readable');\n  stream.emit('readable');\n  flow(stream);\n}\n\n// at this point, the user has presumably seen the 'readable' event,\n// and called read() to consume some data.  that may have triggered\n// in turn another _read(n) call, in which case reading = true if\n// it's in progress.\n// However, if we're not ended, or reading, and the length < hwm,\n// then go ahead and try to read some more preemptively.\nfunction maybeReadMore(stream, state) {\n  if (!state.readingMore) {\n    state.readingMore = true;\n    processNextTick(maybeReadMore_, stream, state);\n  }\n}\n\nfunction maybeReadMore_(stream, state) {\n  var len = state.length;\n  while (!state.reading && !state.flowing && !state.ended && state.length < state.highWaterMark) {\n    debug('maybeReadMore read 0');\n    stream.read(0);\n    if (len === state.length)\n      // didn't get any data, stop spinning.\n      break;else len = state.length;\n  }\n  state.readingMore = false;\n}\n\n// abstract method.  to be overridden in specific implementation classes.\n// call cb(er, data) where data is <= n in length.\n// for virtual (non-string, non-buffer) streams, \"length\" is somewhat\n// arbitrary, and perhaps not very meaningful.\nReadable.prototype._read = function (n) {\n  this.emit('error', new Error('not implemented'));\n};\n\nReadable.prototype.pipe = function (dest, pipeOpts) {\n  var src = this;\n  var state = this._readableState;\n\n  switch (state.pipesCount) {\n    case 0:\n      state.pipes = dest;\n      break;\n    case 1:\n      state.pipes = [state.pipes, dest];\n      break;\n    default:\n      state.pipes.push(dest);\n      break;\n  }\n  state.pipesCount += 1;\n  debug('pipe count=%d opts=%j', state.pipesCount, pipeOpts);\n\n  var doEnd = (!pipeOpts || pipeOpts.end !== false) && dest !== process.stdout && dest !== process.stderr;\n\n  var endFn = doEnd ? onend : cleanup;\n  if (state.endEmitted) processNextTick(endFn);else src.once('end', endFn);\n\n  dest.on('unpipe', onunpipe);\n  function onunpipe(readable) {\n    debug('onunpipe');\n    if (readable === src) {\n      cleanup();\n    }\n  }\n\n  function onend() {\n    debug('onend');\n    dest.end();\n  }\n\n  // when the dest drains, it reduces the awaitDrain counter\n  // on the source.  This would be more elegant with a .once()\n  // handler in flow(), but adding and removing repeatedly is\n  // too slow.\n  var ondrain = pipeOnDrain(src);\n  dest.on('drain', ondrain);\n\n  var cleanedUp = false;\n  function cleanup() {\n    debug('cleanup');\n    // cleanup event handlers once the pipe is broken\n    dest.removeListener('close', onclose);\n    dest.removeListener('finish', onfinish);\n    dest.removeListener('drain', ondrain);\n    dest.removeListener('error', onerror);\n    dest.removeListener('unpipe', onunpipe);\n    src.removeListener('end', onend);\n    src.removeListener('end', cleanup);\n    src.removeListener('data', ondata);\n\n    cleanedUp = true;\n\n    // if the reader is waiting for a drain event from this\n    // specific writer, then it would cause it to never start\n    // flowing again.\n    // So, if this is awaiting a drain, then we just call it now.\n    // If we don't know, then assume that we are waiting for one.\n    if (state.awaitDrain && (!dest._writableState || dest._writableState.needDrain)) ondrain();\n  }\n\n  // If the user pushes more data while we're writing to dest then we'll end up\n  // in ondata again. However, we only want to increase awaitDrain once because\n  // dest will only emit one 'drain' event for the multiple writes.\n  // => Introduce a guard on increasing awaitDrain.\n  var increasedAwaitDrain = false;\n  src.on('data', ondata);\n  function ondata(chunk) {\n    debug('ondata');\n    increasedAwaitDrain = false;\n    var ret = dest.write(chunk);\n    if (false === ret && !increasedAwaitDrain) {\n      // If the user unpiped during `dest.write()`, it is possible\n      // to get stuck in a permanently paused state if that write\n      // also returned false.\n      // => Check whether `dest` is still a piping destination.\n      if ((state.pipesCount === 1 && state.pipes === dest || state.pipesCount > 1 && indexOf(state.pipes, dest) !== -1) && !cleanedUp) {\n        debug('false write response, pause', src._readableState.awaitDrain);\n        src._readableState.awaitDrain++;\n        increasedAwaitDrain = true;\n      }\n      src.pause();\n    }\n  }\n\n  // if the dest has an error, then stop piping into it.\n  // however, don't suppress the throwing behavior for this.\n  function onerror(er) {\n    debug('onerror', er);\n    unpipe();\n    dest.removeListener('error', onerror);\n    if (EElistenerCount(dest, 'error') === 0) dest.emit('error', er);\n  }\n\n  // Make sure our error handler is attached before userland ones.\n  prependListener(dest, 'error', onerror);\n\n  // Both close and finish should trigger unpipe, but only once.\n  function onclose() {\n    dest.removeListener('finish', onfinish);\n    unpipe();\n  }\n  dest.once('close', onclose);\n  function onfinish() {\n    debug('onfinish');\n    dest.removeListener('close', onclose);\n    unpipe();\n  }\n  dest.once('finish', onfinish);\n\n  function unpipe() {\n    debug('unpipe');\n    src.unpipe(dest);\n  }\n\n  // tell the dest that it's being piped to\n  dest.emit('pipe', src);\n\n  // start the flow if it hasn't been started already.\n  if (!state.flowing) {\n    debug('pipe resume');\n    src.resume();\n  }\n\n  return dest;\n};\n\nfunction pipeOnDrain(src) {\n  return function () {\n    var state = src._readableState;\n    debug('pipeOnDrain', state.awaitDrain);\n    if (state.awaitDrain) state.awaitDrain--;\n    if (state.awaitDrain === 0 && EElistenerCount(src, 'data')) {\n      state.flowing = true;\n      flow(src);\n    }\n  };\n}\n\nReadable.prototype.unpipe = function (dest) {\n  var state = this._readableState;\n\n  // if we're not piping anywhere, then do nothing.\n  if (state.pipesCount === 0) return this;\n\n  // just one destination.  most common case.\n  if (state.pipesCount === 1) {\n    // passed in one, but it's not the right one.\n    if (dest && dest !== state.pipes) return this;\n\n    if (!dest) dest = state.pipes;\n\n    // got a match.\n    state.pipes = null;\n    state.pipesCount = 0;\n    state.flowing = false;\n    if (dest) dest.emit('unpipe', this);\n    return this;\n  }\n\n  // slow case. multiple pipe destinations.\n\n  if (!dest) {\n    // remove all.\n    var dests = state.pipes;\n    var len = state.pipesCount;\n    state.pipes = null;\n    state.pipesCount = 0;\n    state.flowing = false;\n\n    for (var _i = 0; _i < len; _i++) {\n      dests[_i].emit('unpipe', this);\n    }return this;\n  }\n\n  // try to find the right one.\n  var i = indexOf(state.pipes, dest);\n  if (i === -1) return this;\n\n  state.pipes.splice(i, 1);\n  state.pipesCount -= 1;\n  if (state.pipesCount === 1) state.pipes = state.pipes[0];\n\n  dest.emit('unpipe', this);\n\n  return this;\n};\n\n// set up data events if they are asked for\n// Ensure readable listeners eventually get something\nReadable.prototype.on = function (ev, fn) {\n  var res = Stream.prototype.on.call(this, ev, fn);\n\n  if (ev === 'data') {\n    // Start flowing on next tick if stream isn't explicitly paused\n    if (this._readableState.flowing !== false) this.resume();\n  } else if (ev === 'readable') {\n    var state = this._readableState;\n    if (!state.endEmitted && !state.readableListening) {\n      state.readableListening = state.needReadable = true;\n      state.emittedReadable = false;\n      if (!state.reading) {\n        processNextTick(nReadingNextTick, this);\n      } else if (state.length) {\n        emitReadable(this, state);\n      }\n    }\n  }\n\n  return res;\n};\nReadable.prototype.addListener = Readable.prototype.on;\n\nfunction nReadingNextTick(self) {\n  debug('readable nexttick read 0');\n  self.read(0);\n}\n\n// pause() and resume() are remnants of the legacy readable stream API\n// If the user uses them, then switch into old mode.\nReadable.prototype.resume = function () {\n  var state = this._readableState;\n  if (!state.flowing) {\n    debug('resume');\n    state.flowing = true;\n    resume(this, state);\n  }\n  return this;\n};\n\nfunction resume(stream, state) {\n  if (!state.resumeScheduled) {\n    state.resumeScheduled = true;\n    processNextTick(resume_, stream, state);\n  }\n}\n\nfunction resume_(stream, state) {\n  if (!state.reading) {\n    debug('resume read 0');\n    stream.read(0);\n  }\n\n  state.resumeScheduled = false;\n  state.awaitDrain = 0;\n  stream.emit('resume');\n  flow(stream);\n  if (state.flowing && !state.reading) stream.read(0);\n}\n\nReadable.prototype.pause = function () {\n  debug('call pause flowing=%j', this._readableState.flowing);\n  if (false !== this._readableState.flowing) {\n    debug('pause');\n    this._readableState.flowing = false;\n    this.emit('pause');\n  }\n  return this;\n};\n\nfunction flow(stream) {\n  var state = stream._readableState;\n  debug('flow', state.flowing);\n  while (state.flowing && stream.read() !== null) {}\n}\n\n// wrap an old-style stream as the async data source.\n// This is *not* part of the readable stream interface.\n// It is an ugly unfortunate mess of history.\nReadable.prototype.wrap = function (stream) {\n  var state = this._readableState;\n  var paused = false;\n\n  var self = this;\n  stream.on('end', function () {\n    debug('wrapped end');\n    if (state.decoder && !state.ended) {\n      var chunk = state.decoder.end();\n      if (chunk && chunk.length) self.push(chunk);\n    }\n\n    self.push(null);\n  });\n\n  stream.on('data', function (chunk) {\n    debug('wrapped data');\n    if (state.decoder) chunk = state.decoder.write(chunk);\n\n    // don't skip over falsy values in objectMode\n    if (state.objectMode && (chunk === null || chunk === undefined)) return;else if (!state.objectMode && (!chunk || !chunk.length)) return;\n\n    var ret = self.push(chunk);\n    if (!ret) {\n      paused = true;\n      stream.pause();\n    }\n  });\n\n  // proxy all the other methods.\n  // important when wrapping filters and duplexes.\n  for (var i in stream) {\n    if (this[i] === undefined && typeof stream[i] === 'function') {\n      this[i] = function (method) {\n        return function () {\n          return stream[method].apply(stream, arguments);\n        };\n      }(i);\n    }\n  }\n\n  // proxy certain important events.\n  var events = ['error', 'close', 'destroy', 'pause', 'resume'];\n  forEach(events, function (ev) {\n    stream.on(ev, self.emit.bind(self, ev));\n  });\n\n  // when we try to consume some more bytes, simply unpause the\n  // underlying stream.\n  self._read = function (n) {\n    debug('wrapped _read', n);\n    if (paused) {\n      paused = false;\n      stream.resume();\n    }\n  };\n\n  return self;\n};\n\n// exposed for testing purposes only.\nReadable._fromList = fromList;\n\n// Pluck off n bytes from an array of buffers.\n// Length is the combined lengths of all the buffers in the list.\n// This function is designed to be inlinable, so please take care when making\n// changes to the function body.\nfunction fromList(n, state) {\n  // nothing buffered\n  if (state.length === 0) return null;\n\n  var ret;\n  if (state.objectMode) ret = state.buffer.shift();else if (!n || n >= state.length) {\n    // read it all, truncate the list\n    if (state.decoder) ret = state.buffer.join('');else if (state.buffer.length === 1) ret = state.buffer.head.data;else ret = state.buffer.concat(state.length);\n    state.buffer.clear();\n  } else {\n    // read part of list\n    ret = fromListPartial(n, state.buffer, state.decoder);\n  }\n\n  return ret;\n}\n\n// Extracts only enough buffered data to satisfy the amount requested.\n// This function is designed to be inlinable, so please take care when making\n// changes to the function body.\nfunction fromListPartial(n, list, hasStrings) {\n  var ret;\n  if (n < list.head.data.length) {\n    // slice is the same for buffers and strings\n    ret = list.head.data.slice(0, n);\n    list.head.data = list.head.data.slice(n);\n  } else if (n === list.head.data.length) {\n    // first chunk is a perfect match\n    ret = list.shift();\n  } else {\n    // result spans more than one buffer\n    ret = hasStrings ? copyFromBufferString(n, list) : copyFromBuffer(n, list);\n  }\n  return ret;\n}\n\n// Copies a specified amount of characters from the list of buffered data\n// chunks.\n// This function is designed to be inlinable, so please take care when making\n// changes to the function body.\nfunction copyFromBufferString(n, list) {\n  var p = list.head;\n  var c = 1;\n  var ret = p.data;\n  n -= ret.length;\n  while (p = p.next) {\n    var str = p.data;\n    var nb = n > str.length ? str.length : n;\n    if (nb === str.length) ret += str;else ret += str.slice(0, n);\n    n -= nb;\n    if (n === 0) {\n      if (nb === str.length) {\n        ++c;\n        if (p.next) list.head = p.next;else list.head = list.tail = null;\n      } else {\n        list.head = p;\n        p.data = str.slice(nb);\n      }\n      break;\n    }\n    ++c;\n  }\n  list.length -= c;\n  return ret;\n}\n\n// Copies a specified amount of bytes from the list of buffered data chunks.\n// This function is designed to be inlinable, so please take care when making\n// changes to the function body.\nfunction copyFromBuffer(n, list) {\n  var ret = bufferShim.allocUnsafe(n);\n  var p = list.head;\n  var c = 1;\n  p.data.copy(ret);\n  n -= p.data.length;\n  while (p = p.next) {\n    var buf = p.data;\n    var nb = n > buf.length ? buf.length : n;\n    buf.copy(ret, ret.length - n, 0, nb);\n    n -= nb;\n    if (n === 0) {\n      if (nb === buf.length) {\n        ++c;\n        if (p.next) list.head = p.next;else list.head = list.tail = null;\n      } else {\n        list.head = p;\n        p.data = buf.slice(nb);\n      }\n      break;\n    }\n    ++c;\n  }\n  list.length -= c;\n  return ret;\n}\n\nfunction endReadable(stream) {\n  var state = stream._readableState;\n\n  // If we get here before consuming all the bytes, then that is a\n  // bug in node.  Should never happen.\n  if (state.length > 0) throw new Error('\"endReadable()\" called on non-empty stream');\n\n  if (!state.endEmitted) {\n    state.ended = true;\n    processNextTick(endReadableNT, state, stream);\n  }\n}\n\nfunction endReadableNT(state, stream) {\n  // Check that we didn't get one last unshift.\n  if (!state.endEmitted && state.length === 0) {\n    state.endEmitted = true;\n    stream.readable = false;\n    stream.emit('end');\n  }\n}\n\nfunction forEach(xs, f) {\n  for (var i = 0, l = xs.length; i < l; i++) {\n    f(xs[i], i);\n  }\n}\n\nfunction indexOf(xs, x) {\n  for (var i = 0, l = xs.length; i < l; i++) {\n    if (xs[i] === x) return i;\n  }\n  return -1;\n}\n}).call(this,require('_process'))\n},{\"./_stream_duplex\":69,\"./internal/streams/BufferList\":74,\"_process\":67,\"buffer\":44,\"buffer-shims\":43,\"core-util-is\":45,\"events\":48,\"inherits\":51,\"isarray\":53,\"process-nextick-args\":66,\"string_decoder/\":80,\"util\":40}],72:[function(require,module,exports){\n// a transform stream is a readable/writable stream where you do\n// something with the data.  Sometimes it's called a \"filter\",\n// but that's not a great name for it, since that implies a thing where\n// some bits pass through, and others are simply ignored.  (That would\n// be a valid example of a transform, of course.)\n//\n// While the output is causally related to the input, it's not a\n// necessarily symmetric or synchronous transformation.  For example,\n// a zlib stream might take multiple plain-text writes(), and then\n// emit a single compressed chunk some time in the future.\n//\n// Here's how this works:\n//\n// The Transform stream has all the aspects of the readable and writable\n// stream classes.  When you write(chunk), that calls _write(chunk,cb)\n// internally, and returns false if there's a lot of pending writes\n// buffered up.  When you call read(), that calls _read(n) until\n// there's enough pending readable data buffered up.\n//\n// In a transform stream, the written data is placed in a buffer.  When\n// _read(n) is called, it transforms the queued up data, calling the\n// buffered _write cb's as it consumes chunks.  If consuming a single\n// written chunk would result in multiple output chunks, then the first\n// outputted bit calls the readcb, and subsequent chunks just go into\n// the read buffer, and will cause it to emit 'readable' if necessary.\n//\n// This way, back-pressure is actually determined by the reading side,\n// since _read has to be called to start processing a new chunk.  However,\n// a pathological inflate type of transform can cause excessive buffering\n// here.  For example, imagine a stream where every byte of input is\n// interpreted as an integer from 0-255, and then results in that many\n// bytes of output.  Writing the 4 bytes {ff,ff,ff,ff} would result in\n// 1kb of data being output.  In this case, you could write a very small\n// amount of input, and end up with a very large amount of output.  In\n// such a pathological inflating mechanism, there'd be no way to tell\n// the system to stop doing the transform.  A single 4MB write could\n// cause the system to run out of memory.\n//\n// However, even in such a pathological case, only a single written chunk\n// would be consumed, and then the rest would wait (un-transformed) until\n// the results of the previous transformed chunk were consumed.\n\n'use strict';\n\nmodule.exports = Transform;\n\nvar Duplex = require('./_stream_duplex');\n\n/*<replacement>*/\nvar util = require('core-util-is');\nutil.inherits = require('inherits');\n/*</replacement>*/\n\nutil.inherits(Transform, Duplex);\n\nfunction TransformState(stream) {\n  this.afterTransform = function (er, data) {\n    return afterTransform(stream, er, data);\n  };\n\n  this.needTransform = false;\n  this.transforming = false;\n  this.writecb = null;\n  this.writechunk = null;\n  this.writeencoding = null;\n}\n\nfunction afterTransform(stream, er, data) {\n  var ts = stream._transformState;\n  ts.transforming = false;\n\n  var cb = ts.writecb;\n\n  if (!cb) return stream.emit('error', new Error('no writecb in Transform class'));\n\n  ts.writechunk = null;\n  ts.writecb = null;\n\n  if (data !== null && data !== undefined) stream.push(data);\n\n  cb(er);\n\n  var rs = stream._readableState;\n  rs.reading = false;\n  if (rs.needReadable || rs.length < rs.highWaterMark) {\n    stream._read(rs.highWaterMark);\n  }\n}\n\nfunction Transform(options) {\n  if (!(this instanceof Transform)) return new Transform(options);\n\n  Duplex.call(this, options);\n\n  this._transformState = new TransformState(this);\n\n  // when the writable side finishes, then flush out anything remaining.\n  var stream = this;\n\n  // start out asking for a readable event once data is transformed.\n  this._readableState.needReadable = true;\n\n  // we have implemented the _read method, and done the other things\n  // that Readable wants before the first _read call, so unset the\n  // sync guard flag.\n  this._readableState.sync = false;\n\n  if (options) {\n    if (typeof options.transform === 'function') this._transform = options.transform;\n\n    if (typeof options.flush === 'function') this._flush = options.flush;\n  }\n\n  this.once('prefinish', function () {\n    if (typeof this._flush === 'function') this._flush(function (er) {\n      done(stream, er);\n    });else done(stream);\n  });\n}\n\nTransform.prototype.push = function (chunk, encoding) {\n  this._transformState.needTransform = false;\n  return Duplex.prototype.push.call(this, chunk, encoding);\n};\n\n// This is the part where you do stuff!\n// override this function in implementation classes.\n// 'chunk' is an input chunk.\n//\n// Call `push(newChunk)` to pass along transformed output\n// to the readable side.  You may call 'push' zero or more times.\n//\n// Call `cb(err)` when you are done with this chunk.  If you pass\n// an error, then that'll put the hurt on the whole operation.  If you\n// never call cb(), then you'll never get another chunk.\nTransform.prototype._transform = function (chunk, encoding, cb) {\n  throw new Error('Not implemented');\n};\n\nTransform.prototype._write = function (chunk, encoding, cb) {\n  var ts = this._transformState;\n  ts.writecb = cb;\n  ts.writechunk = chunk;\n  ts.writeencoding = encoding;\n  if (!ts.transforming) {\n    var rs = this._readableState;\n    if (ts.needTransform || rs.needReadable || rs.length < rs.highWaterMark) this._read(rs.highWaterMark);\n  }\n};\n\n// Doesn't matter what the args are here.\n// _transform does all the work.\n// That we got here means that the readable side wants more data.\nTransform.prototype._read = function (n) {\n  var ts = this._transformState;\n\n  if (ts.writechunk !== null && ts.writecb && !ts.transforming) {\n    ts.transforming = true;\n    this._transform(ts.writechunk, ts.writeencoding, ts.afterTransform);\n  } else {\n    // mark that we need a transform, so that any data that comes in\n    // will get processed, now that we've asked for it.\n    ts.needTransform = true;\n  }\n};\n\nfunction done(stream, er) {\n  if (er) return stream.emit('error', er);\n\n  // if there's nothing in the write buffer, then that means\n  // that nothing more will ever be provided\n  var ws = stream._writableState;\n  var ts = stream._transformState;\n\n  if (ws.length) throw new Error('Calling transform done when ws.length != 0');\n\n  if (ts.transforming) throw new Error('Calling transform done when still transforming');\n\n  return stream.push(null);\n}\n},{\"./_stream_duplex\":69,\"core-util-is\":45,\"inherits\":51}],73:[function(require,module,exports){\n(function (process){\n// A bit simpler than readable streams.\n// Implement an async ._write(chunk, encoding, cb), and it'll handle all\n// the drain event emission and buffering.\n\n'use strict';\n\nmodule.exports = Writable;\n\n/*<replacement>*/\nvar processNextTick = require('process-nextick-args');\n/*</replacement>*/\n\n/*<replacement>*/\nvar asyncWrite = !process.browser && ['v0.10', 'v0.9.'].indexOf(process.version.slice(0, 5)) > -1 ? setImmediate : processNextTick;\n/*</replacement>*/\n\nWritable.WritableState = WritableState;\n\n/*<replacement>*/\nvar util = require('core-util-is');\nutil.inherits = require('inherits');\n/*</replacement>*/\n\n/*<replacement>*/\nvar internalUtil = {\n  deprecate: require('util-deprecate')\n};\n/*</replacement>*/\n\n/*<replacement>*/\nvar Stream;\n(function () {\n  try {\n    Stream = require('st' + 'ream');\n  } catch (_) {} finally {\n    if (!Stream) Stream = require('events').EventEmitter;\n  }\n})();\n/*</replacement>*/\n\nvar Buffer = require('buffer').Buffer;\n/*<replacement>*/\nvar bufferShim = require('buffer-shims');\n/*</replacement>*/\n\nutil.inherits(Writable, Stream);\n\nfunction nop() {}\n\nfunction WriteReq(chunk, encoding, cb) {\n  this.chunk = chunk;\n  this.encoding = encoding;\n  this.callback = cb;\n  this.next = null;\n}\n\nvar Duplex;\nfunction WritableState(options, stream) {\n  Duplex = Duplex || require('./_stream_duplex');\n\n  options = options || {};\n\n  // object stream flag to indicate whether or not this stream\n  // contains buffers or objects.\n  this.objectMode = !!options.objectMode;\n\n  if (stream instanceof Duplex) this.objectMode = this.objectMode || !!options.writableObjectMode;\n\n  // the point at which write() starts returning false\n  // Note: 0 is a valid value, means that we always return false if\n  // the entire buffer is not flushed immediately on write()\n  var hwm = options.highWaterMark;\n  var defaultHwm = this.objectMode ? 16 : 16 * 1024;\n  this.highWaterMark = hwm || hwm === 0 ? hwm : defaultHwm;\n\n  // cast to ints.\n  this.highWaterMark = ~ ~this.highWaterMark;\n\n  this.needDrain = false;\n  // at the start of calling end()\n  this.ending = false;\n  // when end() has been called, and returned\n  this.ended = false;\n  // when 'finish' is emitted\n  this.finished = false;\n\n  // should we decode strings into buffers before passing to _write?\n  // this is here so that some node-core streams can optimize string\n  // handling at a lower level.\n  var noDecode = options.decodeStrings === false;\n  this.decodeStrings = !noDecode;\n\n  // Crypto is kind of old and crusty.  Historically, its default string\n  // encoding is 'binary' so we have to make this configurable.\n  // Everything else in the universe uses 'utf8', though.\n  this.defaultEncoding = options.defaultEncoding || 'utf8';\n\n  // not an actual buffer we keep track of, but a measurement\n  // of how much we're waiting to get pushed to some underlying\n  // socket or file.\n  this.length = 0;\n\n  // a flag to see when we're in the middle of a write.\n  this.writing = false;\n\n  // when true all writes will be buffered until .uncork() call\n  this.corked = 0;\n\n  // a flag to be able to tell if the onwrite cb is called immediately,\n  // or on a later tick.  We set this to true at first, because any\n  // actions that shouldn't happen until \"later\" should generally also\n  // not happen before the first write call.\n  this.sync = true;\n\n  // a flag to know if we're processing previously buffered items, which\n  // may call the _write() callback in the same tick, so that we don't\n  // end up in an overlapped onwrite situation.\n  this.bufferProcessing = false;\n\n  // the callback that's passed to _write(chunk,cb)\n  this.onwrite = function (er) {\n    onwrite(stream, er);\n  };\n\n  // the callback that the user supplies to write(chunk,encoding,cb)\n  this.writecb = null;\n\n  // the amount that is being written when _write is called.\n  this.writelen = 0;\n\n  this.bufferedRequest = null;\n  this.lastBufferedRequest = null;\n\n  // number of pending user-supplied write callbacks\n  // this must be 0 before 'finish' can be emitted\n  this.pendingcb = 0;\n\n  // emit prefinish if the only thing we're waiting for is _write cbs\n  // This is relevant for synchronous Transform streams\n  this.prefinished = false;\n\n  // True if the error was already emitted and should not be thrown again\n  this.errorEmitted = false;\n\n  // count buffered requests\n  this.bufferedRequestCount = 0;\n\n  // allocate the first CorkedRequest, there is always\n  // one allocated and free to use, and we maintain at most two\n  this.corkedRequestsFree = new CorkedRequest(this);\n}\n\nWritableState.prototype.getBuffer = function writableStateGetBuffer() {\n  var current = this.bufferedRequest;\n  var out = [];\n  while (current) {\n    out.push(current);\n    current = current.next;\n  }\n  return out;\n};\n\n(function () {\n  try {\n    Object.defineProperty(WritableState.prototype, 'buffer', {\n      get: internalUtil.deprecate(function () {\n        return this.getBuffer();\n      }, '_writableState.buffer is deprecated. Use _writableState.getBuffer ' + 'instead.')\n    });\n  } catch (_) {}\n})();\n\nvar Duplex;\nfunction Writable(options) {\n  Duplex = Duplex || require('./_stream_duplex');\n\n  // Writable ctor is applied to Duplexes, though they're not\n  // instanceof Writable, they're instanceof Readable.\n  if (!(this instanceof Writable) && !(this instanceof Duplex)) return new Writable(options);\n\n  this._writableState = new WritableState(options, this);\n\n  // legacy.\n  this.writable = true;\n\n  if (options) {\n    if (typeof options.write === 'function') this._write = options.write;\n\n    if (typeof options.writev === 'function') this._writev = options.writev;\n  }\n\n  Stream.call(this);\n}\n\n// Otherwise people can pipe Writable streams, which is just wrong.\nWritable.prototype.pipe = function () {\n  this.emit('error', new Error('Cannot pipe, not readable'));\n};\n\nfunction writeAfterEnd(stream, cb) {\n  var er = new Error('write after end');\n  // TODO: defer error events consistently everywhere, not just the cb\n  stream.emit('error', er);\n  processNextTick(cb, er);\n}\n\n// If we get something that is not a buffer, string, null, or undefined,\n// and we're not in objectMode, then that's an error.\n// Otherwise stream chunks are all considered to be of length=1, and the\n// watermarks determine how many objects to keep in the buffer, rather than\n// how many bytes or characters.\nfunction validChunk(stream, state, chunk, cb) {\n  var valid = true;\n  var er = false;\n  // Always throw error if a null is written\n  // if we are not in object mode then throw\n  // if it is not a buffer, string, or undefined.\n  if (chunk === null) {\n    er = new TypeError('May not write null values to stream');\n  } else if (!Buffer.isBuffer(chunk) && typeof chunk !== 'string' && chunk !== undefined && !state.objectMode) {\n    er = new TypeError('Invalid non-string/buffer chunk');\n  }\n  if (er) {\n    stream.emit('error', er);\n    processNextTick(cb, er);\n    valid = false;\n  }\n  return valid;\n}\n\nWritable.prototype.write = function (chunk, encoding, cb) {\n  var state = this._writableState;\n  var ret = false;\n\n  if (typeof encoding === 'function') {\n    cb = encoding;\n    encoding = null;\n  }\n\n  if (Buffer.isBuffer(chunk)) encoding = 'buffer';else if (!encoding) encoding = state.defaultEncoding;\n\n  if (typeof cb !== 'function') cb = nop;\n\n  if (state.ended) writeAfterEnd(this, cb);else if (validChunk(this, state, chunk, cb)) {\n    state.pendingcb++;\n    ret = writeOrBuffer(this, state, chunk, encoding, cb);\n  }\n\n  return ret;\n};\n\nWritable.prototype.cork = function () {\n  var state = this._writableState;\n\n  state.corked++;\n};\n\nWritable.prototype.uncork = function () {\n  var state = this._writableState;\n\n  if (state.corked) {\n    state.corked--;\n\n    if (!state.writing && !state.corked && !state.finished && !state.bufferProcessing && state.bufferedRequest) clearBuffer(this, state);\n  }\n};\n\nWritable.prototype.setDefaultEncoding = function setDefaultEncoding(encoding) {\n  // node::ParseEncoding() requires lower case.\n  if (typeof encoding === 'string') encoding = encoding.toLowerCase();\n  if (!(['hex', 'utf8', 'utf-8', 'ascii', 'binary', 'base64', 'ucs2', 'ucs-2', 'utf16le', 'utf-16le', 'raw'].indexOf((encoding + '').toLowerCase()) > -1)) throw new TypeError('Unknown encoding: ' + encoding);\n  this._writableState.defaultEncoding = encoding;\n  return this;\n};\n\nfunction decodeChunk(state, chunk, encoding) {\n  if (!state.objectMode && state.decodeStrings !== false && typeof chunk === 'string') {\n    chunk = bufferShim.from(chunk, encoding);\n  }\n  return chunk;\n}\n\n// if we're already writing something, then just put this\n// in the queue, and wait our turn.  Otherwise, call _write\n// If we return false, then we need a drain event, so set that flag.\nfunction writeOrBuffer(stream, state, chunk, encoding, cb) {\n  chunk = decodeChunk(state, chunk, encoding);\n\n  if (Buffer.isBuffer(chunk)) encoding = 'buffer';\n  var len = state.objectMode ? 1 : chunk.length;\n\n  state.length += len;\n\n  var ret = state.length < state.highWaterMark;\n  // we must ensure that previous needDrain will not be reset to false.\n  if (!ret) state.needDrain = true;\n\n  if (state.writing || state.corked) {\n    var last = state.lastBufferedRequest;\n    state.lastBufferedRequest = new WriteReq(chunk, encoding, cb);\n    if (last) {\n      last.next = state.lastBufferedRequest;\n    } else {\n      state.bufferedRequest = state.lastBufferedRequest;\n    }\n    state.bufferedRequestCount += 1;\n  } else {\n    doWrite(stream, state, false, len, chunk, encoding, cb);\n  }\n\n  return ret;\n}\n\nfunction doWrite(stream, state, writev, len, chunk, encoding, cb) {\n  state.writelen = len;\n  state.writecb = cb;\n  state.writing = true;\n  state.sync = true;\n  if (writev) stream._writev(chunk, state.onwrite);else stream._write(chunk, encoding, state.onwrite);\n  state.sync = false;\n}\n\nfunction onwriteError(stream, state, sync, er, cb) {\n  --state.pendingcb;\n  if (sync) processNextTick(cb, er);else cb(er);\n\n  stream._writableState.errorEmitted = true;\n  stream.emit('error', er);\n}\n\nfunction onwriteStateUpdate(state) {\n  state.writing = false;\n  state.writecb = null;\n  state.length -= state.writelen;\n  state.writelen = 0;\n}\n\nfunction onwrite(stream, er) {\n  var state = stream._writableState;\n  var sync = state.sync;\n  var cb = state.writecb;\n\n  onwriteStateUpdate(state);\n\n  if (er) onwriteError(stream, state, sync, er, cb);else {\n    // Check if we're actually ready to finish, but don't emit yet\n    var finished = needFinish(state);\n\n    if (!finished && !state.corked && !state.bufferProcessing && state.bufferedRequest) {\n      clearBuffer(stream, state);\n    }\n\n    if (sync) {\n      /*<replacement>*/\n      asyncWrite(afterWrite, stream, state, finished, cb);\n      /*</replacement>*/\n    } else {\n        afterWrite(stream, state, finished, cb);\n      }\n  }\n}\n\nfunction afterWrite(stream, state, finished, cb) {\n  if (!finished) onwriteDrain(stream, state);\n  state.pendingcb--;\n  cb();\n  finishMaybe(stream, state);\n}\n\n// Must force callback to be called on nextTick, so that we don't\n// emit 'drain' before the write() consumer gets the 'false' return\n// value, and has a chance to attach a 'drain' listener.\nfunction onwriteDrain(stream, state) {\n  if (state.length === 0 && state.needDrain) {\n    state.needDrain = false;\n    stream.emit('drain');\n  }\n}\n\n// if there's something in the buffer waiting, then process it\nfunction clearBuffer(stream, state) {\n  state.bufferProcessing = true;\n  var entry = state.bufferedRequest;\n\n  if (stream._writev && entry && entry.next) {\n    // Fast case, write everything using _writev()\n    var l = state.bufferedRequestCount;\n    var buffer = new Array(l);\n    var holder = state.corkedRequestsFree;\n    holder.entry = entry;\n\n    var count = 0;\n    while (entry) {\n      buffer[count] = entry;\n      entry = entry.next;\n      count += 1;\n    }\n\n    doWrite(stream, state, true, state.length, buffer, '', holder.finish);\n\n    // doWrite is almost always async, defer these to save a bit of time\n    // as the hot path ends with doWrite\n    state.pendingcb++;\n    state.lastBufferedRequest = null;\n    if (holder.next) {\n      state.corkedRequestsFree = holder.next;\n      holder.next = null;\n    } else {\n      state.corkedRequestsFree = new CorkedRequest(state);\n    }\n  } else {\n    // Slow case, write chunks one-by-one\n    while (entry) {\n      var chunk = entry.chunk;\n      var encoding = entry.encoding;\n      var cb = entry.callback;\n      var len = state.objectMode ? 1 : chunk.length;\n\n      doWrite(stream, state, false, len, chunk, encoding, cb);\n      entry = entry.next;\n      // if we didn't call the onwrite immediately, then\n      // it means that we need to wait until it does.\n      // also, that means that the chunk and cb are currently\n      // being processed, so move the buffer counter past them.\n      if (state.writing) {\n        break;\n      }\n    }\n\n    if (entry === null) state.lastBufferedRequest = null;\n  }\n\n  state.bufferedRequestCount = 0;\n  state.bufferedRequest = entry;\n  state.bufferProcessing = false;\n}\n\nWritable.prototype._write = function (chunk, encoding, cb) {\n  cb(new Error('not implemented'));\n};\n\nWritable.prototype._writev = null;\n\nWritable.prototype.end = function (chunk, encoding, cb) {\n  var state = this._writableState;\n\n  if (typeof chunk === 'function') {\n    cb = chunk;\n    chunk = null;\n    encoding = null;\n  } else if (typeof encoding === 'function') {\n    cb = encoding;\n    encoding = null;\n  }\n\n  if (chunk !== null && chunk !== undefined) this.write(chunk, encoding);\n\n  // .end() fully uncorks\n  if (state.corked) {\n    state.corked = 1;\n    this.uncork();\n  }\n\n  // ignore unnecessary end() calls.\n  if (!state.ending && !state.finished) endWritable(this, state, cb);\n};\n\nfunction needFinish(state) {\n  return state.ending && state.length === 0 && state.bufferedRequest === null && !state.finished && !state.writing;\n}\n\nfunction prefinish(stream, state) {\n  if (!state.prefinished) {\n    state.prefinished = true;\n    stream.emit('prefinish');\n  }\n}\n\nfunction finishMaybe(stream, state) {\n  var need = needFinish(state);\n  if (need) {\n    if (state.pendingcb === 0) {\n      prefinish(stream, state);\n      state.finished = true;\n      stream.emit('finish');\n    } else {\n      prefinish(stream, state);\n    }\n  }\n  return need;\n}\n\nfunction endWritable(stream, state, cb) {\n  state.ending = true;\n  finishMaybe(stream, state);\n  if (cb) {\n    if (state.finished) processNextTick(cb);else stream.once('finish', cb);\n  }\n  state.ended = true;\n  stream.writable = false;\n}\n\n// It seems a linked list but it is not\n// there will be only 2 of these for each stream\nfunction CorkedRequest(state) {\n  var _this = this;\n\n  this.next = null;\n  this.entry = null;\n\n  this.finish = function (err) {\n    var entry = _this.entry;\n    _this.entry = null;\n    while (entry) {\n      var cb = entry.callback;\n      state.pendingcb--;\n      cb(err);\n      entry = entry.next;\n    }\n    if (state.corkedRequestsFree) {\n      state.corkedRequestsFree.next = _this;\n    } else {\n      state.corkedRequestsFree = _this;\n    }\n  };\n}\n}).call(this,require('_process'))\n},{\"./_stream_duplex\":69,\"_process\":67,\"buffer\":44,\"buffer-shims\":43,\"core-util-is\":45,\"events\":48,\"inherits\":51,\"process-nextick-args\":66,\"util-deprecate\":81}],74:[function(require,module,exports){\n'use strict';\n\nvar Buffer = require('buffer').Buffer;\n/*<replacement>*/\nvar bufferShim = require('buffer-shims');\n/*</replacement>*/\n\nmodule.exports = BufferList;\n\nfunction BufferList() {\n  this.head = null;\n  this.tail = null;\n  this.length = 0;\n}\n\nBufferList.prototype.push = function (v) {\n  var entry = { data: v, next: null };\n  if (this.length > 0) this.tail.next = entry;else this.head = entry;\n  this.tail = entry;\n  ++this.length;\n};\n\nBufferList.prototype.unshift = function (v) {\n  var entry = { data: v, next: this.head };\n  if (this.length === 0) this.tail = entry;\n  this.head = entry;\n  ++this.length;\n};\n\nBufferList.prototype.shift = function () {\n  if (this.length === 0) return;\n  var ret = this.head.data;\n  if (this.length === 1) this.head = this.tail = null;else this.head = this.head.next;\n  --this.length;\n  return ret;\n};\n\nBufferList.prototype.clear = function () {\n  this.head = this.tail = null;\n  this.length = 0;\n};\n\nBufferList.prototype.join = function (s) {\n  if (this.length === 0) return '';\n  var p = this.head;\n  var ret = '' + p.data;\n  while (p = p.next) {\n    ret += s + p.data;\n  }return ret;\n};\n\nBufferList.prototype.concat = function (n) {\n  if (this.length === 0) return bufferShim.alloc(0);\n  if (this.length === 1) return this.head.data;\n  var ret = bufferShim.allocUnsafe(n >>> 0);\n  var p = this.head;\n  var i = 0;\n  while (p) {\n    p.data.copy(ret, i);\n    i += p.data.length;\n    p = p.next;\n  }\n  return ret;\n};\n},{\"buffer\":44,\"buffer-shims\":43}],75:[function(require,module,exports){\nmodule.exports = require(\"./lib/_stream_passthrough.js\")\n\n},{\"./lib/_stream_passthrough.js\":70}],76:[function(require,module,exports){\n(function (process){\nvar Stream = (function (){\n  try {\n    return require('st' + 'ream'); // hack to fix a circular dependency issue when used with browserify\n  } catch(_){}\n}());\nexports = module.exports = require('./lib/_stream_readable.js');\nexports.Stream = Stream || exports;\nexports.Readable = exports;\nexports.Writable = require('./lib/_stream_writable.js');\nexports.Duplex = require('./lib/_stream_duplex.js');\nexports.Transform = require('./lib/_stream_transform.js');\nexports.PassThrough = require('./lib/_stream_passthrough.js');\n\nif (!process.browser && process.env.READABLE_STREAM === 'disable' && Stream) {\n  module.exports = Stream;\n}\n\n}).call(this,require('_process'))\n},{\"./lib/_stream_duplex.js\":69,\"./lib/_stream_passthrough.js\":70,\"./lib/_stream_readable.js\":71,\"./lib/_stream_transform.js\":72,\"./lib/_stream_writable.js\":73,\"_process\":67}],77:[function(require,module,exports){\nmodule.exports = require(\"./lib/_stream_transform.js\")\n\n},{\"./lib/_stream_transform.js\":72}],78:[function(require,module,exports){\nmodule.exports = require(\"./lib/_stream_writable.js\")\n\n},{\"./lib/_stream_writable.js\":73}],79:[function(require,module,exports){\n// Copyright Joyent, Inc. and other Node contributors.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a\n// copy of this software and associated documentation files (the\n// \"Software\"), to deal in the Software without restriction, including\n// without limitation the rights to use, copy, modify, merge, publish,\n// distribute, sublicense, and/or sell copies of the Software, and to permit\n// persons to whom the Software is furnished to do so, subject to the\n// following conditions:\n//\n// The above copyright notice and this permission notice shall be included\n// in all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS\n// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN\n// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,\n// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE\n// USE OR OTHER DEALINGS IN THE SOFTWARE.\n\nmodule.exports = Stream;\n\nvar EE = require('events').EventEmitter;\nvar inherits = require('inherits');\n\ninherits(Stream, EE);\nStream.Readable = require('readable-stream/readable.js');\nStream.Writable = require('readable-stream/writable.js');\nStream.Duplex = require('readable-stream/duplex.js');\nStream.Transform = require('readable-stream/transform.js');\nStream.PassThrough = require('readable-stream/passthrough.js');\n\n// Backwards-compat with node 0.4.x\nStream.Stream = Stream;\n\n\n\n// old-style streams.  Note that the pipe method (the only relevant\n// part of this class) is overridden in the Readable class.\n\nfunction Stream() {\n  EE.call(this);\n}\n\nStream.prototype.pipe = function(dest, options) {\n  var source = this;\n\n  function ondata(chunk) {\n    if (dest.writable) {\n      if (false === dest.write(chunk) && source.pause) {\n        source.pause();\n      }\n    }\n  }\n\n  source.on('data', ondata);\n\n  function ondrain() {\n    if (source.readable && source.resume) {\n      source.resume();\n    }\n  }\n\n  dest.on('drain', ondrain);\n\n  // If the 'end' option is not supplied, dest.end() will be called when\n  // source gets the 'end' or 'close' events.  Only dest.end() once.\n  if (!dest._isStdio && (!options || options.end !== false)) {\n    source.on('end', onend);\n    source.on('close', onclose);\n  }\n\n  var didOnEnd = false;\n  function onend() {\n    if (didOnEnd) return;\n    didOnEnd = true;\n\n    dest.end();\n  }\n\n\n  function onclose() {\n    if (didOnEnd) return;\n    didOnEnd = true;\n\n    if (typeof dest.destroy === 'function') dest.destroy();\n  }\n\n  // don't leave dangling pipes when there are errors.\n  function onerror(er) {\n    cleanup();\n    if (EE.listenerCount(this, 'error') === 0) {\n      throw er; // Unhandled stream error in pipe.\n    }\n  }\n\n  source.on('error', onerror);\n  dest.on('error', onerror);\n\n  // remove all the event listeners that were added.\n  function cleanup() {\n    source.removeListener('data', ondata);\n    dest.removeListener('drain', ondrain);\n\n    source.removeListener('end', onend);\n    source.removeListener('close', onclose);\n\n    source.removeListener('error', onerror);\n    dest.removeListener('error', onerror);\n\n    source.removeListener('end', cleanup);\n    source.removeListener('close', cleanup);\n\n    dest.removeListener('close', cleanup);\n  }\n\n  source.on('end', cleanup);\n  source.on('close', cleanup);\n\n  dest.on('close', cleanup);\n\n  dest.emit('pipe', source);\n\n  // Allow for unix-like usage: A.pipe(B).pipe(C)\n  return dest;\n};\n\n},{\"events\":48,\"inherits\":51,\"readable-stream/duplex.js\":68,\"readable-stream/passthrough.js\":75,\"readable-stream/readable.js\":76,\"readable-stream/transform.js\":77,\"readable-stream/writable.js\":78}],80:[function(require,module,exports){\n// Copyright Joyent, Inc. and other Node contributors.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a\n// copy of this software and associated documentation files (the\n// \"Software\"), to deal in the Software without restriction, including\n// without limitation the rights to use, copy, modify, merge, publish,\n// distribute, sublicense, and/or sell copies of the Software, and to permit\n// persons to whom the Software is furnished to do so, subject to the\n// following conditions:\n//\n// The above copyright notice and this permission notice shall be included\n// in all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS\n// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN\n// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,\n// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE\n// USE OR OTHER DEALINGS IN THE SOFTWARE.\n\nvar Buffer = require('buffer').Buffer;\n\nvar isBufferEncoding = Buffer.isEncoding\n  || function(encoding) {\n       switch (encoding && encoding.toLowerCase()) {\n         case 'hex': case 'utf8': case 'utf-8': case 'ascii': case 'binary': case 'base64': case 'ucs2': case 'ucs-2': case 'utf16le': case 'utf-16le': case 'raw': return true;\n         default: return false;\n       }\n     }\n\n\nfunction assertEncoding(encoding) {\n  if (encoding && !isBufferEncoding(encoding)) {\n    throw new Error('Unknown encoding: ' + encoding);\n  }\n}\n\n// StringDecoder provides an interface for efficiently splitting a series of\n// buffers into a series of JS strings without breaking apart multi-byte\n// characters. CESU-8 is handled as part of the UTF-8 encoding.\n//\n// @TODO Handling all encodings inside a single object makes it very difficult\n// to reason about this code, so it should be split up in the future.\n// @TODO There should be a utf8-strict encoding that rejects invalid UTF-8 code\n// points as used by CESU-8.\nvar StringDecoder = exports.StringDecoder = function(encoding) {\n  this.encoding = (encoding || 'utf8').toLowerCase().replace(/[-_]/, '');\n  assertEncoding(encoding);\n  switch (this.encoding) {\n    case 'utf8':\n      // CESU-8 represents each of Surrogate Pair by 3-bytes\n      this.surrogateSize = 3;\n      break;\n    case 'ucs2':\n    case 'utf16le':\n      // UTF-16 represents each of Surrogate Pair by 2-bytes\n      this.surrogateSize = 2;\n      this.detectIncompleteChar = utf16DetectIncompleteChar;\n      break;\n    case 'base64':\n      // Base-64 stores 3 bytes in 4 chars, and pads the remainder.\n      this.surrogateSize = 3;\n      this.detectIncompleteChar = base64DetectIncompleteChar;\n      break;\n    default:\n      this.write = passThroughWrite;\n      return;\n  }\n\n  // Enough space to store all bytes of a single character. UTF-8 needs 4\n  // bytes, but CESU-8 may require up to 6 (3 bytes per surrogate).\n  this.charBuffer = new Buffer(6);\n  // Number of bytes received for the current incomplete multi-byte character.\n  this.charReceived = 0;\n  // Number of bytes expected for the current incomplete multi-byte character.\n  this.charLength = 0;\n};\n\n\n// write decodes the given buffer and returns it as JS string that is\n// guaranteed to not contain any partial multi-byte characters. Any partial\n// character found at the end of the buffer is buffered up, and will be\n// returned when calling write again with the remaining bytes.\n//\n// Note: Converting a Buffer containing an orphan surrogate to a String\n// currently works, but converting a String to a Buffer (via `new Buffer`, or\n// Buffer#write) will replace incomplete surrogates with the unicode\n// replacement character. See https://codereview.chromium.org/121173009/ .\nStringDecoder.prototype.write = function(buffer) {\n  var charStr = '';\n  // if our last write ended with an incomplete multibyte character\n  while (this.charLength) {\n    // determine how many remaining bytes this buffer has to offer for this char\n    var available = (buffer.length >= this.charLength - this.charReceived) ?\n        this.charLength - this.charReceived :\n        buffer.length;\n\n    // add the new bytes to the char buffer\n    buffer.copy(this.charBuffer, this.charReceived, 0, available);\n    this.charReceived += available;\n\n    if (this.charReceived < this.charLength) {\n      // still not enough chars in this buffer? wait for more ...\n      return '';\n    }\n\n    // remove bytes belonging to the current character from the buffer\n    buffer = buffer.slice(available, buffer.length);\n\n    // get the character that was split\n    charStr = this.charBuffer.slice(0, this.charLength).toString(this.encoding);\n\n    // CESU-8: lead surrogate (D800-DBFF) is also the incomplete character\n    var charCode = charStr.charCodeAt(charStr.length - 1);\n    if (charCode >= 0xD800 && charCode <= 0xDBFF) {\n      this.charLength += this.surrogateSize;\n      charStr = '';\n      continue;\n    }\n    this.charReceived = this.charLength = 0;\n\n    // if there are no more bytes in this buffer, just emit our char\n    if (buffer.length === 0) {\n      return charStr;\n    }\n    break;\n  }\n\n  // determine and set charLength / charReceived\n  this.detectIncompleteChar(buffer);\n\n  var end = buffer.length;\n  if (this.charLength) {\n    // buffer the incomplete character bytes we got\n    buffer.copy(this.charBuffer, 0, buffer.length - this.charReceived, end);\n    end -= this.charReceived;\n  }\n\n  charStr += buffer.toString(this.encoding, 0, end);\n\n  var end = charStr.length - 1;\n  var charCode = charStr.charCodeAt(end);\n  // CESU-8: lead surrogate (D800-DBFF) is also the incomplete character\n  if (charCode >= 0xD800 && charCode <= 0xDBFF) {\n    var size = this.surrogateSize;\n    this.charLength += size;\n    this.charReceived += size;\n    this.charBuffer.copy(this.charBuffer, size, 0, size);\n    buffer.copy(this.charBuffer, 0, 0, size);\n    return charStr.substring(0, end);\n  }\n\n  // or just emit the charStr\n  return charStr;\n};\n\n// detectIncompleteChar determines if there is an incomplete UTF-8 character at\n// the end of the given buffer. If so, it sets this.charLength to the byte\n// length that character, and sets this.charReceived to the number of bytes\n// that are available for this character.\nStringDecoder.prototype.detectIncompleteChar = function(buffer) {\n  // determine how many bytes we have to check at the end of this buffer\n  var i = (buffer.length >= 3) ? 3 : buffer.length;\n\n  // Figure out if one of the last i bytes of our buffer announces an\n  // incomplete char.\n  for (; i > 0; i--) {\n    var c = buffer[buffer.length - i];\n\n    // See http://en.wikipedia.org/wiki/UTF-8#Description\n\n    // 110XXXXX\n    if (i == 1 && c >> 5 == 0x06) {\n      this.charLength = 2;\n      break;\n    }\n\n    // 1110XXXX\n    if (i <= 2 && c >> 4 == 0x0E) {\n      this.charLength = 3;\n      break;\n    }\n\n    // 11110XXX\n    if (i <= 3 && c >> 3 == 0x1E) {\n      this.charLength = 4;\n      break;\n    }\n  }\n  this.charReceived = i;\n};\n\nStringDecoder.prototype.end = function(buffer) {\n  var res = '';\n  if (buffer && buffer.length)\n    res = this.write(buffer);\n\n  if (this.charReceived) {\n    var cr = this.charReceived;\n    var buf = this.charBuffer;\n    var enc = this.encoding;\n    res += buf.slice(0, cr).toString(enc);\n  }\n\n  return res;\n};\n\nfunction passThroughWrite(buffer) {\n  return buffer.toString(this.encoding);\n}\n\nfunction utf16DetectIncompleteChar(buffer) {\n  this.charReceived = buffer.length % 2;\n  this.charLength = this.charReceived ? 2 : 0;\n}\n\nfunction base64DetectIncompleteChar(buffer) {\n  this.charReceived = buffer.length % 3;\n  this.charLength = this.charReceived ? 3 : 0;\n}\n\n},{\"buffer\":44}],81:[function(require,module,exports){\n(function (global){\n\n/**\n * Module exports.\n */\n\nmodule.exports = deprecate;\n\n/**\n * Mark that a method should not be used.\n * Returns a modified function which warns once by default.\n *\n * If `localStorage.noDeprecation = true` is set, then it is a no-op.\n *\n * If `localStorage.throwDeprecation = true` is set, then deprecated functions\n * will throw an Error when invoked.\n *\n * If `localStorage.traceDeprecation = true` is set, then deprecated functions\n * will invoke `console.trace()` instead of `console.error()`.\n *\n * @param {Function} fn - the function to deprecate\n * @param {String} msg - the string to print to the console when `fn` is invoked\n * @returns {Function} a new \"deprecated\" version of `fn`\n * @api public\n */\n\nfunction deprecate (fn, msg) {\n  if (config('noDeprecation')) {\n    return fn;\n  }\n\n  var warned = false;\n  function deprecated() {\n    if (!warned) {\n      if (config('throwDeprecation')) {\n        throw new Error(msg);\n      } else if (config('traceDeprecation')) {\n        console.trace(msg);\n      } else {\n        console.warn(msg);\n      }\n      warned = true;\n    }\n    return fn.apply(this, arguments);\n  }\n\n  return deprecated;\n}\n\n/**\n * Checks `localStorage` for boolean values for the given `name`.\n *\n * @param {String} name\n * @returns {Boolean}\n * @api private\n */\n\nfunction config (name) {\n  // accessing global.localStorage can trigger a DOMException in sandboxed iframes\n  try {\n    if (!global.localStorage) return false;\n  } catch (_) {\n    return false;\n  }\n  var val = global.localStorage[name];\n  if (null == val) return false;\n  return String(val).toLowerCase() === 'true';\n}\n\n}).call(this,typeof global !== \"undefined\" ? global : typeof self !== \"undefined\" ? self : typeof window !== \"undefined\" ? window : {})\n},{}],82:[function(require,module,exports){\narguments[4][51][0].apply(exports,arguments)\n},{\"dup\":51}],83:[function(require,module,exports){\nmodule.exports = function isBuffer(arg) {\n  return arg && typeof arg === 'object'\n    && typeof arg.copy === 'function'\n    && typeof arg.fill === 'function'\n    && typeof arg.readUInt8 === 'function';\n}\n},{}],84:[function(require,module,exports){\n(function (process,global){\n// Copyright Joyent, Inc. and other Node contributors.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a\n// copy of this software and associated documentation files (the\n// \"Software\"), to deal in the Software without restriction, including\n// without limitation the rights to use, copy, modify, merge, publish,\n// distribute, sublicense, and/or sell copies of the Software, and to permit\n// persons to whom the Software is furnished to do so, subject to the\n// following conditions:\n//\n// The above copyright notice and this permission notice shall be included\n// in all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS\n// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN\n// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,\n// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE\n// USE OR OTHER DEALINGS IN THE SOFTWARE.\n\nvar formatRegExp = /%[sdj%]/g;\nexports.format = function(f) {\n  if (!isString(f)) {\n    var objects = [];\n    for (var i = 0; i < arguments.length; i++) {\n      objects.push(inspect(arguments[i]));\n    }\n    return objects.join(' ');\n  }\n\n  var i = 1;\n  var args = arguments;\n  var len = args.length;\n  var str = String(f).replace(formatRegExp, function(x) {\n    if (x === '%%') return '%';\n    if (i >= len) return x;\n    switch (x) {\n      case '%s': return String(args[i++]);\n      case '%d': return Number(args[i++]);\n      case '%j':\n        try {\n          return JSON.stringify(args[i++]);\n        } catch (_) {\n          return '[Circular]';\n        }\n      default:\n        return x;\n    }\n  });\n  for (var x = args[i]; i < len; x = args[++i]) {\n    if (isNull(x) || !isObject(x)) {\n      str += ' ' + x;\n    } else {\n      str += ' ' + inspect(x);\n    }\n  }\n  return str;\n};\n\n\n// Mark that a method should not be used.\n// Returns a modified function which warns once by default.\n// If --no-deprecation is set, then it is a no-op.\nexports.deprecate = function(fn, msg) {\n  // Allow for deprecating things in the process of starting up.\n  if (isUndefined(global.process)) {\n    return function() {\n      return exports.deprecate(fn, msg).apply(this, arguments);\n    };\n  }\n\n  if (process.noDeprecation === true) {\n    return fn;\n  }\n\n  var warned = false;\n  function deprecated() {\n    if (!warned) {\n      if (process.throwDeprecation) {\n        throw new Error(msg);\n      } else if (process.traceDeprecation) {\n        console.trace(msg);\n      } else {\n        console.error(msg);\n      }\n      warned = true;\n    }\n    return fn.apply(this, arguments);\n  }\n\n  return deprecated;\n};\n\n\nvar debugs = {};\nvar debugEnviron;\nexports.debuglog = function(set) {\n  if (isUndefined(debugEnviron))\n    debugEnviron = process.env.NODE_DEBUG || '';\n  set = set.toUpperCase();\n  if (!debugs[set]) {\n    if (new RegExp('\\\\b' + set + '\\\\b', 'i').test(debugEnviron)) {\n      var pid = process.pid;\n      debugs[set] = function() {\n        var msg = exports.format.apply(exports, arguments);\n        console.error('%s %d: %s', set, pid, msg);\n      };\n    } else {\n      debugs[set] = function() {};\n    }\n  }\n  return debugs[set];\n};\n\n\n/**\n * Echos the value of a value. Trys to print the value out\n * in the best way possible given the different types.\n *\n * @param {Object} obj The object to print out.\n * @param {Object} opts Optional options object that alters the output.\n */\n/* legacy: obj, showHidden, depth, colors*/\nfunction inspect(obj, opts) {\n  // default options\n  var ctx = {\n    seen: [],\n    stylize: stylizeNoColor\n  };\n  // legacy...\n  if (arguments.length >= 3) ctx.depth = arguments[2];\n  if (arguments.length >= 4) ctx.colors = arguments[3];\n  if (isBoolean(opts)) {\n    // legacy...\n    ctx.showHidden = opts;\n  } else if (opts) {\n    // got an \"options\" object\n    exports._extend(ctx, opts);\n  }\n  // set default options\n  if (isUndefined(ctx.showHidden)) ctx.showHidden = false;\n  if (isUndefined(ctx.depth)) ctx.depth = 2;\n  if (isUndefined(ctx.colors)) ctx.colors = false;\n  if (isUndefined(ctx.customInspect)) ctx.customInspect = true;\n  if (ctx.colors) ctx.stylize = stylizeWithColor;\n  return formatValue(ctx, obj, ctx.depth);\n}\nexports.inspect = inspect;\n\n\n// http://en.wikipedia.org/wiki/ANSI_escape_code#graphics\ninspect.colors = {\n  'bold' : [1, 22],\n  'italic' : [3, 23],\n  'underline' : [4, 24],\n  'inverse' : [7, 27],\n  'white' : [37, 39],\n  'grey' : [90, 39],\n  'black' : [30, 39],\n  'blue' : [34, 39],\n  'cyan' : [36, 39],\n  'green' : [32, 39],\n  'magenta' : [35, 39],\n  'red' : [31, 39],\n  'yellow' : [33, 39]\n};\n\n// Don't use 'blue' not visible on cmd.exe\ninspect.styles = {\n  'special': 'cyan',\n  'number': 'yellow',\n  'boolean': 'yellow',\n  'undefined': 'grey',\n  'null': 'bold',\n  'string': 'green',\n  'date': 'magenta',\n  // \"name\": intentionally not styling\n  'regexp': 'red'\n};\n\n\nfunction stylizeWithColor(str, styleType) {\n  var style = inspect.styles[styleType];\n\n  if (style) {\n    return '\\u001b[' + inspect.colors[style][0] + 'm' + str +\n           '\\u001b[' + inspect.colors[style][1] + 'm';\n  } else {\n    return str;\n  }\n}\n\n\nfunction stylizeNoColor(str, styleType) {\n  return str;\n}\n\n\nfunction arrayToHash(array) {\n  var hash = {};\n\n  array.forEach(function(val, idx) {\n    hash[val] = true;\n  });\n\n  return hash;\n}\n\n\nfunction formatValue(ctx, value, recurseTimes) {\n  // Provide a hook for user-specified inspect functions.\n  // Check that value is an object with an inspect function on it\n  if (ctx.customInspect &&\n      value &&\n      isFunction(value.inspect) &&\n      // Filter out the util module, it's inspect function is special\n      value.inspect !== exports.inspect &&\n      // Also filter out any prototype objects using the circular check.\n      !(value.constructor && value.constructor.prototype === value)) {\n    var ret = value.inspect(recurseTimes, ctx);\n    if (!isString(ret)) {\n      ret = formatValue(ctx, ret, recurseTimes);\n    }\n    return ret;\n  }\n\n  // Primitive types cannot have properties\n  var primitive = formatPrimitive(ctx, value);\n  if (primitive) {\n    return primitive;\n  }\n\n  // Look up the keys of the object.\n  var keys = Object.keys(value);\n  var visibleKeys = arrayToHash(keys);\n\n  if (ctx.showHidden) {\n    keys = Object.getOwnPropertyNames(value);\n  }\n\n  // IE doesn't make error fields non-enumerable\n  // http://msdn.microsoft.com/en-us/library/ie/dww52sbt(v=vs.94).aspx\n  if (isError(value)\n      && (keys.indexOf('message') >= 0 || keys.indexOf('description') >= 0)) {\n    return formatError(value);\n  }\n\n  // Some type of object without properties can be shortcutted.\n  if (keys.length === 0) {\n    if (isFunction(value)) {\n      var name = value.name ? ': ' + value.name : '';\n      return ctx.stylize('[Function' + name + ']', 'special');\n    }\n    if (isRegExp(value)) {\n      return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp');\n    }\n    if (isDate(value)) {\n      return ctx.stylize(Date.prototype.toString.call(value), 'date');\n    }\n    if (isError(value)) {\n      return formatError(value);\n    }\n  }\n\n  var base = '', array = false, braces = ['{', '}'];\n\n  // Make Array say that they are Array\n  if (isArray(value)) {\n    array = true;\n    braces = ['[', ']'];\n  }\n\n  // Make functions say that they are functions\n  if (isFunction(value)) {\n    var n = value.name ? ': ' + value.name : '';\n    base = ' [Function' + n + ']';\n  }\n\n  // Make RegExps say that they are RegExps\n  if (isRegExp(value)) {\n    base = ' ' + RegExp.prototype.toString.call(value);\n  }\n\n  // Make dates with properties first say the date\n  if (isDate(value)) {\n    base = ' ' + Date.prototype.toUTCString.call(value);\n  }\n\n  // Make error with message first say the error\n  if (isError(value)) {\n    base = ' ' + formatError(value);\n  }\n\n  if (keys.length === 0 && (!array || value.length == 0)) {\n    return braces[0] + base + braces[1];\n  }\n\n  if (recurseTimes < 0) {\n    if (isRegExp(value)) {\n      return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp');\n    } else {\n      return ctx.stylize('[Object]', 'special');\n    }\n  }\n\n  ctx.seen.push(value);\n\n  var output;\n  if (array) {\n    output = formatArray(ctx, value, recurseTimes, visibleKeys, keys);\n  } else {\n    output = keys.map(function(key) {\n      return formatProperty(ctx, value, recurseTimes, visibleKeys, key, array);\n    });\n  }\n\n  ctx.seen.pop();\n\n  return reduceToSingleString(output, base, braces);\n}\n\n\nfunction formatPrimitive(ctx, value) {\n  if (isUndefined(value))\n    return ctx.stylize('undefined', 'undefined');\n  if (isString(value)) {\n    var simple = '\\'' + JSON.stringify(value).replace(/^\"|\"$/g, '')\n                                             .replace(/'/g, \"\\\\'\")\n                                             .replace(/\\\\\"/g, '\"') + '\\'';\n    return ctx.stylize(simple, 'string');\n  }\n  if (isNumber(value))\n    return ctx.stylize('' + value, 'number');\n  if (isBoolean(value))\n    return ctx.stylize('' + value, 'boolean');\n  // For some reason typeof null is \"object\", so special case here.\n  if (isNull(value))\n    return ctx.stylize('null', 'null');\n}\n\n\nfunction formatError(value) {\n  return '[' + Error.prototype.toString.call(value) + ']';\n}\n\n\nfunction formatArray(ctx, value, recurseTimes, visibleKeys, keys) {\n  var output = [];\n  for (var i = 0, l = value.length; i < l; ++i) {\n    if (hasOwnProperty(value, String(i))) {\n      output.push(formatProperty(ctx, value, recurseTimes, visibleKeys,\n          String(i), true));\n    } else {\n      output.push('');\n    }\n  }\n  keys.forEach(function(key) {\n    if (!key.match(/^\\d+$/)) {\n      output.push(formatProperty(ctx, value, recurseTimes, visibleKeys,\n          key, true));\n    }\n  });\n  return output;\n}\n\n\nfunction formatProperty(ctx, value, recurseTimes, visibleKeys, key, array) {\n  var name, str, desc;\n  desc = Object.getOwnPropertyDescriptor(value, key) || { value: value[key] };\n  if (desc.get) {\n    if (desc.set) {\n      str = ctx.stylize('[Getter/Setter]', 'special');\n    } else {\n      str = ctx.stylize('[Getter]', 'special');\n    }\n  } else {\n    if (desc.set) {\n      str = ctx.stylize('[Setter]', 'special');\n    }\n  }\n  if (!hasOwnProperty(visibleKeys, key)) {\n    name = '[' + key + ']';\n  }\n  if (!str) {\n    if (ctx.seen.indexOf(desc.value) < 0) {\n      if (isNull(recurseTimes)) {\n        str = formatValue(ctx, desc.value, null);\n      } else {\n        str = formatValue(ctx, desc.value, recurseTimes - 1);\n      }\n      if (str.indexOf('\\n') > -1) {\n        if (array) {\n          str = str.split('\\n').map(function(line) {\n            return '  ' + line;\n          }).join('\\n').substr(2);\n        } else {\n          str = '\\n' + str.split('\\n').map(function(line) {\n            return '   ' + line;\n          }).join('\\n');\n        }\n      }\n    } else {\n      str = ctx.stylize('[Circular]', 'special');\n    }\n  }\n  if (isUndefined(name)) {\n    if (array && key.match(/^\\d+$/)) {\n      return str;\n    }\n    name = JSON.stringify('' + key);\n    if (name.match(/^\"([a-zA-Z_][a-zA-Z_0-9]*)\"$/)) {\n      name = name.substr(1, name.length - 2);\n      name = ctx.stylize(name, 'name');\n    } else {\n      name = name.replace(/'/g, \"\\\\'\")\n                 .replace(/\\\\\"/g, '\"')\n                 .replace(/(^\"|\"$)/g, \"'\");\n      name = ctx.stylize(name, 'string');\n    }\n  }\n\n  return name + ': ' + str;\n}\n\n\nfunction reduceToSingleString(output, base, braces) {\n  var numLinesEst = 0;\n  var length = output.reduce(function(prev, cur) {\n    numLinesEst++;\n    if (cur.indexOf('\\n') >= 0) numLinesEst++;\n    return prev + cur.replace(/\\u001b\\[\\d\\d?m/g, '').length + 1;\n  }, 0);\n\n  if (length > 60) {\n    return braces[0] +\n           (base === '' ? '' : base + '\\n ') +\n           ' ' +\n           output.join(',\\n  ') +\n           ' ' +\n           braces[1];\n  }\n\n  return braces[0] + base + ' ' + output.join(', ') + ' ' + braces[1];\n}\n\n\n// NOTE: These type checking functions intentionally don't use `instanceof`\n// because it is fragile and can be easily faked with `Object.create()`.\nfunction isArray(ar) {\n  return Array.isArray(ar);\n}\nexports.isArray = isArray;\n\nfunction isBoolean(arg) {\n  return typeof arg === 'boolean';\n}\nexports.isBoolean = isBoolean;\n\nfunction isNull(arg) {\n  return arg === null;\n}\nexports.isNull = isNull;\n\nfunction isNullOrUndefined(arg) {\n  return arg == null;\n}\nexports.isNullOrUndefined = isNullOrUndefined;\n\nfunction isNumber(arg) {\n  return typeof arg === 'number';\n}\nexports.isNumber = isNumber;\n\nfunction isString(arg) {\n  return typeof arg === 'string';\n}\nexports.isString = isString;\n\nfunction isSymbol(arg) {\n  return typeof arg === 'symbol';\n}\nexports.isSymbol = isSymbol;\n\nfunction isUndefined(arg) {\n  return arg === void 0;\n}\nexports.isUndefined = isUndefined;\n\nfunction isRegExp(re) {\n  return isObject(re) && objectToString(re) === '[object RegExp]';\n}\nexports.isRegExp = isRegExp;\n\nfunction isObject(arg) {\n  return typeof arg === 'object' && arg !== null;\n}\nexports.isObject = isObject;\n\nfunction isDate(d) {\n  return isObject(d) && objectToString(d) === '[object Date]';\n}\nexports.isDate = isDate;\n\nfunction isError(e) {\n  return isObject(e) &&\n      (objectToString(e) === '[object Error]' || e instanceof Error);\n}\nexports.isError = isError;\n\nfunction isFunction(arg) {\n  return typeof arg === 'function';\n}\nexports.isFunction = isFunction;\n\nfunction isPrimitive(arg) {\n  return arg === null ||\n         typeof arg === 'boolean' ||\n         typeof arg === 'number' ||\n         typeof arg === 'string' ||\n         typeof arg === 'symbol' ||  // ES6 symbol\n         typeof arg === 'undefined';\n}\nexports.isPrimitive = isPrimitive;\n\nexports.isBuffer = require('./support/isBuffer');\n\nfunction objectToString(o) {\n  return Object.prototype.toString.call(o);\n}\n\n\nfunction pad(n) {\n  return n < 10 ? '0' + n.toString(10) : n.toString(10);\n}\n\n\nvar months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep',\n              'Oct', 'Nov', 'Dec'];\n\n// 26 Feb 16:19:34\nfunction timestamp() {\n  var d = new Date();\n  var time = [pad(d.getHours()),\n              pad(d.getMinutes()),\n              pad(d.getSeconds())].join(':');\n  return [d.getDate(), months[d.getMonth()], time].join(' ');\n}\n\n\n// log is just a thin wrapper to console.log that prepends a timestamp\nexports.log = function() {\n  console.log('%s - %s', timestamp(), exports.format.apply(exports, arguments));\n};\n\n\n/**\n * Inherit the prototype methods from one constructor into another.\n *\n * The Function.prototype.inherits from lang.js rewritten as a standalone\n * function (not on Function.prototype). NOTE: If this file is to be loaded\n * during bootstrapping this function needs to be rewritten using some native\n * functions as prototype setup using normal JavaScript does not work as\n * expected during bootstrapping (see mirror.js in r114903).\n *\n * @param {function} ctor Constructor function which needs to inherit the\n *     prototype.\n * @param {function} superCtor Constructor function to inherit prototype from.\n */\nexports.inherits = require('inherits');\n\nexports._extend = function(origin, add) {\n  // Don't do anything if add isn't an object\n  if (!add || !isObject(add)) return origin;\n\n  var keys = Object.keys(add);\n  var i = keys.length;\n  while (i--) {\n    origin[keys[i]] = add[keys[i]];\n  }\n  return origin;\n};\n\nfunction hasOwnProperty(obj, prop) {\n  return Object.prototype.hasOwnProperty.call(obj, prop);\n}\n\n}).call(this,require('_process'),typeof global !== \"undefined\" ? global : typeof self !== \"undefined\" ? self : typeof window !== \"undefined\" ? window : {})\n},{\"./support/isBuffer\":83,\"_process\":67,\"inherits\":82}]},{},[1]);\n"
  },
  {
    "path": "app_frontend/static/plugin/JavaScript-Templates/.gitignore",
    "content": ".DS_Store\nnode_modules\n"
  },
  {
    "path": "app_frontend/static/plugin/JavaScript-Templates/.travis.yml",
    "content": "language: node_js\nnode_js:\n  - \"stable\"\n"
  },
  {
    "path": "app_frontend/static/plugin/JavaScript-Templates/README.md",
    "content": "# JavaScript Templates\n\n## Demo\n[JavaScript Templates Demo](https://blueimp.github.io/JavaScript-Templates/)\n\n## Description\n1KB lightweight, fast & powerful JavaScript templating engine with zero\ndependencies. Compatible with server-side environments like Node.js, module\nloaders like RequireJS, Browserify or webpack and all web browsers.\n\n## Usage\n\n### Client-side\nInclude the (minified) JavaScript Templates script in your HTML markup:\n\n```html\n<script src=\"js/tmpl.min.js\"></script>\n```\n\nAdd a script section with type **\"text/x-tmpl\"**, a unique **id** property and\nyour template definition as content:\n\n```html\n<script type=\"text/x-tmpl\" id=\"tmpl-demo\">\n<h3>{%=o.title%}</h3>\n<p>Released under the\n<a href=\"{%=o.license.url%}\">{%=o.license.name%}</a>.</p>\n<h4>Features</h4>\n<ul>\n{% for (var i=0; i<o.features.length; i++) { %}\n    <li>{%=o.features[i]%}</li>\n{% } %}\n</ul>\n</script>\n```\n\n**\"o\"** (the lowercase letter) is a reference to the data parameter of the\ntemplate function (see the API section on how to modify this identifier).\n\nIn your application code, create a JavaScript object to use as data for the\ntemplate:\n\n```js\nvar data = {\n    \"title\": \"JavaScript Templates\",\n    \"license\": {\n        \"name\": \"MIT license\",\n        \"url\": \"http://www.opensource.org/licenses/MIT\"\n    },\n    \"features\": [\n        \"lightweight & fast\",\n        \"powerful\",\n        \"zero dependencies\"\n    ]\n};\n```\n\nIn a real application, this data could be the result of retrieving a\n[JSON](http://json.org/) resource.\n\nRender the result by calling the **tmpl()** method with the id of the template\nand the data object as arguments:\n\n```js\ndocument.getElementById(\"result\").innerHTML = tmpl(\"tmpl-demo\", data);\n```\n\n### Server-side\n\nThe following is an example how to use the JavaScript Templates engine on the\nserver-side with [node.js](http://nodejs.org/).\n\nCreate a new directory and add the **tmpl.js** file. Or alternatively, install\nthe **blueimp-tmpl** package with [npm](https://www.npmjs.org/):\n\n```sh\nnpm install blueimp-tmpl\n```\n\nAdd a file **template.html** with the following content:\n\n```html\n<!DOCTYPE HTML>\n<title>{%=o.title%}</title>\n<h3><a href=\"{%=o.url%}\">{%=o.title%}</a></h3>\n<h4>Features</h4>\n<ul>\n{% for (var i=0; i<o.features.length; i++) { %}\n    <li>{%=o.features[i]%}</li>\n{% } %}\n</ul>\n```\n\nAdd a file **server.js** with the following content:\n\n```js\nrequire(\"http\").createServer(function (req, res) {\n    var fs = require(\"fs\"),\n        // The tmpl module exports the tmpl() function:\n        tmpl = require(\"./tmpl\"),\n        // Use the following version if you installed the package with npm:\n        // tmpl = require(\"blueimp-tmpl\"),\n        // Sample data:\n        data = {\n            \"title\": \"JavaScript Templates\",\n            \"url\": \"https://github.com/blueimp/JavaScript-Templates\",\n            \"features\": [\n                \"lightweight & fast\",\n                \"powerful\",\n                \"zero dependencies\"\n            ]\n        };\n    // Override the template loading method:\n    tmpl.load = function (id) {\n        var filename = id + \".html\";\n        console.log(\"Loading \" + filename);\n        return fs.readFileSync(filename, \"utf8\");\n    };\n    res.writeHead(200, {\"Content-Type\": \"text/x-tmpl\"});\n    // Render the content:\n    res.end(tmpl(\"template\", data));\n}).listen(8080, \"localhost\");\nconsole.log(\"Server running at http://localhost:8080/\");\n```\n\nRun the application with the following command:\n\n```sh\nnode server.js\n```\n\n## Requirements\nThe JavaScript Templates script has zero dependencies.\n\n## API\n\n### tmpl() function\nThe **tmpl()** function is added to the global **window** object and can be\ncalled as global function:\n\n```js\nvar result = tmpl(\"tmpl-demo\", data);\n```\n\nThe **tmpl()** function can be called with the id of a template, or with a\ntemplate string:\n\n```js\nvar result = tmpl(\"<h3>{%=o.title%}</h3>\", data);\n```\n\nIf called without second argument, **tmpl()** returns a reusable template\nfunction:\n\n```js\nvar func = tmpl(\"<h3>{%=o.title%}</h3>\");\ndocument.getElementById(\"result\").innerHTML = func(data);\n```\n\n### Templates cache\nTemplates loaded by id are cached in the map **tmpl.cache**:\n\n```js\nvar func = tmpl(\"tmpl-demo\"), // Loads and parses the template\n    cached = typeof tmpl.cache[\"tmpl-demo\"] === \"function\", // true\n    result = tmpl(\"tmpl-demo\", data); // Uses cached template function\n\ntmpl.cache[\"tmpl-demo\"] = null;\nresult = tmpl(\"tmpl-demo\", data); // Loads and parses the template again\n```\n\n### Output encoding\nThe method **tmpl.encode** is used to escape HTML special characters in the\ntemplate output:\n\n```js\nvar output = tmpl.encode(\"<>&\\\"'\\x00\"); // Renders \"&lt;&gt;&amp;&quot;&#39;\"\n```\n\n**tmpl.encode** makes use of the regular expression **tmpl.encReg** and the\nencoding map **tmpl.encMap** to match and replace special characters, which can\nbe modified to change the behavior of the output encoding.  \nStrings matched by the regular expression, but not found in the encoding map are\nremoved from the output. This allows for example to automatically trim input\nvalues (removing whitespace from the start and end of the string):\n\n```js\ntmpl.encReg = /(^\\s+)|(\\s+$)|[<>&\"'\\x00]/g;\nvar output = tmpl.encode(\"    Banana!    \"); // Renders \"Banana\" (without whitespace)\n```\n\n### Local helper variables\nThe local variables available inside the templates are the following:\n\n* **o**: The data object given as parameter to the template function\n(see the next section on how to modify the parameter name).\n* **tmpl**: A reference to the **tmpl** function object.\n* **_s**: The string for the rendered result content.\n* **_e**: A reference to the **tmpl.encode** method.\n* **print**: Helper function to add content to the rendered result string.\n* **include**: Helper function to include the return value of a different\ntemplate in the result.\n\nTo introduce additional local helper variables, the string **tmpl.helper** can\nbe extended. The following adds a convenience function for *console.log* and a\nstreaming function, that streams the template rendering result back to the\ncallback argument\n(note the comma at the beginning of each variable declaration):\n\n```js\ntmpl.helper += \",log=function(){console.log.apply(console, arguments)}\" +\n    \",st='',stream=function(cb){var l=st.length;st=_s;cb( _s.slice(l));}\";\n```\n\nThose new helper functions could be used to stream the template contents to the\nconsole output:\n\n```html\n<script type=\"text/x-tmpl\" id=\"tmpl-demo\">\n<h3>{%=o.title%}</h3>\n{% stream(log); %}\n<p>Released under the\n<a href=\"{%=o.license.url%}\">{%=o.license.name%}</a>.</p>\n{% stream(log); %}\n<h4>Features</h4>\n<ul>\n{% stream(log); %}\n{% for (var i=0; i<o.features.length; i++) { %}\n    <li>{%=o.features[i]%}</li>\n    {% stream(log); %}\n{% } %}\n</ul>\n{% stream(log); %}\n</script>\n```\n\n### Template function argument\nThe generated template functions accept one argument, which is the data object\ngiven to the **tmpl(id, data)** function. This argument is available inside the\ntemplate definitions as parameter **o** (the lowercase letter).\n\nThe argument name can be modified by overriding **tmpl.arg**:\n\n```js\ntmpl.arg = \"p\";\n\n// Renders \"<h3>JavaScript Templates</h3>\":\nvar result = tmpl(\"<h3>{%=p.title%}</h3>\", {title: \"JavaScript Templates\"});\n```\n\n### Template parsing\nThe template contents are matched and replaced using the regular expression\n**tmpl.regexp** and the replacement function **tmpl.func**.\nThe replacement function operates based on the\n[parenthesized submatch strings](https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/String/replace#Specifying_a_function_as_a_parameter).\n\nTo use different tags for the template syntax, override **tmpl.regexp** with a\nmodified regular expression, by exchanging all occurrences of \"{%\" and \"%}\",\ne.g. with \"[%\" and \"%]\":\n\n```js\ntmpl.regexp = /([\\s'\\\\])(?!(?:[^[]|\\[(?!%))*%\\])|(?:\\[%(=|#)([\\s\\S]+?)%\\])|(\\[%)|(%\\])/g;\n```\n\nBy default, the plugin preserves whitespace\n(newlines, carriage returns, tabs and spaces).\nTo strip unnecessary whitespace, you can override the **tmpl.func** function,\ne.g. with the following code:\n\n```js\nvar originalFunc = tmpl.func;\ntmpl.func = function (s, p1, p2, p3, p4, p5, offset, str) {\n    if (p1 && /\\s/.test(p1)) {\n        if (!offset || /\\s/.test(str.charAt(offset - 1)) ||\n                /^\\s+$/g.test(str.slice(offset))) {\n            return '';\n        }\n        return ' ';\n    }\n    return originalFunc.apply(tmpl, arguments);\n};\n```\n\n## Templates syntax\n\n### Interpolation\nPrint variable with HTML special characters escaped:\n\n```html\n<h3>{%=o.title%}</h3>\n```\n\nPrint variable without escaping:\n\n```html\n<h3>{%#o.user_id%}</h3>\n```\n\nPrint output of function calls:\n\n```html\n<a href=\"{%=encodeURI(o.url)%}\">Website</a>\n```\n\nUse dot notation to print nested properties:\n\n```html\n<strong>{%=o.author.name%}</strong>\n```\n\n### Evaluation\nUse **print(str)** to add escaped content to the output:\n\n```html\n<span>Year: {% var d=new Date(); print(d.getFullYear()); %}</span>\n```\n\nUse **print(str, true)** to add unescaped content to the output:\n\n```html\n<span>{% print(\"Fast &amp; powerful\", true); %}</span>\n```\n\nUse **include(str, obj)** to include content from a different template:\n\n```html\n<div>\n{% include('tmpl-link', {name: \"Website\", url: \"https://example.org\"}); %}\n</div>\n```\n\n**If else condition**:\n\n```html\n{% if (o.author.url) { %}\n    <a href=\"{%=encodeURI(o.author.url)%}\">{%=o.author.name%}</a>\n{% } else { %}\n    <em>No author url.</em>\n{% } %}\n```\n\n**For loop**:\n\n```html\n<ul>\n{% for (var i=0; i<o.features.length; i++) { %}\n    <li>{%=o.features[i]%}</li>\n{% } %}\n</ul>\n```\n\n## Compiled templates\nThe JavaScript Templates project comes with a compilation script, that allows\nyou to compile your templates into JavaScript code and combine them with a\nminimal Templates runtime into one combined JavaScript file.\n\nThe compilation script is built for [node.js](http://nodejs.org/).  \nTo use it, first install the JavaScript Templates project via\n[npm](https://www.npmjs.org/):\n\n```sh\nnpm install blueimp-tmpl\n```\n\nThis will put the executable **tmpl.js** into the folder **node_modules/.bin**.\nIt will also make it available on your PATH if you install the package globally\n(by adding the **-g** flag to the install command).\n\nThe **tmpl.js** executable accepts the paths to one or multiple template files\nas command line arguments and prints the generated JavaScript code to the\nconsole output. The following command line shows you how to store the generated\ncode in a new JavaScript file that can be included in your project:\n\n```sh\ntmpl.js index.html > tmpl.js\n```\n\nThe files given as command line arguments to **tmpl.js** can either be pure\ntemplate files or HTML documents with embedded template script sections.\nFor the pure template files, the file names (without extension) serve as\ntemplate ids.  \nThe generated file can be included in your project as a replacement for the\noriginal **tmpl.js** runtime. It provides you with the same API and provides a\n**tmpl(id, data)** function that accepts the id of one of your templates as\nfirst and a data object as optional second parameter.\n\n## Tests\nThe JavaScript Templates project comes with\n[Unit Tests](https://en.wikipedia.org/wiki/Unit_testing).  \nThere are two different ways to run the tests:\n\n* Open test/index.html in your browser or\n* run `npm test` in the Terminal in the root path of the repository package.\n\nThe first one tests the browser integration,\nthe second one the [node.js](http://nodejs.org/) integration.\n\n## License\nThe JavaScript Templates script is released under the\n[MIT license](http://www.opensource.org/licenses/MIT).\n"
  },
  {
    "path": "app_frontend/static/plugin/JavaScript-Templates/css/demo.css",
    "content": "/*\n * JavaScript Templates Demo CSS\n * https://github.com/blueimp/JavaScript-Templates\n *\n * Copyright 2013, Sebastian Tschan\n * https://blueimp.net\n *\n * Licensed under the MIT license:\n * http://www.opensource.org/licenses/MIT\n */\n\nbody {\n  max-width: 750px;\n  margin: 0 auto;\n  padding: 1em;\n  font-family: 'Lucida Grande', 'Lucida Sans Unicode', Arial, sans-serif;\n  font-size: 1em;\n  line-height: 1.4em;\n  background: #222;\n  color: #fff;\n  -webkit-text-size-adjust: 100%;\n      -ms-text-size-adjust: 100%;\n}\na {\n  color: orange;\n  text-decoration: none;\n}\nimg {\n  border: 0;\n  vertical-align: middle;\n}\nh1 {\n  line-height: 1em;\n}\ntextarea,\ninput {\n  display: inline-block;\n  width: 100%;\n  -webkit-box-sizing: border-box;\n     -moz-box-sizing: border-box;\n          box-sizing: border-box;\n  padding: 10px;\n  margin: 0 0 10px;\n  font-family: \"Lucida Console\", Monaco, monospace;\n}\n.result {\n  padding: 20px 40px;\n  background: #fff;\n  color: #222;\n}\n.error {\n  color: red;\n}\n\n@media (min-width: 481px) {\n  .navigation {\n    list-style: none;\n    padding: 0;\n  }\n  .navigation li {\n    display: inline-block;\n  }\n  .navigation li:not(:first-child):before {\n    content: '| ';\n  }\n}\n\n/* IE7 fixes */\n*+html textarea,\n*+html input {\n  width: 460px;\n}\n*+html .result {\n  width: 400px;\n}\n"
  },
  {
    "path": "app_frontend/static/plugin/JavaScript-Templates/index.html",
    "content": "<!DOCTYPE HTML>\n<!--\n/*\n * JavaScript Templates Demo\n * https://github.com/blueimp/JavaScript-Templates\n *\n * Copyright 2011, Sebastian Tschan\n * https://blueimp.net\n *\n * Licensed under the MIT license:\n * http://www.opensource.org/licenses/MIT\n */\n-->\n<html lang=\"en\">\n<head>\n<!--[if IE]>\n<meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge,chrome=1\">\n<![endif]-->\n<meta charset=\"utf-8\">\n<title>JavaScript Templates Demo</title>\n<meta name=\"description\" content=\"1KB lightweight, fast &amp; powerful JavaScript templating engine with zero dependencies. Compatible with server-side environments like Node.js, module loaders like RequireJS, Browserify or webpack and all web browsers.\">\n<meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n<link rel=\"stylesheet\" href=\"css/demo.css\">\n</head>\n<body>\n<h1>JavaScript Templates Demo</h1>\n<p><strong>1KB</strong> lightweight, fast &amp; powerful <a href=\"https://developer.mozilla.org/en/JavaScript/\">JavaScript</a> templating engine with zero dependencies.<br>\nCompatible with server-side environments like <a href=\"http://nodejs.org/\">Node.js</a>, module loaders like <a href=\"http://requirejs.org/\">RequireJS</a>, <a href=\"http://browserify.org/\">Browserify</a> or <a href=\"https://webpack.github.io/\">webpack</a> and all web browsers.</p>\n<ul class=\"navigation\">\n    <li><a href=\"https://github.com/blueimp/JavaScript-Templates/tags\">Download</a></li>\n    <li><a href=\"https://github.com/blueimp/JavaScript-Templates\">Source Code</a></li>\n    <li><a href=\"https://github.com/blueimp/JavaScript-Templates/blob/master/README.md\">Documentation</a></li>\n    <li><a href=\"test/\">Test</a></li>\n    <li><a href=\"https://blueimp.net\">&copy; Sebastian Tschan</a></li>\n</ul>\n<form>\n    <h2>Template</h2>\n    <textarea rows=\"12\" id=\"template\"></textarea>\n    <br>\n    <h2>Data (JSON)</h2>\n    <textarea rows=\"14\" id=\"data\"></textarea>\n    <br>\n    <button type=\"submit\" id=\"render\">Render</button>\n    <button type=\"reset\" id=\"reset\">Reset</button>\n    <h2>Result</h2>\n    <div id=\"result\" class=\"result\"></div>\n    <br>\n</form>\n<script type=\"text/x-tmpl\" id=\"tmpl-demo\">\n<h3>{%=o.title%}</h3>\n<p>Released under the\n<a href=\"{%=o.license.url%}\">{%=o.license.name%}</a>.</p>\n<h4>Features</h4>\n<ul>\n{% for (var i=0; i<o.features.length; i++) { %}\n    <li>{%=o.features[i]%}</li>\n{% } %}\n</ul>\n</script>\n<script type=\"text/x-tmpl\" id=\"tmpl-data\">\n{\n    \"title\": \"JavaScript Templates\",\n    \"license\": {\n        \"name\": \"MIT license\",\n        \"url\": \"http://www.opensource.org/licenses/MIT\"\n    },\n    \"features\": [\n        \"lightweight & fast\",\n        \"powerful\",\n        \"zero dependencies\"\n    ]\n}\n</script>\n<script type=\"text/x-tmpl\" id=\"tmpl-error\">\n<h3 class=\"error\">{%=o.title%}</h3>\n<code>{%=o.error%}</code>\n</script>\n<script src=\"js/tmpl.js\"></script>\n<script src=\"js/demo.js\"></script>\n</body>\n</html>\n"
  },
  {
    "path": "app_frontend/static/plugin/JavaScript-Templates/js/compile.js",
    "content": "#!/usr/bin/env node\n/*\n * JavaScript Templates Compiler\n * https://github.com/blueimp/JavaScript-Templates\n *\n * Copyright 2011, Sebastian Tschan\n * https://blueimp.net\n *\n * Licensed under the MIT license:\n * http://www.opensource.org/licenses/MIT\n */\n\n/*global require, __dirname, process, console */\n\n;(function () {\n  'use strict'\n  var path = require('path')\n  var tmpl = require(path.join(__dirname, 'tmpl.js'))\n  var fs = require('fs')\n  // Retrieve the content of the minimal runtime:\n  var runtime = fs.readFileSync(path.join(__dirname, 'runtime.js'), 'utf8')\n  // A regular expression to parse templates from script tags in a HTML page:\n  var regexp = /<script( id=\"([\\w\\-]+)\")? type=\"text\\/x-tmpl\"( id=\"([\\w\\-]+)\")?>([\\s\\S]+?)<\\/script>/gi\n  // A regular expression to match the helper function names:\n  var helperRegexp = new RegExp(\n    tmpl.helper.match(/\\w+(?=\\s*=\\s*function\\s*\\()/g).join('\\\\s*\\\\(|') + '\\\\s*\\\\('\n  )\n  // A list to store the function bodies:\n  var list = []\n  var code\n  // Extend the Templating engine with a print method for the generated functions:\n  tmpl.print = function (str) {\n    // Only add helper functions if they are used inside of the template:\n    var helper = helperRegexp.test(str) ? tmpl.helper : ''\n    var body = str.replace(tmpl.regexp, tmpl.func)\n    if (helper || (/_e\\s*\\(/.test(body))) {\n      helper = '_e=tmpl.encode' + helper + ','\n    }\n    return 'function(' + tmpl.arg + ',tmpl){' +\n    ('var ' + helper + \"_s='\" + body + \"';return _s;\")\n      .split(\"_s+='';\").join('') + '}'\n  }\n  // Loop through the command line arguments:\n  process.argv.forEach(function (file, index) {\n    var listLength = list.length\n    var stats\n    var content\n    var result\n    var id\n    // Skip the first two arguments, which are \"node\" and the script:\n    if (index > 1) {\n      stats = fs.statSync(file)\n      if (!stats.isFile()) {\n        console.error(file + ' is not a file.')\n        return\n      }\n      content = fs.readFileSync(file, 'utf8')\n      while (true) {\n        // Find templates in script tags:\n        result = regexp.exec(content)\n        if (!result) {\n          break\n        }\n        id = result[2] || result[4]\n        list.push(\"'\" + id + \"':\" + tmpl.print(result[5]))\n      }\n      if (listLength === list.length) {\n        // No template script tags found, use the complete content:\n        id = path.basename(file, path.extname(file))\n        list.push(\"'\" + id + \"':\" + tmpl.print(content))\n      }\n    }\n  })\n  if (!list.length) {\n    console.error('Missing input file.')\n    return\n  }\n  // Combine the generated functions as cache of the minimal runtime:\n  code = runtime.replace('{}', '{' + list.join(',') + '}')\n  // Print the resulting code to the console output:\n  console.log(code)\n}())\n"
  },
  {
    "path": "app_frontend/static/plugin/JavaScript-Templates/js/demo.js",
    "content": "/*\n * JavaScript Templates Demo\n * https://github.com/blueimp/JavaScript-Templates\n *\n * Copyright 2013, Sebastian Tschan\n * https://blueimp.net\n *\n * Licensed under the MIT license:\n * http://www.opensource.org/licenses/MIT\n */\n\n/* global document, tmpl */\n\n;(function () {\n  'use strict'\n\n  var templateInput = document.getElementById('template')\n  var dataInput = document.getElementById('data')\n  var resultNode = document.getElementById('result')\n  var templateDemoNode = document.getElementById('tmpl-demo')\n  var templateDataNode = document.getElementById('tmpl-data')\n\n  function renderError (title, error) {\n    resultNode.innerHTML = tmpl(\n      'tmpl-error',\n      {title: title, error: error}\n    )\n  }\n\n  function render (event) {\n    event.preventDefault()\n    var data\n    try {\n      data = JSON.parse(dataInput.value)\n    } catch (e) {\n      renderError('JSON parsing failed', e)\n      return\n    }\n    try {\n      resultNode.innerHTML = tmpl(\n        templateInput.value,\n        data\n      )\n    } catch (e) {\n      renderError('Template rendering failed', e)\n    }\n  }\n\n  function empty (node) {\n    while (node.lastChild) {\n      node.removeChild(node.lastChild)\n    }\n  }\n\n  function init (event) {\n    if (event) {\n      event.preventDefault()\n    }\n    templateInput.value = templateDemoNode.innerHTML.trim()\n    dataInput.value = templateDataNode.innerHTML.trim()\n    empty(resultNode)\n  }\n\n  document.getElementById('render').addEventListener('click', render)\n  document.getElementById('reset').addEventListener('click', init)\n\n  init()\n}())\n"
  },
  {
    "path": "app_frontend/static/plugin/JavaScript-Templates/js/runtime.js",
    "content": "/*\n * JavaScript Templates Runtime\n * https://github.com/blueimp/JavaScript-Templates\n *\n * Copyright 2011, Sebastian Tschan\n * https://blueimp.net\n *\n * Licensed under the MIT license:\n * http://www.opensource.org/licenses/MIT\n */\n\n/*global define, module */\n\n;(function ($) {\n  'use strict'\n  var tmpl = function (id, data) {\n    var f = tmpl.cache[id]\n    return data ? f(data, tmpl) : function (data) {\n      return f(data, tmpl)\n    }\n  }\n  tmpl.cache = {}\n  tmpl.encReg = /[<>&\"'\\x00]/g\n  tmpl.encMap = {\n    '<': '&lt;',\n    '>': '&gt;',\n    '&': '&amp;',\n    '\"': '&quot;',\n    \"'\": '&#39;'\n  }\n  tmpl.encode = function (s) {\n    return (s == null ? '' : '' + s).replace(\n      tmpl.encReg,\n      function (c) {\n        return tmpl.encMap[c] || ''\n      }\n    )\n  }\n  if (typeof define === 'function' && define.amd) {\n    define(function () {\n      return tmpl\n    })\n  } else if (typeof module === 'object' && module.exports) {\n    module.exports = tmpl\n  } else {\n    $.tmpl = tmpl\n  }\n}(this))\n"
  },
  {
    "path": "app_frontend/static/plugin/JavaScript-Templates/js/tmpl.js",
    "content": "/*\n * JavaScript Templates\n * https://github.com/blueimp/JavaScript-Templates\n *\n * Copyright 2011, Sebastian Tschan\n * https://blueimp.net\n *\n * Licensed under the MIT license:\n * http://www.opensource.org/licenses/MIT\n *\n * Inspired by John Resig's JavaScript Micro-Templating:\n * http://ejohn.org/blog/javascript-micro-templating/\n */\n\n/*global document, define, module */\n\n;(function ($) {\n  'use strict'\n  var tmpl = function (str, data) {\n    var f = !/[^\\w\\-\\.:]/.test(str)\n      ? tmpl.cache[str] = tmpl.cache[str] || tmpl(tmpl.load(str))\n      : new Function(// eslint-disable-line no-new-func\n        tmpl.arg + ',tmpl',\n        'var _e=tmpl.encode' + tmpl.helper + \",_s='\" +\n          str.replace(tmpl.regexp, tmpl.func) + \"';return _s;\"\n      )\n    return data ? f(data, tmpl) : function (data) {\n      return f(data, tmpl)\n    }\n  }\n  tmpl.cache = {}\n  tmpl.load = function (id) {\n    return document.getElementById(id).innerHTML\n  }\n  tmpl.regexp = /([\\s'\\\\])(?!(?:[^{]|\\{(?!%))*%\\})|(?:\\{%(=|#)([\\s\\S]+?)%\\})|(\\{%)|(%\\})/g\n  tmpl.func = function (s, p1, p2, p3, p4, p5) {\n    if (p1) { // whitespace, quote and backspace in HTML context\n      return {\n        '\\n': '\\\\n',\n        '\\r': '\\\\r',\n        '\\t': '\\\\t',\n        ' ': ' '\n      }[p1] || '\\\\' + p1\n    }\n    if (p2) { // interpolation: {%=prop%}, or unescaped: {%#prop%}\n      if (p2 === '=') {\n        return \"'+_e(\" + p3 + \")+'\"\n      }\n      return \"'+(\" + p3 + \"==null?'':\" + p3 + \")+'\"\n    }\n    if (p4) { // evaluation start tag: {%\n      return \"';\"\n    }\n    if (p5) { // evaluation end tag: %}\n      return \"_s+='\"\n    }\n  }\n  tmpl.encReg = /[<>&\"'\\x00]/g\n  tmpl.encMap = {\n    '<': '&lt;',\n    '>': '&gt;',\n    '&': '&amp;',\n    '\"': '&quot;',\n    \"'\": '&#39;'\n  }\n  tmpl.encode = function (s) {\n    return (s == null ? '' : '' + s).replace(\n      tmpl.encReg,\n      function (c) {\n        return tmpl.encMap[c] || ''\n      }\n    )\n  }\n  tmpl.arg = 'o'\n  tmpl.helper = \",print=function(s,e){_s+=e?(s==null?'':s):_e(s);}\" +\n                  ',include=function(s,d){_s+=tmpl(s,d);}'\n  if (typeof define === 'function' && define.amd) {\n    define(function () {\n      return tmpl\n    })\n  } else if (typeof module === 'object' && module.exports) {\n    module.exports = tmpl\n  } else {\n    $.tmpl = tmpl\n  }\n}(this))\n"
  },
  {
    "path": "app_frontend/static/plugin/JavaScript-Templates/package.json",
    "content": "{\n  \"name\": \"blueimp-tmpl\",\n  \"version\": \"3.4.0\",\n  \"title\": \"JavaScript Templates\",\n  \"description\": \"1KB lightweight, fast & powerful JavaScript templating engine with zero dependencies. Compatible with server-side environments like Node.js, module loaders like RequireJS, Browserify or webpack and all web browsers.\",\n  \"keywords\": [\n    \"javascript\",\n    \"templates\",\n    \"templating\"\n  ],\n  \"homepage\": \"https://github.com/blueimp/JavaScript-Templates\",\n  \"author\": {\n    \"name\": \"Sebastian Tschan\",\n    \"url\": \"https://blueimp.net\"\n  },\n  \"repository\": {\n    \"type\": \"git\",\n    \"url\": \"git://github.com/blueimp/JavaScript-Templates.git\"\n  },\n  \"license\": \"MIT\",\n  \"devDependencies\": {\n    \"expect.js\": \"0.3.1\",\n    \"mocha\": \"2.3.4\",\n    \"standard\": \"6.0.7\",\n    \"uglify-js\": \"2.6.1\"\n  },\n  \"scripts\": {\n    \"test\": \"standard js/*.js test/*.js && mocha\",\n    \"build\": \"cd js && uglifyjs tmpl.js -c -m -o tmpl.min.js --source-map tmpl.min.js.map\",\n    \"preversion\": \"npm test\",\n    \"version\": \"npm run build && git add -A js\",\n    \"postversion\": \"git push --tags origin master master:gh-pages && npm publish\"\n  },\n  \"bin\": {\n    \"tmpl.js\": \"js/compile.js\"\n  },\n  \"main\": \"js/tmpl.js\"\n}\n"
  },
  {
    "path": "app_frontend/static/plugin/JavaScript-Templates/test/index.html",
    "content": "<!DOCTYPE HTML>\n<!--\n/*\n * JavaScript Templates Test\n * https://github.com/blueimp/JavaScript-Templates\n *\n * Copyright 2011, Sebastian Tschan\n * https://blueimp.net\n *\n * Licensed under the MIT license:\n * http://www.opensource.org/licenses/MIT\n */\n-->\n<html lang=\"en\">\n<head>\n<!--[if IE]>\n<meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge,chrome=1\">\n<![endif]-->\n<meta charset=\"utf-8\">\n<title>JavaScript Templates Test</title>\n<meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n<link rel=\"stylesheet\" href=\"vendor/mocha.css\">\n</head>\n<body>\n<div id=\"mocha\"></div>\n<script src=\"vendor/mocha.js\"></script>\n<script src=\"vendor/expect.js\"></script>\n<script>\nmocha.setup('bdd');\n</script>\n<script type=\"text/x-tmpl\" id=\"template\">{%=o.value%}</script>\n<script src=\"../js/tmpl.js\"></script>\n<script src=\"test.js\"></script>\n<script>\nmocha.checkLeaks();\nmocha.run();\n</script>\n</body>\n</html>\n"
  },
  {
    "path": "app_frontend/static/plugin/JavaScript-Templates/test/test.js",
    "content": "/*\n * JavaScript Templates Test\n * https://github.com/blueimp/JavaScript-Templates\n *\n * Copyright 2011, Sebastian Tschan\n * https://blueimp.net\n *\n * Licensed under the MIT license:\n * http://www.opensource.org/licenses/MIT\n */\n\n/*global beforeEach, afterEach, describe, it, require */\n\n;(function (context, expect, tmpl) {\n  'use strict'\n\n  if (context.require === undefined) {\n    // Override the template loading method:\n    tmpl.load = function (id) {\n      switch (id) {\n        case 'template':\n          return '{%=o.value%}'\n      }\n    }\n  }\n\n  var data\n\n  beforeEach(function () {\n    // Initialize the sample data:\n    data = {\n      value: 'value',\n      nullValue: null,\n      falseValue: false,\n      zeroValue: 0,\n      special: '<>&\"\\'\\x00',\n      list: [1, 2, 3, 4, 5],\n      func: function () {\n        return this.value\n      },\n      deep: {\n        value: 'value'\n      }\n    }\n  })\n\n  afterEach(function () {\n    // Purge the template cache:\n    tmpl.cache = {}\n  })\n\n  describe('Template loading', function () {\n    it('String template', function () {\n      expect(\n        tmpl('{%=o.value%}', data)\n      ).to.be(\n        'value'\n      )\n    })\n\n    it('Load template by id', function () {\n      expect(\n        tmpl('template', data)\n      ).to.be(\n        'value'\n      )\n    })\n\n    it('Retun function when called without data parameter', function () {\n      expect(\n        tmpl('{%=o.value%}')(data)\n      ).to.be(\n        'value'\n      )\n    })\n\n    it('Cache templates loaded by id', function () {\n      tmpl('template')\n      expect(\n        tmpl.cache.template\n      ).to.be.a('function')\n    })\n  })\n\n  describe('Interpolation', function () {\n    it('Escape HTML special characters with {%=o.prop%}', function () {\n      expect(\n        tmpl('{%=o.special%}', data)\n      ).to.be(\n        '&lt;&gt;&amp;&quot;&#39;'\n      )\n    })\n\n    it('Allow HTML special characters with {%#o.prop%}', function () {\n      expect(\n        tmpl('{%#o.special%}', data)\n      ).to.be(\n        '<>&\"\\'\\x00'\n      )\n    })\n\n    it('Function call', function () {\n      expect(\n        tmpl('{%=o.func()%}', data)\n      ).to.be(\n        'value'\n      )\n    })\n\n    it('Dot notation', function () {\n      expect(\n        tmpl('{%=o.deep.value%}', data)\n      ).to.be(\n        'value'\n      )\n    })\n\n    it('Handle single quotes', function () {\n      expect(\n        tmpl('\\'single quotes\\'{%=\": \\'\"%}', data)\n      ).to.be(\n        \"'single quotes': &#39;\"\n      )\n    })\n\n    it('Handle double quotes', function () {\n      expect(\n        tmpl('\"double quotes\"{%=\": \\\\\"\"%}', data)\n      ).to.be(\n        '\"double quotes\": &quot;'\n      )\n    })\n\n    it('Handle backslashes', function () {\n      expect(\n        tmpl('\\\\backslashes\\\\{%=\": \\\\\\\\\"%}', data)\n      ).to.be(\n        '\\\\backslashes\\\\: \\\\'\n      )\n    })\n\n    it('Interpolate escaped falsy values except undefined or null', function () {\n      expect(\n        tmpl(\n          '{%=o.undefinedValue%}' +\n          '{%=o.nullValue%}' +\n          '{%=o.falseValue%}' +\n          '{%=o.zeroValue%}',\n          data\n        )\n      ).to.be(\n        'false0'\n      )\n    })\n\n    it('Interpolate unescaped falsy values except undefined or null', function () {\n      expect(\n        tmpl(\n          '{%#o.undefinedValue%}' +\n          '{%#o.nullValue%}' +\n          '{%#o.falseValue%}' +\n          '{%#o.zeroValue%}',\n          data\n        )\n      ).to.be(\n        'false0'\n      )\n    })\n\n    it('Preserve whitespace', function () {\n      expect(\n        tmpl(\n          '\\n\\r\\t{%=o.value%}  \\n\\r\\t{%=o.value%}  ',\n          data\n        )\n      ).to.be(\n        '\\n\\r\\tvalue  \\n\\r\\tvalue  '\n      )\n    })\n  })\n\n  describe('Evaluation', function () {\n    it('Escape HTML special characters with print(data)', function () {\n      expect(\n        tmpl('{% print(o.special); %}', data)\n      ).to.be(\n        '&lt;&gt;&amp;&quot;&#39;'\n      )\n    })\n\n    it('Allow HTML special characters with print(data, true)', function () {\n      expect(\n        tmpl('{% print(o.special, true); %}', data)\n      ).to.be(\n        '<>&\"\\'\\x00'\n      )\n    })\n\n    it('Print out escaped falsy values except undefined or null', function () {\n      expect(\n        tmpl(\n          '{% print(o.undefinedValue); %}' +\n          '{% print(o.nullValue); %}' +\n          '{% print(o.falseValue); %}' +\n          '{% print(o.zeroValue); %}',\n          data\n        )\n      ).to.be(\n        'false0'\n      )\n    })\n\n    it('Print out unescaped falsy values except undefined or null', function () {\n      expect(\n        tmpl(\n          '{% print(o.undefinedValue, true); %}' +\n          '{% print(o.nullValue, true); %}' +\n          '{% print(o.falseValue, true); %}' +\n          '{% print(o.zeroValue, true); %}',\n          data\n        )\n      ).to.be(\n        'false0'\n      )\n    })\n\n    it('Include template', function () {\n      expect(\n        tmpl('{% include(\"template\", {value: \"value\"}); %}', data)\n      ).to.be(\n        'value'\n      )\n    })\n\n    it('If condition', function () {\n      expect(\n        tmpl('{% if (o.value) { %}true{% } else { %}false{% } %}', data)\n      ).to.be(\n        'true'\n      )\n    })\n\n    it('Else condition', function () {\n      expect(\n        tmpl(\n          '{% if (o.undefinedValue) { %}false{% } else { %}true{% } %}',\n          data\n        )\n      ).to.be(\n        'true'\n      )\n    })\n\n    it('For loop', function () {\n      expect(\n        tmpl(\n          '{% for (var i=0; i<o.list.length; i++) { %}' +\n          '{%=o.list[i]%}{% } %}',\n          data\n        )\n      ).to.be(\n        '12345'\n      )\n    })\n\n    it('For loop print call', function () {\n      expect(\n        tmpl(\n          '{% for (var i=0; i<o.list.length; i++) {' +\n          'print(o.list[i]);} %}',\n          data\n        )\n      ).to.be(\n        '12345'\n      )\n    })\n\n    it('For loop include template', function () {\n      expect(\n        tmpl(\n          '{% for (var i=0; i<o.list.length; i++) {' +\n          'include(\"template\", {value: o.list[i]});} %}',\n          data\n        ).replace(/[\\r\\n]/g, '')\n      ).to.be(\n        '12345'\n      )\n    })\n\n    it('Modulo operator', function () {\n      expect(\n        tmpl(\n          '{% if (o.list.length % 5 === 0) { %}5 list items{% } %}',\n          data\n        ).replace(/[\\r\\n]/g, '')\n      ).to.be(\n        '5 list items'\n      )\n    })\n  })\n}(\n  this,\n  this.expect || require('expect.js'),\n  this.tmpl || require('../js/tmpl')\n))\n"
  },
  {
    "path": "app_frontend/static/plugin/JavaScript-Templates/test/vendor/expect.js",
    "content": "(function (global, module) {\n\n  var exports = module.exports;\n\n  /**\n   * Exports.\n   */\n\n  module.exports = expect;\n  expect.Assertion = Assertion;\n\n  /**\n   * Exports version.\n   */\n\n  expect.version = '0.3.1';\n\n  /**\n   * Possible assertion flags.\n   */\n\n  var flags = {\n      not: ['to', 'be', 'have', 'include', 'only']\n    , to: ['be', 'have', 'include', 'only', 'not']\n    , only: ['have']\n    , have: ['own']\n    , be: ['an']\n  };\n\n  function expect (obj) {\n    return new Assertion(obj);\n  }\n\n  /**\n   * Constructor\n   *\n   * @api private\n   */\n\n  function Assertion (obj, flag, parent) {\n    this.obj = obj;\n    this.flags = {};\n\n    if (undefined != parent) {\n      this.flags[flag] = true;\n\n      for (var i in parent.flags) {\n        if (parent.flags.hasOwnProperty(i)) {\n          this.flags[i] = true;\n        }\n      }\n    }\n\n    var $flags = flag ? flags[flag] : keys(flags)\n      , self = this;\n\n    if ($flags) {\n      for (var i = 0, l = $flags.length; i < l; i++) {\n        // avoid recursion\n        if (this.flags[$flags[i]]) continue;\n\n        var name = $flags[i]\n          , assertion = new Assertion(this.obj, name, this)\n\n        if ('function' == typeof Assertion.prototype[name]) {\n          // clone the function, make sure we dont touch the prot reference\n          var old = this[name];\n          this[name] = function () {\n            return old.apply(self, arguments);\n          };\n\n          for (var fn in Assertion.prototype) {\n            if (Assertion.prototype.hasOwnProperty(fn) && fn != name) {\n              this[name][fn] = bind(assertion[fn], assertion);\n            }\n          }\n        } else {\n          this[name] = assertion;\n        }\n      }\n    }\n  }\n\n  /**\n   * Performs an assertion\n   *\n   * @api private\n   */\n\n  Assertion.prototype.assert = function (truth, msg, error, expected) {\n    var msg = this.flags.not ? error : msg\n      , ok = this.flags.not ? !truth : truth\n      , err;\n\n    if (!ok) {\n      err = new Error(msg.call(this));\n      if (arguments.length > 3) {\n        err.actual = this.obj;\n        err.expected = expected;\n        err.showDiff = true;\n      }\n      throw err;\n    }\n\n    this.and = new Assertion(this.obj);\n  };\n\n  /**\n   * Check if the value is truthy\n   *\n   * @api public\n   */\n\n  Assertion.prototype.ok = function () {\n    this.assert(\n        !!this.obj\n      , function(){ return 'expected ' + i(this.obj) + ' to be truthy' }\n      , function(){ return 'expected ' + i(this.obj) + ' to be falsy' });\n  };\n\n  /**\n   * Creates an anonymous function which calls fn with arguments.\n   *\n   * @api public\n   */\n\n  Assertion.prototype.withArgs = function() {\n    expect(this.obj).to.be.a('function');\n    var fn = this.obj;\n    var args = Array.prototype.slice.call(arguments);\n    return expect(function() { fn.apply(null, args); });\n  };\n\n  /**\n   * Assert that the function throws.\n   *\n   * @param {Function|RegExp} callback, or regexp to match error string against\n   * @api public\n   */\n\n  Assertion.prototype.throwError =\n  Assertion.prototype.throwException = function (fn) {\n    expect(this.obj).to.be.a('function');\n\n    var thrown = false\n      , not = this.flags.not;\n\n    try {\n      this.obj();\n    } catch (e) {\n      if (isRegExp(fn)) {\n        var subject = 'string' == typeof e ? e : e.message;\n        if (not) {\n          expect(subject).to.not.match(fn);\n        } else {\n          expect(subject).to.match(fn);\n        }\n      } else if ('function' == typeof fn) {\n        fn(e);\n      }\n      thrown = true;\n    }\n\n    if (isRegExp(fn) && not) {\n      // in the presence of a matcher, ensure the `not` only applies to\n      // the matching.\n      this.flags.not = false;\n    }\n\n    var name = this.obj.name || 'fn';\n    this.assert(\n        thrown\n      , function(){ return 'expected ' + name + ' to throw an exception' }\n      , function(){ return 'expected ' + name + ' not to throw an exception' });\n  };\n\n  /**\n   * Checks if the array is empty.\n   *\n   * @api public\n   */\n\n  Assertion.prototype.empty = function () {\n    var expectation;\n\n    if ('object' == typeof this.obj && null !== this.obj && !isArray(this.obj)) {\n      if ('number' == typeof this.obj.length) {\n        expectation = !this.obj.length;\n      } else {\n        expectation = !keys(this.obj).length;\n      }\n    } else {\n      if ('string' != typeof this.obj) {\n        expect(this.obj).to.be.an('object');\n      }\n\n      expect(this.obj).to.have.property('length');\n      expectation = !this.obj.length;\n    }\n\n    this.assert(\n        expectation\n      , function(){ return 'expected ' + i(this.obj) + ' to be empty' }\n      , function(){ return 'expected ' + i(this.obj) + ' to not be empty' });\n    return this;\n  };\n\n  /**\n   * Checks if the obj exactly equals another.\n   *\n   * @api public\n   */\n\n  Assertion.prototype.be =\n  Assertion.prototype.equal = function (obj) {\n    this.assert(\n        obj === this.obj\n      , function(){ return 'expected ' + i(this.obj) + ' to equal ' + i(obj) }\n      , function(){ return 'expected ' + i(this.obj) + ' to not equal ' + i(obj) });\n    return this;\n  };\n\n  /**\n   * Checks if the obj sortof equals another.\n   *\n   * @api public\n   */\n\n  Assertion.prototype.eql = function (obj) {\n    this.assert(\n        expect.eql(this.obj, obj)\n      , function(){ return 'expected ' + i(this.obj) + ' to sort of equal ' + i(obj) }\n      , function(){ return 'expected ' + i(this.obj) + ' to sort of not equal ' + i(obj) }\n      , obj);\n    return this;\n  };\n\n  /**\n   * Assert within start to finish (inclusive).\n   *\n   * @param {Number} start\n   * @param {Number} finish\n   * @api public\n   */\n\n  Assertion.prototype.within = function (start, finish) {\n    var range = start + '..' + finish;\n    this.assert(\n        this.obj >= start && this.obj <= finish\n      , function(){ return 'expected ' + i(this.obj) + ' to be within ' + range }\n      , function(){ return 'expected ' + i(this.obj) + ' to not be within ' + range });\n    return this;\n  };\n\n  /**\n   * Assert typeof / instance of\n   *\n   * @api public\n   */\n\n  Assertion.prototype.a =\n  Assertion.prototype.an = function (type) {\n    if ('string' == typeof type) {\n      // proper english in error msg\n      var n = /^[aeiou]/.test(type) ? 'n' : '';\n\n      // typeof with support for 'array'\n      this.assert(\n          'array' == type ? isArray(this.obj) :\n            'regexp' == type ? isRegExp(this.obj) :\n              'object' == type\n                ? 'object' == typeof this.obj && null !== this.obj\n                : type == typeof this.obj\n        , function(){ return 'expected ' + i(this.obj) + ' to be a' + n + ' ' + type }\n        , function(){ return 'expected ' + i(this.obj) + ' not to be a' + n + ' ' + type });\n    } else {\n      // instanceof\n      var name = type.name || 'supplied constructor';\n      this.assert(\n          this.obj instanceof type\n        , function(){ return 'expected ' + i(this.obj) + ' to be an instance of ' + name }\n        , function(){ return 'expected ' + i(this.obj) + ' not to be an instance of ' + name });\n    }\n\n    return this;\n  };\n\n  /**\n   * Assert numeric value above _n_.\n   *\n   * @param {Number} n\n   * @api public\n   */\n\n  Assertion.prototype.greaterThan =\n  Assertion.prototype.above = function (n) {\n    this.assert(\n        this.obj > n\n      , function(){ return 'expected ' + i(this.obj) + ' to be above ' + n }\n      , function(){ return 'expected ' + i(this.obj) + ' to be below ' + n });\n    return this;\n  };\n\n  /**\n   * Assert numeric value below _n_.\n   *\n   * @param {Number} n\n   * @api public\n   */\n\n  Assertion.prototype.lessThan =\n  Assertion.prototype.below = function (n) {\n    this.assert(\n        this.obj < n\n      , function(){ return 'expected ' + i(this.obj) + ' to be below ' + n }\n      , function(){ return 'expected ' + i(this.obj) + ' to be above ' + n });\n    return this;\n  };\n\n  /**\n   * Assert string value matches _regexp_.\n   *\n   * @param {RegExp} regexp\n   * @api public\n   */\n\n  Assertion.prototype.match = function (regexp) {\n    this.assert(\n        regexp.exec(this.obj)\n      , function(){ return 'expected ' + i(this.obj) + ' to match ' + regexp }\n      , function(){ return 'expected ' + i(this.obj) + ' not to match ' + regexp });\n    return this;\n  };\n\n  /**\n   * Assert property \"length\" exists and has value of _n_.\n   *\n   * @param {Number} n\n   * @api public\n   */\n\n  Assertion.prototype.length = function (n) {\n    expect(this.obj).to.have.property('length');\n    var len = this.obj.length;\n    this.assert(\n        n == len\n      , function(){ return 'expected ' + i(this.obj) + ' to have a length of ' + n + ' but got ' + len }\n      , function(){ return 'expected ' + i(this.obj) + ' to not have a length of ' + len });\n    return this;\n  };\n\n  /**\n   * Assert property _name_ exists, with optional _val_.\n   *\n   * @param {String} name\n   * @param {Mixed} val\n   * @api public\n   */\n\n  Assertion.prototype.property = function (name, val) {\n    if (this.flags.own) {\n      this.assert(\n          Object.prototype.hasOwnProperty.call(this.obj, name)\n        , function(){ return 'expected ' + i(this.obj) + ' to have own property ' + i(name) }\n        , function(){ return 'expected ' + i(this.obj) + ' to not have own property ' + i(name) });\n      return this;\n    }\n\n    if (this.flags.not && undefined !== val) {\n      if (undefined === this.obj[name]) {\n        throw new Error(i(this.obj) + ' has no property ' + i(name));\n      }\n    } else {\n      var hasProp;\n      try {\n        hasProp = name in this.obj\n      } catch (e) {\n        hasProp = undefined !== this.obj[name]\n      }\n\n      this.assert(\n          hasProp\n        , function(){ return 'expected ' + i(this.obj) + ' to have a property ' + i(name) }\n        , function(){ return 'expected ' + i(this.obj) + ' to not have a property ' + i(name) });\n    }\n\n    if (undefined !== val) {\n      this.assert(\n          val === this.obj[name]\n        , function(){ return 'expected ' + i(this.obj) + ' to have a property ' + i(name)\n          + ' of ' + i(val) + ', but got ' + i(this.obj[name]) }\n        , function(){ return 'expected ' + i(this.obj) + ' to not have a property ' + i(name)\n          + ' of ' + i(val) });\n    }\n\n    this.obj = this.obj[name];\n    return this;\n  };\n\n  /**\n   * Assert that the array contains _obj_ or string contains _obj_.\n   *\n   * @param {Mixed} obj|string\n   * @api public\n   */\n\n  Assertion.prototype.string =\n  Assertion.prototype.contain = function (obj) {\n    if ('string' == typeof this.obj) {\n      this.assert(\n          ~this.obj.indexOf(obj)\n        , function(){ return 'expected ' + i(this.obj) + ' to contain ' + i(obj) }\n        , function(){ return 'expected ' + i(this.obj) + ' to not contain ' + i(obj) });\n    } else {\n      this.assert(\n          ~indexOf(this.obj, obj)\n        , function(){ return 'expected ' + i(this.obj) + ' to contain ' + i(obj) }\n        , function(){ return 'expected ' + i(this.obj) + ' to not contain ' + i(obj) });\n    }\n    return this;\n  };\n\n  /**\n   * Assert exact keys or inclusion of keys by using\n   * the `.own` modifier.\n   *\n   * @param {Array|String ...} keys\n   * @api public\n   */\n\n  Assertion.prototype.key =\n  Assertion.prototype.keys = function ($keys) {\n    var str\n      , ok = true;\n\n    $keys = isArray($keys)\n      ? $keys\n      : Array.prototype.slice.call(arguments);\n\n    if (!$keys.length) throw new Error('keys required');\n\n    var actual = keys(this.obj)\n      , len = $keys.length;\n\n    // Inclusion\n    ok = every($keys, function (key) {\n      return ~indexOf(actual, key);\n    });\n\n    // Strict\n    if (!this.flags.not && this.flags.only) {\n      ok = ok && $keys.length == actual.length;\n    }\n\n    // Key string\n    if (len > 1) {\n      $keys = map($keys, function (key) {\n        return i(key);\n      });\n      var last = $keys.pop();\n      str = $keys.join(', ') + ', and ' + last;\n    } else {\n      str = i($keys[0]);\n    }\n\n    // Form\n    str = (len > 1 ? 'keys ' : 'key ') + str;\n\n    // Have / include\n    str = (!this.flags.only ? 'include ' : 'only have ') + str;\n\n    // Assertion\n    this.assert(\n        ok\n      , function(){ return 'expected ' + i(this.obj) + ' to ' + str }\n      , function(){ return 'expected ' + i(this.obj) + ' to not ' + str });\n\n    return this;\n  };\n\n  /**\n   * Assert a failure.\n   *\n   * @param {String ...} custom message\n   * @api public\n   */\n  Assertion.prototype.fail = function (msg) {\n    var error = function() { return msg || \"explicit failure\"; }\n    this.assert(false, error, error);\n    return this;\n  };\n\n  /**\n   * Function bind implementation.\n   */\n\n  function bind (fn, scope) {\n    return function () {\n      return fn.apply(scope, arguments);\n    }\n  }\n\n  /**\n   * Array every compatibility\n   *\n   * @see bit.ly/5Fq1N2\n   * @api public\n   */\n\n  function every (arr, fn, thisObj) {\n    var scope = thisObj || global;\n    for (var i = 0, j = arr.length; i < j; ++i) {\n      if (!fn.call(scope, arr[i], i, arr)) {\n        return false;\n      }\n    }\n    return true;\n  }\n\n  /**\n   * Array indexOf compatibility.\n   *\n   * @see bit.ly/a5Dxa2\n   * @api public\n   */\n\n  function indexOf (arr, o, i) {\n    if (Array.prototype.indexOf) {\n      return Array.prototype.indexOf.call(arr, o, i);\n    }\n\n    if (arr.length === undefined) {\n      return -1;\n    }\n\n    for (var j = arr.length, i = i < 0 ? i + j < 0 ? 0 : i + j : i || 0\n        ; i < j && arr[i] !== o; i++);\n\n    return j <= i ? -1 : i;\n  }\n\n  // https://gist.github.com/1044128/\n  var getOuterHTML = function(element) {\n    if ('outerHTML' in element) return element.outerHTML;\n    var ns = \"http://www.w3.org/1999/xhtml\";\n    var container = document.createElementNS(ns, '_');\n    var xmlSerializer = new XMLSerializer();\n    var html;\n    if (document.xmlVersion) {\n      return xmlSerializer.serializeToString(element);\n    } else {\n      container.appendChild(element.cloneNode(false));\n      html = container.innerHTML.replace('><', '>' + element.innerHTML + '<');\n      container.innerHTML = '';\n      return html;\n    }\n  };\n\n  // Returns true if object is a DOM element.\n  var isDOMElement = function (object) {\n    if (typeof HTMLElement === 'object') {\n      return object instanceof HTMLElement;\n    } else {\n      return object &&\n        typeof object === 'object' &&\n        object.nodeType === 1 &&\n        typeof object.nodeName === 'string';\n    }\n  };\n\n  /**\n   * Inspects an object.\n   *\n   * @see taken from node.js `util` module (copyright Joyent, MIT license)\n   * @api private\n   */\n\n  function i (obj, showHidden, depth) {\n    var seen = [];\n\n    function stylize (str) {\n      return str;\n    }\n\n    function format (value, recurseTimes) {\n      // Provide a hook for user-specified inspect functions.\n      // Check that value is an object with an inspect function on it\n      if (value && typeof value.inspect === 'function' &&\n          // Filter out the util module, it's inspect function is special\n          value !== exports &&\n          // Also filter out any prototype objects using the circular check.\n          !(value.constructor && value.constructor.prototype === value)) {\n        return value.inspect(recurseTimes);\n      }\n\n      // Primitive types cannot have properties\n      switch (typeof value) {\n        case 'undefined':\n          return stylize('undefined', 'undefined');\n\n        case 'string':\n          var simple = '\\'' + json.stringify(value).replace(/^\"|\"$/g, '')\n                                                   .replace(/'/g, \"\\\\'\")\n                                                   .replace(/\\\\\"/g, '\"') + '\\'';\n          return stylize(simple, 'string');\n\n        case 'number':\n          return stylize('' + value, 'number');\n\n        case 'boolean':\n          return stylize('' + value, 'boolean');\n      }\n      // For some reason typeof null is \"object\", so special case here.\n      if (value === null) {\n        return stylize('null', 'null');\n      }\n\n      if (isDOMElement(value)) {\n        return getOuterHTML(value);\n      }\n\n      // Look up the keys of the object.\n      var visible_keys = keys(value);\n      var $keys = showHidden ? Object.getOwnPropertyNames(value) : visible_keys;\n\n      // Functions without properties can be shortcutted.\n      if (typeof value === 'function' && $keys.length === 0) {\n        if (isRegExp(value)) {\n          return stylize('' + value, 'regexp');\n        } else {\n          var name = value.name ? ': ' + value.name : '';\n          return stylize('[Function' + name + ']', 'special');\n        }\n      }\n\n      // Dates without properties can be shortcutted\n      if (isDate(value) && $keys.length === 0) {\n        return stylize(value.toUTCString(), 'date');\n      }\n      \n      // Error objects can be shortcutted\n      if (value instanceof Error) {\n        return stylize(\"[\"+value.toString()+\"]\", 'Error');\n      }\n\n      var base, type, braces;\n      // Determine the object type\n      if (isArray(value)) {\n        type = 'Array';\n        braces = ['[', ']'];\n      } else {\n        type = 'Object';\n        braces = ['{', '}'];\n      }\n\n      // Make functions say that they are functions\n      if (typeof value === 'function') {\n        var n = value.name ? ': ' + value.name : '';\n        base = (isRegExp(value)) ? ' ' + value : ' [Function' + n + ']';\n      } else {\n        base = '';\n      }\n\n      // Make dates with properties first say the date\n      if (isDate(value)) {\n        base = ' ' + value.toUTCString();\n      }\n\n      if ($keys.length === 0) {\n        return braces[0] + base + braces[1];\n      }\n\n      if (recurseTimes < 0) {\n        if (isRegExp(value)) {\n          return stylize('' + value, 'regexp');\n        } else {\n          return stylize('[Object]', 'special');\n        }\n      }\n\n      seen.push(value);\n\n      var output = map($keys, function (key) {\n        var name, str;\n        if (value.__lookupGetter__) {\n          if (value.__lookupGetter__(key)) {\n            if (value.__lookupSetter__(key)) {\n              str = stylize('[Getter/Setter]', 'special');\n            } else {\n              str = stylize('[Getter]', 'special');\n            }\n          } else {\n            if (value.__lookupSetter__(key)) {\n              str = stylize('[Setter]', 'special');\n            }\n          }\n        }\n        if (indexOf(visible_keys, key) < 0) {\n          name = '[' + key + ']';\n        }\n        if (!str) {\n          if (indexOf(seen, value[key]) < 0) {\n            if (recurseTimes === null) {\n              str = format(value[key]);\n            } else {\n              str = format(value[key], recurseTimes - 1);\n            }\n            if (str.indexOf('\\n') > -1) {\n              if (isArray(value)) {\n                str = map(str.split('\\n'), function (line) {\n                  return '  ' + line;\n                }).join('\\n').substr(2);\n              } else {\n                str = '\\n' + map(str.split('\\n'), function (line) {\n                  return '   ' + line;\n                }).join('\\n');\n              }\n            }\n          } else {\n            str = stylize('[Circular]', 'special');\n          }\n        }\n        if (typeof name === 'undefined') {\n          if (type === 'Array' && key.match(/^\\d+$/)) {\n            return str;\n          }\n          name = json.stringify('' + key);\n          if (name.match(/^\"([a-zA-Z_][a-zA-Z_0-9]*)\"$/)) {\n            name = name.substr(1, name.length - 2);\n            name = stylize(name, 'name');\n          } else {\n            name = name.replace(/'/g, \"\\\\'\")\n                       .replace(/\\\\\"/g, '\"')\n                       .replace(/(^\"|\"$)/g, \"'\");\n            name = stylize(name, 'string');\n          }\n        }\n\n        return name + ': ' + str;\n      });\n\n      seen.pop();\n\n      var numLinesEst = 0;\n      var length = reduce(output, function (prev, cur) {\n        numLinesEst++;\n        if (indexOf(cur, '\\n') >= 0) numLinesEst++;\n        return prev + cur.length + 1;\n      }, 0);\n\n      if (length > 50) {\n        output = braces[0] +\n                 (base === '' ? '' : base + '\\n ') +\n                 ' ' +\n                 output.join(',\\n  ') +\n                 ' ' +\n                 braces[1];\n\n      } else {\n        output = braces[0] + base + ' ' + output.join(', ') + ' ' + braces[1];\n      }\n\n      return output;\n    }\n    return format(obj, (typeof depth === 'undefined' ? 2 : depth));\n  }\n\n  expect.stringify = i;\n\n  function isArray (ar) {\n    return Object.prototype.toString.call(ar) === '[object Array]';\n  }\n\n  function isRegExp(re) {\n    var s;\n    try {\n      s = '' + re;\n    } catch (e) {\n      return false;\n    }\n\n    return re instanceof RegExp || // easy case\n           // duck-type for context-switching evalcx case\n           typeof(re) === 'function' &&\n           re.constructor.name === 'RegExp' &&\n           re.compile &&\n           re.test &&\n           re.exec &&\n           s.match(/^\\/.*\\/[gim]{0,3}$/);\n  }\n\n  function isDate(d) {\n    return d instanceof Date;\n  }\n\n  function keys (obj) {\n    if (Object.keys) {\n      return Object.keys(obj);\n    }\n\n    var keys = [];\n\n    for (var i in obj) {\n      if (Object.prototype.hasOwnProperty.call(obj, i)) {\n        keys.push(i);\n      }\n    }\n\n    return keys;\n  }\n\n  function map (arr, mapper, that) {\n    if (Array.prototype.map) {\n      return Array.prototype.map.call(arr, mapper, that);\n    }\n\n    var other= new Array(arr.length);\n\n    for (var i= 0, n = arr.length; i<n; i++)\n      if (i in arr)\n        other[i] = mapper.call(that, arr[i], i, arr);\n\n    return other;\n  }\n\n  function reduce (arr, fun) {\n    if (Array.prototype.reduce) {\n      return Array.prototype.reduce.apply(\n          arr\n        , Array.prototype.slice.call(arguments, 1)\n      );\n    }\n\n    var len = +this.length;\n\n    if (typeof fun !== \"function\")\n      throw new TypeError();\n\n    // no value to return if no initial value and an empty array\n    if (len === 0 && arguments.length === 1)\n      throw new TypeError();\n\n    var i = 0;\n    if (arguments.length >= 2) {\n      var rv = arguments[1];\n    } else {\n      do {\n        if (i in this) {\n          rv = this[i++];\n          break;\n        }\n\n        // if array contains no values, no initial value to return\n        if (++i >= len)\n          throw new TypeError();\n      } while (true);\n    }\n\n    for (; i < len; i++) {\n      if (i in this)\n        rv = fun.call(null, rv, this[i], i, this);\n    }\n\n    return rv;\n  }\n\n  /**\n   * Asserts deep equality\n   *\n   * @see taken from node.js `assert` module (copyright Joyent, MIT license)\n   * @api private\n   */\n\n  expect.eql = function eql(actual, expected) {\n    // 7.1. All identical values are equivalent, as determined by ===.\n    if (actual === expected) {\n      return true;\n    } else if ('undefined' != typeof Buffer\n      && Buffer.isBuffer(actual) && Buffer.isBuffer(expected)) {\n      if (actual.length != expected.length) return false;\n\n      for (var i = 0; i < actual.length; i++) {\n        if (actual[i] !== expected[i]) return false;\n      }\n\n      return true;\n\n      // 7.2. If the expected value is a Date object, the actual value is\n      // equivalent if it is also a Date object that refers to the same time.\n    } else if (actual instanceof Date && expected instanceof Date) {\n      return actual.getTime() === expected.getTime();\n\n      // 7.3. Other pairs that do not both pass typeof value == \"object\",\n      // equivalence is determined by ==.\n    } else if (typeof actual != 'object' && typeof expected != 'object') {\n      return actual == expected;\n    // If both are regular expression use the special `regExpEquiv` method\n    // to determine equivalence.\n    } else if (isRegExp(actual) && isRegExp(expected)) {\n      return regExpEquiv(actual, expected);\n    // 7.4. For all other Object pairs, including Array objects, equivalence is\n    // determined by having the same number of owned properties (as verified\n    // with Object.prototype.hasOwnProperty.call), the same set of keys\n    // (although not necessarily the same order), equivalent values for every\n    // corresponding key, and an identical \"prototype\" property. Note: this\n    // accounts for both named and indexed properties on Arrays.\n    } else {\n      return objEquiv(actual, expected);\n    }\n  };\n\n  function isUndefinedOrNull (value) {\n    return value === null || value === undefined;\n  }\n\n  function isArguments (object) {\n    return Object.prototype.toString.call(object) == '[object Arguments]';\n  }\n\n  function regExpEquiv (a, b) {\n    return a.source === b.source && a.global === b.global &&\n           a.ignoreCase === b.ignoreCase && a.multiline === b.multiline;\n  }\n\n  function objEquiv (a, b) {\n    if (isUndefinedOrNull(a) || isUndefinedOrNull(b))\n      return false;\n    // an identical \"prototype\" property.\n    if (a.prototype !== b.prototype) return false;\n    //~~~I've managed to break Object.keys through screwy arguments passing.\n    //   Converting to array solves the problem.\n    if (isArguments(a)) {\n      if (!isArguments(b)) {\n        return false;\n      }\n      a = pSlice.call(a);\n      b = pSlice.call(b);\n      return expect.eql(a, b);\n    }\n    try{\n      var ka = keys(a),\n        kb = keys(b),\n        key, i;\n    } catch (e) {//happens when one is a string literal and the other isn't\n      return false;\n    }\n    // having the same number of owned properties (keys incorporates hasOwnProperty)\n    if (ka.length != kb.length)\n      return false;\n    //the same set of keys (although not necessarily the same order),\n    ka.sort();\n    kb.sort();\n    //~~~cheap key test\n    for (i = ka.length - 1; i >= 0; i--) {\n      if (ka[i] != kb[i])\n        return false;\n    }\n    //equivalent values for every corresponding key, and\n    //~~~possibly expensive deep test\n    for (i = ka.length - 1; i >= 0; i--) {\n      key = ka[i];\n      if (!expect.eql(a[key], b[key]))\n         return false;\n    }\n    return true;\n  }\n\n  var json = (function () {\n    \"use strict\";\n\n    if ('object' == typeof JSON && JSON.parse && JSON.stringify) {\n      return {\n          parse: nativeJSON.parse\n        , stringify: nativeJSON.stringify\n      }\n    }\n\n    var JSON = {};\n\n    function f(n) {\n        // Format integers to have at least two digits.\n        return n < 10 ? '0' + n : n;\n    }\n\n    function date(d, key) {\n      return isFinite(d.valueOf()) ?\n          d.getUTCFullYear()     + '-' +\n          f(d.getUTCMonth() + 1) + '-' +\n          f(d.getUTCDate())      + 'T' +\n          f(d.getUTCHours())     + ':' +\n          f(d.getUTCMinutes())   + ':' +\n          f(d.getUTCSeconds())   + 'Z' : null;\n    }\n\n    var cx = /[\\u0000\\u00ad\\u0600-\\u0604\\u070f\\u17b4\\u17b5\\u200c-\\u200f\\u2028-\\u202f\\u2060-\\u206f\\ufeff\\ufff0-\\uffff]/g,\n        escapable = /[\\\\\\\"\\x00-\\x1f\\x7f-\\x9f\\u00ad\\u0600-\\u0604\\u070f\\u17b4\\u17b5\\u200c-\\u200f\\u2028-\\u202f\\u2060-\\u206f\\ufeff\\ufff0-\\uffff]/g,\n        gap,\n        indent,\n        meta = {    // table of character substitutions\n            '\\b': '\\\\b',\n            '\\t': '\\\\t',\n            '\\n': '\\\\n',\n            '\\f': '\\\\f',\n            '\\r': '\\\\r',\n            '\"' : '\\\\\"',\n            '\\\\': '\\\\\\\\'\n        },\n        rep;\n\n\n    function quote(string) {\n\n  // If the string contains no control characters, no quote characters, and no\n  // backslash characters, then we can safely slap some quotes around it.\n  // Otherwise we must also replace the offending characters with safe escape\n  // sequences.\n\n        escapable.lastIndex = 0;\n        return escapable.test(string) ? '\"' + string.replace(escapable, function (a) {\n            var c = meta[a];\n            return typeof c === 'string' ? c :\n                '\\\\u' + ('0000' + a.charCodeAt(0).toString(16)).slice(-4);\n        }) + '\"' : '\"' + string + '\"';\n    }\n\n\n    function str(key, holder) {\n\n  // Produce a string from holder[key].\n\n        var i,          // The loop counter.\n            k,          // The member key.\n            v,          // The member value.\n            length,\n            mind = gap,\n            partial,\n            value = holder[key];\n\n  // If the value has a toJSON method, call it to obtain a replacement value.\n\n        if (value instanceof Date) {\n            value = date(key);\n        }\n\n  // If we were called with a replacer function, then call the replacer to\n  // obtain a replacement value.\n\n        if (typeof rep === 'function') {\n            value = rep.call(holder, key, value);\n        }\n\n  // What happens next depends on the value's type.\n\n        switch (typeof value) {\n        case 'string':\n            return quote(value);\n\n        case 'number':\n\n  // JSON numbers must be finite. Encode non-finite numbers as null.\n\n            return isFinite(value) ? String(value) : 'null';\n\n        case 'boolean':\n        case 'null':\n\n  // If the value is a boolean or null, convert it to a string. Note:\n  // typeof null does not produce 'null'. The case is included here in\n  // the remote chance that this gets fixed someday.\n\n            return String(value);\n\n  // If the type is 'object', we might be dealing with an object or an array or\n  // null.\n\n        case 'object':\n\n  // Due to a specification blunder in ECMAScript, typeof null is 'object',\n  // so watch out for that case.\n\n            if (!value) {\n                return 'null';\n            }\n\n  // Make an array to hold the partial results of stringifying this object value.\n\n            gap += indent;\n            partial = [];\n\n  // Is the value an array?\n\n            if (Object.prototype.toString.apply(value) === '[object Array]') {\n\n  // The value is an array. Stringify every element. Use null as a placeholder\n  // for non-JSON values.\n\n                length = value.length;\n                for (i = 0; i < length; i += 1) {\n                    partial[i] = str(i, value) || 'null';\n                }\n\n  // Join all of the elements together, separated with commas, and wrap them in\n  // brackets.\n\n                v = partial.length === 0 ? '[]' : gap ?\n                    '[\\n' + gap + partial.join(',\\n' + gap) + '\\n' + mind + ']' :\n                    '[' + partial.join(',') + ']';\n                gap = mind;\n                return v;\n            }\n\n  // If the replacer is an array, use it to select the members to be stringified.\n\n            if (rep && typeof rep === 'object') {\n                length = rep.length;\n                for (i = 0; i < length; i += 1) {\n                    if (typeof rep[i] === 'string') {\n                        k = rep[i];\n                        v = str(k, value);\n                        if (v) {\n                            partial.push(quote(k) + (gap ? ': ' : ':') + v);\n                        }\n                    }\n                }\n            } else {\n\n  // Otherwise, iterate through all of the keys in the object.\n\n                for (k in value) {\n                    if (Object.prototype.hasOwnProperty.call(value, k)) {\n                        v = str(k, value);\n                        if (v) {\n                            partial.push(quote(k) + (gap ? ': ' : ':') + v);\n                        }\n                    }\n                }\n            }\n\n  // Join all of the member texts together, separated with commas,\n  // and wrap them in braces.\n\n            v = partial.length === 0 ? '{}' : gap ?\n                '{\\n' + gap + partial.join(',\\n' + gap) + '\\n' + mind + '}' :\n                '{' + partial.join(',') + '}';\n            gap = mind;\n            return v;\n        }\n    }\n\n  // If the JSON object does not yet have a stringify method, give it one.\n\n    JSON.stringify = function (value, replacer, space) {\n\n  // The stringify method takes a value and an optional replacer, and an optional\n  // space parameter, and returns a JSON text. The replacer can be a function\n  // that can replace values, or an array of strings that will select the keys.\n  // A default replacer method can be provided. Use of the space parameter can\n  // produce text that is more easily readable.\n\n        var i;\n        gap = '';\n        indent = '';\n\n  // If the space parameter is a number, make an indent string containing that\n  // many spaces.\n\n        if (typeof space === 'number') {\n            for (i = 0; i < space; i += 1) {\n                indent += ' ';\n            }\n\n  // If the space parameter is a string, it will be used as the indent string.\n\n        } else if (typeof space === 'string') {\n            indent = space;\n        }\n\n  // If there is a replacer, it must be a function or an array.\n  // Otherwise, throw an error.\n\n        rep = replacer;\n        if (replacer && typeof replacer !== 'function' &&\n                (typeof replacer !== 'object' ||\n                typeof replacer.length !== 'number')) {\n            throw new Error('JSON.stringify');\n        }\n\n  // Make a fake root object containing our value under the key of ''.\n  // Return the result of stringifying the value.\n\n        return str('', {'': value});\n    };\n\n  // If the JSON object does not yet have a parse method, give it one.\n\n    JSON.parse = function (text, reviver) {\n    // The parse method takes a text and an optional reviver function, and returns\n    // a JavaScript value if the text is a valid JSON text.\n\n        var j;\n\n        function walk(holder, key) {\n\n    // The walk method is used to recursively walk the resulting structure so\n    // that modifications can be made.\n\n            var k, v, value = holder[key];\n            if (value && typeof value === 'object') {\n                for (k in value) {\n                    if (Object.prototype.hasOwnProperty.call(value, k)) {\n                        v = walk(value, k);\n                        if (v !== undefined) {\n                            value[k] = v;\n                        } else {\n                            delete value[k];\n                        }\n                    }\n                }\n            }\n            return reviver.call(holder, key, value);\n        }\n\n\n    // Parsing happens in four stages. In the first stage, we replace certain\n    // Unicode characters with escape sequences. JavaScript handles many characters\n    // incorrectly, either silently deleting them, or treating them as line endings.\n\n        text = String(text);\n        cx.lastIndex = 0;\n        if (cx.test(text)) {\n            text = text.replace(cx, function (a) {\n                return '\\\\u' +\n                    ('0000' + a.charCodeAt(0).toString(16)).slice(-4);\n            });\n        }\n\n    // In the second stage, we run the text against regular expressions that look\n    // for non-JSON patterns. We are especially concerned with '()' and 'new'\n    // because they can cause invocation, and '=' because it can cause mutation.\n    // But just to be safe, we want to reject all unexpected forms.\n\n    // We split the second stage into 4 regexp operations in order to work around\n    // crippling inefficiencies in IE's and Safari's regexp engines. First we\n    // replace the JSON backslash pairs with '@' (a non-JSON character). Second, we\n    // replace all simple value tokens with ']' characters. Third, we delete all\n    // open brackets that follow a colon or comma or that begin the text. Finally,\n    // we look to see that the remaining characters are only whitespace or ']' or\n    // ',' or ':' or '{' or '}'. If that is so, then the text is safe for eval.\n\n        if (/^[\\],:{}\\s]*$/\n                .test(text.replace(/\\\\(?:[\"\\\\\\/bfnrt]|u[0-9a-fA-F]{4})/g, '@')\n                    .replace(/\"[^\"\\\\\\n\\r]*\"|true|false|null|-?\\d+(?:\\.\\d*)?(?:[eE][+\\-]?\\d+)?/g, ']')\n                    .replace(/(?:^|:|,)(?:\\s*\\[)+/g, ''))) {\n\n    // In the third stage we use the eval function to compile the text into a\n    // JavaScript structure. The '{' operator is subject to a syntactic ambiguity\n    // in JavaScript: it can begin a block or an object literal. We wrap the text\n    // in parens to eliminate the ambiguity.\n\n            j = eval('(' + text + ')');\n\n    // In the optional fourth stage, we recursively walk the new structure, passing\n    // each name/value pair to a reviver function for possible transformation.\n\n            return typeof reviver === 'function' ?\n                walk({'': j}, '') : j;\n        }\n\n    // If the text is not JSON parseable, then a SyntaxError is thrown.\n\n        throw new SyntaxError('JSON.parse');\n    };\n\n    return JSON;\n  })();\n\n  if ('undefined' != typeof window) {\n    window.expect = module.exports;\n  }\n\n})(\n    this\n  , 'undefined' != typeof module ? module : {exports: {}}\n);\n"
  },
  {
    "path": "app_frontend/static/plugin/JavaScript-Templates/test/vendor/mocha.css",
    "content": "@charset \"utf-8\";\n\nbody {\n  margin:0;\n}\n\n#mocha {\n  font: 20px/1.5 \"Helvetica Neue\", Helvetica, Arial, sans-serif;\n  margin: 60px 50px;\n}\n\n#mocha ul,\n#mocha li {\n  margin: 0;\n  padding: 0;\n}\n\n#mocha ul {\n  list-style: none;\n}\n\n#mocha h1,\n#mocha h2 {\n  margin: 0;\n}\n\n#mocha h1 {\n  margin-top: 15px;\n  font-size: 1em;\n  font-weight: 200;\n}\n\n#mocha h1 a {\n  text-decoration: none;\n  color: inherit;\n}\n\n#mocha h1 a:hover {\n  text-decoration: underline;\n}\n\n#mocha .suite .suite h1 {\n  margin-top: 0;\n  font-size: .8em;\n}\n\n#mocha .hidden {\n  display: none;\n}\n\n#mocha h2 {\n  font-size: 12px;\n  font-weight: normal;\n  cursor: pointer;\n}\n\n#mocha .suite {\n  margin-left: 15px;\n}\n\n#mocha .test {\n  margin-left: 15px;\n  overflow: hidden;\n}\n\n#mocha .test.pending:hover h2::after {\n  content: '(pending)';\n  font-family: arial, sans-serif;\n}\n\n#mocha .test.pass.medium .duration {\n  background: #c09853;\n}\n\n#mocha .test.pass.slow .duration {\n  background: #b94a48;\n}\n\n#mocha .test.pass::before {\n  content: '✓';\n  font-size: 12px;\n  display: block;\n  float: left;\n  margin-right: 5px;\n  color: #00d6b2;\n}\n\n#mocha .test.pass .duration {\n  font-size: 9px;\n  margin-left: 5px;\n  padding: 2px 5px;\n  color: #fff;\n  -webkit-box-shadow: inset 0 1px 1px rgba(0,0,0,.2);\n  -moz-box-shadow: inset 0 1px 1px rgba(0,0,0,.2);\n  box-shadow: inset 0 1px 1px rgba(0,0,0,.2);\n  -webkit-border-radius: 5px;\n  -moz-border-radius: 5px;\n  -ms-border-radius: 5px;\n  -o-border-radius: 5px;\n  border-radius: 5px;\n}\n\n#mocha .test.pass.fast .duration {\n  display: none;\n}\n\n#mocha .test.pending {\n  color: #0b97c4;\n}\n\n#mocha .test.pending::before {\n  content: '◦';\n  color: #0b97c4;\n}\n\n#mocha .test.fail {\n  color: #c00;\n}\n\n#mocha .test.fail pre {\n  color: black;\n}\n\n#mocha .test.fail::before {\n  content: '✖';\n  font-size: 12px;\n  display: block;\n  float: left;\n  margin-right: 5px;\n  color: #c00;\n}\n\n#mocha .test pre.error {\n  color: #c00;\n  max-height: 300px;\n  overflow: auto;\n}\n\n#mocha .test .html-error {\n  overflow: auto;\n  color: black;\n  line-height: 1.5;\n  display: block;\n  float: left;\n  clear: left;\n  font: 12px/1.5 monaco, monospace;\n  margin: 5px;\n  padding: 15px;\n  border: 1px solid #eee;\n  max-width: 85%; /*(1)*/\n  max-width: calc(100% - 42px); /*(2)*/\n  max-height: 300px;\n  word-wrap: break-word;\n  border-bottom-color: #ddd;\n  -webkit-border-radius: 3px;\n  -webkit-box-shadow: 0 1px 3px #eee;\n  -moz-border-radius: 3px;\n  -moz-box-shadow: 0 1px 3px #eee;\n  border-radius: 3px;\n}\n\n#mocha .test .html-error pre.error {\n  border: none;\n  -webkit-border-radius: none;\n  -webkit-box-shadow: none;\n  -moz-border-radius: none;\n  -moz-box-shadow: none;\n  padding: 0;\n  margin: 0;\n  margin-top: 18px;\n  max-height: none;\n}\n\n/**\n * (1): approximate for browsers not supporting calc\n * (2): 42 = 2*15 + 2*10 + 2*1 (padding + margin + border)\n *      ^^ seriously\n */\n#mocha .test pre {\n  display: block;\n  float: left;\n  clear: left;\n  font: 12px/1.5 monaco, monospace;\n  margin: 5px;\n  padding: 15px;\n  border: 1px solid #eee;\n  max-width: 85%; /*(1)*/\n  max-width: calc(100% - 42px); /*(2)*/\n  word-wrap: break-word;\n  border-bottom-color: #ddd;\n  -webkit-border-radius: 3px;\n  -webkit-box-shadow: 0 1px 3px #eee;\n  -moz-border-radius: 3px;\n  -moz-box-shadow: 0 1px 3px #eee;\n  border-radius: 3px;\n}\n\n#mocha .test h2 {\n  position: relative;\n}\n\n#mocha .test a.replay {\n  position: absolute;\n  top: 3px;\n  right: 0;\n  text-decoration: none;\n  vertical-align: middle;\n  display: block;\n  width: 15px;\n  height: 15px;\n  line-height: 15px;\n  text-align: center;\n  background: #eee;\n  font-size: 15px;\n  -moz-border-radius: 15px;\n  border-radius: 15px;\n  -webkit-transition: opacity 200ms;\n  -moz-transition: opacity 200ms;\n  transition: opacity 200ms;\n  opacity: 0.3;\n  color: #888;\n}\n\n#mocha .test:hover a.replay {\n  opacity: 1;\n}\n\n#mocha-report.pass .test.fail {\n  display: none;\n}\n\n#mocha-report.fail .test.pass {\n  display: none;\n}\n\n#mocha-report.pending .test.pass,\n#mocha-report.pending .test.fail {\n  display: none;\n}\n#mocha-report.pending .test.pass.pending {\n  display: block;\n}\n\n#mocha-error {\n  color: #c00;\n  font-size: 1.5em;\n  font-weight: 100;\n  letter-spacing: 1px;\n}\n\n#mocha-stats {\n  position: fixed;\n  top: 15px;\n  right: 10px;\n  font-size: 12px;\n  margin: 0;\n  color: #888;\n  z-index: 1;\n}\n\n#mocha-stats .progress {\n  float: right;\n  padding-top: 0;\n}\n\n#mocha-stats em {\n  color: black;\n}\n\n#mocha-stats a {\n  text-decoration: none;\n  color: inherit;\n}\n\n#mocha-stats a:hover {\n  border-bottom: 1px solid #eee;\n}\n\n#mocha-stats li {\n  display: inline-block;\n  margin: 0 5px;\n  list-style: none;\n  padding-top: 11px;\n}\n\n#mocha-stats canvas {\n  width: 40px;\n  height: 40px;\n}\n\n#mocha code .comment { color: #ddd; }\n#mocha code .init { color: #2f6fad; }\n#mocha code .string { color: #5890ad; }\n#mocha code .keyword { color: #8a6343; }\n#mocha code .number { color: #2f6fad; }\n\n@media screen and (max-device-width: 480px) {\n  #mocha {\n    margin: 60px 0px;\n  }\n\n  #mocha #stats {\n    position: absolute;\n  }\n}\n"
  },
  {
    "path": "app_frontend/static/plugin/JavaScript-Templates/test/vendor/mocha.js",
    "content": "(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require==\"function\"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error(\"Cannot find module '\"+o+\"'\");throw f.code=\"MODULE_NOT_FOUND\",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require==\"function\"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){\n(function (process){\nmodule.exports = process.env.COV\n  ? require('./lib-cov/mocha')\n  : require('./lib/mocha');\n\n}).call(this,require('_process'))\n},{\"./lib-cov/mocha\":undefined,\"./lib/mocha\":14,\"_process\":51}],2:[function(require,module,exports){\n/* eslint-disable no-unused-vars */\nmodule.exports = function(type) {\n  return function() {};\n};\n\n},{}],3:[function(require,module,exports){\n/**\n * Module exports.\n */\n\nexports.EventEmitter = EventEmitter;\n\n/**\n * Object#hasOwnProperty reference.\n */\nvar objToString = Object.prototype.toString;\n\n/**\n * Check if a value is an array.\n *\n * @api private\n * @param {*} val The value to test.\n * @return {boolean} true if the value is a boolean, otherwise false.\n */\nfunction isArray(val) {\n  return objToString.call(val) === '[object Array]';\n}\n\n/**\n * Event emitter constructor.\n *\n * @api public\n */\nfunction EventEmitter() {}\n\n/**\n * Add a listener.\n *\n * @api public\n * @param {string} name Event name.\n * @param {Function} fn Event handler.\n * @return {EventEmitter} Emitter instance.\n */\nEventEmitter.prototype.on = function(name, fn) {\n  if (!this.$events) {\n    this.$events = {};\n  }\n\n  if (!this.$events[name]) {\n    this.$events[name] = fn;\n  } else if (isArray(this.$events[name])) {\n    this.$events[name].push(fn);\n  } else {\n    this.$events[name] = [this.$events[name], fn];\n  }\n\n  return this;\n};\n\nEventEmitter.prototype.addListener = EventEmitter.prototype.on;\n\n/**\n * Adds a volatile listener.\n *\n * @api public\n * @param {string} name Event name.\n * @param {Function} fn Event handler.\n * @return {EventEmitter} Emitter instance.\n */\nEventEmitter.prototype.once = function(name, fn) {\n  var self = this;\n\n  function on() {\n    self.removeListener(name, on);\n    fn.apply(this, arguments);\n  }\n\n  on.listener = fn;\n  this.on(name, on);\n\n  return this;\n};\n\n/**\n * Remove a listener.\n *\n * @api public\n * @param {string} name Event name.\n * @param {Function} fn Event handler.\n * @return {EventEmitter} Emitter instance.\n */\nEventEmitter.prototype.removeListener = function(name, fn) {\n  if (this.$events && this.$events[name]) {\n    var list = this.$events[name];\n\n    if (isArray(list)) {\n      var pos = -1;\n\n      for (var i = 0, l = list.length; i < l; i++) {\n        if (list[i] === fn || (list[i].listener && list[i].listener === fn)) {\n          pos = i;\n          break;\n        }\n      }\n\n      if (pos < 0) {\n        return this;\n      }\n\n      list.splice(pos, 1);\n\n      if (!list.length) {\n        delete this.$events[name];\n      }\n    } else if (list === fn || (list.listener && list.listener === fn)) {\n      delete this.$events[name];\n    }\n  }\n\n  return this;\n};\n\n/**\n * Remove all listeners for an event.\n *\n * @api public\n * @param {string} name Event name.\n * @return {EventEmitter} Emitter instance.\n */\nEventEmitter.prototype.removeAllListeners = function(name) {\n  if (name === undefined) {\n    this.$events = {};\n    return this;\n  }\n\n  if (this.$events && this.$events[name]) {\n    this.$events[name] = null;\n  }\n\n  return this;\n};\n\n/**\n * Get all listeners for a given event.\n *\n * @api public\n * @param {string} name Event name.\n * @return {EventEmitter} Emitter instance.\n */\nEventEmitter.prototype.listeners = function(name) {\n  if (!this.$events) {\n    this.$events = {};\n  }\n\n  if (!this.$events[name]) {\n    this.$events[name] = [];\n  }\n\n  if (!isArray(this.$events[name])) {\n    this.$events[name] = [this.$events[name]];\n  }\n\n  return this.$events[name];\n};\n\n/**\n * Emit an event.\n *\n * @api public\n * @param {string} name Event name.\n * @return {boolean} true if at least one handler was invoked, else false.\n */\nEventEmitter.prototype.emit = function(name) {\n  if (!this.$events) {\n    return false;\n  }\n\n  var handler = this.$events[name];\n\n  if (!handler) {\n    return false;\n  }\n\n  var args = Array.prototype.slice.call(arguments, 1);\n\n  if (typeof handler === 'function') {\n    handler.apply(this, args);\n  } else if (isArray(handler)) {\n    var listeners = handler.slice();\n\n    for (var i = 0, l = listeners.length; i < l; i++) {\n      listeners[i].apply(this, args);\n    }\n  } else {\n    return false;\n  }\n\n  return true;\n};\n\n},{}],4:[function(require,module,exports){\n/**\n * Expose `Progress`.\n */\n\nmodule.exports = Progress;\n\n/**\n * Initialize a new `Progress` indicator.\n */\nfunction Progress() {\n  this.percent = 0;\n  this.size(0);\n  this.fontSize(11);\n  this.font('helvetica, arial, sans-serif');\n}\n\n/**\n * Set progress size to `size`.\n *\n * @api public\n * @param {number} size\n * @return {Progress} Progress instance.\n */\nProgress.prototype.size = function(size) {\n  this._size = size;\n  return this;\n};\n\n/**\n * Set text to `text`.\n *\n * @api public\n * @param {string} text\n * @return {Progress} Progress instance.\n */\nProgress.prototype.text = function(text) {\n  this._text = text;\n  return this;\n};\n\n/**\n * Set font size to `size`.\n *\n * @api public\n * @param {number} size\n * @return {Progress} Progress instance.\n */\nProgress.prototype.fontSize = function(size) {\n  this._fontSize = size;\n  return this;\n};\n\n/**\n * Set font to `family`.\n *\n * @param {string} family\n * @return {Progress} Progress instance.\n */\nProgress.prototype.font = function(family) {\n  this._font = family;\n  return this;\n};\n\n/**\n * Update percentage to `n`.\n *\n * @param {number} n\n * @return {Progress} Progress instance.\n */\nProgress.prototype.update = function(n) {\n  this.percent = n;\n  return this;\n};\n\n/**\n * Draw on `ctx`.\n *\n * @param {CanvasRenderingContext2d} ctx\n * @return {Progress} Progress instance.\n */\nProgress.prototype.draw = function(ctx) {\n  try {\n    var percent = Math.min(this.percent, 100);\n    var size = this._size;\n    var half = size / 2;\n    var x = half;\n    var y = half;\n    var rad = half - 1;\n    var fontSize = this._fontSize;\n\n    ctx.font = fontSize + 'px ' + this._font;\n\n    var angle = Math.PI * 2 * (percent / 100);\n    ctx.clearRect(0, 0, size, size);\n\n    // outer circle\n    ctx.strokeStyle = '#9f9f9f';\n    ctx.beginPath();\n    ctx.arc(x, y, rad, 0, angle, false);\n    ctx.stroke();\n\n    // inner circle\n    ctx.strokeStyle = '#eee';\n    ctx.beginPath();\n    ctx.arc(x, y, rad - 1, 0, angle, true);\n    ctx.stroke();\n\n    // text\n    var text = this._text || (percent | 0) + '%';\n    var w = ctx.measureText(text).width;\n\n    ctx.fillText(text, x - w / 2 + 1, y + fontSize / 2 - 1);\n  } catch (err) {\n    // don't fail if we can't render progress\n  }\n  return this;\n};\n\n},{}],5:[function(require,module,exports){\n(function (global){\nexports.isatty = function isatty() {\n  return true;\n};\n\nexports.getWindowSize = function getWindowSize() {\n  if ('innerHeight' in global) {\n    return [global.innerHeight, global.innerWidth];\n  }\n  // In a Web Worker, the DOM Window is not available.\n  return [640, 480];\n};\n\n}).call(this,typeof global !== \"undefined\" ? global : typeof self !== \"undefined\" ? self : typeof window !== \"undefined\" ? window : {})\n},{}],6:[function(require,module,exports){\n/**\n * Expose `Context`.\n */\n\nmodule.exports = Context;\n\n/**\n * Initialize a new `Context`.\n *\n * @api private\n */\nfunction Context() {}\n\n/**\n * Set or get the context `Runnable` to `runnable`.\n *\n * @api private\n * @param {Runnable} runnable\n * @return {Context}\n */\nContext.prototype.runnable = function(runnable) {\n  if (!arguments.length) {\n    return this._runnable;\n  }\n  this.test = this._runnable = runnable;\n  return this;\n};\n\n/**\n * Set test timeout `ms`.\n *\n * @api private\n * @param {number} ms\n * @return {Context} self\n */\nContext.prototype.timeout = function(ms) {\n  if (!arguments.length) {\n    return this.runnable().timeout();\n  }\n  this.runnable().timeout(ms);\n  return this;\n};\n\n/**\n * Set test timeout `enabled`.\n *\n * @api private\n * @param {boolean} enabled\n * @return {Context} self\n */\nContext.prototype.enableTimeouts = function(enabled) {\n  this.runnable().enableTimeouts(enabled);\n  return this;\n};\n\n/**\n * Set test slowness threshold `ms`.\n *\n * @api private\n * @param {number} ms\n * @return {Context} self\n */\nContext.prototype.slow = function(ms) {\n  this.runnable().slow(ms);\n  return this;\n};\n\n/**\n * Mark a test as skipped.\n *\n * @api private\n * @return {Context} self\n */\nContext.prototype.skip = function() {\n  this.runnable().skip();\n  return this;\n};\n\n/**\n * Inspect the context void of `._runnable`.\n *\n * @api private\n * @return {string}\n */\nContext.prototype.inspect = function() {\n  return JSON.stringify(this, function(key, val) {\n    return key === 'runnable' || key === 'test' ? undefined : val;\n  }, 2);\n};\n\n},{}],7:[function(require,module,exports){\n/**\n * Module dependencies.\n */\n\nvar Runnable = require('./runnable');\nvar inherits = require('./utils').inherits;\n\n/**\n * Expose `Hook`.\n */\n\nmodule.exports = Hook;\n\n/**\n * Initialize a new `Hook` with the given `title` and callback `fn`.\n *\n * @param {String} title\n * @param {Function} fn\n * @api private\n */\nfunction Hook(title, fn) {\n  Runnable.call(this, title, fn);\n  this.type = 'hook';\n}\n\n/**\n * Inherit from `Runnable.prototype`.\n */\ninherits(Hook, Runnable);\n\n/**\n * Get or set the test `err`.\n *\n * @param {Error} err\n * @return {Error}\n * @api public\n */\nHook.prototype.error = function(err) {\n  if (!arguments.length) {\n    err = this._error;\n    this._error = null;\n    return err;\n  }\n\n  this._error = err;\n};\n\n},{\"./runnable\":35,\"./utils\":39}],8:[function(require,module,exports){\n/**\n * Module dependencies.\n */\n\nvar Suite = require('../suite');\nvar Test = require('../test');\nvar escapeRe = require('escape-string-regexp');\n\n/**\n * BDD-style interface:\n *\n *      describe('Array', function() {\n *        describe('#indexOf()', function() {\n *          it('should return -1 when not present', function() {\n *            // ...\n *          });\n *\n *          it('should return the index when present', function() {\n *            // ...\n *          });\n *        });\n *      });\n *\n * @param {Suite} suite Root suite.\n */\nmodule.exports = function(suite) {\n  var suites = [suite];\n\n  suite.on('pre-require', function(context, file, mocha) {\n    var common = require('./common')(suites, context);\n\n    context.before = common.before;\n    context.after = common.after;\n    context.beforeEach = common.beforeEach;\n    context.afterEach = common.afterEach;\n    context.run = mocha.options.delay && common.runWithSuite(suite);\n    /**\n     * Describe a \"suite\" with the given `title`\n     * and callback `fn` containing nested suites\n     * and/or tests.\n     */\n\n    context.describe = context.context = function(title, fn) {\n      var suite = Suite.create(suites[0], title);\n      suite.file = file;\n      suites.unshift(suite);\n      fn.call(suite);\n      suites.shift();\n      return suite;\n    };\n\n    /**\n     * Pending describe.\n     */\n\n    context.xdescribe = context.xcontext = context.describe.skip = function(title, fn) {\n      var suite = Suite.create(suites[0], title);\n      suite.pending = true;\n      suites.unshift(suite);\n      fn.call(suite);\n      suites.shift();\n    };\n\n    /**\n     * Exclusive suite.\n     */\n\n    context.describe.only = function(title, fn) {\n      var suite = context.describe(title, fn);\n      mocha.grep(suite.fullTitle());\n      return suite;\n    };\n\n    /**\n     * Describe a specification or test-case\n     * with the given `title` and callback `fn`\n     * acting as a thunk.\n     */\n\n    context.it = context.specify = function(title, fn) {\n      var suite = suites[0];\n      if (suite.pending) {\n        fn = null;\n      }\n      var test = new Test(title, fn);\n      test.file = file;\n      suite.addTest(test);\n      return test;\n    };\n\n    /**\n     * Exclusive test-case.\n     */\n\n    context.it.only = function(title, fn) {\n      var test = context.it(title, fn);\n      var reString = '^' + escapeRe(test.fullTitle()) + '$';\n      mocha.grep(new RegExp(reString));\n      return test;\n    };\n\n    /**\n     * Pending test case.\n     */\n\n    context.xit = context.xspecify = context.it.skip = function(title) {\n      context.it(title);\n    };\n  });\n};\n\n},{\"../suite\":37,\"../test\":38,\"./common\":9,\"escape-string-regexp\":68}],9:[function(require,module,exports){\n'use strict';\n\n/**\n * Functions common to more than one interface.\n *\n * @param {Suite[]} suites\n * @param {Context} context\n * @return {Object} An object containing common functions.\n */\nmodule.exports = function(suites, context) {\n  return {\n    /**\n     * This is only present if flag --delay is passed into Mocha. It triggers\n     * root suite execution.\n     *\n     * @param {Suite} suite The root wuite.\n     * @return {Function} A function which runs the root suite\n     */\n    runWithSuite: function runWithSuite(suite) {\n      return function run() {\n        suite.run();\n      };\n    },\n\n    /**\n     * Execute before running tests.\n     *\n     * @param {string} name\n     * @param {Function} fn\n     */\n    before: function(name, fn) {\n      suites[0].beforeAll(name, fn);\n    },\n\n    /**\n     * Execute after running tests.\n     *\n     * @param {string} name\n     * @param {Function} fn\n     */\n    after: function(name, fn) {\n      suites[0].afterAll(name, fn);\n    },\n\n    /**\n     * Execute before each test case.\n     *\n     * @param {string} name\n     * @param {Function} fn\n     */\n    beforeEach: function(name, fn) {\n      suites[0].beforeEach(name, fn);\n    },\n\n    /**\n     * Execute after each test case.\n     *\n     * @param {string} name\n     * @param {Function} fn\n     */\n    afterEach: function(name, fn) {\n      suites[0].afterEach(name, fn);\n    },\n\n    test: {\n      /**\n       * Pending test case.\n       *\n       * @param {string} title\n       */\n      skip: function(title) {\n        context.test(title);\n      }\n    }\n  };\n};\n\n},{}],10:[function(require,module,exports){\n/**\n * Module dependencies.\n */\n\nvar Suite = require('../suite');\nvar Test = require('../test');\n\n/**\n * TDD-style interface:\n *\n *     exports.Array = {\n *       '#indexOf()': {\n *         'should return -1 when the value is not present': function() {\n *\n *         },\n *\n *         'should return the correct index when the value is present': function() {\n *\n *         }\n *       }\n *     };\n *\n * @param {Suite} suite Root suite.\n */\nmodule.exports = function(suite) {\n  var suites = [suite];\n\n  suite.on('require', visit);\n\n  function visit(obj, file) {\n    var suite;\n    for (var key in obj) {\n      if (typeof obj[key] === 'function') {\n        var fn = obj[key];\n        switch (key) {\n          case 'before':\n            suites[0].beforeAll(fn);\n            break;\n          case 'after':\n            suites[0].afterAll(fn);\n            break;\n          case 'beforeEach':\n            suites[0].beforeEach(fn);\n            break;\n          case 'afterEach':\n            suites[0].afterEach(fn);\n            break;\n          default:\n            var test = new Test(key, fn);\n            test.file = file;\n            suites[0].addTest(test);\n        }\n      } else {\n        suite = Suite.create(suites[0], key);\n        suites.unshift(suite);\n        visit(obj[key]);\n        suites.shift();\n      }\n    }\n  }\n};\n\n},{\"../suite\":37,\"../test\":38}],11:[function(require,module,exports){\nexports.bdd = require('./bdd');\nexports.tdd = require('./tdd');\nexports.qunit = require('./qunit');\nexports.exports = require('./exports');\n\n},{\"./bdd\":8,\"./exports\":10,\"./qunit\":12,\"./tdd\":13}],12:[function(require,module,exports){\n/**\n * Module dependencies.\n */\n\nvar Suite = require('../suite');\nvar Test = require('../test');\nvar escapeRe = require('escape-string-regexp');\n\n/**\n * QUnit-style interface:\n *\n *     suite('Array');\n *\n *     test('#length', function() {\n *       var arr = [1,2,3];\n *       ok(arr.length == 3);\n *     });\n *\n *     test('#indexOf()', function() {\n *       var arr = [1,2,3];\n *       ok(arr.indexOf(1) == 0);\n *       ok(arr.indexOf(2) == 1);\n *       ok(arr.indexOf(3) == 2);\n *     });\n *\n *     suite('String');\n *\n *     test('#length', function() {\n *       ok('foo'.length == 3);\n *     });\n *\n * @param {Suite} suite Root suite.\n */\nmodule.exports = function(suite) {\n  var suites = [suite];\n\n  suite.on('pre-require', function(context, file, mocha) {\n    var common = require('./common')(suites, context);\n\n    context.before = common.before;\n    context.after = common.after;\n    context.beforeEach = common.beforeEach;\n    context.afterEach = common.afterEach;\n    context.run = mocha.options.delay && common.runWithSuite(suite);\n    /**\n     * Describe a \"suite\" with the given `title`.\n     */\n\n    context.suite = function(title) {\n      if (suites.length > 1) {\n        suites.shift();\n      }\n      var suite = Suite.create(suites[0], title);\n      suite.file = file;\n      suites.unshift(suite);\n      return suite;\n    };\n\n    /**\n     * Exclusive test-case.\n     */\n\n    context.suite.only = function(title, fn) {\n      var suite = context.suite(title, fn);\n      mocha.grep(suite.fullTitle());\n    };\n\n    /**\n     * Describe a specification or test-case\n     * with the given `title` and callback `fn`\n     * acting as a thunk.\n     */\n\n    context.test = function(title, fn) {\n      var test = new Test(title, fn);\n      test.file = file;\n      suites[0].addTest(test);\n      return test;\n    };\n\n    /**\n     * Exclusive test-case.\n     */\n\n    context.test.only = function(title, fn) {\n      var test = context.test(title, fn);\n      var reString = '^' + escapeRe(test.fullTitle()) + '$';\n      mocha.grep(new RegExp(reString));\n    };\n\n    context.test.skip = common.test.skip;\n  });\n};\n\n},{\"../suite\":37,\"../test\":38,\"./common\":9,\"escape-string-regexp\":68}],13:[function(require,module,exports){\n/**\n * Module dependencies.\n */\n\nvar Suite = require('../suite');\nvar Test = require('../test');\nvar escapeRe = require('escape-string-regexp');\n\n/**\n * TDD-style interface:\n *\n *      suite('Array', function() {\n *        suite('#indexOf()', function() {\n *          suiteSetup(function() {\n *\n *          });\n *\n *          test('should return -1 when not present', function() {\n *\n *          });\n *\n *          test('should return the index when present', function() {\n *\n *          });\n *\n *          suiteTeardown(function() {\n *\n *          });\n *        });\n *      });\n *\n * @param {Suite} suite Root suite.\n */\nmodule.exports = function(suite) {\n  var suites = [suite];\n\n  suite.on('pre-require', function(context, file, mocha) {\n    var common = require('./common')(suites, context);\n\n    context.setup = common.beforeEach;\n    context.teardown = common.afterEach;\n    context.suiteSetup = common.before;\n    context.suiteTeardown = common.after;\n    context.run = mocha.options.delay && common.runWithSuite(suite);\n\n    /**\n     * Describe a \"suite\" with the given `title` and callback `fn` containing\n     * nested suites and/or tests.\n     */\n    context.suite = function(title, fn) {\n      var suite = Suite.create(suites[0], title);\n      suite.file = file;\n      suites.unshift(suite);\n      fn.call(suite);\n      suites.shift();\n      return suite;\n    };\n\n    /**\n     * Pending suite.\n     */\n    context.suite.skip = function(title, fn) {\n      var suite = Suite.create(suites[0], title);\n      suite.pending = true;\n      suites.unshift(suite);\n      fn.call(suite);\n      suites.shift();\n    };\n\n    /**\n     * Exclusive test-case.\n     */\n    context.suite.only = function(title, fn) {\n      var suite = context.suite(title, fn);\n      mocha.grep(suite.fullTitle());\n    };\n\n    /**\n     * Describe a specification or test-case with the given `title` and\n     * callback `fn` acting as a thunk.\n     */\n    context.test = function(title, fn) {\n      var suite = suites[0];\n      if (suite.pending) {\n        fn = null;\n      }\n      var test = new Test(title, fn);\n      test.file = file;\n      suite.addTest(test);\n      return test;\n    };\n\n    /**\n     * Exclusive test-case.\n     */\n\n    context.test.only = function(title, fn) {\n      var test = context.test(title, fn);\n      var reString = '^' + escapeRe(test.fullTitle()) + '$';\n      mocha.grep(new RegExp(reString));\n    };\n\n    context.test.skip = common.test.skip;\n  });\n};\n\n},{\"../suite\":37,\"../test\":38,\"./common\":9,\"escape-string-regexp\":68}],14:[function(require,module,exports){\n(function (process,global,__dirname){\n/*!\n * mocha\n * Copyright(c) 2011 TJ Holowaychuk <tj@vision-media.ca>\n * MIT Licensed\n */\n\n/**\n * Module dependencies.\n */\n\nvar escapeRe = require('escape-string-regexp');\nvar path = require('path');\nvar reporters = require('./reporters');\nvar utils = require('./utils');\n\n/**\n * Expose `Mocha`.\n */\n\nexports = module.exports = Mocha;\n\n/**\n * To require local UIs and reporters when running in node.\n */\n\nif (!process.browser) {\n  var cwd = process.cwd();\n  module.paths.push(cwd, path.join(cwd, 'node_modules'));\n}\n\n/**\n * Expose internals.\n */\n\nexports.utils = utils;\nexports.interfaces = require('./interfaces');\nexports.reporters = reporters;\nexports.Runnable = require('./runnable');\nexports.Context = require('./context');\nexports.Runner = require('./runner');\nexports.Suite = require('./suite');\nexports.Hook = require('./hook');\nexports.Test = require('./test');\n\n/**\n * Return image `name` path.\n *\n * @api private\n * @param {string} name\n * @return {string}\n */\nfunction image(name) {\n  return path.join(__dirname, '../images', name + '.png');\n}\n\n/**\n * Set up mocha with `options`.\n *\n * Options:\n *\n *   - `ui` name \"bdd\", \"tdd\", \"exports\" etc\n *   - `reporter` reporter instance, defaults to `mocha.reporters.spec`\n *   - `globals` array of accepted globals\n *   - `timeout` timeout in milliseconds\n *   - `bail` bail on the first test failure\n *   - `slow` milliseconds to wait before considering a test slow\n *   - `ignoreLeaks` ignore global leaks\n *   - `fullTrace` display the full stack-trace on failing\n *   - `grep` string or regexp to filter tests with\n *\n * @param {Object} options\n * @api public\n */\nfunction Mocha(options) {\n  options = options || {};\n  this.files = [];\n  this.options = options;\n  if (options.grep) {\n    this.grep(new RegExp(options.grep));\n  }\n  if (options.fgrep) {\n    this.grep(options.fgrep);\n  }\n  this.suite = new exports.Suite('', new exports.Context());\n  this.ui(options.ui);\n  this.bail(options.bail);\n  this.reporter(options.reporter, options.reporterOptions);\n  if (typeof options.timeout !== 'undefined' && options.timeout !== null) {\n    this.timeout(options.timeout);\n  }\n  this.useColors(options.useColors);\n  if (options.enableTimeouts !== null) {\n    this.enableTimeouts(options.enableTimeouts);\n  }\n  if (options.slow) {\n    this.slow(options.slow);\n  }\n\n  this.suite.on('pre-require', function(context) {\n    exports.afterEach = context.afterEach || context.teardown;\n    exports.after = context.after || context.suiteTeardown;\n    exports.beforeEach = context.beforeEach || context.setup;\n    exports.before = context.before || context.suiteSetup;\n    exports.describe = context.describe || context.suite;\n    exports.it = context.it || context.test;\n    exports.setup = context.setup || context.beforeEach;\n    exports.suiteSetup = context.suiteSetup || context.before;\n    exports.suiteTeardown = context.suiteTeardown || context.after;\n    exports.suite = context.suite || context.describe;\n    exports.teardown = context.teardown || context.afterEach;\n    exports.test = context.test || context.it;\n    exports.run = context.run;\n  });\n}\n\n/**\n * Enable or disable bailing on the first failure.\n *\n * @api public\n * @param {boolean} [bail]\n */\nMocha.prototype.bail = function(bail) {\n  if (!arguments.length) {\n    bail = true;\n  }\n  this.suite.bail(bail);\n  return this;\n};\n\n/**\n * Add test `file`.\n *\n * @api public\n * @param {string} file\n */\nMocha.prototype.addFile = function(file) {\n  this.files.push(file);\n  return this;\n};\n\n/**\n * Set reporter to `reporter`, defaults to \"spec\".\n *\n * @param {String|Function} reporter name or constructor\n * @param {Object} reporterOptions optional options\n * @api public\n * @param {string|Function} reporter name or constructor\n * @param {Object} reporterOptions optional options\n */\nMocha.prototype.reporter = function(reporter, reporterOptions) {\n  if (typeof reporter === 'function') {\n    this._reporter = reporter;\n  } else {\n    reporter = reporter || 'spec';\n    var _reporter;\n    // Try to load a built-in reporter.\n    if (reporters[reporter]) {\n      _reporter = reporters[reporter];\n    }\n    // Try to load reporters from process.cwd() and node_modules\n    if (!_reporter) {\n      try {\n        _reporter = require(reporter);\n      } catch (err) {\n        err.message.indexOf('Cannot find module') !== -1\n          ? console.warn('\"' + reporter + '\" reporter not found')\n          : console.warn('\"' + reporter + '\" reporter blew up with error:\\n' + err.stack);\n      }\n    }\n    if (!_reporter && reporter === 'teamcity') {\n      console.warn('The Teamcity reporter was moved to a package named '\n        + 'mocha-teamcity-reporter '\n        + '(https://npmjs.org/package/mocha-teamcity-reporter).');\n    }\n    if (!_reporter) {\n      throw new Error('invalid reporter \"' + reporter + '\"');\n    }\n    this._reporter = _reporter;\n  }\n  this.options.reporterOptions = reporterOptions;\n  return this;\n};\n\n/**\n * Set test UI `name`, defaults to \"bdd\".\n *\n * @api public\n * @param {string} bdd\n */\nMocha.prototype.ui = function(name) {\n  name = name || 'bdd';\n  this._ui = exports.interfaces[name];\n  if (!this._ui) {\n    try {\n      this._ui = require(name);\n    } catch (err) {\n      throw new Error('invalid interface \"' + name + '\"');\n    }\n  }\n  this._ui = this._ui(this.suite);\n  return this;\n};\n\n/**\n * Load registered files.\n *\n * @api private\n */\nMocha.prototype.loadFiles = function(fn) {\n  var self = this;\n  var suite = this.suite;\n  var pending = this.files.length;\n  this.files.forEach(function(file) {\n    file = path.resolve(file);\n    suite.emit('pre-require', global, file, self);\n    suite.emit('require', require(file), file, self);\n    suite.emit('post-require', global, file, self);\n    --pending || (fn && fn());\n  });\n};\n\n/**\n * Enable growl support.\n *\n * @api private\n */\nMocha.prototype._growl = function(runner, reporter) {\n  var notify = require('growl');\n\n  runner.on('end', function() {\n    var stats = reporter.stats;\n    if (stats.failures) {\n      var msg = stats.failures + ' of ' + runner.total + ' tests failed';\n      notify(msg, { name: 'mocha', title: 'Failed', image: image('error') });\n    } else {\n      notify(stats.passes + ' tests passed in ' + stats.duration + 'ms', {\n        name: 'mocha',\n        title: 'Passed',\n        image: image('ok')\n      });\n    }\n  });\n};\n\n/**\n * Add regexp to grep, if `re` is a string it is escaped.\n *\n * @param {RegExp|String} re\n * @return {Mocha}\n * @api public\n * @param {RegExp|string} re\n * @return {Mocha}\n */\nMocha.prototype.grep = function(re) {\n  this.options.grep = typeof re === 'string' ? new RegExp(escapeRe(re)) : re;\n  return this;\n};\n\n/**\n * Invert `.grep()` matches.\n *\n * @return {Mocha}\n * @api public\n */\nMocha.prototype.invert = function() {\n  this.options.invert = true;\n  return this;\n};\n\n/**\n * Ignore global leaks.\n *\n * @param {Boolean} ignore\n * @return {Mocha}\n * @api public\n * @param {boolean} ignore\n * @return {Mocha}\n */\nMocha.prototype.ignoreLeaks = function(ignore) {\n  this.options.ignoreLeaks = Boolean(ignore);\n  return this;\n};\n\n/**\n * Enable global leak checking.\n *\n * @return {Mocha}\n * @api public\n */\nMocha.prototype.checkLeaks = function() {\n  this.options.ignoreLeaks = false;\n  return this;\n};\n\n/**\n * Display long stack-trace on failing\n *\n * @return {Mocha}\n * @api public\n */\nMocha.prototype.fullTrace = function() {\n  this.options.fullStackTrace = true;\n  return this;\n};\n\n/**\n * Enable growl support.\n *\n * @return {Mocha}\n * @api public\n */\nMocha.prototype.growl = function() {\n  this.options.growl = true;\n  return this;\n};\n\n/**\n * Ignore `globals` array or string.\n *\n * @param {Array|String} globals\n * @return {Mocha}\n * @api public\n * @param {Array|string} globals\n * @return {Mocha}\n */\nMocha.prototype.globals = function(globals) {\n  this.options.globals = (this.options.globals || []).concat(globals);\n  return this;\n};\n\n/**\n * Emit color output.\n *\n * @param {Boolean} colors\n * @return {Mocha}\n * @api public\n * @param {boolean} colors\n * @return {Mocha}\n */\nMocha.prototype.useColors = function(colors) {\n  if (colors !== undefined) {\n    this.options.useColors = colors;\n  }\n  return this;\n};\n\n/**\n * Use inline diffs rather than +/-.\n *\n * @param {Boolean} inlineDiffs\n * @return {Mocha}\n * @api public\n * @param {boolean} inlineDiffs\n * @return {Mocha}\n */\nMocha.prototype.useInlineDiffs = function(inlineDiffs) {\n  this.options.useInlineDiffs = inlineDiffs !== undefined && inlineDiffs;\n  return this;\n};\n\n/**\n * Set the timeout in milliseconds.\n *\n * @param {Number} timeout\n * @return {Mocha}\n * @api public\n * @param {number} timeout\n * @return {Mocha}\n */\nMocha.prototype.timeout = function(timeout) {\n  this.suite.timeout(timeout);\n  return this;\n};\n\n/**\n * Set slowness threshold in milliseconds.\n *\n * @param {Number} slow\n * @return {Mocha}\n * @api public\n * @param {number} slow\n * @return {Mocha}\n */\nMocha.prototype.slow = function(slow) {\n  this.suite.slow(slow);\n  return this;\n};\n\n/**\n * Enable timeouts.\n *\n * @param {Boolean} enabled\n * @return {Mocha}\n * @api public\n * @param {boolean} enabled\n * @return {Mocha}\n */\nMocha.prototype.enableTimeouts = function(enabled) {\n  this.suite.enableTimeouts(arguments.length && enabled !== undefined ? enabled : true);\n  return this;\n};\n\n/**\n * Makes all tests async (accepting a callback)\n *\n * @return {Mocha}\n * @api public\n */\nMocha.prototype.asyncOnly = function() {\n  this.options.asyncOnly = true;\n  return this;\n};\n\n/**\n * Disable syntax highlighting (in browser).\n *\n * @api public\n */\nMocha.prototype.noHighlighting = function() {\n  this.options.noHighlighting = true;\n  return this;\n};\n\n/**\n * Enable uncaught errors to propagate (in browser).\n *\n * @return {Mocha}\n * @api public\n */\nMocha.prototype.allowUncaught = function() {\n  this.options.allowUncaught = true;\n  return this;\n};\n\n/**\n * Delay root suite execution.\n * @returns {Mocha}\n */\nMocha.prototype.delay = function delay() {\n  this.options.delay = true;\n  return this;\n};\n\n/**\n * Run tests and invoke `fn()` when complete.\n *\n * @api public\n * @param {Function} fn\n * @return {Runner}\n */\nMocha.prototype.run = function(fn) {\n  if (this.files.length) {\n    this.loadFiles();\n  }\n  var suite = this.suite;\n  var options = this.options;\n  options.files = this.files;\n  var runner = new exports.Runner(suite, options.delay);\n  var reporter = new this._reporter(runner, options);\n  runner.ignoreLeaks = options.ignoreLeaks !== false;\n  runner.fullStackTrace = options.fullStackTrace;\n  runner.asyncOnly = options.asyncOnly;\n  runner.allowUncaught = options.allowUncaught;\n  if (options.grep) {\n    runner.grep(options.grep, options.invert);\n  }\n  if (options.globals) {\n    runner.globals(options.globals);\n  }\n  if (options.growl) {\n    this._growl(runner, reporter);\n  }\n  if (options.useColors !== undefined) {\n    exports.reporters.Base.useColors = options.useColors;\n  }\n  exports.reporters.Base.inlineDiffs = options.useInlineDiffs;\n\n  function done(failures) {\n    if (reporter.done) {\n      reporter.done(failures, fn);\n    } else {\n      fn && fn(failures);\n    }\n  }\n\n  return runner.run(done);\n};\n\n}).call(this,require('_process'),typeof global !== \"undefined\" ? global : typeof self !== \"undefined\" ? self : typeof window !== \"undefined\" ? window : {},\"/lib\")\n},{\"./context\":6,\"./hook\":7,\"./interfaces\":11,\"./reporters\":22,\"./runnable\":35,\"./runner\":36,\"./suite\":37,\"./test\":38,\"./utils\":39,\"_process\":51,\"escape-string-regexp\":68,\"growl\":69,\"path\":41}],15:[function(require,module,exports){\n/**\n * Helpers.\n */\n\nvar s = 1000;\nvar m = s * 60;\nvar h = m * 60;\nvar d = h * 24;\nvar y = d * 365.25;\n\n/**\n * Parse or format the given `val`.\n *\n * Options:\n *\n *  - `long` verbose formatting [false]\n *\n * @api public\n * @param {string|number} val\n * @param {Object} options\n * @return {string|number}\n */\nmodule.exports = function(val, options) {\n  options = options || {};\n  if (typeof val === 'string') {\n    return parse(val);\n  }\n  // https://github.com/mochajs/mocha/pull/1035\n  return options['long'] ? longFormat(val) : shortFormat(val);\n};\n\n/**\n * Parse the given `str` and return milliseconds.\n *\n * @api private\n * @param {string} str\n * @return {number}\n */\nfunction parse(str) {\n  var match = (/^((?:\\d+)?\\.?\\d+) *(ms|seconds?|s|minutes?|m|hours?|h|days?|d|years?|y)?$/i).exec(str);\n  if (!match) {\n    return;\n  }\n  var n = parseFloat(match[1]);\n  var type = (match[2] || 'ms').toLowerCase();\n  switch (type) {\n    case 'years':\n    case 'year':\n    case 'y':\n      return n * y;\n    case 'days':\n    case 'day':\n    case 'd':\n      return n * d;\n    case 'hours':\n    case 'hour':\n    case 'h':\n      return n * h;\n    case 'minutes':\n    case 'minute':\n    case 'm':\n      return n * m;\n    case 'seconds':\n    case 'second':\n    case 's':\n      return n * s;\n    case 'ms':\n      return n;\n    default:\n      // No default case\n  }\n}\n\n/**\n * Short format for `ms`.\n *\n * @api private\n * @param {number} ms\n * @return {string}\n */\nfunction shortFormat(ms) {\n  if (ms >= d) {\n    return Math.round(ms / d) + 'd';\n  }\n  if (ms >= h) {\n    return Math.round(ms / h) + 'h';\n  }\n  if (ms >= m) {\n    return Math.round(ms / m) + 'm';\n  }\n  if (ms >= s) {\n    return Math.round(ms / s) + 's';\n  }\n  return ms + 'ms';\n}\n\n/**\n * Long format for `ms`.\n *\n * @api private\n * @param {number} ms\n * @return {string}\n */\nfunction longFormat(ms) {\n  return plural(ms, d, 'day')\n    || plural(ms, h, 'hour')\n    || plural(ms, m, 'minute')\n    || plural(ms, s, 'second')\n    || ms + ' ms';\n}\n\n/**\n * Pluralization helper.\n *\n * @api private\n * @param {number} ms\n * @param {number} n\n * @param {string} name\n */\nfunction plural(ms, n, name) {\n  if (ms < n) {\n    return;\n  }\n  if (ms < n * 1.5) {\n    return Math.floor(ms / n) + ' ' + name;\n  }\n  return Math.ceil(ms / n) + ' ' + name + 's';\n}\n\n},{}],16:[function(require,module,exports){\n\n/**\n * Expose `Pending`.\n */\n\nmodule.exports = Pending;\n\n/**\n * Initialize a new `Pending` error with the given message.\n *\n * @param {string} message\n */\nfunction Pending(message) {\n  this.message = message;\n}\n\n},{}],17:[function(require,module,exports){\n(function (process,global){\n/**\n * Module dependencies.\n */\n\nvar tty = require('tty');\nvar diff = require('diff');\nvar ms = require('../ms');\nvar utils = require('../utils');\nvar supportsColor = process.browser ? null : require('supports-color');\n\n/**\n * Expose `Base`.\n */\n\nexports = module.exports = Base;\n\n/**\n * Save timer references to avoid Sinon interfering.\n * See: https://github.com/mochajs/mocha/issues/237\n */\n\n/* eslint-disable no-unused-vars, no-native-reassign */\nvar Date = global.Date;\nvar setTimeout = global.setTimeout;\nvar setInterval = global.setInterval;\nvar clearTimeout = global.clearTimeout;\nvar clearInterval = global.clearInterval;\n/* eslint-enable no-unused-vars, no-native-reassign */\n\n/**\n * Check if both stdio streams are associated with a tty.\n */\n\nvar isatty = tty.isatty(1) && tty.isatty(2);\n\n/**\n * Enable coloring by default, except in the browser interface.\n */\n\nexports.useColors = !process.browser && (supportsColor || (process.env.MOCHA_COLORS !== undefined));\n\n/**\n * Inline diffs instead of +/-\n */\n\nexports.inlineDiffs = false;\n\n/**\n * Default color map.\n */\n\nexports.colors = {\n  pass: 90,\n  fail: 31,\n  'bright pass': 92,\n  'bright fail': 91,\n  'bright yellow': 93,\n  pending: 36,\n  suite: 0,\n  'error title': 0,\n  'error message': 31,\n  'error stack': 90,\n  checkmark: 32,\n  fast: 90,\n  medium: 33,\n  slow: 31,\n  green: 32,\n  light: 90,\n  'diff gutter': 90,\n  'diff added': 32,\n  'diff removed': 31\n};\n\n/**\n * Default symbol map.\n */\n\nexports.symbols = {\n  ok: '✓',\n  err: '✖',\n  dot: '․'\n};\n\n// With node.js on Windows: use symbols available in terminal default fonts\nif (process.platform === 'win32') {\n  exports.symbols.ok = '\\u221A';\n  exports.symbols.err = '\\u00D7';\n  exports.symbols.dot = '.';\n}\n\n/**\n * Color `str` with the given `type`,\n * allowing colors to be disabled,\n * as well as user-defined color\n * schemes.\n *\n * @param {string} type\n * @param {string} str\n * @return {string}\n * @api private\n */\nvar color = exports.color = function(type, str) {\n  if (!exports.useColors) {\n    return String(str);\n  }\n  return '\\u001b[' + exports.colors[type] + 'm' + str + '\\u001b[0m';\n};\n\n/**\n * Expose term window size, with some defaults for when stderr is not a tty.\n */\n\nexports.window = {\n  width: 75\n};\n\nif (isatty) {\n  exports.window.width = process.stdout.getWindowSize\n      ? process.stdout.getWindowSize(1)[0]\n      : tty.getWindowSize()[1];\n}\n\n/**\n * Expose some basic cursor interactions that are common among reporters.\n */\n\nexports.cursor = {\n  hide: function() {\n    isatty && process.stdout.write('\\u001b[?25l');\n  },\n\n  show: function() {\n    isatty && process.stdout.write('\\u001b[?25h');\n  },\n\n  deleteLine: function() {\n    isatty && process.stdout.write('\\u001b[2K');\n  },\n\n  beginningOfLine: function() {\n    isatty && process.stdout.write('\\u001b[0G');\n  },\n\n  CR: function() {\n    if (isatty) {\n      exports.cursor.deleteLine();\n      exports.cursor.beginningOfLine();\n    } else {\n      process.stdout.write('\\r');\n    }\n  }\n};\n\n/**\n * Outut the given `failures` as a list.\n *\n * @param {Array} failures\n * @api public\n */\n\nexports.list = function(failures) {\n  console.log();\n  failures.forEach(function(test, i) {\n    // format\n    var fmt = color('error title', '  %s) %s:\\n')\n      + color('error message', '     %s')\n      + color('error stack', '\\n%s\\n');\n\n    // msg\n    var msg;\n    var err = test.err;\n    var message;\n    if (err.message) {\n      message = err.message;\n    } else if (typeof err.inspect === 'function') {\n      message = err.inspect() + '';\n    } else {\n      message = '';\n    }\n    var stack = err.stack || message;\n    var index = stack.indexOf(message);\n    var actual = err.actual;\n    var expected = err.expected;\n    var escape = true;\n\n    if (index === -1) {\n      msg = message;\n    } else {\n      index += message.length;\n      msg = stack.slice(0, index);\n      // remove msg from stack\n      stack = stack.slice(index + 1);\n    }\n\n    // uncaught\n    if (err.uncaught) {\n      msg = 'Uncaught ' + msg;\n    }\n    // explicitly show diff\n    if (err.showDiff !== false && sameType(actual, expected) && expected !== undefined) {\n      escape = false;\n      if (!(utils.isString(actual) && utils.isString(expected))) {\n        err.actual = actual = utils.stringify(actual);\n        err.expected = expected = utils.stringify(expected);\n      }\n\n      fmt = color('error title', '  %s) %s:\\n%s') + color('error stack', '\\n%s\\n');\n      var match = message.match(/^([^:]+): expected/);\n      msg = '\\n      ' + color('error message', match ? match[1] : msg);\n\n      if (exports.inlineDiffs) {\n        msg += inlineDiff(err, escape);\n      } else {\n        msg += unifiedDiff(err, escape);\n      }\n    }\n\n    // indent stack trace\n    stack = stack.replace(/^/gm, '  ');\n\n    console.log(fmt, (i + 1), test.fullTitle(), msg, stack);\n  });\n};\n\n/**\n * Initialize a new `Base` reporter.\n *\n * All other reporters generally\n * inherit from this reporter, providing\n * stats such as test duration, number\n * of tests passed / failed etc.\n *\n * @param {Runner} runner\n * @api public\n */\n\nfunction Base(runner) {\n  var stats = this.stats = { suites: 0, tests: 0, passes: 0, pending: 0, failures: 0 };\n  var failures = this.failures = [];\n\n  if (!runner) {\n    return;\n  }\n  this.runner = runner;\n\n  runner.stats = stats;\n\n  runner.on('start', function() {\n    stats.start = new Date();\n  });\n\n  runner.on('suite', function(suite) {\n    stats.suites = stats.suites || 0;\n    suite.root || stats.suites++;\n  });\n\n  runner.on('test end', function() {\n    stats.tests = stats.tests || 0;\n    stats.tests++;\n  });\n\n  runner.on('pass', function(test) {\n    stats.passes = stats.passes || 0;\n\n    if (test.duration > test.slow()) {\n      test.speed = 'slow';\n    } else if (test.duration > test.slow() / 2) {\n      test.speed = 'medium';\n    } else {\n      test.speed = 'fast';\n    }\n\n    stats.passes++;\n  });\n\n  runner.on('fail', function(test, err) {\n    stats.failures = stats.failures || 0;\n    stats.failures++;\n    test.err = err;\n    failures.push(test);\n  });\n\n  runner.on('end', function() {\n    stats.end = new Date();\n    stats.duration = new Date() - stats.start;\n  });\n\n  runner.on('pending', function() {\n    stats.pending++;\n  });\n}\n\n/**\n * Output common epilogue used by many of\n * the bundled reporters.\n *\n * @api public\n */\nBase.prototype.epilogue = function() {\n  var stats = this.stats;\n  var fmt;\n\n  console.log();\n\n  // passes\n  fmt = color('bright pass', ' ')\n    + color('green', ' %d passing')\n    + color('light', ' (%s)');\n\n  console.log(fmt,\n    stats.passes || 0,\n    ms(stats.duration));\n\n  // pending\n  if (stats.pending) {\n    fmt = color('pending', ' ')\n      + color('pending', ' %d pending');\n\n    console.log(fmt, stats.pending);\n  }\n\n  // failures\n  if (stats.failures) {\n    fmt = color('fail', '  %d failing');\n\n    console.log(fmt, stats.failures);\n\n    Base.list(this.failures);\n    console.log();\n  }\n\n  console.log();\n};\n\n/**\n * Pad the given `str` to `len`.\n *\n * @api private\n * @param {string} str\n * @param {string} len\n * @return {string}\n */\nfunction pad(str, len) {\n  str = String(str);\n  return Array(len - str.length + 1).join(' ') + str;\n}\n\n/**\n * Returns an inline diff between 2 strings with coloured ANSI output\n *\n * @api private\n * @param {Error} err with actual/expected\n * @param {boolean} escape\n * @return {string} Diff\n */\nfunction inlineDiff(err, escape) {\n  var msg = errorDiff(err, 'WordsWithSpace', escape);\n\n  // linenos\n  var lines = msg.split('\\n');\n  if (lines.length > 4) {\n    var width = String(lines.length).length;\n    msg = lines.map(function(str, i) {\n      return pad(++i, width) + ' |' + ' ' + str;\n    }).join('\\n');\n  }\n\n  // legend\n  msg = '\\n'\n    + color('diff removed', 'actual')\n    + ' '\n    + color('diff added', 'expected')\n    + '\\n\\n'\n    + msg\n    + '\\n';\n\n  // indent\n  msg = msg.replace(/^/gm, '      ');\n  return msg;\n}\n\n/**\n * Returns a unified diff between two strings.\n *\n * @api private\n * @param {Error} err with actual/expected\n * @param {boolean} escape\n * @return {string} The diff.\n */\nfunction unifiedDiff(err, escape) {\n  var indent = '      ';\n  function cleanUp(line) {\n    if (escape) {\n      line = escapeInvisibles(line);\n    }\n    if (line[0] === '+') {\n      return indent + colorLines('diff added', line);\n    }\n    if (line[0] === '-') {\n      return indent + colorLines('diff removed', line);\n    }\n    if (line.match(/\\@\\@/)) {\n      return null;\n    }\n    if (line.match(/\\\\ No newline/)) {\n      return null;\n    }\n    return indent + line;\n  }\n  function notBlank(line) {\n    return typeof line !== 'undefined' && line !== null;\n  }\n  var msg = diff.createPatch('string', err.actual, err.expected);\n  var lines = msg.split('\\n').splice(4);\n  return '\\n      '\n    + colorLines('diff added', '+ expected') + ' '\n    + colorLines('diff removed', '- actual')\n    + '\\n\\n'\n    + lines.map(cleanUp).filter(notBlank).join('\\n');\n}\n\n/**\n * Return a character diff for `err`.\n *\n * @api private\n * @param {Error} err\n * @param {string} type\n * @param {boolean} escape\n * @return {string}\n */\nfunction errorDiff(err, type, escape) {\n  var actual = escape ? escapeInvisibles(err.actual) : err.actual;\n  var expected = escape ? escapeInvisibles(err.expected) : err.expected;\n  return diff['diff' + type](actual, expected).map(function(str) {\n    if (str.added) {\n      return colorLines('diff added', str.value);\n    }\n    if (str.removed) {\n      return colorLines('diff removed', str.value);\n    }\n    return str.value;\n  }).join('');\n}\n\n/**\n * Returns a string with all invisible characters in plain text\n *\n * @api private\n * @param {string} line\n * @return {string}\n */\nfunction escapeInvisibles(line) {\n  return line.replace(/\\t/g, '<tab>')\n    .replace(/\\r/g, '<CR>')\n    .replace(/\\n/g, '<LF>\\n');\n}\n\n/**\n * Color lines for `str`, using the color `name`.\n *\n * @api private\n * @param {string} name\n * @param {string} str\n * @return {string}\n */\nfunction colorLines(name, str) {\n  return str.split('\\n').map(function(str) {\n    return color(name, str);\n  }).join('\\n');\n}\n\n/**\n * Object#toString reference.\n */\nvar objToString = Object.prototype.toString;\n\n/**\n * Check that a / b have the same type.\n *\n * @api private\n * @param {Object} a\n * @param {Object} b\n * @return {boolean}\n */\nfunction sameType(a, b) {\n  return objToString.call(a) === objToString.call(b);\n}\n\n}).call(this,require('_process'),typeof global !== \"undefined\" ? global : typeof self !== \"undefined\" ? self : typeof window !== \"undefined\" ? window : {})\n},{\"../ms\":15,\"../utils\":39,\"_process\":51,\"diff\":67,\"supports-color\":41,\"tty\":5}],18:[function(require,module,exports){\n/**\n * Module dependencies.\n */\n\nvar Base = require('./base');\nvar utils = require('../utils');\n\n/**\n * Expose `Doc`.\n */\n\nexports = module.exports = Doc;\n\n/**\n * Initialize a new `Doc` reporter.\n *\n * @param {Runner} runner\n * @api public\n */\nfunction Doc(runner) {\n  Base.call(this, runner);\n\n  var indents = 2;\n\n  function indent() {\n    return Array(indents).join('  ');\n  }\n\n  runner.on('suite', function(suite) {\n    if (suite.root) {\n      return;\n    }\n    ++indents;\n    console.log('%s<section class=\"suite\">', indent());\n    ++indents;\n    console.log('%s<h1>%s</h1>', indent(), utils.escape(suite.title));\n    console.log('%s<dl>', indent());\n  });\n\n  runner.on('suite end', function(suite) {\n    if (suite.root) {\n      return;\n    }\n    console.log('%s</dl>', indent());\n    --indents;\n    console.log('%s</section>', indent());\n    --indents;\n  });\n\n  runner.on('pass', function(test) {\n    console.log('%s  <dt>%s</dt>', indent(), utils.escape(test.title));\n    var code = utils.escape(utils.clean(test.fn.toString()));\n    console.log('%s  <dd><pre><code>%s</code></pre></dd>', indent(), code);\n  });\n\n  runner.on('fail', function(test, err) {\n    console.log('%s  <dt class=\"error\">%s</dt>', indent(), utils.escape(test.title));\n    var code = utils.escape(utils.clean(test.fn.toString()));\n    console.log('%s  <dd class=\"error\"><pre><code>%s</code></pre></dd>', indent(), code);\n    console.log('%s  <dd class=\"error\">%s</dd>', indent(), utils.escape(err));\n  });\n}\n\n},{\"../utils\":39,\"./base\":17}],19:[function(require,module,exports){\n(function (process){\n/**\n * Module dependencies.\n */\n\nvar Base = require('./base');\nvar inherits = require('../utils').inherits;\nvar color = Base.color;\n\n/**\n * Expose `Dot`.\n */\n\nexports = module.exports = Dot;\n\n/**\n * Initialize a new `Dot` matrix test reporter.\n *\n * @api public\n * @param {Runner} runner\n */\nfunction Dot(runner) {\n  Base.call(this, runner);\n\n  var self = this;\n  var width = Base.window.width * .75 | 0;\n  var n = -1;\n\n  runner.on('start', function() {\n    process.stdout.write('\\n');\n  });\n\n  runner.on('pending', function() {\n    if (++n % width === 0) {\n      process.stdout.write('\\n  ');\n    }\n    process.stdout.write(color('pending', Base.symbols.dot));\n  });\n\n  runner.on('pass', function(test) {\n    if (++n % width === 0) {\n      process.stdout.write('\\n  ');\n    }\n    if (test.speed === 'slow') {\n      process.stdout.write(color('bright yellow', Base.symbols.dot));\n    } else {\n      process.stdout.write(color(test.speed, Base.symbols.dot));\n    }\n  });\n\n  runner.on('fail', function() {\n    if (++n % width === 0) {\n      process.stdout.write('\\n  ');\n    }\n    process.stdout.write(color('fail', Base.symbols.dot));\n  });\n\n  runner.on('end', function() {\n    console.log();\n    self.epilogue();\n  });\n}\n\n/**\n * Inherit from `Base.prototype`.\n */\ninherits(Dot, Base);\n\n}).call(this,require('_process'))\n},{\"../utils\":39,\"./base\":17,\"_process\":51}],20:[function(require,module,exports){\n(function (process,__dirname){\n/**\n * Module dependencies.\n */\n\nvar JSONCov = require('./json-cov');\nvar readFileSync = require('fs').readFileSync;\nvar join = require('path').join;\n\n/**\n * Expose `HTMLCov`.\n */\n\nexports = module.exports = HTMLCov;\n\n/**\n * Initialize a new `JsCoverage` reporter.\n *\n * @api public\n * @param {Runner} runner\n */\nfunction HTMLCov(runner) {\n  var jade = require('jade');\n  var file = join(__dirname, '/templates/coverage.jade');\n  var str = readFileSync(file, 'utf8');\n  var fn = jade.compile(str, { filename: file });\n  var self = this;\n\n  JSONCov.call(this, runner, false);\n\n  runner.on('end', function() {\n    process.stdout.write(fn({\n      cov: self.cov,\n      coverageClass: coverageClass\n    }));\n  });\n}\n\n/**\n * Return coverage class for a given coverage percentage.\n *\n * @api private\n * @param {number} coveragePctg\n * @return {string}\n */\nfunction coverageClass(coveragePctg) {\n  if (coveragePctg >= 75) {\n    return 'high';\n  }\n  if (coveragePctg >= 50) {\n    return 'medium';\n  }\n  if (coveragePctg >= 25) {\n    return 'low';\n  }\n  return 'terrible';\n}\n\n}).call(this,require('_process'),\"/lib/reporters\")\n},{\"./json-cov\":23,\"_process\":51,\"fs\":41,\"jade\":41,\"path\":41}],21:[function(require,module,exports){\n(function (global){\n/* eslint-env browser */\n\n/**\n * Module dependencies.\n */\n\nvar Base = require('./base');\nvar utils = require('../utils');\nvar Progress = require('../browser/progress');\nvar escapeRe = require('escape-string-regexp');\nvar escape = utils.escape;\n\n/**\n * Save timer references to avoid Sinon interfering (see GH-237).\n */\n\n/* eslint-disable no-unused-vars, no-native-reassign */\nvar Date = global.Date;\nvar setTimeout = global.setTimeout;\nvar setInterval = global.setInterval;\nvar clearTimeout = global.clearTimeout;\nvar clearInterval = global.clearInterval;\n/* eslint-enable no-unused-vars, no-native-reassign */\n\n/**\n * Expose `HTML`.\n */\n\nexports = module.exports = HTML;\n\n/**\n * Stats template.\n */\n\nvar statsTemplate = '<ul id=\"mocha-stats\">'\n  + '<li class=\"progress\"><canvas width=\"40\" height=\"40\"></canvas></li>'\n  + '<li class=\"passes\"><a href=\"javascript:void(0);\">passes:</a> <em>0</em></li>'\n  + '<li class=\"failures\"><a href=\"javascript:void(0);\">failures:</a> <em>0</em></li>'\n  + '<li class=\"duration\">duration: <em>0</em>s</li>'\n  + '</ul>';\n\n/**\n * Initialize a new `HTML` reporter.\n *\n * @api public\n * @param {Runner} runner\n */\nfunction HTML(runner) {\n  Base.call(this, runner);\n\n  var self = this;\n  var stats = this.stats;\n  var stat = fragment(statsTemplate);\n  var items = stat.getElementsByTagName('li');\n  var passes = items[1].getElementsByTagName('em')[0];\n  var passesLink = items[1].getElementsByTagName('a')[0];\n  var failures = items[2].getElementsByTagName('em')[0];\n  var failuresLink = items[2].getElementsByTagName('a')[0];\n  var duration = items[3].getElementsByTagName('em')[0];\n  var canvas = stat.getElementsByTagName('canvas')[0];\n  var report = fragment('<ul id=\"mocha-report\"></ul>');\n  var stack = [report];\n  var progress;\n  var ctx;\n  var root = document.getElementById('mocha');\n\n  if (canvas.getContext) {\n    var ratio = window.devicePixelRatio || 1;\n    canvas.style.width = canvas.width;\n    canvas.style.height = canvas.height;\n    canvas.width *= ratio;\n    canvas.height *= ratio;\n    ctx = canvas.getContext('2d');\n    ctx.scale(ratio, ratio);\n    progress = new Progress();\n  }\n\n  if (!root) {\n    return error('#mocha div missing, add it to your document');\n  }\n\n  // pass toggle\n  on(passesLink, 'click', function() {\n    unhide();\n    var name = (/pass/).test(report.className) ? '' : ' pass';\n    report.className = report.className.replace(/fail|pass/g, '') + name;\n    if (report.className.trim()) {\n      hideSuitesWithout('test pass');\n    }\n  });\n\n  // failure toggle\n  on(failuresLink, 'click', function() {\n    unhide();\n    var name = (/fail/).test(report.className) ? '' : ' fail';\n    report.className = report.className.replace(/fail|pass/g, '') + name;\n    if (report.className.trim()) {\n      hideSuitesWithout('test fail');\n    }\n  });\n\n  root.appendChild(stat);\n  root.appendChild(report);\n\n  if (progress) {\n    progress.size(40);\n  }\n\n  runner.on('suite', function(suite) {\n    if (suite.root) {\n      return;\n    }\n\n    // suite\n    var url = self.suiteURL(suite);\n    var el = fragment('<li class=\"suite\"><h1><a href=\"%s\">%s</a></h1></li>', url, escape(suite.title));\n\n    // container\n    stack[0].appendChild(el);\n    stack.unshift(document.createElement('ul'));\n    el.appendChild(stack[0]);\n  });\n\n  runner.on('suite end', function(suite) {\n    if (suite.root) {\n      return;\n    }\n    stack.shift();\n  });\n\n  runner.on('fail', function(test) {\n    if (test.type === 'hook') {\n      runner.emit('test end', test);\n    }\n  });\n\n  runner.on('test end', function(test) {\n    // TODO: add to stats\n    var percent = stats.tests / this.total * 100 | 0;\n    if (progress) {\n      progress.update(percent).draw(ctx);\n    }\n\n    // update stats\n    var ms = new Date() - stats.start;\n    text(passes, stats.passes);\n    text(failures, stats.failures);\n    text(duration, (ms / 1000).toFixed(2));\n\n    // test\n    var el;\n    if (test.state === 'passed') {\n      var url = self.testURL(test);\n      el = fragment('<li class=\"test pass %e\"><h2>%e<span class=\"duration\">%ems</span> <a href=\"%s\" class=\"replay\">‣</a></h2></li>', test.speed, test.title, test.duration, url);\n    } else if (test.pending) {\n      el = fragment('<li class=\"test pass pending\"><h2>%e</h2></li>', test.title);\n    } else {\n      el = fragment('<li class=\"test fail\"><h2>%e <a href=\"%e\" class=\"replay\">‣</a></h2></li>', test.title, self.testURL(test));\n      var stackString; // Note: Includes leading newline\n      var message = test.err.toString();\n\n      // <=IE7 stringifies to [Object Error]. Since it can be overloaded, we\n      // check for the result of the stringifying.\n      if (message === '[object Error]') {\n        message = test.err.message;\n      }\n\n      if (test.err.stack) {\n        var indexOfMessage = test.err.stack.indexOf(test.err.message);\n        if (indexOfMessage === -1) {\n          stackString = test.err.stack;\n        } else {\n          stackString = test.err.stack.substr(test.err.message.length + indexOfMessage);\n        }\n      } else if (test.err.sourceURL && test.err.line !== undefined) {\n        // Safari doesn't give you a stack. Let's at least provide a source line.\n        stackString = '\\n(' + test.err.sourceURL + ':' + test.err.line + ')';\n      }\n\n      stackString = stackString || '';\n\n      if (test.err.htmlMessage && stackString) {\n        el.appendChild(fragment('<div class=\"html-error\">%s\\n<pre class=\"error\">%e</pre></div>', test.err.htmlMessage, stackString));\n      } else if (test.err.htmlMessage) {\n        el.appendChild(fragment('<div class=\"html-error\">%s</div>', test.err.htmlMessage));\n      } else {\n        el.appendChild(fragment('<pre class=\"error\">%e%e</pre>', message, stackString));\n      }\n    }\n\n    // toggle code\n    // TODO: defer\n    if (!test.pending) {\n      var h2 = el.getElementsByTagName('h2')[0];\n\n      on(h2, 'click', function() {\n        pre.style.display = pre.style.display === 'none' ? 'block' : 'none';\n      });\n\n      var pre = fragment('<pre><code>%e</code></pre>', utils.clean(test.fn.toString()));\n      el.appendChild(pre);\n      pre.style.display = 'none';\n    }\n\n    // Don't call .appendChild if #mocha-report was already .shift()'ed off the stack.\n    if (stack[0]) {\n      stack[0].appendChild(el);\n    }\n  });\n}\n\n/**\n * Makes a URL, preserving querystring (\"search\") parameters.\n *\n * @param {string} s\n * @return {string} A new URL.\n */\nfunction makeUrl(s) {\n  var search = window.location.search;\n\n  // Remove previous grep query parameter if present\n  if (search) {\n    search = search.replace(/[?&]grep=[^&\\s]*/g, '').replace(/^&/, '?');\n  }\n\n  return window.location.pathname + (search ? search + '&' : '?') + 'grep=' + encodeURIComponent(escapeRe(s));\n}\n\n/**\n * Provide suite URL.\n *\n * @param {Object} [suite]\n */\nHTML.prototype.suiteURL = function(suite) {\n  return makeUrl(suite.fullTitle());\n};\n\n/**\n * Provide test URL.\n *\n * @param {Object} [test]\n */\nHTML.prototype.testURL = function(test) {\n  return makeUrl(test.fullTitle());\n};\n\n/**\n * Display error `msg`.\n *\n * @param {string} msg\n */\nfunction error(msg) {\n  document.body.appendChild(fragment('<div id=\"mocha-error\">%s</div>', msg));\n}\n\n/**\n * Return a DOM fragment from `html`.\n *\n * @param {string} html\n */\nfunction fragment(html) {\n  var args = arguments;\n  var div = document.createElement('div');\n  var i = 1;\n\n  div.innerHTML = html.replace(/%([se])/g, function(_, type) {\n    switch (type) {\n      case 's': return String(args[i++]);\n      case 'e': return escape(args[i++]);\n      // no default\n    }\n  });\n\n  return div.firstChild;\n}\n\n/**\n * Check for suites that do not have elements\n * with `classname`, and hide them.\n *\n * @param {text} classname\n */\nfunction hideSuitesWithout(classname) {\n  var suites = document.getElementsByClassName('suite');\n  for (var i = 0; i < suites.length; i++) {\n    var els = suites[i].getElementsByClassName(classname);\n    if (!els.length) {\n      suites[i].className += ' hidden';\n    }\n  }\n}\n\n/**\n * Unhide .hidden suites.\n */\nfunction unhide() {\n  var els = document.getElementsByClassName('suite hidden');\n  for (var i = 0; i < els.length; ++i) {\n    els[i].className = els[i].className.replace('suite hidden', 'suite');\n  }\n}\n\n/**\n * Set an element's text contents.\n *\n * @param {HTMLElement} el\n * @param {string} contents\n */\nfunction text(el, contents) {\n  if (el.textContent) {\n    el.textContent = contents;\n  } else {\n    el.innerText = contents;\n  }\n}\n\n/**\n * Listen on `event` with callback `fn`.\n */\nfunction on(el, event, fn) {\n  if (el.addEventListener) {\n    el.addEventListener(event, fn, false);\n  } else {\n    el.attachEvent('on' + event, fn);\n  }\n}\n\n}).call(this,typeof global !== \"undefined\" ? global : typeof self !== \"undefined\" ? self : typeof window !== \"undefined\" ? window : {})\n},{\"../browser/progress\":4,\"../utils\":39,\"./base\":17,\"escape-string-regexp\":68}],22:[function(require,module,exports){\n// Alias exports to a their normalized format Mocha#reporter to prevent a need\n// for dynamic (try/catch) requires, which Browserify doesn't handle.\nexports.Base = exports.base = require('./base');\nexports.Dot = exports.dot = require('./dot');\nexports.Doc = exports.doc = require('./doc');\nexports.TAP = exports.tap = require('./tap');\nexports.JSON = exports.json = require('./json');\nexports.HTML = exports.html = require('./html');\nexports.List = exports.list = require('./list');\nexports.Min = exports.min = require('./min');\nexports.Spec = exports.spec = require('./spec');\nexports.Nyan = exports.nyan = require('./nyan');\nexports.XUnit = exports.xunit = require('./xunit');\nexports.Markdown = exports.markdown = require('./markdown');\nexports.Progress = exports.progress = require('./progress');\nexports.Landing = exports.landing = require('./landing');\nexports.JSONCov = exports['json-cov'] = require('./json-cov');\nexports.HTMLCov = exports['html-cov'] = require('./html-cov');\nexports.JSONStream = exports['json-stream'] = require('./json-stream');\n\n},{\"./base\":17,\"./doc\":18,\"./dot\":19,\"./html\":21,\"./html-cov\":20,\"./json\":25,\"./json-cov\":23,\"./json-stream\":24,\"./landing\":26,\"./list\":27,\"./markdown\":28,\"./min\":29,\"./nyan\":30,\"./progress\":31,\"./spec\":32,\"./tap\":33,\"./xunit\":34}],23:[function(require,module,exports){\n(function (process,global){\n/**\n * Module dependencies.\n */\n\nvar Base = require('./base');\n\n/**\n * Expose `JSONCov`.\n */\n\nexports = module.exports = JSONCov;\n\n/**\n * Initialize a new `JsCoverage` reporter.\n *\n * @api public\n * @param {Runner} runner\n * @param {boolean} output\n */\nfunction JSONCov(runner, output) {\n  Base.call(this, runner);\n\n  output = arguments.length === 1 || output;\n  var self = this;\n  var tests = [];\n  var failures = [];\n  var passes = [];\n\n  runner.on('test end', function(test) {\n    tests.push(test);\n  });\n\n  runner.on('pass', function(test) {\n    passes.push(test);\n  });\n\n  runner.on('fail', function(test) {\n    failures.push(test);\n  });\n\n  runner.on('end', function() {\n    var cov = global._$jscoverage || {};\n    var result = self.cov = map(cov);\n    result.stats = self.stats;\n    result.tests = tests.map(clean);\n    result.failures = failures.map(clean);\n    result.passes = passes.map(clean);\n    if (!output) {\n      return;\n    }\n    process.stdout.write(JSON.stringify(result, null, 2));\n  });\n}\n\n/**\n * Map jscoverage data to a JSON structure\n * suitable for reporting.\n *\n * @api private\n * @param {Object} cov\n * @return {Object}\n */\n\nfunction map(cov) {\n  var ret = {\n    instrumentation: 'node-jscoverage',\n    sloc: 0,\n    hits: 0,\n    misses: 0,\n    coverage: 0,\n    files: []\n  };\n\n  for (var filename in cov) {\n    if (Object.prototype.hasOwnProperty.call(cov, filename)) {\n      var data = coverage(filename, cov[filename]);\n      ret.files.push(data);\n      ret.hits += data.hits;\n      ret.misses += data.misses;\n      ret.sloc += data.sloc;\n    }\n  }\n\n  ret.files.sort(function(a, b) {\n    return a.filename.localeCompare(b.filename);\n  });\n\n  if (ret.sloc > 0) {\n    ret.coverage = (ret.hits / ret.sloc) * 100;\n  }\n\n  return ret;\n}\n\n/**\n * Map jscoverage data for a single source file\n * to a JSON structure suitable for reporting.\n *\n * @api private\n * @param {string} filename name of the source file\n * @param {Object} data jscoverage coverage data\n * @return {Object}\n */\nfunction coverage(filename, data) {\n  var ret = {\n    filename: filename,\n    coverage: 0,\n    hits: 0,\n    misses: 0,\n    sloc: 0,\n    source: {}\n  };\n\n  data.source.forEach(function(line, num) {\n    num++;\n\n    if (data[num] === 0) {\n      ret.misses++;\n      ret.sloc++;\n    } else if (data[num] !== undefined) {\n      ret.hits++;\n      ret.sloc++;\n    }\n\n    ret.source[num] = {\n      source: line,\n      coverage: data[num] === undefined ? '' : data[num]\n    };\n  });\n\n  ret.coverage = ret.hits / ret.sloc * 100;\n\n  return ret;\n}\n\n/**\n * Return a plain-object representation of `test`\n * free of cyclic properties etc.\n *\n * @api private\n * @param {Object} test\n * @return {Object}\n */\nfunction clean(test) {\n  return {\n    duration: test.duration,\n    fullTitle: test.fullTitle(),\n    title: test.title\n  };\n}\n\n}).call(this,require('_process'),typeof global !== \"undefined\" ? global : typeof self !== \"undefined\" ? self : typeof window !== \"undefined\" ? window : {})\n},{\"./base\":17,\"_process\":51}],24:[function(require,module,exports){\n(function (process){\n/**\n * Module dependencies.\n */\n\nvar Base = require('./base');\n\n/**\n * Expose `List`.\n */\n\nexports = module.exports = List;\n\n/**\n * Initialize a new `List` test reporter.\n *\n * @api public\n * @param {Runner} runner\n */\nfunction List(runner) {\n  Base.call(this, runner);\n\n  var self = this;\n  var total = runner.total;\n\n  runner.on('start', function() {\n    console.log(JSON.stringify(['start', { total: total }]));\n  });\n\n  runner.on('pass', function(test) {\n    console.log(JSON.stringify(['pass', clean(test)]));\n  });\n\n  runner.on('fail', function(test, err) {\n    test = clean(test);\n    test.err = err.message;\n    test.stack = err.stack || null;\n    console.log(JSON.stringify(['fail', test]));\n  });\n\n  runner.on('end', function() {\n    process.stdout.write(JSON.stringify(['end', self.stats]));\n  });\n}\n\n/**\n * Return a plain-object representation of `test`\n * free of cyclic properties etc.\n *\n * @api private\n * @param {Object} test\n * @return {Object}\n */\nfunction clean(test) {\n  return {\n    title: test.title,\n    fullTitle: test.fullTitle(),\n    duration: test.duration\n  };\n}\n\n}).call(this,require('_process'))\n},{\"./base\":17,\"_process\":51}],25:[function(require,module,exports){\n(function (process){\n/**\n * Module dependencies.\n */\n\nvar Base = require('./base');\n\n/**\n * Expose `JSON`.\n */\n\nexports = module.exports = JSONReporter;\n\n/**\n * Initialize a new `JSON` reporter.\n *\n * @api public\n * @param {Runner} runner\n */\nfunction JSONReporter(runner) {\n  Base.call(this, runner);\n\n  var self = this;\n  var tests = [];\n  var pending = [];\n  var failures = [];\n  var passes = [];\n\n  runner.on('test end', function(test) {\n    tests.push(test);\n  });\n\n  runner.on('pass', function(test) {\n    passes.push(test);\n  });\n\n  runner.on('fail', function(test) {\n    failures.push(test);\n  });\n\n  runner.on('pending', function(test) {\n    pending.push(test);\n  });\n\n  runner.on('end', function() {\n    var obj = {\n      stats: self.stats,\n      tests: tests.map(clean),\n      pending: pending.map(clean),\n      failures: failures.map(clean),\n      passes: passes.map(clean)\n    };\n\n    runner.testResults = obj;\n\n    process.stdout.write(JSON.stringify(obj, null, 2));\n  });\n}\n\n/**\n * Return a plain-object representation of `test`\n * free of cyclic properties etc.\n *\n * @api private\n * @param {Object} test\n * @return {Object}\n */\nfunction clean(test) {\n  return {\n    title: test.title,\n    fullTitle: test.fullTitle(),\n    duration: test.duration,\n    err: errorJSON(test.err || {})\n  };\n}\n\n/**\n * Transform `error` into a JSON object.\n *\n * @api private\n * @param {Error} err\n * @return {Object}\n */\nfunction errorJSON(err) {\n  var res = {};\n  Object.getOwnPropertyNames(err).forEach(function(key) {\n    res[key] = err[key];\n  }, err);\n  return res;\n}\n\n}).call(this,require('_process'))\n},{\"./base\":17,\"_process\":51}],26:[function(require,module,exports){\n(function (process){\n/**\n * Module dependencies.\n */\n\nvar Base = require('./base');\nvar inherits = require('../utils').inherits;\nvar cursor = Base.cursor;\nvar color = Base.color;\n\n/**\n * Expose `Landing`.\n */\n\nexports = module.exports = Landing;\n\n/**\n * Airplane color.\n */\n\nBase.colors.plane = 0;\n\n/**\n * Airplane crash color.\n */\n\nBase.colors['plane crash'] = 31;\n\n/**\n * Runway color.\n */\n\nBase.colors.runway = 90;\n\n/**\n * Initialize a new `Landing` reporter.\n *\n * @api public\n * @param {Runner} runner\n */\nfunction Landing(runner) {\n  Base.call(this, runner);\n\n  var self = this;\n  var width = Base.window.width * .75 | 0;\n  var total = runner.total;\n  var stream = process.stdout;\n  var plane = color('plane', '✈');\n  var crashed = -1;\n  var n = 0;\n\n  function runway() {\n    var buf = Array(width).join('-');\n    return '  ' + color('runway', buf);\n  }\n\n  runner.on('start', function() {\n    stream.write('\\n\\n\\n  ');\n    cursor.hide();\n  });\n\n  runner.on('test end', function(test) {\n    // check if the plane crashed\n    var col = crashed === -1 ? width * ++n / total | 0 : crashed;\n\n    // show the crash\n    if (test.state === 'failed') {\n      plane = color('plane crash', '✈');\n      crashed = col;\n    }\n\n    // render landing strip\n    stream.write('\\u001b[' + (width + 1) + 'D\\u001b[2A');\n    stream.write(runway());\n    stream.write('\\n  ');\n    stream.write(color('runway', Array(col).join('⋅')));\n    stream.write(plane);\n    stream.write(color('runway', Array(width - col).join('⋅') + '\\n'));\n    stream.write(runway());\n    stream.write('\\u001b[0m');\n  });\n\n  runner.on('end', function() {\n    cursor.show();\n    console.log();\n    self.epilogue();\n  });\n}\n\n/**\n * Inherit from `Base.prototype`.\n */\ninherits(Landing, Base);\n\n}).call(this,require('_process'))\n},{\"../utils\":39,\"./base\":17,\"_process\":51}],27:[function(require,module,exports){\n(function (process){\n/**\n * Module dependencies.\n */\n\nvar Base = require('./base');\nvar inherits = require('../utils').inherits;\nvar color = Base.color;\nvar cursor = Base.cursor;\n\n/**\n * Expose `List`.\n */\n\nexports = module.exports = List;\n\n/**\n * Initialize a new `List` test reporter.\n *\n * @api public\n * @param {Runner} runner\n */\nfunction List(runner) {\n  Base.call(this, runner);\n\n  var self = this;\n  var n = 0;\n\n  runner.on('start', function() {\n    console.log();\n  });\n\n  runner.on('test', function(test) {\n    process.stdout.write(color('pass', '    ' + test.fullTitle() + ': '));\n  });\n\n  runner.on('pending', function(test) {\n    var fmt = color('checkmark', '  -')\n      + color('pending', ' %s');\n    console.log(fmt, test.fullTitle());\n  });\n\n  runner.on('pass', function(test) {\n    var fmt = color('checkmark', '  ' + Base.symbols.dot)\n      + color('pass', ' %s: ')\n      + color(test.speed, '%dms');\n    cursor.CR();\n    console.log(fmt, test.fullTitle(), test.duration);\n  });\n\n  runner.on('fail', function(test) {\n    cursor.CR();\n    console.log(color('fail', '  %d) %s'), ++n, test.fullTitle());\n  });\n\n  runner.on('end', self.epilogue.bind(self));\n}\n\n/**\n * Inherit from `Base.prototype`.\n */\ninherits(List, Base);\n\n}).call(this,require('_process'))\n},{\"../utils\":39,\"./base\":17,\"_process\":51}],28:[function(require,module,exports){\n(function (process){\n/**\n * Module dependencies.\n */\n\nvar Base = require('./base');\nvar utils = require('../utils');\n\n/**\n * Constants\n */\n\nvar SUITE_PREFIX = '$';\n\n/**\n * Expose `Markdown`.\n */\n\nexports = module.exports = Markdown;\n\n/**\n * Initialize a new `Markdown` reporter.\n *\n * @api public\n * @param {Runner} runner\n */\nfunction Markdown(runner) {\n  Base.call(this, runner);\n\n  var level = 0;\n  var buf = '';\n\n  function title(str) {\n    return Array(level).join('#') + ' ' + str;\n  }\n\n  function mapTOC(suite, obj) {\n    var ret = obj;\n    var key = SUITE_PREFIX + suite.title;\n\n    obj = obj[key] = obj[key] || { suite: suite };\n    suite.suites.forEach(function(suite) {\n      mapTOC(suite, obj);\n    });\n\n    return ret;\n  }\n\n  function stringifyTOC(obj, level) {\n    ++level;\n    var buf = '';\n    var link;\n    for (var key in obj) {\n      if (key === 'suite') {\n        continue;\n      }\n      if (key !== SUITE_PREFIX) {\n        link = ' - [' + key.substring(1) + ']';\n        link += '(#' + utils.slug(obj[key].suite.fullTitle()) + ')\\n';\n        buf += Array(level).join('  ') + link;\n      }\n      buf += stringifyTOC(obj[key], level);\n    }\n    return buf;\n  }\n\n  function generateTOC(suite) {\n    var obj = mapTOC(suite, {});\n    return stringifyTOC(obj, 0);\n  }\n\n  generateTOC(runner.suite);\n\n  runner.on('suite', function(suite) {\n    ++level;\n    var slug = utils.slug(suite.fullTitle());\n    buf += '<a name=\"' + slug + '\"></a>' + '\\n';\n    buf += title(suite.title) + '\\n';\n  });\n\n  runner.on('suite end', function() {\n    --level;\n  });\n\n  runner.on('pass', function(test) {\n    var code = utils.clean(test.fn.toString());\n    buf += test.title + '.\\n';\n    buf += '\\n```js\\n';\n    buf += code + '\\n';\n    buf += '```\\n\\n';\n  });\n\n  runner.on('end', function() {\n    process.stdout.write('# TOC\\n');\n    process.stdout.write(generateTOC(runner.suite));\n    process.stdout.write(buf);\n  });\n}\n\n}).call(this,require('_process'))\n},{\"../utils\":39,\"./base\":17,\"_process\":51}],29:[function(require,module,exports){\n(function (process){\n/**\n * Module dependencies.\n */\n\nvar Base = require('./base');\nvar inherits = require('../utils').inherits;\n\n/**\n * Expose `Min`.\n */\n\nexports = module.exports = Min;\n\n/**\n * Initialize a new `Min` minimal test reporter (best used with --watch).\n *\n * @api public\n * @param {Runner} runner\n */\nfunction Min(runner) {\n  Base.call(this, runner);\n\n  runner.on('start', function() {\n    // clear screen\n    process.stdout.write('\\u001b[2J');\n    // set cursor position\n    process.stdout.write('\\u001b[1;3H');\n  });\n\n  runner.on('end', this.epilogue.bind(this));\n}\n\n/**\n * Inherit from `Base.prototype`.\n */\ninherits(Min, Base);\n\n}).call(this,require('_process'))\n},{\"../utils\":39,\"./base\":17,\"_process\":51}],30:[function(require,module,exports){\n(function (process){\n/**\n * Module dependencies.\n */\n\nvar Base = require('./base');\nvar inherits = require('../utils').inherits;\n\n/**\n * Expose `Dot`.\n */\n\nexports = module.exports = NyanCat;\n\n/**\n * Initialize a new `Dot` matrix test reporter.\n *\n * @param {Runner} runner\n * @api public\n */\n\nfunction NyanCat(runner) {\n  Base.call(this, runner);\n\n  var self = this;\n  var width = Base.window.width * .75 | 0;\n  var nyanCatWidth = this.nyanCatWidth = 11;\n\n  this.colorIndex = 0;\n  this.numberOfLines = 4;\n  this.rainbowColors = self.generateColors();\n  this.scoreboardWidth = 5;\n  this.tick = 0;\n  this.trajectories = [[], [], [], []];\n  this.trajectoryWidthMax = (width - nyanCatWidth);\n\n  runner.on('start', function() {\n    Base.cursor.hide();\n    self.draw();\n  });\n\n  runner.on('pending', function() {\n    self.draw();\n  });\n\n  runner.on('pass', function() {\n    self.draw();\n  });\n\n  runner.on('fail', function() {\n    self.draw();\n  });\n\n  runner.on('end', function() {\n    Base.cursor.show();\n    for (var i = 0; i < self.numberOfLines; i++) {\n      write('\\n');\n    }\n    self.epilogue();\n  });\n}\n\n/**\n * Inherit from `Base.prototype`.\n */\ninherits(NyanCat, Base);\n\n/**\n * Draw the nyan cat\n *\n * @api private\n */\n\nNyanCat.prototype.draw = function() {\n  this.appendRainbow();\n  this.drawScoreboard();\n  this.drawRainbow();\n  this.drawNyanCat();\n  this.tick = !this.tick;\n};\n\n/**\n * Draw the \"scoreboard\" showing the number\n * of passes, failures and pending tests.\n *\n * @api private\n */\n\nNyanCat.prototype.drawScoreboard = function() {\n  var stats = this.stats;\n\n  function draw(type, n) {\n    write(' ');\n    write(Base.color(type, n));\n    write('\\n');\n  }\n\n  draw('green', stats.passes);\n  draw('fail', stats.failures);\n  draw('pending', stats.pending);\n  write('\\n');\n\n  this.cursorUp(this.numberOfLines);\n};\n\n/**\n * Append the rainbow.\n *\n * @api private\n */\n\nNyanCat.prototype.appendRainbow = function() {\n  var segment = this.tick ? '_' : '-';\n  var rainbowified = this.rainbowify(segment);\n\n  for (var index = 0; index < this.numberOfLines; index++) {\n    var trajectory = this.trajectories[index];\n    if (trajectory.length >= this.trajectoryWidthMax) {\n      trajectory.shift();\n    }\n    trajectory.push(rainbowified);\n  }\n};\n\n/**\n * Draw the rainbow.\n *\n * @api private\n */\n\nNyanCat.prototype.drawRainbow = function() {\n  var self = this;\n\n  this.trajectories.forEach(function(line) {\n    write('\\u001b[' + self.scoreboardWidth + 'C');\n    write(line.join(''));\n    write('\\n');\n  });\n\n  this.cursorUp(this.numberOfLines);\n};\n\n/**\n * Draw the nyan cat\n *\n * @api private\n */\nNyanCat.prototype.drawNyanCat = function() {\n  var self = this;\n  var startWidth = this.scoreboardWidth + this.trajectories[0].length;\n  var dist = '\\u001b[' + startWidth + 'C';\n  var padding = '';\n\n  write(dist);\n  write('_,------,');\n  write('\\n');\n\n  write(dist);\n  padding = self.tick ? '  ' : '   ';\n  write('_|' + padding + '/\\\\_/\\\\ ');\n  write('\\n');\n\n  write(dist);\n  padding = self.tick ? '_' : '__';\n  var tail = self.tick ? '~' : '^';\n  write(tail + '|' + padding + this.face() + ' ');\n  write('\\n');\n\n  write(dist);\n  padding = self.tick ? ' ' : '  ';\n  write(padding + '\"\"  \"\" ');\n  write('\\n');\n\n  this.cursorUp(this.numberOfLines);\n};\n\n/**\n * Draw nyan cat face.\n *\n * @api private\n * @return {string}\n */\n\nNyanCat.prototype.face = function() {\n  var stats = this.stats;\n  if (stats.failures) {\n    return '( x .x)';\n  } else if (stats.pending) {\n    return '( o .o)';\n  } else if (stats.passes) {\n    return '( ^ .^)';\n  }\n  return '( - .-)';\n};\n\n/**\n * Move cursor up `n`.\n *\n * @api private\n * @param {number} n\n */\n\nNyanCat.prototype.cursorUp = function(n) {\n  write('\\u001b[' + n + 'A');\n};\n\n/**\n * Move cursor down `n`.\n *\n * @api private\n * @param {number} n\n */\n\nNyanCat.prototype.cursorDown = function(n) {\n  write('\\u001b[' + n + 'B');\n};\n\n/**\n * Generate rainbow colors.\n *\n * @api private\n * @return {Array}\n */\nNyanCat.prototype.generateColors = function() {\n  var colors = [];\n\n  for (var i = 0; i < (6 * 7); i++) {\n    var pi3 = Math.floor(Math.PI / 3);\n    var n = (i * (1.0 / 6));\n    var r = Math.floor(3 * Math.sin(n) + 3);\n    var g = Math.floor(3 * Math.sin(n + 2 * pi3) + 3);\n    var b = Math.floor(3 * Math.sin(n + 4 * pi3) + 3);\n    colors.push(36 * r + 6 * g + b + 16);\n  }\n\n  return colors;\n};\n\n/**\n * Apply rainbow to the given `str`.\n *\n * @api private\n * @param {string} str\n * @return {string}\n */\nNyanCat.prototype.rainbowify = function(str) {\n  if (!Base.useColors) {\n    return str;\n  }\n  var color = this.rainbowColors[this.colorIndex % this.rainbowColors.length];\n  this.colorIndex += 1;\n  return '\\u001b[38;5;' + color + 'm' + str + '\\u001b[0m';\n};\n\n/**\n * Stdout helper.\n *\n * @param {string} string A message to write to stdout.\n */\nfunction write(string) {\n  process.stdout.write(string);\n}\n\n}).call(this,require('_process'))\n},{\"../utils\":39,\"./base\":17,\"_process\":51}],31:[function(require,module,exports){\n(function (process){\n/**\n * Module dependencies.\n */\n\nvar Base = require('./base');\nvar inherits = require('../utils').inherits;\nvar color = Base.color;\nvar cursor = Base.cursor;\n\n/**\n * Expose `Progress`.\n */\n\nexports = module.exports = Progress;\n\n/**\n * General progress bar color.\n */\n\nBase.colors.progress = 90;\n\n/**\n * Initialize a new `Progress` bar test reporter.\n *\n * @api public\n * @param {Runner} runner\n * @param {Object} options\n */\nfunction Progress(runner, options) {\n  Base.call(this, runner);\n\n  var self = this;\n  var width = Base.window.width * .50 | 0;\n  var total = runner.total;\n  var complete = 0;\n  var lastN = -1;\n\n  // default chars\n  options = options || {};\n  options.open = options.open || '[';\n  options.complete = options.complete || '▬';\n  options.incomplete = options.incomplete || Base.symbols.dot;\n  options.close = options.close || ']';\n  options.verbose = false;\n\n  // tests started\n  runner.on('start', function() {\n    console.log();\n    cursor.hide();\n  });\n\n  // tests complete\n  runner.on('test end', function() {\n    complete++;\n\n    var percent = complete / total;\n    var n = width * percent | 0;\n    var i = width - n;\n\n    if (n === lastN && !options.verbose) {\n      // Don't re-render the line if it hasn't changed\n      return;\n    }\n    lastN = n;\n\n    cursor.CR();\n    process.stdout.write('\\u001b[J');\n    process.stdout.write(color('progress', '  ' + options.open));\n    process.stdout.write(Array(n).join(options.complete));\n    process.stdout.write(Array(i).join(options.incomplete));\n    process.stdout.write(color('progress', options.close));\n    if (options.verbose) {\n      process.stdout.write(color('progress', ' ' + complete + ' of ' + total));\n    }\n  });\n\n  // tests are complete, output some stats\n  // and the failures if any\n  runner.on('end', function() {\n    cursor.show();\n    console.log();\n    self.epilogue();\n  });\n}\n\n/**\n * Inherit from `Base.prototype`.\n */\ninherits(Progress, Base);\n\n}).call(this,require('_process'))\n},{\"../utils\":39,\"./base\":17,\"_process\":51}],32:[function(require,module,exports){\n/**\n * Module dependencies.\n */\n\nvar Base = require('./base');\nvar inherits = require('../utils').inherits;\nvar color = Base.color;\nvar cursor = Base.cursor;\n\n/**\n * Expose `Spec`.\n */\n\nexports = module.exports = Spec;\n\n/**\n * Initialize a new `Spec` test reporter.\n *\n * @api public\n * @param {Runner} runner\n */\nfunction Spec(runner) {\n  Base.call(this, runner);\n\n  var self = this;\n  var indents = 0;\n  var n = 0;\n\n  function indent() {\n    return Array(indents).join('  ');\n  }\n\n  runner.on('start', function() {\n    console.log();\n  });\n\n  runner.on('suite', function(suite) {\n    ++indents;\n    console.log(color('suite', '%s%s'), indent(), suite.title);\n  });\n\n  runner.on('suite end', function() {\n    --indents;\n    if (indents === 1) {\n      console.log();\n    }\n  });\n\n  runner.on('pending', function(test) {\n    var fmt = indent() + color('pending', '  - %s');\n    console.log(fmt, test.title);\n  });\n\n  runner.on('pass', function(test) {\n    var fmt;\n    if (test.speed === 'fast') {\n      fmt = indent()\n        + color('checkmark', '  ' + Base.symbols.ok)\n        + color('pass', ' %s');\n      cursor.CR();\n      console.log(fmt, test.title);\n    } else {\n      fmt = indent()\n        + color('checkmark', '  ' + Base.symbols.ok)\n        + color('pass', ' %s')\n        + color(test.speed, ' (%dms)');\n      cursor.CR();\n      console.log(fmt, test.title, test.duration);\n    }\n  });\n\n  runner.on('fail', function(test) {\n    cursor.CR();\n    console.log(indent() + color('fail', '  %d) %s'), ++n, test.title);\n  });\n\n  runner.on('end', self.epilogue.bind(self));\n}\n\n/**\n * Inherit from `Base.prototype`.\n */\ninherits(Spec, Base);\n\n},{\"../utils\":39,\"./base\":17}],33:[function(require,module,exports){\n/**\n * Module dependencies.\n */\n\nvar Base = require('./base');\n\n/**\n * Expose `TAP`.\n */\n\nexports = module.exports = TAP;\n\n/**\n * Initialize a new `TAP` reporter.\n *\n * @api public\n * @param {Runner} runner\n */\nfunction TAP(runner) {\n  Base.call(this, runner);\n\n  var n = 1;\n  var passes = 0;\n  var failures = 0;\n\n  runner.on('start', function() {\n    var total = runner.grepTotal(runner.suite);\n    console.log('%d..%d', 1, total);\n  });\n\n  runner.on('test end', function() {\n    ++n;\n  });\n\n  runner.on('pending', function(test) {\n    console.log('ok %d %s # SKIP -', n, title(test));\n  });\n\n  runner.on('pass', function(test) {\n    passes++;\n    console.log('ok %d %s', n, title(test));\n  });\n\n  runner.on('fail', function(test, err) {\n    failures++;\n    console.log('not ok %d %s', n, title(test));\n    if (err.stack) {\n      console.log(err.stack.replace(/^/gm, '  '));\n    }\n  });\n\n  runner.on('end', function() {\n    console.log('# tests ' + (passes + failures));\n    console.log('# pass ' + passes);\n    console.log('# fail ' + failures);\n  });\n}\n\n/**\n * Return a TAP-safe title of `test`\n *\n * @api private\n * @param {Object} test\n * @return {String}\n */\nfunction title(test) {\n  return test.fullTitle().replace(/#/g, '');\n}\n\n},{\"./base\":17}],34:[function(require,module,exports){\n(function (global){\n/**\n * Module dependencies.\n */\n\nvar Base = require('./base');\nvar utils = require('../utils');\nvar inherits = utils.inherits;\nvar fs = require('fs');\nvar escape = utils.escape;\n\n/**\n * Save timer references to avoid Sinon interfering (see GH-237).\n */\n\n/* eslint-disable no-unused-vars, no-native-reassign */\nvar Date = global.Date;\nvar setTimeout = global.setTimeout;\nvar setInterval = global.setInterval;\nvar clearTimeout = global.clearTimeout;\nvar clearInterval = global.clearInterval;\n/* eslint-enable no-unused-vars, no-native-reassign */\n\n/**\n * Expose `XUnit`.\n */\n\nexports = module.exports = XUnit;\n\n/**\n * Initialize a new `XUnit` reporter.\n *\n * @api public\n * @param {Runner} runner\n */\nfunction XUnit(runner, options) {\n  Base.call(this, runner);\n\n  var stats = this.stats;\n  var tests = [];\n  var self = this;\n\n  if (options.reporterOptions && options.reporterOptions.output) {\n    if (!fs.createWriteStream) {\n      throw new Error('file output not supported in browser');\n    }\n    self.fileStream = fs.createWriteStream(options.reporterOptions.output);\n  }\n\n  runner.on('pending', function(test) {\n    tests.push(test);\n  });\n\n  runner.on('pass', function(test) {\n    tests.push(test);\n  });\n\n  runner.on('fail', function(test) {\n    tests.push(test);\n  });\n\n  runner.on('end', function() {\n    self.write(tag('testsuite', {\n      name: 'Mocha Tests',\n      tests: stats.tests,\n      failures: stats.failures,\n      errors: stats.failures,\n      skipped: stats.tests - stats.failures - stats.passes,\n      timestamp: (new Date()).toUTCString(),\n      time: (stats.duration / 1000) || 0\n    }, false));\n\n    tests.forEach(function(t) {\n      self.test(t);\n    });\n\n    self.write('</testsuite>');\n  });\n}\n\n/**\n * Inherit from `Base.prototype`.\n */\ninherits(XUnit, Base);\n\n/**\n * Override done to close the stream (if it's a file).\n *\n * @param failures\n * @param {Function} fn\n */\nXUnit.prototype.done = function(failures, fn) {\n  if (this.fileStream) {\n    this.fileStream.end(function() {\n      fn(failures);\n    });\n  } else {\n    fn(failures);\n  }\n};\n\n/**\n * Write out the given line.\n *\n * @param {string} line\n */\nXUnit.prototype.write = function(line) {\n  if (this.fileStream) {\n    this.fileStream.write(line + '\\n');\n  } else {\n    console.log(line);\n  }\n};\n\n/**\n * Output tag for the given `test.`\n *\n * @param {Test} test\n */\nXUnit.prototype.test = function(test) {\n  var attrs = {\n    classname: test.parent.fullTitle(),\n    name: test.title,\n    time: (test.duration / 1000) || 0\n  };\n\n  if (test.state === 'failed') {\n    var err = test.err;\n    this.write(tag('testcase', attrs, false, tag('failure', {}, false, cdata(escape(err.message) + '\\n' + err.stack))));\n  } else if (test.pending) {\n    this.write(tag('testcase', attrs, false, tag('skipped', {}, true)));\n  } else {\n    this.write(tag('testcase', attrs, true));\n  }\n};\n\n/**\n * HTML tag helper.\n *\n * @param name\n * @param attrs\n * @param close\n * @param content\n * @return {string}\n */\nfunction tag(name, attrs, close, content) {\n  var end = close ? '/>' : '>';\n  var pairs = [];\n  var tag;\n\n  for (var key in attrs) {\n    if (Object.prototype.hasOwnProperty.call(attrs, key)) {\n      pairs.push(key + '=\"' + escape(attrs[key]) + '\"');\n    }\n  }\n\n  tag = '<' + name + (pairs.length ? ' ' + pairs.join(' ') : '') + end;\n  if (content) {\n    tag += content + '</' + name + end;\n  }\n  return tag;\n}\n\n/**\n * Return cdata escaped CDATA `str`.\n */\n\nfunction cdata(str) {\n  return '<![CDATA[' + escape(str) + ']]>';\n}\n\n}).call(this,typeof global !== \"undefined\" ? global : typeof self !== \"undefined\" ? self : typeof window !== \"undefined\" ? window : {})\n},{\"../utils\":39,\"./base\":17,\"fs\":41}],35:[function(require,module,exports){\n(function (global){\n/**\n * Module dependencies.\n */\n\nvar EventEmitter = require('events').EventEmitter;\nvar Pending = require('./pending');\nvar debug = require('debug')('mocha:runnable');\nvar milliseconds = require('./ms');\nvar utils = require('./utils');\nvar inherits = utils.inherits;\n\n/**\n * Save timer references to avoid Sinon interfering (see GH-237).\n */\n\n/* eslint-disable no-unused-vars, no-native-reassign */\nvar Date = global.Date;\nvar setTimeout = global.setTimeout;\nvar setInterval = global.setInterval;\nvar clearTimeout = global.clearTimeout;\nvar clearInterval = global.clearInterval;\n/* eslint-enable no-unused-vars, no-native-reassign */\n\n/**\n * Object#toString().\n */\n\nvar toString = Object.prototype.toString;\n\n/**\n * Expose `Runnable`.\n */\n\nmodule.exports = Runnable;\n\n/**\n * Initialize a new `Runnable` with the given `title` and callback `fn`.\n *\n * @param {String} title\n * @param {Function} fn\n * @api private\n * @param {string} title\n * @param {Function} fn\n */\nfunction Runnable(title, fn) {\n  this.title = title;\n  this.fn = fn;\n  this.async = fn && fn.length;\n  this.sync = !this.async;\n  this._timeout = 2000;\n  this._slow = 75;\n  this._enableTimeouts = true;\n  this.timedOut = false;\n  this._trace = new Error('done() called multiple times');\n}\n\n/**\n * Inherit from `EventEmitter.prototype`.\n */\ninherits(Runnable, EventEmitter);\n\n/**\n * Set & get timeout `ms`.\n *\n * @api private\n * @param {number|string} ms\n * @return {Runnable|number} ms or Runnable instance.\n */\nRunnable.prototype.timeout = function(ms) {\n  if (!arguments.length) {\n    return this._timeout;\n  }\n  if (ms === 0) {\n    this._enableTimeouts = false;\n  }\n  if (typeof ms === 'string') {\n    ms = milliseconds(ms);\n  }\n  debug('timeout %d', ms);\n  this._timeout = ms;\n  if (this.timer) {\n    this.resetTimeout();\n  }\n  return this;\n};\n\n/**\n * Set & get slow `ms`.\n *\n * @api private\n * @param {number|string} ms\n * @return {Runnable|number} ms or Runnable instance.\n */\nRunnable.prototype.slow = function(ms) {\n  if (!arguments.length) {\n    return this._slow;\n  }\n  if (typeof ms === 'string') {\n    ms = milliseconds(ms);\n  }\n  debug('timeout %d', ms);\n  this._slow = ms;\n  return this;\n};\n\n/**\n * Set and get whether timeout is `enabled`.\n *\n * @api private\n * @param {boolean} enabled\n * @return {Runnable|boolean} enabled or Runnable instance.\n */\nRunnable.prototype.enableTimeouts = function(enabled) {\n  if (!arguments.length) {\n    return this._enableTimeouts;\n  }\n  debug('enableTimeouts %s', enabled);\n  this._enableTimeouts = enabled;\n  return this;\n};\n\n/**\n * Halt and mark as pending.\n *\n * @api private\n */\nRunnable.prototype.skip = function() {\n  throw new Pending();\n};\n\n/**\n * Return the full title generated by recursively concatenating the parent's\n * full title.\n *\n * @api public\n * @return {string}\n */\nRunnable.prototype.fullTitle = function() {\n  return this.parent.fullTitle() + ' ' + this.title;\n};\n\n/**\n * Clear the timeout.\n *\n * @api private\n */\nRunnable.prototype.clearTimeout = function() {\n  clearTimeout(this.timer);\n};\n\n/**\n * Inspect the runnable void of private properties.\n *\n * @api private\n * @return {string}\n */\nRunnable.prototype.inspect = function() {\n  return JSON.stringify(this, function(key, val) {\n    if (key[0] === '_') {\n      return;\n    }\n    if (key === 'parent') {\n      return '#<Suite>';\n    }\n    if (key === 'ctx') {\n      return '#<Context>';\n    }\n    return val;\n  }, 2);\n};\n\n/**\n * Reset the timeout.\n *\n * @api private\n */\nRunnable.prototype.resetTimeout = function() {\n  var self = this;\n  var ms = this.timeout() || 1e9;\n\n  if (!this._enableTimeouts) {\n    return;\n  }\n  this.clearTimeout();\n  this.timer = setTimeout(function() {\n    if (!self._enableTimeouts) {\n      return;\n    }\n    self.callback(new Error('timeout of ' + ms + 'ms exceeded. Ensure the done() callback is being called in this test.'));\n    self.timedOut = true;\n  }, ms);\n};\n\n/**\n * Whitelist a list of globals for this test run.\n *\n * @api private\n * @param {string[]} globals\n */\nRunnable.prototype.globals = function(globals) {\n  this._allowedGlobals = globals;\n};\n\n/**\n * Run the test and invoke `fn(err)`.\n *\n * @param {Function} fn\n * @api private\n */\nRunnable.prototype.run = function(fn) {\n  var self = this;\n  var start = new Date();\n  var ctx = this.ctx;\n  var finished;\n  var emitted;\n\n  // Sometimes the ctx exists, but it is not runnable\n  if (ctx && ctx.runnable) {\n    ctx.runnable(this);\n  }\n\n  // called multiple times\n  function multiple(err) {\n    if (emitted) {\n      return;\n    }\n    emitted = true;\n    self.emit('error', err || new Error('done() called multiple times; stacktrace may be inaccurate'));\n  }\n\n  // finished\n  function done(err) {\n    var ms = self.timeout();\n    if (self.timedOut) {\n      return;\n    }\n    if (finished) {\n      return multiple(err || self._trace);\n    }\n\n    self.clearTimeout();\n    self.duration = new Date() - start;\n    finished = true;\n    if (!err && self.duration > ms && self._enableTimeouts) {\n      err = new Error('timeout of ' + ms + 'ms exceeded. Ensure the done() callback is being called in this test.');\n    }\n    fn(err);\n  }\n\n  // for .resetTimeout()\n  this.callback = done;\n\n  // explicit async with `done` argument\n  if (this.async) {\n    this.resetTimeout();\n\n    if (this.allowUncaught) {\n      return callFnAsync(this.fn);\n    }\n    try {\n      callFnAsync(this.fn);\n    } catch (err) {\n      done(utils.getError(err));\n    }\n    return;\n  }\n\n  if (this.allowUncaught) {\n    callFn(this.fn);\n    done();\n    return;\n  }\n\n  // sync or promise-returning\n  try {\n    if (this.pending) {\n      done();\n    } else {\n      callFn(this.fn);\n    }\n  } catch (err) {\n    done(utils.getError(err));\n  }\n\n  function callFn(fn) {\n    var result = fn.call(ctx);\n    if (result && typeof result.then === 'function') {\n      self.resetTimeout();\n      result\n        .then(function() {\n          done();\n        },\n        function(reason) {\n          done(reason || new Error('Promise rejected with no or falsy reason'));\n        });\n    } else {\n      if (self.asyncOnly) {\n        return done(new Error('--async-only option in use without declaring `done()` or returning a promise'));\n      }\n\n      done();\n    }\n  }\n\n  function callFnAsync(fn) {\n    fn.call(ctx, function(err) {\n      if (err instanceof Error || toString.call(err) === '[object Error]') {\n        return done(err);\n      }\n      if (err) {\n        if (Object.prototype.toString.call(err) === '[object Object]') {\n          return done(new Error('done() invoked with non-Error: '\n            + JSON.stringify(err)));\n        }\n        return done(new Error('done() invoked with non-Error: ' + err));\n      }\n      done();\n    });\n  }\n};\n\n}).call(this,typeof global !== \"undefined\" ? global : typeof self !== \"undefined\" ? self : typeof window !== \"undefined\" ? window : {})\n},{\"./ms\":15,\"./pending\":16,\"./utils\":39,\"debug\":2,\"events\":3}],36:[function(require,module,exports){\n(function (process,global){\n/**\n * Module dependencies.\n */\n\nvar EventEmitter = require('events').EventEmitter;\nvar Pending = require('./pending');\nvar utils = require('./utils');\nvar inherits = utils.inherits;\nvar debug = require('debug')('mocha:runner');\nvar Runnable = require('./runnable');\nvar filter = utils.filter;\nvar indexOf = utils.indexOf;\nvar keys = utils.keys;\nvar stackFilter = utils.stackTraceFilter();\nvar stringify = utils.stringify;\nvar type = utils.type;\nvar undefinedError = utils.undefinedError;\n\n/**\n * Non-enumerable globals.\n */\n\nvar globals = [\n  'setTimeout',\n  'clearTimeout',\n  'setInterval',\n  'clearInterval',\n  'XMLHttpRequest',\n  'Date',\n  'setImmediate',\n  'clearImmediate'\n];\n\n/**\n * Expose `Runner`.\n */\n\nmodule.exports = Runner;\n\n/**\n * Initialize a `Runner` for the given `suite`.\n *\n * Events:\n *\n *   - `start`  execution started\n *   - `end`  execution complete\n *   - `suite`  (suite) test suite execution started\n *   - `suite end`  (suite) all tests (and sub-suites) have finished\n *   - `test`  (test) test execution started\n *   - `test end`  (test) test completed\n *   - `hook`  (hook) hook execution started\n *   - `hook end`  (hook) hook complete\n *   - `pass`  (test) test passed\n *   - `fail`  (test, err) test failed\n *   - `pending`  (test) test pending\n *\n * @api public\n * @param {Suite} suite Root suite\n * @param {boolean} [delay] Whether or not to delay execution of root suite\n * until ready.\n */\nfunction Runner(suite, delay) {\n  var self = this;\n  this._globals = [];\n  this._abort = false;\n  this._delay = delay;\n  this.suite = suite;\n  this.started = false;\n  this.total = suite.total();\n  this.failures = 0;\n  this.on('test end', function(test) {\n    self.checkGlobals(test);\n  });\n  this.on('hook end', function(hook) {\n    self.checkGlobals(hook);\n  });\n  this._defaultGrep = /.*/;\n  this.grep(this._defaultGrep);\n  this.globals(this.globalProps().concat(extraGlobals()));\n}\n\n/**\n * Wrapper for setImmediate, process.nextTick, or browser polyfill.\n *\n * @param {Function} fn\n * @api private\n */\nRunner.immediately = global.setImmediate || process.nextTick;\n\n/**\n * Inherit from `EventEmitter.prototype`.\n */\ninherits(Runner, EventEmitter);\n\n/**\n * Run tests with full titles matching `re`. Updates runner.total\n * with number of tests matched.\n *\n * @param {RegExp} re\n * @param {Boolean} invert\n * @return {Runner} for chaining\n * @api public\n * @param {RegExp} re\n * @param {boolean} invert\n * @return {Runner} Runner instance.\n */\nRunner.prototype.grep = function(re, invert) {\n  debug('grep %s', re);\n  this._grep = re;\n  this._invert = invert;\n  this.total = this.grepTotal(this.suite);\n  return this;\n};\n\n/**\n * Returns the number of tests matching the grep search for the\n * given suite.\n *\n * @param {Suite} suite\n * @return {Number}\n * @api public\n * @param {Suite} suite\n * @return {number}\n */\nRunner.prototype.grepTotal = function(suite) {\n  var self = this;\n  var total = 0;\n\n  suite.eachTest(function(test) {\n    var match = self._grep.test(test.fullTitle());\n    if (self._invert) {\n      match = !match;\n    }\n    if (match) {\n      total++;\n    }\n  });\n\n  return total;\n};\n\n/**\n * Return a list of global properties.\n *\n * @return {Array}\n * @api private\n */\nRunner.prototype.globalProps = function() {\n  var props = keys(global);\n\n  // non-enumerables\n  for (var i = 0; i < globals.length; ++i) {\n    if (~indexOf(props, globals[i])) {\n      continue;\n    }\n    props.push(globals[i]);\n  }\n\n  return props;\n};\n\n/**\n * Allow the given `arr` of globals.\n *\n * @param {Array} arr\n * @return {Runner} for chaining\n * @api public\n * @param {Array} arr\n * @return {Runner} Runner instance.\n */\nRunner.prototype.globals = function(arr) {\n  if (!arguments.length) {\n    return this._globals;\n  }\n  debug('globals %j', arr);\n  this._globals = this._globals.concat(arr);\n  return this;\n};\n\n/**\n * Check for global variable leaks.\n *\n * @api private\n */\nRunner.prototype.checkGlobals = function(test) {\n  if (this.ignoreLeaks) {\n    return;\n  }\n  var ok = this._globals;\n\n  var globals = this.globalProps();\n  var leaks;\n\n  if (test) {\n    ok = ok.concat(test._allowedGlobals || []);\n  }\n\n  if (this.prevGlobalsLength === globals.length) {\n    return;\n  }\n  this.prevGlobalsLength = globals.length;\n\n  leaks = filterLeaks(ok, globals);\n  this._globals = this._globals.concat(leaks);\n\n  if (leaks.length > 1) {\n    this.fail(test, new Error('global leaks detected: ' + leaks.join(', ') + ''));\n  } else if (leaks.length) {\n    this.fail(test, new Error('global leak detected: ' + leaks[0]));\n  }\n};\n\n/**\n * Fail the given `test`.\n *\n * @api private\n * @param {Test} test\n * @param {Error} err\n */\nRunner.prototype.fail = function(test, err) {\n  ++this.failures;\n  test.state = 'failed';\n\n  if (!(err instanceof Error || err && typeof err.message === 'string')) {\n    err = new Error('the ' + type(err) + ' ' + stringify(err) + ' was thrown, throw an Error :)');\n  }\n\n  err.stack = (this.fullStackTrace || !err.stack)\n    ? err.stack\n    : stackFilter(err.stack);\n\n  this.emit('fail', test, err);\n};\n\n/**\n * Fail the given `hook` with `err`.\n *\n * Hook failures work in the following pattern:\n * - If bail, then exit\n * - Failed `before` hook skips all tests in a suite and subsuites,\n *   but jumps to corresponding `after` hook\n * - Failed `before each` hook skips remaining tests in a\n *   suite and jumps to corresponding `after each` hook,\n *   which is run only once\n * - Failed `after` hook does not alter\n *   execution order\n * - Failed `after each` hook skips remaining tests in a\n *   suite and subsuites, but executes other `after each`\n *   hooks\n *\n * @api private\n * @param {Hook} hook\n * @param {Error} err\n */\nRunner.prototype.failHook = function(hook, err) {\n  if (hook.ctx && hook.ctx.currentTest) {\n    hook.originalTitle = hook.originalTitle || hook.title;\n    hook.title = hook.originalTitle + ' for \"' + hook.ctx.currentTest.title + '\"';\n  }\n\n  this.fail(hook, err);\n  if (this.suite.bail()) {\n    this.emit('end');\n  }\n};\n\n/**\n * Run hook `name` callbacks and then invoke `fn()`.\n *\n * @api private\n * @param {string} name\n * @param {Function} fn\n */\n\nRunner.prototype.hook = function(name, fn) {\n  var suite = this.suite;\n  var hooks = suite['_' + name];\n  var self = this;\n\n  function next(i) {\n    var hook = hooks[i];\n    if (!hook) {\n      return fn();\n    }\n    self.currentRunnable = hook;\n\n    hook.ctx.currentTest = self.test;\n\n    self.emit('hook', hook);\n\n    if (!hook.listeners('error').length) {\n      hook.on('error', function(err) {\n        self.failHook(hook, err);\n      });\n    }\n\n    hook.run(function(err) {\n      var testError = hook.error();\n      if (testError) {\n        self.fail(self.test, testError);\n      }\n      if (err) {\n        if (err instanceof Pending) {\n          suite.pending = true;\n        } else {\n          self.failHook(hook, err);\n\n          // stop executing hooks, notify callee of hook err\n          return fn(err);\n        }\n      }\n      self.emit('hook end', hook);\n      delete hook.ctx.currentTest;\n      next(++i);\n    });\n  }\n\n  Runner.immediately(function() {\n    next(0);\n  });\n};\n\n/**\n * Run hook `name` for the given array of `suites`\n * in order, and callback `fn(err, errSuite)`.\n *\n * @api private\n * @param {string} name\n * @param {Array} suites\n * @param {Function} fn\n */\nRunner.prototype.hooks = function(name, suites, fn) {\n  var self = this;\n  var orig = this.suite;\n\n  function next(suite) {\n    self.suite = suite;\n\n    if (!suite) {\n      self.suite = orig;\n      return fn();\n    }\n\n    self.hook(name, function(err) {\n      if (err) {\n        var errSuite = self.suite;\n        self.suite = orig;\n        return fn(err, errSuite);\n      }\n\n      next(suites.pop());\n    });\n  }\n\n  next(suites.pop());\n};\n\n/**\n * Run hooks from the top level down.\n *\n * @param {String} name\n * @param {Function} fn\n * @api private\n */\nRunner.prototype.hookUp = function(name, fn) {\n  var suites = [this.suite].concat(this.parents()).reverse();\n  this.hooks(name, suites, fn);\n};\n\n/**\n * Run hooks from the bottom up.\n *\n * @param {String} name\n * @param {Function} fn\n * @api private\n */\nRunner.prototype.hookDown = function(name, fn) {\n  var suites = [this.suite].concat(this.parents());\n  this.hooks(name, suites, fn);\n};\n\n/**\n * Return an array of parent Suites from\n * closest to furthest.\n *\n * @return {Array}\n * @api private\n */\nRunner.prototype.parents = function() {\n  var suite = this.suite;\n  var suites = [];\n  while (suite.parent) {\n    suite = suite.parent;\n    suites.push(suite);\n  }\n  return suites;\n};\n\n/**\n * Run the current test and callback `fn(err)`.\n *\n * @param {Function} fn\n * @api private\n */\nRunner.prototype.runTest = function(fn) {\n  var self = this;\n  var test = this.test;\n\n  if (this.asyncOnly) {\n    test.asyncOnly = true;\n  }\n\n  if (this.allowUncaught) {\n    test.allowUncaught = true;\n    return test.run(fn);\n  }\n  try {\n    test.on('error', function(err) {\n      self.fail(test, err);\n    });\n    test.run(fn);\n  } catch (err) {\n    fn(err);\n  }\n};\n\n/**\n * Run tests in the given `suite` and invoke the callback `fn()` when complete.\n *\n * @api private\n * @param {Suite} suite\n * @param {Function} fn\n */\nRunner.prototype.runTests = function(suite, fn) {\n  var self = this;\n  var tests = suite.tests.slice();\n  var test;\n\n  function hookErr(_, errSuite, after) {\n    // before/after Each hook for errSuite failed:\n    var orig = self.suite;\n\n    // for failed 'after each' hook start from errSuite parent,\n    // otherwise start from errSuite itself\n    self.suite = after ? errSuite.parent : errSuite;\n\n    if (self.suite) {\n      // call hookUp afterEach\n      self.hookUp('afterEach', function(err2, errSuite2) {\n        self.suite = orig;\n        // some hooks may fail even now\n        if (err2) {\n          return hookErr(err2, errSuite2, true);\n        }\n        // report error suite\n        fn(errSuite);\n      });\n    } else {\n      // there is no need calling other 'after each' hooks\n      self.suite = orig;\n      fn(errSuite);\n    }\n  }\n\n  function next(err, errSuite) {\n    // if we bail after first err\n    if (self.failures && suite._bail) {\n      return fn();\n    }\n\n    if (self._abort) {\n      return fn();\n    }\n\n    if (err) {\n      return hookErr(err, errSuite, true);\n    }\n\n    // next test\n    test = tests.shift();\n\n    // all done\n    if (!test) {\n      return fn();\n    }\n\n    // grep\n    var match = self._grep.test(test.fullTitle());\n    if (self._invert) {\n      match = !match;\n    }\n    if (!match) {\n      // Run immediately only if we have defined a grep. When we\n      // define a grep — It can cause maximum callstack error if\n      // the grep is doing a large recursive loop by neglecting\n      // all tests. The run immediately function also comes with\n      // a performance cost. So we don't want to run immediately\n      // if we run the whole test suite, because running the whole\n      // test suite don't do any immediate recursive loops. Thus,\n      // allowing a JS runtime to breathe.\n      if (self._grep !== self._defaultGrep) {\n        Runner.immediately(next);\n      } else {\n        next();\n      }\n      return;\n    }\n\n    // pending\n    if (test.pending) {\n      self.emit('pending', test);\n      self.emit('test end', test);\n      return next();\n    }\n\n    // execute test and hook(s)\n    self.emit('test', self.test = test);\n    self.hookDown('beforeEach', function(err, errSuite) {\n      if (suite.pending) {\n        self.emit('pending', test);\n        self.emit('test end', test);\n        return next();\n      }\n      if (err) {\n        return hookErr(err, errSuite, false);\n      }\n      self.currentRunnable = self.test;\n      self.runTest(function(err) {\n        test = self.test;\n\n        if (err) {\n          if (err instanceof Pending) {\n            self.emit('pending', test);\n          } else {\n            self.fail(test, err);\n          }\n          self.emit('test end', test);\n\n          if (err instanceof Pending) {\n            return next();\n          }\n\n          return self.hookUp('afterEach', next);\n        }\n\n        test.state = 'passed';\n        self.emit('pass', test);\n        self.emit('test end', test);\n        self.hookUp('afterEach', next);\n      });\n    });\n  }\n\n  this.next = next;\n  this.hookErr = hookErr;\n  next();\n};\n\n/**\n * Run the given `suite` and invoke the callback `fn()` when complete.\n *\n * @api private\n * @param {Suite} suite\n * @param {Function} fn\n */\nRunner.prototype.runSuite = function(suite, fn) {\n  var i = 0;\n  var self = this;\n  var total = this.grepTotal(suite);\n  var afterAllHookCalled = false;\n\n  debug('run suite %s', suite.fullTitle());\n\n  if (!total || (self.failures && suite._bail)) {\n    return fn();\n  }\n\n  this.emit('suite', this.suite = suite);\n\n  function next(errSuite) {\n    if (errSuite) {\n      // current suite failed on a hook from errSuite\n      if (errSuite === suite) {\n        // if errSuite is current suite\n        // continue to the next sibling suite\n        return done();\n      }\n      // errSuite is among the parents of current suite\n      // stop execution of errSuite and all sub-suites\n      return done(errSuite);\n    }\n\n    if (self._abort) {\n      return done();\n    }\n\n    var curr = suite.suites[i++];\n    if (!curr) {\n      return done();\n    }\n\n    // Avoid grep neglecting large number of tests causing a\n    // huge recursive loop and thus a maximum call stack error.\n    // See comment in `this.runTests()` for more information.\n    if (self._grep !== self._defaultGrep) {\n      Runner.immediately(function() {\n        self.runSuite(curr, next);\n      });\n    } else {\n      self.runSuite(curr, next);\n    }\n  }\n\n  function done(errSuite) {\n    self.suite = suite;\n    self.nextSuite = next;\n\n    if (afterAllHookCalled) {\n      fn(errSuite);\n    } else {\n      // mark that the afterAll block has been called once\n      // and so can be skipped if there is an error in it.\n      afterAllHookCalled = true;\n      self.hook('afterAll', function() {\n        self.emit('suite end', suite);\n        fn(errSuite);\n      });\n    }\n  }\n\n  this.nextSuite = next;\n\n  this.hook('beforeAll', function(err) {\n    if (err) {\n      return done();\n    }\n    self.runTests(suite, next);\n  });\n};\n\n/**\n * Handle uncaught exceptions.\n *\n * @param {Error} err\n * @api private\n */\nRunner.prototype.uncaught = function(err) {\n  if (err) {\n    debug('uncaught exception %s', err !== function() {\n      return this;\n    }.call(err) ? err : (err.message || err));\n  } else {\n    debug('uncaught undefined exception');\n    err = undefinedError();\n  }\n  err.uncaught = true;\n\n  var runnable = this.currentRunnable;\n\n  if (!runnable) {\n    runnable = new Runnable('Uncaught error outside test suite');\n    runnable.parent = this.suite;\n\n    if (this.started) {\n      this.fail(runnable, err);\n    } else {\n      // Can't recover from this failure\n      this.emit('start');\n      this.fail(runnable, err);\n      this.emit('end');\n    }\n\n    return;\n  }\n\n  runnable.clearTimeout();\n\n  // Ignore errors if complete\n  if (runnable.state) {\n    return;\n  }\n  this.fail(runnable, err);\n\n  // recover from test\n  if (runnable.type === 'test') {\n    this.emit('test end', runnable);\n    this.hookUp('afterEach', this.next);\n    return;\n  }\n\n // recover from hooks\n  if (runnable.type === 'hook') {\n    var errSuite = this.suite;\n    // if hook failure is in afterEach block\n    if (runnable.fullTitle().indexOf('after each') > -1) {\n      return this.hookErr(err, errSuite, true);\n    }\n    // if hook failure is in beforeEach block\n    if (runnable.fullTitle().indexOf('before each') > -1) {\n      return this.hookErr(err, errSuite, false);\n    }\n    // if hook failure is in after or before blocks\n    return this.nextSuite(errSuite);\n  }\n\n  // bail\n  this.emit('end');\n};\n\n/**\n * Run the root suite and invoke `fn(failures)`\n * on completion.\n *\n * @param {Function} fn\n * @return {Runner} for chaining\n * @api public\n * @param {Function} fn\n * @return {Runner} Runner instance.\n */\nRunner.prototype.run = function(fn) {\n  var self = this;\n  var rootSuite = this.suite;\n\n  fn = fn || function() {};\n\n  function uncaught(err) {\n    self.uncaught(err);\n  }\n\n  function start() {\n    self.started = true;\n    self.emit('start');\n    self.runSuite(rootSuite, function() {\n      debug('finished running');\n      self.emit('end');\n    });\n  }\n\n  debug('start');\n\n  // callback\n  this.on('end', function() {\n    debug('end');\n    process.removeListener('uncaughtException', uncaught);\n    fn(self.failures);\n  });\n\n  // uncaught exception\n  process.on('uncaughtException', uncaught);\n\n  if (this._delay) {\n    // for reporters, I guess.\n    // might be nice to debounce some dots while we wait.\n    this.emit('waiting', rootSuite);\n    rootSuite.once('run', start);\n  } else {\n    start();\n  }\n\n  return this;\n};\n\n/**\n * Cleanly abort execution.\n *\n * @api public\n * @return {Runner} Runner instance.\n */\nRunner.prototype.abort = function() {\n  debug('aborting');\n  this._abort = true;\n\n  return this;\n};\n\n/**\n * Filter leaks with the given globals flagged as `ok`.\n *\n * @api private\n * @param {Array} ok\n * @param {Array} globals\n * @return {Array}\n */\nfunction filterLeaks(ok, globals) {\n  return filter(globals, function(key) {\n    // Firefox and Chrome exposes iframes as index inside the window object\n    if (/^d+/.test(key)) {\n      return false;\n    }\n\n    // in firefox\n    // if runner runs in an iframe, this iframe's window.getInterface method not init at first\n    // it is assigned in some seconds\n    if (global.navigator && (/^getInterface/).test(key)) {\n      return false;\n    }\n\n    // an iframe could be approached by window[iframeIndex]\n    // in ie6,7,8 and opera, iframeIndex is enumerable, this could cause leak\n    if (global.navigator && (/^\\d+/).test(key)) {\n      return false;\n    }\n\n    // Opera and IE expose global variables for HTML element IDs (issue #243)\n    if (/^mocha-/.test(key)) {\n      return false;\n    }\n\n    var matched = filter(ok, function(ok) {\n      if (~ok.indexOf('*')) {\n        return key.indexOf(ok.split('*')[0]) === 0;\n      }\n      return key === ok;\n    });\n    return !matched.length && (!global.navigator || key !== 'onerror');\n  });\n}\n\n/**\n * Array of globals dependent on the environment.\n *\n * @return {Array}\n * @api private\n */\nfunction extraGlobals() {\n  if (typeof process === 'object' && typeof process.version === 'string') {\n    var parts = process.version.split('.');\n    var nodeVersion = utils.reduce(parts, function(a, v) {\n      return a << 8 | v;\n    });\n\n    // 'errno' was renamed to process._errno in v0.9.11.\n\n    if (nodeVersion < 0x00090B) {\n      return ['errno'];\n    }\n  }\n\n  return [];\n}\n\n}).call(this,require('_process'),typeof global !== \"undefined\" ? global : typeof self !== \"undefined\" ? self : typeof window !== \"undefined\" ? window : {})\n},{\"./pending\":16,\"./runnable\":35,\"./utils\":39,\"_process\":51,\"debug\":2,\"events\":3}],37:[function(require,module,exports){\n/**\n * Module dependencies.\n */\n\nvar EventEmitter = require('events').EventEmitter;\nvar Hook = require('./hook');\nvar utils = require('./utils');\nvar inherits = utils.inherits;\nvar debug = require('debug')('mocha:suite');\nvar milliseconds = require('./ms');\n\n/**\n * Expose `Suite`.\n */\n\nexports = module.exports = Suite;\n\n/**\n * Create a new `Suite` with the given `title` and parent `Suite`. When a suite\n * with the same title is already present, that suite is returned to provide\n * nicer reporter and more flexible meta-testing.\n *\n * @api public\n * @param {Suite} parent\n * @param {string} title\n * @return {Suite}\n */\nexports.create = function(parent, title) {\n  var suite = new Suite(title, parent.ctx);\n  suite.parent = parent;\n  if (parent.pending) {\n    suite.pending = true;\n  }\n  title = suite.fullTitle();\n  parent.addSuite(suite);\n  return suite;\n};\n\n/**\n * Initialize a new `Suite` with the given `title` and `ctx`.\n *\n * @api private\n * @param {string} title\n * @param {Context} parentContext\n */\nfunction Suite(title, parentContext) {\n  this.title = title;\n  function Context() {}\n  Context.prototype = parentContext;\n  this.ctx = new Context();\n  this.suites = [];\n  this.tests = [];\n  this.pending = false;\n  this._beforeEach = [];\n  this._beforeAll = [];\n  this._afterEach = [];\n  this._afterAll = [];\n  this.root = !title;\n  this._timeout = 2000;\n  this._enableTimeouts = true;\n  this._slow = 75;\n  this._bail = false;\n  this.delayed = false;\n}\n\n/**\n * Inherit from `EventEmitter.prototype`.\n */\ninherits(Suite, EventEmitter);\n\n/**\n * Return a clone of this `Suite`.\n *\n * @api private\n * @return {Suite}\n */\nSuite.prototype.clone = function() {\n  var suite = new Suite(this.title);\n  debug('clone');\n  suite.ctx = this.ctx;\n  suite.timeout(this.timeout());\n  suite.enableTimeouts(this.enableTimeouts());\n  suite.slow(this.slow());\n  suite.bail(this.bail());\n  return suite;\n};\n\n/**\n * Set timeout `ms` or short-hand such as \"2s\".\n *\n * @api private\n * @param {number|string} ms\n * @return {Suite|number} for chaining\n */\nSuite.prototype.timeout = function(ms) {\n  if (!arguments.length) {\n    return this._timeout;\n  }\n  if (ms.toString() === '0') {\n    this._enableTimeouts = false;\n  }\n  if (typeof ms === 'string') {\n    ms = milliseconds(ms);\n  }\n  debug('timeout %d', ms);\n  this._timeout = parseInt(ms, 10);\n  return this;\n};\n\n/**\n  * Set timeout to `enabled`.\n  *\n  * @api private\n  * @param {boolean} enabled\n  * @return {Suite|boolean} self or enabled\n  */\nSuite.prototype.enableTimeouts = function(enabled) {\n  if (!arguments.length) {\n    return this._enableTimeouts;\n  }\n  debug('enableTimeouts %s', enabled);\n  this._enableTimeouts = enabled;\n  return this;\n};\n\n/**\n * Set slow `ms` or short-hand such as \"2s\".\n *\n * @api private\n * @param {number|string} ms\n * @return {Suite|number} for chaining\n */\nSuite.prototype.slow = function(ms) {\n  if (!arguments.length) {\n    return this._slow;\n  }\n  if (typeof ms === 'string') {\n    ms = milliseconds(ms);\n  }\n  debug('slow %d', ms);\n  this._slow = ms;\n  return this;\n};\n\n/**\n * Sets whether to bail after first error.\n *\n * @api private\n * @param {boolean} bail\n * @return {Suite|number} for chaining\n */\nSuite.prototype.bail = function(bail) {\n  if (!arguments.length) {\n    return this._bail;\n  }\n  debug('bail %s', bail);\n  this._bail = bail;\n  return this;\n};\n\n/**\n * Run `fn(test[, done])` before running tests.\n *\n * @api private\n * @param {string} title\n * @param {Function} fn\n * @return {Suite} for chaining\n */\nSuite.prototype.beforeAll = function(title, fn) {\n  if (this.pending) {\n    return this;\n  }\n  if (typeof title === 'function') {\n    fn = title;\n    title = fn.name;\n  }\n  title = '\"before all\" hook' + (title ? ': ' + title : '');\n\n  var hook = new Hook(title, fn);\n  hook.parent = this;\n  hook.timeout(this.timeout());\n  hook.enableTimeouts(this.enableTimeouts());\n  hook.slow(this.slow());\n  hook.ctx = this.ctx;\n  this._beforeAll.push(hook);\n  this.emit('beforeAll', hook);\n  return this;\n};\n\n/**\n * Run `fn(test[, done])` after running tests.\n *\n * @api private\n * @param {string} title\n * @param {Function} fn\n * @return {Suite} for chaining\n */\nSuite.prototype.afterAll = function(title, fn) {\n  if (this.pending) {\n    return this;\n  }\n  if (typeof title === 'function') {\n    fn = title;\n    title = fn.name;\n  }\n  title = '\"after all\" hook' + (title ? ': ' + title : '');\n\n  var hook = new Hook(title, fn);\n  hook.parent = this;\n  hook.timeout(this.timeout());\n  hook.enableTimeouts(this.enableTimeouts());\n  hook.slow(this.slow());\n  hook.ctx = this.ctx;\n  this._afterAll.push(hook);\n  this.emit('afterAll', hook);\n  return this;\n};\n\n/**\n * Run `fn(test[, done])` before each test case.\n *\n * @api private\n * @param {string} title\n * @param {Function} fn\n * @return {Suite} for chaining\n */\nSuite.prototype.beforeEach = function(title, fn) {\n  if (this.pending) {\n    return this;\n  }\n  if (typeof title === 'function') {\n    fn = title;\n    title = fn.name;\n  }\n  title = '\"before each\" hook' + (title ? ': ' + title : '');\n\n  var hook = new Hook(title, fn);\n  hook.parent = this;\n  hook.timeout(this.timeout());\n  hook.enableTimeouts(this.enableTimeouts());\n  hook.slow(this.slow());\n  hook.ctx = this.ctx;\n  this._beforeEach.push(hook);\n  this.emit('beforeEach', hook);\n  return this;\n};\n\n/**\n * Run `fn(test[, done])` after each test case.\n *\n * @api private\n * @param {string} title\n * @param {Function} fn\n * @return {Suite} for chaining\n */\nSuite.prototype.afterEach = function(title, fn) {\n  if (this.pending) {\n    return this;\n  }\n  if (typeof title === 'function') {\n    fn = title;\n    title = fn.name;\n  }\n  title = '\"after each\" hook' + (title ? ': ' + title : '');\n\n  var hook = new Hook(title, fn);\n  hook.parent = this;\n  hook.timeout(this.timeout());\n  hook.enableTimeouts(this.enableTimeouts());\n  hook.slow(this.slow());\n  hook.ctx = this.ctx;\n  this._afterEach.push(hook);\n  this.emit('afterEach', hook);\n  return this;\n};\n\n/**\n * Add a test `suite`.\n *\n * @api private\n * @param {Suite} suite\n * @return {Suite} for chaining\n */\nSuite.prototype.addSuite = function(suite) {\n  suite.parent = this;\n  suite.timeout(this.timeout());\n  suite.enableTimeouts(this.enableTimeouts());\n  suite.slow(this.slow());\n  suite.bail(this.bail());\n  this.suites.push(suite);\n  this.emit('suite', suite);\n  return this;\n};\n\n/**\n * Add a `test` to this suite.\n *\n * @api private\n * @param {Test} test\n * @return {Suite} for chaining\n */\nSuite.prototype.addTest = function(test) {\n  test.parent = this;\n  test.timeout(this.timeout());\n  test.enableTimeouts(this.enableTimeouts());\n  test.slow(this.slow());\n  test.ctx = this.ctx;\n  this.tests.push(test);\n  this.emit('test', test);\n  return this;\n};\n\n/**\n * Return the full title generated by recursively concatenating the parent's\n * full title.\n *\n * @api public\n * @return {string}\n */\nSuite.prototype.fullTitle = function() {\n  if (this.parent) {\n    var full = this.parent.fullTitle();\n    if (full) {\n      return full + ' ' + this.title;\n    }\n  }\n  return this.title;\n};\n\n/**\n * Return the total number of tests.\n *\n * @api public\n * @return {number}\n */\nSuite.prototype.total = function() {\n  return utils.reduce(this.suites, function(sum, suite) {\n    return sum + suite.total();\n  }, 0) + this.tests.length;\n};\n\n/**\n * Iterates through each suite recursively to find all tests. Applies a\n * function in the format `fn(test)`.\n *\n * @api private\n * @param {Function} fn\n * @return {Suite}\n */\nSuite.prototype.eachTest = function(fn) {\n  utils.forEach(this.tests, fn);\n  utils.forEach(this.suites, function(suite) {\n    suite.eachTest(fn);\n  });\n  return this;\n};\n\n/**\n * This will run the root suite if we happen to be running in delayed mode.\n */\nSuite.prototype.run = function run() {\n  if (this.root) {\n    this.emit('run');\n  }\n};\n\n},{\"./hook\":7,\"./ms\":15,\"./utils\":39,\"debug\":2,\"events\":3}],38:[function(require,module,exports){\n/**\n * Module dependencies.\n */\n\nvar Runnable = require('./runnable');\nvar inherits = require('./utils').inherits;\n\n/**\n * Expose `Test`.\n */\n\nmodule.exports = Test;\n\n/**\n * Initialize a new `Test` with the given `title` and callback `fn`.\n *\n * @api private\n * @param {String} title\n * @param {Function} fn\n */\nfunction Test(title, fn) {\n  Runnable.call(this, title, fn);\n  this.pending = !fn;\n  this.type = 'test';\n}\n\n/**\n * Inherit from `Runnable.prototype`.\n */\ninherits(Test, Runnable);\n\n},{\"./runnable\":35,\"./utils\":39}],39:[function(require,module,exports){\n(function (process,Buffer){\n/* eslint-env browser */\n\n/**\n * Module dependencies.\n */\n\nvar basename = require('path').basename;\nvar debug = require('debug')('mocha:watch');\nvar exists = require('fs').existsSync || require('path').existsSync;\nvar glob = require('glob');\nvar join = require('path').join;\nvar readdirSync = require('fs').readdirSync;\nvar statSync = require('fs').statSync;\nvar watchFile = require('fs').watchFile;\n\n/**\n * Ignored directories.\n */\n\nvar ignore = ['node_modules', '.git'];\n\nexports.inherits = require('util').inherits;\n\n/**\n * Escape special characters in the given string of html.\n *\n * @api private\n * @param  {string} html\n * @return {string}\n */\nexports.escape = function(html) {\n  return String(html)\n    .replace(/&/g, '&amp;')\n    .replace(/\"/g, '&quot;')\n    .replace(/</g, '&lt;')\n    .replace(/>/g, '&gt;');\n};\n\n/**\n * Array#forEach (<=IE8)\n *\n * @api private\n * @param {Array} arr\n * @param {Function} fn\n * @param {Object} scope\n */\nexports.forEach = function(arr, fn, scope) {\n  for (var i = 0, l = arr.length; i < l; i++) {\n    fn.call(scope, arr[i], i);\n  }\n};\n\n/**\n * Test if the given obj is type of string.\n *\n * @api private\n * @param {Object} obj\n * @return {boolean}\n */\nexports.isString = function(obj) {\n  return typeof obj === 'string';\n};\n\n/**\n * Array#map (<=IE8)\n *\n * @api private\n * @param {Array} arr\n * @param {Function} fn\n * @param {Object} scope\n * @return {Array}\n */\nexports.map = function(arr, fn, scope) {\n  var result = [];\n  for (var i = 0, l = arr.length; i < l; i++) {\n    result.push(fn.call(scope, arr[i], i, arr));\n  }\n  return result;\n};\n\n/**\n * Array#indexOf (<=IE8)\n *\n * @api private\n * @param {Array} arr\n * @param {Object} obj to find index of\n * @param {number} start\n * @return {number}\n */\nexports.indexOf = function(arr, obj, start) {\n  for (var i = start || 0, l = arr.length; i < l; i++) {\n    if (arr[i] === obj) {\n      return i;\n    }\n  }\n  return -1;\n};\n\n/**\n * Array#reduce (<=IE8)\n *\n * @api private\n * @param {Array} arr\n * @param {Function} fn\n * @param {Object} val Initial value.\n * @return {*}\n */\nexports.reduce = function(arr, fn, val) {\n  var rval = val;\n\n  for (var i = 0, l = arr.length; i < l; i++) {\n    rval = fn(rval, arr[i], i, arr);\n  }\n\n  return rval;\n};\n\n/**\n * Array#filter (<=IE8)\n *\n * @api private\n * @param {Array} arr\n * @param {Function} fn\n * @return {Array}\n */\nexports.filter = function(arr, fn) {\n  var ret = [];\n\n  for (var i = 0, l = arr.length; i < l; i++) {\n    var val = arr[i];\n    if (fn(val, i, arr)) {\n      ret.push(val);\n    }\n  }\n\n  return ret;\n};\n\n/**\n * Object.keys (<=IE8)\n *\n * @api private\n * @param {Object} obj\n * @return {Array} keys\n */\nexports.keys = typeof Object.keys === 'function' ? Object.keys : function(obj) {\n  var keys = [];\n  var has = Object.prototype.hasOwnProperty; // for `window` on <=IE8\n\n  for (var key in obj) {\n    if (has.call(obj, key)) {\n      keys.push(key);\n    }\n  }\n\n  return keys;\n};\n\n/**\n * Watch the given `files` for changes\n * and invoke `fn(file)` on modification.\n *\n * @api private\n * @param {Array} files\n * @param {Function} fn\n */\nexports.watch = function(files, fn) {\n  var options = { interval: 100 };\n  files.forEach(function(file) {\n    debug('file %s', file);\n    watchFile(file, options, function(curr, prev) {\n      if (prev.mtime < curr.mtime) {\n        fn(file);\n      }\n    });\n  });\n};\n\n/**\n * Array.isArray (<=IE8)\n *\n * @api private\n * @param {Object} obj\n * @return {Boolean}\n */\nvar isArray = typeof Array.isArray === 'function' ? Array.isArray : function(obj) {\n  return Object.prototype.toString.call(obj) === '[object Array]';\n};\n\n/**\n * Buffer.prototype.toJSON polyfill.\n *\n * @type {Function}\n */\nif (typeof Buffer !== 'undefined' && Buffer.prototype) {\n  Buffer.prototype.toJSON = Buffer.prototype.toJSON || function() {\n    return Array.prototype.slice.call(this, 0);\n  };\n}\n\n/**\n * Ignored files.\n *\n * @api private\n * @param {string} path\n * @return {boolean}\n */\nfunction ignored(path) {\n  return !~ignore.indexOf(path);\n}\n\n/**\n * Lookup files in the given `dir`.\n *\n * @api private\n * @param {string} dir\n * @param {string[]} [ext=['.js']]\n * @param {Array} [ret=[]]\n * @return {Array}\n */\nexports.files = function(dir, ext, ret) {\n  ret = ret || [];\n  ext = ext || ['js'];\n\n  var re = new RegExp('\\\\.(' + ext.join('|') + ')$');\n\n  readdirSync(dir)\n    .filter(ignored)\n    .forEach(function(path) {\n      path = join(dir, path);\n      if (statSync(path).isDirectory()) {\n        exports.files(path, ext, ret);\n      } else if (path.match(re)) {\n        ret.push(path);\n      }\n    });\n\n  return ret;\n};\n\n/**\n * Compute a slug from the given `str`.\n *\n * @api private\n * @param {string} str\n * @return {string}\n */\nexports.slug = function(str) {\n  return str\n    .toLowerCase()\n    .replace(/ +/g, '-')\n    .replace(/[^-\\w]/g, '');\n};\n\n/**\n * Strip the function definition from `str`, and re-indent for pre whitespace.\n *\n * @param {string} str\n * @return {string}\n */\nexports.clean = function(str) {\n  str = str\n    .replace(/\\r\\n?|[\\n\\u2028\\u2029]/g, '\\n').replace(/^\\uFEFF/, '')\n    .replace(/^function *\\(.*\\)\\s*{|\\(.*\\) *=> *{?/, '')\n    .replace(/\\s+\\}$/, '');\n\n  var spaces = str.match(/^\\n?( *)/)[1].length;\n  var tabs = str.match(/^\\n?(\\t*)/)[1].length;\n  var re = new RegExp('^\\n?' + (tabs ? '\\t' : ' ') + '{' + (tabs ? tabs : spaces) + '}', 'gm');\n\n  str = str.replace(re, '');\n\n  return exports.trim(str);\n};\n\n/**\n * Trim the given `str`.\n *\n * @api private\n * @param {string} str\n * @return {string}\n */\nexports.trim = function(str) {\n  return str.replace(/^\\s+|\\s+$/g, '');\n};\n\n/**\n * Parse the given `qs`.\n *\n * @api private\n * @param {string} qs\n * @return {Object}\n */\nexports.parseQuery = function(qs) {\n  return exports.reduce(qs.replace('?', '').split('&'), function(obj, pair) {\n    var i = pair.indexOf('=');\n    var key = pair.slice(0, i);\n    var val = pair.slice(++i);\n\n    obj[key] = decodeURIComponent(val);\n    return obj;\n  }, {});\n};\n\n/**\n * Highlight the given string of `js`.\n *\n * @api private\n * @param {string} js\n * @return {string}\n */\nfunction highlight(js) {\n  return js\n    .replace(/</g, '&lt;')\n    .replace(/>/g, '&gt;')\n    .replace(/\\/\\/(.*)/gm, '<span class=\"comment\">//$1</span>')\n    .replace(/('.*?')/gm, '<span class=\"string\">$1</span>')\n    .replace(/(\\d+\\.\\d+)/gm, '<span class=\"number\">$1</span>')\n    .replace(/(\\d+)/gm, '<span class=\"number\">$1</span>')\n    .replace(/\\bnew[ \\t]+(\\w+)/gm, '<span class=\"keyword\">new</span> <span class=\"init\">$1</span>')\n    .replace(/\\b(function|new|throw|return|var|if|else)\\b/gm, '<span class=\"keyword\">$1</span>');\n}\n\n/**\n * Highlight the contents of tag `name`.\n *\n * @api private\n * @param {string} name\n */\nexports.highlightTags = function(name) {\n  var code = document.getElementById('mocha').getElementsByTagName(name);\n  for (var i = 0, len = code.length; i < len; ++i) {\n    code[i].innerHTML = highlight(code[i].innerHTML);\n  }\n};\n\n/**\n * If a value could have properties, and has none, this function is called,\n * which returns a string representation of the empty value.\n *\n * Functions w/ no properties return `'[Function]'`\n * Arrays w/ length === 0 return `'[]'`\n * Objects w/ no properties return `'{}'`\n * All else: return result of `value.toString()`\n *\n * @api private\n * @param {*} value The value to inspect.\n * @param {string} [type] The type of the value, if known.\n * @returns {string}\n */\nfunction emptyRepresentation(value, type) {\n  type = type || exports.type(value);\n\n  switch (type) {\n    case 'function':\n      return '[Function]';\n    case 'object':\n      return '{}';\n    case 'array':\n      return '[]';\n    default:\n      return value.toString();\n  }\n}\n\n/**\n * Takes some variable and asks `Object.prototype.toString()` what it thinks it\n * is.\n *\n * @api private\n * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/toString\n * @param {*} value The value to test.\n * @returns {string}\n * @example\n * type({}) // 'object'\n * type([]) // 'array'\n * type(1) // 'number'\n * type(false) // 'boolean'\n * type(Infinity) // 'number'\n * type(null) // 'null'\n * type(new Date()) // 'date'\n * type(/foo/) // 'regexp'\n * type('type') // 'string'\n * type(global) // 'global'\n */\nexports.type = function type(value) {\n  if (value === undefined) {\n    return 'undefined';\n  } else if (value === null) {\n    return 'null';\n  } else if (typeof Buffer !== 'undefined' && Buffer.isBuffer(value)) {\n    return 'buffer';\n  }\n  return Object.prototype.toString.call(value)\n    .replace(/^\\[.+\\s(.+?)\\]$/, '$1')\n    .toLowerCase();\n};\n\n/**\n * Stringify `value`. Different behavior depending on type of value:\n *\n * - If `value` is undefined or null, return `'[undefined]'` or `'[null]'`, respectively.\n * - If `value` is not an object, function or array, return result of `value.toString()` wrapped in double-quotes.\n * - If `value` is an *empty* object, function, or array, return result of function\n *   {@link emptyRepresentation}.\n * - If `value` has properties, call {@link exports.canonicalize} on it, then return result of\n *   JSON.stringify().\n *\n * @api private\n * @see exports.type\n * @param {*} value\n * @return {string}\n */\nexports.stringify = function(value) {\n  var type = exports.type(value);\n\n  if (!~exports.indexOf(['object', 'array', 'function'], type)) {\n    if (type !== 'buffer') {\n      return jsonStringify(value);\n    }\n    var json = value.toJSON();\n    // Based on the toJSON result\n    return jsonStringify(json.data && json.type ? json.data : json, 2)\n      .replace(/,(\\n|$)/g, '$1');\n  }\n\n  for (var prop in value) {\n    if (Object.prototype.hasOwnProperty.call(value, prop)) {\n      return jsonStringify(exports.canonicalize(value), 2).replace(/,(\\n|$)/g, '$1');\n    }\n  }\n\n  return emptyRepresentation(value, type);\n};\n\n/**\n * like JSON.stringify but more sense.\n *\n * @api private\n * @param {Object}  object\n * @param {number=} spaces\n * @param {number=} depth\n * @returns {*}\n */\nfunction jsonStringify(object, spaces, depth) {\n  if (typeof spaces === 'undefined') {\n    // primitive types\n    return _stringify(object);\n  }\n\n  depth = depth || 1;\n  var space = spaces * depth;\n  var str = isArray(object) ? '[' : '{';\n  var end = isArray(object) ? ']' : '}';\n  var length = object.length || exports.keys(object).length;\n  // `.repeat()` polyfill\n  function repeat(s, n) {\n    return new Array(n).join(s);\n  }\n\n  function _stringify(val) {\n    switch (exports.type(val)) {\n      case 'null':\n      case 'undefined':\n        val = '[' + val + ']';\n        break;\n      case 'array':\n      case 'object':\n        val = jsonStringify(val, spaces, depth + 1);\n        break;\n      case 'boolean':\n      case 'regexp':\n      case 'number':\n        val = val === 0 && (1 / val) === -Infinity // `-0`\n          ? '-0'\n          : val.toString();\n        break;\n      case 'date':\n        var sDate = isNaN(val.getTime())        // Invalid date\n          ? val.toString()\n          : val.toISOString();\n        val = '[Date: ' + sDate + ']';\n        break;\n      case 'buffer':\n        var json = val.toJSON();\n        // Based on the toJSON result\n        json = json.data && json.type ? json.data : json;\n        val = '[Buffer: ' + jsonStringify(json, 2, depth + 1) + ']';\n        break;\n      default:\n        val = (val === '[Function]' || val === '[Circular]')\n          ? val\n          : JSON.stringify(val); // string\n    }\n    return val;\n  }\n\n  for (var i in object) {\n    if (!object.hasOwnProperty(i)) {\n      continue; // not my business\n    }\n    --length;\n    str += '\\n ' + repeat(' ', space)\n      + (isArray(object) ? '' : '\"' + i + '\": ') // key\n      + _stringify(object[i])                     // value\n      + (length ? ',' : '');                     // comma\n  }\n\n  return str\n    // [], {}\n    + (str.length !== 1 ? '\\n' + repeat(' ', --space) + end : end);\n}\n\n/**\n * Test if a value is a buffer.\n *\n * @api private\n * @param {*} value The value to test.\n * @return {boolean} True if `value` is a buffer, otherwise false\n */\nexports.isBuffer = function(value) {\n  return typeof Buffer !== 'undefined' && Buffer.isBuffer(value);\n};\n\n/**\n * Return a new Thing that has the keys in sorted order. Recursive.\n *\n * If the Thing...\n * - has already been seen, return string `'[Circular]'`\n * - is `undefined`, return string `'[undefined]'`\n * - is `null`, return value `null`\n * - is some other primitive, return the value\n * - is not a primitive or an `Array`, `Object`, or `Function`, return the value of the Thing's `toString()` method\n * - is a non-empty `Array`, `Object`, or `Function`, return the result of calling this function again.\n * - is an empty `Array`, `Object`, or `Function`, return the result of calling `emptyRepresentation()`\n *\n * @api private\n * @see {@link exports.stringify}\n * @param {*} value Thing to inspect.  May or may not have properties.\n * @param {Array} [stack=[]] Stack of seen values\n * @return {(Object|Array|Function|string|undefined)}\n */\nexports.canonicalize = function(value, stack) {\n  var canonicalizedObj;\n  /* eslint-disable no-unused-vars */\n  var prop;\n  /* eslint-enable no-unused-vars */\n  var type = exports.type(value);\n  function withStack(value, fn) {\n    stack.push(value);\n    fn();\n    stack.pop();\n  }\n\n  stack = stack || [];\n\n  if (exports.indexOf(stack, value) !== -1) {\n    return '[Circular]';\n  }\n\n  switch (type) {\n    case 'undefined':\n    case 'buffer':\n    case 'null':\n      canonicalizedObj = value;\n      break;\n    case 'array':\n      withStack(value, function() {\n        canonicalizedObj = exports.map(value, function(item) {\n          return exports.canonicalize(item, stack);\n        });\n      });\n      break;\n    case 'function':\n      /* eslint-disable guard-for-in */\n      for (prop in value) {\n        canonicalizedObj = {};\n        break;\n      }\n      /* eslint-enable guard-for-in */\n      if (!canonicalizedObj) {\n        canonicalizedObj = emptyRepresentation(value, type);\n        break;\n      }\n    /* falls through */\n    case 'object':\n      canonicalizedObj = canonicalizedObj || {};\n      withStack(value, function() {\n        exports.forEach(exports.keys(value).sort(), function(key) {\n          canonicalizedObj[key] = exports.canonicalize(value[key], stack);\n        });\n      });\n      break;\n    case 'date':\n    case 'number':\n    case 'regexp':\n    case 'boolean':\n      canonicalizedObj = value;\n      break;\n    default:\n      canonicalizedObj = value.toString();\n  }\n\n  return canonicalizedObj;\n};\n\n/**\n * Lookup file names at the given `path`.\n *\n * @api public\n * @param {string} path Base path to start searching from.\n * @param {string[]} extensions File extensions to look for.\n * @param {boolean} recursive Whether or not to recurse into subdirectories.\n * @return {string[]} An array of paths.\n */\nexports.lookupFiles = function lookupFiles(path, extensions, recursive) {\n  var files = [];\n  var re = new RegExp('\\\\.(' + extensions.join('|') + ')$');\n\n  if (!exists(path)) {\n    if (exists(path + '.js')) {\n      path += '.js';\n    } else {\n      files = glob.sync(path);\n      if (!files.length) {\n        throw new Error(\"cannot resolve path (or pattern) '\" + path + \"'\");\n      }\n      return files;\n    }\n  }\n\n  try {\n    var stat = statSync(path);\n    if (stat.isFile()) {\n      return path;\n    }\n  } catch (err) {\n    // ignore error\n    return;\n  }\n\n  readdirSync(path).forEach(function(file) {\n    file = join(path, file);\n    try {\n      var stat = statSync(file);\n      if (stat.isDirectory()) {\n        if (recursive) {\n          files = files.concat(lookupFiles(file, extensions, recursive));\n        }\n        return;\n      }\n    } catch (err) {\n      // ignore error\n      return;\n    }\n    if (!stat.isFile() || !re.test(file) || basename(file)[0] === '.') {\n      return;\n    }\n    files.push(file);\n  });\n\n  return files;\n};\n\n/**\n * Generate an undefined error with a message warning the user.\n *\n * @return {Error}\n */\n\nexports.undefinedError = function() {\n  return new Error('Caught undefined error, did you throw without specifying what?');\n};\n\n/**\n * Generate an undefined error if `err` is not defined.\n *\n * @param {Error} err\n * @return {Error}\n */\n\nexports.getError = function(err) {\n  return err || exports.undefinedError();\n};\n\n/**\n * @summary\n * This Filter based on `mocha-clean` module.(see: `github.com/rstacruz/mocha-clean`)\n * @description\n * When invoking this function you get a filter function that get the Error.stack as an input,\n * and return a prettify output.\n * (i.e: strip Mocha and internal node functions from stack trace).\n * @returns {Function}\n */\nexports.stackTraceFilter = function() {\n  // TODO: Replace with `process.browser`\n  var slash = '/';\n  var is = typeof document === 'undefined' ? { node: true } : { browser: true };\n  var cwd = is.node\n      ? process.cwd() + slash\n      : (typeof location === 'undefined' ? window.location : location).href.replace(/\\/[^\\/]*$/, '/');\n\n  function isMochaInternal(line) {\n    return (~line.indexOf('node_modules' + slash + 'mocha' + slash))\n      || (~line.indexOf('components' + slash + 'mochajs' + slash))\n      || (~line.indexOf('components' + slash + 'mocha' + slash))\n      || (~line.indexOf(slash + 'mocha.js'));\n  }\n\n  function isNodeInternal(line) {\n    return (~line.indexOf('(timers.js:'))\n      || (~line.indexOf('(events.js:'))\n      || (~line.indexOf('(node.js:'))\n      || (~line.indexOf('(module.js:'))\n      || (~line.indexOf('GeneratorFunctionPrototype.next (native)'))\n      || false;\n  }\n\n  return function(stack) {\n    stack = stack.split('\\n');\n\n    stack = exports.reduce(stack, function(list, line) {\n      if (isMochaInternal(line)) {\n        return list;\n      }\n\n      if (is.node && isNodeInternal(line)) {\n        return list;\n      }\n\n      // Clean up cwd(absolute)\n      list.push(line.replace(cwd, ''));\n      return list;\n    }, []);\n\n    return stack.join('\\n');\n  };\n};\n\n}).call(this,require('_process'),require(\"buffer\").Buffer)\n},{\"_process\":51,\"buffer\":43,\"debug\":2,\"fs\":41,\"glob\":41,\"path\":41,\"util\":66}],40:[function(require,module,exports){\n(function (process){\nvar WritableStream = require('stream').Writable\nvar inherits = require('util').inherits\n\nmodule.exports = BrowserStdout\n\n\ninherits(BrowserStdout, WritableStream)\n\nfunction BrowserStdout(opts) {\n  if (!(this instanceof BrowserStdout)) return new BrowserStdout(opts)\n\n  opts = opts || {}\n  WritableStream.call(this, opts)\n  this.label = (opts.label !== undefined) ? opts.label : 'stdout'\n}\n\nBrowserStdout.prototype._write = function(chunks, encoding, cb) {\n  var output = chunks.toString ? chunks.toString() : chunks\n  if (this.label === false) {\n    console.log(output)\n  } else {\n    console.log(this.label+':', output)\n  }\n  process.nextTick(cb)\n}\n\n}).call(this,require('_process'))\n},{\"_process\":51,\"stream\":63,\"util\":66}],41:[function(require,module,exports){\n\n},{}],42:[function(require,module,exports){\narguments[4][41][0].apply(exports,arguments)\n},{\"dup\":41}],43:[function(require,module,exports){\n/*!\n * The buffer module from node.js, for the browser.\n *\n * @author   Feross Aboukhadijeh <feross@feross.org> <http://feross.org>\n * @license  MIT\n */\n\nvar base64 = require('base64-js')\nvar ieee754 = require('ieee754')\nvar isArray = require('is-array')\n\nexports.Buffer = Buffer\nexports.SlowBuffer = SlowBuffer\nexports.INSPECT_MAX_BYTES = 50\nBuffer.poolSize = 8192 // not used by this implementation\n\nvar rootParent = {}\n\n/**\n * If `Buffer.TYPED_ARRAY_SUPPORT`:\n *   === true    Use Uint8Array implementation (fastest)\n *   === false   Use Object implementation (most compatible, even IE6)\n *\n * Browsers that support typed arrays are IE 10+, Firefox 4+, Chrome 7+, Safari 5.1+,\n * Opera 11.6+, iOS 4.2+.\n *\n * Due to various browser bugs, sometimes the Object implementation will be used even\n * when the browser supports typed arrays.\n *\n * Note:\n *\n *   - Firefox 4-29 lacks support for adding new properties to `Uint8Array` instances,\n *     See: https://bugzilla.mozilla.org/show_bug.cgi?id=695438.\n *\n *   - Safari 5-7 lacks support for changing the `Object.prototype.constructor` property\n *     on objects.\n *\n *   - Chrome 9-10 is missing the `TypedArray.prototype.subarray` function.\n *\n *   - IE10 has a broken `TypedArray.prototype.subarray` function which returns arrays of\n *     incorrect length in some situations.\n\n * We detect these buggy browsers and set `Buffer.TYPED_ARRAY_SUPPORT` to `false` so they\n * get the Object implementation, which is slower but behaves correctly.\n */\nBuffer.TYPED_ARRAY_SUPPORT = (function () {\n  function Bar () {}\n  try {\n    var arr = new Uint8Array(1)\n    arr.foo = function () { return 42 }\n    arr.constructor = Bar\n    return arr.foo() === 42 && // typed array instances can be augmented\n        arr.constructor === Bar && // constructor can be set\n        typeof arr.subarray === 'function' && // chrome 9-10 lack `subarray`\n        arr.subarray(1, 1).byteLength === 0 // ie10 has broken `subarray`\n  } catch (e) {\n    return false\n  }\n})()\n\nfunction kMaxLength () {\n  return Buffer.TYPED_ARRAY_SUPPORT\n    ? 0x7fffffff\n    : 0x3fffffff\n}\n\n/**\n * Class: Buffer\n * =============\n *\n * The Buffer constructor returns instances of `Uint8Array` that are augmented\n * with function properties for all the node `Buffer` API functions. We use\n * `Uint8Array` so that square bracket notation works as expected -- it returns\n * a single octet.\n *\n * By augmenting the instances, we can avoid modifying the `Uint8Array`\n * prototype.\n */\nfunction Buffer (arg) {\n  if (!(this instanceof Buffer)) {\n    // Avoid going through an ArgumentsAdaptorTrampoline in the common case.\n    if (arguments.length > 1) return new Buffer(arg, arguments[1])\n    return new Buffer(arg)\n  }\n\n  this.length = 0\n  this.parent = undefined\n\n  // Common case.\n  if (typeof arg === 'number') {\n    return fromNumber(this, arg)\n  }\n\n  // Slightly less common case.\n  if (typeof arg === 'string') {\n    return fromString(this, arg, arguments.length > 1 ? arguments[1] : 'utf8')\n  }\n\n  // Unusual.\n  return fromObject(this, arg)\n}\n\nfunction fromNumber (that, length) {\n  that = allocate(that, length < 0 ? 0 : checked(length) | 0)\n  if (!Buffer.TYPED_ARRAY_SUPPORT) {\n    for (var i = 0; i < length; i++) {\n      that[i] = 0\n    }\n  }\n  return that\n}\n\nfunction fromString (that, string, encoding) {\n  if (typeof encoding !== 'string' || encoding === '') encoding = 'utf8'\n\n  // Assumption: byteLength() return value is always < kMaxLength.\n  var length = byteLength(string, encoding) | 0\n  that = allocate(that, length)\n\n  that.write(string, encoding)\n  return that\n}\n\nfunction fromObject (that, object) {\n  if (Buffer.isBuffer(object)) return fromBuffer(that, object)\n\n  if (isArray(object)) return fromArray(that, object)\n\n  if (object == null) {\n    throw new TypeError('must start with number, buffer, array or string')\n  }\n\n  if (typeof ArrayBuffer !== 'undefined') {\n    if (object.buffer instanceof ArrayBuffer) {\n      return fromTypedArray(that, object)\n    }\n    if (object instanceof ArrayBuffer) {\n      return fromArrayBuffer(that, object)\n    }\n  }\n\n  if (object.length) return fromArrayLike(that, object)\n\n  return fromJsonObject(that, object)\n}\n\nfunction fromBuffer (that, buffer) {\n  var length = checked(buffer.length) | 0\n  that = allocate(that, length)\n  buffer.copy(that, 0, 0, length)\n  return that\n}\n\nfunction fromArray (that, array) {\n  var length = checked(array.length) | 0\n  that = allocate(that, length)\n  for (var i = 0; i < length; i += 1) {\n    that[i] = array[i] & 255\n  }\n  return that\n}\n\n// Duplicate of fromArray() to keep fromArray() monomorphic.\nfunction fromTypedArray (that, array) {\n  var length = checked(array.length) | 0\n  that = allocate(that, length)\n  // Truncating the elements is probably not what people expect from typed\n  // arrays with BYTES_PER_ELEMENT > 1 but it's compatible with the behavior\n  // of the old Buffer constructor.\n  for (var i = 0; i < length; i += 1) {\n    that[i] = array[i] & 255\n  }\n  return that\n}\n\nfunction fromArrayBuffer (that, array) {\n  if (Buffer.TYPED_ARRAY_SUPPORT) {\n    // Return an augmented `Uint8Array` instance, for best performance\n    array.byteLength\n    that = Buffer._augment(new Uint8Array(array))\n  } else {\n    // Fallback: Return an object instance of the Buffer class\n    that = fromTypedArray(that, new Uint8Array(array))\n  }\n  return that\n}\n\nfunction fromArrayLike (that, array) {\n  var length = checked(array.length) | 0\n  that = allocate(that, length)\n  for (var i = 0; i < length; i += 1) {\n    that[i] = array[i] & 255\n  }\n  return that\n}\n\n// Deserialize { type: 'Buffer', data: [1,2,3,...] } into a Buffer object.\n// Returns a zero-length buffer for inputs that don't conform to the spec.\nfunction fromJsonObject (that, object) {\n  var array\n  var length = 0\n\n  if (object.type === 'Buffer' && isArray(object.data)) {\n    array = object.data\n    length = checked(array.length) | 0\n  }\n  that = allocate(that, length)\n\n  for (var i = 0; i < length; i += 1) {\n    that[i] = array[i] & 255\n  }\n  return that\n}\n\nfunction allocate (that, length) {\n  if (Buffer.TYPED_ARRAY_SUPPORT) {\n    // Return an augmented `Uint8Array` instance, for best performance\n    that = Buffer._augment(new Uint8Array(length))\n  } else {\n    // Fallback: Return an object instance of the Buffer class\n    that.length = length\n    that._isBuffer = true\n  }\n\n  var fromPool = length !== 0 && length <= Buffer.poolSize >>> 1\n  if (fromPool) that.parent = rootParent\n\n  return that\n}\n\nfunction checked (length) {\n  // Note: cannot use `length < kMaxLength` here because that fails when\n  // length is NaN (which is otherwise coerced to zero.)\n  if (length >= kMaxLength()) {\n    throw new RangeError('Attempt to allocate Buffer larger than maximum ' +\n                         'size: 0x' + kMaxLength().toString(16) + ' bytes')\n  }\n  return length | 0\n}\n\nfunction SlowBuffer (subject, encoding) {\n  if (!(this instanceof SlowBuffer)) return new SlowBuffer(subject, encoding)\n\n  var buf = new Buffer(subject, encoding)\n  delete buf.parent\n  return buf\n}\n\nBuffer.isBuffer = function isBuffer (b) {\n  return !!(b != null && b._isBuffer)\n}\n\nBuffer.compare = function compare (a, b) {\n  if (!Buffer.isBuffer(a) || !Buffer.isBuffer(b)) {\n    throw new TypeError('Arguments must be Buffers')\n  }\n\n  if (a === b) return 0\n\n  var x = a.length\n  var y = b.length\n\n  var i = 0\n  var len = Math.min(x, y)\n  while (i < len) {\n    if (a[i] !== b[i]) break\n\n    ++i\n  }\n\n  if (i !== len) {\n    x = a[i]\n    y = b[i]\n  }\n\n  if (x < y) return -1\n  if (y < x) return 1\n  return 0\n}\n\nBuffer.isEncoding = function isEncoding (encoding) {\n  switch (String(encoding).toLowerCase()) {\n    case 'hex':\n    case 'utf8':\n    case 'utf-8':\n    case 'ascii':\n    case 'binary':\n    case 'base64':\n    case 'raw':\n    case 'ucs2':\n    case 'ucs-2':\n    case 'utf16le':\n    case 'utf-16le':\n      return true\n    default:\n      return false\n  }\n}\n\nBuffer.concat = function concat (list, length) {\n  if (!isArray(list)) throw new TypeError('list argument must be an Array of Buffers.')\n\n  if (list.length === 0) {\n    return new Buffer(0)\n  }\n\n  var i\n  if (length === undefined) {\n    length = 0\n    for (i = 0; i < list.length; i++) {\n      length += list[i].length\n    }\n  }\n\n  var buf = new Buffer(length)\n  var pos = 0\n  for (i = 0; i < list.length; i++) {\n    var item = list[i]\n    item.copy(buf, pos)\n    pos += item.length\n  }\n  return buf\n}\n\nfunction byteLength (string, encoding) {\n  if (typeof string !== 'string') string = '' + string\n\n  var len = string.length\n  if (len === 0) return 0\n\n  // Use a for loop to avoid recursion\n  var loweredCase = false\n  for (;;) {\n    switch (encoding) {\n      case 'ascii':\n      case 'binary':\n      // Deprecated\n      case 'raw':\n      case 'raws':\n        return len\n      case 'utf8':\n      case 'utf-8':\n        return utf8ToBytes(string).length\n      case 'ucs2':\n      case 'ucs-2':\n      case 'utf16le':\n      case 'utf-16le':\n        return len * 2\n      case 'hex':\n        return len >>> 1\n      case 'base64':\n        return base64ToBytes(string).length\n      default:\n        if (loweredCase) return utf8ToBytes(string).length // assume utf8\n        encoding = ('' + encoding).toLowerCase()\n        loweredCase = true\n    }\n  }\n}\nBuffer.byteLength = byteLength\n\n// pre-set for values that may exist in the future\nBuffer.prototype.length = undefined\nBuffer.prototype.parent = undefined\n\nfunction slowToString (encoding, start, end) {\n  var loweredCase = false\n\n  start = start | 0\n  end = end === undefined || end === Infinity ? this.length : end | 0\n\n  if (!encoding) encoding = 'utf8'\n  if (start < 0) start = 0\n  if (end > this.length) end = this.length\n  if (end <= start) return ''\n\n  while (true) {\n    switch (encoding) {\n      case 'hex':\n        return hexSlice(this, start, end)\n\n      case 'utf8':\n      case 'utf-8':\n        return utf8Slice(this, start, end)\n\n      case 'ascii':\n        return asciiSlice(this, start, end)\n\n      case 'binary':\n        return binarySlice(this, start, end)\n\n      case 'base64':\n        return base64Slice(this, start, end)\n\n      case 'ucs2':\n      case 'ucs-2':\n      case 'utf16le':\n      case 'utf-16le':\n        return utf16leSlice(this, start, end)\n\n      default:\n        if (loweredCase) throw new TypeError('Unknown encoding: ' + encoding)\n        encoding = (encoding + '').toLowerCase()\n        loweredCase = true\n    }\n  }\n}\n\nBuffer.prototype.toString = function toString () {\n  var length = this.length | 0\n  if (length === 0) return ''\n  if (arguments.length === 0) return utf8Slice(this, 0, length)\n  return slowToString.apply(this, arguments)\n}\n\nBuffer.prototype.equals = function equals (b) {\n  if (!Buffer.isBuffer(b)) throw new TypeError('Argument must be a Buffer')\n  if (this === b) return true\n  return Buffer.compare(this, b) === 0\n}\n\nBuffer.prototype.inspect = function inspect () {\n  var str = ''\n  var max = exports.INSPECT_MAX_BYTES\n  if (this.length > 0) {\n    str = this.toString('hex', 0, max).match(/.{2}/g).join(' ')\n    if (this.length > max) str += ' ... '\n  }\n  return '<Buffer ' + str + '>'\n}\n\nBuffer.prototype.compare = function compare (b) {\n  if (!Buffer.isBuffer(b)) throw new TypeError('Argument must be a Buffer')\n  if (this === b) return 0\n  return Buffer.compare(this, b)\n}\n\nBuffer.prototype.indexOf = function indexOf (val, byteOffset) {\n  if (byteOffset > 0x7fffffff) byteOffset = 0x7fffffff\n  else if (byteOffset < -0x80000000) byteOffset = -0x80000000\n  byteOffset >>= 0\n\n  if (this.length === 0) return -1\n  if (byteOffset >= this.length) return -1\n\n  // Negative offsets start from the end of the buffer\n  if (byteOffset < 0) byteOffset = Math.max(this.length + byteOffset, 0)\n\n  if (typeof val === 'string') {\n    if (val.length === 0) return -1 // special case: looking for empty string always fails\n    return String.prototype.indexOf.call(this, val, byteOffset)\n  }\n  if (Buffer.isBuffer(val)) {\n    return arrayIndexOf(this, val, byteOffset)\n  }\n  if (typeof val === 'number') {\n    if (Buffer.TYPED_ARRAY_SUPPORT && Uint8Array.prototype.indexOf === 'function') {\n      return Uint8Array.prototype.indexOf.call(this, val, byteOffset)\n    }\n    return arrayIndexOf(this, [ val ], byteOffset)\n  }\n\n  function arrayIndexOf (arr, val, byteOffset) {\n    var foundIndex = -1\n    for (var i = 0; byteOffset + i < arr.length; i++) {\n      if (arr[byteOffset + i] === val[foundIndex === -1 ? 0 : i - foundIndex]) {\n        if (foundIndex === -1) foundIndex = i\n        if (i - foundIndex + 1 === val.length) return byteOffset + foundIndex\n      } else {\n        foundIndex = -1\n      }\n    }\n    return -1\n  }\n\n  throw new TypeError('val must be string, number or Buffer')\n}\n\n// `get` is deprecated\nBuffer.prototype.get = function get (offset) {\n  console.log('.get() is deprecated. Access using array indexes instead.')\n  return this.readUInt8(offset)\n}\n\n// `set` is deprecated\nBuffer.prototype.set = function set (v, offset) {\n  console.log('.set() is deprecated. Access using array indexes instead.')\n  return this.writeUInt8(v, offset)\n}\n\nfunction hexWrite (buf, string, offset, length) {\n  offset = Number(offset) || 0\n  var remaining = buf.length - offset\n  if (!length) {\n    length = remaining\n  } else {\n    length = Number(length)\n    if (length > remaining) {\n      length = remaining\n    }\n  }\n\n  // must be an even number of digits\n  var strLen = string.length\n  if (strLen % 2 !== 0) throw new Error('Invalid hex string')\n\n  if (length > strLen / 2) {\n    length = strLen / 2\n  }\n  for (var i = 0; i < length; i++) {\n    var parsed = parseInt(string.substr(i * 2, 2), 16)\n    if (isNaN(parsed)) throw new Error('Invalid hex string')\n    buf[offset + i] = parsed\n  }\n  return i\n}\n\nfunction utf8Write (buf, string, offset, length) {\n  return blitBuffer(utf8ToBytes(string, buf.length - offset), buf, offset, length)\n}\n\nfunction asciiWrite (buf, string, offset, length) {\n  return blitBuffer(asciiToBytes(string), buf, offset, length)\n}\n\nfunction binaryWrite (buf, string, offset, length) {\n  return asciiWrite(buf, string, offset, length)\n}\n\nfunction base64Write (buf, string, offset, length) {\n  return blitBuffer(base64ToBytes(string), buf, offset, length)\n}\n\nfunction ucs2Write (buf, string, offset, length) {\n  return blitBuffer(utf16leToBytes(string, buf.length - offset), buf, offset, length)\n}\n\nBuffer.prototype.write = function write (string, offset, length, encoding) {\n  // Buffer#write(string)\n  if (offset === undefined) {\n    encoding = 'utf8'\n    length = this.length\n    offset = 0\n  // Buffer#write(string, encoding)\n  } else if (length === undefined && typeof offset === 'string') {\n    encoding = offset\n    length = this.length\n    offset = 0\n  // Buffer#write(string, offset[, length][, encoding])\n  } else if (isFinite(offset)) {\n    offset = offset | 0\n    if (isFinite(length)) {\n      length = length | 0\n      if (encoding === undefined) encoding = 'utf8'\n    } else {\n      encoding = length\n      length = undefined\n    }\n  // legacy write(string, encoding, offset, length) - remove in v0.13\n  } else {\n    var swap = encoding\n    encoding = offset\n    offset = length | 0\n    length = swap\n  }\n\n  var remaining = this.length - offset\n  if (length === undefined || length > remaining) length = remaining\n\n  if ((string.length > 0 && (length < 0 || offset < 0)) || offset > this.length) {\n    throw new RangeError('attempt to write outside buffer bounds')\n  }\n\n  if (!encoding) encoding = 'utf8'\n\n  var loweredCase = false\n  for (;;) {\n    switch (encoding) {\n      case 'hex':\n        return hexWrite(this, string, offset, length)\n\n      case 'utf8':\n      case 'utf-8':\n        return utf8Write(this, string, offset, length)\n\n      case 'ascii':\n        return asciiWrite(this, string, offset, length)\n\n      case 'binary':\n        return binaryWrite(this, string, offset, length)\n\n      case 'base64':\n        // Warning: maxLength not taken into account in base64Write\n        return base64Write(this, string, offset, length)\n\n      case 'ucs2':\n      case 'ucs-2':\n      case 'utf16le':\n      case 'utf-16le':\n        return ucs2Write(this, string, offset, length)\n\n      default:\n        if (loweredCase) throw new TypeError('Unknown encoding: ' + encoding)\n        encoding = ('' + encoding).toLowerCase()\n        loweredCase = true\n    }\n  }\n}\n\nBuffer.prototype.toJSON = function toJSON () {\n  return {\n    type: 'Buffer',\n    data: Array.prototype.slice.call(this._arr || this, 0)\n  }\n}\n\nfunction base64Slice (buf, start, end) {\n  if (start === 0 && end === buf.length) {\n    return base64.fromByteArray(buf)\n  } else {\n    return base64.fromByteArray(buf.slice(start, end))\n  }\n}\n\nfunction utf8Slice (buf, start, end) {\n  end = Math.min(buf.length, end)\n  var res = []\n\n  var i = start\n  while (i < end) {\n    var firstByte = buf[i]\n    var codePoint = null\n    var bytesPerSequence = (firstByte > 0xEF) ? 4\n      : (firstByte > 0xDF) ? 3\n      : (firstByte > 0xBF) ? 2\n      : 1\n\n    if (i + bytesPerSequence <= end) {\n      var secondByte, thirdByte, fourthByte, tempCodePoint\n\n      switch (bytesPerSequence) {\n        case 1:\n          if (firstByte < 0x80) {\n            codePoint = firstByte\n          }\n          break\n        case 2:\n          secondByte = buf[i + 1]\n          if ((secondByte & 0xC0) === 0x80) {\n            tempCodePoint = (firstByte & 0x1F) << 0x6 | (secondByte & 0x3F)\n            if (tempCodePoint > 0x7F) {\n              codePoint = tempCodePoint\n            }\n          }\n          break\n        case 3:\n          secondByte = buf[i + 1]\n          thirdByte = buf[i + 2]\n          if ((secondByte & 0xC0) === 0x80 && (thirdByte & 0xC0) === 0x80) {\n            tempCodePoint = (firstByte & 0xF) << 0xC | (secondByte & 0x3F) << 0x6 | (thirdByte & 0x3F)\n            if (tempCodePoint > 0x7FF && (tempCodePoint < 0xD800 || tempCodePoint > 0xDFFF)) {\n              codePoint = tempCodePoint\n            }\n          }\n          break\n        case 4:\n          secondByte = buf[i + 1]\n          thirdByte = buf[i + 2]\n          fourthByte = buf[i + 3]\n          if ((secondByte & 0xC0) === 0x80 && (thirdByte & 0xC0) === 0x80 && (fourthByte & 0xC0) === 0x80) {\n            tempCodePoint = (firstByte & 0xF) << 0x12 | (secondByte & 0x3F) << 0xC | (thirdByte & 0x3F) << 0x6 | (fourthByte & 0x3F)\n            if (tempCodePoint > 0xFFFF && tempCodePoint < 0x110000) {\n              codePoint = tempCodePoint\n            }\n          }\n      }\n    }\n\n    if (codePoint === null) {\n      // we did not generate a valid codePoint so insert a\n      // replacement char (U+FFFD) and advance only 1 byte\n      codePoint = 0xFFFD\n      bytesPerSequence = 1\n    } else if (codePoint > 0xFFFF) {\n      // encode to utf16 (surrogate pair dance)\n      codePoint -= 0x10000\n      res.push(codePoint >>> 10 & 0x3FF | 0xD800)\n      codePoint = 0xDC00 | codePoint & 0x3FF\n    }\n\n    res.push(codePoint)\n    i += bytesPerSequence\n  }\n\n  return decodeCodePointsArray(res)\n}\n\n// Based on http://stackoverflow.com/a/22747272/680742, the browser with\n// the lowest limit is Chrome, with 0x10000 args.\n// We go 1 magnitude less, for safety\nvar MAX_ARGUMENTS_LENGTH = 0x1000\n\nfunction decodeCodePointsArray (codePoints) {\n  var len = codePoints.length\n  if (len <= MAX_ARGUMENTS_LENGTH) {\n    return String.fromCharCode.apply(String, codePoints) // avoid extra slice()\n  }\n\n  // Decode in chunks to avoid \"call stack size exceeded\".\n  var res = ''\n  var i = 0\n  while (i < len) {\n    res += String.fromCharCode.apply(\n      String,\n      codePoints.slice(i, i += MAX_ARGUMENTS_LENGTH)\n    )\n  }\n  return res\n}\n\nfunction asciiSlice (buf, start, end) {\n  var ret = ''\n  end = Math.min(buf.length, end)\n\n  for (var i = start; i < end; i++) {\n    ret += String.fromCharCode(buf[i] & 0x7F)\n  }\n  return ret\n}\n\nfunction binarySlice (buf, start, end) {\n  var ret = ''\n  end = Math.min(buf.length, end)\n\n  for (var i = start; i < end; i++) {\n    ret += String.fromCharCode(buf[i])\n  }\n  return ret\n}\n\nfunction hexSlice (buf, start, end) {\n  var len = buf.length\n\n  if (!start || start < 0) start = 0\n  if (!end || end < 0 || end > len) end = len\n\n  var out = ''\n  for (var i = start; i < end; i++) {\n    out += toHex(buf[i])\n  }\n  return out\n}\n\nfunction utf16leSlice (buf, start, end) {\n  var bytes = buf.slice(start, end)\n  var res = ''\n  for (var i = 0; i < bytes.length; i += 2) {\n    res += String.fromCharCode(bytes[i] + bytes[i + 1] * 256)\n  }\n  return res\n}\n\nBuffer.prototype.slice = function slice (start, end) {\n  var len = this.length\n  start = ~~start\n  end = end === undefined ? len : ~~end\n\n  if (start < 0) {\n    start += len\n    if (start < 0) start = 0\n  } else if (start > len) {\n    start = len\n  }\n\n  if (end < 0) {\n    end += len\n    if (end < 0) end = 0\n  } else if (end > len) {\n    end = len\n  }\n\n  if (end < start) end = start\n\n  var newBuf\n  if (Buffer.TYPED_ARRAY_SUPPORT) {\n    newBuf = Buffer._augment(this.subarray(start, end))\n  } else {\n    var sliceLen = end - start\n    newBuf = new Buffer(sliceLen, undefined)\n    for (var i = 0; i < sliceLen; i++) {\n      newBuf[i] = this[i + start]\n    }\n  }\n\n  if (newBuf.length) newBuf.parent = this.parent || this\n\n  return newBuf\n}\n\n/*\n * Need to make sure that buffer isn't trying to write out of bounds.\n */\nfunction checkOffset (offset, ext, length) {\n  if ((offset % 1) !== 0 || offset < 0) throw new RangeError('offset is not uint')\n  if (offset + ext > length) throw new RangeError('Trying to access beyond buffer length')\n}\n\nBuffer.prototype.readUIntLE = function readUIntLE (offset, byteLength, noAssert) {\n  offset = offset | 0\n  byteLength = byteLength | 0\n  if (!noAssert) checkOffset(offset, byteLength, this.length)\n\n  var val = this[offset]\n  var mul = 1\n  var i = 0\n  while (++i < byteLength && (mul *= 0x100)) {\n    val += this[offset + i] * mul\n  }\n\n  return val\n}\n\nBuffer.prototype.readUIntBE = function readUIntBE (offset, byteLength, noAssert) {\n  offset = offset | 0\n  byteLength = byteLength | 0\n  if (!noAssert) {\n    checkOffset(offset, byteLength, this.length)\n  }\n\n  var val = this[offset + --byteLength]\n  var mul = 1\n  while (byteLength > 0 && (mul *= 0x100)) {\n    val += this[offset + --byteLength] * mul\n  }\n\n  return val\n}\n\nBuffer.prototype.readUInt8 = function readUInt8 (offset, noAssert) {\n  if (!noAssert) checkOffset(offset, 1, this.length)\n  return this[offset]\n}\n\nBuffer.prototype.readUInt16LE = function readUInt16LE (offset, noAssert) {\n  if (!noAssert) checkOffset(offset, 2, this.length)\n  return this[offset] | (this[offset + 1] << 8)\n}\n\nBuffer.prototype.readUInt16BE = function readUInt16BE (offset, noAssert) {\n  if (!noAssert) checkOffset(offset, 2, this.length)\n  return (this[offset] << 8) | this[offset + 1]\n}\n\nBuffer.prototype.readUInt32LE = function readUInt32LE (offset, noAssert) {\n  if (!noAssert) checkOffset(offset, 4, this.length)\n\n  return ((this[offset]) |\n      (this[offset + 1] << 8) |\n      (this[offset + 2] << 16)) +\n      (this[offset + 3] * 0x1000000)\n}\n\nBuffer.prototype.readUInt32BE = function readUInt32BE (offset, noAssert) {\n  if (!noAssert) checkOffset(offset, 4, this.length)\n\n  return (this[offset] * 0x1000000) +\n    ((this[offset + 1] << 16) |\n    (this[offset + 2] << 8) |\n    this[offset + 3])\n}\n\nBuffer.prototype.readIntLE = function readIntLE (offset, byteLength, noAssert) {\n  offset = offset | 0\n  byteLength = byteLength | 0\n  if (!noAssert) checkOffset(offset, byteLength, this.length)\n\n  var val = this[offset]\n  var mul = 1\n  var i = 0\n  while (++i < byteLength && (mul *= 0x100)) {\n    val += this[offset + i] * mul\n  }\n  mul *= 0x80\n\n  if (val >= mul) val -= Math.pow(2, 8 * byteLength)\n\n  return val\n}\n\nBuffer.prototype.readIntBE = function readIntBE (offset, byteLength, noAssert) {\n  offset = offset | 0\n  byteLength = byteLength | 0\n  if (!noAssert) checkOffset(offset, byteLength, this.length)\n\n  var i = byteLength\n  var mul = 1\n  var val = this[offset + --i]\n  while (i > 0 && (mul *= 0x100)) {\n    val += this[offset + --i] * mul\n  }\n  mul *= 0x80\n\n  if (val >= mul) val -= Math.pow(2, 8 * byteLength)\n\n  return val\n}\n\nBuffer.prototype.readInt8 = function readInt8 (offset, noAssert) {\n  if (!noAssert) checkOffset(offset, 1, this.length)\n  if (!(this[offset] & 0x80)) return (this[offset])\n  return ((0xff - this[offset] + 1) * -1)\n}\n\nBuffer.prototype.readInt16LE = function readInt16LE (offset, noAssert) {\n  if (!noAssert) checkOffset(offset, 2, this.length)\n  var val = this[offset] | (this[offset + 1] << 8)\n  return (val & 0x8000) ? val | 0xFFFF0000 : val\n}\n\nBuffer.prototype.readInt16BE = function readInt16BE (offset, noAssert) {\n  if (!noAssert) checkOffset(offset, 2, this.length)\n  var val = this[offset + 1] | (this[offset] << 8)\n  return (val & 0x8000) ? val | 0xFFFF0000 : val\n}\n\nBuffer.prototype.readInt32LE = function readInt32LE (offset, noAssert) {\n  if (!noAssert) checkOffset(offset, 4, this.length)\n\n  return (this[offset]) |\n    (this[offset + 1] << 8) |\n    (this[offset + 2] << 16) |\n    (this[offset + 3] << 24)\n}\n\nBuffer.prototype.readInt32BE = function readInt32BE (offset, noAssert) {\n  if (!noAssert) checkOffset(offset, 4, this.length)\n\n  return (this[offset] << 24) |\n    (this[offset + 1] << 16) |\n    (this[offset + 2] << 8) |\n    (this[offset + 3])\n}\n\nBuffer.prototype.readFloatLE = function readFloatLE (offset, noAssert) {\n  if (!noAssert) checkOffset(offset, 4, this.length)\n  return ieee754.read(this, offset, true, 23, 4)\n}\n\nBuffer.prototype.readFloatBE = function readFloatBE (offset, noAssert) {\n  if (!noAssert) checkOffset(offset, 4, this.length)\n  return ieee754.read(this, offset, false, 23, 4)\n}\n\nBuffer.prototype.readDoubleLE = function readDoubleLE (offset, noAssert) {\n  if (!noAssert) checkOffset(offset, 8, this.length)\n  return ieee754.read(this, offset, true, 52, 8)\n}\n\nBuffer.prototype.readDoubleBE = function readDoubleBE (offset, noAssert) {\n  if (!noAssert) checkOffset(offset, 8, this.length)\n  return ieee754.read(this, offset, false, 52, 8)\n}\n\nfunction checkInt (buf, value, offset, ext, max, min) {\n  if (!Buffer.isBuffer(buf)) throw new TypeError('buffer must be a Buffer instance')\n  if (value > max || value < min) throw new RangeError('value is out of bounds')\n  if (offset + ext > buf.length) throw new RangeError('index out of range')\n}\n\nBuffer.prototype.writeUIntLE = function writeUIntLE (value, offset, byteLength, noAssert) {\n  value = +value\n  offset = offset | 0\n  byteLength = byteLength | 0\n  if (!noAssert) checkInt(this, value, offset, byteLength, Math.pow(2, 8 * byteLength), 0)\n\n  var mul = 1\n  var i = 0\n  this[offset] = value & 0xFF\n  while (++i < byteLength && (mul *= 0x100)) {\n    this[offset + i] = (value / mul) & 0xFF\n  }\n\n  return offset + byteLength\n}\n\nBuffer.prototype.writeUIntBE = function writeUIntBE (value, offset, byteLength, noAssert) {\n  value = +value\n  offset = offset | 0\n  byteLength = byteLength | 0\n  if (!noAssert) checkInt(this, value, offset, byteLength, Math.pow(2, 8 * byteLength), 0)\n\n  var i = byteLength - 1\n  var mul = 1\n  this[offset + i] = value & 0xFF\n  while (--i >= 0 && (mul *= 0x100)) {\n    this[offset + i] = (value / mul) & 0xFF\n  }\n\n  return offset + byteLength\n}\n\nBuffer.prototype.writeUInt8 = function writeUInt8 (value, offset, noAssert) {\n  value = +value\n  offset = offset | 0\n  if (!noAssert) checkInt(this, value, offset, 1, 0xff, 0)\n  if (!Buffer.TYPED_ARRAY_SUPPORT) value = Math.floor(value)\n  this[offset] = value\n  return offset + 1\n}\n\nfunction objectWriteUInt16 (buf, value, offset, littleEndian) {\n  if (value < 0) value = 0xffff + value + 1\n  for (var i = 0, j = Math.min(buf.length - offset, 2); i < j; i++) {\n    buf[offset + i] = (value & (0xff << (8 * (littleEndian ? i : 1 - i)))) >>>\n      (littleEndian ? i : 1 - i) * 8\n  }\n}\n\nBuffer.prototype.writeUInt16LE = function writeUInt16LE (value, offset, noAssert) {\n  value = +value\n  offset = offset | 0\n  if (!noAssert) checkInt(this, value, offset, 2, 0xffff, 0)\n  if (Buffer.TYPED_ARRAY_SUPPORT) {\n    this[offset] = value\n    this[offset + 1] = (value >>> 8)\n  } else {\n    objectWriteUInt16(this, value, offset, true)\n  }\n  return offset + 2\n}\n\nBuffer.prototype.writeUInt16BE = function writeUInt16BE (value, offset, noAssert) {\n  value = +value\n  offset = offset | 0\n  if (!noAssert) checkInt(this, value, offset, 2, 0xffff, 0)\n  if (Buffer.TYPED_ARRAY_SUPPORT) {\n    this[offset] = (value >>> 8)\n    this[offset + 1] = value\n  } else {\n    objectWriteUInt16(this, value, offset, false)\n  }\n  return offset + 2\n}\n\nfunction objectWriteUInt32 (buf, value, offset, littleEndian) {\n  if (value < 0) value = 0xffffffff + value + 1\n  for (var i = 0, j = Math.min(buf.length - offset, 4); i < j; i++) {\n    buf[offset + i] = (value >>> (littleEndian ? i : 3 - i) * 8) & 0xff\n  }\n}\n\nBuffer.prototype.writeUInt32LE = function writeUInt32LE (value, offset, noAssert) {\n  value = +value\n  offset = offset | 0\n  if (!noAssert) checkInt(this, value, offset, 4, 0xffffffff, 0)\n  if (Buffer.TYPED_ARRAY_SUPPORT) {\n    this[offset + 3] = (value >>> 24)\n    this[offset + 2] = (value >>> 16)\n    this[offset + 1] = (value >>> 8)\n    this[offset] = value\n  } else {\n    objectWriteUInt32(this, value, offset, true)\n  }\n  return offset + 4\n}\n\nBuffer.prototype.writeUInt32BE = function writeUInt32BE (value, offset, noAssert) {\n  value = +value\n  offset = offset | 0\n  if (!noAssert) checkInt(this, value, offset, 4, 0xffffffff, 0)\n  if (Buffer.TYPED_ARRAY_SUPPORT) {\n    this[offset] = (value >>> 24)\n    this[offset + 1] = (value >>> 16)\n    this[offset + 2] = (value >>> 8)\n    this[offset + 3] = value\n  } else {\n    objectWriteUInt32(this, value, offset, false)\n  }\n  return offset + 4\n}\n\nBuffer.prototype.writeIntLE = function writeIntLE (value, offset, byteLength, noAssert) {\n  value = +value\n  offset = offset | 0\n  if (!noAssert) {\n    var limit = Math.pow(2, 8 * byteLength - 1)\n\n    checkInt(this, value, offset, byteLength, limit - 1, -limit)\n  }\n\n  var i = 0\n  var mul = 1\n  var sub = value < 0 ? 1 : 0\n  this[offset] = value & 0xFF\n  while (++i < byteLength && (mul *= 0x100)) {\n    this[offset + i] = ((value / mul) >> 0) - sub & 0xFF\n  }\n\n  return offset + byteLength\n}\n\nBuffer.prototype.writeIntBE = function writeIntBE (value, offset, byteLength, noAssert) {\n  value = +value\n  offset = offset | 0\n  if (!noAssert) {\n    var limit = Math.pow(2, 8 * byteLength - 1)\n\n    checkInt(this, value, offset, byteLength, limit - 1, -limit)\n  }\n\n  var i = byteLength - 1\n  var mul = 1\n  var sub = value < 0 ? 1 : 0\n  this[offset + i] = value & 0xFF\n  while (--i >= 0 && (mul *= 0x100)) {\n    this[offset + i] = ((value / mul) >> 0) - sub & 0xFF\n  }\n\n  return offset + byteLength\n}\n\nBuffer.prototype.writeInt8 = function writeInt8 (value, offset, noAssert) {\n  value = +value\n  offset = offset | 0\n  if (!noAssert) checkInt(this, value, offset, 1, 0x7f, -0x80)\n  if (!Buffer.TYPED_ARRAY_SUPPORT) value = Math.floor(value)\n  if (value < 0) value = 0xff + value + 1\n  this[offset] = value\n  return offset + 1\n}\n\nBuffer.prototype.writeInt16LE = function writeInt16LE (value, offset, noAssert) {\n  value = +value\n  offset = offset | 0\n  if (!noAssert) checkInt(this, value, offset, 2, 0x7fff, -0x8000)\n  if (Buffer.TYPED_ARRAY_SUPPORT) {\n    this[offset] = value\n    this[offset + 1] = (value >>> 8)\n  } else {\n    objectWriteUInt16(this, value, offset, true)\n  }\n  return offset + 2\n}\n\nBuffer.prototype.writeInt16BE = function writeInt16BE (value, offset, noAssert) {\n  value = +value\n  offset = offset | 0\n  if (!noAssert) checkInt(this, value, offset, 2, 0x7fff, -0x8000)\n  if (Buffer.TYPED_ARRAY_SUPPORT) {\n    this[offset] = (value >>> 8)\n    this[offset + 1] = value\n  } else {\n    objectWriteUInt16(this, value, offset, false)\n  }\n  return offset + 2\n}\n\nBuffer.prototype.writeInt32LE = function writeInt32LE (value, offset, noAssert) {\n  value = +value\n  offset = offset | 0\n  if (!noAssert) checkInt(this, value, offset, 4, 0x7fffffff, -0x80000000)\n  if (Buffer.TYPED_ARRAY_SUPPORT) {\n    this[offset] = value\n    this[offset + 1] = (value >>> 8)\n    this[offset + 2] = (value >>> 16)\n    this[offset + 3] = (value >>> 24)\n  } else {\n    objectWriteUInt32(this, value, offset, true)\n  }\n  return offset + 4\n}\n\nBuffer.prototype.writeInt32BE = function writeInt32BE (value, offset, noAssert) {\n  value = +value\n  offset = offset | 0\n  if (!noAssert) checkInt(this, value, offset, 4, 0x7fffffff, -0x80000000)\n  if (value < 0) value = 0xffffffff + value + 1\n  if (Buffer.TYPED_ARRAY_SUPPORT) {\n    this[offset] = (value >>> 24)\n    this[offset + 1] = (value >>> 16)\n    this[offset + 2] = (value >>> 8)\n    this[offset + 3] = value\n  } else {\n    objectWriteUInt32(this, value, offset, false)\n  }\n  return offset + 4\n}\n\nfunction checkIEEE754 (buf, value, offset, ext, max, min) {\n  if (value > max || value < min) throw new RangeError('value is out of bounds')\n  if (offset + ext > buf.length) throw new RangeError('index out of range')\n  if (offset < 0) throw new RangeError('index out of range')\n}\n\nfunction writeFloat (buf, value, offset, littleEndian, noAssert) {\n  if (!noAssert) {\n    checkIEEE754(buf, value, offset, 4, 3.4028234663852886e+38, -3.4028234663852886e+38)\n  }\n  ieee754.write(buf, value, offset, littleEndian, 23, 4)\n  return offset + 4\n}\n\nBuffer.prototype.writeFloatLE = function writeFloatLE (value, offset, noAssert) {\n  return writeFloat(this, value, offset, true, noAssert)\n}\n\nBuffer.prototype.writeFloatBE = function writeFloatBE (value, offset, noAssert) {\n  return writeFloat(this, value, offset, false, noAssert)\n}\n\nfunction writeDouble (buf, value, offset, littleEndian, noAssert) {\n  if (!noAssert) {\n    checkIEEE754(buf, value, offset, 8, 1.7976931348623157E+308, -1.7976931348623157E+308)\n  }\n  ieee754.write(buf, value, offset, littleEndian, 52, 8)\n  return offset + 8\n}\n\nBuffer.prototype.writeDoubleLE = function writeDoubleLE (value, offset, noAssert) {\n  return writeDouble(this, value, offset, true, noAssert)\n}\n\nBuffer.prototype.writeDoubleBE = function writeDoubleBE (value, offset, noAssert) {\n  return writeDouble(this, value, offset, false, noAssert)\n}\n\n// copy(targetBuffer, targetStart=0, sourceStart=0, sourceEnd=buffer.length)\nBuffer.prototype.copy = function copy (target, targetStart, start, end) {\n  if (!start) start = 0\n  if (!end && end !== 0) end = this.length\n  if (targetStart >= target.length) targetStart = target.length\n  if (!targetStart) targetStart = 0\n  if (end > 0 && end < start) end = start\n\n  // Copy 0 bytes; we're done\n  if (end === start) return 0\n  if (target.length === 0 || this.length === 0) return 0\n\n  // Fatal error conditions\n  if (targetStart < 0) {\n    throw new RangeError('targetStart out of bounds')\n  }\n  if (start < 0 || start >= this.length) throw new RangeError('sourceStart out of bounds')\n  if (end < 0) throw new RangeError('sourceEnd out of bounds')\n\n  // Are we oob?\n  if (end > this.length) end = this.length\n  if (target.length - targetStart < end - start) {\n    end = target.length - targetStart + start\n  }\n\n  var len = end - start\n  var i\n\n  if (this === target && start < targetStart && targetStart < end) {\n    // descending copy from end\n    for (i = len - 1; i >= 0; i--) {\n      target[i + targetStart] = this[i + start]\n    }\n  } else if (len < 1000 || !Buffer.TYPED_ARRAY_SUPPORT) {\n    // ascending copy from start\n    for (i = 0; i < len; i++) {\n      target[i + targetStart] = this[i + start]\n    }\n  } else {\n    target._set(this.subarray(start, start + len), targetStart)\n  }\n\n  return len\n}\n\n// fill(value, start=0, end=buffer.length)\nBuffer.prototype.fill = function fill (value, start, end) {\n  if (!value) value = 0\n  if (!start) start = 0\n  if (!end) end = this.length\n\n  if (end < start) throw new RangeError('end < start')\n\n  // Fill 0 bytes; we're done\n  if (end === start) return\n  if (this.length === 0) return\n\n  if (start < 0 || start >= this.length) throw new RangeError('start out of bounds')\n  if (end < 0 || end > this.length) throw new RangeError('end out of bounds')\n\n  var i\n  if (typeof value === 'number') {\n    for (i = start; i < end; i++) {\n      this[i] = value\n    }\n  } else {\n    var bytes = utf8ToBytes(value.toString())\n    var len = bytes.length\n    for (i = start; i < end; i++) {\n      this[i] = bytes[i % len]\n    }\n  }\n\n  return this\n}\n\n/**\n * Creates a new `ArrayBuffer` with the *copied* memory of the buffer instance.\n * Added in Node 0.12. Only available in browsers that support ArrayBuffer.\n */\nBuffer.prototype.toArrayBuffer = function toArrayBuffer () {\n  if (typeof Uint8Array !== 'undefined') {\n    if (Buffer.TYPED_ARRAY_SUPPORT) {\n      return (new Buffer(this)).buffer\n    } else {\n      var buf = new Uint8Array(this.length)\n      for (var i = 0, len = buf.length; i < len; i += 1) {\n        buf[i] = this[i]\n      }\n      return buf.buffer\n    }\n  } else {\n    throw new TypeError('Buffer.toArrayBuffer not supported in this browser')\n  }\n}\n\n// HELPER FUNCTIONS\n// ================\n\nvar BP = Buffer.prototype\n\n/**\n * Augment a Uint8Array *instance* (not the Uint8Array class!) with Buffer methods\n */\nBuffer._augment = function _augment (arr) {\n  arr.constructor = Buffer\n  arr._isBuffer = true\n\n  // save reference to original Uint8Array set method before overwriting\n  arr._set = arr.set\n\n  // deprecated\n  arr.get = BP.get\n  arr.set = BP.set\n\n  arr.write = BP.write\n  arr.toString = BP.toString\n  arr.toLocaleString = BP.toString\n  arr.toJSON = BP.toJSON\n  arr.equals = BP.equals\n  arr.compare = BP.compare\n  arr.indexOf = BP.indexOf\n  arr.copy = BP.copy\n  arr.slice = BP.slice\n  arr.readUIntLE = BP.readUIntLE\n  arr.readUIntBE = BP.readUIntBE\n  arr.readUInt8 = BP.readUInt8\n  arr.readUInt16LE = BP.readUInt16LE\n  arr.readUInt16BE = BP.readUInt16BE\n  arr.readUInt32LE = BP.readUInt32LE\n  arr.readUInt32BE = BP.readUInt32BE\n  arr.readIntLE = BP.readIntLE\n  arr.readIntBE = BP.readIntBE\n  arr.readInt8 = BP.readInt8\n  arr.readInt16LE = BP.readInt16LE\n  arr.readInt16BE = BP.readInt16BE\n  arr.readInt32LE = BP.readInt32LE\n  arr.readInt32BE = BP.readInt32BE\n  arr.readFloatLE = BP.readFloatLE\n  arr.readFloatBE = BP.readFloatBE\n  arr.readDoubleLE = BP.readDoubleLE\n  arr.readDoubleBE = BP.readDoubleBE\n  arr.writeUInt8 = BP.writeUInt8\n  arr.writeUIntLE = BP.writeUIntLE\n  arr.writeUIntBE = BP.writeUIntBE\n  arr.writeUInt16LE = BP.writeUInt16LE\n  arr.writeUInt16BE = BP.writeUInt16BE\n  arr.writeUInt32LE = BP.writeUInt32LE\n  arr.writeUInt32BE = BP.writeUInt32BE\n  arr.writeIntLE = BP.writeIntLE\n  arr.writeIntBE = BP.writeIntBE\n  arr.writeInt8 = BP.writeInt8\n  arr.writeInt16LE = BP.writeInt16LE\n  arr.writeInt16BE = BP.writeInt16BE\n  arr.writeInt32LE = BP.writeInt32LE\n  arr.writeInt32BE = BP.writeInt32BE\n  arr.writeFloatLE = BP.writeFloatLE\n  arr.writeFloatBE = BP.writeFloatBE\n  arr.writeDoubleLE = BP.writeDoubleLE\n  arr.writeDoubleBE = BP.writeDoubleBE\n  arr.fill = BP.fill\n  arr.inspect = BP.inspect\n  arr.toArrayBuffer = BP.toArrayBuffer\n\n  return arr\n}\n\nvar INVALID_BASE64_RE = /[^+\\/0-9A-Za-z-_]/g\n\nfunction base64clean (str) {\n  // Node strips out invalid characters like \\n and \\t from the string, base64-js does not\n  str = stringtrim(str).replace(INVALID_BASE64_RE, '')\n  // Node converts strings with length < 2 to ''\n  if (str.length < 2) return ''\n  // Node allows for non-padded base64 strings (missing trailing ===), base64-js does not\n  while (str.length % 4 !== 0) {\n    str = str + '='\n  }\n  return str\n}\n\nfunction stringtrim (str) {\n  if (str.trim) return str.trim()\n  return str.replace(/^\\s+|\\s+$/g, '')\n}\n\nfunction toHex (n) {\n  if (n < 16) return '0' + n.toString(16)\n  return n.toString(16)\n}\n\nfunction utf8ToBytes (string, units) {\n  units = units || Infinity\n  var codePoint\n  var length = string.length\n  var leadSurrogate = null\n  var bytes = []\n\n  for (var i = 0; i < length; i++) {\n    codePoint = string.charCodeAt(i)\n\n    // is surrogate component\n    if (codePoint > 0xD7FF && codePoint < 0xE000) {\n      // last char was a lead\n      if (!leadSurrogate) {\n        // no lead yet\n        if (codePoint > 0xDBFF) {\n          // unexpected trail\n          if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD)\n          continue\n        } else if (i + 1 === length) {\n          // unpaired lead\n          if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD)\n          continue\n        }\n\n        // valid lead\n        leadSurrogate = codePoint\n\n        continue\n      }\n\n      // 2 leads in a row\n      if (codePoint < 0xDC00) {\n        if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD)\n        leadSurrogate = codePoint\n        continue\n      }\n\n      // valid surrogate pair\n      codePoint = leadSurrogate - 0xD800 << 10 | codePoint - 0xDC00 | 0x10000\n    } else if (leadSurrogate) {\n      // valid bmp char, but last char was a lead\n      if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD)\n    }\n\n    leadSurrogate = null\n\n    // encode utf8\n    if (codePoint < 0x80) {\n      if ((units -= 1) < 0) break\n      bytes.push(codePoint)\n    } else if (codePoint < 0x800) {\n      if ((units -= 2) < 0) break\n      bytes.push(\n        codePoint >> 0x6 | 0xC0,\n        codePoint & 0x3F | 0x80\n      )\n    } else if (codePoint < 0x10000) {\n      if ((units -= 3) < 0) break\n      bytes.push(\n        codePoint >> 0xC | 0xE0,\n        codePoint >> 0x6 & 0x3F | 0x80,\n        codePoint & 0x3F | 0x80\n      )\n    } else if (codePoint < 0x110000) {\n      if ((units -= 4) < 0) break\n      bytes.push(\n        codePoint >> 0x12 | 0xF0,\n        codePoint >> 0xC & 0x3F | 0x80,\n        codePoint >> 0x6 & 0x3F | 0x80,\n        codePoint & 0x3F | 0x80\n      )\n    } else {\n      throw new Error('Invalid code point')\n    }\n  }\n\n  return bytes\n}\n\nfunction asciiToBytes (str) {\n  var byteArray = []\n  for (var i = 0; i < str.length; i++) {\n    // Node's code seems to be doing this and not & 0x7F..\n    byteArray.push(str.charCodeAt(i) & 0xFF)\n  }\n  return byteArray\n}\n\nfunction utf16leToBytes (str, units) {\n  var c, hi, lo\n  var byteArray = []\n  for (var i = 0; i < str.length; i++) {\n    if ((units -= 2) < 0) break\n\n    c = str.charCodeAt(i)\n    hi = c >> 8\n    lo = c % 256\n    byteArray.push(lo)\n    byteArray.push(hi)\n  }\n\n  return byteArray\n}\n\nfunction base64ToBytes (str) {\n  return base64.toByteArray(base64clean(str))\n}\n\nfunction blitBuffer (src, dst, offset, length) {\n  for (var i = 0; i < length; i++) {\n    if ((i + offset >= dst.length) || (i >= src.length)) break\n    dst[i + offset] = src[i]\n  }\n  return i\n}\n\n},{\"base64-js\":44,\"ieee754\":45,\"is-array\":46}],44:[function(require,module,exports){\nvar lookup = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';\n\n;(function (exports) {\n\t'use strict';\n\n  var Arr = (typeof Uint8Array !== 'undefined')\n    ? Uint8Array\n    : Array\n\n\tvar PLUS   = '+'.charCodeAt(0)\n\tvar SLASH  = '/'.charCodeAt(0)\n\tvar NUMBER = '0'.charCodeAt(0)\n\tvar LOWER  = 'a'.charCodeAt(0)\n\tvar UPPER  = 'A'.charCodeAt(0)\n\tvar PLUS_URL_SAFE = '-'.charCodeAt(0)\n\tvar SLASH_URL_SAFE = '_'.charCodeAt(0)\n\n\tfunction decode (elt) {\n\t\tvar code = elt.charCodeAt(0)\n\t\tif (code === PLUS ||\n\t\t    code === PLUS_URL_SAFE)\n\t\t\treturn 62 // '+'\n\t\tif (code === SLASH ||\n\t\t    code === SLASH_URL_SAFE)\n\t\t\treturn 63 // '/'\n\t\tif (code < NUMBER)\n\t\t\treturn -1 //no match\n\t\tif (code < NUMBER + 10)\n\t\t\treturn code - NUMBER + 26 + 26\n\t\tif (code < UPPER + 26)\n\t\t\treturn code - UPPER\n\t\tif (code < LOWER + 26)\n\t\t\treturn code - LOWER + 26\n\t}\n\n\tfunction b64ToByteArray (b64) {\n\t\tvar i, j, l, tmp, placeHolders, arr\n\n\t\tif (b64.length % 4 > 0) {\n\t\t\tthrow new Error('Invalid string. Length must be a multiple of 4')\n\t\t}\n\n\t\t// the number of equal signs (place holders)\n\t\t// if there are two placeholders, than the two characters before it\n\t\t// represent one byte\n\t\t// if there is only one, then the three characters before it represent 2 bytes\n\t\t// this is just a cheap hack to not do indexOf twice\n\t\tvar len = b64.length\n\t\tplaceHolders = '=' === b64.charAt(len - 2) ? 2 : '=' === b64.charAt(len - 1) ? 1 : 0\n\n\t\t// base64 is 4/3 + up to two characters of the original data\n\t\tarr = new Arr(b64.length * 3 / 4 - placeHolders)\n\n\t\t// if there are placeholders, only get up to the last complete 4 chars\n\t\tl = placeHolders > 0 ? b64.length - 4 : b64.length\n\n\t\tvar L = 0\n\n\t\tfunction push (v) {\n\t\t\tarr[L++] = v\n\t\t}\n\n\t\tfor (i = 0, j = 0; i < l; i += 4, j += 3) {\n\t\t\ttmp = (decode(b64.charAt(i)) << 18) | (decode(b64.charAt(i + 1)) << 12) | (decode(b64.charAt(i + 2)) << 6) | decode(b64.charAt(i + 3))\n\t\t\tpush((tmp & 0xFF0000) >> 16)\n\t\t\tpush((tmp & 0xFF00) >> 8)\n\t\t\tpush(tmp & 0xFF)\n\t\t}\n\n\t\tif (placeHolders === 2) {\n\t\t\ttmp = (decode(b64.charAt(i)) << 2) | (decode(b64.charAt(i + 1)) >> 4)\n\t\t\tpush(tmp & 0xFF)\n\t\t} else if (placeHolders === 1) {\n\t\t\ttmp = (decode(b64.charAt(i)) << 10) | (decode(b64.charAt(i + 1)) << 4) | (decode(b64.charAt(i + 2)) >> 2)\n\t\t\tpush((tmp >> 8) & 0xFF)\n\t\t\tpush(tmp & 0xFF)\n\t\t}\n\n\t\treturn arr\n\t}\n\n\tfunction uint8ToBase64 (uint8) {\n\t\tvar i,\n\t\t\textraBytes = uint8.length % 3, // if we have 1 byte left, pad 2 bytes\n\t\t\toutput = \"\",\n\t\t\ttemp, length\n\n\t\tfunction encode (num) {\n\t\t\treturn lookup.charAt(num)\n\t\t}\n\n\t\tfunction tripletToBase64 (num) {\n\t\t\treturn encode(num >> 18 & 0x3F) + encode(num >> 12 & 0x3F) + encode(num >> 6 & 0x3F) + encode(num & 0x3F)\n\t\t}\n\n\t\t// go through the array every three bytes, we'll deal with trailing stuff later\n\t\tfor (i = 0, length = uint8.length - extraBytes; i < length; i += 3) {\n\t\t\ttemp = (uint8[i] << 16) + (uint8[i + 1] << 8) + (uint8[i + 2])\n\t\t\toutput += tripletToBase64(temp)\n\t\t}\n\n\t\t// pad the end with zeros, but make sure to not forget the extra bytes\n\t\tswitch (extraBytes) {\n\t\t\tcase 1:\n\t\t\t\ttemp = uint8[uint8.length - 1]\n\t\t\t\toutput += encode(temp >> 2)\n\t\t\t\toutput += encode((temp << 4) & 0x3F)\n\t\t\t\toutput += '=='\n\t\t\t\tbreak\n\t\t\tcase 2:\n\t\t\t\ttemp = (uint8[uint8.length - 2] << 8) + (uint8[uint8.length - 1])\n\t\t\t\toutput += encode(temp >> 10)\n\t\t\t\toutput += encode((temp >> 4) & 0x3F)\n\t\t\t\toutput += encode((temp << 2) & 0x3F)\n\t\t\t\toutput += '='\n\t\t\t\tbreak\n\t\t}\n\n\t\treturn output\n\t}\n\n\texports.toByteArray = b64ToByteArray\n\texports.fromByteArray = uint8ToBase64\n}(typeof exports === 'undefined' ? (this.base64js = {}) : exports))\n\n},{}],45:[function(require,module,exports){\nexports.read = function (buffer, offset, isLE, mLen, nBytes) {\n  var e, m\n  var eLen = nBytes * 8 - mLen - 1\n  var eMax = (1 << eLen) - 1\n  var eBias = eMax >> 1\n  var nBits = -7\n  var i = isLE ? (nBytes - 1) : 0\n  var d = isLE ? -1 : 1\n  var s = buffer[offset + i]\n\n  i += d\n\n  e = s & ((1 << (-nBits)) - 1)\n  s >>= (-nBits)\n  nBits += eLen\n  for (; nBits > 0; e = e * 256 + buffer[offset + i], i += d, nBits -= 8) {}\n\n  m = e & ((1 << (-nBits)) - 1)\n  e >>= (-nBits)\n  nBits += mLen\n  for (; nBits > 0; m = m * 256 + buffer[offset + i], i += d, nBits -= 8) {}\n\n  if (e === 0) {\n    e = 1 - eBias\n  } else if (e === eMax) {\n    return m ? NaN : ((s ? -1 : 1) * Infinity)\n  } else {\n    m = m + Math.pow(2, mLen)\n    e = e - eBias\n  }\n  return (s ? -1 : 1) * m * Math.pow(2, e - mLen)\n}\n\nexports.write = function (buffer, value, offset, isLE, mLen, nBytes) {\n  var e, m, c\n  var eLen = nBytes * 8 - mLen - 1\n  var eMax = (1 << eLen) - 1\n  var eBias = eMax >> 1\n  var rt = (mLen === 23 ? Math.pow(2, -24) - Math.pow(2, -77) : 0)\n  var i = isLE ? 0 : (nBytes - 1)\n  var d = isLE ? 1 : -1\n  var s = value < 0 || (value === 0 && 1 / value < 0) ? 1 : 0\n\n  value = Math.abs(value)\n\n  if (isNaN(value) || value === Infinity) {\n    m = isNaN(value) ? 1 : 0\n    e = eMax\n  } else {\n    e = Math.floor(Math.log(value) / Math.LN2)\n    if (value * (c = Math.pow(2, -e)) < 1) {\n      e--\n      c *= 2\n    }\n    if (e + eBias >= 1) {\n      value += rt / c\n    } else {\n      value += rt * Math.pow(2, 1 - eBias)\n    }\n    if (value * c >= 2) {\n      e++\n      c /= 2\n    }\n\n    if (e + eBias >= eMax) {\n      m = 0\n      e = eMax\n    } else if (e + eBias >= 1) {\n      m = (value * c - 1) * Math.pow(2, mLen)\n      e = e + eBias\n    } else {\n      m = value * Math.pow(2, eBias - 1) * Math.pow(2, mLen)\n      e = 0\n    }\n  }\n\n  for (; mLen >= 8; buffer[offset + i] = m & 0xff, i += d, m /= 256, mLen -= 8) {}\n\n  e = (e << mLen) | m\n  eLen += mLen\n  for (; eLen > 0; buffer[offset + i] = e & 0xff, i += d, e /= 256, eLen -= 8) {}\n\n  buffer[offset + i - d] |= s * 128\n}\n\n},{}],46:[function(require,module,exports){\n\n/**\n * isArray\n */\n\nvar isArray = Array.isArray;\n\n/**\n * toString\n */\n\nvar str = Object.prototype.toString;\n\n/**\n * Whether or not the given `val`\n * is an array.\n *\n * example:\n *\n *        isArray([]);\n *        // > true\n *        isArray(arguments);\n *        // > false\n *        isArray('');\n *        // > false\n *\n * @param {mixed} val\n * @return {bool}\n */\n\nmodule.exports = isArray || function (val) {\n  return !! val && '[object Array]' == str.call(val);\n};\n\n},{}],47:[function(require,module,exports){\n// Copyright Joyent, Inc. and other Node contributors.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a\n// copy of this software and associated documentation files (the\n// \"Software\"), to deal in the Software without restriction, including\n// without limitation the rights to use, copy, modify, merge, publish,\n// distribute, sublicense, and/or sell copies of the Software, and to permit\n// persons to whom the Software is furnished to do so, subject to the\n// following conditions:\n//\n// The above copyright notice and this permission notice shall be included\n// in all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS\n// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN\n// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,\n// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE\n// USE OR OTHER DEALINGS IN THE SOFTWARE.\n\nfunction EventEmitter() {\n  this._events = this._events || {};\n  this._maxListeners = this._maxListeners || undefined;\n}\nmodule.exports = EventEmitter;\n\n// Backwards-compat with node 0.10.x\nEventEmitter.EventEmitter = EventEmitter;\n\nEventEmitter.prototype._events = undefined;\nEventEmitter.prototype._maxListeners = undefined;\n\n// By default EventEmitters will print a warning if more than 10 listeners are\n// added to it. This is a useful default which helps finding memory leaks.\nEventEmitter.defaultMaxListeners = 10;\n\n// Obviously not all Emitters should be limited to 10. This function allows\n// that to be increased. Set to zero for unlimited.\nEventEmitter.prototype.setMaxListeners = function(n) {\n  if (!isNumber(n) || n < 0 || isNaN(n))\n    throw TypeError('n must be a positive number');\n  this._maxListeners = n;\n  return this;\n};\n\nEventEmitter.prototype.emit = function(type) {\n  var er, handler, len, args, i, listeners;\n\n  if (!this._events)\n    this._events = {};\n\n  // If there is no 'error' event listener then throw.\n  if (type === 'error') {\n    if (!this._events.error ||\n        (isObject(this._events.error) && !this._events.error.length)) {\n      er = arguments[1];\n      if (er instanceof Error) {\n        throw er; // Unhandled 'error' event\n      }\n      throw TypeError('Uncaught, unspecified \"error\" event.');\n    }\n  }\n\n  handler = this._events[type];\n\n  if (isUndefined(handler))\n    return false;\n\n  if (isFunction(handler)) {\n    switch (arguments.length) {\n      // fast cases\n      case 1:\n        handler.call(this);\n        break;\n      case 2:\n        handler.call(this, arguments[1]);\n        break;\n      case 3:\n        handler.call(this, arguments[1], arguments[2]);\n        break;\n      // slower\n      default:\n        len = arguments.length;\n        args = new Array(len - 1);\n        for (i = 1; i < len; i++)\n          args[i - 1] = arguments[i];\n        handler.apply(this, args);\n    }\n  } else if (isObject(handler)) {\n    len = arguments.length;\n    args = new Array(len - 1);\n    for (i = 1; i < len; i++)\n      args[i - 1] = arguments[i];\n\n    listeners = handler.slice();\n    len = listeners.length;\n    for (i = 0; i < len; i++)\n      listeners[i].apply(this, args);\n  }\n\n  return true;\n};\n\nEventEmitter.prototype.addListener = function(type, listener) {\n  var m;\n\n  if (!isFunction(listener))\n    throw TypeError('listener must be a function');\n\n  if (!this._events)\n    this._events = {};\n\n  // To avoid recursion in the case that type === \"newListener\"! Before\n  // adding it to the listeners, first emit \"newListener\".\n  if (this._events.newListener)\n    this.emit('newListener', type,\n              isFunction(listener.listener) ?\n              listener.listener : listener);\n\n  if (!this._events[type])\n    // Optimize the case of one listener. Don't need the extra array object.\n    this._events[type] = listener;\n  else if (isObject(this._events[type]))\n    // If we've already got an array, just append.\n    this._events[type].push(listener);\n  else\n    // Adding the second element, need to change to array.\n    this._events[type] = [this._events[type], listener];\n\n  // Check for listener leak\n  if (isObject(this._events[type]) && !this._events[type].warned) {\n    var m;\n    if (!isUndefined(this._maxListeners)) {\n      m = this._maxListeners;\n    } else {\n      m = EventEmitter.defaultMaxListeners;\n    }\n\n    if (m && m > 0 && this._events[type].length > m) {\n      this._events[type].warned = true;\n      console.error('(node) warning: possible EventEmitter memory ' +\n                    'leak detected. %d listeners added. ' +\n                    'Use emitter.setMaxListeners() to increase limit.',\n                    this._events[type].length);\n      if (typeof console.trace === 'function') {\n        // not supported in IE 10\n        console.trace();\n      }\n    }\n  }\n\n  return this;\n};\n\nEventEmitter.prototype.on = EventEmitter.prototype.addListener;\n\nEventEmitter.prototype.once = function(type, listener) {\n  if (!isFunction(listener))\n    throw TypeError('listener must be a function');\n\n  var fired = false;\n\n  function g() {\n    this.removeListener(type, g);\n\n    if (!fired) {\n      fired = true;\n      listener.apply(this, arguments);\n    }\n  }\n\n  g.listener = listener;\n  this.on(type, g);\n\n  return this;\n};\n\n// emits a 'removeListener' event iff the listener was removed\nEventEmitter.prototype.removeListener = function(type, listener) {\n  var list, position, length, i;\n\n  if (!isFunction(listener))\n    throw TypeError('listener must be a function');\n\n  if (!this._events || !this._events[type])\n    return this;\n\n  list = this._events[type];\n  length = list.length;\n  position = -1;\n\n  if (list === listener ||\n      (isFunction(list.listener) && list.listener === listener)) {\n    delete this._events[type];\n    if (this._events.removeListener)\n      this.emit('removeListener', type, listener);\n\n  } else if (isObject(list)) {\n    for (i = length; i-- > 0;) {\n      if (list[i] === listener ||\n          (list[i].listener && list[i].listener === listener)) {\n        position = i;\n        break;\n      }\n    }\n\n    if (position < 0)\n      return this;\n\n    if (list.length === 1) {\n      list.length = 0;\n      delete this._events[type];\n    } else {\n      list.splice(position, 1);\n    }\n\n    if (this._events.removeListener)\n      this.emit('removeListener', type, listener);\n  }\n\n  return this;\n};\n\nEventEmitter.prototype.removeAllListeners = function(type) {\n  var key, listeners;\n\n  if (!this._events)\n    return this;\n\n  // not listening for removeListener, no need to emit\n  if (!this._events.removeListener) {\n    if (arguments.length === 0)\n      this._events = {};\n    else if (this._events[type])\n      delete this._events[type];\n    return this;\n  }\n\n  // emit removeListener for all listeners on all events\n  if (arguments.length === 0) {\n    for (key in this._events) {\n      if (key === 'removeListener') continue;\n      this.removeAllListeners(key);\n    }\n    this.removeAllListeners('removeListener');\n    this._events = {};\n    return this;\n  }\n\n  listeners = this._events[type];\n\n  if (isFunction(listeners)) {\n    this.removeListener(type, listeners);\n  } else {\n    // LIFO order\n    while (listeners.length)\n      this.removeListener(type, listeners[listeners.length - 1]);\n  }\n  delete this._events[type];\n\n  return this;\n};\n\nEventEmitter.prototype.listeners = function(type) {\n  var ret;\n  if (!this._events || !this._events[type])\n    ret = [];\n  else if (isFunction(this._events[type]))\n    ret = [this._events[type]];\n  else\n    ret = this._events[type].slice();\n  return ret;\n};\n\nEventEmitter.listenerCount = function(emitter, type) {\n  var ret;\n  if (!emitter._events || !emitter._events[type])\n    ret = 0;\n  else if (isFunction(emitter._events[type]))\n    ret = 1;\n  else\n    ret = emitter._events[type].length;\n  return ret;\n};\n\nfunction isFunction(arg) {\n  return typeof arg === 'function';\n}\n\nfunction isNumber(arg) {\n  return typeof arg === 'number';\n}\n\nfunction isObject(arg) {\n  return typeof arg === 'object' && arg !== null;\n}\n\nfunction isUndefined(arg) {\n  return arg === void 0;\n}\n\n},{}],48:[function(require,module,exports){\nif (typeof Object.create === 'function') {\n  // implementation from standard node.js 'util' module\n  module.exports = function inherits(ctor, superCtor) {\n    ctor.super_ = superCtor\n    ctor.prototype = Object.create(superCtor.prototype, {\n      constructor: {\n        value: ctor,\n        enumerable: false,\n        writable: true,\n        configurable: true\n      }\n    });\n  };\n} else {\n  // old school shim for old browsers\n  module.exports = function inherits(ctor, superCtor) {\n    ctor.super_ = superCtor\n    var TempCtor = function () {}\n    TempCtor.prototype = superCtor.prototype\n    ctor.prototype = new TempCtor()\n    ctor.prototype.constructor = ctor\n  }\n}\n\n},{}],49:[function(require,module,exports){\nmodule.exports = Array.isArray || function (arr) {\n  return Object.prototype.toString.call(arr) == '[object Array]';\n};\n\n},{}],50:[function(require,module,exports){\nexports.endianness = function () { return 'LE' };\n\nexports.hostname = function () {\n    if (typeof location !== 'undefined') {\n        return location.hostname\n    }\n    else return '';\n};\n\nexports.loadavg = function () { return [] };\n\nexports.uptime = function () { return 0 };\n\nexports.freemem = function () {\n    return Number.MAX_VALUE;\n};\n\nexports.totalmem = function () {\n    return Number.MAX_VALUE;\n};\n\nexports.cpus = function () { return [] };\n\nexports.type = function () { return 'Browser' };\n\nexports.release = function () {\n    if (typeof navigator !== 'undefined') {\n        return navigator.appVersion;\n    }\n    return '';\n};\n\nexports.networkInterfaces\n= exports.getNetworkInterfaces\n= function () { return {} };\n\nexports.arch = function () { return 'javascript' };\n\nexports.platform = function () { return 'browser' };\n\nexports.tmpdir = exports.tmpDir = function () {\n    return '/tmp';\n};\n\nexports.EOL = '\\n';\n\n},{}],51:[function(require,module,exports){\n// shim for using process in browser\n\nvar process = module.exports = {};\nvar queue = [];\nvar draining = false;\nvar currentQueue;\nvar queueIndex = -1;\n\nfunction cleanUpNextTick() {\n    draining = false;\n    if (currentQueue.length) {\n        queue = currentQueue.concat(queue);\n    } else {\n        queueIndex = -1;\n    }\n    if (queue.length) {\n        drainQueue();\n    }\n}\n\nfunction drainQueue() {\n    if (draining) {\n        return;\n    }\n    var timeout = setTimeout(cleanUpNextTick);\n    draining = true;\n\n    var len = queue.length;\n    while(len) {\n        currentQueue = queue;\n        queue = [];\n        while (++queueIndex < len) {\n            if (currentQueue) {\n                currentQueue[queueIndex].run();\n            }\n        }\n        queueIndex = -1;\n        len = queue.length;\n    }\n    currentQueue = null;\n    draining = false;\n    clearTimeout(timeout);\n}\n\nprocess.nextTick = function (fun) {\n    var args = new Array(arguments.length - 1);\n    if (arguments.length > 1) {\n        for (var i = 1; i < arguments.length; i++) {\n            args[i - 1] = arguments[i];\n        }\n    }\n    queue.push(new Item(fun, args));\n    if (queue.length === 1 && !draining) {\n        setTimeout(drainQueue, 0);\n    }\n};\n\n// v8 likes predictible objects\nfunction Item(fun, array) {\n    this.fun = fun;\n    this.array = array;\n}\nItem.prototype.run = function () {\n    this.fun.apply(null, this.array);\n};\nprocess.title = 'browser';\nprocess.browser = true;\nprocess.env = {};\nprocess.argv = [];\nprocess.version = ''; // empty string to avoid regexp issues\nprocess.versions = {};\n\nfunction noop() {}\n\nprocess.on = noop;\nprocess.addListener = noop;\nprocess.once = noop;\nprocess.off = noop;\nprocess.removeListener = noop;\nprocess.removeAllListeners = noop;\nprocess.emit = noop;\n\nprocess.binding = function (name) {\n    throw new Error('process.binding is not supported');\n};\n\nprocess.cwd = function () { return '/' };\nprocess.chdir = function (dir) {\n    throw new Error('process.chdir is not supported');\n};\nprocess.umask = function() { return 0; };\n\n},{}],52:[function(require,module,exports){\nmodule.exports = require(\"./lib/_stream_duplex.js\")\n\n},{\"./lib/_stream_duplex.js\":53}],53:[function(require,module,exports){\n(function (process){\n// Copyright Joyent, Inc. and other Node contributors.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a\n// copy of this software and associated documentation files (the\n// \"Software\"), to deal in the Software without restriction, including\n// without limitation the rights to use, copy, modify, merge, publish,\n// distribute, sublicense, and/or sell copies of the Software, and to permit\n// persons to whom the Software is furnished to do so, subject to the\n// following conditions:\n//\n// The above copyright notice and this permission notice shall be included\n// in all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS\n// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN\n// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,\n// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE\n// USE OR OTHER DEALINGS IN THE SOFTWARE.\n\n// a duplex stream is just a stream that is both readable and writable.\n// Since JS doesn't have multiple prototypal inheritance, this class\n// prototypally inherits from Readable, and then parasitically from\n// Writable.\n\nmodule.exports = Duplex;\n\n/*<replacement>*/\nvar objectKeys = Object.keys || function (obj) {\n  var keys = [];\n  for (var key in obj) keys.push(key);\n  return keys;\n}\n/*</replacement>*/\n\n\n/*<replacement>*/\nvar util = require('core-util-is');\nutil.inherits = require('inherits');\n/*</replacement>*/\n\nvar Readable = require('./_stream_readable');\nvar Writable = require('./_stream_writable');\n\nutil.inherits(Duplex, Readable);\n\nforEach(objectKeys(Writable.prototype), function(method) {\n  if (!Duplex.prototype[method])\n    Duplex.prototype[method] = Writable.prototype[method];\n});\n\nfunction Duplex(options) {\n  if (!(this instanceof Duplex))\n    return new Duplex(options);\n\n  Readable.call(this, options);\n  Writable.call(this, options);\n\n  if (options && options.readable === false)\n    this.readable = false;\n\n  if (options && options.writable === false)\n    this.writable = false;\n\n  this.allowHalfOpen = true;\n  if (options && options.allowHalfOpen === false)\n    this.allowHalfOpen = false;\n\n  this.once('end', onend);\n}\n\n// the no-half-open enforcer\nfunction onend() {\n  // if we allow half-open state, or if the writable side ended,\n  // then we're ok.\n  if (this.allowHalfOpen || this._writableState.ended)\n    return;\n\n  // no more data can be written.\n  // But allow more writes to happen in this tick.\n  process.nextTick(this.end.bind(this));\n}\n\nfunction forEach (xs, f) {\n  for (var i = 0, l = xs.length; i < l; i++) {\n    f(xs[i], i);\n  }\n}\n\n}).call(this,require('_process'))\n},{\"./_stream_readable\":55,\"./_stream_writable\":57,\"_process\":51,\"core-util-is\":58,\"inherits\":48}],54:[function(require,module,exports){\n// Copyright Joyent, Inc. and other Node contributors.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a\n// copy of this software and associated documentation files (the\n// \"Software\"), to deal in the Software without restriction, including\n// without limitation the rights to use, copy, modify, merge, publish,\n// distribute, sublicense, and/or sell copies of the Software, and to permit\n// persons to whom the Software is furnished to do so, subject to the\n// following conditions:\n//\n// The above copyright notice and this permission notice shall be included\n// in all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS\n// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN\n// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,\n// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE\n// USE OR OTHER DEALINGS IN THE SOFTWARE.\n\n// a passthrough stream.\n// basically just the most minimal sort of Transform stream.\n// Every written chunk gets output as-is.\n\nmodule.exports = PassThrough;\n\nvar Transform = require('./_stream_transform');\n\n/*<replacement>*/\nvar util = require('core-util-is');\nutil.inherits = require('inherits');\n/*</replacement>*/\n\nutil.inherits(PassThrough, Transform);\n\nfunction PassThrough(options) {\n  if (!(this instanceof PassThrough))\n    return new PassThrough(options);\n\n  Transform.call(this, options);\n}\n\nPassThrough.prototype._transform = function(chunk, encoding, cb) {\n  cb(null, chunk);\n};\n\n},{\"./_stream_transform\":56,\"core-util-is\":58,\"inherits\":48}],55:[function(require,module,exports){\n(function (process){\n// Copyright Joyent, Inc. and other Node contributors.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a\n// copy of this software and associated documentation files (the\n// \"Software\"), to deal in the Software without restriction, including\n// without limitation the rights to use, copy, modify, merge, publish,\n// distribute, sublicense, and/or sell copies of the Software, and to permit\n// persons to whom the Software is furnished to do so, subject to the\n// following conditions:\n//\n// The above copyright notice and this permission notice shall be included\n// in all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS\n// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN\n// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,\n// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE\n// USE OR OTHER DEALINGS IN THE SOFTWARE.\n\nmodule.exports = Readable;\n\n/*<replacement>*/\nvar isArray = require('isarray');\n/*</replacement>*/\n\n\n/*<replacement>*/\nvar Buffer = require('buffer').Buffer;\n/*</replacement>*/\n\nReadable.ReadableState = ReadableState;\n\nvar EE = require('events').EventEmitter;\n\n/*<replacement>*/\nif (!EE.listenerCount) EE.listenerCount = function(emitter, type) {\n  return emitter.listeners(type).length;\n};\n/*</replacement>*/\n\nvar Stream = require('stream');\n\n/*<replacement>*/\nvar util = require('core-util-is');\nutil.inherits = require('inherits');\n/*</replacement>*/\n\nvar StringDecoder;\n\n\n/*<replacement>*/\nvar debug = require('util');\nif (debug && debug.debuglog) {\n  debug = debug.debuglog('stream');\n} else {\n  debug = function () {};\n}\n/*</replacement>*/\n\n\nutil.inherits(Readable, Stream);\n\nfunction ReadableState(options, stream) {\n  var Duplex = require('./_stream_duplex');\n\n  options = options || {};\n\n  // the point at which it stops calling _read() to fill the buffer\n  // Note: 0 is a valid value, means \"don't call _read preemptively ever\"\n  var hwm = options.highWaterMark;\n  var defaultHwm = options.objectMode ? 16 : 16 * 1024;\n  this.highWaterMark = (hwm || hwm === 0) ? hwm : defaultHwm;\n\n  // cast to ints.\n  this.highWaterMark = ~~this.highWaterMark;\n\n  this.buffer = [];\n  this.length = 0;\n  this.pipes = null;\n  this.pipesCount = 0;\n  this.flowing = null;\n  this.ended = false;\n  this.endEmitted = false;\n  this.reading = false;\n\n  // a flag to be able to tell if the onwrite cb is called immediately,\n  // or on a later tick.  We set this to true at first, because any\n  // actions that shouldn't happen until \"later\" should generally also\n  // not happen before the first write call.\n  this.sync = true;\n\n  // whenever we return null, then we set a flag to say\n  // that we're awaiting a 'readable' event emission.\n  this.needReadable = false;\n  this.emittedReadable = false;\n  this.readableListening = false;\n\n\n  // object stream flag. Used to make read(n) ignore n and to\n  // make all the buffer merging and length checks go away\n  this.objectMode = !!options.objectMode;\n\n  if (stream instanceof Duplex)\n    this.objectMode = this.objectMode || !!options.readableObjectMode;\n\n  // Crypto is kind of old and crusty.  Historically, its default string\n  // encoding is 'binary' so we have to make this configurable.\n  // Everything else in the universe uses 'utf8', though.\n  this.defaultEncoding = options.defaultEncoding || 'utf8';\n\n  // when piping, we only care about 'readable' events that happen\n  // after read()ing all the bytes and not getting any pushback.\n  this.ranOut = false;\n\n  // the number of writers that are awaiting a drain event in .pipe()s\n  this.awaitDrain = 0;\n\n  // if true, a maybeReadMore has been scheduled\n  this.readingMore = false;\n\n  this.decoder = null;\n  this.encoding = null;\n  if (options.encoding) {\n    if (!StringDecoder)\n      StringDecoder = require('string_decoder/').StringDecoder;\n    this.decoder = new StringDecoder(options.encoding);\n    this.encoding = options.encoding;\n  }\n}\n\nfunction Readable(options) {\n  var Duplex = require('./_stream_duplex');\n\n  if (!(this instanceof Readable))\n    return new Readable(options);\n\n  this._readableState = new ReadableState(options, this);\n\n  // legacy\n  this.readable = true;\n\n  Stream.call(this);\n}\n\n// Manually shove something into the read() buffer.\n// This returns true if the highWaterMark has not been hit yet,\n// similar to how Writable.write() returns true if you should\n// write() some more.\nReadable.prototype.push = function(chunk, encoding) {\n  var state = this._readableState;\n\n  if (util.isString(chunk) && !state.objectMode) {\n    encoding = encoding || state.defaultEncoding;\n    if (encoding !== state.encoding) {\n      chunk = new Buffer(chunk, encoding);\n      encoding = '';\n    }\n  }\n\n  return readableAddChunk(this, state, chunk, encoding, false);\n};\n\n// Unshift should *always* be something directly out of read()\nReadable.prototype.unshift = function(chunk) {\n  var state = this._readableState;\n  return readableAddChunk(this, state, chunk, '', true);\n};\n\nfunction readableAddChunk(stream, state, chunk, encoding, addToFront) {\n  var er = chunkInvalid(state, chunk);\n  if (er) {\n    stream.emit('error', er);\n  } else if (util.isNullOrUndefined(chunk)) {\n    state.reading = false;\n    if (!state.ended)\n      onEofChunk(stream, state);\n  } else if (state.objectMode || chunk && chunk.length > 0) {\n    if (state.ended && !addToFront) {\n      var e = new Error('stream.push() after EOF');\n      stream.emit('error', e);\n    } else if (state.endEmitted && addToFront) {\n      var e = new Error('stream.unshift() after end event');\n      stream.emit('error', e);\n    } else {\n      if (state.decoder && !addToFront && !encoding)\n        chunk = state.decoder.write(chunk);\n\n      if (!addToFront)\n        state.reading = false;\n\n      // if we want the data now, just emit it.\n      if (state.flowing && state.length === 0 && !state.sync) {\n        stream.emit('data', chunk);\n        stream.read(0);\n      } else {\n        // update the buffer info.\n        state.length += state.objectMode ? 1 : chunk.length;\n        if (addToFront)\n          state.buffer.unshift(chunk);\n        else\n          state.buffer.push(chunk);\n\n        if (state.needReadable)\n          emitReadable(stream);\n      }\n\n      maybeReadMore(stream, state);\n    }\n  } else if (!addToFront) {\n    state.reading = false;\n  }\n\n  return needMoreData(state);\n}\n\n\n\n// if it's past the high water mark, we can push in some more.\n// Also, if we have no data yet, we can stand some\n// more bytes.  This is to work around cases where hwm=0,\n// such as the repl.  Also, if the push() triggered a\n// readable event, and the user called read(largeNumber) such that\n// needReadable was set, then we ought to push more, so that another\n// 'readable' event will be triggered.\nfunction needMoreData(state) {\n  return !state.ended &&\n         (state.needReadable ||\n          state.length < state.highWaterMark ||\n          state.length === 0);\n}\n\n// backwards compatibility.\nReadable.prototype.setEncoding = function(enc) {\n  if (!StringDecoder)\n    StringDecoder = require('string_decoder/').StringDecoder;\n  this._readableState.decoder = new StringDecoder(enc);\n  this._readableState.encoding = enc;\n  return this;\n};\n\n// Don't raise the hwm > 128MB\nvar MAX_HWM = 0x800000;\nfunction roundUpToNextPowerOf2(n) {\n  if (n >= MAX_HWM) {\n    n = MAX_HWM;\n  } else {\n    // Get the next highest power of 2\n    n--;\n    for (var p = 1; p < 32; p <<= 1) n |= n >> p;\n    n++;\n  }\n  return n;\n}\n\nfunction howMuchToRead(n, state) {\n  if (state.length === 0 && state.ended)\n    return 0;\n\n  if (state.objectMode)\n    return n === 0 ? 0 : 1;\n\n  if (isNaN(n) || util.isNull(n)) {\n    // only flow one buffer at a time\n    if (state.flowing && state.buffer.length)\n      return state.buffer[0].length;\n    else\n      return state.length;\n  }\n\n  if (n <= 0)\n    return 0;\n\n  // If we're asking for more than the target buffer level,\n  // then raise the water mark.  Bump up to the next highest\n  // power of 2, to prevent increasing it excessively in tiny\n  // amounts.\n  if (n > state.highWaterMark)\n    state.highWaterMark = roundUpToNextPowerOf2(n);\n\n  // don't have that much.  return null, unless we've ended.\n  if (n > state.length) {\n    if (!state.ended) {\n      state.needReadable = true;\n      return 0;\n    } else\n      return state.length;\n  }\n\n  return n;\n}\n\n// you can override either this method, or the async _read(n) below.\nReadable.prototype.read = function(n) {\n  debug('read', n);\n  var state = this._readableState;\n  var nOrig = n;\n\n  if (!util.isNumber(n) || n > 0)\n    state.emittedReadable = false;\n\n  // if we're doing read(0) to trigger a readable event, but we\n  // already have a bunch of data in the buffer, then just trigger\n  // the 'readable' event and move on.\n  if (n === 0 &&\n      state.needReadable &&\n      (state.length >= state.highWaterMark || state.ended)) {\n    debug('read: emitReadable', state.length, state.ended);\n    if (state.length === 0 && state.ended)\n      endReadable(this);\n    else\n      emitReadable(this);\n    return null;\n  }\n\n  n = howMuchToRead(n, state);\n\n  // if we've ended, and we're now clear, then finish it up.\n  if (n === 0 && state.ended) {\n    if (state.length === 0)\n      endReadable(this);\n    return null;\n  }\n\n  // All the actual chunk generation logic needs to be\n  // *below* the call to _read.  The reason is that in certain\n  // synthetic stream cases, such as passthrough streams, _read\n  // may be a completely synchronous operation which may change\n  // the state of the read buffer, providing enough data when\n  // before there was *not* enough.\n  //\n  // So, the steps are:\n  // 1. Figure out what the state of things will be after we do\n  // a read from the buffer.\n  //\n  // 2. If that resulting state will trigger a _read, then call _read.\n  // Note that this may be asynchronous, or synchronous.  Yes, it is\n  // deeply ugly to write APIs this way, but that still doesn't mean\n  // that the Readable class should behave improperly, as streams are\n  // designed to be sync/async agnostic.\n  // Take note if the _read call is sync or async (ie, if the read call\n  // has returned yet), so that we know whether or not it's safe to emit\n  // 'readable' etc.\n  //\n  // 3. Actually pull the requested chunks out of the buffer and return.\n\n  // if we need a readable event, then we need to do some reading.\n  var doRead = state.needReadable;\n  debug('need readable', doRead);\n\n  // if we currently have less than the highWaterMark, then also read some\n  if (state.length === 0 || state.length - n < state.highWaterMark) {\n    doRead = true;\n    debug('length less than watermark', doRead);\n  }\n\n  // however, if we've ended, then there's no point, and if we're already\n  // reading, then it's unnecessary.\n  if (state.ended || state.reading) {\n    doRead = false;\n    debug('reading or ended', doRead);\n  }\n\n  if (doRead) {\n    debug('do read');\n    state.reading = true;\n    state.sync = true;\n    // if the length is currently zero, then we *need* a readable event.\n    if (state.length === 0)\n      state.needReadable = true;\n    // call internal read method\n    this._read(state.highWaterMark);\n    state.sync = false;\n  }\n\n  // If _read pushed data synchronously, then `reading` will be false,\n  // and we need to re-evaluate how much data we can return to the user.\n  if (doRead && !state.reading)\n    n = howMuchToRead(nOrig, state);\n\n  var ret;\n  if (n > 0)\n    ret = fromList(n, state);\n  else\n    ret = null;\n\n  if (util.isNull(ret)) {\n    state.needReadable = true;\n    n = 0;\n  }\n\n  state.length -= n;\n\n  // If we have nothing in the buffer, then we want to know\n  // as soon as we *do* get something into the buffer.\n  if (state.length === 0 && !state.ended)\n    state.needReadable = true;\n\n  // If we tried to read() past the EOF, then emit end on the next tick.\n  if (nOrig !== n && state.ended && state.length === 0)\n    endReadable(this);\n\n  if (!util.isNull(ret))\n    this.emit('data', ret);\n\n  return ret;\n};\n\nfunction chunkInvalid(state, chunk) {\n  var er = null;\n  if (!util.isBuffer(chunk) &&\n      !util.isString(chunk) &&\n      !util.isNullOrUndefined(chunk) &&\n      !state.objectMode) {\n    er = new TypeError('Invalid non-string/buffer chunk');\n  }\n  return er;\n}\n\n\nfunction onEofChunk(stream, state) {\n  if (state.decoder && !state.ended) {\n    var chunk = state.decoder.end();\n    if (chunk && chunk.length) {\n      state.buffer.push(chunk);\n      state.length += state.objectMode ? 1 : chunk.length;\n    }\n  }\n  state.ended = true;\n\n  // emit 'readable' now to make sure it gets picked up.\n  emitReadable(stream);\n}\n\n// Don't emit readable right away in sync mode, because this can trigger\n// another read() call => stack overflow.  This way, it might trigger\n// a nextTick recursion warning, but that's not so bad.\nfunction emitReadable(stream) {\n  var state = stream._readableState;\n  state.needReadable = false;\n  if (!state.emittedReadable) {\n    debug('emitReadable', state.flowing);\n    state.emittedReadable = true;\n    if (state.sync)\n      process.nextTick(function() {\n        emitReadable_(stream);\n      });\n    else\n      emitReadable_(stream);\n  }\n}\n\nfunction emitReadable_(stream) {\n  debug('emit readable');\n  stream.emit('readable');\n  flow(stream);\n}\n\n\n// at this point, the user has presumably seen the 'readable' event,\n// and called read() to consume some data.  that may have triggered\n// in turn another _read(n) call, in which case reading = true if\n// it's in progress.\n// However, if we're not ended, or reading, and the length < hwm,\n// then go ahead and try to read some more preemptively.\nfunction maybeReadMore(stream, state) {\n  if (!state.readingMore) {\n    state.readingMore = true;\n    process.nextTick(function() {\n      maybeReadMore_(stream, state);\n    });\n  }\n}\n\nfunction maybeReadMore_(stream, state) {\n  var len = state.length;\n  while (!state.reading && !state.flowing && !state.ended &&\n         state.length < state.highWaterMark) {\n    debug('maybeReadMore read 0');\n    stream.read(0);\n    if (len === state.length)\n      // didn't get any data, stop spinning.\n      break;\n    else\n      len = state.length;\n  }\n  state.readingMore = false;\n}\n\n// abstract method.  to be overridden in specific implementation classes.\n// call cb(er, data) where data is <= n in length.\n// for virtual (non-string, non-buffer) streams, \"length\" is somewhat\n// arbitrary, and perhaps not very meaningful.\nReadable.prototype._read = function(n) {\n  this.emit('error', new Error('not implemented'));\n};\n\nReadable.prototype.pipe = function(dest, pipeOpts) {\n  var src = this;\n  var state = this._readableState;\n\n  switch (state.pipesCount) {\n    case 0:\n      state.pipes = dest;\n      break;\n    case 1:\n      state.pipes = [state.pipes, dest];\n      break;\n    default:\n      state.pipes.push(dest);\n      break;\n  }\n  state.pipesCount += 1;\n  debug('pipe count=%d opts=%j', state.pipesCount, pipeOpts);\n\n  var doEnd = (!pipeOpts || pipeOpts.end !== false) &&\n              dest !== process.stdout &&\n              dest !== process.stderr;\n\n  var endFn = doEnd ? onend : cleanup;\n  if (state.endEmitted)\n    process.nextTick(endFn);\n  else\n    src.once('end', endFn);\n\n  dest.on('unpipe', onunpipe);\n  function onunpipe(readable) {\n    debug('onunpipe');\n    if (readable === src) {\n      cleanup();\n    }\n  }\n\n  function onend() {\n    debug('onend');\n    dest.end();\n  }\n\n  // when the dest drains, it reduces the awaitDrain counter\n  // on the source.  This would be more elegant with a .once()\n  // handler in flow(), but adding and removing repeatedly is\n  // too slow.\n  var ondrain = pipeOnDrain(src);\n  dest.on('drain', ondrain);\n\n  function cleanup() {\n    debug('cleanup');\n    // cleanup event handlers once the pipe is broken\n    dest.removeListener('close', onclose);\n    dest.removeListener('finish', onfinish);\n    dest.removeListener('drain', ondrain);\n    dest.removeListener('error', onerror);\n    dest.removeListener('unpipe', onunpipe);\n    src.removeListener('end', onend);\n    src.removeListener('end', cleanup);\n    src.removeListener('data', ondata);\n\n    // if the reader is waiting for a drain event from this\n    // specific writer, then it would cause it to never start\n    // flowing again.\n    // So, if this is awaiting a drain, then we just call it now.\n    // If we don't know, then assume that we are waiting for one.\n    if (state.awaitDrain &&\n        (!dest._writableState || dest._writableState.needDrain))\n      ondrain();\n  }\n\n  src.on('data', ondata);\n  function ondata(chunk) {\n    debug('ondata');\n    var ret = dest.write(chunk);\n    if (false === ret) {\n      debug('false write response, pause',\n            src._readableState.awaitDrain);\n      src._readableState.awaitDrain++;\n      src.pause();\n    }\n  }\n\n  // if the dest has an error, then stop piping into it.\n  // however, don't suppress the throwing behavior for this.\n  function onerror(er) {\n    debug('onerror', er);\n    unpipe();\n    dest.removeListener('error', onerror);\n    if (EE.listenerCount(dest, 'error') === 0)\n      dest.emit('error', er);\n  }\n  // This is a brutally ugly hack to make sure that our error handler\n  // is attached before any userland ones.  NEVER DO THIS.\n  if (!dest._events || !dest._events.error)\n    dest.on('error', onerror);\n  else if (isArray(dest._events.error))\n    dest._events.error.unshift(onerror);\n  else\n    dest._events.error = [onerror, dest._events.error];\n\n\n\n  // Both close and finish should trigger unpipe, but only once.\n  function onclose() {\n    dest.removeListener('finish', onfinish);\n    unpipe();\n  }\n  dest.once('close', onclose);\n  function onfinish() {\n    debug('onfinish');\n    dest.removeListener('close', onclose);\n    unpipe();\n  }\n  dest.once('finish', onfinish);\n\n  function unpipe() {\n    debug('unpipe');\n    src.unpipe(dest);\n  }\n\n  // tell the dest that it's being piped to\n  dest.emit('pipe', src);\n\n  // start the flow if it hasn't been started already.\n  if (!state.flowing) {\n    debug('pipe resume');\n    src.resume();\n  }\n\n  return dest;\n};\n\nfunction pipeOnDrain(src) {\n  return function() {\n    var state = src._readableState;\n    debug('pipeOnDrain', state.awaitDrain);\n    if (state.awaitDrain)\n      state.awaitDrain--;\n    if (state.awaitDrain === 0 && EE.listenerCount(src, 'data')) {\n      state.flowing = true;\n      flow(src);\n    }\n  };\n}\n\n\nReadable.prototype.unpipe = function(dest) {\n  var state = this._readableState;\n\n  // if we're not piping anywhere, then do nothing.\n  if (state.pipesCount === 0)\n    return this;\n\n  // just one destination.  most common case.\n  if (state.pipesCount === 1) {\n    // passed in one, but it's not the right one.\n    if (dest && dest !== state.pipes)\n      return this;\n\n    if (!dest)\n      dest = state.pipes;\n\n    // got a match.\n    state.pipes = null;\n    state.pipesCount = 0;\n    state.flowing = false;\n    if (dest)\n      dest.emit('unpipe', this);\n    return this;\n  }\n\n  // slow case. multiple pipe destinations.\n\n  if (!dest) {\n    // remove all.\n    var dests = state.pipes;\n    var len = state.pipesCount;\n    state.pipes = null;\n    state.pipesCount = 0;\n    state.flowing = false;\n\n    for (var i = 0; i < len; i++)\n      dests[i].emit('unpipe', this);\n    return this;\n  }\n\n  // try to find the right one.\n  var i = indexOf(state.pipes, dest);\n  if (i === -1)\n    return this;\n\n  state.pipes.splice(i, 1);\n  state.pipesCount -= 1;\n  if (state.pipesCount === 1)\n    state.pipes = state.pipes[0];\n\n  dest.emit('unpipe', this);\n\n  return this;\n};\n\n// set up data events if they are asked for\n// Ensure readable listeners eventually get something\nReadable.prototype.on = function(ev, fn) {\n  var res = Stream.prototype.on.call(this, ev, fn);\n\n  // If listening to data, and it has not explicitly been paused,\n  // then call resume to start the flow of data on the next tick.\n  if (ev === 'data' && false !== this._readableState.flowing) {\n    this.resume();\n  }\n\n  if (ev === 'readable' && this.readable) {\n    var state = this._readableState;\n    if (!state.readableListening) {\n      state.readableListening = true;\n      state.emittedReadable = false;\n      state.needReadable = true;\n      if (!state.reading) {\n        var self = this;\n        process.nextTick(function() {\n          debug('readable nexttick read 0');\n          self.read(0);\n        });\n      } else if (state.length) {\n        emitReadable(this, state);\n      }\n    }\n  }\n\n  return res;\n};\nReadable.prototype.addListener = Readable.prototype.on;\n\n// pause() and resume() are remnants of the legacy readable stream API\n// If the user uses them, then switch into old mode.\nReadable.prototype.resume = function() {\n  var state = this._readableState;\n  if (!state.flowing) {\n    debug('resume');\n    state.flowing = true;\n    if (!state.reading) {\n      debug('resume read 0');\n      this.read(0);\n    }\n    resume(this, state);\n  }\n  return this;\n};\n\nfunction resume(stream, state) {\n  if (!state.resumeScheduled) {\n    state.resumeScheduled = true;\n    process.nextTick(function() {\n      resume_(stream, state);\n    });\n  }\n}\n\nfunction resume_(stream, state) {\n  state.resumeScheduled = false;\n  stream.emit('resume');\n  flow(stream);\n  if (state.flowing && !state.reading)\n    stream.read(0);\n}\n\nReadable.prototype.pause = function() {\n  debug('call pause flowing=%j', this._readableState.flowing);\n  if (false !== this._readableState.flowing) {\n    debug('pause');\n    this._readableState.flowing = false;\n    this.emit('pause');\n  }\n  return this;\n};\n\nfunction flow(stream) {\n  var state = stream._readableState;\n  debug('flow', state.flowing);\n  if (state.flowing) {\n    do {\n      var chunk = stream.read();\n    } while (null !== chunk && state.flowing);\n  }\n}\n\n// wrap an old-style stream as the async data source.\n// This is *not* part of the readable stream interface.\n// It is an ugly unfortunate mess of history.\nReadable.prototype.wrap = function(stream) {\n  var state = this._readableState;\n  var paused = false;\n\n  var self = this;\n  stream.on('end', function() {\n    debug('wrapped end');\n    if (state.decoder && !state.ended) {\n      var chunk = state.decoder.end();\n      if (chunk && chunk.length)\n        self.push(chunk);\n    }\n\n    self.push(null);\n  });\n\n  stream.on('data', function(chunk) {\n    debug('wrapped data');\n    if (state.decoder)\n      chunk = state.decoder.write(chunk);\n    if (!chunk || !state.objectMode && !chunk.length)\n      return;\n\n    var ret = self.push(chunk);\n    if (!ret) {\n      paused = true;\n      stream.pause();\n    }\n  });\n\n  // proxy all the other methods.\n  // important when wrapping filters and duplexes.\n  for (var i in stream) {\n    if (util.isFunction(stream[i]) && util.isUndefined(this[i])) {\n      this[i] = function(method) { return function() {\n        return stream[method].apply(stream, arguments);\n      }}(i);\n    }\n  }\n\n  // proxy certain important events.\n  var events = ['error', 'close', 'destroy', 'pause', 'resume'];\n  forEach(events, function(ev) {\n    stream.on(ev, self.emit.bind(self, ev));\n  });\n\n  // when we try to consume some more bytes, simply unpause the\n  // underlying stream.\n  self._read = function(n) {\n    debug('wrapped _read', n);\n    if (paused) {\n      paused = false;\n      stream.resume();\n    }\n  };\n\n  return self;\n};\n\n\n\n// exposed for testing purposes only.\nReadable._fromList = fromList;\n\n// Pluck off n bytes from an array of buffers.\n// Length is the combined lengths of all the buffers in the list.\nfunction fromList(n, state) {\n  var list = state.buffer;\n  var length = state.length;\n  var stringMode = !!state.decoder;\n  var objectMode = !!state.objectMode;\n  var ret;\n\n  // nothing in the list, definitely empty.\n  if (list.length === 0)\n    return null;\n\n  if (length === 0)\n    ret = null;\n  else if (objectMode)\n    ret = list.shift();\n  else if (!n || n >= length) {\n    // read it all, truncate the array.\n    if (stringMode)\n      ret = list.join('');\n    else\n      ret = Buffer.concat(list, length);\n    list.length = 0;\n  } else {\n    // read just some of it.\n    if (n < list[0].length) {\n      // just take a part of the first list item.\n      // slice is the same for buffers and strings.\n      var buf = list[0];\n      ret = buf.slice(0, n);\n      list[0] = buf.slice(n);\n    } else if (n === list[0].length) {\n      // first list is a perfect match\n      ret = list.shift();\n    } else {\n      // complex case.\n      // we have enough to cover it, but it spans past the first buffer.\n      if (stringMode)\n        ret = '';\n      else\n        ret = new Buffer(n);\n\n      var c = 0;\n      for (var i = 0, l = list.length; i < l && c < n; i++) {\n        var buf = list[0];\n        var cpy = Math.min(n - c, buf.length);\n\n        if (stringMode)\n          ret += buf.slice(0, cpy);\n        else\n          buf.copy(ret, c, 0, cpy);\n\n        if (cpy < buf.length)\n          list[0] = buf.slice(cpy);\n        else\n          list.shift();\n\n        c += cpy;\n      }\n    }\n  }\n\n  return ret;\n}\n\nfunction endReadable(stream) {\n  var state = stream._readableState;\n\n  // If we get here before consuming all the bytes, then that is a\n  // bug in node.  Should never happen.\n  if (state.length > 0)\n    throw new Error('endReadable called on non-empty stream');\n\n  if (!state.endEmitted) {\n    state.ended = true;\n    process.nextTick(function() {\n      // Check that we didn't get one last unshift.\n      if (!state.endEmitted && state.length === 0) {\n        state.endEmitted = true;\n        stream.readable = false;\n        stream.emit('end');\n      }\n    });\n  }\n}\n\nfunction forEach (xs, f) {\n  for (var i = 0, l = xs.length; i < l; i++) {\n    f(xs[i], i);\n  }\n}\n\nfunction indexOf (xs, x) {\n  for (var i = 0, l = xs.length; i < l; i++) {\n    if (xs[i] === x) return i;\n  }\n  return -1;\n}\n\n}).call(this,require('_process'))\n},{\"./_stream_duplex\":53,\"_process\":51,\"buffer\":43,\"core-util-is\":58,\"events\":47,\"inherits\":48,\"isarray\":49,\"stream\":63,\"string_decoder/\":64,\"util\":42}],56:[function(require,module,exports){\n// Copyright Joyent, Inc. and other Node contributors.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a\n// copy of this software and associated documentation files (the\n// \"Software\"), to deal in the Software without restriction, including\n// without limitation the rights to use, copy, modify, merge, publish,\n// distribute, sublicense, and/or sell copies of the Software, and to permit\n// persons to whom the Software is furnished to do so, subject to the\n// following conditions:\n//\n// The above copyright notice and this permission notice shall be included\n// in all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS\n// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN\n// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,\n// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE\n// USE OR OTHER DEALINGS IN THE SOFTWARE.\n\n\n// a transform stream is a readable/writable stream where you do\n// something with the data.  Sometimes it's called a \"filter\",\n// but that's not a great name for it, since that implies a thing where\n// some bits pass through, and others are simply ignored.  (That would\n// be a valid example of a transform, of course.)\n//\n// While the output is causally related to the input, it's not a\n// necessarily symmetric or synchronous transformation.  For example,\n// a zlib stream might take multiple plain-text writes(), and then\n// emit a single compressed chunk some time in the future.\n//\n// Here's how this works:\n//\n// The Transform stream has all the aspects of the readable and writable\n// stream classes.  When you write(chunk), that calls _write(chunk,cb)\n// internally, and returns false if there's a lot of pending writes\n// buffered up.  When you call read(), that calls _read(n) until\n// there's enough pending readable data buffered up.\n//\n// In a transform stream, the written data is placed in a buffer.  When\n// _read(n) is called, it transforms the queued up data, calling the\n// buffered _write cb's as it consumes chunks.  If consuming a single\n// written chunk would result in multiple output chunks, then the first\n// outputted bit calls the readcb, and subsequent chunks just go into\n// the read buffer, and will cause it to emit 'readable' if necessary.\n//\n// This way, back-pressure is actually determined by the reading side,\n// since _read has to be called to start processing a new chunk.  However,\n// a pathological inflate type of transform can cause excessive buffering\n// here.  For example, imagine a stream where every byte of input is\n// interpreted as an integer from 0-255, and then results in that many\n// bytes of output.  Writing the 4 bytes {ff,ff,ff,ff} would result in\n// 1kb of data being output.  In this case, you could write a very small\n// amount of input, and end up with a very large amount of output.  In\n// such a pathological inflating mechanism, there'd be no way to tell\n// the system to stop doing the transform.  A single 4MB write could\n// cause the system to run out of memory.\n//\n// However, even in such a pathological case, only a single written chunk\n// would be consumed, and then the rest would wait (un-transformed) until\n// the results of the previous transformed chunk were consumed.\n\nmodule.exports = Transform;\n\nvar Duplex = require('./_stream_duplex');\n\n/*<replacement>*/\nvar util = require('core-util-is');\nutil.inherits = require('inherits');\n/*</replacement>*/\n\nutil.inherits(Transform, Duplex);\n\n\nfunction TransformState(options, stream) {\n  this.afterTransform = function(er, data) {\n    return afterTransform(stream, er, data);\n  };\n\n  this.needTransform = false;\n  this.transforming = false;\n  this.writecb = null;\n  this.writechunk = null;\n}\n\nfunction afterTransform(stream, er, data) {\n  var ts = stream._transformState;\n  ts.transforming = false;\n\n  var cb = ts.writecb;\n\n  if (!cb)\n    return stream.emit('error', new Error('no writecb in Transform class'));\n\n  ts.writechunk = null;\n  ts.writecb = null;\n\n  if (!util.isNullOrUndefined(data))\n    stream.push(data);\n\n  if (cb)\n    cb(er);\n\n  var rs = stream._readableState;\n  rs.reading = false;\n  if (rs.needReadable || rs.length < rs.highWaterMark) {\n    stream._read(rs.highWaterMark);\n  }\n}\n\n\nfunction Transform(options) {\n  if (!(this instanceof Transform))\n    return new Transform(options);\n\n  Duplex.call(this, options);\n\n  this._transformState = new TransformState(options, this);\n\n  // when the writable side finishes, then flush out anything remaining.\n  var stream = this;\n\n  // start out asking for a readable event once data is transformed.\n  this._readableState.needReadable = true;\n\n  // we have implemented the _read method, and done the other things\n  // that Readable wants before the first _read call, so unset the\n  // sync guard flag.\n  this._readableState.sync = false;\n\n  this.once('prefinish', function() {\n    if (util.isFunction(this._flush))\n      this._flush(function(er) {\n        done(stream, er);\n      });\n    else\n      done(stream);\n  });\n}\n\nTransform.prototype.push = function(chunk, encoding) {\n  this._transformState.needTransform = false;\n  return Duplex.prototype.push.call(this, chunk, encoding);\n};\n\n// This is the part where you do stuff!\n// override this function in implementation classes.\n// 'chunk' is an input chunk.\n//\n// Call `push(newChunk)` to pass along transformed output\n// to the readable side.  You may call 'push' zero or more times.\n//\n// Call `cb(err)` when you are done with this chunk.  If you pass\n// an error, then that'll put the hurt on the whole operation.  If you\n// never call cb(), then you'll never get another chunk.\nTransform.prototype._transform = function(chunk, encoding, cb) {\n  throw new Error('not implemented');\n};\n\nTransform.prototype._write = function(chunk, encoding, cb) {\n  var ts = this._transformState;\n  ts.writecb = cb;\n  ts.writechunk = chunk;\n  ts.writeencoding = encoding;\n  if (!ts.transforming) {\n    var rs = this._readableState;\n    if (ts.needTransform ||\n        rs.needReadable ||\n        rs.length < rs.highWaterMark)\n      this._read(rs.highWaterMark);\n  }\n};\n\n// Doesn't matter what the args are here.\n// _transform does all the work.\n// That we got here means that the readable side wants more data.\nTransform.prototype._read = function(n) {\n  var ts = this._transformState;\n\n  if (!util.isNull(ts.writechunk) && ts.writecb && !ts.transforming) {\n    ts.transforming = true;\n    this._transform(ts.writechunk, ts.writeencoding, ts.afterTransform);\n  } else {\n    // mark that we need a transform, so that any data that comes in\n    // will get processed, now that we've asked for it.\n    ts.needTransform = true;\n  }\n};\n\n\nfunction done(stream, er) {\n  if (er)\n    return stream.emit('error', er);\n\n  // if there's nothing in the write buffer, then that means\n  // that nothing more will ever be provided\n  var ws = stream._writableState;\n  var ts = stream._transformState;\n\n  if (ws.length)\n    throw new Error('calling transform done when ws.length != 0');\n\n  if (ts.transforming)\n    throw new Error('calling transform done when still transforming');\n\n  return stream.push(null);\n}\n\n},{\"./_stream_duplex\":53,\"core-util-is\":58,\"inherits\":48}],57:[function(require,module,exports){\n(function (process){\n// Copyright Joyent, Inc. and other Node contributors.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a\n// copy of this software and associated documentation files (the\n// \"Software\"), to deal in the Software without restriction, including\n// without limitation the rights to use, copy, modify, merge, publish,\n// distribute, sublicense, and/or sell copies of the Software, and to permit\n// persons to whom the Software is furnished to do so, subject to the\n// following conditions:\n//\n// The above copyright notice and this permission notice shall be included\n// in all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS\n// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN\n// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,\n// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE\n// USE OR OTHER DEALINGS IN THE SOFTWARE.\n\n// A bit simpler than readable streams.\n// Implement an async ._write(chunk, cb), and it'll handle all\n// the drain event emission and buffering.\n\nmodule.exports = Writable;\n\n/*<replacement>*/\nvar Buffer = require('buffer').Buffer;\n/*</replacement>*/\n\nWritable.WritableState = WritableState;\n\n\n/*<replacement>*/\nvar util = require('core-util-is');\nutil.inherits = require('inherits');\n/*</replacement>*/\n\nvar Stream = require('stream');\n\nutil.inherits(Writable, Stream);\n\nfunction WriteReq(chunk, encoding, cb) {\n  this.chunk = chunk;\n  this.encoding = encoding;\n  this.callback = cb;\n}\n\nfunction WritableState(options, stream) {\n  var Duplex = require('./_stream_duplex');\n\n  options = options || {};\n\n  // the point at which write() starts returning false\n  // Note: 0 is a valid value, means that we always return false if\n  // the entire buffer is not flushed immediately on write()\n  var hwm = options.highWaterMark;\n  var defaultHwm = options.objectMode ? 16 : 16 * 1024;\n  this.highWaterMark = (hwm || hwm === 0) ? hwm : defaultHwm;\n\n  // object stream flag to indicate whether or not this stream\n  // contains buffers or objects.\n  this.objectMode = !!options.objectMode;\n\n  if (stream instanceof Duplex)\n    this.objectMode = this.objectMode || !!options.writableObjectMode;\n\n  // cast to ints.\n  this.highWaterMark = ~~this.highWaterMark;\n\n  this.needDrain = false;\n  // at the start of calling end()\n  this.ending = false;\n  // when end() has been called, and returned\n  this.ended = false;\n  // when 'finish' is emitted\n  this.finished = false;\n\n  // should we decode strings into buffers before passing to _write?\n  // this is here so that some node-core streams can optimize string\n  // handling at a lower level.\n  var noDecode = options.decodeStrings === false;\n  this.decodeStrings = !noDecode;\n\n  // Crypto is kind of old and crusty.  Historically, its default string\n  // encoding is 'binary' so we have to make this configurable.\n  // Everything else in the universe uses 'utf8', though.\n  this.defaultEncoding = options.defaultEncoding || 'utf8';\n\n  // not an actual buffer we keep track of, but a measurement\n  // of how much we're waiting to get pushed to some underlying\n  // socket or file.\n  this.length = 0;\n\n  // a flag to see when we're in the middle of a write.\n  this.writing = false;\n\n  // when true all writes will be buffered until .uncork() call\n  this.corked = 0;\n\n  // a flag to be able to tell if the onwrite cb is called immediately,\n  // or on a later tick.  We set this to true at first, because any\n  // actions that shouldn't happen until \"later\" should generally also\n  // not happen before the first write call.\n  this.sync = true;\n\n  // a flag to know if we're processing previously buffered items, which\n  // may call the _write() callback in the same tick, so that we don't\n  // end up in an overlapped onwrite situation.\n  this.bufferProcessing = false;\n\n  // the callback that's passed to _write(chunk,cb)\n  this.onwrite = function(er) {\n    onwrite(stream, er);\n  };\n\n  // the callback that the user supplies to write(chunk,encoding,cb)\n  this.writecb = null;\n\n  // the amount that is being written when _write is called.\n  this.writelen = 0;\n\n  this.buffer = [];\n\n  // number of pending user-supplied write callbacks\n  // this must be 0 before 'finish' can be emitted\n  this.pendingcb = 0;\n\n  // emit prefinish if the only thing we're waiting for is _write cbs\n  // This is relevant for synchronous Transform streams\n  this.prefinished = false;\n\n  // True if the error was already emitted and should not be thrown again\n  this.errorEmitted = false;\n}\n\nfunction Writable(options) {\n  var Duplex = require('./_stream_duplex');\n\n  // Writable ctor is applied to Duplexes, though they're not\n  // instanceof Writable, they're instanceof Readable.\n  if (!(this instanceof Writable) && !(this instanceof Duplex))\n    return new Writable(options);\n\n  this._writableState = new WritableState(options, this);\n\n  // legacy.\n  this.writable = true;\n\n  Stream.call(this);\n}\n\n// Otherwise people can pipe Writable streams, which is just wrong.\nWritable.prototype.pipe = function() {\n  this.emit('error', new Error('Cannot pipe. Not readable.'));\n};\n\n\nfunction writeAfterEnd(stream, state, cb) {\n  var er = new Error('write after end');\n  // TODO: defer error events consistently everywhere, not just the cb\n  stream.emit('error', er);\n  process.nextTick(function() {\n    cb(er);\n  });\n}\n\n// If we get something that is not a buffer, string, null, or undefined,\n// and we're not in objectMode, then that's an error.\n// Otherwise stream chunks are all considered to be of length=1, and the\n// watermarks determine how many objects to keep in the buffer, rather than\n// how many bytes or characters.\nfunction validChunk(stream, state, chunk, cb) {\n  var valid = true;\n  if (!util.isBuffer(chunk) &&\n      !util.isString(chunk) &&\n      !util.isNullOrUndefined(chunk) &&\n      !state.objectMode) {\n    var er = new TypeError('Invalid non-string/buffer chunk');\n    stream.emit('error', er);\n    process.nextTick(function() {\n      cb(er);\n    });\n    valid = false;\n  }\n  return valid;\n}\n\nWritable.prototype.write = function(chunk, encoding, cb) {\n  var state = this._writableState;\n  var ret = false;\n\n  if (util.isFunction(encoding)) {\n    cb = encoding;\n    encoding = null;\n  }\n\n  if (util.isBuffer(chunk))\n    encoding = 'buffer';\n  else if (!encoding)\n    encoding = state.defaultEncoding;\n\n  if (!util.isFunction(cb))\n    cb = function() {};\n\n  if (state.ended)\n    writeAfterEnd(this, state, cb);\n  else if (validChunk(this, state, chunk, cb)) {\n    state.pendingcb++;\n    ret = writeOrBuffer(this, state, chunk, encoding, cb);\n  }\n\n  return ret;\n};\n\nWritable.prototype.cork = function() {\n  var state = this._writableState;\n\n  state.corked++;\n};\n\nWritable.prototype.uncork = function() {\n  var state = this._writableState;\n\n  if (state.corked) {\n    state.corked--;\n\n    if (!state.writing &&\n        !state.corked &&\n        !state.finished &&\n        !state.bufferProcessing &&\n        state.buffer.length)\n      clearBuffer(this, state);\n  }\n};\n\nfunction decodeChunk(state, chunk, encoding) {\n  if (!state.objectMode &&\n      state.decodeStrings !== false &&\n      util.isString(chunk)) {\n    chunk = new Buffer(chunk, encoding);\n  }\n  return chunk;\n}\n\n// if we're already writing something, then just put this\n// in the queue, and wait our turn.  Otherwise, call _write\n// If we return false, then we need a drain event, so set that flag.\nfunction writeOrBuffer(stream, state, chunk, encoding, cb) {\n  chunk = decodeChunk(state, chunk, encoding);\n  if (util.isBuffer(chunk))\n    encoding = 'buffer';\n  var len = state.objectMode ? 1 : chunk.length;\n\n  state.length += len;\n\n  var ret = state.length < state.highWaterMark;\n  // we must ensure that previous needDrain will not be reset to false.\n  if (!ret)\n    state.needDrain = true;\n\n  if (state.writing || state.corked)\n    state.buffer.push(new WriteReq(chunk, encoding, cb));\n  else\n    doWrite(stream, state, false, len, chunk, encoding, cb);\n\n  return ret;\n}\n\nfunction doWrite(stream, state, writev, len, chunk, encoding, cb) {\n  state.writelen = len;\n  state.writecb = cb;\n  state.writing = true;\n  state.sync = true;\n  if (writev)\n    stream._writev(chunk, state.onwrite);\n  else\n    stream._write(chunk, encoding, state.onwrite);\n  state.sync = false;\n}\n\nfunction onwriteError(stream, state, sync, er, cb) {\n  if (sync)\n    process.nextTick(function() {\n      state.pendingcb--;\n      cb(er);\n    });\n  else {\n    state.pendingcb--;\n    cb(er);\n  }\n\n  stream._writableState.errorEmitted = true;\n  stream.emit('error', er);\n}\n\nfunction onwriteStateUpdate(state) {\n  state.writing = false;\n  state.writecb = null;\n  state.length -= state.writelen;\n  state.writelen = 0;\n}\n\nfunction onwrite(stream, er) {\n  var state = stream._writableState;\n  var sync = state.sync;\n  var cb = state.writecb;\n\n  onwriteStateUpdate(state);\n\n  if (er)\n    onwriteError(stream, state, sync, er, cb);\n  else {\n    // Check if we're actually ready to finish, but don't emit yet\n    var finished = needFinish(stream, state);\n\n    if (!finished &&\n        !state.corked &&\n        !state.bufferProcessing &&\n        state.buffer.length) {\n      clearBuffer(stream, state);\n    }\n\n    if (sync) {\n      process.nextTick(function() {\n        afterWrite(stream, state, finished, cb);\n      });\n    } else {\n      afterWrite(stream, state, finished, cb);\n    }\n  }\n}\n\nfunction afterWrite(stream, state, finished, cb) {\n  if (!finished)\n    onwriteDrain(stream, state);\n  state.pendingcb--;\n  cb();\n  finishMaybe(stream, state);\n}\n\n// Must force callback to be called on nextTick, so that we don't\n// emit 'drain' before the write() consumer gets the 'false' return\n// value, and has a chance to attach a 'drain' listener.\nfunction onwriteDrain(stream, state) {\n  if (state.length === 0 && state.needDrain) {\n    state.needDrain = false;\n    stream.emit('drain');\n  }\n}\n\n\n// if there's something in the buffer waiting, then process it\nfunction clearBuffer(stream, state) {\n  state.bufferProcessing = true;\n\n  if (stream._writev && state.buffer.length > 1) {\n    // Fast case, write everything using _writev()\n    var cbs = [];\n    for (var c = 0; c < state.buffer.length; c++)\n      cbs.push(state.buffer[c].callback);\n\n    // count the one we are adding, as well.\n    // TODO(isaacs) clean this up\n    state.pendingcb++;\n    doWrite(stream, state, true, state.length, state.buffer, '', function(err) {\n      for (var i = 0; i < cbs.length; i++) {\n        state.pendingcb--;\n        cbs[i](err);\n      }\n    });\n\n    // Clear buffer\n    state.buffer = [];\n  } else {\n    // Slow case, write chunks one-by-one\n    for (var c = 0; c < state.buffer.length; c++) {\n      var entry = state.buffer[c];\n      var chunk = entry.chunk;\n      var encoding = entry.encoding;\n      var cb = entry.callback;\n      var len = state.objectMode ? 1 : chunk.length;\n\n      doWrite(stream, state, false, len, chunk, encoding, cb);\n\n      // if we didn't call the onwrite immediately, then\n      // it means that we need to wait until it does.\n      // also, that means that the chunk and cb are currently\n      // being processed, so move the buffer counter past them.\n      if (state.writing) {\n        c++;\n        break;\n      }\n    }\n\n    if (c < state.buffer.length)\n      state.buffer = state.buffer.slice(c);\n    else\n      state.buffer.length = 0;\n  }\n\n  state.bufferProcessing = false;\n}\n\nWritable.prototype._write = function(chunk, encoding, cb) {\n  cb(new Error('not implemented'));\n\n};\n\nWritable.prototype._writev = null;\n\nWritable.prototype.end = function(chunk, encoding, cb) {\n  var state = this._writableState;\n\n  if (util.isFunction(chunk)) {\n    cb = chunk;\n    chunk = null;\n    encoding = null;\n  } else if (util.isFunction(encoding)) {\n    cb = encoding;\n    encoding = null;\n  }\n\n  if (!util.isNullOrUndefined(chunk))\n    this.write(chunk, encoding);\n\n  // .end() fully uncorks\n  if (state.corked) {\n    state.corked = 1;\n    this.uncork();\n  }\n\n  // ignore unnecessary end() calls.\n  if (!state.ending && !state.finished)\n    endWritable(this, state, cb);\n};\n\n\nfunction needFinish(stream, state) {\n  return (state.ending &&\n          state.length === 0 &&\n          !state.finished &&\n          !state.writing);\n}\n\nfunction prefinish(stream, state) {\n  if (!state.prefinished) {\n    state.prefinished = true;\n    stream.emit('prefinish');\n  }\n}\n\nfunction finishMaybe(stream, state) {\n  var need = needFinish(stream, state);\n  if (need) {\n    if (state.pendingcb === 0) {\n      prefinish(stream, state);\n      state.finished = true;\n      stream.emit('finish');\n    } else\n      prefinish(stream, state);\n  }\n  return need;\n}\n\nfunction endWritable(stream, state, cb) {\n  state.ending = true;\n  finishMaybe(stream, state);\n  if (cb) {\n    if (state.finished)\n      process.nextTick(cb);\n    else\n      stream.once('finish', cb);\n  }\n  state.ended = true;\n}\n\n}).call(this,require('_process'))\n},{\"./_stream_duplex\":53,\"_process\":51,\"buffer\":43,\"core-util-is\":58,\"inherits\":48,\"stream\":63}],58:[function(require,module,exports){\n(function (Buffer){\n// Copyright Joyent, Inc. and other Node contributors.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a\n// copy of this software and associated documentation files (the\n// \"Software\"), to deal in the Software without restriction, including\n// without limitation the rights to use, copy, modify, merge, publish,\n// distribute, sublicense, and/or sell copies of the Software, and to permit\n// persons to whom the Software is furnished to do so, subject to the\n// following conditions:\n//\n// The above copyright notice and this permission notice shall be included\n// in all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS\n// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN\n// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,\n// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE\n// USE OR OTHER DEALINGS IN THE SOFTWARE.\n\n// NOTE: These type checking functions intentionally don't use `instanceof`\n// because it is fragile and can be easily faked with `Object.create()`.\nfunction isArray(ar) {\n  return Array.isArray(ar);\n}\nexports.isArray = isArray;\n\nfunction isBoolean(arg) {\n  return typeof arg === 'boolean';\n}\nexports.isBoolean = isBoolean;\n\nfunction isNull(arg) {\n  return arg === null;\n}\nexports.isNull = isNull;\n\nfunction isNullOrUndefined(arg) {\n  return arg == null;\n}\nexports.isNullOrUndefined = isNullOrUndefined;\n\nfunction isNumber(arg) {\n  return typeof arg === 'number';\n}\nexports.isNumber = isNumber;\n\nfunction isString(arg) {\n  return typeof arg === 'string';\n}\nexports.isString = isString;\n\nfunction isSymbol(arg) {\n  return typeof arg === 'symbol';\n}\nexports.isSymbol = isSymbol;\n\nfunction isUndefined(arg) {\n  return arg === void 0;\n}\nexports.isUndefined = isUndefined;\n\nfunction isRegExp(re) {\n  return isObject(re) && objectToString(re) === '[object RegExp]';\n}\nexports.isRegExp = isRegExp;\n\nfunction isObject(arg) {\n  return typeof arg === 'object' && arg !== null;\n}\nexports.isObject = isObject;\n\nfunction isDate(d) {\n  return isObject(d) && objectToString(d) === '[object Date]';\n}\nexports.isDate = isDate;\n\nfunction isError(e) {\n  return isObject(e) &&\n      (objectToString(e) === '[object Error]' || e instanceof Error);\n}\nexports.isError = isError;\n\nfunction isFunction(arg) {\n  return typeof arg === 'function';\n}\nexports.isFunction = isFunction;\n\nfunction isPrimitive(arg) {\n  return arg === null ||\n         typeof arg === 'boolean' ||\n         typeof arg === 'number' ||\n         typeof arg === 'string' ||\n         typeof arg === 'symbol' ||  // ES6 symbol\n         typeof arg === 'undefined';\n}\nexports.isPrimitive = isPrimitive;\n\nfunction isBuffer(arg) {\n  return Buffer.isBuffer(arg);\n}\nexports.isBuffer = isBuffer;\n\nfunction objectToString(o) {\n  return Object.prototype.toString.call(o);\n}\n}).call(this,require(\"buffer\").Buffer)\n},{\"buffer\":43}],59:[function(require,module,exports){\nmodule.exports = require(\"./lib/_stream_passthrough.js\")\n\n},{\"./lib/_stream_passthrough.js\":54}],60:[function(require,module,exports){\nexports = module.exports = require('./lib/_stream_readable.js');\nexports.Stream = require('stream');\nexports.Readable = exports;\nexports.Writable = require('./lib/_stream_writable.js');\nexports.Duplex = require('./lib/_stream_duplex.js');\nexports.Transform = require('./lib/_stream_transform.js');\nexports.PassThrough = require('./lib/_stream_passthrough.js');\n\n},{\"./lib/_stream_duplex.js\":53,\"./lib/_stream_passthrough.js\":54,\"./lib/_stream_readable.js\":55,\"./lib/_stream_transform.js\":56,\"./lib/_stream_writable.js\":57,\"stream\":63}],61:[function(require,module,exports){\nmodule.exports = require(\"./lib/_stream_transform.js\")\n\n},{\"./lib/_stream_transform.js\":56}],62:[function(require,module,exports){\nmodule.exports = require(\"./lib/_stream_writable.js\")\n\n},{\"./lib/_stream_writable.js\":57}],63:[function(require,module,exports){\n// Copyright Joyent, Inc. and other Node contributors.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a\n// copy of this software and associated documentation files (the\n// \"Software\"), to deal in the Software without restriction, including\n// without limitation the rights to use, copy, modify, merge, publish,\n// distribute, sublicense, and/or sell copies of the Software, and to permit\n// persons to whom the Software is furnished to do so, subject to the\n// following conditions:\n//\n// The above copyright notice and this permission notice shall be included\n// in all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS\n// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN\n// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,\n// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE\n// USE OR OTHER DEALINGS IN THE SOFTWARE.\n\nmodule.exports = Stream;\n\nvar EE = require('events').EventEmitter;\nvar inherits = require('inherits');\n\ninherits(Stream, EE);\nStream.Readable = require('readable-stream/readable.js');\nStream.Writable = require('readable-stream/writable.js');\nStream.Duplex = require('readable-stream/duplex.js');\nStream.Transform = require('readable-stream/transform.js');\nStream.PassThrough = require('readable-stream/passthrough.js');\n\n// Backwards-compat with node 0.4.x\nStream.Stream = Stream;\n\n\n\n// old-style streams.  Note that the pipe method (the only relevant\n// part of this class) is overridden in the Readable class.\n\nfunction Stream() {\n  EE.call(this);\n}\n\nStream.prototype.pipe = function(dest, options) {\n  var source = this;\n\n  function ondata(chunk) {\n    if (dest.writable) {\n      if (false === dest.write(chunk) && source.pause) {\n        source.pause();\n      }\n    }\n  }\n\n  source.on('data', ondata);\n\n  function ondrain() {\n    if (source.readable && source.resume) {\n      source.resume();\n    }\n  }\n\n  dest.on('drain', ondrain);\n\n  // If the 'end' option is not supplied, dest.end() will be called when\n  // source gets the 'end' or 'close' events.  Only dest.end() once.\n  if (!dest._isStdio && (!options || options.end !== false)) {\n    source.on('end', onend);\n    source.on('close', onclose);\n  }\n\n  var didOnEnd = false;\n  function onend() {\n    if (didOnEnd) return;\n    didOnEnd = true;\n\n    dest.end();\n  }\n\n\n  function onclose() {\n    if (didOnEnd) return;\n    didOnEnd = true;\n\n    if (typeof dest.destroy === 'function') dest.destroy();\n  }\n\n  // don't leave dangling pipes when there are errors.\n  function onerror(er) {\n    cleanup();\n    if (EE.listenerCount(this, 'error') === 0) {\n      throw er; // Unhandled stream error in pipe.\n    }\n  }\n\n  source.on('error', onerror);\n  dest.on('error', onerror);\n\n  // remove all the event listeners that were added.\n  function cleanup() {\n    source.removeListener('data', ondata);\n    dest.removeListener('drain', ondrain);\n\n    source.removeListener('end', onend);\n    source.removeListener('close', onclose);\n\n    source.removeListener('error', onerror);\n    dest.removeListener('error', onerror);\n\n    source.removeListener('end', cleanup);\n    source.removeListener('close', cleanup);\n\n    dest.removeListener('close', cleanup);\n  }\n\n  source.on('end', cleanup);\n  source.on('close', cleanup);\n\n  dest.on('close', cleanup);\n\n  dest.emit('pipe', source);\n\n  // Allow for unix-like usage: A.pipe(B).pipe(C)\n  return dest;\n};\n\n},{\"events\":47,\"inherits\":48,\"readable-stream/duplex.js\":52,\"readable-stream/passthrough.js\":59,\"readable-stream/readable.js\":60,\"readable-stream/transform.js\":61,\"readable-stream/writable.js\":62}],64:[function(require,module,exports){\n// Copyright Joyent, Inc. and other Node contributors.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a\n// copy of this software and associated documentation files (the\n// \"Software\"), to deal in the Software without restriction, including\n// without limitation the rights to use, copy, modify, merge, publish,\n// distribute, sublicense, and/or sell copies of the Software, and to permit\n// persons to whom the Software is furnished to do so, subject to the\n// following conditions:\n//\n// The above copyright notice and this permission notice shall be included\n// in all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS\n// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN\n// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,\n// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE\n// USE OR OTHER DEALINGS IN THE SOFTWARE.\n\nvar Buffer = require('buffer').Buffer;\n\nvar isBufferEncoding = Buffer.isEncoding\n  || function(encoding) {\n       switch (encoding && encoding.toLowerCase()) {\n         case 'hex': case 'utf8': case 'utf-8': case 'ascii': case 'binary': case 'base64': case 'ucs2': case 'ucs-2': case 'utf16le': case 'utf-16le': case 'raw': return true;\n         default: return false;\n       }\n     }\n\n\nfunction assertEncoding(encoding) {\n  if (encoding && !isBufferEncoding(encoding)) {\n    throw new Error('Unknown encoding: ' + encoding);\n  }\n}\n\n// StringDecoder provides an interface for efficiently splitting a series of\n// buffers into a series of JS strings without breaking apart multi-byte\n// characters. CESU-8 is handled as part of the UTF-8 encoding.\n//\n// @TODO Handling all encodings inside a single object makes it very difficult\n// to reason about this code, so it should be split up in the future.\n// @TODO There should be a utf8-strict encoding that rejects invalid UTF-8 code\n// points as used by CESU-8.\nvar StringDecoder = exports.StringDecoder = function(encoding) {\n  this.encoding = (encoding || 'utf8').toLowerCase().replace(/[-_]/, '');\n  assertEncoding(encoding);\n  switch (this.encoding) {\n    case 'utf8':\n      // CESU-8 represents each of Surrogate Pair by 3-bytes\n      this.surrogateSize = 3;\n      break;\n    case 'ucs2':\n    case 'utf16le':\n      // UTF-16 represents each of Surrogate Pair by 2-bytes\n      this.surrogateSize = 2;\n      this.detectIncompleteChar = utf16DetectIncompleteChar;\n      break;\n    case 'base64':\n      // Base-64 stores 3 bytes in 4 chars, and pads the remainder.\n      this.surrogateSize = 3;\n      this.detectIncompleteChar = base64DetectIncompleteChar;\n      break;\n    default:\n      this.write = passThroughWrite;\n      return;\n  }\n\n  // Enough space to store all bytes of a single character. UTF-8 needs 4\n  // bytes, but CESU-8 may require up to 6 (3 bytes per surrogate).\n  this.charBuffer = new Buffer(6);\n  // Number of bytes received for the current incomplete multi-byte character.\n  this.charReceived = 0;\n  // Number of bytes expected for the current incomplete multi-byte character.\n  this.charLength = 0;\n};\n\n\n// write decodes the given buffer and returns it as JS string that is\n// guaranteed to not contain any partial multi-byte characters. Any partial\n// character found at the end of the buffer is buffered up, and will be\n// returned when calling write again with the remaining bytes.\n//\n// Note: Converting a Buffer containing an orphan surrogate to a String\n// currently works, but converting a String to a Buffer (via `new Buffer`, or\n// Buffer#write) will replace incomplete surrogates with the unicode\n// replacement character. See https://codereview.chromium.org/121173009/ .\nStringDecoder.prototype.write = function(buffer) {\n  var charStr = '';\n  // if our last write ended with an incomplete multibyte character\n  while (this.charLength) {\n    // determine how many remaining bytes this buffer has to offer for this char\n    var available = (buffer.length >= this.charLength - this.charReceived) ?\n        this.charLength - this.charReceived :\n        buffer.length;\n\n    // add the new bytes to the char buffer\n    buffer.copy(this.charBuffer, this.charReceived, 0, available);\n    this.charReceived += available;\n\n    if (this.charReceived < this.charLength) {\n      // still not enough chars in this buffer? wait for more ...\n      return '';\n    }\n\n    // remove bytes belonging to the current character from the buffer\n    buffer = buffer.slice(available, buffer.length);\n\n    // get the character that was split\n    charStr = this.charBuffer.slice(0, this.charLength).toString(this.encoding);\n\n    // CESU-8: lead surrogate (D800-DBFF) is also the incomplete character\n    var charCode = charStr.charCodeAt(charStr.length - 1);\n    if (charCode >= 0xD800 && charCode <= 0xDBFF) {\n      this.charLength += this.surrogateSize;\n      charStr = '';\n      continue;\n    }\n    this.charReceived = this.charLength = 0;\n\n    // if there are no more bytes in this buffer, just emit our char\n    if (buffer.length === 0) {\n      return charStr;\n    }\n    break;\n  }\n\n  // determine and set charLength / charReceived\n  this.detectIncompleteChar(buffer);\n\n  var end = buffer.length;\n  if (this.charLength) {\n    // buffer the incomplete character bytes we got\n    buffer.copy(this.charBuffer, 0, buffer.length - this.charReceived, end);\n    end -= this.charReceived;\n  }\n\n  charStr += buffer.toString(this.encoding, 0, end);\n\n  var end = charStr.length - 1;\n  var charCode = charStr.charCodeAt(end);\n  // CESU-8: lead surrogate (D800-DBFF) is also the incomplete character\n  if (charCode >= 0xD800 && charCode <= 0xDBFF) {\n    var size = this.surrogateSize;\n    this.charLength += size;\n    this.charReceived += size;\n    this.charBuffer.copy(this.charBuffer, size, 0, size);\n    buffer.copy(this.charBuffer, 0, 0, size);\n    return charStr.substring(0, end);\n  }\n\n  // or just emit the charStr\n  return charStr;\n};\n\n// detectIncompleteChar determines if there is an incomplete UTF-8 character at\n// the end of the given buffer. If so, it sets this.charLength to the byte\n// length that character, and sets this.charReceived to the number of bytes\n// that are available for this character.\nStringDecoder.prototype.detectIncompleteChar = function(buffer) {\n  // determine how many bytes we have to check at the end of this buffer\n  var i = (buffer.length >= 3) ? 3 : buffer.length;\n\n  // Figure out if one of the last i bytes of our buffer announces an\n  // incomplete char.\n  for (; i > 0; i--) {\n    var c = buffer[buffer.length - i];\n\n    // See http://en.wikipedia.org/wiki/UTF-8#Description\n\n    // 110XXXXX\n    if (i == 1 && c >> 5 == 0x06) {\n      this.charLength = 2;\n      break;\n    }\n\n    // 1110XXXX\n    if (i <= 2 && c >> 4 == 0x0E) {\n      this.charLength = 3;\n      break;\n    }\n\n    // 11110XXX\n    if (i <= 3 && c >> 3 == 0x1E) {\n      this.charLength = 4;\n      break;\n    }\n  }\n  this.charReceived = i;\n};\n\nStringDecoder.prototype.end = function(buffer) {\n  var res = '';\n  if (buffer && buffer.length)\n    res = this.write(buffer);\n\n  if (this.charReceived) {\n    var cr = this.charReceived;\n    var buf = this.charBuffer;\n    var enc = this.encoding;\n    res += buf.slice(0, cr).toString(enc);\n  }\n\n  return res;\n};\n\nfunction passThroughWrite(buffer) {\n  return buffer.toString(this.encoding);\n}\n\nfunction utf16DetectIncompleteChar(buffer) {\n  this.charReceived = buffer.length % 2;\n  this.charLength = this.charReceived ? 2 : 0;\n}\n\nfunction base64DetectIncompleteChar(buffer) {\n  this.charReceived = buffer.length % 3;\n  this.charLength = this.charReceived ? 3 : 0;\n}\n\n},{\"buffer\":43}],65:[function(require,module,exports){\nmodule.exports = function isBuffer(arg) {\n  return arg && typeof arg === 'object'\n    && typeof arg.copy === 'function'\n    && typeof arg.fill === 'function'\n    && typeof arg.readUInt8 === 'function';\n}\n},{}],66:[function(require,module,exports){\n(function (process,global){\n// Copyright Joyent, Inc. and other Node contributors.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a\n// copy of this software and associated documentation files (the\n// \"Software\"), to deal in the Software without restriction, including\n// without limitation the rights to use, copy, modify, merge, publish,\n// distribute, sublicense, and/or sell copies of the Software, and to permit\n// persons to whom the Software is furnished to do so, subject to the\n// following conditions:\n//\n// The above copyright notice and this permission notice shall be included\n// in all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS\n// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN\n// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,\n// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE\n// USE OR OTHER DEALINGS IN THE SOFTWARE.\n\nvar formatRegExp = /%[sdj%]/g;\nexports.format = function(f) {\n  if (!isString(f)) {\n    var objects = [];\n    for (var i = 0; i < arguments.length; i++) {\n      objects.push(inspect(arguments[i]));\n    }\n    return objects.join(' ');\n  }\n\n  var i = 1;\n  var args = arguments;\n  var len = args.length;\n  var str = String(f).replace(formatRegExp, function(x) {\n    if (x === '%%') return '%';\n    if (i >= len) return x;\n    switch (x) {\n      case '%s': return String(args[i++]);\n      case '%d': return Number(args[i++]);\n      case '%j':\n        try {\n          return JSON.stringify(args[i++]);\n        } catch (_) {\n          return '[Circular]';\n        }\n      default:\n        return x;\n    }\n  });\n  for (var x = args[i]; i < len; x = args[++i]) {\n    if (isNull(x) || !isObject(x)) {\n      str += ' ' + x;\n    } else {\n      str += ' ' + inspect(x);\n    }\n  }\n  return str;\n};\n\n\n// Mark that a method should not be used.\n// Returns a modified function which warns once by default.\n// If --no-deprecation is set, then it is a no-op.\nexports.deprecate = function(fn, msg) {\n  // Allow for deprecating things in the process of starting up.\n  if (isUndefined(global.process)) {\n    return function() {\n      return exports.deprecate(fn, msg).apply(this, arguments);\n    };\n  }\n\n  if (process.noDeprecation === true) {\n    return fn;\n  }\n\n  var warned = false;\n  function deprecated() {\n    if (!warned) {\n      if (process.throwDeprecation) {\n        throw new Error(msg);\n      } else if (process.traceDeprecation) {\n        console.trace(msg);\n      } else {\n        console.error(msg);\n      }\n      warned = true;\n    }\n    return fn.apply(this, arguments);\n  }\n\n  return deprecated;\n};\n\n\nvar debugs = {};\nvar debugEnviron;\nexports.debuglog = function(set) {\n  if (isUndefined(debugEnviron))\n    debugEnviron = process.env.NODE_DEBUG || '';\n  set = set.toUpperCase();\n  if (!debugs[set]) {\n    if (new RegExp('\\\\b' + set + '\\\\b', 'i').test(debugEnviron)) {\n      var pid = process.pid;\n      debugs[set] = function() {\n        var msg = exports.format.apply(exports, arguments);\n        console.error('%s %d: %s', set, pid, msg);\n      };\n    } else {\n      debugs[set] = function() {};\n    }\n  }\n  return debugs[set];\n};\n\n\n/**\n * Echos the value of a value. Trys to print the value out\n * in the best way possible given the different types.\n *\n * @param {Object} obj The object to print out.\n * @param {Object} opts Optional options object that alters the output.\n */\n/* legacy: obj, showHidden, depth, colors*/\nfunction inspect(obj, opts) {\n  // default options\n  var ctx = {\n    seen: [],\n    stylize: stylizeNoColor\n  };\n  // legacy...\n  if (arguments.length >= 3) ctx.depth = arguments[2];\n  if (arguments.length >= 4) ctx.colors = arguments[3];\n  if (isBoolean(opts)) {\n    // legacy...\n    ctx.showHidden = opts;\n  } else if (opts) {\n    // got an \"options\" object\n    exports._extend(ctx, opts);\n  }\n  // set default options\n  if (isUndefined(ctx.showHidden)) ctx.showHidden = false;\n  if (isUndefined(ctx.depth)) ctx.depth = 2;\n  if (isUndefined(ctx.colors)) ctx.colors = false;\n  if (isUndefined(ctx.customInspect)) ctx.customInspect = true;\n  if (ctx.colors) ctx.stylize = stylizeWithColor;\n  return formatValue(ctx, obj, ctx.depth);\n}\nexports.inspect = inspect;\n\n\n// http://en.wikipedia.org/wiki/ANSI_escape_code#graphics\ninspect.colors = {\n  'bold' : [1, 22],\n  'italic' : [3, 23],\n  'underline' : [4, 24],\n  'inverse' : [7, 27],\n  'white' : [37, 39],\n  'grey' : [90, 39],\n  'black' : [30, 39],\n  'blue' : [34, 39],\n  'cyan' : [36, 39],\n  'green' : [32, 39],\n  'magenta' : [35, 39],\n  'red' : [31, 39],\n  'yellow' : [33, 39]\n};\n\n// Don't use 'blue' not visible on cmd.exe\ninspect.styles = {\n  'special': 'cyan',\n  'number': 'yellow',\n  'boolean': 'yellow',\n  'undefined': 'grey',\n  'null': 'bold',\n  'string': 'green',\n  'date': 'magenta',\n  // \"name\": intentionally not styling\n  'regexp': 'red'\n};\n\n\nfunction stylizeWithColor(str, styleType) {\n  var style = inspect.styles[styleType];\n\n  if (style) {\n    return '\\u001b[' + inspect.colors[style][0] + 'm' + str +\n           '\\u001b[' + inspect.colors[style][1] + 'm';\n  } else {\n    return str;\n  }\n}\n\n\nfunction stylizeNoColor(str, styleType) {\n  return str;\n}\n\n\nfunction arrayToHash(array) {\n  var hash = {};\n\n  array.forEach(function(val, idx) {\n    hash[val] = true;\n  });\n\n  return hash;\n}\n\n\nfunction formatValue(ctx, value, recurseTimes) {\n  // Provide a hook for user-specified inspect functions.\n  // Check that value is an object with an inspect function on it\n  if (ctx.customInspect &&\n      value &&\n      isFunction(value.inspect) &&\n      // Filter out the util module, it's inspect function is special\n      value.inspect !== exports.inspect &&\n      // Also filter out any prototype objects using the circular check.\n      !(value.constructor && value.constructor.prototype === value)) {\n    var ret = value.inspect(recurseTimes, ctx);\n    if (!isString(ret)) {\n      ret = formatValue(ctx, ret, recurseTimes);\n    }\n    return ret;\n  }\n\n  // Primitive types cannot have properties\n  var primitive = formatPrimitive(ctx, value);\n  if (primitive) {\n    return primitive;\n  }\n\n  // Look up the keys of the object.\n  var keys = Object.keys(value);\n  var visibleKeys = arrayToHash(keys);\n\n  if (ctx.showHidden) {\n    keys = Object.getOwnPropertyNames(value);\n  }\n\n  // IE doesn't make error fields non-enumerable\n  // http://msdn.microsoft.com/en-us/library/ie/dww52sbt(v=vs.94).aspx\n  if (isError(value)\n      && (keys.indexOf('message') >= 0 || keys.indexOf('description') >= 0)) {\n    return formatError(value);\n  }\n\n  // Some type of object without properties can be shortcutted.\n  if (keys.length === 0) {\n    if (isFunction(value)) {\n      var name = value.name ? ': ' + value.name : '';\n      return ctx.stylize('[Function' + name + ']', 'special');\n    }\n    if (isRegExp(value)) {\n      return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp');\n    }\n    if (isDate(value)) {\n      return ctx.stylize(Date.prototype.toString.call(value), 'date');\n    }\n    if (isError(value)) {\n      return formatError(value);\n    }\n  }\n\n  var base = '', array = false, braces = ['{', '}'];\n\n  // Make Array say that they are Array\n  if (isArray(value)) {\n    array = true;\n    braces = ['[', ']'];\n  }\n\n  // Make functions say that they are functions\n  if (isFunction(value)) {\n    var n = value.name ? ': ' + value.name : '';\n    base = ' [Function' + n + ']';\n  }\n\n  // Make RegExps say that they are RegExps\n  if (isRegExp(value)) {\n    base = ' ' + RegExp.prototype.toString.call(value);\n  }\n\n  // Make dates with properties first say the date\n  if (isDate(value)) {\n    base = ' ' + Date.prototype.toUTCString.call(value);\n  }\n\n  // Make error with message first say the error\n  if (isError(value)) {\n    base = ' ' + formatError(value);\n  }\n\n  if (keys.length === 0 && (!array || value.length == 0)) {\n    return braces[0] + base + braces[1];\n  }\n\n  if (recurseTimes < 0) {\n    if (isRegExp(value)) {\n      return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp');\n    } else {\n      return ctx.stylize('[Object]', 'special');\n    }\n  }\n\n  ctx.seen.push(value);\n\n  var output;\n  if (array) {\n    output = formatArray(ctx, value, recurseTimes, visibleKeys, keys);\n  } else {\n    output = keys.map(function(key) {\n      return formatProperty(ctx, value, recurseTimes, visibleKeys, key, array);\n    });\n  }\n\n  ctx.seen.pop();\n\n  return reduceToSingleString(output, base, braces);\n}\n\n\nfunction formatPrimitive(ctx, value) {\n  if (isUndefined(value))\n    return ctx.stylize('undefined', 'undefined');\n  if (isString(value)) {\n    var simple = '\\'' + JSON.stringify(value).replace(/^\"|\"$/g, '')\n                                             .replace(/'/g, \"\\\\'\")\n                                             .replace(/\\\\\"/g, '\"') + '\\'';\n    return ctx.stylize(simple, 'string');\n  }\n  if (isNumber(value))\n    return ctx.stylize('' + value, 'number');\n  if (isBoolean(value))\n    return ctx.stylize('' + value, 'boolean');\n  // For some reason typeof null is \"object\", so special case here.\n  if (isNull(value))\n    return ctx.stylize('null', 'null');\n}\n\n\nfunction formatError(value) {\n  return '[' + Error.prototype.toString.call(value) + ']';\n}\n\n\nfunction formatArray(ctx, value, recurseTimes, visibleKeys, keys) {\n  var output = [];\n  for (var i = 0, l = value.length; i < l; ++i) {\n    if (hasOwnProperty(value, String(i))) {\n      output.push(formatProperty(ctx, value, recurseTimes, visibleKeys,\n          String(i), true));\n    } else {\n      output.push('');\n    }\n  }\n  keys.forEach(function(key) {\n    if (!key.match(/^\\d+$/)) {\n      output.push(formatProperty(ctx, value, recurseTimes, visibleKeys,\n          key, true));\n    }\n  });\n  return output;\n}\n\n\nfunction formatProperty(ctx, value, recurseTimes, visibleKeys, key, array) {\n  var name, str, desc;\n  desc = Object.getOwnPropertyDescriptor(value, key) || { value: value[key] };\n  if (desc.get) {\n    if (desc.set) {\n      str = ctx.stylize('[Getter/Setter]', 'special');\n    } else {\n      str = ctx.stylize('[Getter]', 'special');\n    }\n  } else {\n    if (desc.set) {\n      str = ctx.stylize('[Setter]', 'special');\n    }\n  }\n  if (!hasOwnProperty(visibleKeys, key)) {\n    name = '[' + key + ']';\n  }\n  if (!str) {\n    if (ctx.seen.indexOf(desc.value) < 0) {\n      if (isNull(recurseTimes)) {\n        str = formatValue(ctx, desc.value, null);\n      } else {\n        str = formatValue(ctx, desc.value, recurseTimes - 1);\n      }\n      if (str.indexOf('\\n') > -1) {\n        if (array) {\n          str = str.split('\\n').map(function(line) {\n            return '  ' + line;\n          }).join('\\n').substr(2);\n        } else {\n          str = '\\n' + str.split('\\n').map(function(line) {\n            return '   ' + line;\n          }).join('\\n');\n        }\n      }\n    } else {\n      str = ctx.stylize('[Circular]', 'special');\n    }\n  }\n  if (isUndefined(name)) {\n    if (array && key.match(/^\\d+$/)) {\n      return str;\n    }\n    name = JSON.stringify('' + key);\n    if (name.match(/^\"([a-zA-Z_][a-zA-Z_0-9]*)\"$/)) {\n      name = name.substr(1, name.length - 2);\n      name = ctx.stylize(name, 'name');\n    } else {\n      name = name.replace(/'/g, \"\\\\'\")\n                 .replace(/\\\\\"/g, '\"')\n                 .replace(/(^\"|\"$)/g, \"'\");\n      name = ctx.stylize(name, 'string');\n    }\n  }\n\n  return name + ': ' + str;\n}\n\n\nfunction reduceToSingleString(output, base, braces) {\n  var numLinesEst = 0;\n  var length = output.reduce(function(prev, cur) {\n    numLinesEst++;\n    if (cur.indexOf('\\n') >= 0) numLinesEst++;\n    return prev + cur.replace(/\\u001b\\[\\d\\d?m/g, '').length + 1;\n  }, 0);\n\n  if (length > 60) {\n    return braces[0] +\n           (base === '' ? '' : base + '\\n ') +\n           ' ' +\n           output.join(',\\n  ') +\n           ' ' +\n           braces[1];\n  }\n\n  return braces[0] + base + ' ' + output.join(', ') + ' ' + braces[1];\n}\n\n\n// NOTE: These type checking functions intentionally don't use `instanceof`\n// because it is fragile and can be easily faked with `Object.create()`.\nfunction isArray(ar) {\n  return Array.isArray(ar);\n}\nexports.isArray = isArray;\n\nfunction isBoolean(arg) {\n  return typeof arg === 'boolean';\n}\nexports.isBoolean = isBoolean;\n\nfunction isNull(arg) {\n  return arg === null;\n}\nexports.isNull = isNull;\n\nfunction isNullOrUndefined(arg) {\n  return arg == null;\n}\nexports.isNullOrUndefined = isNullOrUndefined;\n\nfunction isNumber(arg) {\n  return typeof arg === 'number';\n}\nexports.isNumber = isNumber;\n\nfunction isString(arg) {\n  return typeof arg === 'string';\n}\nexports.isString = isString;\n\nfunction isSymbol(arg) {\n  return typeof arg === 'symbol';\n}\nexports.isSymbol = isSymbol;\n\nfunction isUndefined(arg) {\n  return arg === void 0;\n}\nexports.isUndefined = isUndefined;\n\nfunction isRegExp(re) {\n  return isObject(re) && objectToString(re) === '[object RegExp]';\n}\nexports.isRegExp = isRegExp;\n\nfunction isObject(arg) {\n  return typeof arg === 'object' && arg !== null;\n}\nexports.isObject = isObject;\n\nfunction isDate(d) {\n  return isObject(d) && objectToString(d) === '[object Date]';\n}\nexports.isDate = isDate;\n\nfunction isError(e) {\n  return isObject(e) &&\n      (objectToString(e) === '[object Error]' || e instanceof Error);\n}\nexports.isError = isError;\n\nfunction isFunction(arg) {\n  return typeof arg === 'function';\n}\nexports.isFunction = isFunction;\n\nfunction isPrimitive(arg) {\n  return arg === null ||\n         typeof arg === 'boolean' ||\n         typeof arg === 'number' ||\n         typeof arg === 'string' ||\n         typeof arg === 'symbol' ||  // ES6 symbol\n         typeof arg === 'undefined';\n}\nexports.isPrimitive = isPrimitive;\n\nexports.isBuffer = require('./support/isBuffer');\n\nfunction objectToString(o) {\n  return Object.prototype.toString.call(o);\n}\n\n\nfunction pad(n) {\n  return n < 10 ? '0' + n.toString(10) : n.toString(10);\n}\n\n\nvar months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep',\n              'Oct', 'Nov', 'Dec'];\n\n// 26 Feb 16:19:34\nfunction timestamp() {\n  var d = new Date();\n  var time = [pad(d.getHours()),\n              pad(d.getMinutes()),\n              pad(d.getSeconds())].join(':');\n  return [d.getDate(), months[d.getMonth()], time].join(' ');\n}\n\n\n// log is just a thin wrapper to console.log that prepends a timestamp\nexports.log = function() {\n  console.log('%s - %s', timestamp(), exports.format.apply(exports, arguments));\n};\n\n\n/**\n * Inherit the prototype methods from one constructor into another.\n *\n * The Function.prototype.inherits from lang.js rewritten as a standalone\n * function (not on Function.prototype). NOTE: If this file is to be loaded\n * during bootstrapping this function needs to be rewritten using some native\n * functions as prototype setup using normal JavaScript does not work as\n * expected during bootstrapping (see mirror.js in r114903).\n *\n * @param {function} ctor Constructor function which needs to inherit the\n *     prototype.\n * @param {function} superCtor Constructor function to inherit prototype from.\n */\nexports.inherits = require('inherits');\n\nexports._extend = function(origin, add) {\n  // Don't do anything if add isn't an object\n  if (!add || !isObject(add)) return origin;\n\n  var keys = Object.keys(add);\n  var i = keys.length;\n  while (i--) {\n    origin[keys[i]] = add[keys[i]];\n  }\n  return origin;\n};\n\nfunction hasOwnProperty(obj, prop) {\n  return Object.prototype.hasOwnProperty.call(obj, prop);\n}\n\n}).call(this,require('_process'),typeof global !== \"undefined\" ? global : typeof self !== \"undefined\" ? self : typeof window !== \"undefined\" ? window : {})\n},{\"./support/isBuffer\":65,\"_process\":51,\"inherits\":48}],67:[function(require,module,exports){\n/* See LICENSE file for terms of use */\n\n/*\n * Text diff implementation.\n *\n * This library supports the following APIS:\n * JsDiff.diffChars: Character by character diff\n * JsDiff.diffWords: Word (as defined by \\b regex) diff which ignores whitespace\n * JsDiff.diffLines: Line based diff\n *\n * JsDiff.diffCss: Diff targeted at CSS content\n *\n * These methods are based on the implementation proposed in\n * \"An O(ND) Difference Algorithm and its Variations\" (Myers, 1986).\n * http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.4.6927\n */\n(function(global, undefined) {\n  var objectPrototypeToString = Object.prototype.toString;\n\n  /*istanbul ignore next*/\n  function map(arr, mapper, that) {\n    if (Array.prototype.map) {\n      return Array.prototype.map.call(arr, mapper, that);\n    }\n\n    var other = new Array(arr.length);\n\n    for (var i = 0, n = arr.length; i < n; i++) {\n      other[i] = mapper.call(that, arr[i], i, arr);\n    }\n    return other;\n  }\n  function clonePath(path) {\n    return { newPos: path.newPos, components: path.components.slice(0) };\n  }\n  function removeEmpty(array) {\n    var ret = [];\n    for (var i = 0; i < array.length; i++) {\n      if (array[i]) {\n        ret.push(array[i]);\n      }\n    }\n    return ret;\n  }\n  function escapeHTML(s) {\n    var n = s;\n    n = n.replace(/&/g, '&amp;');\n    n = n.replace(/</g, '&lt;');\n    n = n.replace(/>/g, '&gt;');\n    n = n.replace(/\"/g, '&quot;');\n\n    return n;\n  }\n\n  // This function handles the presence of circular references by bailing out when encountering an\n  // object that is already on the \"stack\" of items being processed.\n  function canonicalize(obj, stack, replacementStack) {\n    stack = stack || [];\n    replacementStack = replacementStack || [];\n\n    var i;\n\n    for (i = 0; i < stack.length; i += 1) {\n      if (stack[i] === obj) {\n        return replacementStack[i];\n      }\n    }\n\n    var canonicalizedObj;\n\n    if ('[object Array]' === objectPrototypeToString.call(obj)) {\n      stack.push(obj);\n      canonicalizedObj = new Array(obj.length);\n      replacementStack.push(canonicalizedObj);\n      for (i = 0; i < obj.length; i += 1) {\n        canonicalizedObj[i] = canonicalize(obj[i], stack, replacementStack);\n      }\n      stack.pop();\n      replacementStack.pop();\n    } else if (typeof obj === 'object' && obj !== null) {\n      stack.push(obj);\n      canonicalizedObj = {};\n      replacementStack.push(canonicalizedObj);\n      var sortedKeys = [],\n          key;\n      for (key in obj) {\n        sortedKeys.push(key);\n      }\n      sortedKeys.sort();\n      for (i = 0; i < sortedKeys.length; i += 1) {\n        key = sortedKeys[i];\n        canonicalizedObj[key] = canonicalize(obj[key], stack, replacementStack);\n      }\n      stack.pop();\n      replacementStack.pop();\n    } else {\n      canonicalizedObj = obj;\n    }\n    return canonicalizedObj;\n  }\n\n  function buildValues(components, newString, oldString, useLongestToken) {\n    var componentPos = 0,\n        componentLen = components.length,\n        newPos = 0,\n        oldPos = 0;\n\n    for (; componentPos < componentLen; componentPos++) {\n      var component = components[componentPos];\n      if (!component.removed) {\n        if (!component.added && useLongestToken) {\n          var value = newString.slice(newPos, newPos + component.count);\n          value = map(value, function(value, i) {\n            var oldValue = oldString[oldPos + i];\n            return oldValue.length > value.length ? oldValue : value;\n          });\n\n          component.value = value.join('');\n        } else {\n          component.value = newString.slice(newPos, newPos + component.count).join('');\n        }\n        newPos += component.count;\n\n        // Common case\n        if (!component.added) {\n          oldPos += component.count;\n        }\n      } else {\n        component.value = oldString.slice(oldPos, oldPos + component.count).join('');\n        oldPos += component.count;\n\n        // Reverse add and remove so removes are output first to match common convention\n        // The diffing algorithm is tied to add then remove output and this is the simplest\n        // route to get the desired output with minimal overhead.\n        if (componentPos && components[componentPos - 1].added) {\n          var tmp = components[componentPos - 1];\n          components[componentPos - 1] = components[componentPos];\n          components[componentPos] = tmp;\n        }\n      }\n    }\n\n    return components;\n  }\n\n  function Diff(ignoreWhitespace) {\n    this.ignoreWhitespace = ignoreWhitespace;\n  }\n  Diff.prototype = {\n    diff: function(oldString, newString, callback) {\n      var self = this;\n\n      function done(value) {\n        if (callback) {\n          setTimeout(function() { callback(undefined, value); }, 0);\n          return true;\n        } else {\n          return value;\n        }\n      }\n\n      // Handle the identity case (this is due to unrolling editLength == 0\n      if (newString === oldString) {\n        return done([{ value: newString }]);\n      }\n      if (!newString) {\n        return done([{ value: oldString, removed: true }]);\n      }\n      if (!oldString) {\n        return done([{ value: newString, added: true }]);\n      }\n\n      newString = this.tokenize(newString);\n      oldString = this.tokenize(oldString);\n\n      var newLen = newString.length, oldLen = oldString.length;\n      var editLength = 1;\n      var maxEditLength = newLen + oldLen;\n      var bestPath = [{ newPos: -1, components: [] }];\n\n      // Seed editLength = 0, i.e. the content starts with the same values\n      var oldPos = this.extractCommon(bestPath[0], newString, oldString, 0);\n      if (bestPath[0].newPos + 1 >= newLen && oldPos + 1 >= oldLen) {\n        // Identity per the equality and tokenizer\n        return done([{value: newString.join('')}]);\n      }\n\n      // Main worker method. checks all permutations of a given edit length for acceptance.\n      function execEditLength() {\n        for (var diagonalPath = -1 * editLength; diagonalPath <= editLength; diagonalPath += 2) {\n          var basePath;\n          var addPath = bestPath[diagonalPath - 1],\n              removePath = bestPath[diagonalPath + 1],\n              oldPos = (removePath ? removePath.newPos : 0) - diagonalPath;\n          if (addPath) {\n            // No one else is going to attempt to use this value, clear it\n            bestPath[diagonalPath - 1] = undefined;\n          }\n\n          var canAdd = addPath && addPath.newPos + 1 < newLen,\n              canRemove = removePath && 0 <= oldPos && oldPos < oldLen;\n          if (!canAdd && !canRemove) {\n            // If this path is a terminal then prune\n            bestPath[diagonalPath] = undefined;\n            continue;\n          }\n\n          // Select the diagonal that we want to branch from. We select the prior\n          // path whose position in the new string is the farthest from the origin\n          // and does not pass the bounds of the diff graph\n          if (!canAdd || (canRemove && addPath.newPos < removePath.newPos)) {\n            basePath = clonePath(removePath);\n            self.pushComponent(basePath.components, undefined, true);\n          } else {\n            basePath = addPath;   // No need to clone, we've pulled it from the list\n            basePath.newPos++;\n            self.pushComponent(basePath.components, true, undefined);\n          }\n\n          oldPos = self.extractCommon(basePath, newString, oldString, diagonalPath);\n\n          // If we have hit the end of both strings, then we are done\n          if (basePath.newPos + 1 >= newLen && oldPos + 1 >= oldLen) {\n            return done(buildValues(basePath.components, newString, oldString, self.useLongestToken));\n          } else {\n            // Otherwise track this path as a potential candidate and continue.\n            bestPath[diagonalPath] = basePath;\n          }\n        }\n\n        editLength++;\n      }\n\n      // Performs the length of edit iteration. Is a bit fugly as this has to support the\n      // sync and async mode which is never fun. Loops over execEditLength until a value\n      // is produced.\n      if (callback) {\n        (function exec() {\n          setTimeout(function() {\n            // This should not happen, but we want to be safe.\n            /*istanbul ignore next */\n            if (editLength > maxEditLength) {\n              return callback();\n            }\n\n            if (!execEditLength()) {\n              exec();\n            }\n          }, 0);\n        }());\n      } else {\n        while (editLength <= maxEditLength) {\n          var ret = execEditLength();\n          if (ret) {\n            return ret;\n          }\n        }\n      }\n    },\n\n    pushComponent: function(components, added, removed) {\n      var last = components[components.length - 1];\n      if (last && last.added === added && last.removed === removed) {\n        // We need to clone here as the component clone operation is just\n        // as shallow array clone\n        components[components.length - 1] = {count: last.count + 1, added: added, removed: removed };\n      } else {\n        components.push({count: 1, added: added, removed: removed });\n      }\n    },\n    extractCommon: function(basePath, newString, oldString, diagonalPath) {\n      var newLen = newString.length,\n          oldLen = oldString.length,\n          newPos = basePath.newPos,\n          oldPos = newPos - diagonalPath,\n\n          commonCount = 0;\n      while (newPos + 1 < newLen && oldPos + 1 < oldLen && this.equals(newString[newPos + 1], oldString[oldPos + 1])) {\n        newPos++;\n        oldPos++;\n        commonCount++;\n      }\n\n      if (commonCount) {\n        basePath.components.push({count: commonCount});\n      }\n\n      basePath.newPos = newPos;\n      return oldPos;\n    },\n\n    equals: function(left, right) {\n      var reWhitespace = /\\S/;\n      return left === right || (this.ignoreWhitespace && !reWhitespace.test(left) && !reWhitespace.test(right));\n    },\n    tokenize: function(value) {\n      return value.split('');\n    }\n  };\n\n  var CharDiff = new Diff();\n\n  var WordDiff = new Diff(true);\n  var WordWithSpaceDiff = new Diff();\n  WordDiff.tokenize = WordWithSpaceDiff.tokenize = function(value) {\n    return removeEmpty(value.split(/(\\s+|\\b)/));\n  };\n\n  var CssDiff = new Diff(true);\n  CssDiff.tokenize = function(value) {\n    return removeEmpty(value.split(/([{}:;,]|\\s+)/));\n  };\n\n  var LineDiff = new Diff();\n\n  var TrimmedLineDiff = new Diff();\n  TrimmedLineDiff.ignoreTrim = true;\n\n  LineDiff.tokenize = TrimmedLineDiff.tokenize = function(value) {\n    var retLines = [],\n        lines = value.split(/^/m);\n    for (var i = 0; i < lines.length; i++) {\n      var line = lines[i],\n          lastLine = lines[i - 1],\n          lastLineLastChar = lastLine && lastLine[lastLine.length - 1];\n\n      // Merge lines that may contain windows new lines\n      if (line === '\\n' && lastLineLastChar === '\\r') {\n          retLines[retLines.length - 1] = retLines[retLines.length - 1].slice(0, -1) + '\\r\\n';\n      } else {\n        if (this.ignoreTrim) {\n          line = line.trim();\n          // add a newline unless this is the last line.\n          if (i < lines.length - 1) {\n            line += '\\n';\n          }\n        }\n        retLines.push(line);\n      }\n    }\n\n    return retLines;\n  };\n\n  var PatchDiff = new Diff();\n  PatchDiff.tokenize = function(value) {\n    var ret = [],\n        linesAndNewlines = value.split(/(\\n|\\r\\n)/);\n\n    // Ignore the final empty token that occurs if the string ends with a new line\n    if (!linesAndNewlines[linesAndNewlines.length - 1]) {\n      linesAndNewlines.pop();\n    }\n\n    // Merge the content and line separators into single tokens\n    for (var i = 0; i < linesAndNewlines.length; i++) {\n      var line = linesAndNewlines[i];\n\n      if (i % 2) {\n        ret[ret.length - 1] += line;\n      } else {\n        ret.push(line);\n      }\n    }\n    return ret;\n  };\n\n  var SentenceDiff = new Diff();\n  SentenceDiff.tokenize = function(value) {\n    return removeEmpty(value.split(/(\\S.+?[.!?])(?=\\s+|$)/));\n  };\n\n  var JsonDiff = new Diff();\n  // Discriminate between two lines of pretty-printed, serialized JSON where one of them has a\n  // dangling comma and the other doesn't. Turns out including the dangling comma yields the nicest output:\n  JsonDiff.useLongestToken = true;\n  JsonDiff.tokenize = LineDiff.tokenize;\n  JsonDiff.equals = function(left, right) {\n    return LineDiff.equals(left.replace(/,([\\r\\n])/g, '$1'), right.replace(/,([\\r\\n])/g, '$1'));\n  };\n\n  var JsDiff = {\n    Diff: Diff,\n\n    diffChars: function(oldStr, newStr, callback) { return CharDiff.diff(oldStr, newStr, callback); },\n    diffWords: function(oldStr, newStr, callback) { return WordDiff.diff(oldStr, newStr, callback); },\n    diffWordsWithSpace: function(oldStr, newStr, callback) { return WordWithSpaceDiff.diff(oldStr, newStr, callback); },\n    diffLines: function(oldStr, newStr, callback) { return LineDiff.diff(oldStr, newStr, callback); },\n    diffTrimmedLines: function(oldStr, newStr, callback) { return TrimmedLineDiff.diff(oldStr, newStr, callback); },\n\n    diffSentences: function(oldStr, newStr, callback) { return SentenceDiff.diff(oldStr, newStr, callback); },\n\n    diffCss: function(oldStr, newStr, callback) { return CssDiff.diff(oldStr, newStr, callback); },\n    diffJson: function(oldObj, newObj, callback) {\n      return JsonDiff.diff(\n        typeof oldObj === 'string' ? oldObj : JSON.stringify(canonicalize(oldObj), undefined, '  '),\n        typeof newObj === 'string' ? newObj : JSON.stringify(canonicalize(newObj), undefined, '  '),\n        callback\n      );\n    },\n\n    createTwoFilesPatch: function(oldFileName, newFileName, oldStr, newStr, oldHeader, newHeader) {\n      var ret = [];\n\n      if (oldFileName == newFileName) {\n        ret.push('Index: ' + oldFileName);\n      }\n      ret.push('===================================================================');\n      ret.push('--- ' + oldFileName + (typeof oldHeader === 'undefined' ? '' : '\\t' + oldHeader));\n      ret.push('+++ ' + newFileName + (typeof newHeader === 'undefined' ? '' : '\\t' + newHeader));\n\n      var diff = PatchDiff.diff(oldStr, newStr);\n      diff.push({value: '', lines: []});   // Append an empty value to make cleanup easier\n\n      // Formats a given set of lines for printing as context lines in a patch\n      function contextLines(lines) {\n        return map(lines, function(entry) { return ' ' + entry; });\n      }\n\n      // Outputs the no newline at end of file warning if needed\n      function eofNL(curRange, i, current) {\n        var last = diff[diff.length - 2],\n            isLast = i === diff.length - 2,\n            isLastOfType = i === diff.length - 3 && current.added !== last.added;\n\n        // Figure out if this is the last line for the given file and missing NL\n        if (!(/\\n$/.test(current.value)) && (isLast || isLastOfType)) {\n          curRange.push('\\\\ No newline at end of file');\n        }\n      }\n\n      var oldRangeStart = 0, newRangeStart = 0, curRange = [],\n          oldLine = 1, newLine = 1;\n      for (var i = 0; i < diff.length; i++) {\n        var current = diff[i],\n            lines = current.lines || current.value.replace(/\\n$/, '').split('\\n');\n        current.lines = lines;\n\n        if (current.added || current.removed) {\n          // If we have previous context, start with that\n          if (!oldRangeStart) {\n            var prev = diff[i - 1];\n            oldRangeStart = oldLine;\n            newRangeStart = newLine;\n\n            if (prev) {\n              curRange = contextLines(prev.lines.slice(-4));\n              oldRangeStart -= curRange.length;\n              newRangeStart -= curRange.length;\n            }\n          }\n\n          // Output our changes\n          curRange.push.apply(curRange, map(lines, function(entry) {\n            return (current.added ? '+' : '-') + entry;\n          }));\n          eofNL(curRange, i, current);\n\n          // Track the updated file position\n          if (current.added) {\n            newLine += lines.length;\n          } else {\n            oldLine += lines.length;\n          }\n        } else {\n          // Identical context lines. Track line changes\n          if (oldRangeStart) {\n            // Close out any changes that have been output (or join overlapping)\n            if (lines.length <= 8 && i < diff.length - 2) {\n              // Overlapping\n              curRange.push.apply(curRange, contextLines(lines));\n            } else {\n              // end the range and output\n              var contextSize = Math.min(lines.length, 4);\n              ret.push(\n                  '@@ -' + oldRangeStart + ',' + (oldLine - oldRangeStart + contextSize)\n                  + ' +' + newRangeStart + ',' + (newLine - newRangeStart + contextSize)\n                  + ' @@');\n              ret.push.apply(ret, curRange);\n              ret.push.apply(ret, contextLines(lines.slice(0, contextSize)));\n              if (lines.length <= 4) {\n                eofNL(ret, i, current);\n              }\n\n              oldRangeStart = 0;\n              newRangeStart = 0;\n              curRange = [];\n            }\n          }\n          oldLine += lines.length;\n          newLine += lines.length;\n        }\n      }\n\n      return ret.join('\\n') + '\\n';\n    },\n\n    createPatch: function(fileName, oldStr, newStr, oldHeader, newHeader) {\n      return JsDiff.createTwoFilesPatch(fileName, fileName, oldStr, newStr, oldHeader, newHeader);\n    },\n\n    applyPatch: function(oldStr, uniDiff) {\n      var diffstr = uniDiff.split('\\n'),\n          hunks = [],\n          i = 0,\n          remEOFNL = false,\n          addEOFNL = false;\n\n      // Skip to the first change hunk\n      while (i < diffstr.length && !(/^@@/.test(diffstr[i]))) {\n        i++;\n      }\n\n      // Parse the unified diff\n      for (; i < diffstr.length; i++) {\n        if (diffstr[i][0] === '@') {\n          var chnukHeader = diffstr[i].split(/@@ -(\\d+),(\\d+) \\+(\\d+),(\\d+) @@/);\n          hunks.unshift({\n            start: chnukHeader[3],\n            oldlength: +chnukHeader[2],\n            removed: [],\n            newlength: chnukHeader[4],\n            added: []\n          });\n        } else if (diffstr[i][0] === '+') {\n          hunks[0].added.push(diffstr[i].substr(1));\n        } else if (diffstr[i][0] === '-') {\n          hunks[0].removed.push(diffstr[i].substr(1));\n        } else if (diffstr[i][0] === ' ') {\n          hunks[0].added.push(diffstr[i].substr(1));\n          hunks[0].removed.push(diffstr[i].substr(1));\n        } else if (diffstr[i][0] === '\\\\') {\n          if (diffstr[i - 1][0] === '+') {\n            remEOFNL = true;\n          } else if (diffstr[i - 1][0] === '-') {\n            addEOFNL = true;\n          }\n        }\n      }\n\n      // Apply the diff to the input\n      var lines = oldStr.split('\\n');\n      for (i = hunks.length - 1; i >= 0; i--) {\n        var hunk = hunks[i];\n        // Sanity check the input string. Bail if we don't match.\n        for (var j = 0; j < hunk.oldlength; j++) {\n          if (lines[hunk.start - 1 + j] !== hunk.removed[j]) {\n            return false;\n          }\n        }\n        Array.prototype.splice.apply(lines, [hunk.start - 1, hunk.oldlength].concat(hunk.added));\n      }\n\n      // Handle EOFNL insertion/removal\n      if (remEOFNL) {\n        while (!lines[lines.length - 1]) {\n          lines.pop();\n        }\n      } else if (addEOFNL) {\n        lines.push('');\n      }\n      return lines.join('\\n');\n    },\n\n    convertChangesToXML: function(changes) {\n      var ret = [];\n      for (var i = 0; i < changes.length; i++) {\n        var change = changes[i];\n        if (change.added) {\n          ret.push('<ins>');\n        } else if (change.removed) {\n          ret.push('<del>');\n        }\n\n        ret.push(escapeHTML(change.value));\n\n        if (change.added) {\n          ret.push('</ins>');\n        } else if (change.removed) {\n          ret.push('</del>');\n        }\n      }\n      return ret.join('');\n    },\n\n    // See: http://code.google.com/p/google-diff-match-patch/wiki/API\n    convertChangesToDMP: function(changes) {\n      var ret = [],\n          change,\n          operation;\n      for (var i = 0; i < changes.length; i++) {\n        change = changes[i];\n        if (change.added) {\n          operation = 1;\n        } else if (change.removed) {\n          operation = -1;\n        } else {\n          operation = 0;\n        }\n\n        ret.push([operation, change.value]);\n      }\n      return ret;\n    },\n\n    canonicalize: canonicalize\n  };\n\n  /*istanbul ignore next */\n  /*global module */\n  if (typeof module !== 'undefined' && module.exports) {\n    module.exports = JsDiff;\n  } else if (typeof define === 'function' && define.amd) {\n    /*global define */\n    define([], function() { return JsDiff; });\n  } else if (typeof global.JsDiff === 'undefined') {\n    global.JsDiff = JsDiff;\n  }\n}(this));\n\n},{}],68:[function(require,module,exports){\n'use strict';\n\nvar matchOperatorsRe = /[|\\\\{}()[\\]^$+*?.]/g;\n\nmodule.exports = function (str) {\n\tif (typeof str !== 'string') {\n\t\tthrow new TypeError('Expected a string');\n\t}\n\n\treturn str.replace(matchOperatorsRe,  '\\\\$&');\n};\n\n},{}],69:[function(require,module,exports){\n(function (process){\n// Growl - Copyright TJ Holowaychuk <tj@vision-media.ca> (MIT Licensed)\n\n/**\n * Module dependencies.\n */\n\nvar exec = require('child_process').exec\n  , fs = require('fs')\n  , path = require('path')\n  , exists = fs.existsSync || path.existsSync\n  , os = require('os')\n  , quote = JSON.stringify\n  , cmd;\n\nfunction which(name) {\n  var paths = process.env.PATH.split(':');\n  var loc;\n  \n  for (var i = 0, len = paths.length; i < len; ++i) {\n    loc = path.join(paths[i], name);\n    if (exists(loc)) return loc;\n  }\n}\n\nswitch(os.type()) {\n  case 'Darwin':\n    if (which('terminal-notifier')) {\n      cmd = {\n          type: \"Darwin-NotificationCenter\"\n        , pkg: \"terminal-notifier\"\n        , msg: '-message'\n        , title: '-title'\n        , subtitle: '-subtitle'\n        , priority: {\n              cmd: '-execute'\n            , range: []\n          }\n      };\n    } else {\n      cmd = {\n          type: \"Darwin-Growl\"\n        , pkg: \"growlnotify\"\n        , msg: '-m'\n        , sticky: '--sticky'\n        , priority: {\n              cmd: '--priority'\n            , range: [\n                -2\n              , -1\n              , 0\n              , 1\n              , 2\n              , \"Very Low\"\n              , \"Moderate\"\n              , \"Normal\"\n              , \"High\"\n              , \"Emergency\"\n            ]\n          }\n      };\n    }\n    break;\n  case 'Linux':\n    cmd = {\n        type: \"Linux\"\n      , pkg: \"notify-send\"\n      , msg: ''\n      , sticky: '-t 0'\n      , icon: '-i'\n      , priority: {\n          cmd: '-u'\n        , range: [\n            \"low\"\n          , \"normal\"\n          , \"critical\"\n        ]\n      }\n    };\n    break;\n  case 'Windows_NT':\n    cmd = {\n        type: \"Windows\"\n      , pkg: \"growlnotify\"\n      , msg: ''\n      , sticky: '/s:true'\n      , title: '/t:'\n      , icon: '/i:'\n      , priority: {\n            cmd: '/p:'\n          , range: [\n              -2\n            , -1\n            , 0\n            , 1\n            , 2\n          ]\n        }\n    };\n    break;\n}\n\n/**\n * Expose `growl`.\n */\n\nexports = module.exports = growl;\n\n/**\n * Node-growl version.\n */\n\nexports.version = '1.4.1'\n\n/**\n * Send growl notification _msg_ with _options_.\n *\n * Options:\n *\n *  - title   Notification title\n *  - sticky  Make the notification stick (defaults to false)\n *  - priority  Specify an int or named key (default is 0)\n *  - name    Application name (defaults to growlnotify)\n *  - image\n *    - path to an icon sets --iconpath\n *    - path to an image sets --image\n *    - capitalized word sets --appIcon\n *    - filename uses extname as --icon\n *    - otherwise treated as --icon\n *\n * Examples:\n *\n *   growl('New email')\n *   growl('5 new emails', { title: 'Thunderbird' })\n *   growl('Email sent', function(){\n *     // ... notification sent\n *   })\n *\n * @param {string} msg\n * @param {object} options\n * @param {function} fn\n * @api public\n */\n\nfunction growl(msg, options, fn) {\n  var image\n    , args\n    , options = options || {}\n    , fn = fn || function(){};\n\n  // noop\n  if (!cmd) return fn(new Error('growl not supported on this platform'));\n  args = [cmd.pkg];\n\n  // image\n  if (image = options.image) {\n    switch(cmd.type) {\n      case 'Darwin-Growl':\n        var flag, ext = path.extname(image).substr(1)\n        flag = flag || ext == 'icns' && 'iconpath'\n        flag = flag || /^[A-Z]/.test(image) && 'appIcon'\n        flag = flag || /^png|gif|jpe?g$/.test(ext) && 'image'\n        flag = flag || ext && (image = ext) && 'icon'\n        flag = flag || 'icon'\n        args.push('--' + flag, quote(image))\n        break;\n      case 'Linux':\n        args.push(cmd.icon, quote(image));\n        // libnotify defaults to sticky, set a hint for transient notifications\n        if (!options.sticky) args.push('--hint=int:transient:1');\n        break;\n      case 'Windows':\n        args.push(cmd.icon + quote(image));\n        break;\n    }\n  }\n\n  // sticky\n  if (options.sticky) args.push(cmd.sticky);\n\n  // priority\n  if (options.priority) {\n    var priority = options.priority + '';\n    var checkindexOf = cmd.priority.range.indexOf(priority);\n    if (~cmd.priority.range.indexOf(priority)) {\n      args.push(cmd.priority, options.priority);\n    }\n  }\n\n  // name\n  if (options.name && cmd.type === \"Darwin-Growl\") {\n    args.push('--name', options.name);\n  }\n\n  switch(cmd.type) {\n    case 'Darwin-Growl':\n      args.push(cmd.msg);\n      args.push(quote(msg));\n      if (options.title) args.push(quote(options.title));\n      break;\n    case 'Darwin-NotificationCenter':\n      args.push(cmd.msg);\n      args.push(quote(msg));\n      if (options.title) {\n        args.push(cmd.title);\n        args.push(quote(options.title));\n      }\n      if (options.subtitle) {\n        args.push(cmd.subtitle);\n        args.push(quote(options.subtitle));\n      }\n      break;\n    case 'Darwin-Growl':\n      args.push(cmd.msg);\n      args.push(quote(msg));\n      if (options.title) args.push(quote(options.title));\n      break;\n    case 'Linux':\n      if (options.title) {\n        args.push(quote(options.title));\n        args.push(cmd.msg);\n        args.push(quote(msg));\n      } else {\n        args.push(quote(msg));\n      }\n      break;\n    case 'Windows':\n      args.push(quote(msg));\n      if (options.title) args.push(cmd.title + quote(options.title));\n      break;\n  }\n\n  // execute\n  exec(args.join(' '), fn);\n};\n\n}).call(this,require('_process'))\n},{\"_process\":51,\"child_process\":41,\"fs\":41,\"os\":50,\"path\":41}],70:[function(require,module,exports){\n(function (process,global){\n/**\n * Shim process.stdout.\n */\n\nprocess.stdout = require('browser-stdout')();\n\nvar Mocha = require('../');\n\n/**\n * Create a Mocha instance.\n *\n * @return {undefined}\n */\n\nvar mocha = new Mocha({ reporter: 'html' });\n\n/**\n * Save timer references to avoid Sinon interfering (see GH-237).\n */\n\nvar Date = global.Date;\nvar setTimeout = global.setTimeout;\nvar setInterval = global.setInterval;\nvar clearTimeout = global.clearTimeout;\nvar clearInterval = global.clearInterval;\n\nvar uncaughtExceptionHandlers = [];\n\nvar originalOnerrorHandler = global.onerror;\n\n/**\n * Remove uncaughtException listener.\n * Revert to original onerror handler if previously defined.\n */\n\nprocess.removeListener = function(e, fn){\n  if ('uncaughtException' == e) {\n    if (originalOnerrorHandler) {\n      global.onerror = originalOnerrorHandler;\n    } else {\n      global.onerror = function() {};\n    }\n    var i = Mocha.utils.indexOf(uncaughtExceptionHandlers, fn);\n    if (i != -1) { uncaughtExceptionHandlers.splice(i, 1); }\n  }\n};\n\n/**\n * Implements uncaughtException listener.\n */\n\nprocess.on = function(e, fn){\n  if ('uncaughtException' == e) {\n    global.onerror = function(err, url, line){\n      fn(new Error(err + ' (' + url + ':' + line + ')'));\n      return !mocha.allowUncaught;\n    };\n    uncaughtExceptionHandlers.push(fn);\n  }\n};\n\n// The BDD UI is registered by default, but no UI will be functional in the\n// browser without an explicit call to the overridden `mocha.ui` (see below).\n// Ensure that this default UI does not expose its methods to the global scope.\nmocha.suite.removeAllListeners('pre-require');\n\nvar immediateQueue = []\n  , immediateTimeout;\n\nfunction timeslice() {\n  var immediateStart = new Date().getTime();\n  while (immediateQueue.length && (new Date().getTime() - immediateStart) < 100) {\n    immediateQueue.shift()();\n  }\n  if (immediateQueue.length) {\n    immediateTimeout = setTimeout(timeslice, 0);\n  } else {\n    immediateTimeout = null;\n  }\n}\n\n/**\n * High-performance override of Runner.immediately.\n */\n\nMocha.Runner.immediately = function(callback) {\n  immediateQueue.push(callback);\n  if (!immediateTimeout) {\n    immediateTimeout = setTimeout(timeslice, 0);\n  }\n};\n\n/**\n * Function to allow assertion libraries to throw errors directly into mocha.\n * This is useful when running tests in a browser because window.onerror will\n * only receive the 'message' attribute of the Error.\n */\nmocha.throwError = function(err) {\n  Mocha.utils.forEach(uncaughtExceptionHandlers, function (fn) {\n    fn(err);\n  });\n  throw err;\n};\n\n/**\n * Override ui to ensure that the ui functions are initialized.\n * Normally this would happen in Mocha.prototype.loadFiles.\n */\n\nmocha.ui = function(ui){\n  Mocha.prototype.ui.call(this, ui);\n  this.suite.emit('pre-require', global, null, this);\n  return this;\n};\n\n/**\n * Setup mocha with the given setting options.\n */\n\nmocha.setup = function(opts){\n  if ('string' == typeof opts) opts = { ui: opts };\n  for (var opt in opts) this[opt](opts[opt]);\n  return this;\n};\n\n/**\n * Run mocha, returning the Runner.\n */\n\nmocha.run = function(fn){\n  var options = mocha.options;\n  mocha.globals('location');\n\n  var query = Mocha.utils.parseQuery(global.location.search || '');\n  if (query.grep) mocha.grep(new RegExp(query.grep));\n  if (query.fgrep) mocha.grep(query.fgrep);\n  if (query.invert) mocha.invert();\n\n  return Mocha.prototype.run.call(mocha, function(err){\n    // The DOM Document is not available in Web Workers.\n    var document = global.document;\n    if (document && document.getElementById('mocha') && options.noHighlighting !== true) {\n      Mocha.utils.highlightTags('code');\n    }\n    if (fn) fn(err);\n  });\n};\n\n/**\n * Expose the process shim.\n * https://github.com/mochajs/mocha/pull/916\n */\n\nMocha.process = process;\n\n/**\n * Expose mocha.\n */\n\nwindow.Mocha = Mocha;\nwindow.mocha = mocha;\n\n}).call(this,require('_process'),typeof global !== \"undefined\" ? global : typeof self !== \"undefined\" ? self : typeof window !== \"undefined\" ? window : {})\n},{\"../\":1,\"_process\":51,\"browser-stdout\":40}]},{},[70]);\n"
  },
  {
    "path": "app_frontend/static/plugin/JavaScript-Templates-3.8.0/.gitignore",
    "content": ".DS_Store\nnode_modules\n"
  },
  {
    "path": "app_frontend/static/plugin/JavaScript-Templates-3.8.0/.npmignore",
    "content": "*\n!js/*.js\n!js/*.js.map\n"
  },
  {
    "path": "app_frontend/static/plugin/JavaScript-Templates-3.8.0/.travis.yml",
    "content": "language: node_js\nnode_js:\n  - \"stable\"\n"
  },
  {
    "path": "app_frontend/static/plugin/JavaScript-Templates-3.8.0/README.md",
    "content": "# JavaScript Templates\n\n## Demo\n[JavaScript Templates Demo](https://blueimp.github.io/JavaScript-Templates/)\n\n## Description\n1KB lightweight, fast & powerful JavaScript templating engine with zero\ndependencies. Compatible with server-side environments like Node.js, module\nloaders like RequireJS, Browserify or webpack and all web browsers.\n\n## Usage\n\n### Client-side\nInclude the (minified) JavaScript Templates script in your HTML markup:\n\n```html\n<script src=\"js/tmpl.min.js\"></script>\n```\n\nAdd a script section with type **\"text/x-tmpl\"**, a unique **id** property and\nyour template definition as content:\n\n```html\n<script type=\"text/x-tmpl\" id=\"tmpl-demo\">\n<h3>{%=o.title%}</h3>\n<p>Released under the\n<a href=\"{%=o.license.url%}\">{%=o.license.name%}</a>.</p>\n<h4>Features</h4>\n<ul>\n{% for (var i=0; i<o.features.length; i++) { %}\n    <li>{%=o.features[i]%}</li>\n{% } %}\n</ul>\n</script>\n```\n\n**\"o\"** (the lowercase letter) is a reference to the data parameter of the\ntemplate function (see the API section on how to modify this identifier).\n\nIn your application code, create a JavaScript object to use as data for the\ntemplate:\n\n```js\nvar data = {\n    \"title\": \"JavaScript Templates\",\n    \"license\": {\n        \"name\": \"MIT license\",\n        \"url\": \"https://opensource.org/licenses/MIT\"\n    },\n    \"features\": [\n        \"lightweight & fast\",\n        \"powerful\",\n        \"zero dependencies\"\n    ]\n};\n```\n\nIn a real application, this data could be the result of retrieving a\n[JSON](http://json.org/) resource.\n\nRender the result by calling the **tmpl()** method with the id of the template\nand the data object as arguments:\n\n```js\ndocument.getElementById(\"result\").innerHTML = tmpl(\"tmpl-demo\", data);\n```\n\n### Server-side\n\nThe following is an example how to use the JavaScript Templates engine on the\nserver-side with [node.js](http://nodejs.org/).\n\nCreate a new directory and add the **tmpl.js** file. Or alternatively, install\nthe **blueimp-tmpl** package with [npm](https://www.npmjs.org/):\n\n```sh\nnpm install blueimp-tmpl\n```\n\nAdd a file **template.html** with the following content:\n\n```html\n<!DOCTYPE HTML>\n<title>{%=o.title%}</title>\n<h3><a href=\"{%=o.url%}\">{%=o.title%}</a></h3>\n<h4>Features</h4>\n<ul>\n{% for (var i=0; i<o.features.length; i++) { %}\n    <li>{%=o.features[i]%}</li>\n{% } %}\n</ul>\n```\n\nAdd a file **server.js** with the following content:\n\n```js\nrequire(\"http\").createServer(function (req, res) {\n    var fs = require(\"fs\"),\n        // The tmpl module exports the tmpl() function:\n        tmpl = require(\"./tmpl\"),\n        // Use the following version if you installed the package with npm:\n        // tmpl = require(\"blueimp-tmpl\"),\n        // Sample data:\n        data = {\n            \"title\": \"JavaScript Templates\",\n            \"url\": \"https://github.com/blueimp/JavaScript-Templates\",\n            \"features\": [\n                \"lightweight & fast\",\n                \"powerful\",\n                \"zero dependencies\"\n            ]\n        };\n    // Override the template loading method:\n    tmpl.load = function (id) {\n        var filename = id + \".html\";\n        console.log(\"Loading \" + filename);\n        return fs.readFileSync(filename, \"utf8\");\n    };\n    res.writeHead(200, {\"Content-Type\": \"text/x-tmpl\"});\n    // Render the content:\n    res.end(tmpl(\"template\", data));\n}).listen(8080, \"localhost\");\nconsole.log(\"Server running at http://localhost:8080/\");\n```\n\nRun the application with the following command:\n\n```sh\nnode server.js\n```\n\n## Requirements\nThe JavaScript Templates script has zero dependencies.\n\n## API\n\n### tmpl() function\nThe **tmpl()** function is added to the global **window** object and can be\ncalled as global function:\n\n```js\nvar result = tmpl(\"tmpl-demo\", data);\n```\n\nThe **tmpl()** function can be called with the id of a template, or with a\ntemplate string:\n\n```js\nvar result = tmpl(\"<h3>{%=o.title%}</h3>\", data);\n```\n\nIf called without second argument, **tmpl()** returns a reusable template\nfunction:\n\n```js\nvar func = tmpl(\"<h3>{%=o.title%}</h3>\");\ndocument.getElementById(\"result\").innerHTML = func(data);\n```\n\n### Templates cache\nTemplates loaded by id are cached in the map **tmpl.cache**:\n\n```js\nvar func = tmpl(\"tmpl-demo\"), // Loads and parses the template\n    cached = typeof tmpl.cache[\"tmpl-demo\"] === \"function\", // true\n    result = tmpl(\"tmpl-demo\", data); // Uses cached template function\n\ntmpl.cache[\"tmpl-demo\"] = null;\nresult = tmpl(\"tmpl-demo\", data); // Loads and parses the template again\n```\n\n### Output encoding\nThe method **tmpl.encode** is used to escape HTML special characters in the\ntemplate output:\n\n```js\nvar output = tmpl.encode(\"<>&\\\"'\\x00\"); // Renders \"&lt;&gt;&amp;&quot;&#39;\"\n```\n\n**tmpl.encode** makes use of the regular expression **tmpl.encReg** and the\nencoding map **tmpl.encMap** to match and replace special characters, which can\nbe modified to change the behavior of the output encoding.  \nStrings matched by the regular expression, but not found in the encoding map are\nremoved from the output. This allows for example to automatically trim input\nvalues (removing whitespace from the start and end of the string):\n\n```js\ntmpl.encReg = /(^\\s+)|(\\s+$)|[<>&\"'\\x00]/g;\nvar output = tmpl.encode(\"    Banana!    \"); // Renders \"Banana\" (without whitespace)\n```\n\n### Local helper variables\nThe local variables available inside the templates are the following:\n\n* **o**: The data object given as parameter to the template function\n(see the next section on how to modify the parameter name).\n* **tmpl**: A reference to the **tmpl** function object.\n* **_s**: The string for the rendered result content.\n* **_e**: A reference to the **tmpl.encode** method.\n* **print**: Helper function to add content to the rendered result string.\n* **include**: Helper function to include the return value of a different\ntemplate in the result.\n\nTo introduce additional local helper variables, the string **tmpl.helper** can\nbe extended. The following adds a convenience function for *console.log* and a\nstreaming function, that streams the template rendering result back to the\ncallback argument\n(note the comma at the beginning of each variable declaration):\n\n```js\ntmpl.helper += \",log=function(){console.log.apply(console, arguments)}\" +\n    \",st='',stream=function(cb){var l=st.length;st=_s;cb( _s.slice(l));}\";\n```\n\nThose new helper functions could be used to stream the template contents to the\nconsole output:\n\n```html\n<script type=\"text/x-tmpl\" id=\"tmpl-demo\">\n<h3>{%=o.title%}</h3>\n{% stream(log); %}\n<p>Released under the\n<a href=\"{%=o.license.url%}\">{%=o.license.name%}</a>.</p>\n{% stream(log); %}\n<h4>Features</h4>\n<ul>\n{% stream(log); %}\n{% for (var i=0; i<o.features.length; i++) { %}\n    <li>{%=o.features[i]%}</li>\n    {% stream(log); %}\n{% } %}\n</ul>\n{% stream(log); %}\n</script>\n```\n\n### Template function argument\nThe generated template functions accept one argument, which is the data object\ngiven to the **tmpl(id, data)** function. This argument is available inside the\ntemplate definitions as parameter **o** (the lowercase letter).\n\nThe argument name can be modified by overriding **tmpl.arg**:\n\n```js\ntmpl.arg = \"p\";\n\n// Renders \"<h3>JavaScript Templates</h3>\":\nvar result = tmpl(\"<h3>{%=p.title%}</h3>\", {title: \"JavaScript Templates\"});\n```\n\n### Template parsing\nThe template contents are matched and replaced using the regular expression\n**tmpl.regexp** and the replacement function **tmpl.func**.\nThe replacement function operates based on the\n[parenthesized submatch strings](https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/String/replace#Specifying_a_function_as_a_parameter).\n\nTo use different tags for the template syntax, override **tmpl.regexp** with a\nmodified regular expression, by exchanging all occurrences of \"{%\" and \"%}\",\ne.g. with \"[%\" and \"%]\":\n\n```js\ntmpl.regexp = /([\\s'\\\\])(?!(?:[^[]|\\[(?!%))*%\\])|(?:\\[%(=|#)([\\s\\S]+?)%\\])|(\\[%)|(%\\])/g;\n```\n\nBy default, the plugin preserves whitespace\n(newlines, carriage returns, tabs and spaces).\nTo strip unnecessary whitespace, you can override the **tmpl.func** function,\ne.g. with the following code:\n\n```js\nvar originalFunc = tmpl.func;\ntmpl.func = function (s, p1, p2, p3, p4, p5, offset, str) {\n    if (p1 && /\\s/.test(p1)) {\n        if (!offset || /\\s/.test(str.charAt(offset - 1)) ||\n                /^\\s+$/g.test(str.slice(offset))) {\n            return '';\n        }\n        return ' ';\n    }\n    return originalFunc.apply(tmpl, arguments);\n};\n```\n\n## Templates syntax\n\n### Interpolation\nPrint variable with HTML special characters escaped:\n\n```html\n<h3>{%=o.title%}</h3>\n```\n\nPrint variable without escaping:\n\n```html\n<h3>{%#o.user_id%}</h3>\n```\n\nPrint output of function calls:\n\n```html\n<a href=\"{%=encodeURI(o.url)%}\">Website</a>\n```\n\nUse dot notation to print nested properties:\n\n```html\n<strong>{%=o.author.name%}</strong>\n```\n\n### Evaluation\nUse **print(str)** to add escaped content to the output:\n\n```html\n<span>Year: {% var d=new Date(); print(d.getFullYear()); %}</span>\n```\n\nUse **print(str, true)** to add unescaped content to the output:\n\n```html\n<span>{% print(\"Fast &amp; powerful\", true); %}</span>\n```\n\nUse **include(str, obj)** to include content from a different template:\n\n```html\n<div>\n{% include('tmpl-link', {name: \"Website\", url: \"https://example.org\"}); %}\n</div>\n```\n\n**If else condition**:\n\n```html\n{% if (o.author.url) { %}\n    <a href=\"{%=encodeURI(o.author.url)%}\">{%=o.author.name%}</a>\n{% } else { %}\n    <em>No author url.</em>\n{% } %}\n```\n\n**For loop**:\n\n```html\n<ul>\n{% for (var i=0; i<o.features.length; i++) { %}\n    <li>{%=o.features[i]%}</li>\n{% } %}\n</ul>\n```\n\n## Compiled templates\nThe JavaScript Templates project comes with a compilation script, that allows\nyou to compile your templates into JavaScript code and combine them with a\nminimal Templates runtime into one combined JavaScript file.\n\nThe compilation script is built for [node.js](http://nodejs.org/).  \nTo use it, first install the JavaScript Templates project via\n[npm](https://www.npmjs.org/):\n\n```sh\nnpm install blueimp-tmpl\n```\n\nThis will put the executable **tmpl.js** into the folder **node_modules/.bin**.\nIt will also make it available on your PATH if you install the package globally\n(by adding the **-g** flag to the install command).\n\nThe **tmpl.js** executable accepts the paths to one or multiple template files\nas command line arguments and prints the generated JavaScript code to the\nconsole output. The following command line shows you how to store the generated\ncode in a new JavaScript file that can be included in your project:\n\n```sh\ntmpl.js index.html > tmpl.js\n```\n\nThe files given as command line arguments to **tmpl.js** can either be pure\ntemplate files or HTML documents with embedded template script sections.\nFor the pure template files, the file names (without extension) serve as\ntemplate ids.  \nThe generated file can be included in your project as a replacement for the\noriginal **tmpl.js** runtime. It provides you with the same API and provides a\n**tmpl(id, data)** function that accepts the id of one of your templates as\nfirst and a data object as optional second parameter.\n\n## Tests\nThe JavaScript Templates project comes with\n[Unit Tests](https://en.wikipedia.org/wiki/Unit_testing).  \nThere are two different ways to run the tests:\n\n* Open test/index.html in your browser or\n* run `npm test` in the Terminal in the root path of the repository package.\n\nThe first one tests the browser integration,\nthe second one the [node.js](http://nodejs.org/) integration.\n\n## License\nThe JavaScript Templates script is released under the\n[MIT license](https://opensource.org/licenses/MIT).\n"
  },
  {
    "path": "app_frontend/static/plugin/JavaScript-Templates-3.8.0/css/demo.css",
    "content": "/*\n * JavaScript Templates Demo CSS\n * https://github.com/blueimp/JavaScript-Templates\n *\n * Copyright 2013, Sebastian Tschan\n * https://blueimp.net\n *\n * Licensed under the MIT license:\n * https://opensource.org/licenses/MIT\n */\n\nbody {\n  max-width: 750px;\n  margin: 0 auto;\n  padding: 1em;\n  font-family: 'Lucida Grande', 'Lucida Sans Unicode', Arial, sans-serif;\n  font-size: 1em;\n  line-height: 1.4em;\n  background: #222;\n  color: #fff;\n  -webkit-text-size-adjust: 100%;\n      -ms-text-size-adjust: 100%;\n}\na {\n  color: orange;\n  text-decoration: none;\n}\nimg {\n  border: 0;\n  vertical-align: middle;\n}\nh1 {\n  line-height: 1em;\n}\ntextarea,\ninput {\n  display: inline-block;\n  width: 100%;\n  -webkit-box-sizing: border-box;\n     -moz-box-sizing: border-box;\n          box-sizing: border-box;\n  padding: 10px;\n  margin: 0 0 10px;\n  font-family: \"Lucida Console\", Monaco, monospace;\n}\n.result {\n  padding: 20px 40px;\n  background: #fff;\n  color: #222;\n}\n.error {\n  color: red;\n}\n\n@media (min-width: 481px) {\n  .navigation {\n    list-style: none;\n    padding: 0;\n  }\n  .navigation li {\n    display: inline-block;\n  }\n  .navigation li:not(:first-child):before {\n    content: '| ';\n  }\n}\n\n/* IE7 fixes */\n*+html textarea,\n*+html input {\n  width: 460px;\n}\n*+html .result {\n  width: 400px;\n}\n"
  },
  {
    "path": "app_frontend/static/plugin/JavaScript-Templates-3.8.0/index.html",
    "content": "<!DOCTYPE HTML>\n<!--\n/*\n * JavaScript Templates Demo\n * https://github.com/blueimp/JavaScript-Templates\n *\n * Copyright 2011, Sebastian Tschan\n * https://blueimp.net\n *\n * Licensed under the MIT license:\n * https://opensource.org/licenses/MIT\n */\n-->\n<html lang=\"en\">\n<head>\n<!--[if IE]>\n<meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge,chrome=1\">\n<![endif]-->\n<meta charset=\"utf-8\">\n<title>JavaScript Templates Demo</title>\n<meta name=\"description\" content=\"1KB lightweight, fast &amp; powerful JavaScript templating engine with zero dependencies. Compatible with server-side environments like Node.js, module loaders like RequireJS, Browserify or webpack and all web browsers.\">\n<meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n<link rel=\"stylesheet\" href=\"css/demo.css\">\n</head>\n<body>\n<h1>JavaScript Templates Demo</h1>\n<p><strong>1KB</strong> lightweight, fast &amp; powerful <a href=\"https://developer.mozilla.org/en/JavaScript/\">JavaScript</a> templating engine with zero dependencies.<br>\nCompatible with server-side environments like <a href=\"http://nodejs.org/\">Node.js</a>, module loaders like <a href=\"http://requirejs.org/\">RequireJS</a>, <a href=\"http://browserify.org/\">Browserify</a> or <a href=\"https://webpack.github.io/\">webpack</a> and all web browsers.</p>\n<ul class=\"navigation\">\n    <li><a href=\"https://github.com/blueimp/JavaScript-Templates/tags\">Download</a></li>\n    <li><a href=\"https://github.com/blueimp/JavaScript-Templates\">Source Code</a></li>\n    <li><a href=\"https://github.com/blueimp/JavaScript-Templates/blob/master/README.md\">Documentation</a></li>\n    <li><a href=\"test/\">Test</a></li>\n    <li><a href=\"https://blueimp.net\">&copy; Sebastian Tschan</a></li>\n</ul>\n<form>\n    <h2>Template</h2>\n    <textarea rows=\"12\" id=\"template\"></textarea>\n    <br>\n    <h2>Data (JSON)</h2>\n    <textarea rows=\"14\" id=\"data\"></textarea>\n    <br>\n    <button type=\"submit\" id=\"render\">Render</button>\n    <button type=\"reset\" id=\"reset\">Reset</button>\n    <h2>Result</h2>\n    <div id=\"result\" class=\"result\"></div>\n    <br>\n</form>\n<script type=\"text/x-tmpl\" id=\"tmpl-demo\">\n<h3>{%=o.title%}</h3>\n<p>Released under the\n<a href=\"{%=o.license.url%}\">{%=o.license.name%}</a>.</p>\n<h4>Features</h4>\n<ul>\n{% for (var i=0; i<o.features.length; i++) { %}\n    <li>{%=o.features[i]%}</li>\n{% } %}\n</ul>\n</script>\n<script type=\"text/x-tmpl\" id=\"tmpl-data\">\n{\n    \"title\": \"JavaScript Templates\",\n    \"license\": {\n        \"name\": \"MIT license\",\n        \"url\": \"https://opensource.org/licenses/MIT\"\n    },\n    \"features\": [\n        \"lightweight & fast\",\n        \"powerful\",\n        \"zero dependencies\"\n    ]\n}\n</script>\n<script type=\"text/x-tmpl\" id=\"tmpl-error\">\n<h3 class=\"error\">{%=o.title%}</h3>\n<code>{%=o.error%}</code>\n</script>\n<script src=\"js/tmpl.js\"></script>\n<script src=\"js/demo/demo.js\"></script>\n</body>\n</html>\n"
  },
  {
    "path": "app_frontend/static/plugin/JavaScript-Templates-3.8.0/js/compile.js",
    "content": "#!/usr/bin/env node\n/*\n * JavaScript Templates Compiler\n * https://github.com/blueimp/JavaScript-Templates\n *\n * Copyright 2011, Sebastian Tschan\n * https://blueimp.net\n *\n * Licensed under the MIT license:\n * https://opensource.org/licenses/MIT\n */\n\n;(function () {\n  'use strict'\n  var path = require('path')\n  var tmpl = require(path.join(__dirname, 'tmpl.js'))\n  var fs = require('fs')\n  // Retrieve the content of the minimal runtime:\n  var runtime = fs.readFileSync(path.join(__dirname, 'runtime.js'), 'utf8')\n  // A regular expression to parse templates from script tags in a HTML page:\n  var regexp = /<script( id=\"([\\w\\-]+)\")? type=\"text\\/x-tmpl\"( id=\"([\\w\\-]+)\")?>([\\s\\S]+?)<\\/script>/gi\n  // A regular expression to match the helper function names:\n  var helperRegexp = new RegExp(\n    tmpl.helper.match(/\\w+(?=\\s*=\\s*function\\s*\\()/g).join('\\\\s*\\\\(|') + '\\\\s*\\\\('\n  )\n  // A list to store the function bodies:\n  var list = []\n  var code\n  // Extend the Templating engine with a print method for the generated functions:\n  tmpl.print = function (str) {\n    // Only add helper functions if they are used inside of the template:\n    var helper = helperRegexp.test(str) ? tmpl.helper : ''\n    var body = str.replace(tmpl.regexp, tmpl.func)\n    if (helper || (/_e\\s*\\(/.test(body))) {\n      helper = '_e=tmpl.encode' + helper + ','\n    }\n    return 'function(' + tmpl.arg + ',tmpl){' +\n    ('var ' + helper + \"_s='\" + body + \"';return _s;\")\n      .split(\"_s+='';\").join('') + '}'\n  }\n  // Loop through the command line arguments:\n  process.argv.forEach(function (file, index) {\n    var listLength = list.length\n    var stats\n    var content\n    var result\n    var id\n    // Skip the first two arguments, which are \"node\" and the script:\n    if (index > 1) {\n      stats = fs.statSync(file)\n      if (!stats.isFile()) {\n        console.error(file + ' is not a file.')\n        return\n      }\n      content = fs.readFileSync(file, 'utf8')\n      while (true) {\n        // Find templates in script tags:\n        result = regexp.exec(content)\n        if (!result) {\n          break\n        }\n        id = result[2] || result[4]\n        list.push(\"'\" + id + \"':\" + tmpl.print(result[5]))\n      }\n      if (listLength === list.length) {\n        // No template script tags found, use the complete content:\n        id = path.basename(file, path.extname(file))\n        list.push(\"'\" + id + \"':\" + tmpl.print(content))\n      }\n    }\n  })\n  if (!list.length) {\n    console.error('Missing input file.')\n    return\n  }\n  // Combine the generated functions as cache of the minimal runtime:\n  code = runtime.replace('{}', '{' + list.join(',') + '}')\n  // Print the resulting code to the console output:\n  console.log(code)\n}())\n"
  },
  {
    "path": "app_frontend/static/plugin/JavaScript-Templates-3.8.0/js/demo/demo.js",
    "content": "/*\n * JavaScript Templates Demo\n * https://github.com/blueimp/JavaScript-Templates\n *\n * Copyright 2013, Sebastian Tschan\n * https://blueimp.net\n *\n * Licensed under the MIT license:\n * https://opensource.org/licenses/MIT\n */\n\n/* global tmpl */\n\n;(function () {\n  'use strict'\n\n  var templateInput = document.getElementById('template')\n  var dataInput = document.getElementById('data')\n  var resultNode = document.getElementById('result')\n  var templateDemoNode = document.getElementById('tmpl-demo')\n  var templateDataNode = document.getElementById('tmpl-data')\n\n  function renderError (title, error) {\n    resultNode.innerHTML = tmpl(\n      'tmpl-error',\n      {title: title, error: error}\n    )\n  }\n\n  function render (event) {\n    event.preventDefault()\n    var data\n    try {\n      data = JSON.parse(dataInput.value)\n    } catch (e) {\n      renderError('JSON parsing failed', e)\n      return\n    }\n    try {\n      resultNode.innerHTML = tmpl(\n        templateInput.value,\n        data\n      )\n    } catch (e) {\n      renderError('Template rendering failed', e)\n    }\n  }\n\n  function empty (node) {\n    while (node.lastChild) {\n      node.removeChild(node.lastChild)\n    }\n  }\n\n  function init (event) {\n    if (event) {\n      event.preventDefault()\n    }\n    templateInput.value = templateDemoNode.innerHTML.trim()\n    dataInput.value = templateDataNode.innerHTML.trim()\n    empty(resultNode)\n  }\n\n  document.getElementById('render').addEventListener('click', render)\n  document.getElementById('reset').addEventListener('click', init)\n\n  init()\n}())\n"
  },
  {
    "path": "app_frontend/static/plugin/JavaScript-Templates-3.8.0/js/runtime.js",
    "content": "/*\n * JavaScript Templates Runtime\n * https://github.com/blueimp/JavaScript-Templates\n *\n * Copyright 2011, Sebastian Tschan\n * https://blueimp.net\n *\n * Licensed under the MIT license:\n * https://opensource.org/licenses/MIT\n */\n\n/* global define */\n\n;(function ($) {\n  'use strict'\n  var tmpl = function (id, data) {\n    var f = tmpl.cache[id]\n    return data ? f(data, tmpl) : function (data) {\n      return f(data, tmpl)\n    }\n  }\n  tmpl.cache = {}\n  tmpl.encReg = /[<>&\"'\\x00]/g // eslint-disable-line no-control-regex\n  tmpl.encMap = {\n    '<': '&lt;',\n    '>': '&gt;',\n    '&': '&amp;',\n    '\"': '&quot;',\n    \"'\": '&#39;'\n  }\n  tmpl.encode = function (s) {\n    return (s == null ? '' : '' + s).replace(\n      tmpl.encReg,\n      function (c) {\n        return tmpl.encMap[c] || ''\n      }\n    )\n  }\n  if (typeof define === 'function' && define.amd) {\n    define(function () {\n      return tmpl\n    })\n  } else if (typeof module === 'object' && module.exports) {\n    module.exports = tmpl\n  } else {\n    $.tmpl = tmpl\n  }\n}(this))\n"
  },
  {
    "path": "app_frontend/static/plugin/JavaScript-Templates-3.8.0/js/tmpl.js",
    "content": "/*\n * JavaScript Templates\n * https://github.com/blueimp/JavaScript-Templates\n *\n * Copyright 2011, Sebastian Tschan\n * https://blueimp.net\n *\n * Licensed under the MIT license:\n * https://opensource.org/licenses/MIT\n *\n * Inspired by John Resig's JavaScript Micro-Templating:\n * http://ejohn.org/blog/javascript-micro-templating/\n */\n\n/* global define */\n\n;(function ($) {\n  'use strict'\n  var tmpl = function (str, data) {\n    var f = !/[^\\w\\-\\.:]/.test(str)\n      ? tmpl.cache[str] = tmpl.cache[str] || tmpl(tmpl.load(str))\n      : new Function(// eslint-disable-line no-new-func\n        tmpl.arg + ',tmpl',\n        'var _e=tmpl.encode' + tmpl.helper + \",_s='\" +\n          str.replace(tmpl.regexp, tmpl.func) + \"';return _s;\"\n      )\n    return data ? f(data, tmpl) : function (data) {\n      return f(data, tmpl)\n    }\n  }\n  tmpl.cache = {}\n  tmpl.load = function (id) {\n    return document.getElementById(id).innerHTML\n  }\n  tmpl.regexp = /([\\s'\\\\])(?!(?:[^{]|\\{(?!%))*%\\})|(?:\\{%(=|#)([\\s\\S]+?)%\\})|(\\{%)|(%\\})/g\n  tmpl.func = function (s, p1, p2, p3, p4, p5) {\n    if (p1) { // whitespace, quote and backspace in HTML context\n      return {\n        '\\n': '\\\\n',\n        '\\r': '\\\\r',\n        '\\t': '\\\\t',\n        ' ': ' '\n      }[p1] || '\\\\' + p1\n    }\n    if (p2) { // interpolation: {%=prop%}, or unescaped: {%#prop%}\n      if (p2 === '=') {\n        return \"'+_e(\" + p3 + \")+'\"\n      }\n      return \"'+(\" + p3 + \"==null?'':\" + p3 + \")+'\"\n    }\n    if (p4) { // evaluation start tag: {%\n      return \"';\"\n    }\n    if (p5) { // evaluation end tag: %}\n      return \"_s+='\"\n    }\n  }\n  tmpl.encReg = /[<>&\"'\\x00]/g // eslint-disable-line no-control-regex\n  tmpl.encMap = {\n    '<': '&lt;',\n    '>': '&gt;',\n    '&': '&amp;',\n    '\"': '&quot;',\n    \"'\": '&#39;'\n  }\n  tmpl.encode = function (s) {\n    return (s == null ? '' : '' + s).replace(\n      tmpl.encReg,\n      function (c) {\n        return tmpl.encMap[c] || ''\n      }\n    )\n  }\n  tmpl.arg = 'o'\n  tmpl.helper = \",print=function(s,e){_s+=e?(s==null?'':s):_e(s);}\" +\n                  ',include=function(s,d){_s+=tmpl(s,d);}'\n  if (typeof define === 'function' && define.amd) {\n    define(function () {\n      return tmpl\n    })\n  } else if (typeof module === 'object' && module.exports) {\n    module.exports = tmpl\n  } else {\n    $.tmpl = tmpl\n  }\n}(this))\n"
  },
  {
    "path": "app_frontend/static/plugin/JavaScript-Templates-3.8.0/package.json",
    "content": "{\n  \"name\": \"blueimp-tmpl\",\n  \"version\": \"3.8.0\",\n  \"title\": \"JavaScript Templates\",\n  \"description\": \"1KB lightweight, fast & powerful JavaScript templating engine with zero dependencies. Compatible with server-side environments like Node.js, module loaders like RequireJS, Browserify or webpack and all web browsers.\",\n  \"keywords\": [\n    \"javascript\",\n    \"templates\",\n    \"templating\"\n  ],\n  \"homepage\": \"https://github.com/blueimp/JavaScript-Templates\",\n  \"author\": {\n    \"name\": \"Sebastian Tschan\",\n    \"url\": \"https://blueimp.net\"\n  },\n  \"repository\": {\n    \"type\": \"git\",\n    \"url\": \"git://github.com/blueimp/JavaScript-Templates.git\"\n  },\n  \"license\": \"MIT\",\n  \"devDependencies\": {\n    \"chai\": \"3.5.0\",\n    \"mocha\": \"3.1.0\",\n    \"standard\": \"8.3.0\",\n    \"uglify-js\": \"2.7.3\"\n  },\n  \"scripts\": {\n    \"lint\": \"standard js/*.js test/*.js\",\n    \"unit\": \"mocha\",\n    \"test\": \"npm run lint && npm run unit\",\n    \"build\": \"cd js && uglifyjs tmpl.js -c -m -o tmpl.min.js --source-map tmpl.min.js.map\",\n    \"preversion\": \"npm test\",\n    \"version\": \"npm run build && git add -A js\",\n    \"postversion\": \"git push --tags origin master master:gh-pages && npm publish\"\n  },\n  \"bin\": {\n    \"tmpl.js\": \"js/compile.js\"\n  },\n  \"main\": \"js/tmpl.js\"\n}\n"
  },
  {
    "path": "app_frontend/static/plugin/JavaScript-Templates-3.8.0/test/index.html",
    "content": "<!DOCTYPE HTML>\n<!--\n/*\n * JavaScript Templates Test\n * https://github.com/blueimp/JavaScript-Templates\n *\n * Copyright 2011, Sebastian Tschan\n * https://blueimp.net\n *\n * Licensed under the MIT license:\n * https://opensource.org/licenses/MIT\n */\n-->\n<html lang=\"en\">\n<head>\n<!--[if IE]>\n<meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge,chrome=1\">\n<![endif]-->\n<meta charset=\"utf-8\">\n<title>JavaScript Templates Test</title>\n<meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n<link rel=\"stylesheet\" href=\"vendor/mocha.css\">\n</head>\n<body>\n<div id=\"mocha\"></div>\n<script src=\"vendor/mocha.js\"></script>\n<script src=\"vendor/chai.js\"></script>\n<script>\nmocha.setup('bdd');\n</script>\n<script type=\"text/x-tmpl\" id=\"template\">{%=o.value%}</script>\n<script src=\"../js/tmpl.js\"></script>\n<script src=\"test.js\"></script>\n<script>\nmocha.checkLeaks();\nmocha.run();\n</script>\n</body>\n</html>\n"
  },
  {
    "path": "app_frontend/static/plugin/JavaScript-Templates-3.8.0/test/test.js",
    "content": "/*\n * JavaScript Templates Test\n * https://github.com/blueimp/JavaScript-Templates\n *\n * Copyright 2011, Sebastian Tschan\n * https://blueimp.net\n *\n * Licensed under the MIT license:\n * https://opensource.org/licenses/MIT\n */\n\n/* global beforeEach, afterEach, describe, it */\n\n;(function (context, expect, tmpl) {\n  'use strict'\n\n  if (context.require === undefined) {\n    // Override the template loading method:\n    tmpl.load = function (id) {\n      switch (id) {\n        case 'template':\n          return '{%=o.value%}'\n      }\n    }\n  }\n\n  var data\n\n  beforeEach(function () {\n    // Initialize the sample data:\n    data = {\n      value: 'value',\n      nullValue: null,\n      falseValue: false,\n      zeroValue: 0,\n      special: '<>&\"\\'\\x00',\n      list: [1, 2, 3, 4, 5],\n      func: function () {\n        return this.value\n      },\n      deep: {\n        value: 'value'\n      }\n    }\n  })\n\n  afterEach(function () {\n    // Purge the template cache:\n    tmpl.cache = {}\n  })\n\n  describe('Template loading', function () {\n    it('String template', function () {\n      expect(\n        tmpl('{%=o.value%}', data)\n      ).to.equal(\n        'value'\n      )\n    })\n\n    it('Load template by id', function () {\n      expect(\n        tmpl('template', data)\n      ).to.equal(\n        'value'\n      )\n    })\n\n    it('Retun function when called without data parameter', function () {\n      expect(\n        tmpl('{%=o.value%}')(data)\n      ).to.equal(\n        'value'\n      )\n    })\n\n    it('Cache templates loaded by id', function () {\n      tmpl('template')\n      expect(\n        tmpl.cache.template\n      ).to.be.a('function')\n    })\n  })\n\n  describe('Interpolation', function () {\n    it('Escape HTML special characters with {%=o.prop%}', function () {\n      expect(\n        tmpl('{%=o.special%}', data)\n      ).to.equal(\n        '&lt;&gt;&amp;&quot;&#39;'\n      )\n    })\n\n    it('Allow HTML special characters with {%#o.prop%}', function () {\n      expect(\n        tmpl('{%#o.special%}', data)\n      ).to.equal(\n        '<>&\"\\'\\x00'\n      )\n    })\n\n    it('Function call', function () {\n      expect(\n        tmpl('{%=o.func()%}', data)\n      ).to.equal(\n        'value'\n      )\n    })\n\n    it('Dot notation', function () {\n      expect(\n        tmpl('{%=o.deep.value%}', data)\n      ).to.equal(\n        'value'\n      )\n    })\n\n    it('Handle single quotes', function () {\n      expect(\n        tmpl('\\'single quotes\\'{%=\": \\'\"%}', data)\n      ).to.equal(\n        \"'single quotes': &#39;\"\n      )\n    })\n\n    it('Handle double quotes', function () {\n      expect(\n        tmpl('\"double quotes\"{%=\": \\\\\"\"%}', data)\n      ).to.equal(\n        '\"double quotes\": &quot;'\n      )\n    })\n\n    it('Handle backslashes', function () {\n      expect(\n        tmpl('\\\\backslashes\\\\{%=\": \\\\\\\\\"%}', data)\n      ).to.equal(\n        '\\\\backslashes\\\\: \\\\'\n      )\n    })\n\n    it('Interpolate escaped falsy values except undefined or null', function () {\n      expect(\n        tmpl(\n          '{%=o.undefinedValue%}' +\n          '{%=o.nullValue%}' +\n          '{%=o.falseValue%}' +\n          '{%=o.zeroValue%}',\n          data\n        )\n      ).to.equal(\n        'false0'\n      )\n    })\n\n    it('Interpolate unescaped falsy values except undefined or null', function () {\n      expect(\n        tmpl(\n          '{%#o.undefinedValue%}' +\n          '{%#o.nullValue%}' +\n          '{%#o.falseValue%}' +\n          '{%#o.zeroValue%}',\n          data\n        )\n      ).to.equal(\n        'false0'\n      )\n    })\n\n    it('Preserve whitespace', function () {\n      expect(\n        tmpl(\n          '\\n\\r\\t{%=o.value%}  \\n\\r\\t{%=o.value%}  ',\n          data\n        )\n      ).to.equal(\n        '\\n\\r\\tvalue  \\n\\r\\tvalue  '\n      )\n    })\n  })\n\n  describe('Evaluation', function () {\n    it('Escape HTML special characters with print(data)', function () {\n      expect(\n        tmpl('{% print(o.special); %}', data)\n      ).to.equal(\n        '&lt;&gt;&amp;&quot;&#39;'\n      )\n    })\n\n    it('Allow HTML special characters with print(data, true)', function () {\n      expect(\n        tmpl('{% print(o.special, true); %}', data)\n      ).to.equal(\n        '<>&\"\\'\\x00'\n      )\n    })\n\n    it('Print out escaped falsy values except undefined or null', function () {\n      expect(\n        tmpl(\n          '{% print(o.undefinedValue); %}' +\n          '{% print(o.nullValue); %}' +\n          '{% print(o.falseValue); %}' +\n          '{% print(o.zeroValue); %}',\n          data\n        )\n      ).to.equal(\n        'false0'\n      )\n    })\n\n    it('Print out unescaped falsy values except undefined or null', function () {\n      expect(\n        tmpl(\n          '{% print(o.undefinedValue, true); %}' +\n          '{% print(o.nullValue, true); %}' +\n          '{% print(o.falseValue, true); %}' +\n          '{% print(o.zeroValue, true); %}',\n          data\n        )\n      ).to.equal(\n        'false0'\n      )\n    })\n\n    it('Include template', function () {\n      expect(\n        tmpl('{% include(\"template\", {value: \"value\"}); %}', data)\n      ).to.equal(\n        'value'\n      )\n    })\n\n    it('If condition', function () {\n      expect(\n        tmpl('{% if (o.value) { %}true{% } else { %}false{% } %}', data)\n      ).to.equal(\n        'true'\n      )\n    })\n\n    it('Else condition', function () {\n      expect(\n        tmpl(\n          '{% if (o.undefinedValue) { %}false{% } else { %}true{% } %}',\n          data\n        )\n      ).to.equal(\n        'true'\n      )\n    })\n\n    it('For loop', function () {\n      expect(\n        tmpl(\n          '{% for (var i=0; i<o.list.length; i++) { %}' +\n          '{%=o.list[i]%}{% } %}',\n          data\n        )\n      ).to.equal(\n        '12345'\n      )\n    })\n\n    it('For loop print call', function () {\n      expect(\n        tmpl(\n          '{% for (var i=0; i<o.list.length; i++) {' +\n          'print(o.list[i]);} %}',\n          data\n        )\n      ).to.equal(\n        '12345'\n      )\n    })\n\n    it('For loop include template', function () {\n      expect(\n        tmpl(\n          '{% for (var i=0; i<o.list.length; i++) {' +\n          'include(\"template\", {value: o.list[i]});} %}',\n          data\n        ).replace(/[\\r\\n]/g, '')\n      ).to.equal(\n        '12345'\n      )\n    })\n\n    it('Modulo operator', function () {\n      expect(\n        tmpl(\n          '{% if (o.list.length % 5 === 0) { %}5 list items{% } %}',\n          data\n        ).replace(/[\\r\\n]/g, '')\n      ).to.equal(\n        '5 list items'\n      )\n    })\n  })\n}(\n  this,\n  (this.chai || require('chai')).expect,\n  this.tmpl || require('../js/tmpl')\n))\n"
  },
  {
    "path": "app_frontend/static/plugin/JavaScript-Templates-3.8.0/test/vendor/chai.js",
    "content": "(function(f){if(typeof exports===\"object\"&&typeof module!==\"undefined\"){module.exports=f()}else if(typeof define===\"function\"&&define.amd){define([],f)}else{var g;if(typeof window!==\"undefined\"){g=window}else if(typeof global!==\"undefined\"){g=global}else if(typeof self!==\"undefined\"){g=self}else{g=this}g.chai = f()}})(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require==\"function\"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error(\"Cannot find module '\"+o+\"'\");throw f.code=\"MODULE_NOT_FOUND\",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require==\"function\"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){\nmodule.exports = require('./lib/chai');\n\n},{\"./lib/chai\":2}],2:[function(require,module,exports){\n/*!\n * chai\n * Copyright(c) 2011-2014 Jake Luer <jake@alogicalparadox.com>\n * MIT Licensed\n */\n\nvar used = []\n  , exports = module.exports = {};\n\n/*!\n * Chai version\n */\n\nexports.version = '3.5.0';\n\n/*!\n * Assertion Error\n */\n\nexports.AssertionError = require('assertion-error');\n\n/*!\n * Utils for plugins (not exported)\n */\n\nvar util = require('./chai/utils');\n\n/**\n * # .use(function)\n *\n * Provides a way to extend the internals of Chai\n *\n * @param {Function}\n * @returns {this} for chaining\n * @api public\n */\n\nexports.use = function (fn) {\n  if (!~used.indexOf(fn)) {\n    fn(this, util);\n    used.push(fn);\n  }\n\n  return this;\n};\n\n/*!\n * Utility Functions\n */\n\nexports.util = util;\n\n/*!\n * Configuration\n */\n\nvar config = require('./chai/config');\nexports.config = config;\n\n/*!\n * Primary `Assertion` prototype\n */\n\nvar assertion = require('./chai/assertion');\nexports.use(assertion);\n\n/*!\n * Core Assertions\n */\n\nvar core = require('./chai/core/assertions');\nexports.use(core);\n\n/*!\n * Expect interface\n */\n\nvar expect = require('./chai/interface/expect');\nexports.use(expect);\n\n/*!\n * Should interface\n */\n\nvar should = require('./chai/interface/should');\nexports.use(should);\n\n/*!\n * Assert interface\n */\n\nvar assert = require('./chai/interface/assert');\nexports.use(assert);\n\n},{\"./chai/assertion\":3,\"./chai/config\":4,\"./chai/core/assertions\":5,\"./chai/interface/assert\":6,\"./chai/interface/expect\":7,\"./chai/interface/should\":8,\"./chai/utils\":22,\"assertion-error\":30}],3:[function(require,module,exports){\n/*!\n * chai\n * http://chaijs.com\n * Copyright(c) 2011-2014 Jake Luer <jake@alogicalparadox.com>\n * MIT Licensed\n */\n\nvar config = require('./config');\n\nmodule.exports = function (_chai, util) {\n  /*!\n   * Module dependencies.\n   */\n\n  var AssertionError = _chai.AssertionError\n    , flag = util.flag;\n\n  /*!\n   * Module export.\n   */\n\n  _chai.Assertion = Assertion;\n\n  /*!\n   * Assertion Constructor\n   *\n   * Creates object for chaining.\n   *\n   * @api private\n   */\n\n  function Assertion (obj, msg, stack) {\n    flag(this, 'ssfi', stack || arguments.callee);\n    flag(this, 'object', obj);\n    flag(this, 'message', msg);\n  }\n\n  Object.defineProperty(Assertion, 'includeStack', {\n    get: function() {\n      console.warn('Assertion.includeStack is deprecated, use chai.config.includeStack instead.');\n      return config.includeStack;\n    },\n    set: function(value) {\n      console.warn('Assertion.includeStack is deprecated, use chai.config.includeStack instead.');\n      config.includeStack = value;\n    }\n  });\n\n  Object.defineProperty(Assertion, 'showDiff', {\n    get: function() {\n      console.warn('Assertion.showDiff is deprecated, use chai.config.showDiff instead.');\n      return config.showDiff;\n    },\n    set: function(value) {\n      console.warn('Assertion.showDiff is deprecated, use chai.config.showDiff instead.');\n      config.showDiff = value;\n    }\n  });\n\n  Assertion.addProperty = function (name, fn) {\n    util.addProperty(this.prototype, name, fn);\n  };\n\n  Assertion.addMethod = function (name, fn) {\n    util.addMethod(this.prototype, name, fn);\n  };\n\n  Assertion.addChainableMethod = function (name, fn, chainingBehavior) {\n    util.addChainableMethod(this.prototype, name, fn, chainingBehavior);\n  };\n\n  Assertion.overwriteProperty = function (name, fn) {\n    util.overwriteProperty(this.prototype, name, fn);\n  };\n\n  Assertion.overwriteMethod = function (name, fn) {\n    util.overwriteMethod(this.prototype, name, fn);\n  };\n\n  Assertion.overwriteChainableMethod = function (name, fn, chainingBehavior) {\n    util.overwriteChainableMethod(this.prototype, name, fn, chainingBehavior);\n  };\n\n  /**\n   * ### .assert(expression, message, negateMessage, expected, actual, showDiff)\n   *\n   * Executes an expression and check expectations. Throws AssertionError for reporting if test doesn't pass.\n   *\n   * @name assert\n   * @param {Philosophical} expression to be tested\n   * @param {String|Function} message or function that returns message to display if expression fails\n   * @param {String|Function} negatedMessage or function that returns negatedMessage to display if negated expression fails\n   * @param {Mixed} expected value (remember to check for negation)\n   * @param {Mixed} actual (optional) will default to `this.obj`\n   * @param {Boolean} showDiff (optional) when set to `true`, assert will display a diff in addition to the message if expression fails\n   * @api private\n   */\n\n  Assertion.prototype.assert = function (expr, msg, negateMsg, expected, _actual, showDiff) {\n    var ok = util.test(this, arguments);\n    if (true !== showDiff) showDiff = false;\n    if (true !== config.showDiff) showDiff = false;\n\n    if (!ok) {\n      var msg = util.getMessage(this, arguments)\n        , actual = util.getActual(this, arguments);\n      throw new AssertionError(msg, {\n          actual: actual\n        , expected: expected\n        , showDiff: showDiff\n      }, (config.includeStack) ? this.assert : flag(this, 'ssfi'));\n    }\n  };\n\n  /*!\n   * ### ._obj\n   *\n   * Quick reference to stored `actual` value for plugin developers.\n   *\n   * @api private\n   */\n\n  Object.defineProperty(Assertion.prototype, '_obj',\n    { get: function () {\n        return flag(this, 'object');\n      }\n    , set: function (val) {\n        flag(this, 'object', val);\n      }\n  });\n};\n\n},{\"./config\":4}],4:[function(require,module,exports){\nmodule.exports = {\n\n  /**\n   * ### config.includeStack\n   *\n   * User configurable property, influences whether stack trace\n   * is included in Assertion error message. Default of false\n   * suppresses stack trace in the error message.\n   *\n   *     chai.config.includeStack = true;  // enable stack on error\n   *\n   * @param {Boolean}\n   * @api public\n   */\n\n   includeStack: false,\n\n  /**\n   * ### config.showDiff\n   *\n   * User configurable property, influences whether or not\n   * the `showDiff` flag should be included in the thrown\n   * AssertionErrors. `false` will always be `false`; `true`\n   * will be true when the assertion has requested a diff\n   * be shown.\n   *\n   * @param {Boolean}\n   * @api public\n   */\n\n  showDiff: true,\n\n  /**\n   * ### config.truncateThreshold\n   *\n   * User configurable property, sets length threshold for actual and\n   * expected values in assertion errors. If this threshold is exceeded, for\n   * example for large data structures, the value is replaced with something\n   * like `[ Array(3) ]` or `{ Object (prop1, prop2) }`.\n   *\n   * Set it to zero if you want to disable truncating altogether.\n   *\n   * This is especially userful when doing assertions on arrays: having this\n   * set to a reasonable large value makes the failure messages readily\n   * inspectable.\n   *\n   *     chai.config.truncateThreshold = 0;  // disable truncating\n   *\n   * @param {Number}\n   * @api public\n   */\n\n  truncateThreshold: 40\n\n};\n\n},{}],5:[function(require,module,exports){\n/*!\n * chai\n * http://chaijs.com\n * Copyright(c) 2011-2014 Jake Luer <jake@alogicalparadox.com>\n * MIT Licensed\n */\n\nmodule.exports = function (chai, _) {\n  var Assertion = chai.Assertion\n    , toString = Object.prototype.toString\n    , flag = _.flag;\n\n  /**\n   * ### Language Chains\n   *\n   * The following are provided as chainable getters to\n   * improve the readability of your assertions. They\n   * do not provide testing capabilities unless they\n   * have been overwritten by a plugin.\n   *\n   * **Chains**\n   *\n   * - to\n   * - be\n   * - been\n   * - is\n   * - that\n   * - which\n   * - and\n   * - has\n   * - have\n   * - with\n   * - at\n   * - of\n   * - same\n   *\n   * @name language chains\n   * @namespace BDD\n   * @api public\n   */\n\n  [ 'to', 'be', 'been'\n  , 'is', 'and', 'has', 'have'\n  , 'with', 'that', 'which', 'at'\n  , 'of', 'same' ].forEach(function (chain) {\n    Assertion.addProperty(chain, function () {\n      return this;\n    });\n  });\n\n  /**\n   * ### .not\n   *\n   * Negates any of assertions following in the chain.\n   *\n   *     expect(foo).to.not.equal('bar');\n   *     expect(goodFn).to.not.throw(Error);\n   *     expect({ foo: 'baz' }).to.have.property('foo')\n   *       .and.not.equal('bar');\n   *\n   * @name not\n   * @namespace BDD\n   * @api public\n   */\n\n  Assertion.addProperty('not', function () {\n    flag(this, 'negate', true);\n  });\n\n  /**\n   * ### .deep\n   *\n   * Sets the `deep` flag, later used by the `equal` and\n   * `property` assertions.\n   *\n   *     expect(foo).to.deep.equal({ bar: 'baz' });\n   *     expect({ foo: { bar: { baz: 'quux' } } })\n   *       .to.have.deep.property('foo.bar.baz', 'quux');\n   *\n   * `.deep.property` special characters can be escaped\n   * by adding two slashes before the `.` or `[]`.\n   *\n   *     var deepCss = { '.link': { '[target]': 42 }};\n   *     expect(deepCss).to.have.deep.property('\\\\.link.\\\\[target\\\\]', 42);\n   *\n   * @name deep\n   * @namespace BDD\n   * @api public\n   */\n\n  Assertion.addProperty('deep', function () {\n    flag(this, 'deep', true);\n  });\n\n  /**\n   * ### .any\n   *\n   * Sets the `any` flag, (opposite of the `all` flag)\n   * later used in the `keys` assertion.\n   *\n   *     expect(foo).to.have.any.keys('bar', 'baz');\n   *\n   * @name any\n   * @namespace BDD\n   * @api public\n   */\n\n  Assertion.addProperty('any', function () {\n    flag(this, 'any', true);\n    flag(this, 'all', false)\n  });\n\n\n  /**\n   * ### .all\n   *\n   * Sets the `all` flag (opposite of the `any` flag)\n   * later used by the `keys` assertion.\n   *\n   *     expect(foo).to.have.all.keys('bar', 'baz');\n   *\n   * @name all\n   * @namespace BDD\n   * @api public\n   */\n\n  Assertion.addProperty('all', function () {\n    flag(this, 'all', true);\n    flag(this, 'any', false);\n  });\n\n  /**\n   * ### .a(type)\n   *\n   * The `a` and `an` assertions are aliases that can be\n   * used either as language chains or to assert a value's\n   * type.\n   *\n   *     // typeof\n   *     expect('test').to.be.a('string');\n   *     expect({ foo: 'bar' }).to.be.an('object');\n   *     expect(null).to.be.a('null');\n   *     expect(undefined).to.be.an('undefined');\n   *     expect(new Error).to.be.an('error');\n   *     expect(new Promise).to.be.a('promise');\n   *     expect(new Float32Array()).to.be.a('float32array');\n   *     expect(Symbol()).to.be.a('symbol');\n   *\n   *     // es6 overrides\n   *     expect({[Symbol.toStringTag]:()=>'foo'}).to.be.a('foo');\n   *\n   *     // language chain\n   *     expect(foo).to.be.an.instanceof(Foo);\n   *\n   * @name a\n   * @alias an\n   * @param {String} type\n   * @param {String} message _optional_\n   * @namespace BDD\n   * @api public\n   */\n\n  function an (type, msg) {\n    if (msg) flag(this, 'message', msg);\n    type = type.toLowerCase();\n    var obj = flag(this, 'object')\n      , article = ~[ 'a', 'e', 'i', 'o', 'u' ].indexOf(type.charAt(0)) ? 'an ' : 'a ';\n\n    this.assert(\n        type === _.type(obj)\n      , 'expected #{this} to be ' + article + type\n      , 'expected #{this} not to be ' + article + type\n    );\n  }\n\n  Assertion.addChainableMethod('an', an);\n  Assertion.addChainableMethod('a', an);\n\n  /**\n   * ### .include(value)\n   *\n   * The `include` and `contain` assertions can be used as either property\n   * based language chains or as methods to assert the inclusion of an object\n   * in an array or a substring in a string. When used as language chains,\n   * they toggle the `contains` flag for the `keys` assertion.\n   *\n   *     expect([1,2,3]).to.include(2);\n   *     expect('foobar').to.contain('foo');\n   *     expect({ foo: 'bar', hello: 'universe' }).to.include.keys('foo');\n   *\n   * @name include\n   * @alias contain\n   * @alias includes\n   * @alias contains\n   * @param {Object|String|Number} obj\n   * @param {String} message _optional_\n   * @namespace BDD\n   * @api public\n   */\n\n  function includeChainingBehavior () {\n    flag(this, 'contains', true);\n  }\n\n  function include (val, msg) {\n    _.expectTypes(this, ['array', 'object', 'string']);\n\n    if (msg) flag(this, 'message', msg);\n    var obj = flag(this, 'object');\n    var expected = false;\n\n    if (_.type(obj) === 'array' && _.type(val) === 'object') {\n      for (var i in obj) {\n        if (_.eql(obj[i], val)) {\n          expected = true;\n          break;\n        }\n      }\n    } else if (_.type(val) === 'object') {\n      if (!flag(this, 'negate')) {\n        for (var k in val) new Assertion(obj).property(k, val[k]);\n        return;\n      }\n      var subset = {};\n      for (var k in val) subset[k] = obj[k];\n      expected = _.eql(subset, val);\n    } else {\n      expected = (obj != undefined) && ~obj.indexOf(val);\n    }\n    this.assert(\n        expected\n      , 'expected #{this} to include ' + _.inspect(val)\n      , 'expected #{this} to not include ' + _.inspect(val));\n  }\n\n  Assertion.addChainableMethod('include', include, includeChainingBehavior);\n  Assertion.addChainableMethod('contain', include, includeChainingBehavior);\n  Assertion.addChainableMethod('contains', include, includeChainingBehavior);\n  Assertion.addChainableMethod('includes', include, includeChainingBehavior);\n\n  /**\n   * ### .ok\n   *\n   * Asserts that the target is truthy.\n   *\n   *     expect('everything').to.be.ok;\n   *     expect(1).to.be.ok;\n   *     expect(false).to.not.be.ok;\n   *     expect(undefined).to.not.be.ok;\n   *     expect(null).to.not.be.ok;\n   *\n   * @name ok\n   * @namespace BDD\n   * @api public\n   */\n\n  Assertion.addProperty('ok', function () {\n    this.assert(\n        flag(this, 'object')\n      , 'expected #{this} to be truthy'\n      , 'expected #{this} to be falsy');\n  });\n\n  /**\n   * ### .true\n   *\n   * Asserts that the target is `true`.\n   *\n   *     expect(true).to.be.true;\n   *     expect(1).to.not.be.true;\n   *\n   * @name true\n   * @namespace BDD\n   * @api public\n   */\n\n  Assertion.addProperty('true', function () {\n    this.assert(\n        true === flag(this, 'object')\n      , 'expected #{this} to be true'\n      , 'expected #{this} to be false'\n      , this.negate ? false : true\n    );\n  });\n\n  /**\n   * ### .false\n   *\n   * Asserts that the target is `false`.\n   *\n   *     expect(false).to.be.false;\n   *     expect(0).to.not.be.false;\n   *\n   * @name false\n   * @namespace BDD\n   * @api public\n   */\n\n  Assertion.addProperty('false', function () {\n    this.assert(\n        false === flag(this, 'object')\n      , 'expected #{this} to be false'\n      , 'expected #{this} to be true'\n      , this.negate ? true : false\n    );\n  });\n\n  /**\n   * ### .null\n   *\n   * Asserts that the target is `null`.\n   *\n   *     expect(null).to.be.null;\n   *     expect(undefined).to.not.be.null;\n   *\n   * @name null\n   * @namespace BDD\n   * @api public\n   */\n\n  Assertion.addProperty('null', function () {\n    this.assert(\n        null === flag(this, 'object')\n      , 'expected #{this} to be null'\n      , 'expected #{this} not to be null'\n    );\n  });\n\n  /**\n   * ### .undefined\n   *\n   * Asserts that the target is `undefined`.\n   *\n   *     expect(undefined).to.be.undefined;\n   *     expect(null).to.not.be.undefined;\n   *\n   * @name undefined\n   * @namespace BDD\n   * @api public\n   */\n\n  Assertion.addProperty('undefined', function () {\n    this.assert(\n        undefined === flag(this, 'object')\n      , 'expected #{this} to be undefined'\n      , 'expected #{this} not to be undefined'\n    );\n  });\n\n  /**\n   * ### .NaN\n   * Asserts that the target is `NaN`.\n   *\n   *     expect('foo').to.be.NaN;\n   *     expect(4).not.to.be.NaN;\n   *\n   * @name NaN\n   * @namespace BDD\n   * @api public\n   */\n\n  Assertion.addProperty('NaN', function () {\n    this.assert(\n        isNaN(flag(this, 'object'))\n        , 'expected #{this} to be NaN'\n        , 'expected #{this} not to be NaN'\n    );\n  });\n\n  /**\n   * ### .exist\n   *\n   * Asserts that the target is neither `null` nor `undefined`.\n   *\n   *     var foo = 'hi'\n   *       , bar = null\n   *       , baz;\n   *\n   *     expect(foo).to.exist;\n   *     expect(bar).to.not.exist;\n   *     expect(baz).to.not.exist;\n   *\n   * @name exist\n   * @namespace BDD\n   * @api public\n   */\n\n  Assertion.addProperty('exist', function () {\n    this.assert(\n        null != flag(this, 'object')\n      , 'expected #{this} to exist'\n      , 'expected #{this} to not exist'\n    );\n  });\n\n\n  /**\n   * ### .empty\n   *\n   * Asserts that the target's length is `0`. For arrays and strings, it checks\n   * the `length` property. For objects, it gets the count of\n   * enumerable keys.\n   *\n   *     expect([]).to.be.empty;\n   *     expect('').to.be.empty;\n   *     expect({}).to.be.empty;\n   *\n   * @name empty\n   * @namespace BDD\n   * @api public\n   */\n\n  Assertion.addProperty('empty', function () {\n    var obj = flag(this, 'object')\n      , expected = obj;\n\n    if (Array.isArray(obj) || 'string' === typeof object) {\n      expected = obj.length;\n    } else if (typeof obj === 'object') {\n      expected = Object.keys(obj).length;\n    }\n\n    this.assert(\n        !expected\n      , 'expected #{this} to be empty'\n      , 'expected #{this} not to be empty'\n    );\n  });\n\n  /**\n   * ### .arguments\n   *\n   * Asserts that the target is an arguments object.\n   *\n   *     function test () {\n   *       expect(arguments).to.be.arguments;\n   *     }\n   *\n   * @name arguments\n   * @alias Arguments\n   * @namespace BDD\n   * @api public\n   */\n\n  function checkArguments () {\n    var obj = flag(this, 'object')\n      , type = Object.prototype.toString.call(obj);\n    this.assert(\n        '[object Arguments]' === type\n      , 'expected #{this} to be arguments but got ' + type\n      , 'expected #{this} to not be arguments'\n    );\n  }\n\n  Assertion.addProperty('arguments', checkArguments);\n  Assertion.addProperty('Arguments', checkArguments);\n\n  /**\n   * ### .equal(value)\n   *\n   * Asserts that the target is strictly equal (`===`) to `value`.\n   * Alternately, if the `deep` flag is set, asserts that\n   * the target is deeply equal to `value`.\n   *\n   *     expect('hello').to.equal('hello');\n   *     expect(42).to.equal(42);\n   *     expect(1).to.not.equal(true);\n   *     expect({ foo: 'bar' }).to.not.equal({ foo: 'bar' });\n   *     expect({ foo: 'bar' }).to.deep.equal({ foo: 'bar' });\n   *\n   * @name equal\n   * @alias equals\n   * @alias eq\n   * @alias deep.equal\n   * @param {Mixed} value\n   * @param {String} message _optional_\n   * @namespace BDD\n   * @api public\n   */\n\n  function assertEqual (val, msg) {\n    if (msg) flag(this, 'message', msg);\n    var obj = flag(this, 'object');\n    if (flag(this, 'deep')) {\n      return this.eql(val);\n    } else {\n      this.assert(\n          val === obj\n        , 'expected #{this} to equal #{exp}'\n        , 'expected #{this} to not equal #{exp}'\n        , val\n        , this._obj\n        , true\n      );\n    }\n  }\n\n  Assertion.addMethod('equal', assertEqual);\n  Assertion.addMethod('equals', assertEqual);\n  Assertion.addMethod('eq', assertEqual);\n\n  /**\n   * ### .eql(value)\n   *\n   * Asserts that the target is deeply equal to `value`.\n   *\n   *     expect({ foo: 'bar' }).to.eql({ foo: 'bar' });\n   *     expect([ 1, 2, 3 ]).to.eql([ 1, 2, 3 ]);\n   *\n   * @name eql\n   * @alias eqls\n   * @param {Mixed} value\n   * @param {String} message _optional_\n   * @namespace BDD\n   * @api public\n   */\n\n  function assertEql(obj, msg) {\n    if (msg) flag(this, 'message', msg);\n    this.assert(\n        _.eql(obj, flag(this, 'object'))\n      , 'expected #{this} to deeply equal #{exp}'\n      , 'expected #{this} to not deeply equal #{exp}'\n      , obj\n      , this._obj\n      , true\n    );\n  }\n\n  Assertion.addMethod('eql', assertEql);\n  Assertion.addMethod('eqls', assertEql);\n\n  /**\n   * ### .above(value)\n   *\n   * Asserts that the target is greater than `value`.\n   *\n   *     expect(10).to.be.above(5);\n   *\n   * Can also be used in conjunction with `length` to\n   * assert a minimum length. The benefit being a\n   * more informative error message than if the length\n   * was supplied directly.\n   *\n   *     expect('foo').to.have.length.above(2);\n   *     expect([ 1, 2, 3 ]).to.have.length.above(2);\n   *\n   * @name above\n   * @alias gt\n   * @alias greaterThan\n   * @param {Number} value\n   * @param {String} message _optional_\n   * @namespace BDD\n   * @api public\n   */\n\n  function assertAbove (n, msg) {\n    if (msg) flag(this, 'message', msg);\n    var obj = flag(this, 'object');\n    if (flag(this, 'doLength')) {\n      new Assertion(obj, msg).to.have.property('length');\n      var len = obj.length;\n      this.assert(\n          len > n\n        , 'expected #{this} to have a length above #{exp} but got #{act}'\n        , 'expected #{this} to not have a length above #{exp}'\n        , n\n        , len\n      );\n    } else {\n      this.assert(\n          obj > n\n        , 'expected #{this} to be above ' + n\n        , 'expected #{this} to be at most ' + n\n      );\n    }\n  }\n\n  Assertion.addMethod('above', assertAbove);\n  Assertion.addMethod('gt', assertAbove);\n  Assertion.addMethod('greaterThan', assertAbove);\n\n  /**\n   * ### .least(value)\n   *\n   * Asserts that the target is greater than or equal to `value`.\n   *\n   *     expect(10).to.be.at.least(10);\n   *\n   * Can also be used in conjunction with `length` to\n   * assert a minimum length. The benefit being a\n   * more informative error message than if the length\n   * was supplied directly.\n   *\n   *     expect('foo').to.have.length.of.at.least(2);\n   *     expect([ 1, 2, 3 ]).to.have.length.of.at.least(3);\n   *\n   * @name least\n   * @alias gte\n   * @param {Number} value\n   * @param {String} message _optional_\n   * @namespace BDD\n   * @api public\n   */\n\n  function assertLeast (n, msg) {\n    if (msg) flag(this, 'message', msg);\n    var obj = flag(this, 'object');\n    if (flag(this, 'doLength')) {\n      new Assertion(obj, msg).to.have.property('length');\n      var len = obj.length;\n      this.assert(\n          len >= n\n        , 'expected #{this} to have a length at least #{exp} but got #{act}'\n        , 'expected #{this} to have a length below #{exp}'\n        , n\n        , len\n      );\n    } else {\n      this.assert(\n          obj >= n\n        , 'expected #{this} to be at least ' + n\n        , 'expected #{this} to be below ' + n\n      );\n    }\n  }\n\n  Assertion.addMethod('least', assertLeast);\n  Assertion.addMethod('gte', assertLeast);\n\n  /**\n   * ### .below(value)\n   *\n   * Asserts that the target is less than `value`.\n   *\n   *     expect(5).to.be.below(10);\n   *\n   * Can also be used in conjunction with `length` to\n   * assert a maximum length. The benefit being a\n   * more informative error message than if the length\n   * was supplied directly.\n   *\n   *     expect('foo').to.have.length.below(4);\n   *     expect([ 1, 2, 3 ]).to.have.length.below(4);\n   *\n   * @name below\n   * @alias lt\n   * @alias lessThan\n   * @param {Number} value\n   * @param {String} message _optional_\n   * @namespace BDD\n   * @api public\n   */\n\n  function assertBelow (n, msg) {\n    if (msg) flag(this, 'message', msg);\n    var obj = flag(this, 'object');\n    if (flag(this, 'doLength')) {\n      new Assertion(obj, msg).to.have.property('length');\n      var len = obj.length;\n      this.assert(\n          len < n\n        , 'expected #{this} to have a length below #{exp} but got #{act}'\n        , 'expected #{this} to not have a length below #{exp}'\n        , n\n        , len\n      );\n    } else {\n      this.assert(\n          obj < n\n        , 'expected #{this} to be below ' + n\n        , 'expected #{this} to be at least ' + n\n      );\n    }\n  }\n\n  Assertion.addMethod('below', assertBelow);\n  Assertion.addMethod('lt', assertBelow);\n  Assertion.addMethod('lessThan', assertBelow);\n\n  /**\n   * ### .most(value)\n   *\n   * Asserts that the target is less than or equal to `value`.\n   *\n   *     expect(5).to.be.at.most(5);\n   *\n   * Can also be used in conjunction with `length` to\n   * assert a maximum length. The benefit being a\n   * more informative error message than if the length\n   * was supplied directly.\n   *\n   *     expect('foo').to.have.length.of.at.most(4);\n   *     expect([ 1, 2, 3 ]).to.have.length.of.at.most(3);\n   *\n   * @name most\n   * @alias lte\n   * @param {Number} value\n   * @param {String} message _optional_\n   * @namespace BDD\n   * @api public\n   */\n\n  function assertMost (n, msg) {\n    if (msg) flag(this, 'message', msg);\n    var obj = flag(this, 'object');\n    if (flag(this, 'doLength')) {\n      new Assertion(obj, msg).to.have.property('length');\n      var len = obj.length;\n      this.assert(\n          len <= n\n        , 'expected #{this} to have a length at most #{exp} but got #{act}'\n        , 'expected #{this} to have a length above #{exp}'\n        , n\n        , len\n      );\n    } else {\n      this.assert(\n          obj <= n\n        , 'expected #{this} to be at most ' + n\n        , 'expected #{this} to be above ' + n\n      );\n    }\n  }\n\n  Assertion.addMethod('most', assertMost);\n  Assertion.addMethod('lte', assertMost);\n\n  /**\n   * ### .within(start, finish)\n   *\n   * Asserts that the target is within a range.\n   *\n   *     expect(7).to.be.within(5,10);\n   *\n   * Can also be used in conjunction with `length` to\n   * assert a length range. The benefit being a\n   * more informative error message than if the length\n   * was supplied directly.\n   *\n   *     expect('foo').to.have.length.within(2,4);\n   *     expect([ 1, 2, 3 ]).to.have.length.within(2,4);\n   *\n   * @name within\n   * @param {Number} start lowerbound inclusive\n   * @param {Number} finish upperbound inclusive\n   * @param {String} message _optional_\n   * @namespace BDD\n   * @api public\n   */\n\n  Assertion.addMethod('within', function (start, finish, msg) {\n    if (msg) flag(this, 'message', msg);\n    var obj = flag(this, 'object')\n      , range = start + '..' + finish;\n    if (flag(this, 'doLength')) {\n      new Assertion(obj, msg).to.have.property('length');\n      var len = obj.length;\n      this.assert(\n          len >= start && len <= finish\n        , 'expected #{this} to have a length within ' + range\n        , 'expected #{this} to not have a length within ' + range\n      );\n    } else {\n      this.assert(\n          obj >= start && obj <= finish\n        , 'expected #{this} to be within ' + range\n        , 'expected #{this} to not be within ' + range\n      );\n    }\n  });\n\n  /**\n   * ### .instanceof(constructor)\n   *\n   * Asserts that the target is an instance of `constructor`.\n   *\n   *     var Tea = function (name) { this.name = name; }\n   *       , Chai = new Tea('chai');\n   *\n   *     expect(Chai).to.be.an.instanceof(Tea);\n   *     expect([ 1, 2, 3 ]).to.be.instanceof(Array);\n   *\n   * @name instanceof\n   * @param {Constructor} constructor\n   * @param {String} message _optional_\n   * @alias instanceOf\n   * @namespace BDD\n   * @api public\n   */\n\n  function assertInstanceOf (constructor, msg) {\n    if (msg) flag(this, 'message', msg);\n    var name = _.getName(constructor);\n    this.assert(\n        flag(this, 'object') instanceof constructor\n      , 'expected #{this} to be an instance of ' + name\n      , 'expected #{this} to not be an instance of ' + name\n    );\n  };\n\n  Assertion.addMethod('instanceof', assertInstanceOf);\n  Assertion.addMethod('instanceOf', assertInstanceOf);\n\n  /**\n   * ### .property(name, [value])\n   *\n   * Asserts that the target has a property `name`, optionally asserting that\n   * the value of that property is strictly equal to  `value`.\n   * If the `deep` flag is set, you can use dot- and bracket-notation for deep\n   * references into objects and arrays.\n   *\n   *     // simple referencing\n   *     var obj = { foo: 'bar' };\n   *     expect(obj).to.have.property('foo');\n   *     expect(obj).to.have.property('foo', 'bar');\n   *\n   *     // deep referencing\n   *     var deepObj = {\n   *         green: { tea: 'matcha' }\n   *       , teas: [ 'chai', 'matcha', { tea: 'konacha' } ]\n   *     };\n   *\n   *     expect(deepObj).to.have.deep.property('green.tea', 'matcha');\n   *     expect(deepObj).to.have.deep.property('teas[1]', 'matcha');\n   *     expect(deepObj).to.have.deep.property('teas[2].tea', 'konacha');\n   *\n   * You can also use an array as the starting point of a `deep.property`\n   * assertion, or traverse nested arrays.\n   *\n   *     var arr = [\n   *         [ 'chai', 'matcha', 'konacha' ]\n   *       , [ { tea: 'chai' }\n   *         , { tea: 'matcha' }\n   *         , { tea: 'konacha' } ]\n   *     ];\n   *\n   *     expect(arr).to.have.deep.property('[0][1]', 'matcha');\n   *     expect(arr).to.have.deep.property('[1][2].tea', 'konacha');\n   *\n   * Furthermore, `property` changes the subject of the assertion\n   * to be the value of that property from the original object. This\n   * permits for further chainable assertions on that property.\n   *\n   *     expect(obj).to.have.property('foo')\n   *       .that.is.a('string');\n   *     expect(deepObj).to.have.property('green')\n   *       .that.is.an('object')\n   *       .that.deep.equals({ tea: 'matcha' });\n   *     expect(deepObj).to.have.property('teas')\n   *       .that.is.an('array')\n   *       .with.deep.property('[2]')\n   *         .that.deep.equals({ tea: 'konacha' });\n   *\n   * Note that dots and bracket in `name` must be backslash-escaped when\n   * the `deep` flag is set, while they must NOT be escaped when the `deep`\n   * flag is not set.\n   *\n   *     // simple referencing\n   *     var css = { '.link[target]': 42 };\n   *     expect(css).to.have.property('.link[target]', 42);\n   *\n   *     // deep referencing\n   *     var deepCss = { '.link': { '[target]': 42 }};\n   *     expect(deepCss).to.have.deep.property('\\\\.link.\\\\[target\\\\]', 42);\n   *\n   * @name property\n   * @alias deep.property\n   * @param {String} name\n   * @param {Mixed} value (optional)\n   * @param {String} message _optional_\n   * @returns value of property for chaining\n   * @namespace BDD\n   * @api public\n   */\n\n  Assertion.addMethod('property', function (name, val, msg) {\n    if (msg) flag(this, 'message', msg);\n\n    var isDeep = !!flag(this, 'deep')\n      , descriptor = isDeep ? 'deep property ' : 'property '\n      , negate = flag(this, 'negate')\n      , obj = flag(this, 'object')\n      , pathInfo = isDeep ? _.getPathInfo(name, obj) : null\n      , hasProperty = isDeep\n        ? pathInfo.exists\n        : _.hasProperty(name, obj)\n      , value = isDeep\n        ? pathInfo.value\n        : obj[name];\n\n    if (negate && arguments.length > 1) {\n      if (undefined === value) {\n        msg = (msg != null) ? msg + ': ' : '';\n        throw new Error(msg + _.inspect(obj) + ' has no ' + descriptor + _.inspect(name));\n      }\n    } else {\n      this.assert(\n          hasProperty\n        , 'expected #{this} to have a ' + descriptor + _.inspect(name)\n        , 'expected #{this} to not have ' + descriptor + _.inspect(name));\n    }\n\n    if (arguments.length > 1) {\n      this.assert(\n          val === value\n        , 'expected #{this} to have a ' + descriptor + _.inspect(name) + ' of #{exp}, but got #{act}'\n        , 'expected #{this} to not have a ' + descriptor + _.inspect(name) + ' of #{act}'\n        , val\n        , value\n      );\n    }\n\n    flag(this, 'object', value);\n  });\n\n\n  /**\n   * ### .ownProperty(name)\n   *\n   * Asserts that the target has an own property `name`.\n   *\n   *     expect('test').to.have.ownProperty('length');\n   *\n   * @name ownProperty\n   * @alias haveOwnProperty\n   * @param {String} name\n   * @param {String} message _optional_\n   * @namespace BDD\n   * @api public\n   */\n\n  function assertOwnProperty (name, msg) {\n    if (msg) flag(this, 'message', msg);\n    var obj = flag(this, 'object');\n    this.assert(\n        obj.hasOwnProperty(name)\n      , 'expected #{this} to have own property ' + _.inspect(name)\n      , 'expected #{this} to not have own property ' + _.inspect(name)\n    );\n  }\n\n  Assertion.addMethod('ownProperty', assertOwnProperty);\n  Assertion.addMethod('haveOwnProperty', assertOwnProperty);\n\n  /**\n   * ### .ownPropertyDescriptor(name[, descriptor[, message]])\n   *\n   * Asserts that the target has an own property descriptor `name`, that optionally matches `descriptor`.\n   *\n   *     expect('test').to.have.ownPropertyDescriptor('length');\n   *     expect('test').to.have.ownPropertyDescriptor('length', { enumerable: false, configurable: false, writable: false, value: 4 });\n   *     expect('test').not.to.have.ownPropertyDescriptor('length', { enumerable: false, configurable: false, writable: false, value: 3 });\n   *     expect('test').ownPropertyDescriptor('length').to.have.property('enumerable', false);\n   *     expect('test').ownPropertyDescriptor('length').to.have.keys('value');\n   *\n   * @name ownPropertyDescriptor\n   * @alias haveOwnPropertyDescriptor\n   * @param {String} name\n   * @param {Object} descriptor _optional_\n   * @param {String} message _optional_\n   * @namespace BDD\n   * @api public\n   */\n\n  function assertOwnPropertyDescriptor (name, descriptor, msg) {\n    if (typeof descriptor === 'string') {\n      msg = descriptor;\n      descriptor = null;\n    }\n    if (msg) flag(this, 'message', msg);\n    var obj = flag(this, 'object');\n    var actualDescriptor = Object.getOwnPropertyDescriptor(Object(obj), name);\n    if (actualDescriptor && descriptor) {\n      this.assert(\n          _.eql(descriptor, actualDescriptor)\n        , 'expected the own property descriptor for ' + _.inspect(name) + ' on #{this} to match ' + _.inspect(descriptor) + ', got ' + _.inspect(actualDescriptor)\n        , 'expected the own property descriptor for ' + _.inspect(name) + ' on #{this} to not match ' + _.inspect(descriptor)\n        , descriptor\n        , actualDescriptor\n        , true\n      );\n    } else {\n      this.assert(\n          actualDescriptor\n        , 'expected #{this} to have an own property descriptor for ' + _.inspect(name)\n        , 'expected #{this} to not have an own property descriptor for ' + _.inspect(name)\n      );\n    }\n    flag(this, 'object', actualDescriptor);\n  }\n\n  Assertion.addMethod('ownPropertyDescriptor', assertOwnPropertyDescriptor);\n  Assertion.addMethod('haveOwnPropertyDescriptor', assertOwnPropertyDescriptor);\n\n  /**\n   * ### .length\n   *\n   * Sets the `doLength` flag later used as a chain precursor to a value\n   * comparison for the `length` property.\n   *\n   *     expect('foo').to.have.length.above(2);\n   *     expect([ 1, 2, 3 ]).to.have.length.above(2);\n   *     expect('foo').to.have.length.below(4);\n   *     expect([ 1, 2, 3 ]).to.have.length.below(4);\n   *     expect('foo').to.have.length.within(2,4);\n   *     expect([ 1, 2, 3 ]).to.have.length.within(2,4);\n   *\n   * *Deprecation notice:* Using `length` as an assertion will be deprecated\n   * in version 2.4.0 and removed in 3.0.0. Code using the old style of\n   * asserting for `length` property value using `length(value)` should be\n   * switched to use `lengthOf(value)` instead.\n   *\n   * @name length\n   * @namespace BDD\n   * @api public\n   */\n\n  /**\n   * ### .lengthOf(value[, message])\n   *\n   * Asserts that the target's `length` property has\n   * the expected value.\n   *\n   *     expect([ 1, 2, 3]).to.have.lengthOf(3);\n   *     expect('foobar').to.have.lengthOf(6);\n   *\n   * @name lengthOf\n   * @param {Number} length\n   * @param {String} message _optional_\n   * @namespace BDD\n   * @api public\n   */\n\n  function assertLengthChain () {\n    flag(this, 'doLength', true);\n  }\n\n  function assertLength (n, msg) {\n    if (msg) flag(this, 'message', msg);\n    var obj = flag(this, 'object');\n    new Assertion(obj, msg).to.have.property('length');\n    var len = obj.length;\n\n    this.assert(\n        len == n\n      , 'expected #{this} to have a length of #{exp} but got #{act}'\n      , 'expected #{this} to not have a length of #{act}'\n      , n\n      , len\n    );\n  }\n\n  Assertion.addChainableMethod('length', assertLength, assertLengthChain);\n  Assertion.addMethod('lengthOf', assertLength);\n\n  /**\n   * ### .match(regexp)\n   *\n   * Asserts that the target matches a regular expression.\n   *\n   *     expect('foobar').to.match(/^foo/);\n   *\n   * @name match\n   * @alias matches\n   * @param {RegExp} RegularExpression\n   * @param {String} message _optional_\n   * @namespace BDD\n   * @api public\n   */\n  function assertMatch(re, msg) {\n    if (msg) flag(this, 'message', msg);\n    var obj = flag(this, 'object');\n    this.assert(\n        re.exec(obj)\n      , 'expected #{this} to match ' + re\n      , 'expected #{this} not to match ' + re\n    );\n  }\n\n  Assertion.addMethod('match', assertMatch);\n  Assertion.addMethod('matches', assertMatch);\n\n  /**\n   * ### .string(string)\n   *\n   * Asserts that the string target contains another string.\n   *\n   *     expect('foobar').to.have.string('bar');\n   *\n   * @name string\n   * @param {String} string\n   * @param {String} message _optional_\n   * @namespace BDD\n   * @api public\n   */\n\n  Assertion.addMethod('string', function (str, msg) {\n    if (msg) flag(this, 'message', msg);\n    var obj = flag(this, 'object');\n    new Assertion(obj, msg).is.a('string');\n\n    this.assert(\n        ~obj.indexOf(str)\n      , 'expected #{this} to contain ' + _.inspect(str)\n      , 'expected #{this} to not contain ' + _.inspect(str)\n    );\n  });\n\n\n  /**\n   * ### .keys(key1, [key2], [...])\n   *\n   * Asserts that the target contains any or all of the passed-in keys.\n   * Use in combination with `any`, `all`, `contains`, or `have` will affect\n   * what will pass.\n   *\n   * When used in conjunction with `any`, at least one key that is passed\n   * in must exist in the target object. This is regardless whether or not\n   * the `have` or `contain` qualifiers are used. Note, either `any` or `all`\n   * should be used in the assertion. If neither are used, the assertion is\n   * defaulted to `all`.\n   *\n   * When both `all` and `contain` are used, the target object must have at\n   * least all of the passed-in keys but may have more keys not listed.\n   *\n   * When both `all` and `have` are used, the target object must both contain\n   * all of the passed-in keys AND the number of keys in the target object must\n   * match the number of keys passed in (in other words, a target object must\n   * have all and only all of the passed-in keys).\n   *\n   *     expect({ foo: 1, bar: 2 }).to.have.any.keys('foo', 'baz');\n   *     expect({ foo: 1, bar: 2 }).to.have.any.keys('foo');\n   *     expect({ foo: 1, bar: 2 }).to.contain.any.keys('bar', 'baz');\n   *     expect({ foo: 1, bar: 2 }).to.contain.any.keys(['foo']);\n   *     expect({ foo: 1, bar: 2 }).to.contain.any.keys({'foo': 6});\n   *     expect({ foo: 1, bar: 2 }).to.have.all.keys(['bar', 'foo']);\n   *     expect({ foo: 1, bar: 2 }).to.have.all.keys({'bar': 6, 'foo': 7});\n   *     expect({ foo: 1, bar: 2, baz: 3 }).to.contain.all.keys(['bar', 'foo']);\n   *     expect({ foo: 1, bar: 2, baz: 3 }).to.contain.all.keys({'bar': 6});\n   *\n   *\n   * @name keys\n   * @alias key\n   * @param {...String|Array|Object} keys\n   * @namespace BDD\n   * @api public\n   */\n\n  function assertKeys (keys) {\n    var obj = flag(this, 'object')\n      , str\n      , ok = true\n      , mixedArgsMsg = 'keys must be given single argument of Array|Object|String, or multiple String arguments';\n\n    switch (_.type(keys)) {\n      case \"array\":\n        if (arguments.length > 1) throw (new Error(mixedArgsMsg));\n        break;\n      case \"object\":\n        if (arguments.length > 1) throw (new Error(mixedArgsMsg));\n        keys = Object.keys(keys);\n        break;\n      default:\n        keys = Array.prototype.slice.call(arguments);\n    }\n\n    if (!keys.length) throw new Error('keys required');\n\n    var actual = Object.keys(obj)\n      , expected = keys\n      , len = keys.length\n      , any = flag(this, 'any')\n      , all = flag(this, 'all');\n\n    if (!any && !all) {\n      all = true;\n    }\n\n    // Has any\n    if (any) {\n      var intersection = expected.filter(function(key) {\n        return ~actual.indexOf(key);\n      });\n      ok = intersection.length > 0;\n    }\n\n    // Has all\n    if (all) {\n      ok = keys.every(function(key){\n        return ~actual.indexOf(key);\n      });\n      if (!flag(this, 'negate') && !flag(this, 'contains')) {\n        ok = ok && keys.length == actual.length;\n      }\n    }\n\n    // Key string\n    if (len > 1) {\n      keys = keys.map(function(key){\n        return _.inspect(key);\n      });\n      var last = keys.pop();\n      if (all) {\n        str = keys.join(', ') + ', and ' + last;\n      }\n      if (any) {\n        str = keys.join(', ') + ', or ' + last;\n      }\n    } else {\n      str = _.inspect(keys[0]);\n    }\n\n    // Form\n    str = (len > 1 ? 'keys ' : 'key ') + str;\n\n    // Have / include\n    str = (flag(this, 'contains') ? 'contain ' : 'have ') + str;\n\n    // Assertion\n    this.assert(\n        ok\n      , 'expected #{this} to ' + str\n      , 'expected #{this} to not ' + str\n      , expected.slice(0).sort()\n      , actual.sort()\n      , true\n    );\n  }\n\n  Assertion.addMethod('keys', assertKeys);\n  Assertion.addMethod('key', assertKeys);\n\n  /**\n   * ### .throw(constructor)\n   *\n   * Asserts that the function target will throw a specific error, or specific type of error\n   * (as determined using `instanceof`), optionally with a RegExp or string inclusion test\n   * for the error's message.\n   *\n   *     var err = new ReferenceError('This is a bad function.');\n   *     var fn = function () { throw err; }\n   *     expect(fn).to.throw(ReferenceError);\n   *     expect(fn).to.throw(Error);\n   *     expect(fn).to.throw(/bad function/);\n   *     expect(fn).to.not.throw('good function');\n   *     expect(fn).to.throw(ReferenceError, /bad function/);\n   *     expect(fn).to.throw(err);\n   *\n   * Please note that when a throw expectation is negated, it will check each\n   * parameter independently, starting with error constructor type. The appropriate way\n   * to check for the existence of a type of error but for a message that does not match\n   * is to use `and`.\n   *\n   *     expect(fn).to.throw(ReferenceError)\n   *        .and.not.throw(/good function/);\n   *\n   * @name throw\n   * @alias throws\n   * @alias Throw\n   * @param {ErrorConstructor} constructor\n   * @param {String|RegExp} expected error message\n   * @param {String} message _optional_\n   * @see https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Error#Error_types\n   * @returns error for chaining (null if no error)\n   * @namespace BDD\n   * @api public\n   */\n\n  function assertThrows (constructor, errMsg, msg) {\n    if (msg) flag(this, 'message', msg);\n    var obj = flag(this, 'object');\n    new Assertion(obj, msg).is.a('function');\n\n    var thrown = false\n      , desiredError = null\n      , name = null\n      , thrownError = null;\n\n    if (arguments.length === 0) {\n      errMsg = null;\n      constructor = null;\n    } else if (constructor && (constructor instanceof RegExp || 'string' === typeof constructor)) {\n      errMsg = constructor;\n      constructor = null;\n    } else if (constructor && constructor instanceof Error) {\n      desiredError = constructor;\n      constructor = null;\n      errMsg = null;\n    } else if (typeof constructor === 'function') {\n      name = constructor.prototype.name;\n      if (!name || (name === 'Error' && constructor !== Error)) {\n        name = constructor.name || (new constructor()).name;\n      }\n    } else {\n      constructor = null;\n    }\n\n    try {\n      obj();\n    } catch (err) {\n      // first, check desired error\n      if (desiredError) {\n        this.assert(\n            err === desiredError\n          , 'expected #{this} to throw #{exp} but #{act} was thrown'\n          , 'expected #{this} to not throw #{exp}'\n          , (desiredError instanceof Error ? desiredError.toString() : desiredError)\n          , (err instanceof Error ? err.toString() : err)\n        );\n\n        flag(this, 'object', err);\n        return this;\n      }\n\n      // next, check constructor\n      if (constructor) {\n        this.assert(\n            err instanceof constructor\n          , 'expected #{this} to throw #{exp} but #{act} was thrown'\n          , 'expected #{this} to not throw #{exp} but #{act} was thrown'\n          , name\n          , (err instanceof Error ? err.toString() : err)\n        );\n\n        if (!errMsg) {\n          flag(this, 'object', err);\n          return this;\n        }\n      }\n\n      // next, check message\n      var message = 'error' === _.type(err) && \"message\" in err\n        ? err.message\n        : '' + err;\n\n      if ((message != null) && errMsg && errMsg instanceof RegExp) {\n        this.assert(\n            errMsg.exec(message)\n          , 'expected #{this} to throw error matching #{exp} but got #{act}'\n          , 'expected #{this} to throw error not matching #{exp}'\n          , errMsg\n          , message\n        );\n\n        flag(this, 'object', err);\n        return this;\n      } else if ((message != null) && errMsg && 'string' === typeof errMsg) {\n        this.assert(\n            ~message.indexOf(errMsg)\n          , 'expected #{this} to throw error including #{exp} but got #{act}'\n          , 'expected #{this} to throw error not including #{act}'\n          , errMsg\n          , message\n        );\n\n        flag(this, 'object', err);\n        return this;\n      } else {\n        thrown = true;\n        thrownError = err;\n      }\n    }\n\n    var actuallyGot = ''\n      , expectedThrown = name !== null\n        ? name\n        : desiredError\n          ? '#{exp}' //_.inspect(desiredError)\n          : 'an error';\n\n    if (thrown) {\n      actuallyGot = ' but #{act} was thrown'\n    }\n\n    this.assert(\n        thrown === true\n      , 'expected #{this} to throw ' + expectedThrown + actuallyGot\n      , 'expected #{this} to not throw ' + expectedThrown + actuallyGot\n      , (desiredError instanceof Error ? desiredError.toString() : desiredError)\n      , (thrownError instanceof Error ? thrownError.toString() : thrownError)\n    );\n\n    flag(this, 'object', thrownError);\n  };\n\n  Assertion.addMethod('throw', assertThrows);\n  Assertion.addMethod('throws', assertThrows);\n  Assertion.addMethod('Throw', assertThrows);\n\n  /**\n   * ### .respondTo(method)\n   *\n   * Asserts that the object or class target will respond to a method.\n   *\n   *     Klass.prototype.bar = function(){};\n   *     expect(Klass).to.respondTo('bar');\n   *     expect(obj).to.respondTo('bar');\n   *\n   * To check if a constructor will respond to a static function,\n   * set the `itself` flag.\n   *\n   *     Klass.baz = function(){};\n   *     expect(Klass).itself.to.respondTo('baz');\n   *\n   * @name respondTo\n   * @alias respondsTo\n   * @param {String} method\n   * @param {String} message _optional_\n   * @namespace BDD\n   * @api public\n   */\n\n  function respondTo (method, msg) {\n    if (msg) flag(this, 'message', msg);\n    var obj = flag(this, 'object')\n      , itself = flag(this, 'itself')\n      , context = ('function' === _.type(obj) && !itself)\n        ? obj.prototype[method]\n        : obj[method];\n\n    this.assert(\n        'function' === typeof context\n      , 'expected #{this} to respond to ' + _.inspect(method)\n      , 'expected #{this} to not respond to ' + _.inspect(method)\n    );\n  }\n\n  Assertion.addMethod('respondTo', respondTo);\n  Assertion.addMethod('respondsTo', respondTo);\n\n  /**\n   * ### .itself\n   *\n   * Sets the `itself` flag, later used by the `respondTo` assertion.\n   *\n   *     function Foo() {}\n   *     Foo.bar = function() {}\n   *     Foo.prototype.baz = function() {}\n   *\n   *     expect(Foo).itself.to.respondTo('bar');\n   *     expect(Foo).itself.not.to.respondTo('baz');\n   *\n   * @name itself\n   * @namespace BDD\n   * @api public\n   */\n\n  Assertion.addProperty('itself', function () {\n    flag(this, 'itself', true);\n  });\n\n  /**\n   * ### .satisfy(method)\n   *\n   * Asserts that the target passes a given truth test.\n   *\n   *     expect(1).to.satisfy(function(num) { return num > 0; });\n   *\n   * @name satisfy\n   * @alias satisfies\n   * @param {Function} matcher\n   * @param {String} message _optional_\n   * @namespace BDD\n   * @api public\n   */\n\n  function satisfy (matcher, msg) {\n    if (msg) flag(this, 'message', msg);\n    var obj = flag(this, 'object');\n    var result = matcher(obj);\n    this.assert(\n        result\n      , 'expected #{this} to satisfy ' + _.objDisplay(matcher)\n      , 'expected #{this} to not satisfy' + _.objDisplay(matcher)\n      , this.negate ? false : true\n      , result\n    );\n  }\n\n  Assertion.addMethod('satisfy', satisfy);\n  Assertion.addMethod('satisfies', satisfy);\n\n  /**\n   * ### .closeTo(expected, delta)\n   *\n   * Asserts that the target is equal `expected`, to within a +/- `delta` range.\n   *\n   *     expect(1.5).to.be.closeTo(1, 0.5);\n   *\n   * @name closeTo\n   * @alias approximately\n   * @param {Number} expected\n   * @param {Number} delta\n   * @param {String} message _optional_\n   * @namespace BDD\n   * @api public\n   */\n\n  function closeTo(expected, delta, msg) {\n    if (msg) flag(this, 'message', msg);\n    var obj = flag(this, 'object');\n\n    new Assertion(obj, msg).is.a('number');\n    if (_.type(expected) !== 'number' || _.type(delta) !== 'number') {\n      throw new Error('the arguments to closeTo or approximately must be numbers');\n    }\n\n    this.assert(\n        Math.abs(obj - expected) <= delta\n      , 'expected #{this} to be close to ' + expected + ' +/- ' + delta\n      , 'expected #{this} not to be close to ' + expected + ' +/- ' + delta\n    );\n  }\n\n  Assertion.addMethod('closeTo', closeTo);\n  Assertion.addMethod('approximately', closeTo);\n\n  function isSubsetOf(subset, superset, cmp) {\n    return subset.every(function(elem) {\n      if (!cmp) return superset.indexOf(elem) !== -1;\n\n      return superset.some(function(elem2) {\n        return cmp(elem, elem2);\n      });\n    })\n  }\n\n  /**\n   * ### .members(set)\n   *\n   * Asserts that the target is a superset of `set`,\n   * or that the target and `set` have the same strictly-equal (===) members.\n   * Alternately, if the `deep` flag is set, set members are compared for deep\n   * equality.\n   *\n   *     expect([1, 2, 3]).to.include.members([3, 2]);\n   *     expect([1, 2, 3]).to.not.include.members([3, 2, 8]);\n   *\n   *     expect([4, 2]).to.have.members([2, 4]);\n   *     expect([5, 2]).to.not.have.members([5, 2, 1]);\n   *\n   *     expect([{ id: 1 }]).to.deep.include.members([{ id: 1 }]);\n   *\n   * @name members\n   * @param {Array} set\n   * @param {String} message _optional_\n   * @namespace BDD\n   * @api public\n   */\n\n  Assertion.addMethod('members', function (subset, msg) {\n    if (msg) flag(this, 'message', msg);\n    var obj = flag(this, 'object');\n\n    new Assertion(obj).to.be.an('array');\n    new Assertion(subset).to.be.an('array');\n\n    var cmp = flag(this, 'deep') ? _.eql : undefined;\n\n    if (flag(this, 'contains')) {\n      return this.assert(\n          isSubsetOf(subset, obj, cmp)\n        , 'expected #{this} to be a superset of #{act}'\n        , 'expected #{this} to not be a superset of #{act}'\n        , obj\n        , subset\n      );\n    }\n\n    this.assert(\n        isSubsetOf(obj, subset, cmp) && isSubsetOf(subset, obj, cmp)\n        , 'expected #{this} to have the same members as #{act}'\n        , 'expected #{this} to not have the same members as #{act}'\n        , obj\n        , subset\n    );\n  });\n\n  /**\n   * ### .oneOf(list)\n   *\n   * Assert that a value appears somewhere in the top level of array `list`.\n   *\n   *     expect('a').to.be.oneOf(['a', 'b', 'c']);\n   *     expect(9).to.not.be.oneOf(['z']);\n   *     expect([3]).to.not.be.oneOf([1, 2, [3]]);\n   *\n   *     var three = [3];\n   *     // for object-types, contents are not compared\n   *     expect(three).to.not.be.oneOf([1, 2, [3]]);\n   *     // comparing references works\n   *     expect(three).to.be.oneOf([1, 2, three]);\n   *\n   * @name oneOf\n   * @param {Array<*>} list\n   * @param {String} message _optional_\n   * @namespace BDD\n   * @api public\n   */\n\n  function oneOf (list, msg) {\n    if (msg) flag(this, 'message', msg);\n    var expected = flag(this, 'object');\n    new Assertion(list).to.be.an('array');\n\n    this.assert(\n        list.indexOf(expected) > -1\n      , 'expected #{this} to be one of #{exp}'\n      , 'expected #{this} to not be one of #{exp}'\n      , list\n      , expected\n    );\n  }\n\n  Assertion.addMethod('oneOf', oneOf);\n\n\n  /**\n   * ### .change(function)\n   *\n   * Asserts that a function changes an object property\n   *\n   *     var obj = { val: 10 };\n   *     var fn = function() { obj.val += 3 };\n   *     var noChangeFn = function() { return 'foo' + 'bar'; }\n   *     expect(fn).to.change(obj, 'val');\n   *     expect(noChangeFn).to.not.change(obj, 'val')\n   *\n   * @name change\n   * @alias changes\n   * @alias Change\n   * @param {String} object\n   * @param {String} property name\n   * @param {String} message _optional_\n   * @namespace BDD\n   * @api public\n   */\n\n  function assertChanges (object, prop, msg) {\n    if (msg) flag(this, 'message', msg);\n    var fn = flag(this, 'object');\n    new Assertion(object, msg).to.have.property(prop);\n    new Assertion(fn).is.a('function');\n\n    var initial = object[prop];\n    fn();\n\n    this.assert(\n      initial !== object[prop]\n      , 'expected .' + prop + ' to change'\n      , 'expected .' + prop + ' to not change'\n    );\n  }\n\n  Assertion.addChainableMethod('change', assertChanges);\n  Assertion.addChainableMethod('changes', assertChanges);\n\n  /**\n   * ### .increase(function)\n   *\n   * Asserts that a function increases an object property\n   *\n   *     var obj = { val: 10 };\n   *     var fn = function() { obj.val = 15 };\n   *     expect(fn).to.increase(obj, 'val');\n   *\n   * @name increase\n   * @alias increases\n   * @alias Increase\n   * @param {String} object\n   * @param {String} property name\n   * @param {String} message _optional_\n   * @namespace BDD\n   * @api public\n   */\n\n  function assertIncreases (object, prop, msg) {\n    if (msg) flag(this, 'message', msg);\n    var fn = flag(this, 'object');\n    new Assertion(object, msg).to.have.property(prop);\n    new Assertion(fn).is.a('function');\n\n    var initial = object[prop];\n    fn();\n\n    this.assert(\n      object[prop] - initial > 0\n      , 'expected .' + prop + ' to increase'\n      , 'expected .' + prop + ' to not increase'\n    );\n  }\n\n  Assertion.addChainableMethod('increase', assertIncreases);\n  Assertion.addChainableMethod('increases', assertIncreases);\n\n  /**\n   * ### .decrease(function)\n   *\n   * Asserts that a function decreases an object property\n   *\n   *     var obj = { val: 10 };\n   *     var fn = function() { obj.val = 5 };\n   *     expect(fn).to.decrease(obj, 'val');\n   *\n   * @name decrease\n   * @alias decreases\n   * @alias Decrease\n   * @param {String} object\n   * @param {String} property name\n   * @param {String} message _optional_\n   * @namespace BDD\n   * @api public\n   */\n\n  function assertDecreases (object, prop, msg) {\n    if (msg) flag(this, 'message', msg);\n    var fn = flag(this, 'object');\n    new Assertion(object, msg).to.have.property(prop);\n    new Assertion(fn).is.a('function');\n\n    var initial = object[prop];\n    fn();\n\n    this.assert(\n      object[prop] - initial < 0\n      , 'expected .' + prop + ' to decrease'\n      , 'expected .' + prop + ' to not decrease'\n    );\n  }\n\n  Assertion.addChainableMethod('decrease', assertDecreases);\n  Assertion.addChainableMethod('decreases', assertDecreases);\n\n  /**\n   * ### .extensible\n   *\n   * Asserts that the target is extensible (can have new properties added to\n   * it).\n   *\n   *     var nonExtensibleObject = Object.preventExtensions({});\n   *     var sealedObject = Object.seal({});\n   *     var frozenObject = Object.freeze({});\n   *\n   *     expect({}).to.be.extensible;\n   *     expect(nonExtensibleObject).to.not.be.extensible;\n   *     expect(sealedObject).to.not.be.extensible;\n   *     expect(frozenObject).to.not.be.extensible;\n   *\n   * @name extensible\n   * @namespace BDD\n   * @api public\n   */\n\n  Assertion.addProperty('extensible', function() {\n    var obj = flag(this, 'object');\n\n    // In ES5, if the argument to this method is not an object (a primitive), then it will cause a TypeError.\n    // In ES6, a non-object argument will be treated as if it was a non-extensible ordinary object, simply return false.\n    // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/isExtensible\n    // The following provides ES6 behavior when a TypeError is thrown under ES5.\n\n    var isExtensible;\n\n    try {\n      isExtensible = Object.isExtensible(obj);\n    } catch (err) {\n      if (err instanceof TypeError) isExtensible = false;\n      else throw err;\n    }\n\n    this.assert(\n      isExtensible\n      , 'expected #{this} to be extensible'\n      , 'expected #{this} to not be extensible'\n    );\n  });\n\n  /**\n   * ### .sealed\n   *\n   * Asserts that the target is sealed (cannot have new properties added to it\n   * and its existing properties cannot be removed).\n   *\n   *     var sealedObject = Object.seal({});\n   *     var frozenObject = Object.freeze({});\n   *\n   *     expect(sealedObject).to.be.sealed;\n   *     expect(frozenObject).to.be.sealed;\n   *     expect({}).to.not.be.sealed;\n   *\n   * @name sealed\n   * @namespace BDD\n   * @api public\n   */\n\n  Assertion.addProperty('sealed', function() {\n    var obj = flag(this, 'object');\n\n    // In ES5, if the argument to this method is not an object (a primitive), then it will cause a TypeError.\n    // In ES6, a non-object argument will be treated as if it was a sealed ordinary object, simply return true.\n    // See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/isSealed\n    // The following provides ES6 behavior when a TypeError is thrown under ES5.\n\n    var isSealed;\n\n    try {\n      isSealed = Object.isSealed(obj);\n    } catch (err) {\n      if (err instanceof TypeError) isSealed = true;\n      else throw err;\n    }\n\n    this.assert(\n      isSealed\n      , 'expected #{this} to be sealed'\n      , 'expected #{this} to not be sealed'\n    );\n  });\n\n  /**\n   * ### .frozen\n   *\n   * Asserts that the target is frozen (cannot have new properties added to it\n   * and its existing properties cannot be modified).\n   *\n   *     var frozenObject = Object.freeze({});\n   *\n   *     expect(frozenObject).to.be.frozen;\n   *     expect({}).to.not.be.frozen;\n   *\n   * @name frozen\n   * @namespace BDD\n   * @api public\n   */\n\n  Assertion.addProperty('frozen', function() {\n    var obj = flag(this, 'object');\n\n    // In ES5, if the argument to this method is not an object (a primitive), then it will cause a TypeError.\n    // In ES6, a non-object argument will be treated as if it was a frozen ordinary object, simply return true.\n    // See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/isFrozen\n    // The following provides ES6 behavior when a TypeError is thrown under ES5.\n\n    var isFrozen;\n\n    try {\n      isFrozen = Object.isFrozen(obj);\n    } catch (err) {\n      if (err instanceof TypeError) isFrozen = true;\n      else throw err;\n    }\n\n    this.assert(\n      isFrozen\n      , 'expected #{this} to be frozen'\n      , 'expected #{this} to not be frozen'\n    );\n  });\n};\n\n},{}],6:[function(require,module,exports){\n/*!\n * chai\n * Copyright(c) 2011-2014 Jake Luer <jake@alogicalparadox.com>\n * MIT Licensed\n */\n\n\nmodule.exports = function (chai, util) {\n\n  /*!\n   * Chai dependencies.\n   */\n\n  var Assertion = chai.Assertion\n    , flag = util.flag;\n\n  /*!\n   * Module export.\n   */\n\n  /**\n   * ### assert(expression, message)\n   *\n   * Write your own test expressions.\n   *\n   *     assert('foo' !== 'bar', 'foo is not bar');\n   *     assert(Array.isArray([]), 'empty arrays are arrays');\n   *\n   * @param {Mixed} expression to test for truthiness\n   * @param {String} message to display on error\n   * @name assert\n   * @namespace Assert\n   * @api public\n   */\n\n  var assert = chai.assert = function (express, errmsg) {\n    var test = new Assertion(null, null, chai.assert);\n    test.assert(\n        express\n      , errmsg\n      , '[ negation message unavailable ]'\n    );\n  };\n\n  /**\n   * ### .fail(actual, expected, [message], [operator])\n   *\n   * Throw a failure. Node.js `assert` module-compatible.\n   *\n   * @name fail\n   * @param {Mixed} actual\n   * @param {Mixed} expected\n   * @param {String} message\n   * @param {String} operator\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.fail = function (actual, expected, message, operator) {\n    message = message || 'assert.fail()';\n    throw new chai.AssertionError(message, {\n        actual: actual\n      , expected: expected\n      , operator: operator\n    }, assert.fail);\n  };\n\n  /**\n   * ### .isOk(object, [message])\n   *\n   * Asserts that `object` is truthy.\n   *\n   *     assert.isOk('everything', 'everything is ok');\n   *     assert.isOk(false, 'this will fail');\n   *\n   * @name isOk\n   * @alias ok\n   * @param {Mixed} object to test\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.isOk = function (val, msg) {\n    new Assertion(val, msg).is.ok;\n  };\n\n  /**\n   * ### .isNotOk(object, [message])\n   *\n   * Asserts that `object` is falsy.\n   *\n   *     assert.isNotOk('everything', 'this will fail');\n   *     assert.isNotOk(false, 'this will pass');\n   *\n   * @name isNotOk\n   * @alias notOk\n   * @param {Mixed} object to test\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.isNotOk = function (val, msg) {\n    new Assertion(val, msg).is.not.ok;\n  };\n\n  /**\n   * ### .equal(actual, expected, [message])\n   *\n   * Asserts non-strict equality (`==`) of `actual` and `expected`.\n   *\n   *     assert.equal(3, '3', '== coerces values to strings');\n   *\n   * @name equal\n   * @param {Mixed} actual\n   * @param {Mixed} expected\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.equal = function (act, exp, msg) {\n    var test = new Assertion(act, msg, assert.equal);\n\n    test.assert(\n        exp == flag(test, 'object')\n      , 'expected #{this} to equal #{exp}'\n      , 'expected #{this} to not equal #{act}'\n      , exp\n      , act\n    );\n  };\n\n  /**\n   * ### .notEqual(actual, expected, [message])\n   *\n   * Asserts non-strict inequality (`!=`) of `actual` and `expected`.\n   *\n   *     assert.notEqual(3, 4, 'these numbers are not equal');\n   *\n   * @name notEqual\n   * @param {Mixed} actual\n   * @param {Mixed} expected\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.notEqual = function (act, exp, msg) {\n    var test = new Assertion(act, msg, assert.notEqual);\n\n    test.assert(\n        exp != flag(test, 'object')\n      , 'expected #{this} to not equal #{exp}'\n      , 'expected #{this} to equal #{act}'\n      , exp\n      , act\n    );\n  };\n\n  /**\n   * ### .strictEqual(actual, expected, [message])\n   *\n   * Asserts strict equality (`===`) of `actual` and `expected`.\n   *\n   *     assert.strictEqual(true, true, 'these booleans are strictly equal');\n   *\n   * @name strictEqual\n   * @param {Mixed} actual\n   * @param {Mixed} expected\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.strictEqual = function (act, exp, msg) {\n    new Assertion(act, msg).to.equal(exp);\n  };\n\n  /**\n   * ### .notStrictEqual(actual, expected, [message])\n   *\n   * Asserts strict inequality (`!==`) of `actual` and `expected`.\n   *\n   *     assert.notStrictEqual(3, '3', 'no coercion for strict equality');\n   *\n   * @name notStrictEqual\n   * @param {Mixed} actual\n   * @param {Mixed} expected\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.notStrictEqual = function (act, exp, msg) {\n    new Assertion(act, msg).to.not.equal(exp);\n  };\n\n  /**\n   * ### .deepEqual(actual, expected, [message])\n   *\n   * Asserts that `actual` is deeply equal to `expected`.\n   *\n   *     assert.deepEqual({ tea: 'green' }, { tea: 'green' });\n   *\n   * @name deepEqual\n   * @param {Mixed} actual\n   * @param {Mixed} expected\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.deepEqual = function (act, exp, msg) {\n    new Assertion(act, msg).to.eql(exp);\n  };\n\n  /**\n   * ### .notDeepEqual(actual, expected, [message])\n   *\n   * Assert that `actual` is not deeply equal to `expected`.\n   *\n   *     assert.notDeepEqual({ tea: 'green' }, { tea: 'jasmine' });\n   *\n   * @name notDeepEqual\n   * @param {Mixed} actual\n   * @param {Mixed} expected\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.notDeepEqual = function (act, exp, msg) {\n    new Assertion(act, msg).to.not.eql(exp);\n  };\n\n   /**\n   * ### .isAbove(valueToCheck, valueToBeAbove, [message])\n   *\n   * Asserts `valueToCheck` is strictly greater than (>) `valueToBeAbove`\n   *\n   *     assert.isAbove(5, 2, '5 is strictly greater than 2');\n   *\n   * @name isAbove\n   * @param {Mixed} valueToCheck\n   * @param {Mixed} valueToBeAbove\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.isAbove = function (val, abv, msg) {\n    new Assertion(val, msg).to.be.above(abv);\n  };\n\n   /**\n   * ### .isAtLeast(valueToCheck, valueToBeAtLeast, [message])\n   *\n   * Asserts `valueToCheck` is greater than or equal to (>=) `valueToBeAtLeast`\n   *\n   *     assert.isAtLeast(5, 2, '5 is greater or equal to 2');\n   *     assert.isAtLeast(3, 3, '3 is greater or equal to 3');\n   *\n   * @name isAtLeast\n   * @param {Mixed} valueToCheck\n   * @param {Mixed} valueToBeAtLeast\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.isAtLeast = function (val, atlst, msg) {\n    new Assertion(val, msg).to.be.least(atlst);\n  };\n\n   /**\n   * ### .isBelow(valueToCheck, valueToBeBelow, [message])\n   *\n   * Asserts `valueToCheck` is strictly less than (<) `valueToBeBelow`\n   *\n   *     assert.isBelow(3, 6, '3 is strictly less than 6');\n   *\n   * @name isBelow\n   * @param {Mixed} valueToCheck\n   * @param {Mixed} valueToBeBelow\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.isBelow = function (val, blw, msg) {\n    new Assertion(val, msg).to.be.below(blw);\n  };\n\n   /**\n   * ### .isAtMost(valueToCheck, valueToBeAtMost, [message])\n   *\n   * Asserts `valueToCheck` is less than or equal to (<=) `valueToBeAtMost`\n   *\n   *     assert.isAtMost(3, 6, '3 is less than or equal to 6');\n   *     assert.isAtMost(4, 4, '4 is less than or equal to 4');\n   *\n   * @name isAtMost\n   * @param {Mixed} valueToCheck\n   * @param {Mixed} valueToBeAtMost\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.isAtMost = function (val, atmst, msg) {\n    new Assertion(val, msg).to.be.most(atmst);\n  };\n\n  /**\n   * ### .isTrue(value, [message])\n   *\n   * Asserts that `value` is true.\n   *\n   *     var teaServed = true;\n   *     assert.isTrue(teaServed, 'the tea has been served');\n   *\n   * @name isTrue\n   * @param {Mixed} value\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.isTrue = function (val, msg) {\n    new Assertion(val, msg).is['true'];\n  };\n\n  /**\n   * ### .isNotTrue(value, [message])\n   *\n   * Asserts that `value` is not true.\n   *\n   *     var tea = 'tasty chai';\n   *     assert.isNotTrue(tea, 'great, time for tea!');\n   *\n   * @name isNotTrue\n   * @param {Mixed} value\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.isNotTrue = function (val, msg) {\n    new Assertion(val, msg).to.not.equal(true);\n  };\n\n  /**\n   * ### .isFalse(value, [message])\n   *\n   * Asserts that `value` is false.\n   *\n   *     var teaServed = false;\n   *     assert.isFalse(teaServed, 'no tea yet? hmm...');\n   *\n   * @name isFalse\n   * @param {Mixed} value\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.isFalse = function (val, msg) {\n    new Assertion(val, msg).is['false'];\n  };\n\n  /**\n   * ### .isNotFalse(value, [message])\n   *\n   * Asserts that `value` is not false.\n   *\n   *     var tea = 'tasty chai';\n   *     assert.isNotFalse(tea, 'great, time for tea!');\n   *\n   * @name isNotFalse\n   * @param {Mixed} value\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.isNotFalse = function (val, msg) {\n    new Assertion(val, msg).to.not.equal(false);\n  };\n\n  /**\n   * ### .isNull(value, [message])\n   *\n   * Asserts that `value` is null.\n   *\n   *     assert.isNull(err, 'there was no error');\n   *\n   * @name isNull\n   * @param {Mixed} value\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.isNull = function (val, msg) {\n    new Assertion(val, msg).to.equal(null);\n  };\n\n  /**\n   * ### .isNotNull(value, [message])\n   *\n   * Asserts that `value` is not null.\n   *\n   *     var tea = 'tasty chai';\n   *     assert.isNotNull(tea, 'great, time for tea!');\n   *\n   * @name isNotNull\n   * @param {Mixed} value\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.isNotNull = function (val, msg) {\n    new Assertion(val, msg).to.not.equal(null);\n  };\n\n  /**\n   * ### .isNaN\n   * Asserts that value is NaN\n   *\n   *    assert.isNaN('foo', 'foo is NaN');\n   *\n   * @name isNaN\n   * @param {Mixed} value\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.isNaN = function (val, msg) {\n    new Assertion(val, msg).to.be.NaN;\n  };\n\n  /**\n   * ### .isNotNaN\n   * Asserts that value is not NaN\n   *\n   *    assert.isNotNaN(4, '4 is not NaN');\n   *\n   * @name isNotNaN\n   * @param {Mixed} value\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n  assert.isNotNaN = function (val, msg) {\n    new Assertion(val, msg).not.to.be.NaN;\n  };\n\n  /**\n   * ### .isUndefined(value, [message])\n   *\n   * Asserts that `value` is `undefined`.\n   *\n   *     var tea;\n   *     assert.isUndefined(tea, 'no tea defined');\n   *\n   * @name isUndefined\n   * @param {Mixed} value\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.isUndefined = function (val, msg) {\n    new Assertion(val, msg).to.equal(undefined);\n  };\n\n  /**\n   * ### .isDefined(value, [message])\n   *\n   * Asserts that `value` is not `undefined`.\n   *\n   *     var tea = 'cup of chai';\n   *     assert.isDefined(tea, 'tea has been defined');\n   *\n   * @name isDefined\n   * @param {Mixed} value\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.isDefined = function (val, msg) {\n    new Assertion(val, msg).to.not.equal(undefined);\n  };\n\n  /**\n   * ### .isFunction(value, [message])\n   *\n   * Asserts that `value` is a function.\n   *\n   *     function serveTea() { return 'cup of tea'; };\n   *     assert.isFunction(serveTea, 'great, we can have tea now');\n   *\n   * @name isFunction\n   * @param {Mixed} value\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.isFunction = function (val, msg) {\n    new Assertion(val, msg).to.be.a('function');\n  };\n\n  /**\n   * ### .isNotFunction(value, [message])\n   *\n   * Asserts that `value` is _not_ a function.\n   *\n   *     var serveTea = [ 'heat', 'pour', 'sip' ];\n   *     assert.isNotFunction(serveTea, 'great, we have listed the steps');\n   *\n   * @name isNotFunction\n   * @param {Mixed} value\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.isNotFunction = function (val, msg) {\n    new Assertion(val, msg).to.not.be.a('function');\n  };\n\n  /**\n   * ### .isObject(value, [message])\n   *\n   * Asserts that `value` is an object of type 'Object' (as revealed by `Object.prototype.toString`).\n   * _The assertion does not match subclassed objects._\n   *\n   *     var selection = { name: 'Chai', serve: 'with spices' };\n   *     assert.isObject(selection, 'tea selection is an object');\n   *\n   * @name isObject\n   * @param {Mixed} value\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.isObject = function (val, msg) {\n    new Assertion(val, msg).to.be.a('object');\n  };\n\n  /**\n   * ### .isNotObject(value, [message])\n   *\n   * Asserts that `value` is _not_ an object of type 'Object' (as revealed by `Object.prototype.toString`).\n   *\n   *     var selection = 'chai'\n   *     assert.isNotObject(selection, 'tea selection is not an object');\n   *     assert.isNotObject(null, 'null is not an object');\n   *\n   * @name isNotObject\n   * @param {Mixed} value\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.isNotObject = function (val, msg) {\n    new Assertion(val, msg).to.not.be.a('object');\n  };\n\n  /**\n   * ### .isArray(value, [message])\n   *\n   * Asserts that `value` is an array.\n   *\n   *     var menu = [ 'green', 'chai', 'oolong' ];\n   *     assert.isArray(menu, 'what kind of tea do we want?');\n   *\n   * @name isArray\n   * @param {Mixed} value\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.isArray = function (val, msg) {\n    new Assertion(val, msg).to.be.an('array');\n  };\n\n  /**\n   * ### .isNotArray(value, [message])\n   *\n   * Asserts that `value` is _not_ an array.\n   *\n   *     var menu = 'green|chai|oolong';\n   *     assert.isNotArray(menu, 'what kind of tea do we want?');\n   *\n   * @name isNotArray\n   * @param {Mixed} value\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.isNotArray = function (val, msg) {\n    new Assertion(val, msg).to.not.be.an('array');\n  };\n\n  /**\n   * ### .isString(value, [message])\n   *\n   * Asserts that `value` is a string.\n   *\n   *     var teaOrder = 'chai';\n   *     assert.isString(teaOrder, 'order placed');\n   *\n   * @name isString\n   * @param {Mixed} value\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.isString = function (val, msg) {\n    new Assertion(val, msg).to.be.a('string');\n  };\n\n  /**\n   * ### .isNotString(value, [message])\n   *\n   * Asserts that `value` is _not_ a string.\n   *\n   *     var teaOrder = 4;\n   *     assert.isNotString(teaOrder, 'order placed');\n   *\n   * @name isNotString\n   * @param {Mixed} value\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.isNotString = function (val, msg) {\n    new Assertion(val, msg).to.not.be.a('string');\n  };\n\n  /**\n   * ### .isNumber(value, [message])\n   *\n   * Asserts that `value` is a number.\n   *\n   *     var cups = 2;\n   *     assert.isNumber(cups, 'how many cups');\n   *\n   * @name isNumber\n   * @param {Number} value\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.isNumber = function (val, msg) {\n    new Assertion(val, msg).to.be.a('number');\n  };\n\n  /**\n   * ### .isNotNumber(value, [message])\n   *\n   * Asserts that `value` is _not_ a number.\n   *\n   *     var cups = '2 cups please';\n   *     assert.isNotNumber(cups, 'how many cups');\n   *\n   * @name isNotNumber\n   * @param {Mixed} value\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.isNotNumber = function (val, msg) {\n    new Assertion(val, msg).to.not.be.a('number');\n  };\n\n  /**\n   * ### .isBoolean(value, [message])\n   *\n   * Asserts that `value` is a boolean.\n   *\n   *     var teaReady = true\n   *       , teaServed = false;\n   *\n   *     assert.isBoolean(teaReady, 'is the tea ready');\n   *     assert.isBoolean(teaServed, 'has tea been served');\n   *\n   * @name isBoolean\n   * @param {Mixed} value\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.isBoolean = function (val, msg) {\n    new Assertion(val, msg).to.be.a('boolean');\n  };\n\n  /**\n   * ### .isNotBoolean(value, [message])\n   *\n   * Asserts that `value` is _not_ a boolean.\n   *\n   *     var teaReady = 'yep'\n   *       , teaServed = 'nope';\n   *\n   *     assert.isNotBoolean(teaReady, 'is the tea ready');\n   *     assert.isNotBoolean(teaServed, 'has tea been served');\n   *\n   * @name isNotBoolean\n   * @param {Mixed} value\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.isNotBoolean = function (val, msg) {\n    new Assertion(val, msg).to.not.be.a('boolean');\n  };\n\n  /**\n   * ### .typeOf(value, name, [message])\n   *\n   * Asserts that `value`'s type is `name`, as determined by\n   * `Object.prototype.toString`.\n   *\n   *     assert.typeOf({ tea: 'chai' }, 'object', 'we have an object');\n   *     assert.typeOf(['chai', 'jasmine'], 'array', 'we have an array');\n   *     assert.typeOf('tea', 'string', 'we have a string');\n   *     assert.typeOf(/tea/, 'regexp', 'we have a regular expression');\n   *     assert.typeOf(null, 'null', 'we have a null');\n   *     assert.typeOf(undefined, 'undefined', 'we have an undefined');\n   *\n   * @name typeOf\n   * @param {Mixed} value\n   * @param {String} name\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.typeOf = function (val, type, msg) {\n    new Assertion(val, msg).to.be.a(type);\n  };\n\n  /**\n   * ### .notTypeOf(value, name, [message])\n   *\n   * Asserts that `value`'s type is _not_ `name`, as determined by\n   * `Object.prototype.toString`.\n   *\n   *     assert.notTypeOf('tea', 'number', 'strings are not numbers');\n   *\n   * @name notTypeOf\n   * @param {Mixed} value\n   * @param {String} typeof name\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.notTypeOf = function (val, type, msg) {\n    new Assertion(val, msg).to.not.be.a(type);\n  };\n\n  /**\n   * ### .instanceOf(object, constructor, [message])\n   *\n   * Asserts that `value` is an instance of `constructor`.\n   *\n   *     var Tea = function (name) { this.name = name; }\n   *       , chai = new Tea('chai');\n   *\n   *     assert.instanceOf(chai, Tea, 'chai is an instance of tea');\n   *\n   * @name instanceOf\n   * @param {Object} object\n   * @param {Constructor} constructor\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.instanceOf = function (val, type, msg) {\n    new Assertion(val, msg).to.be.instanceOf(type);\n  };\n\n  /**\n   * ### .notInstanceOf(object, constructor, [message])\n   *\n   * Asserts `value` is not an instance of `constructor`.\n   *\n   *     var Tea = function (name) { this.name = name; }\n   *       , chai = new String('chai');\n   *\n   *     assert.notInstanceOf(chai, Tea, 'chai is not an instance of tea');\n   *\n   * @name notInstanceOf\n   * @param {Object} object\n   * @param {Constructor} constructor\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.notInstanceOf = function (val, type, msg) {\n    new Assertion(val, msg).to.not.be.instanceOf(type);\n  };\n\n  /**\n   * ### .include(haystack, needle, [message])\n   *\n   * Asserts that `haystack` includes `needle`. Works\n   * for strings and arrays.\n   *\n   *     assert.include('foobar', 'bar', 'foobar contains string \"bar\"');\n   *     assert.include([ 1, 2, 3 ], 3, 'array contains value');\n   *\n   * @name include\n   * @param {Array|String} haystack\n   * @param {Mixed} needle\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.include = function (exp, inc, msg) {\n    new Assertion(exp, msg, assert.include).include(inc);\n  };\n\n  /**\n   * ### .notInclude(haystack, needle, [message])\n   *\n   * Asserts that `haystack` does not include `needle`. Works\n   * for strings and arrays.\n   *\n   *     assert.notInclude('foobar', 'baz', 'string not include substring');\n   *     assert.notInclude([ 1, 2, 3 ], 4, 'array not include contain value');\n   *\n   * @name notInclude\n   * @param {Array|String} haystack\n   * @param {Mixed} needle\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.notInclude = function (exp, inc, msg) {\n    new Assertion(exp, msg, assert.notInclude).not.include(inc);\n  };\n\n  /**\n   * ### .match(value, regexp, [message])\n   *\n   * Asserts that `value` matches the regular expression `regexp`.\n   *\n   *     assert.match('foobar', /^foo/, 'regexp matches');\n   *\n   * @name match\n   * @param {Mixed} value\n   * @param {RegExp} regexp\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.match = function (exp, re, msg) {\n    new Assertion(exp, msg).to.match(re);\n  };\n\n  /**\n   * ### .notMatch(value, regexp, [message])\n   *\n   * Asserts that `value` does not match the regular expression `regexp`.\n   *\n   *     assert.notMatch('foobar', /^foo/, 'regexp does not match');\n   *\n   * @name notMatch\n   * @param {Mixed} value\n   * @param {RegExp} regexp\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.notMatch = function (exp, re, msg) {\n    new Assertion(exp, msg).to.not.match(re);\n  };\n\n  /**\n   * ### .property(object, property, [message])\n   *\n   * Asserts that `object` has a property named by `property`.\n   *\n   *     assert.property({ tea: { green: 'matcha' }}, 'tea');\n   *\n   * @name property\n   * @param {Object} object\n   * @param {String} property\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.property = function (obj, prop, msg) {\n    new Assertion(obj, msg).to.have.property(prop);\n  };\n\n  /**\n   * ### .notProperty(object, property, [message])\n   *\n   * Asserts that `object` does _not_ have a property named by `property`.\n   *\n   *     assert.notProperty({ tea: { green: 'matcha' }}, 'coffee');\n   *\n   * @name notProperty\n   * @param {Object} object\n   * @param {String} property\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.notProperty = function (obj, prop, msg) {\n    new Assertion(obj, msg).to.not.have.property(prop);\n  };\n\n  /**\n   * ### .deepProperty(object, property, [message])\n   *\n   * Asserts that `object` has a property named by `property`, which can be a\n   * string using dot- and bracket-notation for deep reference.\n   *\n   *     assert.deepProperty({ tea: { green: 'matcha' }}, 'tea.green');\n   *\n   * @name deepProperty\n   * @param {Object} object\n   * @param {String} property\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.deepProperty = function (obj, prop, msg) {\n    new Assertion(obj, msg).to.have.deep.property(prop);\n  };\n\n  /**\n   * ### .notDeepProperty(object, property, [message])\n   *\n   * Asserts that `object` does _not_ have a property named by `property`, which\n   * can be a string using dot- and bracket-notation for deep reference.\n   *\n   *     assert.notDeepProperty({ tea: { green: 'matcha' }}, 'tea.oolong');\n   *\n   * @name notDeepProperty\n   * @param {Object} object\n   * @param {String} property\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.notDeepProperty = function (obj, prop, msg) {\n    new Assertion(obj, msg).to.not.have.deep.property(prop);\n  };\n\n  /**\n   * ### .propertyVal(object, property, value, [message])\n   *\n   * Asserts that `object` has a property named by `property` with value given\n   * by `value`.\n   *\n   *     assert.propertyVal({ tea: 'is good' }, 'tea', 'is good');\n   *\n   * @name propertyVal\n   * @param {Object} object\n   * @param {String} property\n   * @param {Mixed} value\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.propertyVal = function (obj, prop, val, msg) {\n    new Assertion(obj, msg).to.have.property(prop, val);\n  };\n\n  /**\n   * ### .propertyNotVal(object, property, value, [message])\n   *\n   * Asserts that `object` has a property named by `property`, but with a value\n   * different from that given by `value`.\n   *\n   *     assert.propertyNotVal({ tea: 'is good' }, 'tea', 'is bad');\n   *\n   * @name propertyNotVal\n   * @param {Object} object\n   * @param {String} property\n   * @param {Mixed} value\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.propertyNotVal = function (obj, prop, val, msg) {\n    new Assertion(obj, msg).to.not.have.property(prop, val);\n  };\n\n  /**\n   * ### .deepPropertyVal(object, property, value, [message])\n   *\n   * Asserts that `object` has a property named by `property` with value given\n   * by `value`. `property` can use dot- and bracket-notation for deep\n   * reference.\n   *\n   *     assert.deepPropertyVal({ tea: { green: 'matcha' }}, 'tea.green', 'matcha');\n   *\n   * @name deepPropertyVal\n   * @param {Object} object\n   * @param {String} property\n   * @param {Mixed} value\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.deepPropertyVal = function (obj, prop, val, msg) {\n    new Assertion(obj, msg).to.have.deep.property(prop, val);\n  };\n\n  /**\n   * ### .deepPropertyNotVal(object, property, value, [message])\n   *\n   * Asserts that `object` has a property named by `property`, but with a value\n   * different from that given by `value`. `property` can use dot- and\n   * bracket-notation for deep reference.\n   *\n   *     assert.deepPropertyNotVal({ tea: { green: 'matcha' }}, 'tea.green', 'konacha');\n   *\n   * @name deepPropertyNotVal\n   * @param {Object} object\n   * @param {String} property\n   * @param {Mixed} value\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.deepPropertyNotVal = function (obj, prop, val, msg) {\n    new Assertion(obj, msg).to.not.have.deep.property(prop, val);\n  };\n\n  /**\n   * ### .lengthOf(object, length, [message])\n   *\n   * Asserts that `object` has a `length` property with the expected value.\n   *\n   *     assert.lengthOf([1,2,3], 3, 'array has length of 3');\n   *     assert.lengthOf('foobar', 6, 'string has length of 6');\n   *\n   * @name lengthOf\n   * @param {Mixed} object\n   * @param {Number} length\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.lengthOf = function (exp, len, msg) {\n    new Assertion(exp, msg).to.have.length(len);\n  };\n\n  /**\n   * ### .throws(function, [constructor/string/regexp], [string/regexp], [message])\n   *\n   * Asserts that `function` will throw an error that is an instance of\n   * `constructor`, or alternately that it will throw an error with message\n   * matching `regexp`.\n   *\n   *     assert.throws(fn, 'function throws a reference error');\n   *     assert.throws(fn, /function throws a reference error/);\n   *     assert.throws(fn, ReferenceError);\n   *     assert.throws(fn, ReferenceError, 'function throws a reference error');\n   *     assert.throws(fn, ReferenceError, /function throws a reference error/);\n   *\n   * @name throws\n   * @alias throw\n   * @alias Throw\n   * @param {Function} function\n   * @param {ErrorConstructor} constructor\n   * @param {RegExp} regexp\n   * @param {String} message\n   * @see https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Error#Error_types\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.throws = function (fn, errt, errs, msg) {\n    if ('string' === typeof errt || errt instanceof RegExp) {\n      errs = errt;\n      errt = null;\n    }\n\n    var assertErr = new Assertion(fn, msg).to.throw(errt, errs);\n    return flag(assertErr, 'object');\n  };\n\n  /**\n   * ### .doesNotThrow(function, [constructor/regexp], [message])\n   *\n   * Asserts that `function` will _not_ throw an error that is an instance of\n   * `constructor`, or alternately that it will not throw an error with message\n   * matching `regexp`.\n   *\n   *     assert.doesNotThrow(fn, Error, 'function does not throw');\n   *\n   * @name doesNotThrow\n   * @param {Function} function\n   * @param {ErrorConstructor} constructor\n   * @param {RegExp} regexp\n   * @param {String} message\n   * @see https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Error#Error_types\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.doesNotThrow = function (fn, type, msg) {\n    if ('string' === typeof type) {\n      msg = type;\n      type = null;\n    }\n\n    new Assertion(fn, msg).to.not.Throw(type);\n  };\n\n  /**\n   * ### .operator(val1, operator, val2, [message])\n   *\n   * Compares two values using `operator`.\n   *\n   *     assert.operator(1, '<', 2, 'everything is ok');\n   *     assert.operator(1, '>', 2, 'this will fail');\n   *\n   * @name operator\n   * @param {Mixed} val1\n   * @param {String} operator\n   * @param {Mixed} val2\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.operator = function (val, operator, val2, msg) {\n    var ok;\n    switch(operator) {\n      case '==':\n        ok = val == val2;\n        break;\n      case '===':\n        ok = val === val2;\n        break;\n      case '>':\n        ok = val > val2;\n        break;\n      case '>=':\n        ok = val >= val2;\n        break;\n      case '<':\n        ok = val < val2;\n        break;\n      case '<=':\n        ok = val <= val2;\n        break;\n      case '!=':\n        ok = val != val2;\n        break;\n      case '!==':\n        ok = val !== val2;\n        break;\n      default:\n        throw new Error('Invalid operator \"' + operator + '\"');\n    }\n    var test = new Assertion(ok, msg);\n    test.assert(\n        true === flag(test, 'object')\n      , 'expected ' + util.inspect(val) + ' to be ' + operator + ' ' + util.inspect(val2)\n      , 'expected ' + util.inspect(val) + ' to not be ' + operator + ' ' + util.inspect(val2) );\n  };\n\n  /**\n   * ### .closeTo(actual, expected, delta, [message])\n   *\n   * Asserts that the target is equal `expected`, to within a +/- `delta` range.\n   *\n   *     assert.closeTo(1.5, 1, 0.5, 'numbers are close');\n   *\n   * @name closeTo\n   * @param {Number} actual\n   * @param {Number} expected\n   * @param {Number} delta\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.closeTo = function (act, exp, delta, msg) {\n    new Assertion(act, msg).to.be.closeTo(exp, delta);\n  };\n\n  /**\n   * ### .approximately(actual, expected, delta, [message])\n   *\n   * Asserts that the target is equal `expected`, to within a +/- `delta` range.\n   *\n   *     assert.approximately(1.5, 1, 0.5, 'numbers are close');\n   *\n   * @name approximately\n   * @param {Number} actual\n   * @param {Number} expected\n   * @param {Number} delta\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.approximately = function (act, exp, delta, msg) {\n    new Assertion(act, msg).to.be.approximately(exp, delta);\n  };\n\n  /**\n   * ### .sameMembers(set1, set2, [message])\n   *\n   * Asserts that `set1` and `set2` have the same members.\n   * Order is not taken into account.\n   *\n   *     assert.sameMembers([ 1, 2, 3 ], [ 2, 1, 3 ], 'same members');\n   *\n   * @name sameMembers\n   * @param {Array} set1\n   * @param {Array} set2\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.sameMembers = function (set1, set2, msg) {\n    new Assertion(set1, msg).to.have.same.members(set2);\n  }\n\n  /**\n   * ### .sameDeepMembers(set1, set2, [message])\n   *\n   * Asserts that `set1` and `set2` have the same members - using a deep equality checking.\n   * Order is not taken into account.\n   *\n   *     assert.sameDeepMembers([ {b: 3}, {a: 2}, {c: 5} ], [ {c: 5}, {b: 3}, {a: 2} ], 'same deep members');\n   *\n   * @name sameDeepMembers\n   * @param {Array} set1\n   * @param {Array} set2\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.sameDeepMembers = function (set1, set2, msg) {\n    new Assertion(set1, msg).to.have.same.deep.members(set2);\n  }\n\n  /**\n   * ### .includeMembers(superset, subset, [message])\n   *\n   * Asserts that `subset` is included in `superset`.\n   * Order is not taken into account.\n   *\n   *     assert.includeMembers([ 1, 2, 3 ], [ 2, 1 ], 'include members');\n   *\n   * @name includeMembers\n   * @param {Array} superset\n   * @param {Array} subset\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.includeMembers = function (superset, subset, msg) {\n    new Assertion(superset, msg).to.include.members(subset);\n  }\n\n  /**\n   * ### .includeDeepMembers(superset, subset, [message])\n   *\n   * Asserts that `subset` is included in `superset` - using deep equality checking.\n   * Order is not taken into account.\n   * Duplicates are ignored.\n   *\n   *     assert.includeDeepMembers([ {a: 1}, {b: 2}, {c: 3} ], [ {b: 2}, {a: 1}, {b: 2} ], 'include deep members');\n   *\n   * @name includeDeepMembers\n   * @param {Array} superset\n   * @param {Array} subset\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.includeDeepMembers = function (superset, subset, msg) {\n    new Assertion(superset, msg).to.include.deep.members(subset);\n  }\n\n  /**\n   * ### .oneOf(inList, list, [message])\n   *\n   * Asserts that non-object, non-array value `inList` appears in the flat array `list`.\n   *\n   *     assert.oneOf(1, [ 2, 1 ], 'Not found in list');\n   *\n   * @name oneOf\n   * @param {*} inList\n   * @param {Array<*>} list\n   * @param {String} message\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.oneOf = function (inList, list, msg) {\n    new Assertion(inList, msg).to.be.oneOf(list);\n  }\n\n   /**\n   * ### .changes(function, object, property)\n   *\n   * Asserts that a function changes the value of a property\n   *\n   *     var obj = { val: 10 };\n   *     var fn = function() { obj.val = 22 };\n   *     assert.changes(fn, obj, 'val');\n   *\n   * @name changes\n   * @param {Function} modifier function\n   * @param {Object} object\n   * @param {String} property name\n   * @param {String} message _optional_\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.changes = function (fn, obj, prop) {\n    new Assertion(fn).to.change(obj, prop);\n  }\n\n   /**\n   * ### .doesNotChange(function, object, property)\n   *\n   * Asserts that a function does not changes the value of a property\n   *\n   *     var obj = { val: 10 };\n   *     var fn = function() { console.log('foo'); };\n   *     assert.doesNotChange(fn, obj, 'val');\n   *\n   * @name doesNotChange\n   * @param {Function} modifier function\n   * @param {Object} object\n   * @param {String} property name\n   * @param {String} message _optional_\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.doesNotChange = function (fn, obj, prop) {\n    new Assertion(fn).to.not.change(obj, prop);\n  }\n\n   /**\n   * ### .increases(function, object, property)\n   *\n   * Asserts that a function increases an object property\n   *\n   *     var obj = { val: 10 };\n   *     var fn = function() { obj.val = 13 };\n   *     assert.increases(fn, obj, 'val');\n   *\n   * @name increases\n   * @param {Function} modifier function\n   * @param {Object} object\n   * @param {String} property name\n   * @param {String} message _optional_\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.increases = function (fn, obj, prop) {\n    new Assertion(fn).to.increase(obj, prop);\n  }\n\n   /**\n   * ### .doesNotIncrease(function, object, property)\n   *\n   * Asserts that a function does not increase object property\n   *\n   *     var obj = { val: 10 };\n   *     var fn = function() { obj.val = 8 };\n   *     assert.doesNotIncrease(fn, obj, 'val');\n   *\n   * @name doesNotIncrease\n   * @param {Function} modifier function\n   * @param {Object} object\n   * @param {String} property name\n   * @param {String} message _optional_\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.doesNotIncrease = function (fn, obj, prop) {\n    new Assertion(fn).to.not.increase(obj, prop);\n  }\n\n   /**\n   * ### .decreases(function, object, property)\n   *\n   * Asserts that a function decreases an object property\n   *\n   *     var obj = { val: 10 };\n   *     var fn = function() { obj.val = 5 };\n   *     assert.decreases(fn, obj, 'val');\n   *\n   * @name decreases\n   * @param {Function} modifier function\n   * @param {Object} object\n   * @param {String} property name\n   * @param {String} message _optional_\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.decreases = function (fn, obj, prop) {\n    new Assertion(fn).to.decrease(obj, prop);\n  }\n\n   /**\n   * ### .doesNotDecrease(function, object, property)\n   *\n   * Asserts that a function does not decreases an object property\n   *\n   *     var obj = { val: 10 };\n   *     var fn = function() { obj.val = 15 };\n   *     assert.doesNotDecrease(fn, obj, 'val');\n   *\n   * @name doesNotDecrease\n   * @param {Function} modifier function\n   * @param {Object} object\n   * @param {String} property name\n   * @param {String} message _optional_\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.doesNotDecrease = function (fn, obj, prop) {\n    new Assertion(fn).to.not.decrease(obj, prop);\n  }\n\n  /*!\n   * ### .ifError(object)\n   *\n   * Asserts if value is not a false value, and throws if it is a true value.\n   * This is added to allow for chai to be a drop-in replacement for Node's\n   * assert class.\n   *\n   *     var err = new Error('I am a custom error');\n   *     assert.ifError(err); // Rethrows err!\n   *\n   * @name ifError\n   * @param {Object} object\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.ifError = function (val) {\n    if (val) {\n      throw(val);\n    }\n  };\n\n  /**\n   * ### .isExtensible(object)\n   *\n   * Asserts that `object` is extensible (can have new properties added to it).\n   *\n   *     assert.isExtensible({});\n   *\n   * @name isExtensible\n   * @alias extensible\n   * @param {Object} object\n   * @param {String} message _optional_\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.isExtensible = function (obj, msg) {\n    new Assertion(obj, msg).to.be.extensible;\n  };\n\n  /**\n   * ### .isNotExtensible(object)\n   *\n   * Asserts that `object` is _not_ extensible.\n   *\n   *     var nonExtensibleObject = Object.preventExtensions({});\n   *     var sealedObject = Object.seal({});\n   *     var frozenObject = Object.freese({});\n   *\n   *     assert.isNotExtensible(nonExtensibleObject);\n   *     assert.isNotExtensible(sealedObject);\n   *     assert.isNotExtensible(frozenObject);\n   *\n   * @name isNotExtensible\n   * @alias notExtensible\n   * @param {Object} object\n   * @param {String} message _optional_\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.isNotExtensible = function (obj, msg) {\n    new Assertion(obj, msg).to.not.be.extensible;\n  };\n\n  /**\n   * ### .isSealed(object)\n   *\n   * Asserts that `object` is sealed (cannot have new properties added to it\n   * and its existing properties cannot be removed).\n   *\n   *     var sealedObject = Object.seal({});\n   *     var frozenObject = Object.seal({});\n   *\n   *     assert.isSealed(sealedObject);\n   *     assert.isSealed(frozenObject);\n   *\n   * @name isSealed\n   * @alias sealed\n   * @param {Object} object\n   * @param {String} message _optional_\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.isSealed = function (obj, msg) {\n    new Assertion(obj, msg).to.be.sealed;\n  };\n\n  /**\n   * ### .isNotSealed(object)\n   *\n   * Asserts that `object` is _not_ sealed.\n   *\n   *     assert.isNotSealed({});\n   *\n   * @name isNotSealed\n   * @alias notSealed\n   * @param {Object} object\n   * @param {String} message _optional_\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.isNotSealed = function (obj, msg) {\n    new Assertion(obj, msg).to.not.be.sealed;\n  };\n\n  /**\n   * ### .isFrozen(object)\n   *\n   * Asserts that `object` is frozen (cannot have new properties added to it\n   * and its existing properties cannot be modified).\n   *\n   *     var frozenObject = Object.freeze({});\n   *     assert.frozen(frozenObject);\n   *\n   * @name isFrozen\n   * @alias frozen\n   * @param {Object} object\n   * @param {String} message _optional_\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.isFrozen = function (obj, msg) {\n    new Assertion(obj, msg).to.be.frozen;\n  };\n\n  /**\n   * ### .isNotFrozen(object)\n   *\n   * Asserts that `object` is _not_ frozen.\n   *\n   *     assert.isNotFrozen({});\n   *\n   * @name isNotFrozen\n   * @alias notFrozen\n   * @param {Object} object\n   * @param {String} message _optional_\n   * @namespace Assert\n   * @api public\n   */\n\n  assert.isNotFrozen = function (obj, msg) {\n    new Assertion(obj, msg).to.not.be.frozen;\n  };\n\n  /*!\n   * Aliases.\n   */\n\n  (function alias(name, as){\n    assert[as] = assert[name];\n    return alias;\n  })\n  ('isOk', 'ok')\n  ('isNotOk', 'notOk')\n  ('throws', 'throw')\n  ('throws', 'Throw')\n  ('isExtensible', 'extensible')\n  ('isNotExtensible', 'notExtensible')\n  ('isSealed', 'sealed')\n  ('isNotSealed', 'notSealed')\n  ('isFrozen', 'frozen')\n  ('isNotFrozen', 'notFrozen');\n};\n\n},{}],7:[function(require,module,exports){\n/*!\n * chai\n * Copyright(c) 2011-2014 Jake Luer <jake@alogicalparadox.com>\n * MIT Licensed\n */\n\nmodule.exports = function (chai, util) {\n  chai.expect = function (val, message) {\n    return new chai.Assertion(val, message);\n  };\n\n  /**\n   * ### .fail(actual, expected, [message], [operator])\n   *\n   * Throw a failure.\n   *\n   * @name fail\n   * @param {Mixed} actual\n   * @param {Mixed} expected\n   * @param {String} message\n   * @param {String} operator\n   * @namespace Expect\n   * @api public\n   */\n\n  chai.expect.fail = function (actual, expected, message, operator) {\n    message = message || 'expect.fail()';\n    throw new chai.AssertionError(message, {\n        actual: actual\n      , expected: expected\n      , operator: operator\n    }, chai.expect.fail);\n  };\n};\n\n},{}],8:[function(require,module,exports){\n/*!\n * chai\n * Copyright(c) 2011-2014 Jake Luer <jake@alogicalparadox.com>\n * MIT Licensed\n */\n\nmodule.exports = function (chai, util) {\n  var Assertion = chai.Assertion;\n\n  function loadShould () {\n    // explicitly define this method as function as to have it's name to include as `ssfi`\n    function shouldGetter() {\n      if (this instanceof String || this instanceof Number || this instanceof Boolean ) {\n        return new Assertion(this.valueOf(), null, shouldGetter);\n      }\n      return new Assertion(this, null, shouldGetter);\n    }\n    function shouldSetter(value) {\n      // See https://github.com/chaijs/chai/issues/86: this makes\n      // `whatever.should = someValue` actually set `someValue`, which is\n      // especially useful for `global.should = require('chai').should()`.\n      //\n      // Note that we have to use [[DefineProperty]] instead of [[Put]]\n      // since otherwise we would trigger this very setter!\n      Object.defineProperty(this, 'should', {\n        value: value,\n        enumerable: true,\n        configurable: true,\n        writable: true\n      });\n    }\n    // modify Object.prototype to have `should`\n    Object.defineProperty(Object.prototype, 'should', {\n      set: shouldSetter\n      , get: shouldGetter\n      , configurable: true\n    });\n\n    var should = {};\n\n    /**\n     * ### .fail(actual, expected, [message], [operator])\n     *\n     * Throw a failure.\n     *\n     * @name fail\n     * @param {Mixed} actual\n     * @param {Mixed} expected\n     * @param {String} message\n     * @param {String} operator\n     * @namespace Should\n     * @api public\n     */\n\n    should.fail = function (actual, expected, message, operator) {\n      message = message || 'should.fail()';\n      throw new chai.AssertionError(message, {\n          actual: actual\n        , expected: expected\n        , operator: operator\n      }, should.fail);\n    };\n\n    /**\n     * ### .equal(actual, expected, [message])\n     *\n     * Asserts non-strict equality (`==`) of `actual` and `expected`.\n     *\n     *     should.equal(3, '3', '== coerces values to strings');\n     *\n     * @name equal\n     * @param {Mixed} actual\n     * @param {Mixed} expected\n     * @param {String} message\n     * @namespace Should\n     * @api public\n     */\n\n    should.equal = function (val1, val2, msg) {\n      new Assertion(val1, msg).to.equal(val2);\n    };\n\n    /**\n     * ### .throw(function, [constructor/string/regexp], [string/regexp], [message])\n     *\n     * Asserts that `function` will throw an error that is an instance of\n     * `constructor`, or alternately that it will throw an error with message\n     * matching `regexp`.\n     *\n     *     should.throw(fn, 'function throws a reference error');\n     *     should.throw(fn, /function throws a reference error/);\n     *     should.throw(fn, ReferenceError);\n     *     should.throw(fn, ReferenceError, 'function throws a reference error');\n     *     should.throw(fn, ReferenceError, /function throws a reference error/);\n     *\n     * @name throw\n     * @alias Throw\n     * @param {Function} function\n     * @param {ErrorConstructor} constructor\n     * @param {RegExp} regexp\n     * @param {String} message\n     * @see https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Error#Error_types\n     * @namespace Should\n     * @api public\n     */\n\n    should.Throw = function (fn, errt, errs, msg) {\n      new Assertion(fn, msg).to.Throw(errt, errs);\n    };\n\n    /**\n     * ### .exist\n     *\n     * Asserts that the target is neither `null` nor `undefined`.\n     *\n     *     var foo = 'hi';\n     *\n     *     should.exist(foo, 'foo exists');\n     *\n     * @name exist\n     * @namespace Should\n     * @api public\n     */\n\n    should.exist = function (val, msg) {\n      new Assertion(val, msg).to.exist;\n    }\n\n    // negation\n    should.not = {}\n\n    /**\n     * ### .not.equal(actual, expected, [message])\n     *\n     * Asserts non-strict inequality (`!=`) of `actual` and `expected`.\n     *\n     *     should.not.equal(3, 4, 'these numbers are not equal');\n     *\n     * @name not.equal\n     * @param {Mixed} actual\n     * @param {Mixed} expected\n     * @param {String} message\n     * @namespace Should\n     * @api public\n     */\n\n    should.not.equal = function (val1, val2, msg) {\n      new Assertion(val1, msg).to.not.equal(val2);\n    };\n\n    /**\n     * ### .throw(function, [constructor/regexp], [message])\n     *\n     * Asserts that `function` will _not_ throw an error that is an instance of\n     * `constructor`, or alternately that it will not throw an error with message\n     * matching `regexp`.\n     *\n     *     should.not.throw(fn, Error, 'function does not throw');\n     *\n     * @name not.throw\n     * @alias not.Throw\n     * @param {Function} function\n     * @param {ErrorConstructor} constructor\n     * @param {RegExp} regexp\n     * @param {String} message\n     * @see https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Error#Error_types\n     * @namespace Should\n     * @api public\n     */\n\n    should.not.Throw = function (fn, errt, errs, msg) {\n      new Assertion(fn, msg).to.not.Throw(errt, errs);\n    };\n\n    /**\n     * ### .not.exist\n     *\n     * Asserts that the target is neither `null` nor `undefined`.\n     *\n     *     var bar = null;\n     *\n     *     should.not.exist(bar, 'bar does not exist');\n     *\n     * @name not.exist\n     * @namespace Should\n     * @api public\n     */\n\n    should.not.exist = function (val, msg) {\n      new Assertion(val, msg).to.not.exist;\n    }\n\n    should['throw'] = should['Throw'];\n    should.not['throw'] = should.not['Throw'];\n\n    return should;\n  };\n\n  chai.should = loadShould;\n  chai.Should = loadShould;\n};\n\n},{}],9:[function(require,module,exports){\n/*!\n * Chai - addChainingMethod utility\n * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com>\n * MIT Licensed\n */\n\n/*!\n * Module dependencies\n */\n\nvar transferFlags = require('./transferFlags');\nvar flag = require('./flag');\nvar config = require('../config');\n\n/*!\n * Module variables\n */\n\n// Check whether `__proto__` is supported\nvar hasProtoSupport = '__proto__' in Object;\n\n// Without `__proto__` support, this module will need to add properties to a function.\n// However, some Function.prototype methods cannot be overwritten,\n// and there seems no easy cross-platform way to detect them (@see chaijs/chai/issues/69).\nvar excludeNames = /^(?:length|name|arguments|caller)$/;\n\n// Cache `Function` properties\nvar call  = Function.prototype.call,\n    apply = Function.prototype.apply;\n\n/**\n * ### addChainableMethod (ctx, name, method, chainingBehavior)\n *\n * Adds a method to an object, such that the method can also be chained.\n *\n *     utils.addChainableMethod(chai.Assertion.prototype, 'foo', function (str) {\n *       var obj = utils.flag(this, 'object');\n *       new chai.Assertion(obj).to.be.equal(str);\n *     });\n *\n * Can also be accessed directly from `chai.Assertion`.\n *\n *     chai.Assertion.addChainableMethod('foo', fn, chainingBehavior);\n *\n * The result can then be used as both a method assertion, executing both `method` and\n * `chainingBehavior`, or as a language chain, which only executes `chainingBehavior`.\n *\n *     expect(fooStr).to.be.foo('bar');\n *     expect(fooStr).to.be.foo.equal('foo');\n *\n * @param {Object} ctx object to which the method is added\n * @param {String} name of method to add\n * @param {Function} method function to be used for `name`, when called\n * @param {Function} chainingBehavior function to be called every time the property is accessed\n * @namespace Utils\n * @name addChainableMethod\n * @api public\n */\n\nmodule.exports = function (ctx, name, method, chainingBehavior) {\n  if (typeof chainingBehavior !== 'function') {\n    chainingBehavior = function () { };\n  }\n\n  var chainableBehavior = {\n      method: method\n    , chainingBehavior: chainingBehavior\n  };\n\n  // save the methods so we can overwrite them later, if we need to.\n  if (!ctx.__methods) {\n    ctx.__methods = {};\n  }\n  ctx.__methods[name] = chainableBehavior;\n\n  Object.defineProperty(ctx, name,\n    { get: function () {\n        chainableBehavior.chainingBehavior.call(this);\n\n        var assert = function assert() {\n          var old_ssfi = flag(this, 'ssfi');\n          if (old_ssfi && config.includeStack === false)\n            flag(this, 'ssfi', assert);\n          var result = chainableBehavior.method.apply(this, arguments);\n          return result === undefined ? this : result;\n        };\n\n        // Use `__proto__` if available\n        if (hasProtoSupport) {\n          // Inherit all properties from the object by replacing the `Function` prototype\n          var prototype = assert.__proto__ = Object.create(this);\n          // Restore the `call` and `apply` methods from `Function`\n          prototype.call = call;\n          prototype.apply = apply;\n        }\n        // Otherwise, redefine all properties (slow!)\n        else {\n          var asserterNames = Object.getOwnPropertyNames(ctx);\n          asserterNames.forEach(function (asserterName) {\n            if (!excludeNames.test(asserterName)) {\n              var pd = Object.getOwnPropertyDescriptor(ctx, asserterName);\n              Object.defineProperty(assert, asserterName, pd);\n            }\n          });\n        }\n\n        transferFlags(this, assert);\n        return assert;\n      }\n    , configurable: true\n  });\n};\n\n},{\"../config\":4,\"./flag\":13,\"./transferFlags\":29}],10:[function(require,module,exports){\n/*!\n * Chai - addMethod utility\n * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com>\n * MIT Licensed\n */\n\nvar config = require('../config');\n\n/**\n * ### .addMethod (ctx, name, method)\n *\n * Adds a method to the prototype of an object.\n *\n *     utils.addMethod(chai.Assertion.prototype, 'foo', function (str) {\n *       var obj = utils.flag(this, 'object');\n *       new chai.Assertion(obj).to.be.equal(str);\n *     });\n *\n * Can also be accessed directly from `chai.Assertion`.\n *\n *     chai.Assertion.addMethod('foo', fn);\n *\n * Then can be used as any other assertion.\n *\n *     expect(fooStr).to.be.foo('bar');\n *\n * @param {Object} ctx object to which the method is added\n * @param {String} name of method to add\n * @param {Function} method function to be used for name\n * @namespace Utils\n * @name addMethod\n * @api public\n */\nvar flag = require('./flag');\n\nmodule.exports = function (ctx, name, method) {\n  ctx[name] = function () {\n    var old_ssfi = flag(this, 'ssfi');\n    if (old_ssfi && config.includeStack === false)\n      flag(this, 'ssfi', ctx[name]);\n    var result = method.apply(this, arguments);\n    return result === undefined ? this : result;\n  };\n};\n\n},{\"../config\":4,\"./flag\":13}],11:[function(require,module,exports){\n/*!\n * Chai - addProperty utility\n * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com>\n * MIT Licensed\n */\n\nvar config = require('../config');\nvar flag = require('./flag');\n\n/**\n * ### addProperty (ctx, name, getter)\n *\n * Adds a property to the prototype of an object.\n *\n *     utils.addProperty(chai.Assertion.prototype, 'foo', function () {\n *       var obj = utils.flag(this, 'object');\n *       new chai.Assertion(obj).to.be.instanceof(Foo);\n *     });\n *\n * Can also be accessed directly from `chai.Assertion`.\n *\n *     chai.Assertion.addProperty('foo', fn);\n *\n * Then can be used as any other assertion.\n *\n *     expect(myFoo).to.be.foo;\n *\n * @param {Object} ctx object to which the property is added\n * @param {String} name of property to add\n * @param {Function} getter function to be used for name\n * @namespace Utils\n * @name addProperty\n * @api public\n */\n\nmodule.exports = function (ctx, name, getter) {\n  Object.defineProperty(ctx, name,\n    { get: function addProperty() {\n        var old_ssfi = flag(this, 'ssfi');\n        if (old_ssfi && config.includeStack === false)\n          flag(this, 'ssfi', addProperty);\n\n        var result = getter.call(this);\n        return result === undefined ? this : result;\n      }\n    , configurable: true\n  });\n};\n\n},{\"../config\":4,\"./flag\":13}],12:[function(require,module,exports){\n/*!\n * Chai - expectTypes utility\n * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com>\n * MIT Licensed\n */\n\n/**\n * ### expectTypes(obj, types)\n *\n * Ensures that the object being tested against is of a valid type.\n *\n *     utils.expectTypes(this, ['array', 'object', 'string']);\n *\n * @param {Mixed} obj constructed Assertion\n * @param {Array} type A list of allowed types for this assertion\n * @namespace Utils\n * @name expectTypes\n * @api public\n */\n\nvar AssertionError = require('assertion-error');\nvar flag = require('./flag');\nvar type = require('type-detect');\n\nmodule.exports = function (obj, types) {\n  var obj = flag(obj, 'object');\n  types = types.map(function (t) { return t.toLowerCase(); });\n  types.sort();\n\n  // Transforms ['lorem', 'ipsum'] into 'a lirum, or an ipsum'\n  var str = types.map(function (t, index) {\n    var art = ~[ 'a', 'e', 'i', 'o', 'u' ].indexOf(t.charAt(0)) ? 'an' : 'a';\n    var or = types.length > 1 && index === types.length - 1 ? 'or ' : '';\n    return or + art + ' ' + t;\n  }).join(', ');\n\n  if (!types.some(function (expected) { return type(obj) === expected; })) {\n    throw new AssertionError(\n      'object tested must be ' + str + ', but ' + type(obj) + ' given'\n    );\n  }\n};\n\n},{\"./flag\":13,\"assertion-error\":30,\"type-detect\":35}],13:[function(require,module,exports){\n/*!\n * Chai - flag utility\n * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com>\n * MIT Licensed\n */\n\n/**\n * ### flag(object, key, [value])\n *\n * Get or set a flag value on an object. If a\n * value is provided it will be set, else it will\n * return the currently set value or `undefined` if\n * the value is not set.\n *\n *     utils.flag(this, 'foo', 'bar'); // setter\n *     utils.flag(this, 'foo'); // getter, returns `bar`\n *\n * @param {Object} object constructed Assertion\n * @param {String} key\n * @param {Mixed} value (optional)\n * @namespace Utils\n * @name flag\n * @api private\n */\n\nmodule.exports = function (obj, key, value) {\n  var flags = obj.__flags || (obj.__flags = Object.create(null));\n  if (arguments.length === 3) {\n    flags[key] = value;\n  } else {\n    return flags[key];\n  }\n};\n\n},{}],14:[function(require,module,exports){\n/*!\n * Chai - getActual utility\n * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com>\n * MIT Licensed\n */\n\n/**\n * # getActual(object, [actual])\n *\n * Returns the `actual` value for an Assertion\n *\n * @param {Object} object (constructed Assertion)\n * @param {Arguments} chai.Assertion.prototype.assert arguments\n * @namespace Utils\n * @name getActual\n */\n\nmodule.exports = function (obj, args) {\n  return args.length > 4 ? args[4] : obj._obj;\n};\n\n},{}],15:[function(require,module,exports){\n/*!\n * Chai - getEnumerableProperties utility\n * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com>\n * MIT Licensed\n */\n\n/**\n * ### .getEnumerableProperties(object)\n *\n * This allows the retrieval of enumerable property names of an object,\n * inherited or not.\n *\n * @param {Object} object\n * @returns {Array}\n * @namespace Utils\n * @name getEnumerableProperties\n * @api public\n */\n\nmodule.exports = function getEnumerableProperties(object) {\n  var result = [];\n  for (var name in object) {\n    result.push(name);\n  }\n  return result;\n};\n\n},{}],16:[function(require,module,exports){\n/*!\n * Chai - message composition utility\n * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com>\n * MIT Licensed\n */\n\n/*!\n * Module dependancies\n */\n\nvar flag = require('./flag')\n  , getActual = require('./getActual')\n  , inspect = require('./inspect')\n  , objDisplay = require('./objDisplay');\n\n/**\n * ### .getMessage(object, message, negateMessage)\n *\n * Construct the error message based on flags\n * and template tags. Template tags will return\n * a stringified inspection of the object referenced.\n *\n * Message template tags:\n * - `#{this}` current asserted object\n * - `#{act}` actual value\n * - `#{exp}` expected value\n *\n * @param {Object} object (constructed Assertion)\n * @param {Arguments} chai.Assertion.prototype.assert arguments\n * @namespace Utils\n * @name getMessage\n * @api public\n */\n\nmodule.exports = function (obj, args) {\n  var negate = flag(obj, 'negate')\n    , val = flag(obj, 'object')\n    , expected = args[3]\n    , actual = getActual(obj, args)\n    , msg = negate ? args[2] : args[1]\n    , flagMsg = flag(obj, 'message');\n\n  if(typeof msg === \"function\") msg = msg();\n  msg = msg || '';\n  msg = msg\n    .replace(/#\\{this\\}/g, function () { return objDisplay(val); })\n    .replace(/#\\{act\\}/g, function () { return objDisplay(actual); })\n    .replace(/#\\{exp\\}/g, function () { return objDisplay(expected); });\n\n  return flagMsg ? flagMsg + ': ' + msg : msg;\n};\n\n},{\"./flag\":13,\"./getActual\":14,\"./inspect\":23,\"./objDisplay\":24}],17:[function(require,module,exports){\n/*!\n * Chai - getName utility\n * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com>\n * MIT Licensed\n */\n\n/**\n * # getName(func)\n *\n * Gets the name of a function, in a cross-browser way.\n *\n * @param {Function} a function (usually a constructor)\n * @namespace Utils\n * @name getName\n */\n\nmodule.exports = function (func) {\n  if (func.name) return func.name;\n\n  var match = /^\\s?function ([^(]*)\\(/.exec(func);\n  return match && match[1] ? match[1] : \"\";\n};\n\n},{}],18:[function(require,module,exports){\n/*!\n * Chai - getPathInfo utility\n * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com>\n * MIT Licensed\n */\n\nvar hasProperty = require('./hasProperty');\n\n/**\n * ### .getPathInfo(path, object)\n *\n * This allows the retrieval of property info in an\n * object given a string path.\n *\n * The path info consists of an object with the\n * following properties:\n *\n * * parent - The parent object of the property referenced by `path`\n * * name - The name of the final property, a number if it was an array indexer\n * * value - The value of the property, if it exists, otherwise `undefined`\n * * exists - Whether the property exists or not\n *\n * @param {String} path\n * @param {Object} object\n * @returns {Object} info\n * @namespace Utils\n * @name getPathInfo\n * @api public\n */\n\nmodule.exports = function getPathInfo(path, obj) {\n  var parsed = parsePath(path),\n      last = parsed[parsed.length - 1];\n\n  var info = {\n    parent: parsed.length > 1 ? _getPathValue(parsed, obj, parsed.length - 1) : obj,\n    name: last.p || last.i,\n    value: _getPathValue(parsed, obj)\n  };\n  info.exists = hasProperty(info.name, info.parent);\n\n  return info;\n};\n\n\n/*!\n * ## parsePath(path)\n *\n * Helper function used to parse string object\n * paths. Use in conjunction with `_getPathValue`.\n *\n *      var parsed = parsePath('myobject.property.subprop');\n *\n * ### Paths:\n *\n * * Can be as near infinitely deep and nested\n * * Arrays are also valid using the formal `myobject.document[3].property`.\n * * Literal dots and brackets (not delimiter) must be backslash-escaped.\n *\n * @param {String} path\n * @returns {Object} parsed\n * @api private\n */\n\nfunction parsePath (path) {\n  var str = path.replace(/([^\\\\])\\[/g, '$1.[')\n    , parts = str.match(/(\\\\\\.|[^.]+?)+/g);\n  return parts.map(function (value) {\n    var re = /^\\[(\\d+)\\]$/\n      , mArr = re.exec(value);\n    if (mArr) return { i: parseFloat(mArr[1]) };\n    else return { p: value.replace(/\\\\([.\\[\\]])/g, '$1') };\n  });\n}\n\n\n/*!\n * ## _getPathValue(parsed, obj)\n *\n * Helper companion function for `.parsePath` that returns\n * the value located at the parsed address.\n *\n *      var value = getPathValue(parsed, obj);\n *\n * @param {Object} parsed definition from `parsePath`.\n * @param {Object} object to search against\n * @param {Number} object to search against\n * @returns {Object|Undefined} value\n * @api private\n */\n\nfunction _getPathValue (parsed, obj, index) {\n  var tmp = obj\n    , res;\n\n  index = (index === undefined ? parsed.length : index);\n\n  for (var i = 0, l = index; i < l; i++) {\n    var part = parsed[i];\n    if (tmp) {\n      if ('undefined' !== typeof part.p)\n        tmp = tmp[part.p];\n      else if ('undefined' !== typeof part.i)\n        tmp = tmp[part.i];\n      if (i == (l - 1)) res = tmp;\n    } else {\n      res = undefined;\n    }\n  }\n  return res;\n}\n\n},{\"./hasProperty\":21}],19:[function(require,module,exports){\n/*!\n * Chai - getPathValue utility\n * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com>\n * @see https://github.com/logicalparadox/filtr\n * MIT Licensed\n */\n\nvar getPathInfo = require('./getPathInfo');\n\n/**\n * ### .getPathValue(path, object)\n *\n * This allows the retrieval of values in an\n * object given a string path.\n *\n *     var obj = {\n *         prop1: {\n *             arr: ['a', 'b', 'c']\n *           , str: 'Hello'\n *         }\n *       , prop2: {\n *             arr: [ { nested: 'Universe' } ]\n *           , str: 'Hello again!'\n *         }\n *     }\n *\n * The following would be the results.\n *\n *     getPathValue('prop1.str', obj); // Hello\n *     getPathValue('prop1.att[2]', obj); // b\n *     getPathValue('prop2.arr[0].nested', obj); // Universe\n *\n * @param {String} path\n * @param {Object} object\n * @returns {Object} value or `undefined`\n * @namespace Utils\n * @name getPathValue\n * @api public\n */\nmodule.exports = function(path, obj) {\n  var info = getPathInfo(path, obj);\n  return info.value;\n};\n\n},{\"./getPathInfo\":18}],20:[function(require,module,exports){\n/*!\n * Chai - getProperties utility\n * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com>\n * MIT Licensed\n */\n\n/**\n * ### .getProperties(object)\n *\n * This allows the retrieval of property names of an object, enumerable or not,\n * inherited or not.\n *\n * @param {Object} object\n * @returns {Array}\n * @namespace Utils\n * @name getProperties\n * @api public\n */\n\nmodule.exports = function getProperties(object) {\n  var result = Object.getOwnPropertyNames(object);\n\n  function addProperty(property) {\n    if (result.indexOf(property) === -1) {\n      result.push(property);\n    }\n  }\n\n  var proto = Object.getPrototypeOf(object);\n  while (proto !== null) {\n    Object.getOwnPropertyNames(proto).forEach(addProperty);\n    proto = Object.getPrototypeOf(proto);\n  }\n\n  return result;\n};\n\n},{}],21:[function(require,module,exports){\n/*!\n * Chai - hasProperty utility\n * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com>\n * MIT Licensed\n */\n\nvar type = require('type-detect');\n\n/**\n * ### .hasProperty(object, name)\n *\n * This allows checking whether an object has\n * named property or numeric array index.\n *\n * Basically does the same thing as the `in`\n * operator but works properly with natives\n * and null/undefined values.\n *\n *     var obj = {\n *         arr: ['a', 'b', 'c']\n *       , str: 'Hello'\n *     }\n *\n * The following would be the results.\n *\n *     hasProperty('str', obj);  // true\n *     hasProperty('constructor', obj);  // true\n *     hasProperty('bar', obj);  // false\n *\n *     hasProperty('length', obj.str); // true\n *     hasProperty(1, obj.str);  // true\n *     hasProperty(5, obj.str);  // false\n *\n *     hasProperty('length', obj.arr);  // true\n *     hasProperty(2, obj.arr);  // true\n *     hasProperty(3, obj.arr);  // false\n *\n * @param {Objuect} object\n * @param {String|Number} name\n * @returns {Boolean} whether it exists\n * @namespace Utils\n * @name getPathInfo\n * @api public\n */\n\nvar literals = {\n    'number': Number\n  , 'string': String\n};\n\nmodule.exports = function hasProperty(name, obj) {\n  var ot = type(obj);\n\n  // Bad Object, obviously no props at all\n  if(ot === 'null' || ot === 'undefined')\n    return false;\n\n  // The `in` operator does not work with certain literals\n  // box these before the check\n  if(literals[ot] && typeof obj !== 'object')\n    obj = new literals[ot](obj);\n\n  return name in obj;\n};\n\n},{\"type-detect\":35}],22:[function(require,module,exports){\n/*!\n * chai\n * Copyright(c) 2011 Jake Luer <jake@alogicalparadox.com>\n * MIT Licensed\n */\n\n/*!\n * Main exports\n */\n\nvar exports = module.exports = {};\n\n/*!\n * test utility\n */\n\nexports.test = require('./test');\n\n/*!\n * type utility\n */\n\nexports.type = require('type-detect');\n\n/*!\n * expectTypes utility\n */\nexports.expectTypes = require('./expectTypes');\n\n/*!\n * message utility\n */\n\nexports.getMessage = require('./getMessage');\n\n/*!\n * actual utility\n */\n\nexports.getActual = require('./getActual');\n\n/*!\n * Inspect util\n */\n\nexports.inspect = require('./inspect');\n\n/*!\n * Object Display util\n */\n\nexports.objDisplay = require('./objDisplay');\n\n/*!\n * Flag utility\n */\n\nexports.flag = require('./flag');\n\n/*!\n * Flag transferring utility\n */\n\nexports.transferFlags = require('./transferFlags');\n\n/*!\n * Deep equal utility\n */\n\nexports.eql = require('deep-eql');\n\n/*!\n * Deep path value\n */\n\nexports.getPathValue = require('./getPathValue');\n\n/*!\n * Deep path info\n */\n\nexports.getPathInfo = require('./getPathInfo');\n\n/*!\n * Check if a property exists\n */\n\nexports.hasProperty = require('./hasProperty');\n\n/*!\n * Function name\n */\n\nexports.getName = require('./getName');\n\n/*!\n * add Property\n */\n\nexports.addProperty = require('./addProperty');\n\n/*!\n * add Method\n */\n\nexports.addMethod = require('./addMethod');\n\n/*!\n * overwrite Property\n */\n\nexports.overwriteProperty = require('./overwriteProperty');\n\n/*!\n * overwrite Method\n */\n\nexports.overwriteMethod = require('./overwriteMethod');\n\n/*!\n * Add a chainable method\n */\n\nexports.addChainableMethod = require('./addChainableMethod');\n\n/*!\n * Overwrite chainable method\n */\n\nexports.overwriteChainableMethod = require('./overwriteChainableMethod');\n\n},{\"./addChainableMethod\":9,\"./addMethod\":10,\"./addProperty\":11,\"./expectTypes\":12,\"./flag\":13,\"./getActual\":14,\"./getMessage\":16,\"./getName\":17,\"./getPathInfo\":18,\"./getPathValue\":19,\"./hasProperty\":21,\"./inspect\":23,\"./objDisplay\":24,\"./overwriteChainableMethod\":25,\"./overwriteMethod\":26,\"./overwriteProperty\":27,\"./test\":28,\"./transferFlags\":29,\"deep-eql\":31,\"type-detect\":35}],23:[function(require,module,exports){\n// This is (almost) directly from Node.js utils\n// https://github.com/joyent/node/blob/f8c335d0caf47f16d31413f89aa28eda3878e3aa/lib/util.js\n\nvar getName = require('./getName');\nvar getProperties = require('./getProperties');\nvar getEnumerableProperties = require('./getEnumerableProperties');\n\nmodule.exports = inspect;\n\n/**\n * Echos the value of a value. Trys to print the value out\n * in the best way possible given the different types.\n *\n * @param {Object} obj The object to print out.\n * @param {Boolean} showHidden Flag that shows hidden (not enumerable)\n *    properties of objects.\n * @param {Number} depth Depth in which to descend in object. Default is 2.\n * @param {Boolean} colors Flag to turn on ANSI escape codes to color the\n *    output. Default is false (no coloring).\n * @namespace Utils\n * @name inspect\n */\nfunction inspect(obj, showHidden, depth, colors) {\n  var ctx = {\n    showHidden: showHidden,\n    seen: [],\n    stylize: function (str) { return str; }\n  };\n  return formatValue(ctx, obj, (typeof depth === 'undefined' ? 2 : depth));\n}\n\n// Returns true if object is a DOM element.\nvar isDOMElement = function (object) {\n  if (typeof HTMLElement === 'object') {\n    return object instanceof HTMLElement;\n  } else {\n    return object &&\n      typeof object === 'object' &&\n      object.nodeType === 1 &&\n      typeof object.nodeName === 'string';\n  }\n};\n\nfunction formatValue(ctx, value, recurseTimes) {\n  // Provide a hook for user-specified inspect functions.\n  // Check that value is an object with an inspect function on it\n  if (value && typeof value.inspect === 'function' &&\n      // Filter out the util module, it's inspect function is special\n      value.inspect !== exports.inspect &&\n      // Also filter out any prototype objects using the circular check.\n      !(value.constructor && value.constructor.prototype === value)) {\n    var ret = value.inspect(recurseTimes);\n    if (typeof ret !== 'string') {\n      ret = formatValue(ctx, ret, recurseTimes);\n    }\n    return ret;\n  }\n\n  // Primitive types cannot have properties\n  var primitive = formatPrimitive(ctx, value);\n  if (primitive) {\n    return primitive;\n  }\n\n  // If this is a DOM element, try to get the outer HTML.\n  if (isDOMElement(value)) {\n    if ('outerHTML' in value) {\n      return value.outerHTML;\n      // This value does not have an outerHTML attribute,\n      //   it could still be an XML element\n    } else {\n      // Attempt to serialize it\n      try {\n        if (document.xmlVersion) {\n          var xmlSerializer = new XMLSerializer();\n          return xmlSerializer.serializeToString(value);\n        } else {\n          // Firefox 11- do not support outerHTML\n          //   It does, however, support innerHTML\n          //   Use the following to render the element\n          var ns = \"http://www.w3.org/1999/xhtml\";\n          var container = document.createElementNS(ns, '_');\n\n          container.appendChild(value.cloneNode(false));\n          html = container.innerHTML\n            .replace('><', '>' + value.innerHTML + '<');\n          container.innerHTML = '';\n          return html;\n        }\n      } catch (err) {\n        // This could be a non-native DOM implementation,\n        //   continue with the normal flow:\n        //   printing the element as if it is an object.\n      }\n    }\n  }\n\n  // Look up the keys of the object.\n  var visibleKeys = getEnumerableProperties(value);\n  var keys = ctx.showHidden ? getProperties(value) : visibleKeys;\n\n  // Some type of object without properties can be shortcutted.\n  // In IE, errors have a single `stack` property, or if they are vanilla `Error`,\n  // a `stack` plus `description` property; ignore those for consistency.\n  if (keys.length === 0 || (isError(value) && (\n      (keys.length === 1 && keys[0] === 'stack') ||\n      (keys.length === 2 && keys[0] === 'description' && keys[1] === 'stack')\n     ))) {\n    if (typeof value === 'function') {\n      var name = getName(value);\n      var nameSuffix = name ? ': ' + name : '';\n      return ctx.stylize('[Function' + nameSuffix + ']', 'special');\n    }\n    if (isRegExp(value)) {\n      return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp');\n    }\n    if (isDate(value)) {\n      return ctx.stylize(Date.prototype.toUTCString.call(value), 'date');\n    }\n    if (isError(value)) {\n      return formatError(value);\n    }\n  }\n\n  var base = '', array = false, braces = ['{', '}'];\n\n  // Make Array say that they are Array\n  if (isArray(value)) {\n    array = true;\n    braces = ['[', ']'];\n  }\n\n  // Make functions say that they are functions\n  if (typeof value === 'function') {\n    var name = getName(value);\n    var nameSuffix = name ? ': ' + name : '';\n    base = ' [Function' + nameSuffix + ']';\n  }\n\n  // Make RegExps say that they are RegExps\n  if (isRegExp(value)) {\n    base = ' ' + RegExp.prototype.toString.call(value);\n  }\n\n  // Make dates with properties first say the date\n  if (isDate(value)) {\n    base = ' ' + Date.prototype.toUTCString.call(value);\n  }\n\n  // Make error with message first say the error\n  if (isError(value)) {\n    return formatError(value);\n  }\n\n  if (keys.length === 0 && (!array || value.length == 0)) {\n    return braces[0] + base + braces[1];\n  }\n\n  if (recurseTimes < 0) {\n    if (isRegExp(value)) {\n      return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp');\n    } else {\n      return ctx.stylize('[Object]', 'special');\n    }\n  }\n\n  ctx.seen.push(value);\n\n  var output;\n  if (array) {\n    output = formatArray(ctx, value, recurseTimes, visibleKeys, keys);\n  } else {\n    output = keys.map(function(key) {\n      return formatProperty(ctx, value, recurseTimes, visibleKeys, key, array);\n    });\n  }\n\n  ctx.seen.pop();\n\n  return reduceToSingleString(output, base, braces);\n}\n\n\nfunction formatPrimitive(ctx, value) {\n  switch (typeof value) {\n    case 'undefined':\n      return ctx.stylize('undefined', 'undefined');\n\n    case 'string':\n      var simple = '\\'' + JSON.stringify(value).replace(/^\"|\"$/g, '')\n                                               .replace(/'/g, \"\\\\'\")\n                                               .replace(/\\\\\"/g, '\"') + '\\'';\n      return ctx.stylize(simple, 'string');\n\n    case 'number':\n      if (value === 0 && (1/value) === -Infinity) {\n        return ctx.stylize('-0', 'number');\n      }\n      return ctx.stylize('' + value, 'number');\n\n    case 'boolean':\n      return ctx.stylize('' + value, 'boolean');\n  }\n  // For some reason typeof null is \"object\", so special case here.\n  if (value === null) {\n    return ctx.stylize('null', 'null');\n  }\n}\n\n\nfunction formatError(value) {\n  return '[' + Error.prototype.toString.call(value) + ']';\n}\n\n\nfunction formatArray(ctx, value, recurseTimes, visibleKeys, keys) {\n  var output = [];\n  for (var i = 0, l = value.length; i < l; ++i) {\n    if (Object.prototype.hasOwnProperty.call(value, String(i))) {\n      output.push(formatProperty(ctx, value, recurseTimes, visibleKeys,\n          String(i), true));\n    } else {\n      output.push('');\n    }\n  }\n  keys.forEach(function(key) {\n    if (!key.match(/^\\d+$/)) {\n      output.push(formatProperty(ctx, value, recurseTimes, visibleKeys,\n          key, true));\n    }\n  });\n  return output;\n}\n\n\nfunction formatProperty(ctx, value, recurseTimes, visibleKeys, key, array) {\n  var name, str;\n  if (value.__lookupGetter__) {\n    if (value.__lookupGetter__(key)) {\n      if (value.__lookupSetter__(key)) {\n        str = ctx.stylize('[Getter/Setter]', 'special');\n      } else {\n        str = ctx.stylize('[Getter]', 'special');\n      }\n    } else {\n      if (value.__lookupSetter__(key)) {\n        str = ctx.stylize('[Setter]', 'special');\n      }\n    }\n  }\n  if (visibleKeys.indexOf(key) < 0) {\n    name = '[' + key + ']';\n  }\n  if (!str) {\n    if (ctx.seen.indexOf(value[key]) < 0) {\n      if (recurseTimes === null) {\n        str = formatValue(ctx, value[key], null);\n      } else {\n        str = formatValue(ctx, value[key], recurseTimes - 1);\n      }\n      if (str.indexOf('\\n') > -1) {\n        if (array) {\n          str = str.split('\\n').map(function(line) {\n            return '  ' + line;\n          }).join('\\n').substr(2);\n        } else {\n          str = '\\n' + str.split('\\n').map(function(line) {\n            return '   ' + line;\n          }).join('\\n');\n        }\n      }\n    } else {\n      str = ctx.stylize('[Circular]', 'special');\n    }\n  }\n  if (typeof name === 'undefined') {\n    if (array && key.match(/^\\d+$/)) {\n      return str;\n    }\n    name = JSON.stringify('' + key);\n    if (name.match(/^\"([a-zA-Z_][a-zA-Z_0-9]*)\"$/)) {\n      name = name.substr(1, name.length - 2);\n      name = ctx.stylize(name, 'name');\n    } else {\n      name = name.replace(/'/g, \"\\\\'\")\n                 .replace(/\\\\\"/g, '\"')\n                 .replace(/(^\"|\"$)/g, \"'\");\n      name = ctx.stylize(name, 'string');\n    }\n  }\n\n  return name + ': ' + str;\n}\n\n\nfunction reduceToSingleString(output, base, braces) {\n  var numLinesEst = 0;\n  var length = output.reduce(function(prev, cur) {\n    numLinesEst++;\n    if (cur.indexOf('\\n') >= 0) numLinesEst++;\n    return prev + cur.length + 1;\n  }, 0);\n\n  if (length > 60) {\n    return braces[0] +\n           (base === '' ? '' : base + '\\n ') +\n           ' ' +\n           output.join(',\\n  ') +\n           ' ' +\n           braces[1];\n  }\n\n  return braces[0] + base + ' ' + output.join(', ') + ' ' + braces[1];\n}\n\nfunction isArray(ar) {\n  return Array.isArray(ar) ||\n         (typeof ar === 'object' && objectToString(ar) === '[object Array]');\n}\n\nfunction isRegExp(re) {\n  return typeof re === 'object' && objectToString(re) === '[object RegExp]';\n}\n\nfunction isDate(d) {\n  return typeof d === 'object' && objectToString(d) === '[object Date]';\n}\n\nfunction isError(e) {\n  return typeof e === 'object' && objectToString(e) === '[object Error]';\n}\n\nfunction objectToString(o) {\n  return Object.prototype.toString.call(o);\n}\n\n},{\"./getEnumerableProperties\":15,\"./getName\":17,\"./getProperties\":20}],24:[function(require,module,exports){\n/*!\n * Chai - flag utility\n * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com>\n * MIT Licensed\n */\n\n/*!\n * Module dependancies\n */\n\nvar inspect = require('./inspect');\nvar config = require('../config');\n\n/**\n * ### .objDisplay (object)\n *\n * Determines if an object or an array matches\n * criteria to be inspected in-line for error\n * messages or should be truncated.\n *\n * @param {Mixed} javascript object to inspect\n * @name objDisplay\n * @namespace Utils\n * @api public\n */\n\nmodule.exports = function (obj) {\n  var str = inspect(obj)\n    , type = Object.prototype.toString.call(obj);\n\n  if (config.truncateThreshold && str.length >= config.truncateThreshold) {\n    if (type === '[object Function]') {\n      return !obj.name || obj.name === ''\n        ? '[Function]'\n        : '[Function: ' + obj.name + ']';\n    } else if (type === '[object Array]') {\n      return '[ Array(' + obj.length + ') ]';\n    } else if (type === '[object Object]') {\n      var keys = Object.keys(obj)\n        , kstr = keys.length > 2\n          ? keys.splice(0, 2).join(', ') + ', ...'\n          : keys.join(', ');\n      return '{ Object (' + kstr + ') }';\n    } else {\n      return str;\n    }\n  } else {\n    return str;\n  }\n};\n\n},{\"../config\":4,\"./inspect\":23}],25:[function(require,module,exports){\n/*!\n * Chai - overwriteChainableMethod utility\n * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com>\n * MIT Licensed\n */\n\n/**\n * ### overwriteChainableMethod (ctx, name, method, chainingBehavior)\n *\n * Overwites an already existing chainable method\n * and provides access to the previous function or\n * property.  Must return functions to be used for\n * name.\n *\n *     utils.overwriteChainableMethod(chai.Assertion.prototype, 'length',\n *       function (_super) {\n *       }\n *     , function (_super) {\n *       }\n *     );\n *\n * Can also be accessed directly from `chai.Assertion`.\n *\n *     chai.Assertion.overwriteChainableMethod('foo', fn, fn);\n *\n * Then can be used as any other assertion.\n *\n *     expect(myFoo).to.have.length(3);\n *     expect(myFoo).to.have.length.above(3);\n *\n * @param {Object} ctx object whose method / property is to be overwritten\n * @param {String} name of method / property to overwrite\n * @param {Function} method function that returns a function to be used for name\n * @param {Function} chainingBehavior function that returns a function to be used for property\n * @namespace Utils\n * @name overwriteChainableMethod\n * @api public\n */\n\nmodule.exports = function (ctx, name, method, chainingBehavior) {\n  var chainableBehavior = ctx.__methods[name];\n\n  var _chainingBehavior = chainableBehavior.chainingBehavior;\n  chainableBehavior.chainingBehavior = function () {\n    var result = chainingBehavior(_chainingBehavior).call(this);\n    return result === undefined ? this : result;\n  };\n\n  var _method = chainableBehavior.method;\n  chainableBehavior.method = function () {\n    var result = method(_method).apply(this, arguments);\n    return result === undefined ? this : result;\n  };\n};\n\n},{}],26:[function(require,module,exports){\n/*!\n * Chai - overwriteMethod utility\n * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com>\n * MIT Licensed\n */\n\n/**\n * ### overwriteMethod (ctx, name, fn)\n *\n * Overwites an already existing method and provides\n * access to previous function. Must return function\n * to be used for name.\n *\n *     utils.overwriteMethod(chai.Assertion.prototype, 'equal', function (_super) {\n *       return function (str) {\n *         var obj = utils.flag(this, 'object');\n *         if (obj instanceof Foo) {\n *           new chai.Assertion(obj.value).to.equal(str);\n *         } else {\n *           _super.apply(this, arguments);\n *         }\n *       }\n *     });\n *\n * Can also be accessed directly from `chai.Assertion`.\n *\n *     chai.Assertion.overwriteMethod('foo', fn);\n *\n * Then can be used as any other assertion.\n *\n *     expect(myFoo).to.equal('bar');\n *\n * @param {Object} ctx object whose method is to be overwritten\n * @param {String} name of method to overwrite\n * @param {Function} method function that returns a function to be used for name\n * @namespace Utils\n * @name overwriteMethod\n * @api public\n */\n\nmodule.exports = function (ctx, name, method) {\n  var _method = ctx[name]\n    , _super = function () { return this; };\n\n  if (_method && 'function' === typeof _method)\n    _super = _method;\n\n  ctx[name] = function () {\n    var result = method(_super).apply(this, arguments);\n    return result === undefined ? this : result;\n  }\n};\n\n},{}],27:[function(require,module,exports){\n/*!\n * Chai - overwriteProperty utility\n * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com>\n * MIT Licensed\n */\n\n/**\n * ### overwriteProperty (ctx, name, fn)\n *\n * Overwites an already existing property getter and provides\n * access to previous value. Must return function to use as getter.\n *\n *     utils.overwriteProperty(chai.Assertion.prototype, 'ok', function (_super) {\n *       return function () {\n *         var obj = utils.flag(this, 'object');\n *         if (obj instanceof Foo) {\n *           new chai.Assertion(obj.name).to.equal('bar');\n *         } else {\n *           _super.call(this);\n *         }\n *       }\n *     });\n *\n *\n * Can also be accessed directly from `chai.Assertion`.\n *\n *     chai.Assertion.overwriteProperty('foo', fn);\n *\n * Then can be used as any other assertion.\n *\n *     expect(myFoo).to.be.ok;\n *\n * @param {Object} ctx object whose property is to be overwritten\n * @param {String} name of property to overwrite\n * @param {Function} getter function that returns a getter function to be used for name\n * @namespace Utils\n * @name overwriteProperty\n * @api public\n */\n\nmodule.exports = function (ctx, name, getter) {\n  var _get = Object.getOwnPropertyDescriptor(ctx, name)\n    , _super = function () {};\n\n  if (_get && 'function' === typeof _get.get)\n    _super = _get.get\n\n  Object.defineProperty(ctx, name,\n    { get: function () {\n        var result = getter(_super).call(this);\n        return result === undefined ? this : result;\n      }\n    , configurable: true\n  });\n};\n\n},{}],28:[function(require,module,exports){\n/*!\n * Chai - test utility\n * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com>\n * MIT Licensed\n */\n\n/*!\n * Module dependancies\n */\n\nvar flag = require('./flag');\n\n/**\n * # test(object, expression)\n *\n * Test and object for expression.\n *\n * @param {Object} object (constructed Assertion)\n * @param {Arguments} chai.Assertion.prototype.assert arguments\n * @namespace Utils\n * @name test\n */\n\nmodule.exports = function (obj, args) {\n  var negate = flag(obj, 'negate')\n    , expr = args[0];\n  return negate ? !expr : expr;\n};\n\n},{\"./flag\":13}],29:[function(require,module,exports){\n/*!\n * Chai - transferFlags utility\n * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com>\n * MIT Licensed\n */\n\n/**\n * ### transferFlags(assertion, object, includeAll = true)\n *\n * Transfer all the flags for `assertion` to `object`. If\n * `includeAll` is set to `false`, then the base Chai\n * assertion flags (namely `object`, `ssfi`, and `message`)\n * will not be transferred.\n *\n *\n *     var newAssertion = new Assertion();\n *     utils.transferFlags(assertion, newAssertion);\n *\n *     var anotherAsseriton = new Assertion(myObj);\n *     utils.transferFlags(assertion, anotherAssertion, false);\n *\n * @param {Assertion} assertion the assertion to transfer the flags from\n * @param {Object} object the object to transfer the flags to; usually a new assertion\n * @param {Boolean} includeAll\n * @namespace Utils\n * @name transferFlags\n * @api private\n */\n\nmodule.exports = function (assertion, object, includeAll) {\n  var flags = assertion.__flags || (assertion.__flags = Object.create(null));\n\n  if (!object.__flags) {\n    object.__flags = Object.create(null);\n  }\n\n  includeAll = arguments.length === 3 ? includeAll : true;\n\n  for (var flag in flags) {\n    if (includeAll ||\n        (flag !== 'object' && flag !== 'ssfi' && flag != 'message')) {\n      object.__flags[flag] = flags[flag];\n    }\n  }\n};\n\n},{}],30:[function(require,module,exports){\n/*!\n * assertion-error\n * Copyright(c) 2013 Jake Luer <jake@qualiancy.com>\n * MIT Licensed\n */\n\n/*!\n * Return a function that will copy properties from\n * one object to another excluding any originally\n * listed. Returned function will create a new `{}`.\n *\n * @param {String} excluded properties ...\n * @return {Function}\n */\n\nfunction exclude () {\n  var excludes = [].slice.call(arguments);\n\n  function excludeProps (res, obj) {\n    Object.keys(obj).forEach(function (key) {\n      if (!~excludes.indexOf(key)) res[key] = obj[key];\n    });\n  }\n\n  return function extendExclude () {\n    var args = [].slice.call(arguments)\n      , i = 0\n      , res = {};\n\n    for (; i < args.length; i++) {\n      excludeProps(res, args[i]);\n    }\n\n    return res;\n  };\n};\n\n/*!\n * Primary Exports\n */\n\nmodule.exports = AssertionError;\n\n/**\n * ### AssertionError\n *\n * An extension of the JavaScript `Error` constructor for\n * assertion and validation scenarios.\n *\n * @param {String} message\n * @param {Object} properties to include (optional)\n * @param {callee} start stack function (optional)\n */\n\nfunction AssertionError (message, _props, ssf) {\n  var extend = exclude('name', 'message', 'stack', 'constructor', 'toJSON')\n    , props = extend(_props || {});\n\n  // default values\n  this.message = message || 'Unspecified AssertionError';\n  this.showDiff = false;\n\n  // copy from properties\n  for (var key in props) {\n    this[key] = props[key];\n  }\n\n  // capture stack trace\n  ssf = ssf || arguments.callee;\n  if (ssf && Error.captureStackTrace) {\n    Error.captureStackTrace(this, ssf);\n  } else {\n    this.stack = new Error().stack;\n  }\n}\n\n/*!\n * Inherit from Error.prototype\n */\n\nAssertionError.prototype = Object.create(Error.prototype);\n\n/*!\n * Statically set name\n */\n\nAssertionError.prototype.name = 'AssertionError';\n\n/*!\n * Ensure correct constructor\n */\n\nAssertionError.prototype.constructor = AssertionError;\n\n/**\n * Allow errors to be converted to JSON for static transfer.\n *\n * @param {Boolean} include stack (default: `true`)\n * @return {Object} object that can be `JSON.stringify`\n */\n\nAssertionError.prototype.toJSON = function (stack) {\n  var extend = exclude('constructor', 'toJSON', 'stack')\n    , props = extend({ name: this.name }, this);\n\n  // include stack if exists and not turned off\n  if (false !== stack && this.stack) {\n    props.stack = this.stack;\n  }\n\n  return props;\n};\n\n},{}],31:[function(require,module,exports){\nmodule.exports = require('./lib/eql');\n\n},{\"./lib/eql\":32}],32:[function(require,module,exports){\n/*!\n * deep-eql\n * Copyright(c) 2013 Jake Luer <jake@alogicalparadox.com>\n * MIT Licensed\n */\n\n/*!\n * Module dependencies\n */\n\nvar type = require('type-detect');\n\n/*!\n * Buffer.isBuffer browser shim\n */\n\nvar Buffer;\ntry { Buffer = require('buffer').Buffer; }\ncatch(ex) {\n  Buffer = {};\n  Buffer.isBuffer = function() { return false; }\n}\n\n/*!\n * Primary Export\n */\n\nmodule.exports = deepEqual;\n\n/**\n * Assert super-strict (egal) equality between\n * two objects of any type.\n *\n * @param {Mixed} a\n * @param {Mixed} b\n * @param {Array} memoised (optional)\n * @return {Boolean} equal match\n */\n\nfunction deepEqual(a, b, m) {\n  if (sameValue(a, b)) {\n    return true;\n  } else if ('date' === type(a)) {\n    return dateEqual(a, b);\n  } else if ('regexp' === type(a)) {\n    return regexpEqual(a, b);\n  } else if (Buffer.isBuffer(a)) {\n    return bufferEqual(a, b);\n  } else if ('arguments' === type(a)) {\n    return argumentsEqual(a, b, m);\n  } else if (!typeEqual(a, b)) {\n    return false;\n  } else if (('object' !== type(a) && 'object' !== type(b))\n  && ('array' !== type(a) && 'array' !== type(b))) {\n    return sameValue(a, b);\n  } else {\n    return objectEqual(a, b, m);\n  }\n}\n\n/*!\n * Strict (egal) equality test. Ensures that NaN always\n * equals NaN and `-0` does not equal `+0`.\n *\n * @param {Mixed} a\n * @param {Mixed} b\n * @return {Boolean} equal match\n */\n\nfunction sameValue(a, b) {\n  if (a === b) return a !== 0 || 1 / a === 1 / b;\n  return a !== a && b !== b;\n}\n\n/*!\n * Compare the types of two given objects and\n * return if they are equal. Note that an Array\n * has a type of `array` (not `object`) and arguments\n * have a type of `arguments` (not `array`/`object`).\n *\n * @param {Mixed} a\n * @param {Mixed} b\n * @return {Boolean} result\n */\n\nfunction typeEqual(a, b) {\n  return type(a) === type(b);\n}\n\n/*!\n * Compare two Date objects by asserting that\n * the time values are equal using `saveValue`.\n *\n * @param {Date} a\n * @param {Date} b\n * @return {Boolean} result\n */\n\nfunction dateEqual(a, b) {\n  if ('date' !== type(b)) return false;\n  return sameValue(a.getTime(), b.getTime());\n}\n\n/*!\n * Compare two regular expressions by converting them\n * to string and checking for `sameValue`.\n *\n * @param {RegExp} a\n * @param {RegExp} b\n * @return {Boolean} result\n */\n\nfunction regexpEqual(a, b) {\n  if ('regexp' !== type(b)) return false;\n  return sameValue(a.toString(), b.toString());\n}\n\n/*!\n * Assert deep equality of two `arguments` objects.\n * Unfortunately, these must be sliced to arrays\n * prior to test to ensure no bad behavior.\n *\n * @param {Arguments} a\n * @param {Arguments} b\n * @param {Array} memoize (optional)\n * @return {Boolean} result\n */\n\nfunction argumentsEqual(a, b, m) {\n  if ('arguments' !== type(b)) return false;\n  a = [].slice.call(a);\n  b = [].slice.call(b);\n  return deepEqual(a, b, m);\n}\n\n/*!\n * Get enumerable properties of a given object.\n *\n * @param {Object} a\n * @return {Array} property names\n */\n\nfunction enumerable(a) {\n  var res = [];\n  for (var key in a) res.push(key);\n  return res;\n}\n\n/*!\n * Simple equality for flat iterable objects\n * such as Arrays or Node.js buffers.\n *\n * @param {Iterable} a\n * @param {Iterable} b\n * @return {Boolean} result\n */\n\nfunction iterableEqual(a, b) {\n  if (a.length !==  b.length) return false;\n\n  var i = 0;\n  var match = true;\n\n  for (; i < a.length; i++) {\n    if (a[i] !== b[i]) {\n      match = false;\n      break;\n    }\n  }\n\n  return match;\n}\n\n/*!\n * Extension to `iterableEqual` specifically\n * for Node.js Buffers.\n *\n * @param {Buffer} a\n * @param {Mixed} b\n * @return {Boolean} result\n */\n\nfunction bufferEqual(a, b) {\n  if (!Buffer.isBuffer(b)) return false;\n  return iterableEqual(a, b);\n}\n\n/*!\n * Block for `objectEqual` ensuring non-existing\n * values don't get in.\n *\n * @param {Mixed} object\n * @return {Boolean} result\n */\n\nfunction isValue(a) {\n  return a !== null && a !== undefined;\n}\n\n/*!\n * Recursively check the equality of two objects.\n * Once basic sameness has been established it will\n * defer to `deepEqual` for each enumerable key\n * in the object.\n *\n * @param {Mixed} a\n * @param {Mixed} b\n * @return {Boolean} result\n */\n\nfunction objectEqual(a, b, m) {\n  if (!isValue(a) || !isValue(b)) {\n    return false;\n  }\n\n  if (a.prototype !== b.prototype) {\n    return false;\n  }\n\n  var i;\n  if (m) {\n    for (i = 0; i < m.length; i++) {\n      if ((m[i][0] === a && m[i][1] === b)\n      ||  (m[i][0] === b && m[i][1] === a)) {\n        return true;\n      }\n    }\n  } else {\n    m = [];\n  }\n\n  try {\n    var ka = enumerable(a);\n    var kb = enumerable(b);\n  } catch (ex) {\n    return false;\n  }\n\n  ka.sort();\n  kb.sort();\n\n  if (!iterableEqual(ka, kb)) {\n    return false;\n  }\n\n  m.push([ a, b ]);\n\n  var key;\n  for (i = ka.length - 1; i >= 0; i--) {\n    key = ka[i];\n    if (!deepEqual(a[key], b[key], m)) {\n      return false;\n    }\n  }\n\n  return true;\n}\n\n},{\"buffer\":undefined,\"type-detect\":33}],33:[function(require,module,exports){\nmodule.exports = require('./lib/type');\n\n},{\"./lib/type\":34}],34:[function(require,module,exports){\n/*!\n * type-detect\n * Copyright(c) 2013 jake luer <jake@alogicalparadox.com>\n * MIT Licensed\n */\n\n/*!\n * Primary Exports\n */\n\nvar exports = module.exports = getType;\n\n/*!\n * Detectable javascript natives\n */\n\nvar natives = {\n    '[object Array]': 'array'\n  , '[object RegExp]': 'regexp'\n  , '[object Function]': 'function'\n  , '[object Arguments]': 'arguments'\n  , '[object Date]': 'date'\n};\n\n/**\n * ### typeOf (obj)\n *\n * Use several different techniques to determine\n * the type of object being tested.\n *\n *\n * @param {Mixed} object\n * @return {String} object type\n * @api public\n */\n\nfunction getType (obj) {\n  var str = Object.prototype.toString.call(obj);\n  if (natives[str]) return natives[str];\n  if (obj === null) return 'null';\n  if (obj === undefined) return 'undefined';\n  if (obj === Object(obj)) return 'object';\n  return typeof obj;\n}\n\nexports.Library = Library;\n\n/**\n * ### Library\n *\n * Create a repository for custom type detection.\n *\n * ```js\n * var lib = new type.Library;\n * ```\n *\n */\n\nfunction Library () {\n  this.tests = {};\n}\n\n/**\n * #### .of (obj)\n *\n * Expose replacement `typeof` detection to the library.\n *\n * ```js\n * if ('string' === lib.of('hello world')) {\n *   // ...\n * }\n * ```\n *\n * @param {Mixed} object to test\n * @return {String} type\n */\n\nLibrary.prototype.of = getType;\n\n/**\n * #### .define (type, test)\n *\n * Add a test to for the `.test()` assertion.\n *\n * Can be defined as a regular expression:\n *\n * ```js\n * lib.define('int', /^[0-9]+$/);\n * ```\n *\n * ... or as a function:\n *\n * ```js\n * lib.define('bln', function (obj) {\n *   if ('boolean' === lib.of(obj)) return true;\n *   var blns = [ 'yes', 'no', 'true', 'false', 1, 0 ];\n *   if ('string' === lib.of(obj)) obj = obj.toLowerCase();\n *   return !! ~blns.indexOf(obj);\n * });\n * ```\n *\n * @param {String} type\n * @param {RegExp|Function} test\n * @api public\n */\n\nLibrary.prototype.define = function (type, test) {\n  if (arguments.length === 1) return this.tests[type];\n  this.tests[type] = test;\n  return this;\n};\n\n/**\n * #### .test (obj, test)\n *\n * Assert that an object is of type. Will first\n * check natives, and if that does not pass it will\n * use the user defined custom tests.\n *\n * ```js\n * assert(lib.test('1', 'int'));\n * assert(lib.test('yes', 'bln'));\n * ```\n *\n * @param {Mixed} object\n * @param {String} type\n * @return {Boolean} result\n * @api public\n */\n\nLibrary.prototype.test = function (obj, type) {\n  if (type === getType(obj)) return true;\n  var test = this.tests[type];\n\n  if (test && 'regexp' === getType(test)) {\n    return test.test(obj);\n  } else if (test && 'function' === getType(test)) {\n    return test(obj);\n  } else {\n    throw new ReferenceError('Type test \"' + type + '\" not defined or invalid.');\n  }\n};\n\n},{}],35:[function(require,module,exports){\narguments[4][33][0].apply(exports,arguments)\n},{\"./lib/type\":36,\"dup\":33}],36:[function(require,module,exports){\n/*!\n * type-detect\n * Copyright(c) 2013 jake luer <jake@alogicalparadox.com>\n * MIT Licensed\n */\n\n/*!\n * Primary Exports\n */\n\nvar exports = module.exports = getType;\n\n/**\n * ### typeOf (obj)\n *\n * Use several different techniques to determine\n * the type of object being tested.\n *\n *\n * @param {Mixed} object\n * @return {String} object type\n * @api public\n */\nvar objectTypeRegexp = /^\\[object (.*)\\]$/;\n\nfunction getType(obj) {\n  var type = Object.prototype.toString.call(obj).match(objectTypeRegexp)[1].toLowerCase();\n  // Let \"new String('')\" return 'object'\n  if (typeof Promise === 'function' && obj instanceof Promise) return 'promise';\n  // PhantomJS has type \"DOMWindow\" for null\n  if (obj === null) return 'null';\n  // PhantomJS has type \"DOMWindow\" for undefined\n  if (obj === undefined) return 'undefined';\n  return type;\n}\n\nexports.Library = Library;\n\n/**\n * ### Library\n *\n * Create a repository for custom type detection.\n *\n * ```js\n * var lib = new type.Library;\n * ```\n *\n */\n\nfunction Library() {\n  if (!(this instanceof Library)) return new Library();\n  this.tests = {};\n}\n\n/**\n * #### .of (obj)\n *\n * Expose replacement `typeof` detection to the library.\n *\n * ```js\n * if ('string' === lib.of('hello world')) {\n *   // ...\n * }\n * ```\n *\n * @param {Mixed} object to test\n * @return {String} type\n */\n\nLibrary.prototype.of = getType;\n\n/**\n * #### .define (type, test)\n *\n * Add a test to for the `.test()` assertion.\n *\n * Can be defined as a regular expression:\n *\n * ```js\n * lib.define('int', /^[0-9]+$/);\n * ```\n *\n * ... or as a function:\n *\n * ```js\n * lib.define('bln', function (obj) {\n *   if ('boolean' === lib.of(obj)) return true;\n *   var blns = [ 'yes', 'no', 'true', 'false', 1, 0 ];\n *   if ('string' === lib.of(obj)) obj = obj.toLowerCase();\n *   return !! ~blns.indexOf(obj);\n * });\n * ```\n *\n * @param {String} type\n * @param {RegExp|Function} test\n * @api public\n */\n\nLibrary.prototype.define = function(type, test) {\n  if (arguments.length === 1) return this.tests[type];\n  this.tests[type] = test;\n  return this;\n};\n\n/**\n * #### .test (obj, test)\n *\n * Assert that an object is of type. Will first\n * check natives, and if that does not pass it will\n * use the user defined custom tests.\n *\n * ```js\n * assert(lib.test('1', 'int'));\n * assert(lib.test('yes', 'bln'));\n * ```\n *\n * @param {Mixed} object\n * @param {String} type\n * @return {Boolean} result\n * @api public\n */\n\nLibrary.prototype.test = function(obj, type) {\n  if (type === getType(obj)) return true;\n  var test = this.tests[type];\n\n  if (test && 'regexp' === getType(test)) {\n    return test.test(obj);\n  } else if (test && 'function' === getType(test)) {\n    return test(obj);\n  } else {\n    throw new ReferenceError('Type test \"' + type + '\" not defined or invalid.');\n  }\n};\n\n},{}]},{},[1])(1)\n});\n"
  },
  {
    "path": "app_frontend/static/plugin/JavaScript-Templates-3.8.0/test/vendor/mocha.css",
    "content": "@charset \"utf-8\";\n\nbody {\n  margin:0;\n}\n\n#mocha {\n  font: 20px/1.5 \"Helvetica Neue\", Helvetica, Arial, sans-serif;\n  margin: 60px 50px;\n}\n\n#mocha ul,\n#mocha li {\n  margin: 0;\n  padding: 0;\n}\n\n#mocha ul {\n  list-style: none;\n}\n\n#mocha h1,\n#mocha h2 {\n  margin: 0;\n}\n\n#mocha h1 {\n  margin-top: 15px;\n  font-size: 1em;\n  font-weight: 200;\n}\n\n#mocha h1 a {\n  text-decoration: none;\n  color: inherit;\n}\n\n#mocha h1 a:hover {\n  text-decoration: underline;\n}\n\n#mocha .suite .suite h1 {\n  margin-top: 0;\n  font-size: .8em;\n}\n\n#mocha .hidden {\n  display: none;\n}\n\n#mocha h2 {\n  font-size: 12px;\n  font-weight: normal;\n  cursor: pointer;\n}\n\n#mocha .suite {\n  margin-left: 15px;\n}\n\n#mocha .test {\n  margin-left: 15px;\n  overflow: hidden;\n}\n\n#mocha .test.pending:hover h2::after {\n  content: '(pending)';\n  font-family: arial, sans-serif;\n}\n\n#mocha .test.pass.medium .duration {\n  background: #c09853;\n}\n\n#mocha .test.pass.slow .duration {\n  background: #b94a48;\n}\n\n#mocha .test.pass::before {\n  content: '✓';\n  font-size: 12px;\n  display: block;\n  float: left;\n  margin-right: 5px;\n  color: #00d6b2;\n}\n\n#mocha .test.pass .duration {\n  font-size: 9px;\n  margin-left: 5px;\n  padding: 2px 5px;\n  color: #fff;\n  -webkit-box-shadow: inset 0 1px 1px rgba(0,0,0,.2);\n  -moz-box-shadow: inset 0 1px 1px rgba(0,0,0,.2);\n  box-shadow: inset 0 1px 1px rgba(0,0,0,.2);\n  -webkit-border-radius: 5px;\n  -moz-border-radius: 5px;\n  -ms-border-radius: 5px;\n  -o-border-radius: 5px;\n  border-radius: 5px;\n}\n\n#mocha .test.pass.fast .duration {\n  display: none;\n}\n\n#mocha .test.pending {\n  color: #0b97c4;\n}\n\n#mocha .test.pending::before {\n  content: '◦';\n  color: #0b97c4;\n}\n\n#mocha .test.fail {\n  color: #c00;\n}\n\n#mocha .test.fail pre {\n  color: black;\n}\n\n#mocha .test.fail::before {\n  content: '✖';\n  font-size: 12px;\n  display: block;\n  float: left;\n  margin-right: 5px;\n  color: #c00;\n}\n\n#mocha .test pre.error {\n  color: #c00;\n  max-height: 300px;\n  overflow: auto;\n}\n\n#mocha .test .html-error {\n  overflow: auto;\n  color: black;\n  line-height: 1.5;\n  display: block;\n  float: left;\n  clear: left;\n  font: 12px/1.5 monaco, monospace;\n  margin: 5px;\n  padding: 15px;\n  border: 1px solid #eee;\n  max-width: 85%; /*(1)*/\n  max-width: -webkit-calc(100% - 42px);\n  max-width: -moz-calc(100% - 42px);\n  max-width: calc(100% - 42px); /*(2)*/\n  max-height: 300px;\n  word-wrap: break-word;\n  border-bottom-color: #ddd;\n  -webkit-box-shadow: 0 1px 3px #eee;\n  -moz-box-shadow: 0 1px 3px #eee;\n  box-shadow: 0 1px 3px #eee;\n  -webkit-border-radius: 3px;\n  -moz-border-radius: 3px;\n  border-radius: 3px;\n}\n\n#mocha .test .html-error pre.error {\n  border: none;\n  -webkit-border-radius: 0;\n  -moz-border-radius: 0;\n  border-radius: 0;\n  -webkit-box-shadow: 0;\n  -moz-box-shadow: 0;\n  box-shadow: 0;\n  padding: 0;\n  margin: 0;\n  margin-top: 18px;\n  max-height: none;\n}\n\n/**\n * (1): approximate for browsers not supporting calc\n * (2): 42 = 2*15 + 2*10 + 2*1 (padding + margin + border)\n *      ^^ seriously\n */\n#mocha .test pre {\n  display: block;\n  float: left;\n  clear: left;\n  font: 12px/1.5 monaco, monospace;\n  margin: 5px;\n  padding: 15px;\n  border: 1px solid #eee;\n  max-width: 85%; /*(1)*/\n  max-width: -webkit-calc(100% - 42px);\n  max-width: -moz-calc(100% - 42px);\n  max-width: calc(100% - 42px); /*(2)*/\n  word-wrap: break-word;\n  border-bottom-color: #ddd;\n  -webkit-box-shadow: 0 1px 3px #eee;\n  -moz-box-shadow: 0 1px 3px #eee;\n  box-shadow: 0 1px 3px #eee;\n  -webkit-border-radius: 3px;\n  -moz-border-radius: 3px;\n  border-radius: 3px;\n}\n\n#mocha .test h2 {\n  position: relative;\n}\n\n#mocha .test a.replay {\n  position: absolute;\n  top: 3px;\n  right: 0;\n  text-decoration: none;\n  vertical-align: middle;\n  display: block;\n  width: 15px;\n  height: 15px;\n  line-height: 15px;\n  text-align: center;\n  background: #eee;\n  font-size: 15px;\n  -webkit-border-radius: 15px;\n  -moz-border-radius: 15px;\n  border-radius: 15px;\n  -webkit-transition:opacity 200ms;\n  -moz-transition:opacity 200ms;\n  -o-transition:opacity 200ms;\n  transition: opacity 200ms;\n  opacity: 0.3;\n  color: #888;\n}\n\n#mocha .test:hover a.replay {\n  opacity: 1;\n}\n\n#mocha-report.pass .test.fail {\n  display: none;\n}\n\n#mocha-report.fail .test.pass {\n  display: none;\n}\n\n#mocha-report.pending .test.pass,\n#mocha-report.pending .test.fail {\n  display: none;\n}\n#mocha-report.pending .test.pass.pending {\n  display: block;\n}\n\n#mocha-error {\n  color: #c00;\n  font-size: 1.5em;\n  font-weight: 100;\n  letter-spacing: 1px;\n}\n\n#mocha-stats {\n  position: fixed;\n  top: 15px;\n  right: 10px;\n  font-size: 12px;\n  margin: 0;\n  color: #888;\n  z-index: 1;\n}\n\n#mocha-stats .progress {\n  float: right;\n  padding-top: 0;\n\n  /**\n   * Set safe initial values, so mochas .progress does not inherit these\n   * properties from Bootstrap .progress (which causes .progress height to\n   * equal line height set in Bootstrap).\n   */\n  height: auto;\n  -webkit-box-shadow: none;\n  -moz-box-shadow: none;\n  box-shadow: none;\n  background-color: initial;\n}\n\n#mocha-stats em {\n  color: black;\n}\n\n#mocha-stats a {\n  text-decoration: none;\n  color: inherit;\n}\n\n#mocha-stats a:hover {\n  border-bottom: 1px solid #eee;\n}\n\n#mocha-stats li {\n  display: inline-block;\n  margin: 0 5px;\n  list-style: none;\n  padding-top: 11px;\n}\n\n#mocha-stats canvas {\n  width: 40px;\n  height: 40px;\n}\n\n#mocha code .comment { color: #ddd; }\n#mocha code .init { color: #2f6fad; }\n#mocha code .string { color: #5890ad; }\n#mocha code .keyword { color: #8a6343; }\n#mocha code .number { color: #2f6fad; }\n\n@media screen and (max-device-width: 480px) {\n  #mocha {\n    margin: 60px 0px;\n  }\n\n  #mocha #stats {\n    position: absolute;\n  }\n}\n"
  },
  {
    "path": "app_frontend/static/plugin/JavaScript-Templates-3.8.0/test/vendor/mocha.js",
    "content": "(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require==\"function\"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error(\"Cannot find module '\"+o+\"'\");throw f.code=\"MODULE_NOT_FOUND\",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require==\"function\"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){\n(function (process,global){\n/* eslint no-unused-vars: off */\n\n/**\n * Shim process.stdout.\n */\n\nprocess.stdout = require('browser-stdout')();\n\nvar Mocha = require('./lib/mocha');\n\n/**\n * Create a Mocha instance.\n *\n * @return {undefined}\n */\n\nvar mocha = new Mocha({ reporter: 'html' });\n\n/**\n * Save timer references to avoid Sinon interfering (see GH-237).\n */\n\nvar Date = global.Date;\nvar setTimeout = global.setTimeout;\nvar setInterval = global.setInterval;\nvar clearTimeout = global.clearTimeout;\nvar clearInterval = global.clearInterval;\n\nvar uncaughtExceptionHandlers = [];\n\nvar originalOnerrorHandler = global.onerror;\n\n/**\n * Remove uncaughtException listener.\n * Revert to original onerror handler if previously defined.\n */\n\nprocess.removeListener = function(e, fn) {\n  if (e === 'uncaughtException') {\n    if (originalOnerrorHandler) {\n      global.onerror = originalOnerrorHandler;\n    } else {\n      global.onerror = function() {};\n    }\n    var i = Mocha.utils.indexOf(uncaughtExceptionHandlers, fn);\n    if (i !== -1) {\n      uncaughtExceptionHandlers.splice(i, 1);\n    }\n  }\n};\n\n/**\n * Implements uncaughtException listener.\n */\n\nprocess.on = function(e, fn) {\n  if (e === 'uncaughtException') {\n    global.onerror = function(err, url, line) {\n      fn(new Error(err + ' (' + url + ':' + line + ')'));\n      return !mocha.allowUncaught;\n    };\n    uncaughtExceptionHandlers.push(fn);\n  }\n};\n\n// The BDD UI is registered by default, but no UI will be functional in the\n// browser without an explicit call to the overridden `mocha.ui` (see below).\n// Ensure that this default UI does not expose its methods to the global scope.\nmocha.suite.removeAllListeners('pre-require');\n\nvar immediateQueue = [];\nvar immediateTimeout;\n\nfunction timeslice() {\n  var immediateStart = new Date().getTime();\n  while (immediateQueue.length && (new Date().getTime() - immediateStart) < 100) {\n    immediateQueue.shift()();\n  }\n  if (immediateQueue.length) {\n    immediateTimeout = setTimeout(timeslice, 0);\n  } else {\n    immediateTimeout = null;\n  }\n}\n\n/**\n * High-performance override of Runner.immediately.\n */\n\nMocha.Runner.immediately = function(callback) {\n  immediateQueue.push(callback);\n  if (!immediateTimeout) {\n    immediateTimeout = setTimeout(timeslice, 0);\n  }\n};\n\n/**\n * Function to allow assertion libraries to throw errors directly into mocha.\n * This is useful when running tests in a browser because window.onerror will\n * only receive the 'message' attribute of the Error.\n */\nmocha.throwError = function(err) {\n  Mocha.utils.forEach(uncaughtExceptionHandlers, function(fn) {\n    fn(err);\n  });\n  throw err;\n};\n\n/**\n * Override ui to ensure that the ui functions are initialized.\n * Normally this would happen in Mocha.prototype.loadFiles.\n */\n\nmocha.ui = function(ui) {\n  Mocha.prototype.ui.call(this, ui);\n  this.suite.emit('pre-require', global, null, this);\n  return this;\n};\n\n/**\n * Setup mocha with the given setting options.\n */\n\nmocha.setup = function(opts) {\n  if (typeof opts === 'string') {\n    opts = { ui: opts };\n  }\n  for (var opt in opts) {\n    if (opts.hasOwnProperty(opt)) {\n      this[opt](opts[opt]);\n    }\n  }\n  return this;\n};\n\n/**\n * Run mocha, returning the Runner.\n */\n\nmocha.run = function(fn) {\n  var options = mocha.options;\n  mocha.globals('location');\n\n  var query = Mocha.utils.parseQuery(global.location.search || '');\n  if (query.grep) {\n    mocha.grep(query.grep);\n  }\n  if (query.fgrep) {\n    mocha.fgrep(query.fgrep);\n  }\n  if (query.invert) {\n    mocha.invert();\n  }\n\n  return Mocha.prototype.run.call(mocha, function(err) {\n    // The DOM Document is not available in Web Workers.\n    var document = global.document;\n    if (document && document.getElementById('mocha') && options.noHighlighting !== true) {\n      Mocha.utils.highlightTags('code');\n    }\n    if (fn) {\n      fn(err);\n    }\n  });\n};\n\n/**\n * Expose the process shim.\n * https://github.com/mochajs/mocha/pull/916\n */\n\nMocha.process = process;\n\n/**\n * Expose mocha.\n */\n\nglobal.Mocha = Mocha;\nglobal.mocha = mocha;\n\n// this allows test/acceptance/required-tokens.js to pass; thus,\n// you can now do `const describe = require('mocha').describe` in a\n// browser context (assuming browserification).  should fix #880\nmodule.exports = global;\n\n}).call(this,require('_process'),typeof global !== \"undefined\" ? global : typeof self !== \"undefined\" ? self : typeof window !== \"undefined\" ? window : {})\n},{\"./lib/mocha\":14,\"_process\":67,\"browser-stdout\":41}],2:[function(require,module,exports){\n/* eslint-disable no-unused-vars */\nmodule.exports = function(type) {\n  return function() {};\n};\n\n},{}],3:[function(require,module,exports){\n/**\n * Module exports.\n */\n\nexports.EventEmitter = EventEmitter;\n\n/**\n * Object#toString reference.\n */\nvar objToString = Object.prototype.toString;\n\n/**\n * Check if a value is an array.\n *\n * @api private\n * @param {*} val The value to test.\n * @return {boolean} true if the value is an array, otherwise false.\n */\nfunction isArray(val) {\n  return objToString.call(val) === '[object Array]';\n}\n\n/**\n * Event emitter constructor.\n *\n * @api public\n */\nfunction EventEmitter() {}\n\n/**\n * Add a listener.\n *\n * @api public\n * @param {string} name Event name.\n * @param {Function} fn Event handler.\n * @return {EventEmitter} Emitter instance.\n */\nEventEmitter.prototype.on = function(name, fn) {\n  if (!this.$events) {\n    this.$events = {};\n  }\n\n  if (!this.$events[name]) {\n    this.$events[name] = fn;\n  } else if (isArray(this.$events[name])) {\n    this.$events[name].push(fn);\n  } else {\n    this.$events[name] = [this.$events[name], fn];\n  }\n\n  return this;\n};\n\nEventEmitter.prototype.addListener = EventEmitter.prototype.on;\n\n/**\n * Adds a volatile listener.\n *\n * @api public\n * @param {string} name Event name.\n * @param {Function} fn Event handler.\n * @return {EventEmitter} Emitter instance.\n */\nEventEmitter.prototype.once = function(name, fn) {\n  var self = this;\n\n  function on() {\n    self.removeListener(name, on);\n    fn.apply(this, arguments);\n  }\n\n  on.listener = fn;\n  this.on(name, on);\n\n  return this;\n};\n\n/**\n * Remove a listener.\n *\n * @api public\n * @param {string} name Event name.\n * @param {Function} fn Event handler.\n * @return {EventEmitter} Emitter instance.\n */\nEventEmitter.prototype.removeListener = function(name, fn) {\n  if (this.$events && this.$events[name]) {\n    var list = this.$events[name];\n\n    if (isArray(list)) {\n      var pos = -1;\n\n      for (var i = 0, l = list.length; i < l; i++) {\n        if (list[i] === fn || (list[i].listener && list[i].listener === fn)) {\n          pos = i;\n          break;\n        }\n      }\n\n      if (pos < 0) {\n        return this;\n      }\n\n      list.splice(pos, 1);\n\n      if (!list.length) {\n        delete this.$events[name];\n      }\n    } else if (list === fn || (list.listener && list.listener === fn)) {\n      delete this.$events[name];\n    }\n  }\n\n  return this;\n};\n\n/**\n * Remove all listeners for an event.\n *\n * @api public\n * @param {string} name Event name.\n * @return {EventEmitter} Emitter instance.\n */\nEventEmitter.prototype.removeAllListeners = function(name) {\n  if (name === undefined) {\n    this.$events = {};\n    return this;\n  }\n\n  if (this.$events && this.$events[name]) {\n    this.$events[name] = null;\n  }\n\n  return this;\n};\n\n/**\n * Get all listeners for a given event.\n *\n * @api public\n * @param {string} name Event name.\n * @return {EventEmitter} Emitter instance.\n */\nEventEmitter.prototype.listeners = function(name) {\n  if (!this.$events) {\n    this.$events = {};\n  }\n\n  if (!this.$events[name]) {\n    this.$events[name] = [];\n  }\n\n  if (!isArray(this.$events[name])) {\n    this.$events[name] = [this.$events[name]];\n  }\n\n  return this.$events[name];\n};\n\n/**\n * Emit an event.\n *\n * @api public\n * @param {string} name Event name.\n * @return {boolean} true if at least one handler was invoked, else false.\n */\nEventEmitter.prototype.emit = function(name) {\n  if (!this.$events) {\n    return false;\n  }\n\n  var handler = this.$events[name];\n\n  if (!handler) {\n    return false;\n  }\n\n  var args = Array.prototype.slice.call(arguments, 1);\n\n  if (typeof handler === 'function') {\n    handler.apply(this, args);\n  } else if (isArray(handler)) {\n    var listeners = handler.slice();\n\n    for (var i = 0, l = listeners.length; i < l; i++) {\n      listeners[i].apply(this, args);\n    }\n  } else {\n    return false;\n  }\n\n  return true;\n};\n\n},{}],4:[function(require,module,exports){\n/**\n * Expose `Progress`.\n */\n\nmodule.exports = Progress;\n\n/**\n * Initialize a new `Progress` indicator.\n */\nfunction Progress() {\n  this.percent = 0;\n  this.size(0);\n  this.fontSize(11);\n  this.font('helvetica, arial, sans-serif');\n}\n\n/**\n * Set progress size to `size`.\n *\n * @api public\n * @param {number} size\n * @return {Progress} Progress instance.\n */\nProgress.prototype.size = function(size) {\n  this._size = size;\n  return this;\n};\n\n/**\n * Set text to `text`.\n *\n * @api public\n * @param {string} text\n * @return {Progress} Progress instance.\n */\nProgress.prototype.text = function(text) {\n  this._text = text;\n  return this;\n};\n\n/**\n * Set font size to `size`.\n *\n * @api public\n * @param {number} size\n * @return {Progress} Progress instance.\n */\nProgress.prototype.fontSize = function(size) {\n  this._fontSize = size;\n  return this;\n};\n\n/**\n * Set font to `family`.\n *\n * @param {string} family\n * @return {Progress} Progress instance.\n */\nProgress.prototype.font = function(family) {\n  this._font = family;\n  return this;\n};\n\n/**\n * Update percentage to `n`.\n *\n * @param {number} n\n * @return {Progress} Progress instance.\n */\nProgress.prototype.update = function(n) {\n  this.percent = n;\n  return this;\n};\n\n/**\n * Draw on `ctx`.\n *\n * @param {CanvasRenderingContext2d} ctx\n * @return {Progress} Progress instance.\n */\nProgress.prototype.draw = function(ctx) {\n  try {\n    var percent = Math.min(this.percent, 100);\n    var size = this._size;\n    var half = size / 2;\n    var x = half;\n    var y = half;\n    var rad = half - 1;\n    var fontSize = this._fontSize;\n\n    ctx.font = fontSize + 'px ' + this._font;\n\n    var angle = Math.PI * 2 * (percent / 100);\n    ctx.clearRect(0, 0, size, size);\n\n    // outer circle\n    ctx.strokeStyle = '#9f9f9f';\n    ctx.beginPath();\n    ctx.arc(x, y, rad, 0, angle, false);\n    ctx.stroke();\n\n    // inner circle\n    ctx.strokeStyle = '#eee';\n    ctx.beginPath();\n    ctx.arc(x, y, rad - 1, 0, angle, true);\n    ctx.stroke();\n\n    // text\n    var text = this._text || (percent | 0) + '%';\n    var w = ctx.measureText(text).width;\n\n    ctx.fillText(text, x - w / 2 + 1, y + fontSize / 2 - 1);\n  } catch (err) {\n    // don't fail if we can't render progress\n  }\n  return this;\n};\n\n},{}],5:[function(require,module,exports){\n(function (global){\nexports.isatty = function isatty() {\n  return true;\n};\n\nexports.getWindowSize = function getWindowSize() {\n  if ('innerHeight' in global) {\n    return [global.innerHeight, global.innerWidth];\n  }\n  // In a Web Worker, the DOM Window is not available.\n  return [640, 480];\n};\n\n}).call(this,typeof global !== \"undefined\" ? global : typeof self !== \"undefined\" ? self : typeof window !== \"undefined\" ? window : {})\n},{}],6:[function(require,module,exports){\n/**\n * Module dependencies.\n */\n\nvar JSON = require('json3');\n\n/**\n * Expose `Context`.\n */\n\nmodule.exports = Context;\n\n/**\n * Initialize a new `Context`.\n *\n * @api private\n */\nfunction Context() {}\n\n/**\n * Set or get the context `Runnable` to `runnable`.\n *\n * @api private\n * @param {Runnable} runnable\n * @return {Context}\n */\nContext.prototype.runnable = function(runnable) {\n  if (!arguments.length) {\n    return this._runnable;\n  }\n  this.test = this._runnable = runnable;\n  return this;\n};\n\n/**\n * Set test timeout `ms`.\n *\n * @api private\n * @param {number} ms\n * @return {Context} self\n */\nContext.prototype.timeout = function(ms) {\n  if (!arguments.length) {\n    return this.runnable().timeout();\n  }\n  this.runnable().timeout(ms);\n  return this;\n};\n\n/**\n * Set test timeout `enabled`.\n *\n * @api private\n * @param {boolean} enabled\n * @return {Context} self\n */\nContext.prototype.enableTimeouts = function(enabled) {\n  this.runnable().enableTimeouts(enabled);\n  return this;\n};\n\n/**\n * Set test slowness threshold `ms`.\n *\n * @api private\n * @param {number} ms\n * @return {Context} self\n */\nContext.prototype.slow = function(ms) {\n  this.runnable().slow(ms);\n  return this;\n};\n\n/**\n * Mark a test as skipped.\n *\n * @api private\n * @return {Context} self\n */\nContext.prototype.skip = function() {\n  this.runnable().skip();\n  return this;\n};\n\n/**\n * Allow a number of retries on failed tests\n *\n * @api private\n * @param {number} n\n * @return {Context} self\n */\nContext.prototype.retries = function(n) {\n  if (!arguments.length) {\n    return this.runnable().retries();\n  }\n  this.runnable().retries(n);\n  return this;\n};\n\n/**\n * Inspect the context void of `._runnable`.\n *\n * @api private\n * @return {string}\n */\nContext.prototype.inspect = function() {\n  return JSON.stringify(this, function(key, val) {\n    return key === 'runnable' || key === 'test' ? undefined : val;\n  }, 2);\n};\n\n},{\"json3\":54}],7:[function(require,module,exports){\n/**\n * Module dependencies.\n */\n\nvar Runnable = require('./runnable');\nvar inherits = require('./utils').inherits;\n\n/**\n * Expose `Hook`.\n */\n\nmodule.exports = Hook;\n\n/**\n * Initialize a new `Hook` with the given `title` and callback `fn`.\n *\n * @param {String} title\n * @param {Function} fn\n * @api private\n */\nfunction Hook(title, fn) {\n  Runnable.call(this, title, fn);\n  this.type = 'hook';\n}\n\n/**\n * Inherit from `Runnable.prototype`.\n */\ninherits(Hook, Runnable);\n\n/**\n * Get or set the test `err`.\n *\n * @param {Error} err\n * @return {Error}\n * @api public\n */\nHook.prototype.error = function(err) {\n  if (!arguments.length) {\n    err = this._error;\n    this._error = null;\n    return err;\n  }\n\n  this._error = err;\n};\n\n},{\"./runnable\":33,\"./utils\":38}],8:[function(require,module,exports){\n/**\n * Module dependencies.\n */\n\nvar Test = require('../test');\n\n/**\n * BDD-style interface:\n *\n *      describe('Array', function() {\n *        describe('#indexOf()', function() {\n *          it('should return -1 when not present', function() {\n *            // ...\n *          });\n *\n *          it('should return the index when present', function() {\n *            // ...\n *          });\n *        });\n *      });\n *\n * @param {Suite} suite Root suite.\n */\nmodule.exports = function(suite) {\n  var suites = [suite];\n\n  suite.on('pre-require', function(context, file, mocha) {\n    var common = require('./common')(suites, context, mocha);\n\n    context.before = common.before;\n    context.after = common.after;\n    context.beforeEach = common.beforeEach;\n    context.afterEach = common.afterEach;\n    context.run = mocha.options.delay && common.runWithSuite(suite);\n    /**\n     * Describe a \"suite\" with the given `title`\n     * and callback `fn` containing nested suites\n     * and/or tests.\n     */\n\n    context.describe = context.context = function(title, fn) {\n      return common.suite.create({\n        title: title,\n        file: file,\n        fn: fn\n      });\n    };\n\n    /**\n     * Pending describe.\n     */\n\n    context.xdescribe = context.xcontext = context.describe.skip = function(title, fn) {\n      return common.suite.skip({\n        title: title,\n        file: file,\n        fn: fn\n      });\n    };\n\n    /**\n     * Exclusive suite.\n     */\n\n    context.describe.only = function(title, fn) {\n      return common.suite.only({\n        title: title,\n        file: file,\n        fn: fn\n      });\n    };\n\n    /**\n     * Describe a specification or test-case\n     * with the given `title` and callback `fn`\n     * acting as a thunk.\n     */\n\n    context.it = context.specify = function(title, fn) {\n      var suite = suites[0];\n      if (suite.isPending()) {\n        fn = null;\n      }\n      var test = new Test(title, fn);\n      test.file = file;\n      suite.addTest(test);\n      return test;\n    };\n\n    /**\n     * Exclusive test-case.\n     */\n\n    context.it.only = function(title, fn) {\n      return common.test.only(mocha, context.it(title, fn));\n    };\n\n    /**\n     * Pending test case.\n     */\n\n    context.xit = context.xspecify = context.it.skip = function(title) {\n      context.it(title);\n    };\n\n    /**\n     * Number of attempts to retry.\n     */\n    context.it.retries = function(n) {\n      context.retries(n);\n    };\n  });\n};\n\n},{\"../test\":36,\"./common\":9}],9:[function(require,module,exports){\n'use strict';\n\nvar Suite = require('../suite');\n\n/**\n * Functions common to more than one interface.\n *\n * @param {Suite[]} suites\n * @param {Context} context\n * @param {Mocha} mocha\n * @return {Object} An object containing common functions.\n */\nmodule.exports = function(suites, context, mocha) {\n  return {\n    /**\n     * This is only present if flag --delay is passed into Mocha. It triggers\n     * root suite execution.\n     *\n     * @param {Suite} suite The root wuite.\n     * @return {Function} A function which runs the root suite\n     */\n    runWithSuite: function runWithSuite(suite) {\n      return function run() {\n        suite.run();\n      };\n    },\n\n    /**\n     * Execute before running tests.\n     *\n     * @param {string} name\n     * @param {Function} fn\n     */\n    before: function(name, fn) {\n      suites[0].beforeAll(name, fn);\n    },\n\n    /**\n     * Execute after running tests.\n     *\n     * @param {string} name\n     * @param {Function} fn\n     */\n    after: function(name, fn) {\n      suites[0].afterAll(name, fn);\n    },\n\n    /**\n     * Execute before each test case.\n     *\n     * @param {string} name\n     * @param {Function} fn\n     */\n    beforeEach: function(name, fn) {\n      suites[0].beforeEach(name, fn);\n    },\n\n    /**\n     * Execute after each test case.\n     *\n     * @param {string} name\n     * @param {Function} fn\n     */\n    afterEach: function(name, fn) {\n      suites[0].afterEach(name, fn);\n    },\n\n    suite: {\n      /**\n       * Create an exclusive Suite; convenience function\n       * See docstring for create() below.\n       *\n       * @param {Object} opts\n       * @returns {Suite}\n       */\n      only: function only(opts) {\n        mocha.options.hasOnly = true;\n        opts.isOnly = true;\n        return this.create(opts);\n      },\n\n      /**\n       * Create a Suite, but skip it; convenience function\n       * See docstring for create() below.\n       *\n       * @param {Object} opts\n       * @returns {Suite}\n       */\n      skip: function skip(opts) {\n        opts.pending = true;\n        return this.create(opts);\n      },\n\n      /**\n       * Creates a suite.\n       * @param {Object} opts Options\n       * @param {string} opts.title Title of Suite\n       * @param {Function} [opts.fn] Suite Function (not always applicable)\n       * @param {boolean} [opts.pending] Is Suite pending?\n       * @param {string} [opts.file] Filepath where this Suite resides\n       * @param {boolean} [opts.isOnly] Is Suite exclusive?\n       * @returns {Suite}\n       */\n      create: function create(opts) {\n        var suite = Suite.create(suites[0], opts.title);\n        suite.pending = Boolean(opts.pending);\n        suite.file = opts.file;\n        suites.unshift(suite);\n        if (opts.isOnly) {\n          suite.parent._onlySuites = suite.parent._onlySuites.concat(suite);\n          mocha.options.hasOnly = true;\n        }\n        if (typeof opts.fn === 'function') {\n          opts.fn.call(suite);\n          suites.shift();\n        } else if (typeof opts.fn === 'undefined' && !suite.pending) {\n          throw new Error('Suite \"' + suite.fullTitle() + '\" was defined but no callback was supplied. Supply a callback or explicitly skip the suite.');\n        }\n\n        return suite;\n      }\n    },\n\n    test: {\n\n      /**\n       * Exclusive test-case.\n       *\n       * @param {Object} mocha\n       * @param {Function} test\n       * @returns {*}\n       */\n      only: function(mocha, test) {\n        test.parent._onlyTests = test.parent._onlyTests.concat(test);\n        mocha.options.hasOnly = true;\n        return test;\n      },\n\n      /**\n       * Pending test case.\n       *\n       * @param {string} title\n       */\n      skip: function(title) {\n        context.test(title);\n      },\n\n      /**\n       * Number of retry attempts\n       *\n       * @param {number} n\n       */\n      retries: function(n) {\n        context.retries(n);\n      }\n    }\n  };\n};\n\n},{\"../suite\":35}],10:[function(require,module,exports){\n/**\n * Module dependencies.\n */\n\nvar Suite = require('../suite');\nvar Test = require('../test');\n\n/**\n * Exports-style (as Node.js module) interface:\n *\n *     exports.Array = {\n *       '#indexOf()': {\n *         'should return -1 when the value is not present': function() {\n *\n *         },\n *\n *         'should return the correct index when the value is present': function() {\n *\n *         }\n *       }\n *     };\n *\n * @param {Suite} suite Root suite.\n */\nmodule.exports = function(suite) {\n  var suites = [suite];\n\n  suite.on('require', visit);\n\n  function visit(obj, file) {\n    var suite;\n    for (var key in obj) {\n      if (typeof obj[key] === 'function') {\n        var fn = obj[key];\n        switch (key) {\n          case 'before':\n            suites[0].beforeAll(fn);\n            break;\n          case 'after':\n            suites[0].afterAll(fn);\n            break;\n          case 'beforeEach':\n            suites[0].beforeEach(fn);\n            break;\n          case 'afterEach':\n            suites[0].afterEach(fn);\n            break;\n          default:\n            var test = new Test(key, fn);\n            test.file = file;\n            suites[0].addTest(test);\n        }\n      } else {\n        suite = Suite.create(suites[0], key);\n        suites.unshift(suite);\n        visit(obj[key], file);\n        suites.shift();\n      }\n    }\n  }\n};\n\n},{\"../suite\":35,\"../test\":36}],11:[function(require,module,exports){\nexports.bdd = require('./bdd');\nexports.tdd = require('./tdd');\nexports.qunit = require('./qunit');\nexports.exports = require('./exports');\n\n},{\"./bdd\":8,\"./exports\":10,\"./qunit\":12,\"./tdd\":13}],12:[function(require,module,exports){\n/**\n * Module dependencies.\n */\n\nvar Test = require('../test');\n\n/**\n * QUnit-style interface:\n *\n *     suite('Array');\n *\n *     test('#length', function() {\n *       var arr = [1,2,3];\n *       ok(arr.length == 3);\n *     });\n *\n *     test('#indexOf()', function() {\n *       var arr = [1,2,3];\n *       ok(arr.indexOf(1) == 0);\n *       ok(arr.indexOf(2) == 1);\n *       ok(arr.indexOf(3) == 2);\n *     });\n *\n *     suite('String');\n *\n *     test('#length', function() {\n *       ok('foo'.length == 3);\n *     });\n *\n * @param {Suite} suite Root suite.\n */\nmodule.exports = function(suite) {\n  var suites = [suite];\n\n  suite.on('pre-require', function(context, file, mocha) {\n    var common = require('./common')(suites, context, mocha);\n\n    context.before = common.before;\n    context.after = common.after;\n    context.beforeEach = common.beforeEach;\n    context.afterEach = common.afterEach;\n    context.run = mocha.options.delay && common.runWithSuite(suite);\n    /**\n     * Describe a \"suite\" with the given `title`.\n     */\n\n    context.suite = function(title) {\n      if (suites.length > 1) {\n        suites.shift();\n      }\n      return common.suite.create({\n        title: title,\n        file: file,\n        fn: false\n      });\n    };\n\n    /**\n     * Exclusive Suite.\n     */\n\n    context.suite.only = function(title) {\n      if (suites.length > 1) {\n        suites.shift();\n      }\n      return common.suite.only({\n        title: title,\n        file: file,\n        fn: false\n      });\n    };\n\n    /**\n     * Describe a specification or test-case\n     * with the given `title` and callback `fn`\n     * acting as a thunk.\n     */\n\n    context.test = function(title, fn) {\n      var test = new Test(title, fn);\n      test.file = file;\n      suites[0].addTest(test);\n      return test;\n    };\n\n    /**\n     * Exclusive test-case.\n     */\n\n    context.test.only = function(title, fn) {\n      return common.test.only(mocha, context.test(title, fn));\n    };\n\n    context.test.skip = common.test.skip;\n    context.test.retries = common.test.retries;\n  });\n};\n\n},{\"../test\":36,\"./common\":9}],13:[function(require,module,exports){\n/**\n * Module dependencies.\n */\n\nvar Test = require('../test');\n\n/**\n * TDD-style interface:\n *\n *      suite('Array', function() {\n *        suite('#indexOf()', function() {\n *          suiteSetup(function() {\n *\n *          });\n *\n *          test('should return -1 when not present', function() {\n *\n *          });\n *\n *          test('should return the index when present', function() {\n *\n *          });\n *\n *          suiteTeardown(function() {\n *\n *          });\n *        });\n *      });\n *\n * @param {Suite} suite Root suite.\n */\nmodule.exports = function(suite) {\n  var suites = [suite];\n\n  suite.on('pre-require', function(context, file, mocha) {\n    var common = require('./common')(suites, context, mocha);\n\n    context.setup = common.beforeEach;\n    context.teardown = common.afterEach;\n    context.suiteSetup = common.before;\n    context.suiteTeardown = common.after;\n    context.run = mocha.options.delay && common.runWithSuite(suite);\n\n    /**\n     * Describe a \"suite\" with the given `title` and callback `fn` containing\n     * nested suites and/or tests.\n     */\n    context.suite = function(title, fn) {\n      return common.suite.create({\n        title: title,\n        file: file,\n        fn: fn\n      });\n    };\n\n    /**\n     * Pending suite.\n     */\n    context.suite.skip = function(title, fn) {\n      return common.suite.skip({\n        title: title,\n        file: file,\n        fn: fn\n      });\n    };\n\n    /**\n     * Exclusive test-case.\n     */\n    context.suite.only = function(title, fn) {\n      return common.suite.only({\n        title: title,\n        file: file,\n        fn: fn\n      });\n    };\n\n    /**\n     * Describe a specification or test-case with the given `title` and\n     * callback `fn` acting as a thunk.\n     */\n    context.test = function(title, fn) {\n      var suite = suites[0];\n      if (suite.isPending()) {\n        fn = null;\n      }\n      var test = new Test(title, fn);\n      test.file = file;\n      suite.addTest(test);\n      return test;\n    };\n\n    /**\n     * Exclusive test-case.\n     */\n\n    context.test.only = function(title, fn) {\n      return common.test.only(mocha, context.test(title, fn));\n    };\n\n    context.test.skip = common.test.skip;\n    context.test.retries = common.test.retries;\n  });\n};\n\n},{\"../test\":36,\"./common\":9}],14:[function(require,module,exports){\n(function (process,global,__dirname){\n/*!\n * mocha\n * Copyright(c) 2011 TJ Holowaychuk <tj@vision-media.ca>\n * MIT Licensed\n */\n\n/**\n * Module dependencies.\n */\n\nvar escapeRe = require('escape-string-regexp');\nvar path = require('path');\nvar reporters = require('./reporters');\nvar utils = require('./utils');\n\n/**\n * Expose `Mocha`.\n */\n\nexports = module.exports = Mocha;\n\n/**\n * To require local UIs and reporters when running in node.\n */\n\nif (!process.browser) {\n  var cwd = process.cwd();\n  module.paths.push(cwd, path.join(cwd, 'node_modules'));\n}\n\n/**\n * Expose internals.\n */\n\nexports.utils = utils;\nexports.interfaces = require('./interfaces');\nexports.reporters = reporters;\nexports.Runnable = require('./runnable');\nexports.Context = require('./context');\nexports.Runner = require('./runner');\nexports.Suite = require('./suite');\nexports.Hook = require('./hook');\nexports.Test = require('./test');\n\n/**\n * Return image `name` path.\n *\n * @api private\n * @param {string} name\n * @return {string}\n */\nfunction image(name) {\n  return path.join(__dirname, '../images', name + '.png');\n}\n\n/**\n * Set up mocha with `options`.\n *\n * Options:\n *\n *   - `ui` name \"bdd\", \"tdd\", \"exports\" etc\n *   - `reporter` reporter instance, defaults to `mocha.reporters.spec`\n *   - `globals` array of accepted globals\n *   - `timeout` timeout in milliseconds\n *   - `retries` number of times to retry failed tests\n *   - `bail` bail on the first test failure\n *   - `slow` milliseconds to wait before considering a test slow\n *   - `ignoreLeaks` ignore global leaks\n *   - `fullTrace` display the full stack-trace on failing\n *   - `grep` string or regexp to filter tests with\n *\n * @param {Object} options\n * @api public\n */\nfunction Mocha(options) {\n  options = options || {};\n  this.files = [];\n  this.options = options;\n  if (options.grep) {\n    this.grep(new RegExp(options.grep));\n  }\n  if (options.fgrep) {\n    this.fgrep(options.fgrep);\n  }\n  this.suite = new exports.Suite('', new exports.Context());\n  this.ui(options.ui);\n  this.bail(options.bail);\n  this.reporter(options.reporter, options.reporterOptions);\n  if (typeof options.timeout !== 'undefined' && options.timeout !== null) {\n    this.timeout(options.timeout);\n  }\n  if (typeof options.retries !== 'undefined' && options.retries !== null) {\n    this.retries(options.retries);\n  }\n  this.useColors(options.useColors);\n  if (options.enableTimeouts !== null) {\n    this.enableTimeouts(options.enableTimeouts);\n  }\n  if (options.slow) {\n    this.slow(options.slow);\n  }\n}\n\n/**\n * Enable or disable bailing on the first failure.\n *\n * @api public\n * @param {boolean} [bail]\n */\nMocha.prototype.bail = function(bail) {\n  if (!arguments.length) {\n    bail = true;\n  }\n  this.suite.bail(bail);\n  return this;\n};\n\n/**\n * Add test `file`.\n *\n * @api public\n * @param {string} file\n */\nMocha.prototype.addFile = function(file) {\n  this.files.push(file);\n  return this;\n};\n\n/**\n * Set reporter to `reporter`, defaults to \"spec\".\n *\n * @param {String|Function} reporter name or constructor\n * @param {Object} reporterOptions optional options\n * @api public\n * @param {string|Function} reporter name or constructor\n * @param {Object} reporterOptions optional options\n */\nMocha.prototype.reporter = function(reporter, reporterOptions) {\n  if (typeof reporter === 'function') {\n    this._reporter = reporter;\n  } else {\n    reporter = reporter || 'spec';\n    var _reporter;\n    // Try to load a built-in reporter.\n    if (reporters[reporter]) {\n      _reporter = reporters[reporter];\n    }\n    // Try to load reporters from process.cwd() and node_modules\n    if (!_reporter) {\n      try {\n        _reporter = require(reporter);\n      } catch (err) {\n        err.message.indexOf('Cannot find module') !== -1\n          ? console.warn('\"' + reporter + '\" reporter not found')\n          : console.warn('\"' + reporter + '\" reporter blew up with error:\\n' + err.stack);\n      }\n    }\n    if (!_reporter && reporter === 'teamcity') {\n      console.warn('The Teamcity reporter was moved to a package named '\n        + 'mocha-teamcity-reporter '\n        + '(https://npmjs.org/package/mocha-teamcity-reporter).');\n    }\n    if (!_reporter) {\n      throw new Error('invalid reporter \"' + reporter + '\"');\n    }\n    this._reporter = _reporter;\n  }\n  this.options.reporterOptions = reporterOptions;\n  return this;\n};\n\n/**\n * Set test UI `name`, defaults to \"bdd\".\n *\n * @api public\n * @param {string} bdd\n */\nMocha.prototype.ui = function(name) {\n  name = name || 'bdd';\n  this._ui = exports.interfaces[name];\n  if (!this._ui) {\n    try {\n      this._ui = require(name);\n    } catch (err) {\n      throw new Error('invalid interface \"' + name + '\"');\n    }\n  }\n  this._ui = this._ui(this.suite);\n\n  this.suite.on('pre-require', function(context) {\n    exports.afterEach = context.afterEach || context.teardown;\n    exports.after = context.after || context.suiteTeardown;\n    exports.beforeEach = context.beforeEach || context.setup;\n    exports.before = context.before || context.suiteSetup;\n    exports.describe = context.describe || context.suite;\n    exports.it = context.it || context.test;\n    exports.setup = context.setup || context.beforeEach;\n    exports.suiteSetup = context.suiteSetup || context.before;\n    exports.suiteTeardown = context.suiteTeardown || context.after;\n    exports.suite = context.suite || context.describe;\n    exports.teardown = context.teardown || context.afterEach;\n    exports.test = context.test || context.it;\n    exports.run = context.run;\n  });\n\n  return this;\n};\n\n/**\n * Load registered files.\n *\n * @api private\n */\nMocha.prototype.loadFiles = function(fn) {\n  var self = this;\n  var suite = this.suite;\n  this.files.forEach(function(file) {\n    file = path.resolve(file);\n    suite.emit('pre-require', global, file, self);\n    suite.emit('require', require(file), file, self);\n    suite.emit('post-require', global, file, self);\n  });\n  fn && fn();\n};\n\n/**\n * Enable growl support.\n *\n * @api private\n */\nMocha.prototype._growl = function(runner, reporter) {\n  var notify = require('growl');\n\n  runner.on('end', function() {\n    var stats = reporter.stats;\n    if (stats.failures) {\n      var msg = stats.failures + ' of ' + runner.total + ' tests failed';\n      notify(msg, { name: 'mocha', title: 'Failed', image: image('error') });\n    } else {\n      notify(stats.passes + ' tests passed in ' + stats.duration + 'ms', {\n        name: 'mocha',\n        title: 'Passed',\n        image: image('ok')\n      });\n    }\n  });\n};\n\n/**\n * Escape string and add it to grep as a regexp.\n *\n * @api public\n * @param str\n * @returns {Mocha}\n */\nMocha.prototype.fgrep = function(str) {\n  return this.grep(new RegExp(escapeRe(str)));\n};\n\n/**\n * Add regexp to grep, if `re` is a string it is escaped.\n *\n * @param {RegExp|String} re\n * @return {Mocha}\n * @api public\n * @param {RegExp|string} re\n * @return {Mocha}\n */\nMocha.prototype.grep = function(re) {\n  if (utils.isString(re)) {\n    // extract args if it's regex-like, i.e: [string, pattern, flag]\n    var arg = re.match(/^\\/(.*)\\/(g|i|)$|.*/);\n    this.options.grep = new RegExp(arg[1] || arg[0], arg[2]);\n  } else {\n    this.options.grep = re;\n  }\n  return this;\n};\n/**\n * Invert `.grep()` matches.\n *\n * @return {Mocha}\n * @api public\n */\nMocha.prototype.invert = function() {\n  this.options.invert = true;\n  return this;\n};\n\n/**\n * Ignore global leaks.\n *\n * @param {Boolean} ignore\n * @return {Mocha}\n * @api public\n * @param {boolean} ignore\n * @return {Mocha}\n */\nMocha.prototype.ignoreLeaks = function(ignore) {\n  this.options.ignoreLeaks = Boolean(ignore);\n  return this;\n};\n\n/**\n * Enable global leak checking.\n *\n * @return {Mocha}\n * @api public\n */\nMocha.prototype.checkLeaks = function() {\n  this.options.ignoreLeaks = false;\n  return this;\n};\n\n/**\n * Display long stack-trace on failing\n *\n * @return {Mocha}\n * @api public\n */\nMocha.prototype.fullTrace = function() {\n  this.options.fullStackTrace = true;\n  return this;\n};\n\n/**\n * Enable growl support.\n *\n * @return {Mocha}\n * @api public\n */\nMocha.prototype.growl = function() {\n  this.options.growl = true;\n  return this;\n};\n\n/**\n * Ignore `globals` array or string.\n *\n * @param {Array|String} globals\n * @return {Mocha}\n * @api public\n * @param {Array|string} globals\n * @return {Mocha}\n */\nMocha.prototype.globals = function(globals) {\n  this.options.globals = (this.options.globals || []).concat(globals);\n  return this;\n};\n\n/**\n * Emit color output.\n *\n * @param {Boolean} colors\n * @return {Mocha}\n * @api public\n * @param {boolean} colors\n * @return {Mocha}\n */\nMocha.prototype.useColors = function(colors) {\n  if (colors !== undefined) {\n    this.options.useColors = colors;\n  }\n  return this;\n};\n\n/**\n * Use inline diffs rather than +/-.\n *\n * @param {Boolean} inlineDiffs\n * @return {Mocha}\n * @api public\n * @param {boolean} inlineDiffs\n * @return {Mocha}\n */\nMocha.prototype.useInlineDiffs = function(inlineDiffs) {\n  this.options.useInlineDiffs = inlineDiffs !== undefined && inlineDiffs;\n  return this;\n};\n\n/**\n * Set the timeout in milliseconds.\n *\n * @param {Number} timeout\n * @return {Mocha}\n * @api public\n * @param {number} timeout\n * @return {Mocha}\n */\nMocha.prototype.timeout = function(timeout) {\n  this.suite.timeout(timeout);\n  return this;\n};\n\n/**\n * Set the number of times to retry failed tests.\n *\n * @param {Number} retry times\n * @return {Mocha}\n * @api public\n */\nMocha.prototype.retries = function(n) {\n  this.suite.retries(n);\n  return this;\n};\n\n/**\n * Set slowness threshold in milliseconds.\n *\n * @param {Number} slow\n * @return {Mocha}\n * @api public\n * @param {number} slow\n * @return {Mocha}\n */\nMocha.prototype.slow = function(slow) {\n  this.suite.slow(slow);\n  return this;\n};\n\n/**\n * Enable timeouts.\n *\n * @param {Boolean} enabled\n * @return {Mocha}\n * @api public\n * @param {boolean} enabled\n * @return {Mocha}\n */\nMocha.prototype.enableTimeouts = function(enabled) {\n  this.suite.enableTimeouts(arguments.length && enabled !== undefined ? enabled : true);\n  return this;\n};\n\n/**\n * Makes all tests async (accepting a callback)\n *\n * @return {Mocha}\n * @api public\n */\nMocha.prototype.asyncOnly = function() {\n  this.options.asyncOnly = true;\n  return this;\n};\n\n/**\n * Disable syntax highlighting (in browser).\n *\n * @api public\n */\nMocha.prototype.noHighlighting = function() {\n  this.options.noHighlighting = true;\n  return this;\n};\n\n/**\n * Enable uncaught errors to propagate (in browser).\n *\n * @return {Mocha}\n * @api public\n */\nMocha.prototype.allowUncaught = function() {\n  this.options.allowUncaught = true;\n  return this;\n};\n\n/**\n * Delay root suite execution.\n * @returns {Mocha}\n */\nMocha.prototype.delay = function delay() {\n  this.options.delay = true;\n  return this;\n};\n\n/**\n * Run tests and invoke `fn()` when complete.\n *\n * @api public\n * @param {Function} fn\n * @return {Runner}\n */\nMocha.prototype.run = function(fn) {\n  if (this.files.length) {\n    this.loadFiles();\n  }\n  var suite = this.suite;\n  var options = this.options;\n  options.files = this.files;\n  var runner = new exports.Runner(suite, options.delay);\n  var reporter = new this._reporter(runner, options);\n  runner.ignoreLeaks = options.ignoreLeaks !== false;\n  runner.fullStackTrace = options.fullStackTrace;\n  runner.hasOnly = options.hasOnly;\n  runner.asyncOnly = options.asyncOnly;\n  runner.allowUncaught = options.allowUncaught;\n  if (options.grep) {\n    runner.grep(options.grep, options.invert);\n  }\n  if (options.globals) {\n    runner.globals(options.globals);\n  }\n  if (options.growl) {\n    this._growl(runner, reporter);\n  }\n  if (options.useColors !== undefined) {\n    exports.reporters.Base.useColors = options.useColors;\n  }\n  exports.reporters.Base.inlineDiffs = options.useInlineDiffs;\n\n  function done(failures) {\n    if (reporter.done) {\n      reporter.done(failures, fn);\n    } else {\n      fn && fn(failures);\n    }\n  }\n\n  return runner.run(done);\n};\n\n}).call(this,require('_process'),typeof global !== \"undefined\" ? global : typeof self !== \"undefined\" ? self : typeof window !== \"undefined\" ? window : {},\"/lib\")\n},{\"./context\":6,\"./hook\":7,\"./interfaces\":11,\"./reporters\":21,\"./runnable\":33,\"./runner\":34,\"./suite\":35,\"./test\":36,\"./utils\":38,\"_process\":67,\"escape-string-regexp\":47,\"growl\":49,\"path\":42}],15:[function(require,module,exports){\n/**\n * Helpers.\n */\n\nvar s = 1000;\nvar m = s * 60;\nvar h = m * 60;\nvar d = h * 24;\nvar y = d * 365.25;\n\n/**\n * Parse or format the given `val`.\n *\n * Options:\n *\n *  - `long` verbose formatting [false]\n *\n * @api public\n * @param {string|number} val\n * @param {Object} options\n * @return {string|number}\n */\nmodule.exports = function(val, options) {\n  options = options || {};\n  if (typeof val === 'string') {\n    return parse(val);\n  }\n  // https://github.com/mochajs/mocha/pull/1035\n  return options['long'] ? longFormat(val) : shortFormat(val);\n};\n\n/**\n * Parse the given `str` and return milliseconds.\n *\n * @api private\n * @param {string} str\n * @return {number}\n */\nfunction parse(str) {\n  var match = (/^((?:\\d+)?\\.?\\d+) *(ms|seconds?|s|minutes?|m|hours?|h|days?|d|years?|y)?$/i).exec(str);\n  if (!match) {\n    return;\n  }\n  var n = parseFloat(match[1]);\n  var type = (match[2] || 'ms').toLowerCase();\n  switch (type) {\n    case 'years':\n    case 'year':\n    case 'y':\n      return n * y;\n    case 'days':\n    case 'day':\n    case 'd':\n      return n * d;\n    case 'hours':\n    case 'hour':\n    case 'h':\n      return n * h;\n    case 'minutes':\n    case 'minute':\n    case 'm':\n      return n * m;\n    case 'seconds':\n    case 'second':\n    case 's':\n      return n * s;\n    case 'ms':\n      return n;\n    default:\n      // No default case\n  }\n}\n\n/**\n * Short format for `ms`.\n *\n * @api private\n * @param {number} ms\n * @return {string}\n */\nfunction shortFormat(ms) {\n  if (ms >= d) {\n    return Math.round(ms / d) + 'd';\n  }\n  if (ms >= h) {\n    return Math.round(ms / h) + 'h';\n  }\n  if (ms >= m) {\n    return Math.round(ms / m) + 'm';\n  }\n  if (ms >= s) {\n    return Math.round(ms / s) + 's';\n  }\n  return ms + 'ms';\n}\n\n/**\n * Long format for `ms`.\n *\n * @api private\n * @param {number} ms\n * @return {string}\n */\nfunction longFormat(ms) {\n  return plural(ms, d, 'day')\n    || plural(ms, h, 'hour')\n    || plural(ms, m, 'minute')\n    || plural(ms, s, 'second')\n    || ms + ' ms';\n}\n\n/**\n * Pluralization helper.\n *\n * @api private\n * @param {number} ms\n * @param {number} n\n * @param {string} name\n */\nfunction plural(ms, n, name) {\n  if (ms < n) {\n    return;\n  }\n  if (ms < n * 1.5) {\n    return Math.floor(ms / n) + ' ' + name;\n  }\n  return Math.ceil(ms / n) + ' ' + name + 's';\n}\n\n},{}],16:[function(require,module,exports){\n\n/**\n * Expose `Pending`.\n */\n\nmodule.exports = Pending;\n\n/**\n * Initialize a new `Pending` error with the given message.\n *\n * @param {string} message\n */\nfunction Pending(message) {\n  this.message = message;\n}\n\n},{}],17:[function(require,module,exports){\n(function (process,global){\n/**\n * Module dependencies.\n */\n\nvar tty = require('tty');\nvar diff = require('diff');\nvar ms = require('../ms');\nvar utils = require('../utils');\nvar supportsColor = process.browser ? null : require('supports-color');\n\n/**\n * Expose `Base`.\n */\n\nexports = module.exports = Base;\n\n/**\n * Save timer references to avoid Sinon interfering.\n * See: https://github.com/mochajs/mocha/issues/237\n */\n\n/* eslint-disable no-unused-vars, no-native-reassign */\nvar Date = global.Date;\nvar setTimeout = global.setTimeout;\nvar setInterval = global.setInterval;\nvar clearTimeout = global.clearTimeout;\nvar clearInterval = global.clearInterval;\n/* eslint-enable no-unused-vars, no-native-reassign */\n\n/**\n * Check if both stdio streams are associated with a tty.\n */\n\nvar isatty = tty.isatty(1) && tty.isatty(2);\n\n/**\n * Enable coloring by default, except in the browser interface.\n */\n\nexports.useColors = !process.browser && (supportsColor || (process.env.MOCHA_COLORS !== undefined));\n\n/**\n * Inline diffs instead of +/-\n */\n\nexports.inlineDiffs = false;\n\n/**\n * Default color map.\n */\n\nexports.colors = {\n  pass: 90,\n  fail: 31,\n  'bright pass': 92,\n  'bright fail': 91,\n  'bright yellow': 93,\n  pending: 36,\n  suite: 0,\n  'error title': 0,\n  'error message': 31,\n  'error stack': 90,\n  checkmark: 32,\n  fast: 90,\n  medium: 33,\n  slow: 31,\n  green: 32,\n  light: 90,\n  'diff gutter': 90,\n  'diff added': 32,\n  'diff removed': 31\n};\n\n/**\n * Default symbol map.\n */\n\nexports.symbols = {\n  ok: '✓',\n  err: '✖',\n  dot: '․',\n  comma: ',',\n  bang: '!'\n};\n\n// With node.js on Windows: use symbols available in terminal default fonts\nif (process.platform === 'win32') {\n  exports.symbols.ok = '\\u221A';\n  exports.symbols.err = '\\u00D7';\n  exports.symbols.dot = '.';\n}\n\n/**\n * Color `str` with the given `type`,\n * allowing colors to be disabled,\n * as well as user-defined color\n * schemes.\n *\n * @param {string} type\n * @param {string} str\n * @return {string}\n * @api private\n */\nvar color = exports.color = function(type, str) {\n  if (!exports.useColors) {\n    return String(str);\n  }\n  return '\\u001b[' + exports.colors[type] + 'm' + str + '\\u001b[0m';\n};\n\n/**\n * Expose term window size, with some defaults for when stderr is not a tty.\n */\n\nexports.window = {\n  width: 75\n};\n\nif (isatty) {\n  exports.window.width = process.stdout.getWindowSize\n      ? process.stdout.getWindowSize(1)[0]\n      : tty.getWindowSize()[1];\n}\n\n/**\n * Expose some basic cursor interactions that are common among reporters.\n */\n\nexports.cursor = {\n  hide: function() {\n    isatty && process.stdout.write('\\u001b[?25l');\n  },\n\n  show: function() {\n    isatty && process.stdout.write('\\u001b[?25h');\n  },\n\n  deleteLine: function() {\n    isatty && process.stdout.write('\\u001b[2K');\n  },\n\n  beginningOfLine: function() {\n    isatty && process.stdout.write('\\u001b[0G');\n  },\n\n  CR: function() {\n    if (isatty) {\n      exports.cursor.deleteLine();\n      exports.cursor.beginningOfLine();\n    } else {\n      process.stdout.write('\\r');\n    }\n  }\n};\n\n/**\n * Outut the given `failures` as a list.\n *\n * @param {Array} failures\n * @api public\n */\n\nexports.list = function(failures) {\n  console.log();\n  failures.forEach(function(test, i) {\n    // format\n    var fmt = color('error title', '  %s) %s:\\n')\n      + color('error message', '     %s')\n      + color('error stack', '\\n%s\\n');\n\n    // msg\n    var msg;\n    var err = test.err;\n    var message;\n    if (err.message && typeof err.message.toString === 'function') {\n      message = err.message + '';\n    } else if (typeof err.inspect === 'function') {\n      message = err.inspect() + '';\n    } else {\n      message = '';\n    }\n    var stack = err.stack || message;\n    var index = message ? stack.indexOf(message) : -1;\n    var actual = err.actual;\n    var expected = err.expected;\n    var escape = true;\n\n    if (index === -1) {\n      msg = message;\n    } else {\n      index += message.length;\n      msg = stack.slice(0, index);\n      // remove msg from stack\n      stack = stack.slice(index + 1);\n    }\n\n    // uncaught\n    if (err.uncaught) {\n      msg = 'Uncaught ' + msg;\n    }\n    // explicitly show diff\n    if (err.showDiff !== false && sameType(actual, expected) && expected !== undefined) {\n      escape = false;\n      if (!(utils.isString(actual) && utils.isString(expected))) {\n        err.actual = actual = utils.stringify(actual);\n        err.expected = expected = utils.stringify(expected);\n      }\n\n      fmt = color('error title', '  %s) %s:\\n%s') + color('error stack', '\\n%s\\n');\n      var match = message.match(/^([^:]+): expected/);\n      msg = '\\n      ' + color('error message', match ? match[1] : msg);\n\n      if (exports.inlineDiffs) {\n        msg += inlineDiff(err, escape);\n      } else {\n        msg += unifiedDiff(err, escape);\n      }\n    }\n\n    // indent stack trace\n    stack = stack.replace(/^/gm, '  ');\n\n    console.log(fmt, (i + 1), test.fullTitle(), msg, stack);\n  });\n};\n\n/**\n * Initialize a new `Base` reporter.\n *\n * All other reporters generally\n * inherit from this reporter, providing\n * stats such as test duration, number\n * of tests passed / failed etc.\n *\n * @param {Runner} runner\n * @api public\n */\n\nfunction Base(runner) {\n  var stats = this.stats = { suites: 0, tests: 0, passes: 0, pending: 0, failures: 0 };\n  var failures = this.failures = [];\n\n  if (!runner) {\n    return;\n  }\n  this.runner = runner;\n\n  runner.stats = stats;\n\n  runner.on('start', function() {\n    stats.start = new Date();\n  });\n\n  runner.on('suite', function(suite) {\n    stats.suites = stats.suites || 0;\n    suite.root || stats.suites++;\n  });\n\n  runner.on('test end', function() {\n    stats.tests = stats.tests || 0;\n    stats.tests++;\n  });\n\n  runner.on('pass', function(test) {\n    stats.passes = stats.passes || 0;\n\n    if (test.duration > test.slow()) {\n      test.speed = 'slow';\n    } else if (test.duration > test.slow() / 2) {\n      test.speed = 'medium';\n    } else {\n      test.speed = 'fast';\n    }\n\n    stats.passes++;\n  });\n\n  runner.on('fail', function(test, err) {\n    stats.failures = stats.failures || 0;\n    stats.failures++;\n    test.err = err;\n    failures.push(test);\n  });\n\n  runner.on('end', function() {\n    stats.end = new Date();\n    stats.duration = new Date() - stats.start;\n  });\n\n  runner.on('pending', function() {\n    stats.pending++;\n  });\n}\n\n/**\n * Output common epilogue used by many of\n * the bundled reporters.\n *\n * @api public\n */\nBase.prototype.epilogue = function() {\n  var stats = this.stats;\n  var fmt;\n\n  console.log();\n\n  // passes\n  fmt = color('bright pass', ' ')\n    + color('green', ' %d passing')\n    + color('light', ' (%s)');\n\n  console.log(fmt,\n    stats.passes || 0,\n    ms(stats.duration));\n\n  // pending\n  if (stats.pending) {\n    fmt = color('pending', ' ')\n      + color('pending', ' %d pending');\n\n    console.log(fmt, stats.pending);\n  }\n\n  // failures\n  if (stats.failures) {\n    fmt = color('fail', '  %d failing');\n\n    console.log(fmt, stats.failures);\n\n    Base.list(this.failures);\n    console.log();\n  }\n\n  console.log();\n};\n\n/**\n * Pad the given `str` to `len`.\n *\n * @api private\n * @param {string} str\n * @param {string} len\n * @return {string}\n */\nfunction pad(str, len) {\n  str = String(str);\n  return Array(len - str.length + 1).join(' ') + str;\n}\n\n/**\n * Returns an inline diff between 2 strings with coloured ANSI output\n *\n * @api private\n * @param {Error} err with actual/expected\n * @param {boolean} escape\n * @return {string} Diff\n */\nfunction inlineDiff(err, escape) {\n  var msg = errorDiff(err, 'WordsWithSpace', escape);\n\n  // linenos\n  var lines = msg.split('\\n');\n  if (lines.length > 4) {\n    var width = String(lines.length).length;\n    msg = lines.map(function(str, i) {\n      return pad(++i, width) + ' |' + ' ' + str;\n    }).join('\\n');\n  }\n\n  // legend\n  msg = '\\n'\n    + color('diff removed', 'actual')\n    + ' '\n    + color('diff added', 'expected')\n    + '\\n\\n'\n    + msg\n    + '\\n';\n\n  // indent\n  msg = msg.replace(/^/gm, '      ');\n  return msg;\n}\n\n/**\n * Returns a unified diff between two strings.\n *\n * @api private\n * @param {Error} err with actual/expected\n * @param {boolean} escape\n * @return {string} The diff.\n */\nfunction unifiedDiff(err, escape) {\n  var indent = '      ';\n  function cleanUp(line) {\n    if (escape) {\n      line = escapeInvisibles(line);\n    }\n    if (line[0] === '+') {\n      return indent + colorLines('diff added', line);\n    }\n    if (line[0] === '-') {\n      return indent + colorLines('diff removed', line);\n    }\n    if (line.match(/\\@\\@/)) {\n      return null;\n    }\n    if (line.match(/\\\\ No newline/)) {\n      return null;\n    }\n    return indent + line;\n  }\n  function notBlank(line) {\n    return typeof line !== 'undefined' && line !== null;\n  }\n  var msg = diff.createPatch('string', err.actual, err.expected);\n  var lines = msg.split('\\n').splice(4);\n  return '\\n      '\n    + colorLines('diff added', '+ expected') + ' '\n    + colorLines('diff removed', '- actual')\n    + '\\n\\n'\n    + lines.map(cleanUp).filter(notBlank).join('\\n');\n}\n\n/**\n * Return a character diff for `err`.\n *\n * @api private\n * @param {Error} err\n * @param {string} type\n * @param {boolean} escape\n * @return {string}\n */\nfunction errorDiff(err, type, escape) {\n  var actual = escape ? escapeInvisibles(err.actual) : err.actual;\n  var expected = escape ? escapeInvisibles(err.expected) : err.expected;\n  return diff['diff' + type](actual, expected).map(function(str) {\n    if (str.added) {\n      return colorLines('diff added', str.value);\n    }\n    if (str.removed) {\n      return colorLines('diff removed', str.value);\n    }\n    return str.value;\n  }).join('');\n}\n\n/**\n * Returns a string with all invisible characters in plain text\n *\n * @api private\n * @param {string} line\n * @return {string}\n */\nfunction escapeInvisibles(line) {\n  return line.replace(/\\t/g, '<tab>')\n    .replace(/\\r/g, '<CR>')\n    .replace(/\\n/g, '<LF>\\n');\n}\n\n/**\n * Color lines for `str`, using the color `name`.\n *\n * @api private\n * @param {string} name\n * @param {string} str\n * @return {string}\n */\nfunction colorLines(name, str) {\n  return str.split('\\n').map(function(str) {\n    return color(name, str);\n  }).join('\\n');\n}\n\n/**\n * Object#toString reference.\n */\nvar objToString = Object.prototype.toString;\n\n/**\n * Check that a / b have the same type.\n *\n * @api private\n * @param {Object} a\n * @param {Object} b\n * @return {boolean}\n */\nfunction sameType(a, b) {\n  return objToString.call(a) === objToString.call(b);\n}\n\n}).call(this,require('_process'),typeof global !== \"undefined\" ? global : typeof self !== \"undefined\" ? self : typeof window !== \"undefined\" ? window : {})\n},{\"../ms\":15,\"../utils\":38,\"_process\":67,\"diff\":46,\"supports-color\":42,\"tty\":5}],18:[function(require,module,exports){\n/**\n * Module dependencies.\n */\n\nvar Base = require('./base');\nvar utils = require('../utils');\n\n/**\n * Expose `Doc`.\n */\n\nexports = module.exports = Doc;\n\n/**\n * Initialize a new `Doc` reporter.\n *\n * @param {Runner} runner\n * @api public\n */\nfunction Doc(runner) {\n  Base.call(this, runner);\n\n  var indents = 2;\n\n  function indent() {\n    return Array(indents).join('  ');\n  }\n\n  runner.on('suite', function(suite) {\n    if (suite.root) {\n      return;\n    }\n    ++indents;\n    console.log('%s<section class=\"suite\">', indent());\n    ++indents;\n    console.log('%s<h1>%s</h1>', indent(), utils.escape(suite.title));\n    console.log('%s<dl>', indent());\n  });\n\n  runner.on('suite end', function(suite) {\n    if (suite.root) {\n      return;\n    }\n    console.log('%s</dl>', indent());\n    --indents;\n    console.log('%s</section>', indent());\n    --indents;\n  });\n\n  runner.on('pass', function(test) {\n    console.log('%s  <dt>%s</dt>', indent(), utils.escape(test.title));\n    var code = utils.escape(utils.clean(test.body));\n    console.log('%s  <dd><pre><code>%s</code></pre></dd>', indent(), code);\n  });\n\n  runner.on('fail', function(test, err) {\n    console.log('%s  <dt class=\"error\">%s</dt>', indent(), utils.escape(test.title));\n    var code = utils.escape(utils.clean(test.body));\n    console.log('%s  <dd class=\"error\"><pre><code>%s</code></pre></dd>', indent(), code);\n    console.log('%s  <dd class=\"error\">%s</dd>', indent(), utils.escape(err));\n  });\n}\n\n},{\"../utils\":38,\"./base\":17}],19:[function(require,module,exports){\n(function (process){\n/**\n * Module dependencies.\n */\n\nvar Base = require('./base');\nvar inherits = require('../utils').inherits;\nvar color = Base.color;\n\n/**\n * Expose `Dot`.\n */\n\nexports = module.exports = Dot;\n\n/**\n * Initialize a new `Dot` matrix test reporter.\n *\n * @api public\n * @param {Runner} runner\n */\nfunction Dot(runner) {\n  Base.call(this, runner);\n\n  var self = this;\n  var width = Base.window.width * .75 | 0;\n  var n = -1;\n\n  runner.on('start', function() {\n    process.stdout.write('\\n');\n  });\n\n  runner.on('pending', function() {\n    if (++n % width === 0) {\n      process.stdout.write('\\n  ');\n    }\n    process.stdout.write(color('pending', Base.symbols.comma));\n  });\n\n  runner.on('pass', function(test) {\n    if (++n % width === 0) {\n      process.stdout.write('\\n  ');\n    }\n    if (test.speed === 'slow') {\n      process.stdout.write(color('bright yellow', Base.symbols.dot));\n    } else {\n      process.stdout.write(color(test.speed, Base.symbols.dot));\n    }\n  });\n\n  runner.on('fail', function() {\n    if (++n % width === 0) {\n      process.stdout.write('\\n  ');\n    }\n    process.stdout.write(color('fail', Base.symbols.bang));\n  });\n\n  runner.on('end', function() {\n    console.log();\n    self.epilogue();\n  });\n}\n\n/**\n * Inherit from `Base.prototype`.\n */\ninherits(Dot, Base);\n\n}).call(this,require('_process'))\n},{\"../utils\":38,\"./base\":17,\"_process\":67}],20:[function(require,module,exports){\n(function (global){\n/* eslint-env browser */\n\n/**\n * Module dependencies.\n */\n\nvar Base = require('./base');\nvar utils = require('../utils');\nvar Progress = require('../browser/progress');\nvar escapeRe = require('escape-string-regexp');\nvar escape = utils.escape;\n\n/**\n * Save timer references to avoid Sinon interfering (see GH-237).\n */\n\n/* eslint-disable no-unused-vars, no-native-reassign */\nvar Date = global.Date;\nvar setTimeout = global.setTimeout;\nvar setInterval = global.setInterval;\nvar clearTimeout = global.clearTimeout;\nvar clearInterval = global.clearInterval;\n/* eslint-enable no-unused-vars, no-native-reassign */\n\n/**\n * Expose `HTML`.\n */\n\nexports = module.exports = HTML;\n\n/**\n * Stats template.\n */\n\nvar statsTemplate = '<ul id=\"mocha-stats\">'\n  + '<li class=\"progress\"><canvas width=\"40\" height=\"40\"></canvas></li>'\n  + '<li class=\"passes\"><a href=\"javascript:void(0);\">passes:</a> <em>0</em></li>'\n  + '<li class=\"failures\"><a href=\"javascript:void(0);\">failures:</a> <em>0</em></li>'\n  + '<li class=\"duration\">duration: <em>0</em>s</li>'\n  + '</ul>';\n\n/**\n * Initialize a new `HTML` reporter.\n *\n * @api public\n * @param {Runner} runner\n */\nfunction HTML(runner) {\n  Base.call(this, runner);\n\n  var self = this;\n  var stats = this.stats;\n  var stat = fragment(statsTemplate);\n  var items = stat.getElementsByTagName('li');\n  var passes = items[1].getElementsByTagName('em')[0];\n  var passesLink = items[1].getElementsByTagName('a')[0];\n  var failures = items[2].getElementsByTagName('em')[0];\n  var failuresLink = items[2].getElementsByTagName('a')[0];\n  var duration = items[3].getElementsByTagName('em')[0];\n  var canvas = stat.getElementsByTagName('canvas')[0];\n  var report = fragment('<ul id=\"mocha-report\"></ul>');\n  var stack = [report];\n  var progress;\n  var ctx;\n  var root = document.getElementById('mocha');\n\n  if (canvas.getContext) {\n    var ratio = window.devicePixelRatio || 1;\n    canvas.style.width = canvas.width;\n    canvas.style.height = canvas.height;\n    canvas.width *= ratio;\n    canvas.height *= ratio;\n    ctx = canvas.getContext('2d');\n    ctx.scale(ratio, ratio);\n    progress = new Progress();\n  }\n\n  if (!root) {\n    return error('#mocha div missing, add it to your document');\n  }\n\n  // pass toggle\n  on(passesLink, 'click', function(evt) {\n    evt.preventDefault();\n    unhide();\n    var name = (/pass/).test(report.className) ? '' : ' pass';\n    report.className = report.className.replace(/fail|pass/g, '') + name;\n    if (report.className.trim()) {\n      hideSuitesWithout('test pass');\n    }\n  });\n\n  // failure toggle\n  on(failuresLink, 'click', function(evt) {\n    evt.preventDefault();\n    unhide();\n    var name = (/fail/).test(report.className) ? '' : ' fail';\n    report.className = report.className.replace(/fail|pass/g, '') + name;\n    if (report.className.trim()) {\n      hideSuitesWithout('test fail');\n    }\n  });\n\n  root.appendChild(stat);\n  root.appendChild(report);\n\n  if (progress) {\n    progress.size(40);\n  }\n\n  runner.on('suite', function(suite) {\n    if (suite.root) {\n      return;\n    }\n\n    // suite\n    var url = self.suiteURL(suite);\n    var el = fragment('<li class=\"suite\"><h1><a href=\"%s\">%s</a></h1></li>', url, escape(suite.title));\n\n    // container\n    stack[0].appendChild(el);\n    stack.unshift(document.createElement('ul'));\n    el.appendChild(stack[0]);\n  });\n\n  runner.on('suite end', function(suite) {\n    if (suite.root) {\n      updateStats();\n      return;\n    }\n    stack.shift();\n  });\n\n  runner.on('pass', function(test) {\n    var url = self.testURL(test);\n    var markup = '<li class=\"test pass %e\"><h2>%e<span class=\"duration\">%ems</span> '\n      + '<a href=\"%s\" class=\"replay\">‣</a></h2></li>';\n    var el = fragment(markup, test.speed, test.title, test.duration, url);\n    self.addCodeToggle(el, test.body);\n    appendToStack(el);\n    updateStats();\n  });\n\n  runner.on('fail', function(test) {\n    var el = fragment('<li class=\"test fail\"><h2>%e <a href=\"%e\" class=\"replay\">‣</a></h2></li>',\n      test.title, self.testURL(test));\n    var stackString; // Note: Includes leading newline\n    var message = test.err.toString();\n\n    // <=IE7 stringifies to [Object Error]. Since it can be overloaded, we\n    // check for the result of the stringifying.\n    if (message === '[object Error]') {\n      message = test.err.message;\n    }\n\n    if (test.err.stack) {\n      var indexOfMessage = test.err.stack.indexOf(test.err.message);\n      if (indexOfMessage === -1) {\n        stackString = test.err.stack;\n      } else {\n        stackString = test.err.stack.substr(test.err.message.length + indexOfMessage);\n      }\n    } else if (test.err.sourceURL && test.err.line !== undefined) {\n      // Safari doesn't give you a stack. Let's at least provide a source line.\n      stackString = '\\n(' + test.err.sourceURL + ':' + test.err.line + ')';\n    }\n\n    stackString = stackString || '';\n\n    if (test.err.htmlMessage && stackString) {\n      el.appendChild(fragment('<div class=\"html-error\">%s\\n<pre class=\"error\">%e</pre></div>',\n        test.err.htmlMessage, stackString));\n    } else if (test.err.htmlMessage) {\n      el.appendChild(fragment('<div class=\"html-error\">%s</div>', test.err.htmlMessage));\n    } else {\n      el.appendChild(fragment('<pre class=\"error\">%e%e</pre>', message, stackString));\n    }\n\n    self.addCodeToggle(el, test.body);\n    appendToStack(el);\n    updateStats();\n  });\n\n  runner.on('pending', function(test) {\n    var el = fragment('<li class=\"test pass pending\"><h2>%e</h2></li>', test.title);\n    appendToStack(el);\n    updateStats();\n  });\n\n  function appendToStack(el) {\n    // Don't call .appendChild if #mocha-report was already .shift()'ed off the stack.\n    if (stack[0]) {\n      stack[0].appendChild(el);\n    }\n  }\n\n  function updateStats() {\n    // TODO: add to stats\n    var percent = stats.tests / runner.total * 100 | 0;\n    if (progress) {\n      progress.update(percent).draw(ctx);\n    }\n\n    // update stats\n    var ms = new Date() - stats.start;\n    text(passes, stats.passes);\n    text(failures, stats.failures);\n    text(duration, (ms / 1000).toFixed(2));\n  }\n}\n\n/**\n * Makes a URL, preserving querystring (\"search\") parameters.\n *\n * @param {string} s\n * @return {string} A new URL.\n */\nfunction makeUrl(s) {\n  var search = window.location.search;\n\n  // Remove previous grep query parameter if present\n  if (search) {\n    search = search.replace(/[?&]grep=[^&\\s]*/g, '').replace(/^&/, '?');\n  }\n\n  return window.location.pathname + (search ? search + '&' : '?') + 'grep=' + encodeURIComponent(escapeRe(s));\n}\n\n/**\n * Provide suite URL.\n *\n * @param {Object} [suite]\n */\nHTML.prototype.suiteURL = function(suite) {\n  return makeUrl(suite.fullTitle());\n};\n\n/**\n * Provide test URL.\n *\n * @param {Object} [test]\n */\nHTML.prototype.testURL = function(test) {\n  return makeUrl(test.fullTitle());\n};\n\n/**\n * Adds code toggle functionality for the provided test's list element.\n *\n * @param {HTMLLIElement} el\n * @param {string} contents\n */\nHTML.prototype.addCodeToggle = function(el, contents) {\n  var h2 = el.getElementsByTagName('h2')[0];\n\n  on(h2, 'click', function() {\n    pre.style.display = pre.style.display === 'none' ? 'block' : 'none';\n  });\n\n  var pre = fragment('<pre><code>%e</code></pre>', utils.clean(contents));\n  el.appendChild(pre);\n  pre.style.display = 'none';\n};\n\n/**\n * Display error `msg`.\n *\n * @param {string} msg\n */\nfunction error(msg) {\n  document.body.appendChild(fragment('<div id=\"mocha-error\">%s</div>', msg));\n}\n\n/**\n * Return a DOM fragment from `html`.\n *\n * @param {string} html\n */\nfunction fragment(html) {\n  var args = arguments;\n  var div = document.createElement('div');\n  var i = 1;\n\n  div.innerHTML = html.replace(/%([se])/g, function(_, type) {\n    switch (type) {\n      case 's': return String(args[i++]);\n      case 'e': return escape(args[i++]);\n      // no default\n    }\n  });\n\n  return div.firstChild;\n}\n\n/**\n * Check for suites that do not have elements\n * with `classname`, and hide them.\n *\n * @param {text} classname\n */\nfunction hideSuitesWithout(classname) {\n  var suites = document.getElementsByClassName('suite');\n  for (var i = 0; i < suites.length; i++) {\n    var els = suites[i].getElementsByClassName(classname);\n    if (!els.length) {\n      suites[i].className += ' hidden';\n    }\n  }\n}\n\n/**\n * Unhide .hidden suites.\n */\nfunction unhide() {\n  var els = document.getElementsByClassName('suite hidden');\n  for (var i = 0; i < els.length; ++i) {\n    els[i].className = els[i].className.replace('suite hidden', 'suite');\n  }\n}\n\n/**\n * Set an element's text contents.\n *\n * @param {HTMLElement} el\n * @param {string} contents\n */\nfunction text(el, contents) {\n  if (el.textContent) {\n    el.textContent = contents;\n  } else {\n    el.innerText = contents;\n  }\n}\n\n/**\n * Listen on `event` with callback `fn`.\n */\nfunction on(el, event, fn) {\n  if (el.addEventListener) {\n    el.addEventListener(event, fn, false);\n  } else {\n    el.attachEvent('on' + event, fn);\n  }\n}\n\n}).call(this,typeof global !== \"undefined\" ? global : typeof self !== \"undefined\" ? self : typeof window !== \"undefined\" ? window : {})\n},{\"../browser/progress\":4,\"../utils\":38,\"./base\":17,\"escape-string-regexp\":47}],21:[function(require,module,exports){\n// Alias exports to a their normalized format Mocha#reporter to prevent a need\n// for dynamic (try/catch) requires, which Browserify doesn't handle.\nexports.Base = exports.base = require('./base');\nexports.Dot = exports.dot = require('./dot');\nexports.Doc = exports.doc = require('./doc');\nexports.TAP = exports.tap = require('./tap');\nexports.JSON = exports.json = require('./json');\nexports.HTML = exports.html = require('./html');\nexports.List = exports.list = require('./list');\nexports.Min = exports.min = require('./min');\nexports.Spec = exports.spec = require('./spec');\nexports.Nyan = exports.nyan = require('./nyan');\nexports.XUnit = exports.xunit = require('./xunit');\nexports.Markdown = exports.markdown = require('./markdown');\nexports.Progress = exports.progress = require('./progress');\nexports.Landing = exports.landing = require('./landing');\nexports.JSONStream = exports['json-stream'] = require('./json-stream');\n\n},{\"./base\":17,\"./doc\":18,\"./dot\":19,\"./html\":20,\"./json\":23,\"./json-stream\":22,\"./landing\":24,\"./list\":25,\"./markdown\":26,\"./min\":27,\"./nyan\":28,\"./progress\":29,\"./spec\":30,\"./tap\":31,\"./xunit\":32}],22:[function(require,module,exports){\n(function (process){\n/**\n * Module dependencies.\n */\n\nvar Base = require('./base');\nvar JSON = require('json3');\n\n/**\n * Expose `List`.\n */\n\nexports = module.exports = List;\n\n/**\n * Initialize a new `List` test reporter.\n *\n * @api public\n * @param {Runner} runner\n */\nfunction List(runner) {\n  Base.call(this, runner);\n\n  var self = this;\n  var total = runner.total;\n\n  runner.on('start', function() {\n    console.log(JSON.stringify(['start', { total: total }]));\n  });\n\n  runner.on('pass', function(test) {\n    console.log(JSON.stringify(['pass', clean(test)]));\n  });\n\n  runner.on('fail', function(test, err) {\n    test = clean(test);\n    test.err = err.message;\n    test.stack = err.stack || null;\n    console.log(JSON.stringify(['fail', test]));\n  });\n\n  runner.on('end', function() {\n    process.stdout.write(JSON.stringify(['end', self.stats]));\n  });\n}\n\n/**\n * Return a plain-object representation of `test`\n * free of cyclic properties etc.\n *\n * @api private\n * @param {Object} test\n * @return {Object}\n */\nfunction clean(test) {\n  return {\n    title: test.title,\n    fullTitle: test.fullTitle(),\n    duration: test.duration,\n    currentRetry: test.currentRetry()\n  };\n}\n\n}).call(this,require('_process'))\n},{\"./base\":17,\"_process\":67,\"json3\":54}],23:[function(require,module,exports){\n(function (process){\n/**\n * Module dependencies.\n */\n\nvar Base = require('./base');\n\n/**\n * Expose `JSON`.\n */\n\nexports = module.exports = JSONReporter;\n\n/**\n * Initialize a new `JSON` reporter.\n *\n * @api public\n * @param {Runner} runner\n */\nfunction JSONReporter(runner) {\n  Base.call(this, runner);\n\n  var self = this;\n  var tests = [];\n  var pending = [];\n  var failures = [];\n  var passes = [];\n\n  runner.on('test end', function(test) {\n    tests.push(test);\n  });\n\n  runner.on('pass', function(test) {\n    passes.push(test);\n  });\n\n  runner.on('fail', function(test) {\n    failures.push(test);\n  });\n\n  runner.on('pending', function(test) {\n    pending.push(test);\n  });\n\n  runner.on('end', function() {\n    var obj = {\n      stats: self.stats,\n      tests: tests.map(clean),\n      pending: pending.map(clean),\n      failures: failures.map(clean),\n      passes: passes.map(clean)\n    };\n\n    runner.testResults = obj;\n\n    process.stdout.write(JSON.stringify(obj, null, 2));\n  });\n}\n\n/**\n * Return a plain-object representation of `test`\n * free of cyclic properties etc.\n *\n * @api private\n * @param {Object} test\n * @return {Object}\n */\nfunction clean(test) {\n  return {\n    title: test.title,\n    fullTitle: test.fullTitle(),\n    duration: test.duration,\n    currentRetry: test.currentRetry(),\n    err: errorJSON(test.err || {})\n  };\n}\n\n/**\n * Transform `error` into a JSON object.\n *\n * @api private\n * @param {Error} err\n * @return {Object}\n */\nfunction errorJSON(err) {\n  var res = {};\n  Object.getOwnPropertyNames(err).forEach(function(key) {\n    res[key] = err[key];\n  }, err);\n  return res;\n}\n\n}).call(this,require('_process'))\n},{\"./base\":17,\"_process\":67}],24:[function(require,module,exports){\n(function (process){\n/**\n * Module dependencies.\n */\n\nvar Base = require('./base');\nvar inherits = require('../utils').inherits;\nvar cursor = Base.cursor;\nvar color = Base.color;\n\n/**\n * Expose `Landing`.\n */\n\nexports = module.exports = Landing;\n\n/**\n * Airplane color.\n */\n\nBase.colors.plane = 0;\n\n/**\n * Airplane crash color.\n */\n\nBase.colors['plane crash'] = 31;\n\n/**\n * Runway color.\n */\n\nBase.colors.runway = 90;\n\n/**\n * Initialize a new `Landing` reporter.\n *\n * @api public\n * @param {Runner} runner\n */\nfunction Landing(runner) {\n  Base.call(this, runner);\n\n  var self = this;\n  var width = Base.window.width * .75 | 0;\n  var total = runner.total;\n  var stream = process.stdout;\n  var plane = color('plane', '✈');\n  var crashed = -1;\n  var n = 0;\n\n  function runway() {\n    var buf = Array(width).join('-');\n    return '  ' + color('runway', buf);\n  }\n\n  runner.on('start', function() {\n    stream.write('\\n\\n\\n  ');\n    cursor.hide();\n  });\n\n  runner.on('test end', function(test) {\n    // check if the plane crashed\n    var col = crashed === -1 ? width * ++n / total | 0 : crashed;\n\n    // show the crash\n    if (test.state === 'failed') {\n      plane = color('plane crash', '✈');\n      crashed = col;\n    }\n\n    // render landing strip\n    stream.write('\\u001b[' + (width + 1) + 'D\\u001b[2A');\n    stream.write(runway());\n    stream.write('\\n  ');\n    stream.write(color('runway', Array(col).join('⋅')));\n    stream.write(plane);\n    stream.write(color('runway', Array(width - col).join('⋅') + '\\n'));\n    stream.write(runway());\n    stream.write('\\u001b[0m');\n  });\n\n  runner.on('end', function() {\n    cursor.show();\n    console.log();\n    self.epilogue();\n  });\n}\n\n/**\n * Inherit from `Base.prototype`.\n */\ninherits(Landing, Base);\n\n}).call(this,require('_process'))\n},{\"../utils\":38,\"./base\":17,\"_process\":67}],25:[function(require,module,exports){\n(function (process){\n/**\n * Module dependencies.\n */\n\nvar Base = require('./base');\nvar inherits = require('../utils').inherits;\nvar color = Base.color;\nvar cursor = Base.cursor;\n\n/**\n * Expose `List`.\n */\n\nexports = module.exports = List;\n\n/**\n * Initialize a new `List` test reporter.\n *\n * @api public\n * @param {Runner} runner\n */\nfunction List(runner) {\n  Base.call(this, runner);\n\n  var self = this;\n  var n = 0;\n\n  runner.on('start', function() {\n    console.log();\n  });\n\n  runner.on('test', function(test) {\n    process.stdout.write(color('pass', '    ' + test.fullTitle() + ': '));\n  });\n\n  runner.on('pending', function(test) {\n    var fmt = color('checkmark', '  -')\n      + color('pending', ' %s');\n    console.log(fmt, test.fullTitle());\n  });\n\n  runner.on('pass', function(test) {\n    var fmt = color('checkmark', '  ' + Base.symbols.dot)\n      + color('pass', ' %s: ')\n      + color(test.speed, '%dms');\n    cursor.CR();\n    console.log(fmt, test.fullTitle(), test.duration);\n  });\n\n  runner.on('fail', function(test) {\n    cursor.CR();\n    console.log(color('fail', '  %d) %s'), ++n, test.fullTitle());\n  });\n\n  runner.on('end', self.epilogue.bind(self));\n}\n\n/**\n * Inherit from `Base.prototype`.\n */\ninherits(List, Base);\n\n}).call(this,require('_process'))\n},{\"../utils\":38,\"./base\":17,\"_process\":67}],26:[function(require,module,exports){\n(function (process){\n/**\n * Module dependencies.\n */\n\nvar Base = require('./base');\nvar utils = require('../utils');\n\n/**\n * Constants\n */\n\nvar SUITE_PREFIX = '$';\n\n/**\n * Expose `Markdown`.\n */\n\nexports = module.exports = Markdown;\n\n/**\n * Initialize a new `Markdown` reporter.\n *\n * @api public\n * @param {Runner} runner\n */\nfunction Markdown(runner) {\n  Base.call(this, runner);\n\n  var level = 0;\n  var buf = '';\n\n  function title(str) {\n    return Array(level).join('#') + ' ' + str;\n  }\n\n  function mapTOC(suite, obj) {\n    var ret = obj;\n    var key = SUITE_PREFIX + suite.title;\n\n    obj = obj[key] = obj[key] || { suite: suite };\n    suite.suites.forEach(function(suite) {\n      mapTOC(suite, obj);\n    });\n\n    return ret;\n  }\n\n  function stringifyTOC(obj, level) {\n    ++level;\n    var buf = '';\n    var link;\n    for (var key in obj) {\n      if (key === 'suite') {\n        continue;\n      }\n      if (key !== SUITE_PREFIX) {\n        link = ' - [' + key.substring(1) + ']';\n        link += '(#' + utils.slug(obj[key].suite.fullTitle()) + ')\\n';\n        buf += Array(level).join('  ') + link;\n      }\n      buf += stringifyTOC(obj[key], level);\n    }\n    return buf;\n  }\n\n  function generateTOC(suite) {\n    var obj = mapTOC(suite, {});\n    return stringifyTOC(obj, 0);\n  }\n\n  generateTOC(runner.suite);\n\n  runner.on('suite', function(suite) {\n    ++level;\n    var slug = utils.slug(suite.fullTitle());\n    buf += '<a name=\"' + slug + '\"></a>' + '\\n';\n    buf += title(suite.title) + '\\n';\n  });\n\n  runner.on('suite end', function() {\n    --level;\n  });\n\n  runner.on('pass', function(test) {\n    var code = utils.clean(test.body);\n    buf += test.title + '.\\n';\n    buf += '\\n```js\\n';\n    buf += code + '\\n';\n    buf += '```\\n\\n';\n  });\n\n  runner.on('end', function() {\n    process.stdout.write('# TOC\\n');\n    process.stdout.write(generateTOC(runner.suite));\n    process.stdout.write(buf);\n  });\n}\n\n}).call(this,require('_process'))\n},{\"../utils\":38,\"./base\":17,\"_process\":67}],27:[function(require,module,exports){\n(function (process){\n/**\n * Module dependencies.\n */\n\nvar Base = require('./base');\nvar inherits = require('../utils').inherits;\n\n/**\n * Expose `Min`.\n */\n\nexports = module.exports = Min;\n\n/**\n * Initialize a new `Min` minimal test reporter (best used with --watch).\n *\n * @api public\n * @param {Runner} runner\n */\nfunction Min(runner) {\n  Base.call(this, runner);\n\n  runner.on('start', function() {\n    // clear screen\n    process.stdout.write('\\u001b[2J');\n    // set cursor position\n    process.stdout.write('\\u001b[1;3H');\n  });\n\n  runner.on('end', this.epilogue.bind(this));\n}\n\n/**\n * Inherit from `Base.prototype`.\n */\ninherits(Min, Base);\n\n}).call(this,require('_process'))\n},{\"../utils\":38,\"./base\":17,\"_process\":67}],28:[function(require,module,exports){\n(function (process){\n/**\n * Module dependencies.\n */\n\nvar Base = require('./base');\nvar inherits = require('../utils').inherits;\n\n/**\n * Expose `Dot`.\n */\n\nexports = module.exports = NyanCat;\n\n/**\n * Initialize a new `Dot` matrix test reporter.\n *\n * @param {Runner} runner\n * @api public\n */\n\nfunction NyanCat(runner) {\n  Base.call(this, runner);\n\n  var self = this;\n  var width = Base.window.width * .75 | 0;\n  var nyanCatWidth = this.nyanCatWidth = 11;\n\n  this.colorIndex = 0;\n  this.numberOfLines = 4;\n  this.rainbowColors = self.generateColors();\n  this.scoreboardWidth = 5;\n  this.tick = 0;\n  this.trajectories = [[], [], [], []];\n  this.trajectoryWidthMax = (width - nyanCatWidth);\n\n  runner.on('start', function() {\n    Base.cursor.hide();\n    self.draw();\n  });\n\n  runner.on('pending', function() {\n    self.draw();\n  });\n\n  runner.on('pass', function() {\n    self.draw();\n  });\n\n  runner.on('fail', function() {\n    self.draw();\n  });\n\n  runner.on('end', function() {\n    Base.cursor.show();\n    for (var i = 0; i < self.numberOfLines; i++) {\n      write('\\n');\n    }\n    self.epilogue();\n  });\n}\n\n/**\n * Inherit from `Base.prototype`.\n */\ninherits(NyanCat, Base);\n\n/**\n * Draw the nyan cat\n *\n * @api private\n */\n\nNyanCat.prototype.draw = function() {\n  this.appendRainbow();\n  this.drawScoreboard();\n  this.drawRainbow();\n  this.drawNyanCat();\n  this.tick = !this.tick;\n};\n\n/**\n * Draw the \"scoreboard\" showing the number\n * of passes, failures and pending tests.\n *\n * @api private\n */\n\nNyanCat.prototype.drawScoreboard = function() {\n  var stats = this.stats;\n\n  function draw(type, n) {\n    write(' ');\n    write(Base.color(type, n));\n    write('\\n');\n  }\n\n  draw('green', stats.passes);\n  draw('fail', stats.failures);\n  draw('pending', stats.pending);\n  write('\\n');\n\n  this.cursorUp(this.numberOfLines);\n};\n\n/**\n * Append the rainbow.\n *\n * @api private\n */\n\nNyanCat.prototype.appendRainbow = function() {\n  var segment = this.tick ? '_' : '-';\n  var rainbowified = this.rainbowify(segment);\n\n  for (var index = 0; index < this.numberOfLines; index++) {\n    var trajectory = this.trajectories[index];\n    if (trajectory.length >= this.trajectoryWidthMax) {\n      trajectory.shift();\n    }\n    trajectory.push(rainbowified);\n  }\n};\n\n/**\n * Draw the rainbow.\n *\n * @api private\n */\n\nNyanCat.prototype.drawRainbow = function() {\n  var self = this;\n\n  this.trajectories.forEach(function(line) {\n    write('\\u001b[' + self.scoreboardWidth + 'C');\n    write(line.join(''));\n    write('\\n');\n  });\n\n  this.cursorUp(this.numberOfLines);\n};\n\n/**\n * Draw the nyan cat\n *\n * @api private\n */\nNyanCat.prototype.drawNyanCat = function() {\n  var self = this;\n  var startWidth = this.scoreboardWidth + this.trajectories[0].length;\n  var dist = '\\u001b[' + startWidth + 'C';\n  var padding = '';\n\n  write(dist);\n  write('_,------,');\n  write('\\n');\n\n  write(dist);\n  padding = self.tick ? '  ' : '   ';\n  write('_|' + padding + '/\\\\_/\\\\ ');\n  write('\\n');\n\n  write(dist);\n  padding = self.tick ? '_' : '__';\n  var tail = self.tick ? '~' : '^';\n  write(tail + '|' + padding + this.face() + ' ');\n  write('\\n');\n\n  write(dist);\n  padding = self.tick ? ' ' : '  ';\n  write(padding + '\"\"  \"\" ');\n  write('\\n');\n\n  this.cursorUp(this.numberOfLines);\n};\n\n/**\n * Draw nyan cat face.\n *\n * @api private\n * @return {string}\n */\n\nNyanCat.prototype.face = function() {\n  var stats = this.stats;\n  if (stats.failures) {\n    return '( x .x)';\n  } else if (stats.pending) {\n    return '( o .o)';\n  } else if (stats.passes) {\n    return '( ^ .^)';\n  }\n  return '( - .-)';\n};\n\n/**\n * Move cursor up `n`.\n *\n * @api private\n * @param {number} n\n */\n\nNyanCat.prototype.cursorUp = function(n) {\n  write('\\u001b[' + n + 'A');\n};\n\n/**\n * Move cursor down `n`.\n *\n * @api private\n * @param {number} n\n */\n\nNyanCat.prototype.cursorDown = function(n) {\n  write('\\u001b[' + n + 'B');\n};\n\n/**\n * Generate rainbow colors.\n *\n * @api private\n * @return {Array}\n */\nNyanCat.prototype.generateColors = function() {\n  var colors = [];\n\n  for (var i = 0; i < (6 * 7); i++) {\n    var pi3 = Math.floor(Math.PI / 3);\n    var n = (i * (1.0 / 6));\n    var r = Math.floor(3 * Math.sin(n) + 3);\n    var g = Math.floor(3 * Math.sin(n + 2 * pi3) + 3);\n    var b = Math.floor(3 * Math.sin(n + 4 * pi3) + 3);\n    colors.push(36 * r + 6 * g + b + 16);\n  }\n\n  return colors;\n};\n\n/**\n * Apply rainbow to the given `str`.\n *\n * @api private\n * @param {string} str\n * @return {string}\n */\nNyanCat.prototype.rainbowify = function(str) {\n  if (!Base.useColors) {\n    return str;\n  }\n  var color = this.rainbowColors[this.colorIndex % this.rainbowColors.length];\n  this.colorIndex += 1;\n  return '\\u001b[38;5;' + color + 'm' + str + '\\u001b[0m';\n};\n\n/**\n * Stdout helper.\n *\n * @param {string} string A message to write to stdout.\n */\nfunction write(string) {\n  process.stdout.write(string);\n}\n\n}).call(this,require('_process'))\n},{\"../utils\":38,\"./base\":17,\"_process\":67}],29:[function(require,module,exports){\n(function (process){\n/**\n * Module dependencies.\n */\n\nvar Base = require('./base');\nvar inherits = require('../utils').inherits;\nvar color = Base.color;\nvar cursor = Base.cursor;\n\n/**\n * Expose `Progress`.\n */\n\nexports = module.exports = Progress;\n\n/**\n * General progress bar color.\n */\n\nBase.colors.progress = 90;\n\n/**\n * Initialize a new `Progress` bar test reporter.\n *\n * @api public\n * @param {Runner} runner\n * @param {Object} options\n */\nfunction Progress(runner, options) {\n  Base.call(this, runner);\n\n  var self = this;\n  var width = Base.window.width * .50 | 0;\n  var total = runner.total;\n  var complete = 0;\n  var lastN = -1;\n\n  // default chars\n  options = options || {};\n  options.open = options.open || '[';\n  options.complete = options.complete || '▬';\n  options.incomplete = options.incomplete || Base.symbols.dot;\n  options.close = options.close || ']';\n  options.verbose = false;\n\n  // tests started\n  runner.on('start', function() {\n    console.log();\n    cursor.hide();\n  });\n\n  // tests complete\n  runner.on('test end', function() {\n    complete++;\n\n    var percent = complete / total;\n    var n = width * percent | 0;\n    var i = width - n;\n\n    if (n === lastN && !options.verbose) {\n      // Don't re-render the line if it hasn't changed\n      return;\n    }\n    lastN = n;\n\n    cursor.CR();\n    process.stdout.write('\\u001b[J');\n    process.stdout.write(color('progress', '  ' + options.open));\n    process.stdout.write(Array(n).join(options.complete));\n    process.stdout.write(Array(i).join(options.incomplete));\n    process.stdout.write(color('progress', options.close));\n    if (options.verbose) {\n      process.stdout.write(color('progress', ' ' + complete + ' of ' + total));\n    }\n  });\n\n  // tests are complete, output some stats\n  // and the failures if any\n  runner.on('end', function() {\n    cursor.show();\n    console.log();\n    self.epilogue();\n  });\n}\n\n/**\n * Inherit from `Base.prototype`.\n */\ninherits(Progress, Base);\n\n}).call(this,require('_process'))\n},{\"../utils\":38,\"./base\":17,\"_process\":67}],30:[function(require,module,exports){\n/**\n * Module dependencies.\n */\n\nvar Base = require('./base');\nvar inherits = require('../utils').inherits;\nvar color = Base.color;\n\n/**\n * Expose `Spec`.\n */\n\nexports = module.exports = Spec;\n\n/**\n * Initialize a new `Spec` test reporter.\n *\n * @api public\n * @param {Runner} runner\n */\nfunction Spec(runner) {\n  Base.call(this, runner);\n\n  var self = this;\n  var indents = 0;\n  var n = 0;\n\n  function indent() {\n    return Array(indents).join('  ');\n  }\n\n  runner.on('start', function() {\n    console.log();\n  });\n\n  runner.on('suite', function(suite) {\n    ++indents;\n    console.log(color('suite', '%s%s'), indent(), suite.title);\n  });\n\n  runner.on('suite end', function() {\n    --indents;\n    if (indents === 1) {\n      console.log();\n    }\n  });\n\n  runner.on('pending', function(test) {\n    var fmt = indent() + color('pending', '  - %s');\n    console.log(fmt, test.title);\n  });\n\n  runner.on('pass', function(test) {\n    var fmt;\n    if (test.speed === 'fast') {\n      fmt = indent()\n        + color('checkmark', '  ' + Base.symbols.ok)\n        + color('pass', ' %s');\n      console.log(fmt, test.title);\n    } else {\n      fmt = indent()\n        + color('checkmark', '  ' + Base.symbols.ok)\n        + color('pass', ' %s')\n        + color(test.speed, ' (%dms)');\n      console.log(fmt, test.title, test.duration);\n    }\n  });\n\n  runner.on('fail', function(test) {\n    console.log(indent() + color('fail', '  %d) %s'), ++n, test.title);\n  });\n\n  runner.on('end', self.epilogue.bind(self));\n}\n\n/**\n * Inherit from `Base.prototype`.\n */\ninherits(Spec, Base);\n\n},{\"../utils\":38,\"./base\":17}],31:[function(require,module,exports){\n/**\n * Module dependencies.\n */\n\nvar Base = require('./base');\n\n/**\n * Expose `TAP`.\n */\n\nexports = module.exports = TAP;\n\n/**\n * Initialize a new `TAP` reporter.\n *\n * @api public\n * @param {Runner} runner\n */\nfunction TAP(runner) {\n  Base.call(this, runner);\n\n  var n = 1;\n  var passes = 0;\n  var failures = 0;\n\n  runner.on('start', function() {\n    var total = runner.grepTotal(runner.suite);\n    console.log('%d..%d', 1, total);\n  });\n\n  runner.on('test end', function() {\n    ++n;\n  });\n\n  runner.on('pending', function(test) {\n    console.log('ok %d %s # SKIP -', n, title(test));\n  });\n\n  runner.on('pass', function(test) {\n    passes++;\n    console.log('ok %d %s', n, title(test));\n  });\n\n  runner.on('fail', function(test, err) {\n    failures++;\n    console.log('not ok %d %s', n, title(test));\n    if (err.stack) {\n      console.log(err.stack.replace(/^/gm, '  '));\n    }\n  });\n\n  runner.on('end', function() {\n    console.log('# tests ' + (passes + failures));\n    console.log('# pass ' + passes);\n    console.log('# fail ' + failures);\n  });\n}\n\n/**\n * Return a TAP-safe title of `test`\n *\n * @api private\n * @param {Object} test\n * @return {String}\n */\nfunction title(test) {\n  return test.fullTitle().replace(/#/g, '');\n}\n\n},{\"./base\":17}],32:[function(require,module,exports){\n(function (process,global){\n/**\n * Module dependencies.\n */\n\nvar Base = require('./base');\nvar utils = require('../utils');\nvar inherits = utils.inherits;\nvar fs = require('fs');\nvar escape = utils.escape;\nvar mkdirp = require('mkdirp');\nvar path = require('path');\n\n/**\n * Save timer references to avoid Sinon interfering (see GH-237).\n */\n\n/* eslint-disable no-unused-vars, no-native-reassign */\nvar Date = global.Date;\nvar setTimeout = global.setTimeout;\nvar setInterval = global.setInterval;\nvar clearTimeout = global.clearTimeout;\nvar clearInterval = global.clearInterval;\n/* eslint-enable no-unused-vars, no-native-reassign */\n\n/**\n * Expose `XUnit`.\n */\n\nexports = module.exports = XUnit;\n\n/**\n * Initialize a new `XUnit` reporter.\n *\n * @api public\n * @param {Runner} runner\n */\nfunction XUnit(runner, options) {\n  Base.call(this, runner);\n\n  var stats = this.stats;\n  var tests = [];\n  var self = this;\n\n  if (options.reporterOptions && options.reporterOptions.output) {\n    if (!fs.createWriteStream) {\n      throw new Error('file output not supported in browser');\n    }\n    mkdirp.sync(path.dirname(options.reporterOptions.output));\n    self.fileStream = fs.createWriteStream(options.reporterOptions.output);\n  }\n\n  runner.on('pending', function(test) {\n    tests.push(test);\n  });\n\n  runner.on('pass', function(test) {\n    tests.push(test);\n  });\n\n  runner.on('fail', function(test) {\n    tests.push(test);\n  });\n\n  runner.on('end', function() {\n    self.write(tag('testsuite', {\n      name: 'Mocha Tests',\n      tests: stats.tests,\n      failures: stats.failures,\n      errors: stats.failures,\n      skipped: stats.tests - stats.failures - stats.passes,\n      timestamp: (new Date()).toUTCString(),\n      time: (stats.duration / 1000) || 0\n    }, false));\n\n    tests.forEach(function(t) {\n      self.test(t);\n    });\n\n    self.write('</testsuite>');\n  });\n}\n\n/**\n * Inherit from `Base.prototype`.\n */\ninherits(XUnit, Base);\n\n/**\n * Override done to close the stream (if it's a file).\n *\n * @param failures\n * @param {Function} fn\n */\nXUnit.prototype.done = function(failures, fn) {\n  if (this.fileStream) {\n    this.fileStream.end(function() {\n      fn(failures);\n    });\n  } else {\n    fn(failures);\n  }\n};\n\n/**\n * Write out the given line.\n *\n * @param {string} line\n */\nXUnit.prototype.write = function(line) {\n  if (this.fileStream) {\n    this.fileStream.write(line + '\\n');\n  } else if (typeof process === 'object' && process.stdout) {\n    process.stdout.write(line + '\\n');\n  } else {\n    console.log(line);\n  }\n};\n\n/**\n * Output tag for the given `test.`\n *\n * @param {Test} test\n */\nXUnit.prototype.test = function(test) {\n  var attrs = {\n    classname: test.parent.fullTitle(),\n    name: test.title,\n    time: (test.duration / 1000) || 0\n  };\n\n  if (test.state === 'failed') {\n    var err = test.err;\n    this.write(tag('testcase', attrs, false, tag('failure', {}, false, escape(err.message) + '\\n' + escape(err.stack))));\n  } else if (test.isPending()) {\n    this.write(tag('testcase', attrs, false, tag('skipped', {}, true)));\n  } else {\n    this.write(tag('testcase', attrs, true));\n  }\n};\n\n/**\n * HTML tag helper.\n *\n * @param name\n * @param attrs\n * @param close\n * @param content\n * @return {string}\n */\nfunction tag(name, attrs, close, content) {\n  var end = close ? '/>' : '>';\n  var pairs = [];\n  var tag;\n\n  for (var key in attrs) {\n    if (Object.prototype.hasOwnProperty.call(attrs, key)) {\n      pairs.push(key + '=\"' + escape(attrs[key]) + '\"');\n    }\n  }\n\n  tag = '<' + name + (pairs.length ? ' ' + pairs.join(' ') : '') + end;\n  if (content) {\n    tag += content + '</' + name + end;\n  }\n  return tag;\n}\n\n}).call(this,require('_process'),typeof global !== \"undefined\" ? global : typeof self !== \"undefined\" ? self : typeof window !== \"undefined\" ? window : {})\n},{\"../utils\":38,\"./base\":17,\"_process\":67,\"fs\":42,\"mkdirp\":64,\"path\":42}],33:[function(require,module,exports){\n(function (global){\n/**\n * Module dependencies.\n */\n\nvar EventEmitter = require('events').EventEmitter;\nvar JSON = require('json3');\nvar Pending = require('./pending');\nvar debug = require('debug')('mocha:runnable');\nvar milliseconds = require('./ms');\nvar utils = require('./utils');\nvar create = require('lodash.create');\n\n/**\n * Save timer references to avoid Sinon interfering (see GH-237).\n */\n\n/* eslint-disable no-unused-vars, no-native-reassign */\nvar Date = global.Date;\nvar setTimeout = global.setTimeout;\nvar setInterval = global.setInterval;\nvar clearTimeout = global.clearTimeout;\nvar clearInterval = global.clearInterval;\n/* eslint-enable no-unused-vars, no-native-reassign */\n\n/**\n * Object#toString().\n */\n\nvar toString = Object.prototype.toString;\n\n/**\n * Expose `Runnable`.\n */\n\nmodule.exports = Runnable;\n\n/**\n * Initialize a new `Runnable` with the given `title` and callback `fn`.\n *\n * @param {String} title\n * @param {Function} fn\n * @api private\n * @param {string} title\n * @param {Function} fn\n */\nfunction Runnable(title, fn) {\n  this.title = title;\n  this.fn = fn;\n  this.body = (fn || '').toString();\n  this.async = fn && fn.length;\n  this.sync = !this.async;\n  this._timeout = 2000;\n  this._slow = 75;\n  this._enableTimeouts = true;\n  this.timedOut = false;\n  this._trace = new Error('done() called multiple times');\n  this._retries = -1;\n  this._currentRetry = 0;\n  this.pending = false;\n}\n\n/**\n * Inherit from `EventEmitter.prototype`.\n */\nRunnable.prototype = create(EventEmitter.prototype, {\n  constructor: Runnable\n});\n\n/**\n * Set & get timeout `ms`.\n *\n * @api private\n * @param {number|string} ms\n * @return {Runnable|number} ms or Runnable instance.\n */\nRunnable.prototype.timeout = function(ms) {\n  if (!arguments.length) {\n    return this._timeout;\n  }\n  // see #1652 for reasoning\n  if (ms === 0 || ms > Math.pow(2, 31)) {\n    this._enableTimeouts = false;\n  }\n  if (typeof ms === 'string') {\n    ms = milliseconds(ms);\n  }\n  debug('timeout %d', ms);\n  this._timeout = ms;\n  if (this.timer) {\n    this.resetTimeout();\n  }\n  return this;\n};\n\n/**\n * Set & get slow `ms`.\n *\n * @api private\n * @param {number|string} ms\n * @return {Runnable|number} ms or Runnable instance.\n */\nRunnable.prototype.slow = function(ms) {\n  if (typeof ms === 'undefined') {\n    return this._slow;\n  }\n  if (typeof ms === 'string') {\n    ms = milliseconds(ms);\n  }\n  debug('timeout %d', ms);\n  this._slow = ms;\n  return this;\n};\n\n/**\n * Set and get whether timeout is `enabled`.\n *\n * @api private\n * @param {boolean} enabled\n * @return {Runnable|boolean} enabled or Runnable instance.\n */\nRunnable.prototype.enableTimeouts = function(enabled) {\n  if (!arguments.length) {\n    return this._enableTimeouts;\n  }\n  debug('enableTimeouts %s', enabled);\n  this._enableTimeouts = enabled;\n  return this;\n};\n\n/**\n * Halt and mark as pending.\n *\n * @api public\n */\nRunnable.prototype.skip = function() {\n  throw new Pending('sync skip');\n};\n\n/**\n * Check if this runnable or its parent suite is marked as pending.\n *\n * @api private\n */\nRunnable.prototype.isPending = function() {\n  return this.pending || (this.parent && this.parent.isPending());\n};\n\n/**\n * Set number of retries.\n *\n * @api private\n */\nRunnable.prototype.retries = function(n) {\n  if (!arguments.length) {\n    return this._retries;\n  }\n  this._retries = n;\n};\n\n/**\n * Get current retry\n *\n * @api private\n */\nRunnable.prototype.currentRetry = function(n) {\n  if (!arguments.length) {\n    return this._currentRetry;\n  }\n  this._currentRetry = n;\n};\n\n/**\n * Return the full title generated by recursively concatenating the parent's\n * full title.\n *\n * @api public\n * @return {string}\n */\nRunnable.prototype.fullTitle = function() {\n  return this.parent.fullTitle() + ' ' + this.title;\n};\n\n/**\n * Clear the timeout.\n *\n * @api private\n */\nRunnable.prototype.clearTimeout = function() {\n  clearTimeout(this.timer);\n};\n\n/**\n * Inspect the runnable void of private properties.\n *\n * @api private\n * @return {string}\n */\nRunnable.prototype.inspect = function() {\n  return JSON.stringify(this, function(key, val) {\n    if (key[0] === '_') {\n      return;\n    }\n    if (key === 'parent') {\n      return '#<Suite>';\n    }\n    if (key === 'ctx') {\n      return '#<Context>';\n    }\n    return val;\n  }, 2);\n};\n\n/**\n * Reset the timeout.\n *\n * @api private\n */\nRunnable.prototype.resetTimeout = function() {\n  var self = this;\n  var ms = this.timeout() || 1e9;\n\n  if (!this._enableTimeouts) {\n    return;\n  }\n  this.clearTimeout();\n  this.timer = setTimeout(function() {\n    if (!self._enableTimeouts) {\n      return;\n    }\n    self.callback(new Error('timeout of ' + ms + 'ms exceeded. Ensure the done() callback is being called in this test.'));\n    self.timedOut = true;\n  }, ms);\n};\n\n/**\n * Whitelist a list of globals for this test run.\n *\n * @api private\n * @param {string[]} globals\n */\nRunnable.prototype.globals = function(globals) {\n  if (!arguments.length) {\n    return this._allowedGlobals;\n  }\n  this._allowedGlobals = globals;\n};\n\n/**\n * Run the test and invoke `fn(err)`.\n *\n * @param {Function} fn\n * @api private\n */\nRunnable.prototype.run = function(fn) {\n  var self = this;\n  var start = new Date();\n  var ctx = this.ctx;\n  var finished;\n  var emitted;\n\n  // Sometimes the ctx exists, but it is not runnable\n  if (ctx && ctx.runnable) {\n    ctx.runnable(this);\n  }\n\n  // called multiple times\n  function multiple(err) {\n    if (emitted) {\n      return;\n    }\n    emitted = true;\n    self.emit('error', err || new Error('done() called multiple times; stacktrace may be inaccurate'));\n  }\n\n  // finished\n  function done(err) {\n    var ms = self.timeout();\n    if (self.timedOut) {\n      return;\n    }\n    if (finished) {\n      return multiple(err || self._trace);\n    }\n\n    self.clearTimeout();\n    self.duration = new Date() - start;\n    finished = true;\n    if (!err && self.duration > ms && self._enableTimeouts) {\n      err = new Error('timeout of ' + ms + 'ms exceeded. Ensure the done() callback is being called in this test.');\n    }\n    fn(err);\n  }\n\n  // for .resetTimeout()\n  this.callback = done;\n\n  // explicit async with `done` argument\n  if (this.async) {\n    this.resetTimeout();\n\n    // allows skip() to be used in an explicit async context\n    this.skip = function asyncSkip() {\n      done(new Pending('async skip call'));\n      // halt execution.  the Runnable will be marked pending\n      // by the previous call, and the uncaught handler will ignore\n      // the failure.\n      throw new Pending('async skip; aborting execution');\n    };\n\n    if (this.allowUncaught) {\n      return callFnAsync(this.fn);\n    }\n    try {\n      callFnAsync(this.fn);\n    } catch (err) {\n      done(utils.getError(err));\n    }\n    return;\n  }\n\n  if (this.allowUncaught) {\n    callFn(this.fn);\n    done();\n    return;\n  }\n\n  // sync or promise-returning\n  try {\n    if (this.isPending()) {\n      done();\n    } else {\n      callFn(this.fn);\n    }\n  } catch (err) {\n    done(utils.getError(err));\n  }\n\n  function callFn(fn) {\n    var result = fn.call(ctx);\n    if (result && typeof result.then === 'function') {\n      self.resetTimeout();\n      result\n        .then(function() {\n          done();\n          // Return null so libraries like bluebird do not warn about\n          // subsequently constructed Promises.\n          return null;\n        },\n        function(reason) {\n          done(reason || new Error('Promise rejected with no or falsy reason'));\n        });\n    } else {\n      if (self.asyncOnly) {\n        return done(new Error('--async-only option in use without declaring `done()` or returning a promise'));\n      }\n\n      done();\n    }\n  }\n\n  function callFnAsync(fn) {\n    var result = fn.call(ctx, function(err) {\n      if (err instanceof Error || toString.call(err) === '[object Error]') {\n        return done(err);\n      }\n      if (err) {\n        if (Object.prototype.toString.call(err) === '[object Object]') {\n          return done(new Error('done() invoked with non-Error: '\n            + JSON.stringify(err)));\n        }\n        return done(new Error('done() invoked with non-Error: ' + err));\n      }\n      if (result && utils.isPromise(result)) {\n        return done(new Error('Resolution method is overspecified. Specify a callback *or* return a Promise; not both.'));\n      }\n\n      done();\n    });\n  }\n};\n\n}).call(this,typeof global !== \"undefined\" ? global : typeof self !== \"undefined\" ? self : typeof window !== \"undefined\" ? window : {})\n},{\"./ms\":15,\"./pending\":16,\"./utils\":38,\"debug\":2,\"events\":3,\"json3\":54,\"lodash.create\":60}],34:[function(require,module,exports){\n(function (process,global){\n/**\n * Module dependencies.\n */\n\nvar EventEmitter = require('events').EventEmitter;\nvar Pending = require('./pending');\nvar utils = require('./utils');\nvar inherits = utils.inherits;\nvar debug = require('debug')('mocha:runner');\nvar Runnable = require('./runnable');\nvar filter = utils.filter;\nvar indexOf = utils.indexOf;\nvar some = utils.some;\nvar keys = utils.keys;\nvar stackFilter = utils.stackTraceFilter();\nvar stringify = utils.stringify;\nvar type = utils.type;\nvar undefinedError = utils.undefinedError;\nvar isArray = utils.isArray;\n\n/**\n * Non-enumerable globals.\n */\n\nvar globals = [\n  'setTimeout',\n  'clearTimeout',\n  'setInterval',\n  'clearInterval',\n  'XMLHttpRequest',\n  'Date',\n  'setImmediate',\n  'clearImmediate'\n];\n\n/**\n * Expose `Runner`.\n */\n\nmodule.exports = Runner;\n\n/**\n * Initialize a `Runner` for the given `suite`.\n *\n * Events:\n *\n *   - `start`  execution started\n *   - `end`  execution complete\n *   - `suite`  (suite) test suite execution started\n *   - `suite end`  (suite) all tests (and sub-suites) have finished\n *   - `test`  (test) test execution started\n *   - `test end`  (test) test completed\n *   - `hook`  (hook) hook execution started\n *   - `hook end`  (hook) hook complete\n *   - `pass`  (test) test passed\n *   - `fail`  (test, err) test failed\n *   - `pending`  (test) test pending\n *\n * @api public\n * @param {Suite} suite Root suite\n * @param {boolean} [delay] Whether or not to delay execution of root suite\n * until ready.\n */\nfunction Runner(suite, delay) {\n  var self = this;\n  this._globals = [];\n  this._abort = false;\n  this._delay = delay;\n  this.suite = suite;\n  this.started = false;\n  this.total = suite.total();\n  this.failures = 0;\n  this.on('test end', function(test) {\n    self.checkGlobals(test);\n  });\n  this.on('hook end', function(hook) {\n    self.checkGlobals(hook);\n  });\n  this._defaultGrep = /.*/;\n  this.grep(this._defaultGrep);\n  this.globals(this.globalProps().concat(extraGlobals()));\n}\n\n/**\n * Wrapper for setImmediate, process.nextTick, or browser polyfill.\n *\n * @param {Function} fn\n * @api private\n */\nRunner.immediately = global.setImmediate || process.nextTick;\n\n/**\n * Inherit from `EventEmitter.prototype`.\n */\ninherits(Runner, EventEmitter);\n\n/**\n * Run tests with full titles matching `re`. Updates runner.total\n * with number of tests matched.\n *\n * @param {RegExp} re\n * @param {Boolean} invert\n * @return {Runner} for chaining\n * @api public\n * @param {RegExp} re\n * @param {boolean} invert\n * @return {Runner} Runner instance.\n */\nRunner.prototype.grep = function(re, invert) {\n  debug('grep %s', re);\n  this._grep = re;\n  this._invert = invert;\n  this.total = this.grepTotal(this.suite);\n  return this;\n};\n\n/**\n * Returns the number of tests matching the grep search for the\n * given suite.\n *\n * @param {Suite} suite\n * @return {Number}\n * @api public\n * @param {Suite} suite\n * @return {number}\n */\nRunner.prototype.grepTotal = function(suite) {\n  var self = this;\n  var total = 0;\n\n  suite.eachTest(function(test) {\n    var match = self._grep.test(test.fullTitle());\n    if (self._invert) {\n      match = !match;\n    }\n    if (match) {\n      total++;\n    }\n  });\n\n  return total;\n};\n\n/**\n * Return a list of global properties.\n *\n * @return {Array}\n * @api private\n */\nRunner.prototype.globalProps = function() {\n  var props = keys(global);\n\n  // non-enumerables\n  for (var i = 0; i < globals.length; ++i) {\n    if (~indexOf(props, globals[i])) {\n      continue;\n    }\n    props.push(globals[i]);\n  }\n\n  return props;\n};\n\n/**\n * Allow the given `arr` of globals.\n *\n * @param {Array} arr\n * @return {Runner} for chaining\n * @api public\n * @param {Array} arr\n * @return {Runner} Runner instance.\n */\nRunner.prototype.globals = function(arr) {\n  if (!arguments.length) {\n    return this._globals;\n  }\n  debug('globals %j', arr);\n  this._globals = this._globals.concat(arr);\n  return this;\n};\n\n/**\n * Check for global variable leaks.\n *\n * @api private\n */\nRunner.prototype.checkGlobals = function(test) {\n  if (this.ignoreLeaks) {\n    return;\n  }\n  var ok = this._globals;\n\n  var globals = this.globalProps();\n  var leaks;\n\n  if (test) {\n    ok = ok.concat(test._allowedGlobals || []);\n  }\n\n  if (this.prevGlobalsLength === globals.length) {\n    return;\n  }\n  this.prevGlobalsLength = globals.length;\n\n  leaks = filterLeaks(ok, globals);\n  this._globals = this._globals.concat(leaks);\n\n  if (leaks.length > 1) {\n    this.fail(test, new Error('global leaks detected: ' + leaks.join(', ') + ''));\n  } else if (leaks.length) {\n    this.fail(test, new Error('global leak detected: ' + leaks[0]));\n  }\n};\n\n/**\n * Fail the given `test`.\n *\n * @api private\n * @param {Test} test\n * @param {Error} err\n */\nRunner.prototype.fail = function(test, err) {\n  if (test.isPending()) {\n    return;\n  }\n\n  ++this.failures;\n  test.state = 'failed';\n\n  if (!(err instanceof Error || err && typeof err.message === 'string')) {\n    err = new Error('the ' + type(err) + ' ' + stringify(err) + ' was thrown, throw an Error :)');\n  }\n\n  err.stack = (this.fullStackTrace || !err.stack)\n    ? err.stack\n    : stackFilter(err.stack);\n\n  this.emit('fail', test, err);\n};\n\n/**\n * Fail the given `hook` with `err`.\n *\n * Hook failures work in the following pattern:\n * - If bail, then exit\n * - Failed `before` hook skips all tests in a suite and subsuites,\n *   but jumps to corresponding `after` hook\n * - Failed `before each` hook skips remaining tests in a\n *   suite and jumps to corresponding `after each` hook,\n *   which is run only once\n * - Failed `after` hook does not alter\n *   execution order\n * - Failed `after each` hook skips remaining tests in a\n *   suite and subsuites, but executes other `after each`\n *   hooks\n *\n * @api private\n * @param {Hook} hook\n * @param {Error} err\n */\nRunner.prototype.failHook = function(hook, err) {\n  if (hook.ctx && hook.ctx.currentTest) {\n    hook.originalTitle = hook.originalTitle || hook.title;\n    hook.title = hook.originalTitle + ' for \"' + hook.ctx.currentTest.title + '\"';\n  }\n\n  this.fail(hook, err);\n  if (this.suite.bail()) {\n    this.emit('end');\n  }\n};\n\n/**\n * Run hook `name` callbacks and then invoke `fn()`.\n *\n * @api private\n * @param {string} name\n * @param {Function} fn\n */\n\nRunner.prototype.hook = function(name, fn) {\n  var suite = this.suite;\n  var hooks = suite['_' + name];\n  var self = this;\n\n  function next(i) {\n    var hook = hooks[i];\n    if (!hook) {\n      return fn();\n    }\n    self.currentRunnable = hook;\n\n    hook.ctx.currentTest = self.test;\n\n    self.emit('hook', hook);\n\n    if (!hook.listeners('error').length) {\n      hook.on('error', function(err) {\n        self.failHook(hook, err);\n      });\n    }\n\n    hook.run(function(err) {\n      var testError = hook.error();\n      if (testError) {\n        self.fail(self.test, testError);\n      }\n      if (err) {\n        if (err instanceof Pending) {\n          if (name === 'beforeEach' || name === 'afterEach') {\n            self.test.pending = true;\n          } else {\n            utils.forEach(suite.tests, function(test) {\n              test.pending = true;\n            });\n            // a pending hook won't be executed twice.\n            hook.pending = true;\n          }\n        } else {\n          self.failHook(hook, err);\n\n          // stop executing hooks, notify callee of hook err\n          return fn(err);\n        }\n      }\n      self.emit('hook end', hook);\n      delete hook.ctx.currentTest;\n      next(++i);\n    });\n  }\n\n  Runner.immediately(function() {\n    next(0);\n  });\n};\n\n/**\n * Run hook `name` for the given array of `suites`\n * in order, and callback `fn(err, errSuite)`.\n *\n * @api private\n * @param {string} name\n * @param {Array} suites\n * @param {Function} fn\n */\nRunner.prototype.hooks = function(name, suites, fn) {\n  var self = this;\n  var orig = this.suite;\n\n  function next(suite) {\n    self.suite = suite;\n\n    if (!suite) {\n      self.suite = orig;\n      return fn();\n    }\n\n    self.hook(name, function(err) {\n      if (err) {\n        var errSuite = self.suite;\n        self.suite = orig;\n        return fn(err, errSuite);\n      }\n\n      next(suites.pop());\n    });\n  }\n\n  next(suites.pop());\n};\n\n/**\n * Run hooks from the top level down.\n *\n * @param {String} name\n * @param {Function} fn\n * @api private\n */\nRunner.prototype.hookUp = function(name, fn) {\n  var suites = [this.suite].concat(this.parents()).reverse();\n  this.hooks(name, suites, fn);\n};\n\n/**\n * Run hooks from the bottom up.\n *\n * @param {String} name\n * @param {Function} fn\n * @api private\n */\nRunner.prototype.hookDown = function(name, fn) {\n  var suites = [this.suite].concat(this.parents());\n  this.hooks(name, suites, fn);\n};\n\n/**\n * Return an array of parent Suites from\n * closest to furthest.\n *\n * @return {Array}\n * @api private\n */\nRunner.prototype.parents = function() {\n  var suite = this.suite;\n  var suites = [];\n  while (suite.parent) {\n    suite = suite.parent;\n    suites.push(suite);\n  }\n  return suites;\n};\n\n/**\n * Run the current test and callback `fn(err)`.\n *\n * @param {Function} fn\n * @api private\n */\nRunner.prototype.runTest = function(fn) {\n  var self = this;\n  var test = this.test;\n\n  if (!test) {\n    return;\n  }\n  if (this.asyncOnly) {\n    test.asyncOnly = true;\n  }\n\n  if (this.allowUncaught) {\n    test.allowUncaught = true;\n    return test.run(fn);\n  }\n  try {\n    test.on('error', function(err) {\n      self.fail(test, err);\n    });\n    test.run(fn);\n  } catch (err) {\n    fn(err);\n  }\n};\n\n/**\n * Run tests in the given `suite` and invoke the callback `fn()` when complete.\n *\n * @api private\n * @param {Suite} suite\n * @param {Function} fn\n */\nRunner.prototype.runTests = function(suite, fn) {\n  var self = this;\n  var tests = suite.tests.slice();\n  var test;\n\n  function hookErr(_, errSuite, after) {\n    // before/after Each hook for errSuite failed:\n    var orig = self.suite;\n\n    // for failed 'after each' hook start from errSuite parent,\n    // otherwise start from errSuite itself\n    self.suite = after ? errSuite.parent : errSuite;\n\n    if (self.suite) {\n      // call hookUp afterEach\n      self.hookUp('afterEach', function(err2, errSuite2) {\n        self.suite = orig;\n        // some hooks may fail even now\n        if (err2) {\n          return hookErr(err2, errSuite2, true);\n        }\n        // report error suite\n        fn(errSuite);\n      });\n    } else {\n      // there is no need calling other 'after each' hooks\n      self.suite = orig;\n      fn(errSuite);\n    }\n  }\n\n  function next(err, errSuite) {\n    // if we bail after first err\n    if (self.failures && suite._bail) {\n      return fn();\n    }\n\n    if (self._abort) {\n      return fn();\n    }\n\n    if (err) {\n      return hookErr(err, errSuite, true);\n    }\n\n    // next test\n    test = tests.shift();\n\n    // all done\n    if (!test) {\n      return fn();\n    }\n\n    // grep\n    var match = self._grep.test(test.fullTitle());\n    if (self._invert) {\n      match = !match;\n    }\n    if (!match) {\n      // Run immediately only if we have defined a grep. When we\n      // define a grep — It can cause maximum callstack error if\n      // the grep is doing a large recursive loop by neglecting\n      // all tests. The run immediately function also comes with\n      // a performance cost. So we don't want to run immediately\n      // if we run the whole test suite, because running the whole\n      // test suite don't do any immediate recursive loops. Thus,\n      // allowing a JS runtime to breathe.\n      if (self._grep !== self._defaultGrep) {\n        Runner.immediately(next);\n      } else {\n        next();\n      }\n      return;\n    }\n\n    if (test.isPending()) {\n      self.emit('pending', test);\n      self.emit('test end', test);\n      return next();\n    }\n\n    // execute test and hook(s)\n    self.emit('test', self.test = test);\n    self.hookDown('beforeEach', function(err, errSuite) {\n      if (test.isPending()) {\n        self.emit('pending', test);\n        self.emit('test end', test);\n        return next();\n      }\n      if (err) {\n        return hookErr(err, errSuite, false);\n      }\n      self.currentRunnable = self.test;\n      self.runTest(function(err) {\n        test = self.test;\n        if (err) {\n          var retry = test.currentRetry();\n          if (err instanceof Pending) {\n            test.pending = true;\n            self.emit('pending', test);\n          } else if (retry < test.retries()) {\n            var clonedTest = test.clone();\n            clonedTest.currentRetry(retry + 1);\n            tests.unshift(clonedTest);\n\n            // Early return + hook trigger so that it doesn't\n            // increment the count wrong\n            return self.hookUp('afterEach', next);\n          } else {\n            self.fail(test, err);\n          }\n          self.emit('test end', test);\n\n          if (err instanceof Pending) {\n            return next();\n          }\n\n          return self.hookUp('afterEach', next);\n        }\n\n        test.state = 'passed';\n        self.emit('pass', test);\n        self.emit('test end', test);\n        self.hookUp('afterEach', next);\n      });\n    });\n  }\n\n  this.next = next;\n  this.hookErr = hookErr;\n  next();\n};\n\n/**\n * Run the given `suite` and invoke the callback `fn()` when complete.\n *\n * @api private\n * @param {Suite} suite\n * @param {Function} fn\n */\nRunner.prototype.runSuite = function(suite, fn) {\n  var i = 0;\n  var self = this;\n  var total = this.grepTotal(suite);\n  var afterAllHookCalled = false;\n\n  debug('run suite %s', suite.fullTitle());\n\n  if (!total || (self.failures && suite._bail)) {\n    return fn();\n  }\n\n  this.emit('suite', this.suite = suite);\n\n  function next(errSuite) {\n    if (errSuite) {\n      // current suite failed on a hook from errSuite\n      if (errSuite === suite) {\n        // if errSuite is current suite\n        // continue to the next sibling suite\n        return done();\n      }\n      // errSuite is among the parents of current suite\n      // stop execution of errSuite and all sub-suites\n      return done(errSuite);\n    }\n\n    if (self._abort) {\n      return done();\n    }\n\n    var curr = suite.suites[i++];\n    if (!curr) {\n      return done();\n    }\n\n    // Avoid grep neglecting large number of tests causing a\n    // huge recursive loop and thus a maximum call stack error.\n    // See comment in `this.runTests()` for more information.\n    if (self._grep !== self._defaultGrep) {\n      Runner.immediately(function() {\n        self.runSuite(curr, next);\n      });\n    } else {\n      self.runSuite(curr, next);\n    }\n  }\n\n  function done(errSuite) {\n    self.suite = suite;\n    self.nextSuite = next;\n\n    if (afterAllHookCalled) {\n      fn(errSuite);\n    } else {\n      // mark that the afterAll block has been called once\n      // and so can be skipped if there is an error in it.\n      afterAllHookCalled = true;\n\n      // remove reference to test\n      delete self.test;\n\n      self.hook('afterAll', function() {\n        self.emit('suite end', suite);\n        fn(errSuite);\n      });\n    }\n  }\n\n  this.nextSuite = next;\n\n  this.hook('beforeAll', function(err) {\n    if (err) {\n      return done();\n    }\n    self.runTests(suite, next);\n  });\n};\n\n/**\n * Handle uncaught exceptions.\n *\n * @param {Error} err\n * @api private\n */\nRunner.prototype.uncaught = function(err) {\n  if (err) {\n    debug('uncaught exception %s', err !== function() {\n      return this;\n    }.call(err) ? err : (err.message || err));\n  } else {\n    debug('uncaught undefined exception');\n    err = undefinedError();\n  }\n  err.uncaught = true;\n\n  var runnable = this.currentRunnable;\n\n  if (!runnable) {\n    runnable = new Runnable('Uncaught error outside test suite');\n    runnable.parent = this.suite;\n\n    if (this.started) {\n      this.fail(runnable, err);\n    } else {\n      // Can't recover from this failure\n      this.emit('start');\n      this.fail(runnable, err);\n      this.emit('end');\n    }\n\n    return;\n  }\n\n  runnable.clearTimeout();\n\n  // Ignore errors if complete or pending\n  if (runnable.state || runnable.isPending()) {\n    return;\n  }\n  this.fail(runnable, err);\n\n  // recover from test\n  if (runnable.type === 'test') {\n    this.emit('test end', runnable);\n    this.hookUp('afterEach', this.next);\n    return;\n  }\n\n // recover from hooks\n  if (runnable.type === 'hook') {\n    var errSuite = this.suite;\n    // if hook failure is in afterEach block\n    if (runnable.fullTitle().indexOf('after each') > -1) {\n      return this.hookErr(err, errSuite, true);\n    }\n    // if hook failure is in beforeEach block\n    if (runnable.fullTitle().indexOf('before each') > -1) {\n      return this.hookErr(err, errSuite, false);\n    }\n    // if hook failure is in after or before blocks\n    return this.nextSuite(errSuite);\n  }\n\n  // bail\n  this.emit('end');\n};\n\n/**\n * Cleans up the references to all the deferred functions\n * (before/after/beforeEach/afterEach) and tests of a Suite.\n * These must be deleted otherwise a memory leak can happen,\n * as those functions may reference variables from closures,\n * thus those variables can never be garbage collected as long\n * as the deferred functions exist.\n *\n * @param {Suite} suite\n */\nfunction cleanSuiteReferences(suite) {\n  function cleanArrReferences(arr) {\n    for (var i = 0; i < arr.length; i++) {\n      delete arr[i].fn;\n    }\n  }\n\n  if (isArray(suite._beforeAll)) {\n    cleanArrReferences(suite._beforeAll);\n  }\n\n  if (isArray(suite._beforeEach)) {\n    cleanArrReferences(suite._beforeEach);\n  }\n\n  if (isArray(suite._afterAll)) {\n    cleanArrReferences(suite._afterAll);\n  }\n\n  if (isArray(suite._afterEach)) {\n    cleanArrReferences(suite._afterEach);\n  }\n\n  for (var i = 0; i < suite.tests.length; i++) {\n    delete suite.tests[i].fn;\n  }\n}\n\n/**\n * Run the root suite and invoke `fn(failures)`\n * on completion.\n *\n * @param {Function} fn\n * @return {Runner} for chaining\n * @api public\n * @param {Function} fn\n * @return {Runner} Runner instance.\n */\nRunner.prototype.run = function(fn) {\n  var self = this;\n  var rootSuite = this.suite;\n\n  // If there is an `only` filter\n  if (this.hasOnly) {\n    filterOnly(rootSuite);\n  }\n\n  fn = fn || function() {};\n\n  function uncaught(err) {\n    self.uncaught(err);\n  }\n\n  function start() {\n    self.started = true;\n    self.emit('start');\n    self.runSuite(rootSuite, function() {\n      debug('finished running');\n      self.emit('end');\n    });\n  }\n\n  debug('start');\n\n  // references cleanup to avoid memory leaks\n  this.on('suite end', cleanSuiteReferences);\n\n  // callback\n  this.on('end', function() {\n    debug('end');\n    process.removeListener('uncaughtException', uncaught);\n    fn(self.failures);\n  });\n\n  // uncaught exception\n  process.on('uncaughtException', uncaught);\n\n  if (this._delay) {\n    // for reporters, I guess.\n    // might be nice to debounce some dots while we wait.\n    this.emit('waiting', rootSuite);\n    rootSuite.once('run', start);\n  } else {\n    start();\n  }\n\n  return this;\n};\n\n/**\n * Cleanly abort execution.\n *\n * @api public\n * @return {Runner} Runner instance.\n */\nRunner.prototype.abort = function() {\n  debug('aborting');\n  this._abort = true;\n\n  return this;\n};\n\n/**\n * Filter suites based on `isOnly` logic.\n *\n * @param {Array} suite\n * @returns {Boolean}\n * @api private\n */\nfunction filterOnly(suite) {\n  if (suite._onlyTests.length) {\n    // If the suite contains `only` tests, run those and ignore any nested suites.\n    suite.tests = suite._onlyTests;\n    suite.suites = [];\n  } else {\n    // Otherwise, do not run any of the tests in this suite.\n    suite.tests = [];\n    utils.forEach(suite._onlySuites, function(onlySuite) {\n      // If there are other `only` tests/suites nested in the current `only` suite, then filter that `only` suite.\n      // Otherwise, all of the tests on this `only` suite should be run, so don't filter it.\n      if (hasOnly(onlySuite)) {\n        filterOnly(onlySuite);\n      }\n    });\n    // Run the `only` suites, as well as any other suites that have `only` tests/suites as descendants.\n    suite.suites = filter(suite.suites, function(childSuite) {\n      return indexOf(suite._onlySuites, childSuite) !== -1 || filterOnly(childSuite);\n    });\n  }\n  // Keep the suite only if there is something to run\n  return suite.tests.length || suite.suites.length;\n}\n\n/**\n * Determines whether a suite has an `only` test or suite as a descendant.\n *\n * @param {Array} suite\n * @returns {Boolean}\n * @api private\n */\nfunction hasOnly(suite) {\n  return suite._onlyTests.length || suite._onlySuites.length || some(suite.suites, hasOnly);\n}\n\n/**\n * Filter leaks with the given globals flagged as `ok`.\n *\n * @api private\n * @param {Array} ok\n * @param {Array} globals\n * @return {Array}\n */\nfunction filterLeaks(ok, globals) {\n  return filter(globals, function(key) {\n    // Firefox and Chrome exposes iframes as index inside the window object\n    if (/^\\d+/.test(key)) {\n      return false;\n    }\n\n    // in firefox\n    // if runner runs in an iframe, this iframe's window.getInterface method\n    // not init at first it is assigned in some seconds\n    if (global.navigator && (/^getInterface/).test(key)) {\n      return false;\n    }\n\n    // an iframe could be approached by window[iframeIndex]\n    // in ie6,7,8 and opera, iframeIndex is enumerable, this could cause leak\n    if (global.navigator && (/^\\d+/).test(key)) {\n      return false;\n    }\n\n    // Opera and IE expose global variables for HTML element IDs (issue #243)\n    if (/^mocha-/.test(key)) {\n      return false;\n    }\n\n    var matched = filter(ok, function(ok) {\n      if (~ok.indexOf('*')) {\n        return key.indexOf(ok.split('*')[0]) === 0;\n      }\n      return key === ok;\n    });\n    return !matched.length && (!global.navigator || key !== 'onerror');\n  });\n}\n\n/**\n * Array of globals dependent on the environment.\n *\n * @return {Array}\n * @api private\n */\nfunction extraGlobals() {\n  if (typeof process === 'object' && typeof process.version === 'string') {\n    var parts = process.version.split('.');\n    var nodeVersion = utils.reduce(parts, function(a, v) {\n      return a << 8 | v;\n    });\n\n    // 'errno' was renamed to process._errno in v0.9.11.\n\n    if (nodeVersion < 0x00090B) {\n      return ['errno'];\n    }\n  }\n\n  return [];\n}\n\n}).call(this,require('_process'),typeof global !== \"undefined\" ? global : typeof self !== \"undefined\" ? self : typeof window !== \"undefined\" ? window : {})\n},{\"./pending\":16,\"./runnable\":33,\"./utils\":38,\"_process\":67,\"debug\":2,\"events\":3}],35:[function(require,module,exports){\n/**\n * Module dependencies.\n */\n\nvar EventEmitter = require('events').EventEmitter;\nvar Hook = require('./hook');\nvar utils = require('./utils');\nvar inherits = utils.inherits;\nvar debug = require('debug')('mocha:suite');\nvar milliseconds = require('./ms');\n\n/**\n * Expose `Suite`.\n */\n\nexports = module.exports = Suite;\n\n/**\n * Create a new `Suite` with the given `title` and parent `Suite`. When a suite\n * with the same title is already present, that suite is returned to provide\n * nicer reporter and more flexible meta-testing.\n *\n * @api public\n * @param {Suite} parent\n * @param {string} title\n * @return {Suite}\n */\nexports.create = function(parent, title) {\n  var suite = new Suite(title, parent.ctx);\n  suite.parent = parent;\n  title = suite.fullTitle();\n  parent.addSuite(suite);\n  return suite;\n};\n\n/**\n * Initialize a new `Suite` with the given `title` and `ctx`.\n *\n * @api private\n * @param {string} title\n * @param {Context} parentContext\n */\nfunction Suite(title, parentContext) {\n  if (!utils.isString(title)) {\n    throw new Error('Suite `title` should be a \"string\" but \"' + typeof title + '\" was given instead.');\n  }\n  this.title = title;\n  function Context() {}\n  Context.prototype = parentContext;\n  this.ctx = new Context();\n  this.suites = [];\n  this.tests = [];\n  this.pending = false;\n  this._beforeEach = [];\n  this._beforeAll = [];\n  this._afterEach = [];\n  this._afterAll = [];\n  this.root = !title;\n  this._timeout = 2000;\n  this._enableTimeouts = true;\n  this._slow = 75;\n  this._bail = false;\n  this._retries = -1;\n  this._onlyTests = [];\n  this._onlySuites = [];\n  this.delayed = false;\n}\n\n/**\n * Inherit from `EventEmitter.prototype`.\n */\ninherits(Suite, EventEmitter);\n\n/**\n * Return a clone of this `Suite`.\n *\n * @api private\n * @return {Suite}\n */\nSuite.prototype.clone = function() {\n  var suite = new Suite(this.title);\n  debug('clone');\n  suite.ctx = this.ctx;\n  suite.timeout(this.timeout());\n  suite.retries(this.retries());\n  suite.enableTimeouts(this.enableTimeouts());\n  suite.slow(this.slow());\n  suite.bail(this.bail());\n  return suite;\n};\n\n/**\n * Set timeout `ms` or short-hand such as \"2s\".\n *\n * @api private\n * @param {number|string} ms\n * @return {Suite|number} for chaining\n */\nSuite.prototype.timeout = function(ms) {\n  if (!arguments.length) {\n    return this._timeout;\n  }\n  if (ms.toString() === '0') {\n    this._enableTimeouts = false;\n  }\n  if (typeof ms === 'string') {\n    ms = milliseconds(ms);\n  }\n  debug('timeout %d', ms);\n  this._timeout = parseInt(ms, 10);\n  return this;\n};\n\n/**\n * Set number of times to retry a failed test.\n *\n * @api private\n * @param {number|string} n\n * @return {Suite|number} for chaining\n */\nSuite.prototype.retries = function(n) {\n  if (!arguments.length) {\n    return this._retries;\n  }\n  debug('retries %d', n);\n  this._retries = parseInt(n, 10) || 0;\n  return this;\n};\n\n/**\n  * Set timeout to `enabled`.\n  *\n  * @api private\n  * @param {boolean} enabled\n  * @return {Suite|boolean} self or enabled\n  */\nSuite.prototype.enableTimeouts = function(enabled) {\n  if (!arguments.length) {\n    return this._enableTimeouts;\n  }\n  debug('enableTimeouts %s', enabled);\n  this._enableTimeouts = enabled;\n  return this;\n};\n\n/**\n * Set slow `ms` or short-hand such as \"2s\".\n *\n * @api private\n * @param {number|string} ms\n * @return {Suite|number} for chaining\n */\nSuite.prototype.slow = function(ms) {\n  if (!arguments.length) {\n    return this._slow;\n  }\n  if (typeof ms === 'string') {\n    ms = milliseconds(ms);\n  }\n  debug('slow %d', ms);\n  this._slow = ms;\n  return this;\n};\n\n/**\n * Sets whether to bail after first error.\n *\n * @api private\n * @param {boolean} bail\n * @return {Suite|number} for chaining\n */\nSuite.prototype.bail = function(bail) {\n  if (!arguments.length) {\n    return this._bail;\n  }\n  debug('bail %s', bail);\n  this._bail = bail;\n  return this;\n};\n\n/**\n * Check if this suite or its parent suite is marked as pending.\n *\n * @api private\n */\nSuite.prototype.isPending = function() {\n  return this.pending || (this.parent && this.parent.isPending());\n};\n\n/**\n * Run `fn(test[, done])` before running tests.\n *\n * @api private\n * @param {string} title\n * @param {Function} fn\n * @return {Suite} for chaining\n */\nSuite.prototype.beforeAll = function(title, fn) {\n  if (this.isPending()) {\n    return this;\n  }\n  if (typeof title === 'function') {\n    fn = title;\n    title = fn.name;\n  }\n  title = '\"before all\" hook' + (title ? ': ' + title : '');\n\n  var hook = new Hook(title, fn);\n  hook.parent = this;\n  hook.timeout(this.timeout());\n  hook.retries(this.retries());\n  hook.enableTimeouts(this.enableTimeouts());\n  hook.slow(this.slow());\n  hook.ctx = this.ctx;\n  this._beforeAll.push(hook);\n  this.emit('beforeAll', hook);\n  return this;\n};\n\n/**\n * Run `fn(test[, done])` after running tests.\n *\n * @api private\n * @param {string} title\n * @param {Function} fn\n * @return {Suite} for chaining\n */\nSuite.prototype.afterAll = function(title, fn) {\n  if (this.isPending()) {\n    return this;\n  }\n  if (typeof title === 'function') {\n    fn = title;\n    title = fn.name;\n  }\n  title = '\"after all\" hook' + (title ? ': ' + title : '');\n\n  var hook = new Hook(title, fn);\n  hook.parent = this;\n  hook.timeout(this.timeout());\n  hook.retries(this.retries());\n  hook.enableTimeouts(this.enableTimeouts());\n  hook.slow(this.slow());\n  hook.ctx = this.ctx;\n  this._afterAll.push(hook);\n  this.emit('afterAll', hook);\n  return this;\n};\n\n/**\n * Run `fn(test[, done])` before each test case.\n *\n * @api private\n * @param {string} title\n * @param {Function} fn\n * @return {Suite} for chaining\n */\nSuite.prototype.beforeEach = function(title, fn) {\n  if (this.isPending()) {\n    return this;\n  }\n  if (typeof title === 'function') {\n    fn = title;\n    title = fn.name;\n  }\n  title = '\"before each\" hook' + (title ? ': ' + title : '');\n\n  var hook = new Hook(title, fn);\n  hook.parent = this;\n  hook.timeout(this.timeout());\n  hook.retries(this.retries());\n  hook.enableTimeouts(this.enableTimeouts());\n  hook.slow(this.slow());\n  hook.ctx = this.ctx;\n  this._beforeEach.push(hook);\n  this.emit('beforeEach', hook);\n  return this;\n};\n\n/**\n * Run `fn(test[, done])` after each test case.\n *\n * @api private\n * @param {string} title\n * @param {Function} fn\n * @return {Suite} for chaining\n */\nSuite.prototype.afterEach = function(title, fn) {\n  if (this.isPending()) {\n    return this;\n  }\n  if (typeof title === 'function') {\n    fn = title;\n    title = fn.name;\n  }\n  title = '\"after each\" hook' + (title ? ': ' + title : '');\n\n  var hook = new Hook(title, fn);\n  hook.parent = this;\n  hook.timeout(this.timeout());\n  hook.retries(this.retries());\n  hook.enableTimeouts(this.enableTimeouts());\n  hook.slow(this.slow());\n  hook.ctx = this.ctx;\n  this._afterEach.push(hook);\n  this.emit('afterEach', hook);\n  return this;\n};\n\n/**\n * Add a test `suite`.\n *\n * @api private\n * @param {Suite} suite\n * @return {Suite} for chaining\n */\nSuite.prototype.addSuite = function(suite) {\n  suite.parent = this;\n  suite.timeout(this.timeout());\n  suite.retries(this.retries());\n  suite.enableTimeouts(this.enableTimeouts());\n  suite.slow(this.slow());\n  suite.bail(this.bail());\n  this.suites.push(suite);\n  this.emit('suite', suite);\n  return this;\n};\n\n/**\n * Add a `test` to this suite.\n *\n * @api private\n * @param {Test} test\n * @return {Suite} for chaining\n */\nSuite.prototype.addTest = function(test) {\n  test.parent = this;\n  test.timeout(this.timeout());\n  test.retries(this.retries());\n  test.enableTimeouts(this.enableTimeouts());\n  test.slow(this.slow());\n  test.ctx = this.ctx;\n  this.tests.push(test);\n  this.emit('test', test);\n  return this;\n};\n\n/**\n * Return the full title generated by recursively concatenating the parent's\n * full title.\n *\n * @api public\n * @return {string}\n */\nSuite.prototype.fullTitle = function() {\n  if (this.parent) {\n    var full = this.parent.fullTitle();\n    if (full) {\n      return full + ' ' + this.title;\n    }\n  }\n  return this.title;\n};\n\n/**\n * Return the total number of tests.\n *\n * @api public\n * @return {number}\n */\nSuite.prototype.total = function() {\n  return utils.reduce(this.suites, function(sum, suite) {\n    return sum + suite.total();\n  }, 0) + this.tests.length;\n};\n\n/**\n * Iterates through each suite recursively to find all tests. Applies a\n * function in the format `fn(test)`.\n *\n * @api private\n * @param {Function} fn\n * @return {Suite}\n */\nSuite.prototype.eachTest = function(fn) {\n  utils.forEach(this.tests, fn);\n  utils.forEach(this.suites, function(suite) {\n    suite.eachTest(fn);\n  });\n  return this;\n};\n\n/**\n * This will run the root suite if we happen to be running in delayed mode.\n */\nSuite.prototype.run = function run() {\n  if (this.root) {\n    this.emit('run');\n  }\n};\n\n},{\"./hook\":7,\"./ms\":15,\"./utils\":38,\"debug\":2,\"events\":3}],36:[function(require,module,exports){\n/**\n * Module dependencies.\n */\n\nvar Runnable = require('./runnable');\nvar create = require('lodash.create');\nvar isString = require('./utils').isString;\n\n/**\n * Expose `Test`.\n */\n\nmodule.exports = Test;\n\n/**\n * Initialize a new `Test` with the given `title` and callback `fn`.\n *\n * @api private\n * @param {String} title\n * @param {Function} fn\n */\nfunction Test(title, fn) {\n  if (!isString(title)) {\n    throw new Error('Test `title` should be a \"string\" but \"' + typeof title + '\" was given instead.');\n  }\n  Runnable.call(this, title, fn);\n  this.pending = !fn;\n  this.type = 'test';\n}\n\n/**\n * Inherit from `Runnable.prototype`.\n */\nTest.prototype = create(Runnable.prototype, {\n  constructor: Test\n});\n\nTest.prototype.clone = function() {\n  var test = new Test(this.title, this.fn);\n  test.timeout(this.timeout());\n  test.slow(this.slow());\n  test.enableTimeouts(this.enableTimeouts());\n  test.retries(this.retries());\n  test.currentRetry(this.currentRetry());\n  test.globals(this.globals());\n  test.parent = this.parent;\n  test.file = this.file;\n  test.ctx = this.ctx;\n  return test;\n};\n\n},{\"./runnable\":33,\"./utils\":38,\"lodash.create\":60}],37:[function(require,module,exports){\n'use strict';\n\n/**\n * Pad a `number` with a ten's place zero.\n *\n * @param {number} number\n * @return {string}\n */\nfunction pad(number) {\n  var n = number.toString();\n  return n.length === 1 ? '0' + n : n;\n}\n\n/**\n * Turn a `date` into an ISO string.\n *\n * https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/toISOString\n *\n * @param {Date} date\n * @return {string}\n */\nfunction toISOString(date) {\n  return date.getUTCFullYear()\n    + '-' + pad(date.getUTCMonth() + 1)\n    + '-' + pad(date.getUTCDate())\n    + 'T' + pad(date.getUTCHours())\n    + ':' + pad(date.getUTCMinutes())\n    + ':' + pad(date.getUTCSeconds())\n    + '.' + String((date.getUTCMilliseconds()/1000).toFixed(3)).slice(2, 5)\n    + 'Z';\n}\n\n/*\n * Exports.\n */\n\nmodule.exports = toISOString;\n\n},{}],38:[function(require,module,exports){\n(function (process,Buffer){\n/* eslint-env browser */\n\n/**\n * Module dependencies.\n */\n\nvar JSON = require('json3');\nvar basename = require('path').basename;\nvar debug = require('debug')('mocha:watch');\nvar exists = require('fs').existsSync || require('path').existsSync;\nvar glob = require('glob');\nvar path = require('path');\nvar join = path.join;\nvar readdirSync = require('fs').readdirSync;\nvar statSync = require('fs').statSync;\nvar watchFile = require('fs').watchFile;\nvar toISOString = require('./to-iso-string');\n\n/**\n * Ignored directories.\n */\n\nvar ignore = ['node_modules', '.git'];\n\nexports.inherits = require('util').inherits;\n\n/**\n * Escape special characters in the given string of html.\n *\n * @api private\n * @param  {string} html\n * @return {string}\n */\nexports.escape = function(html) {\n  return String(html)\n    .replace(/&/g, '&amp;')\n    .replace(/\"/g, '&quot;')\n    .replace(/</g, '&lt;')\n    .replace(/>/g, '&gt;');\n};\n\n/**\n * Array#forEach (<=IE8)\n *\n * @api private\n * @param {Array} arr\n * @param {Function} fn\n * @param {Object} scope\n */\nexports.forEach = function(arr, fn, scope) {\n  for (var i = 0, l = arr.length; i < l; i++) {\n    fn.call(scope, arr[i], i);\n  }\n};\n\n/**\n * Test if the given obj is type of string.\n *\n * @api private\n * @param {Object} obj\n * @return {boolean}\n */\nexports.isString = function(obj) {\n  return typeof obj === 'string';\n};\n\n/**\n * Array#map (<=IE8)\n *\n * @api private\n * @param {Array} arr\n * @param {Function} fn\n * @param {Object} scope\n * @return {Array}\n */\nexports.map = function(arr, fn, scope) {\n  var result = [];\n  for (var i = 0, l = arr.length; i < l; i++) {\n    result.push(fn.call(scope, arr[i], i, arr));\n  }\n  return result;\n};\n\n/**\n * Array#indexOf (<=IE8)\n *\n * @api private\n * @param {Array} arr\n * @param {Object} obj to find index of\n * @param {number} start\n * @return {number}\n */\nvar indexOf = exports.indexOf = function(arr, obj, start) {\n  for (var i = start || 0, l = arr.length; i < l; i++) {\n    if (arr[i] === obj) {\n      return i;\n    }\n  }\n  return -1;\n};\n\n/**\n * Array#reduce (<=IE8)\n *\n * @api private\n * @param {Array} arr\n * @param {Function} fn\n * @param {Object} val Initial value.\n * @return {*}\n */\nvar reduce = exports.reduce = function(arr, fn, val) {\n  var rval = val;\n\n  for (var i = 0, l = arr.length; i < l; i++) {\n    rval = fn(rval, arr[i], i, arr);\n  }\n\n  return rval;\n};\n\n/**\n * Array#filter (<=IE8)\n *\n * @api private\n * @param {Array} arr\n * @param {Function} fn\n * @return {Array}\n */\nexports.filter = function(arr, fn) {\n  var ret = [];\n\n  for (var i = 0, l = arr.length; i < l; i++) {\n    var val = arr[i];\n    if (fn(val, i, arr)) {\n      ret.push(val);\n    }\n  }\n\n  return ret;\n};\n\n/**\n * Array#some (<=IE8)\n *\n * @api private\n * @param {Array} arr\n * @param {Function} fn\n * @return {Array}\n */\nexports.some = function(arr, fn) {\n  for (var i = 0, l = arr.length; i < l; i++) {\n    if (fn(arr[i])) {\n      return true;\n    }\n  }\n  return false;\n};\n\n/**\n * Object.keys (<=IE8)\n *\n * @api private\n * @param {Object} obj\n * @return {Array} keys\n */\nexports.keys = typeof Object.keys === 'function' ? Object.keys : function(obj) {\n  var keys = [];\n  var has = Object.prototype.hasOwnProperty; // for `window` on <=IE8\n\n  for (var key in obj) {\n    if (has.call(obj, key)) {\n      keys.push(key);\n    }\n  }\n\n  return keys;\n};\n\n/**\n * Watch the given `files` for changes\n * and invoke `fn(file)` on modification.\n *\n * @api private\n * @param {Array} files\n * @param {Function} fn\n */\nexports.watch = function(files, fn) {\n  var options = { interval: 100 };\n  files.forEach(function(file) {\n    debug('file %s', file);\n    watchFile(file, options, function(curr, prev) {\n      if (prev.mtime < curr.mtime) {\n        fn(file);\n      }\n    });\n  });\n};\n\n/**\n * Array.isArray (<=IE8)\n *\n * @api private\n * @param {Object} obj\n * @return {Boolean}\n */\nvar isArray = typeof Array.isArray === 'function' ? Array.isArray : function(obj) {\n  return Object.prototype.toString.call(obj) === '[object Array]';\n};\n\nexports.isArray = isArray;\n\n/**\n * Buffer.prototype.toJSON polyfill.\n *\n * @type {Function}\n */\nif (typeof Buffer !== 'undefined' && Buffer.prototype) {\n  Buffer.prototype.toJSON = Buffer.prototype.toJSON || function() {\n    return Array.prototype.slice.call(this, 0);\n  };\n}\n\n/**\n * Ignored files.\n *\n * @api private\n * @param {string} path\n * @return {boolean}\n */\nfunction ignored(path) {\n  return !~ignore.indexOf(path);\n}\n\n/**\n * Lookup files in the given `dir`.\n *\n * @api private\n * @param {string} dir\n * @param {string[]} [ext=['.js']]\n * @param {Array} [ret=[]]\n * @return {Array}\n */\nexports.files = function(dir, ext, ret) {\n  ret = ret || [];\n  ext = ext || ['js'];\n\n  var re = new RegExp('\\\\.(' + ext.join('|') + ')$');\n\n  readdirSync(dir)\n    .filter(ignored)\n    .forEach(function(path) {\n      path = join(dir, path);\n      if (statSync(path).isDirectory()) {\n        exports.files(path, ext, ret);\n      } else if (path.match(re)) {\n        ret.push(path);\n      }\n    });\n\n  return ret;\n};\n\n/**\n * Compute a slug from the given `str`.\n *\n * @api private\n * @param {string} str\n * @return {string}\n */\nexports.slug = function(str) {\n  return str\n    .toLowerCase()\n    .replace(/ +/g, '-')\n    .replace(/[^-\\w]/g, '');\n};\n\n/**\n * Strip the function definition from `str`, and re-indent for pre whitespace.\n *\n * @param {string} str\n * @return {string}\n */\nexports.clean = function(str) {\n  str = str\n    .replace(/\\r\\n?|[\\n\\u2028\\u2029]/g, '\\n').replace(/^\\uFEFF/, '')\n    // (traditional)->  space/name     parameters    body     (lambda)-> parameters       body   multi-statement/single          keep body content\n    .replace(/^function(?:\\s*|\\s+[^(]*)\\([^)]*\\)\\s*\\{((?:.|\\n)*?)\\s*\\}$|^\\([^)]*\\)\\s*=>\\s*(?:\\{((?:.|\\n)*?)\\s*\\}|((?:.|\\n)*))$/, '$1$2$3');\n\n  var spaces = str.match(/^\\n?( *)/)[1].length;\n  var tabs = str.match(/^\\n?(\\t*)/)[1].length;\n  var re = new RegExp('^\\n?' + (tabs ? '\\t' : ' ') + '{' + (tabs ? tabs : spaces) + '}', 'gm');\n\n  str = str.replace(re, '');\n\n  return exports.trim(str);\n};\n\n/**\n * Trim the given `str`.\n *\n * @api private\n * @param {string} str\n * @return {string}\n */\nexports.trim = function(str) {\n  return str.replace(/^\\s+|\\s+$/g, '');\n};\n\n/**\n * Parse the given `qs`.\n *\n * @api private\n * @param {string} qs\n * @return {Object}\n */\nexports.parseQuery = function(qs) {\n  return reduce(qs.replace('?', '').split('&'), function(obj, pair) {\n    var i = pair.indexOf('=');\n    var key = pair.slice(0, i);\n    var val = pair.slice(++i);\n\n    obj[key] = decodeURIComponent(val);\n    return obj;\n  }, {});\n};\n\n/**\n * Highlight the given string of `js`.\n *\n * @api private\n * @param {string} js\n * @return {string}\n */\nfunction highlight(js) {\n  return js\n    .replace(/</g, '&lt;')\n    .replace(/>/g, '&gt;')\n    .replace(/\\/\\/(.*)/gm, '<span class=\"comment\">//$1</span>')\n    .replace(/('.*?')/gm, '<span class=\"string\">$1</span>')\n    .replace(/(\\d+\\.\\d+)/gm, '<span class=\"number\">$1</span>')\n    .replace(/(\\d+)/gm, '<span class=\"number\">$1</span>')\n    .replace(/\\bnew[ \\t]+(\\w+)/gm, '<span class=\"keyword\">new</span> <span class=\"init\">$1</span>')\n    .replace(/\\b(function|new|throw|return|var|if|else)\\b/gm, '<span class=\"keyword\">$1</span>');\n}\n\n/**\n * Highlight the contents of tag `name`.\n *\n * @api private\n * @param {string} name\n */\nexports.highlightTags = function(name) {\n  var code = document.getElementById('mocha').getElementsByTagName(name);\n  for (var i = 0, len = code.length; i < len; ++i) {\n    code[i].innerHTML = highlight(code[i].innerHTML);\n  }\n};\n\n/**\n * If a value could have properties, and has none, this function is called,\n * which returns a string representation of the empty value.\n *\n * Functions w/ no properties return `'[Function]'`\n * Arrays w/ length === 0 return `'[]'`\n * Objects w/ no properties return `'{}'`\n * All else: return result of `value.toString()`\n *\n * @api private\n * @param {*} value The value to inspect.\n * @param {string} typeHint The type of the value\n * @returns {string}\n */\nfunction emptyRepresentation(value, typeHint) {\n  switch (typeHint) {\n    case 'function':\n      return '[Function]';\n    case 'object':\n      return '{}';\n    case 'array':\n      return '[]';\n    default:\n      return value.toString();\n  }\n}\n\n/**\n * Takes some variable and asks `Object.prototype.toString()` what it thinks it\n * is.\n *\n * @api private\n * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/toString\n * @param {*} value The value to test.\n * @returns {string} Computed type\n * @example\n * type({}) // 'object'\n * type([]) // 'array'\n * type(1) // 'number'\n * type(false) // 'boolean'\n * type(Infinity) // 'number'\n * type(null) // 'null'\n * type(new Date()) // 'date'\n * type(/foo/) // 'regexp'\n * type('type') // 'string'\n * type(global) // 'global'\n * type(new String('foo') // 'object'\n */\nvar type = exports.type = function type(value) {\n  if (value === undefined) {\n    return 'undefined';\n  } else if (value === null) {\n    return 'null';\n  } else if (typeof Buffer !== 'undefined' && Buffer.isBuffer(value)) {\n    return 'buffer';\n  }\n  return Object.prototype.toString.call(value)\n    .replace(/^\\[.+\\s(.+?)\\]$/, '$1')\n    .toLowerCase();\n};\n\n/**\n * Stringify `value`. Different behavior depending on type of value:\n *\n * - If `value` is undefined or null, return `'[undefined]'` or `'[null]'`, respectively.\n * - If `value` is not an object, function or array, return result of `value.toString()` wrapped in double-quotes.\n * - If `value` is an *empty* object, function, or array, return result of function\n *   {@link emptyRepresentation}.\n * - If `value` has properties, call {@link exports.canonicalize} on it, then return result of\n *   JSON.stringify().\n *\n * @api private\n * @see exports.type\n * @param {*} value\n * @return {string}\n */\nexports.stringify = function(value) {\n  var typeHint = type(value);\n\n  if (!~indexOf(['object', 'array', 'function'], typeHint)) {\n    if (typeHint === 'buffer') {\n      var json = value.toJSON();\n      // Based on the toJSON result\n      return jsonStringify(json.data && json.type ? json.data : json, 2)\n        .replace(/,(\\n|$)/g, '$1');\n    }\n\n    // IE7/IE8 has a bizarre String constructor; needs to be coerced\n    // into an array and back to obj.\n    if (typeHint === 'string' && typeof value === 'object') {\n      value = reduce(value.split(''), function(acc, char, idx) {\n        acc[idx] = char;\n        return acc;\n      }, {});\n      typeHint = 'object';\n    } else {\n      return jsonStringify(value);\n    }\n  }\n\n  for (var prop in value) {\n    if (Object.prototype.hasOwnProperty.call(value, prop)) {\n      return jsonStringify(exports.canonicalize(value, null, typeHint), 2).replace(/,(\\n|$)/g, '$1');\n    }\n  }\n\n  return emptyRepresentation(value, typeHint);\n};\n\n/**\n * like JSON.stringify but more sense.\n *\n * @api private\n * @param {Object}  object\n * @param {number=} spaces\n * @param {number=} depth\n * @returns {*}\n */\nfunction jsonStringify(object, spaces, depth) {\n  if (typeof spaces === 'undefined') {\n    // primitive types\n    return _stringify(object);\n  }\n\n  depth = depth || 1;\n  var space = spaces * depth;\n  var str = isArray(object) ? '[' : '{';\n  var end = isArray(object) ? ']' : '}';\n  var length = typeof object.length === 'number' ? object.length : exports.keys(object).length;\n  // `.repeat()` polyfill\n  function repeat(s, n) {\n    return new Array(n).join(s);\n  }\n\n  function _stringify(val) {\n    switch (type(val)) {\n      case 'null':\n      case 'undefined':\n        val = '[' + val + ']';\n        break;\n      case 'array':\n      case 'object':\n        val = jsonStringify(val, spaces, depth + 1);\n        break;\n      case 'boolean':\n      case 'regexp':\n      case 'symbol':\n      case 'number':\n        val = val === 0 && (1 / val) === -Infinity // `-0`\n          ? '-0'\n          : val.toString();\n        break;\n      case 'date':\n        var sDate;\n        if (isNaN(val.getTime())) { // Invalid date\n          sDate = val.toString();\n        } else {\n          sDate = val.toISOString ? val.toISOString() : toISOString(val);\n        }\n        val = '[Date: ' + sDate + ']';\n        break;\n      case 'buffer':\n        var json = val.toJSON();\n        // Based on the toJSON result\n        json = json.data && json.type ? json.data : json;\n        val = '[Buffer: ' + jsonStringify(json, 2, depth + 1) + ']';\n        break;\n      default:\n        val = (val === '[Function]' || val === '[Circular]')\n          ? val\n          : JSON.stringify(val); // string\n    }\n    return val;\n  }\n\n  for (var i in object) {\n    if (!Object.prototype.hasOwnProperty.call(object, i)) {\n      continue; // not my business\n    }\n    --length;\n    str += '\\n ' + repeat(' ', space)\n      + (isArray(object) ? '' : '\"' + i + '\": ') // key\n      + _stringify(object[i])                     // value\n      + (length ? ',' : '');                     // comma\n  }\n\n  return str\n    // [], {}\n    + (str.length !== 1 ? '\\n' + repeat(' ', --space) + end : end);\n}\n\n/**\n * Test if a value is a buffer.\n *\n * @api private\n * @param {*} value The value to test.\n * @return {boolean} True if `value` is a buffer, otherwise false\n */\nexports.isBuffer = function(value) {\n  return typeof Buffer !== 'undefined' && Buffer.isBuffer(value);\n};\n\n/**\n * Return a new Thing that has the keys in sorted order. Recursive.\n *\n * If the Thing...\n * - has already been seen, return string `'[Circular]'`\n * - is `undefined`, return string `'[undefined]'`\n * - is `null`, return value `null`\n * - is some other primitive, return the value\n * - is not a primitive or an `Array`, `Object`, or `Function`, return the value of the Thing's `toString()` method\n * - is a non-empty `Array`, `Object`, or `Function`, return the result of calling this function again.\n * - is an empty `Array`, `Object`, or `Function`, return the result of calling `emptyRepresentation()`\n *\n * @api private\n * @see {@link exports.stringify}\n * @param {*} value Thing to inspect.  May or may not have properties.\n * @param {Array} [stack=[]] Stack of seen values\n * @param {string} [typeHint] Type hint\n * @return {(Object|Array|Function|string|undefined)}\n */\nexports.canonicalize = function canonicalize(value, stack, typeHint) {\n  var canonicalizedObj;\n  /* eslint-disable no-unused-vars */\n  var prop;\n  /* eslint-enable no-unused-vars */\n  typeHint = typeHint || type(value);\n  function withStack(value, fn) {\n    stack.push(value);\n    fn();\n    stack.pop();\n  }\n\n  stack = stack || [];\n\n  if (indexOf(stack, value) !== -1) {\n    return '[Circular]';\n  }\n\n  switch (typeHint) {\n    case 'undefined':\n    case 'buffer':\n    case 'null':\n      canonicalizedObj = value;\n      break;\n    case 'array':\n      withStack(value, function() {\n        canonicalizedObj = exports.map(value, function(item) {\n          return exports.canonicalize(item, stack);\n        });\n      });\n      break;\n    case 'function':\n      /* eslint-disable guard-for-in */\n      for (prop in value) {\n        canonicalizedObj = {};\n        break;\n      }\n      /* eslint-enable guard-for-in */\n      if (!canonicalizedObj) {\n        canonicalizedObj = emptyRepresentation(value, typeHint);\n        break;\n      }\n    /* falls through */\n    case 'object':\n      canonicalizedObj = canonicalizedObj || {};\n      withStack(value, function() {\n        exports.forEach(exports.keys(value).sort(), function(key) {\n          canonicalizedObj[key] = exports.canonicalize(value[key], stack);\n        });\n      });\n      break;\n    case 'date':\n    case 'number':\n    case 'regexp':\n    case 'boolean':\n    case 'symbol':\n      canonicalizedObj = value;\n      break;\n    default:\n      canonicalizedObj = value + '';\n  }\n\n  return canonicalizedObj;\n};\n\n/**\n * Lookup file names at the given `path`.\n *\n * @api public\n * @param {string} path Base path to start searching from.\n * @param {string[]} extensions File extensions to look for.\n * @param {boolean} recursive Whether or not to recurse into subdirectories.\n * @return {string[]} An array of paths.\n */\nexports.lookupFiles = function lookupFiles(path, extensions, recursive) {\n  var files = [];\n  var re = new RegExp('\\\\.(' + extensions.join('|') + ')$');\n\n  if (!exists(path)) {\n    if (exists(path + '.js')) {\n      path += '.js';\n    } else {\n      files = glob.sync(path);\n      if (!files.length) {\n        throw new Error(\"cannot resolve path (or pattern) '\" + path + \"'\");\n      }\n      return files;\n    }\n  }\n\n  try {\n    var stat = statSync(path);\n    if (stat.isFile()) {\n      return path;\n    }\n  } catch (err) {\n    // ignore error\n    return;\n  }\n\n  readdirSync(path).forEach(function(file) {\n    file = join(path, file);\n    try {\n      var stat = statSync(file);\n      if (stat.isDirectory()) {\n        if (recursive) {\n          files = files.concat(lookupFiles(file, extensions, recursive));\n        }\n        return;\n      }\n    } catch (err) {\n      // ignore error\n      return;\n    }\n    if (!stat.isFile() || !re.test(file) || basename(file)[0] === '.') {\n      return;\n    }\n    files.push(file);\n  });\n\n  return files;\n};\n\n/**\n * Generate an undefined error with a message warning the user.\n *\n * @return {Error}\n */\n\nexports.undefinedError = function() {\n  return new Error('Caught undefined error, did you throw without specifying what?');\n};\n\n/**\n * Generate an undefined error if `err` is not defined.\n *\n * @param {Error} err\n * @return {Error}\n */\n\nexports.getError = function(err) {\n  return err || exports.undefinedError();\n};\n\n/**\n * @summary\n * This Filter based on `mocha-clean` module.(see: `github.com/rstacruz/mocha-clean`)\n * @description\n * When invoking this function you get a filter function that get the Error.stack as an input,\n * and return a prettify output.\n * (i.e: strip Mocha and internal node functions from stack trace).\n * @returns {Function}\n */\nexports.stackTraceFilter = function() {\n  // TODO: Replace with `process.browser`\n  var is = typeof document === 'undefined' ? { node: true } : { browser: true };\n  var slash = path.sep;\n  var cwd;\n  if (is.node) {\n    cwd = process.cwd() + slash;\n  } else {\n    cwd = (typeof location === 'undefined' ? window.location : location).href.replace(/\\/[^\\/]*$/, '/');\n    slash = '/';\n  }\n\n  function isMochaInternal(line) {\n    return (~line.indexOf('node_modules' + slash + 'mocha' + slash))\n      || (~line.indexOf('node_modules' + slash + 'mocha.js'))\n      || (~line.indexOf('bower_components' + slash + 'mocha.js'))\n      || (~line.indexOf(slash + 'mocha.js'));\n  }\n\n  function isNodeInternal(line) {\n    return (~line.indexOf('(timers.js:'))\n      || (~line.indexOf('(events.js:'))\n      || (~line.indexOf('(node.js:'))\n      || (~line.indexOf('(module.js:'))\n      || (~line.indexOf('GeneratorFunctionPrototype.next (native)'))\n      || false;\n  }\n\n  return function(stack) {\n    stack = stack.split('\\n');\n\n    stack = reduce(stack, function(list, line) {\n      if (isMochaInternal(line)) {\n        return list;\n      }\n\n      if (is.node && isNodeInternal(line)) {\n        return list;\n      }\n\n      // Clean up cwd(absolute)\n      if (/\\(?.+:\\d+:\\d+\\)?$/.test(line)) {\n        line = line.replace(cwd, '');\n      }\n\n      list.push(line);\n      return list;\n    }, []);\n\n    return stack.join('\\n');\n  };\n};\n\n/**\n * Crude, but effective.\n * @api\n * @param {*} value\n * @returns {boolean} Whether or not `value` is a Promise\n */\nexports.isPromise = function isPromise(value) {\n  return typeof value === 'object' && typeof value.then === 'function';\n};\n\n}).call(this,require('_process'),require(\"buffer\").Buffer)\n},{\"./to-iso-string\":37,\"_process\":67,\"buffer\":44,\"debug\":2,\"fs\":42,\"glob\":42,\"json3\":54,\"path\":42,\"util\":84}],39:[function(require,module,exports){\n'use strict'\n\nexports.toByteArray = toByteArray\nexports.fromByteArray = fromByteArray\n\nvar lookup = []\nvar revLookup = []\nvar Arr = typeof Uint8Array !== 'undefined' ? Uint8Array : Array\n\nfunction init () {\n  var code = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'\n  for (var i = 0, len = code.length; i < len; ++i) {\n    lookup[i] = code[i]\n    revLookup[code.charCodeAt(i)] = i\n  }\n\n  revLookup['-'.charCodeAt(0)] = 62\n  revLookup['_'.charCodeAt(0)] = 63\n}\n\ninit()\n\nfunction toByteArray (b64) {\n  var i, j, l, tmp, placeHolders, arr\n  var len = b64.length\n\n  if (len % 4 > 0) {\n    throw new Error('Invalid string. Length must be a multiple of 4')\n  }\n\n  // the number of equal signs (place holders)\n  // if there are two placeholders, than the two characters before it\n  // represent one byte\n  // if there is only one, then the three characters before it represent 2 bytes\n  // this is just a cheap hack to not do indexOf twice\n  placeHolders = b64[len - 2] === '=' ? 2 : b64[len - 1] === '=' ? 1 : 0\n\n  // base64 is 4/3 + up to two characters of the original data\n  arr = new Arr(len * 3 / 4 - placeHolders)\n\n  // if there are placeholders, only get up to the last complete 4 chars\n  l = placeHolders > 0 ? len - 4 : len\n\n  var L = 0\n\n  for (i = 0, j = 0; i < l; i += 4, j += 3) {\n    tmp = (revLookup[b64.charCodeAt(i)] << 18) | (revLookup[b64.charCodeAt(i + 1)] << 12) | (revLookup[b64.charCodeAt(i + 2)] << 6) | revLookup[b64.charCodeAt(i + 3)]\n    arr[L++] = (tmp >> 16) & 0xFF\n    arr[L++] = (tmp >> 8) & 0xFF\n    arr[L++] = tmp & 0xFF\n  }\n\n  if (placeHolders === 2) {\n    tmp = (revLookup[b64.charCodeAt(i)] << 2) | (revLookup[b64.charCodeAt(i + 1)] >> 4)\n    arr[L++] = tmp & 0xFF\n  } else if (placeHolders === 1) {\n    tmp = (revLookup[b64.charCodeAt(i)] << 10) | (revLookup[b64.charCodeAt(i + 1)] << 4) | (revLookup[b64.charCodeAt(i + 2)] >> 2)\n    arr[L++] = (tmp >> 8) & 0xFF\n    arr[L++] = tmp & 0xFF\n  }\n\n  return arr\n}\n\nfunction tripletToBase64 (num) {\n  return lookup[num >> 18 & 0x3F] + lookup[num >> 12 & 0x3F] + lookup[num >> 6 & 0x3F] + lookup[num & 0x3F]\n}\n\nfunction encodeChunk (uint8, start, end) {\n  var tmp\n  var output = []\n  for (var i = start; i < end; i += 3) {\n    tmp = (uint8[i] << 16) + (uint8[i + 1] << 8) + (uint8[i + 2])\n    output.push(tripletToBase64(tmp))\n  }\n  return output.join('')\n}\n\nfunction fromByteArray (uint8) {\n  var tmp\n  var len = uint8.length\n  var extraBytes = len % 3 // if we have 1 byte left, pad 2 bytes\n  var output = ''\n  var parts = []\n  var maxChunkLength = 16383 // must be multiple of 3\n\n  // go through the array every three bytes, we'll deal with trailing stuff later\n  for (var i = 0, len2 = len - extraBytes; i < len2; i += maxChunkLength) {\n    parts.push(encodeChunk(uint8, i, (i + maxChunkLength) > len2 ? len2 : (i + maxChunkLength)))\n  }\n\n  // pad the end with zeros, but make sure to not forget the extra bytes\n  if (extraBytes === 1) {\n    tmp = uint8[len - 1]\n    output += lookup[tmp >> 2]\n    output += lookup[(tmp << 4) & 0x3F]\n    output += '=='\n  } else if (extraBytes === 2) {\n    tmp = (uint8[len - 2] << 8) + (uint8[len - 1])\n    output += lookup[tmp >> 10]\n    output += lookup[(tmp >> 4) & 0x3F]\n    output += lookup[(tmp << 2) & 0x3F]\n    output += '='\n  }\n\n  parts.push(output)\n\n  return parts.join('')\n}\n\n},{}],40:[function(require,module,exports){\n\n},{}],41:[function(require,module,exports){\n(function (process){\nvar WritableStream = require('stream').Writable\nvar inherits = require('util').inherits\n\nmodule.exports = BrowserStdout\n\n\ninherits(BrowserStdout, WritableStream)\n\nfunction BrowserStdout(opts) {\n  if (!(this instanceof BrowserStdout)) return new BrowserStdout(opts)\n\n  opts = opts || {}\n  WritableStream.call(this, opts)\n  this.label = (opts.label !== undefined) ? opts.label : 'stdout'\n}\n\nBrowserStdout.prototype._write = function(chunks, encoding, cb) {\n  var output = chunks.toString ? chunks.toString() : chunks\n  if (this.label === false) {\n    console.log(output)\n  } else {\n    console.log(this.label+':', output)\n  }\n  process.nextTick(cb)\n}\n\n}).call(this,require('_process'))\n},{\"_process\":67,\"stream\":79,\"util\":84}],42:[function(require,module,exports){\narguments[4][40][0].apply(exports,arguments)\n},{\"dup\":40}],43:[function(require,module,exports){\n(function (global){\n'use strict';\n\nvar buffer = require('buffer');\nvar Buffer = buffer.Buffer;\nvar SlowBuffer = buffer.SlowBuffer;\nvar MAX_LEN = buffer.kMaxLength || 2147483647;\nexports.alloc = function alloc(size, fill, encoding) {\n  if (typeof Buffer.alloc === 'function') {\n    return Buffer.alloc(size, fill, encoding);\n  }\n  if (typeof encoding === 'number') {\n    throw new TypeError('encoding must not be number');\n  }\n  if (typeof size !== 'number') {\n    throw new TypeError('size must be a number');\n  }\n  if (size > MAX_LEN) {\n    throw new RangeError('size is too large');\n  }\n  var enc = encoding;\n  var _fill = fill;\n  if (_fill === undefined) {\n    enc = undefined;\n    _fill = 0;\n  }\n  var buf = new Buffer(size);\n  if (typeof _fill === 'string') {\n    var fillBuf = new Buffer(_fill, enc);\n    var flen = fillBuf.length;\n    var i = -1;\n    while (++i < size) {\n      buf[i] = fillBuf[i % flen];\n    }\n  } else {\n    buf.fill(_fill);\n  }\n  return buf;\n}\nexports.allocUnsafe = function allocUnsafe(size) {\n  if (typeof Buffer.allocUnsafe === 'function') {\n    return Buffer.allocUnsafe(size);\n  }\n  if (typeof size !== 'number') {\n    throw new TypeError('size must be a number');\n  }\n  if (size > MAX_LEN) {\n    throw new RangeError('size is too large');\n  }\n  return new Buffer(size);\n}\nexports.from = function from(value, encodingOrOffset, length) {\n  if (typeof Buffer.from === 'function' && (!global.Uint8Array || Uint8Array.from !== Buffer.from)) {\n    return Buffer.from(value, encodingOrOffset, length);\n  }\n  if (typeof value === 'number') {\n    throw new TypeError('\"value\" argument must not be a number');\n  }\n  if (typeof value === 'string') {\n    return new Buffer(value, encodingOrOffset);\n  }\n  if (typeof ArrayBuffer !== 'undefined' && value instanceof ArrayBuffer) {\n    var offset = encodingOrOffset;\n    if (arguments.length === 1) {\n      return new Buffer(value);\n    }\n    if (typeof offset === 'undefined') {\n      offset = 0;\n    }\n    var len = length;\n    if (typeof len === 'undefined') {\n      len = value.byteLength - offset;\n    }\n    if (offset >= value.byteLength) {\n      throw new RangeError('\\'offset\\' is out of bounds');\n    }\n    if (len > value.byteLength - offset) {\n      throw new RangeError('\\'length\\' is out of bounds');\n    }\n    return new Buffer(value.slice(offset, offset + len));\n  }\n  if (Buffer.isBuffer(value)) {\n    var out = new Buffer(value.length);\n    value.copy(out, 0, 0, value.length);\n    return out;\n  }\n  if (value) {\n    if (Array.isArray(value) || (typeof ArrayBuffer !== 'undefined' && value.buffer instanceof ArrayBuffer) || 'length' in value) {\n      return new Buffer(value);\n    }\n    if (value.type === 'Buffer' && Array.isArray(value.data)) {\n      return new Buffer(value.data);\n    }\n  }\n\n  throw new TypeError('First argument must be a string, Buffer, ' + 'ArrayBuffer, Array, or array-like object.');\n}\nexports.allocUnsafeSlow = function allocUnsafeSlow(size) {\n  if (typeof Buffer.allocUnsafeSlow === 'function') {\n    return Buffer.allocUnsafeSlow(size);\n  }\n  if (typeof size !== 'number') {\n    throw new TypeError('size must be a number');\n  }\n  if (size >= MAX_LEN) {\n    throw new RangeError('size is too large');\n  }\n  return new SlowBuffer(size);\n}\n\n}).call(this,typeof global !== \"undefined\" ? global : typeof self !== \"undefined\" ? self : typeof window !== \"undefined\" ? window : {})\n},{\"buffer\":44}],44:[function(require,module,exports){\n(function (global){\n/*!\n * The buffer module from node.js, for the browser.\n *\n * @author   Feross Aboukhadijeh <feross@feross.org> <http://feross.org>\n * @license  MIT\n */\n/* eslint-disable no-proto */\n\n'use strict'\n\nvar base64 = require('base64-js')\nvar ieee754 = require('ieee754')\nvar isArray = require('isarray')\n\nexports.Buffer = Buffer\nexports.SlowBuffer = SlowBuffer\nexports.INSPECT_MAX_BYTES = 50\n\n/**\n * If `Buffer.TYPED_ARRAY_SUPPORT`:\n *   === true    Use Uint8Array implementation (fastest)\n *   === false   Use Object implementation (most compatible, even IE6)\n *\n * Browsers that support typed arrays are IE 10+, Firefox 4+, Chrome 7+, Safari 5.1+,\n * Opera 11.6+, iOS 4.2+.\n *\n * Due to various browser bugs, sometimes the Object implementation will be used even\n * when the browser supports typed arrays.\n *\n * Note:\n *\n *   - Firefox 4-29 lacks support for adding new properties to `Uint8Array` instances,\n *     See: https://bugzilla.mozilla.org/show_bug.cgi?id=695438.\n *\n *   - Chrome 9-10 is missing the `TypedArray.prototype.subarray` function.\n *\n *   - IE10 has a broken `TypedArray.prototype.subarray` function which returns arrays of\n *     incorrect length in some situations.\n\n * We detect these buggy browsers and set `Buffer.TYPED_ARRAY_SUPPORT` to `false` so they\n * get the Object implementation, which is slower but behaves correctly.\n */\nBuffer.TYPED_ARRAY_SUPPORT = global.TYPED_ARRAY_SUPPORT !== undefined\n  ? global.TYPED_ARRAY_SUPPORT\n  : typedArraySupport()\n\n/*\n * Export kMaxLength after typed array support is determined.\n */\nexports.kMaxLength = kMaxLength()\n\nfunction typedArraySupport () {\n  try {\n    var arr = new Uint8Array(1)\n    arr.__proto__ = {__proto__: Uint8Array.prototype, foo: function () { return 42 }}\n    return arr.foo() === 42 && // typed array instances can be augmented\n        typeof arr.subarray === 'function' && // chrome 9-10 lack `subarray`\n        arr.subarray(1, 1).byteLength === 0 // ie10 has broken `subarray`\n  } catch (e) {\n    return false\n  }\n}\n\nfunction kMaxLength () {\n  return Buffer.TYPED_ARRAY_SUPPORT\n    ? 0x7fffffff\n    : 0x3fffffff\n}\n\nfunction createBuffer (that, length) {\n  if (kMaxLength() < length) {\n    throw new RangeError('Invalid typed array length')\n  }\n  if (Buffer.TYPED_ARRAY_SUPPORT) {\n    // Return an augmented `Uint8Array` instance, for best performance\n    that = new Uint8Array(length)\n    that.__proto__ = Buffer.prototype\n  } else {\n    // Fallback: Return an object instance of the Buffer class\n    if (that === null) {\n      that = new Buffer(length)\n    }\n    that.length = length\n  }\n\n  return that\n}\n\n/**\n * The Buffer constructor returns instances of `Uint8Array` that have their\n * prototype changed to `Buffer.prototype`. Furthermore, `Buffer` is a subclass of\n * `Uint8Array`, so the returned instances will have all the node `Buffer` methods\n * and the `Uint8Array` methods. Square bracket notation works as expected -- it\n * returns a single octet.\n *\n * The `Uint8Array` prototype remains unmodified.\n */\n\nfunction Buffer (arg, encodingOrOffset, length) {\n  if (!Buffer.TYPED_ARRAY_SUPPORT && !(this instanceof Buffer)) {\n    return new Buffer(arg, encodingOrOffset, length)\n  }\n\n  // Common case.\n  if (typeof arg === 'number') {\n    if (typeof encodingOrOffset === 'string') {\n      throw new Error(\n        'If encoding is specified then the first argument must be a string'\n      )\n    }\n    return allocUnsafe(this, arg)\n  }\n  return from(this, arg, encodingOrOffset, length)\n}\n\nBuffer.poolSize = 8192 // not used by this implementation\n\n// TODO: Legacy, not needed anymore. Remove in next major version.\nBuffer._augment = function (arr) {\n  arr.__proto__ = Buffer.prototype\n  return arr\n}\n\nfunction from (that, value, encodingOrOffset, length) {\n  if (typeof value === 'number') {\n    throw new TypeError('\"value\" argument must not be a number')\n  }\n\n  if (typeof ArrayBuffer !== 'undefined' && value instanceof ArrayBuffer) {\n    return fromArrayBuffer(that, value, encodingOrOffset, length)\n  }\n\n  if (typeof value === 'string') {\n    return fromString(that, value, encodingOrOffset)\n  }\n\n  return fromObject(that, value)\n}\n\n/**\n * Functionally equivalent to Buffer(arg, encoding) but throws a TypeError\n * if value is a number.\n * Buffer.from(str[, encoding])\n * Buffer.from(array)\n * Buffer.from(buffer)\n * Buffer.from(arrayBuffer[, byteOffset[, length]])\n **/\nBuffer.from = function (value, encodingOrOffset, length) {\n  return from(null, value, encodingOrOffset, length)\n}\n\nif (Buffer.TYPED_ARRAY_SUPPORT) {\n  Buffer.prototype.__proto__ = Uint8Array.prototype\n  Buffer.__proto__ = Uint8Array\n  if (typeof Symbol !== 'undefined' && Symbol.species &&\n      Buffer[Symbol.species] === Buffer) {\n    // Fix subarray() in ES2016. See: https://github.com/feross/buffer/pull/97\n    Object.defineProperty(Buffer, Symbol.species, {\n      value: null,\n      configurable: true\n    })\n  }\n}\n\nfunction assertSize (size) {\n  if (typeof size !== 'number') {\n    throw new TypeError('\"size\" argument must be a number')\n  } else if (size < 0) {\n    throw new RangeError('\"size\" argument must not be negative')\n  }\n}\n\nfunction alloc (that, size, fill, encoding) {\n  assertSize(size)\n  if (size <= 0) {\n    return createBuffer(that, size)\n  }\n  if (fill !== undefined) {\n    // Only pay attention to encoding if it's a string. This\n    // prevents accidentally sending in a number that would\n    // be interpretted as a start offset.\n    return typeof encoding === 'string'\n      ? createBuffer(that, size).fill(fill, encoding)\n      : createBuffer(that, size).fill(fill)\n  }\n  return createBuffer(that, size)\n}\n\n/**\n * Creates a new filled Buffer instance.\n * alloc(size[, fill[, encoding]])\n **/\nBuffer.alloc = function (size, fill, encoding) {\n  return alloc(null, size, fill, encoding)\n}\n\nfunction allocUnsafe (that, size) {\n  assertSize(size)\n  that = createBuffer(that, size < 0 ? 0 : checked(size) | 0)\n  if (!Buffer.TYPED_ARRAY_SUPPORT) {\n    for (var i = 0; i < size; ++i) {\n      that[i] = 0\n    }\n  }\n  return that\n}\n\n/**\n * Equivalent to Buffer(num), by default creates a non-zero-filled Buffer instance.\n * */\nBuffer.allocUnsafe = function (size) {\n  return allocUnsafe(null, size)\n}\n/**\n * Equivalent to SlowBuffer(num), by default creates a non-zero-filled Buffer instance.\n */\nBuffer.allocUnsafeSlow = function (size) {\n  return allocUnsafe(null, size)\n}\n\nfunction fromString (that, string, encoding) {\n  if (typeof encoding !== 'string' || encoding === '') {\n    encoding = 'utf8'\n  }\n\n  if (!Buffer.isEncoding(encoding)) {\n    throw new TypeError('\"encoding\" must be a valid string encoding')\n  }\n\n  var length = byteLength(string, encoding) | 0\n  that = createBuffer(that, length)\n\n  var actual = that.write(string, encoding)\n\n  if (actual !== length) {\n    // Writing a hex string, for example, that contains invalid characters will\n    // cause everything after the first invalid character to be ignored. (e.g.\n    // 'abxxcd' will be treated as 'ab')\n    that = that.slice(0, actual)\n  }\n\n  return that\n}\n\nfunction fromArrayLike (that, array) {\n  var length = array.length < 0 ? 0 : checked(array.length) | 0\n  that = createBuffer(that, length)\n  for (var i = 0; i < length; i += 1) {\n    that[i] = array[i] & 255\n  }\n  return that\n}\n\nfunction fromArrayBuffer (that, array, byteOffset, length) {\n  array.byteLength // this throws if `array` is not a valid ArrayBuffer\n\n  if (byteOffset < 0 || array.byteLength < byteOffset) {\n    throw new RangeError('\\'offset\\' is out of bounds')\n  }\n\n  if (array.byteLength < byteOffset + (length || 0)) {\n    throw new RangeError('\\'length\\' is out of bounds')\n  }\n\n  if (byteOffset === undefined && length === undefined) {\n    array = new Uint8Array(array)\n  } else if (length === undefined) {\n    array = new Uint8Array(array, byteOffset)\n  } else {\n    array = new Uint8Array(array, byteOffset, length)\n  }\n\n  if (Buffer.TYPED_ARRAY_SUPPORT) {\n    // Return an augmented `Uint8Array` instance, for best performance\n    that = array\n    that.__proto__ = Buffer.prototype\n  } else {\n    // Fallback: Return an object instance of the Buffer class\n    that = fromArrayLike(that, array)\n  }\n  return that\n}\n\nfunction fromObject (that, obj) {\n  if (Buffer.isBuffer(obj)) {\n    var len = checked(obj.length) | 0\n    that = createBuffer(that, len)\n\n    if (that.length === 0) {\n      return that\n    }\n\n    obj.copy(that, 0, 0, len)\n    return that\n  }\n\n  if (obj) {\n    if ((typeof ArrayBuffer !== 'undefined' &&\n        obj.buffer instanceof ArrayBuffer) || 'length' in obj) {\n      if (typeof obj.length !== 'number' || isnan(obj.length)) {\n        return createBuffer(that, 0)\n      }\n      return fromArrayLike(that, obj)\n    }\n\n    if (obj.type === 'Buffer' && isArray(obj.data)) {\n      return fromArrayLike(that, obj.data)\n    }\n  }\n\n  throw new TypeError('First argument must be a string, Buffer, ArrayBuffer, Array, or array-like object.')\n}\n\nfunction checked (length) {\n  // Note: cannot use `length < kMaxLength()` here because that fails when\n  // length is NaN (which is otherwise coerced to zero.)\n  if (length >= kMaxLength()) {\n    throw new RangeError('Attempt to allocate Buffer larger than maximum ' +\n                         'size: 0x' + kMaxLength().toString(16) + ' bytes')\n  }\n  return length | 0\n}\n\nfunction SlowBuffer (length) {\n  if (+length != length) { // eslint-disable-line eqeqeq\n    length = 0\n  }\n  return Buffer.alloc(+length)\n}\n\nBuffer.isBuffer = function isBuffer (b) {\n  return !!(b != null && b._isBuffer)\n}\n\nBuffer.compare = function compare (a, b) {\n  if (!Buffer.isBuffer(a) || !Buffer.isBuffer(b)) {\n    throw new TypeError('Arguments must be Buffers')\n  }\n\n  if (a === b) return 0\n\n  var x = a.length\n  var y = b.length\n\n  for (var i = 0, len = Math.min(x, y); i < len; ++i) {\n    if (a[i] !== b[i]) {\n      x = a[i]\n      y = b[i]\n      break\n    }\n  }\n\n  if (x < y) return -1\n  if (y < x) return 1\n  return 0\n}\n\nBuffer.isEncoding = function isEncoding (encoding) {\n  switch (String(encoding).toLowerCase()) {\n    case 'hex':\n    case 'utf8':\n    case 'utf-8':\n    case 'ascii':\n    case 'latin1':\n    case 'binary':\n    case 'base64':\n    case 'ucs2':\n    case 'ucs-2':\n    case 'utf16le':\n    case 'utf-16le':\n      return true\n    default:\n      return false\n  }\n}\n\nBuffer.concat = function concat (list, length) {\n  if (!isArray(list)) {\n    throw new TypeError('\"list\" argument must be an Array of Buffers')\n  }\n\n  if (list.length === 0) {\n    return Buffer.alloc(0)\n  }\n\n  var i\n  if (length === undefined) {\n    length = 0\n    for (i = 0; i < list.length; ++i) {\n      length += list[i].length\n    }\n  }\n\n  var buffer = Buffer.allocUnsafe(length)\n  var pos = 0\n  for (i = 0; i < list.length; ++i) {\n    var buf = list[i]\n    if (!Buffer.isBuffer(buf)) {\n      throw new TypeError('\"list\" argument must be an Array of Buffers')\n    }\n    buf.copy(buffer, pos)\n    pos += buf.length\n  }\n  return buffer\n}\n\nfunction byteLength (string, encoding) {\n  if (Buffer.isBuffer(string)) {\n    return string.length\n  }\n  if (typeof ArrayBuffer !== 'undefined' && typeof ArrayBuffer.isView === 'function' &&\n      (ArrayBuffer.isView(string) || string instanceof ArrayBuffer)) {\n    return string.byteLength\n  }\n  if (typeof string !== 'string') {\n    string = '' + string\n  }\n\n  var len = string.length\n  if (len === 0) return 0\n\n  // Use a for loop to avoid recursion\n  var loweredCase = false\n  for (;;) {\n    switch (encoding) {\n      case 'ascii':\n      case 'latin1':\n      case 'binary':\n        return len\n      case 'utf8':\n      case 'utf-8':\n      case undefined:\n        return utf8ToBytes(string).length\n      case 'ucs2':\n      case 'ucs-2':\n      case 'utf16le':\n      case 'utf-16le':\n        return len * 2\n      case 'hex':\n        return len >>> 1\n      case 'base64':\n        return base64ToBytes(string).length\n      default:\n        if (loweredCase) return utf8ToBytes(string).length // assume utf8\n        encoding = ('' + encoding).toLowerCase()\n        loweredCase = true\n    }\n  }\n}\nBuffer.byteLength = byteLength\n\nfunction slowToString (encoding, start, end) {\n  var loweredCase = false\n\n  // No need to verify that \"this.length <= MAX_UINT32\" since it's a read-only\n  // property of a typed array.\n\n  // This behaves neither like String nor Uint8Array in that we set start/end\n  // to their upper/lower bounds if the value passed is out of range.\n  // undefined is handled specially as per ECMA-262 6th Edition,\n  // Section 13.3.3.7 Runtime Semantics: KeyedBindingInitialization.\n  if (start === undefined || start < 0) {\n    start = 0\n  }\n  // Return early if start > this.length. Done here to prevent potential uint32\n  // coercion fail below.\n  if (start > this.length) {\n    return ''\n  }\n\n  if (end === undefined || end > this.length) {\n    end = this.length\n  }\n\n  if (end <= 0) {\n    return ''\n  }\n\n  // Force coersion to uint32. This will also coerce falsey/NaN values to 0.\n  end >>>= 0\n  start >>>= 0\n\n  if (end <= start) {\n    return ''\n  }\n\n  if (!encoding) encoding = 'utf8'\n\n  while (true) {\n    switch (encoding) {\n      case 'hex':\n        return hexSlice(this, start, end)\n\n      case 'utf8':\n      case 'utf-8':\n        return utf8Slice(this, start, end)\n\n      case 'ascii':\n        return asciiSlice(this, start, end)\n\n      case 'latin1':\n      case 'binary':\n        return latin1Slice(this, start, end)\n\n      case 'base64':\n        return base64Slice(this, start, end)\n\n      case 'ucs2':\n      case 'ucs-2':\n      case 'utf16le':\n      case 'utf-16le':\n        return utf16leSlice(this, start, end)\n\n      default:\n        if (loweredCase) throw new TypeError('Unknown encoding: ' + encoding)\n        encoding = (encoding + '').toLowerCase()\n        loweredCase = true\n    }\n  }\n}\n\n// The property is used by `Buffer.isBuffer` and `is-buffer` (in Safari 5-7) to detect\n// Buffer instances.\nBuffer.prototype._isBuffer = true\n\nfunction swap (b, n, m) {\n  var i = b[n]\n  b[n] = b[m]\n  b[m] = i\n}\n\nBuffer.prototype.swap16 = function swap16 () {\n  var len = this.length\n  if (len % 2 !== 0) {\n    throw new RangeError('Buffer size must be a multiple of 16-bits')\n  }\n  for (var i = 0; i < len; i += 2) {\n    swap(this, i, i + 1)\n  }\n  return this\n}\n\nBuffer.prototype.swap32 = function swap32 () {\n  var len = this.length\n  if (len % 4 !== 0) {\n    throw new RangeError('Buffer size must be a multiple of 32-bits')\n  }\n  for (var i = 0; i < len; i += 4) {\n    swap(this, i, i + 3)\n    swap(this, i + 1, i + 2)\n  }\n  return this\n}\n\nBuffer.prototype.swap64 = function swap64 () {\n  var len = this.length\n  if (len % 8 !== 0) {\n    throw new RangeError('Buffer size must be a multiple of 64-bits')\n  }\n  for (var i = 0; i < len; i += 8) {\n    swap(this, i, i + 7)\n    swap(this, i + 1, i + 6)\n    swap(this, i + 2, i + 5)\n    swap(this, i + 3, i + 4)\n  }\n  return this\n}\n\nBuffer.prototype.toString = function toString () {\n  var length = this.length | 0\n  if (length === 0) return ''\n  if (arguments.length === 0) return utf8Slice(this, 0, length)\n  return slowToString.apply(this, arguments)\n}\n\nBuffer.prototype.equals = function equals (b) {\n  if (!Buffer.isBuffer(b)) throw new TypeError('Argument must be a Buffer')\n  if (this === b) return true\n  return Buffer.compare(this, b) === 0\n}\n\nBuffer.prototype.inspect = function inspect () {\n  var str = ''\n  var max = exports.INSPECT_MAX_BYTES\n  if (this.length > 0) {\n    str = this.toString('hex', 0, max).match(/.{2}/g).join(' ')\n    if (this.length > max) str += ' ... '\n  }\n  return '<Buffer ' + str + '>'\n}\n\nBuffer.prototype.compare = function compare (target, start, end, thisStart, thisEnd) {\n  if (!Buffer.isBuffer(target)) {\n    throw new TypeError('Argument must be a Buffer')\n  }\n\n  if (start === undefined) {\n    start = 0\n  }\n  if (end === undefined) {\n    end = target ? target.length : 0\n  }\n  if (thisStart === undefined) {\n    thisStart = 0\n  }\n  if (thisEnd === undefined) {\n    thisEnd = this.length\n  }\n\n  if (start < 0 || end > target.length || thisStart < 0 || thisEnd > this.length) {\n    throw new RangeError('out of range index')\n  }\n\n  if (thisStart >= thisEnd && start >= end) {\n    return 0\n  }\n  if (thisStart >= thisEnd) {\n    return -1\n  }\n  if (start >= end) {\n    return 1\n  }\n\n  start >>>= 0\n  end >>>= 0\n  thisStart >>>= 0\n  thisEnd >>>= 0\n\n  if (this === target) return 0\n\n  var x = thisEnd - thisStart\n  var y = end - start\n  var len = Math.min(x, y)\n\n  var thisCopy = this.slice(thisStart, thisEnd)\n  var targetCopy = target.slice(start, end)\n\n  for (var i = 0; i < len; ++i) {\n    if (thisCopy[i] !== targetCopy[i]) {\n      x = thisCopy[i]\n      y = targetCopy[i]\n      break\n    }\n  }\n\n  if (x < y) return -1\n  if (y < x) return 1\n  return 0\n}\n\n// Finds either the first index of `val` in `buffer` at offset >= `byteOffset`,\n// OR the last index of `val` in `buffer` at offset <= `byteOffset`.\n//\n// Arguments:\n// - buffer - a Buffer to search\n// - val - a string, Buffer, or number\n// - byteOffset - an index into `buffer`; will be clamped to an int32\n// - encoding - an optional encoding, relevant is val is a string\n// - dir - true for indexOf, false for lastIndexOf\nfunction bidirectionalIndexOf (buffer, val, byteOffset, encoding, dir) {\n  // Empty buffer means no match\n  if (buffer.length === 0) return -1\n\n  // Normalize byteOffset\n  if (typeof byteOffset === 'string') {\n    encoding = byteOffset\n    byteOffset = 0\n  } else if (byteOffset > 0x7fffffff) {\n    byteOffset = 0x7fffffff\n  } else if (byteOffset < -0x80000000) {\n    byteOffset = -0x80000000\n  }\n  byteOffset = +byteOffset  // Coerce to Number.\n  if (isNaN(byteOffset)) {\n    // byteOffset: it it's undefined, null, NaN, \"foo\", etc, search whole buffer\n    byteOffset = dir ? 0 : (buffer.length - 1)\n  }\n\n  // Normalize byteOffset: negative offsets start from the end of the buffer\n  if (byteOffset < 0) byteOffset = buffer.length + byteOffset\n  if (byteOffset >= buffer.length) {\n    if (dir) return -1\n    else byteOffset = buffer.length - 1\n  } else if (byteOffset < 0) {\n    if (dir) byteOffset = 0\n    else return -1\n  }\n\n  // Normalize val\n  if (typeof val === 'string') {\n    val = Buffer.from(val, encoding)\n  }\n\n  // Finally, search either indexOf (if dir is true) or lastIndexOf\n  if (Buffer.isBuffer(val)) {\n    // Special case: looking for empty string/buffer always fails\n    if (val.length === 0) {\n      return -1\n    }\n    return arrayIndexOf(buffer, val, byteOffset, encoding, dir)\n  } else if (typeof val === 'number') {\n    val = val & 0xFF // Search for a byte value [0-255]\n    if (Buffer.TYPED_ARRAY_SUPPORT &&\n        typeof Uint8Array.prototype.indexOf === 'function') {\n      if (dir) {\n        return Uint8Array.prototype.indexOf.call(buffer, val, byteOffset)\n      } else {\n        return Uint8Array.prototype.lastIndexOf.call(buffer, val, byteOffset)\n      }\n    }\n    return arrayIndexOf(buffer, [ val ], byteOffset, encoding, dir)\n  }\n\n  throw new TypeError('val must be string, number or Buffer')\n}\n\nfunction arrayIndexOf (arr, val, byteOffset, encoding, dir) {\n  var indexSize = 1\n  var arrLength = arr.length\n  var valLength = val.length\n\n  if (encoding !== undefined) {\n    encoding = String(encoding).toLowerCase()\n    if (encoding === 'ucs2' || encoding === 'ucs-2' ||\n        encoding === 'utf16le' || encoding === 'utf-16le') {\n      if (arr.length < 2 || val.length < 2) {\n        return -1\n      }\n      indexSize = 2\n      arrLength /= 2\n      valLength /= 2\n      byteOffset /= 2\n    }\n  }\n\n  function read (buf, i) {\n    if (indexSize === 1) {\n      return buf[i]\n    } else {\n      return buf.readUInt16BE(i * indexSize)\n    }\n  }\n\n  var i\n  if (dir) {\n    var foundIndex = -1\n    for (i = byteOffset; i < arrLength; i++) {\n      if (read(arr, i) === read(val, foundIndex === -1 ? 0 : i - foundIndex)) {\n        if (foundIndex === -1) foundIndex = i\n        if (i - foundIndex + 1 === valLength) return foundIndex * indexSize\n      } else {\n        if (foundIndex !== -1) i -= i - foundIndex\n        foundIndex = -1\n      }\n    }\n  } else {\n    if (byteOffset + valLength > arrLength) byteOffset = arrLength - valLength\n    for (i = byteOffset; i >= 0; i--) {\n      var found = true\n      for (var j = 0; j < valLength; j++) {\n        if (read(arr, i + j) !== read(val, j)) {\n          found = false\n          break\n        }\n      }\n      if (found) return i\n    }\n  }\n\n  return -1\n}\n\nBuffer.prototype.includes = function includes (val, byteOffset, encoding) {\n  return this.indexOf(val, byteOffset, encoding) !== -1\n}\n\nBuffer.prototype.indexOf = function indexOf (val, byteOffset, encoding) {\n  return bidirectionalIndexOf(this, val, byteOffset, encoding, true)\n}\n\nBuffer.prototype.lastIndexOf = function lastIndexOf (val, byteOffset, encoding) {\n  return bidirectionalIndexOf(this, val, byteOffset, encoding, false)\n}\n\nfunction hexWrite (buf, string, offset, length) {\n  offset = Number(offset) || 0\n  var remaining = buf.length - offset\n  if (!length) {\n    length = remaining\n  } else {\n    length = Number(length)\n    if (length > remaining) {\n      length = remaining\n    }\n  }\n\n  // must be an even number of digits\n  var strLen = string.length\n  if (strLen % 2 !== 0) throw new TypeError('Invalid hex string')\n\n  if (length > strLen / 2) {\n    length = strLen / 2\n  }\n  for (var i = 0; i < length; ++i) {\n    var parsed = parseInt(string.substr(i * 2, 2), 16)\n    if (isNaN(parsed)) return i\n    buf[offset + i] = parsed\n  }\n  return i\n}\n\nfunction utf8Write (buf, string, offset, length) {\n  return blitBuffer(utf8ToBytes(string, buf.length - offset), buf, offset, length)\n}\n\nfunction asciiWrite (buf, string, offset, length) {\n  return blitBuffer(asciiToBytes(string), buf, offset, length)\n}\n\nfunction latin1Write (buf, string, offset, length) {\n  return asciiWrite(buf, string, offset, length)\n}\n\nfunction base64Write (buf, string, offset, length) {\n  return blitBuffer(base64ToBytes(string), buf, offset, length)\n}\n\nfunction ucs2Write (buf, string, offset, length) {\n  return blitBuffer(utf16leToBytes(string, buf.length - offset), buf, offset, length)\n}\n\nBuffer.prototype.write = function write (string, offset, length, encoding) {\n  // Buffer#write(string)\n  if (offset === undefined) {\n    encoding = 'utf8'\n    length = this.length\n    offset = 0\n  // Buffer#write(string, encoding)\n  } else if (length === undefined && typeof offset === 'string') {\n    encoding = offset\n    length = this.length\n    offset = 0\n  // Buffer#write(string, offset[, length][, encoding])\n  } else if (isFinite(offset)) {\n    offset = offset | 0\n    if (isFinite(length)) {\n      length = length | 0\n      if (encoding === undefined) encoding = 'utf8'\n    } else {\n      encoding = length\n      length = undefined\n    }\n  // legacy write(string, encoding, offset, length) - remove in v0.13\n  } else {\n    throw new Error(\n      'Buffer.write(string, encoding, offset[, length]) is no longer supported'\n    )\n  }\n\n  var remaining = this.length - offset\n  if (length === undefined || length > remaining) length = remaining\n\n  if ((string.length > 0 && (length < 0 || offset < 0)) || offset > this.length) {\n    throw new RangeError('Attempt to write outside buffer bounds')\n  }\n\n  if (!encoding) encoding = 'utf8'\n\n  var loweredCase = false\n  for (;;) {\n    switch (encoding) {\n      case 'hex':\n        return hexWrite(this, string, offset, length)\n\n      case 'utf8':\n      case 'utf-8':\n        return utf8Write(this, string, offset, length)\n\n      case 'ascii':\n        return asciiWrite(this, string, offset, length)\n\n      case 'latin1':\n      case 'binary':\n        return latin1Write(this, string, offset, length)\n\n      case 'base64':\n        // Warning: maxLength not taken into account in base64Write\n        return base64Write(this, string, offset, length)\n\n      case 'ucs2':\n      case 'ucs-2':\n      case 'utf16le':\n      case 'utf-16le':\n        return ucs2Write(this, string, offset, length)\n\n      default:\n        if (loweredCase) throw new TypeError('Unknown encoding: ' + encoding)\n        encoding = ('' + encoding).toLowerCase()\n        loweredCase = true\n    }\n  }\n}\n\nBuffer.prototype.toJSON = function toJSON () {\n  return {\n    type: 'Buffer',\n    data: Array.prototype.slice.call(this._arr || this, 0)\n  }\n}\n\nfunction base64Slice (buf, start, end) {\n  if (start === 0 && end === buf.length) {\n    return base64.fromByteArray(buf)\n  } else {\n    return base64.fromByteArray(buf.slice(start, end))\n  }\n}\n\nfunction utf8Slice (buf, start, end) {\n  end = Math.min(buf.length, end)\n  var res = []\n\n  var i = start\n  while (i < end) {\n    var firstByte = buf[i]\n    var codePoint = null\n    var bytesPerSequence = (firstByte > 0xEF) ? 4\n      : (firstByte > 0xDF) ? 3\n      : (firstByte > 0xBF) ? 2\n      : 1\n\n    if (i + bytesPerSequence <= end) {\n      var secondByte, thirdByte, fourthByte, tempCodePoint\n\n      switch (bytesPerSequence) {\n        case 1:\n          if (firstByte < 0x80) {\n            codePoint = firstByte\n          }\n          break\n        case 2:\n          secondByte = buf[i + 1]\n          if ((secondByte & 0xC0) === 0x80) {\n            tempCodePoint = (firstByte & 0x1F) << 0x6 | (secondByte & 0x3F)\n            if (tempCodePoint > 0x7F) {\n              codePoint = tempCodePoint\n            }\n          }\n          break\n        case 3:\n          secondByte = buf[i + 1]\n          thirdByte = buf[i + 2]\n          if ((secondByte & 0xC0) === 0x80 && (thirdByte & 0xC0) === 0x80) {\n            tempCodePoint = (firstByte & 0xF) << 0xC | (secondByte & 0x3F) << 0x6 | (thirdByte & 0x3F)\n            if (tempCodePoint > 0x7FF && (tempCodePoint < 0xD800 || tempCodePoint > 0xDFFF)) {\n              codePoint = tempCodePoint\n            }\n          }\n          break\n        case 4:\n          secondByte = buf[i + 1]\n          thirdByte = buf[i + 2]\n          fourthByte = buf[i + 3]\n          if ((secondByte & 0xC0) === 0x80 && (thirdByte & 0xC0) === 0x80 && (fourthByte & 0xC0) === 0x80) {\n            tempCodePoint = (firstByte & 0xF) << 0x12 | (secondByte & 0x3F) << 0xC | (thirdByte & 0x3F) << 0x6 | (fourthByte & 0x3F)\n            if (tempCodePoint > 0xFFFF && tempCodePoint < 0x110000) {\n              codePoint = tempCodePoint\n            }\n          }\n      }\n    }\n\n    if (codePoint === null) {\n      // we did not generate a valid codePoint so insert a\n      // replacement char (U+FFFD) and advance only 1 byte\n      codePoint = 0xFFFD\n      bytesPerSequence = 1\n    } else if (codePoint > 0xFFFF) {\n      // encode to utf16 (surrogate pair dance)\n      codePoint -= 0x10000\n      res.push(codePoint >>> 10 & 0x3FF | 0xD800)\n      codePoint = 0xDC00 | codePoint & 0x3FF\n    }\n\n    res.push(codePoint)\n    i += bytesPerSequence\n  }\n\n  return decodeCodePointsArray(res)\n}\n\n// Based on http://stackoverflow.com/a/22747272/680742, the browser with\n// the lowest limit is Chrome, with 0x10000 args.\n// We go 1 magnitude less, for safety\nvar MAX_ARGUMENTS_LENGTH = 0x1000\n\nfunction decodeCodePointsArray (codePoints) {\n  var len = codePoints.length\n  if (len <= MAX_ARGUMENTS_LENGTH) {\n    return String.fromCharCode.apply(String, codePoints) // avoid extra slice()\n  }\n\n  // Decode in chunks to avoid \"call stack size exceeded\".\n  var res = ''\n  var i = 0\n  while (i < len) {\n    res += String.fromCharCode.apply(\n      String,\n      codePoints.slice(i, i += MAX_ARGUMENTS_LENGTH)\n    )\n  }\n  return res\n}\n\nfunction asciiSlice (buf, start, end) {\n  var ret = ''\n  end = Math.min(buf.length, end)\n\n  for (var i = start; i < end; ++i) {\n    ret += String.fromCharCode(buf[i] & 0x7F)\n  }\n  return ret\n}\n\nfunction latin1Slice (buf, start, end) {\n  var ret = ''\n  end = Math.min(buf.length, end)\n\n  for (var i = start; i < end; ++i) {\n    ret += String.fromCharCode(buf[i])\n  }\n  return ret\n}\n\nfunction hexSlice (buf, start, end) {\n  var len = buf.length\n\n  if (!start || start < 0) start = 0\n  if (!end || end < 0 || end > len) end = len\n\n  var out = ''\n  for (var i = start; i < end; ++i) {\n    out += toHex(buf[i])\n  }\n  return out\n}\n\nfunction utf16leSlice (buf, start, end) {\n  var bytes = buf.slice(start, end)\n  var res = ''\n  for (var i = 0; i < bytes.length; i += 2) {\n    res += String.fromCharCode(bytes[i] + bytes[i + 1] * 256)\n  }\n  return res\n}\n\nBuffer.prototype.slice = function slice (start, end) {\n  var len = this.length\n  start = ~~start\n  end = end === undefined ? len : ~~end\n\n  if (start < 0) {\n    start += len\n    if (start < 0) start = 0\n  } else if (start > len) {\n    start = len\n  }\n\n  if (end < 0) {\n    end += len\n    if (end < 0) end = 0\n  } else if (end > len) {\n    end = len\n  }\n\n  if (end < start) end = start\n\n  var newBuf\n  if (Buffer.TYPED_ARRAY_SUPPORT) {\n    newBuf = this.subarray(start, end)\n    newBuf.__proto__ = Buffer.prototype\n  } else {\n    var sliceLen = end - start\n    newBuf = new Buffer(sliceLen, undefined)\n    for (var i = 0; i < sliceLen; ++i) {\n      newBuf[i] = this[i + start]\n    }\n  }\n\n  return newBuf\n}\n\n/*\n * Need to make sure that buffer isn't trying to write out of bounds.\n */\nfunction checkOffset (offset, ext, length) {\n  if ((offset % 1) !== 0 || offset < 0) throw new RangeError('offset is not uint')\n  if (offset + ext > length) throw new RangeError('Trying to access beyond buffer length')\n}\n\nBuffer.prototype.readUIntLE = function readUIntLE (offset, byteLength, noAssert) {\n  offset = offset | 0\n  byteLength = byteLength | 0\n  if (!noAssert) checkOffset(offset, byteLength, this.length)\n\n  var val = this[offset]\n  var mul = 1\n  var i = 0\n  while (++i < byteLength && (mul *= 0x100)) {\n    val += this[offset + i] * mul\n  }\n\n  return val\n}\n\nBuffer.prototype.readUIntBE = function readUIntBE (offset, byteLength, noAssert) {\n  offset = offset | 0\n  byteLength = byteLength | 0\n  if (!noAssert) {\n    checkOffset(offset, byteLength, this.length)\n  }\n\n  var val = this[offset + --byteLength]\n  var mul = 1\n  while (byteLength > 0 && (mul *= 0x100)) {\n    val += this[offset + --byteLength] * mul\n  }\n\n  return val\n}\n\nBuffer.prototype.readUInt8 = function readUInt8 (offset, noAssert) {\n  if (!noAssert) checkOffset(offset, 1, this.length)\n  return this[offset]\n}\n\nBuffer.prototype.readUInt16LE = function readUInt16LE (offset, noAssert) {\n  if (!noAssert) checkOffset(offset, 2, this.length)\n  return this[offset] | (this[offset + 1] << 8)\n}\n\nBuffer.prototype.readUInt16BE = function readUInt16BE (offset, noAssert) {\n  if (!noAssert) checkOffset(offset, 2, this.length)\n  return (this[offset] << 8) | this[offset + 1]\n}\n\nBuffer.prototype.readUInt32LE = function readUInt32LE (offset, noAssert) {\n  if (!noAssert) checkOffset(offset, 4, this.length)\n\n  return ((this[offset]) |\n      (this[offset + 1] << 8) |\n      (this[offset + 2] << 16)) +\n      (this[offset + 3] * 0x1000000)\n}\n\nBuffer.prototype.readUInt32BE = function readUInt32BE (offset, noAssert) {\n  if (!noAssert) checkOffset(offset, 4, this.length)\n\n  return (this[offset] * 0x1000000) +\n    ((this[offset + 1] << 16) |\n    (this[offset + 2] << 8) |\n    this[offset + 3])\n}\n\nBuffer.prototype.readIntLE = function readIntLE (offset, byteLength, noAssert) {\n  offset = offset | 0\n  byteLength = byteLength | 0\n  if (!noAssert) checkOffset(offset, byteLength, this.length)\n\n  var val = this[offset]\n  var mul = 1\n  var i = 0\n  while (++i < byteLength && (mul *= 0x100)) {\n    val += this[offset + i] * mul\n  }\n  mul *= 0x80\n\n  if (val >= mul) val -= Math.pow(2, 8 * byteLength)\n\n  return val\n}\n\nBuffer.prototype.readIntBE = function readIntBE (offset, byteLength, noAssert) {\n  offset = offset | 0\n  byteLength = byteLength | 0\n  if (!noAssert) checkOffset(offset, byteLength, this.length)\n\n  var i = byteLength\n  var mul = 1\n  var val = this[offset + --i]\n  while (i > 0 && (mul *= 0x100)) {\n    val += this[offset + --i] * mul\n  }\n  mul *= 0x80\n\n  if (val >= mul) val -= Math.pow(2, 8 * byteLength)\n\n  return val\n}\n\nBuffer.prototype.readInt8 = function readInt8 (offset, noAssert) {\n  if (!noAssert) checkOffset(offset, 1, this.length)\n  if (!(this[offset] & 0x80)) return (this[offset])\n  return ((0xff - this[offset] + 1) * -1)\n}\n\nBuffer.prototype.readInt16LE = function readInt16LE (offset, noAssert) {\n  if (!noAssert) checkOffset(offset, 2, this.length)\n  var val = this[offset] | (this[offset + 1] << 8)\n  return (val & 0x8000) ? val | 0xFFFF0000 : val\n}\n\nBuffer.prototype.readInt16BE = function readInt16BE (offset, noAssert) {\n  if (!noAssert) checkOffset(offset, 2, this.length)\n  var val = this[offset + 1] | (this[offset] << 8)\n  return (val & 0x8000) ? val | 0xFFFF0000 : val\n}\n\nBuffer.prototype.readInt32LE = function readInt32LE (offset, noAssert) {\n  if (!noAssert) checkOffset(offset, 4, this.length)\n\n  return (this[offset]) |\n    (this[offset + 1] << 8) |\n    (this[offset + 2] << 16) |\n    (this[offset + 3] << 24)\n}\n\nBuffer.prototype.readInt32BE = function readInt32BE (offset, noAssert) {\n  if (!noAssert) checkOffset(offset, 4, this.length)\n\n  return (this[offset] << 24) |\n    (this[offset + 1] << 16) |\n    (this[offset + 2] << 8) |\n    (this[offset + 3])\n}\n\nBuffer.prototype.readFloatLE = function readFloatLE (offset, noAssert) {\n  if (!noAssert) checkOffset(offset, 4, this.length)\n  return ieee754.read(this, offset, true, 23, 4)\n}\n\nBuffer.prototype.readFloatBE = function readFloatBE (offset, noAssert) {\n  if (!noAssert) checkOffset(offset, 4, this.length)\n  return ieee754.read(this, offset, false, 23, 4)\n}\n\nBuffer.prototype.readDoubleLE = function readDoubleLE (offset, noAssert) {\n  if (!noAssert) checkOffset(offset, 8, this.length)\n  return ieee754.read(this, offset, true, 52, 8)\n}\n\nBuffer.prototype.readDoubleBE = function readDoubleBE (offset, noAssert) {\n  if (!noAssert) checkOffset(offset, 8, this.length)\n  return ieee754.read(this, offset, false, 52, 8)\n}\n\nfunction checkInt (buf, value, offset, ext, max, min) {\n  if (!Buffer.isBuffer(buf)) throw new TypeError('\"buffer\" argument must be a Buffer instance')\n  if (value > max || value < min) throw new RangeError('\"value\" argument is out of bounds')\n  if (offset + ext > buf.length) throw new RangeError('Index out of range')\n}\n\nBuffer.prototype.writeUIntLE = function writeUIntLE (value, offset, byteLength, noAssert) {\n  value = +value\n  offset = offset | 0\n  byteLength = byteLength | 0\n  if (!noAssert) {\n    var maxBytes = Math.pow(2, 8 * byteLength) - 1\n    checkInt(this, value, offset, byteLength, maxBytes, 0)\n  }\n\n  var mul = 1\n  var i = 0\n  this[offset] = value & 0xFF\n  while (++i < byteLength && (mul *= 0x100)) {\n    this[offset + i] = (value / mul) & 0xFF\n  }\n\n  return offset + byteLength\n}\n\nBuffer.prototype.writeUIntBE = function writeUIntBE (value, offset, byteLength, noAssert) {\n  value = +value\n  offset = offset | 0\n  byteLength = byteLength | 0\n  if (!noAssert) {\n    var maxBytes = Math.pow(2, 8 * byteLength) - 1\n    checkInt(this, value, offset, byteLength, maxBytes, 0)\n  }\n\n  var i = byteLength - 1\n  var mul = 1\n  this[offset + i] = value & 0xFF\n  while (--i >= 0 && (mul *= 0x100)) {\n    this[offset + i] = (value / mul) & 0xFF\n  }\n\n  return offset + byteLength\n}\n\nBuffer.prototype.writeUInt8 = function writeUInt8 (value, offset, noAssert) {\n  value = +value\n  offset = offset | 0\n  if (!noAssert) checkInt(this, value, offset, 1, 0xff, 0)\n  if (!Buffer.TYPED_ARRAY_SUPPORT) value = Math.floor(value)\n  this[offset] = (value & 0xff)\n  return offset + 1\n}\n\nfunction objectWriteUInt16 (buf, value, offset, littleEndian) {\n  if (value < 0) value = 0xffff + value + 1\n  for (var i = 0, j = Math.min(buf.length - offset, 2); i < j; ++i) {\n    buf[offset + i] = (value & (0xff << (8 * (littleEndian ? i : 1 - i)))) >>>\n      (littleEndian ? i : 1 - i) * 8\n  }\n}\n\nBuffer.prototype.writeUInt16LE = function writeUInt16LE (value, offset, noAssert) {\n  value = +value\n  offset = offset | 0\n  if (!noAssert) checkInt(this, value, offset, 2, 0xffff, 0)\n  if (Buffer.TYPED_ARRAY_SUPPORT) {\n    this[offset] = (value & 0xff)\n    this[offset + 1] = (value >>> 8)\n  } else {\n    objectWriteUInt16(this, value, offset, true)\n  }\n  return offset + 2\n}\n\nBuffer.prototype.writeUInt16BE = function writeUInt16BE (value, offset, noAssert) {\n  value = +value\n  offset = offset | 0\n  if (!noAssert) checkInt(this, value, offset, 2, 0xffff, 0)\n  if (Buffer.TYPED_ARRAY_SUPPORT) {\n    this[offset] = (value >>> 8)\n    this[offset + 1] = (value & 0xff)\n  } else {\n    objectWriteUInt16(this, value, offset, false)\n  }\n  return offset + 2\n}\n\nfunction objectWriteUInt32 (buf, value, offset, littleEndian) {\n  if (value < 0) value = 0xffffffff + value + 1\n  for (var i = 0, j = Math.min(buf.length - offset, 4); i < j; ++i) {\n    buf[offset + i] = (value >>> (littleEndian ? i : 3 - i) * 8) & 0xff\n  }\n}\n\nBuffer.prototype.writeUInt32LE = function writeUInt32LE (value, offset, noAssert) {\n  value = +value\n  offset = offset | 0\n  if (!noAssert) checkInt(this, value, offset, 4, 0xffffffff, 0)\n  if (Buffer.TYPED_ARRAY_SUPPORT) {\n    this[offset + 3] = (value >>> 24)\n    this[offset + 2] = (value >>> 16)\n    this[offset + 1] = (value >>> 8)\n    this[offset] = (value & 0xff)\n  } else {\n    objectWriteUInt32(this, value, offset, true)\n  }\n  return offset + 4\n}\n\nBuffer.prototype.writeUInt32BE = function writeUInt32BE (value, offset, noAssert) {\n  value = +value\n  offset = offset | 0\n  if (!noAssert) checkInt(this, value, offset, 4, 0xffffffff, 0)\n  if (Buffer.TYPED_ARRAY_SUPPORT) {\n    this[offset] = (value >>> 24)\n    this[offset + 1] = (value >>> 16)\n    this[offset + 2] = (value >>> 8)\n    this[offset + 3] = (value & 0xff)\n  } else {\n    objectWriteUInt32(this, value, offset, false)\n  }\n  return offset + 4\n}\n\nBuffer.prototype.writeIntLE = function writeIntLE (value, offset, byteLength, noAssert) {\n  value = +value\n  offset = offset | 0\n  if (!noAssert) {\n    var limit = Math.pow(2, 8 * byteLength - 1)\n\n    checkInt(this, value, offset, byteLength, limit - 1, -limit)\n  }\n\n  var i = 0\n  var mul = 1\n  var sub = 0\n  this[offset] = value & 0xFF\n  while (++i < byteLength && (mul *= 0x100)) {\n    if (value < 0 && sub === 0 && this[offset + i - 1] !== 0) {\n      sub = 1\n    }\n    this[offset + i] = ((value / mul) >> 0) - sub & 0xFF\n  }\n\n  return offset + byteLength\n}\n\nBuffer.prototype.writeIntBE = function writeIntBE (value, offset, byteLength, noAssert) {\n  value = +value\n  offset = offset | 0\n  if (!noAssert) {\n    var limit = Math.pow(2, 8 * byteLength - 1)\n\n    checkInt(this, value, offset, byteLength, limit - 1, -limit)\n  }\n\n  var i = byteLength - 1\n  var mul = 1\n  var sub = 0\n  this[offset + i] = value & 0xFF\n  while (--i >= 0 && (mul *= 0x100)) {\n    if (value < 0 && sub === 0 && this[offset + i + 1] !== 0) {\n      sub = 1\n    }\n    this[offset + i] = ((value / mul) >> 0) - sub & 0xFF\n  }\n\n  return offset + byteLength\n}\n\nBuffer.prototype.writeInt8 = function writeInt8 (value, offset, noAssert) {\n  value = +value\n  offset = offset | 0\n  if (!noAssert) checkInt(this, value, offset, 1, 0x7f, -0x80)\n  if (!Buffer.TYPED_ARRAY_SUPPORT) value = Math.floor(value)\n  if (value < 0) value = 0xff + value + 1\n  this[offset] = (value & 0xff)\n  return offset + 1\n}\n\nBuffer.prototype.writeInt16LE = function writeInt16LE (value, offset, noAssert) {\n  value = +value\n  offset = offset | 0\n  if (!noAssert) checkInt(this, value, offset, 2, 0x7fff, -0x8000)\n  if (Buffer.TYPED_ARRAY_SUPPORT) {\n    this[offset] = (value & 0xff)\n    this[offset + 1] = (value >>> 8)\n  } else {\n    objectWriteUInt16(this, value, offset, true)\n  }\n  return offset + 2\n}\n\nBuffer.prototype.writeInt16BE = function writeInt16BE (value, offset, noAssert) {\n  value = +value\n  offset = offset | 0\n  if (!noAssert) checkInt(this, value, offset, 2, 0x7fff, -0x8000)\n  if (Buffer.TYPED_ARRAY_SUPPORT) {\n    this[offset] = (value >>> 8)\n    this[offset + 1] = (value & 0xff)\n  } else {\n    objectWriteUInt16(this, value, offset, false)\n  }\n  return offset + 2\n}\n\nBuffer.prototype.writeInt32LE = function writeInt32LE (value, offset, noAssert) {\n  value = +value\n  offset = offset | 0\n  if (!noAssert) checkInt(this, value, offset, 4, 0x7fffffff, -0x80000000)\n  if (Buffer.TYPED_ARRAY_SUPPORT) {\n    this[offset] = (value & 0xff)\n    this[offset + 1] = (value >>> 8)\n    this[offset + 2] = (value >>> 16)\n    this[offset + 3] = (value >>> 24)\n  } else {\n    objectWriteUInt32(this, value, offset, true)\n  }\n  return offset + 4\n}\n\nBuffer.prototype.writeInt32BE = function writeInt32BE (value, offset, noAssert) {\n  value = +value\n  offset = offset | 0\n  if (!noAssert) checkInt(this, value, offset, 4, 0x7fffffff, -0x80000000)\n  if (value < 0) value = 0xffffffff + value + 1\n  if (Buffer.TYPED_ARRAY_SUPPORT) {\n    this[offset] = (value >>> 24)\n    this[offset + 1] = (value >>> 16)\n    this[offset + 2] = (value >>> 8)\n    this[offset + 3] = (value & 0xff)\n  } else {\n    objectWriteUInt32(this, value, offset, false)\n  }\n  return offset + 4\n}\n\nfunction checkIEEE754 (buf, value, offset, ext, max, min) {\n  if (offset + ext > buf.length) throw new RangeError('Index out of range')\n  if (offset < 0) throw new RangeError('Index out of range')\n}\n\nfunction writeFloat (buf, value, offset, littleEndian, noAssert) {\n  if (!noAssert) {\n    checkIEEE754(buf, value, offset, 4, 3.4028234663852886e+38, -3.4028234663852886e+38)\n  }\n  ieee754.write(buf, value, offset, littleEndian, 23, 4)\n  return offset + 4\n}\n\nBuffer.prototype.writeFloatLE = function writeFloatLE (value, offset, noAssert) {\n  return writeFloat(this, value, offset, true, noAssert)\n}\n\nBuffer.prototype.writeFloatBE = function writeFloatBE (value, offset, noAssert) {\n  return writeFloat(this, value, offset, false, noAssert)\n}\n\nfunction writeDouble (buf, value, offset, littleEndian, noAssert) {\n  if (!noAssert) {\n    checkIEEE754(buf, value, offset, 8, 1.7976931348623157E+308, -1.7976931348623157E+308)\n  }\n  ieee754.write(buf, value, offset, littleEndian, 52, 8)\n  return offset + 8\n}\n\nBuffer.prototype.writeDoubleLE = function writeDoubleLE (value, offset, noAssert) {\n  return writeDouble(this, value, offset, true, noAssert)\n}\n\nBuffer.prototype.writeDoubleBE = function writeDoubleBE (value, offset, noAssert) {\n  return writeDouble(this, value, offset, false, noAssert)\n}\n\n// copy(targetBuffer, targetStart=0, sourceStart=0, sourceEnd=buffer.length)\nBuffer.prototype.copy = function copy (target, targetStart, start, end) {\n  if (!start) start = 0\n  if (!end && end !== 0) end = this.length\n  if (targetStart >= target.length) targetStart = target.length\n  if (!targetStart) targetStart = 0\n  if (end > 0 && end < start) end = start\n\n  // Copy 0 bytes; we're done\n  if (end === start) return 0\n  if (target.length === 0 || this.length === 0) return 0\n\n  // Fatal error conditions\n  if (targetStart < 0) {\n    throw new RangeError('targetStart out of bounds')\n  }\n  if (start < 0 || start >= this.length) throw new RangeError('sourceStart out of bounds')\n  if (end < 0) throw new RangeError('sourceEnd out of bounds')\n\n  // Are we oob?\n  if (end > this.length) end = this.length\n  if (target.length - targetStart < end - start) {\n    end = target.length - targetStart + start\n  }\n\n  var len = end - start\n  var i\n\n  if (this === target && start < targetStart && targetStart < end) {\n    // descending copy from end\n    for (i = len - 1; i >= 0; --i) {\n      target[i + targetStart] = this[i + start]\n    }\n  } else if (len < 1000 || !Buffer.TYPED_ARRAY_SUPPORT) {\n    // ascending copy from start\n    for (i = 0; i < len; ++i) {\n      target[i + targetStart] = this[i + start]\n    }\n  } else {\n    Uint8Array.prototype.set.call(\n      target,\n      this.subarray(start, start + len),\n      targetStart\n    )\n  }\n\n  return len\n}\n\n// Usage:\n//    buffer.fill(number[, offset[, end]])\n//    buffer.fill(buffer[, offset[, end]])\n//    buffer.fill(string[, offset[, end]][, encoding])\nBuffer.prototype.fill = function fill (val, start, end, encoding) {\n  // Handle string cases:\n  if (typeof val === 'string') {\n    if (typeof start === 'string') {\n      encoding = start\n      start = 0\n      end = this.length\n    } else if (typeof end === 'string') {\n      encoding = end\n      end = this.length\n    }\n    if (val.length === 1) {\n      var code = val.charCodeAt(0)\n      if (code < 256) {\n        val = code\n      }\n    }\n    if (encoding !== undefined && typeof encoding !== 'string') {\n      throw new TypeError('encoding must be a string')\n    }\n    if (typeof encoding === 'string' && !Buffer.isEncoding(encoding)) {\n      throw new TypeError('Unknown encoding: ' + encoding)\n    }\n  } else if (typeof val === 'number') {\n    val = val & 255\n  }\n\n  // Invalid ranges are not set to a default, so can range check early.\n  if (start < 0 || this.length < start || this.length < end) {\n    throw new RangeError('Out of range index')\n  }\n\n  if (end <= start) {\n    return this\n  }\n\n  start = start >>> 0\n  end = end === undefined ? this.length : end >>> 0\n\n  if (!val) val = 0\n\n  var i\n  if (typeof val === 'number') {\n    for (i = start; i < end; ++i) {\n      this[i] = val\n    }\n  } else {\n    var bytes = Buffer.isBuffer(val)\n      ? val\n      : utf8ToBytes(new Buffer(val, encoding).toString())\n    var len = bytes.length\n    for (i = 0; i < end - start; ++i) {\n      this[i + start] = bytes[i % len]\n    }\n  }\n\n  return this\n}\n\n// HELPER FUNCTIONS\n// ================\n\nvar INVALID_BASE64_RE = /[^+\\/0-9A-Za-z-_]/g\n\nfunction base64clean (str) {\n  // Node strips out invalid characters like \\n and \\t from the string, base64-js does not\n  str = stringtrim(str).replace(INVALID_BASE64_RE, '')\n  // Node converts strings with length < 2 to ''\n  if (str.length < 2) return ''\n  // Node allows for non-padded base64 strings (missing trailing ===), base64-js does not\n  while (str.length % 4 !== 0) {\n    str = str + '='\n  }\n  return str\n}\n\nfunction stringtrim (str) {\n  if (str.trim) return str.trim()\n  return str.replace(/^\\s+|\\s+$/g, '')\n}\n\nfunction toHex (n) {\n  if (n < 16) return '0' + n.toString(16)\n  return n.toString(16)\n}\n\nfunction utf8ToBytes (string, units) {\n  units = units || Infinity\n  var codePoint\n  var length = string.length\n  var leadSurrogate = null\n  var bytes = []\n\n  for (var i = 0; i < length; ++i) {\n    codePoint = string.charCodeAt(i)\n\n    // is surrogate component\n    if (codePoint > 0xD7FF && codePoint < 0xE000) {\n      // last char was a lead\n      if (!leadSurrogate) {\n        // no lead yet\n        if (codePoint > 0xDBFF) {\n          // unexpected trail\n          if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD)\n          continue\n        } else if (i + 1 === length) {\n          // unpaired lead\n          if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD)\n          continue\n        }\n\n        // valid lead\n        leadSurrogate = codePoint\n\n        continue\n      }\n\n      // 2 leads in a row\n      if (codePoint < 0xDC00) {\n        if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD)\n        leadSurrogate = codePoint\n        continue\n      }\n\n      // valid surrogate pair\n      codePoint = (leadSurrogate - 0xD800 << 10 | codePoint - 0xDC00) + 0x10000\n    } else if (leadSurrogate) {\n      // valid bmp char, but last char was a lead\n      if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD)\n    }\n\n    leadSurrogate = null\n\n    // encode utf8\n    if (codePoint < 0x80) {\n      if ((units -= 1) < 0) break\n      bytes.push(codePoint)\n    } else if (codePoint < 0x800) {\n      if ((units -= 2) < 0) break\n      bytes.push(\n        codePoint >> 0x6 | 0xC0,\n        codePoint & 0x3F | 0x80\n      )\n    } else if (codePoint < 0x10000) {\n      if ((units -= 3) < 0) break\n      bytes.push(\n        codePoint >> 0xC | 0xE0,\n        codePoint >> 0x6 & 0x3F | 0x80,\n        codePoint & 0x3F | 0x80\n      )\n    } else if (codePoint < 0x110000) {\n      if ((units -= 4) < 0) break\n      bytes.push(\n        codePoint >> 0x12 | 0xF0,\n        codePoint >> 0xC & 0x3F | 0x80,\n        codePoint >> 0x6 & 0x3F | 0x80,\n        codePoint & 0x3F | 0x80\n      )\n    } else {\n      throw new Error('Invalid code point')\n    }\n  }\n\n  return bytes\n}\n\nfunction asciiToBytes (str) {\n  var byteArray = []\n  for (var i = 0; i < str.length; ++i) {\n    // Node's code seems to be doing this and not & 0x7F..\n    byteArray.push(str.charCodeAt(i) & 0xFF)\n  }\n  return byteArray\n}\n\nfunction utf16leToBytes (str, units) {\n  var c, hi, lo\n  var byteArray = []\n  for (var i = 0; i < str.length; ++i) {\n    if ((units -= 2) < 0) break\n\n    c = str.charCodeAt(i)\n    hi = c >> 8\n    lo = c % 256\n    byteArray.push(lo)\n    byteArray.push(hi)\n  }\n\n  return byteArray\n}\n\nfunction base64ToBytes (str) {\n  return base64.toByteArray(base64clean(str))\n}\n\nfunction blitBuffer (src, dst, offset, length) {\n  for (var i = 0; i < length; ++i) {\n    if ((i + offset >= dst.length) || (i >= src.length)) break\n    dst[i + offset] = src[i]\n  }\n  return i\n}\n\nfunction isnan (val) {\n  return val !== val // eslint-disable-line no-self-compare\n}\n\n}).call(this,typeof global !== \"undefined\" ? global : typeof self !== \"undefined\" ? self : typeof window !== \"undefined\" ? window : {})\n},{\"base64-js\":39,\"ieee754\":50,\"isarray\":53}],45:[function(require,module,exports){\n(function (Buffer){\n// Copyright Joyent, Inc. and other Node contributors.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a\n// copy of this software and associated documentation files (the\n// \"Software\"), to deal in the Software without restriction, including\n// without limitation the rights to use, copy, modify, merge, publish,\n// distribute, sublicense, and/or sell copies of the Software, and to permit\n// persons to whom the Software is furnished to do so, subject to the\n// following conditions:\n//\n// The above copyright notice and this permission notice shall be included\n// in all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS\n// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN\n// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,\n// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE\n// USE OR OTHER DEALINGS IN THE SOFTWARE.\n\n// NOTE: These type checking functions intentionally don't use `instanceof`\n// because it is fragile and can be easily faked with `Object.create()`.\n\nfunction isArray(arg) {\n  if (Array.isArray) {\n    return Array.isArray(arg);\n  }\n  return objectToString(arg) === '[object Array]';\n}\nexports.isArray = isArray;\n\nfunction isBoolean(arg) {\n  return typeof arg === 'boolean';\n}\nexports.isBoolean = isBoolean;\n\nfunction isNull(arg) {\n  return arg === null;\n}\nexports.isNull = isNull;\n\nfunction isNullOrUndefined(arg) {\n  return arg == null;\n}\nexports.isNullOrUndefined = isNullOrUndefined;\n\nfunction isNumber(arg) {\n  return typeof arg === 'number';\n}\nexports.isNumber = isNumber;\n\nfunction isString(arg) {\n  return typeof arg === 'string';\n}\nexports.isString = isString;\n\nfunction isSymbol(arg) {\n  return typeof arg === 'symbol';\n}\nexports.isSymbol = isSymbol;\n\nfunction isUndefined(arg) {\n  return arg === void 0;\n}\nexports.isUndefined = isUndefined;\n\nfunction isRegExp(re) {\n  return objectToString(re) === '[object RegExp]';\n}\nexports.isRegExp = isRegExp;\n\nfunction isObject(arg) {\n  return typeof arg === 'object' && arg !== null;\n}\nexports.isObject = isObject;\n\nfunction isDate(d) {\n  return objectToString(d) === '[object Date]';\n}\nexports.isDate = isDate;\n\nfunction isError(e) {\n  return (objectToString(e) === '[object Error]' || e instanceof Error);\n}\nexports.isError = isError;\n\nfunction isFunction(arg) {\n  return typeof arg === 'function';\n}\nexports.isFunction = isFunction;\n\nfunction isPrimitive(arg) {\n  return arg === null ||\n         typeof arg === 'boolean' ||\n         typeof arg === 'number' ||\n         typeof arg === 'string' ||\n         typeof arg === 'symbol' ||  // ES6 symbol\n         typeof arg === 'undefined';\n}\nexports.isPrimitive = isPrimitive;\n\nexports.isBuffer = Buffer.isBuffer;\n\nfunction objectToString(o) {\n  return Object.prototype.toString.call(o);\n}\n\n}).call(this,{\"isBuffer\":require(\"../../is-buffer/index.js\")})\n},{\"../../is-buffer/index.js\":52}],46:[function(require,module,exports){\n/* See LICENSE file for terms of use */\n\n/*\n * Text diff implementation.\n *\n * This library supports the following APIS:\n * JsDiff.diffChars: Character by character diff\n * JsDiff.diffWords: Word (as defined by \\b regex) diff which ignores whitespace\n * JsDiff.diffLines: Line based diff\n *\n * JsDiff.diffCss: Diff targeted at CSS content\n *\n * These methods are based on the implementation proposed in\n * \"An O(ND) Difference Algorithm and its Variations\" (Myers, 1986).\n * http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.4.6927\n */\n(function(global, undefined) {\n  var objectPrototypeToString = Object.prototype.toString;\n\n  /*istanbul ignore next*/\n  function map(arr, mapper, that) {\n    if (Array.prototype.map) {\n      return Array.prototype.map.call(arr, mapper, that);\n    }\n\n    var other = new Array(arr.length);\n\n    for (var i = 0, n = arr.length; i < n; i++) {\n      other[i] = mapper.call(that, arr[i], i, arr);\n    }\n    return other;\n  }\n  function clonePath(path) {\n    return { newPos: path.newPos, components: path.components.slice(0) };\n  }\n  function removeEmpty(array) {\n    var ret = [];\n    for (var i = 0; i < array.length; i++) {\n      if (array[i]) {\n        ret.push(array[i]);\n      }\n    }\n    return ret;\n  }\n  function escapeHTML(s) {\n    var n = s;\n    n = n.replace(/&/g, '&amp;');\n    n = n.replace(/</g, '&lt;');\n    n = n.replace(/>/g, '&gt;');\n    n = n.replace(/\"/g, '&quot;');\n\n    return n;\n  }\n\n  // This function handles the presence of circular references by bailing out when encountering an\n  // object that is already on the \"stack\" of items being processed.\n  function canonicalize(obj, stack, replacementStack) {\n    stack = stack || [];\n    replacementStack = replacementStack || [];\n\n    var i;\n\n    for (i = 0; i < stack.length; i += 1) {\n      if (stack[i] === obj) {\n        return replacementStack[i];\n      }\n    }\n\n    var canonicalizedObj;\n\n    if ('[object Array]' === objectPrototypeToString.call(obj)) {\n      stack.push(obj);\n      canonicalizedObj = new Array(obj.length);\n      replacementStack.push(canonicalizedObj);\n      for (i = 0; i < obj.length; i += 1) {\n        canonicalizedObj[i] = canonicalize(obj[i], stack, replacementStack);\n      }\n      stack.pop();\n      replacementStack.pop();\n    } else if (typeof obj === 'object' && obj !== null) {\n      stack.push(obj);\n      canonicalizedObj = {};\n      replacementStack.push(canonicalizedObj);\n      var sortedKeys = [],\n          key;\n      for (key in obj) {\n        sortedKeys.push(key);\n      }\n      sortedKeys.sort();\n      for (i = 0; i < sortedKeys.length; i += 1) {\n        key = sortedKeys[i];\n        canonicalizedObj[key] = canonicalize(obj[key], stack, replacementStack);\n      }\n      stack.pop();\n      replacementStack.pop();\n    } else {\n      canonicalizedObj = obj;\n    }\n    return canonicalizedObj;\n  }\n\n  function buildValues(components, newString, oldString, useLongestToken) {\n    var componentPos = 0,\n        componentLen = components.length,\n        newPos = 0,\n        oldPos = 0;\n\n    for (; componentPos < componentLen; componentPos++) {\n      var component = components[componentPos];\n      if (!component.removed) {\n        if (!component.added && useLongestToken) {\n          var value = newString.slice(newPos, newPos + component.count);\n          value = map(value, function(value, i) {\n            var oldValue = oldString[oldPos + i];\n            return oldValue.length > value.length ? oldValue : value;\n          });\n\n          component.value = value.join('');\n        } else {\n          component.value = newString.slice(newPos, newPos + component.count).join('');\n        }\n        newPos += component.count;\n\n        // Common case\n        if (!component.added) {\n          oldPos += component.count;\n        }\n      } else {\n        component.value = oldString.slice(oldPos, oldPos + component.count).join('');\n        oldPos += component.count;\n\n        // Reverse add and remove so removes are output first to match common convention\n        // The diffing algorithm is tied to add then remove output and this is the simplest\n        // route to get the desired output with minimal overhead.\n        if (componentPos && components[componentPos - 1].added) {\n          var tmp = components[componentPos - 1];\n          components[componentPos - 1] = components[componentPos];\n          components[componentPos] = tmp;\n        }\n      }\n    }\n\n    return components;\n  }\n\n  function Diff(ignoreWhitespace) {\n    this.ignoreWhitespace = ignoreWhitespace;\n  }\n  Diff.prototype = {\n    diff: function(oldString, newString, callback) {\n      var self = this;\n\n      function done(value) {\n        if (callback) {\n          setTimeout(function() { callback(undefined, value); }, 0);\n          return true;\n        } else {\n          return value;\n        }\n      }\n\n      // Handle the identity case (this is due to unrolling editLength == 0\n      if (newString === oldString) {\n        return done([{ value: newString }]);\n      }\n      if (!newString) {\n        return done([{ value: oldString, removed: true }]);\n      }\n      if (!oldString) {\n        return done([{ value: newString, added: true }]);\n      }\n\n      newString = this.tokenize(newString);\n      oldString = this.tokenize(oldString);\n\n      var newLen = newString.length, oldLen = oldString.length;\n      var editLength = 1;\n      var maxEditLength = newLen + oldLen;\n      var bestPath = [{ newPos: -1, components: [] }];\n\n      // Seed editLength = 0, i.e. the content starts with the same values\n      var oldPos = this.extractCommon(bestPath[0], newString, oldString, 0);\n      if (bestPath[0].newPos + 1 >= newLen && oldPos + 1 >= oldLen) {\n        // Identity per the equality and tokenizer\n        return done([{value: newString.join('')}]);\n      }\n\n      // Main worker method. checks all permutations of a given edit length for acceptance.\n      function execEditLength() {\n        for (var diagonalPath = -1 * editLength; diagonalPath <= editLength; diagonalPath += 2) {\n          var basePath;\n          var addPath = bestPath[diagonalPath - 1],\n              removePath = bestPath[diagonalPath + 1],\n              oldPos = (removePath ? removePath.newPos : 0) - diagonalPath;\n          if (addPath) {\n            // No one else is going to attempt to use this value, clear it\n            bestPath[diagonalPath - 1] = undefined;\n          }\n\n          var canAdd = addPath && addPath.newPos + 1 < newLen,\n              canRemove = removePath && 0 <= oldPos && oldPos < oldLen;\n          if (!canAdd && !canRemove) {\n            // If this path is a terminal then prune\n            bestPath[diagonalPath] = undefined;\n            continue;\n          }\n\n          // Select the diagonal that we want to branch from. We select the prior\n          // path whose position in the new string is the farthest from the origin\n          // and does not pass the bounds of the diff graph\n          if (!canAdd || (canRemove && addPath.newPos < removePath.newPos)) {\n            basePath = clonePath(removePath);\n            self.pushComponent(basePath.components, undefined, true);\n          } else {\n            basePath = addPath;   // No need to clone, we've pulled it from the list\n            basePath.newPos++;\n            self.pushComponent(basePath.components, true, undefined);\n          }\n\n          oldPos = self.extractCommon(basePath, newString, oldString, diagonalPath);\n\n          // If we have hit the end of both strings, then we are done\n          if (basePath.newPos + 1 >= newLen && oldPos + 1 >= oldLen) {\n            return done(buildValues(basePath.components, newString, oldString, self.useLongestToken));\n          } else {\n            // Otherwise track this path as a potential candidate and continue.\n            bestPath[diagonalPath] = basePath;\n          }\n        }\n\n        editLength++;\n      }\n\n      // Performs the length of edit iteration. Is a bit fugly as this has to support the\n      // sync and async mode which is never fun. Loops over execEditLength until a value\n      // is produced.\n      if (callback) {\n        (function exec() {\n          setTimeout(function() {\n            // This should not happen, but we want to be safe.\n            /*istanbul ignore next */\n            if (editLength > maxEditLength) {\n              return callback();\n            }\n\n            if (!execEditLength()) {\n              exec();\n            }\n          }, 0);\n        }());\n      } else {\n        while (editLength <= maxEditLength) {\n          var ret = execEditLength();\n          if (ret) {\n            return ret;\n          }\n        }\n      }\n    },\n\n    pushComponent: function(components, added, removed) {\n      var last = components[components.length - 1];\n      if (last && last.added === added && last.removed === removed) {\n        // We need to clone here as the component clone operation is just\n        // as shallow array clone\n        components[components.length - 1] = {count: last.count + 1, added: added, removed: removed };\n      } else {\n        components.push({count: 1, added: added, removed: removed });\n      }\n    },\n    extractCommon: function(basePath, newString, oldString, diagonalPath) {\n      var newLen = newString.length,\n          oldLen = oldString.length,\n          newPos = basePath.newPos,\n          oldPos = newPos - diagonalPath,\n\n          commonCount = 0;\n      while (newPos + 1 < newLen && oldPos + 1 < oldLen && this.equals(newString[newPos + 1], oldString[oldPos + 1])) {\n        newPos++;\n        oldPos++;\n        commonCount++;\n      }\n\n      if (commonCount) {\n        basePath.components.push({count: commonCount});\n      }\n\n      basePath.newPos = newPos;\n      return oldPos;\n    },\n\n    equals: function(left, right) {\n      var reWhitespace = /\\S/;\n      return left === right || (this.ignoreWhitespace && !reWhitespace.test(left) && !reWhitespace.test(right));\n    },\n    tokenize: function(value) {\n      return value.split('');\n    }\n  };\n\n  var CharDiff = new Diff();\n\n  var WordDiff = new Diff(true);\n  var WordWithSpaceDiff = new Diff();\n  WordDiff.tokenize = WordWithSpaceDiff.tokenize = function(value) {\n    return removeEmpty(value.split(/(\\s+|\\b)/));\n  };\n\n  var CssDiff = new Diff(true);\n  CssDiff.tokenize = function(value) {\n    return removeEmpty(value.split(/([{}:;,]|\\s+)/));\n  };\n\n  var LineDiff = new Diff();\n\n  var TrimmedLineDiff = new Diff();\n  TrimmedLineDiff.ignoreTrim = true;\n\n  LineDiff.tokenize = TrimmedLineDiff.tokenize = function(value) {\n    var retLines = [],\n        lines = value.split(/^/m);\n    for (var i = 0; i < lines.length; i++) {\n      var line = lines[i],\n          lastLine = lines[i - 1],\n          lastLineLastChar = lastLine && lastLine[lastLine.length - 1];\n\n      // Merge lines that may contain windows new lines\n      if (line === '\\n' && lastLineLastChar === '\\r') {\n          retLines[retLines.length - 1] = retLines[retLines.length - 1].slice(0, -1) + '\\r\\n';\n      } else {\n        if (this.ignoreTrim) {\n          line = line.trim();\n          // add a newline unless this is the last line.\n          if (i < lines.length - 1) {\n            line += '\\n';\n          }\n        }\n        retLines.push(line);\n      }\n    }\n\n    return retLines;\n  };\n\n  var PatchDiff = new Diff();\n  PatchDiff.tokenize = function(value) {\n    var ret = [],\n        linesAndNewlines = value.split(/(\\n|\\r\\n)/);\n\n    // Ignore the final empty token that occurs if the string ends with a new line\n    if (!linesAndNewlines[linesAndNewlines.length - 1]) {\n      linesAndNewlines.pop();\n    }\n\n    // Merge the content and line separators into single tokens\n    for (var i = 0; i < linesAndNewlines.length; i++) {\n      var line = linesAndNewlines[i];\n\n      if (i % 2) {\n        ret[ret.length - 1] += line;\n      } else {\n        ret.push(line);\n      }\n    }\n    return ret;\n  };\n\n  var SentenceDiff = new Diff();\n  SentenceDiff.tokenize = function(value) {\n    return removeEmpty(value.split(/(\\S.+?[.!?])(?=\\s+|$)/));\n  };\n\n  var JsonDiff = new Diff();\n  // Discriminate between two lines of pretty-printed, serialized JSON where one of them has a\n  // dangling comma and the other doesn't. Turns out including the dangling comma yields the nicest output:\n  JsonDiff.useLongestToken = true;\n  JsonDiff.tokenize = LineDiff.tokenize;\n  JsonDiff.equals = function(left, right) {\n    return LineDiff.equals(left.replace(/,([\\r\\n])/g, '$1'), right.replace(/,([\\r\\n])/g, '$1'));\n  };\n\n  var JsDiff = {\n    Diff: Diff,\n\n    diffChars: function(oldStr, newStr, callback) { return CharDiff.diff(oldStr, newStr, callback); },\n    diffWords: function(oldStr, newStr, callback) { return WordDiff.diff(oldStr, newStr, callback); },\n    diffWordsWithSpace: function(oldStr, newStr, callback) { return WordWithSpaceDiff.diff(oldStr, newStr, callback); },\n    diffLines: function(oldStr, newStr, callback) { return LineDiff.diff(oldStr, newStr, callback); },\n    diffTrimmedLines: function(oldStr, newStr, callback) { return TrimmedLineDiff.diff(oldStr, newStr, callback); },\n\n    diffSentences: function(oldStr, newStr, callback) { return SentenceDiff.diff(oldStr, newStr, callback); },\n\n    diffCss: function(oldStr, newStr, callback) { return CssDiff.diff(oldStr, newStr, callback); },\n    diffJson: function(oldObj, newObj, callback) {\n      return JsonDiff.diff(\n        typeof oldObj === 'string' ? oldObj : JSON.stringify(canonicalize(oldObj), undefined, '  '),\n        typeof newObj === 'string' ? newObj : JSON.stringify(canonicalize(newObj), undefined, '  '),\n        callback\n      );\n    },\n\n    createTwoFilesPatch: function(oldFileName, newFileName, oldStr, newStr, oldHeader, newHeader) {\n      var ret = [];\n\n      if (oldFileName == newFileName) {\n        ret.push('Index: ' + oldFileName);\n      }\n      ret.push('===================================================================');\n      ret.push('--- ' + oldFileName + (typeof oldHeader === 'undefined' ? '' : '\\t' + oldHeader));\n      ret.push('+++ ' + newFileName + (typeof newHeader === 'undefined' ? '' : '\\t' + newHeader));\n\n      var diff = PatchDiff.diff(oldStr, newStr);\n      diff.push({value: '', lines: []});   // Append an empty value to make cleanup easier\n\n      // Formats a given set of lines for printing as context lines in a patch\n      function contextLines(lines) {\n        return map(lines, function(entry) { return ' ' + entry; });\n      }\n\n      // Outputs the no newline at end of file warning if needed\n      function eofNL(curRange, i, current) {\n        var last = diff[diff.length - 2],\n            isLast = i === diff.length - 2,\n            isLastOfType = i === diff.length - 3 && current.added !== last.added;\n\n        // Figure out if this is the last line for the given file and missing NL\n        if (!(/\\n$/.test(current.value)) && (isLast || isLastOfType)) {\n          curRange.push('\\\\ No newline at end of file');\n        }\n      }\n\n      var oldRangeStart = 0, newRangeStart = 0, curRange = [],\n          oldLine = 1, newLine = 1;\n      for (var i = 0; i < diff.length; i++) {\n        var current = diff[i],\n            lines = current.lines || current.value.replace(/\\n$/, '').split('\\n');\n        current.lines = lines;\n\n        if (current.added || current.removed) {\n          // If we have previous context, start with that\n          if (!oldRangeStart) {\n            var prev = diff[i - 1];\n            oldRangeStart = oldLine;\n            newRangeStart = newLine;\n\n            if (prev) {\n              curRange = contextLines(prev.lines.slice(-4));\n              oldRangeStart -= curRange.length;\n              newRangeStart -= curRange.length;\n            }\n          }\n\n          // Output our changes\n          curRange.push.apply(curRange, map(lines, function(entry) {\n            return (current.added ? '+' : '-') + entry;\n          }));\n          eofNL(curRange, i, current);\n\n          // Track the updated file position\n          if (current.added) {\n            newLine += lines.length;\n          } else {\n            oldLine += lines.length;\n          }\n        } else {\n          // Identical context lines. Track line changes\n          if (oldRangeStart) {\n            // Close out any changes that have been output (or join overlapping)\n            if (lines.length <= 8 && i < diff.length - 2) {\n              // Overlapping\n              curRange.push.apply(curRange, contextLines(lines));\n            } else {\n              // end the range and output\n              var contextSize = Math.min(lines.length, 4);\n              ret.push(\n                  '@@ -' + oldRangeStart + ',' + (oldLine - oldRangeStart + contextSize)\n                  + ' +' + newRangeStart + ',' + (newLine - newRangeStart + contextSize)\n                  + ' @@');\n              ret.push.apply(ret, curRange);\n              ret.push.apply(ret, contextLines(lines.slice(0, contextSize)));\n              if (lines.length <= 4) {\n                eofNL(ret, i, current);\n              }\n\n              oldRangeStart = 0;\n              newRangeStart = 0;\n              curRange = [];\n            }\n          }\n          oldLine += lines.length;\n          newLine += lines.length;\n        }\n      }\n\n      return ret.join('\\n') + '\\n';\n    },\n\n    createPatch: function(fileName, oldStr, newStr, oldHeader, newHeader) {\n      return JsDiff.createTwoFilesPatch(fileName, fileName, oldStr, newStr, oldHeader, newHeader);\n    },\n\n    applyPatch: function(oldStr, uniDiff) {\n      var diffstr = uniDiff.split('\\n'),\n          hunks = [],\n          i = 0,\n          remEOFNL = false,\n          addEOFNL = false;\n\n      // Skip to the first change hunk\n      while (i < diffstr.length && !(/^@@/.test(diffstr[i]))) {\n        i++;\n      }\n\n      // Parse the unified diff\n      for (; i < diffstr.length; i++) {\n        if (diffstr[i][0] === '@') {\n          var chnukHeader = diffstr[i].split(/@@ -(\\d+),(\\d+) \\+(\\d+),(\\d+) @@/);\n          hunks.unshift({\n            start: chnukHeader[3],\n            oldlength: +chnukHeader[2],\n            removed: [],\n            newlength: chnukHeader[4],\n            added: []\n          });\n        } else if (diffstr[i][0] === '+') {\n          hunks[0].added.push(diffstr[i].substr(1));\n        } else if (diffstr[i][0] === '-') {\n          hunks[0].removed.push(diffstr[i].substr(1));\n        } else if (diffstr[i][0] === ' ') {\n          hunks[0].added.push(diffstr[i].substr(1));\n          hunks[0].removed.push(diffstr[i].substr(1));\n        } else if (diffstr[i][0] === '\\\\') {\n          if (diffstr[i - 1][0] === '+') {\n            remEOFNL = true;\n          } else if (diffstr[i - 1][0] === '-') {\n            addEOFNL = true;\n          }\n        }\n      }\n\n      // Apply the diff to the input\n      var lines = oldStr.split('\\n');\n      for (i = hunks.length - 1; i >= 0; i--) {\n        var hunk = hunks[i];\n        // Sanity check the input string. Bail if we don't match.\n        for (var j = 0; j < hunk.oldlength; j++) {\n          if (lines[hunk.start - 1 + j] !== hunk.removed[j]) {\n            return false;\n          }\n        }\n        Array.prototype.splice.apply(lines, [hunk.start - 1, hunk.oldlength].concat(hunk.added));\n      }\n\n      // Handle EOFNL insertion/removal\n      if (remEOFNL) {\n        while (!lines[lines.length - 1]) {\n          lines.pop();\n        }\n      } else if (addEOFNL) {\n        lines.push('');\n      }\n      return lines.join('\\n');\n    },\n\n    convertChangesToXML: function(changes) {\n      var ret = [];\n      for (var i = 0; i < changes.length; i++) {\n        var change = changes[i];\n        if (change.added) {\n          ret.push('<ins>');\n        } else if (change.removed) {\n          ret.push('<del>');\n        }\n\n        ret.push(escapeHTML(change.value));\n\n        if (change.added) {\n          ret.push('</ins>');\n        } else if (change.removed) {\n          ret.push('</del>');\n        }\n      }\n      return ret.join('');\n    },\n\n    // See: http://code.google.com/p/google-diff-match-patch/wiki/API\n    convertChangesToDMP: function(changes) {\n      var ret = [],\n          change,\n          operation;\n      for (var i = 0; i < changes.length; i++) {\n        change = changes[i];\n        if (change.added) {\n          operation = 1;\n        } else if (change.removed) {\n          operation = -1;\n        } else {\n          operation = 0;\n        }\n\n        ret.push([operation, change.value]);\n      }\n      return ret;\n    },\n\n    canonicalize: canonicalize\n  };\n\n  /*istanbul ignore next */\n  /*global module */\n  if (typeof module !== 'undefined' && module.exports) {\n    module.exports = JsDiff;\n  } else if (false) {\n    /*global define */\n    define([], function() { return JsDiff; });\n  } else if (typeof global.JsDiff === 'undefined') {\n    global.JsDiff = JsDiff;\n  }\n}(this));\n\n},{}],47:[function(require,module,exports){\n'use strict';\n\nvar matchOperatorsRe = /[|\\\\{}()[\\]^$+*?.]/g;\n\nmodule.exports = function (str) {\n\tif (typeof str !== 'string') {\n\t\tthrow new TypeError('Expected a string');\n\t}\n\n\treturn str.replace(matchOperatorsRe, '\\\\$&');\n};\n\n},{}],48:[function(require,module,exports){\n// Copyright Joyent, Inc. and other Node contributors.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a\n// copy of this software and associated documentation files (the\n// \"Software\"), to deal in the Software without restriction, including\n// without limitation the rights to use, copy, modify, merge, publish,\n// distribute, sublicense, and/or sell copies of the Software, and to permit\n// persons to whom the Software is furnished to do so, subject to the\n// following conditions:\n//\n// The above copyright notice and this permission notice shall be included\n// in all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS\n// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN\n// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,\n// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE\n// USE OR OTHER DEALINGS IN THE SOFTWARE.\n\nfunction EventEmitter() {\n  this._events = this._events || {};\n  this._maxListeners = this._maxListeners || undefined;\n}\nmodule.exports = EventEmitter;\n\n// Backwards-compat with node 0.10.x\nEventEmitter.EventEmitter = EventEmitter;\n\nEventEmitter.prototype._events = undefined;\nEventEmitter.prototype._maxListeners = undefined;\n\n// By default EventEmitters will print a warning if more than 10 listeners are\n// added to it. This is a useful default which helps finding memory leaks.\nEventEmitter.defaultMaxListeners = 10;\n\n// Obviously not all Emitters should be limited to 10. This function allows\n// that to be increased. Set to zero for unlimited.\nEventEmitter.prototype.setMaxListeners = function(n) {\n  if (!isNumber(n) || n < 0 || isNaN(n))\n    throw TypeError('n must be a positive number');\n  this._maxListeners = n;\n  return this;\n};\n\nEventEmitter.prototype.emit = function(type) {\n  var er, handler, len, args, i, listeners;\n\n  if (!this._events)\n    this._events = {};\n\n  // If there is no 'error' event listener then throw.\n  if (type === 'error') {\n    if (!this._events.error ||\n        (isObject(this._events.error) && !this._events.error.length)) {\n      er = arguments[1];\n      if (er instanceof Error) {\n        throw er; // Unhandled 'error' event\n      } else {\n        // At least give some kind of context to the user\n        var err = new Error('Uncaught, unspecified \"error\" event. (' + er + ')');\n        err.context = er;\n        throw err;\n      }\n    }\n  }\n\n  handler = this._events[type];\n\n  if (isUndefined(handler))\n    return false;\n\n  if (isFunction(handler)) {\n    switch (arguments.length) {\n      // fast cases\n      case 1:\n        handler.call(this);\n        break;\n      case 2:\n        handler.call(this, arguments[1]);\n        break;\n      case 3:\n        handler.call(this, arguments[1], arguments[2]);\n        break;\n      // slower\n      default:\n        args = Array.prototype.slice.call(arguments, 1);\n        handler.apply(this, args);\n    }\n  } else if (isObject(handler)) {\n    args = Array.prototype.slice.call(arguments, 1);\n    listeners = handler.slice();\n    len = listeners.length;\n    for (i = 0; i < len; i++)\n      listeners[i].apply(this, args);\n  }\n\n  return true;\n};\n\nEventEmitter.prototype.addListener = function(type, listener) {\n  var m;\n\n  if (!isFunction(listener))\n    throw TypeError('listener must be a function');\n\n  if (!this._events)\n    this._events = {};\n\n  // To avoid recursion in the case that type === \"newListener\"! Before\n  // adding it to the listeners, first emit \"newListener\".\n  if (this._events.newListener)\n    this.emit('newListener', type,\n              isFunction(listener.listener) ?\n              listener.listener : listener);\n\n  if (!this._events[type])\n    // Optimize the case of one listener. Don't need the extra array object.\n    this._events[type] = listener;\n  else if (isObject(this._events[type]))\n    // If we've already got an array, just append.\n    this._events[type].push(listener);\n  else\n    // Adding the second element, need to change to array.\n    this._events[type] = [this._events[type], listener];\n\n  // Check for listener leak\n  if (isObject(this._events[type]) && !this._events[type].warned) {\n    if (!isUndefined(this._maxListeners)) {\n      m = this._maxListeners;\n    } else {\n      m = EventEmitter.defaultMaxListeners;\n    }\n\n    if (m && m > 0 && this._events[type].length > m) {\n      this._events[type].warned = true;\n      console.error('(node) warning: possible EventEmitter memory ' +\n                    'leak detected. %d listeners added. ' +\n                    'Use emitter.setMaxListeners() to increase limit.',\n                    this._events[type].length);\n      if (typeof console.trace === 'function') {\n        // not supported in IE 10\n        console.trace();\n      }\n    }\n  }\n\n  return this;\n};\n\nEventEmitter.prototype.on = EventEmitter.prototype.addListener;\n\nEventEmitter.prototype.once = function(type, listener) {\n  if (!isFunction(listener))\n    throw TypeError('listener must be a function');\n\n  var fired = false;\n\n  function g() {\n    this.removeListener(type, g);\n\n    if (!fired) {\n      fired = true;\n      listener.apply(this, arguments);\n    }\n  }\n\n  g.listener = listener;\n  this.on(type, g);\n\n  return this;\n};\n\n// emits a 'removeListener' event iff the listener was removed\nEventEmitter.prototype.removeListener = function(type, listener) {\n  var list, position, length, i;\n\n  if (!isFunction(listener))\n    throw TypeError('listener must be a function');\n\n  if (!this._events || !this._events[type])\n    return this;\n\n  list = this._events[type];\n  length = list.length;\n  position = -1;\n\n  if (list === listener ||\n      (isFunction(list.listener) && list.listener === listener)) {\n    delete this._events[type];\n    if (this._events.removeListener)\n      this.emit('removeListener', type, listener);\n\n  } else if (isObject(list)) {\n    for (i = length; i-- > 0;) {\n      if (list[i] === listener ||\n          (list[i].listener && list[i].listener === listener)) {\n        position = i;\n        break;\n      }\n    }\n\n    if (position < 0)\n      return this;\n\n    if (list.length === 1) {\n      list.length = 0;\n      delete this._events[type];\n    } else {\n      list.splice(position, 1);\n    }\n\n    if (this._events.removeListener)\n      this.emit('removeListener', type, listener);\n  }\n\n  return this;\n};\n\nEventEmitter.prototype.removeAllListeners = function(type) {\n  var key, listeners;\n\n  if (!this._events)\n    return this;\n\n  // not listening for removeListener, no need to emit\n  if (!this._events.removeListener) {\n    if (arguments.length === 0)\n      this._events = {};\n    else if (this._events[type])\n      delete this._events[type];\n    return this;\n  }\n\n  // emit removeListener for all listeners on all events\n  if (arguments.length === 0) {\n    for (key in this._events) {\n      if (key === 'removeListener') continue;\n      this.removeAllListeners(key);\n    }\n    this.removeAllListeners('removeListener');\n    this._events = {};\n    return this;\n  }\n\n  listeners = this._events[type];\n\n  if (isFunction(listeners)) {\n    this.removeListener(type, listeners);\n  } else if (listeners) {\n    // LIFO order\n    while (listeners.length)\n      this.removeListener(type, listeners[listeners.length - 1]);\n  }\n  delete this._events[type];\n\n  return this;\n};\n\nEventEmitter.prototype.listeners = function(type) {\n  var ret;\n  if (!this._events || !this._events[type])\n    ret = [];\n  else if (isFunction(this._events[type]))\n    ret = [this._events[type]];\n  else\n    ret = this._events[type].slice();\n  return ret;\n};\n\nEventEmitter.prototype.listenerCount = function(type) {\n  if (this._events) {\n    var evlistener = this._events[type];\n\n    if (isFunction(evlistener))\n      return 1;\n    else if (evlistener)\n      return evlistener.length;\n  }\n  return 0;\n};\n\nEventEmitter.listenerCount = function(emitter, type) {\n  return emitter.listenerCount(type);\n};\n\nfunction isFunction(arg) {\n  return typeof arg === 'function';\n}\n\nfunction isNumber(arg) {\n  return typeof arg === 'number';\n}\n\nfunction isObject(arg) {\n  return typeof arg === 'object' && arg !== null;\n}\n\nfunction isUndefined(arg) {\n  return arg === void 0;\n}\n\n},{}],49:[function(require,module,exports){\n(function (process){\n// Growl - Copyright TJ Holowaychuk <tj@vision-media.ca> (MIT Licensed)\n\n/**\n * Module dependencies.\n */\n\nvar exec = require('child_process').exec\n  , fs = require('fs')\n  , path = require('path')\n  , exists = fs.existsSync || path.existsSync\n  , os = require('os')\n  , quote = JSON.stringify\n  , cmd;\n\nfunction which(name) {\n  var paths = process.env.PATH.split(':');\n  var loc;\n\n  for (var i = 0, len = paths.length; i < len; ++i) {\n    loc = path.join(paths[i], name);\n    if (exists(loc)) return loc;\n  }\n}\n\nswitch(os.type()) {\n  case 'Darwin':\n    if (which('terminal-notifier')) {\n      cmd = {\n          type: \"Darwin-NotificationCenter\"\n        , pkg: \"terminal-notifier\"\n        , msg: '-message'\n        , title: '-title'\n        , subtitle: '-subtitle'\n        , icon: '-appIcon'\n        , sound:  '-sound'\n        , url: '-open'\n        , priority: {\n              cmd: '-execute'\n            , range: []\n          }\n      };\n    } else {\n      cmd = {\n          type: \"Darwin-Growl\"\n        , pkg: \"growlnotify\"\n        , msg: '-m'\n        , sticky: '--sticky'\n        , priority: {\n              cmd: '--priority'\n            , range: [\n                -2\n              , -1\n              , 0\n              , 1\n              , 2\n              , \"Very Low\"\n              , \"Moderate\"\n              , \"Normal\"\n              , \"High\"\n              , \"Emergency\"\n            ]\n          }\n      };\n    }\n    break;\n  case 'Linux':\n    if (which('growl')) {\n      cmd = {\n          type: \"Linux-Growl\"\n        , pkg: \"growl\"\n        , msg: '-m'\n        , title: '-title'\n        , subtitle: '-subtitle'\n        , host: {\n            cmd: '-H'\n          , hostname: '192.168.33.1'\n        }\n      };\n    } else {\n      cmd = {\n          type: \"Linux\"\n        , pkg: \"notify-send\"\n        , msg: ''\n        , sticky: '-t 0'\n        , icon: '-i'\n        , priority: {\n            cmd: '-u'\n          , range: [\n              \"low\"\n            , \"normal\"\n            , \"critical\"\n          ]\n        }\n      };\n    }\n    break;\n  case 'Windows_NT':\n    cmd = {\n        type: \"Windows\"\n      , pkg: \"growlnotify\"\n      , msg: ''\n      , sticky: '/s:true'\n      , title: '/t:'\n      , icon: '/i:'\n      , url: '/cu:'\n      , priority: {\n            cmd: '/p:'\n          , range: [\n              -2\n            , -1\n            , 0\n            , 1\n            , 2\n          ]\n        }\n    };\n    break;\n}\n\n/**\n * Expose `growl`.\n */\n\nexports = module.exports = growl;\n\n/**\n * Node-growl version.\n */\n\nexports.version = '1.4.1'\n\n/**\n * Send growl notification _msg_ with _options_.\n *\n * Options:\n *\n *  - title   Notification title\n *  - sticky  Make the notification stick (defaults to false)\n *  - priority  Specify an int or named key (default is 0)\n *  - name    Application name (defaults to growlnotify)\n *  - sound   Sound efect ( in OSx defined in preferences -> sound -> effects) * works only in OSX > 10.8x\n *  - image\n *    - path to an icon sets --iconpath\n *    - path to an image sets --image\n *    - capitalized word sets --appIcon\n *    - filename uses extname as --icon\n *    - otherwise treated as --icon\n *\n * Examples:\n *\n *   growl('New email')\n *   growl('5 new emails', { title: 'Thunderbird' })\n *   growl('5 new emails', { title: 'Thunderbird', sound: 'Purr' })\n *   growl('Email sent', function(){\n *     // ... notification sent\n *   })\n *\n * @param {string} msg\n * @param {object} options\n * @param {function} fn\n * @api public\n */\n\nfunction growl(msg, options, fn) {\n  var image\n    , args\n    , options = options || {}\n    , fn = fn || function(){};\n\n  if (options.exec) {\n    cmd = {\n        type: \"Custom\"\n      , pkg: options.exec\n      , range: []\n    };\n  }\n\n  // noop\n  if (!cmd) return fn(new Error('growl not supported on this platform'));\n  args = [cmd.pkg];\n\n  // image\n  if (image = options.image) {\n    switch(cmd.type) {\n      case 'Darwin-Growl':\n        var flag, ext = path.extname(image).substr(1)\n        flag = flag || ext == 'icns' && 'iconpath'\n        flag = flag || /^[A-Z]/.test(image) && 'appIcon'\n        flag = flag || /^png|gif|jpe?g$/.test(ext) && 'image'\n        flag = flag || ext && (image = ext) && 'icon'\n        flag = flag || 'icon'\n        args.push('--' + flag, quote(image))\n        break;\n      case 'Darwin-NotificationCenter':\n        args.push(cmd.icon, quote(image));\n        break;\n      case 'Linux':\n        args.push(cmd.icon, quote(image));\n        // libnotify defaults to sticky, set a hint for transient notifications\n        if (!options.sticky) args.push('--hint=int:transient:1');\n        break;\n      case 'Windows':\n        args.push(cmd.icon + quote(image));\n        break;\n    }\n  }\n\n  // sticky\n  if (options.sticky) args.push(cmd.sticky);\n\n  // priority\n  if (options.priority) {\n    var priority = options.priority + '';\n    var checkindexOf = cmd.priority.range.indexOf(priority);\n    if (~cmd.priority.range.indexOf(priority)) {\n      args.push(cmd.priority, options.priority);\n    }\n  }\n\n  //sound\n  if(options.sound && cmd.type === 'Darwin-NotificationCenter'){\n    args.push(cmd.sound, options.sound)\n  }\n\n  // name\n  if (options.name && cmd.type === \"Darwin-Growl\") {\n    args.push('--name', options.name);\n  }\n\n  switch(cmd.type) {\n    case 'Darwin-Growl':\n      args.push(cmd.msg);\n      args.push(quote(msg).replace(/\\\\n/g, '\\n'));\n      if (options.title) args.push(quote(options.title));\n      break;\n    case 'Darwin-NotificationCenter':\n      args.push(cmd.msg);\n      var stringifiedMsg = quote(msg);\n      var escapedMsg = stringifiedMsg.replace(/\\\\n/g, '\\n');\n      args.push(escapedMsg);\n      if (options.title) {\n        args.push(cmd.title);\n        args.push(quote(options.title));\n      }\n      if (options.subtitle) {\n        args.push(cmd.subtitle);\n        args.push(quote(options.subtitle));\n      }\n      if (options.url) {\n        args.push(cmd.url);\n        args.push(quote(options.url));\n      }\n      break;\n    case 'Linux-Growl':\n      args.push(cmd.msg);\n      args.push(quote(msg).replace(/\\\\n/g, '\\n'));\n      if (options.title) args.push(quote(options.title));\n      if (cmd.host) {\n        args.push(cmd.host.cmd, cmd.host.hostname)\n      }\n      break;\n    case 'Linux':\n      if (options.title) {\n        args.push(quote(options.title));\n        args.push(cmd.msg);\n        args.push(quote(msg).replace(/\\\\n/g, '\\n'));\n      } else {\n        args.push(quote(msg).replace(/\\\\n/g, '\\n'));\n      }\n      break;\n    case 'Windows':\n      args.push(quote(msg).replace(/\\\\n/g, '\\n'));\n      if (options.title) args.push(cmd.title + quote(options.title));\n      if (options.url) args.push(cmd.url + quote(options.url));\n      break;\n    case 'Custom':\n      args[0] = (function(origCommand) {\n        var message = options.title\n          ? options.title + ': ' + msg\n          : msg;\n        var command = origCommand.replace(/(^|[^%])%s/g, '$1' + quote(message));\n        if (command === origCommand) args.push(quote(message));\n        return command;\n      })(args[0]);\n      break;\n  }\n\n  // execute\n  exec(args.join(' '), fn);\n};\n\n}).call(this,require('_process'))\n},{\"_process\":67,\"child_process\":42,\"fs\":42,\"os\":65,\"path\":42}],50:[function(require,module,exports){\nexports.read = function (buffer, offset, isLE, mLen, nBytes) {\n  var e, m\n  var eLen = nBytes * 8 - mLen - 1\n  var eMax = (1 << eLen) - 1\n  var eBias = eMax >> 1\n  var nBits = -7\n  var i = isLE ? (nBytes - 1) : 0\n  var d = isLE ? -1 : 1\n  var s = buffer[offset + i]\n\n  i += d\n\n  e = s & ((1 << (-nBits)) - 1)\n  s >>= (-nBits)\n  nBits += eLen\n  for (; nBits > 0; e = e * 256 + buffer[offset + i], i += d, nBits -= 8) {}\n\n  m = e & ((1 << (-nBits)) - 1)\n  e >>= (-nBits)\n  nBits += mLen\n  for (; nBits > 0; m = m * 256 + buffer[offset + i], i += d, nBits -= 8) {}\n\n  if (e === 0) {\n    e = 1 - eBias\n  } else if (e === eMax) {\n    return m ? NaN : ((s ? -1 : 1) * Infinity)\n  } else {\n    m = m + Math.pow(2, mLen)\n    e = e - eBias\n  }\n  return (s ? -1 : 1) * m * Math.pow(2, e - mLen)\n}\n\nexports.write = function (buffer, value, offset, isLE, mLen, nBytes) {\n  var e, m, c\n  var eLen = nBytes * 8 - mLen - 1\n  var eMax = (1 << eLen) - 1\n  var eBias = eMax >> 1\n  var rt = (mLen === 23 ? Math.pow(2, -24) - Math.pow(2, -77) : 0)\n  var i = isLE ? 0 : (nBytes - 1)\n  var d = isLE ? 1 : -1\n  var s = value < 0 || (value === 0 && 1 / value < 0) ? 1 : 0\n\n  value = Math.abs(value)\n\n  if (isNaN(value) || value === Infinity) {\n    m = isNaN(value) ? 1 : 0\n    e = eMax\n  } else {\n    e = Math.floor(Math.log(value) / Math.LN2)\n    if (value * (c = Math.pow(2, -e)) < 1) {\n      e--\n      c *= 2\n    }\n    if (e + eBias >= 1) {\n      value += rt / c\n    } else {\n      value += rt * Math.pow(2, 1 - eBias)\n    }\n    if (value * c >= 2) {\n      e++\n      c /= 2\n    }\n\n    if (e + eBias >= eMax) {\n      m = 0\n      e = eMax\n    } else if (e + eBias >= 1) {\n      m = (value * c - 1) * Math.pow(2, mLen)\n      e = e + eBias\n    } else {\n      m = value * Math.pow(2, eBias - 1) * Math.pow(2, mLen)\n      e = 0\n    }\n  }\n\n  for (; mLen >= 8; buffer[offset + i] = m & 0xff, i += d, m /= 256, mLen -= 8) {}\n\n  e = (e << mLen) | m\n  eLen += mLen\n  for (; eLen > 0; buffer[offset + i] = e & 0xff, i += d, e /= 256, eLen -= 8) {}\n\n  buffer[offset + i - d] |= s * 128\n}\n\n},{}],51:[function(require,module,exports){\nif (typeof Object.create === 'function') {\n  // implementation from standard node.js 'util' module\n  module.exports = function inherits(ctor, superCtor) {\n    ctor.super_ = superCtor\n    ctor.prototype = Object.create(superCtor.prototype, {\n      constructor: {\n        value: ctor,\n        enumerable: false,\n        writable: true,\n        configurable: true\n      }\n    });\n  };\n} else {\n  // old school shim for old browsers\n  module.exports = function inherits(ctor, superCtor) {\n    ctor.super_ = superCtor\n    var TempCtor = function () {}\n    TempCtor.prototype = superCtor.prototype\n    ctor.prototype = new TempCtor()\n    ctor.prototype.constructor = ctor\n  }\n}\n\n},{}],52:[function(require,module,exports){\n/*!\n * Determine if an object is a Buffer\n *\n * @author   Feross Aboukhadijeh <feross@feross.org> <http://feross.org>\n * @license  MIT\n */\n\n// The _isBuffer check is for Safari 5-7 support, because it's missing\n// Object.prototype.constructor. Remove this eventually\nmodule.exports = function (obj) {\n  return obj != null && (isBuffer(obj) || isSlowBuffer(obj) || !!obj._isBuffer)\n}\n\nfunction isBuffer (obj) {\n  return !!obj.constructor && typeof obj.constructor.isBuffer === 'function' && obj.constructor.isBuffer(obj)\n}\n\n// For Node v0.10 support. Remove this eventually.\nfunction isSlowBuffer (obj) {\n  return typeof obj.readFloatLE === 'function' && typeof obj.slice === 'function' && isBuffer(obj.slice(0, 0))\n}\n\n},{}],53:[function(require,module,exports){\nvar toString = {}.toString;\n\nmodule.exports = Array.isArray || function (arr) {\n  return toString.call(arr) == '[object Array]';\n};\n\n},{}],54:[function(require,module,exports){\n(function (global){\n/*! JSON v3.3.2 | http://bestiejs.github.io/json3 | Copyright 2012-2014, Kit Cambridge | http://kit.mit-license.org */\n;(function () {\n  // Detect the `define` function exposed by asynchronous module loaders. The\n  // strict `define` check is necessary for compatibility with `r.js`.\n  var isLoader = false;\n\n  // A set of types used to distinguish objects from primitives.\n  var objectTypes = {\n    \"function\": true,\n    \"object\": true\n  };\n\n  // Detect the `exports` object exposed by CommonJS implementations.\n  var freeExports = objectTypes[typeof exports] && exports && !exports.nodeType && exports;\n\n  // Use the `global` object exposed by Node (including Browserify via\n  // `insert-module-globals`), Narwhal, and Ringo as the default context,\n  // and the `window` object in browsers. Rhino exports a `global` function\n  // instead.\n  var root = objectTypes[typeof window] && window || this,\n      freeGlobal = freeExports && objectTypes[typeof module] && module && !module.nodeType && typeof global == \"object\" && global;\n\n  if (freeGlobal && (freeGlobal[\"global\"] === freeGlobal || freeGlobal[\"window\"] === freeGlobal || freeGlobal[\"self\"] === freeGlobal)) {\n    root = freeGlobal;\n  }\n\n  // Public: Initializes JSON 3 using the given `context` object, attaching the\n  // `stringify` and `parse` functions to the specified `exports` object.\n  function runInContext(context, exports) {\n    context || (context = root[\"Object\"]());\n    exports || (exports = root[\"Object\"]());\n\n    // Native constructor aliases.\n    var Number = context[\"Number\"] || root[\"Number\"],\n        String = context[\"String\"] || root[\"String\"],\n        Object = context[\"Object\"] || root[\"Object\"],\n        Date = context[\"Date\"] || root[\"Date\"],\n        SyntaxError = context[\"SyntaxError\"] || root[\"SyntaxError\"],\n        TypeError = context[\"TypeError\"] || root[\"TypeError\"],\n        Math = context[\"Math\"] || root[\"Math\"],\n        nativeJSON = context[\"JSON\"] || root[\"JSON\"];\n\n    // Delegate to the native `stringify` and `parse` implementations.\n    if (typeof nativeJSON == \"object\" && nativeJSON) {\n      exports.stringify = nativeJSON.stringify;\n      exports.parse = nativeJSON.parse;\n    }\n\n    // Convenience aliases.\n    var objectProto = Object.prototype,\n        getClass = objectProto.toString,\n        isProperty, forEach, undef;\n\n    // Test the `Date#getUTC*` methods. Based on work by @Yaffle.\n    var isExtended = new Date(-3509827334573292);\n    try {\n      // The `getUTCFullYear`, `Month`, and `Date` methods return nonsensical\n      // results for certain dates in Opera >= 10.53.\n      isExtended = isExtended.getUTCFullYear() == -109252 && isExtended.getUTCMonth() === 0 && isExtended.getUTCDate() === 1 &&\n        // Safari < 2.0.2 stores the internal millisecond time value correctly,\n        // but clips the values returned by the date methods to the range of\n        // signed 32-bit integers ([-2 ** 31, 2 ** 31 - 1]).\n        isExtended.getUTCHours() == 10 && isExtended.getUTCMinutes() == 37 && isExtended.getUTCSeconds() == 6 && isExtended.getUTCMilliseconds() == 708;\n    } catch (exception) {}\n\n    // Internal: Determines whether the native `JSON.stringify` and `parse`\n    // implementations are spec-compliant. Based on work by Ken Snyder.\n    function has(name) {\n      if (has[name] !== undef) {\n        // Return cached feature test result.\n        return has[name];\n      }\n      var isSupported;\n      if (name == \"bug-string-char-index\") {\n        // IE <= 7 doesn't support accessing string characters using square\n        // bracket notation. IE 8 only supports this for primitives.\n        isSupported = \"a\"[0] != \"a\";\n      } else if (name == \"json\") {\n        // Indicates whether both `JSON.stringify` and `JSON.parse` are\n        // supported.\n        isSupported = has(\"json-stringify\") && has(\"json-parse\");\n      } else {\n        var value, serialized = '{\"a\":[1,true,false,null,\"\\\\u0000\\\\b\\\\n\\\\f\\\\r\\\\t\"]}';\n        // Test `JSON.stringify`.\n        if (name == \"json-stringify\") {\n          var stringify = exports.stringify, stringifySupported = typeof stringify == \"function\" && isExtended;\n          if (stringifySupported) {\n            // A test function object with a custom `toJSON` method.\n            (value = function () {\n              return 1;\n            }).toJSON = value;\n            try {\n              stringifySupported =\n                // Firefox 3.1b1 and b2 serialize string, number, and boolean\n                // primitives as object literals.\n                stringify(0) === \"0\" &&\n                // FF 3.1b1, b2, and JSON 2 serialize wrapped primitives as object\n                // literals.\n                stringify(new Number()) === \"0\" &&\n                stringify(new String()) == '\"\"' &&\n                // FF 3.1b1, 2 throw an error if the value is `null`, `undefined`, or\n                // does not define a canonical JSON representation (this applies to\n                // objects with `toJSON` properties as well, *unless* they are nested\n                // within an object or array).\n                stringify(getClass) === undef &&\n                // IE 8 serializes `undefined` as `\"undefined\"`. Safari <= 5.1.7 and\n                // FF 3.1b3 pass this test.\n                stringify(undef) === undef &&\n                // Safari <= 5.1.7 and FF 3.1b3 throw `Error`s and `TypeError`s,\n                // respectively, if the value is omitted entirely.\n                stringify() === undef &&\n                // FF 3.1b1, 2 throw an error if the given value is not a number,\n                // string, array, object, Boolean, or `null` literal. This applies to\n                // objects with custom `toJSON` methods as well, unless they are nested\n                // inside object or array literals. YUI 3.0.0b1 ignores custom `toJSON`\n                // methods entirely.\n                stringify(value) === \"1\" &&\n                stringify([value]) == \"[1]\" &&\n                // Prototype <= 1.6.1 serializes `[undefined]` as `\"[]\"` instead of\n                // `\"[null]\"`.\n                stringify([undef]) == \"[null]\" &&\n                // YUI 3.0.0b1 fails to serialize `null` literals.\n                stringify(null) == \"null\" &&\n                // FF 3.1b1, 2 halts serialization if an array contains a function:\n                // `[1, true, getClass, 1]` serializes as \"[1,true,],\". FF 3.1b3\n                // elides non-JSON values from objects and arrays, unless they\n                // define custom `toJSON` methods.\n                stringify([undef, getClass, null]) == \"[null,null,null]\" &&\n                // Simple serialization test. FF 3.1b1 uses Unicode escape sequences\n                // where character escape codes are expected (e.g., `\\b` => `\\u0008`).\n                stringify({ \"a\": [value, true, false, null, \"\\x00\\b\\n\\f\\r\\t\"] }) == serialized &&\n                // FF 3.1b1 and b2 ignore the `filter` and `width` arguments.\n                stringify(null, value) === \"1\" &&\n                stringify([1, 2], null, 1) == \"[\\n 1,\\n 2\\n]\" &&\n                // JSON 2, Prototype <= 1.7, and older WebKit builds incorrectly\n                // serialize extended years.\n                stringify(new Date(-8.64e15)) == '\"-271821-04-20T00:00:00.000Z\"' &&\n                // The milliseconds are optional in ES 5, but required in 5.1.\n                stringify(new Date(8.64e15)) == '\"+275760-09-13T00:00:00.000Z\"' &&\n                // Firefox <= 11.0 incorrectly serializes years prior to 0 as negative\n                // four-digit years instead of six-digit years. Credits: @Yaffle.\n                stringify(new Date(-621987552e5)) == '\"-000001-01-01T00:00:00.000Z\"' &&\n                // Safari <= 5.1.5 and Opera >= 10.53 incorrectly serialize millisecond\n                // values less than 1000. Credits: @Yaffle.\n                stringify(new Date(-1)) == '\"1969-12-31T23:59:59.999Z\"';\n            } catch (exception) {\n              stringifySupported = false;\n            }\n          }\n          isSupported = stringifySupported;\n        }\n        // Test `JSON.parse`.\n        if (name == \"json-parse\") {\n          var parse = exports.parse;\n          if (typeof parse == \"function\") {\n            try {\n              // FF 3.1b1, b2 will throw an exception if a bare literal is provided.\n              // Conforming implementations should also coerce the initial argument to\n              // a string prior to parsing.\n              if (parse(\"0\") === 0 && !parse(false)) {\n                // Simple parsing test.\n                value = parse(serialized);\n                var parseSupported = value[\"a\"].length == 5 && value[\"a\"][0] === 1;\n                if (parseSupported) {\n                  try {\n                    // Safari <= 5.1.2 and FF 3.1b1 allow unescaped tabs in strings.\n                    parseSupported = !parse('\"\\t\"');\n                  } catch (exception) {}\n                  if (parseSupported) {\n                    try {\n                      // FF 4.0 and 4.0.1 allow leading `+` signs and leading\n                      // decimal points. FF 4.0, 4.0.1, and IE 9-10 also allow\n                      // certain octal literals.\n                      parseSupported = parse(\"01\") !== 1;\n                    } catch (exception) {}\n                  }\n                  if (parseSupported) {\n                    try {\n                      // FF 4.0, 4.0.1, and Rhino 1.7R3-R4 allow trailing decimal\n                      // points. These environments, along with FF 3.1b1 and 2,\n                      // also allow trailing commas in JSON objects and arrays.\n                      parseSupported = parse(\"1.\") !== 1;\n                    } catch (exception) {}\n                  }\n                }\n              }\n            } catch (exception) {\n              parseSupported = false;\n            }\n          }\n          isSupported = parseSupported;\n        }\n      }\n      return has[name] = !!isSupported;\n    }\n\n    if (!has(\"json\")) {\n      // Common `[[Class]]` name aliases.\n      var functionClass = \"[object Function]\",\n          dateClass = \"[object Date]\",\n          numberClass = \"[object Number]\",\n          stringClass = \"[object String]\",\n          arrayClass = \"[object Array]\",\n          booleanClass = \"[object Boolean]\";\n\n      // Detect incomplete support for accessing string characters by index.\n      var charIndexBuggy = has(\"bug-string-char-index\");\n\n      // Define additional utility methods if the `Date` methods are buggy.\n      if (!isExtended) {\n        var floor = Math.floor;\n        // A mapping between the months of the year and the number of days between\n        // January 1st and the first of the respective month.\n        var Months = [0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334];\n        // Internal: Calculates the number of days between the Unix epoch and the\n        // first day of the given month.\n        var getDay = function (year, month) {\n          return Months[month] + 365 * (year - 1970) + floor((year - 1969 + (month = +(month > 1))) / 4) - floor((year - 1901 + month) / 100) + floor((year - 1601 + month) / 400);\n        };\n      }\n\n      // Internal: Determines if a property is a direct property of the given\n      // object. Delegates to the native `Object#hasOwnProperty` method.\n      if (!(isProperty = objectProto.hasOwnProperty)) {\n        isProperty = function (property) {\n          var members = {}, constructor;\n          if ((members.__proto__ = null, members.__proto__ = {\n            // The *proto* property cannot be set multiple times in recent\n            // versions of Firefox and SeaMonkey.\n            \"toString\": 1\n          }, members).toString != getClass) {\n            // Safari <= 2.0.3 doesn't implement `Object#hasOwnProperty`, but\n            // supports the mutable *proto* property.\n            isProperty = function (property) {\n              // Capture and break the object's prototype chain (see section 8.6.2\n              // of the ES 5.1 spec). The parenthesized expression prevents an\n              // unsafe transformation by the Closure Compiler.\n              var original = this.__proto__, result = property in (this.__proto__ = null, this);\n              // Restore the original prototype chain.\n              this.__proto__ = original;\n              return result;\n            };\n          } else {\n            // Capture a reference to the top-level `Object` constructor.\n            constructor = members.constructor;\n            // Use the `constructor` property to simulate `Object#hasOwnProperty` in\n            // other environments.\n            isProperty = function (property) {\n              var parent = (this.constructor || constructor).prototype;\n              return property in this && !(property in parent && this[property] === parent[property]);\n            };\n          }\n          members = null;\n          return isProperty.call(this, property);\n        };\n      }\n\n      // Internal: Normalizes the `for...in` iteration algorithm across\n      // environments. Each enumerated key is yielded to a `callback` function.\n      forEach = function (object, callback) {\n        var size = 0, Properties, members, property;\n\n        // Tests for bugs in the current environment's `for...in` algorithm. The\n        // `valueOf` property inherits the non-enumerable flag from\n        // `Object.prototype` in older versions of IE, Netscape, and Mozilla.\n        (Properties = function () {\n          this.valueOf = 0;\n        }).prototype.valueOf = 0;\n\n        // Iterate over a new instance of the `Properties` class.\n        members = new Properties();\n        for (property in members) {\n          // Ignore all properties inherited from `Object.prototype`.\n          if (isProperty.call(members, property)) {\n            size++;\n          }\n        }\n        Properties = members = null;\n\n        // Normalize the iteration algorithm.\n        if (!size) {\n          // A list of non-enumerable properties inherited from `Object.prototype`.\n          members = [\"valueOf\", \"toString\", \"toLocaleString\", \"propertyIsEnumerable\", \"isPrototypeOf\", \"hasOwnProperty\", \"constructor\"];\n          // IE <= 8, Mozilla 1.0, and Netscape 6.2 ignore shadowed non-enumerable\n          // properties.\n          forEach = function (object, callback) {\n            var isFunction = getClass.call(object) == functionClass, property, length;\n            var hasProperty = !isFunction && typeof object.constructor != \"function\" && objectTypes[typeof object.hasOwnProperty] && object.hasOwnProperty || isProperty;\n            for (property in object) {\n              // Gecko <= 1.0 enumerates the `prototype` property of functions under\n              // certain conditions; IE does not.\n              if (!(isFunction && property == \"prototype\") && hasProperty.call(object, property)) {\n                callback(property);\n              }\n            }\n            // Manually invoke the callback for each non-enumerable property.\n            for (length = members.length; property = members[--length]; hasProperty.call(object, property) && callback(property));\n          };\n        } else if (size == 2) {\n          // Safari <= 2.0.4 enumerates shadowed properties twice.\n          forEach = function (object, callback) {\n            // Create a set of iterated properties.\n            var members = {}, isFunction = getClass.call(object) == functionClass, property;\n            for (property in object) {\n              // Store each property name to prevent double enumeration. The\n              // `prototype` property of functions is not enumerated due to cross-\n              // environment inconsistencies.\n              if (!(isFunction && property == \"prototype\") && !isProperty.call(members, property) && (members[property] = 1) && isProperty.call(object, property)) {\n                callback(property);\n              }\n            }\n          };\n        } else {\n          // No bugs detected; use the standard `for...in` algorithm.\n          forEach = function (object, callback) {\n            var isFunction = getClass.call(object) == functionClass, property, isConstructor;\n            for (property in object) {\n              if (!(isFunction && property == \"prototype\") && isProperty.call(object, property) && !(isConstructor = property === \"constructor\")) {\n                callback(property);\n              }\n            }\n            // Manually invoke the callback for the `constructor` property due to\n            // cross-environment inconsistencies.\n            if (isConstructor || isProperty.call(object, (property = \"constructor\"))) {\n              callback(property);\n            }\n          };\n        }\n        return forEach(object, callback);\n      };\n\n      // Public: Serializes a JavaScript `value` as a JSON string. The optional\n      // `filter` argument may specify either a function that alters how object and\n      // array members are serialized, or an array of strings and numbers that\n      // indicates which properties should be serialized. The optional `width`\n      // argument may be either a string or number that specifies the indentation\n      // level of the output.\n      if (!has(\"json-stringify\")) {\n        // Internal: A map of control characters and their escaped equivalents.\n        var Escapes = {\n          92: \"\\\\\\\\\",\n          34: '\\\\\"',\n          8: \"\\\\b\",\n          12: \"\\\\f\",\n          10: \"\\\\n\",\n          13: \"\\\\r\",\n          9: \"\\\\t\"\n        };\n\n        // Internal: Converts `value` into a zero-padded string such that its\n        // length is at least equal to `width`. The `width` must be <= 6.\n        var leadingZeroes = \"000000\";\n        var toPaddedString = function (width, value) {\n          // The `|| 0` expression is necessary to work around a bug in\n          // Opera <= 7.54u2 where `0 == -0`, but `String(-0) !== \"0\"`.\n          return (leadingZeroes + (value || 0)).slice(-width);\n        };\n\n        // Internal: Double-quotes a string `value`, replacing all ASCII control\n        // characters (characters with code unit values between 0 and 31) with\n        // their escaped equivalents. This is an implementation of the\n        // `Quote(value)` operation defined in ES 5.1 section 15.12.3.\n        var unicodePrefix = \"\\\\u00\";\n        var quote = function (value) {\n          var result = '\"', index = 0, length = value.length, useCharIndex = !charIndexBuggy || length > 10;\n          var symbols = useCharIndex && (charIndexBuggy ? value.split(\"\") : value);\n          for (; index < length; index++) {\n            var charCode = value.charCodeAt(index);\n            // If the character is a control character, append its Unicode or\n            // shorthand escape sequence; otherwise, append the character as-is.\n            switch (charCode) {\n              case 8: case 9: case 10: case 12: case 13: case 34: case 92:\n                result += Escapes[charCode];\n                break;\n              default:\n                if (charCode < 32) {\n                  result += unicodePrefix + toPaddedString(2, charCode.toString(16));\n                  break;\n                }\n                result += useCharIndex ? symbols[index] : value.charAt(index);\n            }\n          }\n          return result + '\"';\n        };\n\n        // Internal: Recursively serializes an object. Implements the\n        // `Str(key, holder)`, `JO(value)`, and `JA(value)` operations.\n        var serialize = function (property, object, callback, properties, whitespace, indentation, stack) {\n          var value, className, year, month, date, time, hours, minutes, seconds, milliseconds, results, element, index, length, prefix, result;\n          try {\n            // Necessary for host object support.\n            value = object[property];\n          } catch (exception) {}\n          if (typeof value == \"object\" && value) {\n            className = getClass.call(value);\n            if (className == dateClass && !isProperty.call(value, \"toJSON\")) {\n              if (value > -1 / 0 && value < 1 / 0) {\n                // Dates are serialized according to the `Date#toJSON` method\n                // specified in ES 5.1 section 15.9.5.44. See section 15.9.1.15\n                // for the ISO 8601 date time string format.\n                if (getDay) {\n                  // Manually compute the year, month, date, hours, minutes,\n                  // seconds, and milliseconds if the `getUTC*` methods are\n                  // buggy. Adapted from @Yaffle's `date-shim` project.\n                  date = floor(value / 864e5);\n                  for (year = floor(date / 365.2425) + 1970 - 1; getDay(year + 1, 0) <= date; year++);\n                  for (month = floor((date - getDay(year, 0)) / 30.42); getDay(year, month + 1) <= date; month++);\n                  date = 1 + date - getDay(year, month);\n                  // The `time` value specifies the time within the day (see ES\n                  // 5.1 section 15.9.1.2). The formula `(A % B + B) % B` is used\n                  // to compute `A modulo B`, as the `%` operator does not\n                  // correspond to the `modulo` operation for negative numbers.\n                  time = (value % 864e5 + 864e5) % 864e5;\n                  // The hours, minutes, seconds, and milliseconds are obtained by\n                  // decomposing the time within the day. See section 15.9.1.10.\n                  hours = floor(time / 36e5) % 24;\n                  minutes = floor(time / 6e4) % 60;\n                  seconds = floor(time / 1e3) % 60;\n                  milliseconds = time % 1e3;\n                } else {\n                  year = value.getUTCFullYear();\n                  month = value.getUTCMonth();\n                  date = value.getUTCDate();\n                  hours = value.getUTCHours();\n                  minutes = value.getUTCMinutes();\n                  seconds = value.getUTCSeconds();\n                  milliseconds = value.getUTCMilliseconds();\n                }\n                // Serialize extended years correctly.\n                value = (year <= 0 || year >= 1e4 ? (year < 0 ? \"-\" : \"+\") + toPaddedString(6, year < 0 ? -year : year) : toPaddedString(4, year)) +\n                  \"-\" + toPaddedString(2, month + 1) + \"-\" + toPaddedString(2, date) +\n                  // Months, dates, hours, minutes, and seconds should have two\n                  // digits; milliseconds should have three.\n                  \"T\" + toPaddedString(2, hours) + \":\" + toPaddedString(2, minutes) + \":\" + toPaddedString(2, seconds) +\n                  // Milliseconds are optional in ES 5.0, but required in 5.1.\n                  \".\" + toPaddedString(3, milliseconds) + \"Z\";\n              } else {\n                value = null;\n              }\n            } else if (typeof value.toJSON == \"function\" && ((className != numberClass && className != stringClass && className != arrayClass) || isProperty.call(value, \"toJSON\"))) {\n              // Prototype <= 1.6.1 adds non-standard `toJSON` methods to the\n              // `Number`, `String`, `Date`, and `Array` prototypes. JSON 3\n              // ignores all `toJSON` methods on these objects unless they are\n              // defined directly on an instance.\n              value = value.toJSON(property);\n            }\n          }\n          if (callback) {\n            // If a replacement function was provided, call it to obtain the value\n            // for serialization.\n            value = callback.call(object, property, value);\n          }\n          if (value === null) {\n            return \"null\";\n          }\n          className = getClass.call(value);\n          if (className == booleanClass) {\n            // Booleans are represented literally.\n            return \"\" + value;\n          } else if (className == numberClass) {\n            // JSON numbers must be finite. `Infinity` and `NaN` are serialized as\n            // `\"null\"`.\n            return value > -1 / 0 && value < 1 / 0 ? \"\" + value : \"null\";\n          } else if (className == stringClass) {\n            // Strings are double-quoted and escaped.\n            return quote(\"\" + value);\n          }\n          // Recursively serialize objects and arrays.\n          if (typeof value == \"object\") {\n            // Check for cyclic structures. This is a linear search; performance\n            // is inversely proportional to the number of unique nested objects.\n            for (length = stack.length; length--;) {\n              if (stack[length] === value) {\n                // Cyclic structures cannot be serialized by `JSON.stringify`.\n                throw TypeError();\n              }\n            }\n            // Add the object to the stack of traversed objects.\n            stack.push(value);\n            results = [];\n            // Save the current indentation level and indent one additional level.\n            prefix = indentation;\n            indentation += whitespace;\n            if (className == arrayClass) {\n              // Recursively serialize array elements.\n              for (index = 0, length = value.length; index < length; index++) {\n                element = serialize(index, value, callback, properties, whitespace, indentation, stack);\n                results.push(element === undef ? \"null\" : element);\n              }\n              result = results.length ? (whitespace ? \"[\\n\" + indentation + results.join(\",\\n\" + indentation) + \"\\n\" + prefix + \"]\" : (\"[\" + results.join(\",\") + \"]\")) : \"[]\";\n            } else {\n              // Recursively serialize object members. Members are selected from\n              // either a user-specified list of property names, or the object\n              // itself.\n              forEach(properties || value, function (property) {\n                var element = serialize(property, value, callback, properties, whitespace, indentation, stack);\n                if (element !== undef) {\n                  // According to ES 5.1 section 15.12.3: \"If `gap` {whitespace}\n                  // is not the empty string, let `member` {quote(property) + \":\"}\n                  // be the concatenation of `member` and the `space` character.\"\n                  // The \"`space` character\" refers to the literal space\n                  // character, not the `space` {width} argument provided to\n                  // `JSON.stringify`.\n                  results.push(quote(property) + \":\" + (whitespace ? \" \" : \"\") + element);\n                }\n              });\n              result = results.length ? (whitespace ? \"{\\n\" + indentation + results.join(\",\\n\" + indentation) + \"\\n\" + prefix + \"}\" : (\"{\" + results.join(\",\") + \"}\")) : \"{}\";\n            }\n            // Remove the object from the traversed object stack.\n            stack.pop();\n            return result;\n          }\n        };\n\n        // Public: `JSON.stringify`. See ES 5.1 section 15.12.3.\n        exports.stringify = function (source, filter, width) {\n          var whitespace, callback, properties, className;\n          if (objectTypes[typeof filter] && filter) {\n            if ((className = getClass.call(filter)) == functionClass) {\n              callback = filter;\n            } else if (className == arrayClass) {\n              // Convert the property names array into a makeshift set.\n              properties = {};\n              for (var index = 0, length = filter.length, value; index < length; value = filter[index++], ((className = getClass.call(value)), className == stringClass || className == numberClass) && (properties[value] = 1));\n            }\n          }\n          if (width) {\n            if ((className = getClass.call(width)) == numberClass) {\n              // Convert the `width` to an integer and create a string containing\n              // `width` number of space characters.\n              if ((width -= width % 1) > 0) {\n                for (whitespace = \"\", width > 10 && (width = 10); whitespace.length < width; whitespace += \" \");\n              }\n            } else if (className == stringClass) {\n              whitespace = width.length <= 10 ? width : width.slice(0, 10);\n            }\n          }\n          // Opera <= 7.54u2 discards the values associated with empty string keys\n          // (`\"\"`) only if they are used directly within an object member list\n          // (e.g., `!(\"\" in { \"\": 1})`).\n          return serialize(\"\", (value = {}, value[\"\"] = source, value), callback, properties, whitespace, \"\", []);\n        };\n      }\n\n      // Public: Parses a JSON source string.\n      if (!has(\"json-parse\")) {\n        var fromCharCode = String.fromCharCode;\n\n        // Internal: A map of escaped control characters and their unescaped\n        // equivalents.\n        var Unescapes = {\n          92: \"\\\\\",\n          34: '\"',\n          47: \"/\",\n          98: \"\\b\",\n          116: \"\\t\",\n          110: \"\\n\",\n          102: \"\\f\",\n          114: \"\\r\"\n        };\n\n        // Internal: Stores the parser state.\n        var Index, Source;\n\n        // Internal: Resets the parser state and throws a `SyntaxError`.\n        var abort = function () {\n          Index = Source = null;\n          throw SyntaxError();\n        };\n\n        // Internal: Returns the next token, or `\"$\"` if the parser has reached\n        // the end of the source string. A token may be a string, number, `null`\n        // literal, or Boolean literal.\n        var lex = function () {\n          var source = Source, length = source.length, value, begin, position, isSigned, charCode;\n          while (Index < length) {\n            charCode = source.charCodeAt(Index);\n            switch (charCode) {\n              case 9: case 10: case 13: case 32:\n                // Skip whitespace tokens, including tabs, carriage returns, line\n                // feeds, and space characters.\n                Index++;\n                break;\n              case 123: case 125: case 91: case 93: case 58: case 44:\n                // Parse a punctuator token (`{`, `}`, `[`, `]`, `:`, or `,`) at\n                // the current position.\n                value = charIndexBuggy ? source.charAt(Index) : source[Index];\n                Index++;\n                return value;\n              case 34:\n                // `\"` delimits a JSON string; advance to the next character and\n                // begin parsing the string. String tokens are prefixed with the\n                // sentinel `@` character to distinguish them from punctuators and\n                // end-of-string tokens.\n                for (value = \"@\", Index++; Index < length;) {\n                  charCode = source.charCodeAt(Index);\n                  if (charCode < 32) {\n                    // Unescaped ASCII control characters (those with a code unit\n                    // less than the space character) are not permitted.\n                    abort();\n                  } else if (charCode == 92) {\n                    // A reverse solidus (`\\`) marks the beginning of an escaped\n                    // control character (including `\"`, `\\`, and `/`) or Unicode\n                    // escape sequence.\n                    charCode = source.charCodeAt(++Index);\n                    switch (charCode) {\n                      case 92: case 34: case 47: case 98: case 116: case 110: case 102: case 114:\n                        // Revive escaped control characters.\n                        value += Unescapes[charCode];\n                        Index++;\n                        break;\n                      case 117:\n                        // `\\u` marks the beginning of a Unicode escape sequence.\n                        // Advance to the first character and validate the\n                        // four-digit code point.\n                        begin = ++Index;\n                        for (position = Index + 4; Index < position; Index++) {\n                          charCode = source.charCodeAt(Index);\n                          // A valid sequence comprises four hexdigits (case-\n                          // insensitive) that form a single hexadecimal value.\n                          if (!(charCode >= 48 && charCode <= 57 || charCode >= 97 && charCode <= 102 || charCode >= 65 && charCode <= 70)) {\n                            // Invalid Unicode escape sequence.\n                            abort();\n                          }\n                        }\n                        // Revive the escaped character.\n                        value += fromCharCode(\"0x\" + source.slice(begin, Index));\n                        break;\n                      default:\n                        // Invalid escape sequence.\n                        abort();\n                    }\n                  } else {\n                    if (charCode == 34) {\n                      // An unescaped double-quote character marks the end of the\n                      // string.\n                      break;\n                    }\n                    charCode = source.charCodeAt(Index);\n                    begin = Index;\n                    // Optimize for the common case where a string is valid.\n                    while (charCode >= 32 && charCode != 92 && charCode != 34) {\n                      charCode = source.charCodeAt(++Index);\n                    }\n                    // Append the string as-is.\n                    value += source.slice(begin, Index);\n                  }\n                }\n                if (source.charCodeAt(Index) == 34) {\n                  // Advance to the next character and return the revived string.\n                  Index++;\n                  return value;\n                }\n                // Unterminated string.\n                abort();\n              default:\n                // Parse numbers and literals.\n                begin = Index;\n                // Advance past the negative sign, if one is specified.\n                if (charCode == 45) {\n                  isSigned = true;\n                  charCode = source.charCodeAt(++Index);\n                }\n                // Parse an integer or floating-point value.\n                if (charCode >= 48 && charCode <= 57) {\n                  // Leading zeroes are interpreted as octal literals.\n                  if (charCode == 48 && ((charCode = source.charCodeAt(Index + 1)), charCode >= 48 && charCode <= 57)) {\n                    // Illegal octal literal.\n                    abort();\n                  }\n                  isSigned = false;\n                  // Parse the integer component.\n                  for (; Index < length && ((charCode = source.charCodeAt(Index)), charCode >= 48 && charCode <= 57); Index++);\n                  // Floats cannot contain a leading decimal point; however, this\n                  // case is already accounted for by the parser.\n                  if (source.charCodeAt(Index) == 46) {\n                    position = ++Index;\n                    // Parse the decimal component.\n                    for (; position < length && ((charCode = source.charCodeAt(position)), charCode >= 48 && charCode <= 57); position++);\n                    if (position == Index) {\n                      // Illegal trailing decimal.\n                      abort();\n                    }\n                    Index = position;\n                  }\n                  // Parse exponents. The `e` denoting the exponent is\n                  // case-insensitive.\n                  charCode = source.charCodeAt(Index);\n                  if (charCode == 101 || charCode == 69) {\n                    charCode = source.charCodeAt(++Index);\n                    // Skip past the sign following the exponent, if one is\n                    // specified.\n                    if (charCode == 43 || charCode == 45) {\n                      Index++;\n                    }\n                    // Parse the exponential component.\n                    for (position = Index; position < length && ((charCode = source.charCodeAt(position)), charCode >= 48 && charCode <= 57); position++);\n                    if (position == Index) {\n                      // Illegal empty exponent.\n                      abort();\n                    }\n                    Index = position;\n                  }\n                  // Coerce the parsed value to a JavaScript number.\n                  return +source.slice(begin, Index);\n                }\n                // A negative sign may only precede numbers.\n                if (isSigned) {\n                  abort();\n                }\n                // `true`, `false`, and `null` literals.\n                if (source.slice(Index, Index + 4) == \"true\") {\n                  Index += 4;\n                  return true;\n                } else if (source.slice(Index, Index + 5) == \"false\") {\n                  Index += 5;\n                  return false;\n                } else if (source.slice(Index, Index + 4) == \"null\") {\n                  Index += 4;\n                  return null;\n                }\n                // Unrecognized token.\n                abort();\n            }\n          }\n          // Return the sentinel `$` character if the parser has reached the end\n          // of the source string.\n          return \"$\";\n        };\n\n        // Internal: Parses a JSON `value` token.\n        var get = function (value) {\n          var results, hasMembers;\n          if (value == \"$\") {\n            // Unexpected end of input.\n            abort();\n          }\n          if (typeof value == \"string\") {\n            if ((charIndexBuggy ? value.charAt(0) : value[0]) == \"@\") {\n              // Remove the sentinel `@` character.\n              return value.slice(1);\n            }\n            // Parse object and array literals.\n            if (value == \"[\") {\n              // Parses a JSON array, returning a new JavaScript array.\n              results = [];\n              for (;; hasMembers || (hasMembers = true)) {\n                value = lex();\n                // A closing square bracket marks the end of the array literal.\n                if (value == \"]\") {\n                  break;\n                }\n                // If the array literal contains elements, the current token\n                // should be a comma separating the previous element from the\n                // next.\n                if (hasMembers) {\n                  if (value == \",\") {\n                    value = lex();\n                    if (value == \"]\") {\n                      // Unexpected trailing `,` in array literal.\n                      abort();\n                    }\n                  } else {\n                    // A `,` must separate each array element.\n                    abort();\n                  }\n                }\n                // Elisions and leading commas are not permitted.\n                if (value == \",\") {\n                  abort();\n                }\n                results.push(get(value));\n              }\n              return results;\n            } else if (value == \"{\") {\n              // Parses a JSON object, returning a new JavaScript object.\n              results = {};\n              for (;; hasMembers || (hasMembers = true)) {\n                value = lex();\n                // A closing curly brace marks the end of the object literal.\n                if (value == \"}\") {\n                  break;\n                }\n                // If the object literal contains members, the current token\n                // should be a comma separator.\n                if (hasMembers) {\n                  if (value == \",\") {\n                    value = lex();\n                    if (value == \"}\") {\n                      // Unexpected trailing `,` in object literal.\n                      abort();\n                    }\n                  } else {\n                    // A `,` must separate each object member.\n                    abort();\n                  }\n                }\n                // Leading commas are not permitted, object property names must be\n                // double-quoted strings, and a `:` must separate each property\n                // name and value.\n                if (value == \",\" || typeof value != \"string\" || (charIndexBuggy ? value.charAt(0) : value[0]) != \"@\" || lex() != \":\") {\n                  abort();\n                }\n                results[value.slice(1)] = get(lex());\n              }\n              return results;\n            }\n            // Unexpected token encountered.\n            abort();\n          }\n          return value;\n        };\n\n        // Internal: Updates a traversed object member.\n        var update = function (source, property, callback) {\n          var element = walk(source, property, callback);\n          if (element === undef) {\n            delete source[property];\n          } else {\n            source[property] = element;\n          }\n        };\n\n        // Internal: Recursively traverses a parsed JSON object, invoking the\n        // `callback` function for each value. This is an implementation of the\n        // `Walk(holder, name)` operation defined in ES 5.1 section 15.12.2.\n        var walk = function (source, property, callback) {\n          var value = source[property], length;\n          if (typeof value == \"object\" && value) {\n            // `forEach` can't be used to traverse an array in Opera <= 8.54\n            // because its `Object#hasOwnProperty` implementation returns `false`\n            // for array indices (e.g., `![1, 2, 3].hasOwnProperty(\"0\")`).\n            if (getClass.call(value) == arrayClass) {\n              for (length = value.length; length--;) {\n                update(value, length, callback);\n              }\n            } else {\n              forEach(value, function (property) {\n                update(value, property, callback);\n              });\n            }\n          }\n          return callback.call(source, property, value);\n        };\n\n        // Public: `JSON.parse`. See ES 5.1 section 15.12.2.\n        exports.parse = function (source, callback) {\n          var result, value;\n          Index = 0;\n          Source = \"\" + source;\n          result = get(lex());\n          // If a JSON string contains multiple tokens, it is invalid.\n          if (lex() != \"$\") {\n            abort();\n          }\n          // Reset the parser state.\n          Index = Source = null;\n          return callback && getClass.call(callback) == functionClass ? walk((value = {}, value[\"\"] = result, value), \"\", callback) : result;\n        };\n      }\n    }\n\n    exports[\"runInContext\"] = runInContext;\n    return exports;\n  }\n\n  if (freeExports && !isLoader) {\n    // Export for CommonJS environments.\n    runInContext(root, freeExports);\n  } else {\n    // Export for web browsers and JavaScript engines.\n    var nativeJSON = root.JSON,\n        previousJSON = root[\"JSON3\"],\n        isRestored = false;\n\n    var JSON3 = runInContext(root, (root[\"JSON3\"] = {\n      // Public: Restores the original value of the global `JSON` object and\n      // returns a reference to the `JSON3` object.\n      \"noConflict\": function () {\n        if (!isRestored) {\n          isRestored = true;\n          root.JSON = nativeJSON;\n          root[\"JSON3\"] = previousJSON;\n          nativeJSON = previousJSON = null;\n        }\n        return JSON3;\n      }\n    }));\n\n    root.JSON = {\n      \"parse\": JSON3.parse,\n      \"stringify\": JSON3.stringify\n    };\n  }\n\n  // Export for asynchronous module loaders.\n  if (isLoader) {\n    define(function () {\n      return JSON3;\n    });\n  }\n}).call(this);\n\n}).call(this,typeof global !== \"undefined\" ? global : typeof self !== \"undefined\" ? self : typeof window !== \"undefined\" ? window : {})\n},{}],55:[function(require,module,exports){\n/**\n * lodash 3.2.0 (Custom Build) <https://lodash.com/>\n * Build: `lodash modern modularize exports=\"npm\" -o ./`\n * Copyright 2012-2015 The Dojo Foundation <http://dojofoundation.org/>\n * Based on Underscore.js 1.8.3 <http://underscorejs.org/LICENSE>\n * Copyright 2009-2015 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors\n * Available under MIT license <https://lodash.com/license>\n */\nvar baseCopy = require('lodash._basecopy'),\n    keys = require('lodash.keys');\n\n/**\n * The base implementation of `_.assign` without support for argument juggling,\n * multiple sources, and `customizer` functions.\n *\n * @private\n * @param {Object} object The destination object.\n * @param {Object} source The source object.\n * @returns {Object} Returns `object`.\n */\nfunction baseAssign(object, source) {\n  return source == null\n    ? object\n    : baseCopy(source, keys(source), object);\n}\n\nmodule.exports = baseAssign;\n\n},{\"lodash._basecopy\":56,\"lodash.keys\":63}],56:[function(require,module,exports){\n/**\n * lodash 3.0.1 (Custom Build) <https://lodash.com/>\n * Build: `lodash modern modularize exports=\"npm\" -o ./`\n * Copyright 2012-2015 The Dojo Foundation <http://dojofoundation.org/>\n * Based on Underscore.js 1.8.3 <http://underscorejs.org/LICENSE>\n * Copyright 2009-2015 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors\n * Available under MIT license <https://lodash.com/license>\n */\n\n/**\n * Copies properties of `source` to `object`.\n *\n * @private\n * @param {Object} source The object to copy properties from.\n * @param {Array} props The property names to copy.\n * @param {Object} [object={}] The object to copy properties to.\n * @returns {Object} Returns `object`.\n */\nfunction baseCopy(source, props, object) {\n  object || (object = {});\n\n  var index = -1,\n      length = props.length;\n\n  while (++index < length) {\n    var key = props[index];\n    object[key] = source[key];\n  }\n  return object;\n}\n\nmodule.exports = baseCopy;\n\n},{}],57:[function(require,module,exports){\n/**\n * lodash 3.0.3 (Custom Build) <https://lodash.com/>\n * Build: `lodash modern modularize exports=\"npm\" -o ./`\n * Copyright 2012-2015 The Dojo Foundation <http://dojofoundation.org/>\n * Based on Underscore.js 1.8.3 <http://underscorejs.org/LICENSE>\n * Copyright 2009-2015 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors\n * Available under MIT license <https://lodash.com/license>\n */\n\n/**\n * The base implementation of `_.create` without support for assigning\n * properties to the created object.\n *\n * @private\n * @param {Object} prototype The object to inherit from.\n * @returns {Object} Returns the new object.\n */\nvar baseCreate = (function() {\n  function object() {}\n  return function(prototype) {\n    if (isObject(prototype)) {\n      object.prototype = prototype;\n      var result = new object;\n      object.prototype = undefined;\n    }\n    return result || {};\n  };\n}());\n\n/**\n * Checks if `value` is the [language type](https://es5.github.io/#x8) of `Object`.\n * (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)\n *\n * @static\n * @memberOf _\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is an object, else `false`.\n * @example\n *\n * _.isObject({});\n * // => true\n *\n * _.isObject([1, 2, 3]);\n * // => true\n *\n * _.isObject(1);\n * // => false\n */\nfunction isObject(value) {\n  // Avoid a V8 JIT bug in Chrome 19-20.\n  // See https://code.google.com/p/v8/issues/detail?id=2291 for more details.\n  var type = typeof value;\n  return !!value && (type == 'object' || type == 'function');\n}\n\nmodule.exports = baseCreate;\n\n},{}],58:[function(require,module,exports){\n/**\n * lodash 3.9.1 (Custom Build) <https://lodash.com/>\n * Build: `lodash modern modularize exports=\"npm\" -o ./`\n * Copyright 2012-2015 The Dojo Foundation <http://dojofoundation.org/>\n * Based on Underscore.js 1.8.3 <http://underscorejs.org/LICENSE>\n * Copyright 2009-2015 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors\n * Available under MIT license <https://lodash.com/license>\n */\n\n/** `Object#toString` result references. */\nvar funcTag = '[object Function]';\n\n/** Used to detect host constructors (Safari > 5). */\nvar reIsHostCtor = /^\\[object .+?Constructor\\]$/;\n\n/**\n * Checks if `value` is object-like.\n *\n * @private\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is object-like, else `false`.\n */\nfunction isObjectLike(value) {\n  return !!value && typeof value == 'object';\n}\n\n/** Used for native method references. */\nvar objectProto = Object.prototype;\n\n/** Used to resolve the decompiled source of functions. */\nvar fnToString = Function.prototype.toString;\n\n/** Used to check objects for own properties. */\nvar hasOwnProperty = objectProto.hasOwnProperty;\n\n/**\n * Used to resolve the [`toStringTag`](http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring)\n * of values.\n */\nvar objToString = objectProto.toString;\n\n/** Used to detect if a method is native. */\nvar reIsNative = RegExp('^' +\n  fnToString.call(hasOwnProperty).replace(/[\\\\^$.*+?()[\\]{}|]/g, '\\\\$&')\n  .replace(/hasOwnProperty|(function).*?(?=\\\\\\()| for .+?(?=\\\\\\])/g, '$1.*?') + '$'\n);\n\n/**\n * Gets the native function at `key` of `object`.\n *\n * @private\n * @param {Object} object The object to query.\n * @param {string} key The key of the method to get.\n * @returns {*} Returns the function if it's native, else `undefined`.\n */\nfunction getNative(object, key) {\n  var value = object == null ? undefined : object[key];\n  return isNative(value) ? value : undefined;\n}\n\n/**\n * Checks if `value` is classified as a `Function` object.\n *\n * @static\n * @memberOf _\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`.\n * @example\n *\n * _.isFunction(_);\n * // => true\n *\n * _.isFunction(/abc/);\n * // => false\n */\nfunction isFunction(value) {\n  // The use of `Object#toString` avoids issues with the `typeof` operator\n  // in older versions of Chrome and Safari which return 'function' for regexes\n  // and Safari 8 equivalents which return 'object' for typed array constructors.\n  return isObject(value) && objToString.call(value) == funcTag;\n}\n\n/**\n * Checks if `value` is the [language type](https://es5.github.io/#x8) of `Object`.\n * (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)\n *\n * @static\n * @memberOf _\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is an object, else `false`.\n * @example\n *\n * _.isObject({});\n * // => true\n *\n * _.isObject([1, 2, 3]);\n * // => true\n *\n * _.isObject(1);\n * // => false\n */\nfunction isObject(value) {\n  // Avoid a V8 JIT bug in Chrome 19-20.\n  // See https://code.google.com/p/v8/issues/detail?id=2291 for more details.\n  var type = typeof value;\n  return !!value && (type == 'object' || type == 'function');\n}\n\n/**\n * Checks if `value` is a native function.\n *\n * @static\n * @memberOf _\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a native function, else `false`.\n * @example\n *\n * _.isNative(Array.prototype.push);\n * // => true\n *\n * _.isNative(_);\n * // => false\n */\nfunction isNative(value) {\n  if (value == null) {\n    return false;\n  }\n  if (isFunction(value)) {\n    return reIsNative.test(fnToString.call(value));\n  }\n  return isObjectLike(value) && reIsHostCtor.test(value);\n}\n\nmodule.exports = getNative;\n\n},{}],59:[function(require,module,exports){\n/**\n * lodash 3.0.9 (Custom Build) <https://lodash.com/>\n * Build: `lodash modern modularize exports=\"npm\" -o ./`\n * Copyright 2012-2015 The Dojo Foundation <http://dojofoundation.org/>\n * Based on Underscore.js 1.8.3 <http://underscorejs.org/LICENSE>\n * Copyright 2009-2015 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors\n * Available under MIT license <https://lodash.com/license>\n */\n\n/** Used to detect unsigned integer values. */\nvar reIsUint = /^\\d+$/;\n\n/**\n * Used as the [maximum length](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-number.max_safe_integer)\n * of an array-like value.\n */\nvar MAX_SAFE_INTEGER = 9007199254740991;\n\n/**\n * The base implementation of `_.property` without support for deep paths.\n *\n * @private\n * @param {string} key The key of the property to get.\n * @returns {Function} Returns the new function.\n */\nfunction baseProperty(key) {\n  return function(object) {\n    return object == null ? undefined : object[key];\n  };\n}\n\n/**\n * Gets the \"length\" property value of `object`.\n *\n * **Note:** This function is used to avoid a [JIT bug](https://bugs.webkit.org/show_bug.cgi?id=142792)\n * that affects Safari on at least iOS 8.1-8.3 ARM64.\n *\n * @private\n * @param {Object} object The object to query.\n * @returns {*} Returns the \"length\" value.\n */\nvar getLength = baseProperty('length');\n\n/**\n * Checks if `value` is array-like.\n *\n * @private\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is array-like, else `false`.\n */\nfunction isArrayLike(value) {\n  return value != null && isLength(getLength(value));\n}\n\n/**\n * Checks if `value` is a valid array-like index.\n *\n * @private\n * @param {*} value The value to check.\n * @param {number} [length=MAX_SAFE_INTEGER] The upper bounds of a valid index.\n * @returns {boolean} Returns `true` if `value` is a valid index, else `false`.\n */\nfunction isIndex(value, length) {\n  value = (typeof value == 'number' || reIsUint.test(value)) ? +value : -1;\n  length = length == null ? MAX_SAFE_INTEGER : length;\n  return value > -1 && value % 1 == 0 && value < length;\n}\n\n/**\n * Checks if the provided arguments are from an iteratee call.\n *\n * @private\n * @param {*} value The potential iteratee value argument.\n * @param {*} index The potential iteratee index or key argument.\n * @param {*} object The potential iteratee object argument.\n * @returns {boolean} Returns `true` if the arguments are from an iteratee call, else `false`.\n */\nfunction isIterateeCall(value, index, object) {\n  if (!isObject(object)) {\n    return false;\n  }\n  var type = typeof index;\n  if (type == 'number'\n      ? (isArrayLike(object) && isIndex(index, object.length))\n      : (type == 'string' && index in object)) {\n    var other = object[index];\n    return value === value ? (value === other) : (other !== other);\n  }\n  return false;\n}\n\n/**\n * Checks if `value` is a valid array-like length.\n *\n * **Note:** This function is based on [`ToLength`](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-tolength).\n *\n * @private\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a valid length, else `false`.\n */\nfunction isLength(value) {\n  return typeof value == 'number' && value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER;\n}\n\n/**\n * Checks if `value` is the [language type](https://es5.github.io/#x8) of `Object`.\n * (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)\n *\n * @static\n * @memberOf _\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is an object, else `false`.\n * @example\n *\n * _.isObject({});\n * // => true\n *\n * _.isObject([1, 2, 3]);\n * // => true\n *\n * _.isObject(1);\n * // => false\n */\nfunction isObject(value) {\n  // Avoid a V8 JIT bug in Chrome 19-20.\n  // See https://code.google.com/p/v8/issues/detail?id=2291 for more details.\n  var type = typeof value;\n  return !!value && (type == 'object' || type == 'function');\n}\n\nmodule.exports = isIterateeCall;\n\n},{}],60:[function(require,module,exports){\n/**\n * lodash 3.1.1 (Custom Build) <https://lodash.com/>\n * Build: `lodash modern modularize exports=\"npm\" -o ./`\n * Copyright 2012-2015 The Dojo Foundation <http://dojofoundation.org/>\n * Based on Underscore.js 1.8.3 <http://underscorejs.org/LICENSE>\n * Copyright 2009-2015 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors\n * Available under MIT license <https://lodash.com/license>\n */\nvar baseAssign = require('lodash._baseassign'),\n    baseCreate = require('lodash._basecreate'),\n    isIterateeCall = require('lodash._isiterateecall');\n\n/**\n * Creates an object that inherits from the given `prototype` object. If a\n * `properties` object is provided its own enumerable properties are assigned\n * to the created object.\n *\n * @static\n * @memberOf _\n * @category Object\n * @param {Object} prototype The object to inherit from.\n * @param {Object} [properties] The properties to assign to the object.\n * @param- {Object} [guard] Enables use as a callback for functions like `_.map`.\n * @returns {Object} Returns the new object.\n * @example\n *\n * function Shape() {\n *   this.x = 0;\n *   this.y = 0;\n * }\n *\n * function Circle() {\n *   Shape.call(this);\n * }\n *\n * Circle.prototype = _.create(Shape.prototype, {\n *   'constructor': Circle\n * });\n *\n * var circle = new Circle;\n * circle instanceof Circle;\n * // => true\n *\n * circle instanceof Shape;\n * // => true\n */\nfunction create(prototype, properties, guard) {\n  var result = baseCreate(prototype);\n  if (guard && isIterateeCall(prototype, properties, guard)) {\n    properties = undefined;\n  }\n  return properties ? baseAssign(result, properties) : result;\n}\n\nmodule.exports = create;\n\n},{\"lodash._baseassign\":55,\"lodash._basecreate\":57,\"lodash._isiterateecall\":59}],61:[function(require,module,exports){\n/**\n * lodash (Custom Build) <https://lodash.com/>\n * Build: `lodash modularize exports=\"npm\" -o ./`\n * Copyright jQuery Foundation and other contributors <https://jquery.org/>\n * Released under MIT license <https://lodash.com/license>\n * Based on Underscore.js 1.8.3 <http://underscorejs.org/LICENSE>\n * Copyright Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors\n */\n\n/** Used as references for various `Number` constants. */\nvar MAX_SAFE_INTEGER = 9007199254740991;\n\n/** `Object#toString` result references. */\nvar argsTag = '[object Arguments]',\n    funcTag = '[object Function]',\n    genTag = '[object GeneratorFunction]';\n\n/** Used for built-in method references. */\nvar objectProto = Object.prototype;\n\n/** Used to check objects for own properties. */\nvar hasOwnProperty = objectProto.hasOwnProperty;\n\n/**\n * Used to resolve the\n * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring)\n * of values.\n */\nvar objectToString = objectProto.toString;\n\n/** Built-in value references. */\nvar propertyIsEnumerable = objectProto.propertyIsEnumerable;\n\n/**\n * Checks if `value` is likely an `arguments` object.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is an `arguments` object,\n *  else `false`.\n * @example\n *\n * _.isArguments(function() { return arguments; }());\n * // => true\n *\n * _.isArguments([1, 2, 3]);\n * // => false\n */\nfunction isArguments(value) {\n  // Safari 8.1 makes `arguments.callee` enumerable in strict mode.\n  return isArrayLikeObject(value) && hasOwnProperty.call(value, 'callee') &&\n    (!propertyIsEnumerable.call(value, 'callee') || objectToString.call(value) == argsTag);\n}\n\n/**\n * Checks if `value` is array-like. A value is considered array-like if it's\n * not a function and has a `value.length` that's an integer greater than or\n * equal to `0` and less than or equal to `Number.MAX_SAFE_INTEGER`.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is array-like, else `false`.\n * @example\n *\n * _.isArrayLike([1, 2, 3]);\n * // => true\n *\n * _.isArrayLike(document.body.children);\n * // => true\n *\n * _.isArrayLike('abc');\n * // => true\n *\n * _.isArrayLike(_.noop);\n * // => false\n */\nfunction isArrayLike(value) {\n  return value != null && isLength(value.length) && !isFunction(value);\n}\n\n/**\n * This method is like `_.isArrayLike` except that it also checks if `value`\n * is an object.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is an array-like object,\n *  else `false`.\n * @example\n *\n * _.isArrayLikeObject([1, 2, 3]);\n * // => true\n *\n * _.isArrayLikeObject(document.body.children);\n * // => true\n *\n * _.isArrayLikeObject('abc');\n * // => false\n *\n * _.isArrayLikeObject(_.noop);\n * // => false\n */\nfunction isArrayLikeObject(value) {\n  return isObjectLike(value) && isArrayLike(value);\n}\n\n/**\n * Checks if `value` is classified as a `Function` object.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a function, else `false`.\n * @example\n *\n * _.isFunction(_);\n * // => true\n *\n * _.isFunction(/abc/);\n * // => false\n */\nfunction isFunction(value) {\n  // The use of `Object#toString` avoids issues with the `typeof` operator\n  // in Safari 8-9 which returns 'object' for typed array and other constructors.\n  var tag = isObject(value) ? objectToString.call(value) : '';\n  return tag == funcTag || tag == genTag;\n}\n\n/**\n * Checks if `value` is a valid array-like length.\n *\n * **Note:** This method is loosely based on\n * [`ToLength`](http://ecma-international.org/ecma-262/7.0/#sec-tolength).\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a valid length, else `false`.\n * @example\n *\n * _.isLength(3);\n * // => true\n *\n * _.isLength(Number.MIN_VALUE);\n * // => false\n *\n * _.isLength(Infinity);\n * // => false\n *\n * _.isLength('3');\n * // => false\n */\nfunction isLength(value) {\n  return typeof value == 'number' &&\n    value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER;\n}\n\n/**\n * Checks if `value` is the\n * [language type](http://www.ecma-international.org/ecma-262/7.0/#sec-ecmascript-language-types)\n * of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is an object, else `false`.\n * @example\n *\n * _.isObject({});\n * // => true\n *\n * _.isObject([1, 2, 3]);\n * // => true\n *\n * _.isObject(_.noop);\n * // => true\n *\n * _.isObject(null);\n * // => false\n */\nfunction isObject(value) {\n  var type = typeof value;\n  return !!value && (type == 'object' || type == 'function');\n}\n\n/**\n * Checks if `value` is object-like. A value is object-like if it's not `null`\n * and has a `typeof` result of \"object\".\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is object-like, else `false`.\n * @example\n *\n * _.isObjectLike({});\n * // => true\n *\n * _.isObjectLike([1, 2, 3]);\n * // => true\n *\n * _.isObjectLike(_.noop);\n * // => false\n *\n * _.isObjectLike(null);\n * // => false\n */\nfunction isObjectLike(value) {\n  return !!value && typeof value == 'object';\n}\n\nmodule.exports = isArguments;\n\n},{}],62:[function(require,module,exports){\n/**\n * lodash 3.0.4 (Custom Build) <https://lodash.com/>\n * Build: `lodash modern modularize exports=\"npm\" -o ./`\n * Copyright 2012-2015 The Dojo Foundation <http://dojofoundation.org/>\n * Based on Underscore.js 1.8.3 <http://underscorejs.org/LICENSE>\n * Copyright 2009-2015 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors\n * Available under MIT license <https://lodash.com/license>\n */\n\n/** `Object#toString` result references. */\nvar arrayTag = '[object Array]',\n    funcTag = '[object Function]';\n\n/** Used to detect host constructors (Safari > 5). */\nvar reIsHostCtor = /^\\[object .+?Constructor\\]$/;\n\n/**\n * Checks if `value` is object-like.\n *\n * @private\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is object-like, else `false`.\n */\nfunction isObjectLike(value) {\n  return !!value && typeof value == 'object';\n}\n\n/** Used for native method references. */\nvar objectProto = Object.prototype;\n\n/** Used to resolve the decompiled source of functions. */\nvar fnToString = Function.prototype.toString;\n\n/** Used to check objects for own properties. */\nvar hasOwnProperty = objectProto.hasOwnProperty;\n\n/**\n * Used to resolve the [`toStringTag`](http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring)\n * of values.\n */\nvar objToString = objectProto.toString;\n\n/** Used to detect if a method is native. */\nvar reIsNative = RegExp('^' +\n  fnToString.call(hasOwnProperty).replace(/[\\\\^$.*+?()[\\]{}|]/g, '\\\\$&')\n  .replace(/hasOwnProperty|(function).*?(?=\\\\\\()| for .+?(?=\\\\\\])/g, '$1.*?') + '$'\n);\n\n/* Native method references for those with the same name as other `lodash` methods. */\nvar nativeIsArray = getNative(Array, 'isArray');\n\n/**\n * Used as the [maximum length](http://ecma-international.org/ecma-262/6.0/#sec-number.max_safe_integer)\n * of an array-like value.\n */\nvar MAX_SAFE_INTEGER = 9007199254740991;\n\n/**\n * Gets the native function at `key` of `object`.\n *\n * @private\n * @param {Object} object The object to query.\n * @param {string} key The key of the method to get.\n * @returns {*} Returns the function if it's native, else `undefined`.\n */\nfunction getNative(object, key) {\n  var value = object == null ? undefined : object[key];\n  return isNative(value) ? value : undefined;\n}\n\n/**\n * Checks if `value` is a valid array-like length.\n *\n * **Note:** This function is based on [`ToLength`](http://ecma-international.org/ecma-262/6.0/#sec-tolength).\n *\n * @private\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a valid length, else `false`.\n */\nfunction isLength(value) {\n  return typeof value == 'number' && value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER;\n}\n\n/**\n * Checks if `value` is classified as an `Array` object.\n *\n * @static\n * @memberOf _\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`.\n * @example\n *\n * _.isArray([1, 2, 3]);\n * // => true\n *\n * _.isArray(function() { return arguments; }());\n * // => false\n */\nvar isArray = nativeIsArray || function(value) {\n  return isObjectLike(value) && isLength(value.length) && objToString.call(value) == arrayTag;\n};\n\n/**\n * Checks if `value` is classified as a `Function` object.\n *\n * @static\n * @memberOf _\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`.\n * @example\n *\n * _.isFunction(_);\n * // => true\n *\n * _.isFunction(/abc/);\n * // => false\n */\nfunction isFunction(value) {\n  // The use of `Object#toString` avoids issues with the `typeof` operator\n  // in older versions of Chrome and Safari which return 'function' for regexes\n  // and Safari 8 equivalents which return 'object' for typed array constructors.\n  return isObject(value) && objToString.call(value) == funcTag;\n}\n\n/**\n * Checks if `value` is the [language type](https://es5.github.io/#x8) of `Object`.\n * (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)\n *\n * @static\n * @memberOf _\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is an object, else `false`.\n * @example\n *\n * _.isObject({});\n * // => true\n *\n * _.isObject([1, 2, 3]);\n * // => true\n *\n * _.isObject(1);\n * // => false\n */\nfunction isObject(value) {\n  // Avoid a V8 JIT bug in Chrome 19-20.\n  // See https://code.google.com/p/v8/issues/detail?id=2291 for more details.\n  var type = typeof value;\n  return !!value && (type == 'object' || type == 'function');\n}\n\n/**\n * Checks if `value` is a native function.\n *\n * @static\n * @memberOf _\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a native function, else `false`.\n * @example\n *\n * _.isNative(Array.prototype.push);\n * // => true\n *\n * _.isNative(_);\n * // => false\n */\nfunction isNative(value) {\n  if (value == null) {\n    return false;\n  }\n  if (isFunction(value)) {\n    return reIsNative.test(fnToString.call(value));\n  }\n  return isObjectLike(value) && reIsHostCtor.test(value);\n}\n\nmodule.exports = isArray;\n\n},{}],63:[function(require,module,exports){\n/**\n * lodash 3.1.2 (Custom Build) <https://lodash.com/>\n * Build: `lodash modern modularize exports=\"npm\" -o ./`\n * Copyright 2012-2015 The Dojo Foundation <http://dojofoundation.org/>\n * Based on Underscore.js 1.8.3 <http://underscorejs.org/LICENSE>\n * Copyright 2009-2015 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors\n * Available under MIT license <https://lodash.com/license>\n */\nvar getNative = require('lodash._getnative'),\n    isArguments = require('lodash.isarguments'),\n    isArray = require('lodash.isarray');\n\n/** Used to detect unsigned integer values. */\nvar reIsUint = /^\\d+$/;\n\n/** Used for native method references. */\nvar objectProto = Object.prototype;\n\n/** Used to check objects for own properties. */\nvar hasOwnProperty = objectProto.hasOwnProperty;\n\n/* Native method references for those with the same name as other `lodash` methods. */\nvar nativeKeys = getNative(Object, 'keys');\n\n/**\n * Used as the [maximum length](http://ecma-international.org/ecma-262/6.0/#sec-number.max_safe_integer)\n * of an array-like value.\n */\nvar MAX_SAFE_INTEGER = 9007199254740991;\n\n/**\n * The base implementation of `_.property` without support for deep paths.\n *\n * @private\n * @param {string} key The key of the property to get.\n * @returns {Function} Returns the new function.\n */\nfunction baseProperty(key) {\n  return function(object) {\n    return object == null ? undefined : object[key];\n  };\n}\n\n/**\n * Gets the \"length\" property value of `object`.\n *\n * **Note:** This function is used to avoid a [JIT bug](https://bugs.webkit.org/show_bug.cgi?id=142792)\n * that affects Safari on at least iOS 8.1-8.3 ARM64.\n *\n * @private\n * @param {Object} object The object to query.\n * @returns {*} Returns the \"length\" value.\n */\nvar getLength = baseProperty('length');\n\n/**\n * Checks if `value` is array-like.\n *\n * @private\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is array-like, else `false`.\n */\nfunction isArrayLike(value) {\n  return value != null && isLength(getLength(value));\n}\n\n/**\n * Checks if `value` is a valid array-like index.\n *\n * @private\n * @param {*} value The value to check.\n * @param {number} [length=MAX_SAFE_INTEGER] The upper bounds of a valid index.\n * @returns {boolean} Returns `true` if `value` is a valid index, else `false`.\n */\nfunction isIndex(value, length) {\n  value = (typeof value == 'number' || reIsUint.test(value)) ? +value : -1;\n  length = length == null ? MAX_SAFE_INTEGER : length;\n  return value > -1 && value % 1 == 0 && value < length;\n}\n\n/**\n * Checks if `value` is a valid array-like length.\n *\n * **Note:** This function is based on [`ToLength`](http://ecma-international.org/ecma-262/6.0/#sec-tolength).\n *\n * @private\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a valid length, else `false`.\n */\nfunction isLength(value) {\n  return typeof value == 'number' && value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER;\n}\n\n/**\n * A fallback implementation of `Object.keys` which creates an array of the\n * own enumerable property names of `object`.\n *\n * @private\n * @param {Object} object The object to query.\n * @returns {Array} Returns the array of property names.\n */\nfunction shimKeys(object) {\n  var props = keysIn(object),\n      propsLength = props.length,\n      length = propsLength && object.length;\n\n  var allowIndexes = !!length && isLength(length) &&\n    (isArray(object) || isArguments(object));\n\n  var index = -1,\n      result = [];\n\n  while (++index < propsLength) {\n    var key = props[index];\n    if ((allowIndexes && isIndex(key, length)) || hasOwnProperty.call(object, key)) {\n      result.push(key);\n    }\n  }\n  return result;\n}\n\n/**\n * Checks if `value` is the [language type](https://es5.github.io/#x8) of `Object`.\n * (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)\n *\n * @static\n * @memberOf _\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is an object, else `false`.\n * @example\n *\n * _.isObject({});\n * // => true\n *\n * _.isObject([1, 2, 3]);\n * // => true\n *\n * _.isObject(1);\n * // => false\n */\nfunction isObject(value) {\n  // Avoid a V8 JIT bug in Chrome 19-20.\n  // See https://code.google.com/p/v8/issues/detail?id=2291 for more details.\n  var type = typeof value;\n  return !!value && (type == 'object' || type == 'function');\n}\n\n/**\n * Creates an array of the own enumerable property names of `object`.\n *\n * **Note:** Non-object values are coerced to objects. See the\n * [ES spec](http://ecma-international.org/ecma-262/6.0/#sec-object.keys)\n * for more details.\n *\n * @static\n * @memberOf _\n * @category Object\n * @param {Object} object The object to query.\n * @returns {Array} Returns the array of property names.\n * @example\n *\n * function Foo() {\n *   this.a = 1;\n *   this.b = 2;\n * }\n *\n * Foo.prototype.c = 3;\n *\n * _.keys(new Foo);\n * // => ['a', 'b'] (iteration order is not guaranteed)\n *\n * _.keys('hi');\n * // => ['0', '1']\n */\nvar keys = !nativeKeys ? shimKeys : function(object) {\n  var Ctor = object == null ? undefined : object.constructor;\n  if ((typeof Ctor == 'function' && Ctor.prototype === object) ||\n      (typeof object != 'function' && isArrayLike(object))) {\n    return shimKeys(object);\n  }\n  return isObject(object) ? nativeKeys(object) : [];\n};\n\n/**\n * Creates an array of the own and inherited enumerable property names of `object`.\n *\n * **Note:** Non-object values are coerced to objects.\n *\n * @static\n * @memberOf _\n * @category Object\n * @param {Object} object The object to query.\n * @returns {Array} Returns the array of property names.\n * @example\n *\n * function Foo() {\n *   this.a = 1;\n *   this.b = 2;\n * }\n *\n * Foo.prototype.c = 3;\n *\n * _.keysIn(new Foo);\n * // => ['a', 'b', 'c'] (iteration order is not guaranteed)\n */\nfunction keysIn(object) {\n  if (object == null) {\n    return [];\n  }\n  if (!isObject(object)) {\n    object = Object(object);\n  }\n  var length = object.length;\n  length = (length && isLength(length) &&\n    (isArray(object) || isArguments(object)) && length) || 0;\n\n  var Ctor = object.constructor,\n      index = -1,\n      isProto = typeof Ctor == 'function' && Ctor.prototype === object,\n      result = Array(length),\n      skipIndexes = length > 0;\n\n  while (++index < length) {\n    result[index] = (index + '');\n  }\n  for (var key in object) {\n    if (!(skipIndexes && isIndex(key, length)) &&\n        !(key == 'constructor' && (isProto || !hasOwnProperty.call(object, key)))) {\n      result.push(key);\n    }\n  }\n  return result;\n}\n\nmodule.exports = keys;\n\n},{\"lodash._getnative\":58,\"lodash.isarguments\":61,\"lodash.isarray\":62}],64:[function(require,module,exports){\n(function (process){\nvar path = require('path');\nvar fs = require('fs');\nvar _0777 = parseInt('0777', 8);\n\nmodule.exports = mkdirP.mkdirp = mkdirP.mkdirP = mkdirP;\n\nfunction mkdirP (p, opts, f, made) {\n    if (typeof opts === 'function') {\n        f = opts;\n        opts = {};\n    }\n    else if (!opts || typeof opts !== 'object') {\n        opts = { mode: opts };\n    }\n\n    var mode = opts.mode;\n    var xfs = opts.fs || fs;\n\n    if (mode === undefined) {\n        mode = _0777 & (~process.umask());\n    }\n    if (!made) made = null;\n\n    var cb = f || function () {};\n    p = path.resolve(p);\n\n    xfs.mkdir(p, mode, function (er) {\n        if (!er) {\n            made = made || p;\n            return cb(null, made);\n        }\n        switch (er.code) {\n            case 'ENOENT':\n                mkdirP(path.dirname(p), opts, function (er, made) {\n                    if (er) cb(er, made);\n                    else mkdirP(p, opts, cb, made);\n                });\n                break;\n\n            // In the case of any other error, just see if there's a dir\n            // there already.  If so, then hooray!  If not, then something\n            // is borked.\n            default:\n                xfs.stat(p, function (er2, stat) {\n                    // if the stat fails, then that's super weird.\n                    // let the original error be the failure reason.\n                    if (er2 || !stat.isDirectory()) cb(er, made)\n                    else cb(null, made);\n                });\n                break;\n        }\n    });\n}\n\nmkdirP.sync = function sync (p, opts, made) {\n    if (!opts || typeof opts !== 'object') {\n        opts = { mode: opts };\n    }\n\n    var mode = opts.mode;\n    var xfs = opts.fs || fs;\n\n    if (mode === undefined) {\n        mode = _0777 & (~process.umask());\n    }\n    if (!made) made = null;\n\n    p = path.resolve(p);\n\n    try {\n        xfs.mkdirSync(p, mode);\n        made = made || p;\n    }\n    catch (err0) {\n        switch (err0.code) {\n            case 'ENOENT' :\n                made = sync(path.dirname(p), opts, made);\n                sync(p, opts, made);\n                break;\n\n            // In the case of any other error, just see if there's a dir\n            // there already.  If so, then hooray!  If not, then something\n            // is borked.\n            default:\n                var stat;\n                try {\n                    stat = xfs.statSync(p);\n                }\n                catch (err1) {\n                    throw err0;\n                }\n                if (!stat.isDirectory()) throw err0;\n                break;\n        }\n    }\n\n    return made;\n};\n\n}).call(this,require('_process'))\n},{\"_process\":67,\"fs\":42,\"path\":42}],65:[function(require,module,exports){\nexports.endianness = function () { return 'LE' };\n\nexports.hostname = function () {\n    if (typeof location !== 'undefined') {\n        return location.hostname\n    }\n    else return '';\n};\n\nexports.loadavg = function () { return [] };\n\nexports.uptime = function () { return 0 };\n\nexports.freemem = function () {\n    return Number.MAX_VALUE;\n};\n\nexports.totalmem = function () {\n    return Number.MAX_VALUE;\n};\n\nexports.cpus = function () { return [] };\n\nexports.type = function () { return 'Browser' };\n\nexports.release = function () {\n    if (typeof navigator !== 'undefined') {\n        return navigator.appVersion;\n    }\n    return '';\n};\n\nexports.networkInterfaces\n= exports.getNetworkInterfaces\n= function () { return {} };\n\nexports.arch = function () { return 'javascript' };\n\nexports.platform = function () { return 'browser' };\n\nexports.tmpdir = exports.tmpDir = function () {\n    return '/tmp';\n};\n\nexports.EOL = '\\n';\n\n},{}],66:[function(require,module,exports){\n(function (process){\n'use strict';\n\nif (!process.version ||\n    process.version.indexOf('v0.') === 0 ||\n    process.version.indexOf('v1.') === 0 && process.version.indexOf('v1.8.') !== 0) {\n  module.exports = nextTick;\n} else {\n  module.exports = process.nextTick;\n}\n\nfunction nextTick(fn, arg1, arg2, arg3) {\n  if (typeof fn !== 'function') {\n    throw new TypeError('\"callback\" argument must be a function');\n  }\n  var len = arguments.length;\n  var args, i;\n  switch (len) {\n  case 0:\n  case 1:\n    return process.nextTick(fn);\n  case 2:\n    return process.nextTick(function afterTickOne() {\n      fn.call(null, arg1);\n    });\n  case 3:\n    return process.nextTick(function afterTickTwo() {\n      fn.call(null, arg1, arg2);\n    });\n  case 4:\n    return process.nextTick(function afterTickThree() {\n      fn.call(null, arg1, arg2, arg3);\n    });\n  default:\n    args = new Array(len - 1);\n    i = 0;\n    while (i < args.length) {\n      args[i++] = arguments[i];\n    }\n    return process.nextTick(function afterTick() {\n      fn.apply(null, args);\n    });\n  }\n}\n\n}).call(this,require('_process'))\n},{\"_process\":67}],67:[function(require,module,exports){\n// shim for using process in browser\nvar process = module.exports = {};\n\n// cached from whatever global is present so that test runners that stub it\n// don't break things.  But we need to wrap it in a try catch in case it is\n// wrapped in strict mode code which doesn't define any globals.  It's inside a\n// function because try/catches deoptimize in certain engines.\n\nvar cachedSetTimeout;\nvar cachedClearTimeout;\n\nfunction defaultSetTimout() {\n    throw new Error('setTimeout has not been defined');\n}\nfunction defaultClearTimeout () {\n    throw new Error('clearTimeout has not been defined');\n}\n(function () {\n    try {\n        if (typeof setTimeout === 'function') {\n            cachedSetTimeout = setTimeout;\n        } else {\n            cachedSetTimeout = defaultSetTimout;\n        }\n    } catch (e) {\n        cachedSetTimeout = defaultSetTimout;\n    }\n    try {\n        if (typeof clearTimeout === 'function') {\n            cachedClearTimeout = clearTimeout;\n        } else {\n            cachedClearTimeout = defaultClearTimeout;\n        }\n    } catch (e) {\n        cachedClearTimeout = defaultClearTimeout;\n    }\n} ())\nfunction runTimeout(fun) {\n    if (cachedSetTimeout === setTimeout) {\n        //normal enviroments in sane situations\n        return setTimeout(fun, 0);\n    }\n    // if setTimeout wasn't available but was latter defined\n    if ((cachedSetTimeout === defaultSetTimout || !cachedSetTimeout) && setTimeout) {\n        cachedSetTimeout = setTimeout;\n        return setTimeout(fun, 0);\n    }\n    try {\n        // when when somebody has screwed with setTimeout but no I.E. maddness\n        return cachedSetTimeout(fun, 0);\n    } catch(e){\n        try {\n            // When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally\n            return cachedSetTimeout.call(null, fun, 0);\n        } catch(e){\n            // same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error\n            return cachedSetTimeout.call(this, fun, 0);\n        }\n    }\n\n\n}\nfunction runClearTimeout(marker) {\n    if (cachedClearTimeout === clearTimeout) {\n        //normal enviroments in sane situations\n        return clearTimeout(marker);\n    }\n    // if clearTimeout wasn't available but was latter defined\n    if ((cachedClearTimeout === defaultClearTimeout || !cachedClearTimeout) && clearTimeout) {\n        cachedClearTimeout = clearTimeout;\n        return clearTimeout(marker);\n    }\n    try {\n        // when when somebody has screwed with setTimeout but no I.E. maddness\n        return cachedClearTimeout(marker);\n    } catch (e){\n        try {\n            // When we are in I.E. but the script has been evaled so I.E. doesn't  trust the global object when called normally\n            return cachedClearTimeout.call(null, marker);\n        } catch (e){\n            // same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error.\n            // Some versions of I.E. have different rules for clearTimeout vs setTimeout\n            return cachedClearTimeout.call(this, marker);\n        }\n    }\n\n\n\n}\nvar queue = [];\nvar draining = false;\nvar currentQueue;\nvar queueIndex = -1;\n\nfunction cleanUpNextTick() {\n    if (!draining || !currentQueue) {\n        return;\n    }\n    draining = false;\n    if (currentQueue.length) {\n        queue = currentQueue.concat(queue);\n    } else {\n        queueIndex = -1;\n    }\n    if (queue.length) {\n        drainQueue();\n    }\n}\n\nfunction drainQueue() {\n    if (draining) {\n        return;\n    }\n    var timeout = runTimeout(cleanUpNextTick);\n    draining = true;\n\n    var len = queue.length;\n    while(len) {\n        currentQueue = queue;\n        queue = [];\n        while (++queueIndex < len) {\n            if (currentQueue) {\n                currentQueue[queueIndex].run();\n            }\n        }\n        queueIndex = -1;\n        len = queue.length;\n    }\n    currentQueue = null;\n    draining = false;\n    runClearTimeout(timeout);\n}\n\nprocess.nextTick = function (fun) {\n    var args = new Array(arguments.length - 1);\n    if (arguments.length > 1) {\n        for (var i = 1; i < arguments.length; i++) {\n            args[i - 1] = arguments[i];\n        }\n    }\n    queue.push(new Item(fun, args));\n    if (queue.length === 1 && !draining) {\n        runTimeout(drainQueue);\n    }\n};\n\n// v8 likes predictible objects\nfunction Item(fun, array) {\n    this.fun = fun;\n    this.array = array;\n}\nItem.prototype.run = function () {\n    this.fun.apply(null, this.array);\n};\nprocess.title = 'browser';\nprocess.browser = true;\nprocess.env = {};\nprocess.argv = [];\nprocess.version = ''; // empty string to avoid regexp issues\nprocess.versions = {};\n\nfunction noop() {}\n\nprocess.on = noop;\nprocess.addListener = noop;\nprocess.once = noop;\nprocess.off = noop;\nprocess.removeListener = noop;\nprocess.removeAllListeners = noop;\nprocess.emit = noop;\n\nprocess.binding = function (name) {\n    throw new Error('process.binding is not supported');\n};\n\nprocess.cwd = function () { return '/' };\nprocess.chdir = function (dir) {\n    throw new Error('process.chdir is not supported');\n};\nprocess.umask = function() { return 0; };\n\n},{}],68:[function(require,module,exports){\nmodule.exports = require(\"./lib/_stream_duplex.js\")\n\n},{\"./lib/_stream_duplex.js\":69}],69:[function(require,module,exports){\n// a duplex stream is just a stream that is both readable and writable.\n// Since JS doesn't have multiple prototypal inheritance, this class\n// prototypally inherits from Readable, and then parasitically from\n// Writable.\n\n'use strict';\n\n/*<replacement>*/\n\nvar objectKeys = Object.keys || function (obj) {\n  var keys = [];\n  for (var key in obj) {\n    keys.push(key);\n  }return keys;\n};\n/*</replacement>*/\n\nmodule.exports = Duplex;\n\n/*<replacement>*/\nvar processNextTick = require('process-nextick-args');\n/*</replacement>*/\n\n/*<replacement>*/\nvar util = require('core-util-is');\nutil.inherits = require('inherits');\n/*</replacement>*/\n\nvar Readable = require('./_stream_readable');\nvar Writable = require('./_stream_writable');\n\nutil.inherits(Duplex, Readable);\n\nvar keys = objectKeys(Writable.prototype);\nfor (var v = 0; v < keys.length; v++) {\n  var method = keys[v];\n  if (!Duplex.prototype[method]) Duplex.prototype[method] = Writable.prototype[method];\n}\n\nfunction Duplex(options) {\n  if (!(this instanceof Duplex)) return new Duplex(options);\n\n  Readable.call(this, options);\n  Writable.call(this, options);\n\n  if (options && options.readable === false) this.readable = false;\n\n  if (options && options.writable === false) this.writable = false;\n\n  this.allowHalfOpen = true;\n  if (options && options.allowHalfOpen === false) this.allowHalfOpen = false;\n\n  this.once('end', onend);\n}\n\n// the no-half-open enforcer\nfunction onend() {\n  // if we allow half-open state, or if the writable side ended,\n  // then we're ok.\n  if (this.allowHalfOpen || this._writableState.ended) return;\n\n  // no more data can be written.\n  // But allow more writes to happen in this tick.\n  processNextTick(onEndNT, this);\n}\n\nfunction onEndNT(self) {\n  self.end();\n}\n\nfunction forEach(xs, f) {\n  for (var i = 0, l = xs.length; i < l; i++) {\n    f(xs[i], i);\n  }\n}\n},{\"./_stream_readable\":71,\"./_stream_writable\":73,\"core-util-is\":45,\"inherits\":51,\"process-nextick-args\":66}],70:[function(require,module,exports){\n// a passthrough stream.\n// basically just the most minimal sort of Transform stream.\n// Every written chunk gets output as-is.\n\n'use strict';\n\nmodule.exports = PassThrough;\n\nvar Transform = require('./_stream_transform');\n\n/*<replacement>*/\nvar util = require('core-util-is');\nutil.inherits = require('inherits');\n/*</replacement>*/\n\nutil.inherits(PassThrough, Transform);\n\nfunction PassThrough(options) {\n  if (!(this instanceof PassThrough)) return new PassThrough(options);\n\n  Transform.call(this, options);\n}\n\nPassThrough.prototype._transform = function (chunk, encoding, cb) {\n  cb(null, chunk);\n};\n},{\"./_stream_transform\":72,\"core-util-is\":45,\"inherits\":51}],71:[function(require,module,exports){\n(function (process){\n'use strict';\n\nmodule.exports = Readable;\n\n/*<replacement>*/\nvar processNextTick = require('process-nextick-args');\n/*</replacement>*/\n\n/*<replacement>*/\nvar isArray = require('isarray');\n/*</replacement>*/\n\nReadable.ReadableState = ReadableState;\n\n/*<replacement>*/\nvar EE = require('events').EventEmitter;\n\nvar EElistenerCount = function (emitter, type) {\n  return emitter.listeners(type).length;\n};\n/*</replacement>*/\n\n/*<replacement>*/\nvar Stream;\n(function () {\n  try {\n    Stream = require('st' + 'ream');\n  } catch (_) {} finally {\n    if (!Stream) Stream = require('events').EventEmitter;\n  }\n})();\n/*</replacement>*/\n\nvar Buffer = require('buffer').Buffer;\n/*<replacement>*/\nvar bufferShim = require('buffer-shims');\n/*</replacement>*/\n\n/*<replacement>*/\nvar util = require('core-util-is');\nutil.inherits = require('inherits');\n/*</replacement>*/\n\n/*<replacement>*/\nvar debugUtil = require('util');\nvar debug = void 0;\nif (debugUtil && debugUtil.debuglog) {\n  debug = debugUtil.debuglog('stream');\n} else {\n  debug = function () {};\n}\n/*</replacement>*/\n\nvar BufferList = require('./internal/streams/BufferList');\nvar StringDecoder;\n\nutil.inherits(Readable, Stream);\n\nfunction prependListener(emitter, event, fn) {\n  if (typeof emitter.prependListener === 'function') {\n    return emitter.prependListener(event, fn);\n  } else {\n    // This is a hack to make sure that our error handler is attached before any\n    // userland ones.  NEVER DO THIS. This is here only because this code needs\n    // to continue to work with older versions of Node.js that do not include\n    // the prependListener() method. The goal is to eventually remove this hack.\n    if (!emitter._events || !emitter._events[event]) emitter.on(event, fn);else if (isArray(emitter._events[event])) emitter._events[event].unshift(fn);else emitter._events[event] = [fn, emitter._events[event]];\n  }\n}\n\nvar Duplex;\nfunction ReadableState(options, stream) {\n  Duplex = Duplex || require('./_stream_duplex');\n\n  options = options || {};\n\n  // object stream flag. Used to make read(n) ignore n and to\n  // make all the buffer merging and length checks go away\n  this.objectMode = !!options.objectMode;\n\n  if (stream instanceof Duplex) this.objectMode = this.objectMode || !!options.readableObjectMode;\n\n  // the point at which it stops calling _read() to fill the buffer\n  // Note: 0 is a valid value, means \"don't call _read preemptively ever\"\n  var hwm = options.highWaterMark;\n  var defaultHwm = this.objectMode ? 16 : 16 * 1024;\n  this.highWaterMark = hwm || hwm === 0 ? hwm : defaultHwm;\n\n  // cast to ints.\n  this.highWaterMark = ~ ~this.highWaterMark;\n\n  // A linked list is used to store data chunks instead of an array because the\n  // linked list can remove elements from the beginning faster than\n  // array.shift()\n  this.buffer = new BufferList();\n  this.length = 0;\n  this.pipes = null;\n  this.pipesCount = 0;\n  this.flowing = null;\n  this.ended = false;\n  this.endEmitted = false;\n  this.reading = false;\n\n  // a flag to be able to tell if the onwrite cb is called immediately,\n  // or on a later tick.  We set this to true at first, because any\n  // actions that shouldn't happen until \"later\" should generally also\n  // not happen before the first write call.\n  this.sync = true;\n\n  // whenever we return null, then we set a flag to say\n  // that we're awaiting a 'readable' event emission.\n  this.needReadable = false;\n  this.emittedReadable = false;\n  this.readableListening = false;\n  this.resumeScheduled = false;\n\n  // Crypto is kind of old and crusty.  Historically, its default string\n  // encoding is 'binary' so we have to make this configurable.\n  // Everything else in the universe uses 'utf8', though.\n  this.defaultEncoding = options.defaultEncoding || 'utf8';\n\n  // when piping, we only care about 'readable' events that happen\n  // after read()ing all the bytes and not getting any pushback.\n  this.ranOut = false;\n\n  // the number of writers that are awaiting a drain event in .pipe()s\n  this.awaitDrain = 0;\n\n  // if true, a maybeReadMore has been scheduled\n  this.readingMore = false;\n\n  this.decoder = null;\n  this.encoding = null;\n  if (options.encoding) {\n    if (!StringDecoder) StringDecoder = require('string_decoder/').StringDecoder;\n    this.decoder = new StringDecoder(options.encoding);\n    this.encoding = options.encoding;\n  }\n}\n\nvar Duplex;\nfunction Readable(options) {\n  Duplex = Duplex || require('./_stream_duplex');\n\n  if (!(this instanceof Readable)) return new Readable(options);\n\n  this._readableState = new ReadableState(options, this);\n\n  // legacy\n  this.readable = true;\n\n  if (options && typeof options.read === 'function') this._read = options.read;\n\n  Stream.call(this);\n}\n\n// Manually shove something into the read() buffer.\n// This returns true if the highWaterMark has not been hit yet,\n// similar to how Writable.write() returns true if you should\n// write() some more.\nReadable.prototype.push = function (chunk, encoding) {\n  var state = this._readableState;\n\n  if (!state.objectMode && typeof chunk === 'string') {\n    encoding = encoding || state.defaultEncoding;\n    if (encoding !== state.encoding) {\n      chunk = bufferShim.from(chunk, encoding);\n      encoding = '';\n    }\n  }\n\n  return readableAddChunk(this, state, chunk, encoding, false);\n};\n\n// Unshift should *always* be something directly out of read()\nReadable.prototype.unshift = function (chunk) {\n  var state = this._readableState;\n  return readableAddChunk(this, state, chunk, '', true);\n};\n\nReadable.prototype.isPaused = function () {\n  return this._readableState.flowing === false;\n};\n\nfunction readableAddChunk(stream, state, chunk, encoding, addToFront) {\n  var er = chunkInvalid(state, chunk);\n  if (er) {\n    stream.emit('error', er);\n  } else if (chunk === null) {\n    state.reading = false;\n    onEofChunk(stream, state);\n  } else if (state.objectMode || chunk && chunk.length > 0) {\n    if (state.ended && !addToFront) {\n      var e = new Error('stream.push() after EOF');\n      stream.emit('error', e);\n    } else if (state.endEmitted && addToFront) {\n      var _e = new Error('stream.unshift() after end event');\n      stream.emit('error', _e);\n    } else {\n      var skipAdd;\n      if (state.decoder && !addToFront && !encoding) {\n        chunk = state.decoder.write(chunk);\n        skipAdd = !state.objectMode && chunk.length === 0;\n      }\n\n      if (!addToFront) state.reading = false;\n\n      // Don't add to the buffer if we've decoded to an empty string chunk and\n      // we're not in object mode\n      if (!skipAdd) {\n        // if we want the data now, just emit it.\n        if (state.flowing && state.length === 0 && !state.sync) {\n          stream.emit('data', chunk);\n          stream.read(0);\n        } else {\n          // update the buffer info.\n          state.length += state.objectMode ? 1 : chunk.length;\n          if (addToFront) state.buffer.unshift(chunk);else state.buffer.push(chunk);\n\n          if (state.needReadable) emitReadable(stream);\n        }\n      }\n\n      maybeReadMore(stream, state);\n    }\n  } else if (!addToFront) {\n    state.reading = false;\n  }\n\n  return needMoreData(state);\n}\n\n// if it's past the high water mark, we can push in some more.\n// Also, if we have no data yet, we can stand some\n// more bytes.  This is to work around cases where hwm=0,\n// such as the repl.  Also, if the push() triggered a\n// readable event, and the user called read(largeNumber) such that\n// needReadable was set, then we ought to push more, so that another\n// 'readable' event will be triggered.\nfunction needMoreData(state) {\n  return !state.ended && (state.needReadable || state.length < state.highWaterMark || state.length === 0);\n}\n\n// backwards compatibility.\nReadable.prototype.setEncoding = function (enc) {\n  if (!StringDecoder) StringDecoder = require('string_decoder/').StringDecoder;\n  this._readableState.decoder = new StringDecoder(enc);\n  this._readableState.encoding = enc;\n  return this;\n};\n\n// Don't raise the hwm > 8MB\nvar MAX_HWM = 0x800000;\nfunction computeNewHighWaterMark(n) {\n  if (n >= MAX_HWM) {\n    n = MAX_HWM;\n  } else {\n    // Get the next highest power of 2 to prevent increasing hwm excessively in\n    // tiny amounts\n    n--;\n    n |= n >>> 1;\n    n |= n >>> 2;\n    n |= n >>> 4;\n    n |= n >>> 8;\n    n |= n >>> 16;\n    n++;\n  }\n  return n;\n}\n\n// This function is designed to be inlinable, so please take care when making\n// changes to the function body.\nfunction howMuchToRead(n, state) {\n  if (n <= 0 || state.length === 0 && state.ended) return 0;\n  if (state.objectMode) return 1;\n  if (n !== n) {\n    // Only flow one buffer at a time\n    if (state.flowing && state.length) return state.buffer.head.data.length;else return state.length;\n  }\n  // If we're asking for more than the current hwm, then raise the hwm.\n  if (n > state.highWaterMark) state.highWaterMark = computeNewHighWaterMark(n);\n  if (n <= state.length) return n;\n  // Don't have enough\n  if (!state.ended) {\n    state.needReadable = true;\n    return 0;\n  }\n  return state.length;\n}\n\n// you can override either this method, or the async _read(n) below.\nReadable.prototype.read = function (n) {\n  debug('read', n);\n  n = parseInt(n, 10);\n  var state = this._readableState;\n  var nOrig = n;\n\n  if (n !== 0) state.emittedReadable = false;\n\n  // if we're doing read(0) to trigger a readable event, but we\n  // already have a bunch of data in the buffer, then just trigger\n  // the 'readable' event and move on.\n  if (n === 0 && state.needReadable && (state.length >= state.highWaterMark || state.ended)) {\n    debug('read: emitReadable', state.length, state.ended);\n    if (state.length === 0 && state.ended) endReadable(this);else emitReadable(this);\n    return null;\n  }\n\n  n = howMuchToRead(n, state);\n\n  // if we've ended, and we're now clear, then finish it up.\n  if (n === 0 && state.ended) {\n    if (state.length === 0) endReadable(this);\n    return null;\n  }\n\n  // All the actual chunk generation logic needs to be\n  // *below* the call to _read.  The reason is that in certain\n  // synthetic stream cases, such as passthrough streams, _read\n  // may be a completely synchronous operation which may change\n  // the state of the read buffer, providing enough data when\n  // before there was *not* enough.\n  //\n  // So, the steps are:\n  // 1. Figure out what the state of things will be after we do\n  // a read from the buffer.\n  //\n  // 2. If that resulting state will trigger a _read, then call _read.\n  // Note that this may be asynchronous, or synchronous.  Yes, it is\n  // deeply ugly to write APIs this way, but that still doesn't mean\n  // that the Readable class should behave improperly, as streams are\n  // designed to be sync/async agnostic.\n  // Take note if the _read call is sync or async (ie, if the read call\n  // has returned yet), so that we know whether or not it's safe to emit\n  // 'readable' etc.\n  //\n  // 3. Actually pull the requested chunks out of the buffer and return.\n\n  // if we need a readable event, then we need to do some reading.\n  var doRead = state.needReadable;\n  debug('need readable', doRead);\n\n  // if we currently have less than the highWaterMark, then also read some\n  if (state.length === 0 || state.length - n < state.highWaterMark) {\n    doRead = true;\n    debug('length less than watermark', doRead);\n  }\n\n  // however, if we've ended, then there's no point, and if we're already\n  // reading, then it's unnecessary.\n  if (state.ended || state.reading) {\n    doRead = false;\n    debug('reading or ended', doRead);\n  } else if (doRead) {\n    debug('do read');\n    state.reading = true;\n    state.sync = true;\n    // if the length is currently zero, then we *need* a readable event.\n    if (state.length === 0) state.needReadable = true;\n    // call internal read method\n    this._read(state.highWaterMark);\n    state.sync = false;\n    // If _read pushed data synchronously, then `reading` will be false,\n    // and we need to re-evaluate how much data we can return to the user.\n    if (!state.reading) n = howMuchToRead(nOrig, state);\n  }\n\n  var ret;\n  if (n > 0) ret = fromList(n, state);else ret = null;\n\n  if (ret === null) {\n    state.needReadable = true;\n    n = 0;\n  } else {\n    state.length -= n;\n  }\n\n  if (state.length === 0) {\n    // If we have nothing in the buffer, then we want to know\n    // as soon as we *do* get something into the buffer.\n    if (!state.ended) state.needReadable = true;\n\n    // If we tried to read() past the EOF, then emit end on the next tick.\n    if (nOrig !== n && state.ended) endReadable(this);\n  }\n\n  if (ret !== null) this.emit('data', ret);\n\n  return ret;\n};\n\nfunction chunkInvalid(state, chunk) {\n  var er = null;\n  if (!Buffer.isBuffer(chunk) && typeof chunk !== 'string' && chunk !== null && chunk !== undefined && !state.objectMode) {\n    er = new TypeError('Invalid non-string/buffer chunk');\n  }\n  return er;\n}\n\nfunction onEofChunk(stream, state) {\n  if (state.ended) return;\n  if (state.decoder) {\n    var chunk = state.decoder.end();\n    if (chunk && chunk.length) {\n      state.buffer.push(chunk);\n      state.length += state.objectMode ? 1 : chunk.length;\n    }\n  }\n  state.ended = true;\n\n  // emit 'readable' now to make sure it gets picked up.\n  emitReadable(stream);\n}\n\n// Don't emit readable right away in sync mode, because this can trigger\n// another read() call => stack overflow.  This way, it might trigger\n// a nextTick recursion warning, but that's not so bad.\nfunction emitReadable(stream) {\n  var state = stream._readableState;\n  state.needReadable = false;\n  if (!state.emittedReadable) {\n    debug('emitReadable', state.flowing);\n    state.emittedReadable = true;\n    if (state.sync) processNextTick(emitReadable_, stream);else emitReadable_(stream);\n  }\n}\n\nfunction emitReadable_(stream) {\n  debug('emit readable');\n  stream.emit('readable');\n  flow(stream);\n}\n\n// at this point, the user has presumably seen the 'readable' event,\n// and called read() to consume some data.  that may have triggered\n// in turn another _read(n) call, in which case reading = true if\n// it's in progress.\n// However, if we're not ended, or reading, and the length < hwm,\n// then go ahead and try to read some more preemptively.\nfunction maybeReadMore(stream, state) {\n  if (!state.readingMore) {\n    state.readingMore = true;\n    processNextTick(maybeReadMore_, stream, state);\n  }\n}\n\nfunction maybeReadMore_(stream, state) {\n  var len = state.length;\n  while (!state.reading && !state.flowing && !state.ended && state.length < state.highWaterMark) {\n    debug('maybeReadMore read 0');\n    stream.read(0);\n    if (len === state.length)\n      // didn't get any data, stop spinning.\n      break;else len = state.length;\n  }\n  state.readingMore = false;\n}\n\n// abstract method.  to be overridden in specific implementation classes.\n// call cb(er, data) where data is <= n in length.\n// for virtual (non-string, non-buffer) streams, \"length\" is somewhat\n// arbitrary, and perhaps not very meaningful.\nReadable.prototype._read = function (n) {\n  this.emit('error', new Error('not implemented'));\n};\n\nReadable.prototype.pipe = function (dest, pipeOpts) {\n  var src = this;\n  var state = this._readableState;\n\n  switch (state.pipesCount) {\n    case 0:\n      state.pipes = dest;\n      break;\n    case 1:\n      state.pipes = [state.pipes, dest];\n      break;\n    default:\n      state.pipes.push(dest);\n      break;\n  }\n  state.pipesCount += 1;\n  debug('pipe count=%d opts=%j', state.pipesCount, pipeOpts);\n\n  var doEnd = (!pipeOpts || pipeOpts.end !== false) && dest !== process.stdout && dest !== process.stderr;\n\n  var endFn = doEnd ? onend : cleanup;\n  if (state.endEmitted) processNextTick(endFn);else src.once('end', endFn);\n\n  dest.on('unpipe', onunpipe);\n  function onunpipe(readable) {\n    debug('onunpipe');\n    if (readable === src) {\n      cleanup();\n    }\n  }\n\n  function onend() {\n    debug('onend');\n    dest.end();\n  }\n\n  // when the dest drains, it reduces the awaitDrain counter\n  // on the source.  This would be more elegant with a .once()\n  // handler in flow(), but adding and removing repeatedly is\n  // too slow.\n  var ondrain = pipeOnDrain(src);\n  dest.on('drain', ondrain);\n\n  var cleanedUp = false;\n  function cleanup() {\n    debug('cleanup');\n    // cleanup event handlers once the pipe is broken\n    dest.removeListener('close', onclose);\n    dest.removeListener('finish', onfinish);\n    dest.removeListener('drain', ondrain);\n    dest.removeListener('error', onerror);\n    dest.removeListener('unpipe', onunpipe);\n    src.removeListener('end', onend);\n    src.removeListener('end', cleanup);\n    src.removeListener('data', ondata);\n\n    cleanedUp = true;\n\n    // if the reader is waiting for a drain event from this\n    // specific writer, then it would cause it to never start\n    // flowing again.\n    // So, if this is awaiting a drain, then we just call it now.\n    // If we don't know, then assume that we are waiting for one.\n    if (state.awaitDrain && (!dest._writableState || dest._writableState.needDrain)) ondrain();\n  }\n\n  // If the user pushes more data while we're writing to dest then we'll end up\n  // in ondata again. However, we only want to increase awaitDrain once because\n  // dest will only emit one 'drain' event for the multiple writes.\n  // => Introduce a guard on increasing awaitDrain.\n  var increasedAwaitDrain = false;\n  src.on('data', ondata);\n  function ondata(chunk) {\n    debug('ondata');\n    increasedAwaitDrain = false;\n    var ret = dest.write(chunk);\n    if (false === ret && !increasedAwaitDrain) {\n      // If the user unpiped during `dest.write()`, it is possible\n      // to get stuck in a permanently paused state if that write\n      // also returned false.\n      // => Check whether `dest` is still a piping destination.\n      if ((state.pipesCount === 1 && state.pipes === dest || state.pipesCount > 1 && indexOf(state.pipes, dest) !== -1) && !cleanedUp) {\n        debug('false write response, pause', src._readableState.awaitDrain);\n        src._readableState.awaitDrain++;\n        increasedAwaitDrain = true;\n      }\n      src.pause();\n    }\n  }\n\n  // if the dest has an error, then stop piping into it.\n  // however, don't suppress the throwing behavior for this.\n  function onerror(er) {\n    debug('onerror', er);\n    unpipe();\n    dest.removeListener('error', onerror);\n    if (EElistenerCount(dest, 'error') === 0) dest.emit('error', er);\n  }\n\n  // Make sure our error handler is attached before userland ones.\n  prependListener(dest, 'error', onerror);\n\n  // Both close and finish should trigger unpipe, but only once.\n  function onclose() {\n    dest.removeListener('finish', onfinish);\n    unpipe();\n  }\n  dest.once('close', onclose);\n  function onfinish() {\n    debug('onfinish');\n    dest.removeListener('close', onclose);\n    unpipe();\n  }\n  dest.once('finish', onfinish);\n\n  function unpipe() {\n    debug('unpipe');\n    src.unpipe(dest);\n  }\n\n  // tell the dest that it's being piped to\n  dest.emit('pipe', src);\n\n  // start the flow if it hasn't been started already.\n  if (!state.flowing) {\n    debug('pipe resume');\n    src.resume();\n  }\n\n  return dest;\n};\n\nfunction pipeOnDrain(src) {\n  return function () {\n    var state = src._readableState;\n    debug('pipeOnDrain', state.awaitDrain);\n    if (state.awaitDrain) state.awaitDrain--;\n    if (state.awaitDrain === 0 && EElistenerCount(src, 'data')) {\n      state.flowing = true;\n      flow(src);\n    }\n  };\n}\n\nReadable.prototype.unpipe = function (dest) {\n  var state = this._readableState;\n\n  // if we're not piping anywhere, then do nothing.\n  if (state.pipesCount === 0) return this;\n\n  // just one destination.  most common case.\n  if (state.pipesCount === 1) {\n    // passed in one, but it's not the right one.\n    if (dest && dest !== state.pipes) return this;\n\n    if (!dest) dest = state.pipes;\n\n    // got a match.\n    state.pipes = null;\n    state.pipesCount = 0;\n    state.flowing = false;\n    if (dest) dest.emit('unpipe', this);\n    return this;\n  }\n\n  // slow case. multiple pipe destinations.\n\n  if (!dest) {\n    // remove all.\n    var dests = state.pipes;\n    var len = state.pipesCount;\n    state.pipes = null;\n    state.pipesCount = 0;\n    state.flowing = false;\n\n    for (var _i = 0; _i < len; _i++) {\n      dests[_i].emit('unpipe', this);\n    }return this;\n  }\n\n  // try to find the right one.\n  var i = indexOf(state.pipes, dest);\n  if (i === -1) return this;\n\n  state.pipes.splice(i, 1);\n  state.pipesCount -= 1;\n  if (state.pipesCount === 1) state.pipes = state.pipes[0];\n\n  dest.emit('unpipe', this);\n\n  return this;\n};\n\n// set up data events if they are asked for\n// Ensure readable listeners eventually get something\nReadable.prototype.on = function (ev, fn) {\n  var res = Stream.prototype.on.call(this, ev, fn);\n\n  if (ev === 'data') {\n    // Start flowing on next tick if stream isn't explicitly paused\n    if (this._readableState.flowing !== false) this.resume();\n  } else if (ev === 'readable') {\n    var state = this._readableState;\n    if (!state.endEmitted && !state.readableListening) {\n      state.readableListening = state.needReadable = true;\n      state.emittedReadable = false;\n      if (!state.reading) {\n        processNextTick(nReadingNextTick, this);\n      } else if (state.length) {\n        emitReadable(this, state);\n      }\n    }\n  }\n\n  return res;\n};\nReadable.prototype.addListener = Readable.prototype.on;\n\nfunction nReadingNextTick(self) {\n  debug('readable nexttick read 0');\n  self.read(0);\n}\n\n// pause() and resume() are remnants of the legacy readable stream API\n// If the user uses them, then switch into old mode.\nReadable.prototype.resume = function () {\n  var state = this._readableState;\n  if (!state.flowing) {\n    debug('resume');\n    state.flowing = true;\n    resume(this, state);\n  }\n  return this;\n};\n\nfunction resume(stream, state) {\n  if (!state.resumeScheduled) {\n    state.resumeScheduled = true;\n    processNextTick(resume_, stream, state);\n  }\n}\n\nfunction resume_(stream, state) {\n  if (!state.reading) {\n    debug('resume read 0');\n    stream.read(0);\n  }\n\n  state.resumeScheduled = false;\n  state.awaitDrain = 0;\n  stream.emit('resume');\n  flow(stream);\n  if (state.flowing && !state.reading) stream.read(0);\n}\n\nReadable.prototype.pause = function () {\n  debug('call pause flowing=%j', this._readableState.flowing);\n  if (false !== this._readableState.flowing) {\n    debug('pause');\n    this._readableState.flowing = false;\n    this.emit('pause');\n  }\n  return this;\n};\n\nfunction flow(stream) {\n  var state = stream._readableState;\n  debug('flow', state.flowing);\n  while (state.flowing && stream.read() !== null) {}\n}\n\n// wrap an old-style stream as the async data source.\n// This is *not* part of the readable stream interface.\n// It is an ugly unfortunate mess of history.\nReadable.prototype.wrap = function (stream) {\n  var state = this._readableState;\n  var paused = false;\n\n  var self = this;\n  stream.on('end', function () {\n    debug('wrapped end');\n    if (state.decoder && !state.ended) {\n      var chunk = state.decoder.end();\n      if (chunk && chunk.length) self.push(chunk);\n    }\n\n    self.push(null);\n  });\n\n  stream.on('data', function (chunk) {\n    debug('wrapped data');\n    if (state.decoder) chunk = state.decoder.write(chunk);\n\n    // don't skip over falsy values in objectMode\n    if (state.objectMode && (chunk === null || chunk === undefined)) return;else if (!state.objectMode && (!chunk || !chunk.length)) return;\n\n    var ret = self.push(chunk);\n    if (!ret) {\n      paused = true;\n      stream.pause();\n    }\n  });\n\n  // proxy all the other methods.\n  // important when wrapping filters and duplexes.\n  for (var i in stream) {\n    if (this[i] === undefined && typeof stream[i] === 'function') {\n      this[i] = function (method) {\n        return function () {\n          return stream[method].apply(stream, arguments);\n        };\n      }(i);\n    }\n  }\n\n  // proxy certain important events.\n  var events = ['error', 'close', 'destroy', 'pause', 'resume'];\n  forEach(events, function (ev) {\n    stream.on(ev, self.emit.bind(self, ev));\n  });\n\n  // when we try to consume some more bytes, simply unpause the\n  // underlying stream.\n  self._read = function (n) {\n    debug('wrapped _read', n);\n    if (paused) {\n      paused = false;\n      stream.resume();\n    }\n  };\n\n  return self;\n};\n\n// exposed for testing purposes only.\nReadable._fromList = fromList;\n\n// Pluck off n bytes from an array of buffers.\n// Length is the combined lengths of all the buffers in the list.\n// This function is designed to be inlinable, so please take care when making\n// changes to the function body.\nfunction fromList(n, state) {\n  // nothing buffered\n  if (state.length === 0) return null;\n\n  var ret;\n  if (state.objectMode) ret = state.buffer.shift();else if (!n || n >= state.length) {\n    // read it all, truncate the list\n    if (state.decoder) ret = state.buffer.join('');else if (state.buffer.length === 1) ret = state.buffer.head.data;else ret = state.buffer.concat(state.length);\n    state.buffer.clear();\n  } else {\n    // read part of list\n    ret = fromListPartial(n, state.buffer, state.decoder);\n  }\n\n  return ret;\n}\n\n// Extracts only enough buffered data to satisfy the amount requested.\n// This function is designed to be inlinable, so please take care when making\n// changes to the function body.\nfunction fromListPartial(n, list, hasStrings) {\n  var ret;\n  if (n < list.head.data.length) {\n    // slice is the same for buffers and strings\n    ret = list.head.data.slice(0, n);\n    list.head.data = list.head.data.slice(n);\n  } else if (n === list.head.data.length) {\n    // first chunk is a perfect match\n    ret = list.shift();\n  } else {\n    // result spans more than one buffer\n    ret = hasStrings ? copyFromBufferString(n, list) : copyFromBuffer(n, list);\n  }\n  return ret;\n}\n\n// Copies a specified amount of characters from the list of buffered data\n// chunks.\n// This function is designed to be inlinable, so please take care when making\n// changes to the function body.\nfunction copyFromBufferString(n, list) {\n  var p = list.head;\n  var c = 1;\n  var ret = p.data;\n  n -= ret.length;\n  while (p = p.next) {\n    var str = p.data;\n    var nb = n > str.length ? str.length : n;\n    if (nb === str.length) ret += str;else ret += str.slice(0, n);\n    n -= nb;\n    if (n === 0) {\n      if (nb === str.length) {\n        ++c;\n        if (p.next) list.head = p.next;else list.head = list.tail = null;\n      } else {\n        list.head = p;\n        p.data = str.slice(nb);\n      }\n      break;\n    }\n    ++c;\n  }\n  list.length -= c;\n  return ret;\n}\n\n// Copies a specified amount of bytes from the list of buffered data chunks.\n// This function is designed to be inlinable, so please take care when making\n// changes to the function body.\nfunction copyFromBuffer(n, list) {\n  var ret = bufferShim.allocUnsafe(n);\n  var p = list.head;\n  var c = 1;\n  p.data.copy(ret);\n  n -= p.data.length;\n  while (p = p.next) {\n    var buf = p.data;\n    var nb = n > buf.length ? buf.length : n;\n    buf.copy(ret, ret.length - n, 0, nb);\n    n -= nb;\n    if (n === 0) {\n      if (nb === buf.length) {\n        ++c;\n        if (p.next) list.head = p.next;else list.head = list.tail = null;\n      } else {\n        list.head = p;\n        p.data = buf.slice(nb);\n      }\n      break;\n    }\n    ++c;\n  }\n  list.length -= c;\n  return ret;\n}\n\nfunction endReadable(stream) {\n  var state = stream._readableState;\n\n  // If we get here before consuming all the bytes, then that is a\n  // bug in node.  Should never happen.\n  if (state.length > 0) throw new Error('\"endReadable()\" called on non-empty stream');\n\n  if (!state.endEmitted) {\n    state.ended = true;\n    processNextTick(endReadableNT, state, stream);\n  }\n}\n\nfunction endReadableNT(state, stream) {\n  // Check that we didn't get one last unshift.\n  if (!state.endEmitted && state.length === 0) {\n    state.endEmitted = true;\n    stream.readable = false;\n    stream.emit('end');\n  }\n}\n\nfunction forEach(xs, f) {\n  for (var i = 0, l = xs.length; i < l; i++) {\n    f(xs[i], i);\n  }\n}\n\nfunction indexOf(xs, x) {\n  for (var i = 0, l = xs.length; i < l; i++) {\n    if (xs[i] === x) return i;\n  }\n  return -1;\n}\n}).call(this,require('_process'))\n},{\"./_stream_duplex\":69,\"./internal/streams/BufferList\":74,\"_process\":67,\"buffer\":44,\"buffer-shims\":43,\"core-util-is\":45,\"events\":48,\"inherits\":51,\"isarray\":53,\"process-nextick-args\":66,\"string_decoder/\":80,\"util\":40}],72:[function(require,module,exports){\n// a transform stream is a readable/writable stream where you do\n// something with the data.  Sometimes it's called a \"filter\",\n// but that's not a great name for it, since that implies a thing where\n// some bits pass through, and others are simply ignored.  (That would\n// be a valid example of a transform, of course.)\n//\n// While the output is causally related to the input, it's not a\n// necessarily symmetric or synchronous transformation.  For example,\n// a zlib stream might take multiple plain-text writes(), and then\n// emit a single compressed chunk some time in the future.\n//\n// Here's how this works:\n//\n// The Transform stream has all the aspects of the readable and writable\n// stream classes.  When you write(chunk), that calls _write(chunk,cb)\n// internally, and returns false if there's a lot of pending writes\n// buffered up.  When you call read(), that calls _read(n) until\n// there's enough pending readable data buffered up.\n//\n// In a transform stream, the written data is placed in a buffer.  When\n// _read(n) is called, it transforms the queued up data, calling the\n// buffered _write cb's as it consumes chunks.  If consuming a single\n// written chunk would result in multiple output chunks, then the first\n// outputted bit calls the readcb, and subsequent chunks just go into\n// the read buffer, and will cause it to emit 'readable' if necessary.\n//\n// This way, back-pressure is actually determined by the reading side,\n// since _read has to be called to start processing a new chunk.  However,\n// a pathological inflate type of transform can cause excessive buffering\n// here.  For example, imagine a stream where every byte of input is\n// interpreted as an integer from 0-255, and then results in that many\n// bytes of output.  Writing the 4 bytes {ff,ff,ff,ff} would result in\n// 1kb of data being output.  In this case, you could write a very small\n// amount of input, and end up with a very large amount of output.  In\n// such a pathological inflating mechanism, there'd be no way to tell\n// the system to stop doing the transform.  A single 4MB write could\n// cause the system to run out of memory.\n//\n// However, even in such a pathological case, only a single written chunk\n// would be consumed, and then the rest would wait (un-transformed) until\n// the results of the previous transformed chunk were consumed.\n\n'use strict';\n\nmodule.exports = Transform;\n\nvar Duplex = require('./_stream_duplex');\n\n/*<replacement>*/\nvar util = require('core-util-is');\nutil.inherits = require('inherits');\n/*</replacement>*/\n\nutil.inherits(Transform, Duplex);\n\nfunction TransformState(stream) {\n  this.afterTransform = function (er, data) {\n    return afterTransform(stream, er, data);\n  };\n\n  this.needTransform = false;\n  this.transforming = false;\n  this.writecb = null;\n  this.writechunk = null;\n  this.writeencoding = null;\n}\n\nfunction afterTransform(stream, er, data) {\n  var ts = stream._transformState;\n  ts.transforming = false;\n\n  var cb = ts.writecb;\n\n  if (!cb) return stream.emit('error', new Error('no writecb in Transform class'));\n\n  ts.writechunk = null;\n  ts.writecb = null;\n\n  if (data !== null && data !== undefined) stream.push(data);\n\n  cb(er);\n\n  var rs = stream._readableState;\n  rs.reading = false;\n  if (rs.needReadable || rs.length < rs.highWaterMark) {\n    stream._read(rs.highWaterMark);\n  }\n}\n\nfunction Transform(options) {\n  if (!(this instanceof Transform)) return new Transform(options);\n\n  Duplex.call(this, options);\n\n  this._transformState = new TransformState(this);\n\n  // when the writable side finishes, then flush out anything remaining.\n  var stream = this;\n\n  // start out asking for a readable event once data is transformed.\n  this._readableState.needReadable = true;\n\n  // we have implemented the _read method, and done the other things\n  // that Readable wants before the first _read call, so unset the\n  // sync guard flag.\n  this._readableState.sync = false;\n\n  if (options) {\n    if (typeof options.transform === 'function') this._transform = options.transform;\n\n    if (typeof options.flush === 'function') this._flush = options.flush;\n  }\n\n  this.once('prefinish', function () {\n    if (typeof this._flush === 'function') this._flush(function (er) {\n      done(stream, er);\n    });else done(stream);\n  });\n}\n\nTransform.prototype.push = function (chunk, encoding) {\n  this._transformState.needTransform = false;\n  return Duplex.prototype.push.call(this, chunk, encoding);\n};\n\n// This is the part where you do stuff!\n// override this function in implementation classes.\n// 'chunk' is an input chunk.\n//\n// Call `push(newChunk)` to pass along transformed output\n// to the readable side.  You may call 'push' zero or more times.\n//\n// Call `cb(err)` when you are done with this chunk.  If you pass\n// an error, then that'll put the hurt on the whole operation.  If you\n// never call cb(), then you'll never get another chunk.\nTransform.prototype._transform = function (chunk, encoding, cb) {\n  throw new Error('Not implemented');\n};\n\nTransform.prototype._write = function (chunk, encoding, cb) {\n  var ts = this._transformState;\n  ts.writecb = cb;\n  ts.writechunk = chunk;\n  ts.writeencoding = encoding;\n  if (!ts.transforming) {\n    var rs = this._readableState;\n    if (ts.needTransform || rs.needReadable || rs.length < rs.highWaterMark) this._read(rs.highWaterMark);\n  }\n};\n\n// Doesn't matter what the args are here.\n// _transform does all the work.\n// That we got here means that the readable side wants more data.\nTransform.prototype._read = function (n) {\n  var ts = this._transformState;\n\n  if (ts.writechunk !== null && ts.writecb && !ts.transforming) {\n    ts.transforming = true;\n    this._transform(ts.writechunk, ts.writeencoding, ts.afterTransform);\n  } else {\n    // mark that we need a transform, so that any data that comes in\n    // will get processed, now that we've asked for it.\n    ts.needTransform = true;\n  }\n};\n\nfunction done(stream, er) {\n  if (er) return stream.emit('error', er);\n\n  // if there's nothing in the write buffer, then that means\n  // that nothing more will ever be provided\n  var ws = stream._writableState;\n  var ts = stream._transformState;\n\n  if (ws.length) throw new Error('Calling transform done when ws.length != 0');\n\n  if (ts.transforming) throw new Error('Calling transform done when still transforming');\n\n  return stream.push(null);\n}\n},{\"./_stream_duplex\":69,\"core-util-is\":45,\"inherits\":51}],73:[function(require,module,exports){\n(function (process){\n// A bit simpler than readable streams.\n// Implement an async ._write(chunk, encoding, cb), and it'll handle all\n// the drain event emission and buffering.\n\n'use strict';\n\nmodule.exports = Writable;\n\n/*<replacement>*/\nvar processNextTick = require('process-nextick-args');\n/*</replacement>*/\n\n/*<replacement>*/\nvar asyncWrite = !process.browser && ['v0.10', 'v0.9.'].indexOf(process.version.slice(0, 5)) > -1 ? setImmediate : processNextTick;\n/*</replacement>*/\n\nWritable.WritableState = WritableState;\n\n/*<replacement>*/\nvar util = require('core-util-is');\nutil.inherits = require('inherits');\n/*</replacement>*/\n\n/*<replacement>*/\nvar internalUtil = {\n  deprecate: require('util-deprecate')\n};\n/*</replacement>*/\n\n/*<replacement>*/\nvar Stream;\n(function () {\n  try {\n    Stream = require('st' + 'ream');\n  } catch (_) {} finally {\n    if (!Stream) Stream = require('events').EventEmitter;\n  }\n})();\n/*</replacement>*/\n\nvar Buffer = require('buffer').Buffer;\n/*<replacement>*/\nvar bufferShim = require('buffer-shims');\n/*</replacement>*/\n\nutil.inherits(Writable, Stream);\n\nfunction nop() {}\n\nfunction WriteReq(chunk, encoding, cb) {\n  this.chunk = chunk;\n  this.encoding = encoding;\n  this.callback = cb;\n  this.next = null;\n}\n\nvar Duplex;\nfunction WritableState(options, stream) {\n  Duplex = Duplex || require('./_stream_duplex');\n\n  options = options || {};\n\n  // object stream flag to indicate whether or not this stream\n  // contains buffers or objects.\n  this.objectMode = !!options.objectMode;\n\n  if (stream instanceof Duplex) this.objectMode = this.objectMode || !!options.writableObjectMode;\n\n  // the point at which write() starts returning false\n  // Note: 0 is a valid value, means that we always return false if\n  // the entire buffer is not flushed immediately on write()\n  var hwm = options.highWaterMark;\n  var defaultHwm = this.objectMode ? 16 : 16 * 1024;\n  this.highWaterMark = hwm || hwm === 0 ? hwm : defaultHwm;\n\n  // cast to ints.\n  this.highWaterMark = ~ ~this.highWaterMark;\n\n  this.needDrain = false;\n  // at the start of calling end()\n  this.ending = false;\n  // when end() has been called, and returned\n  this.ended = false;\n  // when 'finish' is emitted\n  this.finished = false;\n\n  // should we decode strings into buffers before passing to _write?\n  // this is here so that some node-core streams can optimize string\n  // handling at a lower level.\n  var noDecode = options.decodeStrings === false;\n  this.decodeStrings = !noDecode;\n\n  // Crypto is kind of old and crusty.  Historically, its default string\n  // encoding is 'binary' so we have to make this configurable.\n  // Everything else in the universe uses 'utf8', though.\n  this.defaultEncoding = options.defaultEncoding || 'utf8';\n\n  // not an actual buffer we keep track of, but a measurement\n  // of how much we're waiting to get pushed to some underlying\n  // socket or file.\n  this.length = 0;\n\n  // a flag to see when we're in the middle of a write.\n  this.writing = false;\n\n  // when true all writes will be buffered until .uncork() call\n  this.corked = 0;\n\n  // a flag to be able to tell if the onwrite cb is called immediately,\n  // or on a later tick.  We set this to true at first, because any\n  // actions that shouldn't happen until \"later\" should generally also\n  // not happen before the first write call.\n  this.sync = true;\n\n  // a flag to know if we're processing previously buffered items, which\n  // may call the _write() callback in the same tick, so that we don't\n  // end up in an overlapped onwrite situation.\n  this.bufferProcessing = false;\n\n  // the callback that's passed to _write(chunk,cb)\n  this.onwrite = function (er) {\n    onwrite(stream, er);\n  };\n\n  // the callback that the user supplies to write(chunk,encoding,cb)\n  this.writecb = null;\n\n  // the amount that is being written when _write is called.\n  this.writelen = 0;\n\n  this.bufferedRequest = null;\n  this.lastBufferedRequest = null;\n\n  // number of pending user-supplied write callbacks\n  // this must be 0 before 'finish' can be emitted\n  this.pendingcb = 0;\n\n  // emit prefinish if the only thing we're waiting for is _write cbs\n  // This is relevant for synchronous Transform streams\n  this.prefinished = false;\n\n  // True if the error was already emitted and should not be thrown again\n  this.errorEmitted = false;\n\n  // count buffered requests\n  this.bufferedRequestCount = 0;\n\n  // allocate the first CorkedRequest, there is always\n  // one allocated and free to use, and we maintain at most two\n  this.corkedRequestsFree = new CorkedRequest(this);\n}\n\nWritableState.prototype.getBuffer = function writableStateGetBuffer() {\n  var current = this.bufferedRequest;\n  var out = [];\n  while (current) {\n    out.push(current);\n    current = current.next;\n  }\n  return out;\n};\n\n(function () {\n  try {\n    Object.defineProperty(WritableState.prototype, 'buffer', {\n      get: internalUtil.deprecate(function () {\n        return this.getBuffer();\n      }, '_writableState.buffer is deprecated. Use _writableState.getBuffer ' + 'instead.')\n    });\n  } catch (_) {}\n})();\n\nvar Duplex;\nfunction Writable(options) {\n  Duplex = Duplex || require('./_stream_duplex');\n\n  // Writable ctor is applied to Duplexes, though they're not\n  // instanceof Writable, they're instanceof Readable.\n  if (!(this instanceof Writable) && !(this instanceof Duplex)) return new Writable(options);\n\n  this._writableState = new WritableState(options, this);\n\n  // legacy.\n  this.writable = true;\n\n  if (options) {\n    if (typeof options.write === 'function') this._write = options.write;\n\n    if (typeof options.writev === 'function') this._writev = options.writev;\n  }\n\n  Stream.call(this);\n}\n\n// Otherwise people can pipe Writable streams, which is just wrong.\nWritable.prototype.pipe = function () {\n  this.emit('error', new Error('Cannot pipe, not readable'));\n};\n\nfunction writeAfterEnd(stream, cb) {\n  var er = new Error('write after end');\n  // TODO: defer error events consistently everywhere, not just the cb\n  stream.emit('error', er);\n  processNextTick(cb, er);\n}\n\n// If we get something that is not a buffer, string, null, or undefined,\n// and we're not in objectMode, then that's an error.\n// Otherwise stream chunks are all considered to be of length=1, and the\n// watermarks determine how many objects to keep in the buffer, rather than\n// how many bytes or characters.\nfunction validChunk(stream, state, chunk, cb) {\n  var valid = true;\n  var er = false;\n  // Always throw error if a null is written\n  // if we are not in object mode then throw\n  // if it is not a buffer, string, or undefined.\n  if (chunk === null) {\n    er = new TypeError('May not write null values to stream');\n  } else if (!Buffer.isBuffer(chunk) && typeof chunk !== 'string' && chunk !== undefined && !state.objectMode) {\n    er = new TypeError('Invalid non-string/buffer chunk');\n  }\n  if (er) {\n    stream.emit('error', er);\n    processNextTick(cb, er);\n    valid = false;\n  }\n  return valid;\n}\n\nWritable.prototype.write = function (chunk, encoding, cb) {\n  var state = this._writableState;\n  var ret = false;\n\n  if (typeof encoding === 'function') {\n    cb = encoding;\n    encoding = null;\n  }\n\n  if (Buffer.isBuffer(chunk)) encoding = 'buffer';else if (!encoding) encoding = state.defaultEncoding;\n\n  if (typeof cb !== 'function') cb = nop;\n\n  if (state.ended) writeAfterEnd(this, cb);else if (validChunk(this, state, chunk, cb)) {\n    state.pendingcb++;\n    ret = writeOrBuffer(this, state, chunk, encoding, cb);\n  }\n\n  return ret;\n};\n\nWritable.prototype.cork = function () {\n  var state = this._writableState;\n\n  state.corked++;\n};\n\nWritable.prototype.uncork = function () {\n  var state = this._writableState;\n\n  if (state.corked) {\n    state.corked--;\n\n    if (!state.writing && !state.corked && !state.finished && !state.bufferProcessing && state.bufferedRequest) clearBuffer(this, state);\n  }\n};\n\nWritable.prototype.setDefaultEncoding = function setDefaultEncoding(encoding) {\n  // node::ParseEncoding() requires lower case.\n  if (typeof encoding === 'string') encoding = encoding.toLowerCase();\n  if (!(['hex', 'utf8', 'utf-8', 'ascii', 'binary', 'base64', 'ucs2', 'ucs-2', 'utf16le', 'utf-16le', 'raw'].indexOf((encoding + '').toLowerCase()) > -1)) throw new TypeError('Unknown encoding: ' + encoding);\n  this._writableState.defaultEncoding = encoding;\n  return this;\n};\n\nfunction decodeChunk(state, chunk, encoding) {\n  if (!state.objectMode && state.decodeStrings !== false && typeof chunk === 'string') {\n    chunk = bufferShim.from(chunk, encoding);\n  }\n  return chunk;\n}\n\n// if we're already writing something, then just put this\n// in the queue, and wait our turn.  Otherwise, call _write\n// If we return false, then we need a drain event, so set that flag.\nfunction writeOrBuffer(stream, state, chunk, encoding, cb) {\n  chunk = decodeChunk(state, chunk, encoding);\n\n  if (Buffer.isBuffer(chunk)) encoding = 'buffer';\n  var len = state.objectMode ? 1 : chunk.length;\n\n  state.length += len;\n\n  var ret = state.length < state.highWaterMark;\n  // we must ensure that previous needDrain will not be reset to false.\n  if (!ret) state.needDrain = true;\n\n  if (state.writing || state.corked) {\n    var last = state.lastBufferedRequest;\n    state.lastBufferedRequest = new WriteReq(chunk, encoding, cb);\n    if (last) {\n      last.next = state.lastBufferedRequest;\n    } else {\n      state.bufferedRequest = state.lastBufferedRequest;\n    }\n    state.bufferedRequestCount += 1;\n  } else {\n    doWrite(stream, state, false, len, chunk, encoding, cb);\n  }\n\n  return ret;\n}\n\nfunction doWrite(stream, state, writev, len, chunk, encoding, cb) {\n  state.writelen = len;\n  state.writecb = cb;\n  state.writing = true;\n  state.sync = true;\n  if (writev) stream._writev(chunk, state.onwrite);else stream._write(chunk, encoding, state.onwrite);\n  state.sync = false;\n}\n\nfunction onwriteError(stream, state, sync, er, cb) {\n  --state.pendingcb;\n  if (sync) processNextTick(cb, er);else cb(er);\n\n  stream._writableState.errorEmitted = true;\n  stream.emit('error', er);\n}\n\nfunction onwriteStateUpdate(state) {\n  state.writing = false;\n  state.writecb = null;\n  state.length -= state.writelen;\n  state.writelen = 0;\n}\n\nfunction onwrite(stream, er) {\n  var state = stream._writableState;\n  var sync = state.sync;\n  var cb = state.writecb;\n\n  onwriteStateUpdate(state);\n\n  if (er) onwriteError(stream, state, sync, er, cb);else {\n    // Check if we're actually ready to finish, but don't emit yet\n    var finished = needFinish(state);\n\n    if (!finished && !state.corked && !state.bufferProcessing && state.bufferedRequest) {\n      clearBuffer(stream, state);\n    }\n\n    if (sync) {\n      /*<replacement>*/\n      asyncWrite(afterWrite, stream, state, finished, cb);\n      /*</replacement>*/\n    } else {\n        afterWrite(stream, state, finished, cb);\n      }\n  }\n}\n\nfunction afterWrite(stream, state, finished, cb) {\n  if (!finished) onwriteDrain(stream, state);\n  state.pendingcb--;\n  cb();\n  finishMaybe(stream, state);\n}\n\n// Must force callback to be called on nextTick, so that we don't\n// emit 'drain' before the write() consumer gets the 'false' return\n// value, and has a chance to attach a 'drain' listener.\nfunction onwriteDrain(stream, state) {\n  if (state.length === 0 && state.needDrain) {\n    state.needDrain = false;\n    stream.emit('drain');\n  }\n}\n\n// if there's something in the buffer waiting, then process it\nfunction clearBuffer(stream, state) {\n  state.bufferProcessing = true;\n  var entry = state.bufferedRequest;\n\n  if (stream._writev && entry && entry.next) {\n    // Fast case, write everything using _writev()\n    var l = state.bufferedRequestCount;\n    var buffer = new Array(l);\n    var holder = state.corkedRequestsFree;\n    holder.entry = entry;\n\n    var count = 0;\n    while (entry) {\n      buffer[count] = entry;\n      entry = entry.next;\n      count += 1;\n    }\n\n    doWrite(stream, state, true, state.length, buffer, '', holder.finish);\n\n    // doWrite is almost always async, defer these to save a bit of time\n    // as the hot path ends with doWrite\n    state.pendingcb++;\n    state.lastBufferedRequest = null;\n    if (holder.next) {\n      state.corkedRequestsFree = holder.next;\n      holder.next = null;\n    } else {\n      state.corkedRequestsFree = new CorkedRequest(state);\n    }\n  } else {\n    // Slow case, write chunks one-by-one\n    while (entry) {\n      var chunk = entry.chunk;\n      var encoding = entry.encoding;\n      var cb = entry.callback;\n      var len = state.objectMode ? 1 : chunk.length;\n\n      doWrite(stream, state, false, len, chunk, encoding, cb);\n      entry = entry.next;\n      // if we didn't call the onwrite immediately, then\n      // it means that we need to wait until it does.\n      // also, that means that the chunk and cb are currently\n      // being processed, so move the buffer counter past them.\n      if (state.writing) {\n        break;\n      }\n    }\n\n    if (entry === null) state.lastBufferedRequest = null;\n  }\n\n  state.bufferedRequestCount = 0;\n  state.bufferedRequest = entry;\n  state.bufferProcessing = false;\n}\n\nWritable.prototype._write = function (chunk, encoding, cb) {\n  cb(new Error('not implemented'));\n};\n\nWritable.prototype._writev = null;\n\nWritable.prototype.end = function (chunk, encoding, cb) {\n  var state = this._writableState;\n\n  if (typeof chunk === 'function') {\n    cb = chunk;\n    chunk = null;\n    encoding = null;\n  } else if (typeof encoding === 'function') {\n    cb = encoding;\n    encoding = null;\n  }\n\n  if (chunk !== null && chunk !== undefined) this.write(chunk, encoding);\n\n  // .end() fully uncorks\n  if (state.corked) {\n    state.corked = 1;\n    this.uncork();\n  }\n\n  // ignore unnecessary end() calls.\n  if (!state.ending && !state.finished) endWritable(this, state, cb);\n};\n\nfunction needFinish(state) {\n  return state.ending && state.length === 0 && state.bufferedRequest === null && !state.finished && !state.writing;\n}\n\nfunction prefinish(stream, state) {\n  if (!state.prefinished) {\n    state.prefinished = true;\n    stream.emit('prefinish');\n  }\n}\n\nfunction finishMaybe(stream, state) {\n  var need = needFinish(state);\n  if (need) {\n    if (state.pendingcb === 0) {\n      prefinish(stream, state);\n      state.finished = true;\n      stream.emit('finish');\n    } else {\n      prefinish(stream, state);\n    }\n  }\n  return need;\n}\n\nfunction endWritable(stream, state, cb) {\n  state.ending = true;\n  finishMaybe(stream, state);\n  if (cb) {\n    if (state.finished) processNextTick(cb);else stream.once('finish', cb);\n  }\n  state.ended = true;\n  stream.writable = false;\n}\n\n// It seems a linked list but it is not\n// there will be only 2 of these for each stream\nfunction CorkedRequest(state) {\n  var _this = this;\n\n  this.next = null;\n  this.entry = null;\n\n  this.finish = function (err) {\n    var entry = _this.entry;\n    _this.entry = null;\n    while (entry) {\n      var cb = entry.callback;\n      state.pendingcb--;\n      cb(err);\n      entry = entry.next;\n    }\n    if (state.corkedRequestsFree) {\n      state.corkedRequestsFree.next = _this;\n    } else {\n      state.corkedRequestsFree = _this;\n    }\n  };\n}\n}).call(this,require('_process'))\n},{\"./_stream_duplex\":69,\"_process\":67,\"buffer\":44,\"buffer-shims\":43,\"core-util-is\":45,\"events\":48,\"inherits\":51,\"process-nextick-args\":66,\"util-deprecate\":81}],74:[function(require,module,exports){\n'use strict';\n\nvar Buffer = require('buffer').Buffer;\n/*<replacement>*/\nvar bufferShim = require('buffer-shims');\n/*</replacement>*/\n\nmodule.exports = BufferList;\n\nfunction BufferList() {\n  this.head = null;\n  this.tail = null;\n  this.length = 0;\n}\n\nBufferList.prototype.push = function (v) {\n  var entry = { data: v, next: null };\n  if (this.length > 0) this.tail.next = entry;else this.head = entry;\n  this.tail = entry;\n  ++this.length;\n};\n\nBufferList.prototype.unshift = function (v) {\n  var entry = { data: v, next: this.head };\n  if (this.length === 0) this.tail = entry;\n  this.head = entry;\n  ++this.length;\n};\n\nBufferList.prototype.shift = function () {\n  if (this.length === 0) return;\n  var ret = this.head.data;\n  if (this.length === 1) this.head = this.tail = null;else this.head = this.head.next;\n  --this.length;\n  return ret;\n};\n\nBufferList.prototype.clear = function () {\n  this.head = this.tail = null;\n  this.length = 0;\n};\n\nBufferList.prototype.join = function (s) {\n  if (this.length === 0) return '';\n  var p = this.head;\n  var ret = '' + p.data;\n  while (p = p.next) {\n    ret += s + p.data;\n  }return ret;\n};\n\nBufferList.prototype.concat = function (n) {\n  if (this.length === 0) return bufferShim.alloc(0);\n  if (this.length === 1) return this.head.data;\n  var ret = bufferShim.allocUnsafe(n >>> 0);\n  var p = this.head;\n  var i = 0;\n  while (p) {\n    p.data.copy(ret, i);\n    i += p.data.length;\n    p = p.next;\n  }\n  return ret;\n};\n},{\"buffer\":44,\"buffer-shims\":43}],75:[function(require,module,exports){\nmodule.exports = require(\"./lib/_stream_passthrough.js\")\n\n},{\"./lib/_stream_passthrough.js\":70}],76:[function(require,module,exports){\n(function (process){\nvar Stream = (function (){\n  try {\n    return require('st' + 'ream'); // hack to fix a circular dependency issue when used with browserify\n  } catch(_){}\n}());\nexports = module.exports = require('./lib/_stream_readable.js');\nexports.Stream = Stream || exports;\nexports.Readable = exports;\nexports.Writable = require('./lib/_stream_writable.js');\nexports.Duplex = require('./lib/_stream_duplex.js');\nexports.Transform = require('./lib/_stream_transform.js');\nexports.PassThrough = require('./lib/_stream_passthrough.js');\n\nif (!process.browser && process.env.READABLE_STREAM === 'disable' && Stream) {\n  module.exports = Stream;\n}\n\n}).call(this,require('_process'))\n},{\"./lib/_stream_duplex.js\":69,\"./lib/_stream_passthrough.js\":70,\"./lib/_stream_readable.js\":71,\"./lib/_stream_transform.js\":72,\"./lib/_stream_writable.js\":73,\"_process\":67}],77:[function(require,module,exports){\nmodule.exports = require(\"./lib/_stream_transform.js\")\n\n},{\"./lib/_stream_transform.js\":72}],78:[function(require,module,exports){\nmodule.exports = require(\"./lib/_stream_writable.js\")\n\n},{\"./lib/_stream_writable.js\":73}],79:[function(require,module,exports){\n// Copyright Joyent, Inc. and other Node contributors.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a\n// copy of this software and associated documentation files (the\n// \"Software\"), to deal in the Software without restriction, including\n// without limitation the rights to use, copy, modify, merge, publish,\n// distribute, sublicense, and/or sell copies of the Software, and to permit\n// persons to whom the Software is furnished to do so, subject to the\n// following conditions:\n//\n// The above copyright notice and this permission notice shall be included\n// in all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS\n// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN\n// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,\n// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE\n// USE OR OTHER DEALINGS IN THE SOFTWARE.\n\nmodule.exports = Stream;\n\nvar EE = require('events').EventEmitter;\nvar inherits = require('inherits');\n\ninherits(Stream, EE);\nStream.Readable = require('readable-stream/readable.js');\nStream.Writable = require('readable-stream/writable.js');\nStream.Duplex = require('readable-stream/duplex.js');\nStream.Transform = require('readable-stream/transform.js');\nStream.PassThrough = require('readable-stream/passthrough.js');\n\n// Backwards-compat with node 0.4.x\nStream.Stream = Stream;\n\n\n\n// old-style streams.  Note that the pipe method (the only relevant\n// part of this class) is overridden in the Readable class.\n\nfunction Stream() {\n  EE.call(this);\n}\n\nStream.prototype.pipe = function(dest, options) {\n  var source = this;\n\n  function ondata(chunk) {\n    if (dest.writable) {\n      if (false === dest.write(chunk) && source.pause) {\n        source.pause();\n      }\n    }\n  }\n\n  source.on('data', ondata);\n\n  function ondrain() {\n    if (source.readable && source.resume) {\n      source.resume();\n    }\n  }\n\n  dest.on('drain', ondrain);\n\n  // If the 'end' option is not supplied, dest.end() will be called when\n  // source gets the 'end' or 'close' events.  Only dest.end() once.\n  if (!dest._isStdio && (!options || options.end !== false)) {\n    source.on('end', onend);\n    source.on('close', onclose);\n  }\n\n  var didOnEnd = false;\n  function onend() {\n    if (didOnEnd) return;\n    didOnEnd = true;\n\n    dest.end();\n  }\n\n\n  function onclose() {\n    if (didOnEnd) return;\n    didOnEnd = true;\n\n    if (typeof dest.destroy === 'function') dest.destroy();\n  }\n\n  // don't leave dangling pipes when there are errors.\n  function onerror(er) {\n    cleanup();\n    if (EE.listenerCount(this, 'error') === 0) {\n      throw er; // Unhandled stream error in pipe.\n    }\n  }\n\n  source.on('error', onerror);\n  dest.on('error', onerror);\n\n  // remove all the event listeners that were added.\n  function cleanup() {\n    source.removeListener('data', ondata);\n    dest.removeListener('drain', ondrain);\n\n    source.removeListener('end', onend);\n    source.removeListener('close', onclose);\n\n    source.removeListener('error', onerror);\n    dest.removeListener('error', onerror);\n\n    source.removeListener('end', cleanup);\n    source.removeListener('close', cleanup);\n\n    dest.removeListener('close', cleanup);\n  }\n\n  source.on('end', cleanup);\n  source.on('close', cleanup);\n\n  dest.on('close', cleanup);\n\n  dest.emit('pipe', source);\n\n  // Allow for unix-like usage: A.pipe(B).pipe(C)\n  return dest;\n};\n\n},{\"events\":48,\"inherits\":51,\"readable-stream/duplex.js\":68,\"readable-stream/passthrough.js\":75,\"readable-stream/readable.js\":76,\"readable-stream/transform.js\":77,\"readable-stream/writable.js\":78}],80:[function(require,module,exports){\n// Copyright Joyent, Inc. and other Node contributors.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a\n// copy of this software and associated documentation files (the\n// \"Software\"), to deal in the Software without restriction, including\n// without limitation the rights to use, copy, modify, merge, publish,\n// distribute, sublicense, and/or sell copies of the Software, and to permit\n// persons to whom the Software is furnished to do so, subject to the\n// following conditions:\n//\n// The above copyright notice and this permission notice shall be included\n// in all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS\n// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN\n// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,\n// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE\n// USE OR OTHER DEALINGS IN THE SOFTWARE.\n\nvar Buffer = require('buffer').Buffer;\n\nvar isBufferEncoding = Buffer.isEncoding\n  || function(encoding) {\n       switch (encoding && encoding.toLowerCase()) {\n         case 'hex': case 'utf8': case 'utf-8': case 'ascii': case 'binary': case 'base64': case 'ucs2': case 'ucs-2': case 'utf16le': case 'utf-16le': case 'raw': return true;\n         default: return false;\n       }\n     }\n\n\nfunction assertEncoding(encoding) {\n  if (encoding && !isBufferEncoding(encoding)) {\n    throw new Error('Unknown encoding: ' + encoding);\n  }\n}\n\n// StringDecoder provides an interface for efficiently splitting a series of\n// buffers into a series of JS strings without breaking apart multi-byte\n// characters. CESU-8 is handled as part of the UTF-8 encoding.\n//\n// @TODO Handling all encodings inside a single object makes it very difficult\n// to reason about this code, so it should be split up in the future.\n// @TODO There should be a utf8-strict encoding that rejects invalid UTF-8 code\n// points as used by CESU-8.\nvar StringDecoder = exports.StringDecoder = function(encoding) {\n  this.encoding = (encoding || 'utf8').toLowerCase().replace(/[-_]/, '');\n  assertEncoding(encoding);\n  switch (this.encoding) {\n    case 'utf8':\n      // CESU-8 represents each of Surrogate Pair by 3-bytes\n      this.surrogateSize = 3;\n      break;\n    case 'ucs2':\n    case 'utf16le':\n      // UTF-16 represents each of Surrogate Pair by 2-bytes\n      this.surrogateSize = 2;\n      this.detectIncompleteChar = utf16DetectIncompleteChar;\n      break;\n    case 'base64':\n      // Base-64 stores 3 bytes in 4 chars, and pads the remainder.\n      this.surrogateSize = 3;\n      this.detectIncompleteChar = base64DetectIncompleteChar;\n      break;\n    default:\n      this.write = passThroughWrite;\n      return;\n  }\n\n  // Enough space to store all bytes of a single character. UTF-8 needs 4\n  // bytes, but CESU-8 may require up to 6 (3 bytes per surrogate).\n  this.charBuffer = new Buffer(6);\n  // Number of bytes received for the current incomplete multi-byte character.\n  this.charReceived = 0;\n  // Number of bytes expected for the current incomplete multi-byte character.\n  this.charLength = 0;\n};\n\n\n// write decodes the given buffer and returns it as JS string that is\n// guaranteed to not contain any partial multi-byte characters. Any partial\n// character found at the end of the buffer is buffered up, and will be\n// returned when calling write again with the remaining bytes.\n//\n// Note: Converting a Buffer containing an orphan surrogate to a String\n// currently works, but converting a String to a Buffer (via `new Buffer`, or\n// Buffer#write) will replace incomplete surrogates with the unicode\n// replacement character. See https://codereview.chromium.org/121173009/ .\nStringDecoder.prototype.write = function(buffer) {\n  var charStr = '';\n  // if our last write ended with an incomplete multibyte character\n  while (this.charLength) {\n    // determine how many remaining bytes this buffer has to offer for this char\n    var available = (buffer.length >= this.charLength - this.charReceived) ?\n        this.charLength - this.charReceived :\n        buffer.length;\n\n    // add the new bytes to the char buffer\n    buffer.copy(this.charBuffer, this.charReceived, 0, available);\n    this.charReceived += available;\n\n    if (this.charReceived < this.charLength) {\n      // still not enough chars in this buffer? wait for more ...\n      return '';\n    }\n\n    // remove bytes belonging to the current character from the buffer\n    buffer = buffer.slice(available, buffer.length);\n\n    // get the character that was split\n    charStr = this.charBuffer.slice(0, this.charLength).toString(this.encoding);\n\n    // CESU-8: lead surrogate (D800-DBFF) is also the incomplete character\n    var charCode = charStr.charCodeAt(charStr.length - 1);\n    if (charCode >= 0xD800 && charCode <= 0xDBFF) {\n      this.charLength += this.surrogateSize;\n      charStr = '';\n      continue;\n    }\n    this.charReceived = this.charLength = 0;\n\n    // if there are no more bytes in this buffer, just emit our char\n    if (buffer.length === 0) {\n      return charStr;\n    }\n    break;\n  }\n\n  // determine and set charLength / charReceived\n  this.detectIncompleteChar(buffer);\n\n  var end = buffer.length;\n  if (this.charLength) {\n    // buffer the incomplete character bytes we got\n    buffer.copy(this.charBuffer, 0, buffer.length - this.charReceived, end);\n    end -= this.charReceived;\n  }\n\n  charStr += buffer.toString(this.encoding, 0, end);\n\n  var end = charStr.length - 1;\n  var charCode = charStr.charCodeAt(end);\n  // CESU-8: lead surrogate (D800-DBFF) is also the incomplete character\n  if (charCode >= 0xD800 && charCode <= 0xDBFF) {\n    var size = this.surrogateSize;\n    this.charLength += size;\n    this.charReceived += size;\n    this.charBuffer.copy(this.charBuffer, size, 0, size);\n    buffer.copy(this.charBuffer, 0, 0, size);\n    return charStr.substring(0, end);\n  }\n\n  // or just emit the charStr\n  return charStr;\n};\n\n// detectIncompleteChar determines if there is an incomplete UTF-8 character at\n// the end of the given buffer. If so, it sets this.charLength to the byte\n// length that character, and sets this.charReceived to the number of bytes\n// that are available for this character.\nStringDecoder.prototype.detectIncompleteChar = function(buffer) {\n  // determine how many bytes we have to check at the end of this buffer\n  var i = (buffer.length >= 3) ? 3 : buffer.length;\n\n  // Figure out if one of the last i bytes of our buffer announces an\n  // incomplete char.\n  for (; i > 0; i--) {\n    var c = buffer[buffer.length - i];\n\n    // See http://en.wikipedia.org/wiki/UTF-8#Description\n\n    // 110XXXXX\n    if (i == 1 && c >> 5 == 0x06) {\n      this.charLength = 2;\n      break;\n    }\n\n    // 1110XXXX\n    if (i <= 2 && c >> 4 == 0x0E) {\n      this.charLength = 3;\n      break;\n    }\n\n    // 11110XXX\n    if (i <= 3 && c >> 3 == 0x1E) {\n      this.charLength = 4;\n      break;\n    }\n  }\n  this.charReceived = i;\n};\n\nStringDecoder.prototype.end = function(buffer) {\n  var res = '';\n  if (buffer && buffer.length)\n    res = this.write(buffer);\n\n  if (this.charReceived) {\n    var cr = this.charReceived;\n    var buf = this.charBuffer;\n    var enc = this.encoding;\n    res += buf.slice(0, cr).toString(enc);\n  }\n\n  return res;\n};\n\nfunction passThroughWrite(buffer) {\n  return buffer.toString(this.encoding);\n}\n\nfunction utf16DetectIncompleteChar(buffer) {\n  this.charReceived = buffer.length % 2;\n  this.charLength = this.charReceived ? 2 : 0;\n}\n\nfunction base64DetectIncompleteChar(buffer) {\n  this.charReceived = buffer.length % 3;\n  this.charLength = this.charReceived ? 3 : 0;\n}\n\n},{\"buffer\":44}],81:[function(require,module,exports){\n(function (global){\n\n/**\n * Module exports.\n */\n\nmodule.exports = deprecate;\n\n/**\n * Mark that a method should not be used.\n * Returns a modified function which warns once by default.\n *\n * If `localStorage.noDeprecation = true` is set, then it is a no-op.\n *\n * If `localStorage.throwDeprecation = true` is set, then deprecated functions\n * will throw an Error when invoked.\n *\n * If `localStorage.traceDeprecation = true` is set, then deprecated functions\n * will invoke `console.trace()` instead of `console.error()`.\n *\n * @param {Function} fn - the function to deprecate\n * @param {String} msg - the string to print to the console when `fn` is invoked\n * @returns {Function} a new \"deprecated\" version of `fn`\n * @api public\n */\n\nfunction deprecate (fn, msg) {\n  if (config('noDeprecation')) {\n    return fn;\n  }\n\n  var warned = false;\n  function deprecated() {\n    if (!warned) {\n      if (config('throwDeprecation')) {\n        throw new Error(msg);\n      } else if (config('traceDeprecation')) {\n        console.trace(msg);\n      } else {\n        console.warn(msg);\n      }\n      warned = true;\n    }\n    return fn.apply(this, arguments);\n  }\n\n  return deprecated;\n}\n\n/**\n * Checks `localStorage` for boolean values for the given `name`.\n *\n * @param {String} name\n * @returns {Boolean}\n * @api private\n */\n\nfunction config (name) {\n  // accessing global.localStorage can trigger a DOMException in sandboxed iframes\n  try {\n    if (!global.localStorage) return false;\n  } catch (_) {\n    return false;\n  }\n  var val = global.localStorage[name];\n  if (null == val) return false;\n  return String(val).toLowerCase() === 'true';\n}\n\n}).call(this,typeof global !== \"undefined\" ? global : typeof self !== \"undefined\" ? self : typeof window !== \"undefined\" ? window : {})\n},{}],82:[function(require,module,exports){\narguments[4][51][0].apply(exports,arguments)\n},{\"dup\":51}],83:[function(require,module,exports){\nmodule.exports = function isBuffer(arg) {\n  return arg && typeof arg === 'object'\n    && typeof arg.copy === 'function'\n    && typeof arg.fill === 'function'\n    && typeof arg.readUInt8 === 'function';\n}\n},{}],84:[function(require,module,exports){\n(function (process,global){\n// Copyright Joyent, Inc. and other Node contributors.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a\n// copy of this software and associated documentation files (the\n// \"Software\"), to deal in the Software without restriction, including\n// without limitation the rights to use, copy, modify, merge, publish,\n// distribute, sublicense, and/or sell copies of the Software, and to permit\n// persons to whom the Software is furnished to do so, subject to the\n// following conditions:\n//\n// The above copyright notice and this permission notice shall be included\n// in all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS\n// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN\n// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,\n// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE\n// USE OR OTHER DEALINGS IN THE SOFTWARE.\n\nvar formatRegExp = /%[sdj%]/g;\nexports.format = function(f) {\n  if (!isString(f)) {\n    var objects = [];\n    for (var i = 0; i < arguments.length; i++) {\n      objects.push(inspect(arguments[i]));\n    }\n    return objects.join(' ');\n  }\n\n  var i = 1;\n  var args = arguments;\n  var len = args.length;\n  var str = String(f).replace(formatRegExp, function(x) {\n    if (x === '%%') return '%';\n    if (i >= len) return x;\n    switch (x) {\n      case '%s': return String(args[i++]);\n      case '%d': return Number(args[i++]);\n      case '%j':\n        try {\n          return JSON.stringify(args[i++]);\n        } catch (_) {\n          return '[Circular]';\n        }\n      default:\n        return x;\n    }\n  });\n  for (var x = args[i]; i < len; x = args[++i]) {\n    if (isNull(x) || !isObject(x)) {\n      str += ' ' + x;\n    } else {\n      str += ' ' + inspect(x);\n    }\n  }\n  return str;\n};\n\n\n// Mark that a method should not be used.\n// Returns a modified function which warns once by default.\n// If --no-deprecation is set, then it is a no-op.\nexports.deprecate = function(fn, msg) {\n  // Allow for deprecating things in the process of starting up.\n  if (isUndefined(global.process)) {\n    return function() {\n      return exports.deprecate(fn, msg).apply(this, arguments);\n    };\n  }\n\n  if (process.noDeprecation === true) {\n    return fn;\n  }\n\n  var warned = false;\n  function deprecated() {\n    if (!warned) {\n      if (process.throwDeprecation) {\n        throw new Error(msg);\n      } else if (process.traceDeprecation) {\n        console.trace(msg);\n      } else {\n        console.error(msg);\n      }\n      warned = true;\n    }\n    return fn.apply(this, arguments);\n  }\n\n  return deprecated;\n};\n\n\nvar debugs = {};\nvar debugEnviron;\nexports.debuglog = function(set) {\n  if (isUndefined(debugEnviron))\n    debugEnviron = process.env.NODE_DEBUG || '';\n  set = set.toUpperCase();\n  if (!debugs[set]) {\n    if (new RegExp('\\\\b' + set + '\\\\b', 'i').test(debugEnviron)) {\n      var pid = process.pid;\n      debugs[set] = function() {\n        var msg = exports.format.apply(exports, arguments);\n        console.error('%s %d: %s', set, pid, msg);\n      };\n    } else {\n      debugs[set] = function() {};\n    }\n  }\n  return debugs[set];\n};\n\n\n/**\n * Echos the value of a value. Trys to print the value out\n * in the best way possible given the different types.\n *\n * @param {Object} obj The object to print out.\n * @param {Object} opts Optional options object that alters the output.\n */\n/* legacy: obj, showHidden, depth, colors*/\nfunction inspect(obj, opts) {\n  // default options\n  var ctx = {\n    seen: [],\n    stylize: stylizeNoColor\n  };\n  // legacy...\n  if (arguments.length >= 3) ctx.depth = arguments[2];\n  if (arguments.length >= 4) ctx.colors = arguments[3];\n  if (isBoolean(opts)) {\n    // legacy...\n    ctx.showHidden = opts;\n  } else if (opts) {\n    // got an \"options\" object\n    exports._extend(ctx, opts);\n  }\n  // set default options\n  if (isUndefined(ctx.showHidden)) ctx.showHidden = false;\n  if (isUndefined(ctx.depth)) ctx.depth = 2;\n  if (isUndefined(ctx.colors)) ctx.colors = false;\n  if (isUndefined(ctx.customInspect)) ctx.customInspect = true;\n  if (ctx.colors) ctx.stylize = stylizeWithColor;\n  return formatValue(ctx, obj, ctx.depth);\n}\nexports.inspect = inspect;\n\n\n// http://en.wikipedia.org/wiki/ANSI_escape_code#graphics\ninspect.colors = {\n  'bold' : [1, 22],\n  'italic' : [3, 23],\n  'underline' : [4, 24],\n  'inverse' : [7, 27],\n  'white' : [37, 39],\n  'grey' : [90, 39],\n  'black' : [30, 39],\n  'blue' : [34, 39],\n  'cyan' : [36, 39],\n  'green' : [32, 39],\n  'magenta' : [35, 39],\n  'red' : [31, 39],\n  'yellow' : [33, 39]\n};\n\n// Don't use 'blue' not visible on cmd.exe\ninspect.styles = {\n  'special': 'cyan',\n  'number': 'yellow',\n  'boolean': 'yellow',\n  'undefined': 'grey',\n  'null': 'bold',\n  'string': 'green',\n  'date': 'magenta',\n  // \"name\": intentionally not styling\n  'regexp': 'red'\n};\n\n\nfunction stylizeWithColor(str, styleType) {\n  var style = inspect.styles[styleType];\n\n  if (style) {\n    return '\\u001b[' + inspect.colors[style][0] + 'm' + str +\n           '\\u001b[' + inspect.colors[style][1] + 'm';\n  } else {\n    return str;\n  }\n}\n\n\nfunction stylizeNoColor(str, styleType) {\n  return str;\n}\n\n\nfunction arrayToHash(array) {\n  var hash = {};\n\n  array.forEach(function(val, idx) {\n    hash[val] = true;\n  });\n\n  return hash;\n}\n\n\nfunction formatValue(ctx, value, recurseTimes) {\n  // Provide a hook for user-specified inspect functions.\n  // Check that value is an object with an inspect function on it\n  if (ctx.customInspect &&\n      value &&\n      isFunction(value.inspect) &&\n      // Filter out the util module, it's inspect function is special\n      value.inspect !== exports.inspect &&\n      // Also filter out any prototype objects using the circular check.\n      !(value.constructor && value.constructor.prototype === value)) {\n    var ret = value.inspect(recurseTimes, ctx);\n    if (!isString(ret)) {\n      ret = formatValue(ctx, ret, recurseTimes);\n    }\n    return ret;\n  }\n\n  // Primitive types cannot have properties\n  var primitive = formatPrimitive(ctx, value);\n  if (primitive) {\n    return primitive;\n  }\n\n  // Look up the keys of the object.\n  var keys = Object.keys(value);\n  var visibleKeys = arrayToHash(keys);\n\n  if (ctx.showHidden) {\n    keys = Object.getOwnPropertyNames(value);\n  }\n\n  // IE doesn't make error fields non-enumerable\n  // http://msdn.microsoft.com/en-us/library/ie/dww52sbt(v=vs.94).aspx\n  if (isError(value)\n      && (keys.indexOf('message') >= 0 || keys.indexOf('description') >= 0)) {\n    return formatError(value);\n  }\n\n  // Some type of object without properties can be shortcutted.\n  if (keys.length === 0) {\n    if (isFunction(value)) {\n      var name = value.name ? ': ' + value.name : '';\n      return ctx.stylize('[Function' + name + ']', 'special');\n    }\n    if (isRegExp(value)) {\n      return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp');\n    }\n    if (isDate(value)) {\n      return ctx.stylize(Date.prototype.toString.call(value), 'date');\n    }\n    if (isError(value)) {\n      return formatError(value);\n    }\n  }\n\n  var base = '', array = false, braces = ['{', '}'];\n\n  // Make Array say that they are Array\n  if (isArray(value)) {\n    array = true;\n    braces = ['[', ']'];\n  }\n\n  // Make functions say that they are functions\n  if (isFunction(value)) {\n    var n = value.name ? ': ' + value.name : '';\n    base = ' [Function' + n + ']';\n  }\n\n  // Make RegExps say that they are RegExps\n  if (isRegExp(value)) {\n    base = ' ' + RegExp.prototype.toString.call(value);\n  }\n\n  // Make dates with properties first say the date\n  if (isDate(value)) {\n    base = ' ' + Date.prototype.toUTCString.call(value);\n  }\n\n  // Make error with message first say the error\n  if (isError(value)) {\n    base = ' ' + formatError(value);\n  }\n\n  if (keys.length === 0 && (!array || value.length == 0)) {\n    return braces[0] + base + braces[1];\n  }\n\n  if (recurseTimes < 0) {\n    if (isRegExp(value)) {\n      return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp');\n    } else {\n      return ctx.stylize('[Object]', 'special');\n    }\n  }\n\n  ctx.seen.push(value);\n\n  var output;\n  if (array) {\n    output = formatArray(ctx, value, recurseTimes, visibleKeys, keys);\n  } else {\n    output = keys.map(function(key) {\n      return formatProperty(ctx, value, recurseTimes, visibleKeys, key, array);\n    });\n  }\n\n  ctx.seen.pop();\n\n  return reduceToSingleString(output, base, braces);\n}\n\n\nfunction formatPrimitive(ctx, value) {\n  if (isUndefined(value))\n    return ctx.stylize('undefined', 'undefined');\n  if (isString(value)) {\n    var simple = '\\'' + JSON.stringify(value).replace(/^\"|\"$/g, '')\n                                             .replace(/'/g, \"\\\\'\")\n                                             .replace(/\\\\\"/g, '\"') + '\\'';\n    return ctx.stylize(simple, 'string');\n  }\n  if (isNumber(value))\n    return ctx.stylize('' + value, 'number');\n  if (isBoolean(value))\n    return ctx.stylize('' + value, 'boolean');\n  // For some reason typeof null is \"object\", so special case here.\n  if (isNull(value))\n    return ctx.stylize('null', 'null');\n}\n\n\nfunction formatError(value) {\n  return '[' + Error.prototype.toString.call(value) + ']';\n}\n\n\nfunction formatArray(ctx, value, recurseTimes, visibleKeys, keys) {\n  var output = [];\n  for (var i = 0, l = value.length; i < l; ++i) {\n    if (hasOwnProperty(value, String(i))) {\n      output.push(formatProperty(ctx, value, recurseTimes, visibleKeys,\n          String(i), true));\n    } else {\n      output.push('');\n    }\n  }\n  keys.forEach(function(key) {\n    if (!key.match(/^\\d+$/)) {\n      output.push(formatProperty(ctx, value, recurseTimes, visibleKeys,\n          key, true));\n    }\n  });\n  return output;\n}\n\n\nfunction formatProperty(ctx, value, recurseTimes, visibleKeys, key, array) {\n  var name, str, desc;\n  desc = Object.getOwnPropertyDescriptor(value, key) || { value: value[key] };\n  if (desc.get) {\n    if (desc.set) {\n      str = ctx.stylize('[Getter/Setter]', 'special');\n    } else {\n      str = ctx.stylize('[Getter]', 'special');\n    }\n  } else {\n    if (desc.set) {\n      str = ctx.stylize('[Setter]', 'special');\n    }\n  }\n  if (!hasOwnProperty(visibleKeys, key)) {\n    name = '[' + key + ']';\n  }\n  if (!str) {\n    if (ctx.seen.indexOf(desc.value) < 0) {\n      if (isNull(recurseTimes)) {\n        str = formatValue(ctx, desc.value, null);\n      } else {\n        str = formatValue(ctx, desc.value, recurseTimes - 1);\n      }\n      if (str.indexOf('\\n') > -1) {\n        if (array) {\n          str = str.split('\\n').map(function(line) {\n            return '  ' + line;\n          }).join('\\n').substr(2);\n        } else {\n          str = '\\n' + str.split('\\n').map(function(line) {\n            return '   ' + line;\n          }).join('\\n');\n        }\n      }\n    } else {\n      str = ctx.stylize('[Circular]', 'special');\n    }\n  }\n  if (isUndefined(name)) {\n    if (array && key.match(/^\\d+$/)) {\n      return str;\n    }\n    name = JSON.stringify('' + key);\n    if (name.match(/^\"([a-zA-Z_][a-zA-Z_0-9]*)\"$/)) {\n      name = name.substr(1, name.length - 2);\n      name = ctx.stylize(name, 'name');\n    } else {\n      name = name.replace(/'/g, \"\\\\'\")\n                 .replace(/\\\\\"/g, '\"')\n                 .replace(/(^\"|\"$)/g, \"'\");\n      name = ctx.stylize(name, 'string');\n    }\n  }\n\n  return name + ': ' + str;\n}\n\n\nfunction reduceToSingleString(output, base, braces) {\n  var numLinesEst = 0;\n  var length = output.reduce(function(prev, cur) {\n    numLinesEst++;\n    if (cur.indexOf('\\n') >= 0) numLinesEst++;\n    return prev + cur.replace(/\\u001b\\[\\d\\d?m/g, '').length + 1;\n  }, 0);\n\n  if (length > 60) {\n    return braces[0] +\n           (base === '' ? '' : base + '\\n ') +\n           ' ' +\n           output.join(',\\n  ') +\n           ' ' +\n           braces[1];\n  }\n\n  return braces[0] + base + ' ' + output.join(', ') + ' ' + braces[1];\n}\n\n\n// NOTE: These type checking functions intentionally don't use `instanceof`\n// because it is fragile and can be easily faked with `Object.create()`.\nfunction isArray(ar) {\n  return Array.isArray(ar);\n}\nexports.isArray = isArray;\n\nfunction isBoolean(arg) {\n  return typeof arg === 'boolean';\n}\nexports.isBoolean = isBoolean;\n\nfunction isNull(arg) {\n  return arg === null;\n}\nexports.isNull = isNull;\n\nfunction isNullOrUndefined(arg) {\n  return arg == null;\n}\nexports.isNullOrUndefined = isNullOrUndefined;\n\nfunction isNumber(arg) {\n  return typeof arg === 'number';\n}\nexports.isNumber = isNumber;\n\nfunction isString(arg) {\n  return typeof arg === 'string';\n}\nexports.isString = isString;\n\nfunction isSymbol(arg) {\n  return typeof arg === 'symbol';\n}\nexports.isSymbol = isSymbol;\n\nfunction isUndefined(arg) {\n  return arg === void 0;\n}\nexports.isUndefined = isUndefined;\n\nfunction isRegExp(re) {\n  return isObject(re) && objectToString(re) === '[object RegExp]';\n}\nexports.isRegExp = isRegExp;\n\nfunction isObject(arg) {\n  return typeof arg === 'object' && arg !== null;\n}\nexports.isObject = isObject;\n\nfunction isDate(d) {\n  return isObject(d) && objectToString(d) === '[object Date]';\n}\nexports.isDate = isDate;\n\nfunction isError(e) {\n  return isObject(e) &&\n      (objectToString(e) === '[object Error]' || e instanceof Error);\n}\nexports.isError = isError;\n\nfunction isFunction(arg) {\n  return typeof arg === 'function';\n}\nexports.isFunction = isFunction;\n\nfunction isPrimitive(arg) {\n  return arg === null ||\n         typeof arg === 'boolean' ||\n         typeof arg === 'number' ||\n         typeof arg === 'string' ||\n         typeof arg === 'symbol' ||  // ES6 symbol\n         typeof arg === 'undefined';\n}\nexports.isPrimitive = isPrimitive;\n\nexports.isBuffer = require('./support/isBuffer');\n\nfunction objectToString(o) {\n  return Object.prototype.toString.call(o);\n}\n\n\nfunction pad(n) {\n  return n < 10 ? '0' + n.toString(10) : n.toString(10);\n}\n\n\nvar months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep',\n              'Oct', 'Nov', 'Dec'];\n\n// 26 Feb 16:19:34\nfunction timestamp() {\n  var d = new Date();\n  var time = [pad(d.getHours()),\n              pad(d.getMinutes()),\n              pad(d.getSeconds())].join(':');\n  return [d.getDate(), months[d.getMonth()], time].join(' ');\n}\n\n\n// log is just a thin wrapper to console.log that prepends a timestamp\nexports.log = function() {\n  console.log('%s - %s', timestamp(), exports.format.apply(exports, arguments));\n};\n\n\n/**\n * Inherit the prototype methods from one constructor into another.\n *\n * The Function.prototype.inherits from lang.js rewritten as a standalone\n * function (not on Function.prototype). NOTE: If this file is to be loaded\n * during bootstrapping this function needs to be rewritten using some native\n * functions as prototype setup using normal JavaScript does not work as\n * expected during bootstrapping (see mirror.js in r114903).\n *\n * @param {function} ctor Constructor function which needs to inherit the\n *     prototype.\n * @param {function} superCtor Constructor function to inherit prototype from.\n */\nexports.inherits = require('inherits');\n\nexports._extend = function(origin, add) {\n  // Don't do anything if add isn't an object\n  if (!add || !isObject(add)) return origin;\n\n  var keys = Object.keys(add);\n  var i = keys.length;\n  while (i--) {\n    origin[keys[i]] = add[keys[i]];\n  }\n  return origin;\n};\n\nfunction hasOwnProperty(obj, prop) {\n  return Object.prototype.hasOwnProperty.call(obj, prop);\n}\n\n}).call(this,require('_process'),typeof global !== \"undefined\" ? global : typeof self !== \"undefined\" ? self : typeof window !== \"undefined\" ? window : {})\n},{\"./support/isBuffer\":83,\"_process\":67,\"inherits\":82}]},{},[1]);\n"
  },
  {
    "path": "app_frontend/static/plugin/Lightbox/lightbox.js",
    "content": "/*!\n * Lightbox v2.8.2\n * by Lokesh Dhakar\n *\n * More info:\n * http://lokeshdhakar.com/projects/lightbox2/\n *\n * Copyright 2007, 2015 Lokesh Dhakar\n * Released under the MIT license\n * https://github.com/lokesh/lightbox2/blob/master/LICENSE\n */\n\n// Uses Node, AMD or browser globals to create a module.\n(function (root, factory) {\n    if (typeof define === 'function' && define.amd) {\n        // AMD. Register as an anonymous module.\n        define(['jquery'], factory);\n    } else if (typeof exports === 'object') {\n        // Node. Does not work with strict CommonJS, but\n        // only CommonJS-like environments that support module.exports,\n        // like Node.\n        module.exports = factory(require('jquery'));\n    } else {\n        // Browser globals (root is window)\n        root.lightbox = factory(root.jQuery);\n    }\n}(this, function ($) {\n\n  function Lightbox(options) {\n    this.album = [];\n    this.currentImageIndex = void 0;\n    this.init();\n\n    // options\n    this.options = $.extend({}, this.constructor.defaults);\n    this.option(options);\n  }\n\n  // Descriptions of all options available on the demo site:\n  // http://lokeshdhakar.com/projects/lightbox2/index.html#options\n  Lightbox.defaults = {\n    albumLabel: 'Image %1 of %2',\n    alwaysShowNavOnTouchDevices: false,\n    fadeDuration: 500,\n    fitImagesInViewport: true,\n    // maxWidth: 800,\n    // maxHeight: 600,\n    positionFromTop: 50,\n    resizeDuration: 700,\n    showImageNumberLabel: true,\n    wrapAround: false,\n    disableScrolling: false\n  };\n\n  Lightbox.prototype.option = function(options) {\n    $.extend(this.options, options);\n  };\n\n  Lightbox.prototype.imageCountLabel = function(currentImageNum, totalImages) {\n    return this.options.albumLabel.replace(/%1/g, currentImageNum).replace(/%2/g, totalImages);\n  };\n\n  Lightbox.prototype.init = function() {\n    this.enable();\n    this.build();\n  };\n\n  // Loop through anchors and areamaps looking for either data-lightbox attributes or rel attributes\n  // that contain 'lightbox'. When these are clicked, start lightbox.\n  Lightbox.prototype.enable = function() {\n    var self = this;\n    $('body').on('click', 'a[rel^=lightbox], area[rel^=lightbox], a[data-lightbox], area[data-lightbox]', function(event) {\n      self.start($(event.currentTarget));\n      return false;\n    });\n  };\n\n  // Build html for the lightbox and the overlay.\n  // Attach event handlers to the new DOM elements. click click click\n  Lightbox.prototype.build = function() {\n    var self = this;\n    $('<div id=\"lightboxOverlay\" class=\"lightboxOverlay\"></div><div id=\"lightbox\" class=\"lightbox\"><div class=\"lb-outerContainer\"><div class=\"lb-container\"><img class=\"lb-image\" src=\"data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw==\" /><div class=\"lb-nav\"><a class=\"lb-prev\" href=\"\" ></a><a class=\"lb-next\" href=\"\" ></a></div><div class=\"lb-loader\"><a class=\"lb-cancel\"></a></div></div></div><div class=\"lb-dataContainer\"><div class=\"lb-data\"><div class=\"lb-details\"><span class=\"lb-caption\"></span><span class=\"lb-number\"></span></div><div class=\"lb-closeContainer\"><a class=\"lb-close\"></a></div></div></div></div>').appendTo($('body'));\n\n    // Cache jQuery objects\n    this.$lightbox       = $('#lightbox');\n    this.$overlay        = $('#lightboxOverlay');\n    this.$outerContainer = this.$lightbox.find('.lb-outerContainer');\n    this.$container      = this.$lightbox.find('.lb-container');\n\n    // Store css values for future lookup\n    this.containerTopPadding = parseInt(this.$container.css('padding-top'), 10);\n    this.containerRightPadding = parseInt(this.$container.css('padding-right'), 10);\n    this.containerBottomPadding = parseInt(this.$container.css('padding-bottom'), 10);\n    this.containerLeftPadding = parseInt(this.$container.css('padding-left'), 10);\n\n    // Attach event handlers to the newly minted DOM elements\n    this.$overlay.hide().on('click', function() {\n      self.end();\n      return false;\n    });\n\n    this.$lightbox.hide().on('click', function(event) {\n      if ($(event.target).attr('id') === 'lightbox') {\n        self.end();\n      }\n      return false;\n    });\n\n    this.$outerContainer.on('click', function(event) {\n      if ($(event.target).attr('id') === 'lightbox') {\n        self.end();\n      }\n      return false;\n    });\n\n    this.$lightbox.find('.lb-prev').on('click', function() {\n      if (self.currentImageIndex === 0) {\n        self.changeImage(self.album.length - 1);\n      } else {\n        self.changeImage(self.currentImageIndex - 1);\n      }\n      return false;\n    });\n\n    this.$lightbox.find('.lb-next').on('click', function() {\n      if (self.currentImageIndex === self.album.length - 1) {\n        self.changeImage(0);\n      } else {\n        self.changeImage(self.currentImageIndex + 1);\n      }\n      return false;\n    });\n\n    this.$lightbox.find('.lb-loader, .lb-close').on('click', function() {\n      self.end();\n      return false;\n    });\n  };\n\n  // Show overlay and lightbox. If the image is part of a set, add siblings to album array.\n  Lightbox.prototype.start = function($link) {\n    var self    = this;\n    var $window = $(window);\n\n    $window.on('resize', $.proxy(this.sizeOverlay, this));\n\n    $('select, object, embed').css({\n      visibility: 'hidden'\n    });\n\n    this.sizeOverlay();\n\n    this.album = [];\n    var imageNumber = 0;\n\n    function addToAlbum($link) {\n      self.album.push({\n        link: $link.attr('href'),\n        title: $link.attr('data-title') || $link.attr('title')\n      });\n    }\n\n    // Support both data-lightbox attribute and rel attribute implementations\n    var dataLightboxValue = $link.attr('data-lightbox');\n    var $links;\n\n    if (dataLightboxValue) {\n      $links = $($link.prop('tagName') + '[data-lightbox=\"' + dataLightboxValue + '\"]');\n      for (var i = 0; i < $links.length; i = ++i) {\n        addToAlbum($($links[i]));\n        if ($links[i] === $link[0]) {\n          imageNumber = i;\n        }\n      }\n    } else {\n      if ($link.attr('rel') === 'lightbox') {\n        // If image is not part of a set\n        addToAlbum($link);\n      } else {\n        // If image is part of a set\n        $links = $($link.prop('tagName') + '[rel=\"' + $link.attr('rel') + '\"]');\n        for (var j = 0; j < $links.length; j = ++j) {\n          addToAlbum($($links[j]));\n          if ($links[j] === $link[0]) {\n            imageNumber = j;\n          }\n        }\n      }\n    }\n\n    // Position Lightbox\n    var top  = $window.scrollTop() + this.options.positionFromTop;\n    var left = $window.scrollLeft();\n    this.$lightbox.css({\n      top: top + 'px',\n      left: left + 'px'\n    }).fadeIn(this.options.fadeDuration);\n\n    // Disable scrolling of the page while open\n    if (this.options.disableScrolling) {\n      $('body').addClass('lb-disable-scrolling');\n    }\n\n    this.changeImage(imageNumber);\n  };\n\n  // Hide most UI elements in preparation for the animated resizing of the lightbox.\n  Lightbox.prototype.changeImage = function(imageNumber) {\n    var self = this;\n\n    this.disableKeyboardNav();\n    var $image = this.$lightbox.find('.lb-image');\n\n    this.$overlay.fadeIn(this.options.fadeDuration);\n\n    $('.lb-loader').fadeIn('slow');\n    this.$lightbox.find('.lb-image, .lb-nav, .lb-prev, .lb-next, .lb-dataContainer, .lb-numbers, .lb-caption').hide();\n\n    this.$outerContainer.addClass('animating');\n\n    // When image to show is preloaded, we send the width and height to sizeContainer()\n    var preloader = new Image();\n    preloader.onload = function() {\n      var $preloader;\n      var imageHeight;\n      var imageWidth;\n      var maxImageHeight;\n      var maxImageWidth;\n      var windowHeight;\n      var windowWidth;\n\n      $image.attr('src', self.album[imageNumber].link);\n\n      $preloader = $(preloader);\n\n      $image.width(preloader.width);\n      $image.height(preloader.height);\n\n      if (self.options.fitImagesInViewport) {\n        // Fit image inside the viewport.\n        // Take into account the border around the image and an additional 10px gutter on each side.\n\n        windowWidth    = $(window).width();\n        windowHeight   = $(window).height();\n        maxImageWidth  = windowWidth - self.containerLeftPadding - self.containerRightPadding - 20;\n        maxImageHeight = windowHeight - self.containerTopPadding - self.containerBottomPadding - 120;\n\n        // Check if image size is larger then maxWidth|maxHeight in settings\n        if (self.options.maxWidth && self.options.maxWidth < maxImageWidth) {\n          maxImageWidth = self.options.maxWidth;\n        }\n        if (self.options.maxHeight && self.options.maxHeight < maxImageWidth) {\n          maxImageHeight = self.options.maxHeight;\n        }\n\n        // Is there a fitting issue?\n        if ((preloader.width > maxImageWidth) || (preloader.height > maxImageHeight)) {\n          if ((preloader.width / maxImageWidth) > (preloader.height / maxImageHeight)) {\n            imageWidth  = maxImageWidth;\n            imageHeight = parseInt(preloader.height / (preloader.width / imageWidth), 10);\n            $image.width(imageWidth);\n            $image.height(imageHeight);\n          } else {\n            imageHeight = maxImageHeight;\n            imageWidth = parseInt(preloader.width / (preloader.height / imageHeight), 10);\n            $image.width(imageWidth);\n            $image.height(imageHeight);\n          }\n        }\n      }\n      self.sizeContainer($image.width(), $image.height());\n    };\n\n    preloader.src          = this.album[imageNumber].link;\n    this.currentImageIndex = imageNumber;\n  };\n\n  // Stretch overlay to fit the viewport\n  Lightbox.prototype.sizeOverlay = function() {\n    this.$overlay\n      .width($(document).width())\n      .height($(document).height());\n  };\n\n  // Animate the size of the lightbox to fit the image we are showing\n  Lightbox.prototype.sizeContainer = function(imageWidth, imageHeight) {\n    var self = this;\n\n    var oldWidth  = this.$outerContainer.outerWidth();\n    var oldHeight = this.$outerContainer.outerHeight();\n    var newWidth  = imageWidth + this.containerLeftPadding + this.containerRightPadding;\n    var newHeight = imageHeight + this.containerTopPadding + this.containerBottomPadding;\n\n    function postResize() {\n      self.$lightbox.find('.lb-dataContainer').width(newWidth);\n      self.$lightbox.find('.lb-prevLink').height(newHeight);\n      self.$lightbox.find('.lb-nextLink').height(newHeight);\n      self.showImage();\n    }\n\n    if (oldWidth !== newWidth || oldHeight !== newHeight) {\n      this.$outerContainer.animate({\n        width: newWidth,\n        height: newHeight\n      }, this.options.resizeDuration, 'swing', function() {\n        postResize();\n      });\n    } else {\n      postResize();\n    }\n  };\n\n  // Display the image and its details and begin preload neighboring images.\n  Lightbox.prototype.showImage = function() {\n    this.$lightbox.find('.lb-loader').stop(true).hide();\n    this.$lightbox.find('.lb-image').fadeIn('slow');\n\n    this.updateNav();\n    this.updateDetails();\n    this.preloadNeighboringImages();\n    this.enableKeyboardNav();\n  };\n\n  // Display previous and next navigation if appropriate.\n  Lightbox.prototype.updateNav = function() {\n    // Check to see if the browser supports touch events. If so, we take the conservative approach\n    // and assume that mouse hover events are not supported and always show prev/next navigation\n    // arrows in image sets.\n    var alwaysShowNav = false;\n    try {\n      document.createEvent('TouchEvent');\n      alwaysShowNav = (this.options.alwaysShowNavOnTouchDevices) ? true : false;\n    } catch (e) {}\n\n    this.$lightbox.find('.lb-nav').show();\n\n    if (this.album.length > 1) {\n      if (this.options.wrapAround) {\n        if (alwaysShowNav) {\n          this.$lightbox.find('.lb-prev, .lb-next').css('opacity', '1');\n        }\n        this.$lightbox.find('.lb-prev, .lb-next').show();\n      } else {\n        if (this.currentImageIndex > 0) {\n          this.$lightbox.find('.lb-prev').show();\n          if (alwaysShowNav) {\n            this.$lightbox.find('.lb-prev').css('opacity', '1');\n          }\n        }\n        if (this.currentImageIndex < this.album.length - 1) {\n          this.$lightbox.find('.lb-next').show();\n          if (alwaysShowNav) {\n            this.$lightbox.find('.lb-next').css('opacity', '1');\n          }\n        }\n      }\n    }\n  };\n\n  // Display caption, image number, and closing button.\n  Lightbox.prototype.updateDetails = function() {\n    var self = this;\n\n    // Enable anchor clicks in the injected caption html.\n    // Thanks Nate Wright for the fix. @https://github.com/NateWr\n    if (typeof this.album[this.currentImageIndex].title !== 'undefined' &&\n      this.album[this.currentImageIndex].title !== '') {\n      this.$lightbox.find('.lb-caption')\n        .html(this.album[this.currentImageIndex].title)\n        .fadeIn('fast')\n        .find('a').on('click', function(event) {\n          if ($(this).attr('target') !== undefined) {\n            window.open($(this).attr('href'), $(this).attr('target'));\n          } else {\n            location.href = $(this).attr('href');\n          }\n        });\n    }\n\n    if (this.album.length > 1 && this.options.showImageNumberLabel) {\n      var labelText = this.imageCountLabel(this.currentImageIndex + 1, this.album.length);\n      this.$lightbox.find('.lb-number').text(labelText).fadeIn('fast');\n    } else {\n      this.$lightbox.find('.lb-number').hide();\n    }\n\n    this.$outerContainer.removeClass('animating');\n\n    this.$lightbox.find('.lb-dataContainer').fadeIn(this.options.resizeDuration, function() {\n      return self.sizeOverlay();\n    });\n  };\n\n  // Preload previous and next images in set.\n  Lightbox.prototype.preloadNeighboringImages = function() {\n    if (this.album.length > this.currentImageIndex + 1) {\n      var preloadNext = new Image();\n      preloadNext.src = this.album[this.currentImageIndex + 1].link;\n    }\n    if (this.currentImageIndex > 0) {\n      var preloadPrev = new Image();\n      preloadPrev.src = this.album[this.currentImageIndex - 1].link;\n    }\n  };\n\n  Lightbox.prototype.enableKeyboardNav = function() {\n    $(document).on('keyup.keyboard', $.proxy(this.keyboardAction, this));\n  };\n\n  Lightbox.prototype.disableKeyboardNav = function() {\n    $(document).off('.keyboard');\n  };\n\n  Lightbox.prototype.keyboardAction = function(event) {\n    var KEYCODE_ESC        = 27;\n    var KEYCODE_LEFTARROW  = 37;\n    var KEYCODE_RIGHTARROW = 39;\n\n    var keycode = event.keyCode;\n    var key     = String.fromCharCode(keycode).toLowerCase();\n    if (keycode === KEYCODE_ESC || key.match(/x|o|c/)) {\n      this.end();\n    } else if (key === 'p' || keycode === KEYCODE_LEFTARROW) {\n      if (this.currentImageIndex !== 0) {\n        this.changeImage(this.currentImageIndex - 1);\n      } else if (this.options.wrapAround && this.album.length > 1) {\n        this.changeImage(this.album.length - 1);\n      }\n    } else if (key === 'n' || keycode === KEYCODE_RIGHTARROW) {\n      if (this.currentImageIndex !== this.album.length - 1) {\n        this.changeImage(this.currentImageIndex + 1);\n      } else if (this.options.wrapAround && this.album.length > 1) {\n        this.changeImage(0);\n      }\n    }\n  };\n\n  // Closing time. :-(\n  Lightbox.prototype.end = function() {\n    this.disableKeyboardNav();\n    $(window).off('resize', this.sizeOverlay);\n    this.$lightbox.fadeOut(this.options.fadeDuration);\n    this.$overlay.fadeOut(this.options.fadeDuration);\n    $('select, object, embed').css({\n      visibility: 'visible'\n    });\n    if (this.options.disableScrolling) {\n      $('body').removeClass('lb-disable-scrolling');\n    }\n  };\n\n  return new Lightbox();\n}));\n"
  },
  {
    "path": "app_frontend/static/plugin/Slideout/slideout.js",
    "content": "!function(e){if(\"object\"==typeof exports&&\"undefined\"!=typeof module)module.exports=e();else if(\"function\"==typeof define&&define.amd)define([],e);else{var f;\"undefined\"!=typeof window?f=window:\"undefined\"!=typeof global?f=global:\"undefined\"!=typeof self&&(f=self),f.Slideout=e()}}(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require==\"function\"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error(\"Cannot find module '\"+o+\"'\");throw f.code=\"MODULE_NOT_FOUND\",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require==\"function\"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){\n'use strict';\n\n/**\n * Module dependencies\n */\nvar decouple = require('decouple');\nvar Emitter = require('emitter');\n\n/**\n * Privates\n */\nvar scrollTimeout;\nvar scrolling = false;\nvar doc = window.document;\nvar html = doc.documentElement;\nvar msPointerSupported = window.navigator.msPointerEnabled;\nvar touch = {\n  'start': msPointerSupported ? 'MSPointerDown' : 'touchstart',\n  'move': msPointerSupported ? 'MSPointerMove' : 'touchmove',\n  'end': msPointerSupported ? 'MSPointerUp' : 'touchend'\n};\nvar prefix = (function prefix() {\n  var regex = /^(Webkit|Khtml|Moz|ms|O)(?=[A-Z])/;\n  var styleDeclaration = doc.getElementsByTagName('script')[0].style;\n  for (var prop in styleDeclaration) {\n    if (regex.test(prop)) {\n      return '-' + prop.match(regex)[0].toLowerCase() + '-';\n    }\n  }\n  // Nothing found so far? Webkit does not enumerate over the CSS properties of the style object.\n  // However (prop in style) returns the correct value, so we'll have to test for\n  // the precence of a specific property\n  if ('WebkitOpacity' in styleDeclaration) { return '-webkit-'; }\n  if ('KhtmlOpacity' in styleDeclaration) { return '-khtml-'; }\n  return '';\n}());\nfunction extend(destination, from) {\n  for (var prop in from) {\n    if (from[prop]) {\n      destination[prop] = from[prop];\n    }\n  }\n  return destination;\n}\nfunction inherits(child, uber) {\n  child.prototype = extend(child.prototype || {}, uber.prototype);\n}\n\n/**\n * Slideout constructor\n */\nfunction Slideout(options) {\n  options = options || {};\n\n  // Sets default values\n  this._startOffsetX = 0;\n  this._currentOffsetX = 0;\n  this._opening = false;\n  this._moved = false;\n  this._opened = false;\n  this._preventOpen = false;\n  this._touch = options.touch === undefined ? true : options.touch && true;\n\n  // Sets panel\n  this.panel = options.panel;\n  this.menu = options.menu;\n\n  // Sets  classnames\n  if(this.panel.className.search('slideout-panel') === -1) { this.panel.className += ' slideout-panel'; }\n  if(this.menu.className.search('slideout-menu') === -1) { this.menu.className += ' slideout-menu'; }\n\n\n  // Sets options\n  this._fx = options.fx || 'ease';\n  this._duration = parseInt(options.duration, 10) || 300;\n  this._tolerance = parseInt(options.tolerance, 10) || 70;\n  this._padding = this._translateTo = parseInt(options.padding, 10) || 256;\n  this._orientation = options.side === 'right' ? -1 : 1;\n  this._translateTo *= this._orientation;\n\n  // Init touch events\n  if (this._touch) {\n    this._initTouchEvents();\n  }\n}\n\n/**\n * Inherits from Emitter\n */\ninherits(Slideout, Emitter);\n\n/**\n * Opens the slideout menu.\n */\nSlideout.prototype.open = function() {\n  var self = this;\n  this.emit('beforeopen');\n  if (html.className.search('slideout-open') === -1) { html.className += ' slideout-open'; }\n  this._setTransition();\n  this._translateXTo(this._translateTo);\n  this._opened = true;\n  setTimeout(function() {\n    self.panel.style.transition = self.panel.style['-webkit-transition'] = '';\n    self.emit('open');\n  }, this._duration + 50);\n  return this;\n};\n\n/**\n * Closes slideout menu.\n */\nSlideout.prototype.close = function() {\n  var self = this;\n  if (!this.isOpen() && !this._opening) {\n    return this;\n  }\n  this.emit('beforeclose');\n  this._setTransition();\n  this._translateXTo(0);\n  this._opened = false;\n  setTimeout(function() {\n    html.className = html.className.replace(/ slideout-open/, '');\n    self.panel.style.transition = self.panel.style['-webkit-transition'] = self.panel.style[prefix + 'transform'] = self.panel.style.transform = '';\n    self.emit('close');\n  }, this._duration + 50);\n  return this;\n};\n\n/**\n * Toggles (open/close) slideout menu.\n */\nSlideout.prototype.toggle = function() {\n  return this.isOpen() ? this.close() : this.open();\n};\n\n/**\n * Returns true if the slideout is currently open, and false if it is closed.\n */\nSlideout.prototype.isOpen = function() {\n  return this._opened;\n};\n\n/**\n * Translates panel and updates currentOffset with a given X point\n */\nSlideout.prototype._translateXTo = function(translateX) {\n  this._currentOffsetX = translateX;\n  this.panel.style[prefix + 'transform'] = this.panel.style.transform = 'translateX(' + translateX + 'px)';\n  return this;\n};\n\n/**\n * Set transition properties\n */\nSlideout.prototype._setTransition = function() {\n  this.panel.style[prefix + 'transition'] = this.panel.style.transition = prefix + 'transform ' + this._duration + 'ms ' + this._fx;\n  return this;\n};\n\n/**\n * Initializes touch event\n */\nSlideout.prototype._initTouchEvents = function() {\n  var self = this;\n\n  /**\n   * Decouple scroll event\n   */\n  this._onScrollFn = decouple(doc, 'scroll', function() {\n    if (!self._moved) {\n      clearTimeout(scrollTimeout);\n      scrolling = true;\n      scrollTimeout = setTimeout(function() {\n        scrolling = false;\n      }, 250);\n    }\n  });\n\n  /**\n   * Prevents touchmove event if slideout is moving\n   */\n  this._preventMove = function(eve) {\n    if (self._moved) {\n      eve.preventDefault();\n    }\n  };\n\n  doc.addEventListener(touch.move, this._preventMove);\n\n  /**\n   * Resets values on touchstart\n   */\n  this._resetTouchFn = function(eve) {\n    if (typeof eve.touches === 'undefined') {\n      return;\n    }\n\n    self._moved = false;\n    self._opening = false;\n    self._startOffsetX = eve.touches[0].pageX;\n    self._preventOpen = (!self._touch || (!self.isOpen() && self.menu.clientWidth !== 0));\n  };\n\n  this.panel.addEventListener(touch.start, this._resetTouchFn);\n\n  /**\n   * Resets values on touchcancel\n   */\n  this._onTouchCancelFn = function() {\n    self._moved = false;\n    self._opening = false;\n  };\n\n  this.panel.addEventListener('touchcancel', this._onTouchCancelFn);\n\n  /**\n   * Toggles slideout on touchend\n   */\n  this._onTouchEndFn = function() {\n    if (self._moved) {\n      (self._opening && Math.abs(self._currentOffsetX) > self._tolerance) ? self.open() : self.close();\n    }\n    self._moved = false;\n  };\n\n  this.panel.addEventListener(touch.end, this._onTouchEndFn);\n\n  /**\n   * Translates panel on touchmove\n   */\n  this._onTouchMoveFn = function(eve) {\n\n    if (scrolling || self._preventOpen || typeof eve.touches === 'undefined') {\n      return;\n    }\n\n    var dif_x = eve.touches[0].clientX - self._startOffsetX;\n    var translateX = self._currentOffsetX = dif_x;\n\n    if (Math.abs(translateX) > self._padding) {\n      return;\n    }\n\n    if (Math.abs(dif_x) > 20) {\n\n      self._opening = true;\n\n      var oriented_dif_x = dif_x * self._orientation;\n\n      if (self._opened && oriented_dif_x > 0 || !self._opened && oriented_dif_x < 0) {\n        return;\n      }\n\n      if (oriented_dif_x <= 0) {\n        translateX = dif_x + self._padding * self._orientation;\n        self._opening = false;\n      }\n\n      if (!self._moved && html.className.search('slideout-open') === -1) {\n        html.className += ' slideout-open';\n      }\n\n      self.panel.style[prefix + 'transform'] = self.panel.style.transform = 'translateX(' + translateX + 'px)';\n      self.emit('translate', translateX);\n      self._moved = true;\n    }\n\n  };\n\n  this.panel.addEventListener(touch.move, this._onTouchMoveFn);\n\n  return this;\n};\n\n/**\n * Enable opening the slideout via touch events.\n */\nSlideout.prototype.enableTouch = function() {\n  this._touch = true;\n  return this;\n};\n\n/**\n * Disable opening the slideout via touch events.\n */\nSlideout.prototype.disableTouch = function() {\n  this._touch = false;\n  return this;\n};\n\n/**\n * Destroy an instance of slideout.\n */\nSlideout.prototype.destroy = function() {\n  // Close before clean\n  this.close();\n\n  // Remove event listeners\n  doc.removeEventListener(touch.move, this._preventMove);\n  this.panel.removeEventListener(touch.start, this._resetTouchFn);\n  this.panel.removeEventListener('touchcancel', this._onTouchCancelFn);\n  this.panel.removeEventListener(touch.end, this._onTouchEndFn);\n  this.panel.removeEventListener(touch.move, this._onTouchMoveFn);\n  doc.removeEventListener('scroll', this._onScrollFn);\n\n  // Remove methods\n  this.open = this.close = function() {};\n\n  // Return the instance so it can be easily dereferenced\n  return this;\n};\n\n/**\n * Expose Slideout\n */\nmodule.exports = Slideout;\n\n},{\"decouple\":2,\"emitter\":3}],2:[function(require,module,exports){\n'use strict';\n\nvar requestAnimFrame = (function() {\n  return window.requestAnimationFrame ||\n    window.webkitRequestAnimationFrame ||\n    function (callback) {\n      window.setTimeout(callback, 1000 / 60);\n    };\n}());\n\nfunction decouple(node, event, fn) {\n  var eve,\n      tracking = false;\n\n  function captureEvent(e) {\n    eve = e;\n    track();\n  }\n\n  function track() {\n    if (!tracking) {\n      requestAnimFrame(update);\n      tracking = true;\n    }\n  }\n\n  function update() {\n    fn.call(node, eve);\n    tracking = false;\n  }\n\n  node.addEventListener(event, captureEvent, false);\n\n  return captureEvent;\n}\n\n/**\n * Expose decouple\n */\nmodule.exports = decouple;\n\n},{}],3:[function(require,module,exports){\n\"use strict\";\n\nvar _classCallCheck = function (instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } };\n\nexports.__esModule = true;\n/**\n * Creates a new instance of Emitter.\n * @class\n * @returns {Object} Returns a new instance of Emitter.\n * @example\n * // Creates a new instance of Emitter.\n * var Emitter = require('emitter');\n *\n * var emitter = new Emitter();\n */\n\nvar Emitter = (function () {\n  function Emitter() {\n    _classCallCheck(this, Emitter);\n  }\n\n  /**\n   * Adds a listener to the collection for the specified event.\n   * @memberof! Emitter.prototype\n   * @function\n   * @param {String} event - The event name.\n   * @param {Function} listener - A listener function to add.\n   * @returns {Object} Returns an instance of Emitter.\n   * @example\n   * // Add an event listener to \"foo\" event.\n   * emitter.on('foo', listener);\n   */\n\n  Emitter.prototype.on = function on(event, listener) {\n    // Use the current collection or create it.\n    this._eventCollection = this._eventCollection || {};\n\n    // Use the current collection of an event or create it.\n    this._eventCollection[event] = this._eventCollection[event] || [];\n\n    // Appends the listener into the collection of the given event\n    this._eventCollection[event].push(listener);\n\n    return this;\n  };\n\n  /**\n   * Adds a listener to the collection for the specified event that will be called only once.\n   * @memberof! Emitter.prototype\n   * @function\n   * @param {String} event - The event name.\n   * @param {Function} listener - A listener function to add.\n   * @returns {Object} Returns an instance of Emitter.\n   * @example\n   * // Will add an event handler to \"foo\" event once.\n   * emitter.once('foo', listener);\n   */\n\n  Emitter.prototype.once = function once(event, listener) {\n    var self = this;\n\n    function fn() {\n      self.off(event, fn);\n      listener.apply(this, arguments);\n    }\n\n    fn.listener = listener;\n\n    this.on(event, fn);\n\n    return this;\n  };\n\n  /**\n   * Removes a listener from the collection for the specified event.\n   * @memberof! Emitter.prototype\n   * @function\n   * @param {String} event - The event name.\n   * @param {Function} listener - A listener function to remove.\n   * @returns {Object} Returns an instance of Emitter.\n   * @example\n   * // Remove a given listener.\n   * emitter.off('foo', listener);\n   */\n\n  Emitter.prototype.off = function off(event, listener) {\n\n    var listeners = undefined;\n\n    // Defines listeners value.\n    if (!this._eventCollection || !(listeners = this._eventCollection[event])) {\n      return this;\n    }\n\n    listeners.forEach(function (fn, i) {\n      if (fn === listener || fn.listener === listener) {\n        // Removes the given listener.\n        listeners.splice(i, 1);\n      }\n    });\n\n    // Removes an empty event collection.\n    if (listeners.length === 0) {\n      delete this._eventCollection[event];\n    }\n\n    return this;\n  };\n\n  /**\n   * Execute each item in the listener collection in order with the specified data.\n   * @memberof! Emitter.prototype\n   * @function\n   * @param {String} event - The name of the event you want to emit.\n   * @param {...Object} data - Data to pass to the listeners.\n   * @returns {Object} Returns an instance of Emitter.\n   * @example\n   * // Emits the \"foo\" event with 'param1' and 'param2' as arguments.\n   * emitter.emit('foo', 'param1', 'param2');\n   */\n\n  Emitter.prototype.emit = function emit(event) {\n    var _this = this;\n\n    for (var _len = arguments.length, args = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {\n      args[_key - 1] = arguments[_key];\n    }\n\n    var listeners = undefined;\n\n    // Defines listeners value.\n    if (!this._eventCollection || !(listeners = this._eventCollection[event])) {\n      return this;\n    }\n\n    // Clone listeners\n    listeners = listeners.slice(0);\n\n    listeners.forEach(function (fn) {\n      return fn.apply(_this, args);\n    });\n\n    return this;\n  };\n\n  return Emitter;\n})();\n\n/**\n * Exports Emitter\n */\nexports[\"default\"] = Emitter;\nmodule.exports = exports[\"default\"];\n},{}]},{},[1])(1)\n});\n//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIm5vZGVfbW9kdWxlcy9icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9icm93c2VyLXBhY2svX3ByZWx1ZGUuanMiLCJpbmRleC5qcyIsIm5vZGVfbW9kdWxlcy9kZWNvdXBsZS9pbmRleC5qcyIsIm5vZGVfbW9kdWxlcy9lbWl0dGVyL2Rpc3QvaW5kZXguanMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7QUNBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzVUQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3hDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EiLCJmaWxlIjoiZ2VuZXJhdGVkLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXNDb250ZW50IjpbIihmdW5jdGlvbiBlKHQsbixyKXtmdW5jdGlvbiBzKG8sdSl7aWYoIW5bb10pe2lmKCF0W29dKXt2YXIgYT10eXBlb2YgcmVxdWlyZT09XCJmdW5jdGlvblwiJiZyZXF1aXJlO2lmKCF1JiZhKXJldHVybiBhKG8sITApO2lmKGkpcmV0dXJuIGkobywhMCk7dmFyIGY9bmV3IEVycm9yKFwiQ2Fubm90IGZpbmQgbW9kdWxlICdcIitvK1wiJ1wiKTt0aHJvdyBmLmNvZGU9XCJNT0RVTEVfTk9UX0ZPVU5EXCIsZn12YXIgbD1uW29dPXtleHBvcnRzOnt9fTt0W29dWzBdLmNhbGwobC5leHBvcnRzLGZ1bmN0aW9uKGUpe3ZhciBuPXRbb11bMV1bZV07cmV0dXJuIHMobj9uOmUpfSxsLGwuZXhwb3J0cyxlLHQsbixyKX1yZXR1cm4gbltvXS5leHBvcnRzfXZhciBpPXR5cGVvZiByZXF1aXJlPT1cImZ1bmN0aW9uXCImJnJlcXVpcmU7Zm9yKHZhciBvPTA7bzxyLmxlbmd0aDtvKyspcyhyW29dKTtyZXR1cm4gc30pIiwiJ3VzZSBzdHJpY3QnO1xuXG4vKipcbiAqIE1vZHVsZSBkZXBlbmRlbmNpZXNcbiAqL1xudmFyIGRlY291cGxlID0gcmVxdWlyZSgnZGVjb3VwbGUnKTtcbnZhciBFbWl0dGVyID0gcmVxdWlyZSgnZW1pdHRlcicpO1xuXG4vKipcbiAqIFByaXZhdGVzXG4gKi9cbnZhciBzY3JvbGxUaW1lb3V0O1xudmFyIHNjcm9sbGluZyA9IGZhbHNlO1xudmFyIGRvYyA9IHdpbmRvdy5kb2N1bWVudDtcbnZhciBodG1sID0gZG9jLmRvY3VtZW50RWxlbWVudDtcbnZhciBtc1BvaW50ZXJTdXBwb3J0ZWQgPSB3aW5kb3cubmF2aWdhdG9yLm1zUG9pbnRlckVuYWJsZWQ7XG52YXIgdG91Y2ggPSB7XG4gICdzdGFydCc6IG1zUG9pbnRlclN1cHBvcnRlZCA/ICdNU1BvaW50ZXJEb3duJyA6ICd0b3VjaHN0YXJ0JyxcbiAgJ21vdmUnOiBtc1BvaW50ZXJTdXBwb3J0ZWQgPyAnTVNQb2ludGVyTW92ZScgOiAndG91Y2htb3ZlJyxcbiAgJ2VuZCc6IG1zUG9pbnRlclN1cHBvcnRlZCA/ICdNU1BvaW50ZXJVcCcgOiAndG91Y2hlbmQnXG59O1xudmFyIHByZWZpeCA9IChmdW5jdGlvbiBwcmVmaXgoKSB7XG4gIHZhciByZWdleCA9IC9eKFdlYmtpdHxLaHRtbHxNb3p8bXN8TykoPz1bQS1aXSkvO1xuICB2YXIgc3R5bGVEZWNsYXJhdGlvbiA9IGRvYy5nZXRFbGVtZW50c0J5VGFnTmFtZSgnc2NyaXB0JylbMF0uc3R5bGU7XG4gIGZvciAodmFyIHByb3AgaW4gc3R5bGVEZWNsYXJhdGlvbikge1xuICAgIGlmIChyZWdleC50ZXN0KHByb3ApKSB7XG4gICAgICByZXR1cm4gJy0nICsgcHJvcC5tYXRjaChyZWdleClbMF0udG9Mb3dlckNhc2UoKSArICctJztcbiAgICB9XG4gIH1cbiAgLy8gTm90aGluZyBmb3VuZCBzbyBmYXI/IFdlYmtpdCBkb2VzIG5vdCBlbnVtZXJhdGUgb3ZlciB0aGUgQ1NTIHByb3BlcnRpZXMgb2YgdGhlIHN0eWxlIG9iamVjdC5cbiAgLy8gSG93ZXZlciAocHJvcCBpbiBzdHlsZSkgcmV0dXJucyB0aGUgY29ycmVjdCB2YWx1ZSwgc28gd2UnbGwgaGF2ZSB0byB0ZXN0IGZvclxuICAvLyB0aGUgcHJlY2VuY2Ugb2YgYSBzcGVjaWZpYyBwcm9wZXJ0eVxuICBpZiAoJ1dlYmtpdE9wYWNpdHknIGluIHN0eWxlRGVjbGFyYXRpb24pIHsgcmV0dXJuICctd2Via2l0LSc7IH1cbiAgaWYgKCdLaHRtbE9wYWNpdHknIGluIHN0eWxlRGVjbGFyYXRpb24pIHsgcmV0dXJuICcta2h0bWwtJzsgfVxuICByZXR1cm4gJyc7XG59KCkpO1xuZnVuY3Rpb24gZXh0ZW5kKGRlc3RpbmF0aW9uLCBmcm9tKSB7XG4gIGZvciAodmFyIHByb3AgaW4gZnJvbSkge1xuICAgIGlmIChmcm9tW3Byb3BdKSB7XG4gICAgICBkZXN0aW5hdGlvbltwcm9wXSA9IGZyb21bcHJvcF07XG4gICAgfVxuICB9XG4gIHJldHVybiBkZXN0aW5hdGlvbjtcbn1cbmZ1bmN0aW9uIGluaGVyaXRzKGNoaWxkLCB1YmVyKSB7XG4gIGNoaWxkLnByb3RvdHlwZSA9IGV4dGVuZChjaGlsZC5wcm90b3R5cGUgfHwge30sIHViZXIucHJvdG90eXBlKTtcbn1cblxuLyoqXG4gKiBTbGlkZW91dCBjb25zdHJ1Y3RvclxuICovXG5mdW5jdGlvbiBTbGlkZW91dChvcHRpb25zKSB7XG4gIG9wdGlvbnMgPSBvcHRpb25zIHx8IHt9O1xuXG4gIC8vIFNldHMgZGVmYXVsdCB2YWx1ZXNcbiAgdGhpcy5fc3RhcnRPZmZzZXRYID0gMDtcbiAgdGhpcy5fY3VycmVudE9mZnNldFggPSAwO1xuICB0aGlzLl9vcGVuaW5nID0gZmFsc2U7XG4gIHRoaXMuX21vdmVkID0gZmFsc2U7XG4gIHRoaXMuX29wZW5lZCA9IGZhbHNlO1xuICB0aGlzLl9wcmV2ZW50T3BlbiA9IGZhbHNlO1xuICB0aGlzLl90b3VjaCA9IG9wdGlvbnMudG91Y2ggPT09IHVuZGVmaW5lZCA/IHRydWUgOiBvcHRpb25zLnRvdWNoICYmIHRydWU7XG5cbiAgLy8gU2V0cyBwYW5lbFxuICB0aGlzLnBhbmVsID0gb3B0aW9ucy5wYW5lbDtcbiAgdGhpcy5tZW51ID0gb3B0aW9ucy5tZW51O1xuXG4gIC8vIFNldHMgIGNsYXNzbmFtZXNcbiAgaWYodGhpcy5wYW5lbC5jbGFzc05hbWUuc2VhcmNoKCdzbGlkZW91dC1wYW5lbCcpID09PSAtMSkgeyB0aGlzLnBhbmVsLmNsYXNzTmFtZSArPSAnIHNsaWRlb3V0LXBhbmVsJzsgfVxuICBpZih0aGlzLm1lbnUuY2xhc3NOYW1lLnNlYXJjaCgnc2xpZGVvdXQtbWVudScpID09PSAtMSkgeyB0aGlzLm1lbnUuY2xhc3NOYW1lICs9ICcgc2xpZGVvdXQtbWVudSc7IH1cblxuXG4gIC8vIFNldHMgb3B0aW9uc1xuICB0aGlzLl9meCA9IG9wdGlvbnMuZnggfHwgJ2Vhc2UnO1xuICB0aGlzLl9kdXJhdGlvbiA9IHBhcnNlSW50KG9wdGlvbnMuZHVyYXRpb24sIDEwKSB8fCAzMDA7XG4gIHRoaXMuX3RvbGVyYW5jZSA9IHBhcnNlSW50KG9wdGlvbnMudG9sZXJhbmNlLCAxMCkgfHwgNzA7XG4gIHRoaXMuX3BhZGRpbmcgPSB0aGlzLl90cmFuc2xhdGVUbyA9IHBhcnNlSW50KG9wdGlvbnMucGFkZGluZywgMTApIHx8IDI1NjtcbiAgdGhpcy5fb3JpZW50YXRpb24gPSBvcHRpb25zLnNpZGUgPT09ICdyaWdodCcgPyAtMSA6IDE7XG4gIHRoaXMuX3RyYW5zbGF0ZVRvICo9IHRoaXMuX29yaWVudGF0aW9uO1xuXG4gIC8vIEluaXQgdG91Y2ggZXZlbnRzXG4gIGlmICh0aGlzLl90b3VjaCkge1xuICAgIHRoaXMuX2luaXRUb3VjaEV2ZW50cygpO1xuICB9XG59XG5cbi8qKlxuICogSW5oZXJpdHMgZnJvbSBFbWl0dGVyXG4gKi9cbmluaGVyaXRzKFNsaWRlb3V0LCBFbWl0dGVyKTtcblxuLyoqXG4gKiBPcGVucyB0aGUgc2xpZGVvdXQgbWVudS5cbiAqL1xuU2xpZGVvdXQucHJvdG90eXBlLm9wZW4gPSBmdW5jdGlvbigpIHtcbiAgdmFyIHNlbGYgPSB0aGlzO1xuICB0aGlzLmVtaXQoJ2JlZm9yZW9wZW4nKTtcbiAgaWYgKGh0bWwuY2xhc3NOYW1lLnNlYXJjaCgnc2xpZGVvdXQtb3BlbicpID09PSAtMSkgeyBodG1sLmNsYXNzTmFtZSArPSAnIHNsaWRlb3V0LW9wZW4nOyB9XG4gIHRoaXMuX3NldFRyYW5zaXRpb24oKTtcbiAgdGhpcy5fdHJhbnNsYXRlWFRvKHRoaXMuX3RyYW5zbGF0ZVRvKTtcbiAgdGhpcy5fb3BlbmVkID0gdHJ1ZTtcbiAgc2V0VGltZW91dChmdW5jdGlvbigpIHtcbiAgICBzZWxmLnBhbmVsLnN0eWxlLnRyYW5zaXRpb24gPSBzZWxmLnBhbmVsLnN0eWxlWyctd2Via2l0LXRyYW5zaXRpb24nXSA9ICcnO1xuICAgIHNlbGYuZW1pdCgnb3BlbicpO1xuICB9LCB0aGlzLl9kdXJhdGlvbiArIDUwKTtcbiAgcmV0dXJuIHRoaXM7XG59O1xuXG4vKipcbiAqIENsb3NlcyBzbGlkZW91dCBtZW51LlxuICovXG5TbGlkZW91dC5wcm90b3R5cGUuY2xvc2UgPSBmdW5jdGlvbigpIHtcbiAgdmFyIHNlbGYgPSB0aGlzO1xuICBpZiAoIXRoaXMuaXNPcGVuKCkgJiYgIXRoaXMuX29wZW5pbmcpIHtcbiAgICByZXR1cm4gdGhpcztcbiAgfVxuICB0aGlzLmVtaXQoJ2JlZm9yZWNsb3NlJyk7XG4gIHRoaXMuX3NldFRyYW5zaXRpb24oKTtcbiAgdGhpcy5fdHJhbnNsYXRlWFRvKDApO1xuICB0aGlzLl9vcGVuZWQgPSBmYWxzZTtcbiAgc2V0VGltZW91dChmdW5jdGlvbigpIHtcbiAgICBodG1sLmNsYXNzTmFtZSA9IGh0bWwuY2xhc3NOYW1lLnJlcGxhY2UoLyBzbGlkZW91dC1vcGVuLywgJycpO1xuICAgIHNlbGYucGFuZWwuc3R5bGUudHJhbnNpdGlvbiA9IHNlbGYucGFuZWwuc3R5bGVbJy13ZWJraXQtdHJhbnNpdGlvbiddID0gc2VsZi5wYW5lbC5zdHlsZVtwcmVmaXggKyAndHJhbnNmb3JtJ10gPSBzZWxmLnBhbmVsLnN0eWxlLnRyYW5zZm9ybSA9ICcnO1xuICAgIHNlbGYuZW1pdCgnY2xvc2UnKTtcbiAgfSwgdGhpcy5fZHVyYXRpb24gKyA1MCk7XG4gIHJldHVybiB0aGlzO1xufTtcblxuLyoqXG4gKiBUb2dnbGVzIChvcGVuL2Nsb3NlKSBzbGlkZW91dCBtZW51LlxuICovXG5TbGlkZW91dC5wcm90b3R5cGUudG9nZ2xlID0gZnVuY3Rpb24oKSB7XG4gIHJldHVybiB0aGlzLmlzT3BlbigpID8gdGhpcy5jbG9zZSgpIDogdGhpcy5vcGVuKCk7XG59O1xuXG4vKipcbiAqIFJldHVybnMgdHJ1ZSBpZiB0aGUgc2xpZGVvdXQgaXMgY3VycmVudGx5IG9wZW4sIGFuZCBmYWxzZSBpZiBpdCBpcyBjbG9zZWQuXG4gKi9cblNsaWRlb3V0LnByb3RvdHlwZS5pc09wZW4gPSBmdW5jdGlvbigpIHtcbiAgcmV0dXJuIHRoaXMuX29wZW5lZDtcbn07XG5cbi8qKlxuICogVHJhbnNsYXRlcyBwYW5lbCBhbmQgdXBkYXRlcyBjdXJyZW50T2Zmc2V0IHdpdGggYSBnaXZlbiBYIHBvaW50XG4gKi9cblNsaWRlb3V0LnByb3RvdHlwZS5fdHJhbnNsYXRlWFRvID0gZnVuY3Rpb24odHJhbnNsYXRlWCkge1xuICB0aGlzLl9jdXJyZW50T2Zmc2V0WCA9IHRyYW5zbGF0ZVg7XG4gIHRoaXMucGFuZWwuc3R5bGVbcHJlZml4ICsgJ3RyYW5zZm9ybSddID0gdGhpcy5wYW5lbC5zdHlsZS50cmFuc2Zvcm0gPSAndHJhbnNsYXRlWCgnICsgdHJhbnNsYXRlWCArICdweCknO1xuICByZXR1cm4gdGhpcztcbn07XG5cbi8qKlxuICogU2V0IHRyYW5zaXRpb24gcHJvcGVydGllc1xuICovXG5TbGlkZW91dC5wcm90b3R5cGUuX3NldFRyYW5zaXRpb24gPSBmdW5jdGlvbigpIHtcbiAgdGhpcy5wYW5lbC5zdHlsZVtwcmVmaXggKyAndHJhbnNpdGlvbiddID0gdGhpcy5wYW5lbC5zdHlsZS50cmFuc2l0aW9uID0gcHJlZml4ICsgJ3RyYW5zZm9ybSAnICsgdGhpcy5fZHVyYXRpb24gKyAnbXMgJyArIHRoaXMuX2Z4O1xuICByZXR1cm4gdGhpcztcbn07XG5cbi8qKlxuICogSW5pdGlhbGl6ZXMgdG91Y2ggZXZlbnRcbiAqL1xuU2xpZGVvdXQucHJvdG90eXBlLl9pbml0VG91Y2hFdmVudHMgPSBmdW5jdGlvbigpIHtcbiAgdmFyIHNlbGYgPSB0aGlzO1xuXG4gIC8qKlxuICAgKiBEZWNvdXBsZSBzY3JvbGwgZXZlbnRcbiAgICovXG4gIHRoaXMuX29uU2Nyb2xsRm4gPSBkZWNvdXBsZShkb2MsICdzY3JvbGwnLCBmdW5jdGlvbigpIHtcbiAgICBpZiAoIXNlbGYuX21vdmVkKSB7XG4gICAgICBjbGVhclRpbWVvdXQoc2Nyb2xsVGltZW91dCk7XG4gICAgICBzY3JvbGxpbmcgPSB0cnVlO1xuICAgICAgc2Nyb2xsVGltZW91dCA9IHNldFRpbWVvdXQoZnVuY3Rpb24oKSB7XG4gICAgICAgIHNjcm9sbGluZyA9IGZhbHNlO1xuICAgICAgfSwgMjUwKTtcbiAgICB9XG4gIH0pO1xuXG4gIC8qKlxuICAgKiBQcmV2ZW50cyB0b3VjaG1vdmUgZXZlbnQgaWYgc2xpZGVvdXQgaXMgbW92aW5nXG4gICAqL1xuICB0aGlzLl9wcmV2ZW50TW92ZSA9IGZ1bmN0aW9uKGV2ZSkge1xuICAgIGlmIChzZWxmLl9tb3ZlZCkge1xuICAgICAgZXZlLnByZXZlbnREZWZhdWx0KCk7XG4gICAgfVxuICB9O1xuXG4gIGRvYy5hZGRFdmVudExpc3RlbmVyKHRvdWNoLm1vdmUsIHRoaXMuX3ByZXZlbnRNb3ZlKTtcblxuICAvKipcbiAgICogUmVzZXRzIHZhbHVlcyBvbiB0b3VjaHN0YXJ0XG4gICAqL1xuICB0aGlzLl9yZXNldFRvdWNoRm4gPSBmdW5jdGlvbihldmUpIHtcbiAgICBpZiAodHlwZW9mIGV2ZS50b3VjaGVzID09PSAndW5kZWZpbmVkJykge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHNlbGYuX21vdmVkID0gZmFsc2U7XG4gICAgc2VsZi5fb3BlbmluZyA9IGZhbHNlO1xuICAgIHNlbGYuX3N0YXJ0T2Zmc2V0WCA9IGV2ZS50b3VjaGVzWzBdLnBhZ2VYO1xuICAgIHNlbGYuX3ByZXZlbnRPcGVuID0gKCFzZWxmLl90b3VjaCB8fCAoIXNlbGYuaXNPcGVuKCkgJiYgc2VsZi5tZW51LmNsaWVudFdpZHRoICE9PSAwKSk7XG4gIH07XG5cbiAgdGhpcy5wYW5lbC5hZGRFdmVudExpc3RlbmVyKHRvdWNoLnN0YXJ0LCB0aGlzLl9yZXNldFRvdWNoRm4pO1xuXG4gIC8qKlxuICAgKiBSZXNldHMgdmFsdWVzIG9uIHRvdWNoY2FuY2VsXG4gICAqL1xuICB0aGlzLl9vblRvdWNoQ2FuY2VsRm4gPSBmdW5jdGlvbigpIHtcbiAgICBzZWxmLl9tb3ZlZCA9IGZhbHNlO1xuICAgIHNlbGYuX29wZW5pbmcgPSBmYWxzZTtcbiAgfTtcblxuICB0aGlzLnBhbmVsLmFkZEV2ZW50TGlzdGVuZXIoJ3RvdWNoY2FuY2VsJywgdGhpcy5fb25Ub3VjaENhbmNlbEZuKTtcblxuICAvKipcbiAgICogVG9nZ2xlcyBzbGlkZW91dCBvbiB0b3VjaGVuZFxuICAgKi9cbiAgdGhpcy5fb25Ub3VjaEVuZEZuID0gZnVuY3Rpb24oKSB7XG4gICAgaWYgKHNlbGYuX21vdmVkKSB7XG4gICAgICAoc2VsZi5fb3BlbmluZyAmJiBNYXRoLmFicyhzZWxmLl9jdXJyZW50T2Zmc2V0WCkgPiBzZWxmLl90b2xlcmFuY2UpID8gc2VsZi5vcGVuKCkgOiBzZWxmLmNsb3NlKCk7XG4gICAgfVxuICAgIHNlbGYuX21vdmVkID0gZmFsc2U7XG4gIH07XG5cbiAgdGhpcy5wYW5lbC5hZGRFdmVudExpc3RlbmVyKHRvdWNoLmVuZCwgdGhpcy5fb25Ub3VjaEVuZEZuKTtcblxuICAvKipcbiAgICogVHJhbnNsYXRlcyBwYW5lbCBvbiB0b3VjaG1vdmVcbiAgICovXG4gIHRoaXMuX29uVG91Y2hNb3ZlRm4gPSBmdW5jdGlvbihldmUpIHtcblxuICAgIGlmIChzY3JvbGxpbmcgfHwgc2VsZi5fcHJldmVudE9wZW4gfHwgdHlwZW9mIGV2ZS50b3VjaGVzID09PSAndW5kZWZpbmVkJykge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHZhciBkaWZfeCA9IGV2ZS50b3VjaGVzWzBdLmNsaWVudFggLSBzZWxmLl9zdGFydE9mZnNldFg7XG4gICAgdmFyIHRyYW5zbGF0ZVggPSBzZWxmLl9jdXJyZW50T2Zmc2V0WCA9IGRpZl94O1xuXG4gICAgaWYgKE1hdGguYWJzKHRyYW5zbGF0ZVgpID4gc2VsZi5fcGFkZGluZykge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGlmIChNYXRoLmFicyhkaWZfeCkgPiAyMCkge1xuXG4gICAgICBzZWxmLl9vcGVuaW5nID0gdHJ1ZTtcblxuICAgICAgdmFyIG9yaWVudGVkX2RpZl94ID0gZGlmX3ggKiBzZWxmLl9vcmllbnRhdGlvbjtcblxuICAgICAgaWYgKHNlbGYuX29wZW5lZCAmJiBvcmllbnRlZF9kaWZfeCA+IDAgfHwgIXNlbGYuX29wZW5lZCAmJiBvcmllbnRlZF9kaWZfeCA8IDApIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICBpZiAob3JpZW50ZWRfZGlmX3ggPD0gMCkge1xuICAgICAgICB0cmFuc2xhdGVYID0gZGlmX3ggKyBzZWxmLl9wYWRkaW5nICogc2VsZi5fb3JpZW50YXRpb247XG4gICAgICAgIHNlbGYuX29wZW5pbmcgPSBmYWxzZTtcbiAgICAgIH1cblxuICAgICAgaWYgKCFzZWxmLl9tb3ZlZCAmJiBodG1sLmNsYXNzTmFtZS5zZWFyY2goJ3NsaWRlb3V0LW9wZW4nKSA9PT0gLTEpIHtcbiAgICAgICAgaHRtbC5jbGFzc05hbWUgKz0gJyBzbGlkZW91dC1vcGVuJztcbiAgICAgIH1cblxuICAgICAgc2VsZi5wYW5lbC5zdHlsZVtwcmVmaXggKyAndHJhbnNmb3JtJ10gPSBzZWxmLnBhbmVsLnN0eWxlLnRyYW5zZm9ybSA9ICd0cmFuc2xhdGVYKCcgKyB0cmFuc2xhdGVYICsgJ3B4KSc7XG4gICAgICBzZWxmLmVtaXQoJ3RyYW5zbGF0ZScsIHRyYW5zbGF0ZVgpO1xuICAgICAgc2VsZi5fbW92ZWQgPSB0cnVlO1xuICAgIH1cblxuICB9O1xuXG4gIHRoaXMucGFuZWwuYWRkRXZlbnRMaXN0ZW5lcih0b3VjaC5tb3ZlLCB0aGlzLl9vblRvdWNoTW92ZUZuKTtcblxuICByZXR1cm4gdGhpcztcbn07XG5cbi8qKlxuICogRW5hYmxlIG9wZW5pbmcgdGhlIHNsaWRlb3V0IHZpYSB0b3VjaCBldmVudHMuXG4gKi9cblNsaWRlb3V0LnByb3RvdHlwZS5lbmFibGVUb3VjaCA9IGZ1bmN0aW9uKCkge1xuICB0aGlzLl90b3VjaCA9IHRydWU7XG4gIHJldHVybiB0aGlzO1xufTtcblxuLyoqXG4gKiBEaXNhYmxlIG9wZW5pbmcgdGhlIHNsaWRlb3V0IHZpYSB0b3VjaCBldmVudHMuXG4gKi9cblNsaWRlb3V0LnByb3RvdHlwZS5kaXNhYmxlVG91Y2ggPSBmdW5jdGlvbigpIHtcbiAgdGhpcy5fdG91Y2ggPSBmYWxzZTtcbiAgcmV0dXJuIHRoaXM7XG59O1xuXG4vKipcbiAqIERlc3Ryb3kgYW4gaW5zdGFuY2Ugb2Ygc2xpZGVvdXQuXG4gKi9cblNsaWRlb3V0LnByb3RvdHlwZS5kZXN0cm95ID0gZnVuY3Rpb24oKSB7XG4gIC8vIENsb3NlIGJlZm9yZSBjbGVhblxuICB0aGlzLmNsb3NlKCk7XG5cbiAgLy8gUmVtb3ZlIGV2ZW50IGxpc3RlbmVyc1xuICBkb2MucmVtb3ZlRXZlbnRMaXN0ZW5lcih0b3VjaC5tb3ZlLCB0aGlzLl9wcmV2ZW50TW92ZSk7XG4gIHRoaXMucGFuZWwucmVtb3ZlRXZlbnRMaXN0ZW5lcih0b3VjaC5zdGFydCwgdGhpcy5fcmVzZXRUb3VjaEZuKTtcbiAgdGhpcy5wYW5lbC5yZW1vdmVFdmVudExpc3RlbmVyKCd0b3VjaGNhbmNlbCcsIHRoaXMuX29uVG91Y2hDYW5jZWxGbik7XG4gIHRoaXMucGFuZWwucmVtb3ZlRXZlbnRMaXN0ZW5lcih0b3VjaC5lbmQsIHRoaXMuX29uVG91Y2hFbmRGbik7XG4gIHRoaXMucGFuZWwucmVtb3ZlRXZlbnRMaXN0ZW5lcih0b3VjaC5tb3ZlLCB0aGlzLl9vblRvdWNoTW92ZUZuKTtcbiAgZG9jLnJlbW92ZUV2ZW50TGlzdGVuZXIoJ3Njcm9sbCcsIHRoaXMuX29uU2Nyb2xsRm4pO1xuXG4gIC8vIFJlbW92ZSBtZXRob2RzXG4gIHRoaXMub3BlbiA9IHRoaXMuY2xvc2UgPSBmdW5jdGlvbigpIHt9O1xuXG4gIC8vIFJldHVybiB0aGUgaW5zdGFuY2Ugc28gaXQgY2FuIGJlIGVhc2lseSBkZXJlZmVyZW5jZWRcbiAgcmV0dXJuIHRoaXM7XG59O1xuXG4vKipcbiAqIEV4cG9zZSBTbGlkZW91dFxuICovXG5tb2R1bGUuZXhwb3J0cyA9IFNsaWRlb3V0O1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgcmVxdWVzdEFuaW1GcmFtZSA9IChmdW5jdGlvbigpIHtcbiAgcmV0dXJuIHdpbmRvdy5yZXF1ZXN0QW5pbWF0aW9uRnJhbWUgfHxcbiAgICB3aW5kb3cud2Via2l0UmVxdWVzdEFuaW1hdGlvbkZyYW1lIHx8XG4gICAgZnVuY3Rpb24gKGNhbGxiYWNrKSB7XG4gICAgICB3aW5kb3cuc2V0VGltZW91dChjYWxsYmFjaywgMTAwMCAvIDYwKTtcbiAgICB9O1xufSgpKTtcblxuZnVuY3Rpb24gZGVjb3VwbGUobm9kZSwgZXZlbnQsIGZuKSB7XG4gIHZhciBldmUsXG4gICAgICB0cmFja2luZyA9IGZhbHNlO1xuXG4gIGZ1bmN0aW9uIGNhcHR1cmVFdmVudChlKSB7XG4gICAgZXZlID0gZTtcbiAgICB0cmFjaygpO1xuICB9XG5cbiAgZnVuY3Rpb24gdHJhY2soKSB7XG4gICAgaWYgKCF0cmFja2luZykge1xuICAgICAgcmVxdWVzdEFuaW1GcmFtZSh1cGRhdGUpO1xuICAgICAgdHJhY2tpbmcgPSB0cnVlO1xuICAgIH1cbiAgfVxuXG4gIGZ1bmN0aW9uIHVwZGF0ZSgpIHtcbiAgICBmbi5jYWxsKG5vZGUsIGV2ZSk7XG4gICAgdHJhY2tpbmcgPSBmYWxzZTtcbiAgfVxuXG4gIG5vZGUuYWRkRXZlbnRMaXN0ZW5lcihldmVudCwgY2FwdHVyZUV2ZW50LCBmYWxzZSk7XG5cbiAgcmV0dXJuIGNhcHR1cmVFdmVudDtcbn1cblxuLyoqXG4gKiBFeHBvc2UgZGVjb3VwbGVcbiAqL1xubW9kdWxlLmV4cG9ydHMgPSBkZWNvdXBsZTtcbiIsIlwidXNlIHN0cmljdFwiO1xuXG52YXIgX2NsYXNzQ2FsbENoZWNrID0gZnVuY3Rpb24gKGluc3RhbmNlLCBDb25zdHJ1Y3RvcikgeyBpZiAoIShpbnN0YW5jZSBpbnN0YW5jZW9mIENvbnN0cnVjdG9yKSkgeyB0aHJvdyBuZXcgVHlwZUVycm9yKFwiQ2Fubm90IGNhbGwgYSBjbGFzcyBhcyBhIGZ1bmN0aW9uXCIpOyB9IH07XG5cbmV4cG9ydHMuX19lc01vZHVsZSA9IHRydWU7XG4vKipcbiAqIENyZWF0ZXMgYSBuZXcgaW5zdGFuY2Ugb2YgRW1pdHRlci5cbiAqIEBjbGFzc1xuICogQHJldHVybnMge09iamVjdH0gUmV0dXJucyBhIG5ldyBpbnN0YW5jZSBvZiBFbWl0dGVyLlxuICogQGV4YW1wbGVcbiAqIC8vIENyZWF0ZXMgYSBuZXcgaW5zdGFuY2Ugb2YgRW1pdHRlci5cbiAqIHZhciBFbWl0dGVyID0gcmVxdWlyZSgnZW1pdHRlcicpO1xuICpcbiAqIHZhciBlbWl0dGVyID0gbmV3IEVtaXR0ZXIoKTtcbiAqL1xuXG52YXIgRW1pdHRlciA9IChmdW5jdGlvbiAoKSB7XG4gIGZ1bmN0aW9uIEVtaXR0ZXIoKSB7XG4gICAgX2NsYXNzQ2FsbENoZWNrKHRoaXMsIEVtaXR0ZXIpO1xuICB9XG5cbiAgLyoqXG4gICAqIEFkZHMgYSBsaXN0ZW5lciB0byB0aGUgY29sbGVjdGlvbiBmb3IgdGhlIHNwZWNpZmllZCBldmVudC5cbiAgICogQG1lbWJlcm9mISBFbWl0dGVyLnByb3RvdHlwZVxuICAgKiBAZnVuY3Rpb25cbiAgICogQHBhcmFtIHtTdHJpbmd9IGV2ZW50IC0gVGhlIGV2ZW50IG5hbWUuXG4gICAqIEBwYXJhbSB7RnVuY3Rpb259IGxpc3RlbmVyIC0gQSBsaXN0ZW5lciBmdW5jdGlvbiB0byBhZGQuXG4gICAqIEByZXR1cm5zIHtPYmplY3R9IFJldHVybnMgYW4gaW5zdGFuY2Ugb2YgRW1pdHRlci5cbiAgICogQGV4YW1wbGVcbiAgICogLy8gQWRkIGFuIGV2ZW50IGxpc3RlbmVyIHRvIFwiZm9vXCIgZXZlbnQuXG4gICAqIGVtaXR0ZXIub24oJ2ZvbycsIGxpc3RlbmVyKTtcbiAgICovXG5cbiAgRW1pdHRlci5wcm90b3R5cGUub24gPSBmdW5jdGlvbiBvbihldmVudCwgbGlzdGVuZXIpIHtcbiAgICAvLyBVc2UgdGhlIGN1cnJlbnQgY29sbGVjdGlvbiBvciBjcmVhdGUgaXQuXG4gICAgdGhpcy5fZXZlbnRDb2xsZWN0aW9uID0gdGhpcy5fZXZlbnRDb2xsZWN0aW9uIHx8IHt9O1xuXG4gICAgLy8gVXNlIHRoZSBjdXJyZW50IGNvbGxlY3Rpb24gb2YgYW4gZXZlbnQgb3IgY3JlYXRlIGl0LlxuICAgIHRoaXMuX2V2ZW50Q29sbGVjdGlvbltldmVudF0gPSB0aGlzLl9ldmVudENvbGxlY3Rpb25bZXZlbnRdIHx8IFtdO1xuXG4gICAgLy8gQXBwZW5kcyB0aGUgbGlzdGVuZXIgaW50byB0aGUgY29sbGVjdGlvbiBvZiB0aGUgZ2l2ZW4gZXZlbnRcbiAgICB0aGlzLl9ldmVudENvbGxlY3Rpb25bZXZlbnRdLnB1c2gobGlzdGVuZXIpO1xuXG4gICAgcmV0dXJuIHRoaXM7XG4gIH07XG5cbiAgLyoqXG4gICAqIEFkZHMgYSBsaXN0ZW5lciB0byB0aGUgY29sbGVjdGlvbiBmb3IgdGhlIHNwZWNpZmllZCBldmVudCB0aGF0IHdpbGwgYmUgY2FsbGVkIG9ubHkgb25jZS5cbiAgICogQG1lbWJlcm9mISBFbWl0dGVyLnByb3RvdHlwZVxuICAgKiBAZnVuY3Rpb25cbiAgICogQHBhcmFtIHtTdHJpbmd9IGV2ZW50IC0gVGhlIGV2ZW50IG5hbWUuXG4gICAqIEBwYXJhbSB7RnVuY3Rpb259IGxpc3RlbmVyIC0gQSBsaXN0ZW5lciBmdW5jdGlvbiB0byBhZGQuXG4gICAqIEByZXR1cm5zIHtPYmplY3R9IFJldHVybnMgYW4gaW5zdGFuY2Ugb2YgRW1pdHRlci5cbiAgICogQGV4YW1wbGVcbiAgICogLy8gV2lsbCBhZGQgYW4gZXZlbnQgaGFuZGxlciB0byBcImZvb1wiIGV2ZW50IG9uY2UuXG4gICAqIGVtaXR0ZXIub25jZSgnZm9vJywgbGlzdGVuZXIpO1xuICAgKi9cblxuICBFbWl0dGVyLnByb3RvdHlwZS5vbmNlID0gZnVuY3Rpb24gb25jZShldmVudCwgbGlzdGVuZXIpIHtcbiAgICB2YXIgc2VsZiA9IHRoaXM7XG5cbiAgICBmdW5jdGlvbiBmbigpIHtcbiAgICAgIHNlbGYub2ZmKGV2ZW50LCBmbik7XG4gICAgICBsaXN0ZW5lci5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuICAgIH1cblxuICAgIGZuLmxpc3RlbmVyID0gbGlzdGVuZXI7XG5cbiAgICB0aGlzLm9uKGV2ZW50LCBmbik7XG5cbiAgICByZXR1cm4gdGhpcztcbiAgfTtcblxuICAvKipcbiAgICogUmVtb3ZlcyBhIGxpc3RlbmVyIGZyb20gdGhlIGNvbGxlY3Rpb24gZm9yIHRoZSBzcGVjaWZpZWQgZXZlbnQuXG4gICAqIEBtZW1iZXJvZiEgRW1pdHRlci5wcm90b3R5cGVcbiAgICogQGZ1bmN0aW9uXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBldmVudCAtIFRoZSBldmVudCBuYW1lLlxuICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBsaXN0ZW5lciAtIEEgbGlzdGVuZXIgZnVuY3Rpb24gdG8gcmVtb3ZlLlxuICAgKiBAcmV0dXJucyB7T2JqZWN0fSBSZXR1cm5zIGFuIGluc3RhbmNlIG9mIEVtaXR0ZXIuXG4gICAqIEBleGFtcGxlXG4gICAqIC8vIFJlbW92ZSBhIGdpdmVuIGxpc3RlbmVyLlxuICAgKiBlbWl0dGVyLm9mZignZm9vJywgbGlzdGVuZXIpO1xuICAgKi9cblxuICBFbWl0dGVyLnByb3RvdHlwZS5vZmYgPSBmdW5jdGlvbiBvZmYoZXZlbnQsIGxpc3RlbmVyKSB7XG5cbiAgICB2YXIgbGlzdGVuZXJzID0gdW5kZWZpbmVkO1xuXG4gICAgLy8gRGVmaW5lcyBsaXN0ZW5lcnMgdmFsdWUuXG4gICAgaWYgKCF0aGlzLl9ldmVudENvbGxlY3Rpb24gfHwgIShsaXN0ZW5lcnMgPSB0aGlzLl9ldmVudENvbGxlY3Rpb25bZXZlbnRdKSkge1xuICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgbGlzdGVuZXJzLmZvckVhY2goZnVuY3Rpb24gKGZuLCBpKSB7XG4gICAgICBpZiAoZm4gPT09IGxpc3RlbmVyIHx8IGZuLmxpc3RlbmVyID09PSBsaXN0ZW5lcikge1xuICAgICAgICAvLyBSZW1vdmVzIHRoZSBnaXZlbiBsaXN0ZW5lci5cbiAgICAgICAgbGlzdGVuZXJzLnNwbGljZShpLCAxKTtcbiAgICAgIH1cbiAgICB9KTtcblxuICAgIC8vIFJlbW92ZXMgYW4gZW1wdHkgZXZlbnQgY29sbGVjdGlvbi5cbiAgICBpZiAobGlzdGVuZXJzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgZGVsZXRlIHRoaXMuX2V2ZW50Q29sbGVjdGlvbltldmVudF07XG4gICAgfVxuXG4gICAgcmV0dXJuIHRoaXM7XG4gIH07XG5cbiAgLyoqXG4gICAqIEV4ZWN1dGUgZWFjaCBpdGVtIGluIHRoZSBsaXN0ZW5lciBjb2xsZWN0aW9uIGluIG9yZGVyIHdpdGggdGhlIHNwZWNpZmllZCBkYXRhLlxuICAgKiBAbWVtYmVyb2YhIEVtaXR0ZXIucHJvdG90eXBlXG4gICAqIEBmdW5jdGlvblxuICAgKiBAcGFyYW0ge1N0cmluZ30gZXZlbnQgLSBUaGUgbmFtZSBvZiB0aGUgZXZlbnQgeW91IHdhbnQgdG8gZW1pdC5cbiAgICogQHBhcmFtIHsuLi5PYmplY3R9IGRhdGEgLSBEYXRhIHRvIHBhc3MgdG8gdGhlIGxpc3RlbmVycy5cbiAgICogQHJldHVybnMge09iamVjdH0gUmV0dXJucyBhbiBpbnN0YW5jZSBvZiBFbWl0dGVyLlxuICAgKiBAZXhhbXBsZVxuICAgKiAvLyBFbWl0cyB0aGUgXCJmb29cIiBldmVudCB3aXRoICdwYXJhbTEnIGFuZCAncGFyYW0yJyBhcyBhcmd1bWVudHMuXG4gICAqIGVtaXR0ZXIuZW1pdCgnZm9vJywgJ3BhcmFtMScsICdwYXJhbTInKTtcbiAgICovXG5cbiAgRW1pdHRlci5wcm90b3R5cGUuZW1pdCA9IGZ1bmN0aW9uIGVtaXQoZXZlbnQpIHtcbiAgICB2YXIgX3RoaXMgPSB0aGlzO1xuXG4gICAgZm9yICh2YXIgX2xlbiA9IGFyZ3VtZW50cy5sZW5ndGgsIGFyZ3MgPSBBcnJheShfbGVuID4gMSA/IF9sZW4gLSAxIDogMCksIF9rZXkgPSAxOyBfa2V5IDwgX2xlbjsgX2tleSsrKSB7XG4gICAgICBhcmdzW19rZXkgLSAxXSA9IGFyZ3VtZW50c1tfa2V5XTtcbiAgICB9XG5cbiAgICB2YXIgbGlzdGVuZXJzID0gdW5kZWZpbmVkO1xuXG4gICAgLy8gRGVmaW5lcyBsaXN0ZW5lcnMgdmFsdWUuXG4gICAgaWYgKCF0aGlzLl9ldmVudENvbGxlY3Rpb24gfHwgIShsaXN0ZW5lcnMgPSB0aGlzLl9ldmVudENvbGxlY3Rpb25bZXZlbnRdKSkge1xuICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLy8gQ2xvbmUgbGlzdGVuZXJzXG4gICAgbGlzdGVuZXJzID0gbGlzdGVuZXJzLnNsaWNlKDApO1xuXG4gICAgbGlzdGVuZXJzLmZvckVhY2goZnVuY3Rpb24gKGZuKSB7XG4gICAgICByZXR1cm4gZm4uYXBwbHkoX3RoaXMsIGFyZ3MpO1xuICAgIH0pO1xuXG4gICAgcmV0dXJuIHRoaXM7XG4gIH07XG5cbiAgcmV0dXJuIEVtaXR0ZXI7XG59KSgpO1xuXG4vKipcbiAqIEV4cG9ydHMgRW1pdHRlclxuICovXG5leHBvcnRzW1wiZGVmYXVsdFwiXSA9IEVtaXR0ZXI7XG5tb2R1bGUuZXhwb3J0cyA9IGV4cG9ydHNbXCJkZWZhdWx0XCJdOyJdfQ==\n"
  },
  {
    "path": "app_frontend/static/plugin/Swiper-3.3.1/.gitignore",
    "content": ".DS_Store\nnode_modules\nbuild\n*.log\n\n.versions\n"
  },
  {
    "path": "app_frontend/static/plugin/Swiper-3.3.1/.jshintrc",
    "content": "{\n  \"node\"         : true,\n  \"browser\"      : true,\n  \"esnext\"       : true,\n  \"bitwise\"      : false,\n  \"curly\"        : false,\n  \"eqeqeq\"       : true,\n  \"eqnull\"       : true,\n  \"immed\"        : true,\n  \"newcap\"       : true,\n  \"noarg\"        : true,\n  \"undef\"        : true,\n  \"strict\"       : true,\n  \"smarttabs\"    : true,\n  \"quotmark\"     : \"single\",\n  \"indent\"       : 4,\n  \"globals\":{\n    \"document\": true,\n    \"define\": true,\n    \"Swiper\": true,\n    \"window\": true,\n    \"HTMLElement\": true,\n    \"XMLSerializer\": true,\n    \"Image\": true,\n    \"WheelEvent\": true,\n    \"navigator\": true,\n    \"DocumentTouch\": true,\n    \"Modernizr\": true,\n    \"WebKitCSSMatrix\": true,\n    \"s\": true,\n    \"jQuery\": true,\n    \"Dom7\": true,\n    \"$\": true\n  }\n}\n"
  },
  {
    "path": "app_frontend/static/plugin/Swiper-3.3.1/.travis.yml",
    "content": "language: node_js\nnode_js:\n  - \"0.10\"\nbefore_script:\n  - npm install --global gulp"
  },
  {
    "path": "app_frontend/static/plugin/Swiper-3.3.1/CHANGELOG.md",
    "content": "# Change Log\n\n## Swiper 3.3.1 - Released on February 7, 2016\n  * New `uniqueNavElements` parameter. If enabled (by default) and navigation elements' parameters passed as the string (like `.pagination`) then Swiper will look for such elements through child elements first. Applies for pagination, prev/next buttons and scrollbar\n  * New `onPaginationRendered` callback. Will be fired after pagination elements generated and added to DOM\n  * New `.reLoop()` method, which combines `.destroyLoop()` + `.createLoop()` methods with additional positioning fixes. Useful to call after you have changed `slidesPerView` parameter, it will dynamically recreate duplicated slides required for loop\n  * Fixed not working mousewheel control in IE 11\n  * Fixed issue with lazy loading images not being recalculated after window resize\n  * Fixed issues when using loop with breakpoints changing `slidesPerView/Group` parameters\n  * Numerous minor fixes\n\n## Swiper 3.3.0 - Released on January 10, 2016\n  * New 3D Flip effect. Can be enabled with `effect: 'flip' parameter\n  * New types of pagination with new parameters:\n    * `paginationType` - type of pagination. Can be `'bullets'` (default) or `'fraction'` or `'progress'` or `'custom'`\n    * `paginationFractionRender(swiper, currentClass, totalClass)` - custom function to render \"fraction\" type pagination\n    * `paginationProgressRender(swiper, progressbarClass)` - custom function to render \"progress\" type pagination\n    * `paginationCustomRender(swiper, current, total)` - custom function to render \"custom\" type pagination\n  * New `lazyLoadingInPrevNextAmount` parameter allows to lazy load images in specified amount of next/prev slides\n  * New `autoplayStopOnLast` parameter (`true` by default) tells to autoplay should it stop on last slide or start from first slide\n  * New `onAutoplay(swiper)` callback\n  * Minor fixes\n\n## Swiper 3.2.7 - Released on December 7, 2015\n  * Fixed issue with using HTMLElements for next/prevButton parameters with breakpoints\n  * Fixed issue with not working Auto Height when using Controller\n\n## Swiper 3.2.6 - Released on November 28, 2015\n  * Fixed issue in RTL layout using `mousewheelControl`\n  * Fixed issue in RTL layout using Parallax\n\n## Swiper 3.2.5 - Released on November 21, 2015\n  * New \"Auto Height\" mode when container/wrapper adopts to the height of currently active slide. Can be enabled with `autoHeight: true` parameter\n  * Fixed issue with break points in FireFox\n  * Fixed issue with wrong slides position when using effects\n  * Fixed issue with none-updated scroll bar after using `setWrapperTranslate`\n  * Minor fixes\n\n## Swiper 3.2.0 - Released on November 7, 2015\n  * Added responsive breakpoints support using new `breakpoints` parameter. Now you can specify different `slidesPerView` and other similar parameters for different sizes:\n    ```js\n    slidesPerView: 5,\n    spaceBetween: 50,\n    breakpoints: {\n      1024: {\n        slidesPerView: 4,\n        spaceBetween: 40\n      },\n      768: {\n        slidesPerView: 3,\n        spaceBetween: 30\n      },\n      320: {\n        slidesPerView: 1,\n        spaceBetween: 10\n      }\n    }\n    ```\n\n  * New callbacks: `onSlideNextStart`, `onSlideNextEnd`, `onSlidePrevStart`, `onSlidePrevEnd`\n  * Added Meteor package `meteor add nolimits4web:swiper`\n  * Fixed issue with mouse touchMove/End callbacks firing all the time\n  * Fixed issue with mousewheel in Chrome\n  * Minor fixes\n\n## Swiper 3.1.7 - Released on October 10, 2015\n  * Fixed issue with lazy loading trying to download `undefined`-src images\n  * Fixed lazy loading on slides using jQuery version\n  * Fixed issue with `slideToClickedSlide` with `loop` and `centeredSlides`\n  * Fixed issue with wrong slides fill when number of slides less than `slidesPerView * slidesPerColumn` with `slidesPerColumnFill: 'row'`\n  * Minor fixes\n\n## Swiper 3.1.5 - Released on September 28, 2015\n  * Added support for images `srcset` with lazy loading using `data-srcset` attribute\n  * Fixed new Chrome errors with `WebkitCSSMatrix`\n  * Fixed issue with `slideToClickedSlide` with `loop` and `centeredSlides`\n  * New `freeModeMinimumVelocity` parameter to set minimum required touch velocity to trigger free mode momentum\n  * Ability to make the Scrollbar draggable using new paramaters:\n    * `scrollbarDraggable` - (boolean) by default is `false`. Allows to enable draggable scrollbar\n    * `scrollbarSnapOnRelease` - (boolean) by default is `false`. Control slider snap on scrollbar release\n  * Minor fixes\n\n## Swiper 3.1.2 - Released on August 22, 2015\n  * Fixed issues with loop and mousewheel when swiper stopped on last slide\n  * Imporved mouse wheel behavior in latest Chrome\n  * Fixed issue with `slidesPerView: 'auto'` and enabled `loop:true` mode to set `loopedSlides` to the amount of slides by default (if not specified)\n  * New `mousewheelSensitivity: 1` parameter allows to tweak mouse wheel sensitivity\n  * Fixed issue with updating swiper when swiping is locked (with `allowSwipeToNext`/`allowSwipeToPrev`)\n  * Fixed issue with wrong calculating of \"visible\" slides with enabled `centeredSlides`\n  * CSS fixes for 3D effects\n  * New options to release Swiper events for swipe-to-go-back work in iOS UIWebView with two options:\n    * `iOSEdgeSwipeDetection` (by default is `false`) - enable ios edge detection and release Swiper events\n    * `iOSEdgeSwipeThreshold` (default value is `20`) - area in `px` from left edge of screen to release events\n  * Improved source maps\n  * Minor fixes\n\n## Swiper 3.1.0 - Released on July 14, 2015\n  * Accessibility (a11y)\n    * Fixed issue with wrong buttons labels\n    * Added support for pagination bullets\n    * New accessibility parameter for pagination label `paginationBulletMessage: 'Go to slide {{index}}'`\n  * Controler\n    * New parameter `controlBy` which can be 'slide' (by default) or 'container'. Defines a way how to control another slider: slide by slide or depending on all slides/container (like before)\n    * Now controllers in `controlBy: 'slide'` (default) mode will respect grid of each other\n  * Pagination\n    * New `paginationElement` parameter defines which HTML tag will be use to represent single pagination bullet. By default it is `span`\n  * New `roundLengths` parameter (by default is `false`) to round values of slides width and height to prevent blurry texts on usual resolution screens\n  * New `slidesOffsetBefore: 0` and `slidesOffsetAfter: 0` (in px) parameters to add additional slide offset within a container\n  * Correct calculation for slides size when use CSS padding on `.swiper-container`\n  * Fixed issue with not working onResize handler when swipes are locked\n  * Fixed issue with \"jumping\" effect when you disable `onlyExternal` during touchmove\n  * Fixed issue when slider goes to previos slide from last slide after window resize\n  * Added new `swiper.jquery.umd.js` version for the environment where both Swiper and jQuery included as modules\n  * Minor fixes\n\n## Swiper 3.0.8 - Released on June 14, 2015\n  * Fixed issue with wrong active index and callbacks in Fade effect\n  * New mousewheel parameters:\n    * `mousewheelReleaseOnEdges` - will release mousewheel event and allow page scrolling when swiper is on edge positions (in the beginning or in the end)\n    * `mousewheelInvert` - option to invert mousewheel slides\n  * Fixed issue with lazy loading in next slides when `slidesPerView` > 1\n  * Fixed issue with resistance bounds when swiping is locked\n  * Fixed issue with wrong slides order in multi-row mode (when `slidesPerColumn` > 1)\n  * Fixed issue with not working keyboard control in RTL mode\n  * Fixed issue with nested fade-effect swipers\n  * Minor fixes\n\n## Swiper 3.0.7 - Released on April 25, 2015\n  * New `width` and `height` parameters to force Swiper size, useful when it is hidden on intialization\n  * Better support for \"Scroll Container\". So now Swiper can be used as a scroll container with one single \"scrollable\"/\"swipeable\" slide\n  * Added lazy loading for background images with `data-background` attribute on required elements\n  * New \"Sticky Free Mode\" (with `freeModeSticky` parameter) which will snap to slides positions in free mode\n  * Fixed issues with lazy loading  \n  * Fixed slide removing when loop mode is enabled\n  * Fixed issues with Autoplay and Fade effect\n  * Minor fixes\n\n## Swiper 3.0.6 - Released on March 27, 2015\n  * Fixed sometimes wrong slides position when using \"Fade\" effect\n  * `.destroy(deleteInstance, cleanupStyles)` method now has second `cleanupStyles` argument, when passed - all custom styles will be removed from slides, wrapper and container. Useful if you need to destroy Swiper and to init again with new options or in different direction\n  * Minor fixes\n\n## Swiper 3.0.5 - Released on March 21, 2015\n  * New Keyboard accessibility module to provide foucsable navigation buttons and basic ARIA for screen readers with new parameters:\n    * `a11y: false` - enable accessibility\n    * `prevSlideMessage: 'Previous slide'` - message for screen readers for previous button\n    * `nextSlideMessage: 'Next slide'` - message for screen readers for next button\n    * `firstSlideMessage: 'This is the first slide'` - message for screen readers for previous button when swiper is on first slide\n    * `lastSlideMessage: 'This is the last slide'` - message for screen readers for next button when swiper is on last slide\n  * New Emitter module. It allows to work with callbacks like with events, even adding them after initialization with new methods:\n    * `.on(event, handler)` - add event/callback\n    * `.off(event, handler)` - remove this event/callback\n    * `.once(event, handler)` - add event/callback that will be executed only once\n  * Plugins API is back. It allows to write custom Swiper plugins\n  * Better support for browser that don't support flexbox layout\n  * New parameter `setWrapperSize` (be default it is `false`) to provide better compatibility with browser without flexbox support. Enabled this option and plugin will set width/height on swiper wrapper equal to total size of all slides\n  * New `virtualTranslate` parameter. When it is enabled swiper will be operated as usual except it will not move. Useful when you may need to create custom slide transition\n  * Added support for multiple Pagination containers\n  * Fixed `onLazyImage...` callbacks\n  * Fixed issue with not accessible links inside of Slides on Android < 4.4\n  * Fixed pagination bullets behavior in loop mode with specified `slidesPerGroup`\n  * Fixed issues with clicks on IE 10+ touch devices\n  * Fixed issues with Coverflow support on IE 10+\n  * Hashnav now will update document hash after transition to prevent browsers UI lags, not in the beginning like before\n  * Super basic support for IE 9 with swiper.jquery version. No animation and transitions, but basic stuff like switching slides/pagination/scrollbars works\n  \n\n## Swiper 3.0.4 - Released on March 6, 2015\n  * New Images Lazy Load component\n    * With new parameters `lazyLoading`, `lazyLoadingInPrevNext`, `lazyLoadingOnTransitionStart` (all disabled by default)\n    * With new callbacks `onLazyImageLoad` and `onLazyImageReady`\n  * `updateOnImages` ready split into 2 parameters:\n    * `preloadImages` (by default is true) - to preload all images on swiper init\n    * `updateOnImages` (by default is true) - update swiper when all images loaded\n  * Fixed issues with touchmove on fouces form elements\n  * New `onObserverUpdate` callback function to be called after updates by ovserver\n  * Fixed issue with not working inputs with keyboard control for jQuery version\n  * New `paginationBulletRender` parameter that accepts function which allow custom pagination elements layout\n  * Hash Navigation will run callback dpending on `runCallbacksOnInit` parameter\n  * `watchVisibility` parameter renamed to `watchSlidesVisibility`\n\n## Swiper 3.0.3 - Released on March 1, 2015\n  * Fixed issue with not firing onSlideChangeEnd callback after calling .slideTo with\nrunCallbacks=false\n  * Fixed values of isBeginning/isEnd when there is only one slide\n  * New `crossFade` option for fade effect\n  * Improved support for devices with both touch and mouse inputs, not yet on IE\n  * Fixed not correctly working mousewheel and keyobard control in swiper.jquery version\n  * New parallax module for transitions with parallax effects on internal elements\n  * Improved .update and .onResize methods\n  * Minor fixes\n\n## Swiper 3.0.2 - Released on February 22, 2015\n  * Fixed issue with keyboard events not cleaned up with Swiper.destroy\n  * Encoded inline SVG images for IE support\n  * New callbacks\n    * onInit (swiper)\n    * onTouchMoveOpposite (swiper, e)\n  * Fixed free mode momentum in RTL layout\n  * `.update` method improved to fully cover what `onResize` do for full and correct update\n  * Exposed `swiper.touches` object with the following properties: `startX`, `startY`, `currentX`, `currentY`, `diff`\n  * New methods to remove slides\n    * `.removeSlide(index)` or `.removeSlide([indexes])` - to remove selected slides\n    * `.removeAllSlides()` - to remove all slides\n\n## Swiper 3.0.1 - Released on February 13, 2015\n  * Fixed issue with navigation buttons in Firefox in loop mode\n  * Fixed issue with image dragging in IE 10+\n\n## Swiper 3.0.0 - Released on February 11, 2015\n  * Initial release of all new Swiper 3\n  * Removed features\n    * Dropped support for old browsers. Now it is compatible with:\n      * iOS 7+\n      * Android 4+ (multirow mode only for Android 4.4+)\n      * Latest Chrome, Safari, Firefox and Opera desktop browsers\n      * WP 8+, IE 10+ (3D effects may not work correctly on IE because of wrong nested 3D transform support)\n    * Scroll Container. Removed in favor of pure CSS `overflow: auto` with `-webkit-overflow-scrolling: touch`\n  * New features\n    * Swiper now uses modern flexbox layout, which by itself give more features and advantages\n    * Such Swiper 2.x plugins as Hash Navigation, Smooth Progress, 3D Flow and Scrollbar are now incoroporated into Swiper 3.x core\n    * Full RTL support\n    * Built-in navigation buttons/arrows\n    * Controller. Now one Swiper could be controlled (or control itself) by another Swiper\n    * Multi row slides layout with `slidesPerColumn` option\n    * Better support for nested Swipers, now it is possible to use same-direction nested Swipers, like horizontal in horizontal\n    * Space between slides\n    * New transition effects: 3D Coverflow, 3D Cube and Fade transitions\n    * Slides are `border-box` now, so it is possible to use borders and paddings directly on slides\n    * Auto layout mode (`slidesPerView: 'auto'`) now gives more freedom, you can even specify slides sizes in % and use margins on them\n    * Mutation Observers. If enabled, Swiper will watch for changes in Dom and update its layout automatically\n    * Better clicks prevention during swiping\n  * Many of API methods, parameters and callbacks are changed\n  * Added a bit lightweight jQuery/Zepto version of Swiper that can be used if you use jQuery/Zepto in your project\n\n\n"
  },
  {
    "path": "app_frontend/static/plugin/Swiper-3.3.1/LICENSE",
    "content": "The MIT License (MIT)\n\nCopyright (c) 2014 Vladimir Kharlampidi\n\nPermission is hereby granted, free of charge, to any person obtaining a copy of\nthis software and associated documentation files (the \"Software\"), to deal in\nthe Software without restriction, including without limitation the rights to\nuse, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of\nthe Software, and to permit persons to whom the Software is furnished to do so,\nsubject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS\nFOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR\nCOPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER\nIN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN\nCONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n"
  },
  {
    "path": "app_frontend/static/plugin/Swiper-3.3.1/README.md",
    "content": "[![Join the chat at https://gitter.im/nolimits4web/Swiper](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/nolimits4web/Swiper?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)\n[![Build Status](https://travis-ci.org/nolimits4web/Swiper.svg?branch=master)](https://travis-ci.org/nolimits4web/Swiper)\n[![devDependency Status](https://david-dm.org/nolimits4web/swiper/dev-status.svg)](https://david-dm.org/nolimits4web/swiper#info=devDependencies)\n[![Flattr this git repo](http://api.flattr.com/button/flattr-badge-large.png)](https://flattr.com/submit/auto?user_id=nolimits4web&url=https://github.com/nolimits4web/swiper/&title=Framework7&language=JavaScript&tags=github&category=software)\n\nSwiper\n==========\n\nSwiper - is the free and most modern mobile touch slider with hardware accelerated transitions and amazing native behavior. It is intended to be used in mobile websites, mobile web apps, and mobile native/hybrid apps. Designed mostly for iOS, but also works great on latest Android, Windows Phone 8 and modern Desktop browsers\n\nSwiper is not compatible with all platforms, it is a modern touch slider which is focused only on modern apps/platforms to bring the best experience and simplicity.\n\n# Getting Started\n  * [Getting Started Guide](http://www.idangero.us/swiper/get-started/)\n  * [API](http://www.idangero.us/swiper/api/)\n  * [Demos](http://www.idangero.us/swiper/demos/)\n  * [Forum](http://www.idangero.us/swiper/forum/)\n\n# Dist / Build\n\nOn production use files (JS and CSS) only from `dist/` folder, there will be the most stable versions, `build/` folder is only for development purpose\n\n### Build\n\nSwiper uses `gulp` to build a development (build) and dist versions.\n\nFirst you need to have `gulp-cli` which you should install globally.\n\n```\n$ npm install --global gulp\n```\n\nThen install all dependencies, in repo's root:\n\n```\n$ npm install\n```\n\nAnd build development version of Swiper:\n```\n$ gulp build\n```\n\nThe result is available in `build/` folder.\n\n### Dist/Release\n\nAfter you have made build:\n\n```\n$ gulp dist\n```\n\nDistributable version will available in `dist/` folder.\n\n# Contributing\n\nAll changes should be commited to `src/` files. Swiper uses LESS for CSS compliations, and concatenated JS files (look at gulpfile.js for concat files order)\n\nSwiper 2.x.x\n==========\n\nIf you still using Swiper 2.x.x or you need old browsers support, you may find it in [Swiper2 Branch](https://github.com/nolimits4web/Swiper/tree/Swiper2)\n* [Download Latest Swiper 2.7.6](https://github.com/nolimits4web/Swiper/archive/v2.7.6.zip)\n* [Source Files](https://github.com/nolimits4web/Swiper/tree/Swiper2/src)\n* [API](https://github.com/nolimits4web/Swiper/blob/Swiper2/API.md)"
  },
  {
    "path": "app_frontend/static/plugin/Swiper-3.3.1/bower.json",
    "content": "{\n  \"name\": \"Swiper\",\n  \"repository\": {\n    \"type\": \"git\",\n    \"url\": \"https://github.com/nolimits4web/Swiper.git\"\n  },\n  \"description\": \"Most modern mobile touch slider and framework with hardware accelerated transitions\",\n  \"version\": \"3.3.1\",\n  \"author\": \"Vladimir Kharlampidi\",\n  \"homepage\": \"http://www.idangero.us/swiper/\",\n  \"keywords\": [\"swiper\", \"swipe\", \"slider\", \"touch\", \"ios\", \"mobile\", \"cordova\", \"phonegap\", \"app\", \"framework\", \"carousel\", \"gallery\"],\n  \"dependencies\": {\n  },\n  \"scripts\": [\n    \"dist/js/swiper.js\"\n  ],\n  \"main\": [\n    \"dist/js/swiper.js\",\n    \"dist/css/swiper.css\"\n  ],\n  \"styles\": [\n    \"dist/css/swiper.css\"\n  ],\n  \"license\": [\"MIT\"],\n  \"dependencies\": {},\n  \"ignore\": [\n    \".*\",\n    \"demos\",\n    \"gulpfile\",\n    \"build\",\n    \"node_modules\",\n    \"playground\",\n    \"package.json\"\n  ]\n}"
  },
  {
    "path": "app_frontend/static/plugin/Swiper-3.3.1/component.json",
    "content": "{\n  \"name\": \"swiper\",\n  \"repo\": \"https://github.com/nolimits4web/Swiper.git\",\n  \"description\": \"Most modern mobile touch slider and framework with hardware accelerated transitions\",\n  \"version\": \"3.3.1\",\n  \"keywords\": [\"swiper\", \"swipe\", \"slider\", \"touch\", \"ios\", \"mobile\", \"cordova\", \"phonegap\", \"app\", \"framework\", \"carousel\", \"gallery\"],\n  \"dependencies\": {\n  },\n  \"scripts\": [\n    \"dist/js/swiper.js\"\n  ],\n  \"main\": \"dist/js/swiper.js\",\n  \"styles\": [\n    \"dist/css/swiper.css\"\n  ],\n  \"license\": [\"MIT\"]\n}\n"
  },
  {
    "path": "app_frontend/static/plugin/Swiper-3.3.1/demos/01-default.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n    <meta charset=\"utf-8\">\n    <title>Swiper demo</title>\n    <!-- Link Swiper's CSS -->\n    <link rel=\"stylesheet\" href=\"../dist/css/swiper.min.css\">\n\n    <!-- Demo styles -->\n    <style>\n    body {\n        background: #eee;\n        font-family: Helvetica Neue, Helvetica, Arial, sans-serif;\n        font-size: 14px;\n        color:#000;\n        margin: 0;\n        padding: 0;\n    }\n    .swiper-container {\n        width: 500px;\n        height: 300px;\n        margin: 20px auto;\n    }\n    .swiper-slide {\n        text-align: center;\n        font-size: 18px;\n        background: #fff;\n        \n        /* Center slide text vertically */\n        display: -webkit-box;\n        display: -ms-flexbox;\n        display: -webkit-flex;\n        display: flex;\n        -webkit-box-pack: center;\n        -ms-flex-pack: center;\n        -webkit-justify-content: center;\n        justify-content: center;\n        -webkit-box-align: center;\n        -ms-flex-align: center;\n        -webkit-align-items: center;\n        align-items: center;\n    }\n    </style>\n</head>\n<body>\n    <!-- Swiper -->\n    <div class=\"swiper-container\">\n        <div class=\"swiper-wrapper\">\n            <div class=\"swiper-slide\">Slide 1</div>\n            <div class=\"swiper-slide\">Slide 2</div>\n            <div class=\"swiper-slide\">Slide 3</div>\n            <div class=\"swiper-slide\">Slide 4</div>\n            <div class=\"swiper-slide\">Slide 5</div>\n            <div class=\"swiper-slide\">Slide 6</div>\n            <div class=\"swiper-slide\">Slide 7</div>\n            <div class=\"swiper-slide\">Slide 8</div>\n            <div class=\"swiper-slide\">Slide 9</div>\n            <div class=\"swiper-slide\">Slide 10</div>\n        </div>\n    </div>\n\n    <!-- Swiper JS -->\n    <script src=\"../dist/js/swiper.min.js\"></script>\n\n    <!-- Initialize Swiper -->\n    <script>\n    var swiper = new Swiper('.swiper-container');\n    </script>\n</body>\n</html>"
  },
  {
    "path": "app_frontend/static/plugin/Swiper-3.3.1/demos/02-responsive.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n    <meta charset=\"utf-8\">\n    <title>Swiper demo</title>\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1, minimum-scale=1, maximum-scale=1\">\n\n    <!-- Link Swiper's CSS -->\n    <link rel=\"stylesheet\" href=\"../dist/css/swiper.min.css\">\n\n    <!-- Demo styles -->\n    <style>\n    html, body {\n        position: relative;\n        height: 100%;\n    }\n    body {\n        background: #eee;\n        font-family: Helvetica Neue, Helvetica, Arial, sans-serif;\n        font-size: 14px;\n        color:#000;\n        margin: 0;\n        padding: 0;\n    }\n    .swiper-container {\n        width: 100%;\n        height: 100%;\n    }\n    .swiper-slide {\n        text-align: center;\n        font-size: 18px;\n        background: #fff;\n\n        /* Center slide text vertically */\n        display: -webkit-box;\n        display: -ms-flexbox;\n        display: -webkit-flex;\n        display: flex;\n        -webkit-box-pack: center;\n        -ms-flex-pack: center;\n        -webkit-justify-content: center;\n        justify-content: center;\n        -webkit-box-align: center;\n        -ms-flex-align: center;\n        -webkit-align-items: center;\n        align-items: center;\n    }\n    </style>\n</head>\n<body>\n    <!-- Swiper -->\n    <div class=\"swiper-container\">\n        <div class=\"swiper-wrapper\">\n            <div class=\"swiper-slide\">Slide 1</div>\n            <div class=\"swiper-slide\">Slide 2</div>\n            <div class=\"swiper-slide\">Slide 3</div>\n            <div class=\"swiper-slide\">Slide 4</div>\n            <div class=\"swiper-slide\">Slide 5</div>\n            <div class=\"swiper-slide\">Slide 6</div>\n            <div class=\"swiper-slide\">Slide 7</div>\n            <div class=\"swiper-slide\">Slide 8</div>\n            <div class=\"swiper-slide\">Slide 9</div>\n            <div class=\"swiper-slide\">Slide 10</div>\n        </div>\n        <!-- Add Pagination -->\n        <div class=\"swiper-pagination\"></div>\n    </div>\n\n    <!-- Swiper JS -->\n    <script src=\"../dist/js/swiper.min.js\"></script>\n\n    <!-- Initialize Swiper -->\n    <script>\n    var swiper = new Swiper('.swiper-container', {\n        pagination: '.swiper-pagination',\n        paginationClickable: true\n    });\n    </script>\n</body>\n</html>"
  },
  {
    "path": "app_frontend/static/plugin/Swiper-3.3.1/demos/03-vertical.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n    <meta charset=\"utf-8\">\n    <title>Swiper demo</title>\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1, minimum-scale=1, maximum-scale=1\">\n\n    <!-- Link Swiper's CSS -->\n    <link rel=\"stylesheet\" href=\"../dist/css/swiper.min.css\">\n\n    <!-- Demo styles -->\n    <style>\n    html, body {\n        position: relative;\n        height: 100%;\n    }\n    body {\n        background: #eee;\n        font-family: Helvetica Neue, Helvetica, Arial, sans-serif;\n        font-size: 14px;\n        color:#000;\n        margin: 0;\n        padding: 0;\n    }\n    .swiper-container {\n        width: 100%;\n        height: 100%;\n    }\n    .swiper-slide {\n        text-align: center;\n        font-size: 18px;\n        background: #fff;\n\n        /* Center slide text vertically */\n        display: -webkit-box;\n        display: -ms-flexbox;\n        display: -webkit-flex;\n        display: flex;\n        -webkit-box-pack: center;\n        -ms-flex-pack: center;\n        -webkit-justify-content: center;\n        justify-content: center;\n        -webkit-box-align: center;\n        -ms-flex-align: center;\n        -webkit-align-items: center;\n        align-items: center;\n    }\n    </style>\n</head>\n<body>\n    <!-- Swiper -->\n    <div class=\"swiper-container\">\n        <div class=\"swiper-wrapper\">\n            <div class=\"swiper-slide\">Slide 1</div>\n            <div class=\"swiper-slide\">Slide 2</div>\n            <div class=\"swiper-slide\">Slide 3</div>\n            <div class=\"swiper-slide\">Slide 4</div>\n            <div class=\"swiper-slide\">Slide 5</div>\n            <div class=\"swiper-slide\">Slide 6</div>\n            <div class=\"swiper-slide\">Slide 7</div>\n            <div class=\"swiper-slide\">Slide 8</div>\n            <div class=\"swiper-slide\">Slide 9</div>\n            <div class=\"swiper-slide\">Slide 10</div>\n        </div>\n        <!-- Add Pagination -->\n        <div class=\"swiper-pagination\"></div>\n    </div>\n\n    <!-- Swiper JS -->\n    <script src=\"../dist/js/swiper.min.js\"></script>\n\n    <!-- Initialize Swiper -->\n    <script>\n    var swiper = new Swiper('.swiper-container', {\n        pagination: '.swiper-pagination',\n        paginationClickable: true,\n        direction: 'vertical'\n    });\n    </script>\n</body>\n</html>"
  },
  {
    "path": "app_frontend/static/plugin/Swiper-3.3.1/demos/04-space-between.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n    <meta charset=\"utf-8\">\n    <title>Swiper demo</title>\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1, minimum-scale=1, maximum-scale=1\">\n\n    <!-- Link Swiper's CSS -->\n    <link rel=\"stylesheet\" href=\"../dist/css/swiper.min.css\">\n\n    <!-- Demo styles -->\n    <style>\n    body {\n        background: #eee;\n        font-family: Helvetica Neue, Helvetica, Arial, sans-serif;\n        font-size: 14px;\n        color:#000;\n        margin: 0;\n        padding: 0;\n    }\n    .swiper-container {\n        width: 500px;\n        height: 300px;\n        margin: 20px auto;\n    }\n    .swiper-slide {\n        text-align: center;\n        font-size: 18px;\n        background: #fff;\n\n        /* Center slide text vertically */\n        display: -webkit-box;\n        display: -ms-flexbox;\n        display: -webkit-flex;\n        display: flex;\n        -webkit-box-pack: center;\n        -ms-flex-pack: center;\n        -webkit-justify-content: center;\n        justify-content: center;\n        -webkit-box-align: center;\n        -ms-flex-align: center;\n        -webkit-align-items: center;\n        align-items: center;\n    }\n    </style>\n</head>\n<body>\n    <!-- Swiper -->\n    <div class=\"swiper-container\">\n        <div class=\"swiper-wrapper\">\n            <div class=\"swiper-slide\">Slide 1</div>\n            <div class=\"swiper-slide\">Slide 2</div>\n            <div class=\"swiper-slide\">Slide 3</div>\n            <div class=\"swiper-slide\">Slide 4</div>\n            <div class=\"swiper-slide\">Slide 5</div>\n            <div class=\"swiper-slide\">Slide 6</div>\n            <div class=\"swiper-slide\">Slide 7</div>\n            <div class=\"swiper-slide\">Slide 8</div>\n            <div class=\"swiper-slide\">Slide 9</div>\n            <div class=\"swiper-slide\">Slide 10</div>\n        </div>\n        <!-- Add Pagination -->\n        <div class=\"swiper-pagination\"></div>\n    </div>\n\n    <!-- Swiper JS -->\n    <script src=\"../dist/js/swiper.min.js\"></script>\n\n    <!-- Initialize Swiper -->\n    <script>\n    var swiper = new Swiper('.swiper-container', {\n        pagination: '.swiper-pagination',\n        paginationClickable: true,\n        spaceBetween: 30,\n    });\n    </script>\n</body>\n</html>"
  },
  {
    "path": "app_frontend/static/plugin/Swiper-3.3.1/demos/05-slides-per-view.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n    <meta charset=\"utf-8\">\n    <title>Swiper demo</title>\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1, minimum-scale=1, maximum-scale=1\">\n\n    <!-- Link Swiper's CSS -->\n    <link rel=\"stylesheet\" href=\"../dist/css/swiper.min.css\">\n\n    <!-- Demo styles -->\n    <style>\n    html, body {\n        position: relative;\n        height: 100%;\n    }\n    body {\n        background: #eee;\n        font-family: Helvetica Neue, Helvetica, Arial, sans-serif;\n        font-size: 14px;\n        color:#000;\n        margin: 0;\n        padding: 0;\n    }\n    .swiper-container {\n        width: 100%;\n        height: 100%;\n    }\n    .swiper-slide {\n        text-align: center;\n        font-size: 18px;\n        background: #fff;\n        \n        /* Center slide text vertically */\n        display: -webkit-box;\n        display: -ms-flexbox;\n        display: -webkit-flex;\n        display: flex;\n        -webkit-box-pack: center;\n        -ms-flex-pack: center;\n        -webkit-justify-content: center;\n        justify-content: center;\n        -webkit-box-align: center;\n        -ms-flex-align: center;\n        -webkit-align-items: center;\n        align-items: center;\n    }\n    </style>\n</head>\n<body>\n    <!-- Swiper -->\n    <div class=\"swiper-container\">\n        <div class=\"swiper-wrapper\">\n            <div class=\"swiper-slide\">Slide 1</div>\n            <div class=\"swiper-slide\">Slide 2</div>\n            <div class=\"swiper-slide\">Slide 3</div>\n            <div class=\"swiper-slide\">Slide 4</div>\n            <div class=\"swiper-slide\">Slide 5</div>\n            <div class=\"swiper-slide\">Slide 6</div>\n            <div class=\"swiper-slide\">Slide 7</div>\n            <div class=\"swiper-slide\">Slide 8</div>\n            <div class=\"swiper-slide\">Slide 9</div>\n            <div class=\"swiper-slide\">Slide 10</div>\n        </div>\n        <!-- Add Pagination -->\n        <div class=\"swiper-pagination\"></div>\n    </div>\n\n    <!-- Swiper JS -->\n    <script src=\"../dist/js/swiper.min.js\"></script>\n\n    <!-- Initialize Swiper -->\n    <script>\n    var swiper = new Swiper('.swiper-container', {\n        pagination: '.swiper-pagination',\n        slidesPerView: 3,\n        paginationClickable: true,\n        spaceBetween: 30\n    });\n    </script>\n</body>\n</html>"
  },
  {
    "path": "app_frontend/static/plugin/Swiper-3.3.1/demos/06-slides-per-view-auto.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n    <meta charset=\"utf-8\">\n    <title>Swiper demo</title>\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1, minimum-scale=1, maximum-scale=1\">\n\n    <!-- Link Swiper's CSS -->\n    <link rel=\"stylesheet\" href=\"../dist/css/swiper.min.css\">\n\n    <!-- Demo styles -->\n    <style>\n    html, body {\n        position: relative;\n        height: 100%;\n    }\n    body {\n        background: #eee;\n        font-family: Helvetica Neue, Helvetica, Arial, sans-serif;\n        font-size: 14px;\n        color:#000;\n        margin: 0;\n        padding: 0;\n    }\n    .swiper-container {\n        width: 100%;\n        height: 100%;\n    }\n    .swiper-slide {\n        text-align: center;\n        font-size: 18px;\n        background: #fff;\n        width: 80%;\n\n        /* Center slide text vertically */\n        display: -webkit-box;\n        display: -ms-flexbox;\n        display: -webkit-flex;\n        display: flex;\n        -webkit-box-pack: center;\n        -ms-flex-pack: center;\n        -webkit-justify-content: center;\n        justify-content: center;\n        -webkit-box-align: center;\n        -ms-flex-align: center;\n        -webkit-align-items: center;\n        align-items: center;\n    }\n    .swiper-slide:nth-child(2n) {\n        width: 60%;\n    }\n    .swiper-slide:nth-child(3n) {\n        width: 40%;\n    }\n    </style>\n</head>\n<body>\n    <!-- Swiper -->\n    <div class=\"swiper-container\">\n        <div class=\"swiper-wrapper\">\n            <div class=\"swiper-slide\">Slide 1</div>\n            <div class=\"swiper-slide\">Slide 2</div>\n            <div class=\"swiper-slide\">Slide 3</div>\n            <div class=\"swiper-slide\">Slide 4</div>\n            <div class=\"swiper-slide\">Slide 5</div>\n            <div class=\"swiper-slide\">Slide 6</div>\n            <div class=\"swiper-slide\">Slide 7</div>\n            <div class=\"swiper-slide\">Slide 8</div>\n            <div class=\"swiper-slide\">Slide 9</div>\n            <div class=\"swiper-slide\">Slide 10</div>\n        </div>\n        <!-- Add Pagination -->\n        <div class=\"swiper-pagination\"></div>\n    </div>\n\n    <!-- Swiper JS -->\n    <script src=\"../dist/js/swiper.min.js\"></script>\n\n    <!-- Initialize Swiper -->\n    <script>\n    var swiper = new Swiper('.swiper-container', {\n        pagination: '.swiper-pagination',\n        slidesPerView: 'auto',\n        paginationClickable: true,\n        spaceBetween: 30\n    });\n    </script>\n</body>\n</html>"
  },
  {
    "path": "app_frontend/static/plugin/Swiper-3.3.1/demos/07-centered.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n    <meta charset=\"utf-8\">\n    <title>Swiper demo</title>\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1, minimum-scale=1, maximum-scale=1\">\n\n    <!-- Link Swiper's CSS -->\n    <link rel=\"stylesheet\" href=\"../dist/css/swiper.min.css\">\n\n    <!-- Demo styles -->\n    <style>\n    body {\n        background: #eee;\n        font-family: Helvetica Neue, Helvetica, Arial, sans-serif;\n        font-size: 14px;\n        color:#000;\n        margin: 0;\n        padding: 0;\n    }\n    .swiper-container {\n        width: 100%;\n        height: 300px;\n        margin: 20px auto;\n    }\n    .swiper-slide {\n        text-align: center;\n        font-size: 18px;\n        background: #fff;\n        width: 60%;\n\n        /* Center slide text vertically */\n        display: -webkit-box;\n        display: -ms-flexbox;\n        display: -webkit-flex;\n        display: flex;\n        -webkit-box-pack: center;\n        -ms-flex-pack: center;\n        -webkit-justify-content: center;\n        justify-content: center;\n        -webkit-box-align: center;\n        -ms-flex-align: center;\n        -webkit-align-items: center;\n        align-items: center;\n    }\n    .swiper-slide:nth-child(2n) {\n        width: 40%;\n    }\n    .swiper-slide:nth-child(3n) {\n        width: 20%;\n    }\n    </style>\n</head>\n<body>\n    <!-- Swiper -->\n    <div class=\"swiper-container\">\n        <div class=\"swiper-wrapper\">\n            <div class=\"swiper-slide\">Slide 1</div>\n            <div class=\"swiper-slide\">Slide 2</div>\n            <div class=\"swiper-slide\">Slide 3</div>\n            <div class=\"swiper-slide\">Slide 4</div>\n            <div class=\"swiper-slide\">Slide 5</div>\n            <div class=\"swiper-slide\">Slide 6</div>\n            <div class=\"swiper-slide\">Slide 7</div>\n            <div class=\"swiper-slide\">Slide 8</div>\n            <div class=\"swiper-slide\">Slide 9</div>\n            <div class=\"swiper-slide\">Slide 10</div>\n        </div>\n        <!-- Add Pagination -->\n        <div class=\"swiper-pagination\"></div>\n    </div>\n\n    <!-- Swiper JS -->\n    <script src=\"../dist/js/swiper.min.js\"></script>\n\n    <!-- Initialize Swiper -->\n    <script>\n    var swiper = new Swiper('.swiper-container', {\n        pagination: '.swiper-pagination',\n        slidesPerView: 4,\n        centeredSlides: true,\n        paginationClickable: true,\n        spaceBetween: 30\n    });\n    </script>\n</body>\n</html>"
  },
  {
    "path": "app_frontend/static/plugin/Swiper-3.3.1/demos/08-centered-auto.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n    <meta charset=\"utf-8\">\n    <title>Swiper demo</title>\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1, minimum-scale=1, maximum-scale=1\">\n\n    <!-- Link Swiper's CSS -->\n    <link rel=\"stylesheet\" href=\"../dist/css/swiper.min.css\">\n\n    <!-- Demo styles -->\n    <style>\n    body {\n        background: #eee;\n        font-family: Helvetica Neue, Helvetica, Arial, sans-serif;\n        font-size: 14px;\n        color:#000;\n        margin: 0;\n        padding: 0;\n    }\n    .swiper-container {\n        width: 100%;\n        height: 300px;\n        margin: 20px auto;\n    }\n    .swiper-slide {\n        text-align: center;\n        font-size: 18px;\n        background: #fff;\n        width: 60%;\n\n        /* Center slide text vertically */\n        display: -webkit-box;\n        display: -ms-flexbox;\n        display: -webkit-flex;\n        display: flex;\n        -webkit-box-pack: center;\n        -ms-flex-pack: center;\n        -webkit-justify-content: center;\n        justify-content: center;\n        -webkit-box-align: center;\n        -ms-flex-align: center;\n        -webkit-align-items: center;\n        align-items: center;\n    }\n    .swiper-slide:nth-child(2n) {\n        width: 40%;\n    }\n    .swiper-slide:nth-child(3n) {\n        width: 20%;\n    }\n    </style>\n</head>\n<body>\n    <!-- Swiper -->\n    <div class=\"swiper-container\">\n        <div class=\"swiper-wrapper\">\n            <div class=\"swiper-slide\">Slide 1</div>\n            <div class=\"swiper-slide\">Slide 2</div>\n            <div class=\"swiper-slide\">Slide 3</div>\n            <div class=\"swiper-slide\">Slide 4</div>\n            <div class=\"swiper-slide\">Slide 5</div>\n            <div class=\"swiper-slide\">Slide 6</div>\n            <div class=\"swiper-slide\">Slide 7</div>\n            <div class=\"swiper-slide\">Slide 8</div>\n            <div class=\"swiper-slide\">Slide 9</div>\n            <div class=\"swiper-slide\">Slide 10</div>\n        </div>\n        <!-- Add Pagination -->\n        <div class=\"swiper-pagination\"></div>\n    </div>\n\n    <!-- Swiper JS -->\n    <script src=\"../dist/js/swiper.min.js\"></script>\n\n    <!-- Initialize Swiper -->\n    <script>\n    var swiper = new Swiper('.swiper-container', {\n        pagination: '.swiper-pagination',\n        slidesPerView: 'auto',\n        centeredSlides: true,\n        paginationClickable: true,\n        spaceBetween: 30\n    });\n    </script>\n</body>\n</html>"
  },
  {
    "path": "app_frontend/static/plugin/Swiper-3.3.1/demos/09-freemode.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n    <meta charset=\"utf-8\">\n    <title>Swiper demo</title>\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1, minimum-scale=1, maximum-scale=1\">\n\n    <!-- Link Swiper's CSS -->\n    <link rel=\"stylesheet\" href=\"../dist/css/swiper.min.css\">\n\n    <!-- Demo styles -->\n    <style>\n    body {\n        background: #eee;\n        font-family: Helvetica Neue, Helvetica, Arial, sans-serif;\n        font-size: 14px;\n        color:#000;\n        margin: 0;\n        padding: 0;\n    }\n    .swiper-container {\n        width: 100%;\n        height: 300px;\n        margin: 20px auto;\n    }\n    .swiper-slide {\n        text-align: center;\n        font-size: 18px;\n        background: #fff;\n        \n        /* Center slide text vertically */\n        display: -webkit-box;\n        display: -ms-flexbox;\n        display: -webkit-flex;\n        display: flex;\n        -webkit-box-pack: center;\n        -ms-flex-pack: center;\n        -webkit-justify-content: center;\n        justify-content: center;\n        -webkit-box-align: center;\n        -ms-flex-align: center;\n        -webkit-align-items: center;\n        align-items: center;\n    }\n    </style>\n</head>\n<body>\n    <!-- Swiper -->\n    <div class=\"swiper-container\">\n        <div class=\"swiper-wrapper\">\n            <div class=\"swiper-slide\">Slide 1</div>\n            <div class=\"swiper-slide\">Slide 2</div>\n            <div class=\"swiper-slide\">Slide 3</div>\n            <div class=\"swiper-slide\">Slide 4</div>\n            <div class=\"swiper-slide\">Slide 5</div>\n            <div class=\"swiper-slide\">Slide 6</div>\n            <div class=\"swiper-slide\">Slide 7</div>\n            <div class=\"swiper-slide\">Slide 8</div>\n            <div class=\"swiper-slide\">Slide 9</div>\n            <div class=\"swiper-slide\">Slide 10</div>\n        </div>\n        <!-- Add Pagination -->\n        <div class=\"swiper-pagination\"></div>\n    </div>\n\n    <!-- Swiper JS -->\n    <script src=\"../dist/js/swiper.min.js\"></script>\n\n    <!-- Initialize Swiper -->\n    <script>\n    var swiper = new Swiper('.swiper-container', {\n        pagination: '.swiper-pagination',\n        slidesPerView: 3,\n        paginationClickable: true,\n        spaceBetween: 30,\n        freeMode: true\n    });\n    </script>\n</body>\n</html>"
  },
  {
    "path": "app_frontend/static/plugin/Swiper-3.3.1/demos/10-slides-per-column.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n    <meta charset=\"utf-8\">\n    <title>Swiper demo</title>\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1, minimum-scale=1, maximum-scale=1\">\n\n    <!-- Link Swiper's CSS -->\n    <link rel=\"stylesheet\" href=\"../dist/css/swiper.min.css\">\n\n    <!-- Demo styles -->\n    <style>\n    body {\n        background: #eee;\n        font-family: Helvetica Neue, Helvetica, Arial, sans-serif;\n        font-size: 14px;\n        color:#000;\n        margin: 0;\n        padding: 0;\n    }\n    .swiper-container {\n        width: 100%;\n        height: auto;\n        margin-left: auto;\n        margin-right: auto;\n    }\n    .swiper-slide {\n        text-align: center;\n        font-size: 18px;\n        background: #fff;\n        height: 200px;\n        \n        /* Center slide text vertically */\n        display: -webkit-box;\n        display: -ms-flexbox;\n        display: -webkit-flex;\n        display: flex;\n        -webkit-box-pack: center;\n        -ms-flex-pack: center;\n        -webkit-justify-content: center;\n        justify-content: center;\n        -webkit-box-align: center;\n        -ms-flex-align: center;\n        -webkit-align-items: center;\n        align-items: center;\n    }\n    </style>\n</head>\n<body>\n    <!-- Swiper -->\n    <div class=\"swiper-container\">\n        <div class=\"swiper-wrapper\">\n            <div class=\"swiper-slide\">Slide 1</div>\n            <div class=\"swiper-slide\">Slide 2</div>\n            <div class=\"swiper-slide\">Slide 3</div>\n            <div class=\"swiper-slide\">Slide 4</div>\n            <div class=\"swiper-slide\">Slide 5</div>\n            <div class=\"swiper-slide\">Slide 6</div>\n            <div class=\"swiper-slide\">Slide 7</div>\n            <div class=\"swiper-slide\">Slide 8</div>\n            <div class=\"swiper-slide\">Slide 9</div>\n            <div class=\"swiper-slide\">Slide 10</div>\n        </div>\n        <!-- Add Pagination -->\n        <div class=\"swiper-pagination\"></div>\n    </div>\n\n    <!-- Swiper JS -->\n    <script src=\"../dist/js/swiper.min.js\"></script>\n\n    <!-- Initialize Swiper -->\n    <script>\n    var swiper = new Swiper('.swiper-container', {\n        pagination: '.swiper-pagination',\n        slidesPerView: 3,\n        slidesPerColumn: 2,\n        paginationClickable: true,\n        spaceBetween: 30\n    });\n    </script>\n</body>\n</html>"
  },
  {
    "path": "app_frontend/static/plugin/Swiper-3.3.1/demos/11-nested.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n    <meta charset=\"utf-8\">\n    <title>Swiper demo</title>\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1, minimum-scale=1, maximum-scale=1\">\n\n    <!-- Link Swiper's CSS -->\n    <link rel=\"stylesheet\" href=\"../dist/css/swiper.min.css\">\n\n    <!-- Demo styles -->\n    <style>\n    html, body {\n        position: relative;\n        height: 100%;\n    }\n    body {\n        background: #eee;\n        font-family: Helvetica Neue, Helvetica, Arial, sans-serif;\n        font-size: 14px;\n        color:#000;\n        margin: 0;\n        padding: 0;\n    }\n    .swiper-container {\n        width: 100%;\n        height: 100%;\n    }\n    .swiper-slide {\n        text-align: center;\n        font-size: 18px;\n        background: #fff;\n\n        /* Center slide text vertically */\n        display: -webkit-box;\n        display: -ms-flexbox;\n        display: -webkit-flex;\n        display: flex;\n        -webkit-box-pack: center;\n        -ms-flex-pack: center;\n        -webkit-justify-content: center;\n        justify-content: center;\n        -webkit-box-align: center;\n        -ms-flex-align: center;\n        -webkit-align-items: center;\n        align-items: center;\n    }\n    .swiper-container-v {\n        background: #eee;\n    }\n    </style>\n</head>\n<body>\n    <!-- Swiper -->\n    <div class=\"swiper-container swiper-container-h\">\n        <div class=\"swiper-wrapper\">\n            <div class=\"swiper-slide\">Horizontal Slide 1</div>\n            <div class=\"swiper-slide\">\n                <div class=\"swiper-container swiper-container-v\">\n                    <div class=\"swiper-wrapper\">\n                        <div class=\"swiper-slide\">Vertical Slide 1</div>\n                        <div class=\"swiper-slide\">Vertical Slide 2</div>\n                        <div class=\"swiper-slide\">Vertical Slide 3</div>\n                        <div class=\"swiper-slide\">Vertical Slide 4</div>\n                        <div class=\"swiper-slide\">Vertical Slide 5</div>\n                    </div>\n                    <div class=\"swiper-pagination swiper-pagination-v\"></div>\n                </div>\n            </div>\n            <div class=\"swiper-slide\">Horizontal Slide 3</div>\n            <div class=\"swiper-slide\">Horizontal Slide 4</div>\n        </div>\n        <!-- Add Pagination -->\n        <div class=\"swiper-pagination swiper-pagination-h\"></div>\n    </div>\n\n    <!-- Swiper JS -->\n    <script src=\"../dist/js/swiper.min.js\"></script>\n\n    <!-- Initialize Swiper -->\n    <script>\n    var swiperH = new Swiper('.swiper-container-h', {\n        pagination: '.swiper-pagination-h',\n        paginationClickable: true,\n        spaceBetween: 50\n    });\n    var swiperV = new Swiper('.swiper-container-v', {\n        pagination: '.swiper-pagination-v',\n        paginationClickable: true,\n        direction: 'vertical',\n        spaceBetween: 50\n    });\n    </script>\n</body>\n</html>"
  },
  {
    "path": "app_frontend/static/plugin/Swiper-3.3.1/demos/12-grab-cursor.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n    <meta charset=\"utf-8\">\n    <title>Swiper demo</title>\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1, minimum-scale=1, maximum-scale=1\">\n\n    <!-- Link Swiper's CSS -->\n    <link rel=\"stylesheet\" href=\"../dist/css/swiper.min.css\">\n\n    <!-- Demo styles -->\n    <style>\n    body {\n        background: #eee;\n        font-family: Helvetica Neue, Helvetica, Arial, sans-serif;\n        font-size: 14px;\n        color:#000;\n        margin: 0;\n        padding: 0;\n    }\n    .swiper-container {\n        width: 100%;\n        height: 300px;\n        margin: 20px auto;\n    }\n    .swiper-slide {\n        text-align: center;\n        font-size: 18px;\n        background: #fff;\n        width: 60%;\n\n        /* Center slide text vertically */\n        display: -webkit-box;\n        display: -ms-flexbox;\n        display: -webkit-flex;\n        display: flex;\n        -webkit-box-pack: center;\n        -ms-flex-pack: center;\n        -webkit-justify-content: center;\n        justify-content: center;\n        -webkit-box-align: center;\n        -ms-flex-align: center;\n        -webkit-align-items: center;\n        align-items: center;\n    }\n    .swiper-slide:nth-child(2n) {\n        width: 40%;\n    }\n    .swiper-slide:nth-child(3n) {\n        width: 20%;\n    }\n    </style>\n</head>\n<body>\n    <!-- Swiper -->\n    <div class=\"swiper-container\">\n        <div class=\"swiper-wrapper\">\n            <div class=\"swiper-slide\">Slide 1</div>\n            <div class=\"swiper-slide\">Slide 2</div>\n            <div class=\"swiper-slide\">Slide 3</div>\n            <div class=\"swiper-slide\">Slide 4</div>\n            <div class=\"swiper-slide\">Slide 5</div>\n            <div class=\"swiper-slide\">Slide 6</div>\n            <div class=\"swiper-slide\">Slide 7</div>\n            <div class=\"swiper-slide\">Slide 8</div>\n            <div class=\"swiper-slide\">Slide 9</div>\n            <div class=\"swiper-slide\">Slide 10</div>\n        </div>\n        <!-- Add Pagination -->\n        <div class=\"swiper-pagination\"></div>\n    </div>\n\n    <!-- Swiper JS -->\n    <script src=\"../dist/js/swiper.min.js\"></script>\n\n    <!-- Initialize Swiper -->\n    <script>\n    var swiper = new Swiper('.swiper-container', {\n        pagination: '.swiper-pagination',\n        slidesPerView: 4,\n        centeredSlides: true,\n        paginationClickable: true,\n        spaceBetween: 30,\n        grabCursor: true\n    });\n    </script>\n</body>\n</html>"
  },
  {
    "path": "app_frontend/static/plugin/Swiper-3.3.1/demos/13-scrollbar.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n    <meta charset=\"utf-8\">\n    <title>Swiper demo</title>\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1, minimum-scale=1, maximum-scale=1\">\n\n    <!-- Link Swiper's CSS -->\n    <link rel=\"stylesheet\" href=\"../dist/css/swiper.min.css\">\n\n    <!-- Demo styles -->\n    <style>\n    body {\n        background: #eee;\n        font-family: Helvetica Neue, Helvetica, Arial, sans-serif;\n        font-size: 14px;\n        color:#000;\n        margin: 0;\n        padding: 0;\n    }\n    .swiper-container {\n        width: 100%;\n        height: 300px;\n        margin: 20px auto;\n    }\n    .swiper-slide {\n        text-align: center;\n        font-size: 18px;\n        background: #fff;\n        width: 250px;\n\n        /* Center slide text vertically */\n        display: -webkit-box;\n        display: -ms-flexbox;\n        display: -webkit-flex;\n        display: flex;\n        -webkit-box-pack: center;\n        -ms-flex-pack: center;\n        -webkit-justify-content: center;\n        justify-content: center;\n        -webkit-box-align: center;\n        -ms-flex-align: center;\n        -webkit-align-items: center;\n        align-items: center;\n    }\n    </style>\n</head>\n<body>\n    <!-- Swiper -->\n    <div class=\"swiper-container\">\n        <div class=\"swiper-wrapper\">\n            <div class=\"swiper-slide\">Slide 1</div>\n            <div class=\"swiper-slide\">Slide 2</div>\n            <div class=\"swiper-slide\">Slide 3</div>\n            <div class=\"swiper-slide\">Slide 4</div>\n            <div class=\"swiper-slide\">Slide 5</div>\n            <div class=\"swiper-slide\">Slide 6</div>\n            <div class=\"swiper-slide\">Slide 7</div>\n            <div class=\"swiper-slide\">Slide 8</div>\n            <div class=\"swiper-slide\">Slide 9</div>\n            <div class=\"swiper-slide\">Slide 10</div>\n        </div>\n        <!-- Add Scrollbar -->\n        <div class=\"swiper-scrollbar\"></div>\n    </div>\n\n    <!-- Swiper JS -->\n    <script src=\"../dist/js/swiper.min.js\"></script>\n\n    <!-- Initialize Swiper -->\n    <script>\n    var swiper = new Swiper('.swiper-container', {\n        scrollbar: '.swiper-scrollbar',\n        scrollbarHide: true,\n        slidesPerView: 'auto',\n        centeredSlides: true,\n        spaceBetween: 30,\n        grabCursor: true\n    });\n    </script>\n</body>\n</html>"
  },
  {
    "path": "app_frontend/static/plugin/Swiper-3.3.1/demos/14-nav-arrows.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n    <meta charset=\"utf-8\">\n    <title>Swiper demo</title>\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1, minimum-scale=1, maximum-scale=1\">\n\n    <!-- Link Swiper's CSS -->\n    <link rel=\"stylesheet\" href=\"../dist/css/swiper.min.css\">\n\n    <!-- Demo styles -->\n    <style>\n    html, body {\n        position: relative;\n        height: 100%;\n    }\n    body {\n        background: #eee;\n        font-family: Helvetica Neue, Helvetica, Arial, sans-serif;\n        font-size: 14px;\n        color:#000;\n        margin: 0;\n        padding: 0;\n    }\n    .swiper-container {\n        width: 100%;\n        height: 100%;\n    }\n    .swiper-slide {\n        text-align: center;\n        font-size: 18px;\n        background: #fff;\n\n        /* Center slide text vertically */\n        display: -webkit-box;\n        display: -ms-flexbox;\n        display: -webkit-flex;\n        display: flex;\n        -webkit-box-pack: center;\n        -ms-flex-pack: center;\n        -webkit-justify-content: center;\n        justify-content: center;\n        -webkit-box-align: center;\n        -ms-flex-align: center;\n        -webkit-align-items: center;\n        align-items: center;\n    }\n    </style>\n</head>\n<body>\n    <!-- Swiper -->\n    <div class=\"swiper-container\">\n        <div class=\"swiper-wrapper\">\n            <div class=\"swiper-slide\">Slide 1</div>\n            <div class=\"swiper-slide\">Slide 2</div>\n            <div class=\"swiper-slide\">Slide 3</div>\n            <div class=\"swiper-slide\">Slide 4</div>\n            <div class=\"swiper-slide\">Slide 5</div>\n            <div class=\"swiper-slide\">Slide 6</div>\n            <div class=\"swiper-slide\">Slide 7</div>\n            <div class=\"swiper-slide\">Slide 8</div>\n            <div class=\"swiper-slide\">Slide 9</div>\n            <div class=\"swiper-slide\">Slide 10</div>\n        </div>\n        <!-- Add Pagination -->\n        <div class=\"swiper-pagination\"></div>\n        <!-- Add Arrows -->\n        <div class=\"swiper-button-next\"></div>\n        <div class=\"swiper-button-prev\"></div>\n    </div>\n\n    <!-- Swiper JS -->\n    <script src=\"../dist/js/swiper.min.js\"></script>\n\n    <!-- Initialize Swiper -->\n    <script>\n    var swiper = new Swiper('.swiper-container', {\n        pagination: '.swiper-pagination',\n        paginationClickable: true,\n        nextButton: '.swiper-button-next',\n        prevButton: '.swiper-button-prev',\n        spaceBetween: 30\n    });\n    </script>\n</body>\n</html>"
  },
  {
    "path": "app_frontend/static/plugin/Swiper-3.3.1/demos/15-infinite-loop.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n    <meta charset=\"utf-8\">\n    <title>Swiper demo</title>\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1, minimum-scale=1, maximum-scale=1\">\n\n    <!-- Link Swiper's CSS -->\n    <link rel=\"stylesheet\" href=\"../dist/css/swiper.min.css\">\n\n    <!-- Demo styles -->\n    <style>\n    html, body {\n        position: relative;\n        height: 100%;\n    }\n    body {\n        background: #eee;\n        font-family: Helvetica Neue, Helvetica, Arial, sans-serif;\n        font-size: 14px;\n        color:#000;\n        margin: 0;\n        padding: 0;\n    }\n    .swiper-container {\n        width: 100%;\n        height: 100%;\n        margin-left: auto;\n        margin-right: auto;\n    }\n    .swiper-slide {\n        text-align: center;\n        font-size: 18px;\n        background: #fff;\n\n        /* Center slide text vertically */\n        display: -webkit-box;\n        display: -ms-flexbox;\n        display: -webkit-flex;\n        display: flex;\n        -webkit-box-pack: center;\n        -ms-flex-pack: center;\n        -webkit-justify-content: center;\n        justify-content: center;\n        -webkit-box-align: center;\n        -ms-flex-align: center;\n        -webkit-align-items: center;\n        align-items: center;\n    }\n    </style>\n</head>\n<body>\n    <!-- Swiper -->\n    <div class=\"swiper-container\">\n        <div class=\"swiper-wrapper\">\n            <div class=\"swiper-slide\">Slide 1</div>\n            <div class=\"swiper-slide\">Slide 2</div>\n            <div class=\"swiper-slide\">Slide 3</div>\n            <div class=\"swiper-slide\">Slide 4</div>\n            <div class=\"swiper-slide\">Slide 5</div>\n            <div class=\"swiper-slide\">Slide 6</div>\n            <div class=\"swiper-slide\">Slide 7</div>\n            <div class=\"swiper-slide\">Slide 8</div>\n            <div class=\"swiper-slide\">Slide 9</div>\n            <div class=\"swiper-slide\">Slide 10</div>\n        </div>\n        <!-- Add Pagination -->\n        <div class=\"swiper-pagination\"></div>\n        <!-- Add Arrows -->\n        <div class=\"swiper-button-next\"></div>\n        <div class=\"swiper-button-prev\"></div>\n    </div>\n\n    <!-- Swiper JS -->\n    <script src=\"../dist/js/swiper.min.js\"></script>\n\n    <!-- Initialize Swiper -->\n    <script>\n    var swiper = new Swiper('.swiper-container', {\n        pagination: '.swiper-pagination',\n        nextButton: '.swiper-button-next',\n        prevButton: '.swiper-button-prev',\n        slidesPerView: 1,\n        paginationClickable: true,\n        spaceBetween: 30,\n        loop: true\n    });\n    </script>\n</body>\n</html>"
  },
  {
    "path": "app_frontend/static/plugin/Swiper-3.3.1/demos/16-effect-fade.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n    <meta charset=\"utf-8\">\n    <title>Swiper demo</title>\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1, minimum-scale=1, maximum-scale=1\">\n\n    <!-- Link Swiper's CSS -->\n    <link rel=\"stylesheet\" href=\"../dist/css/swiper.min.css\">\n\n    <!-- Demo styles -->\n    <style>\n    html, body {\n        position: relative;\n        height: 100%;\n    }\n    body {\n        background: #eee;\n        font-family: Helvetica Neue, Helvetica, Arial, sans-serif;\n        font-size: 14px;\n        color:#000;\n        margin: 0;\n        padding: 0;\n    }\n    .swiper-container {\n        width: 100%;\n        height: 100%;\n    }\n    .swiper-slide {\n        background-position: center;\n        background-size: cover;\n    }\n    </style>\n</head>\n<body>\n    <!-- Swiper -->\n    <div class=\"swiper-container\">\n        <div class=\"swiper-wrapper\">\n            <div class=\"swiper-slide\" style=\"background-image:url(http://lorempixel.com/1000/1000/nightlife/1)\"></div>\n            <div class=\"swiper-slide\" style=\"background-image:url(http://lorempixel.com/1000/1000/nightlife/2)\"></div>\n            <div class=\"swiper-slide\" style=\"background-image:url(http://lorempixel.com/1000/1000/nightlife/3)\"></div>\n            <div class=\"swiper-slide\" style=\"background-image:url(http://lorempixel.com/1000/1000/nightlife/4)\"></div>\n            <div class=\"swiper-slide\" style=\"background-image:url(http://lorempixel.com/1000/1000/nightlife/5)\"></div>\n        </div>\n        <!-- Add Pagination -->\n        <div class=\"swiper-pagination swiper-pagination-white\"></div>\n        <!-- Add Arrows -->\n        <div class=\"swiper-button-next swiper-button-white\"></div>\n        <div class=\"swiper-button-prev swiper-button-white\"></div>\n    </div>\n\n    <!-- Swiper JS -->\n    <script src=\"../dist/js/swiper.min.js\"></script>\n\n    <!-- Initialize Swiper -->\n    <script>\n    var swiper = new Swiper('.swiper-container', {\n        pagination: '.swiper-pagination',\n        paginationClickable: true,\n        nextButton: '.swiper-button-next',\n        prevButton: '.swiper-button-prev',\n        spaceBetween: 30,\n        effect: 'fade'\n    });\n    </script>\n</body>\n</html>"
  },
  {
    "path": "app_frontend/static/plugin/Swiper-3.3.1/demos/17-effect-cube.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n    <meta charset=\"utf-8\">\n    <title>Swiper demo</title>\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1, minimum-scale=1, maximum-scale=1\">\n\n    <!-- Link Swiper's CSS -->\n    <link rel=\"stylesheet\" href=\"../dist/css/swiper.min.css\">\n\n    <!-- Demo styles -->\n    <style>\n    html, body {\n        position: relative;\n        height: 100%;\n    }\n    body {\n        background: #fff;\n        font-family: Helvetica Neue, Helvetica, Arial, sans-serif;\n        font-size: 14px;\n        color:#000;\n        margin: 0;\n        padding: 0;\n    }\n    .swiper-container {\n        width: 300px;\n        height: 300px;\n        position: absolute;\n        left: 50%;\n        top: 50%;\n        margin-left: -150px;\n        margin-top: -150px;\n    }\n    .swiper-slide {\n        background-position: center;\n        background-size: cover;\n    }\n    </style>\n</head>\n<body>\n    <!-- Swiper -->\n    <div class=\"swiper-container\">\n        <div class=\"swiper-wrapper\">\n            <div class=\"swiper-slide\" style=\"background-image:url(http://lorempixel.com/600/600/nature/1)\"></div>\n            <div class=\"swiper-slide\" style=\"background-image:url(http://lorempixel.com/600/600/nature/2)\"></div>\n            <div class=\"swiper-slide\" style=\"background-image:url(http://lorempixel.com/600/600/nature/3)\"></div>\n            <div class=\"swiper-slide\" style=\"background-image:url(http://lorempixel.com/600/600/nature/4)\"></div>\n            <div class=\"swiper-slide\" style=\"background-image:url(http://lorempixel.com/600/600/nature/5)\"></div>\n        </div>\n        <!-- Add Pagination -->\n        <div class=\"swiper-pagination\"></div>\n    </div>\n\n    <!-- Swiper JS -->\n    <script src=\"../dist/js/swiper.min.js\"></script>\n\n    <!-- Initialize Swiper -->\n    <script>\n    var swiper = new Swiper('.swiper-container', {\n        pagination: '.swiper-pagination',\n        effect: 'cube',\n        grabCursor: true,\n        cube: {\n            shadow: true,\n            slideShadows: true,\n            shadowOffset: 20,\n            shadowScale: 0.94\n        }\n    });\n    </script>\n</body>\n</html>"
  },
  {
    "path": "app_frontend/static/plugin/Swiper-3.3.1/demos/18-effect-coverflow.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n    <meta charset=\"utf-8\">\n    <title>Swiper demo</title>\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1, minimum-scale=1, maximum-scale=1\">\n\n    <!-- Link Swiper's CSS -->\n    <link rel=\"stylesheet\" href=\"../dist/css/swiper.min.css\">\n\n    <!-- Demo styles -->\n    <style>\n    body {\n        background: #fff;\n        font-family: Helvetica Neue, Helvetica, Arial, sans-serif;\n        font-size: 14px;\n        color:#000;\n        margin: 0;\n        padding: 0;\n    }\n    .swiper-container {\n        width: 100%;\n        padding-top: 50px;\n        padding-bottom: 50px;\n    }\n    .swiper-slide {\n        background-position: center;\n        background-size: cover;\n        width: 300px;\n        height: 300px;\n\n    }\n    </style>\n</head>\n<body>\n    <!-- Swiper -->\n    <div class=\"swiper-container\">\n        <div class=\"swiper-wrapper\">\n            <div class=\"swiper-slide\" style=\"background-image:url(http://lorempixel.com/600/600/nature/1)\"></div>\n            <div class=\"swiper-slide\" style=\"background-image:url(http://lorempixel.com/600/600/nature/2)\"></div>\n            <div class=\"swiper-slide\" style=\"background-image:url(http://lorempixel.com/600/600/nature/3)\"></div>\n            <div class=\"swiper-slide\" style=\"background-image:url(http://lorempixel.com/600/600/nature/4)\"></div>\n            <div class=\"swiper-slide\" style=\"background-image:url(http://lorempixel.com/600/600/nature/5)\"></div>\n            <div class=\"swiper-slide\" style=\"background-image:url(http://lorempixel.com/600/600/nature/6)\"></div>\n            <div class=\"swiper-slide\" style=\"background-image:url(http://lorempixel.com/600/600/nature/7)\"></div>\n            <div class=\"swiper-slide\" style=\"background-image:url(http://lorempixel.com/600/600/nature/8)\"></div>\n            <div class=\"swiper-slide\" style=\"background-image:url(http://lorempixel.com/600/600/nature/9)\"></div>\n            <div class=\"swiper-slide\" style=\"background-image:url(http://lorempixel.com/600/600/nature/10)\"></div>\n        </div>\n        <!-- Add Pagination -->\n        <div class=\"swiper-pagination\"></div>\n    </div>\n\n    <!-- Swiper JS -->\n    <script src=\"../dist/js/swiper.min.js\"></script>\n\n    <!-- Initialize Swiper -->\n    <script>\n    var swiper = new Swiper('.swiper-container', {\n        pagination: '.swiper-pagination',\n        effect: 'coverflow',\n        grabCursor: true,\n        centeredSlides: true,\n        slidesPerView: 'auto',\n        coverflow: {\n            rotate: 50,\n            stretch: 0,\n            depth: 100,\n            modifier: 1,\n            slideShadows : true\n        }\n    });\n    </script>\n</body>\n</html>"
  },
  {
    "path": "app_frontend/static/plugin/Swiper-3.3.1/demos/19-keyboard-control.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n    <meta charset=\"utf-8\">\n    <title>Swiper demo</title>\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1, minimum-scale=1, maximum-scale=1\">\n\n    <!-- Link Swiper's CSS -->\n    <link rel=\"stylesheet\" href=\"../dist/css/swiper.min.css\">\n\n    <!-- Demo styles -->\n    <style>\n    html, body {\n        position: relative;\n        height: 100%;\n    }\n    body {\n        background: #eee;\n        font-family: Helvetica Neue, Helvetica, Arial, sans-serif;\n        font-size: 14px;\n        color:#000;\n        margin: 0;\n        padding: 0;\n    }\n    .swiper-container {\n        width: 100%;\n        height: 100%;\n        margin-left: auto;\n        margin-right: auto;\n    }\n    .swiper-slide {\n        text-align: center;\n        font-size: 18px;\n        background: #fff;\n\n        /* Center slide text vertically */\n        display: -webkit-box;\n        display: -ms-flexbox;\n        display: -webkit-flex;\n        display: flex;\n        -webkit-box-pack: center;\n        -ms-flex-pack: center;\n        -webkit-justify-content: center;\n        justify-content: center;\n        -webkit-box-align: center;\n        -ms-flex-align: center;\n        -webkit-align-items: center;\n        align-items: center;\n    }\n    </style>\n</head>\n<body>\n    <!-- Swiper -->\n    <div class=\"swiper-container\">\n        <div class=\"swiper-wrapper\">\n            <div class=\"swiper-slide\">Slide 1</div>\n            <div class=\"swiper-slide\">Slide 2</div>\n            <div class=\"swiper-slide\">Slide 3</div>\n            <div class=\"swiper-slide\">Slide 4</div>\n            <div class=\"swiper-slide\">Slide 5</div>\n            <div class=\"swiper-slide\">Slide 6</div>\n            <div class=\"swiper-slide\">Slide 7</div>\n            <div class=\"swiper-slide\">Slide 8</div>\n            <div class=\"swiper-slide\">Slide 9</div>\n            <div class=\"swiper-slide\">Slide 10</div>\n        </div>\n        <!-- Add Pagination -->\n        <div class=\"swiper-pagination\"></div>\n        <!-- Add Arrows -->\n        <div class=\"swiper-button-next\"></div>\n        <div class=\"swiper-button-prev\"></div>\n    </div>\n\n    <!-- Swiper JS -->\n    <script src=\"../dist/js/swiper.min.js\"></script>\n\n    <!-- Initialize Swiper -->\n    <script>\n    var swiper = new Swiper('.swiper-container', {\n        pagination: '.swiper-pagination',\n        slidesPerView: 1,\n        paginationClickable: true,\n        spaceBetween: 30,\n        keyboardControl: true,\n        nextButton: '.swiper-button-next',\n        prevButton: '.swiper-button-prev',\n    });\n    </script>\n</body>\n</html>"
  },
  {
    "path": "app_frontend/static/plugin/Swiper-3.3.1/demos/20-mousewheel-control.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n    <meta charset=\"utf-8\">\n    <title>Swiper demo</title>\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1, minimum-scale=1, maximum-scale=1\">\n\n    <!-- Link Swiper's CSS -->\n    <link rel=\"stylesheet\" href=\"../dist/css/swiper.min.css\">\n\n    <!-- Demo styles -->\n    <style>\n    html, body {\n        position: relative;\n        height: 100%;\n    }\n    body {\n        background: #eee;\n        font-family: Helvetica Neue, Helvetica, Arial, sans-serif;\n        font-size: 14px;\n        color:#000;\n        margin: 0;\n        padding: 0;\n    }\n    .swiper-container {\n        width: 100%;\n        height: 100%;\n        margin-left: auto;\n        margin-right: auto;\n    }\n    .swiper-slide {\n        text-align: center;\n        font-size: 18px;\n        background: #fff;\n\n        /* Center slide text vertically */\n        display: -webkit-box;\n        display: -ms-flexbox;\n        display: -webkit-flex;\n        display: flex;\n        -webkit-box-pack: center;\n        -ms-flex-pack: center;\n        -webkit-justify-content: center;\n        justify-content: center;\n        -webkit-box-align: center;\n        -ms-flex-align: center;\n        -webkit-align-items: center;\n        align-items: center;\n    }\n    </style>\n</head>\n<body>\n    <!-- Swiper -->\n    <div class=\"swiper-container\">\n        <div class=\"swiper-wrapper\">\n            <div class=\"swiper-slide\">Slide 1</div>\n            <div class=\"swiper-slide\">Slide 2</div>\n            <div class=\"swiper-slide\">Slide 3</div>\n            <div class=\"swiper-slide\">Slide 4</div>\n            <div class=\"swiper-slide\">Slide 5</div>\n            <div class=\"swiper-slide\">Slide 6</div>\n            <div class=\"swiper-slide\">Slide 7</div>\n            <div class=\"swiper-slide\">Slide 8</div>\n            <div class=\"swiper-slide\">Slide 9</div>\n            <div class=\"swiper-slide\">Slide 10</div>\n        </div>\n        <!-- Add Pagination -->\n        <div class=\"swiper-pagination\"></div>\n    </div>\n\n    <!-- Swiper JS -->\n    <script src=\"../dist/js/swiper.min.js\"></script>\n\n    <!-- Initialize Swiper -->\n    <script>\n    var swiper = new Swiper('.swiper-container', {\n        pagination: '.swiper-pagination',\n        direction: 'vertical',\n        slidesPerView: 1,\n        paginationClickable: true,\n        spaceBetween: 30,\n        mousewheelControl: true\n    });\n    </script>\n</body>\n</html>"
  },
  {
    "path": "app_frontend/static/plugin/Swiper-3.3.1/demos/21-autoplay.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n    <meta charset=\"utf-8\">\n    <title>Swiper demo</title>\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1, minimum-scale=1, maximum-scale=1\">\n\n    <!-- Link Swiper's CSS -->\n    <link rel=\"stylesheet\" href=\"../dist/css/swiper.min.css\">\n\n    <!-- Demo styles -->\n    <style>\n    html, body {\n        position: relative;\n        height: 100%;\n    }\n    body {\n        background: #eee;\n        font-family: Helvetica Neue, Helvetica, Arial, sans-serif;\n        font-size: 14px;\n        color:#000;\n        margin: 0;\n        padding: 0;\n    }\n    .swiper-container {\n        width: 100%;\n        height: 100%;\n        \n    }\n    .swiper-slide {\n        text-align: center;\n        font-size: 18px;\n        background: #fff;\n        \n        /* Center slide text vertically */\n        display: -webkit-box;\n        display: -ms-flexbox;\n        display: -webkit-flex;\n        display: flex;\n        -webkit-box-pack: center;\n        -ms-flex-pack: center;\n        -webkit-justify-content: center;\n        justify-content: center;\n        -webkit-box-align: center;\n        -ms-flex-align: center;\n        -webkit-align-items: center;\n        align-items: center;\n    }\n    </style>\n</head>\n<body>\n    <!-- Swiper -->\n    <div class=\"swiper-container\">\n        <div class=\"swiper-wrapper\">\n            <div class=\"swiper-slide\">Slide 1</div>\n            <div class=\"swiper-slide\">Slide 2</div>\n            <div class=\"swiper-slide\">Slide 3</div>\n            <div class=\"swiper-slide\">Slide 4</div>\n            <div class=\"swiper-slide\">Slide 5</div>\n            <div class=\"swiper-slide\">Slide 6</div>\n            <div class=\"swiper-slide\">Slide 7</div>\n            <div class=\"swiper-slide\">Slide 8</div>\n            <div class=\"swiper-slide\">Slide 9</div>\n            <div class=\"swiper-slide\">Slide 10</div>\n        </div>\n        <!-- Add Pagination -->\n        <div class=\"swiper-pagination\"></div>\n        <!-- Add Arrows -->\n        <div class=\"swiper-button-next\"></div>\n        <div class=\"swiper-button-prev\"></div>\n    </div>\n\n    <!-- Swiper JS -->\n    <script src=\"../dist/js/swiper.min.js\"></script>\n\n    <!-- Initialize Swiper -->\n    <script>\n    var swiper = new Swiper('.swiper-container', {\n        pagination: '.swiper-pagination',\n        nextButton: '.swiper-button-next',\n        prevButton: '.swiper-button-prev',\n        paginationClickable: true,\n        spaceBetween: 30,\n        centeredSlides: true,\n        autoplay: 2500,\n        autoplayDisableOnInteraction: false\n    });\n    </script>\n</body>\n</html>"
  },
  {
    "path": "app_frontend/static/plugin/Swiper-3.3.1/demos/22-dynamic-slides.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n    <meta charset=\"utf-8\">\n    <title>Swiper demo</title>\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1, minimum-scale=1, maximum-scale=1\">\n\n    <!-- Link Swiper's CSS -->\n    <link rel=\"stylesheet\" href=\"../dist/css/swiper.min.css\">\n\n    <!-- Demo styles -->\n    <style>\n    body {\n        background: #eee;\n        font-family: Helvetica Neue, Helvetica, Arial, sans-serif;\n        font-size: 14px;\n        color:#000;\n        margin: 0;\n        padding: 0;\n    }\n    .swiper-container {\n        width: 100%;\n        height: 300px;\n        margin: 20px auto;\n    }\n    .swiper-slide {\n        text-align: center;\n        font-size: 18px;\n        background: #fff;\n        \n        /* Center slide text vertically */\n        display: -webkit-box;\n        display: -ms-flexbox;\n        display: -webkit-flex;\n        display: flex;\n        -webkit-box-pack: center;\n        -ms-flex-pack: center;\n        -webkit-justify-content: center;\n        justify-content: center;\n        -webkit-box-align: center;\n        -ms-flex-align: center;\n        -webkit-align-items: center;\n        align-items: center;\n    }\n    .append-buttons {\n        text-align: center;\n        margin-top: 20px;\n    }\n    .append-buttons a {\n        display: inline-block;\n        border: 1px solid #007aff;\n        color: #007aff;\n        text-decoration: none;\n        padding: 4px 10px;\n        border-radius: 4px;\n        margin: 0 10px;\n        font-size: 13px;\n    }\n    </style>\n</head>\n<body>\n    <!-- Swiper -->\n    <div class=\"swiper-container\">\n        <div class=\"swiper-wrapper\">\n            <div class=\"swiper-slide\">Slide 1</div>\n            <div class=\"swiper-slide\">Slide 2</div>\n            <div class=\"swiper-slide\">Slide 3</div>\n            <div class=\"swiper-slide\">Slide 4</div>\n        </div>\n        <!-- Add Pagination -->\n        <div class=\"swiper-pagination\"></div>\n        <!-- Add Arrows -->\n        <div class=\"swiper-button-next\"></div>\n        <div class=\"swiper-button-prev\"></div>\n    </div>\n    <p class=\"append-buttons\">\n        <a href=\"#\" class=\"prepend-2-slides\">Prepend 2 Slides</a>\n        <a href=\"#\" class=\"prepend-slide\">Prepend Slide</a>\n        <a href=\"#\" class=\"append-slide\">Append Slide</a>\n        <a href=\"#\" class=\"append-2-slides\">Append 2 Slides</a>\n    </p>\n    <!-- Swiper JS -->\n    <script src=\"../dist/js/swiper.min.js\"></script>\n\n    <!-- Initialize Swiper -->\n    <script>\n    var appendNumber = 4;\n    var prependNumber = 1;\n    var swiper = new Swiper('.swiper-container', {\n        pagination: '.swiper-pagination',\n        nextButton: '.swiper-button-next',\n        prevButton: '.swiper-button-prev',\n        slidesPerView: 3,\n        centeredSlides: true,\n        paginationClickable: true,\n        spaceBetween: 30,\n    });\n    document.querySelector('.prepend-2-slides').addEventListener('click', function (e) {\n        e.preventDefault();\n        swiper.prependSlide([\n            '<div class=\"swiper-slide\">Slide ' + (--prependNumber) + '</div>',\n            '<div class=\"swiper-slide\">Slide ' + (--prependNumber) + '</div>'\n        ]);\n    });\n    document.querySelector('.prepend-slide').addEventListener('click', function (e) {\n        e.preventDefault();\n        swiper.prependSlide('<div class=\"swiper-slide\">Slide ' + (--prependNumber) + '</div>');\n    });\n    document.querySelector('.append-slide').addEventListener('click', function (e) {\n        e.preventDefault();\n        swiper.appendSlide('<div class=\"swiper-slide\">Slide ' + (++appendNumber) + '</div>');\n    });\n    document.querySelector('.append-2-slides').addEventListener('click', function (e) {\n        e.preventDefault();\n        swiper.appendSlide([\n            '<div class=\"swiper-slide\">Slide ' + (++appendNumber) + '</div>',\n            '<div class=\"swiper-slide\">Slide ' + (++appendNumber) + '</div>'\n        ]);\n    });\n    </script>\n</body>\n</html>"
  },
  {
    "path": "app_frontend/static/plugin/Swiper-3.3.1/demos/23-thumbs-gallery-loop.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n    <meta charset=\"utf-8\">\n    <title>Swiper demo</title>\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1, minimum-scale=1, maximum-scale=1\">\n    <!-- Link Swiper's CSS -->\n    <link rel=\"stylesheet\" href=\"../dist/css/swiper.min.css\">\n\n    <!-- Demo styles -->\n    <style>\n    html, body {\n        position: relative;\n        height: 100%;\n    }\n    body {\n        background: #000;\n        font-family: Helvetica Neue, Helvetica, Arial, sans-serif;\n        font-size: 14px;\n        color:#000;\n        margin: 0;\n        padding: 0;\n    }\n    .swiper-container {\n        width: 100%;\n        height: 300px;\n        margin-left: auto;\n        margin-right: auto;\n    }\n    .swiper-slide {\n        background-size: cover;\n        background-position: center;\n    }\n    .gallery-top {\n        height: 80%;\n        width: 100%;\n    }\n    .gallery-thumbs {\n        height: 20%;\n        box-sizing: border-box;\n        padding: 10px 0;\n    }\n    .gallery-thumbs .swiper-slide {\n        height: 100%;\n        opacity: 0.4;\n    }\n    .gallery-thumbs .swiper-slide-active {\n        opacity: 1;\n    }\n    \n    </style>\n</head>\n<body>\n    <!-- Swiper -->\n    <div class=\"swiper-container gallery-top\">\n        <div class=\"swiper-wrapper\">\n            <div class=\"swiper-slide\" style=\"background-image:url(http://lorempixel.com/1200/1200/nature/1)\"></div>\n            <div class=\"swiper-slide\" style=\"background-image:url(http://lorempixel.com/1200/1200/nature/2)\"></div>\n            <div class=\"swiper-slide\" style=\"background-image:url(http://lorempixel.com/1200/1200/nature/3)\"></div>\n            <div class=\"swiper-slide\" style=\"background-image:url(http://lorempixel.com/1200/1200/nature/4)\"></div>\n            <div class=\"swiper-slide\" style=\"background-image:url(http://lorempixel.com/1200/1200/nature/5)\"></div>\n            <div class=\"swiper-slide\" style=\"background-image:url(http://lorempixel.com/1200/1200/nature/6)\"></div>\n            <div class=\"swiper-slide\" style=\"background-image:url(http://lorempixel.com/1200/1200/nature/7)\"></div>\n            <div class=\"swiper-slide\" style=\"background-image:url(http://lorempixel.com/1200/1200/nature/8)\"></div>\n            <div class=\"swiper-slide\" style=\"background-image:url(http://lorempixel.com/1200/1200/nature/9)\"></div>\n            <div class=\"swiper-slide\" style=\"background-image:url(http://lorempixel.com/1200/1200/nature/10)\"></div>\n        </div>\n        <!-- Add Arrows -->\n        <div class=\"swiper-button-next swiper-button-white\"></div>\n        <div class=\"swiper-button-prev swiper-button-white\"></div>\n    </div>\n    <div class=\"swiper-container gallery-thumbs\">\n        <div class=\"swiper-wrapper\">\n            <div class=\"swiper-slide\" style=\"background-image:url(http://lorempixel.com/1200/1200/nature/1)\"></div>\n            <div class=\"swiper-slide\" style=\"background-image:url(http://lorempixel.com/1200/1200/nature/2)\"></div>\n            <div class=\"swiper-slide\" style=\"background-image:url(http://lorempixel.com/1200/1200/nature/3)\"></div>\n            <div class=\"swiper-slide\" style=\"background-image:url(http://lorempixel.com/1200/1200/nature/4)\"></div>\n            <div class=\"swiper-slide\" style=\"background-image:url(http://lorempixel.com/1200/1200/nature/5)\"></div>\n            <div class=\"swiper-slide\" style=\"background-image:url(http://lorempixel.com/1200/1200/nature/6)\"></div>\n            <div class=\"swiper-slide\" style=\"background-image:url(http://lorempixel.com/1200/1200/nature/7)\"></div>\n            <div class=\"swiper-slide\" style=\"background-image:url(http://lorempixel.com/1200/1200/nature/8)\"></div>\n            <div class=\"swiper-slide\" style=\"background-image:url(http://lorempixel.com/1200/1200/nature/9)\"></div>\n            <div class=\"swiper-slide\" style=\"background-image:url(http://lorempixel.com/1200/1200/nature/10)\"></div>\n        </div>\n    </div>\n\n    <!-- Swiper JS -->\n    <script src=\"../dist/js/swiper.js\"></script>\n\n    <!-- Initialize Swiper -->\n    <script>\n    var galleryTop = new Swiper('.gallery-top', {\n        nextButton: '.swiper-button-next',\n        prevButton: '.swiper-button-prev',\n        spaceBetween: 10,\n        loop:true,\n        loopedSlides: 5, //looped slides should be the same     \n    });\n    var galleryThumbs = new Swiper('.gallery-thumbs', {\n        spaceBetween: 10,\n        slidesPerView: 4,\n        touchRatio: 0.2,\n        loop:true,\n        loopedSlides: 5, //looped slides should be the same\n        slideToClickedSlide: true\n    });\n    galleryTop.params.control = galleryThumbs;\n    galleryThumbs.params.control = galleryTop;\n    \n    </script>\n</body>\n</html>\n"
  },
  {
    "path": "app_frontend/static/plugin/Swiper-3.3.1/demos/23-thumbs-gallery.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n    <meta charset=\"utf-8\">\n    <title>Swiper demo</title>\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1, minimum-scale=1, maximum-scale=1\">\n    <!-- Link Swiper's CSS -->\n    <link rel=\"stylesheet\" href=\"../dist/css/swiper.min.css\">\n\n    <!-- Demo styles -->\n    <style>\n    html, body {\n        position: relative;\n        height: 100%;\n    }\n    body {\n        background: #000;\n        font-family: Helvetica Neue, Helvetica, Arial, sans-serif;\n        font-size: 14px;\n        color:#000;\n        margin: 0;\n        padding: 0;\n    }\n    .swiper-container {\n        width: 100%;\n        height: 300px;\n        margin-left: auto;\n        margin-right: auto;\n    }\n    .swiper-slide {\n        background-size: cover;\n        background-position: center;\n    }\n    .gallery-top {\n        height: 80%;\n        width: 100%;\n    }\n    .gallery-thumbs {\n        height: 20%;\n        box-sizing: border-box;\n        padding: 10px 0;\n    }\n    .gallery-thumbs .swiper-slide {\n        width: 25%;\n        height: 100%;\n        opacity: 0.4;\n    }\n    .gallery-thumbs .swiper-slide-active {\n        opacity: 1;\n    }\n    \n    </style>\n</head>\n<body>\n    <!-- Swiper -->\n    <div class=\"swiper-container gallery-top\">\n        <div class=\"swiper-wrapper\">\n            <div class=\"swiper-slide\" style=\"background-image:url(http://lorempixel.com/1200/1200/nature/1)\"></div>\n            <div class=\"swiper-slide\" style=\"background-image:url(http://lorempixel.com/1200/1200/nature/2)\"></div>\n            <div class=\"swiper-slide\" style=\"background-image:url(http://lorempixel.com/1200/1200/nature/3)\"></div>\n            <div class=\"swiper-slide\" style=\"background-image:url(http://lorempixel.com/1200/1200/nature/4)\"></div>\n            <div class=\"swiper-slide\" style=\"background-image:url(http://lorempixel.com/1200/1200/nature/5)\"></div>\n            <div class=\"swiper-slide\" style=\"background-image:url(http://lorempixel.com/1200/1200/nature/6)\"></div>\n            <div class=\"swiper-slide\" style=\"background-image:url(http://lorempixel.com/1200/1200/nature/7)\"></div>\n            <div class=\"swiper-slide\" style=\"background-image:url(http://lorempixel.com/1200/1200/nature/8)\"></div>\n            <div class=\"swiper-slide\" style=\"background-image:url(http://lorempixel.com/1200/1200/nature/9)\"></div>\n            <div class=\"swiper-slide\" style=\"background-image:url(http://lorempixel.com/1200/1200/nature/10)\"></div>\n        </div>\n        <!-- Add Arrows -->\n        <div class=\"swiper-button-next swiper-button-white\"></div>\n        <div class=\"swiper-button-prev swiper-button-white\"></div>\n    </div>\n    <div class=\"swiper-container gallery-thumbs\">\n        <div class=\"swiper-wrapper\">\n            <div class=\"swiper-slide\" style=\"background-image:url(http://lorempixel.com/1200/1200/nature/1)\"></div>\n            <div class=\"swiper-slide\" style=\"background-image:url(http://lorempixel.com/1200/1200/nature/2)\"></div>\n            <div class=\"swiper-slide\" style=\"background-image:url(http://lorempixel.com/1200/1200/nature/3)\"></div>\n            <div class=\"swiper-slide\" style=\"background-image:url(http://lorempixel.com/1200/1200/nature/4)\"></div>\n            <div class=\"swiper-slide\" style=\"background-image:url(http://lorempixel.com/1200/1200/nature/5)\"></div>\n            <div class=\"swiper-slide\" style=\"background-image:url(http://lorempixel.com/1200/1200/nature/6)\"></div>\n            <div class=\"swiper-slide\" style=\"background-image:url(http://lorempixel.com/1200/1200/nature/7)\"></div>\n            <div class=\"swiper-slide\" style=\"background-image:url(http://lorempixel.com/1200/1200/nature/8)\"></div>\n            <div class=\"swiper-slide\" style=\"background-image:url(http://lorempixel.com/1200/1200/nature/9)\"></div>\n            <div class=\"swiper-slide\" style=\"background-image:url(http://lorempixel.com/1200/1200/nature/10)\"></div>\n        </div>\n    </div>\n\n    <!-- Swiper JS -->\n    <script src=\"../dist/js/swiper.min.js\"></script>\n\n    <!-- Initialize Swiper -->\n    <script>\n    var galleryTop = new Swiper('.gallery-top', {\n        nextButton: '.swiper-button-next',\n        prevButton: '.swiper-button-prev',\n        spaceBetween: 10,\n    });\n    var galleryThumbs = new Swiper('.gallery-thumbs', {\n        spaceBetween: 10,\n        centeredSlides: true,\n        slidesPerView: 'auto',\n        touchRatio: 0.2,\n        slideToClickedSlide: true\n    });\n    galleryTop.params.control = galleryThumbs;\n    galleryThumbs.params.control = galleryTop;\n    \n    </script>\n</body>\n</html>\n"
  },
  {
    "path": "app_frontend/static/plugin/Swiper-3.3.1/demos/24-multiple-swipers.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n    <meta charset=\"utf-8\">\n    <title>Swiper demo</title>\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1, minimum-scale=1, maximum-scale=1\">\n\n    <!-- Link Swiper's CSS -->\n    <link rel=\"stylesheet\" href=\"../dist/css/swiper.min.css\">\n\n    <!-- Demo styles -->\n    <style>\n    body {\n        background: #eee;\n        font-family: Helvetica Neue, Helvetica, Arial, sans-serif;\n        font-size: 14px;\n        color:#000;\n        margin: 0;\n        padding: 0;\n    }\n    .swiper-container {\n        width: 100%;\n        height: 300px;\n        margin: 20px 0;\n    }\n    .swiper-slide {\n        text-align: center;\n        font-size: 18px;\n        background: #fff;\n\n        /* Center slide text vertically */\n        display: -webkit-box;\n        display: -ms-flexbox;\n        display: -webkit-flex;\n        display: flex;\n        -webkit-box-pack: center;\n        -ms-flex-pack: center;\n        -webkit-justify-content: center;\n        justify-content: center;\n        -webkit-box-align: center;\n        -ms-flex-align: center;\n        -webkit-align-items: center;\n        align-items: center;\n    }\n    </style>\n</head>\n<body>\n    <!-- Swiper -->\n    <div class=\"swiper-container swiper1\">\n        <div class=\"swiper-wrapper\">\n            <div class=\"swiper-slide\">Slide 1</div>\n            <div class=\"swiper-slide\">Slide 2</div>\n            <div class=\"swiper-slide\">Slide 3</div>\n            <div class=\"swiper-slide\">Slide 4</div>\n            <div class=\"swiper-slide\">Slide 5</div>\n            <div class=\"swiper-slide\">Slide 6</div>\n            <div class=\"swiper-slide\">Slide 7</div>\n            <div class=\"swiper-slide\">Slide 8</div>\n            <div class=\"swiper-slide\">Slide 9</div>\n            <div class=\"swiper-slide\">Slide 10</div>\n        </div>\n        <!-- Add Pagination -->\n        <div class=\"swiper-pagination swiper-pagination1\"></div>\n    </div>\n\n    <!-- Swiper -->\n    <div class=\"swiper-container swiper2\">\n        <div class=\"swiper-wrapper\">\n            <div class=\"swiper-slide\">Slide 1</div>\n            <div class=\"swiper-slide\">Slide 2</div>\n            <div class=\"swiper-slide\">Slide 3</div>\n            <div class=\"swiper-slide\">Slide 4</div>\n            <div class=\"swiper-slide\">Slide 5</div>\n            <div class=\"swiper-slide\">Slide 6</div>\n            <div class=\"swiper-slide\">Slide 7</div>\n            <div class=\"swiper-slide\">Slide 8</div>\n            <div class=\"swiper-slide\">Slide 9</div>\n            <div class=\"swiper-slide\">Slide 10</div>\n        </div>\n        <!-- Add Pagination -->\n        <div class=\"swiper-pagination swiper-pagination2\"></div>\n    </div>\n\n    <!-- Swiper -->\n    <div class=\"swiper-container swiper3\">\n        <div class=\"swiper-wrapper\">\n            <div class=\"swiper-slide\">Slide 1</div>\n            <div class=\"swiper-slide\">Slide 2</div>\n            <div class=\"swiper-slide\">Slide 3</div>\n            <div class=\"swiper-slide\">Slide 4</div>\n            <div class=\"swiper-slide\">Slide 5</div>\n            <div class=\"swiper-slide\">Slide 6</div>\n            <div class=\"swiper-slide\">Slide 7</div>\n            <div class=\"swiper-slide\">Slide 8</div>\n            <div class=\"swiper-slide\">Slide 9</div>\n            <div class=\"swiper-slide\">Slide 10</div>\n        </div>\n        <!-- Add Pagination -->\n        <div class=\"swiper-pagination swiper-pagination3\"></div>\n    </div>\n\n    <!-- Swiper JS -->\n    <script src=\"../dist/js/swiper.min.js\"></script>\n\n    <!-- Initialize Swiper -->\n    <script>\n    var swiper1 = new Swiper('.swiper1', {\n        pagination: '.swiper-pagination1',\n        paginationClickable: true,\n        spaceBetween: 30,\n    });\n    var swiper2 = new Swiper('.swiper2', {\n        pagination: '.swiper-pagination2',\n        paginationClickable: true,\n        spaceBetween: 30,\n    });\n    var swiper3 = new Swiper('.swiper3', {\n        pagination: '.swiper-pagination3',\n        paginationClickable: true,\n        spaceBetween: 30,\n    });\n    </script>\n</body>\n</html>"
  },
  {
    "path": "app_frontend/static/plugin/Swiper-3.3.1/demos/25-hash-navigation.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n    <meta charset=\"utf-8\">\n    <title>Swiper demo</title>\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1, minimum-scale=1, maximum-scale=1\">\n\n    <!-- Link Swiper's CSS -->\n    <link rel=\"stylesheet\" href=\"../dist/css/swiper.min.css\">\n\n    <!-- Demo styles -->\n    <style>\n    html, body {\n        position: relative;\n        height: 100%;\n    }\n    body {\n        background: #eee;\n        font-family: Helvetica Neue, Helvetica, Arial, sans-serif;\n        font-size: 14px;\n        color:#000;\n        margin: 0;\n        padding: 0;\n    }\n    .swiper-container {\n        width: 100%;\n        height: 100%;\n    }\n    .swiper-slide {\n        text-align: center;\n        font-size: 18px;\n        background: #fff;\n        \n        /* Center slide text vertically */\n        display: -webkit-box;\n        display: -ms-flexbox;\n        display: -webkit-flex;\n        display: flex;\n        -webkit-box-pack: center;\n        -ms-flex-pack: center;\n        -webkit-justify-content: center;\n        justify-content: center;\n        -webkit-box-align: center;\n        -ms-flex-align: center;\n        -webkit-align-items: center;\n        align-items: center;\n    }\n    </style>\n</head>\n<body>\n    <!-- Swiper -->\n    <div class=\"swiper-container\">\n        <div class=\"swiper-wrapper\">\n            <div class=\"swiper-slide\" data-hash=\"slide1\">Slide 1</div>\n            <div class=\"swiper-slide\" data-hash=\"slide2\">Slide 2</div>\n            <div class=\"swiper-slide\" data-hash=\"slide3\">Slide 3</div>\n            <div class=\"swiper-slide\" data-hash=\"slide4\">Slide 4</div>\n            <div class=\"swiper-slide\" data-hash=\"slide5\">Slide 5</div>\n            <div class=\"swiper-slide\" data-hash=\"slide6\">Slide 6</div>\n            <div class=\"swiper-slide\" data-hash=\"slide7\">Slide 7</div>\n            <div class=\"swiper-slide\" data-hash=\"slide8\">Slide 8</div>\n            <div class=\"swiper-slide\" data-hash=\"slide9\">Slide 9</div>\n            <div class=\"swiper-slide\" data-hash=\"slide10\">Slide 10</div>\n        </div>\n        <!-- Add Pagination -->\n        <div class=\"swiper-pagination\"></div>\n        <!-- Add Arrows -->\n        <div class=\"swiper-button-next\"></div>\n        <div class=\"swiper-button-prev\"></div>\n    </div>\n\n    <!-- Swiper JS -->\n    <script src=\"../dist/js/swiper.min.js\"></script>\n\n    <!-- Initialize Swiper -->\n    <script>\n    var swiper = new Swiper('.swiper-container', {\n        pagination: '.swiper-pagination',\n        paginationClickable: true,\n        nextButton: '.swiper-button-next',\n        prevButton: '.swiper-button-prev',\n        spaceBetween: 30,\n        hashnav: true\n    });\n    </script>\n</body>\n</html>"
  },
  {
    "path": "app_frontend/static/plugin/Swiper-3.3.1/demos/26-rtl.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n    <meta charset=\"utf-8\">\n    <title>Swiper demo</title>\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1, minimum-scale=1, maximum-scale=1\">\n\n    <!-- Link Swiper's CSS -->\n    <link rel=\"stylesheet\" href=\"../dist/css/swiper.min.css\">\n\n    <!-- Demo styles -->\n    <style>\n    html, body {\n        position: relative;\n        height: 100%;\n    }\n    body {\n        background: #eee;\n        font-family: Helvetica Neue, Helvetica, Arial, sans-serif;\n        font-size: 14px;\n        color:#000;\n        margin: 0;\n        padding: 0;\n    }\n    .swiper-container {\n        width: 100%;\n        height: 100%;\n    }\n    .swiper-slide {\n        text-align: center;\n        font-size: 18px;\n        background: #fff;\n\n        /* Center slide text vertically */\n        display: -webkit-box;\n        display: -ms-flexbox;\n        display: -webkit-flex;\n        display: flex;\n        -webkit-box-pack: center;\n        -ms-flex-pack: center;\n        -webkit-justify-content: center;\n        justify-content: center;\n        -webkit-box-align: center;\n        -ms-flex-align: center;\n        -webkit-align-items: center;\n        align-items: center;\n    }\n    </style>\n</head>\n<body>\n    <!-- Swiper -->\n    <div class=\"swiper-container\" dir=\"rtl\">\n        <div class=\"swiper-wrapper\">\n            <div class=\"swiper-slide\">Slide 1</div>\n            <div class=\"swiper-slide\">Slide 2</div>\n            <div class=\"swiper-slide\">Slide 3</div>\n            <div class=\"swiper-slide\">Slide 4</div>\n            <div class=\"swiper-slide\">Slide 5</div>\n            <div class=\"swiper-slide\">Slide 6</div>\n            <div class=\"swiper-slide\">Slide 7</div>\n            <div class=\"swiper-slide\">Slide 8</div>\n            <div class=\"swiper-slide\">Slide 9</div>\n            <div class=\"swiper-slide\">Slide 10</div>\n        </div>\n        <!-- Add Pagination -->\n        <div class=\"swiper-pagination\"></div>\n        <!-- Add Navigation -->\n        <div class=\"swiper-button-prev\"></div>\n        <div class=\"swiper-button-next\"></div>\n    </div>\n\n    <!-- Swiper JS -->\n    <script src=\"../dist/js/swiper.min.js\"></script>\n\n    <!-- Initialize Swiper -->\n    <script>\n    var swiper = new Swiper('.swiper-container', {\n        pagination: '.swiper-pagination',\n        paginationClickable: true,\n        nextButton: '.swiper-button-next',\n        prevButton: '.swiper-button-prev'\n    });\n    </script>\n</body>\n</html>"
  },
  {
    "path": "app_frontend/static/plugin/Swiper-3.3.1/demos/27-jquery.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n    <meta charset=\"utf-8\">\n    <title>Swiper demo</title>\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1, minimum-scale=1, maximum-scale=1\">\n\n    <!-- Link Swiper's CSS -->\n    <link rel=\"stylesheet\" href=\"../dist/css/swiper.min.css\">\n\n    <!-- Demo styles -->\n    <style>\n    html, body {\n        position: relative;\n        height: 100%;\n    }\n    body {\n        background: #eee;\n        font-family: Helvetica Neue, Helvetica, Arial, sans-serif;\n        font-size: 14px;\n        color:#000;\n        margin: 0;\n        padding: 0;\n    }\n    .swiper-container {\n        width: 100%;\n        height: 100%;\n    }\n    .swiper-slide {\n        text-align: center;\n        font-size: 18px;\n        background: #fff;\n\n        /* Center slide text vertically */\n        display: -webkit-box;\n        display: -ms-flexbox;\n        display: -webkit-flex;\n        display: flex;\n        -webkit-box-pack: center;\n        -ms-flex-pack: center;\n        -webkit-justify-content: center;\n        justify-content: center;\n        -webkit-box-align: center;\n        -ms-flex-align: center;\n        -webkit-align-items: center;\n        align-items: center;\n    }\n    </style>\n</head>\n<body>\n    <!-- Swiper -->\n    <div class=\"swiper-container\">\n        <div class=\"swiper-wrapper\">\n            <div class=\"swiper-slide\">Slide 1</div>\n            <div class=\"swiper-slide\">Slide 2</div>\n            <div class=\"swiper-slide\">Slide 3</div>\n            <div class=\"swiper-slide\">Slide 4</div>\n            <div class=\"swiper-slide\">Slide 5</div>\n            <div class=\"swiper-slide\">Slide 6</div>\n            <div class=\"swiper-slide\">Slide 7</div>\n            <div class=\"swiper-slide\">Slide 8</div>\n            <div class=\"swiper-slide\">Slide 9</div>\n            <div class=\"swiper-slide\">Slide 10</div>\n        </div>\n        <!-- Add Pagination -->\n        <div class=\"swiper-pagination\"></div>\n        <!-- Add Navigation -->\n        <div class=\"swiper-button-prev\"></div>\n        <div class=\"swiper-button-next\"></div>\n    </div>\n\n    <!-- jQuery -->\n    <script src=\"http://code.jquery.com/jquery-2.1.3.min.js\"></script>\n    <!-- Swiper JS -->\n    <script src=\"../dist/js/swiper.jquery.min.js\"></script>\n\n    <!-- Initialize Swiper -->\n    <script>\n    var swiper = new Swiper('.swiper-container', {\n        pagination: '.swiper-pagination',\n        paginationClickable: true,\n        nextButton: '.swiper-button-next',\n        prevButton: '.swiper-button-prev'\n    });\n    </script>\n</body>\n</html>"
  },
  {
    "path": "app_frontend/static/plugin/Swiper-3.3.1/demos/28-parallax.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n    <meta charset=\"utf-8\">\n    <title>Swiper demo</title>\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1, minimum-scale=1, maximum-scale=1\">\n\n    <!-- Link Swiper's CSS -->\n    <link rel=\"stylesheet\" href=\"../dist/css/swiper.min.css\">\n\n    <!-- Demo styles -->\n    <style>\n    html, body {\n        position: relative;\n        height: 100%;\n    }\n    body {\n        background: #eee;\n        font-family: Helvetica Neue, Helvetica, Arial, sans-serif;\n        font-size: 14px;\n        color:#000;\n        margin: 0;\n        padding: 0;\n    }\n    .swiper-container {\n        width: 100%;\n        height: 100%;\n        background: #000;\n    }\n    .swiper-slide {\n        font-size: 18px;\n        color:#fff;\n        -webkit-box-sizing: border-box;\n        box-sizing: border-box;\n        padding: 40px 60px;\n    }\n    .parallax-bg {\n        position: absolute;\n        left: 0;\n        top: 0;\n        width: 130%;\n        height: 100%;\n        -webkit-background-size: cover;\n        background-size: cover;\n        background-position: center;\n    }\n    .swiper-slide .title {\n        font-size: 41px;\n        font-weight: 300;\n    }\n    .swiper-slide .subtitle {\n        font-size: 21px;\n    }\n    .swiper-slide .text {\n        font-size: 14px;\n        max-width: 400px;\n        line-height: 1.3;\n    }\n    \n    </style>\n</head>\n<body>\n    <!-- Swiper -->\n    <div class=\"swiper-container\">\n        <div class=\"parallax-bg\" style=\"background-image:url(http://lorempixel.com/900/600/nightlife/2/)\" data-swiper-parallax=\"-23%\"></div>\n        <div class=\"swiper-wrapper\">\n            <div class=\"swiper-slide\">\n                <div class=\"title\" data-swiper-parallax=\"-100\">Slide 1</div>\n                <div class=\"subtitle\" data-swiper-parallax=\"-200\">Subtitle</div>\n                <div class=\"text\" data-swiper-parallax=\"-300\">\n                    <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aliquam dictum mattis velit, sit amet faucibus felis iaculis nec. Nulla laoreet justo vitae porttitor porttitor. Suspendisse in sem justo. Integer laoreet magna nec elit suscipit, ac laoreet nibh euismod. Aliquam hendrerit lorem at elit facilisis rutrum. Ut at ullamcorper velit. Nulla ligula nisi, imperdiet ut lacinia nec, tincidunt ut libero. Aenean feugiat non eros quis feugiat.</p>\n                </div>\n            </div>\n            <div class=\"swiper-slide\">\n                <div class=\"title\" data-swiper-parallax=\"-100\">Slide 2</div>\n                <div class=\"subtitle\" data-swiper-parallax=\"-200\">Subtitle</div>\n                <div class=\"text\" data-swiper-parallax=\"-300\">\n                    <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aliquam dictum mattis velit, sit amet faucibus felis iaculis nec. Nulla laoreet justo vitae porttitor porttitor. Suspendisse in sem justo. Integer laoreet magna nec elit suscipit, ac laoreet nibh euismod. Aliquam hendrerit lorem at elit facilisis rutrum. Ut at ullamcorper velit. Nulla ligula nisi, imperdiet ut lacinia nec, tincidunt ut libero. Aenean feugiat non eros quis feugiat.</p>\n                </div>\n            </div>\n            <div class=\"swiper-slide\">\n                <div class=\"title\" data-swiper-parallax=\"-100\">Slide 3</div>\n                <div class=\"subtitle\" data-swiper-parallax=\"-200\">Subtitle</div>\n                <div class=\"text\" data-swiper-parallax=\"-300\">\n                    <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aliquam dictum mattis velit, sit amet faucibus felis iaculis nec. Nulla laoreet justo vitae porttitor porttitor. Suspendisse in sem justo. Integer laoreet magna nec elit suscipit, ac laoreet nibh euismod. Aliquam hendrerit lorem at elit facilisis rutrum. Ut at ullamcorper velit. Nulla ligula nisi, imperdiet ut lacinia nec, tincidunt ut libero. Aenean feugiat non eros quis feugiat.</p>\n                </div>\n            </div>\n        </div>\n        <!-- Add Pagination -->\n        <div class=\"swiper-pagination swiper-pagination-white\"></div>\n        <!-- Add Navigation -->\n        <div class=\"swiper-button-prev swiper-button-white\"></div>\n        <div class=\"swiper-button-next swiper-button-white\"></div>\n    </div>\n\n    <!-- Swiper JS -->\n    <script src=\"../dist/js/swiper.min.js\"></script>\n\n    <!-- Initialize Swiper -->\n    <script>\n    var swiper = new Swiper('.swiper-container', {\n        pagination: '.swiper-pagination',\n        paginationClickable: true,\n        nextButton: '.swiper-button-next',\n        prevButton: '.swiper-button-prev',\n        parallax: true,\n        speed: 600,\n    });\n    </script>\n</body>\n</html>"
  },
  {
    "path": "app_frontend/static/plugin/Swiper-3.3.1/demos/29-custom-pagination.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n    <meta charset=\"utf-8\">\n    <title>Swiper demo</title>\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1, minimum-scale=1, maximum-scale=1\">\n\n    <!-- Link Swiper's CSS -->\n    <link rel=\"stylesheet\" href=\"../dist/css/swiper.min.css\">\n\n    <!-- Demo styles -->\n    <style>\n    html, body {\n        position: relative;\n        height: 100%;\n    }\n    body {\n        background: #eee;\n        font-family: Helvetica Neue, Helvetica, Arial, sans-serif;\n        font-size: 14px;\n        color:#000;\n        margin: 0;\n        padding: 0;\n    }\n    .swiper-container {\n        width: 100%;\n        height: 100%;\n    }\n    .swiper-slide {\n        text-align: center;\n        font-size: 18px;\n        background: #fff;\n\n        /* Center slide text vertically */\n        display: -webkit-box;\n        display: -ms-flexbox;\n        display: -webkit-flex;\n        display: flex;\n        -webkit-box-pack: center;\n        -ms-flex-pack: center;\n        -webkit-justify-content: center;\n        justify-content: center;\n        -webkit-box-align: center;\n        -ms-flex-align: center;\n        -webkit-align-items: center;\n        align-items: center;\n    }\n    .swiper-pagination-bullet {\n        width: 20px;\n        height: 20px;\n        text-align: center;\n        line-height: 20px;\n        font-size: 12px;\n        color:#000;\n        opacity: 1;\n        background: rgba(0,0,0,0.2);\n    }\n    .swiper-pagination-bullet-active {\n        color:#fff;\n        background: #007aff;\n    }\n    </style>\n</head>\n<body>\n    <!-- Swiper -->\n    <div class=\"swiper-container\">\n        <div class=\"swiper-wrapper\">\n            <div class=\"swiper-slide\">Slide 1</div>\n            <div class=\"swiper-slide\">Slide 2</div>\n            <div class=\"swiper-slide\">Slide 3</div>\n            <div class=\"swiper-slide\">Slide 4</div>\n            <div class=\"swiper-slide\">Slide 5</div>\n            <div class=\"swiper-slide\">Slide 6</div>\n            <div class=\"swiper-slide\">Slide 7</div>\n            <div class=\"swiper-slide\">Slide 8</div>\n            <div class=\"swiper-slide\">Slide 9</div>\n            <div class=\"swiper-slide\">Slide 10</div>\n        </div>\n        <!-- Add Pagination -->\n        <div class=\"swiper-pagination\"></div>\n    </div>\n\n    <!-- Swiper JS -->\n    <script src=\"../dist/js/swiper.min.js\"></script>\n\n    <!-- Initialize Swiper -->\n    <script>\n    var swiper = new Swiper('.swiper-container', {\n        pagination: '.swiper-pagination',\n        paginationClickable: true,\n        paginationBulletRender: function (index, className) {\n            return '<span class=\"' + className + '\">' + (index + 1) + '</span>';\n        }\n    });\n    </script>\n</body>\n</html>"
  },
  {
    "path": "app_frontend/static/plugin/Swiper-3.3.1/demos/30-lazy-load-images.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n    <meta charset=\"utf-8\">\n    <title>Swiper demo</title>\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1, minimum-scale=1, maximum-scale=1\">\n\n    <!-- Link Swiper's CSS -->\n    <link rel=\"stylesheet\" href=\"../dist/css/swiper.min.css\">\n\n    <!-- Demo styles -->\n    <style>\n    html, body {\n        position: relative;\n        height: 100%;\n    }\n    body {\n        background: #000;\n        font-family: Helvetica Neue, Helvetica, Arial, sans-serif;\n        font-size: 14px;\n        color:#000;\n        margin: 0;\n        padding: 0;\n    }\n    .swiper-container {\n        width: 100%;\n        height: 100%;\n    }\n    .swiper-slide {\n        text-align: center;\n        font-size: 18px;\n        background: #000;\n        \n    }\n    .swiper-slide img {\n      width: auto;\n      height: auto;\n      max-width: 100%;\n      max-height: 100%;\n      -ms-transform: translate(-50%, -50%);\n      -webkit-transform: translate(-50%, -50%);\n      -moz-transform: translate(-50%, -50%);\n      transform: translate(-50%, -50%);\n      position: absolute;\n      left: 50%;\n      top: 50%;\n    }\n    </style>\n</head>\n<body>\n    <!-- Swiper -->\n    <div class=\"swiper-container\">\n        <div class=\"swiper-wrapper\">\n            <div class=\"swiper-slide\">\n                <!-- Required swiper-lazy class and image source specified in data-src attribute -->\n                <img data-src=\"http://lorempixel.com/1600/1200/nature/1\" class=\"swiper-lazy\">\n                <!-- Preloader image -->\n                <div class=\"swiper-lazy-preloader swiper-lazy-preloader-white\"></div>\n            </div>\n            <div class=\"swiper-slide\">\n                <img data-src=\"http://lorempixel.com/1600/1200/nature/2\" class=\"swiper-lazy\">\n                <div class=\"swiper-lazy-preloader swiper-lazy-preloader-white\"></div>\n            </div>\n            <div class=\"swiper-slide\">\n                <img data-src=\"http://lorempixel.com/1600/1200/nature/3\" class=\"swiper-lazy\">\n                <div class=\"swiper-lazy-preloader swiper-lazy-preloader-white\"></div>\n            </div>\n            <div class=\"swiper-slide\">\n                <img data-src=\"http://lorempixel.com/1600/1200/nature/4\" class=\"swiper-lazy\">\n                <div class=\"swiper-lazy-preloader swiper-lazy-preloader-white\"></div>\n            </div>\n            <div class=\"swiper-slide\">\n                <img data-src=\"http://lorempixel.com/1600/1200/nature/5\" class=\"swiper-lazy\">\n                <div class=\"swiper-lazy-preloader swiper-lazy-preloader-white\"></div>\n            </div>\n            <div class=\"swiper-slide\">\n                <img data-src=\"http://lorempixel.com/1600/1200/nature/6\" class=\"swiper-lazy\">\n                <div class=\"swiper-lazy-preloader swiper-lazy-preloader-white\"></div>\n            </div>\n            \n        </div>\n        <!-- Add Pagination -->\n        <div class=\"swiper-pagination swiper-pagination-white\"></div>\n        <!-- Navigation -->\n        <div class=\"swiper-button-next swiper-button-white\"></div>\n        <div class=\"swiper-button-prev swiper-button-white\"></div>\n    </div>\n\n    <!-- Swiper JS -->\n    <script src=\"../dist/js/swiper.min.js\"></script>\n\n    <!-- Initialize Swiper -->\n    <script>\n    var swiper = new Swiper('.swiper-container', {\n        nextButton: '.swiper-button-next',\n        prevButton: '.swiper-button-prev',\n        pagination: '.swiper-pagination',\n        paginationClickable: true,\n        // Disable preloading of all images\n        preloadImages: false,\n        // Enable lazy loading\n        lazyLoading: true\n    });\n    </script>\n</body>\n</html>"
  },
  {
    "path": "app_frontend/static/plugin/Swiper-3.3.1/demos/31-custom-plugin.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n    <meta charset=\"utf-8\">\n    <title>Swiper demo</title>\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1, minimum-scale=1, maximum-scale=1\">\n\n    <!-- Link Swiper's CSS -->\n    <link rel=\"stylesheet\" href=\"../dist/css/swiper.min.css\">\n\n    <!-- Demo styles -->\n    <style>\n    html, body {\n        position: relative;\n        height: 100%;\n    }\n    body {\n        background: #eee;\n        font-family: Helvetica Neue, Helvetica, Arial, sans-serif;\n        font-size: 14px;\n        color:#000;\n        margin: 0;\n        padding: 0;\n    }\n    .swiper-container {\n        width: 100%;\n        height: 100%;\n    }\n    .swiper-slide {\n        text-align: center;\n        font-size: 18px;\n        background: #fff;\n\n        /* Center slide text vertically */\n        display: -webkit-box;\n        display: -ms-flexbox;\n        display: -webkit-flex;\n        display: flex;\n        -webkit-box-pack: center;\n        -ms-flex-pack: center;\n        -webkit-justify-content: center;\n        justify-content: center;\n        -webkit-box-align: center;\n        -ms-flex-align: center;\n        -webkit-align-items: center;\n        align-items: center;\n    }\n    </style>\n</head>\n<body>\n    <!-- Swiper -->\n    <div class=\"swiper-container\">\n        <div class=\"swiper-wrapper\">\n            <div class=\"swiper-slide\">Slide 1</div>\n            <div class=\"swiper-slide\">Slide 2</div>\n            <div class=\"swiper-slide\">Slide 3</div>\n            <div class=\"swiper-slide\">Slide 4</div>\n            <div class=\"swiper-slide\">Slide 5</div>\n            <div class=\"swiper-slide\">Slide 6</div>\n            <div class=\"swiper-slide\">Slide 7</div>\n            <div class=\"swiper-slide\">Slide 8</div>\n            <div class=\"swiper-slide\">Slide 9</div>\n            <div class=\"swiper-slide\">Slide 10</div>\n        </div>\n        <!-- Add Pagination -->\n        <div class=\"swiper-pagination\"></div>\n        <!-- Add Navigation -->\n        <div class=\"swiper-button-prev\"></div>\n        <div class=\"swiper-button-next\"></div>\n    </div>\n\n    <!-- Swiper JS -->\n    <script src=\"../dist/js/swiper.min.js\"></script>\n\n    <!-- Include plugin after Swiper -->\n    <script>\n    /* ========\n    Debugger plugin, simple demo plugin to console.log some of callbacks\n    ======== */\n    Swiper.prototype.plugins.debugger = function (swiper, params) {\n        if (!params) return;\n        // Need to return object with properties that names are the same as callbacks\n        return {\n            onInit: function (swiper){\n                console.log('onInit');\n            },\n            onClick: function (swiper, e) {\n                console.log('onClick');\n            },\n            onTap: function (swiper, e) {\n                console.log('onTap');\n            },\n            onDoubleTap: function (swiper, e) {\n                console.log('onDoubleTap');\n            },\n            onSliderMove: function (swiper, e) {\n                console.log('onSliderMove');\n            },\n            onSlideChangeStart: function (swiper) {\n                console.log('onSlideChangeStart');\n            },\n            onSlideChangeEnd: function (swiper) {\n                console.log('onSlideChangeEnd');\n            },\n            onTransitionStart: function (swiper) {\n                console.log('onTransitionStart');\n            },\n            onTransitionEnd: function (swiper) {\n                console.log('onTransitionEnd');\n            },\n            onReachBeginning: function (swiper) {\n                console.log('onReachBeginning');\n            },\n            onReachEnd: function (swiper) {\n                console.log('onReachEnd');\n            }\n        };\n    };\n    </script>\n\n    <!-- Initialize Swiper -->\n    <script>\n    var swiper = new Swiper('.swiper-container', {\n        pagination: '.swiper-pagination',\n        paginationClickable: true,\n        nextButton: '.swiper-button-next',\n        prevButton: '.swiper-button-prev',\n        // Enable debugger\n        debugger: true\n    });\n    </script>\n</body>\n</html>"
  },
  {
    "path": "app_frontend/static/plugin/Swiper-3.3.1/demos/32-scroll-container.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n    <meta charset=\"utf-8\">\n    <title>Swiper demo</title>\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1, minimum-scale=1, maximum-scale=1\">\n\n    <!-- Link Swiper's CSS -->\n    <link rel=\"stylesheet\" href=\"../dist/css/swiper.min.css\">\n\n    <!-- Demo styles -->\n    <style>\n    html, body {\n        position: relative;\n        height: 100%;\n    }\n    body {\n        background: #fff;\n        font-family: Helvetica Neue, Helvetica, Arial, sans-serif;\n        font-size: 14px;\n        color:#000;\n        margin: 0;\n        padding: 0;\n    }\n    .swiper-container {\n        width: 100%;\n        height: 100%;\n    }\n    .swiper-slide {\n        font-size: 18px;\n        height: auto;\n        -webkit-box-sizing: border-box;\n        box-sizing: border-box;\n        padding: 30px;\n    }\n    </style>\n</head>\n<body>\n    <!-- Swiper -->\n    <div class=\"swiper-container\">\n        <div class=\"swiper-wrapper\">\n            <div class=\"swiper-slide\">\n                <h4>Scroll Container</h4>\n                <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. In luctus, ex eu sagittis faucibus, ligula ipsum sagittis magna, et imperdiet dolor lectus eu libero. Vestibulum venenatis eget turpis sed faucibus. Maecenas in ullamcorper orci, eu ullamcorper sem. Etiam elit ante, luctus non ante sit amet, sodales vulputate odio. Aenean tristique nisl tellus, sit amet fringilla nisl volutpat cursus. Quisque dignissim lectus ac nunc consectetur mattis. Proin vel hendrerit ipsum, et lobortis dolor. Vestibulum convallis, nibh et tincidunt tristique, nisl risus facilisis lectus, ut interdum orci nisl ac nunc. Cras et aliquam felis. Quisque vel ipsum at elit sodales posuere eget non est. Fusce convallis vestibulum dolor non volutpat. Vivamus vestibulum quam ut ultricies pretium.</p>\n                <p>Suspendisse rhoncus fringilla nisl. Mauris eget lorem ac urna consectetur convallis non vel mi. Donec libero dolor, volutpat ut urna sit amet, aliquet molestie purus. Phasellus faucibus, leo vel scelerisque lobortis, ipsum leo sollicitudin metus, eget sagittis ante orci eu ipsum. Nulla ac mauris eu risus sagittis scelerisque iaculis bibendum mauris. Cras ut egestas orci. Cras odio risus, sagittis ut nunc vitae, aliquam consectetur purus. Vivamus ornare nunc vel tellus facilisis, quis dictum elit tincidunt. Donec accumsan nisi at laoreet sodales. Cras at ullamcorper massa. Maecenas at facilisis ex. Nam mollis dignissim purus id efficitur.</p>\n                <p>Curabitur eget aliquam erat. Curabitur a neque vitae purus volutpat elementum. Vivamus quis vestibulum leo, efficitur ullamcorper velit. Integer tincidunt finibus metus vel porta. Mauris sed mauris congue, pretium est nec, malesuada purus. Nulla hendrerit consectetur arcu et lacinia. Suspendisse augue justo, convallis eget arcu in, pretium tempor ligula. Nullam vulputate tincidunt est ut ullamcorper.</p>\n                <p>Curabitur sed sodales leo. Nulla facilisi. Etiam condimentum, nisi id tempor vulputate, nisi justo cursus justo, pellentesque condimentum diam arcu sit amet leo. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. In placerat tellus a posuere vehicula. Donec diam massa, efficitur vitae mattis et, pretium in augue. Fusce iaculis mi quis ante venenatis, sit amet pellentesque orci aliquam. Vestibulum elementum posuere vehicula.</p>\n                <p>Sed tincidunt diam a massa pharetra faucibus. Praesent condimentum id arcu nec fringilla. Maecenas faucibus, ante et venenatis interdum, erat mi eleifend dui, at convallis nisl est nec arcu. Duis vitae arcu rhoncus, faucibus magna ut, tempus metus. Cras in nibh sed ipsum consequat rhoncus. Proin fringilla nulla ut augue tempor fermentum. Nunc hendrerit non nisi vitae finibus. Donec eget ornare libero. Aliquam auctor erat enim, a semper risus semper at. In ut dui in metus tincidunt euismod eget et lacus. Aenean et dictum urna, sed rhoncus lorem. Duis pharetra sagittis odio. Etiam a libero ut nisi feugiat tincidunt vel vitae turpis. Maecenas vel orci sit amet lorem hendrerit venenatis sollicitudin ut dui. Quisque rhoncus nibh in massa pretium scelerisque.</p>\n                <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. In luctus, ex eu sagittis faucibus, ligula ipsum sagittis magna, et imperdiet dolor lectus eu libero. Vestibulum venenatis eget turpis sed faucibus. Maecenas in ullamcorper orci, eu ullamcorper sem. Etiam elit ante, luctus non ante sit amet, sodales vulputate odio. Aenean tristique nisl tellus, sit amet fringilla nisl volutpat cursus. Quisque dignissim lectus ac nunc consectetur mattis. Proin vel hendrerit ipsum, et lobortis dolor. Vestibulum convallis, nibh et tincidunt tristique, nisl risus facilisis lectus, ut interdum orci nisl ac nunc. Cras et aliquam felis. Quisque vel ipsum at elit sodales posuere eget non est. Fusce convallis vestibulum dolor non volutpat. Vivamus vestibulum quam ut ultricies pretium.</p>\n                <p>Suspendisse rhoncus fringilla nisl. Mauris eget lorem ac urna consectetur convallis non vel mi. Donec libero dolor, volutpat ut urna sit amet, aliquet molestie purus. Phasellus faucibus, leo vel scelerisque lobortis, ipsum leo sollicitudin metus, eget sagittis ante orci eu ipsum. Nulla ac mauris eu risus sagittis scelerisque iaculis bibendum mauris. Cras ut egestas orci. Cras odio risus, sagittis ut nunc vitae, aliquam consectetur purus. Vivamus ornare nunc vel tellus facilisis, quis dictum elit tincidunt. Donec accumsan nisi at laoreet sodales. Cras at ullamcorper massa. Maecenas at facilisis ex. Nam mollis dignissim purus id efficitur.</p>\n                <p>Curabitur eget aliquam erat. Curabitur a neque vitae purus volutpat elementum. Vivamus quis vestibulum leo, efficitur ullamcorper velit. Integer tincidunt finibus metus vel porta. Mauris sed mauris congue, pretium est nec, malesuada purus. Nulla hendrerit consectetur arcu et lacinia. Suspendisse augue justo, convallis eget arcu in, pretium tempor ligula. Nullam vulputate tincidunt est ut ullamcorper.</p>\n                <p>Curabitur sed sodales leo. Nulla facilisi. Etiam condimentum, nisi id tempor vulputate, nisi justo cursus justo, pellentesque condimentum diam arcu sit amet leo. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. In placerat tellus a posuere vehicula. Donec diam massa, efficitur vitae mattis et, pretium in augue. Fusce iaculis mi quis ante venenatis, sit amet pellentesque orci aliquam. Vestibulum elementum posuere vehicula.</p>\n                <p>Sed tincidunt diam a massa pharetra faucibus. Praesent condimentum id arcu nec fringilla. Maecenas faucibus, ante et venenatis interdum, erat mi eleifend dui, at convallis nisl est nec arcu. Duis vitae arcu rhoncus, faucibus magna ut, tempus metus. Cras in nibh sed ipsum consequat rhoncus. Proin fringilla nulla ut augue tempor fermentum. Nunc hendrerit non nisi vitae finibus. Donec eget ornare libero. Aliquam auctor erat enim, a semper risus semper at. In ut dui in metus tincidunt euismod eget et lacus. Aenean et dictum urna, sed rhoncus lorem. Duis pharetra sagittis odio. Etiam a libero ut nisi feugiat tincidunt vel vitae turpis. Maecenas vel orci sit amet lorem hendrerit venenatis sollicitudin ut dui. Quisque rhoncus nibh in massa pretium scelerisque.</p>\n            </div>\n        </div>\n        <!-- Add Scroll Bar -->\n        <div class=\"swiper-scrollbar\"></div>\n    </div>\n\n    <!-- Swiper JS -->\n    <script src=\"../dist/js/swiper.min.js\"></script>\n\n    <!-- Initialize Swiper -->\n    <script>\n    var swiper = new Swiper('.swiper-container', {\n        scrollbar: '.swiper-scrollbar',\n        direction: 'vertical',\n        slidesPerView: 'auto',\n        mousewheelControl: true,\n        freeMode: true\n    });\n    </script>\n</body>\n</html>"
  },
  {
    "path": "app_frontend/static/plugin/Swiper-3.3.1/demos/33-responsive-breakpoints.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n    <meta charset=\"utf-8\">\n    <title>Swiper demo</title>\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1, minimum-scale=1, maximum-scale=1\">\n\n    <!-- Link Swiper's CSS -->\n    <link rel=\"stylesheet\" href=\"../dist/css/swiper.min.css\">\n\n    <!-- Demo styles -->\n    <style>\n    html, body {\n        position: relative;\n        height: 100%;\n    }\n    body {\n        background: #eee;\n        font-family: Helvetica Neue, Helvetica, Arial, sans-serif;\n        font-size: 14px;\n        color:#000;\n        margin: 0;\n        padding: 0;\n    }\n    .swiper-container {\n        width: 100%;\n        height: 100%;\n    }\n    .swiper-slide {\n        text-align: center;\n        font-size: 18px;\n        background: #fff;\n\n        /* Center slide text vertically */\n        display: -webkit-box;\n        display: -ms-flexbox;\n        display: -webkit-flex;\n        display: flex;\n        -webkit-box-pack: center;\n        -ms-flex-pack: center;\n        -webkit-justify-content: center;\n        justify-content: center;\n        -webkit-box-align: center;\n        -ms-flex-align: center;\n        -webkit-align-items: center;\n        align-items: center;\n    }\n    </style>\n</head>\n<body>\n    <!-- Swiper -->\n    <div class=\"swiper-container\">\n        <div class=\"swiper-wrapper\">\n            <div class=\"swiper-slide\">Slide 1</div>\n            <div class=\"swiper-slide\">Slide 2</div>\n            <div class=\"swiper-slide\">Slide 3</div>\n            <div class=\"swiper-slide\">Slide 4</div>\n            <div class=\"swiper-slide\">Slide 5</div>\n            <div class=\"swiper-slide\">Slide 6</div>\n            <div class=\"swiper-slide\">Slide 7</div>\n            <div class=\"swiper-slide\">Slide 8</div>\n            <div class=\"swiper-slide\">Slide 9</div>\n            <div class=\"swiper-slide\">Slide 10</div>\n        </div>\n        <!-- Add Pagination -->\n        <div class=\"swiper-pagination\"></div>\n    </div>\n\n    <!-- Swiper JS -->\n    <script src=\"../dist/js/swiper.min.js\"></script>\n\n    <!-- Initialize Swiper -->\n    <script>\n    var swiper = new Swiper('.swiper-container', {\n        pagination: '.swiper-pagination',\n        paginationClickable: true,\n        slidesPerView: 5,\n        spaceBetween: 50,\n        breakpoints: {\n            1024: {\n                slidesPerView: 4,\n                spaceBetween: 40\n            },\n            768: {\n                slidesPerView: 3,\n                spaceBetween: 30\n            },\n            640: {\n                slidesPerView: 2,\n                spaceBetween: 20\n            },\n            320: {\n                slidesPerView: 1,\n                spaceBetween: 10\n            }\n        }\n    });\n    </script>\n</body>\n</html>"
  },
  {
    "path": "app_frontend/static/plugin/Swiper-3.3.1/demos/34-autoheight.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n    <meta charset=\"utf-8\">\n    <title>Swiper demo</title>\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1, minimum-scale=1, maximum-scale=1\">\n\n    <!-- Link Swiper's CSS -->\n    <link rel=\"stylesheet\" href=\"../dist/css/swiper.min.css\">\n\n    <!-- Demo styles -->\n    <style>\n    body {\n        background: #eee;\n        font-family: Helvetica Neue, Helvetica, Arial, sans-serif;\n        font-size: 14px;\n        color:#000;\n        margin: 0;\n        padding: 0;\n    }\n    .swiper-container {\n        width: 100%;\n        height: auto;\n    }\n    .swiper-slide {\n        text-align: center;\n        font-size: 18px;\n        background: #fff;\n\n    }\n    .swiper-container .swiper-slide {\n        height: 300px;\n        line-height: 300px;\n    }\n    .swiper-container .swiper-slide:nth-child(2n) {\n        height: 500px;\n        line-height: 500px;\n    }\n    \n    </style>\n</head>\n<body>\n    <!-- Swiper -->\n    <div class=\"swiper-container\">\n        <div class=\"swiper-wrapper\">\n            <div class=\"swiper-slide\">Slide 1</div>\n            <div class=\"swiper-slide\">Slide 2</div>\n            <div class=\"swiper-slide\">Slide 3</div>\n            <div class=\"swiper-slide\">Slide 4</div>\n            <div class=\"swiper-slide\">Slide 5</div>\n            <div class=\"swiper-slide\">Slide 6</div>\n            <div class=\"swiper-slide\">Slide 7</div>\n            <div class=\"swiper-slide\">Slide 8</div>\n            <div class=\"swiper-slide\">Slide 9</div>\n            <div class=\"swiper-slide\">Slide 10</div>\n        </div>\n        <!-- Add Pagination -->\n        <div class=\"swiper-pagination\"></div>\n        <!-- Add Pagination -->\n        <div class=\"swiper-button-next\"></div>\n        <div class=\"swiper-button-prev\"></div>\n    </div>\n\n    <!-- Swiper JS -->\n    <script src=\"../dist/js/swiper.min.js\"></script>\n\n    <!-- Initialize Swiper -->\n    <script>\n    var swiper = new Swiper('.swiper-container', {\n        pagination: '.swiper-pagination',\n        paginationClickable: true,\n        nextButton: '.swiper-button-next',\n        prevButton: '.swiper-button-prev',\n        autoHeight: true, //enable auto height\n    });\n    </script>\n</body>\n</html>"
  },
  {
    "path": "app_frontend/static/plugin/Swiper-3.3.1/demos/35-effect-flip.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n    <meta charset=\"utf-8\">\n    <title>Swiper demo</title>\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1, minimum-scale=1, maximum-scale=1\">\n\n    <!-- Link Swiper's CSS -->\n    <link rel=\"stylesheet\" href=\"../dist/css/swiper.min.css\">\n\n    <!-- Demo styles -->\n    <style>\n    body {\n        background: #fff;\n        font-family: Helvetica Neue, Helvetica, Arial, sans-serif;\n        font-size: 14px;\n        color:#000;\n        margin: 0;\n        padding: 0;\n    }\n    .swiper-container {\n        width: 300px;\n        height: 300px;\n        padding: 50px;\n    }\n    .swiper-slide {\n        background-position: center;\n        background-size: cover;\n        width: 300px;\n        height: 300px;\n    }\n    </style>\n</head>\n<body>\n    <!-- Swiper -->\n    <div class=\"swiper-container\">\n        <div class=\"swiper-wrapper\">\n            <div class=\"swiper-slide\" style=\"background-image:url(http://lorempixel.com/600/600/nature/1)\"></div>\n            <div class=\"swiper-slide\" style=\"background-image:url(http://lorempixel.com/600/600/nature/2)\"></div>\n            <div class=\"swiper-slide\" style=\"background-image:url(http://lorempixel.com/600/600/nature/3)\"></div>\n            <div class=\"swiper-slide\" style=\"background-image:url(http://lorempixel.com/600/600/nature/4)\"></div>\n            <div class=\"swiper-slide\" style=\"background-image:url(http://lorempixel.com/600/600/nature/5)\"></div>\n            <div class=\"swiper-slide\" style=\"background-image:url(http://lorempixel.com/600/600/nature/6)\"></div>\n        </div>\n\n        <!-- Add Pagination -->\n        <div class=\"swiper-pagination\"></div>\n\n        <!-- Add Arrows -->\n        <div class=\"swiper-button-prev\"></div>\n        <div class=\"swiper-button-next\"></div>\n    </div>\n\n    <!-- Swiper JS -->\n    <script src=\"../dist/js/swiper.min.js\"></script>\n\n    <!-- Initialize Swiper -->\n    <script>\n    var swiper = new Swiper('.swiper-container', {\n        pagination: '.swiper-pagination',\n        effect: 'flip',\n        grabCursor: true,\n        nextButton: '.swiper-button-next',\n        prevButton: '.swiper-button-prev'\n    });\n    </script>\n</body>\n</html>"
  },
  {
    "path": "app_frontend/static/plugin/Swiper-3.3.1/demos/36-pagination-fraction.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n    <meta charset=\"utf-8\">\n    <title>Swiper demo</title>\n    <!-- Link Swiper's CSS -->\n    <link rel=\"stylesheet\" href=\"../dist/css/swiper.min.css\">\n\n    <!-- Demo styles -->\n    <style>\n    body {\n        background: #eee;\n        font-family: Helvetica Neue, Helvetica, Arial, sans-serif;\n        font-size: 14px;\n        color:#000;\n        margin: 0;\n        padding: 0;\n    }\n    .swiper-container {\n        width: 500px;\n        height: 300px;\n        margin: 20px auto;\n    }\n    .swiper-slide {\n        text-align: center;\n        font-size: 18px;\n        background: #fff;\n        line-height: 300px;\n    }\n    </style>\n</head>\n<body>\n    <!-- Swiper -->\n    <div class=\"swiper-container\">\n        <div class=\"swiper-wrapper\">\n            <div class=\"swiper-slide\">Slide 1</div>\n            <div class=\"swiper-slide\">Slide 2</div>\n            <div class=\"swiper-slide\">Slide 3</div>\n            <div class=\"swiper-slide\">Slide 4</div>\n            <div class=\"swiper-slide\">Slide 5</div>\n            <div class=\"swiper-slide\">Slide 6</div>\n            <div class=\"swiper-slide\">Slide 7</div>\n            <div class=\"swiper-slide\">Slide 8</div>\n            <div class=\"swiper-slide\">Slide 9</div>\n            <div class=\"swiper-slide\">Slide 10</div>\n        </div>\n        <!-- Add Pagination -->\n        <div class=\"swiper-pagination\"></div>\n        <!-- Add Arrows -->\n        <div class=\"swiper-button-next\"></div>\n        <div class=\"swiper-button-prev\"></div>\n    </div>\n\n    <!-- Swiper JS -->\n    <script src=\"../dist/js/swiper.min.js\"></script>\n\n    <!-- Initialize Swiper -->\n    <script>\n    var swiper = new Swiper('.swiper-container', {\n        nextButton: '.swiper-button-next',\n        prevButton: '.swiper-button-prev',\n        pagination: '.swiper-pagination',\n        paginationType: 'fraction'\n    });\n    </script>\n</body>\n</html>"
  },
  {
    "path": "app_frontend/static/plugin/Swiper-3.3.1/demos/37-pagination-progress.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n    <meta charset=\"utf-8\">\n    <title>Swiper demo</title>\n    <!-- Link Swiper's CSS -->\n    <link rel=\"stylesheet\" href=\"../dist/css/swiper.min.css\">\n\n    <!-- Demo styles -->\n    <style>\n    body {\n        background: #eee;\n        font-family: Helvetica Neue, Helvetica, Arial, sans-serif;\n        font-size: 14px;\n        color:#000;\n        margin: 0;\n        padding: 0;\n    }\n    .swiper-container {\n        width: 500px;\n        height: 300px;\n        margin: 20px auto;\n    }\n    .swiper-slide {\n        text-align: center;\n        font-size: 18px;\n        background: #fff;\n        line-height: 300px;\n    }\n    </style>\n</head>\n<body>\n    <!-- Swiper -->\n    <div class=\"swiper-container\">\n        <div class=\"swiper-wrapper\">\n            <div class=\"swiper-slide\">Slide 1</div>\n            <div class=\"swiper-slide\">Slide 2</div>\n            <div class=\"swiper-slide\">Slide 3</div>\n            <div class=\"swiper-slide\">Slide 4</div>\n            <div class=\"swiper-slide\">Slide 5</div>\n            <div class=\"swiper-slide\">Slide 6</div>\n            <div class=\"swiper-slide\">Slide 7</div>\n            <div class=\"swiper-slide\">Slide 8</div>\n            <div class=\"swiper-slide\">Slide 9</div>\n            <div class=\"swiper-slide\">Slide 10</div>\n        </div>\n        <!-- Add Pagination -->\n        <div class=\"swiper-pagination\"></div>\n        <!-- Add Arrows -->\n        <div class=\"swiper-button-next\"></div>\n        <div class=\"swiper-button-prev\"></div>\n    </div>\n\n    <!-- Swiper JS -->\n    <script src=\"../dist/js/swiper.min.js\"></script>\n\n    <!-- Initialize Swiper -->\n    <script>\n    var swiper = new Swiper('.swiper-container', {\n        nextButton: '.swiper-button-next',\n        prevButton: '.swiper-button-prev',\n        pagination: '.swiper-pagination',\n        paginationType: 'progress'\n    });\n    </script>\n</body>\n</html>"
  },
  {
    "path": "app_frontend/static/plugin/Swiper-3.3.1/dist/css/swiper.css",
    "content": "/**\n * Swiper 3.3.1\n * Most modern mobile touch slider and framework with hardware accelerated transitions\n * \n * http://www.idangero.us/swiper/\n * \n * Copyright 2016, Vladimir Kharlampidi\n * The iDangero.us\n * http://www.idangero.us/\n * \n * Licensed under MIT\n * \n * Released on: February 7, 2016\n */\n.swiper-container {\n  margin: 0 auto;\n  position: relative;\n  overflow: hidden;\n  /* Fix of Webkit flickering */\n  z-index: 1;\n}\n.swiper-container-no-flexbox .swiper-slide {\n  float: left;\n}\n.swiper-container-vertical > .swiper-wrapper {\n  -webkit-box-orient: vertical;\n  -moz-box-orient: vertical;\n  -ms-flex-direction: column;\n  -webkit-flex-direction: column;\n  flex-direction: column;\n}\n.swiper-wrapper {\n  position: relative;\n  width: 100%;\n  height: 100%;\n  z-index: 1;\n  display: -webkit-box;\n  display: -moz-box;\n  display: -ms-flexbox;\n  display: -webkit-flex;\n  display: flex;\n  -webkit-transition-property: -webkit-transform;\n  -moz-transition-property: -moz-transform;\n  -o-transition-property: -o-transform;\n  -ms-transition-property: -ms-transform;\n  transition-property: transform;\n  -webkit-box-sizing: content-box;\n  -moz-box-sizing: content-box;\n  box-sizing: content-box;\n}\n.swiper-container-android .swiper-slide,\n.swiper-wrapper {\n  -webkit-transform: translate3d(0px, 0, 0);\n  -moz-transform: translate3d(0px, 0, 0);\n  -o-transform: translate(0px, 0px);\n  -ms-transform: translate3d(0px, 0, 0);\n  transform: translate3d(0px, 0, 0);\n}\n.swiper-container-multirow > .swiper-wrapper {\n  -webkit-box-lines: multiple;\n  -moz-box-lines: multiple;\n  -ms-flex-wrap: wrap;\n  -webkit-flex-wrap: wrap;\n  flex-wrap: wrap;\n}\n.swiper-container-free-mode > .swiper-wrapper {\n  -webkit-transition-timing-function: ease-out;\n  -moz-transition-timing-function: ease-out;\n  -ms-transition-timing-function: ease-out;\n  -o-transition-timing-function: ease-out;\n  transition-timing-function: ease-out;\n  margin: 0 auto;\n}\n.swiper-slide {\n  -webkit-flex-shrink: 0;\n  -ms-flex: 0 0 auto;\n  flex-shrink: 0;\n  width: 100%;\n  height: 100%;\n  position: relative;\n}\n/* Auto Height */\n.swiper-container-autoheight,\n.swiper-container-autoheight .swiper-slide {\n  height: auto;\n}\n.swiper-container-autoheight .swiper-wrapper {\n  -webkit-box-align: start;\n  -ms-flex-align: start;\n  -webkit-align-items: flex-start;\n  align-items: flex-start;\n  -webkit-transition-property: -webkit-transform, height;\n  -moz-transition-property: -moz-transform;\n  -o-transition-property: -o-transform;\n  -ms-transition-property: -ms-transform;\n  transition-property: transform, height;\n}\n/* a11y */\n.swiper-container .swiper-notification {\n  position: absolute;\n  left: 0;\n  top: 0;\n  pointer-events: none;\n  opacity: 0;\n  z-index: -1000;\n}\n/* IE10 Windows Phone 8 Fixes */\n.swiper-wp8-horizontal {\n  -ms-touch-action: pan-y;\n  touch-action: pan-y;\n}\n.swiper-wp8-vertical {\n  -ms-touch-action: pan-x;\n  touch-action: pan-x;\n}\n/* Arrows */\n.swiper-button-prev,\n.swiper-button-next {\n  position: absolute;\n  top: 50%;\n  width: 27px;\n  height: 44px;\n  margin-top: -22px;\n  z-index: 10;\n  cursor: pointer;\n  -moz-background-size: 27px 44px;\n  -webkit-background-size: 27px 44px;\n  background-size: 27px 44px;\n  background-position: center;\n  background-repeat: no-repeat;\n}\n.swiper-button-prev.swiper-button-disabled,\n.swiper-button-next.swiper-button-disabled {\n  opacity: 0.35;\n  cursor: auto;\n  pointer-events: none;\n}\n.swiper-button-prev,\n.swiper-container-rtl .swiper-button-next {\n  background-image: url(\"data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20viewBox%3D'0%200%2027%2044'%3E%3Cpath%20d%3D'M0%2C22L22%2C0l2.1%2C2.1L4.2%2C22l19.9%2C19.9L22%2C44L0%2C22L0%2C22L0%2C22z'%20fill%3D'%23007aff'%2F%3E%3C%2Fsvg%3E\");\n  left: 10px;\n  right: auto;\n}\n.swiper-button-prev.swiper-button-black,\n.swiper-container-rtl .swiper-button-next.swiper-button-black {\n  background-image: url(\"data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20viewBox%3D'0%200%2027%2044'%3E%3Cpath%20d%3D'M0%2C22L22%2C0l2.1%2C2.1L4.2%2C22l19.9%2C19.9L22%2C44L0%2C22L0%2C22L0%2C22z'%20fill%3D'%23000000'%2F%3E%3C%2Fsvg%3E\");\n}\n.swiper-button-prev.swiper-button-white,\n.swiper-container-rtl .swiper-button-next.swiper-button-white {\n  background-image: url(\"data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20viewBox%3D'0%200%2027%2044'%3E%3Cpath%20d%3D'M0%2C22L22%2C0l2.1%2C2.1L4.2%2C22l19.9%2C19.9L22%2C44L0%2C22L0%2C22L0%2C22z'%20fill%3D'%23ffffff'%2F%3E%3C%2Fsvg%3E\");\n}\n.swiper-button-next,\n.swiper-container-rtl .swiper-button-prev {\n  background-image: url(\"data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20viewBox%3D'0%200%2027%2044'%3E%3Cpath%20d%3D'M27%2C22L27%2C22L5%2C44l-2.1-2.1L22.8%2C22L2.9%2C2.1L5%2C0L27%2C22L27%2C22z'%20fill%3D'%23007aff'%2F%3E%3C%2Fsvg%3E\");\n  right: 10px;\n  left: auto;\n}\n.swiper-button-next.swiper-button-black,\n.swiper-container-rtl .swiper-button-prev.swiper-button-black {\n  background-image: url(\"data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20viewBox%3D'0%200%2027%2044'%3E%3Cpath%20d%3D'M27%2C22L27%2C22L5%2C44l-2.1-2.1L22.8%2C22L2.9%2C2.1L5%2C0L27%2C22L27%2C22z'%20fill%3D'%23000000'%2F%3E%3C%2Fsvg%3E\");\n}\n.swiper-button-next.swiper-button-white,\n.swiper-container-rtl .swiper-button-prev.swiper-button-white {\n  background-image: url(\"data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20viewBox%3D'0%200%2027%2044'%3E%3Cpath%20d%3D'M27%2C22L27%2C22L5%2C44l-2.1-2.1L22.8%2C22L2.9%2C2.1L5%2C0L27%2C22L27%2C22z'%20fill%3D'%23ffffff'%2F%3E%3C%2Fsvg%3E\");\n}\n/* Pagination Styles */\n.swiper-pagination {\n  position: absolute;\n  text-align: center;\n  -webkit-transition: 300ms;\n  -moz-transition: 300ms;\n  -o-transition: 300ms;\n  transition: 300ms;\n  -webkit-transform: translate3d(0, 0, 0);\n  -ms-transform: translate3d(0, 0, 0);\n  -o-transform: translate3d(0, 0, 0);\n  transform: translate3d(0, 0, 0);\n  z-index: 10;\n}\n.swiper-pagination.swiper-pagination-hidden {\n  opacity: 0;\n}\n/* Common Styles */\n.swiper-pagination-fraction,\n.swiper-pagination-custom,\n.swiper-container-horizontal > .swiper-pagination-bullets {\n  bottom: 10px;\n  left: 0;\n  width: 100%;\n}\n/* Bullets */\n.swiper-pagination-bullet {\n  width: 8px;\n  height: 8px;\n  display: inline-block;\n  border-radius: 100%;\n  background: #000;\n  opacity: 0.2;\n}\nbutton.swiper-pagination-bullet {\n  border: none;\n  margin: 0;\n  padding: 0;\n  box-shadow: none;\n  -moz-appearance: none;\n  -ms-appearance: none;\n  -webkit-appearance: none;\n  appearance: none;\n}\n.swiper-pagination-clickable .swiper-pagination-bullet {\n  cursor: pointer;\n}\n.swiper-pagination-white .swiper-pagination-bullet {\n  background: #fff;\n}\n.swiper-pagination-bullet-active {\n  opacity: 1;\n  background: #007aff;\n}\n.swiper-pagination-white .swiper-pagination-bullet-active {\n  background: #fff;\n}\n.swiper-pagination-black .swiper-pagination-bullet-active {\n  background: #000;\n}\n.swiper-container-vertical > .swiper-pagination-bullets {\n  right: 10px;\n  top: 50%;\n  -webkit-transform: translate3d(0px, -50%, 0);\n  -moz-transform: translate3d(0px, -50%, 0);\n  -o-transform: translate(0px, -50%);\n  -ms-transform: translate3d(0px, -50%, 0);\n  transform: translate3d(0px, -50%, 0);\n}\n.swiper-container-vertical > .swiper-pagination-bullets .swiper-pagination-bullet {\n  margin: 5px 0;\n  display: block;\n}\n.swiper-container-horizontal > .swiper-pagination-bullets .swiper-pagination-bullet {\n  margin: 0 5px;\n}\n/* Progress */\n.swiper-pagination-progress {\n  background: rgba(0, 0, 0, 0.25);\n  position: absolute;\n}\n.swiper-pagination-progress .swiper-pagination-progressbar {\n  background: #007aff;\n  position: absolute;\n  left: 0;\n  top: 0;\n  width: 100%;\n  height: 100%;\n  -webkit-transform: scale(0);\n  -ms-transform: scale(0);\n  -o-transform: scale(0);\n  transform: scale(0);\n  -webkit-transform-origin: left top;\n  -moz-transform-origin: left top;\n  -ms-transform-origin: left top;\n  -o-transform-origin: left top;\n  transform-origin: left top;\n}\n.swiper-container-rtl .swiper-pagination-progress .swiper-pagination-progressbar {\n  -webkit-transform-origin: right top;\n  -moz-transform-origin: right top;\n  -ms-transform-origin: right top;\n  -o-transform-origin: right top;\n  transform-origin: right top;\n}\n.swiper-container-horizontal > .swiper-pagination-progress {\n  width: 100%;\n  height: 4px;\n  left: 0;\n  top: 0;\n}\n.swiper-container-vertical > .swiper-pagination-progress {\n  width: 4px;\n  height: 100%;\n  left: 0;\n  top: 0;\n}\n.swiper-pagination-progress.swiper-pagination-white {\n  background: rgba(255, 255, 255, 0.5);\n}\n.swiper-pagination-progress.swiper-pagination-white .swiper-pagination-progressbar {\n  background: #fff;\n}\n.swiper-pagination-progress.swiper-pagination-black .swiper-pagination-progressbar {\n  background: #000;\n}\n/* 3D Container */\n.swiper-container-3d {\n  -webkit-perspective: 1200px;\n  -moz-perspective: 1200px;\n  -o-perspective: 1200px;\n  perspective: 1200px;\n}\n.swiper-container-3d .swiper-wrapper,\n.swiper-container-3d .swiper-slide,\n.swiper-container-3d .swiper-slide-shadow-left,\n.swiper-container-3d .swiper-slide-shadow-right,\n.swiper-container-3d .swiper-slide-shadow-top,\n.swiper-container-3d .swiper-slide-shadow-bottom,\n.swiper-container-3d .swiper-cube-shadow {\n  -webkit-transform-style: preserve-3d;\n  -moz-transform-style: preserve-3d;\n  -ms-transform-style: preserve-3d;\n  transform-style: preserve-3d;\n}\n.swiper-container-3d .swiper-slide-shadow-left,\n.swiper-container-3d .swiper-slide-shadow-right,\n.swiper-container-3d .swiper-slide-shadow-top,\n.swiper-container-3d .swiper-slide-shadow-bottom {\n  position: absolute;\n  left: 0;\n  top: 0;\n  width: 100%;\n  height: 100%;\n  pointer-events: none;\n  z-index: 10;\n}\n.swiper-container-3d .swiper-slide-shadow-left {\n  background-image: -webkit-gradient(linear, left top, right top, from(rgba(0, 0, 0, 0.5)), to(rgba(0, 0, 0, 0)));\n  /* Safari 4+, Chrome */\n  background-image: -webkit-linear-gradient(right, rgba(0, 0, 0, 0.5), rgba(0, 0, 0, 0));\n  /* Chrome 10+, Safari 5.1+, iOS 5+ */\n  background-image: -moz-linear-gradient(right, rgba(0, 0, 0, 0.5), rgba(0, 0, 0, 0));\n  /* Firefox 3.6-15 */\n  background-image: -o-linear-gradient(right, rgba(0, 0, 0, 0.5), rgba(0, 0, 0, 0));\n  /* Opera 11.10-12.00 */\n  background-image: linear-gradient(to left, rgba(0, 0, 0, 0.5), rgba(0, 0, 0, 0));\n  /* Firefox 16+, IE10, Opera 12.50+ */\n}\n.swiper-container-3d .swiper-slide-shadow-right {\n  background-image: -webkit-gradient(linear, right top, left top, from(rgba(0, 0, 0, 0.5)), to(rgba(0, 0, 0, 0)));\n  /* Safari 4+, Chrome */\n  background-image: -webkit-linear-gradient(left, rgba(0, 0, 0, 0.5), rgba(0, 0, 0, 0));\n  /* Chrome 10+, Safari 5.1+, iOS 5+ */\n  background-image: -moz-linear-gradient(left, rgba(0, 0, 0, 0.5), rgba(0, 0, 0, 0));\n  /* Firefox 3.6-15 */\n  background-image: -o-linear-gradient(left, rgba(0, 0, 0, 0.5), rgba(0, 0, 0, 0));\n  /* Opera 11.10-12.00 */\n  background-image: linear-gradient(to right, rgba(0, 0, 0, 0.5), rgba(0, 0, 0, 0));\n  /* Firefox 16+, IE10, Opera 12.50+ */\n}\n.swiper-container-3d .swiper-slide-shadow-top {\n  background-image: -webkit-gradient(linear, left top, left bottom, from(rgba(0, 0, 0, 0.5)), to(rgba(0, 0, 0, 0)));\n  /* Safari 4+, Chrome */\n  background-image: -webkit-linear-gradient(bottom, rgba(0, 0, 0, 0.5), rgba(0, 0, 0, 0));\n  /* Chrome 10+, Safari 5.1+, iOS 5+ */\n  background-image: -moz-linear-gradient(bottom, rgba(0, 0, 0, 0.5), rgba(0, 0, 0, 0));\n  /* Firefox 3.6-15 */\n  background-image: -o-linear-gradient(bottom, rgba(0, 0, 0, 0.5), rgba(0, 0, 0, 0));\n  /* Opera 11.10-12.00 */\n  background-image: linear-gradient(to top, rgba(0, 0, 0, 0.5), rgba(0, 0, 0, 0));\n  /* Firefox 16+, IE10, Opera 12.50+ */\n}\n.swiper-container-3d .swiper-slide-shadow-bottom {\n  background-image: -webkit-gradient(linear, left bottom, left top, from(rgba(0, 0, 0, 0.5)), to(rgba(0, 0, 0, 0)));\n  /* Safari 4+, Chrome */\n  background-image: -webkit-linear-gradient(top, rgba(0, 0, 0, 0.5), rgba(0, 0, 0, 0));\n  /* Chrome 10+, Safari 5.1+, iOS 5+ */\n  background-image: -moz-linear-gradient(top, rgba(0, 0, 0, 0.5), rgba(0, 0, 0, 0));\n  /* Firefox 3.6-15 */\n  background-image: -o-linear-gradient(top, rgba(0, 0, 0, 0.5), rgba(0, 0, 0, 0));\n  /* Opera 11.10-12.00 */\n  background-image: linear-gradient(to bottom, rgba(0, 0, 0, 0.5), rgba(0, 0, 0, 0));\n  /* Firefox 16+, IE10, Opera 12.50+ */\n}\n/* Coverflow */\n.swiper-container-coverflow .swiper-wrapper,\n.swiper-container-flip .swiper-wrapper {\n  /* Windows 8 IE 10 fix */\n  -ms-perspective: 1200px;\n}\n/* Cube + Flip */\n.swiper-container-cube,\n.swiper-container-flip {\n  overflow: visible;\n}\n.swiper-container-cube .swiper-slide,\n.swiper-container-flip .swiper-slide {\n  pointer-events: none;\n  -webkit-backface-visibility: hidden;\n  -moz-backface-visibility: hidden;\n  -ms-backface-visibility: hidden;\n  backface-visibility: hidden;\n  z-index: 1;\n}\n.swiper-container-cube .swiper-slide .swiper-slide,\n.swiper-container-flip .swiper-slide .swiper-slide {\n  pointer-events: none;\n}\n.swiper-container-cube .swiper-slide-active,\n.swiper-container-flip .swiper-slide-active,\n.swiper-container-cube .swiper-slide-active .swiper-slide-active,\n.swiper-container-flip .swiper-slide-active .swiper-slide-active {\n  pointer-events: auto;\n}\n.swiper-container-cube .swiper-slide-shadow-top,\n.swiper-container-flip .swiper-slide-shadow-top,\n.swiper-container-cube .swiper-slide-shadow-bottom,\n.swiper-container-flip .swiper-slide-shadow-bottom,\n.swiper-container-cube .swiper-slide-shadow-left,\n.swiper-container-flip .swiper-slide-shadow-left,\n.swiper-container-cube .swiper-slide-shadow-right,\n.swiper-container-flip .swiper-slide-shadow-right {\n  z-index: 0;\n  -webkit-backface-visibility: hidden;\n  -moz-backface-visibility: hidden;\n  -ms-backface-visibility: hidden;\n  backface-visibility: hidden;\n}\n/* Cube */\n.swiper-container-cube .swiper-slide {\n  visibility: hidden;\n  -webkit-transform-origin: 0 0;\n  -moz-transform-origin: 0 0;\n  -ms-transform-origin: 0 0;\n  transform-origin: 0 0;\n  width: 100%;\n  height: 100%;\n}\n.swiper-container-cube.swiper-container-rtl .swiper-slide {\n  -webkit-transform-origin: 100% 0;\n  -moz-transform-origin: 100% 0;\n  -ms-transform-origin: 100% 0;\n  transform-origin: 100% 0;\n}\n.swiper-container-cube .swiper-slide-active,\n.swiper-container-cube .swiper-slide-next,\n.swiper-container-cube .swiper-slide-prev,\n.swiper-container-cube .swiper-slide-next + .swiper-slide {\n  pointer-events: auto;\n  visibility: visible;\n}\n.swiper-container-cube .swiper-cube-shadow {\n  position: absolute;\n  left: 0;\n  bottom: 0px;\n  width: 100%;\n  height: 100%;\n  background: #000;\n  opacity: 0.6;\n  -webkit-filter: blur(50px);\n  filter: blur(50px);\n  z-index: 0;\n}\n/* Fade */\n.swiper-container-fade.swiper-container-free-mode .swiper-slide {\n  -webkit-transition-timing-function: ease-out;\n  -moz-transition-timing-function: ease-out;\n  -ms-transition-timing-function: ease-out;\n  -o-transition-timing-function: ease-out;\n  transition-timing-function: ease-out;\n}\n.swiper-container-fade .swiper-slide {\n  pointer-events: none;\n  -webkit-transition-property: opacity;\n  -moz-transition-property: opacity;\n  -o-transition-property: opacity;\n  transition-property: opacity;\n}\n.swiper-container-fade .swiper-slide .swiper-slide {\n  pointer-events: none;\n}\n.swiper-container-fade .swiper-slide-active,\n.swiper-container-fade .swiper-slide-active .swiper-slide-active {\n  pointer-events: auto;\n}\n/* Scrollbar */\n.swiper-scrollbar {\n  border-radius: 10px;\n  position: relative;\n  -ms-touch-action: none;\n  background: rgba(0, 0, 0, 0.1);\n}\n.swiper-container-horizontal > .swiper-scrollbar {\n  position: absolute;\n  left: 1%;\n  bottom: 3px;\n  z-index: 50;\n  height: 5px;\n  width: 98%;\n}\n.swiper-container-vertical > .swiper-scrollbar {\n  position: absolute;\n  right: 3px;\n  top: 1%;\n  z-index: 50;\n  width: 5px;\n  height: 98%;\n}\n.swiper-scrollbar-drag {\n  height: 100%;\n  width: 100%;\n  position: relative;\n  background: rgba(0, 0, 0, 0.5);\n  border-radius: 10px;\n  left: 0;\n  top: 0;\n}\n.swiper-scrollbar-cursor-drag {\n  cursor: move;\n}\n/* Preloader */\n.swiper-lazy-preloader {\n  width: 42px;\n  height: 42px;\n  position: absolute;\n  left: 50%;\n  top: 50%;\n  margin-left: -21px;\n  margin-top: -21px;\n  z-index: 10;\n  -webkit-transform-origin: 50%;\n  -moz-transform-origin: 50%;\n  transform-origin: 50%;\n  -webkit-animation: swiper-preloader-spin 1s steps(12, end) infinite;\n  -moz-animation: swiper-preloader-spin 1s steps(12, end) infinite;\n  animation: swiper-preloader-spin 1s steps(12, end) infinite;\n}\n.swiper-lazy-preloader:after {\n  display: block;\n  content: \"\";\n  width: 100%;\n  height: 100%;\n  background-image: url(\"data:image/svg+xml;charset=utf-8,%3Csvg%20viewBox%3D'0%200%20120%20120'%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20xmlns%3Axlink%3D'http%3A%2F%2Fwww.w3.org%2F1999%2Fxlink'%3E%3Cdefs%3E%3Cline%20id%3D'l'%20x1%3D'60'%20x2%3D'60'%20y1%3D'7'%20y2%3D'27'%20stroke%3D'%236c6c6c'%20stroke-width%3D'11'%20stroke-linecap%3D'round'%2F%3E%3C%2Fdefs%3E%3Cg%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.27'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.27'%20transform%3D'rotate(30%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.27'%20transform%3D'rotate(60%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.27'%20transform%3D'rotate(90%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.27'%20transform%3D'rotate(120%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.27'%20transform%3D'rotate(150%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.37'%20transform%3D'rotate(180%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.46'%20transform%3D'rotate(210%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.56'%20transform%3D'rotate(240%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.66'%20transform%3D'rotate(270%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.75'%20transform%3D'rotate(300%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.85'%20transform%3D'rotate(330%2060%2C60)'%2F%3E%3C%2Fg%3E%3C%2Fsvg%3E\");\n  background-position: 50%;\n  -webkit-background-size: 100%;\n  background-size: 100%;\n  background-repeat: no-repeat;\n}\n.swiper-lazy-preloader-white:after {\n  background-image: url(\"data:image/svg+xml;charset=utf-8,%3Csvg%20viewBox%3D'0%200%20120%20120'%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20xmlns%3Axlink%3D'http%3A%2F%2Fwww.w3.org%2F1999%2Fxlink'%3E%3Cdefs%3E%3Cline%20id%3D'l'%20x1%3D'60'%20x2%3D'60'%20y1%3D'7'%20y2%3D'27'%20stroke%3D'%23fff'%20stroke-width%3D'11'%20stroke-linecap%3D'round'%2F%3E%3C%2Fdefs%3E%3Cg%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.27'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.27'%20transform%3D'rotate(30%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.27'%20transform%3D'rotate(60%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.27'%20transform%3D'rotate(90%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.27'%20transform%3D'rotate(120%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.27'%20transform%3D'rotate(150%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.37'%20transform%3D'rotate(180%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.46'%20transform%3D'rotate(210%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.56'%20transform%3D'rotate(240%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.66'%20transform%3D'rotate(270%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.75'%20transform%3D'rotate(300%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.85'%20transform%3D'rotate(330%2060%2C60)'%2F%3E%3C%2Fg%3E%3C%2Fsvg%3E\");\n}\n@-webkit-keyframes swiper-preloader-spin {\n  100% {\n    -webkit-transform: rotate(360deg);\n  }\n}\n@keyframes swiper-preloader-spin {\n  100% {\n    transform: rotate(360deg);\n  }\n}\n"
  },
  {
    "path": "app_frontend/static/plugin/Swiper-3.3.1/dist/js/swiper.jquery.js",
    "content": "/**\n * Swiper 3.3.1\n * Most modern mobile touch slider and framework with hardware accelerated transitions\n * \n * http://www.idangero.us/swiper/\n * \n * Copyright 2016, Vladimir Kharlampidi\n * The iDangero.us\n * http://www.idangero.us/\n * \n * Licensed under MIT\n * \n * Released on: February 7, 2016\n */\n(function () {\n    'use strict';\n    var $;\n    /*===========================\n    Swiper\n    ===========================*/\n    var Swiper = function (container, params) {\n        if (!(this instanceof Swiper)) return new Swiper(container, params);\n\n        var defaults = {\n            direction: 'horizontal',\n            touchEventsTarget: 'container',\n            initialSlide: 0,\n            speed: 300,\n            // autoplay\n            autoplay: false,\n            autoplayDisableOnInteraction: true,\n            autoplayStopOnLast: false,\n            // To support iOS's swipe-to-go-back gesture (when being used in-app, with UIWebView).\n            iOSEdgeSwipeDetection: false,\n            iOSEdgeSwipeThreshold: 20,\n            // Free mode\n            freeMode: false,\n            freeModeMomentum: true,\n            freeModeMomentumRatio: 1,\n            freeModeMomentumBounce: true,\n            freeModeMomentumBounceRatio: 1,\n            freeModeSticky: false,\n            freeModeMinimumVelocity: 0.02,\n            // Autoheight\n            autoHeight: false,\n            // Set wrapper width\n            setWrapperSize: false,\n            // Virtual Translate\n            virtualTranslate: false,\n            // Effects\n            effect: 'slide', // 'slide' or 'fade' or 'cube' or 'coverflow' or 'flip'\n            coverflow: {\n                rotate: 50,\n                stretch: 0,\n                depth: 100,\n                modifier: 1,\n                slideShadows : true\n            },\n            flip: {\n                slideShadows : true,\n                limitRotation: true\n            },\n            cube: {\n                slideShadows: true,\n                shadow: true,\n                shadowOffset: 20,\n                shadowScale: 0.94\n            },\n            fade: {\n                crossFade: false\n            },\n            // Parallax\n            parallax: false,\n            // Scrollbar\n            scrollbar: null,\n            scrollbarHide: true,\n            scrollbarDraggable: false,\n            scrollbarSnapOnRelease: false,\n            // Keyboard Mousewheel\n            keyboardControl: false,\n            mousewheelControl: false,\n            mousewheelReleaseOnEdges: false,\n            mousewheelInvert: false,\n            mousewheelForceToAxis: false,\n            mousewheelSensitivity: 1,\n            // Hash Navigation\n            hashnav: false,\n            // Breakpoints\n            breakpoints: undefined,\n            // Slides grid\n            spaceBetween: 0,\n            slidesPerView: 1,\n            slidesPerColumn: 1,\n            slidesPerColumnFill: 'column',\n            slidesPerGroup: 1,\n            centeredSlides: false,\n            slidesOffsetBefore: 0, // in px\n            slidesOffsetAfter: 0, // in px\n            // Round length\n            roundLengths: false,\n            // Touches\n            touchRatio: 1,\n            touchAngle: 45,\n            simulateTouch: true,\n            shortSwipes: true,\n            longSwipes: true,\n            longSwipesRatio: 0.5,\n            longSwipesMs: 300,\n            followFinger: true,\n            onlyExternal: false,\n            threshold: 0,\n            touchMoveStopPropagation: true,\n            // Unique Navigation Elements\n            uniqueNavElements: true,\n            // Pagination\n            pagination: null,\n            paginationElement: 'span',\n            paginationClickable: false,\n            paginationHide: false,\n            paginationBulletRender: null,\n            paginationProgressRender: null,\n            paginationFractionRender: null,\n            paginationCustomRender: null,\n            paginationType: 'bullets', // 'bullets' or 'progress' or 'fraction' or 'custom'\n            // Resistance\n            resistance: true,\n            resistanceRatio: 0.85,\n            // Next/prev buttons\n            nextButton: null,\n            prevButton: null,\n            // Progress\n            watchSlidesProgress: false,\n            watchSlidesVisibility: false,\n            // Cursor\n            grabCursor: false,\n            // Clicks\n            preventClicks: true,\n            preventClicksPropagation: true,\n            slideToClickedSlide: false,\n            // Lazy Loading\n            lazyLoading: false,\n            lazyLoadingInPrevNext: false,\n            lazyLoadingInPrevNextAmount: 1,\n            lazyLoadingOnTransitionStart: false,\n            // Images\n            preloadImages: true,\n            updateOnImagesReady: true,\n            // loop\n            loop: false,\n            loopAdditionalSlides: 0,\n            loopedSlides: null,\n            // Control\n            control: undefined,\n            controlInverse: false,\n            controlBy: 'slide', //or 'container'\n            // Swiping/no swiping\n            allowSwipeToPrev: true,\n            allowSwipeToNext: true,\n            swipeHandler: null, //'.swipe-handler',\n            noSwiping: true,\n            noSwipingClass: 'swiper-no-swiping',\n            // NS\n            slideClass: 'swiper-slide',\n            slideActiveClass: 'swiper-slide-active',\n            slideVisibleClass: 'swiper-slide-visible',\n            slideDuplicateClass: 'swiper-slide-duplicate',\n            slideNextClass: 'swiper-slide-next',\n            slidePrevClass: 'swiper-slide-prev',\n            wrapperClass: 'swiper-wrapper',\n            bulletClass: 'swiper-pagination-bullet',\n            bulletActiveClass: 'swiper-pagination-bullet-active',\n            buttonDisabledClass: 'swiper-button-disabled',\n            paginationCurrentClass: 'swiper-pagination-current',\n            paginationTotalClass: 'swiper-pagination-total',\n            paginationHiddenClass: 'swiper-pagination-hidden',\n            paginationProgressbarClass: 'swiper-pagination-progressbar',\n            // Observer\n            observer: false,\n            observeParents: false,\n            // Accessibility\n            a11y: false,\n            prevSlideMessage: 'Previous slide',\n            nextSlideMessage: 'Next slide',\n            firstSlideMessage: 'This is the first slide',\n            lastSlideMessage: 'This is the last slide',\n            paginationBulletMessage: 'Go to slide {{index}}',\n            // Callbacks\n            runCallbacksOnInit: true\n            /*\n            Callbacks:\n            onInit: function (swiper)\n            onDestroy: function (swiper)\n            onClick: function (swiper, e)\n            onTap: function (swiper, e)\n            onDoubleTap: function (swiper, e)\n            onSliderMove: function (swiper, e)\n            onSlideChangeStart: function (swiper)\n            onSlideChangeEnd: function (swiper)\n            onTransitionStart: function (swiper)\n            onTransitionEnd: function (swiper)\n            onImagesReady: function (swiper)\n            onProgress: function (swiper, progress)\n            onTouchStart: function (swiper, e)\n            onTouchMove: function (swiper, e)\n            onTouchMoveOpposite: function (swiper, e)\n            onTouchEnd: function (swiper, e)\n            onReachBeginning: function (swiper)\n            onReachEnd: function (swiper)\n            onSetTransition: function (swiper, duration)\n            onSetTranslate: function (swiper, translate)\n            onAutoplayStart: function (swiper)\n            onAutoplayStop: function (swiper),\n            onLazyImageLoad: function (swiper, slide, image)\n            onLazyImageReady: function (swiper, slide, image)\n            */\n        \n        };\n        var initialVirtualTranslate = params && params.virtualTranslate;\n        \n        params = params || {};\n        var originalParams = {};\n        for (var param in params) {\n            if (typeof params[param] === 'object' && params[param] !== null && !(params[param].nodeType || params[param] === window || params[param] === document || (typeof Dom7 !== 'undefined' && params[param] instanceof Dom7) || (typeof jQuery !== 'undefined' && params[param] instanceof jQuery))) {\n                originalParams[param] = {};\n                for (var deepParam in params[param]) {\n                    originalParams[param][deepParam] = params[param][deepParam];\n                }\n            }\n            else {\n                originalParams[param] = params[param];\n            }\n        }\n        for (var def in defaults) {\n            if (typeof params[def] === 'undefined') {\n                params[def] = defaults[def];\n            }\n            else if (typeof params[def] === 'object') {\n                for (var deepDef in defaults[def]) {\n                    if (typeof params[def][deepDef] === 'undefined') {\n                        params[def][deepDef] = defaults[def][deepDef];\n                    }\n                }\n            }\n        }\n        \n        // Swiper\n        var s = this;\n        \n        // Params\n        s.params = params;\n        s.originalParams = originalParams;\n        \n        // Classname\n        s.classNames = [];\n        /*=========================\n          Dom Library and plugins\n          ===========================*/\n        if (typeof $ !== 'undefined' && typeof Dom7 !== 'undefined'){\n            $ = Dom7;\n        }\n        if (typeof $ === 'undefined') {\n            if (typeof Dom7 === 'undefined') {\n                $ = window.Dom7 || window.Zepto || window.jQuery;\n            }\n            else {\n                $ = Dom7;\n            }\n            if (!$) return;\n        }\n        // Export it to Swiper instance\n        s.$ = $;\n        \n        /*=========================\n          Breakpoints\n          ===========================*/\n        s.currentBreakpoint = undefined;\n        s.getActiveBreakpoint = function () {\n            //Get breakpoint for window width\n            if (!s.params.breakpoints) return false;\n            var breakpoint = false;\n            var points = [], point;\n            for ( point in s.params.breakpoints ) {\n                if (s.params.breakpoints.hasOwnProperty(point)) {\n                    points.push(point);\n                }\n            }\n            points.sort(function (a, b) {\n                return parseInt(a, 10) > parseInt(b, 10);\n            });\n            for (var i = 0; i < points.length; i++) {\n                point = points[i];\n                if (point >= window.innerWidth && !breakpoint) {\n                    breakpoint = point;\n                }\n            }\n            return breakpoint || 'max';\n        };\n        s.setBreakpoint = function () {\n            //Set breakpoint for window width and update parameters\n            var breakpoint = s.getActiveBreakpoint();\n            if (breakpoint && s.currentBreakpoint !== breakpoint) {\n                var breakPointsParams = breakpoint in s.params.breakpoints ? s.params.breakpoints[breakpoint] : s.originalParams;\n                var needsReLoop = s.params.loop && (breakPointsParams.slidesPerView !== s.params.slidesPerView);\n                for ( var param in breakPointsParams ) {\n                    s.params[param] = breakPointsParams[param];\n                }\n                s.currentBreakpoint = breakpoint;\n                if(needsReLoop && s.destroyLoop) {\n                    s.reLoop(true);\n                }\n            }\n        };\n        // Set breakpoint on load\n        if (s.params.breakpoints) {\n            s.setBreakpoint();\n        }\n        \n        /*=========================\n          Preparation - Define Container, Wrapper and Pagination\n          ===========================*/\n        s.container = $(container);\n        if (s.container.length === 0) return;\n        if (s.container.length > 1) {\n            var swipers = [];\n            s.container.each(function () {\n                var container = this;\n                swipers.push(new Swiper(this, params));\n            });\n            return swipers;\n        }\n        \n        // Save instance in container HTML Element and in data\n        s.container[0].swiper = s;\n        s.container.data('swiper', s);\n        \n        s.classNames.push('swiper-container-' + s.params.direction);\n        \n        if (s.params.freeMode) {\n            s.classNames.push('swiper-container-free-mode');\n        }\n        if (!s.support.flexbox) {\n            s.classNames.push('swiper-container-no-flexbox');\n            s.params.slidesPerColumn = 1;\n        }\n        if (s.params.autoHeight) {\n            s.classNames.push('swiper-container-autoheight');\n        }\n        // Enable slides progress when required\n        if (s.params.parallax || s.params.watchSlidesVisibility) {\n            s.params.watchSlidesProgress = true;\n        }\n        // Coverflow / 3D\n        if (['cube', 'coverflow', 'flip'].indexOf(s.params.effect) >= 0) {\n            if (s.support.transforms3d) {\n                s.params.watchSlidesProgress = true;\n                s.classNames.push('swiper-container-3d');\n            }\n            else {\n                s.params.effect = 'slide';\n            }\n        }\n        if (s.params.effect !== 'slide') {\n            s.classNames.push('swiper-container-' + s.params.effect);\n        }\n        if (s.params.effect === 'cube') {\n            s.params.resistanceRatio = 0;\n            s.params.slidesPerView = 1;\n            s.params.slidesPerColumn = 1;\n            s.params.slidesPerGroup = 1;\n            s.params.centeredSlides = false;\n            s.params.spaceBetween = 0;\n            s.params.virtualTranslate = true;\n            s.params.setWrapperSize = false;\n        }\n        if (s.params.effect === 'fade' || s.params.effect === 'flip') {\n            s.params.slidesPerView = 1;\n            s.params.slidesPerColumn = 1;\n            s.params.slidesPerGroup = 1;\n            s.params.watchSlidesProgress = true;\n            s.params.spaceBetween = 0;\n            s.params.setWrapperSize = false;\n            if (typeof initialVirtualTranslate === 'undefined') {\n                s.params.virtualTranslate = true;\n            }\n        }\n        \n        // Grab Cursor\n        if (s.params.grabCursor && s.support.touch) {\n            s.params.grabCursor = false;\n        }\n        \n        // Wrapper\n        s.wrapper = s.container.children('.' + s.params.wrapperClass);\n        \n        // Pagination\n        if (s.params.pagination) {\n            s.paginationContainer = $(s.params.pagination);\n            if (s.params.uniqueNavElements && typeof s.params.pagination === 'string' && s.paginationContainer.length > 1 && s.container.find(s.params.pagination).length === 1) {\n                s.paginationContainer = s.container.find(s.params.pagination);\n            }\n        \n            if (s.params.paginationType === 'bullets' && s.params.paginationClickable) {\n                s.paginationContainer.addClass('swiper-pagination-clickable');\n            }\n            else {\n                s.params.paginationClickable = false;\n            }\n            s.paginationContainer.addClass('swiper-pagination-' + s.params.paginationType);\n        }\n        // Next/Prev Buttons\n        if (s.params.nextButton || s.params.prevButton) {\n            if (s.params.nextButton) {\n                s.nextButton = $(s.params.nextButton);\n                if (s.params.uniqueNavElements && typeof s.params.nextButton === 'string' && s.nextButton.length > 1 && s.container.find(s.params.nextButton).length === 1) {\n                    s.nextButton = s.container.find(s.params.nextButton);\n                }\n            }\n            if (s.params.prevButton) {\n                s.prevButton = $(s.params.prevButton);\n                if (s.params.uniqueNavElements && typeof s.params.prevButton === 'string' && s.prevButton.length > 1 && s.container.find(s.params.prevButton).length === 1) {\n                    s.prevButton = s.container.find(s.params.prevButton);\n                }\n            }\n        }\n        \n        // Is Horizontal\n        s.isHorizontal = function () {\n            return s.params.direction === 'horizontal';\n        };\n        // s.isH = isH;\n        \n        // RTL\n        s.rtl = s.isHorizontal() && (s.container[0].dir.toLowerCase() === 'rtl' || s.container.css('direction') === 'rtl');\n        if (s.rtl) {\n            s.classNames.push('swiper-container-rtl');\n        }\n        \n        // Wrong RTL support\n        if (s.rtl) {\n            s.wrongRTL = s.wrapper.css('display') === '-webkit-box';\n        }\n        \n        // Columns\n        if (s.params.slidesPerColumn > 1) {\n            s.classNames.push('swiper-container-multirow');\n        }\n        \n        // Check for Android\n        if (s.device.android) {\n            s.classNames.push('swiper-container-android');\n        }\n        \n        // Add classes\n        s.container.addClass(s.classNames.join(' '));\n        \n        // Translate\n        s.translate = 0;\n        \n        // Progress\n        s.progress = 0;\n        \n        // Velocity\n        s.velocity = 0;\n        \n        /*=========================\n          Locks, unlocks\n          ===========================*/\n        s.lockSwipeToNext = function () {\n            s.params.allowSwipeToNext = false;\n        };\n        s.lockSwipeToPrev = function () {\n            s.params.allowSwipeToPrev = false;\n        };\n        s.lockSwipes = function () {\n            s.params.allowSwipeToNext = s.params.allowSwipeToPrev = false;\n        };\n        s.unlockSwipeToNext = function () {\n            s.params.allowSwipeToNext = true;\n        };\n        s.unlockSwipeToPrev = function () {\n            s.params.allowSwipeToPrev = true;\n        };\n        s.unlockSwipes = function () {\n            s.params.allowSwipeToNext = s.params.allowSwipeToPrev = true;\n        };\n        \n        /*=========================\n          Round helper\n          ===========================*/\n        function round(a) {\n            return Math.floor(a);\n        }\n        /*=========================\n          Set grab cursor\n          ===========================*/\n        if (s.params.grabCursor) {\n            s.container[0].style.cursor = 'move';\n            s.container[0].style.cursor = '-webkit-grab';\n            s.container[0].style.cursor = '-moz-grab';\n            s.container[0].style.cursor = 'grab';\n        }\n        /*=========================\n          Update on Images Ready\n          ===========================*/\n        s.imagesToLoad = [];\n        s.imagesLoaded = 0;\n        \n        s.loadImage = function (imgElement, src, srcset, checkForComplete, callback) {\n            var image;\n            function onReady () {\n                if (callback) callback();\n            }\n            if (!imgElement.complete || !checkForComplete) {\n                if (src) {\n                    image = new window.Image();\n                    image.onload = onReady;\n                    image.onerror = onReady;\n                    if (srcset) {\n                        image.srcset = srcset;\n                    }\n                    if (src) {\n                        image.src = src;\n                    }\n                } else {\n                    onReady();\n                }\n        \n            } else {//image already loaded...\n                onReady();\n            }\n        };\n        s.preloadImages = function () {\n            s.imagesToLoad = s.container.find('img');\n            function _onReady() {\n                if (typeof s === 'undefined' || s === null) return;\n                if (s.imagesLoaded !== undefined) s.imagesLoaded++;\n                if (s.imagesLoaded === s.imagesToLoad.length) {\n                    if (s.params.updateOnImagesReady) s.update();\n                    s.emit('onImagesReady', s);\n                }\n            }\n            for (var i = 0; i < s.imagesToLoad.length; i++) {\n                s.loadImage(s.imagesToLoad[i], (s.imagesToLoad[i].currentSrc || s.imagesToLoad[i].getAttribute('src')), (s.imagesToLoad[i].srcset || s.imagesToLoad[i].getAttribute('srcset')), true, _onReady);\n            }\n        };\n        \n        /*=========================\n          Autoplay\n          ===========================*/\n        s.autoplayTimeoutId = undefined;\n        s.autoplaying = false;\n        s.autoplayPaused = false;\n        function autoplay() {\n            s.autoplayTimeoutId = setTimeout(function () {\n                if (s.params.loop) {\n                    s.fixLoop();\n                    s._slideNext();\n                    s.emit('onAutoplay', s);\n                }\n                else {\n                    if (!s.isEnd) {\n                        s._slideNext();\n                        s.emit('onAutoplay', s);\n                    }\n                    else {\n                        if (!params.autoplayStopOnLast) {\n                            s._slideTo(0);\n                            s.emit('onAutoplay', s);\n                        }\n                        else {\n                            s.stopAutoplay();\n                        }\n                    }\n                }\n            }, s.params.autoplay);\n        }\n        s.startAutoplay = function () {\n            if (typeof s.autoplayTimeoutId !== 'undefined') return false;\n            if (!s.params.autoplay) return false;\n            if (s.autoplaying) return false;\n            s.autoplaying = true;\n            s.emit('onAutoplayStart', s);\n            autoplay();\n        };\n        s.stopAutoplay = function (internal) {\n            if (!s.autoplayTimeoutId) return;\n            if (s.autoplayTimeoutId) clearTimeout(s.autoplayTimeoutId);\n            s.autoplaying = false;\n            s.autoplayTimeoutId = undefined;\n            s.emit('onAutoplayStop', s);\n        };\n        s.pauseAutoplay = function (speed) {\n            if (s.autoplayPaused) return;\n            if (s.autoplayTimeoutId) clearTimeout(s.autoplayTimeoutId);\n            s.autoplayPaused = true;\n            if (speed === 0) {\n                s.autoplayPaused = false;\n                autoplay();\n            }\n            else {\n                s.wrapper.transitionEnd(function () {\n                    if (!s) return;\n                    s.autoplayPaused = false;\n                    if (!s.autoplaying) {\n                        s.stopAutoplay();\n                    }\n                    else {\n                        autoplay();\n                    }\n                });\n            }\n        };\n        /*=========================\n          Min/Max Translate\n          ===========================*/\n        s.minTranslate = function () {\n            return (-s.snapGrid[0]);\n        };\n        s.maxTranslate = function () {\n            return (-s.snapGrid[s.snapGrid.length - 1]);\n        };\n        /*=========================\n          Slider/slides sizes\n          ===========================*/\n        s.updateAutoHeight = function () {\n            // Update Height\n            var slide = s.slides.eq(s.activeIndex)[0];\n            if (typeof slide !== 'undefined') {\n                var newHeight = slide.offsetHeight;\n                if (newHeight) s.wrapper.css('height', newHeight + 'px');\n            }\n        };\n        s.updateContainerSize = function () {\n            var width, height;\n            if (typeof s.params.width !== 'undefined') {\n                width = s.params.width;\n            }\n            else {\n                width = s.container[0].clientWidth;\n            }\n            if (typeof s.params.height !== 'undefined') {\n                height = s.params.height;\n            }\n            else {\n                height = s.container[0].clientHeight;\n            }\n            if (width === 0 && s.isHorizontal() || height === 0 && !s.isHorizontal()) {\n                return;\n            }\n        \n            //Subtract paddings\n            width = width - parseInt(s.container.css('padding-left'), 10) - parseInt(s.container.css('padding-right'), 10);\n            height = height - parseInt(s.container.css('padding-top'), 10) - parseInt(s.container.css('padding-bottom'), 10);\n        \n            // Store values\n            s.width = width;\n            s.height = height;\n            s.size = s.isHorizontal() ? s.width : s.height;\n        };\n        \n        s.updateSlidesSize = function () {\n            s.slides = s.wrapper.children('.' + s.params.slideClass);\n            s.snapGrid = [];\n            s.slidesGrid = [];\n            s.slidesSizesGrid = [];\n        \n            var spaceBetween = s.params.spaceBetween,\n                slidePosition = -s.params.slidesOffsetBefore,\n                i,\n                prevSlideSize = 0,\n                index = 0;\n            if (typeof s.size === 'undefined') return;\n            if (typeof spaceBetween === 'string' && spaceBetween.indexOf('%') >= 0) {\n                spaceBetween = parseFloat(spaceBetween.replace('%', '')) / 100 * s.size;\n            }\n        \n            s.virtualSize = -spaceBetween;\n            // reset margins\n            if (s.rtl) s.slides.css({marginLeft: '', marginTop: ''});\n            else s.slides.css({marginRight: '', marginBottom: ''});\n        \n            var slidesNumberEvenToRows;\n            if (s.params.slidesPerColumn > 1) {\n                if (Math.floor(s.slides.length / s.params.slidesPerColumn) === s.slides.length / s.params.slidesPerColumn) {\n                    slidesNumberEvenToRows = s.slides.length;\n                }\n                else {\n                    slidesNumberEvenToRows = Math.ceil(s.slides.length / s.params.slidesPerColumn) * s.params.slidesPerColumn;\n                }\n                if (s.params.slidesPerView !== 'auto' && s.params.slidesPerColumnFill === 'row') {\n                    slidesNumberEvenToRows = Math.max(slidesNumberEvenToRows, s.params.slidesPerView * s.params.slidesPerColumn);\n                }\n            }\n        \n            // Calc slides\n            var slideSize;\n            var slidesPerColumn = s.params.slidesPerColumn;\n            var slidesPerRow = slidesNumberEvenToRows / slidesPerColumn;\n            var numFullColumns = slidesPerRow - (s.params.slidesPerColumn * slidesPerRow - s.slides.length);\n            for (i = 0; i < s.slides.length; i++) {\n                slideSize = 0;\n                var slide = s.slides.eq(i);\n                if (s.params.slidesPerColumn > 1) {\n                    // Set slides order\n                    var newSlideOrderIndex;\n                    var column, row;\n                    if (s.params.slidesPerColumnFill === 'column') {\n                        column = Math.floor(i / slidesPerColumn);\n                        row = i - column * slidesPerColumn;\n                        if (column > numFullColumns || (column === numFullColumns && row === slidesPerColumn-1)) {\n                            if (++row >= slidesPerColumn) {\n                                row = 0;\n                                column++;\n                            }\n                        }\n                        newSlideOrderIndex = column + row * slidesNumberEvenToRows / slidesPerColumn;\n                        slide\n                            .css({\n                                '-webkit-box-ordinal-group': newSlideOrderIndex,\n                                '-moz-box-ordinal-group': newSlideOrderIndex,\n                                '-ms-flex-order': newSlideOrderIndex,\n                                '-webkit-order': newSlideOrderIndex,\n                                'order': newSlideOrderIndex\n                            });\n                    }\n                    else {\n                        row = Math.floor(i / slidesPerRow);\n                        column = i - row * slidesPerRow;\n                    }\n                    slide\n                        .css({\n                            'margin-top': (row !== 0 && s.params.spaceBetween) && (s.params.spaceBetween + 'px')\n                        })\n                        .attr('data-swiper-column', column)\n                        .attr('data-swiper-row', row);\n        \n                }\n                if (slide.css('display') === 'none') continue;\n                if (s.params.slidesPerView === 'auto') {\n                    slideSize = s.isHorizontal() ? slide.outerWidth(true) : slide.outerHeight(true);\n                    if (s.params.roundLengths) slideSize = round(slideSize);\n                }\n                else {\n                    slideSize = (s.size - (s.params.slidesPerView - 1) * spaceBetween) / s.params.slidesPerView;\n                    if (s.params.roundLengths) slideSize = round(slideSize);\n        \n                    if (s.isHorizontal()) {\n                        s.slides[i].style.width = slideSize + 'px';\n                    }\n                    else {\n                        s.slides[i].style.height = slideSize + 'px';\n                    }\n                }\n                s.slides[i].swiperSlideSize = slideSize;\n                s.slidesSizesGrid.push(slideSize);\n        \n        \n                if (s.params.centeredSlides) {\n                    slidePosition = slidePosition + slideSize / 2 + prevSlideSize / 2 + spaceBetween;\n                    if (i === 0) slidePosition = slidePosition - s.size / 2 - spaceBetween;\n                    if (Math.abs(slidePosition) < 1 / 1000) slidePosition = 0;\n                    if ((index) % s.params.slidesPerGroup === 0) s.snapGrid.push(slidePosition);\n                    s.slidesGrid.push(slidePosition);\n                }\n                else {\n                    if ((index) % s.params.slidesPerGroup === 0) s.snapGrid.push(slidePosition);\n                    s.slidesGrid.push(slidePosition);\n                    slidePosition = slidePosition + slideSize + spaceBetween;\n                }\n        \n                s.virtualSize += slideSize + spaceBetween;\n        \n                prevSlideSize = slideSize;\n        \n                index ++;\n            }\n            s.virtualSize = Math.max(s.virtualSize, s.size) + s.params.slidesOffsetAfter;\n            var newSlidesGrid;\n        \n            if (\n                s.rtl && s.wrongRTL && (s.params.effect === 'slide' || s.params.effect === 'coverflow')) {\n                s.wrapper.css({width: s.virtualSize + s.params.spaceBetween + 'px'});\n            }\n            if (!s.support.flexbox || s.params.setWrapperSize) {\n                if (s.isHorizontal()) s.wrapper.css({width: s.virtualSize + s.params.spaceBetween + 'px'});\n                else s.wrapper.css({height: s.virtualSize + s.params.spaceBetween + 'px'});\n            }\n        \n            if (s.params.slidesPerColumn > 1) {\n                s.virtualSize = (slideSize + s.params.spaceBetween) * slidesNumberEvenToRows;\n                s.virtualSize = Math.ceil(s.virtualSize / s.params.slidesPerColumn) - s.params.spaceBetween;\n                s.wrapper.css({width: s.virtualSize + s.params.spaceBetween + 'px'});\n                if (s.params.centeredSlides) {\n                    newSlidesGrid = [];\n                    for (i = 0; i < s.snapGrid.length; i++) {\n                        if (s.snapGrid[i] < s.virtualSize + s.snapGrid[0]) newSlidesGrid.push(s.snapGrid[i]);\n                    }\n                    s.snapGrid = newSlidesGrid;\n                }\n            }\n        \n            // Remove last grid elements depending on width\n            if (!s.params.centeredSlides) {\n                newSlidesGrid = [];\n                for (i = 0; i < s.snapGrid.length; i++) {\n                    if (s.snapGrid[i] <= s.virtualSize - s.size) {\n                        newSlidesGrid.push(s.snapGrid[i]);\n                    }\n                }\n                s.snapGrid = newSlidesGrid;\n                if (Math.floor(s.virtualSize - s.size) - Math.floor(s.snapGrid[s.snapGrid.length - 1]) > 1) {\n                    s.snapGrid.push(s.virtualSize - s.size);\n                }\n            }\n            if (s.snapGrid.length === 0) s.snapGrid = [0];\n        \n            if (s.params.spaceBetween !== 0) {\n                if (s.isHorizontal()) {\n                    if (s.rtl) s.slides.css({marginLeft: spaceBetween + 'px'});\n                    else s.slides.css({marginRight: spaceBetween + 'px'});\n                }\n                else s.slides.css({marginBottom: spaceBetween + 'px'});\n            }\n            if (s.params.watchSlidesProgress) {\n                s.updateSlidesOffset();\n            }\n        };\n        s.updateSlidesOffset = function () {\n            for (var i = 0; i < s.slides.length; i++) {\n                s.slides[i].swiperSlideOffset = s.isHorizontal() ? s.slides[i].offsetLeft : s.slides[i].offsetTop;\n            }\n        };\n        \n        /*=========================\n          Slider/slides progress\n          ===========================*/\n        s.updateSlidesProgress = function (translate) {\n            if (typeof translate === 'undefined') {\n                translate = s.translate || 0;\n            }\n            if (s.slides.length === 0) return;\n            if (typeof s.slides[0].swiperSlideOffset === 'undefined') s.updateSlidesOffset();\n        \n            var offsetCenter = -translate;\n            if (s.rtl) offsetCenter = translate;\n        \n            // Visible Slides\n            s.slides.removeClass(s.params.slideVisibleClass);\n            for (var i = 0; i < s.slides.length; i++) {\n                var slide = s.slides[i];\n                var slideProgress = (offsetCenter - slide.swiperSlideOffset) / (slide.swiperSlideSize + s.params.spaceBetween);\n                if (s.params.watchSlidesVisibility) {\n                    var slideBefore = -(offsetCenter - slide.swiperSlideOffset);\n                    var slideAfter = slideBefore + s.slidesSizesGrid[i];\n                    var isVisible =\n                        (slideBefore >= 0 && slideBefore < s.size) ||\n                        (slideAfter > 0 && slideAfter <= s.size) ||\n                        (slideBefore <= 0 && slideAfter >= s.size);\n                    if (isVisible) {\n                        s.slides.eq(i).addClass(s.params.slideVisibleClass);\n                    }\n                }\n                slide.progress = s.rtl ? -slideProgress : slideProgress;\n            }\n        };\n        s.updateProgress = function (translate) {\n            if (typeof translate === 'undefined') {\n                translate = s.translate || 0;\n            }\n            var translatesDiff = s.maxTranslate() - s.minTranslate();\n            var wasBeginning = s.isBeginning;\n            var wasEnd = s.isEnd;\n            if (translatesDiff === 0) {\n                s.progress = 0;\n                s.isBeginning = s.isEnd = true;\n            }\n            else {\n                s.progress = (translate - s.minTranslate()) / (translatesDiff);\n                s.isBeginning = s.progress <= 0;\n                s.isEnd = s.progress >= 1;\n            }\n            if (s.isBeginning && !wasBeginning) s.emit('onReachBeginning', s);\n            if (s.isEnd && !wasEnd) s.emit('onReachEnd', s);\n        \n            if (s.params.watchSlidesProgress) s.updateSlidesProgress(translate);\n            s.emit('onProgress', s, s.progress);\n        };\n        s.updateActiveIndex = function () {\n            var translate = s.rtl ? s.translate : -s.translate;\n            var newActiveIndex, i, snapIndex;\n            for (i = 0; i < s.slidesGrid.length; i ++) {\n                if (typeof s.slidesGrid[i + 1] !== 'undefined') {\n                    if (translate >= s.slidesGrid[i] && translate < s.slidesGrid[i + 1] - (s.slidesGrid[i + 1] - s.slidesGrid[i]) / 2) {\n                        newActiveIndex = i;\n                    }\n                    else if (translate >= s.slidesGrid[i] && translate < s.slidesGrid[i + 1]) {\n                        newActiveIndex = i + 1;\n                    }\n                }\n                else {\n                    if (translate >= s.slidesGrid[i]) {\n                        newActiveIndex = i;\n                    }\n                }\n            }\n            // Normalize slideIndex\n            if (newActiveIndex < 0 || typeof newActiveIndex === 'undefined') newActiveIndex = 0;\n            // for (i = 0; i < s.slidesGrid.length; i++) {\n                // if (- translate >= s.slidesGrid[i]) {\n                    // newActiveIndex = i;\n                // }\n            // }\n            snapIndex = Math.floor(newActiveIndex / s.params.slidesPerGroup);\n            if (snapIndex >= s.snapGrid.length) snapIndex = s.snapGrid.length - 1;\n        \n            if (newActiveIndex === s.activeIndex) {\n                return;\n            }\n            s.snapIndex = snapIndex;\n            s.previousIndex = s.activeIndex;\n            s.activeIndex = newActiveIndex;\n            s.updateClasses();\n        };\n        \n        /*=========================\n          Classes\n          ===========================*/\n        s.updateClasses = function () {\n            s.slides.removeClass(s.params.slideActiveClass + ' ' + s.params.slideNextClass + ' ' + s.params.slidePrevClass);\n            var activeSlide = s.slides.eq(s.activeIndex);\n            // Active classes\n            activeSlide.addClass(s.params.slideActiveClass);\n            // Next Slide\n            var nextSlide = activeSlide.next('.' + s.params.slideClass).addClass(s.params.slideNextClass);\n            if (s.params.loop && nextSlide.length === 0) {\n                s.slides.eq(0).addClass(s.params.slideNextClass);\n            }\n            // Prev Slide\n            var prevSlide = activeSlide.prev('.' + s.params.slideClass).addClass(s.params.slidePrevClass);\n            if (s.params.loop && prevSlide.length === 0) {\n                s.slides.eq(-1).addClass(s.params.slidePrevClass);\n            }\n        \n            // Pagination\n            if (s.paginationContainer && s.paginationContainer.length > 0) {\n                // Current/Total\n                var current,\n                    total = s.params.loop ? Math.ceil((s.slides.length - s.loopedSlides * 2) / s.params.slidesPerGroup) : s.snapGrid.length;\n                if (s.params.loop) {\n                    current = Math.ceil((s.activeIndex - s.loopedSlides)/s.params.slidesPerGroup);\n                    if (current > s.slides.length - 1 - s.loopedSlides * 2) {\n                        current = current - (s.slides.length - s.loopedSlides * 2);\n                    }\n                    if (current > total - 1) current = current - total;\n                    if (current < 0 && s.params.paginationType !== 'bullets') current = total + current;\n                }\n                else {\n                    if (typeof s.snapIndex !== 'undefined') {\n                        current = s.snapIndex;\n                    }\n                    else {\n                        current = s.activeIndex || 0;\n                    }\n                }\n                // Types\n                if (s.params.paginationType === 'bullets' && s.bullets && s.bullets.length > 0) {\n                    s.bullets.removeClass(s.params.bulletActiveClass);\n                    if (s.paginationContainer.length > 1) {\n                        s.bullets.each(function () {\n                            if ($(this).index() === current) $(this).addClass(s.params.bulletActiveClass);\n                        });\n                    }\n                    else {\n                        s.bullets.eq(current).addClass(s.params.bulletActiveClass);\n                    }\n                }\n                if (s.params.paginationType === 'fraction') {\n                    s.paginationContainer.find('.' + s.params.paginationCurrentClass).text(current + 1);\n                    s.paginationContainer.find('.' + s.params.paginationTotalClass).text(total);\n                }\n                if (s.params.paginationType === 'progress') {\n                    var scale = (current + 1) / total,\n                        scaleX = scale,\n                        scaleY = 1;\n                    if (!s.isHorizontal()) {\n                        scaleY = scale;\n                        scaleX = 1;\n                    }\n                    s.paginationContainer.find('.' + s.params.paginationProgressbarClass).transform('translate3d(0,0,0) scaleX(' + scaleX + ') scaleY(' + scaleY + ')').transition(s.params.speed);\n                }\n                if (s.params.paginationType === 'custom' && s.params.paginationCustomRender) {\n                    s.paginationContainer.html(s.params.paginationCustomRender(s, current + 1, total));\n                    s.emit('onPaginationRendered', s, s.paginationContainer[0]);\n                }\n            }\n        \n            // Next/active buttons\n            if (!s.params.loop) {\n                if (s.params.prevButton && s.prevButton && s.prevButton.length > 0) {\n                    if (s.isBeginning) {\n                        s.prevButton.addClass(s.params.buttonDisabledClass);\n                        if (s.params.a11y && s.a11y) s.a11y.disable(s.prevButton);\n                    }\n                    else {\n                        s.prevButton.removeClass(s.params.buttonDisabledClass);\n                        if (s.params.a11y && s.a11y) s.a11y.enable(s.prevButton);\n                    }\n                }\n                if (s.params.nextButton && s.nextButton && s.nextButton.length > 0) {\n                    if (s.isEnd) {\n                        s.nextButton.addClass(s.params.buttonDisabledClass);\n                        if (s.params.a11y && s.a11y) s.a11y.disable(s.nextButton);\n                    }\n                    else {\n                        s.nextButton.removeClass(s.params.buttonDisabledClass);\n                        if (s.params.a11y && s.a11y) s.a11y.enable(s.nextButton);\n                    }\n                }\n            }\n        };\n        \n        /*=========================\n          Pagination\n          ===========================*/\n        s.updatePagination = function () {\n            if (!s.params.pagination) return;\n            if (s.paginationContainer && s.paginationContainer.length > 0) {\n                var paginationHTML = '';\n                if (s.params.paginationType === 'bullets') {\n                    var numberOfBullets = s.params.loop ? Math.ceil((s.slides.length - s.loopedSlides * 2) / s.params.slidesPerGroup) : s.snapGrid.length;\n                    for (var i = 0; i < numberOfBullets; i++) {\n                        if (s.params.paginationBulletRender) {\n                            paginationHTML += s.params.paginationBulletRender(i, s.params.bulletClass);\n                        }\n                        else {\n                            paginationHTML += '<' + s.params.paginationElement+' class=\"' + s.params.bulletClass + '\"></' + s.params.paginationElement + '>';\n                        }\n                    }\n                    s.paginationContainer.html(paginationHTML);\n                    s.bullets = s.paginationContainer.find('.' + s.params.bulletClass);\n                    if (s.params.paginationClickable && s.params.a11y && s.a11y) {\n                        s.a11y.initPagination();\n                    }\n                }\n                if (s.params.paginationType === 'fraction') {\n                    if (s.params.paginationFractionRender) {\n                        paginationHTML = s.params.paginationFractionRender(s, s.params.paginationCurrentClass, s.params.paginationTotalClass);\n                    }\n                    else {\n                        paginationHTML =\n                            '<span class=\"' + s.params.paginationCurrentClass + '\"></span>' +\n                            ' / ' +\n                            '<span class=\"' + s.params.paginationTotalClass+'\"></span>';\n                    }\n                    s.paginationContainer.html(paginationHTML);\n                }\n                if (s.params.paginationType === 'progress') {\n                    if (s.params.paginationProgressRender) {\n                        paginationHTML = s.params.paginationProgressRender(s, s.params.paginationProgressbarClass);\n                    }\n                    else {\n                        paginationHTML = '<span class=\"' + s.params.paginationProgressbarClass + '\"></span>';\n                    }\n                    s.paginationContainer.html(paginationHTML);\n                }\n                if (s.params.paginationType !== 'custom') {\n                    s.emit('onPaginationRendered', s, s.paginationContainer[0]);\n                }\n            }\n        };\n        /*=========================\n          Common update method\n          ===========================*/\n        s.update = function (updateTranslate) {\n            s.updateContainerSize();\n            s.updateSlidesSize();\n            s.updateProgress();\n            s.updatePagination();\n            s.updateClasses();\n            if (s.params.scrollbar && s.scrollbar) {\n                s.scrollbar.set();\n            }\n            function forceSetTranslate() {\n                newTranslate = Math.min(Math.max(s.translate, s.maxTranslate()), s.minTranslate());\n                s.setWrapperTranslate(newTranslate);\n                s.updateActiveIndex();\n                s.updateClasses();\n            }\n            if (updateTranslate) {\n                var translated, newTranslate;\n                if (s.controller && s.controller.spline) {\n                    s.controller.spline = undefined;\n                }\n                if (s.params.freeMode) {\n                    forceSetTranslate();\n                    if (s.params.autoHeight) {\n                        s.updateAutoHeight();\n                    }\n                }\n                else {\n                    if ((s.params.slidesPerView === 'auto' || s.params.slidesPerView > 1) && s.isEnd && !s.params.centeredSlides) {\n                        translated = s.slideTo(s.slides.length - 1, 0, false, true);\n                    }\n                    else {\n                        translated = s.slideTo(s.activeIndex, 0, false, true);\n                    }\n                    if (!translated) {\n                        forceSetTranslate();\n                    }\n                }\n            }\n            else if (s.params.autoHeight) {\n                s.updateAutoHeight();\n            }\n        };\n        \n        /*=========================\n          Resize Handler\n          ===========================*/\n        s.onResize = function (forceUpdatePagination) {\n            //Breakpoints\n            if (s.params.breakpoints) {\n                s.setBreakpoint();\n            }\n        \n            // Disable locks on resize\n            var allowSwipeToPrev = s.params.allowSwipeToPrev;\n            var allowSwipeToNext = s.params.allowSwipeToNext;\n            s.params.allowSwipeToPrev = s.params.allowSwipeToNext = true;\n        \n            s.updateContainerSize();\n            s.updateSlidesSize();\n            if (s.params.slidesPerView === 'auto' || s.params.freeMode || forceUpdatePagination) s.updatePagination();\n            if (s.params.scrollbar && s.scrollbar) {\n                s.scrollbar.set();\n            }\n            if (s.controller && s.controller.spline) {\n                s.controller.spline = undefined;\n            }\n            var slideChangedBySlideTo = false;\n            if (s.params.freeMode) {\n                var newTranslate = Math.min(Math.max(s.translate, s.maxTranslate()), s.minTranslate());\n                s.setWrapperTranslate(newTranslate);\n                s.updateActiveIndex();\n                s.updateClasses();\n        \n                if (s.params.autoHeight) {\n                    s.updateAutoHeight();\n                }\n            }\n            else {\n                s.updateClasses();\n                if ((s.params.slidesPerView === 'auto' || s.params.slidesPerView > 1) && s.isEnd && !s.params.centeredSlides) {\n                    slideChangedBySlideTo = s.slideTo(s.slides.length - 1, 0, false, true);\n                }\n                else {\n                    slideChangedBySlideTo = s.slideTo(s.activeIndex, 0, false, true);\n                }\n            }\n            if (s.params.lazyLoading && !slideChangedBySlideTo && s.lazy) {\n                s.lazy.load();\n            }\n            // Return locks after resize\n            s.params.allowSwipeToPrev = allowSwipeToPrev;\n            s.params.allowSwipeToNext = allowSwipeToNext;\n        };\n        \n        /*=========================\n          Events\n          ===========================*/\n        \n        //Define Touch Events\n        var desktopEvents = ['mousedown', 'mousemove', 'mouseup'];\n        if (window.navigator.pointerEnabled) desktopEvents = ['pointerdown', 'pointermove', 'pointerup'];\n        else if (window.navigator.msPointerEnabled) desktopEvents = ['MSPointerDown', 'MSPointerMove', 'MSPointerUp'];\n        s.touchEvents = {\n            start : s.support.touch || !s.params.simulateTouch  ? 'touchstart' : desktopEvents[0],\n            move : s.support.touch || !s.params.simulateTouch ? 'touchmove' : desktopEvents[1],\n            end : s.support.touch || !s.params.simulateTouch ? 'touchend' : desktopEvents[2]\n        };\n        \n        \n        // WP8 Touch Events Fix\n        if (window.navigator.pointerEnabled || window.navigator.msPointerEnabled) {\n            (s.params.touchEventsTarget === 'container' ? s.container : s.wrapper).addClass('swiper-wp8-' + s.params.direction);\n        }\n        \n        // Attach/detach events\n        s.initEvents = function (detach) {\n            var actionDom = detach ? 'off' : 'on';\n            var action = detach ? 'removeEventListener' : 'addEventListener';\n            var touchEventsTarget = s.params.touchEventsTarget === 'container' ? s.container[0] : s.wrapper[0];\n            var target = s.support.touch ? touchEventsTarget : document;\n        \n            var moveCapture = s.params.nested ? true : false;\n        \n            //Touch Events\n            if (s.browser.ie) {\n                touchEventsTarget[action](s.touchEvents.start, s.onTouchStart, false);\n                target[action](s.touchEvents.move, s.onTouchMove, moveCapture);\n                target[action](s.touchEvents.end, s.onTouchEnd, false);\n            }\n            else {\n                if (s.support.touch) {\n                    touchEventsTarget[action](s.touchEvents.start, s.onTouchStart, false);\n                    touchEventsTarget[action](s.touchEvents.move, s.onTouchMove, moveCapture);\n                    touchEventsTarget[action](s.touchEvents.end, s.onTouchEnd, false);\n                }\n                if (params.simulateTouch && !s.device.ios && !s.device.android) {\n                    touchEventsTarget[action]('mousedown', s.onTouchStart, false);\n                    document[action]('mousemove', s.onTouchMove, moveCapture);\n                    document[action]('mouseup', s.onTouchEnd, false);\n                }\n            }\n            window[action]('resize', s.onResize);\n        \n            // Next, Prev, Index\n            if (s.params.nextButton && s.nextButton && s.nextButton.length > 0) {\n                s.nextButton[actionDom]('click', s.onClickNext);\n                if (s.params.a11y && s.a11y) s.nextButton[actionDom]('keydown', s.a11y.onEnterKey);\n            }\n            if (s.params.prevButton && s.prevButton && s.prevButton.length > 0) {\n                s.prevButton[actionDom]('click', s.onClickPrev);\n                if (s.params.a11y && s.a11y) s.prevButton[actionDom]('keydown', s.a11y.onEnterKey);\n            }\n            if (s.params.pagination && s.params.paginationClickable) {\n                s.paginationContainer[actionDom]('click', '.' + s.params.bulletClass, s.onClickIndex);\n                if (s.params.a11y && s.a11y) s.paginationContainer[actionDom]('keydown', '.' + s.params.bulletClass, s.a11y.onEnterKey);\n            }\n        \n            // Prevent Links Clicks\n            if (s.params.preventClicks || s.params.preventClicksPropagation) touchEventsTarget[action]('click', s.preventClicks, true);\n        };\n        s.attachEvents = function () {\n            s.initEvents();\n        };\n        s.detachEvents = function () {\n            s.initEvents(true);\n        };\n        \n        /*=========================\n          Handle Clicks\n          ===========================*/\n        // Prevent Clicks\n        s.allowClick = true;\n        s.preventClicks = function (e) {\n            if (!s.allowClick) {\n                if (s.params.preventClicks) e.preventDefault();\n                if (s.params.preventClicksPropagation && s.animating) {\n                    e.stopPropagation();\n                    e.stopImmediatePropagation();\n                }\n            }\n        };\n        // Clicks\n        s.onClickNext = function (e) {\n            e.preventDefault();\n            if (s.isEnd && !s.params.loop) return;\n            s.slideNext();\n        };\n        s.onClickPrev = function (e) {\n            e.preventDefault();\n            if (s.isBeginning && !s.params.loop) return;\n            s.slidePrev();\n        };\n        s.onClickIndex = function (e) {\n            e.preventDefault();\n            var index = $(this).index() * s.params.slidesPerGroup;\n            if (s.params.loop) index = index + s.loopedSlides;\n            s.slideTo(index);\n        };\n        \n        /*=========================\n          Handle Touches\n          ===========================*/\n        function findElementInEvent(e, selector) {\n            var el = $(e.target);\n            if (!el.is(selector)) {\n                if (typeof selector === 'string') {\n                    el = el.parents(selector);\n                }\n                else if (selector.nodeType) {\n                    var found;\n                    el.parents().each(function (index, _el) {\n                        if (_el === selector) found = selector;\n                    });\n                    if (!found) return undefined;\n                    else return selector;\n                }\n            }\n            if (el.length === 0) {\n                return undefined;\n            }\n            return el[0];\n        }\n        s.updateClickedSlide = function (e) {\n            var slide = findElementInEvent(e, '.' + s.params.slideClass);\n            var slideFound = false;\n            if (slide) {\n                for (var i = 0; i < s.slides.length; i++) {\n                    if (s.slides[i] === slide) slideFound = true;\n                }\n            }\n        \n            if (slide && slideFound) {\n                s.clickedSlide = slide;\n                s.clickedIndex = $(slide).index();\n            }\n            else {\n                s.clickedSlide = undefined;\n                s.clickedIndex = undefined;\n                return;\n            }\n            if (s.params.slideToClickedSlide && s.clickedIndex !== undefined && s.clickedIndex !== s.activeIndex) {\n                var slideToIndex = s.clickedIndex,\n                    realIndex,\n                    duplicatedSlides;\n                if (s.params.loop) {\n                    if (s.animating) return;\n                    realIndex = $(s.clickedSlide).attr('data-swiper-slide-index');\n                    if (s.params.centeredSlides) {\n                        if ((slideToIndex < s.loopedSlides - s.params.slidesPerView/2) || (slideToIndex > s.slides.length - s.loopedSlides + s.params.slidesPerView/2)) {\n                            s.fixLoop();\n                            slideToIndex = s.wrapper.children('.' + s.params.slideClass + '[data-swiper-slide-index=\"' + realIndex + '\"]:not(.swiper-slide-duplicate)').eq(0).index();\n                            setTimeout(function () {\n                                s.slideTo(slideToIndex);\n                            }, 0);\n                        }\n                        else {\n                            s.slideTo(slideToIndex);\n                        }\n                    }\n                    else {\n                        if (slideToIndex > s.slides.length - s.params.slidesPerView) {\n                            s.fixLoop();\n                            slideToIndex = s.wrapper.children('.' + s.params.slideClass + '[data-swiper-slide-index=\"' + realIndex + '\"]:not(.swiper-slide-duplicate)').eq(0).index();\n                            setTimeout(function () {\n                                s.slideTo(slideToIndex);\n                            }, 0);\n                        }\n                        else {\n                            s.slideTo(slideToIndex);\n                        }\n                    }\n                }\n                else {\n                    s.slideTo(slideToIndex);\n                }\n            }\n        };\n        \n        var isTouched,\n            isMoved,\n            allowTouchCallbacks,\n            touchStartTime,\n            isScrolling,\n            currentTranslate,\n            startTranslate,\n            allowThresholdMove,\n            // Form elements to match\n            formElements = 'input, select, textarea, button',\n            // Last click time\n            lastClickTime = Date.now(), clickTimeout,\n            //Velocities\n            velocities = [],\n            allowMomentumBounce;\n        \n        // Animating Flag\n        s.animating = false;\n        \n        // Touches information\n        s.touches = {\n            startX: 0,\n            startY: 0,\n            currentX: 0,\n            currentY: 0,\n            diff: 0\n        };\n        \n        // Touch handlers\n        var isTouchEvent, startMoving;\n        s.onTouchStart = function (e) {\n            if (e.originalEvent) e = e.originalEvent;\n            isTouchEvent = e.type === 'touchstart';\n            if (!isTouchEvent && 'which' in e && e.which === 3) return;\n            if (s.params.noSwiping && findElementInEvent(e, '.' + s.params.noSwipingClass)) {\n                s.allowClick = true;\n                return;\n            }\n            if (s.params.swipeHandler) {\n                if (!findElementInEvent(e, s.params.swipeHandler)) return;\n            }\n        \n            var startX = s.touches.currentX = e.type === 'touchstart' ? e.targetTouches[0].pageX : e.pageX;\n            var startY = s.touches.currentY = e.type === 'touchstart' ? e.targetTouches[0].pageY : e.pageY;\n        \n            // Do NOT start if iOS edge swipe is detected. Otherwise iOS app (UIWebView) cannot swipe-to-go-back anymore\n            if(s.device.ios && s.params.iOSEdgeSwipeDetection && startX <= s.params.iOSEdgeSwipeThreshold) {\n                return;\n            }\n        \n            isTouched = true;\n            isMoved = false;\n            allowTouchCallbacks = true;\n            isScrolling = undefined;\n            startMoving = undefined;\n            s.touches.startX = startX;\n            s.touches.startY = startY;\n            touchStartTime = Date.now();\n            s.allowClick = true;\n            s.updateContainerSize();\n            s.swipeDirection = undefined;\n            if (s.params.threshold > 0) allowThresholdMove = false;\n            if (e.type !== 'touchstart') {\n                var preventDefault = true;\n                if ($(e.target).is(formElements)) preventDefault = false;\n                if (document.activeElement && $(document.activeElement).is(formElements)) {\n                    document.activeElement.blur();\n                }\n                if (preventDefault) {\n                    e.preventDefault();\n                }\n            }\n            s.emit('onTouchStart', s, e);\n        };\n        \n        s.onTouchMove = function (e) {\n            if (e.originalEvent) e = e.originalEvent;\n            if (isTouchEvent && e.type === 'mousemove') return;\n            if (e.preventedByNestedSwiper) {\n                s.touches.startX = e.type === 'touchmove' ? e.targetTouches[0].pageX : e.pageX;\n                s.touches.startY = e.type === 'touchmove' ? e.targetTouches[0].pageY : e.pageY;\n                return;\n            }\n            if (s.params.onlyExternal) {\n                // isMoved = true;\n                s.allowClick = false;\n                if (isTouched) {\n                    s.touches.startX = s.touches.currentX = e.type === 'touchmove' ? e.targetTouches[0].pageX : e.pageX;\n                    s.touches.startY = s.touches.currentY = e.type === 'touchmove' ? e.targetTouches[0].pageY : e.pageY;\n                    touchStartTime = Date.now();\n                }\n                return;\n            }\n            if (isTouchEvent && document.activeElement) {\n                if (e.target === document.activeElement && $(e.target).is(formElements)) {\n                    isMoved = true;\n                    s.allowClick = false;\n                    return;\n                }\n            }\n            if (allowTouchCallbacks) {\n                s.emit('onTouchMove', s, e);\n            }\n            if (e.targetTouches && e.targetTouches.length > 1) return;\n        \n            s.touches.currentX = e.type === 'touchmove' ? e.targetTouches[0].pageX : e.pageX;\n            s.touches.currentY = e.type === 'touchmove' ? e.targetTouches[0].pageY : e.pageY;\n        \n            if (typeof isScrolling === 'undefined') {\n                var touchAngle = Math.atan2(Math.abs(s.touches.currentY - s.touches.startY), Math.abs(s.touches.currentX - s.touches.startX)) * 180 / Math.PI;\n                isScrolling = s.isHorizontal() ? touchAngle > s.params.touchAngle : (90 - touchAngle > s.params.touchAngle);\n            }\n            if (isScrolling) {\n                s.emit('onTouchMoveOpposite', s, e);\n            }\n            if (typeof startMoving === 'undefined' && s.browser.ieTouch) {\n                if (s.touches.currentX !== s.touches.startX || s.touches.currentY !== s.touches.startY) {\n                    startMoving = true;\n                }\n            }\n            if (!isTouched) return;\n            if (isScrolling)  {\n                isTouched = false;\n                return;\n            }\n            if (!startMoving && s.browser.ieTouch) {\n                return;\n            }\n            s.allowClick = false;\n            s.emit('onSliderMove', s, e);\n            e.preventDefault();\n            if (s.params.touchMoveStopPropagation && !s.params.nested) {\n                e.stopPropagation();\n            }\n        \n            if (!isMoved) {\n                if (params.loop) {\n                    s.fixLoop();\n                }\n                startTranslate = s.getWrapperTranslate();\n                s.setWrapperTransition(0);\n                if (s.animating) {\n                    s.wrapper.trigger('webkitTransitionEnd transitionend oTransitionEnd MSTransitionEnd msTransitionEnd');\n                }\n                if (s.params.autoplay && s.autoplaying) {\n                    if (s.params.autoplayDisableOnInteraction) {\n                        s.stopAutoplay();\n                    }\n                    else {\n                        s.pauseAutoplay();\n                    }\n                }\n                allowMomentumBounce = false;\n                //Grab Cursor\n                if (s.params.grabCursor) {\n                    s.container[0].style.cursor = 'move';\n                    s.container[0].style.cursor = '-webkit-grabbing';\n                    s.container[0].style.cursor = '-moz-grabbin';\n                    s.container[0].style.cursor = 'grabbing';\n                }\n            }\n            isMoved = true;\n        \n            var diff = s.touches.diff = s.isHorizontal() ? s.touches.currentX - s.touches.startX : s.touches.currentY - s.touches.startY;\n        \n            diff = diff * s.params.touchRatio;\n            if (s.rtl) diff = -diff;\n        \n            s.swipeDirection = diff > 0 ? 'prev' : 'next';\n            currentTranslate = diff + startTranslate;\n        \n            var disableParentSwiper = true;\n            if ((diff > 0 && currentTranslate > s.minTranslate())) {\n                disableParentSwiper = false;\n                if (s.params.resistance) currentTranslate = s.minTranslate() - 1 + Math.pow(-s.minTranslate() + startTranslate + diff, s.params.resistanceRatio);\n            }\n            else if (diff < 0 && currentTranslate < s.maxTranslate()) {\n                disableParentSwiper = false;\n                if (s.params.resistance) currentTranslate = s.maxTranslate() + 1 - Math.pow(s.maxTranslate() - startTranslate - diff, s.params.resistanceRatio);\n            }\n        \n            if (disableParentSwiper) {\n                e.preventedByNestedSwiper = true;\n            }\n        \n            // Directions locks\n            if (!s.params.allowSwipeToNext && s.swipeDirection === 'next' && currentTranslate < startTranslate) {\n                currentTranslate = startTranslate;\n            }\n            if (!s.params.allowSwipeToPrev && s.swipeDirection === 'prev' && currentTranslate > startTranslate) {\n                currentTranslate = startTranslate;\n            }\n        \n            if (!s.params.followFinger) return;\n        \n            // Threshold\n            if (s.params.threshold > 0) {\n                if (Math.abs(diff) > s.params.threshold || allowThresholdMove) {\n                    if (!allowThresholdMove) {\n                        allowThresholdMove = true;\n                        s.touches.startX = s.touches.currentX;\n                        s.touches.startY = s.touches.currentY;\n                        currentTranslate = startTranslate;\n                        s.touches.diff = s.isHorizontal() ? s.touches.currentX - s.touches.startX : s.touches.currentY - s.touches.startY;\n                        return;\n                    }\n                }\n                else {\n                    currentTranslate = startTranslate;\n                    return;\n                }\n            }\n            // Update active index in free mode\n            if (s.params.freeMode || s.params.watchSlidesProgress) {\n                s.updateActiveIndex();\n            }\n            if (s.params.freeMode) {\n                //Velocity\n                if (velocities.length === 0) {\n                    velocities.push({\n                        position: s.touches[s.isHorizontal() ? 'startX' : 'startY'],\n                        time: touchStartTime\n                    });\n                }\n                velocities.push({\n                    position: s.touches[s.isHorizontal() ? 'currentX' : 'currentY'],\n                    time: (new window.Date()).getTime()\n                });\n            }\n            // Update progress\n            s.updateProgress(currentTranslate);\n            // Update translate\n            s.setWrapperTranslate(currentTranslate);\n        };\n        s.onTouchEnd = function (e) {\n            if (e.originalEvent) e = e.originalEvent;\n            if (allowTouchCallbacks) {\n                s.emit('onTouchEnd', s, e);\n            }\n            allowTouchCallbacks = false;\n            if (!isTouched) return;\n            //Return Grab Cursor\n            if (s.params.grabCursor && isMoved && isTouched) {\n                s.container[0].style.cursor = 'move';\n                s.container[0].style.cursor = '-webkit-grab';\n                s.container[0].style.cursor = '-moz-grab';\n                s.container[0].style.cursor = 'grab';\n            }\n        \n            // Time diff\n            var touchEndTime = Date.now();\n            var timeDiff = touchEndTime - touchStartTime;\n        \n            // Tap, doubleTap, Click\n            if (s.allowClick) {\n                s.updateClickedSlide(e);\n                s.emit('onTap', s, e);\n                if (timeDiff < 300 && (touchEndTime - lastClickTime) > 300) {\n                    if (clickTimeout) clearTimeout(clickTimeout);\n                    clickTimeout = setTimeout(function () {\n                        if (!s) return;\n                        if (s.params.paginationHide && s.paginationContainer.length > 0 && !$(e.target).hasClass(s.params.bulletClass)) {\n                            s.paginationContainer.toggleClass(s.params.paginationHiddenClass);\n                        }\n                        s.emit('onClick', s, e);\n                    }, 300);\n        \n                }\n                if (timeDiff < 300 && (touchEndTime - lastClickTime) < 300) {\n                    if (clickTimeout) clearTimeout(clickTimeout);\n                    s.emit('onDoubleTap', s, e);\n                }\n            }\n        \n            lastClickTime = Date.now();\n            setTimeout(function () {\n                if (s) s.allowClick = true;\n            }, 0);\n        \n            if (!isTouched || !isMoved || !s.swipeDirection || s.touches.diff === 0 || currentTranslate === startTranslate) {\n                isTouched = isMoved = false;\n                return;\n            }\n            isTouched = isMoved = false;\n        \n            var currentPos;\n            if (s.params.followFinger) {\n                currentPos = s.rtl ? s.translate : -s.translate;\n            }\n            else {\n                currentPos = -currentTranslate;\n            }\n            if (s.params.freeMode) {\n                if (currentPos < -s.minTranslate()) {\n                    s.slideTo(s.activeIndex);\n                    return;\n                }\n                else if (currentPos > -s.maxTranslate()) {\n                    if (s.slides.length < s.snapGrid.length) {\n                        s.slideTo(s.snapGrid.length - 1);\n                    }\n                    else {\n                        s.slideTo(s.slides.length - 1);\n                    }\n                    return;\n                }\n        \n                if (s.params.freeModeMomentum) {\n                    if (velocities.length > 1) {\n                        var lastMoveEvent = velocities.pop(), velocityEvent = velocities.pop();\n        \n                        var distance = lastMoveEvent.position - velocityEvent.position;\n                        var time = lastMoveEvent.time - velocityEvent.time;\n                        s.velocity = distance / time;\n                        s.velocity = s.velocity / 2;\n                        if (Math.abs(s.velocity) < s.params.freeModeMinimumVelocity) {\n                            s.velocity = 0;\n                        }\n                        // this implies that the user stopped moving a finger then released.\n                        // There would be no events with distance zero, so the last event is stale.\n                        if (time > 150 || (new window.Date().getTime() - lastMoveEvent.time) > 300) {\n                            s.velocity = 0;\n                        }\n                    } else {\n                        s.velocity = 0;\n                    }\n        \n                    velocities.length = 0;\n                    var momentumDuration = 1000 * s.params.freeModeMomentumRatio;\n                    var momentumDistance = s.velocity * momentumDuration;\n        \n                    var newPosition = s.translate + momentumDistance;\n                    if (s.rtl) newPosition = - newPosition;\n                    var doBounce = false;\n                    var afterBouncePosition;\n                    var bounceAmount = Math.abs(s.velocity) * 20 * s.params.freeModeMomentumBounceRatio;\n                    if (newPosition < s.maxTranslate()) {\n                        if (s.params.freeModeMomentumBounce) {\n                            if (newPosition + s.maxTranslate() < -bounceAmount) {\n                                newPosition = s.maxTranslate() - bounceAmount;\n                            }\n                            afterBouncePosition = s.maxTranslate();\n                            doBounce = true;\n                            allowMomentumBounce = true;\n                        }\n                        else {\n                            newPosition = s.maxTranslate();\n                        }\n                    }\n                    else if (newPosition > s.minTranslate()) {\n                        if (s.params.freeModeMomentumBounce) {\n                            if (newPosition - s.minTranslate() > bounceAmount) {\n                                newPosition = s.minTranslate() + bounceAmount;\n                            }\n                            afterBouncePosition = s.minTranslate();\n                            doBounce = true;\n                            allowMomentumBounce = true;\n                        }\n                        else {\n                            newPosition = s.minTranslate();\n                        }\n                    }\n                    else if (s.params.freeModeSticky) {\n                        var j = 0,\n                            nextSlide;\n                        for (j = 0; j < s.snapGrid.length; j += 1) {\n                            if (s.snapGrid[j] > -newPosition) {\n                                nextSlide = j;\n                                break;\n                            }\n        \n                        }\n                        if (Math.abs(s.snapGrid[nextSlide] - newPosition) < Math.abs(s.snapGrid[nextSlide - 1] - newPosition) || s.swipeDirection === 'next') {\n                            newPosition = s.snapGrid[nextSlide];\n                        } else {\n                            newPosition = s.snapGrid[nextSlide - 1];\n                        }\n                        if (!s.rtl) newPosition = - newPosition;\n                    }\n                    //Fix duration\n                    if (s.velocity !== 0) {\n                        if (s.rtl) {\n                            momentumDuration = Math.abs((-newPosition - s.translate) / s.velocity);\n                        }\n                        else {\n                            momentumDuration = Math.abs((newPosition - s.translate) / s.velocity);\n                        }\n                    }\n                    else if (s.params.freeModeSticky) {\n                        s.slideReset();\n                        return;\n                    }\n        \n                    if (s.params.freeModeMomentumBounce && doBounce) {\n                        s.updateProgress(afterBouncePosition);\n                        s.setWrapperTransition(momentumDuration);\n                        s.setWrapperTranslate(newPosition);\n                        s.onTransitionStart();\n                        s.animating = true;\n                        s.wrapper.transitionEnd(function () {\n                            if (!s || !allowMomentumBounce) return;\n                            s.emit('onMomentumBounce', s);\n        \n                            s.setWrapperTransition(s.params.speed);\n                            s.setWrapperTranslate(afterBouncePosition);\n                            s.wrapper.transitionEnd(function () {\n                                if (!s) return;\n                                s.onTransitionEnd();\n                            });\n                        });\n                    } else if (s.velocity) {\n                        s.updateProgress(newPosition);\n                        s.setWrapperTransition(momentumDuration);\n                        s.setWrapperTranslate(newPosition);\n                        s.onTransitionStart();\n                        if (!s.animating) {\n                            s.animating = true;\n                            s.wrapper.transitionEnd(function () {\n                                if (!s) return;\n                                s.onTransitionEnd();\n                            });\n                        }\n        \n                    } else {\n                        s.updateProgress(newPosition);\n                    }\n        \n                    s.updateActiveIndex();\n                }\n                if (!s.params.freeModeMomentum || timeDiff >= s.params.longSwipesMs) {\n                    s.updateProgress();\n                    s.updateActiveIndex();\n                }\n                return;\n            }\n        \n            // Find current slide\n            var i, stopIndex = 0, groupSize = s.slidesSizesGrid[0];\n            for (i = 0; i < s.slidesGrid.length; i += s.params.slidesPerGroup) {\n                if (typeof s.slidesGrid[i + s.params.slidesPerGroup] !== 'undefined') {\n                    if (currentPos >= s.slidesGrid[i] && currentPos < s.slidesGrid[i + s.params.slidesPerGroup]) {\n                        stopIndex = i;\n                        groupSize = s.slidesGrid[i + s.params.slidesPerGroup] - s.slidesGrid[i];\n                    }\n                }\n                else {\n                    if (currentPos >= s.slidesGrid[i]) {\n                        stopIndex = i;\n                        groupSize = s.slidesGrid[s.slidesGrid.length - 1] - s.slidesGrid[s.slidesGrid.length - 2];\n                    }\n                }\n            }\n        \n            // Find current slide size\n            var ratio = (currentPos - s.slidesGrid[stopIndex]) / groupSize;\n        \n            if (timeDiff > s.params.longSwipesMs) {\n                // Long touches\n                if (!s.params.longSwipes) {\n                    s.slideTo(s.activeIndex);\n                    return;\n                }\n                if (s.swipeDirection === 'next') {\n                    if (ratio >= s.params.longSwipesRatio) s.slideTo(stopIndex + s.params.slidesPerGroup);\n                    else s.slideTo(stopIndex);\n        \n                }\n                if (s.swipeDirection === 'prev') {\n                    if (ratio > (1 - s.params.longSwipesRatio)) s.slideTo(stopIndex + s.params.slidesPerGroup);\n                    else s.slideTo(stopIndex);\n                }\n            }\n            else {\n                // Short swipes\n                if (!s.params.shortSwipes) {\n                    s.slideTo(s.activeIndex);\n                    return;\n                }\n                if (s.swipeDirection === 'next') {\n                    s.slideTo(stopIndex + s.params.slidesPerGroup);\n        \n                }\n                if (s.swipeDirection === 'prev') {\n                    s.slideTo(stopIndex);\n                }\n            }\n        };\n        /*=========================\n          Transitions\n          ===========================*/\n        s._slideTo = function (slideIndex, speed) {\n            return s.slideTo(slideIndex, speed, true, true);\n        };\n        s.slideTo = function (slideIndex, speed, runCallbacks, internal) {\n            if (typeof runCallbacks === 'undefined') runCallbacks = true;\n            if (typeof slideIndex === 'undefined') slideIndex = 0;\n            if (slideIndex < 0) slideIndex = 0;\n            s.snapIndex = Math.floor(slideIndex / s.params.slidesPerGroup);\n            if (s.snapIndex >= s.snapGrid.length) s.snapIndex = s.snapGrid.length - 1;\n        \n            var translate = - s.snapGrid[s.snapIndex];\n            // Stop autoplay\n            if (s.params.autoplay && s.autoplaying) {\n                if (internal || !s.params.autoplayDisableOnInteraction) {\n                    s.pauseAutoplay(speed);\n                }\n                else {\n                    s.stopAutoplay();\n                }\n            }\n            // Update progress\n            s.updateProgress(translate);\n        \n            // Normalize slideIndex\n            for (var i = 0; i < s.slidesGrid.length; i++) {\n                if (- Math.floor(translate * 100) >= Math.floor(s.slidesGrid[i] * 100)) {\n                    slideIndex = i;\n                }\n            }\n        \n            // Directions locks\n            if (!s.params.allowSwipeToNext && translate < s.translate && translate < s.minTranslate()) {\n                return false;\n            }\n            if (!s.params.allowSwipeToPrev && translate > s.translate && translate > s.maxTranslate()) {\n                if ((s.activeIndex || 0) !== slideIndex ) return false;\n            }\n        \n            // Update Index\n            if (typeof speed === 'undefined') speed = s.params.speed;\n            s.previousIndex = s.activeIndex || 0;\n            s.activeIndex = slideIndex;\n        \n            if ((s.rtl && -translate === s.translate) || (!s.rtl && translate === s.translate)) {\n                // Update Height\n                if (s.params.autoHeight) {\n                    s.updateAutoHeight();\n                }\n                s.updateClasses();\n                if (s.params.effect !== 'slide') {\n                    s.setWrapperTranslate(translate);\n                }\n                return false;\n            }\n            s.updateClasses();\n            s.onTransitionStart(runCallbacks);\n        \n            if (speed === 0) {\n                s.setWrapperTranslate(translate);\n                s.setWrapperTransition(0);\n                s.onTransitionEnd(runCallbacks);\n            }\n            else {\n                s.setWrapperTranslate(translate);\n                s.setWrapperTransition(speed);\n                if (!s.animating) {\n                    s.animating = true;\n                    s.wrapper.transitionEnd(function () {\n                        if (!s) return;\n                        s.onTransitionEnd(runCallbacks);\n                    });\n                }\n        \n            }\n        \n            return true;\n        };\n        \n        s.onTransitionStart = function (runCallbacks) {\n            if (typeof runCallbacks === 'undefined') runCallbacks = true;\n            if (s.params.autoHeight) {\n                s.updateAutoHeight();\n            }\n            if (s.lazy) s.lazy.onTransitionStart();\n            if (runCallbacks) {\n                s.emit('onTransitionStart', s);\n                if (s.activeIndex !== s.previousIndex) {\n                    s.emit('onSlideChangeStart', s);\n                    if (s.activeIndex > s.previousIndex) {\n                        s.emit('onSlideNextStart', s);\n                    }\n                    else {\n                        s.emit('onSlidePrevStart', s);\n                    }\n                }\n        \n            }\n        };\n        s.onTransitionEnd = function (runCallbacks) {\n            s.animating = false;\n            s.setWrapperTransition(0);\n            if (typeof runCallbacks === 'undefined') runCallbacks = true;\n            if (s.lazy) s.lazy.onTransitionEnd();\n            if (runCallbacks) {\n                s.emit('onTransitionEnd', s);\n                if (s.activeIndex !== s.previousIndex) {\n                    s.emit('onSlideChangeEnd', s);\n                    if (s.activeIndex > s.previousIndex) {\n                        s.emit('onSlideNextEnd', s);\n                    }\n                    else {\n                        s.emit('onSlidePrevEnd', s);\n                    }\n                }\n            }\n            if (s.params.hashnav && s.hashnav) {\n                s.hashnav.setHash();\n            }\n        \n        };\n        s.slideNext = function (runCallbacks, speed, internal) {\n            if (s.params.loop) {\n                if (s.animating) return false;\n                s.fixLoop();\n                var clientLeft = s.container[0].clientLeft;\n                return s.slideTo(s.activeIndex + s.params.slidesPerGroup, speed, runCallbacks, internal);\n            }\n            else return s.slideTo(s.activeIndex + s.params.slidesPerGroup, speed, runCallbacks, internal);\n        };\n        s._slideNext = function (speed) {\n            return s.slideNext(true, speed, true);\n        };\n        s.slidePrev = function (runCallbacks, speed, internal) {\n            if (s.params.loop) {\n                if (s.animating) return false;\n                s.fixLoop();\n                var clientLeft = s.container[0].clientLeft;\n                return s.slideTo(s.activeIndex - 1, speed, runCallbacks, internal);\n            }\n            else return s.slideTo(s.activeIndex - 1, speed, runCallbacks, internal);\n        };\n        s._slidePrev = function (speed) {\n            return s.slidePrev(true, speed, true);\n        };\n        s.slideReset = function (runCallbacks, speed, internal) {\n            return s.slideTo(s.activeIndex, speed, runCallbacks);\n        };\n        \n        /*=========================\n          Translate/transition helpers\n          ===========================*/\n        s.setWrapperTransition = function (duration, byController) {\n            s.wrapper.transition(duration);\n            if (s.params.effect !== 'slide' && s.effects[s.params.effect]) {\n                s.effects[s.params.effect].setTransition(duration);\n            }\n            if (s.params.parallax && s.parallax) {\n                s.parallax.setTransition(duration);\n            }\n            if (s.params.scrollbar && s.scrollbar) {\n                s.scrollbar.setTransition(duration);\n            }\n            if (s.params.control && s.controller) {\n                s.controller.setTransition(duration, byController);\n            }\n            s.emit('onSetTransition', s, duration);\n        };\n        s.setWrapperTranslate = function (translate, updateActiveIndex, byController) {\n            var x = 0, y = 0, z = 0;\n            if (s.isHorizontal()) {\n                x = s.rtl ? -translate : translate;\n            }\n            else {\n                y = translate;\n            }\n        \n            if (s.params.roundLengths) {\n                x = round(x);\n                y = round(y);\n            }\n        \n            if (!s.params.virtualTranslate) {\n                if (s.support.transforms3d) s.wrapper.transform('translate3d(' + x + 'px, ' + y + 'px, ' + z + 'px)');\n                else s.wrapper.transform('translate(' + x + 'px, ' + y + 'px)');\n            }\n        \n            s.translate = s.isHorizontal() ? x : y;\n        \n            // Check if we need to update progress\n            var progress;\n            var translatesDiff = s.maxTranslate() - s.minTranslate();\n            if (translatesDiff === 0) {\n                progress = 0;\n            }\n            else {\n                progress = (translate - s.minTranslate()) / (translatesDiff);\n            }\n            if (progress !== s.progress) {\n                s.updateProgress(translate);\n            }\n        \n            if (updateActiveIndex) s.updateActiveIndex();\n            if (s.params.effect !== 'slide' && s.effects[s.params.effect]) {\n                s.effects[s.params.effect].setTranslate(s.translate);\n            }\n            if (s.params.parallax && s.parallax) {\n                s.parallax.setTranslate(s.translate);\n            }\n            if (s.params.scrollbar && s.scrollbar) {\n                s.scrollbar.setTranslate(s.translate);\n            }\n            if (s.params.control && s.controller) {\n                s.controller.setTranslate(s.translate, byController);\n            }\n            s.emit('onSetTranslate', s, s.translate);\n        };\n        \n        s.getTranslate = function (el, axis) {\n            var matrix, curTransform, curStyle, transformMatrix;\n        \n            // automatic axis detection\n            if (typeof axis === 'undefined') {\n                axis = 'x';\n            }\n        \n            if (s.params.virtualTranslate) {\n                return s.rtl ? -s.translate : s.translate;\n            }\n        \n            curStyle = window.getComputedStyle(el, null);\n            if (window.WebKitCSSMatrix) {\n                curTransform = curStyle.transform || curStyle.webkitTransform;\n                if (curTransform.split(',').length > 6) {\n                    curTransform = curTransform.split(', ').map(function(a){\n                        return a.replace(',','.');\n                    }).join(', ');\n                }\n                // Some old versions of Webkit choke when 'none' is passed; pass\n                // empty string instead in this case\n                transformMatrix = new window.WebKitCSSMatrix(curTransform === 'none' ? '' : curTransform);\n            }\n            else {\n                transformMatrix = curStyle.MozTransform || curStyle.OTransform || curStyle.MsTransform || curStyle.msTransform  || curStyle.transform || curStyle.getPropertyValue('transform').replace('translate(', 'matrix(1, 0, 0, 1,');\n                matrix = transformMatrix.toString().split(',');\n            }\n        \n            if (axis === 'x') {\n                //Latest Chrome and webkits Fix\n                if (window.WebKitCSSMatrix)\n                    curTransform = transformMatrix.m41;\n                //Crazy IE10 Matrix\n                else if (matrix.length === 16)\n                    curTransform = parseFloat(matrix[12]);\n                //Normal Browsers\n                else\n                    curTransform = parseFloat(matrix[4]);\n            }\n            if (axis === 'y') {\n                //Latest Chrome and webkits Fix\n                if (window.WebKitCSSMatrix)\n                    curTransform = transformMatrix.m42;\n                //Crazy IE10 Matrix\n                else if (matrix.length === 16)\n                    curTransform = parseFloat(matrix[13]);\n                //Normal Browsers\n                else\n                    curTransform = parseFloat(matrix[5]);\n            }\n            if (s.rtl && curTransform) curTransform = -curTransform;\n            return curTransform || 0;\n        };\n        s.getWrapperTranslate = function (axis) {\n            if (typeof axis === 'undefined') {\n                axis = s.isHorizontal() ? 'x' : 'y';\n            }\n            return s.getTranslate(s.wrapper[0], axis);\n        };\n        \n        /*=========================\n          Observer\n          ===========================*/\n        s.observers = [];\n        function initObserver(target, options) {\n            options = options || {};\n            // create an observer instance\n            var ObserverFunc = window.MutationObserver || window.WebkitMutationObserver;\n            var observer = new ObserverFunc(function (mutations) {\n                mutations.forEach(function (mutation) {\n                    s.onResize(true);\n                    s.emit('onObserverUpdate', s, mutation);\n                });\n            });\n        \n            observer.observe(target, {\n                attributes: typeof options.attributes === 'undefined' ? true : options.attributes,\n                childList: typeof options.childList === 'undefined' ? true : options.childList,\n                characterData: typeof options.characterData === 'undefined' ? true : options.characterData\n            });\n        \n            s.observers.push(observer);\n        }\n        s.initObservers = function () {\n            if (s.params.observeParents) {\n                var containerParents = s.container.parents();\n                for (var i = 0; i < containerParents.length; i++) {\n                    initObserver(containerParents[i]);\n                }\n            }\n        \n            // Observe container\n            initObserver(s.container[0], {childList: false});\n        \n            // Observe wrapper\n            initObserver(s.wrapper[0], {attributes: false});\n        };\n        s.disconnectObservers = function () {\n            for (var i = 0; i < s.observers.length; i++) {\n                s.observers[i].disconnect();\n            }\n            s.observers = [];\n        };\n        /*=========================\n          Loop\n          ===========================*/\n        // Create looped slides\n        s.createLoop = function () {\n            // Remove duplicated slides\n            s.wrapper.children('.' + s.params.slideClass + '.' + s.params.slideDuplicateClass).remove();\n        \n            var slides = s.wrapper.children('.' + s.params.slideClass);\n        \n            if(s.params.slidesPerView === 'auto' && !s.params.loopedSlides) s.params.loopedSlides = slides.length;\n        \n            s.loopedSlides = parseInt(s.params.loopedSlides || s.params.slidesPerView, 10);\n            s.loopedSlides = s.loopedSlides + s.params.loopAdditionalSlides;\n            if (s.loopedSlides > slides.length) {\n                s.loopedSlides = slides.length;\n            }\n        \n            var prependSlides = [], appendSlides = [], i;\n            slides.each(function (index, el) {\n                var slide = $(this);\n                if (index < s.loopedSlides) appendSlides.push(el);\n                if (index < slides.length && index >= slides.length - s.loopedSlides) prependSlides.push(el);\n                slide.attr('data-swiper-slide-index', index);\n            });\n            for (i = 0; i < appendSlides.length; i++) {\n                s.wrapper.append($(appendSlides[i].cloneNode(true)).addClass(s.params.slideDuplicateClass));\n            }\n            for (i = prependSlides.length - 1; i >= 0; i--) {\n                s.wrapper.prepend($(prependSlides[i].cloneNode(true)).addClass(s.params.slideDuplicateClass));\n            }\n        };\n        s.destroyLoop = function () {\n            s.wrapper.children('.' + s.params.slideClass + '.' + s.params.slideDuplicateClass).remove();\n            s.slides.removeAttr('data-swiper-slide-index');\n        };\n        s.reLoop = function (updatePosition) {\n            var oldIndex = s.activeIndex - s.loopedSlides;\n            s.destroyLoop();\n            s.createLoop();\n            s.updateSlidesSize();\n            if (updatePosition) {\n                s.slideTo(oldIndex + s.loopedSlides, 0, false);\n            }\n        \n        };\n        s.fixLoop = function () {\n            var newIndex;\n            //Fix For Negative Oversliding\n            if (s.activeIndex < s.loopedSlides) {\n                newIndex = s.slides.length - s.loopedSlides * 3 + s.activeIndex;\n                newIndex = newIndex + s.loopedSlides;\n                s.slideTo(newIndex, 0, false, true);\n            }\n            //Fix For Positive Oversliding\n            else if ((s.params.slidesPerView === 'auto' && s.activeIndex >= s.loopedSlides * 2) || (s.activeIndex > s.slides.length - s.params.slidesPerView * 2)) {\n                newIndex = -s.slides.length + s.activeIndex + s.loopedSlides;\n                newIndex = newIndex + s.loopedSlides;\n                s.slideTo(newIndex, 0, false, true);\n            }\n        };\n        /*=========================\n          Append/Prepend/Remove Slides\n          ===========================*/\n        s.appendSlide = function (slides) {\n            if (s.params.loop) {\n                s.destroyLoop();\n            }\n            if (typeof slides === 'object' && slides.length) {\n                for (var i = 0; i < slides.length; i++) {\n                    if (slides[i]) s.wrapper.append(slides[i]);\n                }\n            }\n            else {\n                s.wrapper.append(slides);\n            }\n            if (s.params.loop) {\n                s.createLoop();\n            }\n            if (!(s.params.observer && s.support.observer)) {\n                s.update(true);\n            }\n        };\n        s.prependSlide = function (slides) {\n            if (s.params.loop) {\n                s.destroyLoop();\n            }\n            var newActiveIndex = s.activeIndex + 1;\n            if (typeof slides === 'object' && slides.length) {\n                for (var i = 0; i < slides.length; i++) {\n                    if (slides[i]) s.wrapper.prepend(slides[i]);\n                }\n                newActiveIndex = s.activeIndex + slides.length;\n            }\n            else {\n                s.wrapper.prepend(slides);\n            }\n            if (s.params.loop) {\n                s.createLoop();\n            }\n            if (!(s.params.observer && s.support.observer)) {\n                s.update(true);\n            }\n            s.slideTo(newActiveIndex, 0, false);\n        };\n        s.removeSlide = function (slidesIndexes) {\n            if (s.params.loop) {\n                s.destroyLoop();\n                s.slides = s.wrapper.children('.' + s.params.slideClass);\n            }\n            var newActiveIndex = s.activeIndex,\n                indexToRemove;\n            if (typeof slidesIndexes === 'object' && slidesIndexes.length) {\n                for (var i = 0; i < slidesIndexes.length; i++) {\n                    indexToRemove = slidesIndexes[i];\n                    if (s.slides[indexToRemove]) s.slides.eq(indexToRemove).remove();\n                    if (indexToRemove < newActiveIndex) newActiveIndex--;\n                }\n                newActiveIndex = Math.max(newActiveIndex, 0);\n            }\n            else {\n                indexToRemove = slidesIndexes;\n                if (s.slides[indexToRemove]) s.slides.eq(indexToRemove).remove();\n                if (indexToRemove < newActiveIndex) newActiveIndex--;\n                newActiveIndex = Math.max(newActiveIndex, 0);\n            }\n        \n            if (s.params.loop) {\n                s.createLoop();\n            }\n        \n            if (!(s.params.observer && s.support.observer)) {\n                s.update(true);\n            }\n            if (s.params.loop) {\n                s.slideTo(newActiveIndex + s.loopedSlides, 0, false);\n            }\n            else {\n                s.slideTo(newActiveIndex, 0, false);\n            }\n        \n        };\n        s.removeAllSlides = function () {\n            var slidesIndexes = [];\n            for (var i = 0; i < s.slides.length; i++) {\n                slidesIndexes.push(i);\n            }\n            s.removeSlide(slidesIndexes);\n        };\n        \n\n        /*=========================\n          Effects\n          ===========================*/\n        s.effects = {\n            fade: {\n                setTranslate: function () {\n                    for (var i = 0; i < s.slides.length; i++) {\n                        var slide = s.slides.eq(i);\n                        var offset = slide[0].swiperSlideOffset;\n                        var tx = -offset;\n                        if (!s.params.virtualTranslate) tx = tx - s.translate;\n                        var ty = 0;\n                        if (!s.isHorizontal()) {\n                            ty = tx;\n                            tx = 0;\n                        }\n                        var slideOpacity = s.params.fade.crossFade ?\n                                Math.max(1 - Math.abs(slide[0].progress), 0) :\n                                1 + Math.min(Math.max(slide[0].progress, -1), 0);\n                        slide\n                            .css({\n                                opacity: slideOpacity\n                            })\n                            .transform('translate3d(' + tx + 'px, ' + ty + 'px, 0px)');\n        \n                    }\n        \n                },\n                setTransition: function (duration) {\n                    s.slides.transition(duration);\n                    if (s.params.virtualTranslate && duration !== 0) {\n                        var eventTriggered = false;\n                        s.slides.transitionEnd(function () {\n                            if (eventTriggered) return;\n                            if (!s) return;\n                            eventTriggered = true;\n                            s.animating = false;\n                            var triggerEvents = ['webkitTransitionEnd', 'transitionend', 'oTransitionEnd', 'MSTransitionEnd', 'msTransitionEnd'];\n                            for (var i = 0; i < triggerEvents.length; i++) {\n                                s.wrapper.trigger(triggerEvents[i]);\n                            }\n                        });\n                    }\n                }\n            },\n            flip: {\n                setTranslate: function () {\n                    for (var i = 0; i < s.slides.length; i++) {\n                        var slide = s.slides.eq(i);\n                        var progress = slide[0].progress;\n                        if (s.params.flip.limitRotation) {\n                            progress = Math.max(Math.min(slide[0].progress, 1), -1);\n                        }\n                        var offset = slide[0].swiperSlideOffset;\n                        var rotate = -180 * progress,\n                            rotateY = rotate,\n                            rotateX = 0,\n                            tx = -offset,\n                            ty = 0;\n                        if (!s.isHorizontal()) {\n                            ty = tx;\n                            tx = 0;\n                            rotateX = -rotateY;\n                            rotateY = 0;\n                        }\n                        else if (s.rtl) {\n                            rotateY = -rotateY;\n                        }\n        \n                        slide[0].style.zIndex = -Math.abs(Math.round(progress)) + s.slides.length;\n        \n                        if (s.params.flip.slideShadows) {\n                            //Set shadows\n                            var shadowBefore = s.isHorizontal() ? slide.find('.swiper-slide-shadow-left') : slide.find('.swiper-slide-shadow-top');\n                            var shadowAfter = s.isHorizontal() ? slide.find('.swiper-slide-shadow-right') : slide.find('.swiper-slide-shadow-bottom');\n                            if (shadowBefore.length === 0) {\n                                shadowBefore = $('<div class=\"swiper-slide-shadow-' + (s.isHorizontal() ? 'left' : 'top') + '\"></div>');\n                                slide.append(shadowBefore);\n                            }\n                            if (shadowAfter.length === 0) {\n                                shadowAfter = $('<div class=\"swiper-slide-shadow-' + (s.isHorizontal() ? 'right' : 'bottom') + '\"></div>');\n                                slide.append(shadowAfter);\n                            }\n                            if (shadowBefore.length) shadowBefore[0].style.opacity = Math.max(-progress, 0);\n                            if (shadowAfter.length) shadowAfter[0].style.opacity = Math.max(progress, 0);\n                        }\n        \n                        slide\n                            .transform('translate3d(' + tx + 'px, ' + ty + 'px, 0px) rotateX(' + rotateX + 'deg) rotateY(' + rotateY + 'deg)');\n                    }\n                },\n                setTransition: function (duration) {\n                    s.slides.transition(duration).find('.swiper-slide-shadow-top, .swiper-slide-shadow-right, .swiper-slide-shadow-bottom, .swiper-slide-shadow-left').transition(duration);\n                    if (s.params.virtualTranslate && duration !== 0) {\n                        var eventTriggered = false;\n                        s.slides.eq(s.activeIndex).transitionEnd(function () {\n                            if (eventTriggered) return;\n                            if (!s) return;\n                            if (!$(this).hasClass(s.params.slideActiveClass)) return;\n                            eventTriggered = true;\n                            s.animating = false;\n                            var triggerEvents = ['webkitTransitionEnd', 'transitionend', 'oTransitionEnd', 'MSTransitionEnd', 'msTransitionEnd'];\n                            for (var i = 0; i < triggerEvents.length; i++) {\n                                s.wrapper.trigger(triggerEvents[i]);\n                            }\n                        });\n                    }\n                }\n            },\n            cube: {\n                setTranslate: function () {\n                    var wrapperRotate = 0, cubeShadow;\n                    if (s.params.cube.shadow) {\n                        if (s.isHorizontal()) {\n                            cubeShadow = s.wrapper.find('.swiper-cube-shadow');\n                            if (cubeShadow.length === 0) {\n                                cubeShadow = $('<div class=\"swiper-cube-shadow\"></div>');\n                                s.wrapper.append(cubeShadow);\n                            }\n                            cubeShadow.css({height: s.width + 'px'});\n                        }\n                        else {\n                            cubeShadow = s.container.find('.swiper-cube-shadow');\n                            if (cubeShadow.length === 0) {\n                                cubeShadow = $('<div class=\"swiper-cube-shadow\"></div>');\n                                s.container.append(cubeShadow);\n                            }\n                        }\n                    }\n                    for (var i = 0; i < s.slides.length; i++) {\n                        var slide = s.slides.eq(i);\n                        var slideAngle = i * 90;\n                        var round = Math.floor(slideAngle / 360);\n                        if (s.rtl) {\n                            slideAngle = -slideAngle;\n                            round = Math.floor(-slideAngle / 360);\n                        }\n                        var progress = Math.max(Math.min(slide[0].progress, 1), -1);\n                        var tx = 0, ty = 0, tz = 0;\n                        if (i % 4 === 0) {\n                            tx = - round * 4 * s.size;\n                            tz = 0;\n                        }\n                        else if ((i - 1) % 4 === 0) {\n                            tx = 0;\n                            tz = - round * 4 * s.size;\n                        }\n                        else if ((i - 2) % 4 === 0) {\n                            tx = s.size + round * 4 * s.size;\n                            tz = s.size;\n                        }\n                        else if ((i - 3) % 4 === 0) {\n                            tx = - s.size;\n                            tz = 3 * s.size + s.size * 4 * round;\n                        }\n                        if (s.rtl) {\n                            tx = -tx;\n                        }\n        \n                        if (!s.isHorizontal()) {\n                            ty = tx;\n                            tx = 0;\n                        }\n        \n                        var transform = 'rotateX(' + (s.isHorizontal() ? 0 : -slideAngle) + 'deg) rotateY(' + (s.isHorizontal() ? slideAngle : 0) + 'deg) translate3d(' + tx + 'px, ' + ty + 'px, ' + tz + 'px)';\n                        if (progress <= 1 && progress > -1) {\n                            wrapperRotate = i * 90 + progress * 90;\n                            if (s.rtl) wrapperRotate = -i * 90 - progress * 90;\n                        }\n                        slide.transform(transform);\n                        if (s.params.cube.slideShadows) {\n                            //Set shadows\n                            var shadowBefore = s.isHorizontal() ? slide.find('.swiper-slide-shadow-left') : slide.find('.swiper-slide-shadow-top');\n                            var shadowAfter = s.isHorizontal() ? slide.find('.swiper-slide-shadow-right') : slide.find('.swiper-slide-shadow-bottom');\n                            if (shadowBefore.length === 0) {\n                                shadowBefore = $('<div class=\"swiper-slide-shadow-' + (s.isHorizontal() ? 'left' : 'top') + '\"></div>');\n                                slide.append(shadowBefore);\n                            }\n                            if (shadowAfter.length === 0) {\n                                shadowAfter = $('<div class=\"swiper-slide-shadow-' + (s.isHorizontal() ? 'right' : 'bottom') + '\"></div>');\n                                slide.append(shadowAfter);\n                            }\n                            if (shadowBefore.length) shadowBefore[0].style.opacity = Math.max(-progress, 0);\n                            if (shadowAfter.length) shadowAfter[0].style.opacity = Math.max(progress, 0);\n                        }\n                    }\n                    s.wrapper.css({\n                        '-webkit-transform-origin': '50% 50% -' + (s.size / 2) + 'px',\n                        '-moz-transform-origin': '50% 50% -' + (s.size / 2) + 'px',\n                        '-ms-transform-origin': '50% 50% -' + (s.size / 2) + 'px',\n                        'transform-origin': '50% 50% -' + (s.size / 2) + 'px'\n                    });\n        \n                    if (s.params.cube.shadow) {\n                        if (s.isHorizontal()) {\n                            cubeShadow.transform('translate3d(0px, ' + (s.width / 2 + s.params.cube.shadowOffset) + 'px, ' + (-s.width / 2) + 'px) rotateX(90deg) rotateZ(0deg) scale(' + (s.params.cube.shadowScale) + ')');\n                        }\n                        else {\n                            var shadowAngle = Math.abs(wrapperRotate) - Math.floor(Math.abs(wrapperRotate) / 90) * 90;\n                            var multiplier = 1.5 - (Math.sin(shadowAngle * 2 * Math.PI / 360) / 2 + Math.cos(shadowAngle * 2 * Math.PI / 360) / 2);\n                            var scale1 = s.params.cube.shadowScale,\n                                scale2 = s.params.cube.shadowScale / multiplier,\n                                offset = s.params.cube.shadowOffset;\n                            cubeShadow.transform('scale3d(' + scale1 + ', 1, ' + scale2 + ') translate3d(0px, ' + (s.height / 2 + offset) + 'px, ' + (-s.height / 2 / scale2) + 'px) rotateX(-90deg)');\n                        }\n                    }\n                    var zFactor = (s.isSafari || s.isUiWebView) ? (-s.size / 2) : 0;\n                    s.wrapper.transform('translate3d(0px,0,' + zFactor + 'px) rotateX(' + (s.isHorizontal() ? 0 : wrapperRotate) + 'deg) rotateY(' + (s.isHorizontal() ? -wrapperRotate : 0) + 'deg)');\n                },\n                setTransition: function (duration) {\n                    s.slides.transition(duration).find('.swiper-slide-shadow-top, .swiper-slide-shadow-right, .swiper-slide-shadow-bottom, .swiper-slide-shadow-left').transition(duration);\n                    if (s.params.cube.shadow && !s.isHorizontal()) {\n                        s.container.find('.swiper-cube-shadow').transition(duration);\n                    }\n                }\n            },\n            coverflow: {\n                setTranslate: function () {\n                    var transform = s.translate;\n                    var center = s.isHorizontal() ? -transform + s.width / 2 : -transform + s.height / 2;\n                    var rotate = s.isHorizontal() ? s.params.coverflow.rotate: -s.params.coverflow.rotate;\n                    var translate = s.params.coverflow.depth;\n                    //Each slide offset from center\n                    for (var i = 0, length = s.slides.length; i < length; i++) {\n                        var slide = s.slides.eq(i);\n                        var slideSize = s.slidesSizesGrid[i];\n                        var slideOffset = slide[0].swiperSlideOffset;\n                        var offsetMultiplier = (center - slideOffset - slideSize / 2) / slideSize * s.params.coverflow.modifier;\n        \n                        var rotateY = s.isHorizontal() ? rotate * offsetMultiplier : 0;\n                        var rotateX = s.isHorizontal() ? 0 : rotate * offsetMultiplier;\n                        // var rotateZ = 0\n                        var translateZ = -translate * Math.abs(offsetMultiplier);\n        \n                        var translateY = s.isHorizontal() ? 0 : s.params.coverflow.stretch * (offsetMultiplier);\n                        var translateX = s.isHorizontal() ? s.params.coverflow.stretch * (offsetMultiplier) : 0;\n        \n                        //Fix for ultra small values\n                        if (Math.abs(translateX) < 0.001) translateX = 0;\n                        if (Math.abs(translateY) < 0.001) translateY = 0;\n                        if (Math.abs(translateZ) < 0.001) translateZ = 0;\n                        if (Math.abs(rotateY) < 0.001) rotateY = 0;\n                        if (Math.abs(rotateX) < 0.001) rotateX = 0;\n        \n                        var slideTransform = 'translate3d(' + translateX + 'px,' + translateY + 'px,' + translateZ + 'px)  rotateX(' + rotateX + 'deg) rotateY(' + rotateY + 'deg)';\n        \n                        slide.transform(slideTransform);\n                        slide[0].style.zIndex = -Math.abs(Math.round(offsetMultiplier)) + 1;\n                        if (s.params.coverflow.slideShadows) {\n                            //Set shadows\n                            var shadowBefore = s.isHorizontal() ? slide.find('.swiper-slide-shadow-left') : slide.find('.swiper-slide-shadow-top');\n                            var shadowAfter = s.isHorizontal() ? slide.find('.swiper-slide-shadow-right') : slide.find('.swiper-slide-shadow-bottom');\n                            if (shadowBefore.length === 0) {\n                                shadowBefore = $('<div class=\"swiper-slide-shadow-' + (s.isHorizontal() ? 'left' : 'top') + '\"></div>');\n                                slide.append(shadowBefore);\n                            }\n                            if (shadowAfter.length === 0) {\n                                shadowAfter = $('<div class=\"swiper-slide-shadow-' + (s.isHorizontal() ? 'right' : 'bottom') + '\"></div>');\n                                slide.append(shadowAfter);\n                            }\n                            if (shadowBefore.length) shadowBefore[0].style.opacity = offsetMultiplier > 0 ? offsetMultiplier : 0;\n                            if (shadowAfter.length) shadowAfter[0].style.opacity = (-offsetMultiplier) > 0 ? -offsetMultiplier : 0;\n                        }\n                    }\n        \n                    //Set correct perspective for IE10\n                    if (s.browser.ie) {\n                        var ws = s.wrapper[0].style;\n                        ws.perspectiveOrigin = center + 'px 50%';\n                    }\n                },\n                setTransition: function (duration) {\n                    s.slides.transition(duration).find('.swiper-slide-shadow-top, .swiper-slide-shadow-right, .swiper-slide-shadow-bottom, .swiper-slide-shadow-left').transition(duration);\n                }\n            }\n        };\n\n        /*=========================\n          Images Lazy Loading\n          ===========================*/\n        s.lazy = {\n            initialImageLoaded: false,\n            loadImageInSlide: function (index, loadInDuplicate) {\n                if (typeof index === 'undefined') return;\n                if (typeof loadInDuplicate === 'undefined') loadInDuplicate = true;\n                if (s.slides.length === 0) return;\n        \n                var slide = s.slides.eq(index);\n                var img = slide.find('.swiper-lazy:not(.swiper-lazy-loaded):not(.swiper-lazy-loading)');\n                if (slide.hasClass('swiper-lazy') && !slide.hasClass('swiper-lazy-loaded') && !slide.hasClass('swiper-lazy-loading')) {\n                    img = img.add(slide[0]);\n                }\n                if (img.length === 0) return;\n        \n                img.each(function () {\n                    var _img = $(this);\n                    _img.addClass('swiper-lazy-loading');\n                    var background = _img.attr('data-background');\n                    var src = _img.attr('data-src'),\n                        srcset = _img.attr('data-srcset');\n                    s.loadImage(_img[0], (src || background), srcset, false, function () {\n                        if (background) {\n                            _img.css('background-image', 'url(\"' + background + '\")');\n                            _img.removeAttr('data-background');\n                        }\n                        else {\n                            if (srcset) {\n                                _img.attr('srcset', srcset);\n                                _img.removeAttr('data-srcset');\n                            }\n                            if (src) {\n                                _img.attr('src', src);\n                                _img.removeAttr('data-src');\n                            }\n        \n                        }\n        \n                        _img.addClass('swiper-lazy-loaded').removeClass('swiper-lazy-loading');\n                        slide.find('.swiper-lazy-preloader, .preloader').remove();\n                        if (s.params.loop && loadInDuplicate) {\n                            var slideOriginalIndex = slide.attr('data-swiper-slide-index');\n                            if (slide.hasClass(s.params.slideDuplicateClass)) {\n                                var originalSlide = s.wrapper.children('[data-swiper-slide-index=\"' + slideOriginalIndex + '\"]:not(.' + s.params.slideDuplicateClass + ')');\n                                s.lazy.loadImageInSlide(originalSlide.index(), false);\n                            }\n                            else {\n                                var duplicatedSlide = s.wrapper.children('.' + s.params.slideDuplicateClass + '[data-swiper-slide-index=\"' + slideOriginalIndex + '\"]');\n                                s.lazy.loadImageInSlide(duplicatedSlide.index(), false);\n                            }\n                        }\n                        s.emit('onLazyImageReady', s, slide[0], _img[0]);\n                    });\n        \n                    s.emit('onLazyImageLoad', s, slide[0], _img[0]);\n                });\n        \n            },\n            load: function () {\n                var i;\n                if (s.params.watchSlidesVisibility) {\n                    s.wrapper.children('.' + s.params.slideVisibleClass).each(function () {\n                        s.lazy.loadImageInSlide($(this).index());\n                    });\n                }\n                else {\n                    if (s.params.slidesPerView > 1) {\n                        for (i = s.activeIndex; i < s.activeIndex + s.params.slidesPerView ; i++) {\n                            if (s.slides[i]) s.lazy.loadImageInSlide(i);\n                        }\n                    }\n                    else {\n                        s.lazy.loadImageInSlide(s.activeIndex);\n                    }\n                }\n                if (s.params.lazyLoadingInPrevNext) {\n                    if (s.params.slidesPerView > 1 || (s.params.lazyLoadingInPrevNextAmount && s.params.lazyLoadingInPrevNextAmount > 1)) {\n                        var amount = s.params.lazyLoadingInPrevNextAmount;\n                        var spv = s.params.slidesPerView;\n                        var maxIndex = Math.min(s.activeIndex + spv + Math.max(amount, spv), s.slides.length);\n                        var minIndex = Math.max(s.activeIndex - Math.max(spv, amount), 0);\n                        // Next Slides\n                        for (i = s.activeIndex + s.params.slidesPerView; i < maxIndex; i++) {\n                            if (s.slides[i]) s.lazy.loadImageInSlide(i);\n                        }\n                        // Prev Slides\n                        for (i = minIndex; i < s.activeIndex ; i++) {\n                            if (s.slides[i]) s.lazy.loadImageInSlide(i);\n                        }\n                    }\n                    else {\n                        var nextSlide = s.wrapper.children('.' + s.params.slideNextClass);\n                        if (nextSlide.length > 0) s.lazy.loadImageInSlide(nextSlide.index());\n        \n                        var prevSlide = s.wrapper.children('.' + s.params.slidePrevClass);\n                        if (prevSlide.length > 0) s.lazy.loadImageInSlide(prevSlide.index());\n                    }\n                }\n            },\n            onTransitionStart: function () {\n                if (s.params.lazyLoading) {\n                    if (s.params.lazyLoadingOnTransitionStart || (!s.params.lazyLoadingOnTransitionStart && !s.lazy.initialImageLoaded)) {\n                        s.lazy.load();\n                    }\n                }\n            },\n            onTransitionEnd: function () {\n                if (s.params.lazyLoading && !s.params.lazyLoadingOnTransitionStart) {\n                    s.lazy.load();\n                }\n            }\n        };\n        \n\n        /*=========================\n          Scrollbar\n          ===========================*/\n        s.scrollbar = {\n            isTouched: false,\n            setDragPosition: function (e) {\n                var sb = s.scrollbar;\n                var x = 0, y = 0;\n                var translate;\n                var pointerPosition = s.isHorizontal() ?\n                    ((e.type === 'touchstart' || e.type === 'touchmove') ? e.targetTouches[0].pageX : e.pageX || e.clientX) :\n                    ((e.type === 'touchstart' || e.type === 'touchmove') ? e.targetTouches[0].pageY : e.pageY || e.clientY) ;\n                var position = (pointerPosition) - sb.track.offset()[s.isHorizontal() ? 'left' : 'top'] - sb.dragSize / 2;\n                var positionMin = -s.minTranslate() * sb.moveDivider;\n                var positionMax = -s.maxTranslate() * sb.moveDivider;\n                if (position < positionMin) {\n                    position = positionMin;\n                }\n                else if (position > positionMax) {\n                    position = positionMax;\n                }\n                position = -position / sb.moveDivider;\n                s.updateProgress(position);\n                s.setWrapperTranslate(position, true);\n            },\n            dragStart: function (e) {\n                var sb = s.scrollbar;\n                sb.isTouched = true;\n                e.preventDefault();\n                e.stopPropagation();\n        \n                sb.setDragPosition(e);\n                clearTimeout(sb.dragTimeout);\n        \n                sb.track.transition(0);\n                if (s.params.scrollbarHide) {\n                    sb.track.css('opacity', 1);\n                }\n                s.wrapper.transition(100);\n                sb.drag.transition(100);\n                s.emit('onScrollbarDragStart', s);\n            },\n            dragMove: function (e) {\n                var sb = s.scrollbar;\n                if (!sb.isTouched) return;\n                if (e.preventDefault) e.preventDefault();\n                else e.returnValue = false;\n                sb.setDragPosition(e);\n                s.wrapper.transition(0);\n                sb.track.transition(0);\n                sb.drag.transition(0);\n                s.emit('onScrollbarDragMove', s);\n            },\n            dragEnd: function (e) {\n                var sb = s.scrollbar;\n                if (!sb.isTouched) return;\n                sb.isTouched = false;\n                if (s.params.scrollbarHide) {\n                    clearTimeout(sb.dragTimeout);\n                    sb.dragTimeout = setTimeout(function () {\n                        sb.track.css('opacity', 0);\n                        sb.track.transition(400);\n                    }, 1000);\n        \n                }\n                s.emit('onScrollbarDragEnd', s);\n                if (s.params.scrollbarSnapOnRelease) {\n                    s.slideReset();\n                }\n            },\n            enableDraggable: function () {\n                var sb = s.scrollbar;\n                var target = s.support.touch ? sb.track : document;\n                $(sb.track).on(s.touchEvents.start, sb.dragStart);\n                $(target).on(s.touchEvents.move, sb.dragMove);\n                $(target).on(s.touchEvents.end, sb.dragEnd);\n            },\n            disableDraggable: function () {\n                var sb = s.scrollbar;\n                var target = s.support.touch ? sb.track : document;\n                $(sb.track).off(s.touchEvents.start, sb.dragStart);\n                $(target).off(s.touchEvents.move, sb.dragMove);\n                $(target).off(s.touchEvents.end, sb.dragEnd);\n            },\n            set: function () {\n                if (!s.params.scrollbar) return;\n                var sb = s.scrollbar;\n                sb.track = $(s.params.scrollbar);\n                if (s.params.uniqueNavElements && typeof s.params.scrollbar === 'string' && sb.track.length > 1 && s.container.find(s.params.scrollbar).length === 1) {\n                    sb.track = s.container.find(s.params.scrollbar);\n                }\n                sb.drag = sb.track.find('.swiper-scrollbar-drag');\n                if (sb.drag.length === 0) {\n                    sb.drag = $('<div class=\"swiper-scrollbar-drag\"></div>');\n                    sb.track.append(sb.drag);\n                }\n                sb.drag[0].style.width = '';\n                sb.drag[0].style.height = '';\n                sb.trackSize = s.isHorizontal() ? sb.track[0].offsetWidth : sb.track[0].offsetHeight;\n        \n                sb.divider = s.size / s.virtualSize;\n                sb.moveDivider = sb.divider * (sb.trackSize / s.size);\n                sb.dragSize = sb.trackSize * sb.divider;\n        \n                if (s.isHorizontal()) {\n                    sb.drag[0].style.width = sb.dragSize + 'px';\n                }\n                else {\n                    sb.drag[0].style.height = sb.dragSize + 'px';\n                }\n        \n                if (sb.divider >= 1) {\n                    sb.track[0].style.display = 'none';\n                }\n                else {\n                    sb.track[0].style.display = '';\n                }\n                if (s.params.scrollbarHide) {\n                    sb.track[0].style.opacity = 0;\n                }\n            },\n            setTranslate: function () {\n                if (!s.params.scrollbar) return;\n                var diff;\n                var sb = s.scrollbar;\n                var translate = s.translate || 0;\n                var newPos;\n        \n                var newSize = sb.dragSize;\n                newPos = (sb.trackSize - sb.dragSize) * s.progress;\n                if (s.rtl && s.isHorizontal()) {\n                    newPos = -newPos;\n                    if (newPos > 0) {\n                        newSize = sb.dragSize - newPos;\n                        newPos = 0;\n                    }\n                    else if (-newPos + sb.dragSize > sb.trackSize) {\n                        newSize = sb.trackSize + newPos;\n                    }\n                }\n                else {\n                    if (newPos < 0) {\n                        newSize = sb.dragSize + newPos;\n                        newPos = 0;\n                    }\n                    else if (newPos + sb.dragSize > sb.trackSize) {\n                        newSize = sb.trackSize - newPos;\n                    }\n                }\n                if (s.isHorizontal()) {\n                    if (s.support.transforms3d) {\n                        sb.drag.transform('translate3d(' + (newPos) + 'px, 0, 0)');\n                    }\n                    else {\n                        sb.drag.transform('translateX(' + (newPos) + 'px)');\n                    }\n                    sb.drag[0].style.width = newSize + 'px';\n                }\n                else {\n                    if (s.support.transforms3d) {\n                        sb.drag.transform('translate3d(0px, ' + (newPos) + 'px, 0)');\n                    }\n                    else {\n                        sb.drag.transform('translateY(' + (newPos) + 'px)');\n                    }\n                    sb.drag[0].style.height = newSize + 'px';\n                }\n                if (s.params.scrollbarHide) {\n                    clearTimeout(sb.timeout);\n                    sb.track[0].style.opacity = 1;\n                    sb.timeout = setTimeout(function () {\n                        sb.track[0].style.opacity = 0;\n                        sb.track.transition(400);\n                    }, 1000);\n                }\n            },\n            setTransition: function (duration) {\n                if (!s.params.scrollbar) return;\n                s.scrollbar.drag.transition(duration);\n            }\n        };\n\n        /*=========================\n          Controller\n          ===========================*/\n        s.controller = {\n            LinearSpline: function (x, y) {\n                this.x = x;\n                this.y = y;\n                this.lastIndex = x.length - 1;\n                // Given an x value (x2), return the expected y2 value:\n                // (x1,y1) is the known point before given value,\n                // (x3,y3) is the known point after given value.\n                var i1, i3;\n                var l = this.x.length;\n        \n                this.interpolate = function (x2) {\n                    if (!x2) return 0;\n        \n                    // Get the indexes of x1 and x3 (the array indexes before and after given x2):\n                    i3 = binarySearch(this.x, x2);\n                    i1 = i3 - 1;\n        \n                    // We have our indexes i1 & i3, so we can calculate already:\n                    // y2 := ((x2−x1) × (y3−y1)) ÷ (x3−x1) + y1\n                    return ((x2 - this.x[i1]) * (this.y[i3] - this.y[i1])) / (this.x[i3] - this.x[i1]) + this.y[i1];\n                };\n        \n                var binarySearch = (function() {\n                    var maxIndex, minIndex, guess;\n                    return function(array, val) {\n                        minIndex = -1;\n                        maxIndex = array.length;\n                        while (maxIndex - minIndex > 1)\n                            if (array[guess = maxIndex + minIndex >> 1] <= val) {\n                                minIndex = guess;\n                            } else {\n                                maxIndex = guess;\n                            }\n                        return maxIndex;\n                    };\n                })();\n            },\n            //xxx: for now i will just save one spline function to to\n            getInterpolateFunction: function(c){\n                if(!s.controller.spline) s.controller.spline = s.params.loop ?\n                    new s.controller.LinearSpline(s.slidesGrid, c.slidesGrid) :\n                    new s.controller.LinearSpline(s.snapGrid, c.snapGrid);\n            },\n            setTranslate: function (translate, byController) {\n               var controlled = s.params.control;\n               var multiplier, controlledTranslate;\n               function setControlledTranslate(c) {\n                    // this will create an Interpolate function based on the snapGrids\n                    // x is the Grid of the scrolled scroller and y will be the controlled scroller\n                    // it makes sense to create this only once and recall it for the interpolation\n                    // the function does a lot of value caching for performance\n                    translate = c.rtl && c.params.direction === 'horizontal' ? -s.translate : s.translate;\n                    if (s.params.controlBy === 'slide') {\n                        s.controller.getInterpolateFunction(c);\n                        // i am not sure why the values have to be multiplicated this way, tried to invert the snapGrid\n                        // but it did not work out\n                        controlledTranslate = -s.controller.spline.interpolate(-translate);\n                    }\n        \n                    if(!controlledTranslate || s.params.controlBy === 'container'){\n                        multiplier = (c.maxTranslate() - c.minTranslate()) / (s.maxTranslate() - s.minTranslate());\n                        controlledTranslate = (translate - s.minTranslate()) * multiplier + c.minTranslate();\n                    }\n        \n                    if (s.params.controlInverse) {\n                        controlledTranslate = c.maxTranslate() - controlledTranslate;\n                    }\n                    c.updateProgress(controlledTranslate);\n                    c.setWrapperTranslate(controlledTranslate, false, s);\n                    c.updateActiveIndex();\n               }\n               if (s.isArray(controlled)) {\n                   for (var i = 0; i < controlled.length; i++) {\n                       if (controlled[i] !== byController && controlled[i] instanceof Swiper) {\n                           setControlledTranslate(controlled[i]);\n                       }\n                   }\n               }\n               else if (controlled instanceof Swiper && byController !== controlled) {\n        \n                   setControlledTranslate(controlled);\n               }\n            },\n            setTransition: function (duration, byController) {\n                var controlled = s.params.control;\n                var i;\n                function setControlledTransition(c) {\n                    c.setWrapperTransition(duration, s);\n                    if (duration !== 0) {\n                        c.onTransitionStart();\n                        c.wrapper.transitionEnd(function(){\n                            if (!controlled) return;\n                            if (c.params.loop && s.params.controlBy === 'slide') {\n                                c.fixLoop();\n                            }\n                            c.onTransitionEnd();\n        \n                        });\n                    }\n                }\n                if (s.isArray(controlled)) {\n                    for (i = 0; i < controlled.length; i++) {\n                        if (controlled[i] !== byController && controlled[i] instanceof Swiper) {\n                            setControlledTransition(controlled[i]);\n                        }\n                    }\n                }\n                else if (controlled instanceof Swiper && byController !== controlled) {\n                    setControlledTransition(controlled);\n                }\n            }\n        };\n\n        /*=========================\n          Hash Navigation\n          ===========================*/\n        s.hashnav = {\n            init: function () {\n                if (!s.params.hashnav) return;\n                s.hashnav.initialized = true;\n                var hash = document.location.hash.replace('#', '');\n                if (!hash) return;\n                var speed = 0;\n                for (var i = 0, length = s.slides.length; i < length; i++) {\n                    var slide = s.slides.eq(i);\n                    var slideHash = slide.attr('data-hash');\n                    if (slideHash === hash && !slide.hasClass(s.params.slideDuplicateClass)) {\n                        var index = slide.index();\n                        s.slideTo(index, speed, s.params.runCallbacksOnInit, true);\n                    }\n                }\n            },\n            setHash: function () {\n                if (!s.hashnav.initialized || !s.params.hashnav) return;\n                document.location.hash = s.slides.eq(s.activeIndex).attr('data-hash') || '';\n            }\n        };\n\n        /*=========================\n          Keyboard Control\n          ===========================*/\n        function handleKeyboard(e) {\n            if (e.originalEvent) e = e.originalEvent; //jquery fix\n            var kc = e.keyCode || e.charCode;\n            // Directions locks\n            if (!s.params.allowSwipeToNext && (s.isHorizontal() && kc === 39 || !s.isHorizontal() && kc === 40)) {\n                return false;\n            }\n            if (!s.params.allowSwipeToPrev && (s.isHorizontal() && kc === 37 || !s.isHorizontal() && kc === 38)) {\n                return false;\n            }\n            if (e.shiftKey || e.altKey || e.ctrlKey || e.metaKey) {\n                return;\n            }\n            if (document.activeElement && document.activeElement.nodeName && (document.activeElement.nodeName.toLowerCase() === 'input' || document.activeElement.nodeName.toLowerCase() === 'textarea')) {\n                return;\n            }\n            if (kc === 37 || kc === 39 || kc === 38 || kc === 40) {\n                var inView = false;\n                //Check that swiper should be inside of visible area of window\n                if (s.container.parents('.swiper-slide').length > 0 && s.container.parents('.swiper-slide-active').length === 0) {\n                    return;\n                }\n                var windowScroll = {\n                    left: window.pageXOffset,\n                    top: window.pageYOffset\n                };\n                var windowWidth = window.innerWidth;\n                var windowHeight = window.innerHeight;\n                var swiperOffset = s.container.offset();\n                if (s.rtl) swiperOffset.left = swiperOffset.left - s.container[0].scrollLeft;\n                var swiperCoord = [\n                    [swiperOffset.left, swiperOffset.top],\n                    [swiperOffset.left + s.width, swiperOffset.top],\n                    [swiperOffset.left, swiperOffset.top + s.height],\n                    [swiperOffset.left + s.width, swiperOffset.top + s.height]\n                ];\n                for (var i = 0; i < swiperCoord.length; i++) {\n                    var point = swiperCoord[i];\n                    if (\n                        point[0] >= windowScroll.left && point[0] <= windowScroll.left + windowWidth &&\n                        point[1] >= windowScroll.top && point[1] <= windowScroll.top + windowHeight\n                    ) {\n                        inView = true;\n                    }\n        \n                }\n                if (!inView) return;\n            }\n            if (s.isHorizontal()) {\n                if (kc === 37 || kc === 39) {\n                    if (e.preventDefault) e.preventDefault();\n                    else e.returnValue = false;\n                }\n                if ((kc === 39 && !s.rtl) || (kc === 37 && s.rtl)) s.slideNext();\n                if ((kc === 37 && !s.rtl) || (kc === 39 && s.rtl)) s.slidePrev();\n            }\n            else {\n                if (kc === 38 || kc === 40) {\n                    if (e.preventDefault) e.preventDefault();\n                    else e.returnValue = false;\n                }\n                if (kc === 40) s.slideNext();\n                if (kc === 38) s.slidePrev();\n            }\n        }\n        s.disableKeyboardControl = function () {\n            s.params.keyboardControl = false;\n            $(document).off('keydown', handleKeyboard);\n        };\n        s.enableKeyboardControl = function () {\n            s.params.keyboardControl = true;\n            $(document).on('keydown', handleKeyboard);\n        };\n        \n\n        /*=========================\n          Mousewheel Control\n          ===========================*/\n        s.mousewheel = {\n            event: false,\n            lastScrollTime: (new window.Date()).getTime()\n        };\n        if (s.params.mousewheelControl) {\n            try {\n                new window.WheelEvent('wheel');\n                s.mousewheel.event = 'wheel';\n            } catch (e) {\n                if (window.WheelEvent || (s.container[0] && 'wheel' in s.container[0])) {\n                    s.mousewheel.event = 'wheel';\n                }\n            }\n            if (!s.mousewheel.event && window.WheelEvent) {\n        \n            }\n            if (!s.mousewheel.event && document.onmousewheel !== undefined) {\n                s.mousewheel.event = 'mousewheel';\n            }\n            if (!s.mousewheel.event) {\n                s.mousewheel.event = 'DOMMouseScroll';\n            }\n        }\n        function handleMousewheel(e) {\n            if (e.originalEvent) e = e.originalEvent; //jquery fix\n            var we = s.mousewheel.event;\n            var delta = 0;\n            var rtlFactor = s.rtl ? -1 : 1;\n        \n            //WebKits\n            if (we === 'mousewheel') {\n                if (s.params.mousewheelForceToAxis) {\n                    if (s.isHorizontal()) {\n                        if (Math.abs(e.wheelDeltaX) > Math.abs(e.wheelDeltaY)) delta = e.wheelDeltaX * rtlFactor;\n                        else return;\n                    }\n                    else {\n                        if (Math.abs(e.wheelDeltaY) > Math.abs(e.wheelDeltaX)) delta = e.wheelDeltaY;\n                        else return;\n                    }\n                }\n                else {\n                    delta = Math.abs(e.wheelDeltaX) > Math.abs(e.wheelDeltaY) ? - e.wheelDeltaX * rtlFactor : - e.wheelDeltaY;\n                }\n            }\n            //Old FireFox\n            else if (we === 'DOMMouseScroll') delta = -e.detail;\n            //New FireFox\n            else if (we === 'wheel') {\n                if (s.params.mousewheelForceToAxis) {\n                    if (s.isHorizontal()) {\n                        if (Math.abs(e.deltaX) > Math.abs(e.deltaY)) delta = -e.deltaX * rtlFactor;\n                        else return;\n                    }\n                    else {\n                        if (Math.abs(e.deltaY) > Math.abs(e.deltaX)) delta = -e.deltaY;\n                        else return;\n                    }\n                }\n                else {\n                    delta = Math.abs(e.deltaX) > Math.abs(e.deltaY) ? - e.deltaX * rtlFactor : - e.deltaY;\n                }\n            }\n            if (delta === 0) return;\n        \n            if (s.params.mousewheelInvert) delta = -delta;\n        \n            if (!s.params.freeMode) {\n                if ((new window.Date()).getTime() - s.mousewheel.lastScrollTime > 60) {\n                    if (delta < 0) {\n                        if ((!s.isEnd || s.params.loop) && !s.animating) s.slideNext();\n                        else if (s.params.mousewheelReleaseOnEdges) return true;\n                    }\n                    else {\n                        if ((!s.isBeginning || s.params.loop) && !s.animating) s.slidePrev();\n                        else if (s.params.mousewheelReleaseOnEdges) return true;\n                    }\n                }\n                s.mousewheel.lastScrollTime = (new window.Date()).getTime();\n        \n            }\n            else {\n                //Freemode or scrollContainer:\n                var position = s.getWrapperTranslate() + delta * s.params.mousewheelSensitivity;\n                var wasBeginning = s.isBeginning,\n                    wasEnd = s.isEnd;\n        \n                if (position >= s.minTranslate()) position = s.minTranslate();\n                if (position <= s.maxTranslate()) position = s.maxTranslate();\n        \n                s.setWrapperTransition(0);\n                s.setWrapperTranslate(position);\n                s.updateProgress();\n                s.updateActiveIndex();\n        \n                if (!wasBeginning && s.isBeginning || !wasEnd && s.isEnd) {\n                    s.updateClasses();\n                }\n        \n                if (s.params.freeModeSticky) {\n                    clearTimeout(s.mousewheel.timeout);\n                    s.mousewheel.timeout = setTimeout(function () {\n                        s.slideReset();\n                    }, 300);\n                }\n                else {\n                    if (s.params.lazyLoading && s.lazy) {\n                        s.lazy.load();\n                    }\n                }\n        \n                // Return page scroll on edge positions\n                if (position === 0 || position === s.maxTranslate()) return;\n            }\n            if (s.params.autoplay) s.stopAutoplay();\n        \n            if (e.preventDefault) e.preventDefault();\n            else e.returnValue = false;\n            return false;\n        }\n        s.disableMousewheelControl = function () {\n            if (!s.mousewheel.event) return false;\n            s.container.off(s.mousewheel.event, handleMousewheel);\n            return true;\n        };\n        \n        s.enableMousewheelControl = function () {\n            if (!s.mousewheel.event) return false;\n            s.container.on(s.mousewheel.event, handleMousewheel);\n            return true;\n        };\n        \n\n        /*=========================\n          Parallax\n          ===========================*/\n        function setParallaxTransform(el, progress) {\n            el = $(el);\n            var p, pX, pY;\n            var rtlFactor = s.rtl ? -1 : 1;\n        \n            p = el.attr('data-swiper-parallax') || '0';\n            pX = el.attr('data-swiper-parallax-x');\n            pY = el.attr('data-swiper-parallax-y');\n            if (pX || pY) {\n                pX = pX || '0';\n                pY = pY || '0';\n            }\n            else {\n                if (s.isHorizontal()) {\n                    pX = p;\n                    pY = '0';\n                }\n                else {\n                    pY = p;\n                    pX = '0';\n                }\n            }\n        \n            if ((pX).indexOf('%') >= 0) {\n                pX = parseInt(pX, 10) * progress * rtlFactor + '%';\n            }\n            else {\n                pX = pX * progress * rtlFactor + 'px' ;\n            }\n            if ((pY).indexOf('%') >= 0) {\n                pY = parseInt(pY, 10) * progress + '%';\n            }\n            else {\n                pY = pY * progress + 'px' ;\n            }\n        \n            el.transform('translate3d(' + pX + ', ' + pY + ',0px)');\n        }\n        s.parallax = {\n            setTranslate: function () {\n                s.container.children('[data-swiper-parallax], [data-swiper-parallax-x], [data-swiper-parallax-y]').each(function(){\n                    setParallaxTransform(this, s.progress);\n        \n                });\n                s.slides.each(function () {\n                    var slide = $(this);\n                    slide.find('[data-swiper-parallax], [data-swiper-parallax-x], [data-swiper-parallax-y]').each(function () {\n                        var progress = Math.min(Math.max(slide[0].progress, -1), 1);\n                        setParallaxTransform(this, progress);\n                    });\n                });\n            },\n            setTransition: function (duration) {\n                if (typeof duration === 'undefined') duration = s.params.speed;\n                s.container.find('[data-swiper-parallax], [data-swiper-parallax-x], [data-swiper-parallax-y]').each(function(){\n                    var el = $(this);\n                    var parallaxDuration = parseInt(el.attr('data-swiper-parallax-duration'), 10) || duration;\n                    if (duration === 0) parallaxDuration = 0;\n                    el.transition(parallaxDuration);\n                });\n            }\n        };\n        \n\n        /*=========================\n          Plugins API. Collect all and init all plugins\n          ===========================*/\n        s._plugins = [];\n        for (var plugin in s.plugins) {\n            var p = s.plugins[plugin](s, s.params[plugin]);\n            if (p) s._plugins.push(p);\n        }\n        // Method to call all plugins event/method\n        s.callPlugins = function (eventName) {\n            for (var i = 0; i < s._plugins.length; i++) {\n                if (eventName in s._plugins[i]) {\n                    s._plugins[i][eventName](arguments[1], arguments[2], arguments[3], arguments[4], arguments[5]);\n                }\n            }\n        };\n\n        /*=========================\n          Events/Callbacks/Plugins Emitter\n          ===========================*/\n        function normalizeEventName (eventName) {\n            if (eventName.indexOf('on') !== 0) {\n                if (eventName[0] !== eventName[0].toUpperCase()) {\n                    eventName = 'on' + eventName[0].toUpperCase() + eventName.substring(1);\n                }\n                else {\n                    eventName = 'on' + eventName;\n                }\n            }\n            return eventName;\n        }\n        s.emitterEventListeners = {\n        \n        };\n        s.emit = function (eventName) {\n            // Trigger callbacks\n            if (s.params[eventName]) {\n                s.params[eventName](arguments[1], arguments[2], arguments[3], arguments[4], arguments[5]);\n            }\n            var i;\n            // Trigger events\n            if (s.emitterEventListeners[eventName]) {\n                for (i = 0; i < s.emitterEventListeners[eventName].length; i++) {\n                    s.emitterEventListeners[eventName][i](arguments[1], arguments[2], arguments[3], arguments[4], arguments[5]);\n                }\n            }\n            // Trigger plugins\n            if (s.callPlugins) s.callPlugins(eventName, arguments[1], arguments[2], arguments[3], arguments[4], arguments[5]);\n        };\n        s.on = function (eventName, handler) {\n            eventName = normalizeEventName(eventName);\n            if (!s.emitterEventListeners[eventName]) s.emitterEventListeners[eventName] = [];\n            s.emitterEventListeners[eventName].push(handler);\n            return s;\n        };\n        s.off = function (eventName, handler) {\n            var i;\n            eventName = normalizeEventName(eventName);\n            if (typeof handler === 'undefined') {\n                // Remove all handlers for such event\n                s.emitterEventListeners[eventName] = [];\n                return s;\n            }\n            if (!s.emitterEventListeners[eventName] || s.emitterEventListeners[eventName].length === 0) return;\n            for (i = 0; i < s.emitterEventListeners[eventName].length; i++) {\n                if(s.emitterEventListeners[eventName][i] === handler) s.emitterEventListeners[eventName].splice(i, 1);\n            }\n            return s;\n        };\n        s.once = function (eventName, handler) {\n            eventName = normalizeEventName(eventName);\n            var _handler = function () {\n                handler(arguments[0], arguments[1], arguments[2], arguments[3], arguments[4]);\n                s.off(eventName, _handler);\n            };\n            s.on(eventName, _handler);\n            return s;\n        };\n\n        // Accessibility tools\n        s.a11y = {\n            makeFocusable: function ($el) {\n                $el.attr('tabIndex', '0');\n                return $el;\n            },\n            addRole: function ($el, role) {\n                $el.attr('role', role);\n                return $el;\n            },\n        \n            addLabel: function ($el, label) {\n                $el.attr('aria-label', label);\n                return $el;\n            },\n        \n            disable: function ($el) {\n                $el.attr('aria-disabled', true);\n                return $el;\n            },\n        \n            enable: function ($el) {\n                $el.attr('aria-disabled', false);\n                return $el;\n            },\n        \n            onEnterKey: function (event) {\n                if (event.keyCode !== 13) return;\n                if ($(event.target).is(s.params.nextButton)) {\n                    s.onClickNext(event);\n                    if (s.isEnd) {\n                        s.a11y.notify(s.params.lastSlideMessage);\n                    }\n                    else {\n                        s.a11y.notify(s.params.nextSlideMessage);\n                    }\n                }\n                else if ($(event.target).is(s.params.prevButton)) {\n                    s.onClickPrev(event);\n                    if (s.isBeginning) {\n                        s.a11y.notify(s.params.firstSlideMessage);\n                    }\n                    else {\n                        s.a11y.notify(s.params.prevSlideMessage);\n                    }\n                }\n                if ($(event.target).is('.' + s.params.bulletClass)) {\n                    $(event.target)[0].click();\n                }\n            },\n        \n            liveRegion: $('<span class=\"swiper-notification\" aria-live=\"assertive\" aria-atomic=\"true\"></span>'),\n        \n            notify: function (message) {\n                var notification = s.a11y.liveRegion;\n                if (notification.length === 0) return;\n                notification.html('');\n                notification.html(message);\n            },\n            init: function () {\n                // Setup accessibility\n                if (s.params.nextButton && s.nextButton && s.nextButton.length > 0) {\n                    s.a11y.makeFocusable(s.nextButton);\n                    s.a11y.addRole(s.nextButton, 'button');\n                    s.a11y.addLabel(s.nextButton, s.params.nextSlideMessage);\n                }\n                if (s.params.prevButton && s.prevButton && s.prevButton.length > 0) {\n                    s.a11y.makeFocusable(s.prevButton);\n                    s.a11y.addRole(s.prevButton, 'button');\n                    s.a11y.addLabel(s.prevButton, s.params.prevSlideMessage);\n                }\n        \n                $(s.container).append(s.a11y.liveRegion);\n            },\n            initPagination: function () {\n                if (s.params.pagination && s.params.paginationClickable && s.bullets && s.bullets.length) {\n                    s.bullets.each(function () {\n                        var bullet = $(this);\n                        s.a11y.makeFocusable(bullet);\n                        s.a11y.addRole(bullet, 'button');\n                        s.a11y.addLabel(bullet, s.params.paginationBulletMessage.replace(/{{index}}/, bullet.index() + 1));\n                    });\n                }\n            },\n            destroy: function () {\n                if (s.a11y.liveRegion && s.a11y.liveRegion.length > 0) s.a11y.liveRegion.remove();\n            }\n        };\n        \n\n        /*=========================\n          Init/Destroy\n          ===========================*/\n        s.init = function () {\n            if (s.params.loop) s.createLoop();\n            s.updateContainerSize();\n            s.updateSlidesSize();\n            s.updatePagination();\n            if (s.params.scrollbar && s.scrollbar) {\n                s.scrollbar.set();\n                if (s.params.scrollbarDraggable) {\n                    s.scrollbar.enableDraggable();\n                }\n            }\n            if (s.params.effect !== 'slide' && s.effects[s.params.effect]) {\n                if (!s.params.loop) s.updateProgress();\n                s.effects[s.params.effect].setTranslate();\n            }\n            if (s.params.loop) {\n                s.slideTo(s.params.initialSlide + s.loopedSlides, 0, s.params.runCallbacksOnInit);\n            }\n            else {\n                s.slideTo(s.params.initialSlide, 0, s.params.runCallbacksOnInit);\n                if (s.params.initialSlide === 0) {\n                    if (s.parallax && s.params.parallax) s.parallax.setTranslate();\n                    if (s.lazy && s.params.lazyLoading) {\n                        s.lazy.load();\n                        s.lazy.initialImageLoaded = true;\n                    }\n                }\n            }\n            s.attachEvents();\n            if (s.params.observer && s.support.observer) {\n                s.initObservers();\n            }\n            if (s.params.preloadImages && !s.params.lazyLoading) {\n                s.preloadImages();\n            }\n            if (s.params.autoplay) {\n                s.startAutoplay();\n            }\n            if (s.params.keyboardControl) {\n                if (s.enableKeyboardControl) s.enableKeyboardControl();\n            }\n            if (s.params.mousewheelControl) {\n                if (s.enableMousewheelControl) s.enableMousewheelControl();\n            }\n            if (s.params.hashnav) {\n                if (s.hashnav) s.hashnav.init();\n            }\n            if (s.params.a11y && s.a11y) s.a11y.init();\n            s.emit('onInit', s);\n        };\n        \n        // Cleanup dynamic styles\n        s.cleanupStyles = function () {\n            // Container\n            s.container.removeClass(s.classNames.join(' ')).removeAttr('style');\n        \n            // Wrapper\n            s.wrapper.removeAttr('style');\n        \n            // Slides\n            if (s.slides && s.slides.length) {\n                s.slides\n                    .removeClass([\n                      s.params.slideVisibleClass,\n                      s.params.slideActiveClass,\n                      s.params.slideNextClass,\n                      s.params.slidePrevClass\n                    ].join(' '))\n                    .removeAttr('style')\n                    .removeAttr('data-swiper-column')\n                    .removeAttr('data-swiper-row');\n            }\n        \n            // Pagination/Bullets\n            if (s.paginationContainer && s.paginationContainer.length) {\n                s.paginationContainer.removeClass(s.params.paginationHiddenClass);\n            }\n            if (s.bullets && s.bullets.length) {\n                s.bullets.removeClass(s.params.bulletActiveClass);\n            }\n        \n            // Buttons\n            if (s.params.prevButton) $(s.params.prevButton).removeClass(s.params.buttonDisabledClass);\n            if (s.params.nextButton) $(s.params.nextButton).removeClass(s.params.buttonDisabledClass);\n        \n            // Scrollbar\n            if (s.params.scrollbar && s.scrollbar) {\n                if (s.scrollbar.track && s.scrollbar.track.length) s.scrollbar.track.removeAttr('style');\n                if (s.scrollbar.drag && s.scrollbar.drag.length) s.scrollbar.drag.removeAttr('style');\n            }\n        };\n        \n        // Destroy\n        s.destroy = function (deleteInstance, cleanupStyles) {\n            // Detach evebts\n            s.detachEvents();\n            // Stop autoplay\n            s.stopAutoplay();\n            // Disable draggable\n            if (s.params.scrollbar && s.scrollbar) {\n                if (s.params.scrollbarDraggable) {\n                    s.scrollbar.disableDraggable();\n                }\n            }\n            // Destroy loop\n            if (s.params.loop) {\n                s.destroyLoop();\n            }\n            // Cleanup styles\n            if (cleanupStyles) {\n                s.cleanupStyles();\n            }\n            // Disconnect observer\n            s.disconnectObservers();\n            // Disable keyboard/mousewheel\n            if (s.params.keyboardControl) {\n                if (s.disableKeyboardControl) s.disableKeyboardControl();\n            }\n            if (s.params.mousewheelControl) {\n                if (s.disableMousewheelControl) s.disableMousewheelControl();\n            }\n            // Disable a11y\n            if (s.params.a11y && s.a11y) s.a11y.destroy();\n            // Destroy callback\n            s.emit('onDestroy');\n            // Delete instance\n            if (deleteInstance !== false) s = null;\n        };\n        \n        s.init();\n        \n\n    \n        // Return swiper instance\n        return s;\n    };\n    \n\n    /*==================================================\n        Prototype\n    ====================================================*/\n    Swiper.prototype = {\n        isSafari: (function () {\n            var ua = navigator.userAgent.toLowerCase();\n            return (ua.indexOf('safari') >= 0 && ua.indexOf('chrome') < 0 && ua.indexOf('android') < 0);\n        })(),\n        isUiWebView: /(iPhone|iPod|iPad).*AppleWebKit(?!.*Safari)/i.test(navigator.userAgent),\n        isArray: function (arr) {\n            return Object.prototype.toString.apply(arr) === '[object Array]';\n        },\n        /*==================================================\n        Browser\n        ====================================================*/\n        browser: {\n            ie: window.navigator.pointerEnabled || window.navigator.msPointerEnabled,\n            ieTouch: (window.navigator.msPointerEnabled && window.navigator.msMaxTouchPoints > 1) || (window.navigator.pointerEnabled && window.navigator.maxTouchPoints > 1)\n        },\n        /*==================================================\n        Devices\n        ====================================================*/\n        device: (function () {\n            var ua = navigator.userAgent;\n            var android = ua.match(/(Android);?[\\s\\/]+([\\d.]+)?/);\n            var ipad = ua.match(/(iPad).*OS\\s([\\d_]+)/);\n            var ipod = ua.match(/(iPod)(.*OS\\s([\\d_]+))?/);\n            var iphone = !ipad && ua.match(/(iPhone\\sOS)\\s([\\d_]+)/);\n            return {\n                ios: ipad || iphone || ipod,\n                android: android\n            };\n        })(),\n        /*==================================================\n        Feature Detection\n        ====================================================*/\n        support: {\n            touch : (window.Modernizr && Modernizr.touch === true) || (function () {\n                return !!(('ontouchstart' in window) || window.DocumentTouch && document instanceof DocumentTouch);\n            })(),\n    \n            transforms3d : (window.Modernizr && Modernizr.csstransforms3d === true) || (function () {\n                var div = document.createElement('div').style;\n                return ('webkitPerspective' in div || 'MozPerspective' in div || 'OPerspective' in div || 'MsPerspective' in div || 'perspective' in div);\n            })(),\n    \n            flexbox: (function () {\n                var div = document.createElement('div').style;\n                var styles = ('alignItems webkitAlignItems webkitBoxAlign msFlexAlign mozBoxAlign webkitFlexDirection msFlexDirection mozBoxDirection mozBoxOrient webkitBoxDirection webkitBoxOrient').split(' ');\n                for (var i = 0; i < styles.length; i++) {\n                    if (styles[i] in div) return true;\n                }\n            })(),\n    \n            observer: (function () {\n                return ('MutationObserver' in window || 'WebkitMutationObserver' in window);\n            })()\n        },\n        /*==================================================\n        Plugins\n        ====================================================*/\n        plugins: {}\n    };\n    \n\n    /*===========================\n     Get Dom libraries\n     ===========================*/\n    var swiperDomPlugins = ['jQuery', 'Zepto', 'Dom7'];\n    for (var i = 0; i < swiperDomPlugins.length; i++) {\n    \tif (window[swiperDomPlugins[i]]) {\n    \t\taddLibraryPlugin(window[swiperDomPlugins[i]]);\n    \t}\n    }\n    // Required DOM Plugins\n    var domLib;\n    if (typeof Dom7 === 'undefined') {\n    \tdomLib = window.Dom7 || window.Zepto || window.jQuery;\n    }\n    else {\n    \tdomLib = Dom7;\n    }\n\n    /*===========================\n    Add .swiper plugin from Dom libraries\n    ===========================*/\n    function addLibraryPlugin(lib) {\n        lib.fn.swiper = function (params) {\n            var firstInstance;\n            lib(this).each(function () {\n                var s = new Swiper(this, params);\n                if (!firstInstance) firstInstance = s;\n            });\n            return firstInstance;\n        };\n    }\n    \n    if (domLib) {\n        if (!('transitionEnd' in domLib.fn)) {\n            domLib.fn.transitionEnd = function (callback) {\n                var events = ['webkitTransitionEnd', 'transitionend', 'oTransitionEnd', 'MSTransitionEnd', 'msTransitionEnd'],\n                    i, j, dom = this;\n                function fireCallBack(e) {\n                    /*jshint validthis:true */\n                    if (e.target !== this) return;\n                    callback.call(this, e);\n                    for (i = 0; i < events.length; i++) {\n                        dom.off(events[i], fireCallBack);\n                    }\n                }\n                if (callback) {\n                    for (i = 0; i < events.length; i++) {\n                        dom.on(events[i], fireCallBack);\n                    }\n                }\n                return this;\n            };\n        }\n        if (!('transform' in domLib.fn)) {\n            domLib.fn.transform = function (transform) {\n                for (var i = 0; i < this.length; i++) {\n                    var elStyle = this[i].style;\n                    elStyle.webkitTransform = elStyle.MsTransform = elStyle.msTransform = elStyle.MozTransform = elStyle.OTransform = elStyle.transform = transform;\n                }\n                return this;\n            };\n        }\n        if (!('transition' in domLib.fn)) {\n            domLib.fn.transition = function (duration) {\n                if (typeof duration !== 'string') {\n                    duration = duration + 'ms';\n                }\n                for (var i = 0; i < this.length; i++) {\n                    var elStyle = this[i].style;\n                    elStyle.webkitTransitionDuration = elStyle.MsTransitionDuration = elStyle.msTransitionDuration = elStyle.MozTransitionDuration = elStyle.OTransitionDuration = elStyle.transitionDuration = duration;\n                }\n                return this;\n            };\n        }\n    }\n\n    window.Swiper = Swiper;\n})();\n/*===========================\nSwiper AMD Export\n===========================*/\nif (typeof(module) !== 'undefined')\n{\n    module.exports = window.Swiper;\n}\nelse if (typeof define === 'function' && define.amd) {\n    define([], function () {\n        'use strict';\n        return window.Swiper;\n    });\n}\n//# sourceMappingURL=maps/swiper.jquery.js.map\n"
  },
  {
    "path": "app_frontend/static/plugin/Swiper-3.3.1/dist/js/swiper.jquery.umd.js",
    "content": "/**\n * Swiper 3.3.1\n * Most modern mobile touch slider and framework with hardware accelerated transitions\n * \n * http://www.idangero.us/swiper/\n * \n * Copyright 2016, Vladimir Kharlampidi\n * The iDangero.us\n * http://www.idangero.us/\n * \n * Licensed under MIT\n * \n * Released on: February 7, 2016\n */\n(function (root, factory) {\n\t'use strict';\n\n\tif (typeof define === 'function' && define.amd) {\n\t\t// AMD. Register as an anonymous module.\n\t\tdefine(['jquery'], factory);\n\t} else if (typeof exports === 'object') {\n\t\t// Node. Does not work with strict CommonJS, but\n\t\t// only CommonJS-like environments that support module.exports,\n\t\t// like Node.\n\t\tmodule.exports = factory(require('jquery'));\n\t} else {\n\t\t// Browser globals (root is window)\n\t\troot.Swiper = factory(root.jQuery);\n\t}\n}(this, function ($) {\n\t'use strict';\n\n    /*===========================\n    Swiper\n    ===========================*/\n    var Swiper = function (container, params) {\n        if (!(this instanceof Swiper)) return new Swiper(container, params);\n\n        var defaults = {\n            direction: 'horizontal',\n            touchEventsTarget: 'container',\n            initialSlide: 0,\n            speed: 300,\n            // autoplay\n            autoplay: false,\n            autoplayDisableOnInteraction: true,\n            autoplayStopOnLast: false,\n            // To support iOS's swipe-to-go-back gesture (when being used in-app, with UIWebView).\n            iOSEdgeSwipeDetection: false,\n            iOSEdgeSwipeThreshold: 20,\n            // Free mode\n            freeMode: false,\n            freeModeMomentum: true,\n            freeModeMomentumRatio: 1,\n            freeModeMomentumBounce: true,\n            freeModeMomentumBounceRatio: 1,\n            freeModeSticky: false,\n            freeModeMinimumVelocity: 0.02,\n            // Autoheight\n            autoHeight: false,\n            // Set wrapper width\n            setWrapperSize: false,\n            // Virtual Translate\n            virtualTranslate: false,\n            // Effects\n            effect: 'slide', // 'slide' or 'fade' or 'cube' or 'coverflow' or 'flip'\n            coverflow: {\n                rotate: 50,\n                stretch: 0,\n                depth: 100,\n                modifier: 1,\n                slideShadows : true\n            },\n            flip: {\n                slideShadows : true,\n                limitRotation: true\n            },\n            cube: {\n                slideShadows: true,\n                shadow: true,\n                shadowOffset: 20,\n                shadowScale: 0.94\n            },\n            fade: {\n                crossFade: false\n            },\n            // Parallax\n            parallax: false,\n            // Scrollbar\n            scrollbar: null,\n            scrollbarHide: true,\n            scrollbarDraggable: false,\n            scrollbarSnapOnRelease: false,\n            // Keyboard Mousewheel\n            keyboardControl: false,\n            mousewheelControl: false,\n            mousewheelReleaseOnEdges: false,\n            mousewheelInvert: false,\n            mousewheelForceToAxis: false,\n            mousewheelSensitivity: 1,\n            // Hash Navigation\n            hashnav: false,\n            // Breakpoints\n            breakpoints: undefined,\n            // Slides grid\n            spaceBetween: 0,\n            slidesPerView: 1,\n            slidesPerColumn: 1,\n            slidesPerColumnFill: 'column',\n            slidesPerGroup: 1,\n            centeredSlides: false,\n            slidesOffsetBefore: 0, // in px\n            slidesOffsetAfter: 0, // in px\n            // Round length\n            roundLengths: false,\n            // Touches\n            touchRatio: 1,\n            touchAngle: 45,\n            simulateTouch: true,\n            shortSwipes: true,\n            longSwipes: true,\n            longSwipesRatio: 0.5,\n            longSwipesMs: 300,\n            followFinger: true,\n            onlyExternal: false,\n            threshold: 0,\n            touchMoveStopPropagation: true,\n            // Unique Navigation Elements\n            uniqueNavElements: true,\n            // Pagination\n            pagination: null,\n            paginationElement: 'span',\n            paginationClickable: false,\n            paginationHide: false,\n            paginationBulletRender: null,\n            paginationProgressRender: null,\n            paginationFractionRender: null,\n            paginationCustomRender: null,\n            paginationType: 'bullets', // 'bullets' or 'progress' or 'fraction' or 'custom'\n            // Resistance\n            resistance: true,\n            resistanceRatio: 0.85,\n            // Next/prev buttons\n            nextButton: null,\n            prevButton: null,\n            // Progress\n            watchSlidesProgress: false,\n            watchSlidesVisibility: false,\n            // Cursor\n            grabCursor: false,\n            // Clicks\n            preventClicks: true,\n            preventClicksPropagation: true,\n            slideToClickedSlide: false,\n            // Lazy Loading\n            lazyLoading: false,\n            lazyLoadingInPrevNext: false,\n            lazyLoadingInPrevNextAmount: 1,\n            lazyLoadingOnTransitionStart: false,\n            // Images\n            preloadImages: true,\n            updateOnImagesReady: true,\n            // loop\n            loop: false,\n            loopAdditionalSlides: 0,\n            loopedSlides: null,\n            // Control\n            control: undefined,\n            controlInverse: false,\n            controlBy: 'slide', //or 'container'\n            // Swiping/no swiping\n            allowSwipeToPrev: true,\n            allowSwipeToNext: true,\n            swipeHandler: null, //'.swipe-handler',\n            noSwiping: true,\n            noSwipingClass: 'swiper-no-swiping',\n            // NS\n            slideClass: 'swiper-slide',\n            slideActiveClass: 'swiper-slide-active',\n            slideVisibleClass: 'swiper-slide-visible',\n            slideDuplicateClass: 'swiper-slide-duplicate',\n            slideNextClass: 'swiper-slide-next',\n            slidePrevClass: 'swiper-slide-prev',\n            wrapperClass: 'swiper-wrapper',\n            bulletClass: 'swiper-pagination-bullet',\n            bulletActiveClass: 'swiper-pagination-bullet-active',\n            buttonDisabledClass: 'swiper-button-disabled',\n            paginationCurrentClass: 'swiper-pagination-current',\n            paginationTotalClass: 'swiper-pagination-total',\n            paginationHiddenClass: 'swiper-pagination-hidden',\n            paginationProgressbarClass: 'swiper-pagination-progressbar',\n            // Observer\n            observer: false,\n            observeParents: false,\n            // Accessibility\n            a11y: false,\n            prevSlideMessage: 'Previous slide',\n            nextSlideMessage: 'Next slide',\n            firstSlideMessage: 'This is the first slide',\n            lastSlideMessage: 'This is the last slide',\n            paginationBulletMessage: 'Go to slide {{index}}',\n            // Callbacks\n            runCallbacksOnInit: true\n            /*\n            Callbacks:\n            onInit: function (swiper)\n            onDestroy: function (swiper)\n            onClick: function (swiper, e)\n            onTap: function (swiper, e)\n            onDoubleTap: function (swiper, e)\n            onSliderMove: function (swiper, e)\n            onSlideChangeStart: function (swiper)\n            onSlideChangeEnd: function (swiper)\n            onTransitionStart: function (swiper)\n            onTransitionEnd: function (swiper)\n            onImagesReady: function (swiper)\n            onProgress: function (swiper, progress)\n            onTouchStart: function (swiper, e)\n            onTouchMove: function (swiper, e)\n            onTouchMoveOpposite: function (swiper, e)\n            onTouchEnd: function (swiper, e)\n            onReachBeginning: function (swiper)\n            onReachEnd: function (swiper)\n            onSetTransition: function (swiper, duration)\n            onSetTranslate: function (swiper, translate)\n            onAutoplayStart: function (swiper)\n            onAutoplayStop: function (swiper),\n            onLazyImageLoad: function (swiper, slide, image)\n            onLazyImageReady: function (swiper, slide, image)\n            */\n        \n        };\n        var initialVirtualTranslate = params && params.virtualTranslate;\n        \n        params = params || {};\n        var originalParams = {};\n        for (var param in params) {\n            if (typeof params[param] === 'object' && params[param] !== null && !(params[param].nodeType || params[param] === window || params[param] === document || (typeof Dom7 !== 'undefined' && params[param] instanceof Dom7) || (typeof jQuery !== 'undefined' && params[param] instanceof jQuery))) {\n                originalParams[param] = {};\n                for (var deepParam in params[param]) {\n                    originalParams[param][deepParam] = params[param][deepParam];\n                }\n            }\n            else {\n                originalParams[param] = params[param];\n            }\n        }\n        for (var def in defaults) {\n            if (typeof params[def] === 'undefined') {\n                params[def] = defaults[def];\n            }\n            else if (typeof params[def] === 'object') {\n                for (var deepDef in defaults[def]) {\n                    if (typeof params[def][deepDef] === 'undefined') {\n                        params[def][deepDef] = defaults[def][deepDef];\n                    }\n                }\n            }\n        }\n        \n        // Swiper\n        var s = this;\n        \n        // Params\n        s.params = params;\n        s.originalParams = originalParams;\n        \n        // Classname\n        s.classNames = [];\n        /*=========================\n          Dom Library and plugins\n          ===========================*/\n        if (typeof $ !== 'undefined' && typeof Dom7 !== 'undefined'){\n            $ = Dom7;\n        }\n        if (typeof $ === 'undefined') {\n            if (typeof Dom7 === 'undefined') {\n                $ = window.Dom7 || window.Zepto || window.jQuery;\n            }\n            else {\n                $ = Dom7;\n            }\n            if (!$) return;\n        }\n        // Export it to Swiper instance\n        s.$ = $;\n        \n        /*=========================\n          Breakpoints\n          ===========================*/\n        s.currentBreakpoint = undefined;\n        s.getActiveBreakpoint = function () {\n            //Get breakpoint for window width\n            if (!s.params.breakpoints) return false;\n            var breakpoint = false;\n            var points = [], point;\n            for ( point in s.params.breakpoints ) {\n                if (s.params.breakpoints.hasOwnProperty(point)) {\n                    points.push(point);\n                }\n            }\n            points.sort(function (a, b) {\n                return parseInt(a, 10) > parseInt(b, 10);\n            });\n            for (var i = 0; i < points.length; i++) {\n                point = points[i];\n                if (point >= window.innerWidth && !breakpoint) {\n                    breakpoint = point;\n                }\n            }\n            return breakpoint || 'max';\n        };\n        s.setBreakpoint = function () {\n            //Set breakpoint for window width and update parameters\n            var breakpoint = s.getActiveBreakpoint();\n            if (breakpoint && s.currentBreakpoint !== breakpoint) {\n                var breakPointsParams = breakpoint in s.params.breakpoints ? s.params.breakpoints[breakpoint] : s.originalParams;\n                var needsReLoop = s.params.loop && (breakPointsParams.slidesPerView !== s.params.slidesPerView);\n                for ( var param in breakPointsParams ) {\n                    s.params[param] = breakPointsParams[param];\n                }\n                s.currentBreakpoint = breakpoint;\n                if(needsReLoop && s.destroyLoop) {\n                    s.reLoop(true);\n                }\n            }\n        };\n        // Set breakpoint on load\n        if (s.params.breakpoints) {\n            s.setBreakpoint();\n        }\n        \n        /*=========================\n          Preparation - Define Container, Wrapper and Pagination\n          ===========================*/\n        s.container = $(container);\n        if (s.container.length === 0) return;\n        if (s.container.length > 1) {\n            var swipers = [];\n            s.container.each(function () {\n                var container = this;\n                swipers.push(new Swiper(this, params));\n            });\n            return swipers;\n        }\n        \n        // Save instance in container HTML Element and in data\n        s.container[0].swiper = s;\n        s.container.data('swiper', s);\n        \n        s.classNames.push('swiper-container-' + s.params.direction);\n        \n        if (s.params.freeMode) {\n            s.classNames.push('swiper-container-free-mode');\n        }\n        if (!s.support.flexbox) {\n            s.classNames.push('swiper-container-no-flexbox');\n            s.params.slidesPerColumn = 1;\n        }\n        if (s.params.autoHeight) {\n            s.classNames.push('swiper-container-autoheight');\n        }\n        // Enable slides progress when required\n        if (s.params.parallax || s.params.watchSlidesVisibility) {\n            s.params.watchSlidesProgress = true;\n        }\n        // Coverflow / 3D\n        if (['cube', 'coverflow', 'flip'].indexOf(s.params.effect) >= 0) {\n            if (s.support.transforms3d) {\n                s.params.watchSlidesProgress = true;\n                s.classNames.push('swiper-container-3d');\n            }\n            else {\n                s.params.effect = 'slide';\n            }\n        }\n        if (s.params.effect !== 'slide') {\n            s.classNames.push('swiper-container-' + s.params.effect);\n        }\n        if (s.params.effect === 'cube') {\n            s.params.resistanceRatio = 0;\n            s.params.slidesPerView = 1;\n            s.params.slidesPerColumn = 1;\n            s.params.slidesPerGroup = 1;\n            s.params.centeredSlides = false;\n            s.params.spaceBetween = 0;\n            s.params.virtualTranslate = true;\n            s.params.setWrapperSize = false;\n        }\n        if (s.params.effect === 'fade' || s.params.effect === 'flip') {\n            s.params.slidesPerView = 1;\n            s.params.slidesPerColumn = 1;\n            s.params.slidesPerGroup = 1;\n            s.params.watchSlidesProgress = true;\n            s.params.spaceBetween = 0;\n            s.params.setWrapperSize = false;\n            if (typeof initialVirtualTranslate === 'undefined') {\n                s.params.virtualTranslate = true;\n            }\n        }\n        \n        // Grab Cursor\n        if (s.params.grabCursor && s.support.touch) {\n            s.params.grabCursor = false;\n        }\n        \n        // Wrapper\n        s.wrapper = s.container.children('.' + s.params.wrapperClass);\n        \n        // Pagination\n        if (s.params.pagination) {\n            s.paginationContainer = $(s.params.pagination);\n            if (s.params.uniqueNavElements && typeof s.params.pagination === 'string' && s.paginationContainer.length > 1 && s.container.find(s.params.pagination).length === 1) {\n                s.paginationContainer = s.container.find(s.params.pagination);\n            }\n        \n            if (s.params.paginationType === 'bullets' && s.params.paginationClickable) {\n                s.paginationContainer.addClass('swiper-pagination-clickable');\n            }\n            else {\n                s.params.paginationClickable = false;\n            }\n            s.paginationContainer.addClass('swiper-pagination-' + s.params.paginationType);\n        }\n        // Next/Prev Buttons\n        if (s.params.nextButton || s.params.prevButton) {\n            if (s.params.nextButton) {\n                s.nextButton = $(s.params.nextButton);\n                if (s.params.uniqueNavElements && typeof s.params.nextButton === 'string' && s.nextButton.length > 1 && s.container.find(s.params.nextButton).length === 1) {\n                    s.nextButton = s.container.find(s.params.nextButton);\n                }\n            }\n            if (s.params.prevButton) {\n                s.prevButton = $(s.params.prevButton);\n                if (s.params.uniqueNavElements && typeof s.params.prevButton === 'string' && s.prevButton.length > 1 && s.container.find(s.params.prevButton).length === 1) {\n                    s.prevButton = s.container.find(s.params.prevButton);\n                }\n            }\n        }\n        \n        // Is Horizontal\n        s.isHorizontal = function () {\n            return s.params.direction === 'horizontal';\n        };\n        // s.isH = isH;\n        \n        // RTL\n        s.rtl = s.isHorizontal() && (s.container[0].dir.toLowerCase() === 'rtl' || s.container.css('direction') === 'rtl');\n        if (s.rtl) {\n            s.classNames.push('swiper-container-rtl');\n        }\n        \n        // Wrong RTL support\n        if (s.rtl) {\n            s.wrongRTL = s.wrapper.css('display') === '-webkit-box';\n        }\n        \n        // Columns\n        if (s.params.slidesPerColumn > 1) {\n            s.classNames.push('swiper-container-multirow');\n        }\n        \n        // Check for Android\n        if (s.device.android) {\n            s.classNames.push('swiper-container-android');\n        }\n        \n        // Add classes\n        s.container.addClass(s.classNames.join(' '));\n        \n        // Translate\n        s.translate = 0;\n        \n        // Progress\n        s.progress = 0;\n        \n        // Velocity\n        s.velocity = 0;\n        \n        /*=========================\n          Locks, unlocks\n          ===========================*/\n        s.lockSwipeToNext = function () {\n            s.params.allowSwipeToNext = false;\n        };\n        s.lockSwipeToPrev = function () {\n            s.params.allowSwipeToPrev = false;\n        };\n        s.lockSwipes = function () {\n            s.params.allowSwipeToNext = s.params.allowSwipeToPrev = false;\n        };\n        s.unlockSwipeToNext = function () {\n            s.params.allowSwipeToNext = true;\n        };\n        s.unlockSwipeToPrev = function () {\n            s.params.allowSwipeToPrev = true;\n        };\n        s.unlockSwipes = function () {\n            s.params.allowSwipeToNext = s.params.allowSwipeToPrev = true;\n        };\n        \n        /*=========================\n          Round helper\n          ===========================*/\n        function round(a) {\n            return Math.floor(a);\n        }\n        /*=========================\n          Set grab cursor\n          ===========================*/\n        if (s.params.grabCursor) {\n            s.container[0].style.cursor = 'move';\n            s.container[0].style.cursor = '-webkit-grab';\n            s.container[0].style.cursor = '-moz-grab';\n            s.container[0].style.cursor = 'grab';\n        }\n        /*=========================\n          Update on Images Ready\n          ===========================*/\n        s.imagesToLoad = [];\n        s.imagesLoaded = 0;\n        \n        s.loadImage = function (imgElement, src, srcset, checkForComplete, callback) {\n            var image;\n            function onReady () {\n                if (callback) callback();\n            }\n            if (!imgElement.complete || !checkForComplete) {\n                if (src) {\n                    image = new window.Image();\n                    image.onload = onReady;\n                    image.onerror = onReady;\n                    if (srcset) {\n                        image.srcset = srcset;\n                    }\n                    if (src) {\n                        image.src = src;\n                    }\n                } else {\n                    onReady();\n                }\n        \n            } else {//image already loaded...\n                onReady();\n            }\n        };\n        s.preloadImages = function () {\n            s.imagesToLoad = s.container.find('img');\n            function _onReady() {\n                if (typeof s === 'undefined' || s === null) return;\n                if (s.imagesLoaded !== undefined) s.imagesLoaded++;\n                if (s.imagesLoaded === s.imagesToLoad.length) {\n                    if (s.params.updateOnImagesReady) s.update();\n                    s.emit('onImagesReady', s);\n                }\n            }\n            for (var i = 0; i < s.imagesToLoad.length; i++) {\n                s.loadImage(s.imagesToLoad[i], (s.imagesToLoad[i].currentSrc || s.imagesToLoad[i].getAttribute('src')), (s.imagesToLoad[i].srcset || s.imagesToLoad[i].getAttribute('srcset')), true, _onReady);\n            }\n        };\n        \n        /*=========================\n          Autoplay\n          ===========================*/\n        s.autoplayTimeoutId = undefined;\n        s.autoplaying = false;\n        s.autoplayPaused = false;\n        function autoplay() {\n            s.autoplayTimeoutId = setTimeout(function () {\n                if (s.params.loop) {\n                    s.fixLoop();\n                    s._slideNext();\n                    s.emit('onAutoplay', s);\n                }\n                else {\n                    if (!s.isEnd) {\n                        s._slideNext();\n                        s.emit('onAutoplay', s);\n                    }\n                    else {\n                        if (!params.autoplayStopOnLast) {\n                            s._slideTo(0);\n                            s.emit('onAutoplay', s);\n                        }\n                        else {\n                            s.stopAutoplay();\n                        }\n                    }\n                }\n            }, s.params.autoplay);\n        }\n        s.startAutoplay = function () {\n            if (typeof s.autoplayTimeoutId !== 'undefined') return false;\n            if (!s.params.autoplay) return false;\n            if (s.autoplaying) return false;\n            s.autoplaying = true;\n            s.emit('onAutoplayStart', s);\n            autoplay();\n        };\n        s.stopAutoplay = function (internal) {\n            if (!s.autoplayTimeoutId) return;\n            if (s.autoplayTimeoutId) clearTimeout(s.autoplayTimeoutId);\n            s.autoplaying = false;\n            s.autoplayTimeoutId = undefined;\n            s.emit('onAutoplayStop', s);\n        };\n        s.pauseAutoplay = function (speed) {\n            if (s.autoplayPaused) return;\n            if (s.autoplayTimeoutId) clearTimeout(s.autoplayTimeoutId);\n            s.autoplayPaused = true;\n            if (speed === 0) {\n                s.autoplayPaused = false;\n                autoplay();\n            }\n            else {\n                s.wrapper.transitionEnd(function () {\n                    if (!s) return;\n                    s.autoplayPaused = false;\n                    if (!s.autoplaying) {\n                        s.stopAutoplay();\n                    }\n                    else {\n                        autoplay();\n                    }\n                });\n            }\n        };\n        /*=========================\n          Min/Max Translate\n          ===========================*/\n        s.minTranslate = function () {\n            return (-s.snapGrid[0]);\n        };\n        s.maxTranslate = function () {\n            return (-s.snapGrid[s.snapGrid.length - 1]);\n        };\n        /*=========================\n          Slider/slides sizes\n          ===========================*/\n        s.updateAutoHeight = function () {\n            // Update Height\n            var slide = s.slides.eq(s.activeIndex)[0];\n            if (typeof slide !== 'undefined') {\n                var newHeight = slide.offsetHeight;\n                if (newHeight) s.wrapper.css('height', newHeight + 'px');\n            }\n        };\n        s.updateContainerSize = function () {\n            var width, height;\n            if (typeof s.params.width !== 'undefined') {\n                width = s.params.width;\n            }\n            else {\n                width = s.container[0].clientWidth;\n            }\n            if (typeof s.params.height !== 'undefined') {\n                height = s.params.height;\n            }\n            else {\n                height = s.container[0].clientHeight;\n            }\n            if (width === 0 && s.isHorizontal() || height === 0 && !s.isHorizontal()) {\n                return;\n            }\n        \n            //Subtract paddings\n            width = width - parseInt(s.container.css('padding-left'), 10) - parseInt(s.container.css('padding-right'), 10);\n            height = height - parseInt(s.container.css('padding-top'), 10) - parseInt(s.container.css('padding-bottom'), 10);\n        \n            // Store values\n            s.width = width;\n            s.height = height;\n            s.size = s.isHorizontal() ? s.width : s.height;\n        };\n        \n        s.updateSlidesSize = function () {\n            s.slides = s.wrapper.children('.' + s.params.slideClass);\n            s.snapGrid = [];\n            s.slidesGrid = [];\n            s.slidesSizesGrid = [];\n        \n            var spaceBetween = s.params.spaceBetween,\n                slidePosition = -s.params.slidesOffsetBefore,\n                i,\n                prevSlideSize = 0,\n                index = 0;\n            if (typeof s.size === 'undefined') return;\n            if (typeof spaceBetween === 'string' && spaceBetween.indexOf('%') >= 0) {\n                spaceBetween = parseFloat(spaceBetween.replace('%', '')) / 100 * s.size;\n            }\n        \n            s.virtualSize = -spaceBetween;\n            // reset margins\n            if (s.rtl) s.slides.css({marginLeft: '', marginTop: ''});\n            else s.slides.css({marginRight: '', marginBottom: ''});\n        \n            var slidesNumberEvenToRows;\n            if (s.params.slidesPerColumn > 1) {\n                if (Math.floor(s.slides.length / s.params.slidesPerColumn) === s.slides.length / s.params.slidesPerColumn) {\n                    slidesNumberEvenToRows = s.slides.length;\n                }\n                else {\n                    slidesNumberEvenToRows = Math.ceil(s.slides.length / s.params.slidesPerColumn) * s.params.slidesPerColumn;\n                }\n                if (s.params.slidesPerView !== 'auto' && s.params.slidesPerColumnFill === 'row') {\n                    slidesNumberEvenToRows = Math.max(slidesNumberEvenToRows, s.params.slidesPerView * s.params.slidesPerColumn);\n                }\n            }\n        \n            // Calc slides\n            var slideSize;\n            var slidesPerColumn = s.params.slidesPerColumn;\n            var slidesPerRow = slidesNumberEvenToRows / slidesPerColumn;\n            var numFullColumns = slidesPerRow - (s.params.slidesPerColumn * slidesPerRow - s.slides.length);\n            for (i = 0; i < s.slides.length; i++) {\n                slideSize = 0;\n                var slide = s.slides.eq(i);\n                if (s.params.slidesPerColumn > 1) {\n                    // Set slides order\n                    var newSlideOrderIndex;\n                    var column, row;\n                    if (s.params.slidesPerColumnFill === 'column') {\n                        column = Math.floor(i / slidesPerColumn);\n                        row = i - column * slidesPerColumn;\n                        if (column > numFullColumns || (column === numFullColumns && row === slidesPerColumn-1)) {\n                            if (++row >= slidesPerColumn) {\n                                row = 0;\n                                column++;\n                            }\n                        }\n                        newSlideOrderIndex = column + row * slidesNumberEvenToRows / slidesPerColumn;\n                        slide\n                            .css({\n                                '-webkit-box-ordinal-group': newSlideOrderIndex,\n                                '-moz-box-ordinal-group': newSlideOrderIndex,\n                                '-ms-flex-order': newSlideOrderIndex,\n                                '-webkit-order': newSlideOrderIndex,\n                                'order': newSlideOrderIndex\n                            });\n                    }\n                    else {\n                        row = Math.floor(i / slidesPerRow);\n                        column = i - row * slidesPerRow;\n                    }\n                    slide\n                        .css({\n                            'margin-top': (row !== 0 && s.params.spaceBetween) && (s.params.spaceBetween + 'px')\n                        })\n                        .attr('data-swiper-column', column)\n                        .attr('data-swiper-row', row);\n        \n                }\n                if (slide.css('display') === 'none') continue;\n                if (s.params.slidesPerView === 'auto') {\n                    slideSize = s.isHorizontal() ? slide.outerWidth(true) : slide.outerHeight(true);\n                    if (s.params.roundLengths) slideSize = round(slideSize);\n                }\n                else {\n                    slideSize = (s.size - (s.params.slidesPerView - 1) * spaceBetween) / s.params.slidesPerView;\n                    if (s.params.roundLengths) slideSize = round(slideSize);\n        \n                    if (s.isHorizontal()) {\n                        s.slides[i].style.width = slideSize + 'px';\n                    }\n                    else {\n                        s.slides[i].style.height = slideSize + 'px';\n                    }\n                }\n                s.slides[i].swiperSlideSize = slideSize;\n                s.slidesSizesGrid.push(slideSize);\n        \n        \n                if (s.params.centeredSlides) {\n                    slidePosition = slidePosition + slideSize / 2 + prevSlideSize / 2 + spaceBetween;\n                    if (i === 0) slidePosition = slidePosition - s.size / 2 - spaceBetween;\n                    if (Math.abs(slidePosition) < 1 / 1000) slidePosition = 0;\n                    if ((index) % s.params.slidesPerGroup === 0) s.snapGrid.push(slidePosition);\n                    s.slidesGrid.push(slidePosition);\n                }\n                else {\n                    if ((index) % s.params.slidesPerGroup === 0) s.snapGrid.push(slidePosition);\n                    s.slidesGrid.push(slidePosition);\n                    slidePosition = slidePosition + slideSize + spaceBetween;\n                }\n        \n                s.virtualSize += slideSize + spaceBetween;\n        \n                prevSlideSize = slideSize;\n        \n                index ++;\n            }\n            s.virtualSize = Math.max(s.virtualSize, s.size) + s.params.slidesOffsetAfter;\n            var newSlidesGrid;\n        \n            if (\n                s.rtl && s.wrongRTL && (s.params.effect === 'slide' || s.params.effect === 'coverflow')) {\n                s.wrapper.css({width: s.virtualSize + s.params.spaceBetween + 'px'});\n            }\n            if (!s.support.flexbox || s.params.setWrapperSize) {\n                if (s.isHorizontal()) s.wrapper.css({width: s.virtualSize + s.params.spaceBetween + 'px'});\n                else s.wrapper.css({height: s.virtualSize + s.params.spaceBetween + 'px'});\n            }\n        \n            if (s.params.slidesPerColumn > 1) {\n                s.virtualSize = (slideSize + s.params.spaceBetween) * slidesNumberEvenToRows;\n                s.virtualSize = Math.ceil(s.virtualSize / s.params.slidesPerColumn) - s.params.spaceBetween;\n                s.wrapper.css({width: s.virtualSize + s.params.spaceBetween + 'px'});\n                if (s.params.centeredSlides) {\n                    newSlidesGrid = [];\n                    for (i = 0; i < s.snapGrid.length; i++) {\n                        if (s.snapGrid[i] < s.virtualSize + s.snapGrid[0]) newSlidesGrid.push(s.snapGrid[i]);\n                    }\n                    s.snapGrid = newSlidesGrid;\n                }\n            }\n        \n            // Remove last grid elements depending on width\n            if (!s.params.centeredSlides) {\n                newSlidesGrid = [];\n                for (i = 0; i < s.snapGrid.length; i++) {\n                    if (s.snapGrid[i] <= s.virtualSize - s.size) {\n                        newSlidesGrid.push(s.snapGrid[i]);\n                    }\n                }\n                s.snapGrid = newSlidesGrid;\n                if (Math.floor(s.virtualSize - s.size) - Math.floor(s.snapGrid[s.snapGrid.length - 1]) > 1) {\n                    s.snapGrid.push(s.virtualSize - s.size);\n                }\n            }\n            if (s.snapGrid.length === 0) s.snapGrid = [0];\n        \n            if (s.params.spaceBetween !== 0) {\n                if (s.isHorizontal()) {\n                    if (s.rtl) s.slides.css({marginLeft: spaceBetween + 'px'});\n                    else s.slides.css({marginRight: spaceBetween + 'px'});\n                }\n                else s.slides.css({marginBottom: spaceBetween + 'px'});\n            }\n            if (s.params.watchSlidesProgress) {\n                s.updateSlidesOffset();\n            }\n        };\n        s.updateSlidesOffset = function () {\n            for (var i = 0; i < s.slides.length; i++) {\n                s.slides[i].swiperSlideOffset = s.isHorizontal() ? s.slides[i].offsetLeft : s.slides[i].offsetTop;\n            }\n        };\n        \n        /*=========================\n          Slider/slides progress\n          ===========================*/\n        s.updateSlidesProgress = function (translate) {\n            if (typeof translate === 'undefined') {\n                translate = s.translate || 0;\n            }\n            if (s.slides.length === 0) return;\n            if (typeof s.slides[0].swiperSlideOffset === 'undefined') s.updateSlidesOffset();\n        \n            var offsetCenter = -translate;\n            if (s.rtl) offsetCenter = translate;\n        \n            // Visible Slides\n            s.slides.removeClass(s.params.slideVisibleClass);\n            for (var i = 0; i < s.slides.length; i++) {\n                var slide = s.slides[i];\n                var slideProgress = (offsetCenter - slide.swiperSlideOffset) / (slide.swiperSlideSize + s.params.spaceBetween);\n                if (s.params.watchSlidesVisibility) {\n                    var slideBefore = -(offsetCenter - slide.swiperSlideOffset);\n                    var slideAfter = slideBefore + s.slidesSizesGrid[i];\n                    var isVisible =\n                        (slideBefore >= 0 && slideBefore < s.size) ||\n                        (slideAfter > 0 && slideAfter <= s.size) ||\n                        (slideBefore <= 0 && slideAfter >= s.size);\n                    if (isVisible) {\n                        s.slides.eq(i).addClass(s.params.slideVisibleClass);\n                    }\n                }\n                slide.progress = s.rtl ? -slideProgress : slideProgress;\n            }\n        };\n        s.updateProgress = function (translate) {\n            if (typeof translate === 'undefined') {\n                translate = s.translate || 0;\n            }\n            var translatesDiff = s.maxTranslate() - s.minTranslate();\n            var wasBeginning = s.isBeginning;\n            var wasEnd = s.isEnd;\n            if (translatesDiff === 0) {\n                s.progress = 0;\n                s.isBeginning = s.isEnd = true;\n            }\n            else {\n                s.progress = (translate - s.minTranslate()) / (translatesDiff);\n                s.isBeginning = s.progress <= 0;\n                s.isEnd = s.progress >= 1;\n            }\n            if (s.isBeginning && !wasBeginning) s.emit('onReachBeginning', s);\n            if (s.isEnd && !wasEnd) s.emit('onReachEnd', s);\n        \n            if (s.params.watchSlidesProgress) s.updateSlidesProgress(translate);\n            s.emit('onProgress', s, s.progress);\n        };\n        s.updateActiveIndex = function () {\n            var translate = s.rtl ? s.translate : -s.translate;\n            var newActiveIndex, i, snapIndex;\n            for (i = 0; i < s.slidesGrid.length; i ++) {\n                if (typeof s.slidesGrid[i + 1] !== 'undefined') {\n                    if (translate >= s.slidesGrid[i] && translate < s.slidesGrid[i + 1] - (s.slidesGrid[i + 1] - s.slidesGrid[i]) / 2) {\n                        newActiveIndex = i;\n                    }\n                    else if (translate >= s.slidesGrid[i] && translate < s.slidesGrid[i + 1]) {\n                        newActiveIndex = i + 1;\n                    }\n                }\n                else {\n                    if (translate >= s.slidesGrid[i]) {\n                        newActiveIndex = i;\n                    }\n                }\n            }\n            // Normalize slideIndex\n            if (newActiveIndex < 0 || typeof newActiveIndex === 'undefined') newActiveIndex = 0;\n            // for (i = 0; i < s.slidesGrid.length; i++) {\n                // if (- translate >= s.slidesGrid[i]) {\n                    // newActiveIndex = i;\n                // }\n            // }\n            snapIndex = Math.floor(newActiveIndex / s.params.slidesPerGroup);\n            if (snapIndex >= s.snapGrid.length) snapIndex = s.snapGrid.length - 1;\n        \n            if (newActiveIndex === s.activeIndex) {\n                return;\n            }\n            s.snapIndex = snapIndex;\n            s.previousIndex = s.activeIndex;\n            s.activeIndex = newActiveIndex;\n            s.updateClasses();\n        };\n        \n        /*=========================\n          Classes\n          ===========================*/\n        s.updateClasses = function () {\n            s.slides.removeClass(s.params.slideActiveClass + ' ' + s.params.slideNextClass + ' ' + s.params.slidePrevClass);\n            var activeSlide = s.slides.eq(s.activeIndex);\n            // Active classes\n            activeSlide.addClass(s.params.slideActiveClass);\n            // Next Slide\n            var nextSlide = activeSlide.next('.' + s.params.slideClass).addClass(s.params.slideNextClass);\n            if (s.params.loop && nextSlide.length === 0) {\n                s.slides.eq(0).addClass(s.params.slideNextClass);\n            }\n            // Prev Slide\n            var prevSlide = activeSlide.prev('.' + s.params.slideClass).addClass(s.params.slidePrevClass);\n            if (s.params.loop && prevSlide.length === 0) {\n                s.slides.eq(-1).addClass(s.params.slidePrevClass);\n            }\n        \n            // Pagination\n            if (s.paginationContainer && s.paginationContainer.length > 0) {\n                // Current/Total\n                var current,\n                    total = s.params.loop ? Math.ceil((s.slides.length - s.loopedSlides * 2) / s.params.slidesPerGroup) : s.snapGrid.length;\n                if (s.params.loop) {\n                    current = Math.ceil((s.activeIndex - s.loopedSlides)/s.params.slidesPerGroup);\n                    if (current > s.slides.length - 1 - s.loopedSlides * 2) {\n                        current = current - (s.slides.length - s.loopedSlides * 2);\n                    }\n                    if (current > total - 1) current = current - total;\n                    if (current < 0 && s.params.paginationType !== 'bullets') current = total + current;\n                }\n                else {\n                    if (typeof s.snapIndex !== 'undefined') {\n                        current = s.snapIndex;\n                    }\n                    else {\n                        current = s.activeIndex || 0;\n                    }\n                }\n                // Types\n                if (s.params.paginationType === 'bullets' && s.bullets && s.bullets.length > 0) {\n                    s.bullets.removeClass(s.params.bulletActiveClass);\n                    if (s.paginationContainer.length > 1) {\n                        s.bullets.each(function () {\n                            if ($(this).index() === current) $(this).addClass(s.params.bulletActiveClass);\n                        });\n                    }\n                    else {\n                        s.bullets.eq(current).addClass(s.params.bulletActiveClass);\n                    }\n                }\n                if (s.params.paginationType === 'fraction') {\n                    s.paginationContainer.find('.' + s.params.paginationCurrentClass).text(current + 1);\n                    s.paginationContainer.find('.' + s.params.paginationTotalClass).text(total);\n                }\n                if (s.params.paginationType === 'progress') {\n                    var scale = (current + 1) / total,\n                        scaleX = scale,\n                        scaleY = 1;\n                    if (!s.isHorizontal()) {\n                        scaleY = scale;\n                        scaleX = 1;\n                    }\n                    s.paginationContainer.find('.' + s.params.paginationProgressbarClass).transform('translate3d(0,0,0) scaleX(' + scaleX + ') scaleY(' + scaleY + ')').transition(s.params.speed);\n                }\n                if (s.params.paginationType === 'custom' && s.params.paginationCustomRender) {\n                    s.paginationContainer.html(s.params.paginationCustomRender(s, current + 1, total));\n                    s.emit('onPaginationRendered', s, s.paginationContainer[0]);\n                }\n            }\n        \n            // Next/active buttons\n            if (!s.params.loop) {\n                if (s.params.prevButton && s.prevButton && s.prevButton.length > 0) {\n                    if (s.isBeginning) {\n                        s.prevButton.addClass(s.params.buttonDisabledClass);\n                        if (s.params.a11y && s.a11y) s.a11y.disable(s.prevButton);\n                    }\n                    else {\n                        s.prevButton.removeClass(s.params.buttonDisabledClass);\n                        if (s.params.a11y && s.a11y) s.a11y.enable(s.prevButton);\n                    }\n                }\n                if (s.params.nextButton && s.nextButton && s.nextButton.length > 0) {\n                    if (s.isEnd) {\n                        s.nextButton.addClass(s.params.buttonDisabledClass);\n                        if (s.params.a11y && s.a11y) s.a11y.disable(s.nextButton);\n                    }\n                    else {\n                        s.nextButton.removeClass(s.params.buttonDisabledClass);\n                        if (s.params.a11y && s.a11y) s.a11y.enable(s.nextButton);\n                    }\n                }\n            }\n        };\n        \n        /*=========================\n          Pagination\n          ===========================*/\n        s.updatePagination = function () {\n            if (!s.params.pagination) return;\n            if (s.paginationContainer && s.paginationContainer.length > 0) {\n                var paginationHTML = '';\n                if (s.params.paginationType === 'bullets') {\n                    var numberOfBullets = s.params.loop ? Math.ceil((s.slides.length - s.loopedSlides * 2) / s.params.slidesPerGroup) : s.snapGrid.length;\n                    for (var i = 0; i < numberOfBullets; i++) {\n                        if (s.params.paginationBulletRender) {\n                            paginationHTML += s.params.paginationBulletRender(i, s.params.bulletClass);\n                        }\n                        else {\n                            paginationHTML += '<' + s.params.paginationElement+' class=\"' + s.params.bulletClass + '\"></' + s.params.paginationElement + '>';\n                        }\n                    }\n                    s.paginationContainer.html(paginationHTML);\n                    s.bullets = s.paginationContainer.find('.' + s.params.bulletClass);\n                    if (s.params.paginationClickable && s.params.a11y && s.a11y) {\n                        s.a11y.initPagination();\n                    }\n                }\n                if (s.params.paginationType === 'fraction') {\n                    if (s.params.paginationFractionRender) {\n                        paginationHTML = s.params.paginationFractionRender(s, s.params.paginationCurrentClass, s.params.paginationTotalClass);\n                    }\n                    else {\n                        paginationHTML =\n                            '<span class=\"' + s.params.paginationCurrentClass + '\"></span>' +\n                            ' / ' +\n                            '<span class=\"' + s.params.paginationTotalClass+'\"></span>';\n                    }\n                    s.paginationContainer.html(paginationHTML);\n                }\n                if (s.params.paginationType === 'progress') {\n                    if (s.params.paginationProgressRender) {\n                        paginationHTML = s.params.paginationProgressRender(s, s.params.paginationProgressbarClass);\n                    }\n                    else {\n                        paginationHTML = '<span class=\"' + s.params.paginationProgressbarClass + '\"></span>';\n                    }\n                    s.paginationContainer.html(paginationHTML);\n                }\n                if (s.params.paginationType !== 'custom') {\n                    s.emit('onPaginationRendered', s, s.paginationContainer[0]);\n                }\n            }\n        };\n        /*=========================\n          Common update method\n          ===========================*/\n        s.update = function (updateTranslate) {\n            s.updateContainerSize();\n            s.updateSlidesSize();\n            s.updateProgress();\n            s.updatePagination();\n            s.updateClasses();\n            if (s.params.scrollbar && s.scrollbar) {\n                s.scrollbar.set();\n            }\n            function forceSetTranslate() {\n                newTranslate = Math.min(Math.max(s.translate, s.maxTranslate()), s.minTranslate());\n                s.setWrapperTranslate(newTranslate);\n                s.updateActiveIndex();\n                s.updateClasses();\n            }\n            if (updateTranslate) {\n                var translated, newTranslate;\n                if (s.controller && s.controller.spline) {\n                    s.controller.spline = undefined;\n                }\n                if (s.params.freeMode) {\n                    forceSetTranslate();\n                    if (s.params.autoHeight) {\n                        s.updateAutoHeight();\n                    }\n                }\n                else {\n                    if ((s.params.slidesPerView === 'auto' || s.params.slidesPerView > 1) && s.isEnd && !s.params.centeredSlides) {\n                        translated = s.slideTo(s.slides.length - 1, 0, false, true);\n                    }\n                    else {\n                        translated = s.slideTo(s.activeIndex, 0, false, true);\n                    }\n                    if (!translated) {\n                        forceSetTranslate();\n                    }\n                }\n            }\n            else if (s.params.autoHeight) {\n                s.updateAutoHeight();\n            }\n        };\n        \n        /*=========================\n          Resize Handler\n          ===========================*/\n        s.onResize = function (forceUpdatePagination) {\n            //Breakpoints\n            if (s.params.breakpoints) {\n                s.setBreakpoint();\n            }\n        \n            // Disable locks on resize\n            var allowSwipeToPrev = s.params.allowSwipeToPrev;\n            var allowSwipeToNext = s.params.allowSwipeToNext;\n            s.params.allowSwipeToPrev = s.params.allowSwipeToNext = true;\n        \n            s.updateContainerSize();\n            s.updateSlidesSize();\n            if (s.params.slidesPerView === 'auto' || s.params.freeMode || forceUpdatePagination) s.updatePagination();\n            if (s.params.scrollbar && s.scrollbar) {\n                s.scrollbar.set();\n            }\n            if (s.controller && s.controller.spline) {\n                s.controller.spline = undefined;\n            }\n            var slideChangedBySlideTo = false;\n            if (s.params.freeMode) {\n                var newTranslate = Math.min(Math.max(s.translate, s.maxTranslate()), s.minTranslate());\n                s.setWrapperTranslate(newTranslate);\n                s.updateActiveIndex();\n                s.updateClasses();\n        \n                if (s.params.autoHeight) {\n                    s.updateAutoHeight();\n                }\n            }\n            else {\n                s.updateClasses();\n                if ((s.params.slidesPerView === 'auto' || s.params.slidesPerView > 1) && s.isEnd && !s.params.centeredSlides) {\n                    slideChangedBySlideTo = s.slideTo(s.slides.length - 1, 0, false, true);\n                }\n                else {\n                    slideChangedBySlideTo = s.slideTo(s.activeIndex, 0, false, true);\n                }\n            }\n            if (s.params.lazyLoading && !slideChangedBySlideTo && s.lazy) {\n                s.lazy.load();\n            }\n            // Return locks after resize\n            s.params.allowSwipeToPrev = allowSwipeToPrev;\n            s.params.allowSwipeToNext = allowSwipeToNext;\n        };\n        \n        /*=========================\n          Events\n          ===========================*/\n        \n        //Define Touch Events\n        var desktopEvents = ['mousedown', 'mousemove', 'mouseup'];\n        if (window.navigator.pointerEnabled) desktopEvents = ['pointerdown', 'pointermove', 'pointerup'];\n        else if (window.navigator.msPointerEnabled) desktopEvents = ['MSPointerDown', 'MSPointerMove', 'MSPointerUp'];\n        s.touchEvents = {\n            start : s.support.touch || !s.params.simulateTouch  ? 'touchstart' : desktopEvents[0],\n            move : s.support.touch || !s.params.simulateTouch ? 'touchmove' : desktopEvents[1],\n            end : s.support.touch || !s.params.simulateTouch ? 'touchend' : desktopEvents[2]\n        };\n        \n        \n        // WP8 Touch Events Fix\n        if (window.navigator.pointerEnabled || window.navigator.msPointerEnabled) {\n            (s.params.touchEventsTarget === 'container' ? s.container : s.wrapper).addClass('swiper-wp8-' + s.params.direction);\n        }\n        \n        // Attach/detach events\n        s.initEvents = function (detach) {\n            var actionDom = detach ? 'off' : 'on';\n            var action = detach ? 'removeEventListener' : 'addEventListener';\n            var touchEventsTarget = s.params.touchEventsTarget === 'container' ? s.container[0] : s.wrapper[0];\n            var target = s.support.touch ? touchEventsTarget : document;\n        \n            var moveCapture = s.params.nested ? true : false;\n        \n            //Touch Events\n            if (s.browser.ie) {\n                touchEventsTarget[action](s.touchEvents.start, s.onTouchStart, false);\n                target[action](s.touchEvents.move, s.onTouchMove, moveCapture);\n                target[action](s.touchEvents.end, s.onTouchEnd, false);\n            }\n            else {\n                if (s.support.touch) {\n                    touchEventsTarget[action](s.touchEvents.start, s.onTouchStart, false);\n                    touchEventsTarget[action](s.touchEvents.move, s.onTouchMove, moveCapture);\n                    touchEventsTarget[action](s.touchEvents.end, s.onTouchEnd, false);\n                }\n                if (params.simulateTouch && !s.device.ios && !s.device.android) {\n                    touchEventsTarget[action]('mousedown', s.onTouchStart, false);\n                    document[action]('mousemove', s.onTouchMove, moveCapture);\n                    document[action]('mouseup', s.onTouchEnd, false);\n                }\n            }\n            window[action]('resize', s.onResize);\n        \n            // Next, Prev, Index\n            if (s.params.nextButton && s.nextButton && s.nextButton.length > 0) {\n                s.nextButton[actionDom]('click', s.onClickNext);\n                if (s.params.a11y && s.a11y) s.nextButton[actionDom]('keydown', s.a11y.onEnterKey);\n            }\n            if (s.params.prevButton && s.prevButton && s.prevButton.length > 0) {\n                s.prevButton[actionDom]('click', s.onClickPrev);\n                if (s.params.a11y && s.a11y) s.prevButton[actionDom]('keydown', s.a11y.onEnterKey);\n            }\n            if (s.params.pagination && s.params.paginationClickable) {\n                s.paginationContainer[actionDom]('click', '.' + s.params.bulletClass, s.onClickIndex);\n                if (s.params.a11y && s.a11y) s.paginationContainer[actionDom]('keydown', '.' + s.params.bulletClass, s.a11y.onEnterKey);\n            }\n        \n            // Prevent Links Clicks\n            if (s.params.preventClicks || s.params.preventClicksPropagation) touchEventsTarget[action]('click', s.preventClicks, true);\n        };\n        s.attachEvents = function () {\n            s.initEvents();\n        };\n        s.detachEvents = function () {\n            s.initEvents(true);\n        };\n        \n        /*=========================\n          Handle Clicks\n          ===========================*/\n        // Prevent Clicks\n        s.allowClick = true;\n        s.preventClicks = function (e) {\n            if (!s.allowClick) {\n                if (s.params.preventClicks) e.preventDefault();\n                if (s.params.preventClicksPropagation && s.animating) {\n                    e.stopPropagation();\n                    e.stopImmediatePropagation();\n                }\n            }\n        };\n        // Clicks\n        s.onClickNext = function (e) {\n            e.preventDefault();\n            if (s.isEnd && !s.params.loop) return;\n            s.slideNext();\n        };\n        s.onClickPrev = function (e) {\n            e.preventDefault();\n            if (s.isBeginning && !s.params.loop) return;\n            s.slidePrev();\n        };\n        s.onClickIndex = function (e) {\n            e.preventDefault();\n            var index = $(this).index() * s.params.slidesPerGroup;\n            if (s.params.loop) index = index + s.loopedSlides;\n            s.slideTo(index);\n        };\n        \n        /*=========================\n          Handle Touches\n          ===========================*/\n        function findElementInEvent(e, selector) {\n            var el = $(e.target);\n            if (!el.is(selector)) {\n                if (typeof selector === 'string') {\n                    el = el.parents(selector);\n                }\n                else if (selector.nodeType) {\n                    var found;\n                    el.parents().each(function (index, _el) {\n                        if (_el === selector) found = selector;\n                    });\n                    if (!found) return undefined;\n                    else return selector;\n                }\n            }\n            if (el.length === 0) {\n                return undefined;\n            }\n            return el[0];\n        }\n        s.updateClickedSlide = function (e) {\n            var slide = findElementInEvent(e, '.' + s.params.slideClass);\n            var slideFound = false;\n            if (slide) {\n                for (var i = 0; i < s.slides.length; i++) {\n                    if (s.slides[i] === slide) slideFound = true;\n                }\n            }\n        \n            if (slide && slideFound) {\n                s.clickedSlide = slide;\n                s.clickedIndex = $(slide).index();\n            }\n            else {\n                s.clickedSlide = undefined;\n                s.clickedIndex = undefined;\n                return;\n            }\n            if (s.params.slideToClickedSlide && s.clickedIndex !== undefined && s.clickedIndex !== s.activeIndex) {\n                var slideToIndex = s.clickedIndex,\n                    realIndex,\n                    duplicatedSlides;\n                if (s.params.loop) {\n                    if (s.animating) return;\n                    realIndex = $(s.clickedSlide).attr('data-swiper-slide-index');\n                    if (s.params.centeredSlides) {\n                        if ((slideToIndex < s.loopedSlides - s.params.slidesPerView/2) || (slideToIndex > s.slides.length - s.loopedSlides + s.params.slidesPerView/2)) {\n                            s.fixLoop();\n                            slideToIndex = s.wrapper.children('.' + s.params.slideClass + '[data-swiper-slide-index=\"' + realIndex + '\"]:not(.swiper-slide-duplicate)').eq(0).index();\n                            setTimeout(function () {\n                                s.slideTo(slideToIndex);\n                            }, 0);\n                        }\n                        else {\n                            s.slideTo(slideToIndex);\n                        }\n                    }\n                    else {\n                        if (slideToIndex > s.slides.length - s.params.slidesPerView) {\n                            s.fixLoop();\n                            slideToIndex = s.wrapper.children('.' + s.params.slideClass + '[data-swiper-slide-index=\"' + realIndex + '\"]:not(.swiper-slide-duplicate)').eq(0).index();\n                            setTimeout(function () {\n                                s.slideTo(slideToIndex);\n                            }, 0);\n                        }\n                        else {\n                            s.slideTo(slideToIndex);\n                        }\n                    }\n                }\n                else {\n                    s.slideTo(slideToIndex);\n                }\n            }\n        };\n        \n        var isTouched,\n            isMoved,\n            allowTouchCallbacks,\n            touchStartTime,\n            isScrolling,\n            currentTranslate,\n            startTranslate,\n            allowThresholdMove,\n            // Form elements to match\n            formElements = 'input, select, textarea, button',\n            // Last click time\n            lastClickTime = Date.now(), clickTimeout,\n            //Velocities\n            velocities = [],\n            allowMomentumBounce;\n        \n        // Animating Flag\n        s.animating = false;\n        \n        // Touches information\n        s.touches = {\n            startX: 0,\n            startY: 0,\n            currentX: 0,\n            currentY: 0,\n            diff: 0\n        };\n        \n        // Touch handlers\n        var isTouchEvent, startMoving;\n        s.onTouchStart = function (e) {\n            if (e.originalEvent) e = e.originalEvent;\n            isTouchEvent = e.type === 'touchstart';\n            if (!isTouchEvent && 'which' in e && e.which === 3) return;\n            if (s.params.noSwiping && findElementInEvent(e, '.' + s.params.noSwipingClass)) {\n                s.allowClick = true;\n                return;\n            }\n            if (s.params.swipeHandler) {\n                if (!findElementInEvent(e, s.params.swipeHandler)) return;\n            }\n        \n            var startX = s.touches.currentX = e.type === 'touchstart' ? e.targetTouches[0].pageX : e.pageX;\n            var startY = s.touches.currentY = e.type === 'touchstart' ? e.targetTouches[0].pageY : e.pageY;\n        \n            // Do NOT start if iOS edge swipe is detected. Otherwise iOS app (UIWebView) cannot swipe-to-go-back anymore\n            if(s.device.ios && s.params.iOSEdgeSwipeDetection && startX <= s.params.iOSEdgeSwipeThreshold) {\n                return;\n            }\n        \n            isTouched = true;\n            isMoved = false;\n            allowTouchCallbacks = true;\n            isScrolling = undefined;\n            startMoving = undefined;\n            s.touches.startX = startX;\n            s.touches.startY = startY;\n            touchStartTime = Date.now();\n            s.allowClick = true;\n            s.updateContainerSize();\n            s.swipeDirection = undefined;\n            if (s.params.threshold > 0) allowThresholdMove = false;\n            if (e.type !== 'touchstart') {\n                var preventDefault = true;\n                if ($(e.target).is(formElements)) preventDefault = false;\n                if (document.activeElement && $(document.activeElement).is(formElements)) {\n                    document.activeElement.blur();\n                }\n                if (preventDefault) {\n                    e.preventDefault();\n                }\n            }\n            s.emit('onTouchStart', s, e);\n        };\n        \n        s.onTouchMove = function (e) {\n            if (e.originalEvent) e = e.originalEvent;\n            if (isTouchEvent && e.type === 'mousemove') return;\n            if (e.preventedByNestedSwiper) {\n                s.touches.startX = e.type === 'touchmove' ? e.targetTouches[0].pageX : e.pageX;\n                s.touches.startY = e.type === 'touchmove' ? e.targetTouches[0].pageY : e.pageY;\n                return;\n            }\n            if (s.params.onlyExternal) {\n                // isMoved = true;\n                s.allowClick = false;\n                if (isTouched) {\n                    s.touches.startX = s.touches.currentX = e.type === 'touchmove' ? e.targetTouches[0].pageX : e.pageX;\n                    s.touches.startY = s.touches.currentY = e.type === 'touchmove' ? e.targetTouches[0].pageY : e.pageY;\n                    touchStartTime = Date.now();\n                }\n                return;\n            }\n            if (isTouchEvent && document.activeElement) {\n                if (e.target === document.activeElement && $(e.target).is(formElements)) {\n                    isMoved = true;\n                    s.allowClick = false;\n                    return;\n                }\n            }\n            if (allowTouchCallbacks) {\n                s.emit('onTouchMove', s, e);\n            }\n            if (e.targetTouches && e.targetTouches.length > 1) return;\n        \n            s.touches.currentX = e.type === 'touchmove' ? e.targetTouches[0].pageX : e.pageX;\n            s.touches.currentY = e.type === 'touchmove' ? e.targetTouches[0].pageY : e.pageY;\n        \n            if (typeof isScrolling === 'undefined') {\n                var touchAngle = Math.atan2(Math.abs(s.touches.currentY - s.touches.startY), Math.abs(s.touches.currentX - s.touches.startX)) * 180 / Math.PI;\n                isScrolling = s.isHorizontal() ? touchAngle > s.params.touchAngle : (90 - touchAngle > s.params.touchAngle);\n            }\n            if (isScrolling) {\n                s.emit('onTouchMoveOpposite', s, e);\n            }\n            if (typeof startMoving === 'undefined' && s.browser.ieTouch) {\n                if (s.touches.currentX !== s.touches.startX || s.touches.currentY !== s.touches.startY) {\n                    startMoving = true;\n                }\n            }\n            if (!isTouched) return;\n            if (isScrolling)  {\n                isTouched = false;\n                return;\n            }\n            if (!startMoving && s.browser.ieTouch) {\n                return;\n            }\n            s.allowClick = false;\n            s.emit('onSliderMove', s, e);\n            e.preventDefault();\n            if (s.params.touchMoveStopPropagation && !s.params.nested) {\n                e.stopPropagation();\n            }\n        \n            if (!isMoved) {\n                if (params.loop) {\n                    s.fixLoop();\n                }\n                startTranslate = s.getWrapperTranslate();\n                s.setWrapperTransition(0);\n                if (s.animating) {\n                    s.wrapper.trigger('webkitTransitionEnd transitionend oTransitionEnd MSTransitionEnd msTransitionEnd');\n                }\n                if (s.params.autoplay && s.autoplaying) {\n                    if (s.params.autoplayDisableOnInteraction) {\n                        s.stopAutoplay();\n                    }\n                    else {\n                        s.pauseAutoplay();\n                    }\n                }\n                allowMomentumBounce = false;\n                //Grab Cursor\n                if (s.params.grabCursor) {\n                    s.container[0].style.cursor = 'move';\n                    s.container[0].style.cursor = '-webkit-grabbing';\n                    s.container[0].style.cursor = '-moz-grabbin';\n                    s.container[0].style.cursor = 'grabbing';\n                }\n            }\n            isMoved = true;\n        \n            var diff = s.touches.diff = s.isHorizontal() ? s.touches.currentX - s.touches.startX : s.touches.currentY - s.touches.startY;\n        \n            diff = diff * s.params.touchRatio;\n            if (s.rtl) diff = -diff;\n        \n            s.swipeDirection = diff > 0 ? 'prev' : 'next';\n            currentTranslate = diff + startTranslate;\n        \n            var disableParentSwiper = true;\n            if ((diff > 0 && currentTranslate > s.minTranslate())) {\n                disableParentSwiper = false;\n                if (s.params.resistance) currentTranslate = s.minTranslate() - 1 + Math.pow(-s.minTranslate() + startTranslate + diff, s.params.resistanceRatio);\n            }\n            else if (diff < 0 && currentTranslate < s.maxTranslate()) {\n                disableParentSwiper = false;\n                if (s.params.resistance) currentTranslate = s.maxTranslate() + 1 - Math.pow(s.maxTranslate() - startTranslate - diff, s.params.resistanceRatio);\n            }\n        \n            if (disableParentSwiper) {\n                e.preventedByNestedSwiper = true;\n            }\n        \n            // Directions locks\n            if (!s.params.allowSwipeToNext && s.swipeDirection === 'next' && currentTranslate < startTranslate) {\n                currentTranslate = startTranslate;\n            }\n            if (!s.params.allowSwipeToPrev && s.swipeDirection === 'prev' && currentTranslate > startTranslate) {\n                currentTranslate = startTranslate;\n            }\n        \n            if (!s.params.followFinger) return;\n        \n            // Threshold\n            if (s.params.threshold > 0) {\n                if (Math.abs(diff) > s.params.threshold || allowThresholdMove) {\n                    if (!allowThresholdMove) {\n                        allowThresholdMove = true;\n                        s.touches.startX = s.touches.currentX;\n                        s.touches.startY = s.touches.currentY;\n                        currentTranslate = startTranslate;\n                        s.touches.diff = s.isHorizontal() ? s.touches.currentX - s.touches.startX : s.touches.currentY - s.touches.startY;\n                        return;\n                    }\n                }\n                else {\n                    currentTranslate = startTranslate;\n                    return;\n                }\n            }\n            // Update active index in free mode\n            if (s.params.freeMode || s.params.watchSlidesProgress) {\n                s.updateActiveIndex();\n            }\n            if (s.params.freeMode) {\n                //Velocity\n                if (velocities.length === 0) {\n                    velocities.push({\n                        position: s.touches[s.isHorizontal() ? 'startX' : 'startY'],\n                        time: touchStartTime\n                    });\n                }\n                velocities.push({\n                    position: s.touches[s.isHorizontal() ? 'currentX' : 'currentY'],\n                    time: (new window.Date()).getTime()\n                });\n            }\n            // Update progress\n            s.updateProgress(currentTranslate);\n            // Update translate\n            s.setWrapperTranslate(currentTranslate);\n        };\n        s.onTouchEnd = function (e) {\n            if (e.originalEvent) e = e.originalEvent;\n            if (allowTouchCallbacks) {\n                s.emit('onTouchEnd', s, e);\n            }\n            allowTouchCallbacks = false;\n            if (!isTouched) return;\n            //Return Grab Cursor\n            if (s.params.grabCursor && isMoved && isTouched) {\n                s.container[0].style.cursor = 'move';\n                s.container[0].style.cursor = '-webkit-grab';\n                s.container[0].style.cursor = '-moz-grab';\n                s.container[0].style.cursor = 'grab';\n            }\n        \n            // Time diff\n            var touchEndTime = Date.now();\n            var timeDiff = touchEndTime - touchStartTime;\n        \n            // Tap, doubleTap, Click\n            if (s.allowClick) {\n                s.updateClickedSlide(e);\n                s.emit('onTap', s, e);\n                if (timeDiff < 300 && (touchEndTime - lastClickTime) > 300) {\n                    if (clickTimeout) clearTimeout(clickTimeout);\n                    clickTimeout = setTimeout(function () {\n                        if (!s) return;\n                        if (s.params.paginationHide && s.paginationContainer.length > 0 && !$(e.target).hasClass(s.params.bulletClass)) {\n                            s.paginationContainer.toggleClass(s.params.paginationHiddenClass);\n                        }\n                        s.emit('onClick', s, e);\n                    }, 300);\n        \n                }\n                if (timeDiff < 300 && (touchEndTime - lastClickTime) < 300) {\n                    if (clickTimeout) clearTimeout(clickTimeout);\n                    s.emit('onDoubleTap', s, e);\n                }\n            }\n        \n            lastClickTime = Date.now();\n            setTimeout(function () {\n                if (s) s.allowClick = true;\n            }, 0);\n        \n            if (!isTouched || !isMoved || !s.swipeDirection || s.touches.diff === 0 || currentTranslate === startTranslate) {\n                isTouched = isMoved = false;\n                return;\n            }\n            isTouched = isMoved = false;\n        \n            var currentPos;\n            if (s.params.followFinger) {\n                currentPos = s.rtl ? s.translate : -s.translate;\n            }\n            else {\n                currentPos = -currentTranslate;\n            }\n            if (s.params.freeMode) {\n                if (currentPos < -s.minTranslate()) {\n                    s.slideTo(s.activeIndex);\n                    return;\n                }\n                else if (currentPos > -s.maxTranslate()) {\n                    if (s.slides.length < s.snapGrid.length) {\n                        s.slideTo(s.snapGrid.length - 1);\n                    }\n                    else {\n                        s.slideTo(s.slides.length - 1);\n                    }\n                    return;\n                }\n        \n                if (s.params.freeModeMomentum) {\n                    if (velocities.length > 1) {\n                        var lastMoveEvent = velocities.pop(), velocityEvent = velocities.pop();\n        \n                        var distance = lastMoveEvent.position - velocityEvent.position;\n                        var time = lastMoveEvent.time - velocityEvent.time;\n                        s.velocity = distance / time;\n                        s.velocity = s.velocity / 2;\n                        if (Math.abs(s.velocity) < s.params.freeModeMinimumVelocity) {\n                            s.velocity = 0;\n                        }\n                        // this implies that the user stopped moving a finger then released.\n                        // There would be no events with distance zero, so the last event is stale.\n                        if (time > 150 || (new window.Date().getTime() - lastMoveEvent.time) > 300) {\n                            s.velocity = 0;\n                        }\n                    } else {\n                        s.velocity = 0;\n                    }\n        \n                    velocities.length = 0;\n                    var momentumDuration = 1000 * s.params.freeModeMomentumRatio;\n                    var momentumDistance = s.velocity * momentumDuration;\n        \n                    var newPosition = s.translate + momentumDistance;\n                    if (s.rtl) newPosition = - newPosition;\n                    var doBounce = false;\n                    var afterBouncePosition;\n                    var bounceAmount = Math.abs(s.velocity) * 20 * s.params.freeModeMomentumBounceRatio;\n                    if (newPosition < s.maxTranslate()) {\n                        if (s.params.freeModeMomentumBounce) {\n                            if (newPosition + s.maxTranslate() < -bounceAmount) {\n                                newPosition = s.maxTranslate() - bounceAmount;\n                            }\n                            afterBouncePosition = s.maxTranslate();\n                            doBounce = true;\n                            allowMomentumBounce = true;\n                        }\n                        else {\n                            newPosition = s.maxTranslate();\n                        }\n                    }\n                    else if (newPosition > s.minTranslate()) {\n                        if (s.params.freeModeMomentumBounce) {\n                            if (newPosition - s.minTranslate() > bounceAmount) {\n                                newPosition = s.minTranslate() + bounceAmount;\n                            }\n                            afterBouncePosition = s.minTranslate();\n                            doBounce = true;\n                            allowMomentumBounce = true;\n                        }\n                        else {\n                            newPosition = s.minTranslate();\n                        }\n                    }\n                    else if (s.params.freeModeSticky) {\n                        var j = 0,\n                            nextSlide;\n                        for (j = 0; j < s.snapGrid.length; j += 1) {\n                            if (s.snapGrid[j] > -newPosition) {\n                                nextSlide = j;\n                                break;\n                            }\n        \n                        }\n                        if (Math.abs(s.snapGrid[nextSlide] - newPosition) < Math.abs(s.snapGrid[nextSlide - 1] - newPosition) || s.swipeDirection === 'next') {\n                            newPosition = s.snapGrid[nextSlide];\n                        } else {\n                            newPosition = s.snapGrid[nextSlide - 1];\n                        }\n                        if (!s.rtl) newPosition = - newPosition;\n                    }\n                    //Fix duration\n                    if (s.velocity !== 0) {\n                        if (s.rtl) {\n                            momentumDuration = Math.abs((-newPosition - s.translate) / s.velocity);\n                        }\n                        else {\n                            momentumDuration = Math.abs((newPosition - s.translate) / s.velocity);\n                        }\n                    }\n                    else if (s.params.freeModeSticky) {\n                        s.slideReset();\n                        return;\n                    }\n        \n                    if (s.params.freeModeMomentumBounce && doBounce) {\n                        s.updateProgress(afterBouncePosition);\n                        s.setWrapperTransition(momentumDuration);\n                        s.setWrapperTranslate(newPosition);\n                        s.onTransitionStart();\n                        s.animating = true;\n                        s.wrapper.transitionEnd(function () {\n                            if (!s || !allowMomentumBounce) return;\n                            s.emit('onMomentumBounce', s);\n        \n                            s.setWrapperTransition(s.params.speed);\n                            s.setWrapperTranslate(afterBouncePosition);\n                            s.wrapper.transitionEnd(function () {\n                                if (!s) return;\n                                s.onTransitionEnd();\n                            });\n                        });\n                    } else if (s.velocity) {\n                        s.updateProgress(newPosition);\n                        s.setWrapperTransition(momentumDuration);\n                        s.setWrapperTranslate(newPosition);\n                        s.onTransitionStart();\n                        if (!s.animating) {\n                            s.animating = true;\n                            s.wrapper.transitionEnd(function () {\n                                if (!s) return;\n                                s.onTransitionEnd();\n                            });\n                        }\n        \n                    } else {\n                        s.updateProgress(newPosition);\n                    }\n        \n                    s.updateActiveIndex();\n                }\n                if (!s.params.freeModeMomentum || timeDiff >= s.params.longSwipesMs) {\n                    s.updateProgress();\n                    s.updateActiveIndex();\n                }\n                return;\n            }\n        \n            // Find current slide\n            var i, stopIndex = 0, groupSize = s.slidesSizesGrid[0];\n            for (i = 0; i < s.slidesGrid.length; i += s.params.slidesPerGroup) {\n                if (typeof s.slidesGrid[i + s.params.slidesPerGroup] !== 'undefined') {\n                    if (currentPos >= s.slidesGrid[i] && currentPos < s.slidesGrid[i + s.params.slidesPerGroup]) {\n                        stopIndex = i;\n                        groupSize = s.slidesGrid[i + s.params.slidesPerGroup] - s.slidesGrid[i];\n                    }\n                }\n                else {\n                    if (currentPos >= s.slidesGrid[i]) {\n                        stopIndex = i;\n                        groupSize = s.slidesGrid[s.slidesGrid.length - 1] - s.slidesGrid[s.slidesGrid.length - 2];\n                    }\n                }\n            }\n        \n            // Find current slide size\n            var ratio = (currentPos - s.slidesGrid[stopIndex]) / groupSize;\n        \n            if (timeDiff > s.params.longSwipesMs) {\n                // Long touches\n                if (!s.params.longSwipes) {\n                    s.slideTo(s.activeIndex);\n                    return;\n                }\n                if (s.swipeDirection === 'next') {\n                    if (ratio >= s.params.longSwipesRatio) s.slideTo(stopIndex + s.params.slidesPerGroup);\n                    else s.slideTo(stopIndex);\n        \n                }\n                if (s.swipeDirection === 'prev') {\n                    if (ratio > (1 - s.params.longSwipesRatio)) s.slideTo(stopIndex + s.params.slidesPerGroup);\n                    else s.slideTo(stopIndex);\n                }\n            }\n            else {\n                // Short swipes\n                if (!s.params.shortSwipes) {\n                    s.slideTo(s.activeIndex);\n                    return;\n                }\n                if (s.swipeDirection === 'next') {\n                    s.slideTo(stopIndex + s.params.slidesPerGroup);\n        \n                }\n                if (s.swipeDirection === 'prev') {\n                    s.slideTo(stopIndex);\n                }\n            }\n        };\n        /*=========================\n          Transitions\n          ===========================*/\n        s._slideTo = function (slideIndex, speed) {\n            return s.slideTo(slideIndex, speed, true, true);\n        };\n        s.slideTo = function (slideIndex, speed, runCallbacks, internal) {\n            if (typeof runCallbacks === 'undefined') runCallbacks = true;\n            if (typeof slideIndex === 'undefined') slideIndex = 0;\n            if (slideIndex < 0) slideIndex = 0;\n            s.snapIndex = Math.floor(slideIndex / s.params.slidesPerGroup);\n            if (s.snapIndex >= s.snapGrid.length) s.snapIndex = s.snapGrid.length - 1;\n        \n            var translate = - s.snapGrid[s.snapIndex];\n            // Stop autoplay\n            if (s.params.autoplay && s.autoplaying) {\n                if (internal || !s.params.autoplayDisableOnInteraction) {\n                    s.pauseAutoplay(speed);\n                }\n                else {\n                    s.stopAutoplay();\n                }\n            }\n            // Update progress\n            s.updateProgress(translate);\n        \n            // Normalize slideIndex\n            for (var i = 0; i < s.slidesGrid.length; i++) {\n                if (- Math.floor(translate * 100) >= Math.floor(s.slidesGrid[i] * 100)) {\n                    slideIndex = i;\n                }\n            }\n        \n            // Directions locks\n            if (!s.params.allowSwipeToNext && translate < s.translate && translate < s.minTranslate()) {\n                return false;\n            }\n            if (!s.params.allowSwipeToPrev && translate > s.translate && translate > s.maxTranslate()) {\n                if ((s.activeIndex || 0) !== slideIndex ) return false;\n            }\n        \n            // Update Index\n            if (typeof speed === 'undefined') speed = s.params.speed;\n            s.previousIndex = s.activeIndex || 0;\n            s.activeIndex = slideIndex;\n        \n            if ((s.rtl && -translate === s.translate) || (!s.rtl && translate === s.translate)) {\n                // Update Height\n                if (s.params.autoHeight) {\n                    s.updateAutoHeight();\n                }\n                s.updateClasses();\n                if (s.params.effect !== 'slide') {\n                    s.setWrapperTranslate(translate);\n                }\n                return false;\n            }\n            s.updateClasses();\n            s.onTransitionStart(runCallbacks);\n        \n            if (speed === 0) {\n                s.setWrapperTranslate(translate);\n                s.setWrapperTransition(0);\n                s.onTransitionEnd(runCallbacks);\n            }\n            else {\n                s.setWrapperTranslate(translate);\n                s.setWrapperTransition(speed);\n                if (!s.animating) {\n                    s.animating = true;\n                    s.wrapper.transitionEnd(function () {\n                        if (!s) return;\n                        s.onTransitionEnd(runCallbacks);\n                    });\n                }\n        \n            }\n        \n            return true;\n        };\n        \n        s.onTransitionStart = function (runCallbacks) {\n            if (typeof runCallbacks === 'undefined') runCallbacks = true;\n            if (s.params.autoHeight) {\n                s.updateAutoHeight();\n            }\n            if (s.lazy) s.lazy.onTransitionStart();\n            if (runCallbacks) {\n                s.emit('onTransitionStart', s);\n                if (s.activeIndex !== s.previousIndex) {\n                    s.emit('onSlideChangeStart', s);\n                    if (s.activeIndex > s.previousIndex) {\n                        s.emit('onSlideNextStart', s);\n                    }\n                    else {\n                        s.emit('onSlidePrevStart', s);\n                    }\n                }\n        \n            }\n        };\n        s.onTransitionEnd = function (runCallbacks) {\n            s.animating = false;\n            s.setWrapperTransition(0);\n            if (typeof runCallbacks === 'undefined') runCallbacks = true;\n            if (s.lazy) s.lazy.onTransitionEnd();\n            if (runCallbacks) {\n                s.emit('onTransitionEnd', s);\n                if (s.activeIndex !== s.previousIndex) {\n                    s.emit('onSlideChangeEnd', s);\n                    if (s.activeIndex > s.previousIndex) {\n                        s.emit('onSlideNextEnd', s);\n                    }\n                    else {\n                        s.emit('onSlidePrevEnd', s);\n                    }\n                }\n            }\n            if (s.params.hashnav && s.hashnav) {\n                s.hashnav.setHash();\n            }\n        \n        };\n        s.slideNext = function (runCallbacks, speed, internal) {\n            if (s.params.loop) {\n                if (s.animating) return false;\n                s.fixLoop();\n                var clientLeft = s.container[0].clientLeft;\n                return s.slideTo(s.activeIndex + s.params.slidesPerGroup, speed, runCallbacks, internal);\n            }\n            else return s.slideTo(s.activeIndex + s.params.slidesPerGroup, speed, runCallbacks, internal);\n        };\n        s._slideNext = function (speed) {\n            return s.slideNext(true, speed, true);\n        };\n        s.slidePrev = function (runCallbacks, speed, internal) {\n            if (s.params.loop) {\n                if (s.animating) return false;\n                s.fixLoop();\n                var clientLeft = s.container[0].clientLeft;\n                return s.slideTo(s.activeIndex - 1, speed, runCallbacks, internal);\n            }\n            else return s.slideTo(s.activeIndex - 1, speed, runCallbacks, internal);\n        };\n        s._slidePrev = function (speed) {\n            return s.slidePrev(true, speed, true);\n        };\n        s.slideReset = function (runCallbacks, speed, internal) {\n            return s.slideTo(s.activeIndex, speed, runCallbacks);\n        };\n        \n        /*=========================\n          Translate/transition helpers\n          ===========================*/\n        s.setWrapperTransition = function (duration, byController) {\n            s.wrapper.transition(duration);\n            if (s.params.effect !== 'slide' && s.effects[s.params.effect]) {\n                s.effects[s.params.effect].setTransition(duration);\n            }\n            if (s.params.parallax && s.parallax) {\n                s.parallax.setTransition(duration);\n            }\n            if (s.params.scrollbar && s.scrollbar) {\n                s.scrollbar.setTransition(duration);\n            }\n            if (s.params.control && s.controller) {\n                s.controller.setTransition(duration, byController);\n            }\n            s.emit('onSetTransition', s, duration);\n        };\n        s.setWrapperTranslate = function (translate, updateActiveIndex, byController) {\n            var x = 0, y = 0, z = 0;\n            if (s.isHorizontal()) {\n                x = s.rtl ? -translate : translate;\n            }\n            else {\n                y = translate;\n            }\n        \n            if (s.params.roundLengths) {\n                x = round(x);\n                y = round(y);\n            }\n        \n            if (!s.params.virtualTranslate) {\n                if (s.support.transforms3d) s.wrapper.transform('translate3d(' + x + 'px, ' + y + 'px, ' + z + 'px)');\n                else s.wrapper.transform('translate(' + x + 'px, ' + y + 'px)');\n            }\n        \n            s.translate = s.isHorizontal() ? x : y;\n        \n            // Check if we need to update progress\n            var progress;\n            var translatesDiff = s.maxTranslate() - s.minTranslate();\n            if (translatesDiff === 0) {\n                progress = 0;\n            }\n            else {\n                progress = (translate - s.minTranslate()) / (translatesDiff);\n            }\n            if (progress !== s.progress) {\n                s.updateProgress(translate);\n            }\n        \n            if (updateActiveIndex) s.updateActiveIndex();\n            if (s.params.effect !== 'slide' && s.effects[s.params.effect]) {\n                s.effects[s.params.effect].setTranslate(s.translate);\n            }\n            if (s.params.parallax && s.parallax) {\n                s.parallax.setTranslate(s.translate);\n            }\n            if (s.params.scrollbar && s.scrollbar) {\n                s.scrollbar.setTranslate(s.translate);\n            }\n            if (s.params.control && s.controller) {\n                s.controller.setTranslate(s.translate, byController);\n            }\n            s.emit('onSetTranslate', s, s.translate);\n        };\n        \n        s.getTranslate = function (el, axis) {\n            var matrix, curTransform, curStyle, transformMatrix;\n        \n            // automatic axis detection\n            if (typeof axis === 'undefined') {\n                axis = 'x';\n            }\n        \n            if (s.params.virtualTranslate) {\n                return s.rtl ? -s.translate : s.translate;\n            }\n        \n            curStyle = window.getComputedStyle(el, null);\n            if (window.WebKitCSSMatrix) {\n                curTransform = curStyle.transform || curStyle.webkitTransform;\n                if (curTransform.split(',').length > 6) {\n                    curTransform = curTransform.split(', ').map(function(a){\n                        return a.replace(',','.');\n                    }).join(', ');\n                }\n                // Some old versions of Webkit choke when 'none' is passed; pass\n                // empty string instead in this case\n                transformMatrix = new window.WebKitCSSMatrix(curTransform === 'none' ? '' : curTransform);\n            }\n            else {\n                transformMatrix = curStyle.MozTransform || curStyle.OTransform || curStyle.MsTransform || curStyle.msTransform  || curStyle.transform || curStyle.getPropertyValue('transform').replace('translate(', 'matrix(1, 0, 0, 1,');\n                matrix = transformMatrix.toString().split(',');\n            }\n        \n            if (axis === 'x') {\n                //Latest Chrome and webkits Fix\n                if (window.WebKitCSSMatrix)\n                    curTransform = transformMatrix.m41;\n                //Crazy IE10 Matrix\n                else if (matrix.length === 16)\n                    curTransform = parseFloat(matrix[12]);\n                //Normal Browsers\n                else\n                    curTransform = parseFloat(matrix[4]);\n            }\n            if (axis === 'y') {\n                //Latest Chrome and webkits Fix\n                if (window.WebKitCSSMatrix)\n                    curTransform = transformMatrix.m42;\n                //Crazy IE10 Matrix\n                else if (matrix.length === 16)\n                    curTransform = parseFloat(matrix[13]);\n                //Normal Browsers\n                else\n                    curTransform = parseFloat(matrix[5]);\n            }\n            if (s.rtl && curTransform) curTransform = -curTransform;\n            return curTransform || 0;\n        };\n        s.getWrapperTranslate = function (axis) {\n            if (typeof axis === 'undefined') {\n                axis = s.isHorizontal() ? 'x' : 'y';\n            }\n            return s.getTranslate(s.wrapper[0], axis);\n        };\n        \n        /*=========================\n          Observer\n          ===========================*/\n        s.observers = [];\n        function initObserver(target, options) {\n            options = options || {};\n            // create an observer instance\n            var ObserverFunc = window.MutationObserver || window.WebkitMutationObserver;\n            var observer = new ObserverFunc(function (mutations) {\n                mutations.forEach(function (mutation) {\n                    s.onResize(true);\n                    s.emit('onObserverUpdate', s, mutation);\n                });\n            });\n        \n            observer.observe(target, {\n                attributes: typeof options.attributes === 'undefined' ? true : options.attributes,\n                childList: typeof options.childList === 'undefined' ? true : options.childList,\n                characterData: typeof options.characterData === 'undefined' ? true : options.characterData\n            });\n        \n            s.observers.push(observer);\n        }\n        s.initObservers = function () {\n            if (s.params.observeParents) {\n                var containerParents = s.container.parents();\n                for (var i = 0; i < containerParents.length; i++) {\n                    initObserver(containerParents[i]);\n                }\n            }\n        \n            // Observe container\n            initObserver(s.container[0], {childList: false});\n        \n            // Observe wrapper\n            initObserver(s.wrapper[0], {attributes: false});\n        };\n        s.disconnectObservers = function () {\n            for (var i = 0; i < s.observers.length; i++) {\n                s.observers[i].disconnect();\n            }\n            s.observers = [];\n        };\n        /*=========================\n          Loop\n          ===========================*/\n        // Create looped slides\n        s.createLoop = function () {\n            // Remove duplicated slides\n            s.wrapper.children('.' + s.params.slideClass + '.' + s.params.slideDuplicateClass).remove();\n        \n            var slides = s.wrapper.children('.' + s.params.slideClass);\n        \n            if(s.params.slidesPerView === 'auto' && !s.params.loopedSlides) s.params.loopedSlides = slides.length;\n        \n            s.loopedSlides = parseInt(s.params.loopedSlides || s.params.slidesPerView, 10);\n            s.loopedSlides = s.loopedSlides + s.params.loopAdditionalSlides;\n            if (s.loopedSlides > slides.length) {\n                s.loopedSlides = slides.length;\n            }\n        \n            var prependSlides = [], appendSlides = [], i;\n            slides.each(function (index, el) {\n                var slide = $(this);\n                if (index < s.loopedSlides) appendSlides.push(el);\n                if (index < slides.length && index >= slides.length - s.loopedSlides) prependSlides.push(el);\n                slide.attr('data-swiper-slide-index', index);\n            });\n            for (i = 0; i < appendSlides.length; i++) {\n                s.wrapper.append($(appendSlides[i].cloneNode(true)).addClass(s.params.slideDuplicateClass));\n            }\n            for (i = prependSlides.length - 1; i >= 0; i--) {\n                s.wrapper.prepend($(prependSlides[i].cloneNode(true)).addClass(s.params.slideDuplicateClass));\n            }\n        };\n        s.destroyLoop = function () {\n            s.wrapper.children('.' + s.params.slideClass + '.' + s.params.slideDuplicateClass).remove();\n            s.slides.removeAttr('data-swiper-slide-index');\n        };\n        s.reLoop = function (updatePosition) {\n            var oldIndex = s.activeIndex - s.loopedSlides;\n            s.destroyLoop();\n            s.createLoop();\n            s.updateSlidesSize();\n            if (updatePosition) {\n                s.slideTo(oldIndex + s.loopedSlides, 0, false);\n            }\n        \n        };\n        s.fixLoop = function () {\n            var newIndex;\n            //Fix For Negative Oversliding\n            if (s.activeIndex < s.loopedSlides) {\n                newIndex = s.slides.length - s.loopedSlides * 3 + s.activeIndex;\n                newIndex = newIndex + s.loopedSlides;\n                s.slideTo(newIndex, 0, false, true);\n            }\n            //Fix For Positive Oversliding\n            else if ((s.params.slidesPerView === 'auto' && s.activeIndex >= s.loopedSlides * 2) || (s.activeIndex > s.slides.length - s.params.slidesPerView * 2)) {\n                newIndex = -s.slides.length + s.activeIndex + s.loopedSlides;\n                newIndex = newIndex + s.loopedSlides;\n                s.slideTo(newIndex, 0, false, true);\n            }\n        };\n        /*=========================\n          Append/Prepend/Remove Slides\n          ===========================*/\n        s.appendSlide = function (slides) {\n            if (s.params.loop) {\n                s.destroyLoop();\n            }\n            if (typeof slides === 'object' && slides.length) {\n                for (var i = 0; i < slides.length; i++) {\n                    if (slides[i]) s.wrapper.append(slides[i]);\n                }\n            }\n            else {\n                s.wrapper.append(slides);\n            }\n            if (s.params.loop) {\n                s.createLoop();\n            }\n            if (!(s.params.observer && s.support.observer)) {\n                s.update(true);\n            }\n        };\n        s.prependSlide = function (slides) {\n            if (s.params.loop) {\n                s.destroyLoop();\n            }\n            var newActiveIndex = s.activeIndex + 1;\n            if (typeof slides === 'object' && slides.length) {\n                for (var i = 0; i < slides.length; i++) {\n                    if (slides[i]) s.wrapper.prepend(slides[i]);\n                }\n                newActiveIndex = s.activeIndex + slides.length;\n            }\n            else {\n                s.wrapper.prepend(slides);\n            }\n            if (s.params.loop) {\n                s.createLoop();\n            }\n            if (!(s.params.observer && s.support.observer)) {\n                s.update(true);\n            }\n            s.slideTo(newActiveIndex, 0, false);\n        };\n        s.removeSlide = function (slidesIndexes) {\n            if (s.params.loop) {\n                s.destroyLoop();\n                s.slides = s.wrapper.children('.' + s.params.slideClass);\n            }\n            var newActiveIndex = s.activeIndex,\n                indexToRemove;\n            if (typeof slidesIndexes === 'object' && slidesIndexes.length) {\n                for (var i = 0; i < slidesIndexes.length; i++) {\n                    indexToRemove = slidesIndexes[i];\n                    if (s.slides[indexToRemove]) s.slides.eq(indexToRemove).remove();\n                    if (indexToRemove < newActiveIndex) newActiveIndex--;\n                }\n                newActiveIndex = Math.max(newActiveIndex, 0);\n            }\n            else {\n                indexToRemove = slidesIndexes;\n                if (s.slides[indexToRemove]) s.slides.eq(indexToRemove).remove();\n                if (indexToRemove < newActiveIndex) newActiveIndex--;\n                newActiveIndex = Math.max(newActiveIndex, 0);\n            }\n        \n            if (s.params.loop) {\n                s.createLoop();\n            }\n        \n            if (!(s.params.observer && s.support.observer)) {\n                s.update(true);\n            }\n            if (s.params.loop) {\n                s.slideTo(newActiveIndex + s.loopedSlides, 0, false);\n            }\n            else {\n                s.slideTo(newActiveIndex, 0, false);\n            }\n        \n        };\n        s.removeAllSlides = function () {\n            var slidesIndexes = [];\n            for (var i = 0; i < s.slides.length; i++) {\n                slidesIndexes.push(i);\n            }\n            s.removeSlide(slidesIndexes);\n        };\n        \n\n        /*=========================\n          Effects\n          ===========================*/\n        s.effects = {\n            fade: {\n                setTranslate: function () {\n                    for (var i = 0; i < s.slides.length; i++) {\n                        var slide = s.slides.eq(i);\n                        var offset = slide[0].swiperSlideOffset;\n                        var tx = -offset;\n                        if (!s.params.virtualTranslate) tx = tx - s.translate;\n                        var ty = 0;\n                        if (!s.isHorizontal()) {\n                            ty = tx;\n                            tx = 0;\n                        }\n                        var slideOpacity = s.params.fade.crossFade ?\n                                Math.max(1 - Math.abs(slide[0].progress), 0) :\n                                1 + Math.min(Math.max(slide[0].progress, -1), 0);\n                        slide\n                            .css({\n                                opacity: slideOpacity\n                            })\n                            .transform('translate3d(' + tx + 'px, ' + ty + 'px, 0px)');\n        \n                    }\n        \n                },\n                setTransition: function (duration) {\n                    s.slides.transition(duration);\n                    if (s.params.virtualTranslate && duration !== 0) {\n                        var eventTriggered = false;\n                        s.slides.transitionEnd(function () {\n                            if (eventTriggered) return;\n                            if (!s) return;\n                            eventTriggered = true;\n                            s.animating = false;\n                            var triggerEvents = ['webkitTransitionEnd', 'transitionend', 'oTransitionEnd', 'MSTransitionEnd', 'msTransitionEnd'];\n                            for (var i = 0; i < triggerEvents.length; i++) {\n                                s.wrapper.trigger(triggerEvents[i]);\n                            }\n                        });\n                    }\n                }\n            },\n            flip: {\n                setTranslate: function () {\n                    for (var i = 0; i < s.slides.length; i++) {\n                        var slide = s.slides.eq(i);\n                        var progress = slide[0].progress;\n                        if (s.params.flip.limitRotation) {\n                            progress = Math.max(Math.min(slide[0].progress, 1), -1);\n                        }\n                        var offset = slide[0].swiperSlideOffset;\n                        var rotate = -180 * progress,\n                            rotateY = rotate,\n                            rotateX = 0,\n                            tx = -offset,\n                            ty = 0;\n                        if (!s.isHorizontal()) {\n                            ty = tx;\n                            tx = 0;\n                            rotateX = -rotateY;\n                            rotateY = 0;\n                        }\n                        else if (s.rtl) {\n                            rotateY = -rotateY;\n                        }\n        \n                        slide[0].style.zIndex = -Math.abs(Math.round(progress)) + s.slides.length;\n        \n                        if (s.params.flip.slideShadows) {\n                            //Set shadows\n                            var shadowBefore = s.isHorizontal() ? slide.find('.swiper-slide-shadow-left') : slide.find('.swiper-slide-shadow-top');\n                            var shadowAfter = s.isHorizontal() ? slide.find('.swiper-slide-shadow-right') : slide.find('.swiper-slide-shadow-bottom');\n                            if (shadowBefore.length === 0) {\n                                shadowBefore = $('<div class=\"swiper-slide-shadow-' + (s.isHorizontal() ? 'left' : 'top') + '\"></div>');\n                                slide.append(shadowBefore);\n                            }\n                            if (shadowAfter.length === 0) {\n                                shadowAfter = $('<div class=\"swiper-slide-shadow-' + (s.isHorizontal() ? 'right' : 'bottom') + '\"></div>');\n                                slide.append(shadowAfter);\n                            }\n                            if (shadowBefore.length) shadowBefore[0].style.opacity = Math.max(-progress, 0);\n                            if (shadowAfter.length) shadowAfter[0].style.opacity = Math.max(progress, 0);\n                        }\n        \n                        slide\n                            .transform('translate3d(' + tx + 'px, ' + ty + 'px, 0px) rotateX(' + rotateX + 'deg) rotateY(' + rotateY + 'deg)');\n                    }\n                },\n                setTransition: function (duration) {\n                    s.slides.transition(duration).find('.swiper-slide-shadow-top, .swiper-slide-shadow-right, .swiper-slide-shadow-bottom, .swiper-slide-shadow-left').transition(duration);\n                    if (s.params.virtualTranslate && duration !== 0) {\n                        var eventTriggered = false;\n                        s.slides.eq(s.activeIndex).transitionEnd(function () {\n                            if (eventTriggered) return;\n                            if (!s) return;\n                            if (!$(this).hasClass(s.params.slideActiveClass)) return;\n                            eventTriggered = true;\n                            s.animating = false;\n                            var triggerEvents = ['webkitTransitionEnd', 'transitionend', 'oTransitionEnd', 'MSTransitionEnd', 'msTransitionEnd'];\n                            for (var i = 0; i < triggerEvents.length; i++) {\n                                s.wrapper.trigger(triggerEvents[i]);\n                            }\n                        });\n                    }\n                }\n            },\n            cube: {\n                setTranslate: function () {\n                    var wrapperRotate = 0, cubeShadow;\n                    if (s.params.cube.shadow) {\n                        if (s.isHorizontal()) {\n                            cubeShadow = s.wrapper.find('.swiper-cube-shadow');\n                            if (cubeShadow.length === 0) {\n                                cubeShadow = $('<div class=\"swiper-cube-shadow\"></div>');\n                                s.wrapper.append(cubeShadow);\n                            }\n                            cubeShadow.css({height: s.width + 'px'});\n                        }\n                        else {\n                            cubeShadow = s.container.find('.swiper-cube-shadow');\n                            if (cubeShadow.length === 0) {\n                                cubeShadow = $('<div class=\"swiper-cube-shadow\"></div>');\n                                s.container.append(cubeShadow);\n                            }\n                        }\n                    }\n                    for (var i = 0; i < s.slides.length; i++) {\n                        var slide = s.slides.eq(i);\n                        var slideAngle = i * 90;\n                        var round = Math.floor(slideAngle / 360);\n                        if (s.rtl) {\n                            slideAngle = -slideAngle;\n                            round = Math.floor(-slideAngle / 360);\n                        }\n                        var progress = Math.max(Math.min(slide[0].progress, 1), -1);\n                        var tx = 0, ty = 0, tz = 0;\n                        if (i % 4 === 0) {\n                            tx = - round * 4 * s.size;\n                            tz = 0;\n                        }\n                        else if ((i - 1) % 4 === 0) {\n                            tx = 0;\n                            tz = - round * 4 * s.size;\n                        }\n                        else if ((i - 2) % 4 === 0) {\n                            tx = s.size + round * 4 * s.size;\n                            tz = s.size;\n                        }\n                        else if ((i - 3) % 4 === 0) {\n                            tx = - s.size;\n                            tz = 3 * s.size + s.size * 4 * round;\n                        }\n                        if (s.rtl) {\n                            tx = -tx;\n                        }\n        \n                        if (!s.isHorizontal()) {\n                            ty = tx;\n                            tx = 0;\n                        }\n        \n                        var transform = 'rotateX(' + (s.isHorizontal() ? 0 : -slideAngle) + 'deg) rotateY(' + (s.isHorizontal() ? slideAngle : 0) + 'deg) translate3d(' + tx + 'px, ' + ty + 'px, ' + tz + 'px)';\n                        if (progress <= 1 && progress > -1) {\n                            wrapperRotate = i * 90 + progress * 90;\n                            if (s.rtl) wrapperRotate = -i * 90 - progress * 90;\n                        }\n                        slide.transform(transform);\n                        if (s.params.cube.slideShadows) {\n                            //Set shadows\n                            var shadowBefore = s.isHorizontal() ? slide.find('.swiper-slide-shadow-left') : slide.find('.swiper-slide-shadow-top');\n                            var shadowAfter = s.isHorizontal() ? slide.find('.swiper-slide-shadow-right') : slide.find('.swiper-slide-shadow-bottom');\n                            if (shadowBefore.length === 0) {\n                                shadowBefore = $('<div class=\"swiper-slide-shadow-' + (s.isHorizontal() ? 'left' : 'top') + '\"></div>');\n                                slide.append(shadowBefore);\n                            }\n                            if (shadowAfter.length === 0) {\n                                shadowAfter = $('<div class=\"swiper-slide-shadow-' + (s.isHorizontal() ? 'right' : 'bottom') + '\"></div>');\n                                slide.append(shadowAfter);\n                            }\n                            if (shadowBefore.length) shadowBefore[0].style.opacity = Math.max(-progress, 0);\n                            if (shadowAfter.length) shadowAfter[0].style.opacity = Math.max(progress, 0);\n                        }\n                    }\n                    s.wrapper.css({\n                        '-webkit-transform-origin': '50% 50% -' + (s.size / 2) + 'px',\n                        '-moz-transform-origin': '50% 50% -' + (s.size / 2) + 'px',\n                        '-ms-transform-origin': '50% 50% -' + (s.size / 2) + 'px',\n                        'transform-origin': '50% 50% -' + (s.size / 2) + 'px'\n                    });\n        \n                    if (s.params.cube.shadow) {\n                        if (s.isHorizontal()) {\n                            cubeShadow.transform('translate3d(0px, ' + (s.width / 2 + s.params.cube.shadowOffset) + 'px, ' + (-s.width / 2) + 'px) rotateX(90deg) rotateZ(0deg) scale(' + (s.params.cube.shadowScale) + ')');\n                        }\n                        else {\n                            var shadowAngle = Math.abs(wrapperRotate) - Math.floor(Math.abs(wrapperRotate) / 90) * 90;\n                            var multiplier = 1.5 - (Math.sin(shadowAngle * 2 * Math.PI / 360) / 2 + Math.cos(shadowAngle * 2 * Math.PI / 360) / 2);\n                            var scale1 = s.params.cube.shadowScale,\n                                scale2 = s.params.cube.shadowScale / multiplier,\n                                offset = s.params.cube.shadowOffset;\n                            cubeShadow.transform('scale3d(' + scale1 + ', 1, ' + scale2 + ') translate3d(0px, ' + (s.height / 2 + offset) + 'px, ' + (-s.height / 2 / scale2) + 'px) rotateX(-90deg)');\n                        }\n                    }\n                    var zFactor = (s.isSafari || s.isUiWebView) ? (-s.size / 2) : 0;\n                    s.wrapper.transform('translate3d(0px,0,' + zFactor + 'px) rotateX(' + (s.isHorizontal() ? 0 : wrapperRotate) + 'deg) rotateY(' + (s.isHorizontal() ? -wrapperRotate : 0) + 'deg)');\n                },\n                setTransition: function (duration) {\n                    s.slides.transition(duration).find('.swiper-slide-shadow-top, .swiper-slide-shadow-right, .swiper-slide-shadow-bottom, .swiper-slide-shadow-left').transition(duration);\n                    if (s.params.cube.shadow && !s.isHorizontal()) {\n                        s.container.find('.swiper-cube-shadow').transition(duration);\n                    }\n                }\n            },\n            coverflow: {\n                setTranslate: function () {\n                    var transform = s.translate;\n                    var center = s.isHorizontal() ? -transform + s.width / 2 : -transform + s.height / 2;\n                    var rotate = s.isHorizontal() ? s.params.coverflow.rotate: -s.params.coverflow.rotate;\n                    var translate = s.params.coverflow.depth;\n                    //Each slide offset from center\n                    for (var i = 0, length = s.slides.length; i < length; i++) {\n                        var slide = s.slides.eq(i);\n                        var slideSize = s.slidesSizesGrid[i];\n                        var slideOffset = slide[0].swiperSlideOffset;\n                        var offsetMultiplier = (center - slideOffset - slideSize / 2) / slideSize * s.params.coverflow.modifier;\n        \n                        var rotateY = s.isHorizontal() ? rotate * offsetMultiplier : 0;\n                        var rotateX = s.isHorizontal() ? 0 : rotate * offsetMultiplier;\n                        // var rotateZ = 0\n                        var translateZ = -translate * Math.abs(offsetMultiplier);\n        \n                        var translateY = s.isHorizontal() ? 0 : s.params.coverflow.stretch * (offsetMultiplier);\n                        var translateX = s.isHorizontal() ? s.params.coverflow.stretch * (offsetMultiplier) : 0;\n        \n                        //Fix for ultra small values\n                        if (Math.abs(translateX) < 0.001) translateX = 0;\n                        if (Math.abs(translateY) < 0.001) translateY = 0;\n                        if (Math.abs(translateZ) < 0.001) translateZ = 0;\n                        if (Math.abs(rotateY) < 0.001) rotateY = 0;\n                        if (Math.abs(rotateX) < 0.001) rotateX = 0;\n        \n                        var slideTransform = 'translate3d(' + translateX + 'px,' + translateY + 'px,' + translateZ + 'px)  rotateX(' + rotateX + 'deg) rotateY(' + rotateY + 'deg)';\n        \n                        slide.transform(slideTransform);\n                        slide[0].style.zIndex = -Math.abs(Math.round(offsetMultiplier)) + 1;\n                        if (s.params.coverflow.slideShadows) {\n                            //Set shadows\n                            var shadowBefore = s.isHorizontal() ? slide.find('.swiper-slide-shadow-left') : slide.find('.swiper-slide-shadow-top');\n                            var shadowAfter = s.isHorizontal() ? slide.find('.swiper-slide-shadow-right') : slide.find('.swiper-slide-shadow-bottom');\n                            if (shadowBefore.length === 0) {\n                                shadowBefore = $('<div class=\"swiper-slide-shadow-' + (s.isHorizontal() ? 'left' : 'top') + '\"></div>');\n                                slide.append(shadowBefore);\n                            }\n                            if (shadowAfter.length === 0) {\n                                shadowAfter = $('<div class=\"swiper-slide-shadow-' + (s.isHorizontal() ? 'right' : 'bottom') + '\"></div>');\n                                slide.append(shadowAfter);\n                            }\n                            if (shadowBefore.length) shadowBefore[0].style.opacity = offsetMultiplier > 0 ? offsetMultiplier : 0;\n                            if (shadowAfter.length) shadowAfter[0].style.opacity = (-offsetMultiplier) > 0 ? -offsetMultiplier : 0;\n                        }\n                    }\n        \n                    //Set correct perspective for IE10\n                    if (s.browser.ie) {\n                        var ws = s.wrapper[0].style;\n                        ws.perspectiveOrigin = center + 'px 50%';\n                    }\n                },\n                setTransition: function (duration) {\n                    s.slides.transition(duration).find('.swiper-slide-shadow-top, .swiper-slide-shadow-right, .swiper-slide-shadow-bottom, .swiper-slide-shadow-left').transition(duration);\n                }\n            }\n        };\n\n        /*=========================\n          Images Lazy Loading\n          ===========================*/\n        s.lazy = {\n            initialImageLoaded: false,\n            loadImageInSlide: function (index, loadInDuplicate) {\n                if (typeof index === 'undefined') return;\n                if (typeof loadInDuplicate === 'undefined') loadInDuplicate = true;\n                if (s.slides.length === 0) return;\n        \n                var slide = s.slides.eq(index);\n                var img = slide.find('.swiper-lazy:not(.swiper-lazy-loaded):not(.swiper-lazy-loading)');\n                if (slide.hasClass('swiper-lazy') && !slide.hasClass('swiper-lazy-loaded') && !slide.hasClass('swiper-lazy-loading')) {\n                    img = img.add(slide[0]);\n                }\n                if (img.length === 0) return;\n        \n                img.each(function () {\n                    var _img = $(this);\n                    _img.addClass('swiper-lazy-loading');\n                    var background = _img.attr('data-background');\n                    var src = _img.attr('data-src'),\n                        srcset = _img.attr('data-srcset');\n                    s.loadImage(_img[0], (src || background), srcset, false, function () {\n                        if (background) {\n                            _img.css('background-image', 'url(\"' + background + '\")');\n                            _img.removeAttr('data-background');\n                        }\n                        else {\n                            if (srcset) {\n                                _img.attr('srcset', srcset);\n                                _img.removeAttr('data-srcset');\n                            }\n                            if (src) {\n                                _img.attr('src', src);\n                                _img.removeAttr('data-src');\n                            }\n        \n                        }\n        \n                        _img.addClass('swiper-lazy-loaded').removeClass('swiper-lazy-loading');\n                        slide.find('.swiper-lazy-preloader, .preloader').remove();\n                        if (s.params.loop && loadInDuplicate) {\n                            var slideOriginalIndex = slide.attr('data-swiper-slide-index');\n                            if (slide.hasClass(s.params.slideDuplicateClass)) {\n                                var originalSlide = s.wrapper.children('[data-swiper-slide-index=\"' + slideOriginalIndex + '\"]:not(.' + s.params.slideDuplicateClass + ')');\n                                s.lazy.loadImageInSlide(originalSlide.index(), false);\n                            }\n                            else {\n                                var duplicatedSlide = s.wrapper.children('.' + s.params.slideDuplicateClass + '[data-swiper-slide-index=\"' + slideOriginalIndex + '\"]');\n                                s.lazy.loadImageInSlide(duplicatedSlide.index(), false);\n                            }\n                        }\n                        s.emit('onLazyImageReady', s, slide[0], _img[0]);\n                    });\n        \n                    s.emit('onLazyImageLoad', s, slide[0], _img[0]);\n                });\n        \n            },\n            load: function () {\n                var i;\n                if (s.params.watchSlidesVisibility) {\n                    s.wrapper.children('.' + s.params.slideVisibleClass).each(function () {\n                        s.lazy.loadImageInSlide($(this).index());\n                    });\n                }\n                else {\n                    if (s.params.slidesPerView > 1) {\n                        for (i = s.activeIndex; i < s.activeIndex + s.params.slidesPerView ; i++) {\n                            if (s.slides[i]) s.lazy.loadImageInSlide(i);\n                        }\n                    }\n                    else {\n                        s.lazy.loadImageInSlide(s.activeIndex);\n                    }\n                }\n                if (s.params.lazyLoadingInPrevNext) {\n                    if (s.params.slidesPerView > 1 || (s.params.lazyLoadingInPrevNextAmount && s.params.lazyLoadingInPrevNextAmount > 1)) {\n                        var amount = s.params.lazyLoadingInPrevNextAmount;\n                        var spv = s.params.slidesPerView;\n                        var maxIndex = Math.min(s.activeIndex + spv + Math.max(amount, spv), s.slides.length);\n                        var minIndex = Math.max(s.activeIndex - Math.max(spv, amount), 0);\n                        // Next Slides\n                        for (i = s.activeIndex + s.params.slidesPerView; i < maxIndex; i++) {\n                            if (s.slides[i]) s.lazy.loadImageInSlide(i);\n                        }\n                        // Prev Slides\n                        for (i = minIndex; i < s.activeIndex ; i++) {\n                            if (s.slides[i]) s.lazy.loadImageInSlide(i);\n                        }\n                    }\n                    else {\n                        var nextSlide = s.wrapper.children('.' + s.params.slideNextClass);\n                        if (nextSlide.length > 0) s.lazy.loadImageInSlide(nextSlide.index());\n        \n                        var prevSlide = s.wrapper.children('.' + s.params.slidePrevClass);\n                        if (prevSlide.length > 0) s.lazy.loadImageInSlide(prevSlide.index());\n                    }\n                }\n            },\n            onTransitionStart: function () {\n                if (s.params.lazyLoading) {\n                    if (s.params.lazyLoadingOnTransitionStart || (!s.params.lazyLoadingOnTransitionStart && !s.lazy.initialImageLoaded)) {\n                        s.lazy.load();\n                    }\n                }\n            },\n            onTransitionEnd: function () {\n                if (s.params.lazyLoading && !s.params.lazyLoadingOnTransitionStart) {\n                    s.lazy.load();\n                }\n            }\n        };\n        \n\n        /*=========================\n          Scrollbar\n          ===========================*/\n        s.scrollbar = {\n            isTouched: false,\n            setDragPosition: function (e) {\n                var sb = s.scrollbar;\n                var x = 0, y = 0;\n                var translate;\n                var pointerPosition = s.isHorizontal() ?\n                    ((e.type === 'touchstart' || e.type === 'touchmove') ? e.targetTouches[0].pageX : e.pageX || e.clientX) :\n                    ((e.type === 'touchstart' || e.type === 'touchmove') ? e.targetTouches[0].pageY : e.pageY || e.clientY) ;\n                var position = (pointerPosition) - sb.track.offset()[s.isHorizontal() ? 'left' : 'top'] - sb.dragSize / 2;\n                var positionMin = -s.minTranslate() * sb.moveDivider;\n                var positionMax = -s.maxTranslate() * sb.moveDivider;\n                if (position < positionMin) {\n                    position = positionMin;\n                }\n                else if (position > positionMax) {\n                    position = positionMax;\n                }\n                position = -position / sb.moveDivider;\n                s.updateProgress(position);\n                s.setWrapperTranslate(position, true);\n            },\n            dragStart: function (e) {\n                var sb = s.scrollbar;\n                sb.isTouched = true;\n                e.preventDefault();\n                e.stopPropagation();\n        \n                sb.setDragPosition(e);\n                clearTimeout(sb.dragTimeout);\n        \n                sb.track.transition(0);\n                if (s.params.scrollbarHide) {\n                    sb.track.css('opacity', 1);\n                }\n                s.wrapper.transition(100);\n                sb.drag.transition(100);\n                s.emit('onScrollbarDragStart', s);\n            },\n            dragMove: function (e) {\n                var sb = s.scrollbar;\n                if (!sb.isTouched) return;\n                if (e.preventDefault) e.preventDefault();\n                else e.returnValue = false;\n                sb.setDragPosition(e);\n                s.wrapper.transition(0);\n                sb.track.transition(0);\n                sb.drag.transition(0);\n                s.emit('onScrollbarDragMove', s);\n            },\n            dragEnd: function (e) {\n                var sb = s.scrollbar;\n                if (!sb.isTouched) return;\n                sb.isTouched = false;\n                if (s.params.scrollbarHide) {\n                    clearTimeout(sb.dragTimeout);\n                    sb.dragTimeout = setTimeout(function () {\n                        sb.track.css('opacity', 0);\n                        sb.track.transition(400);\n                    }, 1000);\n        \n                }\n                s.emit('onScrollbarDragEnd', s);\n                if (s.params.scrollbarSnapOnRelease) {\n                    s.slideReset();\n                }\n            },\n            enableDraggable: function () {\n                var sb = s.scrollbar;\n                var target = s.support.touch ? sb.track : document;\n                $(sb.track).on(s.touchEvents.start, sb.dragStart);\n                $(target).on(s.touchEvents.move, sb.dragMove);\n                $(target).on(s.touchEvents.end, sb.dragEnd);\n            },\n            disableDraggable: function () {\n                var sb = s.scrollbar;\n                var target = s.support.touch ? sb.track : document;\n                $(sb.track).off(s.touchEvents.start, sb.dragStart);\n                $(target).off(s.touchEvents.move, sb.dragMove);\n                $(target).off(s.touchEvents.end, sb.dragEnd);\n            },\n            set: function () {\n                if (!s.params.scrollbar) return;\n                var sb = s.scrollbar;\n                sb.track = $(s.params.scrollbar);\n                if (s.params.uniqueNavElements && typeof s.params.scrollbar === 'string' && sb.track.length > 1 && s.container.find(s.params.scrollbar).length === 1) {\n                    sb.track = s.container.find(s.params.scrollbar);\n                }\n                sb.drag = sb.track.find('.swiper-scrollbar-drag');\n                if (sb.drag.length === 0) {\n                    sb.drag = $('<div class=\"swiper-scrollbar-drag\"></div>');\n                    sb.track.append(sb.drag);\n                }\n                sb.drag[0].style.width = '';\n                sb.drag[0].style.height = '';\n                sb.trackSize = s.isHorizontal() ? sb.track[0].offsetWidth : sb.track[0].offsetHeight;\n        \n                sb.divider = s.size / s.virtualSize;\n                sb.moveDivider = sb.divider * (sb.trackSize / s.size);\n                sb.dragSize = sb.trackSize * sb.divider;\n        \n                if (s.isHorizontal()) {\n                    sb.drag[0].style.width = sb.dragSize + 'px';\n                }\n                else {\n                    sb.drag[0].style.height = sb.dragSize + 'px';\n                }\n        \n                if (sb.divider >= 1) {\n                    sb.track[0].style.display = 'none';\n                }\n                else {\n                    sb.track[0].style.display = '';\n                }\n                if (s.params.scrollbarHide) {\n                    sb.track[0].style.opacity = 0;\n                }\n            },\n            setTranslate: function () {\n                if (!s.params.scrollbar) return;\n                var diff;\n                var sb = s.scrollbar;\n                var translate = s.translate || 0;\n                var newPos;\n        \n                var newSize = sb.dragSize;\n                newPos = (sb.trackSize - sb.dragSize) * s.progress;\n                if (s.rtl && s.isHorizontal()) {\n                    newPos = -newPos;\n                    if (newPos > 0) {\n                        newSize = sb.dragSize - newPos;\n                        newPos = 0;\n                    }\n                    else if (-newPos + sb.dragSize > sb.trackSize) {\n                        newSize = sb.trackSize + newPos;\n                    }\n                }\n                else {\n                    if (newPos < 0) {\n                        newSize = sb.dragSize + newPos;\n                        newPos = 0;\n                    }\n                    else if (newPos + sb.dragSize > sb.trackSize) {\n                        newSize = sb.trackSize - newPos;\n                    }\n                }\n                if (s.isHorizontal()) {\n                    if (s.support.transforms3d) {\n                        sb.drag.transform('translate3d(' + (newPos) + 'px, 0, 0)');\n                    }\n                    else {\n                        sb.drag.transform('translateX(' + (newPos) + 'px)');\n                    }\n                    sb.drag[0].style.width = newSize + 'px';\n                }\n                else {\n                    if (s.support.transforms3d) {\n                        sb.drag.transform('translate3d(0px, ' + (newPos) + 'px, 0)');\n                    }\n                    else {\n                        sb.drag.transform('translateY(' + (newPos) + 'px)');\n                    }\n                    sb.drag[0].style.height = newSize + 'px';\n                }\n                if (s.params.scrollbarHide) {\n                    clearTimeout(sb.timeout);\n                    sb.track[0].style.opacity = 1;\n                    sb.timeout = setTimeout(function () {\n                        sb.track[0].style.opacity = 0;\n                        sb.track.transition(400);\n                    }, 1000);\n                }\n            },\n            setTransition: function (duration) {\n                if (!s.params.scrollbar) return;\n                s.scrollbar.drag.transition(duration);\n            }\n        };\n\n        /*=========================\n          Controller\n          ===========================*/\n        s.controller = {\n            LinearSpline: function (x, y) {\n                this.x = x;\n                this.y = y;\n                this.lastIndex = x.length - 1;\n                // Given an x value (x2), return the expected y2 value:\n                // (x1,y1) is the known point before given value,\n                // (x3,y3) is the known point after given value.\n                var i1, i3;\n                var l = this.x.length;\n        \n                this.interpolate = function (x2) {\n                    if (!x2) return 0;\n        \n                    // Get the indexes of x1 and x3 (the array indexes before and after given x2):\n                    i3 = binarySearch(this.x, x2);\n                    i1 = i3 - 1;\n        \n                    // We have our indexes i1 & i3, so we can calculate already:\n                    // y2 := ((x2−x1) × (y3−y1)) ÷ (x3−x1) + y1\n                    return ((x2 - this.x[i1]) * (this.y[i3] - this.y[i1])) / (this.x[i3] - this.x[i1]) + this.y[i1];\n                };\n        \n                var binarySearch = (function() {\n                    var maxIndex, minIndex, guess;\n                    return function(array, val) {\n                        minIndex = -1;\n                        maxIndex = array.length;\n                        while (maxIndex - minIndex > 1)\n                            if (array[guess = maxIndex + minIndex >> 1] <= val) {\n                                minIndex = guess;\n                            } else {\n                                maxIndex = guess;\n                            }\n                        return maxIndex;\n                    };\n                })();\n            },\n            //xxx: for now i will just save one spline function to to\n            getInterpolateFunction: function(c){\n                if(!s.controller.spline) s.controller.spline = s.params.loop ?\n                    new s.controller.LinearSpline(s.slidesGrid, c.slidesGrid) :\n                    new s.controller.LinearSpline(s.snapGrid, c.snapGrid);\n            },\n            setTranslate: function (translate, byController) {\n               var controlled = s.params.control;\n               var multiplier, controlledTranslate;\n               function setControlledTranslate(c) {\n                    // this will create an Interpolate function based on the snapGrids\n                    // x is the Grid of the scrolled scroller and y will be the controlled scroller\n                    // it makes sense to create this only once and recall it for the interpolation\n                    // the function does a lot of value caching for performance\n                    translate = c.rtl && c.params.direction === 'horizontal' ? -s.translate : s.translate;\n                    if (s.params.controlBy === 'slide') {\n                        s.controller.getInterpolateFunction(c);\n                        // i am not sure why the values have to be multiplicated this way, tried to invert the snapGrid\n                        // but it did not work out\n                        controlledTranslate = -s.controller.spline.interpolate(-translate);\n                    }\n        \n                    if(!controlledTranslate || s.params.controlBy === 'container'){\n                        multiplier = (c.maxTranslate() - c.minTranslate()) / (s.maxTranslate() - s.minTranslate());\n                        controlledTranslate = (translate - s.minTranslate()) * multiplier + c.minTranslate();\n                    }\n        \n                    if (s.params.controlInverse) {\n                        controlledTranslate = c.maxTranslate() - controlledTranslate;\n                    }\n                    c.updateProgress(controlledTranslate);\n                    c.setWrapperTranslate(controlledTranslate, false, s);\n                    c.updateActiveIndex();\n               }\n               if (s.isArray(controlled)) {\n                   for (var i = 0; i < controlled.length; i++) {\n                       if (controlled[i] !== byController && controlled[i] instanceof Swiper) {\n                           setControlledTranslate(controlled[i]);\n                       }\n                   }\n               }\n               else if (controlled instanceof Swiper && byController !== controlled) {\n        \n                   setControlledTranslate(controlled);\n               }\n            },\n            setTransition: function (duration, byController) {\n                var controlled = s.params.control;\n                var i;\n                function setControlledTransition(c) {\n                    c.setWrapperTransition(duration, s);\n                    if (duration !== 0) {\n                        c.onTransitionStart();\n                        c.wrapper.transitionEnd(function(){\n                            if (!controlled) return;\n                            if (c.params.loop && s.params.controlBy === 'slide') {\n                                c.fixLoop();\n                            }\n                            c.onTransitionEnd();\n        \n                        });\n                    }\n                }\n                if (s.isArray(controlled)) {\n                    for (i = 0; i < controlled.length; i++) {\n                        if (controlled[i] !== byController && controlled[i] instanceof Swiper) {\n                            setControlledTransition(controlled[i]);\n                        }\n                    }\n                }\n                else if (controlled instanceof Swiper && byController !== controlled) {\n                    setControlledTransition(controlled);\n                }\n            }\n        };\n\n        /*=========================\n          Hash Navigation\n          ===========================*/\n        s.hashnav = {\n            init: function () {\n                if (!s.params.hashnav) return;\n                s.hashnav.initialized = true;\n                var hash = document.location.hash.replace('#', '');\n                if (!hash) return;\n                var speed = 0;\n                for (var i = 0, length = s.slides.length; i < length; i++) {\n                    var slide = s.slides.eq(i);\n                    var slideHash = slide.attr('data-hash');\n                    if (slideHash === hash && !slide.hasClass(s.params.slideDuplicateClass)) {\n                        var index = slide.index();\n                        s.slideTo(index, speed, s.params.runCallbacksOnInit, true);\n                    }\n                }\n            },\n            setHash: function () {\n                if (!s.hashnav.initialized || !s.params.hashnav) return;\n                document.location.hash = s.slides.eq(s.activeIndex).attr('data-hash') || '';\n            }\n        };\n\n        /*=========================\n          Keyboard Control\n          ===========================*/\n        function handleKeyboard(e) {\n            if (e.originalEvent) e = e.originalEvent; //jquery fix\n            var kc = e.keyCode || e.charCode;\n            // Directions locks\n            if (!s.params.allowSwipeToNext && (s.isHorizontal() && kc === 39 || !s.isHorizontal() && kc === 40)) {\n                return false;\n            }\n            if (!s.params.allowSwipeToPrev && (s.isHorizontal() && kc === 37 || !s.isHorizontal() && kc === 38)) {\n                return false;\n            }\n            if (e.shiftKey || e.altKey || e.ctrlKey || e.metaKey) {\n                return;\n            }\n            if (document.activeElement && document.activeElement.nodeName && (document.activeElement.nodeName.toLowerCase() === 'input' || document.activeElement.nodeName.toLowerCase() === 'textarea')) {\n                return;\n            }\n            if (kc === 37 || kc === 39 || kc === 38 || kc === 40) {\n                var inView = false;\n                //Check that swiper should be inside of visible area of window\n                if (s.container.parents('.swiper-slide').length > 0 && s.container.parents('.swiper-slide-active').length === 0) {\n                    return;\n                }\n                var windowScroll = {\n                    left: window.pageXOffset,\n                    top: window.pageYOffset\n                };\n                var windowWidth = window.innerWidth;\n                var windowHeight = window.innerHeight;\n                var swiperOffset = s.container.offset();\n                if (s.rtl) swiperOffset.left = swiperOffset.left - s.container[0].scrollLeft;\n                var swiperCoord = [\n                    [swiperOffset.left, swiperOffset.top],\n                    [swiperOffset.left + s.width, swiperOffset.top],\n                    [swiperOffset.left, swiperOffset.top + s.height],\n                    [swiperOffset.left + s.width, swiperOffset.top + s.height]\n                ];\n                for (var i = 0; i < swiperCoord.length; i++) {\n                    var point = swiperCoord[i];\n                    if (\n                        point[0] >= windowScroll.left && point[0] <= windowScroll.left + windowWidth &&\n                        point[1] >= windowScroll.top && point[1] <= windowScroll.top + windowHeight\n                    ) {\n                        inView = true;\n                    }\n        \n                }\n                if (!inView) return;\n            }\n            if (s.isHorizontal()) {\n                if (kc === 37 || kc === 39) {\n                    if (e.preventDefault) e.preventDefault();\n                    else e.returnValue = false;\n                }\n                if ((kc === 39 && !s.rtl) || (kc === 37 && s.rtl)) s.slideNext();\n                if ((kc === 37 && !s.rtl) || (kc === 39 && s.rtl)) s.slidePrev();\n            }\n            else {\n                if (kc === 38 || kc === 40) {\n                    if (e.preventDefault) e.preventDefault();\n                    else e.returnValue = false;\n                }\n                if (kc === 40) s.slideNext();\n                if (kc === 38) s.slidePrev();\n            }\n        }\n        s.disableKeyboardControl = function () {\n            s.params.keyboardControl = false;\n            $(document).off('keydown', handleKeyboard);\n        };\n        s.enableKeyboardControl = function () {\n            s.params.keyboardControl = true;\n            $(document).on('keydown', handleKeyboard);\n        };\n        \n\n        /*=========================\n          Mousewheel Control\n          ===========================*/\n        s.mousewheel = {\n            event: false,\n            lastScrollTime: (new window.Date()).getTime()\n        };\n        if (s.params.mousewheelControl) {\n            try {\n                new window.WheelEvent('wheel');\n                s.mousewheel.event = 'wheel';\n            } catch (e) {\n                if (window.WheelEvent || (s.container[0] && 'wheel' in s.container[0])) {\n                    s.mousewheel.event = 'wheel';\n                }\n            }\n            if (!s.mousewheel.event && window.WheelEvent) {\n        \n            }\n            if (!s.mousewheel.event && document.onmousewheel !== undefined) {\n                s.mousewheel.event = 'mousewheel';\n            }\n            if (!s.mousewheel.event) {\n                s.mousewheel.event = 'DOMMouseScroll';\n            }\n        }\n        function handleMousewheel(e) {\n            if (e.originalEvent) e = e.originalEvent; //jquery fix\n            var we = s.mousewheel.event;\n            var delta = 0;\n            var rtlFactor = s.rtl ? -1 : 1;\n        \n            //WebKits\n            if (we === 'mousewheel') {\n                if (s.params.mousewheelForceToAxis) {\n                    if (s.isHorizontal()) {\n                        if (Math.abs(e.wheelDeltaX) > Math.abs(e.wheelDeltaY)) delta = e.wheelDeltaX * rtlFactor;\n                        else return;\n                    }\n                    else {\n                        if (Math.abs(e.wheelDeltaY) > Math.abs(e.wheelDeltaX)) delta = e.wheelDeltaY;\n                        else return;\n                    }\n                }\n                else {\n                    delta = Math.abs(e.wheelDeltaX) > Math.abs(e.wheelDeltaY) ? - e.wheelDeltaX * rtlFactor : - e.wheelDeltaY;\n                }\n            }\n            //Old FireFox\n            else if (we === 'DOMMouseScroll') delta = -e.detail;\n            //New FireFox\n            else if (we === 'wheel') {\n                if (s.params.mousewheelForceToAxis) {\n                    if (s.isHorizontal()) {\n                        if (Math.abs(e.deltaX) > Math.abs(e.deltaY)) delta = -e.deltaX * rtlFactor;\n                        else return;\n                    }\n                    else {\n                        if (Math.abs(e.deltaY) > Math.abs(e.deltaX)) delta = -e.deltaY;\n                        else return;\n                    }\n                }\n                else {\n                    delta = Math.abs(e.deltaX) > Math.abs(e.deltaY) ? - e.deltaX * rtlFactor : - e.deltaY;\n                }\n            }\n            if (delta === 0) return;\n        \n            if (s.params.mousewheelInvert) delta = -delta;\n        \n            if (!s.params.freeMode) {\n                if ((new window.Date()).getTime() - s.mousewheel.lastScrollTime > 60) {\n                    if (delta < 0) {\n                        if ((!s.isEnd || s.params.loop) && !s.animating) s.slideNext();\n                        else if (s.params.mousewheelReleaseOnEdges) return true;\n                    }\n                    else {\n                        if ((!s.isBeginning || s.params.loop) && !s.animating) s.slidePrev();\n                        else if (s.params.mousewheelReleaseOnEdges) return true;\n                    }\n                }\n                s.mousewheel.lastScrollTime = (new window.Date()).getTime();\n        \n            }\n            else {\n                //Freemode or scrollContainer:\n                var position = s.getWrapperTranslate() + delta * s.params.mousewheelSensitivity;\n                var wasBeginning = s.isBeginning,\n                    wasEnd = s.isEnd;\n        \n                if (position >= s.minTranslate()) position = s.minTranslate();\n                if (position <= s.maxTranslate()) position = s.maxTranslate();\n        \n                s.setWrapperTransition(0);\n                s.setWrapperTranslate(position);\n                s.updateProgress();\n                s.updateActiveIndex();\n        \n                if (!wasBeginning && s.isBeginning || !wasEnd && s.isEnd) {\n                    s.updateClasses();\n                }\n        \n                if (s.params.freeModeSticky) {\n                    clearTimeout(s.mousewheel.timeout);\n                    s.mousewheel.timeout = setTimeout(function () {\n                        s.slideReset();\n                    }, 300);\n                }\n                else {\n                    if (s.params.lazyLoading && s.lazy) {\n                        s.lazy.load();\n                    }\n                }\n        \n                // Return page scroll on edge positions\n                if (position === 0 || position === s.maxTranslate()) return;\n            }\n            if (s.params.autoplay) s.stopAutoplay();\n        \n            if (e.preventDefault) e.preventDefault();\n            else e.returnValue = false;\n            return false;\n        }\n        s.disableMousewheelControl = function () {\n            if (!s.mousewheel.event) return false;\n            s.container.off(s.mousewheel.event, handleMousewheel);\n            return true;\n        };\n        \n        s.enableMousewheelControl = function () {\n            if (!s.mousewheel.event) return false;\n            s.container.on(s.mousewheel.event, handleMousewheel);\n            return true;\n        };\n        \n\n        /*=========================\n          Parallax\n          ===========================*/\n        function setParallaxTransform(el, progress) {\n            el = $(el);\n            var p, pX, pY;\n            var rtlFactor = s.rtl ? -1 : 1;\n        \n            p = el.attr('data-swiper-parallax') || '0';\n            pX = el.attr('data-swiper-parallax-x');\n            pY = el.attr('data-swiper-parallax-y');\n            if (pX || pY) {\n                pX = pX || '0';\n                pY = pY || '0';\n            }\n            else {\n                if (s.isHorizontal()) {\n                    pX = p;\n                    pY = '0';\n                }\n                else {\n                    pY = p;\n                    pX = '0';\n                }\n            }\n        \n            if ((pX).indexOf('%') >= 0) {\n                pX = parseInt(pX, 10) * progress * rtlFactor + '%';\n            }\n            else {\n                pX = pX * progress * rtlFactor + 'px' ;\n            }\n            if ((pY).indexOf('%') >= 0) {\n                pY = parseInt(pY, 10) * progress + '%';\n            }\n            else {\n                pY = pY * progress + 'px' ;\n            }\n        \n            el.transform('translate3d(' + pX + ', ' + pY + ',0px)');\n        }\n        s.parallax = {\n            setTranslate: function () {\n                s.container.children('[data-swiper-parallax], [data-swiper-parallax-x], [data-swiper-parallax-y]').each(function(){\n                    setParallaxTransform(this, s.progress);\n        \n                });\n                s.slides.each(function () {\n                    var slide = $(this);\n                    slide.find('[data-swiper-parallax], [data-swiper-parallax-x], [data-swiper-parallax-y]').each(function () {\n                        var progress = Math.min(Math.max(slide[0].progress, -1), 1);\n                        setParallaxTransform(this, progress);\n                    });\n                });\n            },\n            setTransition: function (duration) {\n                if (typeof duration === 'undefined') duration = s.params.speed;\n                s.container.find('[data-swiper-parallax], [data-swiper-parallax-x], [data-swiper-parallax-y]').each(function(){\n                    var el = $(this);\n                    var parallaxDuration = parseInt(el.attr('data-swiper-parallax-duration'), 10) || duration;\n                    if (duration === 0) parallaxDuration = 0;\n                    el.transition(parallaxDuration);\n                });\n            }\n        };\n        \n\n        /*=========================\n          Plugins API. Collect all and init all plugins\n          ===========================*/\n        s._plugins = [];\n        for (var plugin in s.plugins) {\n            var p = s.plugins[plugin](s, s.params[plugin]);\n            if (p) s._plugins.push(p);\n        }\n        // Method to call all plugins event/method\n        s.callPlugins = function (eventName) {\n            for (var i = 0; i < s._plugins.length; i++) {\n                if (eventName in s._plugins[i]) {\n                    s._plugins[i][eventName](arguments[1], arguments[2], arguments[3], arguments[4], arguments[5]);\n                }\n            }\n        };\n\n        /*=========================\n          Events/Callbacks/Plugins Emitter\n          ===========================*/\n        function normalizeEventName (eventName) {\n            if (eventName.indexOf('on') !== 0) {\n                if (eventName[0] !== eventName[0].toUpperCase()) {\n                    eventName = 'on' + eventName[0].toUpperCase() + eventName.substring(1);\n                }\n                else {\n                    eventName = 'on' + eventName;\n                }\n            }\n            return eventName;\n        }\n        s.emitterEventListeners = {\n        \n        };\n        s.emit = function (eventName) {\n            // Trigger callbacks\n            if (s.params[eventName]) {\n                s.params[eventName](arguments[1], arguments[2], arguments[3], arguments[4], arguments[5]);\n            }\n            var i;\n            // Trigger events\n            if (s.emitterEventListeners[eventName]) {\n                for (i = 0; i < s.emitterEventListeners[eventName].length; i++) {\n                    s.emitterEventListeners[eventName][i](arguments[1], arguments[2], arguments[3], arguments[4], arguments[5]);\n                }\n            }\n            // Trigger plugins\n            if (s.callPlugins) s.callPlugins(eventName, arguments[1], arguments[2], arguments[3], arguments[4], arguments[5]);\n        };\n        s.on = function (eventName, handler) {\n            eventName = normalizeEventName(eventName);\n            if (!s.emitterEventListeners[eventName]) s.emitterEventListeners[eventName] = [];\n            s.emitterEventListeners[eventName].push(handler);\n            return s;\n        };\n        s.off = function (eventName, handler) {\n            var i;\n            eventName = normalizeEventName(eventName);\n            if (typeof handler === 'undefined') {\n                // Remove all handlers for such event\n                s.emitterEventListeners[eventName] = [];\n                return s;\n            }\n            if (!s.emitterEventListeners[eventName] || s.emitterEventListeners[eventName].length === 0) return;\n            for (i = 0; i < s.emitterEventListeners[eventName].length; i++) {\n                if(s.emitterEventListeners[eventName][i] === handler) s.emitterEventListeners[eventName].splice(i, 1);\n            }\n            return s;\n        };\n        s.once = function (eventName, handler) {\n            eventName = normalizeEventName(eventName);\n            var _handler = function () {\n                handler(arguments[0], arguments[1], arguments[2], arguments[3], arguments[4]);\n                s.off(eventName, _handler);\n            };\n            s.on(eventName, _handler);\n            return s;\n        };\n\n        // Accessibility tools\n        s.a11y = {\n            makeFocusable: function ($el) {\n                $el.attr('tabIndex', '0');\n                return $el;\n            },\n            addRole: function ($el, role) {\n                $el.attr('role', role);\n                return $el;\n            },\n        \n            addLabel: function ($el, label) {\n                $el.attr('aria-label', label);\n                return $el;\n            },\n        \n            disable: function ($el) {\n                $el.attr('aria-disabled', true);\n                return $el;\n            },\n        \n            enable: function ($el) {\n                $el.attr('aria-disabled', false);\n                return $el;\n            },\n        \n            onEnterKey: function (event) {\n                if (event.keyCode !== 13) return;\n                if ($(event.target).is(s.params.nextButton)) {\n                    s.onClickNext(event);\n                    if (s.isEnd) {\n                        s.a11y.notify(s.params.lastSlideMessage);\n                    }\n                    else {\n                        s.a11y.notify(s.params.nextSlideMessage);\n                    }\n                }\n                else if ($(event.target).is(s.params.prevButton)) {\n                    s.onClickPrev(event);\n                    if (s.isBeginning) {\n                        s.a11y.notify(s.params.firstSlideMessage);\n                    }\n                    else {\n                        s.a11y.notify(s.params.prevSlideMessage);\n                    }\n                }\n                if ($(event.target).is('.' + s.params.bulletClass)) {\n                    $(event.target)[0].click();\n                }\n            },\n        \n            liveRegion: $('<span class=\"swiper-notification\" aria-live=\"assertive\" aria-atomic=\"true\"></span>'),\n        \n            notify: function (message) {\n                var notification = s.a11y.liveRegion;\n                if (notification.length === 0) return;\n                notification.html('');\n                notification.html(message);\n            },\n            init: function () {\n                // Setup accessibility\n                if (s.params.nextButton && s.nextButton && s.nextButton.length > 0) {\n                    s.a11y.makeFocusable(s.nextButton);\n                    s.a11y.addRole(s.nextButton, 'button');\n                    s.a11y.addLabel(s.nextButton, s.params.nextSlideMessage);\n                }\n                if (s.params.prevButton && s.prevButton && s.prevButton.length > 0) {\n                    s.a11y.makeFocusable(s.prevButton);\n                    s.a11y.addRole(s.prevButton, 'button');\n                    s.a11y.addLabel(s.prevButton, s.params.prevSlideMessage);\n                }\n        \n                $(s.container).append(s.a11y.liveRegion);\n            },\n            initPagination: function () {\n                if (s.params.pagination && s.params.paginationClickable && s.bullets && s.bullets.length) {\n                    s.bullets.each(function () {\n                        var bullet = $(this);\n                        s.a11y.makeFocusable(bullet);\n                        s.a11y.addRole(bullet, 'button');\n                        s.a11y.addLabel(bullet, s.params.paginationBulletMessage.replace(/{{index}}/, bullet.index() + 1));\n                    });\n                }\n            },\n            destroy: function () {\n                if (s.a11y.liveRegion && s.a11y.liveRegion.length > 0) s.a11y.liveRegion.remove();\n            }\n        };\n        \n\n        /*=========================\n          Init/Destroy\n          ===========================*/\n        s.init = function () {\n            if (s.params.loop) s.createLoop();\n            s.updateContainerSize();\n            s.updateSlidesSize();\n            s.updatePagination();\n            if (s.params.scrollbar && s.scrollbar) {\n                s.scrollbar.set();\n                if (s.params.scrollbarDraggable) {\n                    s.scrollbar.enableDraggable();\n                }\n            }\n            if (s.params.effect !== 'slide' && s.effects[s.params.effect]) {\n                if (!s.params.loop) s.updateProgress();\n                s.effects[s.params.effect].setTranslate();\n            }\n            if (s.params.loop) {\n                s.slideTo(s.params.initialSlide + s.loopedSlides, 0, s.params.runCallbacksOnInit);\n            }\n            else {\n                s.slideTo(s.params.initialSlide, 0, s.params.runCallbacksOnInit);\n                if (s.params.initialSlide === 0) {\n                    if (s.parallax && s.params.parallax) s.parallax.setTranslate();\n                    if (s.lazy && s.params.lazyLoading) {\n                        s.lazy.load();\n                        s.lazy.initialImageLoaded = true;\n                    }\n                }\n            }\n            s.attachEvents();\n            if (s.params.observer && s.support.observer) {\n                s.initObservers();\n            }\n            if (s.params.preloadImages && !s.params.lazyLoading) {\n                s.preloadImages();\n            }\n            if (s.params.autoplay) {\n                s.startAutoplay();\n            }\n            if (s.params.keyboardControl) {\n                if (s.enableKeyboardControl) s.enableKeyboardControl();\n            }\n            if (s.params.mousewheelControl) {\n                if (s.enableMousewheelControl) s.enableMousewheelControl();\n            }\n            if (s.params.hashnav) {\n                if (s.hashnav) s.hashnav.init();\n            }\n            if (s.params.a11y && s.a11y) s.a11y.init();\n            s.emit('onInit', s);\n        };\n        \n        // Cleanup dynamic styles\n        s.cleanupStyles = function () {\n            // Container\n            s.container.removeClass(s.classNames.join(' ')).removeAttr('style');\n        \n            // Wrapper\n            s.wrapper.removeAttr('style');\n        \n            // Slides\n            if (s.slides && s.slides.length) {\n                s.slides\n                    .removeClass([\n                      s.params.slideVisibleClass,\n                      s.params.slideActiveClass,\n                      s.params.slideNextClass,\n                      s.params.slidePrevClass\n                    ].join(' '))\n                    .removeAttr('style')\n                    .removeAttr('data-swiper-column')\n                    .removeAttr('data-swiper-row');\n            }\n        \n            // Pagination/Bullets\n            if (s.paginationContainer && s.paginationContainer.length) {\n                s.paginationContainer.removeClass(s.params.paginationHiddenClass);\n            }\n            if (s.bullets && s.bullets.length) {\n                s.bullets.removeClass(s.params.bulletActiveClass);\n            }\n        \n            // Buttons\n            if (s.params.prevButton) $(s.params.prevButton).removeClass(s.params.buttonDisabledClass);\n            if (s.params.nextButton) $(s.params.nextButton).removeClass(s.params.buttonDisabledClass);\n        \n            // Scrollbar\n            if (s.params.scrollbar && s.scrollbar) {\n                if (s.scrollbar.track && s.scrollbar.track.length) s.scrollbar.track.removeAttr('style');\n                if (s.scrollbar.drag && s.scrollbar.drag.length) s.scrollbar.drag.removeAttr('style');\n            }\n        };\n        \n        // Destroy\n        s.destroy = function (deleteInstance, cleanupStyles) {\n            // Detach evebts\n            s.detachEvents();\n            // Stop autoplay\n            s.stopAutoplay();\n            // Disable draggable\n            if (s.params.scrollbar && s.scrollbar) {\n                if (s.params.scrollbarDraggable) {\n                    s.scrollbar.disableDraggable();\n                }\n            }\n            // Destroy loop\n            if (s.params.loop) {\n                s.destroyLoop();\n            }\n            // Cleanup styles\n            if (cleanupStyles) {\n                s.cleanupStyles();\n            }\n            // Disconnect observer\n            s.disconnectObservers();\n            // Disable keyboard/mousewheel\n            if (s.params.keyboardControl) {\n                if (s.disableKeyboardControl) s.disableKeyboardControl();\n            }\n            if (s.params.mousewheelControl) {\n                if (s.disableMousewheelControl) s.disableMousewheelControl();\n            }\n            // Disable a11y\n            if (s.params.a11y && s.a11y) s.a11y.destroy();\n            // Destroy callback\n            s.emit('onDestroy');\n            // Delete instance\n            if (deleteInstance !== false) s = null;\n        };\n        \n        s.init();\n        \n\n    \n        // Return swiper instance\n        return s;\n    };\n    \n\n    /*==================================================\n        Prototype\n    ====================================================*/\n    Swiper.prototype = {\n        isSafari: (function () {\n            var ua = navigator.userAgent.toLowerCase();\n            return (ua.indexOf('safari') >= 0 && ua.indexOf('chrome') < 0 && ua.indexOf('android') < 0);\n        })(),\n        isUiWebView: /(iPhone|iPod|iPad).*AppleWebKit(?!.*Safari)/i.test(navigator.userAgent),\n        isArray: function (arr) {\n            return Object.prototype.toString.apply(arr) === '[object Array]';\n        },\n        /*==================================================\n        Browser\n        ====================================================*/\n        browser: {\n            ie: window.navigator.pointerEnabled || window.navigator.msPointerEnabled,\n            ieTouch: (window.navigator.msPointerEnabled && window.navigator.msMaxTouchPoints > 1) || (window.navigator.pointerEnabled && window.navigator.maxTouchPoints > 1)\n        },\n        /*==================================================\n        Devices\n        ====================================================*/\n        device: (function () {\n            var ua = navigator.userAgent;\n            var android = ua.match(/(Android);?[\\s\\/]+([\\d.]+)?/);\n            var ipad = ua.match(/(iPad).*OS\\s([\\d_]+)/);\n            var ipod = ua.match(/(iPod)(.*OS\\s([\\d_]+))?/);\n            var iphone = !ipad && ua.match(/(iPhone\\sOS)\\s([\\d_]+)/);\n            return {\n                ios: ipad || iphone || ipod,\n                android: android\n            };\n        })(),\n        /*==================================================\n        Feature Detection\n        ====================================================*/\n        support: {\n            touch : (window.Modernizr && Modernizr.touch === true) || (function () {\n                return !!(('ontouchstart' in window) || window.DocumentTouch && document instanceof DocumentTouch);\n            })(),\n    \n            transforms3d : (window.Modernizr && Modernizr.csstransforms3d === true) || (function () {\n                var div = document.createElement('div').style;\n                return ('webkitPerspective' in div || 'MozPerspective' in div || 'OPerspective' in div || 'MsPerspective' in div || 'perspective' in div);\n            })(),\n    \n            flexbox: (function () {\n                var div = document.createElement('div').style;\n                var styles = ('alignItems webkitAlignItems webkitBoxAlign msFlexAlign mozBoxAlign webkitFlexDirection msFlexDirection mozBoxDirection mozBoxOrient webkitBoxDirection webkitBoxOrient').split(' ');\n                for (var i = 0; i < styles.length; i++) {\n                    if (styles[i] in div) return true;\n                }\n            })(),\n    \n            observer: (function () {\n                return ('MutationObserver' in window || 'WebkitMutationObserver' in window);\n            })()\n        },\n        /*==================================================\n        Plugins\n        ====================================================*/\n        plugins: {}\n    };\n    \n\n    /*===========================\n     Get jQuery\n     ===========================*/\n    \n    addLibraryPlugin($);\n    \n    var domLib = $;\n\n    /*===========================\n    Add .swiper plugin from Dom libraries\n    ===========================*/\n    function addLibraryPlugin(lib) {\n        lib.fn.swiper = function (params) {\n            var firstInstance;\n            lib(this).each(function () {\n                var s = new Swiper(this, params);\n                if (!firstInstance) firstInstance = s;\n            });\n            return firstInstance;\n        };\n    }\n    \n    if (domLib) {\n        if (!('transitionEnd' in domLib.fn)) {\n            domLib.fn.transitionEnd = function (callback) {\n                var events = ['webkitTransitionEnd', 'transitionend', 'oTransitionEnd', 'MSTransitionEnd', 'msTransitionEnd'],\n                    i, j, dom = this;\n                function fireCallBack(e) {\n                    /*jshint validthis:true */\n                    if (e.target !== this) return;\n                    callback.call(this, e);\n                    for (i = 0; i < events.length; i++) {\n                        dom.off(events[i], fireCallBack);\n                    }\n                }\n                if (callback) {\n                    for (i = 0; i < events.length; i++) {\n                        dom.on(events[i], fireCallBack);\n                    }\n                }\n                return this;\n            };\n        }\n        if (!('transform' in domLib.fn)) {\n            domLib.fn.transform = function (transform) {\n                for (var i = 0; i < this.length; i++) {\n                    var elStyle = this[i].style;\n                    elStyle.webkitTransform = elStyle.MsTransform = elStyle.msTransform = elStyle.MozTransform = elStyle.OTransform = elStyle.transform = transform;\n                }\n                return this;\n            };\n        }\n        if (!('transition' in domLib.fn)) {\n            domLib.fn.transition = function (duration) {\n                if (typeof duration !== 'string') {\n                    duration = duration + 'ms';\n                }\n                for (var i = 0; i < this.length; i++) {\n                    var elStyle = this[i].style;\n                    elStyle.webkitTransitionDuration = elStyle.MsTransitionDuration = elStyle.msTransitionDuration = elStyle.MozTransitionDuration = elStyle.OTransitionDuration = elStyle.transitionDuration = duration;\n                }\n                return this;\n            };\n        }\n    }\n\n\treturn Swiper;\n}));\n//# sourceMappingURL=maps/swiper.jquery.umd.js.map\n"
  },
  {
    "path": "app_frontend/static/plugin/Swiper-3.3.1/dist/js/swiper.js",
    "content": "/**\n * Swiper 3.3.1\n * Most modern mobile touch slider and framework with hardware accelerated transitions\n * \n * http://www.idangero.us/swiper/\n * \n * Copyright 2016, Vladimir Kharlampidi\n * The iDangero.us\n * http://www.idangero.us/\n * \n * Licensed under MIT\n * \n * Released on: February 7, 2016\n */\n(function () {\n    'use strict';\n    var $;\n    /*===========================\n    Swiper\n    ===========================*/\n    var Swiper = function (container, params) {\n        if (!(this instanceof Swiper)) return new Swiper(container, params);\n\n        var defaults = {\n            direction: 'horizontal',\n            touchEventsTarget: 'container',\n            initialSlide: 0,\n            speed: 300,\n            // autoplay\n            autoplay: false,\n            autoplayDisableOnInteraction: true,\n            autoplayStopOnLast: false,\n            // To support iOS's swipe-to-go-back gesture (when being used in-app, with UIWebView).\n            iOSEdgeSwipeDetection: false,\n            iOSEdgeSwipeThreshold: 20,\n            // Free mode\n            freeMode: false,\n            freeModeMomentum: true,\n            freeModeMomentumRatio: 1,\n            freeModeMomentumBounce: true,\n            freeModeMomentumBounceRatio: 1,\n            freeModeSticky: false,\n            freeModeMinimumVelocity: 0.02,\n            // Autoheight\n            autoHeight: false,\n            // Set wrapper width\n            setWrapperSize: false,\n            // Virtual Translate\n            virtualTranslate: false,\n            // Effects\n            effect: 'slide', // 'slide' or 'fade' or 'cube' or 'coverflow' or 'flip'\n            coverflow: {\n                rotate: 50,\n                stretch: 0,\n                depth: 100,\n                modifier: 1,\n                slideShadows : true\n            },\n            flip: {\n                slideShadows : true,\n                limitRotation: true\n            },\n            cube: {\n                slideShadows: true,\n                shadow: true,\n                shadowOffset: 20,\n                shadowScale: 0.94\n            },\n            fade: {\n                crossFade: false\n            },\n            // Parallax\n            parallax: false,\n            // Scrollbar\n            scrollbar: null,\n            scrollbarHide: true,\n            scrollbarDraggable: false,\n            scrollbarSnapOnRelease: false,\n            // Keyboard Mousewheel\n            keyboardControl: false,\n            mousewheelControl: false,\n            mousewheelReleaseOnEdges: false,\n            mousewheelInvert: false,\n            mousewheelForceToAxis: false,\n            mousewheelSensitivity: 1,\n            // Hash Navigation\n            hashnav: false,\n            // Breakpoints\n            breakpoints: undefined,\n            // Slides grid\n            spaceBetween: 0,\n            slidesPerView: 1,\n            slidesPerColumn: 1,\n            slidesPerColumnFill: 'column',\n            slidesPerGroup: 1,\n            centeredSlides: false,\n            slidesOffsetBefore: 0, // in px\n            slidesOffsetAfter: 0, // in px\n            // Round length\n            roundLengths: false,\n            // Touches\n            touchRatio: 1,\n            touchAngle: 45,\n            simulateTouch: true,\n            shortSwipes: true,\n            longSwipes: true,\n            longSwipesRatio: 0.5,\n            longSwipesMs: 300,\n            followFinger: true,\n            onlyExternal: false,\n            threshold: 0,\n            touchMoveStopPropagation: true,\n            // Unique Navigation Elements\n            uniqueNavElements: true,\n            // Pagination\n            pagination: null,\n            paginationElement: 'span',\n            paginationClickable: false,\n            paginationHide: false,\n            paginationBulletRender: null,\n            paginationProgressRender: null,\n            paginationFractionRender: null,\n            paginationCustomRender: null,\n            paginationType: 'bullets', // 'bullets' or 'progress' or 'fraction' or 'custom'\n            // Resistance\n            resistance: true,\n            resistanceRatio: 0.85,\n            // Next/prev buttons\n            nextButton: null,\n            prevButton: null,\n            // Progress\n            watchSlidesProgress: false,\n            watchSlidesVisibility: false,\n            // Cursor\n            grabCursor: false,\n            // Clicks\n            preventClicks: true,\n            preventClicksPropagation: true,\n            slideToClickedSlide: false,\n            // Lazy Loading\n            lazyLoading: false,\n            lazyLoadingInPrevNext: false,\n            lazyLoadingInPrevNextAmount: 1,\n            lazyLoadingOnTransitionStart: false,\n            // Images\n            preloadImages: true,\n            updateOnImagesReady: true,\n            // loop\n            loop: false,\n            loopAdditionalSlides: 0,\n            loopedSlides: null,\n            // Control\n            control: undefined,\n            controlInverse: false,\n            controlBy: 'slide', //or 'container'\n            // Swiping/no swiping\n            allowSwipeToPrev: true,\n            allowSwipeToNext: true,\n            swipeHandler: null, //'.swipe-handler',\n            noSwiping: true,\n            noSwipingClass: 'swiper-no-swiping',\n            // NS\n            slideClass: 'swiper-slide',\n            slideActiveClass: 'swiper-slide-active',\n            slideVisibleClass: 'swiper-slide-visible',\n            slideDuplicateClass: 'swiper-slide-duplicate',\n            slideNextClass: 'swiper-slide-next',\n            slidePrevClass: 'swiper-slide-prev',\n            wrapperClass: 'swiper-wrapper',\n            bulletClass: 'swiper-pagination-bullet',\n            bulletActiveClass: 'swiper-pagination-bullet-active',\n            buttonDisabledClass: 'swiper-button-disabled',\n            paginationCurrentClass: 'swiper-pagination-current',\n            paginationTotalClass: 'swiper-pagination-total',\n            paginationHiddenClass: 'swiper-pagination-hidden',\n            paginationProgressbarClass: 'swiper-pagination-progressbar',\n            // Observer\n            observer: false,\n            observeParents: false,\n            // Accessibility\n            a11y: false,\n            prevSlideMessage: 'Previous slide',\n            nextSlideMessage: 'Next slide',\n            firstSlideMessage: 'This is the first slide',\n            lastSlideMessage: 'This is the last slide',\n            paginationBulletMessage: 'Go to slide {{index}}',\n            // Callbacks\n            runCallbacksOnInit: true\n            /*\n            Callbacks:\n            onInit: function (swiper)\n            onDestroy: function (swiper)\n            onClick: function (swiper, e)\n            onTap: function (swiper, e)\n            onDoubleTap: function (swiper, e)\n            onSliderMove: function (swiper, e)\n            onSlideChangeStart: function (swiper)\n            onSlideChangeEnd: function (swiper)\n            onTransitionStart: function (swiper)\n            onTransitionEnd: function (swiper)\n            onImagesReady: function (swiper)\n            onProgress: function (swiper, progress)\n            onTouchStart: function (swiper, e)\n            onTouchMove: function (swiper, e)\n            onTouchMoveOpposite: function (swiper, e)\n            onTouchEnd: function (swiper, e)\n            onReachBeginning: function (swiper)\n            onReachEnd: function (swiper)\n            onSetTransition: function (swiper, duration)\n            onSetTranslate: function (swiper, translate)\n            onAutoplayStart: function (swiper)\n            onAutoplayStop: function (swiper),\n            onLazyImageLoad: function (swiper, slide, image)\n            onLazyImageReady: function (swiper, slide, image)\n            */\n        \n        };\n        var initialVirtualTranslate = params && params.virtualTranslate;\n        \n        params = params || {};\n        var originalParams = {};\n        for (var param in params) {\n            if (typeof params[param] === 'object' && params[param] !== null && !(params[param].nodeType || params[param] === window || params[param] === document || (typeof Dom7 !== 'undefined' && params[param] instanceof Dom7) || (typeof jQuery !== 'undefined' && params[param] instanceof jQuery))) {\n                originalParams[param] = {};\n                for (var deepParam in params[param]) {\n                    originalParams[param][deepParam] = params[param][deepParam];\n                }\n            }\n            else {\n                originalParams[param] = params[param];\n            }\n        }\n        for (var def in defaults) {\n            if (typeof params[def] === 'undefined') {\n                params[def] = defaults[def];\n            }\n            else if (typeof params[def] === 'object') {\n                for (var deepDef in defaults[def]) {\n                    if (typeof params[def][deepDef] === 'undefined') {\n                        params[def][deepDef] = defaults[def][deepDef];\n                    }\n                }\n            }\n        }\n        \n        // Swiper\n        var s = this;\n        \n        // Params\n        s.params = params;\n        s.originalParams = originalParams;\n        \n        // Classname\n        s.classNames = [];\n        /*=========================\n          Dom Library and plugins\n          ===========================*/\n        if (typeof $ !== 'undefined' && typeof Dom7 !== 'undefined'){\n            $ = Dom7;\n        }\n        if (typeof $ === 'undefined') {\n            if (typeof Dom7 === 'undefined') {\n                $ = window.Dom7 || window.Zepto || window.jQuery;\n            }\n            else {\n                $ = Dom7;\n            }\n            if (!$) return;\n        }\n        // Export it to Swiper instance\n        s.$ = $;\n        \n        /*=========================\n          Breakpoints\n          ===========================*/\n        s.currentBreakpoint = undefined;\n        s.getActiveBreakpoint = function () {\n            //Get breakpoint for window width\n            if (!s.params.breakpoints) return false;\n            var breakpoint = false;\n            var points = [], point;\n            for ( point in s.params.breakpoints ) {\n                if (s.params.breakpoints.hasOwnProperty(point)) {\n                    points.push(point);\n                }\n            }\n            points.sort(function (a, b) {\n                return parseInt(a, 10) > parseInt(b, 10);\n            });\n            for (var i = 0; i < points.length; i++) {\n                point = points[i];\n                if (point >= window.innerWidth && !breakpoint) {\n                    breakpoint = point;\n                }\n            }\n            return breakpoint || 'max';\n        };\n        s.setBreakpoint = function () {\n            //Set breakpoint for window width and update parameters\n            var breakpoint = s.getActiveBreakpoint();\n            if (breakpoint && s.currentBreakpoint !== breakpoint) {\n                var breakPointsParams = breakpoint in s.params.breakpoints ? s.params.breakpoints[breakpoint] : s.originalParams;\n                var needsReLoop = s.params.loop && (breakPointsParams.slidesPerView !== s.params.slidesPerView);\n                for ( var param in breakPointsParams ) {\n                    s.params[param] = breakPointsParams[param];\n                }\n                s.currentBreakpoint = breakpoint;\n                if(needsReLoop && s.destroyLoop) {\n                    s.reLoop(true);\n                }\n            }\n        };\n        // Set breakpoint on load\n        if (s.params.breakpoints) {\n            s.setBreakpoint();\n        }\n        \n        /*=========================\n          Preparation - Define Container, Wrapper and Pagination\n          ===========================*/\n        s.container = $(container);\n        if (s.container.length === 0) return;\n        if (s.container.length > 1) {\n            var swipers = [];\n            s.container.each(function () {\n                var container = this;\n                swipers.push(new Swiper(this, params));\n            });\n            return swipers;\n        }\n        \n        // Save instance in container HTML Element and in data\n        s.container[0].swiper = s;\n        s.container.data('swiper', s);\n        \n        s.classNames.push('swiper-container-' + s.params.direction);\n        \n        if (s.params.freeMode) {\n            s.classNames.push('swiper-container-free-mode');\n        }\n        if (!s.support.flexbox) {\n            s.classNames.push('swiper-container-no-flexbox');\n            s.params.slidesPerColumn = 1;\n        }\n        if (s.params.autoHeight) {\n            s.classNames.push('swiper-container-autoheight');\n        }\n        // Enable slides progress when required\n        if (s.params.parallax || s.params.watchSlidesVisibility) {\n            s.params.watchSlidesProgress = true;\n        }\n        // Coverflow / 3D\n        if (['cube', 'coverflow', 'flip'].indexOf(s.params.effect) >= 0) {\n            if (s.support.transforms3d) {\n                s.params.watchSlidesProgress = true;\n                s.classNames.push('swiper-container-3d');\n            }\n            else {\n                s.params.effect = 'slide';\n            }\n        }\n        if (s.params.effect !== 'slide') {\n            s.classNames.push('swiper-container-' + s.params.effect);\n        }\n        if (s.params.effect === 'cube') {\n            s.params.resistanceRatio = 0;\n            s.params.slidesPerView = 1;\n            s.params.slidesPerColumn = 1;\n            s.params.slidesPerGroup = 1;\n            s.params.centeredSlides = false;\n            s.params.spaceBetween = 0;\n            s.params.virtualTranslate = true;\n            s.params.setWrapperSize = false;\n        }\n        if (s.params.effect === 'fade' || s.params.effect === 'flip') {\n            s.params.slidesPerView = 1;\n            s.params.slidesPerColumn = 1;\n            s.params.slidesPerGroup = 1;\n            s.params.watchSlidesProgress = true;\n            s.params.spaceBetween = 0;\n            s.params.setWrapperSize = false;\n            if (typeof initialVirtualTranslate === 'undefined') {\n                s.params.virtualTranslate = true;\n            }\n        }\n        \n        // Grab Cursor\n        if (s.params.grabCursor && s.support.touch) {\n            s.params.grabCursor = false;\n        }\n        \n        // Wrapper\n        s.wrapper = s.container.children('.' + s.params.wrapperClass);\n        \n        // Pagination\n        if (s.params.pagination) {\n            s.paginationContainer = $(s.params.pagination);\n            if (s.params.uniqueNavElements && typeof s.params.pagination === 'string' && s.paginationContainer.length > 1 && s.container.find(s.params.pagination).length === 1) {\n                s.paginationContainer = s.container.find(s.params.pagination);\n            }\n        \n            if (s.params.paginationType === 'bullets' && s.params.paginationClickable) {\n                s.paginationContainer.addClass('swiper-pagination-clickable');\n            }\n            else {\n                s.params.paginationClickable = false;\n            }\n            s.paginationContainer.addClass('swiper-pagination-' + s.params.paginationType);\n        }\n        // Next/Prev Buttons\n        if (s.params.nextButton || s.params.prevButton) {\n            if (s.params.nextButton) {\n                s.nextButton = $(s.params.nextButton);\n                if (s.params.uniqueNavElements && typeof s.params.nextButton === 'string' && s.nextButton.length > 1 && s.container.find(s.params.nextButton).length === 1) {\n                    s.nextButton = s.container.find(s.params.nextButton);\n                }\n            }\n            if (s.params.prevButton) {\n                s.prevButton = $(s.params.prevButton);\n                if (s.params.uniqueNavElements && typeof s.params.prevButton === 'string' && s.prevButton.length > 1 && s.container.find(s.params.prevButton).length === 1) {\n                    s.prevButton = s.container.find(s.params.prevButton);\n                }\n            }\n        }\n        \n        // Is Horizontal\n        s.isHorizontal = function () {\n            return s.params.direction === 'horizontal';\n        };\n        // s.isH = isH;\n        \n        // RTL\n        s.rtl = s.isHorizontal() && (s.container[0].dir.toLowerCase() === 'rtl' || s.container.css('direction') === 'rtl');\n        if (s.rtl) {\n            s.classNames.push('swiper-container-rtl');\n        }\n        \n        // Wrong RTL support\n        if (s.rtl) {\n            s.wrongRTL = s.wrapper.css('display') === '-webkit-box';\n        }\n        \n        // Columns\n        if (s.params.slidesPerColumn > 1) {\n            s.classNames.push('swiper-container-multirow');\n        }\n        \n        // Check for Android\n        if (s.device.android) {\n            s.classNames.push('swiper-container-android');\n        }\n        \n        // Add classes\n        s.container.addClass(s.classNames.join(' '));\n        \n        // Translate\n        s.translate = 0;\n        \n        // Progress\n        s.progress = 0;\n        \n        // Velocity\n        s.velocity = 0;\n        \n        /*=========================\n          Locks, unlocks\n          ===========================*/\n        s.lockSwipeToNext = function () {\n            s.params.allowSwipeToNext = false;\n        };\n        s.lockSwipeToPrev = function () {\n            s.params.allowSwipeToPrev = false;\n        };\n        s.lockSwipes = function () {\n            s.params.allowSwipeToNext = s.params.allowSwipeToPrev = false;\n        };\n        s.unlockSwipeToNext = function () {\n            s.params.allowSwipeToNext = true;\n        };\n        s.unlockSwipeToPrev = function () {\n            s.params.allowSwipeToPrev = true;\n        };\n        s.unlockSwipes = function () {\n            s.params.allowSwipeToNext = s.params.allowSwipeToPrev = true;\n        };\n        \n        /*=========================\n          Round helper\n          ===========================*/\n        function round(a) {\n            return Math.floor(a);\n        }\n        /*=========================\n          Set grab cursor\n          ===========================*/\n        if (s.params.grabCursor) {\n            s.container[0].style.cursor = 'move';\n            s.container[0].style.cursor = '-webkit-grab';\n            s.container[0].style.cursor = '-moz-grab';\n            s.container[0].style.cursor = 'grab';\n        }\n        /*=========================\n          Update on Images Ready\n          ===========================*/\n        s.imagesToLoad = [];\n        s.imagesLoaded = 0;\n        \n        s.loadImage = function (imgElement, src, srcset, checkForComplete, callback) {\n            var image;\n            function onReady () {\n                if (callback) callback();\n            }\n            if (!imgElement.complete || !checkForComplete) {\n                if (src) {\n                    image = new window.Image();\n                    image.onload = onReady;\n                    image.onerror = onReady;\n                    if (srcset) {\n                        image.srcset = srcset;\n                    }\n                    if (src) {\n                        image.src = src;\n                    }\n                } else {\n                    onReady();\n                }\n        \n            } else {//image already loaded...\n                onReady();\n            }\n        };\n        s.preloadImages = function () {\n            s.imagesToLoad = s.container.find('img');\n            function _onReady() {\n                if (typeof s === 'undefined' || s === null) return;\n                if (s.imagesLoaded !== undefined) s.imagesLoaded++;\n                if (s.imagesLoaded === s.imagesToLoad.length) {\n                    if (s.params.updateOnImagesReady) s.update();\n                    s.emit('onImagesReady', s);\n                }\n            }\n            for (var i = 0; i < s.imagesToLoad.length; i++) {\n                s.loadImage(s.imagesToLoad[i], (s.imagesToLoad[i].currentSrc || s.imagesToLoad[i].getAttribute('src')), (s.imagesToLoad[i].srcset || s.imagesToLoad[i].getAttribute('srcset')), true, _onReady);\n            }\n        };\n        \n        /*=========================\n          Autoplay\n          ===========================*/\n        s.autoplayTimeoutId = undefined;\n        s.autoplaying = false;\n        s.autoplayPaused = false;\n        function autoplay() {\n            s.autoplayTimeoutId = setTimeout(function () {\n                if (s.params.loop) {\n                    s.fixLoop();\n                    s._slideNext();\n                    s.emit('onAutoplay', s);\n                }\n                else {\n                    if (!s.isEnd) {\n                        s._slideNext();\n                        s.emit('onAutoplay', s);\n                    }\n                    else {\n                        if (!params.autoplayStopOnLast) {\n                            s._slideTo(0);\n                            s.emit('onAutoplay', s);\n                        }\n                        else {\n                            s.stopAutoplay();\n                        }\n                    }\n                }\n            }, s.params.autoplay);\n        }\n        s.startAutoplay = function () {\n            if (typeof s.autoplayTimeoutId !== 'undefined') return false;\n            if (!s.params.autoplay) return false;\n            if (s.autoplaying) return false;\n            s.autoplaying = true;\n            s.emit('onAutoplayStart', s);\n            autoplay();\n        };\n        s.stopAutoplay = function (internal) {\n            if (!s.autoplayTimeoutId) return;\n            if (s.autoplayTimeoutId) clearTimeout(s.autoplayTimeoutId);\n            s.autoplaying = false;\n            s.autoplayTimeoutId = undefined;\n            s.emit('onAutoplayStop', s);\n        };\n        s.pauseAutoplay = function (speed) {\n            if (s.autoplayPaused) return;\n            if (s.autoplayTimeoutId) clearTimeout(s.autoplayTimeoutId);\n            s.autoplayPaused = true;\n            if (speed === 0) {\n                s.autoplayPaused = false;\n                autoplay();\n            }\n            else {\n                s.wrapper.transitionEnd(function () {\n                    if (!s) return;\n                    s.autoplayPaused = false;\n                    if (!s.autoplaying) {\n                        s.stopAutoplay();\n                    }\n                    else {\n                        autoplay();\n                    }\n                });\n            }\n        };\n        /*=========================\n          Min/Max Translate\n          ===========================*/\n        s.minTranslate = function () {\n            return (-s.snapGrid[0]);\n        };\n        s.maxTranslate = function () {\n            return (-s.snapGrid[s.snapGrid.length - 1]);\n        };\n        /*=========================\n          Slider/slides sizes\n          ===========================*/\n        s.updateAutoHeight = function () {\n            // Update Height\n            var slide = s.slides.eq(s.activeIndex)[0];\n            if (typeof slide !== 'undefined') {\n                var newHeight = slide.offsetHeight;\n                if (newHeight) s.wrapper.css('height', newHeight + 'px');\n            }\n        };\n        s.updateContainerSize = function () {\n            var width, height;\n            if (typeof s.params.width !== 'undefined') {\n                width = s.params.width;\n            }\n            else {\n                width = s.container[0].clientWidth;\n            }\n            if (typeof s.params.height !== 'undefined') {\n                height = s.params.height;\n            }\n            else {\n                height = s.container[0].clientHeight;\n            }\n            if (width === 0 && s.isHorizontal() || height === 0 && !s.isHorizontal()) {\n                return;\n            }\n        \n            //Subtract paddings\n            width = width - parseInt(s.container.css('padding-left'), 10) - parseInt(s.container.css('padding-right'), 10);\n            height = height - parseInt(s.container.css('padding-top'), 10) - parseInt(s.container.css('padding-bottom'), 10);\n        \n            // Store values\n            s.width = width;\n            s.height = height;\n            s.size = s.isHorizontal() ? s.width : s.height;\n        };\n        \n        s.updateSlidesSize = function () {\n            s.slides = s.wrapper.children('.' + s.params.slideClass);\n            s.snapGrid = [];\n            s.slidesGrid = [];\n            s.slidesSizesGrid = [];\n        \n            var spaceBetween = s.params.spaceBetween,\n                slidePosition = -s.params.slidesOffsetBefore,\n                i,\n                prevSlideSize = 0,\n                index = 0;\n            if (typeof s.size === 'undefined') return;\n            if (typeof spaceBetween === 'string' && spaceBetween.indexOf('%') >= 0) {\n                spaceBetween = parseFloat(spaceBetween.replace('%', '')) / 100 * s.size;\n            }\n        \n            s.virtualSize = -spaceBetween;\n            // reset margins\n            if (s.rtl) s.slides.css({marginLeft: '', marginTop: ''});\n            else s.slides.css({marginRight: '', marginBottom: ''});\n        \n            var slidesNumberEvenToRows;\n            if (s.params.slidesPerColumn > 1) {\n                if (Math.floor(s.slides.length / s.params.slidesPerColumn) === s.slides.length / s.params.slidesPerColumn) {\n                    slidesNumberEvenToRows = s.slides.length;\n                }\n                else {\n                    slidesNumberEvenToRows = Math.ceil(s.slides.length / s.params.slidesPerColumn) * s.params.slidesPerColumn;\n                }\n                if (s.params.slidesPerView !== 'auto' && s.params.slidesPerColumnFill === 'row') {\n                    slidesNumberEvenToRows = Math.max(slidesNumberEvenToRows, s.params.slidesPerView * s.params.slidesPerColumn);\n                }\n            }\n        \n            // Calc slides\n            var slideSize;\n            var slidesPerColumn = s.params.slidesPerColumn;\n            var slidesPerRow = slidesNumberEvenToRows / slidesPerColumn;\n            var numFullColumns = slidesPerRow - (s.params.slidesPerColumn * slidesPerRow - s.slides.length);\n            for (i = 0; i < s.slides.length; i++) {\n                slideSize = 0;\n                var slide = s.slides.eq(i);\n                if (s.params.slidesPerColumn > 1) {\n                    // Set slides order\n                    var newSlideOrderIndex;\n                    var column, row;\n                    if (s.params.slidesPerColumnFill === 'column') {\n                        column = Math.floor(i / slidesPerColumn);\n                        row = i - column * slidesPerColumn;\n                        if (column > numFullColumns || (column === numFullColumns && row === slidesPerColumn-1)) {\n                            if (++row >= slidesPerColumn) {\n                                row = 0;\n                                column++;\n                            }\n                        }\n                        newSlideOrderIndex = column + row * slidesNumberEvenToRows / slidesPerColumn;\n                        slide\n                            .css({\n                                '-webkit-box-ordinal-group': newSlideOrderIndex,\n                                '-moz-box-ordinal-group': newSlideOrderIndex,\n                                '-ms-flex-order': newSlideOrderIndex,\n                                '-webkit-order': newSlideOrderIndex,\n                                'order': newSlideOrderIndex\n                            });\n                    }\n                    else {\n                        row = Math.floor(i / slidesPerRow);\n                        column = i - row * slidesPerRow;\n                    }\n                    slide\n                        .css({\n                            'margin-top': (row !== 0 && s.params.spaceBetween) && (s.params.spaceBetween + 'px')\n                        })\n                        .attr('data-swiper-column', column)\n                        .attr('data-swiper-row', row);\n        \n                }\n                if (slide.css('display') === 'none') continue;\n                if (s.params.slidesPerView === 'auto') {\n                    slideSize = s.isHorizontal() ? slide.outerWidth(true) : slide.outerHeight(true);\n                    if (s.params.roundLengths) slideSize = round(slideSize);\n                }\n                else {\n                    slideSize = (s.size - (s.params.slidesPerView - 1) * spaceBetween) / s.params.slidesPerView;\n                    if (s.params.roundLengths) slideSize = round(slideSize);\n        \n                    if (s.isHorizontal()) {\n                        s.slides[i].style.width = slideSize + 'px';\n                    }\n                    else {\n                        s.slides[i].style.height = slideSize + 'px';\n                    }\n                }\n                s.slides[i].swiperSlideSize = slideSize;\n                s.slidesSizesGrid.push(slideSize);\n        \n        \n                if (s.params.centeredSlides) {\n                    slidePosition = slidePosition + slideSize / 2 + prevSlideSize / 2 + spaceBetween;\n                    if (i === 0) slidePosition = slidePosition - s.size / 2 - spaceBetween;\n                    if (Math.abs(slidePosition) < 1 / 1000) slidePosition = 0;\n                    if ((index) % s.params.slidesPerGroup === 0) s.snapGrid.push(slidePosition);\n                    s.slidesGrid.push(slidePosition);\n                }\n                else {\n                    if ((index) % s.params.slidesPerGroup === 0) s.snapGrid.push(slidePosition);\n                    s.slidesGrid.push(slidePosition);\n                    slidePosition = slidePosition + slideSize + spaceBetween;\n                }\n        \n                s.virtualSize += slideSize + spaceBetween;\n        \n                prevSlideSize = slideSize;\n        \n                index ++;\n            }\n            s.virtualSize = Math.max(s.virtualSize, s.size) + s.params.slidesOffsetAfter;\n            var newSlidesGrid;\n        \n            if (\n                s.rtl && s.wrongRTL && (s.params.effect === 'slide' || s.params.effect === 'coverflow')) {\n                s.wrapper.css({width: s.virtualSize + s.params.spaceBetween + 'px'});\n            }\n            if (!s.support.flexbox || s.params.setWrapperSize) {\n                if (s.isHorizontal()) s.wrapper.css({width: s.virtualSize + s.params.spaceBetween + 'px'});\n                else s.wrapper.css({height: s.virtualSize + s.params.spaceBetween + 'px'});\n            }\n        \n            if (s.params.slidesPerColumn > 1) {\n                s.virtualSize = (slideSize + s.params.spaceBetween) * slidesNumberEvenToRows;\n                s.virtualSize = Math.ceil(s.virtualSize / s.params.slidesPerColumn) - s.params.spaceBetween;\n                s.wrapper.css({width: s.virtualSize + s.params.spaceBetween + 'px'});\n                if (s.params.centeredSlides) {\n                    newSlidesGrid = [];\n                    for (i = 0; i < s.snapGrid.length; i++) {\n                        if (s.snapGrid[i] < s.virtualSize + s.snapGrid[0]) newSlidesGrid.push(s.snapGrid[i]);\n                    }\n                    s.snapGrid = newSlidesGrid;\n                }\n            }\n        \n            // Remove last grid elements depending on width\n            if (!s.params.centeredSlides) {\n                newSlidesGrid = [];\n                for (i = 0; i < s.snapGrid.length; i++) {\n                    if (s.snapGrid[i] <= s.virtualSize - s.size) {\n                        newSlidesGrid.push(s.snapGrid[i]);\n                    }\n                }\n                s.snapGrid = newSlidesGrid;\n                if (Math.floor(s.virtualSize - s.size) - Math.floor(s.snapGrid[s.snapGrid.length - 1]) > 1) {\n                    s.snapGrid.push(s.virtualSize - s.size);\n                }\n            }\n            if (s.snapGrid.length === 0) s.snapGrid = [0];\n        \n            if (s.params.spaceBetween !== 0) {\n                if (s.isHorizontal()) {\n                    if (s.rtl) s.slides.css({marginLeft: spaceBetween + 'px'});\n                    else s.slides.css({marginRight: spaceBetween + 'px'});\n                }\n                else s.slides.css({marginBottom: spaceBetween + 'px'});\n            }\n            if (s.params.watchSlidesProgress) {\n                s.updateSlidesOffset();\n            }\n        };\n        s.updateSlidesOffset = function () {\n            for (var i = 0; i < s.slides.length; i++) {\n                s.slides[i].swiperSlideOffset = s.isHorizontal() ? s.slides[i].offsetLeft : s.slides[i].offsetTop;\n            }\n        };\n        \n        /*=========================\n          Slider/slides progress\n          ===========================*/\n        s.updateSlidesProgress = function (translate) {\n            if (typeof translate === 'undefined') {\n                translate = s.translate || 0;\n            }\n            if (s.slides.length === 0) return;\n            if (typeof s.slides[0].swiperSlideOffset === 'undefined') s.updateSlidesOffset();\n        \n            var offsetCenter = -translate;\n            if (s.rtl) offsetCenter = translate;\n        \n            // Visible Slides\n            s.slides.removeClass(s.params.slideVisibleClass);\n            for (var i = 0; i < s.slides.length; i++) {\n                var slide = s.slides[i];\n                var slideProgress = (offsetCenter - slide.swiperSlideOffset) / (slide.swiperSlideSize + s.params.spaceBetween);\n                if (s.params.watchSlidesVisibility) {\n                    var slideBefore = -(offsetCenter - slide.swiperSlideOffset);\n                    var slideAfter = slideBefore + s.slidesSizesGrid[i];\n                    var isVisible =\n                        (slideBefore >= 0 && slideBefore < s.size) ||\n                        (slideAfter > 0 && slideAfter <= s.size) ||\n                        (slideBefore <= 0 && slideAfter >= s.size);\n                    if (isVisible) {\n                        s.slides.eq(i).addClass(s.params.slideVisibleClass);\n                    }\n                }\n                slide.progress = s.rtl ? -slideProgress : slideProgress;\n            }\n        };\n        s.updateProgress = function (translate) {\n            if (typeof translate === 'undefined') {\n                translate = s.translate || 0;\n            }\n            var translatesDiff = s.maxTranslate() - s.minTranslate();\n            var wasBeginning = s.isBeginning;\n            var wasEnd = s.isEnd;\n            if (translatesDiff === 0) {\n                s.progress = 0;\n                s.isBeginning = s.isEnd = true;\n            }\n            else {\n                s.progress = (translate - s.minTranslate()) / (translatesDiff);\n                s.isBeginning = s.progress <= 0;\n                s.isEnd = s.progress >= 1;\n            }\n            if (s.isBeginning && !wasBeginning) s.emit('onReachBeginning', s);\n            if (s.isEnd && !wasEnd) s.emit('onReachEnd', s);\n        \n            if (s.params.watchSlidesProgress) s.updateSlidesProgress(translate);\n            s.emit('onProgress', s, s.progress);\n        };\n        s.updateActiveIndex = function () {\n            var translate = s.rtl ? s.translate : -s.translate;\n            var newActiveIndex, i, snapIndex;\n            for (i = 0; i < s.slidesGrid.length; i ++) {\n                if (typeof s.slidesGrid[i + 1] !== 'undefined') {\n                    if (translate >= s.slidesGrid[i] && translate < s.slidesGrid[i + 1] - (s.slidesGrid[i + 1] - s.slidesGrid[i]) / 2) {\n                        newActiveIndex = i;\n                    }\n                    else if (translate >= s.slidesGrid[i] && translate < s.slidesGrid[i + 1]) {\n                        newActiveIndex = i + 1;\n                    }\n                }\n                else {\n                    if (translate >= s.slidesGrid[i]) {\n                        newActiveIndex = i;\n                    }\n                }\n            }\n            // Normalize slideIndex\n            if (newActiveIndex < 0 || typeof newActiveIndex === 'undefined') newActiveIndex = 0;\n            // for (i = 0; i < s.slidesGrid.length; i++) {\n                // if (- translate >= s.slidesGrid[i]) {\n                    // newActiveIndex = i;\n                // }\n            // }\n            snapIndex = Math.floor(newActiveIndex / s.params.slidesPerGroup);\n            if (snapIndex >= s.snapGrid.length) snapIndex = s.snapGrid.length - 1;\n        \n            if (newActiveIndex === s.activeIndex) {\n                return;\n            }\n            s.snapIndex = snapIndex;\n            s.previousIndex = s.activeIndex;\n            s.activeIndex = newActiveIndex;\n            s.updateClasses();\n        };\n        \n        /*=========================\n          Classes\n          ===========================*/\n        s.updateClasses = function () {\n            s.slides.removeClass(s.params.slideActiveClass + ' ' + s.params.slideNextClass + ' ' + s.params.slidePrevClass);\n            var activeSlide = s.slides.eq(s.activeIndex);\n            // Active classes\n            activeSlide.addClass(s.params.slideActiveClass);\n            // Next Slide\n            var nextSlide = activeSlide.next('.' + s.params.slideClass).addClass(s.params.slideNextClass);\n            if (s.params.loop && nextSlide.length === 0) {\n                s.slides.eq(0).addClass(s.params.slideNextClass);\n            }\n            // Prev Slide\n            var prevSlide = activeSlide.prev('.' + s.params.slideClass).addClass(s.params.slidePrevClass);\n            if (s.params.loop && prevSlide.length === 0) {\n                s.slides.eq(-1).addClass(s.params.slidePrevClass);\n            }\n        \n            // Pagination\n            if (s.paginationContainer && s.paginationContainer.length > 0) {\n                // Current/Total\n                var current,\n                    total = s.params.loop ? Math.ceil((s.slides.length - s.loopedSlides * 2) / s.params.slidesPerGroup) : s.snapGrid.length;\n                if (s.params.loop) {\n                    current = Math.ceil((s.activeIndex - s.loopedSlides)/s.params.slidesPerGroup);\n                    if (current > s.slides.length - 1 - s.loopedSlides * 2) {\n                        current = current - (s.slides.length - s.loopedSlides * 2);\n                    }\n                    if (current > total - 1) current = current - total;\n                    if (current < 0 && s.params.paginationType !== 'bullets') current = total + current;\n                }\n                else {\n                    if (typeof s.snapIndex !== 'undefined') {\n                        current = s.snapIndex;\n                    }\n                    else {\n                        current = s.activeIndex || 0;\n                    }\n                }\n                // Types\n                if (s.params.paginationType === 'bullets' && s.bullets && s.bullets.length > 0) {\n                    s.bullets.removeClass(s.params.bulletActiveClass);\n                    if (s.paginationContainer.length > 1) {\n                        s.bullets.each(function () {\n                            if ($(this).index() === current) $(this).addClass(s.params.bulletActiveClass);\n                        });\n                    }\n                    else {\n                        s.bullets.eq(current).addClass(s.params.bulletActiveClass);\n                    }\n                }\n                if (s.params.paginationType === 'fraction') {\n                    s.paginationContainer.find('.' + s.params.paginationCurrentClass).text(current + 1);\n                    s.paginationContainer.find('.' + s.params.paginationTotalClass).text(total);\n                }\n                if (s.params.paginationType === 'progress') {\n                    var scale = (current + 1) / total,\n                        scaleX = scale,\n                        scaleY = 1;\n                    if (!s.isHorizontal()) {\n                        scaleY = scale;\n                        scaleX = 1;\n                    }\n                    s.paginationContainer.find('.' + s.params.paginationProgressbarClass).transform('translate3d(0,0,0) scaleX(' + scaleX + ') scaleY(' + scaleY + ')').transition(s.params.speed);\n                }\n                if (s.params.paginationType === 'custom' && s.params.paginationCustomRender) {\n                    s.paginationContainer.html(s.params.paginationCustomRender(s, current + 1, total));\n                    s.emit('onPaginationRendered', s, s.paginationContainer[0]);\n                }\n            }\n        \n            // Next/active buttons\n            if (!s.params.loop) {\n                if (s.params.prevButton && s.prevButton && s.prevButton.length > 0) {\n                    if (s.isBeginning) {\n                        s.prevButton.addClass(s.params.buttonDisabledClass);\n                        if (s.params.a11y && s.a11y) s.a11y.disable(s.prevButton);\n                    }\n                    else {\n                        s.prevButton.removeClass(s.params.buttonDisabledClass);\n                        if (s.params.a11y && s.a11y) s.a11y.enable(s.prevButton);\n                    }\n                }\n                if (s.params.nextButton && s.nextButton && s.nextButton.length > 0) {\n                    if (s.isEnd) {\n                        s.nextButton.addClass(s.params.buttonDisabledClass);\n                        if (s.params.a11y && s.a11y) s.a11y.disable(s.nextButton);\n                    }\n                    else {\n                        s.nextButton.removeClass(s.params.buttonDisabledClass);\n                        if (s.params.a11y && s.a11y) s.a11y.enable(s.nextButton);\n                    }\n                }\n            }\n        };\n        \n        /*=========================\n          Pagination\n          ===========================*/\n        s.updatePagination = function () {\n            if (!s.params.pagination) return;\n            if (s.paginationContainer && s.paginationContainer.length > 0) {\n                var paginationHTML = '';\n                if (s.params.paginationType === 'bullets') {\n                    var numberOfBullets = s.params.loop ? Math.ceil((s.slides.length - s.loopedSlides * 2) / s.params.slidesPerGroup) : s.snapGrid.length;\n                    for (var i = 0; i < numberOfBullets; i++) {\n                        if (s.params.paginationBulletRender) {\n                            paginationHTML += s.params.paginationBulletRender(i, s.params.bulletClass);\n                        }\n                        else {\n                            paginationHTML += '<' + s.params.paginationElement+' class=\"' + s.params.bulletClass + '\"></' + s.params.paginationElement + '>';\n                        }\n                    }\n                    s.paginationContainer.html(paginationHTML);\n                    s.bullets = s.paginationContainer.find('.' + s.params.bulletClass);\n                    if (s.params.paginationClickable && s.params.a11y && s.a11y) {\n                        s.a11y.initPagination();\n                    }\n                }\n                if (s.params.paginationType === 'fraction') {\n                    if (s.params.paginationFractionRender) {\n                        paginationHTML = s.params.paginationFractionRender(s, s.params.paginationCurrentClass, s.params.paginationTotalClass);\n                    }\n                    else {\n                        paginationHTML =\n                            '<span class=\"' + s.params.paginationCurrentClass + '\"></span>' +\n                            ' / ' +\n                            '<span class=\"' + s.params.paginationTotalClass+'\"></span>';\n                    }\n                    s.paginationContainer.html(paginationHTML);\n                }\n                if (s.params.paginationType === 'progress') {\n                    if (s.params.paginationProgressRender) {\n                        paginationHTML = s.params.paginationProgressRender(s, s.params.paginationProgressbarClass);\n                    }\n                    else {\n                        paginationHTML = '<span class=\"' + s.params.paginationProgressbarClass + '\"></span>';\n                    }\n                    s.paginationContainer.html(paginationHTML);\n                }\n                if (s.params.paginationType !== 'custom') {\n                    s.emit('onPaginationRendered', s, s.paginationContainer[0]);\n                }\n            }\n        };\n        /*=========================\n          Common update method\n          ===========================*/\n        s.update = function (updateTranslate) {\n            s.updateContainerSize();\n            s.updateSlidesSize();\n            s.updateProgress();\n            s.updatePagination();\n            s.updateClasses();\n            if (s.params.scrollbar && s.scrollbar) {\n                s.scrollbar.set();\n            }\n            function forceSetTranslate() {\n                newTranslate = Math.min(Math.max(s.translate, s.maxTranslate()), s.minTranslate());\n                s.setWrapperTranslate(newTranslate);\n                s.updateActiveIndex();\n                s.updateClasses();\n            }\n            if (updateTranslate) {\n                var translated, newTranslate;\n                if (s.controller && s.controller.spline) {\n                    s.controller.spline = undefined;\n                }\n                if (s.params.freeMode) {\n                    forceSetTranslate();\n                    if (s.params.autoHeight) {\n                        s.updateAutoHeight();\n                    }\n                }\n                else {\n                    if ((s.params.slidesPerView === 'auto' || s.params.slidesPerView > 1) && s.isEnd && !s.params.centeredSlides) {\n                        translated = s.slideTo(s.slides.length - 1, 0, false, true);\n                    }\n                    else {\n                        translated = s.slideTo(s.activeIndex, 0, false, true);\n                    }\n                    if (!translated) {\n                        forceSetTranslate();\n                    }\n                }\n            }\n            else if (s.params.autoHeight) {\n                s.updateAutoHeight();\n            }\n        };\n        \n        /*=========================\n          Resize Handler\n          ===========================*/\n        s.onResize = function (forceUpdatePagination) {\n            //Breakpoints\n            if (s.params.breakpoints) {\n                s.setBreakpoint();\n            }\n        \n            // Disable locks on resize\n            var allowSwipeToPrev = s.params.allowSwipeToPrev;\n            var allowSwipeToNext = s.params.allowSwipeToNext;\n            s.params.allowSwipeToPrev = s.params.allowSwipeToNext = true;\n        \n            s.updateContainerSize();\n            s.updateSlidesSize();\n            if (s.params.slidesPerView === 'auto' || s.params.freeMode || forceUpdatePagination) s.updatePagination();\n            if (s.params.scrollbar && s.scrollbar) {\n                s.scrollbar.set();\n            }\n            if (s.controller && s.controller.spline) {\n                s.controller.spline = undefined;\n            }\n            var slideChangedBySlideTo = false;\n            if (s.params.freeMode) {\n                var newTranslate = Math.min(Math.max(s.translate, s.maxTranslate()), s.minTranslate());\n                s.setWrapperTranslate(newTranslate);\n                s.updateActiveIndex();\n                s.updateClasses();\n        \n                if (s.params.autoHeight) {\n                    s.updateAutoHeight();\n                }\n            }\n            else {\n                s.updateClasses();\n                if ((s.params.slidesPerView === 'auto' || s.params.slidesPerView > 1) && s.isEnd && !s.params.centeredSlides) {\n                    slideChangedBySlideTo = s.slideTo(s.slides.length - 1, 0, false, true);\n                }\n                else {\n                    slideChangedBySlideTo = s.slideTo(s.activeIndex, 0, false, true);\n                }\n            }\n            if (s.params.lazyLoading && !slideChangedBySlideTo && s.lazy) {\n                s.lazy.load();\n            }\n            // Return locks after resize\n            s.params.allowSwipeToPrev = allowSwipeToPrev;\n            s.params.allowSwipeToNext = allowSwipeToNext;\n        };\n        \n        /*=========================\n          Events\n          ===========================*/\n        \n        //Define Touch Events\n        var desktopEvents = ['mousedown', 'mousemove', 'mouseup'];\n        if (window.navigator.pointerEnabled) desktopEvents = ['pointerdown', 'pointermove', 'pointerup'];\n        else if (window.navigator.msPointerEnabled) desktopEvents = ['MSPointerDown', 'MSPointerMove', 'MSPointerUp'];\n        s.touchEvents = {\n            start : s.support.touch || !s.params.simulateTouch  ? 'touchstart' : desktopEvents[0],\n            move : s.support.touch || !s.params.simulateTouch ? 'touchmove' : desktopEvents[1],\n            end : s.support.touch || !s.params.simulateTouch ? 'touchend' : desktopEvents[2]\n        };\n        \n        \n        // WP8 Touch Events Fix\n        if (window.navigator.pointerEnabled || window.navigator.msPointerEnabled) {\n            (s.params.touchEventsTarget === 'container' ? s.container : s.wrapper).addClass('swiper-wp8-' + s.params.direction);\n        }\n        \n        // Attach/detach events\n        s.initEvents = function (detach) {\n            var actionDom = detach ? 'off' : 'on';\n            var action = detach ? 'removeEventListener' : 'addEventListener';\n            var touchEventsTarget = s.params.touchEventsTarget === 'container' ? s.container[0] : s.wrapper[0];\n            var target = s.support.touch ? touchEventsTarget : document;\n        \n            var moveCapture = s.params.nested ? true : false;\n        \n            //Touch Events\n            if (s.browser.ie) {\n                touchEventsTarget[action](s.touchEvents.start, s.onTouchStart, false);\n                target[action](s.touchEvents.move, s.onTouchMove, moveCapture);\n                target[action](s.touchEvents.end, s.onTouchEnd, false);\n            }\n            else {\n                if (s.support.touch) {\n                    touchEventsTarget[action](s.touchEvents.start, s.onTouchStart, false);\n                    touchEventsTarget[action](s.touchEvents.move, s.onTouchMove, moveCapture);\n                    touchEventsTarget[action](s.touchEvents.end, s.onTouchEnd, false);\n                }\n                if (params.simulateTouch && !s.device.ios && !s.device.android) {\n                    touchEventsTarget[action]('mousedown', s.onTouchStart, false);\n                    document[action]('mousemove', s.onTouchMove, moveCapture);\n                    document[action]('mouseup', s.onTouchEnd, false);\n                }\n            }\n            window[action]('resize', s.onResize);\n        \n            // Next, Prev, Index\n            if (s.params.nextButton && s.nextButton && s.nextButton.length > 0) {\n                s.nextButton[actionDom]('click', s.onClickNext);\n                if (s.params.a11y && s.a11y) s.nextButton[actionDom]('keydown', s.a11y.onEnterKey);\n            }\n            if (s.params.prevButton && s.prevButton && s.prevButton.length > 0) {\n                s.prevButton[actionDom]('click', s.onClickPrev);\n                if (s.params.a11y && s.a11y) s.prevButton[actionDom]('keydown', s.a11y.onEnterKey);\n            }\n            if (s.params.pagination && s.params.paginationClickable) {\n                s.paginationContainer[actionDom]('click', '.' + s.params.bulletClass, s.onClickIndex);\n                if (s.params.a11y && s.a11y) s.paginationContainer[actionDom]('keydown', '.' + s.params.bulletClass, s.a11y.onEnterKey);\n            }\n        \n            // Prevent Links Clicks\n            if (s.params.preventClicks || s.params.preventClicksPropagation) touchEventsTarget[action]('click', s.preventClicks, true);\n        };\n        s.attachEvents = function () {\n            s.initEvents();\n        };\n        s.detachEvents = function () {\n            s.initEvents(true);\n        };\n        \n        /*=========================\n          Handle Clicks\n          ===========================*/\n        // Prevent Clicks\n        s.allowClick = true;\n        s.preventClicks = function (e) {\n            if (!s.allowClick) {\n                if (s.params.preventClicks) e.preventDefault();\n                if (s.params.preventClicksPropagation && s.animating) {\n                    e.stopPropagation();\n                    e.stopImmediatePropagation();\n                }\n            }\n        };\n        // Clicks\n        s.onClickNext = function (e) {\n            e.preventDefault();\n            if (s.isEnd && !s.params.loop) return;\n            s.slideNext();\n        };\n        s.onClickPrev = function (e) {\n            e.preventDefault();\n            if (s.isBeginning && !s.params.loop) return;\n            s.slidePrev();\n        };\n        s.onClickIndex = function (e) {\n            e.preventDefault();\n            var index = $(this).index() * s.params.slidesPerGroup;\n            if (s.params.loop) index = index + s.loopedSlides;\n            s.slideTo(index);\n        };\n        \n        /*=========================\n          Handle Touches\n          ===========================*/\n        function findElementInEvent(e, selector) {\n            var el = $(e.target);\n            if (!el.is(selector)) {\n                if (typeof selector === 'string') {\n                    el = el.parents(selector);\n                }\n                else if (selector.nodeType) {\n                    var found;\n                    el.parents().each(function (index, _el) {\n                        if (_el === selector) found = selector;\n                    });\n                    if (!found) return undefined;\n                    else return selector;\n                }\n            }\n            if (el.length === 0) {\n                return undefined;\n            }\n            return el[0];\n        }\n        s.updateClickedSlide = function (e) {\n            var slide = findElementInEvent(e, '.' + s.params.slideClass);\n            var slideFound = false;\n            if (slide) {\n                for (var i = 0; i < s.slides.length; i++) {\n                    if (s.slides[i] === slide) slideFound = true;\n                }\n            }\n        \n            if (slide && slideFound) {\n                s.clickedSlide = slide;\n                s.clickedIndex = $(slide).index();\n            }\n            else {\n                s.clickedSlide = undefined;\n                s.clickedIndex = undefined;\n                return;\n            }\n            if (s.params.slideToClickedSlide && s.clickedIndex !== undefined && s.clickedIndex !== s.activeIndex) {\n                var slideToIndex = s.clickedIndex,\n                    realIndex,\n                    duplicatedSlides;\n                if (s.params.loop) {\n                    if (s.animating) return;\n                    realIndex = $(s.clickedSlide).attr('data-swiper-slide-index');\n                    if (s.params.centeredSlides) {\n                        if ((slideToIndex < s.loopedSlides - s.params.slidesPerView/2) || (slideToIndex > s.slides.length - s.loopedSlides + s.params.slidesPerView/2)) {\n                            s.fixLoop();\n                            slideToIndex = s.wrapper.children('.' + s.params.slideClass + '[data-swiper-slide-index=\"' + realIndex + '\"]:not(.swiper-slide-duplicate)').eq(0).index();\n                            setTimeout(function () {\n                                s.slideTo(slideToIndex);\n                            }, 0);\n                        }\n                        else {\n                            s.slideTo(slideToIndex);\n                        }\n                    }\n                    else {\n                        if (slideToIndex > s.slides.length - s.params.slidesPerView) {\n                            s.fixLoop();\n                            slideToIndex = s.wrapper.children('.' + s.params.slideClass + '[data-swiper-slide-index=\"' + realIndex + '\"]:not(.swiper-slide-duplicate)').eq(0).index();\n                            setTimeout(function () {\n                                s.slideTo(slideToIndex);\n                            }, 0);\n                        }\n                        else {\n                            s.slideTo(slideToIndex);\n                        }\n                    }\n                }\n                else {\n                    s.slideTo(slideToIndex);\n                }\n            }\n        };\n        \n        var isTouched,\n            isMoved,\n            allowTouchCallbacks,\n            touchStartTime,\n            isScrolling,\n            currentTranslate,\n            startTranslate,\n            allowThresholdMove,\n            // Form elements to match\n            formElements = 'input, select, textarea, button',\n            // Last click time\n            lastClickTime = Date.now(), clickTimeout,\n            //Velocities\n            velocities = [],\n            allowMomentumBounce;\n        \n        // Animating Flag\n        s.animating = false;\n        \n        // Touches information\n        s.touches = {\n            startX: 0,\n            startY: 0,\n            currentX: 0,\n            currentY: 0,\n            diff: 0\n        };\n        \n        // Touch handlers\n        var isTouchEvent, startMoving;\n        s.onTouchStart = function (e) {\n            if (e.originalEvent) e = e.originalEvent;\n            isTouchEvent = e.type === 'touchstart';\n            if (!isTouchEvent && 'which' in e && e.which === 3) return;\n            if (s.params.noSwiping && findElementInEvent(e, '.' + s.params.noSwipingClass)) {\n                s.allowClick = true;\n                return;\n            }\n            if (s.params.swipeHandler) {\n                if (!findElementInEvent(e, s.params.swipeHandler)) return;\n            }\n        \n            var startX = s.touches.currentX = e.type === 'touchstart' ? e.targetTouches[0].pageX : e.pageX;\n            var startY = s.touches.currentY = e.type === 'touchstart' ? e.targetTouches[0].pageY : e.pageY;\n        \n            // Do NOT start if iOS edge swipe is detected. Otherwise iOS app (UIWebView) cannot swipe-to-go-back anymore\n            if(s.device.ios && s.params.iOSEdgeSwipeDetection && startX <= s.params.iOSEdgeSwipeThreshold) {\n                return;\n            }\n        \n            isTouched = true;\n            isMoved = false;\n            allowTouchCallbacks = true;\n            isScrolling = undefined;\n            startMoving = undefined;\n            s.touches.startX = startX;\n            s.touches.startY = startY;\n            touchStartTime = Date.now();\n            s.allowClick = true;\n            s.updateContainerSize();\n            s.swipeDirection = undefined;\n            if (s.params.threshold > 0) allowThresholdMove = false;\n            if (e.type !== 'touchstart') {\n                var preventDefault = true;\n                if ($(e.target).is(formElements)) preventDefault = false;\n                if (document.activeElement && $(document.activeElement).is(formElements)) {\n                    document.activeElement.blur();\n                }\n                if (preventDefault) {\n                    e.preventDefault();\n                }\n            }\n            s.emit('onTouchStart', s, e);\n        };\n        \n        s.onTouchMove = function (e) {\n            if (e.originalEvent) e = e.originalEvent;\n            if (isTouchEvent && e.type === 'mousemove') return;\n            if (e.preventedByNestedSwiper) {\n                s.touches.startX = e.type === 'touchmove' ? e.targetTouches[0].pageX : e.pageX;\n                s.touches.startY = e.type === 'touchmove' ? e.targetTouches[0].pageY : e.pageY;\n                return;\n            }\n            if (s.params.onlyExternal) {\n                // isMoved = true;\n                s.allowClick = false;\n                if (isTouched) {\n                    s.touches.startX = s.touches.currentX = e.type === 'touchmove' ? e.targetTouches[0].pageX : e.pageX;\n                    s.touches.startY = s.touches.currentY = e.type === 'touchmove' ? e.targetTouches[0].pageY : e.pageY;\n                    touchStartTime = Date.now();\n                }\n                return;\n            }\n            if (isTouchEvent && document.activeElement) {\n                if (e.target === document.activeElement && $(e.target).is(formElements)) {\n                    isMoved = true;\n                    s.allowClick = false;\n                    return;\n                }\n            }\n            if (allowTouchCallbacks) {\n                s.emit('onTouchMove', s, e);\n            }\n            if (e.targetTouches && e.targetTouches.length > 1) return;\n        \n            s.touches.currentX = e.type === 'touchmove' ? e.targetTouches[0].pageX : e.pageX;\n            s.touches.currentY = e.type === 'touchmove' ? e.targetTouches[0].pageY : e.pageY;\n        \n            if (typeof isScrolling === 'undefined') {\n                var touchAngle = Math.atan2(Math.abs(s.touches.currentY - s.touches.startY), Math.abs(s.touches.currentX - s.touches.startX)) * 180 / Math.PI;\n                isScrolling = s.isHorizontal() ? touchAngle > s.params.touchAngle : (90 - touchAngle > s.params.touchAngle);\n            }\n            if (isScrolling) {\n                s.emit('onTouchMoveOpposite', s, e);\n            }\n            if (typeof startMoving === 'undefined' && s.browser.ieTouch) {\n                if (s.touches.currentX !== s.touches.startX || s.touches.currentY !== s.touches.startY) {\n                    startMoving = true;\n                }\n            }\n            if (!isTouched) return;\n            if (isScrolling)  {\n                isTouched = false;\n                return;\n            }\n            if (!startMoving && s.browser.ieTouch) {\n                return;\n            }\n            s.allowClick = false;\n            s.emit('onSliderMove', s, e);\n            e.preventDefault();\n            if (s.params.touchMoveStopPropagation && !s.params.nested) {\n                e.stopPropagation();\n            }\n        \n            if (!isMoved) {\n                if (params.loop) {\n                    s.fixLoop();\n                }\n                startTranslate = s.getWrapperTranslate();\n                s.setWrapperTransition(0);\n                if (s.animating) {\n                    s.wrapper.trigger('webkitTransitionEnd transitionend oTransitionEnd MSTransitionEnd msTransitionEnd');\n                }\n                if (s.params.autoplay && s.autoplaying) {\n                    if (s.params.autoplayDisableOnInteraction) {\n                        s.stopAutoplay();\n                    }\n                    else {\n                        s.pauseAutoplay();\n                    }\n                }\n                allowMomentumBounce = false;\n                //Grab Cursor\n                if (s.params.grabCursor) {\n                    s.container[0].style.cursor = 'move';\n                    s.container[0].style.cursor = '-webkit-grabbing';\n                    s.container[0].style.cursor = '-moz-grabbin';\n                    s.container[0].style.cursor = 'grabbing';\n                }\n            }\n            isMoved = true;\n        \n            var diff = s.touches.diff = s.isHorizontal() ? s.touches.currentX - s.touches.startX : s.touches.currentY - s.touches.startY;\n        \n            diff = diff * s.params.touchRatio;\n            if (s.rtl) diff = -diff;\n        \n            s.swipeDirection = diff > 0 ? 'prev' : 'next';\n            currentTranslate = diff + startTranslate;\n        \n            var disableParentSwiper = true;\n            if ((diff > 0 && currentTranslate > s.minTranslate())) {\n                disableParentSwiper = false;\n                if (s.params.resistance) currentTranslate = s.minTranslate() - 1 + Math.pow(-s.minTranslate() + startTranslate + diff, s.params.resistanceRatio);\n            }\n            else if (diff < 0 && currentTranslate < s.maxTranslate()) {\n                disableParentSwiper = false;\n                if (s.params.resistance) currentTranslate = s.maxTranslate() + 1 - Math.pow(s.maxTranslate() - startTranslate - diff, s.params.resistanceRatio);\n            }\n        \n            if (disableParentSwiper) {\n                e.preventedByNestedSwiper = true;\n            }\n        \n            // Directions locks\n            if (!s.params.allowSwipeToNext && s.swipeDirection === 'next' && currentTranslate < startTranslate) {\n                currentTranslate = startTranslate;\n            }\n            if (!s.params.allowSwipeToPrev && s.swipeDirection === 'prev' && currentTranslate > startTranslate) {\n                currentTranslate = startTranslate;\n            }\n        \n            if (!s.params.followFinger) return;\n        \n            // Threshold\n            if (s.params.threshold > 0) {\n                if (Math.abs(diff) > s.params.threshold || allowThresholdMove) {\n                    if (!allowThresholdMove) {\n                        allowThresholdMove = true;\n                        s.touches.startX = s.touches.currentX;\n                        s.touches.startY = s.touches.currentY;\n                        currentTranslate = startTranslate;\n                        s.touches.diff = s.isHorizontal() ? s.touches.currentX - s.touches.startX : s.touches.currentY - s.touches.startY;\n                        return;\n                    }\n                }\n                else {\n                    currentTranslate = startTranslate;\n                    return;\n                }\n            }\n            // Update active index in free mode\n            if (s.params.freeMode || s.params.watchSlidesProgress) {\n                s.updateActiveIndex();\n            }\n            if (s.params.freeMode) {\n                //Velocity\n                if (velocities.length === 0) {\n                    velocities.push({\n                        position: s.touches[s.isHorizontal() ? 'startX' : 'startY'],\n                        time: touchStartTime\n                    });\n                }\n                velocities.push({\n                    position: s.touches[s.isHorizontal() ? 'currentX' : 'currentY'],\n                    time: (new window.Date()).getTime()\n                });\n            }\n            // Update progress\n            s.updateProgress(currentTranslate);\n            // Update translate\n            s.setWrapperTranslate(currentTranslate);\n        };\n        s.onTouchEnd = function (e) {\n            if (e.originalEvent) e = e.originalEvent;\n            if (allowTouchCallbacks) {\n                s.emit('onTouchEnd', s, e);\n            }\n            allowTouchCallbacks = false;\n            if (!isTouched) return;\n            //Return Grab Cursor\n            if (s.params.grabCursor && isMoved && isTouched) {\n                s.container[0].style.cursor = 'move';\n                s.container[0].style.cursor = '-webkit-grab';\n                s.container[0].style.cursor = '-moz-grab';\n                s.container[0].style.cursor = 'grab';\n            }\n        \n            // Time diff\n            var touchEndTime = Date.now();\n            var timeDiff = touchEndTime - touchStartTime;\n        \n            // Tap, doubleTap, Click\n            if (s.allowClick) {\n                s.updateClickedSlide(e);\n                s.emit('onTap', s, e);\n                if (timeDiff < 300 && (touchEndTime - lastClickTime) > 300) {\n                    if (clickTimeout) clearTimeout(clickTimeout);\n                    clickTimeout = setTimeout(function () {\n                        if (!s) return;\n                        if (s.params.paginationHide && s.paginationContainer.length > 0 && !$(e.target).hasClass(s.params.bulletClass)) {\n                            s.paginationContainer.toggleClass(s.params.paginationHiddenClass);\n                        }\n                        s.emit('onClick', s, e);\n                    }, 300);\n        \n                }\n                if (timeDiff < 300 && (touchEndTime - lastClickTime) < 300) {\n                    if (clickTimeout) clearTimeout(clickTimeout);\n                    s.emit('onDoubleTap', s, e);\n                }\n            }\n        \n            lastClickTime = Date.now();\n            setTimeout(function () {\n                if (s) s.allowClick = true;\n            }, 0);\n        \n            if (!isTouched || !isMoved || !s.swipeDirection || s.touches.diff === 0 || currentTranslate === startTranslate) {\n                isTouched = isMoved = false;\n                return;\n            }\n            isTouched = isMoved = false;\n        \n            var currentPos;\n            if (s.params.followFinger) {\n                currentPos = s.rtl ? s.translate : -s.translate;\n            }\n            else {\n                currentPos = -currentTranslate;\n            }\n            if (s.params.freeMode) {\n                if (currentPos < -s.minTranslate()) {\n                    s.slideTo(s.activeIndex);\n                    return;\n                }\n                else if (currentPos > -s.maxTranslate()) {\n                    if (s.slides.length < s.snapGrid.length) {\n                        s.slideTo(s.snapGrid.length - 1);\n                    }\n                    else {\n                        s.slideTo(s.slides.length - 1);\n                    }\n                    return;\n                }\n        \n                if (s.params.freeModeMomentum) {\n                    if (velocities.length > 1) {\n                        var lastMoveEvent = velocities.pop(), velocityEvent = velocities.pop();\n        \n                        var distance = lastMoveEvent.position - velocityEvent.position;\n                        var time = lastMoveEvent.time - velocityEvent.time;\n                        s.velocity = distance / time;\n                        s.velocity = s.velocity / 2;\n                        if (Math.abs(s.velocity) < s.params.freeModeMinimumVelocity) {\n                            s.velocity = 0;\n                        }\n                        // this implies that the user stopped moving a finger then released.\n                        // There would be no events with distance zero, so the last event is stale.\n                        if (time > 150 || (new window.Date().getTime() - lastMoveEvent.time) > 300) {\n                            s.velocity = 0;\n                        }\n                    } else {\n                        s.velocity = 0;\n                    }\n        \n                    velocities.length = 0;\n                    var momentumDuration = 1000 * s.params.freeModeMomentumRatio;\n                    var momentumDistance = s.velocity * momentumDuration;\n        \n                    var newPosition = s.translate + momentumDistance;\n                    if (s.rtl) newPosition = - newPosition;\n                    var doBounce = false;\n                    var afterBouncePosition;\n                    var bounceAmount = Math.abs(s.velocity) * 20 * s.params.freeModeMomentumBounceRatio;\n                    if (newPosition < s.maxTranslate()) {\n                        if (s.params.freeModeMomentumBounce) {\n                            if (newPosition + s.maxTranslate() < -bounceAmount) {\n                                newPosition = s.maxTranslate() - bounceAmount;\n                            }\n                            afterBouncePosition = s.maxTranslate();\n                            doBounce = true;\n                            allowMomentumBounce = true;\n                        }\n                        else {\n                            newPosition = s.maxTranslate();\n                        }\n                    }\n                    else if (newPosition > s.minTranslate()) {\n                        if (s.params.freeModeMomentumBounce) {\n                            if (newPosition - s.minTranslate() > bounceAmount) {\n                                newPosition = s.minTranslate() + bounceAmount;\n                            }\n                            afterBouncePosition = s.minTranslate();\n                            doBounce = true;\n                            allowMomentumBounce = true;\n                        }\n                        else {\n                            newPosition = s.minTranslate();\n                        }\n                    }\n                    else if (s.params.freeModeSticky) {\n                        var j = 0,\n                            nextSlide;\n                        for (j = 0; j < s.snapGrid.length; j += 1) {\n                            if (s.snapGrid[j] > -newPosition) {\n                                nextSlide = j;\n                                break;\n                            }\n        \n                        }\n                        if (Math.abs(s.snapGrid[nextSlide] - newPosition) < Math.abs(s.snapGrid[nextSlide - 1] - newPosition) || s.swipeDirection === 'next') {\n                            newPosition = s.snapGrid[nextSlide];\n                        } else {\n                            newPosition = s.snapGrid[nextSlide - 1];\n                        }\n                        if (!s.rtl) newPosition = - newPosition;\n                    }\n                    //Fix duration\n                    if (s.velocity !== 0) {\n                        if (s.rtl) {\n                            momentumDuration = Math.abs((-newPosition - s.translate) / s.velocity);\n                        }\n                        else {\n                            momentumDuration = Math.abs((newPosition - s.translate) / s.velocity);\n                        }\n                    }\n                    else if (s.params.freeModeSticky) {\n                        s.slideReset();\n                        return;\n                    }\n        \n                    if (s.params.freeModeMomentumBounce && doBounce) {\n                        s.updateProgress(afterBouncePosition);\n                        s.setWrapperTransition(momentumDuration);\n                        s.setWrapperTranslate(newPosition);\n                        s.onTransitionStart();\n                        s.animating = true;\n                        s.wrapper.transitionEnd(function () {\n                            if (!s || !allowMomentumBounce) return;\n                            s.emit('onMomentumBounce', s);\n        \n                            s.setWrapperTransition(s.params.speed);\n                            s.setWrapperTranslate(afterBouncePosition);\n                            s.wrapper.transitionEnd(function () {\n                                if (!s) return;\n                                s.onTransitionEnd();\n                            });\n                        });\n                    } else if (s.velocity) {\n                        s.updateProgress(newPosition);\n                        s.setWrapperTransition(momentumDuration);\n                        s.setWrapperTranslate(newPosition);\n                        s.onTransitionStart();\n                        if (!s.animating) {\n                            s.animating = true;\n                            s.wrapper.transitionEnd(function () {\n                                if (!s) return;\n                                s.onTransitionEnd();\n                            });\n                        }\n        \n                    } else {\n                        s.updateProgress(newPosition);\n                    }\n        \n                    s.updateActiveIndex();\n                }\n                if (!s.params.freeModeMomentum || timeDiff >= s.params.longSwipesMs) {\n                    s.updateProgress();\n                    s.updateActiveIndex();\n                }\n                return;\n            }\n        \n            // Find current slide\n            var i, stopIndex = 0, groupSize = s.slidesSizesGrid[0];\n            for (i = 0; i < s.slidesGrid.length; i += s.params.slidesPerGroup) {\n                if (typeof s.slidesGrid[i + s.params.slidesPerGroup] !== 'undefined') {\n                    if (currentPos >= s.slidesGrid[i] && currentPos < s.slidesGrid[i + s.params.slidesPerGroup]) {\n                        stopIndex = i;\n                        groupSize = s.slidesGrid[i + s.params.slidesPerGroup] - s.slidesGrid[i];\n                    }\n                }\n                else {\n                    if (currentPos >= s.slidesGrid[i]) {\n                        stopIndex = i;\n                        groupSize = s.slidesGrid[s.slidesGrid.length - 1] - s.slidesGrid[s.slidesGrid.length - 2];\n                    }\n                }\n            }\n        \n            // Find current slide size\n            var ratio = (currentPos - s.slidesGrid[stopIndex]) / groupSize;\n        \n            if (timeDiff > s.params.longSwipesMs) {\n                // Long touches\n                if (!s.params.longSwipes) {\n                    s.slideTo(s.activeIndex);\n                    return;\n                }\n                if (s.swipeDirection === 'next') {\n                    if (ratio >= s.params.longSwipesRatio) s.slideTo(stopIndex + s.params.slidesPerGroup);\n                    else s.slideTo(stopIndex);\n        \n                }\n                if (s.swipeDirection === 'prev') {\n                    if (ratio > (1 - s.params.longSwipesRatio)) s.slideTo(stopIndex + s.params.slidesPerGroup);\n                    else s.slideTo(stopIndex);\n                }\n            }\n            else {\n                // Short swipes\n                if (!s.params.shortSwipes) {\n                    s.slideTo(s.activeIndex);\n                    return;\n                }\n                if (s.swipeDirection === 'next') {\n                    s.slideTo(stopIndex + s.params.slidesPerGroup);\n        \n                }\n                if (s.swipeDirection === 'prev') {\n                    s.slideTo(stopIndex);\n                }\n            }\n        };\n        /*=========================\n          Transitions\n          ===========================*/\n        s._slideTo = function (slideIndex, speed) {\n            return s.slideTo(slideIndex, speed, true, true);\n        };\n        s.slideTo = function (slideIndex, speed, runCallbacks, internal) {\n            if (typeof runCallbacks === 'undefined') runCallbacks = true;\n            if (typeof slideIndex === 'undefined') slideIndex = 0;\n            if (slideIndex < 0) slideIndex = 0;\n            s.snapIndex = Math.floor(slideIndex / s.params.slidesPerGroup);\n            if (s.snapIndex >= s.snapGrid.length) s.snapIndex = s.snapGrid.length - 1;\n        \n            var translate = - s.snapGrid[s.snapIndex];\n            // Stop autoplay\n            if (s.params.autoplay && s.autoplaying) {\n                if (internal || !s.params.autoplayDisableOnInteraction) {\n                    s.pauseAutoplay(speed);\n                }\n                else {\n                    s.stopAutoplay();\n                }\n            }\n            // Update progress\n            s.updateProgress(translate);\n        \n            // Normalize slideIndex\n            for (var i = 0; i < s.slidesGrid.length; i++) {\n                if (- Math.floor(translate * 100) >= Math.floor(s.slidesGrid[i] * 100)) {\n                    slideIndex = i;\n                }\n            }\n        \n            // Directions locks\n            if (!s.params.allowSwipeToNext && translate < s.translate && translate < s.minTranslate()) {\n                return false;\n            }\n            if (!s.params.allowSwipeToPrev && translate > s.translate && translate > s.maxTranslate()) {\n                if ((s.activeIndex || 0) !== slideIndex ) return false;\n            }\n        \n            // Update Index\n            if (typeof speed === 'undefined') speed = s.params.speed;\n            s.previousIndex = s.activeIndex || 0;\n            s.activeIndex = slideIndex;\n        \n            if ((s.rtl && -translate === s.translate) || (!s.rtl && translate === s.translate)) {\n                // Update Height\n                if (s.params.autoHeight) {\n                    s.updateAutoHeight();\n                }\n                s.updateClasses();\n                if (s.params.effect !== 'slide') {\n                    s.setWrapperTranslate(translate);\n                }\n                return false;\n            }\n            s.updateClasses();\n            s.onTransitionStart(runCallbacks);\n        \n            if (speed === 0) {\n                s.setWrapperTranslate(translate);\n                s.setWrapperTransition(0);\n                s.onTransitionEnd(runCallbacks);\n            }\n            else {\n                s.setWrapperTranslate(translate);\n                s.setWrapperTransition(speed);\n                if (!s.animating) {\n                    s.animating = true;\n                    s.wrapper.transitionEnd(function () {\n                        if (!s) return;\n                        s.onTransitionEnd(runCallbacks);\n                    });\n                }\n        \n            }\n        \n            return true;\n        };\n        \n        s.onTransitionStart = function (runCallbacks) {\n            if (typeof runCallbacks === 'undefined') runCallbacks = true;\n            if (s.params.autoHeight) {\n                s.updateAutoHeight();\n            }\n            if (s.lazy) s.lazy.onTransitionStart();\n            if (runCallbacks) {\n                s.emit('onTransitionStart', s);\n                if (s.activeIndex !== s.previousIndex) {\n                    s.emit('onSlideChangeStart', s);\n                    if (s.activeIndex > s.previousIndex) {\n                        s.emit('onSlideNextStart', s);\n                    }\n                    else {\n                        s.emit('onSlidePrevStart', s);\n                    }\n                }\n        \n            }\n        };\n        s.onTransitionEnd = function (runCallbacks) {\n            s.animating = false;\n            s.setWrapperTransition(0);\n            if (typeof runCallbacks === 'undefined') runCallbacks = true;\n            if (s.lazy) s.lazy.onTransitionEnd();\n            if (runCallbacks) {\n                s.emit('onTransitionEnd', s);\n                if (s.activeIndex !== s.previousIndex) {\n                    s.emit('onSlideChangeEnd', s);\n                    if (s.activeIndex > s.previousIndex) {\n                        s.emit('onSlideNextEnd', s);\n                    }\n                    else {\n                        s.emit('onSlidePrevEnd', s);\n                    }\n                }\n            }\n            if (s.params.hashnav && s.hashnav) {\n                s.hashnav.setHash();\n            }\n        \n        };\n        s.slideNext = function (runCallbacks, speed, internal) {\n            if (s.params.loop) {\n                if (s.animating) return false;\n                s.fixLoop();\n                var clientLeft = s.container[0].clientLeft;\n                return s.slideTo(s.activeIndex + s.params.slidesPerGroup, speed, runCallbacks, internal);\n            }\n            else return s.slideTo(s.activeIndex + s.params.slidesPerGroup, speed, runCallbacks, internal);\n        };\n        s._slideNext = function (speed) {\n            return s.slideNext(true, speed, true);\n        };\n        s.slidePrev = function (runCallbacks, speed, internal) {\n            if (s.params.loop) {\n                if (s.animating) return false;\n                s.fixLoop();\n                var clientLeft = s.container[0].clientLeft;\n                return s.slideTo(s.activeIndex - 1, speed, runCallbacks, internal);\n            }\n            else return s.slideTo(s.activeIndex - 1, speed, runCallbacks, internal);\n        };\n        s._slidePrev = function (speed) {\n            return s.slidePrev(true, speed, true);\n        };\n        s.slideReset = function (runCallbacks, speed, internal) {\n            return s.slideTo(s.activeIndex, speed, runCallbacks);\n        };\n        \n        /*=========================\n          Translate/transition helpers\n          ===========================*/\n        s.setWrapperTransition = function (duration, byController) {\n            s.wrapper.transition(duration);\n            if (s.params.effect !== 'slide' && s.effects[s.params.effect]) {\n                s.effects[s.params.effect].setTransition(duration);\n            }\n            if (s.params.parallax && s.parallax) {\n                s.parallax.setTransition(duration);\n            }\n            if (s.params.scrollbar && s.scrollbar) {\n                s.scrollbar.setTransition(duration);\n            }\n            if (s.params.control && s.controller) {\n                s.controller.setTransition(duration, byController);\n            }\n            s.emit('onSetTransition', s, duration);\n        };\n        s.setWrapperTranslate = function (translate, updateActiveIndex, byController) {\n            var x = 0, y = 0, z = 0;\n            if (s.isHorizontal()) {\n                x = s.rtl ? -translate : translate;\n            }\n            else {\n                y = translate;\n            }\n        \n            if (s.params.roundLengths) {\n                x = round(x);\n                y = round(y);\n            }\n        \n            if (!s.params.virtualTranslate) {\n                if (s.support.transforms3d) s.wrapper.transform('translate3d(' + x + 'px, ' + y + 'px, ' + z + 'px)');\n                else s.wrapper.transform('translate(' + x + 'px, ' + y + 'px)');\n            }\n        \n            s.translate = s.isHorizontal() ? x : y;\n        \n            // Check if we need to update progress\n            var progress;\n            var translatesDiff = s.maxTranslate() - s.minTranslate();\n            if (translatesDiff === 0) {\n                progress = 0;\n            }\n            else {\n                progress = (translate - s.minTranslate()) / (translatesDiff);\n            }\n            if (progress !== s.progress) {\n                s.updateProgress(translate);\n            }\n        \n            if (updateActiveIndex) s.updateActiveIndex();\n            if (s.params.effect !== 'slide' && s.effects[s.params.effect]) {\n                s.effects[s.params.effect].setTranslate(s.translate);\n            }\n            if (s.params.parallax && s.parallax) {\n                s.parallax.setTranslate(s.translate);\n            }\n            if (s.params.scrollbar && s.scrollbar) {\n                s.scrollbar.setTranslate(s.translate);\n            }\n            if (s.params.control && s.controller) {\n                s.controller.setTranslate(s.translate, byController);\n            }\n            s.emit('onSetTranslate', s, s.translate);\n        };\n        \n        s.getTranslate = function (el, axis) {\n            var matrix, curTransform, curStyle, transformMatrix;\n        \n            // automatic axis detection\n            if (typeof axis === 'undefined') {\n                axis = 'x';\n            }\n        \n            if (s.params.virtualTranslate) {\n                return s.rtl ? -s.translate : s.translate;\n            }\n        \n            curStyle = window.getComputedStyle(el, null);\n            if (window.WebKitCSSMatrix) {\n                curTransform = curStyle.transform || curStyle.webkitTransform;\n                if (curTransform.split(',').length > 6) {\n                    curTransform = curTransform.split(', ').map(function(a){\n                        return a.replace(',','.');\n                    }).join(', ');\n                }\n                // Some old versions of Webkit choke when 'none' is passed; pass\n                // empty string instead in this case\n                transformMatrix = new window.WebKitCSSMatrix(curTransform === 'none' ? '' : curTransform);\n            }\n            else {\n                transformMatrix = curStyle.MozTransform || curStyle.OTransform || curStyle.MsTransform || curStyle.msTransform  || curStyle.transform || curStyle.getPropertyValue('transform').replace('translate(', 'matrix(1, 0, 0, 1,');\n                matrix = transformMatrix.toString().split(',');\n            }\n        \n            if (axis === 'x') {\n                //Latest Chrome and webkits Fix\n                if (window.WebKitCSSMatrix)\n                    curTransform = transformMatrix.m41;\n                //Crazy IE10 Matrix\n                else if (matrix.length === 16)\n                    curTransform = parseFloat(matrix[12]);\n                //Normal Browsers\n                else\n                    curTransform = parseFloat(matrix[4]);\n            }\n            if (axis === 'y') {\n                //Latest Chrome and webkits Fix\n                if (window.WebKitCSSMatrix)\n                    curTransform = transformMatrix.m42;\n                //Crazy IE10 Matrix\n                else if (matrix.length === 16)\n                    curTransform = parseFloat(matrix[13]);\n                //Normal Browsers\n                else\n                    curTransform = parseFloat(matrix[5]);\n            }\n            if (s.rtl && curTransform) curTransform = -curTransform;\n            return curTransform || 0;\n        };\n        s.getWrapperTranslate = function (axis) {\n            if (typeof axis === 'undefined') {\n                axis = s.isHorizontal() ? 'x' : 'y';\n            }\n            return s.getTranslate(s.wrapper[0], axis);\n        };\n        \n        /*=========================\n          Observer\n          ===========================*/\n        s.observers = [];\n        function initObserver(target, options) {\n            options = options || {};\n            // create an observer instance\n            var ObserverFunc = window.MutationObserver || window.WebkitMutationObserver;\n            var observer = new ObserverFunc(function (mutations) {\n                mutations.forEach(function (mutation) {\n                    s.onResize(true);\n                    s.emit('onObserverUpdate', s, mutation);\n                });\n            });\n        \n            observer.observe(target, {\n                attributes: typeof options.attributes === 'undefined' ? true : options.attributes,\n                childList: typeof options.childList === 'undefined' ? true : options.childList,\n                characterData: typeof options.characterData === 'undefined' ? true : options.characterData\n            });\n        \n            s.observers.push(observer);\n        }\n        s.initObservers = function () {\n            if (s.params.observeParents) {\n                var containerParents = s.container.parents();\n                for (var i = 0; i < containerParents.length; i++) {\n                    initObserver(containerParents[i]);\n                }\n            }\n        \n            // Observe container\n            initObserver(s.container[0], {childList: false});\n        \n            // Observe wrapper\n            initObserver(s.wrapper[0], {attributes: false});\n        };\n        s.disconnectObservers = function () {\n            for (var i = 0; i < s.observers.length; i++) {\n                s.observers[i].disconnect();\n            }\n            s.observers = [];\n        };\n        /*=========================\n          Loop\n          ===========================*/\n        // Create looped slides\n        s.createLoop = function () {\n            // Remove duplicated slides\n            s.wrapper.children('.' + s.params.slideClass + '.' + s.params.slideDuplicateClass).remove();\n        \n            var slides = s.wrapper.children('.' + s.params.slideClass);\n        \n            if(s.params.slidesPerView === 'auto' && !s.params.loopedSlides) s.params.loopedSlides = slides.length;\n        \n            s.loopedSlides = parseInt(s.params.loopedSlides || s.params.slidesPerView, 10);\n            s.loopedSlides = s.loopedSlides + s.params.loopAdditionalSlides;\n            if (s.loopedSlides > slides.length) {\n                s.loopedSlides = slides.length;\n            }\n        \n            var prependSlides = [], appendSlides = [], i;\n            slides.each(function (index, el) {\n                var slide = $(this);\n                if (index < s.loopedSlides) appendSlides.push(el);\n                if (index < slides.length && index >= slides.length - s.loopedSlides) prependSlides.push(el);\n                slide.attr('data-swiper-slide-index', index);\n            });\n            for (i = 0; i < appendSlides.length; i++) {\n                s.wrapper.append($(appendSlides[i].cloneNode(true)).addClass(s.params.slideDuplicateClass));\n            }\n            for (i = prependSlides.length - 1; i >= 0; i--) {\n                s.wrapper.prepend($(prependSlides[i].cloneNode(true)).addClass(s.params.slideDuplicateClass));\n            }\n        };\n        s.destroyLoop = function () {\n            s.wrapper.children('.' + s.params.slideClass + '.' + s.params.slideDuplicateClass).remove();\n            s.slides.removeAttr('data-swiper-slide-index');\n        };\n        s.reLoop = function (updatePosition) {\n            var oldIndex = s.activeIndex - s.loopedSlides;\n            s.destroyLoop();\n            s.createLoop();\n            s.updateSlidesSize();\n            if (updatePosition) {\n                s.slideTo(oldIndex + s.loopedSlides, 0, false);\n            }\n        \n        };\n        s.fixLoop = function () {\n            var newIndex;\n            //Fix For Negative Oversliding\n            if (s.activeIndex < s.loopedSlides) {\n                newIndex = s.slides.length - s.loopedSlides * 3 + s.activeIndex;\n                newIndex = newIndex + s.loopedSlides;\n                s.slideTo(newIndex, 0, false, true);\n            }\n            //Fix For Positive Oversliding\n            else if ((s.params.slidesPerView === 'auto' && s.activeIndex >= s.loopedSlides * 2) || (s.activeIndex > s.slides.length - s.params.slidesPerView * 2)) {\n                newIndex = -s.slides.length + s.activeIndex + s.loopedSlides;\n                newIndex = newIndex + s.loopedSlides;\n                s.slideTo(newIndex, 0, false, true);\n            }\n        };\n        /*=========================\n          Append/Prepend/Remove Slides\n          ===========================*/\n        s.appendSlide = function (slides) {\n            if (s.params.loop) {\n                s.destroyLoop();\n            }\n            if (typeof slides === 'object' && slides.length) {\n                for (var i = 0; i < slides.length; i++) {\n                    if (slides[i]) s.wrapper.append(slides[i]);\n                }\n            }\n            else {\n                s.wrapper.append(slides);\n            }\n            if (s.params.loop) {\n                s.createLoop();\n            }\n            if (!(s.params.observer && s.support.observer)) {\n                s.update(true);\n            }\n        };\n        s.prependSlide = function (slides) {\n            if (s.params.loop) {\n                s.destroyLoop();\n            }\n            var newActiveIndex = s.activeIndex + 1;\n            if (typeof slides === 'object' && slides.length) {\n                for (var i = 0; i < slides.length; i++) {\n                    if (slides[i]) s.wrapper.prepend(slides[i]);\n                }\n                newActiveIndex = s.activeIndex + slides.length;\n            }\n            else {\n                s.wrapper.prepend(slides);\n            }\n            if (s.params.loop) {\n                s.createLoop();\n            }\n            if (!(s.params.observer && s.support.observer)) {\n                s.update(true);\n            }\n            s.slideTo(newActiveIndex, 0, false);\n        };\n        s.removeSlide = function (slidesIndexes) {\n            if (s.params.loop) {\n                s.destroyLoop();\n                s.slides = s.wrapper.children('.' + s.params.slideClass);\n            }\n            var newActiveIndex = s.activeIndex,\n                indexToRemove;\n            if (typeof slidesIndexes === 'object' && slidesIndexes.length) {\n                for (var i = 0; i < slidesIndexes.length; i++) {\n                    indexToRemove = slidesIndexes[i];\n                    if (s.slides[indexToRemove]) s.slides.eq(indexToRemove).remove();\n                    if (indexToRemove < newActiveIndex) newActiveIndex--;\n                }\n                newActiveIndex = Math.max(newActiveIndex, 0);\n            }\n            else {\n                indexToRemove = slidesIndexes;\n                if (s.slides[indexToRemove]) s.slides.eq(indexToRemove).remove();\n                if (indexToRemove < newActiveIndex) newActiveIndex--;\n                newActiveIndex = Math.max(newActiveIndex, 0);\n            }\n        \n            if (s.params.loop) {\n                s.createLoop();\n            }\n        \n            if (!(s.params.observer && s.support.observer)) {\n                s.update(true);\n            }\n            if (s.params.loop) {\n                s.slideTo(newActiveIndex + s.loopedSlides, 0, false);\n            }\n            else {\n                s.slideTo(newActiveIndex, 0, false);\n            }\n        \n        };\n        s.removeAllSlides = function () {\n            var slidesIndexes = [];\n            for (var i = 0; i < s.slides.length; i++) {\n                slidesIndexes.push(i);\n            }\n            s.removeSlide(slidesIndexes);\n        };\n        \n\n        /*=========================\n          Effects\n          ===========================*/\n        s.effects = {\n            fade: {\n                setTranslate: function () {\n                    for (var i = 0; i < s.slides.length; i++) {\n                        var slide = s.slides.eq(i);\n                        var offset = slide[0].swiperSlideOffset;\n                        var tx = -offset;\n                        if (!s.params.virtualTranslate) tx = tx - s.translate;\n                        var ty = 0;\n                        if (!s.isHorizontal()) {\n                            ty = tx;\n                            tx = 0;\n                        }\n                        var slideOpacity = s.params.fade.crossFade ?\n                                Math.max(1 - Math.abs(slide[0].progress), 0) :\n                                1 + Math.min(Math.max(slide[0].progress, -1), 0);\n                        slide\n                            .css({\n                                opacity: slideOpacity\n                            })\n                            .transform('translate3d(' + tx + 'px, ' + ty + 'px, 0px)');\n        \n                    }\n        \n                },\n                setTransition: function (duration) {\n                    s.slides.transition(duration);\n                    if (s.params.virtualTranslate && duration !== 0) {\n                        var eventTriggered = false;\n                        s.slides.transitionEnd(function () {\n                            if (eventTriggered) return;\n                            if (!s) return;\n                            eventTriggered = true;\n                            s.animating = false;\n                            var triggerEvents = ['webkitTransitionEnd', 'transitionend', 'oTransitionEnd', 'MSTransitionEnd', 'msTransitionEnd'];\n                            for (var i = 0; i < triggerEvents.length; i++) {\n                                s.wrapper.trigger(triggerEvents[i]);\n                            }\n                        });\n                    }\n                }\n            },\n            flip: {\n                setTranslate: function () {\n                    for (var i = 0; i < s.slides.length; i++) {\n                        var slide = s.slides.eq(i);\n                        var progress = slide[0].progress;\n                        if (s.params.flip.limitRotation) {\n                            progress = Math.max(Math.min(slide[0].progress, 1), -1);\n                        }\n                        var offset = slide[0].swiperSlideOffset;\n                        var rotate = -180 * progress,\n                            rotateY = rotate,\n                            rotateX = 0,\n                            tx = -offset,\n                            ty = 0;\n                        if (!s.isHorizontal()) {\n                            ty = tx;\n                            tx = 0;\n                            rotateX = -rotateY;\n                            rotateY = 0;\n                        }\n                        else if (s.rtl) {\n                            rotateY = -rotateY;\n                        }\n        \n                        slide[0].style.zIndex = -Math.abs(Math.round(progress)) + s.slides.length;\n        \n                        if (s.params.flip.slideShadows) {\n                            //Set shadows\n                            var shadowBefore = s.isHorizontal() ? slide.find('.swiper-slide-shadow-left') : slide.find('.swiper-slide-shadow-top');\n                            var shadowAfter = s.isHorizontal() ? slide.find('.swiper-slide-shadow-right') : slide.find('.swiper-slide-shadow-bottom');\n                            if (shadowBefore.length === 0) {\n                                shadowBefore = $('<div class=\"swiper-slide-shadow-' + (s.isHorizontal() ? 'left' : 'top') + '\"></div>');\n                                slide.append(shadowBefore);\n                            }\n                            if (shadowAfter.length === 0) {\n                                shadowAfter = $('<div class=\"swiper-slide-shadow-' + (s.isHorizontal() ? 'right' : 'bottom') + '\"></div>');\n                                slide.append(shadowAfter);\n                            }\n                            if (shadowBefore.length) shadowBefore[0].style.opacity = Math.max(-progress, 0);\n                            if (shadowAfter.length) shadowAfter[0].style.opacity = Math.max(progress, 0);\n                        }\n        \n                        slide\n                            .transform('translate3d(' + tx + 'px, ' + ty + 'px, 0px) rotateX(' + rotateX + 'deg) rotateY(' + rotateY + 'deg)');\n                    }\n                },\n                setTransition: function (duration) {\n                    s.slides.transition(duration).find('.swiper-slide-shadow-top, .swiper-slide-shadow-right, .swiper-slide-shadow-bottom, .swiper-slide-shadow-left').transition(duration);\n                    if (s.params.virtualTranslate && duration !== 0) {\n                        var eventTriggered = false;\n                        s.slides.eq(s.activeIndex).transitionEnd(function () {\n                            if (eventTriggered) return;\n                            if (!s) return;\n                            if (!$(this).hasClass(s.params.slideActiveClass)) return;\n                            eventTriggered = true;\n                            s.animating = false;\n                            var triggerEvents = ['webkitTransitionEnd', 'transitionend', 'oTransitionEnd', 'MSTransitionEnd', 'msTransitionEnd'];\n                            for (var i = 0; i < triggerEvents.length; i++) {\n                                s.wrapper.trigger(triggerEvents[i]);\n                            }\n                        });\n                    }\n                }\n            },\n            cube: {\n                setTranslate: function () {\n                    var wrapperRotate = 0, cubeShadow;\n                    if (s.params.cube.shadow) {\n                        if (s.isHorizontal()) {\n                            cubeShadow = s.wrapper.find('.swiper-cube-shadow');\n                            if (cubeShadow.length === 0) {\n                                cubeShadow = $('<div class=\"swiper-cube-shadow\"></div>');\n                                s.wrapper.append(cubeShadow);\n                            }\n                            cubeShadow.css({height: s.width + 'px'});\n                        }\n                        else {\n                            cubeShadow = s.container.find('.swiper-cube-shadow');\n                            if (cubeShadow.length === 0) {\n                                cubeShadow = $('<div class=\"swiper-cube-shadow\"></div>');\n                                s.container.append(cubeShadow);\n                            }\n                        }\n                    }\n                    for (var i = 0; i < s.slides.length; i++) {\n                        var slide = s.slides.eq(i);\n                        var slideAngle = i * 90;\n                        var round = Math.floor(slideAngle / 360);\n                        if (s.rtl) {\n                            slideAngle = -slideAngle;\n                            round = Math.floor(-slideAngle / 360);\n                        }\n                        var progress = Math.max(Math.min(slide[0].progress, 1), -1);\n                        var tx = 0, ty = 0, tz = 0;\n                        if (i % 4 === 0) {\n                            tx = - round * 4 * s.size;\n                            tz = 0;\n                        }\n                        else if ((i - 1) % 4 === 0) {\n                            tx = 0;\n                            tz = - round * 4 * s.size;\n                        }\n                        else if ((i - 2) % 4 === 0) {\n                            tx = s.size + round * 4 * s.size;\n                            tz = s.size;\n                        }\n                        else if ((i - 3) % 4 === 0) {\n                            tx = - s.size;\n                            tz = 3 * s.size + s.size * 4 * round;\n                        }\n                        if (s.rtl) {\n                            tx = -tx;\n                        }\n        \n                        if (!s.isHorizontal()) {\n                            ty = tx;\n                            tx = 0;\n                        }\n        \n                        var transform = 'rotateX(' + (s.isHorizontal() ? 0 : -slideAngle) + 'deg) rotateY(' + (s.isHorizontal() ? slideAngle : 0) + 'deg) translate3d(' + tx + 'px, ' + ty + 'px, ' + tz + 'px)';\n                        if (progress <= 1 && progress > -1) {\n                            wrapperRotate = i * 90 + progress * 90;\n                            if (s.rtl) wrapperRotate = -i * 90 - progress * 90;\n                        }\n                        slide.transform(transform);\n                        if (s.params.cube.slideShadows) {\n                            //Set shadows\n                            var shadowBefore = s.isHorizontal() ? slide.find('.swiper-slide-shadow-left') : slide.find('.swiper-slide-shadow-top');\n                            var shadowAfter = s.isHorizontal() ? slide.find('.swiper-slide-shadow-right') : slide.find('.swiper-slide-shadow-bottom');\n                            if (shadowBefore.length === 0) {\n                                shadowBefore = $('<div class=\"swiper-slide-shadow-' + (s.isHorizontal() ? 'left' : 'top') + '\"></div>');\n                                slide.append(shadowBefore);\n                            }\n                            if (shadowAfter.length === 0) {\n                                shadowAfter = $('<div class=\"swiper-slide-shadow-' + (s.isHorizontal() ? 'right' : 'bottom') + '\"></div>');\n                                slide.append(shadowAfter);\n                            }\n                            if (shadowBefore.length) shadowBefore[0].style.opacity = Math.max(-progress, 0);\n                            if (shadowAfter.length) shadowAfter[0].style.opacity = Math.max(progress, 0);\n                        }\n                    }\n                    s.wrapper.css({\n                        '-webkit-transform-origin': '50% 50% -' + (s.size / 2) + 'px',\n                        '-moz-transform-origin': '50% 50% -' + (s.size / 2) + 'px',\n                        '-ms-transform-origin': '50% 50% -' + (s.size / 2) + 'px',\n                        'transform-origin': '50% 50% -' + (s.size / 2) + 'px'\n                    });\n        \n                    if (s.params.cube.shadow) {\n                        if (s.isHorizontal()) {\n                            cubeShadow.transform('translate3d(0px, ' + (s.width / 2 + s.params.cube.shadowOffset) + 'px, ' + (-s.width / 2) + 'px) rotateX(90deg) rotateZ(0deg) scale(' + (s.params.cube.shadowScale) + ')');\n                        }\n                        else {\n                            var shadowAngle = Math.abs(wrapperRotate) - Math.floor(Math.abs(wrapperRotate) / 90) * 90;\n                            var multiplier = 1.5 - (Math.sin(shadowAngle * 2 * Math.PI / 360) / 2 + Math.cos(shadowAngle * 2 * Math.PI / 360) / 2);\n                            var scale1 = s.params.cube.shadowScale,\n                                scale2 = s.params.cube.shadowScale / multiplier,\n                                offset = s.params.cube.shadowOffset;\n                            cubeShadow.transform('scale3d(' + scale1 + ', 1, ' + scale2 + ') translate3d(0px, ' + (s.height / 2 + offset) + 'px, ' + (-s.height / 2 / scale2) + 'px) rotateX(-90deg)');\n                        }\n                    }\n                    var zFactor = (s.isSafari || s.isUiWebView) ? (-s.size / 2) : 0;\n                    s.wrapper.transform('translate3d(0px,0,' + zFactor + 'px) rotateX(' + (s.isHorizontal() ? 0 : wrapperRotate) + 'deg) rotateY(' + (s.isHorizontal() ? -wrapperRotate : 0) + 'deg)');\n                },\n                setTransition: function (duration) {\n                    s.slides.transition(duration).find('.swiper-slide-shadow-top, .swiper-slide-shadow-right, .swiper-slide-shadow-bottom, .swiper-slide-shadow-left').transition(duration);\n                    if (s.params.cube.shadow && !s.isHorizontal()) {\n                        s.container.find('.swiper-cube-shadow').transition(duration);\n                    }\n                }\n            },\n            coverflow: {\n                setTranslate: function () {\n                    var transform = s.translate;\n                    var center = s.isHorizontal() ? -transform + s.width / 2 : -transform + s.height / 2;\n                    var rotate = s.isHorizontal() ? s.params.coverflow.rotate: -s.params.coverflow.rotate;\n                    var translate = s.params.coverflow.depth;\n                    //Each slide offset from center\n                    for (var i = 0, length = s.slides.length; i < length; i++) {\n                        var slide = s.slides.eq(i);\n                        var slideSize = s.slidesSizesGrid[i];\n                        var slideOffset = slide[0].swiperSlideOffset;\n                        var offsetMultiplier = (center - slideOffset - slideSize / 2) / slideSize * s.params.coverflow.modifier;\n        \n                        var rotateY = s.isHorizontal() ? rotate * offsetMultiplier : 0;\n                        var rotateX = s.isHorizontal() ? 0 : rotate * offsetMultiplier;\n                        // var rotateZ = 0\n                        var translateZ = -translate * Math.abs(offsetMultiplier);\n        \n                        var translateY = s.isHorizontal() ? 0 : s.params.coverflow.stretch * (offsetMultiplier);\n                        var translateX = s.isHorizontal() ? s.params.coverflow.stretch * (offsetMultiplier) : 0;\n        \n                        //Fix for ultra small values\n                        if (Math.abs(translateX) < 0.001) translateX = 0;\n                        if (Math.abs(translateY) < 0.001) translateY = 0;\n                        if (Math.abs(translateZ) < 0.001) translateZ = 0;\n                        if (Math.abs(rotateY) < 0.001) rotateY = 0;\n                        if (Math.abs(rotateX) < 0.001) rotateX = 0;\n        \n                        var slideTransform = 'translate3d(' + translateX + 'px,' + translateY + 'px,' + translateZ + 'px)  rotateX(' + rotateX + 'deg) rotateY(' + rotateY + 'deg)';\n        \n                        slide.transform(slideTransform);\n                        slide[0].style.zIndex = -Math.abs(Math.round(offsetMultiplier)) + 1;\n                        if (s.params.coverflow.slideShadows) {\n                            //Set shadows\n                            var shadowBefore = s.isHorizontal() ? slide.find('.swiper-slide-shadow-left') : slide.find('.swiper-slide-shadow-top');\n                            var shadowAfter = s.isHorizontal() ? slide.find('.swiper-slide-shadow-right') : slide.find('.swiper-slide-shadow-bottom');\n                            if (shadowBefore.length === 0) {\n                                shadowBefore = $('<div class=\"swiper-slide-shadow-' + (s.isHorizontal() ? 'left' : 'top') + '\"></div>');\n                                slide.append(shadowBefore);\n                            }\n                            if (shadowAfter.length === 0) {\n                                shadowAfter = $('<div class=\"swiper-slide-shadow-' + (s.isHorizontal() ? 'right' : 'bottom') + '\"></div>');\n                                slide.append(shadowAfter);\n                            }\n                            if (shadowBefore.length) shadowBefore[0].style.opacity = offsetMultiplier > 0 ? offsetMultiplier : 0;\n                            if (shadowAfter.length) shadowAfter[0].style.opacity = (-offsetMultiplier) > 0 ? -offsetMultiplier : 0;\n                        }\n                    }\n        \n                    //Set correct perspective for IE10\n                    if (s.browser.ie) {\n                        var ws = s.wrapper[0].style;\n                        ws.perspectiveOrigin = center + 'px 50%';\n                    }\n                },\n                setTransition: function (duration) {\n                    s.slides.transition(duration).find('.swiper-slide-shadow-top, .swiper-slide-shadow-right, .swiper-slide-shadow-bottom, .swiper-slide-shadow-left').transition(duration);\n                }\n            }\n        };\n\n        /*=========================\n          Images Lazy Loading\n          ===========================*/\n        s.lazy = {\n            initialImageLoaded: false,\n            loadImageInSlide: function (index, loadInDuplicate) {\n                if (typeof index === 'undefined') return;\n                if (typeof loadInDuplicate === 'undefined') loadInDuplicate = true;\n                if (s.slides.length === 0) return;\n        \n                var slide = s.slides.eq(index);\n                var img = slide.find('.swiper-lazy:not(.swiper-lazy-loaded):not(.swiper-lazy-loading)');\n                if (slide.hasClass('swiper-lazy') && !slide.hasClass('swiper-lazy-loaded') && !slide.hasClass('swiper-lazy-loading')) {\n                    img = img.add(slide[0]);\n                }\n                if (img.length === 0) return;\n        \n                img.each(function () {\n                    var _img = $(this);\n                    _img.addClass('swiper-lazy-loading');\n                    var background = _img.attr('data-background');\n                    var src = _img.attr('data-src'),\n                        srcset = _img.attr('data-srcset');\n                    s.loadImage(_img[0], (src || background), srcset, false, function () {\n                        if (background) {\n                            _img.css('background-image', 'url(\"' + background + '\")');\n                            _img.removeAttr('data-background');\n                        }\n                        else {\n                            if (srcset) {\n                                _img.attr('srcset', srcset);\n                                _img.removeAttr('data-srcset');\n                            }\n                            if (src) {\n                                _img.attr('src', src);\n                                _img.removeAttr('data-src');\n                            }\n        \n                        }\n        \n                        _img.addClass('swiper-lazy-loaded').removeClass('swiper-lazy-loading');\n                        slide.find('.swiper-lazy-preloader, .preloader').remove();\n                        if (s.params.loop && loadInDuplicate) {\n                            var slideOriginalIndex = slide.attr('data-swiper-slide-index');\n                            if (slide.hasClass(s.params.slideDuplicateClass)) {\n                                var originalSlide = s.wrapper.children('[data-swiper-slide-index=\"' + slideOriginalIndex + '\"]:not(.' + s.params.slideDuplicateClass + ')');\n                                s.lazy.loadImageInSlide(originalSlide.index(), false);\n                            }\n                            else {\n                                var duplicatedSlide = s.wrapper.children('.' + s.params.slideDuplicateClass + '[data-swiper-slide-index=\"' + slideOriginalIndex + '\"]');\n                                s.lazy.loadImageInSlide(duplicatedSlide.index(), false);\n                            }\n                        }\n                        s.emit('onLazyImageReady', s, slide[0], _img[0]);\n                    });\n        \n                    s.emit('onLazyImageLoad', s, slide[0], _img[0]);\n                });\n        \n            },\n            load: function () {\n                var i;\n                if (s.params.watchSlidesVisibility) {\n                    s.wrapper.children('.' + s.params.slideVisibleClass).each(function () {\n                        s.lazy.loadImageInSlide($(this).index());\n                    });\n                }\n                else {\n                    if (s.params.slidesPerView > 1) {\n                        for (i = s.activeIndex; i < s.activeIndex + s.params.slidesPerView ; i++) {\n                            if (s.slides[i]) s.lazy.loadImageInSlide(i);\n                        }\n                    }\n                    else {\n                        s.lazy.loadImageInSlide(s.activeIndex);\n                    }\n                }\n                if (s.params.lazyLoadingInPrevNext) {\n                    if (s.params.slidesPerView > 1 || (s.params.lazyLoadingInPrevNextAmount && s.params.lazyLoadingInPrevNextAmount > 1)) {\n                        var amount = s.params.lazyLoadingInPrevNextAmount;\n                        var spv = s.params.slidesPerView;\n                        var maxIndex = Math.min(s.activeIndex + spv + Math.max(amount, spv), s.slides.length);\n                        var minIndex = Math.max(s.activeIndex - Math.max(spv, amount), 0);\n                        // Next Slides\n                        for (i = s.activeIndex + s.params.slidesPerView; i < maxIndex; i++) {\n                            if (s.slides[i]) s.lazy.loadImageInSlide(i);\n                        }\n                        // Prev Slides\n                        for (i = minIndex; i < s.activeIndex ; i++) {\n                            if (s.slides[i]) s.lazy.loadImageInSlide(i);\n                        }\n                    }\n                    else {\n                        var nextSlide = s.wrapper.children('.' + s.params.slideNextClass);\n                        if (nextSlide.length > 0) s.lazy.loadImageInSlide(nextSlide.index());\n        \n                        var prevSlide = s.wrapper.children('.' + s.params.slidePrevClass);\n                        if (prevSlide.length > 0) s.lazy.loadImageInSlide(prevSlide.index());\n                    }\n                }\n            },\n            onTransitionStart: function () {\n                if (s.params.lazyLoading) {\n                    if (s.params.lazyLoadingOnTransitionStart || (!s.params.lazyLoadingOnTransitionStart && !s.lazy.initialImageLoaded)) {\n                        s.lazy.load();\n                    }\n                }\n            },\n            onTransitionEnd: function () {\n                if (s.params.lazyLoading && !s.params.lazyLoadingOnTransitionStart) {\n                    s.lazy.load();\n                }\n            }\n        };\n        \n\n        /*=========================\n          Scrollbar\n          ===========================*/\n        s.scrollbar = {\n            isTouched: false,\n            setDragPosition: function (e) {\n                var sb = s.scrollbar;\n                var x = 0, y = 0;\n                var translate;\n                var pointerPosition = s.isHorizontal() ?\n                    ((e.type === 'touchstart' || e.type === 'touchmove') ? e.targetTouches[0].pageX : e.pageX || e.clientX) :\n                    ((e.type === 'touchstart' || e.type === 'touchmove') ? e.targetTouches[0].pageY : e.pageY || e.clientY) ;\n                var position = (pointerPosition) - sb.track.offset()[s.isHorizontal() ? 'left' : 'top'] - sb.dragSize / 2;\n                var positionMin = -s.minTranslate() * sb.moveDivider;\n                var positionMax = -s.maxTranslate() * sb.moveDivider;\n                if (position < positionMin) {\n                    position = positionMin;\n                }\n                else if (position > positionMax) {\n                    position = positionMax;\n                }\n                position = -position / sb.moveDivider;\n                s.updateProgress(position);\n                s.setWrapperTranslate(position, true);\n            },\n            dragStart: function (e) {\n                var sb = s.scrollbar;\n                sb.isTouched = true;\n                e.preventDefault();\n                e.stopPropagation();\n        \n                sb.setDragPosition(e);\n                clearTimeout(sb.dragTimeout);\n        \n                sb.track.transition(0);\n                if (s.params.scrollbarHide) {\n                    sb.track.css('opacity', 1);\n                }\n                s.wrapper.transition(100);\n                sb.drag.transition(100);\n                s.emit('onScrollbarDragStart', s);\n            },\n            dragMove: function (e) {\n                var sb = s.scrollbar;\n                if (!sb.isTouched) return;\n                if (e.preventDefault) e.preventDefault();\n                else e.returnValue = false;\n                sb.setDragPosition(e);\n                s.wrapper.transition(0);\n                sb.track.transition(0);\n                sb.drag.transition(0);\n                s.emit('onScrollbarDragMove', s);\n            },\n            dragEnd: function (e) {\n                var sb = s.scrollbar;\n                if (!sb.isTouched) return;\n                sb.isTouched = false;\n                if (s.params.scrollbarHide) {\n                    clearTimeout(sb.dragTimeout);\n                    sb.dragTimeout = setTimeout(function () {\n                        sb.track.css('opacity', 0);\n                        sb.track.transition(400);\n                    }, 1000);\n        \n                }\n                s.emit('onScrollbarDragEnd', s);\n                if (s.params.scrollbarSnapOnRelease) {\n                    s.slideReset();\n                }\n            },\n            enableDraggable: function () {\n                var sb = s.scrollbar;\n                var target = s.support.touch ? sb.track : document;\n                $(sb.track).on(s.touchEvents.start, sb.dragStart);\n                $(target).on(s.touchEvents.move, sb.dragMove);\n                $(target).on(s.touchEvents.end, sb.dragEnd);\n            },\n            disableDraggable: function () {\n                var sb = s.scrollbar;\n                var target = s.support.touch ? sb.track : document;\n                $(sb.track).off(s.touchEvents.start, sb.dragStart);\n                $(target).off(s.touchEvents.move, sb.dragMove);\n                $(target).off(s.touchEvents.end, sb.dragEnd);\n            },\n            set: function () {\n                if (!s.params.scrollbar) return;\n                var sb = s.scrollbar;\n                sb.track = $(s.params.scrollbar);\n                if (s.params.uniqueNavElements && typeof s.params.scrollbar === 'string' && sb.track.length > 1 && s.container.find(s.params.scrollbar).length === 1) {\n                    sb.track = s.container.find(s.params.scrollbar);\n                }\n                sb.drag = sb.track.find('.swiper-scrollbar-drag');\n                if (sb.drag.length === 0) {\n                    sb.drag = $('<div class=\"swiper-scrollbar-drag\"></div>');\n                    sb.track.append(sb.drag);\n                }\n                sb.drag[0].style.width = '';\n                sb.drag[0].style.height = '';\n                sb.trackSize = s.isHorizontal() ? sb.track[0].offsetWidth : sb.track[0].offsetHeight;\n        \n                sb.divider = s.size / s.virtualSize;\n                sb.moveDivider = sb.divider * (sb.trackSize / s.size);\n                sb.dragSize = sb.trackSize * sb.divider;\n        \n                if (s.isHorizontal()) {\n                    sb.drag[0].style.width = sb.dragSize + 'px';\n                }\n                else {\n                    sb.drag[0].style.height = sb.dragSize + 'px';\n                }\n        \n                if (sb.divider >= 1) {\n                    sb.track[0].style.display = 'none';\n                }\n                else {\n                    sb.track[0].style.display = '';\n                }\n                if (s.params.scrollbarHide) {\n                    sb.track[0].style.opacity = 0;\n                }\n            },\n            setTranslate: function () {\n                if (!s.params.scrollbar) return;\n                var diff;\n                var sb = s.scrollbar;\n                var translate = s.translate || 0;\n                var newPos;\n        \n                var newSize = sb.dragSize;\n                newPos = (sb.trackSize - sb.dragSize) * s.progress;\n                if (s.rtl && s.isHorizontal()) {\n                    newPos = -newPos;\n                    if (newPos > 0) {\n                        newSize = sb.dragSize - newPos;\n                        newPos = 0;\n                    }\n                    else if (-newPos + sb.dragSize > sb.trackSize) {\n                        newSize = sb.trackSize + newPos;\n                    }\n                }\n                else {\n                    if (newPos < 0) {\n                        newSize = sb.dragSize + newPos;\n                        newPos = 0;\n                    }\n                    else if (newPos + sb.dragSize > sb.trackSize) {\n                        newSize = sb.trackSize - newPos;\n                    }\n                }\n                if (s.isHorizontal()) {\n                    if (s.support.transforms3d) {\n                        sb.drag.transform('translate3d(' + (newPos) + 'px, 0, 0)');\n                    }\n                    else {\n                        sb.drag.transform('translateX(' + (newPos) + 'px)');\n                    }\n                    sb.drag[0].style.width = newSize + 'px';\n                }\n                else {\n                    if (s.support.transforms3d) {\n                        sb.drag.transform('translate3d(0px, ' + (newPos) + 'px, 0)');\n                    }\n                    else {\n                        sb.drag.transform('translateY(' + (newPos) + 'px)');\n                    }\n                    sb.drag[0].style.height = newSize + 'px';\n                }\n                if (s.params.scrollbarHide) {\n                    clearTimeout(sb.timeout);\n                    sb.track[0].style.opacity = 1;\n                    sb.timeout = setTimeout(function () {\n                        sb.track[0].style.opacity = 0;\n                        sb.track.transition(400);\n                    }, 1000);\n                }\n            },\n            setTransition: function (duration) {\n                if (!s.params.scrollbar) return;\n                s.scrollbar.drag.transition(duration);\n            }\n        };\n\n        /*=========================\n          Controller\n          ===========================*/\n        s.controller = {\n            LinearSpline: function (x, y) {\n                this.x = x;\n                this.y = y;\n                this.lastIndex = x.length - 1;\n                // Given an x value (x2), return the expected y2 value:\n                // (x1,y1) is the known point before given value,\n                // (x3,y3) is the known point after given value.\n                var i1, i3;\n                var l = this.x.length;\n        \n                this.interpolate = function (x2) {\n                    if (!x2) return 0;\n        \n                    // Get the indexes of x1 and x3 (the array indexes before and after given x2):\n                    i3 = binarySearch(this.x, x2);\n                    i1 = i3 - 1;\n        \n                    // We have our indexes i1 & i3, so we can calculate already:\n                    // y2 := ((x2−x1) × (y3−y1)) ÷ (x3−x1) + y1\n                    return ((x2 - this.x[i1]) * (this.y[i3] - this.y[i1])) / (this.x[i3] - this.x[i1]) + this.y[i1];\n                };\n        \n                var binarySearch = (function() {\n                    var maxIndex, minIndex, guess;\n                    return function(array, val) {\n                        minIndex = -1;\n                        maxIndex = array.length;\n                        while (maxIndex - minIndex > 1)\n                            if (array[guess = maxIndex + minIndex >> 1] <= val) {\n                                minIndex = guess;\n                            } else {\n                                maxIndex = guess;\n                            }\n                        return maxIndex;\n                    };\n                })();\n            },\n            //xxx: for now i will just save one spline function to to\n            getInterpolateFunction: function(c){\n                if(!s.controller.spline) s.controller.spline = s.params.loop ?\n                    new s.controller.LinearSpline(s.slidesGrid, c.slidesGrid) :\n                    new s.controller.LinearSpline(s.snapGrid, c.snapGrid);\n            },\n            setTranslate: function (translate, byController) {\n               var controlled = s.params.control;\n               var multiplier, controlledTranslate;\n               function setControlledTranslate(c) {\n                    // this will create an Interpolate function based on the snapGrids\n                    // x is the Grid of the scrolled scroller and y will be the controlled scroller\n                    // it makes sense to create this only once and recall it for the interpolation\n                    // the function does a lot of value caching for performance\n                    translate = c.rtl && c.params.direction === 'horizontal' ? -s.translate : s.translate;\n                    if (s.params.controlBy === 'slide') {\n                        s.controller.getInterpolateFunction(c);\n                        // i am not sure why the values have to be multiplicated this way, tried to invert the snapGrid\n                        // but it did not work out\n                        controlledTranslate = -s.controller.spline.interpolate(-translate);\n                    }\n        \n                    if(!controlledTranslate || s.params.controlBy === 'container'){\n                        multiplier = (c.maxTranslate() - c.minTranslate()) / (s.maxTranslate() - s.minTranslate());\n                        controlledTranslate = (translate - s.minTranslate()) * multiplier + c.minTranslate();\n                    }\n        \n                    if (s.params.controlInverse) {\n                        controlledTranslate = c.maxTranslate() - controlledTranslate;\n                    }\n                    c.updateProgress(controlledTranslate);\n                    c.setWrapperTranslate(controlledTranslate, false, s);\n                    c.updateActiveIndex();\n               }\n               if (s.isArray(controlled)) {\n                   for (var i = 0; i < controlled.length; i++) {\n                       if (controlled[i] !== byController && controlled[i] instanceof Swiper) {\n                           setControlledTranslate(controlled[i]);\n                       }\n                   }\n               }\n               else if (controlled instanceof Swiper && byController !== controlled) {\n        \n                   setControlledTranslate(controlled);\n               }\n            },\n            setTransition: function (duration, byController) {\n                var controlled = s.params.control;\n                var i;\n                function setControlledTransition(c) {\n                    c.setWrapperTransition(duration, s);\n                    if (duration !== 0) {\n                        c.onTransitionStart();\n                        c.wrapper.transitionEnd(function(){\n                            if (!controlled) return;\n                            if (c.params.loop && s.params.controlBy === 'slide') {\n                                c.fixLoop();\n                            }\n                            c.onTransitionEnd();\n        \n                        });\n                    }\n                }\n                if (s.isArray(controlled)) {\n                    for (i = 0; i < controlled.length; i++) {\n                        if (controlled[i] !== byController && controlled[i] instanceof Swiper) {\n                            setControlledTransition(controlled[i]);\n                        }\n                    }\n                }\n                else if (controlled instanceof Swiper && byController !== controlled) {\n                    setControlledTransition(controlled);\n                }\n            }\n        };\n\n        /*=========================\n          Hash Navigation\n          ===========================*/\n        s.hashnav = {\n            init: function () {\n                if (!s.params.hashnav) return;\n                s.hashnav.initialized = true;\n                var hash = document.location.hash.replace('#', '');\n                if (!hash) return;\n                var speed = 0;\n                for (var i = 0, length = s.slides.length; i < length; i++) {\n                    var slide = s.slides.eq(i);\n                    var slideHash = slide.attr('data-hash');\n                    if (slideHash === hash && !slide.hasClass(s.params.slideDuplicateClass)) {\n                        var index = slide.index();\n                        s.slideTo(index, speed, s.params.runCallbacksOnInit, true);\n                    }\n                }\n            },\n            setHash: function () {\n                if (!s.hashnav.initialized || !s.params.hashnav) return;\n                document.location.hash = s.slides.eq(s.activeIndex).attr('data-hash') || '';\n            }\n        };\n\n        /*=========================\n          Keyboard Control\n          ===========================*/\n        function handleKeyboard(e) {\n            if (e.originalEvent) e = e.originalEvent; //jquery fix\n            var kc = e.keyCode || e.charCode;\n            // Directions locks\n            if (!s.params.allowSwipeToNext && (s.isHorizontal() && kc === 39 || !s.isHorizontal() && kc === 40)) {\n                return false;\n            }\n            if (!s.params.allowSwipeToPrev && (s.isHorizontal() && kc === 37 || !s.isHorizontal() && kc === 38)) {\n                return false;\n            }\n            if (e.shiftKey || e.altKey || e.ctrlKey || e.metaKey) {\n                return;\n            }\n            if (document.activeElement && document.activeElement.nodeName && (document.activeElement.nodeName.toLowerCase() === 'input' || document.activeElement.nodeName.toLowerCase() === 'textarea')) {\n                return;\n            }\n            if (kc === 37 || kc === 39 || kc === 38 || kc === 40) {\n                var inView = false;\n                //Check that swiper should be inside of visible area of window\n                if (s.container.parents('.swiper-slide').length > 0 && s.container.parents('.swiper-slide-active').length === 0) {\n                    return;\n                }\n                var windowScroll = {\n                    left: window.pageXOffset,\n                    top: window.pageYOffset\n                };\n                var windowWidth = window.innerWidth;\n                var windowHeight = window.innerHeight;\n                var swiperOffset = s.container.offset();\n                if (s.rtl) swiperOffset.left = swiperOffset.left - s.container[0].scrollLeft;\n                var swiperCoord = [\n                    [swiperOffset.left, swiperOffset.top],\n                    [swiperOffset.left + s.width, swiperOffset.top],\n                    [swiperOffset.left, swiperOffset.top + s.height],\n                    [swiperOffset.left + s.width, swiperOffset.top + s.height]\n                ];\n                for (var i = 0; i < swiperCoord.length; i++) {\n                    var point = swiperCoord[i];\n                    if (\n                        point[0] >= windowScroll.left && point[0] <= windowScroll.left + windowWidth &&\n                        point[1] >= windowScroll.top && point[1] <= windowScroll.top + windowHeight\n                    ) {\n                        inView = true;\n                    }\n        \n                }\n                if (!inView) return;\n            }\n            if (s.isHorizontal()) {\n                if (kc === 37 || kc === 39) {\n                    if (e.preventDefault) e.preventDefault();\n                    else e.returnValue = false;\n                }\n                if ((kc === 39 && !s.rtl) || (kc === 37 && s.rtl)) s.slideNext();\n                if ((kc === 37 && !s.rtl) || (kc === 39 && s.rtl)) s.slidePrev();\n            }\n            else {\n                if (kc === 38 || kc === 40) {\n                    if (e.preventDefault) e.preventDefault();\n                    else e.returnValue = false;\n                }\n                if (kc === 40) s.slideNext();\n                if (kc === 38) s.slidePrev();\n            }\n        }\n        s.disableKeyboardControl = function () {\n            s.params.keyboardControl = false;\n            $(document).off('keydown', handleKeyboard);\n        };\n        s.enableKeyboardControl = function () {\n            s.params.keyboardControl = true;\n            $(document).on('keydown', handleKeyboard);\n        };\n        \n\n        /*=========================\n          Mousewheel Control\n          ===========================*/\n        s.mousewheel = {\n            event: false,\n            lastScrollTime: (new window.Date()).getTime()\n        };\n        if (s.params.mousewheelControl) {\n            try {\n                new window.WheelEvent('wheel');\n                s.mousewheel.event = 'wheel';\n            } catch (e) {\n                if (window.WheelEvent || (s.container[0] && 'wheel' in s.container[0])) {\n                    s.mousewheel.event = 'wheel';\n                }\n            }\n            if (!s.mousewheel.event && window.WheelEvent) {\n        \n            }\n            if (!s.mousewheel.event && document.onmousewheel !== undefined) {\n                s.mousewheel.event = 'mousewheel';\n            }\n            if (!s.mousewheel.event) {\n                s.mousewheel.event = 'DOMMouseScroll';\n            }\n        }\n        function handleMousewheel(e) {\n            if (e.originalEvent) e = e.originalEvent; //jquery fix\n            var we = s.mousewheel.event;\n            var delta = 0;\n            var rtlFactor = s.rtl ? -1 : 1;\n        \n            //WebKits\n            if (we === 'mousewheel') {\n                if (s.params.mousewheelForceToAxis) {\n                    if (s.isHorizontal()) {\n                        if (Math.abs(e.wheelDeltaX) > Math.abs(e.wheelDeltaY)) delta = e.wheelDeltaX * rtlFactor;\n                        else return;\n                    }\n                    else {\n                        if (Math.abs(e.wheelDeltaY) > Math.abs(e.wheelDeltaX)) delta = e.wheelDeltaY;\n                        else return;\n                    }\n                }\n                else {\n                    delta = Math.abs(e.wheelDeltaX) > Math.abs(e.wheelDeltaY) ? - e.wheelDeltaX * rtlFactor : - e.wheelDeltaY;\n                }\n            }\n            //Old FireFox\n            else if (we === 'DOMMouseScroll') delta = -e.detail;\n            //New FireFox\n            else if (we === 'wheel') {\n                if (s.params.mousewheelForceToAxis) {\n                    if (s.isHorizontal()) {\n                        if (Math.abs(e.deltaX) > Math.abs(e.deltaY)) delta = -e.deltaX * rtlFactor;\n                        else return;\n                    }\n                    else {\n                        if (Math.abs(e.deltaY) > Math.abs(e.deltaX)) delta = -e.deltaY;\n                        else return;\n                    }\n                }\n                else {\n                    delta = Math.abs(e.deltaX) > Math.abs(e.deltaY) ? - e.deltaX * rtlFactor : - e.deltaY;\n                }\n            }\n            if (delta === 0) return;\n        \n            if (s.params.mousewheelInvert) delta = -delta;\n        \n            if (!s.params.freeMode) {\n                if ((new window.Date()).getTime() - s.mousewheel.lastScrollTime > 60) {\n                    if (delta < 0) {\n                        if ((!s.isEnd || s.params.loop) && !s.animating) s.slideNext();\n                        else if (s.params.mousewheelReleaseOnEdges) return true;\n                    }\n                    else {\n                        if ((!s.isBeginning || s.params.loop) && !s.animating) s.slidePrev();\n                        else if (s.params.mousewheelReleaseOnEdges) return true;\n                    }\n                }\n                s.mousewheel.lastScrollTime = (new window.Date()).getTime();\n        \n            }\n            else {\n                //Freemode or scrollContainer:\n                var position = s.getWrapperTranslate() + delta * s.params.mousewheelSensitivity;\n                var wasBeginning = s.isBeginning,\n                    wasEnd = s.isEnd;\n        \n                if (position >= s.minTranslate()) position = s.minTranslate();\n                if (position <= s.maxTranslate()) position = s.maxTranslate();\n        \n                s.setWrapperTransition(0);\n                s.setWrapperTranslate(position);\n                s.updateProgress();\n                s.updateActiveIndex();\n        \n                if (!wasBeginning && s.isBeginning || !wasEnd && s.isEnd) {\n                    s.updateClasses();\n                }\n        \n                if (s.params.freeModeSticky) {\n                    clearTimeout(s.mousewheel.timeout);\n                    s.mousewheel.timeout = setTimeout(function () {\n                        s.slideReset();\n                    }, 300);\n                }\n                else {\n                    if (s.params.lazyLoading && s.lazy) {\n                        s.lazy.load();\n                    }\n                }\n        \n                // Return page scroll on edge positions\n                if (position === 0 || position === s.maxTranslate()) return;\n            }\n            if (s.params.autoplay) s.stopAutoplay();\n        \n            if (e.preventDefault) e.preventDefault();\n            else e.returnValue = false;\n            return false;\n        }\n        s.disableMousewheelControl = function () {\n            if (!s.mousewheel.event) return false;\n            s.container.off(s.mousewheel.event, handleMousewheel);\n            return true;\n        };\n        \n        s.enableMousewheelControl = function () {\n            if (!s.mousewheel.event) return false;\n            s.container.on(s.mousewheel.event, handleMousewheel);\n            return true;\n        };\n        \n\n        /*=========================\n          Parallax\n          ===========================*/\n        function setParallaxTransform(el, progress) {\n            el = $(el);\n            var p, pX, pY;\n            var rtlFactor = s.rtl ? -1 : 1;\n        \n            p = el.attr('data-swiper-parallax') || '0';\n            pX = el.attr('data-swiper-parallax-x');\n            pY = el.attr('data-swiper-parallax-y');\n            if (pX || pY) {\n                pX = pX || '0';\n                pY = pY || '0';\n            }\n            else {\n                if (s.isHorizontal()) {\n                    pX = p;\n                    pY = '0';\n                }\n                else {\n                    pY = p;\n                    pX = '0';\n                }\n            }\n        \n            if ((pX).indexOf('%') >= 0) {\n                pX = parseInt(pX, 10) * progress * rtlFactor + '%';\n            }\n            else {\n                pX = pX * progress * rtlFactor + 'px' ;\n            }\n            if ((pY).indexOf('%') >= 0) {\n                pY = parseInt(pY, 10) * progress + '%';\n            }\n            else {\n                pY = pY * progress + 'px' ;\n            }\n        \n            el.transform('translate3d(' + pX + ', ' + pY + ',0px)');\n        }\n        s.parallax = {\n            setTranslate: function () {\n                s.container.children('[data-swiper-parallax], [data-swiper-parallax-x], [data-swiper-parallax-y]').each(function(){\n                    setParallaxTransform(this, s.progress);\n        \n                });\n                s.slides.each(function () {\n                    var slide = $(this);\n                    slide.find('[data-swiper-parallax], [data-swiper-parallax-x], [data-swiper-parallax-y]').each(function () {\n                        var progress = Math.min(Math.max(slide[0].progress, -1), 1);\n                        setParallaxTransform(this, progress);\n                    });\n                });\n            },\n            setTransition: function (duration) {\n                if (typeof duration === 'undefined') duration = s.params.speed;\n                s.container.find('[data-swiper-parallax], [data-swiper-parallax-x], [data-swiper-parallax-y]').each(function(){\n                    var el = $(this);\n                    var parallaxDuration = parseInt(el.attr('data-swiper-parallax-duration'), 10) || duration;\n                    if (duration === 0) parallaxDuration = 0;\n                    el.transition(parallaxDuration);\n                });\n            }\n        };\n        \n\n        /*=========================\n          Plugins API. Collect all and init all plugins\n          ===========================*/\n        s._plugins = [];\n        for (var plugin in s.plugins) {\n            var p = s.plugins[plugin](s, s.params[plugin]);\n            if (p) s._plugins.push(p);\n        }\n        // Method to call all plugins event/method\n        s.callPlugins = function (eventName) {\n            for (var i = 0; i < s._plugins.length; i++) {\n                if (eventName in s._plugins[i]) {\n                    s._plugins[i][eventName](arguments[1], arguments[2], arguments[3], arguments[4], arguments[5]);\n                }\n            }\n        };\n\n        /*=========================\n          Events/Callbacks/Plugins Emitter\n          ===========================*/\n        function normalizeEventName (eventName) {\n            if (eventName.indexOf('on') !== 0) {\n                if (eventName[0] !== eventName[0].toUpperCase()) {\n                    eventName = 'on' + eventName[0].toUpperCase() + eventName.substring(1);\n                }\n                else {\n                    eventName = 'on' + eventName;\n                }\n            }\n            return eventName;\n        }\n        s.emitterEventListeners = {\n        \n        };\n        s.emit = function (eventName) {\n            // Trigger callbacks\n            if (s.params[eventName]) {\n                s.params[eventName](arguments[1], arguments[2], arguments[3], arguments[4], arguments[5]);\n            }\n            var i;\n            // Trigger events\n            if (s.emitterEventListeners[eventName]) {\n                for (i = 0; i < s.emitterEventListeners[eventName].length; i++) {\n                    s.emitterEventListeners[eventName][i](arguments[1], arguments[2], arguments[3], arguments[4], arguments[5]);\n                }\n            }\n            // Trigger plugins\n            if (s.callPlugins) s.callPlugins(eventName, arguments[1], arguments[2], arguments[3], arguments[4], arguments[5]);\n        };\n        s.on = function (eventName, handler) {\n            eventName = normalizeEventName(eventName);\n            if (!s.emitterEventListeners[eventName]) s.emitterEventListeners[eventName] = [];\n            s.emitterEventListeners[eventName].push(handler);\n            return s;\n        };\n        s.off = function (eventName, handler) {\n            var i;\n            eventName = normalizeEventName(eventName);\n            if (typeof handler === 'undefined') {\n                // Remove all handlers for such event\n                s.emitterEventListeners[eventName] = [];\n                return s;\n            }\n            if (!s.emitterEventListeners[eventName] || s.emitterEventListeners[eventName].length === 0) return;\n            for (i = 0; i < s.emitterEventListeners[eventName].length; i++) {\n                if(s.emitterEventListeners[eventName][i] === handler) s.emitterEventListeners[eventName].splice(i, 1);\n            }\n            return s;\n        };\n        s.once = function (eventName, handler) {\n            eventName = normalizeEventName(eventName);\n            var _handler = function () {\n                handler(arguments[0], arguments[1], arguments[2], arguments[3], arguments[4]);\n                s.off(eventName, _handler);\n            };\n            s.on(eventName, _handler);\n            return s;\n        };\n\n        // Accessibility tools\n        s.a11y = {\n            makeFocusable: function ($el) {\n                $el.attr('tabIndex', '0');\n                return $el;\n            },\n            addRole: function ($el, role) {\n                $el.attr('role', role);\n                return $el;\n            },\n        \n            addLabel: function ($el, label) {\n                $el.attr('aria-label', label);\n                return $el;\n            },\n        \n            disable: function ($el) {\n                $el.attr('aria-disabled', true);\n                return $el;\n            },\n        \n            enable: function ($el) {\n                $el.attr('aria-disabled', false);\n                return $el;\n            },\n        \n            onEnterKey: function (event) {\n                if (event.keyCode !== 13) return;\n                if ($(event.target).is(s.params.nextButton)) {\n                    s.onClickNext(event);\n                    if (s.isEnd) {\n                        s.a11y.notify(s.params.lastSlideMessage);\n                    }\n                    else {\n                        s.a11y.notify(s.params.nextSlideMessage);\n                    }\n                }\n                else if ($(event.target).is(s.params.prevButton)) {\n                    s.onClickPrev(event);\n                    if (s.isBeginning) {\n                        s.a11y.notify(s.params.firstSlideMessage);\n                    }\n                    else {\n                        s.a11y.notify(s.params.prevSlideMessage);\n                    }\n                }\n                if ($(event.target).is('.' + s.params.bulletClass)) {\n                    $(event.target)[0].click();\n                }\n            },\n        \n            liveRegion: $('<span class=\"swiper-notification\" aria-live=\"assertive\" aria-atomic=\"true\"></span>'),\n        \n            notify: function (message) {\n                var notification = s.a11y.liveRegion;\n                if (notification.length === 0) return;\n                notification.html('');\n                notification.html(message);\n            },\n            init: function () {\n                // Setup accessibility\n                if (s.params.nextButton && s.nextButton && s.nextButton.length > 0) {\n                    s.a11y.makeFocusable(s.nextButton);\n                    s.a11y.addRole(s.nextButton, 'button');\n                    s.a11y.addLabel(s.nextButton, s.params.nextSlideMessage);\n                }\n                if (s.params.prevButton && s.prevButton && s.prevButton.length > 0) {\n                    s.a11y.makeFocusable(s.prevButton);\n                    s.a11y.addRole(s.prevButton, 'button');\n                    s.a11y.addLabel(s.prevButton, s.params.prevSlideMessage);\n                }\n        \n                $(s.container).append(s.a11y.liveRegion);\n            },\n            initPagination: function () {\n                if (s.params.pagination && s.params.paginationClickable && s.bullets && s.bullets.length) {\n                    s.bullets.each(function () {\n                        var bullet = $(this);\n                        s.a11y.makeFocusable(bullet);\n                        s.a11y.addRole(bullet, 'button');\n                        s.a11y.addLabel(bullet, s.params.paginationBulletMessage.replace(/{{index}}/, bullet.index() + 1));\n                    });\n                }\n            },\n            destroy: function () {\n                if (s.a11y.liveRegion && s.a11y.liveRegion.length > 0) s.a11y.liveRegion.remove();\n            }\n        };\n        \n\n        /*=========================\n          Init/Destroy\n          ===========================*/\n        s.init = function () {\n            if (s.params.loop) s.createLoop();\n            s.updateContainerSize();\n            s.updateSlidesSize();\n            s.updatePagination();\n            if (s.params.scrollbar && s.scrollbar) {\n                s.scrollbar.set();\n                if (s.params.scrollbarDraggable) {\n                    s.scrollbar.enableDraggable();\n                }\n            }\n            if (s.params.effect !== 'slide' && s.effects[s.params.effect]) {\n                if (!s.params.loop) s.updateProgress();\n                s.effects[s.params.effect].setTranslate();\n            }\n            if (s.params.loop) {\n                s.slideTo(s.params.initialSlide + s.loopedSlides, 0, s.params.runCallbacksOnInit);\n            }\n            else {\n                s.slideTo(s.params.initialSlide, 0, s.params.runCallbacksOnInit);\n                if (s.params.initialSlide === 0) {\n                    if (s.parallax && s.params.parallax) s.parallax.setTranslate();\n                    if (s.lazy && s.params.lazyLoading) {\n                        s.lazy.load();\n                        s.lazy.initialImageLoaded = true;\n                    }\n                }\n            }\n            s.attachEvents();\n            if (s.params.observer && s.support.observer) {\n                s.initObservers();\n            }\n            if (s.params.preloadImages && !s.params.lazyLoading) {\n                s.preloadImages();\n            }\n            if (s.params.autoplay) {\n                s.startAutoplay();\n            }\n            if (s.params.keyboardControl) {\n                if (s.enableKeyboardControl) s.enableKeyboardControl();\n            }\n            if (s.params.mousewheelControl) {\n                if (s.enableMousewheelControl) s.enableMousewheelControl();\n            }\n            if (s.params.hashnav) {\n                if (s.hashnav) s.hashnav.init();\n            }\n            if (s.params.a11y && s.a11y) s.a11y.init();\n            s.emit('onInit', s);\n        };\n        \n        // Cleanup dynamic styles\n        s.cleanupStyles = function () {\n            // Container\n            s.container.removeClass(s.classNames.join(' ')).removeAttr('style');\n        \n            // Wrapper\n            s.wrapper.removeAttr('style');\n        \n            // Slides\n            if (s.slides && s.slides.length) {\n                s.slides\n                    .removeClass([\n                      s.params.slideVisibleClass,\n                      s.params.slideActiveClass,\n                      s.params.slideNextClass,\n                      s.params.slidePrevClass\n                    ].join(' '))\n                    .removeAttr('style')\n                    .removeAttr('data-swiper-column')\n                    .removeAttr('data-swiper-row');\n            }\n        \n            // Pagination/Bullets\n            if (s.paginationContainer && s.paginationContainer.length) {\n                s.paginationContainer.removeClass(s.params.paginationHiddenClass);\n            }\n            if (s.bullets && s.bullets.length) {\n                s.bullets.removeClass(s.params.bulletActiveClass);\n            }\n        \n            // Buttons\n            if (s.params.prevButton) $(s.params.prevButton).removeClass(s.params.buttonDisabledClass);\n            if (s.params.nextButton) $(s.params.nextButton).removeClass(s.params.buttonDisabledClass);\n        \n            // Scrollbar\n            if (s.params.scrollbar && s.scrollbar) {\n                if (s.scrollbar.track && s.scrollbar.track.length) s.scrollbar.track.removeAttr('style');\n                if (s.scrollbar.drag && s.scrollbar.drag.length) s.scrollbar.drag.removeAttr('style');\n            }\n        };\n        \n        // Destroy\n        s.destroy = function (deleteInstance, cleanupStyles) {\n            // Detach evebts\n            s.detachEvents();\n            // Stop autoplay\n            s.stopAutoplay();\n            // Disable draggable\n            if (s.params.scrollbar && s.scrollbar) {\n                if (s.params.scrollbarDraggable) {\n                    s.scrollbar.disableDraggable();\n                }\n            }\n            // Destroy loop\n            if (s.params.loop) {\n                s.destroyLoop();\n            }\n            // Cleanup styles\n            if (cleanupStyles) {\n                s.cleanupStyles();\n            }\n            // Disconnect observer\n            s.disconnectObservers();\n            // Disable keyboard/mousewheel\n            if (s.params.keyboardControl) {\n                if (s.disableKeyboardControl) s.disableKeyboardControl();\n            }\n            if (s.params.mousewheelControl) {\n                if (s.disableMousewheelControl) s.disableMousewheelControl();\n            }\n            // Disable a11y\n            if (s.params.a11y && s.a11y) s.a11y.destroy();\n            // Destroy callback\n            s.emit('onDestroy');\n            // Delete instance\n            if (deleteInstance !== false) s = null;\n        };\n        \n        s.init();\n        \n\n    \n        // Return swiper instance\n        return s;\n    };\n    \n\n    /*==================================================\n        Prototype\n    ====================================================*/\n    Swiper.prototype = {\n        isSafari: (function () {\n            var ua = navigator.userAgent.toLowerCase();\n            return (ua.indexOf('safari') >= 0 && ua.indexOf('chrome') < 0 && ua.indexOf('android') < 0);\n        })(),\n        isUiWebView: /(iPhone|iPod|iPad).*AppleWebKit(?!.*Safari)/i.test(navigator.userAgent),\n        isArray: function (arr) {\n            return Object.prototype.toString.apply(arr) === '[object Array]';\n        },\n        /*==================================================\n        Browser\n        ====================================================*/\n        browser: {\n            ie: window.navigator.pointerEnabled || window.navigator.msPointerEnabled,\n            ieTouch: (window.navigator.msPointerEnabled && window.navigator.msMaxTouchPoints > 1) || (window.navigator.pointerEnabled && window.navigator.maxTouchPoints > 1)\n        },\n        /*==================================================\n        Devices\n        ====================================================*/\n        device: (function () {\n            var ua = navigator.userAgent;\n            var android = ua.match(/(Android);?[\\s\\/]+([\\d.]+)?/);\n            var ipad = ua.match(/(iPad).*OS\\s([\\d_]+)/);\n            var ipod = ua.match(/(iPod)(.*OS\\s([\\d_]+))?/);\n            var iphone = !ipad && ua.match(/(iPhone\\sOS)\\s([\\d_]+)/);\n            return {\n                ios: ipad || iphone || ipod,\n                android: android\n            };\n        })(),\n        /*==================================================\n        Feature Detection\n        ====================================================*/\n        support: {\n            touch : (window.Modernizr && Modernizr.touch === true) || (function () {\n                return !!(('ontouchstart' in window) || window.DocumentTouch && document instanceof DocumentTouch);\n            })(),\n    \n            transforms3d : (window.Modernizr && Modernizr.csstransforms3d === true) || (function () {\n                var div = document.createElement('div').style;\n                return ('webkitPerspective' in div || 'MozPerspective' in div || 'OPerspective' in div || 'MsPerspective' in div || 'perspective' in div);\n            })(),\n    \n            flexbox: (function () {\n                var div = document.createElement('div').style;\n                var styles = ('alignItems webkitAlignItems webkitBoxAlign msFlexAlign mozBoxAlign webkitFlexDirection msFlexDirection mozBoxDirection mozBoxOrient webkitBoxDirection webkitBoxOrient').split(' ');\n                for (var i = 0; i < styles.length; i++) {\n                    if (styles[i] in div) return true;\n                }\n            })(),\n    \n            observer: (function () {\n                return ('MutationObserver' in window || 'WebkitMutationObserver' in window);\n            })()\n        },\n        /*==================================================\n        Plugins\n        ====================================================*/\n        plugins: {}\n    };\n    \n\n    /*===========================\n    Dom7 Library\n    ===========================*/\n    var Dom7 = (function () {\n        var Dom7 = function (arr) {\n            var _this = this, i = 0;\n            // Create array-like object\n            for (i = 0; i < arr.length; i++) {\n                _this[i] = arr[i];\n            }\n            _this.length = arr.length;\n            // Return collection with methods\n            return this;\n        };\n        var $ = function (selector, context) {\n            var arr = [], i = 0;\n            if (selector && !context) {\n                if (selector instanceof Dom7) {\n                    return selector;\n                }\n            }\n            if (selector) {\n                // String\n                if (typeof selector === 'string') {\n                    var els, tempParent, html = selector.trim();\n                    if (html.indexOf('<') >= 0 && html.indexOf('>') >= 0) {\n                        var toCreate = 'div';\n                        if (html.indexOf('<li') === 0) toCreate = 'ul';\n                        if (html.indexOf('<tr') === 0) toCreate = 'tbody';\n                        if (html.indexOf('<td') === 0 || html.indexOf('<th') === 0) toCreate = 'tr';\n                        if (html.indexOf('<tbody') === 0) toCreate = 'table';\n                        if (html.indexOf('<option') === 0) toCreate = 'select';\n                        tempParent = document.createElement(toCreate);\n                        tempParent.innerHTML = selector;\n                        for (i = 0; i < tempParent.childNodes.length; i++) {\n                            arr.push(tempParent.childNodes[i]);\n                        }\n                    }\n                    else {\n                        if (!context && selector[0] === '#' && !selector.match(/[ .<>:~]/)) {\n                            // Pure ID selector\n                            els = [document.getElementById(selector.split('#')[1])];\n                        }\n                        else {\n                            // Other selectors\n                            els = (context || document).querySelectorAll(selector);\n                        }\n                        for (i = 0; i < els.length; i++) {\n                            if (els[i]) arr.push(els[i]);\n                        }\n                    }\n                }\n                // Node/element\n                else if (selector.nodeType || selector === window || selector === document) {\n                    arr.push(selector);\n                }\n                //Array of elements or instance of Dom\n                else if (selector.length > 0 && selector[0].nodeType) {\n                    for (i = 0; i < selector.length; i++) {\n                        arr.push(selector[i]);\n                    }\n                }\n            }\n            return new Dom7(arr);\n        };\n        Dom7.prototype = {\n            // Classes and attriutes\n            addClass: function (className) {\n                if (typeof className === 'undefined') {\n                    return this;\n                }\n                var classes = className.split(' ');\n                for (var i = 0; i < classes.length; i++) {\n                    for (var j = 0; j < this.length; j++) {\n                        this[j].classList.add(classes[i]);\n                    }\n                }\n                return this;\n            },\n            removeClass: function (className) {\n                var classes = className.split(' ');\n                for (var i = 0; i < classes.length; i++) {\n                    for (var j = 0; j < this.length; j++) {\n                        this[j].classList.remove(classes[i]);\n                    }\n                }\n                return this;\n            },\n            hasClass: function (className) {\n                if (!this[0]) return false;\n                else return this[0].classList.contains(className);\n            },\n            toggleClass: function (className) {\n                var classes = className.split(' ');\n                for (var i = 0; i < classes.length; i++) {\n                    for (var j = 0; j < this.length; j++) {\n                        this[j].classList.toggle(classes[i]);\n                    }\n                }\n                return this;\n            },\n            attr: function (attrs, value) {\n                if (arguments.length === 1 && typeof attrs === 'string') {\n                    // Get attr\n                    if (this[0]) return this[0].getAttribute(attrs);\n                    else return undefined;\n                }\n                else {\n                    // Set attrs\n                    for (var i = 0; i < this.length; i++) {\n                        if (arguments.length === 2) {\n                            // String\n                            this[i].setAttribute(attrs, value);\n                        }\n                        else {\n                            // Object\n                            for (var attrName in attrs) {\n                                this[i][attrName] = attrs[attrName];\n                                this[i].setAttribute(attrName, attrs[attrName]);\n                            }\n                        }\n                    }\n                    return this;\n                }\n            },\n            removeAttr: function (attr) {\n                for (var i = 0; i < this.length; i++) {\n                    this[i].removeAttribute(attr);\n                }\n                return this;\n            },\n            data: function (key, value) {\n                if (typeof value === 'undefined') {\n                    // Get value\n                    if (this[0]) {\n                        var dataKey = this[0].getAttribute('data-' + key);\n                        if (dataKey) return dataKey;\n                        else if (this[0].dom7ElementDataStorage && (key in this[0].dom7ElementDataStorage)) return this[0].dom7ElementDataStorage[key];\n                        else return undefined;\n                    }\n                    else return undefined;\n                }\n                else {\n                    // Set value\n                    for (var i = 0; i < this.length; i++) {\n                        var el = this[i];\n                        if (!el.dom7ElementDataStorage) el.dom7ElementDataStorage = {};\n                        el.dom7ElementDataStorage[key] = value;\n                    }\n                    return this;\n                }\n            },\n            // Transforms\n            transform : function (transform) {\n                for (var i = 0; i < this.length; i++) {\n                    var elStyle = this[i].style;\n                    elStyle.webkitTransform = elStyle.MsTransform = elStyle.msTransform = elStyle.MozTransform = elStyle.OTransform = elStyle.transform = transform;\n                }\n                return this;\n            },\n            transition: function (duration) {\n                if (typeof duration !== 'string') {\n                    duration = duration + 'ms';\n                }\n                for (var i = 0; i < this.length; i++) {\n                    var elStyle = this[i].style;\n                    elStyle.webkitTransitionDuration = elStyle.MsTransitionDuration = elStyle.msTransitionDuration = elStyle.MozTransitionDuration = elStyle.OTransitionDuration = elStyle.transitionDuration = duration;\n                }\n                return this;\n            },\n            //Events\n            on: function (eventName, targetSelector, listener, capture) {\n                function handleLiveEvent(e) {\n                    var target = e.target;\n                    if ($(target).is(targetSelector)) listener.call(target, e);\n                    else {\n                        var parents = $(target).parents();\n                        for (var k = 0; k < parents.length; k++) {\n                            if ($(parents[k]).is(targetSelector)) listener.call(parents[k], e);\n                        }\n                    }\n                }\n                var events = eventName.split(' ');\n                var i, j;\n                for (i = 0; i < this.length; i++) {\n                    if (typeof targetSelector === 'function' || targetSelector === false) {\n                        // Usual events\n                        if (typeof targetSelector === 'function') {\n                            listener = arguments[1];\n                            capture = arguments[2] || false;\n                        }\n                        for (j = 0; j < events.length; j++) {\n                            this[i].addEventListener(events[j], listener, capture);\n                        }\n                    }\n                    else {\n                        //Live events\n                        for (j = 0; j < events.length; j++) {\n                            if (!this[i].dom7LiveListeners) this[i].dom7LiveListeners = [];\n                            this[i].dom7LiveListeners.push({listener: listener, liveListener: handleLiveEvent});\n                            this[i].addEventListener(events[j], handleLiveEvent, capture);\n                        }\n                    }\n                }\n    \n                return this;\n            },\n            off: function (eventName, targetSelector, listener, capture) {\n                var events = eventName.split(' ');\n                for (var i = 0; i < events.length; i++) {\n                    for (var j = 0; j < this.length; j++) {\n                        if (typeof targetSelector === 'function' || targetSelector === false) {\n                            // Usual events\n                            if (typeof targetSelector === 'function') {\n                                listener = arguments[1];\n                                capture = arguments[2] || false;\n                            }\n                            this[j].removeEventListener(events[i], listener, capture);\n                        }\n                        else {\n                            // Live event\n                            if (this[j].dom7LiveListeners) {\n                                for (var k = 0; k < this[j].dom7LiveListeners.length; k++) {\n                                    if (this[j].dom7LiveListeners[k].listener === listener) {\n                                        this[j].removeEventListener(events[i], this[j].dom7LiveListeners[k].liveListener, capture);\n                                    }\n                                }\n                            }\n                        }\n                    }\n                }\n                return this;\n            },\n            once: function (eventName, targetSelector, listener, capture) {\n                var dom = this;\n                if (typeof targetSelector === 'function') {\n                    targetSelector = false;\n                    listener = arguments[1];\n                    capture = arguments[2];\n                }\n                function proxy(e) {\n                    listener(e);\n                    dom.off(eventName, targetSelector, proxy, capture);\n                }\n                dom.on(eventName, targetSelector, proxy, capture);\n            },\n            trigger: function (eventName, eventData) {\n                for (var i = 0; i < this.length; i++) {\n                    var evt;\n                    try {\n                        evt = new window.CustomEvent(eventName, {detail: eventData, bubbles: true, cancelable: true});\n                    }\n                    catch (e) {\n                        evt = document.createEvent('Event');\n                        evt.initEvent(eventName, true, true);\n                        evt.detail = eventData;\n                    }\n                    this[i].dispatchEvent(evt);\n                }\n                return this;\n            },\n            transitionEnd: function (callback) {\n                var events = ['webkitTransitionEnd', 'transitionend', 'oTransitionEnd', 'MSTransitionEnd', 'msTransitionEnd'],\n                    i, j, dom = this;\n                function fireCallBack(e) {\n                    /*jshint validthis:true */\n                    if (e.target !== this) return;\n                    callback.call(this, e);\n                    for (i = 0; i < events.length; i++) {\n                        dom.off(events[i], fireCallBack);\n                    }\n                }\n                if (callback) {\n                    for (i = 0; i < events.length; i++) {\n                        dom.on(events[i], fireCallBack);\n                    }\n                }\n                return this;\n            },\n            // Sizing/Styles\n            width: function () {\n                if (this[0] === window) {\n                    return window.innerWidth;\n                }\n                else {\n                    if (this.length > 0) {\n                        return parseFloat(this.css('width'));\n                    }\n                    else {\n                        return null;\n                    }\n                }\n            },\n            outerWidth: function (includeMargins) {\n                if (this.length > 0) {\n                    if (includeMargins)\n                        return this[0].offsetWidth + parseFloat(this.css('margin-right')) + parseFloat(this.css('margin-left'));\n                    else\n                        return this[0].offsetWidth;\n                }\n                else return null;\n            },\n            height: function () {\n                if (this[0] === window) {\n                    return window.innerHeight;\n                }\n                else {\n                    if (this.length > 0) {\n                        return parseFloat(this.css('height'));\n                    }\n                    else {\n                        return null;\n                    }\n                }\n            },\n            outerHeight: function (includeMargins) {\n                if (this.length > 0) {\n                    if (includeMargins)\n                        return this[0].offsetHeight + parseFloat(this.css('margin-top')) + parseFloat(this.css('margin-bottom'));\n                    else\n                        return this[0].offsetHeight;\n                }\n                else return null;\n            },\n            offset: function () {\n                if (this.length > 0) {\n                    var el = this[0];\n                    var box = el.getBoundingClientRect();\n                    var body = document.body;\n                    var clientTop  = el.clientTop  || body.clientTop  || 0;\n                    var clientLeft = el.clientLeft || body.clientLeft || 0;\n                    var scrollTop  = window.pageYOffset || el.scrollTop;\n                    var scrollLeft = window.pageXOffset || el.scrollLeft;\n                    return {\n                        top: box.top  + scrollTop  - clientTop,\n                        left: box.left + scrollLeft - clientLeft\n                    };\n                }\n                else {\n                    return null;\n                }\n            },\n            css: function (props, value) {\n                var i;\n                if (arguments.length === 1) {\n                    if (typeof props === 'string') {\n                        if (this[0]) return window.getComputedStyle(this[0], null).getPropertyValue(props);\n                    }\n                    else {\n                        for (i = 0; i < this.length; i++) {\n                            for (var prop in props) {\n                                this[i].style[prop] = props[prop];\n                            }\n                        }\n                        return this;\n                    }\n                }\n                if (arguments.length === 2 && typeof props === 'string') {\n                    for (i = 0; i < this.length; i++) {\n                        this[i].style[props] = value;\n                    }\n                    return this;\n                }\n                return this;\n            },\n    \n            //Dom manipulation\n            each: function (callback) {\n                for (var i = 0; i < this.length; i++) {\n                    callback.call(this[i], i, this[i]);\n                }\n                return this;\n            },\n            html: function (html) {\n                if (typeof html === 'undefined') {\n                    return this[0] ? this[0].innerHTML : undefined;\n                }\n                else {\n                    for (var i = 0; i < this.length; i++) {\n                        this[i].innerHTML = html;\n                    }\n                    return this;\n                }\n            },\n            text: function (text) {\n                if (typeof text === 'undefined') {\n                    if (this[0]) {\n                        return this[0].textContent.trim();\n                    }\n                    else return null;\n                }\n                else {\n                    for (var i = 0; i < this.length; i++) {\n                        this[i].textContent = text;\n                    }\n                    return this;\n                }\n            },\n            is: function (selector) {\n                if (!this[0]) return false;\n                var compareWith, i;\n                if (typeof selector === 'string') {\n                    var el = this[0];\n                    if (el === document) return selector === document;\n                    if (el === window) return selector === window;\n    \n                    if (el.matches) return el.matches(selector);\n                    else if (el.webkitMatchesSelector) return el.webkitMatchesSelector(selector);\n                    else if (el.mozMatchesSelector) return el.mozMatchesSelector(selector);\n                    else if (el.msMatchesSelector) return el.msMatchesSelector(selector);\n                    else {\n                        compareWith = $(selector);\n                        for (i = 0; i < compareWith.length; i++) {\n                            if (compareWith[i] === this[0]) return true;\n                        }\n                        return false;\n                    }\n                }\n                else if (selector === document) return this[0] === document;\n                else if (selector === window) return this[0] === window;\n                else {\n                    if (selector.nodeType || selector instanceof Dom7) {\n                        compareWith = selector.nodeType ? [selector] : selector;\n                        for (i = 0; i < compareWith.length; i++) {\n                            if (compareWith[i] === this[0]) return true;\n                        }\n                        return false;\n                    }\n                    return false;\n                }\n    \n            },\n            index: function () {\n                if (this[0]) {\n                    var child = this[0];\n                    var i = 0;\n                    while ((child = child.previousSibling) !== null) {\n                        if (child.nodeType === 1) i++;\n                    }\n                    return i;\n                }\n                else return undefined;\n            },\n            eq: function (index) {\n                if (typeof index === 'undefined') return this;\n                var length = this.length;\n                var returnIndex;\n                if (index > length - 1) {\n                    return new Dom7([]);\n                }\n                if (index < 0) {\n                    returnIndex = length + index;\n                    if (returnIndex < 0) return new Dom7([]);\n                    else return new Dom7([this[returnIndex]]);\n                }\n                return new Dom7([this[index]]);\n            },\n            append: function (newChild) {\n                var i, j;\n                for (i = 0; i < this.length; i++) {\n                    if (typeof newChild === 'string') {\n                        var tempDiv = document.createElement('div');\n                        tempDiv.innerHTML = newChild;\n                        while (tempDiv.firstChild) {\n                            this[i].appendChild(tempDiv.firstChild);\n                        }\n                    }\n                    else if (newChild instanceof Dom7) {\n                        for (j = 0; j < newChild.length; j++) {\n                            this[i].appendChild(newChild[j]);\n                        }\n                    }\n                    else {\n                        this[i].appendChild(newChild);\n                    }\n                }\n                return this;\n            },\n            prepend: function (newChild) {\n                var i, j;\n                for (i = 0; i < this.length; i++) {\n                    if (typeof newChild === 'string') {\n                        var tempDiv = document.createElement('div');\n                        tempDiv.innerHTML = newChild;\n                        for (j = tempDiv.childNodes.length - 1; j >= 0; j--) {\n                            this[i].insertBefore(tempDiv.childNodes[j], this[i].childNodes[0]);\n                        }\n                        // this[i].insertAdjacentHTML('afterbegin', newChild);\n                    }\n                    else if (newChild instanceof Dom7) {\n                        for (j = 0; j < newChild.length; j++) {\n                            this[i].insertBefore(newChild[j], this[i].childNodes[0]);\n                        }\n                    }\n                    else {\n                        this[i].insertBefore(newChild, this[i].childNodes[0]);\n                    }\n                }\n                return this;\n            },\n            insertBefore: function (selector) {\n                var before = $(selector);\n                for (var i = 0; i < this.length; i++) {\n                    if (before.length === 1) {\n                        before[0].parentNode.insertBefore(this[i], before[0]);\n                    }\n                    else if (before.length > 1) {\n                        for (var j = 0; j < before.length; j++) {\n                            before[j].parentNode.insertBefore(this[i].cloneNode(true), before[j]);\n                        }\n                    }\n                }\n            },\n            insertAfter: function (selector) {\n                var after = $(selector);\n                for (var i = 0; i < this.length; i++) {\n                    if (after.length === 1) {\n                        after[0].parentNode.insertBefore(this[i], after[0].nextSibling);\n                    }\n                    else if (after.length > 1) {\n                        for (var j = 0; j < after.length; j++) {\n                            after[j].parentNode.insertBefore(this[i].cloneNode(true), after[j].nextSibling);\n                        }\n                    }\n                }\n            },\n            next: function (selector) {\n                if (this.length > 0) {\n                    if (selector) {\n                        if (this[0].nextElementSibling && $(this[0].nextElementSibling).is(selector)) return new Dom7([this[0].nextElementSibling]);\n                        else return new Dom7([]);\n                    }\n                    else {\n                        if (this[0].nextElementSibling) return new Dom7([this[0].nextElementSibling]);\n                        else return new Dom7([]);\n                    }\n                }\n                else return new Dom7([]);\n            },\n            nextAll: function (selector) {\n                var nextEls = [];\n                var el = this[0];\n                if (!el) return new Dom7([]);\n                while (el.nextElementSibling) {\n                    var next = el.nextElementSibling;\n                    if (selector) {\n                        if($(next).is(selector)) nextEls.push(next);\n                    }\n                    else nextEls.push(next);\n                    el = next;\n                }\n                return new Dom7(nextEls);\n            },\n            prev: function (selector) {\n                if (this.length > 0) {\n                    if (selector) {\n                        if (this[0].previousElementSibling && $(this[0].previousElementSibling).is(selector)) return new Dom7([this[0].previousElementSibling]);\n                        else return new Dom7([]);\n                    }\n                    else {\n                        if (this[0].previousElementSibling) return new Dom7([this[0].previousElementSibling]);\n                        else return new Dom7([]);\n                    }\n                }\n                else return new Dom7([]);\n            },\n            prevAll: function (selector) {\n                var prevEls = [];\n                var el = this[0];\n                if (!el) return new Dom7([]);\n                while (el.previousElementSibling) {\n                    var prev = el.previousElementSibling;\n                    if (selector) {\n                        if($(prev).is(selector)) prevEls.push(prev);\n                    }\n                    else prevEls.push(prev);\n                    el = prev;\n                }\n                return new Dom7(prevEls);\n            },\n            parent: function (selector) {\n                var parents = [];\n                for (var i = 0; i < this.length; i++) {\n                    if (selector) {\n                        if ($(this[i].parentNode).is(selector)) parents.push(this[i].parentNode);\n                    }\n                    else {\n                        parents.push(this[i].parentNode);\n                    }\n                }\n                return $($.unique(parents));\n            },\n            parents: function (selector) {\n                var parents = [];\n                for (var i = 0; i < this.length; i++) {\n                    var parent = this[i].parentNode;\n                    while (parent) {\n                        if (selector) {\n                            if ($(parent).is(selector)) parents.push(parent);\n                        }\n                        else {\n                            parents.push(parent);\n                        }\n                        parent = parent.parentNode;\n                    }\n                }\n                return $($.unique(parents));\n            },\n            find : function (selector) {\n                var foundElements = [];\n                for (var i = 0; i < this.length; i++) {\n                    var found = this[i].querySelectorAll(selector);\n                    for (var j = 0; j < found.length; j++) {\n                        foundElements.push(found[j]);\n                    }\n                }\n                return new Dom7(foundElements);\n            },\n            children: function (selector) {\n                var children = [];\n                for (var i = 0; i < this.length; i++) {\n                    var childNodes = this[i].childNodes;\n    \n                    for (var j = 0; j < childNodes.length; j++) {\n                        if (!selector) {\n                            if (childNodes[j].nodeType === 1) children.push(childNodes[j]);\n                        }\n                        else {\n                            if (childNodes[j].nodeType === 1 && $(childNodes[j]).is(selector)) children.push(childNodes[j]);\n                        }\n                    }\n                }\n                return new Dom7($.unique(children));\n            },\n            remove: function () {\n                for (var i = 0; i < this.length; i++) {\n                    if (this[i].parentNode) this[i].parentNode.removeChild(this[i]);\n                }\n                return this;\n            },\n            add: function () {\n                var dom = this;\n                var i, j;\n                for (i = 0; i < arguments.length; i++) {\n                    var toAdd = $(arguments[i]);\n                    for (j = 0; j < toAdd.length; j++) {\n                        dom[dom.length] = toAdd[j];\n                        dom.length++;\n                    }\n                }\n                return dom;\n            }\n        };\n        $.fn = Dom7.prototype;\n        $.unique = function (arr) {\n            var unique = [];\n            for (var i = 0; i < arr.length; i++) {\n                if (unique.indexOf(arr[i]) === -1) unique.push(arr[i]);\n            }\n            return unique;\n        };\n    \n        return $;\n    })();\n    \n\n    /*===========================\n     Get Dom libraries\n     ===========================*/\n    var swiperDomPlugins = ['jQuery', 'Zepto', 'Dom7'];\n    for (var i = 0; i < swiperDomPlugins.length; i++) {\n    \tif (window[swiperDomPlugins[i]]) {\n    \t\taddLibraryPlugin(window[swiperDomPlugins[i]]);\n    \t}\n    }\n    // Required DOM Plugins\n    var domLib;\n    if (typeof Dom7 === 'undefined') {\n    \tdomLib = window.Dom7 || window.Zepto || window.jQuery;\n    }\n    else {\n    \tdomLib = Dom7;\n    }\n\n    /*===========================\n    Add .swiper plugin from Dom libraries\n    ===========================*/\n    function addLibraryPlugin(lib) {\n        lib.fn.swiper = function (params) {\n            var firstInstance;\n            lib(this).each(function () {\n                var s = new Swiper(this, params);\n                if (!firstInstance) firstInstance = s;\n            });\n            return firstInstance;\n        };\n    }\n    \n    if (domLib) {\n        if (!('transitionEnd' in domLib.fn)) {\n            domLib.fn.transitionEnd = function (callback) {\n                var events = ['webkitTransitionEnd', 'transitionend', 'oTransitionEnd', 'MSTransitionEnd', 'msTransitionEnd'],\n                    i, j, dom = this;\n                function fireCallBack(e) {\n                    /*jshint validthis:true */\n                    if (e.target !== this) return;\n                    callback.call(this, e);\n                    for (i = 0; i < events.length; i++) {\n                        dom.off(events[i], fireCallBack);\n                    }\n                }\n                if (callback) {\n                    for (i = 0; i < events.length; i++) {\n                        dom.on(events[i], fireCallBack);\n                    }\n                }\n                return this;\n            };\n        }\n        if (!('transform' in domLib.fn)) {\n            domLib.fn.transform = function (transform) {\n                for (var i = 0; i < this.length; i++) {\n                    var elStyle = this[i].style;\n                    elStyle.webkitTransform = elStyle.MsTransform = elStyle.msTransform = elStyle.MozTransform = elStyle.OTransform = elStyle.transform = transform;\n                }\n                return this;\n            };\n        }\n        if (!('transition' in domLib.fn)) {\n            domLib.fn.transition = function (duration) {\n                if (typeof duration !== 'string') {\n                    duration = duration + 'ms';\n                }\n                for (var i = 0; i < this.length; i++) {\n                    var elStyle = this[i].style;\n                    elStyle.webkitTransitionDuration = elStyle.MsTransitionDuration = elStyle.msTransitionDuration = elStyle.MozTransitionDuration = elStyle.OTransitionDuration = elStyle.transitionDuration = duration;\n                }\n                return this;\n            };\n        }\n    }\n\n    window.Swiper = Swiper;\n})();\n/*===========================\nSwiper AMD Export\n===========================*/\nif (typeof(module) !== 'undefined')\n{\n    module.exports = window.Swiper;\n}\nelse if (typeof define === 'function' && define.amd) {\n    define([], function () {\n        'use strict';\n        return window.Swiper;\n    });\n}\n//# sourceMappingURL=maps/swiper.js.map\n"
  },
  {
    "path": "app_frontend/static/plugin/Swiper-3.3.1/gulpfile.js",
    "content": "(function(){\n    'use strict';\n    var gulp = require('gulp'),\n        connect = require('gulp-connect'),\n        open = require('gulp-open'),\n        less = require('gulp-less'),\n        rename = require('gulp-rename'),\n        header = require('gulp-header'),\n        path = require('path'),\n        uglify = require('gulp-uglify'),\n        sourcemaps = require('gulp-sourcemaps'),\n        minifyCSS = require('gulp-minify-css'),\n        tap = require('gulp-tap'),\n        concat = require('gulp-concat'),\n        jshint = require('gulp-jshint'),\n        stylish = require('jshint-stylish'),\n        fs = require('fs'),\n        paths = {\n            root: './',\n            build: {\n                root: 'build/',\n                styles: 'build/css/',\n                scripts: 'build/js/'\n            },\n            dist: {\n                root: 'dist/',\n                styles: 'dist/css/',\n                scripts: 'dist/js/'\n            },\n            playground: {\n                root: 'playground/'\n            },\n            source: {\n                root: 'src/',\n                styles: 'src/less/',\n                scripts: 'src/js/*.js'\n            },\n        },\n        swiper = {\n            filename: 'swiper',\n            jsFiles: [\n                'src/js/wrap-start.js',\n                'src/js/swiper-intro.js',\n                'src/js/core.js',\n                'src/js/effects.js',\n                'src/js/lazy-load.js',\n                'src/js/scrollbar.js',\n                'src/js/controller.js',\n                'src/js/hashnav.js',\n                'src/js/keyboard.js',\n                'src/js/mousewheel.js',\n                'src/js/parallax.js',\n                'src/js/plugins.js',\n                'src/js/emitter.js',\n                'src/js/a11y.js',\n                'src/js/init.js',\n                'src/js/swiper-outro.js',\n                'src/js/swiper-proto.js',\n                'src/js/dom.js',\n                'src/js/get-dom-lib.js',\n                'src/js/dom-plugins.js',\n                'src/js/wrap-end.js',\n                'src/js/amd.js'\n            ],\n            jQueryFiles : [\n                'src/js/wrap-start.js',\n                'src/js/swiper-intro.js',\n                'src/js/core.js',\n                'src/js/effects.js',\n                'src/js/lazy-load.js',\n                'src/js/scrollbar.js',\n                'src/js/controller.js',\n                'src/js/hashnav.js',\n                'src/js/keyboard.js',\n                'src/js/mousewheel.js',\n                'src/js/parallax.js',\n                'src/js/plugins.js',\n                'src/js/emitter.js',\n                'src/js/a11y.js',\n                'src/js/init.js',\n                'src/js/swiper-outro.js',\n                'src/js/swiper-proto.js',\n                'src/js/get-dom-lib.js',\n                'src/js/dom-plugins.js',\n                'src/js/wrap-end.js',\n                'src/js/amd.js'\n            ],\n            jQueryUMDFiles : [\n                'src/js/wrap-start-umd.js',\n                'src/js/swiper-intro.js',\n                'src/js/core.js',\n                'src/js/effects.js',\n                'src/js/lazy-load.js',\n                'src/js/scrollbar.js',\n                'src/js/controller.js',\n                'src/js/hashnav.js',\n                'src/js/keyboard.js',\n                'src/js/mousewheel.js',\n                'src/js/parallax.js',\n                'src/js/plugins.js',\n                'src/js/emitter.js',\n                'src/js/a11y.js',\n                'src/js/init.js',\n                'src/js/swiper-outro.js',\n                'src/js/swiper-proto.js',\n                'src/js/get-jquery.js',\n                'src/js/dom-plugins.js',\n                'src/js/wrap-end-umd.js',\n            ],\n            Framework7Files : [\n                'src/js/swiper-intro-f7.js',\n                'src/js/core.js',\n                'src/js/effects.js',\n                'src/js/lazy-load.js',\n                'src/js/scrollbar.js',\n                'src/js/controller.js',\n                'src/js/parallax.js',\n                'src/js/plugins.js',\n                'src/js/emitter.js',\n                'src/js/a11y.js',\n                'src/js/init.js',\n                'src/js/swiper-outro.js',\n                'src/js/swiper-proto.js',\n            ],\n            pkg: require('./bower.json'),\n            banner: [\n                '/**',\n                ' * Swiper <%= pkg.version %>',\n                ' * <%= pkg.description %>',\n                ' * ',\n                ' * <%= pkg.homepage %>',\n                ' * ',\n                ' * Copyright <%= date.year %>, <%= pkg.author %>',\n                ' * The iDangero.us',\n                ' * http://www.idangero.us/',\n                ' * ',\n                ' * Licensed under <%= pkg.license.join(\" & \") %>',\n                ' * ',\n                ' * Released on: <%= date.month %> <%= date.day %>, <%= date.year %>',\n                ' */',\n                ''].join('\\n'),\n            date: {\n                year: new Date().getFullYear(),\n                month: ('January February March April May June July August September October November December').split(' ')[new Date().getMonth()],\n                day: new Date().getDate()\n            }\n        };\n\n    function addJSIndent (file, t, minusIndent) {\n        var addIndent = '        ';\n        var filename = file.path.split('src/js/')[1];\n        if (['wrap-start.js', 'wrap-start-umd.js', 'wrap-end.js', 'wrap-end-umd.js', 'amd.js'].indexOf(filename) !== -1) {\n            addIndent = '';\n        }\n        if (filename === 'swiper-intro.js' || filename === 'swiper-intro-f7.js' || filename === 'swiper-outro.js' || filename === 'dom.js' || filename === 'get-dom-lib.js' || filename === 'get-jquery.js' || filename === 'dom-plugins.js' || filename === 'swiper-proto.js') addIndent = '    ';\n        if (minusIndent) {\n            addIndent = addIndent.substring(4);\n        }\n        if (addIndent !== '') {\n            var fileLines = fs.readFileSync(file.path).toString().split('\\n');\n            var newFileContents = '';\n            for (var i = 0; i < fileLines.length; i++) {\n                newFileContents += addIndent + fileLines[i] + (i === fileLines.length ? '' : '\\n');\n            }\n            file.contents = new Buffer(newFileContents);\n        }\n    }\n    gulp.task('scripts', function (cb) {\n        gulp.src(swiper.jsFiles)\n            .pipe(tap(function (file, t){\n                addJSIndent (file, t);\n            }))\n            .pipe(sourcemaps.init())\n            .pipe(concat(swiper.filename + '.js'))\n            .pipe(header(swiper.banner, { pkg : swiper.pkg, date: swiper.date } ))\n            .pipe(jshint())\n            .pipe(jshint.reporter(stylish))\n            .pipe(sourcemaps.write('./maps/'))\n            .pipe(gulp.dest(paths.build.scripts));\n\n            \n        gulp.src(swiper.jQueryFiles)\n            .pipe(tap(function (file, t){\n                addJSIndent (file, t);\n            }))\n            .pipe(sourcemaps.init())\n            .pipe(concat(swiper.filename + '.jquery.js'))\n            .pipe(header(swiper.banner, { pkg : swiper.pkg, date: swiper.date } ))\n            .pipe(sourcemaps.write('./maps/'))\n            .pipe(gulp.dest(paths.build.scripts));\n        gulp.src(swiper.jQueryUMDFiles)\n            .pipe(tap(function (file, t){\n                addJSIndent (file, t);\n            }))\n            .pipe(sourcemaps.init())\n            .pipe(concat(swiper.filename + '.jquery.umd.js'))\n            .pipe(header(swiper.banner, { pkg : swiper.pkg, date: swiper.date } ))\n            .pipe(sourcemaps.write('./maps/'))\n            .pipe(gulp.dest(paths.build.scripts));\n        gulp.src(swiper.Framework7Files)\n            .pipe(tap(function (file, t){\n                addJSIndent (file, t, true);\n            }))\n            .pipe(sourcemaps.init())\n            .pipe(concat(swiper.filename + '.framework7.js'))\n            .pipe(header(swiper.banner, { pkg : swiper.pkg, date: swiper.date } ))\n            .pipe(sourcemaps.write('./maps/'))\n            .pipe(gulp.dest(paths.build.scripts))\n            .pipe(connect.reload());\n        cb();\n    });\n    gulp.task('styles', function (cb) {\n\n        gulp.src(paths.source.styles + 'swiper.less')\n            .pipe(less({\n                paths: [ path.join(__dirname, 'less', 'includes') ]\n            }))\n            .pipe(header(swiper.banner, { pkg : swiper.pkg, date: swiper.date }))\n            .pipe(rename(function(path) {\n                path.basename = swiper.filename;\n            }))\n            .pipe(gulp.dest(paths.build.styles))\n            .pipe(connect.reload());\n\n        gulp.src([\n                paths.source.styles + 'core.less',\n                paths.source.styles + 'navigation-f7.less',\n                paths.source.styles + 'effects.less',\n                paths.source.styles + 'scrollbar.less',\n                paths.source.styles + 'preloader-f7.less',\n            ])\n            .pipe(concat(swiper.filename + '.framework7.less'))\n            .pipe(header('/* === Swiper === */\\n'))\n            .pipe(gulp.dest(paths.build.styles));\n        cb();\n    });\n    gulp.task('build', ['scripts', 'styles'], function (cb) {\n        cb();\n    });\n\n    gulp.task('dist', function () {\n        gulp.src([paths.build.scripts + swiper.filename + '.js'])\n            .pipe(gulp.dest(paths.dist.scripts))\n            .pipe(sourcemaps.init())\n            .pipe(uglify())\n            .pipe(header(swiper.banner, { pkg : swiper.pkg, date: swiper.date }))\n            .pipe(rename(function(path) {\n                path.basename = swiper.filename + '.min';\n            }))\n            .pipe(sourcemaps.write('./maps'))\n            .pipe(gulp.dest(paths.dist.scripts));\n\n        gulp.src([paths.build.scripts + swiper.filename + '.jquery.js'])\n            .pipe(gulp.dest(paths.dist.scripts))\n            .pipe(sourcemaps.init())\n            .pipe(uglify())\n            .pipe(header(swiper.banner, { pkg : swiper.pkg, date: swiper.date } ))\n            .pipe(rename(function(path) {\n                path.basename = swiper.filename + '.jquery.min';\n            }))\n            .pipe(sourcemaps.write('./maps'))\n            .pipe(gulp.dest(paths.dist.scripts));\n\n        gulp.src([paths.build.scripts + swiper.filename + '.jquery.umd.js'])\n            .pipe(gulp.dest(paths.dist.scripts))\n            .pipe(sourcemaps.init())\n            .pipe(uglify())\n            .pipe(header(swiper.banner, { pkg : swiper.pkg, date: swiper.date } ))\n            .pipe(rename(function(path) {\n                path.basename = swiper.filename + '.jquery.umd.min';\n            }))\n            .pipe(sourcemaps.write('./maps'))\n            .pipe(gulp.dest(paths.dist.scripts));\n\n        gulp.src(paths.build.styles + '*.css')\n            .pipe(gulp.dest(paths.dist.styles))\n            .pipe(minifyCSS({\n                advanced: false,\n                aggressiveMerging: false,\n            }))\n            .pipe(header(swiper.banner, { pkg : swiper.pkg, date: swiper.date }))\n            .pipe(rename(function(path) {\n                path.basename = swiper.filename + '.min';\n            }))\n            .pipe(gulp.dest(paths.dist.styles));\n    });\n\n    gulp.task('watch', function () {\n        gulp.watch(paths.source.scripts, [ 'scripts' ]);\n        gulp.watch(paths.source.styles + '*.less', [ 'styles' ]);\n    });\n\n    gulp.task('connect', function () {\n        return connect.server({\n            root: [ paths.root ],\n            livereload: true,\n            port:'3000'\n        });\n    });\n\n    gulp.task('open', function () {\n        return gulp.src(paths.playground.root + 'index.html').pipe(open({ uri: 'http://localhost:3000/' + paths.playground.root + 'index.html'}));\n    });\n\n    gulp.task('server', [ 'watch', 'connect', 'open' ]);\n\n    gulp.task('default', [ 'server' ]);\n})();\n"
  },
  {
    "path": "app_frontend/static/plugin/Swiper-3.3.1/package.js",
    "content": "var version = '3.3.1';\n\nPackage.describe({\n  name: 'nolimits4web:swiper',\n  summary: 'iDangero.us Swiper - mobile touch slider with hardware accelerated transitions and native behavior',\n  version: version,\n  git: 'https://github.com/nolimits4web/Swiper'\n});\n\nPackage.onUse(function (api) {\n  api.versionsFrom('1.1.0.2');\n\n  api.addFiles([\n    'dist/css/swiper.min.css',\n    'dist/js/swiper.js'\n    ], ['client']\n  );\n\n  // Since swiper is attached to window, we do not need to export Swiper\n  // api.export('Swiper');\n});\n\nPackage.onTest(function (api) {\n});\n"
  },
  {
    "path": "app_frontend/static/plugin/Swiper-3.3.1/package.json",
    "content": "{\n  \"name\": \"swiper\",\n  \"version\": \"3.3.1\",\n  \"description\": \"Most modern mobile touch slider and framework with hardware accelerated transitions\",\n  \"main\": \"dist/js/swiper.js\",\n  \"files\": [\"dist\", \"src\", \"*.json\", \"*.js\"],\n  \"repository\": {\n    \"type\": \"git\",\n    \"url\": \"https://github.com/nolimits4web/Swiper.git\"\n  },\n  \"keywords\": [\"swiper\", \"swipe\", \"slider\", \"touch\", \"ios\", \"mobile\", \"cordova\", \"phonegap\", \"app\", \"framework\", \"carousel\", \"gallery\"],\n  \"author\": \"Vladimir Kharlampidi\",\n  \"license\": \"MIT\",\n  \"bugs\": {\n    \"url\": \"https://github.com/nolimits4web/Swiper/issues\"\n  },\n  \"homepage\": \"http://www.idangero.us/swiper/\",\n  \"engines\": {\n    \"node\": \">= 0.10.0\"\n  },\n  \"devDependencies\": {\n    \"jshint\": \"~2.9.1\",\n    \"gulp\": \"~3.9.0\",\n    \"gulp-less\": \"~3.0.5\",\n    \"gulp-connect\": \"~2.3.1\",\n    \"gulp-open\": \"~1.0.0\",\n    \"gulp-uglify\": \"~1.5.1\",\n    \"gulp-sourcemaps\": \"~1.6.0\",\n    \"gulp-minify-css\": \"1.2.3\",\n    \"gulp-jshint\": \"~2.0.0\",\n    \"gulp-concat\": \"~2.6.0\",\n    \"gulp-rename\": \"~1.2.2\",\n    \"gulp-header\": \"~1.7.1\",\n    \"gulp-tap\": \"~0.1.3\",\n    \"jshint-stylish\": \"~2.1.0\"\n  },\n  \"scripts\": {\n    \"test\": \"gulp build\"\n  },\n  \"style\": \"dist/css/swiper.css\"\n}\n"
  },
  {
    "path": "app_frontend/static/plugin/Swiper-3.3.1/playground/index.html",
    "content": "<!doctype html>\n<html lang=\"en\">\n<head>\n    <meta charset=\"UTF-8\">\n    <title>Swiper Playground</title>\n    <link rel=\"stylesheet\" href=\"../build/css/swiper.css\">\n    <meta name=\"viewport\" content=\"width=device-width\">\n</head>\n<body>\n    <div class=\"swiper-container\">\n        <div class=\"swiper-scrollbar\"></div>\n        <div class=\"swiper-button-prev\"></div>\n        <div class=\"swiper-button-next\"></div>\n        <div class=\"swiper-wrapper\">\n            <div class=\"swiper-slide\">Slide 1</div>\n            <div class=\"swiper-slide\">Slide 2</div>\n            <div class=\"swiper-slide\">Slide 3</div>\n            <div class=\"swiper-slide\">Slide 4</div>\n            <div class=\"swiper-slide\">Slide 5</div>\n            <div class=\"swiper-slide\">Slide 6</div>\n            <div class=\"swiper-slide\">Slide 7</div>\n            <div class=\"swiper-slide\">Slide 8</div>\n            <div class=\"swiper-slide\">Slide 9</div>\n            <div class=\"swiper-slide\">Slide 10</div>\n        </div>\n        <div class=\"swiper-pagination\"></div>\n    </div>\n    <style>\n    body, html {\n        padding: 0;\n        margin: 0;\n        position: relative;\n        height: 100%;\n    }\n    .swiper-container {\n        width: 100%;\n        height: 300px;\n        margin: 50px auto;\n    }\n    .swiper-slide {\n        background: #f1f1f1;\n        color:#000;\n        text-align: center;\n        line-height: 300px;\n    }\n    </style>\n    <script src=\"../build/js/swiper.js\"></script>\n    <script>\n        var swiper = new Swiper('.swiper-container', {\n            spaceBetween: 50,\n            slidesPerView: 2,\n            centeredSlides: true,\n            slideToClickedSlide: true,\n            grabCursor: true,\n            nextButton: '.swiper-button-next',\n            prevButton: '.swiper-button-prev',\n            scrollbar: '.swiper-scrollbar',\n            pagination: '.swiper-pagination',\n        });\n    </script>\n</body>\n</html>"
  },
  {
    "path": "app_frontend/static/plugin/Swiper-3.3.1/src/js/a11y.js",
    "content": "// Accessibility tools\ns.a11y = {\n    makeFocusable: function ($el) {\n        $el.attr('tabIndex', '0');\n        return $el;\n    },\n    addRole: function ($el, role) {\n        $el.attr('role', role);\n        return $el;\n    },\n\n    addLabel: function ($el, label) {\n        $el.attr('aria-label', label);\n        return $el;\n    },\n\n    disable: function ($el) {\n        $el.attr('aria-disabled', true);\n        return $el;\n    },\n\n    enable: function ($el) {\n        $el.attr('aria-disabled', false);\n        return $el;\n    },\n\n    onEnterKey: function (event) {\n        if (event.keyCode !== 13) return;\n        if ($(event.target).is(s.params.nextButton)) {\n            s.onClickNext(event);\n            if (s.isEnd) {\n                s.a11y.notify(s.params.lastSlideMessage);\n            }\n            else {\n                s.a11y.notify(s.params.nextSlideMessage);\n            }\n        }\n        else if ($(event.target).is(s.params.prevButton)) {\n            s.onClickPrev(event);\n            if (s.isBeginning) {\n                s.a11y.notify(s.params.firstSlideMessage);\n            }\n            else {\n                s.a11y.notify(s.params.prevSlideMessage);\n            }\n        }\n        if ($(event.target).is('.' + s.params.bulletClass)) {\n            $(event.target)[0].click();\n        }\n    },\n\n    liveRegion: $('<span class=\"swiper-notification\" aria-live=\"assertive\" aria-atomic=\"true\"></span>'),\n\n    notify: function (message) {\n        var notification = s.a11y.liveRegion;\n        if (notification.length === 0) return;\n        notification.html('');\n        notification.html(message);\n    },\n    init: function () {\n        // Setup accessibility\n        if (s.params.nextButton && s.nextButton && s.nextButton.length > 0) {\n            s.a11y.makeFocusable(s.nextButton);\n            s.a11y.addRole(s.nextButton, 'button');\n            s.a11y.addLabel(s.nextButton, s.params.nextSlideMessage);\n        }\n        if (s.params.prevButton && s.prevButton && s.prevButton.length > 0) {\n            s.a11y.makeFocusable(s.prevButton);\n            s.a11y.addRole(s.prevButton, 'button');\n            s.a11y.addLabel(s.prevButton, s.params.prevSlideMessage);\n        }\n\n        $(s.container).append(s.a11y.liveRegion);\n    },\n    initPagination: function () {\n        if (s.params.pagination && s.params.paginationClickable && s.bullets && s.bullets.length) {\n            s.bullets.each(function () {\n                var bullet = $(this);\n                s.a11y.makeFocusable(bullet);\n                s.a11y.addRole(bullet, 'button');\n                s.a11y.addLabel(bullet, s.params.paginationBulletMessage.replace(/{{index}}/, bullet.index() + 1));\n            });\n        }\n    },\n    destroy: function () {\n        if (s.a11y.liveRegion && s.a11y.liveRegion.length > 0) s.a11y.liveRegion.remove();\n    }\n};\n"
  },
  {
    "path": "app_frontend/static/plugin/Swiper-3.3.1/src/js/amd.js",
    "content": "/*===========================\nSwiper AMD Export\n===========================*/\nif (typeof(module) !== 'undefined')\n{\n    module.exports = window.Swiper;\n}\nelse if (typeof define === 'function' && define.amd) {\n    define([], function () {\n        'use strict';\n        return window.Swiper;\n    });\n}"
  },
  {
    "path": "app_frontend/static/plugin/Swiper-3.3.1/src/js/controller.js",
    "content": "/*=========================\n  Controller\n  ===========================*/\ns.controller = {\n    LinearSpline: function (x, y) {\n        this.x = x;\n        this.y = y;\n        this.lastIndex = x.length - 1;\n        // Given an x value (x2), return the expected y2 value:\n        // (x1,y1) is the known point before given value,\n        // (x3,y3) is the known point after given value.\n        var i1, i3;\n        var l = this.x.length;\n\n        this.interpolate = function (x2) {\n            if (!x2) return 0;\n\n            // Get the indexes of x1 and x3 (the array indexes before and after given x2):\n            i3 = binarySearch(this.x, x2);\n            i1 = i3 - 1;\n\n            // We have our indexes i1 & i3, so we can calculate already:\n            // y2 := ((x2−x1) × (y3−y1)) ÷ (x3−x1) + y1\n            return ((x2 - this.x[i1]) * (this.y[i3] - this.y[i1])) / (this.x[i3] - this.x[i1]) + this.y[i1];\n        };\n\n        var binarySearch = (function() {\n            var maxIndex, minIndex, guess;\n            return function(array, val) {\n                minIndex = -1;\n                maxIndex = array.length;\n                while (maxIndex - minIndex > 1)\n                    if (array[guess = maxIndex + minIndex >> 1] <= val) {\n                        minIndex = guess;\n                    } else {\n                        maxIndex = guess;\n                    }\n                return maxIndex;\n            };\n        })();\n    },\n    //xxx: for now i will just save one spline function to to\n    getInterpolateFunction: function(c){\n        if(!s.controller.spline) s.controller.spline = s.params.loop ?\n            new s.controller.LinearSpline(s.slidesGrid, c.slidesGrid) :\n            new s.controller.LinearSpline(s.snapGrid, c.snapGrid);\n    },\n    setTranslate: function (translate, byController) {\n       var controlled = s.params.control;\n       var multiplier, controlledTranslate;\n       function setControlledTranslate(c) {\n            // this will create an Interpolate function based on the snapGrids\n            // x is the Grid of the scrolled scroller and y will be the controlled scroller\n            // it makes sense to create this only once and recall it for the interpolation\n            // the function does a lot of value caching for performance\n            translate = c.rtl && c.params.direction === 'horizontal' ? -s.translate : s.translate;\n            if (s.params.controlBy === 'slide') {\n                s.controller.getInterpolateFunction(c);\n                // i am not sure why the values have to be multiplicated this way, tried to invert the snapGrid\n                // but it did not work out\n                controlledTranslate = -s.controller.spline.interpolate(-translate);\n            }\n\n            if(!controlledTranslate || s.params.controlBy === 'container'){\n                multiplier = (c.maxTranslate() - c.minTranslate()) / (s.maxTranslate() - s.minTranslate());\n                controlledTranslate = (translate - s.minTranslate()) * multiplier + c.minTranslate();\n            }\n\n            if (s.params.controlInverse) {\n                controlledTranslate = c.maxTranslate() - controlledTranslate;\n            }\n            c.updateProgress(controlledTranslate);\n            c.setWrapperTranslate(controlledTranslate, false, s);\n            c.updateActiveIndex();\n       }\n       if (s.isArray(controlled)) {\n           for (var i = 0; i < controlled.length; i++) {\n               if (controlled[i] !== byController && controlled[i] instanceof Swiper) {\n                   setControlledTranslate(controlled[i]);\n               }\n           }\n       }\n       else if (controlled instanceof Swiper && byController !== controlled) {\n\n           setControlledTranslate(controlled);\n       }\n    },\n    setTransition: function (duration, byController) {\n        var controlled = s.params.control;\n        var i;\n        function setControlledTransition(c) {\n            c.setWrapperTransition(duration, s);\n            if (duration !== 0) {\n                c.onTransitionStart();\n                c.wrapper.transitionEnd(function(){\n                    if (!controlled) return;\n                    if (c.params.loop && s.params.controlBy === 'slide') {\n                        c.fixLoop();\n                    }\n                    c.onTransitionEnd();\n\n                });\n            }\n        }\n        if (s.isArray(controlled)) {\n            for (i = 0; i < controlled.length; i++) {\n                if (controlled[i] !== byController && controlled[i] instanceof Swiper) {\n                    setControlledTransition(controlled[i]);\n                }\n            }\n        }\n        else if (controlled instanceof Swiper && byController !== controlled) {\n            setControlledTransition(controlled);\n        }\n    }\n};"
  },
  {
    "path": "app_frontend/static/plugin/Swiper-3.3.1/src/js/core.js",
    "content": "var defaults = {\n    direction: 'horizontal',\n    touchEventsTarget: 'container',\n    initialSlide: 0,\n    speed: 300,\n    // autoplay\n    autoplay: false,\n    autoplayDisableOnInteraction: true,\n    autoplayStopOnLast: false,\n    // To support iOS's swipe-to-go-back gesture (when being used in-app, with UIWebView).\n    iOSEdgeSwipeDetection: false,\n    iOSEdgeSwipeThreshold: 20,\n    // Free mode\n    freeMode: false,\n    freeModeMomentum: true,\n    freeModeMomentumRatio: 1,\n    freeModeMomentumBounce: true,\n    freeModeMomentumBounceRatio: 1,\n    freeModeSticky: false,\n    freeModeMinimumVelocity: 0.02,\n    // Autoheight\n    autoHeight: false,\n    // Set wrapper width\n    setWrapperSize: false,\n    // Virtual Translate\n    virtualTranslate: false,\n    // Effects\n    effect: 'slide', // 'slide' or 'fade' or 'cube' or 'coverflow' or 'flip'\n    coverflow: {\n        rotate: 50,\n        stretch: 0,\n        depth: 100,\n        modifier: 1,\n        slideShadows : true\n    },\n    flip: {\n        slideShadows : true,\n        limitRotation: true\n    },\n    cube: {\n        slideShadows: true,\n        shadow: true,\n        shadowOffset: 20,\n        shadowScale: 0.94\n    },\n    fade: {\n        crossFade: false\n    },\n    // Parallax\n    parallax: false,\n    // Scrollbar\n    scrollbar: null,\n    scrollbarHide: true,\n    scrollbarDraggable: false,\n    scrollbarSnapOnRelease: false,\n    // Keyboard Mousewheel\n    keyboardControl: false,\n    mousewheelControl: false,\n    mousewheelReleaseOnEdges: false,\n    mousewheelInvert: false,\n    mousewheelForceToAxis: false,\n    mousewheelSensitivity: 1,\n    // Hash Navigation\n    hashnav: false,\n    // Breakpoints\n    breakpoints: undefined,\n    // Slides grid\n    spaceBetween: 0,\n    slidesPerView: 1,\n    slidesPerColumn: 1,\n    slidesPerColumnFill: 'column',\n    slidesPerGroup: 1,\n    centeredSlides: false,\n    slidesOffsetBefore: 0, // in px\n    slidesOffsetAfter: 0, // in px\n    // Round length\n    roundLengths: false,\n    // Touches\n    touchRatio: 1,\n    touchAngle: 45,\n    simulateTouch: true,\n    shortSwipes: true,\n    longSwipes: true,\n    longSwipesRatio: 0.5,\n    longSwipesMs: 300,\n    followFinger: true,\n    onlyExternal: false,\n    threshold: 0,\n    touchMoveStopPropagation: true,\n    // Unique Navigation Elements\n    uniqueNavElements: true,\n    // Pagination\n    pagination: null,\n    paginationElement: 'span',\n    paginationClickable: false,\n    paginationHide: false,\n    paginationBulletRender: null,\n    paginationProgressRender: null,\n    paginationFractionRender: null,\n    paginationCustomRender: null,\n    paginationType: 'bullets', // 'bullets' or 'progress' or 'fraction' or 'custom'\n    // Resistance\n    resistance: true,\n    resistanceRatio: 0.85,\n    // Next/prev buttons\n    nextButton: null,\n    prevButton: null,\n    // Progress\n    watchSlidesProgress: false,\n    watchSlidesVisibility: false,\n    // Cursor\n    grabCursor: false,\n    // Clicks\n    preventClicks: true,\n    preventClicksPropagation: true,\n    slideToClickedSlide: false,\n    // Lazy Loading\n    lazyLoading: false,\n    lazyLoadingInPrevNext: false,\n    lazyLoadingInPrevNextAmount: 1,\n    lazyLoadingOnTransitionStart: false,\n    // Images\n    preloadImages: true,\n    updateOnImagesReady: true,\n    // loop\n    loop: false,\n    loopAdditionalSlides: 0,\n    loopedSlides: null,\n    // Control\n    control: undefined,\n    controlInverse: false,\n    controlBy: 'slide', //or 'container'\n    // Swiping/no swiping\n    allowSwipeToPrev: true,\n    allowSwipeToNext: true,\n    swipeHandler: null, //'.swipe-handler',\n    noSwiping: true,\n    noSwipingClass: 'swiper-no-swiping',\n    // NS\n    slideClass: 'swiper-slide',\n    slideActiveClass: 'swiper-slide-active',\n    slideVisibleClass: 'swiper-slide-visible',\n    slideDuplicateClass: 'swiper-slide-duplicate',\n    slideNextClass: 'swiper-slide-next',\n    slidePrevClass: 'swiper-slide-prev',\n    wrapperClass: 'swiper-wrapper',\n    bulletClass: 'swiper-pagination-bullet',\n    bulletActiveClass: 'swiper-pagination-bullet-active',\n    buttonDisabledClass: 'swiper-button-disabled',\n    paginationCurrentClass: 'swiper-pagination-current',\n    paginationTotalClass: 'swiper-pagination-total',\n    paginationHiddenClass: 'swiper-pagination-hidden',\n    paginationProgressbarClass: 'swiper-pagination-progressbar',\n    // Observer\n    observer: false,\n    observeParents: false,\n    // Accessibility\n    a11y: false,\n    prevSlideMessage: 'Previous slide',\n    nextSlideMessage: 'Next slide',\n    firstSlideMessage: 'This is the first slide',\n    lastSlideMessage: 'This is the last slide',\n    paginationBulletMessage: 'Go to slide {{index}}',\n    // Callbacks\n    runCallbacksOnInit: true\n    /*\n    Callbacks:\n    onInit: function (swiper)\n    onDestroy: function (swiper)\n    onClick: function (swiper, e)\n    onTap: function (swiper, e)\n    onDoubleTap: function (swiper, e)\n    onSliderMove: function (swiper, e)\n    onSlideChangeStart: function (swiper)\n    onSlideChangeEnd: function (swiper)\n    onTransitionStart: function (swiper)\n    onTransitionEnd: function (swiper)\n    onImagesReady: function (swiper)\n    onProgress: function (swiper, progress)\n    onTouchStart: function (swiper, e)\n    onTouchMove: function (swiper, e)\n    onTouchMoveOpposite: function (swiper, e)\n    onTouchEnd: function (swiper, e)\n    onReachBeginning: function (swiper)\n    onReachEnd: function (swiper)\n    onSetTransition: function (swiper, duration)\n    onSetTranslate: function (swiper, translate)\n    onAutoplayStart: function (swiper)\n    onAutoplayStop: function (swiper),\n    onLazyImageLoad: function (swiper, slide, image)\n    onLazyImageReady: function (swiper, slide, image)\n    */\n\n};\nvar initialVirtualTranslate = params && params.virtualTranslate;\n\nparams = params || {};\nvar originalParams = {};\nfor (var param in params) {\n    if (typeof params[param] === 'object' && params[param] !== null && !(params[param].nodeType || params[param] === window || params[param] === document || (typeof Dom7 !== 'undefined' && params[param] instanceof Dom7) || (typeof jQuery !== 'undefined' && params[param] instanceof jQuery))) {\n        originalParams[param] = {};\n        for (var deepParam in params[param]) {\n            originalParams[param][deepParam] = params[param][deepParam];\n        }\n    }\n    else {\n        originalParams[param] = params[param];\n    }\n}\nfor (var def in defaults) {\n    if (typeof params[def] === 'undefined') {\n        params[def] = defaults[def];\n    }\n    else if (typeof params[def] === 'object') {\n        for (var deepDef in defaults[def]) {\n            if (typeof params[def][deepDef] === 'undefined') {\n                params[def][deepDef] = defaults[def][deepDef];\n            }\n        }\n    }\n}\n\n// Swiper\nvar s = this;\n\n// Params\ns.params = params;\ns.originalParams = originalParams;\n\n// Classname\ns.classNames = [];\n/*=========================\n  Dom Library and plugins\n  ===========================*/\nif (typeof $ !== 'undefined' && typeof Dom7 !== 'undefined'){\n    $ = Dom7;\n}\nif (typeof $ === 'undefined') {\n    if (typeof Dom7 === 'undefined') {\n        $ = window.Dom7 || window.Zepto || window.jQuery;\n    }\n    else {\n        $ = Dom7;\n    }\n    if (!$) return;\n}\n// Export it to Swiper instance\ns.$ = $;\n\n/*=========================\n  Breakpoints\n  ===========================*/\ns.currentBreakpoint = undefined;\ns.getActiveBreakpoint = function () {\n    //Get breakpoint for window width\n    if (!s.params.breakpoints) return false;\n    var breakpoint = false;\n    var points = [], point;\n    for ( point in s.params.breakpoints ) {\n        if (s.params.breakpoints.hasOwnProperty(point)) {\n            points.push(point);\n        }\n    }\n    points.sort(function (a, b) {\n        return parseInt(a, 10) > parseInt(b, 10);\n    });\n    for (var i = 0; i < points.length; i++) {\n        point = points[i];\n        if (point >= window.innerWidth && !breakpoint) {\n            breakpoint = point;\n        }\n    }\n    return breakpoint || 'max';\n};\ns.setBreakpoint = function () {\n    //Set breakpoint for window width and update parameters\n    var breakpoint = s.getActiveBreakpoint();\n    if (breakpoint && s.currentBreakpoint !== breakpoint) {\n        var breakPointsParams = breakpoint in s.params.breakpoints ? s.params.breakpoints[breakpoint] : s.originalParams;\n        var needsReLoop = s.params.loop && (breakPointsParams.slidesPerView !== s.params.slidesPerView);\n        for ( var param in breakPointsParams ) {\n            s.params[param] = breakPointsParams[param];\n        }\n        s.currentBreakpoint = breakpoint;\n        if(needsReLoop && s.destroyLoop) {\n            s.reLoop(true);\n        }\n    }\n};\n// Set breakpoint on load\nif (s.params.breakpoints) {\n    s.setBreakpoint();\n}\n\n/*=========================\n  Preparation - Define Container, Wrapper and Pagination\n  ===========================*/\ns.container = $(container);\nif (s.container.length === 0) return;\nif (s.container.length > 1) {\n    var swipers = [];\n    s.container.each(function () {\n        var container = this;\n        swipers.push(new Swiper(this, params));\n    });\n    return swipers;\n}\n\n// Save instance in container HTML Element and in data\ns.container[0].swiper = s;\ns.container.data('swiper', s);\n\ns.classNames.push('swiper-container-' + s.params.direction);\n\nif (s.params.freeMode) {\n    s.classNames.push('swiper-container-free-mode');\n}\nif (!s.support.flexbox) {\n    s.classNames.push('swiper-container-no-flexbox');\n    s.params.slidesPerColumn = 1;\n}\nif (s.params.autoHeight) {\n    s.classNames.push('swiper-container-autoheight');\n}\n// Enable slides progress when required\nif (s.params.parallax || s.params.watchSlidesVisibility) {\n    s.params.watchSlidesProgress = true;\n}\n// Coverflow / 3D\nif (['cube', 'coverflow', 'flip'].indexOf(s.params.effect) >= 0) {\n    if (s.support.transforms3d) {\n        s.params.watchSlidesProgress = true;\n        s.classNames.push('swiper-container-3d');\n    }\n    else {\n        s.params.effect = 'slide';\n    }\n}\nif (s.params.effect !== 'slide') {\n    s.classNames.push('swiper-container-' + s.params.effect);\n}\nif (s.params.effect === 'cube') {\n    s.params.resistanceRatio = 0;\n    s.params.slidesPerView = 1;\n    s.params.slidesPerColumn = 1;\n    s.params.slidesPerGroup = 1;\n    s.params.centeredSlides = false;\n    s.params.spaceBetween = 0;\n    s.params.virtualTranslate = true;\n    s.params.setWrapperSize = false;\n}\nif (s.params.effect === 'fade' || s.params.effect === 'flip') {\n    s.params.slidesPerView = 1;\n    s.params.slidesPerColumn = 1;\n    s.params.slidesPerGroup = 1;\n    s.params.watchSlidesProgress = true;\n    s.params.spaceBetween = 0;\n    s.params.setWrapperSize = false;\n    if (typeof initialVirtualTranslate === 'undefined') {\n        s.params.virtualTranslate = true;\n    }\n}\n\n// Grab Cursor\nif (s.params.grabCursor && s.support.touch) {\n    s.params.grabCursor = false;\n}\n\n// Wrapper\ns.wrapper = s.container.children('.' + s.params.wrapperClass);\n\n// Pagination\nif (s.params.pagination) {\n    s.paginationContainer = $(s.params.pagination);\n    if (s.params.uniqueNavElements && typeof s.params.pagination === 'string' && s.paginationContainer.length > 1 && s.container.find(s.params.pagination).length === 1) {\n        s.paginationContainer = s.container.find(s.params.pagination);\n    }\n\n    if (s.params.paginationType === 'bullets' && s.params.paginationClickable) {\n        s.paginationContainer.addClass('swiper-pagination-clickable');\n    }\n    else {\n        s.params.paginationClickable = false;\n    }\n    s.paginationContainer.addClass('swiper-pagination-' + s.params.paginationType);\n}\n// Next/Prev Buttons\nif (s.params.nextButton || s.params.prevButton) {\n    if (s.params.nextButton) {\n        s.nextButton = $(s.params.nextButton);\n        if (s.params.uniqueNavElements && typeof s.params.nextButton === 'string' && s.nextButton.length > 1 && s.container.find(s.params.nextButton).length === 1) {\n            s.nextButton = s.container.find(s.params.nextButton);\n        }\n    }\n    if (s.params.prevButton) {\n        s.prevButton = $(s.params.prevButton);\n        if (s.params.uniqueNavElements && typeof s.params.prevButton === 'string' && s.prevButton.length > 1 && s.container.find(s.params.prevButton).length === 1) {\n            s.prevButton = s.container.find(s.params.prevButton);\n        }\n    }\n}\n\n// Is Horizontal\ns.isHorizontal = function () {\n    return s.params.direction === 'horizontal';\n};\n// s.isH = isH;\n\n// RTL\ns.rtl = s.isHorizontal() && (s.container[0].dir.toLowerCase() === 'rtl' || s.container.css('direction') === 'rtl');\nif (s.rtl) {\n    s.classNames.push('swiper-container-rtl');\n}\n\n// Wrong RTL support\nif (s.rtl) {\n    s.wrongRTL = s.wrapper.css('display') === '-webkit-box';\n}\n\n// Columns\nif (s.params.slidesPerColumn > 1) {\n    s.classNames.push('swiper-container-multirow');\n}\n\n// Check for Android\nif (s.device.android) {\n    s.classNames.push('swiper-container-android');\n}\n\n// Add classes\ns.container.addClass(s.classNames.join(' '));\n\n// Translate\ns.translate = 0;\n\n// Progress\ns.progress = 0;\n\n// Velocity\ns.velocity = 0;\n\n/*=========================\n  Locks, unlocks\n  ===========================*/\ns.lockSwipeToNext = function () {\n    s.params.allowSwipeToNext = false;\n};\ns.lockSwipeToPrev = function () {\n    s.params.allowSwipeToPrev = false;\n};\ns.lockSwipes = function () {\n    s.params.allowSwipeToNext = s.params.allowSwipeToPrev = false;\n};\ns.unlockSwipeToNext = function () {\n    s.params.allowSwipeToNext = true;\n};\ns.unlockSwipeToPrev = function () {\n    s.params.allowSwipeToPrev = true;\n};\ns.unlockSwipes = function () {\n    s.params.allowSwipeToNext = s.params.allowSwipeToPrev = true;\n};\n\n/*=========================\n  Round helper\n  ===========================*/\nfunction round(a) {\n    return Math.floor(a);\n}\n/*=========================\n  Set grab cursor\n  ===========================*/\nif (s.params.grabCursor) {\n    s.container[0].style.cursor = 'move';\n    s.container[0].style.cursor = '-webkit-grab';\n    s.container[0].style.cursor = '-moz-grab';\n    s.container[0].style.cursor = 'grab';\n}\n/*=========================\n  Update on Images Ready\n  ===========================*/\ns.imagesToLoad = [];\ns.imagesLoaded = 0;\n\ns.loadImage = function (imgElement, src, srcset, checkForComplete, callback) {\n    var image;\n    function onReady () {\n        if (callback) callback();\n    }\n    if (!imgElement.complete || !checkForComplete) {\n        if (src) {\n            image = new window.Image();\n            image.onload = onReady;\n            image.onerror = onReady;\n            if (srcset) {\n                image.srcset = srcset;\n            }\n            if (src) {\n                image.src = src;\n            }\n        } else {\n            onReady();\n        }\n\n    } else {//image already loaded...\n        onReady();\n    }\n};\ns.preloadImages = function () {\n    s.imagesToLoad = s.container.find('img');\n    function _onReady() {\n        if (typeof s === 'undefined' || s === null) return;\n        if (s.imagesLoaded !== undefined) s.imagesLoaded++;\n        if (s.imagesLoaded === s.imagesToLoad.length) {\n            if (s.params.updateOnImagesReady) s.update();\n            s.emit('onImagesReady', s);\n        }\n    }\n    for (var i = 0; i < s.imagesToLoad.length; i++) {\n        s.loadImage(s.imagesToLoad[i], (s.imagesToLoad[i].currentSrc || s.imagesToLoad[i].getAttribute('src')), (s.imagesToLoad[i].srcset || s.imagesToLoad[i].getAttribute('srcset')), true, _onReady);\n    }\n};\n\n/*=========================\n  Autoplay\n  ===========================*/\ns.autoplayTimeoutId = undefined;\ns.autoplaying = false;\ns.autoplayPaused = false;\nfunction autoplay() {\n    s.autoplayTimeoutId = setTimeout(function () {\n        if (s.params.loop) {\n            s.fixLoop();\n            s._slideNext();\n            s.emit('onAutoplay', s);\n        }\n        else {\n            if (!s.isEnd) {\n                s._slideNext();\n                s.emit('onAutoplay', s);\n            }\n            else {\n                if (!params.autoplayStopOnLast) {\n                    s._slideTo(0);\n                    s.emit('onAutoplay', s);\n                }\n                else {\n                    s.stopAutoplay();\n                }\n            }\n        }\n    }, s.params.autoplay);\n}\ns.startAutoplay = function () {\n    if (typeof s.autoplayTimeoutId !== 'undefined') return false;\n    if (!s.params.autoplay) return false;\n    if (s.autoplaying) return false;\n    s.autoplaying = true;\n    s.emit('onAutoplayStart', s);\n    autoplay();\n};\ns.stopAutoplay = function (internal) {\n    if (!s.autoplayTimeoutId) return;\n    if (s.autoplayTimeoutId) clearTimeout(s.autoplayTimeoutId);\n    s.autoplaying = false;\n    s.autoplayTimeoutId = undefined;\n    s.emit('onAutoplayStop', s);\n};\ns.pauseAutoplay = function (speed) {\n    if (s.autoplayPaused) return;\n    if (s.autoplayTimeoutId) clearTimeout(s.autoplayTimeoutId);\n    s.autoplayPaused = true;\n    if (speed === 0) {\n        s.autoplayPaused = false;\n        autoplay();\n    }\n    else {\n        s.wrapper.transitionEnd(function () {\n            if (!s) return;\n            s.autoplayPaused = false;\n            if (!s.autoplaying) {\n                s.stopAutoplay();\n            }\n            else {\n                autoplay();\n            }\n        });\n    }\n};\n/*=========================\n  Min/Max Translate\n  ===========================*/\ns.minTranslate = function () {\n    return (-s.snapGrid[0]);\n};\ns.maxTranslate = function () {\n    return (-s.snapGrid[s.snapGrid.length - 1]);\n};\n/*=========================\n  Slider/slides sizes\n  ===========================*/\ns.updateAutoHeight = function () {\n    // Update Height\n    var slide = s.slides.eq(s.activeIndex)[0];\n    if (typeof slide !== 'undefined') {\n        var newHeight = slide.offsetHeight;\n        if (newHeight) s.wrapper.css('height', newHeight + 'px');\n    }\n};\ns.updateContainerSize = function () {\n    var width, height;\n    if (typeof s.params.width !== 'undefined') {\n        width = s.params.width;\n    }\n    else {\n        width = s.container[0].clientWidth;\n    }\n    if (typeof s.params.height !== 'undefined') {\n        height = s.params.height;\n    }\n    else {\n        height = s.container[0].clientHeight;\n    }\n    if (width === 0 && s.isHorizontal() || height === 0 && !s.isHorizontal()) {\n        return;\n    }\n\n    //Subtract paddings\n    width = width - parseInt(s.container.css('padding-left'), 10) - parseInt(s.container.css('padding-right'), 10);\n    height = height - parseInt(s.container.css('padding-top'), 10) - parseInt(s.container.css('padding-bottom'), 10);\n\n    // Store values\n    s.width = width;\n    s.height = height;\n    s.size = s.isHorizontal() ? s.width : s.height;\n};\n\ns.updateSlidesSize = function () {\n    s.slides = s.wrapper.children('.' + s.params.slideClass);\n    s.snapGrid = [];\n    s.slidesGrid = [];\n    s.slidesSizesGrid = [];\n\n    var spaceBetween = s.params.spaceBetween,\n        slidePosition = -s.params.slidesOffsetBefore,\n        i,\n        prevSlideSize = 0,\n        index = 0;\n    if (typeof s.size === 'undefined') return;\n    if (typeof spaceBetween === 'string' && spaceBetween.indexOf('%') >= 0) {\n        spaceBetween = parseFloat(spaceBetween.replace('%', '')) / 100 * s.size;\n    }\n\n    s.virtualSize = -spaceBetween;\n    // reset margins\n    if (s.rtl) s.slides.css({marginLeft: '', marginTop: ''});\n    else s.slides.css({marginRight: '', marginBottom: ''});\n\n    var slidesNumberEvenToRows;\n    if (s.params.slidesPerColumn > 1) {\n        if (Math.floor(s.slides.length / s.params.slidesPerColumn) === s.slides.length / s.params.slidesPerColumn) {\n            slidesNumberEvenToRows = s.slides.length;\n        }\n        else {\n            slidesNumberEvenToRows = Math.ceil(s.slides.length / s.params.slidesPerColumn) * s.params.slidesPerColumn;\n        }\n        if (s.params.slidesPerView !== 'auto' && s.params.slidesPerColumnFill === 'row') {\n            slidesNumberEvenToRows = Math.max(slidesNumberEvenToRows, s.params.slidesPerView * s.params.slidesPerColumn);\n        }\n    }\n\n    // Calc slides\n    var slideSize;\n    var slidesPerColumn = s.params.slidesPerColumn;\n    var slidesPerRow = slidesNumberEvenToRows / slidesPerColumn;\n    var numFullColumns = slidesPerRow - (s.params.slidesPerColumn * slidesPerRow - s.slides.length);\n    for (i = 0; i < s.slides.length; i++) {\n        slideSize = 0;\n        var slide = s.slides.eq(i);\n        if (s.params.slidesPerColumn > 1) {\n            // Set slides order\n            var newSlideOrderIndex;\n            var column, row;\n            if (s.params.slidesPerColumnFill === 'column') {\n                column = Math.floor(i / slidesPerColumn);\n                row = i - column * slidesPerColumn;\n                if (column > numFullColumns || (column === numFullColumns && row === slidesPerColumn-1)) {\n                    if (++row >= slidesPerColumn) {\n                        row = 0;\n                        column++;\n                    }\n                }\n                newSlideOrderIndex = column + row * slidesNumberEvenToRows / slidesPerColumn;\n                slide\n                    .css({\n                        '-webkit-box-ordinal-group': newSlideOrderIndex,\n                        '-moz-box-ordinal-group': newSlideOrderIndex,\n                        '-ms-flex-order': newSlideOrderIndex,\n                        '-webkit-order': newSlideOrderIndex,\n                        'order': newSlideOrderIndex\n                    });\n            }\n            else {\n                row = Math.floor(i / slidesPerRow);\n                column = i - row * slidesPerRow;\n            }\n            slide\n                .css({\n                    'margin-top': (row !== 0 && s.params.spaceBetween) && (s.params.spaceBetween + 'px')\n                })\n                .attr('data-swiper-column', column)\n                .attr('data-swiper-row', row);\n\n        }\n        if (slide.css('display') === 'none') continue;\n        if (s.params.slidesPerView === 'auto') {\n            slideSize = s.isHorizontal() ? slide.outerWidth(true) : slide.outerHeight(true);\n            if (s.params.roundLengths) slideSize = round(slideSize);\n        }\n        else {\n            slideSize = (s.size - (s.params.slidesPerView - 1) * spaceBetween) / s.params.slidesPerView;\n            if (s.params.roundLengths) slideSize = round(slideSize);\n\n            if (s.isHorizontal()) {\n                s.slides[i].style.width = slideSize + 'px';\n            }\n            else {\n                s.slides[i].style.height = slideSize + 'px';\n            }\n        }\n        s.slides[i].swiperSlideSize = slideSize;\n        s.slidesSizesGrid.push(slideSize);\n\n\n        if (s.params.centeredSlides) {\n            slidePosition = slidePosition + slideSize / 2 + prevSlideSize / 2 + spaceBetween;\n            if (i === 0) slidePosition = slidePosition - s.size / 2 - spaceBetween;\n            if (Math.abs(slidePosition) < 1 / 1000) slidePosition = 0;\n            if ((index) % s.params.slidesPerGroup === 0) s.snapGrid.push(slidePosition);\n            s.slidesGrid.push(slidePosition);\n        }\n        else {\n            if ((index) % s.params.slidesPerGroup === 0) s.snapGrid.push(slidePosition);\n            s.slidesGrid.push(slidePosition);\n            slidePosition = slidePosition + slideSize + spaceBetween;\n        }\n\n        s.virtualSize += slideSize + spaceBetween;\n\n        prevSlideSize = slideSize;\n\n        index ++;\n    }\n    s.virtualSize = Math.max(s.virtualSize, s.size) + s.params.slidesOffsetAfter;\n    var newSlidesGrid;\n\n    if (\n        s.rtl && s.wrongRTL && (s.params.effect === 'slide' || s.params.effect === 'coverflow')) {\n        s.wrapper.css({width: s.virtualSize + s.params.spaceBetween + 'px'});\n    }\n    if (!s.support.flexbox || s.params.setWrapperSize) {\n        if (s.isHorizontal()) s.wrapper.css({width: s.virtualSize + s.params.spaceBetween + 'px'});\n        else s.wrapper.css({height: s.virtualSize + s.params.spaceBetween + 'px'});\n    }\n\n    if (s.params.slidesPerColumn > 1) {\n        s.virtualSize = (slideSize + s.params.spaceBetween) * slidesNumberEvenToRows;\n        s.virtualSize = Math.ceil(s.virtualSize / s.params.slidesPerColumn) - s.params.spaceBetween;\n        s.wrapper.css({width: s.virtualSize + s.params.spaceBetween + 'px'});\n        if (s.params.centeredSlides) {\n            newSlidesGrid = [];\n            for (i = 0; i < s.snapGrid.length; i++) {\n                if (s.snapGrid[i] < s.virtualSize + s.snapGrid[0]) newSlidesGrid.push(s.snapGrid[i]);\n            }\n            s.snapGrid = newSlidesGrid;\n        }\n    }\n\n    // Remove last grid elements depending on width\n    if (!s.params.centeredSlides) {\n        newSlidesGrid = [];\n        for (i = 0; i < s.snapGrid.length; i++) {\n            if (s.snapGrid[i] <= s.virtualSize - s.size) {\n                newSlidesGrid.push(s.snapGrid[i]);\n            }\n        }\n        s.snapGrid = newSlidesGrid;\n        if (Math.floor(s.virtualSize - s.size) - Math.floor(s.snapGrid[s.snapGrid.length - 1]) > 1) {\n            s.snapGrid.push(s.virtualSize - s.size);\n        }\n    }\n    if (s.snapGrid.length === 0) s.snapGrid = [0];\n\n    if (s.params.spaceBetween !== 0) {\n        if (s.isHorizontal()) {\n            if (s.rtl) s.slides.css({marginLeft: spaceBetween + 'px'});\n            else s.slides.css({marginRight: spaceBetween + 'px'});\n        }\n        else s.slides.css({marginBottom: spaceBetween + 'px'});\n    }\n    if (s.params.watchSlidesProgress) {\n        s.updateSlidesOffset();\n    }\n};\ns.updateSlidesOffset = function () {\n    for (var i = 0; i < s.slides.length; i++) {\n        s.slides[i].swiperSlideOffset = s.isHorizontal() ? s.slides[i].offsetLeft : s.slides[i].offsetTop;\n    }\n};\n\n/*=========================\n  Slider/slides progress\n  ===========================*/\ns.updateSlidesProgress = function (translate) {\n    if (typeof translate === 'undefined') {\n        translate = s.translate || 0;\n    }\n    if (s.slides.length === 0) return;\n    if (typeof s.slides[0].swiperSlideOffset === 'undefined') s.updateSlidesOffset();\n\n    var offsetCenter = -translate;\n    if (s.rtl) offsetCenter = translate;\n\n    // Visible Slides\n    s.slides.removeClass(s.params.slideVisibleClass);\n    for (var i = 0; i < s.slides.length; i++) {\n        var slide = s.slides[i];\n        var slideProgress = (offsetCenter - slide.swiperSlideOffset) / (slide.swiperSlideSize + s.params.spaceBetween);\n        if (s.params.watchSlidesVisibility) {\n            var slideBefore = -(offsetCenter - slide.swiperSlideOffset);\n            var slideAfter = slideBefore + s.slidesSizesGrid[i];\n            var isVisible =\n                (slideBefore >= 0 && slideBefore < s.size) ||\n                (slideAfter > 0 && slideAfter <= s.size) ||\n                (slideBefore <= 0 && slideAfter >= s.size);\n            if (isVisible) {\n                s.slides.eq(i).addClass(s.params.slideVisibleClass);\n            }\n        }\n        slide.progress = s.rtl ? -slideProgress : slideProgress;\n    }\n};\ns.updateProgress = function (translate) {\n    if (typeof translate === 'undefined') {\n        translate = s.translate || 0;\n    }\n    var translatesDiff = s.maxTranslate() - s.minTranslate();\n    var wasBeginning = s.isBeginning;\n    var wasEnd = s.isEnd;\n    if (translatesDiff === 0) {\n        s.progress = 0;\n        s.isBeginning = s.isEnd = true;\n    }\n    else {\n        s.progress = (translate - s.minTranslate()) / (translatesDiff);\n        s.isBeginning = s.progress <= 0;\n        s.isEnd = s.progress >= 1;\n    }\n    if (s.isBeginning && !wasBeginning) s.emit('onReachBeginning', s);\n    if (s.isEnd && !wasEnd) s.emit('onReachEnd', s);\n\n    if (s.params.watchSlidesProgress) s.updateSlidesProgress(translate);\n    s.emit('onProgress', s, s.progress);\n};\ns.updateActiveIndex = function () {\n    var translate = s.rtl ? s.translate : -s.translate;\n    var newActiveIndex, i, snapIndex;\n    for (i = 0; i < s.slidesGrid.length; i ++) {\n        if (typeof s.slidesGrid[i + 1] !== 'undefined') {\n            if (translate >= s.slidesGrid[i] && translate < s.slidesGrid[i + 1] - (s.slidesGrid[i + 1] - s.slidesGrid[i]) / 2) {\n                newActiveIndex = i;\n            }\n            else if (translate >= s.slidesGrid[i] && translate < s.slidesGrid[i + 1]) {\n                newActiveIndex = i + 1;\n            }\n        }\n        else {\n            if (translate >= s.slidesGrid[i]) {\n                newActiveIndex = i;\n            }\n        }\n    }\n    // Normalize slideIndex\n    if (newActiveIndex < 0 || typeof newActiveIndex === 'undefined') newActiveIndex = 0;\n    // for (i = 0; i < s.slidesGrid.length; i++) {\n        // if (- translate >= s.slidesGrid[i]) {\n            // newActiveIndex = i;\n        // }\n    // }\n    snapIndex = Math.floor(newActiveIndex / s.params.slidesPerGroup);\n    if (snapIndex >= s.snapGrid.length) snapIndex = s.snapGrid.length - 1;\n\n    if (newActiveIndex === s.activeIndex) {\n        return;\n    }\n    s.snapIndex = snapIndex;\n    s.previousIndex = s.activeIndex;\n    s.activeIndex = newActiveIndex;\n    s.updateClasses();\n};\n\n/*=========================\n  Classes\n  ===========================*/\ns.updateClasses = function () {\n    s.slides.removeClass(s.params.slideActiveClass + ' ' + s.params.slideNextClass + ' ' + s.params.slidePrevClass);\n    var activeSlide = s.slides.eq(s.activeIndex);\n    // Active classes\n    activeSlide.addClass(s.params.slideActiveClass);\n    // Next Slide\n    var nextSlide = activeSlide.next('.' + s.params.slideClass).addClass(s.params.slideNextClass);\n    if (s.params.loop && nextSlide.length === 0) {\n        s.slides.eq(0).addClass(s.params.slideNextClass);\n    }\n    // Prev Slide\n    var prevSlide = activeSlide.prev('.' + s.params.slideClass).addClass(s.params.slidePrevClass);\n    if (s.params.loop && prevSlide.length === 0) {\n        s.slides.eq(-1).addClass(s.params.slidePrevClass);\n    }\n\n    // Pagination\n    if (s.paginationContainer && s.paginationContainer.length > 0) {\n        // Current/Total\n        var current,\n            total = s.params.loop ? Math.ceil((s.slides.length - s.loopedSlides * 2) / s.params.slidesPerGroup) : s.snapGrid.length;\n        if (s.params.loop) {\n            current = Math.ceil((s.activeIndex - s.loopedSlides)/s.params.slidesPerGroup);\n            if (current > s.slides.length - 1 - s.loopedSlides * 2) {\n                current = current - (s.slides.length - s.loopedSlides * 2);\n            }\n            if (current > total - 1) current = current - total;\n            if (current < 0 && s.params.paginationType !== 'bullets') current = total + current;\n        }\n        else {\n            if (typeof s.snapIndex !== 'undefined') {\n                current = s.snapIndex;\n            }\n            else {\n                current = s.activeIndex || 0;\n            }\n        }\n        // Types\n        if (s.params.paginationType === 'bullets' && s.bullets && s.bullets.length > 0) {\n            s.bullets.removeClass(s.params.bulletActiveClass);\n            if (s.paginationContainer.length > 1) {\n                s.bullets.each(function () {\n                    if ($(this).index() === current) $(this).addClass(s.params.bulletActiveClass);\n                });\n            }\n            else {\n                s.bullets.eq(current).addClass(s.params.bulletActiveClass);\n            }\n        }\n        if (s.params.paginationType === 'fraction') {\n            s.paginationContainer.find('.' + s.params.paginationCurrentClass).text(current + 1);\n            s.paginationContainer.find('.' + s.params.paginationTotalClass).text(total);\n        }\n        if (s.params.paginationType === 'progress') {\n            var scale = (current + 1) / total,\n                scaleX = scale,\n                scaleY = 1;\n            if (!s.isHorizontal()) {\n                scaleY = scale;\n                scaleX = 1;\n            }\n            s.paginationContainer.find('.' + s.params.paginationProgressbarClass).transform('translate3d(0,0,0) scaleX(' + scaleX + ') scaleY(' + scaleY + ')').transition(s.params.speed);\n        }\n        if (s.params.paginationType === 'custom' && s.params.paginationCustomRender) {\n            s.paginationContainer.html(s.params.paginationCustomRender(s, current + 1, total));\n            s.emit('onPaginationRendered', s, s.paginationContainer[0]);\n        }\n    }\n\n    // Next/active buttons\n    if (!s.params.loop) {\n        if (s.params.prevButton && s.prevButton && s.prevButton.length > 0) {\n            if (s.isBeginning) {\n                s.prevButton.addClass(s.params.buttonDisabledClass);\n                if (s.params.a11y && s.a11y) s.a11y.disable(s.prevButton);\n            }\n            else {\n                s.prevButton.removeClass(s.params.buttonDisabledClass);\n                if (s.params.a11y && s.a11y) s.a11y.enable(s.prevButton);\n            }\n        }\n        if (s.params.nextButton && s.nextButton && s.nextButton.length > 0) {\n            if (s.isEnd) {\n                s.nextButton.addClass(s.params.buttonDisabledClass);\n                if (s.params.a11y && s.a11y) s.a11y.disable(s.nextButton);\n            }\n            else {\n                s.nextButton.removeClass(s.params.buttonDisabledClass);\n                if (s.params.a11y && s.a11y) s.a11y.enable(s.nextButton);\n            }\n        }\n    }\n};\n\n/*=========================\n  Pagination\n  ===========================*/\ns.updatePagination = function () {\n    if (!s.params.pagination) return;\n    if (s.paginationContainer && s.paginationContainer.length > 0) {\n        var paginationHTML = '';\n        if (s.params.paginationType === 'bullets') {\n            var numberOfBullets = s.params.loop ? Math.ceil((s.slides.length - s.loopedSlides * 2) / s.params.slidesPerGroup) : s.snapGrid.length;\n            for (var i = 0; i < numberOfBullets; i++) {\n                if (s.params.paginationBulletRender) {\n                    paginationHTML += s.params.paginationBulletRender(i, s.params.bulletClass);\n                }\n                else {\n                    paginationHTML += '<' + s.params.paginationElement+' class=\"' + s.params.bulletClass + '\"></' + s.params.paginationElement + '>';\n                }\n            }\n            s.paginationContainer.html(paginationHTML);\n            s.bullets = s.paginationContainer.find('.' + s.params.bulletClass);\n            if (s.params.paginationClickable && s.params.a11y && s.a11y) {\n                s.a11y.initPagination();\n            }\n        }\n        if (s.params.paginationType === 'fraction') {\n            if (s.params.paginationFractionRender) {\n                paginationHTML = s.params.paginationFractionRender(s, s.params.paginationCurrentClass, s.params.paginationTotalClass);\n            }\n            else {\n                paginationHTML =\n                    '<span class=\"' + s.params.paginationCurrentClass + '\"></span>' +\n                    ' / ' +\n                    '<span class=\"' + s.params.paginationTotalClass+'\"></span>';\n            }\n            s.paginationContainer.html(paginationHTML);\n        }\n        if (s.params.paginationType === 'progress') {\n            if (s.params.paginationProgressRender) {\n                paginationHTML = s.params.paginationProgressRender(s, s.params.paginationProgressbarClass);\n            }\n            else {\n                paginationHTML = '<span class=\"' + s.params.paginationProgressbarClass + '\"></span>';\n            }\n            s.paginationContainer.html(paginationHTML);\n        }\n        if (s.params.paginationType !== 'custom') {\n            s.emit('onPaginationRendered', s, s.paginationContainer[0]);\n        }\n    }\n};\n/*=========================\n  Common update method\n  ===========================*/\ns.update = function (updateTranslate) {\n    s.updateContainerSize();\n    s.updateSlidesSize();\n    s.updateProgress();\n    s.updatePagination();\n    s.updateClasses();\n    if (s.params.scrollbar && s.scrollbar) {\n        s.scrollbar.set();\n    }\n    function forceSetTranslate() {\n        newTranslate = Math.min(Math.max(s.translate, s.maxTranslate()), s.minTranslate());\n        s.setWrapperTranslate(newTranslate);\n        s.updateActiveIndex();\n        s.updateClasses();\n    }\n    if (updateTranslate) {\n        var translated, newTranslate;\n        if (s.controller && s.controller.spline) {\n            s.controller.spline = undefined;\n        }\n        if (s.params.freeMode) {\n            forceSetTranslate();\n            if (s.params.autoHeight) {\n                s.updateAutoHeight();\n            }\n        }\n        else {\n            if ((s.params.slidesPerView === 'auto' || s.params.slidesPerView > 1) && s.isEnd && !s.params.centeredSlides) {\n                translated = s.slideTo(s.slides.length - 1, 0, false, true);\n            }\n            else {\n                translated = s.slideTo(s.activeIndex, 0, false, true);\n            }\n            if (!translated) {\n                forceSetTranslate();\n            }\n        }\n    }\n    else if (s.params.autoHeight) {\n        s.updateAutoHeight();\n    }\n};\n\n/*=========================\n  Resize Handler\n  ===========================*/\ns.onResize = function (forceUpdatePagination) {\n    //Breakpoints\n    if (s.params.breakpoints) {\n        s.setBreakpoint();\n    }\n\n    // Disable locks on resize\n    var allowSwipeToPrev = s.params.allowSwipeToPrev;\n    var allowSwipeToNext = s.params.allowSwipeToNext;\n    s.params.allowSwipeToPrev = s.params.allowSwipeToNext = true;\n\n    s.updateContainerSize();\n    s.updateSlidesSize();\n    if (s.params.slidesPerView === 'auto' || s.params.freeMode || forceUpdatePagination) s.updatePagination();\n    if (s.params.scrollbar && s.scrollbar) {\n        s.scrollbar.set();\n    }\n    if (s.controller && s.controller.spline) {\n        s.controller.spline = undefined;\n    }\n    var slideChangedBySlideTo = false;\n    if (s.params.freeMode) {\n        var newTranslate = Math.min(Math.max(s.translate, s.maxTranslate()), s.minTranslate());\n        s.setWrapperTranslate(newTranslate);\n        s.updateActiveIndex();\n        s.updateClasses();\n\n        if (s.params.autoHeight) {\n            s.updateAutoHeight();\n        }\n    }\n    else {\n        s.updateClasses();\n        if ((s.params.slidesPerView === 'auto' || s.params.slidesPerView > 1) && s.isEnd && !s.params.centeredSlides) {\n            slideChangedBySlideTo = s.slideTo(s.slides.length - 1, 0, false, true);\n        }\n        else {\n            slideChangedBySlideTo = s.slideTo(s.activeIndex, 0, false, true);\n        }\n    }\n    if (s.params.lazyLoading && !slideChangedBySlideTo && s.lazy) {\n        s.lazy.load();\n    }\n    // Return locks after resize\n    s.params.allowSwipeToPrev = allowSwipeToPrev;\n    s.params.allowSwipeToNext = allowSwipeToNext;\n};\n\n/*=========================\n  Events\n  ===========================*/\n\n//Define Touch Events\nvar desktopEvents = ['mousedown', 'mousemove', 'mouseup'];\nif (window.navigator.pointerEnabled) desktopEvents = ['pointerdown', 'pointermove', 'pointerup'];\nelse if (window.navigator.msPointerEnabled) desktopEvents = ['MSPointerDown', 'MSPointerMove', 'MSPointerUp'];\ns.touchEvents = {\n    start : s.support.touch || !s.params.simulateTouch  ? 'touchstart' : desktopEvents[0],\n    move : s.support.touch || !s.params.simulateTouch ? 'touchmove' : desktopEvents[1],\n    end : s.support.touch || !s.params.simulateTouch ? 'touchend' : desktopEvents[2]\n};\n\n\n// WP8 Touch Events Fix\nif (window.navigator.pointerEnabled || window.navigator.msPointerEnabled) {\n    (s.params.touchEventsTarget === 'container' ? s.container : s.wrapper).addClass('swiper-wp8-' + s.params.direction);\n}\n\n// Attach/detach events\ns.initEvents = function (detach) {\n    var actionDom = detach ? 'off' : 'on';\n    var action = detach ? 'removeEventListener' : 'addEventListener';\n    var touchEventsTarget = s.params.touchEventsTarget === 'container' ? s.container[0] : s.wrapper[0];\n    var target = s.support.touch ? touchEventsTarget : document;\n\n    var moveCapture = s.params.nested ? true : false;\n\n    //Touch Events\n    if (s.browser.ie) {\n        touchEventsTarget[action](s.touchEvents.start, s.onTouchStart, false);\n        target[action](s.touchEvents.move, s.onTouchMove, moveCapture);\n        target[action](s.touchEvents.end, s.onTouchEnd, false);\n    }\n    else {\n        if (s.support.touch) {\n            touchEventsTarget[action](s.touchEvents.start, s.onTouchStart, false);\n            touchEventsTarget[action](s.touchEvents.move, s.onTouchMove, moveCapture);\n            touchEventsTarget[action](s.touchEvents.end, s.onTouchEnd, false);\n        }\n        if (params.simulateTouch && !s.device.ios && !s.device.android) {\n            touchEventsTarget[action]('mousedown', s.onTouchStart, false);\n            document[action]('mousemove', s.onTouchMove, moveCapture);\n            document[action]('mouseup', s.onTouchEnd, false);\n        }\n    }\n    window[action]('resize', s.onResize);\n\n    // Next, Prev, Index\n    if (s.params.nextButton && s.nextButton && s.nextButton.length > 0) {\n        s.nextButton[actionDom]('click', s.onClickNext);\n        if (s.params.a11y && s.a11y) s.nextButton[actionDom]('keydown', s.a11y.onEnterKey);\n    }\n    if (s.params.prevButton && s.prevButton && s.prevButton.length > 0) {\n        s.prevButton[actionDom]('click', s.onClickPrev);\n        if (s.params.a11y && s.a11y) s.prevButton[actionDom]('keydown', s.a11y.onEnterKey);\n    }\n    if (s.params.pagination && s.params.paginationClickable) {\n        s.paginationContainer[actionDom]('click', '.' + s.params.bulletClass, s.onClickIndex);\n        if (s.params.a11y && s.a11y) s.paginationContainer[actionDom]('keydown', '.' + s.params.bulletClass, s.a11y.onEnterKey);\n    }\n\n    // Prevent Links Clicks\n    if (s.params.preventClicks || s.params.preventClicksPropagation) touchEventsTarget[action]('click', s.preventClicks, true);\n};\ns.attachEvents = function () {\n    s.initEvents();\n};\ns.detachEvents = function () {\n    s.initEvents(true);\n};\n\n/*=========================\n  Handle Clicks\n  ===========================*/\n// Prevent Clicks\ns.allowClick = true;\ns.preventClicks = function (e) {\n    if (!s.allowClick) {\n        if (s.params.preventClicks) e.preventDefault();\n        if (s.params.preventClicksPropagation && s.animating) {\n            e.stopPropagation();\n            e.stopImmediatePropagation();\n        }\n    }\n};\n// Clicks\ns.onClickNext = function (e) {\n    e.preventDefault();\n    if (s.isEnd && !s.params.loop) return;\n    s.slideNext();\n};\ns.onClickPrev = function (e) {\n    e.preventDefault();\n    if (s.isBeginning && !s.params.loop) return;\n    s.slidePrev();\n};\ns.onClickIndex = function (e) {\n    e.preventDefault();\n    var index = $(this).index() * s.params.slidesPerGroup;\n    if (s.params.loop) index = index + s.loopedSlides;\n    s.slideTo(index);\n};\n\n/*=========================\n  Handle Touches\n  ===========================*/\nfunction findElementInEvent(e, selector) {\n    var el = $(e.target);\n    if (!el.is(selector)) {\n        if (typeof selector === 'string') {\n            el = el.parents(selector);\n        }\n        else if (selector.nodeType) {\n            var found;\n            el.parents().each(function (index, _el) {\n                if (_el === selector) found = selector;\n            });\n            if (!found) return undefined;\n            else return selector;\n        }\n    }\n    if (el.length === 0) {\n        return undefined;\n    }\n    return el[0];\n}\ns.updateClickedSlide = function (e) {\n    var slide = findElementInEvent(e, '.' + s.params.slideClass);\n    var slideFound = false;\n    if (slide) {\n        for (var i = 0; i < s.slides.length; i++) {\n            if (s.slides[i] === slide) slideFound = true;\n        }\n    }\n\n    if (slide && slideFound) {\n        s.clickedSlide = slide;\n        s.clickedIndex = $(slide).index();\n    }\n    else {\n        s.clickedSlide = undefined;\n        s.clickedIndex = undefined;\n        return;\n    }\n    if (s.params.slideToClickedSlide && s.clickedIndex !== undefined && s.clickedIndex !== s.activeIndex) {\n        var slideToIndex = s.clickedIndex,\n            realIndex,\n            duplicatedSlides;\n        if (s.params.loop) {\n            if (s.animating) return;\n            realIndex = $(s.clickedSlide).attr('data-swiper-slide-index');\n            if (s.params.centeredSlides) {\n                if ((slideToIndex < s.loopedSlides - s.params.slidesPerView/2) || (slideToIndex > s.slides.length - s.loopedSlides + s.params.slidesPerView/2)) {\n                    s.fixLoop();\n                    slideToIndex = s.wrapper.children('.' + s.params.slideClass + '[data-swiper-slide-index=\"' + realIndex + '\"]:not(.swiper-slide-duplicate)').eq(0).index();\n                    setTimeout(function () {\n                        s.slideTo(slideToIndex);\n                    }, 0);\n                }\n                else {\n                    s.slideTo(slideToIndex);\n                }\n            }\n            else {\n                if (slideToIndex > s.slides.length - s.params.slidesPerView) {\n                    s.fixLoop();\n                    slideToIndex = s.wrapper.children('.' + s.params.slideClass + '[data-swiper-slide-index=\"' + realIndex + '\"]:not(.swiper-slide-duplicate)').eq(0).index();\n                    setTimeout(function () {\n                        s.slideTo(slideToIndex);\n                    }, 0);\n                }\n                else {\n                    s.slideTo(slideToIndex);\n                }\n            }\n        }\n        else {\n            s.slideTo(slideToIndex);\n        }\n    }\n};\n\nvar isTouched,\n    isMoved,\n    allowTouchCallbacks,\n    touchStartTime,\n    isScrolling,\n    currentTranslate,\n    startTranslate,\n    allowThresholdMove,\n    // Form elements to match\n    formElements = 'input, select, textarea, button',\n    // Last click time\n    lastClickTime = Date.now(), clickTimeout,\n    //Velocities\n    velocities = [],\n    allowMomentumBounce;\n\n// Animating Flag\ns.animating = false;\n\n// Touches information\ns.touches = {\n    startX: 0,\n    startY: 0,\n    currentX: 0,\n    currentY: 0,\n    diff: 0\n};\n\n// Touch handlers\nvar isTouchEvent, startMoving;\ns.onTouchStart = function (e) {\n    if (e.originalEvent) e = e.originalEvent;\n    isTouchEvent = e.type === 'touchstart';\n    if (!isTouchEvent && 'which' in e && e.which === 3) return;\n    if (s.params.noSwiping && findElementInEvent(e, '.' + s.params.noSwipingClass)) {\n        s.allowClick = true;\n        return;\n    }\n    if (s.params.swipeHandler) {\n        if (!findElementInEvent(e, s.params.swipeHandler)) return;\n    }\n\n    var startX = s.touches.currentX = e.type === 'touchstart' ? e.targetTouches[0].pageX : e.pageX;\n    var startY = s.touches.currentY = e.type === 'touchstart' ? e.targetTouches[0].pageY : e.pageY;\n\n    // Do NOT start if iOS edge swipe is detected. Otherwise iOS app (UIWebView) cannot swipe-to-go-back anymore\n    if(s.device.ios && s.params.iOSEdgeSwipeDetection && startX <= s.params.iOSEdgeSwipeThreshold) {\n        return;\n    }\n\n    isTouched = true;\n    isMoved = false;\n    allowTouchCallbacks = true;\n    isScrolling = undefined;\n    startMoving = undefined;\n    s.touches.startX = startX;\n    s.touches.startY = startY;\n    touchStartTime = Date.now();\n    s.allowClick = true;\n    s.updateContainerSize();\n    s.swipeDirection = undefined;\n    if (s.params.threshold > 0) allowThresholdMove = false;\n    if (e.type !== 'touchstart') {\n        var preventDefault = true;\n        if ($(e.target).is(formElements)) preventDefault = false;\n        if (document.activeElement && $(document.activeElement).is(formElements)) {\n            document.activeElement.blur();\n        }\n        if (preventDefault) {\n            e.preventDefault();\n        }\n    }\n    s.emit('onTouchStart', s, e);\n};\n\ns.onTouchMove = function (e) {\n    if (e.originalEvent) e = e.originalEvent;\n    if (isTouchEvent && e.type === 'mousemove') return;\n    if (e.preventedByNestedSwiper) {\n        s.touches.startX = e.type === 'touchmove' ? e.targetTouches[0].pageX : e.pageX;\n        s.touches.startY = e.type === 'touchmove' ? e.targetTouches[0].pageY : e.pageY;\n        return;\n    }\n    if (s.params.onlyExternal) {\n        // isMoved = true;\n        s.allowClick = false;\n        if (isTouched) {\n            s.touches.startX = s.touches.currentX = e.type === 'touchmove' ? e.targetTouches[0].pageX : e.pageX;\n            s.touches.startY = s.touches.currentY = e.type === 'touchmove' ? e.targetTouches[0].pageY : e.pageY;\n            touchStartTime = Date.now();\n        }\n        return;\n    }\n    if (isTouchEvent && document.activeElement) {\n        if (e.target === document.activeElement && $(e.target).is(formElements)) {\n            isMoved = true;\n            s.allowClick = false;\n            return;\n        }\n    }\n    if (allowTouchCallbacks) {\n        s.emit('onTouchMove', s, e);\n    }\n    if (e.targetTouches && e.targetTouches.length > 1) return;\n\n    s.touches.currentX = e.type === 'touchmove' ? e.targetTouches[0].pageX : e.pageX;\n    s.touches.currentY = e.type === 'touchmove' ? e.targetTouches[0].pageY : e.pageY;\n\n    if (typeof isScrolling === 'undefined') {\n        var touchAngle = Math.atan2(Math.abs(s.touches.currentY - s.touches.startY), Math.abs(s.touches.currentX - s.touches.startX)) * 180 / Math.PI;\n        isScrolling = s.isHorizontal() ? touchAngle > s.params.touchAngle : (90 - touchAngle > s.params.touchAngle);\n    }\n    if (isScrolling) {\n        s.emit('onTouchMoveOpposite', s, e);\n    }\n    if (typeof startMoving === 'undefined' && s.browser.ieTouch) {\n        if (s.touches.currentX !== s.touches.startX || s.touches.currentY !== s.touches.startY) {\n            startMoving = true;\n        }\n    }\n    if (!isTouched) return;\n    if (isScrolling)  {\n        isTouched = false;\n        return;\n    }\n    if (!startMoving && s.browser.ieTouch) {\n        return;\n    }\n    s.allowClick = false;\n    s.emit('onSliderMove', s, e);\n    e.preventDefault();\n    if (s.params.touchMoveStopPropagation && !s.params.nested) {\n        e.stopPropagation();\n    }\n\n    if (!isMoved) {\n        if (params.loop) {\n            s.fixLoop();\n        }\n        startTranslate = s.getWrapperTranslate();\n        s.setWrapperTransition(0);\n        if (s.animating) {\n            s.wrapper.trigger('webkitTransitionEnd transitionend oTransitionEnd MSTransitionEnd msTransitionEnd');\n        }\n        if (s.params.autoplay && s.autoplaying) {\n            if (s.params.autoplayDisableOnInteraction) {\n                s.stopAutoplay();\n            }\n            else {\n                s.pauseAutoplay();\n            }\n        }\n        allowMomentumBounce = false;\n        //Grab Cursor\n        if (s.params.grabCursor) {\n            s.container[0].style.cursor = 'move';\n            s.container[0].style.cursor = '-webkit-grabbing';\n            s.container[0].style.cursor = '-moz-grabbin';\n            s.container[0].style.cursor = 'grabbing';\n        }\n    }\n    isMoved = true;\n\n    var diff = s.touches.diff = s.isHorizontal() ? s.touches.currentX - s.touches.startX : s.touches.currentY - s.touches.startY;\n\n    diff = diff * s.params.touchRatio;\n    if (s.rtl) diff = -diff;\n\n    s.swipeDirection = diff > 0 ? 'prev' : 'next';\n    currentTranslate = diff + startTranslate;\n\n    var disableParentSwiper = true;\n    if ((diff > 0 && currentTranslate > s.minTranslate())) {\n        disableParentSwiper = false;\n        if (s.params.resistance) currentTranslate = s.minTranslate() - 1 + Math.pow(-s.minTranslate() + startTranslate + diff, s.params.resistanceRatio);\n    }\n    else if (diff < 0 && currentTranslate < s.maxTranslate()) {\n        disableParentSwiper = false;\n        if (s.params.resistance) currentTranslate = s.maxTranslate() + 1 - Math.pow(s.maxTranslate() - startTranslate - diff, s.params.resistanceRatio);\n    }\n\n    if (disableParentSwiper) {\n        e.preventedByNestedSwiper = true;\n    }\n\n    // Directions locks\n    if (!s.params.allowSwipeToNext && s.swipeDirection === 'next' && currentTranslate < startTranslate) {\n        currentTranslate = startTranslate;\n    }\n    if (!s.params.allowSwipeToPrev && s.swipeDirection === 'prev' && currentTranslate > startTranslate) {\n        currentTranslate = startTranslate;\n    }\n\n    if (!s.params.followFinger) return;\n\n    // Threshold\n    if (s.params.threshold > 0) {\n        if (Math.abs(diff) > s.params.threshold || allowThresholdMove) {\n            if (!allowThresholdMove) {\n                allowThresholdMove = true;\n                s.touches.startX = s.touches.currentX;\n                s.touches.startY = s.touches.currentY;\n                currentTranslate = startTranslate;\n                s.touches.diff = s.isHorizontal() ? s.touches.currentX - s.touches.startX : s.touches.currentY - s.touches.startY;\n                return;\n            }\n        }\n        else {\n            currentTranslate = startTranslate;\n            return;\n        }\n    }\n    // Update active index in free mode\n    if (s.params.freeMode || s.params.watchSlidesProgress) {\n        s.updateActiveIndex();\n    }\n    if (s.params.freeMode) {\n        //Velocity\n        if (velocities.length === 0) {\n            velocities.push({\n                position: s.touches[s.isHorizontal() ? 'startX' : 'startY'],\n                time: touchStartTime\n            });\n        }\n        velocities.push({\n            position: s.touches[s.isHorizontal() ? 'currentX' : 'currentY'],\n            time: (new window.Date()).getTime()\n        });\n    }\n    // Update progress\n    s.updateProgress(currentTranslate);\n    // Update translate\n    s.setWrapperTranslate(currentTranslate);\n};\ns.onTouchEnd = function (e) {\n    if (e.originalEvent) e = e.originalEvent;\n    if (allowTouchCallbacks) {\n        s.emit('onTouchEnd', s, e);\n    }\n    allowTouchCallbacks = false;\n    if (!isTouched) return;\n    //Return Grab Cursor\n    if (s.params.grabCursor && isMoved && isTouched) {\n        s.container[0].style.cursor = 'move';\n        s.container[0].style.cursor = '-webkit-grab';\n        s.container[0].style.cursor = '-moz-grab';\n        s.container[0].style.cursor = 'grab';\n    }\n\n    // Time diff\n    var touchEndTime = Date.now();\n    var timeDiff = touchEndTime - touchStartTime;\n\n    // Tap, doubleTap, Click\n    if (s.allowClick) {\n        s.updateClickedSlide(e);\n        s.emit('onTap', s, e);\n        if (timeDiff < 300 && (touchEndTime - lastClickTime) > 300) {\n            if (clickTimeout) clearTimeout(clickTimeout);\n            clickTimeout = setTimeout(function () {\n                if (!s) return;\n                if (s.params.paginationHide && s.paginationContainer.length > 0 && !$(e.target).hasClass(s.params.bulletClass)) {\n                    s.paginationContainer.toggleClass(s.params.paginationHiddenClass);\n                }\n                s.emit('onClick', s, e);\n            }, 300);\n\n        }\n        if (timeDiff < 300 && (touchEndTime - lastClickTime) < 300) {\n            if (clickTimeout) clearTimeout(clickTimeout);\n            s.emit('onDoubleTap', s, e);\n        }\n    }\n\n    lastClickTime = Date.now();\n    setTimeout(function () {\n        if (s) s.allowClick = true;\n    }, 0);\n\n    if (!isTouched || !isMoved || !s.swipeDirection || s.touches.diff === 0 || currentTranslate === startTranslate) {\n        isTouched = isMoved = false;\n        return;\n    }\n    isTouched = isMoved = false;\n\n    var currentPos;\n    if (s.params.followFinger) {\n        currentPos = s.rtl ? s.translate : -s.translate;\n    }\n    else {\n        currentPos = -currentTranslate;\n    }\n    if (s.params.freeMode) {\n        if (currentPos < -s.minTranslate()) {\n            s.slideTo(s.activeIndex);\n            return;\n        }\n        else if (currentPos > -s.maxTranslate()) {\n            if (s.slides.length < s.snapGrid.length) {\n                s.slideTo(s.snapGrid.length - 1);\n            }\n            else {\n                s.slideTo(s.slides.length - 1);\n            }\n            return;\n        }\n\n        if (s.params.freeModeMomentum) {\n            if (velocities.length > 1) {\n                var lastMoveEvent = velocities.pop(), velocityEvent = velocities.pop();\n\n                var distance = lastMoveEvent.position - velocityEvent.position;\n                var time = lastMoveEvent.time - velocityEvent.time;\n                s.velocity = distance / time;\n                s.velocity = s.velocity / 2;\n                if (Math.abs(s.velocity) < s.params.freeModeMinimumVelocity) {\n                    s.velocity = 0;\n                }\n                // this implies that the user stopped moving a finger then released.\n                // There would be no events with distance zero, so the last event is stale.\n                if (time > 150 || (new window.Date().getTime() - lastMoveEvent.time) > 300) {\n                    s.velocity = 0;\n                }\n            } else {\n                s.velocity = 0;\n            }\n\n            velocities.length = 0;\n            var momentumDuration = 1000 * s.params.freeModeMomentumRatio;\n            var momentumDistance = s.velocity * momentumDuration;\n\n            var newPosition = s.translate + momentumDistance;\n            if (s.rtl) newPosition = - newPosition;\n            var doBounce = false;\n            var afterBouncePosition;\n            var bounceAmount = Math.abs(s.velocity) * 20 * s.params.freeModeMomentumBounceRatio;\n            if (newPosition < s.maxTranslate()) {\n                if (s.params.freeModeMomentumBounce) {\n                    if (newPosition + s.maxTranslate() < -bounceAmount) {\n                        newPosition = s.maxTranslate() - bounceAmount;\n                    }\n                    afterBouncePosition = s.maxTranslate();\n                    doBounce = true;\n                    allowMomentumBounce = true;\n                }\n                else {\n                    newPosition = s.maxTranslate();\n                }\n            }\n            else if (newPosition > s.minTranslate()) {\n                if (s.params.freeModeMomentumBounce) {\n                    if (newPosition - s.minTranslate() > bounceAmount) {\n                        newPosition = s.minTranslate() + bounceAmount;\n                    }\n                    afterBouncePosition = s.minTranslate();\n                    doBounce = true;\n                    allowMomentumBounce = true;\n                }\n                else {\n                    newPosition = s.minTranslate();\n                }\n            }\n            else if (s.params.freeModeSticky) {\n                var j = 0,\n                    nextSlide;\n                for (j = 0; j < s.snapGrid.length; j += 1) {\n                    if (s.snapGrid[j] > -newPosition) {\n                        nextSlide = j;\n                        break;\n                    }\n\n                }\n                if (Math.abs(s.snapGrid[nextSlide] - newPosition) < Math.abs(s.snapGrid[nextSlide - 1] - newPosition) || s.swipeDirection === 'next') {\n                    newPosition = s.snapGrid[nextSlide];\n                } else {\n                    newPosition = s.snapGrid[nextSlide - 1];\n                }\n                if (!s.rtl) newPosition = - newPosition;\n            }\n            //Fix duration\n            if (s.velocity !== 0) {\n                if (s.rtl) {\n                    momentumDuration = Math.abs((-newPosition - s.translate) / s.velocity);\n                }\n                else {\n                    momentumDuration = Math.abs((newPosition - s.translate) / s.velocity);\n                }\n            }\n            else if (s.params.freeModeSticky) {\n                s.slideReset();\n                return;\n            }\n\n            if (s.params.freeModeMomentumBounce && doBounce) {\n                s.updateProgress(afterBouncePosition);\n                s.setWrapperTransition(momentumDuration);\n                s.setWrapperTranslate(newPosition);\n                s.onTransitionStart();\n                s.animating = true;\n                s.wrapper.transitionEnd(function () {\n                    if (!s || !allowMomentumBounce) return;\n                    s.emit('onMomentumBounce', s);\n\n                    s.setWrapperTransition(s.params.speed);\n                    s.setWrapperTranslate(afterBouncePosition);\n                    s.wrapper.transitionEnd(function () {\n                        if (!s) return;\n                        s.onTransitionEnd();\n                    });\n                });\n            } else if (s.velocity) {\n                s.updateProgress(newPosition);\n                s.setWrapperTransition(momentumDuration);\n                s.setWrapperTranslate(newPosition);\n                s.onTransitionStart();\n                if (!s.animating) {\n                    s.animating = true;\n                    s.wrapper.transitionEnd(function () {\n                        if (!s) return;\n                        s.onTransitionEnd();\n                    });\n                }\n\n            } else {\n                s.updateProgress(newPosition);\n            }\n\n            s.updateActiveIndex();\n        }\n        if (!s.params.freeModeMomentum || timeDiff >= s.params.longSwipesMs) {\n            s.updateProgress();\n            s.updateActiveIndex();\n        }\n        return;\n    }\n\n    // Find current slide\n    var i, stopIndex = 0, groupSize = s.slidesSizesGrid[0];\n    for (i = 0; i < s.slidesGrid.length; i += s.params.slidesPerGroup) {\n        if (typeof s.slidesGrid[i + s.params.slidesPerGroup] !== 'undefined') {\n            if (currentPos >= s.slidesGrid[i] && currentPos < s.slidesGrid[i + s.params.slidesPerGroup]) {\n                stopIndex = i;\n                groupSize = s.slidesGrid[i + s.params.slidesPerGroup] - s.slidesGrid[i];\n            }\n        }\n        else {\n            if (currentPos >= s.slidesGrid[i]) {\n                stopIndex = i;\n                groupSize = s.slidesGrid[s.slidesGrid.length - 1] - s.slidesGrid[s.slidesGrid.length - 2];\n            }\n        }\n    }\n\n    // Find current slide size\n    var ratio = (currentPos - s.slidesGrid[stopIndex]) / groupSize;\n\n    if (timeDiff > s.params.longSwipesMs) {\n        // Long touches\n        if (!s.params.longSwipes) {\n            s.slideTo(s.activeIndex);\n            return;\n        }\n        if (s.swipeDirection === 'next') {\n            if (ratio >= s.params.longSwipesRatio) s.slideTo(stopIndex + s.params.slidesPerGroup);\n            else s.slideTo(stopIndex);\n\n        }\n        if (s.swipeDirection === 'prev') {\n            if (ratio > (1 - s.params.longSwipesRatio)) s.slideTo(stopIndex + s.params.slidesPerGroup);\n            else s.slideTo(stopIndex);\n        }\n    }\n    else {\n        // Short swipes\n        if (!s.params.shortSwipes) {\n            s.slideTo(s.activeIndex);\n            return;\n        }\n        if (s.swipeDirection === 'next') {\n            s.slideTo(stopIndex + s.params.slidesPerGroup);\n\n        }\n        if (s.swipeDirection === 'prev') {\n            s.slideTo(stopIndex);\n        }\n    }\n};\n/*=========================\n  Transitions\n  ===========================*/\ns._slideTo = function (slideIndex, speed) {\n    return s.slideTo(slideIndex, speed, true, true);\n};\ns.slideTo = function (slideIndex, speed, runCallbacks, internal) {\n    if (typeof runCallbacks === 'undefined') runCallbacks = true;\n    if (typeof slideIndex === 'undefined') slideIndex = 0;\n    if (slideIndex < 0) slideIndex = 0;\n    s.snapIndex = Math.floor(slideIndex / s.params.slidesPerGroup);\n    if (s.snapIndex >= s.snapGrid.length) s.snapIndex = s.snapGrid.length - 1;\n\n    var translate = - s.snapGrid[s.snapIndex];\n    // Stop autoplay\n    if (s.params.autoplay && s.autoplaying) {\n        if (internal || !s.params.autoplayDisableOnInteraction) {\n            s.pauseAutoplay(speed);\n        }\n        else {\n            s.stopAutoplay();\n        }\n    }\n    // Update progress\n    s.updateProgress(translate);\n\n    // Normalize slideIndex\n    for (var i = 0; i < s.slidesGrid.length; i++) {\n        if (- Math.floor(translate * 100) >= Math.floor(s.slidesGrid[i] * 100)) {\n            slideIndex = i;\n        }\n    }\n\n    // Directions locks\n    if (!s.params.allowSwipeToNext && translate < s.translate && translate < s.minTranslate()) {\n        return false;\n    }\n    if (!s.params.allowSwipeToPrev && translate > s.translate && translate > s.maxTranslate()) {\n        if ((s.activeIndex || 0) !== slideIndex ) return false;\n    }\n\n    // Update Index\n    if (typeof speed === 'undefined') speed = s.params.speed;\n    s.previousIndex = s.activeIndex || 0;\n    s.activeIndex = slideIndex;\n\n    if ((s.rtl && -translate === s.translate) || (!s.rtl && translate === s.translate)) {\n        // Update Height\n        if (s.params.autoHeight) {\n            s.updateAutoHeight();\n        }\n        s.updateClasses();\n        if (s.params.effect !== 'slide') {\n            s.setWrapperTranslate(translate);\n        }\n        return false;\n    }\n    s.updateClasses();\n    s.onTransitionStart(runCallbacks);\n\n    if (speed === 0) {\n        s.setWrapperTranslate(translate);\n        s.setWrapperTransition(0);\n        s.onTransitionEnd(runCallbacks);\n    }\n    else {\n        s.setWrapperTranslate(translate);\n        s.setWrapperTransition(speed);\n        if (!s.animating) {\n            s.animating = true;\n            s.wrapper.transitionEnd(function () {\n                if (!s) return;\n                s.onTransitionEnd(runCallbacks);\n            });\n        }\n\n    }\n\n    return true;\n};\n\ns.onTransitionStart = function (runCallbacks) {\n    if (typeof runCallbacks === 'undefined') runCallbacks = true;\n    if (s.params.autoHeight) {\n        s.updateAutoHeight();\n    }\n    if (s.lazy) s.lazy.onTransitionStart();\n    if (runCallbacks) {\n        s.emit('onTransitionStart', s);\n        if (s.activeIndex !== s.previousIndex) {\n            s.emit('onSlideChangeStart', s);\n            if (s.activeIndex > s.previousIndex) {\n                s.emit('onSlideNextStart', s);\n            }\n            else {\n                s.emit('onSlidePrevStart', s);\n            }\n        }\n\n    }\n};\ns.onTransitionEnd = function (runCallbacks) {\n    s.animating = false;\n    s.setWrapperTransition(0);\n    if (typeof runCallbacks === 'undefined') runCallbacks = true;\n    if (s.lazy) s.lazy.onTransitionEnd();\n    if (runCallbacks) {\n        s.emit('onTransitionEnd', s);\n        if (s.activeIndex !== s.previousIndex) {\n            s.emit('onSlideChangeEnd', s);\n            if (s.activeIndex > s.previousIndex) {\n                s.emit('onSlideNextEnd', s);\n            }\n            else {\n                s.emit('onSlidePrevEnd', s);\n            }\n        }\n    }\n    if (s.params.hashnav && s.hashnav) {\n        s.hashnav.setHash();\n    }\n\n};\ns.slideNext = function (runCallbacks, speed, internal) {\n    if (s.params.loop) {\n        if (s.animating) return false;\n        s.fixLoop();\n        var clientLeft = s.container[0].clientLeft;\n        return s.slideTo(s.activeIndex + s.params.slidesPerGroup, speed, runCallbacks, internal);\n    }\n    else return s.slideTo(s.activeIndex + s.params.slidesPerGroup, speed, runCallbacks, internal);\n};\ns._slideNext = function (speed) {\n    return s.slideNext(true, speed, true);\n};\ns.slidePrev = function (runCallbacks, speed, internal) {\n    if (s.params.loop) {\n        if (s.animating) return false;\n        s.fixLoop();\n        var clientLeft = s.container[0].clientLeft;\n        return s.slideTo(s.activeIndex - 1, speed, runCallbacks, internal);\n    }\n    else return s.slideTo(s.activeIndex - 1, speed, runCallbacks, internal);\n};\ns._slidePrev = function (speed) {\n    return s.slidePrev(true, speed, true);\n};\ns.slideReset = function (runCallbacks, speed, internal) {\n    return s.slideTo(s.activeIndex, speed, runCallbacks);\n};\n\n/*=========================\n  Translate/transition helpers\n  ===========================*/\ns.setWrapperTransition = function (duration, byController) {\n    s.wrapper.transition(duration);\n    if (s.params.effect !== 'slide' && s.effects[s.params.effect]) {\n        s.effects[s.params.effect].setTransition(duration);\n    }\n    if (s.params.parallax && s.parallax) {\n        s.parallax.setTransition(duration);\n    }\n    if (s.params.scrollbar && s.scrollbar) {\n        s.scrollbar.setTransition(duration);\n    }\n    if (s.params.control && s.controller) {\n        s.controller.setTransition(duration, byController);\n    }\n    s.emit('onSetTransition', s, duration);\n};\ns.setWrapperTranslate = function (translate, updateActiveIndex, byController) {\n    var x = 0, y = 0, z = 0;\n    if (s.isHorizontal()) {\n        x = s.rtl ? -translate : translate;\n    }\n    else {\n        y = translate;\n    }\n\n    if (s.params.roundLengths) {\n        x = round(x);\n        y = round(y);\n    }\n\n    if (!s.params.virtualTranslate) {\n        if (s.support.transforms3d) s.wrapper.transform('translate3d(' + x + 'px, ' + y + 'px, ' + z + 'px)');\n        else s.wrapper.transform('translate(' + x + 'px, ' + y + 'px)');\n    }\n\n    s.translate = s.isHorizontal() ? x : y;\n\n    // Check if we need to update progress\n    var progress;\n    var translatesDiff = s.maxTranslate() - s.minTranslate();\n    if (translatesDiff === 0) {\n        progress = 0;\n    }\n    else {\n        progress = (translate - s.minTranslate()) / (translatesDiff);\n    }\n    if (progress !== s.progress) {\n        s.updateProgress(translate);\n    }\n\n    if (updateActiveIndex) s.updateActiveIndex();\n    if (s.params.effect !== 'slide' && s.effects[s.params.effect]) {\n        s.effects[s.params.effect].setTranslate(s.translate);\n    }\n    if (s.params.parallax && s.parallax) {\n        s.parallax.setTranslate(s.translate);\n    }\n    if (s.params.scrollbar && s.scrollbar) {\n        s.scrollbar.setTranslate(s.translate);\n    }\n    if (s.params.control && s.controller) {\n        s.controller.setTranslate(s.translate, byController);\n    }\n    s.emit('onSetTranslate', s, s.translate);\n};\n\ns.getTranslate = function (el, axis) {\n    var matrix, curTransform, curStyle, transformMatrix;\n\n    // automatic axis detection\n    if (typeof axis === 'undefined') {\n        axis = 'x';\n    }\n\n    if (s.params.virtualTranslate) {\n        return s.rtl ? -s.translate : s.translate;\n    }\n\n    curStyle = window.getComputedStyle(el, null);\n    if (window.WebKitCSSMatrix) {\n        curTransform = curStyle.transform || curStyle.webkitTransform;\n        if (curTransform.split(',').length > 6) {\n            curTransform = curTransform.split(', ').map(function(a){\n                return a.replace(',','.');\n            }).join(', ');\n        }\n        // Some old versions of Webkit choke when 'none' is passed; pass\n        // empty string instead in this case\n        transformMatrix = new window.WebKitCSSMatrix(curTransform === 'none' ? '' : curTransform);\n    }\n    else {\n        transformMatrix = curStyle.MozTransform || curStyle.OTransform || curStyle.MsTransform || curStyle.msTransform  || curStyle.transform || curStyle.getPropertyValue('transform').replace('translate(', 'matrix(1, 0, 0, 1,');\n        matrix = transformMatrix.toString().split(',');\n    }\n\n    if (axis === 'x') {\n        //Latest Chrome and webkits Fix\n        if (window.WebKitCSSMatrix)\n            curTransform = transformMatrix.m41;\n        //Crazy IE10 Matrix\n        else if (matrix.length === 16)\n            curTransform = parseFloat(matrix[12]);\n        //Normal Browsers\n        else\n            curTransform = parseFloat(matrix[4]);\n    }\n    if (axis === 'y') {\n        //Latest Chrome and webkits Fix\n        if (window.WebKitCSSMatrix)\n            curTransform = transformMatrix.m42;\n        //Crazy IE10 Matrix\n        else if (matrix.length === 16)\n            curTransform = parseFloat(matrix[13]);\n        //Normal Browsers\n        else\n            curTransform = parseFloat(matrix[5]);\n    }\n    if (s.rtl && curTransform) curTransform = -curTransform;\n    return curTransform || 0;\n};\ns.getWrapperTranslate = function (axis) {\n    if (typeof axis === 'undefined') {\n        axis = s.isHorizontal() ? 'x' : 'y';\n    }\n    return s.getTranslate(s.wrapper[0], axis);\n};\n\n/*=========================\n  Observer\n  ===========================*/\ns.observers = [];\nfunction initObserver(target, options) {\n    options = options || {};\n    // create an observer instance\n    var ObserverFunc = window.MutationObserver || window.WebkitMutationObserver;\n    var observer = new ObserverFunc(function (mutations) {\n        mutations.forEach(function (mutation) {\n            s.onResize(true);\n            s.emit('onObserverUpdate', s, mutation);\n        });\n    });\n\n    observer.observe(target, {\n        attributes: typeof options.attributes === 'undefined' ? true : options.attributes,\n        childList: typeof options.childList === 'undefined' ? true : options.childList,\n        characterData: typeof options.characterData === 'undefined' ? true : options.characterData\n    });\n\n    s.observers.push(observer);\n}\ns.initObservers = function () {\n    if (s.params.observeParents) {\n        var containerParents = s.container.parents();\n        for (var i = 0; i < containerParents.length; i++) {\n            initObserver(containerParents[i]);\n        }\n    }\n\n    // Observe container\n    initObserver(s.container[0], {childList: false});\n\n    // Observe wrapper\n    initObserver(s.wrapper[0], {attributes: false});\n};\ns.disconnectObservers = function () {\n    for (var i = 0; i < s.observers.length; i++) {\n        s.observers[i].disconnect();\n    }\n    s.observers = [];\n};\n/*=========================\n  Loop\n  ===========================*/\n// Create looped slides\ns.createLoop = function () {\n    // Remove duplicated slides\n    s.wrapper.children('.' + s.params.slideClass + '.' + s.params.slideDuplicateClass).remove();\n\n    var slides = s.wrapper.children('.' + s.params.slideClass);\n\n    if(s.params.slidesPerView === 'auto' && !s.params.loopedSlides) s.params.loopedSlides = slides.length;\n\n    s.loopedSlides = parseInt(s.params.loopedSlides || s.params.slidesPerView, 10);\n    s.loopedSlides = s.loopedSlides + s.params.loopAdditionalSlides;\n    if (s.loopedSlides > slides.length) {\n        s.loopedSlides = slides.length;\n    }\n\n    var prependSlides = [], appendSlides = [], i;\n    slides.each(function (index, el) {\n        var slide = $(this);\n        if (index < s.loopedSlides) appendSlides.push(el);\n        if (index < slides.length && index >= slides.length - s.loopedSlides) prependSlides.push(el);\n        slide.attr('data-swiper-slide-index', index);\n    });\n    for (i = 0; i < appendSlides.length; i++) {\n        s.wrapper.append($(appendSlides[i].cloneNode(true)).addClass(s.params.slideDuplicateClass));\n    }\n    for (i = prependSlides.length - 1; i >= 0; i--) {\n        s.wrapper.prepend($(prependSlides[i].cloneNode(true)).addClass(s.params.slideDuplicateClass));\n    }\n};\ns.destroyLoop = function () {\n    s.wrapper.children('.' + s.params.slideClass + '.' + s.params.slideDuplicateClass).remove();\n    s.slides.removeAttr('data-swiper-slide-index');\n};\ns.reLoop = function (updatePosition) {\n    var oldIndex = s.activeIndex - s.loopedSlides;\n    s.destroyLoop();\n    s.createLoop();\n    s.updateSlidesSize();\n    if (updatePosition) {\n        s.slideTo(oldIndex + s.loopedSlides, 0, false);\n    }\n\n};\ns.fixLoop = function () {\n    var newIndex;\n    //Fix For Negative Oversliding\n    if (s.activeIndex < s.loopedSlides) {\n        newIndex = s.slides.length - s.loopedSlides * 3 + s.activeIndex;\n        newIndex = newIndex + s.loopedSlides;\n        s.slideTo(newIndex, 0, false, true);\n    }\n    //Fix For Positive Oversliding\n    else if ((s.params.slidesPerView === 'auto' && s.activeIndex >= s.loopedSlides * 2) || (s.activeIndex > s.slides.length - s.params.slidesPerView * 2)) {\n        newIndex = -s.slides.length + s.activeIndex + s.loopedSlides;\n        newIndex = newIndex + s.loopedSlides;\n        s.slideTo(newIndex, 0, false, true);\n    }\n};\n/*=========================\n  Append/Prepend/Remove Slides\n  ===========================*/\ns.appendSlide = function (slides) {\n    if (s.params.loop) {\n        s.destroyLoop();\n    }\n    if (typeof slides === 'object' && slides.length) {\n        for (var i = 0; i < slides.length; i++) {\n            if (slides[i]) s.wrapper.append(slides[i]);\n        }\n    }\n    else {\n        s.wrapper.append(slides);\n    }\n    if (s.params.loop) {\n        s.createLoop();\n    }\n    if (!(s.params.observer && s.support.observer)) {\n        s.update(true);\n    }\n};\ns.prependSlide = function (slides) {\n    if (s.params.loop) {\n        s.destroyLoop();\n    }\n    var newActiveIndex = s.activeIndex + 1;\n    if (typeof slides === 'object' && slides.length) {\n        for (var i = 0; i < slides.length; i++) {\n            if (slides[i]) s.wrapper.prepend(slides[i]);\n        }\n        newActiveIndex = s.activeIndex + slides.length;\n    }\n    else {\n        s.wrapper.prepend(slides);\n    }\n    if (s.params.loop) {\n        s.createLoop();\n    }\n    if (!(s.params.observer && s.support.observer)) {\n        s.update(true);\n    }\n    s.slideTo(newActiveIndex, 0, false);\n};\ns.removeSlide = function (slidesIndexes) {\n    if (s.params.loop) {\n        s.destroyLoop();\n        s.slides = s.wrapper.children('.' + s.params.slideClass);\n    }\n    var newActiveIndex = s.activeIndex,\n        indexToRemove;\n    if (typeof slidesIndexes === 'object' && slidesIndexes.length) {\n        for (var i = 0; i < slidesIndexes.length; i++) {\n            indexToRemove = slidesIndexes[i];\n            if (s.slides[indexToRemove]) s.slides.eq(indexToRemove).remove();\n            if (indexToRemove < newActiveIndex) newActiveIndex--;\n        }\n        newActiveIndex = Math.max(newActiveIndex, 0);\n    }\n    else {\n        indexToRemove = slidesIndexes;\n        if (s.slides[indexToRemove]) s.slides.eq(indexToRemove).remove();\n        if (indexToRemove < newActiveIndex) newActiveIndex--;\n        newActiveIndex = Math.max(newActiveIndex, 0);\n    }\n\n    if (s.params.loop) {\n        s.createLoop();\n    }\n\n    if (!(s.params.observer && s.support.observer)) {\n        s.update(true);\n    }\n    if (s.params.loop) {\n        s.slideTo(newActiveIndex + s.loopedSlides, 0, false);\n    }\n    else {\n        s.slideTo(newActiveIndex, 0, false);\n    }\n\n};\ns.removeAllSlides = function () {\n    var slidesIndexes = [];\n    for (var i = 0; i < s.slides.length; i++) {\n        slidesIndexes.push(i);\n    }\n    s.removeSlide(slidesIndexes);\n};\n"
  },
  {
    "path": "app_frontend/static/plugin/Swiper-3.3.1/src/js/dom-plugins.js",
    "content": "/*===========================\nAdd .swiper plugin from Dom libraries\n===========================*/\nfunction addLibraryPlugin(lib) {\n    lib.fn.swiper = function (params) {\n        var firstInstance;\n        lib(this).each(function () {\n            var s = new Swiper(this, params);\n            if (!firstInstance) firstInstance = s;\n        });\n        return firstInstance;\n    };\n}\n\nif (domLib) {\n    if (!('transitionEnd' in domLib.fn)) {\n        domLib.fn.transitionEnd = function (callback) {\n            var events = ['webkitTransitionEnd', 'transitionend', 'oTransitionEnd', 'MSTransitionEnd', 'msTransitionEnd'],\n                i, j, dom = this;\n            function fireCallBack(e) {\n                /*jshint validthis:true */\n                if (e.target !== this) return;\n                callback.call(this, e);\n                for (i = 0; i < events.length; i++) {\n                    dom.off(events[i], fireCallBack);\n                }\n            }\n            if (callback) {\n                for (i = 0; i < events.length; i++) {\n                    dom.on(events[i], fireCallBack);\n                }\n            }\n            return this;\n        };\n    }\n    if (!('transform' in domLib.fn)) {\n        domLib.fn.transform = function (transform) {\n            for (var i = 0; i < this.length; i++) {\n                var elStyle = this[i].style;\n                elStyle.webkitTransform = elStyle.MsTransform = elStyle.msTransform = elStyle.MozTransform = elStyle.OTransform = elStyle.transform = transform;\n            }\n            return this;\n        };\n    }\n    if (!('transition' in domLib.fn)) {\n        domLib.fn.transition = function (duration) {\n            if (typeof duration !== 'string') {\n                duration = duration + 'ms';\n            }\n            for (var i = 0; i < this.length; i++) {\n                var elStyle = this[i].style;\n                elStyle.webkitTransitionDuration = elStyle.MsTransitionDuration = elStyle.msTransitionDuration = elStyle.MozTransitionDuration = elStyle.OTransitionDuration = elStyle.transitionDuration = duration;\n            }\n            return this;\n        };\n    }\n}"
  },
  {
    "path": "app_frontend/static/plugin/Swiper-3.3.1/src/js/dom.js",
    "content": "/*===========================\nDom7 Library\n===========================*/\nvar Dom7 = (function () {\n    var Dom7 = function (arr) {\n        var _this = this, i = 0;\n        // Create array-like object\n        for (i = 0; i < arr.length; i++) {\n            _this[i] = arr[i];\n        }\n        _this.length = arr.length;\n        // Return collection with methods\n        return this;\n    };\n    var $ = function (selector, context) {\n        var arr = [], i = 0;\n        if (selector && !context) {\n            if (selector instanceof Dom7) {\n                return selector;\n            }\n        }\n        if (selector) {\n            // String\n            if (typeof selector === 'string') {\n                var els, tempParent, html = selector.trim();\n                if (html.indexOf('<') >= 0 && html.indexOf('>') >= 0) {\n                    var toCreate = 'div';\n                    if (html.indexOf('<li') === 0) toCreate = 'ul';\n                    if (html.indexOf('<tr') === 0) toCreate = 'tbody';\n                    if (html.indexOf('<td') === 0 || html.indexOf('<th') === 0) toCreate = 'tr';\n                    if (html.indexOf('<tbody') === 0) toCreate = 'table';\n                    if (html.indexOf('<option') === 0) toCreate = 'select';\n                    tempParent = document.createElement(toCreate);\n                    tempParent.innerHTML = selector;\n                    for (i = 0; i < tempParent.childNodes.length; i++) {\n                        arr.push(tempParent.childNodes[i]);\n                    }\n                }\n                else {\n                    if (!context && selector[0] === '#' && !selector.match(/[ .<>:~]/)) {\n                        // Pure ID selector\n                        els = [document.getElementById(selector.split('#')[1])];\n                    }\n                    else {\n                        // Other selectors\n                        els = (context || document).querySelectorAll(selector);\n                    }\n                    for (i = 0; i < els.length; i++) {\n                        if (els[i]) arr.push(els[i]);\n                    }\n                }\n            }\n            // Node/element\n            else if (selector.nodeType || selector === window || selector === document) {\n                arr.push(selector);\n            }\n            //Array of elements or instance of Dom\n            else if (selector.length > 0 && selector[0].nodeType) {\n                for (i = 0; i < selector.length; i++) {\n                    arr.push(selector[i]);\n                }\n            }\n        }\n        return new Dom7(arr);\n    };\n    Dom7.prototype = {\n        // Classes and attriutes\n        addClass: function (className) {\n            if (typeof className === 'undefined') {\n                return this;\n            }\n            var classes = className.split(' ');\n            for (var i = 0; i < classes.length; i++) {\n                for (var j = 0; j < this.length; j++) {\n                    this[j].classList.add(classes[i]);\n                }\n            }\n            return this;\n        },\n        removeClass: function (className) {\n            var classes = className.split(' ');\n            for (var i = 0; i < classes.length; i++) {\n                for (var j = 0; j < this.length; j++) {\n                    this[j].classList.remove(classes[i]);\n                }\n            }\n            return this;\n        },\n        hasClass: function (className) {\n            if (!this[0]) return false;\n            else return this[0].classList.contains(className);\n        },\n        toggleClass: function (className) {\n            var classes = className.split(' ');\n            for (var i = 0; i < classes.length; i++) {\n                for (var j = 0; j < this.length; j++) {\n                    this[j].classList.toggle(classes[i]);\n                }\n            }\n            return this;\n        },\n        attr: function (attrs, value) {\n            if (arguments.length === 1 && typeof attrs === 'string') {\n                // Get attr\n                if (this[0]) return this[0].getAttribute(attrs);\n                else return undefined;\n            }\n            else {\n                // Set attrs\n                for (var i = 0; i < this.length; i++) {\n                    if (arguments.length === 2) {\n                        // String\n                        this[i].setAttribute(attrs, value);\n                    }\n                    else {\n                        // Object\n                        for (var attrName in attrs) {\n                            this[i][attrName] = attrs[attrName];\n                            this[i].setAttribute(attrName, attrs[attrName]);\n                        }\n                    }\n                }\n                return this;\n            }\n        },\n        removeAttr: function (attr) {\n            for (var i = 0; i < this.length; i++) {\n                this[i].removeAttribute(attr);\n            }\n            return this;\n        },\n        data: function (key, value) {\n            if (typeof value === 'undefined') {\n                // Get value\n                if (this[0]) {\n                    var dataKey = this[0].getAttribute('data-' + key);\n                    if (dataKey) return dataKey;\n                    else if (this[0].dom7ElementDataStorage && (key in this[0].dom7ElementDataStorage)) return this[0].dom7ElementDataStorage[key];\n                    else return undefined;\n                }\n                else return undefined;\n            }\n            else {\n                // Set value\n                for (var i = 0; i < this.length; i++) {\n                    var el = this[i];\n                    if (!el.dom7ElementDataStorage) el.dom7ElementDataStorage = {};\n                    el.dom7ElementDataStorage[key] = value;\n                }\n                return this;\n            }\n        },\n        // Transforms\n        transform : function (transform) {\n            for (var i = 0; i < this.length; i++) {\n                var elStyle = this[i].style;\n                elStyle.webkitTransform = elStyle.MsTransform = elStyle.msTransform = elStyle.MozTransform = elStyle.OTransform = elStyle.transform = transform;\n            }\n            return this;\n        },\n        transition: function (duration) {\n            if (typeof duration !== 'string') {\n                duration = duration + 'ms';\n            }\n            for (var i = 0; i < this.length; i++) {\n                var elStyle = this[i].style;\n                elStyle.webkitTransitionDuration = elStyle.MsTransitionDuration = elStyle.msTransitionDuration = elStyle.MozTransitionDuration = elStyle.OTransitionDuration = elStyle.transitionDuration = duration;\n            }\n            return this;\n        },\n        //Events\n        on: function (eventName, targetSelector, listener, capture) {\n            function handleLiveEvent(e) {\n                var target = e.target;\n                if ($(target).is(targetSelector)) listener.call(target, e);\n                else {\n                    var parents = $(target).parents();\n                    for (var k = 0; k < parents.length; k++) {\n                        if ($(parents[k]).is(targetSelector)) listener.call(parents[k], e);\n                    }\n                }\n            }\n            var events = eventName.split(' ');\n            var i, j;\n            for (i = 0; i < this.length; i++) {\n                if (typeof targetSelector === 'function' || targetSelector === false) {\n                    // Usual events\n                    if (typeof targetSelector === 'function') {\n                        listener = arguments[1];\n                        capture = arguments[2] || false;\n                    }\n                    for (j = 0; j < events.length; j++) {\n                        this[i].addEventListener(events[j], listener, capture);\n                    }\n                }\n                else {\n                    //Live events\n                    for (j = 0; j < events.length; j++) {\n                        if (!this[i].dom7LiveListeners) this[i].dom7LiveListeners = [];\n                        this[i].dom7LiveListeners.push({listener: listener, liveListener: handleLiveEvent});\n                        this[i].addEventListener(events[j], handleLiveEvent, capture);\n                    }\n                }\n            }\n\n            return this;\n        },\n        off: function (eventName, targetSelector, listener, capture) {\n            var events = eventName.split(' ');\n            for (var i = 0; i < events.length; i++) {\n                for (var j = 0; j < this.length; j++) {\n                    if (typeof targetSelector === 'function' || targetSelector === false) {\n                        // Usual events\n                        if (typeof targetSelector === 'function') {\n                            listener = arguments[1];\n                            capture = arguments[2] || false;\n                        }\n                        this[j].removeEventListener(events[i], listener, capture);\n                    }\n                    else {\n                        // Live event\n                        if (this[j].dom7LiveListeners) {\n                            for (var k = 0; k < this[j].dom7LiveListeners.length; k++) {\n                                if (this[j].dom7LiveListeners[k].listener === listener) {\n                                    this[j].removeEventListener(events[i], this[j].dom7LiveListeners[k].liveListener, capture);\n                                }\n                            }\n                        }\n                    }\n                }\n            }\n            return this;\n        },\n        once: function (eventName, targetSelector, listener, capture) {\n            var dom = this;\n            if (typeof targetSelector === 'function') {\n                targetSelector = false;\n                listener = arguments[1];\n                capture = arguments[2];\n            }\n            function proxy(e) {\n                listener(e);\n                dom.off(eventName, targetSelector, proxy, capture);\n            }\n            dom.on(eventName, targetSelector, proxy, capture);\n        },\n        trigger: function (eventName, eventData) {\n            for (var i = 0; i < this.length; i++) {\n                var evt;\n                try {\n                    evt = new window.CustomEvent(eventName, {detail: eventData, bubbles: true, cancelable: true});\n                }\n                catch (e) {\n                    evt = document.createEvent('Event');\n                    evt.initEvent(eventName, true, true);\n                    evt.detail = eventData;\n                }\n                this[i].dispatchEvent(evt);\n            }\n            return this;\n        },\n        transitionEnd: function (callback) {\n            var events = ['webkitTransitionEnd', 'transitionend', 'oTransitionEnd', 'MSTransitionEnd', 'msTransitionEnd'],\n                i, j, dom = this;\n            function fireCallBack(e) {\n                /*jshint validthis:true */\n                if (e.target !== this) return;\n                callback.call(this, e);\n                for (i = 0; i < events.length; i++) {\n                    dom.off(events[i], fireCallBack);\n                }\n            }\n            if (callback) {\n                for (i = 0; i < events.length; i++) {\n                    dom.on(events[i], fireCallBack);\n                }\n            }\n            return this;\n        },\n        // Sizing/Styles\n        width: function () {\n            if (this[0] === window) {\n                return window.innerWidth;\n            }\n            else {\n                if (this.length > 0) {\n                    return parseFloat(this.css('width'));\n                }\n                else {\n                    return null;\n                }\n            }\n        },\n        outerWidth: function (includeMargins) {\n            if (this.length > 0) {\n                if (includeMargins)\n                    return this[0].offsetWidth + parseFloat(this.css('margin-right')) + parseFloat(this.css('margin-left'));\n                else\n                    return this[0].offsetWidth;\n            }\n            else return null;\n        },\n        height: function () {\n            if (this[0] === window) {\n                return window.innerHeight;\n            }\n            else {\n                if (this.length > 0) {\n                    return parseFloat(this.css('height'));\n                }\n                else {\n                    return null;\n                }\n            }\n        },\n        outerHeight: function (includeMargins) {\n            if (this.length > 0) {\n                if (includeMargins)\n                    return this[0].offsetHeight + parseFloat(this.css('margin-top')) + parseFloat(this.css('margin-bottom'));\n                else\n                    return this[0].offsetHeight;\n            }\n            else return null;\n        },\n        offset: function () {\n            if (this.length > 0) {\n                var el = this[0];\n                var box = el.getBoundingClientRect();\n                var body = document.body;\n                var clientTop  = el.clientTop  || body.clientTop  || 0;\n                var clientLeft = el.clientLeft || body.clientLeft || 0;\n                var scrollTop  = window.pageYOffset || el.scrollTop;\n                var scrollLeft = window.pageXOffset || el.scrollLeft;\n                return {\n                    top: box.top  + scrollTop  - clientTop,\n                    left: box.left + scrollLeft - clientLeft\n                };\n            }\n            else {\n                return null;\n            }\n        },\n        css: function (props, value) {\n            var i;\n            if (arguments.length === 1) {\n                if (typeof props === 'string') {\n                    if (this[0]) return window.getComputedStyle(this[0], null).getPropertyValue(props);\n                }\n                else {\n                    for (i = 0; i < this.length; i++) {\n                        for (var prop in props) {\n                            this[i].style[prop] = props[prop];\n                        }\n                    }\n                    return this;\n                }\n            }\n            if (arguments.length === 2 && typeof props === 'string') {\n                for (i = 0; i < this.length; i++) {\n                    this[i].style[props] = value;\n                }\n                return this;\n            }\n            return this;\n        },\n\n        //Dom manipulation\n        each: function (callback) {\n            for (var i = 0; i < this.length; i++) {\n                callback.call(this[i], i, this[i]);\n            }\n            return this;\n        },\n        html: function (html) {\n            if (typeof html === 'undefined') {\n                return this[0] ? this[0].innerHTML : undefined;\n            }\n            else {\n                for (var i = 0; i < this.length; i++) {\n                    this[i].innerHTML = html;\n                }\n                return this;\n            }\n        },\n        text: function (text) {\n            if (typeof text === 'undefined') {\n                if (this[0]) {\n                    return this[0].textContent.trim();\n                }\n                else return null;\n            }\n            else {\n                for (var i = 0; i < this.length; i++) {\n                    this[i].textContent = text;\n                }\n                return this;\n            }\n        },\n        is: function (selector) {\n            if (!this[0]) return false;\n            var compareWith, i;\n            if (typeof selector === 'string') {\n                var el = this[0];\n                if (el === document) return selector === document;\n                if (el === window) return selector === window;\n\n                if (el.matches) return el.matches(selector);\n                else if (el.webkitMatchesSelector) return el.webkitMatchesSelector(selector);\n                else if (el.mozMatchesSelector) return el.mozMatchesSelector(selector);\n                else if (el.msMatchesSelector) return el.msMatchesSelector(selector);\n                else {\n                    compareWith = $(selector);\n                    for (i = 0; i < compareWith.length; i++) {\n                        if (compareWith[i] === this[0]) return true;\n                    }\n                    return false;\n                }\n            }\n            else if (selector === document) return this[0] === document;\n            else if (selector === window) return this[0] === window;\n            else {\n                if (selector.nodeType || selector instanceof Dom7) {\n                    compareWith = selector.nodeType ? [selector] : selector;\n                    for (i = 0; i < compareWith.length; i++) {\n                        if (compareWith[i] === this[0]) return true;\n                    }\n                    return false;\n                }\n                return false;\n            }\n\n        },\n        index: function () {\n            if (this[0]) {\n                var child = this[0];\n                var i = 0;\n                while ((child = child.previousSibling) !== null) {\n                    if (child.nodeType === 1) i++;\n                }\n                return i;\n            }\n            else return undefined;\n        },\n        eq: function (index) {\n            if (typeof index === 'undefined') return this;\n            var length = this.length;\n            var returnIndex;\n            if (index > length - 1) {\n                return new Dom7([]);\n            }\n            if (index < 0) {\n                returnIndex = length + index;\n                if (returnIndex < 0) return new Dom7([]);\n                else return new Dom7([this[returnIndex]]);\n            }\n            return new Dom7([this[index]]);\n        },\n        append: function (newChild) {\n            var i, j;\n            for (i = 0; i < this.length; i++) {\n                if (typeof newChild === 'string') {\n                    var tempDiv = document.createElement('div');\n                    tempDiv.innerHTML = newChild;\n                    while (tempDiv.firstChild) {\n                        this[i].appendChild(tempDiv.firstChild);\n                    }\n                }\n                else if (newChild instanceof Dom7) {\n                    for (j = 0; j < newChild.length; j++) {\n                        this[i].appendChild(newChild[j]);\n                    }\n                }\n                else {\n                    this[i].appendChild(newChild);\n                }\n            }\n            return this;\n        },\n        prepend: function (newChild) {\n            var i, j;\n            for (i = 0; i < this.length; i++) {\n                if (typeof newChild === 'string') {\n                    var tempDiv = document.createElement('div');\n                    tempDiv.innerHTML = newChild;\n                    for (j = tempDiv.childNodes.length - 1; j >= 0; j--) {\n                        this[i].insertBefore(tempDiv.childNodes[j], this[i].childNodes[0]);\n                    }\n                    // this[i].insertAdjacentHTML('afterbegin', newChild);\n                }\n                else if (newChild instanceof Dom7) {\n                    for (j = 0; j < newChild.length; j++) {\n                        this[i].insertBefore(newChild[j], this[i].childNodes[0]);\n                    }\n                }\n                else {\n                    this[i].insertBefore(newChild, this[i].childNodes[0]);\n                }\n            }\n            return this;\n        },\n        insertBefore: function (selector) {\n            var before = $(selector);\n            for (var i = 0; i < this.length; i++) {\n                if (before.length === 1) {\n                    before[0].parentNode.insertBefore(this[i], before[0]);\n                }\n                else if (before.length > 1) {\n                    for (var j = 0; j < before.length; j++) {\n                        before[j].parentNode.insertBefore(this[i].cloneNode(true), before[j]);\n                    }\n                }\n            }\n        },\n        insertAfter: function (selector) {\n            var after = $(selector);\n            for (var i = 0; i < this.length; i++) {\n                if (after.length === 1) {\n                    after[0].parentNode.insertBefore(this[i], after[0].nextSibling);\n                }\n                else if (after.length > 1) {\n                    for (var j = 0; j < after.length; j++) {\n                        after[j].parentNode.insertBefore(this[i].cloneNode(true), after[j].nextSibling);\n                    }\n                }\n            }\n        },\n        next: function (selector) {\n            if (this.length > 0) {\n                if (selector) {\n                    if (this[0].nextElementSibling && $(this[0].nextElementSibling).is(selector)) return new Dom7([this[0].nextElementSibling]);\n                    else return new Dom7([]);\n                }\n                else {\n                    if (this[0].nextElementSibling) return new Dom7([this[0].nextElementSibling]);\n                    else return new Dom7([]);\n                }\n            }\n            else return new Dom7([]);\n        },\n        nextAll: function (selector) {\n            var nextEls = [];\n            var el = this[0];\n            if (!el) return new Dom7([]);\n            while (el.nextElementSibling) {\n                var next = el.nextElementSibling;\n                if (selector) {\n                    if($(next).is(selector)) nextEls.push(next);\n                }\n                else nextEls.push(next);\n                el = next;\n            }\n            return new Dom7(nextEls);\n        },\n        prev: function (selector) {\n            if (this.length > 0) {\n                if (selector) {\n                    if (this[0].previousElementSibling && $(this[0].previousElementSibling).is(selector)) return new Dom7([this[0].previousElementSibling]);\n                    else return new Dom7([]);\n                }\n                else {\n                    if (this[0].previousElementSibling) return new Dom7([this[0].previousElementSibling]);\n                    else return new Dom7([]);\n                }\n            }\n            else return new Dom7([]);\n        },\n        prevAll: function (selector) {\n            var prevEls = [];\n            var el = this[0];\n            if (!el) return new Dom7([]);\n            while (el.previousElementSibling) {\n                var prev = el.previousElementSibling;\n                if (selector) {\n                    if($(prev).is(selector)) prevEls.push(prev);\n                }\n                else prevEls.push(prev);\n                el = prev;\n            }\n            return new Dom7(prevEls);\n        },\n        parent: function (selector) {\n            var parents = [];\n            for (var i = 0; i < this.length; i++) {\n                if (selector) {\n                    if ($(this[i].parentNode).is(selector)) parents.push(this[i].parentNode);\n                }\n                else {\n                    parents.push(this[i].parentNode);\n                }\n            }\n            return $($.unique(parents));\n        },\n        parents: function (selector) {\n            var parents = [];\n            for (var i = 0; i < this.length; i++) {\n                var parent = this[i].parentNode;\n                while (parent) {\n                    if (selector) {\n                        if ($(parent).is(selector)) parents.push(parent);\n                    }\n                    else {\n                        parents.push(parent);\n                    }\n                    parent = parent.parentNode;\n                }\n            }\n            return $($.unique(parents));\n        },\n        find : function (selector) {\n            var foundElements = [];\n            for (var i = 0; i < this.length; i++) {\n                var found = this[i].querySelectorAll(selector);\n                for (var j = 0; j < found.length; j++) {\n                    foundElements.push(found[j]);\n                }\n            }\n            return new Dom7(foundElements);\n        },\n        children: function (selector) {\n            var children = [];\n            for (var i = 0; i < this.length; i++) {\n                var childNodes = this[i].childNodes;\n\n                for (var j = 0; j < childNodes.length; j++) {\n                    if (!selector) {\n                        if (childNodes[j].nodeType === 1) children.push(childNodes[j]);\n                    }\n                    else {\n                        if (childNodes[j].nodeType === 1 && $(childNodes[j]).is(selector)) children.push(childNodes[j]);\n                    }\n                }\n            }\n            return new Dom7($.unique(children));\n        },\n        remove: function () {\n            for (var i = 0; i < this.length; i++) {\n                if (this[i].parentNode) this[i].parentNode.removeChild(this[i]);\n            }\n            return this;\n        },\n        add: function () {\n            var dom = this;\n            var i, j;\n            for (i = 0; i < arguments.length; i++) {\n                var toAdd = $(arguments[i]);\n                for (j = 0; j < toAdd.length; j++) {\n                    dom[dom.length] = toAdd[j];\n                    dom.length++;\n                }\n            }\n            return dom;\n        }\n    };\n    $.fn = Dom7.prototype;\n    $.unique = function (arr) {\n        var unique = [];\n        for (var i = 0; i < arr.length; i++) {\n            if (unique.indexOf(arr[i]) === -1) unique.push(arr[i]);\n        }\n        return unique;\n    };\n\n    return $;\n})();\n"
  },
  {
    "path": "app_frontend/static/plugin/Swiper-3.3.1/src/js/effects.js",
    "content": "/*=========================\n  Effects\n  ===========================*/\ns.effects = {\n    fade: {\n        setTranslate: function () {\n            for (var i = 0; i < s.slides.length; i++) {\n                var slide = s.slides.eq(i);\n                var offset = slide[0].swiperSlideOffset;\n                var tx = -offset;\n                if (!s.params.virtualTranslate) tx = tx - s.translate;\n                var ty = 0;\n                if (!s.isHorizontal()) {\n                    ty = tx;\n                    tx = 0;\n                }\n                var slideOpacity = s.params.fade.crossFade ?\n                        Math.max(1 - Math.abs(slide[0].progress), 0) :\n                        1 + Math.min(Math.max(slide[0].progress, -1), 0);\n                slide\n                    .css({\n                        opacity: slideOpacity\n                    })\n                    .transform('translate3d(' + tx + 'px, ' + ty + 'px, 0px)');\n\n            }\n\n        },\n        setTransition: function (duration) {\n            s.slides.transition(duration);\n            if (s.params.virtualTranslate && duration !== 0) {\n                var eventTriggered = false;\n                s.slides.transitionEnd(function () {\n                    if (eventTriggered) return;\n                    if (!s) return;\n                    eventTriggered = true;\n                    s.animating = false;\n                    var triggerEvents = ['webkitTransitionEnd', 'transitionend', 'oTransitionEnd', 'MSTransitionEnd', 'msTransitionEnd'];\n                    for (var i = 0; i < triggerEvents.length; i++) {\n                        s.wrapper.trigger(triggerEvents[i]);\n                    }\n                });\n            }\n        }\n    },\n    flip: {\n        setTranslate: function () {\n            for (var i = 0; i < s.slides.length; i++) {\n                var slide = s.slides.eq(i);\n                var progress = slide[0].progress;\n                if (s.params.flip.limitRotation) {\n                    progress = Math.max(Math.min(slide[0].progress, 1), -1);\n                }\n                var offset = slide[0].swiperSlideOffset;\n                var rotate = -180 * progress,\n                    rotateY = rotate,\n                    rotateX = 0,\n                    tx = -offset,\n                    ty = 0;\n                if (!s.isHorizontal()) {\n                    ty = tx;\n                    tx = 0;\n                    rotateX = -rotateY;\n                    rotateY = 0;\n                }\n                else if (s.rtl) {\n                    rotateY = -rotateY;\n                }\n\n                slide[0].style.zIndex = -Math.abs(Math.round(progress)) + s.slides.length;\n\n                if (s.params.flip.slideShadows) {\n                    //Set shadows\n                    var shadowBefore = s.isHorizontal() ? slide.find('.swiper-slide-shadow-left') : slide.find('.swiper-slide-shadow-top');\n                    var shadowAfter = s.isHorizontal() ? slide.find('.swiper-slide-shadow-right') : slide.find('.swiper-slide-shadow-bottom');\n                    if (shadowBefore.length === 0) {\n                        shadowBefore = $('<div class=\"swiper-slide-shadow-' + (s.isHorizontal() ? 'left' : 'top') + '\"></div>');\n                        slide.append(shadowBefore);\n                    }\n                    if (shadowAfter.length === 0) {\n                        shadowAfter = $('<div class=\"swiper-slide-shadow-' + (s.isHorizontal() ? 'right' : 'bottom') + '\"></div>');\n                        slide.append(shadowAfter);\n                    }\n                    if (shadowBefore.length) shadowBefore[0].style.opacity = Math.max(-progress, 0);\n                    if (shadowAfter.length) shadowAfter[0].style.opacity = Math.max(progress, 0);\n                }\n\n                slide\n                    .transform('translate3d(' + tx + 'px, ' + ty + 'px, 0px) rotateX(' + rotateX + 'deg) rotateY(' + rotateY + 'deg)');\n            }\n        },\n        setTransition: function (duration) {\n            s.slides.transition(duration).find('.swiper-slide-shadow-top, .swiper-slide-shadow-right, .swiper-slide-shadow-bottom, .swiper-slide-shadow-left').transition(duration);\n            if (s.params.virtualTranslate && duration !== 0) {\n                var eventTriggered = false;\n                s.slides.eq(s.activeIndex).transitionEnd(function () {\n                    if (eventTriggered) return;\n                    if (!s) return;\n                    if (!$(this).hasClass(s.params.slideActiveClass)) return;\n                    eventTriggered = true;\n                    s.animating = false;\n                    var triggerEvents = ['webkitTransitionEnd', 'transitionend', 'oTransitionEnd', 'MSTransitionEnd', 'msTransitionEnd'];\n                    for (var i = 0; i < triggerEvents.length; i++) {\n                        s.wrapper.trigger(triggerEvents[i]);\n                    }\n                });\n            }\n        }\n    },\n    cube: {\n        setTranslate: function () {\n            var wrapperRotate = 0, cubeShadow;\n            if (s.params.cube.shadow) {\n                if (s.isHorizontal()) {\n                    cubeShadow = s.wrapper.find('.swiper-cube-shadow');\n                    if (cubeShadow.length === 0) {\n                        cubeShadow = $('<div class=\"swiper-cube-shadow\"></div>');\n                        s.wrapper.append(cubeShadow);\n                    }\n                    cubeShadow.css({height: s.width + 'px'});\n                }\n                else {\n                    cubeShadow = s.container.find('.swiper-cube-shadow');\n                    if (cubeShadow.length === 0) {\n                        cubeShadow = $('<div class=\"swiper-cube-shadow\"></div>');\n                        s.container.append(cubeShadow);\n                    }\n                }\n            }\n            for (var i = 0; i < s.slides.length; i++) {\n                var slide = s.slides.eq(i);\n                var slideAngle = i * 90;\n                var round = Math.floor(slideAngle / 360);\n                if (s.rtl) {\n                    slideAngle = -slideAngle;\n                    round = Math.floor(-slideAngle / 360);\n                }\n                var progress = Math.max(Math.min(slide[0].progress, 1), -1);\n                var tx = 0, ty = 0, tz = 0;\n                if (i % 4 === 0) {\n                    tx = - round * 4 * s.size;\n                    tz = 0;\n                }\n                else if ((i - 1) % 4 === 0) {\n                    tx = 0;\n                    tz = - round * 4 * s.size;\n                }\n                else if ((i - 2) % 4 === 0) {\n                    tx = s.size + round * 4 * s.size;\n                    tz = s.size;\n                }\n                else if ((i - 3) % 4 === 0) {\n                    tx = - s.size;\n                    tz = 3 * s.size + s.size * 4 * round;\n                }\n                if (s.rtl) {\n                    tx = -tx;\n                }\n\n                if (!s.isHorizontal()) {\n                    ty = tx;\n                    tx = 0;\n                }\n\n                var transform = 'rotateX(' + (s.isHorizontal() ? 0 : -slideAngle) + 'deg) rotateY(' + (s.isHorizontal() ? slideAngle : 0) + 'deg) translate3d(' + tx + 'px, ' + ty + 'px, ' + tz + 'px)';\n                if (progress <= 1 && progress > -1) {\n                    wrapperRotate = i * 90 + progress * 90;\n                    if (s.rtl) wrapperRotate = -i * 90 - progress * 90;\n                }\n                slide.transform(transform);\n                if (s.params.cube.slideShadows) {\n                    //Set shadows\n                    var shadowBefore = s.isHorizontal() ? slide.find('.swiper-slide-shadow-left') : slide.find('.swiper-slide-shadow-top');\n                    var shadowAfter = s.isHorizontal() ? slide.find('.swiper-slide-shadow-right') : slide.find('.swiper-slide-shadow-bottom');\n                    if (shadowBefore.length === 0) {\n                        shadowBefore = $('<div class=\"swiper-slide-shadow-' + (s.isHorizontal() ? 'left' : 'top') + '\"></div>');\n                        slide.append(shadowBefore);\n                    }\n                    if (shadowAfter.length === 0) {\n                        shadowAfter = $('<div class=\"swiper-slide-shadow-' + (s.isHorizontal() ? 'right' : 'bottom') + '\"></div>');\n                        slide.append(shadowAfter);\n                    }\n                    if (shadowBefore.length) shadowBefore[0].style.opacity = Math.max(-progress, 0);\n                    if (shadowAfter.length) shadowAfter[0].style.opacity = Math.max(progress, 0);\n                }\n            }\n            s.wrapper.css({\n                '-webkit-transform-origin': '50% 50% -' + (s.size / 2) + 'px',\n                '-moz-transform-origin': '50% 50% -' + (s.size / 2) + 'px',\n                '-ms-transform-origin': '50% 50% -' + (s.size / 2) + 'px',\n                'transform-origin': '50% 50% -' + (s.size / 2) + 'px'\n            });\n\n            if (s.params.cube.shadow) {\n                if (s.isHorizontal()) {\n                    cubeShadow.transform('translate3d(0px, ' + (s.width / 2 + s.params.cube.shadowOffset) + 'px, ' + (-s.width / 2) + 'px) rotateX(90deg) rotateZ(0deg) scale(' + (s.params.cube.shadowScale) + ')');\n                }\n                else {\n                    var shadowAngle = Math.abs(wrapperRotate) - Math.floor(Math.abs(wrapperRotate) / 90) * 90;\n                    var multiplier = 1.5 - (Math.sin(shadowAngle * 2 * Math.PI / 360) / 2 + Math.cos(shadowAngle * 2 * Math.PI / 360) / 2);\n                    var scale1 = s.params.cube.shadowScale,\n                        scale2 = s.params.cube.shadowScale / multiplier,\n                        offset = s.params.cube.shadowOffset;\n                    cubeShadow.transform('scale3d(' + scale1 + ', 1, ' + scale2 + ') translate3d(0px, ' + (s.height / 2 + offset) + 'px, ' + (-s.height / 2 / scale2) + 'px) rotateX(-90deg)');\n                }\n            }\n            var zFactor = (s.isSafari || s.isUiWebView) ? (-s.size / 2) : 0;\n            s.wrapper.transform('translate3d(0px,0,' + zFactor + 'px) rotateX(' + (s.isHorizontal() ? 0 : wrapperRotate) + 'deg) rotateY(' + (s.isHorizontal() ? -wrapperRotate : 0) + 'deg)');\n        },\n        setTransition: function (duration) {\n            s.slides.transition(duration).find('.swiper-slide-shadow-top, .swiper-slide-shadow-right, .swiper-slide-shadow-bottom, .swiper-slide-shadow-left').transition(duration);\n            if (s.params.cube.shadow && !s.isHorizontal()) {\n                s.container.find('.swiper-cube-shadow').transition(duration);\n            }\n        }\n    },\n    coverflow: {\n        setTranslate: function () {\n            var transform = s.translate;\n            var center = s.isHorizontal() ? -transform + s.width / 2 : -transform + s.height / 2;\n            var rotate = s.isHorizontal() ? s.params.coverflow.rotate: -s.params.coverflow.rotate;\n            var translate = s.params.coverflow.depth;\n            //Each slide offset from center\n            for (var i = 0, length = s.slides.length; i < length; i++) {\n                var slide = s.slides.eq(i);\n                var slideSize = s.slidesSizesGrid[i];\n                var slideOffset = slide[0].swiperSlideOffset;\n                var offsetMultiplier = (center - slideOffset - slideSize / 2) / slideSize * s.params.coverflow.modifier;\n\n                var rotateY = s.isHorizontal() ? rotate * offsetMultiplier : 0;\n                var rotateX = s.isHorizontal() ? 0 : rotate * offsetMultiplier;\n                // var rotateZ = 0\n                var translateZ = -translate * Math.abs(offsetMultiplier);\n\n                var translateY = s.isHorizontal() ? 0 : s.params.coverflow.stretch * (offsetMultiplier);\n                var translateX = s.isHorizontal() ? s.params.coverflow.stretch * (offsetMultiplier) : 0;\n\n                //Fix for ultra small values\n                if (Math.abs(translateX) < 0.001) translateX = 0;\n                if (Math.abs(translateY) < 0.001) translateY = 0;\n                if (Math.abs(translateZ) < 0.001) translateZ = 0;\n                if (Math.abs(rotateY) < 0.001) rotateY = 0;\n                if (Math.abs(rotateX) < 0.001) rotateX = 0;\n\n                var slideTransform = 'translate3d(' + translateX + 'px,' + translateY + 'px,' + translateZ + 'px)  rotateX(' + rotateX + 'deg) rotateY(' + rotateY + 'deg)';\n\n                slide.transform(slideTransform);\n                slide[0].style.zIndex = -Math.abs(Math.round(offsetMultiplier)) + 1;\n                if (s.params.coverflow.slideShadows) {\n                    //Set shadows\n                    var shadowBefore = s.isHorizontal() ? slide.find('.swiper-slide-shadow-left') : slide.find('.swiper-slide-shadow-top');\n                    var shadowAfter = s.isHorizontal() ? slide.find('.swiper-slide-shadow-right') : slide.find('.swiper-slide-shadow-bottom');\n                    if (shadowBefore.length === 0) {\n                        shadowBefore = $('<div class=\"swiper-slide-shadow-' + (s.isHorizontal() ? 'left' : 'top') + '\"></div>');\n                        slide.append(shadowBefore);\n                    }\n                    if (shadowAfter.length === 0) {\n                        shadowAfter = $('<div class=\"swiper-slide-shadow-' + (s.isHorizontal() ? 'right' : 'bottom') + '\"></div>');\n                        slide.append(shadowAfter);\n                    }\n                    if (shadowBefore.length) shadowBefore[0].style.opacity = offsetMultiplier > 0 ? offsetMultiplier : 0;\n                    if (shadowAfter.length) shadowAfter[0].style.opacity = (-offsetMultiplier) > 0 ? -offsetMultiplier : 0;\n                }\n            }\n\n            //Set correct perspective for IE10\n            if (s.browser.ie) {\n                var ws = s.wrapper[0].style;\n                ws.perspectiveOrigin = center + 'px 50%';\n            }\n        },\n        setTransition: function (duration) {\n            s.slides.transition(duration).find('.swiper-slide-shadow-top, .swiper-slide-shadow-right, .swiper-slide-shadow-bottom, .swiper-slide-shadow-left').transition(duration);\n        }\n    }\n};"
  },
  {
    "path": "app_frontend/static/plugin/Swiper-3.3.1/src/js/emitter.js",
    "content": "/*=========================\n  Events/Callbacks/Plugins Emitter\n  ===========================*/\nfunction normalizeEventName (eventName) {\n    if (eventName.indexOf('on') !== 0) {\n        if (eventName[0] !== eventName[0].toUpperCase()) {\n            eventName = 'on' + eventName[0].toUpperCase() + eventName.substring(1);\n        }\n        else {\n            eventName = 'on' + eventName;\n        }\n    }\n    return eventName;\n}\ns.emitterEventListeners = {\n\n};\ns.emit = function (eventName) {\n    // Trigger callbacks\n    if (s.params[eventName]) {\n        s.params[eventName](arguments[1], arguments[2], arguments[3], arguments[4], arguments[5]);\n    }\n    var i;\n    // Trigger events\n    if (s.emitterEventListeners[eventName]) {\n        for (i = 0; i < s.emitterEventListeners[eventName].length; i++) {\n            s.emitterEventListeners[eventName][i](arguments[1], arguments[2], arguments[3], arguments[4], arguments[5]);\n        }\n    }\n    // Trigger plugins\n    if (s.callPlugins) s.callPlugins(eventName, arguments[1], arguments[2], arguments[3], arguments[4], arguments[5]);\n};\ns.on = function (eventName, handler) {\n    eventName = normalizeEventName(eventName);\n    if (!s.emitterEventListeners[eventName]) s.emitterEventListeners[eventName] = [];\n    s.emitterEventListeners[eventName].push(handler);\n    return s;\n};\ns.off = function (eventName, handler) {\n    var i;\n    eventName = normalizeEventName(eventName);\n    if (typeof handler === 'undefined') {\n        // Remove all handlers for such event\n        s.emitterEventListeners[eventName] = [];\n        return s;\n    }\n    if (!s.emitterEventListeners[eventName] || s.emitterEventListeners[eventName].length === 0) return;\n    for (i = 0; i < s.emitterEventListeners[eventName].length; i++) {\n        if(s.emitterEventListeners[eventName][i] === handler) s.emitterEventListeners[eventName].splice(i, 1);\n    }\n    return s;\n};\ns.once = function (eventName, handler) {\n    eventName = normalizeEventName(eventName);\n    var _handler = function () {\n        handler(arguments[0], arguments[1], arguments[2], arguments[3], arguments[4]);\n        s.off(eventName, _handler);\n    };\n    s.on(eventName, _handler);\n    return s;\n};"
  },
  {
    "path": "app_frontend/static/plugin/Swiper-3.3.1/src/js/get-dom-lib.js",
    "content": "/*===========================\n Get Dom libraries\n ===========================*/\nvar swiperDomPlugins = ['jQuery', 'Zepto', 'Dom7'];\nfor (var i = 0; i < swiperDomPlugins.length; i++) {\n\tif (window[swiperDomPlugins[i]]) {\n\t\taddLibraryPlugin(window[swiperDomPlugins[i]]);\n\t}\n}\n// Required DOM Plugins\nvar domLib;\nif (typeof Dom7 === 'undefined') {\n\tdomLib = window.Dom7 || window.Zepto || window.jQuery;\n}\nelse {\n\tdomLib = Dom7;\n}"
  },
  {
    "path": "app_frontend/static/plugin/Swiper-3.3.1/src/js/get-jquery.js",
    "content": "/*===========================\n Get jQuery\n ===========================*/\n\naddLibraryPlugin($);\n\nvar domLib = $;"
  },
  {
    "path": "app_frontend/static/plugin/Swiper-3.3.1/src/js/hashnav.js",
    "content": "/*=========================\n  Hash Navigation\n  ===========================*/\ns.hashnav = {\n    init: function () {\n        if (!s.params.hashnav) return;\n        s.hashnav.initialized = true;\n        var hash = document.location.hash.replace('#', '');\n        if (!hash) return;\n        var speed = 0;\n        for (var i = 0, length = s.slides.length; i < length; i++) {\n            var slide = s.slides.eq(i);\n            var slideHash = slide.attr('data-hash');\n            if (slideHash === hash && !slide.hasClass(s.params.slideDuplicateClass)) {\n                var index = slide.index();\n                s.slideTo(index, speed, s.params.runCallbacksOnInit, true);\n            }\n        }\n    },\n    setHash: function () {\n        if (!s.hashnav.initialized || !s.params.hashnav) return;\n        document.location.hash = s.slides.eq(s.activeIndex).attr('data-hash') || '';\n    }\n};"
  },
  {
    "path": "app_frontend/static/plugin/Swiper-3.3.1/src/js/init.js",
    "content": "/*=========================\n  Init/Destroy\n  ===========================*/\ns.init = function () {\n    if (s.params.loop) s.createLoop();\n    s.updateContainerSize();\n    s.updateSlidesSize();\n    s.updatePagination();\n    if (s.params.scrollbar && s.scrollbar) {\n        s.scrollbar.set();\n        if (s.params.scrollbarDraggable) {\n            s.scrollbar.enableDraggable();\n        }\n    }\n    if (s.params.effect !== 'slide' && s.effects[s.params.effect]) {\n        if (!s.params.loop) s.updateProgress();\n        s.effects[s.params.effect].setTranslate();\n    }\n    if (s.params.loop) {\n        s.slideTo(s.params.initialSlide + s.loopedSlides, 0, s.params.runCallbacksOnInit);\n    }\n    else {\n        s.slideTo(s.params.initialSlide, 0, s.params.runCallbacksOnInit);\n        if (s.params.initialSlide === 0) {\n            if (s.parallax && s.params.parallax) s.parallax.setTranslate();\n            if (s.lazy && s.params.lazyLoading) {\n                s.lazy.load();\n                s.lazy.initialImageLoaded = true;\n            }\n        }\n    }\n    s.attachEvents();\n    if (s.params.observer && s.support.observer) {\n        s.initObservers();\n    }\n    if (s.params.preloadImages && !s.params.lazyLoading) {\n        s.preloadImages();\n    }\n    if (s.params.autoplay) {\n        s.startAutoplay();\n    }\n    if (s.params.keyboardControl) {\n        if (s.enableKeyboardControl) s.enableKeyboardControl();\n    }\n    if (s.params.mousewheelControl) {\n        if (s.enableMousewheelControl) s.enableMousewheelControl();\n    }\n    if (s.params.hashnav) {\n        if (s.hashnav) s.hashnav.init();\n    }\n    if (s.params.a11y && s.a11y) s.a11y.init();\n    s.emit('onInit', s);\n};\n\n// Cleanup dynamic styles\ns.cleanupStyles = function () {\n    // Container\n    s.container.removeClass(s.classNames.join(' ')).removeAttr('style');\n\n    // Wrapper\n    s.wrapper.removeAttr('style');\n\n    // Slides\n    if (s.slides && s.slides.length) {\n        s.slides\n            .removeClass([\n              s.params.slideVisibleClass,\n              s.params.slideActiveClass,\n              s.params.slideNextClass,\n              s.params.slidePrevClass\n            ].join(' '))\n            .removeAttr('style')\n            .removeAttr('data-swiper-column')\n            .removeAttr('data-swiper-row');\n    }\n\n    // Pagination/Bullets\n    if (s.paginationContainer && s.paginationContainer.length) {\n        s.paginationContainer.removeClass(s.params.paginationHiddenClass);\n    }\n    if (s.bullets && s.bullets.length) {\n        s.bullets.removeClass(s.params.bulletActiveClass);\n    }\n\n    // Buttons\n    if (s.params.prevButton) $(s.params.prevButton).removeClass(s.params.buttonDisabledClass);\n    if (s.params.nextButton) $(s.params.nextButton).removeClass(s.params.buttonDisabledClass);\n\n    // Scrollbar\n    if (s.params.scrollbar && s.scrollbar) {\n        if (s.scrollbar.track && s.scrollbar.track.length) s.scrollbar.track.removeAttr('style');\n        if (s.scrollbar.drag && s.scrollbar.drag.length) s.scrollbar.drag.removeAttr('style');\n    }\n};\n\n// Destroy\ns.destroy = function (deleteInstance, cleanupStyles) {\n    // Detach evebts\n    s.detachEvents();\n    // Stop autoplay\n    s.stopAutoplay();\n    // Disable draggable\n    if (s.params.scrollbar && s.scrollbar) {\n        if (s.params.scrollbarDraggable) {\n            s.scrollbar.disableDraggable();\n        }\n    }\n    // Destroy loop\n    if (s.params.loop) {\n        s.destroyLoop();\n    }\n    // Cleanup styles\n    if (cleanupStyles) {\n        s.cleanupStyles();\n    }\n    // Disconnect observer\n    s.disconnectObservers();\n    // Disable keyboard/mousewheel\n    if (s.params.keyboardControl) {\n        if (s.disableKeyboardControl) s.disableKeyboardControl();\n    }\n    if (s.params.mousewheelControl) {\n        if (s.disableMousewheelControl) s.disableMousewheelControl();\n    }\n    // Disable a11y\n    if (s.params.a11y && s.a11y) s.a11y.destroy();\n    // Destroy callback\n    s.emit('onDestroy');\n    // Delete instance\n    if (deleteInstance !== false) s = null;\n};\n\ns.init();\n"
  },
  {
    "path": "app_frontend/static/plugin/Swiper-3.3.1/src/js/keyboard.js",
    "content": "/*=========================\n  Keyboard Control\n  ===========================*/\nfunction handleKeyboard(e) {\n    if (e.originalEvent) e = e.originalEvent; //jquery fix\n    var kc = e.keyCode || e.charCode;\n    // Directions locks\n    if (!s.params.allowSwipeToNext && (s.isHorizontal() && kc === 39 || !s.isHorizontal() && kc === 40)) {\n        return false;\n    }\n    if (!s.params.allowSwipeToPrev && (s.isHorizontal() && kc === 37 || !s.isHorizontal() && kc === 38)) {\n        return false;\n    }\n    if (e.shiftKey || e.altKey || e.ctrlKey || e.metaKey) {\n        return;\n    }\n    if (document.activeElement && document.activeElement.nodeName && (document.activeElement.nodeName.toLowerCase() === 'input' || document.activeElement.nodeName.toLowerCase() === 'textarea')) {\n        return;\n    }\n    if (kc === 37 || kc === 39 || kc === 38 || kc === 40) {\n        var inView = false;\n        //Check that swiper should be inside of visible area of window\n        if (s.container.parents('.swiper-slide').length > 0 && s.container.parents('.swiper-slide-active').length === 0) {\n            return;\n        }\n        var windowScroll = {\n            left: window.pageXOffset,\n            top: window.pageYOffset\n        };\n        var windowWidth = window.innerWidth;\n        var windowHeight = window.innerHeight;\n        var swiperOffset = s.container.offset();\n        if (s.rtl) swiperOffset.left = swiperOffset.left - s.container[0].scrollLeft;\n        var swiperCoord = [\n            [swiperOffset.left, swiperOffset.top],\n            [swiperOffset.left + s.width, swiperOffset.top],\n            [swiperOffset.left, swiperOffset.top + s.height],\n            [swiperOffset.left + s.width, swiperOffset.top + s.height]\n        ];\n        for (var i = 0; i < swiperCoord.length; i++) {\n            var point = swiperCoord[i];\n            if (\n                point[0] >= windowScroll.left && point[0] <= windowScroll.left + windowWidth &&\n                point[1] >= windowScroll.top && point[1] <= windowScroll.top + windowHeight\n            ) {\n                inView = true;\n            }\n\n        }\n        if (!inView) return;\n    }\n    if (s.isHorizontal()) {\n        if (kc === 37 || kc === 39) {\n            if (e.preventDefault) e.preventDefault();\n            else e.returnValue = false;\n        }\n        if ((kc === 39 && !s.rtl) || (kc === 37 && s.rtl)) s.slideNext();\n        if ((kc === 37 && !s.rtl) || (kc === 39 && s.rtl)) s.slidePrev();\n    }\n    else {\n        if (kc === 38 || kc === 40) {\n            if (e.preventDefault) e.preventDefault();\n            else e.returnValue = false;\n        }\n        if (kc === 40) s.slideNext();\n        if (kc === 38) s.slidePrev();\n    }\n}\ns.disableKeyboardControl = function () {\n    s.params.keyboardControl = false;\n    $(document).off('keydown', handleKeyboard);\n};\ns.enableKeyboardControl = function () {\n    s.params.keyboardControl = true;\n    $(document).on('keydown', handleKeyboard);\n};\n"
  },
  {
    "path": "app_frontend/static/plugin/Swiper-3.3.1/src/js/lazy-load.js",
    "content": "/*=========================\n  Images Lazy Loading\n  ===========================*/\ns.lazy = {\n    initialImageLoaded: false,\n    loadImageInSlide: function (index, loadInDuplicate) {\n        if (typeof index === 'undefined') return;\n        if (typeof loadInDuplicate === 'undefined') loadInDuplicate = true;\n        if (s.slides.length === 0) return;\n\n        var slide = s.slides.eq(index);\n        var img = slide.find('.swiper-lazy:not(.swiper-lazy-loaded):not(.swiper-lazy-loading)');\n        if (slide.hasClass('swiper-lazy') && !slide.hasClass('swiper-lazy-loaded') && !slide.hasClass('swiper-lazy-loading')) {\n            img = img.add(slide[0]);\n        }\n        if (img.length === 0) return;\n\n        img.each(function () {\n            var _img = $(this);\n            _img.addClass('swiper-lazy-loading');\n            var background = _img.attr('data-background');\n            var src = _img.attr('data-src'),\n                srcset = _img.attr('data-srcset');\n            s.loadImage(_img[0], (src || background), srcset, false, function () {\n                if (background) {\n                    _img.css('background-image', 'url(\"' + background + '\")');\n                    _img.removeAttr('data-background');\n                }\n                else {\n                    if (srcset) {\n                        _img.attr('srcset', srcset);\n                        _img.removeAttr('data-srcset');\n                    }\n                    if (src) {\n                        _img.attr('src', src);\n                        _img.removeAttr('data-src');\n                    }\n\n                }\n\n                _img.addClass('swiper-lazy-loaded').removeClass('swiper-lazy-loading');\n                slide.find('.swiper-lazy-preloader, .preloader').remove();\n                if (s.params.loop && loadInDuplicate) {\n                    var slideOriginalIndex = slide.attr('data-swiper-slide-index');\n                    if (slide.hasClass(s.params.slideDuplicateClass)) {\n                        var originalSlide = s.wrapper.children('[data-swiper-slide-index=\"' + slideOriginalIndex + '\"]:not(.' + s.params.slideDuplicateClass + ')');\n                        s.lazy.loadImageInSlide(originalSlide.index(), false);\n                    }\n                    else {\n                        var duplicatedSlide = s.wrapper.children('.' + s.params.slideDuplicateClass + '[data-swiper-slide-index=\"' + slideOriginalIndex + '\"]');\n                        s.lazy.loadImageInSlide(duplicatedSlide.index(), false);\n                    }\n                }\n                s.emit('onLazyImageReady', s, slide[0], _img[0]);\n            });\n\n            s.emit('onLazyImageLoad', s, slide[0], _img[0]);\n        });\n\n    },\n    load: function () {\n        var i;\n        if (s.params.watchSlidesVisibility) {\n            s.wrapper.children('.' + s.params.slideVisibleClass).each(function () {\n                s.lazy.loadImageInSlide($(this).index());\n            });\n        }\n        else {\n            if (s.params.slidesPerView > 1) {\n                for (i = s.activeIndex; i < s.activeIndex + s.params.slidesPerView ; i++) {\n                    if (s.slides[i]) s.lazy.loadImageInSlide(i);\n                }\n            }\n            else {\n                s.lazy.loadImageInSlide(s.activeIndex);\n            }\n        }\n        if (s.params.lazyLoadingInPrevNext) {\n            if (s.params.slidesPerView > 1 || (s.params.lazyLoadingInPrevNextAmount && s.params.lazyLoadingInPrevNextAmount > 1)) {\n                var amount = s.params.lazyLoadingInPrevNextAmount;\n                var spv = s.params.slidesPerView;\n                var maxIndex = Math.min(s.activeIndex + spv + Math.max(amount, spv), s.slides.length);\n                var minIndex = Math.max(s.activeIndex - Math.max(spv, amount), 0);\n                // Next Slides\n                for (i = s.activeIndex + s.params.slidesPerView; i < maxIndex; i++) {\n                    if (s.slides[i]) s.lazy.loadImageInSlide(i);\n                }\n                // Prev Slides\n                for (i = minIndex; i < s.activeIndex ; i++) {\n                    if (s.slides[i]) s.lazy.loadImageInSlide(i);\n                }\n            }\n            else {\n                var nextSlide = s.wrapper.children('.' + s.params.slideNextClass);\n                if (nextSlide.length > 0) s.lazy.loadImageInSlide(nextSlide.index());\n\n                var prevSlide = s.wrapper.children('.' + s.params.slidePrevClass);\n                if (prevSlide.length > 0) s.lazy.loadImageInSlide(prevSlide.index());\n            }\n        }\n    },\n    onTransitionStart: function () {\n        if (s.params.lazyLoading) {\n            if (s.params.lazyLoadingOnTransitionStart || (!s.params.lazyLoadingOnTransitionStart && !s.lazy.initialImageLoaded)) {\n                s.lazy.load();\n            }\n        }\n    },\n    onTransitionEnd: function () {\n        if (s.params.lazyLoading && !s.params.lazyLoadingOnTransitionStart) {\n            s.lazy.load();\n        }\n    }\n};\n"
  },
  {
    "path": "app_frontend/static/plugin/Swiper-3.3.1/src/js/mousewheel.js",
    "content": "/*=========================\n  Mousewheel Control\n  ===========================*/\ns.mousewheel = {\n    event: false,\n    lastScrollTime: (new window.Date()).getTime()\n};\nif (s.params.mousewheelControl) {\n    try {\n        new window.WheelEvent('wheel');\n        s.mousewheel.event = 'wheel';\n    } catch (e) {\n        if (window.WheelEvent || (s.container[0] && 'wheel' in s.container[0])) {\n            s.mousewheel.event = 'wheel';\n        }\n    }\n    if (!s.mousewheel.event && window.WheelEvent) {\n\n    }\n    if (!s.mousewheel.event && document.onmousewheel !== undefined) {\n        s.mousewheel.event = 'mousewheel';\n    }\n    if (!s.mousewheel.event) {\n        s.mousewheel.event = 'DOMMouseScroll';\n    }\n}\nfunction handleMousewheel(e) {\n    if (e.originalEvent) e = e.originalEvent; //jquery fix\n    var we = s.mousewheel.event;\n    var delta = 0;\n    var rtlFactor = s.rtl ? -1 : 1;\n\n    //WebKits\n    if (we === 'mousewheel') {\n        if (s.params.mousewheelForceToAxis) {\n            if (s.isHorizontal()) {\n                if (Math.abs(e.wheelDeltaX) > Math.abs(e.wheelDeltaY)) delta = e.wheelDeltaX * rtlFactor;\n                else return;\n            }\n            else {\n                if (Math.abs(e.wheelDeltaY) > Math.abs(e.wheelDeltaX)) delta = e.wheelDeltaY;\n                else return;\n            }\n        }\n        else {\n            delta = Math.abs(e.wheelDeltaX) > Math.abs(e.wheelDeltaY) ? - e.wheelDeltaX * rtlFactor : - e.wheelDeltaY;\n        }\n    }\n    //Old FireFox\n    else if (we === 'DOMMouseScroll') delta = -e.detail;\n    //New FireFox\n    else if (we === 'wheel') {\n        if (s.params.mousewheelForceToAxis) {\n            if (s.isHorizontal()) {\n                if (Math.abs(e.deltaX) > Math.abs(e.deltaY)) delta = -e.deltaX * rtlFactor;\n                else return;\n            }\n            else {\n                if (Math.abs(e.deltaY) > Math.abs(e.deltaX)) delta = -e.deltaY;\n                else return;\n            }\n        }\n        else {\n            delta = Math.abs(e.deltaX) > Math.abs(e.deltaY) ? - e.deltaX * rtlFactor : - e.deltaY;\n        }\n    }\n    if (delta === 0) return;\n\n    if (s.params.mousewheelInvert) delta = -delta;\n\n    if (!s.params.freeMode) {\n        if ((new window.Date()).getTime() - s.mousewheel.lastScrollTime > 60) {\n            if (delta < 0) {\n                if ((!s.isEnd || s.params.loop) && !s.animating) s.slideNext();\n                else if (s.params.mousewheelReleaseOnEdges) return true;\n            }\n            else {\n                if ((!s.isBeginning || s.params.loop) && !s.animating) s.slidePrev();\n                else if (s.params.mousewheelReleaseOnEdges) return true;\n            }\n        }\n        s.mousewheel.lastScrollTime = (new window.Date()).getTime();\n\n    }\n    else {\n        //Freemode or scrollContainer:\n        var position = s.getWrapperTranslate() + delta * s.params.mousewheelSensitivity;\n        var wasBeginning = s.isBeginning,\n            wasEnd = s.isEnd;\n\n        if (position >= s.minTranslate()) position = s.minTranslate();\n        if (position <= s.maxTranslate()) position = s.maxTranslate();\n\n        s.setWrapperTransition(0);\n        s.setWrapperTranslate(position);\n        s.updateProgress();\n        s.updateActiveIndex();\n\n        if (!wasBeginning && s.isBeginning || !wasEnd && s.isEnd) {\n            s.updateClasses();\n        }\n\n        if (s.params.freeModeSticky) {\n            clearTimeout(s.mousewheel.timeout);\n            s.mousewheel.timeout = setTimeout(function () {\n                s.slideReset();\n            }, 300);\n        }\n        else {\n            if (s.params.lazyLoading && s.lazy) {\n                s.lazy.load();\n            }\n        }\n\n        // Return page scroll on edge positions\n        if (position === 0 || position === s.maxTranslate()) return;\n    }\n    if (s.params.autoplay) s.stopAutoplay();\n\n    if (e.preventDefault) e.preventDefault();\n    else e.returnValue = false;\n    return false;\n}\ns.disableMousewheelControl = function () {\n    if (!s.mousewheel.event) return false;\n    s.container.off(s.mousewheel.event, handleMousewheel);\n    return true;\n};\n\ns.enableMousewheelControl = function () {\n    if (!s.mousewheel.event) return false;\n    s.container.on(s.mousewheel.event, handleMousewheel);\n    return true;\n};\n"
  },
  {
    "path": "app_frontend/static/plugin/Swiper-3.3.1/src/js/parallax.js",
    "content": "/*=========================\n  Parallax\n  ===========================*/\nfunction setParallaxTransform(el, progress) {\n    el = $(el);\n    var p, pX, pY;\n    var rtlFactor = s.rtl ? -1 : 1;\n\n    p = el.attr('data-swiper-parallax') || '0';\n    pX = el.attr('data-swiper-parallax-x');\n    pY = el.attr('data-swiper-parallax-y');\n    if (pX || pY) {\n        pX = pX || '0';\n        pY = pY || '0';\n    }\n    else {\n        if (s.isHorizontal()) {\n            pX = p;\n            pY = '0';\n        }\n        else {\n            pY = p;\n            pX = '0';\n        }\n    }\n\n    if ((pX).indexOf('%') >= 0) {\n        pX = parseInt(pX, 10) * progress * rtlFactor + '%';\n    }\n    else {\n        pX = pX * progress * rtlFactor + 'px' ;\n    }\n    if ((pY).indexOf('%') >= 0) {\n        pY = parseInt(pY, 10) * progress + '%';\n    }\n    else {\n        pY = pY * progress + 'px' ;\n    }\n\n    el.transform('translate3d(' + pX + ', ' + pY + ',0px)');\n}\ns.parallax = {\n    setTranslate: function () {\n        s.container.children('[data-swiper-parallax], [data-swiper-parallax-x], [data-swiper-parallax-y]').each(function(){\n            setParallaxTransform(this, s.progress);\n\n        });\n        s.slides.each(function () {\n            var slide = $(this);\n            slide.find('[data-swiper-parallax], [data-swiper-parallax-x], [data-swiper-parallax-y]').each(function () {\n                var progress = Math.min(Math.max(slide[0].progress, -1), 1);\n                setParallaxTransform(this, progress);\n            });\n        });\n    },\n    setTransition: function (duration) {\n        if (typeof duration === 'undefined') duration = s.params.speed;\n        s.container.find('[data-swiper-parallax], [data-swiper-parallax-x], [data-swiper-parallax-y]').each(function(){\n            var el = $(this);\n            var parallaxDuration = parseInt(el.attr('data-swiper-parallax-duration'), 10) || duration;\n            if (duration === 0) parallaxDuration = 0;\n            el.transition(parallaxDuration);\n        });\n    }\n};\n"
  },
  {
    "path": "app_frontend/static/plugin/Swiper-3.3.1/src/js/plugins.js",
    "content": "/*=========================\n  Plugins API. Collect all and init all plugins\n  ===========================*/\ns._plugins = [];\nfor (var plugin in s.plugins) {\n    var p = s.plugins[plugin](s, s.params[plugin]);\n    if (p) s._plugins.push(p);\n}\n// Method to call all plugins event/method\ns.callPlugins = function (eventName) {\n    for (var i = 0; i < s._plugins.length; i++) {\n        if (eventName in s._plugins[i]) {\n            s._plugins[i][eventName](arguments[1], arguments[2], arguments[3], arguments[4], arguments[5]);\n        }\n    }\n};"
  },
  {
    "path": "app_frontend/static/plugin/Swiper-3.3.1/src/js/scrollbar.js",
    "content": "/*=========================\n  Scrollbar\n  ===========================*/\ns.scrollbar = {\n    isTouched: false,\n    setDragPosition: function (e) {\n        var sb = s.scrollbar;\n        var x = 0, y = 0;\n        var translate;\n        var pointerPosition = s.isHorizontal() ?\n            ((e.type === 'touchstart' || e.type === 'touchmove') ? e.targetTouches[0].pageX : e.pageX || e.clientX) :\n            ((e.type === 'touchstart' || e.type === 'touchmove') ? e.targetTouches[0].pageY : e.pageY || e.clientY) ;\n        var position = (pointerPosition) - sb.track.offset()[s.isHorizontal() ? 'left' : 'top'] - sb.dragSize / 2;\n        var positionMin = -s.minTranslate() * sb.moveDivider;\n        var positionMax = -s.maxTranslate() * sb.moveDivider;\n        if (position < positionMin) {\n            position = positionMin;\n        }\n        else if (position > positionMax) {\n            position = positionMax;\n        }\n        position = -position / sb.moveDivider;\n        s.updateProgress(position);\n        s.setWrapperTranslate(position, true);\n    },\n    dragStart: function (e) {\n        var sb = s.scrollbar;\n        sb.isTouched = true;\n        e.preventDefault();\n        e.stopPropagation();\n\n        sb.setDragPosition(e);\n        clearTimeout(sb.dragTimeout);\n\n        sb.track.transition(0);\n        if (s.params.scrollbarHide) {\n            sb.track.css('opacity', 1);\n        }\n        s.wrapper.transition(100);\n        sb.drag.transition(100);\n        s.emit('onScrollbarDragStart', s);\n    },\n    dragMove: function (e) {\n        var sb = s.scrollbar;\n        if (!sb.isTouched) return;\n        if (e.preventDefault) e.preventDefault();\n        else e.returnValue = false;\n        sb.setDragPosition(e);\n        s.wrapper.transition(0);\n        sb.track.transition(0);\n        sb.drag.transition(0);\n        s.emit('onScrollbarDragMove', s);\n    },\n    dragEnd: function (e) {\n        var sb = s.scrollbar;\n        if (!sb.isTouched) return;\n        sb.isTouched = false;\n        if (s.params.scrollbarHide) {\n            clearTimeout(sb.dragTimeout);\n            sb.dragTimeout = setTimeout(function () {\n                sb.track.css('opacity', 0);\n                sb.track.transition(400);\n            }, 1000);\n\n        }\n        s.emit('onScrollbarDragEnd', s);\n        if (s.params.scrollbarSnapOnRelease) {\n            s.slideReset();\n        }\n    },\n    enableDraggable: function () {\n        var sb = s.scrollbar;\n        var target = s.support.touch ? sb.track : document;\n        $(sb.track).on(s.touchEvents.start, sb.dragStart);\n        $(target).on(s.touchEvents.move, sb.dragMove);\n        $(target).on(s.touchEvents.end, sb.dragEnd);\n    },\n    disableDraggable: function () {\n        var sb = s.scrollbar;\n        var target = s.support.touch ? sb.track : document;\n        $(sb.track).off(s.touchEvents.start, sb.dragStart);\n        $(target).off(s.touchEvents.move, sb.dragMove);\n        $(target).off(s.touchEvents.end, sb.dragEnd);\n    },\n    set: function () {\n        if (!s.params.scrollbar) return;\n        var sb = s.scrollbar;\n        sb.track = $(s.params.scrollbar);\n        if (s.params.uniqueNavElements && typeof s.params.scrollbar === 'string' && sb.track.length > 1 && s.container.find(s.params.scrollbar).length === 1) {\n            sb.track = s.container.find(s.params.scrollbar);\n        }\n        sb.drag = sb.track.find('.swiper-scrollbar-drag');\n        if (sb.drag.length === 0) {\n            sb.drag = $('<div class=\"swiper-scrollbar-drag\"></div>');\n            sb.track.append(sb.drag);\n        }\n        sb.drag[0].style.width = '';\n        sb.drag[0].style.height = '';\n        sb.trackSize = s.isHorizontal() ? sb.track[0].offsetWidth : sb.track[0].offsetHeight;\n\n        sb.divider = s.size / s.virtualSize;\n        sb.moveDivider = sb.divider * (sb.trackSize / s.size);\n        sb.dragSize = sb.trackSize * sb.divider;\n\n        if (s.isHorizontal()) {\n            sb.drag[0].style.width = sb.dragSize + 'px';\n        }\n        else {\n            sb.drag[0].style.height = sb.dragSize + 'px';\n        }\n\n        if (sb.divider >= 1) {\n            sb.track[0].style.display = 'none';\n        }\n        else {\n            sb.track[0].style.display = '';\n        }\n        if (s.params.scrollbarHide) {\n            sb.track[0].style.opacity = 0;\n        }\n    },\n    setTranslate: function () {\n        if (!s.params.scrollbar) return;\n        var diff;\n        var sb = s.scrollbar;\n        var translate = s.translate || 0;\n        var newPos;\n\n        var newSize = sb.dragSize;\n        newPos = (sb.trackSize - sb.dragSize) * s.progress;\n        if (s.rtl && s.isHorizontal()) {\n            newPos = -newPos;\n            if (newPos > 0) {\n                newSize = sb.dragSize - newPos;\n                newPos = 0;\n            }\n            else if (-newPos + sb.dragSize > sb.trackSize) {\n                newSize = sb.trackSize + newPos;\n            }\n        }\n        else {\n            if (newPos < 0) {\n                newSize = sb.dragSize + newPos;\n                newPos = 0;\n            }\n            else if (newPos + sb.dragSize > sb.trackSize) {\n                newSize = sb.trackSize - newPos;\n            }\n        }\n        if (s.isHorizontal()) {\n            if (s.support.transforms3d) {\n                sb.drag.transform('translate3d(' + (newPos) + 'px, 0, 0)');\n            }\n            else {\n                sb.drag.transform('translateX(' + (newPos) + 'px)');\n            }\n            sb.drag[0].style.width = newSize + 'px';\n        }\n        else {\n            if (s.support.transforms3d) {\n                sb.drag.transform('translate3d(0px, ' + (newPos) + 'px, 0)');\n            }\n            else {\n                sb.drag.transform('translateY(' + (newPos) + 'px)');\n            }\n            sb.drag[0].style.height = newSize + 'px';\n        }\n        if (s.params.scrollbarHide) {\n            clearTimeout(sb.timeout);\n            sb.track[0].style.opacity = 1;\n            sb.timeout = setTimeout(function () {\n                sb.track[0].style.opacity = 0;\n                sb.track.transition(400);\n            }, 1000);\n        }\n    },\n    setTransition: function (duration) {\n        if (!s.params.scrollbar) return;\n        s.scrollbar.drag.transition(duration);\n    }\n};"
  },
  {
    "path": "app_frontend/static/plugin/Swiper-3.3.1/src/js/swiper-intro-f7.js",
    "content": "/*===========================\nSwiper\n===========================*/\nwindow.Swiper = function (container, params) {\n    if (!(this instanceof Swiper)) return new Swiper(container, params);"
  },
  {
    "path": "app_frontend/static/plugin/Swiper-3.3.1/src/js/swiper-intro.js",
    "content": "/*===========================\nSwiper\n===========================*/\nvar Swiper = function (container, params) {\n    if (!(this instanceof Swiper)) return new Swiper(container, params);"
  },
  {
    "path": "app_frontend/static/plugin/Swiper-3.3.1/src/js/swiper-outro.js",
    "content": "\n    // Return swiper instance\n    return s;\n};\n"
  },
  {
    "path": "app_frontend/static/plugin/Swiper-3.3.1/src/js/swiper-proto.js",
    "content": "/*==================================================\n    Prototype\n====================================================*/\nSwiper.prototype = {\n    isSafari: (function () {\n        var ua = navigator.userAgent.toLowerCase();\n        return (ua.indexOf('safari') >= 0 && ua.indexOf('chrome') < 0 && ua.indexOf('android') < 0);\n    })(),\n    isUiWebView: /(iPhone|iPod|iPad).*AppleWebKit(?!.*Safari)/i.test(navigator.userAgent),\n    isArray: function (arr) {\n        return Object.prototype.toString.apply(arr) === '[object Array]';\n    },\n    /*==================================================\n    Browser\n    ====================================================*/\n    browser: {\n        ie: window.navigator.pointerEnabled || window.navigator.msPointerEnabled,\n        ieTouch: (window.navigator.msPointerEnabled && window.navigator.msMaxTouchPoints > 1) || (window.navigator.pointerEnabled && window.navigator.maxTouchPoints > 1)\n    },\n    /*==================================================\n    Devices\n    ====================================================*/\n    device: (function () {\n        var ua = navigator.userAgent;\n        var android = ua.match(/(Android);?[\\s\\/]+([\\d.]+)?/);\n        var ipad = ua.match(/(iPad).*OS\\s([\\d_]+)/);\n        var ipod = ua.match(/(iPod)(.*OS\\s([\\d_]+))?/);\n        var iphone = !ipad && ua.match(/(iPhone\\sOS)\\s([\\d_]+)/);\n        return {\n            ios: ipad || iphone || ipod,\n            android: android\n        };\n    })(),\n    /*==================================================\n    Feature Detection\n    ====================================================*/\n    support: {\n        touch : (window.Modernizr && Modernizr.touch === true) || (function () {\n            return !!(('ontouchstart' in window) || window.DocumentTouch && document instanceof DocumentTouch);\n        })(),\n\n        transforms3d : (window.Modernizr && Modernizr.csstransforms3d === true) || (function () {\n            var div = document.createElement('div').style;\n            return ('webkitPerspective' in div || 'MozPerspective' in div || 'OPerspective' in div || 'MsPerspective' in div || 'perspective' in div);\n        })(),\n\n        flexbox: (function () {\n            var div = document.createElement('div').style;\n            var styles = ('alignItems webkitAlignItems webkitBoxAlign msFlexAlign mozBoxAlign webkitFlexDirection msFlexDirection mozBoxDirection mozBoxOrient webkitBoxDirection webkitBoxOrient').split(' ');\n            for (var i = 0; i < styles.length; i++) {\n                if (styles[i] in div) return true;\n            }\n        })(),\n\n        observer: (function () {\n            return ('MutationObserver' in window || 'WebkitMutationObserver' in window);\n        })()\n    },\n    /*==================================================\n    Plugins\n    ====================================================*/\n    plugins: {}\n};\n"
  },
  {
    "path": "app_frontend/static/plugin/Swiper-3.3.1/src/js/wrap-end-umd.js",
    "content": "\treturn Swiper;\n}));"
  },
  {
    "path": "app_frontend/static/plugin/Swiper-3.3.1/src/js/wrap-end.js",
    "content": "    window.Swiper = Swiper;\n})();"
  },
  {
    "path": "app_frontend/static/plugin/Swiper-3.3.1/src/js/wrap-start-umd.js",
    "content": "(function (root, factory) {\n\t'use strict';\n\n\tif (typeof define === 'function' && define.amd) {\n\t\t// AMD. Register as an anonymous module.\n\t\tdefine(['jquery'], factory);\n\t} else if (typeof exports === 'object') {\n\t\t// Node. Does not work with strict CommonJS, but\n\t\t// only CommonJS-like environments that support module.exports,\n\t\t// like Node.\n\t\tmodule.exports = factory(require('jquery'));\n\t} else {\n\t\t// Browser globals (root is window)\n\t\troot.Swiper = factory(root.jQuery);\n\t}\n}(this, function ($) {\n\t'use strict';\n"
  },
  {
    "path": "app_frontend/static/plugin/Swiper-3.3.1/src/js/wrap-start.js",
    "content": "(function () {\n    'use strict';\n    var $;"
  },
  {
    "path": "app_frontend/static/plugin/Swiper-3.3.1/src/less/core.less",
    "content": ".swiper-container {\n    margin:0 auto;\n    position:relative;\n    overflow:hidden;\n    /* Fix of Webkit flickering */\n    z-index:1;\n}\n.swiper-container-no-flexbox {\n    .swiper-slide {\n        float: left;\n    }\n}\n.swiper-container-vertical > .swiper-wrapper{\n    -webkit-box-orient: vertical;\n    -moz-box-orient: vertical;\n    -ms-flex-direction: column;\n    -webkit-flex-direction: column;\n    flex-direction: column;\n}\n.swiper-wrapper {\n    position:relative;\n    width: 100%;\n    height: 100%;\n    z-index: 1;\n    display: -webkit-box;\n    display: -moz-box;\n    display: -ms-flexbox;\n    display: -webkit-flex;\n    display: flex;\n\n    -webkit-transition-property:-webkit-transform;\n    -moz-transition-property:-moz-transform;\n    -o-transition-property:-o-transform;\n    -ms-transition-property:-ms-transform;\n    transition-property:transform;\n    \n    -webkit-box-sizing: content-box;\n    -moz-box-sizing: content-box;\n    box-sizing: content-box;\n}\n.swiper-container-android .swiper-slide, .swiper-wrapper {\n    -webkit-transform:translate3d(0px,0,0);\n    -moz-transform:translate3d(0px,0,0);\n    -o-transform:translate(0px,0px);\n    -ms-transform:translate3d(0px,0,0);\n    transform:translate3d(0px,0,0);\n}\n.swiper-container-multirow > .swiper-wrapper {\n    -webkit-box-lines: multiple;\n    -moz-box-lines: multiple;\n    -ms-flex-wrap: wrap;\n    -webkit-flex-wrap: wrap;\n    flex-wrap: wrap;\n}\n.swiper-container-free-mode > .swiper-wrapper {\n    -webkit-transition-timing-function: ease-out;\n    -moz-transition-timing-function: ease-out;\n    -ms-transition-timing-function: ease-out;\n    -o-transition-timing-function: ease-out;\n    transition-timing-function: ease-out;\n    margin: 0 auto;\n}\n.swiper-slide {\n    -webkit-flex-shrink: 0;\n    -ms-flex: 0 0 auto;\n    flex-shrink: 0;\n    width: 100%;\n    height: 100%;\n    position: relative;\n}\n/* Auto Height */\n.swiper-container-autoheight, .swiper-container-autoheight .swiper-slide {\n    height: auto;\n}\n.swiper-container-autoheight .swiper-wrapper {\n    -webkit-box-align: start;\n    -ms-flex-align: start;\n    -webkit-align-items: flex-start;\n    align-items: flex-start;\n    -webkit-transition-property: -webkit-transform, height;\n    -moz-transition-property: -moz-transform;\n    -o-transition-property: -o-transform;\n    -ms-transition-property: -ms-transform;\n    transition-property: transform, height;\n}\n/* a11y */\n.swiper-container .swiper-notification {\n    position: absolute;\n    left: 0;\n    top: 0;\n    pointer-events: none;\n    opacity: 0;\n    z-index: -1000;\n}\n\n/* IE10 Windows Phone 8 Fixes */\n.swiper-wp8-horizontal {\n    -ms-touch-action: pan-y;\n    touch-action: pan-y;\n}\n.swiper-wp8-vertical {\n    -ms-touch-action: pan-x;\n    touch-action: pan-x;\n}"
  },
  {
    "path": "app_frontend/static/plugin/Swiper-3.3.1/src/less/effects.less",
    "content": "/* 3D Container */\n.swiper-container-3d {\n    -webkit-perspective: 1200px;\n    -moz-perspective: 1200px;\n    -o-perspective: 1200px;\n    perspective: 1200px;\n    .swiper-wrapper, .swiper-slide, .swiper-slide-shadow-left, .swiper-slide-shadow-right, .swiper-slide-shadow-top, .swiper-slide-shadow-bottom, .swiper-cube-shadow {\n        .preserve3d();\n    }\n    .swiper-slide-shadow-left, .swiper-slide-shadow-right, .swiper-slide-shadow-top, .swiper-slide-shadow-bottom {\n        position: absolute;\n        left: 0;\n        top: 0;\n        width: 100%;\n        height: 100%;\n        pointer-events: none;\n        z-index: 10;\n    }\n    .swiper-slide-shadow-left { \n        background-image: -webkit-gradient(linear, left top, right top, from(rgba(0,0,0,0.5)), to(rgba(0,0,0,0))); /* Safari 4+, Chrome */\n        background-image: -webkit-linear-gradient(right, rgba(0,0,0,0.5), rgba(0,0,0,0)); /* Chrome 10+, Safari 5.1+, iOS 5+ */\n        background-image:    -moz-linear-gradient(right, rgba(0,0,0,0.5), rgba(0,0,0,0)); /* Firefox 3.6-15 */\n        background-image:      -o-linear-gradient(right, rgba(0,0,0,0.5), rgba(0,0,0,0)); /* Opera 11.10-12.00 */\n        background-image:         linear-gradient(to left, rgba(0,0,0,0.5), rgba(0,0,0,0)); /* Firefox 16+, IE10, Opera 12.50+ */\n    }\n    .swiper-slide-shadow-right {    \n        background-image: -webkit-gradient(linear, right top, left top, from(rgba(0,0,0,0.5)), to(rgba(0,0,0,0))); /* Safari 4+, Chrome */\n        background-image: -webkit-linear-gradient(left, rgba(0,0,0,0.5), rgba(0,0,0,0)); /* Chrome 10+, Safari 5.1+, iOS 5+ */\n        background-image:    -moz-linear-gradient(left, rgba(0,0,0,0.5), rgba(0,0,0,0)); /* Firefox 3.6-15 */\n        background-image:      -o-linear-gradient(left, rgba(0,0,0,0.5), rgba(0,0,0,0)); /* Opera 11.10-12.00 */\n        background-image:         linear-gradient(to right, rgba(0,0,0,0.5), rgba(0,0,0,0)); /* Firefox 16+, IE10, Opera 12.50+ */  \n    }\n    .swiper-slide-shadow-top {  \n        background-image: -webkit-gradient(linear, left top, left bottom, from(rgba(0,0,0,0.5)), to(rgba(0,0,0,0))); /* Safari 4+, Chrome */\n        background-image: -webkit-linear-gradient(bottom, rgba(0,0,0,0.5), rgba(0,0,0,0)); /* Chrome 10+, Safari 5.1+, iOS 5+ */\n        background-image:    -moz-linear-gradient(bottom, rgba(0,0,0,0.5), rgba(0,0,0,0)); /* Firefox 3.6-15 */\n        background-image:      -o-linear-gradient(bottom, rgba(0,0,0,0.5), rgba(0,0,0,0)); /* Opera 11.10-12.00 */\n        background-image:         linear-gradient(to top, rgba(0,0,0,0.5), rgba(0,0,0,0)); /* Firefox 16+, IE10, Opera 12.50+ */\n    }\n    .swiper-slide-shadow-bottom {   \n        background-image: -webkit-gradient(linear, left bottom, left top, from(rgba(0,0,0,0.5)), to(rgba(0,0,0,0))); /* Safari 4+, Chrome */\n        background-image: -webkit-linear-gradient(top, rgba(0,0,0,0.5), rgba(0,0,0,0)); /* Chrome 10+, Safari 5.1+, iOS 5+ */\n        background-image:    -moz-linear-gradient(top, rgba(0,0,0,0.5), rgba(0,0,0,0)); /* Firefox 3.6-15 */\n        background-image:      -o-linear-gradient(top, rgba(0,0,0,0.5), rgba(0,0,0,0)); /* Opera 11.10-12.00 */\n        background-image:         linear-gradient(to bottom, rgba(0,0,0,0.5), rgba(0,0,0,0)); /* Firefox 16+, IE10, Opera 12.50+ */\n    }\n}\n/* Coverflow */\n.swiper-container-coverflow, .swiper-container-flip {\n    .swiper-wrapper {\n        /* Windows 8 IE 10 fix */\n        -ms-perspective:1200px;\n    }\n}\n/* Cube + Flip */\n.swiper-container-cube, .swiper-container-flip {\n    overflow: visible;\n    .swiper-slide {\n        pointer-events: none;\n        -webkit-backface-visibility: hidden;\n        -moz-backface-visibility: hidden;\n        -ms-backface-visibility: hidden;\n        backface-visibility: hidden;\n        z-index: 1;\n        .swiper-slide {\n            pointer-events: none;\n        }\n    }\n    .swiper-slide-active {\n        &, & .swiper-slide-active {\n            pointer-events: auto;\n        }\n    }\n    .swiper-slide-shadow-top, .swiper-slide-shadow-bottom, .swiper-slide-shadow-left, .swiper-slide-shadow-right {\n        z-index: 0;\n        -webkit-backface-visibility: hidden;\n        -moz-backface-visibility: hidden;\n        -ms-backface-visibility: hidden;\n        backface-visibility: hidden;\n    }\n}\n/* Cube */\n.swiper-container-cube {\n    .swiper-slide {\n        visibility: hidden;\n        -webkit-transform-origin: 0 0;\n        -moz-transform-origin: 0 0;\n        -ms-transform-origin: 0 0;\n        transform-origin: 0 0;\n        width: 100%;\n        height: 100%;\n    }\n    &.swiper-container-rtl .swiper-slide{\n        -webkit-transform-origin: 100% 0;\n        -moz-transform-origin: 100% 0;\n        -ms-transform-origin: 100% 0;\n        transform-origin: 100% 0;\n    }\n    .swiper-slide-active, .swiper-slide-next, .swiper-slide-prev, .swiper-slide-next + .swiper-slide {\n        pointer-events: auto;\n        visibility: visible;\n    }\n    .swiper-cube-shadow {\n        position: absolute;\n        left: 0;\n        bottom: 0px;\n        width: 100%;\n        height: 100%;\n        background: #000;\n        opacity: 0.6;\n        -webkit-filter: blur(50px);\n        filter: blur(50px);\n        z-index: 0;\n    }\n}\n/* Fade */\n.swiper-container-fade {\n    &.swiper-container-free-mode {\n        .swiper-slide {\n            -webkit-transition-timing-function: ease-out;\n            -moz-transition-timing-function: ease-out;\n            -ms-transition-timing-function: ease-out;\n            -o-transition-timing-function: ease-out;\n            transition-timing-function: ease-out;\n        }\n    }\n    .swiper-slide {\n        pointer-events: none;\n        -webkit-transition-property: opacity;\n        -moz-transition-property: opacity;\n        -o-transition-property: opacity;\n        transition-property: opacity;\n        .swiper-slide {\n            pointer-events: none;\n        }\n    }\n    .swiper-slide-active {\n        &, & .swiper-slide-active {\n            pointer-events: auto;\n        }\n    }\n}"
  },
  {
    "path": "app_frontend/static/plugin/Swiper-3.3.1/src/less/mixins.less",
    "content": ".preserve3d() {\n    -webkit-transform-style: preserve-3d;\n    -moz-transform-style: preserve-3d;\n    -ms-transform-style: preserve-3d;\n    transform-style: preserve-3d;\n}\n.encoded-svg-background(@svg) {\n    @url: `encodeURIComponent(@{svg})`;\n    background-image: url(\"data:image/svg+xml;charset=utf-8,@{url}\");\n}"
  },
  {
    "path": "app_frontend/static/plugin/Swiper-3.3.1/src/less/navigation-f7.less",
    "content": "/* Arrows */\n.swiper-button-prev, .swiper-button-next {\n    position: absolute;\n    top: 50%;\n    width: 27px;\n    height: 44px;\n    margin-top: -22px;\n    z-index: 10;\n    cursor: pointer;\n    -moz-background-size: 27px 44px;\n    -webkit-background-size: 27px 44px;\n    background-size: 27px 44px;\n    background-position: center;\n    background-repeat: no-repeat;\n    &.swiper-button-disabled {\n        opacity: 0.35;\n        cursor: auto;\n        pointer-events: none;\n    }\n}\n.swiper-button-prev, .swiper-container-rtl .swiper-button-next {\n    .encoded-svg-background(\"<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 27 44'><path d='M0,22L22,0l2.1,2.1L4.2,22l19.9,19.9L22,44L0,22L0,22L0,22z' fill='#007aff'/></svg>\");\n    left: 10px;\n    right: auto;\n}\n.swiper-button-next, .swiper-container-rtl .swiper-button-prev {\n    .encoded-svg-background(\"<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 27 44'><path d='M27,22L27,22L5,44l-2.1-2.1L22.8,22L2.9,2.1L5,0L27,22L27,22z' fill='#007aff'/></svg>\");\n    right: 10px;\n    left: auto;\n}\n\n/* Pagination Styles */\n.swiper-pagination {\n    position: absolute;\n    text-align: center;\n    -webkit-transition: 300ms;\n    -moz-transition: 300ms;\n    -o-transition: 300ms;\n    transition: 300ms;\n    -webkit-transform: translate3d(0,0,0);\n    -ms-transform: translate3d(0,0,0);\n    -o-transform: translate3d(0,0,0);\n    transform: translate3d(0,0,0);\n    z-index: 10;\n    &.swiper-pagination-hidden {\n        opacity: 0;\n    }\n}\n/* Common Styles */\n.swiper-pagination-fraction, .swiper-pagination-custom, .swiper-container-horizontal > .swiper-pagination-bullets{\n    bottom: 10px;\n    left: 0;\n    width: 100%;\n}\n/* Bullets */\n.swiper-pagination-bullet {\n    width: 8px;\n    height: 8px;\n    display: inline-block;\n    border-radius: 100%;\n    background: #000;\n    opacity: 0.2;\n    button& {\n        border: none;\n        margin: 0;\n        padding: 0;\n        box-shadow: none;\n        -moz-appearance: none;\n        -ms-appearance: none;\n        -webkit-appearance: none;\n        appearance: none;\n    }\n    .swiper-pagination-clickable & {\n        cursor: pointer;\n    }\n}\n.swiper-pagination-bullet-active {\n    opacity: 1;\n    background: #007aff;\n}\n.swiper-container-vertical {\n    > .swiper-pagination-bullets {\n        right: 10px;\n        top: 50%;\n        -webkit-transform:translate3d(0px,-50%,0);\n        -moz-transform:translate3d(0px,-50%,0);\n        -o-transform:translate(0px,-50%);\n        -ms-transform:translate3d(0px,-50%,0);\n        transform:translate3d(0px,-50%,0);\n        .swiper-pagination-bullet {\n            margin: 5px 0;\n            display: block;\n        }\n    }\n}\n.swiper-container-horizontal {\n    > .swiper-pagination-bullets {\n        .swiper-pagination-bullet {\n            margin: 0 5px;\n        }\n    }\n}\n/* Progress */\n.swiper-pagination-progress {\n    background: rgba(0,0,0,0.25);\n    position: absolute;\n    .swiper-pagination-progressbar {\n        background: #007aff;\n        position: absolute;\n        left: 0;\n        top: 0;\n        width: 100%;\n        height: 100%;\n        -webkit-transform: scale(0);\n        -ms-transform: scale(0);\n        -o-transform: scale(0);\n        transform: scale(0);\n        -webkit-transform-origin: left top;\n        -moz-transform-origin: left top;\n        -ms-transform-origin: left top;\n        -o-transform-origin: left top;\n        transform-origin: left top;\n    }\n    .swiper-container-rtl & .swiper-pagination-progressbar {\n        -webkit-transform-origin: right top;\n        -moz-transform-origin: right top;\n        -ms-transform-origin: right top;\n        -o-transform-origin: right top;\n        transform-origin: right top;\n    }\n    .swiper-container-horizontal > & {\n        width: 100%;\n        height: 4px;\n        left: 0;\n        top: 0;\n    }\n    .swiper-container-vertical > & {\n        width: 4px;\n        height: 100%;\n        left: 0;\n        top: 0;\n    }\n}"
  },
  {
    "path": "app_frontend/static/plugin/Swiper-3.3.1/src/less/navigation.less",
    "content": "/* Arrows */\n.swiper-button-prev, .swiper-button-next {\n    position: absolute;\n    top: 50%;\n    width: 27px;\n    height: 44px;\n    margin-top: -22px;\n    z-index: 10;\n    cursor: pointer;\n    -moz-background-size: 27px 44px;\n    -webkit-background-size: 27px 44px;\n    background-size: 27px 44px;\n    background-position: center;\n    background-repeat: no-repeat;\n    &.swiper-button-disabled {\n        opacity: 0.35;\n        cursor: auto;\n        pointer-events: none;\n    }\n}\n.swiper-button-prev, .swiper-container-rtl .swiper-button-next {\n    .encoded-svg-background(\"<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 27 44'><path d='M0,22L22,0l2.1,2.1L4.2,22l19.9,19.9L22,44L0,22L0,22L0,22z' fill='#007aff'/></svg>\");\n    left: 10px;\n    right: auto;\n    &.swiper-button-black {\n        .encoded-svg-background(\"<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 27 44'><path d='M0,22L22,0l2.1,2.1L4.2,22l19.9,19.9L22,44L0,22L0,22L0,22z' fill='#000000'/></svg>\");\n    }\n    &.swiper-button-white {\n        .encoded-svg-background(\"<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 27 44'><path d='M0,22L22,0l2.1,2.1L4.2,22l19.9,19.9L22,44L0,22L0,22L0,22z' fill='#ffffff'/></svg>\");\n    }\n}\n.swiper-button-next, .swiper-container-rtl .swiper-button-prev {\n    .encoded-svg-background(\"<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 27 44'><path d='M27,22L27,22L5,44l-2.1-2.1L22.8,22L2.9,2.1L5,0L27,22L27,22z' fill='#007aff'/></svg>\");\n    right: 10px;\n    left: auto;\n    &.swiper-button-black {\n        .encoded-svg-background(\"<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 27 44'><path d='M27,22L27,22L5,44l-2.1-2.1L22.8,22L2.9,2.1L5,0L27,22L27,22z' fill='#000000'/></svg>\");\n    }\n    &.swiper-button-white {\n        .encoded-svg-background(\"<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 27 44'><path d='M27,22L27,22L5,44l-2.1-2.1L22.8,22L2.9,2.1L5,0L27,22L27,22z' fill='#ffffff'/></svg>\");\n    }\n}\n/* Pagination Styles */\n.swiper-pagination {\n    position: absolute;\n    text-align: center;\n    -webkit-transition: 300ms;\n    -moz-transition: 300ms;\n    -o-transition: 300ms;\n    transition: 300ms;\n    -webkit-transform: translate3d(0,0,0);\n    -ms-transform: translate3d(0,0,0);\n    -o-transform: translate3d(0,0,0);\n    transform: translate3d(0,0,0);\n    z-index: 10;\n    &.swiper-pagination-hidden {\n        opacity: 0;\n    }\n}\n/* Common Styles */\n.swiper-pagination-fraction, .swiper-pagination-custom, .swiper-container-horizontal > .swiper-pagination-bullets{\n    bottom: 10px;\n    left: 0;\n    width: 100%;\n}\n/* Bullets */\n.swiper-pagination-bullet {\n    width: 8px;\n    height: 8px;\n    display: inline-block;\n    border-radius: 100%;\n    background: #000;\n    opacity: 0.2;\n    button& {\n        border: none;\n        margin: 0;\n        padding: 0;\n        box-shadow: none;\n        -moz-appearance: none;\n        -ms-appearance: none;\n        -webkit-appearance: none;\n        appearance: none;\n    }\n    .swiper-pagination-clickable & {\n        cursor: pointer;\n    }\n    .swiper-pagination-white & {\n        background: #fff;\n    }\n}\n.swiper-pagination-bullet-active {\n    opacity: 1;\n    background: #007aff;\n    .swiper-pagination-white & {\n        background: #fff;\n    }\n    .swiper-pagination-black & {\n        background: #000;\n    }\n}\n.swiper-container-vertical {\n    > .swiper-pagination-bullets {\n        right: 10px;\n        top: 50%;\n        -webkit-transform:translate3d(0px,-50%,0);\n        -moz-transform:translate3d(0px,-50%,0);\n        -o-transform:translate(0px,-50%);\n        -ms-transform:translate3d(0px,-50%,0);\n        transform:translate3d(0px,-50%,0);\n        .swiper-pagination-bullet {\n            margin: 5px 0;\n            display: block;\n        }\n    }\n}\n.swiper-container-horizontal {\n    > .swiper-pagination-bullets {\n        .swiper-pagination-bullet {\n            margin: 0 5px;\n        }\n    }\n}\n/* Progress */\n.swiper-pagination-progress {\n    background: rgba(0,0,0,0.25);\n    position: absolute;\n    .swiper-pagination-progressbar {\n        background: #007aff;\n        position: absolute;\n        left: 0;\n        top: 0;\n        width: 100%;\n        height: 100%;\n        -webkit-transform: scale(0);\n        -ms-transform: scale(0);\n        -o-transform: scale(0);\n        transform: scale(0);\n        -webkit-transform-origin: left top;\n        -moz-transform-origin: left top;\n        -ms-transform-origin: left top;\n        -o-transform-origin: left top;\n        transform-origin: left top;\n    }\n    .swiper-container-rtl & .swiper-pagination-progressbar {\n        -webkit-transform-origin: right top;\n        -moz-transform-origin: right top;\n        -ms-transform-origin: right top;\n        -o-transform-origin: right top;\n        transform-origin: right top;\n    }\n    .swiper-container-horizontal > & {\n        width: 100%;\n        height: 4px;\n        left: 0;\n        top: 0;\n    }\n    .swiper-container-vertical > & {\n        width: 4px;\n        height: 100%;\n        left: 0;\n        top: 0;\n    }\n    &.swiper-pagination-white {\n        background: rgba(255,255,255,0.5);\n        .swiper-pagination-progressbar {\n            background: #fff;\n        }\n    }\n    &.swiper-pagination-black {\n        .swiper-pagination-progressbar {\n            background: #000;\n        }\n    }\n}"
  },
  {
    "path": "app_frontend/static/plugin/Swiper-3.3.1/src/less/preloader-f7.less",
    "content": "/* Preloader */\n.swiper-slide .preloader {\n    width: 42px;\n    height: 42px;\n    position: absolute;\n    left: 50%;\n    top: 50%;\n    margin-left: -21px;\n    margin-top: -21px;\n    z-index: 10;\n}"
  },
  {
    "path": "app_frontend/static/plugin/Swiper-3.3.1/src/less/preloader.less",
    "content": "/* Preloader */\n.swiper-lazy-preloader {\n    width: 42px;\n    height: 42px;\n    position: absolute;\n    left: 50%;\n    top: 50%;\n    margin-left: -21px;\n    margin-top: -21px;\n    z-index: 10;\n    -webkit-transform-origin: 50%;\n    -moz-transform-origin: 50%;\n    transform-origin: 50%;\n    -webkit-animation: swiper-preloader-spin 1s steps(12, end) infinite;\n    -moz-animation: swiper-preloader-spin 1s steps(12, end) infinite;\n    animation: swiper-preloader-spin 1s steps(12, end) infinite;\n}\n.swiper-lazy-preloader:after {\n    display: block;\n    content: \"\";\n    width: 100%;\n    height: 100%;\n    .encoded-svg-background(\"<svg viewBox='0 0 120 120' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink'><defs><line id='l' x1='60' x2='60' y1='7' y2='27' stroke='#6c6c6c' stroke-width='11' stroke-linecap='round'/></defs><g><use xlink:href='#l' opacity='.27'/><use xlink:href='#l' opacity='.27' transform='rotate(30 60,60)'/><use xlink:href='#l' opacity='.27' transform='rotate(60 60,60)'/><use xlink:href='#l' opacity='.27' transform='rotate(90 60,60)'/><use xlink:href='#l' opacity='.27' transform='rotate(120 60,60)'/><use xlink:href='#l' opacity='.27' transform='rotate(150 60,60)'/><use xlink:href='#l' opacity='.37' transform='rotate(180 60,60)'/><use xlink:href='#l' opacity='.46' transform='rotate(210 60,60)'/><use xlink:href='#l' opacity='.56' transform='rotate(240 60,60)'/><use xlink:href='#l' opacity='.66' transform='rotate(270 60,60)'/><use xlink:href='#l' opacity='.75' transform='rotate(300 60,60)'/><use xlink:href='#l' opacity='.85' transform='rotate(330 60,60)'/></g></svg>\");\n    background-position: 50%;\n    -webkit-background-size: 100%;\n    background-size: 100%;\n    background-repeat: no-repeat;\n    \n}\n.swiper-lazy-preloader-white:after {\n    .encoded-svg-background(\"<svg viewBox='0 0 120 120' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink'><defs><line id='l' x1='60' x2='60' y1='7' y2='27' stroke='#fff' stroke-width='11' stroke-linecap='round'/></defs><g><use xlink:href='#l' opacity='.27'/><use xlink:href='#l' opacity='.27' transform='rotate(30 60,60)'/><use xlink:href='#l' opacity='.27' transform='rotate(60 60,60)'/><use xlink:href='#l' opacity='.27' transform='rotate(90 60,60)'/><use xlink:href='#l' opacity='.27' transform='rotate(120 60,60)'/><use xlink:href='#l' opacity='.27' transform='rotate(150 60,60)'/><use xlink:href='#l' opacity='.37' transform='rotate(180 60,60)'/><use xlink:href='#l' opacity='.46' transform='rotate(210 60,60)'/><use xlink:href='#l' opacity='.56' transform='rotate(240 60,60)'/><use xlink:href='#l' opacity='.66' transform='rotate(270 60,60)'/><use xlink:href='#l' opacity='.75' transform='rotate(300 60,60)'/><use xlink:href='#l' opacity='.85' transform='rotate(330 60,60)'/></g></svg>\");\n}\n@-webkit-keyframes swiper-preloader-spin {\n    100% {\n        -webkit-transform: rotate(360deg);\n    }\n}\n@keyframes swiper-preloader-spin {\n    100% {\n        transform: rotate(360deg);\n    }\n}"
  },
  {
    "path": "app_frontend/static/plugin/Swiper-3.3.1/src/less/scrollbar.less",
    "content": "/* Scrollbar */\n.swiper-scrollbar {\n    border-radius: 10px;\n    position: relative;\n    -ms-touch-action: none;\n    background: rgba(0,0,0,0.1);\n    .swiper-container-horizontal > & {\n        position: absolute;\n        left: 1%;\n        bottom: 3px;\n        z-index: 50;\n        height: 5px;\n        width: 98%;\n    }\n    .swiper-container-vertical > & {\n        position: absolute;\n        right: 3px;\n        top: 1%;\n        z-index: 50;\n        width: 5px;\n        height: 98%;\n    }\n}\n.swiper-scrollbar-drag {\n    height: 100%;\n    width: 100%;\n    position: relative;\n    background: rgba(0,0,0,0.5);\n    border-radius: 10px;\n    left: 0;\n    top: 0;\n}\n.swiper-scrollbar-cursor-drag {\n    cursor: move;\n}"
  },
  {
    "path": "app_frontend/static/plugin/Swiper-3.3.1/src/less/swiper.less",
    "content": "@import url('mixins.less');\n@import url('core.less');\n@import url('navigation.less');\n@import url('effects.less');\n@import url('scrollbar.less');\n@import url('preloader.less');"
  },
  {
    "path": "app_frontend/static/plugin/bootstrap-select-1.12.2/.github/ISSUE_TEMPLATE.md",
    "content": "Before posting, please see [guidelines for contributing](https://github.com/silviomoreto/bootstrap-select/blob/master/CONTRIBUTING.md). If you're submitting a bug report, see below.\n\n## Bug reports\n\nA bug is a _demonstrable problem_ that is caused by the code in the repository.\nGood bug reports are extremely helpful - thank you!\n\nGuidelines for bug reports:\n\n1. **Use the GitHub issue search.** Check if the issue has already been\n   reported.\n\n2. **Check if the issue has been fixed.** Try to reproduce it using the\n   latest `master` or development branch in the repository.\n\n3. **Provide environment details.** Provide your operating system, browser(s),\n   jQuery version, Bootstrap version, and bootstrap-select version.\n\n4. **Create an isolated and reproducible test case.** Create a [reduced test\n   case](http://css-tricks.com/6263-reduced-test-cases/).\n\n5. **Include a live example.** Use [this Plunker debugging template](http://silviomoreto.github.io/bootstrap-select/playground/) to share your isolated test cases. You can also make use of [jsFiddle](http://jsfiddle.net/) or [jsBin](http://jsbin.com/).\n\nA good bug report shouldn't leave others needing to chase you up for more\ninformation. Please try to be as detailed as possible in your report. What is\nyour environment? What steps will reproduce the issue? What browser(s) and OS\nexperience the problem? What would you expect to be the outcome? All these\ndetails will help people to fix any potential bugs.\n\nExample:\n\n> Short and descriptive example bug report title\n>\n> A summary of the issue and the browser/OS environment in which it occurs. If\n> suitable, include the steps required to reproduce the bug.\n>\n> 1. This is the first step\n> 2. This is the second step\n> 3. Further steps, etc.\n>\n> `<url>` - a link to the reduced test case\n>\n> Any other information you want to share that is relevant to the issue being\n> reported. This might include the lines of code that you have identified as\n> causing the bug, and potential solutions (and your opinions on their\n> merits).\n\n## Erase the above text and being typing. Thanks!"
  },
  {
    "path": "app_frontend/static/plugin/bootstrap-select-1.12.2/.gitignore",
    "content": "# OS or Editor folders\n.DS_Store\n.idea\n\n# Folders to ignore\nnode_modules\nbower_components\n.sass-cache\n\n# Dist zip\nbootstrap-select-*.zip\n\ndocs/site\n"
  },
  {
    "path": "app_frontend/static/plugin/bootstrap-select-1.12.2/CHANGELOG.md",
    "content": "### v1.12.2 (2017-01-30)\n\n## Bug Fixes\n* [#1563]: key word searching broken in [#1516].\n* [#1570]: properly adjust size when inside form-group-sm or form-group-lg\n* [#1590]: menu height calculated improperly when using liveSearch and input has custom height\n\n[#1563]: https://github.com/silviomoreto/bootstrap-select/issues/1563\n[#1570]: https://github.com/silviomoreto/bootstrap-select/issues/1570\n[#1590]: https://github.com/silviomoreto/bootstrap-select/issues/1590\n\n-------------------\n\n### v1.12.1 (2016-11-22)\n\n## Bug Fixes\n* [#1167], [#1366]: using a method before initializing bootstrap-select throws an error\n\n[#1167]: https://github.com/silviomoreto/bootstrap-select/issues/1167\n[#1366]: https://github.com/silviomoreto/bootstrap-select/issues/1366\n\n-------------------\n\n### v1.12.0 (2016-11-18)\n\n## Bug Fixes\n* [#1220]: unescape button title\n* [#1348]: escape HTML for optgroup label\n* [#1506]: Fix bs-placeholder usage for jQuery>=3.0\n* [#1509]: inline style Content Security Policy\n* [#1477]: using liveSearchNormalize and liveSearchStyle=\"startsWith\" simultaneously breaks search\n* [#1489] fix selectOnTab with liveSearch enabled which was broken when [#1489] was fixed\n* [#1533]: remove touchstart event listener (issues with FastClick)\n* remove destroyLi function - improve refresh() performance\n* [#1531]: add Spanish (Spain) translations\n* [#1553]: don't use replace in normalizeToBase if text is undefined (throws error otherwise)\n\n## New Features\n* [#1503]: Add windowPadding option (either a number or an array of numbers - [top, right, bottom, left])\n* [#1516]: Improve liveSearch performance (addresses [#1275])\n* [#1440]: allow HTML in placeholder title for non-multiple selects\n* [#1555]: Use default with SCSS variables\n\n[#1220]: https://github.com/silviomoreto/bootstrap-select/issues/1220\n[#1275]: https://github.com/silviomoreto/bootstrap-select/issues/1275\n[#1348]: https://github.com/silviomoreto/bootstrap-select/issues/1348\n[#1506]: https://github.com/silviomoreto/bootstrap-select/issues/1506\n[#1509]: https://github.com/silviomoreto/bootstrap-select/issues/1509\n[#1477]: https://github.com/silviomoreto/bootstrap-select/issues/1477\n[#1489]: https://github.com/silviomoreto/bootstrap-select/issues/1489\n[#1533]: https://github.com/silviomoreto/bootstrap-select/issues/1533\n[#1531]: https://github.com/silviomoreto/bootstrap-select/issues/1531\n[#1503]: https://github.com/silviomoreto/bootstrap-select/issues/1503\n[#1516]: https://github.com/silviomoreto/bootstrap-select/issues/1516\n[#1440]: https://github.com/silviomoreto/bootstrap-select/issues/1440\n[#1553]: https://github.com/silviomoreto/bootstrap-select/issues/1553\n[#1555]: https://github.com/silviomoreto/bootstrap-select/issues/1555\n\n-------------------\n\n### v1.11.2 (2016-09-09)\n\n#### Bug Fixes\n* fix sourceMappingURL in bootstrap-select.min.js\n\n-------------------\n\n### v1.11.1 (2016-09-09)\n\n#### Bug Fixes\n* [#1475]: fix Cannot read property 'apply' of null error\n* [#1484]: Change events fire twice on IE8\n* [#1489]: hide.bs.select and hidden.bs.select events not fired when \"Esc\" key pressed with live search enabled\n\n[#1475]: https://github.com/silviomoreto/bootstrap-select/issues/1475\n[#1484]: https://github.com/silviomoreto/bootstrap-select/issues/1484\n[#1489]: https://github.com/silviomoreto/bootstrap-select/issues/1489\n\n-------------------\n\n### v1.11.0 (2016-08-16)\n\n#### Bug Fixes\n* [#1291]: don't trigger change event if selecting an option that passes the limit\n* [#1284]: check if all options are already selected/deselected before triggering changed/changed.bs.select\n* [#1245], [#1310]: With livesearch, when keypress, focus to search field isn't working with some characters\n* [#1257]: fix issue with Norwegian translation\n* [#1346]: fix edge case where default values are not respected when initializing the plugin\n* [#1338]: improve support for disabled optgroups and hidden options\n* [#1373]: prevent selectAll and deselectAll from being called on standard select boxes\n* [#1363]: if hideDisabled is enabled, and all options in an optgroup are disabled, the optgroup is still visible\n* [#1422]: fix menu position inside a scrolling container\n* [#1451]: fix select with input-group-addon on both sides\n* [#1465]: changed.bs.select not firing for native mobile menu\n* [#1459]: jQuery 3 support - $.expr[':'] -> $.expr.pseudos\n\n#### New Features\n* [#1139]: add placeholder styling via `bs-placeholder` class\n* [#1290]: auto close the menu if maxOptions is set to 1 (instead of leaving open)\n* [#1127], [#1016], [#1160], [#1269]: add 'auto' option for dropdownAlignRight\n* [58ed408]: support using a string for maxOptionsText\n* [#541]: ARIA - Accessibility\n\n[#1291]: https://github.com/silviomoreto/bootstrap-select/issues/1291\n[#1284]: https://github.com/silviomoreto/bootstrap-select/issues/1284\n[#1245]: https://github.com/silviomoreto/bootstrap-select/issues/1245\n[#1257]: https://github.com/silviomoreto/bootstrap-select/issues/1257\n[#1310]: https://github.com/silviomoreto/bootstrap-select/issues/1310\n[#1346]: https://github.com/silviomoreto/bootstrap-select/issues/1346\n[#1338]: https://github.com/silviomoreto/bootstrap-select/issues/1338\n[#1373]: https://github.com/silviomoreto/bootstrap-select/issues/1373\n[#1363]: https://github.com/silviomoreto/bootstrap-select/issues/1363\n[#1422]: https://github.com/silviomoreto/bootstrap-select/issues/1422\n[#1451]: https://github.com/silviomoreto/bootstrap-select/issues/1451\n[#1465]: https://github.com/silviomoreto/bootstrap-select/issues/1465\n[#1459]: https://github.com/silviomoreto/bootstrap-select/issues/1459\n[#1139]: https://github.com/silviomoreto/bootstrap-select/issues/1139\n[#1290]: https://github.com/silviomoreto/bootstrap-select/issues/1290\n[#1127]: https://github.com/silviomoreto/bootstrap-select/issues/1127\n[#1016]: https://github.com/silviomoreto/bootstrap-select/issues/1016\n[#1160]: https://github.com/silviomoreto/bootstrap-select/issues/1160\n[#1269]: https://github.com/silviomoreto/bootstrap-select/issues/1269\n[58ed408]: https://github.com/silviomoreto/bootstrap-select/commit/58ed4085019526141be07beeada37788dfe2d316\n[#541]: https://github.com/silviomoreto/bootstrap-select/issues/541\n\n-------------------\n\n### v1.10.0 (2016-02-17)\n\n#### Bug Fixes\n* [#1268]: performance bug in clickListener\n* [#1273]: html5 validation message disappears in Chrome 47+\n* [#1295]: hide select by default (so there is no flash of unstyled content)\n\n#### New Features\n* [#950]: add `.selectpicker('toggle')` method to allow menu to be open/closed programmatically\n* [#1272]: add showTick option\n* [#1284]: selectAll and deselectAll now trigger the `changed.bs.select` event\n\nAdd Lithuanian translations.\n\n[#1268]: https://github.com/silviomoreto/bootstrap-select/issues/1268\n[#1273]: https://github.com/silviomoreto/bootstrap-select/issues/1273\n[#1295]: https://github.com/silviomoreto/bootstrap-select/issues/1295\n[#950]: https://github.com/silviomoreto/bootstrap-select/issues/950\n[#1272]: https://github.com/silviomoreto/bootstrap-select/issues/1272\n[#1284]: https://github.com/silviomoreto/bootstrap-select/issues/1284\n\n-------------------\n\n### v1.9.4 (2016-01-18)\n\n#### Bug fixes\n* [#1250]: don't destroy original select when using `destroy` method\n* [#1230]: Optgroup label missing when first option is disabled and `hideDisabled` is true\n\nAdd new translations.\n\n[#1250]: https://github.com/silviomoreto/bootstrap-select/issues/1250\n[#1230]: https://github.com/silviomoreto/bootstrap-select/issues/1230\n\n-------------------\n\n### v1.9.3 (2015-12-16)\n\n#### Bug fixes\n* Fix [#1235] - issue with selects that had `form-control` class\n\n[#1235]: https://github.com/silviomoreto/bootstrap-select/issues/1235\n"
  },
  {
    "path": "app_frontend/static/plugin/bootstrap-select-1.12.2/CONTRIBUTING.md",
    "content": "# Contributing to this project\n\nPlease take a moment to review this document in order to make the contribution\nprocess easy and effective for everyone involved.\n\nFollowing these guidelines helps to communicate that you respect the time of\nthe developers managing and developing this open source project. In return,\nthey should reciprocate that respect in addressing your issue or assessing\npatches and features.\n\n\n## Using the issue tracker\n\nThe issue tracker is the preferred channel for [bug reports](#bug-reports),\n[features requests](#feature-requests) and submitting pull requests, but please\nrespect the following restrictions:\n\n* Please **do not** use the issue tracker for personal support requests (use\n  [Stack Overflow](http://stackoverflow.com) or IRC).\n\n* Please **do not** derail or troll issues. Keep the discussion on topic and\n  respect the opinions of others.\n\n\n## Bug reports\n\nA bug is a _demonstrable problem_ that is caused by the code in the repository.\nGood bug reports are extremely helpful - thank you!\n\nGuidelines for bug reports:\n\n1. **Use the GitHub issue search.** Check if the issue has already been\n   reported.\n\n2. **Check if the issue has been fixed.** Try to reproduce it using the\n   latest `master` or development branch in the repository.\n\n3. **Provide environment details.** Provide your operating system, browser(s),\n   jQuery version, Bootstrap version, and bootstrap-select version.\n\n4. **Create an isolated and reproducible test case.** Create a [reduced test\n   case](http://css-tricks.com/6263-reduced-test-cases/).\n\n5. **Include a live example.** Use [this Plunker debugging template](http://silviomoreto.github.io/bootstrap-select/playground/) to share your isolated test cases. You can also make use of [jsFiddle](http://jsfiddle.net/) or [jsBin](http://jsbin.com/).\n\nA good bug report shouldn't leave others needing to chase you up for more\ninformation. Please try to be as detailed as possible in your report. What is\nyour environment? What steps will reproduce the issue? What browser(s) and OS\nexperience the problem? What would you expect to be the outcome? All these\ndetails will help people to fix any potential bugs.\n\nExample:\n\n> Short and descriptive example bug report title\n>\n> A summary of the issue and the browser/OS environment in which it occurs. If\n> suitable, include the steps required to reproduce the bug.\n>\n> 1. This is the first step\n> 2. This is the second step\n> 3. Further steps, etc.\n>\n> `<url>` - a link to the reduced test case\n>\n> Any other information you want to share that is relevant to the issue being\n> reported. This might include the lines of code that you have identified as\n> causing the bug, and potential solutions (and your opinions on their\n> merits).\n\n\n## Feature requests\n\nFeature requests are welcome. But take a moment to find out whether your idea\nfits with the scope and aims of the project. It's up to *you* to make a strong\ncase to convince the project's developers of the merits of this feature. Please\nprovide as much detail and context as possible.\n\n## Pull Request Guidelines\n\nYou must understand that by contributing code to this project, you are granting\nthe authors (and/or leaders) of the project a non-exclusive license to\nre-distribute your code under the current license and possibly re-license the\ncode as deemed necessary.\n\n* To instantiate a context or use it, use the variable **that** instead of\n  **_this**.\n* Please check to make sure that there aren't existing pull requests attempting\n  to address the issue mentioned. We also recommend checking for issues related\n  to the issue on the tracker, as a team member may be working on the issue in\n  a branch or fork.\n* Non-trivial changes should be discussed in an issue first\n* When modifying files, please do not edit the generated or minified files in the dist/ directory. Please edit the original files.\n* If possible, add relevant tests to cover the change\n* Write a convincing description of your PR and why we should land it\n\n## Using Grunt\n\nWe are using node and grunt to build and (in the future) test this project.\nThis means that you must setup a local development environment:\n\n1. Install `node` and `npm` using your preferred method\n2. Install the grunt CLI: `npm install -g grunt-cli`\n3. Install the project's development dependencies: `npm install`\n4. Run the various grunt tasks as needed:\n   - `grunt`: clean the distribution files and re-build them\n   - `grunt dist`: build the distribution files\n   - `grunt clean`: clean the distribution files\n   - `grunt dist-css`: build the css distribution files\n   - `grunt dist-js`: build the javascript distribution files\n   - `grunt watch`: watch for changes in the source files and build the\n     distribution files as needed\n\n"
  },
  {
    "path": "app_frontend/static/plugin/bootstrap-select-1.12.2/Gruntfile.js",
    "content": "module.exports = function (grunt) {\n\n  // From TWBS\n  RegExp.quote = function (string) {\n    return string.replace(/[-\\\\^$*+?.()|[\\]{}]/g, '\\\\$&');\n  };\n\n  // Project configuration.\n  grunt.initConfig({\n\n    // Metadata.\n    pkg: grunt.file.readJSON('package.json'),\n    banner: '/*!\\n' +\n    ' * Bootstrap-select v<%= pkg.version %> (<%= pkg.homepage %>)\\n' +\n    ' *\\n' +\n    ' * Copyright 2013-<%= grunt.template.today(\\'yyyy\\') %> bootstrap-select\\n' +\n    ' * Licensed under <%= pkg.license %> (https://github.com/silviomoreto/bootstrap-select/blob/master/LICENSE)\\n' +\n    ' */\\n',\n\n    // Task configuration.\n\n    clean: {\n      css: 'dist/css',\n      js: 'dist/js',\n      docs: 'docs/docs/dist'\n    },\n\n    jshint: {\n      options: {\n        jshintrc: 'js/.jshintrc'\n      },\n      gruntfile: {\n        options: {\n          'node': true\n        },\n        src: 'Gruntfile.js'\n      },\n      main: {\n        src: 'js/*.js'\n      },\n      i18n: {\n        src: 'js/i18n/*.js'\n      }\n    },\n\n    concat: {\n      options: {\n        stripBanners: true\n      },\n      main: {\n        src: '<%= jshint.main.src %>',\n        dest: 'dist/js/<%= pkg.name %>.js'\n      },\n      i18n: {\n        expand: true,\n        src: '<%= jshint.i18n.src %>',\n        dest: 'dist/'\n      }\n    },\n\n    umd: {\n      main: {\n        options: {\n          deps: {\n            'default': ['jQuery'],\n            amd: ['jquery'],\n            cjs: ['jquery'],\n            global: ['jQuery']\n          }\n        },\n        src: '<%= concat.main.dest %>'\n      },\n      i18n: {\n        options: {\n          deps: {\n            'default': ['jQuery'],\n            amd: ['jquery'],\n            cjs: ['jquery'],\n            global: ['jQuery']\n          }\n        },\n        src: 'dist/<%= jshint.i18n.src %>',\n        dest: '.'\n      }\n    },\n\n    uglify: {\n      options: {\n        preserveComments: function(node, comment) {\n          return /^!|@preserve|@license|@cc_on/i.test(comment.value);\n        }\n      },\n      main: {\n        src: '<%= concat.main.dest %>',\n        dest: 'dist/js/<%= pkg.name %>.min.js',\n        options: {\n          sourceMap: true,\n          sourceMapName: 'dist/js/<%= pkg.name %>.js.map'\n        }\n      },\n      i18n: {\n        expand: true,\n        src: 'dist/<%= jshint.i18n.src %>',\n        ext: '.min.js'\n      }\n    },\n\n    less: {\n      options: {\n        strictMath: true,\n        sourceMap: true,\n        outputSourceFiles: true,\n        sourceMapURL: '<%= pkg.name %>.css.map',\n        sourceMapFilename: '<%= less.css.dest %>.map'\n      },\n      css: {\n        src: 'less/bootstrap-select.less',\n        dest: 'dist/css/<%= pkg.name %>.css'\n      }\n    },\n\n    usebanner: {\n      css: {\n        options: {\n          banner: '<%= banner %>'\n        },\n        src: '<%= less.css.dest %>'\n      },\n      js: {\n        options: {\n          banner: '<%= banner %>'\n        },\n        src: [\n          '<%= concat.main.dest %>',\n          '<%= uglify.main.dest %>',\n          'dist/<%= jshint.i18n.src %>',\n        ]\n      }\n    },\n\n    copy: {\n      docs: {\n        expand: true,\n        cwd: 'dist/',\n        src: [\n          '**/*'\n        ],\n        dest: 'docs/docs/dist/'\n      }\n    },\n\n    cssmin: {\n      options: {\n        compatibility: 'ie8',\n        keepSpecialComments: '*',\n        advanced: false\n      },\n      css: {\n        src: '<%= less.css.dest %>',\n        dest: 'dist/css/<%= pkg.name %>.min.css'\n      }\n    },\n\n    csslint: {\n      options: {\n        'adjoining-classes': false,\n        'box-sizing': false,\n        'box-model': false,\n        'compatible-vendor-prefixes': false,\n        'floats': false,\n        'font-sizes': false,\n        'gradients': false,\n        'important': false,\n        'known-properties': false,\n        'outline-none': false,\n        'qualified-headings': false,\n        'regex-selectors': false,\n        'shorthand': false,\n        'text-indent': false,\n        'unique-headings': false,\n        'universal-selector': false,\n        'unqualified-attributes': false,\n        'overqualified-elements': false\n      },\n      css: {\n        src: '<%= less.css.dest %>'\n      }\n    },\n\n    version: {\n      js: {\n        options: {\n          prefix: 'Selectpicker.VERSION = \\''\n        },\n        src: [\n          'js/<%= pkg.name %>.js'\n        ],\n      },\n      cdn: {\n        options: {\n          prefix: 'ajax/libs/<%= pkg.name %>/'\n        },\n        src: [\n          'README.md',\n          'docs/docs/index.md'\n        ],\n      },\n      nuget: {\n        options: {\n          prefix: '<version>'\n        },\n        src: [\n          'nuget/bootstrap-select.nuspec'\n        ],\n      },\n      default: {\n        options: {\n          prefix: '[\\'\"]?version[\\'\"]?:[ \"\\']*'\n        },\n        src: [\n          'composer.json',\n          'docs/mkdocs.yml',\n          'package.json'\n        ],\n      }\n    },\n\n    autoprefixer: {\n      options: {\n        browsers: [\n          'Android 2.3',\n          'Android >= 4',\n          'Chrome >= 20',\n          'Firefox >= 24', // Firefox 24 is the latest ESR\n          'Explorer >= 8',\n          'iOS >= 6',\n          'Opera >= 12',\n          'Safari >= 6'\n        ]\n      },\n      css: {\n        options: {\n          map: true\n        },\n        src: '<%= less.css.dest %>'\n      }\n    },\n\n    compress: {\n      zip: {\n        options: {\n          archive: 'bootstrap-select-<%= pkg.version %>.zip',\n          mode: 'zip'\n        },\n        files: [\n          {\n            expand: true,\n            cwd: 'dist/',\n            src: '**',\n            dest: 'bootstrap-select-<%= pkg.version %>/'\n          }, {\n            src: ['bower.json', 'composer.json', 'package.json'],\n            dest: 'bootstrap-select-<%= pkg.version %>/'\n          }\n        ]\n      }\n    },\n\n    watch: {\n      gruntfile: {\n        files: '<%= jshint.gruntfile.src %>',\n        tasks: 'jshint:gruntfile'\n      },\n      js: {\n        files: ['<%= jshint.main.src %>', '<%= jshint.i18n.src %>'],\n        tasks: 'build-js'\n      },\n      less: {\n        files: 'less/*.less',\n        tasks: 'build-css'\n      }\n    }\n  });\n\n  // These plugins provide necessary tasks.\n  require('load-grunt-tasks')(grunt, {\n    scope: 'devDependencies'\n  });\n\n  // Version numbering task.\n  // to update version number, use grunt version::x.y.z\n\n  // CSS distribution\n  grunt.registerTask('build-css', ['clean:css', 'less', 'autoprefixer', 'usebanner:css', 'cssmin']);\n\n  // JS distribution\n  grunt.registerTask('build-js', ['clean:js', 'concat', 'umd', 'usebanner:js', 'uglify']);\n\n  // Copy dist to docs\n  grunt.registerTask('docs', ['clean:docs', 'copy:docs']);\n\n  // Development watch\n  grunt.registerTask('dev-watch', ['build-css', 'build-js', 'watch']);\n\n  // Full distribution\n  grunt.registerTask('dist', ['build-css', 'build-js', 'compress']);\n\n  // Default task.\n  grunt.registerTask('default', ['build-css', 'build-js']);\n\n};\n"
  },
  {
    "path": "app_frontend/static/plugin/bootstrap-select-1.12.2/LICENSE",
    "content": "The MIT License (MIT)\n\nCopyright (c) 2013-2015 bootstrap-select\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
  },
  {
    "path": "app_frontend/static/plugin/bootstrap-select-1.12.2/README.md",
    "content": "bootstrap-select\r\n================\r\n\r\n[![Latest release](https://img.shields.io/github/release/silviomoreto/bootstrap-select.svg)](https://github.com/silviomoreto/bootstrap-select/releases/latest)\r\n[![Bower](https://img.shields.io/bower/v/bootstrap-select.svg)]()\r\n[![npm](https://img.shields.io/npm/v/bootstrap-select.svg)](https://www.npmjs.com/package/bootstrap-select)\r\n[![NuGet](https://img.shields.io/nuget/v/bootstrap-select.svg)](https://www.nuget.org/packages/bootstrap-select/)\r\n[![CDNJS](https://img.shields.io/cdnjs/v/bootstrap-select.svg)](https://cdnjs.com/libraries/bootstrap-select)\r\n\r\n[![License](https://img.shields.io/badge/license-MIT-brightgreen.svg)](LICENSE)\r\n[![Dependency Status](https://david-dm.org/silviomoreto/bootstrap-select.svg)](https://david-dm.org/silviomoreto/bootstrap-select)\r\n[![devDependency Status](https://david-dm.org/silviomoreto/bootstrap-select/dev-status.svg)](https://david-dm.org/silviomoreto/bootstrap-select#info=devDependencies)\r\n\r\nBootstrap-select is a jQuery plugin that utilizes Bootstrap's dropdown.js to style and bring additional functionality to standard select elements.\r\n\r\n<a href=\"http://silviomoreto.github.io/bootstrap-select/\"><img src=\"https://cloud.githubusercontent.com/assets/2874325/18023324/42cf556c-6bb5-11e6-84ce-35be08ae57ba.gif\" alt=\"bootstrap-select demo\"></a>\r\n\r\n## Demo and Documentation\r\n\r\nYou can view a live demo and some examples of how to use the various options [here](http://silviomoreto.github.io/bootstrap-select).\r\n\r\nBootstrap-select's documentation, included in this repo in the root directory, is built with MkDocs and publicly hosted on GitHub Pages at http://silviomoreto.github.io/bootstrap-select. The documentation may also be run locally.\r\n\r\n\r\n### Running documentation locally\r\n\r\n1. If necessary, [install MkDocs](http://www.mkdocs.org/#installation).\r\n3. From the `/bootstrap-select/docs` directory, run `mkdocs serve` in the command line.\r\n4. Open `http://127.0.0.1:8000/` in your browser, and voilà.\r\n\r\nLearn more about using MkDocs by reading its [documentation](http://www.mkdocs.org/).\r\n\r\n## Authors\r\n\r\n[Silvio Moreto](https://github.com/silviomoreto),\r\n[Ana Carolina](https://github.com/anacarolinats),\r\n[caseyjhol](https://github.com/caseyjhol),\r\n[Matt Bryson](https://github.com/mattbryson), and\r\n[t0xicCode](https://github.com/t0xicCode).\r\n\r\n## Usage\r\n\r\nCreate your `<select>` with the `.selectpicker` class.\r\n```html\r\n<select class=\"selectpicker\">\r\n  <option>Mustard</option>\r\n  <option>Ketchup</option>\r\n  <option>Barbecue</option>\r\n</select>\r\n```\r\n\r\nIf you use a 1.6.3 or newer, you don't need to do anything else, as the data-api automatically picks up the `<select>`s with the `selectpicker` class.\r\n\r\nIf you use an older version, you need to add the following either at the bottom of the page (after the last selectpicker), or in a [`$(document).ready()`](http://api.jquery.com/ready/) block.\r\n```js\r\n// To style only <select>s with the selectpicker class\r\n$('.selectpicker').selectpicker();\r\n```\r\nOr\r\n```js\r\n// To style all <select>s\r\n$('select').selectpicker();\r\n```\r\n\r\nCheckout the [documentation](http://silviomoreto.github.io/bootstrap-select) for further information.\r\n\r\n## CDN\r\n\r\n**N.B.**: The CDN is updated after the release is made public, which means that there is a delay between the publishing of a release and its availability on the CDN. Check [the GitHub page](https://github.com/silviomoreto/bootstrap-select/releases) for the latest release.\r\n\r\n* [//cdnjs.cloudflare.com/ajax/libs/bootstrap-select/1.12.2/css/bootstrap-select.min.css](//cdnjs.cloudflare.com/ajax/libs/bootstrap-select/1.12.2/css/bootstrap-select.min.css)\r\n* [//cdnjs.cloudflare.com/ajax/libs/bootstrap-select/1.12.2/js/bootstrap-select.min.js](//cdnjs.cloudflare.com/ajax/libs/bootstrap-select/1.12.2/js/bootstrap-select.min.js)\r\n* //cdnjs.cloudflare.com/ajax/libs/bootstrap-select/1.12.2/js/i18n/defaults-*.min.js (The translation files)\r\n\r\n## Bugs and feature requests\r\n\r\nAnyone and everyone is welcome to contribute. **Please take a moment to\r\nreview the [guidelines for contributing](CONTRIBUTING.md)**. Make sure you're using the latest version of bootstrap-select before submitting an issue.\r\n\r\n* [Bug reports](CONTRIBUTING.md#bug-reports)\r\n* [Feature requests](CONTRIBUTING.md#feature-requests)\r\n\r\n## Copyright and license\r\n\r\nCopyright (C) 2013-2015 bootstrap-select\r\n\r\nLicensed under [the MIT license](LICENSE).\r\n\r\n## Used by\r\n\r\n* [SnapAppointments](https://snapappointments.com)\r\n* [Thermo Fisher Scientific Inc.](https://www.thermofisher.com)\r\n* [membermeister](https://www.membermeister.com)\r\n* [Solve for All](https://solveforall.com)\r\n* [EstiMATEit](http://www.123itworks.co.uk)\r\n* [Convertizer](https://convertizer.com)\r\n\r\nDoes your organization use bootstrap-select? Open an issue, and include a link and logo, and you'll be added to the list.\r\n"
  },
  {
    "path": "app_frontend/static/plugin/bootstrap-select-1.12.2/bower.json",
    "content": "{\n  \"name\": \"bootstrap-select\",\n  \"main\": [\n    \"less/bootstrap-select.less\",\n    \"dist/css/bootstrap-select.css\",\n    \"dist/js/bootstrap-select.js\"\n  ],\n  \"homepage\": \"http://silviomoreto.github.io/bootstrap-select\",\n  \"authors\": [\n    \"silviomoreto\"\n  ],\n  \"keywords\": [\n    \"form\",\n    \"bootstrap\",\n    \"select\",\n    \"replacement\"\n  ],\n  \"dependencies\": {\n    \"jquery\": \">=1.8\"\n  },\n  \"license\": \"MIT\",\n  \"ignore\": [\n    \".gitignore\",\n    \"CONTRIBUTING.md\",\n    \"Gruntfile.js\",\n    \"README.md\",\n    \"composer.json\",\n    \"package.json\",\n    \"test.html\"\n  ]\n}\n"
  },
  {
    "path": "app_frontend/static/plugin/bootstrap-select-1.12.2/composer.json",
    "content": "{\n  \"name\": \"bootstrap-select/bootstrap-select\",\n  \"description\": \"Bootstrap-select is a jQuery plugin that utilizes Bootstrap's dropdown.js to style and bring additional functionality to standard select elements.\",\n  \"keywords\": [\n    \"form\",\n    \"bootstrap\",\n    \"select\",\n    \"replacement\"\n  ],\n  \"homepage\": \"http://silviomoreto.github.io/bootstrap-select\",\n  \"version\": \"1.12.2\",\n  \"authors\": [\n    {\n      \"name\": \"Silvio Moreto\",\n      \"homepage\": \"https://github.com/silviomoreto\"\n    }\n  ],\n  \"license\": \"MIT\",\n  \"suggest\": {\n    \"components/jquery\": \">=1.8\",\n    \"twbs/bootstrap\": \"~3.0.0\"\n  }\n}\n"
  },
  {
    "path": "app_frontend/static/plugin/bootstrap-select-1.12.2/dist/css/bootstrap-select.css",
    "content": "/*!\r\n * Bootstrap-select v1.12.2 (http://silviomoreto.github.io/bootstrap-select)\r\n *\r\n * Copyright 2013-2017 bootstrap-select\r\n * Licensed under MIT (https://github.com/silviomoreto/bootstrap-select/blob/master/LICENSE)\r\n */\r\n\r\nselect.bs-select-hidden,\nselect.selectpicker {\n  display: none !important;\n}\n.bootstrap-select {\n  width: 220px \\0;\n  /*IE9 and below*/\n}\n.bootstrap-select > .dropdown-toggle {\n  width: 100%;\n  padding-right: 25px;\n  z-index: 1;\n}\n.bootstrap-select > .dropdown-toggle.bs-placeholder,\n.bootstrap-select > .dropdown-toggle.bs-placeholder:hover,\n.bootstrap-select > .dropdown-toggle.bs-placeholder:focus,\n.bootstrap-select > .dropdown-toggle.bs-placeholder:active {\n  color: #999;\n}\n.bootstrap-select > select {\n  position: absolute !important;\n  bottom: 0;\n  left: 50%;\n  display: block !important;\n  width: 0.5px !important;\n  height: 100% !important;\n  padding: 0 !important;\n  opacity: 0 !important;\n  border: none;\n}\n.bootstrap-select > select.mobile-device {\n  top: 0;\n  left: 0;\n  display: block !important;\n  width: 100% !important;\n  z-index: 2;\n}\n.has-error .bootstrap-select .dropdown-toggle,\n.error .bootstrap-select .dropdown-toggle {\n  border-color: #b94a48;\n}\n.bootstrap-select.fit-width {\n  width: auto !important;\n}\n.bootstrap-select:not([class*=\"col-\"]):not([class*=\"form-control\"]):not(.input-group-btn) {\n  width: 220px;\n}\n.bootstrap-select .dropdown-toggle:focus {\n  outline: thin dotted #333333 !important;\n  outline: 5px auto -webkit-focus-ring-color !important;\n  outline-offset: -2px;\n}\n.bootstrap-select.form-control {\n  margin-bottom: 0;\n  padding: 0;\n  border: none;\n}\n.bootstrap-select.form-control:not([class*=\"col-\"]) {\n  width: 100%;\n}\n.bootstrap-select.form-control.input-group-btn {\n  z-index: auto;\n}\n.bootstrap-select.form-control.input-group-btn:not(:first-child):not(:last-child) > .btn {\n  border-radius: 0;\n}\n.bootstrap-select.btn-group:not(.input-group-btn),\n.bootstrap-select.btn-group[class*=\"col-\"] {\n  float: none;\n  display: inline-block;\n  margin-left: 0;\n}\n.bootstrap-select.btn-group.dropdown-menu-right,\n.bootstrap-select.btn-group[class*=\"col-\"].dropdown-menu-right,\n.row .bootstrap-select.btn-group[class*=\"col-\"].dropdown-menu-right {\n  float: right;\n}\n.form-inline .bootstrap-select.btn-group,\n.form-horizontal .bootstrap-select.btn-group,\n.form-group .bootstrap-select.btn-group {\n  margin-bottom: 0;\n}\n.form-group-lg .bootstrap-select.btn-group.form-control,\n.form-group-sm .bootstrap-select.btn-group.form-control {\n  padding: 0;\n}\n.form-group-lg .bootstrap-select.btn-group.form-control .dropdown-toggle,\n.form-group-sm .bootstrap-select.btn-group.form-control .dropdown-toggle {\n  height: 100%;\n  font-size: inherit;\n  line-height: inherit;\n  border-radius: inherit;\n}\n.form-inline .bootstrap-select.btn-group .form-control {\n  width: 100%;\n}\n.bootstrap-select.btn-group.disabled,\n.bootstrap-select.btn-group > .disabled {\n  cursor: not-allowed;\n}\n.bootstrap-select.btn-group.disabled:focus,\n.bootstrap-select.btn-group > .disabled:focus {\n  outline: none !important;\n}\n.bootstrap-select.btn-group.bs-container {\n  position: absolute;\n  height: 0 !important;\n  padding: 0 !important;\n}\n.bootstrap-select.btn-group.bs-container .dropdown-menu {\n  z-index: 1060;\n}\n.bootstrap-select.btn-group .dropdown-toggle .filter-option {\n  display: inline-block;\n  overflow: hidden;\n  width: 100%;\n  text-align: left;\n}\n.bootstrap-select.btn-group .dropdown-toggle .caret {\n  position: absolute;\n  top: 50%;\n  right: 12px;\n  margin-top: -2px;\n  vertical-align: middle;\n}\n.bootstrap-select.btn-group[class*=\"col-\"] .dropdown-toggle {\n  width: 100%;\n}\n.bootstrap-select.btn-group .dropdown-menu {\n  min-width: 100%;\n  -webkit-box-sizing: border-box;\n     -moz-box-sizing: border-box;\n          box-sizing: border-box;\n}\n.bootstrap-select.btn-group .dropdown-menu.inner {\n  position: static;\n  float: none;\n  border: 0;\n  padding: 0;\n  margin: 0;\n  border-radius: 0;\n  -webkit-box-shadow: none;\n          box-shadow: none;\n}\n.bootstrap-select.btn-group .dropdown-menu li {\n  position: relative;\n}\n.bootstrap-select.btn-group .dropdown-menu li.active small {\n  color: #fff;\n}\n.bootstrap-select.btn-group .dropdown-menu li.disabled a {\n  cursor: not-allowed;\n}\n.bootstrap-select.btn-group .dropdown-menu li a {\n  cursor: pointer;\n  -webkit-user-select: none;\n     -moz-user-select: none;\n      -ms-user-select: none;\n          user-select: none;\n}\n.bootstrap-select.btn-group .dropdown-menu li a.opt {\n  position: relative;\n  padding-left: 2.25em;\n}\n.bootstrap-select.btn-group .dropdown-menu li a span.check-mark {\n  display: none;\n}\n.bootstrap-select.btn-group .dropdown-menu li a span.text {\n  display: inline-block;\n}\n.bootstrap-select.btn-group .dropdown-menu li small {\n  padding-left: 0.5em;\n}\n.bootstrap-select.btn-group .dropdown-menu .notify {\n  position: absolute;\n  bottom: 5px;\n  width: 96%;\n  margin: 0 2%;\n  min-height: 26px;\n  padding: 3px 5px;\n  background: #f5f5f5;\n  border: 1px solid #e3e3e3;\n  -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.05);\n          box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.05);\n  pointer-events: none;\n  opacity: 0.9;\n  -webkit-box-sizing: border-box;\n     -moz-box-sizing: border-box;\n          box-sizing: border-box;\n}\n.bootstrap-select.btn-group .no-results {\n  padding: 3px;\n  background: #f5f5f5;\n  margin: 0 5px;\n  white-space: nowrap;\n}\n.bootstrap-select.btn-group.fit-width .dropdown-toggle .filter-option {\n  position: static;\n}\n.bootstrap-select.btn-group.fit-width .dropdown-toggle .caret {\n  position: static;\n  top: auto;\n  margin-top: -1px;\n}\n.bootstrap-select.btn-group.show-tick .dropdown-menu li.selected a span.check-mark {\n  position: absolute;\n  display: inline-block;\n  right: 15px;\n  margin-top: 5px;\n}\n.bootstrap-select.btn-group.show-tick .dropdown-menu li a span.text {\n  margin-right: 34px;\n}\n.bootstrap-select.show-menu-arrow.open > .dropdown-toggle {\n  z-index: 1061;\n}\n.bootstrap-select.show-menu-arrow .dropdown-toggle:before {\n  content: '';\n  border-left: 7px solid transparent;\n  border-right: 7px solid transparent;\n  border-bottom: 7px solid rgba(204, 204, 204, 0.2);\n  position: absolute;\n  bottom: -4px;\n  left: 9px;\n  display: none;\n}\n.bootstrap-select.show-menu-arrow .dropdown-toggle:after {\n  content: '';\n  border-left: 6px solid transparent;\n  border-right: 6px solid transparent;\n  border-bottom: 6px solid white;\n  position: absolute;\n  bottom: -4px;\n  left: 10px;\n  display: none;\n}\n.bootstrap-select.show-menu-arrow.dropup .dropdown-toggle:before {\n  bottom: auto;\n  top: -3px;\n  border-top: 7px solid rgba(204, 204, 204, 0.2);\n  border-bottom: 0;\n}\n.bootstrap-select.show-menu-arrow.dropup .dropdown-toggle:after {\n  bottom: auto;\n  top: -3px;\n  border-top: 6px solid white;\n  border-bottom: 0;\n}\n.bootstrap-select.show-menu-arrow.pull-right .dropdown-toggle:before {\n  right: 12px;\n  left: auto;\n}\n.bootstrap-select.show-menu-arrow.pull-right .dropdown-toggle:after {\n  right: 13px;\n  left: auto;\n}\n.bootstrap-select.show-menu-arrow.open > .dropdown-toggle:before,\n.bootstrap-select.show-menu-arrow.open > .dropdown-toggle:after {\n  display: block;\n}\n.bs-searchbox,\n.bs-actionsbox,\n.bs-donebutton {\n  padding: 4px 8px;\n}\n.bs-actionsbox {\n  width: 100%;\n  -webkit-box-sizing: border-box;\n     -moz-box-sizing: border-box;\n          box-sizing: border-box;\n}\n.bs-actionsbox .btn-group button {\n  width: 50%;\n}\n.bs-donebutton {\n  float: left;\n  width: 100%;\n  -webkit-box-sizing: border-box;\n     -moz-box-sizing: border-box;\n          box-sizing: border-box;\n}\n.bs-donebutton .btn-group button {\n  width: 100%;\n}\n.bs-searchbox + .bs-actionsbox {\n  padding: 0 8px 4px;\n}\n.bs-searchbox .form-control {\n  margin-bottom: 0;\n  width: 100%;\n  float: none;\n}\n/*# sourceMappingURL=bootstrap-select.css.map */"
  },
  {
    "path": "app_frontend/static/plugin/bootstrap-select-1.12.2/dist/js/bootstrap-select.js",
    "content": "/*!\n * Bootstrap-select v1.12.2 (http://silviomoreto.github.io/bootstrap-select)\n *\n * Copyright 2013-2017 bootstrap-select\n * Licensed under MIT (https://github.com/silviomoreto/bootstrap-select/blob/master/LICENSE)\n */\n\n(function (root, factory) {\n  if (typeof define === 'function' && define.amd) {\n    // AMD. Register as an anonymous module unless amdModuleId is set\n    define([\"jquery\"], function (a0) {\n      return (factory(a0));\n    });\n  } else if (typeof module === 'object' && module.exports) {\n    // Node. Does not work with strict CommonJS, but\n    // only CommonJS-like environments that support module.exports,\n    // like Node.\n    module.exports = factory(require(\"jquery\"));\n  } else {\n    factory(root[\"jQuery\"]);\n  }\n}(this, function (jQuery) {\n\n(function ($) {\n  'use strict';\n\n  //<editor-fold desc=\"Shims\">\n  if (!String.prototype.includes) {\n    (function () {\n      'use strict'; // needed to support `apply`/`call` with `undefined`/`null`\n      var toString = {}.toString;\n      var defineProperty = (function () {\n        // IE 8 only supports `Object.defineProperty` on DOM elements\n        try {\n          var object = {};\n          var $defineProperty = Object.defineProperty;\n          var result = $defineProperty(object, object, object) && $defineProperty;\n        } catch (error) {\n        }\n        return result;\n      }());\n      var indexOf = ''.indexOf;\n      var includes = function (search) {\n        if (this == null) {\n          throw new TypeError();\n        }\n        var string = String(this);\n        if (search && toString.call(search) == '[object RegExp]') {\n          throw new TypeError();\n        }\n        var stringLength = string.length;\n        var searchString = String(search);\n        var searchLength = searchString.length;\n        var position = arguments.length > 1 ? arguments[1] : undefined;\n        // `ToInteger`\n        var pos = position ? Number(position) : 0;\n        if (pos != pos) { // better `isNaN`\n          pos = 0;\n        }\n        var start = Math.min(Math.max(pos, 0), stringLength);\n        // Avoid the `indexOf` call if no match is possible\n        if (searchLength + start > stringLength) {\n          return false;\n        }\n        return indexOf.call(string, searchString, pos) != -1;\n      };\n      if (defineProperty) {\n        defineProperty(String.prototype, 'includes', {\n          'value': includes,\n          'configurable': true,\n          'writable': true\n        });\n      } else {\n        String.prototype.includes = includes;\n      }\n    }());\n  }\n\n  if (!String.prototype.startsWith) {\n    (function () {\n      'use strict'; // needed to support `apply`/`call` with `undefined`/`null`\n      var defineProperty = (function () {\n        // IE 8 only supports `Object.defineProperty` on DOM elements\n        try {\n          var object = {};\n          var $defineProperty = Object.defineProperty;\n          var result = $defineProperty(object, object, object) && $defineProperty;\n        } catch (error) {\n        }\n        return result;\n      }());\n      var toString = {}.toString;\n      var startsWith = function (search) {\n        if (this == null) {\n          throw new TypeError();\n        }\n        var string = String(this);\n        if (search && toString.call(search) == '[object RegExp]') {\n          throw new TypeError();\n        }\n        var stringLength = string.length;\n        var searchString = String(search);\n        var searchLength = searchString.length;\n        var position = arguments.length > 1 ? arguments[1] : undefined;\n        // `ToInteger`\n        var pos = position ? Number(position) : 0;\n        if (pos != pos) { // better `isNaN`\n          pos = 0;\n        }\n        var start = Math.min(Math.max(pos, 0), stringLength);\n        // Avoid the `indexOf` call if no match is possible\n        if (searchLength + start > stringLength) {\n          return false;\n        }\n        var index = -1;\n        while (++index < searchLength) {\n          if (string.charCodeAt(start + index) != searchString.charCodeAt(index)) {\n            return false;\n          }\n        }\n        return true;\n      };\n      if (defineProperty) {\n        defineProperty(String.prototype, 'startsWith', {\n          'value': startsWith,\n          'configurable': true,\n          'writable': true\n        });\n      } else {\n        String.prototype.startsWith = startsWith;\n      }\n    }());\n  }\n\n  if (!Object.keys) {\n    Object.keys = function (\n      o, // object\n      k, // key\n      r  // result array\n      ){\n      // initialize object and result\n      r=[];\n      // iterate over object keys\n      for (k in o)\n          // fill result array with non-prototypical keys\n        r.hasOwnProperty.call(o, k) && r.push(k);\n      // return result\n      return r;\n    };\n  }\n\n  // set data-selected on select element if the value has been programmatically selected\n  // prior to initialization of bootstrap-select\n  // * consider removing or replacing an alternative method *\n  var valHooks = {\n    useDefault: false,\n    _set: $.valHooks.select.set\n  };\n\n  $.valHooks.select.set = function(elem, value) {\n    if (value && !valHooks.useDefault) $(elem).data('selected', true);\n\n    return valHooks._set.apply(this, arguments);\n  };\n\n  var changed_arguments = null;\n  $.fn.triggerNative = function (eventName) {\n    var el = this[0],\n        event;\n\n    if (el.dispatchEvent) { // for modern browsers & IE9+\n      if (typeof Event === 'function') {\n        // For modern browsers\n        event = new Event(eventName, {\n          bubbles: true\n        });\n      } else {\n        // For IE since it doesn't support Event constructor\n        event = document.createEvent('Event');\n        event.initEvent(eventName, true, false);\n      }\n\n      el.dispatchEvent(event);\n    } else if (el.fireEvent) { // for IE8\n      event = document.createEventObject();\n      event.eventType = eventName;\n      el.fireEvent('on' + eventName, event);\n    } else {\n      // fall back to jQuery.trigger\n      this.trigger(eventName);\n    }\n  };\n  //</editor-fold>\n\n  // Case insensitive contains search\n  $.expr.pseudos.icontains = function (obj, index, meta) {\n    var $obj = $(obj);\n    var haystack = ($obj.data('tokens') || $obj.text()).toString().toUpperCase();\n    return haystack.includes(meta[3].toUpperCase());\n  };\n\n  // Case insensitive begins search\n  $.expr.pseudos.ibegins = function (obj, index, meta) {\n    var $obj = $(obj);\n    var haystack = ($obj.data('tokens') || $obj.text()).toString().toUpperCase();\n    return haystack.startsWith(meta[3].toUpperCase());\n  };\n\n  // Case and accent insensitive contains search\n  $.expr.pseudos.aicontains = function (obj, index, meta) {\n    var $obj = $(obj);\n    var haystack = ($obj.data('tokens') || $obj.data('normalizedText') || $obj.text()).toString().toUpperCase();\n    return haystack.includes(meta[3].toUpperCase());\n  };\n\n  // Case and accent insensitive begins search\n  $.expr.pseudos.aibegins = function (obj, index, meta) {\n    var $obj = $(obj);\n    var haystack = ($obj.data('tokens') || $obj.data('normalizedText') || $obj.text()).toString().toUpperCase();\n    return haystack.startsWith(meta[3].toUpperCase());\n  };\n\n  /**\n   * Remove all diatrics from the given text.\n   * @access private\n   * @param {String} text\n   * @returns {String}\n   */\n  function normalizeToBase(text) {\n    var rExps = [\n      {re: /[\\xC0-\\xC6]/g, ch: \"A\"},\n      {re: /[\\xE0-\\xE6]/g, ch: \"a\"},\n      {re: /[\\xC8-\\xCB]/g, ch: \"E\"},\n      {re: /[\\xE8-\\xEB]/g, ch: \"e\"},\n      {re: /[\\xCC-\\xCF]/g, ch: \"I\"},\n      {re: /[\\xEC-\\xEF]/g, ch: \"i\"},\n      {re: /[\\xD2-\\xD6]/g, ch: \"O\"},\n      {re: /[\\xF2-\\xF6]/g, ch: \"o\"},\n      {re: /[\\xD9-\\xDC]/g, ch: \"U\"},\n      {re: /[\\xF9-\\xFC]/g, ch: \"u\"},\n      {re: /[\\xC7-\\xE7]/g, ch: \"c\"},\n      {re: /[\\xD1]/g, ch: \"N\"},\n      {re: /[\\xF1]/g, ch: \"n\"}\n    ];\n    $.each(rExps, function () {\n      text = text ? text.replace(this.re, this.ch) : '';\n    });\n    return text;\n  }\n\n\n  // List of HTML entities for escaping.\n  var escapeMap = {\n    '&': '&amp;',\n    '<': '&lt;',\n    '>': '&gt;',\n    '\"': '&quot;',\n    \"'\": '&#x27;',\n    '`': '&#x60;'\n  };\n  \n  var unescapeMap = {\n    '&amp;': '&',\n    '&lt;': '<',\n    '&gt;': '>',\n    '&quot;': '\"',\n    '&#x27;': \"'\",\n    '&#x60;': '`'\n  };\n\n  // Functions for escaping and unescaping strings to/from HTML interpolation.\n  var createEscaper = function(map) {\n    var escaper = function(match) {\n      return map[match];\n    };\n    // Regexes for identifying a key that needs to be escaped.\n    var source = '(?:' + Object.keys(map).join('|') + ')';\n    var testRegexp = RegExp(source);\n    var replaceRegexp = RegExp(source, 'g');\n    return function(string) {\n      string = string == null ? '' : '' + string;\n      return testRegexp.test(string) ? string.replace(replaceRegexp, escaper) : string;\n    };\n  };\n\n  var htmlEscape = createEscaper(escapeMap);\n  var htmlUnescape = createEscaper(unescapeMap);\n\n  var Selectpicker = function (element, options) {\n    // bootstrap-select has been initialized - revert valHooks.select.set back to its original function\n    if (!valHooks.useDefault) {\n      $.valHooks.select.set = valHooks._set;\n      valHooks.useDefault = true;\n    }\n\n    this.$element = $(element);\n    this.$newElement = null;\n    this.$button = null;\n    this.$menu = null;\n    this.$lis = null;\n    this.options = options;\n\n    // If we have no title yet, try to pull it from the html title attribute (jQuery doesnt' pick it up as it's not a\n    // data-attribute)\n    if (this.options.title === null) {\n      this.options.title = this.$element.attr('title');\n    }\n\n    // Format window padding\n    var winPad = this.options.windowPadding;\n    if (typeof winPad === 'number') {\n      this.options.windowPadding = [winPad, winPad, winPad, winPad];\n    }\n\n    //Expose public methods\n    this.val = Selectpicker.prototype.val;\n    this.render = Selectpicker.prototype.render;\n    this.refresh = Selectpicker.prototype.refresh;\n    this.setStyle = Selectpicker.prototype.setStyle;\n    this.selectAll = Selectpicker.prototype.selectAll;\n    this.deselectAll = Selectpicker.prototype.deselectAll;\n    this.destroy = Selectpicker.prototype.destroy;\n    this.remove = Selectpicker.prototype.remove;\n    this.show = Selectpicker.prototype.show;\n    this.hide = Selectpicker.prototype.hide;\n\n    this.init();\n  };\n\n  Selectpicker.VERSION = '1.12.2';\n\n  // part of this is duplicated in i18n/defaults-en_US.js. Make sure to update both.\n  Selectpicker.DEFAULTS = {\n    noneSelectedText: 'Nothing selected',\n    noneResultsText: 'No results matched {0}',\n    countSelectedText: function (numSelected, numTotal) {\n      return (numSelected == 1) ? \"{0} item selected\" : \"{0} items selected\";\n    },\n    maxOptionsText: function (numAll, numGroup) {\n      return [\n        (numAll == 1) ? 'Limit reached ({n} item max)' : 'Limit reached ({n} items max)',\n        (numGroup == 1) ? 'Group limit reached ({n} item max)' : 'Group limit reached ({n} items max)'\n      ];\n    },\n    selectAllText: 'Select All',\n    deselectAllText: 'Deselect All',\n    doneButton: false,\n    doneButtonText: 'Close',\n    multipleSeparator: ', ',\n    styleBase: 'btn',\n    style: 'btn-default',\n    size: 'auto',\n    title: null,\n    selectedTextFormat: 'values',\n    width: false,\n    container: false,\n    hideDisabled: false,\n    showSubtext: false,\n    showIcon: true,\n    showContent: true,\n    dropupAuto: true,\n    header: false,\n    liveSearch: false,\n    liveSearchPlaceholder: null,\n    liveSearchNormalize: false,\n    liveSearchStyle: 'contains',\n    actionsBox: false,\n    iconBase: 'glyphicon',\n    tickIcon: 'glyphicon-ok',\n    showTick: false,\n    template: {\n      caret: '<span class=\"caret\"></span>'\n    },\n    maxOptions: false,\n    mobile: false,\n    selectOnTab: false,\n    dropdownAlignRight: false,\n    windowPadding: 0\n  };\n\n  Selectpicker.prototype = {\n\n    constructor: Selectpicker,\n\n    init: function () {\n      var that = this,\n          id = this.$element.attr('id');\n\n      this.$element.addClass('bs-select-hidden');\n\n      // store originalIndex (key) and newIndex (value) in this.liObj for fast accessibility\n      // allows us to do this.$lis.eq(that.liObj[index]) instead of this.$lis.filter('[data-original-index=\"' + index + '\"]')\n      this.liObj = {};\n      this.multiple = this.$element.prop('multiple');\n      this.autofocus = this.$element.prop('autofocus');\n      this.$newElement = this.createView();\n      this.$element\n        .after(this.$newElement)\n        .appendTo(this.$newElement);\n      this.$button = this.$newElement.children('button');\n      this.$menu = this.$newElement.children('.dropdown-menu');\n      this.$menuInner = this.$menu.children('.inner');\n      this.$searchbox = this.$menu.find('input');\n\n      this.$element.removeClass('bs-select-hidden');\n\n      if (this.options.dropdownAlignRight === true) this.$menu.addClass('dropdown-menu-right');\n\n      if (typeof id !== 'undefined') {\n        this.$button.attr('data-id', id);\n        $('label[for=\"' + id + '\"]').click(function (e) {\n          e.preventDefault();\n          that.$button.focus();\n        });\n      }\n\n      this.checkDisabled();\n      this.clickListener();\n      if (this.options.liveSearch) this.liveSearchListener();\n      this.render();\n      this.setStyle();\n      this.setWidth();\n      if (this.options.container) this.selectPosition();\n      this.$menu.data('this', this);\n      this.$newElement.data('this', this);\n      if (this.options.mobile) this.mobile();\n\n      this.$newElement.on({\n        'hide.bs.dropdown': function (e) {\n          that.$menuInner.attr('aria-expanded', false);\n          that.$element.trigger('hide.bs.select', e);\n        },\n        'hidden.bs.dropdown': function (e) {\n          that.$element.trigger('hidden.bs.select', e);\n        },\n        'show.bs.dropdown': function (e) {\n          that.$menuInner.attr('aria-expanded', true);\n          that.$element.trigger('show.bs.select', e);\n        },\n        'shown.bs.dropdown': function (e) {\n          that.$element.trigger('shown.bs.select', e);\n        }\n      });\n\n      if (that.$element[0].hasAttribute('required')) {\n        this.$element.on('invalid', function () {\n          that.$button\n            .addClass('bs-invalid')\n            .focus();\n\n          that.$element.on({\n            'focus.bs.select': function () {\n              that.$button.focus();\n              that.$element.off('focus.bs.select');\n            },\n            'shown.bs.select': function () {\n              that.$element\n                .val(that.$element.val()) // set the value to hide the validation message in Chrome when menu is opened\n                .off('shown.bs.select');\n            },\n            'rendered.bs.select': function () {\n              // if select is no longer invalid, remove the bs-invalid class\n              if (this.validity.valid) that.$button.removeClass('bs-invalid');\n              that.$element.off('rendered.bs.select');\n            }\n          });\n        });\n      }\n\n      setTimeout(function () {\n        that.$element.trigger('loaded.bs.select');\n      });\n    },\n\n    createDropdown: function () {\n      // Options\n      // If we are multiple or showTick option is set, then add the show-tick class\n      var showTick = (this.multiple || this.options.showTick) ? ' show-tick' : '',\n          inputGroup = this.$element.parent().hasClass('input-group') ? ' input-group-btn' : '',\n          autofocus = this.autofocus ? ' autofocus' : '';\n      // Elements\n      var header = this.options.header ? '<div class=\"popover-title\"><button type=\"button\" class=\"close\" aria-hidden=\"true\">&times;</button>' + this.options.header + '</div>' : '';\n      var searchbox = this.options.liveSearch ?\n      '<div class=\"bs-searchbox\">' +\n      '<input type=\"text\" class=\"form-control\" autocomplete=\"off\"' +\n      (null === this.options.liveSearchPlaceholder ? '' : ' placeholder=\"' + htmlEscape(this.options.liveSearchPlaceholder) + '\"') + ' role=\"textbox\" aria-label=\"Search\">' +\n      '</div>'\n          : '';\n      var actionsbox = this.multiple && this.options.actionsBox ?\n      '<div class=\"bs-actionsbox\">' +\n      '<div class=\"btn-group btn-group-sm btn-block\">' +\n      '<button type=\"button\" class=\"actions-btn bs-select-all btn btn-default\">' +\n      this.options.selectAllText +\n      '</button>' +\n      '<button type=\"button\" class=\"actions-btn bs-deselect-all btn btn-default\">' +\n      this.options.deselectAllText +\n      '</button>' +\n      '</div>' +\n      '</div>'\n          : '';\n      var donebutton = this.multiple && this.options.doneButton ?\n      '<div class=\"bs-donebutton\">' +\n      '<div class=\"btn-group btn-block\">' +\n      '<button type=\"button\" class=\"btn btn-sm btn-default\">' +\n      this.options.doneButtonText +\n      '</button>' +\n      '</div>' +\n      '</div>'\n          : '';\n      var drop =\n          '<div class=\"btn-group bootstrap-select' + showTick + inputGroup + '\">' +\n          '<button type=\"button\" class=\"' + this.options.styleBase + ' dropdown-toggle\" data-toggle=\"dropdown\"' + autofocus + ' role=\"button\">' +\n          '<span class=\"filter-option pull-left\"></span>&nbsp;' +\n          '<span class=\"bs-caret\">' +\n          this.options.template.caret +\n          '</span>' +\n          '</button>' +\n          '<div class=\"dropdown-menu open\" role=\"combobox\">' +\n          header +\n          searchbox +\n          actionsbox +\n          '<ul class=\"dropdown-menu inner\" role=\"listbox\" aria-expanded=\"false\">' +\n          '</ul>' +\n          donebutton +\n          '</div>' +\n          '</div>';\n\n      return $(drop);\n    },\n\n    createView: function () {\n      var $drop = this.createDropdown(),\n          li = this.createLi();\n\n      $drop.find('ul')[0].innerHTML = li;\n      return $drop;\n    },\n\n    reloadLi: function () {\n      // rebuild\n      var li = this.createLi();\n      this.$menuInner[0].innerHTML = li;\n    },\n\n    createLi: function () {\n      var that = this,\n          _li = [],\n          optID = 0,\n          titleOption = document.createElement('option'),\n          liIndex = -1; // increment liIndex whenever a new <li> element is created to ensure liObj is correct\n\n      // Helper functions\n      /**\n       * @param content\n       * @param [index]\n       * @param [classes]\n       * @param [optgroup]\n       * @returns {string}\n       */\n      var generateLI = function (content, index, classes, optgroup) {\n        return '<li' +\n            ((typeof classes !== 'undefined' & '' !== classes) ? ' class=\"' + classes + '\"' : '') +\n            ((typeof index !== 'undefined' & null !== index) ? ' data-original-index=\"' + index + '\"' : '') +\n            ((typeof optgroup !== 'undefined' & null !== optgroup) ? 'data-optgroup=\"' + optgroup + '\"' : '') +\n            '>' + content + '</li>';\n      };\n\n      /**\n       * @param text\n       * @param [classes]\n       * @param [inline]\n       * @param [tokens]\n       * @returns {string}\n       */\n      var generateA = function (text, classes, inline, tokens) {\n        return '<a tabindex=\"0\"' +\n            (typeof classes !== 'undefined' ? ' class=\"' + classes + '\"' : '') +\n            (inline ? ' style=\"' + inline + '\"' : '') +\n            (that.options.liveSearchNormalize ? ' data-normalized-text=\"' + normalizeToBase(htmlEscape($(text).html())) + '\"' : '') +\n            (typeof tokens !== 'undefined' || tokens !== null ? ' data-tokens=\"' + tokens + '\"' : '') +\n            ' role=\"option\">' + text +\n            '<span class=\"' + that.options.iconBase + ' ' + that.options.tickIcon + ' check-mark\"></span>' +\n            '</a>';\n      };\n\n      if (this.options.title && !this.multiple) {\n        // this option doesn't create a new <li> element, but does add a new option, so liIndex is decreased\n        // since liObj is recalculated on every refresh, liIndex needs to be decreased even if the titleOption is already appended\n        liIndex--;\n\n        if (!this.$element.find('.bs-title-option').length) {\n          // Use native JS to prepend option (faster)\n          var element = this.$element[0];\n          titleOption.className = 'bs-title-option';\n          titleOption.innerHTML = this.options.title;\n          titleOption.value = '';\n          element.insertBefore(titleOption, element.firstChild);\n          // Check if selected or data-selected attribute is already set on an option. If not, select the titleOption option.\n          // the selected item may have been changed by user or programmatically before the bootstrap select plugin runs,\n          // if so, the select will have the data-selected attribute\n          var $opt = $(element.options[element.selectedIndex]);\n          if ($opt.attr('selected') === undefined && this.$element.data('selected') === undefined) {\n            titleOption.selected = true;\n          }\n        }\n      }\n\n      this.$element.find('option').each(function (index) {\n        var $this = $(this);\n\n        liIndex++;\n\n        if ($this.hasClass('bs-title-option')) return;\n\n        // Get the class and text for the option\n        var optionClass = this.className || '',\n            inline = this.style.cssText,\n            text = $this.data('content') ? $this.data('content') : $this.html(),\n            tokens = $this.data('tokens') ? $this.data('tokens') : null,\n            subtext = typeof $this.data('subtext') !== 'undefined' ? '<small class=\"text-muted\">' + $this.data('subtext') + '</small>' : '',\n            icon = typeof $this.data('icon') !== 'undefined' ? '<span class=\"' + that.options.iconBase + ' ' + $this.data('icon') + '\"></span> ' : '',\n            $parent = $this.parent(),\n            isOptgroup = $parent[0].tagName === 'OPTGROUP',\n            isOptgroupDisabled = isOptgroup && $parent[0].disabled,\n            isDisabled = this.disabled || isOptgroupDisabled;\n\n        if (icon !== '' && isDisabled) {\n          icon = '<span>' + icon + '</span>';\n        }\n\n        if (that.options.hideDisabled && (isDisabled && !isOptgroup || isOptgroupDisabled)) {\n          liIndex--;\n          return;\n        }\n\n        if (!$this.data('content')) {\n          // Prepend any icon and append any subtext to the main text.\n          text = icon + '<span class=\"text\">' + text + subtext + '</span>';\n        }\n\n        if (isOptgroup && $this.data('divider') !== true) {\n          if (that.options.hideDisabled && isDisabled) {\n            if ($parent.data('allOptionsDisabled') === undefined) {\n              var $options = $parent.children();\n              $parent.data('allOptionsDisabled', $options.filter(':disabled').length === $options.length);\n            }\n\n            if ($parent.data('allOptionsDisabled')) {\n              liIndex--;\n              return;\n            }\n          }\n\n          var optGroupClass = ' ' + $parent[0].className || '';\n\n          if ($this.index() === 0) { // Is it the first option of the optgroup?\n            optID += 1;\n\n            // Get the opt group label\n            var label = $parent[0].label,\n                labelSubtext = typeof $parent.data('subtext') !== 'undefined' ? '<small class=\"text-muted\">' + $parent.data('subtext') + '</small>' : '',\n                labelIcon = $parent.data('icon') ? '<span class=\"' + that.options.iconBase + ' ' + $parent.data('icon') + '\"></span> ' : '';\n\n            label = labelIcon + '<span class=\"text\">' + htmlEscape(label) + labelSubtext + '</span>';\n\n            if (index !== 0 && _li.length > 0) { // Is it NOT the first option of the select && are there elements in the dropdown?\n              liIndex++;\n              _li.push(generateLI('', null, 'divider', optID + 'div'));\n            }\n            liIndex++;\n            _li.push(generateLI(label, null, 'dropdown-header' + optGroupClass, optID));\n          }\n\n          if (that.options.hideDisabled && isDisabled) {\n            liIndex--;\n            return;\n          }\n\n          _li.push(generateLI(generateA(text, 'opt ' + optionClass + optGroupClass, inline, tokens), index, '', optID));\n        } else if ($this.data('divider') === true) {\n          _li.push(generateLI('', index, 'divider'));\n        } else if ($this.data('hidden') === true) {\n          _li.push(generateLI(generateA(text, optionClass, inline, tokens), index, 'hidden is-hidden'));\n        } else {\n          var showDivider = this.previousElementSibling && this.previousElementSibling.tagName === 'OPTGROUP';\n\n          // if previous element is not an optgroup and hideDisabled is true\n          if (!showDivider && that.options.hideDisabled) {\n            // get previous elements\n            var $prev = $(this).prevAll();\n\n            for (var i = 0; i < $prev.length; i++) {\n              // find the first element in the previous elements that is an optgroup\n              if ($prev[i].tagName === 'OPTGROUP') {\n                var optGroupDistance = 0;\n\n                // loop through the options in between the current option and the optgroup\n                // and check if they are hidden or disabled\n                for (var d = 0; d < i; d++) {\n                  var prevOption = $prev[d];\n                  if (prevOption.disabled || $(prevOption).data('hidden') === true) optGroupDistance++;\n                }\n\n                // if all of the options between the current option and the optgroup are hidden or disabled, show the divider\n                if (optGroupDistance === i) showDivider = true;\n\n                break;\n              }\n            }\n          }\n\n          if (showDivider) {\n            liIndex++;\n            _li.push(generateLI('', null, 'divider', optID + 'div'));\n          }\n          _li.push(generateLI(generateA(text, optionClass, inline, tokens), index));\n        }\n\n        that.liObj[index] = liIndex;\n      });\n\n      //If we are not multiple, we don't have a selected item, and we don't have a title, select the first element so something is set in the button\n      if (!this.multiple && this.$element.find('option:selected').length === 0 && !this.options.title) {\n        this.$element.find('option').eq(0).prop('selected', true).attr('selected', 'selected');\n      }\n\n      return _li.join('');\n    },\n\n    findLis: function () {\n      if (this.$lis == null) this.$lis = this.$menu.find('li');\n      return this.$lis;\n    },\n\n    /**\n     * @param [updateLi] defaults to true\n     */\n    render: function (updateLi) {\n      var that = this,\n          notDisabled;\n\n      //Update the LI to match the SELECT\n      if (updateLi !== false) {\n        this.$element.find('option').each(function (index) {\n          var $lis = that.findLis().eq(that.liObj[index]);\n\n          that.setDisabled(index, this.disabled || this.parentNode.tagName === 'OPTGROUP' && this.parentNode.disabled, $lis);\n          that.setSelected(index, this.selected, $lis);\n        });\n      }\n\n      this.togglePlaceholder();\n\n      this.tabIndex();\n\n      var selectedItems = this.$element.find('option').map(function () {\n        if (this.selected) {\n          if (that.options.hideDisabled && (this.disabled || this.parentNode.tagName === 'OPTGROUP' && this.parentNode.disabled)) return;\n\n          var $this = $(this),\n              icon = $this.data('icon') && that.options.showIcon ? '<i class=\"' + that.options.iconBase + ' ' + $this.data('icon') + '\"></i> ' : '',\n              subtext;\n\n          if (that.options.showSubtext && $this.data('subtext') && !that.multiple) {\n            subtext = ' <small class=\"text-muted\">' + $this.data('subtext') + '</small>';\n          } else {\n            subtext = '';\n          }\n          if (typeof $this.attr('title') !== 'undefined') {\n            return $this.attr('title');\n          } else if ($this.data('content') && that.options.showContent) {\n            return $this.data('content').toString();\n          } else {\n            return icon + $this.html() + subtext;\n          }\n        }\n      }).toArray();\n\n      //Fixes issue in IE10 occurring when no default option is selected and at least one option is disabled\n      //Convert all the values into a comma delimited string\n      var title = !this.multiple ? selectedItems[0] : selectedItems.join(this.options.multipleSeparator);\n\n      //If this is multi select, and the selectText type is count, the show 1 of 2 selected etc..\n      if (this.multiple && this.options.selectedTextFormat.indexOf('count') > -1) {\n        var max = this.options.selectedTextFormat.split('>');\n        if ((max.length > 1 && selectedItems.length > max[1]) || (max.length == 1 && selectedItems.length >= 2)) {\n          notDisabled = this.options.hideDisabled ? ', [disabled]' : '';\n          var totalCount = this.$element.find('option').not('[data-divider=\"true\"], [data-hidden=\"true\"]' + notDisabled).length,\n              tr8nText = (typeof this.options.countSelectedText === 'function') ? this.options.countSelectedText(selectedItems.length, totalCount) : this.options.countSelectedText;\n          title = tr8nText.replace('{0}', selectedItems.length.toString()).replace('{1}', totalCount.toString());\n        }\n      }\n\n      if (this.options.title == undefined) {\n        this.options.title = this.$element.attr('title');\n      }\n\n      if (this.options.selectedTextFormat == 'static') {\n        title = this.options.title;\n      }\n\n      //If we dont have a title, then use the default, or if nothing is set at all, use the not selected text\n      if (!title) {\n        title = typeof this.options.title !== 'undefined' ? this.options.title : this.options.noneSelectedText;\n      }\n\n      //strip all HTML tags and trim the result, then unescape any escaped tags\n      this.$button.attr('title', htmlUnescape($.trim(title.replace(/<[^>]*>?/g, ''))));\n      this.$button.children('.filter-option').html(title);\n\n      this.$element.trigger('rendered.bs.select');\n    },\n\n    /**\n     * @param [style]\n     * @param [status]\n     */\n    setStyle: function (style, status) {\n      if (this.$element.attr('class')) {\n        this.$newElement.addClass(this.$element.attr('class').replace(/selectpicker|mobile-device|bs-select-hidden|validate\\[.*\\]/gi, ''));\n      }\n\n      var buttonClass = style ? style : this.options.style;\n\n      if (status == 'add') {\n        this.$button.addClass(buttonClass);\n      } else if (status == 'remove') {\n        this.$button.removeClass(buttonClass);\n      } else {\n        this.$button.removeClass(this.options.style);\n        this.$button.addClass(buttonClass);\n      }\n    },\n\n    liHeight: function (refresh) {\n      if (!refresh && (this.options.size === false || this.sizeInfo)) return;\n\n      var newElement = document.createElement('div'),\n          menu = document.createElement('div'),\n          menuInner = document.createElement('ul'),\n          divider = document.createElement('li'),\n          li = document.createElement('li'),\n          a = document.createElement('a'),\n          text = document.createElement('span'),\n          header = this.options.header && this.$menu.find('.popover-title').length > 0 ? this.$menu.find('.popover-title')[0].cloneNode(true) : null,\n          search = this.options.liveSearch ? document.createElement('div') : null,\n          actions = this.options.actionsBox && this.multiple && this.$menu.find('.bs-actionsbox').length > 0 ? this.$menu.find('.bs-actionsbox')[0].cloneNode(true) : null,\n          doneButton = this.options.doneButton && this.multiple && this.$menu.find('.bs-donebutton').length > 0 ? this.$menu.find('.bs-donebutton')[0].cloneNode(true) : null;\n\n      text.className = 'text';\n      newElement.className = this.$menu[0].parentNode.className + ' open';\n      menu.className = 'dropdown-menu open';\n      menuInner.className = 'dropdown-menu inner';\n      divider.className = 'divider';\n\n      text.appendChild(document.createTextNode('Inner text'));\n      a.appendChild(text);\n      li.appendChild(a);\n      menuInner.appendChild(li);\n      menuInner.appendChild(divider);\n      if (header) menu.appendChild(header);\n      if (search) {\n        var input = document.createElement('input');\n        search.className = 'bs-searchbox';\n        input.className = 'form-control';\n        search.appendChild(input);\n        menu.appendChild(search);\n      }\n      if (actions) menu.appendChild(actions);\n      menu.appendChild(menuInner);\n      if (doneButton) menu.appendChild(doneButton);\n      newElement.appendChild(menu);\n\n      document.body.appendChild(newElement);\n\n      var liHeight = a.offsetHeight,\n          headerHeight = header ? header.offsetHeight : 0,\n          searchHeight = search ? search.offsetHeight : 0,\n          actionsHeight = actions ? actions.offsetHeight : 0,\n          doneButtonHeight = doneButton ? doneButton.offsetHeight : 0,\n          dividerHeight = $(divider).outerHeight(true),\n          // fall back to jQuery if getComputedStyle is not supported\n          menuStyle = typeof getComputedStyle === 'function' ? getComputedStyle(menu) : false,\n          $menu = menuStyle ? null : $(menu),\n          menuPadding = {\n            vert: parseInt(menuStyle ? menuStyle.paddingTop : $menu.css('paddingTop')) +\n                  parseInt(menuStyle ? menuStyle.paddingBottom : $menu.css('paddingBottom')) +\n                  parseInt(menuStyle ? menuStyle.borderTopWidth : $menu.css('borderTopWidth')) +\n                  parseInt(menuStyle ? menuStyle.borderBottomWidth : $menu.css('borderBottomWidth')),\n            horiz: parseInt(menuStyle ? menuStyle.paddingLeft : $menu.css('paddingLeft')) +\n                  parseInt(menuStyle ? menuStyle.paddingRight : $menu.css('paddingRight')) +\n                  parseInt(menuStyle ? menuStyle.borderLeftWidth : $menu.css('borderLeftWidth')) +\n                  parseInt(menuStyle ? menuStyle.borderRightWidth : $menu.css('borderRightWidth'))\n          },\n          menuExtras =  {\n            vert: menuPadding.vert +\n                  parseInt(menuStyle ? menuStyle.marginTop : $menu.css('marginTop')) +\n                  parseInt(menuStyle ? menuStyle.marginBottom : $menu.css('marginBottom')) + 2,\n            horiz: menuPadding.horiz +\n                  parseInt(menuStyle ? menuStyle.marginLeft : $menu.css('marginLeft')) +\n                  parseInt(menuStyle ? menuStyle.marginRight : $menu.css('marginRight')) + 2\n          }\n\n      document.body.removeChild(newElement);\n\n      this.sizeInfo = {\n        liHeight: liHeight,\n        headerHeight: headerHeight,\n        searchHeight: searchHeight,\n        actionsHeight: actionsHeight,\n        doneButtonHeight: doneButtonHeight,\n        dividerHeight: dividerHeight,\n        menuPadding: menuPadding,\n        menuExtras: menuExtras\n      };\n    },\n\n    setSize: function () {\n      this.findLis();\n      this.liHeight();\n\n      if (this.options.header) this.$menu.css('padding-top', 0);\n      if (this.options.size === false) return;\n\n      var that = this,\n          $menu = this.$menu,\n          $menuInner = this.$menuInner,\n          $window = $(window),\n          selectHeight = this.$newElement[0].offsetHeight,\n          selectWidth = this.$newElement[0].offsetWidth,\n          liHeight = this.sizeInfo['liHeight'],\n          headerHeight = this.sizeInfo['headerHeight'],\n          searchHeight = this.sizeInfo['searchHeight'],\n          actionsHeight = this.sizeInfo['actionsHeight'],\n          doneButtonHeight = this.sizeInfo['doneButtonHeight'],\n          divHeight = this.sizeInfo['dividerHeight'],\n          menuPadding = this.sizeInfo['menuPadding'],\n          menuExtras = this.sizeInfo['menuExtras'],\n          notDisabled = this.options.hideDisabled ? '.disabled' : '',\n          menuHeight,\n          menuWidth,\n          getHeight,\n          getWidth,\n          selectOffsetTop,\n          selectOffsetBot,\n          selectOffsetLeft,\n          selectOffsetRight,\n          getPos = function() {\n            var pos = that.$newElement.offset(),\n                $container = $(that.options.container),\n                containerPos;\n\n            if (that.options.container && !$container.is('body')) {\n              containerPos = $container.offset();\n              containerPos.top += parseInt($container.css('borderTopWidth'));\n              containerPos.left += parseInt($container.css('borderLeftWidth'));\n            } else {\n              containerPos = { top: 0, left: 0 };\n            }\n\n            var winPad = that.options.windowPadding;\n            selectOffsetTop = pos.top - containerPos.top - $window.scrollTop();\n            selectOffsetBot = $window.height() - selectOffsetTop - selectHeight - containerPos.top - winPad[2];\n            selectOffsetLeft = pos.left - containerPos.left - $window.scrollLeft();\n            selectOffsetRight = $window.width() - selectOffsetLeft - selectWidth - containerPos.left - winPad[1];\n            selectOffsetTop -= winPad[0];\n            selectOffsetLeft -= winPad[3];\n          };\n\n      getPos();\n\n      if (this.options.size === 'auto') {\n        var getSize = function () {\n          var minHeight,\n              hasClass = function (className, include) {\n                return function (element) {\n                    if (include) {\n                        return (element.classList ? element.classList.contains(className) : $(element).hasClass(className));\n                    } else {\n                        return !(element.classList ? element.classList.contains(className) : $(element).hasClass(className));\n                    }\n                };\n              },\n              lis = that.$menuInner[0].getElementsByTagName('li'),\n              lisVisible = Array.prototype.filter ? Array.prototype.filter.call(lis, hasClass('hidden', false)) : that.$lis.not('.hidden'),\n              optGroup = Array.prototype.filter ? Array.prototype.filter.call(lisVisible, hasClass('dropdown-header', true)) : lisVisible.filter('.dropdown-header');\n\n          getPos();\n          menuHeight = selectOffsetBot - menuExtras.vert;\n          menuWidth = selectOffsetRight - menuExtras.horiz;\n\n          if (that.options.container) {\n            if (!$menu.data('height')) $menu.data('height', $menu.height());\n            getHeight = $menu.data('height');\n\n            if (!$menu.data('width')) $menu.data('width', $menu.width());\n            getWidth = $menu.data('width');\n          } else {\n            getHeight = $menu.height();\n            getWidth = $menu.width();\n          }\n\n          if (that.options.dropupAuto) {\n            that.$newElement.toggleClass('dropup', selectOffsetTop > selectOffsetBot && (menuHeight - menuExtras.vert) < getHeight);\n          }\n\n          if (that.$newElement.hasClass('dropup')) {\n            menuHeight = selectOffsetTop - menuExtras.vert;\n          }\n\n          if (that.options.dropdownAlignRight === 'auto') {\n            $menu.toggleClass('dropdown-menu-right', selectOffsetLeft > selectOffsetRight && (menuWidth - menuExtras.horiz) < (getWidth - selectWidth));\n          }\n\n          if ((lisVisible.length + optGroup.length) > 3) {\n            minHeight = liHeight * 3 + menuExtras.vert - 2;\n          } else {\n            minHeight = 0;\n          }\n\n          $menu.css({\n            'max-height': menuHeight + 'px',\n            'overflow': 'hidden',\n            'min-height': minHeight + headerHeight + searchHeight + actionsHeight + doneButtonHeight + 'px'\n          });\n          $menuInner.css({\n            'max-height': menuHeight - headerHeight - searchHeight - actionsHeight - doneButtonHeight - menuPadding.vert + 'px',\n            'overflow-y': 'auto',\n            'min-height': Math.max(minHeight - menuPadding.vert, 0) + 'px'\n          });\n        };\n        getSize();\n        this.$searchbox.off('input.getSize propertychange.getSize').on('input.getSize propertychange.getSize', getSize);\n        $window.off('resize.getSize scroll.getSize').on('resize.getSize scroll.getSize', getSize);\n      } else if (this.options.size && this.options.size != 'auto' && this.$lis.not(notDisabled).length > this.options.size) {\n        var optIndex = this.$lis.not('.divider').not(notDisabled).children().slice(0, this.options.size).last().parent().index(),\n            divLength = this.$lis.slice(0, optIndex + 1).filter('.divider').length;\n        menuHeight = liHeight * this.options.size + divLength * divHeight + menuPadding.vert;\n\n        if (that.options.container) {\n          if (!$menu.data('height')) $menu.data('height', $menu.height());\n          getHeight = $menu.data('height');\n        } else {\n          getHeight = $menu.height();\n        }\n\n        if (that.options.dropupAuto) {\n          //noinspection JSUnusedAssignment\n          this.$newElement.toggleClass('dropup', selectOffsetTop > selectOffsetBot && (menuHeight - menuExtras.vert) < getHeight);\n        }\n        $menu.css({\n          'max-height': menuHeight + headerHeight + searchHeight + actionsHeight + doneButtonHeight + 'px',\n          'overflow': 'hidden',\n          'min-height': ''\n        });\n        $menuInner.css({\n          'max-height': menuHeight - menuPadding.vert + 'px',\n          'overflow-y': 'auto',\n          'min-height': ''\n        });\n      }\n    },\n\n    setWidth: function () {\n      if (this.options.width === 'auto') {\n        this.$menu.css('min-width', '0');\n\n        // Get correct width if element is hidden\n        var $selectClone = this.$menu.parent().clone().appendTo('body'),\n            $selectClone2 = this.options.container ? this.$newElement.clone().appendTo('body') : $selectClone,\n            ulWidth = $selectClone.children('.dropdown-menu').outerWidth(),\n            btnWidth = $selectClone2.css('width', 'auto').children('button').outerWidth();\n\n        $selectClone.remove();\n        $selectClone2.remove();\n\n        // Set width to whatever's larger, button title or longest option\n        this.$newElement.css('width', Math.max(ulWidth, btnWidth) + 'px');\n      } else if (this.options.width === 'fit') {\n        // Remove inline min-width so width can be changed from 'auto'\n        this.$menu.css('min-width', '');\n        this.$newElement.css('width', '').addClass('fit-width');\n      } else if (this.options.width) {\n        // Remove inline min-width so width can be changed from 'auto'\n        this.$menu.css('min-width', '');\n        this.$newElement.css('width', this.options.width);\n      } else {\n        // Remove inline min-width/width so width can be changed\n        this.$menu.css('min-width', '');\n        this.$newElement.css('width', '');\n      }\n      // Remove fit-width class if width is changed programmatically\n      if (this.$newElement.hasClass('fit-width') && this.options.width !== 'fit') {\n        this.$newElement.removeClass('fit-width');\n      }\n    },\n\n    selectPosition: function () {\n      this.$bsContainer = $('<div class=\"bs-container\" />');\n\n      var that = this,\n          $container = $(this.options.container),\n          pos,\n          containerPos,\n          actualHeight,\n          getPlacement = function ($element) {\n            that.$bsContainer.addClass($element.attr('class').replace(/form-control|fit-width/gi, '')).toggleClass('dropup', $element.hasClass('dropup'));\n            pos = $element.offset();\n\n            if (!$container.is('body')) {\n              containerPos = $container.offset();\n              containerPos.top += parseInt($container.css('borderTopWidth')) - $container.scrollTop();\n              containerPos.left += parseInt($container.css('borderLeftWidth')) - $container.scrollLeft();\n            } else {\n              containerPos = { top: 0, left: 0 };\n            }\n\n            actualHeight = $element.hasClass('dropup') ? 0 : $element[0].offsetHeight;\n\n            that.$bsContainer.css({\n              'top': pos.top - containerPos.top + actualHeight,\n              'left': pos.left - containerPos.left,\n              'width': $element[0].offsetWidth\n            });\n          };\n\n      this.$button.on('click', function () {\n        var $this = $(this);\n\n        if (that.isDisabled()) {\n          return;\n        }\n\n        getPlacement(that.$newElement);\n\n        that.$bsContainer\n          .appendTo(that.options.container)\n          .toggleClass('open', !$this.hasClass('open'))\n          .append(that.$menu);\n      });\n\n      $(window).on('resize scroll', function () {\n        getPlacement(that.$newElement);\n      });\n\n      this.$element.on('hide.bs.select', function () {\n        that.$menu.data('height', that.$menu.height());\n        that.$bsContainer.detach();\n      });\n    },\n\n    /**\n     * @param {number} index - the index of the option that is being changed\n     * @param {boolean} selected - true if the option is being selected, false if being deselected\n     * @param {JQuery} $lis - the 'li' element that is being modified\n     */\n    setSelected: function (index, selected, $lis) {\n      if (!$lis) {\n        this.togglePlaceholder(); // check if setSelected is being called by changing the value of the select\n        $lis = this.findLis().eq(this.liObj[index]);\n      }\n\n      $lis.toggleClass('selected', selected).find('a').attr('aria-selected', selected);\n    },\n\n    /**\n     * @param {number} index - the index of the option that is being disabled\n     * @param {boolean} disabled - true if the option is being disabled, false if being enabled\n     * @param {JQuery} $lis - the 'li' element that is being modified\n     */\n    setDisabled: function (index, disabled, $lis) {\n      if (!$lis) {\n        $lis = this.findLis().eq(this.liObj[index]);\n      }\n\n      if (disabled) {\n        $lis.addClass('disabled').children('a').attr('href', '#').attr('tabindex', -1).attr('aria-disabled', true);\n      } else {\n        $lis.removeClass('disabled').children('a').removeAttr('href').attr('tabindex', 0).attr('aria-disabled', false);\n      }\n    },\n\n    isDisabled: function () {\n      return this.$element[0].disabled;\n    },\n\n    checkDisabled: function () {\n      var that = this;\n\n      if (this.isDisabled()) {\n        this.$newElement.addClass('disabled');\n        this.$button.addClass('disabled').attr('tabindex', -1).attr('aria-disabled', true);\n      } else {\n        if (this.$button.hasClass('disabled')) {\n          this.$newElement.removeClass('disabled');\n          this.$button.removeClass('disabled').attr('aria-disabled', false);\n        }\n\n        if (this.$button.attr('tabindex') == -1 && !this.$element.data('tabindex')) {\n          this.$button.removeAttr('tabindex');\n        }\n      }\n\n      this.$button.click(function () {\n        return !that.isDisabled();\n      });\n    },\n\n    togglePlaceholder: function () {\n      var value = this.$element.val();\n      this.$button.toggleClass('bs-placeholder', value === null || value === '' || (value.constructor === Array && value.length === 0));\n    },\n\n    tabIndex: function () {\n      if (this.$element.data('tabindex') !== this.$element.attr('tabindex') && \n        (this.$element.attr('tabindex') !== -98 && this.$element.attr('tabindex') !== '-98')) {\n        this.$element.data('tabindex', this.$element.attr('tabindex'));\n        this.$button.attr('tabindex', this.$element.data('tabindex'));\n      }\n\n      this.$element.attr('tabindex', -98);\n    },\n\n    clickListener: function () {\n      var that = this,\n          $document = $(document);\n\n      $document.data('spaceSelect', false);\n\n      this.$button.on('keyup', function (e) {\n        if (/(32)/.test(e.keyCode.toString(10)) && $document.data('spaceSelect')) {\n            e.preventDefault();\n            $document.data('spaceSelect', false);\n        }\n      });\n\n      this.$button.on('click', function () {\n        that.setSize();\n      });\n\n      this.$element.on('shown.bs.select', function () {\n        if (!that.options.liveSearch && !that.multiple) {\n          that.$menuInner.find('.selected a').focus();\n        } else if (!that.multiple) {\n          var selectedIndex = that.liObj[that.$element[0].selectedIndex];\n\n          if (typeof selectedIndex !== 'number' || that.options.size === false) return;\n\n          // scroll to selected option\n          var offset = that.$lis.eq(selectedIndex)[0].offsetTop - that.$menuInner[0].offsetTop;\n          offset = offset - that.$menuInner[0].offsetHeight/2 + that.sizeInfo.liHeight/2;\n          that.$menuInner[0].scrollTop = offset;\n        }\n      });\n\n      this.$menuInner.on('click', 'li a', function (e) {\n        var $this = $(this),\n            clickedIndex = $this.parent().data('originalIndex'),\n            prevValue = that.$element.val(),\n            prevIndex = that.$element.prop('selectedIndex'),\n            triggerChange = true;\n\n        // Don't close on multi choice menu\n        if (that.multiple && that.options.maxOptions !== 1) {\n          e.stopPropagation();\n        }\n\n        e.preventDefault();\n\n        //Don't run if we have been disabled\n        if (!that.isDisabled() && !$this.parent().hasClass('disabled')) {\n          var $options = that.$element.find('option'),\n              $option = $options.eq(clickedIndex),\n              state = $option.prop('selected'),\n              $optgroup = $option.parent('optgroup'),\n              maxOptions = that.options.maxOptions,\n              maxOptionsGrp = $optgroup.data('maxOptions') || false;\n\n          if (!that.multiple) { // Deselect all others if not multi select box\n            $options.prop('selected', false);\n            $option.prop('selected', true);\n            that.$menuInner.find('.selected').removeClass('selected').find('a').attr('aria-selected', false);\n            that.setSelected(clickedIndex, true);\n          } else { // Toggle the one we have chosen if we are multi select.\n            $option.prop('selected', !state);\n            that.setSelected(clickedIndex, !state);\n            $this.blur();\n\n            if (maxOptions !== false || maxOptionsGrp !== false) {\n              var maxReached = maxOptions < $options.filter(':selected').length,\n                  maxReachedGrp = maxOptionsGrp < $optgroup.find('option:selected').length;\n\n              if ((maxOptions && maxReached) || (maxOptionsGrp && maxReachedGrp)) {\n                if (maxOptions && maxOptions == 1) {\n                  $options.prop('selected', false);\n                  $option.prop('selected', true);\n                  that.$menuInner.find('.selected').removeClass('selected');\n                  that.setSelected(clickedIndex, true);\n                } else if (maxOptionsGrp && maxOptionsGrp == 1) {\n                  $optgroup.find('option:selected').prop('selected', false);\n                  $option.prop('selected', true);\n                  var optgroupID = $this.parent().data('optgroup');\n                  that.$menuInner.find('[data-optgroup=\"' + optgroupID + '\"]').removeClass('selected');\n                  that.setSelected(clickedIndex, true);\n                } else {\n                  var maxOptionsText = typeof that.options.maxOptionsText === 'string' ? [that.options.maxOptionsText, that.options.maxOptionsText] : that.options.maxOptionsText,\n                      maxOptionsArr = typeof maxOptionsText === 'function' ? maxOptionsText(maxOptions, maxOptionsGrp) : maxOptionsText,\n                      maxTxt = maxOptionsArr[0].replace('{n}', maxOptions),\n                      maxTxtGrp = maxOptionsArr[1].replace('{n}', maxOptionsGrp),\n                      $notify = $('<div class=\"notify\"></div>');\n                  // If {var} is set in array, replace it\n                  /** @deprecated */\n                  if (maxOptionsArr[2]) {\n                    maxTxt = maxTxt.replace('{var}', maxOptionsArr[2][maxOptions > 1 ? 0 : 1]);\n                    maxTxtGrp = maxTxtGrp.replace('{var}', maxOptionsArr[2][maxOptionsGrp > 1 ? 0 : 1]);\n                  }\n\n                  $option.prop('selected', false);\n\n                  that.$menu.append($notify);\n\n                  if (maxOptions && maxReached) {\n                    $notify.append($('<div>' + maxTxt + '</div>'));\n                    triggerChange = false;\n                    that.$element.trigger('maxReached.bs.select');\n                  }\n\n                  if (maxOptionsGrp && maxReachedGrp) {\n                    $notify.append($('<div>' + maxTxtGrp + '</div>'));\n                    triggerChange = false;\n                    that.$element.trigger('maxReachedGrp.bs.select');\n                  }\n\n                  setTimeout(function () {\n                    that.setSelected(clickedIndex, false);\n                  }, 10);\n\n                  $notify.delay(750).fadeOut(300, function () {\n                    $(this).remove();\n                  });\n                }\n              }\n            }\n          }\n\n          if (!that.multiple || (that.multiple && that.options.maxOptions === 1)) {\n            that.$button.focus();\n          } else if (that.options.liveSearch) {\n            that.$searchbox.focus();\n          }\n\n          // Trigger select 'change'\n          if (triggerChange) {\n            if ((prevValue != that.$element.val() && that.multiple) || (prevIndex != that.$element.prop('selectedIndex') && !that.multiple)) {\n              // $option.prop('selected') is current option state (selected/unselected). state is previous option state.\n              changed_arguments = [clickedIndex, $option.prop('selected'), state];\n              that.$element\n                .triggerNative('change');\n            }\n          }\n        }\n      });\n\n      this.$menu.on('click', 'li.disabled a, .popover-title, .popover-title :not(.close)', function (e) {\n        if (e.currentTarget == this) {\n          e.preventDefault();\n          e.stopPropagation();\n          if (that.options.liveSearch && !$(e.target).hasClass('close')) {\n            that.$searchbox.focus();\n          } else {\n            that.$button.focus();\n          }\n        }\n      });\n\n      this.$menuInner.on('click', '.divider, .dropdown-header', function (e) {\n        e.preventDefault();\n        e.stopPropagation();\n        if (that.options.liveSearch) {\n          that.$searchbox.focus();\n        } else {\n          that.$button.focus();\n        }\n      });\n\n      this.$menu.on('click', '.popover-title .close', function () {\n        that.$button.click();\n      });\n\n      this.$searchbox.on('click', function (e) {\n        e.stopPropagation();\n      });\n\n      this.$menu.on('click', '.actions-btn', function (e) {\n        if (that.options.liveSearch) {\n          that.$searchbox.focus();\n        } else {\n          that.$button.focus();\n        }\n\n        e.preventDefault();\n        e.stopPropagation();\n\n        if ($(this).hasClass('bs-select-all')) {\n          that.selectAll();\n        } else {\n          that.deselectAll();\n        }\n      });\n\n      this.$element.change(function () {\n        that.render(false);\n        that.$element.trigger('changed.bs.select', changed_arguments);\n        changed_arguments = null;\n      });\n    },\n\n    liveSearchListener: function () {\n      var that = this,\n          $no_results = $('<li class=\"no-results\"></li>');\n\n      this.$button.on('click.dropdown.data-api', function () {\n        that.$menuInner.find('.active').removeClass('active');\n        if (!!that.$searchbox.val()) {\n          that.$searchbox.val('');\n          that.$lis.not('.is-hidden').removeClass('hidden');\n          if (!!$no_results.parent().length) $no_results.remove();\n        }\n        if (!that.multiple) that.$menuInner.find('.selected').addClass('active');\n        setTimeout(function () {\n          that.$searchbox.focus();\n        }, 10);\n      });\n\n      this.$searchbox.on('click.dropdown.data-api focus.dropdown.data-api touchend.dropdown.data-api', function (e) {\n        e.stopPropagation();\n      });\n\n      this.$searchbox.on('input propertychange', function () {\n        that.$lis.not('.is-hidden').removeClass('hidden');\n        that.$lis.filter('.active').removeClass('active');\n        $no_results.remove();\n\n        if (that.$searchbox.val()) {\n          var $searchBase = that.$lis.not('.is-hidden, .divider, .dropdown-header'),\n              $hideItems;\n          if (that.options.liveSearchNormalize) {\n            $hideItems = $searchBase.find('a').not(':a' + that._searchStyle() + '(\"' + normalizeToBase(that.$searchbox.val()) + '\")');\n          } else {\n            $hideItems = $searchBase.find('a').not(':' + that._searchStyle() + '(\"' + that.$searchbox.val() + '\")');\n          }\n\n          if ($hideItems.length === $searchBase.length) {\n            $no_results.html(that.options.noneResultsText.replace('{0}', '\"' + htmlEscape(that.$searchbox.val()) + '\"'));\n            that.$menuInner.append($no_results);\n            that.$lis.addClass('hidden');\n          } else {\n            $hideItems.parent().addClass('hidden');\n\n            var $lisVisible = that.$lis.not('.hidden'),\n                $foundDiv;\n\n            // hide divider if first or last visible, or if followed by another divider\n            $lisVisible.each(function (index) {\n              var $this = $(this);\n\n              if ($this.hasClass('divider')) {\n                if ($foundDiv === undefined) {\n                  $this.addClass('hidden');\n                } else {\n                  if ($foundDiv) $foundDiv.addClass('hidden');\n                  $foundDiv = $this;\n                }\n              } else if ($this.hasClass('dropdown-header') && $lisVisible.eq(index + 1).data('optgroup') !== $this.data('optgroup')) {\n                $this.addClass('hidden');\n              } else {\n                $foundDiv = null;\n              }\n            });\n            if ($foundDiv) $foundDiv.addClass('hidden');\n\n            $searchBase.not('.hidden').first().addClass('active');\n          }\n        }\n      });\n    },\n\n    _searchStyle: function () {\n      var styles = {\n        begins: 'ibegins',\n        startsWith: 'ibegins'\n      };\n\n      return styles[this.options.liveSearchStyle] || 'icontains';\n    },\n\n    val: function (value) {\n      if (typeof value !== 'undefined') {\n        this.$element.val(value);\n        this.render();\n\n        return this.$element;\n      } else {\n        return this.$element.val();\n      }\n    },\n\n    changeAll: function (status) {\n      if (!this.multiple) return;\n      if (typeof status === 'undefined') status = true;\n\n      this.findLis();\n\n      var $options = this.$element.find('option'),\n          $lisVisible = this.$lis.not('.divider, .dropdown-header, .disabled, .hidden'),\n          lisVisLen = $lisVisible.length,\n          selectedOptions = [];\n          \n      if (status) {\n        if ($lisVisible.filter('.selected').length === $lisVisible.length) return;\n      } else {\n        if ($lisVisible.filter('.selected').length === 0) return;\n      }\n          \n      $lisVisible.toggleClass('selected', status);\n\n      for (var i = 0; i < lisVisLen; i++) {\n        var origIndex = $lisVisible[i].getAttribute('data-original-index');\n        selectedOptions[selectedOptions.length] = $options.eq(origIndex)[0];\n      }\n\n      $(selectedOptions).prop('selected', status);\n\n      this.render(false);\n\n      this.togglePlaceholder();\n\n      this.$element\n        .triggerNative('change');\n    },\n\n    selectAll: function () {\n      return this.changeAll(true);\n    },\n\n    deselectAll: function () {\n      return this.changeAll(false);\n    },\n\n    toggle: function (e) {\n      e = e || window.event;\n\n      if (e) e.stopPropagation();\n\n      this.$button.trigger('click');\n    },\n\n    keydown: function (e) {\n      var $this = $(this),\n          $parent = $this.is('input') ? $this.parent().parent() : $this.parent(),\n          $items,\n          that = $parent.data('this'),\n          index,\n          next,\n          first,\n          last,\n          prev,\n          nextPrev,\n          prevIndex,\n          isActive,\n          selector = ':not(.disabled, .hidden, .dropdown-header, .divider)',\n          keyCodeMap = {\n            32: ' ',\n            48: '0',\n            49: '1',\n            50: '2',\n            51: '3',\n            52: '4',\n            53: '5',\n            54: '6',\n            55: '7',\n            56: '8',\n            57: '9',\n            59: ';',\n            65: 'a',\n            66: 'b',\n            67: 'c',\n            68: 'd',\n            69: 'e',\n            70: 'f',\n            71: 'g',\n            72: 'h',\n            73: 'i',\n            74: 'j',\n            75: 'k',\n            76: 'l',\n            77: 'm',\n            78: 'n',\n            79: 'o',\n            80: 'p',\n            81: 'q',\n            82: 'r',\n            83: 's',\n            84: 't',\n            85: 'u',\n            86: 'v',\n            87: 'w',\n            88: 'x',\n            89: 'y',\n            90: 'z',\n            96: '0',\n            97: '1',\n            98: '2',\n            99: '3',\n            100: '4',\n            101: '5',\n            102: '6',\n            103: '7',\n            104: '8',\n            105: '9'\n          };\n\n      if (that.options.liveSearch) $parent = $this.parent().parent();\n\n      if (that.options.container) $parent = that.$menu;\n\n      $items = $('[role=\"listbox\"] li', $parent);\n\n      isActive = that.$newElement.hasClass('open');\n\n      if (!isActive && (e.keyCode >= 48 && e.keyCode <= 57 || e.keyCode >= 96 && e.keyCode <= 105 || e.keyCode >= 65 && e.keyCode <= 90)) {\n        if (!that.options.container) {\n          that.setSize();\n          that.$menu.parent().addClass('open');\n          isActive = true;\n        } else {\n          that.$button.trigger('click');\n        }\n        that.$searchbox.focus();\n        return;\n      }\n\n      if (that.options.liveSearch) {\n        if (/(^9$|27)/.test(e.keyCode.toString(10)) && isActive) {\n          e.preventDefault();\n          e.stopPropagation();\n          that.$menuInner.click();\n          that.$button.focus();\n        }\n        // $items contains li elements when liveSearch is enabled\n        $items = $('[role=\"listbox\"] li' + selector, $parent);\n        if (!$this.val() && !/(38|40)/.test(e.keyCode.toString(10))) {\n          if ($items.filter('.active').length === 0) {\n            $items = that.$menuInner.find('li');\n            if (that.options.liveSearchNormalize) {\n              $items = $items.filter(':a' + that._searchStyle() + '(' + normalizeToBase(keyCodeMap[e.keyCode]) + ')');\n            } else {\n              $items = $items.filter(':' + that._searchStyle() + '(' + keyCodeMap[e.keyCode] + ')');\n            }\n          }\n        }\n      }\n\n      if (!$items.length) return;\n\n      if (/(38|40)/.test(e.keyCode.toString(10))) {\n        index = $items.index($items.find('a').filter(':focus').parent());\n        first = $items.filter(selector).first().index();\n        last = $items.filter(selector).last().index();\n        next = $items.eq(index).nextAll(selector).eq(0).index();\n        prev = $items.eq(index).prevAll(selector).eq(0).index();\n        nextPrev = $items.eq(next).prevAll(selector).eq(0).index();\n\n        if (that.options.liveSearch) {\n          $items.each(function (i) {\n            if (!$(this).hasClass('disabled')) {\n              $(this).data('index', i);\n            }\n          });\n          index = $items.index($items.filter('.active'));\n          first = $items.first().data('index');\n          last = $items.last().data('index');\n          next = $items.eq(index).nextAll().eq(0).data('index');\n          prev = $items.eq(index).prevAll().eq(0).data('index');\n          nextPrev = $items.eq(next).prevAll().eq(0).data('index');\n        }\n\n        prevIndex = $this.data('prevIndex');\n\n        if (e.keyCode == 38) {\n          if (that.options.liveSearch) index--;\n          if (index != nextPrev && index > prev) index = prev;\n          if (index < first) index = first;\n          if (index == prevIndex) index = last;\n        } else if (e.keyCode == 40) {\n          if (that.options.liveSearch) index++;\n          if (index == -1) index = 0;\n          if (index != nextPrev && index < next) index = next;\n          if (index > last) index = last;\n          if (index == prevIndex) index = first;\n        }\n\n        $this.data('prevIndex', index);\n\n        if (!that.options.liveSearch) {\n          $items.eq(index).children('a').focus();\n        } else {\n          e.preventDefault();\n          if (!$this.hasClass('dropdown-toggle')) {\n            $items.removeClass('active').eq(index).addClass('active').children('a').focus();\n            $this.focus();\n          }\n        }\n\n      } else if (!$this.is('input')) {\n        var keyIndex = [],\n            count,\n            prevKey;\n\n        $items.each(function () {\n          if (!$(this).hasClass('disabled')) {\n            if ($.trim($(this).children('a').text().toLowerCase()).substring(0, 1) == keyCodeMap[e.keyCode]) {\n              keyIndex.push($(this).index());\n            }\n          }\n        });\n\n        count = $(document).data('keycount');\n        count++;\n        $(document).data('keycount', count);\n\n        prevKey = $.trim($(':focus').text().toLowerCase()).substring(0, 1);\n\n        if (prevKey != keyCodeMap[e.keyCode]) {\n          count = 1;\n          $(document).data('keycount', count);\n        } else if (count >= keyIndex.length) {\n          $(document).data('keycount', 0);\n          if (count > keyIndex.length) count = 1;\n        }\n\n        $items.eq(keyIndex[count - 1]).children('a').focus();\n      }\n\n      // Select focused option if \"Enter\", \"Spacebar\" or \"Tab\" (when selectOnTab is true) are pressed inside the menu.\n      if ((/(13|32)/.test(e.keyCode.toString(10)) || (/(^9$)/.test(e.keyCode.toString(10)) && that.options.selectOnTab)) && isActive) {\n        if (!/(32)/.test(e.keyCode.toString(10))) e.preventDefault();\n        if (!that.options.liveSearch) {\n          var elem = $(':focus');\n          elem.click();\n          // Bring back focus for multiselects\n          elem.focus();\n          // Prevent screen from scrolling if the user hit the spacebar\n          e.preventDefault();\n          // Fixes spacebar selection of dropdown items in FF & IE\n          $(document).data('spaceSelect', true);\n        } else if (!/(32)/.test(e.keyCode.toString(10))) {\n          that.$menuInner.find('.active a').click();\n          $this.focus();\n        }\n        $(document).data('keycount', 0);\n      }\n\n      if ((/(^9$|27)/.test(e.keyCode.toString(10)) && isActive && (that.multiple || that.options.liveSearch)) || (/(27)/.test(e.keyCode.toString(10)) && !isActive)) {\n        that.$menu.parent().removeClass('open');\n        if (that.options.container) that.$newElement.removeClass('open');\n        that.$button.focus();\n      }\n    },\n\n    mobile: function () {\n      this.$element.addClass('mobile-device');\n    },\n\n    refresh: function () {\n      this.$lis = null;\n      this.liObj = {};\n      this.reloadLi();\n      this.render();\n      this.checkDisabled();\n      this.liHeight(true);\n      this.setStyle();\n      this.setWidth();\n      if (this.$lis) this.$searchbox.trigger('propertychange');\n\n      this.$element.trigger('refreshed.bs.select');\n    },\n\n    hide: function () {\n      this.$newElement.hide();\n    },\n\n    show: function () {\n      this.$newElement.show();\n    },\n\n    remove: function () {\n      this.$newElement.remove();\n      this.$element.remove();\n    },\n\n    destroy: function () {\n      this.$newElement.before(this.$element).remove();\n\n      if (this.$bsContainer) {\n        this.$bsContainer.remove();\n      } else {\n        this.$menu.remove();\n      }\n\n      this.$element\n        .off('.bs.select')\n        .removeData('selectpicker')\n        .removeClass('bs-select-hidden selectpicker');\n    }\n  };\n\n  // SELECTPICKER PLUGIN DEFINITION\n  // ==============================\n  function Plugin(option) {\n    // get the args of the outer function..\n    var args = arguments;\n    // The arguments of the function are explicitly re-defined from the argument list, because the shift causes them\n    // to get lost/corrupted in android 2.3 and IE9 #715 #775\n    var _option = option;\n\n    [].shift.apply(args);\n\n    var value;\n    var chain = this.each(function () {\n      var $this = $(this);\n      if ($this.is('select')) {\n        var data = $this.data('selectpicker'),\n            options = typeof _option == 'object' && _option;\n\n        if (!data) {\n          var config = $.extend({}, Selectpicker.DEFAULTS, $.fn.selectpicker.defaults || {}, $this.data(), options);\n          config.template = $.extend({}, Selectpicker.DEFAULTS.template, ($.fn.selectpicker.defaults ? $.fn.selectpicker.defaults.template : {}), $this.data().template, options.template);\n          $this.data('selectpicker', (data = new Selectpicker(this, config)));\n        } else if (options) {\n          for (var i in options) {\n            if (options.hasOwnProperty(i)) {\n              data.options[i] = options[i];\n            }\n          }\n        }\n\n        if (typeof _option == 'string') {\n          if (data[_option] instanceof Function) {\n            value = data[_option].apply(data, args);\n          } else {\n            value = data.options[_option];\n          }\n        }\n      }\n    });\n\n    if (typeof value !== 'undefined') {\n      //noinspection JSUnusedAssignment\n      return value;\n    } else {\n      return chain;\n    }\n  }\n\n  var old = $.fn.selectpicker;\n  $.fn.selectpicker = Plugin;\n  $.fn.selectpicker.Constructor = Selectpicker;\n\n  // SELECTPICKER NO CONFLICT\n  // ========================\n  $.fn.selectpicker.noConflict = function () {\n    $.fn.selectpicker = old;\n    return this;\n  };\n\n  $(document)\n      .data('keycount', 0)\n      .on('keydown.bs.select', '.bootstrap-select [data-toggle=dropdown], .bootstrap-select [role=\"listbox\"], .bs-searchbox input', Selectpicker.prototype.keydown)\n      .on('focusin.modal', '.bootstrap-select [data-toggle=dropdown], .bootstrap-select [role=\"listbox\"], .bs-searchbox input', function (e) {\n        e.stopPropagation();\n      });\n\n  // SELECTPICKER DATA-API\n  // =====================\n  $(window).on('load.bs.select.data-api', function () {\n    $('.selectpicker').each(function () {\n      var $selectpicker = $(this);\n      Plugin.call($selectpicker, $selectpicker.data());\n    })\n  });\n})(jQuery);\n\n\n}));\n"
  },
  {
    "path": "app_frontend/static/plugin/bootstrap-select-1.12.2/dist/js/i18n/defaults-ar_AR.js",
    "content": "/*!\n * Bootstrap-select v1.12.2 (http://silviomoreto.github.io/bootstrap-select)\n *\n * Copyright 2013-2017 bootstrap-select\n * Licensed under MIT (https://github.com/silviomoreto/bootstrap-select/blob/master/LICENSE)\n */\n\n(function (root, factory) {\n  if (typeof define === 'function' && define.amd) {\n    // AMD. Register as an anonymous module unless amdModuleId is set\n    define([\"jquery\"], function (a0) {\n      return (factory(a0));\n    });\n  } else if (typeof module === 'object' && module.exports) {\n    // Node. Does not work with strict CommonJS, but\n    // only CommonJS-like environments that support module.exports,\n    // like Node.\n    module.exports = factory(require(\"jquery\"));\n  } else {\n    factory(root[\"jQuery\"]);\n  }\n}(this, function (jQuery) {\n\n/*!\n * Translated default messages for bootstrap-select.\n * Locale: AR (Arabic)\n * Author: Yasser Lotfy <y_l@alive.com>\n */\n(function ($) {\n  $.fn.selectpicker.defaults = {\n    noneSelectedText: 'لم يتم إختيار شئ',\n    noneResultsText: 'لا توجد نتائج مطابقة لـ {0}',\n    countSelectedText: function (numSelected, numTotal) {\n      return (numSelected == 1) ? \"{0} خيار تم إختياره\" : \"{0} خيارات تمت إختيارها\";\n    },\n    maxOptionsText: function (numAll, numGroup) {\n      return [\n        (numAll == 1) ? 'تخطى الحد المسموح ({n} خيار بحد أقصى)' : 'تخطى الحد المسموح ({n} خيارات بحد أقصى)',\n        (numGroup == 1) ? 'تخطى الحد المسموح للمجموعة ({n} خيار بحد أقصى)' : 'تخطى الحد المسموح للمجموعة ({n} خيارات بحد أقصى)'\n      ];\n    },\n    selectAllText: 'إختيار الجميع',\n    deselectAllText: 'إلغاء إختيار الجميع',\n    multipleSeparator: '، '\n  };\n})(jQuery);\n\n\n}));\n"
  },
  {
    "path": "app_frontend/static/plugin/bootstrap-select-1.12.2/dist/js/i18n/defaults-bg_BG.js",
    "content": "/*!\n * Bootstrap-select v1.12.2 (http://silviomoreto.github.io/bootstrap-select)\n *\n * Copyright 2013-2017 bootstrap-select\n * Licensed under MIT (https://github.com/silviomoreto/bootstrap-select/blob/master/LICENSE)\n */\n\n(function (root, factory) {\n  if (typeof define === 'function' && define.amd) {\n    // AMD. Register as an anonymous module unless amdModuleId is set\n    define([\"jquery\"], function (a0) {\n      return (factory(a0));\n    });\n  } else if (typeof module === 'object' && module.exports) {\n    // Node. Does not work with strict CommonJS, but\n    // only CommonJS-like environments that support module.exports,\n    // like Node.\n    module.exports = factory(require(\"jquery\"));\n  } else {\n    factory(root[\"jQuery\"]);\n  }\n}(this, function (jQuery) {\n\n(function ($) {\n  $.fn.selectpicker.defaults = {\n    noneSelectedText: 'Нищо избрано',\n    noneResultsText: 'Няма резултат за {0}',\n    countSelectedText: function (numSelected, numTotal) {\n      return (numSelected == 1) ? \"{0} избран елемент\" : \"{0} избрани елемента\";\n    },\n    maxOptionsText: function (numAll, numGroup) {\n      return [\n        (numAll == 1) ? 'Лимита е достигнат ({n} елемент максимум)' : 'Лимита е достигнат ({n} елемента максимум)',\n        (numGroup == 1) ? 'Груповия лимит е достигнат ({n} елемент максимум)' : 'Груповия лимит е достигнат ({n} елемента максимум)'\n      ];\n    },\n    selectAllText: 'Избери всички',\n    deselectAllText: 'Размаркирай всички',\n    multipleSeparator: ', '\n  };\n})(jQuery);\n\n\n}));\n"
  },
  {
    "path": "app_frontend/static/plugin/bootstrap-select-1.12.2/dist/js/i18n/defaults-cro_CRO.js",
    "content": "/*!\n * Bootstrap-select v1.12.2 (http://silviomoreto.github.io/bootstrap-select)\n *\n * Copyright 2013-2017 bootstrap-select\n * Licensed under MIT (https://github.com/silviomoreto/bootstrap-select/blob/master/LICENSE)\n */\n\n(function (root, factory) {\n  if (typeof define === 'function' && define.amd) {\n    // AMD. Register as an anonymous module unless amdModuleId is set\n    define([\"jquery\"], function (a0) {\n      return (factory(a0));\n    });\n  } else if (typeof module === 'object' && module.exports) {\n    // Node. Does not work with strict CommonJS, but\n    // only CommonJS-like environments that support module.exports,\n    // like Node.\n    module.exports = factory(require(\"jquery\"));\n  } else {\n    factory(root[\"jQuery\"]);\n  }\n}(this, function (jQuery) {\n\n(function ($) {\n  $.fn.selectpicker.defaults = {\n    noneSelectedText: 'Odaberite stavku',\n    noneResultsText: 'Nema rezultata pretrage {0}',\n    countSelectedText: function (numSelected, numTotal) {\n      return (numSelected == 1) ? \"{0} stavka selektirana\" : \"{0} stavke selektirane\";\n    },\n    maxOptionsText: function (numAll, numGroup) {\n      return [\n        (numAll == 1) ? 'Limit je postignut ({n} stvar maximalno)' : 'Limit je postignut ({n} stavke maksimalno)',\n        (numGroup == 1) ? 'Grupni limit je postignut ({n} stvar maksimalno)' : 'Grupni limit je postignut ({n} stavke maksimalno)'\n      ];\n    },\n    selectAllText: 'Selektiraj sve',\n    deselectAllText: 'Deselektiraj sve',\n    multipleSeparator: ', '\n  };\n})(jQuery);\n\n\n}));\n"
  },
  {
    "path": "app_frontend/static/plugin/bootstrap-select-1.12.2/dist/js/i18n/defaults-cs_CZ.js",
    "content": "/*!\n * Bootstrap-select v1.12.2 (http://silviomoreto.github.io/bootstrap-select)\n *\n * Copyright 2013-2017 bootstrap-select\n * Licensed under MIT (https://github.com/silviomoreto/bootstrap-select/blob/master/LICENSE)\n */\n\n(function (root, factory) {\n  if (typeof define === 'function' && define.amd) {\n    // AMD. Register as an anonymous module unless amdModuleId is set\n    define([\"jquery\"], function (a0) {\n      return (factory(a0));\n    });\n  } else if (typeof module === 'object' && module.exports) {\n    // Node. Does not work with strict CommonJS, but\n    // only CommonJS-like environments that support module.exports,\n    // like Node.\n    module.exports = factory(require(\"jquery\"));\n  } else {\n    factory(root[\"jQuery\"]);\n  }\n}(this, function (jQuery) {\n\n(function ($) {\n  $.fn.selectpicker.defaults = {\n    noneSelectedText: 'Nic není vybráno',\n    noneResultsText: 'Žádné výsledky {0}',\n    countSelectedText: 'Označeno {0} z {1}',\n    maxOptionsText: ['Limit překročen ({n} {var} max)', 'Limit skupiny překročen ({n} {var} max)', ['položek', 'položka']],\n    multipleSeparator: ', '\n  };\n})(jQuery);\n\n\n}));\n"
  },
  {
    "path": "app_frontend/static/plugin/bootstrap-select-1.12.2/dist/js/i18n/defaults-da_DK.js",
    "content": "/*!\n * Bootstrap-select v1.12.2 (http://silviomoreto.github.io/bootstrap-select)\n *\n * Copyright 2013-2017 bootstrap-select\n * Licensed under MIT (https://github.com/silviomoreto/bootstrap-select/blob/master/LICENSE)\n */\n\n(function (root, factory) {\n  if (typeof define === 'function' && define.amd) {\n    // AMD. Register as an anonymous module unless amdModuleId is set\n    define([\"jquery\"], function (a0) {\n      return (factory(a0));\n    });\n  } else if (typeof module === 'object' && module.exports) {\n    // Node. Does not work with strict CommonJS, but\n    // only CommonJS-like environments that support module.exports,\n    // like Node.\n    module.exports = factory(require(\"jquery\"));\n  } else {\n    factory(root[\"jQuery\"]);\n  }\n}(this, function (jQuery) {\n\n(function ($) {\n  $.fn.selectpicker.defaults = {\n    noneSelectedText: 'Intet valgt',\n    noneResultsText: 'Ingen resultater fundet {0}',\n    countSelectedText: function (numSelected, numTotal) {\n      return (numSelected == 1) ? \"{0} valgt\" : \"{0} valgt\";\n    },\n    maxOptionsText: function (numAll, numGroup) {\n      return [\n        (numAll == 1) ? 'Begrænsning nået (max {n} valgt)' : 'Begrænsning nået (max {n} valgte)',\n        (numGroup == 1) ? 'Gruppe-begrænsning nået (max {n} valgt)' : 'Gruppe-begrænsning nået (max {n} valgte)'\n      ];\n    },\n    selectAllText: 'Markér alle',\n    deselectAllText: 'Afmarkér alle',\n    multipleSeparator: ', '\n  };\n})(jQuery);\n\n\n}));\n"
  },
  {
    "path": "app_frontend/static/plugin/bootstrap-select-1.12.2/dist/js/i18n/defaults-de_DE.js",
    "content": "/*!\n * Bootstrap-select v1.12.2 (http://silviomoreto.github.io/bootstrap-select)\n *\n * Copyright 2013-2017 bootstrap-select\n * Licensed under MIT (https://github.com/silviomoreto/bootstrap-select/blob/master/LICENSE)\n */\n\n(function (root, factory) {\n  if (typeof define === 'function' && define.amd) {\n    // AMD. Register as an anonymous module unless amdModuleId is set\n    define([\"jquery\"], function (a0) {\n      return (factory(a0));\n    });\n  } else if (typeof module === 'object' && module.exports) {\n    // Node. Does not work with strict CommonJS, but\n    // only CommonJS-like environments that support module.exports,\n    // like Node.\n    module.exports = factory(require(\"jquery\"));\n  } else {\n    factory(root[\"jQuery\"]);\n  }\n}(this, function (jQuery) {\n\n(function ($) {\n  $.fn.selectpicker.defaults = {\n    noneSelectedText: 'Bitte wählen...',\n    noneResultsText: 'Keine Ergebnisse für {0}',\n    countSelectedText: function (numSelected, numTotal) {\n      return (numSelected == 1) ? \"{0} Element ausgewählt\" : \"{0} Elemente ausgewählt\";\n    },\n    maxOptionsText: function (numAll, numGroup) {\n      return [\n        (numAll == 1) ? 'Limit erreicht ({n} Element max.)' : 'Limit erreicht ({n} Elemente max.)',\n        (numGroup == 1) ? 'Gruppen-Limit erreicht ({n} Element max.)' : 'Gruppen-Limit erreicht ({n} Elemente max.)'\n      ];\n    },\n    selectAllText: 'Alles auswählen',\n    deselectAllText: 'Nichts auswählen',\n    multipleSeparator: ', '\n  };\n})(jQuery);\n\n\n}));\n"
  },
  {
    "path": "app_frontend/static/plugin/bootstrap-select-1.12.2/dist/js/i18n/defaults-en_US.js",
    "content": "/*!\n * Bootstrap-select v1.12.2 (http://silviomoreto.github.io/bootstrap-select)\n *\n * Copyright 2013-2017 bootstrap-select\n * Licensed under MIT (https://github.com/silviomoreto/bootstrap-select/blob/master/LICENSE)\n */\n\n(function (root, factory) {\n  if (typeof define === 'function' && define.amd) {\n    // AMD. Register as an anonymous module unless amdModuleId is set\n    define([\"jquery\"], function (a0) {\n      return (factory(a0));\n    });\n  } else if (typeof module === 'object' && module.exports) {\n    // Node. Does not work with strict CommonJS, but\n    // only CommonJS-like environments that support module.exports,\n    // like Node.\n    module.exports = factory(require(\"jquery\"));\n  } else {\n    factory(root[\"jQuery\"]);\n  }\n}(this, function (jQuery) {\n\n(function ($) {\n  $.fn.selectpicker.defaults = {\n    noneSelectedText: 'Nothing selected',\n    noneResultsText: 'No results match {0}',\n    countSelectedText: function (numSelected, numTotal) {\n      return (numSelected == 1) ? \"{0} item selected\" : \"{0} items selected\";\n    },\n    maxOptionsText: function (numAll, numGroup) {\n      return [\n        (numAll == 1) ? 'Limit reached ({n} item max)' : 'Limit reached ({n} items max)',\n        (numGroup == 1) ? 'Group limit reached ({n} item max)' : 'Group limit reached ({n} items max)'\n      ];\n    },\n    selectAllText: 'Select All',\n    deselectAllText: 'Deselect All',\n    multipleSeparator: ', '\n  };\n})(jQuery);\n\n\n}));\n"
  },
  {
    "path": "app_frontend/static/plugin/bootstrap-select-1.12.2/dist/js/i18n/defaults-es_CL.js",
    "content": "/*!\n * Bootstrap-select v1.12.2 (http://silviomoreto.github.io/bootstrap-select)\n *\n * Copyright 2013-2017 bootstrap-select\n * Licensed under MIT (https://github.com/silviomoreto/bootstrap-select/blob/master/LICENSE)\n */\n\n(function (root, factory) {\n  if (typeof define === 'function' && define.amd) {\n    // AMD. Register as an anonymous module unless amdModuleId is set\n    define([\"jquery\"], function (a0) {\n      return (factory(a0));\n    });\n  } else if (typeof module === 'object' && module.exports) {\n    // Node. Does not work with strict CommonJS, but\n    // only CommonJS-like environments that support module.exports,\n    // like Node.\n    module.exports = factory(require(\"jquery\"));\n  } else {\n    factory(root[\"jQuery\"]);\n  }\n}(this, function (jQuery) {\n\n(function ($) {\n  $.fn.selectpicker.defaults = {\n    noneSelectedText: 'No hay selección',\n    noneResultsText: 'No hay resultados {0}',\n    countSelectedText: 'Seleccionados {0} de {1}',\n    maxOptionsText: ['Límite alcanzado ({n} {var} max)', 'Límite del grupo alcanzado({n} {var} max)', ['elementos', 'element']],\n    multipleSeparator: ', ',\n    selectAllText: 'Seleccionar Todos',\n    deselectAllText: 'Desmarcar Todos'\n  };\n})(jQuery);\n\n\n}));\n"
  },
  {
    "path": "app_frontend/static/plugin/bootstrap-select-1.12.2/dist/js/i18n/defaults-es_ES.js",
    "content": "/*!\n * Bootstrap-select v1.12.2 (http://silviomoreto.github.io/bootstrap-select)\n *\n * Copyright 2013-2017 bootstrap-select\n * Licensed under MIT (https://github.com/silviomoreto/bootstrap-select/blob/master/LICENSE)\n */\n\n(function (root, factory) {\n  if (typeof define === 'function' && define.amd) {\n    // AMD. Register as an anonymous module unless amdModuleId is set\n    define([\"jquery\"], function (a0) {\n      return (factory(a0));\n    });\n  } else if (typeof module === 'object' && module.exports) {\n    // Node. Does not work with strict CommonJS, but\n    // only CommonJS-like environments that support module.exports,\n    // like Node.\n    module.exports = factory(require(\"jquery\"));\n  } else {\n    factory(root[\"jQuery\"]);\n  }\n}(this, function (jQuery) {\n\n(function ($) {\n  $.fn.selectpicker.defaults = {\n    noneSelectedText: 'No hay selección',\n    noneResultsText: 'No hay resultados {0}',\n    countSelectedText: 'Seleccionados {0} de {1}',\n    maxOptionsText: ['Límite alcanzado ({n} {var} max)', 'Límite del grupo alcanzado({n} {var} max)', ['elementos', 'element']],\n    multipleSeparator: ', ',\n    selectAllText: 'Seleccionar Todos',\n    deselectAllText: 'Desmarcar Todos'\n  };\n})(jQuery);\n\n\n}));\n"
  },
  {
    "path": "app_frontend/static/plugin/bootstrap-select-1.12.2/dist/js/i18n/defaults-eu.js",
    "content": "/*!\n * Bootstrap-select v1.12.2 (http://silviomoreto.github.io/bootstrap-select)\n *\n * Copyright 2013-2017 bootstrap-select\n * Licensed under MIT (https://github.com/silviomoreto/bootstrap-select/blob/master/LICENSE)\n */\n\n(function (root, factory) {\n  if (typeof define === 'function' && define.amd) {\n    // AMD. Register as an anonymous module unless amdModuleId is set\n    define([\"jquery\"], function (a0) {\n      return (factory(a0));\n    });\n  } else if (typeof module === 'object' && module.exports) {\n    // Node. Does not work with strict CommonJS, but\n    // only CommonJS-like environments that support module.exports,\n    // like Node.\n    module.exports = factory(require(\"jquery\"));\n  } else {\n    factory(root[\"jQuery\"]);\n  }\n}(this, function (jQuery) {\n\n(function ($) {\n  $.fn.selectpicker.defaults = {\n    noneSelectedText: 'Hautapenik ez',\n    noneResultsText: 'Emaitzarik ez {0}',\n    countSelectedText: '{1}(e)tik {0} hautatuta',\n    maxOptionsText: ['Mugara iritsita ({n} {var} gehienez)', 'Taldearen mugara iritsita ({n} {var} gehienez)', ['elementu', 'elementu']],\n    multipleSeparator: ', '\n  };\n})(jQuery);\n\n\n}));\n"
  },
  {
    "path": "app_frontend/static/plugin/bootstrap-select-1.12.2/dist/js/i18n/defaults-fa_IR.js",
    "content": "/*!\n * Bootstrap-select v1.12.2 (http://silviomoreto.github.io/bootstrap-select)\n *\n * Copyright 2013-2017 bootstrap-select\n * Licensed under MIT (https://github.com/silviomoreto/bootstrap-select/blob/master/LICENSE)\n */\n\n(function (root, factory) {\n  if (typeof define === 'function' && define.amd) {\n    // AMD. Register as an anonymous module unless amdModuleId is set\n    define([\"jquery\"], function (a0) {\n      return (factory(a0));\n    });\n  } else if (typeof module === 'object' && module.exports) {\n    // Node. Does not work with strict CommonJS, but\n    // only CommonJS-like environments that support module.exports,\n    // like Node.\n    module.exports = factory(require(\"jquery\"));\n  } else {\n    factory(root[\"jQuery\"]);\n  }\n}(this, function (jQuery) {\n\n(function ($) {\n    $.fn.selectpicker.defaults = {\n        noneSelectedText: 'چیزی انتخاب نشده است',\n        noneResultsText: 'هیج مشابهی برای {0} پیدا نشد',\n        countSelectedText: \"{0} از {1} مورد انتخاب شده\",\n        maxOptionsText: ['بیشتر ممکن نیست {حداکثر {n} عدد}', 'بیشتر ممکن نیست {حداکثر {n} عدد}'],\n        selectAllText: 'انتخاب همه',\n        deselectAllText: 'انتخاب هیچ کدام',\n        multipleSeparator: ', '\n    };\n})(jQuery);\n\n\n}));\n"
  },
  {
    "path": "app_frontend/static/plugin/bootstrap-select-1.12.2/dist/js/i18n/defaults-fi_FI.js",
    "content": "/*!\n * Bootstrap-select v1.12.2 (http://silviomoreto.github.io/bootstrap-select)\n *\n * Copyright 2013-2017 bootstrap-select\n * Licensed under MIT (https://github.com/silviomoreto/bootstrap-select/blob/master/LICENSE)\n */\n\n(function (root, factory) {\n  if (typeof define === 'function' && define.amd) {\n    // AMD. Register as an anonymous module unless amdModuleId is set\n    define([\"jquery\"], function (a0) {\n      return (factory(a0));\n    });\n  } else if (typeof module === 'object' && module.exports) {\n    // Node. Does not work with strict CommonJS, but\n    // only CommonJS-like environments that support module.exports,\n    // like Node.\n    module.exports = factory(require(\"jquery\"));\n  } else {\n    factory(root[\"jQuery\"]);\n  }\n}(this, function (jQuery) {\n\n(function ($) {\n  $.fn.selectpicker.defaults = {\n    noneSelectedText: 'Ei valintoja',\n    noneResultsText: 'Ei hakutuloksia {0}',\n    countSelectedText: function (numSelected, numTotal) {\n      return (numSelected == 1) ? \"{0} valittu\" : \"{0} valitut\";\n    },\n    maxOptionsText: function (numAll, numGroup) {\n      return [\n        (numAll == 1) ? 'Valintojen maksimimäärä ({n} saavutettu)' : 'Valintojen maksimimäärä ({n} saavutettu)',\n        (numGroup == 1) ? 'Ryhmän maksimimäärä ({n} saavutettu)' : 'Ryhmän maksimimäärä ({n} saavutettu)'\n      ];\n    },\n    selectAllText: 'Valitse kaikki',\n    deselectAllText: 'Poista kaikki',\n    multipleSeparator: ', '\n  };\n})(jQuery);\n\n\n}));\n"
  },
  {
    "path": "app_frontend/static/plugin/bootstrap-select-1.12.2/dist/js/i18n/defaults-fr_FR.js",
    "content": "/*!\n * Bootstrap-select v1.12.2 (http://silviomoreto.github.io/bootstrap-select)\n *\n * Copyright 2013-2017 bootstrap-select\n * Licensed under MIT (https://github.com/silviomoreto/bootstrap-select/blob/master/LICENSE)\n */\n\n(function (root, factory) {\n  if (typeof define === 'function' && define.amd) {\n    // AMD. Register as an anonymous module unless amdModuleId is set\n    define([\"jquery\"], function (a0) {\n      return (factory(a0));\n    });\n  } else if (typeof module === 'object' && module.exports) {\n    // Node. Does not work with strict CommonJS, but\n    // only CommonJS-like environments that support module.exports,\n    // like Node.\n    module.exports = factory(require(\"jquery\"));\n  } else {\n    factory(root[\"jQuery\"]);\n  }\n}(this, function (jQuery) {\n\n(function ($) {\n  $.fn.selectpicker.defaults = {\n    noneSelectedText: 'Aucune sélection',\n    noneResultsText: 'Aucun résultat pour {0}',\n    countSelectedText: function (numSelected, numTotal) {\n      return (numSelected > 1) ? \"{0} éléments sélectionnés\" : \"{0} élément sélectionné\";\n    },\n    maxOptionsText: function (numAll, numGroup) {\n      return [\n        (numAll > 1) ? 'Limite atteinte ({n} éléments max)' : 'Limite atteinte ({n} élément max)',\n        (numGroup > 1) ? 'Limite du groupe atteinte ({n} éléments max)' : 'Limite du groupe atteinte ({n} élément max)'\n      ];\n    },\n    multipleSeparator: ', ',\n    selectAllText: 'Tout Sélectionner',\n    deselectAllText: 'Tout Dé-selectionner',\n  };\n})(jQuery);\n\n\n}));\n"
  },
  {
    "path": "app_frontend/static/plugin/bootstrap-select-1.12.2/dist/js/i18n/defaults-hu_HU.js",
    "content": "/*!\n * Bootstrap-select v1.12.2 (http://silviomoreto.github.io/bootstrap-select)\n *\n * Copyright 2013-2017 bootstrap-select\n * Licensed under MIT (https://github.com/silviomoreto/bootstrap-select/blob/master/LICENSE)\n */\n\n(function (root, factory) {\n  if (typeof define === 'function' && define.amd) {\n    // AMD. Register as an anonymous module unless amdModuleId is set\n    define([\"jquery\"], function (a0) {\n      return (factory(a0));\n    });\n  } else if (typeof module === 'object' && module.exports) {\n    // Node. Does not work with strict CommonJS, but\n    // only CommonJS-like environments that support module.exports,\n    // like Node.\n    module.exports = factory(require(\"jquery\"));\n  } else {\n    factory(root[\"jQuery\"]);\n  }\n}(this, function (jQuery) {\n\n(function ($) {\n  $.fn.selectpicker.defaults = {\n    noneSelectedText: 'Válasszon!',\n    noneResultsText: 'Nincs találat {0}',\n    countSelectedText: function (numSelected, numTotal) {\n      return '{0} elem kiválasztva';\n    },\n    maxOptionsText: function (numAll, numGroup) {\n      return [\n        'Legfeljebb {n} elem választható',\n        'A csoportban legfeljebb {n} elem választható'\n      ];\n    },\n    selectAllText: 'Mind',\n    deselectAllText: 'Egyik sem',\n    multipleSeparator: ', '\n  };\n})(jQuery);\n\n\n}));\n"
  },
  {
    "path": "app_frontend/static/plugin/bootstrap-select-1.12.2/dist/js/i18n/defaults-id_ID.js",
    "content": "/*!\n * Bootstrap-select v1.12.2 (http://silviomoreto.github.io/bootstrap-select)\n *\n * Copyright 2013-2017 bootstrap-select\n * Licensed under MIT (https://github.com/silviomoreto/bootstrap-select/blob/master/LICENSE)\n */\n\n(function (root, factory) {\n  if (typeof define === 'function' && define.amd) {\n    // AMD. Register as an anonymous module unless amdModuleId is set\n    define([\"jquery\"], function (a0) {\n      return (factory(a0));\n    });\n  } else if (typeof module === 'object' && module.exports) {\n    // Node. Does not work with strict CommonJS, but\n    // only CommonJS-like environments that support module.exports,\n    // like Node.\n    module.exports = factory(require(\"jquery\"));\n  } else {\n    factory(root[\"jQuery\"]);\n  }\n}(this, function (jQuery) {\n\n(function ($) {\n  $.fn.selectpicker.defaults = {\n    noneSelectedText: 'Tidak ada yang dipilih',\n    noneResultsText: 'Tidak ada yang cocok {0}',\n    countSelectedText: '{0} terpilih',\n    maxOptionsText: ['Mencapai batas (maksimum {n})', 'Mencapai batas grup (maksimum {n})'],\n    selectAllText: 'Pilih Semua',\n    deselectAllText: 'Hapus Semua',\n    multipleSeparator: ', '\n  };\n})(jQuery);\n\n\n}));\n"
  },
  {
    "path": "app_frontend/static/plugin/bootstrap-select-1.12.2/dist/js/i18n/defaults-it_IT.js",
    "content": "/*!\n * Bootstrap-select v1.12.2 (http://silviomoreto.github.io/bootstrap-select)\n *\n * Copyright 2013-2017 bootstrap-select\n * Licensed under MIT (https://github.com/silviomoreto/bootstrap-select/blob/master/LICENSE)\n */\n\n(function (root, factory) {\n  if (typeof define === 'function' && define.amd) {\n    // AMD. Register as an anonymous module unless amdModuleId is set\n    define([\"jquery\"], function (a0) {\n      return (factory(a0));\n    });\n  } else if (typeof module === 'object' && module.exports) {\n    // Node. Does not work with strict CommonJS, but\n    // only CommonJS-like environments that support module.exports,\n    // like Node.\n    module.exports = factory(require(\"jquery\"));\n  } else {\n    factory(root[\"jQuery\"]);\n  }\n}(this, function (jQuery) {\n\n(function ($) {\n  $.fn.selectpicker.defaults = {\n    noneSelectedText: 'Nessuna selezione',\n    noneResultsText: 'Nessun risultato per {0}',\n    countSelectedText: function (numSelected, numTotal){\n      return (numSelected == 1) ? 'Selezionato {0} di {1}' : 'Selezionati {0} di {1}';\n    },\n    maxOptionsText: ['Limite raggiunto ({n} {var} max)', 'Limite del gruppo raggiunto ({n} {var} max)', ['elementi', 'elemento']],\n    multipleSeparator: ', ',\n    selectAllText: 'Seleziona Tutto',\n    deselectAllText: 'Deseleziona Tutto'\n  };\n})(jQuery);\n\n\n}));\n"
  },
  {
    "path": "app_frontend/static/plugin/bootstrap-select-1.12.2/dist/js/i18n/defaults-ko_KR.js",
    "content": "/*!\n * Bootstrap-select v1.12.2 (http://silviomoreto.github.io/bootstrap-select)\n *\n * Copyright 2013-2017 bootstrap-select\n * Licensed under MIT (https://github.com/silviomoreto/bootstrap-select/blob/master/LICENSE)\n */\n\n(function (root, factory) {\n  if (typeof define === 'function' && define.amd) {\n    // AMD. Register as an anonymous module unless amdModuleId is set\n    define([\"jquery\"], function (a0) {\n      return (factory(a0));\n    });\n  } else if (typeof module === 'object' && module.exports) {\n    // Node. Does not work with strict CommonJS, but\n    // only CommonJS-like environments that support module.exports,\n    // like Node.\n    module.exports = factory(require(\"jquery\"));\n  } else {\n    factory(root[\"jQuery\"]);\n  }\n}(this, function (jQuery) {\n\n(function ($) {\n  $.fn.selectpicker.defaults = {\n    noneSelectedText: '항목을 선택해주세요',\n    noneResultsText: '{0} 검색 결과가 없습니다',\n    countSelectedText: function (numSelected, numTotal) {\n      return \"{0}개를 선택하였습니다\";\n    },\n    maxOptionsText: function (numAll, numGroup) {\n      return [\n        '{n}개까지 선택 가능합니다',\n        '해당 그룹은 {n}개까지 선택 가능합니다'\n      ];\n    },\n    selectAllText: '전체선택',\n    deselectAllText: '전체해제',\n    multipleSeparator: ', '\n  };\n})(jQuery);\n\n\n}));\n"
  },
  {
    "path": "app_frontend/static/plugin/bootstrap-select-1.12.2/dist/js/i18n/defaults-lt_LT.js",
    "content": "/*!\n * Bootstrap-select v1.12.2 (http://silviomoreto.github.io/bootstrap-select)\n *\n * Copyright 2013-2017 bootstrap-select\n * Licensed under MIT (https://github.com/silviomoreto/bootstrap-select/blob/master/LICENSE)\n */\n\n(function (root, factory) {\n  if (typeof define === 'function' && define.amd) {\n    // AMD. Register as an anonymous module unless amdModuleId is set\n    define([\"jquery\"], function (a0) {\n      return (factory(a0));\n    });\n  } else if (typeof module === 'object' && module.exports) {\n    // Node. Does not work with strict CommonJS, but\n    // only CommonJS-like environments that support module.exports,\n    // like Node.\n    module.exports = factory(require(\"jquery\"));\n  } else {\n    factory(root[\"jQuery\"]);\n  }\n}(this, function (jQuery) {\n\n(function ($) {\n  $.fn.selectpicker.defaults = {\n    noneSelectedText: 'Niekas nepasirinkta',\n    noneResultsText: 'Niekas nesutapo su {0}',\n    countSelectedText: function (numSelected, numTotal) {\n      return (numSelected == 1) ? \"{0} elementas pasirinktas\" : \"{0} elementai(-ų) pasirinkta\";\n    },\n    maxOptionsText: function (numAll, numGroup) {\n      return [\n        (numAll == 1) ? 'Pasiekta riba ({n} elementas daugiausiai)' : 'Riba pasiekta ({n} elementai(-ų) daugiausiai)',\n        (numGroup == 1) ? 'Grupės riba pasiekta ({n} elementas daugiausiai)' : 'Grupės riba pasiekta ({n} elementai(-ų) daugiausiai)'\n      ];\n    },\n    selectAllText: 'Pasirinkti visus',\n    deselectAllText: 'Atmesti visus',\n    multipleSeparator: ', '\n  };\n})(jQuery);\n\n\n}));\n"
  },
  {
    "path": "app_frontend/static/plugin/bootstrap-select-1.12.2/dist/js/i18n/defaults-nb_NO.js",
    "content": "/*!\n * Bootstrap-select v1.12.2 (http://silviomoreto.github.io/bootstrap-select)\n *\n * Copyright 2013-2017 bootstrap-select\n * Licensed under MIT (https://github.com/silviomoreto/bootstrap-select/blob/master/LICENSE)\n */\n\n(function (root, factory) {\n  if (typeof define === 'function' && define.amd) {\n    // AMD. Register as an anonymous module unless amdModuleId is set\n    define([\"jquery\"], function (a0) {\n      return (factory(a0));\n    });\n  } else if (typeof module === 'object' && module.exports) {\n    // Node. Does not work with strict CommonJS, but\n    // only CommonJS-like environments that support module.exports,\n    // like Node.\n    module.exports = factory(require(\"jquery\"));\n  } else {\n    factory(root[\"jQuery\"]);\n  }\n}(this, function (jQuery) {\n\n(function ($) {\n  $.fn.selectpicker.defaults = {\n    noneSelectedText: 'Ingen valgt',\n    noneResultsText: 'Søket gir ingen treff {0}',\n    countSelectedText: function (numSelected, numTotal) {\n      return (numSelected == 1) ? \"{0} alternativ valgt\" : \"{0} alternativer valgt\";\n    },\n    maxOptionsText: function (numAll, numGroup) {\n      return [\n        (numAll == 1) ? 'Grense nådd (maks {n} valg)' : 'Grense nådd (maks {n} valg)',\n        (numGroup == 1) ? 'Grense for grupper nådd (maks {n} grupper)' : 'Grense for grupper nådd (maks {n} grupper)'\n      ];\n    },\n    selectAllText: 'Merk alle',\n    deselectAllText: 'Fjern alle',\n    multipleSeparator: ', '\n  };\n})(jQuery);\n\n\n}));\n"
  },
  {
    "path": "app_frontend/static/plugin/bootstrap-select-1.12.2/dist/js/i18n/defaults-nl_NL.js",
    "content": "/*!\n * Bootstrap-select v1.12.2 (http://silviomoreto.github.io/bootstrap-select)\n *\n * Copyright 2013-2017 bootstrap-select\n * Licensed under MIT (https://github.com/silviomoreto/bootstrap-select/blob/master/LICENSE)\n */\n\n(function (root, factory) {\n  if (typeof define === 'function' && define.amd) {\n    // AMD. Register as an anonymous module unless amdModuleId is set\n    define([\"jquery\"], function (a0) {\n      return (factory(a0));\n    });\n  } else if (typeof module === 'object' && module.exports) {\n    // Node. Does not work with strict CommonJS, but\n    // only CommonJS-like environments that support module.exports,\n    // like Node.\n    module.exports = factory(require(\"jquery\"));\n  } else {\n    factory(root[\"jQuery\"]);\n  }\n}(this, function (jQuery) {\n\n(function ($) {\n  $.fn.selectpicker.defaults = {\n    noneSelectedText: 'Niets geselecteerd',\n    noneResultsText: 'Geen resultaten gevonden voor {0}',\n    countSelectedText: '{0} van {1} geselecteerd',\n    maxOptionsText: ['Limiet bereikt ({n} {var} max)', 'Groep limiet bereikt ({n} {var} max)', ['items', 'item']],\n    multipleSeparator: ', '\n  };\n})(jQuery);\n\n\n}));\n"
  },
  {
    "path": "app_frontend/static/plugin/bootstrap-select-1.12.2/dist/js/i18n/defaults-pl_PL.js",
    "content": "/*!\n * Bootstrap-select v1.12.2 (http://silviomoreto.github.io/bootstrap-select)\n *\n * Copyright 2013-2017 bootstrap-select\n * Licensed under MIT (https://github.com/silviomoreto/bootstrap-select/blob/master/LICENSE)\n */\n\n(function (root, factory) {\n  if (typeof define === 'function' && define.amd) {\n    // AMD. Register as an anonymous module unless amdModuleId is set\n    define([\"jquery\"], function (a0) {\n      return (factory(a0));\n    });\n  } else if (typeof module === 'object' && module.exports) {\n    // Node. Does not work with strict CommonJS, but\n    // only CommonJS-like environments that support module.exports,\n    // like Node.\n    module.exports = factory(require(\"jquery\"));\n  } else {\n    factory(root[\"jQuery\"]);\n  }\n}(this, function (jQuery) {\n\n(function ($) {\n  $.fn.selectpicker.defaults = {\n    noneSelectedText: 'Nic nie zaznaczono',\n    noneResultsText: 'Brak wyników wyszukiwania {0}',\n    countSelectedText: 'Zaznaczono {0} z {1}',\n    maxOptionsText: ['Osiągnięto limit ({n} {var} max)', 'Limit grupy osiągnięty ({n} {var} max)', ['elementy', 'element']],\n    selectAll: 'Zaznacz wszystkie',\n    deselectAll: 'Odznacz wszystkie',\n    multipleSeparator: ', '\n  };\n})(jQuery);\n\n\n}));\n"
  },
  {
    "path": "app_frontend/static/plugin/bootstrap-select-1.12.2/dist/js/i18n/defaults-pt_BR.js",
    "content": "/*!\n * Bootstrap-select v1.12.2 (http://silviomoreto.github.io/bootstrap-select)\n *\n * Copyright 2013-2017 bootstrap-select\n * Licensed under MIT (https://github.com/silviomoreto/bootstrap-select/blob/master/LICENSE)\n */\n\n(function (root, factory) {\n  if (typeof define === 'function' && define.amd) {\n    // AMD. Register as an anonymous module unless amdModuleId is set\n    define([\"jquery\"], function (a0) {\n      return (factory(a0));\n    });\n  } else if (typeof module === 'object' && module.exports) {\n    // Node. Does not work with strict CommonJS, but\n    // only CommonJS-like environments that support module.exports,\n    // like Node.\n    module.exports = factory(require(\"jquery\"));\n  } else {\n    factory(root[\"jQuery\"]);\n  }\n}(this, function (jQuery) {\n\n(function ($) {\n  $.fn.selectpicker.defaults = {\n    noneSelectedText: 'Nada selecionado',\n    noneResultsText: 'Nada encontrado contendo {0}',\n    countSelectedText: 'Selecionado {0} de {1}',\n    maxOptionsText: ['Limite excedido (máx. {n} {var})', 'Limite do grupo excedido (máx. {n} {var})', ['itens', 'item']],\n    multipleSeparator: ', '\n  };\n})(jQuery);\n\n\n}));\n"
  },
  {
    "path": "app_frontend/static/plugin/bootstrap-select-1.12.2/dist/js/i18n/defaults-pt_PT.js",
    "content": "/*!\n * Bootstrap-select v1.12.2 (http://silviomoreto.github.io/bootstrap-select)\n *\n * Copyright 2013-2017 bootstrap-select\n * Licensed under MIT (https://github.com/silviomoreto/bootstrap-select/blob/master/LICENSE)\n */\n\n(function (root, factory) {\n  if (typeof define === 'function' && define.amd) {\n    // AMD. Register as an anonymous module unless amdModuleId is set\n    define([\"jquery\"], function (a0) {\n      return (factory(a0));\n    });\n  } else if (typeof module === 'object' && module.exports) {\n    // Node. Does not work with strict CommonJS, but\n    // only CommonJS-like environments that support module.exports,\n    // like Node.\n    module.exports = factory(require(\"jquery\"));\n  } else {\n    factory(root[\"jQuery\"]);\n  }\n}(this, function (jQuery) {\n\n(function ($) {\n$.fn.selectpicker.defaults = {\nnoneSelectedText: 'Nenhum seleccionado',\nnoneResultsText: 'Sem resultados contendo {0}',\ncountSelectedText: 'Selecionado {0} de {1}',\nmaxOptionsText: ['Limite ultrapassado (máx. {n} {var})', 'Limite de seleções ultrapassado (máx. {n} {var})', ['itens', 'item']],\nmultipleSeparator: ', '\n};\n})(jQuery);\n\n\n}));\n"
  },
  {
    "path": "app_frontend/static/plugin/bootstrap-select-1.12.2/dist/js/i18n/defaults-ro_RO.js",
    "content": "/*!\n * Bootstrap-select v1.12.2 (http://silviomoreto.github.io/bootstrap-select)\n *\n * Copyright 2013-2017 bootstrap-select\n * Licensed under MIT (https://github.com/silviomoreto/bootstrap-select/blob/master/LICENSE)\n */\n\n(function (root, factory) {\n  if (typeof define === 'function' && define.amd) {\n    // AMD. Register as an anonymous module unless amdModuleId is set\n    define([\"jquery\"], function (a0) {\n      return (factory(a0));\n    });\n  } else if (typeof module === 'object' && module.exports) {\n    // Node. Does not work with strict CommonJS, but\n    // only CommonJS-like environments that support module.exports,\n    // like Node.\n    module.exports = factory(require(\"jquery\"));\n  } else {\n    factory(root[\"jQuery\"]);\n  }\n}(this, function (jQuery) {\n\n(function ($) {\n  $.fn.selectpicker.defaults = {\n    noneSelectedText: 'Nu a fost selectat nimic',\n    noneResultsText: 'Nu exista niciun rezultat {0}',\n    countSelectedText: '{0} din {1} selectat(e)',\n    maxOptionsText: ['Limita a fost atinsa ({n} {var} max)', 'Limita de grup a fost atinsa ({n} {var} max)', ['iteme', 'item']],\n    multipleSeparator: ', '\n  };\n})(jQuery);\n\n\n}));\n"
  },
  {
    "path": "app_frontend/static/plugin/bootstrap-select-1.12.2/dist/js/i18n/defaults-ru_RU.js",
    "content": "/*!\n * Bootstrap-select v1.12.2 (http://silviomoreto.github.io/bootstrap-select)\n *\n * Copyright 2013-2017 bootstrap-select\n * Licensed under MIT (https://github.com/silviomoreto/bootstrap-select/blob/master/LICENSE)\n */\n\n(function (root, factory) {\n  if (typeof define === 'function' && define.amd) {\n    // AMD. Register as an anonymous module unless amdModuleId is set\n    define([\"jquery\"], function (a0) {\n      return (factory(a0));\n    });\n  } else if (typeof module === 'object' && module.exports) {\n    // Node. Does not work with strict CommonJS, but\n    // only CommonJS-like environments that support module.exports,\n    // like Node.\n    module.exports = factory(require(\"jquery\"));\n  } else {\n    factory(root[\"jQuery\"]);\n  }\n}(this, function (jQuery) {\n\n(function ($) {\n  $.fn.selectpicker.defaults = {\n    noneSelectedText: 'Ничего не выбрано',\n    noneResultsText: 'Совпадений не найдено {0}',\n    countSelectedText: 'Выбрано {0} из {1}',\n    maxOptionsText: ['Достигнут предел ({n} {var} максимум)', 'Достигнут предел в группе ({n} {var} максимум)', ['шт.', 'шт.']],\n    doneButtonText: 'Закрыть',\n    selectAllText: 'Выбрать все',\n    deselectAllText: 'Отменить все',    \n    multipleSeparator: ', '\n  };\n})(jQuery);\n\n\n}));\n"
  },
  {
    "path": "app_frontend/static/plugin/bootstrap-select-1.12.2/dist/js/i18n/defaults-sk_SK.js",
    "content": "/*!\n * Bootstrap-select v1.12.2 (http://silviomoreto.github.io/bootstrap-select)\n *\n * Copyright 2013-2017 bootstrap-select\n * Licensed under MIT (https://github.com/silviomoreto/bootstrap-select/blob/master/LICENSE)\n */\n\n(function (root, factory) {\n  if (typeof define === 'function' && define.amd) {\n    // AMD. Register as an anonymous module unless amdModuleId is set\n    define([\"jquery\"], function (a0) {\n      return (factory(a0));\n    });\n  } else if (typeof module === 'object' && module.exports) {\n    // Node. Does not work with strict CommonJS, but\n    // only CommonJS-like environments that support module.exports,\n    // like Node.\n    module.exports = factory(require(\"jquery\"));\n  } else {\n    factory(root[\"jQuery\"]);\n  }\n}(this, function (jQuery) {\n\n(function ($) {\n  $.fn.selectpicker.defaults = {\n    noneSelectedText: 'Vyberte zo zoznamu',\n    noneResultsText: 'Pre výraz {0} neboli nájdené žiadne výsledky',\n    countSelectedText: 'Vybrané {0} z {1}',\n    maxOptionsText: ['Limit prekročený ({n} {var} max)', 'Limit skupiny prekročený ({n} {var} max)', ['položiek', 'položka']],\n    selectAllText: 'Vybrať všetky',\n    deselectAllText: 'Zrušiť výber',\n    multipleSeparator: ', '\n  };\n})(jQuery);\n\n\n}));\n"
  },
  {
    "path": "app_frontend/static/plugin/bootstrap-select-1.12.2/dist/js/i18n/defaults-sl_SI.js",
    "content": "/*!\n * Bootstrap-select v1.12.2 (http://silviomoreto.github.io/bootstrap-select)\n *\n * Copyright 2013-2017 bootstrap-select\n * Licensed under MIT (https://github.com/silviomoreto/bootstrap-select/blob/master/LICENSE)\n */\n\n(function (root, factory) {\n  if (typeof define === 'function' && define.amd) {\n    // AMD. Register as an anonymous module unless amdModuleId is set\n    define([\"jquery\"], function (a0) {\n      return (factory(a0));\n    });\n  } else if (typeof module === 'object' && module.exports) {\n    // Node. Does not work with strict CommonJS, but\n    // only CommonJS-like environments that support module.exports,\n    // like Node.\n    module.exports = factory(require(\"jquery\"));\n  } else {\n    factory(root[\"jQuery\"]);\n  }\n}(this, function (jQuery) {\n\n(function ($) {\n  $.fn.selectpicker.defaults = {\n    noneSelectedText: 'Nič izbranega',\n    noneResultsText: 'Ni zadetkov za {0}',\n    countSelectedText: function (numSelected, numTotal) {\n      \"Število izbranih: {0}\";\n    },\n    maxOptionsText: function (numAll, numGroup) {\n      return [\n        'Omejitev dosežena (max. izbranih: {n})',\n        'Omejitev skupine dosežena (max. izbranih: {n})'\n      ];\n    },\n    selectAllText: 'Izberi vse',\n    deselectAllText: 'Počisti izbor',\n    multipleSeparator: ', '\n  };\n})(jQuery);\n\n\n}));\n"
  },
  {
    "path": "app_frontend/static/plugin/bootstrap-select-1.12.2/dist/js/i18n/defaults-sv_SE.js",
    "content": "/*!\n * Bootstrap-select v1.12.2 (http://silviomoreto.github.io/bootstrap-select)\n *\n * Copyright 2013-2017 bootstrap-select\n * Licensed under MIT (https://github.com/silviomoreto/bootstrap-select/blob/master/LICENSE)\n */\n\n(function (root, factory) {\n  if (typeof define === 'function' && define.amd) {\n    // AMD. Register as an anonymous module unless amdModuleId is set\n    define([\"jquery\"], function (a0) {\n      return (factory(a0));\n    });\n  } else if (typeof module === 'object' && module.exports) {\n    // Node. Does not work with strict CommonJS, but\n    // only CommonJS-like environments that support module.exports,\n    // like Node.\n    module.exports = factory(require(\"jquery\"));\n  } else {\n    factory(root[\"jQuery\"]);\n  }\n}(this, function (jQuery) {\n\n(function ($) {\n  $.fn.selectpicker.defaults = {\n    noneSelectedText: 'Inget valt',\n    noneResultsText: 'Inget sökresultat matchar {0}',\n    countSelectedText: function (numSelected, numTotal) {\n      return (numSelected === 1) ? \"{0} alternativ valt\" : \"{0} alternativ valda\";\n    },\n    maxOptionsText: function (numAll, numGroup) {\n      return [\n        'Gräns uppnåd (max {n} alternativ)',\n        'Gräns uppnåd (max {n} gruppalternativ)'\n      ];\n    },\n    selectAllText: 'Markera alla',\n    deselectAllText: 'Avmarkera alla',\n    multipleSeparator: ', '\n  };\n})(jQuery);\n\n\n}));\n"
  },
  {
    "path": "app_frontend/static/plugin/bootstrap-select-1.12.2/dist/js/i18n/defaults-tr_TR.js",
    "content": "/*!\n * Bootstrap-select v1.12.2 (http://silviomoreto.github.io/bootstrap-select)\n *\n * Copyright 2013-2017 bootstrap-select\n * Licensed under MIT (https://github.com/silviomoreto/bootstrap-select/blob/master/LICENSE)\n */\n\n(function (root, factory) {\n  if (typeof define === 'function' && define.amd) {\n    // AMD. Register as an anonymous module unless amdModuleId is set\n    define([\"jquery\"], function (a0) {\n      return (factory(a0));\n    });\n  } else if (typeof module === 'object' && module.exports) {\n    // Node. Does not work with strict CommonJS, but\n    // only CommonJS-like environments that support module.exports,\n    // like Node.\n    module.exports = factory(require(\"jquery\"));\n  } else {\n    factory(root[\"jQuery\"]);\n  }\n}(this, function (jQuery) {\n\n(function ($) {\n  $.fn.selectpicker.defaults = {\n    noneSelectedText: 'Hiçbiri seçilmedi',\n    noneResultsText: 'Hiçbir sonuç bulunamadı {0}',\n    countSelectedText: function (numSelected, numTotal) {\n      return (numSelected == 1) ? \"{0} öğe seçildi\" : \"{0} öğe seçildi\";\n    },\n    maxOptionsText: function (numAll, numGroup) {\n      return [\n        (numAll == 1) ? 'Limit aşıldı (maksimum {n} sayıda öğe )' : 'Limit aşıldı (maksimum {n} sayıda öğe)',\n        (numGroup == 1) ? 'Grup limiti aşıldı (maksimum {n} sayıda öğe)' : 'Grup limiti aşıldı (maksimum {n} sayıda öğe)'\n      ];\n    },\n    selectAllText: 'Tümünü Seç',\n    deselectAllText: 'Seçiniz',\n    multipleSeparator: ', '\n  };\n})(jQuery);\n\n\n}));\n"
  },
  {
    "path": "app_frontend/static/plugin/bootstrap-select-1.12.2/dist/js/i18n/defaults-ua_UA.js",
    "content": "/*!\n * Bootstrap-select v1.12.2 (http://silviomoreto.github.io/bootstrap-select)\n *\n * Copyright 2013-2017 bootstrap-select\n * Licensed under MIT (https://github.com/silviomoreto/bootstrap-select/blob/master/LICENSE)\n */\n\n(function (root, factory) {\n  if (typeof define === 'function' && define.amd) {\n    // AMD. Register as an anonymous module unless amdModuleId is set\n    define([\"jquery\"], function (a0) {\n      return (factory(a0));\n    });\n  } else if (typeof module === 'object' && module.exports) {\n    // Node. Does not work with strict CommonJS, but\n    // only CommonJS-like environments that support module.exports,\n    // like Node.\n    module.exports = factory(require(\"jquery\"));\n  } else {\n    factory(root[\"jQuery\"]);\n  }\n}(this, function (jQuery) {\n\n(function ($) {\n  $.fn.selectpicker.defaults = {\n    noneSelectedText: 'Нічого не вибрано',\n    noneResultsText: 'Збігів не знайдено {0}',\n    countSelectedText: 'Вибрано {0} із {1}',\n    maxOptionsText: ['Досягнута межа ({n} {var} максимум)', 'Досягнута межа в групі ({n} {var} максимум)', ['items', 'item']],\n    multipleSeparator: ', '\n  };\n})(jQuery);\n\n\n}));\n"
  },
  {
    "path": "app_frontend/static/plugin/bootstrap-select-1.12.2/dist/js/i18n/defaults-zh_CN.js",
    "content": "/*!\n * Bootstrap-select v1.12.2 (http://silviomoreto.github.io/bootstrap-select)\n *\n * Copyright 2013-2017 bootstrap-select\n * Licensed under MIT (https://github.com/silviomoreto/bootstrap-select/blob/master/LICENSE)\n */\n\n(function (root, factory) {\n  if (typeof define === 'function' && define.amd) {\n    // AMD. Register as an anonymous module unless amdModuleId is set\n    define([\"jquery\"], function (a0) {\n      return (factory(a0));\n    });\n  } else if (typeof module === 'object' && module.exports) {\n    // Node. Does not work with strict CommonJS, but\n    // only CommonJS-like environments that support module.exports,\n    // like Node.\n    module.exports = factory(require(\"jquery\"));\n  } else {\n    factory(root[\"jQuery\"]);\n  }\n}(this, function (jQuery) {\n\n(function ($) {\n  $.fn.selectpicker.defaults = {\n    noneSelectedText: '没有选中任何项',\n    noneResultsText: '没有找到匹配项',\n    countSelectedText: '选中{1}中的{0}项',\n    maxOptionsText: ['超出限制 (最多选择{n}项)', '组选择超出限制(最多选择{n}组)'],\n    multipleSeparator: ', '\n  };\n})(jQuery);\n\n\n}));\n"
  },
  {
    "path": "app_frontend/static/plugin/bootstrap-select-1.12.2/dist/js/i18n/defaults-zh_TW.js",
    "content": "/*!\n * Bootstrap-select v1.12.2 (http://silviomoreto.github.io/bootstrap-select)\n *\n * Copyright 2013-2017 bootstrap-select\n * Licensed under MIT (https://github.com/silviomoreto/bootstrap-select/blob/master/LICENSE)\n */\n\n(function (root, factory) {\n  if (typeof define === 'function' && define.amd) {\n    // AMD. Register as an anonymous module unless amdModuleId is set\n    define([\"jquery\"], function (a0) {\n      return (factory(a0));\n    });\n  } else if (typeof module === 'object' && module.exports) {\n    // Node. Does not work with strict CommonJS, but\n    // only CommonJS-like environments that support module.exports,\n    // like Node.\n    module.exports = factory(require(\"jquery\"));\n  } else {\n    factory(root[\"jQuery\"]);\n  }\n}(this, function (jQuery) {\n\n(function ($) {\n  $.fn.selectpicker.defaults = {\n    noneSelectedText: '沒有選取任何項目',\n    noneResultsText: '沒有找到符合的結果',\n    countSelectedText: '已經選取{0}個項目',\n    maxOptionsText: ['超過限制 (最多選擇{n}項)', '超過限制(最多選擇{n}組)'],\n    selectAllText: '選取全部',\n    deselectAllText: '全部取消',\n    multipleSeparator: ', '\n  };\n})(jQuery);\n\n\n}));\n"
  },
  {
    "path": "app_frontend/static/plugin/bootstrap-select-1.12.2/docs/custom_theme/base.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n  <meta charset=\"utf-8\">\n  <meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\">\n  <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n  {% if page_description %}<meta name=\"description\" content=\"{{ page_description }}\">{% endif %}\n  {% if site_author %}<meta name=\"author\" content=\"{{ site_author }}\">{% endif %}\n  {% if canonical_url %}<link rel=\"canonical\" href=\"{{ canonical_url }}\">{% endif %}\n  {% if favicon %}<link rel=\"shortcut icon\" href=\"{{ favicon }}\">\n  {% else %}<link rel=\"shortcut icon\" href=\"{{ base_url }}/img/favicon.ico\">{% endif %}\n\n  <title>{% if page_title %}{{ page_title }} - {% endif %}{{ site_name }}</title>\n\n  <link href=\"https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css\" rel=\"stylesheet\">\n  <link href=\"https://maxcdn.bootstrapcdn.com/font-awesome/4.5.0/css/font-awesome.min.css\" rel=\"stylesheet\">\n  <link href=\"{{ base_url }}/css/highlight.css\" rel=\"stylesheet\">\n  <link href=\"{{ base_url }}/css/base.css\" rel=\"stylesheet\">\n  {%- for path in extra_css %}\n  <link href=\"{{ path }}\" rel=\"stylesheet\">\n  {%- endfor %}\n\n  <!-- HTML5 shim and Respond.js IE8 support of HTML5 elements and media queries -->\n  <!--[if lt IE 9]>\n    <script src=\"https://oss.maxcdn.com/libs/html5shiv/3.7.0/html5shiv.js\"></script>\n    <script src=\"https://oss.maxcdn.com/libs/respond.js/1.3.0/respond.min.js\"></script>\n  <![endif]-->\n</head>\n\n<body>\n\n{% include \"nav.html\" %}\n\n{% if current_page and current_page.is_homepage %} \n<div class=\"jumbotron bs-docs-header text-center\">\n  <div class=\"container\">\n    <h1>bootstrap-select</h1>\n    <p class=\"lead\">Bootstrap-select is a jQuery plugin that utilizes Bootstrap's dropdown.js to style and bring additional functionality to standard select elements.</p>\n    <a class=\"btn btn-outline-inverse btn-lg\" href=\"//github.com/silviomoreto/bootstrap-select/archive/v{{ config.extra.version }}.zip\" role=\"button\">\n      <i class=\"fa fa-download\"></i> Download (v{{ config.extra.version }})\n    </a>\n  </div>\n  <div class=\"gh-btns\">\n    <iframe src=\"https://ghbtns.com/github-btn.html?user=silviomoreto&repo=bootstrap-select&type=star&count=true&size=large\" frameborder=\"0\" scrolling=\"0\" width=\"160px\" height=\"30px\"></iframe>\n    <iframe src=\"https://ghbtns.com/github-btn.html?user=silviomoreto&repo=bootstrap-select&type=fork&count=true&size=large\" frameborder=\"0\" scrolling=\"0\" width=\"160px\" height=\"30px\"></iframe>\n  </div>\n  <div class=\"carbonad\">\n    <div class=\"carbonad-inner\">\n      <script async type=\"text/javascript\" src=\"//cdn.carbonads.com/carbon.js?zoneid=1673&serve=C6AILKT&placement=silviomoretogithubiobootstrapsel\" id=\"_carbonads_js\"></script>\n    </div>\n    <div class=\"charity\">Ad revenue is donated to <a href=\"http://www.projetocana.org/\" target=\"_blank\" rel=\"nofollow\">Projecto Cana</a>.</div>\n  </div>\n</div>\n<div class=\"container\">\n{% include \"content.html\" %}\n</div>\n{% else %}\n<section class=\"jumbotron\">\n  <div class=\"container\">\n    <h1>{{ page_title }}</h1>\n  </div>\n</section>\n<div class=\"container\">\n  <div class=\"col-md-3\">{% include \"toc.html\" %}</div>\n  <div class=\"col-md-9\" role=\"main\">{% include \"content.html\" %}</div>\n</div>\n{% endif %}\n\n  <div class=\"footer\">\n    <div class=\"container text-center\">\n      <p class=\"text-muted\">Bootstrap-select is maintained by <a href=\"https://github.com/caseyjhol\">caseyjhol</a>,\n        <a href=\"https://github.com/t0xicCode\">t0xicCode</a>, and the community.</p>\n    </div>\n  </div>\n\n<script src=\"//ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js\"></script>\n<script src=\"//maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js\"></script>\n<script src=\"{{ base_url }}/js/highlight.pack.js\"></script>\n<script src=\"{{ base_url }}/js/base.js\"></script>\n{%- for path in extra_javascript %}\n<script src=\"{{ path }}\"></script>\n{%- endfor %}\n\n<script type=\"text/javascript\">\n  var _gaq = _gaq || [];\n  _gaq.push(['_setAccount', 'UA-35848102-1']);\n  _gaq.push(['_trackPageview']);\n\n  (function () {\n    var ga = document.createElement('script');\n    ga.type = 'text/javascript';\n    ga.async = true;\n    ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';\n    var s = document.getElementsByTagName('script')[0];\n    s.parentNode.insertBefore(ga, s);\n  })();\n</script>\n</body>\n</html>\n"
  },
  {
    "path": "app_frontend/static/plugin/bootstrap-select-1.12.2/docs/custom_theme/css/base.css",
    "content": "body {\n    padding-top: 70px;\n}\n\nh1[id]:before, h2[id]:before, h3[id]:before, h4[id]:before, h5[id]:before, h6[id]:before {\n    content: \"\";\n    display: block;\n    margin-top: -75px;\n    height: 75px;\n}\n\nh2 code, h3 code, h4 code {\n    background-color: inherit;\n}\n\nul.nav li.main {\n    font-weight: bold;\n}\n\n.container > div.col-md-3 {\n    padding-left: 0;\n}\n\n.container > div.col-md-9 {\n    padding-bottom: 100px;\n}\n\ndiv.source-links {\n    float: right;\n}\n\n/*\n * Side navigation\n *\n * Scrollspy and affixed enhanced navigation to highlight sections and secondary\n * sections of docs content.\n */\n\n/* By default it's not affixed in mobile views, so undo that */\n.bs-sidebar.affix {\n    position: static;\n}\n\n.bs-sidebar.well {\n    padding: 0;\n}\n\n/* First level of nav */\n.bs-sidenav {\n    margin-top: 30px;\n    margin-bottom: 30px;\n    padding-top:    10px;\n    padding-bottom: 10px;\n    border-radius: 5px;\n}\n\n/* All levels of nav */\n.bs-sidebar .nav > li > a {\n    display: block;\n    padding: 5px 20px;\n    z-index: 1;\n}\n.bs-sidebar .nav > li > a:hover,\n.bs-sidebar .nav > li > a:focus {\n    text-decoration: none;\n    border-right: 1px solid;\n}\n.bs-sidebar .nav > .active > a,\n.bs-sidebar .nav > .active:hover > a,\n.bs-sidebar .nav > .active:focus > a {\n    font-weight: bold;\n    background-color: transparent;\n    border-right: 1px solid;\n}\n\n/* Nav: second level (shown on .active) */\n.bs-sidebar .nav .nav {\n    display: none; /* Hide by default, but at >768px, show it */\n    margin-bottom: 8px;\n}\n.bs-sidebar .nav .nav > li > a {\n    padding-top:    3px;\n    padding-bottom: 3px;\n    padding-left: 30px;\n    font-size: 90%;\n}\n\n/* Show and affix the side nav when space allows it */\n@media (min-width: 992px) {\n    .bs-sidebar .nav > .active > ul {\n        display: block;\n    }\n    /* Widen the fixed sidebar */\n    .bs-sidebar.affix,\n    .bs-sidebar.affix-bottom {\n        width: 213px;\n    }\n    .bs-sidebar.affix {\n        position: fixed; /* Undo the static from mobile first approach */\n        top: 80px;\n    }\n    .bs-sidebar.affix-bottom {\n        position: absolute; /* Undo the static from mobile first approach */\n    }\n    .bs-sidebar.affix-bottom .bs-sidenav,\n    .bs-sidebar.affix .bs-sidenav {\n        margin-top: 0;\n        margin-bottom: 0;\n    }\n}\n@media (min-width: 1200px) {\n    /* Widen the fixed sidebar again */\n    .bs-sidebar.affix-bottom,\n    .bs-sidebar.affix {\n        width: 263px;\n    }\n}"
  },
  {
    "path": "app_frontend/static/plugin/bootstrap-select-1.12.2/docs/custom_theme/js/base.js",
    "content": "/* Highlight */\n$( document ).ready(function() {\n    hljs.initHighlightingOnLoad();\n    $('table').addClass('table table-striped table-hover');\n    $('pre').addClass('highlight');\n});\n\n$('body').scrollspy({\n    target: '.bs-sidebar',\n});\n\n$('.bs-sidebar').affix({\n  offset: {\n    top: 210\n  }\n});\n\n/* Prevent disabled links from causing a page reload */\n$(\"li.disabled a\").click(function() {\n    event.preventDefault();\n});"
  },
  {
    "path": "app_frontend/static/plugin/bootstrap-select-1.12.2/docs/custom_theme/nav.html",
    "content": "<div class=\"navbar navbar-default navbar-fixed-top\" role=\"navigation\">\n  <div class=\"container\">\n\n    <!-- Collapsed navigation -->\n    <div class=\"navbar-header\">\n      {% if include_nav or include_next_prev or repo_url %}\n      <!-- Expander button -->\n      <button type=\"button\" class=\"navbar-toggle\" data-toggle=\"collapse\" data-target=\".navbar-collapse\">\n        <span class=\"sr-only\">Toggle navigation</span>\n        <span class=\"icon-bar\"></span>\n        <span class=\"icon-bar\"></span>\n        <span class=\"icon-bar\"></span>\n      </button>\n      {% endif %}\n\n      <!-- Main title -->\n      <a class=\"navbar-brand\" href=\"{{ homepage_url }}\">{{ site_name }}</a>\n    </div>\n\n    <!-- Expanded navigation -->\n    <div class=\"navbar-collapse collapse\">\n      {% if include_nav %}\n      <!-- Main navigation -->\n      <ul class=\"nav navbar-nav\">\n        {% for nav_item in nav %}\n        {% if nav_item.children %}\n        <li class=\"dropdown{% if nav_item.active %} active{% endif %}\">\n          <a href=\"#\" class=\"dropdown-toggle\" data-toggle=\"dropdown\">{{ nav_item.title }} <b class=\"caret\"></b></a>\n          <ul class=\"dropdown-menu\">\n            {% for nav_item in nav_item.children %}\n            {% include \"nav-sub.html\" %}\n            {% endfor %}\n          </ul>\n        </li>\n        {% else %}\n        <li {% if nav_item.active %}class=\"active\"{% endif %}>\n          <a href=\"{{ nav_item.url }}\">{{ nav_item.title }}</a>\n        </li>\n        {% endif %}\n        {% endfor %}\n      </ul>\n      {% endif %}\n\n      <ul class=\"nav navbar-nav navbar-right\">\n        {% if repo_url %}\n        <li>\n          <a href=\"{{ repo_url }}\">\n            {% if repo_name == 'GitHub' %}\n            <i class=\"fa fa-github\"></i>\n            {% elif repo_name == 'Bitbucket' %}\n            <i class=\"fa fa-bitbucket\"></i>\n            {% endif %}\n            {{ repo_name }}\n          </a>\n        </li>\n        {% endif %}\n      </ul>\n    </div>\n  </div>\n</div>\n"
  },
  {
    "path": "app_frontend/static/plugin/bootstrap-select-1.12.2/docs/custom_theme/toc.html",
    "content": "<div class=\"bs-sidebar hidden-print affix-top\" role=\"complementary\">\n    <ul class=\"nav bs-sidenav\">\n    {% for toc_item in toc %}\n        <li class=\"main {% if toc_item.active %}active{% endif %}\">\n\t        <a href=\"{{ toc_item.url }}\">{{ toc_item.title }}</a>\n\t        <ul class=\"nav\">\n\t        {% for toc_item in toc_item.children %}\n\t            <li><a href=\"{{ toc_item.url }}\">{{ toc_item.title }}</a></li>\n\t        {% endfor %}\n\t        </ul>\n        </li>\n    {% endfor %}\n    </ul>\n</div>"
  },
  {
    "path": "app_frontend/static/plugin/bootstrap-select-1.12.2/docs/docs/css/custom.css",
    "content": "html {\n  position: relative;\n  min-height: 100%;\n}\nbody {\n  padding-top: 51px;\n  /* Margin bottom by footer height */\n  margin-bottom: 60px;\n}\nlabel {\n  display: block;\n}\n/* hide \"Home\" in navbar */\n.nav.navbar-nav:first-child > li:first-child {\n    display: none;\n}\n\nul.nav li.main {\n  font-weight: normal;\n}\n\n.footer {\n  position: absolute;\n  bottom: 0;\n  width: 100%;\n  /* Set the fixed height of the footer here */\n  height: 60px;\n  background-color: #f5f5f5;\n}\n\n.footer .container .text-muted {\n  margin: 20px 0;\n}\n\n.footer .container {\n  padding-right: 15px;\n  padding-left: 15px;\n}\n\n/* Outline button for use within the docs */\n.btn-outline {\n  color: #337ab7;\n  background-color: transparent;\n  border-color: #337ab7;\n}\n.btn-outline:hover,\n.btn-outline:focus,\n.btn-outline:active {\n  color: #fff;\n  background-color: #337ab7;\n  border-color: #337ab7;\n}\n\n/* Inverted outline button (white on dark) */\n.btn-outline-inverse {\n  color: #fff;\n  background-color: transparent;\n  border-color: #fff;\n}\n.btn-outline-inverse:hover,\n.btn-outline-inverse:focus,\n.btn-outline-inverse:active {\n  color: #337ab7;\n  text-shadow: none;\n  background-color: #fff;\n  border-color: #fff;\n}\n\n.bs-docs-header {\n  margin-bottom: 0;\n  background: #337ab7;\n  color: #fff;\n}\n\n.bs-docs-header .btn {\n  padding: 15px 30px;\n  font-size: 20px\n}\n\n.bs-docs-header h1 {\n  margin-bottom: 30px;\n}\n\n.bs-docs-header .lead {\n  margin: 0 auto 30px;\n}\n\n.bs-docs-sub-header {\n  padding-top: 20px;\n  padding-bottom: 20px;\n}\n\n.gh-btns {\n  margin: 48px 0 -30px;\n  background: rgba(0,0,0,.1);\n  padding: 20px 0 15px;\n}\n\n.content h1:first-of-type,\n.content h1:first-of-type + p:first-of-type {\n  text-align: center;\n}\n\n.bs-docs-example > p {\n  margin-top: 20px;\n}\n\n.bs-docs-example > p:last-child {\n  margin-bottom: 0;\n}\n\n.bs-docs-example .table,\n.bs-docs-example .progress,\n.bs-docs-example .well,\n.bs-docs-example .alert,\n.bs-docs-example .hero-unit,\n.bs-docs-example .pagination,\n.bs-docs-example .navbar,\n.bs-docs-example > .nav,\n.bs-docs-example blockquote {\n  margin-bottom: 5px;\n}\n\n.bs-docs-example .pagination {\n  margin-top: 0;\n}\n\n.special {\n  font-weight: bold !important;\n  color: #fff !important;\n  background: #bc0000 !important;\n  text-transform: uppercase;\n}\n\n.bs-docs-example {\n  position: relative;\n  padding: 45px 15px 15px;\n  margin: 0 -15px 15px;\n  border-color: #e5e5e5 #eee #eee;\n  border-style: solid;\n  border-width: 1px 0;\n  -webkit-box-shadow: inset 0 3px 6px rgba(0,0,0,.05);\n  box-shadow: inset 0 3px 6px rgba(0,0,0,.05);\n}\n\n/* Echo out a label for the example */\n.bs-docs-example:after {\n  position: absolute;\n  top: 15px;\n  left: 15px;\n  font-size: 12px;\n  font-weight: 700;\n  color: #959595;\n  text-transform: uppercase;\n  letter-spacing: 1px;\n  content: \"Example\";\n}\n\n.highlight {\n  padding: 9px 14px;\n  margin-bottom: 14px;\n  background-color: #f7f7f9;\n  border: 1px solid #e1e1e8;\n  border-radius: 4px;\n}\n\n.bs-docs-example + .highlight {\n  margin: -15px -15px 15px;\n  border-width: 0 0 1px;\n  border-radius: 0;\n}\n\n.carbonad {\n  margin-top: 80px;\n}\n\n.carbonad-inner {\n  width: auto!important;\n  height: auto!important;\n  padding: 20px!important;\n  margin: 30px -15px 0!important;\n  overflow: hidden;\n  font-size: 13px!important;\n  line-height: 16px!important;\n  text-align: left;\n  background: 0 0!important;\n  border: solid rgba(255, 255, 255, 0.50) !important;\n  border-width: 1px 0!important;\n}\n\n.carbon-poweredby,\n.carbon-text {\n  display: block!important;\n  float: none!important;\n  width: auto!important;\n  height: auto!important;\n  margin-left: 145px!important;\n  font-family: \"Helvetica Neue\",Helvetica,Arial,sans-serif!important;\n  color: #fff!important;\n}\n\n.carbon-poweredby {\n  float: left;\n  margin-top: 9px;\n  text-align: left;\n  width: 142px;\n  opacity: 0.5;\n}\n\n.charity {\n  opacity: 0.5;\n  padding: 4px;\n  margin-bottom: -31px;\n}\n\n.charity a {\n  color: #fff;\n}\n\n.carbon-img img {\n    border: none;\n    display: inline;\n    float: left;\n    height: 100px;\n    margin: 0 !important;\n    width: 130px;\n}\n\n.logo-block a {\n  display: block;\n  padding: 5px;\n  margin: 5px 0;\n}\n\n.logo-block img {\n  height: auto;\n  max-width: 100%;\n  max-height: 40px;\n}\n\n.logo-container {\n  float: left;\n  max-width: 25%;\n  margin: 0 15px;\n}\n\n.logo-block + div {\n  margin: 5px 0;\n}\n\n@media (min-width: 480px){\n  .carbonad-inner {\n    width: 330px!important;\n    margin: 50px auto 0 !important;\n    border-width: 1px!important;\n    border-radius: 4px;\n  }\n\n  .charity {\n    margin-bottom: 0;\n  }\n\n  .logo-container {\n    max-width: 60%;\n  }\n}\n\n@media (min-width: 768px) {\n  .bs-docs-example {\n    margin-right: 0;\n    margin-left: 0;\n    background-color: #fff;\n    border-color: #ddd;\n    border-width: 1px;\n    border-radius: 4px 4px 0 0;\n    -webkit-box-shadow: none;\n    box-shadow: none;\n  }\n\n  .bs-docs-example.no-code {\n    border-radius: 4px;\n  }\n\n  .bs-docs-example + .highlight {\n    margin-top: -16px;\n    margin-right: 0;\n    margin-left: 0;\n    border-width: 1px;\n    border-bottom-right-radius: 4px;\n    border-bottom-left-radius: 4px;\n  }\n\n  .logo-container {\n    max-width: 33.3333%;\n  }\n\n  .gh-btns {\n    margin-bottom: -48px;\n  }\n}\n\n@media (min-width: 992px){\n  .bs-docs-header .lead {\n      width: 80%;\n  }\n\n  .carbonad-inner {\n    top: 0;\n    right: 15px;\n    width: 330px!important;\n    padding: 15px!important;\n  }\n\n  .logo-container {\n    max-width: 25%;\n  }\n}"
  },
  {
    "path": "app_frontend/static/plugin/bootstrap-select-1.12.2/docs/docs/dist/css/bootstrap-select.css",
    "content": "/*!\n * Bootstrap-select v1.12.2 (http://silviomoreto.github.io/bootstrap-select)\n *\n * Copyright 2013-2017 bootstrap-select\n * Licensed under MIT (https://github.com/silviomoreto/bootstrap-select/blob/master/LICENSE)\n */\n\nselect.bs-select-hidden,\nselect.selectpicker {\n  display: none !important;\n}\n.bootstrap-select {\n  width: 220px \\0;\n  /*IE9 and below*/\n}\n.bootstrap-select > .dropdown-toggle {\n  width: 100%;\n  padding-right: 25px;\n  z-index: 1;\n}\n.bootstrap-select > .dropdown-toggle.bs-placeholder,\n.bootstrap-select > .dropdown-toggle.bs-placeholder:hover,\n.bootstrap-select > .dropdown-toggle.bs-placeholder:focus,\n.bootstrap-select > .dropdown-toggle.bs-placeholder:active {\n  color: #999;\n}\n.bootstrap-select > select {\n  position: absolute !important;\n  bottom: 0;\n  left: 50%;\n  display: block !important;\n  width: 0.5px !important;\n  height: 100% !important;\n  padding: 0 !important;\n  opacity: 0 !important;\n  border: none;\n}\n.bootstrap-select > select.mobile-device {\n  top: 0;\n  left: 0;\n  display: block !important;\n  width: 100% !important;\n  z-index: 2;\n}\n.has-error .bootstrap-select .dropdown-toggle,\n.error .bootstrap-select .dropdown-toggle {\n  border-color: #b94a48;\n}\n.bootstrap-select.fit-width {\n  width: auto !important;\n}\n.bootstrap-select:not([class*=\"col-\"]):not([class*=\"form-control\"]):not(.input-group-btn) {\n  width: 220px;\n}\n.bootstrap-select .dropdown-toggle:focus {\n  outline: thin dotted #333333 !important;\n  outline: 5px auto -webkit-focus-ring-color !important;\n  outline-offset: -2px;\n}\n.bootstrap-select.form-control {\n  margin-bottom: 0;\n  padding: 0;\n  border: none;\n}\n.bootstrap-select.form-control:not([class*=\"col-\"]) {\n  width: 100%;\n}\n.bootstrap-select.form-control.input-group-btn {\n  z-index: auto;\n}\n.bootstrap-select.form-control.input-group-btn:not(:first-child):not(:last-child) > .btn {\n  border-radius: 0;\n}\n.bootstrap-select.btn-group:not(.input-group-btn),\n.bootstrap-select.btn-group[class*=\"col-\"] {\n  float: none;\n  display: inline-block;\n  margin-left: 0;\n}\n.bootstrap-select.btn-group.dropdown-menu-right,\n.bootstrap-select.btn-group[class*=\"col-\"].dropdown-menu-right,\n.row .bootstrap-select.btn-group[class*=\"col-\"].dropdown-menu-right {\n  float: right;\n}\n.form-inline .bootstrap-select.btn-group,\n.form-horizontal .bootstrap-select.btn-group,\n.form-group .bootstrap-select.btn-group {\n  margin-bottom: 0;\n}\n.form-group-lg .bootstrap-select.btn-group.form-control,\n.form-group-sm .bootstrap-select.btn-group.form-control {\n  padding: 0;\n}\n.form-group-lg .bootstrap-select.btn-group.form-control .dropdown-toggle,\n.form-group-sm .bootstrap-select.btn-group.form-control .dropdown-toggle {\n  height: 100%;\n  font-size: inherit;\n  line-height: inherit;\n  border-radius: inherit;\n}\n.form-inline .bootstrap-select.btn-group .form-control {\n  width: 100%;\n}\n.bootstrap-select.btn-group.disabled,\n.bootstrap-select.btn-group > .disabled {\n  cursor: not-allowed;\n}\n.bootstrap-select.btn-group.disabled:focus,\n.bootstrap-select.btn-group > .disabled:focus {\n  outline: none !important;\n}\n.bootstrap-select.btn-group.bs-container {\n  position: absolute;\n  height: 0 !important;\n  padding: 0 !important;\n}\n.bootstrap-select.btn-group.bs-container .dropdown-menu {\n  z-index: 1060;\n}\n.bootstrap-select.btn-group .dropdown-toggle .filter-option {\n  display: inline-block;\n  overflow: hidden;\n  width: 100%;\n  text-align: left;\n}\n.bootstrap-select.btn-group .dropdown-toggle .caret {\n  position: absolute;\n  top: 50%;\n  right: 12px;\n  margin-top: -2px;\n  vertical-align: middle;\n}\n.bootstrap-select.btn-group[class*=\"col-\"] .dropdown-toggle {\n  width: 100%;\n}\n.bootstrap-select.btn-group .dropdown-menu {\n  min-width: 100%;\n  -webkit-box-sizing: border-box;\n     -moz-box-sizing: border-box;\n          box-sizing: border-box;\n}\n.bootstrap-select.btn-group .dropdown-menu.inner {\n  position: static;\n  float: none;\n  border: 0;\n  padding: 0;\n  margin: 0;\n  border-radius: 0;\n  -webkit-box-shadow: none;\n          box-shadow: none;\n}\n.bootstrap-select.btn-group .dropdown-menu li {\n  position: relative;\n}\n.bootstrap-select.btn-group .dropdown-menu li.active small {\n  color: #fff;\n}\n.bootstrap-select.btn-group .dropdown-menu li.disabled a {\n  cursor: not-allowed;\n}\n.bootstrap-select.btn-group .dropdown-menu li a {\n  cursor: pointer;\n  -webkit-user-select: none;\n     -moz-user-select: none;\n      -ms-user-select: none;\n          user-select: none;\n}\n.bootstrap-select.btn-group .dropdown-menu li a.opt {\n  position: relative;\n  padding-left: 2.25em;\n}\n.bootstrap-select.btn-group .dropdown-menu li a span.check-mark {\n  display: none;\n}\n.bootstrap-select.btn-group .dropdown-menu li a span.text {\n  display: inline-block;\n}\n.bootstrap-select.btn-group .dropdown-menu li small {\n  padding-left: 0.5em;\n}\n.bootstrap-select.btn-group .dropdown-menu .notify {\n  position: absolute;\n  bottom: 5px;\n  width: 96%;\n  margin: 0 2%;\n  min-height: 26px;\n  padding: 3px 5px;\n  background: #f5f5f5;\n  border: 1px solid #e3e3e3;\n  -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.05);\n          box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.05);\n  pointer-events: none;\n  opacity: 0.9;\n  -webkit-box-sizing: border-box;\n     -moz-box-sizing: border-box;\n          box-sizing: border-box;\n}\n.bootstrap-select.btn-group .no-results {\n  padding: 3px;\n  background: #f5f5f5;\n  margin: 0 5px;\n  white-space: nowrap;\n}\n.bootstrap-select.btn-group.fit-width .dropdown-toggle .filter-option {\n  position: static;\n}\n.bootstrap-select.btn-group.fit-width .dropdown-toggle .caret {\n  position: static;\n  top: auto;\n  margin-top: -1px;\n}\n.bootstrap-select.btn-group.show-tick .dropdown-menu li.selected a span.check-mark {\n  position: absolute;\n  display: inline-block;\n  right: 15px;\n  margin-top: 5px;\n}\n.bootstrap-select.btn-group.show-tick .dropdown-menu li a span.text {\n  margin-right: 34px;\n}\n.bootstrap-select.show-menu-arrow.open > .dropdown-toggle {\n  z-index: 1061;\n}\n.bootstrap-select.show-menu-arrow .dropdown-toggle:before {\n  content: '';\n  border-left: 7px solid transparent;\n  border-right: 7px solid transparent;\n  border-bottom: 7px solid rgba(204, 204, 204, 0.2);\n  position: absolute;\n  bottom: -4px;\n  left: 9px;\n  display: none;\n}\n.bootstrap-select.show-menu-arrow .dropdown-toggle:after {\n  content: '';\n  border-left: 6px solid transparent;\n  border-right: 6px solid transparent;\n  border-bottom: 6px solid white;\n  position: absolute;\n  bottom: -4px;\n  left: 10px;\n  display: none;\n}\n.bootstrap-select.show-menu-arrow.dropup .dropdown-toggle:before {\n  bottom: auto;\n  top: -3px;\n  border-top: 7px solid rgba(204, 204, 204, 0.2);\n  border-bottom: 0;\n}\n.bootstrap-select.show-menu-arrow.dropup .dropdown-toggle:after {\n  bottom: auto;\n  top: -3px;\n  border-top: 6px solid white;\n  border-bottom: 0;\n}\n.bootstrap-select.show-menu-arrow.pull-right .dropdown-toggle:before {\n  right: 12px;\n  left: auto;\n}\n.bootstrap-select.show-menu-arrow.pull-right .dropdown-toggle:after {\n  right: 13px;\n  left: auto;\n}\n.bootstrap-select.show-menu-arrow.open > .dropdown-toggle:before,\n.bootstrap-select.show-menu-arrow.open > .dropdown-toggle:after {\n  display: block;\n}\n.bs-searchbox,\n.bs-actionsbox,\n.bs-donebutton {\n  padding: 4px 8px;\n}\n.bs-actionsbox {\n  width: 100%;\n  -webkit-box-sizing: border-box;\n     -moz-box-sizing: border-box;\n          box-sizing: border-box;\n}\n.bs-actionsbox .btn-group button {\n  width: 50%;\n}\n.bs-donebutton {\n  float: left;\n  width: 100%;\n  -webkit-box-sizing: border-box;\n     -moz-box-sizing: border-box;\n          box-sizing: border-box;\n}\n.bs-donebutton .btn-group button {\n  width: 100%;\n}\n.bs-searchbox + .bs-actionsbox {\n  padding: 0 8px 4px;\n}\n.bs-searchbox .form-control {\n  margin-bottom: 0;\n  width: 100%;\n  float: none;\n}\n/*# sourceMappingURL=bootstrap-select.css.map */"
  },
  {
    "path": "app_frontend/static/plugin/bootstrap-select-1.12.2/docs/docs/dist/js/bootstrap-select.js",
    "content": "/*!\n * Bootstrap-select v1.12.2 (http://silviomoreto.github.io/bootstrap-select)\n *\n * Copyright 2013-2017 bootstrap-select\n * Licensed under MIT (https://github.com/silviomoreto/bootstrap-select/blob/master/LICENSE)\n */\n\n(function (root, factory) {\n  if (typeof define === 'function' && define.amd) {\n    // AMD. Register as an anonymous module unless amdModuleId is set\n    define([\"jquery\"], function (a0) {\n      return (factory(a0));\n    });\n  } else if (typeof module === 'object' && module.exports) {\n    // Node. Does not work with strict CommonJS, but\n    // only CommonJS-like environments that support module.exports,\n    // like Node.\n    module.exports = factory(require(\"jquery\"));\n  } else {\n    factory(root[\"jQuery\"]);\n  }\n}(this, function (jQuery) {\n\n(function ($) {\n  'use strict';\n\n  //<editor-fold desc=\"Shims\">\n  if (!String.prototype.includes) {\n    (function () {\n      'use strict'; // needed to support `apply`/`call` with `undefined`/`null`\n      var toString = {}.toString;\n      var defineProperty = (function () {\n        // IE 8 only supports `Object.defineProperty` on DOM elements\n        try {\n          var object = {};\n          var $defineProperty = Object.defineProperty;\n          var result = $defineProperty(object, object, object) && $defineProperty;\n        } catch (error) {\n        }\n        return result;\n      }());\n      var indexOf = ''.indexOf;\n      var includes = function (search) {\n        if (this == null) {\n          throw new TypeError();\n        }\n        var string = String(this);\n        if (search && toString.call(search) == '[object RegExp]') {\n          throw new TypeError();\n        }\n        var stringLength = string.length;\n        var searchString = String(search);\n        var searchLength = searchString.length;\n        var position = arguments.length > 1 ? arguments[1] : undefined;\n        // `ToInteger`\n        var pos = position ? Number(position) : 0;\n        if (pos != pos) { // better `isNaN`\n          pos = 0;\n        }\n        var start = Math.min(Math.max(pos, 0), stringLength);\n        // Avoid the `indexOf` call if no match is possible\n        if (searchLength + start > stringLength) {\n          return false;\n        }\n        return indexOf.call(string, searchString, pos) != -1;\n      };\n      if (defineProperty) {\n        defineProperty(String.prototype, 'includes', {\n          'value': includes,\n          'configurable': true,\n          'writable': true\n        });\n      } else {\n        String.prototype.includes = includes;\n      }\n    }());\n  }\n\n  if (!String.prototype.startsWith) {\n    (function () {\n      'use strict'; // needed to support `apply`/`call` with `undefined`/`null`\n      var defineProperty = (function () {\n        // IE 8 only supports `Object.defineProperty` on DOM elements\n        try {\n          var object = {};\n          var $defineProperty = Object.defineProperty;\n          var result = $defineProperty(object, object, object) && $defineProperty;\n        } catch (error) {\n        }\n        return result;\n      }());\n      var toString = {}.toString;\n      var startsWith = function (search) {\n        if (this == null) {\n          throw new TypeError();\n        }\n        var string = String(this);\n        if (search && toString.call(search) == '[object RegExp]') {\n          throw new TypeError();\n        }\n        var stringLength = string.length;\n        var searchString = String(search);\n        var searchLength = searchString.length;\n        var position = arguments.length > 1 ? arguments[1] : undefined;\n        // `ToInteger`\n        var pos = position ? Number(position) : 0;\n        if (pos != pos) { // better `isNaN`\n          pos = 0;\n        }\n        var start = Math.min(Math.max(pos, 0), stringLength);\n        // Avoid the `indexOf` call if no match is possible\n        if (searchLength + start > stringLength) {\n          return false;\n        }\n        var index = -1;\n        while (++index < searchLength) {\n          if (string.charCodeAt(start + index) != searchString.charCodeAt(index)) {\n            return false;\n          }\n        }\n        return true;\n      };\n      if (defineProperty) {\n        defineProperty(String.prototype, 'startsWith', {\n          'value': startsWith,\n          'configurable': true,\n          'writable': true\n        });\n      } else {\n        String.prototype.startsWith = startsWith;\n      }\n    }());\n  }\n\n  if (!Object.keys) {\n    Object.keys = function (\n      o, // object\n      k, // key\n      r  // result array\n      ){\n      // initialize object and result\n      r=[];\n      // iterate over object keys\n      for (k in o)\n          // fill result array with non-prototypical keys\n        r.hasOwnProperty.call(o, k) && r.push(k);\n      // return result\n      return r;\n    };\n  }\n\n  // set data-selected on select element if the value has been programmatically selected\n  // prior to initialization of bootstrap-select\n  // * consider removing or replacing an alternative method *\n  var valHooks = {\n    useDefault: false,\n    _set: $.valHooks.select.set\n  };\n\n  $.valHooks.select.set = function(elem, value) {\n    if (value && !valHooks.useDefault) $(elem).data('selected', true);\n\n    return valHooks._set.apply(this, arguments);\n  };\n\n  var changed_arguments = null;\n  $.fn.triggerNative = function (eventName) {\n    var el = this[0],\n        event;\n\n    if (el.dispatchEvent) { // for modern browsers & IE9+\n      if (typeof Event === 'function') {\n        // For modern browsers\n        event = new Event(eventName, {\n          bubbles: true\n        });\n      } else {\n        // For IE since it doesn't support Event constructor\n        event = document.createEvent('Event');\n        event.initEvent(eventName, true, false);\n      }\n\n      el.dispatchEvent(event);\n    } else if (el.fireEvent) { // for IE8\n      event = document.createEventObject();\n      event.eventType = eventName;\n      el.fireEvent('on' + eventName, event);\n    } else {\n      // fall back to jQuery.trigger\n      this.trigger(eventName);\n    }\n  };\n  //</editor-fold>\n\n  // Case insensitive contains search\n  $.expr.pseudos.icontains = function (obj, index, meta) {\n    var $obj = $(obj);\n    var haystack = ($obj.data('tokens') || $obj.text()).toString().toUpperCase();\n    return haystack.includes(meta[3].toUpperCase());\n  };\n\n  // Case insensitive begins search\n  $.expr.pseudos.ibegins = function (obj, index, meta) {\n    var $obj = $(obj);\n    var haystack = ($obj.data('tokens') || $obj.text()).toString().toUpperCase();\n    return haystack.startsWith(meta[3].toUpperCase());\n  };\n\n  // Case and accent insensitive contains search\n  $.expr.pseudos.aicontains = function (obj, index, meta) {\n    var $obj = $(obj);\n    var haystack = ($obj.data('tokens') || $obj.data('normalizedText') || $obj.text()).toString().toUpperCase();\n    return haystack.includes(meta[3].toUpperCase());\n  };\n\n  // Case and accent insensitive begins search\n  $.expr.pseudos.aibegins = function (obj, index, meta) {\n    var $obj = $(obj);\n    var haystack = ($obj.data('tokens') || $obj.data('normalizedText') || $obj.text()).toString().toUpperCase();\n    return haystack.startsWith(meta[3].toUpperCase());\n  };\n\n  /**\n   * Remove all diatrics from the given text.\n   * @access private\n   * @param {String} text\n   * @returns {String}\n   */\n  function normalizeToBase(text) {\n    var rExps = [\n      {re: /[\\xC0-\\xC6]/g, ch: \"A\"},\n      {re: /[\\xE0-\\xE6]/g, ch: \"a\"},\n      {re: /[\\xC8-\\xCB]/g, ch: \"E\"},\n      {re: /[\\xE8-\\xEB]/g, ch: \"e\"},\n      {re: /[\\xCC-\\xCF]/g, ch: \"I\"},\n      {re: /[\\xEC-\\xEF]/g, ch: \"i\"},\n      {re: /[\\xD2-\\xD6]/g, ch: \"O\"},\n      {re: /[\\xF2-\\xF6]/g, ch: \"o\"},\n      {re: /[\\xD9-\\xDC]/g, ch: \"U\"},\n      {re: /[\\xF9-\\xFC]/g, ch: \"u\"},\n      {re: /[\\xC7-\\xE7]/g, ch: \"c\"},\n      {re: /[\\xD1]/g, ch: \"N\"},\n      {re: /[\\xF1]/g, ch: \"n\"}\n    ];\n    $.each(rExps, function () {\n      text = text ? text.replace(this.re, this.ch) : '';\n    });\n    return text;\n  }\n\n\n  // List of HTML entities for escaping.\n  var escapeMap = {\n    '&': '&amp;',\n    '<': '&lt;',\n    '>': '&gt;',\n    '\"': '&quot;',\n    \"'\": '&#x27;',\n    '`': '&#x60;'\n  };\n  \n  var unescapeMap = {\n    '&amp;': '&',\n    '&lt;': '<',\n    '&gt;': '>',\n    '&quot;': '\"',\n    '&#x27;': \"'\",\n    '&#x60;': '`'\n  };\n\n  // Functions for escaping and unescaping strings to/from HTML interpolation.\n  var createEscaper = function(map) {\n    var escaper = function(match) {\n      return map[match];\n    };\n    // Regexes for identifying a key that needs to be escaped.\n    var source = '(?:' + Object.keys(map).join('|') + ')';\n    var testRegexp = RegExp(source);\n    var replaceRegexp = RegExp(source, 'g');\n    return function(string) {\n      string = string == null ? '' : '' + string;\n      return testRegexp.test(string) ? string.replace(replaceRegexp, escaper) : string;\n    };\n  };\n\n  var htmlEscape = createEscaper(escapeMap);\n  var htmlUnescape = createEscaper(unescapeMap);\n\n  var Selectpicker = function (element, options) {\n    // bootstrap-select has been initialized - revert valHooks.select.set back to its original function\n    if (!valHooks.useDefault) {\n      $.valHooks.select.set = valHooks._set;\n      valHooks.useDefault = true;\n    }\n\n    this.$element = $(element);\n    this.$newElement = null;\n    this.$button = null;\n    this.$menu = null;\n    this.$lis = null;\n    this.options = options;\n\n    // If we have no title yet, try to pull it from the html title attribute (jQuery doesnt' pick it up as it's not a\n    // data-attribute)\n    if (this.options.title === null) {\n      this.options.title = this.$element.attr('title');\n    }\n\n    // Format window padding\n    var winPad = this.options.windowPadding;\n    if (typeof winPad === 'number') {\n      this.options.windowPadding = [winPad, winPad, winPad, winPad];\n    }\n\n    //Expose public methods\n    this.val = Selectpicker.prototype.val;\n    this.render = Selectpicker.prototype.render;\n    this.refresh = Selectpicker.prototype.refresh;\n    this.setStyle = Selectpicker.prototype.setStyle;\n    this.selectAll = Selectpicker.prototype.selectAll;\n    this.deselectAll = Selectpicker.prototype.deselectAll;\n    this.destroy = Selectpicker.prototype.destroy;\n    this.remove = Selectpicker.prototype.remove;\n    this.show = Selectpicker.prototype.show;\n    this.hide = Selectpicker.prototype.hide;\n\n    this.init();\n  };\n\n  Selectpicker.VERSION = '1.12.2';\n\n  // part of this is duplicated in i18n/defaults-en_US.js. Make sure to update both.\n  Selectpicker.DEFAULTS = {\n    noneSelectedText: 'Nothing selected',\n    noneResultsText: 'No results matched {0}',\n    countSelectedText: function (numSelected, numTotal) {\n      return (numSelected == 1) ? \"{0} item selected\" : \"{0} items selected\";\n    },\n    maxOptionsText: function (numAll, numGroup) {\n      return [\n        (numAll == 1) ? 'Limit reached ({n} item max)' : 'Limit reached ({n} items max)',\n        (numGroup == 1) ? 'Group limit reached ({n} item max)' : 'Group limit reached ({n} items max)'\n      ];\n    },\n    selectAllText: 'Select All',\n    deselectAllText: 'Deselect All',\n    doneButton: false,\n    doneButtonText: 'Close',\n    multipleSeparator: ', ',\n    styleBase: 'btn',\n    style: 'btn-default',\n    size: 'auto',\n    title: null,\n    selectedTextFormat: 'values',\n    width: false,\n    container: false,\n    hideDisabled: false,\n    showSubtext: false,\n    showIcon: true,\n    showContent: true,\n    dropupAuto: true,\n    header: false,\n    liveSearch: false,\n    liveSearchPlaceholder: null,\n    liveSearchNormalize: false,\n    liveSearchStyle: 'contains',\n    actionsBox: false,\n    iconBase: 'glyphicon',\n    tickIcon: 'glyphicon-ok',\n    showTick: false,\n    template: {\n      caret: '<span class=\"caret\"></span>'\n    },\n    maxOptions: false,\n    mobile: false,\n    selectOnTab: false,\n    dropdownAlignRight: false,\n    windowPadding: 0\n  };\n\n  Selectpicker.prototype = {\n\n    constructor: Selectpicker,\n\n    init: function () {\n      var that = this,\n          id = this.$element.attr('id');\n\n      this.$element.addClass('bs-select-hidden');\n\n      // store originalIndex (key) and newIndex (value) in this.liObj for fast accessibility\n      // allows us to do this.$lis.eq(that.liObj[index]) instead of this.$lis.filter('[data-original-index=\"' + index + '\"]')\n      this.liObj = {};\n      this.multiple = this.$element.prop('multiple');\n      this.autofocus = this.$element.prop('autofocus');\n      this.$newElement = this.createView();\n      this.$element\n        .after(this.$newElement)\n        .appendTo(this.$newElement);\n      this.$button = this.$newElement.children('button');\n      this.$menu = this.$newElement.children('.dropdown-menu');\n      this.$menuInner = this.$menu.children('.inner');\n      this.$searchbox = this.$menu.find('input');\n\n      this.$element.removeClass('bs-select-hidden');\n\n      if (this.options.dropdownAlignRight === true) this.$menu.addClass('dropdown-menu-right');\n\n      if (typeof id !== 'undefined') {\n        this.$button.attr('data-id', id);\n        $('label[for=\"' + id + '\"]').click(function (e) {\n          e.preventDefault();\n          that.$button.focus();\n        });\n      }\n\n      this.checkDisabled();\n      this.clickListener();\n      if (this.options.liveSearch) this.liveSearchListener();\n      this.render();\n      this.setStyle();\n      this.setWidth();\n      if (this.options.container) this.selectPosition();\n      this.$menu.data('this', this);\n      this.$newElement.data('this', this);\n      if (this.options.mobile) this.mobile();\n\n      this.$newElement.on({\n        'hide.bs.dropdown': function (e) {\n          that.$menuInner.attr('aria-expanded', false);\n          that.$element.trigger('hide.bs.select', e);\n        },\n        'hidden.bs.dropdown': function (e) {\n          that.$element.trigger('hidden.bs.select', e);\n        },\n        'show.bs.dropdown': function (e) {\n          that.$menuInner.attr('aria-expanded', true);\n          that.$element.trigger('show.bs.select', e);\n        },\n        'shown.bs.dropdown': function (e) {\n          that.$element.trigger('shown.bs.select', e);\n        }\n      });\n\n      if (that.$element[0].hasAttribute('required')) {\n        this.$element.on('invalid', function () {\n          that.$button\n            .addClass('bs-invalid')\n            .focus();\n\n          that.$element.on({\n            'focus.bs.select': function () {\n              that.$button.focus();\n              that.$element.off('focus.bs.select');\n            },\n            'shown.bs.select': function () {\n              that.$element\n                .val(that.$element.val()) // set the value to hide the validation message in Chrome when menu is opened\n                .off('shown.bs.select');\n            },\n            'rendered.bs.select': function () {\n              // if select is no longer invalid, remove the bs-invalid class\n              if (this.validity.valid) that.$button.removeClass('bs-invalid');\n              that.$element.off('rendered.bs.select');\n            }\n          });\n        });\n      }\n\n      setTimeout(function () {\n        that.$element.trigger('loaded.bs.select');\n      });\n    },\n\n    createDropdown: function () {\n      // Options\n      // If we are multiple or showTick option is set, then add the show-tick class\n      var showTick = (this.multiple || this.options.showTick) ? ' show-tick' : '',\n          inputGroup = this.$element.parent().hasClass('input-group') ? ' input-group-btn' : '',\n          autofocus = this.autofocus ? ' autofocus' : '';\n      // Elements\n      var header = this.options.header ? '<div class=\"popover-title\"><button type=\"button\" class=\"close\" aria-hidden=\"true\">&times;</button>' + this.options.header + '</div>' : '';\n      var searchbox = this.options.liveSearch ?\n      '<div class=\"bs-searchbox\">' +\n      '<input type=\"text\" class=\"form-control\" autocomplete=\"off\"' +\n      (null === this.options.liveSearchPlaceholder ? '' : ' placeholder=\"' + htmlEscape(this.options.liveSearchPlaceholder) + '\"') + ' role=\"textbox\" aria-label=\"Search\">' +\n      '</div>'\n          : '';\n      var actionsbox = this.multiple && this.options.actionsBox ?\n      '<div class=\"bs-actionsbox\">' +\n      '<div class=\"btn-group btn-group-sm btn-block\">' +\n      '<button type=\"button\" class=\"actions-btn bs-select-all btn btn-default\">' +\n      this.options.selectAllText +\n      '</button>' +\n      '<button type=\"button\" class=\"actions-btn bs-deselect-all btn btn-default\">' +\n      this.options.deselectAllText +\n      '</button>' +\n      '</div>' +\n      '</div>'\n          : '';\n      var donebutton = this.multiple && this.options.doneButton ?\n      '<div class=\"bs-donebutton\">' +\n      '<div class=\"btn-group btn-block\">' +\n      '<button type=\"button\" class=\"btn btn-sm btn-default\">' +\n      this.options.doneButtonText +\n      '</button>' +\n      '</div>' +\n      '</div>'\n          : '';\n      var drop =\n          '<div class=\"btn-group bootstrap-select' + showTick + inputGroup + '\">' +\n          '<button type=\"button\" class=\"' + this.options.styleBase + ' dropdown-toggle\" data-toggle=\"dropdown\"' + autofocus + ' role=\"button\">' +\n          '<span class=\"filter-option pull-left\"></span>&nbsp;' +\n          '<span class=\"bs-caret\">' +\n          this.options.template.caret +\n          '</span>' +\n          '</button>' +\n          '<div class=\"dropdown-menu open\" role=\"combobox\">' +\n          header +\n          searchbox +\n          actionsbox +\n          '<ul class=\"dropdown-menu inner\" role=\"listbox\" aria-expanded=\"false\">' +\n          '</ul>' +\n          donebutton +\n          '</div>' +\n          '</div>';\n\n      return $(drop);\n    },\n\n    createView: function () {\n      var $drop = this.createDropdown(),\n          li = this.createLi();\n\n      $drop.find('ul')[0].innerHTML = li;\n      return $drop;\n    },\n\n    reloadLi: function () {\n      // rebuild\n      var li = this.createLi();\n      this.$menuInner[0].innerHTML = li;\n    },\n\n    createLi: function () {\n      var that = this,\n          _li = [],\n          optID = 0,\n          titleOption = document.createElement('option'),\n          liIndex = -1; // increment liIndex whenever a new <li> element is created to ensure liObj is correct\n\n      // Helper functions\n      /**\n       * @param content\n       * @param [index]\n       * @param [classes]\n       * @param [optgroup]\n       * @returns {string}\n       */\n      var generateLI = function (content, index, classes, optgroup) {\n        return '<li' +\n            ((typeof classes !== 'undefined' & '' !== classes) ? ' class=\"' + classes + '\"' : '') +\n            ((typeof index !== 'undefined' & null !== index) ? ' data-original-index=\"' + index + '\"' : '') +\n            ((typeof optgroup !== 'undefined' & null !== optgroup) ? 'data-optgroup=\"' + optgroup + '\"' : '') +\n            '>' + content + '</li>';\n      };\n\n      /**\n       * @param text\n       * @param [classes]\n       * @param [inline]\n       * @param [tokens]\n       * @returns {string}\n       */\n      var generateA = function (text, classes, inline, tokens) {\n        return '<a tabindex=\"0\"' +\n            (typeof classes !== 'undefined' ? ' class=\"' + classes + '\"' : '') +\n            (inline ? ' style=\"' + inline + '\"' : '') +\n            (that.options.liveSearchNormalize ? ' data-normalized-text=\"' + normalizeToBase(htmlEscape($(text).html())) + '\"' : '') +\n            (typeof tokens !== 'undefined' || tokens !== null ? ' data-tokens=\"' + tokens + '\"' : '') +\n            ' role=\"option\">' + text +\n            '<span class=\"' + that.options.iconBase + ' ' + that.options.tickIcon + ' check-mark\"></span>' +\n            '</a>';\n      };\n\n      if (this.options.title && !this.multiple) {\n        // this option doesn't create a new <li> element, but does add a new option, so liIndex is decreased\n        // since liObj is recalculated on every refresh, liIndex needs to be decreased even if the titleOption is already appended\n        liIndex--;\n\n        if (!this.$element.find('.bs-title-option').length) {\n          // Use native JS to prepend option (faster)\n          var element = this.$element[0];\n          titleOption.className = 'bs-title-option';\n          titleOption.innerHTML = this.options.title;\n          titleOption.value = '';\n          element.insertBefore(titleOption, element.firstChild);\n          // Check if selected or data-selected attribute is already set on an option. If not, select the titleOption option.\n          // the selected item may have been changed by user or programmatically before the bootstrap select plugin runs,\n          // if so, the select will have the data-selected attribute\n          var $opt = $(element.options[element.selectedIndex]);\n          if ($opt.attr('selected') === undefined && this.$element.data('selected') === undefined) {\n            titleOption.selected = true;\n          }\n        }\n      }\n\n      this.$element.find('option').each(function (index) {\n        var $this = $(this);\n\n        liIndex++;\n\n        if ($this.hasClass('bs-title-option')) return;\n\n        // Get the class and text for the option\n        var optionClass = this.className || '',\n            inline = this.style.cssText,\n            text = $this.data('content') ? $this.data('content') : $this.html(),\n            tokens = $this.data('tokens') ? $this.data('tokens') : null,\n            subtext = typeof $this.data('subtext') !== 'undefined' ? '<small class=\"text-muted\">' + $this.data('subtext') + '</small>' : '',\n            icon = typeof $this.data('icon') !== 'undefined' ? '<span class=\"' + that.options.iconBase + ' ' + $this.data('icon') + '\"></span> ' : '',\n            $parent = $this.parent(),\n            isOptgroup = $parent[0].tagName === 'OPTGROUP',\n            isOptgroupDisabled = isOptgroup && $parent[0].disabled,\n            isDisabled = this.disabled || isOptgroupDisabled;\n\n        if (icon !== '' && isDisabled) {\n          icon = '<span>' + icon + '</span>';\n        }\n\n        if (that.options.hideDisabled && (isDisabled && !isOptgroup || isOptgroupDisabled)) {\n          liIndex--;\n          return;\n        }\n\n        if (!$this.data('content')) {\n          // Prepend any icon and append any subtext to the main text.\n          text = icon + '<span class=\"text\">' + text + subtext + '</span>';\n        }\n\n        if (isOptgroup && $this.data('divider') !== true) {\n          if (that.options.hideDisabled && isDisabled) {\n            if ($parent.data('allOptionsDisabled') === undefined) {\n              var $options = $parent.children();\n              $parent.data('allOptionsDisabled', $options.filter(':disabled').length === $options.length);\n            }\n\n            if ($parent.data('allOptionsDisabled')) {\n              liIndex--;\n              return;\n            }\n          }\n\n          var optGroupClass = ' ' + $parent[0].className || '';\n\n          if ($this.index() === 0) { // Is it the first option of the optgroup?\n            optID += 1;\n\n            // Get the opt group label\n            var label = $parent[0].label,\n                labelSubtext = typeof $parent.data('subtext') !== 'undefined' ? '<small class=\"text-muted\">' + $parent.data('subtext') + '</small>' : '',\n                labelIcon = $parent.data('icon') ? '<span class=\"' + that.options.iconBase + ' ' + $parent.data('icon') + '\"></span> ' : '';\n\n            label = labelIcon + '<span class=\"text\">' + htmlEscape(label) + labelSubtext + '</span>';\n\n            if (index !== 0 && _li.length > 0) { // Is it NOT the first option of the select && are there elements in the dropdown?\n              liIndex++;\n              _li.push(generateLI('', null, 'divider', optID + 'div'));\n            }\n            liIndex++;\n            _li.push(generateLI(label, null, 'dropdown-header' + optGroupClass, optID));\n          }\n\n          if (that.options.hideDisabled && isDisabled) {\n            liIndex--;\n            return;\n          }\n\n          _li.push(generateLI(generateA(text, 'opt ' + optionClass + optGroupClass, inline, tokens), index, '', optID));\n        } else if ($this.data('divider') === true) {\n          _li.push(generateLI('', index, 'divider'));\n        } else if ($this.data('hidden') === true) {\n          _li.push(generateLI(generateA(text, optionClass, inline, tokens), index, 'hidden is-hidden'));\n        } else {\n          var showDivider = this.previousElementSibling && this.previousElementSibling.tagName === 'OPTGROUP';\n\n          // if previous element is not an optgroup and hideDisabled is true\n          if (!showDivider && that.options.hideDisabled) {\n            // get previous elements\n            var $prev = $(this).prevAll();\n\n            for (var i = 0; i < $prev.length; i++) {\n              // find the first element in the previous elements that is an optgroup\n              if ($prev[i].tagName === 'OPTGROUP') {\n                var optGroupDistance = 0;\n\n                // loop through the options in between the current option and the optgroup\n                // and check if they are hidden or disabled\n                for (var d = 0; d < i; d++) {\n                  var prevOption = $prev[d];\n                  if (prevOption.disabled || $(prevOption).data('hidden') === true) optGroupDistance++;\n                }\n\n                // if all of the options between the current option and the optgroup are hidden or disabled, show the divider\n                if (optGroupDistance === i) showDivider = true;\n\n                break;\n              }\n            }\n          }\n\n          if (showDivider) {\n            liIndex++;\n            _li.push(generateLI('', null, 'divider', optID + 'div'));\n          }\n          _li.push(generateLI(generateA(text, optionClass, inline, tokens), index));\n        }\n\n        that.liObj[index] = liIndex;\n      });\n\n      //If we are not multiple, we don't have a selected item, and we don't have a title, select the first element so something is set in the button\n      if (!this.multiple && this.$element.find('option:selected').length === 0 && !this.options.title) {\n        this.$element.find('option').eq(0).prop('selected', true).attr('selected', 'selected');\n      }\n\n      return _li.join('');\n    },\n\n    findLis: function () {\n      if (this.$lis == null) this.$lis = this.$menu.find('li');\n      return this.$lis;\n    },\n\n    /**\n     * @param [updateLi] defaults to true\n     */\n    render: function (updateLi) {\n      var that = this,\n          notDisabled;\n\n      //Update the LI to match the SELECT\n      if (updateLi !== false) {\n        this.$element.find('option').each(function (index) {\n          var $lis = that.findLis().eq(that.liObj[index]);\n\n          that.setDisabled(index, this.disabled || this.parentNode.tagName === 'OPTGROUP' && this.parentNode.disabled, $lis);\n          that.setSelected(index, this.selected, $lis);\n        });\n      }\n\n      this.togglePlaceholder();\n\n      this.tabIndex();\n\n      var selectedItems = this.$element.find('option').map(function () {\n        if (this.selected) {\n          if (that.options.hideDisabled && (this.disabled || this.parentNode.tagName === 'OPTGROUP' && this.parentNode.disabled)) return;\n\n          var $this = $(this),\n              icon = $this.data('icon') && that.options.showIcon ? '<i class=\"' + that.options.iconBase + ' ' + $this.data('icon') + '\"></i> ' : '',\n              subtext;\n\n          if (that.options.showSubtext && $this.data('subtext') && !that.multiple) {\n            subtext = ' <small class=\"text-muted\">' + $this.data('subtext') + '</small>';\n          } else {\n            subtext = '';\n          }\n          if (typeof $this.attr('title') !== 'undefined') {\n            return $this.attr('title');\n          } else if ($this.data('content') && that.options.showContent) {\n            return $this.data('content').toString();\n          } else {\n            return icon + $this.html() + subtext;\n          }\n        }\n      }).toArray();\n\n      //Fixes issue in IE10 occurring when no default option is selected and at least one option is disabled\n      //Convert all the values into a comma delimited string\n      var title = !this.multiple ? selectedItems[0] : selectedItems.join(this.options.multipleSeparator);\n\n      //If this is multi select, and the selectText type is count, the show 1 of 2 selected etc..\n      if (this.multiple && this.options.selectedTextFormat.indexOf('count') > -1) {\n        var max = this.options.selectedTextFormat.split('>');\n        if ((max.length > 1 && selectedItems.length > max[1]) || (max.length == 1 && selectedItems.length >= 2)) {\n          notDisabled = this.options.hideDisabled ? ', [disabled]' : '';\n          var totalCount = this.$element.find('option').not('[data-divider=\"true\"], [data-hidden=\"true\"]' + notDisabled).length,\n              tr8nText = (typeof this.options.countSelectedText === 'function') ? this.options.countSelectedText(selectedItems.length, totalCount) : this.options.countSelectedText;\n          title = tr8nText.replace('{0}', selectedItems.length.toString()).replace('{1}', totalCount.toString());\n        }\n      }\n\n      if (this.options.title == undefined) {\n        this.options.title = this.$element.attr('title');\n      }\n\n      if (this.options.selectedTextFormat == 'static') {\n        title = this.options.title;\n      }\n\n      //If we dont have a title, then use the default, or if nothing is set at all, use the not selected text\n      if (!title) {\n        title = typeof this.options.title !== 'undefined' ? this.options.title : this.options.noneSelectedText;\n      }\n\n      //strip all HTML tags and trim the result, then unescape any escaped tags\n      this.$button.attr('title', htmlUnescape($.trim(title.replace(/<[^>]*>?/g, ''))));\n      this.$button.children('.filter-option').html(title);\n\n      this.$element.trigger('rendered.bs.select');\n    },\n\n    /**\n     * @param [style]\n     * @param [status]\n     */\n    setStyle: function (style, status) {\n      if (this.$element.attr('class')) {\n        this.$newElement.addClass(this.$element.attr('class').replace(/selectpicker|mobile-device|bs-select-hidden|validate\\[.*\\]/gi, ''));\n      }\n\n      var buttonClass = style ? style : this.options.style;\n\n      if (status == 'add') {\n        this.$button.addClass(buttonClass);\n      } else if (status == 'remove') {\n        this.$button.removeClass(buttonClass);\n      } else {\n        this.$button.removeClass(this.options.style);\n        this.$button.addClass(buttonClass);\n      }\n    },\n\n    liHeight: function (refresh) {\n      if (!refresh && (this.options.size === false || this.sizeInfo)) return;\n\n      var newElement = document.createElement('div'),\n          menu = document.createElement('div'),\n          menuInner = document.createElement('ul'),\n          divider = document.createElement('li'),\n          li = document.createElement('li'),\n          a = document.createElement('a'),\n          text = document.createElement('span'),\n          header = this.options.header && this.$menu.find('.popover-title').length > 0 ? this.$menu.find('.popover-title')[0].cloneNode(true) : null,\n          search = this.options.liveSearch ? document.createElement('div') : null,\n          actions = this.options.actionsBox && this.multiple && this.$menu.find('.bs-actionsbox').length > 0 ? this.$menu.find('.bs-actionsbox')[0].cloneNode(true) : null,\n          doneButton = this.options.doneButton && this.multiple && this.$menu.find('.bs-donebutton').length > 0 ? this.$menu.find('.bs-donebutton')[0].cloneNode(true) : null;\n\n      text.className = 'text';\n      newElement.className = this.$menu[0].parentNode.className + ' open';\n      menu.className = 'dropdown-menu open';\n      menuInner.className = 'dropdown-menu inner';\n      divider.className = 'divider';\n\n      text.appendChild(document.createTextNode('Inner text'));\n      a.appendChild(text);\n      li.appendChild(a);\n      menuInner.appendChild(li);\n      menuInner.appendChild(divider);\n      if (header) menu.appendChild(header);\n      if (search) {\n        var input = document.createElement('input');\n        search.className = 'bs-searchbox';\n        input.className = 'form-control';\n        search.appendChild(input);\n        menu.appendChild(search);\n      }\n      if (actions) menu.appendChild(actions);\n      menu.appendChild(menuInner);\n      if (doneButton) menu.appendChild(doneButton);\n      newElement.appendChild(menu);\n\n      document.body.appendChild(newElement);\n\n      var liHeight = a.offsetHeight,\n          headerHeight = header ? header.offsetHeight : 0,\n          searchHeight = search ? search.offsetHeight : 0,\n          actionsHeight = actions ? actions.offsetHeight : 0,\n          doneButtonHeight = doneButton ? doneButton.offsetHeight : 0,\n          dividerHeight = $(divider).outerHeight(true),\n          // fall back to jQuery if getComputedStyle is not supported\n          menuStyle = typeof getComputedStyle === 'function' ? getComputedStyle(menu) : false,\n          $menu = menuStyle ? null : $(menu),\n          menuPadding = {\n            vert: parseInt(menuStyle ? menuStyle.paddingTop : $menu.css('paddingTop')) +\n                  parseInt(menuStyle ? menuStyle.paddingBottom : $menu.css('paddingBottom')) +\n                  parseInt(menuStyle ? menuStyle.borderTopWidth : $menu.css('borderTopWidth')) +\n                  parseInt(menuStyle ? menuStyle.borderBottomWidth : $menu.css('borderBottomWidth')),\n            horiz: parseInt(menuStyle ? menuStyle.paddingLeft : $menu.css('paddingLeft')) +\n                  parseInt(menuStyle ? menuStyle.paddingRight : $menu.css('paddingRight')) +\n                  parseInt(menuStyle ? menuStyle.borderLeftWidth : $menu.css('borderLeftWidth')) +\n                  parseInt(menuStyle ? menuStyle.borderRightWidth : $menu.css('borderRightWidth'))\n          },\n          menuExtras =  {\n            vert: menuPadding.vert +\n                  parseInt(menuStyle ? menuStyle.marginTop : $menu.css('marginTop')) +\n                  parseInt(menuStyle ? menuStyle.marginBottom : $menu.css('marginBottom')) + 2,\n            horiz: menuPadding.horiz +\n                  parseInt(menuStyle ? menuStyle.marginLeft : $menu.css('marginLeft')) +\n                  parseInt(menuStyle ? menuStyle.marginRight : $menu.css('marginRight')) + 2\n          }\n\n      document.body.removeChild(newElement);\n\n      this.sizeInfo = {\n        liHeight: liHeight,\n        headerHeight: headerHeight,\n        searchHeight: searchHeight,\n        actionsHeight: actionsHeight,\n        doneButtonHeight: doneButtonHeight,\n        dividerHeight: dividerHeight,\n        menuPadding: menuPadding,\n        menuExtras: menuExtras\n      };\n    },\n\n    setSize: function () {\n      this.findLis();\n      this.liHeight();\n\n      if (this.options.header) this.$menu.css('padding-top', 0);\n      if (this.options.size === false) return;\n\n      var that = this,\n          $menu = this.$menu,\n          $menuInner = this.$menuInner,\n          $window = $(window),\n          selectHeight = this.$newElement[0].offsetHeight,\n          selectWidth = this.$newElement[0].offsetWidth,\n          liHeight = this.sizeInfo['liHeight'],\n          headerHeight = this.sizeInfo['headerHeight'],\n          searchHeight = this.sizeInfo['searchHeight'],\n          actionsHeight = this.sizeInfo['actionsHeight'],\n          doneButtonHeight = this.sizeInfo['doneButtonHeight'],\n          divHeight = this.sizeInfo['dividerHeight'],\n          menuPadding = this.sizeInfo['menuPadding'],\n          menuExtras = this.sizeInfo['menuExtras'],\n          notDisabled = this.options.hideDisabled ? '.disabled' : '',\n          menuHeight,\n          menuWidth,\n          getHeight,\n          getWidth,\n          selectOffsetTop,\n          selectOffsetBot,\n          selectOffsetLeft,\n          selectOffsetRight,\n          getPos = function() {\n            var pos = that.$newElement.offset(),\n                $container = $(that.options.container),\n                containerPos;\n\n            if (that.options.container && !$container.is('body')) {\n              containerPos = $container.offset();\n              containerPos.top += parseInt($container.css('borderTopWidth'));\n              containerPos.left += parseInt($container.css('borderLeftWidth'));\n            } else {\n              containerPos = { top: 0, left: 0 };\n            }\n\n            var winPad = that.options.windowPadding;\n            selectOffsetTop = pos.top - containerPos.top - $window.scrollTop();\n            selectOffsetBot = $window.height() - selectOffsetTop - selectHeight - containerPos.top - winPad[2];\n            selectOffsetLeft = pos.left - containerPos.left - $window.scrollLeft();\n            selectOffsetRight = $window.width() - selectOffsetLeft - selectWidth - containerPos.left - winPad[1];\n            selectOffsetTop -= winPad[0];\n            selectOffsetLeft -= winPad[3];\n          };\n\n      getPos();\n\n      if (this.options.size === 'auto') {\n        var getSize = function () {\n          var minHeight,\n              hasClass = function (className, include) {\n                return function (element) {\n                    if (include) {\n                        return (element.classList ? element.classList.contains(className) : $(element).hasClass(className));\n                    } else {\n                        return !(element.classList ? element.classList.contains(className) : $(element).hasClass(className));\n                    }\n                };\n              },\n              lis = that.$menuInner[0].getElementsByTagName('li'),\n              lisVisible = Array.prototype.filter ? Array.prototype.filter.call(lis, hasClass('hidden', false)) : that.$lis.not('.hidden'),\n              optGroup = Array.prototype.filter ? Array.prototype.filter.call(lisVisible, hasClass('dropdown-header', true)) : lisVisible.filter('.dropdown-header');\n\n          getPos();\n          menuHeight = selectOffsetBot - menuExtras.vert;\n          menuWidth = selectOffsetRight - menuExtras.horiz;\n\n          if (that.options.container) {\n            if (!$menu.data('height')) $menu.data('height', $menu.height());\n            getHeight = $menu.data('height');\n\n            if (!$menu.data('width')) $menu.data('width', $menu.width());\n            getWidth = $menu.data('width');\n          } else {\n            getHeight = $menu.height();\n            getWidth = $menu.width();\n          }\n\n          if (that.options.dropupAuto) {\n            that.$newElement.toggleClass('dropup', selectOffsetTop > selectOffsetBot && (menuHeight - menuExtras.vert) < getHeight);\n          }\n\n          if (that.$newElement.hasClass('dropup')) {\n            menuHeight = selectOffsetTop - menuExtras.vert;\n          }\n\n          if (that.options.dropdownAlignRight === 'auto') {\n            $menu.toggleClass('dropdown-menu-right', selectOffsetLeft > selectOffsetRight && (menuWidth - menuExtras.horiz) < (getWidth - selectWidth));\n          }\n\n          if ((lisVisible.length + optGroup.length) > 3) {\n            minHeight = liHeight * 3 + menuExtras.vert - 2;\n          } else {\n            minHeight = 0;\n          }\n\n          $menu.css({\n            'max-height': menuHeight + 'px',\n            'overflow': 'hidden',\n            'min-height': minHeight + headerHeight + searchHeight + actionsHeight + doneButtonHeight + 'px'\n          });\n          $menuInner.css({\n            'max-height': menuHeight - headerHeight - searchHeight - actionsHeight - doneButtonHeight - menuPadding.vert + 'px',\n            'overflow-y': 'auto',\n            'min-height': Math.max(minHeight - menuPadding.vert, 0) + 'px'\n          });\n        };\n        getSize();\n        this.$searchbox.off('input.getSize propertychange.getSize').on('input.getSize propertychange.getSize', getSize);\n        $window.off('resize.getSize scroll.getSize').on('resize.getSize scroll.getSize', getSize);\n      } else if (this.options.size && this.options.size != 'auto' && this.$lis.not(notDisabled).length > this.options.size) {\n        var optIndex = this.$lis.not('.divider').not(notDisabled).children().slice(0, this.options.size).last().parent().index(),\n            divLength = this.$lis.slice(0, optIndex + 1).filter('.divider').length;\n        menuHeight = liHeight * this.options.size + divLength * divHeight + menuPadding.vert;\n\n        if (that.options.container) {\n          if (!$menu.data('height')) $menu.data('height', $menu.height());\n          getHeight = $menu.data('height');\n        } else {\n          getHeight = $menu.height();\n        }\n\n        if (that.options.dropupAuto) {\n          //noinspection JSUnusedAssignment\n          this.$newElement.toggleClass('dropup', selectOffsetTop > selectOffsetBot && (menuHeight - menuExtras.vert) < getHeight);\n        }\n        $menu.css({\n          'max-height': menuHeight + headerHeight + searchHeight + actionsHeight + doneButtonHeight + 'px',\n          'overflow': 'hidden',\n          'min-height': ''\n        });\n        $menuInner.css({\n          'max-height': menuHeight - menuPadding.vert + 'px',\n          'overflow-y': 'auto',\n          'min-height': ''\n        });\n      }\n    },\n\n    setWidth: function () {\n      if (this.options.width === 'auto') {\n        this.$menu.css('min-width', '0');\n\n        // Get correct width if element is hidden\n        var $selectClone = this.$menu.parent().clone().appendTo('body'),\n            $selectClone2 = this.options.container ? this.$newElement.clone().appendTo('body') : $selectClone,\n            ulWidth = $selectClone.children('.dropdown-menu').outerWidth(),\n            btnWidth = $selectClone2.css('width', 'auto').children('button').outerWidth();\n\n        $selectClone.remove();\n        $selectClone2.remove();\n\n        // Set width to whatever's larger, button title or longest option\n        this.$newElement.css('width', Math.max(ulWidth, btnWidth) + 'px');\n      } else if (this.options.width === 'fit') {\n        // Remove inline min-width so width can be changed from 'auto'\n        this.$menu.css('min-width', '');\n        this.$newElement.css('width', '').addClass('fit-width');\n      } else if (this.options.width) {\n        // Remove inline min-width so width can be changed from 'auto'\n        this.$menu.css('min-width', '');\n        this.$newElement.css('width', this.options.width);\n      } else {\n        // Remove inline min-width/width so width can be changed\n        this.$menu.css('min-width', '');\n        this.$newElement.css('width', '');\n      }\n      // Remove fit-width class if width is changed programmatically\n      if (this.$newElement.hasClass('fit-width') && this.options.width !== 'fit') {\n        this.$newElement.removeClass('fit-width');\n      }\n    },\n\n    selectPosition: function () {\n      this.$bsContainer = $('<div class=\"bs-container\" />');\n\n      var that = this,\n          $container = $(this.options.container),\n          pos,\n          containerPos,\n          actualHeight,\n          getPlacement = function ($element) {\n            that.$bsContainer.addClass($element.attr('class').replace(/form-control|fit-width/gi, '')).toggleClass('dropup', $element.hasClass('dropup'));\n            pos = $element.offset();\n\n            if (!$container.is('body')) {\n              containerPos = $container.offset();\n              containerPos.top += parseInt($container.css('borderTopWidth')) - $container.scrollTop();\n              containerPos.left += parseInt($container.css('borderLeftWidth')) - $container.scrollLeft();\n            } else {\n              containerPos = { top: 0, left: 0 };\n            }\n\n            actualHeight = $element.hasClass('dropup') ? 0 : $element[0].offsetHeight;\n\n            that.$bsContainer.css({\n              'top': pos.top - containerPos.top + actualHeight,\n              'left': pos.left - containerPos.left,\n              'width': $element[0].offsetWidth\n            });\n          };\n\n      this.$button.on('click', function () {\n        var $this = $(this);\n\n        if (that.isDisabled()) {\n          return;\n        }\n\n        getPlacement(that.$newElement);\n\n        that.$bsContainer\n          .appendTo(that.options.container)\n          .toggleClass('open', !$this.hasClass('open'))\n          .append(that.$menu);\n      });\n\n      $(window).on('resize scroll', function () {\n        getPlacement(that.$newElement);\n      });\n\n      this.$element.on('hide.bs.select', function () {\n        that.$menu.data('height', that.$menu.height());\n        that.$bsContainer.detach();\n      });\n    },\n\n    /**\n     * @param {number} index - the index of the option that is being changed\n     * @param {boolean} selected - true if the option is being selected, false if being deselected\n     * @param {JQuery} $lis - the 'li' element that is being modified\n     */\n    setSelected: function (index, selected, $lis) {\n      if (!$lis) {\n        this.togglePlaceholder(); // check if setSelected is being called by changing the value of the select\n        $lis = this.findLis().eq(this.liObj[index]);\n      }\n\n      $lis.toggleClass('selected', selected).find('a').attr('aria-selected', selected);\n    },\n\n    /**\n     * @param {number} index - the index of the option that is being disabled\n     * @param {boolean} disabled - true if the option is being disabled, false if being enabled\n     * @param {JQuery} $lis - the 'li' element that is being modified\n     */\n    setDisabled: function (index, disabled, $lis) {\n      if (!$lis) {\n        $lis = this.findLis().eq(this.liObj[index]);\n      }\n\n      if (disabled) {\n        $lis.addClass('disabled').children('a').attr('href', '#').attr('tabindex', -1).attr('aria-disabled', true);\n      } else {\n        $lis.removeClass('disabled').children('a').removeAttr('href').attr('tabindex', 0).attr('aria-disabled', false);\n      }\n    },\n\n    isDisabled: function () {\n      return this.$element[0].disabled;\n    },\n\n    checkDisabled: function () {\n      var that = this;\n\n      if (this.isDisabled()) {\n        this.$newElement.addClass('disabled');\n        this.$button.addClass('disabled').attr('tabindex', -1).attr('aria-disabled', true);\n      } else {\n        if (this.$button.hasClass('disabled')) {\n          this.$newElement.removeClass('disabled');\n          this.$button.removeClass('disabled').attr('aria-disabled', false);\n        }\n\n        if (this.$button.attr('tabindex') == -1 && !this.$element.data('tabindex')) {\n          this.$button.removeAttr('tabindex');\n        }\n      }\n\n      this.$button.click(function () {\n        return !that.isDisabled();\n      });\n    },\n\n    togglePlaceholder: function () {\n      var value = this.$element.val();\n      this.$button.toggleClass('bs-placeholder', value === null || value === '' || (value.constructor === Array && value.length === 0));\n    },\n\n    tabIndex: function () {\n      if (this.$element.data('tabindex') !== this.$element.attr('tabindex') && \n        (this.$element.attr('tabindex') !== -98 && this.$element.attr('tabindex') !== '-98')) {\n        this.$element.data('tabindex', this.$element.attr('tabindex'));\n        this.$button.attr('tabindex', this.$element.data('tabindex'));\n      }\n\n      this.$element.attr('tabindex', -98);\n    },\n\n    clickListener: function () {\n      var that = this,\n          $document = $(document);\n\n      $document.data('spaceSelect', false);\n\n      this.$button.on('keyup', function (e) {\n        if (/(32)/.test(e.keyCode.toString(10)) && $document.data('spaceSelect')) {\n            e.preventDefault();\n            $document.data('spaceSelect', false);\n        }\n      });\n\n      this.$button.on('click', function () {\n        that.setSize();\n      });\n\n      this.$element.on('shown.bs.select', function () {\n        if (!that.options.liveSearch && !that.multiple) {\n          that.$menuInner.find('.selected a').focus();\n        } else if (!that.multiple) {\n          var selectedIndex = that.liObj[that.$element[0].selectedIndex];\n\n          if (typeof selectedIndex !== 'number' || that.options.size === false) return;\n\n          // scroll to selected option\n          var offset = that.$lis.eq(selectedIndex)[0].offsetTop - that.$menuInner[0].offsetTop;\n          offset = offset - that.$menuInner[0].offsetHeight/2 + that.sizeInfo.liHeight/2;\n          that.$menuInner[0].scrollTop = offset;\n        }\n      });\n\n      this.$menuInner.on('click', 'li a', function (e) {\n        var $this = $(this),\n            clickedIndex = $this.parent().data('originalIndex'),\n            prevValue = that.$element.val(),\n            prevIndex = that.$element.prop('selectedIndex'),\n            triggerChange = true;\n\n        // Don't close on multi choice menu\n        if (that.multiple && that.options.maxOptions !== 1) {\n          e.stopPropagation();\n        }\n\n        e.preventDefault();\n\n        //Don't run if we have been disabled\n        if (!that.isDisabled() && !$this.parent().hasClass('disabled')) {\n          var $options = that.$element.find('option'),\n              $option = $options.eq(clickedIndex),\n              state = $option.prop('selected'),\n              $optgroup = $option.parent('optgroup'),\n              maxOptions = that.options.maxOptions,\n              maxOptionsGrp = $optgroup.data('maxOptions') || false;\n\n          if (!that.multiple) { // Deselect all others if not multi select box\n            $options.prop('selected', false);\n            $option.prop('selected', true);\n            that.$menuInner.find('.selected').removeClass('selected').find('a').attr('aria-selected', false);\n            that.setSelected(clickedIndex, true);\n          } else { // Toggle the one we have chosen if we are multi select.\n            $option.prop('selected', !state);\n            that.setSelected(clickedIndex, !state);\n            $this.blur();\n\n            if (maxOptions !== false || maxOptionsGrp !== false) {\n              var maxReached = maxOptions < $options.filter(':selected').length,\n                  maxReachedGrp = maxOptionsGrp < $optgroup.find('option:selected').length;\n\n              if ((maxOptions && maxReached) || (maxOptionsGrp && maxReachedGrp)) {\n                if (maxOptions && maxOptions == 1) {\n                  $options.prop('selected', false);\n                  $option.prop('selected', true);\n                  that.$menuInner.find('.selected').removeClass('selected');\n                  that.setSelected(clickedIndex, true);\n                } else if (maxOptionsGrp && maxOptionsGrp == 1) {\n                  $optgroup.find('option:selected').prop('selected', false);\n                  $option.prop('selected', true);\n                  var optgroupID = $this.parent().data('optgroup');\n                  that.$menuInner.find('[data-optgroup=\"' + optgroupID + '\"]').removeClass('selected');\n                  that.setSelected(clickedIndex, true);\n                } else {\n                  var maxOptionsText = typeof that.options.maxOptionsText === 'string' ? [that.options.maxOptionsText, that.options.maxOptionsText] : that.options.maxOptionsText,\n                      maxOptionsArr = typeof maxOptionsText === 'function' ? maxOptionsText(maxOptions, maxOptionsGrp) : maxOptionsText,\n                      maxTxt = maxOptionsArr[0].replace('{n}', maxOptions),\n                      maxTxtGrp = maxOptionsArr[1].replace('{n}', maxOptionsGrp),\n                      $notify = $('<div class=\"notify\"></div>');\n                  // If {var} is set in array, replace it\n                  /** @deprecated */\n                  if (maxOptionsArr[2]) {\n                    maxTxt = maxTxt.replace('{var}', maxOptionsArr[2][maxOptions > 1 ? 0 : 1]);\n                    maxTxtGrp = maxTxtGrp.replace('{var}', maxOptionsArr[2][maxOptionsGrp > 1 ? 0 : 1]);\n                  }\n\n                  $option.prop('selected', false);\n\n                  that.$menu.append($notify);\n\n                  if (maxOptions && maxReached) {\n                    $notify.append($('<div>' + maxTxt + '</div>'));\n                    triggerChange = false;\n                    that.$element.trigger('maxReached.bs.select');\n                  }\n\n                  if (maxOptionsGrp && maxReachedGrp) {\n                    $notify.append($('<div>' + maxTxtGrp + '</div>'));\n                    triggerChange = false;\n                    that.$element.trigger('maxReachedGrp.bs.select');\n                  }\n\n                  setTimeout(function () {\n                    that.setSelected(clickedIndex, false);\n                  }, 10);\n\n                  $notify.delay(750).fadeOut(300, function () {\n                    $(this).remove();\n                  });\n                }\n              }\n            }\n          }\n\n          if (!that.multiple || (that.multiple && that.options.maxOptions === 1)) {\n            that.$button.focus();\n          } else if (that.options.liveSearch) {\n            that.$searchbox.focus();\n          }\n\n          // Trigger select 'change'\n          if (triggerChange) {\n            if ((prevValue != that.$element.val() && that.multiple) || (prevIndex != that.$element.prop('selectedIndex') && !that.multiple)) {\n              // $option.prop('selected') is current option state (selected/unselected). state is previous option state.\n              changed_arguments = [clickedIndex, $option.prop('selected'), state];\n              that.$element\n                .triggerNative('change');\n            }\n          }\n        }\n      });\n\n      this.$menu.on('click', 'li.disabled a, .popover-title, .popover-title :not(.close)', function (e) {\n        if (e.currentTarget == this) {\n          e.preventDefault();\n          e.stopPropagation();\n          if (that.options.liveSearch && !$(e.target).hasClass('close')) {\n            that.$searchbox.focus();\n          } else {\n            that.$button.focus();\n          }\n        }\n      });\n\n      this.$menuInner.on('click', '.divider, .dropdown-header', function (e) {\n        e.preventDefault();\n        e.stopPropagation();\n        if (that.options.liveSearch) {\n          that.$searchbox.focus();\n        } else {\n          that.$button.focus();\n        }\n      });\n\n      this.$menu.on('click', '.popover-title .close', function () {\n        that.$button.click();\n      });\n\n      this.$searchbox.on('click', function (e) {\n        e.stopPropagation();\n      });\n\n      this.$menu.on('click', '.actions-btn', function (e) {\n        if (that.options.liveSearch) {\n          that.$searchbox.focus();\n        } else {\n          that.$button.focus();\n        }\n\n        e.preventDefault();\n        e.stopPropagation();\n\n        if ($(this).hasClass('bs-select-all')) {\n          that.selectAll();\n        } else {\n          that.deselectAll();\n        }\n      });\n\n      this.$element.change(function () {\n        that.render(false);\n        that.$element.trigger('changed.bs.select', changed_arguments);\n        changed_arguments = null;\n      });\n    },\n\n    liveSearchListener: function () {\n      var that = this,\n          $no_results = $('<li class=\"no-results\"></li>');\n\n      this.$button.on('click.dropdown.data-api', function () {\n        that.$menuInner.find('.active').removeClass('active');\n        if (!!that.$searchbox.val()) {\n          that.$searchbox.val('');\n          that.$lis.not('.is-hidden').removeClass('hidden');\n          if (!!$no_results.parent().length) $no_results.remove();\n        }\n        if (!that.multiple) that.$menuInner.find('.selected').addClass('active');\n        setTimeout(function () {\n          that.$searchbox.focus();\n        }, 10);\n      });\n\n      this.$searchbox.on('click.dropdown.data-api focus.dropdown.data-api touchend.dropdown.data-api', function (e) {\n        e.stopPropagation();\n      });\n\n      this.$searchbox.on('input propertychange', function () {\n        that.$lis.not('.is-hidden').removeClass('hidden');\n        that.$lis.filter('.active').removeClass('active');\n        $no_results.remove();\n\n        if (that.$searchbox.val()) {\n          var $searchBase = that.$lis.not('.is-hidden, .divider, .dropdown-header'),\n              $hideItems;\n          if (that.options.liveSearchNormalize) {\n            $hideItems = $searchBase.find('a').not(':a' + that._searchStyle() + '(\"' + normalizeToBase(that.$searchbox.val()) + '\")');\n          } else {\n            $hideItems = $searchBase.find('a').not(':' + that._searchStyle() + '(\"' + that.$searchbox.val() + '\")');\n          }\n\n          if ($hideItems.length === $searchBase.length) {\n            $no_results.html(that.options.noneResultsText.replace('{0}', '\"' + htmlEscape(that.$searchbox.val()) + '\"'));\n            that.$menuInner.append($no_results);\n            that.$lis.addClass('hidden');\n          } else {\n            $hideItems.parent().addClass('hidden');\n\n            var $lisVisible = that.$lis.not('.hidden'),\n                $foundDiv;\n\n            // hide divider if first or last visible, or if followed by another divider\n            $lisVisible.each(function (index) {\n              var $this = $(this);\n\n              if ($this.hasClass('divider')) {\n                if ($foundDiv === undefined) {\n                  $this.addClass('hidden');\n                } else {\n                  if ($foundDiv) $foundDiv.addClass('hidden');\n                  $foundDiv = $this;\n                }\n              } else if ($this.hasClass('dropdown-header') && $lisVisible.eq(index + 1).data('optgroup') !== $this.data('optgroup')) {\n                $this.addClass('hidden');\n              } else {\n                $foundDiv = null;\n              }\n            });\n            if ($foundDiv) $foundDiv.addClass('hidden');\n\n            $searchBase.not('.hidden').first().addClass('active');\n          }\n        }\n      });\n    },\n\n    _searchStyle: function () {\n      var styles = {\n        begins: 'ibegins',\n        startsWith: 'ibegins'\n      };\n\n      return styles[this.options.liveSearchStyle] || 'icontains';\n    },\n\n    val: function (value) {\n      if (typeof value !== 'undefined') {\n        this.$element.val(value);\n        this.render();\n\n        return this.$element;\n      } else {\n        return this.$element.val();\n      }\n    },\n\n    changeAll: function (status) {\n      if (!this.multiple) return;\n      if (typeof status === 'undefined') status = true;\n\n      this.findLis();\n\n      var $options = this.$element.find('option'),\n          $lisVisible = this.$lis.not('.divider, .dropdown-header, .disabled, .hidden'),\n          lisVisLen = $lisVisible.length,\n          selectedOptions = [];\n          \n      if (status) {\n        if ($lisVisible.filter('.selected').length === $lisVisible.length) return;\n      } else {\n        if ($lisVisible.filter('.selected').length === 0) return;\n      }\n          \n      $lisVisible.toggleClass('selected', status);\n\n      for (var i = 0; i < lisVisLen; i++) {\n        var origIndex = $lisVisible[i].getAttribute('data-original-index');\n        selectedOptions[selectedOptions.length] = $options.eq(origIndex)[0];\n      }\n\n      $(selectedOptions).prop('selected', status);\n\n      this.render(false);\n\n      this.togglePlaceholder();\n\n      this.$element\n        .triggerNative('change');\n    },\n\n    selectAll: function () {\n      return this.changeAll(true);\n    },\n\n    deselectAll: function () {\n      return this.changeAll(false);\n    },\n\n    toggle: function (e) {\n      e = e || window.event;\n\n      if (e) e.stopPropagation();\n\n      this.$button.trigger('click');\n    },\n\n    keydown: function (e) {\n      var $this = $(this),\n          $parent = $this.is('input') ? $this.parent().parent() : $this.parent(),\n          $items,\n          that = $parent.data('this'),\n          index,\n          next,\n          first,\n          last,\n          prev,\n          nextPrev,\n          prevIndex,\n          isActive,\n          selector = ':not(.disabled, .hidden, .dropdown-header, .divider)',\n          keyCodeMap = {\n            32: ' ',\n            48: '0',\n            49: '1',\n            50: '2',\n            51: '3',\n            52: '4',\n            53: '5',\n            54: '6',\n            55: '7',\n            56: '8',\n            57: '9',\n            59: ';',\n            65: 'a',\n            66: 'b',\n            67: 'c',\n            68: 'd',\n            69: 'e',\n            70: 'f',\n            71: 'g',\n            72: 'h',\n            73: 'i',\n            74: 'j',\n            75: 'k',\n            76: 'l',\n            77: 'm',\n            78: 'n',\n            79: 'o',\n            80: 'p',\n            81: 'q',\n            82: 'r',\n            83: 's',\n            84: 't',\n            85: 'u',\n            86: 'v',\n            87: 'w',\n            88: 'x',\n            89: 'y',\n            90: 'z',\n            96: '0',\n            97: '1',\n            98: '2',\n            99: '3',\n            100: '4',\n            101: '5',\n            102: '6',\n            103: '7',\n            104: '8',\n            105: '9'\n          };\n\n      if (that.options.liveSearch) $parent = $this.parent().parent();\n\n      if (that.options.container) $parent = that.$menu;\n\n      $items = $('[role=\"listbox\"] li', $parent);\n\n      isActive = that.$newElement.hasClass('open');\n\n      if (!isActive && (e.keyCode >= 48 && e.keyCode <= 57 || e.keyCode >= 96 && e.keyCode <= 105 || e.keyCode >= 65 && e.keyCode <= 90)) {\n        if (!that.options.container) {\n          that.setSize();\n          that.$menu.parent().addClass('open');\n          isActive = true;\n        } else {\n          that.$button.trigger('click');\n        }\n        that.$searchbox.focus();\n        return;\n      }\n\n      if (that.options.liveSearch) {\n        if (/(^9$|27)/.test(e.keyCode.toString(10)) && isActive) {\n          e.preventDefault();\n          e.stopPropagation();\n          that.$menuInner.click();\n          that.$button.focus();\n        }\n        // $items contains li elements when liveSearch is enabled\n        $items = $('[role=\"listbox\"] li' + selector, $parent);\n        if (!$this.val() && !/(38|40)/.test(e.keyCode.toString(10))) {\n          if ($items.filter('.active').length === 0) {\n            $items = that.$menuInner.find('li');\n            if (that.options.liveSearchNormalize) {\n              $items = $items.filter(':a' + that._searchStyle() + '(' + normalizeToBase(keyCodeMap[e.keyCode]) + ')');\n            } else {\n              $items = $items.filter(':' + that._searchStyle() + '(' + keyCodeMap[e.keyCode] + ')');\n            }\n          }\n        }\n      }\n\n      if (!$items.length) return;\n\n      if (/(38|40)/.test(e.keyCode.toString(10))) {\n        index = $items.index($items.find('a').filter(':focus').parent());\n        first = $items.filter(selector).first().index();\n        last = $items.filter(selector).last().index();\n        next = $items.eq(index).nextAll(selector).eq(0).index();\n        prev = $items.eq(index).prevAll(selector).eq(0).index();\n        nextPrev = $items.eq(next).prevAll(selector).eq(0).index();\n\n        if (that.options.liveSearch) {\n          $items.each(function (i) {\n            if (!$(this).hasClass('disabled')) {\n              $(this).data('index', i);\n            }\n          });\n          index = $items.index($items.filter('.active'));\n          first = $items.first().data('index');\n          last = $items.last().data('index');\n          next = $items.eq(index).nextAll().eq(0).data('index');\n          prev = $items.eq(index).prevAll().eq(0).data('index');\n          nextPrev = $items.eq(next).prevAll().eq(0).data('index');\n        }\n\n        prevIndex = $this.data('prevIndex');\n\n        if (e.keyCode == 38) {\n          if (that.options.liveSearch) index--;\n          if (index != nextPrev && index > prev) index = prev;\n          if (index < first) index = first;\n          if (index == prevIndex) index = last;\n        } else if (e.keyCode == 40) {\n          if (that.options.liveSearch) index++;\n          if (index == -1) index = 0;\n          if (index != nextPrev && index < next) index = next;\n          if (index > last) index = last;\n          if (index == prevIndex) index = first;\n        }\n\n        $this.data('prevIndex', index);\n\n        if (!that.options.liveSearch) {\n          $items.eq(index).children('a').focus();\n        } else {\n          e.preventDefault();\n          if (!$this.hasClass('dropdown-toggle')) {\n            $items.removeClass('active').eq(index).addClass('active').children('a').focus();\n            $this.focus();\n          }\n        }\n\n      } else if (!$this.is('input')) {\n        var keyIndex = [],\n            count,\n            prevKey;\n\n        $items.each(function () {\n          if (!$(this).hasClass('disabled')) {\n            if ($.trim($(this).children('a').text().toLowerCase()).substring(0, 1) == keyCodeMap[e.keyCode]) {\n              keyIndex.push($(this).index());\n            }\n          }\n        });\n\n        count = $(document).data('keycount');\n        count++;\n        $(document).data('keycount', count);\n\n        prevKey = $.trim($(':focus').text().toLowerCase()).substring(0, 1);\n\n        if (prevKey != keyCodeMap[e.keyCode]) {\n          count = 1;\n          $(document).data('keycount', count);\n        } else if (count >= keyIndex.length) {\n          $(document).data('keycount', 0);\n          if (count > keyIndex.length) count = 1;\n        }\n\n        $items.eq(keyIndex[count - 1]).children('a').focus();\n      }\n\n      // Select focused option if \"Enter\", \"Spacebar\" or \"Tab\" (when selectOnTab is true) are pressed inside the menu.\n      if ((/(13|32)/.test(e.keyCode.toString(10)) || (/(^9$)/.test(e.keyCode.toString(10)) && that.options.selectOnTab)) && isActive) {\n        if (!/(32)/.test(e.keyCode.toString(10))) e.preventDefault();\n        if (!that.options.liveSearch) {\n          var elem = $(':focus');\n          elem.click();\n          // Bring back focus for multiselects\n          elem.focus();\n          // Prevent screen from scrolling if the user hit the spacebar\n          e.preventDefault();\n          // Fixes spacebar selection of dropdown items in FF & IE\n          $(document).data('spaceSelect', true);\n        } else if (!/(32)/.test(e.keyCode.toString(10))) {\n          that.$menuInner.find('.active a').click();\n          $this.focus();\n        }\n        $(document).data('keycount', 0);\n      }\n\n      if ((/(^9$|27)/.test(e.keyCode.toString(10)) && isActive && (that.multiple || that.options.liveSearch)) || (/(27)/.test(e.keyCode.toString(10)) && !isActive)) {\n        that.$menu.parent().removeClass('open');\n        if (that.options.container) that.$newElement.removeClass('open');\n        that.$button.focus();\n      }\n    },\n\n    mobile: function () {\n      this.$element.addClass('mobile-device');\n    },\n\n    refresh: function () {\n      this.$lis = null;\n      this.liObj = {};\n      this.reloadLi();\n      this.render();\n      this.checkDisabled();\n      this.liHeight(true);\n      this.setStyle();\n      this.setWidth();\n      if (this.$lis) this.$searchbox.trigger('propertychange');\n\n      this.$element.trigger('refreshed.bs.select');\n    },\n\n    hide: function () {\n      this.$newElement.hide();\n    },\n\n    show: function () {\n      this.$newElement.show();\n    },\n\n    remove: function () {\n      this.$newElement.remove();\n      this.$element.remove();\n    },\n\n    destroy: function () {\n      this.$newElement.before(this.$element).remove();\n\n      if (this.$bsContainer) {\n        this.$bsContainer.remove();\n      } else {\n        this.$menu.remove();\n      }\n\n      this.$element\n        .off('.bs.select')\n        .removeData('selectpicker')\n        .removeClass('bs-select-hidden selectpicker');\n    }\n  };\n\n  // SELECTPICKER PLUGIN DEFINITION\n  // ==============================\n  function Plugin(option) {\n    // get the args of the outer function..\n    var args = arguments;\n    // The arguments of the function are explicitly re-defined from the argument list, because the shift causes them\n    // to get lost/corrupted in android 2.3 and IE9 #715 #775\n    var _option = option;\n\n    [].shift.apply(args);\n\n    var value;\n    var chain = this.each(function () {\n      var $this = $(this);\n      if ($this.is('select')) {\n        var data = $this.data('selectpicker'),\n            options = typeof _option == 'object' && _option;\n\n        if (!data) {\n          var config = $.extend({}, Selectpicker.DEFAULTS, $.fn.selectpicker.defaults || {}, $this.data(), options);\n          config.template = $.extend({}, Selectpicker.DEFAULTS.template, ($.fn.selectpicker.defaults ? $.fn.selectpicker.defaults.template : {}), $this.data().template, options.template);\n          $this.data('selectpicker', (data = new Selectpicker(this, config)));\n        } else if (options) {\n          for (var i in options) {\n            if (options.hasOwnProperty(i)) {\n              data.options[i] = options[i];\n            }\n          }\n        }\n\n        if (typeof _option == 'string') {\n          if (data[_option] instanceof Function) {\n            value = data[_option].apply(data, args);\n          } else {\n            value = data.options[_option];\n          }\n        }\n      }\n    });\n\n    if (typeof value !== 'undefined') {\n      //noinspection JSUnusedAssignment\n      return value;\n    } else {\n      return chain;\n    }\n  }\n\n  var old = $.fn.selectpicker;\n  $.fn.selectpicker = Plugin;\n  $.fn.selectpicker.Constructor = Selectpicker;\n\n  // SELECTPICKER NO CONFLICT\n  // ========================\n  $.fn.selectpicker.noConflict = function () {\n    $.fn.selectpicker = old;\n    return this;\n  };\n\n  $(document)\n      .data('keycount', 0)\n      .on('keydown.bs.select', '.bootstrap-select [data-toggle=dropdown], .bootstrap-select [role=\"listbox\"], .bs-searchbox input', Selectpicker.prototype.keydown)\n      .on('focusin.modal', '.bootstrap-select [data-toggle=dropdown], .bootstrap-select [role=\"listbox\"], .bs-searchbox input', function (e) {\n        e.stopPropagation();\n      });\n\n  // SELECTPICKER DATA-API\n  // =====================\n  $(window).on('load.bs.select.data-api', function () {\n    $('.selectpicker').each(function () {\n      var $selectpicker = $(this);\n      Plugin.call($selectpicker, $selectpicker.data());\n    })\n  });\n})(jQuery);\n\n\n}));\n"
  },
  {
    "path": "app_frontend/static/plugin/bootstrap-select-1.12.2/docs/docs/dist/js/i18n/defaults-ar_AR.js",
    "content": "/*!\n * Bootstrap-select v1.12.2 (http://silviomoreto.github.io/bootstrap-select)\n *\n * Copyright 2013-2017 bootstrap-select\n * Licensed under MIT (https://github.com/silviomoreto/bootstrap-select/blob/master/LICENSE)\n */\n\n(function (root, factory) {\n  if (typeof define === 'function' && define.amd) {\n    // AMD. Register as an anonymous module unless amdModuleId is set\n    define([\"jquery\"], function (a0) {\n      return (factory(a0));\n    });\n  } else if (typeof module === 'object' && module.exports) {\n    // Node. Does not work with strict CommonJS, but\n    // only CommonJS-like environments that support module.exports,\n    // like Node.\n    module.exports = factory(require(\"jquery\"));\n  } else {\n    factory(root[\"jQuery\"]);\n  }\n}(this, function (jQuery) {\n\n/*!\n * Translated default messages for bootstrap-select.\n * Locale: AR (Arabic)\n * Author: Yasser Lotfy <y_l@alive.com>\n */\n(function ($) {\n  $.fn.selectpicker.defaults = {\n    noneSelectedText: 'لم يتم إختيار شئ',\n    noneResultsText: 'لا توجد نتائج مطابقة لـ {0}',\n    countSelectedText: function (numSelected, numTotal) {\n      return (numSelected == 1) ? \"{0} خيار تم إختياره\" : \"{0} خيارات تمت إختيارها\";\n    },\n    maxOptionsText: function (numAll, numGroup) {\n      return [\n        (numAll == 1) ? 'تخطى الحد المسموح ({n} خيار بحد أقصى)' : 'تخطى الحد المسموح ({n} خيارات بحد أقصى)',\n        (numGroup == 1) ? 'تخطى الحد المسموح للمجموعة ({n} خيار بحد أقصى)' : 'تخطى الحد المسموح للمجموعة ({n} خيارات بحد أقصى)'\n      ];\n    },\n    selectAllText: 'إختيار الجميع',\n    deselectAllText: 'إلغاء إختيار الجميع',\n    multipleSeparator: '، '\n  };\n})(jQuery);\n\n\n}));\n"
  },
  {
    "path": "app_frontend/static/plugin/bootstrap-select-1.12.2/docs/docs/dist/js/i18n/defaults-bg_BG.js",
    "content": "/*!\n * Bootstrap-select v1.12.2 (http://silviomoreto.github.io/bootstrap-select)\n *\n * Copyright 2013-2017 bootstrap-select\n * Licensed under MIT (https://github.com/silviomoreto/bootstrap-select/blob/master/LICENSE)\n */\n\n(function (root, factory) {\n  if (typeof define === 'function' && define.amd) {\n    // AMD. Register as an anonymous module unless amdModuleId is set\n    define([\"jquery\"], function (a0) {\n      return (factory(a0));\n    });\n  } else if (typeof module === 'object' && module.exports) {\n    // Node. Does not work with strict CommonJS, but\n    // only CommonJS-like environments that support module.exports,\n    // like Node.\n    module.exports = factory(require(\"jquery\"));\n  } else {\n    factory(root[\"jQuery\"]);\n  }\n}(this, function (jQuery) {\n\n(function ($) {\n  $.fn.selectpicker.defaults = {\n    noneSelectedText: 'Нищо избрано',\n    noneResultsText: 'Няма резултат за {0}',\n    countSelectedText: function (numSelected, numTotal) {\n      return (numSelected == 1) ? \"{0} избран елемент\" : \"{0} избрани елемента\";\n    },\n    maxOptionsText: function (numAll, numGroup) {\n      return [\n        (numAll == 1) ? 'Лимита е достигнат ({n} елемент максимум)' : 'Лимита е достигнат ({n} елемента максимум)',\n        (numGroup == 1) ? 'Груповия лимит е достигнат ({n} елемент максимум)' : 'Груповия лимит е достигнат ({n} елемента максимум)'\n      ];\n    },\n    selectAllText: 'Избери всички',\n    deselectAllText: 'Размаркирай всички',\n    multipleSeparator: ', '\n  };\n})(jQuery);\n\n\n}));\n"
  },
  {
    "path": "app_frontend/static/plugin/bootstrap-select-1.12.2/docs/docs/dist/js/i18n/defaults-cro_CRO.js",
    "content": "/*!\n * Bootstrap-select v1.12.2 (http://silviomoreto.github.io/bootstrap-select)\n *\n * Copyright 2013-2017 bootstrap-select\n * Licensed under MIT (https://github.com/silviomoreto/bootstrap-select/blob/master/LICENSE)\n */\n\n(function (root, factory) {\n  if (typeof define === 'function' && define.amd) {\n    // AMD. Register as an anonymous module unless amdModuleId is set\n    define([\"jquery\"], function (a0) {\n      return (factory(a0));\n    });\n  } else if (typeof module === 'object' && module.exports) {\n    // Node. Does not work with strict CommonJS, but\n    // only CommonJS-like environments that support module.exports,\n    // like Node.\n    module.exports = factory(require(\"jquery\"));\n  } else {\n    factory(root[\"jQuery\"]);\n  }\n}(this, function (jQuery) {\n\n(function ($) {\n  $.fn.selectpicker.defaults = {\n    noneSelectedText: 'Odaberite stavku',\n    noneResultsText: 'Nema rezultata pretrage {0}',\n    countSelectedText: function (numSelected, numTotal) {\n      return (numSelected == 1) ? \"{0} stavka selektirana\" : \"{0} stavke selektirane\";\n    },\n    maxOptionsText: function (numAll, numGroup) {\n      return [\n        (numAll == 1) ? 'Limit je postignut ({n} stvar maximalno)' : 'Limit je postignut ({n} stavke maksimalno)',\n        (numGroup == 1) ? 'Grupni limit je postignut ({n} stvar maksimalno)' : 'Grupni limit je postignut ({n} stavke maksimalno)'\n      ];\n    },\n    selectAllText: 'Selektiraj sve',\n    deselectAllText: 'Deselektiraj sve',\n    multipleSeparator: ', '\n  };\n})(jQuery);\n\n\n}));\n"
  },
  {
    "path": "app_frontend/static/plugin/bootstrap-select-1.12.2/docs/docs/dist/js/i18n/defaults-cs_CZ.js",
    "content": "/*!\n * Bootstrap-select v1.12.2 (http://silviomoreto.github.io/bootstrap-select)\n *\n * Copyright 2013-2017 bootstrap-select\n * Licensed under MIT (https://github.com/silviomoreto/bootstrap-select/blob/master/LICENSE)\n */\n\n(function (root, factory) {\n  if (typeof define === 'function' && define.amd) {\n    // AMD. Register as an anonymous module unless amdModuleId is set\n    define([\"jquery\"], function (a0) {\n      return (factory(a0));\n    });\n  } else if (typeof module === 'object' && module.exports) {\n    // Node. Does not work with strict CommonJS, but\n    // only CommonJS-like environments that support module.exports,\n    // like Node.\n    module.exports = factory(require(\"jquery\"));\n  } else {\n    factory(root[\"jQuery\"]);\n  }\n}(this, function (jQuery) {\n\n(function ($) {\n  $.fn.selectpicker.defaults = {\n    noneSelectedText: 'Nic není vybráno',\n    noneResultsText: 'Žádné výsledky {0}',\n    countSelectedText: 'Označeno {0} z {1}',\n    maxOptionsText: ['Limit překročen ({n} {var} max)', 'Limit skupiny překročen ({n} {var} max)', ['položek', 'položka']],\n    multipleSeparator: ', '\n  };\n})(jQuery);\n\n\n}));\n"
  },
  {
    "path": "app_frontend/static/plugin/bootstrap-select-1.12.2/docs/docs/dist/js/i18n/defaults-da_DK.js",
    "content": "/*!\n * Bootstrap-select v1.12.2 (http://silviomoreto.github.io/bootstrap-select)\n *\n * Copyright 2013-2017 bootstrap-select\n * Licensed under MIT (https://github.com/silviomoreto/bootstrap-select/blob/master/LICENSE)\n */\n\n(function (root, factory) {\n  if (typeof define === 'function' && define.amd) {\n    // AMD. Register as an anonymous module unless amdModuleId is set\n    define([\"jquery\"], function (a0) {\n      return (factory(a0));\n    });\n  } else if (typeof module === 'object' && module.exports) {\n    // Node. Does not work with strict CommonJS, but\n    // only CommonJS-like environments that support module.exports,\n    // like Node.\n    module.exports = factory(require(\"jquery\"));\n  } else {\n    factory(root[\"jQuery\"]);\n  }\n}(this, function (jQuery) {\n\n(function ($) {\n  $.fn.selectpicker.defaults = {\n    noneSelectedText: 'Intet valgt',\n    noneResultsText: 'Ingen resultater fundet {0}',\n    countSelectedText: function (numSelected, numTotal) {\n      return (numSelected == 1) ? \"{0} valgt\" : \"{0} valgt\";\n    },\n    maxOptionsText: function (numAll, numGroup) {\n      return [\n        (numAll == 1) ? 'Begrænsning nået (max {n} valgt)' : 'Begrænsning nået (max {n} valgte)',\n        (numGroup == 1) ? 'Gruppe-begrænsning nået (max {n} valgt)' : 'Gruppe-begrænsning nået (max {n} valgte)'\n      ];\n    },\n    selectAllText: 'Markér alle',\n    deselectAllText: 'Afmarkér alle',\n    multipleSeparator: ', '\n  };\n})(jQuery);\n\n\n}));\n"
  },
  {
    "path": "app_frontend/static/plugin/bootstrap-select-1.12.2/docs/docs/dist/js/i18n/defaults-de_DE.js",
    "content": "/*!\n * Bootstrap-select v1.12.2 (http://silviomoreto.github.io/bootstrap-select)\n *\n * Copyright 2013-2017 bootstrap-select\n * Licensed under MIT (https://github.com/silviomoreto/bootstrap-select/blob/master/LICENSE)\n */\n\n(function (root, factory) {\n  if (typeof define === 'function' && define.amd) {\n    // AMD. Register as an anonymous module unless amdModuleId is set\n    define([\"jquery\"], function (a0) {\n      return (factory(a0));\n    });\n  } else if (typeof module === 'object' && module.exports) {\n    // Node. Does not work with strict CommonJS, but\n    // only CommonJS-like environments that support module.exports,\n    // like Node.\n    module.exports = factory(require(\"jquery\"));\n  } else {\n    factory(root[\"jQuery\"]);\n  }\n}(this, function (jQuery) {\n\n(function ($) {\n  $.fn.selectpicker.defaults = {\n    noneSelectedText: 'Bitte wählen...',\n    noneResultsText: 'Keine Ergebnisse für {0}',\n    countSelectedText: function (numSelected, numTotal) {\n      return (numSelected == 1) ? \"{0} Element ausgewählt\" : \"{0} Elemente ausgewählt\";\n    },\n    maxOptionsText: function (numAll, numGroup) {\n      return [\n        (numAll == 1) ? 'Limit erreicht ({n} Element max.)' : 'Limit erreicht ({n} Elemente max.)',\n        (numGroup == 1) ? 'Gruppen-Limit erreicht ({n} Element max.)' : 'Gruppen-Limit erreicht ({n} Elemente max.)'\n      ];\n    },\n    selectAllText: 'Alles auswählen',\n    deselectAllText: 'Nichts auswählen',\n    multipleSeparator: ', '\n  };\n})(jQuery);\n\n\n}));\n"
  },
  {
    "path": "app_frontend/static/plugin/bootstrap-select-1.12.2/docs/docs/dist/js/i18n/defaults-en_US.js",
    "content": "/*!\n * Bootstrap-select v1.12.2 (http://silviomoreto.github.io/bootstrap-select)\n *\n * Copyright 2013-2017 bootstrap-select\n * Licensed under MIT (https://github.com/silviomoreto/bootstrap-select/blob/master/LICENSE)\n */\n\n(function (root, factory) {\n  if (typeof define === 'function' && define.amd) {\n    // AMD. Register as an anonymous module unless amdModuleId is set\n    define([\"jquery\"], function (a0) {\n      return (factory(a0));\n    });\n  } else if (typeof module === 'object' && module.exports) {\n    // Node. Does not work with strict CommonJS, but\n    // only CommonJS-like environments that support module.exports,\n    // like Node.\n    module.exports = factory(require(\"jquery\"));\n  } else {\n    factory(root[\"jQuery\"]);\n  }\n}(this, function (jQuery) {\n\n(function ($) {\n  $.fn.selectpicker.defaults = {\n    noneSelectedText: 'Nothing selected',\n    noneResultsText: 'No results match {0}',\n    countSelectedText: function (numSelected, numTotal) {\n      return (numSelected == 1) ? \"{0} item selected\" : \"{0} items selected\";\n    },\n    maxOptionsText: function (numAll, numGroup) {\n      return [\n        (numAll == 1) ? 'Limit reached ({n} item max)' : 'Limit reached ({n} items max)',\n        (numGroup == 1) ? 'Group limit reached ({n} item max)' : 'Group limit reached ({n} items max)'\n      ];\n    },\n    selectAllText: 'Select All',\n    deselectAllText: 'Deselect All',\n    multipleSeparator: ', '\n  };\n})(jQuery);\n\n\n}));\n"
  },
  {
    "path": "app_frontend/static/plugin/bootstrap-select-1.12.2/docs/docs/dist/js/i18n/defaults-es_CL.js",
    "content": "/*!\n * Bootstrap-select v1.12.2 (http://silviomoreto.github.io/bootstrap-select)\n *\n * Copyright 2013-2017 bootstrap-select\n * Licensed under MIT (https://github.com/silviomoreto/bootstrap-select/blob/master/LICENSE)\n */\n\n(function (root, factory) {\n  if (typeof define === 'function' && define.amd) {\n    // AMD. Register as an anonymous module unless amdModuleId is set\n    define([\"jquery\"], function (a0) {\n      return (factory(a0));\n    });\n  } else if (typeof module === 'object' && module.exports) {\n    // Node. Does not work with strict CommonJS, but\n    // only CommonJS-like environments that support module.exports,\n    // like Node.\n    module.exports = factory(require(\"jquery\"));\n  } else {\n    factory(root[\"jQuery\"]);\n  }\n}(this, function (jQuery) {\n\n(function ($) {\n  $.fn.selectpicker.defaults = {\n    noneSelectedText: 'No hay selección',\n    noneResultsText: 'No hay resultados {0}',\n    countSelectedText: 'Seleccionados {0} de {1}',\n    maxOptionsText: ['Límite alcanzado ({n} {var} max)', 'Límite del grupo alcanzado({n} {var} max)', ['elementos', 'element']],\n    multipleSeparator: ', ',\n    selectAllText: 'Seleccionar Todos',\n    deselectAllText: 'Desmarcar Todos'\n  };\n})(jQuery);\n\n\n}));\n"
  },
  {
    "path": "app_frontend/static/plugin/bootstrap-select-1.12.2/docs/docs/dist/js/i18n/defaults-es_ES.js",
    "content": "/*!\n * Bootstrap-select v1.12.2 (http://silviomoreto.github.io/bootstrap-select)\n *\n * Copyright 2013-2017 bootstrap-select\n * Licensed under MIT (https://github.com/silviomoreto/bootstrap-select/blob/master/LICENSE)\n */\n\n(function (root, factory) {\n  if (typeof define === 'function' && define.amd) {\n    // AMD. Register as an anonymous module unless amdModuleId is set\n    define([\"jquery\"], function (a0) {\n      return (factory(a0));\n    });\n  } else if (typeof module === 'object' && module.exports) {\n    // Node. Does not work with strict CommonJS, but\n    // only CommonJS-like environments that support module.exports,\n    // like Node.\n    module.exports = factory(require(\"jquery\"));\n  } else {\n    factory(root[\"jQuery\"]);\n  }\n}(this, function (jQuery) {\n\n(function ($) {\n  $.fn.selectpicker.defaults = {\n    noneSelectedText: 'No hay selección',\n    noneResultsText: 'No hay resultados {0}',\n    countSelectedText: 'Seleccionados {0} de {1}',\n    maxOptionsText: ['Límite alcanzado ({n} {var} max)', 'Límite del grupo alcanzado({n} {var} max)', ['elementos', 'element']],\n    multipleSeparator: ', ',\n    selectAllText: 'Seleccionar Todos',\n    deselectAllText: 'Desmarcar Todos'\n  };\n})(jQuery);\n\n\n}));\n"
  },
  {
    "path": "app_frontend/static/plugin/bootstrap-select-1.12.2/docs/docs/dist/js/i18n/defaults-eu.js",
    "content": "/*!\n * Bootstrap-select v1.12.2 (http://silviomoreto.github.io/bootstrap-select)\n *\n * Copyright 2013-2017 bootstrap-select\n * Licensed under MIT (https://github.com/silviomoreto/bootstrap-select/blob/master/LICENSE)\n */\n\n(function (root, factory) {\n  if (typeof define === 'function' && define.amd) {\n    // AMD. Register as an anonymous module unless amdModuleId is set\n    define([\"jquery\"], function (a0) {\n      return (factory(a0));\n    });\n  } else if (typeof module === 'object' && module.exports) {\n    // Node. Does not work with strict CommonJS, but\n    // only CommonJS-like environments that support module.exports,\n    // like Node.\n    module.exports = factory(require(\"jquery\"));\n  } else {\n    factory(root[\"jQuery\"]);\n  }\n}(this, function (jQuery) {\n\n(function ($) {\n  $.fn.selectpicker.defaults = {\n    noneSelectedText: 'Hautapenik ez',\n    noneResultsText: 'Emaitzarik ez {0}',\n    countSelectedText: '{1}(e)tik {0} hautatuta',\n    maxOptionsText: ['Mugara iritsita ({n} {var} gehienez)', 'Taldearen mugara iritsita ({n} {var} gehienez)', ['elementu', 'elementu']],\n    multipleSeparator: ', '\n  };\n})(jQuery);\n\n\n}));\n"
  },
  {
    "path": "app_frontend/static/plugin/bootstrap-select-1.12.2/docs/docs/dist/js/i18n/defaults-fa_IR.js",
    "content": "/*!\n * Bootstrap-select v1.12.2 (http://silviomoreto.github.io/bootstrap-select)\n *\n * Copyright 2013-2017 bootstrap-select\n * Licensed under MIT (https://github.com/silviomoreto/bootstrap-select/blob/master/LICENSE)\n */\n\n(function (root, factory) {\n  if (typeof define === 'function' && define.amd) {\n    // AMD. Register as an anonymous module unless amdModuleId is set\n    define([\"jquery\"], function (a0) {\n      return (factory(a0));\n    });\n  } else if (typeof module === 'object' && module.exports) {\n    // Node. Does not work with strict CommonJS, but\n    // only CommonJS-like environments that support module.exports,\n    // like Node.\n    module.exports = factory(require(\"jquery\"));\n  } else {\n    factory(root[\"jQuery\"]);\n  }\n}(this, function (jQuery) {\n\n(function ($) {\n    $.fn.selectpicker.defaults = {\n        noneSelectedText: 'چیزی انتخاب نشده است',\n        noneResultsText: 'هیج مشابهی برای {0} پیدا نشد',\n        countSelectedText: \"{0} از {1} مورد انتخاب شده\",\n        maxOptionsText: ['بیشتر ممکن نیست {حداکثر {n} عدد}', 'بیشتر ممکن نیست {حداکثر {n} عدد}'],\n        selectAllText: 'انتخاب همه',\n        deselectAllText: 'انتخاب هیچ کدام',\n        multipleSeparator: ', '\n    };\n})(jQuery);\n\n\n}));\n"
  },
  {
    "path": "app_frontend/static/plugin/bootstrap-select-1.12.2/docs/docs/dist/js/i18n/defaults-fi_FI.js",
    "content": "/*!\n * Bootstrap-select v1.12.2 (http://silviomoreto.github.io/bootstrap-select)\n *\n * Copyright 2013-2017 bootstrap-select\n * Licensed under MIT (https://github.com/silviomoreto/bootstrap-select/blob/master/LICENSE)\n */\n\n(function (root, factory) {\n  if (typeof define === 'function' && define.amd) {\n    // AMD. Register as an anonymous module unless amdModuleId is set\n    define([\"jquery\"], function (a0) {\n      return (factory(a0));\n    });\n  } else if (typeof module === 'object' && module.exports) {\n    // Node. Does not work with strict CommonJS, but\n    // only CommonJS-like environments that support module.exports,\n    // like Node.\n    module.exports = factory(require(\"jquery\"));\n  } else {\n    factory(root[\"jQuery\"]);\n  }\n}(this, function (jQuery) {\n\n(function ($) {\n  $.fn.selectpicker.defaults = {\n    noneSelectedText: 'Ei valintoja',\n    noneResultsText: 'Ei hakutuloksia {0}',\n    countSelectedText: function (numSelected, numTotal) {\n      return (numSelected == 1) ? \"{0} valittu\" : \"{0} valitut\";\n    },\n    maxOptionsText: function (numAll, numGroup) {\n      return [\n        (numAll == 1) ? 'Valintojen maksimimäärä ({n} saavutettu)' : 'Valintojen maksimimäärä ({n} saavutettu)',\n        (numGroup == 1) ? 'Ryhmän maksimimäärä ({n} saavutettu)' : 'Ryhmän maksimimäärä ({n} saavutettu)'\n      ];\n    },\n    selectAllText: 'Valitse kaikki',\n    deselectAllText: 'Poista kaikki',\n    multipleSeparator: ', '\n  };\n})(jQuery);\n\n\n}));\n"
  },
  {
    "path": "app_frontend/static/plugin/bootstrap-select-1.12.2/docs/docs/dist/js/i18n/defaults-fr_FR.js",
    "content": "/*!\n * Bootstrap-select v1.12.2 (http://silviomoreto.github.io/bootstrap-select)\n *\n * Copyright 2013-2017 bootstrap-select\n * Licensed under MIT (https://github.com/silviomoreto/bootstrap-select/blob/master/LICENSE)\n */\n\n(function (root, factory) {\n  if (typeof define === 'function' && define.amd) {\n    // AMD. Register as an anonymous module unless amdModuleId is set\n    define([\"jquery\"], function (a0) {\n      return (factory(a0));\n    });\n  } else if (typeof module === 'object' && module.exports) {\n    // Node. Does not work with strict CommonJS, but\n    // only CommonJS-like environments that support module.exports,\n    // like Node.\n    module.exports = factory(require(\"jquery\"));\n  } else {\n    factory(root[\"jQuery\"]);\n  }\n}(this, function (jQuery) {\n\n(function ($) {\n  $.fn.selectpicker.defaults = {\n    noneSelectedText: 'Aucune sélection',\n    noneResultsText: 'Aucun résultat pour {0}',\n    countSelectedText: function (numSelected, numTotal) {\n      return (numSelected > 1) ? \"{0} éléments sélectionnés\" : \"{0} élément sélectionné\";\n    },\n    maxOptionsText: function (numAll, numGroup) {\n      return [\n        (numAll > 1) ? 'Limite atteinte ({n} éléments max)' : 'Limite atteinte ({n} élément max)',\n        (numGroup > 1) ? 'Limite du groupe atteinte ({n} éléments max)' : 'Limite du groupe atteinte ({n} élément max)'\n      ];\n    },\n    multipleSeparator: ', ',\n    selectAllText: 'Tout Sélectionner',\n    deselectAllText: 'Tout Dé-selectionner',\n  };\n})(jQuery);\n\n\n}));\n"
  },
  {
    "path": "app_frontend/static/plugin/bootstrap-select-1.12.2/docs/docs/dist/js/i18n/defaults-hu_HU.js",
    "content": "/*!\n * Bootstrap-select v1.12.2 (http://silviomoreto.github.io/bootstrap-select)\n *\n * Copyright 2013-2017 bootstrap-select\n * Licensed under MIT (https://github.com/silviomoreto/bootstrap-select/blob/master/LICENSE)\n */\n\n(function (root, factory) {\n  if (typeof define === 'function' && define.amd) {\n    // AMD. Register as an anonymous module unless amdModuleId is set\n    define([\"jquery\"], function (a0) {\n      return (factory(a0));\n    });\n  } else if (typeof module === 'object' && module.exports) {\n    // Node. Does not work with strict CommonJS, but\n    // only CommonJS-like environments that support module.exports,\n    // like Node.\n    module.exports = factory(require(\"jquery\"));\n  } else {\n    factory(root[\"jQuery\"]);\n  }\n}(this, function (jQuery) {\n\n(function ($) {\n  $.fn.selectpicker.defaults = {\n    noneSelectedText: 'Válasszon!',\n    noneResultsText: 'Nincs találat {0}',\n    countSelectedText: function (numSelected, numTotal) {\n      return '{0} elem kiválasztva';\n    },\n    maxOptionsText: function (numAll, numGroup) {\n      return [\n        'Legfeljebb {n} elem választható',\n        'A csoportban legfeljebb {n} elem választható'\n      ];\n    },\n    selectAllText: 'Mind',\n    deselectAllText: 'Egyik sem',\n    multipleSeparator: ', '\n  };\n})(jQuery);\n\n\n}));\n"
  },
  {
    "path": "app_frontend/static/plugin/bootstrap-select-1.12.2/docs/docs/dist/js/i18n/defaults-id_ID.js",
    "content": "/*!\n * Bootstrap-select v1.12.2 (http://silviomoreto.github.io/bootstrap-select)\n *\n * Copyright 2013-2017 bootstrap-select\n * Licensed under MIT (https://github.com/silviomoreto/bootstrap-select/blob/master/LICENSE)\n */\n\n(function (root, factory) {\n  if (typeof define === 'function' && define.amd) {\n    // AMD. Register as an anonymous module unless amdModuleId is set\n    define([\"jquery\"], function (a0) {\n      return (factory(a0));\n    });\n  } else if (typeof module === 'object' && module.exports) {\n    // Node. Does not work with strict CommonJS, but\n    // only CommonJS-like environments that support module.exports,\n    // like Node.\n    module.exports = factory(require(\"jquery\"));\n  } else {\n    factory(root[\"jQuery\"]);\n  }\n}(this, function (jQuery) {\n\n(function ($) {\n  $.fn.selectpicker.defaults = {\n    noneSelectedText: 'Tidak ada yang dipilih',\n    noneResultsText: 'Tidak ada yang cocok {0}',\n    countSelectedText: '{0} terpilih',\n    maxOptionsText: ['Mencapai batas (maksimum {n})', 'Mencapai batas grup (maksimum {n})'],\n    selectAllText: 'Pilih Semua',\n    deselectAllText: 'Hapus Semua',\n    multipleSeparator: ', '\n  };\n})(jQuery);\n\n\n}));\n"
  },
  {
    "path": "app_frontend/static/plugin/bootstrap-select-1.12.2/docs/docs/dist/js/i18n/defaults-it_IT.js",
    "content": "/*!\n * Bootstrap-select v1.12.2 (http://silviomoreto.github.io/bootstrap-select)\n *\n * Copyright 2013-2017 bootstrap-select\n * Licensed under MIT (https://github.com/silviomoreto/bootstrap-select/blob/master/LICENSE)\n */\n\n(function (root, factory) {\n  if (typeof define === 'function' && define.amd) {\n    // AMD. Register as an anonymous module unless amdModuleId is set\n    define([\"jquery\"], function (a0) {\n      return (factory(a0));\n    });\n  } else if (typeof module === 'object' && module.exports) {\n    // Node. Does not work with strict CommonJS, but\n    // only CommonJS-like environments that support module.exports,\n    // like Node.\n    module.exports = factory(require(\"jquery\"));\n  } else {\n    factory(root[\"jQuery\"]);\n  }\n}(this, function (jQuery) {\n\n(function ($) {\n  $.fn.selectpicker.defaults = {\n    noneSelectedText: 'Nessuna selezione',\n    noneResultsText: 'Nessun risultato per {0}',\n    countSelectedText: function (numSelected, numTotal){\n      return (numSelected == 1) ? 'Selezionato {0} di {1}' : 'Selezionati {0} di {1}';\n    },\n    maxOptionsText: ['Limite raggiunto ({n} {var} max)', 'Limite del gruppo raggiunto ({n} {var} max)', ['elementi', 'elemento']],\n    multipleSeparator: ', ',\n    selectAllText: 'Seleziona Tutto',\n    deselectAllText: 'Deseleziona Tutto'\n  };\n})(jQuery);\n\n\n}));\n"
  },
  {
    "path": "app_frontend/static/plugin/bootstrap-select-1.12.2/docs/docs/dist/js/i18n/defaults-ko_KR.js",
    "content": "/*!\n * Bootstrap-select v1.12.2 (http://silviomoreto.github.io/bootstrap-select)\n *\n * Copyright 2013-2017 bootstrap-select\n * Licensed under MIT (https://github.com/silviomoreto/bootstrap-select/blob/master/LICENSE)\n */\n\n(function (root, factory) {\n  if (typeof define === 'function' && define.amd) {\n    // AMD. Register as an anonymous module unless amdModuleId is set\n    define([\"jquery\"], function (a0) {\n      return (factory(a0));\n    });\n  } else if (typeof module === 'object' && module.exports) {\n    // Node. Does not work with strict CommonJS, but\n    // only CommonJS-like environments that support module.exports,\n    // like Node.\n    module.exports = factory(require(\"jquery\"));\n  } else {\n    factory(root[\"jQuery\"]);\n  }\n}(this, function (jQuery) {\n\n(function ($) {\n  $.fn.selectpicker.defaults = {\n    noneSelectedText: '항목을 선택해주세요',\n    noneResultsText: '{0} 검색 결과가 없습니다',\n    countSelectedText: function (numSelected, numTotal) {\n      return \"{0}개를 선택하였습니다\";\n    },\n    maxOptionsText: function (numAll, numGroup) {\n      return [\n        '{n}개까지 선택 가능합니다',\n        '해당 그룹은 {n}개까지 선택 가능합니다'\n      ];\n    },\n    selectAllText: '전체선택',\n    deselectAllText: '전체해제',\n    multipleSeparator: ', '\n  };\n})(jQuery);\n\n\n}));\n"
  },
  {
    "path": "app_frontend/static/plugin/bootstrap-select-1.12.2/docs/docs/dist/js/i18n/defaults-lt_LT.js",
    "content": "/*!\n * Bootstrap-select v1.12.2 (http://silviomoreto.github.io/bootstrap-select)\n *\n * Copyright 2013-2017 bootstrap-select\n * Licensed under MIT (https://github.com/silviomoreto/bootstrap-select/blob/master/LICENSE)\n */\n\n(function (root, factory) {\n  if (typeof define === 'function' && define.amd) {\n    // AMD. Register as an anonymous module unless amdModuleId is set\n    define([\"jquery\"], function (a0) {\n      return (factory(a0));\n    });\n  } else if (typeof module === 'object' && module.exports) {\n    // Node. Does not work with strict CommonJS, but\n    // only CommonJS-like environments that support module.exports,\n    // like Node.\n    module.exports = factory(require(\"jquery\"));\n  } else {\n    factory(root[\"jQuery\"]);\n  }\n}(this, function (jQuery) {\n\n(function ($) {\n  $.fn.selectpicker.defaults = {\n    noneSelectedText: 'Niekas nepasirinkta',\n    noneResultsText: 'Niekas nesutapo su {0}',\n    countSelectedText: function (numSelected, numTotal) {\n      return (numSelected == 1) ? \"{0} elementas pasirinktas\" : \"{0} elementai(-ų) pasirinkta\";\n    },\n    maxOptionsText: function (numAll, numGroup) {\n      return [\n        (numAll == 1) ? 'Pasiekta riba ({n} elementas daugiausiai)' : 'Riba pasiekta ({n} elementai(-ų) daugiausiai)',\n        (numGroup == 1) ? 'Grupės riba pasiekta ({n} elementas daugiausiai)' : 'Grupės riba pasiekta ({n} elementai(-ų) daugiausiai)'\n      ];\n    },\n    selectAllText: 'Pasirinkti visus',\n    deselectAllText: 'Atmesti visus',\n    multipleSeparator: ', '\n  };\n})(jQuery);\n\n\n}));\n"
  },
  {
    "path": "app_frontend/static/plugin/bootstrap-select-1.12.2/docs/docs/dist/js/i18n/defaults-nb_NO.js",
    "content": "/*!\n * Bootstrap-select v1.12.2 (http://silviomoreto.github.io/bootstrap-select)\n *\n * Copyright 2013-2017 bootstrap-select\n * Licensed under MIT (https://github.com/silviomoreto/bootstrap-select/blob/master/LICENSE)\n */\n\n(function (root, factory) {\n  if (typeof define === 'function' && define.amd) {\n    // AMD. Register as an anonymous module unless amdModuleId is set\n    define([\"jquery\"], function (a0) {\n      return (factory(a0));\n    });\n  } else if (typeof module === 'object' && module.exports) {\n    // Node. Does not work with strict CommonJS, but\n    // only CommonJS-like environments that support module.exports,\n    // like Node.\n    module.exports = factory(require(\"jquery\"));\n  } else {\n    factory(root[\"jQuery\"]);\n  }\n}(this, function (jQuery) {\n\n(function ($) {\n  $.fn.selectpicker.defaults = {\n    noneSelectedText: 'Ingen valgt',\n    noneResultsText: 'Søket gir ingen treff {0}',\n    countSelectedText: function (numSelected, numTotal) {\n      return (numSelected == 1) ? \"{0} alternativ valgt\" : \"{0} alternativer valgt\";\n    },\n    maxOptionsText: function (numAll, numGroup) {\n      return [\n        (numAll == 1) ? 'Grense nådd (maks {n} valg)' : 'Grense nådd (maks {n} valg)',\n        (numGroup == 1) ? 'Grense for grupper nådd (maks {n} grupper)' : 'Grense for grupper nådd (maks {n} grupper)'\n      ];\n    },\n    selectAllText: 'Merk alle',\n    deselectAllText: 'Fjern alle',\n    multipleSeparator: ', '\n  };\n})(jQuery);\n\n\n}));\n"
  },
  {
    "path": "app_frontend/static/plugin/bootstrap-select-1.12.2/docs/docs/dist/js/i18n/defaults-nl_NL.js",
    "content": "/*!\n * Bootstrap-select v1.12.2 (http://silviomoreto.github.io/bootstrap-select)\n *\n * Copyright 2013-2017 bootstrap-select\n * Licensed under MIT (https://github.com/silviomoreto/bootstrap-select/blob/master/LICENSE)\n */\n\n(function (root, factory) {\n  if (typeof define === 'function' && define.amd) {\n    // AMD. Register as an anonymous module unless amdModuleId is set\n    define([\"jquery\"], function (a0) {\n      return (factory(a0));\n    });\n  } else if (typeof module === 'object' && module.exports) {\n    // Node. Does not work with strict CommonJS, but\n    // only CommonJS-like environments that support module.exports,\n    // like Node.\n    module.exports = factory(require(\"jquery\"));\n  } else {\n    factory(root[\"jQuery\"]);\n  }\n}(this, function (jQuery) {\n\n(function ($) {\n  $.fn.selectpicker.defaults = {\n    noneSelectedText: 'Niets geselecteerd',\n    noneResultsText: 'Geen resultaten gevonden voor {0}',\n    countSelectedText: '{0} van {1} geselecteerd',\n    maxOptionsText: ['Limiet bereikt ({n} {var} max)', 'Groep limiet bereikt ({n} {var} max)', ['items', 'item']],\n    multipleSeparator: ', '\n  };\n})(jQuery);\n\n\n}));\n"
  },
  {
    "path": "app_frontend/static/plugin/bootstrap-select-1.12.2/docs/docs/dist/js/i18n/defaults-pl_PL.js",
    "content": "/*!\n * Bootstrap-select v1.12.2 (http://silviomoreto.github.io/bootstrap-select)\n *\n * Copyright 2013-2017 bootstrap-select\n * Licensed under MIT (https://github.com/silviomoreto/bootstrap-select/blob/master/LICENSE)\n */\n\n(function (root, factory) {\n  if (typeof define === 'function' && define.amd) {\n    // AMD. Register as an anonymous module unless amdModuleId is set\n    define([\"jquery\"], function (a0) {\n      return (factory(a0));\n    });\n  } else if (typeof module === 'object' && module.exports) {\n    // Node. Does not work with strict CommonJS, but\n    // only CommonJS-like environments that support module.exports,\n    // like Node.\n    module.exports = factory(require(\"jquery\"));\n  } else {\n    factory(root[\"jQuery\"]);\n  }\n}(this, function (jQuery) {\n\n(function ($) {\n  $.fn.selectpicker.defaults = {\n    noneSelectedText: 'Nic nie zaznaczono',\n    noneResultsText: 'Brak wyników wyszukiwania {0}',\n    countSelectedText: 'Zaznaczono {0} z {1}',\n    maxOptionsText: ['Osiągnięto limit ({n} {var} max)', 'Limit grupy osiągnięty ({n} {var} max)', ['elementy', 'element']],\n    selectAll: 'Zaznacz wszystkie',\n    deselectAll: 'Odznacz wszystkie',\n    multipleSeparator: ', '\n  };\n})(jQuery);\n\n\n}));\n"
  },
  {
    "path": "app_frontend/static/plugin/bootstrap-select-1.12.2/docs/docs/dist/js/i18n/defaults-pt_BR.js",
    "content": "/*!\n * Bootstrap-select v1.12.2 (http://silviomoreto.github.io/bootstrap-select)\n *\n * Copyright 2013-2017 bootstrap-select\n * Licensed under MIT (https://github.com/silviomoreto/bootstrap-select/blob/master/LICENSE)\n */\n\n(function (root, factory) {\n  if (typeof define === 'function' && define.amd) {\n    // AMD. Register as an anonymous module unless amdModuleId is set\n    define([\"jquery\"], function (a0) {\n      return (factory(a0));\n    });\n  } else if (typeof module === 'object' && module.exports) {\n    // Node. Does not work with strict CommonJS, but\n    // only CommonJS-like environments that support module.exports,\n    // like Node.\n    module.exports = factory(require(\"jquery\"));\n  } else {\n    factory(root[\"jQuery\"]);\n  }\n}(this, function (jQuery) {\n\n(function ($) {\n  $.fn.selectpicker.defaults = {\n    noneSelectedText: 'Nada selecionado',\n    noneResultsText: 'Nada encontrado contendo {0}',\n    countSelectedText: 'Selecionado {0} de {1}',\n    maxOptionsText: ['Limite excedido (máx. {n} {var})', 'Limite do grupo excedido (máx. {n} {var})', ['itens', 'item']],\n    multipleSeparator: ', '\n  };\n})(jQuery);\n\n\n}));\n"
  },
  {
    "path": "app_frontend/static/plugin/bootstrap-select-1.12.2/docs/docs/dist/js/i18n/defaults-pt_PT.js",
    "content": "/*!\n * Bootstrap-select v1.12.2 (http://silviomoreto.github.io/bootstrap-select)\n *\n * Copyright 2013-2017 bootstrap-select\n * Licensed under MIT (https://github.com/silviomoreto/bootstrap-select/blob/master/LICENSE)\n */\n\n(function (root, factory) {\n  if (typeof define === 'function' && define.amd) {\n    // AMD. Register as an anonymous module unless amdModuleId is set\n    define([\"jquery\"], function (a0) {\n      return (factory(a0));\n    });\n  } else if (typeof module === 'object' && module.exports) {\n    // Node. Does not work with strict CommonJS, but\n    // only CommonJS-like environments that support module.exports,\n    // like Node.\n    module.exports = factory(require(\"jquery\"));\n  } else {\n    factory(root[\"jQuery\"]);\n  }\n}(this, function (jQuery) {\n\n(function ($) {\n$.fn.selectpicker.defaults = {\nnoneSelectedText: 'Nenhum seleccionado',\nnoneResultsText: 'Sem resultados contendo {0}',\ncountSelectedText: 'Selecionado {0} de {1}',\nmaxOptionsText: ['Limite ultrapassado (máx. {n} {var})', 'Limite de seleções ultrapassado (máx. {n} {var})', ['itens', 'item']],\nmultipleSeparator: ', '\n};\n})(jQuery);\n\n\n}));\n"
  },
  {
    "path": "app_frontend/static/plugin/bootstrap-select-1.12.2/docs/docs/dist/js/i18n/defaults-ro_RO.js",
    "content": "/*!\n * Bootstrap-select v1.12.2 (http://silviomoreto.github.io/bootstrap-select)\n *\n * Copyright 2013-2017 bootstrap-select\n * Licensed under MIT (https://github.com/silviomoreto/bootstrap-select/blob/master/LICENSE)\n */\n\n(function (root, factory) {\n  if (typeof define === 'function' && define.amd) {\n    // AMD. Register as an anonymous module unless amdModuleId is set\n    define([\"jquery\"], function (a0) {\n      return (factory(a0));\n    });\n  } else if (typeof module === 'object' && module.exports) {\n    // Node. Does not work with strict CommonJS, but\n    // only CommonJS-like environments that support module.exports,\n    // like Node.\n    module.exports = factory(require(\"jquery\"));\n  } else {\n    factory(root[\"jQuery\"]);\n  }\n}(this, function (jQuery) {\n\n(function ($) {\n  $.fn.selectpicker.defaults = {\n    noneSelectedText: 'Nu a fost selectat nimic',\n    noneResultsText: 'Nu exista niciun rezultat {0}',\n    countSelectedText: '{0} din {1} selectat(e)',\n    maxOptionsText: ['Limita a fost atinsa ({n} {var} max)', 'Limita de grup a fost atinsa ({n} {var} max)', ['iteme', 'item']],\n    multipleSeparator: ', '\n  };\n})(jQuery);\n\n\n}));\n"
  },
  {
    "path": "app_frontend/static/plugin/bootstrap-select-1.12.2/docs/docs/dist/js/i18n/defaults-ru_RU.js",
    "content": "/*!\n * Bootstrap-select v1.12.2 (http://silviomoreto.github.io/bootstrap-select)\n *\n * Copyright 2013-2017 bootstrap-select\n * Licensed under MIT (https://github.com/silviomoreto/bootstrap-select/blob/master/LICENSE)\n */\n\n(function (root, factory) {\n  if (typeof define === 'function' && define.amd) {\n    // AMD. Register as an anonymous module unless amdModuleId is set\n    define([\"jquery\"], function (a0) {\n      return (factory(a0));\n    });\n  } else if (typeof module === 'object' && module.exports) {\n    // Node. Does not work with strict CommonJS, but\n    // only CommonJS-like environments that support module.exports,\n    // like Node.\n    module.exports = factory(require(\"jquery\"));\n  } else {\n    factory(root[\"jQuery\"]);\n  }\n}(this, function (jQuery) {\n\n(function ($) {\n  $.fn.selectpicker.defaults = {\n    noneSelectedText: 'Ничего не выбрано',\n    noneResultsText: 'Совпадений не найдено {0}',\n    countSelectedText: 'Выбрано {0} из {1}',\n    maxOptionsText: ['Достигнут предел ({n} {var} максимум)', 'Достигнут предел в группе ({n} {var} максимум)', ['шт.', 'шт.']],\n    doneButtonText: 'Закрыть',\n    selectAllText: 'Выбрать все',\n    deselectAllText: 'Отменить все',    \n    multipleSeparator: ', '\n  };\n})(jQuery);\n\n\n}));\n"
  },
  {
    "path": "app_frontend/static/plugin/bootstrap-select-1.12.2/docs/docs/dist/js/i18n/defaults-sk_SK.js",
    "content": "/*!\n * Bootstrap-select v1.12.2 (http://silviomoreto.github.io/bootstrap-select)\n *\n * Copyright 2013-2017 bootstrap-select\n * Licensed under MIT (https://github.com/silviomoreto/bootstrap-select/blob/master/LICENSE)\n */\n\n(function (root, factory) {\n  if (typeof define === 'function' && define.amd) {\n    // AMD. Register as an anonymous module unless amdModuleId is set\n    define([\"jquery\"], function (a0) {\n      return (factory(a0));\n    });\n  } else if (typeof module === 'object' && module.exports) {\n    // Node. Does not work with strict CommonJS, but\n    // only CommonJS-like environments that support module.exports,\n    // like Node.\n    module.exports = factory(require(\"jquery\"));\n  } else {\n    factory(root[\"jQuery\"]);\n  }\n}(this, function (jQuery) {\n\n(function ($) {\n  $.fn.selectpicker.defaults = {\n    noneSelectedText: 'Vyberte zo zoznamu',\n    noneResultsText: 'Pre výraz {0} neboli nájdené žiadne výsledky',\n    countSelectedText: 'Vybrané {0} z {1}',\n    maxOptionsText: ['Limit prekročený ({n} {var} max)', 'Limit skupiny prekročený ({n} {var} max)', ['položiek', 'položka']],\n    selectAllText: 'Vybrať všetky',\n    deselectAllText: 'Zrušiť výber',\n    multipleSeparator: ', '\n  };\n})(jQuery);\n\n\n}));\n"
  },
  {
    "path": "app_frontend/static/plugin/bootstrap-select-1.12.2/docs/docs/dist/js/i18n/defaults-sl_SI.js",
    "content": "/*!\n * Bootstrap-select v1.12.2 (http://silviomoreto.github.io/bootstrap-select)\n *\n * Copyright 2013-2017 bootstrap-select\n * Licensed under MIT (https://github.com/silviomoreto/bootstrap-select/blob/master/LICENSE)\n */\n\n(function (root, factory) {\n  if (typeof define === 'function' && define.amd) {\n    // AMD. Register as an anonymous module unless amdModuleId is set\n    define([\"jquery\"], function (a0) {\n      return (factory(a0));\n    });\n  } else if (typeof module === 'object' && module.exports) {\n    // Node. Does not work with strict CommonJS, but\n    // only CommonJS-like environments that support module.exports,\n    // like Node.\n    module.exports = factory(require(\"jquery\"));\n  } else {\n    factory(root[\"jQuery\"]);\n  }\n}(this, function (jQuery) {\n\n(function ($) {\n  $.fn.selectpicker.defaults = {\n    noneSelectedText: 'Nič izbranega',\n    noneResultsText: 'Ni zadetkov za {0}',\n    countSelectedText: function (numSelected, numTotal) {\n      \"Število izbranih: {0}\";\n    },\n    maxOptionsText: function (numAll, numGroup) {\n      return [\n        'Omejitev dosežena (max. izbranih: {n})',\n        'Omejitev skupine dosežena (max. izbranih: {n})'\n      ];\n    },\n    selectAllText: 'Izberi vse',\n    deselectAllText: 'Počisti izbor',\n    multipleSeparator: ', '\n  };\n})(jQuery);\n\n\n}));\n"
  },
  {
    "path": "app_frontend/static/plugin/bootstrap-select-1.12.2/docs/docs/dist/js/i18n/defaults-sv_SE.js",
    "content": "/*!\n * Bootstrap-select v1.12.2 (http://silviomoreto.github.io/bootstrap-select)\n *\n * Copyright 2013-2017 bootstrap-select\n * Licensed under MIT (https://github.com/silviomoreto/bootstrap-select/blob/master/LICENSE)\n */\n\n(function (root, factory) {\n  if (typeof define === 'function' && define.amd) {\n    // AMD. Register as an anonymous module unless amdModuleId is set\n    define([\"jquery\"], function (a0) {\n      return (factory(a0));\n    });\n  } else if (typeof module === 'object' && module.exports) {\n    // Node. Does not work with strict CommonJS, but\n    // only CommonJS-like environments that support module.exports,\n    // like Node.\n    module.exports = factory(require(\"jquery\"));\n  } else {\n    factory(root[\"jQuery\"]);\n  }\n}(this, function (jQuery) {\n\n(function ($) {\n  $.fn.selectpicker.defaults = {\n    noneSelectedText: 'Inget valt',\n    noneResultsText: 'Inget sökresultat matchar {0}',\n    countSelectedText: function (numSelected, numTotal) {\n      return (numSelected === 1) ? \"{0} alternativ valt\" : \"{0} alternativ valda\";\n    },\n    maxOptionsText: function (numAll, numGroup) {\n      return [\n        'Gräns uppnåd (max {n} alternativ)',\n        'Gräns uppnåd (max {n} gruppalternativ)'\n      ];\n    },\n    selectAllText: 'Markera alla',\n    deselectAllText: 'Avmarkera alla',\n    multipleSeparator: ', '\n  };\n})(jQuery);\n\n\n}));\n"
  },
  {
    "path": "app_frontend/static/plugin/bootstrap-select-1.12.2/docs/docs/dist/js/i18n/defaults-tr_TR.js",
    "content": "/*!\n * Bootstrap-select v1.12.2 (http://silviomoreto.github.io/bootstrap-select)\n *\n * Copyright 2013-2017 bootstrap-select\n * Licensed under MIT (https://github.com/silviomoreto/bootstrap-select/blob/master/LICENSE)\n */\n\n(function (root, factory) {\n  if (typeof define === 'function' && define.amd) {\n    // AMD. Register as an anonymous module unless amdModuleId is set\n    define([\"jquery\"], function (a0) {\n      return (factory(a0));\n    });\n  } else if (typeof module === 'object' && module.exports) {\n    // Node. Does not work with strict CommonJS, but\n    // only CommonJS-like environments that support module.exports,\n    // like Node.\n    module.exports = factory(require(\"jquery\"));\n  } else {\n    factory(root[\"jQuery\"]);\n  }\n}(this, function (jQuery) {\n\n(function ($) {\n  $.fn.selectpicker.defaults = {\n    noneSelectedText: 'Hiçbiri seçilmedi',\n    noneResultsText: 'Hiçbir sonuç bulunamadı {0}',\n    countSelectedText: function (numSelected, numTotal) {\n      return (numSelected == 1) ? \"{0} öğe seçildi\" : \"{0} öğe seçildi\";\n    },\n    maxOptionsText: function (numAll, numGroup) {\n      return [\n        (numAll == 1) ? 'Limit aşıldı (maksimum {n} sayıda öğe )' : 'Limit aşıldı (maksimum {n} sayıda öğe)',\n        (numGroup == 1) ? 'Grup limiti aşıldı (maksimum {n} sayıda öğe)' : 'Grup limiti aşıldı (maksimum {n} sayıda öğe)'\n      ];\n    },\n    selectAllText: 'Tümünü Seç',\n    deselectAllText: 'Seçiniz',\n    multipleSeparator: ', '\n  };\n})(jQuery);\n\n\n}));\n"
  },
  {
    "path": "app_frontend/static/plugin/bootstrap-select-1.12.2/docs/docs/dist/js/i18n/defaults-ua_UA.js",
    "content": "/*!\n * Bootstrap-select v1.12.2 (http://silviomoreto.github.io/bootstrap-select)\n *\n * Copyright 2013-2017 bootstrap-select\n * Licensed under MIT (https://github.com/silviomoreto/bootstrap-select/blob/master/LICENSE)\n */\n\n(function (root, factory) {\n  if (typeof define === 'function' && define.amd) {\n    // AMD. Register as an anonymous module unless amdModuleId is set\n    define([\"jquery\"], function (a0) {\n      return (factory(a0));\n    });\n  } else if (typeof module === 'object' && module.exports) {\n    // Node. Does not work with strict CommonJS, but\n    // only CommonJS-like environments that support module.exports,\n    // like Node.\n    module.exports = factory(require(\"jquery\"));\n  } else {\n    factory(root[\"jQuery\"]);\n  }\n}(this, function (jQuery) {\n\n(function ($) {\n  $.fn.selectpicker.defaults = {\n    noneSelectedText: 'Нічого не вибрано',\n    noneResultsText: 'Збігів не знайдено {0}',\n    countSelectedText: 'Вибрано {0} із {1}',\n    maxOptionsText: ['Досягнута межа ({n} {var} максимум)', 'Досягнута межа в групі ({n} {var} максимум)', ['items', 'item']],\n    multipleSeparator: ', '\n  };\n})(jQuery);\n\n\n}));\n"
  },
  {
    "path": "app_frontend/static/plugin/bootstrap-select-1.12.2/docs/docs/dist/js/i18n/defaults-zh_CN.js",
    "content": "/*!\n * Bootstrap-select v1.12.2 (http://silviomoreto.github.io/bootstrap-select)\n *\n * Copyright 2013-2017 bootstrap-select\n * Licensed under MIT (https://github.com/silviomoreto/bootstrap-select/blob/master/LICENSE)\n */\n\n(function (root, factory) {\n  if (typeof define === 'function' && define.amd) {\n    // AMD. Register as an anonymous module unless amdModuleId is set\n    define([\"jquery\"], function (a0) {\n      return (factory(a0));\n    });\n  } else if (typeof module === 'object' && module.exports) {\n    // Node. Does not work with strict CommonJS, but\n    // only CommonJS-like environments that support module.exports,\n    // like Node.\n    module.exports = factory(require(\"jquery\"));\n  } else {\n    factory(root[\"jQuery\"]);\n  }\n}(this, function (jQuery) {\n\n(function ($) {\n  $.fn.selectpicker.defaults = {\n    noneSelectedText: '没有选中任何项',\n    noneResultsText: '没有找到匹配项',\n    countSelectedText: '选中{1}中的{0}项',\n    maxOptionsText: ['超出限制 (最多选择{n}项)', '组选择超出限制(最多选择{n}组)'],\n    multipleSeparator: ', '\n  };\n})(jQuery);\n\n\n}));\n"
  },
  {
    "path": "app_frontend/static/plugin/bootstrap-select-1.12.2/docs/docs/dist/js/i18n/defaults-zh_TW.js",
    "content": "/*!\n * Bootstrap-select v1.12.2 (http://silviomoreto.github.io/bootstrap-select)\n *\n * Copyright 2013-2017 bootstrap-select\n * Licensed under MIT (https://github.com/silviomoreto/bootstrap-select/blob/master/LICENSE)\n */\n\n(function (root, factory) {\n  if (typeof define === 'function' && define.amd) {\n    // AMD. Register as an anonymous module unless amdModuleId is set\n    define([\"jquery\"], function (a0) {\n      return (factory(a0));\n    });\n  } else if (typeof module === 'object' && module.exports) {\n    // Node. Does not work with strict CommonJS, but\n    // only CommonJS-like environments that support module.exports,\n    // like Node.\n    module.exports = factory(require(\"jquery\"));\n  } else {\n    factory(root[\"jQuery\"]);\n  }\n}(this, function (jQuery) {\n\n(function ($) {\n  $.fn.selectpicker.defaults = {\n    noneSelectedText: '沒有選取任何項目',\n    noneResultsText: '沒有找到符合的結果',\n    countSelectedText: '已經選取{0}個項目',\n    maxOptionsText: ['超過限制 (最多選擇{n}項)', '超過限制(最多選擇{n}組)'],\n    selectAllText: '選取全部',\n    deselectAllText: '全部取消',\n    multipleSeparator: ', '\n  };\n})(jQuery);\n\n\n}));\n"
  },
  {
    "path": "app_frontend/static/plugin/bootstrap-select-1.12.2/docs/docs/examples.md",
    "content": "# Basic examples\n\n---\n## Standard select boxes\n\n<div class=\"bs-docs-example\">\n  <p>Make this:</p>\n\n  <select>\n    <option>Mustard</option>\n    <option>Ketchup</option>\n    <option>Relish</option>\n  </select>\n\n  <p>Become this:</p>\n\n  <select class=\"selectpicker\">\n    <option>Mustard</option>\n    <option>Ketchup</option>\n    <option>Relish</option>\n  </select>\n</div>\n\n```html\n<select class=\"selectpicker\">\n  <option>Mustard</option>\n  <option>Ketchup</option>\n  <option>Relish</option>\n</select>\n```\n\n<div id=\"optgroup\"></div>\n## Select boxes with optgroups\n\n<div class=\"bs-docs-example\">\n  <select class=\"selectpicker\">\n    <optgroup label=\"Picnic\">\n      <option>Mustard</option>\n      <option>Ketchup</option>\n      <option>Relish</option>\n    </optgroup>\n    <optgroup label=\"Camping\">\n      <option>Tent</option>\n      <option>Flashlight</option>\n      <option>Toilet Paper</option>\n    </optgroup>\n  </select>\n</div>\n\n```html\n<select class=\"selectpicker\">\n  <optgroup label=\"Picnic\">\n    <option>Mustard</option>\n    <option>Ketchup</option>\n    <option>Relish</option>\n  </optgroup>\n  <optgroup label=\"Camping\">\n    <option>Tent</option>\n    <option>Flashlight</option>\n    <option>Toilet Paper</option>\n  </optgroup>\n</select>\n```\n\n## Multiple select boxes\n\n<div class=\"bs-docs-example\">\n  <select class=\"selectpicker\" multiple>\n    <option>Mustard</option>\n    <option>Ketchup</option>\n    <option>Relish</option>\n  </select>\n</div>\n\n```html\n<select class=\"selectpicker\" multiple>\n  <option>Mustard</option>\n  <option>Ketchup</option>\n  <option>Relish</option>\n</select>\n```\n\n# Live search\n\n---\n\n## Live search\n\nYou can add a search input by passing `data-live-search=\"true\"` attribute:\n\n<div class=\"bs-docs-example no-code\">\n  <select class=\"selectpicker\" data-live-search=\"true\">\n    <option>Hot Dog, Fries and a Soda</option>\n    <option>Burger, Shake and a Smile</option>\n    <option>Sugar, Spice and all things nice</option>\n  </select>\n</div>\n\n## Key words\n\nAdd key words to options to improve their searchability using `data-tokens`.\n\n<div class=\"bs-docs-example\">\n  <select class=\"selectpicker\" data-live-search=\"true\">\n    <option data-tokens=\"ketchup mustard\">Hot Dog, Fries and a Soda</option>\n    <option data-tokens=\"mustard\">Burger, Shake and a Smile</option>\n    <option data-tokens=\"frosting\">Sugar, Spice and all things nice</option>\n  </select>\n</div>\n\n```html\n<select class=\"selectpicker\" data-live-search=\"true\">\n  <option data-tokens=\"ketchup mustard\">Hot Dog, Fries and a Soda</option>\n  <option data-tokens=\"mustard\">Burger, Shake and a Smile</option>\n  <option data-tokens=\"frosting\">Sugar, Spice and all things nice</option>\n</select>\n```\n\n# Limit the number of selections\n\nLimit the number of options that can be selected via the `data-max-options` attribute. It also works for option groups. Customize the message displayed when the limit is reached with `maxOptionsText`.\n\n<div class=\"bs-docs-example\">\n  <select class=\"selectpicker\" multiple data-max-options=\"2\">\n    <option>Mustard</option>\n    <option>Ketchup</option>\n    <option>Relish</option>\n  </select>\n\n  <select class=\"selectpicker\" multiple>\n    <optgroup label=\"Condiments\" data-max-options=\"2\">\n      <option>Mustard</option>\n      <option>Ketchup</option>\n      <option>Relish</option>\n    </optgroup>\n    <optgroup label=\"Breads\" data-max-options=\"2\">\n      <option>Plain</option>\n      <option>Steamed</option>\n      <option>Toasted</option>\n    </optgroup>\n  </select>\n</div>\n\n```html\n<select class=\"selectpicker\" multiple data-max-options=\"2\">\n  <option>Mustard</option>\n  <option>Ketchup</option>\n  <option>Relish</option>\n</select>\n\n<select class=\"selectpicker\" multiple>\n  <optgroup label=\"Condiments\" data-max-options=\"2\">\n    <option>Mustard</option>\n    <option>Ketchup</option>\n    <option>Relish</option>\n  </optgroup>\n  <optgroup label=\"Breads\" data-max-options=\"2\">\n    <option>Plain</option>\n    <option>Steamed</option>\n    <option>Toasted</option>\n  </optgroup>\n</select>\n```\n\n# Custom button text\n\n---\n\n## Placeholder\n<p id=\"titleMultiples\"></p>\nUsing the `title` attribute will set the default placeholder text when nothing is selected. This works for both multiple and standard select boxes:\n\n<div class=\"bs-docs-example\">\n  <div class=\"form-group\">\n    <label>Multiple</label>\n    <select class=\"selectpicker\" multiple title=\"Choose one of the following...\">\n      <option>Mustard</option>\n      <option>Ketchup</option>\n      <option>Relish</option>\n    </select>\n  </div>\n\n  <div class=\"form-group\">\n    <label>Standard</label>\n    <select class=\"selectpicker\" title=\"Choose one of the following...\">\n      <option>Mustard</option>\n      <option>Ketchup</option>\n      <option>Relish</option>\n    </select>\n  </div>\n</div>\n\n```html\n<select class=\"selectpicker\" multiple title=\"Choose one of the following...\">\n  <option>Mustard</option>\n  <option>Ketchup</option>\n  <option>Relish</option>\n</select>\n```\n\n## Selected text\n\n<p id=\"title\"></p>\nSet the `title` attribute on individual options to display alternative text when the option is selected:\n\n<div class=\"bs-docs-example no-code\">\n  <select class=\"selectpicker\">\n    <option title=\"Combo 1\">Hot Dog, Fries and a Soda</option>\n    <option title=\"Combo 2\">Burger, Shake and a Smile</option>\n    <option title=\"Combo 3\">Sugar, Spice and all things nice</option>\n  </select>\n</div>\n\n```html\n<select class=\"selectpicker\">\n  <option title=\"Combo 1\">Hot Dog, Fries and a Soda</option>\n  <option title=\"Combo 2\">Burger, Shake and a Smile</option>\n  <option title=\"Combo 3\">Sugar, Spice and all things nice</option>\n</select>\n```\n## Selected text format\n\n<p id=\"titleMultiplesFormat\"></p>\nSpecify how the selection is displayed with the `data-selected-text-format` attribute on a multiple select.\n\nThe supported values are:\n\n* `values`: A comma delimited list of selected values (default)\n* `count`: If one item is selected, then the option value is shown. If more than one is selected then the number of selected items is displayed, e.g. `2 of 6 selected`\n* `count > x`: Where `x` is the number of items selected when the display format changes from `values` to `count`\n* `static`: Always show the select title (placeholder), regardless of selection\n\n<div class=\"bs-docs-example\">\n  <select class=\"selectpicker\" multiple data-selected-text-format=\"count\">\n    <option>Mustard</option>\n    <option>Ketchup</option>\n    <option>Relish</option>\n  </select>\n</div>\n\n```html\n<select class=\"selectpicker\" multiple data-selected-text-format=\"count\">\n  <option>Mustard</option>\n  <option>Ketchup</option>\n  <option>Relish</option>\n</select>\n```\n\n<div class=\"bs-docs-example\">\n  <select class=\"selectpicker\" multiple data-selected-text-format=\"count > 3\">\n    <option>Mustard</option>\n    <option>Ketchup</option>\n    <option>Relish</option>\n    <option>Onions</option>\n  </select>\n</div>\n\n```html\n<select class=\"selectpicker\" multiple data-selected-text-format=\"count > 3\">\n  <option>Mustard</option>\n  <option>Ketchup</option>\n  <option>Relish</option>\n  <option>Onions</option>\n</select>\n```\n\n# Styling\n\n---\n\n## Button classes\n\nYou can set the button classes via the `data-style` attribute:\n\n<div class=\"bs-docs-example\">\n  <div class=\"form-group\">\n    <select class=\"selectpicker\" data-style=\"btn-primary\">\n      <option>Mustard</option>\n      <option>Ketchup</option>\n      <option>Relish</option>\n    </select>\n  </div>\n  <div class=\"form-group\">\n    <select class=\"selectpicker\" data-style=\"btn-info\">\n      <option>Mustard</option>\n      <option>Ketchup</option>\n      <option>Relish</option>\n    </select>\n  </div>\n  <div class=\"form-group\">\n    <select class=\"selectpicker\" data-style=\"btn-success\">\n      <option>Mustard</option>\n      <option>Ketchup</option>\n      <option>Relish</option>\n    </select>\n  </div>\n  <div class=\"form-group\">\n    <select class=\"selectpicker\" data-style=\"btn-warning\">\n      <option>Mustard</option>\n      <option>Ketchup</option>\n      <option>Relish</option>\n    </select>\n  </div>\n  <div class=\"form-group\">\n    <select class=\"selectpicker\" data-style=\"btn-danger\">\n      <option>Mustard</option>\n      <option>Ketchup</option>\n      <option>Relish</option>\n    </select>\n  </div>\n</div>\n\n```html\n<select class=\"selectpicker\" data-style=\"btn-primary\">\n  ...\n</select>\n\n<select class=\"selectpicker\" data-style=\"btn-info\">\n  ...\n</select>\n\n<select class=\"selectpicker\" data-style=\"btn-success\">\n  ...\n</select>\n\n<select class=\"selectpicker\" data-style=\"btn-warning\">\n  ...\n</select>\n\n<select class=\"selectpicker\" data-style=\"btn-danger\">\n  ...\n</select>\n```\n\n## Checkmark on selected option\n\nYou can also show the checkmark icon on standard select boxes with the `show-tick` class:\n\n<div class=\"bs-docs-example\">\n  <select class=\"selectpicker show-tick\">\n    <option>Mustard</option>\n    <option>Ketchup</option>\n    <option>Relish</option>\n  </select>\n</div>\n\n```html\n<select class=\"selectpicker show-tick\">\n  <option>Mustard</option>\n  <option>Ketchup</option>\n  <option>Relish</option>\n</select>\n```\n\n## Menu arrow\n\nThe Bootstrap menu arrow can be added with the `show-menu-arrow` class:\n\n<div class=\"bs-docs-example\">\n  <select class=\"selectpicker show-menu-arrow\">\n    <option>Mustard</option>\n    <option>Ketchup</option>\n    <option>Relish</option>\n  </select>\n</div>\n\n```html\n<select class=\"selectpicker show-menu-arrow\">\n  <option>Mustard</option>\n  <option>Ketchup</option>\n  <option>Relish</option>\n</select>\n```\n\n## Style individual options\n\n<p id=\"classes\"></p>\nClasses and styles added to options are transferred to the select box:\n\n<div class=\"bs-docs-example\">\n  <select class=\"selectpicker\">\n    <option>Mustard</option>\n    <option class=\"special\">Ketchup</option>\n    <option style=\"background: #5cb85c; color: #fff;\">Relish</option>\n  </select>\n</div>\n\n```html\n<select class=\"selectpicker\">\n  <option>Mustard</option>\n  <option class=\"special\">Ketchup</option>\n  <option style=\"background: #5cb85c; color: #fff;\">Relish</option>\n</select>\n```\n\n```css\n.special {\n  font-weight: bold !important;\n  color: #fff !important;\n  background: #bc0000 !important;\n  text-transform: uppercase;\n}\n```\n\n## Width\n\n<p id=\"grid\"></p>\nWrap selects in grid columns, or any custom parent element, to easily enforce desired widths.\n\n<div class=\"bs-docs-example\">\n  <div class=\"row\">\n    <div class=\"col-xs-3\">\n      <div class=\"form-group\">\n        <select class=\"selectpicker form-control\">\n          <option>Mustard</option>\n          <option>Ketchup</option>\n          <option>Relish</option>\n        </select>\n      </div>\n    </div>\n    <div class=\"col-xs-9\">\n      <div class=\"form-group\">\n        <select class=\"selectpicker form-control\">\n          <option>Mustard</option>\n          <option>Ketchup</option>\n          <option>Relish</option>\n        </select>\n      </div>\n    </div>\n  </div>\n  <div class=\"row\">\n    <div class=\"col-xs-4\">\n       <div class=\"form-group\">\n        <select class=\"selectpicker form-control\">\n          <option>Mustard</option>\n          <option>Ketchup</option>\n          <option>Relish</option>\n        </select>\n      </div>\n    </div>\n    <div class=\"col-xs-8\">\n       <div class=\"form-group\">\n        <select class=\"selectpicker form-control\">\n          <option>Mustard</option>\n          <option>Ketchup</option>\n          <option>Relish</option>\n        </select>\n      </div>\n    </div>\n  </div>\n  <div class=\"row\">\n    <div class=\"col-xs-5\">\n      <div class=\"form-group\">\n        <select class=\"selectpicker form-control\">\n          <option>Mustard</option>\n          <option>Ketchup</option>\n          <option>Relish</option>\n        </select>\n      </div>\n    </div>\n    <div class=\"col-xs-7\">\n      <div class=\"form-group\">\n        <select class=\"selectpicker form-control\">\n          <option>Mustard</option>\n          <option>Ketchup</option>\n          <option>Relish</option>\n        </select>\n      </div>\n    </div>\n  </div>\n</div>\n\n```html\n<div class=\"row\">\n  <div class=\"col-xs-3\">\n    <div class=\"form-group\">\n      <select class=\"selectpicker form-control\">\n        <option>Mustard</option>\n        <option>Ketchup</option>\n        <option>Relish</option>\n      </select>\n    </div>\n  </div>\n</div>\n```\n\n<div id=\"data-width\"></div>\n\nAlternatively, use the `data-width` attribute to set the width of the select. Set `data-width` to `'auto'` to automatically adjust the width of the select to its widest option. `'fit'` automatically adjusts the width of the select to the width of its currently selected option. An exact value can also be specified, e.g., `300px` or `50%`.\n\n<div class=\"bs-docs-example\">\n  <div class=\"row\">\n    <div class=\"col-xs-12\">\n      <div class=\"form-group\">\n        <label>width: 'auto'</label>\n        <select class=\"selectpicker form-control\" data-width=\"auto\">\n          <option>Mustard</option>\n          <option>Ketchup</option>\n          <option>Relish</option>\n          <option>All of the above (and much, much more!)</option>\n        </select>\n      </div>\n    </div>\n  </div>\n  <div class=\"row\">\n    <div class=\"col-xs-12\">\n      <div class=\"form-group\">\n        <label>width: 'fit'</label>\n        <select class=\"selectpicker form-control\" data-width=\"fit\">\n          <option>Mustard</option>\n          <option>Ketchup</option>\n          <option>Relish</option>\n          <option>All of the above (and much, much more!)</option>\n        </select>\n      </div>\n    </div>\n  </div>\n  <div class=\"row\">\n    <div class=\"col-xs-12\">\n      <div class=\"form-group\">\n        <label>width: '100px'</label>\n        <select class=\"selectpicker form-control\" data-width=\"100px\">\n          <option>Mustard</option>\n          <option>Ketchup</option>\n          <option>Relish</option>\n          <option>All of the above (and much, much more!)</option>\n        </select>\n      </div>\n    </div>\n  </div>\n  <div class=\"row\">\n    <div class=\"col-xs-12\">\n      <div class=\"form-group\">\n        <label>width: '75%'</label>\n        <select class=\"selectpicker form-control\" data-width=\"75%\">\n          <option>Mustard</option>\n          <option>Ketchup</option>\n          <option>Relish</option>\n          <option>All of the above (and much, much more!)</option>\n        </select>\n      </div>\n    </div>\n  </div>\n</div>\n\n```html\n<select class=\"selectpicker\" data-width=\"auto\">\n  ...\n</select>\n<select class=\"selectpicker\" data-width=\"fit\">\n  ...\n</select>\n<select class=\"selectpicker\" data-width=\"100px\">\n  ...\n</select>\n<select class=\"selectpicker\" data-width=\"75%\">\n  ...\n</select>\n```\n\n# Customize options\n\n---\n\n## Icons\n\nAdd an icon to an option or optgroup with the `data-icon` attribute:\n\n<div class=\"bs-docs-example\">\n  <select class=\"selectpicker\">\n    <option data-icon=\"glyphicon-glass\">Mustard</option>\n    <option data-icon=\"glyphicon-heart\">Ketchup</option>\n    <option data-icon=\"glyphicon-film\">Relish</option>\n    <option data-icon=\"glyphicon-home\">Mayonnaise</option>\n    <option data-icon=\"glyphicon-print\">Barbecue Sauce</option>\n  </select>\n</div>\n\n```html\n<select class=\"selectpicker\">\n  <option data-icon=\"glyphicon-heart\">Ketchup</option>\n</select>\n```\n\n## Custom content\n\nInsert custom HTML into the option with the `data-content` attribute:\n\n<div class=\"bs-docs-example\">\n  <select class=\"selectpicker\">\n    <option data-content=\"<span class='label label-warning'>Mustard</span>\">Mustard</option>\n    <option data-content=\"<span class='label label-danger label-important'>Ketchup</span>\">Ketchup</option>\n    <option data-content=\"<span class='label label-success'>Relish</span>\">Relish</option>\n    <option data-content=\"<span class='label label-info'>Mayonnaise</span>\">Mayonnaise</option>\n  </select>\n</div>\n\n```html\n<select class=\"selectpicker\">\n  <option data-content=\"<span class='label label-success'>Relish</span>\">Relish</option>\n</select>\n```\n\n## Subtext\nAdd subtext to an option or optgroup with the `data-subtext` attribute:\n\n<div class=\"bs-docs-example\">\n  <div class=\"form-group\">\n    <select class=\"selectpicker\">\n      <option data-subtext=\"French's\">Mustard</option>\n      <option data-subtext=\"Heinz\">Ketchup</option>\n      <option data-subtext=\"Sweet\">Relish</option>\n      <option data-subtext=\"Miracle Whip\">Mayonnaise</option>\n      <option data-divider=\"true\"></option>\n      <option data-subtext=\"Honey\">Barbecue Sauce</option>\n      <option data-subtext=\"Ranch\">Salad Dressing</option>\n      <option data-subtext=\"Sweet & Spicy\">Tabasco</option>\n      <option data-subtext=\"Chunky\">Salsa</option>\n    </select>\n  </div>\n\n  <div class=\"form-group\">\n    <select class=\"selectpicker\" data-show-subtext=\"true\">\n      <option data-subtext=\"French's\">Mustard</option>\n      <option data-subtext=\"Heinz\">Ketchup</option>\n      <option data-subtext=\"Sweet\">Relish</option>\n      <option data-subtext=\"Miracle Whip\">Mayonnaise</option>\n      <option data-divider=\"true\"></option>\n      <option data-subtext=\"Honey\">Barbecue Sauce</option>\n      <option data-subtext=\"Ranch\">Salad Dressing</option>\n      <option data-subtext=\"Sweet & Spicy\">Tabasco</option>\n      <option data-subtext=\"Chunky\">Salsa</option>\n    </select>\n    <span class=\"help-block\">With <code>showSubtext</code> set to true.</span>\n  </div>\n</div>\n\n```html\n<select class=\"selectpicker\" data-size=\"5\">\n  <option data-subtext=\"Heinz\">Ketchup</option>\n</select>\n```\n\n# Customize menu\n\n---\n\n## Menu size\n\nThe `size` option is set to `'auto'` by default. When `size` is set to `'auto'`, the menu always opens up to show as many items as the window will allow without being cut off. Set `size` to `false` to always show all items. The size of the menu can also be specifed using the `data-size` attribute.\n\n<div class=\"bs-docs-example\">\n  <select class=\"selectpicker\">\n    <option>Mustard</option>\n    <option>Ketchup</option>\n    <option>Relish</option>\n    <option>Mayonnaise</option>\n    <option>Barbecue Sauce</option>\n    <option>Salad Dressing</option>\n    <option>Tabasco</option>\n    <option>Salsa</option>\n    <option>Mustard</option>\n    <option>Ketchup</option>\n    <option>Relish</option>\n    <option>Mayonnaise</option>\n    <option>Barbecue Sauce</option>\n    <option>Salad Dressing</option>\n    <option>Tabasco</option>\n    <option>Salsa</option>\n    <option>Mustard</option>\n    <option>Ketchup</option>\n    <option>Relish</option>\n    <option>Mayonnaise</option>\n    <option>Barbecue Sauce</option>\n    <option>Salad Dressing</option>\n    <option>Tabasco</option>\n    <option>Salsa</option>\n  </select>\n</div>\n\n<p id=\"data-size\"></p>\nSpecify a number for `data-size` to choose the maximum number of items to show in the menu.\n\n<div class=\"bs-docs-example\">\n  <select class=\"selectpicker\" data-size=\"5\">\n    <option>Mustard</option>\n    <option>Ketchup</option>\n    <option>Relish</option>\n    <option>Mayonnaise</option>\n    <option>Barbecue Sauce</option>\n    <option>Salad Dressing</option>\n    <option>Tabasco</option>\n    <option>Salsa</option>\n  </select>\n</div>\n\n```html\n<select class=\"selectpicker\" data-size=\"5\">\n  ...\n</select>\n```\n\n## Select/deselect all options\n\nAdds two buttons to the top of the menu - **Select All** & **Deselect All** with `data-actions-box=\"true\"`.\n\n<div class=\"bs-docs-example\">\n  <select class=\"selectpicker\" multiple data-actions-box=\"true\">\n    <option>Mustard</option>\n    <option>Ketchup</option>\n    <option>Relish</option>\n  </select>\n</div>\n\n```html\n<select class=\"selectpicker\" multiple data-actions-box=\"true\">\n  <option>Mustard</option>\n  <option>Ketchup</option>\n  <option>Relish</option>\n</select>\n```\n\n## Divider\n\nAdd `data-divider=\"true\"` to an option to turn it into a divider.\n\n<div class=\"bs-docs-example\">\n  <select class=\"selectpicker\">\n    <option>Mustard</option>\n    <option>Ketchup</option>\n    <option>Relish</option>\n    <option>Mayonnaise</option>\n    <option data-divider=\"true\"></option>\n    <option>Barbecue Sauce</option>\n    <option>Salad Dressing</option>\n    <option>Tabasco</option>\n    <option>Salsa</option>\n  </select>\n</div>\n\n```html\n<select class=\"selectpicker\" data-size=\"5\">\n  <option data-divider=\"true\"></option>\n</select>\n```\n\n## Menu header\n\nAdd a header to the dropdown menu, e.g. `header: 'Select a condiment'` or `data-header=\"Select a condiment\"`\n\n<div class=\"bs-docs-example\">\n  <div class=\"row-fluid\">\n    <select class=\"selectpicker\" data-header=\"Select a condiment\">\n      <option data-subtext=\"French's\">Mustard</option>\n      <option data-subtext=\"Heinz\">Ketchup</option>\n      <option data-subtext=\"Sweet\">Relish</option>\n      <option data-subtext=\"Miracle Whip\">Mayonnaise</option>\n      <option data-divider=\"true\"></option>\n      <option data-subtext=\"Honey\">Barbecue Sauce</option>\n      <option data-subtext=\"Ranch\">Salad Dressing</option>\n      <option data-subtext=\"Sweet & Spicy\">Tabasco</option>\n      <option data-subtext=\"Chunky\">Salsa</option>\n    </select>\n  </div>\n</div>\n\n```html\n<select class=\"selectpicker\" data-header=\"Select a condiment\">\n  ...\n</select>\n```\n\n## Container\n\nAppend the select to a specific element, e.g. `container: 'body'` or `data-container=\".main-content\"`\n\n<div class=\"bs-docs-example\" style=\"overflow:hidden;\">\n  <div class=\"row-fluid\">\n    <select class=\"selectpicker\">\n      <option data-subtext=\"French's\">Mustard</option>\n      <option data-subtext=\"Heinz\">Ketchup</option>\n      <option data-subtext=\"Sweet\">Relish</option>\n      <option data-subtext=\"Miracle Whip\">Mayonnaise</option>\n      <option data-divider=\"true\"></option>\n      <option data-subtext=\"Honey\">Barbecue Sauce</option>\n      <option data-subtext=\"Ranch\">Salad Dressing</option>\n      <option data-subtext=\"Sweet & Spicy\">Tabasco</option>\n      <option data-subtext=\"Chunky\">Salsa</option>\n    </select>\n    <select class=\"selectpicker\" data-container=\"body\">\n      <option data-subtext=\"French's\">Mustard</option>\n      <option data-subtext=\"Heinz\">Ketchup</option>\n      <option data-subtext=\"Sweet\">Relish</option>\n      <option data-subtext=\"Miracle Whip\">Mayonnaise</option>\n      <option data-divider=\"true\"></option>\n      <option data-subtext=\"Honey\">Barbecue Sauce</option>\n      <option data-subtext=\"Ranch\">Salad Dressing</option>\n      <option data-subtext=\"Sweet & Spicy\">Tabasco</option>\n      <option data-subtext=\"Chunky\">Salsa</option>\n    </select>\n  </div>\n</div>\n\n```html\n<div style=\"overflow:hidden;\">\n  <select class=\"selectpicker\">\n    ...\n  </select>\n  <select class=\"selectpicker\" data-container=\"body\">\n    ...\n  </select>\n</div>\n```\n\n## Dropup menu\n\n`dropupAuto` is set to true by default, which automatically determines whether or not the menu should display above or below the select box. If `dropupAuto` is set to false, manually make the select a dropup menu by adding the `.dropup` class to the select.\n\n<div class=\"bs-docs-example\">\n  <select class=\"selectpicker dropup\">\n    <option>Mustard</option>\n    <option>Ketchup</option>\n    <option>Relish</option>\n  </select>\n</div>\n\n```html\n<select class=\"selectpicker dropup\">\n  ...\n</select>\n```\n\n# Disabled\n\n---\n\n## Disabled select box\n\n<div class=\"bs-docs-example\">\n  <select class=\"selectpicker\" disabled>\n    <option>Mustard</option>\n    <option>Ketchup</option>\n    <option>Relish</option>\n  </select>\n</div>\n\n```html\n<select class=\"selectpicker\" disabled>\n  <option>Mustard</option>\n  <option>Ketchup</option>\n  <option>Relish</option>\n</select>\n```\n\n## Disabled options\n\n<div class=\"bs-docs-example\">\n  <select class=\"selectpicker\">\n    <option>Mustard</option>\n    <option disabled>Ketchup</option>\n    <option>Relish</option>\n  </select>\n</div>\n\n```html\n<select class=\"selectpicker\">\n  <option>Mustard</option>\n  <option disabled>Ketchup</option>\n  <option>Relish</option>\n</select>\n```\n\n## Disabled option groups\n\n<div class=\"bs-docs-example\">\n  <select class=\"selectpicker test\">\n    <optgroup label=\"Picnic\" disabled>\n      <option>Mustard</option>\n      <option>Ketchup</option>\n      <option>Relish</option>\n    </optgroup>\n    <optgroup label=\"Camping\">\n      <option>Tent</option>\n      <option>Flashlight</option>\n      <option>Toilet Paper</option>\n    </optgroup>\n  </select>\n</div>\n\n```html\n<select class=\"selectpicker test\">\n  <optgroup label=\"Picnic\" disabled>\n    <option>Mustard</option>\n    <option>Ketchup</option>\n    <option>Relish</option>\n  </optgroup>\n  <optgroup label=\"Camping\">\n    <option>Tent</option>\n    <option>Flashlight</option>\n    <option>Toilet Paper</option>\n  </optgroup>\n</select>\n```"
  },
  {
    "path": "app_frontend/static/plugin/bootstrap-select-1.12.2/docs/docs/index.md",
    "content": "# Getting Started\n\n---\n\n## Dependencies\n\nRequires jQuery v1.8.0+, Bootstrap’s dropdown.js component, and Bootstrap's CSS. If you're not already using Bootstrap in your project, a precompiled version of the minimum requirements can be downloaded [here](http://getbootstrap.com/customize/?id=7830063837006f6fc84f).\n\n## CDNJS\n\nThe folks at CDNJS host a copy of the library. The CDN is updated after the release is made public, which means there is a delay between the publishing of a release and its availability on the CDN, so keep that in mind. Just use these links:\n\n```html\n<!-- Latest compiled and minified CSS -->\n<link rel=\"stylesheet\" href=\"https://cdnjs.cloudflare.com/ajax/libs/bootstrap-select/1.12.2/css/bootstrap-select.min.css\">\n\n<!-- Latest compiled and minified JavaScript -->\n<script src=\"https://cdnjs.cloudflare.com/ajax/libs/bootstrap-select/1.12.2/js/bootstrap-select.min.js\"></script>\n\n<!-- (Optional) Latest compiled and minified JavaScript translation files -->\n<script src=\"https://cdnjs.cloudflare.com/ajax/libs/bootstrap-select/1.12.2/js/i18n/defaults-*.min.js\"></script>\n```\n\n## Install with Bower\n\nYou can also install bootstrap-select using [Bower](http://bower.io):\n\n```elixir\n$ bower install bootstrap-select\n```\n\n## Install with npm\n\nYou can also install bootstrap-select using [npm](https://www.npmjs.com/package/bootstrap-select):\n\n```elixir\n$ npm install bootstrap-select\n```\n\n## Install with NuGet\n\nYou can also install bootstrap-select using [NuGet](https://www.nuget.org/packages/bootstrap-select):\n\n```elixir\n$ Install-Package bootstrap-select\n```\n\n# Usage\n\n---\n\nCreate your `<select>` with the `.selectpicker` class. The data-api will automatically theme these elements.\n\n```html\n<select class=\"selectpicker\">\n  <option>Mustard</option>\n  <option>Ketchup</option>\n  <option>Relish</option>\n</select>\n```\n\nOptions can be passed via data attributes or JavaScript.\n\n```js\n$('.selectpicker').selectpicker({\n  style: 'btn-info',\n  size: 4\n});\n```\n\n# Used by\n\n---\n\n<div class=\"row logo-block\">\n\t<div class=\"logo-container\">\n\t\t<a href=\"https://snapappointments.com\" target=\"_blank\"><img src=\"img/logos/snapappointments.png\" alt=\"SnapAppointments\"></a>\n\t</div>\n\t<div class=\"logo-container\">\n\t\t<a href=\"https://www.thermofisher.com\" target=\"_blank\"><img src=\"img/logos/thermofisher.png\" alt=\"Thermo Fisher Scientific Inc.\"></a>\n\t</div>\n\t<div class=\"logo-container\">\n\t\t<a href=\"https://www.membermeister.com\" target=\"_blank\"><img src=\"img/logos/membermeister.png\" alt=\"membermeister\"></a>\n\t</div>\n\t<div class=\"logo-container\">\n\t\t<a href=\"https://solveforall.com\" target=\"_blank\"><img src=\"img/logos/solveforall.png\" alt=\"Solve for All\"></a>\n\t</div>\n\t<div class=\"logo-container\">\n\t\t<a href=\"http://www.123itworks.co.uk\" target=\"_blank\"><img src=\"img/logos/estimateit.png\" alt=\"EstiMATEit\"></a>\n\t</div>\n\t<div class=\"logo-container\">\n\t\t<a href=\"https://convertizer.com\" target=\"_blank\"><img src=\"img/logos/convertizer.png\" alt=\"Convertizer\"></a>\n\t</div>\n</div>\n\n<div class=\"text-muted\">Does your organization use bootstrap-select? Open an issue, and include a link and logo, and you'll be added to the list.</div>\n\n\n"
  },
  {
    "path": "app_frontend/static/plugin/bootstrap-select-1.12.2/docs/docs/methods.md",
    "content": "# Methods\n\nInterface with bootstrap-select.\n\n---\n\n#### `.selectpicker('val')`\n\nYou can set the selected value by calling the `val` method on the element.\n\n```js\n$('.selectpicker').selectpicker('val', 'Mustard');\n$('.selectpicker').selectpicker('val', ['Mustard','Relish']);\n```\n\nThis is different to calling `val()` directly on the `select` element. If you call `val()` on the element directly, the bootstrap-select ui will not refresh (as the change event only fires from user interaction). You will have to call the ui refresh method yourself.\n\n```js\n$('.selectpicker').val('Mustard');\n$('.selectpicker').selectpicker('render');\n\n// this is the equivalent of the above\n$('.selectpicker').selectpicker('val', 'Mustard');\n```\n\n---\n\n#### `.selectpicker('selectAll')`\n\nThis will select all items in a multi-select.\n\n```js\n$('.selectpicker').selectpicker('selectAll');\n```\n\n---\n\n#### `.selectpicker('deselectAll')`\n\nThis will deselect all items in a multi-select.\n\n```js\n$('.selectpicker').selectpicker('deselectAll');\n```\n\n---\n\n#### `.selectpicker('render')`\n\nYou can force a re-render of the bootstrap-select ui with the `render` method. This is useful if you programatically change any underlying values that affect the layout of the element.\n\n```js\n$('.selectpicker').selectpicker('render');\n```\n\n---\n\n#### `.selectpicker('mobile')`\n\nEnable mobile scrolling by calling `$('.selectpicker').selectpicker('mobile')`. This enables the device's native menu for select menus.\n\nThe method for detecting the browser is left up to the user.\n\n```js\nif( /Android|webOS|iPhone|iPad|iPod|BlackBerry/i.test(navigator.userAgent) ) {\n  $('.selectpicker').selectpicker('mobile');\n}\n```\n\n---\n\n#### `.selectpicker('setStyle')`\n\nModify the class(es) associated with either the button itself or its container.\n\nIf changing the class on the container:\n\n```js\n$('.selectpicker').addClass('col-lg-12').selectpicker('setStyle');\n```\n\nIf changing the class(es) on the button (altering data-style):\n\n```js\n// Replace Class\n$('.selectpicker').selectpicker('setStyle', 'btn-danger');\n\n// Add Class\n$('.selectpicker').selectpicker('setStyle', 'btn-large', 'add');\n\n// Remove Class\n$('.selectpicker').selectpicker('setStyle', 'btn-large', 'remove');\n```\n\n\n---\n\n#### `.selectpicker('refresh')`\n\nTo programmatically update a select with JavaScript, first manipulate the select, then use the `refresh` method to \nupdate the UI to match the new state. This is necessary when removing or adding options, or when disabling/enabling a \nselect via JavaScript.\n\n```js\n$('.selectpicker').selectpicker('refresh');\n```\n\n<div class=\"bs-docs-example\">\n  <div class=\"form-group\">\n    <select class=\"selectpicker remove-example\">\n      <option value=\"Mustard\">Mustard</option>\n      <option value=\"Ketchup\">Ketchup</option>\n      <option value=\"Relish\">Relish</option>\n    </select>\n  </div>\n\n  <button class=\"btn btn-warning rm-mustard\">Remove Mustard</button>\n  <button class=\"btn btn-danger rm-ketchup\">Remove Ketchup</button>\n  <button class=\"btn btn-success rm-relish\">Remove Relish</button>\n</div>\n\n```html\n<select class=\"selectpicker remove-example\">\n  <option value=\"Mustard\">Mustard</option>\n  <option value=\"Ketchup\">Ketchup</option>\n  <option value=\"Relish\">Relish</option>\n</select>\n\n<button class=\"btn btn-warning rm-mustard\">Remove Mustard</button>\n<button class=\"btn btn-danger rm-ketchup\">Remove Ketchup</button>\n<button class=\"btn btn-success rm-relish\">Remove Relish</button>\n```\n```js\n$('.rm-mustard').click(function () {\n  $('.remove-example').find('[value=Mustard]').remove();\n  $('.remove-example').selectpicker('refresh');\n});\n```\n\n<div class=\"bs-docs-example\">\n  <div class=\"form-group\">\n    <select class=\"selectpicker disable-example\">\n      <option value=\"Mustard\">Mustard</option>\n      <option value=\"Ketchup\">Ketchup</option>\n      <option value=\"Relish\">Relish</option>\n    </select>\n  </div>\n\n  <button class=\"btn btn-default ex-disable\"><i class=\"icon-remove\"></i> Disable</button>\n  <button class=\"btn btn-default ex-enable\"><i class=\"icon-ok\"></i> Enable</button>\n</div>\n\n```js\n$('.ex-disable').click(function () {\n  $('.disable-example').prop('disabled', true);\n  $('.disable-example').selectpicker('refresh');\n});\n\n$('.ex-enable').click(function () {\n  $('.disable-example').prop('disabled', false);\n  $('.disable-example').selectpicker('refresh');\n});\n```\n\n<script type=\"text/javascript\">\n  window.onload = function () {\n    var $re = $('.remove-example'),\n        $de = $('.disable-example');\n\n    $('.rm-mustard').click(function () {\n      $re.find('[value=Mustard]').remove();\n      $re.selectpicker('refresh');\n    });\n    $('.rm-ketchup').click(function () {\n      $re.find('[value=Ketchup]').remove();\n      $re.selectpicker('refresh');\n    });\n    $('.rm-relish').click(function () {\n      $re.find('[value=Relish]').remove();\n      $re.selectpicker('refresh');\n    });\n    $('.ex-disable').click(function () {\n      $de.prop('disabled', true);\n      $de.selectpicker('refresh');\n    });\n    $('.ex-enable').click(function () {\n      $de.prop('disabled', false);\n      $de.selectpicker('refresh');\n    });\n  };\n</script>\n\n---\n\n#### `.selectpicker('toggle')`\n\nProgrammatically toggles the bootstrap-select menu open/closed.\n\n```js\n$('.selectpicker').selectpicker('toggle');\n```\n\n---\n\n#### `.selectpicker('hide')`\n\nTo programmatically hide the bootstrap-select use the `hide` method (this only affects the visibility of the bootstrap-select itself).\n\n```js\n$('.selectpicker').selectpicker('hide');\n```\n\n---\n\n#### `.selectpicker('show')`\n\nTo programmatically show the bootstrap-select use the `show` method (this only affects the visibility of the bootstrap-select itself).\n\n```js\n$('.selectpicker').selectpicker('show');\n```\n\n---\n\n#### `.selectpicker('destroy')`\n\nTo programmatically destroy the bootstrap-select, use the `destroy` method.\n\n```js\n$('.selectpicker').selectpicker('destroy');\n```\n"
  },
  {
    "path": "app_frontend/static/plugin/bootstrap-select-1.12.2/docs/docs/options.md",
    "content": "# Core options\n\n---\n\nOptions can be passed via data attributes or JavaScript. For data attributes, append the option name to `data-`, as in \n`data-style=\"\"` or `data-selected-text-format=\"count\"`.\n\n<table class=\"table table-bordered table-striped\">\n  <thead>\n  <tr>\n    <th style=\"width: 15%;\">Name</th>\n    <th style=\"width: 32%;\">Type</th>\n    <th style=\"width: 10%;\">Default</th>\n    <th style=\"width: 43%;\">Description</th>\n  </tr>\n  </thead>\n  <tbody>\n  <tr>\n    <td>actionsBox</td>\n    <td>boolean</td>\n    <td><code>false</code></td>\n    <td>\n      <p>When set to <code>true</code>, adds two buttons to the top of the dropdown menu (<strong>Select All</strong> &amp; <strong>Deselect All</strong>).</p>\n    </td>\n  </tr>\n  <tr>\n    <td>container</td>\n    <td>string | false</td>\n    <td><code>false</code></td>\n    <td>\n        <p>When set to a string, appends the select to a specific element or selector, e.g., \n        <code>container: 'body' | '.main-body'</code></p>\n    </td>\n  </tr>\n  <tr>\n    <td>countSelectedText</td>\n    <td>string | function</td>\n    <td><code>function</code></td>\n    <td>\n      <p>Sets the format for the text displayed when selectedTextFormat is <code>count</code> or <code>count > \n      #</code>. {0} is the selected amount. {1} is total available for selection.</p>\n      <p>When set to a function, the first parameter is the number of selected options, and the second is the total number of \n      options. The function must return a string.</p>\n    </td>\n  </tr>\n  <tr>\n    <td>deselectAllText</td>\n    <td>string</td>\n    <td><code>'Deselect All'</code></td>\n    <td>\n      <p>The text on the button that deselects all options when <code>actionsBox</code> is enabled.</p>\n    </td>\n  </tr>\n  <tr>\n    <td>dropdownAlignRight</td>\n    <td>boolean | <code>'auto'</code></td>\n    <td><code>false</code></td>\n    <td>\n      <p>Align the menu to the right instead of the left. If set to <code>'auto'</code>, the menu will automatically align right if there isn't room for the menu's full width when aligned to the left.</p>\n    </td>\n  </tr>\n  <tr>\n    <td>dropupAuto</td>\n    <td>boolean</td>\n    <td><code>true</code></td>\n    <td>\n      <p>checks to see which has more room, above or below. If the dropup has enough room to fully open normally, but\n      there is more room above, the dropup still opens normally. Otherwise, it becomes a dropup. If dropupAuto is\n      set to false, dropups must be called manually.</p>\n    </td>\n  </tr>\n  <tr>\n    <td>header</td>\n    <td>string</td>\n    <td><code>false</code></td>\n    <td>\n      <p>adds a header to the top of the menu; includes a close button by default</p>\n    </td>\n  </tr>\n  <tr>\n    <td>hideDisabled</td>\n    <td>boolean</td>\n    <td><code>false</code></td>\n    <td>\n      <p>removes disabled options and optgroups from the menu <code>data-hide-disabled: true</code></p>\n    </td>\n  </tr>\n  <tr>\n    <td>iconBase</td>\n    <td>string</td>\n    <td><code>'glyphicon'</code></td>\n    <td>\n      <p>Set the base to use a different icon font instead of Glyphicons. If changing iconBase, you might also want to change <code>tickIcon</code>, in case the new icon font uses a different naming scheme.</p>\n    </td>\n  </tr>\n  <tr>\n    <td>liveSearch</td>\n    <td>boolean</td>\n    <td><code>false</code></td>\n    <td>\n      <p>When set to <code>true</code>, adds a search box to the top of the selectpicker dropdown.</p>\n    </td>\n  </tr>\n  <tr>\n    <td>liveSearchNormalize</td>\n    <td>boolean</td>\n    <td><code>false</code></td>\n    <td>\n      <p>Setting liveSearchNormalize to <code>true</code> allows for accent-insensitive searching.</p>\n    </td>\n  </tr>\n  <tr>\n    <td>liveSearchPlaceholder</td>\n    <td>string</td>\n    <td><code>null</code></td>\n    <td>\n      <p>When set to a string, a placeholder attribute equal to the string will be added to the liveSearch input.</p>\n    </td>\n  </tr>\n  <tr>\n    <td>liveSearchStyle</td>\n    <td>string</td>\n    <td><code>'contains'</code></td>\n    <td>\n      <p>When set to <code>'contains'</code>, searching will reveal options that contain the searched text. For example, searching for pl with return both Ap<b>pl</b>e, <b>Pl</b>um, and <b>Pl</b>antain. When set to <code>'startsWith'</code>, searching for pl will return only <b>Pl</b>um and <b>Pl</b>antain.</p>\n    </td>\n  </tr>\n  <tr>\n    <td>maxOptions</td>\n    <td>integer | false</td>\n    <td><code>false</code></td>\n    <td>\n      <p>When set to an integer and in a multi-select, the number of selected options cannot exceed the given value.</p>\n      <p>This option can also exist as a data-attribute for an <code>&lt;optgroup&gt;</code>, in which case it only \n      applies to that <code>&lt;optgroup&gt;</code>.</p>\n    </td>\n  </tr>\n  <tr>\n    <td>maxOptionsText</td>\n    <td>string | array | function</td>\n    <td><code>function</code></td>\n    <td>\n      <p>The text that is displayed when maxOptions is enabled and the maximum number of options for the given scenario have been selected.</p>\n      <p>If a function is used, it must return an array. array[0] is the text used when maxOptions is applied to the entire select element. array[1] is the text used when maxOptions is used on an optgroup. If a string is used, the same text is used for both the element and the optgroup.</p>\n    </td>\n  </tr>\n  <tr>\n    <td>mobile</td>\n    <td>boolean</td>\n    <td><code>false</code></td>\n    <td>\n      <p>When set to <code>true</code>, enables the device's native menu for select menus.</p>\n    </td>\n  </tr>\n  <tr>\n    <td>multipleSeparator</td>\n    <td>string</td>\n    <td><code>', '</code></td>\n    <td>\n      <p>Set the character displayed in the button that separates selected options.</p>\n    </td>\n  </tr>\n  <tr>\n    <td>noneSelectedText</td>\n    <td>string</td>\n    <td><code>'Nothing selected'</code></td>\n    <td>\n      <p>The text that is displayed when a multiple select has no selected options.</p>\n    </td>\n  </tr>\n  <tr>\n    <td>selectAllText</td>\n    <td>string</td>\n    <td><code>'Select All'</code></td>\n    <td>\n      <p>The text on the button that selects all options when <code>actionsBox</code> is enabled.</p>\n    </td>\n  </tr>\n  <tr>\n    <td>selectedTextFormat</td>\n    <td><code>'values'</code> | <code>'static'</code> | <code>'count'</code> | <code>'count > x'</code> (where x is an integer)</td>\n    <td><code>'values'</code></td>\n    <td>\n      <p>Specifies how the selection is displayed with a multiple select.</p>\n      <p><code>'values'</code> displays a list of the selected options (separated by <code>multipleSeparator</code>. <code>'static'</code> simply displays the select element's title. <code>'count'</code> displays the total number of selected options. <code>'count > x'</code> behaves like <code>'values'</code> until the number of selected options is greater than x; after that, it behaves like <code>'count'</code>.\n    </td>\n  </tr>\n  <tr>\n    <td>selectOnTab</td>\n    <td>boolean</td>\n    <td><code>false</code></td>\n    <td>\n      <p>When set to <code>true</code>, treats the tab character like the enter or space characters within the \n      selectpicker dropdown.</p>\n    </td>\n  </tr>\n  <tr>\n    <td>showContent</td>\n    <td>boolean</td>\n    <td><code>true</code></td>\n    <td>\n      <p>When set to <code>true</code>, display custom HTML associated with selected option(s) in the button. When set \n       to <code>false</code>, the option value will be displayed instead.</p>\n    </td>\n  </tr>\n  <tr>\n    <td>showIcon</td>\n    <td>boolean</td>\n    <td><code>true</code></td>\n    <td>\n      <p>When set to <code>true</code>, display icon(s) associated with selected option(s) in the button.</p>\n    </td>\n  </tr>\n  <tr>\n    <td>showSubtext</td>\n    <td>boolean</td>\n    <td><code>false</code></td>\n    <td>\n      <p>When set to <code>true</code>, display subtext associated with a selected option in the button.</p>\n    </td>\n  </tr>\n  <tr>\n    <td>showTick</td>\n    <td>boolean</td>\n    <td><code>false</code></td>\n    <td>\n      <p>Show checkmark on selected option (for items without <code>multiple</code> attribute).</p>\n    </td>\n  </tr>\n  <tr>\n    <td>size</td>\n    <td><code>'auto'</code> | integer | false</td>\n    <td><code>'auto'</code></td>\n    <td>\n      <p>When set to <code>'auto'</code>, the menu always opens up to show as many items as the window will allow\n      without being cut off.</p>\n      <p>When set to an integer, the menu will show the given number of items, even if the dropdown is cut off.</p>\n      <p>When set to <code>false</code>, the menu will always show all items.</p>\n    </td>\n  </tr>\n  <tr>\n    <td>style</td>\n    <td>string | null</td>\n    <td><code>null</code></td>\n    <td>\n      <p>When set to a string, add the value to the button's style.</p>\n    </td>\n  </tr>\n  <tr>\n    <td>tickIcon</td>\n    <td>string</td>\n    <td><code>'glyphicon-ok'</code></td>\n    <td>\n      <p>Set which icon to use to display as the \"tick\" next to selected options.</p>\n    </td>\n  </tr>\n  <tr>\n    <td>title</td>\n    <td>string | null</td>\n    <td><code>null</code></td>\n    <td>\n      <p>The default title for the selectpicker.</p>\n    </td>\n  </tr>\n  <tr>\n    <td>width</td>\n    <td><code>'auto'</code> | <code>'fit'</code> | css-width | false (where <code>css-width</code> is a CSS width with units, e.g. <code>100px</code>)</td>\n    <td><code>false</code></td>\n    <td>\n      <p>When set to <code>auto</code>, the width of the selectpicker is automatically adjusted to accommodate the \n      widest option.</p>\n      <p>When set to a css-width, the width of the selectpicker is forced inline to the given value.</p>\n      <p>When set to <code>false</code>, all width information is removed.</p>\n    </td>\n  </tr>\n  <tr>\n    <td>windowPadding</td>\n    <td>integer | array</td>\n    <td><code>0</code></td>\n    <td>\n      <p>This is useful in cases where the window has areas that the dropdown menu should not cover - for instance a fixed header. When set to an integer, the same padding will be added to all sides. Alternatively, an array of integers can be used in the format <code>[top, right, bottom, left]</code>.</p>\n    </td>\n  </tr>\n  </tbody>\n</table>\n\n# Events\n\n---\n\nBootstrap-select exposes a few events for hooking into select functionality.\n\nhide.bs.select, hidden.bs.select, show.bs.select, and shown.bs.select all have a `relatedTarget` property, whose value is the toggling anchor element.\n\n<table class=\"table table-bordered table-striped\">\n  <thead>\n    <tr>\n      <th>Event Type</th>\n      <th>Description</th>\n    </tr>\n  </thead>\n  <tbody>\n    <tr>\n      <td>show.bs.select</td>\n      <td>This event fires immediately when the show instance method is called.</td>\n    </tr>\n    <tr>\n      <td>shown.bs.select</td>\n      <td>This event is fired when the dropdown has been made visible to the user (will wait for CSS transitions, to complete).</td>\n    </tr>\n    <tr>\n      <td>hide.bs.select</td>\n      <td>This event is fired immediately when the hide instance method has been called.</td>\n    </tr>\n    <tr>\n      <td>hidden.bs.select</td>\n      <td>This event is fired when the dropdown has finished being hidden from the user (will wait for CSS transitions, to complete).</td>\n    </tr>\n    <tr>\n      <td>loaded.bs.select</td>\n      <td>This event fires after the select has been initialized.</td>\n    </tr>\n    <tr>\n      <td>rendered.bs.select</td>\n      <td>This event fires after the render instance has been called.</td>\n    </tr>\n    <tr>\n      <td>refreshed.bs.select</td>\n      <td>This event fires after the refresh instance has been called.</td>\n    </tr>\n    <tr>\n      <td>changed.bs.select</td>\n      <td>This event fires after the select's value has been changed. It passes through event, clickedIndex, newValue, oldValue.</td>\n    </tr>\n  </tbody>\n</table>\n\n```js\n$('#mySelect').on('hidden.bs.select', function (e) {\n  // do something...\n});\n```\n"
  },
  {
    "path": "app_frontend/static/plugin/bootstrap-select-1.12.2/docs/docs/playground/index.html",
    "content": "<!DOCTYPE html>\n<html>\n\n  <head>\n    <script data-require=\"jquery@2.2.0\" data-semver=\"2.2.0\" src=\"https://ajax.googleapis.com/ajax/libs/jquery/2.2.0/jquery.min.js\"></script>\n    <script src=\"plnkrOpener.js\"></script>\n  </head>\n\n  <body>\n  </body>\n\n</html>"
  },
  {
    "path": "app_frontend/static/plugin/bootstrap-select-1.12.2/docs/docs/playground/plnkrOpener.js",
    "content": "$(document).ready(function() {\n  function formPostData(url, fields) {\n    var form = $('<form style=\"display: none;\" method=\"post\" action=\"' + url + '\"></form>');\n    $.each(fields, function(name, value) {\n      var input = $('<input type=\"hidden\" name=\"' + name + '\">');\n      input.attr('value', value);\n      form.append(input);\n    });\n\n    $(document).find('body').append(form);\n\n    form[0].submit(function(e) {\n      e.preventDefault();\n    });\n\n    form.remove();\n  }\n  \n  function plnkrOpener() {\n    var ctrl = {};\n  \n    ctrl.example = {\n      path: ctrl.examplePath,\n      manifest: undefined,\n      files: undefined,\n      name: 'bootstrap-select example'\n    };\n  \n    ctrl.open = function() {\n      var postData = {\n        'tags[0]': 'jquery',\n        'tags[1]': 'bootstrap-select',\n        'private': true\n      };\n  \n      ctrl.example.files = [\n        {\n          name: 'index.html',\n          url: 'test.html',\n          content: ''\n        },\n        {\n          name: 'bootstrap-select.js',\n          url: 'https://raw.githubusercontent.com/silviomoreto/bootstrap-select/master/dist/js/bootstrap-select.js',\n          content: ''\n        },\n        {\n          name: 'bootstrap-select.css',\n          url: 'https://raw.githubusercontent.com/silviomoreto/bootstrap-select/master/dist/css/bootstrap-select.css',\n          content: ''\n        }\n      ]\n\n      function getData(file) {\n        return $.ajax({\n          method: 'GET',\n          url: file.url\n        })\n        .then(function(data) {\n          file.content = data;\n          postData['files[' + file.name + ']'] = file.content;\n        });\n      }\n\n      var files = [];\n\n      $.each(ctrl.example.files, function(i, file) {\n        files.push(getData(file));\n      });\n\n      function sendData() {\n        postData.description = ctrl.example.name;\n\n        formPostData('https://plnkr.co/edit/?p=preview', postData);\n      };\n\n      $.when.apply(this, files).done(function() {\n        sendData();\n      });\n    };\n    \n    return ctrl.open()\n  }\n\n  plnkrOpener();\n});"
  },
  {
    "path": "app_frontend/static/plugin/bootstrap-select-1.12.2/docs/docs/playground/test.html",
    "content": "<!DOCTYPE html>\n<html>\n<head>\n  <title>Bootstrap-select test page</title>\n\n  <meta charset=\"utf-8\">\n\n  <link rel=\"stylesheet\" href=\"https://maxcdn.bootstrapcdn.com/bootstrap/3.3.4/css/bootstrap.min.css\">\n  <link rel=\"stylesheet\" href=\"bootstrap-select.css\">\n\n  <script src=\"https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js\"></script>\n  <script src=\"https://maxcdn.bootstrapcdn.com/bootstrap/3.3.4/js/bootstrap.min.js\"></script>\n  <script src=\"bootstrap-select.js\"></script>\n</head>\n<body>\n\n<div class=\"container\">\n  <form class=\"form-horizontal\" role=\"form\">\n    <div class=\"form-group\">\n      <label for=\"basic\" class=\"col-lg-2 control-label\">\"Basic\" (liveSearch disabled)</label>\n\n      <div class=\"col-lg-10\">\n        <select id=\"basic\" class=\"selectpicker show-tick form-control\">\n          <option>cow</option>\n          <option data-subtext=\"option subtext\">bull</option>\n          <option class=\"get-class\" disabled>ox</option>\n          <optgroup label=\"test\" data-subtext=\"optgroup subtext\">\n            <option>ASD</option>\n            <option selected>Bla</option>\n            <option>Ble</option>\n          </optgroup>\n        </select>\n      </div>\n    </div>\n  </form>\n\n  <hr>\n\n  <form class=\"form-horizontal\" role=\"form\">\n    <div class=\"form-group\">\n      <label for=\"basic\" class=\"col-lg-2 control-label\">\"Basic\" (liveSearch enabled)</label>\n\n      <div class=\"col-lg-10\">\n        <select id=\"basic\" class=\"selectpicker show-tick form-control\" data-live-search=\"true\">\n          <option>cow</option>\n          <option data-subtext=\"option subtext\">bull</option>\n          <option class=\"get-class\" disabled>ox</option>\n          <optgroup label=\"test\" data-subtext=\"optgroup subtext\">\n            <option>ASD</option>\n            <option selected>Bla</option>\n            <option>Ble</option>\n          </optgroup>\n        </select>\n      </div>\n    </div>\n  </form>\n\n  <hr>\n  <form class=\"form-horizontal\" role=\"form\">\n    <div class=\"form-group\">\n      <label for=\"basic2\" class=\"col-lg-2 control-label\">\"Basic\" (multiple, maxOptions=1)</label>\n\n      <div class=\"col-lg-10\">\n        <select id=\"basic2\" class=\"show-tick form-control\" multiple>\n          <option>cow</option>\n          <option>bull</option>\n          <option class=\"get-class\" disabled>ox</option>\n          <optgroup label=\"test\" data-subtext=\"another test\">\n            <option>ASD</option>\n            <option selected>Bla</option>\n            <option>Ble</option>\n          </optgroup>\n        </select>\n      </div>\n    </div>\n  </form>\n\n  <hr>\n  <form class=\"form-horizontal\" role=\"form\">\n    <div class=\"form-group\">\n      <label for=\"maxOption2\" class=\"col-lg-2 control-label\">multiple, show-menu-arrow, maxOptions=2</label>\n\n      <div class=\"col-lg-10\">\n        <select id=\"maxOption2\" class=\"selectpicker show-menu-arrow form-control\" multiple data-max-options=\"2\">\n          <option>chicken</option>\n          <option>turkey</option>\n          <option disabled>duck</option>\n          <option>goose</option>\n        </select>\n      </div>\n    </div>\n  </form>\n\n  <hr>\n  <form class=\"form-inline\">\n    <div class=\"form-group\">\n      <label class=\"col-md-1 control-label\" for=\"lunch\">Lunch:</label>\n    </div>\n    <div class=\"form-group\">\n      <select id=\"lunch\" class=\"selectpicker\" data-live-search=\"true\" title=\"Please select a lunch ...\">\n        <option>Hot Dog, Fries and a Soda</option>\n        <option>Burger, Shake and a Smile</option>\n        <option>Sugar, Spice and all things nice</option>\n        <option>Baby Back Ribs</option>\n        <option>A really really long option made to illustrate an issue with the live search in an inline form</option>\n      </select>\n    </div>\n  </form>\n\n  <hr>\n  <form class=\"form-horizontal\" role=\"form\">\n    <div class=\"form-group form-group-lg\">\n      <label for=\"error\" class=\"col-lg-2 control-label\">error</label>\n\n      <div class=\"col-lg-10 error\">\n        <select id=\"error\" class=\"selectpicker show-tick form-control\">\n          <option>pen</option>\n          <option>pencil</option>\n          <option selected>brush</option>\n        </select>\n      </div>\n    </div>\n  </form>\n\n  <hr>\n  <form class=\"form-horizontal\" role=\"form\">\n    <div class=\"form-group has-error form-group-lg\">\n      <label class=\"control-label col-lg-2\" for=\"country\">error type 2</label>\n\n      <div class=\"col-lg-10\">\n        <select id=\"country\" name=\"country\" class=\"form-control selectpicker\">\n          <option>Argentina</option>\n          <option>United State</option>\n          <option>Mexico</option>\n        </select>\n\n        <p class=\"help-block\">No service available in the selected country</p>\n      </div>\n    </div>\n  </form>\n\n  <hr>\n  <nav class=\"navbar navbar-default\" role=\"navigation\">\n    <div class=\"container-fluid\">\n      <div class=\"navbar-header\">\n        <a class=\"navbar-brand\" href=\"#\">Navbar</a>\n      </div>\n\n      <form class=\"navbar-form navbar-left\" role=\"search\">\n        <div class=\"form-group\">\n          <select class=\"selectpicker\" multiple data-live-search=\"true\" data-live-search-placeholder=\"Search\" data-actions-box=\"true\">\n            <optgroup label=\"filter1\">\n              <option>option1</option>\n              <option>option2</option>\n              <option>option3</option>\n              <option>option4</option>\n            </optgroup>\n            <optgroup label=\"filter2\">\n              <option>option1</option>\n              <option>option2</option>\n              <option>option3</option>\n              <option>option4</option>\n            </optgroup>\n            <optgroup label=\"filter3\">\n              <option>option1</option>\n              <option>option2</option>\n              <option>option3</option>\n              <option>option4</option>\n            </optgroup>\n          </select>\n        </div>\n\n        <div class=\"input-group\">\n          <input type=\"text\" class=\"form-control\" placeholder=\"Search\" name=\"q\">\n\n          <div class=\"input-group-btn\">\n            <button class=\"btn btn-default\" type=\"submit\"><i class=\"glyphicon glyphicon-search\"></i></button>\n          </div>\n        </div>\n        <button type=\"submit\" class=\"btn btn-default\">Search</button>\n      </form>\n\n    </div>\n    <!-- .container-fluid -->\n  </nav>\n\n  <hr>\n  <select id=\"first-disabled\" class=\"selectpicker\" data-hide-disabled=\"true\" data-live-search=\"true\">\n    <optgroup disabled=\"disabled\" label=\"disabled\">\n      <option>Hidden</option>\n    </optgroup>\n    <optgroup label=\"Fruit\">\n      <option>Apple</option>\n      <option>Orange</option>\n    </optgroup>\n    <optgroup label=\"Vegetable\">\n      <option>Corn</option>\n      <option>Carrot</option>\n    </optgroup>\n  </select>\n\n  <hr>\n  <select id=\"first-disabled2\" class=\"selectpicker\" multiple data-hide-disabled=\"true\" data-size=\"5\">\n    <option>Apple</option>\n    <option>Banana</option>\n    <option>Orange</option>\n    <option>Pineapple</option>\n    <option>Apple2</option>\n    <option>Banana2</option>\n    <option>Orange2</option>\n    <option>Pineapple2</option>\n    <option>Apple2</option>\n    <option>Banana2</option>\n    <option>Orange2</option>\n    <option>Pineapple2</option>\n  </select>\n  <button id=\"special\" class=\"btn btn-default\">Hide selected by disabling</button>\n  <button id=\"special2\" class=\"btn btn-default\">Reset</button>\n  <p>Just select 1st element, click button and check list again</p>\n\n  <hr>\n  <div class=\"input-group\">\n    <span class=\"input-group-addon\">@</span>\n    <select class=\"form-control selectpicker\">\n      <option>One</option>\n      <option>Two</option>\n      <option>Three</option>\n    </select>\n  </div>\n\n  <hr>\n  <div class=\"input-group\">\n    <span class=\"input-group-addon\">@</span>\n    <select class=\"form-control selectpicker\" data-mobile=\"true\">\n      <option>One</option>\n      <option>Two</option>\n      <option>Three</option>\n    </select>\n  </div>\n  <p>With <code>data-mobile=\"true\"</code> option.</p>\n\n  <hr>\n  <select id=\"done\" class=\"selectpicker\" multiple data-done-button=\"true\">\n    <option>Apple</option>\n    <option>Banana</option>\n    <option>Orange</option>\n    <option>Pineapple</option>\n    <option>Apple2</option>\n    <option>Banana2</option>\n    <option>Orange2</option>\n    <option>Pineapple2</option>\n    <option>Apple2</option>\n    <option>Banana2</option>\n    <option>Orange2</option>\n    <option>Pineapple2</option>\n  </select>\n\n  <hr>\n  <select id=\"tokens\" class=\"selectpicker\" multiple data-live-search=\"true\">\n    <option data-tokens=\"first\">I actually am called \"first\"</option>\n    <option data-tokens=\"second\">And me \"second\"</option>\n    <option data-tokens=\"last\">I am \"last\"</option>\n  </select>\n\n  <hr>\n  <form class=\"form-inline\">\n    <div class=\"form-group\">\n      <label class=\"col-md-1 control-label\" for=\"lunchBegins\">Lunch (Begins search):</label>\n    </div>\n    <div class=\"form-group\">\n      <select id=\"lunchBegins\" class=\"selectpicker\" data-live-search=\"true\" data-live-search-style=\"begins\" title=\"Please select a lunch ...\">\n        <option>Hot Dog, Fries and a Soda</option>\n        <option>Burger, Shake and a Smile</option>\n        <option>Sugar, Spice and all things nice</option>\n        <option>Baby Back Ribs</option>\n        <option>A really really long option made to illustrate an issue with the live search in an inline form</option>\n      </select>\n    </div>\n  </form>\n</div>\n\n<script>\n  $(document).ready(function () {\n    var mySelect = $('#first-disabled2');\n\n    $('#special').on('click', function () {\n      mySelect.find('option:selected').prop('disabled', true);\n      mySelect.selectpicker('refresh');\n    });\n\n    $('#special2').on('click', function () {\n      mySelect.find('option:disabled').prop('disabled', false);\n      mySelect.selectpicker('refresh');\n    });\n\n    $('#basic2').selectpicker({\n      liveSearch: true,\n      maxOptions: 1\n    });\n  });\n</script>\n</body>\n</html>"
  },
  {
    "path": "app_frontend/static/plugin/bootstrap-select-1.12.2/docs/mkdocs.yml",
    "content": "site_name: bootstrap-select\nsite_description: Bootstrap-select is a jQuery plugin that utilizes Bootstrap's dropdown.js to style and bring additional functionality to standard select elements.\nrepo_url: https://github.com/silviomoreto/bootstrap-select\ntheme: bootstrap\ntheme_dir: custom_theme\nextra_css:\n- css/custom.css\n- dist/css/bootstrap-select.min.css\nextra_javascript:\n- dist/js/bootstrap-select.min.js\npages:\n- Bootstrap-select: index.md\n- Examples: examples.md\n- Options: options.md\n- Methods: methods.md\nextra:\n    version: 1.12.2\n"
  },
  {
    "path": "app_frontend/static/plugin/bootstrap-select-1.12.2/js/.jshintrc",
    "content": "{\n  \"curly\": true,\n  \"eqeqeq\": true,\n  \"immed\": true,\n  \"latedef\": true,\n  \"newcap\": true,\n  \"noarg\": true,\n  \"sub\": true,\n  \"undef\": true,\n  \"unused\": true,\n  \"boss\": true,\n  \"eqnull\": true,\n  \"browser\": true,\n  \"jquery\": true\n}\n"
  },
  {
    "path": "app_frontend/static/plugin/bootstrap-select-1.12.2/js/bootstrap-select.js",
    "content": "(function ($) {\n  'use strict';\n\n  //<editor-fold desc=\"Shims\">\n  if (!String.prototype.includes) {\n    (function () {\n      'use strict'; // needed to support `apply`/`call` with `undefined`/`null`\n      var toString = {}.toString;\n      var defineProperty = (function () {\n        // IE 8 only supports `Object.defineProperty` on DOM elements\n        try {\n          var object = {};\n          var $defineProperty = Object.defineProperty;\n          var result = $defineProperty(object, object, object) && $defineProperty;\n        } catch (error) {\n        }\n        return result;\n      }());\n      var indexOf = ''.indexOf;\n      var includes = function (search) {\n        if (this == null) {\n          throw new TypeError();\n        }\n        var string = String(this);\n        if (search && toString.call(search) == '[object RegExp]') {\n          throw new TypeError();\n        }\n        var stringLength = string.length;\n        var searchString = String(search);\n        var searchLength = searchString.length;\n        var position = arguments.length > 1 ? arguments[1] : undefined;\n        // `ToInteger`\n        var pos = position ? Number(position) : 0;\n        if (pos != pos) { // better `isNaN`\n          pos = 0;\n        }\n        var start = Math.min(Math.max(pos, 0), stringLength);\n        // Avoid the `indexOf` call if no match is possible\n        if (searchLength + start > stringLength) {\n          return false;\n        }\n        return indexOf.call(string, searchString, pos) != -1;\n      };\n      if (defineProperty) {\n        defineProperty(String.prototype, 'includes', {\n          'value': includes,\n          'configurable': true,\n          'writable': true\n        });\n      } else {\n        String.prototype.includes = includes;\n      }\n    }());\n  }\n\n  if (!String.prototype.startsWith) {\n    (function () {\n      'use strict'; // needed to support `apply`/`call` with `undefined`/`null`\n      var defineProperty = (function () {\n        // IE 8 only supports `Object.defineProperty` on DOM elements\n        try {\n          var object = {};\n          var $defineProperty = Object.defineProperty;\n          var result = $defineProperty(object, object, object) && $defineProperty;\n        } catch (error) {\n        }\n        return result;\n      }());\n      var toString = {}.toString;\n      var startsWith = function (search) {\n        if (this == null) {\n          throw new TypeError();\n        }\n        var string = String(this);\n        if (search && toString.call(search) == '[object RegExp]') {\n          throw new TypeError();\n        }\n        var stringLength = string.length;\n        var searchString = String(search);\n        var searchLength = searchString.length;\n        var position = arguments.length > 1 ? arguments[1] : undefined;\n        // `ToInteger`\n        var pos = position ? Number(position) : 0;\n        if (pos != pos) { // better `isNaN`\n          pos = 0;\n        }\n        var start = Math.min(Math.max(pos, 0), stringLength);\n        // Avoid the `indexOf` call if no match is possible\n        if (searchLength + start > stringLength) {\n          return false;\n        }\n        var index = -1;\n        while (++index < searchLength) {\n          if (string.charCodeAt(start + index) != searchString.charCodeAt(index)) {\n            return false;\n          }\n        }\n        return true;\n      };\n      if (defineProperty) {\n        defineProperty(String.prototype, 'startsWith', {\n          'value': startsWith,\n          'configurable': true,\n          'writable': true\n        });\n      } else {\n        String.prototype.startsWith = startsWith;\n      }\n    }());\n  }\n\n  if (!Object.keys) {\n    Object.keys = function (\n      o, // object\n      k, // key\n      r  // result array\n      ){\n      // initialize object and result\n      r=[];\n      // iterate over object keys\n      for (k in o)\n          // fill result array with non-prototypical keys\n        r.hasOwnProperty.call(o, k) && r.push(k);\n      // return result\n      return r;\n    };\n  }\n\n  // set data-selected on select element if the value has been programmatically selected\n  // prior to initialization of bootstrap-select\n  // * consider removing or replacing an alternative method *\n  var valHooks = {\n    useDefault: false,\n    _set: $.valHooks.select.set\n  };\n\n  $.valHooks.select.set = function(elem, value) {\n    if (value && !valHooks.useDefault) $(elem).data('selected', true);\n\n    return valHooks._set.apply(this, arguments);\n  };\n\n  var changed_arguments = null;\n  $.fn.triggerNative = function (eventName) {\n    var el = this[0],\n        event;\n\n    if (el.dispatchEvent) { // for modern browsers & IE9+\n      if (typeof Event === 'function') {\n        // For modern browsers\n        event = new Event(eventName, {\n          bubbles: true\n        });\n      } else {\n        // For IE since it doesn't support Event constructor\n        event = document.createEvent('Event');\n        event.initEvent(eventName, true, false);\n      }\n\n      el.dispatchEvent(event);\n    } else if (el.fireEvent) { // for IE8\n      event = document.createEventObject();\n      event.eventType = eventName;\n      el.fireEvent('on' + eventName, event);\n    } else {\n      // fall back to jQuery.trigger\n      this.trigger(eventName);\n    }\n  };\n  //</editor-fold>\n\n  // Case insensitive contains search\n  $.expr.pseudos.icontains = function (obj, index, meta) {\n    var $obj = $(obj);\n    var haystack = ($obj.data('tokens') || $obj.text()).toString().toUpperCase();\n    return haystack.includes(meta[3].toUpperCase());\n  };\n\n  // Case insensitive begins search\n  $.expr.pseudos.ibegins = function (obj, index, meta) {\n    var $obj = $(obj);\n    var haystack = ($obj.data('tokens') || $obj.text()).toString().toUpperCase();\n    return haystack.startsWith(meta[3].toUpperCase());\n  };\n\n  // Case and accent insensitive contains search\n  $.expr.pseudos.aicontains = function (obj, index, meta) {\n    var $obj = $(obj);\n    var haystack = ($obj.data('tokens') || $obj.data('normalizedText') || $obj.text()).toString().toUpperCase();\n    return haystack.includes(meta[3].toUpperCase());\n  };\n\n  // Case and accent insensitive begins search\n  $.expr.pseudos.aibegins = function (obj, index, meta) {\n    var $obj = $(obj);\n    var haystack = ($obj.data('tokens') || $obj.data('normalizedText') || $obj.text()).toString().toUpperCase();\n    return haystack.startsWith(meta[3].toUpperCase());\n  };\n\n  /**\n   * Remove all diatrics from the given text.\n   * @access private\n   * @param {String} text\n   * @returns {String}\n   */\n  function normalizeToBase(text) {\n    var rExps = [\n      {re: /[\\xC0-\\xC6]/g, ch: \"A\"},\n      {re: /[\\xE0-\\xE6]/g, ch: \"a\"},\n      {re: /[\\xC8-\\xCB]/g, ch: \"E\"},\n      {re: /[\\xE8-\\xEB]/g, ch: \"e\"},\n      {re: /[\\xCC-\\xCF]/g, ch: \"I\"},\n      {re: /[\\xEC-\\xEF]/g, ch: \"i\"},\n      {re: /[\\xD2-\\xD6]/g, ch: \"O\"},\n      {re: /[\\xF2-\\xF6]/g, ch: \"o\"},\n      {re: /[\\xD9-\\xDC]/g, ch: \"U\"},\n      {re: /[\\xF9-\\xFC]/g, ch: \"u\"},\n      {re: /[\\xC7-\\xE7]/g, ch: \"c\"},\n      {re: /[\\xD1]/g, ch: \"N\"},\n      {re: /[\\xF1]/g, ch: \"n\"}\n    ];\n    $.each(rExps, function () {\n      text = text ? text.replace(this.re, this.ch) : '';\n    });\n    return text;\n  }\n\n\n  // List of HTML entities for escaping.\n  var escapeMap = {\n    '&': '&amp;',\n    '<': '&lt;',\n    '>': '&gt;',\n    '\"': '&quot;',\n    \"'\": '&#x27;',\n    '`': '&#x60;'\n  };\n  \n  var unescapeMap = {\n    '&amp;': '&',\n    '&lt;': '<',\n    '&gt;': '>',\n    '&quot;': '\"',\n    '&#x27;': \"'\",\n    '&#x60;': '`'\n  };\n\n  // Functions for escaping and unescaping strings to/from HTML interpolation.\n  var createEscaper = function(map) {\n    var escaper = function(match) {\n      return map[match];\n    };\n    // Regexes for identifying a key that needs to be escaped.\n    var source = '(?:' + Object.keys(map).join('|') + ')';\n    var testRegexp = RegExp(source);\n    var replaceRegexp = RegExp(source, 'g');\n    return function(string) {\n      string = string == null ? '' : '' + string;\n      return testRegexp.test(string) ? string.replace(replaceRegexp, escaper) : string;\n    };\n  };\n\n  var htmlEscape = createEscaper(escapeMap);\n  var htmlUnescape = createEscaper(unescapeMap);\n\n  var Selectpicker = function (element, options) {\n    // bootstrap-select has been initialized - revert valHooks.select.set back to its original function\n    if (!valHooks.useDefault) {\n      $.valHooks.select.set = valHooks._set;\n      valHooks.useDefault = true;\n    }\n\n    this.$element = $(element);\n    this.$newElement = null;\n    this.$button = null;\n    this.$menu = null;\n    this.$lis = null;\n    this.options = options;\n\n    // If we have no title yet, try to pull it from the html title attribute (jQuery doesnt' pick it up as it's not a\n    // data-attribute)\n    if (this.options.title === null) {\n      this.options.title = this.$element.attr('title');\n    }\n\n    // Format window padding\n    var winPad = this.options.windowPadding;\n    if (typeof winPad === 'number') {\n      this.options.windowPadding = [winPad, winPad, winPad, winPad];\n    }\n\n    //Expose public methods\n    this.val = Selectpicker.prototype.val;\n    this.render = Selectpicker.prototype.render;\n    this.refresh = Selectpicker.prototype.refresh;\n    this.setStyle = Selectpicker.prototype.setStyle;\n    this.selectAll = Selectpicker.prototype.selectAll;\n    this.deselectAll = Selectpicker.prototype.deselectAll;\n    this.destroy = Selectpicker.prototype.destroy;\n    this.remove = Selectpicker.prototype.remove;\n    this.show = Selectpicker.prototype.show;\n    this.hide = Selectpicker.prototype.hide;\n\n    this.init();\n  };\n\n  Selectpicker.VERSION = '1.12.2';\n\n  // part of this is duplicated in i18n/defaults-en_US.js. Make sure to update both.\n  Selectpicker.DEFAULTS = {\n    noneSelectedText: 'Nothing selected',\n    noneResultsText: 'No results matched {0}',\n    countSelectedText: function (numSelected, numTotal) {\n      return (numSelected == 1) ? \"{0} item selected\" : \"{0} items selected\";\n    },\n    maxOptionsText: function (numAll, numGroup) {\n      return [\n        (numAll == 1) ? 'Limit reached ({n} item max)' : 'Limit reached ({n} items max)',\n        (numGroup == 1) ? 'Group limit reached ({n} item max)' : 'Group limit reached ({n} items max)'\n      ];\n    },\n    selectAllText: 'Select All',\n    deselectAllText: 'Deselect All',\n    doneButton: false,\n    doneButtonText: 'Close',\n    multipleSeparator: ', ',\n    styleBase: 'btn',\n    style: 'btn-default',\n    size: 'auto',\n    title: null,\n    selectedTextFormat: 'values',\n    width: false,\n    container: false,\n    hideDisabled: false,\n    showSubtext: false,\n    showIcon: true,\n    showContent: true,\n    dropupAuto: true,\n    header: false,\n    liveSearch: false,\n    liveSearchPlaceholder: null,\n    liveSearchNormalize: false,\n    liveSearchStyle: 'contains',\n    actionsBox: false,\n    iconBase: 'glyphicon',\n    tickIcon: 'glyphicon-ok',\n    showTick: false,\n    template: {\n      caret: '<span class=\"caret\"></span>'\n    },\n    maxOptions: false,\n    mobile: false,\n    selectOnTab: false,\n    dropdownAlignRight: false,\n    windowPadding: 0\n  };\n\n  Selectpicker.prototype = {\n\n    constructor: Selectpicker,\n\n    init: function () {\n      var that = this,\n          id = this.$element.attr('id');\n\n      this.$element.addClass('bs-select-hidden');\n\n      // store originalIndex (key) and newIndex (value) in this.liObj for fast accessibility\n      // allows us to do this.$lis.eq(that.liObj[index]) instead of this.$lis.filter('[data-original-index=\"' + index + '\"]')\n      this.liObj = {};\n      this.multiple = this.$element.prop('multiple');\n      this.autofocus = this.$element.prop('autofocus');\n      this.$newElement = this.createView();\n      this.$element\n        .after(this.$newElement)\n        .appendTo(this.$newElement);\n      this.$button = this.$newElement.children('button');\n      this.$menu = this.$newElement.children('.dropdown-menu');\n      this.$menuInner = this.$menu.children('.inner');\n      this.$searchbox = this.$menu.find('input');\n\n      this.$element.removeClass('bs-select-hidden');\n\n      if (this.options.dropdownAlignRight === true) this.$menu.addClass('dropdown-menu-right');\n\n      if (typeof id !== 'undefined') {\n        this.$button.attr('data-id', id);\n        $('label[for=\"' + id + '\"]').click(function (e) {\n          e.preventDefault();\n          that.$button.focus();\n        });\n      }\n\n      this.checkDisabled();\n      this.clickListener();\n      if (this.options.liveSearch) this.liveSearchListener();\n      this.render();\n      this.setStyle();\n      this.setWidth();\n      if (this.options.container) this.selectPosition();\n      this.$menu.data('this', this);\n      this.$newElement.data('this', this);\n      if (this.options.mobile) this.mobile();\n\n      this.$newElement.on({\n        'hide.bs.dropdown': function (e) {\n          that.$menuInner.attr('aria-expanded', false);\n          that.$element.trigger('hide.bs.select', e);\n        },\n        'hidden.bs.dropdown': function (e) {\n          that.$element.trigger('hidden.bs.select', e);\n        },\n        'show.bs.dropdown': function (e) {\n          that.$menuInner.attr('aria-expanded', true);\n          that.$element.trigger('show.bs.select', e);\n        },\n        'shown.bs.dropdown': function (e) {\n          that.$element.trigger('shown.bs.select', e);\n        }\n      });\n\n      if (that.$element[0].hasAttribute('required')) {\n        this.$element.on('invalid', function () {\n          that.$button\n            .addClass('bs-invalid')\n            .focus();\n\n          that.$element.on({\n            'focus.bs.select': function () {\n              that.$button.focus();\n              that.$element.off('focus.bs.select');\n            },\n            'shown.bs.select': function () {\n              that.$element\n                .val(that.$element.val()) // set the value to hide the validation message in Chrome when menu is opened\n                .off('shown.bs.select');\n            },\n            'rendered.bs.select': function () {\n              // if select is no longer invalid, remove the bs-invalid class\n              if (this.validity.valid) that.$button.removeClass('bs-invalid');\n              that.$element.off('rendered.bs.select');\n            }\n          });\n        });\n      }\n\n      setTimeout(function () {\n        that.$element.trigger('loaded.bs.select');\n      });\n    },\n\n    createDropdown: function () {\n      // Options\n      // If we are multiple or showTick option is set, then add the show-tick class\n      var showTick = (this.multiple || this.options.showTick) ? ' show-tick' : '',\n          inputGroup = this.$element.parent().hasClass('input-group') ? ' input-group-btn' : '',\n          autofocus = this.autofocus ? ' autofocus' : '';\n      // Elements\n      var header = this.options.header ? '<div class=\"popover-title\"><button type=\"button\" class=\"close\" aria-hidden=\"true\">&times;</button>' + this.options.header + '</div>' : '';\n      var searchbox = this.options.liveSearch ?\n      '<div class=\"bs-searchbox\">' +\n      '<input type=\"text\" class=\"form-control\" autocomplete=\"off\"' +\n      (null === this.options.liveSearchPlaceholder ? '' : ' placeholder=\"' + htmlEscape(this.options.liveSearchPlaceholder) + '\"') + ' role=\"textbox\" aria-label=\"Search\">' +\n      '</div>'\n          : '';\n      var actionsbox = this.multiple && this.options.actionsBox ?\n      '<div class=\"bs-actionsbox\">' +\n      '<div class=\"btn-group btn-group-sm btn-block\">' +\n      '<button type=\"button\" class=\"actions-btn bs-select-all btn btn-default\">' +\n      this.options.selectAllText +\n      '</button>' +\n      '<button type=\"button\" class=\"actions-btn bs-deselect-all btn btn-default\">' +\n      this.options.deselectAllText +\n      '</button>' +\n      '</div>' +\n      '</div>'\n          : '';\n      var donebutton = this.multiple && this.options.doneButton ?\n      '<div class=\"bs-donebutton\">' +\n      '<div class=\"btn-group btn-block\">' +\n      '<button type=\"button\" class=\"btn btn-sm btn-default\">' +\n      this.options.doneButtonText +\n      '</button>' +\n      '</div>' +\n      '</div>'\n          : '';\n      var drop =\n          '<div class=\"btn-group bootstrap-select' + showTick + inputGroup + '\">' +\n          '<button type=\"button\" class=\"' + this.options.styleBase + ' dropdown-toggle\" data-toggle=\"dropdown\"' + autofocus + ' role=\"button\">' +\n          '<span class=\"filter-option pull-left\"></span>&nbsp;' +\n          '<span class=\"bs-caret\">' +\n          this.options.template.caret +\n          '</span>' +\n          '</button>' +\n          '<div class=\"dropdown-menu open\" role=\"combobox\">' +\n          header +\n          searchbox +\n          actionsbox +\n          '<ul class=\"dropdown-menu inner\" role=\"listbox\" aria-expanded=\"false\">' +\n          '</ul>' +\n          donebutton +\n          '</div>' +\n          '</div>';\n\n      return $(drop);\n    },\n\n    createView: function () {\n      var $drop = this.createDropdown(),\n          li = this.createLi();\n\n      $drop.find('ul')[0].innerHTML = li;\n      return $drop;\n    },\n\n    reloadLi: function () {\n      // rebuild\n      var li = this.createLi();\n      this.$menuInner[0].innerHTML = li;\n    },\n\n    createLi: function () {\n      var that = this,\n          _li = [],\n          optID = 0,\n          titleOption = document.createElement('option'),\n          liIndex = -1; // increment liIndex whenever a new <li> element is created to ensure liObj is correct\n\n      // Helper functions\n      /**\n       * @param content\n       * @param [index]\n       * @param [classes]\n       * @param [optgroup]\n       * @returns {string}\n       */\n      var generateLI = function (content, index, classes, optgroup) {\n        return '<li' +\n            ((typeof classes !== 'undefined' & '' !== classes) ? ' class=\"' + classes + '\"' : '') +\n            ((typeof index !== 'undefined' & null !== index) ? ' data-original-index=\"' + index + '\"' : '') +\n            ((typeof optgroup !== 'undefined' & null !== optgroup) ? 'data-optgroup=\"' + optgroup + '\"' : '') +\n            '>' + content + '</li>';\n      };\n\n      /**\n       * @param text\n       * @param [classes]\n       * @param [inline]\n       * @param [tokens]\n       * @returns {string}\n       */\n      var generateA = function (text, classes, inline, tokens) {\n        return '<a tabindex=\"0\"' +\n            (typeof classes !== 'undefined' ? ' class=\"' + classes + '\"' : '') +\n            (inline ? ' style=\"' + inline + '\"' : '') +\n            (that.options.liveSearchNormalize ? ' data-normalized-text=\"' + normalizeToBase(htmlEscape($(text).html())) + '\"' : '') +\n            (typeof tokens !== 'undefined' || tokens !== null ? ' data-tokens=\"' + tokens + '\"' : '') +\n            ' role=\"option\">' + text +\n            '<span class=\"' + that.options.iconBase + ' ' + that.options.tickIcon + ' check-mark\"></span>' +\n            '</a>';\n      };\n\n      if (this.options.title && !this.multiple) {\n        // this option doesn't create a new <li> element, but does add a new option, so liIndex is decreased\n        // since liObj is recalculated on every refresh, liIndex needs to be decreased even if the titleOption is already appended\n        liIndex--;\n\n        if (!this.$element.find('.bs-title-option').length) {\n          // Use native JS to prepend option (faster)\n          var element = this.$element[0];\n          titleOption.className = 'bs-title-option';\n          titleOption.innerHTML = this.options.title;\n          titleOption.value = '';\n          element.insertBefore(titleOption, element.firstChild);\n          // Check if selected or data-selected attribute is already set on an option. If not, select the titleOption option.\n          // the selected item may have been changed by user or programmatically before the bootstrap select plugin runs,\n          // if so, the select will have the data-selected attribute\n          var $opt = $(element.options[element.selectedIndex]);\n          if ($opt.attr('selected') === undefined && this.$element.data('selected') === undefined) {\n            titleOption.selected = true;\n          }\n        }\n      }\n\n      this.$element.find('option').each(function (index) {\n        var $this = $(this);\n\n        liIndex++;\n\n        if ($this.hasClass('bs-title-option')) return;\n\n        // Get the class and text for the option\n        var optionClass = this.className || '',\n            inline = this.style.cssText,\n            text = $this.data('content') ? $this.data('content') : $this.html(),\n            tokens = $this.data('tokens') ? $this.data('tokens') : null,\n            subtext = typeof $this.data('subtext') !== 'undefined' ? '<small class=\"text-muted\">' + $this.data('subtext') + '</small>' : '',\n            icon = typeof $this.data('icon') !== 'undefined' ? '<span class=\"' + that.options.iconBase + ' ' + $this.data('icon') + '\"></span> ' : '',\n            $parent = $this.parent(),\n            isOptgroup = $parent[0].tagName === 'OPTGROUP',\n            isOptgroupDisabled = isOptgroup && $parent[0].disabled,\n            isDisabled = this.disabled || isOptgroupDisabled;\n\n        if (icon !== '' && isDisabled) {\n          icon = '<span>' + icon + '</span>';\n        }\n\n        if (that.options.hideDisabled && (isDisabled && !isOptgroup || isOptgroupDisabled)) {\n          liIndex--;\n          return;\n        }\n\n        if (!$this.data('content')) {\n          // Prepend any icon and append any subtext to the main text.\n          text = icon + '<span class=\"text\">' + text + subtext + '</span>';\n        }\n\n        if (isOptgroup && $this.data('divider') !== true) {\n          if (that.options.hideDisabled && isDisabled) {\n            if ($parent.data('allOptionsDisabled') === undefined) {\n              var $options = $parent.children();\n              $parent.data('allOptionsDisabled', $options.filter(':disabled').length === $options.length);\n            }\n\n            if ($parent.data('allOptionsDisabled')) {\n              liIndex--;\n              return;\n            }\n          }\n\n          var optGroupClass = ' ' + $parent[0].className || '';\n\n          if ($this.index() === 0) { // Is it the first option of the optgroup?\n            optID += 1;\n\n            // Get the opt group label\n            var label = $parent[0].label,\n                labelSubtext = typeof $parent.data('subtext') !== 'undefined' ? '<small class=\"text-muted\">' + $parent.data('subtext') + '</small>' : '',\n                labelIcon = $parent.data('icon') ? '<span class=\"' + that.options.iconBase + ' ' + $parent.data('icon') + '\"></span> ' : '';\n\n            label = labelIcon + '<span class=\"text\">' + htmlEscape(label) + labelSubtext + '</span>';\n\n            if (index !== 0 && _li.length > 0) { // Is it NOT the first option of the select && are there elements in the dropdown?\n              liIndex++;\n              _li.push(generateLI('', null, 'divider', optID + 'div'));\n            }\n            liIndex++;\n            _li.push(generateLI(label, null, 'dropdown-header' + optGroupClass, optID));\n          }\n\n          if (that.options.hideDisabled && isDisabled) {\n            liIndex--;\n            return;\n          }\n\n          _li.push(generateLI(generateA(text, 'opt ' + optionClass + optGroupClass, inline, tokens), index, '', optID));\n        } else if ($this.data('divider') === true) {\n          _li.push(generateLI('', index, 'divider'));\n        } else if ($this.data('hidden') === true) {\n          _li.push(generateLI(generateA(text, optionClass, inline, tokens), index, 'hidden is-hidden'));\n        } else {\n          var showDivider = this.previousElementSibling && this.previousElementSibling.tagName === 'OPTGROUP';\n\n          // if previous element is not an optgroup and hideDisabled is true\n          if (!showDivider && that.options.hideDisabled) {\n            // get previous elements\n            var $prev = $(this).prevAll();\n\n            for (var i = 0; i < $prev.length; i++) {\n              // find the first element in the previous elements that is an optgroup\n              if ($prev[i].tagName === 'OPTGROUP') {\n                var optGroupDistance = 0;\n\n                // loop through the options in between the current option and the optgroup\n                // and check if they are hidden or disabled\n                for (var d = 0; d < i; d++) {\n                  var prevOption = $prev[d];\n                  if (prevOption.disabled || $(prevOption).data('hidden') === true) optGroupDistance++;\n                }\n\n                // if all of the options between the current option and the optgroup are hidden or disabled, show the divider\n                if (optGroupDistance === i) showDivider = true;\n\n                break;\n              }\n            }\n          }\n\n          if (showDivider) {\n            liIndex++;\n            _li.push(generateLI('', null, 'divider', optID + 'div'));\n          }\n          _li.push(generateLI(generateA(text, optionClass, inline, tokens), index));\n        }\n\n        that.liObj[index] = liIndex;\n      });\n\n      //If we are not multiple, we don't have a selected item, and we don't have a title, select the first element so something is set in the button\n      if (!this.multiple && this.$element.find('option:selected').length === 0 && !this.options.title) {\n        this.$element.find('option').eq(0).prop('selected', true).attr('selected', 'selected');\n      }\n\n      return _li.join('');\n    },\n\n    findLis: function () {\n      if (this.$lis == null) this.$lis = this.$menu.find('li');\n      return this.$lis;\n    },\n\n    /**\n     * @param [updateLi] defaults to true\n     */\n    render: function (updateLi) {\n      var that = this,\n          notDisabled;\n\n      //Update the LI to match the SELECT\n      if (updateLi !== false) {\n        this.$element.find('option').each(function (index) {\n          var $lis = that.findLis().eq(that.liObj[index]);\n\n          that.setDisabled(index, this.disabled || this.parentNode.tagName === 'OPTGROUP' && this.parentNode.disabled, $lis);\n          that.setSelected(index, this.selected, $lis);\n        });\n      }\n\n      this.togglePlaceholder();\n\n      this.tabIndex();\n\n      var selectedItems = this.$element.find('option').map(function () {\n        if (this.selected) {\n          if (that.options.hideDisabled && (this.disabled || this.parentNode.tagName === 'OPTGROUP' && this.parentNode.disabled)) return;\n\n          var $this = $(this),\n              icon = $this.data('icon') && that.options.showIcon ? '<i class=\"' + that.options.iconBase + ' ' + $this.data('icon') + '\"></i> ' : '',\n              subtext;\n\n          if (that.options.showSubtext && $this.data('subtext') && !that.multiple) {\n            subtext = ' <small class=\"text-muted\">' + $this.data('subtext') + '</small>';\n          } else {\n            subtext = '';\n          }\n          if (typeof $this.attr('title') !== 'undefined') {\n            return $this.attr('title');\n          } else if ($this.data('content') && that.options.showContent) {\n            return $this.data('content').toString();\n          } else {\n            return icon + $this.html() + subtext;\n          }\n        }\n      }).toArray();\n\n      //Fixes issue in IE10 occurring when no default option is selected and at least one option is disabled\n      //Convert all the values into a comma delimited string\n      var title = !this.multiple ? selectedItems[0] : selectedItems.join(this.options.multipleSeparator);\n\n      //If this is multi select, and the selectText type is count, the show 1 of 2 selected etc..\n      if (this.multiple && this.options.selectedTextFormat.indexOf('count') > -1) {\n        var max = this.options.selectedTextFormat.split('>');\n        if ((max.length > 1 && selectedItems.length > max[1]) || (max.length == 1 && selectedItems.length >= 2)) {\n          notDisabled = this.options.hideDisabled ? ', [disabled]' : '';\n          var totalCount = this.$element.find('option').not('[data-divider=\"true\"], [data-hidden=\"true\"]' + notDisabled).length,\n              tr8nText = (typeof this.options.countSelectedText === 'function') ? this.options.countSelectedText(selectedItems.length, totalCount) : this.options.countSelectedText;\n          title = tr8nText.replace('{0}', selectedItems.length.toString()).replace('{1}', totalCount.toString());\n        }\n      }\n\n      if (this.options.title == undefined) {\n        this.options.title = this.$element.attr('title');\n      }\n\n      if (this.options.selectedTextFormat == 'static') {\n        title = this.options.title;\n      }\n\n      //If we dont have a title, then use the default, or if nothing is set at all, use the not selected text\n      if (!title) {\n        title = typeof this.options.title !== 'undefined' ? this.options.title : this.options.noneSelectedText;\n      }\n\n      //strip all HTML tags and trim the result, then unescape any escaped tags\n      this.$button.attr('title', htmlUnescape($.trim(title.replace(/<[^>]*>?/g, ''))));\n      this.$button.children('.filter-option').html(title);\n\n      this.$element.trigger('rendered.bs.select');\n    },\n\n    /**\n     * @param [style]\n     * @param [status]\n     */\n    setStyle: function (style, status) {\n      if (this.$element.attr('class')) {\n        this.$newElement.addClass(this.$element.attr('class').replace(/selectpicker|mobile-device|bs-select-hidden|validate\\[.*\\]/gi, ''));\n      }\n\n      var buttonClass = style ? style : this.options.style;\n\n      if (status == 'add') {\n        this.$button.addClass(buttonClass);\n      } else if (status == 'remove') {\n        this.$button.removeClass(buttonClass);\n      } else {\n        this.$button.removeClass(this.options.style);\n        this.$button.addClass(buttonClass);\n      }\n    },\n\n    liHeight: function (refresh) {\n      if (!refresh && (this.options.size === false || this.sizeInfo)) return;\n\n      var newElement = document.createElement('div'),\n          menu = document.createElement('div'),\n          menuInner = document.createElement('ul'),\n          divider = document.createElement('li'),\n          li = document.createElement('li'),\n          a = document.createElement('a'),\n          text = document.createElement('span'),\n          header = this.options.header && this.$menu.find('.popover-title').length > 0 ? this.$menu.find('.popover-title')[0].cloneNode(true) : null,\n          search = this.options.liveSearch ? document.createElement('div') : null,\n          actions = this.options.actionsBox && this.multiple && this.$menu.find('.bs-actionsbox').length > 0 ? this.$menu.find('.bs-actionsbox')[0].cloneNode(true) : null,\n          doneButton = this.options.doneButton && this.multiple && this.$menu.find('.bs-donebutton').length > 0 ? this.$menu.find('.bs-donebutton')[0].cloneNode(true) : null;\n\n      text.className = 'text';\n      newElement.className = this.$menu[0].parentNode.className + ' open';\n      menu.className = 'dropdown-menu open';\n      menuInner.className = 'dropdown-menu inner';\n      divider.className = 'divider';\n\n      text.appendChild(document.createTextNode('Inner text'));\n      a.appendChild(text);\n      li.appendChild(a);\n      menuInner.appendChild(li);\n      menuInner.appendChild(divider);\n      if (header) menu.appendChild(header);\n      if (search) {\n        var input = document.createElement('input');\n        search.className = 'bs-searchbox';\n        input.className = 'form-control';\n        search.appendChild(input);\n        menu.appendChild(search);\n      }\n      if (actions) menu.appendChild(actions);\n      menu.appendChild(menuInner);\n      if (doneButton) menu.appendChild(doneButton);\n      newElement.appendChild(menu);\n\n      document.body.appendChild(newElement);\n\n      var liHeight = a.offsetHeight,\n          headerHeight = header ? header.offsetHeight : 0,\n          searchHeight = search ? search.offsetHeight : 0,\n          actionsHeight = actions ? actions.offsetHeight : 0,\n          doneButtonHeight = doneButton ? doneButton.offsetHeight : 0,\n          dividerHeight = $(divider).outerHeight(true),\n          // fall back to jQuery if getComputedStyle is not supported\n          menuStyle = typeof getComputedStyle === 'function' ? getComputedStyle(menu) : false,\n          $menu = menuStyle ? null : $(menu),\n          menuPadding = {\n            vert: parseInt(menuStyle ? menuStyle.paddingTop : $menu.css('paddingTop')) +\n                  parseInt(menuStyle ? menuStyle.paddingBottom : $menu.css('paddingBottom')) +\n                  parseInt(menuStyle ? menuStyle.borderTopWidth : $menu.css('borderTopWidth')) +\n                  parseInt(menuStyle ? menuStyle.borderBottomWidth : $menu.css('borderBottomWidth')),\n            horiz: parseInt(menuStyle ? menuStyle.paddingLeft : $menu.css('paddingLeft')) +\n                  parseInt(menuStyle ? menuStyle.paddingRight : $menu.css('paddingRight')) +\n                  parseInt(menuStyle ? menuStyle.borderLeftWidth : $menu.css('borderLeftWidth')) +\n                  parseInt(menuStyle ? menuStyle.borderRightWidth : $menu.css('borderRightWidth'))\n          },\n          menuExtras =  {\n            vert: menuPadding.vert +\n                  parseInt(menuStyle ? menuStyle.marginTop : $menu.css('marginTop')) +\n                  parseInt(menuStyle ? menuStyle.marginBottom : $menu.css('marginBottom')) + 2,\n            horiz: menuPadding.horiz +\n                  parseInt(menuStyle ? menuStyle.marginLeft : $menu.css('marginLeft')) +\n                  parseInt(menuStyle ? menuStyle.marginRight : $menu.css('marginRight')) + 2\n          }\n\n      document.body.removeChild(newElement);\n\n      this.sizeInfo = {\n        liHeight: liHeight,\n        headerHeight: headerHeight,\n        searchHeight: searchHeight,\n        actionsHeight: actionsHeight,\n        doneButtonHeight: doneButtonHeight,\n        dividerHeight: dividerHeight,\n        menuPadding: menuPadding,\n        menuExtras: menuExtras\n      };\n    },\n\n    setSize: function () {\n      this.findLis();\n      this.liHeight();\n\n      if (this.options.header) this.$menu.css('padding-top', 0);\n      if (this.options.size === false) return;\n\n      var that = this,\n          $menu = this.$menu,\n          $menuInner = this.$menuInner,\n          $window = $(window),\n          selectHeight = this.$newElement[0].offsetHeight,\n          selectWidth = this.$newElement[0].offsetWidth,\n          liHeight = this.sizeInfo['liHeight'],\n          headerHeight = this.sizeInfo['headerHeight'],\n          searchHeight = this.sizeInfo['searchHeight'],\n          actionsHeight = this.sizeInfo['actionsHeight'],\n          doneButtonHeight = this.sizeInfo['doneButtonHeight'],\n          divHeight = this.sizeInfo['dividerHeight'],\n          menuPadding = this.sizeInfo['menuPadding'],\n          menuExtras = this.sizeInfo['menuExtras'],\n          notDisabled = this.options.hideDisabled ? '.disabled' : '',\n          menuHeight,\n          menuWidth,\n          getHeight,\n          getWidth,\n          selectOffsetTop,\n          selectOffsetBot,\n          selectOffsetLeft,\n          selectOffsetRight,\n          getPos = function() {\n            var pos = that.$newElement.offset(),\n                $container = $(that.options.container),\n                containerPos;\n\n            if (that.options.container && !$container.is('body')) {\n              containerPos = $container.offset();\n              containerPos.top += parseInt($container.css('borderTopWidth'));\n              containerPos.left += parseInt($container.css('borderLeftWidth'));\n            } else {\n              containerPos = { top: 0, left: 0 };\n            }\n\n            var winPad = that.options.windowPadding;\n            selectOffsetTop = pos.top - containerPos.top - $window.scrollTop();\n            selectOffsetBot = $window.height() - selectOffsetTop - selectHeight - containerPos.top - winPad[2];\n            selectOffsetLeft = pos.left - containerPos.left - $window.scrollLeft();\n            selectOffsetRight = $window.width() - selectOffsetLeft - selectWidth - containerPos.left - winPad[1];\n            selectOffsetTop -= winPad[0];\n            selectOffsetLeft -= winPad[3];\n          };\n\n      getPos();\n\n      if (this.options.size === 'auto') {\n        var getSize = function () {\n          var minHeight,\n              hasClass = function (className, include) {\n                return function (element) {\n                    if (include) {\n                        return (element.classList ? element.classList.contains(className) : $(element).hasClass(className));\n                    } else {\n                        return !(element.classList ? element.classList.contains(className) : $(element).hasClass(className));\n                    }\n                };\n              },\n              lis = that.$menuInner[0].getElementsByTagName('li'),\n              lisVisible = Array.prototype.filter ? Array.prototype.filter.call(lis, hasClass('hidden', false)) : that.$lis.not('.hidden'),\n              optGroup = Array.prototype.filter ? Array.prototype.filter.call(lisVisible, hasClass('dropdown-header', true)) : lisVisible.filter('.dropdown-header');\n\n          getPos();\n          menuHeight = selectOffsetBot - menuExtras.vert;\n          menuWidth = selectOffsetRight - menuExtras.horiz;\n\n          if (that.options.container) {\n            if (!$menu.data('height')) $menu.data('height', $menu.height());\n            getHeight = $menu.data('height');\n\n            if (!$menu.data('width')) $menu.data('width', $menu.width());\n            getWidth = $menu.data('width');\n          } else {\n            getHeight = $menu.height();\n            getWidth = $menu.width();\n          }\n\n          if (that.options.dropupAuto) {\n            that.$newElement.toggleClass('dropup', selectOffsetTop > selectOffsetBot && (menuHeight - menuExtras.vert) < getHeight);\n          }\n\n          if (that.$newElement.hasClass('dropup')) {\n            menuHeight = selectOffsetTop - menuExtras.vert;\n          }\n\n          if (that.options.dropdownAlignRight === 'auto') {\n            $menu.toggleClass('dropdown-menu-right', selectOffsetLeft > selectOffsetRight && (menuWidth - menuExtras.horiz) < (getWidth - selectWidth));\n          }\n\n          if ((lisVisible.length + optGroup.length) > 3) {\n            minHeight = liHeight * 3 + menuExtras.vert - 2;\n          } else {\n            minHeight = 0;\n          }\n\n          $menu.css({\n            'max-height': menuHeight + 'px',\n            'overflow': 'hidden',\n            'min-height': minHeight + headerHeight + searchHeight + actionsHeight + doneButtonHeight + 'px'\n          });\n          $menuInner.css({\n            'max-height': menuHeight - headerHeight - searchHeight - actionsHeight - doneButtonHeight - menuPadding.vert + 'px',\n            'overflow-y': 'auto',\n            'min-height': Math.max(minHeight - menuPadding.vert, 0) + 'px'\n          });\n        };\n        getSize();\n        this.$searchbox.off('input.getSize propertychange.getSize').on('input.getSize propertychange.getSize', getSize);\n        $window.off('resize.getSize scroll.getSize').on('resize.getSize scroll.getSize', getSize);\n      } else if (this.options.size && this.options.size != 'auto' && this.$lis.not(notDisabled).length > this.options.size) {\n        var optIndex = this.$lis.not('.divider').not(notDisabled).children().slice(0, this.options.size).last().parent().index(),\n            divLength = this.$lis.slice(0, optIndex + 1).filter('.divider').length;\n        menuHeight = liHeight * this.options.size + divLength * divHeight + menuPadding.vert;\n\n        if (that.options.container) {\n          if (!$menu.data('height')) $menu.data('height', $menu.height());\n          getHeight = $menu.data('height');\n        } else {\n          getHeight = $menu.height();\n        }\n\n        if (that.options.dropupAuto) {\n          //noinspection JSUnusedAssignment\n          this.$newElement.toggleClass('dropup', selectOffsetTop > selectOffsetBot && (menuHeight - menuExtras.vert) < getHeight);\n        }\n        $menu.css({\n          'max-height': menuHeight + headerHeight + searchHeight + actionsHeight + doneButtonHeight + 'px',\n          'overflow': 'hidden',\n          'min-height': ''\n        });\n        $menuInner.css({\n          'max-height': menuHeight - menuPadding.vert + 'px',\n          'overflow-y': 'auto',\n          'min-height': ''\n        });\n      }\n    },\n\n    setWidth: function () {\n      if (this.options.width === 'auto') {\n        this.$menu.css('min-width', '0');\n\n        // Get correct width if element is hidden\n        var $selectClone = this.$menu.parent().clone().appendTo('body'),\n            $selectClone2 = this.options.container ? this.$newElement.clone().appendTo('body') : $selectClone,\n            ulWidth = $selectClone.children('.dropdown-menu').outerWidth(),\n            btnWidth = $selectClone2.css('width', 'auto').children('button').outerWidth();\n\n        $selectClone.remove();\n        $selectClone2.remove();\n\n        // Set width to whatever's larger, button title or longest option\n        this.$newElement.css('width', Math.max(ulWidth, btnWidth) + 'px');\n      } else if (this.options.width === 'fit') {\n        // Remove inline min-width so width can be changed from 'auto'\n        this.$menu.css('min-width', '');\n        this.$newElement.css('width', '').addClass('fit-width');\n      } else if (this.options.width) {\n        // Remove inline min-width so width can be changed from 'auto'\n        this.$menu.css('min-width', '');\n        this.$newElement.css('width', this.options.width);\n      } else {\n        // Remove inline min-width/width so width can be changed\n        this.$menu.css('min-width', '');\n        this.$newElement.css('width', '');\n      }\n      // Remove fit-width class if width is changed programmatically\n      if (this.$newElement.hasClass('fit-width') && this.options.width !== 'fit') {\n        this.$newElement.removeClass('fit-width');\n      }\n    },\n\n    selectPosition: function () {\n      this.$bsContainer = $('<div class=\"bs-container\" />');\n\n      var that = this,\n          $container = $(this.options.container),\n          pos,\n          containerPos,\n          actualHeight,\n          getPlacement = function ($element) {\n            that.$bsContainer.addClass($element.attr('class').replace(/form-control|fit-width/gi, '')).toggleClass('dropup', $element.hasClass('dropup'));\n            pos = $element.offset();\n\n            if (!$container.is('body')) {\n              containerPos = $container.offset();\n              containerPos.top += parseInt($container.css('borderTopWidth')) - $container.scrollTop();\n              containerPos.left += parseInt($container.css('borderLeftWidth')) - $container.scrollLeft();\n            } else {\n              containerPos = { top: 0, left: 0 };\n            }\n\n            actualHeight = $element.hasClass('dropup') ? 0 : $element[0].offsetHeight;\n\n            that.$bsContainer.css({\n              'top': pos.top - containerPos.top + actualHeight,\n              'left': pos.left - containerPos.left,\n              'width': $element[0].offsetWidth\n            });\n          };\n\n      this.$button.on('click', function () {\n        var $this = $(this);\n\n        if (that.isDisabled()) {\n          return;\n        }\n\n        getPlacement(that.$newElement);\n\n        that.$bsContainer\n          .appendTo(that.options.container)\n          .toggleClass('open', !$this.hasClass('open'))\n          .append(that.$menu);\n      });\n\n      $(window).on('resize scroll', function () {\n        getPlacement(that.$newElement);\n      });\n\n      this.$element.on('hide.bs.select', function () {\n        that.$menu.data('height', that.$menu.height());\n        that.$bsContainer.detach();\n      });\n    },\n\n    /**\n     * @param {number} index - the index of the option that is being changed\n     * @param {boolean} selected - true if the option is being selected, false if being deselected\n     * @param {JQuery} $lis - the 'li' element that is being modified\n     */\n    setSelected: function (index, selected, $lis) {\n      if (!$lis) {\n        this.togglePlaceholder(); // check if setSelected is being called by changing the value of the select\n        $lis = this.findLis().eq(this.liObj[index]);\n      }\n\n      $lis.toggleClass('selected', selected).find('a').attr('aria-selected', selected);\n    },\n\n    /**\n     * @param {number} index - the index of the option that is being disabled\n     * @param {boolean} disabled - true if the option is being disabled, false if being enabled\n     * @param {JQuery} $lis - the 'li' element that is being modified\n     */\n    setDisabled: function (index, disabled, $lis) {\n      if (!$lis) {\n        $lis = this.findLis().eq(this.liObj[index]);\n      }\n\n      if (disabled) {\n        $lis.addClass('disabled').children('a').attr('href', '#').attr('tabindex', -1).attr('aria-disabled', true);\n      } else {\n        $lis.removeClass('disabled').children('a').removeAttr('href').attr('tabindex', 0).attr('aria-disabled', false);\n      }\n    },\n\n    isDisabled: function () {\n      return this.$element[0].disabled;\n    },\n\n    checkDisabled: function () {\n      var that = this;\n\n      if (this.isDisabled()) {\n        this.$newElement.addClass('disabled');\n        this.$button.addClass('disabled').attr('tabindex', -1).attr('aria-disabled', true);\n      } else {\n        if (this.$button.hasClass('disabled')) {\n          this.$newElement.removeClass('disabled');\n          this.$button.removeClass('disabled').attr('aria-disabled', false);\n        }\n\n        if (this.$button.attr('tabindex') == -1 && !this.$element.data('tabindex')) {\n          this.$button.removeAttr('tabindex');\n        }\n      }\n\n      this.$button.click(function () {\n        return !that.isDisabled();\n      });\n    },\n\n    togglePlaceholder: function () {\n      var value = this.$element.val();\n      this.$button.toggleClass('bs-placeholder', value === null || value === '' || (value.constructor === Array && value.length === 0));\n    },\n\n    tabIndex: function () {\n      if (this.$element.data('tabindex') !== this.$element.attr('tabindex') && \n        (this.$element.attr('tabindex') !== -98 && this.$element.attr('tabindex') !== '-98')) {\n        this.$element.data('tabindex', this.$element.attr('tabindex'));\n        this.$button.attr('tabindex', this.$element.data('tabindex'));\n      }\n\n      this.$element.attr('tabindex', -98);\n    },\n\n    clickListener: function () {\n      var that = this,\n          $document = $(document);\n\n      $document.data('spaceSelect', false);\n\n      this.$button.on('keyup', function (e) {\n        if (/(32)/.test(e.keyCode.toString(10)) && $document.data('spaceSelect')) {\n            e.preventDefault();\n            $document.data('spaceSelect', false);\n        }\n      });\n\n      this.$button.on('click', function () {\n        that.setSize();\n      });\n\n      this.$element.on('shown.bs.select', function () {\n        if (!that.options.liveSearch && !that.multiple) {\n          that.$menuInner.find('.selected a').focus();\n        } else if (!that.multiple) {\n          var selectedIndex = that.liObj[that.$element[0].selectedIndex];\n\n          if (typeof selectedIndex !== 'number' || that.options.size === false) return;\n\n          // scroll to selected option\n          var offset = that.$lis.eq(selectedIndex)[0].offsetTop - that.$menuInner[0].offsetTop;\n          offset = offset - that.$menuInner[0].offsetHeight/2 + that.sizeInfo.liHeight/2;\n          that.$menuInner[0].scrollTop = offset;\n        }\n      });\n\n      this.$menuInner.on('click', 'li a', function (e) {\n        var $this = $(this),\n            clickedIndex = $this.parent().data('originalIndex'),\n            prevValue = that.$element.val(),\n            prevIndex = that.$element.prop('selectedIndex'),\n            triggerChange = true;\n\n        // Don't close on multi choice menu\n        if (that.multiple && that.options.maxOptions !== 1) {\n          e.stopPropagation();\n        }\n\n        e.preventDefault();\n\n        //Don't run if we have been disabled\n        if (!that.isDisabled() && !$this.parent().hasClass('disabled')) {\n          var $options = that.$element.find('option'),\n              $option = $options.eq(clickedIndex),\n              state = $option.prop('selected'),\n              $optgroup = $option.parent('optgroup'),\n              maxOptions = that.options.maxOptions,\n              maxOptionsGrp = $optgroup.data('maxOptions') || false;\n\n          if (!that.multiple) { // Deselect all others if not multi select box\n            $options.prop('selected', false);\n            $option.prop('selected', true);\n            that.$menuInner.find('.selected').removeClass('selected').find('a').attr('aria-selected', false);\n            that.setSelected(clickedIndex, true);\n          } else { // Toggle the one we have chosen if we are multi select.\n            $option.prop('selected', !state);\n            that.setSelected(clickedIndex, !state);\n            $this.blur();\n\n            if (maxOptions !== false || maxOptionsGrp !== false) {\n              var maxReached = maxOptions < $options.filter(':selected').length,\n                  maxReachedGrp = maxOptionsGrp < $optgroup.find('option:selected').length;\n\n              if ((maxOptions && maxReached) || (maxOptionsGrp && maxReachedGrp)) {\n                if (maxOptions && maxOptions == 1) {\n                  $options.prop('selected', false);\n                  $option.prop('selected', true);\n                  that.$menuInner.find('.selected').removeClass('selected');\n                  that.setSelected(clickedIndex, true);\n                } else if (maxOptionsGrp && maxOptionsGrp == 1) {\n                  $optgroup.find('option:selected').prop('selected', false);\n                  $option.prop('selected', true);\n                  var optgroupID = $this.parent().data('optgroup');\n                  that.$menuInner.find('[data-optgroup=\"' + optgroupID + '\"]').removeClass('selected');\n                  that.setSelected(clickedIndex, true);\n                } else {\n                  var maxOptionsText = typeof that.options.maxOptionsText === 'string' ? [that.options.maxOptionsText, that.options.maxOptionsText] : that.options.maxOptionsText,\n                      maxOptionsArr = typeof maxOptionsText === 'function' ? maxOptionsText(maxOptions, maxOptionsGrp) : maxOptionsText,\n                      maxTxt = maxOptionsArr[0].replace('{n}', maxOptions),\n                      maxTxtGrp = maxOptionsArr[1].replace('{n}', maxOptionsGrp),\n                      $notify = $('<div class=\"notify\"></div>');\n                  // If {var} is set in array, replace it\n                  /** @deprecated */\n                  if (maxOptionsArr[2]) {\n                    maxTxt = maxTxt.replace('{var}', maxOptionsArr[2][maxOptions > 1 ? 0 : 1]);\n                    maxTxtGrp = maxTxtGrp.replace('{var}', maxOptionsArr[2][maxOptionsGrp > 1 ? 0 : 1]);\n                  }\n\n                  $option.prop('selected', false);\n\n                  that.$menu.append($notify);\n\n                  if (maxOptions && maxReached) {\n                    $notify.append($('<div>' + maxTxt + '</div>'));\n                    triggerChange = false;\n                    that.$element.trigger('maxReached.bs.select');\n                  }\n\n                  if (maxOptionsGrp && maxReachedGrp) {\n                    $notify.append($('<div>' + maxTxtGrp + '</div>'));\n                    triggerChange = false;\n                    that.$element.trigger('maxReachedGrp.bs.select');\n                  }\n\n                  setTimeout(function () {\n                    that.setSelected(clickedIndex, false);\n                  }, 10);\n\n                  $notify.delay(750).fadeOut(300, function () {\n                    $(this).remove();\n                  });\n                }\n              }\n            }\n          }\n\n          if (!that.multiple || (that.multiple && that.options.maxOptions === 1)) {\n            that.$button.focus();\n          } else if (that.options.liveSearch) {\n            that.$searchbox.focus();\n          }\n\n          // Trigger select 'change'\n          if (triggerChange) {\n            if ((prevValue != that.$element.val() && that.multiple) || (prevIndex != that.$element.prop('selectedIndex') && !that.multiple)) {\n              // $option.prop('selected') is current option state (selected/unselected). state is previous option state.\n              changed_arguments = [clickedIndex, $option.prop('selected'), state];\n              that.$element\n                .triggerNative('change');\n            }\n          }\n        }\n      });\n\n      this.$menu.on('click', 'li.disabled a, .popover-title, .popover-title :not(.close)', function (e) {\n        if (e.currentTarget == this) {\n          e.preventDefault();\n          e.stopPropagation();\n          if (that.options.liveSearch && !$(e.target).hasClass('close')) {\n            that.$searchbox.focus();\n          } else {\n            that.$button.focus();\n          }\n        }\n      });\n\n      this.$menuInner.on('click', '.divider, .dropdown-header', function (e) {\n        e.preventDefault();\n        e.stopPropagation();\n        if (that.options.liveSearch) {\n          that.$searchbox.focus();\n        } else {\n          that.$button.focus();\n        }\n      });\n\n      this.$menu.on('click', '.popover-title .close', function () {\n        that.$button.click();\n      });\n\n      this.$searchbox.on('click', function (e) {\n        e.stopPropagation();\n      });\n\n      this.$menu.on('click', '.actions-btn', function (e) {\n        if (that.options.liveSearch) {\n          that.$searchbox.focus();\n        } else {\n          that.$button.focus();\n        }\n\n        e.preventDefault();\n        e.stopPropagation();\n\n        if ($(this).hasClass('bs-select-all')) {\n          that.selectAll();\n        } else {\n          that.deselectAll();\n        }\n      });\n\n      this.$element.change(function () {\n        that.render(false);\n        that.$element.trigger('changed.bs.select', changed_arguments);\n        changed_arguments = null;\n      });\n    },\n\n    liveSearchListener: function () {\n      var that = this,\n          $no_results = $('<li class=\"no-results\"></li>');\n\n      this.$button.on('click.dropdown.data-api', function () {\n        that.$menuInner.find('.active').removeClass('active');\n        if (!!that.$searchbox.val()) {\n          that.$searchbox.val('');\n          that.$lis.not('.is-hidden').removeClass('hidden');\n          if (!!$no_results.parent().length) $no_results.remove();\n        }\n        if (!that.multiple) that.$menuInner.find('.selected').addClass('active');\n        setTimeout(function () {\n          that.$searchbox.focus();\n        }, 10);\n      });\n\n      this.$searchbox.on('click.dropdown.data-api focus.dropdown.data-api touchend.dropdown.data-api', function (e) {\n        e.stopPropagation();\n      });\n\n      this.$searchbox.on('input propertychange', function () {\n        that.$lis.not('.is-hidden').removeClass('hidden');\n        that.$lis.filter('.active').removeClass('active');\n        $no_results.remove();\n\n        if (that.$searchbox.val()) {\n          var $searchBase = that.$lis.not('.is-hidden, .divider, .dropdown-header'),\n              $hideItems;\n          if (that.options.liveSearchNormalize) {\n            $hideItems = $searchBase.find('a').not(':a' + that._searchStyle() + '(\"' + normalizeToBase(that.$searchbox.val()) + '\")');\n          } else {\n            $hideItems = $searchBase.find('a').not(':' + that._searchStyle() + '(\"' + that.$searchbox.val() + '\")');\n          }\n\n          if ($hideItems.length === $searchBase.length) {\n            $no_results.html(that.options.noneResultsText.replace('{0}', '\"' + htmlEscape(that.$searchbox.val()) + '\"'));\n            that.$menuInner.append($no_results);\n            that.$lis.addClass('hidden');\n          } else {\n            $hideItems.parent().addClass('hidden');\n\n            var $lisVisible = that.$lis.not('.hidden'),\n                $foundDiv;\n\n            // hide divider if first or last visible, or if followed by another divider\n            $lisVisible.each(function (index) {\n              var $this = $(this);\n\n              if ($this.hasClass('divider')) {\n                if ($foundDiv === undefined) {\n                  $this.addClass('hidden');\n                } else {\n                  if ($foundDiv) $foundDiv.addClass('hidden');\n                  $foundDiv = $this;\n                }\n              } else if ($this.hasClass('dropdown-header') && $lisVisible.eq(index + 1).data('optgroup') !== $this.data('optgroup')) {\n                $this.addClass('hidden');\n              } else {\n                $foundDiv = null;\n              }\n            });\n            if ($foundDiv) $foundDiv.addClass('hidden');\n\n            $searchBase.not('.hidden').first().addClass('active');\n          }\n        }\n      });\n    },\n\n    _searchStyle: function () {\n      var styles = {\n        begins: 'ibegins',\n        startsWith: 'ibegins'\n      };\n\n      return styles[this.options.liveSearchStyle] || 'icontains';\n    },\n\n    val: function (value) {\n      if (typeof value !== 'undefined') {\n        this.$element.val(value);\n        this.render();\n\n        return this.$element;\n      } else {\n        return this.$element.val();\n      }\n    },\n\n    changeAll: function (status) {\n      if (!this.multiple) return;\n      if (typeof status === 'undefined') status = true;\n\n      this.findLis();\n\n      var $options = this.$element.find('option'),\n          $lisVisible = this.$lis.not('.divider, .dropdown-header, .disabled, .hidden'),\n          lisVisLen = $lisVisible.length,\n          selectedOptions = [];\n          \n      if (status) {\n        if ($lisVisible.filter('.selected').length === $lisVisible.length) return;\n      } else {\n        if ($lisVisible.filter('.selected').length === 0) return;\n      }\n          \n      $lisVisible.toggleClass('selected', status);\n\n      for (var i = 0; i < lisVisLen; i++) {\n        var origIndex = $lisVisible[i].getAttribute('data-original-index');\n        selectedOptions[selectedOptions.length] = $options.eq(origIndex)[0];\n      }\n\n      $(selectedOptions).prop('selected', status);\n\n      this.render(false);\n\n      this.togglePlaceholder();\n\n      this.$element\n        .triggerNative('change');\n    },\n\n    selectAll: function () {\n      return this.changeAll(true);\n    },\n\n    deselectAll: function () {\n      return this.changeAll(false);\n    },\n\n    toggle: function (e) {\n      e = e || window.event;\n\n      if (e) e.stopPropagation();\n\n      this.$button.trigger('click');\n    },\n\n    keydown: function (e) {\n      var $this = $(this),\n          $parent = $this.is('input') ? $this.parent().parent() : $this.parent(),\n          $items,\n          that = $parent.data('this'),\n          index,\n          next,\n          first,\n          last,\n          prev,\n          nextPrev,\n          prevIndex,\n          isActive,\n          selector = ':not(.disabled, .hidden, .dropdown-header, .divider)',\n          keyCodeMap = {\n            32: ' ',\n            48: '0',\n            49: '1',\n            50: '2',\n            51: '3',\n            52: '4',\n            53: '5',\n            54: '6',\n            55: '7',\n            56: '8',\n            57: '9',\n            59: ';',\n            65: 'a',\n            66: 'b',\n            67: 'c',\n            68: 'd',\n            69: 'e',\n            70: 'f',\n            71: 'g',\n            72: 'h',\n            73: 'i',\n            74: 'j',\n            75: 'k',\n            76: 'l',\n            77: 'm',\n            78: 'n',\n            79: 'o',\n            80: 'p',\n            81: 'q',\n            82: 'r',\n            83: 's',\n            84: 't',\n            85: 'u',\n            86: 'v',\n            87: 'w',\n            88: 'x',\n            89: 'y',\n            90: 'z',\n            96: '0',\n            97: '1',\n            98: '2',\n            99: '3',\n            100: '4',\n            101: '5',\n            102: '6',\n            103: '7',\n            104: '8',\n            105: '9'\n          };\n\n      if (that.options.liveSearch) $parent = $this.parent().parent();\n\n      if (that.options.container) $parent = that.$menu;\n\n      $items = $('[role=\"listbox\"] li', $parent);\n\n      isActive = that.$newElement.hasClass('open');\n\n      if (!isActive && (e.keyCode >= 48 && e.keyCode <= 57 || e.keyCode >= 96 && e.keyCode <= 105 || e.keyCode >= 65 && e.keyCode <= 90)) {\n        if (!that.options.container) {\n          that.setSize();\n          that.$menu.parent().addClass('open');\n          isActive = true;\n        } else {\n          that.$button.trigger('click');\n        }\n        that.$searchbox.focus();\n        return;\n      }\n\n      if (that.options.liveSearch) {\n        if (/(^9$|27)/.test(e.keyCode.toString(10)) && isActive) {\n          e.preventDefault();\n          e.stopPropagation();\n          that.$menuInner.click();\n          that.$button.focus();\n        }\n        // $items contains li elements when liveSearch is enabled\n        $items = $('[role=\"listbox\"] li' + selector, $parent);\n        if (!$this.val() && !/(38|40)/.test(e.keyCode.toString(10))) {\n          if ($items.filter('.active').length === 0) {\n            $items = that.$menuInner.find('li');\n            if (that.options.liveSearchNormalize) {\n              $items = $items.filter(':a' + that._searchStyle() + '(' + normalizeToBase(keyCodeMap[e.keyCode]) + ')');\n            } else {\n              $items = $items.filter(':' + that._searchStyle() + '(' + keyCodeMap[e.keyCode] + ')');\n            }\n          }\n        }\n      }\n\n      if (!$items.length) return;\n\n      if (/(38|40)/.test(e.keyCode.toString(10))) {\n        index = $items.index($items.find('a').filter(':focus').parent());\n        first = $items.filter(selector).first().index();\n        last = $items.filter(selector).last().index();\n        next = $items.eq(index).nextAll(selector).eq(0).index();\n        prev = $items.eq(index).prevAll(selector).eq(0).index();\n        nextPrev = $items.eq(next).prevAll(selector).eq(0).index();\n\n        if (that.options.liveSearch) {\n          $items.each(function (i) {\n            if (!$(this).hasClass('disabled')) {\n              $(this).data('index', i);\n            }\n          });\n          index = $items.index($items.filter('.active'));\n          first = $items.first().data('index');\n          last = $items.last().data('index');\n          next = $items.eq(index).nextAll().eq(0).data('index');\n          prev = $items.eq(index).prevAll().eq(0).data('index');\n          nextPrev = $items.eq(next).prevAll().eq(0).data('index');\n        }\n\n        prevIndex = $this.data('prevIndex');\n\n        if (e.keyCode == 38) {\n          if (that.options.liveSearch) index--;\n          if (index != nextPrev && index > prev) index = prev;\n          if (index < first) index = first;\n          if (index == prevIndex) index = last;\n        } else if (e.keyCode == 40) {\n          if (that.options.liveSearch) index++;\n          if (index == -1) index = 0;\n          if (index != nextPrev && index < next) index = next;\n          if (index > last) index = last;\n          if (index == prevIndex) index = first;\n        }\n\n        $this.data('prevIndex', index);\n\n        if (!that.options.liveSearch) {\n          $items.eq(index).children('a').focus();\n        } else {\n          e.preventDefault();\n          if (!$this.hasClass('dropdown-toggle')) {\n            $items.removeClass('active').eq(index).addClass('active').children('a').focus();\n            $this.focus();\n          }\n        }\n\n      } else if (!$this.is('input')) {\n        var keyIndex = [],\n            count,\n            prevKey;\n\n        $items.each(function () {\n          if (!$(this).hasClass('disabled')) {\n            if ($.trim($(this).children('a').text().toLowerCase()).substring(0, 1) == keyCodeMap[e.keyCode]) {\n              keyIndex.push($(this).index());\n            }\n          }\n        });\n\n        count = $(document).data('keycount');\n        count++;\n        $(document).data('keycount', count);\n\n        prevKey = $.trim($(':focus').text().toLowerCase()).substring(0, 1);\n\n        if (prevKey != keyCodeMap[e.keyCode]) {\n          count = 1;\n          $(document).data('keycount', count);\n        } else if (count >= keyIndex.length) {\n          $(document).data('keycount', 0);\n          if (count > keyIndex.length) count = 1;\n        }\n\n        $items.eq(keyIndex[count - 1]).children('a').focus();\n      }\n\n      // Select focused option if \"Enter\", \"Spacebar\" or \"Tab\" (when selectOnTab is true) are pressed inside the menu.\n      if ((/(13|32)/.test(e.keyCode.toString(10)) || (/(^9$)/.test(e.keyCode.toString(10)) && that.options.selectOnTab)) && isActive) {\n        if (!/(32)/.test(e.keyCode.toString(10))) e.preventDefault();\n        if (!that.options.liveSearch) {\n          var elem = $(':focus');\n          elem.click();\n          // Bring back focus for multiselects\n          elem.focus();\n          // Prevent screen from scrolling if the user hit the spacebar\n          e.preventDefault();\n          // Fixes spacebar selection of dropdown items in FF & IE\n          $(document).data('spaceSelect', true);\n        } else if (!/(32)/.test(e.keyCode.toString(10))) {\n          that.$menuInner.find('.active a').click();\n          $this.focus();\n        }\n        $(document).data('keycount', 0);\n      }\n\n      if ((/(^9$|27)/.test(e.keyCode.toString(10)) && isActive && (that.multiple || that.options.liveSearch)) || (/(27)/.test(e.keyCode.toString(10)) && !isActive)) {\n        that.$menu.parent().removeClass('open');\n        if (that.options.container) that.$newElement.removeClass('open');\n        that.$button.focus();\n      }\n    },\n\n    mobile: function () {\n      this.$element.addClass('mobile-device');\n    },\n\n    refresh: function () {\n      this.$lis = null;\n      this.liObj = {};\n      this.reloadLi();\n      this.render();\n      this.checkDisabled();\n      this.liHeight(true);\n      this.setStyle();\n      this.setWidth();\n      if (this.$lis) this.$searchbox.trigger('propertychange');\n\n      this.$element.trigger('refreshed.bs.select');\n    },\n\n    hide: function () {\n      this.$newElement.hide();\n    },\n\n    show: function () {\n      this.$newElement.show();\n    },\n\n    remove: function () {\n      this.$newElement.remove();\n      this.$element.remove();\n    },\n\n    destroy: function () {\n      this.$newElement.before(this.$element).remove();\n\n      if (this.$bsContainer) {\n        this.$bsContainer.remove();\n      } else {\n        this.$menu.remove();\n      }\n\n      this.$element\n        .off('.bs.select')\n        .removeData('selectpicker')\n        .removeClass('bs-select-hidden selectpicker');\n    }\n  };\n\n  // SELECTPICKER PLUGIN DEFINITION\n  // ==============================\n  function Plugin(option) {\n    // get the args of the outer function..\n    var args = arguments;\n    // The arguments of the function are explicitly re-defined from the argument list, because the shift causes them\n    // to get lost/corrupted in android 2.3 and IE9 #715 #775\n    var _option = option;\n\n    [].shift.apply(args);\n\n    var value;\n    var chain = this.each(function () {\n      var $this = $(this);\n      if ($this.is('select')) {\n        var data = $this.data('selectpicker'),\n            options = typeof _option == 'object' && _option;\n\n        if (!data) {\n          var config = $.extend({}, Selectpicker.DEFAULTS, $.fn.selectpicker.defaults || {}, $this.data(), options);\n          config.template = $.extend({}, Selectpicker.DEFAULTS.template, ($.fn.selectpicker.defaults ? $.fn.selectpicker.defaults.template : {}), $this.data().template, options.template);\n          $this.data('selectpicker', (data = new Selectpicker(this, config)));\n        } else if (options) {\n          for (var i in options) {\n            if (options.hasOwnProperty(i)) {\n              data.options[i] = options[i];\n            }\n          }\n        }\n\n        if (typeof _option == 'string') {\n          if (data[_option] instanceof Function) {\n            value = data[_option].apply(data, args);\n          } else {\n            value = data.options[_option];\n          }\n        }\n      }\n    });\n\n    if (typeof value !== 'undefined') {\n      //noinspection JSUnusedAssignment\n      return value;\n    } else {\n      return chain;\n    }\n  }\n\n  var old = $.fn.selectpicker;\n  $.fn.selectpicker = Plugin;\n  $.fn.selectpicker.Constructor = Selectpicker;\n\n  // SELECTPICKER NO CONFLICT\n  // ========================\n  $.fn.selectpicker.noConflict = function () {\n    $.fn.selectpicker = old;\n    return this;\n  };\n\n  $(document)\n      .data('keycount', 0)\n      .on('keydown.bs.select', '.bootstrap-select [data-toggle=dropdown], .bootstrap-select [role=\"listbox\"], .bs-searchbox input', Selectpicker.prototype.keydown)\n      .on('focusin.modal', '.bootstrap-select [data-toggle=dropdown], .bootstrap-select [role=\"listbox\"], .bs-searchbox input', function (e) {\n        e.stopPropagation();\n      });\n\n  // SELECTPICKER DATA-API\n  // =====================\n  $(window).on('load.bs.select.data-api', function () {\n    $('.selectpicker').each(function () {\n      var $selectpicker = $(this);\n      Plugin.call($selectpicker, $selectpicker.data());\n    })\n  });\n})(jQuery);\n"
  },
  {
    "path": "app_frontend/static/plugin/bootstrap-select-1.12.2/js/i18n/defaults-ar_AR.js",
    "content": "/*!\n * Translated default messages for bootstrap-select.\n * Locale: AR (Arabic)\n * Author: Yasser Lotfy <y_l@alive.com>\n */\n(function ($) {\n  $.fn.selectpicker.defaults = {\n    noneSelectedText: 'لم يتم إختيار شئ',\n    noneResultsText: 'لا توجد نتائج مطابقة لـ {0}',\n    countSelectedText: function (numSelected, numTotal) {\n      return (numSelected == 1) ? \"{0} خيار تم إختياره\" : \"{0} خيارات تمت إختيارها\";\n    },\n    maxOptionsText: function (numAll, numGroup) {\n      return [\n        (numAll == 1) ? 'تخطى الحد المسموح ({n} خيار بحد أقصى)' : 'تخطى الحد المسموح ({n} خيارات بحد أقصى)',\n        (numGroup == 1) ? 'تخطى الحد المسموح للمجموعة ({n} خيار بحد أقصى)' : 'تخطى الحد المسموح للمجموعة ({n} خيارات بحد أقصى)'\n      ];\n    },\n    selectAllText: 'إختيار الجميع',\n    deselectAllText: 'إلغاء إختيار الجميع',\n    multipleSeparator: '، '\n  };\n})(jQuery);\n"
  },
  {
    "path": "app_frontend/static/plugin/bootstrap-select-1.12.2/js/i18n/defaults-bg_BG.js",
    "content": "/*\n * Translated default messages for bootstrap-select.\n * Locale: BG (Bulgaria)\n * Region: BG (Bulgaria)\n */\n(function ($) {\n  $.fn.selectpicker.defaults = {\n    noneSelectedText: 'Нищо избрано',\n    noneResultsText: 'Няма резултат за {0}',\n    countSelectedText: function (numSelected, numTotal) {\n      return (numSelected == 1) ? \"{0} избран елемент\" : \"{0} избрани елемента\";\n    },\n    maxOptionsText: function (numAll, numGroup) {\n      return [\n        (numAll == 1) ? 'Лимита е достигнат ({n} елемент максимум)' : 'Лимита е достигнат ({n} елемента максимум)',\n        (numGroup == 1) ? 'Груповия лимит е достигнат ({n} елемент максимум)' : 'Груповия лимит е достигнат ({n} елемента максимум)'\n      ];\n    },\n    selectAllText: 'Избери всички',\n    deselectAllText: 'Размаркирай всички',\n    multipleSeparator: ', '\n  };\n})(jQuery);\n"
  },
  {
    "path": "app_frontend/static/plugin/bootstrap-select-1.12.2/js/i18n/defaults-cro_CRO.js",
    "content": "/*\n * Translated default messages for bootstrap-select.\n * Locale: CRO (Croatia)\n * Region: CRO (Croatia)\n */\n(function ($) {\n  $.fn.selectpicker.defaults = {\n    noneSelectedText: 'Odaberite stavku',\n    noneResultsText: 'Nema rezultata pretrage {0}',\n    countSelectedText: function (numSelected, numTotal) {\n      return (numSelected == 1) ? \"{0} stavka selektirana\" : \"{0} stavke selektirane\";\n    },\n    maxOptionsText: function (numAll, numGroup) {\n      return [\n        (numAll == 1) ? 'Limit je postignut ({n} stvar maximalno)' : 'Limit je postignut ({n} stavke maksimalno)',\n        (numGroup == 1) ? 'Grupni limit je postignut ({n} stvar maksimalno)' : 'Grupni limit je postignut ({n} stavke maksimalno)'\n      ];\n    },\n    selectAllText: 'Selektiraj sve',\n    deselectAllText: 'Deselektiraj sve',\n    multipleSeparator: ', '\n  };\n})(jQuery);\n"
  },
  {
    "path": "app_frontend/static/plugin/bootstrap-select-1.12.2/js/i18n/defaults-cs_CZ.js",
    "content": "/*\n * Translated default messages for bootstrap-select.\n * Locale: CS\n * Region: CZ (Czech Republic)\n */\n(function ($) {\n  $.fn.selectpicker.defaults = {\n    noneSelectedText: 'Nic není vybráno',\n    noneResultsText: 'Žádné výsledky {0}',\n    countSelectedText: 'Označeno {0} z {1}',\n    maxOptionsText: ['Limit překročen ({n} {var} max)', 'Limit skupiny překročen ({n} {var} max)', ['položek', 'položka']],\n    multipleSeparator: ', '\n  };\n})(jQuery);\n"
  },
  {
    "path": "app_frontend/static/plugin/bootstrap-select-1.12.2/js/i18n/defaults-da_DK.js",
    "content": "/*\n * Translated default messages for bootstrap-select.\n * Locale: DA (Danish)\n * Region: DK (Denmark)\n */\n(function ($) {\n  $.fn.selectpicker.defaults = {\n    noneSelectedText: 'Intet valgt',\n    noneResultsText: 'Ingen resultater fundet {0}',\n    countSelectedText: function (numSelected, numTotal) {\n      return (numSelected == 1) ? \"{0} valgt\" : \"{0} valgt\";\n    },\n    maxOptionsText: function (numAll, numGroup) {\n      return [\n        (numAll == 1) ? 'Begrænsning nået (max {n} valgt)' : 'Begrænsning nået (max {n} valgte)',\n        (numGroup == 1) ? 'Gruppe-begrænsning nået (max {n} valgt)' : 'Gruppe-begrænsning nået (max {n} valgte)'\n      ];\n    },\n    selectAllText: 'Markér alle',\n    deselectAllText: 'Afmarkér alle',\n    multipleSeparator: ', '\n  };\n})(jQuery);\n"
  },
  {
    "path": "app_frontend/static/plugin/bootstrap-select-1.12.2/js/i18n/defaults-de_DE.js",
    "content": "/*\n * Translated default messages for bootstrap-select.\n * Locale: DE (German, deutsch)\n * Region: DE (Germany, Deutschland)\n */\n(function ($) {\n  $.fn.selectpicker.defaults = {\n    noneSelectedText: 'Bitte wählen...',\n    noneResultsText: 'Keine Ergebnisse für {0}',\n    countSelectedText: function (numSelected, numTotal) {\n      return (numSelected == 1) ? \"{0} Element ausgewählt\" : \"{0} Elemente ausgewählt\";\n    },\n    maxOptionsText: function (numAll, numGroup) {\n      return [\n        (numAll == 1) ? 'Limit erreicht ({n} Element max.)' : 'Limit erreicht ({n} Elemente max.)',\n        (numGroup == 1) ? 'Gruppen-Limit erreicht ({n} Element max.)' : 'Gruppen-Limit erreicht ({n} Elemente max.)'\n      ];\n    },\n    selectAllText: 'Alles auswählen',\n    deselectAllText: 'Nichts auswählen',\n    multipleSeparator: ', '\n  };\n})(jQuery);\n"
  },
  {
    "path": "app_frontend/static/plugin/bootstrap-select-1.12.2/js/i18n/defaults-en_US.js",
    "content": "/*\n * Translated default messages for bootstrap-select.\n * Locale: EN (English)\n * Region: US (United States)\n */\n(function ($) {\n  $.fn.selectpicker.defaults = {\n    noneSelectedText: 'Nothing selected',\n    noneResultsText: 'No results match {0}',\n    countSelectedText: function (numSelected, numTotal) {\n      return (numSelected == 1) ? \"{0} item selected\" : \"{0} items selected\";\n    },\n    maxOptionsText: function (numAll, numGroup) {\n      return [\n        (numAll == 1) ? 'Limit reached ({n} item max)' : 'Limit reached ({n} items max)',\n        (numGroup == 1) ? 'Group limit reached ({n} item max)' : 'Group limit reached ({n} items max)'\n      ];\n    },\n    selectAllText: 'Select All',\n    deselectAllText: 'Deselect All',\n    multipleSeparator: ', '\n  };\n})(jQuery);\n"
  },
  {
    "path": "app_frontend/static/plugin/bootstrap-select-1.12.2/js/i18n/defaults-es_CL.js",
    "content": "/*\n * Translated default messages for bootstrap-select.\n * Locale: ES (Spanish)\n * Region: CL (Chile)\n */\n(function ($) {\n  $.fn.selectpicker.defaults = {\n    noneSelectedText: 'No hay selección',\n    noneResultsText: 'No hay resultados {0}',\n    countSelectedText: 'Seleccionados {0} de {1}',\n    maxOptionsText: ['Límite alcanzado ({n} {var} max)', 'Límite del grupo alcanzado({n} {var} max)', ['elementos', 'element']],\n    multipleSeparator: ', ',\n    selectAllText: 'Seleccionar Todos',\n    deselectAllText: 'Desmarcar Todos'\n  };\n})(jQuery);\n"
  },
  {
    "path": "app_frontend/static/plugin/bootstrap-select-1.12.2/js/i18n/defaults-es_ES.js",
    "content": "/*\n * Translated default messages for bootstrap-select.\n * Locale: ES (Spanish)\n * Region: ES (Spain)\n */\n(function ($) {\n  $.fn.selectpicker.defaults = {\n    noneSelectedText: 'No hay selección',\n    noneResultsText: 'No hay resultados {0}',\n    countSelectedText: 'Seleccionados {0} de {1}',\n    maxOptionsText: ['Límite alcanzado ({n} {var} max)', 'Límite del grupo alcanzado({n} {var} max)', ['elementos', 'element']],\n    multipleSeparator: ', ',\n    selectAllText: 'Seleccionar Todos',\n    deselectAllText: 'Desmarcar Todos'\n  };\n})(jQuery);\n"
  },
  {
    "path": "app_frontend/static/plugin/bootstrap-select-1.12.2/js/i18n/defaults-eu.js",
    "content": "/*\n * Translated default messages for bootstrap-select.\n * Locale: EU (Basque)\n * Region: \n */\n(function ($) {\n  $.fn.selectpicker.defaults = {\n    noneSelectedText: 'Hautapenik ez',\n    noneResultsText: 'Emaitzarik ez {0}',\n    countSelectedText: '{1}(e)tik {0} hautatuta',\n    maxOptionsText: ['Mugara iritsita ({n} {var} gehienez)', 'Taldearen mugara iritsita ({n} {var} gehienez)', ['elementu', 'elementu']],\n    multipleSeparator: ', '\n  };\n})(jQuery);\n"
  },
  {
    "path": "app_frontend/static/plugin/bootstrap-select-1.12.2/js/i18n/defaults-fa_IR.js",
    "content": "/*\n * Translated default messages for bootstrap-select.\n * Locale: FA (Farsi)\n * Region: IR (Iran)\n */\n(function ($) {\n    $.fn.selectpicker.defaults = {\n        noneSelectedText: 'چیزی انتخاب نشده است',\n        noneResultsText: 'هیج مشابهی برای {0} پیدا نشد',\n        countSelectedText: \"{0} از {1} مورد انتخاب شده\",\n        maxOptionsText: ['بیشتر ممکن نیست {حداکثر {n} عدد}', 'بیشتر ممکن نیست {حداکثر {n} عدد}'],\n        selectAllText: 'انتخاب همه',\n        deselectAllText: 'انتخاب هیچ کدام',\n        multipleSeparator: ', '\n    };\n})(jQuery);\n"
  },
  {
    "path": "app_frontend/static/plugin/bootstrap-select-1.12.2/js/i18n/defaults-fi_FI.js",
    "content": "/*\n * Translated default messages for bootstrap-select.\n * Locale: FI (Finnish)\n * Region: FI (Finland)\n */\n(function ($) {\n  $.fn.selectpicker.defaults = {\n    noneSelectedText: 'Ei valintoja',\n    noneResultsText: 'Ei hakutuloksia {0}',\n    countSelectedText: function (numSelected, numTotal) {\n      return (numSelected == 1) ? \"{0} valittu\" : \"{0} valitut\";\n    },\n    maxOptionsText: function (numAll, numGroup) {\n      return [\n        (numAll == 1) ? 'Valintojen maksimimäärä ({n} saavutettu)' : 'Valintojen maksimimäärä ({n} saavutettu)',\n        (numGroup == 1) ? 'Ryhmän maksimimäärä ({n} saavutettu)' : 'Ryhmän maksimimäärä ({n} saavutettu)'\n      ];\n    },\n    selectAllText: 'Valitse kaikki',\n    deselectAllText: 'Poista kaikki',\n    multipleSeparator: ', '\n  };\n})(jQuery);\n"
  },
  {
    "path": "app_frontend/static/plugin/bootstrap-select-1.12.2/js/i18n/defaults-fr_FR.js",
    "content": "/*\n * Translated default messages for bootstrap-select.\n * Locale: FR (French; Français)\n * Region: FR (France)\n */\n(function ($) {\n  $.fn.selectpicker.defaults = {\n    noneSelectedText: 'Aucune sélection',\n    noneResultsText: 'Aucun résultat pour {0}',\n    countSelectedText: function (numSelected, numTotal) {\n      return (numSelected > 1) ? \"{0} éléments sélectionnés\" : \"{0} élément sélectionné\";\n    },\n    maxOptionsText: function (numAll, numGroup) {\n      return [\n        (numAll > 1) ? 'Limite atteinte ({n} éléments max)' : 'Limite atteinte ({n} élément max)',\n        (numGroup > 1) ? 'Limite du groupe atteinte ({n} éléments max)' : 'Limite du groupe atteinte ({n} élément max)'\n      ];\n    },\n    multipleSeparator: ', ',\n    selectAllText: 'Tout Sélectionner',\n    deselectAllText: 'Tout Dé-selectionner',\n  };\n})(jQuery);\n"
  },
  {
    "path": "app_frontend/static/plugin/bootstrap-select-1.12.2/js/i18n/defaults-hu_HU.js",
    "content": "/*\n * Translated default messages for bootstrap-select.\n * Locale: HU (Hungarian)\n * Region: HU (Hungary)\n */\n(function ($) {\n  $.fn.selectpicker.defaults = {\n    noneSelectedText: 'Válasszon!',\n    noneResultsText: 'Nincs találat {0}',\n    countSelectedText: function (numSelected, numTotal) {\n      return '{0} elem kiválasztva';\n    },\n    maxOptionsText: function (numAll, numGroup) {\n      return [\n        'Legfeljebb {n} elem választható',\n        'A csoportban legfeljebb {n} elem választható'\n      ];\n    },\n    selectAllText: 'Mind',\n    deselectAllText: 'Egyik sem',\n    multipleSeparator: ', '\n  };\n})(jQuery);\n"
  },
  {
    "path": "app_frontend/static/plugin/bootstrap-select-1.12.2/js/i18n/defaults-id_ID.js",
    "content": "/*\n * Translated default messages for bootstrap-select.\n * Locale: ID (Indonesian; Bahasa Indonesia)\n * Region: ID (Indonesia)\n */\n(function ($) {\n  $.fn.selectpicker.defaults = {\n    noneSelectedText: 'Tidak ada yang dipilih',\n    noneResultsText: 'Tidak ada yang cocok {0}',\n    countSelectedText: '{0} terpilih',\n    maxOptionsText: ['Mencapai batas (maksimum {n})', 'Mencapai batas grup (maksimum {n})'],\n    selectAllText: 'Pilih Semua',\n    deselectAllText: 'Hapus Semua',\n    multipleSeparator: ', '\n  };\n})(jQuery);\n"
  },
  {
    "path": "app_frontend/static/plugin/bootstrap-select-1.12.2/js/i18n/defaults-it_IT.js",
    "content": "/*\n * Translated default messages for bootstrap-select.\n * Locale: IT (Italian; italiano)\n * Region: IT (Italy; Italia)\n * Author: Michele Beltrame <mb@cattlegrid.info>\n */\n(function ($) {\n  $.fn.selectpicker.defaults = {\n    noneSelectedText: 'Nessuna selezione',\n    noneResultsText: 'Nessun risultato per {0}',\n    countSelectedText: function (numSelected, numTotal){\n      return (numSelected == 1) ? 'Selezionato {0} di {1}' : 'Selezionati {0} di {1}';\n    },\n    maxOptionsText: ['Limite raggiunto ({n} {var} max)', 'Limite del gruppo raggiunto ({n} {var} max)', ['elementi', 'elemento']],\n    multipleSeparator: ', ',\n    selectAllText: 'Seleziona Tutto',\n    deselectAllText: 'Deseleziona Tutto'\n  };\n})(jQuery);\n"
  },
  {
    "path": "app_frontend/static/plugin/bootstrap-select-1.12.2/js/i18n/defaults-ko_KR.js",
    "content": "/*\n * Translated default messages for bootstrap-select.\n * Locale: KO (Korean)\n * Region: KR (South Korea)\n */\n(function ($) {\n  $.fn.selectpicker.defaults = {\n    noneSelectedText: '항목을 선택해주세요',\n    noneResultsText: '{0} 검색 결과가 없습니다',\n    countSelectedText: function (numSelected, numTotal) {\n      return \"{0}개를 선택하였습니다\";\n    },\n    maxOptionsText: function (numAll, numGroup) {\n      return [\n        '{n}개까지 선택 가능합니다',\n        '해당 그룹은 {n}개까지 선택 가능합니다'\n      ];\n    },\n    selectAllText: '전체선택',\n    deselectAllText: '전체해제',\n    multipleSeparator: ', '\n  };\n})(jQuery);\n"
  },
  {
    "path": "app_frontend/static/plugin/bootstrap-select-1.12.2/js/i18n/defaults-lt_LT.js",
    "content": "/*\n * Translated default messages for bootstrap-select.\n * Locale: LT (Lithuanian)\n * Region: LT (Lithuania)\n */\n(function ($) {\n  $.fn.selectpicker.defaults = {\n    noneSelectedText: 'Niekas nepasirinkta',\n    noneResultsText: 'Niekas nesutapo su {0}',\n    countSelectedText: function (numSelected, numTotal) {\n      return (numSelected == 1) ? \"{0} elementas pasirinktas\" : \"{0} elementai(-ų) pasirinkta\";\n    },\n    maxOptionsText: function (numAll, numGroup) {\n      return [\n        (numAll == 1) ? 'Pasiekta riba ({n} elementas daugiausiai)' : 'Riba pasiekta ({n} elementai(-ų) daugiausiai)',\n        (numGroup == 1) ? 'Grupės riba pasiekta ({n} elementas daugiausiai)' : 'Grupės riba pasiekta ({n} elementai(-ų) daugiausiai)'\n      ];\n    },\n    selectAllText: 'Pasirinkti visus',\n    deselectAllText: 'Atmesti visus',\n    multipleSeparator: ', '\n  };\n})(jQuery);\n"
  },
  {
    "path": "app_frontend/static/plugin/bootstrap-select-1.12.2/js/i18n/defaults-nb_NO.js",
    "content": "/*\n * Translated default messages for bootstrap-select.\n * Locale: NB (Norwegian; Bokmål)\n * Region: NO (Norway)\n */\n(function ($) {\n  $.fn.selectpicker.defaults = {\n    noneSelectedText: 'Ingen valgt',\n    noneResultsText: 'Søket gir ingen treff {0}',\n    countSelectedText: function (numSelected, numTotal) {\n      return (numSelected == 1) ? \"{0} alternativ valgt\" : \"{0} alternativer valgt\";\n    },\n    maxOptionsText: function (numAll, numGroup) {\n      return [\n        (numAll == 1) ? 'Grense nådd (maks {n} valg)' : 'Grense nådd (maks {n} valg)',\n        (numGroup == 1) ? 'Grense for grupper nådd (maks {n} grupper)' : 'Grense for grupper nådd (maks {n} grupper)'\n      ];\n    },\n    selectAllText: 'Merk alle',\n    deselectAllText: 'Fjern alle',\n    multipleSeparator: ', '\n  };\n})(jQuery);\n"
  },
  {
    "path": "app_frontend/static/plugin/bootstrap-select-1.12.2/js/i18n/defaults-nl_NL.js",
    "content": "/*\n * Translated default messages for bootstrap-select.\n * Locale: NL (Dutch; Nederlands)\n * Region: NL (Europe)\n * Author: Daan Rosbergen (Badmuts)\n */\n(function ($) {\n  $.fn.selectpicker.defaults = {\n    noneSelectedText: 'Niets geselecteerd',\n    noneResultsText: 'Geen resultaten gevonden voor {0}',\n    countSelectedText: '{0} van {1} geselecteerd',\n    maxOptionsText: ['Limiet bereikt ({n} {var} max)', 'Groep limiet bereikt ({n} {var} max)', ['items', 'item']],\n    multipleSeparator: ', '\n  };\n})(jQuery);\n"
  },
  {
    "path": "app_frontend/static/plugin/bootstrap-select-1.12.2/js/i18n/defaults-pl_PL.js",
    "content": "/*\n * Translated default messages for bootstrap-select.\n * Locale: PL (Polish)\n * Region: EU (Europe)\n */\n(function ($) {\n  $.fn.selectpicker.defaults = {\n    noneSelectedText: 'Nic nie zaznaczono',\n    noneResultsText: 'Brak wyników wyszukiwania {0}',\n    countSelectedText: 'Zaznaczono {0} z {1}',\n    maxOptionsText: ['Osiągnięto limit ({n} {var} max)', 'Limit grupy osiągnięty ({n} {var} max)', ['elementy', 'element']],\n    selectAll: 'Zaznacz wszystkie',\n    deselectAll: 'Odznacz wszystkie',\n    multipleSeparator: ', '\n  };\n})(jQuery);\n"
  },
  {
    "path": "app_frontend/static/plugin/bootstrap-select-1.12.2/js/i18n/defaults-pt_BR.js",
    "content": "/*\n * Translated default messages for bootstrap-select.\n * Locale: PT (Portuguese; português)\n * Region: BR (Brazil; Brasil)\n * Author: Rodrigo de Avila <rodrigo@avila.net.br>\n */\n(function ($) {\n  $.fn.selectpicker.defaults = {\n    noneSelectedText: 'Nada selecionado',\n    noneResultsText: 'Nada encontrado contendo {0}',\n    countSelectedText: 'Selecionado {0} de {1}',\n    maxOptionsText: ['Limite excedido (máx. {n} {var})', 'Limite do grupo excedido (máx. {n} {var})', ['itens', 'item']],\n    multipleSeparator: ', '\n  };\n})(jQuery);\n"
  },
  {
    "path": "app_frontend/static/plugin/bootstrap-select-1.12.2/js/i18n/defaults-pt_PT.js",
    "content": "/*\n* Translated default messages for bootstrap-select.\n* Locale: PT (Portuguese; português)\n* Region: PT (Portugal; Portugal)\n* Author: Burnspirit <burnspirit@gmail.com>\n*/\n(function ($) {\n$.fn.selectpicker.defaults = {\nnoneSelectedText: 'Nenhum seleccionado',\nnoneResultsText: 'Sem resultados contendo {0}',\ncountSelectedText: 'Selecionado {0} de {1}',\nmaxOptionsText: ['Limite ultrapassado (máx. {n} {var})', 'Limite de seleções ultrapassado (máx. {n} {var})', ['itens', 'item']],\nmultipleSeparator: ', '\n};\n})(jQuery);\n"
  },
  {
    "path": "app_frontend/static/plugin/bootstrap-select-1.12.2/js/i18n/defaults-ro_RO.js",
    "content": "/*\n * Translated default messages for bootstrap-select.\n * Locale: RO (Romanian)\n * Region: RO (Romania)\n * Alex Florea <alecz.fia@gmail.com>\n */\n(function ($) {\n  $.fn.selectpicker.defaults = {\n    noneSelectedText: 'Nu a fost selectat nimic',\n    noneResultsText: 'Nu exista niciun rezultat {0}',\n    countSelectedText: '{0} din {1} selectat(e)',\n    maxOptionsText: ['Limita a fost atinsa ({n} {var} max)', 'Limita de grup a fost atinsa ({n} {var} max)', ['iteme', 'item']],\n    multipleSeparator: ', '\n  };\n})(jQuery);\n"
  },
  {
    "path": "app_frontend/static/plugin/bootstrap-select-1.12.2/js/i18n/defaults-ru_RU.js",
    "content": "/*\n * Translated default messages for bootstrap-select.\n * Locale: RU (Russian; Русский)\n * Region: RU (Russian Federation)\n */\n(function ($) {\n  $.fn.selectpicker.defaults = {\n    noneSelectedText: 'Ничего не выбрано',\n    noneResultsText: 'Совпадений не найдено {0}',\n    countSelectedText: 'Выбрано {0} из {1}',\n    maxOptionsText: ['Достигнут предел ({n} {var} максимум)', 'Достигнут предел в группе ({n} {var} максимум)', ['шт.', 'шт.']],\n    doneButtonText: 'Закрыть',\n    selectAllText: 'Выбрать все',\n    deselectAllText: 'Отменить все',    \n    multipleSeparator: ', '\n  };\n})(jQuery);\n"
  },
  {
    "path": "app_frontend/static/plugin/bootstrap-select-1.12.2/js/i18n/defaults-sk_SK.js",
    "content": "/*\n * Translated default messages for bootstrap-select.\n * Locale: SK\n * Region: SK (Slovak Republic)\n */\n(function ($) {\n  $.fn.selectpicker.defaults = {\n    noneSelectedText: 'Vyberte zo zoznamu',\n    noneResultsText: 'Pre výraz {0} neboli nájdené žiadne výsledky',\n    countSelectedText: 'Vybrané {0} z {1}',\n    maxOptionsText: ['Limit prekročený ({n} {var} max)', 'Limit skupiny prekročený ({n} {var} max)', ['položiek', 'položka']],\n    selectAllText: 'Vybrať všetky',\n    deselectAllText: 'Zrušiť výber',\n    multipleSeparator: ', '\n  };\n})(jQuery);\n"
  },
  {
    "path": "app_frontend/static/plugin/bootstrap-select-1.12.2/js/i18n/defaults-sl_SI.js",
    "content": "/*\n * Translated default messages for bootstrap-select.\n * Locale: SL (Slovenian)\n * Region: SI (Slovenia)\n */\n(function ($) {\n  $.fn.selectpicker.defaults = {\n    noneSelectedText: 'Nič izbranega',\n    noneResultsText: 'Ni zadetkov za {0}',\n    countSelectedText: function (numSelected, numTotal) {\n      \"Število izbranih: {0}\";\n    },\n    maxOptionsText: function (numAll, numGroup) {\n      return [\n        'Omejitev dosežena (max. izbranih: {n})',\n        'Omejitev skupine dosežena (max. izbranih: {n})'\n      ];\n    },\n    selectAllText: 'Izberi vse',\n    deselectAllText: 'Počisti izbor',\n    multipleSeparator: ', '\n  };\n})(jQuery);\n"
  },
  {
    "path": "app_frontend/static/plugin/bootstrap-select-1.12.2/js/i18n/defaults-sv_SE.js",
    "content": "/*\n * Translated default messages for bootstrap-select.\n * Locale: SV (Swedish)\n * Region: SE (Sweden)\n */\n(function ($) {\n  $.fn.selectpicker.defaults = {\n    noneSelectedText: 'Inget valt',\n    noneResultsText: 'Inget sökresultat matchar {0}',\n    countSelectedText: function (numSelected, numTotal) {\n      return (numSelected === 1) ? \"{0} alternativ valt\" : \"{0} alternativ valda\";\n    },\n    maxOptionsText: function (numAll, numGroup) {\n      return [\n        'Gräns uppnåd (max {n} alternativ)',\n        'Gräns uppnåd (max {n} gruppalternativ)'\n      ];\n    },\n    selectAllText: 'Markera alla',\n    deselectAllText: 'Avmarkera alla',\n    multipleSeparator: ', '\n  };\n})(jQuery);\n"
  },
  {
    "path": "app_frontend/static/plugin/bootstrap-select-1.12.2/js/i18n/defaults-tr_TR.js",
    "content": "/*\n * Translated default messages for bootstrap-select.\n * Locale: TR (Turkey)\n * Region: TR (Europe)\n * Author: Serhan Güney\n */\n(function ($) {\n  $.fn.selectpicker.defaults = {\n    noneSelectedText: 'Hiçbiri seçilmedi',\n    noneResultsText: 'Hiçbir sonuç bulunamadı {0}',\n    countSelectedText: function (numSelected, numTotal) {\n      return (numSelected == 1) ? \"{0} öğe seçildi\" : \"{0} öğe seçildi\";\n    },\n    maxOptionsText: function (numAll, numGroup) {\n      return [\n        (numAll == 1) ? 'Limit aşıldı (maksimum {n} sayıda öğe )' : 'Limit aşıldı (maksimum {n} sayıda öğe)',\n        (numGroup == 1) ? 'Grup limiti aşıldı (maksimum {n} sayıda öğe)' : 'Grup limiti aşıldı (maksimum {n} sayıda öğe)'\n      ];\n    },\n    selectAllText: 'Tümünü Seç',\n    deselectAllText: 'Seçiniz',\n    multipleSeparator: ', '\n  };\n})(jQuery);\n"
  },
  {
    "path": "app_frontend/static/plugin/bootstrap-select-1.12.2/js/i18n/defaults-ua_UA.js",
    "content": "/*\n * Translated default messages for bootstrap-select.\n * Locale: UA (Ukrainian; Українська)\n * Region: UA (Ukraine)\n */\n(function ($) {\n  $.fn.selectpicker.defaults = {\n    noneSelectedText: 'Нічого не вибрано',\n    noneResultsText: 'Збігів не знайдено {0}',\n    countSelectedText: 'Вибрано {0} із {1}',\n    maxOptionsText: ['Досягнута межа ({n} {var} максимум)', 'Досягнута межа в групі ({n} {var} максимум)', ['items', 'item']],\n    multipleSeparator: ', '\n  };\n})(jQuery);\n"
  },
  {
    "path": "app_frontend/static/plugin/bootstrap-select-1.12.2/js/i18n/defaults-zh_CN.js",
    "content": "/*\n * Translated default messages for bootstrap-select.\n * Locale: ZH (Chinese)\n * Region: CN (China)\n */\n(function ($) {\n  $.fn.selectpicker.defaults = {\n    noneSelectedText: '没有选中任何项',\n    noneResultsText: '没有找到匹配项',\n    countSelectedText: '选中{1}中的{0}项',\n    maxOptionsText: ['超出限制 (最多选择{n}项)', '组选择超出限制(最多选择{n}组)'],\n    multipleSeparator: ', '\n  };\n})(jQuery);\n"
  },
  {
    "path": "app_frontend/static/plugin/bootstrap-select-1.12.2/js/i18n/defaults-zh_TW.js",
    "content": "/*\n * Translated default messages for bootstrap-select.\n * Locale: ZH (Chinese)\n * Region: TW (Taiwan)\n */\n(function ($) {\n  $.fn.selectpicker.defaults = {\n    noneSelectedText: '沒有選取任何項目',\n    noneResultsText: '沒有找到符合的結果',\n    countSelectedText: '已經選取{0}個項目',\n    maxOptionsText: ['超過限制 (最多選擇{n}項)', '超過限制(最多選擇{n}組)'],\n    selectAllText: '選取全部',\n    deselectAllText: '全部取消',\n    multipleSeparator: ', '\n  };\n})(jQuery);\n"
  },
  {
    "path": "app_frontend/static/plugin/bootstrap-select-1.12.2/less/bootstrap-select.less",
    "content": "@import \"variables\";\n\n// Mixins\n.cursor-disabled() {\n  cursor: not-allowed;\n}\n\n// Rules\nselect.bs-select-hidden,\nselect.selectpicker {\n  display: none !important;\n}\n\n.bootstrap-select {\n  width: 220px \\0; /*IE9 and below*/\n\n  // The selectpicker button\n  > .dropdown-toggle {\n    width: 100%;\n    padding-right: 25px;\n    z-index: 1;\n\n    &.bs-placeholder,\n    &.bs-placeholder:hover,\n    &.bs-placeholder:focus,\n    &.bs-placeholder:active { color: @input-color-placeholder; }\n  }\n\n  > select {\n    position: absolute !important;\n    bottom: 0;\n    left: 50%;\n    display: block !important;\n    width: 0.5px !important;\n    height: 100% !important;\n    padding: 0 !important;\n    opacity: 0 !important;\n    border: none;\n\n    &.mobile-device {\n      top: 0;\n      left: 0;\n      display: block !important;\n      width: 100% !important;\n      z-index: 2;\n    }\n  }\n\n  // Error display\n  .has-error & .dropdown-toggle,\n  .error & .dropdown-toggle {\n    border-color: @color-red-error;\n  }\n\n  &.fit-width {\n    width: auto !important;\n  }\n\n  &:not([class*=\"col-\"]):not([class*=\"form-control\"]):not(.input-group-btn) {\n    width: @width-default;\n  }\n\n  .dropdown-toggle:focus {\n    outline: thin dotted #333333 !important;\n    outline: 5px auto -webkit-focus-ring-color !important;\n    outline-offset: -2px;\n  }\n}\n\n.bootstrap-select.form-control {\n  margin-bottom: 0;\n  padding: 0;\n  border: none;\n\n  &:not([class*=\"col-\"]) {\n    width: 100%;\n  }\n\n  &.input-group-btn {\n    z-index: auto;\n\n    &:not(:first-child):not(:last-child) {\n      > .btn {\n        border-radius: 0;\n      }\n    }\n  }\n}\n\n// The selectpicker components\n.bootstrap-select.btn-group {\n  &:not(.input-group-btn),\n  &[class*=\"col-\"] {\n    float: none;\n    display: inline-block;\n    margin-left: 0;\n  }\n\n  // Forces the pull to the right, if necessary\n  &,\n  &[class*=\"col-\"],\n  .row &[class*=\"col-\"] {\n    &.dropdown-menu-right {\n      float: right;\n    }\n  }\n\n  .form-inline &,\n  .form-horizontal &,\n  .form-group & {\n    margin-bottom: 0;\n  }\n\n  .form-group-lg &.form-control,\n  .form-group-sm &.form-control {\n    padding: 0;\n\n    .dropdown-toggle {\n      height: 100%;\n      font-size: inherit;\n      line-height: inherit;\n      border-radius: inherit;\n    }\n  }\n\n  // Set the width of the live search (and any other form control within an inline form)\n  // see https://github.com/silviomoreto/bootstrap-select/issues/685\n  .form-inline & .form-control {\n    width: 100%;\n  }\n\n  &.disabled,\n  > .disabled {\n    .cursor-disabled();\n\n    &:focus {\n      outline: none !important;\n    }\n  }\n\n  &.bs-container {\n    position: absolute;\n    height: 0 !important;\n    padding: 0 !important;\n    \n    .dropdown-menu {\n      z-index: @zindex-select-dropdown;\n    }\n  }\n\n  // The selectpicker button\n  .dropdown-toggle {\n    .filter-option {\n      display: inline-block;\n      overflow: hidden;\n      width: 100%;\n      text-align: left;\n    }\n\n    .caret {\n      position: absolute;\n      top: 50%;\n      right: 12px;\n      margin-top: -2px;\n      vertical-align: middle;\n    }\n  }\n\n  &[class*=\"col-\"] .dropdown-toggle {\n    width: 100%;\n  }\n\n  // The selectpicker dropdown\n  .dropdown-menu {\n    min-width: 100%;\n    box-sizing: border-box;\n\n    &.inner {\n      position: static;\n      float: none;\n      border: 0;\n      padding: 0;\n      margin: 0;\n      border-radius: 0;\n      box-shadow: none;\n    }\n\n    li {\n      position: relative;\n\n      &.active small {\n        color: #fff;\n      }\n\n      &.disabled a {\n        .cursor-disabled();\n      }\n\n      a {\n        cursor: pointer;\n        user-select: none;\n\n        &.opt {\n          position: relative;\n          padding-left: 2.25em;\n        }\n\n        span.check-mark {\n          display: none;\n        }\n\n        span.text {\n          display: inline-block;\n        }\n      }\n\n      small {\n        padding-left: 0.5em;\n      }\n    }\n\n    .notify {\n      position: absolute;\n      bottom: 5px;\n      width: 96%;\n      margin: 0 2%;\n      min-height: 26px;\n      padding: 3px 5px;\n      background: rgb(245, 245, 245);\n      border: 1px solid rgb(227, 227, 227);\n      box-shadow: inset 0 1px 1px fade(rgb(0, 0, 0), 5%);\n      pointer-events: none;\n      opacity: 0.9;\n      box-sizing: border-box;\n    }\n  }\n\n  .no-results {\n    padding: 3px;\n    background: #f5f5f5;\n    margin: 0 5px;\n    white-space: nowrap;\n  }\n\n  &.fit-width .dropdown-toggle {\n    .filter-option {\n      position: static;\n    }\n\n    .caret {\n      position: static;\n      top: auto;\n      margin-top: -1px;\n    }\n  }\n\n  &.show-tick .dropdown-menu li {\n    &.selected a span.check-mark {\n      position: absolute;\n      display: inline-block;\n      right: 15px;\n      margin-top: 5px;\n    }\n\n    a span.text {\n      margin-right: 34px;\n    }\n  }\n}\n\n.bootstrap-select.show-menu-arrow {\n  &.open > .dropdown-toggle {\n    z-index: (@zindex-select-dropdown + 1);\n  }\n\n  .dropdown-toggle {\n    &:before {\n      content: '';\n      border-left: 7px solid transparent;\n      border-right: 7px solid transparent;\n      border-bottom: 7px solid @color-grey-arrow;\n      position: absolute;\n      bottom: -4px;\n      left: 9px;\n      display: none;\n    }\n\n    &:after {\n      content: '';\n      border-left: 6px solid transparent;\n      border-right: 6px solid transparent;\n      border-bottom: 6px solid white;\n      position: absolute;\n      bottom: -4px;\n      left: 10px;\n      display: none;\n    }\n  }\n\n  &.dropup .dropdown-toggle {\n    &:before {\n      bottom: auto;\n      top: -3px;\n      border-top: 7px solid @color-grey-arrow;\n      border-bottom: 0;\n    }\n\n    &:after {\n      bottom: auto;\n      top: -3px;\n      border-top: 6px solid white;\n      border-bottom: 0;\n    }\n  }\n\n  &.pull-right .dropdown-toggle {\n    &:before {\n      right: 12px;\n      left: auto;\n    }\n\n    &:after {\n      right: 13px;\n      left: auto;\n    }\n  }\n\n  &.open > .dropdown-toggle {\n    &:before,\n    &:after {\n      display: block;\n    }\n  }\n}\n\n.bs-searchbox,\n.bs-actionsbox,\n.bs-donebutton {\n  padding: 4px 8px;\n}\n\n.bs-actionsbox {\n  width: 100%;\n  box-sizing: border-box;\n\n  & .btn-group button {\n    width: 50%;\n  }\n}\n\n.bs-donebutton {\n  float: left;\n  width: 100%;\n  box-sizing: border-box;\n\n  & .btn-group button {\n    width: 100%;\n  }\n}\n\n.bs-searchbox {\n  & + .bs-actionsbox {\n    padding: 0 8px 4px;\n  }\n\n  & .form-control {\n    margin-bottom: 0;\n    width: 100%;\n    float: none;\n  }\n}\n"
  },
  {
    "path": "app_frontend/static/plugin/bootstrap-select-1.12.2/less/variables.less",
    "content": "@color-red-error: rgb(185, 74, 72);\n@color-grey-arrow: rgba(204, 204, 204, 0.2);\n\n@width-default: 220px; // 3 960px-grid columns\n\n@zindex-select-dropdown: 1060; // must be higher than a modal background (1050)\n\n//** Placeholder text color\n@input-color-placeholder: #999;"
  },
  {
    "path": "app_frontend/static/plugin/bootstrap-select-1.12.2/nuget/MyGet.ps1",
    "content": "# set env vars usually set by MyGet (enable for local testing)\n#$env:SourcesPath = '..'\n#$env:NuGet = \"./nuget.exe\" #https://dist.nuget.org/win-x86-commandline/latest/nuget.exe\n\n$nuget = $env:NuGet\n\n# parse the version number out of package.json\n$bsversionParts = ((Get-Content $env:SourcesPath\\package.json) -join \"`n\" | ConvertFrom-Json).version.split('-', 2) # split the version on the '-'\n$bsversion = $bsversionParts[0]\n\nif ($bsversionParts.Length -gt 1)\n{\n    $bsversion += '-' + $bsversionParts[1].replace('.', '').replace('-', '_')   # strip out invalid chars from the PreRelease part\n}\n\n# update sourceMappingURL in bootstrap-select.min.js\n(Get-Content $env:SourcesPath\\dist\\js\\bootstrap-select.min.js).replace(\"sourceMappingURL=\", \"sourceMappingURL=Scripts/\") | Set-Content $env:SourcesPath\\dist\\js\\bootstrap-select.min.js\n\n# create packages\n& $nuget pack \"$env:SourcesPath\\nuget\\bootstrap-select.nuspec\" -Verbosity detailed -NonInteractive -NoPackageAnalysis -BasePath $env:SourcesPath -Version $bsversion"
  },
  {
    "path": "app_frontend/static/plugin/bootstrap-select-1.12.2/nuget/bootstrap-select.nuspec",
    "content": "<?xml version=\"1.0\"?>\n<package xmlns=\"http://schemas.microsoft.com/packaging/2012/06/nuspec.xsd\">\n    <metadata>\n        <id>bootstrap-select</id>\n        <version>1.12.2</version>\n        <title>bootstrap-select</title>\n        <authors>Silvio Moreto,Ana Carolina,caseyjhol,Matt Bryson,and t0xicCode.</authors>\n        <owners>Silvio Moreto</owners>\n        <projectUrl>https://github.com/silviomoreto/bootstrap-select</projectUrl>\n        <description>Bootstrap-select is a jQuery plugin that utilizes Bootstrap's dropdown.js to style and bring additional functionality to standard select elements.</description>\n        <tags>bootstrap dropdown select</tags>\n        <requireLicenseAcceptance>false</requireLicenseAcceptance>\n        <dependencies>\n            <dependency id=\"jQuery\" version=\"1.8.0\" />\n        </dependencies>\n    </metadata>\n    <files>\n        <file src=\"dist\\js\\bootstrap-select*.*\" target=\"content\\Scripts\" />\n        <file src=\"dist\\js\\i18n\\*.*\" target=\"content\\Scripts\\i18n\" />\n        <file src=\"dist\\css\\*.*\" target=\"content\\Content\" />\n    </files>\n</package>"
  },
  {
    "path": "app_frontend/static/plugin/bootstrap-select-1.12.2/package.json",
    "content": "{\n  \"name\": \"bootstrap-select\",\n  \"title\": \"bootstrap-select\",\n  \"main\": \"dist/js/bootstrap-select.js\",\n  \"description\": \"Bootstrap-select is a jQuery plugin that utilizes Bootstrap's dropdown.js to style and bring additional functionality to standard select elements.\",\n  \"version\": \"1.12.2\",\n  \"homepage\": \"http://silviomoreto.github.io/bootstrap-select\",\n  \"author\": {\n    \"name\": \"Silvio Moreto\",\n    \"url\": \"https://github.com/silviomoreto\"\n  },\n  \"contributors\": [\n    {\n      \"name\": \"Silvio Moreto\",\n      \"url\": \"https://github.com/silviomoreto\"\n    },\n    {\n      \"name\": \"Ana Carolina\",\n      \"url\": \"https://github.com/anacarolinats\"\n    },\n    {\n      \"name\": \"caseyjhol\",\n      \"url\": \"https://github.com/caseyjhol\"\n    },\n    {\n      \"name\": \"Matt Bryson\",\n      \"url\": \"https://github.com/mattbryson\"\n    },\n    {\n      \"name\": \"t0xicCode\",\n      \"url\": \"https://github.com/t0xicCode\"\n    }\n  ],\n  \"repository\": {\n    \"type\": \"git\",\n    \"url\": \"git://github.com/silviomoreto/bootstrap-select.git\"\n  },\n  \"license\": \"MIT\",\n  \"dependencies\": {\n    \"jquery\": \">=1.8\"\n  },\n  \"devDependencies\": {\n    \"grunt\": \"^1.0.1\",\n    \"grunt-autoprefixer\": \"^3.0.4\",\n    \"grunt-banner\": \"^0.6.0\",\n    \"grunt-contrib-clean\": \"^1.0.0\",\n    \"grunt-contrib-compress\": \"^1.3.0\",\n    \"grunt-contrib-concat\": \"^1.0.1\",\n    \"grunt-contrib-copy\": \"^1.0.0\",\n    \"grunt-contrib-csslint\": \"^2.0.0\",\n    \"grunt-contrib-cssmin\": \"^1.0.2\",\n    \"grunt-contrib-jshint\": \"^1.0.0\",\n    \"grunt-contrib-less\": \"^1.4.0\",\n    \"grunt-contrib-uglify\": \"^2.0.0\",\n    \"grunt-contrib-watch\": \"^1.0.0\",\n    \"grunt-umd\": \"^2.3.6\",\n    \"grunt-version\": \"^1.1.1\",\n    \"load-grunt-tasks\": \"^3.5.2\"\n  },\n  \"keywords\": [\n    \"form\",\n    \"bootstrap\",\n    \"select\",\n    \"replacement\"\n  ]\n}\n"
  },
  {
    "path": "app_frontend/static/plugin/bootstrap-select-1.12.2/sass/bootstrap-select.scss",
    "content": "@import \"variables\";\n\n// Mixins\n@mixin cursor-disabled() {\n  cursor: not-allowed;\n}\n\n@mixin box-sizing($fmt) {\n  -webkit-box-sizing: $fmt;\n     -moz-box-sizing: $fmt;\n          box-sizing: $fmt;\n}\n\n@mixin box-shadow($fmt) {\n  -webkit-box-shadow: $fmt;\n          box-shadow: $fmt;\n}\n\n@function fade($color, $amnt) {\n  @if $amnt > 1 {\n    $amnt: $amnt / 100; // convert to percentage if int\n  }\n  @return rgba($color, $amnt);\n}\n\n// Rules\nselect.bs-select-hidden,\nselect.selectpicker {\n  display: none !important;\n}\n\n.bootstrap-select {\n  width: 220px \\0; /*IE9 and below*/\n\n  // The selectpicker button\n  > .dropdown-toggle {\n    width: 100%;\n    padding-right: 25px;\n    z-index: 1;\n\n    &.bs-placeholder,\n    &.bs-placeholder:hover,\n    &.bs-placeholder:focus,\n    &.bs-placeholder:active { color: $input-color-placeholder; }\n  }\n\n  > select {\n    position: absolute !important;\n    bottom: 0;\n    left: 50%;\n    display: block !important;\n    width: 0.5px !important;\n    height: 100% !important;\n    padding: 0 !important;\n    opacity: 0 !important;\n    border: none;\n\n    &.mobile-device {\n      top: 0;\n      left: 0;\n      display: block !important;\n      width: 100% !important;\n      z-index: 2;\n    }\n  }\n\n  // Error display\n  .has-error & .dropdown-toggle,\n  .error & .dropdown-toggle {\n    border-color: $color-red-error;\n  }\n\n  &.fit-width {\n    width: auto !important;\n  }\n\n  &:not([class*=\"col-\"]):not([class*=\"form-control\"]):not(.input-group-btn) {\n    width: $width-default;\n  }\n\n  .dropdown-toggle:focus {\n    outline: thin dotted #333333 !important;\n    outline: 5px auto -webkit-focus-ring-color !important;\n    outline-offset: -2px;\n  }\n}\n\n.bootstrap-select.form-control {\n  margin-bottom: 0;\n  padding: 0;\n  border: none;\n\n  &:not([class*=\"col-\"]) {\n    width: 100%;\n  }\n\n  &.input-group-btn {\n    z-index: auto;\n\n    &:not(:first-child):not(:last-child) {\n      > .btn {\n        border-radius: 0;\n      }\n    }\n  }\n}\n\n// The selectpicker components\n.bootstrap-select.btn-group {\n  &:not(.input-group-btn),\n  &[class*=\"col-\"] {\n    float: none;\n    display: inline-block;\n    margin-left: 0;\n  }\n\n  // Forces the pull to the right, if necessary\n  &,\n  &[class*=\"col-\"],\n  .row &[class*=\"col-\"] {\n    &.dropdown-menu-right {\n      float: right;\n    }\n  }\n\n  .form-inline &,\n  .form-horizontal &,\n  .form-group & {\n    margin-bottom: 0;\n  }\n\n  .form-group-lg &.form-control,\n  .form-group-sm &.form-control {\n    padding: 0;\n\n    .dropdown-toggle {\n      height: 100%;\n      font-size: inherit;\n      line-height: inherit;\n      border-radius: inherit;\n    }\n  }\n\n  // Set the width of the live search (and any other form control within an inline form)\n  // see https://github.com/silviomoreto/bootstrap-select/issues/685\n  .form-inline & .form-control {\n    width: 100%;\n  }\n\n  &.disabled,\n  > .disabled {\n    @include cursor-disabled();\n\n    &:focus {\n      outline: none !important;\n    }\n  }\n\n  &.bs-container {\n    position: absolute;\n    height: 0 !important;\n    padding: 0 !important;\n\n    .dropdown-menu {\n      z-index: $zindex-select-dropdown;\n    }\n  }\n\n  // The selectpicker button\n  .dropdown-toggle {\n    .filter-option {\n      display: inline-block;\n      overflow: hidden;\n      width: 100%;\n      text-align: left;\n    }\n\n    .caret {\n      position: absolute;\n      top: 50%;\n      right: 12px;\n      margin-top: -2px;\n      vertical-align: middle;\n    }\n  }\n\n  &[class*=\"col-\"] .dropdown-toggle {\n    width: 100%;\n  }\n\n  // The selectpicker dropdown\n  .dropdown-menu {\n    min-width: 100%;\n    @include box-sizing(border-box);\n\n    &.inner {\n      position: static;\n      float: none;\n      border: 0;\n      padding: 0;\n      margin: 0;\n      border-radius: 0;\n      box-shadow: none;\n    }\n\n    li {\n      position: relative;\n\n      &.active small {\n        color: #fff;\n      }\n\n      &.disabled a {\n        @include cursor-disabled();\n      }\n\n      a {\n        cursor: pointer;\n        user-select: none;\n\n        &.opt {\n          position: relative;\n          padding-left: 2.25em;\n        }\n\n        span.check-mark {\n          display: none;\n        }\n\n        span.text {\n          display: inline-block;\n        }\n      }\n\n      small {\n        padding-left: 0.5em;\n      }\n    }\n\n    .notify {\n      position: absolute;\n      bottom: 5px;\n      width: 96%;\n      margin: 0 2%;\n      min-height: 26px;\n      padding: 3px 5px;\n      background: rgb(245, 245, 245);\n      border: 1px solid rgb(227, 227, 227);\n      @include box-shadow(inset 0 1px 1px fade(rgb(0, 0, 0), 5));\n      pointer-events: none;\n      opacity: 0.9;\n      @include box-sizing(border-box);\n    }\n  }\n\n  .no-results {\n    padding: 3px;\n    background: #f5f5f5;\n    margin: 0 5px;\n    white-space: nowrap;\n  }\n\n  &.fit-width .dropdown-toggle {\n    .filter-option {\n      position: static;\n    }\n\n    .caret {\n      position: static;\n      top: auto;\n      margin-top: -1px;\n    }\n  }\n\n  &.show-tick .dropdown-menu li {\n    &.selected a span.check-mark {\n      position: absolute;\n      display: inline-block;\n      right: 15px;\n      margin-top: 5px;\n    }\n\n    a span.text {\n      margin-right: 34px;\n    }\n  }\n}\n\n.bootstrap-select.show-menu-arrow {\n  &.open > .dropdown-toggle {\n    z-index: ($zindex-select-dropdown + 1);\n  }\n\n  .dropdown-toggle {\n    &:before {\n      content: '';\n      border-left: 7px solid transparent;\n      border-right: 7px solid transparent;\n      border-bottom: 7px solid $color-grey-arrow;\n      position: absolute;\n      bottom: -4px;\n      left: 9px;\n      display: none;\n    }\n\n    &:after {\n      content: '';\n      border-left: 6px solid transparent;\n      border-right: 6px solid transparent;\n      border-bottom: 6px solid white;\n      position: absolute;\n      bottom: -4px;\n      left: 10px;\n      display: none;\n    }\n  }\n\n  &.dropup .dropdown-toggle {\n    &:before {\n      bottom: auto;\n      top: -3px;\n      border-top: 7px solid $color-grey-arrow;\n      border-bottom: 0;\n    }\n\n    &:after {\n      bottom: auto;\n      top: -3px;\n      border-top: 6px solid white;\n      border-bottom: 0;\n    }\n  }\n\n  &.pull-right .dropdown-toggle {\n    &:before {\n      right: 12px;\n      left: auto;\n    }\n\n    &:after {\n      right: 13px;\n      left: auto;\n    }\n  }\n\n  &.open > .dropdown-toggle {\n    &:before,\n    &:after {\n      display: block;\n    }\n  }\n}\n\n.bs-searchbox,\n.bs-actionsbox,\n.bs-donebutton {\n  padding: 4px 8px;\n}\n\n.bs-actionsbox {\n  width: 100%;\n  @include box-sizing(border-box);\n\n  & .btn-group button {\n    width: 50%;\n  }\n}\n\n.bs-donebutton {\n  float: left;\n  width: 100%;\n  @include box-sizing(border-box);\n\n  & .btn-group button {\n    width: 100%;\n  }\n}\n\n.bs-searchbox {\n  & + .bs-actionsbox {\n    padding: 0 8px 4px;\n  }\n\n  & .form-control {\n    margin-bottom: 0;\n    width: 100%;\n    float: none;\n  }\n}\n"
  },
  {
    "path": "app_frontend/static/plugin/bootstrap-select-1.12.2/sass/variables.scss",
    "content": "$color-red-error: rgb(185, 74, 72) !default;\n$color-grey-arrow: rgba(204, 204, 204, 0.2) !default;\n\n$width-default: 220px !default; // 3 960px-grid columns\n\n$zindex-select-dropdown: 1060 !default; // must be higher than a modal background (1050)\n\n//** Placeholder text color\n$input-color-placeholder: #999 !default;"
  },
  {
    "path": "app_frontend/static/plugin/bootstrap-select-1.12.2/test.html",
    "content": "<!DOCTYPE html>\n<html>\n<head>\n  <title>Bootstrap-select test page</title>\n\n  <meta charset=\"utf-8\">\n\n  <link rel=\"stylesheet\" href=\"https://maxcdn.bootstrapcdn.com/bootstrap/3.3.4/css/bootstrap.min.css\">\n  <link rel=\"stylesheet\" href=\"dist/css/bootstrap-select.css\">\n\n  <style>\n    body {\n      padding-top: 70px;\n    }\n  </style>\n\n  <script src=\"https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js\"></script>\n  <script src=\"https://maxcdn.bootstrapcdn.com/bootstrap/3.3.4/js/bootstrap.min.js\"></script>\n  <script src=\"dist/js/bootstrap-select.js\"></script>\n</head>\n<body>\n<nav class=\"navbar navbar-default navbar-fixed-top\" role=\"navigation\">\n  <div class=\"container\">\n    <div class=\"navbar-header\">\n      <a class=\"navbar-brand\" href=\"#\">Bootstrap-select usability tests</a>\n    </div>\n  </div>\n</nav>\n\n<div class=\"container\">\n  <form class=\"form-horizontal\" role=\"form\">\n    <div class=\"form-group\">\n      <label for=\"basic\" class=\"col-lg-2 control-label\">\"Basic\" (liveSearch disabled)</label>\n\n      <div class=\"col-lg-10\">\n        <select id=\"basic\" class=\"selectpicker show-tick form-control\">\n          <option>cow</option>\n          <option data-subtext=\"option subtext\">bull</option>\n          <option class=\"get-class\" disabled>ox</option>\n          <optgroup label=\"test\" data-subtext=\"optgroup subtext\">\n            <option>ASD</option>\n            <option selected>Bla</option>\n            <option>Ble</option>\n          </optgroup>\n        </select>\n      </div>\n    </div>\n  </form>\n\n  <hr>\n\n  <form class=\"form-horizontal\" role=\"form\">\n    <div class=\"form-group\">\n      <label for=\"basic\" class=\"col-lg-2 control-label\">\"Basic\" (liveSearch enabled)</label>\n\n      <div class=\"col-lg-10\">\n        <select id=\"basic\" class=\"selectpicker show-tick form-control\" data-live-search=\"true\">\n          <option>cow</option>\n          <option data-subtext=\"option subtext\">bull</option>\n          <option class=\"get-class\" disabled>ox</option>\n          <optgroup label=\"test\" data-subtext=\"optgroup subtext\">\n            <option>ASD</option>\n            <option selected>Bla</option>\n            <option>Ble</option>\n          </optgroup>\n        </select>\n      </div>\n    </div>\n  </form>\n\n  <hr>\n  <form class=\"form-horizontal\" role=\"form\">\n    <div class=\"form-group\">\n      <label for=\"basic2\" class=\"col-lg-2 control-label\">\"Basic\" (multiple, maxOptions=1)</label>\n\n      <div class=\"col-lg-10\">\n        <select id=\"basic2\" class=\"show-tick form-control\" multiple>\n          <option>cow</option>\n          <option>bull</option>\n          <option class=\"get-class\" disabled>ox</option>\n          <optgroup label=\"test\" data-subtext=\"another test\">\n            <option>ASD</option>\n            <option selected>Bla</option>\n            <option>Ble</option>\n          </optgroup>\n        </select>\n      </div>\n    </div>\n  </form>\n\n  <hr>\n  <form class=\"form-horizontal\" role=\"form\">\n    <div class=\"form-group\">\n      <label for=\"maxOption2\" class=\"col-lg-2 control-label\">multiple, show-menu-arrow, maxOptions=2</label>\n\n      <div class=\"col-lg-10\">\n        <select id=\"maxOption2\" class=\"selectpicker show-menu-arrow form-control\" multiple data-max-options=\"2\">\n          <option>chicken</option>\n          <option>turkey</option>\n          <option disabled>duck</option>\n          <option>goose</option>\n        </select>\n      </div>\n    </div>\n  </form>\n\n  <hr>\n  <form class=\"form-inline\">\n    <div class=\"form-group\">\n      <label class=\"col-md-1 control-label\" for=\"lunch\">Lunch:</label>\n    </div>\n    <div class=\"form-group\">\n      <select id=\"lunch\" class=\"selectpicker\" data-live-search=\"true\" title=\"Please select a lunch ...\">\n        <option>Hot Dog, Fries and a Soda</option>\n        <option>Burger, Shake and a Smile</option>\n        <option>Sugar, Spice and all things nice</option>\n        <option>Baby Back Ribs</option>\n        <option>A really really long option made to illustrate an issue with the live search in an inline form</option>\n      </select>\n    </div>\n  </form>\n\n  <hr>\n  <form class=\"form-horizontal\" role=\"form\">\n    <div class=\"form-group form-group-lg\">\n      <label for=\"error\" class=\"col-lg-2 control-label\">error</label>\n\n      <div class=\"col-lg-10 error\">\n        <select id=\"error\" class=\"selectpicker show-tick form-control\">\n          <option>pen</option>\n          <option>pencil</option>\n          <option selected>brush</option>\n        </select>\n      </div>\n    </div>\n  </form>\n\n  <hr>\n  <form class=\"form-horizontal\" role=\"form\">\n    <div class=\"form-group has-error form-group-lg\">\n      <label class=\"control-label col-lg-2\" for=\"country\">error type 2</label>\n\n      <div class=\"col-lg-10\">\n        <select id=\"country\" name=\"country\" class=\"form-control selectpicker\">\n          <option>Argentina</option>\n          <option>United State</option>\n          <option>Mexico</option>\n        </select>\n\n        <p class=\"help-block\">No service available in the selected country</p>\n      </div>\n    </div>\n  </form>\n\n  <hr>\n  <nav class=\"navbar navbar-default\" role=\"navigation\">\n    <div class=\"container-fluid\">\n      <div class=\"navbar-header\">\n        <a class=\"navbar-brand\" href=\"#\">Navbar</a>\n      </div>\n\n      <form class=\"navbar-form navbar-left\" role=\"search\">\n        <div class=\"form-group\">\n          <select class=\"selectpicker\" multiple data-live-search=\"true\" data-live-search-placeholder=\"Search\" data-actions-box=\"true\">\n            <optgroup label=\"filter1\">\n              <option>option1</option>\n              <option>option2</option>\n              <option>option3</option>\n              <option>option4</option>\n            </optgroup>\n            <optgroup label=\"filter2\">\n              <option>option1</option>\n              <option>option2</option>\n              <option>option3</option>\n              <option>option4</option>\n            </optgroup>\n            <optgroup label=\"filter3\">\n              <option>option1</option>\n              <option>option2</option>\n              <option>option3</option>\n              <option>option4</option>\n            </optgroup>\n          </select>\n        </div>\n\n        <div class=\"input-group\">\n          <input type=\"text\" class=\"form-control\" placeholder=\"Search\" name=\"q\">\n\n          <div class=\"input-group-btn\">\n            <button class=\"btn btn-default\" type=\"submit\"><i class=\"glyphicon glyphicon-search\"></i></button>\n          </div>\n        </div>\n        <button type=\"submit\" class=\"btn btn-default\">Search</button>\n      </form>\n\n    </div>\n    <!-- .container-fluid -->\n  </nav>\n\n  <hr>\n  <select id=\"first-disabled\" class=\"selectpicker\" data-hide-disabled=\"true\" data-live-search=\"true\">\n    <optgroup disabled=\"disabled\" label=\"disabled\">\n      <option>Hidden</option>\n    </optgroup>\n    <optgroup label=\"Fruit\">\n      <option>Apple</option>\n      <option>Orange</option>\n    </optgroup>\n    <optgroup label=\"Vegetable\">\n      <option>Corn</option>\n      <option>Carrot</option>\n    </optgroup>\n  </select>\n\n  <hr>\n  <select id=\"first-disabled2\" class=\"selectpicker\" multiple data-hide-disabled=\"true\" data-size=\"5\">\n    <option>Apple</option>\n    <option>Banana</option>\n    <option>Orange</option>\n    <option>Pineapple</option>\n    <option>Apple2</option>\n    <option>Banana2</option>\n    <option>Orange2</option>\n    <option>Pineapple2</option>\n    <option>Apple2</option>\n    <option>Banana2</option>\n    <option>Orange2</option>\n    <option>Pineapple2</option>\n  </select>\n  <button id=\"special\" class=\"btn btn-default\">Hide selected by disabling</button>\n  <button id=\"special2\" class=\"btn btn-default\">Reset</button>\n  <p>Just select 1st element, click button and check list again</p>\n\n  <hr>\n  <div class=\"input-group\">\n    <span class=\"input-group-addon\">@</span>\n    <select class=\"form-control selectpicker\">\n      <option>One</option>\n      <option>Two</option>\n      <option>Three</option>\n    </select>\n  </div>\n\n  <hr>\n  <div class=\"input-group\">\n    <span class=\"input-group-addon\">@</span>\n    <select class=\"form-control selectpicker\" data-mobile=\"true\">\n      <option>One</option>\n      <option>Two</option>\n      <option>Three</option>\n    </select>\n  </div>\n  <p>With <code>data-mobile=\"true\"</code> option.</p>\n\n  <hr>\n  <select id=\"done\" class=\"selectpicker\" multiple data-done-button=\"true\">\n    <option>Apple</option>\n    <option>Banana</option>\n    <option>Orange</option>\n    <option>Pineapple</option>\n    <option>Apple2</option>\n    <option>Banana2</option>\n    <option>Orange2</option>\n    <option>Pineapple2</option>\n    <option>Apple2</option>\n    <option>Banana2</option>\n    <option>Orange2</option>\n    <option>Pineapple2</option>\n  </select>\n\n  <hr>\n\n  <div class=\"form-group\">\n    <label for=\"tokens\">Key words (data-tokens)</label>\n    <select id=\"tokens\" class=\"selectpicker form-control\" multiple data-live-search=\"true\">\n      <option data-tokens=\"first\">I actually am called \"one\"</option>\n      <option data-tokens=\"second\">And me \"two\"</option>\n      <option data-tokens=\"last\">I am \"three\"</option>\n    </select>\n  </div>\n\n  <hr>\n  <form class=\"form-inline\">\n    <div class=\"form-group\">\n      <label class=\"col-md-1 control-label\" for=\"lunchBegins\">Lunch (Begins search):</label>\n    </div>\n    <div class=\"form-group\">\n      <select id=\"lunchBegins\" class=\"selectpicker\" data-live-search=\"true\" data-live-search-style=\"begins\" title=\"Please select a lunch ...\">\n        <option>Hot Dog, Fries and a Soda</option>\n        <option>Burger, Shake and a Smile</option>\n        <option>Sugar, Spice and all things nice</option>\n        <option>Baby Back Ribs</option>\n        <option>A really really long option made to illustrate an issue with the live search in an inline form</option>\n      </select>\n    </div>\n  </form>\n</div>\n\n<script>\n  $(document).ready(function () {\n    var mySelect = $('#first-disabled2');\n\n    $('#special').on('click', function () {\n      mySelect.find('option:selected').prop('disabled', true);\n      mySelect.selectpicker('refresh');\n    });\n\n    $('#special2').on('click', function () {\n      mySelect.find('option:disabled').prop('disabled', false);\n      mySelect.selectpicker('refresh');\n    });\n\n    $('#basic2').selectpicker({\n      liveSearch: true,\n      maxOptions: 1\n    });\n  });\n</script>\n</body>\n</html>\n"
  },
  {
    "path": "app_frontend/static/plugin/clipboard.js-1.6.1/.babelrc",
    "content": "{\n  \"presets\": [\"es2015\"],\n  \"plugins\": [\"transform-es2015-modules-umd\"]\n}\n"
  },
  {
    "path": "app_frontend/static/plugin/clipboard.js-1.6.1/.banner",
    "content": "/*!\n * clipboard.js v<%= pkg.version %>\n * https://zenorocha.github.io/clipboard.js\n *\n * Licensed MIT © Zeno Rocha\n */\n"
  },
  {
    "path": "app_frontend/static/plugin/clipboard.js-1.6.1/.editorconfig",
    "content": "# EditorConfig helps developers define and maintain consistent\n# coding styles between different editors and IDEs\n# http://editorconfig.org\n\nroot = true\n\n[*]\n# Change these settings to your own preference\nindent_style = space\nindent_size = 4\n\n# We recommend you to keep these unchanged\nend_of_line = lf\ncharset = utf-8\ntrim_trailing_whitespace = true\ninsert_final_newline = true\n\n[*.md]\ntrim_trailing_whitespace = false\n\n[{package.json,bower.json}]\nindent_size = 2\n"
  },
  {
    "path": "app_frontend/static/plugin/clipboard.js-1.6.1/.github/issue_template.md",
    "content": "### Minimal example\n\n> Fork this [JSFiddle](https://jsfiddle.net/zenorocha/5kk0eysw/) and reproduce your issue.\n\n### Expected behaviour\n\nI thought that by going to the page '...' and pressing the button '...' then '...' would happen.\n\n### Actual behaviour\n\nInstead of '...', what I saw was that '...' happened instead.\n\n### Browsers affected\n\nI tested on all major browsers and only IE 11 does not work.\n"
  },
  {
    "path": "app_frontend/static/plugin/clipboard.js-1.6.1/.gitignore",
    "content": "lib\nnpm-debug.log\nbower_components\nnode_modules\n"
  },
  {
    "path": "app_frontend/static/plugin/clipboard.js-1.6.1/.npmignore",
    "content": "/.*/\n/demo/\n/test/\n/.*\n/bower.json\n/karma.conf.js\n/src\n"
  },
  {
    "path": "app_frontend/static/plugin/clipboard.js-1.6.1/.travis.yml",
    "content": "sudo: false\nlanguage: node_js\nnode_js:\n  - stable\n"
  },
  {
    "path": "app_frontend/static/plugin/clipboard.js-1.6.1/bower.json",
    "content": "{\n  \"name\": \"clipboard\",\n  \"version\": \"1.6.1\",\n  \"description\": \"Modern copy to clipboard. No Flash. Just 2kb\",\n  \"license\": \"MIT\",\n  \"main\": \"dist/clipboard.js\",\n  \"ignore\": [\n    \"/.*/\",\n    \"/demo/\",\n    \"/test/\",\n    \"/.*\",\n    \"/bower.json\",\n    \"/karma.conf.js\",\n    \"/src\",\n    \"/lib\"\n  ],\n  \"keywords\": [\n    \"clipboard\",\n    \"copy\",\n    \"cut\"\n  ]\n}\n"
  },
  {
    "path": "app_frontend/static/plugin/clipboard.js-1.6.1/contributing.md",
    "content": "# Contributing guide\n\nWant to contribute to Clipboard.js? Awesome!\nThere are many ways you can contribute, see below.\n\n## Opening issues\n\nOpen an issue to report bugs or to propose new features.\n\n- Reporting bugs: describe the bug as clearly as you can, including steps to reproduce, what happened and what you were expecting to happen. Also include browser version, OS and other related software's (npm, Node.js, etc) versions when applicable.\n\n- Proposing features: explain the proposed feature, what it should do, why it is useful, how users should use it. Give us as much info as possible so it will be easier to discuss, access and implement the proposed feature. When you're unsure about a certain aspect of the feature, feel free to leave it open for others to discuss and find an appropriate solution.\n\n## Proposing pull requests\n\nPull requests are very welcome. Note that if you are going to propose drastic changes, be sure to open an issue for discussion first, to make sure that your PR will be accepted before you spend effort coding it.\n\nFork the Clipboard.js repository, clone it locally and create a branch for your proposed bug fix or new feature. Avoid working directly on the master branch.\n\nImplement your bug fix or feature, write tests to cover it and make sure all tests are passing (run a final `npm test` to make sure everything is correct). Then commit your changes, push your bug fix/feature branch to the origin (your forked repo) and open a pull request to the upstream (the repository you originally forked)'s master branch.\n\n## Documentation\n\nDocumentation is extremely important and takes a fair deal of time and effort to write and keep updated. Please submit any and all improvements you can make to the repository's docs.\n\n## Known issues\nIf you're using npm@3 you'll probably face some issues related to peerDependencies.\nhttps://github.com/npm/npm/issues/9204\n"
  },
  {
    "path": "app_frontend/static/plugin/clipboard.js-1.6.1/demo/constructor-node.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n    <meta charset=\"UTF-8\">\n    <title>constructor-node</title>\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">\n</head>\n<body>\n    <!-- 1. Define some markup -->\n    <div id=\"btn\" data-clipboard-text=\"1\">\n        <span>Copy</span>\n    </div>\n\n    <!-- 2. Include library -->\n    <script src=\"../dist/clipboard.min.js\"></script>\n\n    <!-- 3. Instantiate clipboard by passing a HTML element -->\n    <script>\n    var btn = document.getElementById('btn');\n    var clipboard = new Clipboard(btn);\n\n    clipboard.on('success', function(e) {\n        console.log(e);\n    });\n\n    clipboard.on('error', function(e) {\n        console.log(e);\n    });\n    </script>\n</body>\n</html>\n"
  },
  {
    "path": "app_frontend/static/plugin/clipboard.js-1.6.1/demo/constructor-nodelist.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n    <meta charset=\"UTF-8\">\n    <title>constructor-nodelist</title>\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">\n</head>\n<body>\n    <!-- 1. Define some markup -->\n    <button data-clipboard-text=\"1\">Copy</button>\n    <button data-clipboard-text=\"2\">Copy</button>\n    <button data-clipboard-text=\"3\">Copy</button>\n\n    <!-- 2. Include library -->\n    <script src=\"../dist/clipboard.min.js\"></script>\n\n    <!-- 3. Instantiate clipboard by passing a list of HTML elements -->\n    <script>\n    var btns = document.querySelectorAll('button');\n    var clipboard = new Clipboard(btns);\n\n    clipboard.on('success', function(e) {\n        console.log(e);\n    });\n\n    clipboard.on('error', function(e) {\n        console.log(e);\n    });\n    </script>\n</body>\n</html>\n"
  },
  {
    "path": "app_frontend/static/plugin/clipboard.js-1.6.1/demo/constructor-selector.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n    <meta charset=\"UTF-8\">\n    <title>constructor-selector</title>\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">\n</head>\n<body>\n    <!-- 1. Define some markup -->\n    <button class=\"btn\" data-clipboard-text=\"1\">Copy</button>\n    <button class=\"btn\" data-clipboard-text=\"2\">Copy</button>\n    <button class=\"btn\" data-clipboard-text=\"3\">Copy</button>\n\n    <!-- 2. Include library -->\n    <script src=\"../dist/clipboard.min.js\"></script>\n\n    <!-- 3. Instantiate clipboard by passing a string selector -->\n    <script>\n    var clipboard = new Clipboard('.btn');\n\n    clipboard.on('success', function(e) {\n        console.log(e);\n    });\n\n    clipboard.on('error', function(e) {\n        console.log(e);\n    });\n    </script>\n</body>\n</html>\n"
  },
  {
    "path": "app_frontend/static/plugin/clipboard.js-1.6.1/demo/function-target.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n    <meta charset=\"UTF-8\">\n    <title>function-target</title>\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">\n</head>\n<body>\n    <!-- 1. Define some markup -->\n    <button class=\"btn\">Copy</button>\n    <div>hello</div>\n\n    <!-- 2. Include library -->\n    <script src=\"../dist/clipboard.min.js\"></script>\n\n    <!-- 3. Instantiate clipboard -->\n    <script>\n    var clipboard = new Clipboard('.btn', {\n        target: function() {\n            return document.querySelector('div');\n        }\n    });\n\n    clipboard.on('success', function(e) {\n        console.log(e);\n    });\n\n    clipboard.on('error', function(e) {\n        console.log(e);\n    });\n    </script>\n</body>\n</html>\n"
  },
  {
    "path": "app_frontend/static/plugin/clipboard.js-1.6.1/demo/function-text.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n    <meta charset=\"UTF-8\">\n    <title>function-text</title>\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">\n</head>\n<body>\n    <!-- 1. Define some markup -->\n    <button class=\"btn\">Copy</button>\n\n    <!-- 2. Include library -->\n    <script src=\"../dist/clipboard.min.js\"></script>\n\n    <!-- 3. Instantiate clipboard -->\n    <script>\n    var clipboard = new Clipboard('.btn', {\n        text: function() {\n            return 'to be or not to be';\n        }\n    });\n\n    clipboard.on('success', function(e) {\n        console.log(e);\n    });\n\n    clipboard.on('error', function(e) {\n        console.log(e);\n    });\n    </script>\n</body>\n</html>\n"
  },
  {
    "path": "app_frontend/static/plugin/clipboard.js-1.6.1/demo/target-div.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n    <meta charset=\"UTF-8\">\n    <title>target-div</title>\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">\n</head>\n<body>\n    <!-- 1. Define some markup -->\n    <div>hello</div>\n    <button class=\"btn\" data-clipboard-action=\"copy\" data-clipboard-target=\"div\">Copy</button>\n\n    <!-- 2. Include library -->\n    <script src=\"../dist/clipboard.min.js\"></script>\n\n    <!-- 3. Instantiate clipboard -->\n    <script>\n    var clipboard = new Clipboard('.btn');\n\n    clipboard.on('success', function(e) {\n        console.log(e);\n    });\n\n    clipboard.on('error', function(e) {\n        console.log(e);\n    });\n    </script>\n</body>\n</html>\n"
  },
  {
    "path": "app_frontend/static/plugin/clipboard.js-1.6.1/demo/target-input.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n    <meta charset=\"UTF-8\">\n    <title>target-input</title>\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">\n</head>\n<body>\n    <!-- 1. Define some markup -->\n    <input id=\"foo\" type=\"text\" value=\"hello\">\n    <button class=\"btn\" data-clipboard-action=\"copy\" data-clipboard-target=\"#foo\">Copy</button>\n\n    <!-- 2. Include library -->\n    <script src=\"../dist/clipboard.min.js\"></script>\n\n    <!-- 3. Instantiate clipboard -->\n    <script>\n    var clipboard = new Clipboard('.btn');\n\n    clipboard.on('success', function(e) {\n        console.log(e);\n    });\n\n    clipboard.on('error', function(e) {\n        console.log(e);\n    });\n    </script>\n</body>\n</html>\n"
  },
  {
    "path": "app_frontend/static/plugin/clipboard.js-1.6.1/demo/target-textarea.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n    <meta charset=\"UTF-8\">\n    <title>target-textarea</title>\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">\n</head>\n<body>\n    <!-- 1. Define some markup -->\n    <textarea id=\"bar\">hello</textarea>\n    <button class=\"btn\" data-clipboard-action=\"cut\" data-clipboard-target=\"#bar\">Cut</button>\n\n    <!-- 2. Include library -->\n    <script src=\"../dist/clipboard.min.js\"></script>\n\n    <!-- 3. Instantiate clipboard -->\n    <script>\n    var clipboard = new Clipboard('.btn');\n\n    clipboard.on('success', function(e) {\n        console.log(e);\n    });\n\n    clipboard.on('error', function(e) {\n        console.log(e);\n    });\n    </script>\n</body>\n</html>\n"
  },
  {
    "path": "app_frontend/static/plugin/clipboard.js-1.6.1/dist/clipboard.js",
    "content": "/*!\n * clipboard.js v1.6.1\n * https://zenorocha.github.io/clipboard.js\n *\n * Licensed MIT © Zeno Rocha\n */\n(function(f){if(typeof exports===\"object\"&&typeof module!==\"undefined\"){module.exports=f()}else if(typeof define===\"function\"&&define.amd){define([],f)}else{var g;if(typeof window!==\"undefined\"){g=window}else if(typeof global!==\"undefined\"){g=global}else if(typeof self!==\"undefined\"){g=self}else{g=this}g.Clipboard = f()}})(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require==\"function\"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error(\"Cannot find module '\"+o+\"'\");throw f.code=\"MODULE_NOT_FOUND\",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require==\"function\"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){\nvar DOCUMENT_NODE_TYPE = 9;\n\n/**\n * A polyfill for Element.matches()\n */\nif (typeof Element !== 'undefined' && !Element.prototype.matches) {\n    var proto = Element.prototype;\n\n    proto.matches = proto.matchesSelector ||\n                    proto.mozMatchesSelector ||\n                    proto.msMatchesSelector ||\n                    proto.oMatchesSelector ||\n                    proto.webkitMatchesSelector;\n}\n\n/**\n * Finds the closest parent that matches a selector.\n *\n * @param {Element} element\n * @param {String} selector\n * @return {Function}\n */\nfunction closest (element, selector) {\n    while (element && element.nodeType !== DOCUMENT_NODE_TYPE) {\n        if (element.matches(selector)) return element;\n        element = element.parentNode;\n    }\n}\n\nmodule.exports = closest;\n\n},{}],2:[function(require,module,exports){\nvar closest = require('./closest');\n\n/**\n * Delegates event to a selector.\n *\n * @param {Element} element\n * @param {String} selector\n * @param {String} type\n * @param {Function} callback\n * @param {Boolean} useCapture\n * @return {Object}\n */\nfunction delegate(element, selector, type, callback, useCapture) {\n    var listenerFn = listener.apply(this, arguments);\n\n    element.addEventListener(type, listenerFn, useCapture);\n\n    return {\n        destroy: function() {\n            element.removeEventListener(type, listenerFn, useCapture);\n        }\n    }\n}\n\n/**\n * Finds closest match and invokes callback.\n *\n * @param {Element} element\n * @param {String} selector\n * @param {String} type\n * @param {Function} callback\n * @return {Function}\n */\nfunction listener(element, selector, type, callback) {\n    return function(e) {\n        e.delegateTarget = closest(e.target, selector);\n\n        if (e.delegateTarget) {\n            callback.call(element, e);\n        }\n    }\n}\n\nmodule.exports = delegate;\n\n},{\"./closest\":1}],3:[function(require,module,exports){\n/**\n * Check if argument is a HTML element.\n *\n * @param {Object} value\n * @return {Boolean}\n */\nexports.node = function(value) {\n    return value !== undefined\n        && value instanceof HTMLElement\n        && value.nodeType === 1;\n};\n\n/**\n * Check if argument is a list of HTML elements.\n *\n * @param {Object} value\n * @return {Boolean}\n */\nexports.nodeList = function(value) {\n    var type = Object.prototype.toString.call(value);\n\n    return value !== undefined\n        && (type === '[object NodeList]' || type === '[object HTMLCollection]')\n        && ('length' in value)\n        && (value.length === 0 || exports.node(value[0]));\n};\n\n/**\n * Check if argument is a string.\n *\n * @param {Object} value\n * @return {Boolean}\n */\nexports.string = function(value) {\n    return typeof value === 'string'\n        || value instanceof String;\n};\n\n/**\n * Check if argument is a function.\n *\n * @param {Object} value\n * @return {Boolean}\n */\nexports.fn = function(value) {\n    var type = Object.prototype.toString.call(value);\n\n    return type === '[object Function]';\n};\n\n},{}],4:[function(require,module,exports){\nvar is = require('./is');\nvar delegate = require('delegate');\n\n/**\n * Validates all params and calls the right\n * listener function based on its target type.\n *\n * @param {String|HTMLElement|HTMLCollection|NodeList} target\n * @param {String} type\n * @param {Function} callback\n * @return {Object}\n */\nfunction listen(target, type, callback) {\n    if (!target && !type && !callback) {\n        throw new Error('Missing required arguments');\n    }\n\n    if (!is.string(type)) {\n        throw new TypeError('Second argument must be a String');\n    }\n\n    if (!is.fn(callback)) {\n        throw new TypeError('Third argument must be a Function');\n    }\n\n    if (is.node(target)) {\n        return listenNode(target, type, callback);\n    }\n    else if (is.nodeList(target)) {\n        return listenNodeList(target, type, callback);\n    }\n    else if (is.string(target)) {\n        return listenSelector(target, type, callback);\n    }\n    else {\n        throw new TypeError('First argument must be a String, HTMLElement, HTMLCollection, or NodeList');\n    }\n}\n\n/**\n * Adds an event listener to a HTML element\n * and returns a remove listener function.\n *\n * @param {HTMLElement} node\n * @param {String} type\n * @param {Function} callback\n * @return {Object}\n */\nfunction listenNode(node, type, callback) {\n    node.addEventListener(type, callback);\n\n    return {\n        destroy: function() {\n            node.removeEventListener(type, callback);\n        }\n    }\n}\n\n/**\n * Add an event listener to a list of HTML elements\n * and returns a remove listener function.\n *\n * @param {NodeList|HTMLCollection} nodeList\n * @param {String} type\n * @param {Function} callback\n * @return {Object}\n */\nfunction listenNodeList(nodeList, type, callback) {\n    Array.prototype.forEach.call(nodeList, function(node) {\n        node.addEventListener(type, callback);\n    });\n\n    return {\n        destroy: function() {\n            Array.prototype.forEach.call(nodeList, function(node) {\n                node.removeEventListener(type, callback);\n            });\n        }\n    }\n}\n\n/**\n * Add an event listener to a selector\n * and returns a remove listener function.\n *\n * @param {String} selector\n * @param {String} type\n * @param {Function} callback\n * @return {Object}\n */\nfunction listenSelector(selector, type, callback) {\n    return delegate(document.body, selector, type, callback);\n}\n\nmodule.exports = listen;\n\n},{\"./is\":3,\"delegate\":2}],5:[function(require,module,exports){\nfunction select(element) {\n    var selectedText;\n\n    if (element.nodeName === 'SELECT') {\n        element.focus();\n\n        selectedText = element.value;\n    }\n    else if (element.nodeName === 'INPUT' || element.nodeName === 'TEXTAREA') {\n        var isReadOnly = element.hasAttribute('readonly');\n\n        if (!isReadOnly) {\n            element.setAttribute('readonly', '');\n        }\n\n        element.select();\n        element.setSelectionRange(0, element.value.length);\n\n        if (!isReadOnly) {\n            element.removeAttribute('readonly');\n        }\n\n        selectedText = element.value;\n    }\n    else {\n        if (element.hasAttribute('contenteditable')) {\n            element.focus();\n        }\n\n        var selection = window.getSelection();\n        var range = document.createRange();\n\n        range.selectNodeContents(element);\n        selection.removeAllRanges();\n        selection.addRange(range);\n\n        selectedText = selection.toString();\n    }\n\n    return selectedText;\n}\n\nmodule.exports = select;\n\n},{}],6:[function(require,module,exports){\nfunction E () {\n  // Keep this empty so it's easier to inherit from\n  // (via https://github.com/lipsmack from https://github.com/scottcorgan/tiny-emitter/issues/3)\n}\n\nE.prototype = {\n  on: function (name, callback, ctx) {\n    var e = this.e || (this.e = {});\n\n    (e[name] || (e[name] = [])).push({\n      fn: callback,\n      ctx: ctx\n    });\n\n    return this;\n  },\n\n  once: function (name, callback, ctx) {\n    var self = this;\n    function listener () {\n      self.off(name, listener);\n      callback.apply(ctx, arguments);\n    };\n\n    listener._ = callback\n    return this.on(name, listener, ctx);\n  },\n\n  emit: function (name) {\n    var data = [].slice.call(arguments, 1);\n    var evtArr = ((this.e || (this.e = {}))[name] || []).slice();\n    var i = 0;\n    var len = evtArr.length;\n\n    for (i; i < len; i++) {\n      evtArr[i].fn.apply(evtArr[i].ctx, data);\n    }\n\n    return this;\n  },\n\n  off: function (name, callback) {\n    var e = this.e || (this.e = {});\n    var evts = e[name];\n    var liveEvents = [];\n\n    if (evts && callback) {\n      for (var i = 0, len = evts.length; i < len; i++) {\n        if (evts[i].fn !== callback && evts[i].fn._ !== callback)\n          liveEvents.push(evts[i]);\n      }\n    }\n\n    // Remove event from queue to prevent memory leak\n    // Suggested by https://github.com/lazd\n    // Ref: https://github.com/scottcorgan/tiny-emitter/commit/c6ebfaa9bc973b33d110a84a307742b7cf94c953#commitcomment-5024910\n\n    (liveEvents.length)\n      ? e[name] = liveEvents\n      : delete e[name];\n\n    return this;\n  }\n};\n\nmodule.exports = E;\n\n},{}],7:[function(require,module,exports){\n(function (global, factory) {\n    if (typeof define === \"function\" && define.amd) {\n        define(['module', 'select'], factory);\n    } else if (typeof exports !== \"undefined\") {\n        factory(module, require('select'));\n    } else {\n        var mod = {\n            exports: {}\n        };\n        factory(mod, global.select);\n        global.clipboardAction = mod.exports;\n    }\n})(this, function (module, _select) {\n    'use strict';\n\n    var _select2 = _interopRequireDefault(_select);\n\n    function _interopRequireDefault(obj) {\n        return obj && obj.__esModule ? obj : {\n            default: obj\n        };\n    }\n\n    var _typeof = typeof Symbol === \"function\" && typeof Symbol.iterator === \"symbol\" ? function (obj) {\n        return typeof obj;\n    } : function (obj) {\n        return obj && typeof Symbol === \"function\" && obj.constructor === Symbol && obj !== Symbol.prototype ? \"symbol\" : typeof obj;\n    };\n\n    function _classCallCheck(instance, Constructor) {\n        if (!(instance instanceof Constructor)) {\n            throw new TypeError(\"Cannot call a class as a function\");\n        }\n    }\n\n    var _createClass = function () {\n        function defineProperties(target, props) {\n            for (var i = 0; i < props.length; i++) {\n                var descriptor = props[i];\n                descriptor.enumerable = descriptor.enumerable || false;\n                descriptor.configurable = true;\n                if (\"value\" in descriptor) descriptor.writable = true;\n                Object.defineProperty(target, descriptor.key, descriptor);\n            }\n        }\n\n        return function (Constructor, protoProps, staticProps) {\n            if (protoProps) defineProperties(Constructor.prototype, protoProps);\n            if (staticProps) defineProperties(Constructor, staticProps);\n            return Constructor;\n        };\n    }();\n\n    var ClipboardAction = function () {\n        /**\n         * @param {Object} options\n         */\n        function ClipboardAction(options) {\n            _classCallCheck(this, ClipboardAction);\n\n            this.resolveOptions(options);\n            this.initSelection();\n        }\n\n        /**\n         * Defines base properties passed from constructor.\n         * @param {Object} options\n         */\n\n\n        _createClass(ClipboardAction, [{\n            key: 'resolveOptions',\n            value: function resolveOptions() {\n                var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};\n\n                this.action = options.action;\n                this.emitter = options.emitter;\n                this.target = options.target;\n                this.text = options.text;\n                this.trigger = options.trigger;\n\n                this.selectedText = '';\n            }\n        }, {\n            key: 'initSelection',\n            value: function initSelection() {\n                if (this.text) {\n                    this.selectFake();\n                } else if (this.target) {\n                    this.selectTarget();\n                }\n            }\n        }, {\n            key: 'selectFake',\n            value: function selectFake() {\n                var _this = this;\n\n                var isRTL = document.documentElement.getAttribute('dir') == 'rtl';\n\n                this.removeFake();\n\n                this.fakeHandlerCallback = function () {\n                    return _this.removeFake();\n                };\n                this.fakeHandler = document.body.addEventListener('click', this.fakeHandlerCallback) || true;\n\n                this.fakeElem = document.createElement('textarea');\n                // Prevent zooming on iOS\n                this.fakeElem.style.fontSize = '12pt';\n                // Reset box model\n                this.fakeElem.style.border = '0';\n                this.fakeElem.style.padding = '0';\n                this.fakeElem.style.margin = '0';\n                // Move element out of screen horizontally\n                this.fakeElem.style.position = 'absolute';\n                this.fakeElem.style[isRTL ? 'right' : 'left'] = '-9999px';\n                // Move element to the same position vertically\n                var yPosition = window.pageYOffset || document.documentElement.scrollTop;\n                this.fakeElem.style.top = yPosition + 'px';\n\n                this.fakeElem.setAttribute('readonly', '');\n                this.fakeElem.value = this.text;\n\n                document.body.appendChild(this.fakeElem);\n\n                this.selectedText = (0, _select2.default)(this.fakeElem);\n                this.copyText();\n            }\n        }, {\n            key: 'removeFake',\n            value: function removeFake() {\n                if (this.fakeHandler) {\n                    document.body.removeEventListener('click', this.fakeHandlerCallback);\n                    this.fakeHandler = null;\n                    this.fakeHandlerCallback = null;\n                }\n\n                if (this.fakeElem) {\n                    document.body.removeChild(this.fakeElem);\n                    this.fakeElem = null;\n                }\n            }\n        }, {\n            key: 'selectTarget',\n            value: function selectTarget() {\n                this.selectedText = (0, _select2.default)(this.target);\n                this.copyText();\n            }\n        }, {\n            key: 'copyText',\n            value: function copyText() {\n                var succeeded = void 0;\n\n                try {\n                    succeeded = document.execCommand(this.action);\n                } catch (err) {\n                    succeeded = false;\n                }\n\n                this.handleResult(succeeded);\n            }\n        }, {\n            key: 'handleResult',\n            value: function handleResult(succeeded) {\n                this.emitter.emit(succeeded ? 'success' : 'error', {\n                    action: this.action,\n                    text: this.selectedText,\n                    trigger: this.trigger,\n                    clearSelection: this.clearSelection.bind(this)\n                });\n            }\n        }, {\n            key: 'clearSelection',\n            value: function clearSelection() {\n                if (this.target) {\n                    this.target.blur();\n                }\n\n                window.getSelection().removeAllRanges();\n            }\n        }, {\n            key: 'destroy',\n            value: function destroy() {\n                this.removeFake();\n            }\n        }, {\n            key: 'action',\n            set: function set() {\n                var action = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 'copy';\n\n                this._action = action;\n\n                if (this._action !== 'copy' && this._action !== 'cut') {\n                    throw new Error('Invalid \"action\" value, use either \"copy\" or \"cut\"');\n                }\n            },\n            get: function get() {\n                return this._action;\n            }\n        }, {\n            key: 'target',\n            set: function set(target) {\n                if (target !== undefined) {\n                    if (target && (typeof target === 'undefined' ? 'undefined' : _typeof(target)) === 'object' && target.nodeType === 1) {\n                        if (this.action === 'copy' && target.hasAttribute('disabled')) {\n                            throw new Error('Invalid \"target\" attribute. Please use \"readonly\" instead of \"disabled\" attribute');\n                        }\n\n                        if (this.action === 'cut' && (target.hasAttribute('readonly') || target.hasAttribute('disabled'))) {\n                            throw new Error('Invalid \"target\" attribute. You can\\'t cut text from elements with \"readonly\" or \"disabled\" attributes');\n                        }\n\n                        this._target = target;\n                    } else {\n                        throw new Error('Invalid \"target\" value, use a valid Element');\n                    }\n                }\n            },\n            get: function get() {\n                return this._target;\n            }\n        }]);\n\n        return ClipboardAction;\n    }();\n\n    module.exports = ClipboardAction;\n});\n\n},{\"select\":5}],8:[function(require,module,exports){\n(function (global, factory) {\n    if (typeof define === \"function\" && define.amd) {\n        define(['module', './clipboard-action', 'tiny-emitter', 'good-listener'], factory);\n    } else if (typeof exports !== \"undefined\") {\n        factory(module, require('./clipboard-action'), require('tiny-emitter'), require('good-listener'));\n    } else {\n        var mod = {\n            exports: {}\n        };\n        factory(mod, global.clipboardAction, global.tinyEmitter, global.goodListener);\n        global.clipboard = mod.exports;\n    }\n})(this, function (module, _clipboardAction, _tinyEmitter, _goodListener) {\n    'use strict';\n\n    var _clipboardAction2 = _interopRequireDefault(_clipboardAction);\n\n    var _tinyEmitter2 = _interopRequireDefault(_tinyEmitter);\n\n    var _goodListener2 = _interopRequireDefault(_goodListener);\n\n    function _interopRequireDefault(obj) {\n        return obj && obj.__esModule ? obj : {\n            default: obj\n        };\n    }\n\n    function _classCallCheck(instance, Constructor) {\n        if (!(instance instanceof Constructor)) {\n            throw new TypeError(\"Cannot call a class as a function\");\n        }\n    }\n\n    var _createClass = function () {\n        function defineProperties(target, props) {\n            for (var i = 0; i < props.length; i++) {\n                var descriptor = props[i];\n                descriptor.enumerable = descriptor.enumerable || false;\n                descriptor.configurable = true;\n                if (\"value\" in descriptor) descriptor.writable = true;\n                Object.defineProperty(target, descriptor.key, descriptor);\n            }\n        }\n\n        return function (Constructor, protoProps, staticProps) {\n            if (protoProps) defineProperties(Constructor.prototype, protoProps);\n            if (staticProps) defineProperties(Constructor, staticProps);\n            return Constructor;\n        };\n    }();\n\n    function _possibleConstructorReturn(self, call) {\n        if (!self) {\n            throw new ReferenceError(\"this hasn't been initialised - super() hasn't been called\");\n        }\n\n        return call && (typeof call === \"object\" || typeof call === \"function\") ? call : self;\n    }\n\n    function _inherits(subClass, superClass) {\n        if (typeof superClass !== \"function\" && superClass !== null) {\n            throw new TypeError(\"Super expression must either be null or a function, not \" + typeof superClass);\n        }\n\n        subClass.prototype = Object.create(superClass && superClass.prototype, {\n            constructor: {\n                value: subClass,\n                enumerable: false,\n                writable: true,\n                configurable: true\n            }\n        });\n        if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass;\n    }\n\n    var Clipboard = function (_Emitter) {\n        _inherits(Clipboard, _Emitter);\n\n        /**\n         * @param {String|HTMLElement|HTMLCollection|NodeList} trigger\n         * @param {Object} options\n         */\n        function Clipboard(trigger, options) {\n            _classCallCheck(this, Clipboard);\n\n            var _this = _possibleConstructorReturn(this, (Clipboard.__proto__ || Object.getPrototypeOf(Clipboard)).call(this));\n\n            _this.resolveOptions(options);\n            _this.listenClick(trigger);\n            return _this;\n        }\n\n        /**\n         * Defines if attributes would be resolved using internal setter functions\n         * or custom functions that were passed in the constructor.\n         * @param {Object} options\n         */\n\n\n        _createClass(Clipboard, [{\n            key: 'resolveOptions',\n            value: function resolveOptions() {\n                var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};\n\n                this.action = typeof options.action === 'function' ? options.action : this.defaultAction;\n                this.target = typeof options.target === 'function' ? options.target : this.defaultTarget;\n                this.text = typeof options.text === 'function' ? options.text : this.defaultText;\n            }\n        }, {\n            key: 'listenClick',\n            value: function listenClick(trigger) {\n                var _this2 = this;\n\n                this.listener = (0, _goodListener2.default)(trigger, 'click', function (e) {\n                    return _this2.onClick(e);\n                });\n            }\n        }, {\n            key: 'onClick',\n            value: function onClick(e) {\n                var trigger = e.delegateTarget || e.currentTarget;\n\n                if (this.clipboardAction) {\n                    this.clipboardAction = null;\n                }\n\n                this.clipboardAction = new _clipboardAction2.default({\n                    action: this.action(trigger),\n                    target: this.target(trigger),\n                    text: this.text(trigger),\n                    trigger: trigger,\n                    emitter: this\n                });\n            }\n        }, {\n            key: 'defaultAction',\n            value: function defaultAction(trigger) {\n                return getAttributeValue('action', trigger);\n            }\n        }, {\n            key: 'defaultTarget',\n            value: function defaultTarget(trigger) {\n                var selector = getAttributeValue('target', trigger);\n\n                if (selector) {\n                    return document.querySelector(selector);\n                }\n            }\n        }, {\n            key: 'defaultText',\n            value: function defaultText(trigger) {\n                return getAttributeValue('text', trigger);\n            }\n        }, {\n            key: 'destroy',\n            value: function destroy() {\n                this.listener.destroy();\n\n                if (this.clipboardAction) {\n                    this.clipboardAction.destroy();\n                    this.clipboardAction = null;\n                }\n            }\n        }], [{\n            key: 'isSupported',\n            value: function isSupported() {\n                var action = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : ['copy', 'cut'];\n\n                var actions = typeof action === 'string' ? [action] : action;\n                var support = !!document.queryCommandSupported;\n\n                actions.forEach(function (action) {\n                    support = support && !!document.queryCommandSupported(action);\n                });\n\n                return support;\n            }\n        }]);\n\n        return Clipboard;\n    }(_tinyEmitter2.default);\n\n    /**\n     * Helper function to retrieve attribute value.\n     * @param {String} suffix\n     * @param {Element} element\n     */\n    function getAttributeValue(suffix, element) {\n        var attribute = 'data-clipboard-' + suffix;\n\n        if (!element.hasAttribute(attribute)) {\n            return;\n        }\n\n        return element.getAttribute(attribute);\n    }\n\n    module.exports = Clipboard;\n});\n\n},{\"./clipboard-action\":7,\"good-listener\":4,\"tiny-emitter\":6}]},{},[8])(8)\n});"
  },
  {
    "path": "app_frontend/static/plugin/clipboard.js-1.6.1/karma.conf.js",
    "content": "module.exports = function(karma) {\n    karma.set({\n        plugins: ['karma-browserify', 'karma-chai', 'karma-sinon', 'karma-mocha', 'karma-phantomjs-launcher'],\n\n        frameworks: ['browserify', 'chai', 'sinon', 'mocha'],\n\n        files: [\n            'src/**/*.js',\n            'test/**/*.js',\n            './node_modules/phantomjs-polyfill/bind-polyfill.js'\n        ],\n\n        exclude: ['test/module-systems.js'],\n\n        preprocessors: {\n            'src/**/*.js' : ['browserify'],\n            'test/**/*.js': ['browserify']\n        },\n\n        browserify: {\n            debug: true,\n            transform: ['babelify']\n        },\n\n        browsers: ['PhantomJS']\n    });\n}\n"
  },
  {
    "path": "app_frontend/static/plugin/clipboard.js-1.6.1/package.js",
    "content": "// Package metadata for Meteor.js.\n\nPackage.describe({\n  name: \"zenorocha:clipboard\",\n  summary: \"Modern copy to clipboard. No Flash. Just 2kb.\",\n  version: \"1.6.1\",\n  git: \"https://github.com/zenorocha/clipboard.js\"\n});\n\nPackage.onUse(function(api) {\n  api.addFiles(\"dist/clipboard.js\", \"client\");\n});\n"
  },
  {
    "path": "app_frontend/static/plugin/clipboard.js-1.6.1/package.json",
    "content": "{\n  \"name\": \"clipboard\",\n  \"version\": \"1.6.1\",\n  \"description\": \"Modern copy to clipboard. No Flash. Just 2kb\",\n  \"repository\": \"zenorocha/clipboard.js\",\n  \"license\": \"MIT\",\n  \"main\": \"lib/clipboard.js\",\n  \"keywords\": [\n    \"clipboard\",\n    \"copy\",\n    \"cut\"\n  ],\n  \"dependencies\": {\n    \"good-listener\": \"^1.2.0\",\n    \"select\": \"^1.1.2\",\n    \"tiny-emitter\": \"^1.0.0\"\n  },\n  \"devDependencies\": {\n    \"babel-cli\": \"^6.5.1\",\n    \"babel-core\": \"^6.5.2\",\n    \"babel-plugin-transform-es2015-modules-umd\": \"^6.5.0\",\n    \"babel-preset-es2015\": \"^6.5.0\",\n    \"babelify\": \"^7.2.0\",\n    \"bannerify\": \"Vekat/bannerify#feature-option\",\n    \"browserify\": \"^13.0.0\",\n    \"chai\": \"^3.4.1\",\n    \"install\": \"^0.8.1\",\n    \"karma\": \"^1.3.0\",\n    \"karma-browserify\": \"^5.0.1\",\n    \"karma-chai\": \"^0.1.0\",\n    \"karma-mocha\": \"^1.2.0\",\n    \"karma-phantomjs-launcher\": \"^1.0.0\",\n    \"karma-sinon\": \"^1.0.4\",\n    \"mocha\": \"^3.1.2\",\n    \"phantomjs-prebuilt\": \"^2.1.4\",\n    \"sinon\": \"^1.17.2\",\n    \"uglify-js\": \"^2.4.24\",\n    \"watchify\": \"^3.4.0\"\n  },\n  \"scripts\": {\n    \"build\": \"npm run build-debug && npm run build-min\",\n    \"build-debug\": \"browserify src/clipboard.js -s Clipboard -t [babelify] -p [bannerify --file .banner ] -o dist/clipboard.js\",\n    \"build-min\": \"uglifyjs dist/clipboard.js --comments '/!/' -m screw_ie8=true -c screw_ie8=true,unused=false -o dist/clipboard.min.js\",\n    \"build-watch\": \"watchify src/clipboard.js -s Clipboard -t [babelify] -o dist/clipboard.js -v\",\n    \"test\": \"karma start --single-run\",\n    \"prepublish\": \"babel src --out-dir lib\"\n  }\n}\n"
  },
  {
    "path": "app_frontend/static/plugin/clipboard.js-1.6.1/readme.md",
    "content": "# clipboard.js\n\n[![Build Status](http://img.shields.io/travis/zenorocha/clipboard.js/master.svg?style=flat)](https://travis-ci.org/zenorocha/clipboard.js)\n![Killing Flash](https://img.shields.io/badge/killing-flash-brightgreen.svg?style=flat)\n\n> Modern copy to clipboard. No Flash. Just 3kb gzipped.\n\n<a href=\"https://clipboardjs.com/\"><img width=\"728\" src=\"https://cloud.githubusercontent.com/assets/398893/16165747/a0f6fc46-349a-11e6-8c9b-c5fd58d9099c.png\" alt=\"Demo\"></a>\n\n## Why\n\nCopying text to the clipboard shouldn't be hard. It shouldn't require dozens of steps to configure or hundreds of KBs to load. But most of all, it shouldn't depend on Flash or any bloated framework.\n\nThat's why clipboard.js exists.\n\n## Install\n\nYou can get it on npm.\n\n```\nnpm install clipboard --save\n```\n\nOr bower, too.\n\n```\nbower install clipboard --save\n```\n\nIf you're not into package management, just [download a ZIP](https://github.com/zenorocha/clipboard.js/archive/master.zip) file.\n\n## Setup\n\nFirst, include the script located on the `dist` folder or load it from [a third-party CDN provider](https://github.com/zenorocha/clipboard.js/wiki/CDN-Providers).\n\n```html\n<script src=\"dist/clipboard.min.js\"></script>\n```\n\nNow, you need to instantiate it by [passing a DOM selector](https://github.com/zenorocha/clipboard.js/blob/master/demo/constructor-selector.html#L18), [HTML element](https://github.com/zenorocha/clipboard.js/blob/master/demo/constructor-node.html#L16-L17), or [list of HTML elements](https://github.com/zenorocha/clipboard.js/blob/master/demo/constructor-nodelist.html#L18-L19).\n\n```js\nnew Clipboard('.btn');\n```\n\nInternally, we need to fetch all elements that matches with your selector and attach event listeners for each one. But guess what? If you have hundreds of matches, this operation can consume a lot of memory.\n\nFor this reason we use [event delegation](http://stackoverflow.com/questions/1687296/what-is-dom-event-delegation) which replaces multiple event listeners with just a single listener. After all, [#perfmatters](https://twitter.com/hashtag/perfmatters).\n\n# Usage\n\nWe're living a _declarative renaissance_, that's why we decided to take advantage of [HTML5 data attributes](https://developer.mozilla.org/en-US/docs/Web/Guide/HTML/Using_data_attributes) for better usability.\n\n### Copy text from another element\n\nA pretty common use case is to copy content from another element. You can do that by adding a `data-clipboard-target` attribute in your trigger element.\n\nThe value you include on this attribute needs to match another's element selector.\n\n<a href=\"https://clipboardjs.com/#example-target\"><img width=\"473\" alt=\"example-2\" src=\"https://cloud.githubusercontent.com/assets/398893/9983467/a4946aaa-5fb1-11e5-9780-f09fcd7ca6c8.png\"></a>\n\n```html\n<!-- Target -->\n<input id=\"foo\" value=\"https://github.com/zenorocha/clipboard.js.git\">\n\n<!-- Trigger -->\n<button class=\"btn\" data-clipboard-target=\"#foo\">\n    <img src=\"assets/clippy.svg\" alt=\"Copy to clipboard\">\n</button>\n```\n\n### Cut text from another element\n\nAdditionally, you can define a `data-clipboard-action` attribute to specify if you want to either `copy` or `cut` content.\n\nIf you omit this attribute, `copy` will be used by default.\n\n<a href=\"https://clipboardjs.com/#example-action\"><img width=\"473\" alt=\"example-3\" src=\"https://cloud.githubusercontent.com/assets/398893/10000358/7df57b9c-6050-11e5-9cd1-fbc51d2fd0a7.png\"></a>\n\n```html\n<!-- Target -->\n<textarea id=\"bar\">Mussum ipsum cacilds...</textarea>\n\n<!-- Trigger -->\n<button class=\"btn\" data-clipboard-action=\"cut\" data-clipboard-target=\"#bar\">\n    Cut to clipboard\n</button>\n```\n\nAs you may expect, the `cut` action only works on `<input>` or `<textarea>` elements.\n\n### Copy text from attribute\n\nTruth is, you don't even need another element to copy its content from. You can just include a `data-clipboard-text` attribute in your trigger element.\n\n<a href=\"https://clipboardjs.com/#example-text\"><img width=\"147\" alt=\"example-1\" src=\"https://cloud.githubusercontent.com/assets/398893/10000347/6e16cf8c-6050-11e5-9883-1c5681f9ec45.png\"></a>\n\n```html\n<!-- Trigger -->\n<button class=\"btn\" data-clipboard-text=\"Just because you can doesn't mean you should — clipboard.js\">\n    Copy to clipboard\n</button>\n```\n\n## Events\n\nThere are cases where you'd like to show some user feedback or capture what has been selected after a copy/cut operation.\n\nThat's why we fire custom events such as `success` and `error` for you to listen and implement your custom logic.\n\n```js\nvar clipboard = new Clipboard('.btn');\n\nclipboard.on('success', function(e) {\n    console.info('Action:', e.action);\n    console.info('Text:', e.text);\n    console.info('Trigger:', e.trigger);\n\n    e.clearSelection();\n});\n\nclipboard.on('error', function(e) {\n    console.error('Action:', e.action);\n    console.error('Trigger:', e.trigger);\n});\n```\n\nFor a live demonstration, open this [site](https://clipboardjs.com/) and just your console :)\n\n## Advanced Options\n\nIf you don't want to modify your HTML, there's a pretty handy imperative API for you to use. All you need to do is declare a function, do your thing, and return a value.\n\nFor instance, if you want to dynamically set a `target`, you'll need to return a Node.\n\n```js\nnew Clipboard('.btn', {\n    target: function(trigger) {\n        return trigger.nextElementSibling;\n    }\n});\n```\n\nIf you want to dynamically set a `text`, you'll return a String.\n\n```js\nnew Clipboard('.btn', {\n    text: function(trigger) {\n        return trigger.getAttribute('aria-label');\n    }\n});\n```\n\nAlso, if you are working with single page apps, you may want to manage the lifecycle of the DOM more precisely. Here's how you clean up the events and objects that we create.\n\n```js\nvar clipboard = new Clipboard('.btn');\nclipboard.destroy();\n```\n\n## Browser Support\n\nThis library relies on both [Selection](https://developer.mozilla.org/en-US/docs/Web/API/Selection) and [execCommand](https://developer.mozilla.org/en-US/docs/Web/API/Document/execCommand) APIs. The first one is [supported by all browsers](http://caniuse.com/#search=selection) while the second one is supported in the following browsers.\n\n| <img src=\"https://clipboardjs.com/assets/images/chrome.png\" width=\"48px\" height=\"48px\" alt=\"Chrome logo\"> | <img src=\"https://clipboardjs.com/assets/images/edge.png\" width=\"48px\" height=\"48px\" alt=\"Edge logo\"> | <img src=\"https://clipboardjs.com/assets/images/firefox.png\" width=\"48px\" height=\"48px\" alt=\"Firefox logo\"> | <img src=\"https://clipboardjs.com/assets/images/ie.png\" width=\"48px\" height=\"48px\" alt=\"Internet Explorer logo\"> | <img src=\"https://clipboardjs.com/assets/images/opera.png\" width=\"48px\" height=\"48px\" alt=\"Opera logo\"> | <img src=\"https://clipboardjs.com/assets/images/safari.png\" width=\"48px\" height=\"48px\" alt=\"Safari logo\"> |\n|:---:|:---:|:---:|:---:|:---:|:---:|\n| 42+ ✔ | 12+ ✔ | 41+ ✔ | 9+ ✔ | 29+ ✔ | 10+ ✔ |\n\nThe good news is that clipboard.js gracefully degrades if you need to support older browsers. All you have to do is show a tooltip saying `Copied!` when `success` event is called and `Press Ctrl+C to copy` when `error` event is called because the text is already selected.\n\nYou can also check if clipboard.js is supported or not by running `Clipboard.isSupported()`, that way you can hide copy/cut buttons from the UI.\n\n## License\n\n[MIT License](http://zenorocha.mit-license.org/) © Zeno Rocha\n"
  },
  {
    "path": "app_frontend/static/plugin/clipboard.js-1.6.1/src/clipboard-action.js",
    "content": "import select from 'select';\n\n/**\n * Inner class which performs selection from either `text` or `target`\n * properties and then executes copy or cut operations.\n */\nclass ClipboardAction {\n    /**\n     * @param {Object} options\n     */\n    constructor(options) {\n        this.resolveOptions(options);\n        this.initSelection();\n    }\n\n    /**\n     * Defines base properties passed from constructor.\n     * @param {Object} options\n     */\n    resolveOptions(options = {}) {\n        this.action  = options.action;\n        this.emitter = options.emitter;\n        this.target  = options.target;\n        this.text    = options.text;\n        this.trigger = options.trigger;\n\n        this.selectedText = '';\n    }\n\n    /**\n     * Decides which selection strategy is going to be applied based\n     * on the existence of `text` and `target` properties.\n     */\n    initSelection() {\n        if (this.text) {\n            this.selectFake();\n        }\n        else if (this.target) {\n            this.selectTarget();\n        }\n    }\n\n    /**\n     * Creates a fake textarea element, sets its value from `text` property,\n     * and makes a selection on it.\n     */\n    selectFake() {\n        const isRTL = document.documentElement.getAttribute('dir') == 'rtl';\n\n        this.removeFake();\n\n        this.fakeHandlerCallback = () => this.removeFake();\n        this.fakeHandler = document.body.addEventListener('click', this.fakeHandlerCallback) || true;\n\n        this.fakeElem = document.createElement('textarea');\n        // Prevent zooming on iOS\n        this.fakeElem.style.fontSize = '12pt';\n        // Reset box model\n        this.fakeElem.style.border = '0';\n        this.fakeElem.style.padding = '0';\n        this.fakeElem.style.margin = '0';\n        // Move element out of screen horizontally\n        this.fakeElem.style.position = 'absolute';\n        this.fakeElem.style[ isRTL ? 'right' : 'left' ] = '-9999px';\n        // Move element to the same position vertically\n        let yPosition = window.pageYOffset || document.documentElement.scrollTop;\n        this.fakeElem.style.top = yPosition + 'px';\n\n        this.fakeElem.setAttribute('readonly', '');\n        this.fakeElem.value = this.text;\n\n        document.body.appendChild(this.fakeElem);\n\n        this.selectedText = select(this.fakeElem);\n        this.copyText();\n    }\n\n    /**\n     * Only removes the fake element after another click event, that way\n     * a user can hit `Ctrl+C` to copy because selection still exists.\n     */\n    removeFake() {\n        if (this.fakeHandler) {\n            document.body.removeEventListener('click', this.fakeHandlerCallback);\n            this.fakeHandler = null;\n            this.fakeHandlerCallback = null;\n        }\n\n        if (this.fakeElem) {\n            document.body.removeChild(this.fakeElem);\n            this.fakeElem = null;\n        }\n    }\n\n    /**\n     * Selects the content from element passed on `target` property.\n     */\n    selectTarget() {\n        this.selectedText = select(this.target);\n        this.copyText();\n    }\n\n    /**\n     * Executes the copy operation based on the current selection.\n     */\n    copyText() {\n        let succeeded;\n\n        try {\n            succeeded = document.execCommand(this.action);\n        }\n        catch (err) {\n            succeeded = false;\n        }\n\n        this.handleResult(succeeded);\n    }\n\n    /**\n     * Fires an event based on the copy operation result.\n     * @param {Boolean} succeeded\n     */\n    handleResult(succeeded) {\n        this.emitter.emit(succeeded ? 'success' : 'error', {\n            action: this.action,\n            text: this.selectedText,\n            trigger: this.trigger,\n            clearSelection: this.clearSelection.bind(this)\n        });\n    }\n\n    /**\n     * Removes current selection and focus from `target` element.\n     */\n    clearSelection() {\n        if (this.target) {\n            this.target.blur();\n        }\n\n        window.getSelection().removeAllRanges();\n    }\n\n    /**\n     * Sets the `action` to be performed which can be either 'copy' or 'cut'.\n     * @param {String} action\n     */\n    set action(action = 'copy') {\n        this._action = action;\n\n        if (this._action !== 'copy' && this._action !== 'cut') {\n            throw new Error('Invalid \"action\" value, use either \"copy\" or \"cut\"');\n        }\n    }\n\n    /**\n     * Gets the `action` property.\n     * @return {String}\n     */\n    get action() {\n        return this._action;\n    }\n\n    /**\n     * Sets the `target` property using an element\n     * that will be have its content copied.\n     * @param {Element} target\n     */\n    set target(target) {\n        if (target !== undefined) {\n            if (target && typeof target === 'object' && target.nodeType === 1) {\n                if (this.action === 'copy' && target.hasAttribute('disabled')) {\n                    throw new Error('Invalid \"target\" attribute. Please use \"readonly\" instead of \"disabled\" attribute');\n                }\n\n                if (this.action === 'cut' && (target.hasAttribute('readonly') || target.hasAttribute('disabled'))) {\n                    throw new Error('Invalid \"target\" attribute. You can\\'t cut text from elements with \"readonly\" or \"disabled\" attributes');\n                }\n\n                this._target = target;\n            }\n            else {\n                throw new Error('Invalid \"target\" value, use a valid Element');\n            }\n        }\n    }\n\n    /**\n     * Gets the `target` property.\n     * @return {String|HTMLElement}\n     */\n    get target() {\n        return this._target;\n    }\n\n    /**\n     * Destroy lifecycle.\n     */\n    destroy() {\n        this.removeFake();\n    }\n}\n\nmodule.exports = ClipboardAction;\n"
  },
  {
    "path": "app_frontend/static/plugin/clipboard.js-1.6.1/src/clipboard.js",
    "content": "import ClipboardAction from './clipboard-action';\nimport Emitter from 'tiny-emitter';\nimport listen from 'good-listener';\n\n/**\n * Base class which takes one or more elements, adds event listeners to them,\n * and instantiates a new `ClipboardAction` on each click.\n */\nclass Clipboard extends Emitter {\n    /**\n     * @param {String|HTMLElement|HTMLCollection|NodeList} trigger\n     * @param {Object} options\n     */\n    constructor(trigger, options) {\n        super();\n\n        this.resolveOptions(options);\n        this.listenClick(trigger);\n    }\n\n    /**\n     * Defines if attributes would be resolved using internal setter functions\n     * or custom functions that were passed in the constructor.\n     * @param {Object} options\n     */\n    resolveOptions(options = {}) {\n        this.action = (typeof options.action === 'function') ? options.action : this.defaultAction;\n        this.target = (typeof options.target === 'function') ? options.target : this.defaultTarget;\n        this.text   = (typeof options.text   === 'function') ? options.text   : this.defaultText;\n    }\n\n    /**\n     * Adds a click event listener to the passed trigger.\n     * @param {String|HTMLElement|HTMLCollection|NodeList} trigger\n     */\n    listenClick(trigger) {\n        this.listener = listen(trigger, 'click', (e) => this.onClick(e));\n    }\n\n    /**\n     * Defines a new `ClipboardAction` on each click event.\n     * @param {Event} e\n     */\n    onClick(e) {\n        const trigger = e.delegateTarget || e.currentTarget;\n\n        if (this.clipboardAction) {\n            this.clipboardAction = null;\n        }\n\n        this.clipboardAction = new ClipboardAction({\n            action  : this.action(trigger),\n            target  : this.target(trigger),\n            text    : this.text(trigger),\n            trigger : trigger,\n            emitter : this\n        });\n    }\n\n    /**\n     * Default `action` lookup function.\n     * @param {Element} trigger\n     */\n    defaultAction(trigger) {\n        return getAttributeValue('action', trigger);\n    }\n\n    /**\n     * Default `target` lookup function.\n     * @param {Element} trigger\n     */\n    defaultTarget(trigger) {\n        const selector = getAttributeValue('target', trigger);\n\n        if (selector) {\n            return document.querySelector(selector);\n        }\n    }\n\n    /**\n     * Returns the support of the given action, or all actions if no action is\n     * given.\n     * @param {String} [action]\n     */\n    static isSupported(action = ['copy', 'cut']) {\n        const actions = (typeof action === 'string') ? [action] : action;\n        let support = !!document.queryCommandSupported;\n\n        actions.forEach((action) => {\n            support = support && !!document.queryCommandSupported(action);\n        });\n\n        return support;\n    }\n\n    /**\n     * Default `text` lookup function.\n     * @param {Element} trigger\n     */\n    defaultText(trigger) {\n        return getAttributeValue('text', trigger);\n    }\n\n    /**\n     * Destroy lifecycle.\n     */\n    destroy() {\n        this.listener.destroy();\n\n        if (this.clipboardAction) {\n            this.clipboardAction.destroy();\n            this.clipboardAction = null;\n        }\n    }\n}\n\n\n/**\n * Helper function to retrieve attribute value.\n * @param {String} suffix\n * @param {Element} element\n */\nfunction getAttributeValue(suffix, element) {\n    const attribute = `data-clipboard-${suffix}`;\n\n    if (!element.hasAttribute(attribute)) {\n        return;\n    }\n\n    return element.getAttribute(attribute);\n}\n\nmodule.exports = Clipboard;\n"
  },
  {
    "path": "app_frontend/static/plugin/clipboard.js-1.6.1/test/clipboard-action.js",
    "content": "import ClipboardAction from '../src/clipboard-action';\nimport Emitter from 'tiny-emitter';\n\ndescribe('ClipboardAction', () => {\n    before(() => {\n        global.input = document.createElement('input');\n        global.input.setAttribute('id', 'input');\n        global.input.setAttribute('value', 'abc');\n        document.body.appendChild(global.input);\n\n        global.paragraph = document.createElement('p');\n        global.paragraph.setAttribute('id', 'paragraph');\n        global.paragraph.textContent = 'abc';\n        document.body.appendChild(global.paragraph);\n    });\n\n    after(() => {\n        document.body.innerHTML = '';\n    });\n\n    describe('#resolveOptions', () => {\n        it('should set base properties', () => {\n            let clip = new ClipboardAction({\n                emitter: new Emitter(),\n                text: 'foo'\n            });\n\n            assert.property(clip, 'action');\n            assert.property(clip, 'emitter');\n            assert.property(clip, 'target');\n            assert.property(clip, 'text');\n            assert.property(clip, 'trigger');\n            assert.property(clip, 'selectedText');\n        });\n    });\n\n    describe('#initSelection', () => {\n        it('should set the position right style property', done => {\n            // Set document direction\n            document.documentElement.setAttribute('dir', 'rtl');\n\n            let clip = new ClipboardAction({\n                    emitter: new Emitter(),\n                    text: 'foo'\n                });\n\n            assert.equal(clip.fakeElem.style.right, '-9999px');\n            done();\n        });\n    });\n\n    describe('#set action', () => {\n        it('should throw an error since \"action\" is invalid', done => {\n            try {\n                new ClipboardAction({\n                    text: 'foo',\n                    action: 'paste'\n                });\n            }\n            catch(e) {\n                assert.equal(e.message, 'Invalid \"action\" value, use either \"copy\" or \"cut\"');\n                done();\n            }\n        });\n    });\n\n    describe('#set target', () => {\n        it('should throw an error since \"target\" do not match any element', done => {\n            try {\n                new ClipboardAction({\n                    target: document.querySelector('#foo')\n                });\n            }\n            catch(e) {\n                assert.equal(e.message, 'Invalid \"target\" value, use a valid Element');\n                done();\n            }\n        });\n    });\n\n    describe('#selectText', () => {\n        it('should create a fake element and select its value', () => {\n            let clip = new ClipboardAction({\n                emitter: new Emitter(),\n                text: 'blah'\n            });\n\n            assert.equal(clip.selectedText, clip.fakeElem.value);\n        });\n    });\n\n    describe('#removeFake', () => {\n        it('should remove a temporary fake element', () => {\n            let clip = new ClipboardAction({\n                emitter: new Emitter(),\n                text: 'blah'\n            });\n\n            clip.removeFake();\n\n            assert.equal(clip.fakeElem, null);\n        });\n    });\n\n    describe('#selectTarget', () => {\n        it('should select text from editable element', () => {\n            let clip = new ClipboardAction({\n                emitter: new Emitter(),\n                target: document.querySelector('#input')\n            });\n\n            assert.equal(clip.selectedText, clip.target.value);\n        });\n\n        it('should select text from non-editable element', () => {\n            let clip = new ClipboardAction({\n                emitter: new Emitter(),\n                target: document.querySelector('#paragraph')\n            });\n\n            assert.equal(clip.selectedText, clip.target.textContent);\n        });\n    });\n\n    describe('#copyText', () => {\n        before(() => {\n            global.stub = sinon.stub(document, 'execCommand');\n        });\n\n        after(() => {\n            global.stub.restore();\n        });\n\n        it('should fire a success event on browsers that support copy command', done => {\n            global.stub.returns(true);\n\n            let emitter = new Emitter();\n\n            emitter.on('success', () => {\n                done();\n            });\n\n            let clip = new ClipboardAction({\n                emitter: emitter,\n                target: document.querySelector('#input')\n            });\n        });\n\n        it('should fire an error event on browsers that support copy command', done => {\n            global.stub.returns(false);\n\n            let emitter = new Emitter();\n\n            emitter.on('error', () => {\n                done();\n            });\n\n            let clip = new ClipboardAction({\n                emitter: emitter,\n                target: document.querySelector('#input')\n            });\n        });\n    });\n\n    describe('#handleResult', () => {\n        it('should fire a success event with certain properties', done => {\n            let clip = new ClipboardAction({\n                emitter: new Emitter(),\n                target: document.querySelector('#input')\n            });\n\n            clip.emitter.on('success', (e) => {\n                assert.property(e, 'action');\n                assert.property(e, 'text');\n                assert.property(e, 'trigger');\n                assert.property(e, 'clearSelection');\n\n                done();\n            });\n\n            clip.handleResult(true);\n        });\n\n        it('should fire a error event with certain properties', done => {\n            let clip = new ClipboardAction({\n                emitter: new Emitter(),\n                target: document.querySelector('#input')\n            });\n\n            clip.emitter.on('error', (e) => {\n                assert.property(e, 'action');\n                assert.property(e, 'trigger');\n                assert.property(e, 'clearSelection');\n\n                done();\n            });\n\n            clip.handleResult(false);\n        });\n    });\n\n    describe('#clearSelection', () => {\n        it('should remove focus from target and text selection', () => {\n            let clip = new ClipboardAction({\n                emitter: new Emitter(),\n                target: document.querySelector('#input')\n            });\n\n            clip.clearSelection();\n\n            let selectedElem = document.activeElement;\n            let selectedText = window.getSelection().toString();\n\n            assert.equal(selectedElem, document.body);\n            assert.equal(selectedText, '');\n        });\n    });\n\n    describe('#destroy', () => {\n        it('should destroy an existing fake element', () => {\n            let clip = new ClipboardAction({\n                emitter: new Emitter(),\n                text: 'blah'\n            });\n\n            clip.selectFake();\n            clip.destroy();\n\n            assert.equal(clip.fakeElem, null);\n        });\n    });\n});\n"
  },
  {
    "path": "app_frontend/static/plugin/clipboard.js-1.6.1/test/clipboard.js",
    "content": "import Clipboard from '../src/clipboard';\nimport ClipboardAction from '../src/clipboard-action';\nimport listen from 'good-listener';\n\ndescribe('Clipboard', () => {\n    before(() => {\n        global.button = document.createElement('button');\n        global.button.setAttribute('class', 'btn');\n        global.button.setAttribute('data-clipboard-text', 'foo');\n        document.body.appendChild(global.button);\n\n        global.span = document.createElement('span');\n        global.span.innerHTML = 'bar';\n\n        global.button.appendChild(span);\n\n        global.event = {\n            target: global.button,\n            currentTarget: global.button\n        };\n    });\n\n    after(() => {\n        document.body.innerHTML = '';\n    });\n\n    describe('#resolveOptions', () => {\n        before(() => {\n            global.fn = function() {};\n        });\n\n        it('should set action as a function', () => {\n            let clipboard = new Clipboard('.btn', {\n                action: global.fn\n            });\n\n            assert.equal(global.fn, clipboard.action);\n        });\n\n        it('should set target as a function', () => {\n            let clipboard = new Clipboard('.btn', {\n                target: global.fn\n            });\n\n            assert.equal(global.fn, clipboard.target);\n        });\n\n        it('should set text as a function', () => {\n            let clipboard = new Clipboard('.btn', {\n                text: global.fn\n            });\n\n            assert.equal(global.fn, clipboard.text);\n        });\n    });\n\n    describe('#listenClick', () => {\n        it('should add a click event listener to the passed selector', () => {\n            let clipboard = new Clipboard('.btn');\n            assert.isObject(clipboard.listener);\n        });\n    });\n\n    describe('#onClick', () => {\n        it('should create a new instance of ClipboardAction', () => {\n            let clipboard = new Clipboard('.btn');\n\n            clipboard.onClick(global.event);\n            assert.instanceOf(clipboard.clipboardAction, ClipboardAction);\n        });\n\n        it('should use an event\\'s currentTarget when not equal to target', () => {\n            let clipboard = new Clipboard('.btn');\n            let bubbledEvent = { target: global.span, currentTarget: global.button };\n\n            clipboard.onClick(bubbledEvent);\n            assert.instanceOf(clipboard.clipboardAction, ClipboardAction);\n        });\n\n        it('should throw an exception when target is invalid', done => {\n            try {\n                var clipboard = new Clipboard('.btn', {\n                    target: function() {\n                        return null;\n                    }\n                });\n\n                clipboard.onClick(global.event);\n            }\n            catch(e) {\n                assert.equal(e.message, 'Invalid \"target\" value, use a valid Element');\n                done();\n            }\n        });\n    });\n\n    describe('#static isSupported', () => {\n        it('should return the support of the given action', () => {\n            assert.equal(Clipboard.isSupported('copy'), false);\n            assert.equal(Clipboard.isSupported('cut'), false);\n        });\n\n        it('should return the support of the cut and copy actions', () => {\n            assert.equal(Clipboard.isSupported(), false);\n        });\n    });\n\n    describe('#destroy', () => {\n        it('should destroy an existing instance of ClipboardAction', () => {\n            let clipboard = new Clipboard('.btn');\n\n            clipboard.onClick(global.event);\n            clipboard.destroy();\n\n            assert.equal(clipboard.clipboardAction, null);\n        });\n    });\n});\n"
  },
  {
    "path": "app_frontend/static/plugin/jQuery-File-Upload-9.18.0/.gitignore",
    "content": ".DS_Store\n*.pyc\nnode_modules\n"
  },
  {
    "path": "app_frontend/static/plugin/jQuery-File-Upload-9.18.0/.jshintrc",
    "content": "{\n  \"bitwise\"       : true,     // true: Prohibit bitwise operators (&, |, ^, etc.)\n  \"camelcase\"     : true,     // true: Identifiers must be in camelCase\n  \"curly\"         : true,     // true: Require {} for every new block or scope\n  \"eqeqeq\"        : true,     // true: Require triple equals (===) for comparison\n  \"forin\"         : true,     // true: Require filtering for..in loops with obj.hasOwnProperty()\n  \"immed\"         : true,     // true: Require immediate invocations to be wrapped in parens\n                              // e.g. `(function () { } ());`\n  \"indent\"        : 4,        // {int} Number of spaces to use for indentation\n  \"latedef\"       : true,     // true: Require variables/functions to be defined before being used\n  \"newcap\"        : true,     // true: Require capitalization of all constructor functions e.g. `new F()`\n  \"noarg\"         : true,     // true: Prohibit use of `arguments.caller` and `arguments.callee`\n  \"noempty\"       : true,     // true: Prohibit use of empty blocks\n  \"nonew\"         : true,     // true: Prohibit use of constructors for side-effects (without assignment)\n  \"plusplus\"      : false,    // true: Prohibit use of `++` & `--`\n  \"quotmark\"      : \"single\", // Quotation mark consistency:\n                              //   false    : do nothing (default)\n                              //   true     : ensure whatever is used is consistent\n                              //   \"single\" : require single quotes\n                              //   \"double\" : require double quotes\n  \"undef\"         : true,     // true: Require all non-global variables to be declared (prevents global leaks)\n  \"unused\"        : true,     // true: Require all defined variables be used\n  \"strict\"        : true,     // true: Requires all functions run in ES5 Strict Mode\n  \"trailing\"      : true,     // true: Prohibit trailing whitespaces\n  \"maxparams\"     : false,    // {int} Max number of formal params allowed per function\n  \"maxdepth\"      : false,    // {int} Max depth of nested blocks (within functions)\n  \"maxstatements\" : false,    // {int} Max number statements per function\n  \"maxcomplexity\" : false,    // {int} Max cyclomatic complexity per function\n  \"maxlen\"        : false,    // {int} Max number of characters per line\n\n  // Relaxing\n  \"asi\"           : false,     // true: Tolerate Automatic Semicolon Insertion (no semicolons)\n  \"boss\"          : false,     // true: Tolerate assignments where comparisons would be expected\n  \"debug\"         : false,     // true: Allow debugger statements e.g. browser breakpoints.\n  \"eqnull\"        : false,     // true: Tolerate use of `== null`\n  \"es5\"           : false,     // true: Allow ES5 syntax (ex: getters and setters)\n  \"esnext\"        : false,     // true: Allow ES.next (ES6) syntax (ex: `const`)\n  \"moz\"           : false,     // true: Allow Mozilla specific syntax (extends and overrides esnext features)\n                               // (ex: `for each`, multiple try/catch, function expression…)\n  \"evil\"          : false,     // true: Tolerate use of `eval` and `new Function()`\n  \"expr\"          : false,     // true: Tolerate `ExpressionStatement` as Programs\n  \"funcscope\"     : false,     // true: Tolerate defining variables inside control statements\"\n  \"globalstrict\"  : false,     // true: Allow global \"use strict\" (also enables 'strict')\n  \"iterator\"      : false,     // true: Tolerate using the `__iterator__` property\n  \"lastsemic\"     : false,     // true: Tolerate omitting a semicolon for the last statement of a 1-line block\n  \"laxbreak\"      : false,     // true: Tolerate possibly unsafe line breakings\n  \"laxcomma\"      : false,     // true: Tolerate comma-first style coding\n  \"loopfunc\"      : false,     // true: Tolerate functions being defined in loops\n  \"multistr\"      : false,     // true: Tolerate multi-line strings\n  \"proto\"         : false,     // true: Tolerate using the `__proto__` property\n  \"scripturl\"     : false,     // true: Tolerate script-targeted URLs\n  \"smarttabs\"     : false,     // true: Tolerate mixed tabs/spaces when used for alignment\n  \"shadow\"        : false,     // true: Allows re-define variables later in code e.g. `var x=1; x=2;`\n  \"sub\"           : false,     // true: Tolerate using `[]` notation when it can still be expressed in dot notation\n  \"supernew\"      : false,     // true: Tolerate `new function () { ... };` and `new Object;`\n  \"validthis\"     : false,     // true: Tolerate using this in a non-constructor function\n\n  // Environments\n  \"browser\"       : false,    // Web Browser (window, document, etc)\n  \"couch\"         : false,    // CouchDB\n  \"devel\"         : false,    // Development/debugging (alert, confirm, etc)\n  \"dojo\"          : false,    // Dojo Toolkit\n  \"jquery\"        : false,    // jQuery\n  \"mootools\"      : false,    // MooTools\n  \"node\"          : false,    // Node.js\n  \"nonstandard\"   : false,    // Widely adopted globals (escape, unescape, etc)\n  \"prototypejs\"   : false,    // Prototype and Scriptaculous\n  \"rhino\"         : false,    // Rhino\n  \"worker\"        : false,    // Web Workers\n  \"wsh\"           : false,    // Windows Scripting Host\n  \"yui\"           : false,    // Yahoo User Interface\n\n  // Legacy\n  \"nomen\"         : true,     // true: Prohibit dangling `_` in variables\n  \"onevar\"        : true,     // true: Allow only one `var` statement per function\n  \"passfail\"      : false,    // true: Stop on first error\n  \"white\"         : true,     // true: Check against strict whitespace and indentation rules\n\n  // Custom Globals\n  \"globals\"       : {}        // additional predefined global variables\n}\n"
  },
  {
    "path": "app_frontend/static/plugin/jQuery-File-Upload-9.18.0/.npmignore",
    "content": "*\n!css/jquery.fileupload-noscript.css\n!css/jquery.fileupload-ui-noscript.css\n!css/jquery.fileupload-ui.css\n!css/jquery.fileupload.css\n!img/loading.gif\n!img/progressbar.gif\n!js/cors/jquery.postmessage-transport.js\n!js/cors/jquery.xdr-transport.js\n!js/vendor/jquery.ui.widget.js\n!js/jquery.fileupload-angular.js\n!js/jquery.fileupload-audio.js\n!js/jquery.fileupload-image.js\n!js/jquery.fileupload-jquery-ui.js\n!js/jquery.fileupload-process.js\n!js/jquery.fileupload-ui.js\n!js/jquery.fileupload-validate.js\n!js/jquery.fileupload-video.js\n!js/jquery.fileupload.js\n!js/jquery.iframe-transport.js\n"
  },
  {
    "path": "app_frontend/static/plugin/jQuery-File-Upload-9.18.0/CONTRIBUTING.md",
    "content": "Please follow these pull request guidelines:\n\n1. Update your fork to the latest upstream version.\n\n2. Follow the coding conventions of the original source files (indentation, spaces, brackets layout).\n\n3. Code changes must pass JSHint validation with the `.jshintrc` settings of this project.\n\n4. Code changes must pass the QUnit tests defined in the `test` folder.\n\n5. New features should be covered by accompanying QUnit tests.\n\n6. Keep your commits as atomic as possible, i.e. create a new commit for every single bug fix or feature added.\n\n7. Always add meaningful commit messages.\n"
  },
  {
    "path": "app_frontend/static/plugin/jQuery-File-Upload-9.18.0/LICENSE",
    "content": "The MIT License (MIT)\n\nCopyright (c) 2017 jQuery-File-Upload Authors\n\nPermission is hereby granted, free of charge, to any person obtaining a copy of\nthis software and associated documentation files (the \"Software\"), to deal in\nthe Software without restriction, including without limitation the rights to\nuse, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of\nthe Software, and to permit persons to whom the Software is furnished to do so,\nsubject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS\nFOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR\nCOPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER\nIN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN\nCONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n"
  },
  {
    "path": "app_frontend/static/plugin/jQuery-File-Upload-9.18.0/README.md",
    "content": "# jQuery File Upload Plugin\n\n## Demo\n[Demo File Upload](https://blueimp.github.io/jQuery-File-Upload/)\n\n## Description\nFile Upload widget with multiple file selection, drag&amp;drop support, progress bars, validation and preview images, audio and video for jQuery.  \nSupports cross-domain, chunked and resumable file uploads and client-side image resizing. Works with any server-side platform (PHP, Python, Ruby on Rails, Java, Node.js, Go etc.) that supports standard HTML form file uploads.\n\n## Setup\n* [How to setup the plugin on your website](https://github.com/blueimp/jQuery-File-Upload/wiki/Setup)\n* [How to use only the basic plugin (minimal setup guide).](https://github.com/blueimp/jQuery-File-Upload/wiki/Basic-plugin)\n\n## Features\n* **Multiple file upload:**  \n  Allows to select multiple files at once and upload them simultaneously.\n* **Drag & Drop support:**  \n  Allows to upload files by dragging them from your desktop or filemanager and dropping them on your browser window.\n* **Upload progress bar:**  \n  Shows a progress bar indicating the upload progress for individual files and for all uploads combined.\n* **Cancelable uploads:**  \n  Individual file uploads can be canceled to stop the upload progress.\n* **Resumable uploads:**  \n  Aborted uploads can be resumed with browsers supporting the Blob API.\n* **Chunked uploads:**  \n  Large files can be uploaded in smaller chunks with browsers supporting the Blob API.\n* **Client-side image resizing:**  \n  Images can be automatically resized on client-side with browsers supporting the required JS APIs.\n* **Preview images, audio and video:**  \n  A preview of image, audio and video files can be displayed before uploading with browsers supporting the required APIs.\n* **No browser plugins (e.g. Adobe Flash) required:**  \n  The implementation is based on open standards like HTML5 and JavaScript and requires no additional browser plugins.\n* **Graceful fallback for legacy browsers:**  \n  Uploads files via XMLHttpRequests if supported and uses iframes as fallback for legacy browsers.\n* **HTML file upload form fallback:**  \n  Allows progressive enhancement by using a standard HTML file upload form as widget element.\n* **Cross-site file uploads:**  \n  Supports uploading files to a different domain with cross-site XMLHttpRequests or iframe redirects.\n* **Multiple plugin instances:**  \n  Allows to use multiple plugin instances on the same webpage.\n* **Customizable and extensible:**  \n  Provides an API to set individual options and define callBack methods for various upload events.\n* **Multipart and file contents stream uploads:**  \n  Files can be uploaded as standard \"multipart/form-data\" or file contents stream (HTTP PUT file upload).\n* **Compatible with any server-side application platform:**  \n  Works with any server-side platform (PHP, Python, Ruby on Rails, Java, Node.js, Go etc.) that supports standard HTML form file uploads.\n\n## Requirements\n\n### Mandatory requirements\n* [jQuery](https://jquery.com/) v. 1.6+\n* [jQuery UI widget factory](https://api.jqueryui.com/jQuery.widget/) v. 1.9+ (included): Required for the basic File Upload plugin, but very lightweight without any other dependencies from the jQuery UI suite.\n* [jQuery Iframe Transport plugin](https://github.com/blueimp/jQuery-File-Upload/blob/master/js/jquery.iframe-transport.js) (included): Required for [browsers without XHR file upload support](https://github.com/blueimp/jQuery-File-Upload/wiki/Browser-support).\n\n### Optional requirements\n* [JavaScript Templates engine](https://github.com/blueimp/JavaScript-Templates) v. 2.5.4+: Used to render the selected and uploaded files for the Basic Plus UI and jQuery UI versions.\n* [JavaScript Load Image library](https://github.com/blueimp/JavaScript-Load-Image) v. 1.13.0+: Required for the image previews and resizing functionality.\n* [JavaScript Canvas to Blob polyfill](https://github.com/blueimp/JavaScript-Canvas-to-Blob) v. 2.1.1+:Required for the image previews and resizing functionality.\n* [blueimp Gallery](https://github.com/blueimp/Gallery) v. 2.15.1+: Used to display the uploaded images in a lightbox.\n* [Bootstrap](http://getbootstrap.com/) v. 3.2.0+\n* [Glyphicons](http://glyphicons.com/)\n\nThe user interface of all versions except the jQuery UI version is built with [Bootstrap](http://getbootstrap.com/) and icons from [Glyphicons](http://glyphicons.com/).\n\n### Cross-domain requirements\n[Cross-domain File Uploads](https://github.com/blueimp/jQuery-File-Upload/wiki/Cross-domain-uploads) using the [Iframe Transport plugin](https://github.com/blueimp/jQuery-File-Upload/blob/master/js/jquery.iframe-transport.js) require a redirect back to the origin server to retrieve the upload results. The [example implementation](https://github.com/blueimp/jQuery-File-Upload/blob/master/js/main.js) makes use of [result.html](https://github.com/blueimp/jQuery-File-Upload/blob/master/cors/result.html) as a static redirect page for the origin server.\n\nThe repository also includes the [jQuery XDomainRequest Transport plugin](https://github.com/blueimp/jQuery-File-Upload/blob/master/js/cors/jquery.xdr-transport.js), which enables limited cross-domain AJAX requests in Microsoft Internet Explorer 8 and 9 (IE 10 supports cross-domain XHR requests).  \nThe XDomainRequest object allows GET and POST requests only and doesn't support file uploads. It is used on the [Demo](https://blueimp.github.io/jQuery-File-Upload/) to delete uploaded files from the cross-domain demo file upload service.\n\n### Custom Backends\n\nYou can add support for various backends by adhering to the specification [outlined here](https://github.com/blueimp/jQuery-File-Upload/wiki/JSON-Response).\n\n## Browsers\n\n### Desktop browsers\nThe File Upload plugin is regularly tested with the latest browser versions and supports the following minimal versions:\n\n* Google Chrome\n* Apple Safari 4.0+\n* Mozilla Firefox 3.0+\n* Opera 11.0+\n* Microsoft Internet Explorer 6.0+\n\n### Mobile browsers\nThe File Upload plugin has been tested with and supports the following mobile browsers:\n\n* Apple Safari on iOS 6.0+\n* Google Chrome on iOS 6.0+\n* Google Chrome on Android 4.0+\n* Default Browser on Android 2.3+\n* Opera Mobile 12.0+\n\n### Supported features\nFor a detailed overview of the features supported by each browser version, please have a look at the [Extended browser support information](https://github.com/blueimp/jQuery-File-Upload/wiki/Browser-support).\n\n## Contributing\n**Bug fixes** and **new features** can be proposed using [pull requests](https://github.com/blueimp/jQuery-File-Upload/pulls).\nPlease read the [contribution guidelines](https://github.com/blueimp/jQuery-File-Upload/blob/master/CONTRIBUTING.md) before submitting a pull request.\n\n## Support\nThis project is actively maintained, but there is no official support channel.  \nIf you have a question that another developer might help you with, please post to [Stack Overflow](http://stackoverflow.com/questions/tagged/blueimp+jquery+file-upload) and tag your question with `blueimp jquery file upload`.\n\n## License\nReleased under the [MIT license](https://opensource.org/licenses/MIT).\n"
  },
  {
    "path": "app_frontend/static/plugin/jQuery-File-Upload-9.18.0/angularjs.html",
    "content": "<!DOCTYPE HTML>\n<!--\n/*\n * jQuery File Upload Plugin AngularJS Demo\n * https://github.com/blueimp/jQuery-File-Upload\n *\n * Copyright 2013, Sebastian Tschan\n * https://blueimp.net\n *\n * Licensed under the MIT license:\n * https://opensource.org/licenses/MIT\n */\n-->\n<html lang=\"en\">\n<head>\n<!-- Force latest IE rendering engine or ChromeFrame if installed -->\n<!--[if IE]>\n<meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge,chrome=1\">\n<![endif]-->\n<meta charset=\"utf-8\">\n<title>jQuery File Upload Demo - AngularJS version</title>\n<meta name=\"description\" content=\"File Upload widget with multiple file selection, drag&amp;drop support, progress bars, validation and preview images, audio and video for AngularJS. Supports cross-domain, chunked and resumable file uploads and client-side image resizing. Works with any server-side platform (PHP, Python, Ruby on Rails, Java, Node.js, Go etc.) that supports standard HTML form file uploads.\">\n<meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n<!-- Bootstrap styles -->\n<link rel=\"stylesheet\" href=\"//netdna.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.min.css\">\n<!-- Generic page styles -->\n<link rel=\"stylesheet\" href=\"css/style.css\">\n<!-- blueimp Gallery styles -->\n<link rel=\"stylesheet\" href=\"//blueimp.github.io/Gallery/css/blueimp-gallery.min.css\">\n<!-- CSS to style the file input field as button and adjust the Bootstrap progress bars -->\n<link rel=\"stylesheet\" href=\"css/jquery.fileupload.css\">\n<link rel=\"stylesheet\" href=\"css/jquery.fileupload-ui.css\">\n<!-- CSS adjustments for browsers with JavaScript disabled -->\n<noscript><link rel=\"stylesheet\" href=\"css/jquery.fileupload-noscript.css\"></noscript>\n<noscript><link rel=\"stylesheet\" href=\"css/jquery.fileupload-ui-noscript.css\"></noscript>\n<style>\n/* Hide Angular JS elements before initializing */\n.ng-cloak {\n    display: none;\n}\n</style>\n</head>\n<body>\n<div class=\"navbar navbar-default navbar-fixed-top\">\n    <div class=\"container\">\n        <div class=\"navbar-header\">\n            <button type=\"button\" class=\"navbar-toggle\" data-toggle=\"collapse\" data-target=\".navbar-fixed-top .navbar-collapse\">\n                <span class=\"icon-bar\"></span>\n                <span class=\"icon-bar\"></span>\n                <span class=\"icon-bar\"></span>\n            </button>\n            <a class=\"navbar-brand\" href=\"https://github.com/blueimp/jQuery-File-Upload\">jQuery File Upload</a>\n        </div>\n        <div class=\"navbar-collapse collapse\">\n            <ul class=\"nav navbar-nav\">\n                <li><a href=\"https://github.com/blueimp/jQuery-File-Upload/tags\">Download</a></li>\n                <li><a href=\"https://github.com/blueimp/jQuery-File-Upload\">Source Code</a></li>\n                <li><a href=\"https://github.com/blueimp/jQuery-File-Upload/wiki\">Documentation</a></li>\n                <li><a href=\"https://blueimp.net\">&copy; Sebastian Tschan</a></li>\n            </ul>\n        </div>\n    </div>\n</div>\n<div class=\"container\">\n    <h1>jQuery File Upload Demo</h1>\n    <h2 class=\"lead\">AngularJS version</h2>\n    <ul class=\"nav nav-tabs\">\n        <li><a href=\"basic.html\">Basic</a></li>\n        <li><a href=\"basic-plus.html\">Basic Plus</a></li>\n        <li><a href=\"index.html\">Basic Plus UI</a></li>\n        <li class=\"active\"><a href=\"angularjs.html\">AngularJS</a></li>\n        <li><a href=\"jquery-ui.html\">jQuery UI</a></li>\n    </ul>\n    <br>\n    <blockquote>\n        <p>File Upload widget with multiple file selection, drag&amp;drop support, progress bars, validation and preview images, audio and video for AngularJS.<br>\n        Supports cross-domain, chunked and resumable file uploads and client-side image resizing.<br>\n        Works with any server-side platform (PHP, Python, Ruby on Rails, Java, Node.js, Go etc.) that supports standard HTML form file uploads.</p>\n    </blockquote>\n    <br>\n    <!-- The file upload form used as target for the file upload widget -->\n    <form id=\"fileupload\" action=\"//jquery-file-upload.appspot.com/\" method=\"POST\" enctype=\"multipart/form-data\" data-ng-app=\"demo\" data-ng-controller=\"DemoFileUploadController\" data-file-upload=\"options\" data-ng-class=\"{'fileupload-processing': processing() || loadingFiles}\">\n        <!-- Redirect browsers with JavaScript disabled to the origin page -->\n        <noscript><input type=\"hidden\" name=\"redirect\" value=\"https://blueimp.github.io/jQuery-File-Upload/\"></noscript>\n        <!-- The fileupload-buttonbar contains buttons to add/delete files and start/cancel the upload -->\n        <div class=\"row fileupload-buttonbar\">\n            <div class=\"col-lg-7\">\n                <!-- The fileinput-button span is used to style the file input field as button -->\n                <span class=\"btn btn-success fileinput-button\" ng-class=\"{disabled: disabled}\">\n                    <i class=\"glyphicon glyphicon-plus\"></i>\n                    <span>Add files...</span>\n                    <input type=\"file\" name=\"files[]\" multiple ng-disabled=\"disabled\">\n                </span>\n                <button type=\"button\" class=\"btn btn-primary start\" data-ng-click=\"submit()\">\n                    <i class=\"glyphicon glyphicon-upload\"></i>\n                    <span>Start upload</span>\n                </button>\n                <button type=\"button\" class=\"btn btn-warning cancel\" data-ng-click=\"cancel()\">\n                    <i class=\"glyphicon glyphicon-ban-circle\"></i>\n                    <span>Cancel upload</span>\n                </button>\n                <!-- The global file processing state -->\n                <span class=\"fileupload-process\"></span>\n            </div>\n            <!-- The global progress state -->\n            <div class=\"col-lg-5 fade\" data-ng-class=\"{in: active()}\">\n                <!-- The global progress bar -->\n                <div class=\"progress progress-striped active\" data-file-upload-progress=\"progress()\"><div class=\"progress-bar progress-bar-success\" data-ng-style=\"{width: num + '%'}\"></div></div>\n                <!-- The extended global progress state -->\n                <div class=\"progress-extended\">&nbsp;</div>\n            </div>\n        </div>\n        <!-- The table listing the files available for upload/download -->\n        <table class=\"table table-striped files ng-cloak\">\n            <tr data-ng-repeat=\"file in queue\" data-ng-class=\"{'processing': file.$processing()}\">\n                <td data-ng-switch data-on=\"!!file.thumbnailUrl\">\n                    <div class=\"preview\" data-ng-switch-when=\"true\">\n                        <a data-ng-href=\"{{file.url}}\" title=\"{{file.name}}\" download=\"{{file.name}}\" data-gallery><img data-ng-src=\"{{file.thumbnailUrl}}\" alt=\"\"></a>\n                    </div>\n                    <div class=\"preview\" data-ng-switch-default data-file-upload-preview=\"file\"></div>\n                </td>\n                <td>\n                    <p class=\"name\" data-ng-switch data-on=\"!!file.url\">\n                        <span data-ng-switch-when=\"true\" data-ng-switch data-on=\"!!file.thumbnailUrl\">\n                            <a data-ng-switch-when=\"true\" data-ng-href=\"{{file.url}}\" title=\"{{file.name}}\" download=\"{{file.name}}\" data-gallery>{{file.name}}</a>\n                            <a data-ng-switch-default data-ng-href=\"{{file.url}}\" title=\"{{file.name}}\" download=\"{{file.name}}\">{{file.name}}</a>\n                        </span>\n                        <span data-ng-switch-default>{{file.name}}</span>\n                    </p>\n                    <strong data-ng-show=\"file.error\" class=\"error text-danger\">{{file.error}}</strong>\n                </td>\n                <td>\n                    <p class=\"size\">{{file.size | formatFileSize}}</p>\n                    <div class=\"progress progress-striped active fade\" data-ng-class=\"{pending: 'in'}[file.$state()]\" data-file-upload-progress=\"file.$progress()\"><div class=\"progress-bar progress-bar-success\" data-ng-style=\"{width: num + '%'}\"></div></div>\n                </td>\n                <td>\n                    <button type=\"button\" class=\"btn btn-primary start\" data-ng-click=\"file.$submit()\" data-ng-hide=\"!file.$submit || options.autoUpload\" data-ng-disabled=\"file.$state() == 'pending' || file.$state() == 'rejected'\">\n                        <i class=\"glyphicon glyphicon-upload\"></i>\n                        <span>Start</span>\n                    </button>\n                    <button type=\"button\" class=\"btn btn-warning cancel\" data-ng-click=\"file.$cancel()\" data-ng-hide=\"!file.$cancel\">\n                        <i class=\"glyphicon glyphicon-ban-circle\"></i>\n                        <span>Cancel</span>\n                    </button>\n                    <button data-ng-controller=\"FileDestroyController\" type=\"button\" class=\"btn btn-danger destroy\" data-ng-click=\"file.$destroy()\" data-ng-hide=\"!file.$destroy\">\n                        <i class=\"glyphicon glyphicon-trash\"></i>\n                        <span>Delete</span>\n                    </button>\n                </td>\n            </tr>\n        </table>\n    </form>\n    <br>\n    <div class=\"panel panel-default\">\n        <div class=\"panel-heading\">\n            <h3 class=\"panel-title\">Demo Notes</h3>\n        </div>\n        <div class=\"panel-body\">\n            <ul>\n                <li>The maximum file size for uploads in this demo is <strong>999 KB</strong> (default file size is unlimited).</li>\n                <li>Only image files (<strong>JPG, GIF, PNG</strong>) are allowed in this demo (by default there is no file type restriction).</li>\n                <li>Uploaded files will be deleted automatically after <strong>5 minutes or less</strong> (demo files are stored in memory).</li>\n                <li>You can <strong>drag &amp; drop</strong> files from your desktop on this webpage (see <a href=\"https://github.com/blueimp/jQuery-File-Upload/wiki/Browser-support\">Browser support</a>).</li>\n                <li>Please refer to the <a href=\"https://github.com/blueimp/jQuery-File-Upload\">project website</a> and <a href=\"https://github.com/blueimp/jQuery-File-Upload/wiki\">documentation</a> for more information.</li>\n                <li>Built with the <a href=\"http://getbootstrap.com/\">Bootstrap</a> CSS framework and Icons from <a href=\"http://glyphicons.com/\">Glyphicons</a>.</li>\n            </ul>\n        </div>\n    </div>\n</div>\n<!-- The blueimp Gallery widget -->\n<div id=\"blueimp-gallery\" class=\"blueimp-gallery blueimp-gallery-controls\" data-filter=\":even\">\n    <div class=\"slides\"></div>\n    <h3 class=\"title\"></h3>\n    <a class=\"prev\">‹</a>\n    <a class=\"next\">›</a>\n    <a class=\"close\">×</a>\n    <a class=\"play-pause\"></a>\n    <ol class=\"indicator\"></ol>\n</div>\n<script src=\"//ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js\"></script>\n<script src=\"//ajax.googleapis.com/ajax/libs/angularjs/1.3.15/angular.min.js\"></script>\n<!-- The jQuery UI widget factory, can be omitted if jQuery UI is already included -->\n<script src=\"js/vendor/jquery.ui.widget.js\"></script>\n<!-- The Load Image plugin is included for the preview images and image resizing functionality -->\n<script src=\"//blueimp.github.io/JavaScript-Load-Image/js/load-image.all.min.js\"></script>\n<!-- The Canvas to Blob plugin is included for image resizing functionality -->\n<script src=\"//blueimp.github.io/JavaScript-Canvas-to-Blob/js/canvas-to-blob.min.js\"></script>\n<!-- Bootstrap JS is not required, but included for the responsive demo navigation -->\n<script src=\"//netdna.bootstrapcdn.com/bootstrap/3.2.0/js/bootstrap.min.js\"></script>\n<!-- blueimp Gallery script -->\n<script src=\"//blueimp.github.io/Gallery/js/jquery.blueimp-gallery.min.js\"></script>\n<!-- The Iframe Transport is required for browsers without support for XHR file uploads -->\n<script src=\"js/jquery.iframe-transport.js\"></script>\n<!-- The basic File Upload plugin -->\n<script src=\"js/jquery.fileupload.js\"></script>\n<!-- The File Upload processing plugin -->\n<script src=\"js/jquery.fileupload-process.js\"></script>\n<!-- The File Upload image preview & resize plugin -->\n<script src=\"js/jquery.fileupload-image.js\"></script>\n<!-- The File Upload audio preview plugin -->\n<script src=\"js/jquery.fileupload-audio.js\"></script>\n<!-- The File Upload video preview plugin -->\n<script src=\"js/jquery.fileupload-video.js\"></script>\n<!-- The File Upload validation plugin -->\n<script src=\"js/jquery.fileupload-validate.js\"></script>\n<!-- The File Upload Angular JS module -->\n<script src=\"js/jquery.fileupload-angular.js\"></script>\n<!-- The main application script -->\n<script src=\"js/app.js\"></script>\n</body>\n</html>\n"
  },
  {
    "path": "app_frontend/static/plugin/jQuery-File-Upload-9.18.0/basic-plus.html",
    "content": "<!DOCTYPE HTML>\n<!--\n/*\n * jQuery File Upload Plugin Basic Plus Demo\n * https://github.com/blueimp/jQuery-File-Upload\n *\n * Copyright 2013, Sebastian Tschan\n * https://blueimp.net\n *\n * Licensed under the MIT license:\n * https://opensource.org/licenses/MIT\n */\n-->\n<html lang=\"en\">\n<head>\n<!-- Force latest IE rendering engine or ChromeFrame if installed -->\n<!--[if IE]><meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge,chrome=1\"><![endif]-->\n<meta charset=\"utf-8\">\n<title>jQuery File Upload Demo - Basic Plus version</title>\n<meta name=\"description\" content=\"File Upload widget with multiple file selection, drag&amp;drop support, progress bar, validation and preview images, audio and video for jQuery. Supports cross-domain, chunked and resumable file uploads. Works with any server-side platform (Google App Engine, PHP, Python, Ruby on Rails, Java, etc.) that supports standard HTML form file uploads.\">\n<meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n<!-- Bootstrap styles -->\n<link rel=\"stylesheet\" href=\"//netdna.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.min.css\">\n<!-- Generic page styles -->\n<link rel=\"stylesheet\" href=\"css/style.css\">\n<!-- CSS to style the file input field as button and adjust the Bootstrap progress bars -->\n<link rel=\"stylesheet\" href=\"css/jquery.fileupload.css\">\n</head>\n<body>\n<div class=\"navbar navbar-default navbar-fixed-top\">\n    <div class=\"container\">\n        <div class=\"navbar-header\">\n            <button type=\"button\" class=\"navbar-toggle\" data-toggle=\"collapse\" data-target=\".navbar-fixed-top .navbar-collapse\">\n                <span class=\"icon-bar\"></span>\n                <span class=\"icon-bar\"></span>\n                <span class=\"icon-bar\"></span>\n            </button>\n            <a class=\"navbar-brand\" href=\"https://github.com/blueimp/jQuery-File-Upload\">jQuery File Upload</a>\n        </div>\n        <div class=\"navbar-collapse collapse\">\n            <ul class=\"nav navbar-nav\">\n                <li><a href=\"https://github.com/blueimp/jQuery-File-Upload/tags\">Download</a></li>\n                <li><a href=\"https://github.com/blueimp/jQuery-File-Upload\">Source Code</a></li>\n                <li><a href=\"https://github.com/blueimp/jQuery-File-Upload/wiki\">Documentation</a></li>\n                <li><a href=\"https://blueimp.net\">&copy; Sebastian Tschan</a></li>\n            </ul>\n        </div>\n    </div>\n</div>\n<div class=\"container\">\n    <h1>jQuery File Upload Demo</h1>\n    <h2 class=\"lead\">Basic Plus version</h2>\n    <ul class=\"nav nav-tabs\">\n        <li><a href=\"basic.html\">Basic</a></li>\n        <li class=\"active\"><a href=\"basic-plus.html\">Basic Plus</a></li>\n        <li><a href=\"index.html\">Basic Plus UI</a></li>\n        <li><a href=\"angularjs.html\">AngularJS</a></li>\n        <li><a href=\"jquery-ui.html\">jQuery UI</a></li>\n    </ul>\n    <br>\n    <blockquote>\n        <p>File Upload widget with multiple file selection, drag&amp;drop support, progress bar, validation and preview images, audio and video for jQuery.<br>\n        Supports cross-domain, chunked and resumable file uploads and client-side image resizing.<br>\n        Works with any server-side platform (PHP, Python, Ruby on Rails, Java, Node.js, Go etc.) that supports standard HTML form file uploads.</p>\n    </blockquote>\n    <br>\n    <!-- The fileinput-button span is used to style the file input field as button -->\n    <span class=\"btn btn-success fileinput-button\">\n        <i class=\"glyphicon glyphicon-plus\"></i>\n        <span>Add files...</span>\n        <!-- The file input field used as target for the file upload widget -->\n        <input id=\"fileupload\" type=\"file\" name=\"files[]\" multiple>\n    </span>\n    <br>\n    <br>\n    <!-- The global progress bar -->\n    <div id=\"progress\" class=\"progress\">\n        <div class=\"progress-bar progress-bar-success\"></div>\n    </div>\n    <!-- The container for the uploaded files -->\n    <div id=\"files\" class=\"files\"></div>\n    <br>\n    <div class=\"panel panel-default\">\n        <div class=\"panel-heading\">\n            <h3 class=\"panel-title\">Demo Notes</h3>\n        </div>\n        <div class=\"panel-body\">\n            <ul>\n                <li>The maximum file size for uploads in this demo is <strong>999 KB</strong> (default file size is unlimited).</li>\n                <li>Only image files (<strong>JPG, GIF, PNG</strong>) are allowed in this demo (by default there is no file type restriction).</li>\n                <li>Uploaded files will be deleted automatically after <strong>5 minutes or less</strong> (demo files are stored in memory).</li>\n                <li>You can <strong>drag &amp; drop</strong> files from your desktop on this webpage (see <a href=\"https://github.com/blueimp/jQuery-File-Upload/wiki/Browser-support\">Browser support</a>).</li>\n                <li>Please refer to the <a href=\"https://github.com/blueimp/jQuery-File-Upload\">project website</a> and <a href=\"https://github.com/blueimp/jQuery-File-Upload/wiki\">documentation</a> for more information.</li>\n                <li>Built with the <a href=\"http://getbootstrap.com/\">Bootstrap</a> CSS framework and Icons from <a href=\"http://glyphicons.com/\">Glyphicons</a>.</li>\n            </ul>\n        </div>\n    </div>\n</div>\n<script src=\"//ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js\"></script>\n<!-- The jQuery UI widget factory, can be omitted if jQuery UI is already included -->\n<script src=\"js/vendor/jquery.ui.widget.js\"></script>\n<!-- The Load Image plugin is included for the preview images and image resizing functionality -->\n<script src=\"//blueimp.github.io/JavaScript-Load-Image/js/load-image.all.min.js\"></script>\n<!-- The Canvas to Blob plugin is included for image resizing functionality -->\n<script src=\"//blueimp.github.io/JavaScript-Canvas-to-Blob/js/canvas-to-blob.min.js\"></script>\n<!-- Bootstrap JS is not required, but included for the responsive demo navigation -->\n<script src=\"//netdna.bootstrapcdn.com/bootstrap/3.2.0/js/bootstrap.min.js\"></script>\n<!-- The Iframe Transport is required for browsers without support for XHR file uploads -->\n<script src=\"js/jquery.iframe-transport.js\"></script>\n<!-- The basic File Upload plugin -->\n<script src=\"js/jquery.fileupload.js\"></script>\n<!-- The File Upload processing plugin -->\n<script src=\"js/jquery.fileupload-process.js\"></script>\n<!-- The File Upload image preview & resize plugin -->\n<script src=\"js/jquery.fileupload-image.js\"></script>\n<!-- The File Upload audio preview plugin -->\n<script src=\"js/jquery.fileupload-audio.js\"></script>\n<!-- The File Upload video preview plugin -->\n<script src=\"js/jquery.fileupload-video.js\"></script>\n<!-- The File Upload validation plugin -->\n<script src=\"js/jquery.fileupload-validate.js\"></script>\n<script>\n/*jslint unparam: true, regexp: true */\n/*global window, $ */\n$(function () {\n    'use strict';\n    // Change this to the location of your server-side upload handler:\n    var url = window.location.hostname === 'blueimp.github.io' ?\n                '//jquery-file-upload.appspot.com/' : 'server/php/',\n        uploadButton = $('<button/>')\n            .addClass('btn btn-primary')\n            .prop('disabled', true)\n            .text('Processing...')\n            .on('click', function () {\n                var $this = $(this),\n                    data = $this.data();\n                $this\n                    .off('click')\n                    .text('Abort')\n                    .on('click', function () {\n                        $this.remove();\n                        data.abort();\n                    });\n                data.submit().always(function () {\n                    $this.remove();\n                });\n            });\n    $('#fileupload').fileupload({\n        url: url,\n        dataType: 'json',\n        autoUpload: false,\n        acceptFileTypes: /(\\.|\\/)(gif|jpe?g|png)$/i,\n        maxFileSize: 999000,\n        // Enable image resizing, except for Android and Opera,\n        // which actually support image resizing, but fail to\n        // send Blob objects via XHR requests:\n        disableImageResize: /Android(?!.*Chrome)|Opera/\n            .test(window.navigator.userAgent),\n        previewMaxWidth: 100,\n        previewMaxHeight: 100,\n        previewCrop: true\n    }).on('fileuploadadd', function (e, data) {\n        data.context = $('<div/>').appendTo('#files');\n        $.each(data.files, function (index, file) {\n            var node = $('<p/>')\n                    .append($('<span/>').text(file.name));\n            if (!index) {\n                node\n                    .append('<br>')\n                    .append(uploadButton.clone(true).data(data));\n            }\n            node.appendTo(data.context);\n        });\n    }).on('fileuploadprocessalways', function (e, data) {\n        var index = data.index,\n            file = data.files[index],\n            node = $(data.context.children()[index]);\n        if (file.preview) {\n            node\n                .prepend('<br>')\n                .prepend(file.preview);\n        }\n        if (file.error) {\n            node\n                .append('<br>')\n                .append($('<span class=\"text-danger\"/>').text(file.error));\n        }\n        if (index + 1 === data.files.length) {\n            data.context.find('button')\n                .text('Upload')\n                .prop('disabled', !!data.files.error);\n        }\n    }).on('fileuploadprogressall', function (e, data) {\n        var progress = parseInt(data.loaded / data.total * 100, 10);\n        $('#progress .progress-bar').css(\n            'width',\n            progress + '%'\n        );\n    }).on('fileuploaddone', function (e, data) {\n        $.each(data.result.files, function (index, file) {\n            if (file.url) {\n                var link = $('<a>')\n                    .attr('target', '_blank')\n                    .prop('href', file.url);\n                $(data.context.children()[index])\n                    .wrap(link);\n            } else if (file.error) {\n                var error = $('<span class=\"text-danger\"/>').text(file.error);\n                $(data.context.children()[index])\n                    .append('<br>')\n                    .append(error);\n            }\n        });\n    }).on('fileuploadfail', function (e, data) {\n        $.each(data.files, function (index) {\n            var error = $('<span class=\"text-danger\"/>').text('File upload failed.');\n            $(data.context.children()[index])\n                .append('<br>')\n                .append(error);\n        });\n    }).prop('disabled', !$.support.fileInput)\n        .parent().addClass($.support.fileInput ? undefined : 'disabled');\n});\n</script>\n</body>\n</html>\n"
  },
  {
    "path": "app_frontend/static/plugin/jQuery-File-Upload-9.18.0/basic.html",
    "content": "<!DOCTYPE HTML>\n<!--\n/*\n * jQuery File Upload Plugin Basic Demo\n * https://github.com/blueimp/jQuery-File-Upload\n *\n * Copyright 2013, Sebastian Tschan\n * https://blueimp.net\n *\n * Licensed under the MIT license:\n * https://opensource.org/licenses/MIT\n */\n-->\n<html lang=\"en\">\n<head>\n<!-- Force latest IE rendering engine or ChromeFrame if installed -->\n<!--[if IE]><meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge,chrome=1\"><![endif]-->\n<meta charset=\"utf-8\">\n<title>jQuery File Upload Demo - Basic version</title>\n<meta name=\"description\" content=\"File Upload widget with multiple file selection, drag&amp;drop support and progress bar for jQuery. Supports cross-domain, chunked and resumable file uploads. Works with any server-side platform (PHP, Python, Ruby on Rails, Java, Node.js, Go etc.) that supports standard HTML form file uploads.\">\n<meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n<!-- Bootstrap styles -->\n<link rel=\"stylesheet\" href=\"//netdna.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.min.css\">\n<!-- Generic page styles -->\n<link rel=\"stylesheet\" href=\"css/style.css\">\n<!-- CSS to style the file input field as button and adjust the Bootstrap progress bars -->\n<link rel=\"stylesheet\" href=\"css/jquery.fileupload.css\">\n</head>\n<body>\n<div class=\"navbar navbar-default navbar-fixed-top\">\n    <div class=\"container\">\n        <div class=\"navbar-header\">\n            <button type=\"button\" class=\"navbar-toggle\" data-toggle=\"collapse\" data-target=\".navbar-fixed-top .navbar-collapse\">\n                <span class=\"icon-bar\"></span>\n                <span class=\"icon-bar\"></span>\n                <span class=\"icon-bar\"></span>\n            </button>\n            <a class=\"navbar-brand\" href=\"https://github.com/blueimp/jQuery-File-Upload\">jQuery File Upload</a>\n        </div>\n        <div class=\"navbar-collapse collapse\">\n            <ul class=\"nav navbar-nav\">\n                <li><a href=\"https://github.com/blueimp/jQuery-File-Upload/tags\">Download</a></li>\n                <li><a href=\"https://github.com/blueimp/jQuery-File-Upload\">Source Code</a></li>\n                <li><a href=\"https://github.com/blueimp/jQuery-File-Upload/wiki\">Documentation</a></li>\n                <li><a href=\"https://blueimp.net\">&copy; Sebastian Tschan</a></li>\n            </ul>\n        </div>\n    </div>\n</div>\n<div class=\"container\">\n    <h1>jQuery File Upload Demo</h1>\n    <h2 class=\"lead\">Basic version</h2>\n    <ul class=\"nav nav-tabs\">\n        <li class=\"active\"><a href=\"basic.html\">Basic</a></li>\n        <li><a href=\"basic-plus.html\">Basic Plus</a></li>\n        <li><a href=\"index.html\">Basic Plus UI</a></li>\n        <li><a href=\"angularjs.html\">AngularJS</a></li>\n        <li><a href=\"jquery-ui.html\">jQuery UI</a></li>\n    </ul>\n    <br>\n    <blockquote>\n        <p>File Upload widget with multiple file selection, drag&amp;drop support and progress bar for jQuery.<br>\n        Supports cross-domain, chunked and resumable file uploads.<br>\n        Works with any server-side platform (PHP, Python, Ruby on Rails, Java, Node.js, Go etc.) that supports standard HTML form file uploads.</p>\n    </blockquote>\n    <br>\n    <!-- The fileinput-button span is used to style the file input field as button -->\n    <span class=\"btn btn-success fileinput-button\">\n        <i class=\"glyphicon glyphicon-plus\"></i>\n        <span>Select files...</span>\n        <!-- The file input field used as target for the file upload widget -->\n        <input id=\"fileupload\" type=\"file\" name=\"files[]\" multiple>\n    </span>\n    <br>\n    <br>\n    <!-- The global progress bar -->\n    <div id=\"progress\" class=\"progress\">\n        <div class=\"progress-bar progress-bar-success\"></div>\n    </div>\n    <!-- The container for the uploaded files -->\n    <div id=\"files\" class=\"files\"></div>\n    <br>\n    <div class=\"panel panel-default\">\n        <div class=\"panel-heading\">\n            <h3 class=\"panel-title\">Demo Notes</h3>\n        </div>\n        <div class=\"panel-body\">\n            <ul>\n                <li>The maximum file size for uploads in this demo is <strong>999 KB</strong> (default file size is unlimited).</li>\n                <li>Only image files (<strong>JPG, GIF, PNG</strong>) are allowed in this demo (by default there is no file type restriction).</li>\n                <li>Uploaded files will be deleted automatically after <strong>5 minutes or less</strong> (demo files are stored in memory).</li>\n                <li>You can <strong>drag &amp; drop</strong> files from your desktop on this webpage (see <a href=\"https://github.com/blueimp/jQuery-File-Upload/wiki/Browser-support\">Browser support</a>).</li>\n                <li>Please refer to the <a href=\"https://github.com/blueimp/jQuery-File-Upload\">project website</a> and <a href=\"https://github.com/blueimp/jQuery-File-Upload/wiki\">documentation</a> for more information.</li>\n                <li>Built with the <a href=\"http://getbootstrap.com/\">Bootstrap</a> CSS framework and Icons from <a href=\"http://glyphicons.com/\">Glyphicons</a>.</li>\n            </ul>\n        </div>\n    </div>\n</div>\n<script src=\"//ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js\"></script>\n<!-- The jQuery UI widget factory, can be omitted if jQuery UI is already included -->\n<script src=\"js/vendor/jquery.ui.widget.js\"></script>\n<!-- The Iframe Transport is required for browsers without support for XHR file uploads -->\n<script src=\"js/jquery.iframe-transport.js\"></script>\n<!-- The basic File Upload plugin -->\n<script src=\"js/jquery.fileupload.js\"></script>\n<!-- Bootstrap JS is not required, but included for the responsive demo navigation -->\n<script src=\"//netdna.bootstrapcdn.com/bootstrap/3.2.0/js/bootstrap.min.js\"></script>\n<script>\n/*jslint unparam: true */\n/*global window, $ */\n$(function () {\n    'use strict';\n    // Change this to the location of your server-side upload handler:\n    var url = window.location.hostname === 'blueimp.github.io' ?\n                '//jquery-file-upload.appspot.com/' : 'server/php/';\n    $('#fileupload').fileupload({\n        url: url,\n        dataType: 'json',\n        done: function (e, data) {\n            $.each(data.result.files, function (index, file) {\n                $('<p/>').text(file.name).appendTo('#files');\n            });\n        },\n        progressall: function (e, data) {\n            var progress = parseInt(data.loaded / data.total * 100, 10);\n            $('#progress .progress-bar').css(\n                'width',\n                progress + '%'\n            );\n        }\n    }).prop('disabled', !$.support.fileInput)\n        .parent().addClass($.support.fileInput ? undefined : 'disabled');\n});\n</script>\n</body>\n</html>\n"
  },
  {
    "path": "app_frontend/static/plugin/jQuery-File-Upload-9.18.0/bower-version-update.js",
    "content": "#!/usr/bin/env node\n\n'use strict';\n\nvar path = require('path');\nvar packageJSON = require(path.join(__dirname, 'package.json'));\nvar bowerFile = path.join(__dirname, 'bower.json');\nvar bowerJSON = require('bower-json').parse(\n  require(bowerFile),\n  {normalize: true}\n);\nbowerJSON.version = packageJSON.version;\nrequire('fs').writeFileSync(\n  bowerFile,\n  JSON.stringify(bowerJSON, null, 2) + '\\n'\n);\n"
  },
  {
    "path": "app_frontend/static/plugin/jQuery-File-Upload-9.18.0/bower.json",
    "content": "{\n  \"name\": \"blueimp-file-upload\",\n  \"version\": \"9.18.0\",\n  \"title\": \"jQuery File Upload\",\n  \"description\": \"File Upload widget with multiple file selection, drag&amp;drop support, progress bar, validation and preview images.\",\n  \"keywords\": [\n    \"jquery\",\n    \"file\",\n    \"upload\",\n    \"widget\",\n    \"multiple\",\n    \"selection\",\n    \"drag\",\n    \"drop\",\n    \"progress\",\n    \"preview\",\n    \"cross-domain\",\n    \"cross-site\",\n    \"chunk\",\n    \"resume\",\n    \"gae\",\n    \"go\",\n    \"python\",\n    \"php\",\n    \"bootstrap\"\n  ],\n  \"homepage\": \"https://github.com/blueimp/jQuery-File-Upload\",\n  \"author\": {\n    \"name\": \"Sebastian Tschan\",\n    \"url\": \"https://blueimp.net\"\n  },\n  \"maintainers\": [\n    {\n      \"name\": \"Sebastian Tschan\",\n      \"url\": \"https://blueimp.net\"\n    }\n  ],\n  \"repository\": {\n    \"type\": \"git\",\n    \"url\": \"git://github.com/blueimp/jQuery-File-Upload.git\"\n  },\n  \"bugs\": \"https://github.com/blueimp/jQuery-File-Upload/issues\",\n  \"license\": \"MIT\",\n  \"dependencies\": {\n    \"jquery\": \">=1.6\",\n    \"blueimp-tmpl\": \">=2.5.4\",\n    \"blueimp-load-image\": \">=1.13.0\",\n    \"blueimp-canvas-to-blob\": \">=2.1.1\"\n  },\n  \"main\": [\n    \"js/jquery.fileupload.js\"\n  ],\n  \"ignore\": [\n    \"/*.*\",\n    \"/cors\",\n    \"css/demo-ie8.css\",\n    \"css/demo.css\",\n    \"css/style.css\",\n    \"js/app.js\",\n    \"js/main.js\",\n    \"server\",\n    \"test\"\n  ]\n}\n"
  },
  {
    "path": "app_frontend/static/plugin/jQuery-File-Upload-9.18.0/cors/postmessage.html",
    "content": "<!DOCTYPE HTML>\n<!--\n/*\n * jQuery File Upload Plugin postMessage API\n * https://github.com/blueimp/jQuery-File-Upload\n *\n * Copyright 2011, Sebastian Tschan\n * https://blueimp.net\n *\n * Licensed under the MIT license:\n * https://opensource.org/licenses/MIT\n */\n-->\n<html lang=\"en\">\n<head>\n<meta charset=\"utf-8\">\n<title>jQuery File Upload Plugin postMessage API</title>\n<script src=\"//ajax.googleapis.com/ajax/libs/jquery/1.10.1/jquery.min.js\"></script>\n</head>\n<body>\n<script>\n/*jslint unparam: true, regexp: true */\n/*global $, Blob, FormData, location */\n'use strict';\nvar origin = /^http:\\/\\/example.org/,\n    target = new RegExp('^(http(s)?:)?\\\\/\\\\/' + location.host + '\\\\/');\n$(window).on('message', function (e) {\n    e = e.originalEvent;\n    var s = e.data,\n        xhr = $.ajaxSettings.xhr(),\n        f;\n    if (!origin.test(e.origin)) {\n        throw new Error('Origin \"' + e.origin + '\" does not match ' + origin);\n    }\n    if (!target.test(e.data.url)) {\n        throw new Error('Target \"' + e.data.url + '\" does not match ' + target);\n    }\n    $(xhr.upload).on('progress', function (ev) {\n        ev = ev.originalEvent;\n        e.source.postMessage({\n            id: s.id,\n            type: ev.type,\n            timeStamp: ev.timeStamp,\n            lengthComputable: ev.lengthComputable,\n            loaded: ev.loaded,\n            total: ev.total\n        }, e.origin);\n    });\n    s.xhr = function () {\n        return xhr;\n    };\n    if (!(s.data instanceof Blob)) {\n        f = new FormData();\n        $.each(s.data, function (i, v) {\n            f.append(v.name, v.value);\n        });\n        s.data = f;\n    }\n    $.ajax(s).always(function (result, statusText, jqXHR) {\n        if (!jqXHR.done) {\n            jqXHR = result;\n            result = null;\n        }\n        e.source.postMessage({\n            id: s.id,\n            status: jqXHR.status,\n            statusText: statusText,\n            result: result,\n            headers: jqXHR.getAllResponseHeaders()\n        }, e.origin);\n    });\n});\n</script>\n</body>\n</html>\n"
  },
  {
    "path": "app_frontend/static/plugin/jQuery-File-Upload-9.18.0/cors/result.html",
    "content": "<!DOCTYPE HTML>\n<!--\n/*\n * jQuery Iframe Transport Plugin Redirect Page\n * https://github.com/blueimp/jQuery-File-Upload\n *\n * Copyright 2010, Sebastian Tschan\n * https://blueimp.net\n *\n * Licensed under the MIT license:\n * https://opensource.org/licenses/MIT\n */\n-->\n<html lang=\"en\">\n<head>\n<meta charset=\"utf-8\">\n<title>jQuery Iframe Transport Plugin Redirect Page</title>\n</head>\n<body>\n<script>\ndocument.body.innerText=document.body.textContent=decodeURIComponent(window.location.search.slice(1));\n</script>\n</body>\n</html>\n"
  },
  {
    "path": "app_frontend/static/plugin/jQuery-File-Upload-9.18.0/css/demo-ie8.css",
    "content": "@charset \"UTF-8\";\n/*\n * jQuery File Upload Demo CSS Fixes for IE<9\n * https://github.com/blueimp/jQuery-File-Upload\n *\n * Copyright 2013, Sebastian Tschan\n * https://blueimp.net\n *\n * Licensed under the MIT license:\n * https://opensource.org/licenses/MIT\n */\n\n.navigation {\n  list-style: none;\n  padding: 0;\n  margin: 1em 0;\n}\n.navigation li {\n  display: inline;\n  margin-right: 10px;\n}\n"
  },
  {
    "path": "app_frontend/static/plugin/jQuery-File-Upload-9.18.0/css/demo.css",
    "content": "@charset \"UTF-8\";\n/*\n * jQuery File Upload Demo CSS\n * https://github.com/blueimp/jQuery-File-Upload\n *\n * Copyright 2013, Sebastian Tschan\n * https://blueimp.net\n *\n * Licensed under the MIT license:\n * https://opensource.org/licenses/MIT\n */\n\nbody {\n  max-width: 750px;\n  margin: 0 auto;\n  padding: 1em;\n  font-family: \"Lucida Grande\", \"Lucida Sans Unicode\", Arial, sans-serif;\n  font-size: 1em;\n  line-height: 1.4em;\n  background: #222;\n  color: #fff;\n  -webkit-text-size-adjust: 100%;\n      -ms-text-size-adjust: 100%;\n}\na {\n  color: orange;\n  text-decoration: none;\n}\nimg {\n  border: 0;\n  vertical-align: middle;\n}\nh1 {\n  line-height: 1em;\n}\nblockquote {\n  padding: 0 0 0 15px;\n  margin: 0 0 20px;\n  border-left: 5px solid #eee;\n}\ntable {\n  width: 100%;\n  margin: 10px 0;\n}\n\n.fileupload-progress {\n\tmargin: 10px 0;\n}\n.fileupload-progress .progress-extended {\n\tmargin-top: 5px;\n}\n.error {\n  color: red;\n}\n\n@media (min-width: 481px) {\n  .navigation {\n    list-style: none;\n    padding: 0;\n  }\n  .navigation li {\n    display: inline-block;\n  }\n  .navigation li:not(:first-child):before {\n    content: \"| \";\n  }\n}\n"
  },
  {
    "path": "app_frontend/static/plugin/jQuery-File-Upload-9.18.0/css/jquery.fileupload-noscript.css",
    "content": "@charset \"UTF-8\";\n/*\n * jQuery File Upload Plugin NoScript CSS\n * https://github.com/blueimp/jQuery-File-Upload\n *\n * Copyright 2013, Sebastian Tschan\n * https://blueimp.net\n *\n * Licensed under the MIT license:\n * https://opensource.org/licenses/MIT\n */\n\n.fileinput-button input {\n  position: static;\n  opacity: 1;\n  filter: none;\n  font-size: inherit !important;\n  direction: inherit;\n}\n.fileinput-button span {\n  display: none;\n}\n"
  },
  {
    "path": "app_frontend/static/plugin/jQuery-File-Upload-9.18.0/css/jquery.fileupload-ui-noscript.css",
    "content": "@charset \"UTF-8\";\n/*\n * jQuery File Upload UI Plugin NoScript CSS\n * https://github.com/blueimp/jQuery-File-Upload\n *\n * Copyright 2012, Sebastian Tschan\n * https://blueimp.net\n *\n * Licensed under the MIT license:\n * https://opensource.org/licenses/MIT\n */\n\n.fileinput-button i,\n.fileupload-buttonbar .delete,\n.fileupload-buttonbar .toggle {\n  display: none;\n}\n"
  },
  {
    "path": "app_frontend/static/plugin/jQuery-File-Upload-9.18.0/css/jquery.fileupload-ui.css",
    "content": "@charset \"UTF-8\";\n/*\n * jQuery File Upload UI Plugin CSS\n * https://github.com/blueimp/jQuery-File-Upload\n *\n * Copyright 2010, Sebastian Tschan\n * https://blueimp.net\n *\n * Licensed under the MIT license:\n * https://opensource.org/licenses/MIT\n */\n\n.fileupload-buttonbar .btn,\n.fileupload-buttonbar .toggle {\n  margin-bottom: 5px;\n}\n.progress-animated .progress-bar,\n.progress-animated .bar {\n  background: url(\"../img/progressbar.gif\") !important;\n  filter: none;\n}\n.fileupload-process {\n  float: right;\n  display: none;\n}\n.fileupload-processing .fileupload-process,\n.files .processing .preview {\n  display: block;\n  width: 32px;\n  height: 32px;\n  background: url(\"../img/loading.gif\") center no-repeat;\n  background-size: contain;\n}\n.files audio,\n.files video {\n  max-width: 300px;\n}\n\n@media (max-width: 767px) {\n  .fileupload-buttonbar .toggle,\n  .files .toggle,\n  .files .btn span {\n    display: none;\n  }\n  .files .name {\n    width: 80px;\n    word-wrap: break-word;\n  }\n  .files audio,\n  .files video {\n    max-width: 80px;\n  }\n  .files img,\n  .files canvas {\n    max-width: 100%;\n  }\n}\n"
  },
  {
    "path": "app_frontend/static/plugin/jQuery-File-Upload-9.18.0/css/jquery.fileupload.css",
    "content": "@charset \"UTF-8\";\n/*\n * jQuery File Upload Plugin CSS\n * https://github.com/blueimp/jQuery-File-Upload\n *\n * Copyright 2013, Sebastian Tschan\n * https://blueimp.net\n *\n * Licensed under the MIT license:\n * https://opensource.org/licenses/MIT\n */\n\n.fileinput-button {\n  position: relative;\n  overflow: hidden;\n  display: inline-block;\n}\n.fileinput-button input {\n  position: absolute;\n  top: 0;\n  right: 0;\n  margin: 0;\n  opacity: 0;\n  -ms-filter: 'alpha(opacity=0)';\n  font-size: 200px !important;\n  direction: ltr;\n  cursor: pointer;\n}\n\n/* Fixes for IE < 8 */\n@media screen\\9 {\n  .fileinput-button input {\n    filter: alpha(opacity=0);\n    font-size: 100%;\n    height: 100%;\n  }\n}\n"
  },
  {
    "path": "app_frontend/static/plugin/jQuery-File-Upload-9.18.0/css/style.css",
    "content": "@charset \"UTF-8\";\n/*\n * jQuery File Upload Plugin CSS Example\n * https://github.com/blueimp/jQuery-File-Upload\n *\n * Copyright 2013, Sebastian Tschan\n * https://blueimp.net\n *\n * Licensed under the MIT license:\n * https://opensource.org/licenses/MIT\n */\n\nbody {\n  padding-top: 60px;\n}\n"
  },
  {
    "path": "app_frontend/static/plugin/jQuery-File-Upload-9.18.0/index.html",
    "content": "<!DOCTYPE HTML>\n<!--\n/*\n * jQuery File Upload Plugin Demo\n * https://github.com/blueimp/jQuery-File-Upload\n *\n * Copyright 2010, Sebastian Tschan\n * https://blueimp.net\n *\n * Licensed under the MIT license:\n * https://opensource.org/licenses/MIT\n */\n-->\n<html lang=\"en\">\n<head>\n<!-- Force latest IE rendering engine or ChromeFrame if installed -->\n<!--[if IE]>\n<meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge,chrome=1\">\n<![endif]-->\n<meta charset=\"utf-8\">\n<title>jQuery File Upload Demo</title>\n<meta name=\"description\" content=\"File Upload widget with multiple file selection, drag&amp;drop support, progress bars, validation and preview images, audio and video for jQuery. Supports cross-domain, chunked and resumable file uploads and client-side image resizing. Works with any server-side platform (PHP, Python, Ruby on Rails, Java, Node.js, Go etc.) that supports standard HTML form file uploads.\">\n<meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n<!-- Bootstrap styles -->\n<link rel=\"stylesheet\" href=\"//netdna.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.min.css\">\n<!-- Generic page styles -->\n<link rel=\"stylesheet\" href=\"css/style.css\">\n<!-- blueimp Gallery styles -->\n<link rel=\"stylesheet\" href=\"//blueimp.github.io/Gallery/css/blueimp-gallery.min.css\">\n<!-- CSS to style the file input field as button and adjust the Bootstrap progress bars -->\n<link rel=\"stylesheet\" href=\"css/jquery.fileupload.css\">\n<link rel=\"stylesheet\" href=\"css/jquery.fileupload-ui.css\">\n<!-- CSS adjustments for browsers with JavaScript disabled -->\n<noscript><link rel=\"stylesheet\" href=\"css/jquery.fileupload-noscript.css\"></noscript>\n<noscript><link rel=\"stylesheet\" href=\"css/jquery.fileupload-ui-noscript.css\"></noscript>\n</head>\n<body>\n<div class=\"navbar navbar-default navbar-fixed-top\">\n    <div class=\"container\">\n        <div class=\"navbar-header\">\n            <button type=\"button\" class=\"navbar-toggle\" data-toggle=\"collapse\" data-target=\".navbar-fixed-top .navbar-collapse\">\n                <span class=\"icon-bar\"></span>\n                <span class=\"icon-bar\"></span>\n                <span class=\"icon-bar\"></span>\n            </button>\n            <a class=\"navbar-brand\" href=\"https://github.com/blueimp/jQuery-File-Upload\">jQuery File Upload</a>\n        </div>\n        <div class=\"navbar-collapse collapse\">\n            <ul class=\"nav navbar-nav\">\n                <li><a href=\"https://github.com/blueimp/jQuery-File-Upload/tags\">Download</a></li>\n                <li><a href=\"https://github.com/blueimp/jQuery-File-Upload\">Source Code</a></li>\n                <li><a href=\"https://github.com/blueimp/jQuery-File-Upload/wiki\">Documentation</a></li>\n                <li><a href=\"https://blueimp.net\">&copy; Sebastian Tschan</a></li>\n            </ul>\n        </div>\n    </div>\n</div>\n<div class=\"container\">\n    <h1>jQuery File Upload Demo</h1>\n    <h2 class=\"lead\">Basic Plus UI version</h2>\n    <ul class=\"nav nav-tabs\">\n        <li><a href=\"basic.html\">Basic</a></li>\n        <li><a href=\"basic-plus.html\">Basic Plus</a></li>\n        <li class=\"active\"><a href=\"index.html\">Basic Plus UI</a></li>\n        <li><a href=\"angularjs.html\">AngularJS</a></li>\n        <li><a href=\"jquery-ui.html\">jQuery UI</a></li>\n    </ul>\n    <br>\n    <blockquote>\n        <p>File Upload widget with multiple file selection, drag&amp;drop support, progress bars, validation and preview images, audio and video for jQuery.<br>\n        Supports cross-domain, chunked and resumable file uploads and client-side image resizing.<br>\n        Works with any server-side platform (PHP, Python, Ruby on Rails, Java, Node.js, Go etc.) that supports standard HTML form file uploads.</p>\n    </blockquote>\n    <br>\n    <!-- The file upload form used as target for the file upload widget -->\n    <form id=\"fileupload\" action=\"//jquery-file-upload.appspot.com/\" method=\"POST\" enctype=\"multipart/form-data\">\n        <!-- Redirect browsers with JavaScript disabled to the origin page -->\n        <noscript><input type=\"hidden\" name=\"redirect\" value=\"https://blueimp.github.io/jQuery-File-Upload/\"></noscript>\n        <!-- The fileupload-buttonbar contains buttons to add/delete files and start/cancel the upload -->\n        <div class=\"row fileupload-buttonbar\">\n            <div class=\"col-lg-7\">\n                <!-- The fileinput-button span is used to style the file input field as button -->\n                <span class=\"btn btn-success fileinput-button\">\n                    <i class=\"glyphicon glyphicon-plus\"></i>\n                    <span>Add files...</span>\n                    <input type=\"file\" name=\"files[]\" multiple>\n                </span>\n                <button type=\"submit\" class=\"btn btn-primary start\">\n                    <i class=\"glyphicon glyphicon-upload\"></i>\n                    <span>Start upload</span>\n                </button>\n                <button type=\"reset\" class=\"btn btn-warning cancel\">\n                    <i class=\"glyphicon glyphicon-ban-circle\"></i>\n                    <span>Cancel upload</span>\n                </button>\n                <button type=\"button\" class=\"btn btn-danger delete\">\n                    <i class=\"glyphicon glyphicon-trash\"></i>\n                    <span>Delete</span>\n                </button>\n                <input type=\"checkbox\" class=\"toggle\">\n                <!-- The global file processing state -->\n                <span class=\"fileupload-process\"></span>\n            </div>\n            <!-- The global progress state -->\n            <div class=\"col-lg-5 fileupload-progress fade\">\n                <!-- The global progress bar -->\n                <div class=\"progress progress-striped active\" role=\"progressbar\" aria-valuemin=\"0\" aria-valuemax=\"100\">\n                    <div class=\"progress-bar progress-bar-success\" style=\"width:0%;\"></div>\n                </div>\n                <!-- The extended global progress state -->\n                <div class=\"progress-extended\">&nbsp;</div>\n            </div>\n        </div>\n        <!-- The table listing the files available for upload/download -->\n        <table role=\"presentation\" class=\"table table-striped\"><tbody class=\"files\"></tbody></table>\n    </form>\n    <br>\n    <div class=\"panel panel-default\">\n        <div class=\"panel-heading\">\n            <h3 class=\"panel-title\">Demo Notes</h3>\n        </div>\n        <div class=\"panel-body\">\n            <ul>\n                <li>The maximum file size for uploads in this demo is <strong>999 KB</strong> (default file size is unlimited).</li>\n                <li>Only image files (<strong>JPG, GIF, PNG</strong>) are allowed in this demo (by default there is no file type restriction).</li>\n                <li>Uploaded files will be deleted automatically after <strong>5 minutes or less</strong> (demo files are stored in memory).</li>\n                <li>You can <strong>drag &amp; drop</strong> files from your desktop on this webpage (see <a href=\"https://github.com/blueimp/jQuery-File-Upload/wiki/Browser-support\">Browser support</a>).</li>\n                <li>Please refer to the <a href=\"https://github.com/blueimp/jQuery-File-Upload\">project website</a> and <a href=\"https://github.com/blueimp/jQuery-File-Upload/wiki\">documentation</a> for more information.</li>\n                <li>Built with the <a href=\"http://getbootstrap.com/\">Bootstrap</a> CSS framework and Icons from <a href=\"http://glyphicons.com/\">Glyphicons</a>.</li>\n            </ul>\n        </div>\n    </div>\n</div>\n<!-- The blueimp Gallery widget -->\n<div id=\"blueimp-gallery\" class=\"blueimp-gallery blueimp-gallery-controls\" data-filter=\":even\">\n    <div class=\"slides\"></div>\n    <h3 class=\"title\"></h3>\n    <a class=\"prev\">‹</a>\n    <a class=\"next\">›</a>\n    <a class=\"close\">×</a>\n    <a class=\"play-pause\"></a>\n    <ol class=\"indicator\"></ol>\n</div>\n<!-- The template to display files available for upload -->\n<script id=\"template-upload\" type=\"text/x-tmpl\">\n{% for (var i=0, file; file=o.files[i]; i++) { %}\n    <tr class=\"template-upload fade\">\n        <td>\n            <span class=\"preview\"></span>\n        </td>\n        <td>\n            <p class=\"name\">{%=file.name%}</p>\n            <strong class=\"error text-danger\"></strong>\n        </td>\n        <td>\n            <p class=\"size\">Processing...</p>\n            <div class=\"progress progress-striped active\" role=\"progressbar\" aria-valuemin=\"0\" aria-valuemax=\"100\" aria-valuenow=\"0\"><div class=\"progress-bar progress-bar-success\" style=\"width:0%;\"></div></div>\n        </td>\n        <td>\n            {% if (!i && !o.options.autoUpload) { %}\n                <button class=\"btn btn-primary start\" disabled>\n                    <i class=\"glyphicon glyphicon-upload\"></i>\n                    <span>Start</span>\n                </button>\n            {% } %}\n            {% if (!i) { %}\n                <button class=\"btn btn-warning cancel\">\n                    <i class=\"glyphicon glyphicon-ban-circle\"></i>\n                    <span>Cancel</span>\n                </button>\n            {% } %}\n        </td>\n    </tr>\n{% } %}\n</script>\n<!-- The template to display files available for download -->\n<script id=\"template-download\" type=\"text/x-tmpl\">\n{% for (var i=0, file; file=o.files[i]; i++) { %}\n    <tr class=\"template-download fade\">\n        <td>\n            <span class=\"preview\">\n                {% if (file.thumbnailUrl) { %}\n                    <a href=\"{%=file.url%}\" title=\"{%=file.name%}\" download=\"{%=file.name%}\" data-gallery><img src=\"{%=file.thumbnailUrl%}\"></a>\n                {% } %}\n            </span>\n        </td>\n        <td>\n            <p class=\"name\">\n                {% if (file.url) { %}\n                    <a href=\"{%=file.url%}\" title=\"{%=file.name%}\" download=\"{%=file.name%}\" {%=file.thumbnailUrl?'data-gallery':''%}>{%=file.name%}</a>\n                {% } else { %}\n                    <span>{%=file.name%}</span>\n                {% } %}\n            </p>\n            {% if (file.error) { %}\n                <div><span class=\"label label-danger\">Error</span> {%=file.error%}</div>\n            {% } %}\n        </td>\n        <td>\n            <span class=\"size\">{%=o.formatFileSize(file.size)%}</span>\n        </td>\n        <td>\n            {% if (file.deleteUrl) { %}\n                <button class=\"btn btn-danger delete\" data-type=\"{%=file.deleteType%}\" data-url=\"{%=file.deleteUrl%}\"{% if (file.deleteWithCredentials) { %} data-xhr-fields='{\"withCredentials\":true}'{% } %}>\n                    <i class=\"glyphicon glyphicon-trash\"></i>\n                    <span>Delete</span>\n                </button>\n                <input type=\"checkbox\" name=\"delete\" value=\"1\" class=\"toggle\">\n            {% } else { %}\n                <button class=\"btn btn-warning cancel\">\n                    <i class=\"glyphicon glyphicon-ban-circle\"></i>\n                    <span>Cancel</span>\n                </button>\n            {% } %}\n        </td>\n    </tr>\n{% } %}\n</script>\n<script src=\"//ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js\"></script>\n<!-- The jQuery UI widget factory, can be omitted if jQuery UI is already included -->\n<script src=\"js/vendor/jquery.ui.widget.js\"></script>\n<!-- The Templates plugin is included to render the upload/download listings -->\n<script src=\"//blueimp.github.io/JavaScript-Templates/js/tmpl.min.js\"></script>\n<!-- The Load Image plugin is included for the preview images and image resizing functionality -->\n<script src=\"//blueimp.github.io/JavaScript-Load-Image/js/load-image.all.min.js\"></script>\n<!-- The Canvas to Blob plugin is included for image resizing functionality -->\n<script src=\"//blueimp.github.io/JavaScript-Canvas-to-Blob/js/canvas-to-blob.min.js\"></script>\n<!-- Bootstrap JS is not required, but included for the responsive demo navigation -->\n<script src=\"//netdna.bootstrapcdn.com/bootstrap/3.2.0/js/bootstrap.min.js\"></script>\n<!-- blueimp Gallery script -->\n<script src=\"//blueimp.github.io/Gallery/js/jquery.blueimp-gallery.min.js\"></script>\n<!-- The Iframe Transport is required for browsers without support for XHR file uploads -->\n<script src=\"js/jquery.iframe-transport.js\"></script>\n<!-- The basic File Upload plugin -->\n<script src=\"js/jquery.fileupload.js\"></script>\n<!-- The File Upload processing plugin -->\n<script src=\"js/jquery.fileupload-process.js\"></script>\n<!-- The File Upload image preview & resize plugin -->\n<script src=\"js/jquery.fileupload-image.js\"></script>\n<!-- The File Upload audio preview plugin -->\n<script src=\"js/jquery.fileupload-audio.js\"></script>\n<!-- The File Upload video preview plugin -->\n<script src=\"js/jquery.fileupload-video.js\"></script>\n<!-- The File Upload validation plugin -->\n<script src=\"js/jquery.fileupload-validate.js\"></script>\n<!-- The File Upload user interface plugin -->\n<script src=\"js/jquery.fileupload-ui.js\"></script>\n<!-- The main application script -->\n<script src=\"js/main.js\"></script>\n<!-- The XDomainRequest Transport is included for cross-domain file deletion for IE 8 and IE 9 -->\n<!--[if (gte IE 8)&(lt IE 10)]>\n<script src=\"js/cors/jquery.xdr-transport.js\"></script>\n<![endif]-->\n</body>\n</html>\n"
  },
  {
    "path": "app_frontend/static/plugin/jQuery-File-Upload-9.18.0/jquery-ui.html",
    "content": "<!DOCTYPE HTML>\n<!--\n/*\n * jQuery File Upload Plugin jQuery UI Demo\n * https://github.com/blueimp/jQuery-File-Upload\n *\n * Copyright 2013, Sebastian Tschan\n * https://blueimp.net\n *\n * Licensed under the MIT license:\n * https://opensource.org/licenses/MIT\n */\n-->\n<html lang=\"en\">\n<head>\n<!-- Force latest IE rendering engine or ChromeFrame if installed -->\n<!--[if IE]>\n<meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge,chrome=1\">\n<![endif]-->\n<meta charset=\"utf-8\">\n<title>jQuery File Upload Demo - jQuery UI version</title>\n<meta name=\"description\" content=\"File Upload widget with multiple file selection, drag&amp;drop support, progress bars, validation and preview images, audio and video for jQuery. Supports cross-domain, chunked and resumable file uploads and client-side image resizing. Works with any server-side platform (PHP, Python, Ruby on Rails, Java, Node.js, Go etc.) that supports standard HTML form file uploads.\">\n<meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n<!-- jQuery UI styles -->\n<link rel=\"stylesheet\" href=\"//ajax.googleapis.com/ajax/libs/jqueryui/1.11.1/themes/dark-hive/jquery-ui.css\" id=\"theme\">\n<!-- Demo styles -->\n<link rel=\"stylesheet\" href=\"css/demo.css\">\n<!--[if lte IE 8]>\n<link rel=\"stylesheet\" href=\"css/demo-ie8.css\">\n<![endif]-->\n<style>\n/* Adjust the jQuery UI widget font-size: */\n.ui-widget {\n    font-size: 0.95em;\n}\n</style>\n<!-- blueimp Gallery styles -->\n<link rel=\"stylesheet\" href=\"//blueimp.github.io/Gallery/css/blueimp-gallery.min.css\">\n<!-- CSS to style the file input field as button and adjust the Bootstrap progress bars -->\n<link rel=\"stylesheet\" href=\"css/jquery.fileupload.css\">\n<link rel=\"stylesheet\" href=\"css/jquery.fileupload-ui.css\">\n<!-- CSS adjustments for browsers with JavaScript disabled -->\n<noscript><link rel=\"stylesheet\" href=\"css/jquery.fileupload-noscript.css\"></noscript>\n<noscript><link rel=\"stylesheet\" href=\"css/jquery.fileupload-ui-noscript.css\"></noscript>\n</head>\n<body>\n<ul class=\"navigation\">\n    <li><h3><a href=\"https://github.com/blueimp/jQuery-File-Upload\">jQuery File Upload</a></h3></li>\n    <li><a href=\"https://github.com/blueimp/jQuery-File-Upload/tags\">Download</a></li>\n    <li><a href=\"https://github.com/blueimp/jQuery-File-Upload\">Source Code</a></li>\n    <li><a href=\"https://github.com/blueimp/jQuery-File-Upload/wiki\">Documentation</a></li>\n    <li><a href=\"https://blueimp.net\">&copy; blueimp.net</a></li>\n</ul>\n<h1>jQuery File Upload Demo</h1>\n<h2>jQuery UI version</h2>\n<form>\n    <label for=\"theme-switcher\">Theme:</label>\n    <select id=\"theme-switcher\" class=\"pull-right\">\n        <option value=\"black-tie\">Black Tie</option>\n        <option value=\"blitzer\">Blitzer</option>\n        <option value=\"cupertino\">Cupertino</option>\n        <option value=\"dark-hive\" selected>Dark Hive</option>\n        <option value=\"dot-luv\">Dot Luv</option>\n        <option value=\"eggplant\">Eggplant</option>\n        <option value=\"excite-bike\">Excite Bike</option>\n        <option value=\"flick\">Flick</option>\n        <option value=\"hot-sneaks\">Hot sneaks</option>\n        <option value=\"humanity\">Humanity</option>\n        <option value=\"le-frog\">Le Frog</option>\n        <option value=\"mint-choc\">Mint Choc</option>\n        <option value=\"overcast\">Overcast</option>\n        <option value=\"pepper-grinder\">Pepper Grinder</option>\n        <option value=\"redmond\">Redmond</option>\n        <option value=\"smoothness\">Smoothness</option>\n        <option value=\"south-street\">South Street</option>\n        <option value=\"start\">Start</option>\n        <option value=\"sunny\">Sunny</option>\n        <option value=\"swanky-purse\">Swanky Purse</option>\n        <option value=\"trontastic\">Trontastic</option>\n        <option value=\"ui-darkness\">UI Darkness</option>\n        <option value=\"ui-lightness\">UI Lightness</option>\n        <option value=\"vader\">Vader</option>\n    </select>\n</form>\n<ul class=\"navigation\">\n    <li><a href=\"basic.html\">Basic</a></li>\n    <li><a href=\"basic-plus.html\">Basic Plus</a></li>\n    <li><a href=\"index.html\">Basic Plus UI</a></li>\n    <li><a href=\"angularjs.html\">AngularJS</a></li>\n    <li class=\"active\"><a href=\"jquery-ui.html\">jQuery UI</a></li>\n</ul>\n<blockquote>\n    <p>File Upload widget with multiple file selection, drag&amp;drop support, progress bars, validation and preview images, audio and video for jQuery UI.<br>\n    Supports cross-domain, chunked and resumable file uploads and client-side image resizing.<br>\n    Works with any server-side platform (PHP, Python, Ruby on Rails, Java, Node.js, Go etc.) that supports standard HTML form file uploads.</p>\n</blockquote>\n<!-- The file upload form used as target for the file upload widget -->\n<form id=\"fileupload\" action=\"//jquery-file-upload.appspot.com/\" method=\"POST\" enctype=\"multipart/form-data\">\n    <!-- Redirect browsers with JavaScript disabled to the origin page -->\n    <noscript><input type=\"hidden\" name=\"redirect\" value=\"https://blueimp.github.io/jQuery-File-Upload/\"></noscript>\n    <!-- The fileupload-buttonbar contains buttons to add/delete files and start/cancel the upload -->\n    <div class=\"fileupload-buttonbar\">\n        <div class=\"fileupload-buttons\">\n            <!-- The fileinput-button span is used to style the file input field as button -->\n            <span class=\"fileinput-button\">\n                <span>Add files...</span>\n                <input type=\"file\" name=\"files[]\" multiple>\n            </span>\n            <button type=\"submit\" class=\"start\">Start upload</button>\n            <button type=\"reset\" class=\"cancel\">Cancel upload</button>\n            <button type=\"button\" class=\"delete\">Delete</button>\n            <input type=\"checkbox\" class=\"toggle\">\n            <!-- The global file processing state -->\n            <span class=\"fileupload-process\"></span>\n        </div>\n        <!-- The global progress state -->\n        <div class=\"fileupload-progress fade\" style=\"display:none\">\n            <!-- The global progress bar -->\n            <div class=\"progress\" role=\"progressbar\" aria-valuemin=\"0\" aria-valuemax=\"100\"></div>\n            <!-- The extended global progress state -->\n            <div class=\"progress-extended\">&nbsp;</div>\n        </div>\n    </div>\n    <!-- The table listing the files available for upload/download -->\n    <table role=\"presentation\"><tbody class=\"files\"></tbody></table>\n</form>\n<br>\n<h3>Demo Notes</h3>\n<ul>\n    <li>The maximum file size for uploads in this demo is <strong>999 KB</strong> (default file size is unlimited).</li>\n    <li>Only image files (<strong>JPG, GIF, PNG</strong>) are allowed in this demo (by default there is no file type restriction).</li>\n    <li>Uploaded files will be deleted automatically after <strong>5 minutes or less</strong> (demo files are stored in memory).</li>\n    <li>You can <strong>drag &amp; drop</strong> files from your desktop on this webpage (see <a href=\"https://github.com/blueimp/jQuery-File-Upload/wiki/Browser-support\">Browser support</a>).</li>\n    <li>Please refer to the <a href=\"https://github.com/blueimp/jQuery-File-Upload\">project website</a> and <a href=\"https://github.com/blueimp/jQuery-File-Upload/wiki\">documentation</a> for more information.</li>\n    <li>Built with <a href=\"https://jqueryui.com\">jQuery UI</a>.</li>\n</ul>\n<!-- The blueimp Gallery widget -->\n<div id=\"blueimp-gallery\" class=\"blueimp-gallery blueimp-gallery-controls\" data-filter=\":even\">\n    <div class=\"slides\"></div>\n    <h3 class=\"title\"></h3>\n    <a class=\"prev\">‹</a>\n    <a class=\"next\">›</a>\n    <a class=\"close\">×</a>\n    <a class=\"play-pause\"></a>\n    <ol class=\"indicator\"></ol>\n</div>\n<!-- The template to display files available for upload -->\n<script id=\"template-upload\" type=\"text/x-tmpl\">\n{% for (var i=0, file; file=o.files[i]; i++) { %}\n    <tr class=\"template-upload fade\">\n        <td>\n            <span class=\"preview\"></span>\n        </td>\n        <td>\n            <p class=\"name\">{%=file.name%}</p>\n            <strong class=\"error\"></strong>\n        </td>\n        <td>\n            <p class=\"size\">Processing...</p>\n            <div class=\"progress\"></div>\n        </td>\n        <td>\n            {% if (!i && !o.options.autoUpload) { %}\n                <button class=\"start\" disabled>Start</button>\n            {% } %}\n            {% if (!i) { %}\n                <button class=\"cancel\">Cancel</button>\n            {% } %}\n        </td>\n    </tr>\n{% } %}\n</script>\n<!-- The template to display files available for download -->\n<script id=\"template-download\" type=\"text/x-tmpl\">\n{% for (var i=0, file; file=o.files[i]; i++) { %}\n    <tr class=\"template-download fade\">\n        <td>\n            <span class=\"preview\">\n                {% if (file.thumbnailUrl) { %}\n                    <a href=\"{%=file.url%}\" title=\"{%=file.name%}\" download=\"{%=file.name%}\" data-gallery><img src=\"{%=file.thumbnailUrl%}\"></a>\n                {% } %}\n            </span>\n        </td>\n        <td>\n            <p class=\"name\">\n                <a href=\"{%=file.url%}\" title=\"{%=file.name%}\" download=\"{%=file.name%}\" {%=file.thumbnailUrl?'data-gallery':''%}>{%=file.name%}</a>\n            </p>\n            {% if (file.error) { %}\n                <div><span class=\"error\">Error</span> {%=file.error%}</div>\n            {% } %}\n        </td>\n        <td>\n            <span class=\"size\">{%=o.formatFileSize(file.size)%}</span>\n        </td>\n        <td>\n            <button class=\"delete\" data-type=\"{%=file.deleteType%}\" data-url=\"{%=file.deleteUrl%}\"{% if (file.deleteWithCredentials) { %} data-xhr-fields='{\"withCredentials\":true}'{% } %}>Delete</button>\n            <input type=\"checkbox\" name=\"delete\" value=\"1\" class=\"toggle\">\n        </td>\n    </tr>\n{% } %}\n</script>\n<script src=\"//ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js\"></script>\n<script src=\"//ajax.googleapis.com/ajax/libs/jqueryui/1.11.4/jquery-ui.min.js\"></script>\n<!-- The Templates plugin is included to render the upload/download listings -->\n<script src=\"//blueimp.github.io/JavaScript-Templates/js/tmpl.min.js\"></script>\n<!-- The Load Image plugin is included for the preview images and image resizing functionality -->\n<script src=\"//blueimp.github.io/JavaScript-Load-Image/js/load-image.all.min.js\"></script>\n<!-- The Canvas to Blob plugin is included for image resizing functionality -->\n<script src=\"//blueimp.github.io/JavaScript-Canvas-to-Blob/js/canvas-to-blob.min.js\"></script>\n<!-- blueimp Gallery script -->\n<script src=\"//blueimp.github.io/Gallery/js/jquery.blueimp-gallery.min.js\"></script>\n<!-- The Iframe Transport is required for browsers without support for XHR file uploads -->\n<script src=\"js/jquery.iframe-transport.js\"></script>\n<!-- The basic File Upload plugin -->\n<script src=\"js/jquery.fileupload.js\"></script>\n<!-- The File Upload processing plugin -->\n<script src=\"js/jquery.fileupload-process.js\"></script>\n<!-- The File Upload image preview & resize plugin -->\n<script src=\"js/jquery.fileupload-image.js\"></script>\n<!-- The File Upload audio preview plugin -->\n<script src=\"js/jquery.fileupload-audio.js\"></script>\n<!-- The File Upload video preview plugin -->\n<script src=\"js/jquery.fileupload-video.js\"></script>\n<!-- The File Upload validation plugin -->\n<script src=\"js/jquery.fileupload-validate.js\"></script>\n<!-- The File Upload user interface plugin -->\n<script src=\"js/jquery.fileupload-ui.js\"></script>\n<!-- The File Upload jQuery UI plugin -->\n<script src=\"js/jquery.fileupload-jquery-ui.js\"></script>\n<!-- The main application script -->\n<script src=\"js/main.js\"></script>\n<script>\n// Initialize the jQuery UI theme switcher:\n$('#theme-switcher').change(function () {\n    var theme = $('#theme');\n    theme.prop(\n        'href',\n        theme.prop('href').replace(\n            /[\\w\\-]+\\/jquery-ui.css/,\n            $(this).val() + '/jquery-ui.css'\n        )\n    );\n});\n</script>\n<!-- The XDomainRequest Transport is included for cross-domain file deletion for IE 8 and IE 9 -->\n<!--[if (gte IE 8)&(lt IE 10)]>\n<script src=\"js/cors/jquery.xdr-transport.js\"></script>\n<![endif]-->\n</body>\n</html>\n"
  },
  {
    "path": "app_frontend/static/plugin/jQuery-File-Upload-9.18.0/js/app.js",
    "content": "/*\n * jQuery File Upload Plugin Angular JS Example\n * https://github.com/blueimp/jQuery-File-Upload\n *\n * Copyright 2013, Sebastian Tschan\n * https://blueimp.net\n *\n * Licensed under the MIT license:\n * https://opensource.org/licenses/MIT\n */\n\n/* jshint nomen:false */\n/* global window, angular */\n\n;(function () {\n    'use strict';\n\n    var isOnGitHub = window.location.hostname === 'blueimp.github.io',\n        url = isOnGitHub ? '//jquery-file-upload.appspot.com/' : 'server/php/';\n\n    angular.module('demo', [\n        'blueimp.fileupload'\n    ])\n        .config([\n            '$httpProvider', 'fileUploadProvider',\n            function ($httpProvider, fileUploadProvider) {\n                delete $httpProvider.defaults.headers.common['X-Requested-With'];\n                fileUploadProvider.defaults.redirect = window.location.href.replace(\n                    /\\/[^\\/]*$/,\n                    '/cors/result.html?%s'\n                );\n                if (isOnGitHub) {\n                    // Demo settings:\n                    angular.extend(fileUploadProvider.defaults, {\n                        // Enable image resizing, except for Android and Opera,\n                        // which actually support image resizing, but fail to\n                        // send Blob objects via XHR requests:\n                        disableImageResize: /Android(?!.*Chrome)|Opera/\n                            .test(window.navigator.userAgent),\n                        maxFileSize: 999000,\n                        acceptFileTypes: /(\\.|\\/)(gif|jpe?g|png)$/i\n                    });\n                }\n            }\n        ])\n\n        .controller('DemoFileUploadController', [\n            '$scope', '$http', '$filter', '$window',\n            function ($scope, $http) {\n                $scope.options = {\n                    url: url\n                };\n                if (!isOnGitHub) {\n                    $scope.loadingFiles = true;\n                    $http.get(url)\n                        .then(\n                            function (response) {\n                                $scope.loadingFiles = false;\n                                $scope.queue = response.data.files || [];\n                            },\n                            function () {\n                                $scope.loadingFiles = false;\n                            }\n                        );\n                }\n            }\n        ])\n\n        .controller('FileDestroyController', [\n            '$scope', '$http',\n            function ($scope, $http) {\n                var file = $scope.file,\n                    state;\n                if (file.url) {\n                    file.$state = function () {\n                        return state;\n                    };\n                    file.$destroy = function () {\n                        state = 'pending';\n                        return $http({\n                            url: file.deleteUrl,\n                            method: file.deleteType\n                        }).then(\n                            function () {\n                                state = 'resolved';\n                                $scope.clear(file);\n                            },\n                            function () {\n                                state = 'rejected';\n                            }\n                        );\n                    };\n                } else if (!file.$cancel && !file._index) {\n                    file.$cancel = function () {\n                        $scope.clear(file);\n                    };\n                }\n            }\n        ]);\n\n}());\n"
  },
  {
    "path": "app_frontend/static/plugin/jQuery-File-Upload-9.18.0/js/cors/jquery.postmessage-transport.js",
    "content": "/*\n * jQuery postMessage Transport Plugin\n * https://github.com/blueimp/jQuery-File-Upload\n *\n * Copyright 2011, Sebastian Tschan\n * https://blueimp.net\n *\n * Licensed under the MIT license:\n * https://opensource.org/licenses/MIT\n */\n\n/* global define, require, window, document */\n\n;(function (factory) {\n    'use strict';\n    if (typeof define === 'function' && define.amd) {\n        // Register as an anonymous AMD module:\n        define(['jquery'], factory);\n    } else if (typeof exports === 'object') {\n        // Node/CommonJS:\n        factory(require('jquery'));\n    } else {\n        // Browser globals:\n        factory(window.jQuery);\n    }\n}(function ($) {\n    'use strict';\n\n    var counter = 0,\n        names = [\n            'accepts',\n            'cache',\n            'contents',\n            'contentType',\n            'crossDomain',\n            'data',\n            'dataType',\n            'headers',\n            'ifModified',\n            'mimeType',\n            'password',\n            'processData',\n            'timeout',\n            'traditional',\n            'type',\n            'url',\n            'username'\n        ],\n        convert = function (p) {\n            return p;\n        };\n\n    $.ajaxSetup({\n        converters: {\n            'postmessage text': convert,\n            'postmessage json': convert,\n            'postmessage html': convert\n        }\n    });\n\n    $.ajaxTransport('postmessage', function (options) {\n        if (options.postMessage && window.postMessage) {\n            var iframe,\n                loc = $('<a>').prop('href', options.postMessage)[0],\n                target = loc.protocol + '//' + loc.host,\n                xhrUpload = options.xhr().upload;\n            // IE always includes the port for the host property of a link\n            // element, but not in the location.host or origin property for the\n            // default http port 80 and https port 443, so we strip it:\n            if (/^(http:\\/\\/.+:80)|(https:\\/\\/.+:443)$/.test(target)) {\n              target = target.replace(/:(80|443)$/, '');\n            }\n            return {\n                send: function (_, completeCallback) {\n                    counter += 1;\n                    var message = {\n                            id: 'postmessage-transport-' + counter\n                        },\n                        eventName = 'message.' + message.id;\n                    iframe = $(\n                        '<iframe style=\"display:none;\" src=\"' +\n                            options.postMessage + '\" name=\"' +\n                            message.id + '\"></iframe>'\n                    ).bind('load', function () {\n                        $.each(names, function (i, name) {\n                            message[name] = options[name];\n                        });\n                        message.dataType = message.dataType.replace('postmessage ', '');\n                        $(window).bind(eventName, function (e) {\n                            e = e.originalEvent;\n                            var data = e.data,\n                                ev;\n                            if (e.origin === target && data.id === message.id) {\n                                if (data.type === 'progress') {\n                                    ev = document.createEvent('Event');\n                                    ev.initEvent(data.type, false, true);\n                                    $.extend(ev, data);\n                                    xhrUpload.dispatchEvent(ev);\n                                } else {\n                                    completeCallback(\n                                        data.status,\n                                        data.statusText,\n                                        {postmessage: data.result},\n                                        data.headers\n                                    );\n                                    iframe.remove();\n                                    $(window).unbind(eventName);\n                                }\n                            }\n                        });\n                        iframe[0].contentWindow.postMessage(\n                            message,\n                            target\n                        );\n                    }).appendTo(document.body);\n                },\n                abort: function () {\n                    if (iframe) {\n                        iframe.remove();\n                    }\n                }\n            };\n        }\n    });\n\n}));\n"
  },
  {
    "path": "app_frontend/static/plugin/jQuery-File-Upload-9.18.0/js/cors/jquery.xdr-transport.js",
    "content": "/*\n * jQuery XDomainRequest Transport Plugin\n * https://github.com/blueimp/jQuery-File-Upload\n *\n * Copyright 2011, Sebastian Tschan\n * https://blueimp.net\n *\n * Licensed under the MIT license:\n * https://opensource.org/licenses/MIT\n *\n * Based on Julian Aubourg's ajaxHooks xdr.js:\n * https://github.com/jaubourg/ajaxHooks/\n */\n\n/* global define, require, window, XDomainRequest */\n\n;(function (factory) {\n    'use strict';\n    if (typeof define === 'function' && define.amd) {\n        // Register as an anonymous AMD module:\n        define(['jquery'], factory);\n    } else if (typeof exports === 'object') {\n        // Node/CommonJS:\n        factory(require('jquery'));\n    } else {\n        // Browser globals:\n        factory(window.jQuery);\n    }\n}(function ($) {\n    'use strict';\n    if (window.XDomainRequest && !$.support.cors) {\n        $.ajaxTransport(function (s) {\n            if (s.crossDomain && s.async) {\n                if (s.timeout) {\n                    s.xdrTimeout = s.timeout;\n                    delete s.timeout;\n                }\n                var xdr;\n                return {\n                    send: function (headers, completeCallback) {\n                        var addParamChar = /\\?/.test(s.url) ? '&' : '?';\n                        function callback(status, statusText, responses, responseHeaders) {\n                            xdr.onload = xdr.onerror = xdr.ontimeout = $.noop;\n                            xdr = null;\n                            completeCallback(status, statusText, responses, responseHeaders);\n                        }\n                        xdr = new XDomainRequest();\n                        // XDomainRequest only supports GET and POST:\n                        if (s.type === 'DELETE') {\n                            s.url = s.url + addParamChar + '_method=DELETE';\n                            s.type = 'POST';\n                        } else if (s.type === 'PUT') {\n                            s.url = s.url + addParamChar + '_method=PUT';\n                            s.type = 'POST';\n                        } else if (s.type === 'PATCH') {\n                            s.url = s.url + addParamChar + '_method=PATCH';\n                            s.type = 'POST';\n                        }\n                        xdr.open(s.type, s.url);\n                        xdr.onload = function () {\n                            callback(\n                                200,\n                                'OK',\n                                {text: xdr.responseText},\n                                'Content-Type: ' + xdr.contentType\n                            );\n                        };\n                        xdr.onerror = function () {\n                            callback(404, 'Not Found');\n                        };\n                        if (s.xdrTimeout) {\n                            xdr.ontimeout = function () {\n                                callback(0, 'timeout');\n                            };\n                            xdr.timeout = s.xdrTimeout;\n                        }\n                        xdr.send((s.hasContent && s.data) || null);\n                    },\n                    abort: function () {\n                        if (xdr) {\n                            xdr.onerror = $.noop();\n                            xdr.abort();\n                        }\n                    }\n                };\n            }\n        });\n    }\n}));\n"
  },
  {
    "path": "app_frontend/static/plugin/jQuery-File-Upload-9.18.0/js/jquery.fileupload-angular.js",
    "content": "/*\n * jQuery File Upload AngularJS Plugin\n * https://github.com/blueimp/jQuery-File-Upload\n *\n * Copyright 2013, Sebastian Tschan\n * https://blueimp.net\n *\n * Licensed under the MIT license:\n * https://opensource.org/licenses/MIT\n */\n\n/* jshint nomen:false */\n/* global define, angular, require */\n\n;(function (factory) {\n    'use strict';\n    if (typeof define === 'function' && define.amd) {\n        // Register as an anonymous AMD module:\n        define([\n            'jquery',\n            'angular',\n            './jquery.fileupload-image',\n            './jquery.fileupload-audio',\n            './jquery.fileupload-video',\n            './jquery.fileupload-validate'\n        ], factory);\n    } else if (typeof exports === 'object') {\n        // Node/CommonJS:\n        factory(\n            require('jquery'),\n            require('angular'),\n            require('./jquery.fileupload-image'),\n            require('./jquery.fileupload-audio'),\n            require('./jquery.fileupload-video'),\n            require('./jquery.fileupload-validate')\n        );\n    } else {\n        factory();\n    }\n}(function () {\n    'use strict';\n\n    angular.module('blueimp.fileupload', [])\n\n        // The fileUpload service provides configuration options\n        // for the fileUpload directive and default handlers for\n        // File Upload events:\n        .provider('fileUpload', function () {\n            var scopeEvalAsync = function (expression) {\n                    var scope = angular.element(this)\n                            .fileupload('option', 'scope');\n                    // Schedule a new $digest cycle if not already inside of one\n                    // and evaluate the given expression:\n                    scope.$evalAsync(expression);\n                },\n                addFileMethods = function (scope, data) {\n                    var files = data.files,\n                        file = files[0];\n                    angular.forEach(files, function (file, index) {\n                        file._index = index;\n                        file.$state = function () {\n                            return data.state();\n                        };\n                        file.$processing = function () {\n                            return data.processing();\n                        };\n                        file.$progress = function () {\n                            return data.progress();\n                        };\n                        file.$response = function () {\n                            return data.response();\n                        };\n                    });\n                    file.$submit = function () {\n                        if (!file.error) {\n                            return data.submit();\n                        }\n                    };\n                    file.$cancel = function () {\n                        return data.abort();\n                    };\n                },\n                $config;\n            $config = this.defaults = {\n                handleResponse: function (e, data) {\n                    var files = data.result && data.result.files;\n                    if (files) {\n                        data.scope.replace(data.files, files);\n                    } else if (data.errorThrown ||\n                            data.textStatus === 'error') {\n                        data.files[0].error = data.errorThrown ||\n                            data.textStatus;\n                    }\n                },\n                add: function (e, data) {\n                    if (e.isDefaultPrevented()) {\n                        return false;\n                    }\n                    var scope = data.scope,\n                        filesCopy = [];\n                    angular.forEach(data.files, function (file) {\n                        filesCopy.push(file);\n                    });\n                    scope.$parent.$applyAsync(function () {\n                        addFileMethods(scope, data);\n                        var method = scope.option('prependFiles') ?\n                                'unshift' : 'push';\n                        Array.prototype[method].apply(scope.queue, data.files);\n                    });\n                    data.process(function () {\n                        return scope.process(data);\n                    }).always(function () {\n                        scope.$parent.$applyAsync(function () {\n                            addFileMethods(scope, data);\n                            scope.replace(filesCopy, data.files);\n                        });\n                    }).then(function () {\n                        if ((scope.option('autoUpload') ||\n                                data.autoUpload) &&\n                                data.autoUpload !== false) {\n                            data.submit();\n                        }\n                    });\n                },\n                done: function (e, data) {\n                    if (e.isDefaultPrevented()) {\n                        return false;\n                    }\n                    var that = this;\n                    data.scope.$apply(function () {\n                        data.handleResponse.call(that, e, data);\n                    });\n                },\n                fail: function (e, data) {\n                    if (e.isDefaultPrevented()) {\n                        return false;\n                    }\n                    var that = this,\n                        scope = data.scope;\n                    if (data.errorThrown === 'abort') {\n                        scope.clear(data.files);\n                        return;\n                    }\n                    scope.$apply(function () {\n                        data.handleResponse.call(that, e, data);\n                    });\n                },\n                stop: scopeEvalAsync,\n                processstart: scopeEvalAsync,\n                processstop: scopeEvalAsync,\n                getNumberOfFiles: function () {\n                    var scope = this.scope;\n                    return scope.queue.length - scope.processing();\n                },\n                dataType: 'json',\n                autoUpload: false\n            };\n            this.$get = [\n                function () {\n                    return {\n                        defaults: $config\n                    };\n                }\n            ];\n        })\n\n        // Format byte numbers to readable presentations:\n        .provider('formatFileSizeFilter', function () {\n            var $config = {\n                // Byte units following the IEC format\n                // http://en.wikipedia.org/wiki/Kilobyte\n                units: [\n                    {size: 1000000000, suffix: ' GB'},\n                    {size: 1000000, suffix: ' MB'},\n                    {size: 1000, suffix: ' KB'}\n                ]\n            };\n            this.defaults = $config;\n            this.$get = function () {\n                return function (bytes) {\n                    if (!angular.isNumber(bytes)) {\n                        return '';\n                    }\n                    var unit = true,\n                        i = 0,\n                        prefix,\n                        suffix;\n                    while (unit) {\n                        unit = $config.units[i];\n                        prefix = unit.prefix || '';\n                        suffix = unit.suffix || '';\n                        if (i === $config.units.length - 1 || bytes >= unit.size) {\n                            return prefix + (bytes / unit.size).toFixed(2) + suffix;\n                        }\n                        i += 1;\n                    }\n                };\n            };\n        })\n\n        // The FileUploadController initializes the fileupload widget and\n        // provides scope methods to control the File Upload functionality:\n        .controller('FileUploadController', [\n            '$scope', '$element', '$attrs', '$window', 'fileUpload','$q',\n            function ($scope, $element, $attrs, $window, fileUpload, $q) {\n                var uploadMethods = {\n                    progress: function () {\n                        return $element.fileupload('progress');\n                    },\n                    active: function () {\n                        return $element.fileupload('active');\n                    },\n                    option: function (option, data) {\n                        if (arguments.length === 1) {\n                            return $element.fileupload('option', option);\n                        }\n                        $element.fileupload('option', option, data);\n                    },\n                    add: function (data) {\n                        return $element.fileupload('add', data);\n                    },\n                    send: function (data) {\n                        return $element.fileupload('send', data);\n                    },\n                    process: function (data) {\n                        return $element.fileupload('process', data);\n                    },\n                    processing: function (data) {\n                        return $element.fileupload('processing', data);\n                    }\n                };\n                $scope.disabled = !$window.jQuery.support.fileInput;\n                $scope.queue = $scope.queue || [];\n                $scope.clear = function (files) {\n                    var queue = this.queue,\n                        i = queue.length,\n                        file = files,\n                        length = 1;\n                    if (angular.isArray(files)) {\n                        file = files[0];\n                        length = files.length;\n                    }\n                    while (i) {\n                        i -= 1;\n                        if (queue[i] === file) {\n                            return queue.splice(i, length);\n                        }\n                    }\n                };\n                $scope.replace = function (oldFiles, newFiles) {\n                    var queue = this.queue,\n                        file = oldFiles[0],\n                        i,\n                        j;\n                    for (i = 0; i < queue.length; i += 1) {\n                        if (queue[i] === file) {\n                            for (j = 0; j < newFiles.length; j += 1) {\n                                queue[i + j] = newFiles[j];\n                            }\n                            return;\n                        }\n                    }\n                };\n                $scope.applyOnQueue = function (method) {\n                    var list = this.queue.slice(0),\n                        i,\n                        file,\n                        promises = [];\n                    for (i = 0; i < list.length; i += 1) {\n                        file = list[i];\n                        if (file[method]) {\n                            promises.push(file[method]());\n                        }\n                    }\n                    return $q.all(promises);\n                };\n                $scope.submit = function () {\n                    return this.applyOnQueue('$submit');\n                };\n                $scope.cancel = function () {\n                    return this.applyOnQueue('$cancel');\n                };\n                // Add upload methods to the scope:\n                angular.extend($scope, uploadMethods);\n                // The fileupload widget will initialize with\n                // the options provided via \"data-\"-parameters,\n                // as well as those given via options object:\n                $element.fileupload(angular.extend(\n                    {scope: $scope},\n                    fileUpload.defaults\n                )).on('fileuploadadd', function (e, data) {\n                    data.scope = $scope;\n                }).on('fileuploadfail', function (e, data) {\n                    if (data.errorThrown === 'abort') {\n                        return;\n                    }\n                    if (data.dataType &&\n                            data.dataType.indexOf('json') === data.dataType.length - 4) {\n                        try {\n                            data.result = angular.fromJson(data.jqXHR.responseText);\n                        } catch (ignore) {}\n                    }\n                }).on([\n                    'fileuploadadd',\n                    'fileuploadsubmit',\n                    'fileuploadsend',\n                    'fileuploaddone',\n                    'fileuploadfail',\n                    'fileuploadalways',\n                    'fileuploadprogress',\n                    'fileuploadprogressall',\n                    'fileuploadstart',\n                    'fileuploadstop',\n                    'fileuploadchange',\n                    'fileuploadpaste',\n                    'fileuploaddrop',\n                    'fileuploaddragover',\n                    'fileuploadchunksend',\n                    'fileuploadchunkdone',\n                    'fileuploadchunkfail',\n                    'fileuploadchunkalways',\n                    'fileuploadprocessstart',\n                    'fileuploadprocess',\n                    'fileuploadprocessdone',\n                    'fileuploadprocessfail',\n                    'fileuploadprocessalways',\n                    'fileuploadprocessstop'\n                ].join(' '), function (e, data) {\n                    $scope.$parent.$applyAsync(function () {\n                        if ($scope.$emit(e.type, data).defaultPrevented) {\n                            e.preventDefault();\n                        }\n                    });\n                }).on('remove', function () {\n                    // Remove upload methods from the scope,\n                    // when the widget is removed:\n                    var method;\n                    for (method in uploadMethods) {\n                        if (uploadMethods.hasOwnProperty(method)) {\n                            delete $scope[method];\n                        }\n                    }\n                });\n                // Observe option changes:\n                $scope.$watch(\n                    $attrs.fileUpload,\n                    function (newOptions) {\n                        if (newOptions) {\n                            $element.fileupload('option', newOptions);\n                        }\n                    }\n                );\n            }\n        ])\n\n        // Provide File Upload progress feedback:\n        .controller('FileUploadProgressController', [\n            '$scope', '$attrs', '$parse',\n            function ($scope, $attrs, $parse) {\n                var fn = $parse($attrs.fileUploadProgress),\n                    update = function () {\n                        var progress = fn($scope);\n                        if (!progress || !progress.total) {\n                            return;\n                        }\n                        $scope.num = Math.floor(\n                            progress.loaded / progress.total * 100\n                        );\n                    };\n                update();\n                $scope.$watch(\n                    $attrs.fileUploadProgress + '.loaded',\n                    function (newValue, oldValue) {\n                        if (newValue !== oldValue) {\n                            update();\n                        }\n                    }\n                );\n            }\n        ])\n\n        // Display File Upload previews:\n        .controller('FileUploadPreviewController', [\n            '$scope', '$element', '$attrs',\n            function ($scope, $element, $attrs) {\n                $scope.$watch(\n                    $attrs.fileUploadPreview + '.preview',\n                    function (preview) {\n                        $element.empty();\n                        if (preview) {\n                            $element.append(preview);\n                        }\n                    }\n                );\n            }\n        ])\n\n        .directive('fileUpload', function () {\n            return {\n                controller: 'FileUploadController',\n                scope: true\n            };\n        })\n\n        .directive('fileUploadProgress', function () {\n            return {\n                controller: 'FileUploadProgressController',\n                scope: true\n            };\n        })\n\n        .directive('fileUploadPreview', function () {\n            return {\n                controller: 'FileUploadPreviewController'\n            };\n        })\n\n        // Enhance the HTML5 download attribute to\n        // allow drag&drop of files to the desktop:\n        .directive('download', function () {\n            return function (scope, elm) {\n                elm.on('dragstart', function (e) {\n                    try {\n                        e.originalEvent.dataTransfer.setData(\n                            'DownloadURL',\n                            [\n                                'application/octet-stream',\n                                elm.prop('download'),\n                                elm.prop('href')\n                            ].join(':')\n                        );\n                    } catch (ignore) {}\n                });\n            };\n        });\n\n}));\n"
  },
  {
    "path": "app_frontend/static/plugin/jQuery-File-Upload-9.18.0/js/jquery.fileupload-audio.js",
    "content": "/*\n * jQuery File Upload Audio Preview Plugin\n * https://github.com/blueimp/jQuery-File-Upload\n *\n * Copyright 2013, Sebastian Tschan\n * https://blueimp.net\n *\n * Licensed under the MIT license:\n * https://opensource.org/licenses/MIT\n */\n\n/* jshint nomen:false */\n/* global define, require, window, document */\n\n;(function (factory) {\n    'use strict';\n    if (typeof define === 'function' && define.amd) {\n        // Register as an anonymous AMD module:\n        define([\n            'jquery',\n            'load-image',\n            './jquery.fileupload-process'\n        ], factory);\n    } else if (typeof exports === 'object') {\n        // Node/CommonJS:\n        factory(\n            require('jquery'),\n            require('blueimp-load-image/js/load-image'),\n            require('./jquery.fileupload-process')\n        );\n    } else {\n        // Browser globals:\n        factory(\n            window.jQuery,\n            window.loadImage\n        );\n    }\n}(function ($, loadImage) {\n    'use strict';\n\n    // Prepend to the default processQueue:\n    $.blueimp.fileupload.prototype.options.processQueue.unshift(\n        {\n            action: 'loadAudio',\n            // Use the action as prefix for the \"@\" options:\n            prefix: true,\n            fileTypes: '@',\n            maxFileSize: '@',\n            disabled: '@disableAudioPreview'\n        },\n        {\n            action: 'setAudio',\n            name: '@audioPreviewName',\n            disabled: '@disableAudioPreview'\n        }\n    );\n\n    // The File Upload Audio Preview plugin extends the fileupload widget\n    // with audio preview functionality:\n    $.widget('blueimp.fileupload', $.blueimp.fileupload, {\n\n        options: {\n            // The regular expression for the types of audio files to load,\n            // matched against the file type:\n            loadAudioFileTypes: /^audio\\/.*$/\n        },\n\n        _audioElement: document.createElement('audio'),\n\n        processActions: {\n\n            // Loads the audio file given via data.files and data.index\n            // as audio element if the browser supports playing it.\n            // Accepts the options fileTypes (regular expression)\n            // and maxFileSize (integer) to limit the files to load:\n            loadAudio: function (data, options) {\n                if (options.disabled) {\n                    return data;\n                }\n                var file = data.files[data.index],\n                    url,\n                    audio;\n                if (this._audioElement.canPlayType &&\n                        this._audioElement.canPlayType(file.type) &&\n                        ($.type(options.maxFileSize) !== 'number' ||\n                            file.size <= options.maxFileSize) &&\n                        (!options.fileTypes ||\n                            options.fileTypes.test(file.type))) {\n                    url = loadImage.createObjectURL(file);\n                    if (url) {\n                        audio = this._audioElement.cloneNode(false);\n                        audio.src = url;\n                        audio.controls = true;\n                        data.audio = audio;\n                        return data;\n                    }\n                }\n                return data;\n            },\n\n            // Sets the audio element as a property of the file object:\n            setAudio: function (data, options) {\n                if (data.audio && !options.disabled) {\n                    data.files[data.index][options.name || 'preview'] = data.audio;\n                }\n                return data;\n            }\n\n        }\n\n    });\n\n}));\n"
  },
  {
    "path": "app_frontend/static/plugin/jQuery-File-Upload-9.18.0/js/jquery.fileupload-image.js",
    "content": "/*\n * jQuery File Upload Image Preview & Resize Plugin\n * https://github.com/blueimp/jQuery-File-Upload\n *\n * Copyright 2013, Sebastian Tschan\n * https://blueimp.net\n *\n * Licensed under the MIT license:\n * https://opensource.org/licenses/MIT\n */\n\n/* jshint nomen:false */\n/* global define, require, window, Blob */\n\n;(function (factory) {\n    'use strict';\n    if (typeof define === 'function' && define.amd) {\n        // Register as an anonymous AMD module:\n        define([\n            'jquery',\n            'load-image',\n            'load-image-meta',\n            'load-image-scale',\n            'load-image-exif',\n            'canvas-to-blob',\n            './jquery.fileupload-process'\n        ], factory);\n    } else if (typeof exports === 'object') {\n        // Node/CommonJS:\n        factory(\n            require('jquery'),\n            require('blueimp-load-image/js/load-image'),\n            require('blueimp-load-image/js/load-image-meta'),\n            require('blueimp-load-image/js/load-image-scale'),\n            require('blueimp-load-image/js/load-image-exif'),\n            require('blueimp-canvas-to-blob'),\n            require('./jquery.fileupload-process')\n        );\n    } else {\n        // Browser globals:\n        factory(\n            window.jQuery,\n            window.loadImage\n        );\n    }\n}(function ($, loadImage) {\n    'use strict';\n\n    // Prepend to the default processQueue:\n    $.blueimp.fileupload.prototype.options.processQueue.unshift(\n        {\n            action: 'loadImageMetaData',\n            disableImageHead: '@',\n            disableExif: '@',\n            disableExifThumbnail: '@',\n            disableExifSub: '@',\n            disableExifGps: '@',\n            disabled: '@disableImageMetaDataLoad'\n        },\n        {\n            action: 'loadImage',\n            // Use the action as prefix for the \"@\" options:\n            prefix: true,\n            fileTypes: '@',\n            maxFileSize: '@',\n            noRevoke: '@',\n            disabled: '@disableImageLoad'\n        },\n        {\n            action: 'resizeImage',\n            // Use \"image\" as prefix for the \"@\" options:\n            prefix: 'image',\n            maxWidth: '@',\n            maxHeight: '@',\n            minWidth: '@',\n            minHeight: '@',\n            crop: '@',\n            orientation: '@',\n            forceResize: '@',\n            disabled: '@disableImageResize'\n        },\n        {\n            action: 'saveImage',\n            quality: '@imageQuality',\n            type: '@imageType',\n            disabled: '@disableImageResize'\n        },\n        {\n            action: 'saveImageMetaData',\n            disabled: '@disableImageMetaDataSave'\n        },\n        {\n            action: 'resizeImage',\n            // Use \"preview\" as prefix for the \"@\" options:\n            prefix: 'preview',\n            maxWidth: '@',\n            maxHeight: '@',\n            minWidth: '@',\n            minHeight: '@',\n            crop: '@',\n            orientation: '@',\n            thumbnail: '@',\n            canvas: '@',\n            disabled: '@disableImagePreview'\n        },\n        {\n            action: 'setImage',\n            name: '@imagePreviewName',\n            disabled: '@disableImagePreview'\n        },\n        {\n            action: 'deleteImageReferences',\n            disabled: '@disableImageReferencesDeletion'\n        }\n    );\n\n    // The File Upload Resize plugin extends the fileupload widget\n    // with image resize functionality:\n    $.widget('blueimp.fileupload', $.blueimp.fileupload, {\n\n        options: {\n            // The regular expression for the types of images to load:\n            // matched against the file type:\n            loadImageFileTypes: /^image\\/(gif|jpeg|png|svg\\+xml)$/,\n            // The maximum file size of images to load:\n            loadImageMaxFileSize: 10000000, // 10MB\n            // The maximum width of resized images:\n            imageMaxWidth: 1920,\n            // The maximum height of resized images:\n            imageMaxHeight: 1080,\n            // Defines the image orientation (1-8) or takes the orientation\n            // value from Exif data if set to true:\n            imageOrientation: false,\n            // Define if resized images should be cropped or only scaled:\n            imageCrop: false,\n            // Disable the resize image functionality by default:\n            disableImageResize: true,\n            // The maximum width of the preview images:\n            previewMaxWidth: 80,\n            // The maximum height of the preview images:\n            previewMaxHeight: 80,\n            // Defines the preview orientation (1-8) or takes the orientation\n            // value from Exif data if set to true:\n            previewOrientation: true,\n            // Create the preview using the Exif data thumbnail:\n            previewThumbnail: true,\n            // Define if preview images should be cropped or only scaled:\n            previewCrop: false,\n            // Define if preview images should be resized as canvas elements:\n            previewCanvas: true\n        },\n\n        processActions: {\n\n            // Loads the image given via data.files and data.index\n            // as img element, if the browser supports the File API.\n            // Accepts the options fileTypes (regular expression)\n            // and maxFileSize (integer) to limit the files to load:\n            loadImage: function (data, options) {\n                if (options.disabled) {\n                    return data;\n                }\n                var that = this,\n                    file = data.files[data.index],\n                    dfd = $.Deferred();\n                if (($.type(options.maxFileSize) === 'number' &&\n                            file.size > options.maxFileSize) ||\n                        (options.fileTypes &&\n                            !options.fileTypes.test(file.type)) ||\n                        !loadImage(\n                            file,\n                            function (img) {\n                                if (img.src) {\n                                    data.img = img;\n                                }\n                                dfd.resolveWith(that, [data]);\n                            },\n                            options\n                        )) {\n                    return data;\n                }\n                return dfd.promise();\n            },\n\n            // Resizes the image given as data.canvas or data.img\n            // and updates data.canvas or data.img with the resized image.\n            // Also stores the resized image as preview property.\n            // Accepts the options maxWidth, maxHeight, minWidth,\n            // minHeight, canvas and crop:\n            resizeImage: function (data, options) {\n                if (options.disabled || !(data.canvas || data.img)) {\n                    return data;\n                }\n                options = $.extend({canvas: true}, options);\n                var that = this,\n                    dfd = $.Deferred(),\n                    img = (options.canvas && data.canvas) || data.img,\n                    resolve = function (newImg) {\n                        if (newImg && (newImg.width !== img.width ||\n                                newImg.height !== img.height ||\n                                options.forceResize)) {\n                            data[newImg.getContext ? 'canvas' : 'img'] = newImg;\n                        }\n                        data.preview = newImg;\n                        dfd.resolveWith(that, [data]);\n                    },\n                    thumbnail;\n                if (data.exif) {\n                    if (options.orientation === true) {\n                        options.orientation = data.exif.get('Orientation');\n                    }\n                    if (options.thumbnail) {\n                        thumbnail = data.exif.get('Thumbnail');\n                        if (thumbnail) {\n                            loadImage(thumbnail, resolve, options);\n                            return dfd.promise();\n                        }\n                    }\n                    // Prevent orienting the same image twice:\n                    if (data.orientation) {\n                        delete options.orientation;\n                    } else {\n                        data.orientation = options.orientation;\n                    }\n                }\n                if (img) {\n                    resolve(loadImage.scale(img, options));\n                    return dfd.promise();\n                }\n                return data;\n            },\n\n            // Saves the processed image given as data.canvas\n            // inplace at data.index of data.files:\n            saveImage: function (data, options) {\n                if (!data.canvas || options.disabled) {\n                    return data;\n                }\n                var that = this,\n                    file = data.files[data.index],\n                    dfd = $.Deferred();\n                if (data.canvas.toBlob) {\n                    data.canvas.toBlob(\n                        function (blob) {\n                            if (!blob.name) {\n                                if (file.type === blob.type) {\n                                    blob.name = file.name;\n                                } else if (file.name) {\n                                    blob.name = file.name.replace(\n                                        /\\.\\w+$/,\n                                        '.' + blob.type.substr(6)\n                                    );\n                                }\n                            }\n                            // Don't restore invalid meta data:\n                            if (file.type !== blob.type) {\n                                delete data.imageHead;\n                            }\n                            // Store the created blob at the position\n                            // of the original file in the files list:\n                            data.files[data.index] = blob;\n                            dfd.resolveWith(that, [data]);\n                        },\n                        options.type || file.type,\n                        options.quality\n                    );\n                } else {\n                    return data;\n                }\n                return dfd.promise();\n            },\n\n            loadImageMetaData: function (data, options) {\n                if (options.disabled) {\n                    return data;\n                }\n                var that = this,\n                    dfd = $.Deferred();\n                loadImage.parseMetaData(data.files[data.index], function (result) {\n                    $.extend(data, result);\n                    dfd.resolveWith(that, [data]);\n                }, options);\n                return dfd.promise();\n            },\n\n            saveImageMetaData: function (data, options) {\n                if (!(data.imageHead && data.canvas &&\n                        data.canvas.toBlob && !options.disabled)) {\n                    return data;\n                }\n                var file = data.files[data.index],\n                    blob = new Blob([\n                        data.imageHead,\n                        // Resized images always have a head size of 20 bytes,\n                        // including the JPEG marker and a minimal JFIF header:\n                        this._blobSlice.call(file, 20)\n                    ], {type: file.type});\n                blob.name = file.name;\n                data.files[data.index] = blob;\n                return data;\n            },\n\n            // Sets the resized version of the image as a property of the\n            // file object, must be called after \"saveImage\":\n            setImage: function (data, options) {\n                if (data.preview && !options.disabled) {\n                    data.files[data.index][options.name || 'preview'] = data.preview;\n                }\n                return data;\n            },\n\n            deleteImageReferences: function (data, options) {\n                if (!options.disabled) {\n                    delete data.img;\n                    delete data.canvas;\n                    delete data.preview;\n                    delete data.imageHead;\n                }\n                return data;\n            }\n\n        }\n\n    });\n\n}));\n"
  },
  {
    "path": "app_frontend/static/plugin/jQuery-File-Upload-9.18.0/js/jquery.fileupload-jquery-ui.js",
    "content": "/*\n * jQuery File Upload jQuery UI Plugin\n * https://github.com/blueimp/jQuery-File-Upload\n *\n * Copyright 2013, Sebastian Tschan\n * https://blueimp.net\n *\n * Licensed under the MIT license:\n * https://opensource.org/licenses/MIT\n */\n\n/* jshint nomen:false */\n/* global define, require, window */\n\n;(function (factory) {\n    'use strict';\n    if (typeof define === 'function' && define.amd) {\n        // Register as an anonymous AMD module:\n        define([\n            'jquery',\n            './jquery.fileupload-ui'\n        ], factory);\n    } else if (typeof exports === 'object') {\n        // Node/CommonJS:\n        factory(\n            require('jquery'),\n            require('./jquery.fileupload-ui')\n        );\n    } else {\n        // Browser globals:\n        factory(window.jQuery);\n    }\n}(function ($) {\n    'use strict';\n\n    $.widget('blueimp.fileupload', $.blueimp.fileupload, {\n\n        options: {\n            processdone: function (e, data) {\n                data.context.find('.start').button('enable');\n            },\n            progress: function (e, data) {\n                if (data.context) {\n                    data.context.find('.progress').progressbar(\n                        'option',\n                        'value',\n                        parseInt(data.loaded / data.total * 100, 10)\n                    );\n                }\n            },\n            progressall: function (e, data) {\n                var $this = $(this);\n                $this.find('.fileupload-progress')\n                    .find('.progress').progressbar(\n                        'option',\n                        'value',\n                        parseInt(data.loaded / data.total * 100, 10)\n                    ).end()\n                    .find('.progress-extended').each(function () {\n                        $(this).html(\n                            ($this.data('blueimp-fileupload') ||\n                                    $this.data('fileupload'))\n                                ._renderExtendedProgress(data)\n                        );\n                    });\n            }\n        },\n\n        _renderUpload: function (func, files) {\n            var node = this._super(func, files),\n                showIconText = $(window).width() > 480;\n            node.find('.progress').empty().progressbar();\n            node.find('.start').button({\n                icons: {primary: 'ui-icon-circle-arrow-e'},\n                text: showIconText\n            });\n            node.find('.cancel').button({\n                icons: {primary: 'ui-icon-cancel'},\n                text: showIconText\n            });\n            if (node.hasClass('fade')) {\n                node.hide();\n            }\n            return node;\n        },\n\n        _renderDownload: function (func, files) {\n            var node = this._super(func, files),\n                showIconText = $(window).width() > 480;\n            node.find('.delete').button({\n                icons: {primary: 'ui-icon-trash'},\n                text: showIconText\n            });\n            if (node.hasClass('fade')) {\n                node.hide();\n            }\n            return node;\n        },\n\n        _startHandler: function (e) {\n            $(e.currentTarget).button('disable');\n            this._super(e);\n        },\n\n        _transition: function (node) {\n            var deferred = $.Deferred();\n            if (node.hasClass('fade')) {\n                node.fadeToggle(\n                    this.options.transitionDuration,\n                    this.options.transitionEasing,\n                    function () {\n                        deferred.resolveWith(node);\n                    }\n                );\n            } else {\n                deferred.resolveWith(node);\n            }\n            return deferred;\n        },\n\n        _create: function () {\n            this._super();\n            this.element\n                .find('.fileupload-buttonbar')\n                .find('.fileinput-button').each(function () {\n                    var input = $(this).find('input:file').detach();\n                    $(this)\n                        .button({icons: {primary: 'ui-icon-plusthick'}})\n                        .append(input);\n                })\n                .end().find('.start')\n                .button({icons: {primary: 'ui-icon-circle-arrow-e'}})\n                .end().find('.cancel')\n                .button({icons: {primary: 'ui-icon-cancel'}})\n                .end().find('.delete')\n                .button({icons: {primary: 'ui-icon-trash'}})\n                .end().find('.progress').progressbar();\n        },\n\n        _destroy: function () {\n            this.element\n                .find('.fileupload-buttonbar')\n                .find('.fileinput-button').each(function () {\n                    var input = $(this).find('input:file').detach();\n                    $(this)\n                        .button('destroy')\n                        .append(input);\n                })\n                .end().find('.start')\n                .button('destroy')\n                .end().find('.cancel')\n                .button('destroy')\n                .end().find('.delete')\n                .button('destroy')\n                .end().find('.progress').progressbar('destroy');\n            this._super();\n        }\n\n    });\n\n}));\n"
  },
  {
    "path": "app_frontend/static/plugin/jQuery-File-Upload-9.18.0/js/jquery.fileupload-process.js",
    "content": "/*\n * jQuery File Upload Processing Plugin\n * https://github.com/blueimp/jQuery-File-Upload\n *\n * Copyright 2012, Sebastian Tschan\n * https://blueimp.net\n *\n * Licensed under the MIT license:\n * https://opensource.org/licenses/MIT\n */\n\n/* jshint nomen:false */\n/* global define, require, window */\n\n;(function (factory) {\n    'use strict';\n    if (typeof define === 'function' && define.amd) {\n        // Register as an anonymous AMD module:\n        define([\n            'jquery',\n            './jquery.fileupload'\n        ], factory);\n    } else if (typeof exports === 'object') {\n        // Node/CommonJS:\n        factory(\n            require('jquery'),\n            require('./jquery.fileupload')\n        );\n    } else {\n        // Browser globals:\n        factory(\n            window.jQuery\n        );\n    }\n}(function ($) {\n    'use strict';\n\n    var originalAdd = $.blueimp.fileupload.prototype.options.add;\n\n    // The File Upload Processing plugin extends the fileupload widget\n    // with file processing functionality:\n    $.widget('blueimp.fileupload', $.blueimp.fileupload, {\n\n        options: {\n            // The list of processing actions:\n            processQueue: [\n                /*\n                {\n                    action: 'log',\n                    type: 'debug'\n                }\n                */\n            ],\n            add: function (e, data) {\n                var $this = $(this);\n                data.process(function () {\n                    return $this.fileupload('process', data);\n                });\n                originalAdd.call(this, e, data);\n            }\n        },\n\n        processActions: {\n            /*\n            log: function (data, options) {\n                console[options.type](\n                    'Processing \"' + data.files[data.index].name + '\"'\n                );\n            }\n            */\n        },\n\n        _processFile: function (data, originalData) {\n            var that = this,\n                dfd = $.Deferred().resolveWith(that, [data]),\n                chain = dfd.promise();\n            this._trigger('process', null, data);\n            $.each(data.processQueue, function (i, settings) {\n                var func = function (data) {\n                    if (originalData.errorThrown) {\n                        return $.Deferred()\n                                .rejectWith(that, [originalData]).promise();\n                    }\n                    return that.processActions[settings.action].call(\n                        that,\n                        data,\n                        settings\n                    );\n                };\n                chain = chain.then(func, settings.always && func);\n            });\n            chain\n                .done(function () {\n                    that._trigger('processdone', null, data);\n                    that._trigger('processalways', null, data);\n                })\n                .fail(function () {\n                    that._trigger('processfail', null, data);\n                    that._trigger('processalways', null, data);\n                });\n            return chain;\n        },\n\n        // Replaces the settings of each processQueue item that\n        // are strings starting with an \"@\", using the remaining\n        // substring as key for the option map,\n        // e.g. \"@autoUpload\" is replaced with options.autoUpload:\n        _transformProcessQueue: function (options) {\n            var processQueue = [];\n            $.each(options.processQueue, function () {\n                var settings = {},\n                    action = this.action,\n                    prefix = this.prefix === true ? action : this.prefix;\n                $.each(this, function (key, value) {\n                    if ($.type(value) === 'string' &&\n                            value.charAt(0) === '@') {\n                        settings[key] = options[\n                            value.slice(1) || (prefix ? prefix +\n                                key.charAt(0).toUpperCase() + key.slice(1) : key)\n                        ];\n                    } else {\n                        settings[key] = value;\n                    }\n\n                });\n                processQueue.push(settings);\n            });\n            options.processQueue = processQueue;\n        },\n\n        // Returns the number of files currently in the processsing queue:\n        processing: function () {\n            return this._processing;\n        },\n\n        // Processes the files given as files property of the data parameter,\n        // returns a Promise object that allows to bind callbacks:\n        process: function (data) {\n            var that = this,\n                options = $.extend({}, this.options, data);\n            if (options.processQueue && options.processQueue.length) {\n                this._transformProcessQueue(options);\n                if (this._processing === 0) {\n                    this._trigger('processstart');\n                }\n                $.each(data.files, function (index) {\n                    var opts = index ? $.extend({}, options) : options,\n                        func = function () {\n                            if (data.errorThrown) {\n                                return $.Deferred()\n                                        .rejectWith(that, [data]).promise();\n                            }\n                            return that._processFile(opts, data);\n                        };\n                    opts.index = index;\n                    that._processing += 1;\n                    that._processingQueue = that._processingQueue.then(func, func)\n                        .always(function () {\n                            that._processing -= 1;\n                            if (that._processing === 0) {\n                                that._trigger('processstop');\n                            }\n                        });\n                });\n            }\n            return this._processingQueue;\n        },\n\n        _create: function () {\n            this._super();\n            this._processing = 0;\n            this._processingQueue = $.Deferred().resolveWith(this)\n                .promise();\n        }\n\n    });\n\n}));\n"
  },
  {
    "path": "app_frontend/static/plugin/jQuery-File-Upload-9.18.0/js/jquery.fileupload-ui.js",
    "content": "/*\n * jQuery File Upload User Interface Plugin\n * https://github.com/blueimp/jQuery-File-Upload\n *\n * Copyright 2010, Sebastian Tschan\n * https://blueimp.net\n *\n * Licensed under the MIT license:\n * https://opensource.org/licenses/MIT\n */\n\n/* jshint nomen:false */\n/* global define, require, window */\n\n;(function (factory) {\n    'use strict';\n    if (typeof define === 'function' && define.amd) {\n        // Register as an anonymous AMD module:\n        define([\n            'jquery',\n            'blueimp-tmpl',\n            './jquery.fileupload-image',\n            './jquery.fileupload-audio',\n            './jquery.fileupload-video',\n            './jquery.fileupload-validate'\n        ], factory);\n    } else if (typeof exports === 'object') {\n        // Node/CommonJS:\n        factory(\n            require('jquery'),\n            require('blueimp-tmpl'),\n            require('./jquery.fileupload-image'),\n            require('./jquery.fileupload-video'),\n            require('./jquery.fileupload-validate')\n        );\n    } else {\n        // Browser globals:\n        factory(\n            window.jQuery,\n            window.tmpl\n        );\n    }\n}(function ($, tmpl) {\n    'use strict';\n\n    $.blueimp.fileupload.prototype._specialOptions.push(\n        'filesContainer',\n        'uploadTemplateId',\n        'downloadTemplateId'\n    );\n\n    // The UI version extends the file upload widget\n    // and adds complete user interface interaction:\n    $.widget('blueimp.fileupload', $.blueimp.fileupload, {\n\n        options: {\n            // By default, files added to the widget are uploaded as soon\n            // as the user clicks on the start buttons. To enable automatic\n            // uploads, set the following option to true:\n            autoUpload: false,\n            // The ID of the upload template:\n            uploadTemplateId: 'template-upload',\n            // The ID of the download template:\n            downloadTemplateId: 'template-download',\n            // The container for the list of files. If undefined, it is set to\n            // an element with class \"files\" inside of the widget element:\n            filesContainer: undefined,\n            // By default, files are appended to the files container.\n            // Set the following option to true, to prepend files instead:\n            prependFiles: false,\n            // The expected data type of the upload response, sets the dataType\n            // option of the $.ajax upload requests:\n            dataType: 'json',\n\n            // Error and info messages:\n            messages: {\n                unknownError: 'Unknown error'\n            },\n\n            // Function returning the current number of files,\n            // used by the maxNumberOfFiles validation:\n            getNumberOfFiles: function () {\n                return this.filesContainer.children()\n                    .not('.processing').length;\n            },\n\n            // Callback to retrieve the list of files from the server response:\n            getFilesFromResponse: function (data) {\n                if (data.result && $.isArray(data.result.files)) {\n                    return data.result.files;\n                }\n                return [];\n            },\n\n            // The add callback is invoked as soon as files are added to the fileupload\n            // widget (via file input selection, drag & drop or add API call).\n            // See the basic file upload widget for more information:\n            add: function (e, data) {\n                if (e.isDefaultPrevented()) {\n                    return false;\n                }\n                var $this = $(this),\n                    that = $this.data('blueimp-fileupload') ||\n                        $this.data('fileupload'),\n                    options = that.options;\n                data.context = that._renderUpload(data.files)\n                    .data('data', data)\n                    .addClass('processing');\n                options.filesContainer[\n                    options.prependFiles ? 'prepend' : 'append'\n                ](data.context);\n                that._forceReflow(data.context);\n                that._transition(data.context);\n                data.process(function () {\n                    return $this.fileupload('process', data);\n                }).always(function () {\n                    data.context.each(function (index) {\n                        $(this).find('.size').text(\n                            that._formatFileSize(data.files[index].size)\n                        );\n                    }).removeClass('processing');\n                    that._renderPreviews(data);\n                }).done(function () {\n                    data.context.find('.start').prop('disabled', false);\n                    if ((that._trigger('added', e, data) !== false) &&\n                            (options.autoUpload || data.autoUpload) &&\n                            data.autoUpload !== false) {\n                        data.submit();\n                    }\n                }).fail(function () {\n                    if (data.files.error) {\n                        data.context.each(function (index) {\n                            var error = data.files[index].error;\n                            if (error) {\n                                $(this).find('.error').text(error);\n                            }\n                        });\n                    }\n                });\n            },\n            // Callback for the start of each file upload request:\n            send: function (e, data) {\n                if (e.isDefaultPrevented()) {\n                    return false;\n                }\n                var that = $(this).data('blueimp-fileupload') ||\n                        $(this).data('fileupload');\n                if (data.context && data.dataType &&\n                        data.dataType.substr(0, 6) === 'iframe') {\n                    // Iframe Transport does not support progress events.\n                    // In lack of an indeterminate progress bar, we set\n                    // the progress to 100%, showing the full animated bar:\n                    data.context\n                        .find('.progress').addClass(\n                            !$.support.transition && 'progress-animated'\n                        )\n                        .attr('aria-valuenow', 100)\n                        .children().first().css(\n                            'width',\n                            '100%'\n                        );\n                }\n                return that._trigger('sent', e, data);\n            },\n            // Callback for successful uploads:\n            done: function (e, data) {\n                if (e.isDefaultPrevented()) {\n                    return false;\n                }\n                var that = $(this).data('blueimp-fileupload') ||\n                        $(this).data('fileupload'),\n                    getFilesFromResponse = data.getFilesFromResponse ||\n                        that.options.getFilesFromResponse,\n                    files = getFilesFromResponse(data),\n                    template,\n                    deferred;\n                if (data.context) {\n                    data.context.each(function (index) {\n                        var file = files[index] ||\n                                {error: 'Empty file upload result'};\n                        deferred = that._addFinishedDeferreds();\n                        that._transition($(this)).done(\n                            function () {\n                                var node = $(this);\n                                template = that._renderDownload([file])\n                                    .replaceAll(node);\n                                that._forceReflow(template);\n                                that._transition(template).done(\n                                    function () {\n                                        data.context = $(this);\n                                        that._trigger('completed', e, data);\n                                        that._trigger('finished', e, data);\n                                        deferred.resolve();\n                                    }\n                                );\n                            }\n                        );\n                    });\n                } else {\n                    template = that._renderDownload(files)[\n                        that.options.prependFiles ? 'prependTo' : 'appendTo'\n                    ](that.options.filesContainer);\n                    that._forceReflow(template);\n                    deferred = that._addFinishedDeferreds();\n                    that._transition(template).done(\n                        function () {\n                            data.context = $(this);\n                            that._trigger('completed', e, data);\n                            that._trigger('finished', e, data);\n                            deferred.resolve();\n                        }\n                    );\n                }\n            },\n            // Callback for failed (abort or error) uploads:\n            fail: function (e, data) {\n                if (e.isDefaultPrevented()) {\n                    return false;\n                }\n                var that = $(this).data('blueimp-fileupload') ||\n                        $(this).data('fileupload'),\n                    template,\n                    deferred;\n                if (data.context) {\n                    data.context.each(function (index) {\n                        if (data.errorThrown !== 'abort') {\n                            var file = data.files[index];\n                            file.error = file.error || data.errorThrown ||\n                                data.i18n('unknownError');\n                            deferred = that._addFinishedDeferreds();\n                            that._transition($(this)).done(\n                                function () {\n                                    var node = $(this);\n                                    template = that._renderDownload([file])\n                                        .replaceAll(node);\n                                    that._forceReflow(template);\n                                    that._transition(template).done(\n                                        function () {\n                                            data.context = $(this);\n                                            that._trigger('failed', e, data);\n                                            that._trigger('finished', e, data);\n                                            deferred.resolve();\n                                        }\n                                    );\n                                }\n                            );\n                        } else {\n                            deferred = that._addFinishedDeferreds();\n                            that._transition($(this)).done(\n                                function () {\n                                    $(this).remove();\n                                    that._trigger('failed', e, data);\n                                    that._trigger('finished', e, data);\n                                    deferred.resolve();\n                                }\n                            );\n                        }\n                    });\n                } else if (data.errorThrown !== 'abort') {\n                    data.context = that._renderUpload(data.files)[\n                        that.options.prependFiles ? 'prependTo' : 'appendTo'\n                    ](that.options.filesContainer)\n                        .data('data', data);\n                    that._forceReflow(data.context);\n                    deferred = that._addFinishedDeferreds();\n                    that._transition(data.context).done(\n                        function () {\n                            data.context = $(this);\n                            that._trigger('failed', e, data);\n                            that._trigger('finished', e, data);\n                            deferred.resolve();\n                        }\n                    );\n                } else {\n                    that._trigger('failed', e, data);\n                    that._trigger('finished', e, data);\n                    that._addFinishedDeferreds().resolve();\n                }\n            },\n            // Callback for upload progress events:\n            progress: function (e, data) {\n                if (e.isDefaultPrevented()) {\n                    return false;\n                }\n                var progress = Math.floor(data.loaded / data.total * 100);\n                if (data.context) {\n                    data.context.each(function () {\n                        $(this).find('.progress')\n                            .attr('aria-valuenow', progress)\n                            .children().first().css(\n                                'width',\n                                progress + '%'\n                            );\n                    });\n                }\n            },\n            // Callback for global upload progress events:\n            progressall: function (e, data) {\n                if (e.isDefaultPrevented()) {\n                    return false;\n                }\n                var $this = $(this),\n                    progress = Math.floor(data.loaded / data.total * 100),\n                    globalProgressNode = $this.find('.fileupload-progress'),\n                    extendedProgressNode = globalProgressNode\n                        .find('.progress-extended');\n                if (extendedProgressNode.length) {\n                    extendedProgressNode.html(\n                        ($this.data('blueimp-fileupload') || $this.data('fileupload'))\n                            ._renderExtendedProgress(data)\n                    );\n                }\n                globalProgressNode\n                    .find('.progress')\n                    .attr('aria-valuenow', progress)\n                    .children().first().css(\n                        'width',\n                        progress + '%'\n                    );\n            },\n            // Callback for uploads start, equivalent to the global ajaxStart event:\n            start: function (e) {\n                if (e.isDefaultPrevented()) {\n                    return false;\n                }\n                var that = $(this).data('blueimp-fileupload') ||\n                        $(this).data('fileupload');\n                that._resetFinishedDeferreds();\n                that._transition($(this).find('.fileupload-progress')).done(\n                    function () {\n                        that._trigger('started', e);\n                    }\n                );\n            },\n            // Callback for uploads stop, equivalent to the global ajaxStop event:\n            stop: function (e) {\n                if (e.isDefaultPrevented()) {\n                    return false;\n                }\n                var that = $(this).data('blueimp-fileupload') ||\n                        $(this).data('fileupload'),\n                    deferred = that._addFinishedDeferreds();\n                $.when.apply($, that._getFinishedDeferreds())\n                    .done(function () {\n                        that._trigger('stopped', e);\n                    });\n                that._transition($(this).find('.fileupload-progress')).done(\n                    function () {\n                        $(this).find('.progress')\n                            .attr('aria-valuenow', '0')\n                            .children().first().css('width', '0%');\n                        $(this).find('.progress-extended').html('&nbsp;');\n                        deferred.resolve();\n                    }\n                );\n            },\n            processstart: function (e) {\n                if (e.isDefaultPrevented()) {\n                    return false;\n                }\n                $(this).addClass('fileupload-processing');\n            },\n            processstop: function (e) {\n                if (e.isDefaultPrevented()) {\n                    return false;\n                }\n                $(this).removeClass('fileupload-processing');\n            },\n            // Callback for file deletion:\n            destroy: function (e, data) {\n                if (e.isDefaultPrevented()) {\n                    return false;\n                }\n                var that = $(this).data('blueimp-fileupload') ||\n                        $(this).data('fileupload'),\n                    removeNode = function () {\n                        that._transition(data.context).done(\n                            function () {\n                                $(this).remove();\n                                that._trigger('destroyed', e, data);\n                            }\n                        );\n                    };\n                if (data.url) {\n                    data.dataType = data.dataType || that.options.dataType;\n                    $.ajax(data).done(removeNode).fail(function () {\n                        that._trigger('destroyfailed', e, data);\n                    });\n                } else {\n                    removeNode();\n                }\n            }\n        },\n\n        _resetFinishedDeferreds: function () {\n            this._finishedUploads = [];\n        },\n\n        _addFinishedDeferreds: function (deferred) {\n            if (!deferred) {\n                deferred = $.Deferred();\n            }\n            this._finishedUploads.push(deferred);\n            return deferred;\n        },\n\n        _getFinishedDeferreds: function () {\n            return this._finishedUploads;\n        },\n\n        // Link handler, that allows to download files\n        // by drag & drop of the links to the desktop:\n        _enableDragToDesktop: function () {\n            var link = $(this),\n                url = link.prop('href'),\n                name = link.prop('download'),\n                type = 'application/octet-stream';\n            link.bind('dragstart', function (e) {\n                try {\n                    e.originalEvent.dataTransfer.setData(\n                        'DownloadURL',\n                        [type, name, url].join(':')\n                    );\n                } catch (ignore) {}\n            });\n        },\n\n        _formatFileSize: function (bytes) {\n            if (typeof bytes !== 'number') {\n                return '';\n            }\n            if (bytes >= 1000000000) {\n                return (bytes / 1000000000).toFixed(2) + ' GB';\n            }\n            if (bytes >= 1000000) {\n                return (bytes / 1000000).toFixed(2) + ' MB';\n            }\n            return (bytes / 1000).toFixed(2) + ' KB';\n        },\n\n        _formatBitrate: function (bits) {\n            if (typeof bits !== 'number') {\n                return '';\n            }\n            if (bits >= 1000000000) {\n                return (bits / 1000000000).toFixed(2) + ' Gbit/s';\n            }\n            if (bits >= 1000000) {\n                return (bits / 1000000).toFixed(2) + ' Mbit/s';\n            }\n            if (bits >= 1000) {\n                return (bits / 1000).toFixed(2) + ' kbit/s';\n            }\n            return bits.toFixed(2) + ' bit/s';\n        },\n\n        _formatTime: function (seconds) {\n            var date = new Date(seconds * 1000),\n                days = Math.floor(seconds / 86400);\n            days = days ? days + 'd ' : '';\n            return days +\n                ('0' + date.getUTCHours()).slice(-2) + ':' +\n                ('0' + date.getUTCMinutes()).slice(-2) + ':' +\n                ('0' + date.getUTCSeconds()).slice(-2);\n        },\n\n        _formatPercentage: function (floatValue) {\n            return (floatValue * 100).toFixed(2) + ' %';\n        },\n\n        _renderExtendedProgress: function (data) {\n            return this._formatBitrate(data.bitrate) + ' | ' +\n                this._formatTime(\n                    (data.total - data.loaded) * 8 / data.bitrate\n                ) + ' | ' +\n                this._formatPercentage(\n                    data.loaded / data.total\n                ) + ' | ' +\n                this._formatFileSize(data.loaded) + ' / ' +\n                this._formatFileSize(data.total);\n        },\n\n        _renderTemplate: function (func, files) {\n            if (!func) {\n                return $();\n            }\n            var result = func({\n                files: files,\n                formatFileSize: this._formatFileSize,\n                options: this.options\n            });\n            if (result instanceof $) {\n                return result;\n            }\n            return $(this.options.templatesContainer).html(result).children();\n        },\n\n        _renderPreviews: function (data) {\n            data.context.find('.preview').each(function (index, elm) {\n                $(elm).append(data.files[index].preview);\n            });\n        },\n\n        _renderUpload: function (files) {\n            return this._renderTemplate(\n                this.options.uploadTemplate,\n                files\n            );\n        },\n\n        _renderDownload: function (files) {\n            return this._renderTemplate(\n                this.options.downloadTemplate,\n                files\n            ).find('a[download]').each(this._enableDragToDesktop).end();\n        },\n\n        _startHandler: function (e) {\n            e.preventDefault();\n            var button = $(e.currentTarget),\n                template = button.closest('.template-upload'),\n                data = template.data('data');\n            button.prop('disabled', true);\n            if (data && data.submit) {\n                data.submit();\n            }\n        },\n\n        _cancelHandler: function (e) {\n            e.preventDefault();\n            var template = $(e.currentTarget)\n                    .closest('.template-upload,.template-download'),\n                data = template.data('data') || {};\n            data.context = data.context || template;\n            if (data.abort) {\n                data.abort();\n            } else {\n                data.errorThrown = 'abort';\n                this._trigger('fail', e, data);\n            }\n        },\n\n        _deleteHandler: function (e) {\n            e.preventDefault();\n            var button = $(e.currentTarget);\n            this._trigger('destroy', e, $.extend({\n                context: button.closest('.template-download'),\n                type: 'DELETE'\n            }, button.data()));\n        },\n\n        _forceReflow: function (node) {\n            return $.support.transition && node.length &&\n                node[0].offsetWidth;\n        },\n\n        _transition: function (node) {\n            var dfd = $.Deferred();\n            if ($.support.transition && node.hasClass('fade') && node.is(':visible')) {\n                node.bind(\n                    $.support.transition.end,\n                    function (e) {\n                        // Make sure we don't respond to other transitions events\n                        // in the container element, e.g. from button elements:\n                        if (e.target === node[0]) {\n                            node.unbind($.support.transition.end);\n                            dfd.resolveWith(node);\n                        }\n                    }\n                ).toggleClass('in');\n            } else {\n                node.toggleClass('in');\n                dfd.resolveWith(node);\n            }\n            return dfd;\n        },\n\n        _initButtonBarEventHandlers: function () {\n            var fileUploadButtonBar = this.element.find('.fileupload-buttonbar'),\n                filesList = this.options.filesContainer;\n            this._on(fileUploadButtonBar.find('.start'), {\n                click: function (e) {\n                    e.preventDefault();\n                    filesList.find('.start').click();\n                }\n            });\n            this._on(fileUploadButtonBar.find('.cancel'), {\n                click: function (e) {\n                    e.preventDefault();\n                    filesList.find('.cancel').click();\n                }\n            });\n            this._on(fileUploadButtonBar.find('.delete'), {\n                click: function (e) {\n                    e.preventDefault();\n                    filesList.find('.toggle:checked')\n                        .closest('.template-download')\n                        .find('.delete').click();\n                    fileUploadButtonBar.find('.toggle')\n                        .prop('checked', false);\n                }\n            });\n            this._on(fileUploadButtonBar.find('.toggle'), {\n                change: function (e) {\n                    filesList.find('.toggle').prop(\n                        'checked',\n                        $(e.currentTarget).is(':checked')\n                    );\n                }\n            });\n        },\n\n        _destroyButtonBarEventHandlers: function () {\n            this._off(\n                this.element.find('.fileupload-buttonbar')\n                    .find('.start, .cancel, .delete'),\n                'click'\n            );\n            this._off(\n                this.element.find('.fileupload-buttonbar .toggle'),\n                'change.'\n            );\n        },\n\n        _initEventHandlers: function () {\n            this._super();\n            this._on(this.options.filesContainer, {\n                'click .start': this._startHandler,\n                'click .cancel': this._cancelHandler,\n                'click .delete': this._deleteHandler\n            });\n            this._initButtonBarEventHandlers();\n        },\n\n        _destroyEventHandlers: function () {\n            this._destroyButtonBarEventHandlers();\n            this._off(this.options.filesContainer, 'click');\n            this._super();\n        },\n\n        _enableFileInputButton: function () {\n            this.element.find('.fileinput-button input')\n                .prop('disabled', false)\n                .parent().removeClass('disabled');\n        },\n\n        _disableFileInputButton: function () {\n            this.element.find('.fileinput-button input')\n                .prop('disabled', true)\n                .parent().addClass('disabled');\n        },\n\n        _initTemplates: function () {\n            var options = this.options;\n            options.templatesContainer = this.document[0].createElement(\n                options.filesContainer.prop('nodeName')\n            );\n            if (tmpl) {\n                if (options.uploadTemplateId) {\n                    options.uploadTemplate = tmpl(options.uploadTemplateId);\n                }\n                if (options.downloadTemplateId) {\n                    options.downloadTemplate = tmpl(options.downloadTemplateId);\n                }\n            }\n        },\n\n        _initFilesContainer: function () {\n            var options = this.options;\n            if (options.filesContainer === undefined) {\n                options.filesContainer = this.element.find('.files');\n            } else if (!(options.filesContainer instanceof $)) {\n                options.filesContainer = $(options.filesContainer);\n            }\n        },\n\n        _initSpecialOptions: function () {\n            this._super();\n            this._initFilesContainer();\n            this._initTemplates();\n        },\n\n        _create: function () {\n            this._super();\n            this._resetFinishedDeferreds();\n            if (!$.support.fileInput) {\n                this._disableFileInputButton();\n            }\n        },\n\n        enable: function () {\n            var wasDisabled = false;\n            if (this.options.disabled) {\n                wasDisabled = true;\n            }\n            this._super();\n            if (wasDisabled) {\n                this.element.find('input, button').prop('disabled', false);\n                this._enableFileInputButton();\n            }\n        },\n\n        disable: function () {\n            if (!this.options.disabled) {\n                this.element.find('input, button').prop('disabled', true);\n                this._disableFileInputButton();\n            }\n            this._super();\n        }\n\n    });\n\n}));\n"
  },
  {
    "path": "app_frontend/static/plugin/jQuery-File-Upload-9.18.0/js/jquery.fileupload-validate.js",
    "content": "/*\n * jQuery File Upload Validation Plugin\n * https://github.com/blueimp/jQuery-File-Upload\n *\n * Copyright 2013, Sebastian Tschan\n * https://blueimp.net\n *\n * Licensed under the MIT license:\n * https://opensource.org/licenses/MIT\n */\n\n/* global define, require, window */\n\n;(function (factory) {\n    'use strict';\n    if (typeof define === 'function' && define.amd) {\n        // Register as an anonymous AMD module:\n        define([\n            'jquery',\n            './jquery.fileupload-process'\n        ], factory);\n    } else if (typeof exports === 'object') {\n        // Node/CommonJS:\n        factory(\n            require('jquery'),\n            require('./jquery.fileupload-process')\n        );\n    } else {\n        // Browser globals:\n        factory(\n            window.jQuery\n        );\n    }\n}(function ($) {\n    'use strict';\n\n    // Append to the default processQueue:\n    $.blueimp.fileupload.prototype.options.processQueue.push(\n        {\n            action: 'validate',\n            // Always trigger this action,\n            // even if the previous action was rejected:\n            always: true,\n            // Options taken from the global options map:\n            acceptFileTypes: '@',\n            maxFileSize: '@',\n            minFileSize: '@',\n            maxNumberOfFiles: '@',\n            disabled: '@disableValidation'\n        }\n    );\n\n    // The File Upload Validation plugin extends the fileupload widget\n    // with file validation functionality:\n    $.widget('blueimp.fileupload', $.blueimp.fileupload, {\n\n        options: {\n            /*\n            // The regular expression for allowed file types, matches\n            // against either file type or file name:\n            acceptFileTypes: /(\\.|\\/)(gif|jpe?g|png)$/i,\n            // The maximum allowed file size in bytes:\n            maxFileSize: 10000000, // 10 MB\n            // The minimum allowed file size in bytes:\n            minFileSize: undefined, // No minimal file size\n            // The limit of files to be uploaded:\n            maxNumberOfFiles: 10,\n            */\n\n            // Function returning the current number of files,\n            // has to be overriden for maxNumberOfFiles validation:\n            getNumberOfFiles: $.noop,\n\n            // Error and info messages:\n            messages: {\n                maxNumberOfFiles: 'Maximum number of files exceeded',\n                acceptFileTypes: 'File type not allowed',\n                maxFileSize: 'File is too large',\n                minFileSize: 'File is too small'\n            }\n        },\n\n        processActions: {\n\n            validate: function (data, options) {\n                if (options.disabled) {\n                    return data;\n                }\n                var dfd = $.Deferred(),\n                    settings = this.options,\n                    file = data.files[data.index],\n                    fileSize;\n                if (options.minFileSize || options.maxFileSize) {\n                    fileSize = file.size;\n                }\n                if ($.type(options.maxNumberOfFiles) === 'number' &&\n                        (settings.getNumberOfFiles() || 0) + data.files.length >\n                            options.maxNumberOfFiles) {\n                    file.error = settings.i18n('maxNumberOfFiles');\n                } else if (options.acceptFileTypes &&\n                        !(options.acceptFileTypes.test(file.type) ||\n                        options.acceptFileTypes.test(file.name))) {\n                    file.error = settings.i18n('acceptFileTypes');\n                } else if (fileSize > options.maxFileSize) {\n                    file.error = settings.i18n('maxFileSize');\n                } else if ($.type(fileSize) === 'number' &&\n                        fileSize < options.minFileSize) {\n                    file.error = settings.i18n('minFileSize');\n                } else {\n                    delete file.error;\n                }\n                if (file.error || data.files.error) {\n                    data.files.error = true;\n                    dfd.rejectWith(this, [data]);\n                } else {\n                    dfd.resolveWith(this, [data]);\n                }\n                return dfd.promise();\n            }\n\n        }\n\n    });\n\n}));\n"
  },
  {
    "path": "app_frontend/static/plugin/jQuery-File-Upload-9.18.0/js/jquery.fileupload-video.js",
    "content": "/*\n * jQuery File Upload Video Preview Plugin\n * https://github.com/blueimp/jQuery-File-Upload\n *\n * Copyright 2013, Sebastian Tschan\n * https://blueimp.net\n *\n * Licensed under the MIT license:\n * https://opensource.org/licenses/MIT\n */\n\n/* jshint nomen:false */\n/* global define, require, window, document */\n\n;(function (factory) {\n    'use strict';\n    if (typeof define === 'function' && define.amd) {\n        // Register as an anonymous AMD module:\n        define([\n            'jquery',\n            'load-image',\n            './jquery.fileupload-process'\n        ], factory);\n    } else if (typeof exports === 'object') {\n        // Node/CommonJS:\n        factory(\n            require('jquery'),\n            require('blueimp-load-image/js/load-image'),\n            require('./jquery.fileupload-process')\n        );\n    } else {\n        // Browser globals:\n        factory(\n            window.jQuery,\n            window.loadImage\n        );\n    }\n}(function ($, loadImage) {\n    'use strict';\n\n    // Prepend to the default processQueue:\n    $.blueimp.fileupload.prototype.options.processQueue.unshift(\n        {\n            action: 'loadVideo',\n            // Use the action as prefix for the \"@\" options:\n            prefix: true,\n            fileTypes: '@',\n            maxFileSize: '@',\n            disabled: '@disableVideoPreview'\n        },\n        {\n            action: 'setVideo',\n            name: '@videoPreviewName',\n            disabled: '@disableVideoPreview'\n        }\n    );\n\n    // The File Upload Video Preview plugin extends the fileupload widget\n    // with video preview functionality:\n    $.widget('blueimp.fileupload', $.blueimp.fileupload, {\n\n        options: {\n            // The regular expression for the types of video files to load,\n            // matched against the file type:\n            loadVideoFileTypes: /^video\\/.*$/\n        },\n\n        _videoElement: document.createElement('video'),\n\n        processActions: {\n\n            // Loads the video file given via data.files and data.index\n            // as video element if the browser supports playing it.\n            // Accepts the options fileTypes (regular expression)\n            // and maxFileSize (integer) to limit the files to load:\n            loadVideo: function (data, options) {\n                if (options.disabled) {\n                    return data;\n                }\n                var file = data.files[data.index],\n                    url,\n                    video;\n                if (this._videoElement.canPlayType &&\n                        this._videoElement.canPlayType(file.type) &&\n                        ($.type(options.maxFileSize) !== 'number' ||\n                            file.size <= options.maxFileSize) &&\n                        (!options.fileTypes ||\n                            options.fileTypes.test(file.type))) {\n                    url = loadImage.createObjectURL(file);\n                    if (url) {\n                        video = this._videoElement.cloneNode(false);\n                        video.src = url;\n                        video.controls = true;\n                        data.video = video;\n                        return data;\n                    }\n                }\n                return data;\n            },\n\n            // Sets the video element as a property of the file object:\n            setVideo: function (data, options) {\n                if (data.video && !options.disabled) {\n                    data.files[data.index][options.name || 'preview'] = data.video;\n                }\n                return data;\n            }\n\n        }\n\n    });\n\n}));\n"
  },
  {
    "path": "app_frontend/static/plugin/jQuery-File-Upload-9.18.0/js/jquery.fileupload.js",
    "content": "/*\n * jQuery File Upload Plugin\n * https://github.com/blueimp/jQuery-File-Upload\n *\n * Copyright 2010, Sebastian Tschan\n * https://blueimp.net\n *\n * Licensed under the MIT license:\n * https://opensource.org/licenses/MIT\n */\n\n/* jshint nomen:false */\n/* global define, require, window, document, location, Blob, FormData */\n\n;(function (factory) {\n    'use strict';\n    if (typeof define === 'function' && define.amd) {\n        // Register as an anonymous AMD module:\n        define([\n            'jquery',\n            'jquery-ui/ui/widget'\n        ], factory);\n    } else if (typeof exports === 'object') {\n        // Node/CommonJS:\n        factory(\n            require('jquery'),\n            require('./vendor/jquery.ui.widget')\n        );\n    } else {\n        // Browser globals:\n        factory(window.jQuery);\n    }\n}(function ($) {\n    'use strict';\n\n    // Detect file input support, based on\n    // http://viljamis.com/blog/2012/file-upload-support-on-mobile/\n    $.support.fileInput = !(new RegExp(\n        // Handle devices which give false positives for the feature detection:\n        '(Android (1\\\\.[0156]|2\\\\.[01]))' +\n            '|(Windows Phone (OS 7|8\\\\.0))|(XBLWP)|(ZuneWP)|(WPDesktop)' +\n            '|(w(eb)?OSBrowser)|(webOS)' +\n            '|(Kindle/(1\\\\.0|2\\\\.[05]|3\\\\.0))'\n    ).test(window.navigator.userAgent) ||\n        // Feature detection for all other devices:\n        $('<input type=\"file\">').prop('disabled'));\n\n    // The FileReader API is not actually used, but works as feature detection,\n    // as some Safari versions (5?) support XHR file uploads via the FormData API,\n    // but not non-multipart XHR file uploads.\n    // window.XMLHttpRequestUpload is not available on IE10, so we check for\n    // window.ProgressEvent instead to detect XHR2 file upload capability:\n    $.support.xhrFileUpload = !!(window.ProgressEvent && window.FileReader);\n    $.support.xhrFormDataFileUpload = !!window.FormData;\n\n    // Detect support for Blob slicing (required for chunked uploads):\n    $.support.blobSlice = window.Blob && (Blob.prototype.slice ||\n        Blob.prototype.webkitSlice || Blob.prototype.mozSlice);\n\n    // Helper function to create drag handlers for dragover/dragenter/dragleave:\n    function getDragHandler(type) {\n        var isDragOver = type === 'dragover';\n        return function (e) {\n            e.dataTransfer = e.originalEvent && e.originalEvent.dataTransfer;\n            var dataTransfer = e.dataTransfer;\n            if (dataTransfer && $.inArray('Files', dataTransfer.types) !== -1 &&\n                    this._trigger(\n                        type,\n                        $.Event(type, {delegatedEvent: e})\n                    ) !== false) {\n                e.preventDefault();\n                if (isDragOver) {\n                    dataTransfer.dropEffect = 'copy';\n                }\n            }\n        };\n    }\n\n    // The fileupload widget listens for change events on file input fields defined\n    // via fileInput setting and paste or drop events of the given dropZone.\n    // In addition to the default jQuery Widget methods, the fileupload widget\n    // exposes the \"add\" and \"send\" methods, to add or directly send files using\n    // the fileupload API.\n    // By default, files added via file input selection, paste, drag & drop or\n    // \"add\" method are uploaded immediately, but it is possible to override\n    // the \"add\" callback option to queue file uploads.\n    $.widget('blueimp.fileupload', {\n\n        options: {\n            // The drop target element(s), by the default the complete document.\n            // Set to null to disable drag & drop support:\n            dropZone: $(document),\n            // The paste target element(s), by the default undefined.\n            // Set to a DOM node or jQuery object to enable file pasting:\n            pasteZone: undefined,\n            // The file input field(s), that are listened to for change events.\n            // If undefined, it is set to the file input fields inside\n            // of the widget element on plugin initialization.\n            // Set to null to disable the change listener.\n            fileInput: undefined,\n            // By default, the file input field is replaced with a clone after\n            // each input field change event. This is required for iframe transport\n            // queues and allows change events to be fired for the same file\n            // selection, but can be disabled by setting the following option to false:\n            replaceFileInput: true,\n            // The parameter name for the file form data (the request argument name).\n            // If undefined or empty, the name property of the file input field is\n            // used, or \"files[]\" if the file input name property is also empty,\n            // can be a string or an array of strings:\n            paramName: undefined,\n            // By default, each file of a selection is uploaded using an individual\n            // request for XHR type uploads. Set to false to upload file\n            // selections in one request each:\n            singleFileUploads: true,\n            // To limit the number of files uploaded with one XHR request,\n            // set the following option to an integer greater than 0:\n            limitMultiFileUploads: undefined,\n            // The following option limits the number of files uploaded with one\n            // XHR request to keep the request size under or equal to the defined\n            // limit in bytes:\n            limitMultiFileUploadSize: undefined,\n            // Multipart file uploads add a number of bytes to each uploaded file,\n            // therefore the following option adds an overhead for each file used\n            // in the limitMultiFileUploadSize configuration:\n            limitMultiFileUploadSizeOverhead: 512,\n            // Set the following option to true to issue all file upload requests\n            // in a sequential order:\n            sequentialUploads: false,\n            // To limit the number of concurrent uploads,\n            // set the following option to an integer greater than 0:\n            limitConcurrentUploads: undefined,\n            // Set the following option to true to force iframe transport uploads:\n            forceIframeTransport: false,\n            // Set the following option to the location of a redirect url on the\n            // origin server, for cross-domain iframe transport uploads:\n            redirect: undefined,\n            // The parameter name for the redirect url, sent as part of the form\n            // data and set to 'redirect' if this option is empty:\n            redirectParamName: undefined,\n            // Set the following option to the location of a postMessage window,\n            // to enable postMessage transport uploads:\n            postMessage: undefined,\n            // By default, XHR file uploads are sent as multipart/form-data.\n            // The iframe transport is always using multipart/form-data.\n            // Set to false to enable non-multipart XHR uploads:\n            multipart: true,\n            // To upload large files in smaller chunks, set the following option\n            // to a preferred maximum chunk size. If set to 0, null or undefined,\n            // or the browser does not support the required Blob API, files will\n            // be uploaded as a whole.\n            maxChunkSize: undefined,\n            // When a non-multipart upload or a chunked multipart upload has been\n            // aborted, this option can be used to resume the upload by setting\n            // it to the size of the already uploaded bytes. This option is most\n            // useful when modifying the options object inside of the \"add\" or\n            // \"send\" callbacks, as the options are cloned for each file upload.\n            uploadedBytes: undefined,\n            // By default, failed (abort or error) file uploads are removed from the\n            // global progress calculation. Set the following option to false to\n            // prevent recalculating the global progress data:\n            recalculateProgress: true,\n            // Interval in milliseconds to calculate and trigger progress events:\n            progressInterval: 100,\n            // Interval in milliseconds to calculate progress bitrate:\n            bitrateInterval: 500,\n            // By default, uploads are started automatically when adding files:\n            autoUpload: true,\n\n            // Error and info messages:\n            messages: {\n                uploadedBytes: 'Uploaded bytes exceed file size'\n            },\n\n            // Translation function, gets the message key to be translated\n            // and an object with context specific data as arguments:\n            i18n: function (message, context) {\n                message = this.messages[message] || message.toString();\n                if (context) {\n                    $.each(context, function (key, value) {\n                        message = message.replace('{' + key + '}', value);\n                    });\n                }\n                return message;\n            },\n\n            // Additional form data to be sent along with the file uploads can be set\n            // using this option, which accepts an array of objects with name and\n            // value properties, a function returning such an array, a FormData\n            // object (for XHR file uploads), or a simple object.\n            // The form of the first fileInput is given as parameter to the function:\n            formData: function (form) {\n                return form.serializeArray();\n            },\n\n            // The add callback is invoked as soon as files are added to the fileupload\n            // widget (via file input selection, drag & drop, paste or add API call).\n            // If the singleFileUploads option is enabled, this callback will be\n            // called once for each file in the selection for XHR file uploads, else\n            // once for each file selection.\n            //\n            // The upload starts when the submit method is invoked on the data parameter.\n            // The data object contains a files property holding the added files\n            // and allows you to override plugin options as well as define ajax settings.\n            //\n            // Listeners for this callback can also be bound the following way:\n            // .bind('fileuploadadd', func);\n            //\n            // data.submit() returns a Promise object and allows to attach additional\n            // handlers using jQuery's Deferred callbacks:\n            // data.submit().done(func).fail(func).always(func);\n            add: function (e, data) {\n                if (e.isDefaultPrevented()) {\n                    return false;\n                }\n                if (data.autoUpload || (data.autoUpload !== false &&\n                        $(this).fileupload('option', 'autoUpload'))) {\n                    data.process().done(function () {\n                        data.submit();\n                    });\n                }\n            },\n\n            // Other callbacks:\n\n            // Callback for the submit event of each file upload:\n            // submit: function (e, data) {}, // .bind('fileuploadsubmit', func);\n\n            // Callback for the start of each file upload request:\n            // send: function (e, data) {}, // .bind('fileuploadsend', func);\n\n            // Callback for successful uploads:\n            // done: function (e, data) {}, // .bind('fileuploaddone', func);\n\n            // Callback for failed (abort or error) uploads:\n            // fail: function (e, data) {}, // .bind('fileuploadfail', func);\n\n            // Callback for completed (success, abort or error) requests:\n            // always: function (e, data) {}, // .bind('fileuploadalways', func);\n\n            // Callback for upload progress events:\n            // progress: function (e, data) {}, // .bind('fileuploadprogress', func);\n\n            // Callback for global upload progress events:\n            // progressall: function (e, data) {}, // .bind('fileuploadprogressall', func);\n\n            // Callback for uploads start, equivalent to the global ajaxStart event:\n            // start: function (e) {}, // .bind('fileuploadstart', func);\n\n            // Callback for uploads stop, equivalent to the global ajaxStop event:\n            // stop: function (e) {}, // .bind('fileuploadstop', func);\n\n            // Callback for change events of the fileInput(s):\n            // change: function (e, data) {}, // .bind('fileuploadchange', func);\n\n            // Callback for paste events to the pasteZone(s):\n            // paste: function (e, data) {}, // .bind('fileuploadpaste', func);\n\n            // Callback for drop events of the dropZone(s):\n            // drop: function (e, data) {}, // .bind('fileuploaddrop', func);\n\n            // Callback for dragover events of the dropZone(s):\n            // dragover: function (e) {}, // .bind('fileuploaddragover', func);\n\n            // Callback for the start of each chunk upload request:\n            // chunksend: function (e, data) {}, // .bind('fileuploadchunksend', func);\n\n            // Callback for successful chunk uploads:\n            // chunkdone: function (e, data) {}, // .bind('fileuploadchunkdone', func);\n\n            // Callback for failed (abort or error) chunk uploads:\n            // chunkfail: function (e, data) {}, // .bind('fileuploadchunkfail', func);\n\n            // Callback for completed (success, abort or error) chunk upload requests:\n            // chunkalways: function (e, data) {}, // .bind('fileuploadchunkalways', func);\n\n            // The plugin options are used as settings object for the ajax calls.\n            // The following are jQuery ajax settings required for the file uploads:\n            processData: false,\n            contentType: false,\n            cache: false,\n            timeout: 0\n        },\n\n        // A list of options that require reinitializing event listeners and/or\n        // special initialization code:\n        _specialOptions: [\n            'fileInput',\n            'dropZone',\n            'pasteZone',\n            'multipart',\n            'forceIframeTransport'\n        ],\n\n        _blobSlice: $.support.blobSlice && function () {\n            var slice = this.slice || this.webkitSlice || this.mozSlice;\n            return slice.apply(this, arguments);\n        },\n\n        _BitrateTimer: function () {\n            this.timestamp = ((Date.now) ? Date.now() : (new Date()).getTime());\n            this.loaded = 0;\n            this.bitrate = 0;\n            this.getBitrate = function (now, loaded, interval) {\n                var timeDiff = now - this.timestamp;\n                if (!this.bitrate || !interval || timeDiff > interval) {\n                    this.bitrate = (loaded - this.loaded) * (1000 / timeDiff) * 8;\n                    this.loaded = loaded;\n                    this.timestamp = now;\n                }\n                return this.bitrate;\n            };\n        },\n\n        _isXHRUpload: function (options) {\n            return !options.forceIframeTransport &&\n                ((!options.multipart && $.support.xhrFileUpload) ||\n                $.support.xhrFormDataFileUpload);\n        },\n\n        _getFormData: function (options) {\n            var formData;\n            if ($.type(options.formData) === 'function') {\n                return options.formData(options.form);\n            }\n            if ($.isArray(options.formData)) {\n                return options.formData;\n            }\n            if ($.type(options.formData) === 'object') {\n                formData = [];\n                $.each(options.formData, function (name, value) {\n                    formData.push({name: name, value: value});\n                });\n                return formData;\n            }\n            return [];\n        },\n\n        _getTotal: function (files) {\n            var total = 0;\n            $.each(files, function (index, file) {\n                total += file.size || 1;\n            });\n            return total;\n        },\n\n        _initProgressObject: function (obj) {\n            var progress = {\n                loaded: 0,\n                total: 0,\n                bitrate: 0\n            };\n            if (obj._progress) {\n                $.extend(obj._progress, progress);\n            } else {\n                obj._progress = progress;\n            }\n        },\n\n        _initResponseObject: function (obj) {\n            var prop;\n            if (obj._response) {\n                for (prop in obj._response) {\n                    if (obj._response.hasOwnProperty(prop)) {\n                        delete obj._response[prop];\n                    }\n                }\n            } else {\n                obj._response = {};\n            }\n        },\n\n        _onProgress: function (e, data) {\n            if (e.lengthComputable) {\n                var now = ((Date.now) ? Date.now() : (new Date()).getTime()),\n                    loaded;\n                if (data._time && data.progressInterval &&\n                        (now - data._time < data.progressInterval) &&\n                        e.loaded !== e.total) {\n                    return;\n                }\n                data._time = now;\n                loaded = Math.floor(\n                    e.loaded / e.total * (data.chunkSize || data._progress.total)\n                ) + (data.uploadedBytes || 0);\n                // Add the difference from the previously loaded state\n                // to the global loaded counter:\n                this._progress.loaded += (loaded - data._progress.loaded);\n                this._progress.bitrate = this._bitrateTimer.getBitrate(\n                    now,\n                    this._progress.loaded,\n                    data.bitrateInterval\n                );\n                data._progress.loaded = data.loaded = loaded;\n                data._progress.bitrate = data.bitrate = data._bitrateTimer.getBitrate(\n                    now,\n                    loaded,\n                    data.bitrateInterval\n                );\n                // Trigger a custom progress event with a total data property set\n                // to the file size(s) of the current upload and a loaded data\n                // property calculated accordingly:\n                this._trigger(\n                    'progress',\n                    $.Event('progress', {delegatedEvent: e}),\n                    data\n                );\n                // Trigger a global progress event for all current file uploads,\n                // including ajax calls queued for sequential file uploads:\n                this._trigger(\n                    'progressall',\n                    $.Event('progressall', {delegatedEvent: e}),\n                    this._progress\n                );\n            }\n        },\n\n        _initProgressListener: function (options) {\n            var that = this,\n                xhr = options.xhr ? options.xhr() : $.ajaxSettings.xhr();\n            // Accesss to the native XHR object is required to add event listeners\n            // for the upload progress event:\n            if (xhr.upload) {\n                $(xhr.upload).bind('progress', function (e) {\n                    var oe = e.originalEvent;\n                    // Make sure the progress event properties get copied over:\n                    e.lengthComputable = oe.lengthComputable;\n                    e.loaded = oe.loaded;\n                    e.total = oe.total;\n                    that._onProgress(e, options);\n                });\n                options.xhr = function () {\n                    return xhr;\n                };\n            }\n        },\n\n        _isInstanceOf: function (type, obj) {\n            // Cross-frame instanceof check\n            return Object.prototype.toString.call(obj) === '[object ' + type + ']';\n        },\n\n        _initXHRData: function (options) {\n            var that = this,\n                formData,\n                file = options.files[0],\n                // Ignore non-multipart setting if not supported:\n                multipart = options.multipart || !$.support.xhrFileUpload,\n                paramName = $.type(options.paramName) === 'array' ?\n                    options.paramName[0] : options.paramName;\n            options.headers = $.extend({}, options.headers);\n            if (options.contentRange) {\n                options.headers['Content-Range'] = options.contentRange;\n            }\n            if (!multipart || options.blob || !this._isInstanceOf('File', file)) {\n                options.headers['Content-Disposition'] = 'attachment; filename=\"' +\n                    encodeURI(file.name) + '\"';\n            }\n            if (!multipart) {\n                options.contentType = file.type || 'application/octet-stream';\n                options.data = options.blob || file;\n            } else if ($.support.xhrFormDataFileUpload) {\n                if (options.postMessage) {\n                    // window.postMessage does not allow sending FormData\n                    // objects, so we just add the File/Blob objects to\n                    // the formData array and let the postMessage window\n                    // create the FormData object out of this array:\n                    formData = this._getFormData(options);\n                    if (options.blob) {\n                        formData.push({\n                            name: paramName,\n                            value: options.blob\n                        });\n                    } else {\n                        $.each(options.files, function (index, file) {\n                            formData.push({\n                                name: ($.type(options.paramName) === 'array' &&\n                                    options.paramName[index]) || paramName,\n                                value: file\n                            });\n                        });\n                    }\n                } else {\n                    if (that._isInstanceOf('FormData', options.formData)) {\n                        formData = options.formData;\n                    } else {\n                        formData = new FormData();\n                        $.each(this._getFormData(options), function (index, field) {\n                            formData.append(field.name, field.value);\n                        });\n                    }\n                    if (options.blob) {\n                        formData.append(paramName, options.blob, file.name);\n                    } else {\n                        $.each(options.files, function (index, file) {\n                            // This check allows the tests to run with\n                            // dummy objects:\n                            if (that._isInstanceOf('File', file) ||\n                                    that._isInstanceOf('Blob', file)) {\n                                formData.append(\n                                    ($.type(options.paramName) === 'array' &&\n                                        options.paramName[index]) || paramName,\n                                    file,\n                                    file.uploadName || file.name\n                                );\n                            }\n                        });\n                    }\n                }\n                options.data = formData;\n            }\n            // Blob reference is not needed anymore, free memory:\n            options.blob = null;\n        },\n\n        _initIframeSettings: function (options) {\n            var targetHost = $('<a></a>').prop('href', options.url).prop('host');\n            // Setting the dataType to iframe enables the iframe transport:\n            options.dataType = 'iframe ' + (options.dataType || '');\n            // The iframe transport accepts a serialized array as form data:\n            options.formData = this._getFormData(options);\n            // Add redirect url to form data on cross-domain uploads:\n            if (options.redirect && targetHost && targetHost !== location.host) {\n                options.formData.push({\n                    name: options.redirectParamName || 'redirect',\n                    value: options.redirect\n                });\n            }\n        },\n\n        _initDataSettings: function (options) {\n            if (this._isXHRUpload(options)) {\n                if (!this._chunkedUpload(options, true)) {\n                    if (!options.data) {\n                        this._initXHRData(options);\n                    }\n                    this._initProgressListener(options);\n                }\n                if (options.postMessage) {\n                    // Setting the dataType to postmessage enables the\n                    // postMessage transport:\n                    options.dataType = 'postmessage ' + (options.dataType || '');\n                }\n            } else {\n                this._initIframeSettings(options);\n            }\n        },\n\n        _getParamName: function (options) {\n            var fileInput = $(options.fileInput),\n                paramName = options.paramName;\n            if (!paramName) {\n                paramName = [];\n                fileInput.each(function () {\n                    var input = $(this),\n                        name = input.prop('name') || 'files[]',\n                        i = (input.prop('files') || [1]).length;\n                    while (i) {\n                        paramName.push(name);\n                        i -= 1;\n                    }\n                });\n                if (!paramName.length) {\n                    paramName = [fileInput.prop('name') || 'files[]'];\n                }\n            } else if (!$.isArray(paramName)) {\n                paramName = [paramName];\n            }\n            return paramName;\n        },\n\n        _initFormSettings: function (options) {\n            // Retrieve missing options from the input field and the\n            // associated form, if available:\n            if (!options.form || !options.form.length) {\n                options.form = $(options.fileInput.prop('form'));\n                // If the given file input doesn't have an associated form,\n                // use the default widget file input's form:\n                if (!options.form.length) {\n                    options.form = $(this.options.fileInput.prop('form'));\n                }\n            }\n            options.paramName = this._getParamName(options);\n            if (!options.url) {\n                options.url = options.form.prop('action') || location.href;\n            }\n            // The HTTP request method must be \"POST\" or \"PUT\":\n            options.type = (options.type ||\n                ($.type(options.form.prop('method')) === 'string' &&\n                    options.form.prop('method')) || ''\n                ).toUpperCase();\n            if (options.type !== 'POST' && options.type !== 'PUT' &&\n                    options.type !== 'PATCH') {\n                options.type = 'POST';\n            }\n            if (!options.formAcceptCharset) {\n                options.formAcceptCharset = options.form.attr('accept-charset');\n            }\n        },\n\n        _getAJAXSettings: function (data) {\n            var options = $.extend({}, this.options, data);\n            this._initFormSettings(options);\n            this._initDataSettings(options);\n            return options;\n        },\n\n        // jQuery 1.6 doesn't provide .state(),\n        // while jQuery 1.8+ removed .isRejected() and .isResolved():\n        _getDeferredState: function (deferred) {\n            if (deferred.state) {\n                return deferred.state();\n            }\n            if (deferred.isResolved()) {\n                return 'resolved';\n            }\n            if (deferred.isRejected()) {\n                return 'rejected';\n            }\n            return 'pending';\n        },\n\n        // Maps jqXHR callbacks to the equivalent\n        // methods of the given Promise object:\n        _enhancePromise: function (promise) {\n            promise.success = promise.done;\n            promise.error = promise.fail;\n            promise.complete = promise.always;\n            return promise;\n        },\n\n        // Creates and returns a Promise object enhanced with\n        // the jqXHR methods abort, success, error and complete:\n        _getXHRPromise: function (resolveOrReject, context, args) {\n            var dfd = $.Deferred(),\n                promise = dfd.promise();\n            context = context || this.options.context || promise;\n            if (resolveOrReject === true) {\n                dfd.resolveWith(context, args);\n            } else if (resolveOrReject === false) {\n                dfd.rejectWith(context, args);\n            }\n            promise.abort = dfd.promise;\n            return this._enhancePromise(promise);\n        },\n\n        // Adds convenience methods to the data callback argument:\n        _addConvenienceMethods: function (e, data) {\n            var that = this,\n                getPromise = function (args) {\n                    return $.Deferred().resolveWith(that, args).promise();\n                };\n            data.process = function (resolveFunc, rejectFunc) {\n                if (resolveFunc || rejectFunc) {\n                    data._processQueue = this._processQueue =\n                        (this._processQueue || getPromise([this])).then(\n                            function () {\n                                if (data.errorThrown) {\n                                    return $.Deferred()\n                                        .rejectWith(that, [data]).promise();\n                                }\n                                return getPromise(arguments);\n                            }\n                        ).then(resolveFunc, rejectFunc);\n                }\n                return this._processQueue || getPromise([this]);\n            };\n            data.submit = function () {\n                if (this.state() !== 'pending') {\n                    data.jqXHR = this.jqXHR =\n                        (that._trigger(\n                            'submit',\n                            $.Event('submit', {delegatedEvent: e}),\n                            this\n                        ) !== false) && that._onSend(e, this);\n                }\n                return this.jqXHR || that._getXHRPromise();\n            };\n            data.abort = function () {\n                if (this.jqXHR) {\n                    return this.jqXHR.abort();\n                }\n                this.errorThrown = 'abort';\n                that._trigger('fail', null, this);\n                return that._getXHRPromise(false);\n            };\n            data.state = function () {\n                if (this.jqXHR) {\n                    return that._getDeferredState(this.jqXHR);\n                }\n                if (this._processQueue) {\n                    return that._getDeferredState(this._processQueue);\n                }\n            };\n            data.processing = function () {\n                return !this.jqXHR && this._processQueue && that\n                    ._getDeferredState(this._processQueue) === 'pending';\n            };\n            data.progress = function () {\n                return this._progress;\n            };\n            data.response = function () {\n                return this._response;\n            };\n        },\n\n        // Parses the Range header from the server response\n        // and returns the uploaded bytes:\n        _getUploadedBytes: function (jqXHR) {\n            var range = jqXHR.getResponseHeader('Range'),\n                parts = range && range.split('-'),\n                upperBytesPos = parts && parts.length > 1 &&\n                    parseInt(parts[1], 10);\n            return upperBytesPos && upperBytesPos + 1;\n        },\n\n        // Uploads a file in multiple, sequential requests\n        // by splitting the file up in multiple blob chunks.\n        // If the second parameter is true, only tests if the file\n        // should be uploaded in chunks, but does not invoke any\n        // upload requests:\n        _chunkedUpload: function (options, testOnly) {\n            options.uploadedBytes = options.uploadedBytes || 0;\n            var that = this,\n                file = options.files[0],\n                fs = file.size,\n                ub = options.uploadedBytes,\n                mcs = options.maxChunkSize || fs,\n                slice = this._blobSlice,\n                dfd = $.Deferred(),\n                promise = dfd.promise(),\n                jqXHR,\n                upload;\n            if (!(this._isXHRUpload(options) && slice && (ub || mcs < fs)) ||\n                    options.data) {\n                return false;\n            }\n            if (testOnly) {\n                return true;\n            }\n            if (ub >= fs) {\n                file.error = options.i18n('uploadedBytes');\n                return this._getXHRPromise(\n                    false,\n                    options.context,\n                    [null, 'error', file.error]\n                );\n            }\n            // The chunk upload method:\n            upload = function () {\n                // Clone the options object for each chunk upload:\n                var o = $.extend({}, options),\n                    currentLoaded = o._progress.loaded;\n                o.blob = slice.call(\n                    file,\n                    ub,\n                    ub + mcs,\n                    file.type\n                );\n                // Store the current chunk size, as the blob itself\n                // will be dereferenced after data processing:\n                o.chunkSize = o.blob.size;\n                // Expose the chunk bytes position range:\n                o.contentRange = 'bytes ' + ub + '-' +\n                    (ub + o.chunkSize - 1) + '/' + fs;\n                // Process the upload data (the blob and potential form data):\n                that._initXHRData(o);\n                // Add progress listeners for this chunk upload:\n                that._initProgressListener(o);\n                jqXHR = ((that._trigger('chunksend', null, o) !== false && $.ajax(o)) ||\n                        that._getXHRPromise(false, o.context))\n                    .done(function (result, textStatus, jqXHR) {\n                        ub = that._getUploadedBytes(jqXHR) ||\n                            (ub + o.chunkSize);\n                        // Create a progress event if no final progress event\n                        // with loaded equaling total has been triggered\n                        // for this chunk:\n                        if (currentLoaded + o.chunkSize - o._progress.loaded) {\n                            that._onProgress($.Event('progress', {\n                                lengthComputable: true,\n                                loaded: ub - o.uploadedBytes,\n                                total: ub - o.uploadedBytes\n                            }), o);\n                        }\n                        options.uploadedBytes = o.uploadedBytes = ub;\n                        o.result = result;\n                        o.textStatus = textStatus;\n                        o.jqXHR = jqXHR;\n                        that._trigger('chunkdone', null, o);\n                        that._trigger('chunkalways', null, o);\n                        if (ub < fs) {\n                            // File upload not yet complete,\n                            // continue with the next chunk:\n                            upload();\n                        } else {\n                            dfd.resolveWith(\n                                o.context,\n                                [result, textStatus, jqXHR]\n                            );\n                        }\n                    })\n                    .fail(function (jqXHR, textStatus, errorThrown) {\n                        o.jqXHR = jqXHR;\n                        o.textStatus = textStatus;\n                        o.errorThrown = errorThrown;\n                        that._trigger('chunkfail', null, o);\n                        that._trigger('chunkalways', null, o);\n                        dfd.rejectWith(\n                            o.context,\n                            [jqXHR, textStatus, errorThrown]\n                        );\n                    });\n            };\n            this._enhancePromise(promise);\n            promise.abort = function () {\n                return jqXHR.abort();\n            };\n            upload();\n            return promise;\n        },\n\n        _beforeSend: function (e, data) {\n            if (this._active === 0) {\n                // the start callback is triggered when an upload starts\n                // and no other uploads are currently running,\n                // equivalent to the global ajaxStart event:\n                this._trigger('start');\n                // Set timer for global bitrate progress calculation:\n                this._bitrateTimer = new this._BitrateTimer();\n                // Reset the global progress values:\n                this._progress.loaded = this._progress.total = 0;\n                this._progress.bitrate = 0;\n            }\n            // Make sure the container objects for the .response() and\n            // .progress() methods on the data object are available\n            // and reset to their initial state:\n            this._initResponseObject(data);\n            this._initProgressObject(data);\n            data._progress.loaded = data.loaded = data.uploadedBytes || 0;\n            data._progress.total = data.total = this._getTotal(data.files) || 1;\n            data._progress.bitrate = data.bitrate = 0;\n            this._active += 1;\n            // Initialize the global progress values:\n            this._progress.loaded += data.loaded;\n            this._progress.total += data.total;\n        },\n\n        _onDone: function (result, textStatus, jqXHR, options) {\n            var total = options._progress.total,\n                response = options._response;\n            if (options._progress.loaded < total) {\n                // Create a progress event if no final progress event\n                // with loaded equaling total has been triggered:\n                this._onProgress($.Event('progress', {\n                    lengthComputable: true,\n                    loaded: total,\n                    total: total\n                }), options);\n            }\n            response.result = options.result = result;\n            response.textStatus = options.textStatus = textStatus;\n            response.jqXHR = options.jqXHR = jqXHR;\n            this._trigger('done', null, options);\n        },\n\n        _onFail: function (jqXHR, textStatus, errorThrown, options) {\n            var response = options._response;\n            if (options.recalculateProgress) {\n                // Remove the failed (error or abort) file upload from\n                // the global progress calculation:\n                this._progress.loaded -= options._progress.loaded;\n                this._progress.total -= options._progress.total;\n            }\n            response.jqXHR = options.jqXHR = jqXHR;\n            response.textStatus = options.textStatus = textStatus;\n            response.errorThrown = options.errorThrown = errorThrown;\n            this._trigger('fail', null, options);\n        },\n\n        _onAlways: function (jqXHRorResult, textStatus, jqXHRorError, options) {\n            // jqXHRorResult, textStatus and jqXHRorError are added to the\n            // options object via done and fail callbacks\n            this._trigger('always', null, options);\n        },\n\n        _onSend: function (e, data) {\n            if (!data.submit) {\n                this._addConvenienceMethods(e, data);\n            }\n            var that = this,\n                jqXHR,\n                aborted,\n                slot,\n                pipe,\n                options = that._getAJAXSettings(data),\n                send = function () {\n                    that._sending += 1;\n                    // Set timer for bitrate progress calculation:\n                    options._bitrateTimer = new that._BitrateTimer();\n                    jqXHR = jqXHR || (\n                        ((aborted || that._trigger(\n                            'send',\n                            $.Event('send', {delegatedEvent: e}),\n                            options\n                        ) === false) &&\n                        that._getXHRPromise(false, options.context, aborted)) ||\n                        that._chunkedUpload(options) || $.ajax(options)\n                    ).done(function (result, textStatus, jqXHR) {\n                        that._onDone(result, textStatus, jqXHR, options);\n                    }).fail(function (jqXHR, textStatus, errorThrown) {\n                        that._onFail(jqXHR, textStatus, errorThrown, options);\n                    }).always(function (jqXHRorResult, textStatus, jqXHRorError) {\n                        that._onAlways(\n                            jqXHRorResult,\n                            textStatus,\n                            jqXHRorError,\n                            options\n                        );\n                        that._sending -= 1;\n                        that._active -= 1;\n                        if (options.limitConcurrentUploads &&\n                                options.limitConcurrentUploads > that._sending) {\n                            // Start the next queued upload,\n                            // that has not been aborted:\n                            var nextSlot = that._slots.shift();\n                            while (nextSlot) {\n                                if (that._getDeferredState(nextSlot) === 'pending') {\n                                    nextSlot.resolve();\n                                    break;\n                                }\n                                nextSlot = that._slots.shift();\n                            }\n                        }\n                        if (that._active === 0) {\n                            // The stop callback is triggered when all uploads have\n                            // been completed, equivalent to the global ajaxStop event:\n                            that._trigger('stop');\n                        }\n                    });\n                    return jqXHR;\n                };\n            this._beforeSend(e, options);\n            if (this.options.sequentialUploads ||\n                    (this.options.limitConcurrentUploads &&\n                    this.options.limitConcurrentUploads <= this._sending)) {\n                if (this.options.limitConcurrentUploads > 1) {\n                    slot = $.Deferred();\n                    this._slots.push(slot);\n                    pipe = slot.then(send);\n                } else {\n                    this._sequence = this._sequence.then(send, send);\n                    pipe = this._sequence;\n                }\n                // Return the piped Promise object, enhanced with an abort method,\n                // which is delegated to the jqXHR object of the current upload,\n                // and jqXHR callbacks mapped to the equivalent Promise methods:\n                pipe.abort = function () {\n                    aborted = [undefined, 'abort', 'abort'];\n                    if (!jqXHR) {\n                        if (slot) {\n                            slot.rejectWith(options.context, aborted);\n                        }\n                        return send();\n                    }\n                    return jqXHR.abort();\n                };\n                return this._enhancePromise(pipe);\n            }\n            return send();\n        },\n\n        _onAdd: function (e, data) {\n            var that = this,\n                result = true,\n                options = $.extend({}, this.options, data),\n                files = data.files,\n                filesLength = files.length,\n                limit = options.limitMultiFileUploads,\n                limitSize = options.limitMultiFileUploadSize,\n                overhead = options.limitMultiFileUploadSizeOverhead,\n                batchSize = 0,\n                paramName = this._getParamName(options),\n                paramNameSet,\n                paramNameSlice,\n                fileSet,\n                i,\n                j = 0;\n            if (!filesLength) {\n                return false;\n            }\n            if (limitSize && files[0].size === undefined) {\n                limitSize = undefined;\n            }\n            if (!(options.singleFileUploads || limit || limitSize) ||\n                    !this._isXHRUpload(options)) {\n                fileSet = [files];\n                paramNameSet = [paramName];\n            } else if (!(options.singleFileUploads || limitSize) && limit) {\n                fileSet = [];\n                paramNameSet = [];\n                for (i = 0; i < filesLength; i += limit) {\n                    fileSet.push(files.slice(i, i + limit));\n                    paramNameSlice = paramName.slice(i, i + limit);\n                    if (!paramNameSlice.length) {\n                        paramNameSlice = paramName;\n                    }\n                    paramNameSet.push(paramNameSlice);\n                }\n            } else if (!options.singleFileUploads && limitSize) {\n                fileSet = [];\n                paramNameSet = [];\n                for (i = 0; i < filesLength; i = i + 1) {\n                    batchSize += files[i].size + overhead;\n                    if (i + 1 === filesLength ||\n                            ((batchSize + files[i + 1].size + overhead) > limitSize) ||\n                            (limit && i + 1 - j >= limit)) {\n                        fileSet.push(files.slice(j, i + 1));\n                        paramNameSlice = paramName.slice(j, i + 1);\n                        if (!paramNameSlice.length) {\n                            paramNameSlice = paramName;\n                        }\n                        paramNameSet.push(paramNameSlice);\n                        j = i + 1;\n                        batchSize = 0;\n                    }\n                }\n            } else {\n                paramNameSet = paramName;\n            }\n            data.originalFiles = files;\n            $.each(fileSet || files, function (index, element) {\n                var newData = $.extend({}, data);\n                newData.files = fileSet ? element : [element];\n                newData.paramName = paramNameSet[index];\n                that._initResponseObject(newData);\n                that._initProgressObject(newData);\n                that._addConvenienceMethods(e, newData);\n                result = that._trigger(\n                    'add',\n                    $.Event('add', {delegatedEvent: e}),\n                    newData\n                );\n                return result;\n            });\n            return result;\n        },\n\n        _replaceFileInput: function (data) {\n            var input = data.fileInput,\n                inputClone = input.clone(true),\n                restoreFocus = input.is(document.activeElement);\n            // Add a reference for the new cloned file input to the data argument:\n            data.fileInputClone = inputClone;\n            $('<form></form>').append(inputClone)[0].reset();\n            // Detaching allows to insert the fileInput on another form\n            // without loosing the file input value:\n            input.after(inputClone).detach();\n            // If the fileInput had focus before it was detached,\n            // restore focus to the inputClone.\n            if (restoreFocus) {\n                inputClone.focus();\n            }\n            // Avoid memory leaks with the detached file input:\n            $.cleanData(input.unbind('remove'));\n            // Replace the original file input element in the fileInput\n            // elements set with the clone, which has been copied including\n            // event handlers:\n            this.options.fileInput = this.options.fileInput.map(function (i, el) {\n                if (el === input[0]) {\n                    return inputClone[0];\n                }\n                return el;\n            });\n            // If the widget has been initialized on the file input itself,\n            // override this.element with the file input clone:\n            if (input[0] === this.element[0]) {\n                this.element = inputClone;\n            }\n        },\n\n        _handleFileTreeEntry: function (entry, path) {\n            var that = this,\n                dfd = $.Deferred(),\n                entries = [],\n                dirReader,\n                errorHandler = function (e) {\n                    if (e && !e.entry) {\n                        e.entry = entry;\n                    }\n                    // Since $.when returns immediately if one\n                    // Deferred is rejected, we use resolve instead.\n                    // This allows valid files and invalid items\n                    // to be returned together in one set:\n                    dfd.resolve([e]);\n                },\n                successHandler = function (entries) {\n                    that._handleFileTreeEntries(\n                        entries,\n                        path + entry.name + '/'\n                    ).done(function (files) {\n                        dfd.resolve(files);\n                    }).fail(errorHandler);\n                },\n                readEntries = function () {\n                    dirReader.readEntries(function (results) {\n                        if (!results.length) {\n                            successHandler(entries);\n                        } else {\n                            entries = entries.concat(results);\n                            readEntries();\n                        }\n                    }, errorHandler);\n                };\n            path = path || '';\n            if (entry.isFile) {\n                if (entry._file) {\n                    // Workaround for Chrome bug #149735\n                    entry._file.relativePath = path;\n                    dfd.resolve(entry._file);\n                } else {\n                    entry.file(function (file) {\n                        file.relativePath = path;\n                        dfd.resolve(file);\n                    }, errorHandler);\n                }\n            } else if (entry.isDirectory) {\n                dirReader = entry.createReader();\n                readEntries();\n            } else {\n                // Return an empy list for file system items\n                // other than files or directories:\n                dfd.resolve([]);\n            }\n            return dfd.promise();\n        },\n\n        _handleFileTreeEntries: function (entries, path) {\n            var that = this;\n            return $.when.apply(\n                $,\n                $.map(entries, function (entry) {\n                    return that._handleFileTreeEntry(entry, path);\n                })\n            ).then(function () {\n                return Array.prototype.concat.apply(\n                    [],\n                    arguments\n                );\n            });\n        },\n\n        _getDroppedFiles: function (dataTransfer) {\n            dataTransfer = dataTransfer || {};\n            var items = dataTransfer.items;\n            if (items && items.length && (items[0].webkitGetAsEntry ||\n                    items[0].getAsEntry)) {\n                return this._handleFileTreeEntries(\n                    $.map(items, function (item) {\n                        var entry;\n                        if (item.webkitGetAsEntry) {\n                            entry = item.webkitGetAsEntry();\n                            if (entry) {\n                                // Workaround for Chrome bug #149735:\n                                entry._file = item.getAsFile();\n                            }\n                            return entry;\n                        }\n                        return item.getAsEntry();\n                    })\n                );\n            }\n            return $.Deferred().resolve(\n                $.makeArray(dataTransfer.files)\n            ).promise();\n        },\n\n        _getSingleFileInputFiles: function (fileInput) {\n            fileInput = $(fileInput);\n            var entries = fileInput.prop('webkitEntries') ||\n                    fileInput.prop('entries'),\n                files,\n                value;\n            if (entries && entries.length) {\n                return this._handleFileTreeEntries(entries);\n            }\n            files = $.makeArray(fileInput.prop('files'));\n            if (!files.length) {\n                value = fileInput.prop('value');\n                if (!value) {\n                    return $.Deferred().resolve([]).promise();\n                }\n                // If the files property is not available, the browser does not\n                // support the File API and we add a pseudo File object with\n                // the input value as name with path information removed:\n                files = [{name: value.replace(/^.*\\\\/, '')}];\n            } else if (files[0].name === undefined && files[0].fileName) {\n                // File normalization for Safari 4 and Firefox 3:\n                $.each(files, function (index, file) {\n                    file.name = file.fileName;\n                    file.size = file.fileSize;\n                });\n            }\n            return $.Deferred().resolve(files).promise();\n        },\n\n        _getFileInputFiles: function (fileInput) {\n            if (!(fileInput instanceof $) || fileInput.length === 1) {\n                return this._getSingleFileInputFiles(fileInput);\n            }\n            return $.when.apply(\n                $,\n                $.map(fileInput, this._getSingleFileInputFiles)\n            ).then(function () {\n                return Array.prototype.concat.apply(\n                    [],\n                    arguments\n                );\n            });\n        },\n\n        _onChange: function (e) {\n            var that = this,\n                data = {\n                    fileInput: $(e.target),\n                    form: $(e.target.form)\n                };\n            this._getFileInputFiles(data.fileInput).always(function (files) {\n                data.files = files;\n                if (that.options.replaceFileInput) {\n                    that._replaceFileInput(data);\n                }\n                if (that._trigger(\n                        'change',\n                        $.Event('change', {delegatedEvent: e}),\n                        data\n                    ) !== false) {\n                    that._onAdd(e, data);\n                }\n            });\n        },\n\n        _onPaste: function (e) {\n            var items = e.originalEvent && e.originalEvent.clipboardData &&\n                    e.originalEvent.clipboardData.items,\n                data = {files: []};\n            if (items && items.length) {\n                $.each(items, function (index, item) {\n                    var file = item.getAsFile && item.getAsFile();\n                    if (file) {\n                        data.files.push(file);\n                    }\n                });\n                if (this._trigger(\n                        'paste',\n                        $.Event('paste', {delegatedEvent: e}),\n                        data\n                    ) !== false) {\n                    this._onAdd(e, data);\n                }\n            }\n        },\n\n        _onDrop: function (e) {\n            e.dataTransfer = e.originalEvent && e.originalEvent.dataTransfer;\n            var that = this,\n                dataTransfer = e.dataTransfer,\n                data = {};\n            if (dataTransfer && dataTransfer.files && dataTransfer.files.length) {\n                e.preventDefault();\n                this._getDroppedFiles(dataTransfer).always(function (files) {\n                    data.files = files;\n                    if (that._trigger(\n                            'drop',\n                            $.Event('drop', {delegatedEvent: e}),\n                            data\n                        ) !== false) {\n                        that._onAdd(e, data);\n                    }\n                });\n            }\n        },\n\n        _onDragOver: getDragHandler('dragover'),\n\n        _onDragEnter: getDragHandler('dragenter'),\n\n        _onDragLeave: getDragHandler('dragleave'),\n\n        _initEventHandlers: function () {\n            if (this._isXHRUpload(this.options)) {\n                this._on(this.options.dropZone, {\n                    dragover: this._onDragOver,\n                    drop: this._onDrop,\n                    // event.preventDefault() on dragenter is required for IE10+:\n                    dragenter: this._onDragEnter,\n                    // dragleave is not required, but added for completeness:\n                    dragleave: this._onDragLeave\n                });\n                this._on(this.options.pasteZone, {\n                    paste: this._onPaste\n                });\n            }\n            if ($.support.fileInput) {\n                this._on(this.options.fileInput, {\n                    change: this._onChange\n                });\n            }\n        },\n\n        _destroyEventHandlers: function () {\n            this._off(this.options.dropZone, 'dragenter dragleave dragover drop');\n            this._off(this.options.pasteZone, 'paste');\n            this._off(this.options.fileInput, 'change');\n        },\n\n        _destroy: function () {\n            this._destroyEventHandlers();\n        },\n\n        _setOption: function (key, value) {\n            var reinit = $.inArray(key, this._specialOptions) !== -1;\n            if (reinit) {\n                this._destroyEventHandlers();\n            }\n            this._super(key, value);\n            if (reinit) {\n                this._initSpecialOptions();\n                this._initEventHandlers();\n            }\n        },\n\n        _initSpecialOptions: function () {\n            var options = this.options;\n            if (options.fileInput === undefined) {\n                options.fileInput = this.element.is('input[type=\"file\"]') ?\n                        this.element : this.element.find('input[type=\"file\"]');\n            } else if (!(options.fileInput instanceof $)) {\n                options.fileInput = $(options.fileInput);\n            }\n            if (!(options.dropZone instanceof $)) {\n                options.dropZone = $(options.dropZone);\n            }\n            if (!(options.pasteZone instanceof $)) {\n                options.pasteZone = $(options.pasteZone);\n            }\n        },\n\n        _getRegExp: function (str) {\n            var parts = str.split('/'),\n                modifiers = parts.pop();\n            parts.shift();\n            return new RegExp(parts.join('/'), modifiers);\n        },\n\n        _isRegExpOption: function (key, value) {\n            return key !== 'url' && $.type(value) === 'string' &&\n                /^\\/.*\\/[igm]{0,3}$/.test(value);\n        },\n\n        _initDataAttributes: function () {\n            var that = this,\n                options = this.options,\n                data = this.element.data();\n            // Initialize options set via HTML5 data-attributes:\n            $.each(\n                this.element[0].attributes,\n                function (index, attr) {\n                    var key = attr.name.toLowerCase(),\n                        value;\n                    if (/^data-/.test(key)) {\n                        // Convert hyphen-ated key to camelCase:\n                        key = key.slice(5).replace(/-[a-z]/g, function (str) {\n                            return str.charAt(1).toUpperCase();\n                        });\n                        value = data[key];\n                        if (that._isRegExpOption(key, value)) {\n                            value = that._getRegExp(value);\n                        }\n                        options[key] = value;\n                    }\n                }\n            );\n        },\n\n        _create: function () {\n            this._initDataAttributes();\n            this._initSpecialOptions();\n            this._slots = [];\n            this._sequence = this._getXHRPromise(true);\n            this._sending = this._active = 0;\n            this._initProgressObject(this);\n            this._initEventHandlers();\n        },\n\n        // This method is exposed to the widget API and allows to query\n        // the number of active uploads:\n        active: function () {\n            return this._active;\n        },\n\n        // This method is exposed to the widget API and allows to query\n        // the widget upload progress.\n        // It returns an object with loaded, total and bitrate properties\n        // for the running uploads:\n        progress: function () {\n            return this._progress;\n        },\n\n        // This method is exposed to the widget API and allows adding files\n        // using the fileupload API. The data parameter accepts an object which\n        // must have a files property and can contain additional options:\n        // .fileupload('add', {files: filesList});\n        add: function (data) {\n            var that = this;\n            if (!data || this.options.disabled) {\n                return;\n            }\n            if (data.fileInput && !data.files) {\n                this._getFileInputFiles(data.fileInput).always(function (files) {\n                    data.files = files;\n                    that._onAdd(null, data);\n                });\n            } else {\n                data.files = $.makeArray(data.files);\n                this._onAdd(null, data);\n            }\n        },\n\n        // This method is exposed to the widget API and allows sending files\n        // using the fileupload API. The data parameter accepts an object which\n        // must have a files or fileInput property and can contain additional options:\n        // .fileupload('send', {files: filesList});\n        // The method returns a Promise object for the file upload call.\n        send: function (data) {\n            if (data && !this.options.disabled) {\n                if (data.fileInput && !data.files) {\n                    var that = this,\n                        dfd = $.Deferred(),\n                        promise = dfd.promise(),\n                        jqXHR,\n                        aborted;\n                    promise.abort = function () {\n                        aborted = true;\n                        if (jqXHR) {\n                            return jqXHR.abort();\n                        }\n                        dfd.reject(null, 'abort', 'abort');\n                        return promise;\n                    };\n                    this._getFileInputFiles(data.fileInput).always(\n                        function (files) {\n                            if (aborted) {\n                                return;\n                            }\n                            if (!files.length) {\n                                dfd.reject();\n                                return;\n                            }\n                            data.files = files;\n                            jqXHR = that._onSend(null, data);\n                            jqXHR.then(\n                                function (result, textStatus, jqXHR) {\n                                    dfd.resolve(result, textStatus, jqXHR);\n                                },\n                                function (jqXHR, textStatus, errorThrown) {\n                                    dfd.reject(jqXHR, textStatus, errorThrown);\n                                }\n                            );\n                        }\n                    );\n                    return this._enhancePromise(promise);\n                }\n                data.files = $.makeArray(data.files);\n                if (data.files.length) {\n                    return this._onSend(null, data);\n                }\n            }\n            return this._getXHRPromise(false, data && data.context);\n        }\n\n    });\n\n}));\n"
  },
  {
    "path": "app_frontend/static/plugin/jQuery-File-Upload-9.18.0/js/jquery.iframe-transport.js",
    "content": "/*\n * jQuery Iframe Transport Plugin\n * https://github.com/blueimp/jQuery-File-Upload\n *\n * Copyright 2011, Sebastian Tschan\n * https://blueimp.net\n *\n * Licensed under the MIT license:\n * https://opensource.org/licenses/MIT\n */\n\n/* global define, require, window, document, JSON */\n\n;(function (factory) {\n    'use strict';\n    if (typeof define === 'function' && define.amd) {\n        // Register as an anonymous AMD module:\n        define(['jquery'], factory);\n    } else if (typeof exports === 'object') {\n        // Node/CommonJS:\n        factory(require('jquery'));\n    } else {\n        // Browser globals:\n        factory(window.jQuery);\n    }\n}(function ($) {\n    'use strict';\n\n    // Helper variable to create unique names for the transport iframes:\n    var counter = 0,\n        jsonAPI = $,\n        jsonParse = 'parseJSON';\n\n    if ('JSON' in window && 'parse' in JSON) {\n      jsonAPI = JSON;\n      jsonParse = 'parse';\n    }\n\n    // The iframe transport accepts four additional options:\n    // options.fileInput: a jQuery collection of file input fields\n    // options.paramName: the parameter name for the file form data,\n    //  overrides the name property of the file input field(s),\n    //  can be a string or an array of strings.\n    // options.formData: an array of objects with name and value properties,\n    //  equivalent to the return data of .serializeArray(), e.g.:\n    //  [{name: 'a', value: 1}, {name: 'b', value: 2}]\n    // options.initialIframeSrc: the URL of the initial iframe src,\n    //  by default set to \"javascript:false;\"\n    $.ajaxTransport('iframe', function (options) {\n        if (options.async) {\n            // javascript:false as initial iframe src\n            // prevents warning popups on HTTPS in IE6:\n            /*jshint scripturl: true */\n            var initialIframeSrc = options.initialIframeSrc || 'javascript:false;',\n            /*jshint scripturl: false */\n                form,\n                iframe,\n                addParamChar;\n            return {\n                send: function (_, completeCallback) {\n                    form = $('<form style=\"display:none;\"></form>');\n                    form.attr('accept-charset', options.formAcceptCharset);\n                    addParamChar = /\\?/.test(options.url) ? '&' : '?';\n                    // XDomainRequest only supports GET and POST:\n                    if (options.type === 'DELETE') {\n                        options.url = options.url + addParamChar + '_method=DELETE';\n                        options.type = 'POST';\n                    } else if (options.type === 'PUT') {\n                        options.url = options.url + addParamChar + '_method=PUT';\n                        options.type = 'POST';\n                    } else if (options.type === 'PATCH') {\n                        options.url = options.url + addParamChar + '_method=PATCH';\n                        options.type = 'POST';\n                    }\n                    // IE versions below IE8 cannot set the name property of\n                    // elements that have already been added to the DOM,\n                    // so we set the name along with the iframe HTML markup:\n                    counter += 1;\n                    iframe = $(\n                        '<iframe src=\"' + initialIframeSrc +\n                            '\" name=\"iframe-transport-' + counter + '\"></iframe>'\n                    ).bind('load', function () {\n                        var fileInputClones,\n                            paramNames = $.isArray(options.paramName) ?\n                                    options.paramName : [options.paramName];\n                        iframe\n                            .unbind('load')\n                            .bind('load', function () {\n                                var response;\n                                // Wrap in a try/catch block to catch exceptions thrown\n                                // when trying to access cross-domain iframe contents:\n                                try {\n                                    response = iframe.contents();\n                                    // Google Chrome and Firefox do not throw an\n                                    // exception when calling iframe.contents() on\n                                    // cross-domain requests, so we unify the response:\n                                    if (!response.length || !response[0].firstChild) {\n                                        throw new Error();\n                                    }\n                                } catch (e) {\n                                    response = undefined;\n                                }\n                                // The complete callback returns the\n                                // iframe content document as response object:\n                                completeCallback(\n                                    200,\n                                    'success',\n                                    {'iframe': response}\n                                );\n                                // Fix for IE endless progress bar activity bug\n                                // (happens on form submits to iframe targets):\n                                $('<iframe src=\"' + initialIframeSrc + '\"></iframe>')\n                                    .appendTo(form);\n                                window.setTimeout(function () {\n                                    // Removing the form in a setTimeout call\n                                    // allows Chrome's developer tools to display\n                                    // the response result\n                                    form.remove();\n                                }, 0);\n                            });\n                        form\n                            .prop('target', iframe.prop('name'))\n                            .prop('action', options.url)\n                            .prop('method', options.type);\n                        if (options.formData) {\n                            $.each(options.formData, function (index, field) {\n                                $('<input type=\"hidden\"/>')\n                                    .prop('name', field.name)\n                                    .val(field.value)\n                                    .appendTo(form);\n                            });\n                        }\n                        if (options.fileInput && options.fileInput.length &&\n                                options.type === 'POST') {\n                            fileInputClones = options.fileInput.clone();\n                            // Insert a clone for each file input field:\n                            options.fileInput.after(function (index) {\n                                return fileInputClones[index];\n                            });\n                            if (options.paramName) {\n                                options.fileInput.each(function (index) {\n                                    $(this).prop(\n                                        'name',\n                                        paramNames[index] || options.paramName\n                                    );\n                                });\n                            }\n                            // Appending the file input fields to the hidden form\n                            // removes them from their original location:\n                            form\n                                .append(options.fileInput)\n                                .prop('enctype', 'multipart/form-data')\n                                // enctype must be set as encoding for IE:\n                                .prop('encoding', 'multipart/form-data');\n                            // Remove the HTML5 form attribute from the input(s):\n                            options.fileInput.removeAttr('form');\n                        }\n                        form.submit();\n                        // Insert the file input fields at their original location\n                        // by replacing the clones with the originals:\n                        if (fileInputClones && fileInputClones.length) {\n                            options.fileInput.each(function (index, input) {\n                                var clone = $(fileInputClones[index]);\n                                // Restore the original name and form properties:\n                                $(input)\n                                    .prop('name', clone.prop('name'))\n                                    .attr('form', clone.attr('form'));\n                                clone.replaceWith(input);\n                            });\n                        }\n                    });\n                    form.append(iframe).appendTo(document.body);\n                },\n                abort: function () {\n                    if (iframe) {\n                        // javascript:false as iframe src aborts the request\n                        // and prevents warning popups on HTTPS in IE6.\n                        // concat is used to avoid the \"Script URL\" JSLint error:\n                        iframe\n                            .unbind('load')\n                            .prop('src', initialIframeSrc);\n                    }\n                    if (form) {\n                        form.remove();\n                    }\n                }\n            };\n        }\n    });\n\n    // The iframe transport returns the iframe content document as response.\n    // The following adds converters from iframe to text, json, html, xml\n    // and script.\n    // Please note that the Content-Type for JSON responses has to be text/plain\n    // or text/html, if the browser doesn't include application/json in the\n    // Accept header, else IE will show a download dialog.\n    // The Content-Type for XML responses on the other hand has to be always\n    // application/xml or text/xml, so IE properly parses the XML response.\n    // See also\n    // https://github.com/blueimp/jQuery-File-Upload/wiki/Setup#content-type-negotiation\n    $.ajaxSetup({\n        converters: {\n            'iframe text': function (iframe) {\n                return iframe && $(iframe[0].body).text();\n            },\n            'iframe json': function (iframe) {\n                return iframe && jsonAPI[jsonParse]($(iframe[0].body).text());\n            },\n            'iframe html': function (iframe) {\n                return iframe && $(iframe[0].body).html();\n            },\n            'iframe xml': function (iframe) {\n                var xmlDoc = iframe && iframe[0];\n                return xmlDoc && $.isXMLDoc(xmlDoc) ? xmlDoc :\n                        $.parseXML((xmlDoc.XMLDocument && xmlDoc.XMLDocument.xml) ||\n                            $(xmlDoc.body).html());\n            },\n            'iframe script': function (iframe) {\n                return iframe && $.globalEval($(iframe[0].body).text());\n            }\n        }\n    });\n\n}));\n"
  },
  {
    "path": "app_frontend/static/plugin/jQuery-File-Upload-9.18.0/js/main.js",
    "content": "/*\n * jQuery File Upload Plugin JS Example\n * https://github.com/blueimp/jQuery-File-Upload\n *\n * Copyright 2010, Sebastian Tschan\n * https://blueimp.net\n *\n * Licensed under the MIT license:\n * https://opensource.org/licenses/MIT\n */\n\n/* global $, window */\n\n$(function () {\n    'use strict';\n\n    // Initialize the jQuery File Upload widget:\n    $('#fileupload').fileupload({\n        // Uncomment the following to send cross-domain cookies:\n        //xhrFields: {withCredentials: true},\n        url: 'server/php/'\n    });\n\n    // Enable iframe cross-domain access via redirect option:\n    $('#fileupload').fileupload(\n        'option',\n        'redirect',\n        window.location.href.replace(\n            /\\/[^\\/]*$/,\n            '/cors/result.html?%s'\n        )\n    );\n\n    if (window.location.hostname === 'blueimp.github.io') {\n        // Demo settings:\n        $('#fileupload').fileupload('option', {\n            url: '//jquery-file-upload.appspot.com/',\n            // Enable image resizing, except for Android and Opera,\n            // which actually support image resizing, but fail to\n            // send Blob objects via XHR requests:\n            disableImageResize: /Android(?!.*Chrome)|Opera/\n                .test(window.navigator.userAgent),\n            maxFileSize: 999000,\n            acceptFileTypes: /(\\.|\\/)(gif|jpe?g|png)$/i\n        });\n        // Upload server status check for browsers with CORS support:\n        if ($.support.cors) {\n            $.ajax({\n                url: '//jquery-file-upload.appspot.com/',\n                type: 'HEAD'\n            }).fail(function () {\n                $('<div class=\"alert alert-danger\"/>')\n                    .text('Upload server currently unavailable - ' +\n                            new Date())\n                    .appendTo('#fileupload');\n            });\n        }\n    } else {\n        // Load existing files:\n        $('#fileupload').addClass('fileupload-processing');\n        $.ajax({\n            // Uncomment the following to send cross-domain cookies:\n            //xhrFields: {withCredentials: true},\n            url: $('#fileupload').fileupload('option', 'url'),\n            dataType: 'json',\n            context: $('#fileupload')[0]\n        }).always(function () {\n            $(this).removeClass('fileupload-processing');\n        }).done(function (result) {\n            $(this).fileupload('option', 'done')\n                .call(this, $.Event('done'), {result: result});\n        });\n    }\n\n});\n"
  },
  {
    "path": "app_frontend/static/plugin/jQuery-File-Upload-9.18.0/js/vendor/jquery.ui.widget.js",
    "content": "/*! jQuery UI - v1.11.4+CommonJS - 2015-08-28\n* http://jqueryui.com\n* Includes: widget.js\n* Copyright 2015 jQuery Foundation and other contributors; Licensed MIT */\n\n(function( factory ) {\n\tif ( typeof define === \"function\" && define.amd ) {\n\n\t\t// AMD. Register as an anonymous module.\n\t\tdefine([ \"jquery\" ], factory );\n\n\t} else if ( typeof exports === \"object\" ) {\n\n\t\t// Node/CommonJS\n\t\tfactory( require( \"jquery\" ) );\n\n\t} else {\n\n\t\t// Browser globals\n\t\tfactory( jQuery );\n\t}\n}(function( $ ) {\n/*!\n * jQuery UI Widget 1.11.4\n * http://jqueryui.com\n *\n * Copyright jQuery Foundation and other contributors\n * Released under the MIT license.\n * http://jquery.org/license\n *\n * http://api.jqueryui.com/jQuery.widget/\n */\n\n\nvar widget_uuid = 0,\n\twidget_slice = Array.prototype.slice;\n\n$.cleanData = (function( orig ) {\n\treturn function( elems ) {\n\t\tvar events, elem, i;\n\t\tfor ( i = 0; (elem = elems[i]) != null; i++ ) {\n\t\t\ttry {\n\n\t\t\t\t// Only trigger remove when necessary to save time\n\t\t\t\tevents = $._data( elem, \"events\" );\n\t\t\t\tif ( events && events.remove ) {\n\t\t\t\t\t$( elem ).triggerHandler( \"remove\" );\n\t\t\t\t}\n\n\t\t\t// http://bugs.jquery.com/ticket/8235\n\t\t\t} catch ( e ) {}\n\t\t}\n\t\torig( elems );\n\t};\n})( $.cleanData );\n\n$.widget = function( name, base, prototype ) {\n\tvar fullName, existingConstructor, constructor, basePrototype,\n\t\t// proxiedPrototype allows the provided prototype to remain unmodified\n\t\t// so that it can be used as a mixin for multiple widgets (#8876)\n\t\tproxiedPrototype = {},\n\t\tnamespace = name.split( \".\" )[ 0 ];\n\n\tname = name.split( \".\" )[ 1 ];\n\tfullName = namespace + \"-\" + name;\n\n\tif ( !prototype ) {\n\t\tprototype = base;\n\t\tbase = $.Widget;\n\t}\n\n\t// create selector for plugin\n\t$.expr[ \":\" ][ fullName.toLowerCase() ] = function( elem ) {\n\t\treturn !!$.data( elem, fullName );\n\t};\n\n\t$[ namespace ] = $[ namespace ] || {};\n\texistingConstructor = $[ namespace ][ name ];\n\tconstructor = $[ namespace ][ name ] = function( options, element ) {\n\t\t// allow instantiation without \"new\" keyword\n\t\tif ( !this._createWidget ) {\n\t\t\treturn new constructor( options, element );\n\t\t}\n\n\t\t// allow instantiation without initializing for simple inheritance\n\t\t// must use \"new\" keyword (the code above always passes args)\n\t\tif ( arguments.length ) {\n\t\t\tthis._createWidget( options, element );\n\t\t}\n\t};\n\t// extend with the existing constructor to carry over any static properties\n\t$.extend( constructor, existingConstructor, {\n\t\tversion: prototype.version,\n\t\t// copy the object used to create the prototype in case we need to\n\t\t// redefine the widget later\n\t\t_proto: $.extend( {}, prototype ),\n\t\t// track widgets that inherit from this widget in case this widget is\n\t\t// redefined after a widget inherits from it\n\t\t_childConstructors: []\n\t});\n\n\tbasePrototype = new base();\n\t// we need to make the options hash a property directly on the new instance\n\t// otherwise we'll modify the options hash on the prototype that we're\n\t// inheriting from\n\tbasePrototype.options = $.widget.extend( {}, basePrototype.options );\n\t$.each( prototype, function( prop, value ) {\n\t\tif ( !$.isFunction( value ) ) {\n\t\t\tproxiedPrototype[ prop ] = value;\n\t\t\treturn;\n\t\t}\n\t\tproxiedPrototype[ prop ] = (function() {\n\t\t\tvar _super = function() {\n\t\t\t\t\treturn base.prototype[ prop ].apply( this, arguments );\n\t\t\t\t},\n\t\t\t\t_superApply = function( args ) {\n\t\t\t\t\treturn base.prototype[ prop ].apply( this, args );\n\t\t\t\t};\n\t\t\treturn function() {\n\t\t\t\tvar __super = this._super,\n\t\t\t\t\t__superApply = this._superApply,\n\t\t\t\t\treturnValue;\n\n\t\t\t\tthis._super = _super;\n\t\t\t\tthis._superApply = _superApply;\n\n\t\t\t\treturnValue = value.apply( this, arguments );\n\n\t\t\t\tthis._super = __super;\n\t\t\t\tthis._superApply = __superApply;\n\n\t\t\t\treturn returnValue;\n\t\t\t};\n\t\t})();\n\t});\n\tconstructor.prototype = $.widget.extend( basePrototype, {\n\t\t// TODO: remove support for widgetEventPrefix\n\t\t// always use the name + a colon as the prefix, e.g., draggable:start\n\t\t// don't prefix for widgets that aren't DOM-based\n\t\twidgetEventPrefix: existingConstructor ? (basePrototype.widgetEventPrefix || name) : name\n\t}, proxiedPrototype, {\n\t\tconstructor: constructor,\n\t\tnamespace: namespace,\n\t\twidgetName: name,\n\t\twidgetFullName: fullName\n\t});\n\n\t// If this widget is being redefined then we need to find all widgets that\n\t// are inheriting from it and redefine all of them so that they inherit from\n\t// the new version of this widget. We're essentially trying to replace one\n\t// level in the prototype chain.\n\tif ( existingConstructor ) {\n\t\t$.each( existingConstructor._childConstructors, function( i, child ) {\n\t\t\tvar childPrototype = child.prototype;\n\n\t\t\t// redefine the child widget using the same prototype that was\n\t\t\t// originally used, but inherit from the new version of the base\n\t\t\t$.widget( childPrototype.namespace + \".\" + childPrototype.widgetName, constructor, child._proto );\n\t\t});\n\t\t// remove the list of existing child constructors from the old constructor\n\t\t// so the old child constructors can be garbage collected\n\t\tdelete existingConstructor._childConstructors;\n\t} else {\n\t\tbase._childConstructors.push( constructor );\n\t}\n\n\t$.widget.bridge( name, constructor );\n\n\treturn constructor;\n};\n\n$.widget.extend = function( target ) {\n\tvar input = widget_slice.call( arguments, 1 ),\n\t\tinputIndex = 0,\n\t\tinputLength = input.length,\n\t\tkey,\n\t\tvalue;\n\tfor ( ; inputIndex < inputLength; inputIndex++ ) {\n\t\tfor ( key in input[ inputIndex ] ) {\n\t\t\tvalue = input[ inputIndex ][ key ];\n\t\t\tif ( input[ inputIndex ].hasOwnProperty( key ) && value !== undefined ) {\n\t\t\t\t// Clone objects\n\t\t\t\tif ( $.isPlainObject( value ) ) {\n\t\t\t\t\ttarget[ key ] = $.isPlainObject( target[ key ] ) ?\n\t\t\t\t\t\t$.widget.extend( {}, target[ key ], value ) :\n\t\t\t\t\t\t// Don't extend strings, arrays, etc. with objects\n\t\t\t\t\t\t$.widget.extend( {}, value );\n\t\t\t\t// Copy everything else by reference\n\t\t\t\t} else {\n\t\t\t\t\ttarget[ key ] = value;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\treturn target;\n};\n\n$.widget.bridge = function( name, object ) {\n\tvar fullName = object.prototype.widgetFullName || name;\n\t$.fn[ name ] = function( options ) {\n\t\tvar isMethodCall = typeof options === \"string\",\n\t\t\targs = widget_slice.call( arguments, 1 ),\n\t\t\treturnValue = this;\n\n\t\tif ( isMethodCall ) {\n\t\t\tthis.each(function() {\n\t\t\t\tvar methodValue,\n\t\t\t\t\tinstance = $.data( this, fullName );\n\t\t\t\tif ( options === \"instance\" ) {\n\t\t\t\t\treturnValue = instance;\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t\tif ( !instance ) {\n\t\t\t\t\treturn $.error( \"cannot call methods on \" + name + \" prior to initialization; \" +\n\t\t\t\t\t\t\"attempted to call method '\" + options + \"'\" );\n\t\t\t\t}\n\t\t\t\tif ( !$.isFunction( instance[options] ) || options.charAt( 0 ) === \"_\" ) {\n\t\t\t\t\treturn $.error( \"no such method '\" + options + \"' for \" + name + \" widget instance\" );\n\t\t\t\t}\n\t\t\t\tmethodValue = instance[ options ].apply( instance, args );\n\t\t\t\tif ( methodValue !== instance && methodValue !== undefined ) {\n\t\t\t\t\treturnValue = methodValue && methodValue.jquery ?\n\t\t\t\t\t\treturnValue.pushStack( methodValue.get() ) :\n\t\t\t\t\t\tmethodValue;\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t});\n\t\t} else {\n\n\t\t\t// Allow multiple hashes to be passed on init\n\t\t\tif ( args.length ) {\n\t\t\t\toptions = $.widget.extend.apply( null, [ options ].concat(args) );\n\t\t\t}\n\n\t\t\tthis.each(function() {\n\t\t\t\tvar instance = $.data( this, fullName );\n\t\t\t\tif ( instance ) {\n\t\t\t\t\tinstance.option( options || {} );\n\t\t\t\t\tif ( instance._init ) {\n\t\t\t\t\t\tinstance._init();\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\t$.data( this, fullName, new object( options, this ) );\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\n\t\treturn returnValue;\n\t};\n};\n\n$.Widget = function( /* options, element */ ) {};\n$.Widget._childConstructors = [];\n\n$.Widget.prototype = {\n\twidgetName: \"widget\",\n\twidgetEventPrefix: \"\",\n\tdefaultElement: \"<div>\",\n\toptions: {\n\t\tdisabled: false,\n\n\t\t// callbacks\n\t\tcreate: null\n\t},\n\t_createWidget: function( options, element ) {\n\t\telement = $( element || this.defaultElement || this )[ 0 ];\n\t\tthis.element = $( element );\n\t\tthis.uuid = widget_uuid++;\n\t\tthis.eventNamespace = \".\" + this.widgetName + this.uuid;\n\n\t\tthis.bindings = $();\n\t\tthis.hoverable = $();\n\t\tthis.focusable = $();\n\n\t\tif ( element !== this ) {\n\t\t\t$.data( element, this.widgetFullName, this );\n\t\t\tthis._on( true, this.element, {\n\t\t\t\tremove: function( event ) {\n\t\t\t\t\tif ( event.target === element ) {\n\t\t\t\t\t\tthis.destroy();\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t});\n\t\t\tthis.document = $( element.style ?\n\t\t\t\t// element within the document\n\t\t\t\telement.ownerDocument :\n\t\t\t\t// element is window or document\n\t\t\t\telement.document || element );\n\t\t\tthis.window = $( this.document[0].defaultView || this.document[0].parentWindow );\n\t\t}\n\n\t\tthis.options = $.widget.extend( {},\n\t\t\tthis.options,\n\t\t\tthis._getCreateOptions(),\n\t\t\toptions );\n\n\t\tthis._create();\n\t\tthis._trigger( \"create\", null, this._getCreateEventData() );\n\t\tthis._init();\n\t},\n\t_getCreateOptions: $.noop,\n\t_getCreateEventData: $.noop,\n\t_create: $.noop,\n\t_init: $.noop,\n\n\tdestroy: function() {\n\t\tthis._destroy();\n\t\t// we can probably remove the unbind calls in 2.0\n\t\t// all event bindings should go through this._on()\n\t\tthis.element\n\t\t\t.unbind( this.eventNamespace )\n\t\t\t.removeData( this.widgetFullName )\n\t\t\t// support: jquery <1.6.3\n\t\t\t// http://bugs.jquery.com/ticket/9413\n\t\t\t.removeData( $.camelCase( this.widgetFullName ) );\n\t\tthis.widget()\n\t\t\t.unbind( this.eventNamespace )\n\t\t\t.removeAttr( \"aria-disabled\" )\n\t\t\t.removeClass(\n\t\t\t\tthis.widgetFullName + \"-disabled \" +\n\t\t\t\t\"ui-state-disabled\" );\n\n\t\t// clean up events and states\n\t\tthis.bindings.unbind( this.eventNamespace );\n\t\tthis.hoverable.removeClass( \"ui-state-hover\" );\n\t\tthis.focusable.removeClass( \"ui-state-focus\" );\n\t},\n\t_destroy: $.noop,\n\n\twidget: function() {\n\t\treturn this.element;\n\t},\n\n\toption: function( key, value ) {\n\t\tvar options = key,\n\t\t\tparts,\n\t\t\tcurOption,\n\t\t\ti;\n\n\t\tif ( arguments.length === 0 ) {\n\t\t\t// don't return a reference to the internal hash\n\t\t\treturn $.widget.extend( {}, this.options );\n\t\t}\n\n\t\tif ( typeof key === \"string\" ) {\n\t\t\t// handle nested keys, e.g., \"foo.bar\" => { foo: { bar: ___ } }\n\t\t\toptions = {};\n\t\t\tparts = key.split( \".\" );\n\t\t\tkey = parts.shift();\n\t\t\tif ( parts.length ) {\n\t\t\t\tcurOption = options[ key ] = $.widget.extend( {}, this.options[ key ] );\n\t\t\t\tfor ( i = 0; i < parts.length - 1; i++ ) {\n\t\t\t\t\tcurOption[ parts[ i ] ] = curOption[ parts[ i ] ] || {};\n\t\t\t\t\tcurOption = curOption[ parts[ i ] ];\n\t\t\t\t}\n\t\t\t\tkey = parts.pop();\n\t\t\t\tif ( arguments.length === 1 ) {\n\t\t\t\t\treturn curOption[ key ] === undefined ? null : curOption[ key ];\n\t\t\t\t}\n\t\t\t\tcurOption[ key ] = value;\n\t\t\t} else {\n\t\t\t\tif ( arguments.length === 1 ) {\n\t\t\t\t\treturn this.options[ key ] === undefined ? null : this.options[ key ];\n\t\t\t\t}\n\t\t\t\toptions[ key ] = value;\n\t\t\t}\n\t\t}\n\n\t\tthis._setOptions( options );\n\n\t\treturn this;\n\t},\n\t_setOptions: function( options ) {\n\t\tvar key;\n\n\t\tfor ( key in options ) {\n\t\t\tthis._setOption( key, options[ key ] );\n\t\t}\n\n\t\treturn this;\n\t},\n\t_setOption: function( key, value ) {\n\t\tthis.options[ key ] = value;\n\n\t\tif ( key === \"disabled\" ) {\n\t\t\tthis.widget()\n\t\t\t\t.toggleClass( this.widgetFullName + \"-disabled\", !!value );\n\n\t\t\t// If the widget is becoming disabled, then nothing is interactive\n\t\t\tif ( value ) {\n\t\t\t\tthis.hoverable.removeClass( \"ui-state-hover\" );\n\t\t\t\tthis.focusable.removeClass( \"ui-state-focus\" );\n\t\t\t}\n\t\t}\n\n\t\treturn this;\n\t},\n\n\tenable: function() {\n\t\treturn this._setOptions({ disabled: false });\n\t},\n\tdisable: function() {\n\t\treturn this._setOptions({ disabled: true });\n\t},\n\n\t_on: function( suppressDisabledCheck, element, handlers ) {\n\t\tvar delegateElement,\n\t\t\tinstance = this;\n\n\t\t// no suppressDisabledCheck flag, shuffle arguments\n\t\tif ( typeof suppressDisabledCheck !== \"boolean\" ) {\n\t\t\thandlers = element;\n\t\t\telement = suppressDisabledCheck;\n\t\t\tsuppressDisabledCheck = false;\n\t\t}\n\n\t\t// no element argument, shuffle and use this.element\n\t\tif ( !handlers ) {\n\t\t\thandlers = element;\n\t\t\telement = this.element;\n\t\t\tdelegateElement = this.widget();\n\t\t} else {\n\t\t\telement = delegateElement = $( element );\n\t\t\tthis.bindings = this.bindings.add( element );\n\t\t}\n\n\t\t$.each( handlers, function( event, handler ) {\n\t\t\tfunction handlerProxy() {\n\t\t\t\t// allow widgets to customize the disabled handling\n\t\t\t\t// - disabled as an array instead of boolean\n\t\t\t\t// - disabled class as method for disabling individual parts\n\t\t\t\tif ( !suppressDisabledCheck &&\n\t\t\t\t\t\t( instance.options.disabled === true ||\n\t\t\t\t\t\t\t$( this ).hasClass( \"ui-state-disabled\" ) ) ) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\treturn ( typeof handler === \"string\" ? instance[ handler ] : handler )\n\t\t\t\t\t.apply( instance, arguments );\n\t\t\t}\n\n\t\t\t// copy the guid so direct unbinding works\n\t\t\tif ( typeof handler !== \"string\" ) {\n\t\t\t\thandlerProxy.guid = handler.guid =\n\t\t\t\t\thandler.guid || handlerProxy.guid || $.guid++;\n\t\t\t}\n\n\t\t\tvar match = event.match( /^([\\w:-]*)\\s*(.*)$/ ),\n\t\t\t\teventName = match[1] + instance.eventNamespace,\n\t\t\t\tselector = match[2];\n\t\t\tif ( selector ) {\n\t\t\t\tdelegateElement.delegate( selector, eventName, handlerProxy );\n\t\t\t} else {\n\t\t\t\telement.bind( eventName, handlerProxy );\n\t\t\t}\n\t\t});\n\t},\n\n\t_off: function( element, eventName ) {\n\t\teventName = (eventName || \"\").split( \" \" ).join( this.eventNamespace + \" \" ) +\n\t\t\tthis.eventNamespace;\n\t\telement.unbind( eventName ).undelegate( eventName );\n\n\t\t// Clear the stack to avoid memory leaks (#10056)\n\t\tthis.bindings = $( this.bindings.not( element ).get() );\n\t\tthis.focusable = $( this.focusable.not( element ).get() );\n\t\tthis.hoverable = $( this.hoverable.not( element ).get() );\n\t},\n\n\t_delay: function( handler, delay ) {\n\t\tfunction handlerProxy() {\n\t\t\treturn ( typeof handler === \"string\" ? instance[ handler ] : handler )\n\t\t\t\t.apply( instance, arguments );\n\t\t}\n\t\tvar instance = this;\n\t\treturn setTimeout( handlerProxy, delay || 0 );\n\t},\n\n\t_hoverable: function( element ) {\n\t\tthis.hoverable = this.hoverable.add( element );\n\t\tthis._on( element, {\n\t\t\tmouseenter: function( event ) {\n\t\t\t\t$( event.currentTarget ).addClass( \"ui-state-hover\" );\n\t\t\t},\n\t\t\tmouseleave: function( event ) {\n\t\t\t\t$( event.currentTarget ).removeClass( \"ui-state-hover\" );\n\t\t\t}\n\t\t});\n\t},\n\n\t_focusable: function( element ) {\n\t\tthis.focusable = this.focusable.add( element );\n\t\tthis._on( element, {\n\t\t\tfocusin: function( event ) {\n\t\t\t\t$( event.currentTarget ).addClass( \"ui-state-focus\" );\n\t\t\t},\n\t\t\tfocusout: function( event ) {\n\t\t\t\t$( event.currentTarget ).removeClass( \"ui-state-focus\" );\n\t\t\t}\n\t\t});\n\t},\n\n\t_trigger: function( type, event, data ) {\n\t\tvar prop, orig,\n\t\t\tcallback = this.options[ type ];\n\n\t\tdata = data || {};\n\t\tevent = $.Event( event );\n\t\tevent.type = ( type === this.widgetEventPrefix ?\n\t\t\ttype :\n\t\t\tthis.widgetEventPrefix + type ).toLowerCase();\n\t\t// the original event may come from any element\n\t\t// so we need to reset the target on the new event\n\t\tevent.target = this.element[ 0 ];\n\n\t\t// copy original event properties over to the new event\n\t\torig = event.originalEvent;\n\t\tif ( orig ) {\n\t\t\tfor ( prop in orig ) {\n\t\t\t\tif ( !( prop in event ) ) {\n\t\t\t\t\tevent[ prop ] = orig[ prop ];\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tthis.element.trigger( event, data );\n\t\treturn !( $.isFunction( callback ) &&\n\t\t\tcallback.apply( this.element[0], [ event ].concat( data ) ) === false ||\n\t\t\tevent.isDefaultPrevented() );\n\t}\n};\n\n$.each( { show: \"fadeIn\", hide: \"fadeOut\" }, function( method, defaultEffect ) {\n\t$.Widget.prototype[ \"_\" + method ] = function( element, options, callback ) {\n\t\tif ( typeof options === \"string\" ) {\n\t\t\toptions = { effect: options };\n\t\t}\n\t\tvar hasOptions,\n\t\t\teffectName = !options ?\n\t\t\t\tmethod :\n\t\t\t\toptions === true || typeof options === \"number\" ?\n\t\t\t\t\tdefaultEffect :\n\t\t\t\t\toptions.effect || defaultEffect;\n\t\toptions = options || {};\n\t\tif ( typeof options === \"number\" ) {\n\t\t\toptions = { duration: options };\n\t\t}\n\t\thasOptions = !$.isEmptyObject( options );\n\t\toptions.complete = callback;\n\t\tif ( options.delay ) {\n\t\t\telement.delay( options.delay );\n\t\t}\n\t\tif ( hasOptions && $.effects && $.effects.effect[ effectName ] ) {\n\t\t\telement[ method ]( options );\n\t\t} else if ( effectName !== method && element[ effectName ] ) {\n\t\t\telement[ effectName ]( options.duration, options.easing, callback );\n\t\t} else {\n\t\t\telement.queue(function( next ) {\n\t\t\t\t$( this )[ method ]();\n\t\t\t\tif ( callback ) {\n\t\t\t\t\tcallback.call( element[ 0 ] );\n\t\t\t\t}\n\t\t\t\tnext();\n\t\t\t});\n\t\t}\n\t};\n});\n\nvar widget = $.widget;\n\n\n\n}));\n"
  },
  {
    "path": "app_frontend/static/plugin/jQuery-File-Upload-9.18.0/package.json",
    "content": "{\n  \"name\": \"blueimp-file-upload\",\n  \"version\": \"9.18.0\",\n  \"title\": \"jQuery File Upload\",\n  \"description\": \"File Upload widget with multiple file selection, drag&drop support, progress bar, validation and preview images, audio and video for jQuery. Supports cross-domain, chunked and resumable file uploads. Works with any server-side platform (Google App Engine, PHP, Python, Ruby on Rails, Java, etc.) that supports standard HTML form file uploads.\",\n  \"keywords\": [\n    \"jquery\",\n    \"file\",\n    \"upload\",\n    \"widget\",\n    \"multiple\",\n    \"selection\",\n    \"drag\",\n    \"drop\",\n    \"progress\",\n    \"preview\",\n    \"cross-domain\",\n    \"cross-site\",\n    \"chunk\",\n    \"resume\",\n    \"gae\",\n    \"go\",\n    \"python\",\n    \"php\",\n    \"bootstrap\"\n  ],\n  \"homepage\": \"https://github.com/blueimp/jQuery-File-Upload\",\n  \"author\": {\n    \"name\": \"Sebastian Tschan\",\n    \"url\": \"https://blueimp.net\"\n  },\n  \"repository\": {\n    \"type\": \"git\",\n    \"url\": \"git://github.com/blueimp/jQuery-File-Upload.git\"\n  },\n  \"license\": \"MIT\",\n  \"optionalDependencies\": {\n    \"blueimp-canvas-to-blob\": \"3.5.0\",\n    \"blueimp-load-image\": \"2.12.2\",\n    \"blueimp-tmpl\": \"3.6.0\"\n  },\n  \"devDependencies\": {\n    \"bower-json\": \"0.8.1\",\n    \"jshint\": \"2.9.3\"\n  },\n  \"scripts\": {\n    \"bower-version-update\": \"./bower-version-update.js\",\n    \"lint\": \"jshint *.js js/*.js js/cors/*.js\",\n    \"test\": \"npm run lint\",\n    \"preversion\": \"npm test\",\n    \"version\": \"npm run bower-version-update && git add bower.json\",\n    \"postversion\": \"git push --tags origin master && npm publish\"\n  },\n  \"main\": \"js/jquery.fileupload.js\"\n}\n"
  },
  {
    "path": "app_frontend/static/plugin/jQuery-File-Upload-9.18.0/server/gae-go/app/main.go",
    "content": "/*\n * jQuery File Upload Plugin GAE Go Example\n * https://github.com/blueimp/jQuery-File-Upload\n *\n * Copyright 2011, Sebastian Tschan\n * https://blueimp.net\n *\n * Licensed under the MIT license:\n * https://opensource.org/licenses/MIT\n */\n\npackage app\n\nimport (\n\t\"bufio\"\n\t\"bytes\"\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"github.com/disintegration/gift\"\n\t\"golang.org/x/net/context\"\n\t\"google.golang.org/appengine\"\n\t\"google.golang.org/appengine/memcache\"\n\t\"hash/crc32\"\n\t\"image\"\n\t\"image/gif\"\n\t\"image/jpeg\"\n\t\"image/png\"\n\t\"io\"\n\t\"log\"\n\t\"mime/multipart\"\n\t\"net/http\"\n\t\"net/url\"\n\t\"path/filepath\"\n\t\"regexp\"\n\t\"strings\"\n)\n\nconst (\n\tWEBSITE       = \"https://blueimp.github.io/jQuery-File-Upload/\"\n\tMIN_FILE_SIZE = 1 // bytes\n\t// Max file size is memcache limit (1MB) minus key size minus overhead:\n\tMAX_FILE_SIZE     = 999000 // bytes\n\tIMAGE_TYPES       = \"image/(gif|p?jpeg|(x-)?png)\"\n\tACCEPT_FILE_TYPES = IMAGE_TYPES\n\tTHUMB_MAX_WIDTH   = 80\n\tTHUMB_MAX_HEIGHT  = 80\n\tEXPIRATION_TIME   = 300 // seconds\n\t// If empty, only allow redirects to the referer protocol+host.\n\t// Set to a regexp string for custom pattern matching:\n\tREDIRECT_ALLOW_TARGET = \"\"\n)\n\nvar (\n\timageTypes      = regexp.MustCompile(IMAGE_TYPES)\n\tacceptFileTypes = regexp.MustCompile(ACCEPT_FILE_TYPES)\n\tthumbSuffix     = \".\" + fmt.Sprint(THUMB_MAX_WIDTH) + \"x\" +\n\t\tfmt.Sprint(THUMB_MAX_HEIGHT)\n)\n\nfunc escape(s string) string {\n\treturn strings.Replace(url.QueryEscape(s), \"+\", \"%20\", -1)\n}\n\nfunc extractKey(r *http.Request) string {\n\t// Use RequestURI instead of r.URL.Path, as we need the encoded form:\n\tpath := strings.Split(r.RequestURI, \"?\")[0]\n\t// Also adjust double encoded slashes:\n\treturn strings.Replace(path[1:], \"%252F\", \"%2F\", -1)\n}\n\nfunc check(err error) {\n\tif err != nil {\n\t\tpanic(err)\n\t}\n}\n\ntype FileInfo struct {\n\tKey          string `json:\"-\"`\n\tThumbnailKey string `json:\"-\"`\n\tUrl          string `json:\"url,omitempty\"`\n\tThumbnailUrl string `json:\"thumbnailUrl,omitempty\"`\n\tName         string `json:\"name\"`\n\tType         string `json:\"type\"`\n\tSize         int64  `json:\"size\"`\n\tError        string `json:\"error,omitempty\"`\n\tDeleteUrl    string `json:\"deleteUrl,omitempty\"`\n\tDeleteType   string `json:\"deleteType,omitempty\"`\n}\n\nfunc (fi *FileInfo) ValidateType() (valid bool) {\n\tif acceptFileTypes.MatchString(fi.Type) {\n\t\treturn true\n\t}\n\tfi.Error = \"Filetype not allowed\"\n\treturn false\n}\n\nfunc (fi *FileInfo) ValidateSize() (valid bool) {\n\tif fi.Size < MIN_FILE_SIZE {\n\t\tfi.Error = \"File is too small\"\n\t} else if fi.Size > MAX_FILE_SIZE {\n\t\tfi.Error = \"File is too big\"\n\t} else {\n\t\treturn true\n\t}\n\treturn false\n}\n\nfunc (fi *FileInfo) CreateUrls(r *http.Request, c context.Context) {\n\tu := &url.URL{\n\t\tScheme: r.URL.Scheme,\n\t\tHost:   appengine.DefaultVersionHostname(c),\n\t\tPath:   \"/\",\n\t}\n\tuString := u.String()\n\tfi.Url = uString + fi.Key\n\tfi.DeleteUrl = fi.Url\n\tfi.DeleteType = \"DELETE\"\n\tif fi.ThumbnailKey != \"\" {\n\t\tfi.ThumbnailUrl = uString + fi.ThumbnailKey\n\t}\n}\n\nfunc (fi *FileInfo) SetKey(checksum uint32) {\n\tfi.Key = escape(string(fi.Type)) + \"/\" +\n\t\tescape(fmt.Sprint(checksum)) + \"/\" +\n\t\tescape(string(fi.Name))\n}\n\nfunc (fi *FileInfo) createThumb(buffer *bytes.Buffer, c context.Context) {\n\tif imageTypes.MatchString(fi.Type) {\n\t\tsrc, _, err := image.Decode(bytes.NewReader(buffer.Bytes()))\n\t\tcheck(err)\n\t\tfilter := gift.New(gift.ResizeToFit(\n\t\t\tTHUMB_MAX_WIDTH,\n\t\t\tTHUMB_MAX_HEIGHT,\n\t\t\tgift.LanczosResampling,\n\t\t))\n\t\tdst := image.NewNRGBA(filter.Bounds(src.Bounds()))\n\t\tfilter.Draw(dst, src)\n\t\tbuffer.Reset()\n\t\tbWriter := bufio.NewWriter(buffer)\n\t\tswitch fi.Type {\n\t\tcase \"image/jpeg\", \"image/pjpeg\":\n\t\t\terr = jpeg.Encode(bWriter, dst, nil)\n\t\tcase \"image/gif\":\n\t\t\terr = gif.Encode(bWriter, dst, nil)\n\t\tdefault:\n\t\t\terr = png.Encode(bWriter, dst)\n\t\t}\n\t\tcheck(err)\n\t\tbWriter.Flush()\n\t\tthumbnailKey := fi.Key + thumbSuffix + filepath.Ext(fi.Name)\n\t\titem := &memcache.Item{\n\t\t\tKey:   thumbnailKey,\n\t\t\tValue: buffer.Bytes(),\n\t\t}\n\t\terr = memcache.Set(c, item)\n\t\tcheck(err)\n\t\tfi.ThumbnailKey = thumbnailKey\n\t}\n}\n\nfunc handleUpload(r *http.Request, p *multipart.Part) (fi *FileInfo) {\n\tfi = &FileInfo{\n\t\tName: p.FileName(),\n\t\tType: p.Header.Get(\"Content-Type\"),\n\t}\n\tif !fi.ValidateType() {\n\t\treturn\n\t}\n\tdefer func() {\n\t\tif rec := recover(); rec != nil {\n\t\t\tlog.Println(rec)\n\t\t\tfi.Error = rec.(error).Error()\n\t\t}\n\t}()\n\tvar buffer bytes.Buffer\n\thash := crc32.NewIEEE()\n\tmw := io.MultiWriter(&buffer, hash)\n\tlr := &io.LimitedReader{R: p, N: MAX_FILE_SIZE + 1}\n\t_, err := io.Copy(mw, lr)\n\tcheck(err)\n\tfi.Size = MAX_FILE_SIZE + 1 - lr.N\n\tif !fi.ValidateSize() {\n\t\treturn\n\t}\n\tfi.SetKey(hash.Sum32())\n\titem := &memcache.Item{\n\t\tKey:   fi.Key,\n\t\tValue: buffer.Bytes(),\n\t}\n\tcontext := appengine.NewContext(r)\n\terr = memcache.Set(context, item)\n\tcheck(err)\n\tfi.createThumb(&buffer, context)\n\tfi.CreateUrls(r, context)\n\treturn\n}\n\nfunc getFormValue(p *multipart.Part) string {\n\tvar b bytes.Buffer\n\tio.CopyN(&b, p, int64(1<<20)) // Copy max: 1 MiB\n\treturn b.String()\n}\n\nfunc handleUploads(r *http.Request) (fileInfos []*FileInfo) {\n\tfileInfos = make([]*FileInfo, 0)\n\tmr, err := r.MultipartReader()\n\tcheck(err)\n\tr.Form, err = url.ParseQuery(r.URL.RawQuery)\n\tcheck(err)\n\tpart, err := mr.NextPart()\n\tfor err == nil {\n\t\tif name := part.FormName(); name != \"\" {\n\t\t\tif part.FileName() != \"\" {\n\t\t\t\tfileInfos = append(fileInfos, handleUpload(r, part))\n\t\t\t} else {\n\t\t\t\tr.Form[name] = append(r.Form[name], getFormValue(part))\n\t\t\t}\n\t\t}\n\t\tpart, err = mr.NextPart()\n\t}\n\treturn\n}\n\nfunc validateRedirect(r *http.Request, redirect string) bool {\n\tif redirect != \"\" {\n\t\tvar redirectAllowTarget *regexp.Regexp\n\t\tif REDIRECT_ALLOW_TARGET != \"\" {\n\t\t\tredirectAllowTarget = regexp.MustCompile(REDIRECT_ALLOW_TARGET)\n\t\t} else {\n\t\t\treferer := r.Referer()\n\t\t\tif referer == \"\" {\n\t\t\t\treturn false\n\t\t\t}\n\t\t\trefererUrl, err := url.Parse(referer)\n\t\t\tif err != nil {\n\t\t\t\treturn false\n\t\t\t}\n\t\t\tredirectAllowTarget = regexp.MustCompile(\"^\" + regexp.QuoteMeta(\n\t\t\t\trefererUrl.Scheme+\"://\"+refererUrl.Host+\"/\",\n\t\t\t))\n\t\t}\n\t\treturn redirectAllowTarget.MatchString(redirect)\n\t}\n\treturn false\n}\n\nfunc get(w http.ResponseWriter, r *http.Request) {\n\tif r.URL.Path == \"/\" {\n\t\thttp.Redirect(w, r, WEBSITE, http.StatusFound)\n\t\treturn\n\t}\n\t// Use RequestURI instead of r.URL.Path, as we need the encoded form:\n\tkey := extractKey(r)\n\tparts := strings.Split(key, \"/\")\n\tif len(parts) == 3 {\n\t\tcontext := appengine.NewContext(r)\n\t\titem, err := memcache.Get(context, key)\n\t\tif err == nil {\n\t\t\tw.Header().Add(\"X-Content-Type-Options\", \"nosniff\")\n\t\t\tcontentType, _ := url.QueryUnescape(parts[0])\n\t\t\tif !imageTypes.MatchString(contentType) {\n\t\t\t\tcontentType = \"application/octet-stream\"\n\t\t\t}\n\t\t\tw.Header().Add(\"Content-Type\", contentType)\n\t\t\tw.Header().Add(\n\t\t\t\t\"Cache-Control\",\n\t\t\t\tfmt.Sprintf(\"public,max-age=%d\", EXPIRATION_TIME),\n\t\t\t)\n\t\t\tw.Write(item.Value)\n\t\t\treturn\n\t\t}\n\t}\n\thttp.Error(w, \"404 Not Found\", http.StatusNotFound)\n}\n\nfunc post(w http.ResponseWriter, r *http.Request) {\n\tresult := make(map[string][]*FileInfo, 1)\n\tresult[\"files\"] = handleUploads(r)\n\tb, err := json.Marshal(result)\n\tcheck(err)\n\tif redirect := r.FormValue(\"redirect\"); validateRedirect(r, redirect) {\n\t\tif strings.Contains(redirect, \"%s\") {\n\t\t\tredirect = fmt.Sprintf(\n\t\t\t\tredirect,\n\t\t\t\tescape(string(b)),\n\t\t\t)\n\t\t}\n\t\thttp.Redirect(w, r, redirect, http.StatusFound)\n\t\treturn\n\t}\n\tw.Header().Set(\"Cache-Control\", \"no-cache\")\n\tjsonType := \"application/json\"\n\tif strings.Index(r.Header.Get(\"Accept\"), jsonType) != -1 {\n\t\tw.Header().Set(\"Content-Type\", jsonType)\n\t}\n\tfmt.Fprintln(w, string(b))\n}\n\nfunc delete(w http.ResponseWriter, r *http.Request) {\n\tkey := extractKey(r)\n\tparts := strings.Split(key, \"/\")\n\tif len(parts) == 3 {\n\t\tresult := make(map[string]bool, 1)\n\t\tcontext := appengine.NewContext(r)\n\t\terr := memcache.Delete(context, key)\n\t\tif err == nil {\n\t\t\tresult[key] = true\n\t\t\tcontentType, _ := url.QueryUnescape(parts[0])\n\t\t\tif imageTypes.MatchString(contentType) {\n\t\t\t\tthumbnailKey := key + thumbSuffix + filepath.Ext(parts[2])\n\t\t\t\terr := memcache.Delete(context, thumbnailKey)\n\t\t\t\tif err == nil {\n\t\t\t\t\tresult[thumbnailKey] = true\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tw.Header().Set(\"Content-Type\", \"application/json\")\n\t\tb, err := json.Marshal(result)\n\t\tcheck(err)\n\t\tfmt.Fprintln(w, string(b))\n\t} else {\n\t\thttp.Error(w, \"405 Method not allowed\", http.StatusMethodNotAllowed)\n\t}\n}\n\nfunc handle(w http.ResponseWriter, r *http.Request) {\n\tparams, err := url.ParseQuery(r.URL.RawQuery)\n\tcheck(err)\n\tw.Header().Add(\"Access-Control-Allow-Origin\", \"*\")\n\tw.Header().Add(\n\t\t\"Access-Control-Allow-Methods\",\n\t\t\"OPTIONS, HEAD, GET, POST, DELETE\",\n\t)\n\tw.Header().Add(\n\t\t\"Access-Control-Allow-Headers\",\n\t\t\"Content-Type, Content-Range, Content-Disposition\",\n\t)\n\tswitch r.Method {\n\tcase \"OPTIONS\", \"HEAD\":\n\t\treturn\n\tcase \"GET\":\n\t\tget(w, r)\n\tcase \"POST\":\n\t\tif len(params[\"_method\"]) > 0 && params[\"_method\"][0] == \"DELETE\" {\n\t\t\tdelete(w, r)\n\t\t} else {\n\t\t\tpost(w, r)\n\t\t}\n\tcase \"DELETE\":\n\t\tdelete(w, r)\n\tdefault:\n\t\thttp.Error(w, \"501 Not Implemented\", http.StatusNotImplemented)\n\t}\n}\n\nfunc init() {\n\thttp.HandleFunc(\"/\", handle)\n}\n"
  },
  {
    "path": "app_frontend/static/plugin/jQuery-File-Upload-9.18.0/server/gae-go/app.yaml",
    "content": "application: jquery-file-upload\nversion: 2\nruntime: go\napi_version: go1\n\nhandlers:\n- url: /(favicon\\.ico|robots\\.txt)\n  static_files: static/\\1\n  upload: static/(.*)\n  expiration: '1d'\n- url: /.*\n  script: _go_app\n"
  },
  {
    "path": "app_frontend/static/plugin/jQuery-File-Upload-9.18.0/server/gae-go/static/robots.txt",
    "content": "User-agent: *\nDisallow:\n"
  },
  {
    "path": "app_frontend/static/plugin/jQuery-File-Upload-9.18.0/server/gae-python/app.yaml",
    "content": "application: jquery-file-upload\nversion: 1\nruntime: python27\napi_version: 1\nthreadsafe: true\n\nlibraries:\n- name: PIL\n  version: latest\n\nhandlers:\n- url: /(favicon\\.ico|robots\\.txt)\n  static_files: static/\\1\n  upload: static/(.*)\n  expiration: '1d'\n- url: /.*\n  script: main.app\n"
  },
  {
    "path": "app_frontend/static/plugin/jQuery-File-Upload-9.18.0/server/gae-python/main.py",
    "content": "# -*- coding: utf-8 -*-\n#\n# jQuery File Upload Plugin GAE Python Example\n# https://github.com/blueimp/jQuery-File-Upload\n#\n# Copyright 2011, Sebastian Tschan\n# https://blueimp.net\n#\n# Licensed under the MIT license:\n# https://opensource.org/licenses/MIT\n#\n\nfrom google.appengine.api import memcache, images\nimport json\nimport os\nimport re\nimport urllib\nimport webapp2\n\nDEBUG=os.environ.get('SERVER_SOFTWARE', '').startswith('Dev')\nWEBSITE = 'https://blueimp.github.io/jQuery-File-Upload/'\nMIN_FILE_SIZE = 1  # bytes\n# Max file size is memcache limit (1MB) minus key size minus overhead:\nMAX_FILE_SIZE = 999000  # bytes\nIMAGE_TYPES = re.compile('image/(gif|p?jpeg|(x-)?png)')\nACCEPT_FILE_TYPES = IMAGE_TYPES\nTHUMB_MAX_WIDTH = 80\nTHUMB_MAX_HEIGHT = 80\nTHUMB_SUFFIX = '.'+str(THUMB_MAX_WIDTH)+'x'+str(THUMB_MAX_HEIGHT)+'.png'\nEXPIRATION_TIME = 300  # seconds\n# If set to None, only allow redirects to the referer protocol+host.\n# Set to a regexp for custom pattern matching against the redirect value:\nREDIRECT_ALLOW_TARGET = None\n\nclass CORSHandler(webapp2.RequestHandler):\n    def cors(self):\n        headers = self.response.headers\n        headers['Access-Control-Allow-Origin'] = '*'\n        headers['Access-Control-Allow-Methods'] =\\\n            'OPTIONS, HEAD, GET, POST, DELETE'\n        headers['Access-Control-Allow-Headers'] =\\\n            'Content-Type, Content-Range, Content-Disposition'\n\n    def initialize(self, request, response):\n        super(CORSHandler, self).initialize(request, response)\n        self.cors()\n\n    def json_stringify(self, obj):\n        return json.dumps(obj, separators=(',', ':'))\n\n    def options(self, *args, **kwargs):\n        pass\n\nclass UploadHandler(CORSHandler):\n    def validate(self, file):\n        if file['size'] < MIN_FILE_SIZE:\n            file['error'] = 'File is too small'\n        elif file['size'] > MAX_FILE_SIZE:\n            file['error'] = 'File is too big'\n        elif not ACCEPT_FILE_TYPES.match(file['type']):\n            file['error'] = 'Filetype not allowed'\n        else:\n            return True\n        return False\n\n    def validate_redirect(self, redirect):\n        if redirect:\n            if REDIRECT_ALLOW_TARGET:\n                return REDIRECT_ALLOW_TARGET.match(redirect)\n            referer = self.request.headers['referer']\n            if referer:\n                from urlparse import urlparse\n                parts = urlparse(referer)\n                redirect_allow_target = '^' + re.escape(\n                    parts.scheme + '://' + parts.netloc + '/'\n                )\n            return re.match(redirect_allow_target, redirect)\n        return False\n\n    def get_file_size(self, file):\n        file.seek(0, 2)  # Seek to the end of the file\n        size = file.tell()  # Get the position of EOF\n        file.seek(0)  # Reset the file position to the beginning\n        return size\n\n    def write_blob(self, data, info):\n        key = urllib.quote(info['type'].encode('utf-8'), '') +\\\n            '/' + str(hash(data)) +\\\n            '/' + urllib.quote(info['name'].encode('utf-8'), '')\n        try:\n            memcache.set(key, data, time=EXPIRATION_TIME)\n        except: #Failed to add to memcache\n            return (None, None)\n        thumbnail_key = None\n        if IMAGE_TYPES.match(info['type']):\n            try:\n                img = images.Image(image_data=data)\n                img.resize(\n                    width=THUMB_MAX_WIDTH,\n                    height=THUMB_MAX_HEIGHT\n                )\n                thumbnail_data = img.execute_transforms()\n                thumbnail_key = key + THUMB_SUFFIX\n                memcache.set(\n                    thumbnail_key,\n                    thumbnail_data,\n                    time=EXPIRATION_TIME\n                )\n            except: #Failed to resize Image or add to memcache\n                thumbnail_key = None\n        return (key, thumbnail_key)\n\n    def handle_upload(self):\n        results = []\n        for name, fieldStorage in self.request.POST.items():\n            if type(fieldStorage) is unicode:\n                continue\n            result = {}\n            result['name'] = urllib.unquote(fieldStorage.filename)\n            result['type'] = fieldStorage.type\n            result['size'] = self.get_file_size(fieldStorage.file)\n            if self.validate(result):\n                key, thumbnail_key = self.write_blob(\n                    fieldStorage.value,\n                    result\n                )\n                if key is not None:\n                    result['url'] = self.request.host_url + '/' + key\n                    result['deleteUrl'] = result['url']\n                    result['deleteType'] = 'DELETE'\n                    if thumbnail_key is not None:\n                        result['thumbnailUrl'] = self.request.host_url +\\\n                             '/' + thumbnail_key\n                else:\n                    result['error'] = 'Failed to store uploaded file.'\n            results.append(result)\n        return results\n\n    def head(self):\n        pass\n\n    def get(self):\n        self.redirect(WEBSITE)\n\n    def post(self):\n        if (self.request.get('_method') == 'DELETE'):\n            return self.delete()\n        result = {'files': self.handle_upload()}\n        s = self.json_stringify(result)\n        redirect = self.request.get('redirect')\n        if self.validate_redirect(redirect):\n            return self.redirect(str(\n                redirect.replace('%s', urllib.quote(s, ''), 1)\n            ))\n        if 'application/json' in self.request.headers.get('Accept'):\n            self.response.headers['Content-Type'] = 'application/json'\n        self.response.write(s)\n\nclass FileHandler(CORSHandler):\n    def normalize(self, str):\n        return urllib.quote(urllib.unquote(str), '')\n\n    def get(self, content_type, data_hash, file_name):\n        content_type = self.normalize(content_type)\n        file_name = self.normalize(file_name)\n        key = content_type + '/' + data_hash + '/' + file_name\n        data = memcache.get(key)\n        if data is None:\n            return self.error(404)\n        # Prevent browsers from MIME-sniffing the content-type:\n        self.response.headers['X-Content-Type-Options'] = 'nosniff'\n        content_type = urllib.unquote(content_type)\n        if not IMAGE_TYPES.match(content_type):\n            # Force a download dialog for non-image types:\n            content_type = 'application/octet-stream'\n        elif file_name.endswith(THUMB_SUFFIX):\n            content_type = 'image/png'\n        self.response.headers['Content-Type'] = content_type\n        # Cache for the expiration time:\n        self.response.headers['Cache-Control'] = 'public,max-age=%d' \\\n            % EXPIRATION_TIME\n        self.response.write(data)\n\n    def delete(self, content_type, data_hash, file_name):\n        content_type = self.normalize(content_type)\n        file_name = self.normalize(file_name)\n        key = content_type + '/' + data_hash + '/' + file_name\n        result = {key: memcache.delete(key)}\n        content_type = urllib.unquote(content_type)\n        if IMAGE_TYPES.match(content_type):\n            thumbnail_key = key + THUMB_SUFFIX\n            result[thumbnail_key] = memcache.delete(thumbnail_key)\n        if 'application/json' in self.request.headers.get('Accept'):\n            self.response.headers['Content-Type'] = 'application/json'\n        s = self.json_stringify(result)\n        self.response.write(s)\n\napp = webapp2.WSGIApplication(\n    [\n        ('/', UploadHandler),\n        ('/(.+)/([^/]+)/([^/]+)', FileHandler)\n    ],\n    debug=DEBUG\n)\n"
  },
  {
    "path": "app_frontend/static/plugin/jQuery-File-Upload-9.18.0/server/gae-python/static/robots.txt",
    "content": "User-agent: *\nDisallow:\n"
  },
  {
    "path": "app_frontend/static/plugin/jQuery-File-Upload-9.18.0/server/php/Dockerfile",
    "content": "FROM php:7.0-apache\n\n# Enable the Apache Headers module:\nRUN ln -s /etc/apache2/mods-available/headers.load \\\n  /etc/apache2/mods-enabled/headers.load\n\n# Enable the Apache Rewrite module:\nRUN ln -s /etc/apache2/mods-available/rewrite.load \\\n  /etc/apache2/mods-enabled/rewrite.load\n\n# Install GD, Imagick and ImageMagick as image conversion options:\nRUN DEBIAN_FRONTEND=noninteractive \\\n  apt-get update && apt-get install -y --no-install-recommends \\\n    libpng-dev \\\n    libjpeg-dev \\\n    libmagickwand-dev \\\n    imagemagick \\\n  && pecl install \\\n    imagick \\\n  && docker-php-ext-enable \\\n    imagick \\\n  && docker-php-ext-configure \\\n    gd --with-jpeg-dir=/usr/include/ \\\n  && docker-php-ext-install \\\n    gd \\\n  # Uninstall obsolete packages:\n  && apt-get autoremove -y \\\n    libpng-dev \\\n    libjpeg-dev \\\n    libmagickwand-dev \\\n  # Remove obsolete files:\n  && apt-get clean \\\n  && rm -rf \\\n    /tmp/* \\\n    /usr/share/doc/* \\\n    /var/cache/* \\\n    /var/lib/apt/lists/* \\\n    /var/tmp/*\n"
  },
  {
    "path": "app_frontend/static/plugin/jQuery-File-Upload-9.18.0/server/php/UploadHandler.php",
    "content": "<?php\n/*\n * jQuery File Upload Plugin PHP Class\n * https://github.com/blueimp/jQuery-File-Upload\n *\n * Copyright 2010, Sebastian Tschan\n * https://blueimp.net\n *\n * Licensed under the MIT license:\n * https://opensource.org/licenses/MIT\n */\n\nclass UploadHandler\n{\n\n    protected $options;\n\n    // PHP File Upload error message codes:\n    // http://php.net/manual/en/features.file-upload.errors.php\n    protected $error_messages = array(\n        1 => 'The uploaded file exceeds the upload_max_filesize directive in php.ini',\n        2 => 'The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form',\n        3 => 'The uploaded file was only partially uploaded',\n        4 => 'No file was uploaded',\n        6 => 'Missing a temporary folder',\n        7 => 'Failed to write file to disk',\n        8 => 'A PHP extension stopped the file upload',\n        'post_max_size' => 'The uploaded file exceeds the post_max_size directive in php.ini',\n        'max_file_size' => 'File is too big',\n        'min_file_size' => 'File is too small',\n        'accept_file_types' => 'Filetype not allowed',\n        'max_number_of_files' => 'Maximum number of files exceeded',\n        'max_width' => 'Image exceeds maximum width',\n        'min_width' => 'Image requires a minimum width',\n        'max_height' => 'Image exceeds maximum height',\n        'min_height' => 'Image requires a minimum height',\n        'abort' => 'File upload aborted',\n        'image_resize' => 'Failed to resize image'\n    );\n\n    protected $image_objects = array();\n\n    public function __construct($options = null, $initialize = true, $error_messages = null) {\n        $this->response = array();\n        $this->options = array(\n            'script_url' => $this->get_full_url().'/'.$this->basename($this->get_server_var('SCRIPT_NAME')),\n            'upload_dir' => dirname($this->get_server_var('SCRIPT_FILENAME')).'/files/',\n            'upload_url' => $this->get_full_url().'/files/',\n            'input_stream' => 'php://input',\n            'user_dirs' => false,\n            'mkdir_mode' => 0755,\n            'param_name' => 'files',\n            // Set the following option to 'POST', if your server does not support\n            // DELETE requests. This is a parameter sent to the client:\n            'delete_type' => 'DELETE',\n            'access_control_allow_origin' => '*',\n            'access_control_allow_credentials' => false,\n            'access_control_allow_methods' => array(\n                'OPTIONS',\n                'HEAD',\n                'GET',\n                'POST',\n                'PUT',\n                'PATCH',\n                'DELETE'\n            ),\n            'access_control_allow_headers' => array(\n                'Content-Type',\n                'Content-Range',\n                'Content-Disposition'\n            ),\n            // By default, allow redirects to the referer protocol+host:\n            'redirect_allow_target' => '/^'.preg_quote(\n              parse_url($this->get_server_var('HTTP_REFERER'), PHP_URL_SCHEME)\n                .'://'\n                .parse_url($this->get_server_var('HTTP_REFERER'), PHP_URL_HOST)\n                .'/', // Trailing slash to not match subdomains by mistake\n              '/' // preg_quote delimiter param\n            ).'/',\n            // Enable to provide file downloads via GET requests to the PHP script:\n            //     1. Set to 1 to download files via readfile method through PHP\n            //     2. Set to 2 to send a X-Sendfile header for lighttpd/Apache\n            //     3. Set to 3 to send a X-Accel-Redirect header for nginx\n            // If set to 2 or 3, adjust the upload_url option to the base path of\n            // the redirect parameter, e.g. '/files/'.\n            'download_via_php' => false,\n            // Read files in chunks to avoid memory limits when download_via_php\n            // is enabled, set to 0 to disable chunked reading of files:\n            'readfile_chunk_size' => 10 * 1024 * 1024, // 10 MiB\n            // Defines which files can be displayed inline when downloaded:\n            'inline_file_types' => '/\\.(gif|jpe?g|png)$/i',\n            // Defines which files (based on their names) are accepted for upload:\n            'accept_file_types' => '/.+$/i',\n            // The php.ini settings upload_max_filesize and post_max_size\n            // take precedence over the following max_file_size setting:\n            'max_file_size' => null,\n            'min_file_size' => 1,\n            // The maximum number of files for the upload directory:\n            'max_number_of_files' => null,\n            // Defines which files are handled as image files:\n            'image_file_types' => '/\\.(gif|jpe?g|png)$/i',\n            // Use exif_imagetype on all files to correct file extensions:\n            'correct_image_extensions' => false,\n            // Image resolution restrictions:\n            'max_width' => null,\n            'max_height' => null,\n            'min_width' => 1,\n            'min_height' => 1,\n            // Set the following option to false to enable resumable uploads:\n            'discard_aborted_uploads' => true,\n            // Set to 0 to use the GD library to scale and orient images,\n            // set to 1 to use imagick (if installed, falls back to GD),\n            // set to 2 to use the ImageMagick convert binary directly:\n            'image_library' => 1,\n            // Uncomment the following to define an array of resource limits\n            // for imagick:\n            /*\n            'imagick_resource_limits' => array(\n                imagick::RESOURCETYPE_MAP => 32,\n                imagick::RESOURCETYPE_MEMORY => 32\n            ),\n            */\n            // Command or path for to the ImageMagick convert binary:\n            'convert_bin' => 'convert',\n            // Uncomment the following to add parameters in front of each\n            // ImageMagick convert call (the limit constraints seem only\n            // to have an effect if put in front):\n            /*\n            'convert_params' => '-limit memory 32MiB -limit map 32MiB',\n            */\n            // Command or path for to the ImageMagick identify binary:\n            'identify_bin' => 'identify',\n            'image_versions' => array(\n                // The empty image version key defines options for the original image:\n                '' => array(\n                    // Automatically rotate images based on EXIF meta data:\n                    'auto_orient' => true\n                ),\n                // Uncomment the following to create medium sized images:\n                /*\n                'medium' => array(\n                    'max_width' => 800,\n                    'max_height' => 600\n                ),\n                */\n                'thumbnail' => array(\n                    // Uncomment the following to use a defined directory for the thumbnails\n                    // instead of a subdirectory based on the version identifier.\n                    // Make sure that this directory doesn't allow execution of files if you\n                    // don't pose any restrictions on the type of uploaded files, e.g. by\n                    // copying the .htaccess file from the files directory for Apache:\n                    //'upload_dir' => dirname($this->get_server_var('SCRIPT_FILENAME')).'/thumb/',\n                    //'upload_url' => $this->get_full_url().'/thumb/',\n                    // Uncomment the following to force the max\n                    // dimensions and e.g. create square thumbnails:\n                    //'crop' => true,\n                    'max_width' => 80,\n                    'max_height' => 80\n                )\n            ),\n            'print_response' => true\n        );\n        if ($options) {\n            $this->options = $options + $this->options;\n        }\n        if ($error_messages) {\n            $this->error_messages = $error_messages + $this->error_messages;\n        }\n        if ($initialize) {\n            $this->initialize();\n        }\n    }\n\n    protected function initialize() {\n        switch ($this->get_server_var('REQUEST_METHOD')) {\n            case 'OPTIONS':\n            case 'HEAD':\n                $this->head();\n                break;\n            case 'GET':\n                $this->get($this->options['print_response']);\n                break;\n            case 'PATCH':\n            case 'PUT':\n            case 'POST':\n                $this->post($this->options['print_response']);\n                break;\n            case 'DELETE':\n                $this->delete($this->options['print_response']);\n                break;\n            default:\n                $this->header('HTTP/1.1 405 Method Not Allowed');\n        }\n    }\n\n    protected function get_full_url() {\n        $https = !empty($_SERVER['HTTPS']) && strcasecmp($_SERVER['HTTPS'], 'on') === 0 ||\n            !empty($_SERVER['HTTP_X_FORWARDED_PROTO']) &&\n                strcasecmp($_SERVER['HTTP_X_FORWARDED_PROTO'], 'https') === 0;\n        return\n            ($https ? 'https://' : 'http://').\n            (!empty($_SERVER['REMOTE_USER']) ? $_SERVER['REMOTE_USER'].'@' : '').\n            (isset($_SERVER['HTTP_HOST']) ? $_SERVER['HTTP_HOST'] : ($_SERVER['SERVER_NAME'].\n            ($https && $_SERVER['SERVER_PORT'] === 443 ||\n            $_SERVER['SERVER_PORT'] === 80 ? '' : ':'.$_SERVER['SERVER_PORT']))).\n            substr($_SERVER['SCRIPT_NAME'],0, strrpos($_SERVER['SCRIPT_NAME'], '/'));\n    }\n\n    protected function get_user_id() {\n        @session_start();\n        return session_id();\n    }\n\n    protected function get_user_path() {\n        if ($this->options['user_dirs']) {\n            return $this->get_user_id().'/';\n        }\n        return '';\n    }\n\n    protected function get_upload_path($file_name = null, $version = null) {\n        $file_name = $file_name ? $file_name : '';\n        if (empty($version)) {\n            $version_path = '';\n        } else {\n            $version_dir = @$this->options['image_versions'][$version]['upload_dir'];\n            if ($version_dir) {\n                return $version_dir.$this->get_user_path().$file_name;\n            }\n            $version_path = $version.'/';\n        }\n        return $this->options['upload_dir'].$this->get_user_path()\n            .$version_path.$file_name;\n    }\n\n    protected function get_query_separator($url) {\n        return strpos($url, '?') === false ? '?' : '&';\n    }\n\n    protected function get_download_url($file_name, $version = null, $direct = false) {\n        if (!$direct && $this->options['download_via_php']) {\n            $url = $this->options['script_url']\n                .$this->get_query_separator($this->options['script_url'])\n                .$this->get_singular_param_name()\n                .'='.rawurlencode($file_name);\n            if ($version) {\n                $url .= '&version='.rawurlencode($version);\n            }\n            return $url.'&download=1';\n        }\n        if (empty($version)) {\n            $version_path = '';\n        } else {\n            $version_url = @$this->options['image_versions'][$version]['upload_url'];\n            if ($version_url) {\n                return $version_url.$this->get_user_path().rawurlencode($file_name);\n            }\n            $version_path = rawurlencode($version).'/';\n        }\n        return $this->options['upload_url'].$this->get_user_path()\n            .$version_path.rawurlencode($file_name);\n    }\n\n    protected function set_additional_file_properties($file) {\n        $file->deleteUrl = $this->options['script_url']\n            .$this->get_query_separator($this->options['script_url'])\n            .$this->get_singular_param_name()\n            .'='.rawurlencode($file->name);\n        $file->deleteType = $this->options['delete_type'];\n        if ($file->deleteType !== 'DELETE') {\n            $file->deleteUrl .= '&_method=DELETE';\n        }\n        if ($this->options['access_control_allow_credentials']) {\n            $file->deleteWithCredentials = true;\n        }\n    }\n\n    // Fix for overflowing signed 32 bit integers,\n    // works for sizes up to 2^32-1 bytes (4 GiB - 1):\n    protected function fix_integer_overflow($size) {\n        if ($size < 0) {\n            $size += 2.0 * (PHP_INT_MAX + 1);\n        }\n        return $size;\n    }\n\n    protected function get_file_size($file_path, $clear_stat_cache = false) {\n        if ($clear_stat_cache) {\n            if (version_compare(PHP_VERSION, '5.3.0') >= 0) {\n                clearstatcache(true, $file_path);\n            } else {\n                clearstatcache();\n            }\n        }\n        return $this->fix_integer_overflow(filesize($file_path));\n    }\n\n    protected function is_valid_file_object($file_name) {\n        $file_path = $this->get_upload_path($file_name);\n        if (is_file($file_path) && $file_name[0] !== '.') {\n            return true;\n        }\n        return false;\n    }\n\n    protected function get_file_object($file_name) {\n        if ($this->is_valid_file_object($file_name)) {\n            $file = new \\stdClass();\n            $file->name = $file_name;\n            $file->size = $this->get_file_size(\n                $this->get_upload_path($file_name)\n            );\n            $file->url = $this->get_download_url($file->name);\n            foreach ($this->options['image_versions'] as $version => $options) {\n                if (!empty($version)) {\n                    if (is_file($this->get_upload_path($file_name, $version))) {\n                        $file->{$version.'Url'} = $this->get_download_url(\n                            $file->name,\n                            $version\n                        );\n                    }\n                }\n            }\n            $this->set_additional_file_properties($file);\n            return $file;\n        }\n        return null;\n    }\n\n    protected function get_file_objects($iteration_method = 'get_file_object') {\n        $upload_dir = $this->get_upload_path();\n        if (!is_dir($upload_dir)) {\n            return array();\n        }\n        return array_values(array_filter(array_map(\n            array($this, $iteration_method),\n            scandir($upload_dir)\n        )));\n    }\n\n    protected function count_file_objects() {\n        return count($this->get_file_objects('is_valid_file_object'));\n    }\n\n    protected function get_error_message($error) {\n        return isset($this->error_messages[$error]) ?\n            $this->error_messages[$error] : $error;\n    }\n\n    public function get_config_bytes($val) {\n        $val = trim($val);\n        $last = strtolower($val[strlen($val)-1]);\n        $val = (int)$val;\n        switch ($last) {\n            case 'g':\n                $val *= 1024;\n            case 'm':\n                $val *= 1024;\n            case 'k':\n                $val *= 1024;\n        }\n        return $this->fix_integer_overflow($val);\n    }\n\n    protected function validate($uploaded_file, $file, $error, $index) {\n        if ($error) {\n            $file->error = $this->get_error_message($error);\n            return false;\n        }\n        $content_length = $this->fix_integer_overflow(\n            (int)$this->get_server_var('CONTENT_LENGTH')\n        );\n        $post_max_size = $this->get_config_bytes(ini_get('post_max_size'));\n        if ($post_max_size && ($content_length > $post_max_size)) {\n            $file->error = $this->get_error_message('post_max_size');\n            return false;\n        }\n        if (!preg_match($this->options['accept_file_types'], $file->name)) {\n            $file->error = $this->get_error_message('accept_file_types');\n            return false;\n        }\n        if ($uploaded_file && is_uploaded_file($uploaded_file)) {\n            $file_size = $this->get_file_size($uploaded_file);\n        } else {\n            $file_size = $content_length;\n        }\n        if ($this->options['max_file_size'] && (\n                $file_size > $this->options['max_file_size'] ||\n                $file->size > $this->options['max_file_size'])\n            ) {\n            $file->error = $this->get_error_message('max_file_size');\n            return false;\n        }\n        if ($this->options['min_file_size'] &&\n            $file_size < $this->options['min_file_size']) {\n            $file->error = $this->get_error_message('min_file_size');\n            return false;\n        }\n        if (is_int($this->options['max_number_of_files']) &&\n                ($this->count_file_objects() >= $this->options['max_number_of_files']) &&\n                // Ignore additional chunks of existing files:\n                !is_file($this->get_upload_path($file->name))) {\n            $file->error = $this->get_error_message('max_number_of_files');\n            return false;\n        }\n        $max_width = @$this->options['max_width'];\n        $max_height = @$this->options['max_height'];\n        $min_width = @$this->options['min_width'];\n        $min_height = @$this->options['min_height'];\n        if (($max_width || $max_height || $min_width || $min_height)\n           && preg_match($this->options['image_file_types'], $file->name)) {\n            list($img_width, $img_height) = $this->get_image_size($uploaded_file);\n\n            // If we are auto rotating the image by default, do the checks on\n            // the correct orientation\n            if (\n                @$this->options['image_versions']['']['auto_orient'] &&\n                function_exists('exif_read_data') &&\n                ($exif = @exif_read_data($uploaded_file)) &&\n                (((int) @$exif['Orientation']) >= 5)\n            ) {\n                $tmp = $img_width;\n                $img_width = $img_height;\n                $img_height = $tmp;\n                unset($tmp);\n            }\n\n        }\n        if (!empty($img_width)) {\n            if ($max_width && $img_width > $max_width) {\n                $file->error = $this->get_error_message('max_width');\n                return false;\n            }\n            if ($max_height && $img_height > $max_height) {\n                $file->error = $this->get_error_message('max_height');\n                return false;\n            }\n            if ($min_width && $img_width < $min_width) {\n                $file->error = $this->get_error_message('min_width');\n                return false;\n            }\n            if ($min_height && $img_height < $min_height) {\n                $file->error = $this->get_error_message('min_height');\n                return false;\n            }\n        }\n        return true;\n    }\n\n    protected function upcount_name_callback($matches) {\n        $index = isset($matches[1]) ? ((int)$matches[1]) + 1 : 1;\n        $ext = isset($matches[2]) ? $matches[2] : '';\n        return ' ('.$index.')'.$ext;\n    }\n\n    protected function upcount_name($name) {\n        return preg_replace_callback(\n            '/(?:(?: \\(([\\d]+)\\))?(\\.[^.]+))?$/',\n            array($this, 'upcount_name_callback'),\n            $name,\n            1\n        );\n    }\n\n    protected function get_unique_filename($file_path, $name, $size, $type, $error,\n            $index, $content_range) {\n        while(is_dir($this->get_upload_path($name))) {\n            $name = $this->upcount_name($name);\n        }\n        // Keep an existing filename if this is part of a chunked upload:\n        $uploaded_bytes = $this->fix_integer_overflow((int)$content_range[1]);\n        while (is_file($this->get_upload_path($name))) {\n            if ($uploaded_bytes === $this->get_file_size(\n                    $this->get_upload_path($name))) {\n                break;\n            }\n            $name = $this->upcount_name($name);\n        }\n        return $name;\n    }\n\n    protected function fix_file_extension($file_path, $name, $size, $type, $error,\n            $index, $content_range) {\n        // Add missing file extension for known image types:\n        if (strpos($name, '.') === false &&\n                preg_match('/^image\\/(gif|jpe?g|png)/', $type, $matches)) {\n            $name .= '.'.$matches[1];\n        }\n        if ($this->options['correct_image_extensions'] &&\n                function_exists('exif_imagetype')) {\n            switch (@exif_imagetype($file_path)){\n                case IMAGETYPE_JPEG:\n                    $extensions = array('jpg', 'jpeg');\n                    break;\n                case IMAGETYPE_PNG:\n                    $extensions = array('png');\n                    break;\n                case IMAGETYPE_GIF:\n                    $extensions = array('gif');\n                    break;\n            }\n            // Adjust incorrect image file extensions:\n            if (!empty($extensions)) {\n                $parts = explode('.', $name);\n                $extIndex = count($parts) - 1;\n                $ext = strtolower(@$parts[$extIndex]);\n                if (!in_array($ext, $extensions)) {\n                    $parts[$extIndex] = $extensions[0];\n                    $name = implode('.', $parts);\n                }\n            }\n        }\n        return $name;\n    }\n\n    protected function trim_file_name($file_path, $name, $size, $type, $error,\n            $index, $content_range) {\n        // Remove path information and dots around the filename, to prevent uploading\n        // into different directories or replacing hidden system files.\n        // Also remove control characters and spaces (\\x00..\\x20) around the filename:\n        $name = trim($this->basename(stripslashes($name)), \".\\x00..\\x20\");\n        // Use a timestamp for empty filenames:\n        if (!$name) {\n            $name = str_replace('.', '-', microtime(true));\n        }\n        return $name;\n    }\n\n    protected function get_file_name($file_path, $name, $size, $type, $error,\n            $index, $content_range) {\n        $name = $this->trim_file_name($file_path, $name, $size, $type, $error,\n            $index, $content_range);\n        return $this->get_unique_filename(\n            $file_path,\n            $this->fix_file_extension($file_path, $name, $size, $type, $error,\n                $index, $content_range),\n            $size,\n            $type,\n            $error,\n            $index,\n            $content_range\n        );\n    }\n\n    protected function get_scaled_image_file_paths($file_name, $version) {\n        $file_path = $this->get_upload_path($file_name);\n        if (!empty($version)) {\n            $version_dir = $this->get_upload_path(null, $version);\n            if (!is_dir($version_dir)) {\n                mkdir($version_dir, $this->options['mkdir_mode'], true);\n            }\n            $new_file_path = $version_dir.'/'.$file_name;\n        } else {\n            $new_file_path = $file_path;\n        }\n        return array($file_path, $new_file_path);\n    }\n\n    protected function gd_get_image_object($file_path, $func, $no_cache = false) {\n        if (empty($this->image_objects[$file_path]) || $no_cache) {\n            $this->gd_destroy_image_object($file_path);\n            $this->image_objects[$file_path] = $func($file_path);\n        }\n        return $this->image_objects[$file_path];\n    }\n\n    protected function gd_set_image_object($file_path, $image) {\n        $this->gd_destroy_image_object($file_path);\n        $this->image_objects[$file_path] = $image;\n    }\n\n    protected function gd_destroy_image_object($file_path) {\n        $image = (isset($this->image_objects[$file_path])) ? $this->image_objects[$file_path] : null ;\n        return $image && imagedestroy($image);\n    }\n\n    protected function gd_imageflip($image, $mode) {\n        if (function_exists('imageflip')) {\n            return imageflip($image, $mode);\n        }\n        $new_width = $src_width = imagesx($image);\n        $new_height = $src_height = imagesy($image);\n        $new_img = imagecreatetruecolor($new_width, $new_height);\n        $src_x = 0;\n        $src_y = 0;\n        switch ($mode) {\n            case '1': // flip on the horizontal axis\n                $src_y = $new_height - 1;\n                $src_height = -$new_height;\n                break;\n            case '2': // flip on the vertical axis\n                $src_x  = $new_width - 1;\n                $src_width = -$new_width;\n                break;\n            case '3': // flip on both axes\n                $src_y = $new_height - 1;\n                $src_height = -$new_height;\n                $src_x  = $new_width - 1;\n                $src_width = -$new_width;\n                break;\n            default:\n                return $image;\n        }\n        imagecopyresampled(\n            $new_img,\n            $image,\n            0,\n            0,\n            $src_x,\n            $src_y,\n            $new_width,\n            $new_height,\n            $src_width,\n            $src_height\n        );\n        return $new_img;\n    }\n\n    protected function gd_orient_image($file_path, $src_img) {\n        if (!function_exists('exif_read_data')) {\n            return false;\n        }\n        $exif = @exif_read_data($file_path);\n        if ($exif === false) {\n            return false;\n        }\n        $orientation = (int)@$exif['Orientation'];\n        if ($orientation < 2 || $orientation > 8) {\n            return false;\n        }\n        switch ($orientation) {\n            case 2:\n                $new_img = $this->gd_imageflip(\n                    $src_img,\n                    defined('IMG_FLIP_VERTICAL') ? IMG_FLIP_VERTICAL : 2\n                );\n                break;\n            case 3:\n                $new_img = imagerotate($src_img, 180, 0);\n                break;\n            case 4:\n                $new_img = $this->gd_imageflip(\n                    $src_img,\n                    defined('IMG_FLIP_HORIZONTAL') ? IMG_FLIP_HORIZONTAL : 1\n                );\n                break;\n            case 5:\n                $tmp_img = $this->gd_imageflip(\n                    $src_img,\n                    defined('IMG_FLIP_HORIZONTAL') ? IMG_FLIP_HORIZONTAL : 1\n                );\n                $new_img = imagerotate($tmp_img, 270, 0);\n                imagedestroy($tmp_img);\n                break;\n            case 6:\n                $new_img = imagerotate($src_img, 270, 0);\n                break;\n            case 7:\n                $tmp_img = $this->gd_imageflip(\n                    $src_img,\n                    defined('IMG_FLIP_VERTICAL') ? IMG_FLIP_VERTICAL : 2\n                );\n                $new_img = imagerotate($tmp_img, 270, 0);\n                imagedestroy($tmp_img);\n                break;\n            case 8:\n                $new_img = imagerotate($src_img, 90, 0);\n                break;\n            default:\n                return false;\n        }\n        $this->gd_set_image_object($file_path, $new_img);\n        return true;\n    }\n\n    protected function gd_create_scaled_image($file_name, $version, $options) {\n        if (!function_exists('imagecreatetruecolor')) {\n            error_log('Function not found: imagecreatetruecolor');\n            return false;\n        }\n        list($file_path, $new_file_path) =\n            $this->get_scaled_image_file_paths($file_name, $version);\n        $type = strtolower(substr(strrchr($file_name, '.'), 1));\n        switch ($type) {\n            case 'jpg':\n            case 'jpeg':\n                $src_func = 'imagecreatefromjpeg';\n                $write_func = 'imagejpeg';\n                $image_quality = isset($options['jpeg_quality']) ?\n                    $options['jpeg_quality'] : 75;\n                break;\n            case 'gif':\n                $src_func = 'imagecreatefromgif';\n                $write_func = 'imagegif';\n                $image_quality = null;\n                break;\n            case 'png':\n                $src_func = 'imagecreatefrompng';\n                $write_func = 'imagepng';\n                $image_quality = isset($options['png_quality']) ?\n                    $options['png_quality'] : 9;\n                break;\n            default:\n                return false;\n        }\n        $src_img = $this->gd_get_image_object(\n            $file_path,\n            $src_func,\n            !empty($options['no_cache'])\n        );\n        $image_oriented = false;\n        if (!empty($options['auto_orient']) && $this->gd_orient_image(\n                $file_path,\n                $src_img\n            )) {\n            $image_oriented = true;\n            $src_img = $this->gd_get_image_object(\n                $file_path,\n                $src_func\n            );\n        }\n        $max_width = $img_width = imagesx($src_img);\n        $max_height = $img_height = imagesy($src_img);\n        if (!empty($options['max_width'])) {\n            $max_width = $options['max_width'];\n        }\n        if (!empty($options['max_height'])) {\n            $max_height = $options['max_height'];\n        }\n        $scale = min(\n            $max_width / $img_width,\n            $max_height / $img_height\n        );\n        if ($scale >= 1) {\n            if ($image_oriented) {\n                return $write_func($src_img, $new_file_path, $image_quality);\n            }\n            if ($file_path !== $new_file_path) {\n                return copy($file_path, $new_file_path);\n            }\n            return true;\n        }\n        if (empty($options['crop'])) {\n            $new_width = $img_width * $scale;\n            $new_height = $img_height * $scale;\n            $dst_x = 0;\n            $dst_y = 0;\n            $new_img = imagecreatetruecolor($new_width, $new_height);\n        } else {\n            if (($img_width / $img_height) >= ($max_width / $max_height)) {\n                $new_width = $img_width / ($img_height / $max_height);\n                $new_height = $max_height;\n            } else {\n                $new_width = $max_width;\n                $new_height = $img_height / ($img_width / $max_width);\n            }\n            $dst_x = 0 - ($new_width - $max_width) / 2;\n            $dst_y = 0 - ($new_height - $max_height) / 2;\n            $new_img = imagecreatetruecolor($max_width, $max_height);\n        }\n        // Handle transparency in GIF and PNG images:\n        switch ($type) {\n            case 'gif':\n            case 'png':\n                imagecolortransparent($new_img, imagecolorallocate($new_img, 0, 0, 0));\n            case 'png':\n                imagealphablending($new_img, false);\n                imagesavealpha($new_img, true);\n                break;\n        }\n        $success = imagecopyresampled(\n            $new_img,\n            $src_img,\n            $dst_x,\n            $dst_y,\n            0,\n            0,\n            $new_width,\n            $new_height,\n            $img_width,\n            $img_height\n        ) && $write_func($new_img, $new_file_path, $image_quality);\n        $this->gd_set_image_object($file_path, $new_img);\n        return $success;\n    }\n\n    protected function imagick_get_image_object($file_path, $no_cache = false) {\n        if (empty($this->image_objects[$file_path]) || $no_cache) {\n            $this->imagick_destroy_image_object($file_path);\n            $image = new \\Imagick();\n            if (!empty($this->options['imagick_resource_limits'])) {\n                foreach ($this->options['imagick_resource_limits'] as $type => $limit) {\n                    $image->setResourceLimit($type, $limit);\n                }\n            }\n            $image->readImage($file_path);\n            $this->image_objects[$file_path] = $image;\n        }\n        return $this->image_objects[$file_path];\n    }\n\n    protected function imagick_set_image_object($file_path, $image) {\n        $this->imagick_destroy_image_object($file_path);\n        $this->image_objects[$file_path] = $image;\n    }\n\n    protected function imagick_destroy_image_object($file_path) {\n        $image = (isset($this->image_objects[$file_path])) ? $this->image_objects[$file_path] : null ;\n        return $image && $image->destroy();\n    }\n\n    protected function imagick_orient_image($image) {\n        $orientation = $image->getImageOrientation();\n        $background = new \\ImagickPixel('none');\n        switch ($orientation) {\n            case \\imagick::ORIENTATION_TOPRIGHT: // 2\n                $image->flopImage(); // horizontal flop around y-axis\n                break;\n            case \\imagick::ORIENTATION_BOTTOMRIGHT: // 3\n                $image->rotateImage($background, 180);\n                break;\n            case \\imagick::ORIENTATION_BOTTOMLEFT: // 4\n                $image->flipImage(); // vertical flip around x-axis\n                break;\n            case \\imagick::ORIENTATION_LEFTTOP: // 5\n                $image->flopImage(); // horizontal flop around y-axis\n                $image->rotateImage($background, 270);\n                break;\n            case \\imagick::ORIENTATION_RIGHTTOP: // 6\n                $image->rotateImage($background, 90);\n                break;\n            case \\imagick::ORIENTATION_RIGHTBOTTOM: // 7\n                $image->flipImage(); // vertical flip around x-axis\n                $image->rotateImage($background, 270);\n                break;\n            case \\imagick::ORIENTATION_LEFTBOTTOM: // 8\n                $image->rotateImage($background, 270);\n                break;\n            default:\n                return false;\n        }\n        $image->setImageOrientation(\\imagick::ORIENTATION_TOPLEFT); // 1\n        return true;\n    }\n\n    protected function imagick_create_scaled_image($file_name, $version, $options) {\n        list($file_path, $new_file_path) =\n            $this->get_scaled_image_file_paths($file_name, $version);\n        $image = $this->imagick_get_image_object(\n            $file_path,\n            !empty($options['crop']) || !empty($options['no_cache'])\n        );\n        if ($image->getImageFormat() === 'GIF') {\n            // Handle animated GIFs:\n            $images = $image->coalesceImages();\n            foreach ($images as $frame) {\n                $image = $frame;\n                $this->imagick_set_image_object($file_name, $image);\n                break;\n            }\n        }\n        $image_oriented = false;\n        if (!empty($options['auto_orient'])) {\n            $image_oriented = $this->imagick_orient_image($image);\n        }\n        $new_width = $max_width = $img_width = $image->getImageWidth();\n        $new_height = $max_height = $img_height = $image->getImageHeight();\n        if (!empty($options['max_width'])) {\n            $new_width = $max_width = $options['max_width'];\n        }\n        if (!empty($options['max_height'])) {\n            $new_height = $max_height = $options['max_height'];\n        }\n        if (!($image_oriented || $max_width < $img_width || $max_height < $img_height)) {\n            if ($file_path !== $new_file_path) {\n                return copy($file_path, $new_file_path);\n            }\n            return true;\n        }\n        $crop = !empty($options['crop']);\n        if ($crop) {\n            $x = 0;\n            $y = 0;\n            if (($img_width / $img_height) >= ($max_width / $max_height)) {\n                $new_width = 0; // Enables proportional scaling based on max_height\n                $x = ($img_width / ($img_height / $max_height) - $max_width) / 2;\n            } else {\n                $new_height = 0; // Enables proportional scaling based on max_width\n                $y = ($img_height / ($img_width / $max_width) - $max_height) / 2;\n            }\n        }\n        $success = $image->resizeImage(\n            $new_width,\n            $new_height,\n            isset($options['filter']) ? $options['filter'] : \\imagick::FILTER_LANCZOS,\n            isset($options['blur']) ? $options['blur'] : 1,\n            $new_width && $new_height // fit image into constraints if not to be cropped\n        );\n        if ($success && $crop) {\n            $success = $image->cropImage(\n                $max_width,\n                $max_height,\n                $x,\n                $y\n            );\n            if ($success) {\n                $success = $image->setImagePage($max_width, $max_height, 0, 0);\n            }\n        }\n        $type = strtolower(substr(strrchr($file_name, '.'), 1));\n        switch ($type) {\n            case 'jpg':\n            case 'jpeg':\n                if (!empty($options['jpeg_quality'])) {\n                    $image->setImageCompression(\\imagick::COMPRESSION_JPEG);\n                    $image->setImageCompressionQuality($options['jpeg_quality']);\n                }\n                break;\n        }\n        if (!empty($options['strip'])) {\n            $image->stripImage();\n        }\n        return $success && $image->writeImage($new_file_path);\n    }\n\n    protected function imagemagick_create_scaled_image($file_name, $version, $options) {\n        list($file_path, $new_file_path) =\n            $this->get_scaled_image_file_paths($file_name, $version);\n        $resize = @$options['max_width']\n            .(empty($options['max_height']) ? '' : 'X'.$options['max_height']);\n        if (!$resize && empty($options['auto_orient'])) {\n            if ($file_path !== $new_file_path) {\n                return copy($file_path, $new_file_path);\n            }\n            return true;\n        }\n        $cmd = $this->options['convert_bin'];\n        if (!empty($this->options['convert_params'])) {\n            $cmd .= ' '.$this->options['convert_params'];\n        }\n        $cmd .= ' '.escapeshellarg($file_path);\n        if (!empty($options['auto_orient'])) {\n            $cmd .= ' -auto-orient';\n        }\n        if ($resize) {\n            // Handle animated GIFs:\n            $cmd .= ' -coalesce';\n            if (empty($options['crop'])) {\n                $cmd .= ' -resize '.escapeshellarg($resize.'>');\n            } else {\n                $cmd .= ' -resize '.escapeshellarg($resize.'^');\n                $cmd .= ' -gravity center';\n                $cmd .= ' -crop '.escapeshellarg($resize.'+0+0');\n            }\n            // Make sure the page dimensions are correct (fixes offsets of animated GIFs):\n            $cmd .= ' +repage';\n        }\n        if (!empty($options['convert_params'])) {\n            $cmd .= ' '.$options['convert_params'];\n        }\n        $cmd .= ' '.escapeshellarg($new_file_path);\n        exec($cmd, $output, $error);\n        if ($error) {\n            error_log(implode('\\n', $output));\n            return false;\n        }\n        return true;\n    }\n\n    protected function get_image_size($file_path) {\n        if ($this->options['image_library']) {\n            if (extension_loaded('imagick')) {\n                $image = new \\Imagick();\n                try {\n                    if (@$image->pingImage($file_path)) {\n                        $dimensions = array($image->getImageWidth(), $image->getImageHeight());\n                        $image->destroy();\n                        return $dimensions;\n                    }\n                    return false;\n                } catch (\\Exception $e) {\n                    error_log($e->getMessage());\n                }\n            }\n            if ($this->options['image_library'] === 2) {\n                $cmd = $this->options['identify_bin'];\n                $cmd .= ' -ping '.escapeshellarg($file_path);\n                exec($cmd, $output, $error);\n                if (!$error && !empty($output)) {\n                    // image.jpg JPEG 1920x1080 1920x1080+0+0 8-bit sRGB 465KB 0.000u 0:00.000\n                    $infos = preg_split('/\\s+/', substr($output[0], strlen($file_path)));\n                    $dimensions = preg_split('/x/', $infos[2]);\n                    return $dimensions;\n                }\n                return false;\n            }\n        }\n        if (!function_exists('getimagesize')) {\n            error_log('Function not found: getimagesize');\n            return false;\n        }\n        return @getimagesize($file_path);\n    }\n\n    protected function create_scaled_image($file_name, $version, $options) {\n        if ($this->options['image_library'] === 2) {\n            return $this->imagemagick_create_scaled_image($file_name, $version, $options);\n        }\n        if ($this->options['image_library'] && extension_loaded('imagick')) {\n            return $this->imagick_create_scaled_image($file_name, $version, $options);\n        }\n        return $this->gd_create_scaled_image($file_name, $version, $options);\n    }\n\n    protected function destroy_image_object($file_path) {\n        if ($this->options['image_library'] && extension_loaded('imagick')) {\n            return $this->imagick_destroy_image_object($file_path);\n        }\n    }\n\n    protected function is_valid_image_file($file_path) {\n        if (!preg_match($this->options['image_file_types'], $file_path)) {\n            return false;\n        }\n        if (function_exists('exif_imagetype')) {\n            return @exif_imagetype($file_path);\n        }\n        $image_info = $this->get_image_size($file_path);\n        return $image_info && $image_info[0] && $image_info[1];\n    }\n\n    protected function handle_image_file($file_path, $file) {\n        $failed_versions = array();\n        foreach ($this->options['image_versions'] as $version => $options) {\n            if ($this->create_scaled_image($file->name, $version, $options)) {\n                if (!empty($version)) {\n                    $file->{$version.'Url'} = $this->get_download_url(\n                        $file->name,\n                        $version\n                    );\n                } else {\n                    $file->size = $this->get_file_size($file_path, true);\n                }\n            } else {\n                $failed_versions[] = $version ? $version : 'original';\n            }\n        }\n        if (count($failed_versions)) {\n            $file->error = $this->get_error_message('image_resize')\n                    .' ('.implode($failed_versions, ', ').')';\n        }\n        // Free memory:\n        $this->destroy_image_object($file_path);\n    }\n\n    protected function handle_file_upload($uploaded_file, $name, $size, $type, $error,\n            $index = null, $content_range = null) {\n        $file = new \\stdClass();\n        $file->name = $this->get_file_name($uploaded_file, $name, $size, $type, $error,\n            $index, $content_range);\n        $file->size = $this->fix_integer_overflow((int)$size);\n        $file->type = $type;\n        if ($this->validate($uploaded_file, $file, $error, $index)) {\n            $this->handle_form_data($file, $index);\n            $upload_dir = $this->get_upload_path();\n            if (!is_dir($upload_dir)) {\n                mkdir($upload_dir, $this->options['mkdir_mode'], true);\n            }\n            $file_path = $this->get_upload_path($file->name);\n            $append_file = $content_range && is_file($file_path) &&\n                $file->size > $this->get_file_size($file_path);\n            if ($uploaded_file && is_uploaded_file($uploaded_file)) {\n                // multipart/formdata uploads (POST method uploads)\n                if ($append_file) {\n                    file_put_contents(\n                        $file_path,\n                        fopen($uploaded_file, 'r'),\n                        FILE_APPEND\n                    );\n                } else {\n                    move_uploaded_file($uploaded_file, $file_path);\n                }\n            } else {\n                // Non-multipart uploads (PUT method support)\n                file_put_contents(\n                    $file_path,\n                    fopen($this->options['input_stream'], 'r'),\n                    $append_file ? FILE_APPEND : 0\n                );\n            }\n            $file_size = $this->get_file_size($file_path, $append_file);\n            if ($file_size === $file->size) {\n                $file->url = $this->get_download_url($file->name);\n                if ($this->is_valid_image_file($file_path)) {\n                    $this->handle_image_file($file_path, $file);\n                }\n            } else {\n                $file->size = $file_size;\n                if (!$content_range && $this->options['discard_aborted_uploads']) {\n                    unlink($file_path);\n                    $file->error = $this->get_error_message('abort');\n                }\n            }\n            $this->set_additional_file_properties($file);\n        }\n        return $file;\n    }\n\n    protected function readfile($file_path) {\n        $file_size = $this->get_file_size($file_path);\n        $chunk_size = $this->options['readfile_chunk_size'];\n        if ($chunk_size && $file_size > $chunk_size) {\n            $handle = fopen($file_path, 'rb');\n            while (!feof($handle)) {\n                echo fread($handle, $chunk_size);\n                @ob_flush();\n                @flush();\n            }\n            fclose($handle);\n            return $file_size;\n        }\n        return readfile($file_path);\n    }\n\n    protected function body($str) {\n        echo $str;\n    }\n\n    protected function header($str) {\n        header($str);\n    }\n\n    protected function get_upload_data($id) {\n        return @$_FILES[$id];\n    }\n\n    protected function get_post_param($id) {\n        return @$_POST[$id];\n    }\n\n    protected function get_query_param($id) {\n        return @$_GET[$id];\n    }\n\n    protected function get_server_var($id) {\n        return @$_SERVER[$id];\n    }\n\n    protected function handle_form_data($file, $index) {\n        // Handle form data, e.g. $_POST['description'][$index]\n    }\n\n    protected function get_version_param() {\n        return $this->basename(stripslashes($this->get_query_param('version')));\n    }\n\n    protected function get_singular_param_name() {\n        return substr($this->options['param_name'], 0, -1);\n    }\n\n    protected function get_file_name_param() {\n        $name = $this->get_singular_param_name();\n        return $this->basename(stripslashes($this->get_query_param($name)));\n    }\n\n    protected function get_file_names_params() {\n        $params = $this->get_query_param($this->options['param_name']);\n        if (!$params) {\n            return null;\n        }\n        foreach ($params as $key => $value) {\n            $params[$key] = $this->basename(stripslashes($value));\n        }\n        return $params;\n    }\n\n    protected function get_file_type($file_path) {\n        switch (strtolower(pathinfo($file_path, PATHINFO_EXTENSION))) {\n            case 'jpeg':\n            case 'jpg':\n                return 'image/jpeg';\n            case 'png':\n                return 'image/png';\n            case 'gif':\n                return 'image/gif';\n            default:\n                return '';\n        }\n    }\n\n    protected function download() {\n        switch ($this->options['download_via_php']) {\n            case 1:\n                $redirect_header = null;\n                break;\n            case 2:\n                $redirect_header = 'X-Sendfile';\n                break;\n            case 3:\n                $redirect_header = 'X-Accel-Redirect';\n                break;\n            default:\n                return $this->header('HTTP/1.1 403 Forbidden');\n        }\n        $file_name = $this->get_file_name_param();\n        if (!$this->is_valid_file_object($file_name)) {\n            return $this->header('HTTP/1.1 404 Not Found');\n        }\n        if ($redirect_header) {\n            return $this->header(\n                $redirect_header.': '.$this->get_download_url(\n                    $file_name,\n                    $this->get_version_param(),\n                    true\n                )\n            );\n        }\n        $file_path = $this->get_upload_path($file_name, $this->get_version_param());\n        // Prevent browsers from MIME-sniffing the content-type:\n        $this->header('X-Content-Type-Options: nosniff');\n        if (!preg_match($this->options['inline_file_types'], $file_name)) {\n            $this->header('Content-Type: application/octet-stream');\n            $this->header('Content-Disposition: attachment; filename=\"'.$file_name.'\"');\n        } else {\n            $this->header('Content-Type: '.$this->get_file_type($file_path));\n            $this->header('Content-Disposition: inline; filename=\"'.$file_name.'\"');\n        }\n        $this->header('Content-Length: '.$this->get_file_size($file_path));\n        $this->header('Last-Modified: '.gmdate('D, d M Y H:i:s T', filemtime($file_path)));\n        $this->readfile($file_path);\n    }\n\n    protected function send_content_type_header() {\n        $this->header('Vary: Accept');\n        if (strpos($this->get_server_var('HTTP_ACCEPT'), 'application/json') !== false) {\n            $this->header('Content-type: application/json');\n        } else {\n            $this->header('Content-type: text/plain');\n        }\n    }\n\n    protected function send_access_control_headers() {\n        $this->header('Access-Control-Allow-Origin: '.$this->options['access_control_allow_origin']);\n        $this->header('Access-Control-Allow-Credentials: '\n            .($this->options['access_control_allow_credentials'] ? 'true' : 'false'));\n        $this->header('Access-Control-Allow-Methods: '\n            .implode(', ', $this->options['access_control_allow_methods']));\n        $this->header('Access-Control-Allow-Headers: '\n            .implode(', ', $this->options['access_control_allow_headers']));\n    }\n\n    public function generate_response($content, $print_response = true) {\n        $this->response = $content;\n        if ($print_response) {\n            $json = json_encode($content);\n            $redirect = stripslashes($this->get_post_param('redirect'));\n            if ($redirect && preg_match($this->options['redirect_allow_target'], $redirect)) {\n                $this->header('Location: '.sprintf($redirect, rawurlencode($json)));\n                return;\n            }\n            $this->head();\n            if ($this->get_server_var('HTTP_CONTENT_RANGE')) {\n                $files = isset($content[$this->options['param_name']]) ?\n                    $content[$this->options['param_name']] : null;\n                if ($files && is_array($files) && is_object($files[0]) && $files[0]->size) {\n                    $this->header('Range: 0-'.(\n                        $this->fix_integer_overflow((int)$files[0]->size) - 1\n                    ));\n                }\n            }\n            $this->body($json);\n        }\n        return $content;\n    }\n\n    public function get_response () {\n        return $this->response;\n    }\n\n    public function head() {\n        $this->header('Pragma: no-cache');\n        $this->header('Cache-Control: no-store, no-cache, must-revalidate');\n        $this->header('Content-Disposition: inline; filename=\"files.json\"');\n        // Prevent Internet Explorer from MIME-sniffing the content-type:\n        $this->header('X-Content-Type-Options: nosniff');\n        if ($this->options['access_control_allow_origin']) {\n            $this->send_access_control_headers();\n        }\n        $this->send_content_type_header();\n    }\n\n    public function get($print_response = true) {\n        if ($print_response && $this->get_query_param('download')) {\n            return $this->download();\n        }\n        $file_name = $this->get_file_name_param();\n        if ($file_name) {\n            $response = array(\n                $this->get_singular_param_name() => $this->get_file_object($file_name)\n            );\n        } else {\n            $response = array(\n                $this->options['param_name'] => $this->get_file_objects()\n            );\n        }\n        return $this->generate_response($response, $print_response);\n    }\n\n    public function post($print_response = true) {\n        if ($this->get_query_param('_method') === 'DELETE') {\n            return $this->delete($print_response);\n        }\n        $upload = $this->get_upload_data($this->options['param_name']);\n        // Parse the Content-Disposition header, if available:\n        $content_disposition_header = $this->get_server_var('HTTP_CONTENT_DISPOSITION');\n        $file_name = $content_disposition_header ?\n            rawurldecode(preg_replace(\n                '/(^[^\"]+\")|(\"$)/',\n                '',\n                $content_disposition_header\n            )) : null;\n        // Parse the Content-Range header, which has the following form:\n        // Content-Range: bytes 0-524287/2000000\n        $content_range_header = $this->get_server_var('HTTP_CONTENT_RANGE');\n        $content_range = $content_range_header ?\n            preg_split('/[^0-9]+/', $content_range_header) : null;\n        $size =  $content_range ? $content_range[3] : null;\n        $files = array();\n        if ($upload) {\n            if (is_array($upload['tmp_name'])) {\n                // param_name is an array identifier like \"files[]\",\n                // $upload is a multi-dimensional array:\n                foreach ($upload['tmp_name'] as $index => $value) {\n                    $files[] = $this->handle_file_upload(\n                        $upload['tmp_name'][$index],\n                        $file_name ? $file_name : $upload['name'][$index],\n                        $size ? $size : $upload['size'][$index],\n                        $upload['type'][$index],\n                        $upload['error'][$index],\n                        $index,\n                        $content_range\n                    );\n                }\n            } else {\n                // param_name is a single object identifier like \"file\",\n                // $upload is a one-dimensional array:\n                $files[] = $this->handle_file_upload(\n                    isset($upload['tmp_name']) ? $upload['tmp_name'] : null,\n                    $file_name ? $file_name : (isset($upload['name']) ?\n                            $upload['name'] : null),\n                    $size ? $size : (isset($upload['size']) ?\n                            $upload['size'] : $this->get_server_var('CONTENT_LENGTH')),\n                    isset($upload['type']) ?\n                            $upload['type'] : $this->get_server_var('CONTENT_TYPE'),\n                    isset($upload['error']) ? $upload['error'] : null,\n                    null,\n                    $content_range\n                );\n            }\n        }\n        $response = array($this->options['param_name'] => $files);\n        return $this->generate_response($response, $print_response);\n    }\n\n    public function delete($print_response = true) {\n        $file_names = $this->get_file_names_params();\n        if (empty($file_names)) {\n            $file_names = array($this->get_file_name_param());\n        }\n        $response = array();\n        foreach ($file_names as $file_name) {\n            $file_path = $this->get_upload_path($file_name);\n            $success = is_file($file_path) && $file_name[0] !== '.' && unlink($file_path);\n            if ($success) {\n                foreach ($this->options['image_versions'] as $version => $options) {\n                    if (!empty($version)) {\n                        $file = $this->get_upload_path($file_name, $version);\n                        if (is_file($file)) {\n                            unlink($file);\n                        }\n                    }\n                }\n            }\n            $response[$file_name] = $success;\n        }\n        return $this->generate_response($response, $print_response);\n    }\n\n    protected function basename($filepath, $suffix = null) {\n        $splited = preg_split('/\\//', rtrim ($filepath, '/ '));\n        return substr(basename('X'.$splited[count($splited)-1], $suffix), 1);\n    }\n}\n"
  },
  {
    "path": "app_frontend/static/plugin/jQuery-File-Upload-9.18.0/server/php/docker-compose.yml",
    "content": "apache:\n  build: ./\n  ports:\n    - \"80:80\"\n  volumes:\n    - \"../../:/var/www/html\"\n"
  },
  {
    "path": "app_frontend/static/plugin/jQuery-File-Upload-9.18.0/server/php/files/.gitignore",
    "content": "*\n!.gitignore\n!.htaccess\n"
  },
  {
    "path": "app_frontend/static/plugin/jQuery-File-Upload-9.18.0/server/php/files/.htaccess",
    "content": "# To enable the Headers module, execute the following command and reload Apache:\n# sudo a2enmod headers\n\n# The following directives prevent the execution of script files\n# in the context of the website.\n# They also force the content-type application/octet-stream and\n# force browsers to display a download dialog for non-image files.\nSetHandler default-handler\nForceType application/octet-stream\nHeader set Content-Disposition attachment\n\n# The following unsets the forced type and Content-Disposition headers\n# for known image files:\n<FilesMatch \"(?i)\\.(gif|jpe?g|png)$\">\n\tForceType none\n\tHeader unset Content-Disposition\n</FilesMatch>\n\n# The following directive prevents browsers from MIME-sniffing the content-type.\n# This is an important complement to the ForceType directive above:\nHeader set X-Content-Type-Options nosniff\n\n# Uncomment the following lines to prevent unauthorized download of files:\n#AuthName \"Authorization required\"\n#AuthType Basic\n#require valid-user\n"
  },
  {
    "path": "app_frontend/static/plugin/jQuery-File-Upload-9.18.0/server/php/index.php",
    "content": "<?php\n/*\n * jQuery File Upload Plugin PHP Example\n * https://github.com/blueimp/jQuery-File-Upload\n *\n * Copyright 2010, Sebastian Tschan\n * https://blueimp.net\n *\n * Licensed under the MIT license:\n * https://opensource.org/licenses/MIT\n */\n\nerror_reporting(E_ALL | E_STRICT);\nrequire('UploadHandler.php');\n$upload_handler = new UploadHandler();\n"
  },
  {
    "path": "app_frontend/static/plugin/jQuery-File-Upload-9.18.0/test/index.html",
    "content": "<!DOCTYPE HTML>\n<!--\n/*\n * jQuery File Upload Plugin Test\n * https://github.com/blueimp/jQuery-File-Upload\n *\n * Copyright 2010, Sebastian Tschan\n * https://blueimp.net\n *\n * Licensed under the MIT license:\n * https://opensource.org/licenses/MIT\n */\n-->\n<html lang=\"en\">\n<head>\n<!-- Force latest IE rendering engine or ChromeFrame if installed -->\n<!--[if IE]>\n<meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge,chrome=1\">\n<![endif]-->\n<meta charset=\"utf-8\">\n<title>jQuery File Upload Plugin Test</title>\n<meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n<link rel=\"stylesheet\" href=\"//codeorigin.jquery.com/qunit/qunit-1.14.0.css\">\n</head>\n<body>\n<h1 id=\"qunit-header\">jQuery File Upload Plugin Test</h1>\n<h2 id=\"qunit-banner\"></h2>\n<div id=\"qunit-testrunner-toolbar\"></div>\n<h2 id=\"qunit-userAgent\"></h2>\n<ol id=\"qunit-tests\"></ol>\n<div id=\"qunit-fixture\">\n    <!-- The file upload form used as target for the file upload widget -->\n    <form id=\"fileupload\" action=\"../server/php/\" method=\"POST\" enctype=\"multipart/form-data\">\n        <!-- The fileupload-buttonbar contains buttons to add/delete files and start/cancel the upload -->\n       <div class=\"row fileupload-buttonbar\">\n            <div class=\"col-lg-7\">\n                <!-- The fileinput-button span is used to style the file input field as button -->\n                <span class=\"btn btn-success fileinput-button\">\n                    <i class=\"icon-plus icon-white\"></i>\n                    <span>Add files...</span>\n                    <input type=\"file\" name=\"files[]\" multiple>\n                </span>\n                <button type=\"submit\" class=\"btn btn-primary start\">\n                    <i class=\"icon-upload icon-white\"></i>\n                    <span>Start upload</span>\n                </button>\n                <button type=\"reset\" class=\"btn btn-warning cancel\">\n                    <i class=\"icon-ban-circle icon-white\"></i>\n                    <span>Cancel upload</span>\n                </button>\n                <button type=\"button\" class=\"btn btn-danger delete\">\n                    <i class=\"icon-trash icon-white\"></i>\n                    <span>Delete</span>\n                </button>\n                <input type=\"checkbox\" class=\"toggle\">\n                <!-- The global file processing state -->\n                <span class=\"fileupload-process\"></span>\n            </div>\n            <!-- The global progress state -->\n            <div class=\"col-lg-5 fileupload-progress\">\n                <!-- The global progress bar -->\n                <div class=\"progress progress-striped active\" role=\"progressbar\" aria-valuemin=\"0\" aria-valuemax=\"100\">\n                    <div class=\"progress-bar progress-bar-success\" style=\"width:0%;\"></div>\n                </div>\n                <!-- The extended global progress state -->\n                <div class=\"progress-extended\">&nbsp;</div>\n            </div>\n        </div>\n        <!-- The table listing the files available for upload/download -->\n        <table role=\"presentation\" class=\"table table-striped\"><tbody class=\"files\"></tbody></table>\n    </form>\n</div>\n<!-- The template to display files available for upload -->\n<script id=\"template-upload\" type=\"text/x-tmpl\">\n{% for (var i=0, file; file=o.files[i]; i++) { %}\n    <tr class=\"template-upload\">\n        <td>\n            <span class=\"preview\"></span>\n        </td>\n        <td>\n            <p class=\"name\">{%=file.name%}</p>\n            <strong class=\"error text-danger\"></strong>\n        </td>\n        <td>\n            <p class=\"size\">Processing...</p>\n            <div class=\"progress progress-striped active\" role=\"progressbar\" aria-valuemin=\"0\" aria-valuemax=\"100\" aria-valuenow=\"0\"><div class=\"progress-bar progress-bar-success\" style=\"width:0%;\"></div></div>\n        </td>\n        <td>\n            {% if (!i && !o.options.autoUpload) { %}\n                <button class=\"btn btn-primary start\" disabled>\n                    <i class=\"glyphicon glyphicon-upload\"></i>\n                    <span>Start</span>\n                </button>\n            {% } %}\n            {% if (!i) { %}\n                <button class=\"btn btn-warning cancel\">\n                    <i class=\"glyphicon glyphicon-ban-circle\"></i>\n                    <span>Cancel</span>\n                </button>\n            {% } %}\n        </td>\n    </tr>\n{% } %}\n</script>\n<!-- The template to display files available for download -->\n<script id=\"template-download\" type=\"text/x-tmpl\">\n{% for (var i=0, file; file=o.files[i]; i++) { %}\n    <tr class=\"template-download\">\n        <td>\n            <span class=\"preview\">\n                {% if (file.thumbnailUrl) { %}\n                    <a href=\"{%=file.url%}\" title=\"{%=file.name%}\" download=\"{%=file.name%}\" data-gallery><img src=\"{%=file.thumbnailUrl%}\"></a>\n                {% } %}\n            </span>\n        </td>\n        <td>\n            <p class=\"name\">\n                {% if (file.url) { %}\n                    <a href=\"{%=file.url%}\" title=\"{%=file.name%}\" download=\"{%=file.name%}\" {%=file.thumbnailUrl?'data-gallery':''%}>{%=file.name%}</a>\n                {% } else { %}\n                    <span>{%=file.name%}</span>\n                {% } %}\n            </p>\n            {% if (file.error) { %}\n                <div><span class=\"label label-danger\">Error</span> {%=file.error%}</div>\n            {% } %}\n        </td>\n        <td>\n            <span class=\"size\">{%=o.formatFileSize(file.size)%}</span>\n        </td>\n        <td>\n            {% if (file.deleteUrl) { %}\n                <button class=\"btn btn-danger delete\" data-type=\"{%=file.deleteType%}\" data-url=\"{%=file.deleteUrl%}\"{% if (file.deleteWithCredentials) { %} data-xhr-fields='{\"withCredentials\":true}'{% } %}>\n                    <i class=\"glyphicon glyphicon-trash\"></i>\n                    <span>Delete</span>\n                </button>\n                <input type=\"checkbox\" name=\"delete\" value=\"1\" class=\"toggle\">\n            {% } else { %}\n                <button class=\"btn btn-warning cancel\">\n                    <i class=\"glyphicon glyphicon-ban-circle\"></i>\n                    <span>Cancel</span>\n                </button>\n            {% } %}\n        </td>\n    </tr>\n{% } %}\n</script>\n<script src=\"//ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js\"></script>\n<script src=\"../js/vendor/jquery.ui.widget.js\"></script>\n<script src=\"//blueimp.github.io/JavaScript-Templates/js/tmpl.min.js\"></script>\n<script src=\"//blueimp.github.io/JavaScript-Load-Image/js/load-image.all.min.js\"></script>\n<script src=\"//blueimp.github.io/JavaScript-Canvas-to-Blob/js/canvas-to-blob.min.js\"></script>\n<script src=\"../js/jquery.iframe-transport.js\"></script>\n<script src=\"../js/jquery.fileupload.js\"></script>\n<script>\n/* global window, $ */\nwindow.testBasicWidget = $.blueimp.fileupload;\n</script>\n<script src=\"../js/jquery.fileupload-process.js\"></script>\n<script src=\"../js/jquery.fileupload-image.js\"></script>\n<script src=\"../js/jquery.fileupload-audio.js\"></script>\n<script src=\"../js/jquery.fileupload-video.js\"></script>\n<script src=\"../js/jquery.fileupload-validate.js\"></script>\n<script src=\"../js/jquery.fileupload-ui.js\"></script>\n<script>\n/* global window, $ */\nwindow.testUIWidget = $.blueimp.fileupload;\n</script>\n<script src=\"//code.jquery.com/qunit/qunit-1.15.0.js\"></script>\n<script src=\"test.js\"></script>\n</body>\n</html>\n"
  },
  {
    "path": "app_frontend/static/plugin/jQuery-File-Upload-9.18.0/test/test.js",
    "content": "/*\n * jQuery File Upload Plugin Test\n * https://github.com/blueimp/jQuery-File-Upload\n *\n * Copyright 2010, Sebastian Tschan\n * https://blueimp.net\n *\n * Licensed under the MIT license:\n * https://opensource.org/licenses/MIT\n */\n\n/* global $, QUnit, window, document, expect, module, test, asyncTest, start, ok, strictEqual, notStrictEqual */\n\n$(function () {\n    // jshint nomen:false\n    'use strict';\n\n    QUnit.done = function () {\n        // Delete all uploaded files:\n        var url = $('#fileupload').prop('action');\n        $.getJSON(url, function (result) {\n            $.each(result.files, function (index, file) {\n                $.ajax({\n                    url: url + '?file=' + encodeURIComponent(file.name),\n                    type: 'DELETE'\n                });\n            });\n        });\n    };\n\n    var lifecycle = {\n            setup: function () {\n                // Set the .fileupload method to the basic widget method:\n                $.widget('blueimp.fileupload', window.testBasicWidget, {});\n            },\n            teardown: function () {\n                // Remove all remaining event listeners:\n                $(document).unbind();\n            }\n        },\n        lifecycleUI = {\n            setup: function () {\n                // Set the .fileupload method to the UI widget method:\n                $.widget('blueimp.fileupload', window.testUIWidget, {});\n            },\n            teardown: function () {\n                // Remove all remaining event listeners:\n                $(document).unbind();\n            }\n        };\n\n    module('Initialization', lifecycle);\n\n    test('Widget initialization', function () {\n        var fu = $('#fileupload').fileupload();\n        ok(fu.data('blueimp-fileupload') || fu.data('fileupload'));\n    });\n\n    test('Data attribute options', function () {\n        $('#fileupload').attr('data-url', 'http://example.org');\n        $('#fileupload').fileupload();\n        strictEqual(\n            $('#fileupload').fileupload('option', 'url'),\n            'http://example.org'\n        );\n    });\n\n    test('File input initialization', function () {\n        var fu = $('#fileupload').fileupload();\n        ok(\n            fu.fileupload('option', 'fileInput').length,\n            'File input field inside of the widget'\n        );\n        ok(\n            fu.fileupload('option', 'fileInput').length,\n            'Widget element as file input field'\n        );\n    });\n\n    test('Drop zone initialization', function () {\n        ok($('#fileupload').fileupload()\n            .fileupload('option', 'dropZone').length);\n    });\n\n    test('Paste zone initialization', function () {\n        ok($('#fileupload').fileupload({pasteZone: document})\n            .fileupload('option', 'pasteZone').length);\n    });\n\n    test('Event listeners initialization', function () {\n        expect(\n            $.support.xhrFormDataFileUpload ? 4 : 1\n        );\n        var eo = {\n                originalEvent: {\n                    dataTransfer: {files: [{}], types: ['Files']},\n                    clipboardData: {items: [{}]}\n                }\n            },\n            fu = $('#fileupload').fileupload({\n                pasteZone: document,\n                dragover: function () {\n                    ok(true, 'Triggers dragover callback');\n                    return false;\n                },\n                drop: function () {\n                    ok(true, 'Triggers drop callback');\n                    return false;\n                },\n                paste: function () {\n                    ok(true, 'Triggers paste callback');\n                    return false;\n                },\n                change: function () {\n                    ok(true, 'Triggers change callback');\n                    return false;\n                }\n            }),\n            fileInput = fu.fileupload('option', 'fileInput'),\n            dropZone = fu.fileupload('option', 'dropZone'),\n            pasteZone = fu.fileupload('option', 'pasteZone');\n        fileInput.trigger($.Event('change', eo));\n        dropZone.trigger($.Event('dragover', eo));\n        dropZone.trigger($.Event('drop', eo));\n        pasteZone.trigger($.Event('paste', eo));\n    });\n\n    module('API', lifecycle);\n\n    test('destroy', function () {\n        expect(4);\n        var eo = {\n                originalEvent: {\n                    dataTransfer: {files: [{}], types: ['Files']},\n                    clipboardData: {items: [{}]}\n                }\n            },\n            options = {\n                pasteZone: document,\n                dragover: function () {\n                    ok(true, 'Triggers dragover callback');\n                    return false;\n                },\n                drop: function () {\n                    ok(true, 'Triggers drop callback');\n                    return false;\n                },\n                paste: function () {\n                    ok(true, 'Triggers paste callback');\n                    return false;\n                },\n                change: function () {\n                    ok(true, 'Triggers change callback');\n                    return false;\n                }\n            },\n            fu = $('#fileupload').fileupload(options),\n            fileInput = fu.fileupload('option', 'fileInput'),\n            dropZone = fu.fileupload('option', 'dropZone'),\n            pasteZone = fu.fileupload('option', 'pasteZone');\n        dropZone.bind('dragover', options.dragover);\n        dropZone.bind('drop', options.drop);\n        pasteZone.bind('paste', options.paste);\n        fileInput.bind('change', options.change);\n        fu.fileupload('destroy');\n        fileInput.trigger($.Event('change', eo));\n        dropZone.trigger($.Event('dragover', eo));\n        dropZone.trigger($.Event('drop', eo));\n        pasteZone.trigger($.Event('paste', eo));\n    });\n\n    test('disable/enable', function () {\n        expect(\n            $.support.xhrFormDataFileUpload ? 4 : 1\n        );\n        var eo = {\n                originalEvent: {\n                    dataTransfer: {files: [{}], types: ['Files']},\n                    clipboardData: {items: [{}]}\n                }\n            },\n            fu = $('#fileupload').fileupload({\n                pasteZone: document,\n                dragover: function () {\n                    ok(true, 'Triggers dragover callback');\n                    return false;\n                },\n                drop: function () {\n                    ok(true, 'Triggers drop callback');\n                    return false;\n                },\n                paste: function () {\n                    ok(true, 'Triggers paste callback');\n                    return false;\n                },\n                change: function () {\n                    ok(true, 'Triggers change callback');\n                    return false;\n                }\n            }),\n            fileInput = fu.fileupload('option', 'fileInput'),\n            dropZone = fu.fileupload('option', 'dropZone'),\n            pasteZone = fu.fileupload('option', 'pasteZone');\n        fu.fileupload('disable');\n        fileInput.trigger($.Event('change', eo));\n        dropZone.trigger($.Event('dragover', eo));\n        dropZone.trigger($.Event('drop', eo));\n        pasteZone.trigger($.Event('paste', eo));\n        fu.fileupload('enable');\n        fileInput.trigger($.Event('change', eo));\n        dropZone.trigger($.Event('dragover', eo));\n        dropZone.trigger($.Event('drop', eo));\n        pasteZone.trigger($.Event('paste', eo));\n    });\n\n    test('option', function () {\n        expect(\n            $.support.xhrFormDataFileUpload ? 10 : 7\n        );\n        var eo = {\n                originalEvent: {\n                    dataTransfer: {files: [{}], types: ['Files']},\n                    clipboardData: {items: [{}]}\n                }\n            },\n            fu = $('#fileupload').fileupload({\n                pasteZone: document,\n                dragover: function () {\n                    ok(true, 'Triggers dragover callback');\n                    return false;\n                },\n                drop: function () {\n                    ok(true, 'Triggers drop callback');\n                    return false;\n                },\n                paste: function () {\n                    ok(true, 'Triggers paste callback');\n                    return false;\n                },\n                change: function () {\n                    ok(true, 'Triggers change callback');\n                    return false;\n                }\n            }),\n            fileInput = fu.fileupload('option', 'fileInput'),\n            dropZone = fu.fileupload('option', 'dropZone'),\n            pasteZone = fu.fileupload('option', 'pasteZone');\n        fu.fileupload('option', 'fileInput', null);\n        fu.fileupload('option', 'dropZone', null);\n        fu.fileupload('option', 'pasteZone', null);\n        fileInput.trigger($.Event('change', eo));\n        dropZone.trigger($.Event('dragover', eo));\n        dropZone.trigger($.Event('drop', eo));\n        pasteZone.trigger($.Event('paste', eo));\n        fu.fileupload('option', 'dropZone', 'body');\n        strictEqual(\n            fu.fileupload('option', 'dropZone')[0],\n            document.body,\n            'Allow a query string as parameter for the dropZone option'\n        );\n        fu.fileupload('option', 'dropZone', document);\n        strictEqual(\n            fu.fileupload('option', 'dropZone')[0],\n            document,\n            'Allow a document element as parameter for the dropZone option'\n        );\n        fu.fileupload('option', 'pasteZone', 'body');\n        strictEqual(\n            fu.fileupload('option', 'pasteZone')[0],\n            document.body,\n            'Allow a query string as parameter for the pasteZone option'\n        );\n        fu.fileupload('option', 'pasteZone', document);\n        strictEqual(\n            fu.fileupload('option', 'pasteZone')[0],\n            document,\n            'Allow a document element as parameter for the pasteZone option'\n        );\n        fu.fileupload('option', 'fileInput', ':file');\n        strictEqual(\n            fu.fileupload('option', 'fileInput')[0],\n            $(':file')[0],\n            'Allow a query string as parameter for the fileInput option'\n        );\n        fu.fileupload('option', 'fileInput', $(':file')[0]);\n        strictEqual(\n            fu.fileupload('option', 'fileInput')[0],\n            $(':file')[0],\n            'Allow a document element as parameter for the fileInput option'\n        );\n        fu.fileupload('option', 'fileInput', fileInput);\n        fu.fileupload('option', 'dropZone', dropZone);\n        fu.fileupload('option', 'pasteZone', pasteZone);\n        fileInput.trigger($.Event('change', eo));\n        dropZone.trigger($.Event('dragover', eo));\n        dropZone.trigger($.Event('drop', eo));\n        pasteZone.trigger($.Event('paste', eo));\n    });\n\n    asyncTest('add', function () {\n        expect(2);\n        var param = {files: [{name: 'test'}]};\n        $('#fileupload').fileupload({\n            add: function (e, data) {\n                strictEqual(\n                    data.files[0].name,\n                    param.files[0].name,\n                    'Triggers add callback'\n                );\n            }\n        }).fileupload('add', param).fileupload(\n            'option',\n            'add',\n            function (e, data) {\n                data.submit().complete(function () {\n                    ok(true, 'data.submit() Returns a jqXHR object');\n                    start();\n                });\n            }\n        ).fileupload('add', param);\n    });\n\n    asyncTest('send', function () {\n        expect(3);\n        var param = {files: [{name: 'test'}]};\n        $('#fileupload').fileupload({\n            send: function (e, data) {\n                strictEqual(\n                    data.files[0].name,\n                    'test',\n                    'Triggers send callback'\n                );\n            }\n        }).fileupload('send', param).fail(function () {\n            ok(true, 'Allows to abort the request');\n        }).complete(function () {\n            ok(true, 'Returns a jqXHR object');\n            start();\n        }).abort();\n    });\n\n    module('Callbacks', lifecycle);\n\n    asyncTest('add', function () {\n        expect(1);\n        var param = {files: [{name: 'test'}]};\n        $('#fileupload').fileupload({\n            add: function () {\n                ok(true, 'Triggers add callback');\n                start();\n            }\n        }).fileupload('add', param);\n    });\n\n    asyncTest('submit', function () {\n        expect(1);\n        var param = {files: [{name: 'test'}]};\n        $('#fileupload').fileupload({\n            submit: function () {\n                ok(true, 'Triggers submit callback');\n                start();\n                return false;\n            }\n        }).fileupload('add', param);\n    });\n\n    asyncTest('send', function () {\n        expect(1);\n        var param = {files: [{name: 'test'}]};\n        $('#fileupload').fileupload({\n            send: function () {\n                ok(true, 'Triggers send callback');\n                start();\n                return false;\n            }\n        }).fileupload('send', param);\n    });\n\n    asyncTest('done', function () {\n        expect(1);\n        var param = {files: [{name: 'test'}]};\n        $('#fileupload').fileupload({\n            done: function () {\n                ok(true, 'Triggers done callback');\n                start();\n            }\n        }).fileupload('send', param);\n    });\n\n    asyncTest('fail', function () {\n        expect(1);\n        var param = {files: [{name: 'test'}]},\n            fu = $('#fileupload').fileupload({\n                url: '404',\n                fail: function () {\n                    ok(true, 'Triggers fail callback');\n                    start();\n                }\n            });\n        (fu.data('blueimp-fileupload') || fu.data('fileupload'))\n            ._isXHRUpload = function () {\n                return true;\n            };\n        fu.fileupload('send', param);\n    });\n\n    asyncTest('always', function () {\n        expect(2);\n        var param = {files: [{name: 'test'}]},\n            counter = 0,\n            fu = $('#fileupload').fileupload({\n                always: function () {\n                    ok(true, 'Triggers always callback');\n                    if (counter === 1) {\n                        start();\n                    } else {\n                        counter += 1;\n                    }\n                }\n            });\n        (fu.data('blueimp-fileupload') || fu.data('fileupload'))\n            ._isXHRUpload = function () {\n                return true;\n            };\n        fu.fileupload('add', param).fileupload(\n            'option',\n            'url',\n            '404'\n        ).fileupload('add', param);\n    });\n\n    asyncTest('progress', function () {\n        expect(1);\n        var param = {files: [{name: 'test'}]},\n            counter = 0;\n        $('#fileupload').fileupload({\n            forceIframeTransport: true,\n            progress: function () {\n                ok(true, 'Triggers progress callback');\n                if (counter === 0) {\n                    start();\n                } else {\n                    counter += 1;\n                }\n            }\n        }).fileupload('send', param);\n    });\n\n    asyncTest('progressall', function () {\n        expect(1);\n        var param = {files: [{name: 'test'}]},\n            counter = 0;\n        $('#fileupload').fileupload({\n            forceIframeTransport: true,\n            progressall: function () {\n                ok(true, 'Triggers progressall callback');\n                if (counter === 0) {\n                    start();\n                } else {\n                    counter += 1;\n                }\n            }\n        }).fileupload('send', param);\n    });\n\n    asyncTest('start', function () {\n        expect(1);\n        var param = {files: [{name: '1'}, {name: '2'}]},\n            active = 0;\n        $('#fileupload').fileupload({\n            send: function () {\n                active += 1;\n            },\n            start: function () {\n                ok(!active, 'Triggers start callback before uploads');\n                start();\n            }\n        }).fileupload('send', param);\n    });\n\n    asyncTest('stop', function () {\n        expect(1);\n        var param = {files: [{name: '1'}, {name: '2'}]},\n            active = 0;\n        $('#fileupload').fileupload({\n            send: function () {\n                active += 1;\n            },\n            always: function () {\n                active -= 1;\n            },\n            stop: function () {\n                ok(!active, 'Triggers stop callback after uploads');\n                start();\n            }\n        }).fileupload('send', param);\n    });\n\n    test('change', function () {\n        var fu = $('#fileupload').fileupload(),\n            fuo = fu.data('blueimp-fileupload') || fu.data('fileupload'),\n            fileInput = fu.fileupload('option', 'fileInput');\n        expect(2);\n        fu.fileupload({\n            change: function (e, data) {\n                ok(true, 'Triggers change callback');\n                strictEqual(\n                    data.files.length,\n                    0,\n                    'Returns empty files list'\n                );\n            },\n            add: $.noop\n        });\n        fuo._onChange({\n            data: {fileupload: fuo},\n            target: fileInput[0]\n        });\n    });\n\n    test('paste', function () {\n        var fu = $('#fileupload').fileupload(),\n            fuo = fu.data('blueimp-fileupload') || fu.data('fileupload');\n        expect(1);\n        fu.fileupload({\n            paste: function () {\n                ok(true, 'Triggers paste callback');\n            },\n            add: $.noop\n        });\n        fuo._onPaste({\n            data: {fileupload: fuo},\n            originalEvent: {\n                dataTransfer: {files: [{}]},\n                clipboardData: {items: [{}]}\n            },\n            preventDefault: $.noop\n        });\n    });\n\n    test('drop', function () {\n        var fu = $('#fileupload').fileupload(),\n            fuo = fu.data('blueimp-fileupload') || fu.data('fileupload');\n        expect(1);\n        fu.fileupload({\n            drop: function () {\n                ok(true, 'Triggers drop callback');\n            },\n            add: $.noop\n        });\n        fuo._onDrop({\n            data: {fileupload: fuo},\n            originalEvent: {\n                dataTransfer: {files: [{}]},\n                clipboardData: {items: [{}]}\n            },\n            preventDefault: $.noop\n        });\n    });\n\n    test('dragover', function () {\n        var fu = $('#fileupload').fileupload(),\n            fuo = fu.data('blueimp-fileupload') || fu.data('fileupload');\n        expect(1);\n        fu.fileupload({\n            dragover: function () {\n                ok(true, 'Triggers dragover callback');\n            },\n            add: $.noop\n        });\n        fuo._onDragOver({\n            data: {fileupload: fuo},\n            originalEvent: {dataTransfer: {types: ['Files']}},\n            preventDefault: $.noop\n        });\n    });\n\n    module('Options', lifecycle);\n\n    test('paramName', function () {\n        expect(1);\n        var param = {files: [{name: 'test'}]};\n        $('#fileupload').fileupload({\n            paramName: null,\n            send: function (e, data) {\n                strictEqual(\n                    data.paramName[0],\n                    data.fileInput.prop('name'),\n                    'Takes paramName from file input field if not set'\n                );\n                return false;\n            }\n        }).fileupload('send', param);\n    });\n\n    test('url', function () {\n        expect(1);\n        var param = {files: [{name: 'test'}]};\n        $('#fileupload').fileupload({\n            url: null,\n            send: function (e, data) {\n                strictEqual(\n                    data.url,\n                    $(data.fileInput.prop('form')).prop('action'),\n                    'Takes url from form action if not set'\n                );\n                return false;\n            }\n        }).fileupload('send', param);\n    });\n\n    test('type', function () {\n        expect(2);\n        var param = {files: [{name: 'test'}]};\n        $('#fileupload').fileupload({\n            type: null,\n            send: function (e, data) {\n                strictEqual(\n                    data.type,\n                    'POST',\n                    'Request type is \"POST\" if not set to \"PUT\"'\n                );\n                return false;\n            }\n        }).fileupload('send', param);\n        $('#fileupload').fileupload({\n            type: 'PUT',\n            send: function (e, data) {\n                strictEqual(\n                    data.type,\n                    'PUT',\n                    'Request type is \"PUT\" if set to \"PUT\"'\n                );\n                return false;\n            }\n        }).fileupload('send', param);\n    });\n\n    test('replaceFileInput', function () {\n        var fu = $('#fileupload').fileupload(),\n            fuo = fu.data('blueimp-fileupload') || fu.data('fileupload'),\n            fileInput = fu.fileupload('option', 'fileInput'),\n            fileInputElement = fileInput[0];\n        expect(2);\n        fu.fileupload({\n            replaceFileInput: false,\n            change: function () {\n                strictEqual(\n                    fu.fileupload('option', 'fileInput')[0],\n                    fileInputElement,\n                    'Keeps file input with replaceFileInput: false'\n                );\n            },\n            add: $.noop\n        });\n        fuo._onChange({\n            data: {fileupload: fuo},\n            target: fileInput[0]\n        });\n        fu.fileupload({\n            replaceFileInput: true,\n            change: function () {\n                notStrictEqual(\n                    fu.fileupload('option', 'fileInput')[0],\n                    fileInputElement,\n                    'Replaces file input with replaceFileInput: true'\n                );\n            },\n            add: $.noop\n        });\n        fuo._onChange({\n            data: {fileupload: fuo},\n            target: fileInput[0]\n        });\n    });\n\n    asyncTest('forceIframeTransport', function () {\n        expect(1);\n        var param = {files: [{name: 'test'}]};\n        $('#fileupload').fileupload({\n            forceIframeTransport: true,\n            done: function (e, data) {\n                strictEqual(\n                    data.dataType.substr(0, 6),\n                    'iframe',\n                    'Iframe Transport is used'\n                );\n                start();\n            }\n        }).fileupload('send', param);\n    });\n\n    test('singleFileUploads', function () {\n        expect(3);\n        var fu = $('#fileupload').fileupload(),\n            param = {files: [{name: '1'}, {name: '2'}]},\n            index = 1;\n        (fu.data('blueimp-fileupload') || fu.data('fileupload'))\n            ._isXHRUpload = function () {\n                return true;\n            };\n        $('#fileupload').fileupload({\n            singleFileUploads: true,\n            add: function () {\n                ok(true, 'Triggers callback number ' + index.toString());\n                index += 1;\n            }\n        }).fileupload('add', param).fileupload(\n            'option',\n            'singleFileUploads',\n            false\n        ).fileupload('add', param);\n    });\n\n    test('limitMultiFileUploads', function () {\n        expect(3);\n        var fu = $('#fileupload').fileupload(),\n            param = {files: [\n                {name: '1'},\n                {name: '2'},\n                {name: '3'},\n                {name: '4'},\n                {name: '5'}\n            ]},\n            index = 1;\n        (fu.data('blueimp-fileupload') || fu.data('fileupload'))\n            ._isXHRUpload = function () {\n                return true;\n            };\n        $('#fileupload').fileupload({\n            singleFileUploads: false,\n            limitMultiFileUploads: 2,\n            add: function () {\n                ok(true, 'Triggers callback number ' + index.toString());\n                index += 1;\n            }\n        }).fileupload('add', param);\n    });\n\n    test('limitMultiFileUploadSize', function () {\n        expect(7);\n        var fu = $('#fileupload').fileupload(),\n            param = {files: [\n                {name: '1-1', size: 100000},\n                {name: '1-2', size: 40000},\n                {name: '2-1', size: 100000},\n                {name: '3-1', size: 50000},\n                {name: '3-2', size: 40000},\n                {name: '4-1', size: 45000} // New request due to limitMultiFileUploads\n            ]},\n            param2 = {files: [\n                {name: '5-1'},\n                {name: '5-2'},\n                {name: '6-1'},\n                {name: '6-2'},\n                {name: '7-1'}\n            ]},\n            index = 1;\n        (fu.data('blueimp-fileupload') || fu.data('fileupload'))\n            ._isXHRUpload = function () {\n                return true;\n            };\n        $('#fileupload').fileupload({\n            singleFileUploads: false,\n            limitMultiFileUploads: 2,\n            limitMultiFileUploadSize: 150000,\n            limitMultiFileUploadSizeOverhead: 5000,\n            add: function () {\n                ok(true, 'Triggers callback number ' + index.toString());\n                index += 1;\n            }\n        }).fileupload('add', param).fileupload('add', param2);\n    });\n\n    asyncTest('sequentialUploads', function () {\n        expect(6);\n        var param = {files: [\n                {name: '1'},\n                {name: '2'},\n                {name: '3'},\n                {name: '4'},\n                {name: '5'},\n                {name: '6'}\n            ]},\n            addIndex = 0,\n            sendIndex = 0,\n            loadIndex = 0,\n            fu = $('#fileupload').fileupload({\n                sequentialUploads: true,\n                add: function (e, data) {\n                    addIndex += 1;\n                    if (addIndex === 4) {\n                        data.submit().abort();\n                    } else {\n                        data.submit();\n                    }\n                },\n                send: function () {\n                    sendIndex += 1;\n                },\n                done: function () {\n                    loadIndex += 1;\n                    strictEqual(sendIndex, loadIndex, 'upload in order');\n                },\n                fail: function (e, data) {\n                    strictEqual(data.errorThrown, 'abort', 'upload aborted');\n                },\n                stop: function () {\n                    start();\n                }\n            });\n        (fu.data('blueimp-fileupload') || fu.data('fileupload'))\n            ._isXHRUpload = function () {\n                return true;\n            };\n        fu.fileupload('add', param);\n    });\n\n    asyncTest('limitConcurrentUploads', function () {\n        expect(12);\n        var param = {files: [\n                {name: '1'},\n                {name: '2'},\n                {name: '3'},\n                {name: '4'},\n                {name: '5'},\n                {name: '6'},\n                {name: '7'},\n                {name: '8'},\n                {name: '9'},\n                {name: '10'},\n                {name: '11'},\n                {name: '12'}\n            ]},\n            addIndex = 0,\n            sendIndex = 0,\n            loadIndex = 0,\n            fu = $('#fileupload').fileupload({\n                limitConcurrentUploads: 3,\n                add: function (e, data) {\n                    addIndex += 1;\n                    if (addIndex === 4) {\n                        data.submit().abort();\n                    } else {\n                        data.submit();\n                    }\n                },\n                send: function () {\n                    sendIndex += 1;\n                },\n                done: function () {\n                    loadIndex += 1;\n                    ok(sendIndex - loadIndex < 3);\n                },\n                fail: function (e, data) {\n                    strictEqual(data.errorThrown, 'abort', 'upload aborted');\n                },\n                stop: function () {\n                    start();\n                }\n            });\n        (fu.data('blueimp-fileupload') || fu.data('fileupload'))\n            ._isXHRUpload = function () {\n                return true;\n            };\n        fu.fileupload('add', param);\n    });\n\n    if ($.support.xhrFileUpload) {\n        asyncTest('multipart', function () {\n            expect(2);\n            var param = {files: [{\n                    name: 'test.png',\n                    size: 123,\n                    type: 'image/png'\n                }]},\n                fu = $('#fileupload').fileupload({\n                    multipart: false,\n                    always: function (e, data) {\n                        strictEqual(\n                            data.contentType,\n                            param.files[0].type,\n                            'non-multipart upload sets file type as contentType'\n                        );\n                        strictEqual(\n                            data.headers['Content-Disposition'],\n                            'attachment; filename=\"' + param.files[0].name + '\"',\n                            'non-multipart upload sets Content-Disposition header'\n                        );\n                        start();\n                    }\n                });\n            fu.fileupload('send', param);\n        });\n    }\n\n    module('UI Initialization', lifecycleUI);\n\n    test('Widget initialization', function () {\n        var fu = $('#fileupload').fileupload();\n        ok(fu.data('blueimp-fileupload') || fu.data('fileupload'));\n        ok(\n            $('#fileupload').fileupload('option', 'uploadTemplate').length,\n            'Initialized upload template'\n        );\n        ok(\n            $('#fileupload').fileupload('option', 'downloadTemplate').length,\n            'Initialized download template'\n        );\n    });\n\n    test('Buttonbar event listeners', function () {\n        var buttonbar = $('#fileupload .fileupload-buttonbar'),\n            files = [{name: 'test'}];\n        expect(4);\n        $('#fileupload').fileupload({\n            send: function () {\n                ok(true, 'Started file upload via global start button');\n            },\n            fail: function (e, data) {\n                ok(true, 'Canceled file upload via global cancel button');\n                data.context.remove();\n            },\n            destroy: function () {\n                ok(true, 'Delete action called via global delete button');\n            }\n        });\n        $('#fileupload').fileupload('add', {files: files});\n        buttonbar.find('.cancel').click();\n        $('#fileupload').fileupload('add', {files: files});\n        buttonbar.find('.start').click();\n        buttonbar.find('.cancel').click();\n        files[0].deleteUrl = 'http://example.org/banana.jpg';\n        ($('#fileupload').data('blueimp-fileupload') ||\n                $('#fileupload').data('fileupload'))\n            ._renderDownload(files)\n            .appendTo($('#fileupload .files')).show()\n            .find('.toggle').click();\n        buttonbar.find('.delete').click();\n    });\n\n    module('UI API', lifecycleUI);\n\n    test('destroy', function () {\n        var buttonbar = $('#fileupload .fileupload-buttonbar'),\n            files = [{name: 'test'}];\n        expect(1);\n        $('#fileupload').fileupload({\n            send: function () {\n                ok(true, 'This test should not run');\n                return false;\n            }\n        })\n            .fileupload('add', {files: files})\n            .fileupload('destroy');\n        buttonbar.find('.start').click(function () {\n            ok(true, 'Clicked global start button');\n            return false;\n        }).click();\n    });\n\n    test('disable/enable', function () {\n        var buttonbar = $('#fileupload .fileupload-buttonbar');\n        $('#fileupload').fileupload();\n        $('#fileupload').fileupload('disable');\n        strictEqual(\n            buttonbar.find('input[type=file], button').not(':disabled').length,\n            0,\n            'Disables the buttonbar buttons'\n        );\n        $('#fileupload').fileupload('enable');\n        strictEqual(\n            buttonbar.find('input[type=file], button').not(':disabled').length,\n            4,\n            'Enables the buttonbar buttons'\n        );\n    });\n\n    module('UI Callbacks', lifecycleUI);\n\n    test('destroy', function () {\n        expect(3);\n        $('#fileupload').fileupload({\n            destroy: function (e, data) {\n                ok(true, 'Triggers destroy callback');\n                strictEqual(\n                    data.url,\n                    'test',\n                    'Passes over deletion url parameter'\n                );\n                strictEqual(\n                    data.type,\n                    'DELETE',\n                    'Passes over deletion request type parameter'\n                );\n            }\n        });\n        ($('#fileupload').data('blueimp-fileupload') ||\n                $('#fileupload').data('fileupload'))\n            ._renderDownload([{\n                name: 'test',\n                deleteUrl: 'test',\n                deleteType: 'DELETE'\n            }])\n            .appendTo($('#fileupload .files'))\n            .show()\n            .find('.toggle').click();\n        $('#fileupload .fileupload-buttonbar .delete').click();\n    });\n\n    asyncTest('added', function () {\n        expect(1);\n        var param = {files: [{name: 'test'}]};\n        $('#fileupload').fileupload({\n            added: function (e, data) {\n                start();\n                strictEqual(\n                    data.files[0].name,\n                    param.files[0].name,\n                    'Triggers added callback'\n                );\n            },\n            send: function () {\n                return false;\n            }\n        }).fileupload('add', param);\n    });\n\n    asyncTest('started', function () {\n        expect(1);\n        var param = {files: [{name: 'test'}]};\n        $('#fileupload').fileupload({\n            started: function () {\n                start();\n                ok('Triggers started callback');\n                return false;\n            },\n            sent: function () {\n                return false;\n            }\n        }).fileupload('send', param);\n    });\n\n    asyncTest('sent', function () {\n        expect(1);\n        var param = {files: [{name: 'test'}]};\n        $('#fileupload').fileupload({\n            sent: function (e, data) {\n                start();\n                strictEqual(\n                    data.files[0].name,\n                    param.files[0].name,\n                    'Triggers sent callback'\n                );\n                return false;\n            }\n        }).fileupload('send', param);\n    });\n\n    asyncTest('completed', function () {\n        expect(1);\n        var param = {files: [{name: 'test'}]};\n        $('#fileupload').fileupload({\n            completed: function () {\n                start();\n                ok('Triggers completed callback');\n                return false;\n            }\n        }).fileupload('send', param);\n    });\n\n    asyncTest('failed', function () {\n        expect(1);\n        var param = {files: [{name: 'test'}]};\n        $('#fileupload').fileupload({\n            failed: function () {\n                start();\n                ok('Triggers failed callback');\n                return false;\n            }\n        }).fileupload('send', param).abort();\n    });\n\n    asyncTest('stopped', function () {\n        expect(1);\n        var param = {files: [{name: 'test'}]};\n        $('#fileupload').fileupload({\n            stopped: function () {\n                start();\n                ok('Triggers stopped callback');\n                return false;\n            }\n        }).fileupload('send', param);\n    });\n\n    asyncTest('destroyed', function () {\n        expect(1);\n        $('#fileupload').fileupload({\n            dataType: 'html',\n            destroyed: function () {\n                start();\n                ok(true, 'Triggers destroyed callback');\n            }\n        });\n        ($('#fileupload').data('blueimp-fileupload') ||\n                $('#fileupload').data('fileupload'))\n            ._renderDownload([{\n                name: 'test',\n                deleteUrl: '.',\n                deleteType: 'GET'\n            }])\n            .appendTo($('#fileupload .files'))\n            .show()\n            .find('.toggle').click();\n        $('#fileupload .fileupload-buttonbar .delete').click();\n    });\n\n    module('UI Options', lifecycleUI);\n\n    test('autoUpload', function () {\n        expect(1);\n        $('#fileupload')\n            .fileupload({\n                autoUpload: true,\n                send: function () {\n                    ok(true, 'Started file upload automatically');\n                    return false;\n                }\n            })\n            .fileupload('add', {files: [{name: 'test'}]})\n            .fileupload('option', 'autoUpload', false)\n            .fileupload('add', {files: [{name: 'test'}]});\n    });\n\n    test('maxNumberOfFiles', function () {\n        expect(3);\n        var addIndex = 0,\n            sendIndex = 0;\n        $('#fileupload')\n            .fileupload({\n                autoUpload: true,\n                maxNumberOfFiles: 3,\n                singleFileUploads: false,\n                send: function () {\n                    strictEqual(\n                        sendIndex += 1,\n                        addIndex\n                    );\n                },\n                progress: $.noop,\n                progressall: $.noop,\n                done: $.noop,\n                stop: $.noop\n            })\n            .fileupload('add', {files: [{name: (addIndex += 1)}]})\n            .fileupload('add', {files: [{name: (addIndex += 1)}]})\n            .fileupload('add', {files: [{name: (addIndex += 1)}]})\n            .fileupload('add', {files: [{name: 'test'}]});\n    });\n\n    test('maxFileSize', function () {\n        expect(2);\n        var addIndex = 0,\n            sendIndex = 0;\n        $('#fileupload')\n            .fileupload({\n                autoUpload: true,\n                maxFileSize: 1000,\n                send: function () {\n                    strictEqual(\n                        sendIndex += 1,\n                        addIndex\n                    );\n                    return false;\n                }\n            })\n            .fileupload('add', {files: [{\n                name: (addIndex += 1)\n            }]})\n            .fileupload('add', {files: [{\n                name: (addIndex += 1),\n                size: 999\n            }]})\n            .fileupload('add', {files: [{\n                name: 'test',\n                size: 1001\n            }]})\n            .fileupload({\n                send: function (e, data) {\n                    ok(\n                        !$.blueimp.fileupload.prototype.options\n                            .send.call(this, e, data)\n                    );\n                    return false;\n                }\n            });\n    });\n\n    test('minFileSize', function () {\n        expect(2);\n        var addIndex = 0,\n            sendIndex = 0;\n        $('#fileupload')\n            .fileupload({\n                autoUpload: true,\n                minFileSize: 1000,\n                send: function () {\n                    strictEqual(\n                        sendIndex += 1,\n                        addIndex\n                    );\n                    return false;\n                }\n            })\n            .fileupload('add', {files: [{\n                name: (addIndex += 1)\n            }]})\n            .fileupload('add', {files: [{\n                name: (addIndex += 1),\n                size: 1001\n            }]})\n            .fileupload('add', {files: [{\n                name: 'test',\n                size: 999\n            }]})\n            .fileupload({\n                send: function (e, data) {\n                    ok(\n                        !$.blueimp.fileupload.prototype.options\n                            .send.call(this, e, data)\n                    );\n                    return false;\n                }\n            });\n    });\n\n    test('acceptFileTypes', function () {\n        expect(2);\n        var addIndex = 0,\n            sendIndex = 0;\n        $('#fileupload')\n            .fileupload({\n                autoUpload: true,\n                acceptFileTypes: /(\\.|\\/)(gif|jpe?g|png)$/i,\n                disableImageMetaDataLoad: true,\n                send: function () {\n                    strictEqual(\n                        sendIndex += 1,\n                        addIndex\n                    );\n                    return false;\n                }\n            })\n            .fileupload('add', {files: [{\n                name: (addIndex += 1) + '.jpg'\n            }]})\n            .fileupload('add', {files: [{\n                name: (addIndex += 1),\n                type: 'image/jpeg'\n            }]})\n            .fileupload('add', {files: [{\n                name: 'test.txt',\n                type: 'text/plain'\n            }]})\n            .fileupload({\n                send: function (e, data) {\n                    ok(\n                        !$.blueimp.fileupload.prototype.options\n                            .send.call(this, e, data)\n                    );\n                    return false;\n                }\n            });\n    });\n\n    test('acceptFileTypes as HTML5 data attribute', function () {\n        expect(2);\n        var regExp = /(\\.|\\/)(gif|jpe?g|png)$/i;\n        $('#fileupload')\n            .attr('data-accept-file-types', regExp.toString())\n            .fileupload();\n        strictEqual(\n            $.type($('#fileupload').fileupload('option', 'acceptFileTypes')),\n            $.type(regExp)\n        );\n        strictEqual(\n            $('#fileupload').fileupload('option', 'acceptFileTypes').toString(),\n            regExp.toString()\n        );\n    });\n\n});\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/.editorconfig",
    "content": "root = true\n\n[*]\ncharset = utf-8\nend_of_line = lf\ninsert_final_newline = true\ntrim_trailing_whitespace = true\nindent_style = space\n\n[*.{js,json}]\nindent_size = 4\n\n[*.{yml}]\nindent_size = 2\n\n[*.md]\ntrim_trailing_whitespace = false\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/.gitattributes",
    "content": "# we don't have non-text files, don't take chances with git's text=auto\n* text\n# this file is read by nuget (Windows) tooling, lets keep it happy\nMoment.js.nuspec eol=crlf\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/.gitignore",
    "content": "node_modules/\n.DS_Store\nmin/moment+customlangs.js\nmin/moment+customlangs.min.js\nsauce_connect.log\n.sauce-labs.creds\nnpm-debug.log\n.build*\nbuild\ncoverage\nnyc_output\n.nyc_output\n.coveralls.yml\n.vscode/\n.idea\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/.jscs.json",
    "content": "{\n    \"requireCurlyBraces\": [\n        \"if\",\n        \"else\",\n        \"for\",\n        \"while\",\n        \"do\",\n        \"try\",\n        \"catch\"\n    ],\n    \"requireSpaceAfterKeywords\": [\n        \"if\",\n        \"else\",\n        \"for\",\n        \"while\",\n        \"do\",\n        \"switch\",\n        \"return\",\n        \"try\",\n        \"catch\"\n    ],\n    \"requireSpaceBeforeBlockStatements\": true,\n    \"requireParenthesesAroundIIFE\": true,\n    \"requireSpacesInConditionalExpression\": true,\n    \"requireSpacesInAnonymousFunctionExpression\": {\n        \"beforeOpeningRoundBrace\": true,\n        \"beforeOpeningCurlyBrace\": true\n    },\n    \"requireSpacesInNamedFunctionExpression\": {\n        \"beforeOpeningCurlyBrace\": true\n    },\n    \"disallowSpacesInNamedFunctionExpression\": {\n        \"beforeOpeningRoundBrace\": true\n    },\n    \"requireBlocksOnNewline\": true,\n    \"disallowPaddingNewlinesInBlocks\": true,\n    \"disallowEmptyBlocks\": true,\n    \"disallowSpacesInsideObjectBrackets\": true,\n    \"disallowSpacesInsideArrayBrackets\": true,\n    \"disallowSpacesInsideParentheses\": true,\n    \"requireCommaBeforeLineBreak\": true,\n    \"disallowSpaceAfterPrefixUnaryOperators\": [\"++\", \"--\", \"+\", \"-\", \"~\", \"!\"],\n    \"disallowSpaceBeforePostfixUnaryOperators\": [\"++\", \"--\"],\n    \"requireSpaceBeforeBinaryOperators\": [\n        \"=\", \"+=\", \"-=\", \"*=\", \"/=\", \"%=\", \"<<=\", \">>=\", \">>>=\",\n        \"&=\", \"|=\", \"^=\",\n\n        \"+\", \"-\", \"*\", \"/\", \"%\", \"<<\", \">>\", \">>>\", \"&\",\n        \"|\", \"^\", \"&&\", \"||\", \"===\", \"==\", \">=\",\n        \"<=\", \"<\", \">\", \"!=\", \"!==\"\n    ],\n    \"requireSpaceAfterBinaryOperators\": true,\n    \"requireCamelCaseOrUpperCaseIdentifiers\": \"ignoreProperties\",\n    \"disallowKeywords\": [\"with\"],\n    \"disallowMultipleLineStrings\": true,\n    \"validateIndentation\": 4,\n    \"disallowTrailingWhitespace\": true,\n    \"disallowTrailingComma\": true,\n    \"requireLineFeedAtFileEnd\": true,\n    \"requireCapitalizedConstructors\": true,\n    \"validateQuoteMarks\": {\n        \"mark\": \"'\",\n        \"escape\": true\n    }\n}\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/.jshintrc",
    "content": "{\n    \"node\"     : true,\n    \"browser\"  : true,\n    \"boss\"     : false,\n    \"curly\"    : true,\n    \"debug\"    : false,\n    \"devel\"    : false,\n    \"eqeqeq\"   : true,\n    \"eqnull\"   : true,\n    \"esnext\"   : true,\n    \"evil\"     : false,\n    \"forin\"    : false,\n    \"immed\"    : false,\n    \"laxbreak\" : false,\n    \"newcap\"   : true,\n    \"noarg\"    : true,\n    \"noempty\"  : false,\n    \"nonew\"    : false,\n    \"onevar\"   : true,\n    \"plusplus\" : false,\n    \"regexp\"   : false,\n    \"undef\"    : true,\n    \"sub\"      : true,\n    \"strict\"   : false,\n    \"white\"    : true,\n    \"es3\"      : false,\n    \"camelcase\" : true,\n    \"globals\": {\n        \"define\": false\n    }\n}\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/.npmignore",
    "content": "test\nmin/tests.js\n.npmignore\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/.spmignore",
    "content": "benchmarks\nbower_components\nmeteor\nmin\nnode_modules\nscripts\ntasks\ntest\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/.travis.yml",
    "content": "language: node_js\nnode_js:\n  - \"node\"\n  - \"0.12\"\nsudo: false\n\nenv:\n  global:\n    - secure: \"M4STT2TOZxjzv3cZOgSVi0J4j6enrGjgE+p5YTNUw+S6Dg6FS5pTIPeafu1kGhfm7F0uk7xPVwGKYb+3uWNO9IhkKXz8jySMMQ2iKISHwECGNNuFNjSMD1vIjbIkLwV8TyPO/PurQg2s+WtYz+DoAZsDFKpdaRUtif64OjdQ3vQ=\"\n    - secure: \"V+i7kHoGe7VXWGplPNqJz+aDtgDF9Dh9/guoaf2BPyXLvkFW6VgMjJyoNUW7JVsakrWzAz2ubb734vAPDt7BCcFQ2BqfatOmabdFogviCaXC6IqVaEkYS2eSP7MIUPIeWJgnTrDGzkFMDk4K7y5SiVJ8UmYwZxe+tJV7kbb0Yig=\"\n\ninstall:\n  - npm install\n  - npm install -g grunt-cli\n\nscript: grunt build:travis\n\ngit:\n  depth: 10\n\n# TODO: Fix problem with coveralls.io not displaying autogenerated files\n# after_success: npm run coveralls\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/CHANGELOG.md",
    "content": "Changelog\n=========\n\n### 2.18.1\n\n* Release Mar 22, 2017\n\n* [#3853](https://github.com/moment/moment/pull/3853) [misc] Fix invalid whitespace character causing inability to parse\n  moment.js\n\n### 2.18.0 [See full changelog](https://gist.github.com/ichernev/78920c5a1e419fb28c6e4546d1b7235c)\n\n* Release Mar 18, 2017\n\n## Features\n\n* [#3708](https://github.com/moment/moment/pull/3708) [feature] RFC2822 parsing\n* [#3611](https://github.com/moment/moment/pull/3611) [feature] Durations gain validity\n* [#3738](https://github.com/moment/moment/pull/3738) [feature] Enable relative time for multiple seconds, request [#2558](https://github.com/moment/moment/issues/2558)\n* [#3766](https://github.com/moment/moment/pull/3766) [feature] Add support for k and kk format parsing\n\n## Bugfixes\n\n* [#3643](https://github.com/moment/moment/pull/3643) [bugfix] Fixes [#3520](https://github.com/moment/moment/issues/3520), parseZone incorrectly handled minutes under 16\n* [#3710](https://github.com/moment/moment/pull/3710) [bugfix] Fixes [#3632](https://github.com/moment/moment/issues/3632), toISOString returns null for invalid date\n* [#3787](https://github.com/moment/moment/pull/3787) [bugfix] Fixes [#3717](https://github.com/moment/moment/issues/3717), ensure day-of-year is non-zero\n* [#3780](https://github.com/moment/moment/pull/3780) [bugfix] Fixes [#3765](https://github.com/moment/moment/issues/3765): Ensure year 0 is formatted with YYYY\n* [#3806](https://github.com/moment/moment/pull/3806) [bugfix] Fixes [#3805](https://github.com/moment/moment/issues/3805), fix locale month getters for standalone/format cases\n\n7 new locales, many locale improvements and some misc changes\n\n### 2.17.1 [Also available here](https://gist.github.com/ichernev/f38280b2b29c4932914a6d3a4e50bfb2)\n* Release Dec 03, 2016\n\n* [#3638](https://github.com/moment/moment/pull/3638) [misc] TS: Make typescript definitions work with 1.x\n* [#3628](https://github.com/moment/moment/pull/3628) [misc] Adds \"sign CLA\" link to `CONTRIBUTING.md`\n* [#3640](https://github.com/moment/moment/pull/3640) [misc] Fix locale issues\n\n### 2.17.0 [Also available here](https://gist.github.com/ichernev/ed58f76fb95205eeac653d719972b90c)\n* Release Nov 22, 2016\n\n* [#3435](https://github.com/moment/moment/pull/3435) [new locale] yo: Yoruba (Nigeria) locale\n* [#3595](https://github.com/moment/moment/pull/3595) [bugfix] Fix accidental reference to global \"value\" variable\n* [#3506](https://github.com/moment/moment/pull/3506) [bugfix] Fix invalid moments returning valid dates to method calls\n* [#3563](https://github.com/moment/moment/pull/3563) [locale] ca: Change future relative time\n* [#3504](https://github.com/moment/moment/pull/3504) [tests] Fixes [#3463](https://github.com/moment/moment/issues/3463), parseZone not handling Z correctly (tests only)\n* [#3591](https://github.com/moment/moment/pull/3591) [misc] typescript: update typescript to 2.0.8, add strictNullChecks=true\n* [#3597](https://github.com/moment/moment/pull/3597) [misc] Fixed capitalization in nuget spec\n\n### 2.16.0 [See full changelog](https://gist.github.com/ichernev/17bffc1005a032cb1a8ac4c1558b4994)\n* Release Nov 9, 2016\n\n## Features\n* [#3530](https://github.com/moment/moment/pull/3530) [feature] Check whether input is date before checking if format is array\n* [#3515](https://github.com/moment/moment/pull/3515) [feature] Fix [#2300](https://github.com/moment/moment/issues/2300): Default to current week.\n\n## Bugfixes\n* [#3546](https://github.com/moment/moment/pull/3546) [bugfix] Implement lazy-loading of child locales with missing prents\n* [#3523](https://github.com/moment/moment/pull/3523) [bugfix] parseZone should handle UTC\n* [#3502](https://github.com/moment/moment/pull/3502) [bugfix] Fix [#3500](https://github.com/moment/moment/issues/3500): ISO 8601 parsing should match the full string, not the beginning of the string.\n* [#3581](https://github.com/moment/moment/pull/3581) [bugfix] Fix parseZone, redo [#3504](https://github.com/moment/moment/issues/3504), fix [#3463](https://github.com/moment/moment/issues/3463)\n\n## New Locales\n* [#3416](https://github.com/moment/moment/pull/3416) [new locale] nl-be: Dutch (Belgium) locale\n* [#3393](https://github.com/moment/moment/pull/3393) [new locale] ar-dz: Arabic (Algeria) locale\n* [#3342](https://github.com/moment/moment/pull/3342) [new locale] tet: Tetun Dili (East Timor) locale\n\nAnd more locale, build and typescript improvements\n\n### 2.15.2\n* Release Oct 23, 2016\n* [#3525](https://github.com/moment/moment/pull/3525) Speedup month standalone/format regexes **(IMPORTANT)**\n* [#3466](https://github.com/moment/moment/pull/3466) Fix typo of Javanese\n\n### 2.15.1\n* Release Sept 20, 2016\n* [#3438](https://github.com/moment/moment/pull/3438) Fix locale autoload, revert [#3344](https://github.com/moment/moment/pull/3344)\n\n### 2.15.0 [See full changelog](https://gist.github.com/ichernev/10e1c5bf647545c72ca30e9628a09ed3)\n- Release Sept 12, 2016\n\n## New Locales\n* [#3255](https://github.com/moment/moment/pull/3255) [new locale] mi: Maori language\n* [#3267](https://github.com/moment/moment/pull/3267) [new locale] ar-ly: Arabic (Libya) locale\n* [#3333](https://github.com/moment/moment/pull/3333) [new locale] zh-hk: Chinese (Hong Kong) locale\n\n## Bugfixes\n* [#3276](https://github.com/moment/moment/pull/3276) [bugfix] duration: parser: Support ms durations in .NET syntax\n* [#3312](https://github.com/moment/moment/pull/3312) [bugfix] locales: Enable locale-data getters without moment (fixes [#3284](https://github.com/moment/moment/issues/3284))\n* [#3381](https://github.com/moment/moment/pull/3381) [bugfix] parsing: Fix parseZone without timezone in string, fixes [#3083](https://github.com/moment/moment/issues/3083)\n* [#3383](https://github.com/moment/moment/pull/3383) [bugfix] toJSON: Fix isValid so that toJSON works after a moment is frozen\n* [#3427](https://github.com/moment/moment/pull/3427) [bugfix] ie8: Fix IE8 (regression in 2.14.x)\n\n## Packaging\n* [#3299](https://github.com/moment/moment/pull/3299) [pkg] npm: Do not include .npmignore in npm package\n* [#3273](https://github.com/moment/moment/pull/3273) [pkg] jspm: Include moment.d.ts file in package\n* [#3344](https://github.com/moment/moment/pull/3344) [pkg] exports: use module.require for nodejs\n\nAlso some locale and typescript improvements\n\n### 2.14.1\n- Release July 20, 2016\n* [#3280](https://github.com/moment/moment/pull/3280) Fix typescript definitions\n\n\n### 2.14.0 [See full changelog](https://gist.github.com/ichernev/812e79ac36a7829a22598fe964bfc18a)\n\n- Release July 20, 2016\n\n## New Features\n* [#3233](https://github.com/moment/moment/pull/3233) Introduce month.isFormat for format/standalone discovery\n* [#2848](https://github.com/moment/moment/pull/2848) Allow user to get/set the rounding method used when calculating relative time\n* [#3112](https://github.com/moment/moment/pull/3112) optimize configFromStringAndFormat\n* [#3147](https://github.com/moment/moment/pull/3147) Call calendar format function with moment context\n* [#3160](https://github.com/moment/moment/pull/3160) deprecate isDSTShifted\n* [#3175](https://github.com/moment/moment/pull/3175) make moment calendar extensible with ad-hoc options\n* [#3191](https://github.com/moment/moment/pull/3191) toDate returns a copy of the internal date object\n* [#3192](https://github.com/moment/moment/pull/3192) Adding support for rollup import.\n* [#3238](https://github.com/moment/moment/pull/3238) Handle empty object and empty array for creation as now\n* [#3082](https://github.com/moment/moment/pull/3082) Use relative AMD moment dependency\n\n## Bugfixes\n* [#3241](https://github.com/moment/moment/pull/3241) Escape all 24 mixed pieces, not only first 12 in computeMonthsParse\n* [#3008](https://github.com/moment/moment/pull/3008) Object setter orders sets based on size of unit\n* [#3177](https://github.com/moment/moment/pull/3177) Bug Fix [#2704](https://github.com/moment/moment/pull/2704) - isoWeekday(String) inconsistent with isoWeekday(Number)\n* [#3230](https://github.com/moment/moment/pull/3230) fix passing date with format string to ignore format string\n* [#3232](https://github.com/moment/moment/pull/3232) Fix negative 0 in certain diff cases\n* [#3235](https://github.com/moment/moment/pull/3235) Use proper locale inheritance for the base locale, fixes [#3137](https://github.com/moment/moment/pull/3137)\n\nPlus es-do locale and locale bugfixes\n\n### 2.13.0 [See full changelog](https://gist.github.com/ichernev/0132fcf5b61f7fc140b0bb0090480d49)\n- Release April 18, 2016\n\n## Enhancements:\n* [#2982](https://github.com/moment/moment/pull/2982) Add 'date' as alias to 'day' for startOf() and endOf().\n* [#2955](https://github.com/moment/moment/pull/2955) Add parsing negative components in durations when ISO 8601\n* [#2991](https://github.com/moment/moment/pull/2991) isBetween support for both open and closed intervals\n* [#3105](https://github.com/moment/moment/pull/3105) Add localeSorted argument to weekday listers\n* [#3102](https://github.com/moment/moment/pull/3102) Add k and kk formatting tokens\n\n## Bugfixes\n* [#3109](https://github.com/moment/moment/pull/3109) Fix [#1756](https://github.com/moment/moment/issues/1756) Resolved thread-safe issue on server side.\n* [#3078](https://github.com/moment/moment/pull/3078) Fix parsing for months/weekdays with weird characters\n* [#3098](https://github.com/moment/moment/pull/3098) Use Z suffix when in UTC mode ([#3020](https://github.com/moment/moment/issues/3020))\n* [#2995](https://github.com/moment/moment/pull/2995) Fix floating point rounding errors in durations\n* [#3059](https://github.com/moment/moment/pull/3059) fix bug where diff returns -0 in month-related diffs\n* [#3045](https://github.com/moment/moment/pull/3045) Fix mistaking any input for 'a' token\n* [#2877](https://github.com/moment/moment/pull/2877) Use explicit .valueOf() calls instead of coercion\n* [#3036](https://github.com/moment/moment/pull/3036) Year setter should keep time when DST changes\n\nPlus 3 new locales and locale fixes.\n\n### 2.12.0 [See full changelog](https://gist.github.com/ichernev/6e5bfdf8d6522fc4ac73)\n\n- Release March 7, 2016\n\n## Enhancements:\n* [#2932](https://github.com/moment/moment/pull/2932) List loaded locales\n* [#2818](https://github.com/moment/moment/pull/2818) Parse ISO-8061 duration containing both day and week values\n* [#2774](https://github.com/moment/moment/pull/2774) Implement locale inheritance and locale updating\n\n## Bugfixes:\n* [#2970](https://github.com/moment/moment/pull/2970) change add subtract to handle decimal values by rounding\n* [#2887](https://github.com/moment/moment/pull/2887) Fix toJSON casting of invalid moment\n* [#2897](https://github.com/moment/moment/pull/2897) parse string arguments for month() correctly, closes #2884\n* [#2946](https://github.com/moment/moment/pull/2946) Fix usage suggestions for min and max\n\n## New locales:\n* [#2917](https://github.com/moment/moment/pull/2917) Locale Punjabi(Gurmukhi) India format conversion\n\nAnd more\n\n### 2.11.2 (Fix ReDoS attack vector)\n\n- Release February 7, 2016\n\n* [#2939](https://github.com/moment/moment/pull/2939) use full-string match to speed up aspnet regex match\n\n### 2.11.1 [See full changelog](https://gist.github.com/ichernev/8ec3ee25b749b4cff3c2)\n\n- Release January 9, 2016\n\n## Bugfixes:\n* [#2881](https://github.com/moment/moment/pull/2881) Revert \"Merge pull request #2746 from mbad0la:develop\" Sep->Sept\n* [#2868](https://github.com/moment/moment/pull/2868) Add format and parse token Y, so it actually works\n* [#2865](https://github.com/moment/moment/pull/2865) Use typeof checks for undefined for global variables\n* [#2858](https://github.com/moment/moment/pull/2858) Fix Date mocking regression introduced in 2.11.0\n* [#2864](https://github.com/moment/moment/pull/2864) Include changelog in npm release\n* [#2830](https://github.com/moment/moment/pull/2830) dep: add grunt-cli\n* [#2869](https://github.com/moment/moment/pull/2869) Fix months parsing for some locales\n\n### 2.11.0 [See full changelog](https://gist.github.com/ichernev/6594bc29719dde6b2f66)\n\n- Release January 4, 2016\n\n* [#2624](https://github.com/moment/moment/pull/2624) Proper handling of invalid moments\n* [#2634](https://github.com/moment/moment/pull/2634) Fix strict month parsing issue in cs,ru,sk\n* [#2735](https://github.com/moment/moment/pull/2735) Reset the locale back to 'en' after defining all locales in min/locales.js\n* [#2702](https://github.com/moment/moment/pull/2702) Week rework\n* [#2746](https://github.com/moment/moment/pull/2746) Changed September Abbreviation to \"Sept\" in locale-specific english\n  files and default locale file\n* [#2646](https://github.com/moment/moment/pull/2646) Fix [#2645](https://github.com/moment/moment/pull/2645) - invalid dates pre-1970\n\n* [#2641](https://github.com/moment/moment/pull/2641) Implement basic format and comma as ms separator in ISO 8601\n* [#2665](https://github.com/moment/moment/pull/2665) Implement stricter weekday parsing\n* [#2700](https://github.com/moment/moment/pull/2700) Add [Hh]mm and [Hh]mmss formatting tokens, so you can parse 123 with\n  hmm for example\n* [#2565](https://github.com/moment/moment/pull/2565) [#2835](https://github.com/moment/moment/pull/2835) Expose arguments used for moment creation with creationData\n  (fix [#2443](https://github.com/moment/moment/pull/2443))\n* [#2648](https://github.com/moment/moment/pull/2648) fix issue [#2640](https://github.com/moment/moment/pull/2640): support instanceof operator\n* [#2709](https://github.com/moment/moment/pull/2709) Add isSameOrAfter and isSameOrBefore comparison methods\n* [#2721](https://github.com/moment/moment/pull/2721) Fix moment creation from object with strings values\n* [#2740](https://github.com/moment/moment/pull/2740) Enable 'd hh:mm:ss.sss' format for durations\n* [#2766](https://github.com/moment/moment/pull/2766) [#2833](https://github.com/moment/moment/pull/2833) Alternate Clock Source Support\n\n### 2.10.6\n\n- Release July 28, 2015\n\n[#2515](https://github.com/moment/moment/pull/2515) Fix regression introduced\nin `2.10.5` related to `moment.ISO_8601` parsing.\n\n### 2.10.5 [See full changelog](https://gist.github.com/ichernev/6ec13ac7efc396da44b2)\n\n- Release July 26, 2015\n\nImportant changes:\n* [#2357](https://github.com/moment/moment/pull/2357) Improve unit bubbling for ISO dates\n  this fixes day to year conversions to work around end-of-year (~365 days). As\n  a side effect 365 days is 11 months and 30 days, and 366 days is one year.\n* [#2438](https://github.com/moment/moment/pull/2438) Fix inconsistent moment.min and moment.max results\n  Return invalid result if any of the inputs is invalid\n* [#2494](https://github.com/moment/moment/pull/2494) Fix two digit year parsing with YYYY format\n  This brings the benefits of YY to YYYY\n* [#2368](https://github.com/moment/moment/pull/2368) perf: use faster form of copying dates, across the board improvement\n\n\n### 2.10.3 [See full changelog](https://gist.github.com/ichernev/f264b9bed5b00f8b1b7f)\n\n- Release May 13, 2015\n\n* add `moment.fn.to` and `moment.fn.toNow` (similar to `from` and `fromNow`)\n* new locales (Sinhalese (si), Montenegrin (me), Javanese (ja))\n* performance improvements\n\n### 2.10.2\n\n- Release April 9, 2015\n\n* fixed moment-with-locales in browser env caused by esperanto change\n\n### 2.10.1\n\n* regression: Add moment.duration.fn back\n\n### 2.10.0\n\nPorted code to es6 modules.\n\n### 2.9.0 [See full changelog](https://gist.github.com/ichernev/0c9a9b49951111a27ce7)\n\n- Release January 8, 2015\n\nlanguages:\n* [2104](https://github.com/moment/moment/issues/2104) Frisian (fy) language file with unit test\n* [2097](https://github.com/moment/moment/issues/2097) add ar-tn locale\n\ndeprecations:\n* [2074](https://github.com/moment/moment/issues/2074) Implement `moment.fn.utcOffset`, deprecate `moment.fn.zone`\n\nfeatures:\n* [2088](https://github.com/moment/moment/issues/2088) add moment.fn.isBetween\n* [2054](https://github.com/moment/moment/issues/2054) Call updateOffset when creating moment (needed for default timezone in\n  moment-timezone)\n* [1893](https://github.com/moment/moment/issues/1893) Add moment.isDate method\n* [1825](https://github.com/moment/moment/issues/1825) Implement toJSON function on Duration\n* [1809](https://github.com/moment/moment/issues/1809) Allowing moment.set() to accept a hash of units\n* [2128](https://github.com/moment/moment/issues/2128) Add firstDayOfWeek, firstDayOfYear locale getters\n* [2131](https://github.com/moment/moment/issues/2131) Add quarter diff support\n\nSome bugfixes and language improvements -- [full changelog](https://gist.github.com/ichernev/0c9a9b49951111a27ce7)\n\n### 2.8.4 [See full changelog](https://gist.github.com/ichernev/a4fcb0a46d74e4b9b996)\n\n- Release November 19, 2014\n\nFeatures:\n\n* [#2000](https://github.com/moment/moment/issues/2000) Add LTS localised format that includes seconds\n* [#1960](https://github.com/moment/moment/issues/1960) added formatToken 'x' for unix offset in milliseconds #1938\n* [#1965](https://github.com/moment/moment/issues/1965) Support 24:00:00.000 to mean next day, at midnight.\n* [#2002](https://github.com/moment/moment/issues/2002) Accept 'date' key when creating moment with object\n* [#2009](https://github.com/moment/moment/issues/2009) Use native toISOString when we can\n\nSome bugfixes and language improvements -- [full changelog](https://gist.github.com/ichernev/a4fcb0a46d74e4b9b996)\n\n### 2.8.3\n\n- Release September 5, 2014\n\nBugfixes:\n\n* [#1801](https://github.com/moment/moment/issues/1801) proper pluralization for Arabic\n* [#1833](https://github.com/moment/moment/issues/1833) improve spm integration\n* [#1871](https://github.com/moment/moment/issues/1871) fix zone bug caused by Firefox 24\n* [#1882](https://github.com/moment/moment/issues/1882) Use hh:mm in Czech\n* [#1883](https://github.com/moment/moment/issues/1883) Fix 2.8.0 regression in duration as conversions\n* [#1890](https://github.com/moment/moment/issues/1890) Faster travis builds\n* [#1892](https://github.com/moment/moment/issues/1892) Faster isBefore/After/Same\n* [#1848](https://github.com/moment/moment/issues/1848) Fix flaky month diffs\n* [#1895](https://github.com/moment/moment/issues/1895) Fix 2.8.0 regression in moment.utc with format array\n* [#1896](https://github.com/moment/moment/issues/1896) Support setting invalid instance locale (noop)\n* [#1897](https://github.com/moment/moment/issues/1897) Support moment([str]) in addition to moment([int])\n\n### 2.8.2\n\n- Release August 22, 2014\n\nMinor bugfixes:\n\n* [#1874](https://github.com/moment/moment/issues/1874) use `Object.prototype.hasOwnProperty`\n  instead of `obj.hasOwnProperty` (ie8 bug)\n* [#1873](https://github.com/moment/moment/issues/1873) add `duration#toString()`\n* [#1859](https://github.com/moment/moment/issues/1859) better month/weekday names in norwegian\n* [#1812](https://github.com/moment/moment/issues/1812) meridiem parsing for greek\n* [#1804](https://github.com/moment/moment/issues/1804) spanish del -> de\n* [#1800](https://github.com/moment/moment/issues/1800) korean LT improvement\n\n### 2.8.1\n\n- Release August 1, 2014\n\n* bugfix [#1813](https://github.com/moment/moment/issues/1813): fix moment().lang([key]) incompatibility\n\n### 2.8.0 [See changelog](https://gist.github.com/ichernev/ac3899324a5fa6c8c9b4)\n\n- Release July 31, 2014\n\n* incompatible changes\n    * [#1761](https://github.com/moment/moment/issues/1761): moments created without a language are no longer following the global language, in case it changes. Only newly created moments take the global language by default. In case you're affected by this, wait, comment on [#1797](https://github.com/moment/moment/issues/1797) and wait for a proper reimplementation\n    * [#1642](https://github.com/moment/moment/issues/1642): 45 days is no longer \"a month\" according to humanize, cutoffs for month, and year have changed. Hopefully your code does not depend on a particular answer from humanize (which it shouldn't anyway)\n    * [#1784](https://github.com/moment/moment/issues/1784): if you use the human readable English datetime format in a weird way (like storing them in a database) that would break when the format changes you're at risk.\n\n* deprecations (old behavior will be dropped in 3.0)\n    * [#1761](https://github.com/moment/moment/issues/1761) `lang` is renamed to `locale`, `langData` -> `localeData`. Also there is now `defineLocale` that should be used when creating new locales\n    * [#1763](https://github.com/moment/moment/issues/1763) `add(unit, value)` and `subtract(unit, value)` are now deprecated. Use `add(value, unit)` and `subtract(value, unit)` instead.\n    * [#1759](https://github.com/moment/moment/issues/1759) rename `duration.toIsoString` to `duration.toISOString`. The js standard library and moment's `toISOString` follow that convention.\n\n* new locales\n    * [#1789](https://github.com/moment/moment/issues/1789) Tibetan (bo)\n    * [#1786](https://github.com/moment/moment/issues/1786) Africaans (af)\n    * [#1778](https://github.com/moment/moment/issues/1778) Burmese (my)\n    * [#1727](https://github.com/moment/moment/issues/1727) Belarusian (be)\n\n* bugfixes, locale bugfixes, performance improvements, features\n\n### 2.7.0 [See changelog](https://gist.github.com/ichernev/b0a3d456d5a84c9901d7)\n\n- Release June 12, 2014\n\n* new languages\n\n  * [#1678](https://github.com/moment/moment/issues/1678) Bengali (bn)\n  * [#1628](https://github.com/moment/moment/issues/1628) Azerbaijani (az)\n  * [#1633](https://github.com/moment/moment/issues/1633) Arabic, Saudi Arabia (ar-sa)\n  * [#1648](https://github.com/moment/moment/issues/1648) Austrian German (de-at)\n\n* features\n\n  * [#1663](https://github.com/moment/moment/issues/1663) configurable relative time thresholds\n  * [#1554](https://github.com/moment/moment/issues/1554) support anchor time in moment.calendar\n  * [#1693](https://github.com/moment/moment/issues/1693) support moment.ISO_8601 as parsing format\n  * [#1637](https://github.com/moment/moment/issues/1637) add moment.min and moment.max and deprecate min/max instance methods\n  * [#1704](https://github.com/moment/moment/issues/1704) support string value in add/subtract\n  * [#1647](https://github.com/moment/moment/issues/1647) add spm support (package manager)\n\n* bugfixes\n\n### 2.6.0 [See changelog](https://gist.github.com/ichernev/10544682)\n\n- Release April 12 , 2014\n\n* languages\n  * [#1529](https://github.com/moment/moment/issues/1529) Serbian-Cyrillic (sr-cyr)\n  * [#1544](https://github.com/moment/moment/issues/1544), [#1546](https://github.com/moment/moment/issues/1546) Khmer Cambodia (km)\n\n* features\n    * [#1419](https://github.com/moment/moment/issues/1419), [#1468](https://github.com/moment/moment/issues/1468), [#1467](https://github.com/moment/moment/issues/1467), [#1546](https://github.com/moment/moment/issues/1546) better handling of timezone-d moments around DST\n    * [#1462](https://github.com/moment/moment/issues/1462) add weeksInYear and isoWeeksInYear\n    * [#1475](https://github.com/moment/moment/issues/1475) support ordinal parsing\n    * [#1499](https://github.com/moment/moment/issues/1499) composer support\n    * [#1577](https://github.com/moment/moment/issues/1577), [#1604](https://github.com/moment/moment/issues/1604) put Date parsing in moment.createFromInputFallback so it can be properly deprecated and controlled in the future\n    * [#1545](https://github.com/moment/moment/issues/1545) extract two-digit year parsing in moment.parseTwoDigitYear, so it can be overwritten\n    * [#1590](https://github.com/moment/moment/issues/1590) (see [#1574](https://github.com/moment/moment/issues/1574)) set AMD global before module definition to better support non AMD module dependencies used in AMD environment\n    * [#1589](https://github.com/moment/moment/issues/1589) remove global in Node.JS environment (was not working before, nobody complained, was scheduled for removal anyway)\n    * [#1586](https://github.com/moment/moment/issues/1586) support quarter setting and parsing\n\n* 18 bugs fixed\n\n### 2.5.1\n\n- Release January 22, 2014\n\n* languages\n  * [#1392](https://github.com/moment/moment/issues/1392) Armenian (hy-am)\n\n* bugfixes\n  * [#1429](https://github.com/moment/moment/issues/1429) fixes [#1423](https://github.com/moment/moment/issues/1423) weird chrome-32 bug with js object creation\n  * [#1421](https://github.com/moment/moment/issues/1421) remove html entities from Welsh\n  * [#1418](https://github.com/moment/moment/issues/1418) fixes [#1401](https://github.com/moment/moment/issues/1401) improved non-padded tokens in strict matching\n  * [#1417](https://github.com/moment/moment/issues/1417) fixes [#1404](https://github.com/moment/moment/issues/1404) handle buggy moment object created by property cloning\n  * [#1398](https://github.com/moment/moment/issues/1398) fixes [#1397](https://github.com/moment/moment/issues/1397) fix Arabic-like week number parsing\n  * [#1396](https://github.com/moment/moment/issues/1396) add leftZeroFill(4) to GGGG and gggg formats\n  * [#1373](https://github.com/moment/moment/issues/1373) use lowercase for months and days in Catalan\n\n* testing\n  * [#1374](https://github.com/moment/moment/issues/1374) run tests on multiple browser/os combos via SauceLabs and Travis\n\n### 2.5.0 [See changelog](https://gist.github.com/ichernev/8104451)\n\n- Release Dec 24, 2013\n\n* New languages\n  * Luxemburish (lb) [1247](https://github.com/moment/moment/issues/1247)\n  * Serbian (rs) [1319](https://github.com/moment/moment/issues/1319)\n  * Tamil (ta) [1324](https://github.com/moment/moment/issues/1324)\n  * Macedonian (mk) [1337](https://github.com/moment/moment/issues/1337)\n\n* Features\n  * [1311](https://github.com/moment/moment/issues/1311) Add quarter getter and format token `Q`\n  * [1303](https://github.com/moment/moment/issues/1303) strict parsing now respects number of digits per token (fix [1196](https://github.com/moment/moment/issues/1196))\n  * 0d30bb7 add jspm support\n  * [1347](https://github.com/moment/moment/issues/1347) improve zone parsing\n  * [1362](https://github.com/moment/moment/issues/1362) support merideam parsing in Korean\n\n* 22 bugfixes\n\n### 2.4.0\n\n- Release Oct 27, 2013\n\n* **Deprecate** globally exported moment, will be removed in next major\n* New languages\n  * Farose (fo) [#1206](https://github.com/moment/moment/issues/1206)\n  * Tagalog/Filipino (tl-ph) [#1197](https://github.com/moment/moment/issues/1197)\n  * Welsh (cy) [#1215](https://github.com/moment/moment/issues/1215)\n* Bugfixes\n  * properly handle Z at the end of iso RegExp [#1187](https://github.com/moment/moment/issues/1187)\n  * chinese meridian time improvements [#1076](https://github.com/moment/moment/issues/1076)\n  * fix language tests [#1177](https://github.com/moment/moment/issues/1177)\n  * remove some failing tests (that should have never existed :))\n    [#1185](https://github.com/moment/moment/issues/1185)\n    [#1183](https://github.com/moment/moment/issues/1183)\n  * handle russian noun cases in weird cases [#1195](https://github.com/moment/moment/issues/1195)\n\n### 2.3.1\n\n- Release Oct 9, 2013\n\nRemoved a trailing comma [1169] and fixed a bug with `months`, `weekdays` getters [#1171](https://github.com/moment/moment/issues/1171).\n\n### 2.3.0 [See changelog](https://gist.github.com/ichernev/6864354)\n\n- Release Oct 7, 2013\n\nChanged isValid, added strict parsing.\nWeek tokens parsing.\n\n### 2.2.1\n\n- Release Sep 12, 2013\n\nFixed bug in string prototype test.\nUpdated authors and contributors.\n\n### 2.2.0 [See changelog](https://gist.github.com/ichernev/00f837a9baf46a3565e4)\n\n- Release  Sep 11, 2013\n\nAdded bower support.\n\nLanguage files now use UMD.\n\nCreating moment defaults to current date/month/year.\n\nAdded a bundle of moment and all language files.\n\n### 2.1.0 [See changelog](https://gist.github.com/timrwood/b8c2d90d528eddb53ab5)\n\n- Release Jul 8, 2013\n\nAdded better week support.\n\nAdded ability to set offset with `moment#zone`.\n\nAdded ability to set month or weekday from a string.\n\nAdded `moment#min` and `moment#max`\n\n### 2.0.0 [See changelog](https://gist.github.com/timrwood/e72f2eef320ed9e37c51)\n\n- Release Feb 9, 2013\n\nAdded short form localized tokens.\n\nAdded ability to define language a string should be parsed in.\n\nAdded support for reversed add/subtract arguments.\n\nAdded support for `endOf('week')` and `startOf('week')`.\n\nFixed the logic for `moment#diff(Moment, 'months')` and `moment#diff(Moment, 'years')`\n\n`moment#diff` now floors instead of rounds.\n\nNormalized `moment#toString`.\n\nAdded `isSame`, `isAfter`, and `isBefore` methods.\n\nAdded better week support.\n\nAdded `moment#toJSON`\n\nBugfix: Fixed parsing of first century dates\n\nBugfix: Parsing 10Sep2001 should work as expected\n\nBugfix: Fixed weirdness with `moment.utc()` parsing.\n\nChanged language ordinal method to return the number + ordinal instead of just the ordinal.\n\nChanged two digit year parsing cutoff to match strptime.\n\nRemoved `moment#sod` and `moment#eod` in favor of `moment#startOf` and `moment#endOf`.\n\nRemoved `moment.humanizeDuration()` in favor of `moment.duration().humanize()`.\n\nRemoved the lang data objects from the top level namespace.\n\nDuplicate `Date` passed to `moment()` instead of referencing it.\n\n### 1.7.2 [See discussion](https://github.com/timrwood/moment/issues/456)\n\n- Release Oct 2, 2012\n\nBugfixes\n\n### 1.7.1 [See discussion](https://github.com/timrwood/moment/issues/384)\n\n- Release Oct 1, 2012\n\nBugfixes\n\n### 1.7.0 [See discussion](https://github.com/timrwood/moment/issues/288)\n\n- Release Jul 26, 2012\n\nAdded `moment.fn.endOf()` and `moment.fn.startOf()`.\n\nAdded validation via `moment.fn.isValid()`.\n\nMade formatting method 3x faster. http://jsperf.com/momentjs-cached-format-functions\n\nAdd support for month/weekday callbacks in `moment.fn.format()`\n\nAdded instance specific languages.\n\nAdded two letter weekday abbreviations with the formatting token `dd`.\n\nVarious language updates.\n\nVarious bugfixes.\n\n### 1.6.0 [See discussion](https://github.com/timrwood/moment/pull/268)\n\n- Release Apr 26, 2012\n\nAdded Durations.\n\nRevamped parser to support parsing non-separated strings (YYYYMMDD vs YYYY-MM-DD).\n\nAdded support for millisecond parsing and formatting tokens (S SS SSS)\n\nAdded a getter for `moment.lang()`\n\nVarious bugfixes.\n\nThere are a few things deprecated in the 1.6.0 release.\n\n1. The format tokens `z` and `zz` (timezone abbreviations like EST CST MST etc) will no longer be supported. Due to inconsistent browser support, we are unable to consistently produce this value. See [this issue](https://github.com/timrwood/moment/issues/162) for more background.\n\n2. The method `moment.fn.native` is deprecated in favor of `moment.fn.toDate`. There continue to be issues with Google Closure Compiler throwing errors when using `native`, even in valid instances.\n\n3. The way to customize am/pm strings is being changed. This would only affect you if you created a custom language file. For more information, see [this issue](https://github.com/timrwood/moment/pull/222).\n\n### 1.5.0 [See milestone](https://github.com/timrwood/moment/issues?milestone=10&page=1&state=closed)\n\n- Release Mar 20, 2012\n\nAdded UTC mode.\n\nAdded automatic ISO8601 parsing.\n\nVarious bugfixes.\n\n### 1.4.0 [See milestone](https://github.com/timrwood/moment/issues?milestone=8&state=closed)\n\n- Release Feb 4, 2012\n\nAdded `moment.fn.toDate` as a replacement for `moment.fn.native`.\n\nAdded `moment.fn.sod` and `moment.fn.eod` to get the start and end of day.\n\nVarious bugfixes.\n\n### 1.3.0 [See milestone](https://github.com/timrwood/moment/issues?milestone=7&state=closed)\n\n- Release Jan 5, 2012\n\nAdded support for parsing month names in the current language.\n\nAdded escape blocks for parsing tokens.\n\nAdded `moment.fn.calendar` to format strings like 'Today 2:30 PM', 'Tomorrow 1:25 AM', and 'Last Sunday 4:30 AM'.\n\nAdded `moment.fn.day` as a setter.\n\nVarious bugfixes\n\n### 1.2.0 [See milestone](https://github.com/timrwood/moment/issues?milestone=4&state=closed)\n\n- Release Dec 7, 2011\n\nAdded timezones to parser and formatter.\n\nAdded `moment.fn.isDST`.\n\nAdded `moment.fn.zone` to get the timezone offset in minutes.\n\n### 1.1.2 [See milestone](https://github.com/timrwood/moment/issues?milestone=6&state=closed)\n\n- Release Nov 18, 2011\n\nVarious bugfixes\n\n### 1.1.1 [See milestone](https://github.com/timrwood/moment/issues?milestone=5&state=closed)\n\n- Release Nov 12, 2011\n\nAdded time specific diffs (months, days, hours, etc)\n\n### 1.1.0\n\n- Release Oct 28, 2011\n\nAdded `moment.fn.format` localized masks. 'L LL LLL LLLL' [issue 29](https://github.com/timrwood/moment/pull/29)\n\nFixed [issue 31](https://github.com/timrwood/moment/pull/31).\n\n### 1.0.1\n\n- Release Oct 18, 2011\n\nAdded `moment.version` to get the current version.\n\nRemoved `window !== undefined` when checking if module exists to support browserify. [issue 25](https://github.com/timrwood/moment/pull/25)\n\n### 1.0.0\n\n- Release\n\nAdded convenience methods for getting and setting date parts.\n\nAdded better support for `moment.add()`.\n\nAdded better lang support in NodeJS.\n\nRenamed library from underscore.date to Moment.js\n\n### 0.6.1\n\n- Release Oct 12, 2011\n\nAdded Portuguese, Italian, and French language support\n\n### 0.6.0\n\n- Release Sep 21, 2011\n\nAdded _date.lang() support.\nAdded support for passing multiple formats to try to parse a date. _date(\"07-10-1986\", [\"MM-DD-YYYY\", \"YYYY-MM-DD\"]);\nMade parse from string and single format 25% faster.\n\n### 0.5.2\n\n- Release Jul 11, 2011\n\nBugfix for [issue 8](https://github.com/timrwood/underscore.date/pull/8) and [issue 9](https://github.com/timrwood/underscore.date/pull/9).\n\n### 0.5.1\n\n- Release Jun 17, 2011\n\nBugfix for [issue 5](https://github.com/timrwood/underscore.date/pull/5).\n\n### 0.5.0\n\n- Release Jun 13, 2011\n\nDropped the redundant `_date.date()` in favor of `_date()`.\nRemoved `_date.now()`, as it is a duplicate of `_date()` with no parameters.\nRemoved `_date.isLeapYear(yearNumber)`. Use `_date([yearNumber]).isLeapYear()` instead.\nExposed customization options through the `_date.relativeTime`, `_date.weekdays`, `_date.weekdaysShort`, `_date.months`, `_date.monthsShort`, and `_date.ordinal` variables instead of the `_date.customize()` function.\n\n### 0.4.1\n\n- Release May 9, 2011\n\nAdded date input formats for input strings.\n\n### 0.4.0\n\n- Release May 9, 2011\n\nAdded underscore.date to npm. Removed dependencies on underscore.\n\n### 0.3.2\n\n- Release Apr 9, 2011\n\nAdded `'z'` and `'zz'` to `_.date().format()`. Cleaned up some redundant code to trim off some bytes.\n\n### 0.3.1\n\n- Release Mar 25, 2011\n\nCleaned up the namespace. Moved all date manipulation and display functions to the _.date() object.\n\n### 0.3.0\n\n- Release Mar 25, 2011\n\nSwitched to the Underscore methodology of not mucking with the native objects' prototypes.\nMade chaining possible.\n\n### 0.2.1\n\n- Release\n\nChanged date names to be a more pseudo standardized 'dddd, MMMM Do YYYY, h:mm:ss a'.\nAdded `Date.prototype` functions `add`, `subtract`, `isdst`, and `isleapyear`.\n\n### 0.2.0\n\n- Release\n\nChanged function names to be more concise.\nChanged date format from php date format to custom format.\n\n### 0.1.0\n\n- Release\n\nInitial release\n\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/CONTRIBUTING.md",
    "content": "Submitting Issues\n=================\n\nIf you are submitting a bug, please create a [jsfiddle](http://jsfiddle.net/) demonstrating the issue.\n\nRead before submitting Pull Requests\n====================================\n\n * **Pull requests to the `master` branch will be closed.** Please submit all pull requests to the `develop` branch.\n * **You will be required to sign a JS Foundation CLA before your pull request can be merged.** [Sign it right now](https://cla.js.foundation/moment/moment).\n * **Locale translations will not be merged without unit tests.** See [the British English unit tests](https://github.com/moment/moment/blob/develop/src/test/locale/en-gb.js) for an example.\n * **Do not include the minified files in your pull request.** These are\n   `moment.js`, `locale/*.js`, `min/*.js`. Don't worry, we'll build them when\n   we cut a release.\n\nCode organization\n=================\n\nStarting from version 2.10.0 the code is placed under `src/`.\n`moment.js`, `locale/*.js`, `min/*.js` are generated only on release.\n\n**DO NOT** submit changes to the generated files. Instead only change\n`src/**/*.js` and run the tests.\n\n* `src/lib/**/*.js` moment core files\n* `src/locale/*.js` locale files\n* `src/test/moment/*.js` moment core tests\n* `src/test/locale/*.js` locale tests\n\nWe're using ES6 module system, but nothing else ES6, because of performance\nconsiderations (added code by the transpiler, less than optimal translation to\nES5). So please do not use that fancy new ES6 feature in your patch, it won't\nbe accepted.\n\nSetting up development environment\n==================================\n\nTo contribute, fork the library and install grunt and dependencies. You need\n[git](http://git-scm.com/) and\n[node](http://nodejs.org/); you might use\n[nvm](https://github.com/creationix/nvm) or\n[nenv](https://github.com/ryuone/nenv) to install node.\n\n```bash\ngit clone https://github.com/moment/moment.git\ncd moment\nnpm install -g grunt-cli\nnpm install\ngit checkout develop  # all patches against develop branch, please!\ngrunt                 # this runs tests and jshint\n```\n\nChanging locale files\n=====================\n\nIf you have any changes to existing locale files, `@mention` the original\nauthor in the pull request (check the top of the language file), and ask if\nhe/she approves of your changes. Because I don't know any languages I can't\njudge your locale changes, only the original author can :)\n\nIn order for your pull request to get merged it must have approval of original\nauthor, or at least one other native speaker has to approve of the change\n(happens rarely).\n\nGrunt tasks\n===========\n\nWe use Grunt for managing the build. Here are some useful Grunt tasks:\n\n  * `grunt` The default task lints the code and runs the tests. You should make sure you do this before submitting a PR.\n  * `grunt test` run the tests.\n  * `grunt release` Build everything, including minified files (do not include\n    those in Pull Requests)\n  * `grunt transpile:fr,ru` Build custom locale bundles `moment-with-locales.custom.js` and `locales.custom.js` inside `build/umd/min` containing just French and Russian.\n  * `grunt size` Print size statistics.\n\nBecoming a moment team member\n=============================\n\nMoment's team members have extra powers and responsibilities. If you want to\nbecome one -- be active in our repositories by answering issues, reviewing PRs,\ndiscussing changes, submitting PRs for open bugs. Any help on\n[moment/moment](https://github.com/moment/moment),\n[moment/momentjs.com](https://github.com/moment/momentjs.com),\n[moment/moment-timezone](https://github.com/moment/moment-timezone) will be\nnoticed.\n\nOnce you've proven to be trustworthy, submit your request to the\n[gitter chat](https://gitter.im/moment/moment), and it will be reviewed by the\nexisting team.\n\nOnce you become a member:\n* you can tell your friends\n* you can close issues submitted by others\n\nBut also:\n* be active in the repositories\n* pick up work nobody else wants to\n* attend a monthly meeting\n* participate in the internal slack group\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/Gruntfile.js",
    "content": "module.exports = function (grunt) {\n    grunt.initConfig({\n        pkg: grunt.file.readJSON('package.json'),\n        env : {\n            sauceLabs : (grunt.file.exists('.sauce-labs.creds') ?\n                    grunt.file.readJSON('.sauce-labs.creds') : {})\n        },\n        karma : {\n            options: {\n                browserNoActivityTimeout: 60000,\n                browserDisconnectTimeout: 10000,\n                browserDisconnectTolerance: 2,\n                frameworks: ['qunit'],\n                files: [\n                    'min/moment-with-locales.js',\n                    'min/tests.js'\n                ],\n                sauceLabs: {\n                    startConnect: true,\n                    testName: 'MomentJS'\n                },\n                customLaunchers: {\n                    slChromeWinXp: {\n                        base: 'SauceLabs',\n                        browserName: 'chrome',\n                        platform: 'Windows XP'\n                    },\n                    slIe10Win7: {\n                        base: 'SauceLabs',\n                        browserName: 'internet explorer',\n                        platform: 'Windows 7',\n                        version: '10'\n                    },\n                    slIe9Win7: {\n                        base: 'SauceLabs',\n                        browserName: 'internet explorer',\n                        platform: 'Windows 7',\n                        version: '9'\n                    },\n                    slIe8Win7: {\n                        base: 'SauceLabs',\n                        browserName: 'internet explorer',\n                        platform: 'Windows 7',\n                        version: '8'\n                    },\n                    slIe11Win10: {\n                        base: 'SauceLabs',\n                        browserName: 'internet explorer',\n                        platform: 'Windows 10',\n                        version: '11'\n                    },\n                    slME25Win10: {\n                        base: 'SauceLabs',\n                        browserName: 'MicrosoftEdge',\n                        platform: 'Windows 10',\n                        version: '20.10240'\n                    },\n                    slFfLinux: {\n                        base: 'SauceLabs',\n                        browserName: 'firefox',\n                        platform: 'Linux'\n                    },\n                    slSafariOsx: {\n                        base: 'SauceLabs',\n                        browserName: 'safari',\n                        platform: 'OS X 10.8'\n                    },\n                    slSafariOsx11: {\n                        base: 'SauceLabs',\n                        browserName: 'safari',\n                        platform: 'OS X 10.11'\n                    }\n                }\n            },\n            server: {\n                browsers: []\n            },\n            chrome: {\n                singleRun: true,\n                browsers: ['Chrome']\n            },\n            firefox: {\n                singleRun: true,\n                browsers: ['Firefox']\n            },\n            sauce: {\n                options: {\n                    reporters: ['dots']\n                },\n                singleRun: true,\n                browsers: [\n                    'slChromeWinXp',\n                    'slIe10Win7',\n                    'slIe9Win7',\n                    'slIe8Win7',\n                    'slIe11Win10',\n                    'slME25Win10',\n                    'slFfLinux',\n                    'slSafariOsx'\n                ]\n            }\n        },\n        uglify : {\n            main: {\n                files: {\n                    'min/moment-with-locales.min.js'     : 'min/moment-with-locales.js',\n                    'min/locales.min.js'                 : 'min/locales.js',\n                    'min/moment.min.js'                  : 'moment.js'\n                }\n            },\n            options: {\n                mangle: true,\n                compress: {\n                    dead_code: false // jshint ignore:line\n                },\n                output: {\n                    ascii_only: true // jshint ignore:line\n                },\n                report: 'min',\n                preserveComments: /^!|@preserve|@license|@cc_on/i\n            }\n        },\n        jshint: {\n            all: [\n                'Gruntfile.js',\n                'tasks/**.js',\n                'src/**/*.js'\n            ],\n            options: {\n                jshintrc: true\n            }\n        },\n        jscs: {\n            all: [\n                'Gruntfile.js',\n                'tasks/**.js',\n                'src/**/*.js'\n            ],\n            options: {\n                config: '.jscs.json'\n            }\n        },\n        watch : {\n            test : {\n                files : [\n                    'src/**/*.js'\n                ],\n                tasks: ['test']\n            },\n            jshint : {\n                files : '<%= jshint.all %>',\n                tasks: ['jshint']\n            }\n        },\n        benchmark: {\n            all: {\n                src: ['benchmarks/*.js']\n            }\n        },\n        exec: {\n            'meteor-init': {\n                // Make sure Meteor is installed, per https://meteor.com/install.\n                // The curl'ed script is safe; takes 2 minutes to read source & check.\n                command: 'type meteor >/dev/null 2>&1 || { curl https://install.meteor.com/ | sh; }'\n            },\n            'meteor-test': {\n                command: 'spacejam --mongo-url mongodb:// test-packages ./meteor'\n            },\n            'meteor-publish': {\n                command: 'cd meteor && meteor publish'\n            },\n            'typescript-test': {\n                command: 'npm run typescript-test'\n            }\n        }\n\n    });\n\n    grunt.loadTasks('tasks');\n\n    // These plugins provide necessary tasks.\n    require('load-grunt-tasks')(grunt);\n\n    // Default task.\n    grunt.registerTask('default', ['lint', 'test']);\n\n    // linting\n    grunt.registerTask('lint', ['jshint', 'jscs']);\n\n    // test tasks\n    grunt.registerTask('test', ['test:node', 'test:typescript']);\n    grunt.registerTask('test:node', ['transpile', 'qtest']);\n    grunt.registerTask('test:typescript', ['exec:typescript-test']);\n    // TODO: For some weird reason karma doesn't like the files in\n    // build/umd/min/* but works with min/*, so update-index, then git checkout\n    grunt.registerTask('test:server', ['transpile', 'update-index', 'karma:server']);\n    grunt.registerTask('test:browser', ['transpile', 'update-index', 'karma:chrome', 'karma:firefox']);\n    grunt.registerTask('test:sauce-browser', ['transpile', 'update-index', 'env:sauceLabs', 'karma:sauce']);\n    grunt.registerTask('test:meteor', ['exec:meteor-init', 'exec:meteor-test', 'exec:meteor-cleanup']);\n\n    // travis build task\n    grunt.registerTask('build:travis', ['default']);\n    grunt.registerTask('meteor-publish', ['exec:meteor-init', 'exec:meteor-publish', 'exec:meteor-cleanup']);\n\n    // Task to be run when releasing a new version\n    grunt.registerTask('release', [\n        'default',\n        'update-index',\n        'component',\n        'uglify:main'\n    ]);\n};\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/ISSUE_TEMPLATE.md",
    "content": "**Description of the Issue and Steps to Reproduce:**\n\n*Please include the values of all variables used.*\n\n**Environment:**\n\n*Examples: Chrome 49 on OSX, Internet Explorer 10 on Windows 7, Node.JS 4.4.4 on Ubuntu 16.0.4*\n\n*Both the browser and the OS are important to us, particularly if you have an unsual environment like an IOT application.*\n\n**Other information that may be helpful:**\n* The time zone setting of the machine the code is running on\n* The time and date at which the code was run\n* Other libraries in use (TypeScript, Immutable.js, etc)\n\nIf you are reporting an issue, please run the following code in the environment you are using and include the output:\n```js\nconsole.log( (new Date()).toString())\nconsole.log((new Date()).toLocaleString())\nconsole.log( (new Date()).getTimezoneOffset())\nconsole.log( navigator.userAgent)\nconsole.log(moment.version)\n```\n\n*Ensure your issue is isolated to moment. Issues involving third party tools will be closed unless submitted by the tool's author/maintainer.*"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/LICENSE",
    "content": "Copyright (c) JS Foundation and other contributors\n\nPermission is hereby granted, free of charge, to any person\nobtaining a copy of this software and associated documentation\nfiles (the \"Software\"), to deal in the Software without\nrestriction, including without limitation the rights to use,\ncopy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the\nSoftware is furnished to do so, subject to the following\nconditions:\n\nThe above copyright notice and this permission notice shall be\nincluded in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\nEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES\nOF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\nNONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT\nHOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,\nWHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\nFROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR\nOTHER DEALINGS IN THE SOFTWARE.\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/Moment.js.nuspec",
    "content": "<?xml version=\"1.0\"?>\r\n<package xmlns=\"http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd\">\r\n    <metadata>\r\n        <id>Moment.js</id>\r\n        <version>2.18.1</version>\r\n        <authors>Tim Wood, Iskren Chernev, Moment.js contributors</authors>\r\n        <owners>Cory Deppen, Iskren Chernev</owners>\r\n        <description>A lightweight JavaScript date library for parsing, manipulating, and formatting dates.</description>\r\n        <releaseNotes>\r\n            * Release Mar 22, 2017\r\n            * [#3853](https://github.com/moment/moment/pull/3853) [misc] Fix invalid whitespace character causing inability to parse\r\n              moment.js\r\n        </releaseNotes>\r\n        <projectUrl>http://momentjs.com/</projectUrl>\r\n        <iconUrl>http://pbs.twimg.com/profile_images/482670411402858496/Xrtdc94q_normal.png</iconUrl>\r\n        <licenseUrl>https://raw.github.com/timrwood/moment/master/LICENSE</licenseUrl>\r\n        <tags>JavaScript date time browser node.js</tags>\r\n  </metadata>\r\n  <files>\r\n      <file src=\"moment.js\" target=\"Content\\Scripts\" />\r\n      <file src=\"min/moment.min.js\" target=\"Content\\Scripts\" />\r\n      <file src=\"min/moment-with-locales.js\" target=\"Content\\Scripts\" />\r\n      <file src=\"min/moment-with-locales.min.js\" target=\"Content\\Scripts\" />\r\n  </files>\r\n</package>\r\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/README.md",
    "content": "[![Join the chat at https://gitter.im/moment/moment](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/moment/moment?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)\n\n[![NPM version][npm-version-image]][npm-url] [![NPM downloads][npm-downloads-image]][npm-url] [![MIT License][license-image]][license-url] [![Build Status][travis-image]][travis-url]\n[![Coverage Status](https://coveralls.io/repos/moment/moment/badge.svg?branch=develop)](https://coveralls.io/r/moment/moment?branch=develop)\n\nA lightweight JavaScript date library for parsing, validating, manipulating, and formatting dates.\n\n**[Documentation](http://momentjs.com/docs/)**\n\n## Port to ECMAScript 6 (version 2.10.0)\n\nMoment 2.10.0 does not bring any new features, but the code is now written in\nECMAScript 6 modules and placed inside `src/`. Previously `moment.js`, `locale/*.js` and\n`test/moment/*.js`, `test/locale/*.js` contained the source of the project. Now\nthe source is in `src/`, temporary build (ECMAScript 5) files are placed under\n`build/umd/` (for running tests during development), and the `moment.js` and\n`locale/*.js` files are updated only on release.\n\nIf you want to use a particular revision of the code, make sure to run\n`grunt transpile update-index`, so `moment.js` and `locales/*.js` are synced\nwith `src/*`. We might place that in a commit hook in the future.\n\n## Upgrading to 2.0.0\n\nThere are a number of small backwards incompatible changes with version 2.0.0. [See the full descriptions here](https://gist.github.com/timrwood/e72f2eef320ed9e37c51#backwards-incompatible-changes)\n\n * Changed language ordinal method to return the number + ordinal instead of just the ordinal.\n\n * Changed two digit year parsing cutoff to match strptime.\n\n * Removed `moment#sod` and `moment#eod` in favor of `moment#startOf` and `moment#endOf`.\n\n * Removed `moment.humanizeDuration()` in favor of `moment.duration().humanize()`.\n\n * Removed the lang data objects from the top level namespace.\n\n * Duplicate `Date` passed to `moment()` instead of referencing it.\n\n## [Changelog](https://github.com/moment/moment/blob/develop/CHANGELOG.md)\n\n## [Contributing](https://github.com/moment/moment/blob/develop/CONTRIBUTING.md)\n\nWe're looking for co-maintainers! If you want to become a master of time please\nwrite to [ichernev](https://github.com/ichernev).\n\n## License\n\nMoment.js is freely distributable under the terms of the [MIT license](https://github.com/moment/moment/blob/develop/LICENSE).\n\n[license-image]: http://img.shields.io/badge/license-MIT-blue.svg?style=flat\n[license-url]: LICENSE\n\n[npm-url]: https://npmjs.org/package/moment\n[npm-version-image]: http://img.shields.io/npm/v/moment.svg?style=flat\n[npm-downloads-image]: http://img.shields.io/npm/dm/moment.svg?style=flat\n\n[travis-url]: http://travis-ci.org/moment/moment\n[travis-image]: http://img.shields.io/travis/moment/moment/develop.svg?style=flat\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/benchmarks/add.js",
    "content": "var Benchmark = require('benchmark'),\n    moment = require(\"./../moment.js\"),\n    base = moment('2013-05-25');\n\nvar unitsUnderTest = [\"milliseconds\", \"seconds\", \"minutes\", \"hours\", \"days\", \"weeks\", \"months\", \"quarters\", \"years\"];\nvar tests = unitsUnderTest.reduce(function (testsSoFar, unit) {\n    testsSoFar[\"add \" + unit] = generateTestForUnit(unit);\n    return testsSoFar;\n}, {});\n\nfunction generateTestForUnit(unit) {\n    return {\n        setup: function(){var base = base; var unit = unit;},\n        fn: function(){base.add(8, unit);},\n        async: true\n    };\n}\n\nmodule.exports = {\n    name: 'add',\n    tests: tests\n};\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/benchmarks/clone.js",
    "content": "var Benchmark = require('benchmark'),\n    moment = require(\"./../moment.js\"),\n    base = moment('2013-05-25');\n\nmodule.exports = {\n  name: 'clone',\n  onComplete: function(){},\n  fn: function(){base.clone();},\n  async: true\n};\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/benchmarks/endOf.js",
    "content": "var Benchmark = require('benchmark'),\n    moment = require(\"./../moment.js\"),\n    base = moment('2013-05-25');\n\nvar unitsUnderTest = [\"second\", \"minute\", \"hour\", \"date\", \"day\", \"isoWeek\", \"week\", \"month\", \"quarter\", \"year\"];\nvar tests = unitsUnderTest.reduce(function (testsSoFar, unit) {\n    testsSoFar[\"endOf \" + unit] = generateTestForUnit(unit);\n    return testsSoFar;\n}, {});\n\nfunction generateTestForUnit(unit) {\n    return {\n        setup: function(){var base = base; var unit = unit;},\n        fn: function(){base.endOf(unit);},\n        async: true\n    };\n}\n\nmodule.exports = {\n    name: 'endOf',\n    tests: tests\n};\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/benchmarks/fromDate.js",
    "content": "var Benchmark = require('benchmark'),\n    moment = require('./../moment.js'),\n    base = new Date();\n\nmodule.exports = {\n  name: 'fromDate',\n  onComplete: function(){},\n  fn: function(){\n      moment(base);\n  },\n  async: true\n};\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/benchmarks/fromDateUtc.js",
    "content": "var Benchmark = require('benchmark'),\n    moment = require('./../moment.js'),\n    base = new Date();\n\nmodule.exports = {\n  name: 'fromDateUtc',\n  onComplete: function(){},\n  fn: function(){\n      moment.utc(base);\n  },\n  async: true\n};\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/benchmarks/makeDuration.js",
    "content": "var Benchmark = require('benchmark'),\n    moment = require('./../moment.js');\n\nmodule.exports = {\n  name: 'makeDuration',\n  onComplete: function(){},\n  fn: function(){\n      moment.duration(5, 'years');\n  },\n  async: true\n};\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/benchmarks/query.js",
    "content": "var Benchmark = require('benchmark'),\n    moment = require(\"./../moment.js\"),\n    base = moment('2013-05-25');\n\n\nmodule.exports = {\n    name: 'clone',\n    tests: {\n        isBefore_true: {\n            onComplete: function(){},\n            fn: function(){base.isBefore('2013-06-25');},\n            async: true\n        },\n        isBefore_self: {\n            onComplete: function(){},\n            fn: function(){base.isBefore('2013-05-25');},\n            async: true\n        },\n        isBefore_false: {\n            onComplete: function(){},\n            fn: function(){base.isBefore('2013-04-25');},\n            async: true\n        },\n        isAfter_true: {\n            onComplete: function(){},\n            fn: function(){base.isAfter('2013-04-25');},\n            async: true\n        },\n        isAfter_self: {\n            onComplete: function(){},\n            fn: function(){base.isAfter('2013-05-25');},\n            async: true\n        },\n        isAfter_false: {\n            onComplete: function(){},\n            fn: function(){base.isAfter('2013-06-25');},\n            async: true\n        }\n    }\n};\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/benchmarks/startOf.js",
    "content": "var Benchmark = require('benchmark'),\n    moment = require(\"./../moment.js\"),\n    base = moment('2013-05-25');\n\nvar unitsUnderTest = [\"second\", \"minute\", \"hour\", \"date\", \"day\", \"isoWeek\", \"week\", \"month\", \"quarter\", \"year\"];\nvar tests = unitsUnderTest.reduce(function (testsSoFar, unit) {\n    testsSoFar[\"startOf \" + unit] = generateTestForUnit(unit);\n    return testsSoFar;\n}, {});\n\nfunction generateTestForUnit(unit) {\n    return {\n        setup: function(){var base = base; var unit = unit;},\n        fn: function(){base.startOf(unit);},\n        async: true\n    };\n}\n\nmodule.exports = {\n    name: 'startOf',\n    tests: tests\n};\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/benchmarks/subtract.js",
    "content": "var Benchmark = require('benchmark'),\n    moment = require(\"./../moment.js\"),\n    base = moment('2013-05-25');\n\nvar unitsUnderTest = [\"milliseconds\", \"seconds\", \"minutes\", \"hours\", \"days\", \"weeks\", \"months\", \"quarters\", \"years\"];\nvar tests = unitsUnderTest.reduce(function (testsSoFar, unit) {\n    testsSoFar[\"subtract \" + unit] = generateTestForUnit(unit);\n    return testsSoFar;\n}, {});\n\nfunction generateTestForUnit(unit) {\n    return {\n        setup: function(){var base = base; var unit = unit;},\n        fn: function(){base.subtract(8, unit);},\n        async: true\n    };\n}\n\nmodule.exports = {\n    name: 'subtract',\n    tests: tests\n};\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/benchmarks/zeroFill.js",
    "content": "var Benchmark = require('benchmark');\n\nmodule.exports = {\n  name: 'zeroFill',\n  tests: {\n    zeroFillMath: {\n      setup: function() {\n        var zeroFillMath = function(number, targetLength, forceSign) {\n            var absNumber = '' + Math.abs(number),\n                zerosToFill = targetLength - absNumber.length,\n                sign = number >= 0;\n            return (sign ? (forceSign ? '+' : '') : '-') +\n                Math.pow(10, Math.max(0, zerosToFill)).toString().substr(1) + absNumber;\n        }\n      },\n      fn: function() {\n        zeroFillMath(Math.random() * 1e5 | 0, 5);\n        zeroFillMath(Math.random() * 1e5 | 0, 10);\n        zeroFillMath(Math.random() * 1e10 | 0, 20);\n      },\n      async: true\n    },\n    zeroFillWhile: {\n      setup: function() {\n        var zeroFillWhile = function(number, targetLength, forceSign) {\n          var output = '' + Math.abs(number),\n              sign = number >= 0;\n\n          while (output.length < targetLength) {\n              output = '0' + output;\n          }\n          return (sign ? (forceSign ? '+' : '') : '-') + output;\n        }\n      },\n      fn: function() {\n        zeroFillWhile(Math.random() * 1e5 | 0, 5);\n        zeroFillWhile(Math.random() * 1e5 | 0, 10);\n        zeroFillWhile(Math.random() * 1e10 | 0, 20);\n      },\n      async: true\n    }\n  }\n};\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/bower.json",
    "content": "{\n  \"name\": \"moment\",\n  \"license\": \"MIT\",\n  \"main\": \"moment.js\",\n  \"ignore\": [\n    \"**/.*\",\n    \"benchmarks\",\n    \"bower_components\",\n    \"meteor\",\n    \"node_modules\",\n    \"scripts\",\n    \"tasks\",\n    \"test\",\n    \"component.json\",\n    \"composer.json\",\n    \"CONTRIBUTING.md\",\n    \"ender.js\",\n    \"Gruntfile.js\",\n    \"Moment.js.nuspec\",\n    \"package.js\",\n    \"package.json\",\n    \"ISSUE_TEMPLATE.md\",\n    \"typing-tests\"\n  ]\n}\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/component.json",
    "content": "{\n  \"name\": \"moment\",\n  \"version\": \"2.18.1\",\n  \"main\": \"moment.js\",\n  \"description\": \"Parse, validate, manipulate, and display dates in JavaScript.\",\n  \"files\": [\n    \"moment.js\",\n    \"locale/af.js\",\n    \"locale/ar-dz.js\",\n    \"locale/ar-kw.js\",\n    \"locale/ar-ly.js\",\n    \"locale/ar-ma.js\",\n    \"locale/ar-sa.js\",\n    \"locale/ar-tn.js\",\n    \"locale/ar.js\",\n    \"locale/az.js\",\n    \"locale/be.js\",\n    \"locale/bg.js\",\n    \"locale/bn.js\",\n    \"locale/bo.js\",\n    \"locale/br.js\",\n    \"locale/bs.js\",\n    \"locale/ca.js\",\n    \"locale/cs.js\",\n    \"locale/cv.js\",\n    \"locale/cy.js\",\n    \"locale/da.js\",\n    \"locale/de-at.js\",\n    \"locale/de-ch.js\",\n    \"locale/de.js\",\n    \"locale/dv.js\",\n    \"locale/el.js\",\n    \"locale/en-au.js\",\n    \"locale/en-ca.js\",\n    \"locale/en-gb.js\",\n    \"locale/en-ie.js\",\n    \"locale/en-nz.js\",\n    \"locale/eo.js\",\n    \"locale/es-do.js\",\n    \"locale/es.js\",\n    \"locale/et.js\",\n    \"locale/eu.js\",\n    \"locale/fa.js\",\n    \"locale/fi.js\",\n    \"locale/fo.js\",\n    \"locale/fr-ca.js\",\n    \"locale/fr-ch.js\",\n    \"locale/fr.js\",\n    \"locale/fy.js\",\n    \"locale/gd.js\",\n    \"locale/gl.js\",\n    \"locale/gom-latn.js\",\n    \"locale/he.js\",\n    \"locale/hi.js\",\n    \"locale/hr.js\",\n    \"locale/hu.js\",\n    \"locale/hy-am.js\",\n    \"locale/id.js\",\n    \"locale/is.js\",\n    \"locale/it.js\",\n    \"locale/ja.js\",\n    \"locale/jv.js\",\n    \"locale/ka.js\",\n    \"locale/kk.js\",\n    \"locale/km.js\",\n    \"locale/kn.js\",\n    \"locale/ko.js\",\n    \"locale/ky.js\",\n    \"locale/lb.js\",\n    \"locale/lo.js\",\n    \"locale/lt.js\",\n    \"locale/lv.js\",\n    \"locale/me.js\",\n    \"locale/mi.js\",\n    \"locale/mk.js\",\n    \"locale/ml.js\",\n    \"locale/mr.js\",\n    \"locale/ms-my.js\",\n    \"locale/ms.js\",\n    \"locale/my.js\",\n    \"locale/nb.js\",\n    \"locale/ne.js\",\n    \"locale/nl-be.js\",\n    \"locale/nl.js\",\n    \"locale/nn.js\",\n    \"locale/pa-in.js\",\n    \"locale/pl.js\",\n    \"locale/pt-br.js\",\n    \"locale/pt.js\",\n    \"locale/ro.js\",\n    \"locale/ru.js\",\n    \"locale/sd.js\",\n    \"locale/se.js\",\n    \"locale/si.js\",\n    \"locale/sk.js\",\n    \"locale/sl.js\",\n    \"locale/sq.js\",\n    \"locale/sr-cyrl.js\",\n    \"locale/sr.js\",\n    \"locale/ss.js\",\n    \"locale/sv.js\",\n    \"locale/sw.js\",\n    \"locale/ta.js\",\n    \"locale/te.js\",\n    \"locale/tet.js\",\n    \"locale/th.js\",\n    \"locale/tl-ph.js\",\n    \"locale/tlh.js\",\n    \"locale/tr.js\",\n    \"locale/tzl.js\",\n    \"locale/tzm-latn.js\",\n    \"locale/tzm.js\",\n    \"locale/uk.js\",\n    \"locale/ur.js\",\n    \"locale/uz-latn.js\",\n    \"locale/uz.js\",\n    \"locale/vi.js\",\n    \"locale/x-pseudo.js\",\n    \"locale/yo.js\",\n    \"locale/zh-cn.js\",\n    \"locale/zh-hk.js\",\n    \"locale/zh-tw.js\"\n  ],\n  \"scripts\": [\n    \"moment.js\"\n  ]\n}\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/composer.json",
    "content": "{\n    \"name\": \"moment/moment\",\n    \"description\": \"Parse, validate, manipulate, and display dates in JavaScript.\",\n    \"keywords\": [\n        \"moment\",\n        \"date\",\n        \"time\",\n        \"parse\",\n        \"format\",\n        \"validate\",\n        \"i18n\",\n        \"l10n\",\n        \"ender\"\n    ],\n    \"homepage\": \"https://github.com/moment/moment\",\n    \"authors\": [{\"name\": \"Tim Wood\", \"email\": \"washwithcare@gmail.com\"}],\n    \"license\": \"MIT\",\n    \"type\": \"component\",\n    \"require\": {\n        \"robloach/component-installer\": \"*\"\n    },\n    \"extra\": {\n        \"component\": {\n            \"scripts\": [\n                \"moment.js\"\n            ],\n            \"files\": [\n               \"min/*.js\",\n               \"locale/*.js\"\n            ]\n        }\n    }\n}\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/ender.js",
    "content": "$.ender({ moment: require('moment') })\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/locale/af.js",
    "content": "//! moment.js locale configuration\n//! locale : Afrikaans [af]\n//! author : Werner Mollentze : https://github.com/wernerm\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\n\nvar af = moment.defineLocale('af', {\n    months : 'Januarie_Februarie_Maart_April_Mei_Junie_Julie_Augustus_September_Oktober_November_Desember'.split('_'),\n    monthsShort : 'Jan_Feb_Mrt_Apr_Mei_Jun_Jul_Aug_Sep_Okt_Nov_Des'.split('_'),\n    weekdays : 'Sondag_Maandag_Dinsdag_Woensdag_Donderdag_Vrydag_Saterdag'.split('_'),\n    weekdaysShort : 'Son_Maa_Din_Woe_Don_Vry_Sat'.split('_'),\n    weekdaysMin : 'So_Ma_Di_Wo_Do_Vr_Sa'.split('_'),\n    meridiemParse: /vm|nm/i,\n    isPM : function (input) {\n        return /^nm$/i.test(input);\n    },\n    meridiem : function (hours, minutes, isLower) {\n        if (hours < 12) {\n            return isLower ? 'vm' : 'VM';\n        } else {\n            return isLower ? 'nm' : 'NM';\n        }\n    },\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY HH:mm',\n        LLLL : 'dddd, D MMMM YYYY HH:mm'\n    },\n    calendar : {\n        sameDay : '[Vandag om] LT',\n        nextDay : '[Môre om] LT',\n        nextWeek : 'dddd [om] LT',\n        lastDay : '[Gister om] LT',\n        lastWeek : '[Laas] dddd [om] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'oor %s',\n        past : '%s gelede',\n        s : '\\'n paar sekondes',\n        m : '\\'n minuut',\n        mm : '%d minute',\n        h : '\\'n uur',\n        hh : '%d ure',\n        d : '\\'n dag',\n        dd : '%d dae',\n        M : '\\'n maand',\n        MM : '%d maande',\n        y : '\\'n jaar',\n        yy : '%d jaar'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}(ste|de)/,\n    ordinal : function (number) {\n        return number + ((number === 1 || number === 8 || number >= 20) ? 'ste' : 'de'); // Thanks to Joris Röling : https://github.com/jjupiter\n    },\n    week : {\n        dow : 1, // Maandag is die eerste dag van die week.\n        doy : 4  // Die week wat die 4de Januarie bevat is die eerste week van die jaar.\n    }\n});\n\nreturn af;\n\n})));\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/locale/ar-dz.js",
    "content": "//! moment.js locale configuration\n//! locale : Arabic (Algeria) [ar-dz]\n//! author : Noureddine LOUAHEDJ : https://github.com/noureddineme\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\n\nvar arDz = moment.defineLocale('ar-dz', {\n    months : 'جانفي_فيفري_مارس_أفريل_ماي_جوان_جويلية_أوت_سبتمبر_أكتوبر_نوفمبر_ديسمبر'.split('_'),\n    monthsShort : 'جانفي_فيفري_مارس_أفريل_ماي_جوان_جويلية_أوت_سبتمبر_أكتوبر_نوفمبر_ديسمبر'.split('_'),\n    weekdays : 'الأحد_الإثنين_الثلاثاء_الأربعاء_الخميس_الجمعة_السبت'.split('_'),\n    weekdaysShort : 'احد_اثنين_ثلاثاء_اربعاء_خميس_جمعة_سبت'.split('_'),\n    weekdaysMin : 'أح_إث_ثلا_أر_خم_جم_سب'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY HH:mm',\n        LLLL : 'dddd D MMMM YYYY HH:mm'\n    },\n    calendar : {\n        sameDay: '[اليوم على الساعة] LT',\n        nextDay: '[غدا على الساعة] LT',\n        nextWeek: 'dddd [على الساعة] LT',\n        lastDay: '[أمس على الساعة] LT',\n        lastWeek: 'dddd [على الساعة] LT',\n        sameElse: 'L'\n    },\n    relativeTime : {\n        future : 'في %s',\n        past : 'منذ %s',\n        s : 'ثوان',\n        m : 'دقيقة',\n        mm : '%d دقائق',\n        h : 'ساعة',\n        hh : '%d ساعات',\n        d : 'يوم',\n        dd : '%d أيام',\n        M : 'شهر',\n        MM : '%d أشهر',\n        y : 'سنة',\n        yy : '%d سنوات'\n    },\n    week : {\n        dow : 0, // Sunday is the first day of the week.\n        doy : 4  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\nreturn arDz;\n\n})));\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/locale/ar-kw.js",
    "content": "//! moment.js locale configuration\n//! locale : Arabic (Kuwait) [ar-kw]\n//! author : Nusret Parlak: https://github.com/nusretparlak\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\n\nvar arKw = moment.defineLocale('ar-kw', {\n    months : 'يناير_فبراير_مارس_أبريل_ماي_يونيو_يوليوز_غشت_شتنبر_أكتوبر_نونبر_دجنبر'.split('_'),\n    monthsShort : 'يناير_فبراير_مارس_أبريل_ماي_يونيو_يوليوز_غشت_شتنبر_أكتوبر_نونبر_دجنبر'.split('_'),\n    weekdays : 'الأحد_الإتنين_الثلاثاء_الأربعاء_الخميس_الجمعة_السبت'.split('_'),\n    weekdaysShort : 'احد_اتنين_ثلاثاء_اربعاء_خميس_جمعة_سبت'.split('_'),\n    weekdaysMin : 'ح_ن_ث_ر_خ_ج_س'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY HH:mm',\n        LLLL : 'dddd D MMMM YYYY HH:mm'\n    },\n    calendar : {\n        sameDay: '[اليوم على الساعة] LT',\n        nextDay: '[غدا على الساعة] LT',\n        nextWeek: 'dddd [على الساعة] LT',\n        lastDay: '[أمس على الساعة] LT',\n        lastWeek: 'dddd [على الساعة] LT',\n        sameElse: 'L'\n    },\n    relativeTime : {\n        future : 'في %s',\n        past : 'منذ %s',\n        s : 'ثوان',\n        m : 'دقيقة',\n        mm : '%d دقائق',\n        h : 'ساعة',\n        hh : '%d ساعات',\n        d : 'يوم',\n        dd : '%d أيام',\n        M : 'شهر',\n        MM : '%d أشهر',\n        y : 'سنة',\n        yy : '%d سنوات'\n    },\n    week : {\n        dow : 0, // Sunday is the first day of the week.\n        doy : 12  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\nreturn arKw;\n\n})));\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/locale/ar-ly.js",
    "content": "//! moment.js locale configuration\n//! locale : Arabic (Lybia) [ar-ly]\n//! author : Ali Hmer: https://github.com/kikoanis\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\n\nvar symbolMap = {\n    '1': '1',\n    '2': '2',\n    '3': '3',\n    '4': '4',\n    '5': '5',\n    '6': '6',\n    '7': '7',\n    '8': '8',\n    '9': '9',\n    '0': '0'\n};\nvar pluralForm = function (n) {\n    return n === 0 ? 0 : n === 1 ? 1 : n === 2 ? 2 : n % 100 >= 3 && n % 100 <= 10 ? 3 : n % 100 >= 11 ? 4 : 5;\n};\nvar plurals = {\n    s : ['أقل من ثانية', 'ثانية واحدة', ['ثانيتان', 'ثانيتين'], '%d ثوان', '%d ثانية', '%d ثانية'],\n    m : ['أقل من دقيقة', 'دقيقة واحدة', ['دقيقتان', 'دقيقتين'], '%d دقائق', '%d دقيقة', '%d دقيقة'],\n    h : ['أقل من ساعة', 'ساعة واحدة', ['ساعتان', 'ساعتين'], '%d ساعات', '%d ساعة', '%d ساعة'],\n    d : ['أقل من يوم', 'يوم واحد', ['يومان', 'يومين'], '%d أيام', '%d يومًا', '%d يوم'],\n    M : ['أقل من شهر', 'شهر واحد', ['شهران', 'شهرين'], '%d أشهر', '%d شهرا', '%d شهر'],\n    y : ['أقل من عام', 'عام واحد', ['عامان', 'عامين'], '%d أعوام', '%d عامًا', '%d عام']\n};\nvar pluralize = function (u) {\n    return function (number, withoutSuffix, string, isFuture) {\n        var f = pluralForm(number),\n            str = plurals[u][pluralForm(number)];\n        if (f === 2) {\n            str = str[withoutSuffix ? 0 : 1];\n        }\n        return str.replace(/%d/i, number);\n    };\n};\nvar months = [\n    'يناير',\n    'فبراير',\n    'مارس',\n    'أبريل',\n    'مايو',\n    'يونيو',\n    'يوليو',\n    'أغسطس',\n    'سبتمبر',\n    'أكتوبر',\n    'نوفمبر',\n    'ديسمبر'\n];\n\nvar arLy = moment.defineLocale('ar-ly', {\n    months : months,\n    monthsShort : months,\n    weekdays : 'الأحد_الإثنين_الثلاثاء_الأربعاء_الخميس_الجمعة_السبت'.split('_'),\n    weekdaysShort : 'أحد_إثنين_ثلاثاء_أربعاء_خميس_جمعة_سبت'.split('_'),\n    weekdaysMin : 'ح_ن_ث_ر_خ_ج_س'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'D/\\u200FM/\\u200FYYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY HH:mm',\n        LLLL : 'dddd D MMMM YYYY HH:mm'\n    },\n    meridiemParse: /ص|م/,\n    isPM : function (input) {\n        return 'م' === input;\n    },\n    meridiem : function (hour, minute, isLower) {\n        if (hour < 12) {\n            return 'ص';\n        } else {\n            return 'م';\n        }\n    },\n    calendar : {\n        sameDay: '[اليوم عند الساعة] LT',\n        nextDay: '[غدًا عند الساعة] LT',\n        nextWeek: 'dddd [عند الساعة] LT',\n        lastDay: '[أمس عند الساعة] LT',\n        lastWeek: 'dddd [عند الساعة] LT',\n        sameElse: 'L'\n    },\n    relativeTime : {\n        future : 'بعد %s',\n        past : 'منذ %s',\n        s : pluralize('s'),\n        m : pluralize('m'),\n        mm : pluralize('m'),\n        h : pluralize('h'),\n        hh : pluralize('h'),\n        d : pluralize('d'),\n        dd : pluralize('d'),\n        M : pluralize('M'),\n        MM : pluralize('M'),\n        y : pluralize('y'),\n        yy : pluralize('y')\n    },\n    preparse: function (string) {\n        return string.replace(/\\u200f/g, '').replace(/،/g, ',');\n    },\n    postformat: function (string) {\n        return string.replace(/\\d/g, function (match) {\n            return symbolMap[match];\n        }).replace(/,/g, '،');\n    },\n    week : {\n        dow : 6, // Saturday is the first day of the week.\n        doy : 12  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\nreturn arLy;\n\n})));\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/locale/ar-ma.js",
    "content": "//! moment.js locale configuration\n//! locale : Arabic (Morocco) [ar-ma]\n//! author : ElFadili Yassine : https://github.com/ElFadiliY\n//! author : Abdel Said : https://github.com/abdelsaid\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\n\nvar arMa = moment.defineLocale('ar-ma', {\n    months : 'يناير_فبراير_مارس_أبريل_ماي_يونيو_يوليوز_غشت_شتنبر_أكتوبر_نونبر_دجنبر'.split('_'),\n    monthsShort : 'يناير_فبراير_مارس_أبريل_ماي_يونيو_يوليوز_غشت_شتنبر_أكتوبر_نونبر_دجنبر'.split('_'),\n    weekdays : 'الأحد_الإتنين_الثلاثاء_الأربعاء_الخميس_الجمعة_السبت'.split('_'),\n    weekdaysShort : 'احد_اتنين_ثلاثاء_اربعاء_خميس_جمعة_سبت'.split('_'),\n    weekdaysMin : 'ح_ن_ث_ر_خ_ج_س'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY HH:mm',\n        LLLL : 'dddd D MMMM YYYY HH:mm'\n    },\n    calendar : {\n        sameDay: '[اليوم على الساعة] LT',\n        nextDay: '[غدا على الساعة] LT',\n        nextWeek: 'dddd [على الساعة] LT',\n        lastDay: '[أمس على الساعة] LT',\n        lastWeek: 'dddd [على الساعة] LT',\n        sameElse: 'L'\n    },\n    relativeTime : {\n        future : 'في %s',\n        past : 'منذ %s',\n        s : 'ثوان',\n        m : 'دقيقة',\n        mm : '%d دقائق',\n        h : 'ساعة',\n        hh : '%d ساعات',\n        d : 'يوم',\n        dd : '%d أيام',\n        M : 'شهر',\n        MM : '%d أشهر',\n        y : 'سنة',\n        yy : '%d سنوات'\n    },\n    week : {\n        dow : 6, // Saturday is the first day of the week.\n        doy : 12  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\nreturn arMa;\n\n})));\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/locale/ar-sa.js",
    "content": "//! moment.js locale configuration\n//! locale : Arabic (Saudi Arabia) [ar-sa]\n//! author : Suhail Alkowaileet : https://github.com/xsoh\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\n\nvar symbolMap = {\n    '1': '١',\n    '2': '٢',\n    '3': '٣',\n    '4': '٤',\n    '5': '٥',\n    '6': '٦',\n    '7': '٧',\n    '8': '٨',\n    '9': '٩',\n    '0': '٠'\n};\nvar numberMap = {\n    '١': '1',\n    '٢': '2',\n    '٣': '3',\n    '٤': '4',\n    '٥': '5',\n    '٦': '6',\n    '٧': '7',\n    '٨': '8',\n    '٩': '9',\n    '٠': '0'\n};\n\nvar arSa = moment.defineLocale('ar-sa', {\n    months : 'يناير_فبراير_مارس_أبريل_مايو_يونيو_يوليو_أغسطس_سبتمبر_أكتوبر_نوفمبر_ديسمبر'.split('_'),\n    monthsShort : 'يناير_فبراير_مارس_أبريل_مايو_يونيو_يوليو_أغسطس_سبتمبر_أكتوبر_نوفمبر_ديسمبر'.split('_'),\n    weekdays : 'الأحد_الإثنين_الثلاثاء_الأربعاء_الخميس_الجمعة_السبت'.split('_'),\n    weekdaysShort : 'أحد_إثنين_ثلاثاء_أربعاء_خميس_جمعة_سبت'.split('_'),\n    weekdaysMin : 'ح_ن_ث_ر_خ_ج_س'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY HH:mm',\n        LLLL : 'dddd D MMMM YYYY HH:mm'\n    },\n    meridiemParse: /ص|م/,\n    isPM : function (input) {\n        return 'م' === input;\n    },\n    meridiem : function (hour, minute, isLower) {\n        if (hour < 12) {\n            return 'ص';\n        } else {\n            return 'م';\n        }\n    },\n    calendar : {\n        sameDay: '[اليوم على الساعة] LT',\n        nextDay: '[غدا على الساعة] LT',\n        nextWeek: 'dddd [على الساعة] LT',\n        lastDay: '[أمس على الساعة] LT',\n        lastWeek: 'dddd [على الساعة] LT',\n        sameElse: 'L'\n    },\n    relativeTime : {\n        future : 'في %s',\n        past : 'منذ %s',\n        s : 'ثوان',\n        m : 'دقيقة',\n        mm : '%d دقائق',\n        h : 'ساعة',\n        hh : '%d ساعات',\n        d : 'يوم',\n        dd : '%d أيام',\n        M : 'شهر',\n        MM : '%d أشهر',\n        y : 'سنة',\n        yy : '%d سنوات'\n    },\n    preparse: function (string) {\n        return string.replace(/[١٢٣٤٥٦٧٨٩٠]/g, function (match) {\n            return numberMap[match];\n        }).replace(/،/g, ',');\n    },\n    postformat: function (string) {\n        return string.replace(/\\d/g, function (match) {\n            return symbolMap[match];\n        }).replace(/,/g, '،');\n    },\n    week : {\n        dow : 0, // Sunday is the first day of the week.\n        doy : 6  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\nreturn arSa;\n\n})));\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/locale/ar-tn.js",
    "content": "//! moment.js locale configuration\n//! locale  :  Arabic (Tunisia) [ar-tn]\n//! author : Nader Toukabri : https://github.com/naderio\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\n\nvar arTn = moment.defineLocale('ar-tn', {\n    months: 'جانفي_فيفري_مارس_أفريل_ماي_جوان_جويلية_أوت_سبتمبر_أكتوبر_نوفمبر_ديسمبر'.split('_'),\n    monthsShort: 'جانفي_فيفري_مارس_أفريل_ماي_جوان_جويلية_أوت_سبتمبر_أكتوبر_نوفمبر_ديسمبر'.split('_'),\n    weekdays: 'الأحد_الإثنين_الثلاثاء_الأربعاء_الخميس_الجمعة_السبت'.split('_'),\n    weekdaysShort: 'أحد_إثنين_ثلاثاء_أربعاء_خميس_جمعة_سبت'.split('_'),\n    weekdaysMin: 'ح_ن_ث_ر_خ_ج_س'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat: {\n        LT: 'HH:mm',\n        LTS: 'HH:mm:ss',\n        L: 'DD/MM/YYYY',\n        LL: 'D MMMM YYYY',\n        LLL: 'D MMMM YYYY HH:mm',\n        LLLL: 'dddd D MMMM YYYY HH:mm'\n    },\n    calendar: {\n        sameDay: '[اليوم على الساعة] LT',\n        nextDay: '[غدا على الساعة] LT',\n        nextWeek: 'dddd [على الساعة] LT',\n        lastDay: '[أمس على الساعة] LT',\n        lastWeek: 'dddd [على الساعة] LT',\n        sameElse: 'L'\n    },\n    relativeTime: {\n        future: 'في %s',\n        past: 'منذ %s',\n        s: 'ثوان',\n        m: 'دقيقة',\n        mm: '%d دقائق',\n        h: 'ساعة',\n        hh: '%d ساعات',\n        d: 'يوم',\n        dd: '%d أيام',\n        M: 'شهر',\n        MM: '%d أشهر',\n        y: 'سنة',\n        yy: '%d سنوات'\n    },\n    week: {\n        dow: 1, // Monday is the first day of the week.\n        doy: 4 // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\nreturn arTn;\n\n})));\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/locale/ar.js",
    "content": "//! moment.js locale configuration\n//! locale : Arabic [ar]\n//! author : Abdel Said: https://github.com/abdelsaid\n//! author : Ahmed Elkhatib\n//! author : forabi https://github.com/forabi\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\n\nvar symbolMap = {\n    '1': '١',\n    '2': '٢',\n    '3': '٣',\n    '4': '٤',\n    '5': '٥',\n    '6': '٦',\n    '7': '٧',\n    '8': '٨',\n    '9': '٩',\n    '0': '٠'\n};\nvar numberMap = {\n    '١': '1',\n    '٢': '2',\n    '٣': '3',\n    '٤': '4',\n    '٥': '5',\n    '٦': '6',\n    '٧': '7',\n    '٨': '8',\n    '٩': '9',\n    '٠': '0'\n};\nvar pluralForm = function (n) {\n    return n === 0 ? 0 : n === 1 ? 1 : n === 2 ? 2 : n % 100 >= 3 && n % 100 <= 10 ? 3 : n % 100 >= 11 ? 4 : 5;\n};\nvar plurals = {\n    s : ['أقل من ثانية', 'ثانية واحدة', ['ثانيتان', 'ثانيتين'], '%d ثوان', '%d ثانية', '%d ثانية'],\n    m : ['أقل من دقيقة', 'دقيقة واحدة', ['دقيقتان', 'دقيقتين'], '%d دقائق', '%d دقيقة', '%d دقيقة'],\n    h : ['أقل من ساعة', 'ساعة واحدة', ['ساعتان', 'ساعتين'], '%d ساعات', '%d ساعة', '%d ساعة'],\n    d : ['أقل من يوم', 'يوم واحد', ['يومان', 'يومين'], '%d أيام', '%d يومًا', '%d يوم'],\n    M : ['أقل من شهر', 'شهر واحد', ['شهران', 'شهرين'], '%d أشهر', '%d شهرا', '%d شهر'],\n    y : ['أقل من عام', 'عام واحد', ['عامان', 'عامين'], '%d أعوام', '%d عامًا', '%d عام']\n};\nvar pluralize = function (u) {\n    return function (number, withoutSuffix, string, isFuture) {\n        var f = pluralForm(number),\n            str = plurals[u][pluralForm(number)];\n        if (f === 2) {\n            str = str[withoutSuffix ? 0 : 1];\n        }\n        return str.replace(/%d/i, number);\n    };\n};\nvar months = [\n    'كانون الثاني يناير',\n    'شباط فبراير',\n    'آذار مارس',\n    'نيسان أبريل',\n    'أيار مايو',\n    'حزيران يونيو',\n    'تموز يوليو',\n    'آب أغسطس',\n    'أيلول سبتمبر',\n    'تشرين الأول أكتوبر',\n    'تشرين الثاني نوفمبر',\n    'كانون الأول ديسمبر'\n];\n\nvar ar = moment.defineLocale('ar', {\n    months : months,\n    monthsShort : months,\n    weekdays : 'الأحد_الإثنين_الثلاثاء_الأربعاء_الخميس_الجمعة_السبت'.split('_'),\n    weekdaysShort : 'أحد_إثنين_ثلاثاء_أربعاء_خميس_جمعة_سبت'.split('_'),\n    weekdaysMin : 'ح_ن_ث_ر_خ_ج_س'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'D/\\u200FM/\\u200FYYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY HH:mm',\n        LLLL : 'dddd D MMMM YYYY HH:mm'\n    },\n    meridiemParse: /ص|م/,\n    isPM : function (input) {\n        return 'م' === input;\n    },\n    meridiem : function (hour, minute, isLower) {\n        if (hour < 12) {\n            return 'ص';\n        } else {\n            return 'م';\n        }\n    },\n    calendar : {\n        sameDay: '[اليوم عند الساعة] LT',\n        nextDay: '[غدًا عند الساعة] LT',\n        nextWeek: 'dddd [عند الساعة] LT',\n        lastDay: '[أمس عند الساعة] LT',\n        lastWeek: 'dddd [عند الساعة] LT',\n        sameElse: 'L'\n    },\n    relativeTime : {\n        future : 'بعد %s',\n        past : 'منذ %s',\n        s : pluralize('s'),\n        m : pluralize('m'),\n        mm : pluralize('m'),\n        h : pluralize('h'),\n        hh : pluralize('h'),\n        d : pluralize('d'),\n        dd : pluralize('d'),\n        M : pluralize('M'),\n        MM : pluralize('M'),\n        y : pluralize('y'),\n        yy : pluralize('y')\n    },\n    preparse: function (string) {\n        return string.replace(/\\u200f/g, '').replace(/[١٢٣٤٥٦٧٨٩٠]/g, function (match) {\n            return numberMap[match];\n        }).replace(/،/g, ',');\n    },\n    postformat: function (string) {\n        return string.replace(/\\d/g, function (match) {\n            return symbolMap[match];\n        }).replace(/,/g, '،');\n    },\n    week : {\n        dow : 6, // Saturday is the first day of the week.\n        doy : 12  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\nreturn ar;\n\n})));\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/locale/az.js",
    "content": "//! moment.js locale configuration\n//! locale : Azerbaijani [az]\n//! author : topchiyev : https://github.com/topchiyev\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\n\nvar suffixes = {\n    1: '-inci',\n    5: '-inci',\n    8: '-inci',\n    70: '-inci',\n    80: '-inci',\n    2: '-nci',\n    7: '-nci',\n    20: '-nci',\n    50: '-nci',\n    3: '-üncü',\n    4: '-üncü',\n    100: '-üncü',\n    6: '-ncı',\n    9: '-uncu',\n    10: '-uncu',\n    30: '-uncu',\n    60: '-ıncı',\n    90: '-ıncı'\n};\n\nvar az = moment.defineLocale('az', {\n    months : 'yanvar_fevral_mart_aprel_may_iyun_iyul_avqust_sentyabr_oktyabr_noyabr_dekabr'.split('_'),\n    monthsShort : 'yan_fev_mar_apr_may_iyn_iyl_avq_sen_okt_noy_dek'.split('_'),\n    weekdays : 'Bazar_Bazar ertəsi_Çərşənbə axşamı_Çərşənbə_Cümə axşamı_Cümə_Şənbə'.split('_'),\n    weekdaysShort : 'Baz_BzE_ÇAx_Çər_CAx_Cüm_Şən'.split('_'),\n    weekdaysMin : 'Bz_BE_ÇA_Çə_CA_Cü_Şə'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD.MM.YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY HH:mm',\n        LLLL : 'dddd, D MMMM YYYY HH:mm'\n    },\n    calendar : {\n        sameDay : '[bugün saat] LT',\n        nextDay : '[sabah saat] LT',\n        nextWeek : '[gələn həftə] dddd [saat] LT',\n        lastDay : '[dünən] LT',\n        lastWeek : '[keçən həftə] dddd [saat] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : '%s sonra',\n        past : '%s əvvəl',\n        s : 'birneçə saniyyə',\n        m : 'bir dəqiqə',\n        mm : '%d dəqiqə',\n        h : 'bir saat',\n        hh : '%d saat',\n        d : 'bir gün',\n        dd : '%d gün',\n        M : 'bir ay',\n        MM : '%d ay',\n        y : 'bir il',\n        yy : '%d il'\n    },\n    meridiemParse: /gecə|səhər|gündüz|axşam/,\n    isPM : function (input) {\n        return /^(gündüz|axşam)$/.test(input);\n    },\n    meridiem : function (hour, minute, isLower) {\n        if (hour < 4) {\n            return 'gecə';\n        } else if (hour < 12) {\n            return 'səhər';\n        } else if (hour < 17) {\n            return 'gündüz';\n        } else {\n            return 'axşam';\n        }\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}-(ıncı|inci|nci|üncü|ncı|uncu)/,\n    ordinal : function (number) {\n        if (number === 0) {  // special case for zero\n            return number + '-ıncı';\n        }\n        var a = number % 10,\n            b = number % 100 - a,\n            c = number >= 100 ? 100 : null;\n        return number + (suffixes[a] || suffixes[b] || suffixes[c]);\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 7  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\nreturn az;\n\n})));\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/locale/be.js",
    "content": "//! moment.js locale configuration\n//! locale : Belarusian [be]\n//! author : Dmitry Demidov : https://github.com/demidov91\n//! author: Praleska: http://praleska.pro/\n//! Author : Menelion Elensúle : https://github.com/Oire\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\n\nfunction plural(word, num) {\n    var forms = word.split('_');\n    return num % 10 === 1 && num % 100 !== 11 ? forms[0] : (num % 10 >= 2 && num % 10 <= 4 && (num % 100 < 10 || num % 100 >= 20) ? forms[1] : forms[2]);\n}\nfunction relativeTimeWithPlural(number, withoutSuffix, key) {\n    var format = {\n        'mm': withoutSuffix ? 'хвіліна_хвіліны_хвілін' : 'хвіліну_хвіліны_хвілін',\n        'hh': withoutSuffix ? 'гадзіна_гадзіны_гадзін' : 'гадзіну_гадзіны_гадзін',\n        'dd': 'дзень_дні_дзён',\n        'MM': 'месяц_месяцы_месяцаў',\n        'yy': 'год_гады_гадоў'\n    };\n    if (key === 'm') {\n        return withoutSuffix ? 'хвіліна' : 'хвіліну';\n    }\n    else if (key === 'h') {\n        return withoutSuffix ? 'гадзіна' : 'гадзіну';\n    }\n    else {\n        return number + ' ' + plural(format[key], +number);\n    }\n}\n\nvar be = moment.defineLocale('be', {\n    months : {\n        format: 'студзеня_лютага_сакавіка_красавіка_траўня_чэрвеня_ліпеня_жніўня_верасня_кастрычніка_лістапада_снежня'.split('_'),\n        standalone: 'студзень_люты_сакавік_красавік_травень_чэрвень_ліпень_жнівень_верасень_кастрычнік_лістапад_снежань'.split('_')\n    },\n    monthsShort : 'студ_лют_сак_крас_трав_чэрв_ліп_жнів_вер_каст_ліст_снеж'.split('_'),\n    weekdays : {\n        format: 'нядзелю_панядзелак_аўторак_сераду_чацвер_пятніцу_суботу'.split('_'),\n        standalone: 'нядзеля_панядзелак_аўторак_серада_чацвер_пятніца_субота'.split('_'),\n        isFormat: /\\[ ?[Вв] ?(?:мінулую|наступную)? ?\\] ?dddd/\n    },\n    weekdaysShort : 'нд_пн_ат_ср_чц_пт_сб'.split('_'),\n    weekdaysMin : 'нд_пн_ат_ср_чц_пт_сб'.split('_'),\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD.MM.YYYY',\n        LL : 'D MMMM YYYY г.',\n        LLL : 'D MMMM YYYY г., HH:mm',\n        LLLL : 'dddd, D MMMM YYYY г., HH:mm'\n    },\n    calendar : {\n        sameDay: '[Сёння ў] LT',\n        nextDay: '[Заўтра ў] LT',\n        lastDay: '[Учора ў] LT',\n        nextWeek: function () {\n            return '[У] dddd [ў] LT';\n        },\n        lastWeek: function () {\n            switch (this.day()) {\n                case 0:\n                case 3:\n                case 5:\n                case 6:\n                    return '[У мінулую] dddd [ў] LT';\n                case 1:\n                case 2:\n                case 4:\n                    return '[У мінулы] dddd [ў] LT';\n            }\n        },\n        sameElse: 'L'\n    },\n    relativeTime : {\n        future : 'праз %s',\n        past : '%s таму',\n        s : 'некалькі секунд',\n        m : relativeTimeWithPlural,\n        mm : relativeTimeWithPlural,\n        h : relativeTimeWithPlural,\n        hh : relativeTimeWithPlural,\n        d : 'дзень',\n        dd : relativeTimeWithPlural,\n        M : 'месяц',\n        MM : relativeTimeWithPlural,\n        y : 'год',\n        yy : relativeTimeWithPlural\n    },\n    meridiemParse: /ночы|раніцы|дня|вечара/,\n    isPM : function (input) {\n        return /^(дня|вечара)$/.test(input);\n    },\n    meridiem : function (hour, minute, isLower) {\n        if (hour < 4) {\n            return 'ночы';\n        } else if (hour < 12) {\n            return 'раніцы';\n        } else if (hour < 17) {\n            return 'дня';\n        } else {\n            return 'вечара';\n        }\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}-(і|ы|га)/,\n    ordinal: function (number, period) {\n        switch (period) {\n            case 'M':\n            case 'd':\n            case 'DDD':\n            case 'w':\n            case 'W':\n                return (number % 10 === 2 || number % 10 === 3) && (number % 100 !== 12 && number % 100 !== 13) ? number + '-і' : number + '-ы';\n            case 'D':\n                return number + '-га';\n            default:\n                return number;\n        }\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 7  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\nreturn be;\n\n})));\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/locale/bg.js",
    "content": "//! moment.js locale configuration\n//! locale : Bulgarian [bg]\n//! author : Krasen Borisov : https://github.com/kraz\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\n\nvar bg = moment.defineLocale('bg', {\n    months : 'януари_февруари_март_април_май_юни_юли_август_септември_октомври_ноември_декември'.split('_'),\n    monthsShort : 'янр_фев_мар_апр_май_юни_юли_авг_сеп_окт_ное_дек'.split('_'),\n    weekdays : 'неделя_понеделник_вторник_сряда_четвъртък_петък_събота'.split('_'),\n    weekdaysShort : 'нед_пон_вто_сря_чет_пет_съб'.split('_'),\n    weekdaysMin : 'нд_пн_вт_ср_чт_пт_сб'.split('_'),\n    longDateFormat : {\n        LT : 'H:mm',\n        LTS : 'H:mm:ss',\n        L : 'D.MM.YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY H:mm',\n        LLLL : 'dddd, D MMMM YYYY H:mm'\n    },\n    calendar : {\n        sameDay : '[Днес в] LT',\n        nextDay : '[Утре в] LT',\n        nextWeek : 'dddd [в] LT',\n        lastDay : '[Вчера в] LT',\n        lastWeek : function () {\n            switch (this.day()) {\n                case 0:\n                case 3:\n                case 6:\n                    return '[В изминалата] dddd [в] LT';\n                case 1:\n                case 2:\n                case 4:\n                case 5:\n                    return '[В изминалия] dddd [в] LT';\n            }\n        },\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'след %s',\n        past : 'преди %s',\n        s : 'няколко секунди',\n        m : 'минута',\n        mm : '%d минути',\n        h : 'час',\n        hh : '%d часа',\n        d : 'ден',\n        dd : '%d дни',\n        M : 'месец',\n        MM : '%d месеца',\n        y : 'година',\n        yy : '%d години'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}-(ев|ен|ти|ви|ри|ми)/,\n    ordinal : function (number) {\n        var lastDigit = number % 10,\n            last2Digits = number % 100;\n        if (number === 0) {\n            return number + '-ев';\n        } else if (last2Digits === 0) {\n            return number + '-ен';\n        } else if (last2Digits > 10 && last2Digits < 20) {\n            return number + '-ти';\n        } else if (lastDigit === 1) {\n            return number + '-ви';\n        } else if (lastDigit === 2) {\n            return number + '-ри';\n        } else if (lastDigit === 7 || lastDigit === 8) {\n            return number + '-ми';\n        } else {\n            return number + '-ти';\n        }\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 7  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\nreturn bg;\n\n})));\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/locale/bn.js",
    "content": "//! moment.js locale configuration\n//! locale : Bengali [bn]\n//! author : Kaushik Gandhi : https://github.com/kaushikgandhi\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\n\nvar symbolMap = {\n    '1': '১',\n    '2': '২',\n    '3': '৩',\n    '4': '৪',\n    '5': '৫',\n    '6': '৬',\n    '7': '৭',\n    '8': '৮',\n    '9': '৯',\n    '0': '০'\n};\nvar numberMap = {\n    '১': '1',\n    '২': '2',\n    '৩': '3',\n    '৪': '4',\n    '৫': '5',\n    '৬': '6',\n    '৭': '7',\n    '৮': '8',\n    '৯': '9',\n    '০': '0'\n};\n\nvar bn = moment.defineLocale('bn', {\n    months : 'জানুয়ারী_ফেব্রুয়ারি_মার্চ_এপ্রিল_মে_জুন_জুলাই_আগস্ট_সেপ্টেম্বর_অক্টোবর_নভেম্বর_ডিসেম্বর'.split('_'),\n    monthsShort : 'জানু_ফেব_মার্চ_এপ্র_মে_জুন_জুল_আগ_সেপ্ট_অক্টো_নভে_ডিসে'.split('_'),\n    weekdays : 'রবিবার_সোমবার_মঙ্গলবার_বুধবার_বৃহস্পতিবার_শুক্রবার_শনিবার'.split('_'),\n    weekdaysShort : 'রবি_সোম_মঙ্গল_বুধ_বৃহস্পতি_শুক্র_শনি'.split('_'),\n    weekdaysMin : 'রবি_সোম_মঙ্গ_বুধ_বৃহঃ_শুক্র_শনি'.split('_'),\n    longDateFormat : {\n        LT : 'A h:mm সময়',\n        LTS : 'A h:mm:ss সময়',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY, A h:mm সময়',\n        LLLL : 'dddd, D MMMM YYYY, A h:mm সময়'\n    },\n    calendar : {\n        sameDay : '[আজ] LT',\n        nextDay : '[আগামীকাল] LT',\n        nextWeek : 'dddd, LT',\n        lastDay : '[গতকাল] LT',\n        lastWeek : '[গত] dddd, LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : '%s পরে',\n        past : '%s আগে',\n        s : 'কয়েক সেকেন্ড',\n        m : 'এক মিনিট',\n        mm : '%d মিনিট',\n        h : 'এক ঘন্টা',\n        hh : '%d ঘন্টা',\n        d : 'এক দিন',\n        dd : '%d দিন',\n        M : 'এক মাস',\n        MM : '%d মাস',\n        y : 'এক বছর',\n        yy : '%d বছর'\n    },\n    preparse: function (string) {\n        return string.replace(/[১২৩৪৫৬৭৮৯০]/g, function (match) {\n            return numberMap[match];\n        });\n    },\n    postformat: function (string) {\n        return string.replace(/\\d/g, function (match) {\n            return symbolMap[match];\n        });\n    },\n    meridiemParse: /রাত|সকাল|দুপুর|বিকাল|রাত/,\n    meridiemHour : function (hour, meridiem) {\n        if (hour === 12) {\n            hour = 0;\n        }\n        if ((meridiem === 'রাত' && hour >= 4) ||\n                (meridiem === 'দুপুর' && hour < 5) ||\n                meridiem === 'বিকাল') {\n            return hour + 12;\n        } else {\n            return hour;\n        }\n    },\n    meridiem : function (hour, minute, isLower) {\n        if (hour < 4) {\n            return 'রাত';\n        } else if (hour < 10) {\n            return 'সকাল';\n        } else if (hour < 17) {\n            return 'দুপুর';\n        } else if (hour < 20) {\n            return 'বিকাল';\n        } else {\n            return 'রাত';\n        }\n    },\n    week : {\n        dow : 0, // Sunday is the first day of the week.\n        doy : 6  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\nreturn bn;\n\n})));\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/locale/bo.js",
    "content": "//! moment.js locale configuration\n//! locale : Tibetan [bo]\n//! author : Thupten N. Chakrishar : https://github.com/vajradog\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\n\nvar symbolMap = {\n    '1': '༡',\n    '2': '༢',\n    '3': '༣',\n    '4': '༤',\n    '5': '༥',\n    '6': '༦',\n    '7': '༧',\n    '8': '༨',\n    '9': '༩',\n    '0': '༠'\n};\nvar numberMap = {\n    '༡': '1',\n    '༢': '2',\n    '༣': '3',\n    '༤': '4',\n    '༥': '5',\n    '༦': '6',\n    '༧': '7',\n    '༨': '8',\n    '༩': '9',\n    '༠': '0'\n};\n\nvar bo = moment.defineLocale('bo', {\n    months : 'ཟླ་བ་དང་པོ_ཟླ་བ་གཉིས་པ_ཟླ་བ་གསུམ་པ_ཟླ་བ་བཞི་པ_ཟླ་བ་ལྔ་པ_ཟླ་བ་དྲུག་པ_ཟླ་བ་བདུན་པ_ཟླ་བ་བརྒྱད་པ_ཟླ་བ་དགུ་པ_ཟླ་བ་བཅུ་པ_ཟླ་བ་བཅུ་གཅིག་པ_ཟླ་བ་བཅུ་གཉིས་པ'.split('_'),\n    monthsShort : 'ཟླ་བ་དང་པོ_ཟླ་བ་གཉིས་པ_ཟླ་བ་གསུམ་པ_ཟླ་བ་བཞི་པ_ཟླ་བ་ལྔ་པ_ཟླ་བ་དྲུག་པ_ཟླ་བ་བདུན་པ_ཟླ་བ་བརྒྱད་པ_ཟླ་བ་དགུ་པ_ཟླ་བ་བཅུ་པ_ཟླ་བ་བཅུ་གཅིག་པ_ཟླ་བ་བཅུ་གཉིས་པ'.split('_'),\n    weekdays : 'གཟའ་ཉི་མ་_གཟའ་ཟླ་བ་_གཟའ་མིག་དམར་_གཟའ་ལྷག་པ་_གཟའ་ཕུར་བུ_གཟའ་པ་སངས་_གཟའ་སྤེན་པ་'.split('_'),\n    weekdaysShort : 'ཉི་མ་_ཟླ་བ་_མིག་དམར་_ལྷག་པ་_ཕུར་བུ_པ་སངས་_སྤེན་པ་'.split('_'),\n    weekdaysMin : 'ཉི་མ་_ཟླ་བ་_མིག་དམར་_ལྷག་པ་_ཕུར་བུ_པ་སངས་_སྤེན་པ་'.split('_'),\n    longDateFormat : {\n        LT : 'A h:mm',\n        LTS : 'A h:mm:ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY, A h:mm',\n        LLLL : 'dddd, D MMMM YYYY, A h:mm'\n    },\n    calendar : {\n        sameDay : '[དི་རིང] LT',\n        nextDay : '[སང་ཉིན] LT',\n        nextWeek : '[བདུན་ཕྲག་རྗེས་མ], LT',\n        lastDay : '[ཁ་སང] LT',\n        lastWeek : '[བདུན་ཕྲག་མཐའ་མ] dddd, LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : '%s ལ་',\n        past : '%s སྔན་ལ',\n        s : 'ལམ་སང',\n        m : 'སྐར་མ་གཅིག',\n        mm : '%d སྐར་མ',\n        h : 'ཆུ་ཚོད་གཅིག',\n        hh : '%d ཆུ་ཚོད',\n        d : 'ཉིན་གཅིག',\n        dd : '%d ཉིན་',\n        M : 'ཟླ་བ་གཅིག',\n        MM : '%d ཟླ་བ',\n        y : 'ལོ་གཅིག',\n        yy : '%d ལོ'\n    },\n    preparse: function (string) {\n        return string.replace(/[༡༢༣༤༥༦༧༨༩༠]/g, function (match) {\n            return numberMap[match];\n        });\n    },\n    postformat: function (string) {\n        return string.replace(/\\d/g, function (match) {\n            return symbolMap[match];\n        });\n    },\n    meridiemParse: /མཚན་མོ|ཞོགས་ཀས|ཉིན་གུང|དགོང་དག|མཚན་མོ/,\n    meridiemHour : function (hour, meridiem) {\n        if (hour === 12) {\n            hour = 0;\n        }\n        if ((meridiem === 'མཚན་མོ' && hour >= 4) ||\n                (meridiem === 'ཉིན་གུང' && hour < 5) ||\n                meridiem === 'དགོང་དག') {\n            return hour + 12;\n        } else {\n            return hour;\n        }\n    },\n    meridiem : function (hour, minute, isLower) {\n        if (hour < 4) {\n            return 'མཚན་མོ';\n        } else if (hour < 10) {\n            return 'ཞོགས་ཀས';\n        } else if (hour < 17) {\n            return 'ཉིན་གུང';\n        } else if (hour < 20) {\n            return 'དགོང་དག';\n        } else {\n            return 'མཚན་མོ';\n        }\n    },\n    week : {\n        dow : 0, // Sunday is the first day of the week.\n        doy : 6  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\nreturn bo;\n\n})));\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/locale/br.js",
    "content": "//! moment.js locale configuration\n//! locale : Breton [br]\n//! author : Jean-Baptiste Le Duigou : https://github.com/jbleduigou\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\n\nfunction relativeTimeWithMutation(number, withoutSuffix, key) {\n    var format = {\n        'mm': 'munutenn',\n        'MM': 'miz',\n        'dd': 'devezh'\n    };\n    return number + ' ' + mutation(format[key], number);\n}\nfunction specialMutationForYears(number) {\n    switch (lastNumber(number)) {\n        case 1:\n        case 3:\n        case 4:\n        case 5:\n        case 9:\n            return number + ' bloaz';\n        default:\n            return number + ' vloaz';\n    }\n}\nfunction lastNumber(number) {\n    if (number > 9) {\n        return lastNumber(number % 10);\n    }\n    return number;\n}\nfunction mutation(text, number) {\n    if (number === 2) {\n        return softMutation(text);\n    }\n    return text;\n}\nfunction softMutation(text) {\n    var mutationTable = {\n        'm': 'v',\n        'b': 'v',\n        'd': 'z'\n    };\n    if (mutationTable[text.charAt(0)] === undefined) {\n        return text;\n    }\n    return mutationTable[text.charAt(0)] + text.substring(1);\n}\n\nvar br = moment.defineLocale('br', {\n    months : 'Genver_C\\'hwevrer_Meurzh_Ebrel_Mae_Mezheven_Gouere_Eost_Gwengolo_Here_Du_Kerzu'.split('_'),\n    monthsShort : 'Gen_C\\'hwe_Meu_Ebr_Mae_Eve_Gou_Eos_Gwe_Her_Du_Ker'.split('_'),\n    weekdays : 'Sul_Lun_Meurzh_Merc\\'her_Yaou_Gwener_Sadorn'.split('_'),\n    weekdaysShort : 'Sul_Lun_Meu_Mer_Yao_Gwe_Sad'.split('_'),\n    weekdaysMin : 'Su_Lu_Me_Mer_Ya_Gw_Sa'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat : {\n        LT : 'h[e]mm A',\n        LTS : 'h[e]mm:ss A',\n        L : 'DD/MM/YYYY',\n        LL : 'D [a viz] MMMM YYYY',\n        LLL : 'D [a viz] MMMM YYYY h[e]mm A',\n        LLLL : 'dddd, D [a viz] MMMM YYYY h[e]mm A'\n    },\n    calendar : {\n        sameDay : '[Hiziv da] LT',\n        nextDay : '[Warc\\'hoazh da] LT',\n        nextWeek : 'dddd [da] LT',\n        lastDay : '[Dec\\'h da] LT',\n        lastWeek : 'dddd [paset da] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'a-benn %s',\n        past : '%s \\'zo',\n        s : 'un nebeud segondennoù',\n        m : 'ur vunutenn',\n        mm : relativeTimeWithMutation,\n        h : 'un eur',\n        hh : '%d eur',\n        d : 'un devezh',\n        dd : relativeTimeWithMutation,\n        M : 'ur miz',\n        MM : relativeTimeWithMutation,\n        y : 'ur bloaz',\n        yy : specialMutationForYears\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}(añ|vet)/,\n    ordinal : function (number) {\n        var output = (number === 1) ? 'añ' : 'vet';\n        return number + output;\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\nreturn br;\n\n})));\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/locale/bs.js",
    "content": "//! moment.js locale configuration\n//! locale : Bosnian [bs]\n//! author : Nedim Cholich : https://github.com/frontyard\n//! based on (hr) translation by Bojan Marković\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\n\nfunction translate(number, withoutSuffix, key) {\n    var result = number + ' ';\n    switch (key) {\n        case 'm':\n            return withoutSuffix ? 'jedna minuta' : 'jedne minute';\n        case 'mm':\n            if (number === 1) {\n                result += 'minuta';\n            } else if (number === 2 || number === 3 || number === 4) {\n                result += 'minute';\n            } else {\n                result += 'minuta';\n            }\n            return result;\n        case 'h':\n            return withoutSuffix ? 'jedan sat' : 'jednog sata';\n        case 'hh':\n            if (number === 1) {\n                result += 'sat';\n            } else if (number === 2 || number === 3 || number === 4) {\n                result += 'sata';\n            } else {\n                result += 'sati';\n            }\n            return result;\n        case 'dd':\n            if (number === 1) {\n                result += 'dan';\n            } else {\n                result += 'dana';\n            }\n            return result;\n        case 'MM':\n            if (number === 1) {\n                result += 'mjesec';\n            } else if (number === 2 || number === 3 || number === 4) {\n                result += 'mjeseca';\n            } else {\n                result += 'mjeseci';\n            }\n            return result;\n        case 'yy':\n            if (number === 1) {\n                result += 'godina';\n            } else if (number === 2 || number === 3 || number === 4) {\n                result += 'godine';\n            } else {\n                result += 'godina';\n            }\n            return result;\n    }\n}\n\nvar bs = moment.defineLocale('bs', {\n    months : 'januar_februar_mart_april_maj_juni_juli_august_septembar_oktobar_novembar_decembar'.split('_'),\n    monthsShort : 'jan._feb._mar._apr._maj._jun._jul._aug._sep._okt._nov._dec.'.split('_'),\n    monthsParseExact: true,\n    weekdays : 'nedjelja_ponedjeljak_utorak_srijeda_četvrtak_petak_subota'.split('_'),\n    weekdaysShort : 'ned._pon._uto._sri._čet._pet._sub.'.split('_'),\n    weekdaysMin : 'ne_po_ut_sr_če_pe_su'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat : {\n        LT : 'H:mm',\n        LTS : 'H:mm:ss',\n        L : 'DD.MM.YYYY',\n        LL : 'D. MMMM YYYY',\n        LLL : 'D. MMMM YYYY H:mm',\n        LLLL : 'dddd, D. MMMM YYYY H:mm'\n    },\n    calendar : {\n        sameDay  : '[danas u] LT',\n        nextDay  : '[sutra u] LT',\n        nextWeek : function () {\n            switch (this.day()) {\n                case 0:\n                    return '[u] [nedjelju] [u] LT';\n                case 3:\n                    return '[u] [srijedu] [u] LT';\n                case 6:\n                    return '[u] [subotu] [u] LT';\n                case 1:\n                case 2:\n                case 4:\n                case 5:\n                    return '[u] dddd [u] LT';\n            }\n        },\n        lastDay  : '[jučer u] LT',\n        lastWeek : function () {\n            switch (this.day()) {\n                case 0:\n                case 3:\n                    return '[prošlu] dddd [u] LT';\n                case 6:\n                    return '[prošle] [subote] [u] LT';\n                case 1:\n                case 2:\n                case 4:\n                case 5:\n                    return '[prošli] dddd [u] LT';\n            }\n        },\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'za %s',\n        past   : 'prije %s',\n        s      : 'par sekundi',\n        m      : translate,\n        mm     : translate,\n        h      : translate,\n        hh     : translate,\n        d      : 'dan',\n        dd     : translate,\n        M      : 'mjesec',\n        MM     : translate,\n        y      : 'godinu',\n        yy     : translate\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}\\./,\n    ordinal : '%d.',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 7  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\nreturn bs;\n\n})));\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/locale/ca.js",
    "content": "//! moment.js locale configuration\n//! locale : Catalan [ca]\n//! author : Juan G. Hurtado : https://github.com/juanghurtado\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\n\nvar ca = moment.defineLocale('ca', {\n    months : {\n        standalone: 'gener_febrer_març_abril_maig_juny_juliol_agost_setembre_octubre_novembre_desembre'.split('_'),\n        format: 'de gener_de febrer_de març_d\\'abril_de maig_de juny_de juliol_d\\'agost_de setembre_d\\'octubre_de novembre_de desembre'.split('_'),\n        isFormat: /D[oD]?(\\s)+MMMM/\n    },\n    monthsShort : 'gen._febr._març_abr._maig_juny_jul._ag._set._oct._nov._des.'.split('_'),\n    monthsParseExact : true,\n    weekdays : 'diumenge_dilluns_dimarts_dimecres_dijous_divendres_dissabte'.split('_'),\n    weekdaysShort : 'dg._dl._dt._dc._dj._dv._ds.'.split('_'),\n    weekdaysMin : 'Dg_Dl_Dt_Dc_Dj_Dv_Ds'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat : {\n        LT : 'H:mm',\n        LTS : 'H:mm:ss',\n        L : 'DD/MM/YYYY',\n        LL : '[el] D MMMM [de] YYYY',\n        ll : 'D MMM YYYY',\n        LLL : '[el] D MMMM [de] YYYY [a les] H:mm',\n        lll : 'D MMM YYYY, H:mm',\n        LLLL : '[el] dddd D MMMM [de] YYYY [a les] H:mm',\n        llll : 'ddd D MMM YYYY, H:mm'\n    },\n    calendar : {\n        sameDay : function () {\n            return '[avui a ' + ((this.hours() !== 1) ? 'les' : 'la') + '] LT';\n        },\n        nextDay : function () {\n            return '[demà a ' + ((this.hours() !== 1) ? 'les' : 'la') + '] LT';\n        },\n        nextWeek : function () {\n            return 'dddd [a ' + ((this.hours() !== 1) ? 'les' : 'la') + '] LT';\n        },\n        lastDay : function () {\n            return '[ahir a ' + ((this.hours() !== 1) ? 'les' : 'la') + '] LT';\n        },\n        lastWeek : function () {\n            return '[el] dddd [passat a ' + ((this.hours() !== 1) ? 'les' : 'la') + '] LT';\n        },\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'd\\'aquí %s',\n        past : 'fa %s',\n        s : 'uns segons',\n        m : 'un minut',\n        mm : '%d minuts',\n        h : 'una hora',\n        hh : '%d hores',\n        d : 'un dia',\n        dd : '%d dies',\n        M : 'un mes',\n        MM : '%d mesos',\n        y : 'un any',\n        yy : '%d anys'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}(r|n|t|è|a)/,\n    ordinal : function (number, period) {\n        var output = (number === 1) ? 'r' :\n            (number === 2) ? 'n' :\n            (number === 3) ? 'r' :\n            (number === 4) ? 't' : 'è';\n        if (period === 'w' || period === 'W') {\n            output = 'a';\n        }\n        return number + output;\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\nreturn ca;\n\n})));\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/locale/cs.js",
    "content": "//! moment.js locale configuration\n//! locale : Czech [cs]\n//! author : petrbela : https://github.com/petrbela\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\n\nvar months = 'leden_únor_březen_duben_květen_červen_červenec_srpen_září_říjen_listopad_prosinec'.split('_');\nvar monthsShort = 'led_úno_bře_dub_kvě_čvn_čvc_srp_zář_říj_lis_pro'.split('_');\nfunction plural(n) {\n    return (n > 1) && (n < 5) && (~~(n / 10) !== 1);\n}\nfunction translate(number, withoutSuffix, key, isFuture) {\n    var result = number + ' ';\n    switch (key) {\n        case 's':  // a few seconds / in a few seconds / a few seconds ago\n            return (withoutSuffix || isFuture) ? 'pár sekund' : 'pár sekundami';\n        case 'm':  // a minute / in a minute / a minute ago\n            return withoutSuffix ? 'minuta' : (isFuture ? 'minutu' : 'minutou');\n        case 'mm': // 9 minutes / in 9 minutes / 9 minutes ago\n            if (withoutSuffix || isFuture) {\n                return result + (plural(number) ? 'minuty' : 'minut');\n            } else {\n                return result + 'minutami';\n            }\n            break;\n        case 'h':  // an hour / in an hour / an hour ago\n            return withoutSuffix ? 'hodina' : (isFuture ? 'hodinu' : 'hodinou');\n        case 'hh': // 9 hours / in 9 hours / 9 hours ago\n            if (withoutSuffix || isFuture) {\n                return result + (plural(number) ? 'hodiny' : 'hodin');\n            } else {\n                return result + 'hodinami';\n            }\n            break;\n        case 'd':  // a day / in a day / a day ago\n            return (withoutSuffix || isFuture) ? 'den' : 'dnem';\n        case 'dd': // 9 days / in 9 days / 9 days ago\n            if (withoutSuffix || isFuture) {\n                return result + (plural(number) ? 'dny' : 'dní');\n            } else {\n                return result + 'dny';\n            }\n            break;\n        case 'M':  // a month / in a month / a month ago\n            return (withoutSuffix || isFuture) ? 'měsíc' : 'měsícem';\n        case 'MM': // 9 months / in 9 months / 9 months ago\n            if (withoutSuffix || isFuture) {\n                return result + (plural(number) ? 'měsíce' : 'měsíců');\n            } else {\n                return result + 'měsíci';\n            }\n            break;\n        case 'y':  // a year / in a year / a year ago\n            return (withoutSuffix || isFuture) ? 'rok' : 'rokem';\n        case 'yy': // 9 years / in 9 years / 9 years ago\n            if (withoutSuffix || isFuture) {\n                return result + (plural(number) ? 'roky' : 'let');\n            } else {\n                return result + 'lety';\n            }\n            break;\n    }\n}\n\nvar cs = moment.defineLocale('cs', {\n    months : months,\n    monthsShort : monthsShort,\n    monthsParse : (function (months, monthsShort) {\n        var i, _monthsParse = [];\n        for (i = 0; i < 12; i++) {\n            // use custom parser to solve problem with July (červenec)\n            _monthsParse[i] = new RegExp('^' + months[i] + '$|^' + monthsShort[i] + '$', 'i');\n        }\n        return _monthsParse;\n    }(months, monthsShort)),\n    shortMonthsParse : (function (monthsShort) {\n        var i, _shortMonthsParse = [];\n        for (i = 0; i < 12; i++) {\n            _shortMonthsParse[i] = new RegExp('^' + monthsShort[i] + '$', 'i');\n        }\n        return _shortMonthsParse;\n    }(monthsShort)),\n    longMonthsParse : (function (months) {\n        var i, _longMonthsParse = [];\n        for (i = 0; i < 12; i++) {\n            _longMonthsParse[i] = new RegExp('^' + months[i] + '$', 'i');\n        }\n        return _longMonthsParse;\n    }(months)),\n    weekdays : 'neděle_pondělí_úterý_středa_čtvrtek_pátek_sobota'.split('_'),\n    weekdaysShort : 'ne_po_út_st_čt_pá_so'.split('_'),\n    weekdaysMin : 'ne_po_út_st_čt_pá_so'.split('_'),\n    longDateFormat : {\n        LT: 'H:mm',\n        LTS : 'H:mm:ss',\n        L : 'DD.MM.YYYY',\n        LL : 'D. MMMM YYYY',\n        LLL : 'D. MMMM YYYY H:mm',\n        LLLL : 'dddd D. MMMM YYYY H:mm',\n        l : 'D. M. YYYY'\n    },\n    calendar : {\n        sameDay: '[dnes v] LT',\n        nextDay: '[zítra v] LT',\n        nextWeek: function () {\n            switch (this.day()) {\n                case 0:\n                    return '[v neděli v] LT';\n                case 1:\n                case 2:\n                    return '[v] dddd [v] LT';\n                case 3:\n                    return '[ve středu v] LT';\n                case 4:\n                    return '[ve čtvrtek v] LT';\n                case 5:\n                    return '[v pátek v] LT';\n                case 6:\n                    return '[v sobotu v] LT';\n            }\n        },\n        lastDay: '[včera v] LT',\n        lastWeek: function () {\n            switch (this.day()) {\n                case 0:\n                    return '[minulou neděli v] LT';\n                case 1:\n                case 2:\n                    return '[minulé] dddd [v] LT';\n                case 3:\n                    return '[minulou středu v] LT';\n                case 4:\n                case 5:\n                    return '[minulý] dddd [v] LT';\n                case 6:\n                    return '[minulou sobotu v] LT';\n            }\n        },\n        sameElse: 'L'\n    },\n    relativeTime : {\n        future : 'za %s',\n        past : 'před %s',\n        s : translate,\n        m : translate,\n        mm : translate,\n        h : translate,\n        hh : translate,\n        d : translate,\n        dd : translate,\n        M : translate,\n        MM : translate,\n        y : translate,\n        yy : translate\n    },\n    dayOfMonthOrdinalParse : /\\d{1,2}\\./,\n    ordinal : '%d.',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\nreturn cs;\n\n})));\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/locale/cv.js",
    "content": "//! moment.js locale configuration\n//! locale : Chuvash [cv]\n//! author : Anatoly Mironov : https://github.com/mirontoli\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\n\nvar cv = moment.defineLocale('cv', {\n    months : 'кӑрлач_нарӑс_пуш_ака_май_ҫӗртме_утӑ_ҫурла_авӑн_юпа_чӳк_раштав'.split('_'),\n    monthsShort : 'кӑр_нар_пуш_ака_май_ҫӗр_утӑ_ҫур_авн_юпа_чӳк_раш'.split('_'),\n    weekdays : 'вырсарникун_тунтикун_ытларикун_юнкун_кӗҫнерникун_эрнекун_шӑматкун'.split('_'),\n    weekdaysShort : 'выр_тун_ытл_юн_кӗҫ_эрн_шӑм'.split('_'),\n    weekdaysMin : 'вр_тн_ыт_юн_кҫ_эр_шм'.split('_'),\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD-MM-YYYY',\n        LL : 'YYYY [ҫулхи] MMMM [уйӑхӗн] D[-мӗшӗ]',\n        LLL : 'YYYY [ҫулхи] MMMM [уйӑхӗн] D[-мӗшӗ], HH:mm',\n        LLLL : 'dddd, YYYY [ҫулхи] MMMM [уйӑхӗн] D[-мӗшӗ], HH:mm'\n    },\n    calendar : {\n        sameDay: '[Паян] LT [сехетре]',\n        nextDay: '[Ыран] LT [сехетре]',\n        lastDay: '[Ӗнер] LT [сехетре]',\n        nextWeek: '[Ҫитес] dddd LT [сехетре]',\n        lastWeek: '[Иртнӗ] dddd LT [сехетре]',\n        sameElse: 'L'\n    },\n    relativeTime : {\n        future : function (output) {\n            var affix = /сехет$/i.exec(output) ? 'рен' : /ҫул$/i.exec(output) ? 'тан' : 'ран';\n            return output + affix;\n        },\n        past : '%s каялла',\n        s : 'пӗр-ик ҫеккунт',\n        m : 'пӗр минут',\n        mm : '%d минут',\n        h : 'пӗр сехет',\n        hh : '%d сехет',\n        d : 'пӗр кун',\n        dd : '%d кун',\n        M : 'пӗр уйӑх',\n        MM : '%d уйӑх',\n        y : 'пӗр ҫул',\n        yy : '%d ҫул'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}-мӗш/,\n    ordinal : '%d-мӗш',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 7  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\nreturn cv;\n\n})));\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/locale/cy.js",
    "content": "//! moment.js locale configuration\n//! locale : Welsh [cy]\n//! author : Robert Allen : https://github.com/robgallen\n//! author : https://github.com/ryangreaves\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\n\nvar cy = moment.defineLocale('cy', {\n    months: 'Ionawr_Chwefror_Mawrth_Ebrill_Mai_Mehefin_Gorffennaf_Awst_Medi_Hydref_Tachwedd_Rhagfyr'.split('_'),\n    monthsShort: 'Ion_Chwe_Maw_Ebr_Mai_Meh_Gor_Aws_Med_Hyd_Tach_Rhag'.split('_'),\n    weekdays: 'Dydd Sul_Dydd Llun_Dydd Mawrth_Dydd Mercher_Dydd Iau_Dydd Gwener_Dydd Sadwrn'.split('_'),\n    weekdaysShort: 'Sul_Llun_Maw_Mer_Iau_Gwe_Sad'.split('_'),\n    weekdaysMin: 'Su_Ll_Ma_Me_Ia_Gw_Sa'.split('_'),\n    weekdaysParseExact : true,\n    // time formats are the same as en-gb\n    longDateFormat: {\n        LT: 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L: 'DD/MM/YYYY',\n        LL: 'D MMMM YYYY',\n        LLL: 'D MMMM YYYY HH:mm',\n        LLLL: 'dddd, D MMMM YYYY HH:mm'\n    },\n    calendar: {\n        sameDay: '[Heddiw am] LT',\n        nextDay: '[Yfory am] LT',\n        nextWeek: 'dddd [am] LT',\n        lastDay: '[Ddoe am] LT',\n        lastWeek: 'dddd [diwethaf am] LT',\n        sameElse: 'L'\n    },\n    relativeTime: {\n        future: 'mewn %s',\n        past: '%s yn ôl',\n        s: 'ychydig eiliadau',\n        m: 'munud',\n        mm: '%d munud',\n        h: 'awr',\n        hh: '%d awr',\n        d: 'diwrnod',\n        dd: '%d diwrnod',\n        M: 'mis',\n        MM: '%d mis',\n        y: 'blwyddyn',\n        yy: '%d flynedd'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}(fed|ain|af|il|ydd|ed|eg)/,\n    // traditional ordinal numbers above 31 are not commonly used in colloquial Welsh\n    ordinal: function (number) {\n        var b = number,\n            output = '',\n            lookup = [\n                '', 'af', 'il', 'ydd', 'ydd', 'ed', 'ed', 'ed', 'fed', 'fed', 'fed', // 1af to 10fed\n                'eg', 'fed', 'eg', 'eg', 'fed', 'eg', 'eg', 'fed', 'eg', 'fed' // 11eg to 20fed\n            ];\n        if (b > 20) {\n            if (b === 40 || b === 50 || b === 60 || b === 80 || b === 100) {\n                output = 'fed'; // not 30ain, 70ain or 90ain\n            } else {\n                output = 'ain';\n            }\n        } else if (b > 0) {\n            output = lookup[b];\n        }\n        return number + output;\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\nreturn cy;\n\n})));\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/locale/da.js",
    "content": "//! moment.js locale configuration\n//! locale : Danish [da]\n//! author : Ulrik Nielsen : https://github.com/mrbase\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\n\nvar da = moment.defineLocale('da', {\n    months : 'januar_februar_marts_april_maj_juni_juli_august_september_oktober_november_december'.split('_'),\n    monthsShort : 'jan_feb_mar_apr_maj_jun_jul_aug_sep_okt_nov_dec'.split('_'),\n    weekdays : 'søndag_mandag_tirsdag_onsdag_torsdag_fredag_lørdag'.split('_'),\n    weekdaysShort : 'søn_man_tir_ons_tor_fre_lør'.split('_'),\n    weekdaysMin : 'sø_ma_ti_on_to_fr_lø'.split('_'),\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D. MMMM YYYY',\n        LLL : 'D. MMMM YYYY HH:mm',\n        LLLL : 'dddd [d.] D. MMMM YYYY [kl.] HH:mm'\n    },\n    calendar : {\n        sameDay : '[i dag kl.] LT',\n        nextDay : '[i morgen kl.] LT',\n        nextWeek : 'på dddd [kl.] LT',\n        lastDay : '[i går kl.] LT',\n        lastWeek : '[i] dddd[s kl.] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'om %s',\n        past : '%s siden',\n        s : 'få sekunder',\n        m : 'et minut',\n        mm : '%d minutter',\n        h : 'en time',\n        hh : '%d timer',\n        d : 'en dag',\n        dd : '%d dage',\n        M : 'en måned',\n        MM : '%d måneder',\n        y : 'et år',\n        yy : '%d år'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}\\./,\n    ordinal : '%d.',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\nreturn da;\n\n})));\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/locale/de-at.js",
    "content": "//! moment.js locale configuration\n//! locale : German (Austria) [de-at]\n//! author : lluchs : https://github.com/lluchs\n//! author: Menelion Elensúle: https://github.com/Oire\n//! author : Martin Groller : https://github.com/MadMG\n//! author : Mikolaj Dadela : https://github.com/mik01aj\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\n\nfunction processRelativeTime(number, withoutSuffix, key, isFuture) {\n    var format = {\n        'm': ['eine Minute', 'einer Minute'],\n        'h': ['eine Stunde', 'einer Stunde'],\n        'd': ['ein Tag', 'einem Tag'],\n        'dd': [number + ' Tage', number + ' Tagen'],\n        'M': ['ein Monat', 'einem Monat'],\n        'MM': [number + ' Monate', number + ' Monaten'],\n        'y': ['ein Jahr', 'einem Jahr'],\n        'yy': [number + ' Jahre', number + ' Jahren']\n    };\n    return withoutSuffix ? format[key][0] : format[key][1];\n}\n\nvar deAt = moment.defineLocale('de-at', {\n    months : 'Jänner_Februar_März_April_Mai_Juni_Juli_August_September_Oktober_November_Dezember'.split('_'),\n    monthsShort : 'Jän._Febr._Mrz._Apr._Mai_Jun._Jul._Aug._Sept._Okt._Nov._Dez.'.split('_'),\n    monthsParseExact : true,\n    weekdays : 'Sonntag_Montag_Dienstag_Mittwoch_Donnerstag_Freitag_Samstag'.split('_'),\n    weekdaysShort : 'So._Mo._Di._Mi._Do._Fr._Sa.'.split('_'),\n    weekdaysMin : 'So_Mo_Di_Mi_Do_Fr_Sa'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat : {\n        LT: 'HH:mm',\n        LTS: 'HH:mm:ss',\n        L : 'DD.MM.YYYY',\n        LL : 'D. MMMM YYYY',\n        LLL : 'D. MMMM YYYY HH:mm',\n        LLLL : 'dddd, D. MMMM YYYY HH:mm'\n    },\n    calendar : {\n        sameDay: '[heute um] LT [Uhr]',\n        sameElse: 'L',\n        nextDay: '[morgen um] LT [Uhr]',\n        nextWeek: 'dddd [um] LT [Uhr]',\n        lastDay: '[gestern um] LT [Uhr]',\n        lastWeek: '[letzten] dddd [um] LT [Uhr]'\n    },\n    relativeTime : {\n        future : 'in %s',\n        past : 'vor %s',\n        s : 'ein paar Sekunden',\n        m : processRelativeTime,\n        mm : '%d Minuten',\n        h : processRelativeTime,\n        hh : '%d Stunden',\n        d : processRelativeTime,\n        dd : processRelativeTime,\n        M : processRelativeTime,\n        MM : processRelativeTime,\n        y : processRelativeTime,\n        yy : processRelativeTime\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}\\./,\n    ordinal : '%d.',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\nreturn deAt;\n\n})));\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/locale/de-ch.js",
    "content": "//! moment.js locale configuration\n//! locale : German (Switzerland) [de-ch]\n//! author : sschueller : https://github.com/sschueller\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\n\n// based on: https://www.bk.admin.ch/dokumentation/sprachen/04915/05016/index.html?lang=de#\n\nfunction processRelativeTime(number, withoutSuffix, key, isFuture) {\n    var format = {\n        'm': ['eine Minute', 'einer Minute'],\n        'h': ['eine Stunde', 'einer Stunde'],\n        'd': ['ein Tag', 'einem Tag'],\n        'dd': [number + ' Tage', number + ' Tagen'],\n        'M': ['ein Monat', 'einem Monat'],\n        'MM': [number + ' Monate', number + ' Monaten'],\n        'y': ['ein Jahr', 'einem Jahr'],\n        'yy': [number + ' Jahre', number + ' Jahren']\n    };\n    return withoutSuffix ? format[key][0] : format[key][1];\n}\n\nvar deCh = moment.defineLocale('de-ch', {\n    months : 'Januar_Februar_März_April_Mai_Juni_Juli_August_September_Oktober_November_Dezember'.split('_'),\n    monthsShort : 'Jan._Febr._März_April_Mai_Juni_Juli_Aug._Sept._Okt._Nov._Dez.'.split('_'),\n    monthsParseExact : true,\n    weekdays : 'Sonntag_Montag_Dienstag_Mittwoch_Donnerstag_Freitag_Samstag'.split('_'),\n    weekdaysShort : 'So_Mo_Di_Mi_Do_Fr_Sa'.split('_'),\n    weekdaysMin : 'So_Mo_Di_Mi_Do_Fr_Sa'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat : {\n        LT: 'HH.mm',\n        LTS: 'HH.mm.ss',\n        L : 'DD.MM.YYYY',\n        LL : 'D. MMMM YYYY',\n        LLL : 'D. MMMM YYYY HH.mm',\n        LLLL : 'dddd, D. MMMM YYYY HH.mm'\n    },\n    calendar : {\n        sameDay: '[heute um] LT [Uhr]',\n        sameElse: 'L',\n        nextDay: '[morgen um] LT [Uhr]',\n        nextWeek: 'dddd [um] LT [Uhr]',\n        lastDay: '[gestern um] LT [Uhr]',\n        lastWeek: '[letzten] dddd [um] LT [Uhr]'\n    },\n    relativeTime : {\n        future : 'in %s',\n        past : 'vor %s',\n        s : 'ein paar Sekunden',\n        m : processRelativeTime,\n        mm : '%d Minuten',\n        h : processRelativeTime,\n        hh : '%d Stunden',\n        d : processRelativeTime,\n        dd : processRelativeTime,\n        M : processRelativeTime,\n        MM : processRelativeTime,\n        y : processRelativeTime,\n        yy : processRelativeTime\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}\\./,\n    ordinal : '%d.',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\nreturn deCh;\n\n})));\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/locale/de.js",
    "content": "//! moment.js locale configuration\n//! locale : German [de]\n//! author : lluchs : https://github.com/lluchs\n//! author: Menelion Elensúle: https://github.com/Oire\n//! author : Mikolaj Dadela : https://github.com/mik01aj\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\n\nfunction processRelativeTime(number, withoutSuffix, key, isFuture) {\n    var format = {\n        'm': ['eine Minute', 'einer Minute'],\n        'h': ['eine Stunde', 'einer Stunde'],\n        'd': ['ein Tag', 'einem Tag'],\n        'dd': [number + ' Tage', number + ' Tagen'],\n        'M': ['ein Monat', 'einem Monat'],\n        'MM': [number + ' Monate', number + ' Monaten'],\n        'y': ['ein Jahr', 'einem Jahr'],\n        'yy': [number + ' Jahre', number + ' Jahren']\n    };\n    return withoutSuffix ? format[key][0] : format[key][1];\n}\n\nvar de = moment.defineLocale('de', {\n    months : 'Januar_Februar_März_April_Mai_Juni_Juli_August_September_Oktober_November_Dezember'.split('_'),\n    monthsShort : 'Jan._Febr._Mrz._Apr._Mai_Jun._Jul._Aug._Sept._Okt._Nov._Dez.'.split('_'),\n    monthsParseExact : true,\n    weekdays : 'Sonntag_Montag_Dienstag_Mittwoch_Donnerstag_Freitag_Samstag'.split('_'),\n    weekdaysShort : 'So._Mo._Di._Mi._Do._Fr._Sa.'.split('_'),\n    weekdaysMin : 'So_Mo_Di_Mi_Do_Fr_Sa'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat : {\n        LT: 'HH:mm',\n        LTS: 'HH:mm:ss',\n        L : 'DD.MM.YYYY',\n        LL : 'D. MMMM YYYY',\n        LLL : 'D. MMMM YYYY HH:mm',\n        LLLL : 'dddd, D. MMMM YYYY HH:mm'\n    },\n    calendar : {\n        sameDay: '[heute um] LT [Uhr]',\n        sameElse: 'L',\n        nextDay: '[morgen um] LT [Uhr]',\n        nextWeek: 'dddd [um] LT [Uhr]',\n        lastDay: '[gestern um] LT [Uhr]',\n        lastWeek: '[letzten] dddd [um] LT [Uhr]'\n    },\n    relativeTime : {\n        future : 'in %s',\n        past : 'vor %s',\n        s : 'ein paar Sekunden',\n        m : processRelativeTime,\n        mm : '%d Minuten',\n        h : processRelativeTime,\n        hh : '%d Stunden',\n        d : processRelativeTime,\n        dd : processRelativeTime,\n        M : processRelativeTime,\n        MM : processRelativeTime,\n        y : processRelativeTime,\n        yy : processRelativeTime\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}\\./,\n    ordinal : '%d.',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\nreturn de;\n\n})));\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/locale/dv.js",
    "content": "//! moment.js locale configuration\n//! locale : Maldivian [dv]\n//! author : Jawish Hameed : https://github.com/jawish\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\n\nvar months = [\n    'ޖެނުއަރީ',\n    'ފެބްރުއަރީ',\n    'މާރިޗު',\n    'އޭޕްރީލު',\n    'މޭ',\n    'ޖޫން',\n    'ޖުލައި',\n    'އޯގަސްޓު',\n    'ސެޕްޓެމްބަރު',\n    'އޮކްޓޯބަރު',\n    'ނޮވެމްބަރު',\n    'ޑިސެމްބަރު'\n];\nvar weekdays = [\n    'އާދިއްތަ',\n    'ހޯމަ',\n    'އަންގާރަ',\n    'ބުދަ',\n    'ބުރާސްފަތި',\n    'ހުކުރު',\n    'ހޮނިހިރު'\n];\n\nvar dv = moment.defineLocale('dv', {\n    months : months,\n    monthsShort : months,\n    weekdays : weekdays,\n    weekdaysShort : weekdays,\n    weekdaysMin : 'އާދި_ހޯމަ_އަން_ބުދަ_ބުރާ_ހުކު_ހޮނި'.split('_'),\n    longDateFormat : {\n\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'D/M/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY HH:mm',\n        LLLL : 'dddd D MMMM YYYY HH:mm'\n    },\n    meridiemParse: /މކ|މފ/,\n    isPM : function (input) {\n        return 'މފ' === input;\n    },\n    meridiem : function (hour, minute, isLower) {\n        if (hour < 12) {\n            return 'މކ';\n        } else {\n            return 'މފ';\n        }\n    },\n    calendar : {\n        sameDay : '[މިއަދު] LT',\n        nextDay : '[މާދަމާ] LT',\n        nextWeek : 'dddd LT',\n        lastDay : '[އިއްޔެ] LT',\n        lastWeek : '[ފާއިތުވި] dddd LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'ތެރޭގައި %s',\n        past : 'ކުރިން %s',\n        s : 'ސިކުންތުކޮޅެއް',\n        m : 'މިނިޓެއް',\n        mm : 'މިނިޓު %d',\n        h : 'ގަޑިއިރެއް',\n        hh : 'ގަޑިއިރު %d',\n        d : 'ދުވަހެއް',\n        dd : 'ދުވަސް %d',\n        M : 'މަހެއް',\n        MM : 'މަސް %d',\n        y : 'އަހަރެއް',\n        yy : 'އަހަރު %d'\n    },\n    preparse: function (string) {\n        return string.replace(/،/g, ',');\n    },\n    postformat: function (string) {\n        return string.replace(/,/g, '،');\n    },\n    week : {\n        dow : 7,  // Sunday is the first day of the week.\n        doy : 12  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\nreturn dv;\n\n})));\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/locale/el.js",
    "content": "//! moment.js locale configuration\n//! locale : Greek [el]\n//! author : Aggelos Karalias : https://github.com/mehiel\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction isFunction(input) {\n    return input instanceof Function || Object.prototype.toString.call(input) === '[object Function]';\n}\n\n\nvar el = moment.defineLocale('el', {\n    monthsNominativeEl : 'Ιανουάριος_Φεβρουάριος_Μάρτιος_Απρίλιος_Μάιος_Ιούνιος_Ιούλιος_Αύγουστος_Σεπτέμβριος_Οκτώβριος_Νοέμβριος_Δεκέμβριος'.split('_'),\n    monthsGenitiveEl : 'Ιανουαρίου_Φεβρουαρίου_Μαρτίου_Απριλίου_Μαΐου_Ιουνίου_Ιουλίου_Αυγούστου_Σεπτεμβρίου_Οκτωβρίου_Νοεμβρίου_Δεκεμβρίου'.split('_'),\n    months : function (momentToFormat, format) {\n        if (!momentToFormat) {\n            return this._monthsNominativeEl;\n        } else if (/D/.test(format.substring(0, format.indexOf('MMMM')))) { // if there is a day number before 'MMMM'\n            return this._monthsGenitiveEl[momentToFormat.month()];\n        } else {\n            return this._monthsNominativeEl[momentToFormat.month()];\n        }\n    },\n    monthsShort : 'Ιαν_Φεβ_Μαρ_Απρ_Μαϊ_Ιουν_Ιουλ_Αυγ_Σεπ_Οκτ_Νοε_Δεκ'.split('_'),\n    weekdays : 'Κυριακή_Δευτέρα_Τρίτη_Τετάρτη_Πέμπτη_Παρασκευή_Σάββατο'.split('_'),\n    weekdaysShort : 'Κυρ_Δευ_Τρι_Τετ_Πεμ_Παρ_Σαβ'.split('_'),\n    weekdaysMin : 'Κυ_Δε_Τρ_Τε_Πε_Πα_Σα'.split('_'),\n    meridiem : function (hours, minutes, isLower) {\n        if (hours > 11) {\n            return isLower ? 'μμ' : 'ΜΜ';\n        } else {\n            return isLower ? 'πμ' : 'ΠΜ';\n        }\n    },\n    isPM : function (input) {\n        return ((input + '').toLowerCase()[0] === 'μ');\n    },\n    meridiemParse : /[ΠΜ]\\.?Μ?\\.?/i,\n    longDateFormat : {\n        LT : 'h:mm A',\n        LTS : 'h:mm:ss A',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY h:mm A',\n        LLLL : 'dddd, D MMMM YYYY h:mm A'\n    },\n    calendarEl : {\n        sameDay : '[Σήμερα {}] LT',\n        nextDay : '[Αύριο {}] LT',\n        nextWeek : 'dddd [{}] LT',\n        lastDay : '[Χθες {}] LT',\n        lastWeek : function () {\n            switch (this.day()) {\n                case 6:\n                    return '[το προηγούμενο] dddd [{}] LT';\n                default:\n                    return '[την προηγούμενη] dddd [{}] LT';\n            }\n        },\n        sameElse : 'L'\n    },\n    calendar : function (key, mom) {\n        var output = this._calendarEl[key],\n            hours = mom && mom.hours();\n        if (isFunction(output)) {\n            output = output.apply(mom);\n        }\n        return output.replace('{}', (hours % 12 === 1 ? 'στη' : 'στις'));\n    },\n    relativeTime : {\n        future : 'σε %s',\n        past : '%s πριν',\n        s : 'λίγα δευτερόλεπτα',\n        m : 'ένα λεπτό',\n        mm : '%d λεπτά',\n        h : 'μία ώρα',\n        hh : '%d ώρες',\n        d : 'μία μέρα',\n        dd : '%d μέρες',\n        M : 'ένας μήνας',\n        MM : '%d μήνες',\n        y : 'ένας χρόνος',\n        yy : '%d χρόνια'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}η/,\n    ordinal: '%dη',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4st is the first week of the year.\n    }\n});\n\nreturn el;\n\n})));\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/locale/en-au.js",
    "content": "//! moment.js locale configuration\n//! locale : English (Australia) [en-au]\n//! author : Jared Morse : https://github.com/jarcoal\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\n\nvar enAu = moment.defineLocale('en-au', {\n    months : 'January_February_March_April_May_June_July_August_September_October_November_December'.split('_'),\n    monthsShort : 'Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec'.split('_'),\n    weekdays : 'Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday'.split('_'),\n    weekdaysShort : 'Sun_Mon_Tue_Wed_Thu_Fri_Sat'.split('_'),\n    weekdaysMin : 'Su_Mo_Tu_We_Th_Fr_Sa'.split('_'),\n    longDateFormat : {\n        LT : 'h:mm A',\n        LTS : 'h:mm:ss A',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY h:mm A',\n        LLLL : 'dddd, D MMMM YYYY h:mm A'\n    },\n    calendar : {\n        sameDay : '[Today at] LT',\n        nextDay : '[Tomorrow at] LT',\n        nextWeek : 'dddd [at] LT',\n        lastDay : '[Yesterday at] LT',\n        lastWeek : '[Last] dddd [at] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'in %s',\n        past : '%s ago',\n        s : 'a few seconds',\n        m : 'a minute',\n        mm : '%d minutes',\n        h : 'an hour',\n        hh : '%d hours',\n        d : 'a day',\n        dd : '%d days',\n        M : 'a month',\n        MM : '%d months',\n        y : 'a year',\n        yy : '%d years'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}(st|nd|rd|th)/,\n    ordinal : function (number) {\n        var b = number % 10,\n            output = (~~(number % 100 / 10) === 1) ? 'th' :\n            (b === 1) ? 'st' :\n            (b === 2) ? 'nd' :\n            (b === 3) ? 'rd' : 'th';\n        return number + output;\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\nreturn enAu;\n\n})));\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/locale/en-ca.js",
    "content": "//! moment.js locale configuration\n//! locale : English (Canada) [en-ca]\n//! author : Jonathan Abourbih : https://github.com/jonbca\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\n\nvar enCa = moment.defineLocale('en-ca', {\n    months : 'January_February_March_April_May_June_July_August_September_October_November_December'.split('_'),\n    monthsShort : 'Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec'.split('_'),\n    weekdays : 'Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday'.split('_'),\n    weekdaysShort : 'Sun_Mon_Tue_Wed_Thu_Fri_Sat'.split('_'),\n    weekdaysMin : 'Su_Mo_Tu_We_Th_Fr_Sa'.split('_'),\n    longDateFormat : {\n        LT : 'h:mm A',\n        LTS : 'h:mm:ss A',\n        L : 'YYYY-MM-DD',\n        LL : 'MMMM D, YYYY',\n        LLL : 'MMMM D, YYYY h:mm A',\n        LLLL : 'dddd, MMMM D, YYYY h:mm A'\n    },\n    calendar : {\n        sameDay : '[Today at] LT',\n        nextDay : '[Tomorrow at] LT',\n        nextWeek : 'dddd [at] LT',\n        lastDay : '[Yesterday at] LT',\n        lastWeek : '[Last] dddd [at] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'in %s',\n        past : '%s ago',\n        s : 'a few seconds',\n        m : 'a minute',\n        mm : '%d minutes',\n        h : 'an hour',\n        hh : '%d hours',\n        d : 'a day',\n        dd : '%d days',\n        M : 'a month',\n        MM : '%d months',\n        y : 'a year',\n        yy : '%d years'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}(st|nd|rd|th)/,\n    ordinal : function (number) {\n        var b = number % 10,\n            output = (~~(number % 100 / 10) === 1) ? 'th' :\n            (b === 1) ? 'st' :\n            (b === 2) ? 'nd' :\n            (b === 3) ? 'rd' : 'th';\n        return number + output;\n    }\n});\n\nreturn enCa;\n\n})));\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/locale/en-gb.js",
    "content": "//! moment.js locale configuration\n//! locale : English (United Kingdom) [en-gb]\n//! author : Chris Gedrim : https://github.com/chrisgedrim\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\n\nvar enGb = moment.defineLocale('en-gb', {\n    months : 'January_February_March_April_May_June_July_August_September_October_November_December'.split('_'),\n    monthsShort : 'Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec'.split('_'),\n    weekdays : 'Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday'.split('_'),\n    weekdaysShort : 'Sun_Mon_Tue_Wed_Thu_Fri_Sat'.split('_'),\n    weekdaysMin : 'Su_Mo_Tu_We_Th_Fr_Sa'.split('_'),\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY HH:mm',\n        LLLL : 'dddd, D MMMM YYYY HH:mm'\n    },\n    calendar : {\n        sameDay : '[Today at] LT',\n        nextDay : '[Tomorrow at] LT',\n        nextWeek : 'dddd [at] LT',\n        lastDay : '[Yesterday at] LT',\n        lastWeek : '[Last] dddd [at] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'in %s',\n        past : '%s ago',\n        s : 'a few seconds',\n        m : 'a minute',\n        mm : '%d minutes',\n        h : 'an hour',\n        hh : '%d hours',\n        d : 'a day',\n        dd : '%d days',\n        M : 'a month',\n        MM : '%d months',\n        y : 'a year',\n        yy : '%d years'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}(st|nd|rd|th)/,\n    ordinal : function (number) {\n        var b = number % 10,\n            output = (~~(number % 100 / 10) === 1) ? 'th' :\n            (b === 1) ? 'st' :\n            (b === 2) ? 'nd' :\n            (b === 3) ? 'rd' : 'th';\n        return number + output;\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\nreturn enGb;\n\n})));\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/locale/en-ie.js",
    "content": "//! moment.js locale configuration\n//! locale : English (Ireland) [en-ie]\n//! author : Chris Cartlidge : https://github.com/chriscartlidge\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\n\nvar enIe = moment.defineLocale('en-ie', {\n    months : 'January_February_March_April_May_June_July_August_September_October_November_December'.split('_'),\n    monthsShort : 'Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec'.split('_'),\n    weekdays : 'Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday'.split('_'),\n    weekdaysShort : 'Sun_Mon_Tue_Wed_Thu_Fri_Sat'.split('_'),\n    weekdaysMin : 'Su_Mo_Tu_We_Th_Fr_Sa'.split('_'),\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD-MM-YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY HH:mm',\n        LLLL : 'dddd D MMMM YYYY HH:mm'\n    },\n    calendar : {\n        sameDay : '[Today at] LT',\n        nextDay : '[Tomorrow at] LT',\n        nextWeek : 'dddd [at] LT',\n        lastDay : '[Yesterday at] LT',\n        lastWeek : '[Last] dddd [at] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'in %s',\n        past : '%s ago',\n        s : 'a few seconds',\n        m : 'a minute',\n        mm : '%d minutes',\n        h : 'an hour',\n        hh : '%d hours',\n        d : 'a day',\n        dd : '%d days',\n        M : 'a month',\n        MM : '%d months',\n        y : 'a year',\n        yy : '%d years'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}(st|nd|rd|th)/,\n    ordinal : function (number) {\n        var b = number % 10,\n            output = (~~(number % 100 / 10) === 1) ? 'th' :\n            (b === 1) ? 'st' :\n            (b === 2) ? 'nd' :\n            (b === 3) ? 'rd' : 'th';\n        return number + output;\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\nreturn enIe;\n\n})));\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/locale/en-nz.js",
    "content": "//! moment.js locale configuration\n//! locale : English (New Zealand) [en-nz]\n//! author : Luke McGregor : https://github.com/lukemcgregor\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\n\nvar enNz = moment.defineLocale('en-nz', {\n    months : 'January_February_March_April_May_June_July_August_September_October_November_December'.split('_'),\n    monthsShort : 'Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec'.split('_'),\n    weekdays : 'Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday'.split('_'),\n    weekdaysShort : 'Sun_Mon_Tue_Wed_Thu_Fri_Sat'.split('_'),\n    weekdaysMin : 'Su_Mo_Tu_We_Th_Fr_Sa'.split('_'),\n    longDateFormat : {\n        LT : 'h:mm A',\n        LTS : 'h:mm:ss A',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY h:mm A',\n        LLLL : 'dddd, D MMMM YYYY h:mm A'\n    },\n    calendar : {\n        sameDay : '[Today at] LT',\n        nextDay : '[Tomorrow at] LT',\n        nextWeek : 'dddd [at] LT',\n        lastDay : '[Yesterday at] LT',\n        lastWeek : '[Last] dddd [at] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'in %s',\n        past : '%s ago',\n        s : 'a few seconds',\n        m : 'a minute',\n        mm : '%d minutes',\n        h : 'an hour',\n        hh : '%d hours',\n        d : 'a day',\n        dd : '%d days',\n        M : 'a month',\n        MM : '%d months',\n        y : 'a year',\n        yy : '%d years'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}(st|nd|rd|th)/,\n    ordinal : function (number) {\n        var b = number % 10,\n            output = (~~(number % 100 / 10) === 1) ? 'th' :\n            (b === 1) ? 'st' :\n            (b === 2) ? 'nd' :\n            (b === 3) ? 'rd' : 'th';\n        return number + output;\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\nreturn enNz;\n\n})));\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/locale/eo.js",
    "content": "//! moment.js locale configuration\n//! locale : Esperanto [eo]\n//! author : Colin Dean : https://github.com/colindean\n//! author : Mia Nordentoft Imperatori : https://github.com/miestasmia\n//! comment : miestasmia corrected the translation by colindean\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\n\nvar eo = moment.defineLocale('eo', {\n    months : 'januaro_februaro_marto_aprilo_majo_junio_julio_aŭgusto_septembro_oktobro_novembro_decembro'.split('_'),\n    monthsShort : 'jan_feb_mar_apr_maj_jun_jul_aŭg_sep_okt_nov_dec'.split('_'),\n    weekdays : 'dimanĉo_lundo_mardo_merkredo_ĵaŭdo_vendredo_sabato'.split('_'),\n    weekdaysShort : 'dim_lun_mard_merk_ĵaŭ_ven_sab'.split('_'),\n    weekdaysMin : 'di_lu_ma_me_ĵa_ve_sa'.split('_'),\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'YYYY-MM-DD',\n        LL : 'D[-a de] MMMM, YYYY',\n        LLL : 'D[-a de] MMMM, YYYY HH:mm',\n        LLLL : 'dddd, [la] D[-a de] MMMM, YYYY HH:mm'\n    },\n    meridiemParse: /[ap]\\.t\\.m/i,\n    isPM: function (input) {\n        return input.charAt(0).toLowerCase() === 'p';\n    },\n    meridiem : function (hours, minutes, isLower) {\n        if (hours > 11) {\n            return isLower ? 'p.t.m.' : 'P.T.M.';\n        } else {\n            return isLower ? 'a.t.m.' : 'A.T.M.';\n        }\n    },\n    calendar : {\n        sameDay : '[Hodiaŭ je] LT',\n        nextDay : '[Morgaŭ je] LT',\n        nextWeek : 'dddd [je] LT',\n        lastDay : '[Hieraŭ je] LT',\n        lastWeek : '[pasinta] dddd [je] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'post %s',\n        past : 'antaŭ %s',\n        s : 'sekundoj',\n        m : 'minuto',\n        mm : '%d minutoj',\n        h : 'horo',\n        hh : '%d horoj',\n        d : 'tago',//ne 'diurno', ĉar estas uzita por proksimumo\n        dd : '%d tagoj',\n        M : 'monato',\n        MM : '%d monatoj',\n        y : 'jaro',\n        yy : '%d jaroj'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}a/,\n    ordinal : '%da',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 7  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\nreturn eo;\n\n})));\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/locale/es-do.js",
    "content": "//! moment.js locale configuration\n//! locale : Spanish (Dominican Republic) [es-do]\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\n\nvar monthsShortDot = 'ene._feb._mar._abr._may._jun._jul._ago._sep._oct._nov._dic.'.split('_');\nvar monthsShort = 'ene_feb_mar_abr_may_jun_jul_ago_sep_oct_nov_dic'.split('_');\n\nvar esDo = moment.defineLocale('es-do', {\n    months : 'enero_febrero_marzo_abril_mayo_junio_julio_agosto_septiembre_octubre_noviembre_diciembre'.split('_'),\n    monthsShort : function (m, format) {\n        if (!m) {\n            return monthsShortDot;\n        } else if (/-MMM-/.test(format)) {\n            return monthsShort[m.month()];\n        } else {\n            return monthsShortDot[m.month()];\n        }\n    },\n    monthsParseExact : true,\n    weekdays : 'domingo_lunes_martes_miércoles_jueves_viernes_sábado'.split('_'),\n    weekdaysShort : 'dom._lun._mar._mié._jue._vie._sáb.'.split('_'),\n    weekdaysMin : 'do_lu_ma_mi_ju_vi_sá'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat : {\n        LT : 'h:mm A',\n        LTS : 'h:mm:ss A',\n        L : 'DD/MM/YYYY',\n        LL : 'D [de] MMMM [de] YYYY',\n        LLL : 'D [de] MMMM [de] YYYY h:mm A',\n        LLLL : 'dddd, D [de] MMMM [de] YYYY h:mm A'\n    },\n    calendar : {\n        sameDay : function () {\n            return '[hoy a la' + ((this.hours() !== 1) ? 's' : '') + '] LT';\n        },\n        nextDay : function () {\n            return '[mañana a la' + ((this.hours() !== 1) ? 's' : '') + '] LT';\n        },\n        nextWeek : function () {\n            return 'dddd [a la' + ((this.hours() !== 1) ? 's' : '') + '] LT';\n        },\n        lastDay : function () {\n            return '[ayer a la' + ((this.hours() !== 1) ? 's' : '') + '] LT';\n        },\n        lastWeek : function () {\n            return '[el] dddd [pasado a la' + ((this.hours() !== 1) ? 's' : '') + '] LT';\n        },\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'en %s',\n        past : 'hace %s',\n        s : 'unos segundos',\n        m : 'un minuto',\n        mm : '%d minutos',\n        h : 'una hora',\n        hh : '%d horas',\n        d : 'un día',\n        dd : '%d días',\n        M : 'un mes',\n        MM : '%d meses',\n        y : 'un año',\n        yy : '%d años'\n    },\n    dayOfMonthOrdinalParse : /\\d{1,2}º/,\n    ordinal : '%dº',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\nreturn esDo;\n\n})));\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/locale/es.js",
    "content": "//! moment.js locale configuration\n//! locale : Spanish [es]\n//! author : Julio Napurí : https://github.com/julionc\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\n\nvar monthsShortDot = 'ene._feb._mar._abr._may._jun._jul._ago._sep._oct._nov._dic.'.split('_');\nvar monthsShort = 'ene_feb_mar_abr_may_jun_jul_ago_sep_oct_nov_dic'.split('_');\n\nvar es = moment.defineLocale('es', {\n    months : 'enero_febrero_marzo_abril_mayo_junio_julio_agosto_septiembre_octubre_noviembre_diciembre'.split('_'),\n    monthsShort : function (m, format) {\n        if (!m) {\n            return monthsShortDot;\n        } else if (/-MMM-/.test(format)) {\n            return monthsShort[m.month()];\n        } else {\n            return monthsShortDot[m.month()];\n        }\n    },\n    monthsParseExact : true,\n    weekdays : 'domingo_lunes_martes_miércoles_jueves_viernes_sábado'.split('_'),\n    weekdaysShort : 'dom._lun._mar._mié._jue._vie._sáb.'.split('_'),\n    weekdaysMin : 'do_lu_ma_mi_ju_vi_sá'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat : {\n        LT : 'H:mm',\n        LTS : 'H:mm:ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D [de] MMMM [de] YYYY',\n        LLL : 'D [de] MMMM [de] YYYY H:mm',\n        LLLL : 'dddd, D [de] MMMM [de] YYYY H:mm'\n    },\n    calendar : {\n        sameDay : function () {\n            return '[hoy a la' + ((this.hours() !== 1) ? 's' : '') + '] LT';\n        },\n        nextDay : function () {\n            return '[mañana a la' + ((this.hours() !== 1) ? 's' : '') + '] LT';\n        },\n        nextWeek : function () {\n            return 'dddd [a la' + ((this.hours() !== 1) ? 's' : '') + '] LT';\n        },\n        lastDay : function () {\n            return '[ayer a la' + ((this.hours() !== 1) ? 's' : '') + '] LT';\n        },\n        lastWeek : function () {\n            return '[el] dddd [pasado a la' + ((this.hours() !== 1) ? 's' : '') + '] LT';\n        },\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'en %s',\n        past : 'hace %s',\n        s : 'unos segundos',\n        m : 'un minuto',\n        mm : '%d minutos',\n        h : 'una hora',\n        hh : '%d horas',\n        d : 'un día',\n        dd : '%d días',\n        M : 'un mes',\n        MM : '%d meses',\n        y : 'un año',\n        yy : '%d años'\n    },\n    dayOfMonthOrdinalParse : /\\d{1,2}º/,\n    ordinal : '%dº',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\nreturn es;\n\n})));\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/locale/et.js",
    "content": "//! moment.js locale configuration\n//! locale : Estonian [et]\n//! author : Henry Kehlmann : https://github.com/madhenry\n//! improvements : Illimar Tambek : https://github.com/ragulka\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\n\nfunction processRelativeTime(number, withoutSuffix, key, isFuture) {\n    var format = {\n        's' : ['mõne sekundi', 'mõni sekund', 'paar sekundit'],\n        'm' : ['ühe minuti', 'üks minut'],\n        'mm': [number + ' minuti', number + ' minutit'],\n        'h' : ['ühe tunni', 'tund aega', 'üks tund'],\n        'hh': [number + ' tunni', number + ' tundi'],\n        'd' : ['ühe päeva', 'üks päev'],\n        'M' : ['kuu aja', 'kuu aega', 'üks kuu'],\n        'MM': [number + ' kuu', number + ' kuud'],\n        'y' : ['ühe aasta', 'aasta', 'üks aasta'],\n        'yy': [number + ' aasta', number + ' aastat']\n    };\n    if (withoutSuffix) {\n        return format[key][2] ? format[key][2] : format[key][1];\n    }\n    return isFuture ? format[key][0] : format[key][1];\n}\n\nvar et = moment.defineLocale('et', {\n    months        : 'jaanuar_veebruar_märts_aprill_mai_juuni_juuli_august_september_oktoober_november_detsember'.split('_'),\n    monthsShort   : 'jaan_veebr_märts_apr_mai_juuni_juuli_aug_sept_okt_nov_dets'.split('_'),\n    weekdays      : 'pühapäev_esmaspäev_teisipäev_kolmapäev_neljapäev_reede_laupäev'.split('_'),\n    weekdaysShort : 'P_E_T_K_N_R_L'.split('_'),\n    weekdaysMin   : 'P_E_T_K_N_R_L'.split('_'),\n    longDateFormat : {\n        LT   : 'H:mm',\n        LTS : 'H:mm:ss',\n        L    : 'DD.MM.YYYY',\n        LL   : 'D. MMMM YYYY',\n        LLL  : 'D. MMMM YYYY H:mm',\n        LLLL : 'dddd, D. MMMM YYYY H:mm'\n    },\n    calendar : {\n        sameDay  : '[Täna,] LT',\n        nextDay  : '[Homme,] LT',\n        nextWeek : '[Järgmine] dddd LT',\n        lastDay  : '[Eile,] LT',\n        lastWeek : '[Eelmine] dddd LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : '%s pärast',\n        past   : '%s tagasi',\n        s      : processRelativeTime,\n        m      : processRelativeTime,\n        mm     : processRelativeTime,\n        h      : processRelativeTime,\n        hh     : processRelativeTime,\n        d      : processRelativeTime,\n        dd     : '%d päeva',\n        M      : processRelativeTime,\n        MM     : processRelativeTime,\n        y      : processRelativeTime,\n        yy     : processRelativeTime\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}\\./,\n    ordinal : '%d.',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\nreturn et;\n\n})));\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/locale/eu.js",
    "content": "//! moment.js locale configuration\n//! locale : Basque [eu]\n//! author : Eneko Illarramendi : https://github.com/eillarra\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\n\nvar eu = moment.defineLocale('eu', {\n    months : 'urtarrila_otsaila_martxoa_apirila_maiatza_ekaina_uztaila_abuztua_iraila_urria_azaroa_abendua'.split('_'),\n    monthsShort : 'urt._ots._mar._api._mai._eka._uzt._abu._ira._urr._aza._abe.'.split('_'),\n    monthsParseExact : true,\n    weekdays : 'igandea_astelehena_asteartea_asteazkena_osteguna_ostirala_larunbata'.split('_'),\n    weekdaysShort : 'ig._al._ar._az._og._ol._lr.'.split('_'),\n    weekdaysMin : 'ig_al_ar_az_og_ol_lr'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'YYYY-MM-DD',\n        LL : 'YYYY[ko] MMMM[ren] D[a]',\n        LLL : 'YYYY[ko] MMMM[ren] D[a] HH:mm',\n        LLLL : 'dddd, YYYY[ko] MMMM[ren] D[a] HH:mm',\n        l : 'YYYY-M-D',\n        ll : 'YYYY[ko] MMM D[a]',\n        lll : 'YYYY[ko] MMM D[a] HH:mm',\n        llll : 'ddd, YYYY[ko] MMM D[a] HH:mm'\n    },\n    calendar : {\n        sameDay : '[gaur] LT[etan]',\n        nextDay : '[bihar] LT[etan]',\n        nextWeek : 'dddd LT[etan]',\n        lastDay : '[atzo] LT[etan]',\n        lastWeek : '[aurreko] dddd LT[etan]',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : '%s barru',\n        past : 'duela %s',\n        s : 'segundo batzuk',\n        m : 'minutu bat',\n        mm : '%d minutu',\n        h : 'ordu bat',\n        hh : '%d ordu',\n        d : 'egun bat',\n        dd : '%d egun',\n        M : 'hilabete bat',\n        MM : '%d hilabete',\n        y : 'urte bat',\n        yy : '%d urte'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}\\./,\n    ordinal : '%d.',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 7  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\nreturn eu;\n\n})));\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/locale/fa.js",
    "content": "//! moment.js locale configuration\n//! locale : Persian [fa]\n//! author : Ebrahim Byagowi : https://github.com/ebraminio\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\n\nvar symbolMap = {\n    '1': '۱',\n    '2': '۲',\n    '3': '۳',\n    '4': '۴',\n    '5': '۵',\n    '6': '۶',\n    '7': '۷',\n    '8': '۸',\n    '9': '۹',\n    '0': '۰'\n};\nvar numberMap = {\n    '۱': '1',\n    '۲': '2',\n    '۳': '3',\n    '۴': '4',\n    '۵': '5',\n    '۶': '6',\n    '۷': '7',\n    '۸': '8',\n    '۹': '9',\n    '۰': '0'\n};\n\nvar fa = moment.defineLocale('fa', {\n    months : 'ژانویه_فوریه_مارس_آوریل_مه_ژوئن_ژوئیه_اوت_سپتامبر_اکتبر_نوامبر_دسامبر'.split('_'),\n    monthsShort : 'ژانویه_فوریه_مارس_آوریل_مه_ژوئن_ژوئیه_اوت_سپتامبر_اکتبر_نوامبر_دسامبر'.split('_'),\n    weekdays : 'یک\\u200cشنبه_دوشنبه_سه\\u200cشنبه_چهارشنبه_پنج\\u200cشنبه_جمعه_شنبه'.split('_'),\n    weekdaysShort : 'یک\\u200cشنبه_دوشنبه_سه\\u200cشنبه_چهارشنبه_پنج\\u200cشنبه_جمعه_شنبه'.split('_'),\n    weekdaysMin : 'ی_د_س_چ_پ_ج_ش'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY HH:mm',\n        LLLL : 'dddd, D MMMM YYYY HH:mm'\n    },\n    meridiemParse: /قبل از ظهر|بعد از ظهر/,\n    isPM: function (input) {\n        return /بعد از ظهر/.test(input);\n    },\n    meridiem : function (hour, minute, isLower) {\n        if (hour < 12) {\n            return 'قبل از ظهر';\n        } else {\n            return 'بعد از ظهر';\n        }\n    },\n    calendar : {\n        sameDay : '[امروز ساعت] LT',\n        nextDay : '[فردا ساعت] LT',\n        nextWeek : 'dddd [ساعت] LT',\n        lastDay : '[دیروز ساعت] LT',\n        lastWeek : 'dddd [پیش] [ساعت] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'در %s',\n        past : '%s پیش',\n        s : 'چند ثانیه',\n        m : 'یک دقیقه',\n        mm : '%d دقیقه',\n        h : 'یک ساعت',\n        hh : '%d ساعت',\n        d : 'یک روز',\n        dd : '%d روز',\n        M : 'یک ماه',\n        MM : '%d ماه',\n        y : 'یک سال',\n        yy : '%d سال'\n    },\n    preparse: function (string) {\n        return string.replace(/[۰-۹]/g, function (match) {\n            return numberMap[match];\n        }).replace(/،/g, ',');\n    },\n    postformat: function (string) {\n        return string.replace(/\\d/g, function (match) {\n            return symbolMap[match];\n        }).replace(/,/g, '،');\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}م/,\n    ordinal : '%dم',\n    week : {\n        dow : 6, // Saturday is the first day of the week.\n        doy : 12 // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\nreturn fa;\n\n})));\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/locale/fi.js",
    "content": "//! moment.js locale configuration\n//! locale : Finnish [fi]\n//! author : Tarmo Aidantausta : https://github.com/bleadof\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\n\nvar numbersPast = 'nolla yksi kaksi kolme neljä viisi kuusi seitsemän kahdeksan yhdeksän'.split(' ');\nvar numbersFuture = [\n        'nolla', 'yhden', 'kahden', 'kolmen', 'neljän', 'viiden', 'kuuden',\n        numbersPast[7], numbersPast[8], numbersPast[9]\n    ];\nfunction translate(number, withoutSuffix, key, isFuture) {\n    var result = '';\n    switch (key) {\n        case 's':\n            return isFuture ? 'muutaman sekunnin' : 'muutama sekunti';\n        case 'm':\n            return isFuture ? 'minuutin' : 'minuutti';\n        case 'mm':\n            result = isFuture ? 'minuutin' : 'minuuttia';\n            break;\n        case 'h':\n            return isFuture ? 'tunnin' : 'tunti';\n        case 'hh':\n            result = isFuture ? 'tunnin' : 'tuntia';\n            break;\n        case 'd':\n            return isFuture ? 'päivän' : 'päivä';\n        case 'dd':\n            result = isFuture ? 'päivän' : 'päivää';\n            break;\n        case 'M':\n            return isFuture ? 'kuukauden' : 'kuukausi';\n        case 'MM':\n            result = isFuture ? 'kuukauden' : 'kuukautta';\n            break;\n        case 'y':\n            return isFuture ? 'vuoden' : 'vuosi';\n        case 'yy':\n            result = isFuture ? 'vuoden' : 'vuotta';\n            break;\n    }\n    result = verbalNumber(number, isFuture) + ' ' + result;\n    return result;\n}\nfunction verbalNumber(number, isFuture) {\n    return number < 10 ? (isFuture ? numbersFuture[number] : numbersPast[number]) : number;\n}\n\nvar fi = moment.defineLocale('fi', {\n    months : 'tammikuu_helmikuu_maaliskuu_huhtikuu_toukokuu_kesäkuu_heinäkuu_elokuu_syyskuu_lokakuu_marraskuu_joulukuu'.split('_'),\n    monthsShort : 'tammi_helmi_maalis_huhti_touko_kesä_heinä_elo_syys_loka_marras_joulu'.split('_'),\n    weekdays : 'sunnuntai_maanantai_tiistai_keskiviikko_torstai_perjantai_lauantai'.split('_'),\n    weekdaysShort : 'su_ma_ti_ke_to_pe_la'.split('_'),\n    weekdaysMin : 'su_ma_ti_ke_to_pe_la'.split('_'),\n    longDateFormat : {\n        LT : 'HH.mm',\n        LTS : 'HH.mm.ss',\n        L : 'DD.MM.YYYY',\n        LL : 'Do MMMM[ta] YYYY',\n        LLL : 'Do MMMM[ta] YYYY, [klo] HH.mm',\n        LLLL : 'dddd, Do MMMM[ta] YYYY, [klo] HH.mm',\n        l : 'D.M.YYYY',\n        ll : 'Do MMM YYYY',\n        lll : 'Do MMM YYYY, [klo] HH.mm',\n        llll : 'ddd, Do MMM YYYY, [klo] HH.mm'\n    },\n    calendar : {\n        sameDay : '[tänään] [klo] LT',\n        nextDay : '[huomenna] [klo] LT',\n        nextWeek : 'dddd [klo] LT',\n        lastDay : '[eilen] [klo] LT',\n        lastWeek : '[viime] dddd[na] [klo] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : '%s päästä',\n        past : '%s sitten',\n        s : translate,\n        m : translate,\n        mm : translate,\n        h : translate,\n        hh : translate,\n        d : translate,\n        dd : translate,\n        M : translate,\n        MM : translate,\n        y : translate,\n        yy : translate\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}\\./,\n    ordinal : '%d.',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\nreturn fi;\n\n})));\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/locale/fo.js",
    "content": "//! moment.js locale configuration\n//! locale : Faroese [fo]\n//! author : Ragnar Johannesen : https://github.com/ragnar123\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\n\nvar fo = moment.defineLocale('fo', {\n    months : 'januar_februar_mars_apríl_mai_juni_juli_august_september_oktober_november_desember'.split('_'),\n    monthsShort : 'jan_feb_mar_apr_mai_jun_jul_aug_sep_okt_nov_des'.split('_'),\n    weekdays : 'sunnudagur_mánadagur_týsdagur_mikudagur_hósdagur_fríggjadagur_leygardagur'.split('_'),\n    weekdaysShort : 'sun_mán_týs_mik_hós_frí_ley'.split('_'),\n    weekdaysMin : 'su_má_tý_mi_hó_fr_le'.split('_'),\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY HH:mm',\n        LLLL : 'dddd D. MMMM, YYYY HH:mm'\n    },\n    calendar : {\n        sameDay : '[Í dag kl.] LT',\n        nextDay : '[Í morgin kl.] LT',\n        nextWeek : 'dddd [kl.] LT',\n        lastDay : '[Í gjár kl.] LT',\n        lastWeek : '[síðstu] dddd [kl] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'um %s',\n        past : '%s síðani',\n        s : 'fá sekund',\n        m : 'ein minutt',\n        mm : '%d minuttir',\n        h : 'ein tími',\n        hh : '%d tímar',\n        d : 'ein dagur',\n        dd : '%d dagar',\n        M : 'ein mánaði',\n        MM : '%d mánaðir',\n        y : 'eitt ár',\n        yy : '%d ár'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}\\./,\n    ordinal : '%d.',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\nreturn fo;\n\n})));\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/locale/fr-ca.js",
    "content": "//! moment.js locale configuration\n//! locale : French (Canada) [fr-ca]\n//! author : Jonathan Abourbih : https://github.com/jonbca\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\n\nvar frCa = moment.defineLocale('fr-ca', {\n    months : 'janvier_février_mars_avril_mai_juin_juillet_août_septembre_octobre_novembre_décembre'.split('_'),\n    monthsShort : 'janv._févr._mars_avr._mai_juin_juil._août_sept._oct._nov._déc.'.split('_'),\n    monthsParseExact : true,\n    weekdays : 'dimanche_lundi_mardi_mercredi_jeudi_vendredi_samedi'.split('_'),\n    weekdaysShort : 'dim._lun._mar._mer._jeu._ven._sam.'.split('_'),\n    weekdaysMin : 'Di_Lu_Ma_Me_Je_Ve_Sa'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'YYYY-MM-DD',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY HH:mm',\n        LLLL : 'dddd D MMMM YYYY HH:mm'\n    },\n    calendar : {\n        sameDay : '[Aujourd’hui à] LT',\n        nextDay : '[Demain à] LT',\n        nextWeek : 'dddd [à] LT',\n        lastDay : '[Hier à] LT',\n        lastWeek : 'dddd [dernier à] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'dans %s',\n        past : 'il y a %s',\n        s : 'quelques secondes',\n        m : 'une minute',\n        mm : '%d minutes',\n        h : 'une heure',\n        hh : '%d heures',\n        d : 'un jour',\n        dd : '%d jours',\n        M : 'un mois',\n        MM : '%d mois',\n        y : 'un an',\n        yy : '%d ans'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}(er|e)/,\n    ordinal : function (number, period) {\n        switch (period) {\n            // Words with masculine grammatical gender: mois, trimestre, jour\n            default:\n            case 'M':\n            case 'Q':\n            case 'D':\n            case 'DDD':\n            case 'd':\n                return number + (number === 1 ? 'er' : 'e');\n\n            // Words with feminine grammatical gender: semaine\n            case 'w':\n            case 'W':\n                return number + (number === 1 ? 're' : 'e');\n        }\n    }\n});\n\nreturn frCa;\n\n})));\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/locale/fr-ch.js",
    "content": "//! moment.js locale configuration\n//! locale : French (Switzerland) [fr-ch]\n//! author : Gaspard Bucher : https://github.com/gaspard\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\n\nvar frCh = moment.defineLocale('fr-ch', {\n    months : 'janvier_février_mars_avril_mai_juin_juillet_août_septembre_octobre_novembre_décembre'.split('_'),\n    monthsShort : 'janv._févr._mars_avr._mai_juin_juil._août_sept._oct._nov._déc.'.split('_'),\n    monthsParseExact : true,\n    weekdays : 'dimanche_lundi_mardi_mercredi_jeudi_vendredi_samedi'.split('_'),\n    weekdaysShort : 'dim._lun._mar._mer._jeu._ven._sam.'.split('_'),\n    weekdaysMin : 'Di_Lu_Ma_Me_Je_Ve_Sa'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD.MM.YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY HH:mm',\n        LLLL : 'dddd D MMMM YYYY HH:mm'\n    },\n    calendar : {\n        sameDay : '[Aujourd’hui à] LT',\n        nextDay : '[Demain à] LT',\n        nextWeek : 'dddd [à] LT',\n        lastDay : '[Hier à] LT',\n        lastWeek : 'dddd [dernier à] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'dans %s',\n        past : 'il y a %s',\n        s : 'quelques secondes',\n        m : 'une minute',\n        mm : '%d minutes',\n        h : 'une heure',\n        hh : '%d heures',\n        d : 'un jour',\n        dd : '%d jours',\n        M : 'un mois',\n        MM : '%d mois',\n        y : 'un an',\n        yy : '%d ans'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}(er|e)/,\n    ordinal : function (number, period) {\n        switch (period) {\n            // Words with masculine grammatical gender: mois, trimestre, jour\n            default:\n            case 'M':\n            case 'Q':\n            case 'D':\n            case 'DDD':\n            case 'd':\n                return number + (number === 1 ? 'er' : 'e');\n\n            // Words with feminine grammatical gender: semaine\n            case 'w':\n            case 'W':\n                return number + (number === 1 ? 're' : 'e');\n        }\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\nreturn frCh;\n\n})));\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/locale/fr.js",
    "content": "//! moment.js locale configuration\n//! locale : French [fr]\n//! author : John Fischer : https://github.com/jfroffice\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\n\nvar fr = moment.defineLocale('fr', {\n    months : 'janvier_février_mars_avril_mai_juin_juillet_août_septembre_octobre_novembre_décembre'.split('_'),\n    monthsShort : 'janv._févr._mars_avr._mai_juin_juil._août_sept._oct._nov._déc.'.split('_'),\n    monthsParseExact : true,\n    weekdays : 'dimanche_lundi_mardi_mercredi_jeudi_vendredi_samedi'.split('_'),\n    weekdaysShort : 'dim._lun._mar._mer._jeu._ven._sam.'.split('_'),\n    weekdaysMin : 'Di_Lu_Ma_Me_Je_Ve_Sa'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY HH:mm',\n        LLLL : 'dddd D MMMM YYYY HH:mm'\n    },\n    calendar : {\n        sameDay : '[Aujourd’hui à] LT',\n        nextDay : '[Demain à] LT',\n        nextWeek : 'dddd [à] LT',\n        lastDay : '[Hier à] LT',\n        lastWeek : 'dddd [dernier à] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'dans %s',\n        past : 'il y a %s',\n        s : 'quelques secondes',\n        m : 'une minute',\n        mm : '%d minutes',\n        h : 'une heure',\n        hh : '%d heures',\n        d : 'un jour',\n        dd : '%d jours',\n        M : 'un mois',\n        MM : '%d mois',\n        y : 'un an',\n        yy : '%d ans'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}(er|)/,\n    ordinal : function (number, period) {\n        switch (period) {\n            // TODO: Return 'e' when day of month > 1. Move this case inside\n            // block for masculine words below.\n            // See https://github.com/moment/moment/issues/3375\n            case 'D':\n                return number + (number === 1 ? 'er' : '');\n\n            // Words with masculine grammatical gender: mois, trimestre, jour\n            default:\n            case 'M':\n            case 'Q':\n            case 'DDD':\n            case 'd':\n                return number + (number === 1 ? 'er' : 'e');\n\n            // Words with feminine grammatical gender: semaine\n            case 'w':\n            case 'W':\n                return number + (number === 1 ? 're' : 'e');\n        }\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\nreturn fr;\n\n})));\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/locale/fy.js",
    "content": "//! moment.js locale configuration\n//! locale : Frisian [fy]\n//! author : Robin van der Vliet : https://github.com/robin0van0der0v\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\n\nvar monthsShortWithDots = 'jan._feb._mrt._apr._mai_jun._jul._aug._sep._okt._nov._des.'.split('_');\nvar monthsShortWithoutDots = 'jan_feb_mrt_apr_mai_jun_jul_aug_sep_okt_nov_des'.split('_');\n\nvar fy = moment.defineLocale('fy', {\n    months : 'jannewaris_febrewaris_maart_april_maaie_juny_july_augustus_septimber_oktober_novimber_desimber'.split('_'),\n    monthsShort : function (m, format) {\n        if (!m) {\n            return monthsShortWithDots;\n        } else if (/-MMM-/.test(format)) {\n            return monthsShortWithoutDots[m.month()];\n        } else {\n            return monthsShortWithDots[m.month()];\n        }\n    },\n    monthsParseExact : true,\n    weekdays : 'snein_moandei_tiisdei_woansdei_tongersdei_freed_sneon'.split('_'),\n    weekdaysShort : 'si._mo._ti._wo._to._fr._so.'.split('_'),\n    weekdaysMin : 'Si_Mo_Ti_Wo_To_Fr_So'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD-MM-YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY HH:mm',\n        LLLL : 'dddd D MMMM YYYY HH:mm'\n    },\n    calendar : {\n        sameDay: '[hjoed om] LT',\n        nextDay: '[moarn om] LT',\n        nextWeek: 'dddd [om] LT',\n        lastDay: '[juster om] LT',\n        lastWeek: '[ôfrûne] dddd [om] LT',\n        sameElse: 'L'\n    },\n    relativeTime : {\n        future : 'oer %s',\n        past : '%s lyn',\n        s : 'in pear sekonden',\n        m : 'ien minút',\n        mm : '%d minuten',\n        h : 'ien oere',\n        hh : '%d oeren',\n        d : 'ien dei',\n        dd : '%d dagen',\n        M : 'ien moanne',\n        MM : '%d moannen',\n        y : 'ien jier',\n        yy : '%d jierren'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}(ste|de)/,\n    ordinal : function (number) {\n        return number + ((number === 1 || number === 8 || number >= 20) ? 'ste' : 'de');\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\nreturn fy;\n\n})));\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/locale/gd.js",
    "content": "//! moment.js locale configuration\n//! locale : Scottish Gaelic [gd]\n//! author : Jon Ashdown : https://github.com/jonashdown\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\n\nvar months = [\n    'Am Faoilleach', 'An Gearran', 'Am Màrt', 'An Giblean', 'An Cèitean', 'An t-Ògmhios', 'An t-Iuchar', 'An Lùnastal', 'An t-Sultain', 'An Dàmhair', 'An t-Samhain', 'An Dùbhlachd'\n];\n\nvar monthsShort = ['Faoi', 'Gear', 'Màrt', 'Gibl', 'Cèit', 'Ògmh', 'Iuch', 'Lùn', 'Sult', 'Dàmh', 'Samh', 'Dùbh'];\n\nvar weekdays = ['Didòmhnaich', 'Diluain', 'Dimàirt', 'Diciadain', 'Diardaoin', 'Dihaoine', 'Disathairne'];\n\nvar weekdaysShort = ['Did', 'Dil', 'Dim', 'Dic', 'Dia', 'Dih', 'Dis'];\n\nvar weekdaysMin = ['Dò', 'Lu', 'Mà', 'Ci', 'Ar', 'Ha', 'Sa'];\n\nvar gd = moment.defineLocale('gd', {\n    months : months,\n    monthsShort : monthsShort,\n    monthsParseExact : true,\n    weekdays : weekdays,\n    weekdaysShort : weekdaysShort,\n    weekdaysMin : weekdaysMin,\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY HH:mm',\n        LLLL : 'dddd, D MMMM YYYY HH:mm'\n    },\n    calendar : {\n        sameDay : '[An-diugh aig] LT',\n        nextDay : '[A-màireach aig] LT',\n        nextWeek : 'dddd [aig] LT',\n        lastDay : '[An-dè aig] LT',\n        lastWeek : 'dddd [seo chaidh] [aig] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'ann an %s',\n        past : 'bho chionn %s',\n        s : 'beagan diogan',\n        m : 'mionaid',\n        mm : '%d mionaidean',\n        h : 'uair',\n        hh : '%d uairean',\n        d : 'latha',\n        dd : '%d latha',\n        M : 'mìos',\n        MM : '%d mìosan',\n        y : 'bliadhna',\n        yy : '%d bliadhna'\n    },\n    dayOfMonthOrdinalParse : /\\d{1,2}(d|na|mh)/,\n    ordinal : function (number) {\n        var output = number === 1 ? 'd' : number % 10 === 2 ? 'na' : 'mh';\n        return number + output;\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\nreturn gd;\n\n})));\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/locale/gl.js",
    "content": "//! moment.js locale configuration\n//! locale : Galician [gl]\n//! author : Juan G. Hurtado : https://github.com/juanghurtado\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\n\nvar gl = moment.defineLocale('gl', {\n    months : 'xaneiro_febreiro_marzo_abril_maio_xuño_xullo_agosto_setembro_outubro_novembro_decembro'.split('_'),\n    monthsShort : 'xan._feb._mar._abr._mai._xuñ._xul._ago._set._out._nov._dec.'.split('_'),\n    monthsParseExact: true,\n    weekdays : 'domingo_luns_martes_mércores_xoves_venres_sábado'.split('_'),\n    weekdaysShort : 'dom._lun._mar._mér._xov._ven._sáb.'.split('_'),\n    weekdaysMin : 'do_lu_ma_mé_xo_ve_sá'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat : {\n        LT : 'H:mm',\n        LTS : 'H:mm:ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D [de] MMMM [de] YYYY',\n        LLL : 'D [de] MMMM [de] YYYY H:mm',\n        LLLL : 'dddd, D [de] MMMM [de] YYYY H:mm'\n    },\n    calendar : {\n        sameDay : function () {\n            return '[hoxe ' + ((this.hours() !== 1) ? 'ás' : 'á') + '] LT';\n        },\n        nextDay : function () {\n            return '[mañá ' + ((this.hours() !== 1) ? 'ás' : 'á') + '] LT';\n        },\n        nextWeek : function () {\n            return 'dddd [' + ((this.hours() !== 1) ? 'ás' : 'a') + '] LT';\n        },\n        lastDay : function () {\n            return '[onte ' + ((this.hours() !== 1) ? 'á' : 'a') + '] LT';\n        },\n        lastWeek : function () {\n            return '[o] dddd [pasado ' + ((this.hours() !== 1) ? 'ás' : 'a') + '] LT';\n        },\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : function (str) {\n            if (str.indexOf('un') === 0) {\n                return 'n' + str;\n            }\n            return 'en ' + str;\n        },\n        past : 'hai %s',\n        s : 'uns segundos',\n        m : 'un minuto',\n        mm : '%d minutos',\n        h : 'unha hora',\n        hh : '%d horas',\n        d : 'un día',\n        dd : '%d días',\n        M : 'un mes',\n        MM : '%d meses',\n        y : 'un ano',\n        yy : '%d anos'\n    },\n    dayOfMonthOrdinalParse : /\\d{1,2}º/,\n    ordinal : '%dº',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\nreturn gl;\n\n})));\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/locale/gom-latn.js",
    "content": "//! moment.js locale configuration\n//! locale : Konkani Latin script [gom-latn]\n//! author : The Discoverer : https://github.com/WikiDiscoverer\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\n\nfunction processRelativeTime(number, withoutSuffix, key, isFuture) {\n    var format = {\n        's': ['thodde secondanim', 'thodde second'],\n        'm': ['eka mintan', 'ek minute'],\n        'mm': [number + ' mintanim', number + ' mintam'],\n        'h': ['eka horan', 'ek hor'],\n        'hh': [number + ' horanim', number + ' hor'],\n        'd': ['eka disan', 'ek dis'],\n        'dd': [number + ' disanim', number + ' dis'],\n        'M': ['eka mhoinean', 'ek mhoino'],\n        'MM': [number + ' mhoineanim', number + ' mhoine'],\n        'y': ['eka vorsan', 'ek voros'],\n        'yy': [number + ' vorsanim', number + ' vorsam']\n    };\n    return withoutSuffix ? format[key][0] : format[key][1];\n}\n\nvar gomLatn = moment.defineLocale('gom-latn', {\n    months : 'Janer_Febrer_Mars_Abril_Mai_Jun_Julai_Agost_Setembr_Otubr_Novembr_Dezembr'.split('_'),\n    monthsShort : 'Jan._Feb._Mars_Abr._Mai_Jun_Jul._Ago._Set._Otu._Nov._Dez.'.split('_'),\n    monthsParseExact : true,\n    weekdays : 'Aitar_Somar_Mongllar_Budvar_Brestar_Sukrar_Son\\'var'.split('_'),\n    weekdaysShort : 'Ait._Som._Mon._Bud._Bre._Suk._Son.'.split('_'),\n    weekdaysMin : 'Ai_Sm_Mo_Bu_Br_Su_Sn'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat : {\n        LT : 'A h:mm [vazta]',\n        LTS : 'A h:mm:ss [vazta]',\n        L : 'DD-MM-YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY A h:mm [vazta]',\n        LLLL : 'dddd, MMMM[achea] Do, YYYY, A h:mm [vazta]',\n        llll: 'ddd, D MMM YYYY, A h:mm [vazta]'\n    },\n    calendar : {\n        sameDay: '[Aiz] LT',\n        nextDay: '[Faleam] LT',\n        nextWeek: '[Ieta to] dddd[,] LT',\n        lastDay: '[Kal] LT',\n        lastWeek: '[Fatlo] dddd[,] LT',\n        sameElse: 'L'\n    },\n    relativeTime : {\n        future : '%s',\n        past : '%s adim',\n        s : processRelativeTime,\n        m : processRelativeTime,\n        mm : processRelativeTime,\n        h : processRelativeTime,\n        hh : processRelativeTime,\n        d : processRelativeTime,\n        dd : processRelativeTime,\n        M : processRelativeTime,\n        MM : processRelativeTime,\n        y : processRelativeTime,\n        yy : processRelativeTime\n    },\n    dayOfMonthOrdinalParse : /\\d{1,2}(er)/,\n    ordinal : function (number, period) {\n        switch (period) {\n            // the ordinal 'er' only applies to day of the month\n            case 'D':\n                return number + 'er';\n            default:\n            case 'M':\n            case 'Q':\n            case 'DDD':\n            case 'd':\n            case 'w':\n            case 'W':\n                return number;\n        }\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    },\n    meridiemParse: /rati|sokalli|donparam|sanje/,\n    meridiemHour : function (hour, meridiem) {\n        if (hour === 12) {\n            hour = 0;\n        }\n        if (meridiem === 'rati') {\n            return hour < 4 ? hour : hour + 12;\n        } else if (meridiem === 'sokalli') {\n            return hour;\n        } else if (meridiem === 'donparam') {\n            return hour > 12 ? hour : hour + 12;\n        } else if (meridiem === 'sanje') {\n            return hour + 12;\n        }\n    },\n    meridiem : function (hour, minute, isLower) {\n        if (hour < 4) {\n            return 'rati';\n        } else if (hour < 12) {\n            return 'sokalli';\n        } else if (hour < 16) {\n            return 'donparam';\n        } else if (hour < 20) {\n            return 'sanje';\n        } else {\n            return 'rati';\n        }\n    }\n});\n\nreturn gomLatn;\n\n})));\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/locale/he.js",
    "content": "//! moment.js locale configuration\n//! locale : Hebrew [he]\n//! author : Tomer Cohen : https://github.com/tomer\n//! author : Moshe Simantov : https://github.com/DevelopmentIL\n//! author : Tal Ater : https://github.com/TalAter\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\n\nvar he = moment.defineLocale('he', {\n    months : 'ינואר_פברואר_מרץ_אפריל_מאי_יוני_יולי_אוגוסט_ספטמבר_אוקטובר_נובמבר_דצמבר'.split('_'),\n    monthsShort : 'ינו׳_פבר׳_מרץ_אפר׳_מאי_יוני_יולי_אוג׳_ספט׳_אוק׳_נוב׳_דצמ׳'.split('_'),\n    weekdays : 'ראשון_שני_שלישי_רביעי_חמישי_שישי_שבת'.split('_'),\n    weekdaysShort : 'א׳_ב׳_ג׳_ד׳_ה׳_ו׳_ש׳'.split('_'),\n    weekdaysMin : 'א_ב_ג_ד_ה_ו_ש'.split('_'),\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D [ב]MMMM YYYY',\n        LLL : 'D [ב]MMMM YYYY HH:mm',\n        LLLL : 'dddd, D [ב]MMMM YYYY HH:mm',\n        l : 'D/M/YYYY',\n        ll : 'D MMM YYYY',\n        lll : 'D MMM YYYY HH:mm',\n        llll : 'ddd, D MMM YYYY HH:mm'\n    },\n    calendar : {\n        sameDay : '[היום ב־]LT',\n        nextDay : '[מחר ב־]LT',\n        nextWeek : 'dddd [בשעה] LT',\n        lastDay : '[אתמול ב־]LT',\n        lastWeek : '[ביום] dddd [האחרון בשעה] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'בעוד %s',\n        past : 'לפני %s',\n        s : 'מספר שניות',\n        m : 'דקה',\n        mm : '%d דקות',\n        h : 'שעה',\n        hh : function (number) {\n            if (number === 2) {\n                return 'שעתיים';\n            }\n            return number + ' שעות';\n        },\n        d : 'יום',\n        dd : function (number) {\n            if (number === 2) {\n                return 'יומיים';\n            }\n            return number + ' ימים';\n        },\n        M : 'חודש',\n        MM : function (number) {\n            if (number === 2) {\n                return 'חודשיים';\n            }\n            return number + ' חודשים';\n        },\n        y : 'שנה',\n        yy : function (number) {\n            if (number === 2) {\n                return 'שנתיים';\n            } else if (number % 10 === 0 && number !== 10) {\n                return number + ' שנה';\n            }\n            return number + ' שנים';\n        }\n    },\n    meridiemParse: /אחה\"צ|לפנה\"צ|אחרי הצהריים|לפני הצהריים|לפנות בוקר|בבוקר|בערב/i,\n    isPM : function (input) {\n        return /^(אחה\"צ|אחרי הצהריים|בערב)$/.test(input);\n    },\n    meridiem : function (hour, minute, isLower) {\n        if (hour < 5) {\n            return 'לפנות בוקר';\n        } else if (hour < 10) {\n            return 'בבוקר';\n        } else if (hour < 12) {\n            return isLower ? 'לפנה\"צ' : 'לפני הצהריים';\n        } else if (hour < 18) {\n            return isLower ? 'אחה\"צ' : 'אחרי הצהריים';\n        } else {\n            return 'בערב';\n        }\n    }\n});\n\nreturn he;\n\n})));\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/locale/hi.js",
    "content": "//! moment.js locale configuration\n//! locale : Hindi [hi]\n//! author : Mayank Singhal : https://github.com/mayanksinghal\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\n\nvar symbolMap = {\n    '1': '१',\n    '2': '२',\n    '3': '३',\n    '4': '४',\n    '5': '५',\n    '6': '६',\n    '7': '७',\n    '8': '८',\n    '9': '९',\n    '0': '०'\n};\nvar numberMap = {\n    '१': '1',\n    '२': '2',\n    '३': '3',\n    '४': '4',\n    '५': '5',\n    '६': '6',\n    '७': '7',\n    '८': '8',\n    '९': '9',\n    '०': '0'\n};\n\nvar hi = moment.defineLocale('hi', {\n    months : 'जनवरी_फ़रवरी_मार्च_अप्रैल_मई_जून_जुलाई_अगस्त_सितम्बर_अक्टूबर_नवम्बर_दिसम्बर'.split('_'),\n    monthsShort : 'जन._फ़र._मार्च_अप्रै._मई_जून_जुल._अग._सित._अक्टू._नव._दिस.'.split('_'),\n    monthsParseExact: true,\n    weekdays : 'रविवार_सोमवार_मंगलवार_बुधवार_गुरूवार_शुक्रवार_शनिवार'.split('_'),\n    weekdaysShort : 'रवि_सोम_मंगल_बुध_गुरू_शुक्र_शनि'.split('_'),\n    weekdaysMin : 'र_सो_मं_बु_गु_शु_श'.split('_'),\n    longDateFormat : {\n        LT : 'A h:mm बजे',\n        LTS : 'A h:mm:ss बजे',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY, A h:mm बजे',\n        LLLL : 'dddd, D MMMM YYYY, A h:mm बजे'\n    },\n    calendar : {\n        sameDay : '[आज] LT',\n        nextDay : '[कल] LT',\n        nextWeek : 'dddd, LT',\n        lastDay : '[कल] LT',\n        lastWeek : '[पिछले] dddd, LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : '%s में',\n        past : '%s पहले',\n        s : 'कुछ ही क्षण',\n        m : 'एक मिनट',\n        mm : '%d मिनट',\n        h : 'एक घंटा',\n        hh : '%d घंटे',\n        d : 'एक दिन',\n        dd : '%d दिन',\n        M : 'एक महीने',\n        MM : '%d महीने',\n        y : 'एक वर्ष',\n        yy : '%d वर्ष'\n    },\n    preparse: function (string) {\n        return string.replace(/[१२३४५६७८९०]/g, function (match) {\n            return numberMap[match];\n        });\n    },\n    postformat: function (string) {\n        return string.replace(/\\d/g, function (match) {\n            return symbolMap[match];\n        });\n    },\n    // Hindi notation for meridiems are quite fuzzy in practice. While there exists\n    // a rigid notion of a 'Pahar' it is not used as rigidly in modern Hindi.\n    meridiemParse: /रात|सुबह|दोपहर|शाम/,\n    meridiemHour : function (hour, meridiem) {\n        if (hour === 12) {\n            hour = 0;\n        }\n        if (meridiem === 'रात') {\n            return hour < 4 ? hour : hour + 12;\n        } else if (meridiem === 'सुबह') {\n            return hour;\n        } else if (meridiem === 'दोपहर') {\n            return hour >= 10 ? hour : hour + 12;\n        } else if (meridiem === 'शाम') {\n            return hour + 12;\n        }\n    },\n    meridiem : function (hour, minute, isLower) {\n        if (hour < 4) {\n            return 'रात';\n        } else if (hour < 10) {\n            return 'सुबह';\n        } else if (hour < 17) {\n            return 'दोपहर';\n        } else if (hour < 20) {\n            return 'शाम';\n        } else {\n            return 'रात';\n        }\n    },\n    week : {\n        dow : 0, // Sunday is the first day of the week.\n        doy : 6  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\nreturn hi;\n\n})));\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/locale/hr.js",
    "content": "//! moment.js locale configuration\n//! locale : Croatian [hr]\n//! author : Bojan Marković : https://github.com/bmarkovic\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\n\nfunction translate(number, withoutSuffix, key) {\n    var result = number + ' ';\n    switch (key) {\n        case 'm':\n            return withoutSuffix ? 'jedna minuta' : 'jedne minute';\n        case 'mm':\n            if (number === 1) {\n                result += 'minuta';\n            } else if (number === 2 || number === 3 || number === 4) {\n                result += 'minute';\n            } else {\n                result += 'minuta';\n            }\n            return result;\n        case 'h':\n            return withoutSuffix ? 'jedan sat' : 'jednog sata';\n        case 'hh':\n            if (number === 1) {\n                result += 'sat';\n            } else if (number === 2 || number === 3 || number === 4) {\n                result += 'sata';\n            } else {\n                result += 'sati';\n            }\n            return result;\n        case 'dd':\n            if (number === 1) {\n                result += 'dan';\n            } else {\n                result += 'dana';\n            }\n            return result;\n        case 'MM':\n            if (number === 1) {\n                result += 'mjesec';\n            } else if (number === 2 || number === 3 || number === 4) {\n                result += 'mjeseca';\n            } else {\n                result += 'mjeseci';\n            }\n            return result;\n        case 'yy':\n            if (number === 1) {\n                result += 'godina';\n            } else if (number === 2 || number === 3 || number === 4) {\n                result += 'godine';\n            } else {\n                result += 'godina';\n            }\n            return result;\n    }\n}\n\nvar hr = moment.defineLocale('hr', {\n    months : {\n        format: 'siječnja_veljače_ožujka_travnja_svibnja_lipnja_srpnja_kolovoza_rujna_listopada_studenoga_prosinca'.split('_'),\n        standalone: 'siječanj_veljača_ožujak_travanj_svibanj_lipanj_srpanj_kolovoz_rujan_listopad_studeni_prosinac'.split('_')\n    },\n    monthsShort : 'sij._velj._ožu._tra._svi._lip._srp._kol._ruj._lis._stu._pro.'.split('_'),\n    monthsParseExact: true,\n    weekdays : 'nedjelja_ponedjeljak_utorak_srijeda_četvrtak_petak_subota'.split('_'),\n    weekdaysShort : 'ned._pon._uto._sri._čet._pet._sub.'.split('_'),\n    weekdaysMin : 'ne_po_ut_sr_če_pe_su'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat : {\n        LT : 'H:mm',\n        LTS : 'H:mm:ss',\n        L : 'DD.MM.YYYY',\n        LL : 'D. MMMM YYYY',\n        LLL : 'D. MMMM YYYY H:mm',\n        LLLL : 'dddd, D. MMMM YYYY H:mm'\n    },\n    calendar : {\n        sameDay  : '[danas u] LT',\n        nextDay  : '[sutra u] LT',\n        nextWeek : function () {\n            switch (this.day()) {\n                case 0:\n                    return '[u] [nedjelju] [u] LT';\n                case 3:\n                    return '[u] [srijedu] [u] LT';\n                case 6:\n                    return '[u] [subotu] [u] LT';\n                case 1:\n                case 2:\n                case 4:\n                case 5:\n                    return '[u] dddd [u] LT';\n            }\n        },\n        lastDay  : '[jučer u] LT',\n        lastWeek : function () {\n            switch (this.day()) {\n                case 0:\n                case 3:\n                    return '[prošlu] dddd [u] LT';\n                case 6:\n                    return '[prošle] [subote] [u] LT';\n                case 1:\n                case 2:\n                case 4:\n                case 5:\n                    return '[prošli] dddd [u] LT';\n            }\n        },\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'za %s',\n        past   : 'prije %s',\n        s      : 'par sekundi',\n        m      : translate,\n        mm     : translate,\n        h      : translate,\n        hh     : translate,\n        d      : 'dan',\n        dd     : translate,\n        M      : 'mjesec',\n        MM     : translate,\n        y      : 'godinu',\n        yy     : translate\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}\\./,\n    ordinal : '%d.',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 7  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\nreturn hr;\n\n})));\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/locale/hu.js",
    "content": "//! moment.js locale configuration\n//! locale : Hungarian [hu]\n//! author : Adam Brunner : https://github.com/adambrunner\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\n\nvar weekEndings = 'vasárnap hétfőn kedden szerdán csütörtökön pénteken szombaton'.split(' ');\nfunction translate(number, withoutSuffix, key, isFuture) {\n    var num = number,\n        suffix;\n    switch (key) {\n        case 's':\n            return (isFuture || withoutSuffix) ? 'néhány másodperc' : 'néhány másodperce';\n        case 'm':\n            return 'egy' + (isFuture || withoutSuffix ? ' perc' : ' perce');\n        case 'mm':\n            return num + (isFuture || withoutSuffix ? ' perc' : ' perce');\n        case 'h':\n            return 'egy' + (isFuture || withoutSuffix ? ' óra' : ' órája');\n        case 'hh':\n            return num + (isFuture || withoutSuffix ? ' óra' : ' órája');\n        case 'd':\n            return 'egy' + (isFuture || withoutSuffix ? ' nap' : ' napja');\n        case 'dd':\n            return num + (isFuture || withoutSuffix ? ' nap' : ' napja');\n        case 'M':\n            return 'egy' + (isFuture || withoutSuffix ? ' hónap' : ' hónapja');\n        case 'MM':\n            return num + (isFuture || withoutSuffix ? ' hónap' : ' hónapja');\n        case 'y':\n            return 'egy' + (isFuture || withoutSuffix ? ' év' : ' éve');\n        case 'yy':\n            return num + (isFuture || withoutSuffix ? ' év' : ' éve');\n    }\n    return '';\n}\nfunction week(isFuture) {\n    return (isFuture ? '' : '[múlt] ') + '[' + weekEndings[this.day()] + '] LT[-kor]';\n}\n\nvar hu = moment.defineLocale('hu', {\n    months : 'január_február_március_április_május_június_július_augusztus_szeptember_október_november_december'.split('_'),\n    monthsShort : 'jan_feb_márc_ápr_máj_jún_júl_aug_szept_okt_nov_dec'.split('_'),\n    weekdays : 'vasárnap_hétfő_kedd_szerda_csütörtök_péntek_szombat'.split('_'),\n    weekdaysShort : 'vas_hét_kedd_sze_csüt_pén_szo'.split('_'),\n    weekdaysMin : 'v_h_k_sze_cs_p_szo'.split('_'),\n    longDateFormat : {\n        LT : 'H:mm',\n        LTS : 'H:mm:ss',\n        L : 'YYYY.MM.DD.',\n        LL : 'YYYY. MMMM D.',\n        LLL : 'YYYY. MMMM D. H:mm',\n        LLLL : 'YYYY. MMMM D., dddd H:mm'\n    },\n    meridiemParse: /de|du/i,\n    isPM: function (input) {\n        return input.charAt(1).toLowerCase() === 'u';\n    },\n    meridiem : function (hours, minutes, isLower) {\n        if (hours < 12) {\n            return isLower === true ? 'de' : 'DE';\n        } else {\n            return isLower === true ? 'du' : 'DU';\n        }\n    },\n    calendar : {\n        sameDay : '[ma] LT[-kor]',\n        nextDay : '[holnap] LT[-kor]',\n        nextWeek : function () {\n            return week.call(this, true);\n        },\n        lastDay : '[tegnap] LT[-kor]',\n        lastWeek : function () {\n            return week.call(this, false);\n        },\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : '%s múlva',\n        past : '%s',\n        s : translate,\n        m : translate,\n        mm : translate,\n        h : translate,\n        hh : translate,\n        d : translate,\n        dd : translate,\n        M : translate,\n        MM : translate,\n        y : translate,\n        yy : translate\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}\\./,\n    ordinal : '%d.',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\nreturn hu;\n\n})));\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/locale/hy-am.js",
    "content": "//! moment.js locale configuration\n//! locale : Armenian [hy-am]\n//! author : Armendarabyan : https://github.com/armendarabyan\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\n\nvar hyAm = moment.defineLocale('hy-am', {\n    months : {\n        format: 'հունվարի_փետրվարի_մարտի_ապրիլի_մայիսի_հունիսի_հուլիսի_օգոստոսի_սեպտեմբերի_հոկտեմբերի_նոյեմբերի_դեկտեմբերի'.split('_'),\n        standalone: 'հունվար_փետրվար_մարտ_ապրիլ_մայիս_հունիս_հուլիս_օգոստոս_սեպտեմբեր_հոկտեմբեր_նոյեմբեր_դեկտեմբեր'.split('_')\n    },\n    monthsShort : 'հնվ_փտր_մրտ_ապր_մյս_հնս_հլս_օգս_սպտ_հկտ_նմբ_դկտ'.split('_'),\n    weekdays : 'կիրակի_երկուշաբթի_երեքշաբթի_չորեքշաբթի_հինգշաբթի_ուրբաթ_շաբաթ'.split('_'),\n    weekdaysShort : 'կրկ_երկ_երք_չրք_հնգ_ուրբ_շբթ'.split('_'),\n    weekdaysMin : 'կրկ_երկ_երք_չրք_հնգ_ուրբ_շբթ'.split('_'),\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD.MM.YYYY',\n        LL : 'D MMMM YYYY թ.',\n        LLL : 'D MMMM YYYY թ., HH:mm',\n        LLLL : 'dddd, D MMMM YYYY թ., HH:mm'\n    },\n    calendar : {\n        sameDay: '[այսօր] LT',\n        nextDay: '[վաղը] LT',\n        lastDay: '[երեկ] LT',\n        nextWeek: function () {\n            return 'dddd [օրը ժամը] LT';\n        },\n        lastWeek: function () {\n            return '[անցած] dddd [օրը ժամը] LT';\n        },\n        sameElse: 'L'\n    },\n    relativeTime : {\n        future : '%s հետո',\n        past : '%s առաջ',\n        s : 'մի քանի վայրկյան',\n        m : 'րոպե',\n        mm : '%d րոպե',\n        h : 'ժամ',\n        hh : '%d ժամ',\n        d : 'օր',\n        dd : '%d օր',\n        M : 'ամիս',\n        MM : '%d ամիս',\n        y : 'տարի',\n        yy : '%d տարի'\n    },\n    meridiemParse: /գիշերվա|առավոտվա|ցերեկվա|երեկոյան/,\n    isPM: function (input) {\n        return /^(ցերեկվա|երեկոյան)$/.test(input);\n    },\n    meridiem : function (hour) {\n        if (hour < 4) {\n            return 'գիշերվա';\n        } else if (hour < 12) {\n            return 'առավոտվա';\n        } else if (hour < 17) {\n            return 'ցերեկվա';\n        } else {\n            return 'երեկոյան';\n        }\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}|\\d{1,2}-(ին|րդ)/,\n    ordinal: function (number, period) {\n        switch (period) {\n            case 'DDD':\n            case 'w':\n            case 'W':\n            case 'DDDo':\n                if (number === 1) {\n                    return number + '-ին';\n                }\n                return number + '-րդ';\n            default:\n                return number;\n        }\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 7  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\nreturn hyAm;\n\n})));\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/locale/id.js",
    "content": "//! moment.js locale configuration\n//! locale : Indonesian [id]\n//! author : Mohammad Satrio Utomo : https://github.com/tyok\n//! reference: http://id.wikisource.org/wiki/Pedoman_Umum_Ejaan_Bahasa_Indonesia_yang_Disempurnakan\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\n\nvar id = moment.defineLocale('id', {\n    months : 'Januari_Februari_Maret_April_Mei_Juni_Juli_Agustus_September_Oktober_November_Desember'.split('_'),\n    monthsShort : 'Jan_Feb_Mar_Apr_Mei_Jun_Jul_Ags_Sep_Okt_Nov_Des'.split('_'),\n    weekdays : 'Minggu_Senin_Selasa_Rabu_Kamis_Jumat_Sabtu'.split('_'),\n    weekdaysShort : 'Min_Sen_Sel_Rab_Kam_Jum_Sab'.split('_'),\n    weekdaysMin : 'Mg_Sn_Sl_Rb_Km_Jm_Sb'.split('_'),\n    longDateFormat : {\n        LT : 'HH.mm',\n        LTS : 'HH.mm.ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY [pukul] HH.mm',\n        LLLL : 'dddd, D MMMM YYYY [pukul] HH.mm'\n    },\n    meridiemParse: /pagi|siang|sore|malam/,\n    meridiemHour : function (hour, meridiem) {\n        if (hour === 12) {\n            hour = 0;\n        }\n        if (meridiem === 'pagi') {\n            return hour;\n        } else if (meridiem === 'siang') {\n            return hour >= 11 ? hour : hour + 12;\n        } else if (meridiem === 'sore' || meridiem === 'malam') {\n            return hour + 12;\n        }\n    },\n    meridiem : function (hours, minutes, isLower) {\n        if (hours < 11) {\n            return 'pagi';\n        } else if (hours < 15) {\n            return 'siang';\n        } else if (hours < 19) {\n            return 'sore';\n        } else {\n            return 'malam';\n        }\n    },\n    calendar : {\n        sameDay : '[Hari ini pukul] LT',\n        nextDay : '[Besok pukul] LT',\n        nextWeek : 'dddd [pukul] LT',\n        lastDay : '[Kemarin pukul] LT',\n        lastWeek : 'dddd [lalu pukul] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'dalam %s',\n        past : '%s yang lalu',\n        s : 'beberapa detik',\n        m : 'semenit',\n        mm : '%d menit',\n        h : 'sejam',\n        hh : '%d jam',\n        d : 'sehari',\n        dd : '%d hari',\n        M : 'sebulan',\n        MM : '%d bulan',\n        y : 'setahun',\n        yy : '%d tahun'\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 7  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\nreturn id;\n\n})));\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/locale/is.js",
    "content": "//! moment.js locale configuration\n//! locale : Icelandic [is]\n//! author : Hinrik Örn Sigurðsson : https://github.com/hinrik\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\n\nfunction plural(n) {\n    if (n % 100 === 11) {\n        return true;\n    } else if (n % 10 === 1) {\n        return false;\n    }\n    return true;\n}\nfunction translate(number, withoutSuffix, key, isFuture) {\n    var result = number + ' ';\n    switch (key) {\n        case 's':\n            return withoutSuffix || isFuture ? 'nokkrar sekúndur' : 'nokkrum sekúndum';\n        case 'm':\n            return withoutSuffix ? 'mínúta' : 'mínútu';\n        case 'mm':\n            if (plural(number)) {\n                return result + (withoutSuffix || isFuture ? 'mínútur' : 'mínútum');\n            } else if (withoutSuffix) {\n                return result + 'mínúta';\n            }\n            return result + 'mínútu';\n        case 'hh':\n            if (plural(number)) {\n                return result + (withoutSuffix || isFuture ? 'klukkustundir' : 'klukkustundum');\n            }\n            return result + 'klukkustund';\n        case 'd':\n            if (withoutSuffix) {\n                return 'dagur';\n            }\n            return isFuture ? 'dag' : 'degi';\n        case 'dd':\n            if (plural(number)) {\n                if (withoutSuffix) {\n                    return result + 'dagar';\n                }\n                return result + (isFuture ? 'daga' : 'dögum');\n            } else if (withoutSuffix) {\n                return result + 'dagur';\n            }\n            return result + (isFuture ? 'dag' : 'degi');\n        case 'M':\n            if (withoutSuffix) {\n                return 'mánuður';\n            }\n            return isFuture ? 'mánuð' : 'mánuði';\n        case 'MM':\n            if (plural(number)) {\n                if (withoutSuffix) {\n                    return result + 'mánuðir';\n                }\n                return result + (isFuture ? 'mánuði' : 'mánuðum');\n            } else if (withoutSuffix) {\n                return result + 'mánuður';\n            }\n            return result + (isFuture ? 'mánuð' : 'mánuði');\n        case 'y':\n            return withoutSuffix || isFuture ? 'ár' : 'ári';\n        case 'yy':\n            if (plural(number)) {\n                return result + (withoutSuffix || isFuture ? 'ár' : 'árum');\n            }\n            return result + (withoutSuffix || isFuture ? 'ár' : 'ári');\n    }\n}\n\nvar is = moment.defineLocale('is', {\n    months : 'janúar_febrúar_mars_apríl_maí_júní_júlí_ágúst_september_október_nóvember_desember'.split('_'),\n    monthsShort : 'jan_feb_mar_apr_maí_jún_júl_ágú_sep_okt_nóv_des'.split('_'),\n    weekdays : 'sunnudagur_mánudagur_þriðjudagur_miðvikudagur_fimmtudagur_föstudagur_laugardagur'.split('_'),\n    weekdaysShort : 'sun_mán_þri_mið_fim_fös_lau'.split('_'),\n    weekdaysMin : 'Su_Má_Þr_Mi_Fi_Fö_La'.split('_'),\n    longDateFormat : {\n        LT : 'H:mm',\n        LTS : 'H:mm:ss',\n        L : 'DD.MM.YYYY',\n        LL : 'D. MMMM YYYY',\n        LLL : 'D. MMMM YYYY [kl.] H:mm',\n        LLLL : 'dddd, D. MMMM YYYY [kl.] H:mm'\n    },\n    calendar : {\n        sameDay : '[í dag kl.] LT',\n        nextDay : '[á morgun kl.] LT',\n        nextWeek : 'dddd [kl.] LT',\n        lastDay : '[í gær kl.] LT',\n        lastWeek : '[síðasta] dddd [kl.] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'eftir %s',\n        past : 'fyrir %s síðan',\n        s : translate,\n        m : translate,\n        mm : translate,\n        h : 'klukkustund',\n        hh : translate,\n        d : translate,\n        dd : translate,\n        M : translate,\n        MM : translate,\n        y : translate,\n        yy : translate\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}\\./,\n    ordinal : '%d.',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\nreturn is;\n\n})));\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/locale/it.js",
    "content": "//! moment.js locale configuration\n//! locale : Italian [it]\n//! author : Lorenzo : https://github.com/aliem\n//! author: Mattia Larentis: https://github.com/nostalgiaz\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\n\nvar it = moment.defineLocale('it', {\n    months : 'gennaio_febbraio_marzo_aprile_maggio_giugno_luglio_agosto_settembre_ottobre_novembre_dicembre'.split('_'),\n    monthsShort : 'gen_feb_mar_apr_mag_giu_lug_ago_set_ott_nov_dic'.split('_'),\n    weekdays : 'domenica_lunedì_martedì_mercoledì_giovedì_venerdì_sabato'.split('_'),\n    weekdaysShort : 'dom_lun_mar_mer_gio_ven_sab'.split('_'),\n    weekdaysMin : 'do_lu_ma_me_gi_ve_sa'.split('_'),\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY HH:mm',\n        LLLL : 'dddd, D MMMM YYYY HH:mm'\n    },\n    calendar : {\n        sameDay: '[Oggi alle] LT',\n        nextDay: '[Domani alle] LT',\n        nextWeek: 'dddd [alle] LT',\n        lastDay: '[Ieri alle] LT',\n        lastWeek: function () {\n            switch (this.day()) {\n                case 0:\n                    return '[la scorsa] dddd [alle] LT';\n                default:\n                    return '[lo scorso] dddd [alle] LT';\n            }\n        },\n        sameElse: 'L'\n    },\n    relativeTime : {\n        future : function (s) {\n            return ((/^[0-9].+$/).test(s) ? 'tra' : 'in') + ' ' + s;\n        },\n        past : '%s fa',\n        s : 'alcuni secondi',\n        m : 'un minuto',\n        mm : '%d minuti',\n        h : 'un\\'ora',\n        hh : '%d ore',\n        d : 'un giorno',\n        dd : '%d giorni',\n        M : 'un mese',\n        MM : '%d mesi',\n        y : 'un anno',\n        yy : '%d anni'\n    },\n    dayOfMonthOrdinalParse : /\\d{1,2}º/,\n    ordinal: '%dº',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\nreturn it;\n\n})));\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/locale/ja.js",
    "content": "//! moment.js locale configuration\n//! locale : Japanese [ja]\n//! author : LI Long : https://github.com/baryon\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\n\nvar ja = moment.defineLocale('ja', {\n    months : '1月_2月_3月_4月_5月_6月_7月_8月_9月_10月_11月_12月'.split('_'),\n    monthsShort : '1月_2月_3月_4月_5月_6月_7月_8月_9月_10月_11月_12月'.split('_'),\n    weekdays : '日曜日_月曜日_火曜日_水曜日_木曜日_金曜日_土曜日'.split('_'),\n    weekdaysShort : '日_月_火_水_木_金_土'.split('_'),\n    weekdaysMin : '日_月_火_水_木_金_土'.split('_'),\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'YYYY/MM/DD',\n        LL : 'YYYY年M月D日',\n        LLL : 'YYYY年M月D日 HH:mm',\n        LLLL : 'YYYY年M月D日 HH:mm dddd',\n        l : 'YYYY/MM/DD',\n        ll : 'YYYY年M月D日',\n        lll : 'YYYY年M月D日 HH:mm',\n        llll : 'YYYY年M月D日 HH:mm dddd'\n    },\n    meridiemParse: /午前|午後/i,\n    isPM : function (input) {\n        return input === '午後';\n    },\n    meridiem : function (hour, minute, isLower) {\n        if (hour < 12) {\n            return '午前';\n        } else {\n            return '午後';\n        }\n    },\n    calendar : {\n        sameDay : '[今日] LT',\n        nextDay : '[明日] LT',\n        nextWeek : '[来週]dddd LT',\n        lastDay : '[昨日] LT',\n        lastWeek : '[前週]dddd LT',\n        sameElse : 'L'\n    },\n    dayOfMonthOrdinalParse : /\\d{1,2}日/,\n    ordinal : function (number, period) {\n        switch (period) {\n            case 'd':\n            case 'D':\n            case 'DDD':\n                return number + '日';\n            default:\n                return number;\n        }\n    },\n    relativeTime : {\n        future : '%s後',\n        past : '%s前',\n        s : '数秒',\n        m : '1分',\n        mm : '%d分',\n        h : '1時間',\n        hh : '%d時間',\n        d : '1日',\n        dd : '%d日',\n        M : '1ヶ月',\n        MM : '%dヶ月',\n        y : '1年',\n        yy : '%d年'\n    }\n});\n\nreturn ja;\n\n})));\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/locale/jv.js",
    "content": "//! moment.js locale configuration\n//! locale : Javanese [jv]\n//! author : Rony Lantip : https://github.com/lantip\n//! reference: http://jv.wikipedia.org/wiki/Basa_Jawa\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\n\nvar jv = moment.defineLocale('jv', {\n    months : 'Januari_Februari_Maret_April_Mei_Juni_Juli_Agustus_September_Oktober_Nopember_Desember'.split('_'),\n    monthsShort : 'Jan_Feb_Mar_Apr_Mei_Jun_Jul_Ags_Sep_Okt_Nop_Des'.split('_'),\n    weekdays : 'Minggu_Senen_Seloso_Rebu_Kemis_Jemuwah_Septu'.split('_'),\n    weekdaysShort : 'Min_Sen_Sel_Reb_Kem_Jem_Sep'.split('_'),\n    weekdaysMin : 'Mg_Sn_Sl_Rb_Km_Jm_Sp'.split('_'),\n    longDateFormat : {\n        LT : 'HH.mm',\n        LTS : 'HH.mm.ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY [pukul] HH.mm',\n        LLLL : 'dddd, D MMMM YYYY [pukul] HH.mm'\n    },\n    meridiemParse: /enjing|siyang|sonten|ndalu/,\n    meridiemHour : function (hour, meridiem) {\n        if (hour === 12) {\n            hour = 0;\n        }\n        if (meridiem === 'enjing') {\n            return hour;\n        } else if (meridiem === 'siyang') {\n            return hour >= 11 ? hour : hour + 12;\n        } else if (meridiem === 'sonten' || meridiem === 'ndalu') {\n            return hour + 12;\n        }\n    },\n    meridiem : function (hours, minutes, isLower) {\n        if (hours < 11) {\n            return 'enjing';\n        } else if (hours < 15) {\n            return 'siyang';\n        } else if (hours < 19) {\n            return 'sonten';\n        } else {\n            return 'ndalu';\n        }\n    },\n    calendar : {\n        sameDay : '[Dinten puniko pukul] LT',\n        nextDay : '[Mbenjang pukul] LT',\n        nextWeek : 'dddd [pukul] LT',\n        lastDay : '[Kala wingi pukul] LT',\n        lastWeek : 'dddd [kepengker pukul] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'wonten ing %s',\n        past : '%s ingkang kepengker',\n        s : 'sawetawis detik',\n        m : 'setunggal menit',\n        mm : '%d menit',\n        h : 'setunggal jam',\n        hh : '%d jam',\n        d : 'sedinten',\n        dd : '%d dinten',\n        M : 'sewulan',\n        MM : '%d wulan',\n        y : 'setaun',\n        yy : '%d taun'\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 7  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\nreturn jv;\n\n})));\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/locale/ka.js",
    "content": "//! moment.js locale configuration\n//! locale : Georgian [ka]\n//! author : Irakli Janiashvili : https://github.com/irakli-janiashvili\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\n\nvar ka = moment.defineLocale('ka', {\n    months : {\n        standalone: 'იანვარი_თებერვალი_მარტი_აპრილი_მაისი_ივნისი_ივლისი_აგვისტო_სექტემბერი_ოქტომბერი_ნოემბერი_დეკემბერი'.split('_'),\n        format: 'იანვარს_თებერვალს_მარტს_აპრილის_მაისს_ივნისს_ივლისს_აგვისტს_სექტემბერს_ოქტომბერს_ნოემბერს_დეკემბერს'.split('_')\n    },\n    monthsShort : 'იან_თებ_მარ_აპრ_მაი_ივნ_ივლ_აგვ_სექ_ოქტ_ნოე_დეკ'.split('_'),\n    weekdays : {\n        standalone: 'კვირა_ორშაბათი_სამშაბათი_ოთხშაბათი_ხუთშაბათი_პარასკევი_შაბათი'.split('_'),\n        format: 'კვირას_ორშაბათს_სამშაბათს_ოთხშაბათს_ხუთშაბათს_პარასკევს_შაბათს'.split('_'),\n        isFormat: /(წინა|შემდეგ)/\n    },\n    weekdaysShort : 'კვი_ორშ_სამ_ოთხ_ხუთ_პარ_შაბ'.split('_'),\n    weekdaysMin : 'კვ_ორ_სა_ოთ_ხუ_პა_შა'.split('_'),\n    longDateFormat : {\n        LT : 'h:mm A',\n        LTS : 'h:mm:ss A',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY h:mm A',\n        LLLL : 'dddd, D MMMM YYYY h:mm A'\n    },\n    calendar : {\n        sameDay : '[დღეს] LT[-ზე]',\n        nextDay : '[ხვალ] LT[-ზე]',\n        lastDay : '[გუშინ] LT[-ზე]',\n        nextWeek : '[შემდეგ] dddd LT[-ზე]',\n        lastWeek : '[წინა] dddd LT-ზე',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : function (s) {\n            return (/(წამი|წუთი|საათი|წელი)/).test(s) ?\n                s.replace(/ი$/, 'ში') :\n                s + 'ში';\n        },\n        past : function (s) {\n            if ((/(წამი|წუთი|საათი|დღე|თვე)/).test(s)) {\n                return s.replace(/(ი|ე)$/, 'ის უკან');\n            }\n            if ((/წელი/).test(s)) {\n                return s.replace(/წელი$/, 'წლის უკან');\n            }\n        },\n        s : 'რამდენიმე წამი',\n        m : 'წუთი',\n        mm : '%d წუთი',\n        h : 'საათი',\n        hh : '%d საათი',\n        d : 'დღე',\n        dd : '%d დღე',\n        M : 'თვე',\n        MM : '%d თვე',\n        y : 'წელი',\n        yy : '%d წელი'\n    },\n    dayOfMonthOrdinalParse: /0|1-ლი|მე-\\d{1,2}|\\d{1,2}-ე/,\n    ordinal : function (number) {\n        if (number === 0) {\n            return number;\n        }\n        if (number === 1) {\n            return number + '-ლი';\n        }\n        if ((number < 20) || (number <= 100 && (number % 20 === 0)) || (number % 100 === 0)) {\n            return 'მე-' + number;\n        }\n        return number + '-ე';\n    },\n    week : {\n        dow : 1,\n        doy : 7\n    }\n});\n\nreturn ka;\n\n})));\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/locale/kk.js",
    "content": "//! moment.js locale configuration\n//! locale : Kazakh [kk]\n//! authors : Nurlan Rakhimzhanov : https://github.com/nurlan\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\n\nvar suffixes = {\n    0: '-ші',\n    1: '-ші',\n    2: '-ші',\n    3: '-ші',\n    4: '-ші',\n    5: '-ші',\n    6: '-шы',\n    7: '-ші',\n    8: '-ші',\n    9: '-шы',\n    10: '-шы',\n    20: '-шы',\n    30: '-шы',\n    40: '-шы',\n    50: '-ші',\n    60: '-шы',\n    70: '-ші',\n    80: '-ші',\n    90: '-шы',\n    100: '-ші'\n};\n\nvar kk = moment.defineLocale('kk', {\n    months : 'қаңтар_ақпан_наурыз_сәуір_мамыр_маусым_шілде_тамыз_қыркүйек_қазан_қараша_желтоқсан'.split('_'),\n    monthsShort : 'қаң_ақп_нау_сәу_мам_мау_шіл_там_қыр_қаз_қар_жел'.split('_'),\n    weekdays : 'жексенбі_дүйсенбі_сейсенбі_сәрсенбі_бейсенбі_жұма_сенбі'.split('_'),\n    weekdaysShort : 'жек_дүй_сей_сәр_бей_жұм_сен'.split('_'),\n    weekdaysMin : 'жк_дй_сй_ср_бй_жм_сн'.split('_'),\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD.MM.YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY HH:mm',\n        LLLL : 'dddd, D MMMM YYYY HH:mm'\n    },\n    calendar : {\n        sameDay : '[Бүгін сағат] LT',\n        nextDay : '[Ертең сағат] LT',\n        nextWeek : 'dddd [сағат] LT',\n        lastDay : '[Кеше сағат] LT',\n        lastWeek : '[Өткен аптаның] dddd [сағат] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : '%s ішінде',\n        past : '%s бұрын',\n        s : 'бірнеше секунд',\n        m : 'бір минут',\n        mm : '%d минут',\n        h : 'бір сағат',\n        hh : '%d сағат',\n        d : 'бір күн',\n        dd : '%d күн',\n        M : 'бір ай',\n        MM : '%d ай',\n        y : 'бір жыл',\n        yy : '%d жыл'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}-(ші|шы)/,\n    ordinal : function (number) {\n        var a = number % 10,\n            b = number >= 100 ? 100 : null;\n        return number + (suffixes[number] || suffixes[a] || suffixes[b]);\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 7  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\nreturn kk;\n\n})));\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/locale/km.js",
    "content": "//! moment.js locale configuration\n//! locale : Cambodian [km]\n//! author : Kruy Vanna : https://github.com/kruyvanna\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\n\nvar km = moment.defineLocale('km', {\n    months: 'មករា_កុម្ភៈ_មីនា_មេសា_ឧសភា_មិថុនា_កក្កដា_សីហា_កញ្ញា_តុលា_វិច្ឆិកា_ធ្នូ'.split('_'),\n    monthsShort: 'មករា_កុម្ភៈ_មីនា_មេសា_ឧសភា_មិថុនា_កក្កដា_សីហា_កញ្ញា_តុលា_វិច្ឆិកា_ធ្នូ'.split('_'),\n    weekdays: 'អាទិត្យ_ច័ន្ទ_អង្គារ_ពុធ_ព្រហស្បតិ៍_សុក្រ_សៅរ៍'.split('_'),\n    weekdaysShort: 'អាទិត្យ_ច័ន្ទ_អង្គារ_ពុធ_ព្រហស្បតិ៍_សុក្រ_សៅរ៍'.split('_'),\n    weekdaysMin: 'អាទិត្យ_ច័ន្ទ_អង្គារ_ពុធ_ព្រហស្បតិ៍_សុក្រ_សៅរ៍'.split('_'),\n    longDateFormat: {\n        LT: 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L: 'DD/MM/YYYY',\n        LL: 'D MMMM YYYY',\n        LLL: 'D MMMM YYYY HH:mm',\n        LLLL: 'dddd, D MMMM YYYY HH:mm'\n    },\n    calendar: {\n        sameDay: '[ថ្ងៃនេះ ម៉ោង] LT',\n        nextDay: '[ស្អែក ម៉ោង] LT',\n        nextWeek: 'dddd [ម៉ោង] LT',\n        lastDay: '[ម្សិលមិញ ម៉ោង] LT',\n        lastWeek: 'dddd [សប្តាហ៍មុន] [ម៉ោង] LT',\n        sameElse: 'L'\n    },\n    relativeTime: {\n        future: '%sទៀត',\n        past: '%sមុន',\n        s: 'ប៉ុន្មានវិនាទី',\n        m: 'មួយនាទី',\n        mm: '%d នាទី',\n        h: 'មួយម៉ោង',\n        hh: '%d ម៉ោង',\n        d: 'មួយថ្ងៃ',\n        dd: '%d ថ្ងៃ',\n        M: 'មួយខែ',\n        MM: '%d ខែ',\n        y: 'មួយឆ្នាំ',\n        yy: '%d ឆ្នាំ'\n    },\n    week: {\n        dow: 1, // Monday is the first day of the week.\n        doy: 4 // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\nreturn km;\n\n})));\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/locale/kn.js",
    "content": "//! moment.js locale configuration\n//! locale : Kannada [kn]\n//! author : Rajeev Naik : https://github.com/rajeevnaikte\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\n\nvar symbolMap = {\n    '1': '೧',\n    '2': '೨',\n    '3': '೩',\n    '4': '೪',\n    '5': '೫',\n    '6': '೬',\n    '7': '೭',\n    '8': '೮',\n    '9': '೯',\n    '0': '೦'\n};\nvar numberMap = {\n    '೧': '1',\n    '೨': '2',\n    '೩': '3',\n    '೪': '4',\n    '೫': '5',\n    '೬': '6',\n    '೭': '7',\n    '೮': '8',\n    '೯': '9',\n    '೦': '0'\n};\n\nvar kn = moment.defineLocale('kn', {\n    months : 'ಜನವರಿ_ಫೆಬ್ರವರಿ_ಮಾರ್ಚ್_ಏಪ್ರಿಲ್_ಮೇ_ಜೂನ್_ಜುಲೈ_ಆಗಸ್ಟ್_ಸೆಪ್ಟೆಂಬರ್_ಅಕ್ಟೋಬರ್_ನವೆಂಬರ್_ಡಿಸೆಂಬರ್'.split('_'),\n    monthsShort : 'ಜನ_ಫೆಬ್ರ_ಮಾರ್ಚ್_ಏಪ್ರಿಲ್_ಮೇ_ಜೂನ್_ಜುಲೈ_ಆಗಸ್ಟ್_ಸೆಪ್ಟೆಂಬ_ಅಕ್ಟೋಬ_ನವೆಂಬ_ಡಿಸೆಂಬ'.split('_'),\n    monthsParseExact: true,\n    weekdays : 'ಭಾನುವಾರ_ಸೋಮವಾರ_ಮಂಗಳವಾರ_ಬುಧವಾರ_ಗುರುವಾರ_ಶುಕ್ರವಾರ_ಶನಿವಾರ'.split('_'),\n    weekdaysShort : 'ಭಾನು_ಸೋಮ_ಮಂಗಳ_ಬುಧ_ಗುರು_ಶುಕ್ರ_ಶನಿ'.split('_'),\n    weekdaysMin : 'ಭಾ_ಸೋ_ಮಂ_ಬು_ಗು_ಶು_ಶ'.split('_'),\n    longDateFormat : {\n        LT : 'A h:mm',\n        LTS : 'A h:mm:ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY, A h:mm',\n        LLLL : 'dddd, D MMMM YYYY, A h:mm'\n    },\n    calendar : {\n        sameDay : '[ಇಂದು] LT',\n        nextDay : '[ನಾಳೆ] LT',\n        nextWeek : 'dddd, LT',\n        lastDay : '[ನಿನ್ನೆ] LT',\n        lastWeek : '[ಕೊನೆಯ] dddd, LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : '%s ನಂತರ',\n        past : '%s ಹಿಂದೆ',\n        s : 'ಕೆಲವು ಕ್ಷಣಗಳು',\n        m : 'ಒಂದು ನಿಮಿಷ',\n        mm : '%d ನಿಮಿಷ',\n        h : 'ಒಂದು ಗಂಟೆ',\n        hh : '%d ಗಂಟೆ',\n        d : 'ಒಂದು ದಿನ',\n        dd : '%d ದಿನ',\n        M : 'ಒಂದು ತಿಂಗಳು',\n        MM : '%d ತಿಂಗಳು',\n        y : 'ಒಂದು ವರ್ಷ',\n        yy : '%d ವರ್ಷ'\n    },\n    preparse: function (string) {\n        return string.replace(/[೧೨೩೪೫೬೭೮೯೦]/g, function (match) {\n            return numberMap[match];\n        });\n    },\n    postformat: function (string) {\n        return string.replace(/\\d/g, function (match) {\n            return symbolMap[match];\n        });\n    },\n    meridiemParse: /ರಾತ್ರಿ|ಬೆಳಿಗ್ಗೆ|ಮಧ್ಯಾಹ್ನ|ಸಂಜೆ/,\n    meridiemHour : function (hour, meridiem) {\n        if (hour === 12) {\n            hour = 0;\n        }\n        if (meridiem === 'ರಾತ್ರಿ') {\n            return hour < 4 ? hour : hour + 12;\n        } else if (meridiem === 'ಬೆಳಿಗ್ಗೆ') {\n            return hour;\n        } else if (meridiem === 'ಮಧ್ಯಾಹ್ನ') {\n            return hour >= 10 ? hour : hour + 12;\n        } else if (meridiem === 'ಸಂಜೆ') {\n            return hour + 12;\n        }\n    },\n    meridiem : function (hour, minute, isLower) {\n        if (hour < 4) {\n            return 'ರಾತ್ರಿ';\n        } else if (hour < 10) {\n            return 'ಬೆಳಿಗ್ಗೆ';\n        } else if (hour < 17) {\n            return 'ಮಧ್ಯಾಹ್ನ';\n        } else if (hour < 20) {\n            return 'ಸಂಜೆ';\n        } else {\n            return 'ರಾತ್ರಿ';\n        }\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}(ನೇ)/,\n    ordinal : function (number) {\n        return number + 'ನೇ';\n    },\n    week : {\n        dow : 0, // Sunday is the first day of the week.\n        doy : 6  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\nreturn kn;\n\n})));\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/locale/ko.js",
    "content": "//! moment.js locale configuration\n//! locale : Korean [ko]\n//! author : Kyungwook, Park : https://github.com/kyungw00k\n//! author : Jeeeyul Lee <jeeeyul@gmail.com>\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\n\nvar ko = moment.defineLocale('ko', {\n    months : '1월_2월_3월_4월_5월_6월_7월_8월_9월_10월_11월_12월'.split('_'),\n    monthsShort : '1월_2월_3월_4월_5월_6월_7월_8월_9월_10월_11월_12월'.split('_'),\n    weekdays : '일요일_월요일_화요일_수요일_목요일_금요일_토요일'.split('_'),\n    weekdaysShort : '일_월_화_수_목_금_토'.split('_'),\n    weekdaysMin : '일_월_화_수_목_금_토'.split('_'),\n    longDateFormat : {\n        LT : 'A h:mm',\n        LTS : 'A h:mm:ss',\n        L : 'YYYY.MM.DD',\n        LL : 'YYYY년 MMMM D일',\n        LLL : 'YYYY년 MMMM D일 A h:mm',\n        LLLL : 'YYYY년 MMMM D일 dddd A h:mm',\n        l : 'YYYY.MM.DD',\n        ll : 'YYYY년 MMMM D일',\n        lll : 'YYYY년 MMMM D일 A h:mm',\n        llll : 'YYYY년 MMMM D일 dddd A h:mm'\n    },\n    calendar : {\n        sameDay : '오늘 LT',\n        nextDay : '내일 LT',\n        nextWeek : 'dddd LT',\n        lastDay : '어제 LT',\n        lastWeek : '지난주 dddd LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : '%s 후',\n        past : '%s 전',\n        s : '몇 초',\n        ss : '%d초',\n        m : '1분',\n        mm : '%d분',\n        h : '한 시간',\n        hh : '%d시간',\n        d : '하루',\n        dd : '%d일',\n        M : '한 달',\n        MM : '%d달',\n        y : '일 년',\n        yy : '%d년'\n    },\n    dayOfMonthOrdinalParse : /\\d{1,2}일/,\n    ordinal : '%d일',\n    meridiemParse : /오전|오후/,\n    isPM : function (token) {\n        return token === '오후';\n    },\n    meridiem : function (hour, minute, isUpper) {\n        return hour < 12 ? '오전' : '오후';\n    }\n});\n\nreturn ko;\n\n})));\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/locale/ky.js",
    "content": "//! moment.js locale configuration\n//! locale : Kyrgyz [ky]\n//! author : Chyngyz Arystan uulu : https://github.com/chyngyz\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\n\n\nvar suffixes = {\n    0: '-чү',\n    1: '-чи',\n    2: '-чи',\n    3: '-чү',\n    4: '-чү',\n    5: '-чи',\n    6: '-чы',\n    7: '-чи',\n    8: '-чи',\n    9: '-чу',\n    10: '-чу',\n    20: '-чы',\n    30: '-чу',\n    40: '-чы',\n    50: '-чү',\n    60: '-чы',\n    70: '-чи',\n    80: '-чи',\n    90: '-чу',\n    100: '-чү'\n};\n\nvar ky = moment.defineLocale('ky', {\n    months : 'январь_февраль_март_апрель_май_июнь_июль_август_сентябрь_октябрь_ноябрь_декабрь'.split('_'),\n    monthsShort : 'янв_фев_март_апр_май_июнь_июль_авг_сен_окт_ноя_дек'.split('_'),\n    weekdays : 'Жекшемби_Дүйшөмбү_Шейшемби_Шаршемби_Бейшемби_Жума_Ишемби'.split('_'),\n    weekdaysShort : 'Жек_Дүй_Шей_Шар_Бей_Жум_Ише'.split('_'),\n    weekdaysMin : 'Жк_Дй_Шй_Шр_Бй_Жм_Иш'.split('_'),\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD.MM.YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY HH:mm',\n        LLLL : 'dddd, D MMMM YYYY HH:mm'\n    },\n    calendar : {\n        sameDay : '[Бүгүн саат] LT',\n        nextDay : '[Эртең саат] LT',\n        nextWeek : 'dddd [саат] LT',\n        lastDay : '[Кече саат] LT',\n        lastWeek : '[Өткен аптанын] dddd [күнү] [саат] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : '%s ичинде',\n        past : '%s мурун',\n        s : 'бирнече секунд',\n        m : 'бир мүнөт',\n        mm : '%d мүнөт',\n        h : 'бир саат',\n        hh : '%d саат',\n        d : 'бир күн',\n        dd : '%d күн',\n        M : 'бир ай',\n        MM : '%d ай',\n        y : 'бир жыл',\n        yy : '%d жыл'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}-(чи|чы|чү|чу)/,\n    ordinal : function (number) {\n        var a = number % 10,\n            b = number >= 100 ? 100 : null;\n        return number + (suffixes[number] || suffixes[a] || suffixes[b]);\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 7  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\nreturn ky;\n\n})));\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/locale/lb.js",
    "content": "//! moment.js locale configuration\n//! locale : Luxembourgish [lb]\n//! author : mweimerskirch : https://github.com/mweimerskirch\n//! author : David Raison : https://github.com/kwisatz\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\n\nfunction processRelativeTime(number, withoutSuffix, key, isFuture) {\n    var format = {\n        'm': ['eng Minutt', 'enger Minutt'],\n        'h': ['eng Stonn', 'enger Stonn'],\n        'd': ['een Dag', 'engem Dag'],\n        'M': ['ee Mount', 'engem Mount'],\n        'y': ['ee Joer', 'engem Joer']\n    };\n    return withoutSuffix ? format[key][0] : format[key][1];\n}\nfunction processFutureTime(string) {\n    var number = string.substr(0, string.indexOf(' '));\n    if (eifelerRegelAppliesToNumber(number)) {\n        return 'a ' + string;\n    }\n    return 'an ' + string;\n}\nfunction processPastTime(string) {\n    var number = string.substr(0, string.indexOf(' '));\n    if (eifelerRegelAppliesToNumber(number)) {\n        return 'viru ' + string;\n    }\n    return 'virun ' + string;\n}\n/**\n * Returns true if the word before the given number loses the '-n' ending.\n * e.g. 'an 10 Deeg' but 'a 5 Deeg'\n *\n * @param number {integer}\n * @returns {boolean}\n */\nfunction eifelerRegelAppliesToNumber(number) {\n    number = parseInt(number, 10);\n    if (isNaN(number)) {\n        return false;\n    }\n    if (number < 0) {\n        // Negative Number --> always true\n        return true;\n    } else if (number < 10) {\n        // Only 1 digit\n        if (4 <= number && number <= 7) {\n            return true;\n        }\n        return false;\n    } else if (number < 100) {\n        // 2 digits\n        var lastDigit = number % 10, firstDigit = number / 10;\n        if (lastDigit === 0) {\n            return eifelerRegelAppliesToNumber(firstDigit);\n        }\n        return eifelerRegelAppliesToNumber(lastDigit);\n    } else if (number < 10000) {\n        // 3 or 4 digits --> recursively check first digit\n        while (number >= 10) {\n            number = number / 10;\n        }\n        return eifelerRegelAppliesToNumber(number);\n    } else {\n        // Anything larger than 4 digits: recursively check first n-3 digits\n        number = number / 1000;\n        return eifelerRegelAppliesToNumber(number);\n    }\n}\n\nvar lb = moment.defineLocale('lb', {\n    months: 'Januar_Februar_Mäerz_Abrëll_Mee_Juni_Juli_August_September_Oktober_November_Dezember'.split('_'),\n    monthsShort: 'Jan._Febr._Mrz._Abr._Mee_Jun._Jul._Aug._Sept._Okt._Nov._Dez.'.split('_'),\n    monthsParseExact : true,\n    weekdays: 'Sonndeg_Méindeg_Dënschdeg_Mëttwoch_Donneschdeg_Freideg_Samschdeg'.split('_'),\n    weekdaysShort: 'So._Mé._Dë._Më._Do._Fr._Sa.'.split('_'),\n    weekdaysMin: 'So_Mé_Dë_Më_Do_Fr_Sa'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat: {\n        LT: 'H:mm [Auer]',\n        LTS: 'H:mm:ss [Auer]',\n        L: 'DD.MM.YYYY',\n        LL: 'D. MMMM YYYY',\n        LLL: 'D. MMMM YYYY H:mm [Auer]',\n        LLLL: 'dddd, D. MMMM YYYY H:mm [Auer]'\n    },\n    calendar: {\n        sameDay: '[Haut um] LT',\n        sameElse: 'L',\n        nextDay: '[Muer um] LT',\n        nextWeek: 'dddd [um] LT',\n        lastDay: '[Gëschter um] LT',\n        lastWeek: function () {\n            // Different date string for 'Dënschdeg' (Tuesday) and 'Donneschdeg' (Thursday) due to phonological rule\n            switch (this.day()) {\n                case 2:\n                case 4:\n                    return '[Leschten] dddd [um] LT';\n                default:\n                    return '[Leschte] dddd [um] LT';\n            }\n        }\n    },\n    relativeTime : {\n        future : processFutureTime,\n        past : processPastTime,\n        s : 'e puer Sekonnen',\n        m : processRelativeTime,\n        mm : '%d Minutten',\n        h : processRelativeTime,\n        hh : '%d Stonnen',\n        d : processRelativeTime,\n        dd : '%d Deeg',\n        M : processRelativeTime,\n        MM : '%d Méint',\n        y : processRelativeTime,\n        yy : '%d Joer'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}\\./,\n    ordinal: '%d.',\n    week: {\n        dow: 1, // Monday is the first day of the week.\n        doy: 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\nreturn lb;\n\n})));\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/locale/lo.js",
    "content": "//! moment.js locale configuration\n//! locale : Lao [lo]\n//! author : Ryan Hart : https://github.com/ryanhart2\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\n\nvar lo = moment.defineLocale('lo', {\n    months : 'ມັງກອນ_ກຸມພາ_ມີນາ_ເມສາ_ພຶດສະພາ_ມິຖຸນາ_ກໍລະກົດ_ສິງຫາ_ກັນຍາ_ຕຸລາ_ພະຈິກ_ທັນວາ'.split('_'),\n    monthsShort : 'ມັງກອນ_ກຸມພາ_ມີນາ_ເມສາ_ພຶດສະພາ_ມິຖຸນາ_ກໍລະກົດ_ສິງຫາ_ກັນຍາ_ຕຸລາ_ພະຈິກ_ທັນວາ'.split('_'),\n    weekdays : 'ອາທິດ_ຈັນ_ອັງຄານ_ພຸດ_ພະຫັດ_ສຸກ_ເສົາ'.split('_'),\n    weekdaysShort : 'ທິດ_ຈັນ_ອັງຄານ_ພຸດ_ພະຫັດ_ສຸກ_ເສົາ'.split('_'),\n    weekdaysMin : 'ທ_ຈ_ອຄ_ພ_ພຫ_ສກ_ສ'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY HH:mm',\n        LLLL : 'ວັນdddd D MMMM YYYY HH:mm'\n    },\n    meridiemParse: /ຕອນເຊົ້າ|ຕອນແລງ/,\n    isPM: function (input) {\n        return input === 'ຕອນແລງ';\n    },\n    meridiem : function (hour, minute, isLower) {\n        if (hour < 12) {\n            return 'ຕອນເຊົ້າ';\n        } else {\n            return 'ຕອນແລງ';\n        }\n    },\n    calendar : {\n        sameDay : '[ມື້ນີ້ເວລາ] LT',\n        nextDay : '[ມື້ອື່ນເວລາ] LT',\n        nextWeek : '[ວັນ]dddd[ໜ້າເວລາ] LT',\n        lastDay : '[ມື້ວານນີ້ເວລາ] LT',\n        lastWeek : '[ວັນ]dddd[ແລ້ວນີ້ເວລາ] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'ອີກ %s',\n        past : '%sຜ່ານມາ',\n        s : 'ບໍ່ເທົ່າໃດວິນາທີ',\n        m : '1 ນາທີ',\n        mm : '%d ນາທີ',\n        h : '1 ຊົ່ວໂມງ',\n        hh : '%d ຊົ່ວໂມງ',\n        d : '1 ມື້',\n        dd : '%d ມື້',\n        M : '1 ເດືອນ',\n        MM : '%d ເດືອນ',\n        y : '1 ປີ',\n        yy : '%d ປີ'\n    },\n    dayOfMonthOrdinalParse: /(ທີ່)\\d{1,2}/,\n    ordinal : function (number) {\n        return 'ທີ່' + number;\n    }\n});\n\nreturn lo;\n\n})));\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/locale/lt.js",
    "content": "//! moment.js locale configuration\n//! locale : Lithuanian [lt]\n//! author : Mindaugas Mozūras : https://github.com/mmozuras\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\n\nvar units = {\n    'm' : 'minutė_minutės_minutę',\n    'mm': 'minutės_minučių_minutes',\n    'h' : 'valanda_valandos_valandą',\n    'hh': 'valandos_valandų_valandas',\n    'd' : 'diena_dienos_dieną',\n    'dd': 'dienos_dienų_dienas',\n    'M' : 'mėnuo_mėnesio_mėnesį',\n    'MM': 'mėnesiai_mėnesių_mėnesius',\n    'y' : 'metai_metų_metus',\n    'yy': 'metai_metų_metus'\n};\nfunction translateSeconds(number, withoutSuffix, key, isFuture) {\n    if (withoutSuffix) {\n        return 'kelios sekundės';\n    } else {\n        return isFuture ? 'kelių sekundžių' : 'kelias sekundes';\n    }\n}\nfunction translateSingular(number, withoutSuffix, key, isFuture) {\n    return withoutSuffix ? forms(key)[0] : (isFuture ? forms(key)[1] : forms(key)[2]);\n}\nfunction special(number) {\n    return number % 10 === 0 || (number > 10 && number < 20);\n}\nfunction forms(key) {\n    return units[key].split('_');\n}\nfunction translate(number, withoutSuffix, key, isFuture) {\n    var result = number + ' ';\n    if (number === 1) {\n        return result + translateSingular(number, withoutSuffix, key[0], isFuture);\n    } else if (withoutSuffix) {\n        return result + (special(number) ? forms(key)[1] : forms(key)[0]);\n    } else {\n        if (isFuture) {\n            return result + forms(key)[1];\n        } else {\n            return result + (special(number) ? forms(key)[1] : forms(key)[2]);\n        }\n    }\n}\nvar lt = moment.defineLocale('lt', {\n    months : {\n        format: 'sausio_vasario_kovo_balandžio_gegužės_birželio_liepos_rugpjūčio_rugsėjo_spalio_lapkričio_gruodžio'.split('_'),\n        standalone: 'sausis_vasaris_kovas_balandis_gegužė_birželis_liepa_rugpjūtis_rugsėjis_spalis_lapkritis_gruodis'.split('_'),\n        isFormat: /D[oD]?(\\[[^\\[\\]]*\\]|\\s)+MMMM?|MMMM?(\\[[^\\[\\]]*\\]|\\s)+D[oD]?/\n    },\n    monthsShort : 'sau_vas_kov_bal_geg_bir_lie_rgp_rgs_spa_lap_grd'.split('_'),\n    weekdays : {\n        format: 'sekmadienį_pirmadienį_antradienį_trečiadienį_ketvirtadienį_penktadienį_šeštadienį'.split('_'),\n        standalone: 'sekmadienis_pirmadienis_antradienis_trečiadienis_ketvirtadienis_penktadienis_šeštadienis'.split('_'),\n        isFormat: /dddd HH:mm/\n    },\n    weekdaysShort : 'Sek_Pir_Ant_Tre_Ket_Pen_Šeš'.split('_'),\n    weekdaysMin : 'S_P_A_T_K_Pn_Š'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'YYYY-MM-DD',\n        LL : 'YYYY [m.] MMMM D [d.]',\n        LLL : 'YYYY [m.] MMMM D [d.], HH:mm [val.]',\n        LLLL : 'YYYY [m.] MMMM D [d.], dddd, HH:mm [val.]',\n        l : 'YYYY-MM-DD',\n        ll : 'YYYY [m.] MMMM D [d.]',\n        lll : 'YYYY [m.] MMMM D [d.], HH:mm [val.]',\n        llll : 'YYYY [m.] MMMM D [d.], ddd, HH:mm [val.]'\n    },\n    calendar : {\n        sameDay : '[Šiandien] LT',\n        nextDay : '[Rytoj] LT',\n        nextWeek : 'dddd LT',\n        lastDay : '[Vakar] LT',\n        lastWeek : '[Praėjusį] dddd LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'po %s',\n        past : 'prieš %s',\n        s : translateSeconds,\n        m : translateSingular,\n        mm : translate,\n        h : translateSingular,\n        hh : translate,\n        d : translateSingular,\n        dd : translate,\n        M : translateSingular,\n        MM : translate,\n        y : translateSingular,\n        yy : translate\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}-oji/,\n    ordinal : function (number) {\n        return number + '-oji';\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\nreturn lt;\n\n})));\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/locale/lv.js",
    "content": "//! moment.js locale configuration\n//! locale : Latvian [lv]\n//! author : Kristaps Karlsons : https://github.com/skakri\n//! author : Jānis Elmeris : https://github.com/JanisE\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\n\nvar units = {\n    'm': 'minūtes_minūtēm_minūte_minūtes'.split('_'),\n    'mm': 'minūtes_minūtēm_minūte_minūtes'.split('_'),\n    'h': 'stundas_stundām_stunda_stundas'.split('_'),\n    'hh': 'stundas_stundām_stunda_stundas'.split('_'),\n    'd': 'dienas_dienām_diena_dienas'.split('_'),\n    'dd': 'dienas_dienām_diena_dienas'.split('_'),\n    'M': 'mēneša_mēnešiem_mēnesis_mēneši'.split('_'),\n    'MM': 'mēneša_mēnešiem_mēnesis_mēneši'.split('_'),\n    'y': 'gada_gadiem_gads_gadi'.split('_'),\n    'yy': 'gada_gadiem_gads_gadi'.split('_')\n};\n/**\n * @param withoutSuffix boolean true = a length of time; false = before/after a period of time.\n */\nfunction format(forms, number, withoutSuffix) {\n    if (withoutSuffix) {\n        // E.g. \"21 minūte\", \"3 minūtes\".\n        return number % 10 === 1 && number % 100 !== 11 ? forms[2] : forms[3];\n    } else {\n        // E.g. \"21 minūtes\" as in \"pēc 21 minūtes\".\n        // E.g. \"3 minūtēm\" as in \"pēc 3 minūtēm\".\n        return number % 10 === 1 && number % 100 !== 11 ? forms[0] : forms[1];\n    }\n}\nfunction relativeTimeWithPlural(number, withoutSuffix, key) {\n    return number + ' ' + format(units[key], number, withoutSuffix);\n}\nfunction relativeTimeWithSingular(number, withoutSuffix, key) {\n    return format(units[key], number, withoutSuffix);\n}\nfunction relativeSeconds(number, withoutSuffix) {\n    return withoutSuffix ? 'dažas sekundes' : 'dažām sekundēm';\n}\n\nvar lv = moment.defineLocale('lv', {\n    months : 'janvāris_februāris_marts_aprīlis_maijs_jūnijs_jūlijs_augusts_septembris_oktobris_novembris_decembris'.split('_'),\n    monthsShort : 'jan_feb_mar_apr_mai_jūn_jūl_aug_sep_okt_nov_dec'.split('_'),\n    weekdays : 'svētdiena_pirmdiena_otrdiena_trešdiena_ceturtdiena_piektdiena_sestdiena'.split('_'),\n    weekdaysShort : 'Sv_P_O_T_C_Pk_S'.split('_'),\n    weekdaysMin : 'Sv_P_O_T_C_Pk_S'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD.MM.YYYY.',\n        LL : 'YYYY. [gada] D. MMMM',\n        LLL : 'YYYY. [gada] D. MMMM, HH:mm',\n        LLLL : 'YYYY. [gada] D. MMMM, dddd, HH:mm'\n    },\n    calendar : {\n        sameDay : '[Šodien pulksten] LT',\n        nextDay : '[Rīt pulksten] LT',\n        nextWeek : 'dddd [pulksten] LT',\n        lastDay : '[Vakar pulksten] LT',\n        lastWeek : '[Pagājušā] dddd [pulksten] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'pēc %s',\n        past : 'pirms %s',\n        s : relativeSeconds,\n        m : relativeTimeWithSingular,\n        mm : relativeTimeWithPlural,\n        h : relativeTimeWithSingular,\n        hh : relativeTimeWithPlural,\n        d : relativeTimeWithSingular,\n        dd : relativeTimeWithPlural,\n        M : relativeTimeWithSingular,\n        MM : relativeTimeWithPlural,\n        y : relativeTimeWithSingular,\n        yy : relativeTimeWithPlural\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}\\./,\n    ordinal : '%d.',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\nreturn lv;\n\n})));\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/locale/me.js",
    "content": "//! moment.js locale configuration\n//! locale : Montenegrin [me]\n//! author : Miodrag Nikač <miodrag@restartit.me> : https://github.com/miodragnikac\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\n\nvar translator = {\n    words: { //Different grammatical cases\n        m: ['jedan minut', 'jednog minuta'],\n        mm: ['minut', 'minuta', 'minuta'],\n        h: ['jedan sat', 'jednog sata'],\n        hh: ['sat', 'sata', 'sati'],\n        dd: ['dan', 'dana', 'dana'],\n        MM: ['mjesec', 'mjeseca', 'mjeseci'],\n        yy: ['godina', 'godine', 'godina']\n    },\n    correctGrammaticalCase: function (number, wordKey) {\n        return number === 1 ? wordKey[0] : (number >= 2 && number <= 4 ? wordKey[1] : wordKey[2]);\n    },\n    translate: function (number, withoutSuffix, key) {\n        var wordKey = translator.words[key];\n        if (key.length === 1) {\n            return withoutSuffix ? wordKey[0] : wordKey[1];\n        } else {\n            return number + ' ' + translator.correctGrammaticalCase(number, wordKey);\n        }\n    }\n};\n\nvar me = moment.defineLocale('me', {\n    months: 'januar_februar_mart_april_maj_jun_jul_avgust_septembar_oktobar_novembar_decembar'.split('_'),\n    monthsShort: 'jan._feb._mar._apr._maj_jun_jul_avg._sep._okt._nov._dec.'.split('_'),\n    monthsParseExact : true,\n    weekdays: 'nedjelja_ponedjeljak_utorak_srijeda_četvrtak_petak_subota'.split('_'),\n    weekdaysShort: 'ned._pon._uto._sri._čet._pet._sub.'.split('_'),\n    weekdaysMin: 'ne_po_ut_sr_če_pe_su'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat: {\n        LT: 'H:mm',\n        LTS : 'H:mm:ss',\n        L: 'DD.MM.YYYY',\n        LL: 'D. MMMM YYYY',\n        LLL: 'D. MMMM YYYY H:mm',\n        LLLL: 'dddd, D. MMMM YYYY H:mm'\n    },\n    calendar: {\n        sameDay: '[danas u] LT',\n        nextDay: '[sjutra u] LT',\n\n        nextWeek: function () {\n            switch (this.day()) {\n                case 0:\n                    return '[u] [nedjelju] [u] LT';\n                case 3:\n                    return '[u] [srijedu] [u] LT';\n                case 6:\n                    return '[u] [subotu] [u] LT';\n                case 1:\n                case 2:\n                case 4:\n                case 5:\n                    return '[u] dddd [u] LT';\n            }\n        },\n        lastDay  : '[juče u] LT',\n        lastWeek : function () {\n            var lastWeekDays = [\n                '[prošle] [nedjelje] [u] LT',\n                '[prošlog] [ponedjeljka] [u] LT',\n                '[prošlog] [utorka] [u] LT',\n                '[prošle] [srijede] [u] LT',\n                '[prošlog] [četvrtka] [u] LT',\n                '[prošlog] [petka] [u] LT',\n                '[prošle] [subote] [u] LT'\n            ];\n            return lastWeekDays[this.day()];\n        },\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'za %s',\n        past   : 'prije %s',\n        s      : 'nekoliko sekundi',\n        m      : translator.translate,\n        mm     : translator.translate,\n        h      : translator.translate,\n        hh     : translator.translate,\n        d      : 'dan',\n        dd     : translator.translate,\n        M      : 'mjesec',\n        MM     : translator.translate,\n        y      : 'godinu',\n        yy     : translator.translate\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}\\./,\n    ordinal : '%d.',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 7  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\nreturn me;\n\n})));\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/locale/mi.js",
    "content": "//! moment.js locale configuration\n//! locale : Maori [mi]\n//! author : John Corrigan <robbiecloset@gmail.com> : https://github.com/johnideal\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\n\nvar mi = moment.defineLocale('mi', {\n    months: 'Kohi-tāte_Hui-tanguru_Poutū-te-rangi_Paenga-whāwhā_Haratua_Pipiri_Hōngoingoi_Here-turi-kōkā_Mahuru_Whiringa-ā-nuku_Whiringa-ā-rangi_Hakihea'.split('_'),\n    monthsShort: 'Kohi_Hui_Pou_Pae_Hara_Pipi_Hōngoi_Here_Mahu_Whi-nu_Whi-ra_Haki'.split('_'),\n    monthsRegex: /(?:['a-z\\u0101\\u014D\\u016B]+\\-?){1,3}/i,\n    monthsStrictRegex: /(?:['a-z\\u0101\\u014D\\u016B]+\\-?){1,3}/i,\n    monthsShortRegex: /(?:['a-z\\u0101\\u014D\\u016B]+\\-?){1,3}/i,\n    monthsShortStrictRegex: /(?:['a-z\\u0101\\u014D\\u016B]+\\-?){1,2}/i,\n    weekdays: 'Rātapu_Mane_Tūrei_Wenerei_Tāite_Paraire_Hātarei'.split('_'),\n    weekdaysShort: 'Ta_Ma_Tū_We_Tāi_Pa_Hā'.split('_'),\n    weekdaysMin: 'Ta_Ma_Tū_We_Tāi_Pa_Hā'.split('_'),\n    longDateFormat: {\n        LT: 'HH:mm',\n        LTS: 'HH:mm:ss',\n        L: 'DD/MM/YYYY',\n        LL: 'D MMMM YYYY',\n        LLL: 'D MMMM YYYY [i] HH:mm',\n        LLLL: 'dddd, D MMMM YYYY [i] HH:mm'\n    },\n    calendar: {\n        sameDay: '[i teie mahana, i] LT',\n        nextDay: '[apopo i] LT',\n        nextWeek: 'dddd [i] LT',\n        lastDay: '[inanahi i] LT',\n        lastWeek: 'dddd [whakamutunga i] LT',\n        sameElse: 'L'\n    },\n    relativeTime: {\n        future: 'i roto i %s',\n        past: '%s i mua',\n        s: 'te hēkona ruarua',\n        m: 'he meneti',\n        mm: '%d meneti',\n        h: 'te haora',\n        hh: '%d haora',\n        d: 'he ra',\n        dd: '%d ra',\n        M: 'he marama',\n        MM: '%d marama',\n        y: 'he tau',\n        yy: '%d tau'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}º/,\n    ordinal: '%dº',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\nreturn mi;\n\n})));\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/locale/mk.js",
    "content": "//! moment.js locale configuration\n//! locale : Macedonian [mk]\n//! author : Borislav Mickov : https://github.com/B0k0\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\n\nvar mk = moment.defineLocale('mk', {\n    months : 'јануари_февруари_март_април_мај_јуни_јули_август_септември_октомври_ноември_декември'.split('_'),\n    monthsShort : 'јан_фев_мар_апр_мај_јун_јул_авг_сеп_окт_ное_дек'.split('_'),\n    weekdays : 'недела_понеделник_вторник_среда_четврток_петок_сабота'.split('_'),\n    weekdaysShort : 'нед_пон_вто_сре_чет_пет_саб'.split('_'),\n    weekdaysMin : 'нe_пo_вт_ср_че_пе_сa'.split('_'),\n    longDateFormat : {\n        LT : 'H:mm',\n        LTS : 'H:mm:ss',\n        L : 'D.MM.YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY H:mm',\n        LLLL : 'dddd, D MMMM YYYY H:mm'\n    },\n    calendar : {\n        sameDay : '[Денес во] LT',\n        nextDay : '[Утре во] LT',\n        nextWeek : '[Во] dddd [во] LT',\n        lastDay : '[Вчера во] LT',\n        lastWeek : function () {\n            switch (this.day()) {\n                case 0:\n                case 3:\n                case 6:\n                    return '[Изминатата] dddd [во] LT';\n                case 1:\n                case 2:\n                case 4:\n                case 5:\n                    return '[Изминатиот] dddd [во] LT';\n            }\n        },\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'после %s',\n        past : 'пред %s',\n        s : 'неколку секунди',\n        m : 'минута',\n        mm : '%d минути',\n        h : 'час',\n        hh : '%d часа',\n        d : 'ден',\n        dd : '%d дена',\n        M : 'месец',\n        MM : '%d месеци',\n        y : 'година',\n        yy : '%d години'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}-(ев|ен|ти|ви|ри|ми)/,\n    ordinal : function (number) {\n        var lastDigit = number % 10,\n            last2Digits = number % 100;\n        if (number === 0) {\n            return number + '-ев';\n        } else if (last2Digits === 0) {\n            return number + '-ен';\n        } else if (last2Digits > 10 && last2Digits < 20) {\n            return number + '-ти';\n        } else if (lastDigit === 1) {\n            return number + '-ви';\n        } else if (lastDigit === 2) {\n            return number + '-ри';\n        } else if (lastDigit === 7 || lastDigit === 8) {\n            return number + '-ми';\n        } else {\n            return number + '-ти';\n        }\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 7  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\nreturn mk;\n\n})));\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/locale/ml.js",
    "content": "//! moment.js locale configuration\n//! locale : Malayalam [ml]\n//! author : Floyd Pink : https://github.com/floydpink\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\n\nvar ml = moment.defineLocale('ml', {\n    months : 'ജനുവരി_ഫെബ്രുവരി_മാർച്ച്_ഏപ്രിൽ_മേയ്_ജൂൺ_ജൂലൈ_ഓഗസ്റ്റ്_സെപ്റ്റംബർ_ഒക്ടോബർ_നവംബർ_ഡിസംബർ'.split('_'),\n    monthsShort : 'ജനു._ഫെബ്രു._മാർ._ഏപ്രി._മേയ്_ജൂൺ_ജൂലൈ._ഓഗ._സെപ്റ്റ._ഒക്ടോ._നവം._ഡിസം.'.split('_'),\n    monthsParseExact : true,\n    weekdays : 'ഞായറാഴ്ച_തിങ്കളാഴ്ച_ചൊവ്വാഴ്ച_ബുധനാഴ്ച_വ്യാഴാഴ്ച_വെള്ളിയാഴ്ച_ശനിയാഴ്ച'.split('_'),\n    weekdaysShort : 'ഞായർ_തിങ്കൾ_ചൊവ്വ_ബുധൻ_വ്യാഴം_വെള്ളി_ശനി'.split('_'),\n    weekdaysMin : 'ഞാ_തി_ചൊ_ബു_വ്യാ_വെ_ശ'.split('_'),\n    longDateFormat : {\n        LT : 'A h:mm -നു',\n        LTS : 'A h:mm:ss -നു',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY, A h:mm -നു',\n        LLLL : 'dddd, D MMMM YYYY, A h:mm -നു'\n    },\n    calendar : {\n        sameDay : '[ഇന്ന്] LT',\n        nextDay : '[നാളെ] LT',\n        nextWeek : 'dddd, LT',\n        lastDay : '[ഇന്നലെ] LT',\n        lastWeek : '[കഴിഞ്ഞ] dddd, LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : '%s കഴിഞ്ഞ്',\n        past : '%s മുൻപ്',\n        s : 'അൽപ നിമിഷങ്ങൾ',\n        m : 'ഒരു മിനിറ്റ്',\n        mm : '%d മിനിറ്റ്',\n        h : 'ഒരു മണിക്കൂർ',\n        hh : '%d മണിക്കൂർ',\n        d : 'ഒരു ദിവസം',\n        dd : '%d ദിവസം',\n        M : 'ഒരു മാസം',\n        MM : '%d മാസം',\n        y : 'ഒരു വർഷം',\n        yy : '%d വർഷം'\n    },\n    meridiemParse: /രാത്രി|രാവിലെ|ഉച്ച കഴിഞ്ഞ്|വൈകുന്നേരം|രാത്രി/i,\n    meridiemHour : function (hour, meridiem) {\n        if (hour === 12) {\n            hour = 0;\n        }\n        if ((meridiem === 'രാത്രി' && hour >= 4) ||\n                meridiem === 'ഉച്ച കഴിഞ്ഞ്' ||\n                meridiem === 'വൈകുന്നേരം') {\n            return hour + 12;\n        } else {\n            return hour;\n        }\n    },\n    meridiem : function (hour, minute, isLower) {\n        if (hour < 4) {\n            return 'രാത്രി';\n        } else if (hour < 12) {\n            return 'രാവിലെ';\n        } else if (hour < 17) {\n            return 'ഉച്ച കഴിഞ്ഞ്';\n        } else if (hour < 20) {\n            return 'വൈകുന്നേരം';\n        } else {\n            return 'രാത്രി';\n        }\n    }\n});\n\nreturn ml;\n\n})));\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/locale/mr.js",
    "content": "//! moment.js locale configuration\n//! locale : Marathi [mr]\n//! author : Harshad Kale : https://github.com/kalehv\n//! author : Vivek Athalye : https://github.com/vnathalye\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\n\nvar symbolMap = {\n    '1': '१',\n    '2': '२',\n    '3': '३',\n    '4': '४',\n    '5': '५',\n    '6': '६',\n    '7': '७',\n    '8': '८',\n    '9': '९',\n    '0': '०'\n};\nvar numberMap = {\n    '१': '1',\n    '२': '2',\n    '३': '3',\n    '४': '4',\n    '५': '5',\n    '६': '6',\n    '७': '7',\n    '८': '8',\n    '९': '9',\n    '०': '0'\n};\n\nfunction relativeTimeMr(number, withoutSuffix, string, isFuture)\n{\n    var output = '';\n    if (withoutSuffix) {\n        switch (string) {\n            case 's': output = 'काही सेकंद'; break;\n            case 'm': output = 'एक मिनिट'; break;\n            case 'mm': output = '%d मिनिटे'; break;\n            case 'h': output = 'एक तास'; break;\n            case 'hh': output = '%d तास'; break;\n            case 'd': output = 'एक दिवस'; break;\n            case 'dd': output = '%d दिवस'; break;\n            case 'M': output = 'एक महिना'; break;\n            case 'MM': output = '%d महिने'; break;\n            case 'y': output = 'एक वर्ष'; break;\n            case 'yy': output = '%d वर्षे'; break;\n        }\n    }\n    else {\n        switch (string) {\n            case 's': output = 'काही सेकंदां'; break;\n            case 'm': output = 'एका मिनिटा'; break;\n            case 'mm': output = '%d मिनिटां'; break;\n            case 'h': output = 'एका तासा'; break;\n            case 'hh': output = '%d तासां'; break;\n            case 'd': output = 'एका दिवसा'; break;\n            case 'dd': output = '%d दिवसां'; break;\n            case 'M': output = 'एका महिन्या'; break;\n            case 'MM': output = '%d महिन्यां'; break;\n            case 'y': output = 'एका वर्षा'; break;\n            case 'yy': output = '%d वर्षां'; break;\n        }\n    }\n    return output.replace(/%d/i, number);\n}\n\nvar mr = moment.defineLocale('mr', {\n    months : 'जानेवारी_फेब्रुवारी_मार्च_एप्रिल_मे_जून_जुलै_ऑगस्ट_सप्टेंबर_ऑक्टोबर_नोव्हेंबर_डिसेंबर'.split('_'),\n    monthsShort: 'जाने._फेब्रु._मार्च._एप्रि._मे._जून._जुलै._ऑग._सप्टें._ऑक्टो._नोव्हें._डिसें.'.split('_'),\n    monthsParseExact : true,\n    weekdays : 'रविवार_सोमवार_मंगळवार_बुधवार_गुरूवार_शुक्रवार_शनिवार'.split('_'),\n    weekdaysShort : 'रवि_सोम_मंगळ_बुध_गुरू_शुक्र_शनि'.split('_'),\n    weekdaysMin : 'र_सो_मं_बु_गु_शु_श'.split('_'),\n    longDateFormat : {\n        LT : 'A h:mm वाजता',\n        LTS : 'A h:mm:ss वाजता',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY, A h:mm वाजता',\n        LLLL : 'dddd, D MMMM YYYY, A h:mm वाजता'\n    },\n    calendar : {\n        sameDay : '[आज] LT',\n        nextDay : '[उद्या] LT',\n        nextWeek : 'dddd, LT',\n        lastDay : '[काल] LT',\n        lastWeek: '[मागील] dddd, LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future: '%sमध्ये',\n        past: '%sपूर्वी',\n        s: relativeTimeMr,\n        m: relativeTimeMr,\n        mm: relativeTimeMr,\n        h: relativeTimeMr,\n        hh: relativeTimeMr,\n        d: relativeTimeMr,\n        dd: relativeTimeMr,\n        M: relativeTimeMr,\n        MM: relativeTimeMr,\n        y: relativeTimeMr,\n        yy: relativeTimeMr\n    },\n    preparse: function (string) {\n        return string.replace(/[१२३४५६७८९०]/g, function (match) {\n            return numberMap[match];\n        });\n    },\n    postformat: function (string) {\n        return string.replace(/\\d/g, function (match) {\n            return symbolMap[match];\n        });\n    },\n    meridiemParse: /रात्री|सकाळी|दुपारी|सायंकाळी/,\n    meridiemHour : function (hour, meridiem) {\n        if (hour === 12) {\n            hour = 0;\n        }\n        if (meridiem === 'रात्री') {\n            return hour < 4 ? hour : hour + 12;\n        } else if (meridiem === 'सकाळी') {\n            return hour;\n        } else if (meridiem === 'दुपारी') {\n            return hour >= 10 ? hour : hour + 12;\n        } else if (meridiem === 'सायंकाळी') {\n            return hour + 12;\n        }\n    },\n    meridiem: function (hour, minute, isLower) {\n        if (hour < 4) {\n            return 'रात्री';\n        } else if (hour < 10) {\n            return 'सकाळी';\n        } else if (hour < 17) {\n            return 'दुपारी';\n        } else if (hour < 20) {\n            return 'सायंकाळी';\n        } else {\n            return 'रात्री';\n        }\n    },\n    week : {\n        dow : 0, // Sunday is the first day of the week.\n        doy : 6  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\nreturn mr;\n\n})));\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/locale/ms-my.js",
    "content": "//! moment.js locale configuration\n//! locale : Malay [ms-my]\n//! note : DEPRECATED, the correct one is [ms]\n//! author : Weldan Jamili : https://github.com/weldan\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\n\nvar msMy = moment.defineLocale('ms-my', {\n    months : 'Januari_Februari_Mac_April_Mei_Jun_Julai_Ogos_September_Oktober_November_Disember'.split('_'),\n    monthsShort : 'Jan_Feb_Mac_Apr_Mei_Jun_Jul_Ogs_Sep_Okt_Nov_Dis'.split('_'),\n    weekdays : 'Ahad_Isnin_Selasa_Rabu_Khamis_Jumaat_Sabtu'.split('_'),\n    weekdaysShort : 'Ahd_Isn_Sel_Rab_Kha_Jum_Sab'.split('_'),\n    weekdaysMin : 'Ah_Is_Sl_Rb_Km_Jm_Sb'.split('_'),\n    longDateFormat : {\n        LT : 'HH.mm',\n        LTS : 'HH.mm.ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY [pukul] HH.mm',\n        LLLL : 'dddd, D MMMM YYYY [pukul] HH.mm'\n    },\n    meridiemParse: /pagi|tengahari|petang|malam/,\n    meridiemHour: function (hour, meridiem) {\n        if (hour === 12) {\n            hour = 0;\n        }\n        if (meridiem === 'pagi') {\n            return hour;\n        } else if (meridiem === 'tengahari') {\n            return hour >= 11 ? hour : hour + 12;\n        } else if (meridiem === 'petang' || meridiem === 'malam') {\n            return hour + 12;\n        }\n    },\n    meridiem : function (hours, minutes, isLower) {\n        if (hours < 11) {\n            return 'pagi';\n        } else if (hours < 15) {\n            return 'tengahari';\n        } else if (hours < 19) {\n            return 'petang';\n        } else {\n            return 'malam';\n        }\n    },\n    calendar : {\n        sameDay : '[Hari ini pukul] LT',\n        nextDay : '[Esok pukul] LT',\n        nextWeek : 'dddd [pukul] LT',\n        lastDay : '[Kelmarin pukul] LT',\n        lastWeek : 'dddd [lepas pukul] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'dalam %s',\n        past : '%s yang lepas',\n        s : 'beberapa saat',\n        m : 'seminit',\n        mm : '%d minit',\n        h : 'sejam',\n        hh : '%d jam',\n        d : 'sehari',\n        dd : '%d hari',\n        M : 'sebulan',\n        MM : '%d bulan',\n        y : 'setahun',\n        yy : '%d tahun'\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 7  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\nreturn msMy;\n\n})));\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/locale/ms.js",
    "content": "//! moment.js locale configuration\n//! locale : Malay [ms]\n//! author : Weldan Jamili : https://github.com/weldan\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\n\nvar ms = moment.defineLocale('ms', {\n    months : 'Januari_Februari_Mac_April_Mei_Jun_Julai_Ogos_September_Oktober_November_Disember'.split('_'),\n    monthsShort : 'Jan_Feb_Mac_Apr_Mei_Jun_Jul_Ogs_Sep_Okt_Nov_Dis'.split('_'),\n    weekdays : 'Ahad_Isnin_Selasa_Rabu_Khamis_Jumaat_Sabtu'.split('_'),\n    weekdaysShort : 'Ahd_Isn_Sel_Rab_Kha_Jum_Sab'.split('_'),\n    weekdaysMin : 'Ah_Is_Sl_Rb_Km_Jm_Sb'.split('_'),\n    longDateFormat : {\n        LT : 'HH.mm',\n        LTS : 'HH.mm.ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY [pukul] HH.mm',\n        LLLL : 'dddd, D MMMM YYYY [pukul] HH.mm'\n    },\n    meridiemParse: /pagi|tengahari|petang|malam/,\n    meridiemHour: function (hour, meridiem) {\n        if (hour === 12) {\n            hour = 0;\n        }\n        if (meridiem === 'pagi') {\n            return hour;\n        } else if (meridiem === 'tengahari') {\n            return hour >= 11 ? hour : hour + 12;\n        } else if (meridiem === 'petang' || meridiem === 'malam') {\n            return hour + 12;\n        }\n    },\n    meridiem : function (hours, minutes, isLower) {\n        if (hours < 11) {\n            return 'pagi';\n        } else if (hours < 15) {\n            return 'tengahari';\n        } else if (hours < 19) {\n            return 'petang';\n        } else {\n            return 'malam';\n        }\n    },\n    calendar : {\n        sameDay : '[Hari ini pukul] LT',\n        nextDay : '[Esok pukul] LT',\n        nextWeek : 'dddd [pukul] LT',\n        lastDay : '[Kelmarin pukul] LT',\n        lastWeek : 'dddd [lepas pukul] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'dalam %s',\n        past : '%s yang lepas',\n        s : 'beberapa saat',\n        m : 'seminit',\n        mm : '%d minit',\n        h : 'sejam',\n        hh : '%d jam',\n        d : 'sehari',\n        dd : '%d hari',\n        M : 'sebulan',\n        MM : '%d bulan',\n        y : 'setahun',\n        yy : '%d tahun'\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 7  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\nreturn ms;\n\n})));\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/locale/my.js",
    "content": "//! moment.js locale configuration\n//! locale : Burmese [my]\n//! author : Squar team, mysquar.com\n//! author : David Rossellat : https://github.com/gholadr\n//! author : Tin Aung Lin : https://github.com/thanyawzinmin\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\n\nvar symbolMap = {\n    '1': '၁',\n    '2': '၂',\n    '3': '၃',\n    '4': '၄',\n    '5': '၅',\n    '6': '၆',\n    '7': '၇',\n    '8': '၈',\n    '9': '၉',\n    '0': '၀'\n};\nvar numberMap = {\n    '၁': '1',\n    '၂': '2',\n    '၃': '3',\n    '၄': '4',\n    '၅': '5',\n    '၆': '6',\n    '၇': '7',\n    '၈': '8',\n    '၉': '9',\n    '၀': '0'\n};\n\nvar my = moment.defineLocale('my', {\n    months: 'ဇန်နဝါရီ_ဖေဖော်ဝါရီ_မတ်_ဧပြီ_မေ_ဇွန်_ဇူလိုင်_သြဂုတ်_စက်တင်ဘာ_အောက်တိုဘာ_နိုဝင်ဘာ_ဒီဇင်ဘာ'.split('_'),\n    monthsShort: 'ဇန်_ဖေ_မတ်_ပြီ_မေ_ဇွန်_လိုင်_သြ_စက်_အောက်_နို_ဒီ'.split('_'),\n    weekdays: 'တနင်္ဂနွေ_တနင်္လာ_အင်္ဂါ_ဗုဒ္ဓဟူး_ကြာသပတေး_သောကြာ_စနေ'.split('_'),\n    weekdaysShort: 'နွေ_လာ_ဂါ_ဟူး_ကြာ_သော_နေ'.split('_'),\n    weekdaysMin: 'နွေ_လာ_ဂါ_ဟူး_ကြာ_သော_နေ'.split('_'),\n\n    longDateFormat: {\n        LT: 'HH:mm',\n        LTS: 'HH:mm:ss',\n        L: 'DD/MM/YYYY',\n        LL: 'D MMMM YYYY',\n        LLL: 'D MMMM YYYY HH:mm',\n        LLLL: 'dddd D MMMM YYYY HH:mm'\n    },\n    calendar: {\n        sameDay: '[ယနေ.] LT [မှာ]',\n        nextDay: '[မနက်ဖြန်] LT [မှာ]',\n        nextWeek: 'dddd LT [မှာ]',\n        lastDay: '[မနေ.က] LT [မှာ]',\n        lastWeek: '[ပြီးခဲ့သော] dddd LT [မှာ]',\n        sameElse: 'L'\n    },\n    relativeTime: {\n        future: 'လာမည့် %s မှာ',\n        past: 'လွန်ခဲ့သော %s က',\n        s: 'စက္ကန်.အနည်းငယ်',\n        m: 'တစ်မိနစ်',\n        mm: '%d မိနစ်',\n        h: 'တစ်နာရီ',\n        hh: '%d နာရီ',\n        d: 'တစ်ရက်',\n        dd: '%d ရက်',\n        M: 'တစ်လ',\n        MM: '%d လ',\n        y: 'တစ်နှစ်',\n        yy: '%d နှစ်'\n    },\n    preparse: function (string) {\n        return string.replace(/[၁၂၃၄၅၆၇၈၉၀]/g, function (match) {\n            return numberMap[match];\n        });\n    },\n    postformat: function (string) {\n        return string.replace(/\\d/g, function (match) {\n            return symbolMap[match];\n        });\n    },\n    week: {\n        dow: 1, // Monday is the first day of the week.\n        doy: 4 // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\nreturn my;\n\n})));\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/locale/nb.js",
    "content": "//! moment.js locale configuration\n//! locale : Norwegian Bokmål [nb]\n//! authors : Espen Hovlandsdal : https://github.com/rexxars\n//!           Sigurd Gartmann : https://github.com/sigurdga\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\n\nvar nb = moment.defineLocale('nb', {\n    months : 'januar_februar_mars_april_mai_juni_juli_august_september_oktober_november_desember'.split('_'),\n    monthsShort : 'jan._feb._mars_april_mai_juni_juli_aug._sep._okt._nov._des.'.split('_'),\n    monthsParseExact : true,\n    weekdays : 'søndag_mandag_tirsdag_onsdag_torsdag_fredag_lørdag'.split('_'),\n    weekdaysShort : 'sø._ma._ti._on._to._fr._lø.'.split('_'),\n    weekdaysMin : 'sø_ma_ti_on_to_fr_lø'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD.MM.YYYY',\n        LL : 'D. MMMM YYYY',\n        LLL : 'D. MMMM YYYY [kl.] HH:mm',\n        LLLL : 'dddd D. MMMM YYYY [kl.] HH:mm'\n    },\n    calendar : {\n        sameDay: '[i dag kl.] LT',\n        nextDay: '[i morgen kl.] LT',\n        nextWeek: 'dddd [kl.] LT',\n        lastDay: '[i går kl.] LT',\n        lastWeek: '[forrige] dddd [kl.] LT',\n        sameElse: 'L'\n    },\n    relativeTime : {\n        future : 'om %s',\n        past : '%s siden',\n        s : 'noen sekunder',\n        m : 'ett minutt',\n        mm : '%d minutter',\n        h : 'en time',\n        hh : '%d timer',\n        d : 'en dag',\n        dd : '%d dager',\n        M : 'en måned',\n        MM : '%d måneder',\n        y : 'ett år',\n        yy : '%d år'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}\\./,\n    ordinal : '%d.',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\nreturn nb;\n\n})));\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/locale/ne.js",
    "content": "//! moment.js locale configuration\n//! locale : Nepalese [ne]\n//! author : suvash : https://github.com/suvash\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\n\nvar symbolMap = {\n    '1': '१',\n    '2': '२',\n    '3': '३',\n    '4': '४',\n    '5': '५',\n    '6': '६',\n    '7': '७',\n    '8': '८',\n    '9': '९',\n    '0': '०'\n};\nvar numberMap = {\n    '१': '1',\n    '२': '2',\n    '३': '3',\n    '४': '4',\n    '५': '5',\n    '६': '6',\n    '७': '7',\n    '८': '8',\n    '९': '9',\n    '०': '0'\n};\n\nvar ne = moment.defineLocale('ne', {\n    months : 'जनवरी_फेब्रुवरी_मार्च_अप्रिल_मई_जुन_जुलाई_अगष्ट_सेप्टेम्बर_अक्टोबर_नोभेम्बर_डिसेम्बर'.split('_'),\n    monthsShort : 'जन._फेब्रु._मार्च_अप्रि._मई_जुन_जुलाई._अग._सेप्ट._अक्टो._नोभे._डिसे.'.split('_'),\n    monthsParseExact : true,\n    weekdays : 'आइतबार_सोमबार_मङ्गलबार_बुधबार_बिहिबार_शुक्रबार_शनिबार'.split('_'),\n    weekdaysShort : 'आइत._सोम._मङ्गल._बुध._बिहि._शुक्र._शनि.'.split('_'),\n    weekdaysMin : 'आ._सो._मं._बु._बि._शु._श.'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat : {\n        LT : 'Aको h:mm बजे',\n        LTS : 'Aको h:mm:ss बजे',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY, Aको h:mm बजे',\n        LLLL : 'dddd, D MMMM YYYY, Aको h:mm बजे'\n    },\n    preparse: function (string) {\n        return string.replace(/[१२३४५६७८९०]/g, function (match) {\n            return numberMap[match];\n        });\n    },\n    postformat: function (string) {\n        return string.replace(/\\d/g, function (match) {\n            return symbolMap[match];\n        });\n    },\n    meridiemParse: /राति|बिहान|दिउँसो|साँझ/,\n    meridiemHour : function (hour, meridiem) {\n        if (hour === 12) {\n            hour = 0;\n        }\n        if (meridiem === 'राति') {\n            return hour < 4 ? hour : hour + 12;\n        } else if (meridiem === 'बिहान') {\n            return hour;\n        } else if (meridiem === 'दिउँसो') {\n            return hour >= 10 ? hour : hour + 12;\n        } else if (meridiem === 'साँझ') {\n            return hour + 12;\n        }\n    },\n    meridiem : function (hour, minute, isLower) {\n        if (hour < 3) {\n            return 'राति';\n        } else if (hour < 12) {\n            return 'बिहान';\n        } else if (hour < 16) {\n            return 'दिउँसो';\n        } else if (hour < 20) {\n            return 'साँझ';\n        } else {\n            return 'राति';\n        }\n    },\n    calendar : {\n        sameDay : '[आज] LT',\n        nextDay : '[भोलि] LT',\n        nextWeek : '[आउँदो] dddd[,] LT',\n        lastDay : '[हिजो] LT',\n        lastWeek : '[गएको] dddd[,] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : '%sमा',\n        past : '%s अगाडि',\n        s : 'केही क्षण',\n        m : 'एक मिनेट',\n        mm : '%d मिनेट',\n        h : 'एक घण्टा',\n        hh : '%d घण्टा',\n        d : 'एक दिन',\n        dd : '%d दिन',\n        M : 'एक महिना',\n        MM : '%d महिना',\n        y : 'एक बर्ष',\n        yy : '%d बर्ष'\n    },\n    week : {\n        dow : 0, // Sunday is the first day of the week.\n        doy : 6  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\nreturn ne;\n\n})));\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/locale/nl-be.js",
    "content": "//! moment.js locale configuration\n//! locale : Dutch (Belgium) [nl-be]\n//! author : Joris Röling : https://github.com/jorisroling\n//! author : Jacob Middag : https://github.com/middagj\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\n\nvar monthsShortWithDots = 'jan._feb._mrt._apr._mei_jun._jul._aug._sep._okt._nov._dec.'.split('_');\nvar monthsShortWithoutDots = 'jan_feb_mrt_apr_mei_jun_jul_aug_sep_okt_nov_dec'.split('_');\n\nvar monthsParse = [/^jan/i, /^feb/i, /^maart|mrt.?$/i, /^apr/i, /^mei$/i, /^jun[i.]?$/i, /^jul[i.]?$/i, /^aug/i, /^sep/i, /^okt/i, /^nov/i, /^dec/i];\nvar monthsRegex = /^(januari|februari|maart|april|mei|april|ju[nl]i|augustus|september|oktober|november|december|jan\\.?|feb\\.?|mrt\\.?|apr\\.?|ju[nl]\\.?|aug\\.?|sep\\.?|okt\\.?|nov\\.?|dec\\.?)/i;\n\nvar nlBe = moment.defineLocale('nl-be', {\n    months : 'januari_februari_maart_april_mei_juni_juli_augustus_september_oktober_november_december'.split('_'),\n    monthsShort : function (m, format) {\n        if (!m) {\n            return monthsShortWithDots;\n        } else if (/-MMM-/.test(format)) {\n            return monthsShortWithoutDots[m.month()];\n        } else {\n            return monthsShortWithDots[m.month()];\n        }\n    },\n\n    monthsRegex: monthsRegex,\n    monthsShortRegex: monthsRegex,\n    monthsStrictRegex: /^(januari|februari|maart|mei|ju[nl]i|april|augustus|september|oktober|november|december)/i,\n    monthsShortStrictRegex: /^(jan\\.?|feb\\.?|mrt\\.?|apr\\.?|mei|ju[nl]\\.?|aug\\.?|sep\\.?|okt\\.?|nov\\.?|dec\\.?)/i,\n\n    monthsParse : monthsParse,\n    longMonthsParse : monthsParse,\n    shortMonthsParse : monthsParse,\n\n    weekdays : 'zondag_maandag_dinsdag_woensdag_donderdag_vrijdag_zaterdag'.split('_'),\n    weekdaysShort : 'zo._ma._di._wo._do._vr._za.'.split('_'),\n    weekdaysMin : 'Zo_Ma_Di_Wo_Do_Vr_Za'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY HH:mm',\n        LLLL : 'dddd D MMMM YYYY HH:mm'\n    },\n    calendar : {\n        sameDay: '[vandaag om] LT',\n        nextDay: '[morgen om] LT',\n        nextWeek: 'dddd [om] LT',\n        lastDay: '[gisteren om] LT',\n        lastWeek: '[afgelopen] dddd [om] LT',\n        sameElse: 'L'\n    },\n    relativeTime : {\n        future : 'over %s',\n        past : '%s geleden',\n        s : 'een paar seconden',\n        m : 'één minuut',\n        mm : '%d minuten',\n        h : 'één uur',\n        hh : '%d uur',\n        d : 'één dag',\n        dd : '%d dagen',\n        M : 'één maand',\n        MM : '%d maanden',\n        y : 'één jaar',\n        yy : '%d jaar'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}(ste|de)/,\n    ordinal : function (number) {\n        return number + ((number === 1 || number === 8 || number >= 20) ? 'ste' : 'de');\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\nreturn nlBe;\n\n})));\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/locale/nl.js",
    "content": "//! moment.js locale configuration\n//! locale : Dutch [nl]\n//! author : Joris Röling : https://github.com/jorisroling\n//! author : Jacob Middag : https://github.com/middagj\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\n\nvar monthsShortWithDots = 'jan._feb._mrt._apr._mei_jun._jul._aug._sep._okt._nov._dec.'.split('_');\nvar monthsShortWithoutDots = 'jan_feb_mrt_apr_mei_jun_jul_aug_sep_okt_nov_dec'.split('_');\n\nvar monthsParse = [/^jan/i, /^feb/i, /^maart|mrt.?$/i, /^apr/i, /^mei$/i, /^jun[i.]?$/i, /^jul[i.]?$/i, /^aug/i, /^sep/i, /^okt/i, /^nov/i, /^dec/i];\nvar monthsRegex = /^(januari|februari|maart|april|mei|april|ju[nl]i|augustus|september|oktober|november|december|jan\\.?|feb\\.?|mrt\\.?|apr\\.?|ju[nl]\\.?|aug\\.?|sep\\.?|okt\\.?|nov\\.?|dec\\.?)/i;\n\nvar nl = moment.defineLocale('nl', {\n    months : 'januari_februari_maart_april_mei_juni_juli_augustus_september_oktober_november_december'.split('_'),\n    monthsShort : function (m, format) {\n        if (!m) {\n            return monthsShortWithDots;\n        } else if (/-MMM-/.test(format)) {\n            return monthsShortWithoutDots[m.month()];\n        } else {\n            return monthsShortWithDots[m.month()];\n        }\n    },\n\n    monthsRegex: monthsRegex,\n    monthsShortRegex: monthsRegex,\n    monthsStrictRegex: /^(januari|februari|maart|mei|ju[nl]i|april|augustus|september|oktober|november|december)/i,\n    monthsShortStrictRegex: /^(jan\\.?|feb\\.?|mrt\\.?|apr\\.?|mei|ju[nl]\\.?|aug\\.?|sep\\.?|okt\\.?|nov\\.?|dec\\.?)/i,\n\n    monthsParse : monthsParse,\n    longMonthsParse : monthsParse,\n    shortMonthsParse : monthsParse,\n\n    weekdays : 'zondag_maandag_dinsdag_woensdag_donderdag_vrijdag_zaterdag'.split('_'),\n    weekdaysShort : 'zo._ma._di._wo._do._vr._za.'.split('_'),\n    weekdaysMin : 'Zo_Ma_Di_Wo_Do_Vr_Za'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD-MM-YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY HH:mm',\n        LLLL : 'dddd D MMMM YYYY HH:mm'\n    },\n    calendar : {\n        sameDay: '[vandaag om] LT',\n        nextDay: '[morgen om] LT',\n        nextWeek: 'dddd [om] LT',\n        lastDay: '[gisteren om] LT',\n        lastWeek: '[afgelopen] dddd [om] LT',\n        sameElse: 'L'\n    },\n    relativeTime : {\n        future : 'over %s',\n        past : '%s geleden',\n        s : 'een paar seconden',\n        m : 'één minuut',\n        mm : '%d minuten',\n        h : 'één uur',\n        hh : '%d uur',\n        d : 'één dag',\n        dd : '%d dagen',\n        M : 'één maand',\n        MM : '%d maanden',\n        y : 'één jaar',\n        yy : '%d jaar'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}(ste|de)/,\n    ordinal : function (number) {\n        return number + ((number === 1 || number === 8 || number >= 20) ? 'ste' : 'de');\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\nreturn nl;\n\n})));\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/locale/nn.js",
    "content": "//! moment.js locale configuration\n//! locale : Nynorsk [nn]\n//! author : https://github.com/mechuwind\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\n\nvar nn = moment.defineLocale('nn', {\n    months : 'januar_februar_mars_april_mai_juni_juli_august_september_oktober_november_desember'.split('_'),\n    monthsShort : 'jan_feb_mar_apr_mai_jun_jul_aug_sep_okt_nov_des'.split('_'),\n    weekdays : 'sundag_måndag_tysdag_onsdag_torsdag_fredag_laurdag'.split('_'),\n    weekdaysShort : 'sun_mån_tys_ons_tor_fre_lau'.split('_'),\n    weekdaysMin : 'su_må_ty_on_to_fr_lø'.split('_'),\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD.MM.YYYY',\n        LL : 'D. MMMM YYYY',\n        LLL : 'D. MMMM YYYY [kl.] H:mm',\n        LLLL : 'dddd D. MMMM YYYY [kl.] HH:mm'\n    },\n    calendar : {\n        sameDay: '[I dag klokka] LT',\n        nextDay: '[I morgon klokka] LT',\n        nextWeek: 'dddd [klokka] LT',\n        lastDay: '[I går klokka] LT',\n        lastWeek: '[Føregåande] dddd [klokka] LT',\n        sameElse: 'L'\n    },\n    relativeTime : {\n        future : 'om %s',\n        past : '%s sidan',\n        s : 'nokre sekund',\n        m : 'eit minutt',\n        mm : '%d minutt',\n        h : 'ein time',\n        hh : '%d timar',\n        d : 'ein dag',\n        dd : '%d dagar',\n        M : 'ein månad',\n        MM : '%d månader',\n        y : 'eit år',\n        yy : '%d år'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}\\./,\n    ordinal : '%d.',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\nreturn nn;\n\n})));\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/locale/pa-in.js",
    "content": "//! moment.js locale configuration\n//! locale : Punjabi (India) [pa-in]\n//! author : Harpreet Singh : https://github.com/harpreetkhalsagtbit\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\n\nvar symbolMap = {\n    '1': '੧',\n    '2': '੨',\n    '3': '੩',\n    '4': '੪',\n    '5': '੫',\n    '6': '੬',\n    '7': '੭',\n    '8': '੮',\n    '9': '੯',\n    '0': '੦'\n};\nvar numberMap = {\n    '੧': '1',\n    '੨': '2',\n    '੩': '3',\n    '੪': '4',\n    '੫': '5',\n    '੬': '6',\n    '੭': '7',\n    '੮': '8',\n    '੯': '9',\n    '੦': '0'\n};\n\nvar paIn = moment.defineLocale('pa-in', {\n    // There are months name as per Nanakshahi Calender but they are not used as rigidly in modern Punjabi.\n    months : 'ਜਨਵਰੀ_ਫ਼ਰਵਰੀ_ਮਾਰਚ_ਅਪ੍ਰੈਲ_ਮਈ_ਜੂਨ_ਜੁਲਾਈ_ਅਗਸਤ_ਸਤੰਬਰ_ਅਕਤੂਬਰ_ਨਵੰਬਰ_ਦਸੰਬਰ'.split('_'),\n    monthsShort : 'ਜਨਵਰੀ_ਫ਼ਰਵਰੀ_ਮਾਰਚ_ਅਪ੍ਰੈਲ_ਮਈ_ਜੂਨ_ਜੁਲਾਈ_ਅਗਸਤ_ਸਤੰਬਰ_ਅਕਤੂਬਰ_ਨਵੰਬਰ_ਦਸੰਬਰ'.split('_'),\n    weekdays : 'ਐਤਵਾਰ_ਸੋਮਵਾਰ_ਮੰਗਲਵਾਰ_ਬੁਧਵਾਰ_ਵੀਰਵਾਰ_ਸ਼ੁੱਕਰਵਾਰ_ਸ਼ਨੀਚਰਵਾਰ'.split('_'),\n    weekdaysShort : 'ਐਤ_ਸੋਮ_ਮੰਗਲ_ਬੁਧ_ਵੀਰ_ਸ਼ੁਕਰ_ਸ਼ਨੀ'.split('_'),\n    weekdaysMin : 'ਐਤ_ਸੋਮ_ਮੰਗਲ_ਬੁਧ_ਵੀਰ_ਸ਼ੁਕਰ_ਸ਼ਨੀ'.split('_'),\n    longDateFormat : {\n        LT : 'A h:mm ਵਜੇ',\n        LTS : 'A h:mm:ss ਵਜੇ',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY, A h:mm ਵਜੇ',\n        LLLL : 'dddd, D MMMM YYYY, A h:mm ਵਜੇ'\n    },\n    calendar : {\n        sameDay : '[ਅਜ] LT',\n        nextDay : '[ਕਲ] LT',\n        nextWeek : 'dddd, LT',\n        lastDay : '[ਕਲ] LT',\n        lastWeek : '[ਪਿਛਲੇ] dddd, LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : '%s ਵਿੱਚ',\n        past : '%s ਪਿਛਲੇ',\n        s : 'ਕੁਝ ਸਕਿੰਟ',\n        m : 'ਇਕ ਮਿੰਟ',\n        mm : '%d ਮਿੰਟ',\n        h : 'ਇੱਕ ਘੰਟਾ',\n        hh : '%d ਘੰਟੇ',\n        d : 'ਇੱਕ ਦਿਨ',\n        dd : '%d ਦਿਨ',\n        M : 'ਇੱਕ ਮਹੀਨਾ',\n        MM : '%d ਮਹੀਨੇ',\n        y : 'ਇੱਕ ਸਾਲ',\n        yy : '%d ਸਾਲ'\n    },\n    preparse: function (string) {\n        return string.replace(/[੧੨੩੪੫੬੭੮੯੦]/g, function (match) {\n            return numberMap[match];\n        });\n    },\n    postformat: function (string) {\n        return string.replace(/\\d/g, function (match) {\n            return symbolMap[match];\n        });\n    },\n    // Punjabi notation for meridiems are quite fuzzy in practice. While there exists\n    // a rigid notion of a 'Pahar' it is not used as rigidly in modern Punjabi.\n    meridiemParse: /ਰਾਤ|ਸਵੇਰ|ਦੁਪਹਿਰ|ਸ਼ਾਮ/,\n    meridiemHour : function (hour, meridiem) {\n        if (hour === 12) {\n            hour = 0;\n        }\n        if (meridiem === 'ਰਾਤ') {\n            return hour < 4 ? hour : hour + 12;\n        } else if (meridiem === 'ਸਵੇਰ') {\n            return hour;\n        } else if (meridiem === 'ਦੁਪਹਿਰ') {\n            return hour >= 10 ? hour : hour + 12;\n        } else if (meridiem === 'ਸ਼ਾਮ') {\n            return hour + 12;\n        }\n    },\n    meridiem : function (hour, minute, isLower) {\n        if (hour < 4) {\n            return 'ਰਾਤ';\n        } else if (hour < 10) {\n            return 'ਸਵੇਰ';\n        } else if (hour < 17) {\n            return 'ਦੁਪਹਿਰ';\n        } else if (hour < 20) {\n            return 'ਸ਼ਾਮ';\n        } else {\n            return 'ਰਾਤ';\n        }\n    },\n    week : {\n        dow : 0, // Sunday is the first day of the week.\n        doy : 6  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\nreturn paIn;\n\n})));\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/locale/pl.js",
    "content": "//! moment.js locale configuration\n//! locale : Polish [pl]\n//! author : Rafal Hirsz : https://github.com/evoL\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\n\nvar monthsNominative = 'styczeń_luty_marzec_kwiecień_maj_czerwiec_lipiec_sierpień_wrzesień_październik_listopad_grudzień'.split('_');\nvar monthsSubjective = 'stycznia_lutego_marca_kwietnia_maja_czerwca_lipca_sierpnia_września_października_listopada_grudnia'.split('_');\nfunction plural(n) {\n    return (n % 10 < 5) && (n % 10 > 1) && ((~~(n / 10) % 10) !== 1);\n}\nfunction translate(number, withoutSuffix, key) {\n    var result = number + ' ';\n    switch (key) {\n        case 'm':\n            return withoutSuffix ? 'minuta' : 'minutę';\n        case 'mm':\n            return result + (plural(number) ? 'minuty' : 'minut');\n        case 'h':\n            return withoutSuffix  ? 'godzina'  : 'godzinę';\n        case 'hh':\n            return result + (plural(number) ? 'godziny' : 'godzin');\n        case 'MM':\n            return result + (plural(number) ? 'miesiące' : 'miesięcy');\n        case 'yy':\n            return result + (plural(number) ? 'lata' : 'lat');\n    }\n}\n\nvar pl = moment.defineLocale('pl', {\n    months : function (momentToFormat, format) {\n        if (!momentToFormat) {\n            return monthsNominative;\n        } else if (format === '') {\n            // Hack: if format empty we know this is used to generate\n            // RegExp by moment. Give then back both valid forms of months\n            // in RegExp ready format.\n            return '(' + monthsSubjective[momentToFormat.month()] + '|' + monthsNominative[momentToFormat.month()] + ')';\n        } else if (/D MMMM/.test(format)) {\n            return monthsSubjective[momentToFormat.month()];\n        } else {\n            return monthsNominative[momentToFormat.month()];\n        }\n    },\n    monthsShort : 'sty_lut_mar_kwi_maj_cze_lip_sie_wrz_paź_lis_gru'.split('_'),\n    weekdays : 'niedziela_poniedziałek_wtorek_środa_czwartek_piątek_sobota'.split('_'),\n    weekdaysShort : 'ndz_pon_wt_śr_czw_pt_sob'.split('_'),\n    weekdaysMin : 'Nd_Pn_Wt_Śr_Cz_Pt_So'.split('_'),\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD.MM.YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY HH:mm',\n        LLLL : 'dddd, D MMMM YYYY HH:mm'\n    },\n    calendar : {\n        sameDay: '[Dziś o] LT',\n        nextDay: '[Jutro o] LT',\n        nextWeek: '[W] dddd [o] LT',\n        lastDay: '[Wczoraj o] LT',\n        lastWeek: function () {\n            switch (this.day()) {\n                case 0:\n                    return '[W zeszłą niedzielę o] LT';\n                case 3:\n                    return '[W zeszłą środę o] LT';\n                case 6:\n                    return '[W zeszłą sobotę o] LT';\n                default:\n                    return '[W zeszły] dddd [o] LT';\n            }\n        },\n        sameElse: 'L'\n    },\n    relativeTime : {\n        future : 'za %s',\n        past : '%s temu',\n        s : 'kilka sekund',\n        m : translate,\n        mm : translate,\n        h : translate,\n        hh : translate,\n        d : '1 dzień',\n        dd : '%d dni',\n        M : 'miesiąc',\n        MM : translate,\n        y : 'rok',\n        yy : translate\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}\\./,\n    ordinal : '%d.',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\nreturn pl;\n\n})));\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/locale/pt-br.js",
    "content": "//! moment.js locale configuration\n//! locale : Portuguese (Brazil) [pt-br]\n//! author : Caio Ribeiro Pereira : https://github.com/caio-ribeiro-pereira\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\n\nvar ptBr = moment.defineLocale('pt-br', {\n    months : 'Janeiro_Fevereiro_Março_Abril_Maio_Junho_Julho_Agosto_Setembro_Outubro_Novembro_Dezembro'.split('_'),\n    monthsShort : 'Jan_Fev_Mar_Abr_Mai_Jun_Jul_Ago_Set_Out_Nov_Dez'.split('_'),\n    weekdays : 'Domingo_Segunda-feira_Terça-feira_Quarta-feira_Quinta-feira_Sexta-feira_Sábado'.split('_'),\n    weekdaysShort : 'Dom_Seg_Ter_Qua_Qui_Sex_Sáb'.split('_'),\n    weekdaysMin : 'Do_2ª_3ª_4ª_5ª_6ª_Sá'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D [de] MMMM [de] YYYY',\n        LLL : 'D [de] MMMM [de] YYYY [às] HH:mm',\n        LLLL : 'dddd, D [de] MMMM [de] YYYY [às] HH:mm'\n    },\n    calendar : {\n        sameDay: '[Hoje às] LT',\n        nextDay: '[Amanhã às] LT',\n        nextWeek: 'dddd [às] LT',\n        lastDay: '[Ontem às] LT',\n        lastWeek: function () {\n            return (this.day() === 0 || this.day() === 6) ?\n                '[Último] dddd [às] LT' : // Saturday + Sunday\n                '[Última] dddd [às] LT'; // Monday - Friday\n        },\n        sameElse: 'L'\n    },\n    relativeTime : {\n        future : 'em %s',\n        past : '%s atrás',\n        s : 'poucos segundos',\n        m : 'um minuto',\n        mm : '%d minutos',\n        h : 'uma hora',\n        hh : '%d horas',\n        d : 'um dia',\n        dd : '%d dias',\n        M : 'um mês',\n        MM : '%d meses',\n        y : 'um ano',\n        yy : '%d anos'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}º/,\n    ordinal : '%dº'\n});\n\nreturn ptBr;\n\n})));\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/locale/pt.js",
    "content": "//! moment.js locale configuration\n//! locale : Portuguese [pt]\n//! author : Jefferson : https://github.com/jalex79\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\n\nvar pt = moment.defineLocale('pt', {\n    months : 'Janeiro_Fevereiro_Março_Abril_Maio_Junho_Julho_Agosto_Setembro_Outubro_Novembro_Dezembro'.split('_'),\n    monthsShort : 'Jan_Fev_Mar_Abr_Mai_Jun_Jul_Ago_Set_Out_Nov_Dez'.split('_'),\n    weekdays : 'Domingo_Segunda-Feira_Terça-Feira_Quarta-Feira_Quinta-Feira_Sexta-Feira_Sábado'.split('_'),\n    weekdaysShort : 'Dom_Seg_Ter_Qua_Qui_Sex_Sáb'.split('_'),\n    weekdaysMin : 'Do_2ª_3ª_4ª_5ª_6ª_Sá'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D [de] MMMM [de] YYYY',\n        LLL : 'D [de] MMMM [de] YYYY HH:mm',\n        LLLL : 'dddd, D [de] MMMM [de] YYYY HH:mm'\n    },\n    calendar : {\n        sameDay: '[Hoje às] LT',\n        nextDay: '[Amanhã às] LT',\n        nextWeek: 'dddd [às] LT',\n        lastDay: '[Ontem às] LT',\n        lastWeek: function () {\n            return (this.day() === 0 || this.day() === 6) ?\n                '[Último] dddd [às] LT' : // Saturday + Sunday\n                '[Última] dddd [às] LT'; // Monday - Friday\n        },\n        sameElse: 'L'\n    },\n    relativeTime : {\n        future : 'em %s',\n        past : 'há %s',\n        s : 'segundos',\n        m : 'um minuto',\n        mm : '%d minutos',\n        h : 'uma hora',\n        hh : '%d horas',\n        d : 'um dia',\n        dd : '%d dias',\n        M : 'um mês',\n        MM : '%d meses',\n        y : 'um ano',\n        yy : '%d anos'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}º/,\n    ordinal : '%dº',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\nreturn pt;\n\n})));\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/locale/ro.js",
    "content": "//! moment.js locale configuration\n//! locale : Romanian [ro]\n//! author : Vlad Gurdiga : https://github.com/gurdiga\n//! author : Valentin Agachi : https://github.com/avaly\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\n\nfunction relativeTimeWithPlural(number, withoutSuffix, key) {\n    var format = {\n            'mm': 'minute',\n            'hh': 'ore',\n            'dd': 'zile',\n            'MM': 'luni',\n            'yy': 'ani'\n        },\n        separator = ' ';\n    if (number % 100 >= 20 || (number >= 100 && number % 100 === 0)) {\n        separator = ' de ';\n    }\n    return number + separator + format[key];\n}\n\nvar ro = moment.defineLocale('ro', {\n    months : 'ianuarie_februarie_martie_aprilie_mai_iunie_iulie_august_septembrie_octombrie_noiembrie_decembrie'.split('_'),\n    monthsShort : 'ian._febr._mart._apr._mai_iun._iul._aug._sept._oct._nov._dec.'.split('_'),\n    monthsParseExact: true,\n    weekdays : 'duminică_luni_marți_miercuri_joi_vineri_sâmbătă'.split('_'),\n    weekdaysShort : 'Dum_Lun_Mar_Mie_Joi_Vin_Sâm'.split('_'),\n    weekdaysMin : 'Du_Lu_Ma_Mi_Jo_Vi_Sâ'.split('_'),\n    longDateFormat : {\n        LT : 'H:mm',\n        LTS : 'H:mm:ss',\n        L : 'DD.MM.YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY H:mm',\n        LLLL : 'dddd, D MMMM YYYY H:mm'\n    },\n    calendar : {\n        sameDay: '[azi la] LT',\n        nextDay: '[mâine la] LT',\n        nextWeek: 'dddd [la] LT',\n        lastDay: '[ieri la] LT',\n        lastWeek: '[fosta] dddd [la] LT',\n        sameElse: 'L'\n    },\n    relativeTime : {\n        future : 'peste %s',\n        past : '%s în urmă',\n        s : 'câteva secunde',\n        m : 'un minut',\n        mm : relativeTimeWithPlural,\n        h : 'o oră',\n        hh : relativeTimeWithPlural,\n        d : 'o zi',\n        dd : relativeTimeWithPlural,\n        M : 'o lună',\n        MM : relativeTimeWithPlural,\n        y : 'un an',\n        yy : relativeTimeWithPlural\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 7  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\nreturn ro;\n\n})));\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/locale/ru.js",
    "content": "//! moment.js locale configuration\n//! locale : Russian [ru]\n//! author : Viktorminator : https://github.com/Viktorminator\n//! Author : Menelion Elensúle : https://github.com/Oire\n//! author : Коренберг Марк : https://github.com/socketpair\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\n\nfunction plural(word, num) {\n    var forms = word.split('_');\n    return num % 10 === 1 && num % 100 !== 11 ? forms[0] : (num % 10 >= 2 && num % 10 <= 4 && (num % 100 < 10 || num % 100 >= 20) ? forms[1] : forms[2]);\n}\nfunction relativeTimeWithPlural(number, withoutSuffix, key) {\n    var format = {\n        'mm': withoutSuffix ? 'минута_минуты_минут' : 'минуту_минуты_минут',\n        'hh': 'час_часа_часов',\n        'dd': 'день_дня_дней',\n        'MM': 'месяц_месяца_месяцев',\n        'yy': 'год_года_лет'\n    };\n    if (key === 'm') {\n        return withoutSuffix ? 'минута' : 'минуту';\n    }\n    else {\n        return number + ' ' + plural(format[key], +number);\n    }\n}\nvar monthsParse = [/^янв/i, /^фев/i, /^мар/i, /^апр/i, /^ма[йя]/i, /^июн/i, /^июл/i, /^авг/i, /^сен/i, /^окт/i, /^ноя/i, /^дек/i];\n\n// http://new.gramota.ru/spravka/rules/139-prop : § 103\n// Сокращения месяцев: http://new.gramota.ru/spravka/buro/search-answer?s=242637\n// CLDR data:          http://www.unicode.org/cldr/charts/28/summary/ru.html#1753\nvar ru = moment.defineLocale('ru', {\n    months : {\n        format: 'января_февраля_марта_апреля_мая_июня_июля_августа_сентября_октября_ноября_декабря'.split('_'),\n        standalone: 'январь_февраль_март_апрель_май_июнь_июль_август_сентябрь_октябрь_ноябрь_декабрь'.split('_')\n    },\n    monthsShort : {\n        // по CLDR именно \"июл.\" и \"июн.\", но какой смысл менять букву на точку ?\n        format: 'янв._февр._мар._апр._мая_июня_июля_авг._сент._окт._нояб._дек.'.split('_'),\n        standalone: 'янв._февр._март_апр._май_июнь_июль_авг._сент._окт._нояб._дек.'.split('_')\n    },\n    weekdays : {\n        standalone: 'воскресенье_понедельник_вторник_среда_четверг_пятница_суббота'.split('_'),\n        format: 'воскресенье_понедельник_вторник_среду_четверг_пятницу_субботу'.split('_'),\n        isFormat: /\\[ ?[Вв] ?(?:прошлую|следующую|эту)? ?\\] ?dddd/\n    },\n    weekdaysShort : 'вс_пн_вт_ср_чт_пт_сб'.split('_'),\n    weekdaysMin : 'вс_пн_вт_ср_чт_пт_сб'.split('_'),\n    monthsParse : monthsParse,\n    longMonthsParse : monthsParse,\n    shortMonthsParse : monthsParse,\n\n    // полные названия с падежами, по три буквы, для некоторых, по 4 буквы, сокращения с точкой и без точки\n    monthsRegex: /^(январ[ья]|янв\\.?|феврал[ья]|февр?\\.?|марта?|мар\\.?|апрел[ья]|апр\\.?|ма[йя]|июн[ья]|июн\\.?|июл[ья]|июл\\.?|августа?|авг\\.?|сентябр[ья]|сент?\\.?|октябр[ья]|окт\\.?|ноябр[ья]|нояб?\\.?|декабр[ья]|дек\\.?)/i,\n\n    // копия предыдущего\n    monthsShortRegex: /^(январ[ья]|янв\\.?|феврал[ья]|февр?\\.?|марта?|мар\\.?|апрел[ья]|апр\\.?|ма[йя]|июн[ья]|июн\\.?|июл[ья]|июл\\.?|августа?|авг\\.?|сентябр[ья]|сент?\\.?|октябр[ья]|окт\\.?|ноябр[ья]|нояб?\\.?|декабр[ья]|дек\\.?)/i,\n\n    // полные названия с падежами\n    monthsStrictRegex: /^(январ[яь]|феврал[яь]|марта?|апрел[яь]|ма[яй]|июн[яь]|июл[яь]|августа?|сентябр[яь]|октябр[яь]|ноябр[яь]|декабр[яь])/i,\n\n    // Выражение, которое соотвествует только сокращённым формам\n    monthsShortStrictRegex: /^(янв\\.|февр?\\.|мар[т.]|апр\\.|ма[яй]|июн[ья.]|июл[ья.]|авг\\.|сент?\\.|окт\\.|нояб?\\.|дек\\.)/i,\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD.MM.YYYY',\n        LL : 'D MMMM YYYY г.',\n        LLL : 'D MMMM YYYY г., HH:mm',\n        LLLL : 'dddd, D MMMM YYYY г., HH:mm'\n    },\n    calendar : {\n        sameDay: '[Сегодня в] LT',\n        nextDay: '[Завтра в] LT',\n        lastDay: '[Вчера в] LT',\n        nextWeek: function (now) {\n            if (now.week() !== this.week()) {\n                switch (this.day()) {\n                    case 0:\n                        return '[В следующее] dddd [в] LT';\n                    case 1:\n                    case 2:\n                    case 4:\n                        return '[В следующий] dddd [в] LT';\n                    case 3:\n                    case 5:\n                    case 6:\n                        return '[В следующую] dddd [в] LT';\n                }\n            } else {\n                if (this.day() === 2) {\n                    return '[Во] dddd [в] LT';\n                } else {\n                    return '[В] dddd [в] LT';\n                }\n            }\n        },\n        lastWeek: function (now) {\n            if (now.week() !== this.week()) {\n                switch (this.day()) {\n                    case 0:\n                        return '[В прошлое] dddd [в] LT';\n                    case 1:\n                    case 2:\n                    case 4:\n                        return '[В прошлый] dddd [в] LT';\n                    case 3:\n                    case 5:\n                    case 6:\n                        return '[В прошлую] dddd [в] LT';\n                }\n            } else {\n                if (this.day() === 2) {\n                    return '[Во] dddd [в] LT';\n                } else {\n                    return '[В] dddd [в] LT';\n                }\n            }\n        },\n        sameElse: 'L'\n    },\n    relativeTime : {\n        future : 'через %s',\n        past : '%s назад',\n        s : 'несколько секунд',\n        m : relativeTimeWithPlural,\n        mm : relativeTimeWithPlural,\n        h : 'час',\n        hh : relativeTimeWithPlural,\n        d : 'день',\n        dd : relativeTimeWithPlural,\n        M : 'месяц',\n        MM : relativeTimeWithPlural,\n        y : 'год',\n        yy : relativeTimeWithPlural\n    },\n    meridiemParse: /ночи|утра|дня|вечера/i,\n    isPM : function (input) {\n        return /^(дня|вечера)$/.test(input);\n    },\n    meridiem : function (hour, minute, isLower) {\n        if (hour < 4) {\n            return 'ночи';\n        } else if (hour < 12) {\n            return 'утра';\n        } else if (hour < 17) {\n            return 'дня';\n        } else {\n            return 'вечера';\n        }\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}-(й|го|я)/,\n    ordinal: function (number, period) {\n        switch (period) {\n            case 'M':\n            case 'd':\n            case 'DDD':\n                return number + '-й';\n            case 'D':\n                return number + '-го';\n            case 'w':\n            case 'W':\n                return number + '-я';\n            default:\n                return number;\n        }\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 7  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\nreturn ru;\n\n})));\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/locale/sd.js",
    "content": "//! moment.js locale configuration\n//! locale : Sindhi [sd]\n//! author : Narain Sagar : https://github.com/narainsagar\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\n\nvar months = [\n    'جنوري',\n    'فيبروري',\n    'مارچ',\n    'اپريل',\n    'مئي',\n    'جون',\n    'جولاءِ',\n    'آگسٽ',\n    'سيپٽمبر',\n    'آڪٽوبر',\n    'نومبر',\n    'ڊسمبر'\n];\nvar days = [\n    'آچر',\n    'سومر',\n    'اڱارو',\n    'اربع',\n    'خميس',\n    'جمع',\n    'ڇنڇر'\n];\n\nvar sd = moment.defineLocale('sd', {\n    months : months,\n    monthsShort : months,\n    weekdays : days,\n    weekdaysShort : days,\n    weekdaysMin : days,\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY HH:mm',\n        LLLL : 'dddd، D MMMM YYYY HH:mm'\n    },\n    meridiemParse: /صبح|شام/,\n    isPM : function (input) {\n        return 'شام' === input;\n    },\n    meridiem : function (hour, minute, isLower) {\n        if (hour < 12) {\n            return 'صبح';\n        }\n        return 'شام';\n    },\n    calendar : {\n        sameDay : '[اڄ] LT',\n        nextDay : '[سڀاڻي] LT',\n        nextWeek : 'dddd [اڳين هفتي تي] LT',\n        lastDay : '[ڪالهه] LT',\n        lastWeek : '[گزريل هفتي] dddd [تي] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : '%s پوء',\n        past : '%s اڳ',\n        s : 'چند سيڪنڊ',\n        m : 'هڪ منٽ',\n        mm : '%d منٽ',\n        h : 'هڪ ڪلاڪ',\n        hh : '%d ڪلاڪ',\n        d : 'هڪ ڏينهن',\n        dd : '%d ڏينهن',\n        M : 'هڪ مهينو',\n        MM : '%d مهينا',\n        y : 'هڪ سال',\n        yy : '%d سال'\n    },\n    preparse: function (string) {\n        return string.replace(/،/g, ',');\n    },\n    postformat: function (string) {\n        return string.replace(/,/g, '،');\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\nreturn sd;\n\n})));\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/locale/se.js",
    "content": "//! moment.js locale configuration\n//! locale : Northern Sami [se]\n//! authors : Bård Rolstad Henriksen : https://github.com/karamell\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\n\n\nvar se = moment.defineLocale('se', {\n    months : 'ođđajagemánnu_guovvamánnu_njukčamánnu_cuoŋománnu_miessemánnu_geassemánnu_suoidnemánnu_borgemánnu_čakčamánnu_golggotmánnu_skábmamánnu_juovlamánnu'.split('_'),\n    monthsShort : 'ođđj_guov_njuk_cuo_mies_geas_suoi_borg_čakč_golg_skáb_juov'.split('_'),\n    weekdays : 'sotnabeaivi_vuossárga_maŋŋebárga_gaskavahkku_duorastat_bearjadat_lávvardat'.split('_'),\n    weekdaysShort : 'sotn_vuos_maŋ_gask_duor_bear_láv'.split('_'),\n    weekdaysMin : 's_v_m_g_d_b_L'.split('_'),\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD.MM.YYYY',\n        LL : 'MMMM D. [b.] YYYY',\n        LLL : 'MMMM D. [b.] YYYY [ti.] HH:mm',\n        LLLL : 'dddd, MMMM D. [b.] YYYY [ti.] HH:mm'\n    },\n    calendar : {\n        sameDay: '[otne ti] LT',\n        nextDay: '[ihttin ti] LT',\n        nextWeek: 'dddd [ti] LT',\n        lastDay: '[ikte ti] LT',\n        lastWeek: '[ovddit] dddd [ti] LT',\n        sameElse: 'L'\n    },\n    relativeTime : {\n        future : '%s geažes',\n        past : 'maŋit %s',\n        s : 'moadde sekunddat',\n        m : 'okta minuhta',\n        mm : '%d minuhtat',\n        h : 'okta diimmu',\n        hh : '%d diimmut',\n        d : 'okta beaivi',\n        dd : '%d beaivvit',\n        M : 'okta mánnu',\n        MM : '%d mánut',\n        y : 'okta jahki',\n        yy : '%d jagit'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}\\./,\n    ordinal : '%d.',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\nreturn se;\n\n})));\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/locale/si.js",
    "content": "//! moment.js locale configuration\n//! locale : Sinhalese [si]\n//! author : Sampath Sitinamaluwa : https://github.com/sampathsris\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\n\n/*jshint -W100*/\nvar si = moment.defineLocale('si', {\n    months : 'ජනවාරි_පෙබරවාරි_මාර්තු_අප්‍රේල්_මැයි_ජූනි_ජූලි_අගෝස්තු_සැප්තැම්බර්_ඔක්තෝබර්_නොවැම්බර්_දෙසැම්බර්'.split('_'),\n    monthsShort : 'ජන_පෙබ_මාර්_අප්_මැයි_ජූනි_ජූලි_අගෝ_සැප්_ඔක්_නොවැ_දෙසැ'.split('_'),\n    weekdays : 'ඉරිදා_සඳුදා_අඟහරුවාදා_බදාදා_බ්‍රහස්පතින්දා_සිකුරාදා_සෙනසුරාදා'.split('_'),\n    weekdaysShort : 'ඉරි_සඳු_අඟ_බදා_බ්‍රහ_සිකු_සෙන'.split('_'),\n    weekdaysMin : 'ඉ_ස_අ_බ_බ්‍ර_සි_සෙ'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat : {\n        LT : 'a h:mm',\n        LTS : 'a h:mm:ss',\n        L : 'YYYY/MM/DD',\n        LL : 'YYYY MMMM D',\n        LLL : 'YYYY MMMM D, a h:mm',\n        LLLL : 'YYYY MMMM D [වැනි] dddd, a h:mm:ss'\n    },\n    calendar : {\n        sameDay : '[අද] LT[ට]',\n        nextDay : '[හෙට] LT[ට]',\n        nextWeek : 'dddd LT[ට]',\n        lastDay : '[ඊයේ] LT[ට]',\n        lastWeek : '[පසුගිය] dddd LT[ට]',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : '%sකින්',\n        past : '%sකට පෙර',\n        s : 'තත්පර කිහිපය',\n        m : 'මිනිත්තුව',\n        mm : 'මිනිත්තු %d',\n        h : 'පැය',\n        hh : 'පැය %d',\n        d : 'දිනය',\n        dd : 'දින %d',\n        M : 'මාසය',\n        MM : 'මාස %d',\n        y : 'වසර',\n        yy : 'වසර %d'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2} වැනි/,\n    ordinal : function (number) {\n        return number + ' වැනි';\n    },\n    meridiemParse : /පෙර වරු|පස් වරු|පෙ.ව|ප.ව./,\n    isPM : function (input) {\n        return input === 'ප.ව.' || input === 'පස් වරු';\n    },\n    meridiem : function (hours, minutes, isLower) {\n        if (hours > 11) {\n            return isLower ? 'ප.ව.' : 'පස් වරු';\n        } else {\n            return isLower ? 'පෙ.ව.' : 'පෙර වරු';\n        }\n    }\n});\n\nreturn si;\n\n})));\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/locale/sk.js",
    "content": "//! moment.js locale configuration\n//! locale : Slovak [sk]\n//! author : Martin Minka : https://github.com/k2s\n//! based on work of petrbela : https://github.com/petrbela\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\n\nvar months = 'január_február_marec_apríl_máj_jún_júl_august_september_október_november_december'.split('_');\nvar monthsShort = 'jan_feb_mar_apr_máj_jún_júl_aug_sep_okt_nov_dec'.split('_');\nfunction plural(n) {\n    return (n > 1) && (n < 5);\n}\nfunction translate(number, withoutSuffix, key, isFuture) {\n    var result = number + ' ';\n    switch (key) {\n        case 's':  // a few seconds / in a few seconds / a few seconds ago\n            return (withoutSuffix || isFuture) ? 'pár sekúnd' : 'pár sekundami';\n        case 'm':  // a minute / in a minute / a minute ago\n            return withoutSuffix ? 'minúta' : (isFuture ? 'minútu' : 'minútou');\n        case 'mm': // 9 minutes / in 9 minutes / 9 minutes ago\n            if (withoutSuffix || isFuture) {\n                return result + (plural(number) ? 'minúty' : 'minút');\n            } else {\n                return result + 'minútami';\n            }\n            break;\n        case 'h':  // an hour / in an hour / an hour ago\n            return withoutSuffix ? 'hodina' : (isFuture ? 'hodinu' : 'hodinou');\n        case 'hh': // 9 hours / in 9 hours / 9 hours ago\n            if (withoutSuffix || isFuture) {\n                return result + (plural(number) ? 'hodiny' : 'hodín');\n            } else {\n                return result + 'hodinami';\n            }\n            break;\n        case 'd':  // a day / in a day / a day ago\n            return (withoutSuffix || isFuture) ? 'deň' : 'dňom';\n        case 'dd': // 9 days / in 9 days / 9 days ago\n            if (withoutSuffix || isFuture) {\n                return result + (plural(number) ? 'dni' : 'dní');\n            } else {\n                return result + 'dňami';\n            }\n            break;\n        case 'M':  // a month / in a month / a month ago\n            return (withoutSuffix || isFuture) ? 'mesiac' : 'mesiacom';\n        case 'MM': // 9 months / in 9 months / 9 months ago\n            if (withoutSuffix || isFuture) {\n                return result + (plural(number) ? 'mesiace' : 'mesiacov');\n            } else {\n                return result + 'mesiacmi';\n            }\n            break;\n        case 'y':  // a year / in a year / a year ago\n            return (withoutSuffix || isFuture) ? 'rok' : 'rokom';\n        case 'yy': // 9 years / in 9 years / 9 years ago\n            if (withoutSuffix || isFuture) {\n                return result + (plural(number) ? 'roky' : 'rokov');\n            } else {\n                return result + 'rokmi';\n            }\n            break;\n    }\n}\n\nvar sk = moment.defineLocale('sk', {\n    months : months,\n    monthsShort : monthsShort,\n    weekdays : 'nedeľa_pondelok_utorok_streda_štvrtok_piatok_sobota'.split('_'),\n    weekdaysShort : 'ne_po_ut_st_št_pi_so'.split('_'),\n    weekdaysMin : 'ne_po_ut_st_št_pi_so'.split('_'),\n    longDateFormat : {\n        LT: 'H:mm',\n        LTS : 'H:mm:ss',\n        L : 'DD.MM.YYYY',\n        LL : 'D. MMMM YYYY',\n        LLL : 'D. MMMM YYYY H:mm',\n        LLLL : 'dddd D. MMMM YYYY H:mm'\n    },\n    calendar : {\n        sameDay: '[dnes o] LT',\n        nextDay: '[zajtra o] LT',\n        nextWeek: function () {\n            switch (this.day()) {\n                case 0:\n                    return '[v nedeľu o] LT';\n                case 1:\n                case 2:\n                    return '[v] dddd [o] LT';\n                case 3:\n                    return '[v stredu o] LT';\n                case 4:\n                    return '[vo štvrtok o] LT';\n                case 5:\n                    return '[v piatok o] LT';\n                case 6:\n                    return '[v sobotu o] LT';\n            }\n        },\n        lastDay: '[včera o] LT',\n        lastWeek: function () {\n            switch (this.day()) {\n                case 0:\n                    return '[minulú nedeľu o] LT';\n                case 1:\n                case 2:\n                    return '[minulý] dddd [o] LT';\n                case 3:\n                    return '[minulú stredu o] LT';\n                case 4:\n                case 5:\n                    return '[minulý] dddd [o] LT';\n                case 6:\n                    return '[minulú sobotu o] LT';\n            }\n        },\n        sameElse: 'L'\n    },\n    relativeTime : {\n        future : 'za %s',\n        past : 'pred %s',\n        s : translate,\n        m : translate,\n        mm : translate,\n        h : translate,\n        hh : translate,\n        d : translate,\n        dd : translate,\n        M : translate,\n        MM : translate,\n        y : translate,\n        yy : translate\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}\\./,\n    ordinal : '%d.',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\nreturn sk;\n\n})));\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/locale/sl.js",
    "content": "//! moment.js locale configuration\n//! locale : Slovenian [sl]\n//! author : Robert Sedovšek : https://github.com/sedovsek\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\n\nfunction processRelativeTime(number, withoutSuffix, key, isFuture) {\n    var result = number + ' ';\n    switch (key) {\n        case 's':\n            return withoutSuffix || isFuture ? 'nekaj sekund' : 'nekaj sekundami';\n        case 'm':\n            return withoutSuffix ? 'ena minuta' : 'eno minuto';\n        case 'mm':\n            if (number === 1) {\n                result += withoutSuffix ? 'minuta' : 'minuto';\n            } else if (number === 2) {\n                result += withoutSuffix || isFuture ? 'minuti' : 'minutama';\n            } else if (number < 5) {\n                result += withoutSuffix || isFuture ? 'minute' : 'minutami';\n            } else {\n                result += withoutSuffix || isFuture ? 'minut' : 'minutami';\n            }\n            return result;\n        case 'h':\n            return withoutSuffix ? 'ena ura' : 'eno uro';\n        case 'hh':\n            if (number === 1) {\n                result += withoutSuffix ? 'ura' : 'uro';\n            } else if (number === 2) {\n                result += withoutSuffix || isFuture ? 'uri' : 'urama';\n            } else if (number < 5) {\n                result += withoutSuffix || isFuture ? 'ure' : 'urami';\n            } else {\n                result += withoutSuffix || isFuture ? 'ur' : 'urami';\n            }\n            return result;\n        case 'd':\n            return withoutSuffix || isFuture ? 'en dan' : 'enim dnem';\n        case 'dd':\n            if (number === 1) {\n                result += withoutSuffix || isFuture ? 'dan' : 'dnem';\n            } else if (number === 2) {\n                result += withoutSuffix || isFuture ? 'dni' : 'dnevoma';\n            } else {\n                result += withoutSuffix || isFuture ? 'dni' : 'dnevi';\n            }\n            return result;\n        case 'M':\n            return withoutSuffix || isFuture ? 'en mesec' : 'enim mesecem';\n        case 'MM':\n            if (number === 1) {\n                result += withoutSuffix || isFuture ? 'mesec' : 'mesecem';\n            } else if (number === 2) {\n                result += withoutSuffix || isFuture ? 'meseca' : 'mesecema';\n            } else if (number < 5) {\n                result += withoutSuffix || isFuture ? 'mesece' : 'meseci';\n            } else {\n                result += withoutSuffix || isFuture ? 'mesecev' : 'meseci';\n            }\n            return result;\n        case 'y':\n            return withoutSuffix || isFuture ? 'eno leto' : 'enim letom';\n        case 'yy':\n            if (number === 1) {\n                result += withoutSuffix || isFuture ? 'leto' : 'letom';\n            } else if (number === 2) {\n                result += withoutSuffix || isFuture ? 'leti' : 'letoma';\n            } else if (number < 5) {\n                result += withoutSuffix || isFuture ? 'leta' : 'leti';\n            } else {\n                result += withoutSuffix || isFuture ? 'let' : 'leti';\n            }\n            return result;\n    }\n}\n\nvar sl = moment.defineLocale('sl', {\n    months : 'januar_februar_marec_april_maj_junij_julij_avgust_september_oktober_november_december'.split('_'),\n    monthsShort : 'jan._feb._mar._apr._maj._jun._jul._avg._sep._okt._nov._dec.'.split('_'),\n    monthsParseExact: true,\n    weekdays : 'nedelja_ponedeljek_torek_sreda_četrtek_petek_sobota'.split('_'),\n    weekdaysShort : 'ned._pon._tor._sre._čet._pet._sob.'.split('_'),\n    weekdaysMin : 'ne_po_to_sr_če_pe_so'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat : {\n        LT : 'H:mm',\n        LTS : 'H:mm:ss',\n        L : 'DD.MM.YYYY',\n        LL : 'D. MMMM YYYY',\n        LLL : 'D. MMMM YYYY H:mm',\n        LLLL : 'dddd, D. MMMM YYYY H:mm'\n    },\n    calendar : {\n        sameDay  : '[danes ob] LT',\n        nextDay  : '[jutri ob] LT',\n\n        nextWeek : function () {\n            switch (this.day()) {\n                case 0:\n                    return '[v] [nedeljo] [ob] LT';\n                case 3:\n                    return '[v] [sredo] [ob] LT';\n                case 6:\n                    return '[v] [soboto] [ob] LT';\n                case 1:\n                case 2:\n                case 4:\n                case 5:\n                    return '[v] dddd [ob] LT';\n            }\n        },\n        lastDay  : '[včeraj ob] LT',\n        lastWeek : function () {\n            switch (this.day()) {\n                case 0:\n                    return '[prejšnjo] [nedeljo] [ob] LT';\n                case 3:\n                    return '[prejšnjo] [sredo] [ob] LT';\n                case 6:\n                    return '[prejšnjo] [soboto] [ob] LT';\n                case 1:\n                case 2:\n                case 4:\n                case 5:\n                    return '[prejšnji] dddd [ob] LT';\n            }\n        },\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'čez %s',\n        past   : 'pred %s',\n        s      : processRelativeTime,\n        m      : processRelativeTime,\n        mm     : processRelativeTime,\n        h      : processRelativeTime,\n        hh     : processRelativeTime,\n        d      : processRelativeTime,\n        dd     : processRelativeTime,\n        M      : processRelativeTime,\n        MM     : processRelativeTime,\n        y      : processRelativeTime,\n        yy     : processRelativeTime\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}\\./,\n    ordinal : '%d.',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 7  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\nreturn sl;\n\n})));\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/locale/sq.js",
    "content": "//! moment.js locale configuration\n//! locale : Albanian [sq]\n//! author : Flakërim Ismani : https://github.com/flakerimi\n//! author : Menelion Elensúle : https://github.com/Oire\n//! author : Oerd Cukalla : https://github.com/oerd\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\n\nvar sq = moment.defineLocale('sq', {\n    months : 'Janar_Shkurt_Mars_Prill_Maj_Qershor_Korrik_Gusht_Shtator_Tetor_Nëntor_Dhjetor'.split('_'),\n    monthsShort : 'Jan_Shk_Mar_Pri_Maj_Qer_Kor_Gus_Sht_Tet_Nën_Dhj'.split('_'),\n    weekdays : 'E Diel_E Hënë_E Martë_E Mërkurë_E Enjte_E Premte_E Shtunë'.split('_'),\n    weekdaysShort : 'Die_Hën_Mar_Mër_Enj_Pre_Sht'.split('_'),\n    weekdaysMin : 'D_H_Ma_Më_E_P_Sh'.split('_'),\n    weekdaysParseExact : true,\n    meridiemParse: /PD|MD/,\n    isPM: function (input) {\n        return input.charAt(0) === 'M';\n    },\n    meridiem : function (hours, minutes, isLower) {\n        return hours < 12 ? 'PD' : 'MD';\n    },\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY HH:mm',\n        LLLL : 'dddd, D MMMM YYYY HH:mm'\n    },\n    calendar : {\n        sameDay : '[Sot në] LT',\n        nextDay : '[Nesër në] LT',\n        nextWeek : 'dddd [në] LT',\n        lastDay : '[Dje në] LT',\n        lastWeek : 'dddd [e kaluar në] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'në %s',\n        past : '%s më parë',\n        s : 'disa sekonda',\n        m : 'një minutë',\n        mm : '%d minuta',\n        h : 'një orë',\n        hh : '%d orë',\n        d : 'një ditë',\n        dd : '%d ditë',\n        M : 'një muaj',\n        MM : '%d muaj',\n        y : 'një vit',\n        yy : '%d vite'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}\\./,\n    ordinal : '%d.',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\nreturn sq;\n\n})));\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/locale/sr-cyrl.js",
    "content": "//! moment.js locale configuration\n//! locale : Serbian Cyrillic [sr-cyrl]\n//! author : Milan Janačković<milanjanackovic@gmail.com> : https://github.com/milan-j\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\n\nvar translator = {\n    words: { //Different grammatical cases\n        m: ['један минут', 'једне минуте'],\n        mm: ['минут', 'минуте', 'минута'],\n        h: ['један сат', 'једног сата'],\n        hh: ['сат', 'сата', 'сати'],\n        dd: ['дан', 'дана', 'дана'],\n        MM: ['месец', 'месеца', 'месеци'],\n        yy: ['година', 'године', 'година']\n    },\n    correctGrammaticalCase: function (number, wordKey) {\n        return number === 1 ? wordKey[0] : (number >= 2 && number <= 4 ? wordKey[1] : wordKey[2]);\n    },\n    translate: function (number, withoutSuffix, key) {\n        var wordKey = translator.words[key];\n        if (key.length === 1) {\n            return withoutSuffix ? wordKey[0] : wordKey[1];\n        } else {\n            return number + ' ' + translator.correctGrammaticalCase(number, wordKey);\n        }\n    }\n};\n\nvar srCyrl = moment.defineLocale('sr-cyrl', {\n    months: 'јануар_фебруар_март_април_мај_јун_јул_август_септембар_октобар_новембар_децембар'.split('_'),\n    monthsShort: 'јан._феб._мар._апр._мај_јун_јул_авг._сеп._окт._нов._дец.'.split('_'),\n    monthsParseExact: true,\n    weekdays: 'недеља_понедељак_уторак_среда_четвртак_петак_субота'.split('_'),\n    weekdaysShort: 'нед._пон._уто._сре._чет._пет._суб.'.split('_'),\n    weekdaysMin: 'не_по_ут_ср_че_пе_су'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat: {\n        LT: 'H:mm',\n        LTS : 'H:mm:ss',\n        L: 'DD.MM.YYYY',\n        LL: 'D. MMMM YYYY',\n        LLL: 'D. MMMM YYYY H:mm',\n        LLLL: 'dddd, D. MMMM YYYY H:mm'\n    },\n    calendar: {\n        sameDay: '[данас у] LT',\n        nextDay: '[сутра у] LT',\n        nextWeek: function () {\n            switch (this.day()) {\n                case 0:\n                    return '[у] [недељу] [у] LT';\n                case 3:\n                    return '[у] [среду] [у] LT';\n                case 6:\n                    return '[у] [суботу] [у] LT';\n                case 1:\n                case 2:\n                case 4:\n                case 5:\n                    return '[у] dddd [у] LT';\n            }\n        },\n        lastDay  : '[јуче у] LT',\n        lastWeek : function () {\n            var lastWeekDays = [\n                '[прошле] [недеље] [у] LT',\n                '[прошлог] [понедељка] [у] LT',\n                '[прошлог] [уторка] [у] LT',\n                '[прошле] [среде] [у] LT',\n                '[прошлог] [четвртка] [у] LT',\n                '[прошлог] [петка] [у] LT',\n                '[прошле] [суботе] [у] LT'\n            ];\n            return lastWeekDays[this.day()];\n        },\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'за %s',\n        past   : 'пре %s',\n        s      : 'неколико секунди',\n        m      : translator.translate,\n        mm     : translator.translate,\n        h      : translator.translate,\n        hh     : translator.translate,\n        d      : 'дан',\n        dd     : translator.translate,\n        M      : 'месец',\n        MM     : translator.translate,\n        y      : 'годину',\n        yy     : translator.translate\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}\\./,\n    ordinal : '%d.',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 7  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\nreturn srCyrl;\n\n})));\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/locale/sr.js",
    "content": "//! moment.js locale configuration\n//! locale : Serbian [sr]\n//! author : Milan Janačković<milanjanackovic@gmail.com> : https://github.com/milan-j\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\n\nvar translator = {\n    words: { //Different grammatical cases\n        m: ['jedan minut', 'jedne minute'],\n        mm: ['minut', 'minute', 'minuta'],\n        h: ['jedan sat', 'jednog sata'],\n        hh: ['sat', 'sata', 'sati'],\n        dd: ['dan', 'dana', 'dana'],\n        MM: ['mesec', 'meseca', 'meseci'],\n        yy: ['godina', 'godine', 'godina']\n    },\n    correctGrammaticalCase: function (number, wordKey) {\n        return number === 1 ? wordKey[0] : (number >= 2 && number <= 4 ? wordKey[1] : wordKey[2]);\n    },\n    translate: function (number, withoutSuffix, key) {\n        var wordKey = translator.words[key];\n        if (key.length === 1) {\n            return withoutSuffix ? wordKey[0] : wordKey[1];\n        } else {\n            return number + ' ' + translator.correctGrammaticalCase(number, wordKey);\n        }\n    }\n};\n\nvar sr = moment.defineLocale('sr', {\n    months: 'januar_februar_mart_april_maj_jun_jul_avgust_septembar_oktobar_novembar_decembar'.split('_'),\n    monthsShort: 'jan._feb._mar._apr._maj_jun_jul_avg._sep._okt._nov._dec.'.split('_'),\n    monthsParseExact: true,\n    weekdays: 'nedelja_ponedeljak_utorak_sreda_četvrtak_petak_subota'.split('_'),\n    weekdaysShort: 'ned._pon._uto._sre._čet._pet._sub.'.split('_'),\n    weekdaysMin: 'ne_po_ut_sr_če_pe_su'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat: {\n        LT: 'H:mm',\n        LTS : 'H:mm:ss',\n        L: 'DD.MM.YYYY',\n        LL: 'D. MMMM YYYY',\n        LLL: 'D. MMMM YYYY H:mm',\n        LLLL: 'dddd, D. MMMM YYYY H:mm'\n    },\n    calendar: {\n        sameDay: '[danas u] LT',\n        nextDay: '[sutra u] LT',\n        nextWeek: function () {\n            switch (this.day()) {\n                case 0:\n                    return '[u] [nedelju] [u] LT';\n                case 3:\n                    return '[u] [sredu] [u] LT';\n                case 6:\n                    return '[u] [subotu] [u] LT';\n                case 1:\n                case 2:\n                case 4:\n                case 5:\n                    return '[u] dddd [u] LT';\n            }\n        },\n        lastDay  : '[juče u] LT',\n        lastWeek : function () {\n            var lastWeekDays = [\n                '[prošle] [nedelje] [u] LT',\n                '[prošlog] [ponedeljka] [u] LT',\n                '[prošlog] [utorka] [u] LT',\n                '[prošle] [srede] [u] LT',\n                '[prošlog] [četvrtka] [u] LT',\n                '[prošlog] [petka] [u] LT',\n                '[prošle] [subote] [u] LT'\n            ];\n            return lastWeekDays[this.day()];\n        },\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'za %s',\n        past   : 'pre %s',\n        s      : 'nekoliko sekundi',\n        m      : translator.translate,\n        mm     : translator.translate,\n        h      : translator.translate,\n        hh     : translator.translate,\n        d      : 'dan',\n        dd     : translator.translate,\n        M      : 'mesec',\n        MM     : translator.translate,\n        y      : 'godinu',\n        yy     : translator.translate\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}\\./,\n    ordinal : '%d.',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 7  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\nreturn sr;\n\n})));\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/locale/ss.js",
    "content": "//! moment.js locale configuration\n//! locale : siSwati [ss]\n//! author : Nicolai Davies<mail@nicolai.io> : https://github.com/nicolaidavies\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\n\n\nvar ss = moment.defineLocale('ss', {\n    months : \"Bhimbidvwane_Indlovana_Indlov'lenkhulu_Mabasa_Inkhwekhweti_Inhlaba_Kholwane_Ingci_Inyoni_Imphala_Lweti_Ingongoni\".split('_'),\n    monthsShort : 'Bhi_Ina_Inu_Mab_Ink_Inh_Kho_Igc_Iny_Imp_Lwe_Igo'.split('_'),\n    weekdays : 'Lisontfo_Umsombuluko_Lesibili_Lesitsatfu_Lesine_Lesihlanu_Umgcibelo'.split('_'),\n    weekdaysShort : 'Lis_Umb_Lsb_Les_Lsi_Lsh_Umg'.split('_'),\n    weekdaysMin : 'Li_Us_Lb_Lt_Ls_Lh_Ug'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat : {\n        LT : 'h:mm A',\n        LTS : 'h:mm:ss A',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY h:mm A',\n        LLLL : 'dddd, D MMMM YYYY h:mm A'\n    },\n    calendar : {\n        sameDay : '[Namuhla nga] LT',\n        nextDay : '[Kusasa nga] LT',\n        nextWeek : 'dddd [nga] LT',\n        lastDay : '[Itolo nga] LT',\n        lastWeek : 'dddd [leliphelile] [nga] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'nga %s',\n        past : 'wenteka nga %s',\n        s : 'emizuzwana lomcane',\n        m : 'umzuzu',\n        mm : '%d emizuzu',\n        h : 'lihora',\n        hh : '%d emahora',\n        d : 'lilanga',\n        dd : '%d emalanga',\n        M : 'inyanga',\n        MM : '%d tinyanga',\n        y : 'umnyaka',\n        yy : '%d iminyaka'\n    },\n    meridiemParse: /ekuseni|emini|entsambama|ebusuku/,\n    meridiem : function (hours, minutes, isLower) {\n        if (hours < 11) {\n            return 'ekuseni';\n        } else if (hours < 15) {\n            return 'emini';\n        } else if (hours < 19) {\n            return 'entsambama';\n        } else {\n            return 'ebusuku';\n        }\n    },\n    meridiemHour : function (hour, meridiem) {\n        if (hour === 12) {\n            hour = 0;\n        }\n        if (meridiem === 'ekuseni') {\n            return hour;\n        } else if (meridiem === 'emini') {\n            return hour >= 11 ? hour : hour + 12;\n        } else if (meridiem === 'entsambama' || meridiem === 'ebusuku') {\n            if (hour === 0) {\n                return 0;\n            }\n            return hour + 12;\n        }\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}/,\n    ordinal : '%d',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\nreturn ss;\n\n})));\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/locale/sv.js",
    "content": "//! moment.js locale configuration\n//! locale : Swedish [sv]\n//! author : Jens Alm : https://github.com/ulmus\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\n\nvar sv = moment.defineLocale('sv', {\n    months : 'januari_februari_mars_april_maj_juni_juli_augusti_september_oktober_november_december'.split('_'),\n    monthsShort : 'jan_feb_mar_apr_maj_jun_jul_aug_sep_okt_nov_dec'.split('_'),\n    weekdays : 'söndag_måndag_tisdag_onsdag_torsdag_fredag_lördag'.split('_'),\n    weekdaysShort : 'sön_mån_tis_ons_tor_fre_lör'.split('_'),\n    weekdaysMin : 'sö_må_ti_on_to_fr_lö'.split('_'),\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'YYYY-MM-DD',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY [kl.] HH:mm',\n        LLLL : 'dddd D MMMM YYYY [kl.] HH:mm',\n        lll : 'D MMM YYYY HH:mm',\n        llll : 'ddd D MMM YYYY HH:mm'\n    },\n    calendar : {\n        sameDay: '[Idag] LT',\n        nextDay: '[Imorgon] LT',\n        lastDay: '[Igår] LT',\n        nextWeek: '[På] dddd LT',\n        lastWeek: '[I] dddd[s] LT',\n        sameElse: 'L'\n    },\n    relativeTime : {\n        future : 'om %s',\n        past : 'för %s sedan',\n        s : 'några sekunder',\n        m : 'en minut',\n        mm : '%d minuter',\n        h : 'en timme',\n        hh : '%d timmar',\n        d : 'en dag',\n        dd : '%d dagar',\n        M : 'en månad',\n        MM : '%d månader',\n        y : 'ett år',\n        yy : '%d år'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}(e|a)/,\n    ordinal : function (number) {\n        var b = number % 10,\n            output = (~~(number % 100 / 10) === 1) ? 'e' :\n            (b === 1) ? 'a' :\n            (b === 2) ? 'a' :\n            (b === 3) ? 'e' : 'e';\n        return number + output;\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\nreturn sv;\n\n})));\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/locale/sw.js",
    "content": "//! moment.js locale configuration\n//! locale : Swahili [sw]\n//! author : Fahad Kassim : https://github.com/fadsel\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\n\nvar sw = moment.defineLocale('sw', {\n    months : 'Januari_Februari_Machi_Aprili_Mei_Juni_Julai_Agosti_Septemba_Oktoba_Novemba_Desemba'.split('_'),\n    monthsShort : 'Jan_Feb_Mac_Apr_Mei_Jun_Jul_Ago_Sep_Okt_Nov_Des'.split('_'),\n    weekdays : 'Jumapili_Jumatatu_Jumanne_Jumatano_Alhamisi_Ijumaa_Jumamosi'.split('_'),\n    weekdaysShort : 'Jpl_Jtat_Jnne_Jtan_Alh_Ijm_Jmos'.split('_'),\n    weekdaysMin : 'J2_J3_J4_J5_Al_Ij_J1'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD.MM.YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY HH:mm',\n        LLLL : 'dddd, D MMMM YYYY HH:mm'\n    },\n    calendar : {\n        sameDay : '[leo saa] LT',\n        nextDay : '[kesho saa] LT',\n        nextWeek : '[wiki ijayo] dddd [saat] LT',\n        lastDay : '[jana] LT',\n        lastWeek : '[wiki iliyopita] dddd [saat] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : '%s baadaye',\n        past : 'tokea %s',\n        s : 'hivi punde',\n        m : 'dakika moja',\n        mm : 'dakika %d',\n        h : 'saa limoja',\n        hh : 'masaa %d',\n        d : 'siku moja',\n        dd : 'masiku %d',\n        M : 'mwezi mmoja',\n        MM : 'miezi %d',\n        y : 'mwaka mmoja',\n        yy : 'miaka %d'\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 7  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\nreturn sw;\n\n})));\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/locale/ta.js",
    "content": "//! moment.js locale configuration\n//! locale : Tamil [ta]\n//! author : Arjunkumar Krishnamoorthy : https://github.com/tk120404\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\n\nvar symbolMap = {\n    '1': '௧',\n    '2': '௨',\n    '3': '௩',\n    '4': '௪',\n    '5': '௫',\n    '6': '௬',\n    '7': '௭',\n    '8': '௮',\n    '9': '௯',\n    '0': '௦'\n};\nvar numberMap = {\n    '௧': '1',\n    '௨': '2',\n    '௩': '3',\n    '௪': '4',\n    '௫': '5',\n    '௬': '6',\n    '௭': '7',\n    '௮': '8',\n    '௯': '9',\n    '௦': '0'\n};\n\nvar ta = moment.defineLocale('ta', {\n    months : 'ஜனவரி_பிப்ரவரி_மார்ச்_ஏப்ரல்_மே_ஜூன்_ஜூலை_ஆகஸ்ட்_செப்டெம்பர்_அக்டோபர்_நவம்பர்_டிசம்பர்'.split('_'),\n    monthsShort : 'ஜனவரி_பிப்ரவரி_மார்ச்_ஏப்ரல்_மே_ஜூன்_ஜூலை_ஆகஸ்ட்_செப்டெம்பர்_அக்டோபர்_நவம்பர்_டிசம்பர்'.split('_'),\n    weekdays : 'ஞாயிற்றுக்கிழமை_திங்கட்கிழமை_செவ்வாய்கிழமை_புதன்கிழமை_வியாழக்கிழமை_வெள்ளிக்கிழமை_சனிக்கிழமை'.split('_'),\n    weekdaysShort : 'ஞாயிறு_திங்கள்_செவ்வாய்_புதன்_வியாழன்_வெள்ளி_சனி'.split('_'),\n    weekdaysMin : 'ஞா_தி_செ_பு_வி_வெ_ச'.split('_'),\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY, HH:mm',\n        LLLL : 'dddd, D MMMM YYYY, HH:mm'\n    },\n    calendar : {\n        sameDay : '[இன்று] LT',\n        nextDay : '[நாளை] LT',\n        nextWeek : 'dddd, LT',\n        lastDay : '[நேற்று] LT',\n        lastWeek : '[கடந்த வாரம்] dddd, LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : '%s இல்',\n        past : '%s முன்',\n        s : 'ஒரு சில விநாடிகள்',\n        m : 'ஒரு நிமிடம்',\n        mm : '%d நிமிடங்கள்',\n        h : 'ஒரு மணி நேரம்',\n        hh : '%d மணி நேரம்',\n        d : 'ஒரு நாள்',\n        dd : '%d நாட்கள்',\n        M : 'ஒரு மாதம்',\n        MM : '%d மாதங்கள்',\n        y : 'ஒரு வருடம்',\n        yy : '%d ஆண்டுகள்'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}வது/,\n    ordinal : function (number) {\n        return number + 'வது';\n    },\n    preparse: function (string) {\n        return string.replace(/[௧௨௩௪௫௬௭௮௯௦]/g, function (match) {\n            return numberMap[match];\n        });\n    },\n    postformat: function (string) {\n        return string.replace(/\\d/g, function (match) {\n            return symbolMap[match];\n        });\n    },\n    // refer http://ta.wikipedia.org/s/1er1\n    meridiemParse: /யாமம்|வைகறை|காலை|நண்பகல்|எற்பாடு|மாலை/,\n    meridiem : function (hour, minute, isLower) {\n        if (hour < 2) {\n            return ' யாமம்';\n        } else if (hour < 6) {\n            return ' வைகறை';  // வைகறை\n        } else if (hour < 10) {\n            return ' காலை'; // காலை\n        } else if (hour < 14) {\n            return ' நண்பகல்'; // நண்பகல்\n        } else if (hour < 18) {\n            return ' எற்பாடு'; // எற்பாடு\n        } else if (hour < 22) {\n            return ' மாலை'; // மாலை\n        } else {\n            return ' யாமம்';\n        }\n    },\n    meridiemHour : function (hour, meridiem) {\n        if (hour === 12) {\n            hour = 0;\n        }\n        if (meridiem === 'யாமம்') {\n            return hour < 2 ? hour : hour + 12;\n        } else if (meridiem === 'வைகறை' || meridiem === 'காலை') {\n            return hour;\n        } else if (meridiem === 'நண்பகல்') {\n            return hour >= 10 ? hour : hour + 12;\n        } else {\n            return hour + 12;\n        }\n    },\n    week : {\n        dow : 0, // Sunday is the first day of the week.\n        doy : 6  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\nreturn ta;\n\n})));\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/locale/te.js",
    "content": "//! moment.js locale configuration\n//! locale : Telugu [te]\n//! author : Krishna Chaitanya Thota : https://github.com/kcthota\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\n\nvar te = moment.defineLocale('te', {\n    months : 'జనవరి_ఫిబ్రవరి_మార్చి_ఏప్రిల్_మే_జూన్_జూలై_ఆగస్టు_సెప్టెంబర్_అక్టోబర్_నవంబర్_డిసెంబర్'.split('_'),\n    monthsShort : 'జన._ఫిబ్ర._మార్చి_ఏప్రి._మే_జూన్_జూలై_ఆగ._సెప్._అక్టో._నవ._డిసె.'.split('_'),\n    monthsParseExact : true,\n    weekdays : 'ఆదివారం_సోమవారం_మంగళవారం_బుధవారం_గురువారం_శుక్రవారం_శనివారం'.split('_'),\n    weekdaysShort : 'ఆది_సోమ_మంగళ_బుధ_గురు_శుక్ర_శని'.split('_'),\n    weekdaysMin : 'ఆ_సో_మం_బు_గు_శు_శ'.split('_'),\n    longDateFormat : {\n        LT : 'A h:mm',\n        LTS : 'A h:mm:ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY, A h:mm',\n        LLLL : 'dddd, D MMMM YYYY, A h:mm'\n    },\n    calendar : {\n        sameDay : '[నేడు] LT',\n        nextDay : '[రేపు] LT',\n        nextWeek : 'dddd, LT',\n        lastDay : '[నిన్న] LT',\n        lastWeek : '[గత] dddd, LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : '%s లో',\n        past : '%s క్రితం',\n        s : 'కొన్ని క్షణాలు',\n        m : 'ఒక నిమిషం',\n        mm : '%d నిమిషాలు',\n        h : 'ఒక గంట',\n        hh : '%d గంటలు',\n        d : 'ఒక రోజు',\n        dd : '%d రోజులు',\n        M : 'ఒక నెల',\n        MM : '%d నెలలు',\n        y : 'ఒక సంవత్సరం',\n        yy : '%d సంవత్సరాలు'\n    },\n    dayOfMonthOrdinalParse : /\\d{1,2}వ/,\n    ordinal : '%dవ',\n    meridiemParse: /రాత్రి|ఉదయం|మధ్యాహ్నం|సాయంత్రం/,\n    meridiemHour : function (hour, meridiem) {\n        if (hour === 12) {\n            hour = 0;\n        }\n        if (meridiem === 'రాత్రి') {\n            return hour < 4 ? hour : hour + 12;\n        } else if (meridiem === 'ఉదయం') {\n            return hour;\n        } else if (meridiem === 'మధ్యాహ్నం') {\n            return hour >= 10 ? hour : hour + 12;\n        } else if (meridiem === 'సాయంత్రం') {\n            return hour + 12;\n        }\n    },\n    meridiem : function (hour, minute, isLower) {\n        if (hour < 4) {\n            return 'రాత్రి';\n        } else if (hour < 10) {\n            return 'ఉదయం';\n        } else if (hour < 17) {\n            return 'మధ్యాహ్నం';\n        } else if (hour < 20) {\n            return 'సాయంత్రం';\n        } else {\n            return 'రాత్రి';\n        }\n    },\n    week : {\n        dow : 0, // Sunday is the first day of the week.\n        doy : 6  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\nreturn te;\n\n})));\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/locale/tet.js",
    "content": "//! moment.js locale configuration\n//! locale : Tetun Dili (East Timor) [tet]\n//! author : Joshua Brooks : https://github.com/joshbrooks\n//! author : Onorio De J. Afonso : https://github.com/marobo\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\n\nvar tet = moment.defineLocale('tet', {\n    months : 'Janeiru_Fevereiru_Marsu_Abril_Maiu_Juniu_Juliu_Augustu_Setembru_Outubru_Novembru_Dezembru'.split('_'),\n    monthsShort : 'Jan_Fev_Mar_Abr_Mai_Jun_Jul_Aug_Set_Out_Nov_Dez'.split('_'),\n    weekdays : 'Domingu_Segunda_Tersa_Kuarta_Kinta_Sexta_Sabadu'.split('_'),\n    weekdaysShort : 'Dom_Seg_Ters_Kua_Kint_Sext_Sab'.split('_'),\n    weekdaysMin : 'Do_Seg_Te_Ku_Ki_Sex_Sa'.split('_'),\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY HH:mm',\n        LLLL : 'dddd, D MMMM YYYY HH:mm'\n    },\n    calendar : {\n        sameDay: '[Ohin iha] LT',\n        nextDay: '[Aban iha] LT',\n        nextWeek: 'dddd [iha] LT',\n        lastDay: '[Horiseik iha] LT',\n        lastWeek: 'dddd [semana kotuk] [iha] LT',\n        sameElse: 'L'\n    },\n    relativeTime : {\n        future : 'iha %s',\n        past : '%s liuba',\n        s : 'minutu balun',\n        m : 'minutu ida',\n        mm : 'minutus %d',\n        h : 'horas ida',\n        hh : 'horas %d',\n        d : 'loron ida',\n        dd : 'loron %d',\n        M : 'fulan ida',\n        MM : 'fulan %d',\n        y : 'tinan ida',\n        yy : 'tinan %d'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}(st|nd|rd|th)/,\n    ordinal : function (number) {\n        var b = number % 10,\n            output = (~~(number % 100 / 10) === 1) ? 'th' :\n            (b === 1) ? 'st' :\n            (b === 2) ? 'nd' :\n            (b === 3) ? 'rd' : 'th';\n        return number + output;\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\nreturn tet;\n\n})));\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/locale/th.js",
    "content": "//! moment.js locale configuration\n//! locale : Thai [th]\n//! author : Kridsada Thanabulpong : https://github.com/sirn\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\n\nvar th = moment.defineLocale('th', {\n    months : 'มกราคม_กุมภาพันธ์_มีนาคม_เมษายน_พฤษภาคม_มิถุนายน_กรกฎาคม_สิงหาคม_กันยายน_ตุลาคม_พฤศจิกายน_ธันวาคม'.split('_'),\n    monthsShort : 'ม.ค._ก.พ._มี.ค._เม.ย._พ.ค._มิ.ย._ก.ค._ส.ค._ก.ย._ต.ค._พ.ย._ธ.ค.'.split('_'),\n    monthsParseExact: true,\n    weekdays : 'อาทิตย์_จันทร์_อังคาร_พุธ_พฤหัสบดี_ศุกร์_เสาร์'.split('_'),\n    weekdaysShort : 'อาทิตย์_จันทร์_อังคาร_พุธ_พฤหัส_ศุกร์_เสาร์'.split('_'), // yes, three characters difference\n    weekdaysMin : 'อา._จ._อ._พ._พฤ._ศ._ส.'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat : {\n        LT : 'H:mm',\n        LTS : 'H:mm:ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY เวลา H:mm',\n        LLLL : 'วันddddที่ D MMMM YYYY เวลา H:mm'\n    },\n    meridiemParse: /ก่อนเที่ยง|หลังเที่ยง/,\n    isPM: function (input) {\n        return input === 'หลังเที่ยง';\n    },\n    meridiem : function (hour, minute, isLower) {\n        if (hour < 12) {\n            return 'ก่อนเที่ยง';\n        } else {\n            return 'หลังเที่ยง';\n        }\n    },\n    calendar : {\n        sameDay : '[วันนี้ เวลา] LT',\n        nextDay : '[พรุ่งนี้ เวลา] LT',\n        nextWeek : 'dddd[หน้า เวลา] LT',\n        lastDay : '[เมื่อวานนี้ เวลา] LT',\n        lastWeek : '[วัน]dddd[ที่แล้ว เวลา] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'อีก %s',\n        past : '%sที่แล้ว',\n        s : 'ไม่กี่วินาที',\n        m : '1 นาที',\n        mm : '%d นาที',\n        h : '1 ชั่วโมง',\n        hh : '%d ชั่วโมง',\n        d : '1 วัน',\n        dd : '%d วัน',\n        M : '1 เดือน',\n        MM : '%d เดือน',\n        y : '1 ปี',\n        yy : '%d ปี'\n    }\n});\n\nreturn th;\n\n})));\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/locale/tl-ph.js",
    "content": "//! moment.js locale configuration\n//! locale : Tagalog (Philippines) [tl-ph]\n//! author : Dan Hagman : https://github.com/hagmandan\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\n\nvar tlPh = moment.defineLocale('tl-ph', {\n    months : 'Enero_Pebrero_Marso_Abril_Mayo_Hunyo_Hulyo_Agosto_Setyembre_Oktubre_Nobyembre_Disyembre'.split('_'),\n    monthsShort : 'Ene_Peb_Mar_Abr_May_Hun_Hul_Ago_Set_Okt_Nob_Dis'.split('_'),\n    weekdays : 'Linggo_Lunes_Martes_Miyerkules_Huwebes_Biyernes_Sabado'.split('_'),\n    weekdaysShort : 'Lin_Lun_Mar_Miy_Huw_Biy_Sab'.split('_'),\n    weekdaysMin : 'Li_Lu_Ma_Mi_Hu_Bi_Sab'.split('_'),\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'MM/D/YYYY',\n        LL : 'MMMM D, YYYY',\n        LLL : 'MMMM D, YYYY HH:mm',\n        LLLL : 'dddd, MMMM DD, YYYY HH:mm'\n    },\n    calendar : {\n        sameDay: 'LT [ngayong araw]',\n        nextDay: '[Bukas ng] LT',\n        nextWeek: 'LT [sa susunod na] dddd',\n        lastDay: 'LT [kahapon]',\n        lastWeek: 'LT [noong nakaraang] dddd',\n        sameElse: 'L'\n    },\n    relativeTime : {\n        future : 'sa loob ng %s',\n        past : '%s ang nakalipas',\n        s : 'ilang segundo',\n        m : 'isang minuto',\n        mm : '%d minuto',\n        h : 'isang oras',\n        hh : '%d oras',\n        d : 'isang araw',\n        dd : '%d araw',\n        M : 'isang buwan',\n        MM : '%d buwan',\n        y : 'isang taon',\n        yy : '%d taon'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}/,\n    ordinal : function (number) {\n        return number;\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\nreturn tlPh;\n\n})));\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/locale/tlh.js",
    "content": "//! moment.js locale configuration\n//! locale : Klingon [tlh]\n//! author : Dominika Kruk : https://github.com/amaranthrose\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\n\nvar numbersNouns = 'pagh_wa’_cha’_wej_loS_vagh_jav_Soch_chorgh_Hut'.split('_');\n\nfunction translateFuture(output) {\n    var time = output;\n    time = (output.indexOf('jaj') !== -1) ?\n    time.slice(0, -3) + 'leS' :\n    (output.indexOf('jar') !== -1) ?\n    time.slice(0, -3) + 'waQ' :\n    (output.indexOf('DIS') !== -1) ?\n    time.slice(0, -3) + 'nem' :\n    time + ' pIq';\n    return time;\n}\n\nfunction translatePast(output) {\n    var time = output;\n    time = (output.indexOf('jaj') !== -1) ?\n    time.slice(0, -3) + 'Hu’' :\n    (output.indexOf('jar') !== -1) ?\n    time.slice(0, -3) + 'wen' :\n    (output.indexOf('DIS') !== -1) ?\n    time.slice(0, -3) + 'ben' :\n    time + ' ret';\n    return time;\n}\n\nfunction translate(number, withoutSuffix, string, isFuture) {\n    var numberNoun = numberAsNoun(number);\n    switch (string) {\n        case 'mm':\n            return numberNoun + ' tup';\n        case 'hh':\n            return numberNoun + ' rep';\n        case 'dd':\n            return numberNoun + ' jaj';\n        case 'MM':\n            return numberNoun + ' jar';\n        case 'yy':\n            return numberNoun + ' DIS';\n    }\n}\n\nfunction numberAsNoun(number) {\n    var hundred = Math.floor((number % 1000) / 100),\n    ten = Math.floor((number % 100) / 10),\n    one = number % 10,\n    word = '';\n    if (hundred > 0) {\n        word += numbersNouns[hundred] + 'vatlh';\n    }\n    if (ten > 0) {\n        word += ((word !== '') ? ' ' : '') + numbersNouns[ten] + 'maH';\n    }\n    if (one > 0) {\n        word += ((word !== '') ? ' ' : '') + numbersNouns[one];\n    }\n    return (word === '') ? 'pagh' : word;\n}\n\nvar tlh = moment.defineLocale('tlh', {\n    months : 'tera’ jar wa’_tera’ jar cha’_tera’ jar wej_tera’ jar loS_tera’ jar vagh_tera’ jar jav_tera’ jar Soch_tera’ jar chorgh_tera’ jar Hut_tera’ jar wa’maH_tera’ jar wa’maH wa’_tera’ jar wa’maH cha’'.split('_'),\n    monthsShort : 'jar wa’_jar cha’_jar wej_jar loS_jar vagh_jar jav_jar Soch_jar chorgh_jar Hut_jar wa’maH_jar wa’maH wa’_jar wa’maH cha’'.split('_'),\n    monthsParseExact : true,\n    weekdays : 'lojmItjaj_DaSjaj_povjaj_ghItlhjaj_loghjaj_buqjaj_ghInjaj'.split('_'),\n    weekdaysShort : 'lojmItjaj_DaSjaj_povjaj_ghItlhjaj_loghjaj_buqjaj_ghInjaj'.split('_'),\n    weekdaysMin : 'lojmItjaj_DaSjaj_povjaj_ghItlhjaj_loghjaj_buqjaj_ghInjaj'.split('_'),\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD.MM.YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY HH:mm',\n        LLLL : 'dddd, D MMMM YYYY HH:mm'\n    },\n    calendar : {\n        sameDay: '[DaHjaj] LT',\n        nextDay: '[wa’leS] LT',\n        nextWeek: 'LLL',\n        lastDay: '[wa’Hu’] LT',\n        lastWeek: 'LLL',\n        sameElse: 'L'\n    },\n    relativeTime : {\n        future : translateFuture,\n        past : translatePast,\n        s : 'puS lup',\n        m : 'wa’ tup',\n        mm : translate,\n        h : 'wa’ rep',\n        hh : translate,\n        d : 'wa’ jaj',\n        dd : translate,\n        M : 'wa’ jar',\n        MM : translate,\n        y : 'wa’ DIS',\n        yy : translate\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}\\./,\n    ordinal : '%d.',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\nreturn tlh;\n\n})));\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/locale/tr.js",
    "content": "//! moment.js locale configuration\n//! locale : Turkish [tr]\n//! authors : Erhan Gundogan : https://github.com/erhangundogan,\n//!           Burak Yiğit Kaya: https://github.com/BYK\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\n\nvar suffixes = {\n    1: '\\'inci',\n    5: '\\'inci',\n    8: '\\'inci',\n    70: '\\'inci',\n    80: '\\'inci',\n    2: '\\'nci',\n    7: '\\'nci',\n    20: '\\'nci',\n    50: '\\'nci',\n    3: '\\'üncü',\n    4: '\\'üncü',\n    100: '\\'üncü',\n    6: '\\'ncı',\n    9: '\\'uncu',\n    10: '\\'uncu',\n    30: '\\'uncu',\n    60: '\\'ıncı',\n    90: '\\'ıncı'\n};\n\nvar tr = moment.defineLocale('tr', {\n    months : 'Ocak_Şubat_Mart_Nisan_Mayıs_Haziran_Temmuz_Ağustos_Eylül_Ekim_Kasım_Aralık'.split('_'),\n    monthsShort : 'Oca_Şub_Mar_Nis_May_Haz_Tem_Ağu_Eyl_Eki_Kas_Ara'.split('_'),\n    weekdays : 'Pazar_Pazartesi_Salı_Çarşamba_Perşembe_Cuma_Cumartesi'.split('_'),\n    weekdaysShort : 'Paz_Pts_Sal_Çar_Per_Cum_Cts'.split('_'),\n    weekdaysMin : 'Pz_Pt_Sa_Ça_Pe_Cu_Ct'.split('_'),\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD.MM.YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY HH:mm',\n        LLLL : 'dddd, D MMMM YYYY HH:mm'\n    },\n    calendar : {\n        sameDay : '[bugün saat] LT',\n        nextDay : '[yarın saat] LT',\n        nextWeek : '[haftaya] dddd [saat] LT',\n        lastDay : '[dün] LT',\n        lastWeek : '[geçen hafta] dddd [saat] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : '%s sonra',\n        past : '%s önce',\n        s : 'birkaç saniye',\n        m : 'bir dakika',\n        mm : '%d dakika',\n        h : 'bir saat',\n        hh : '%d saat',\n        d : 'bir gün',\n        dd : '%d gün',\n        M : 'bir ay',\n        MM : '%d ay',\n        y : 'bir yıl',\n        yy : '%d yıl'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}'(inci|nci|üncü|ncı|uncu|ıncı)/,\n    ordinal : function (number) {\n        if (number === 0) {  // special case for zero\n            return number + '\\'ıncı';\n        }\n        var a = number % 10,\n            b = number % 100 - a,\n            c = number >= 100 ? 100 : null;\n        return number + (suffixes[a] || suffixes[b] || suffixes[c]);\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 7  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\nreturn tr;\n\n})));\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/locale/tzl.js",
    "content": "//! moment.js locale configuration\n//! locale : Talossan [tzl]\n//! author : Robin van der Vliet : https://github.com/robin0van0der0v\n//! author : Iustì Canun\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\n\n// After the year there should be a slash and the amount of years since December 26, 1979 in Roman numerals.\n// This is currently too difficult (maybe even impossible) to add.\nvar tzl = moment.defineLocale('tzl', {\n    months : 'Januar_Fevraglh_Març_Avrïu_Mai_Gün_Julia_Guscht_Setemvar_Listopäts_Noemvar_Zecemvar'.split('_'),\n    monthsShort : 'Jan_Fev_Mar_Avr_Mai_Gün_Jul_Gus_Set_Lis_Noe_Zec'.split('_'),\n    weekdays : 'Súladi_Lúneçi_Maitzi_Márcuri_Xhúadi_Viénerçi_Sáturi'.split('_'),\n    weekdaysShort : 'Súl_Lún_Mai_Már_Xhú_Vié_Sát'.split('_'),\n    weekdaysMin : 'Sú_Lú_Ma_Má_Xh_Vi_Sá'.split('_'),\n    longDateFormat : {\n        LT : 'HH.mm',\n        LTS : 'HH.mm.ss',\n        L : 'DD.MM.YYYY',\n        LL : 'D. MMMM [dallas] YYYY',\n        LLL : 'D. MMMM [dallas] YYYY HH.mm',\n        LLLL : 'dddd, [li] D. MMMM [dallas] YYYY HH.mm'\n    },\n    meridiemParse: /d\\'o|d\\'a/i,\n    isPM : function (input) {\n        return 'd\\'o' === input.toLowerCase();\n    },\n    meridiem : function (hours, minutes, isLower) {\n        if (hours > 11) {\n            return isLower ? 'd\\'o' : 'D\\'O';\n        } else {\n            return isLower ? 'd\\'a' : 'D\\'A';\n        }\n    },\n    calendar : {\n        sameDay : '[oxhi à] LT',\n        nextDay : '[demà à] LT',\n        nextWeek : 'dddd [à] LT',\n        lastDay : '[ieiri à] LT',\n        lastWeek : '[sür el] dddd [lasteu à] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'osprei %s',\n        past : 'ja%s',\n        s : processRelativeTime,\n        m : processRelativeTime,\n        mm : processRelativeTime,\n        h : processRelativeTime,\n        hh : processRelativeTime,\n        d : processRelativeTime,\n        dd : processRelativeTime,\n        M : processRelativeTime,\n        MM : processRelativeTime,\n        y : processRelativeTime,\n        yy : processRelativeTime\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}\\./,\n    ordinal : '%d.',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\nfunction processRelativeTime(number, withoutSuffix, key, isFuture) {\n    var format = {\n        's': ['viensas secunds', '\\'iensas secunds'],\n        'm': ['\\'n míut', '\\'iens míut'],\n        'mm': [number + ' míuts', '' + number + ' míuts'],\n        'h': ['\\'n þora', '\\'iensa þora'],\n        'hh': [number + ' þoras', '' + number + ' þoras'],\n        'd': ['\\'n ziua', '\\'iensa ziua'],\n        'dd': [number + ' ziuas', '' + number + ' ziuas'],\n        'M': ['\\'n mes', '\\'iens mes'],\n        'MM': [number + ' mesen', '' + number + ' mesen'],\n        'y': ['\\'n ar', '\\'iens ar'],\n        'yy': [number + ' ars', '' + number + ' ars']\n    };\n    return isFuture ? format[key][0] : (withoutSuffix ? format[key][0] : format[key][1]);\n}\n\nreturn tzl;\n\n})));\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/locale/tzm-latn.js",
    "content": "//! moment.js locale configuration\n//! locale : Central Atlas Tamazight Latin [tzm-latn]\n//! author : Abdel Said : https://github.com/abdelsaid\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\n\nvar tzmLatn = moment.defineLocale('tzm-latn', {\n    months : 'innayr_brˤayrˤ_marˤsˤ_ibrir_mayyw_ywnyw_ywlywz_ɣwšt_šwtanbir_ktˤwbrˤ_nwwanbir_dwjnbir'.split('_'),\n    monthsShort : 'innayr_brˤayrˤ_marˤsˤ_ibrir_mayyw_ywnyw_ywlywz_ɣwšt_šwtanbir_ktˤwbrˤ_nwwanbir_dwjnbir'.split('_'),\n    weekdays : 'asamas_aynas_asinas_akras_akwas_asimwas_asiḍyas'.split('_'),\n    weekdaysShort : 'asamas_aynas_asinas_akras_akwas_asimwas_asiḍyas'.split('_'),\n    weekdaysMin : 'asamas_aynas_asinas_akras_akwas_asimwas_asiḍyas'.split('_'),\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY HH:mm',\n        LLLL : 'dddd D MMMM YYYY HH:mm'\n    },\n    calendar : {\n        sameDay: '[asdkh g] LT',\n        nextDay: '[aska g] LT',\n        nextWeek: 'dddd [g] LT',\n        lastDay: '[assant g] LT',\n        lastWeek: 'dddd [g] LT',\n        sameElse: 'L'\n    },\n    relativeTime : {\n        future : 'dadkh s yan %s',\n        past : 'yan %s',\n        s : 'imik',\n        m : 'minuḍ',\n        mm : '%d minuḍ',\n        h : 'saɛa',\n        hh : '%d tassaɛin',\n        d : 'ass',\n        dd : '%d ossan',\n        M : 'ayowr',\n        MM : '%d iyyirn',\n        y : 'asgas',\n        yy : '%d isgasn'\n    },\n    week : {\n        dow : 6, // Saturday is the first day of the week.\n        doy : 12  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\nreturn tzmLatn;\n\n})));\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/locale/tzm.js",
    "content": "//! moment.js locale configuration\n//! locale : Central Atlas Tamazight [tzm]\n//! author : Abdel Said : https://github.com/abdelsaid\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\n\nvar tzm = moment.defineLocale('tzm', {\n    months : 'ⵉⵏⵏⴰⵢⵔ_ⴱⵕⴰⵢⵕ_ⵎⴰⵕⵚ_ⵉⴱⵔⵉⵔ_ⵎⴰⵢⵢⵓ_ⵢⵓⵏⵢⵓ_ⵢⵓⵍⵢⵓⵣ_ⵖⵓⵛⵜ_ⵛⵓⵜⴰⵏⴱⵉⵔ_ⴽⵟⵓⴱⵕ_ⵏⵓⵡⴰⵏⴱⵉⵔ_ⴷⵓⵊⵏⴱⵉⵔ'.split('_'),\n    monthsShort : 'ⵉⵏⵏⴰⵢⵔ_ⴱⵕⴰⵢⵕ_ⵎⴰⵕⵚ_ⵉⴱⵔⵉⵔ_ⵎⴰⵢⵢⵓ_ⵢⵓⵏⵢⵓ_ⵢⵓⵍⵢⵓⵣ_ⵖⵓⵛⵜ_ⵛⵓⵜⴰⵏⴱⵉⵔ_ⴽⵟⵓⴱⵕ_ⵏⵓⵡⴰⵏⴱⵉⵔ_ⴷⵓⵊⵏⴱⵉⵔ'.split('_'),\n    weekdays : 'ⴰⵙⴰⵎⴰⵙ_ⴰⵢⵏⴰⵙ_ⴰⵙⵉⵏⴰⵙ_ⴰⴽⵔⴰⵙ_ⴰⴽⵡⴰⵙ_ⴰⵙⵉⵎⵡⴰⵙ_ⴰⵙⵉⴹⵢⴰⵙ'.split('_'),\n    weekdaysShort : 'ⴰⵙⴰⵎⴰⵙ_ⴰⵢⵏⴰⵙ_ⴰⵙⵉⵏⴰⵙ_ⴰⴽⵔⴰⵙ_ⴰⴽⵡⴰⵙ_ⴰⵙⵉⵎⵡⴰⵙ_ⴰⵙⵉⴹⵢⴰⵙ'.split('_'),\n    weekdaysMin : 'ⴰⵙⴰⵎⴰⵙ_ⴰⵢⵏⴰⵙ_ⴰⵙⵉⵏⴰⵙ_ⴰⴽⵔⴰⵙ_ⴰⴽⵡⴰⵙ_ⴰⵙⵉⵎⵡⴰⵙ_ⴰⵙⵉⴹⵢⴰⵙ'.split('_'),\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS: 'HH:mm:ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY HH:mm',\n        LLLL : 'dddd D MMMM YYYY HH:mm'\n    },\n    calendar : {\n        sameDay: '[ⴰⵙⴷⵅ ⴴ] LT',\n        nextDay: '[ⴰⵙⴽⴰ ⴴ] LT',\n        nextWeek: 'dddd [ⴴ] LT',\n        lastDay: '[ⴰⵚⴰⵏⵜ ⴴ] LT',\n        lastWeek: 'dddd [ⴴ] LT',\n        sameElse: 'L'\n    },\n    relativeTime : {\n        future : 'ⴷⴰⴷⵅ ⵙ ⵢⴰⵏ %s',\n        past : 'ⵢⴰⵏ %s',\n        s : 'ⵉⵎⵉⴽ',\n        m : 'ⵎⵉⵏⵓⴺ',\n        mm : '%d ⵎⵉⵏⵓⴺ',\n        h : 'ⵙⴰⵄⴰ',\n        hh : '%d ⵜⴰⵙⵙⴰⵄⵉⵏ',\n        d : 'ⴰⵙⵙ',\n        dd : '%d oⵙⵙⴰⵏ',\n        M : 'ⴰⵢoⵓⵔ',\n        MM : '%d ⵉⵢⵢⵉⵔⵏ',\n        y : 'ⴰⵙⴳⴰⵙ',\n        yy : '%d ⵉⵙⴳⴰⵙⵏ'\n    },\n    week : {\n        dow : 6, // Saturday is the first day of the week.\n        doy : 12  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\nreturn tzm;\n\n})));\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/locale/uk.js",
    "content": "//! moment.js locale configuration\n//! locale : Ukrainian [uk]\n//! author : zemlanin : https://github.com/zemlanin\n//! Author : Menelion Elensúle : https://github.com/Oire\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\n\nfunction plural(word, num) {\n    var forms = word.split('_');\n    return num % 10 === 1 && num % 100 !== 11 ? forms[0] : (num % 10 >= 2 && num % 10 <= 4 && (num % 100 < 10 || num % 100 >= 20) ? forms[1] : forms[2]);\n}\nfunction relativeTimeWithPlural(number, withoutSuffix, key) {\n    var format = {\n        'mm': withoutSuffix ? 'хвилина_хвилини_хвилин' : 'хвилину_хвилини_хвилин',\n        'hh': withoutSuffix ? 'година_години_годин' : 'годину_години_годин',\n        'dd': 'день_дні_днів',\n        'MM': 'місяць_місяці_місяців',\n        'yy': 'рік_роки_років'\n    };\n    if (key === 'm') {\n        return withoutSuffix ? 'хвилина' : 'хвилину';\n    }\n    else if (key === 'h') {\n        return withoutSuffix ? 'година' : 'годину';\n    }\n    else {\n        return number + ' ' + plural(format[key], +number);\n    }\n}\nfunction weekdaysCaseReplace(m, format) {\n    var weekdays = {\n        'nominative': 'неділя_понеділок_вівторок_середа_четвер_п’ятниця_субота'.split('_'),\n        'accusative': 'неділю_понеділок_вівторок_середу_четвер_п’ятницю_суботу'.split('_'),\n        'genitive': 'неділі_понеділка_вівторка_середи_четверга_п’ятниці_суботи'.split('_')\n    };\n\n    if (!m) {\n        return weekdays['nominative'];\n    }\n\n    var nounCase = (/(\\[[ВвУу]\\]) ?dddd/).test(format) ?\n        'accusative' :\n        ((/\\[?(?:минулої|наступної)? ?\\] ?dddd/).test(format) ?\n            'genitive' :\n            'nominative');\n    return weekdays[nounCase][m.day()];\n}\nfunction processHoursFunction(str) {\n    return function () {\n        return str + 'о' + (this.hours() === 11 ? 'б' : '') + '] LT';\n    };\n}\n\nvar uk = moment.defineLocale('uk', {\n    months : {\n        'format': 'січня_лютого_березня_квітня_травня_червня_липня_серпня_вересня_жовтня_листопада_грудня'.split('_'),\n        'standalone': 'січень_лютий_березень_квітень_травень_червень_липень_серпень_вересень_жовтень_листопад_грудень'.split('_')\n    },\n    monthsShort : 'січ_лют_бер_квіт_трав_черв_лип_серп_вер_жовт_лист_груд'.split('_'),\n    weekdays : weekdaysCaseReplace,\n    weekdaysShort : 'нд_пн_вт_ср_чт_пт_сб'.split('_'),\n    weekdaysMin : 'нд_пн_вт_ср_чт_пт_сб'.split('_'),\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD.MM.YYYY',\n        LL : 'D MMMM YYYY р.',\n        LLL : 'D MMMM YYYY р., HH:mm',\n        LLLL : 'dddd, D MMMM YYYY р., HH:mm'\n    },\n    calendar : {\n        sameDay: processHoursFunction('[Сьогодні '),\n        nextDay: processHoursFunction('[Завтра '),\n        lastDay: processHoursFunction('[Вчора '),\n        nextWeek: processHoursFunction('[У] dddd ['),\n        lastWeek: function () {\n            switch (this.day()) {\n                case 0:\n                case 3:\n                case 5:\n                case 6:\n                    return processHoursFunction('[Минулої] dddd [').call(this);\n                case 1:\n                case 2:\n                case 4:\n                    return processHoursFunction('[Минулого] dddd [').call(this);\n            }\n        },\n        sameElse: 'L'\n    },\n    relativeTime : {\n        future : 'за %s',\n        past : '%s тому',\n        s : 'декілька секунд',\n        m : relativeTimeWithPlural,\n        mm : relativeTimeWithPlural,\n        h : 'годину',\n        hh : relativeTimeWithPlural,\n        d : 'день',\n        dd : relativeTimeWithPlural,\n        M : 'місяць',\n        MM : relativeTimeWithPlural,\n        y : 'рік',\n        yy : relativeTimeWithPlural\n    },\n    // M. E.: those two are virtually unused but a user might want to implement them for his/her website for some reason\n    meridiemParse: /ночі|ранку|дня|вечора/,\n    isPM: function (input) {\n        return /^(дня|вечора)$/.test(input);\n    },\n    meridiem : function (hour, minute, isLower) {\n        if (hour < 4) {\n            return 'ночі';\n        } else if (hour < 12) {\n            return 'ранку';\n        } else if (hour < 17) {\n            return 'дня';\n        } else {\n            return 'вечора';\n        }\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}-(й|го)/,\n    ordinal: function (number, period) {\n        switch (period) {\n            case 'M':\n            case 'd':\n            case 'DDD':\n            case 'w':\n            case 'W':\n                return number + '-й';\n            case 'D':\n                return number + '-го';\n            default:\n                return number;\n        }\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 7  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\nreturn uk;\n\n})));\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/locale/ur.js",
    "content": "//! moment.js locale configuration\n//! locale : Urdu [ur]\n//! author : Sawood Alam : https://github.com/ibnesayeed\n//! author : Zack : https://github.com/ZackVision\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\n\nvar months = [\n    'جنوری',\n    'فروری',\n    'مارچ',\n    'اپریل',\n    'مئی',\n    'جون',\n    'جولائی',\n    'اگست',\n    'ستمبر',\n    'اکتوبر',\n    'نومبر',\n    'دسمبر'\n];\nvar days = [\n    'اتوار',\n    'پیر',\n    'منگل',\n    'بدھ',\n    'جمعرات',\n    'جمعہ',\n    'ہفتہ'\n];\n\nvar ur = moment.defineLocale('ur', {\n    months : months,\n    monthsShort : months,\n    weekdays : days,\n    weekdaysShort : days,\n    weekdaysMin : days,\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY HH:mm',\n        LLLL : 'dddd، D MMMM YYYY HH:mm'\n    },\n    meridiemParse: /صبح|شام/,\n    isPM : function (input) {\n        return 'شام' === input;\n    },\n    meridiem : function (hour, minute, isLower) {\n        if (hour < 12) {\n            return 'صبح';\n        }\n        return 'شام';\n    },\n    calendar : {\n        sameDay : '[آج بوقت] LT',\n        nextDay : '[کل بوقت] LT',\n        nextWeek : 'dddd [بوقت] LT',\n        lastDay : '[گذشتہ روز بوقت] LT',\n        lastWeek : '[گذشتہ] dddd [بوقت] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : '%s بعد',\n        past : '%s قبل',\n        s : 'چند سیکنڈ',\n        m : 'ایک منٹ',\n        mm : '%d منٹ',\n        h : 'ایک گھنٹہ',\n        hh : '%d گھنٹے',\n        d : 'ایک دن',\n        dd : '%d دن',\n        M : 'ایک ماہ',\n        MM : '%d ماہ',\n        y : 'ایک سال',\n        yy : '%d سال'\n    },\n    preparse: function (string) {\n        return string.replace(/،/g, ',');\n    },\n    postformat: function (string) {\n        return string.replace(/,/g, '،');\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\nreturn ur;\n\n})));\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/locale/uz-latn.js",
    "content": "//! moment.js locale configuration\n//! locale : Uzbek Latin [uz-latn]\n//! author : Rasulbek Mirzayev : github.com/Rasulbeeek\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\n\nvar uzLatn = moment.defineLocale('uz-latn', {\n    months : 'Yanvar_Fevral_Mart_Aprel_May_Iyun_Iyul_Avgust_Sentabr_Oktabr_Noyabr_Dekabr'.split('_'),\n    monthsShort : 'Yan_Fev_Mar_Apr_May_Iyun_Iyul_Avg_Sen_Okt_Noy_Dek'.split('_'),\n    weekdays : 'Yakshanba_Dushanba_Seshanba_Chorshanba_Payshanba_Juma_Shanba'.split('_'),\n    weekdaysShort : 'Yak_Dush_Sesh_Chor_Pay_Jum_Shan'.split('_'),\n    weekdaysMin : 'Ya_Du_Se_Cho_Pa_Ju_Sha'.split('_'),\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY HH:mm',\n        LLLL : 'D MMMM YYYY, dddd HH:mm'\n    },\n    calendar : {\n        sameDay : '[Bugun soat] LT [da]',\n        nextDay : '[Ertaga] LT [da]',\n        nextWeek : 'dddd [kuni soat] LT [da]',\n        lastDay : '[Kecha soat] LT [da]',\n        lastWeek : '[O\\'tgan] dddd [kuni soat] LT [da]',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'Yaqin %s ichida',\n        past : 'Bir necha %s oldin',\n        s : 'soniya',\n        m : 'bir daqiqa',\n        mm : '%d daqiqa',\n        h : 'bir soat',\n        hh : '%d soat',\n        d : 'bir kun',\n        dd : '%d kun',\n        M : 'bir oy',\n        MM : '%d oy',\n        y : 'bir yil',\n        yy : '%d yil'\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 7  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\nreturn uzLatn;\n\n})));\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/locale/uz.js",
    "content": "//! moment.js locale configuration\n//! locale : Uzbek [uz]\n//! author : Sardor Muminov : https://github.com/muminoff\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\n\nvar uz = moment.defineLocale('uz', {\n    months : 'январ_феврал_март_апрел_май_июн_июл_август_сентябр_октябр_ноябр_декабр'.split('_'),\n    monthsShort : 'янв_фев_мар_апр_май_июн_июл_авг_сен_окт_ноя_дек'.split('_'),\n    weekdays : 'Якшанба_Душанба_Сешанба_Чоршанба_Пайшанба_Жума_Шанба'.split('_'),\n    weekdaysShort : 'Якш_Душ_Сеш_Чор_Пай_Жум_Шан'.split('_'),\n    weekdaysMin : 'Як_Ду_Се_Чо_Па_Жу_Ша'.split('_'),\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY HH:mm',\n        LLLL : 'D MMMM YYYY, dddd HH:mm'\n    },\n    calendar : {\n        sameDay : '[Бугун соат] LT [да]',\n        nextDay : '[Эртага] LT [да]',\n        nextWeek : 'dddd [куни соат] LT [да]',\n        lastDay : '[Кеча соат] LT [да]',\n        lastWeek : '[Утган] dddd [куни соат] LT [да]',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'Якин %s ичида',\n        past : 'Бир неча %s олдин',\n        s : 'фурсат',\n        m : 'бир дакика',\n        mm : '%d дакика',\n        h : 'бир соат',\n        hh : '%d соат',\n        d : 'бир кун',\n        dd : '%d кун',\n        M : 'бир ой',\n        MM : '%d ой',\n        y : 'бир йил',\n        yy : '%d йил'\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 7  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\nreturn uz;\n\n})));\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/locale/vi.js",
    "content": "//! moment.js locale configuration\n//! locale : Vietnamese [vi]\n//! author : Bang Nguyen : https://github.com/bangnk\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\n\nvar vi = moment.defineLocale('vi', {\n    months : 'tháng 1_tháng 2_tháng 3_tháng 4_tháng 5_tháng 6_tháng 7_tháng 8_tháng 9_tháng 10_tháng 11_tháng 12'.split('_'),\n    monthsShort : 'Th01_Th02_Th03_Th04_Th05_Th06_Th07_Th08_Th09_Th10_Th11_Th12'.split('_'),\n    monthsParseExact : true,\n    weekdays : 'chủ nhật_thứ hai_thứ ba_thứ tư_thứ năm_thứ sáu_thứ bảy'.split('_'),\n    weekdaysShort : 'CN_T2_T3_T4_T5_T6_T7'.split('_'),\n    weekdaysMin : 'CN_T2_T3_T4_T5_T6_T7'.split('_'),\n    weekdaysParseExact : true,\n    meridiemParse: /sa|ch/i,\n    isPM : function (input) {\n        return /^ch$/i.test(input);\n    },\n    meridiem : function (hours, minutes, isLower) {\n        if (hours < 12) {\n            return isLower ? 'sa' : 'SA';\n        } else {\n            return isLower ? 'ch' : 'CH';\n        }\n    },\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM [năm] YYYY',\n        LLL : 'D MMMM [năm] YYYY HH:mm',\n        LLLL : 'dddd, D MMMM [năm] YYYY HH:mm',\n        l : 'DD/M/YYYY',\n        ll : 'D MMM YYYY',\n        lll : 'D MMM YYYY HH:mm',\n        llll : 'ddd, D MMM YYYY HH:mm'\n    },\n    calendar : {\n        sameDay: '[Hôm nay lúc] LT',\n        nextDay: '[Ngày mai lúc] LT',\n        nextWeek: 'dddd [tuần tới lúc] LT',\n        lastDay: '[Hôm qua lúc] LT',\n        lastWeek: 'dddd [tuần rồi lúc] LT',\n        sameElse: 'L'\n    },\n    relativeTime : {\n        future : '%s tới',\n        past : '%s trước',\n        s : 'vài giây',\n        m : 'một phút',\n        mm : '%d phút',\n        h : 'một giờ',\n        hh : '%d giờ',\n        d : 'một ngày',\n        dd : '%d ngày',\n        M : 'một tháng',\n        MM : '%d tháng',\n        y : 'một năm',\n        yy : '%d năm'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}/,\n    ordinal : function (number) {\n        return number;\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\nreturn vi;\n\n})));\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/locale/x-pseudo.js",
    "content": "//! moment.js locale configuration\n//! locale : Pseudo [x-pseudo]\n//! author : Andrew Hood : https://github.com/andrewhood125\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\n\nvar xPseudo = moment.defineLocale('x-pseudo', {\n    months : 'J~áñúá~rý_F~ébrú~árý_~Márc~h_Áp~ríl_~Máý_~Júñé~_Júl~ý_Áú~gúst~_Sép~témb~ér_Ó~ctób~ér_Ñ~óvém~bér_~Décé~mbér'.split('_'),\n    monthsShort : 'J~áñ_~Féb_~Már_~Ápr_~Máý_~Júñ_~Júl_~Áúg_~Sép_~Óct_~Ñóv_~Déc'.split('_'),\n    monthsParseExact : true,\n    weekdays : 'S~úñdá~ý_Mó~ñdáý~_Túé~sdáý~_Wéd~ñésd~áý_T~húrs~dáý_~Fríd~áý_S~átúr~dáý'.split('_'),\n    weekdaysShort : 'S~úñ_~Móñ_~Túé_~Wéd_~Thú_~Frí_~Sát'.split('_'),\n    weekdaysMin : 'S~ú_Mó~_Tú_~Wé_T~h_Fr~_Sá'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat : {\n        LT : 'HH:mm',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY HH:mm',\n        LLLL : 'dddd, D MMMM YYYY HH:mm'\n    },\n    calendar : {\n        sameDay : '[T~ódá~ý át] LT',\n        nextDay : '[T~ómó~rró~w át] LT',\n        nextWeek : 'dddd [át] LT',\n        lastDay : '[Ý~ést~érdá~ý át] LT',\n        lastWeek : '[L~ást] dddd [át] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'í~ñ %s',\n        past : '%s á~gó',\n        s : 'á ~féw ~sécó~ñds',\n        m : 'á ~míñ~úté',\n        mm : '%d m~íñú~tés',\n        h : 'á~ñ hó~úr',\n        hh : '%d h~óúrs',\n        d : 'á ~dáý',\n        dd : '%d d~áýs',\n        M : 'á ~móñ~th',\n        MM : '%d m~óñt~hs',\n        y : 'á ~ýéár',\n        yy : '%d ý~éárs'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}(th|st|nd|rd)/,\n    ordinal : function (number) {\n        var b = number % 10,\n            output = (~~(number % 100 / 10) === 1) ? 'th' :\n            (b === 1) ? 'st' :\n            (b === 2) ? 'nd' :\n            (b === 3) ? 'rd' : 'th';\n        return number + output;\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\nreturn xPseudo;\n\n})));\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/locale/yo.js",
    "content": "//! moment.js locale configuration\n//! locale : Yoruba Nigeria [yo]\n//! author : Atolagbe Abisoye : https://github.com/andela-batolagbe\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\n\nvar yo = moment.defineLocale('yo', {\n    months : 'Sẹ́rẹ́_Èrèlè_Ẹrẹ̀nà_Ìgbé_Èbibi_Òkùdu_Agẹmo_Ògún_Owewe_Ọ̀wàrà_Bélú_Ọ̀pẹ̀̀'.split('_'),\n    monthsShort : 'Sẹ́r_Èrl_Ẹrn_Ìgb_Èbi_Òkù_Agẹ_Ògú_Owe_Ọ̀wà_Bél_Ọ̀pẹ̀̀'.split('_'),\n    weekdays : 'Àìkú_Ajé_Ìsẹ́gun_Ọjọ́rú_Ọjọ́bọ_Ẹtì_Àbámẹ́ta'.split('_'),\n    weekdaysShort : 'Àìk_Ajé_Ìsẹ́_Ọjr_Ọjb_Ẹtì_Àbá'.split('_'),\n    weekdaysMin : 'Àì_Aj_Ìs_Ọr_Ọb_Ẹt_Àb'.split('_'),\n    longDateFormat : {\n        LT : 'h:mm A',\n        LTS : 'h:mm:ss A',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY h:mm A',\n        LLLL : 'dddd, D MMMM YYYY h:mm A'\n    },\n    calendar : {\n        sameDay : '[Ònì ni] LT',\n        nextDay : '[Ọ̀la ni] LT',\n        nextWeek : 'dddd [Ọsẹ̀ tón\\'bọ] [ni] LT',\n        lastDay : '[Àna ni] LT',\n        lastWeek : 'dddd [Ọsẹ̀ tólọ́] [ni] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'ní %s',\n        past : '%s kọjá',\n        s : 'ìsẹjú aayá die',\n        m : 'ìsẹjú kan',\n        mm : 'ìsẹjú %d',\n        h : 'wákati kan',\n        hh : 'wákati %d',\n        d : 'ọjọ́ kan',\n        dd : 'ọjọ́ %d',\n        M : 'osù kan',\n        MM : 'osù %d',\n        y : 'ọdún kan',\n        yy : 'ọdún %d'\n    },\n    dayOfMonthOrdinalParse : /ọjọ́\\s\\d{1,2}/,\n    ordinal : 'ọjọ́ %d',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4 // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\nreturn yo;\n\n})));\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/locale/zh-cn.js",
    "content": "//! moment.js locale configuration\n//! locale : Chinese (China) [zh-cn]\n//! author : suupic : https://github.com/suupic\n//! author : Zeno Zeng : https://github.com/zenozeng\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\n\nvar zhCn = moment.defineLocale('zh-cn', {\n    months : '一月_二月_三月_四月_五月_六月_七月_八月_九月_十月_十一月_十二月'.split('_'),\n    monthsShort : '1月_2月_3月_4月_5月_6月_7月_8月_9月_10月_11月_12月'.split('_'),\n    weekdays : '星期日_星期一_星期二_星期三_星期四_星期五_星期六'.split('_'),\n    weekdaysShort : '周日_周一_周二_周三_周四_周五_周六'.split('_'),\n    weekdaysMin : '日_一_二_三_四_五_六'.split('_'),\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'YYYY年MMMD日',\n        LL : 'YYYY年MMMD日',\n        LLL : 'YYYY年MMMD日Ah点mm分',\n        LLLL : 'YYYY年MMMD日ddddAh点mm分',\n        l : 'YYYY年MMMD日',\n        ll : 'YYYY年MMMD日',\n        lll : 'YYYY年MMMD日 HH:mm',\n        llll : 'YYYY年MMMD日dddd HH:mm'\n    },\n    meridiemParse: /凌晨|早上|上午|中午|下午|晚上/,\n    meridiemHour: function (hour, meridiem) {\n        if (hour === 12) {\n            hour = 0;\n        }\n        if (meridiem === '凌晨' || meridiem === '早上' ||\n                meridiem === '上午') {\n            return hour;\n        } else if (meridiem === '下午' || meridiem === '晚上') {\n            return hour + 12;\n        } else {\n            // '中午'\n            return hour >= 11 ? hour : hour + 12;\n        }\n    },\n    meridiem : function (hour, minute, isLower) {\n        var hm = hour * 100 + minute;\n        if (hm < 600) {\n            return '凌晨';\n        } else if (hm < 900) {\n            return '早上';\n        } else if (hm < 1130) {\n            return '上午';\n        } else if (hm < 1230) {\n            return '中午';\n        } else if (hm < 1800) {\n            return '下午';\n        } else {\n            return '晚上';\n        }\n    },\n    calendar : {\n        sameDay : '[今天]LT',\n        nextDay : '[明天]LT',\n        nextWeek : '[下]ddddLT',\n        lastDay : '[昨天]LT',\n        lastWeek : '[上]ddddLT',\n        sameElse : 'L'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}(日|月|周)/,\n    ordinal : function (number, period) {\n        switch (period) {\n            case 'd':\n            case 'D':\n            case 'DDD':\n                return number + '日';\n            case 'M':\n                return number + '月';\n            case 'w':\n            case 'W':\n                return number + '周';\n            default:\n                return number;\n        }\n    },\n    relativeTime : {\n        future : '%s内',\n        past : '%s前',\n        s : '几秒',\n        m : '1 分钟',\n        mm : '%d 分钟',\n        h : '1 小时',\n        hh : '%d 小时',\n        d : '1 天',\n        dd : '%d 天',\n        M : '1 个月',\n        MM : '%d 个月',\n        y : '1 年',\n        yy : '%d 年'\n    },\n    week : {\n        // GB/T 7408-1994《数据元和交换格式·信息交换·日期和时间表示法》与ISO 8601:1988等效\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\nreturn zhCn;\n\n})));\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/locale/zh-hk.js",
    "content": "//! moment.js locale configuration\n//! locale : Chinese (Hong Kong) [zh-hk]\n//! author : Ben : https://github.com/ben-lin\n//! author : Chris Lam : https://github.com/hehachris\n//! author : Konstantin : https://github.com/skfd\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\n\nvar zhHk = moment.defineLocale('zh-hk', {\n    months : '一月_二月_三月_四月_五月_六月_七月_八月_九月_十月_十一月_十二月'.split('_'),\n    monthsShort : '1月_2月_3月_4月_5月_6月_7月_8月_9月_10月_11月_12月'.split('_'),\n    weekdays : '星期日_星期一_星期二_星期三_星期四_星期五_星期六'.split('_'),\n    weekdaysShort : '週日_週一_週二_週三_週四_週五_週六'.split('_'),\n    weekdaysMin : '日_一_二_三_四_五_六'.split('_'),\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'YYYY年MMMD日',\n        LL : 'YYYY年MMMD日',\n        LLL : 'YYYY年MMMD日 HH:mm',\n        LLLL : 'YYYY年MMMD日dddd HH:mm',\n        l : 'YYYY年MMMD日',\n        ll : 'YYYY年MMMD日',\n        lll : 'YYYY年MMMD日 HH:mm',\n        llll : 'YYYY年MMMD日dddd HH:mm'\n    },\n    meridiemParse: /凌晨|早上|上午|中午|下午|晚上/,\n    meridiemHour : function (hour, meridiem) {\n        if (hour === 12) {\n            hour = 0;\n        }\n        if (meridiem === '凌晨' || meridiem === '早上' || meridiem === '上午') {\n            return hour;\n        } else if (meridiem === '中午') {\n            return hour >= 11 ? hour : hour + 12;\n        } else if (meridiem === '下午' || meridiem === '晚上') {\n            return hour + 12;\n        }\n    },\n    meridiem : function (hour, minute, isLower) {\n        var hm = hour * 100 + minute;\n        if (hm < 600) {\n            return '凌晨';\n        } else if (hm < 900) {\n            return '早上';\n        } else if (hm < 1130) {\n            return '上午';\n        } else if (hm < 1230) {\n            return '中午';\n        } else if (hm < 1800) {\n            return '下午';\n        } else {\n            return '晚上';\n        }\n    },\n    calendar : {\n        sameDay : '[今天]LT',\n        nextDay : '[明天]LT',\n        nextWeek : '[下]ddddLT',\n        lastDay : '[昨天]LT',\n        lastWeek : '[上]ddddLT',\n        sameElse : 'L'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}(日|月|週)/,\n    ordinal : function (number, period) {\n        switch (period) {\n            case 'd' :\n            case 'D' :\n            case 'DDD' :\n                return number + '日';\n            case 'M' :\n                return number + '月';\n            case 'w' :\n            case 'W' :\n                return number + '週';\n            default :\n                return number;\n        }\n    },\n    relativeTime : {\n        future : '%s內',\n        past : '%s前',\n        s : '幾秒',\n        m : '1 分鐘',\n        mm : '%d 分鐘',\n        h : '1 小時',\n        hh : '%d 小時',\n        d : '1 天',\n        dd : '%d 天',\n        M : '1 個月',\n        MM : '%d 個月',\n        y : '1 年',\n        yy : '%d 年'\n    }\n});\n\nreturn zhHk;\n\n})));\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/locale/zh-tw.js",
    "content": "//! moment.js locale configuration\n//! locale : Chinese (Taiwan) [zh-tw]\n//! author : Ben : https://github.com/ben-lin\n//! author : Chris Lam : https://github.com/hehachris\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\n\nvar zhTw = moment.defineLocale('zh-tw', {\n    months : '一月_二月_三月_四月_五月_六月_七月_八月_九月_十月_十一月_十二月'.split('_'),\n    monthsShort : '1月_2月_3月_4月_5月_6月_7月_8月_9月_10月_11月_12月'.split('_'),\n    weekdays : '星期日_星期一_星期二_星期三_星期四_星期五_星期六'.split('_'),\n    weekdaysShort : '週日_週一_週二_週三_週四_週五_週六'.split('_'),\n    weekdaysMin : '日_一_二_三_四_五_六'.split('_'),\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'YYYY年MMMD日',\n        LL : 'YYYY年MMMD日',\n        LLL : 'YYYY年MMMD日 HH:mm',\n        LLLL : 'YYYY年MMMD日dddd HH:mm',\n        l : 'YYYY年MMMD日',\n        ll : 'YYYY年MMMD日',\n        lll : 'YYYY年MMMD日 HH:mm',\n        llll : 'YYYY年MMMD日dddd HH:mm'\n    },\n    meridiemParse: /凌晨|早上|上午|中午|下午|晚上/,\n    meridiemHour : function (hour, meridiem) {\n        if (hour === 12) {\n            hour = 0;\n        }\n        if (meridiem === '凌晨' || meridiem === '早上' || meridiem === '上午') {\n            return hour;\n        } else if (meridiem === '中午') {\n            return hour >= 11 ? hour : hour + 12;\n        } else if (meridiem === '下午' || meridiem === '晚上') {\n            return hour + 12;\n        }\n    },\n    meridiem : function (hour, minute, isLower) {\n        var hm = hour * 100 + minute;\n        if (hm < 600) {\n            return '凌晨';\n        } else if (hm < 900) {\n            return '早上';\n        } else if (hm < 1130) {\n            return '上午';\n        } else if (hm < 1230) {\n            return '中午';\n        } else if (hm < 1800) {\n            return '下午';\n        } else {\n            return '晚上';\n        }\n    },\n    calendar : {\n        sameDay : '[今天]LT',\n        nextDay : '[明天]LT',\n        nextWeek : '[下]ddddLT',\n        lastDay : '[昨天]LT',\n        lastWeek : '[上]ddddLT',\n        sameElse : 'L'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}(日|月|週)/,\n    ordinal : function (number, period) {\n        switch (period) {\n            case 'd' :\n            case 'D' :\n            case 'DDD' :\n                return number + '日';\n            case 'M' :\n                return number + '月';\n            case 'w' :\n            case 'W' :\n                return number + '週';\n            default :\n                return number;\n        }\n    },\n    relativeTime : {\n        future : '%s內',\n        past : '%s前',\n        s : '幾秒',\n        m : '1 分鐘',\n        mm : '%d 分鐘',\n        h : '1 小時',\n        hh : '%d 小時',\n        d : '1 天',\n        dd : '%d 天',\n        M : '1 個月',\n        MM : '%d 個月',\n        y : '1 年',\n        yy : '%d 年'\n    }\n});\n\nreturn zhTw;\n\n})));\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/meteor/README.md",
    "content": "Packaging [Moment](momentjs.org) for [Meteor.js](http://meteor.com).\n\n# Issues\n\nIf you encounter an issue while using this package, please CC @dandv when you file it in this repo.\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/meteor/export.js",
    "content": "// moment.js makes `moment` global on the window (or global) object, while Meteor expects a file-scoped global variable\nmoment = this.moment;\ntry {\n    delete this.moment;\n} catch (e) {\n}\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/meteor/moment.js",
    "content": "//! moment.js\n//! version : 2.18.1\n//! authors : Tim Wood, Iskren Chernev, Moment.js contributors\n//! license : MIT\n//! momentjs.com\n\n;(function (global, factory) {\n    typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :\n    typeof define === 'function' && define.amd ? define(factory) :\n    global.moment = factory()\n}(this, (function () { 'use strict';\n\nvar hookCallback;\n\nfunction hooks () {\n    return hookCallback.apply(null, arguments);\n}\n\n// This is done to register the method called with moment()\n// without creating circular dependencies.\nfunction setHookCallback (callback) {\n    hookCallback = callback;\n}\n\nfunction isArray(input) {\n    return input instanceof Array || Object.prototype.toString.call(input) === '[object Array]';\n}\n\nfunction isObject(input) {\n    // IE8 will treat undefined and null as object if it wasn't for\n    // input != null\n    return input != null && Object.prototype.toString.call(input) === '[object Object]';\n}\n\nfunction isObjectEmpty(obj) {\n    var k;\n    for (k in obj) {\n        // even if its not own property I'd still call it non-empty\n        return false;\n    }\n    return true;\n}\n\nfunction isUndefined(input) {\n    return input === void 0;\n}\n\nfunction isNumber(input) {\n    return typeof input === 'number' || Object.prototype.toString.call(input) === '[object Number]';\n}\n\nfunction isDate(input) {\n    return input instanceof Date || Object.prototype.toString.call(input) === '[object Date]';\n}\n\nfunction map(arr, fn) {\n    var res = [], i;\n    for (i = 0; i < arr.length; ++i) {\n        res.push(fn(arr[i], i));\n    }\n    return res;\n}\n\nfunction hasOwnProp(a, b) {\n    return Object.prototype.hasOwnProperty.call(a, b);\n}\n\nfunction extend(a, b) {\n    for (var i in b) {\n        if (hasOwnProp(b, i)) {\n            a[i] = b[i];\n        }\n    }\n\n    if (hasOwnProp(b, 'toString')) {\n        a.toString = b.toString;\n    }\n\n    if (hasOwnProp(b, 'valueOf')) {\n        a.valueOf = b.valueOf;\n    }\n\n    return a;\n}\n\nfunction createUTC (input, format, locale, strict) {\n    return createLocalOrUTC(input, format, locale, strict, true).utc();\n}\n\nfunction defaultParsingFlags() {\n    // We need to deep clone this object.\n    return {\n        empty           : false,\n        unusedTokens    : [],\n        unusedInput     : [],\n        overflow        : -2,\n        charsLeftOver   : 0,\n        nullInput       : false,\n        invalidMonth    : null,\n        invalidFormat   : false,\n        userInvalidated : false,\n        iso             : false,\n        parsedDateParts : [],\n        meridiem        : null,\n        rfc2822         : false,\n        weekdayMismatch : false\n    };\n}\n\nfunction getParsingFlags(m) {\n    if (m._pf == null) {\n        m._pf = defaultParsingFlags();\n    }\n    return m._pf;\n}\n\nvar some;\nif (Array.prototype.some) {\n    some = Array.prototype.some;\n} else {\n    some = function (fun) {\n        var t = Object(this);\n        var len = t.length >>> 0;\n\n        for (var i = 0; i < len; i++) {\n            if (i in t && fun.call(this, t[i], i, t)) {\n                return true;\n            }\n        }\n\n        return false;\n    };\n}\n\nvar some$1 = some;\n\nfunction isValid(m) {\n    if (m._isValid == null) {\n        var flags = getParsingFlags(m);\n        var parsedParts = some$1.call(flags.parsedDateParts, function (i) {\n            return i != null;\n        });\n        var isNowValid = !isNaN(m._d.getTime()) &&\n            flags.overflow < 0 &&\n            !flags.empty &&\n            !flags.invalidMonth &&\n            !flags.invalidWeekday &&\n            !flags.nullInput &&\n            !flags.invalidFormat &&\n            !flags.userInvalidated &&\n            (!flags.meridiem || (flags.meridiem && parsedParts));\n\n        if (m._strict) {\n            isNowValid = isNowValid &&\n                flags.charsLeftOver === 0 &&\n                flags.unusedTokens.length === 0 &&\n                flags.bigHour === undefined;\n        }\n\n        if (Object.isFrozen == null || !Object.isFrozen(m)) {\n            m._isValid = isNowValid;\n        }\n        else {\n            return isNowValid;\n        }\n    }\n    return m._isValid;\n}\n\nfunction createInvalid (flags) {\n    var m = createUTC(NaN);\n    if (flags != null) {\n        extend(getParsingFlags(m), flags);\n    }\n    else {\n        getParsingFlags(m).userInvalidated = true;\n    }\n\n    return m;\n}\n\n// Plugins that add properties should also add the key here (null value),\n// so we can properly clone ourselves.\nvar momentProperties = hooks.momentProperties = [];\n\nfunction copyConfig(to, from) {\n    var i, prop, val;\n\n    if (!isUndefined(from._isAMomentObject)) {\n        to._isAMomentObject = from._isAMomentObject;\n    }\n    if (!isUndefined(from._i)) {\n        to._i = from._i;\n    }\n    if (!isUndefined(from._f)) {\n        to._f = from._f;\n    }\n    if (!isUndefined(from._l)) {\n        to._l = from._l;\n    }\n    if (!isUndefined(from._strict)) {\n        to._strict = from._strict;\n    }\n    if (!isUndefined(from._tzm)) {\n        to._tzm = from._tzm;\n    }\n    if (!isUndefined(from._isUTC)) {\n        to._isUTC = from._isUTC;\n    }\n    if (!isUndefined(from._offset)) {\n        to._offset = from._offset;\n    }\n    if (!isUndefined(from._pf)) {\n        to._pf = getParsingFlags(from);\n    }\n    if (!isUndefined(from._locale)) {\n        to._locale = from._locale;\n    }\n\n    if (momentProperties.length > 0) {\n        for (i = 0; i < momentProperties.length; i++) {\n            prop = momentProperties[i];\n            val = from[prop];\n            if (!isUndefined(val)) {\n                to[prop] = val;\n            }\n        }\n    }\n\n    return to;\n}\n\nvar updateInProgress = false;\n\n// Moment prototype object\nfunction Moment(config) {\n    copyConfig(this, config);\n    this._d = new Date(config._d != null ? config._d.getTime() : NaN);\n    if (!this.isValid()) {\n        this._d = new Date(NaN);\n    }\n    // Prevent infinite loop in case updateOffset creates new moment\n    // objects.\n    if (updateInProgress === false) {\n        updateInProgress = true;\n        hooks.updateOffset(this);\n        updateInProgress = false;\n    }\n}\n\nfunction isMoment (obj) {\n    return obj instanceof Moment || (obj != null && obj._isAMomentObject != null);\n}\n\nfunction absFloor (number) {\n    if (number < 0) {\n        // -0 -> 0\n        return Math.ceil(number) || 0;\n    } else {\n        return Math.floor(number);\n    }\n}\n\nfunction toInt(argumentForCoercion) {\n    var coercedNumber = +argumentForCoercion,\n        value = 0;\n\n    if (coercedNumber !== 0 && isFinite(coercedNumber)) {\n        value = absFloor(coercedNumber);\n    }\n\n    return value;\n}\n\n// compare two arrays, return the number of differences\nfunction compareArrays(array1, array2, dontConvert) {\n    var len = Math.min(array1.length, array2.length),\n        lengthDiff = Math.abs(array1.length - array2.length),\n        diffs = 0,\n        i;\n    for (i = 0; i < len; i++) {\n        if ((dontConvert && array1[i] !== array2[i]) ||\n            (!dontConvert && toInt(array1[i]) !== toInt(array2[i]))) {\n            diffs++;\n        }\n    }\n    return diffs + lengthDiff;\n}\n\nfunction warn(msg) {\n    if (hooks.suppressDeprecationWarnings === false &&\n            (typeof console !==  'undefined') && console.warn) {\n        console.warn('Deprecation warning: ' + msg);\n    }\n}\n\nfunction deprecate(msg, fn) {\n    var firstTime = true;\n\n    return extend(function () {\n        if (hooks.deprecationHandler != null) {\n            hooks.deprecationHandler(null, msg);\n        }\n        if (firstTime) {\n            var args = [];\n            var arg;\n            for (var i = 0; i < arguments.length; i++) {\n                arg = '';\n                if (typeof arguments[i] === 'object') {\n                    arg += '\\n[' + i + '] ';\n                    for (var key in arguments[0]) {\n                        arg += key + ': ' + arguments[0][key] + ', ';\n                    }\n                    arg = arg.slice(0, -2); // Remove trailing comma and space\n                } else {\n                    arg = arguments[i];\n                }\n                args.push(arg);\n            }\n            warn(msg + '\\nArguments: ' + Array.prototype.slice.call(args).join('') + '\\n' + (new Error()).stack);\n            firstTime = false;\n        }\n        return fn.apply(this, arguments);\n    }, fn);\n}\n\nvar deprecations = {};\n\nfunction deprecateSimple(name, msg) {\n    if (hooks.deprecationHandler != null) {\n        hooks.deprecationHandler(name, msg);\n    }\n    if (!deprecations[name]) {\n        warn(msg);\n        deprecations[name] = true;\n    }\n}\n\nhooks.suppressDeprecationWarnings = false;\nhooks.deprecationHandler = null;\n\nfunction isFunction(input) {\n    return input instanceof Function || Object.prototype.toString.call(input) === '[object Function]';\n}\n\nfunction set (config) {\n    var prop, i;\n    for (i in config) {\n        prop = config[i];\n        if (isFunction(prop)) {\n            this[i] = prop;\n        } else {\n            this['_' + i] = prop;\n        }\n    }\n    this._config = config;\n    // Lenient ordinal parsing accepts just a number in addition to\n    // number + (possibly) stuff coming from _dayOfMonthOrdinalParse.\n    // TODO: Remove \"ordinalParse\" fallback in next major release.\n    this._dayOfMonthOrdinalParseLenient = new RegExp(\n        (this._dayOfMonthOrdinalParse.source || this._ordinalParse.source) +\n            '|' + (/\\d{1,2}/).source);\n}\n\nfunction mergeConfigs(parentConfig, childConfig) {\n    var res = extend({}, parentConfig), prop;\n    for (prop in childConfig) {\n        if (hasOwnProp(childConfig, prop)) {\n            if (isObject(parentConfig[prop]) && isObject(childConfig[prop])) {\n                res[prop] = {};\n                extend(res[prop], parentConfig[prop]);\n                extend(res[prop], childConfig[prop]);\n            } else if (childConfig[prop] != null) {\n                res[prop] = childConfig[prop];\n            } else {\n                delete res[prop];\n            }\n        }\n    }\n    for (prop in parentConfig) {\n        if (hasOwnProp(parentConfig, prop) &&\n                !hasOwnProp(childConfig, prop) &&\n                isObject(parentConfig[prop])) {\n            // make sure changes to properties don't modify parent config\n            res[prop] = extend({}, res[prop]);\n        }\n    }\n    return res;\n}\n\nfunction Locale(config) {\n    if (config != null) {\n        this.set(config);\n    }\n}\n\nvar keys;\n\nif (Object.keys) {\n    keys = Object.keys;\n} else {\n    keys = function (obj) {\n        var i, res = [];\n        for (i in obj) {\n            if (hasOwnProp(obj, i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    };\n}\n\nvar keys$1 = keys;\n\nvar defaultCalendar = {\n    sameDay : '[Today at] LT',\n    nextDay : '[Tomorrow at] LT',\n    nextWeek : 'dddd [at] LT',\n    lastDay : '[Yesterday at] LT',\n    lastWeek : '[Last] dddd [at] LT',\n    sameElse : 'L'\n};\n\nfunction calendar (key, mom, now) {\n    var output = this._calendar[key] || this._calendar['sameElse'];\n    return isFunction(output) ? output.call(mom, now) : output;\n}\n\nvar defaultLongDateFormat = {\n    LTS  : 'h:mm:ss A',\n    LT   : 'h:mm A',\n    L    : 'MM/DD/YYYY',\n    LL   : 'MMMM D, YYYY',\n    LLL  : 'MMMM D, YYYY h:mm A',\n    LLLL : 'dddd, MMMM D, YYYY h:mm A'\n};\n\nfunction longDateFormat (key) {\n    var format = this._longDateFormat[key],\n        formatUpper = this._longDateFormat[key.toUpperCase()];\n\n    if (format || !formatUpper) {\n        return format;\n    }\n\n    this._longDateFormat[key] = formatUpper.replace(/MMMM|MM|DD|dddd/g, function (val) {\n        return val.slice(1);\n    });\n\n    return this._longDateFormat[key];\n}\n\nvar defaultInvalidDate = 'Invalid date';\n\nfunction invalidDate () {\n    return this._invalidDate;\n}\n\nvar defaultOrdinal = '%d';\nvar defaultDayOfMonthOrdinalParse = /\\d{1,2}/;\n\nfunction ordinal (number) {\n    return this._ordinal.replace('%d', number);\n}\n\nvar defaultRelativeTime = {\n    future : 'in %s',\n    past   : '%s ago',\n    s  : 'a few seconds',\n    ss : '%d seconds',\n    m  : 'a minute',\n    mm : '%d minutes',\n    h  : 'an hour',\n    hh : '%d hours',\n    d  : 'a day',\n    dd : '%d days',\n    M  : 'a month',\n    MM : '%d months',\n    y  : 'a year',\n    yy : '%d years'\n};\n\nfunction relativeTime (number, withoutSuffix, string, isFuture) {\n    var output = this._relativeTime[string];\n    return (isFunction(output)) ?\n        output(number, withoutSuffix, string, isFuture) :\n        output.replace(/%d/i, number);\n}\n\nfunction pastFuture (diff, output) {\n    var format = this._relativeTime[diff > 0 ? 'future' : 'past'];\n    return isFunction(format) ? format(output) : format.replace(/%s/i, output);\n}\n\nvar aliases = {};\n\nfunction addUnitAlias (unit, shorthand) {\n    var lowerCase = unit.toLowerCase();\n    aliases[lowerCase] = aliases[lowerCase + 's'] = aliases[shorthand] = unit;\n}\n\nfunction normalizeUnits(units) {\n    return typeof units === 'string' ? aliases[units] || aliases[units.toLowerCase()] : undefined;\n}\n\nfunction normalizeObjectUnits(inputObject) {\n    var normalizedInput = {},\n        normalizedProp,\n        prop;\n\n    for (prop in inputObject) {\n        if (hasOwnProp(inputObject, prop)) {\n            normalizedProp = normalizeUnits(prop);\n            if (normalizedProp) {\n                normalizedInput[normalizedProp] = inputObject[prop];\n            }\n        }\n    }\n\n    return normalizedInput;\n}\n\nvar priorities = {};\n\nfunction addUnitPriority(unit, priority) {\n    priorities[unit] = priority;\n}\n\nfunction getPrioritizedUnits(unitsObj) {\n    var units = [];\n    for (var u in unitsObj) {\n        units.push({unit: u, priority: priorities[u]});\n    }\n    units.sort(function (a, b) {\n        return a.priority - b.priority;\n    });\n    return units;\n}\n\nfunction makeGetSet (unit, keepTime) {\n    return function (value) {\n        if (value != null) {\n            set$1(this, unit, value);\n            hooks.updateOffset(this, keepTime);\n            return this;\n        } else {\n            return get(this, unit);\n        }\n    };\n}\n\nfunction get (mom, unit) {\n    return mom.isValid() ?\n        mom._d['get' + (mom._isUTC ? 'UTC' : '') + unit]() : NaN;\n}\n\nfunction set$1 (mom, unit, value) {\n    if (mom.isValid()) {\n        mom._d['set' + (mom._isUTC ? 'UTC' : '') + unit](value);\n    }\n}\n\n// MOMENTS\n\nfunction stringGet (units) {\n    units = normalizeUnits(units);\n    if (isFunction(this[units])) {\n        return this[units]();\n    }\n    return this;\n}\n\n\nfunction stringSet (units, value) {\n    if (typeof units === 'object') {\n        units = normalizeObjectUnits(units);\n        var prioritized = getPrioritizedUnits(units);\n        for (var i = 0; i < prioritized.length; i++) {\n            this[prioritized[i].unit](units[prioritized[i].unit]);\n        }\n    } else {\n        units = normalizeUnits(units);\n        if (isFunction(this[units])) {\n            return this[units](value);\n        }\n    }\n    return this;\n}\n\nfunction zeroFill(number, targetLength, forceSign) {\n    var absNumber = '' + Math.abs(number),\n        zerosToFill = targetLength - absNumber.length,\n        sign = number >= 0;\n    return (sign ? (forceSign ? '+' : '') : '-') +\n        Math.pow(10, Math.max(0, zerosToFill)).toString().substr(1) + absNumber;\n}\n\nvar formattingTokens = /(\\[[^\\[]*\\])|(\\\\)?([Hh]mm(ss)?|Mo|MM?M?M?|Do|DDDo|DD?D?D?|ddd?d?|do?|w[o|w]?|W[o|W]?|Qo?|YYYYYY|YYYYY|YYYY|YY|gg(ggg?)?|GG(GGG?)?|e|E|a|A|hh?|HH?|kk?|mm?|ss?|S{1,9}|x|X|zz?|ZZ?|.)/g;\n\nvar localFormattingTokens = /(\\[[^\\[]*\\])|(\\\\)?(LTS|LT|LL?L?L?|l{1,4})/g;\n\nvar formatFunctions = {};\n\nvar formatTokenFunctions = {};\n\n// token:    'M'\n// padded:   ['MM', 2]\n// ordinal:  'Mo'\n// callback: function () { this.month() + 1 }\nfunction addFormatToken (token, padded, ordinal, callback) {\n    var func = callback;\n    if (typeof callback === 'string') {\n        func = function () {\n            return this[callback]();\n        };\n    }\n    if (token) {\n        formatTokenFunctions[token] = func;\n    }\n    if (padded) {\n        formatTokenFunctions[padded[0]] = function () {\n            return zeroFill(func.apply(this, arguments), padded[1], padded[2]);\n        };\n    }\n    if (ordinal) {\n        formatTokenFunctions[ordinal] = function () {\n            return this.localeData().ordinal(func.apply(this, arguments), token);\n        };\n    }\n}\n\nfunction removeFormattingTokens(input) {\n    if (input.match(/\\[[\\s\\S]/)) {\n        return input.replace(/^\\[|\\]$/g, '');\n    }\n    return input.replace(/\\\\/g, '');\n}\n\nfunction makeFormatFunction(format) {\n    var array = format.match(formattingTokens), i, length;\n\n    for (i = 0, length = array.length; i < length; i++) {\n        if (formatTokenFunctions[array[i]]) {\n            array[i] = formatTokenFunctions[array[i]];\n        } else {\n            array[i] = removeFormattingTokens(array[i]);\n        }\n    }\n\n    return function (mom) {\n        var output = '', i;\n        for (i = 0; i < length; i++) {\n            output += isFunction(array[i]) ? array[i].call(mom, format) : array[i];\n        }\n        return output;\n    };\n}\n\n// format date using native date object\nfunction formatMoment(m, format) {\n    if (!m.isValid()) {\n        return m.localeData().invalidDate();\n    }\n\n    format = expandFormat(format, m.localeData());\n    formatFunctions[format] = formatFunctions[format] || makeFormatFunction(format);\n\n    return formatFunctions[format](m);\n}\n\nfunction expandFormat(format, locale) {\n    var i = 5;\n\n    function replaceLongDateFormatTokens(input) {\n        return locale.longDateFormat(input) || input;\n    }\n\n    localFormattingTokens.lastIndex = 0;\n    while (i >= 0 && localFormattingTokens.test(format)) {\n        format = format.replace(localFormattingTokens, replaceLongDateFormatTokens);\n        localFormattingTokens.lastIndex = 0;\n        i -= 1;\n    }\n\n    return format;\n}\n\nvar match1         = /\\d/;            //       0 - 9\nvar match2         = /\\d\\d/;          //      00 - 99\nvar match3         = /\\d{3}/;         //     000 - 999\nvar match4         = /\\d{4}/;         //    0000 - 9999\nvar match6         = /[+-]?\\d{6}/;    // -999999 - 999999\nvar match1to2      = /\\d\\d?/;         //       0 - 99\nvar match3to4      = /\\d\\d\\d\\d?/;     //     999 - 9999\nvar match5to6      = /\\d\\d\\d\\d\\d\\d?/; //   99999 - 999999\nvar match1to3      = /\\d{1,3}/;       //       0 - 999\nvar match1to4      = /\\d{1,4}/;       //       0 - 9999\nvar match1to6      = /[+-]?\\d{1,6}/;  // -999999 - 999999\n\nvar matchUnsigned  = /\\d+/;           //       0 - inf\nvar matchSigned    = /[+-]?\\d+/;      //    -inf - inf\n\nvar matchOffset    = /Z|[+-]\\d\\d:?\\d\\d/gi; // +00:00 -00:00 +0000 -0000 or Z\nvar matchShortOffset = /Z|[+-]\\d\\d(?::?\\d\\d)?/gi; // +00 -00 +00:00 -00:00 +0000 -0000 or Z\n\nvar matchTimestamp = /[+-]?\\d+(\\.\\d{1,3})?/; // 123456789 123456789.123\n\n// any word (or two) characters or numbers including two/three word month in arabic.\n// includes scottish gaelic two word and hyphenated months\nvar matchWord = /[0-9]*['a-z\\u00A0-\\u05FF\\u0700-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF]+|[\\u0600-\\u06FF\\/]+(\\s*?[\\u0600-\\u06FF]+){1,2}/i;\n\n\nvar regexes = {};\n\nfunction addRegexToken (token, regex, strictRegex) {\n    regexes[token] = isFunction(regex) ? regex : function (isStrict, localeData) {\n        return (isStrict && strictRegex) ? strictRegex : regex;\n    };\n}\n\nfunction getParseRegexForToken (token, config) {\n    if (!hasOwnProp(regexes, token)) {\n        return new RegExp(unescapeFormat(token));\n    }\n\n    return regexes[token](config._strict, config._locale);\n}\n\n// Code from http://stackoverflow.com/questions/3561493/is-there-a-regexp-escape-function-in-javascript\nfunction unescapeFormat(s) {\n    return regexEscape(s.replace('\\\\', '').replace(/\\\\(\\[)|\\\\(\\])|\\[([^\\]\\[]*)\\]|\\\\(.)/g, function (matched, p1, p2, p3, p4) {\n        return p1 || p2 || p3 || p4;\n    }));\n}\n\nfunction regexEscape(s) {\n    return s.replace(/[-\\/\\\\^$*+?.()|[\\]{}]/g, '\\\\$&');\n}\n\nvar tokens = {};\n\nfunction addParseToken (token, callback) {\n    var i, func = callback;\n    if (typeof token === 'string') {\n        token = [token];\n    }\n    if (isNumber(callback)) {\n        func = function (input, array) {\n            array[callback] = toInt(input);\n        };\n    }\n    for (i = 0; i < token.length; i++) {\n        tokens[token[i]] = func;\n    }\n}\n\nfunction addWeekParseToken (token, callback) {\n    addParseToken(token, function (input, array, config, token) {\n        config._w = config._w || {};\n        callback(input, config._w, config, token);\n    });\n}\n\nfunction addTimeToArrayFromToken(token, input, config) {\n    if (input != null && hasOwnProp(tokens, token)) {\n        tokens[token](input, config._a, config, token);\n    }\n}\n\nvar YEAR = 0;\nvar MONTH = 1;\nvar DATE = 2;\nvar HOUR = 3;\nvar MINUTE = 4;\nvar SECOND = 5;\nvar MILLISECOND = 6;\nvar WEEK = 7;\nvar WEEKDAY = 8;\n\nvar indexOf;\n\nif (Array.prototype.indexOf) {\n    indexOf = Array.prototype.indexOf;\n} else {\n    indexOf = function (o) {\n        // I know\n        var i;\n        for (i = 0; i < this.length; ++i) {\n            if (this[i] === o) {\n                return i;\n            }\n        }\n        return -1;\n    };\n}\n\nvar indexOf$1 = indexOf;\n\nfunction daysInMonth(year, month) {\n    return new Date(Date.UTC(year, month + 1, 0)).getUTCDate();\n}\n\n// FORMATTING\n\naddFormatToken('M', ['MM', 2], 'Mo', function () {\n    return this.month() + 1;\n});\n\naddFormatToken('MMM', 0, 0, function (format) {\n    return this.localeData().monthsShort(this, format);\n});\n\naddFormatToken('MMMM', 0, 0, function (format) {\n    return this.localeData().months(this, format);\n});\n\n// ALIASES\n\naddUnitAlias('month', 'M');\n\n// PRIORITY\n\naddUnitPriority('month', 8);\n\n// PARSING\n\naddRegexToken('M',    match1to2);\naddRegexToken('MM',   match1to2, match2);\naddRegexToken('MMM',  function (isStrict, locale) {\n    return locale.monthsShortRegex(isStrict);\n});\naddRegexToken('MMMM', function (isStrict, locale) {\n    return locale.monthsRegex(isStrict);\n});\n\naddParseToken(['M', 'MM'], function (input, array) {\n    array[MONTH] = toInt(input) - 1;\n});\n\naddParseToken(['MMM', 'MMMM'], function (input, array, config, token) {\n    var month = config._locale.monthsParse(input, token, config._strict);\n    // if we didn't find a month name, mark the date as invalid.\n    if (month != null) {\n        array[MONTH] = month;\n    } else {\n        getParsingFlags(config).invalidMonth = input;\n    }\n});\n\n// LOCALES\n\nvar MONTHS_IN_FORMAT = /D[oD]?(\\[[^\\[\\]]*\\]|\\s)+MMMM?/;\nvar defaultLocaleMonths = 'January_February_March_April_May_June_July_August_September_October_November_December'.split('_');\nfunction localeMonths (m, format) {\n    if (!m) {\n        return isArray(this._months) ? this._months :\n            this._months['standalone'];\n    }\n    return isArray(this._months) ? this._months[m.month()] :\n        this._months[(this._months.isFormat || MONTHS_IN_FORMAT).test(format) ? 'format' : 'standalone'][m.month()];\n}\n\nvar defaultLocaleMonthsShort = 'Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec'.split('_');\nfunction localeMonthsShort (m, format) {\n    if (!m) {\n        return isArray(this._monthsShort) ? this._monthsShort :\n            this._monthsShort['standalone'];\n    }\n    return isArray(this._monthsShort) ? this._monthsShort[m.month()] :\n        this._monthsShort[MONTHS_IN_FORMAT.test(format) ? 'format' : 'standalone'][m.month()];\n}\n\nfunction handleStrictParse(monthName, format, strict) {\n    var i, ii, mom, llc = monthName.toLocaleLowerCase();\n    if (!this._monthsParse) {\n        // this is not used\n        this._monthsParse = [];\n        this._longMonthsParse = [];\n        this._shortMonthsParse = [];\n        for (i = 0; i < 12; ++i) {\n            mom = createUTC([2000, i]);\n            this._shortMonthsParse[i] = this.monthsShort(mom, '').toLocaleLowerCase();\n            this._longMonthsParse[i] = this.months(mom, '').toLocaleLowerCase();\n        }\n    }\n\n    if (strict) {\n        if (format === 'MMM') {\n            ii = indexOf$1.call(this._shortMonthsParse, llc);\n            return ii !== -1 ? ii : null;\n        } else {\n            ii = indexOf$1.call(this._longMonthsParse, llc);\n            return ii !== -1 ? ii : null;\n        }\n    } else {\n        if (format === 'MMM') {\n            ii = indexOf$1.call(this._shortMonthsParse, llc);\n            if (ii !== -1) {\n                return ii;\n            }\n            ii = indexOf$1.call(this._longMonthsParse, llc);\n            return ii !== -1 ? ii : null;\n        } else {\n            ii = indexOf$1.call(this._longMonthsParse, llc);\n            if (ii !== -1) {\n                return ii;\n            }\n            ii = indexOf$1.call(this._shortMonthsParse, llc);\n            return ii !== -1 ? ii : null;\n        }\n    }\n}\n\nfunction localeMonthsParse (monthName, format, strict) {\n    var i, mom, regex;\n\n    if (this._monthsParseExact) {\n        return handleStrictParse.call(this, monthName, format, strict);\n    }\n\n    if (!this._monthsParse) {\n        this._monthsParse = [];\n        this._longMonthsParse = [];\n        this._shortMonthsParse = [];\n    }\n\n    // TODO: add sorting\n    // Sorting makes sure if one month (or abbr) is a prefix of another\n    // see sorting in computeMonthsParse\n    for (i = 0; i < 12; i++) {\n        // make the regex if we don't have it already\n        mom = createUTC([2000, i]);\n        if (strict && !this._longMonthsParse[i]) {\n            this._longMonthsParse[i] = new RegExp('^' + this.months(mom, '').replace('.', '') + '$', 'i');\n            this._shortMonthsParse[i] = new RegExp('^' + this.monthsShort(mom, '').replace('.', '') + '$', 'i');\n        }\n        if (!strict && !this._monthsParse[i]) {\n            regex = '^' + this.months(mom, '') + '|^' + this.monthsShort(mom, '');\n            this._monthsParse[i] = new RegExp(regex.replace('.', ''), 'i');\n        }\n        // test the regex\n        if (strict && format === 'MMMM' && this._longMonthsParse[i].test(monthName)) {\n            return i;\n        } else if (strict && format === 'MMM' && this._shortMonthsParse[i].test(monthName)) {\n            return i;\n        } else if (!strict && this._monthsParse[i].test(monthName)) {\n            return i;\n        }\n    }\n}\n\n// MOMENTS\n\nfunction setMonth (mom, value) {\n    var dayOfMonth;\n\n    if (!mom.isValid()) {\n        // No op\n        return mom;\n    }\n\n    if (typeof value === 'string') {\n        if (/^\\d+$/.test(value)) {\n            value = toInt(value);\n        } else {\n            value = mom.localeData().monthsParse(value);\n            // TODO: Another silent failure?\n            if (!isNumber(value)) {\n                return mom;\n            }\n        }\n    }\n\n    dayOfMonth = Math.min(mom.date(), daysInMonth(mom.year(), value));\n    mom._d['set' + (mom._isUTC ? 'UTC' : '') + 'Month'](value, dayOfMonth);\n    return mom;\n}\n\nfunction getSetMonth (value) {\n    if (value != null) {\n        setMonth(this, value);\n        hooks.updateOffset(this, true);\n        return this;\n    } else {\n        return get(this, 'Month');\n    }\n}\n\nfunction getDaysInMonth () {\n    return daysInMonth(this.year(), this.month());\n}\n\nvar defaultMonthsShortRegex = matchWord;\nfunction monthsShortRegex (isStrict) {\n    if (this._monthsParseExact) {\n        if (!hasOwnProp(this, '_monthsRegex')) {\n            computeMonthsParse.call(this);\n        }\n        if (isStrict) {\n            return this._monthsShortStrictRegex;\n        } else {\n            return this._monthsShortRegex;\n        }\n    } else {\n        if (!hasOwnProp(this, '_monthsShortRegex')) {\n            this._monthsShortRegex = defaultMonthsShortRegex;\n        }\n        return this._monthsShortStrictRegex && isStrict ?\n            this._monthsShortStrictRegex : this._monthsShortRegex;\n    }\n}\n\nvar defaultMonthsRegex = matchWord;\nfunction monthsRegex (isStrict) {\n    if (this._monthsParseExact) {\n        if (!hasOwnProp(this, '_monthsRegex')) {\n            computeMonthsParse.call(this);\n        }\n        if (isStrict) {\n            return this._monthsStrictRegex;\n        } else {\n            return this._monthsRegex;\n        }\n    } else {\n        if (!hasOwnProp(this, '_monthsRegex')) {\n            this._monthsRegex = defaultMonthsRegex;\n        }\n        return this._monthsStrictRegex && isStrict ?\n            this._monthsStrictRegex : this._monthsRegex;\n    }\n}\n\nfunction computeMonthsParse () {\n    function cmpLenRev(a, b) {\n        return b.length - a.length;\n    }\n\n    var shortPieces = [], longPieces = [], mixedPieces = [],\n        i, mom;\n    for (i = 0; i < 12; i++) {\n        // make the regex if we don't have it already\n        mom = createUTC([2000, i]);\n        shortPieces.push(this.monthsShort(mom, ''));\n        longPieces.push(this.months(mom, ''));\n        mixedPieces.push(this.months(mom, ''));\n        mixedPieces.push(this.monthsShort(mom, ''));\n    }\n    // Sorting makes sure if one month (or abbr) is a prefix of another it\n    // will match the longer piece.\n    shortPieces.sort(cmpLenRev);\n    longPieces.sort(cmpLenRev);\n    mixedPieces.sort(cmpLenRev);\n    for (i = 0; i < 12; i++) {\n        shortPieces[i] = regexEscape(shortPieces[i]);\n        longPieces[i] = regexEscape(longPieces[i]);\n    }\n    for (i = 0; i < 24; i++) {\n        mixedPieces[i] = regexEscape(mixedPieces[i]);\n    }\n\n    this._monthsRegex = new RegExp('^(' + mixedPieces.join('|') + ')', 'i');\n    this._monthsShortRegex = this._monthsRegex;\n    this._monthsStrictRegex = new RegExp('^(' + longPieces.join('|') + ')', 'i');\n    this._monthsShortStrictRegex = new RegExp('^(' + shortPieces.join('|') + ')', 'i');\n}\n\n// FORMATTING\n\naddFormatToken('Y', 0, 0, function () {\n    var y = this.year();\n    return y <= 9999 ? '' + y : '+' + y;\n});\n\naddFormatToken(0, ['YY', 2], 0, function () {\n    return this.year() % 100;\n});\n\naddFormatToken(0, ['YYYY',   4],       0, 'year');\naddFormatToken(0, ['YYYYY',  5],       0, 'year');\naddFormatToken(0, ['YYYYYY', 6, true], 0, 'year');\n\n// ALIASES\n\naddUnitAlias('year', 'y');\n\n// PRIORITIES\n\naddUnitPriority('year', 1);\n\n// PARSING\n\naddRegexToken('Y',      matchSigned);\naddRegexToken('YY',     match1to2, match2);\naddRegexToken('YYYY',   match1to4, match4);\naddRegexToken('YYYYY',  match1to6, match6);\naddRegexToken('YYYYYY', match1to6, match6);\n\naddParseToken(['YYYYY', 'YYYYYY'], YEAR);\naddParseToken('YYYY', function (input, array) {\n    array[YEAR] = input.length === 2 ? hooks.parseTwoDigitYear(input) : toInt(input);\n});\naddParseToken('YY', function (input, array) {\n    array[YEAR] = hooks.parseTwoDigitYear(input);\n});\naddParseToken('Y', function (input, array) {\n    array[YEAR] = parseInt(input, 10);\n});\n\n// HELPERS\n\nfunction daysInYear(year) {\n    return isLeapYear(year) ? 366 : 365;\n}\n\nfunction isLeapYear(year) {\n    return (year % 4 === 0 && year % 100 !== 0) || year % 400 === 0;\n}\n\n// HOOKS\n\nhooks.parseTwoDigitYear = function (input) {\n    return toInt(input) + (toInt(input) > 68 ? 1900 : 2000);\n};\n\n// MOMENTS\n\nvar getSetYear = makeGetSet('FullYear', true);\n\nfunction getIsLeapYear () {\n    return isLeapYear(this.year());\n}\n\nfunction createDate (y, m, d, h, M, s, ms) {\n    // can't just apply() to create a date:\n    // https://stackoverflow.com/q/181348\n    var date = new Date(y, m, d, h, M, s, ms);\n\n    // the date constructor remaps years 0-99 to 1900-1999\n    if (y < 100 && y >= 0 && isFinite(date.getFullYear())) {\n        date.setFullYear(y);\n    }\n    return date;\n}\n\nfunction createUTCDate (y) {\n    var date = new Date(Date.UTC.apply(null, arguments));\n\n    // the Date.UTC function remaps years 0-99 to 1900-1999\n    if (y < 100 && y >= 0 && isFinite(date.getUTCFullYear())) {\n        date.setUTCFullYear(y);\n    }\n    return date;\n}\n\n// start-of-first-week - start-of-year\nfunction firstWeekOffset(year, dow, doy) {\n    var // first-week day -- which january is always in the first week (4 for iso, 1 for other)\n        fwd = 7 + dow - doy,\n        // first-week day local weekday -- which local weekday is fwd\n        fwdlw = (7 + createUTCDate(year, 0, fwd).getUTCDay() - dow) % 7;\n\n    return -fwdlw + fwd - 1;\n}\n\n// https://en.wikipedia.org/wiki/ISO_week_date#Calculating_a_date_given_the_year.2C_week_number_and_weekday\nfunction dayOfYearFromWeeks(year, week, weekday, dow, doy) {\n    var localWeekday = (7 + weekday - dow) % 7,\n        weekOffset = firstWeekOffset(year, dow, doy),\n        dayOfYear = 1 + 7 * (week - 1) + localWeekday + weekOffset,\n        resYear, resDayOfYear;\n\n    if (dayOfYear <= 0) {\n        resYear = year - 1;\n        resDayOfYear = daysInYear(resYear) + dayOfYear;\n    } else if (dayOfYear > daysInYear(year)) {\n        resYear = year + 1;\n        resDayOfYear = dayOfYear - daysInYear(year);\n    } else {\n        resYear = year;\n        resDayOfYear = dayOfYear;\n    }\n\n    return {\n        year: resYear,\n        dayOfYear: resDayOfYear\n    };\n}\n\nfunction weekOfYear(mom, dow, doy) {\n    var weekOffset = firstWeekOffset(mom.year(), dow, doy),\n        week = Math.floor((mom.dayOfYear() - weekOffset - 1) / 7) + 1,\n        resWeek, resYear;\n\n    if (week < 1) {\n        resYear = mom.year() - 1;\n        resWeek = week + weeksInYear(resYear, dow, doy);\n    } else if (week > weeksInYear(mom.year(), dow, doy)) {\n        resWeek = week - weeksInYear(mom.year(), dow, doy);\n        resYear = mom.year() + 1;\n    } else {\n        resYear = mom.year();\n        resWeek = week;\n    }\n\n    return {\n        week: resWeek,\n        year: resYear\n    };\n}\n\nfunction weeksInYear(year, dow, doy) {\n    var weekOffset = firstWeekOffset(year, dow, doy),\n        weekOffsetNext = firstWeekOffset(year + 1, dow, doy);\n    return (daysInYear(year) - weekOffset + weekOffsetNext) / 7;\n}\n\n// FORMATTING\n\naddFormatToken('w', ['ww', 2], 'wo', 'week');\naddFormatToken('W', ['WW', 2], 'Wo', 'isoWeek');\n\n// ALIASES\n\naddUnitAlias('week', 'w');\naddUnitAlias('isoWeek', 'W');\n\n// PRIORITIES\n\naddUnitPriority('week', 5);\naddUnitPriority('isoWeek', 5);\n\n// PARSING\n\naddRegexToken('w',  match1to2);\naddRegexToken('ww', match1to2, match2);\naddRegexToken('W',  match1to2);\naddRegexToken('WW', match1to2, match2);\n\naddWeekParseToken(['w', 'ww', 'W', 'WW'], function (input, week, config, token) {\n    week[token.substr(0, 1)] = toInt(input);\n});\n\n// HELPERS\n\n// LOCALES\n\nfunction localeWeek (mom) {\n    return weekOfYear(mom, this._week.dow, this._week.doy).week;\n}\n\nvar defaultLocaleWeek = {\n    dow : 0, // Sunday is the first day of the week.\n    doy : 6  // The week that contains Jan 1st is the first week of the year.\n};\n\nfunction localeFirstDayOfWeek () {\n    return this._week.dow;\n}\n\nfunction localeFirstDayOfYear () {\n    return this._week.doy;\n}\n\n// MOMENTS\n\nfunction getSetWeek (input) {\n    var week = this.localeData().week(this);\n    return input == null ? week : this.add((input - week) * 7, 'd');\n}\n\nfunction getSetISOWeek (input) {\n    var week = weekOfYear(this, 1, 4).week;\n    return input == null ? week : this.add((input - week) * 7, 'd');\n}\n\n// FORMATTING\n\naddFormatToken('d', 0, 'do', 'day');\n\naddFormatToken('dd', 0, 0, function (format) {\n    return this.localeData().weekdaysMin(this, format);\n});\n\naddFormatToken('ddd', 0, 0, function (format) {\n    return this.localeData().weekdaysShort(this, format);\n});\n\naddFormatToken('dddd', 0, 0, function (format) {\n    return this.localeData().weekdays(this, format);\n});\n\naddFormatToken('e', 0, 0, 'weekday');\naddFormatToken('E', 0, 0, 'isoWeekday');\n\n// ALIASES\n\naddUnitAlias('day', 'd');\naddUnitAlias('weekday', 'e');\naddUnitAlias('isoWeekday', 'E');\n\n// PRIORITY\naddUnitPriority('day', 11);\naddUnitPriority('weekday', 11);\naddUnitPriority('isoWeekday', 11);\n\n// PARSING\n\naddRegexToken('d',    match1to2);\naddRegexToken('e',    match1to2);\naddRegexToken('E',    match1to2);\naddRegexToken('dd',   function (isStrict, locale) {\n    return locale.weekdaysMinRegex(isStrict);\n});\naddRegexToken('ddd',   function (isStrict, locale) {\n    return locale.weekdaysShortRegex(isStrict);\n});\naddRegexToken('dddd',   function (isStrict, locale) {\n    return locale.weekdaysRegex(isStrict);\n});\n\naddWeekParseToken(['dd', 'ddd', 'dddd'], function (input, week, config, token) {\n    var weekday = config._locale.weekdaysParse(input, token, config._strict);\n    // if we didn't get a weekday name, mark the date as invalid\n    if (weekday != null) {\n        week.d = weekday;\n    } else {\n        getParsingFlags(config).invalidWeekday = input;\n    }\n});\n\naddWeekParseToken(['d', 'e', 'E'], function (input, week, config, token) {\n    week[token] = toInt(input);\n});\n\n// HELPERS\n\nfunction parseWeekday(input, locale) {\n    if (typeof input !== 'string') {\n        return input;\n    }\n\n    if (!isNaN(input)) {\n        return parseInt(input, 10);\n    }\n\n    input = locale.weekdaysParse(input);\n    if (typeof input === 'number') {\n        return input;\n    }\n\n    return null;\n}\n\nfunction parseIsoWeekday(input, locale) {\n    if (typeof input === 'string') {\n        return locale.weekdaysParse(input) % 7 || 7;\n    }\n    return isNaN(input) ? null : input;\n}\n\n// LOCALES\n\nvar defaultLocaleWeekdays = 'Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday'.split('_');\nfunction localeWeekdays (m, format) {\n    if (!m) {\n        return isArray(this._weekdays) ? this._weekdays :\n            this._weekdays['standalone'];\n    }\n    return isArray(this._weekdays) ? this._weekdays[m.day()] :\n        this._weekdays[this._weekdays.isFormat.test(format) ? 'format' : 'standalone'][m.day()];\n}\n\nvar defaultLocaleWeekdaysShort = 'Sun_Mon_Tue_Wed_Thu_Fri_Sat'.split('_');\nfunction localeWeekdaysShort (m) {\n    return (m) ? this._weekdaysShort[m.day()] : this._weekdaysShort;\n}\n\nvar defaultLocaleWeekdaysMin = 'Su_Mo_Tu_We_Th_Fr_Sa'.split('_');\nfunction localeWeekdaysMin (m) {\n    return (m) ? this._weekdaysMin[m.day()] : this._weekdaysMin;\n}\n\nfunction handleStrictParse$1(weekdayName, format, strict) {\n    var i, ii, mom, llc = weekdayName.toLocaleLowerCase();\n    if (!this._weekdaysParse) {\n        this._weekdaysParse = [];\n        this._shortWeekdaysParse = [];\n        this._minWeekdaysParse = [];\n\n        for (i = 0; i < 7; ++i) {\n            mom = createUTC([2000, 1]).day(i);\n            this._minWeekdaysParse[i] = this.weekdaysMin(mom, '').toLocaleLowerCase();\n            this._shortWeekdaysParse[i] = this.weekdaysShort(mom, '').toLocaleLowerCase();\n            this._weekdaysParse[i] = this.weekdays(mom, '').toLocaleLowerCase();\n        }\n    }\n\n    if (strict) {\n        if (format === 'dddd') {\n            ii = indexOf$1.call(this._weekdaysParse, llc);\n            return ii !== -1 ? ii : null;\n        } else if (format === 'ddd') {\n            ii = indexOf$1.call(this._shortWeekdaysParse, llc);\n            return ii !== -1 ? ii : null;\n        } else {\n            ii = indexOf$1.call(this._minWeekdaysParse, llc);\n            return ii !== -1 ? ii : null;\n        }\n    } else {\n        if (format === 'dddd') {\n            ii = indexOf$1.call(this._weekdaysParse, llc);\n            if (ii !== -1) {\n                return ii;\n            }\n            ii = indexOf$1.call(this._shortWeekdaysParse, llc);\n            if (ii !== -1) {\n                return ii;\n            }\n            ii = indexOf$1.call(this._minWeekdaysParse, llc);\n            return ii !== -1 ? ii : null;\n        } else if (format === 'ddd') {\n            ii = indexOf$1.call(this._shortWeekdaysParse, llc);\n            if (ii !== -1) {\n                return ii;\n            }\n            ii = indexOf$1.call(this._weekdaysParse, llc);\n            if (ii !== -1) {\n                return ii;\n            }\n            ii = indexOf$1.call(this._minWeekdaysParse, llc);\n            return ii !== -1 ? ii : null;\n        } else {\n            ii = indexOf$1.call(this._minWeekdaysParse, llc);\n            if (ii !== -1) {\n                return ii;\n            }\n            ii = indexOf$1.call(this._weekdaysParse, llc);\n            if (ii !== -1) {\n                return ii;\n            }\n            ii = indexOf$1.call(this._shortWeekdaysParse, llc);\n            return ii !== -1 ? ii : null;\n        }\n    }\n}\n\nfunction localeWeekdaysParse (weekdayName, format, strict) {\n    var i, mom, regex;\n\n    if (this._weekdaysParseExact) {\n        return handleStrictParse$1.call(this, weekdayName, format, strict);\n    }\n\n    if (!this._weekdaysParse) {\n        this._weekdaysParse = [];\n        this._minWeekdaysParse = [];\n        this._shortWeekdaysParse = [];\n        this._fullWeekdaysParse = [];\n    }\n\n    for (i = 0; i < 7; i++) {\n        // make the regex if we don't have it already\n\n        mom = createUTC([2000, 1]).day(i);\n        if (strict && !this._fullWeekdaysParse[i]) {\n            this._fullWeekdaysParse[i] = new RegExp('^' + this.weekdays(mom, '').replace('.', '\\.?') + '$', 'i');\n            this._shortWeekdaysParse[i] = new RegExp('^' + this.weekdaysShort(mom, '').replace('.', '\\.?') + '$', 'i');\n            this._minWeekdaysParse[i] = new RegExp('^' + this.weekdaysMin(mom, '').replace('.', '\\.?') + '$', 'i');\n        }\n        if (!this._weekdaysParse[i]) {\n            regex = '^' + this.weekdays(mom, '') + '|^' + this.weekdaysShort(mom, '') + '|^' + this.weekdaysMin(mom, '');\n            this._weekdaysParse[i] = new RegExp(regex.replace('.', ''), 'i');\n        }\n        // test the regex\n        if (strict && format === 'dddd' && this._fullWeekdaysParse[i].test(weekdayName)) {\n            return i;\n        } else if (strict && format === 'ddd' && this._shortWeekdaysParse[i].test(weekdayName)) {\n            return i;\n        } else if (strict && format === 'dd' && this._minWeekdaysParse[i].test(weekdayName)) {\n            return i;\n        } else if (!strict && this._weekdaysParse[i].test(weekdayName)) {\n            return i;\n        }\n    }\n}\n\n// MOMENTS\n\nfunction getSetDayOfWeek (input) {\n    if (!this.isValid()) {\n        return input != null ? this : NaN;\n    }\n    var day = this._isUTC ? this._d.getUTCDay() : this._d.getDay();\n    if (input != null) {\n        input = parseWeekday(input, this.localeData());\n        return this.add(input - day, 'd');\n    } else {\n        return day;\n    }\n}\n\nfunction getSetLocaleDayOfWeek (input) {\n    if (!this.isValid()) {\n        return input != null ? this : NaN;\n    }\n    var weekday = (this.day() + 7 - this.localeData()._week.dow) % 7;\n    return input == null ? weekday : this.add(input - weekday, 'd');\n}\n\nfunction getSetISODayOfWeek (input) {\n    if (!this.isValid()) {\n        return input != null ? this : NaN;\n    }\n\n    // behaves the same as moment#day except\n    // as a getter, returns 7 instead of 0 (1-7 range instead of 0-6)\n    // as a setter, sunday should belong to the previous week.\n\n    if (input != null) {\n        var weekday = parseIsoWeekday(input, this.localeData());\n        return this.day(this.day() % 7 ? weekday : weekday - 7);\n    } else {\n        return this.day() || 7;\n    }\n}\n\nvar defaultWeekdaysRegex = matchWord;\nfunction weekdaysRegex (isStrict) {\n    if (this._weekdaysParseExact) {\n        if (!hasOwnProp(this, '_weekdaysRegex')) {\n            computeWeekdaysParse.call(this);\n        }\n        if (isStrict) {\n            return this._weekdaysStrictRegex;\n        } else {\n            return this._weekdaysRegex;\n        }\n    } else {\n        if (!hasOwnProp(this, '_weekdaysRegex')) {\n            this._weekdaysRegex = defaultWeekdaysRegex;\n        }\n        return this._weekdaysStrictRegex && isStrict ?\n            this._weekdaysStrictRegex : this._weekdaysRegex;\n    }\n}\n\nvar defaultWeekdaysShortRegex = matchWord;\nfunction weekdaysShortRegex (isStrict) {\n    if (this._weekdaysParseExact) {\n        if (!hasOwnProp(this, '_weekdaysRegex')) {\n            computeWeekdaysParse.call(this);\n        }\n        if (isStrict) {\n            return this._weekdaysShortStrictRegex;\n        } else {\n            return this._weekdaysShortRegex;\n        }\n    } else {\n        if (!hasOwnProp(this, '_weekdaysShortRegex')) {\n            this._weekdaysShortRegex = defaultWeekdaysShortRegex;\n        }\n        return this._weekdaysShortStrictRegex && isStrict ?\n            this._weekdaysShortStrictRegex : this._weekdaysShortRegex;\n    }\n}\n\nvar defaultWeekdaysMinRegex = matchWord;\nfunction weekdaysMinRegex (isStrict) {\n    if (this._weekdaysParseExact) {\n        if (!hasOwnProp(this, '_weekdaysRegex')) {\n            computeWeekdaysParse.call(this);\n        }\n        if (isStrict) {\n            return this._weekdaysMinStrictRegex;\n        } else {\n            return this._weekdaysMinRegex;\n        }\n    } else {\n        if (!hasOwnProp(this, '_weekdaysMinRegex')) {\n            this._weekdaysMinRegex = defaultWeekdaysMinRegex;\n        }\n        return this._weekdaysMinStrictRegex && isStrict ?\n            this._weekdaysMinStrictRegex : this._weekdaysMinRegex;\n    }\n}\n\n\nfunction computeWeekdaysParse () {\n    function cmpLenRev(a, b) {\n        return b.length - a.length;\n    }\n\n    var minPieces = [], shortPieces = [], longPieces = [], mixedPieces = [],\n        i, mom, minp, shortp, longp;\n    for (i = 0; i < 7; i++) {\n        // make the regex if we don't have it already\n        mom = createUTC([2000, 1]).day(i);\n        minp = this.weekdaysMin(mom, '');\n        shortp = this.weekdaysShort(mom, '');\n        longp = this.weekdays(mom, '');\n        minPieces.push(minp);\n        shortPieces.push(shortp);\n        longPieces.push(longp);\n        mixedPieces.push(minp);\n        mixedPieces.push(shortp);\n        mixedPieces.push(longp);\n    }\n    // Sorting makes sure if one weekday (or abbr) is a prefix of another it\n    // will match the longer piece.\n    minPieces.sort(cmpLenRev);\n    shortPieces.sort(cmpLenRev);\n    longPieces.sort(cmpLenRev);\n    mixedPieces.sort(cmpLenRev);\n    for (i = 0; i < 7; i++) {\n        shortPieces[i] = regexEscape(shortPieces[i]);\n        longPieces[i] = regexEscape(longPieces[i]);\n        mixedPieces[i] = regexEscape(mixedPieces[i]);\n    }\n\n    this._weekdaysRegex = new RegExp('^(' + mixedPieces.join('|') + ')', 'i');\n    this._weekdaysShortRegex = this._weekdaysRegex;\n    this._weekdaysMinRegex = this._weekdaysRegex;\n\n    this._weekdaysStrictRegex = new RegExp('^(' + longPieces.join('|') + ')', 'i');\n    this._weekdaysShortStrictRegex = new RegExp('^(' + shortPieces.join('|') + ')', 'i');\n    this._weekdaysMinStrictRegex = new RegExp('^(' + minPieces.join('|') + ')', 'i');\n}\n\n// FORMATTING\n\nfunction hFormat() {\n    return this.hours() % 12 || 12;\n}\n\nfunction kFormat() {\n    return this.hours() || 24;\n}\n\naddFormatToken('H', ['HH', 2], 0, 'hour');\naddFormatToken('h', ['hh', 2], 0, hFormat);\naddFormatToken('k', ['kk', 2], 0, kFormat);\n\naddFormatToken('hmm', 0, 0, function () {\n    return '' + hFormat.apply(this) + zeroFill(this.minutes(), 2);\n});\n\naddFormatToken('hmmss', 0, 0, function () {\n    return '' + hFormat.apply(this) + zeroFill(this.minutes(), 2) +\n        zeroFill(this.seconds(), 2);\n});\n\naddFormatToken('Hmm', 0, 0, function () {\n    return '' + this.hours() + zeroFill(this.minutes(), 2);\n});\n\naddFormatToken('Hmmss', 0, 0, function () {\n    return '' + this.hours() + zeroFill(this.minutes(), 2) +\n        zeroFill(this.seconds(), 2);\n});\n\nfunction meridiem (token, lowercase) {\n    addFormatToken(token, 0, 0, function () {\n        return this.localeData().meridiem(this.hours(), this.minutes(), lowercase);\n    });\n}\n\nmeridiem('a', true);\nmeridiem('A', false);\n\n// ALIASES\n\naddUnitAlias('hour', 'h');\n\n// PRIORITY\naddUnitPriority('hour', 13);\n\n// PARSING\n\nfunction matchMeridiem (isStrict, locale) {\n    return locale._meridiemParse;\n}\n\naddRegexToken('a',  matchMeridiem);\naddRegexToken('A',  matchMeridiem);\naddRegexToken('H',  match1to2);\naddRegexToken('h',  match1to2);\naddRegexToken('k',  match1to2);\naddRegexToken('HH', match1to2, match2);\naddRegexToken('hh', match1to2, match2);\naddRegexToken('kk', match1to2, match2);\n\naddRegexToken('hmm', match3to4);\naddRegexToken('hmmss', match5to6);\naddRegexToken('Hmm', match3to4);\naddRegexToken('Hmmss', match5to6);\n\naddParseToken(['H', 'HH'], HOUR);\naddParseToken(['k', 'kk'], function (input, array, config) {\n    var kInput = toInt(input);\n    array[HOUR] = kInput === 24 ? 0 : kInput;\n});\naddParseToken(['a', 'A'], function (input, array, config) {\n    config._isPm = config._locale.isPM(input);\n    config._meridiem = input;\n});\naddParseToken(['h', 'hh'], function (input, array, config) {\n    array[HOUR] = toInt(input);\n    getParsingFlags(config).bigHour = true;\n});\naddParseToken('hmm', function (input, array, config) {\n    var pos = input.length - 2;\n    array[HOUR] = toInt(input.substr(0, pos));\n    array[MINUTE] = toInt(input.substr(pos));\n    getParsingFlags(config).bigHour = true;\n});\naddParseToken('hmmss', function (input, array, config) {\n    var pos1 = input.length - 4;\n    var pos2 = input.length - 2;\n    array[HOUR] = toInt(input.substr(0, pos1));\n    array[MINUTE] = toInt(input.substr(pos1, 2));\n    array[SECOND] = toInt(input.substr(pos2));\n    getParsingFlags(config).bigHour = true;\n});\naddParseToken('Hmm', function (input, array, config) {\n    var pos = input.length - 2;\n    array[HOUR] = toInt(input.substr(0, pos));\n    array[MINUTE] = toInt(input.substr(pos));\n});\naddParseToken('Hmmss', function (input, array, config) {\n    var pos1 = input.length - 4;\n    var pos2 = input.length - 2;\n    array[HOUR] = toInt(input.substr(0, pos1));\n    array[MINUTE] = toInt(input.substr(pos1, 2));\n    array[SECOND] = toInt(input.substr(pos2));\n});\n\n// LOCALES\n\nfunction localeIsPM (input) {\n    // IE8 Quirks Mode & IE7 Standards Mode do not allow accessing strings like arrays\n    // Using charAt should be more compatible.\n    return ((input + '').toLowerCase().charAt(0) === 'p');\n}\n\nvar defaultLocaleMeridiemParse = /[ap]\\.?m?\\.?/i;\nfunction localeMeridiem (hours, minutes, isLower) {\n    if (hours > 11) {\n        return isLower ? 'pm' : 'PM';\n    } else {\n        return isLower ? 'am' : 'AM';\n    }\n}\n\n\n// MOMENTS\n\n// Setting the hour should keep the time, because the user explicitly\n// specified which hour he wants. So trying to maintain the same hour (in\n// a new timezone) makes sense. Adding/subtracting hours does not follow\n// this rule.\nvar getSetHour = makeGetSet('Hours', true);\n\n// months\n// week\n// weekdays\n// meridiem\nvar baseConfig = {\n    calendar: defaultCalendar,\n    longDateFormat: defaultLongDateFormat,\n    invalidDate: defaultInvalidDate,\n    ordinal: defaultOrdinal,\n    dayOfMonthOrdinalParse: defaultDayOfMonthOrdinalParse,\n    relativeTime: defaultRelativeTime,\n\n    months: defaultLocaleMonths,\n    monthsShort: defaultLocaleMonthsShort,\n\n    week: defaultLocaleWeek,\n\n    weekdays: defaultLocaleWeekdays,\n    weekdaysMin: defaultLocaleWeekdaysMin,\n    weekdaysShort: defaultLocaleWeekdaysShort,\n\n    meridiemParse: defaultLocaleMeridiemParse\n};\n\n// internal storage for locale config files\nvar locales = {};\nvar localeFamilies = {};\nvar globalLocale;\n\nfunction normalizeLocale(key) {\n    return key ? key.toLowerCase().replace('_', '-') : key;\n}\n\n// pick the locale from the array\n// try ['en-au', 'en-gb'] as 'en-au', 'en-gb', 'en', as in move through the list trying each\n// substring from most specific to least, but move to the next array item if it's a more specific variant than the current root\nfunction chooseLocale(names) {\n    var i = 0, j, next, locale, split;\n\n    while (i < names.length) {\n        split = normalizeLocale(names[i]).split('-');\n        j = split.length;\n        next = normalizeLocale(names[i + 1]);\n        next = next ? next.split('-') : null;\n        while (j > 0) {\n            locale = loadLocale(split.slice(0, j).join('-'));\n            if (locale) {\n                return locale;\n            }\n            if (next && next.length >= j && compareArrays(split, next, true) >= j - 1) {\n                //the next array item is better than a shallower substring of this one\n                break;\n            }\n            j--;\n        }\n        i++;\n    }\n    return null;\n}\n\nfunction loadLocale(name) {\n    var oldLocale = null;\n    // TODO: Find a better way to register and load all the locales in Node\n    if (!locales[name] && (typeof module !== 'undefined') &&\n            module && module.exports) {\n        try {\n            oldLocale = globalLocale._abbr;\n            require('./locale/' + name);\n            // because defineLocale currently also sets the global locale, we\n            // want to undo that for lazy loaded locales\n            getSetGlobalLocale(oldLocale);\n        } catch (e) { }\n    }\n    return locales[name];\n}\n\n// This function will load locale and then set the global locale.  If\n// no arguments are passed in, it will simply return the current global\n// locale key.\nfunction getSetGlobalLocale (key, values) {\n    var data;\n    if (key) {\n        if (isUndefined(values)) {\n            data = getLocale(key);\n        }\n        else {\n            data = defineLocale(key, values);\n        }\n\n        if (data) {\n            // moment.duration._locale = moment._locale = data;\n            globalLocale = data;\n        }\n    }\n\n    return globalLocale._abbr;\n}\n\nfunction defineLocale (name, config) {\n    if (config !== null) {\n        var parentConfig = baseConfig;\n        config.abbr = name;\n        if (locales[name] != null) {\n            deprecateSimple('defineLocaleOverride',\n                    'use moment.updateLocale(localeName, config) to change ' +\n                    'an existing locale. moment.defineLocale(localeName, ' +\n                    'config) should only be used for creating a new locale ' +\n                    'See http://momentjs.com/guides/#/warnings/define-locale/ for more info.');\n            parentConfig = locales[name]._config;\n        } else if (config.parentLocale != null) {\n            if (locales[config.parentLocale] != null) {\n                parentConfig = locales[config.parentLocale]._config;\n            } else {\n                if (!localeFamilies[config.parentLocale]) {\n                    localeFamilies[config.parentLocale] = [];\n                }\n                localeFamilies[config.parentLocale].push({\n                    name: name,\n                    config: config\n                });\n                return null;\n            }\n        }\n        locales[name] = new Locale(mergeConfigs(parentConfig, config));\n\n        if (localeFamilies[name]) {\n            localeFamilies[name].forEach(function (x) {\n                defineLocale(x.name, x.config);\n            });\n        }\n\n        // backwards compat for now: also set the locale\n        // make sure we set the locale AFTER all child locales have been\n        // created, so we won't end up with the child locale set.\n        getSetGlobalLocale(name);\n\n\n        return locales[name];\n    } else {\n        // useful for testing\n        delete locales[name];\n        return null;\n    }\n}\n\nfunction updateLocale(name, config) {\n    if (config != null) {\n        var locale, parentConfig = baseConfig;\n        // MERGE\n        if (locales[name] != null) {\n            parentConfig = locales[name]._config;\n        }\n        config = mergeConfigs(parentConfig, config);\n        locale = new Locale(config);\n        locale.parentLocale = locales[name];\n        locales[name] = locale;\n\n        // backwards compat for now: also set the locale\n        getSetGlobalLocale(name);\n    } else {\n        // pass null for config to unupdate, useful for tests\n        if (locales[name] != null) {\n            if (locales[name].parentLocale != null) {\n                locales[name] = locales[name].parentLocale;\n            } else if (locales[name] != null) {\n                delete locales[name];\n            }\n        }\n    }\n    return locales[name];\n}\n\n// returns locale data\nfunction getLocale (key) {\n    var locale;\n\n    if (key && key._locale && key._locale._abbr) {\n        key = key._locale._abbr;\n    }\n\n    if (!key) {\n        return globalLocale;\n    }\n\n    if (!isArray(key)) {\n        //short-circuit everything else\n        locale = loadLocale(key);\n        if (locale) {\n            return locale;\n        }\n        key = [key];\n    }\n\n    return chooseLocale(key);\n}\n\nfunction listLocales() {\n    return keys$1(locales);\n}\n\nfunction checkOverflow (m) {\n    var overflow;\n    var a = m._a;\n\n    if (a && getParsingFlags(m).overflow === -2) {\n        overflow =\n            a[MONTH]       < 0 || a[MONTH]       > 11  ? MONTH :\n            a[DATE]        < 1 || a[DATE]        > daysInMonth(a[YEAR], a[MONTH]) ? DATE :\n            a[HOUR]        < 0 || a[HOUR]        > 24 || (a[HOUR] === 24 && (a[MINUTE] !== 0 || a[SECOND] !== 0 || a[MILLISECOND] !== 0)) ? HOUR :\n            a[MINUTE]      < 0 || a[MINUTE]      > 59  ? MINUTE :\n            a[SECOND]      < 0 || a[SECOND]      > 59  ? SECOND :\n            a[MILLISECOND] < 0 || a[MILLISECOND] > 999 ? MILLISECOND :\n            -1;\n\n        if (getParsingFlags(m)._overflowDayOfYear && (overflow < YEAR || overflow > DATE)) {\n            overflow = DATE;\n        }\n        if (getParsingFlags(m)._overflowWeeks && overflow === -1) {\n            overflow = WEEK;\n        }\n        if (getParsingFlags(m)._overflowWeekday && overflow === -1) {\n            overflow = WEEKDAY;\n        }\n\n        getParsingFlags(m).overflow = overflow;\n    }\n\n    return m;\n}\n\n// iso 8601 regex\n// 0000-00-00 0000-W00 or 0000-W00-0 + T + 00 or 00:00 or 00:00:00 or 00:00:00.000 + +00:00 or +0000 or +00)\nvar extendedIsoRegex = /^\\s*((?:[+-]\\d{6}|\\d{4})-(?:\\d\\d-\\d\\d|W\\d\\d-\\d|W\\d\\d|\\d\\d\\d|\\d\\d))(?:(T| )(\\d\\d(?::\\d\\d(?::\\d\\d(?:[.,]\\d+)?)?)?)([\\+\\-]\\d\\d(?::?\\d\\d)?|\\s*Z)?)?$/;\nvar basicIsoRegex = /^\\s*((?:[+-]\\d{6}|\\d{4})(?:\\d\\d\\d\\d|W\\d\\d\\d|W\\d\\d|\\d\\d\\d|\\d\\d))(?:(T| )(\\d\\d(?:\\d\\d(?:\\d\\d(?:[.,]\\d+)?)?)?)([\\+\\-]\\d\\d(?::?\\d\\d)?|\\s*Z)?)?$/;\n\nvar tzRegex = /Z|[+-]\\d\\d(?::?\\d\\d)?/;\n\nvar isoDates = [\n    ['YYYYYY-MM-DD', /[+-]\\d{6}-\\d\\d-\\d\\d/],\n    ['YYYY-MM-DD', /\\d{4}-\\d\\d-\\d\\d/],\n    ['GGGG-[W]WW-E', /\\d{4}-W\\d\\d-\\d/],\n    ['GGGG-[W]WW', /\\d{4}-W\\d\\d/, false],\n    ['YYYY-DDD', /\\d{4}-\\d{3}/],\n    ['YYYY-MM', /\\d{4}-\\d\\d/, false],\n    ['YYYYYYMMDD', /[+-]\\d{10}/],\n    ['YYYYMMDD', /\\d{8}/],\n    // YYYYMM is NOT allowed by the standard\n    ['GGGG[W]WWE', /\\d{4}W\\d{3}/],\n    ['GGGG[W]WW', /\\d{4}W\\d{2}/, false],\n    ['YYYYDDD', /\\d{7}/]\n];\n\n// iso time formats and regexes\nvar isoTimes = [\n    ['HH:mm:ss.SSSS', /\\d\\d:\\d\\d:\\d\\d\\.\\d+/],\n    ['HH:mm:ss,SSSS', /\\d\\d:\\d\\d:\\d\\d,\\d+/],\n    ['HH:mm:ss', /\\d\\d:\\d\\d:\\d\\d/],\n    ['HH:mm', /\\d\\d:\\d\\d/],\n    ['HHmmss.SSSS', /\\d\\d\\d\\d\\d\\d\\.\\d+/],\n    ['HHmmss,SSSS', /\\d\\d\\d\\d\\d\\d,\\d+/],\n    ['HHmmss', /\\d\\d\\d\\d\\d\\d/],\n    ['HHmm', /\\d\\d\\d\\d/],\n    ['HH', /\\d\\d/]\n];\n\nvar aspNetJsonRegex = /^\\/?Date\\((\\-?\\d+)/i;\n\n// date from iso format\nfunction configFromISO(config) {\n    var i, l,\n        string = config._i,\n        match = extendedIsoRegex.exec(string) || basicIsoRegex.exec(string),\n        allowTime, dateFormat, timeFormat, tzFormat;\n\n    if (match) {\n        getParsingFlags(config).iso = true;\n\n        for (i = 0, l = isoDates.length; i < l; i++) {\n            if (isoDates[i][1].exec(match[1])) {\n                dateFormat = isoDates[i][0];\n                allowTime = isoDates[i][2] !== false;\n                break;\n            }\n        }\n        if (dateFormat == null) {\n            config._isValid = false;\n            return;\n        }\n        if (match[3]) {\n            for (i = 0, l = isoTimes.length; i < l; i++) {\n                if (isoTimes[i][1].exec(match[3])) {\n                    // match[2] should be 'T' or space\n                    timeFormat = (match[2] || ' ') + isoTimes[i][0];\n                    break;\n                }\n            }\n            if (timeFormat == null) {\n                config._isValid = false;\n                return;\n            }\n        }\n        if (!allowTime && timeFormat != null) {\n            config._isValid = false;\n            return;\n        }\n        if (match[4]) {\n            if (tzRegex.exec(match[4])) {\n                tzFormat = 'Z';\n            } else {\n                config._isValid = false;\n                return;\n            }\n        }\n        config._f = dateFormat + (timeFormat || '') + (tzFormat || '');\n        configFromStringAndFormat(config);\n    } else {\n        config._isValid = false;\n    }\n}\n\n// RFC 2822 regex: For details see https://tools.ietf.org/html/rfc2822#section-3.3\nvar basicRfcRegex = /^((?:Mon|Tue|Wed|Thu|Fri|Sat|Sun),?\\s)?(\\d?\\d\\s(?:Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)\\s(?:\\d\\d)?\\d\\d\\s)(\\d\\d:\\d\\d)(\\:\\d\\d)?(\\s(?:UT|GMT|[ECMP][SD]T|[A-IK-Za-ik-z]|[+-]\\d{4}))$/;\n\n// date and time from ref 2822 format\nfunction configFromRFC2822(config) {\n    var string, match, dayFormat,\n        dateFormat, timeFormat, tzFormat;\n    var timezones = {\n        ' GMT': ' +0000',\n        ' EDT': ' -0400',\n        ' EST': ' -0500',\n        ' CDT': ' -0500',\n        ' CST': ' -0600',\n        ' MDT': ' -0600',\n        ' MST': ' -0700',\n        ' PDT': ' -0700',\n        ' PST': ' -0800'\n    };\n    var military = 'YXWVUTSRQPONZABCDEFGHIKLM';\n    var timezone, timezoneIndex;\n\n    string = config._i\n        .replace(/\\([^\\)]*\\)|[\\n\\t]/g, ' ') // Remove comments and folding whitespace\n        .replace(/(\\s\\s+)/g, ' ') // Replace multiple-spaces with a single space\n        .replace(/^\\s|\\s$/g, ''); // Remove leading and trailing spaces\n    match = basicRfcRegex.exec(string);\n\n    if (match) {\n        dayFormat = match[1] ? 'ddd' + ((match[1].length === 5) ? ', ' : ' ') : '';\n        dateFormat = 'D MMM ' + ((match[2].length > 10) ? 'YYYY ' : 'YY ');\n        timeFormat = 'HH:mm' + (match[4] ? ':ss' : '');\n\n        // TODO: Replace the vanilla JS Date object with an indepentent day-of-week check.\n        if (match[1]) { // day of week given\n            var momentDate = new Date(match[2]);\n            var momentDay = ['Sun','Mon','Tue','Wed','Thu','Fri','Sat'][momentDate.getDay()];\n\n            if (match[1].substr(0,3) !== momentDay) {\n                getParsingFlags(config).weekdayMismatch = true;\n                config._isValid = false;\n                return;\n            }\n        }\n\n        switch (match[5].length) {\n            case 2: // military\n                if (timezoneIndex === 0) {\n                    timezone = ' +0000';\n                } else {\n                    timezoneIndex = military.indexOf(match[5][1].toUpperCase()) - 12;\n                    timezone = ((timezoneIndex < 0) ? ' -' : ' +') +\n                        (('' + timezoneIndex).replace(/^-?/, '0')).match(/..$/)[0] + '00';\n                }\n                break;\n            case 4: // Zone\n                timezone = timezones[match[5]];\n                break;\n            default: // UT or +/-9999\n                timezone = timezones[' GMT'];\n        }\n        match[5] = timezone;\n        config._i = match.splice(1).join('');\n        tzFormat = ' ZZ';\n        config._f = dayFormat + dateFormat + timeFormat + tzFormat;\n        configFromStringAndFormat(config);\n        getParsingFlags(config).rfc2822 = true;\n    } else {\n        config._isValid = false;\n    }\n}\n\n// date from iso format or fallback\nfunction configFromString(config) {\n    var matched = aspNetJsonRegex.exec(config._i);\n\n    if (matched !== null) {\n        config._d = new Date(+matched[1]);\n        return;\n    }\n\n    configFromISO(config);\n    if (config._isValid === false) {\n        delete config._isValid;\n    } else {\n        return;\n    }\n\n    configFromRFC2822(config);\n    if (config._isValid === false) {\n        delete config._isValid;\n    } else {\n        return;\n    }\n\n    // Final attempt, use Input Fallback\n    hooks.createFromInputFallback(config);\n}\n\nhooks.createFromInputFallback = deprecate(\n    'value provided is not in a recognized RFC2822 or ISO format. moment construction falls back to js Date(), ' +\n    'which is not reliable across all browsers and versions. Non RFC2822/ISO date formats are ' +\n    'discouraged and will be removed in an upcoming major release. Please refer to ' +\n    'http://momentjs.com/guides/#/warnings/js-date/ for more info.',\n    function (config) {\n        config._d = new Date(config._i + (config._useUTC ? ' UTC' : ''));\n    }\n);\n\n// Pick the first defined of two or three arguments.\nfunction defaults(a, b, c) {\n    if (a != null) {\n        return a;\n    }\n    if (b != null) {\n        return b;\n    }\n    return c;\n}\n\nfunction currentDateArray(config) {\n    // hooks is actually the exported moment object\n    var nowValue = new Date(hooks.now());\n    if (config._useUTC) {\n        return [nowValue.getUTCFullYear(), nowValue.getUTCMonth(), nowValue.getUTCDate()];\n    }\n    return [nowValue.getFullYear(), nowValue.getMonth(), nowValue.getDate()];\n}\n\n// convert an array to a date.\n// the array should mirror the parameters below\n// note: all values past the year are optional and will default to the lowest possible value.\n// [year, month, day , hour, minute, second, millisecond]\nfunction configFromArray (config) {\n    var i, date, input = [], currentDate, yearToUse;\n\n    if (config._d) {\n        return;\n    }\n\n    currentDate = currentDateArray(config);\n\n    //compute day of the year from weeks and weekdays\n    if (config._w && config._a[DATE] == null && config._a[MONTH] == null) {\n        dayOfYearFromWeekInfo(config);\n    }\n\n    //if the day of the year is set, figure out what it is\n    if (config._dayOfYear != null) {\n        yearToUse = defaults(config._a[YEAR], currentDate[YEAR]);\n\n        if (config._dayOfYear > daysInYear(yearToUse) || config._dayOfYear === 0) {\n            getParsingFlags(config)._overflowDayOfYear = true;\n        }\n\n        date = createUTCDate(yearToUse, 0, config._dayOfYear);\n        config._a[MONTH] = date.getUTCMonth();\n        config._a[DATE] = date.getUTCDate();\n    }\n\n    // Default to current date.\n    // * if no year, month, day of month are given, default to today\n    // * if day of month is given, default month and year\n    // * if month is given, default only year\n    // * if year is given, don't default anything\n    for (i = 0; i < 3 && config._a[i] == null; ++i) {\n        config._a[i] = input[i] = currentDate[i];\n    }\n\n    // Zero out whatever was not defaulted, including time\n    for (; i < 7; i++) {\n        config._a[i] = input[i] = (config._a[i] == null) ? (i === 2 ? 1 : 0) : config._a[i];\n    }\n\n    // Check for 24:00:00.000\n    if (config._a[HOUR] === 24 &&\n            config._a[MINUTE] === 0 &&\n            config._a[SECOND] === 0 &&\n            config._a[MILLISECOND] === 0) {\n        config._nextDay = true;\n        config._a[HOUR] = 0;\n    }\n\n    config._d = (config._useUTC ? createUTCDate : createDate).apply(null, input);\n    // Apply timezone offset from input. The actual utcOffset can be changed\n    // with parseZone.\n    if (config._tzm != null) {\n        config._d.setUTCMinutes(config._d.getUTCMinutes() - config._tzm);\n    }\n\n    if (config._nextDay) {\n        config._a[HOUR] = 24;\n    }\n}\n\nfunction dayOfYearFromWeekInfo(config) {\n    var w, weekYear, week, weekday, dow, doy, temp, weekdayOverflow;\n\n    w = config._w;\n    if (w.GG != null || w.W != null || w.E != null) {\n        dow = 1;\n        doy = 4;\n\n        // TODO: We need to take the current isoWeekYear, but that depends on\n        // how we interpret now (local, utc, fixed offset). So create\n        // a now version of current config (take local/utc/offset flags, and\n        // create now).\n        weekYear = defaults(w.GG, config._a[YEAR], weekOfYear(createLocal(), 1, 4).year);\n        week = defaults(w.W, 1);\n        weekday = defaults(w.E, 1);\n        if (weekday < 1 || weekday > 7) {\n            weekdayOverflow = true;\n        }\n    } else {\n        dow = config._locale._week.dow;\n        doy = config._locale._week.doy;\n\n        var curWeek = weekOfYear(createLocal(), dow, doy);\n\n        weekYear = defaults(w.gg, config._a[YEAR], curWeek.year);\n\n        // Default to current week.\n        week = defaults(w.w, curWeek.week);\n\n        if (w.d != null) {\n            // weekday -- low day numbers are considered next week\n            weekday = w.d;\n            if (weekday < 0 || weekday > 6) {\n                weekdayOverflow = true;\n            }\n        } else if (w.e != null) {\n            // local weekday -- counting starts from begining of week\n            weekday = w.e + dow;\n            if (w.e < 0 || w.e > 6) {\n                weekdayOverflow = true;\n            }\n        } else {\n            // default to begining of week\n            weekday = dow;\n        }\n    }\n    if (week < 1 || week > weeksInYear(weekYear, dow, doy)) {\n        getParsingFlags(config)._overflowWeeks = true;\n    } else if (weekdayOverflow != null) {\n        getParsingFlags(config)._overflowWeekday = true;\n    } else {\n        temp = dayOfYearFromWeeks(weekYear, week, weekday, dow, doy);\n        config._a[YEAR] = temp.year;\n        config._dayOfYear = temp.dayOfYear;\n    }\n}\n\n// constant that refers to the ISO standard\nhooks.ISO_8601 = function () {};\n\n// constant that refers to the RFC 2822 form\nhooks.RFC_2822 = function () {};\n\n// date from string and format string\nfunction configFromStringAndFormat(config) {\n    // TODO: Move this to another part of the creation flow to prevent circular deps\n    if (config._f === hooks.ISO_8601) {\n        configFromISO(config);\n        return;\n    }\n    if (config._f === hooks.RFC_2822) {\n        configFromRFC2822(config);\n        return;\n    }\n    config._a = [];\n    getParsingFlags(config).empty = true;\n\n    // This array is used to make a Date, either with `new Date` or `Date.UTC`\n    var string = '' + config._i,\n        i, parsedInput, tokens, token, skipped,\n        stringLength = string.length,\n        totalParsedInputLength = 0;\n\n    tokens = expandFormat(config._f, config._locale).match(formattingTokens) || [];\n\n    for (i = 0; i < tokens.length; i++) {\n        token = tokens[i];\n        parsedInput = (string.match(getParseRegexForToken(token, config)) || [])[0];\n        // console.log('token', token, 'parsedInput', parsedInput,\n        //         'regex', getParseRegexForToken(token, config));\n        if (parsedInput) {\n            skipped = string.substr(0, string.indexOf(parsedInput));\n            if (skipped.length > 0) {\n                getParsingFlags(config).unusedInput.push(skipped);\n            }\n            string = string.slice(string.indexOf(parsedInput) + parsedInput.length);\n            totalParsedInputLength += parsedInput.length;\n        }\n        // don't parse if it's not a known token\n        if (formatTokenFunctions[token]) {\n            if (parsedInput) {\n                getParsingFlags(config).empty = false;\n            }\n            else {\n                getParsingFlags(config).unusedTokens.push(token);\n            }\n            addTimeToArrayFromToken(token, parsedInput, config);\n        }\n        else if (config._strict && !parsedInput) {\n            getParsingFlags(config).unusedTokens.push(token);\n        }\n    }\n\n    // add remaining unparsed input length to the string\n    getParsingFlags(config).charsLeftOver = stringLength - totalParsedInputLength;\n    if (string.length > 0) {\n        getParsingFlags(config).unusedInput.push(string);\n    }\n\n    // clear _12h flag if hour is <= 12\n    if (config._a[HOUR] <= 12 &&\n        getParsingFlags(config).bigHour === true &&\n        config._a[HOUR] > 0) {\n        getParsingFlags(config).bigHour = undefined;\n    }\n\n    getParsingFlags(config).parsedDateParts = config._a.slice(0);\n    getParsingFlags(config).meridiem = config._meridiem;\n    // handle meridiem\n    config._a[HOUR] = meridiemFixWrap(config._locale, config._a[HOUR], config._meridiem);\n\n    configFromArray(config);\n    checkOverflow(config);\n}\n\n\nfunction meridiemFixWrap (locale, hour, meridiem) {\n    var isPm;\n\n    if (meridiem == null) {\n        // nothing to do\n        return hour;\n    }\n    if (locale.meridiemHour != null) {\n        return locale.meridiemHour(hour, meridiem);\n    } else if (locale.isPM != null) {\n        // Fallback\n        isPm = locale.isPM(meridiem);\n        if (isPm && hour < 12) {\n            hour += 12;\n        }\n        if (!isPm && hour === 12) {\n            hour = 0;\n        }\n        return hour;\n    } else {\n        // this is not supposed to happen\n        return hour;\n    }\n}\n\n// date from string and array of format strings\nfunction configFromStringAndArray(config) {\n    var tempConfig,\n        bestMoment,\n\n        scoreToBeat,\n        i,\n        currentScore;\n\n    if (config._f.length === 0) {\n        getParsingFlags(config).invalidFormat = true;\n        config._d = new Date(NaN);\n        return;\n    }\n\n    for (i = 0; i < config._f.length; i++) {\n        currentScore = 0;\n        tempConfig = copyConfig({}, config);\n        if (config._useUTC != null) {\n            tempConfig._useUTC = config._useUTC;\n        }\n        tempConfig._f = config._f[i];\n        configFromStringAndFormat(tempConfig);\n\n        if (!isValid(tempConfig)) {\n            continue;\n        }\n\n        // if there is any input that was not parsed add a penalty for that format\n        currentScore += getParsingFlags(tempConfig).charsLeftOver;\n\n        //or tokens\n        currentScore += getParsingFlags(tempConfig).unusedTokens.length * 10;\n\n        getParsingFlags(tempConfig).score = currentScore;\n\n        if (scoreToBeat == null || currentScore < scoreToBeat) {\n            scoreToBeat = currentScore;\n            bestMoment = tempConfig;\n        }\n    }\n\n    extend(config, bestMoment || tempConfig);\n}\n\nfunction configFromObject(config) {\n    if (config._d) {\n        return;\n    }\n\n    var i = normalizeObjectUnits(config._i);\n    config._a = map([i.year, i.month, i.day || i.date, i.hour, i.minute, i.second, i.millisecond], function (obj) {\n        return obj && parseInt(obj, 10);\n    });\n\n    configFromArray(config);\n}\n\nfunction createFromConfig (config) {\n    var res = new Moment(checkOverflow(prepareConfig(config)));\n    if (res._nextDay) {\n        // Adding is smart enough around DST\n        res.add(1, 'd');\n        res._nextDay = undefined;\n    }\n\n    return res;\n}\n\nfunction prepareConfig (config) {\n    var input = config._i,\n        format = config._f;\n\n    config._locale = config._locale || getLocale(config._l);\n\n    if (input === null || (format === undefined && input === '')) {\n        return createInvalid({nullInput: true});\n    }\n\n    if (typeof input === 'string') {\n        config._i = input = config._locale.preparse(input);\n    }\n\n    if (isMoment(input)) {\n        return new Moment(checkOverflow(input));\n    } else if (isDate(input)) {\n        config._d = input;\n    } else if (isArray(format)) {\n        configFromStringAndArray(config);\n    } else if (format) {\n        configFromStringAndFormat(config);\n    }  else {\n        configFromInput(config);\n    }\n\n    if (!isValid(config)) {\n        config._d = null;\n    }\n\n    return config;\n}\n\nfunction configFromInput(config) {\n    var input = config._i;\n    if (isUndefined(input)) {\n        config._d = new Date(hooks.now());\n    } else if (isDate(input)) {\n        config._d = new Date(input.valueOf());\n    } else if (typeof input === 'string') {\n        configFromString(config);\n    } else if (isArray(input)) {\n        config._a = map(input.slice(0), function (obj) {\n            return parseInt(obj, 10);\n        });\n        configFromArray(config);\n    } else if (isObject(input)) {\n        configFromObject(config);\n    } else if (isNumber(input)) {\n        // from milliseconds\n        config._d = new Date(input);\n    } else {\n        hooks.createFromInputFallback(config);\n    }\n}\n\nfunction createLocalOrUTC (input, format, locale, strict, isUTC) {\n    var c = {};\n\n    if (locale === true || locale === false) {\n        strict = locale;\n        locale = undefined;\n    }\n\n    if ((isObject(input) && isObjectEmpty(input)) ||\n            (isArray(input) && input.length === 0)) {\n        input = undefined;\n    }\n    // object construction must be done this way.\n    // https://github.com/moment/moment/issues/1423\n    c._isAMomentObject = true;\n    c._useUTC = c._isUTC = isUTC;\n    c._l = locale;\n    c._i = input;\n    c._f = format;\n    c._strict = strict;\n\n    return createFromConfig(c);\n}\n\nfunction createLocal (input, format, locale, strict) {\n    return createLocalOrUTC(input, format, locale, strict, false);\n}\n\nvar prototypeMin = deprecate(\n    'moment().min is deprecated, use moment.max instead. http://momentjs.com/guides/#/warnings/min-max/',\n    function () {\n        var other = createLocal.apply(null, arguments);\n        if (this.isValid() && other.isValid()) {\n            return other < this ? this : other;\n        } else {\n            return createInvalid();\n        }\n    }\n);\n\nvar prototypeMax = deprecate(\n    'moment().max is deprecated, use moment.min instead. http://momentjs.com/guides/#/warnings/min-max/',\n    function () {\n        var other = createLocal.apply(null, arguments);\n        if (this.isValid() && other.isValid()) {\n            return other > this ? this : other;\n        } else {\n            return createInvalid();\n        }\n    }\n);\n\n// Pick a moment m from moments so that m[fn](other) is true for all\n// other. This relies on the function fn to be transitive.\n//\n// moments should either be an array of moment objects or an array, whose\n// first element is an array of moment objects.\nfunction pickBy(fn, moments) {\n    var res, i;\n    if (moments.length === 1 && isArray(moments[0])) {\n        moments = moments[0];\n    }\n    if (!moments.length) {\n        return createLocal();\n    }\n    res = moments[0];\n    for (i = 1; i < moments.length; ++i) {\n        if (!moments[i].isValid() || moments[i][fn](res)) {\n            res = moments[i];\n        }\n    }\n    return res;\n}\n\n// TODO: Use [].sort instead?\nfunction min () {\n    var args = [].slice.call(arguments, 0);\n\n    return pickBy('isBefore', args);\n}\n\nfunction max () {\n    var args = [].slice.call(arguments, 0);\n\n    return pickBy('isAfter', args);\n}\n\nvar now = function () {\n    return Date.now ? Date.now() : +(new Date());\n};\n\nvar ordering = ['year', 'quarter', 'month', 'week', 'day', 'hour', 'minute', 'second', 'millisecond'];\n\nfunction isDurationValid(m) {\n    for (var key in m) {\n        if (!(ordering.indexOf(key) !== -1 && (m[key] == null || !isNaN(m[key])))) {\n            return false;\n        }\n    }\n\n    var unitHasDecimal = false;\n    for (var i = 0; i < ordering.length; ++i) {\n        if (m[ordering[i]]) {\n            if (unitHasDecimal) {\n                return false; // only allow non-integers for smallest unit\n            }\n            if (parseFloat(m[ordering[i]]) !== toInt(m[ordering[i]])) {\n                unitHasDecimal = true;\n            }\n        }\n    }\n\n    return true;\n}\n\nfunction isValid$1() {\n    return this._isValid;\n}\n\nfunction createInvalid$1() {\n    return createDuration(NaN);\n}\n\nfunction Duration (duration) {\n    var normalizedInput = normalizeObjectUnits(duration),\n        years = normalizedInput.year || 0,\n        quarters = normalizedInput.quarter || 0,\n        months = normalizedInput.month || 0,\n        weeks = normalizedInput.week || 0,\n        days = normalizedInput.day || 0,\n        hours = normalizedInput.hour || 0,\n        minutes = normalizedInput.minute || 0,\n        seconds = normalizedInput.second || 0,\n        milliseconds = normalizedInput.millisecond || 0;\n\n    this._isValid = isDurationValid(normalizedInput);\n\n    // representation for dateAddRemove\n    this._milliseconds = +milliseconds +\n        seconds * 1e3 + // 1000\n        minutes * 6e4 + // 1000 * 60\n        hours * 1000 * 60 * 60; //using 1000 * 60 * 60 instead of 36e5 to avoid floating point rounding errors https://github.com/moment/moment/issues/2978\n    // Because of dateAddRemove treats 24 hours as different from a\n    // day when working around DST, we need to store them separately\n    this._days = +days +\n        weeks * 7;\n    // It is impossible translate months into days without knowing\n    // which months you are are talking about, so we have to store\n    // it separately.\n    this._months = +months +\n        quarters * 3 +\n        years * 12;\n\n    this._data = {};\n\n    this._locale = getLocale();\n\n    this._bubble();\n}\n\nfunction isDuration (obj) {\n    return obj instanceof Duration;\n}\n\nfunction absRound (number) {\n    if (number < 0) {\n        return Math.round(-1 * number) * -1;\n    } else {\n        return Math.round(number);\n    }\n}\n\n// FORMATTING\n\nfunction offset (token, separator) {\n    addFormatToken(token, 0, 0, function () {\n        var offset = this.utcOffset();\n        var sign = '+';\n        if (offset < 0) {\n            offset = -offset;\n            sign = '-';\n        }\n        return sign + zeroFill(~~(offset / 60), 2) + separator + zeroFill(~~(offset) % 60, 2);\n    });\n}\n\noffset('Z', ':');\noffset('ZZ', '');\n\n// PARSING\n\naddRegexToken('Z',  matchShortOffset);\naddRegexToken('ZZ', matchShortOffset);\naddParseToken(['Z', 'ZZ'], function (input, array, config) {\n    config._useUTC = true;\n    config._tzm = offsetFromString(matchShortOffset, input);\n});\n\n// HELPERS\n\n// timezone chunker\n// '+10:00' > ['10',  '00']\n// '-1530'  > ['-15', '30']\nvar chunkOffset = /([\\+\\-]|\\d\\d)/gi;\n\nfunction offsetFromString(matcher, string) {\n    var matches = (string || '').match(matcher);\n\n    if (matches === null) {\n        return null;\n    }\n\n    var chunk   = matches[matches.length - 1] || [];\n    var parts   = (chunk + '').match(chunkOffset) || ['-', 0, 0];\n    var minutes = +(parts[1] * 60) + toInt(parts[2]);\n\n    return minutes === 0 ?\n      0 :\n      parts[0] === '+' ? minutes : -minutes;\n}\n\n// Return a moment from input, that is local/utc/zone equivalent to model.\nfunction cloneWithOffset(input, model) {\n    var res, diff;\n    if (model._isUTC) {\n        res = model.clone();\n        diff = (isMoment(input) || isDate(input) ? input.valueOf() : createLocal(input).valueOf()) - res.valueOf();\n        // Use low-level api, because this fn is low-level api.\n        res._d.setTime(res._d.valueOf() + diff);\n        hooks.updateOffset(res, false);\n        return res;\n    } else {\n        return createLocal(input).local();\n    }\n}\n\nfunction getDateOffset (m) {\n    // On Firefox.24 Date#getTimezoneOffset returns a floating point.\n    // https://github.com/moment/moment/pull/1871\n    return -Math.round(m._d.getTimezoneOffset() / 15) * 15;\n}\n\n// HOOKS\n\n// This function will be called whenever a moment is mutated.\n// It is intended to keep the offset in sync with the timezone.\nhooks.updateOffset = function () {};\n\n// MOMENTS\n\n// keepLocalTime = true means only change the timezone, without\n// affecting the local hour. So 5:31:26 +0300 --[utcOffset(2, true)]-->\n// 5:31:26 +0200 It is possible that 5:31:26 doesn't exist with offset\n// +0200, so we adjust the time as needed, to be valid.\n//\n// Keeping the time actually adds/subtracts (one hour)\n// from the actual represented time. That is why we call updateOffset\n// a second time. In case it wants us to change the offset again\n// _changeInProgress == true case, then we have to adjust, because\n// there is no such time in the given timezone.\nfunction getSetOffset (input, keepLocalTime, keepMinutes) {\n    var offset = this._offset || 0,\n        localAdjust;\n    if (!this.isValid()) {\n        return input != null ? this : NaN;\n    }\n    if (input != null) {\n        if (typeof input === 'string') {\n            input = offsetFromString(matchShortOffset, input);\n            if (input === null) {\n                return this;\n            }\n        } else if (Math.abs(input) < 16 && !keepMinutes) {\n            input = input * 60;\n        }\n        if (!this._isUTC && keepLocalTime) {\n            localAdjust = getDateOffset(this);\n        }\n        this._offset = input;\n        this._isUTC = true;\n        if (localAdjust != null) {\n            this.add(localAdjust, 'm');\n        }\n        if (offset !== input) {\n            if (!keepLocalTime || this._changeInProgress) {\n                addSubtract(this, createDuration(input - offset, 'm'), 1, false);\n            } else if (!this._changeInProgress) {\n                this._changeInProgress = true;\n                hooks.updateOffset(this, true);\n                this._changeInProgress = null;\n            }\n        }\n        return this;\n    } else {\n        return this._isUTC ? offset : getDateOffset(this);\n    }\n}\n\nfunction getSetZone (input, keepLocalTime) {\n    if (input != null) {\n        if (typeof input !== 'string') {\n            input = -input;\n        }\n\n        this.utcOffset(input, keepLocalTime);\n\n        return this;\n    } else {\n        return -this.utcOffset();\n    }\n}\n\nfunction setOffsetToUTC (keepLocalTime) {\n    return this.utcOffset(0, keepLocalTime);\n}\n\nfunction setOffsetToLocal (keepLocalTime) {\n    if (this._isUTC) {\n        this.utcOffset(0, keepLocalTime);\n        this._isUTC = false;\n\n        if (keepLocalTime) {\n            this.subtract(getDateOffset(this), 'm');\n        }\n    }\n    return this;\n}\n\nfunction setOffsetToParsedOffset () {\n    if (this._tzm != null) {\n        this.utcOffset(this._tzm, false, true);\n    } else if (typeof this._i === 'string') {\n        var tZone = offsetFromString(matchOffset, this._i);\n        if (tZone != null) {\n            this.utcOffset(tZone);\n        }\n        else {\n            this.utcOffset(0, true);\n        }\n    }\n    return this;\n}\n\nfunction hasAlignedHourOffset (input) {\n    if (!this.isValid()) {\n        return false;\n    }\n    input = input ? createLocal(input).utcOffset() : 0;\n\n    return (this.utcOffset() - input) % 60 === 0;\n}\n\nfunction isDaylightSavingTime () {\n    return (\n        this.utcOffset() > this.clone().month(0).utcOffset() ||\n        this.utcOffset() > this.clone().month(5).utcOffset()\n    );\n}\n\nfunction isDaylightSavingTimeShifted () {\n    if (!isUndefined(this._isDSTShifted)) {\n        return this._isDSTShifted;\n    }\n\n    var c = {};\n\n    copyConfig(c, this);\n    c = prepareConfig(c);\n\n    if (c._a) {\n        var other = c._isUTC ? createUTC(c._a) : createLocal(c._a);\n        this._isDSTShifted = this.isValid() &&\n            compareArrays(c._a, other.toArray()) > 0;\n    } else {\n        this._isDSTShifted = false;\n    }\n\n    return this._isDSTShifted;\n}\n\nfunction isLocal () {\n    return this.isValid() ? !this._isUTC : false;\n}\n\nfunction isUtcOffset () {\n    return this.isValid() ? this._isUTC : false;\n}\n\nfunction isUtc () {\n    return this.isValid() ? this._isUTC && this._offset === 0 : false;\n}\n\n// ASP.NET json date format regex\nvar aspNetRegex = /^(\\-)?(?:(\\d*)[. ])?(\\d+)\\:(\\d+)(?:\\:(\\d+)(\\.\\d*)?)?$/;\n\n// from http://docs.closure-library.googlecode.com/git/closure_goog_date_date.js.source.html\n// somewhat more in line with 4.4.3.2 2004 spec, but allows decimal anywhere\n// and further modified to allow for strings containing both week and day\nvar isoRegex = /^(-)?P(?:(-?[0-9,.]*)Y)?(?:(-?[0-9,.]*)M)?(?:(-?[0-9,.]*)W)?(?:(-?[0-9,.]*)D)?(?:T(?:(-?[0-9,.]*)H)?(?:(-?[0-9,.]*)M)?(?:(-?[0-9,.]*)S)?)?$/;\n\nfunction createDuration (input, key) {\n    var duration = input,\n        // matching against regexp is expensive, do it on demand\n        match = null,\n        sign,\n        ret,\n        diffRes;\n\n    if (isDuration(input)) {\n        duration = {\n            ms : input._milliseconds,\n            d  : input._days,\n            M  : input._months\n        };\n    } else if (isNumber(input)) {\n        duration = {};\n        if (key) {\n            duration[key] = input;\n        } else {\n            duration.milliseconds = input;\n        }\n    } else if (!!(match = aspNetRegex.exec(input))) {\n        sign = (match[1] === '-') ? -1 : 1;\n        duration = {\n            y  : 0,\n            d  : toInt(match[DATE])                         * sign,\n            h  : toInt(match[HOUR])                         * sign,\n            m  : toInt(match[MINUTE])                       * sign,\n            s  : toInt(match[SECOND])                       * sign,\n            ms : toInt(absRound(match[MILLISECOND] * 1000)) * sign // the millisecond decimal point is included in the match\n        };\n    } else if (!!(match = isoRegex.exec(input))) {\n        sign = (match[1] === '-') ? -1 : 1;\n        duration = {\n            y : parseIso(match[2], sign),\n            M : parseIso(match[3], sign),\n            w : parseIso(match[4], sign),\n            d : parseIso(match[5], sign),\n            h : parseIso(match[6], sign),\n            m : parseIso(match[7], sign),\n            s : parseIso(match[8], sign)\n        };\n    } else if (duration == null) {// checks for null or undefined\n        duration = {};\n    } else if (typeof duration === 'object' && ('from' in duration || 'to' in duration)) {\n        diffRes = momentsDifference(createLocal(duration.from), createLocal(duration.to));\n\n        duration = {};\n        duration.ms = diffRes.milliseconds;\n        duration.M = diffRes.months;\n    }\n\n    ret = new Duration(duration);\n\n    if (isDuration(input) && hasOwnProp(input, '_locale')) {\n        ret._locale = input._locale;\n    }\n\n    return ret;\n}\n\ncreateDuration.fn = Duration.prototype;\ncreateDuration.invalid = createInvalid$1;\n\nfunction parseIso (inp, sign) {\n    // We'd normally use ~~inp for this, but unfortunately it also\n    // converts floats to ints.\n    // inp may be undefined, so careful calling replace on it.\n    var res = inp && parseFloat(inp.replace(',', '.'));\n    // apply sign while we're at it\n    return (isNaN(res) ? 0 : res) * sign;\n}\n\nfunction positiveMomentsDifference(base, other) {\n    var res = {milliseconds: 0, months: 0};\n\n    res.months = other.month() - base.month() +\n        (other.year() - base.year()) * 12;\n    if (base.clone().add(res.months, 'M').isAfter(other)) {\n        --res.months;\n    }\n\n    res.milliseconds = +other - +(base.clone().add(res.months, 'M'));\n\n    return res;\n}\n\nfunction momentsDifference(base, other) {\n    var res;\n    if (!(base.isValid() && other.isValid())) {\n        return {milliseconds: 0, months: 0};\n    }\n\n    other = cloneWithOffset(other, base);\n    if (base.isBefore(other)) {\n        res = positiveMomentsDifference(base, other);\n    } else {\n        res = positiveMomentsDifference(other, base);\n        res.milliseconds = -res.milliseconds;\n        res.months = -res.months;\n    }\n\n    return res;\n}\n\n// TODO: remove 'name' arg after deprecation is removed\nfunction createAdder(direction, name) {\n    return function (val, period) {\n        var dur, tmp;\n        //invert the arguments, but complain about it\n        if (period !== null && !isNaN(+period)) {\n            deprecateSimple(name, 'moment().' + name  + '(period, number) is deprecated. Please use moment().' + name + '(number, period). ' +\n            'See http://momentjs.com/guides/#/warnings/add-inverted-param/ for more info.');\n            tmp = val; val = period; period = tmp;\n        }\n\n        val = typeof val === 'string' ? +val : val;\n        dur = createDuration(val, period);\n        addSubtract(this, dur, direction);\n        return this;\n    };\n}\n\nfunction addSubtract (mom, duration, isAdding, updateOffset) {\n    var milliseconds = duration._milliseconds,\n        days = absRound(duration._days),\n        months = absRound(duration._months);\n\n    if (!mom.isValid()) {\n        // No op\n        return;\n    }\n\n    updateOffset = updateOffset == null ? true : updateOffset;\n\n    if (milliseconds) {\n        mom._d.setTime(mom._d.valueOf() + milliseconds * isAdding);\n    }\n    if (days) {\n        set$1(mom, 'Date', get(mom, 'Date') + days * isAdding);\n    }\n    if (months) {\n        setMonth(mom, get(mom, 'Month') + months * isAdding);\n    }\n    if (updateOffset) {\n        hooks.updateOffset(mom, days || months);\n    }\n}\n\nvar add      = createAdder(1, 'add');\nvar subtract = createAdder(-1, 'subtract');\n\nfunction getCalendarFormat(myMoment, now) {\n    var diff = myMoment.diff(now, 'days', true);\n    return diff < -6 ? 'sameElse' :\n            diff < -1 ? 'lastWeek' :\n            diff < 0 ? 'lastDay' :\n            diff < 1 ? 'sameDay' :\n            diff < 2 ? 'nextDay' :\n            diff < 7 ? 'nextWeek' : 'sameElse';\n}\n\nfunction calendar$1 (time, formats) {\n    // We want to compare the start of today, vs this.\n    // Getting start-of-today depends on whether we're local/utc/offset or not.\n    var now = time || createLocal(),\n        sod = cloneWithOffset(now, this).startOf('day'),\n        format = hooks.calendarFormat(this, sod) || 'sameElse';\n\n    var output = formats && (isFunction(formats[format]) ? formats[format].call(this, now) : formats[format]);\n\n    return this.format(output || this.localeData().calendar(format, this, createLocal(now)));\n}\n\nfunction clone () {\n    return new Moment(this);\n}\n\nfunction isAfter (input, units) {\n    var localInput = isMoment(input) ? input : createLocal(input);\n    if (!(this.isValid() && localInput.isValid())) {\n        return false;\n    }\n    units = normalizeUnits(!isUndefined(units) ? units : 'millisecond');\n    if (units === 'millisecond') {\n        return this.valueOf() > localInput.valueOf();\n    } else {\n        return localInput.valueOf() < this.clone().startOf(units).valueOf();\n    }\n}\n\nfunction isBefore (input, units) {\n    var localInput = isMoment(input) ? input : createLocal(input);\n    if (!(this.isValid() && localInput.isValid())) {\n        return false;\n    }\n    units = normalizeUnits(!isUndefined(units) ? units : 'millisecond');\n    if (units === 'millisecond') {\n        return this.valueOf() < localInput.valueOf();\n    } else {\n        return this.clone().endOf(units).valueOf() < localInput.valueOf();\n    }\n}\n\nfunction isBetween (from, to, units, inclusivity) {\n    inclusivity = inclusivity || '()';\n    return (inclusivity[0] === '(' ? this.isAfter(from, units) : !this.isBefore(from, units)) &&\n        (inclusivity[1] === ')' ? this.isBefore(to, units) : !this.isAfter(to, units));\n}\n\nfunction isSame (input, units) {\n    var localInput = isMoment(input) ? input : createLocal(input),\n        inputMs;\n    if (!(this.isValid() && localInput.isValid())) {\n        return false;\n    }\n    units = normalizeUnits(units || 'millisecond');\n    if (units === 'millisecond') {\n        return this.valueOf() === localInput.valueOf();\n    } else {\n        inputMs = localInput.valueOf();\n        return this.clone().startOf(units).valueOf() <= inputMs && inputMs <= this.clone().endOf(units).valueOf();\n    }\n}\n\nfunction isSameOrAfter (input, units) {\n    return this.isSame(input, units) || this.isAfter(input,units);\n}\n\nfunction isSameOrBefore (input, units) {\n    return this.isSame(input, units) || this.isBefore(input,units);\n}\n\nfunction diff (input, units, asFloat) {\n    var that,\n        zoneDelta,\n        delta, output;\n\n    if (!this.isValid()) {\n        return NaN;\n    }\n\n    that = cloneWithOffset(input, this);\n\n    if (!that.isValid()) {\n        return NaN;\n    }\n\n    zoneDelta = (that.utcOffset() - this.utcOffset()) * 6e4;\n\n    units = normalizeUnits(units);\n\n    if (units === 'year' || units === 'month' || units === 'quarter') {\n        output = monthDiff(this, that);\n        if (units === 'quarter') {\n            output = output / 3;\n        } else if (units === 'year') {\n            output = output / 12;\n        }\n    } else {\n        delta = this - that;\n        output = units === 'second' ? delta / 1e3 : // 1000\n            units === 'minute' ? delta / 6e4 : // 1000 * 60\n            units === 'hour' ? delta / 36e5 : // 1000 * 60 * 60\n            units === 'day' ? (delta - zoneDelta) / 864e5 : // 1000 * 60 * 60 * 24, negate dst\n            units === 'week' ? (delta - zoneDelta) / 6048e5 : // 1000 * 60 * 60 * 24 * 7, negate dst\n            delta;\n    }\n    return asFloat ? output : absFloor(output);\n}\n\nfunction monthDiff (a, b) {\n    // difference in months\n    var wholeMonthDiff = ((b.year() - a.year()) * 12) + (b.month() - a.month()),\n        // b is in (anchor - 1 month, anchor + 1 month)\n        anchor = a.clone().add(wholeMonthDiff, 'months'),\n        anchor2, adjust;\n\n    if (b - anchor < 0) {\n        anchor2 = a.clone().add(wholeMonthDiff - 1, 'months');\n        // linear across the month\n        adjust = (b - anchor) / (anchor - anchor2);\n    } else {\n        anchor2 = a.clone().add(wholeMonthDiff + 1, 'months');\n        // linear across the month\n        adjust = (b - anchor) / (anchor2 - anchor);\n    }\n\n    //check for negative zero, return zero if negative zero\n    return -(wholeMonthDiff + adjust) || 0;\n}\n\nhooks.defaultFormat = 'YYYY-MM-DDTHH:mm:ssZ';\nhooks.defaultFormatUtc = 'YYYY-MM-DDTHH:mm:ss[Z]';\n\nfunction toString () {\n    return this.clone().locale('en').format('ddd MMM DD YYYY HH:mm:ss [GMT]ZZ');\n}\n\nfunction toISOString() {\n    if (!this.isValid()) {\n        return null;\n    }\n    var m = this.clone().utc();\n    if (m.year() < 0 || m.year() > 9999) {\n        return formatMoment(m, 'YYYYYY-MM-DD[T]HH:mm:ss.SSS[Z]');\n    }\n    if (isFunction(Date.prototype.toISOString)) {\n        // native implementation is ~50x faster, use it when we can\n        return this.toDate().toISOString();\n    }\n    return formatMoment(m, 'YYYY-MM-DD[T]HH:mm:ss.SSS[Z]');\n}\n\n/**\n * Return a human readable representation of a moment that can\n * also be evaluated to get a new moment which is the same\n *\n * @link https://nodejs.org/dist/latest/docs/api/util.html#util_custom_inspect_function_on_objects\n */\nfunction inspect () {\n    if (!this.isValid()) {\n        return 'moment.invalid(/* ' + this._i + ' */)';\n    }\n    var func = 'moment';\n    var zone = '';\n    if (!this.isLocal()) {\n        func = this.utcOffset() === 0 ? 'moment.utc' : 'moment.parseZone';\n        zone = 'Z';\n    }\n    var prefix = '[' + func + '(\"]';\n    var year = (0 <= this.year() && this.year() <= 9999) ? 'YYYY' : 'YYYYYY';\n    var datetime = '-MM-DD[T]HH:mm:ss.SSS';\n    var suffix = zone + '[\")]';\n\n    return this.format(prefix + year + datetime + suffix);\n}\n\nfunction format (inputString) {\n    if (!inputString) {\n        inputString = this.isUtc() ? hooks.defaultFormatUtc : hooks.defaultFormat;\n    }\n    var output = formatMoment(this, inputString);\n    return this.localeData().postformat(output);\n}\n\nfunction from (time, withoutSuffix) {\n    if (this.isValid() &&\n            ((isMoment(time) && time.isValid()) ||\n             createLocal(time).isValid())) {\n        return createDuration({to: this, from: time}).locale(this.locale()).humanize(!withoutSuffix);\n    } else {\n        return this.localeData().invalidDate();\n    }\n}\n\nfunction fromNow (withoutSuffix) {\n    return this.from(createLocal(), withoutSuffix);\n}\n\nfunction to (time, withoutSuffix) {\n    if (this.isValid() &&\n            ((isMoment(time) && time.isValid()) ||\n             createLocal(time).isValid())) {\n        return createDuration({from: this, to: time}).locale(this.locale()).humanize(!withoutSuffix);\n    } else {\n        return this.localeData().invalidDate();\n    }\n}\n\nfunction toNow (withoutSuffix) {\n    return this.to(createLocal(), withoutSuffix);\n}\n\n// If passed a locale key, it will set the locale for this\n// instance.  Otherwise, it will return the locale configuration\n// variables for this instance.\nfunction locale (key) {\n    var newLocaleData;\n\n    if (key === undefined) {\n        return this._locale._abbr;\n    } else {\n        newLocaleData = getLocale(key);\n        if (newLocaleData != null) {\n            this._locale = newLocaleData;\n        }\n        return this;\n    }\n}\n\nvar lang = deprecate(\n    'moment().lang() is deprecated. Instead, use moment().localeData() to get the language configuration. Use moment().locale() to change languages.',\n    function (key) {\n        if (key === undefined) {\n            return this.localeData();\n        } else {\n            return this.locale(key);\n        }\n    }\n);\n\nfunction localeData () {\n    return this._locale;\n}\n\nfunction startOf (units) {\n    units = normalizeUnits(units);\n    // the following switch intentionally omits break keywords\n    // to utilize falling through the cases.\n    switch (units) {\n        case 'year':\n            this.month(0);\n            /* falls through */\n        case 'quarter':\n        case 'month':\n            this.date(1);\n            /* falls through */\n        case 'week':\n        case 'isoWeek':\n        case 'day':\n        case 'date':\n            this.hours(0);\n            /* falls through */\n        case 'hour':\n            this.minutes(0);\n            /* falls through */\n        case 'minute':\n            this.seconds(0);\n            /* falls through */\n        case 'second':\n            this.milliseconds(0);\n    }\n\n    // weeks are a special case\n    if (units === 'week') {\n        this.weekday(0);\n    }\n    if (units === 'isoWeek') {\n        this.isoWeekday(1);\n    }\n\n    // quarters are also special\n    if (units === 'quarter') {\n        this.month(Math.floor(this.month() / 3) * 3);\n    }\n\n    return this;\n}\n\nfunction endOf (units) {\n    units = normalizeUnits(units);\n    if (units === undefined || units === 'millisecond') {\n        return this;\n    }\n\n    // 'date' is an alias for 'day', so it should be considered as such.\n    if (units === 'date') {\n        units = 'day';\n    }\n\n    return this.startOf(units).add(1, (units === 'isoWeek' ? 'week' : units)).subtract(1, 'ms');\n}\n\nfunction valueOf () {\n    return this._d.valueOf() - ((this._offset || 0) * 60000);\n}\n\nfunction unix () {\n    return Math.floor(this.valueOf() / 1000);\n}\n\nfunction toDate () {\n    return new Date(this.valueOf());\n}\n\nfunction toArray () {\n    var m = this;\n    return [m.year(), m.month(), m.date(), m.hour(), m.minute(), m.second(), m.millisecond()];\n}\n\nfunction toObject () {\n    var m = this;\n    return {\n        years: m.year(),\n        months: m.month(),\n        date: m.date(),\n        hours: m.hours(),\n        minutes: m.minutes(),\n        seconds: m.seconds(),\n        milliseconds: m.milliseconds()\n    };\n}\n\nfunction toJSON () {\n    // new Date(NaN).toJSON() === null\n    return this.isValid() ? this.toISOString() : null;\n}\n\nfunction isValid$2 () {\n    return isValid(this);\n}\n\nfunction parsingFlags () {\n    return extend({}, getParsingFlags(this));\n}\n\nfunction invalidAt () {\n    return getParsingFlags(this).overflow;\n}\n\nfunction creationData() {\n    return {\n        input: this._i,\n        format: this._f,\n        locale: this._locale,\n        isUTC: this._isUTC,\n        strict: this._strict\n    };\n}\n\n// FORMATTING\n\naddFormatToken(0, ['gg', 2], 0, function () {\n    return this.weekYear() % 100;\n});\n\naddFormatToken(0, ['GG', 2], 0, function () {\n    return this.isoWeekYear() % 100;\n});\n\nfunction addWeekYearFormatToken (token, getter) {\n    addFormatToken(0, [token, token.length], 0, getter);\n}\n\naddWeekYearFormatToken('gggg',     'weekYear');\naddWeekYearFormatToken('ggggg',    'weekYear');\naddWeekYearFormatToken('GGGG',  'isoWeekYear');\naddWeekYearFormatToken('GGGGG', 'isoWeekYear');\n\n// ALIASES\n\naddUnitAlias('weekYear', 'gg');\naddUnitAlias('isoWeekYear', 'GG');\n\n// PRIORITY\n\naddUnitPriority('weekYear', 1);\naddUnitPriority('isoWeekYear', 1);\n\n\n// PARSING\n\naddRegexToken('G',      matchSigned);\naddRegexToken('g',      matchSigned);\naddRegexToken('GG',     match1to2, match2);\naddRegexToken('gg',     match1to2, match2);\naddRegexToken('GGGG',   match1to4, match4);\naddRegexToken('gggg',   match1to4, match4);\naddRegexToken('GGGGG',  match1to6, match6);\naddRegexToken('ggggg',  match1to6, match6);\n\naddWeekParseToken(['gggg', 'ggggg', 'GGGG', 'GGGGG'], function (input, week, config, token) {\n    week[token.substr(0, 2)] = toInt(input);\n});\n\naddWeekParseToken(['gg', 'GG'], function (input, week, config, token) {\n    week[token] = hooks.parseTwoDigitYear(input);\n});\n\n// MOMENTS\n\nfunction getSetWeekYear (input) {\n    return getSetWeekYearHelper.call(this,\n            input,\n            this.week(),\n            this.weekday(),\n            this.localeData()._week.dow,\n            this.localeData()._week.doy);\n}\n\nfunction getSetISOWeekYear (input) {\n    return getSetWeekYearHelper.call(this,\n            input, this.isoWeek(), this.isoWeekday(), 1, 4);\n}\n\nfunction getISOWeeksInYear () {\n    return weeksInYear(this.year(), 1, 4);\n}\n\nfunction getWeeksInYear () {\n    var weekInfo = this.localeData()._week;\n    return weeksInYear(this.year(), weekInfo.dow, weekInfo.doy);\n}\n\nfunction getSetWeekYearHelper(input, week, weekday, dow, doy) {\n    var weeksTarget;\n    if (input == null) {\n        return weekOfYear(this, dow, doy).year;\n    } else {\n        weeksTarget = weeksInYear(input, dow, doy);\n        if (week > weeksTarget) {\n            week = weeksTarget;\n        }\n        return setWeekAll.call(this, input, week, weekday, dow, doy);\n    }\n}\n\nfunction setWeekAll(weekYear, week, weekday, dow, doy) {\n    var dayOfYearData = dayOfYearFromWeeks(weekYear, week, weekday, dow, doy),\n        date = createUTCDate(dayOfYearData.year, 0, dayOfYearData.dayOfYear);\n\n    this.year(date.getUTCFullYear());\n    this.month(date.getUTCMonth());\n    this.date(date.getUTCDate());\n    return this;\n}\n\n// FORMATTING\n\naddFormatToken('Q', 0, 'Qo', 'quarter');\n\n// ALIASES\n\naddUnitAlias('quarter', 'Q');\n\n// PRIORITY\n\naddUnitPriority('quarter', 7);\n\n// PARSING\n\naddRegexToken('Q', match1);\naddParseToken('Q', function (input, array) {\n    array[MONTH] = (toInt(input) - 1) * 3;\n});\n\n// MOMENTS\n\nfunction getSetQuarter (input) {\n    return input == null ? Math.ceil((this.month() + 1) / 3) : this.month((input - 1) * 3 + this.month() % 3);\n}\n\n// FORMATTING\n\naddFormatToken('D', ['DD', 2], 'Do', 'date');\n\n// ALIASES\n\naddUnitAlias('date', 'D');\n\n// PRIOROITY\naddUnitPriority('date', 9);\n\n// PARSING\n\naddRegexToken('D',  match1to2);\naddRegexToken('DD', match1to2, match2);\naddRegexToken('Do', function (isStrict, locale) {\n    // TODO: Remove \"ordinalParse\" fallback in next major release.\n    return isStrict ?\n      (locale._dayOfMonthOrdinalParse || locale._ordinalParse) :\n      locale._dayOfMonthOrdinalParseLenient;\n});\n\naddParseToken(['D', 'DD'], DATE);\naddParseToken('Do', function (input, array) {\n    array[DATE] = toInt(input.match(match1to2)[0], 10);\n});\n\n// MOMENTS\n\nvar getSetDayOfMonth = makeGetSet('Date', true);\n\n// FORMATTING\n\naddFormatToken('DDD', ['DDDD', 3], 'DDDo', 'dayOfYear');\n\n// ALIASES\n\naddUnitAlias('dayOfYear', 'DDD');\n\n// PRIORITY\naddUnitPriority('dayOfYear', 4);\n\n// PARSING\n\naddRegexToken('DDD',  match1to3);\naddRegexToken('DDDD', match3);\naddParseToken(['DDD', 'DDDD'], function (input, array, config) {\n    config._dayOfYear = toInt(input);\n});\n\n// HELPERS\n\n// MOMENTS\n\nfunction getSetDayOfYear (input) {\n    var dayOfYear = Math.round((this.clone().startOf('day') - this.clone().startOf('year')) / 864e5) + 1;\n    return input == null ? dayOfYear : this.add((input - dayOfYear), 'd');\n}\n\n// FORMATTING\n\naddFormatToken('m', ['mm', 2], 0, 'minute');\n\n// ALIASES\n\naddUnitAlias('minute', 'm');\n\n// PRIORITY\n\naddUnitPriority('minute', 14);\n\n// PARSING\n\naddRegexToken('m',  match1to2);\naddRegexToken('mm', match1to2, match2);\naddParseToken(['m', 'mm'], MINUTE);\n\n// MOMENTS\n\nvar getSetMinute = makeGetSet('Minutes', false);\n\n// FORMATTING\n\naddFormatToken('s', ['ss', 2], 0, 'second');\n\n// ALIASES\n\naddUnitAlias('second', 's');\n\n// PRIORITY\n\naddUnitPriority('second', 15);\n\n// PARSING\n\naddRegexToken('s',  match1to2);\naddRegexToken('ss', match1to2, match2);\naddParseToken(['s', 'ss'], SECOND);\n\n// MOMENTS\n\nvar getSetSecond = makeGetSet('Seconds', false);\n\n// FORMATTING\n\naddFormatToken('S', 0, 0, function () {\n    return ~~(this.millisecond() / 100);\n});\n\naddFormatToken(0, ['SS', 2], 0, function () {\n    return ~~(this.millisecond() / 10);\n});\n\naddFormatToken(0, ['SSS', 3], 0, 'millisecond');\naddFormatToken(0, ['SSSS', 4], 0, function () {\n    return this.millisecond() * 10;\n});\naddFormatToken(0, ['SSSSS', 5], 0, function () {\n    return this.millisecond() * 100;\n});\naddFormatToken(0, ['SSSSSS', 6], 0, function () {\n    return this.millisecond() * 1000;\n});\naddFormatToken(0, ['SSSSSSS', 7], 0, function () {\n    return this.millisecond() * 10000;\n});\naddFormatToken(0, ['SSSSSSSS', 8], 0, function () {\n    return this.millisecond() * 100000;\n});\naddFormatToken(0, ['SSSSSSSSS', 9], 0, function () {\n    return this.millisecond() * 1000000;\n});\n\n\n// ALIASES\n\naddUnitAlias('millisecond', 'ms');\n\n// PRIORITY\n\naddUnitPriority('millisecond', 16);\n\n// PARSING\n\naddRegexToken('S',    match1to3, match1);\naddRegexToken('SS',   match1to3, match2);\naddRegexToken('SSS',  match1to3, match3);\n\nvar token;\nfor (token = 'SSSS'; token.length <= 9; token += 'S') {\n    addRegexToken(token, matchUnsigned);\n}\n\nfunction parseMs(input, array) {\n    array[MILLISECOND] = toInt(('0.' + input) * 1000);\n}\n\nfor (token = 'S'; token.length <= 9; token += 'S') {\n    addParseToken(token, parseMs);\n}\n// MOMENTS\n\nvar getSetMillisecond = makeGetSet('Milliseconds', false);\n\n// FORMATTING\n\naddFormatToken('z',  0, 0, 'zoneAbbr');\naddFormatToken('zz', 0, 0, 'zoneName');\n\n// MOMENTS\n\nfunction getZoneAbbr () {\n    return this._isUTC ? 'UTC' : '';\n}\n\nfunction getZoneName () {\n    return this._isUTC ? 'Coordinated Universal Time' : '';\n}\n\nvar proto = Moment.prototype;\n\nproto.add               = add;\nproto.calendar          = calendar$1;\nproto.clone             = clone;\nproto.diff              = diff;\nproto.endOf             = endOf;\nproto.format            = format;\nproto.from              = from;\nproto.fromNow           = fromNow;\nproto.to                = to;\nproto.toNow             = toNow;\nproto.get               = stringGet;\nproto.invalidAt         = invalidAt;\nproto.isAfter           = isAfter;\nproto.isBefore          = isBefore;\nproto.isBetween         = isBetween;\nproto.isSame            = isSame;\nproto.isSameOrAfter     = isSameOrAfter;\nproto.isSameOrBefore    = isSameOrBefore;\nproto.isValid           = isValid$2;\nproto.lang              = lang;\nproto.locale            = locale;\nproto.localeData        = localeData;\nproto.max               = prototypeMax;\nproto.min               = prototypeMin;\nproto.parsingFlags      = parsingFlags;\nproto.set               = stringSet;\nproto.startOf           = startOf;\nproto.subtract          = subtract;\nproto.toArray           = toArray;\nproto.toObject          = toObject;\nproto.toDate            = toDate;\nproto.toISOString       = toISOString;\nproto.inspect           = inspect;\nproto.toJSON            = toJSON;\nproto.toString          = toString;\nproto.unix              = unix;\nproto.valueOf           = valueOf;\nproto.creationData      = creationData;\n\n// Year\nproto.year       = getSetYear;\nproto.isLeapYear = getIsLeapYear;\n\n// Week Year\nproto.weekYear    = getSetWeekYear;\nproto.isoWeekYear = getSetISOWeekYear;\n\n// Quarter\nproto.quarter = proto.quarters = getSetQuarter;\n\n// Month\nproto.month       = getSetMonth;\nproto.daysInMonth = getDaysInMonth;\n\n// Week\nproto.week           = proto.weeks        = getSetWeek;\nproto.isoWeek        = proto.isoWeeks     = getSetISOWeek;\nproto.weeksInYear    = getWeeksInYear;\nproto.isoWeeksInYear = getISOWeeksInYear;\n\n// Day\nproto.date       = getSetDayOfMonth;\nproto.day        = proto.days             = getSetDayOfWeek;\nproto.weekday    = getSetLocaleDayOfWeek;\nproto.isoWeekday = getSetISODayOfWeek;\nproto.dayOfYear  = getSetDayOfYear;\n\n// Hour\nproto.hour = proto.hours = getSetHour;\n\n// Minute\nproto.minute = proto.minutes = getSetMinute;\n\n// Second\nproto.second = proto.seconds = getSetSecond;\n\n// Millisecond\nproto.millisecond = proto.milliseconds = getSetMillisecond;\n\n// Offset\nproto.utcOffset            = getSetOffset;\nproto.utc                  = setOffsetToUTC;\nproto.local                = setOffsetToLocal;\nproto.parseZone            = setOffsetToParsedOffset;\nproto.hasAlignedHourOffset = hasAlignedHourOffset;\nproto.isDST                = isDaylightSavingTime;\nproto.isLocal              = isLocal;\nproto.isUtcOffset          = isUtcOffset;\nproto.isUtc                = isUtc;\nproto.isUTC                = isUtc;\n\n// Timezone\nproto.zoneAbbr = getZoneAbbr;\nproto.zoneName = getZoneName;\n\n// Deprecations\nproto.dates  = deprecate('dates accessor is deprecated. Use date instead.', getSetDayOfMonth);\nproto.months = deprecate('months accessor is deprecated. Use month instead', getSetMonth);\nproto.years  = deprecate('years accessor is deprecated. Use year instead', getSetYear);\nproto.zone   = deprecate('moment().zone is deprecated, use moment().utcOffset instead. http://momentjs.com/guides/#/warnings/zone/', getSetZone);\nproto.isDSTShifted = deprecate('isDSTShifted is deprecated. See http://momentjs.com/guides/#/warnings/dst-shifted/ for more information', isDaylightSavingTimeShifted);\n\nfunction createUnix (input) {\n    return createLocal(input * 1000);\n}\n\nfunction createInZone () {\n    return createLocal.apply(null, arguments).parseZone();\n}\n\nfunction preParsePostFormat (string) {\n    return string;\n}\n\nvar proto$1 = Locale.prototype;\n\nproto$1.calendar        = calendar;\nproto$1.longDateFormat  = longDateFormat;\nproto$1.invalidDate     = invalidDate;\nproto$1.ordinal         = ordinal;\nproto$1.preparse        = preParsePostFormat;\nproto$1.postformat      = preParsePostFormat;\nproto$1.relativeTime    = relativeTime;\nproto$1.pastFuture      = pastFuture;\nproto$1.set             = set;\n\n// Month\nproto$1.months            =        localeMonths;\nproto$1.monthsShort       =        localeMonthsShort;\nproto$1.monthsParse       =        localeMonthsParse;\nproto$1.monthsRegex       = monthsRegex;\nproto$1.monthsShortRegex  = monthsShortRegex;\n\n// Week\nproto$1.week = localeWeek;\nproto$1.firstDayOfYear = localeFirstDayOfYear;\nproto$1.firstDayOfWeek = localeFirstDayOfWeek;\n\n// Day of Week\nproto$1.weekdays       =        localeWeekdays;\nproto$1.weekdaysMin    =        localeWeekdaysMin;\nproto$1.weekdaysShort  =        localeWeekdaysShort;\nproto$1.weekdaysParse  =        localeWeekdaysParse;\n\nproto$1.weekdaysRegex       =        weekdaysRegex;\nproto$1.weekdaysShortRegex  =        weekdaysShortRegex;\nproto$1.weekdaysMinRegex    =        weekdaysMinRegex;\n\n// Hours\nproto$1.isPM = localeIsPM;\nproto$1.meridiem = localeMeridiem;\n\nfunction get$1 (format, index, field, setter) {\n    var locale = getLocale();\n    var utc = createUTC().set(setter, index);\n    return locale[field](utc, format);\n}\n\nfunction listMonthsImpl (format, index, field) {\n    if (isNumber(format)) {\n        index = format;\n        format = undefined;\n    }\n\n    format = format || '';\n\n    if (index != null) {\n        return get$1(format, index, field, 'month');\n    }\n\n    var i;\n    var out = [];\n    for (i = 0; i < 12; i++) {\n        out[i] = get$1(format, i, field, 'month');\n    }\n    return out;\n}\n\n// ()\n// (5)\n// (fmt, 5)\n// (fmt)\n// (true)\n// (true, 5)\n// (true, fmt, 5)\n// (true, fmt)\nfunction listWeekdaysImpl (localeSorted, format, index, field) {\n    if (typeof localeSorted === 'boolean') {\n        if (isNumber(format)) {\n            index = format;\n            format = undefined;\n        }\n\n        format = format || '';\n    } else {\n        format = localeSorted;\n        index = format;\n        localeSorted = false;\n\n        if (isNumber(format)) {\n            index = format;\n            format = undefined;\n        }\n\n        format = format || '';\n    }\n\n    var locale = getLocale(),\n        shift = localeSorted ? locale._week.dow : 0;\n\n    if (index != null) {\n        return get$1(format, (index + shift) % 7, field, 'day');\n    }\n\n    var i;\n    var out = [];\n    for (i = 0; i < 7; i++) {\n        out[i] = get$1(format, (i + shift) % 7, field, 'day');\n    }\n    return out;\n}\n\nfunction listMonths (format, index) {\n    return listMonthsImpl(format, index, 'months');\n}\n\nfunction listMonthsShort (format, index) {\n    return listMonthsImpl(format, index, 'monthsShort');\n}\n\nfunction listWeekdays (localeSorted, format, index) {\n    return listWeekdaysImpl(localeSorted, format, index, 'weekdays');\n}\n\nfunction listWeekdaysShort (localeSorted, format, index) {\n    return listWeekdaysImpl(localeSorted, format, index, 'weekdaysShort');\n}\n\nfunction listWeekdaysMin (localeSorted, format, index) {\n    return listWeekdaysImpl(localeSorted, format, index, 'weekdaysMin');\n}\n\ngetSetGlobalLocale('en', {\n    dayOfMonthOrdinalParse: /\\d{1,2}(th|st|nd|rd)/,\n    ordinal : function (number) {\n        var b = number % 10,\n            output = (toInt(number % 100 / 10) === 1) ? 'th' :\n            (b === 1) ? 'st' :\n            (b === 2) ? 'nd' :\n            (b === 3) ? 'rd' : 'th';\n        return number + output;\n    }\n});\n\n// Side effect imports\nhooks.lang = deprecate('moment.lang is deprecated. Use moment.locale instead.', getSetGlobalLocale);\nhooks.langData = deprecate('moment.langData is deprecated. Use moment.localeData instead.', getLocale);\n\nvar mathAbs = Math.abs;\n\nfunction abs () {\n    var data           = this._data;\n\n    this._milliseconds = mathAbs(this._milliseconds);\n    this._days         = mathAbs(this._days);\n    this._months       = mathAbs(this._months);\n\n    data.milliseconds  = mathAbs(data.milliseconds);\n    data.seconds       = mathAbs(data.seconds);\n    data.minutes       = mathAbs(data.minutes);\n    data.hours         = mathAbs(data.hours);\n    data.months        = mathAbs(data.months);\n    data.years         = mathAbs(data.years);\n\n    return this;\n}\n\nfunction addSubtract$1 (duration, input, value, direction) {\n    var other = createDuration(input, value);\n\n    duration._milliseconds += direction * other._milliseconds;\n    duration._days         += direction * other._days;\n    duration._months       += direction * other._months;\n\n    return duration._bubble();\n}\n\n// supports only 2.0-style add(1, 's') or add(duration)\nfunction add$1 (input, value) {\n    return addSubtract$1(this, input, value, 1);\n}\n\n// supports only 2.0-style subtract(1, 's') or subtract(duration)\nfunction subtract$1 (input, value) {\n    return addSubtract$1(this, input, value, -1);\n}\n\nfunction absCeil (number) {\n    if (number < 0) {\n        return Math.floor(number);\n    } else {\n        return Math.ceil(number);\n    }\n}\n\nfunction bubble () {\n    var milliseconds = this._milliseconds;\n    var days         = this._days;\n    var months       = this._months;\n    var data         = this._data;\n    var seconds, minutes, hours, years, monthsFromDays;\n\n    // if we have a mix of positive and negative values, bubble down first\n    // check: https://github.com/moment/moment/issues/2166\n    if (!((milliseconds >= 0 && days >= 0 && months >= 0) ||\n            (milliseconds <= 0 && days <= 0 && months <= 0))) {\n        milliseconds += absCeil(monthsToDays(months) + days) * 864e5;\n        days = 0;\n        months = 0;\n    }\n\n    // The following code bubbles up values, see the tests for\n    // examples of what that means.\n    data.milliseconds = milliseconds % 1000;\n\n    seconds           = absFloor(milliseconds / 1000);\n    data.seconds      = seconds % 60;\n\n    minutes           = absFloor(seconds / 60);\n    data.minutes      = minutes % 60;\n\n    hours             = absFloor(minutes / 60);\n    data.hours        = hours % 24;\n\n    days += absFloor(hours / 24);\n\n    // convert days to months\n    monthsFromDays = absFloor(daysToMonths(days));\n    months += monthsFromDays;\n    days -= absCeil(monthsToDays(monthsFromDays));\n\n    // 12 months -> 1 year\n    years = absFloor(months / 12);\n    months %= 12;\n\n    data.days   = days;\n    data.months = months;\n    data.years  = years;\n\n    return this;\n}\n\nfunction daysToMonths (days) {\n    // 400 years have 146097 days (taking into account leap year rules)\n    // 400 years have 12 months === 4800\n    return days * 4800 / 146097;\n}\n\nfunction monthsToDays (months) {\n    // the reverse of daysToMonths\n    return months * 146097 / 4800;\n}\n\nfunction as (units) {\n    if (!this.isValid()) {\n        return NaN;\n    }\n    var days;\n    var months;\n    var milliseconds = this._milliseconds;\n\n    units = normalizeUnits(units);\n\n    if (units === 'month' || units === 'year') {\n        days   = this._days   + milliseconds / 864e5;\n        months = this._months + daysToMonths(days);\n        return units === 'month' ? months : months / 12;\n    } else {\n        // handle milliseconds separately because of floating point math errors (issue #1867)\n        days = this._days + Math.round(monthsToDays(this._months));\n        switch (units) {\n            case 'week'   : return days / 7     + milliseconds / 6048e5;\n            case 'day'    : return days         + milliseconds / 864e5;\n            case 'hour'   : return days * 24    + milliseconds / 36e5;\n            case 'minute' : return days * 1440  + milliseconds / 6e4;\n            case 'second' : return days * 86400 + milliseconds / 1000;\n            // Math.floor prevents floating point math errors here\n            case 'millisecond': return Math.floor(days * 864e5) + milliseconds;\n            default: throw new Error('Unknown unit ' + units);\n        }\n    }\n}\n\n// TODO: Use this.as('ms')?\nfunction valueOf$1 () {\n    if (!this.isValid()) {\n        return NaN;\n    }\n    return (\n        this._milliseconds +\n        this._days * 864e5 +\n        (this._months % 12) * 2592e6 +\n        toInt(this._months / 12) * 31536e6\n    );\n}\n\nfunction makeAs (alias) {\n    return function () {\n        return this.as(alias);\n    };\n}\n\nvar asMilliseconds = makeAs('ms');\nvar asSeconds      = makeAs('s');\nvar asMinutes      = makeAs('m');\nvar asHours        = makeAs('h');\nvar asDays         = makeAs('d');\nvar asWeeks        = makeAs('w');\nvar asMonths       = makeAs('M');\nvar asYears        = makeAs('y');\n\nfunction get$2 (units) {\n    units = normalizeUnits(units);\n    return this.isValid() ? this[units + 's']() : NaN;\n}\n\nfunction makeGetter(name) {\n    return function () {\n        return this.isValid() ? this._data[name] : NaN;\n    };\n}\n\nvar milliseconds = makeGetter('milliseconds');\nvar seconds      = makeGetter('seconds');\nvar minutes      = makeGetter('minutes');\nvar hours        = makeGetter('hours');\nvar days         = makeGetter('days');\nvar months       = makeGetter('months');\nvar years        = makeGetter('years');\n\nfunction weeks () {\n    return absFloor(this.days() / 7);\n}\n\nvar round = Math.round;\nvar thresholds = {\n    ss: 44,         // a few seconds to seconds\n    s : 45,         // seconds to minute\n    m : 45,         // minutes to hour\n    h : 22,         // hours to day\n    d : 26,         // days to month\n    M : 11          // months to year\n};\n\n// helper function for moment.fn.from, moment.fn.fromNow, and moment.duration.fn.humanize\nfunction substituteTimeAgo(string, number, withoutSuffix, isFuture, locale) {\n    return locale.relativeTime(number || 1, !!withoutSuffix, string, isFuture);\n}\n\nfunction relativeTime$1 (posNegDuration, withoutSuffix, locale) {\n    var duration = createDuration(posNegDuration).abs();\n    var seconds  = round(duration.as('s'));\n    var minutes  = round(duration.as('m'));\n    var hours    = round(duration.as('h'));\n    var days     = round(duration.as('d'));\n    var months   = round(duration.as('M'));\n    var years    = round(duration.as('y'));\n\n    var a = seconds <= thresholds.ss && ['s', seconds]  ||\n            seconds < thresholds.s   && ['ss', seconds] ||\n            minutes <= 1             && ['m']           ||\n            minutes < thresholds.m   && ['mm', minutes] ||\n            hours   <= 1             && ['h']           ||\n            hours   < thresholds.h   && ['hh', hours]   ||\n            days    <= 1             && ['d']           ||\n            days    < thresholds.d   && ['dd', days]    ||\n            months  <= 1             && ['M']           ||\n            months  < thresholds.M   && ['MM', months]  ||\n            years   <= 1             && ['y']           || ['yy', years];\n\n    a[2] = withoutSuffix;\n    a[3] = +posNegDuration > 0;\n    a[4] = locale;\n    return substituteTimeAgo.apply(null, a);\n}\n\n// This function allows you to set the rounding function for relative time strings\nfunction getSetRelativeTimeRounding (roundingFunction) {\n    if (roundingFunction === undefined) {\n        return round;\n    }\n    if (typeof(roundingFunction) === 'function') {\n        round = roundingFunction;\n        return true;\n    }\n    return false;\n}\n\n// This function allows you to set a threshold for relative time strings\nfunction getSetRelativeTimeThreshold (threshold, limit) {\n    if (thresholds[threshold] === undefined) {\n        return false;\n    }\n    if (limit === undefined) {\n        return thresholds[threshold];\n    }\n    thresholds[threshold] = limit;\n    if (threshold === 's') {\n        thresholds.ss = limit - 1;\n    }\n    return true;\n}\n\nfunction humanize (withSuffix) {\n    if (!this.isValid()) {\n        return this.localeData().invalidDate();\n    }\n\n    var locale = this.localeData();\n    var output = relativeTime$1(this, !withSuffix, locale);\n\n    if (withSuffix) {\n        output = locale.pastFuture(+this, output);\n    }\n\n    return locale.postformat(output);\n}\n\nvar abs$1 = Math.abs;\n\nfunction toISOString$1() {\n    // for ISO strings we do not use the normal bubbling rules:\n    //  * milliseconds bubble up until they become hours\n    //  * days do not bubble at all\n    //  * months bubble up until they become years\n    // This is because there is no context-free conversion between hours and days\n    // (think of clock changes)\n    // and also not between days and months (28-31 days per month)\n    if (!this.isValid()) {\n        return this.localeData().invalidDate();\n    }\n\n    var seconds = abs$1(this._milliseconds) / 1000;\n    var days         = abs$1(this._days);\n    var months       = abs$1(this._months);\n    var minutes, hours, years;\n\n    // 3600 seconds -> 60 minutes -> 1 hour\n    minutes           = absFloor(seconds / 60);\n    hours             = absFloor(minutes / 60);\n    seconds %= 60;\n    minutes %= 60;\n\n    // 12 months -> 1 year\n    years  = absFloor(months / 12);\n    months %= 12;\n\n\n    // inspired by https://github.com/dordille/moment-isoduration/blob/master/moment.isoduration.js\n    var Y = years;\n    var M = months;\n    var D = days;\n    var h = hours;\n    var m = minutes;\n    var s = seconds;\n    var total = this.asSeconds();\n\n    if (!total) {\n        // this is the same as C#'s (Noda) and python (isodate)...\n        // but not other JS (goog.date)\n        return 'P0D';\n    }\n\n    return (total < 0 ? '-' : '') +\n        'P' +\n        (Y ? Y + 'Y' : '') +\n        (M ? M + 'M' : '') +\n        (D ? D + 'D' : '') +\n        ((h || m || s) ? 'T' : '') +\n        (h ? h + 'H' : '') +\n        (m ? m + 'M' : '') +\n        (s ? s + 'S' : '');\n}\n\nvar proto$2 = Duration.prototype;\n\nproto$2.isValid        = isValid$1;\nproto$2.abs            = abs;\nproto$2.add            = add$1;\nproto$2.subtract       = subtract$1;\nproto$2.as             = as;\nproto$2.asMilliseconds = asMilliseconds;\nproto$2.asSeconds      = asSeconds;\nproto$2.asMinutes      = asMinutes;\nproto$2.asHours        = asHours;\nproto$2.asDays         = asDays;\nproto$2.asWeeks        = asWeeks;\nproto$2.asMonths       = asMonths;\nproto$2.asYears        = asYears;\nproto$2.valueOf        = valueOf$1;\nproto$2._bubble        = bubble;\nproto$2.get            = get$2;\nproto$2.milliseconds   = milliseconds;\nproto$2.seconds        = seconds;\nproto$2.minutes        = minutes;\nproto$2.hours          = hours;\nproto$2.days           = days;\nproto$2.weeks          = weeks;\nproto$2.months         = months;\nproto$2.years          = years;\nproto$2.humanize       = humanize;\nproto$2.toISOString    = toISOString$1;\nproto$2.toString       = toISOString$1;\nproto$2.toJSON         = toISOString$1;\nproto$2.locale         = locale;\nproto$2.localeData     = localeData;\n\n// Deprecations\nproto$2.toIsoString = deprecate('toIsoString() is deprecated. Please use toISOString() instead (notice the capitals)', toISOString$1);\nproto$2.lang = lang;\n\n// Side effect imports\n\n// FORMATTING\n\naddFormatToken('X', 0, 0, 'unix');\naddFormatToken('x', 0, 0, 'valueOf');\n\n// PARSING\n\naddRegexToken('x', matchSigned);\naddRegexToken('X', matchTimestamp);\naddParseToken('X', function (input, array, config) {\n    config._d = new Date(parseFloat(input, 10) * 1000);\n});\naddParseToken('x', function (input, array, config) {\n    config._d = new Date(toInt(input));\n});\n\n// Side effect imports\n\n\nhooks.version = '2.18.1';\n\nsetHookCallback(createLocal);\n\nhooks.fn                    = proto;\nhooks.min                   = min;\nhooks.max                   = max;\nhooks.now                   = now;\nhooks.utc                   = createUTC;\nhooks.unix                  = createUnix;\nhooks.months                = listMonths;\nhooks.isDate                = isDate;\nhooks.locale                = getSetGlobalLocale;\nhooks.invalid               = createInvalid;\nhooks.duration              = createDuration;\nhooks.isMoment              = isMoment;\nhooks.weekdays              = listWeekdays;\nhooks.parseZone             = createInZone;\nhooks.localeData            = getLocale;\nhooks.isDuration            = isDuration;\nhooks.monthsShort           = listMonthsShort;\nhooks.weekdaysMin           = listWeekdaysMin;\nhooks.defineLocale          = defineLocale;\nhooks.updateLocale          = updateLocale;\nhooks.locales               = listLocales;\nhooks.weekdaysShort         = listWeekdaysShort;\nhooks.normalizeUnits        = normalizeUnits;\nhooks.relativeTimeRounding = getSetRelativeTimeRounding;\nhooks.relativeTimeThreshold = getSetRelativeTimeThreshold;\nhooks.calendarFormat        = getCalendarFormat;\nhooks.prototype             = proto;\n\nreturn hooks;\n\n})));\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/meteor/package.js",
    "content": "// package metadata file for Meteor.js\n'use strict';\n\nvar packageName = 'momentjs:moment';  // https://atmospherejs.com/momentjs/moment\n\nPackage.describe({\n  name: packageName,\n  summary: 'Moment.js (official): parse, validate, manipulate, and display dates - official Meteor packaging',\n  version: '2.18.1',\n  git: 'https://github.com/moment/moment.git'\n});\n\nPackage.onUse(function (api) {\n  api.versionsFrom(['METEOR@0.9.0', 'METEOR@1.0', 'METEOR@1.2']);\n  api.export('moment');\n  api.addFiles([\n    'moment.js',\n    'export.js'\n  ]);\n});\n\nPackage.onTest(function (api) {\n  api.use(packageName);\n  api.use('tinytest');\n\n  api.addFiles('test.js');\n});\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/meteor/test.js",
    "content": "'use strict';\n\nTinytest.add('Moment.is', function (test) {\n  test.ok(moment.isMoment(moment()), {message: 'simple moment object'});\n});\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/min/locales.js",
    "content": ";(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\n//! moment.js locale configuration\n//! locale : Afrikaans [af]\n//! author : Werner Mollentze : https://github.com/wernerm\n\nmoment.defineLocale('af', {\n    months : 'Januarie_Februarie_Maart_April_Mei_Junie_Julie_Augustus_September_Oktober_November_Desember'.split('_'),\n    monthsShort : 'Jan_Feb_Mrt_Apr_Mei_Jun_Jul_Aug_Sep_Okt_Nov_Des'.split('_'),\n    weekdays : 'Sondag_Maandag_Dinsdag_Woensdag_Donderdag_Vrydag_Saterdag'.split('_'),\n    weekdaysShort : 'Son_Maa_Din_Woe_Don_Vry_Sat'.split('_'),\n    weekdaysMin : 'So_Ma_Di_Wo_Do_Vr_Sa'.split('_'),\n    meridiemParse: /vm|nm/i,\n    isPM : function (input) {\n        return /^nm$/i.test(input);\n    },\n    meridiem : function (hours, minutes, isLower) {\n        if (hours < 12) {\n            return isLower ? 'vm' : 'VM';\n        } else {\n            return isLower ? 'nm' : 'NM';\n        }\n    },\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY HH:mm',\n        LLLL : 'dddd, D MMMM YYYY HH:mm'\n    },\n    calendar : {\n        sameDay : '[Vandag om] LT',\n        nextDay : '[Môre om] LT',\n        nextWeek : 'dddd [om] LT',\n        lastDay : '[Gister om] LT',\n        lastWeek : '[Laas] dddd [om] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'oor %s',\n        past : '%s gelede',\n        s : '\\'n paar sekondes',\n        m : '\\'n minuut',\n        mm : '%d minute',\n        h : '\\'n uur',\n        hh : '%d ure',\n        d : '\\'n dag',\n        dd : '%d dae',\n        M : '\\'n maand',\n        MM : '%d maande',\n        y : '\\'n jaar',\n        yy : '%d jaar'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}(ste|de)/,\n    ordinal : function (number) {\n        return number + ((number === 1 || number === 8 || number >= 20) ? 'ste' : 'de'); // Thanks to Joris Röling : https://github.com/jjupiter\n    },\n    week : {\n        dow : 1, // Maandag is die eerste dag van die week.\n        doy : 4  // Die week wat die 4de Januarie bevat is die eerste week van die jaar.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Arabic (Algeria) [ar-dz]\n//! author : Noureddine LOUAHEDJ : https://github.com/noureddineme\n\nmoment.defineLocale('ar-dz', {\n    months : 'جانفي_فيفري_مارس_أفريل_ماي_جوان_جويلية_أوت_سبتمبر_أكتوبر_نوفمبر_ديسمبر'.split('_'),\n    monthsShort : 'جانفي_فيفري_مارس_أفريل_ماي_جوان_جويلية_أوت_سبتمبر_أكتوبر_نوفمبر_ديسمبر'.split('_'),\n    weekdays : 'الأحد_الإثنين_الثلاثاء_الأربعاء_الخميس_الجمعة_السبت'.split('_'),\n    weekdaysShort : 'احد_اثنين_ثلاثاء_اربعاء_خميس_جمعة_سبت'.split('_'),\n    weekdaysMin : 'أح_إث_ثلا_أر_خم_جم_سب'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY HH:mm',\n        LLLL : 'dddd D MMMM YYYY HH:mm'\n    },\n    calendar : {\n        sameDay: '[اليوم على الساعة] LT',\n        nextDay: '[غدا على الساعة] LT',\n        nextWeek: 'dddd [على الساعة] LT',\n        lastDay: '[أمس على الساعة] LT',\n        lastWeek: 'dddd [على الساعة] LT',\n        sameElse: 'L'\n    },\n    relativeTime : {\n        future : 'في %s',\n        past : 'منذ %s',\n        s : 'ثوان',\n        m : 'دقيقة',\n        mm : '%d دقائق',\n        h : 'ساعة',\n        hh : '%d ساعات',\n        d : 'يوم',\n        dd : '%d أيام',\n        M : 'شهر',\n        MM : '%d أشهر',\n        y : 'سنة',\n        yy : '%d سنوات'\n    },\n    week : {\n        dow : 0, // Sunday is the first day of the week.\n        doy : 4  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Arabic (Kuwait) [ar-kw]\n//! author : Nusret Parlak: https://github.com/nusretparlak\n\nmoment.defineLocale('ar-kw', {\n    months : 'يناير_فبراير_مارس_أبريل_ماي_يونيو_يوليوز_غشت_شتنبر_أكتوبر_نونبر_دجنبر'.split('_'),\n    monthsShort : 'يناير_فبراير_مارس_أبريل_ماي_يونيو_يوليوز_غشت_شتنبر_أكتوبر_نونبر_دجنبر'.split('_'),\n    weekdays : 'الأحد_الإتنين_الثلاثاء_الأربعاء_الخميس_الجمعة_السبت'.split('_'),\n    weekdaysShort : 'احد_اتنين_ثلاثاء_اربعاء_خميس_جمعة_سبت'.split('_'),\n    weekdaysMin : 'ح_ن_ث_ر_خ_ج_س'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY HH:mm',\n        LLLL : 'dddd D MMMM YYYY HH:mm'\n    },\n    calendar : {\n        sameDay: '[اليوم على الساعة] LT',\n        nextDay: '[غدا على الساعة] LT',\n        nextWeek: 'dddd [على الساعة] LT',\n        lastDay: '[أمس على الساعة] LT',\n        lastWeek: 'dddd [على الساعة] LT',\n        sameElse: 'L'\n    },\n    relativeTime : {\n        future : 'في %s',\n        past : 'منذ %s',\n        s : 'ثوان',\n        m : 'دقيقة',\n        mm : '%d دقائق',\n        h : 'ساعة',\n        hh : '%d ساعات',\n        d : 'يوم',\n        dd : '%d أيام',\n        M : 'شهر',\n        MM : '%d أشهر',\n        y : 'سنة',\n        yy : '%d سنوات'\n    },\n    week : {\n        dow : 0, // Sunday is the first day of the week.\n        doy : 12  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Arabic (Lybia) [ar-ly]\n//! author : Ali Hmer: https://github.com/kikoanis\n\nvar symbolMap = {\n    '1': '1',\n    '2': '2',\n    '3': '3',\n    '4': '4',\n    '5': '5',\n    '6': '6',\n    '7': '7',\n    '8': '8',\n    '9': '9',\n    '0': '0'\n};\nvar pluralForm = function (n) {\n    return n === 0 ? 0 : n === 1 ? 1 : n === 2 ? 2 : n % 100 >= 3 && n % 100 <= 10 ? 3 : n % 100 >= 11 ? 4 : 5;\n};\nvar plurals = {\n    s : ['أقل من ثانية', 'ثانية واحدة', ['ثانيتان', 'ثانيتين'], '%d ثوان', '%d ثانية', '%d ثانية'],\n    m : ['أقل من دقيقة', 'دقيقة واحدة', ['دقيقتان', 'دقيقتين'], '%d دقائق', '%d دقيقة', '%d دقيقة'],\n    h : ['أقل من ساعة', 'ساعة واحدة', ['ساعتان', 'ساعتين'], '%d ساعات', '%d ساعة', '%d ساعة'],\n    d : ['أقل من يوم', 'يوم واحد', ['يومان', 'يومين'], '%d أيام', '%d يومًا', '%d يوم'],\n    M : ['أقل من شهر', 'شهر واحد', ['شهران', 'شهرين'], '%d أشهر', '%d شهرا', '%d شهر'],\n    y : ['أقل من عام', 'عام واحد', ['عامان', 'عامين'], '%d أعوام', '%d عامًا', '%d عام']\n};\nvar pluralize = function (u) {\n    return function (number, withoutSuffix, string, isFuture) {\n        var f = pluralForm(number),\n            str = plurals[u][pluralForm(number)];\n        if (f === 2) {\n            str = str[withoutSuffix ? 0 : 1];\n        }\n        return str.replace(/%d/i, number);\n    };\n};\nvar months = [\n    'يناير',\n    'فبراير',\n    'مارس',\n    'أبريل',\n    'مايو',\n    'يونيو',\n    'يوليو',\n    'أغسطس',\n    'سبتمبر',\n    'أكتوبر',\n    'نوفمبر',\n    'ديسمبر'\n];\n\nmoment.defineLocale('ar-ly', {\n    months : months,\n    monthsShort : months,\n    weekdays : 'الأحد_الإثنين_الثلاثاء_الأربعاء_الخميس_الجمعة_السبت'.split('_'),\n    weekdaysShort : 'أحد_إثنين_ثلاثاء_أربعاء_خميس_جمعة_سبت'.split('_'),\n    weekdaysMin : 'ح_ن_ث_ر_خ_ج_س'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'D/\\u200FM/\\u200FYYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY HH:mm',\n        LLLL : 'dddd D MMMM YYYY HH:mm'\n    },\n    meridiemParse: /ص|م/,\n    isPM : function (input) {\n        return 'م' === input;\n    },\n    meridiem : function (hour, minute, isLower) {\n        if (hour < 12) {\n            return 'ص';\n        } else {\n            return 'م';\n        }\n    },\n    calendar : {\n        sameDay: '[اليوم عند الساعة] LT',\n        nextDay: '[غدًا عند الساعة] LT',\n        nextWeek: 'dddd [عند الساعة] LT',\n        lastDay: '[أمس عند الساعة] LT',\n        lastWeek: 'dddd [عند الساعة] LT',\n        sameElse: 'L'\n    },\n    relativeTime : {\n        future : 'بعد %s',\n        past : 'منذ %s',\n        s : pluralize('s'),\n        m : pluralize('m'),\n        mm : pluralize('m'),\n        h : pluralize('h'),\n        hh : pluralize('h'),\n        d : pluralize('d'),\n        dd : pluralize('d'),\n        M : pluralize('M'),\n        MM : pluralize('M'),\n        y : pluralize('y'),\n        yy : pluralize('y')\n    },\n    preparse: function (string) {\n        return string.replace(/\\u200f/g, '').replace(/،/g, ',');\n    },\n    postformat: function (string) {\n        return string.replace(/\\d/g, function (match) {\n            return symbolMap[match];\n        }).replace(/,/g, '،');\n    },\n    week : {\n        dow : 6, // Saturday is the first day of the week.\n        doy : 12  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Arabic (Morocco) [ar-ma]\n//! author : ElFadili Yassine : https://github.com/ElFadiliY\n//! author : Abdel Said : https://github.com/abdelsaid\n\nmoment.defineLocale('ar-ma', {\n    months : 'يناير_فبراير_مارس_أبريل_ماي_يونيو_يوليوز_غشت_شتنبر_أكتوبر_نونبر_دجنبر'.split('_'),\n    monthsShort : 'يناير_فبراير_مارس_أبريل_ماي_يونيو_يوليوز_غشت_شتنبر_أكتوبر_نونبر_دجنبر'.split('_'),\n    weekdays : 'الأحد_الإتنين_الثلاثاء_الأربعاء_الخميس_الجمعة_السبت'.split('_'),\n    weekdaysShort : 'احد_اتنين_ثلاثاء_اربعاء_خميس_جمعة_سبت'.split('_'),\n    weekdaysMin : 'ح_ن_ث_ر_خ_ج_س'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY HH:mm',\n        LLLL : 'dddd D MMMM YYYY HH:mm'\n    },\n    calendar : {\n        sameDay: '[اليوم على الساعة] LT',\n        nextDay: '[غدا على الساعة] LT',\n        nextWeek: 'dddd [على الساعة] LT',\n        lastDay: '[أمس على الساعة] LT',\n        lastWeek: 'dddd [على الساعة] LT',\n        sameElse: 'L'\n    },\n    relativeTime : {\n        future : 'في %s',\n        past : 'منذ %s',\n        s : 'ثوان',\n        m : 'دقيقة',\n        mm : '%d دقائق',\n        h : 'ساعة',\n        hh : '%d ساعات',\n        d : 'يوم',\n        dd : '%d أيام',\n        M : 'شهر',\n        MM : '%d أشهر',\n        y : 'سنة',\n        yy : '%d سنوات'\n    },\n    week : {\n        dow : 6, // Saturday is the first day of the week.\n        doy : 12  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Arabic (Saudi Arabia) [ar-sa]\n//! author : Suhail Alkowaileet : https://github.com/xsoh\n\nvar symbolMap$1 = {\n    '1': '١',\n    '2': '٢',\n    '3': '٣',\n    '4': '٤',\n    '5': '٥',\n    '6': '٦',\n    '7': '٧',\n    '8': '٨',\n    '9': '٩',\n    '0': '٠'\n};\nvar numberMap = {\n    '١': '1',\n    '٢': '2',\n    '٣': '3',\n    '٤': '4',\n    '٥': '5',\n    '٦': '6',\n    '٧': '7',\n    '٨': '8',\n    '٩': '9',\n    '٠': '0'\n};\n\nmoment.defineLocale('ar-sa', {\n    months : 'يناير_فبراير_مارس_أبريل_مايو_يونيو_يوليو_أغسطس_سبتمبر_أكتوبر_نوفمبر_ديسمبر'.split('_'),\n    monthsShort : 'يناير_فبراير_مارس_أبريل_مايو_يونيو_يوليو_أغسطس_سبتمبر_أكتوبر_نوفمبر_ديسمبر'.split('_'),\n    weekdays : 'الأحد_الإثنين_الثلاثاء_الأربعاء_الخميس_الجمعة_السبت'.split('_'),\n    weekdaysShort : 'أحد_إثنين_ثلاثاء_أربعاء_خميس_جمعة_سبت'.split('_'),\n    weekdaysMin : 'ح_ن_ث_ر_خ_ج_س'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY HH:mm',\n        LLLL : 'dddd D MMMM YYYY HH:mm'\n    },\n    meridiemParse: /ص|م/,\n    isPM : function (input) {\n        return 'م' === input;\n    },\n    meridiem : function (hour, minute, isLower) {\n        if (hour < 12) {\n            return 'ص';\n        } else {\n            return 'م';\n        }\n    },\n    calendar : {\n        sameDay: '[اليوم على الساعة] LT',\n        nextDay: '[غدا على الساعة] LT',\n        nextWeek: 'dddd [على الساعة] LT',\n        lastDay: '[أمس على الساعة] LT',\n        lastWeek: 'dddd [على الساعة] LT',\n        sameElse: 'L'\n    },\n    relativeTime : {\n        future : 'في %s',\n        past : 'منذ %s',\n        s : 'ثوان',\n        m : 'دقيقة',\n        mm : '%d دقائق',\n        h : 'ساعة',\n        hh : '%d ساعات',\n        d : 'يوم',\n        dd : '%d أيام',\n        M : 'شهر',\n        MM : '%d أشهر',\n        y : 'سنة',\n        yy : '%d سنوات'\n    },\n    preparse: function (string) {\n        return string.replace(/[١٢٣٤٥٦٧٨٩٠]/g, function (match) {\n            return numberMap[match];\n        }).replace(/،/g, ',');\n    },\n    postformat: function (string) {\n        return string.replace(/\\d/g, function (match) {\n            return symbolMap$1[match];\n        }).replace(/,/g, '،');\n    },\n    week : {\n        dow : 0, // Sunday is the first day of the week.\n        doy : 6  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale  :  Arabic (Tunisia) [ar-tn]\n//! author : Nader Toukabri : https://github.com/naderio\n\nmoment.defineLocale('ar-tn', {\n    months: 'جانفي_فيفري_مارس_أفريل_ماي_جوان_جويلية_أوت_سبتمبر_أكتوبر_نوفمبر_ديسمبر'.split('_'),\n    monthsShort: 'جانفي_فيفري_مارس_أفريل_ماي_جوان_جويلية_أوت_سبتمبر_أكتوبر_نوفمبر_ديسمبر'.split('_'),\n    weekdays: 'الأحد_الإثنين_الثلاثاء_الأربعاء_الخميس_الجمعة_السبت'.split('_'),\n    weekdaysShort: 'أحد_إثنين_ثلاثاء_أربعاء_خميس_جمعة_سبت'.split('_'),\n    weekdaysMin: 'ح_ن_ث_ر_خ_ج_س'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat: {\n        LT: 'HH:mm',\n        LTS: 'HH:mm:ss',\n        L: 'DD/MM/YYYY',\n        LL: 'D MMMM YYYY',\n        LLL: 'D MMMM YYYY HH:mm',\n        LLLL: 'dddd D MMMM YYYY HH:mm'\n    },\n    calendar: {\n        sameDay: '[اليوم على الساعة] LT',\n        nextDay: '[غدا على الساعة] LT',\n        nextWeek: 'dddd [على الساعة] LT',\n        lastDay: '[أمس على الساعة] LT',\n        lastWeek: 'dddd [على الساعة] LT',\n        sameElse: 'L'\n    },\n    relativeTime: {\n        future: 'في %s',\n        past: 'منذ %s',\n        s: 'ثوان',\n        m: 'دقيقة',\n        mm: '%d دقائق',\n        h: 'ساعة',\n        hh: '%d ساعات',\n        d: 'يوم',\n        dd: '%d أيام',\n        M: 'شهر',\n        MM: '%d أشهر',\n        y: 'سنة',\n        yy: '%d سنوات'\n    },\n    week: {\n        dow: 1, // Monday is the first day of the week.\n        doy: 4 // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Arabic [ar]\n//! author : Abdel Said: https://github.com/abdelsaid\n//! author : Ahmed Elkhatib\n//! author : forabi https://github.com/forabi\n\nvar symbolMap$2 = {\n    '1': '١',\n    '2': '٢',\n    '3': '٣',\n    '4': '٤',\n    '5': '٥',\n    '6': '٦',\n    '7': '٧',\n    '8': '٨',\n    '9': '٩',\n    '0': '٠'\n};\nvar numberMap$1 = {\n    '١': '1',\n    '٢': '2',\n    '٣': '3',\n    '٤': '4',\n    '٥': '5',\n    '٦': '6',\n    '٧': '7',\n    '٨': '8',\n    '٩': '9',\n    '٠': '0'\n};\nvar pluralForm$1 = function (n) {\n    return n === 0 ? 0 : n === 1 ? 1 : n === 2 ? 2 : n % 100 >= 3 && n % 100 <= 10 ? 3 : n % 100 >= 11 ? 4 : 5;\n};\nvar plurals$1 = {\n    s : ['أقل من ثانية', 'ثانية واحدة', ['ثانيتان', 'ثانيتين'], '%d ثوان', '%d ثانية', '%d ثانية'],\n    m : ['أقل من دقيقة', 'دقيقة واحدة', ['دقيقتان', 'دقيقتين'], '%d دقائق', '%d دقيقة', '%d دقيقة'],\n    h : ['أقل من ساعة', 'ساعة واحدة', ['ساعتان', 'ساعتين'], '%d ساعات', '%d ساعة', '%d ساعة'],\n    d : ['أقل من يوم', 'يوم واحد', ['يومان', 'يومين'], '%d أيام', '%d يومًا', '%d يوم'],\n    M : ['أقل من شهر', 'شهر واحد', ['شهران', 'شهرين'], '%d أشهر', '%d شهرا', '%d شهر'],\n    y : ['أقل من عام', 'عام واحد', ['عامان', 'عامين'], '%d أعوام', '%d عامًا', '%d عام']\n};\nvar pluralize$1 = function (u) {\n    return function (number, withoutSuffix, string, isFuture) {\n        var f = pluralForm$1(number),\n            str = plurals$1[u][pluralForm$1(number)];\n        if (f === 2) {\n            str = str[withoutSuffix ? 0 : 1];\n        }\n        return str.replace(/%d/i, number);\n    };\n};\nvar months$1 = [\n    'كانون الثاني يناير',\n    'شباط فبراير',\n    'آذار مارس',\n    'نيسان أبريل',\n    'أيار مايو',\n    'حزيران يونيو',\n    'تموز يوليو',\n    'آب أغسطس',\n    'أيلول سبتمبر',\n    'تشرين الأول أكتوبر',\n    'تشرين الثاني نوفمبر',\n    'كانون الأول ديسمبر'\n];\n\nmoment.defineLocale('ar', {\n    months : months$1,\n    monthsShort : months$1,\n    weekdays : 'الأحد_الإثنين_الثلاثاء_الأربعاء_الخميس_الجمعة_السبت'.split('_'),\n    weekdaysShort : 'أحد_إثنين_ثلاثاء_أربعاء_خميس_جمعة_سبت'.split('_'),\n    weekdaysMin : 'ح_ن_ث_ر_خ_ج_س'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'D/\\u200FM/\\u200FYYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY HH:mm',\n        LLLL : 'dddd D MMMM YYYY HH:mm'\n    },\n    meridiemParse: /ص|م/,\n    isPM : function (input) {\n        return 'م' === input;\n    },\n    meridiem : function (hour, minute, isLower) {\n        if (hour < 12) {\n            return 'ص';\n        } else {\n            return 'م';\n        }\n    },\n    calendar : {\n        sameDay: '[اليوم عند الساعة] LT',\n        nextDay: '[غدًا عند الساعة] LT',\n        nextWeek: 'dddd [عند الساعة] LT',\n        lastDay: '[أمس عند الساعة] LT',\n        lastWeek: 'dddd [عند الساعة] LT',\n        sameElse: 'L'\n    },\n    relativeTime : {\n        future : 'بعد %s',\n        past : 'منذ %s',\n        s : pluralize$1('s'),\n        m : pluralize$1('m'),\n        mm : pluralize$1('m'),\n        h : pluralize$1('h'),\n        hh : pluralize$1('h'),\n        d : pluralize$1('d'),\n        dd : pluralize$1('d'),\n        M : pluralize$1('M'),\n        MM : pluralize$1('M'),\n        y : pluralize$1('y'),\n        yy : pluralize$1('y')\n    },\n    preparse: function (string) {\n        return string.replace(/\\u200f/g, '').replace(/[١٢٣٤٥٦٧٨٩٠]/g, function (match) {\n            return numberMap$1[match];\n        }).replace(/،/g, ',');\n    },\n    postformat: function (string) {\n        return string.replace(/\\d/g, function (match) {\n            return symbolMap$2[match];\n        }).replace(/,/g, '،');\n    },\n    week : {\n        dow : 6, // Saturday is the first day of the week.\n        doy : 12  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Azerbaijani [az]\n//! author : topchiyev : https://github.com/topchiyev\n\nvar suffixes = {\n    1: '-inci',\n    5: '-inci',\n    8: '-inci',\n    70: '-inci',\n    80: '-inci',\n    2: '-nci',\n    7: '-nci',\n    20: '-nci',\n    50: '-nci',\n    3: '-üncü',\n    4: '-üncü',\n    100: '-üncü',\n    6: '-ncı',\n    9: '-uncu',\n    10: '-uncu',\n    30: '-uncu',\n    60: '-ıncı',\n    90: '-ıncı'\n};\n\nmoment.defineLocale('az', {\n    months : 'yanvar_fevral_mart_aprel_may_iyun_iyul_avqust_sentyabr_oktyabr_noyabr_dekabr'.split('_'),\n    monthsShort : 'yan_fev_mar_apr_may_iyn_iyl_avq_sen_okt_noy_dek'.split('_'),\n    weekdays : 'Bazar_Bazar ertəsi_Çərşənbə axşamı_Çərşənbə_Cümə axşamı_Cümə_Şənbə'.split('_'),\n    weekdaysShort : 'Baz_BzE_ÇAx_Çər_CAx_Cüm_Şən'.split('_'),\n    weekdaysMin : 'Bz_BE_ÇA_Çə_CA_Cü_Şə'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD.MM.YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY HH:mm',\n        LLLL : 'dddd, D MMMM YYYY HH:mm'\n    },\n    calendar : {\n        sameDay : '[bugün saat] LT',\n        nextDay : '[sabah saat] LT',\n        nextWeek : '[gələn həftə] dddd [saat] LT',\n        lastDay : '[dünən] LT',\n        lastWeek : '[keçən həftə] dddd [saat] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : '%s sonra',\n        past : '%s əvvəl',\n        s : 'birneçə saniyyə',\n        m : 'bir dəqiqə',\n        mm : '%d dəqiqə',\n        h : 'bir saat',\n        hh : '%d saat',\n        d : 'bir gün',\n        dd : '%d gün',\n        M : 'bir ay',\n        MM : '%d ay',\n        y : 'bir il',\n        yy : '%d il'\n    },\n    meridiemParse: /gecə|səhər|gündüz|axşam/,\n    isPM : function (input) {\n        return /^(gündüz|axşam)$/.test(input);\n    },\n    meridiem : function (hour, minute, isLower) {\n        if (hour < 4) {\n            return 'gecə';\n        } else if (hour < 12) {\n            return 'səhər';\n        } else if (hour < 17) {\n            return 'gündüz';\n        } else {\n            return 'axşam';\n        }\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}-(ıncı|inci|nci|üncü|ncı|uncu)/,\n    ordinal : function (number) {\n        if (number === 0) {  // special case for zero\n            return number + '-ıncı';\n        }\n        var a = number % 10,\n            b = number % 100 - a,\n            c = number >= 100 ? 100 : null;\n        return number + (suffixes[a] || suffixes[b] || suffixes[c]);\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 7  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Belarusian [be]\n//! author : Dmitry Demidov : https://github.com/demidov91\n//! author: Praleska: http://praleska.pro/\n//! Author : Menelion Elensúle : https://github.com/Oire\n\nfunction plural(word, num) {\n    var forms = word.split('_');\n    return num % 10 === 1 && num % 100 !== 11 ? forms[0] : (num % 10 >= 2 && num % 10 <= 4 && (num % 100 < 10 || num % 100 >= 20) ? forms[1] : forms[2]);\n}\nfunction relativeTimeWithPlural(number, withoutSuffix, key) {\n    var format = {\n        'mm': withoutSuffix ? 'хвіліна_хвіліны_хвілін' : 'хвіліну_хвіліны_хвілін',\n        'hh': withoutSuffix ? 'гадзіна_гадзіны_гадзін' : 'гадзіну_гадзіны_гадзін',\n        'dd': 'дзень_дні_дзён',\n        'MM': 'месяц_месяцы_месяцаў',\n        'yy': 'год_гады_гадоў'\n    };\n    if (key === 'm') {\n        return withoutSuffix ? 'хвіліна' : 'хвіліну';\n    }\n    else if (key === 'h') {\n        return withoutSuffix ? 'гадзіна' : 'гадзіну';\n    }\n    else {\n        return number + ' ' + plural(format[key], +number);\n    }\n}\n\nmoment.defineLocale('be', {\n    months : {\n        format: 'студзеня_лютага_сакавіка_красавіка_траўня_чэрвеня_ліпеня_жніўня_верасня_кастрычніка_лістапада_снежня'.split('_'),\n        standalone: 'студзень_люты_сакавік_красавік_травень_чэрвень_ліпень_жнівень_верасень_кастрычнік_лістапад_снежань'.split('_')\n    },\n    monthsShort : 'студ_лют_сак_крас_трав_чэрв_ліп_жнів_вер_каст_ліст_снеж'.split('_'),\n    weekdays : {\n        format: 'нядзелю_панядзелак_аўторак_сераду_чацвер_пятніцу_суботу'.split('_'),\n        standalone: 'нядзеля_панядзелак_аўторак_серада_чацвер_пятніца_субота'.split('_'),\n        isFormat: /\\[ ?[Вв] ?(?:мінулую|наступную)? ?\\] ?dddd/\n    },\n    weekdaysShort : 'нд_пн_ат_ср_чц_пт_сб'.split('_'),\n    weekdaysMin : 'нд_пн_ат_ср_чц_пт_сб'.split('_'),\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD.MM.YYYY',\n        LL : 'D MMMM YYYY г.',\n        LLL : 'D MMMM YYYY г., HH:mm',\n        LLLL : 'dddd, D MMMM YYYY г., HH:mm'\n    },\n    calendar : {\n        sameDay: '[Сёння ў] LT',\n        nextDay: '[Заўтра ў] LT',\n        lastDay: '[Учора ў] LT',\n        nextWeek: function () {\n            return '[У] dddd [ў] LT';\n        },\n        lastWeek: function () {\n            switch (this.day()) {\n                case 0:\n                case 3:\n                case 5:\n                case 6:\n                    return '[У мінулую] dddd [ў] LT';\n                case 1:\n                case 2:\n                case 4:\n                    return '[У мінулы] dddd [ў] LT';\n            }\n        },\n        sameElse: 'L'\n    },\n    relativeTime : {\n        future : 'праз %s',\n        past : '%s таму',\n        s : 'некалькі секунд',\n        m : relativeTimeWithPlural,\n        mm : relativeTimeWithPlural,\n        h : relativeTimeWithPlural,\n        hh : relativeTimeWithPlural,\n        d : 'дзень',\n        dd : relativeTimeWithPlural,\n        M : 'месяц',\n        MM : relativeTimeWithPlural,\n        y : 'год',\n        yy : relativeTimeWithPlural\n    },\n    meridiemParse: /ночы|раніцы|дня|вечара/,\n    isPM : function (input) {\n        return /^(дня|вечара)$/.test(input);\n    },\n    meridiem : function (hour, minute, isLower) {\n        if (hour < 4) {\n            return 'ночы';\n        } else if (hour < 12) {\n            return 'раніцы';\n        } else if (hour < 17) {\n            return 'дня';\n        } else {\n            return 'вечара';\n        }\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}-(і|ы|га)/,\n    ordinal: function (number, period) {\n        switch (period) {\n            case 'M':\n            case 'd':\n            case 'DDD':\n            case 'w':\n            case 'W':\n                return (number % 10 === 2 || number % 10 === 3) && (number % 100 !== 12 && number % 100 !== 13) ? number + '-і' : number + '-ы';\n            case 'D':\n                return number + '-га';\n            default:\n                return number;\n        }\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 7  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Bulgarian [bg]\n//! author : Krasen Borisov : https://github.com/kraz\n\nmoment.defineLocale('bg', {\n    months : 'януари_февруари_март_април_май_юни_юли_август_септември_октомври_ноември_декември'.split('_'),\n    monthsShort : 'янр_фев_мар_апр_май_юни_юли_авг_сеп_окт_ное_дек'.split('_'),\n    weekdays : 'неделя_понеделник_вторник_сряда_четвъртък_петък_събота'.split('_'),\n    weekdaysShort : 'нед_пон_вто_сря_чет_пет_съб'.split('_'),\n    weekdaysMin : 'нд_пн_вт_ср_чт_пт_сб'.split('_'),\n    longDateFormat : {\n        LT : 'H:mm',\n        LTS : 'H:mm:ss',\n        L : 'D.MM.YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY H:mm',\n        LLLL : 'dddd, D MMMM YYYY H:mm'\n    },\n    calendar : {\n        sameDay : '[Днес в] LT',\n        nextDay : '[Утре в] LT',\n        nextWeek : 'dddd [в] LT',\n        lastDay : '[Вчера в] LT',\n        lastWeek : function () {\n            switch (this.day()) {\n                case 0:\n                case 3:\n                case 6:\n                    return '[В изминалата] dddd [в] LT';\n                case 1:\n                case 2:\n                case 4:\n                case 5:\n                    return '[В изминалия] dddd [в] LT';\n            }\n        },\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'след %s',\n        past : 'преди %s',\n        s : 'няколко секунди',\n        m : 'минута',\n        mm : '%d минути',\n        h : 'час',\n        hh : '%d часа',\n        d : 'ден',\n        dd : '%d дни',\n        M : 'месец',\n        MM : '%d месеца',\n        y : 'година',\n        yy : '%d години'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}-(ев|ен|ти|ви|ри|ми)/,\n    ordinal : function (number) {\n        var lastDigit = number % 10,\n            last2Digits = number % 100;\n        if (number === 0) {\n            return number + '-ев';\n        } else if (last2Digits === 0) {\n            return number + '-ен';\n        } else if (last2Digits > 10 && last2Digits < 20) {\n            return number + '-ти';\n        } else if (lastDigit === 1) {\n            return number + '-ви';\n        } else if (lastDigit === 2) {\n            return number + '-ри';\n        } else if (lastDigit === 7 || lastDigit === 8) {\n            return number + '-ми';\n        } else {\n            return number + '-ти';\n        }\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 7  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Bengali [bn]\n//! author : Kaushik Gandhi : https://github.com/kaushikgandhi\n\nvar symbolMap$3 = {\n    '1': '১',\n    '2': '২',\n    '3': '৩',\n    '4': '৪',\n    '5': '৫',\n    '6': '৬',\n    '7': '৭',\n    '8': '৮',\n    '9': '৯',\n    '0': '০'\n};\nvar numberMap$2 = {\n    '১': '1',\n    '২': '2',\n    '৩': '3',\n    '৪': '4',\n    '৫': '5',\n    '৬': '6',\n    '৭': '7',\n    '৮': '8',\n    '৯': '9',\n    '০': '0'\n};\n\nmoment.defineLocale('bn', {\n    months : 'জানুয়ারী_ফেব্রুয়ারি_মার্চ_এপ্রিল_মে_জুন_জুলাই_আগস্ট_সেপ্টেম্বর_অক্টোবর_নভেম্বর_ডিসেম্বর'.split('_'),\n    monthsShort : 'জানু_ফেব_মার্চ_এপ্র_মে_জুন_জুল_আগ_সেপ্ট_অক্টো_নভে_ডিসে'.split('_'),\n    weekdays : 'রবিবার_সোমবার_মঙ্গলবার_বুধবার_বৃহস্পতিবার_শুক্রবার_শনিবার'.split('_'),\n    weekdaysShort : 'রবি_সোম_মঙ্গল_বুধ_বৃহস্পতি_শুক্র_শনি'.split('_'),\n    weekdaysMin : 'রবি_সোম_মঙ্গ_বুধ_বৃহঃ_শুক্র_শনি'.split('_'),\n    longDateFormat : {\n        LT : 'A h:mm সময়',\n        LTS : 'A h:mm:ss সময়',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY, A h:mm সময়',\n        LLLL : 'dddd, D MMMM YYYY, A h:mm সময়'\n    },\n    calendar : {\n        sameDay : '[আজ] LT',\n        nextDay : '[আগামীকাল] LT',\n        nextWeek : 'dddd, LT',\n        lastDay : '[গতকাল] LT',\n        lastWeek : '[গত] dddd, LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : '%s পরে',\n        past : '%s আগে',\n        s : 'কয়েক সেকেন্ড',\n        m : 'এক মিনিট',\n        mm : '%d মিনিট',\n        h : 'এক ঘন্টা',\n        hh : '%d ঘন্টা',\n        d : 'এক দিন',\n        dd : '%d দিন',\n        M : 'এক মাস',\n        MM : '%d মাস',\n        y : 'এক বছর',\n        yy : '%d বছর'\n    },\n    preparse: function (string) {\n        return string.replace(/[১২৩৪৫৬৭৮৯০]/g, function (match) {\n            return numberMap$2[match];\n        });\n    },\n    postformat: function (string) {\n        return string.replace(/\\d/g, function (match) {\n            return symbolMap$3[match];\n        });\n    },\n    meridiemParse: /রাত|সকাল|দুপুর|বিকাল|রাত/,\n    meridiemHour : function (hour, meridiem) {\n        if (hour === 12) {\n            hour = 0;\n        }\n        if ((meridiem === 'রাত' && hour >= 4) ||\n                (meridiem === 'দুপুর' && hour < 5) ||\n                meridiem === 'বিকাল') {\n            return hour + 12;\n        } else {\n            return hour;\n        }\n    },\n    meridiem : function (hour, minute, isLower) {\n        if (hour < 4) {\n            return 'রাত';\n        } else if (hour < 10) {\n            return 'সকাল';\n        } else if (hour < 17) {\n            return 'দুপুর';\n        } else if (hour < 20) {\n            return 'বিকাল';\n        } else {\n            return 'রাত';\n        }\n    },\n    week : {\n        dow : 0, // Sunday is the first day of the week.\n        doy : 6  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Tibetan [bo]\n//! author : Thupten N. Chakrishar : https://github.com/vajradog\n\nvar symbolMap$4 = {\n    '1': '༡',\n    '2': '༢',\n    '3': '༣',\n    '4': '༤',\n    '5': '༥',\n    '6': '༦',\n    '7': '༧',\n    '8': '༨',\n    '9': '༩',\n    '0': '༠'\n};\nvar numberMap$3 = {\n    '༡': '1',\n    '༢': '2',\n    '༣': '3',\n    '༤': '4',\n    '༥': '5',\n    '༦': '6',\n    '༧': '7',\n    '༨': '8',\n    '༩': '9',\n    '༠': '0'\n};\n\nmoment.defineLocale('bo', {\n    months : 'ཟླ་བ་དང་པོ_ཟླ་བ་གཉིས་པ_ཟླ་བ་གསུམ་པ_ཟླ་བ་བཞི་པ_ཟླ་བ་ལྔ་པ_ཟླ་བ་དྲུག་པ_ཟླ་བ་བདུན་པ_ཟླ་བ་བརྒྱད་པ_ཟླ་བ་དགུ་པ_ཟླ་བ་བཅུ་པ_ཟླ་བ་བཅུ་གཅིག་པ_ཟླ་བ་བཅུ་གཉིས་པ'.split('_'),\n    monthsShort : 'ཟླ་བ་དང་པོ_ཟླ་བ་གཉིས་པ_ཟླ་བ་གསུམ་པ_ཟླ་བ་བཞི་པ_ཟླ་བ་ལྔ་པ_ཟླ་བ་དྲུག་པ_ཟླ་བ་བདུན་པ_ཟླ་བ་བརྒྱད་པ_ཟླ་བ་དགུ་པ_ཟླ་བ་བཅུ་པ_ཟླ་བ་བཅུ་གཅིག་པ_ཟླ་བ་བཅུ་གཉིས་པ'.split('_'),\n    weekdays : 'གཟའ་ཉི་མ་_གཟའ་ཟླ་བ་_གཟའ་མིག་དམར་_གཟའ་ལྷག་པ་_གཟའ་ཕུར་བུ_གཟའ་པ་སངས་_གཟའ་སྤེན་པ་'.split('_'),\n    weekdaysShort : 'ཉི་མ་_ཟླ་བ་_མིག་དམར་_ལྷག་པ་_ཕུར་བུ_པ་སངས་_སྤེན་པ་'.split('_'),\n    weekdaysMin : 'ཉི་མ་_ཟླ་བ་_མིག་དམར་_ལྷག་པ་_ཕུར་བུ_པ་སངས་_སྤེན་པ་'.split('_'),\n    longDateFormat : {\n        LT : 'A h:mm',\n        LTS : 'A h:mm:ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY, A h:mm',\n        LLLL : 'dddd, D MMMM YYYY, A h:mm'\n    },\n    calendar : {\n        sameDay : '[དི་རིང] LT',\n        nextDay : '[སང་ཉིན] LT',\n        nextWeek : '[བདུན་ཕྲག་རྗེས་མ], LT',\n        lastDay : '[ཁ་སང] LT',\n        lastWeek : '[བདུན་ཕྲག་མཐའ་མ] dddd, LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : '%s ལ་',\n        past : '%s སྔན་ལ',\n        s : 'ལམ་སང',\n        m : 'སྐར་མ་གཅིག',\n        mm : '%d སྐར་མ',\n        h : 'ཆུ་ཚོད་གཅིག',\n        hh : '%d ཆུ་ཚོད',\n        d : 'ཉིན་གཅིག',\n        dd : '%d ཉིན་',\n        M : 'ཟླ་བ་གཅིག',\n        MM : '%d ཟླ་བ',\n        y : 'ལོ་གཅིག',\n        yy : '%d ལོ'\n    },\n    preparse: function (string) {\n        return string.replace(/[༡༢༣༤༥༦༧༨༩༠]/g, function (match) {\n            return numberMap$3[match];\n        });\n    },\n    postformat: function (string) {\n        return string.replace(/\\d/g, function (match) {\n            return symbolMap$4[match];\n        });\n    },\n    meridiemParse: /མཚན་མོ|ཞོགས་ཀས|ཉིན་གུང|དགོང་དག|མཚན་མོ/,\n    meridiemHour : function (hour, meridiem) {\n        if (hour === 12) {\n            hour = 0;\n        }\n        if ((meridiem === 'མཚན་མོ' && hour >= 4) ||\n                (meridiem === 'ཉིན་གུང' && hour < 5) ||\n                meridiem === 'དགོང་དག') {\n            return hour + 12;\n        } else {\n            return hour;\n        }\n    },\n    meridiem : function (hour, minute, isLower) {\n        if (hour < 4) {\n            return 'མཚན་མོ';\n        } else if (hour < 10) {\n            return 'ཞོགས་ཀས';\n        } else if (hour < 17) {\n            return 'ཉིན་གུང';\n        } else if (hour < 20) {\n            return 'དགོང་དག';\n        } else {\n            return 'མཚན་མོ';\n        }\n    },\n    week : {\n        dow : 0, // Sunday is the first day of the week.\n        doy : 6  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Breton [br]\n//! author : Jean-Baptiste Le Duigou : https://github.com/jbleduigou\n\nfunction relativeTimeWithMutation(number, withoutSuffix, key) {\n    var format = {\n        'mm': 'munutenn',\n        'MM': 'miz',\n        'dd': 'devezh'\n    };\n    return number + ' ' + mutation(format[key], number);\n}\nfunction specialMutationForYears(number) {\n    switch (lastNumber(number)) {\n        case 1:\n        case 3:\n        case 4:\n        case 5:\n        case 9:\n            return number + ' bloaz';\n        default:\n            return number + ' vloaz';\n    }\n}\nfunction lastNumber(number) {\n    if (number > 9) {\n        return lastNumber(number % 10);\n    }\n    return number;\n}\nfunction mutation(text, number) {\n    if (number === 2) {\n        return softMutation(text);\n    }\n    return text;\n}\nfunction softMutation(text) {\n    var mutationTable = {\n        'm': 'v',\n        'b': 'v',\n        'd': 'z'\n    };\n    if (mutationTable[text.charAt(0)] === undefined) {\n        return text;\n    }\n    return mutationTable[text.charAt(0)] + text.substring(1);\n}\n\nmoment.defineLocale('br', {\n    months : 'Genver_C\\'hwevrer_Meurzh_Ebrel_Mae_Mezheven_Gouere_Eost_Gwengolo_Here_Du_Kerzu'.split('_'),\n    monthsShort : 'Gen_C\\'hwe_Meu_Ebr_Mae_Eve_Gou_Eos_Gwe_Her_Du_Ker'.split('_'),\n    weekdays : 'Sul_Lun_Meurzh_Merc\\'her_Yaou_Gwener_Sadorn'.split('_'),\n    weekdaysShort : 'Sul_Lun_Meu_Mer_Yao_Gwe_Sad'.split('_'),\n    weekdaysMin : 'Su_Lu_Me_Mer_Ya_Gw_Sa'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat : {\n        LT : 'h[e]mm A',\n        LTS : 'h[e]mm:ss A',\n        L : 'DD/MM/YYYY',\n        LL : 'D [a viz] MMMM YYYY',\n        LLL : 'D [a viz] MMMM YYYY h[e]mm A',\n        LLLL : 'dddd, D [a viz] MMMM YYYY h[e]mm A'\n    },\n    calendar : {\n        sameDay : '[Hiziv da] LT',\n        nextDay : '[Warc\\'hoazh da] LT',\n        nextWeek : 'dddd [da] LT',\n        lastDay : '[Dec\\'h da] LT',\n        lastWeek : 'dddd [paset da] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'a-benn %s',\n        past : '%s \\'zo',\n        s : 'un nebeud segondennoù',\n        m : 'ur vunutenn',\n        mm : relativeTimeWithMutation,\n        h : 'un eur',\n        hh : '%d eur',\n        d : 'un devezh',\n        dd : relativeTimeWithMutation,\n        M : 'ur miz',\n        MM : relativeTimeWithMutation,\n        y : 'ur bloaz',\n        yy : specialMutationForYears\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}(añ|vet)/,\n    ordinal : function (number) {\n        var output = (number === 1) ? 'añ' : 'vet';\n        return number + output;\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Bosnian [bs]\n//! author : Nedim Cholich : https://github.com/frontyard\n//! based on (hr) translation by Bojan Marković\n\nfunction translate(number, withoutSuffix, key) {\n    var result = number + ' ';\n    switch (key) {\n        case 'm':\n            return withoutSuffix ? 'jedna minuta' : 'jedne minute';\n        case 'mm':\n            if (number === 1) {\n                result += 'minuta';\n            } else if (number === 2 || number === 3 || number === 4) {\n                result += 'minute';\n            } else {\n                result += 'minuta';\n            }\n            return result;\n        case 'h':\n            return withoutSuffix ? 'jedan sat' : 'jednog sata';\n        case 'hh':\n            if (number === 1) {\n                result += 'sat';\n            } else if (number === 2 || number === 3 || number === 4) {\n                result += 'sata';\n            } else {\n                result += 'sati';\n            }\n            return result;\n        case 'dd':\n            if (number === 1) {\n                result += 'dan';\n            } else {\n                result += 'dana';\n            }\n            return result;\n        case 'MM':\n            if (number === 1) {\n                result += 'mjesec';\n            } else if (number === 2 || number === 3 || number === 4) {\n                result += 'mjeseca';\n            } else {\n                result += 'mjeseci';\n            }\n            return result;\n        case 'yy':\n            if (number === 1) {\n                result += 'godina';\n            } else if (number === 2 || number === 3 || number === 4) {\n                result += 'godine';\n            } else {\n                result += 'godina';\n            }\n            return result;\n    }\n}\n\nmoment.defineLocale('bs', {\n    months : 'januar_februar_mart_april_maj_juni_juli_august_septembar_oktobar_novembar_decembar'.split('_'),\n    monthsShort : 'jan._feb._mar._apr._maj._jun._jul._aug._sep._okt._nov._dec.'.split('_'),\n    monthsParseExact: true,\n    weekdays : 'nedjelja_ponedjeljak_utorak_srijeda_četvrtak_petak_subota'.split('_'),\n    weekdaysShort : 'ned._pon._uto._sri._čet._pet._sub.'.split('_'),\n    weekdaysMin : 'ne_po_ut_sr_če_pe_su'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat : {\n        LT : 'H:mm',\n        LTS : 'H:mm:ss',\n        L : 'DD.MM.YYYY',\n        LL : 'D. MMMM YYYY',\n        LLL : 'D. MMMM YYYY H:mm',\n        LLLL : 'dddd, D. MMMM YYYY H:mm'\n    },\n    calendar : {\n        sameDay  : '[danas u] LT',\n        nextDay  : '[sutra u] LT',\n        nextWeek : function () {\n            switch (this.day()) {\n                case 0:\n                    return '[u] [nedjelju] [u] LT';\n                case 3:\n                    return '[u] [srijedu] [u] LT';\n                case 6:\n                    return '[u] [subotu] [u] LT';\n                case 1:\n                case 2:\n                case 4:\n                case 5:\n                    return '[u] dddd [u] LT';\n            }\n        },\n        lastDay  : '[jučer u] LT',\n        lastWeek : function () {\n            switch (this.day()) {\n                case 0:\n                case 3:\n                    return '[prošlu] dddd [u] LT';\n                case 6:\n                    return '[prošle] [subote] [u] LT';\n                case 1:\n                case 2:\n                case 4:\n                case 5:\n                    return '[prošli] dddd [u] LT';\n            }\n        },\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'za %s',\n        past   : 'prije %s',\n        s      : 'par sekundi',\n        m      : translate,\n        mm     : translate,\n        h      : translate,\n        hh     : translate,\n        d      : 'dan',\n        dd     : translate,\n        M      : 'mjesec',\n        MM     : translate,\n        y      : 'godinu',\n        yy     : translate\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}\\./,\n    ordinal : '%d.',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 7  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Catalan [ca]\n//! author : Juan G. Hurtado : https://github.com/juanghurtado\n\nmoment.defineLocale('ca', {\n    months : {\n        standalone: 'gener_febrer_març_abril_maig_juny_juliol_agost_setembre_octubre_novembre_desembre'.split('_'),\n        format: 'de gener_de febrer_de març_d\\'abril_de maig_de juny_de juliol_d\\'agost_de setembre_d\\'octubre_de novembre_de desembre'.split('_'),\n        isFormat: /D[oD]?(\\s)+MMMM/\n    },\n    monthsShort : 'gen._febr._març_abr._maig_juny_jul._ag._set._oct._nov._des.'.split('_'),\n    monthsParseExact : true,\n    weekdays : 'diumenge_dilluns_dimarts_dimecres_dijous_divendres_dissabte'.split('_'),\n    weekdaysShort : 'dg._dl._dt._dc._dj._dv._ds.'.split('_'),\n    weekdaysMin : 'Dg_Dl_Dt_Dc_Dj_Dv_Ds'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat : {\n        LT : 'H:mm',\n        LTS : 'H:mm:ss',\n        L : 'DD/MM/YYYY',\n        LL : '[el] D MMMM [de] YYYY',\n        ll : 'D MMM YYYY',\n        LLL : '[el] D MMMM [de] YYYY [a les] H:mm',\n        lll : 'D MMM YYYY, H:mm',\n        LLLL : '[el] dddd D MMMM [de] YYYY [a les] H:mm',\n        llll : 'ddd D MMM YYYY, H:mm'\n    },\n    calendar : {\n        sameDay : function () {\n            return '[avui a ' + ((this.hours() !== 1) ? 'les' : 'la') + '] LT';\n        },\n        nextDay : function () {\n            return '[demà a ' + ((this.hours() !== 1) ? 'les' : 'la') + '] LT';\n        },\n        nextWeek : function () {\n            return 'dddd [a ' + ((this.hours() !== 1) ? 'les' : 'la') + '] LT';\n        },\n        lastDay : function () {\n            return '[ahir a ' + ((this.hours() !== 1) ? 'les' : 'la') + '] LT';\n        },\n        lastWeek : function () {\n            return '[el] dddd [passat a ' + ((this.hours() !== 1) ? 'les' : 'la') + '] LT';\n        },\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'd\\'aquí %s',\n        past : 'fa %s',\n        s : 'uns segons',\n        m : 'un minut',\n        mm : '%d minuts',\n        h : 'una hora',\n        hh : '%d hores',\n        d : 'un dia',\n        dd : '%d dies',\n        M : 'un mes',\n        MM : '%d mesos',\n        y : 'un any',\n        yy : '%d anys'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}(r|n|t|è|a)/,\n    ordinal : function (number, period) {\n        var output = (number === 1) ? 'r' :\n            (number === 2) ? 'n' :\n            (number === 3) ? 'r' :\n            (number === 4) ? 't' : 'è';\n        if (period === 'w' || period === 'W') {\n            output = 'a';\n        }\n        return number + output;\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Czech [cs]\n//! author : petrbela : https://github.com/petrbela\n\nvar months$2 = 'leden_únor_březen_duben_květen_červen_červenec_srpen_září_říjen_listopad_prosinec'.split('_');\nvar monthsShort = 'led_úno_bře_dub_kvě_čvn_čvc_srp_zář_říj_lis_pro'.split('_');\nfunction plural$1(n) {\n    return (n > 1) && (n < 5) && (~~(n / 10) !== 1);\n}\nfunction translate$1(number, withoutSuffix, key, isFuture) {\n    var result = number + ' ';\n    switch (key) {\n        case 's':  // a few seconds / in a few seconds / a few seconds ago\n            return (withoutSuffix || isFuture) ? 'pár sekund' : 'pár sekundami';\n        case 'm':  // a minute / in a minute / a minute ago\n            return withoutSuffix ? 'minuta' : (isFuture ? 'minutu' : 'minutou');\n        case 'mm': // 9 minutes / in 9 minutes / 9 minutes ago\n            if (withoutSuffix || isFuture) {\n                return result + (plural$1(number) ? 'minuty' : 'minut');\n            } else {\n                return result + 'minutami';\n            }\n            break;\n        case 'h':  // an hour / in an hour / an hour ago\n            return withoutSuffix ? 'hodina' : (isFuture ? 'hodinu' : 'hodinou');\n        case 'hh': // 9 hours / in 9 hours / 9 hours ago\n            if (withoutSuffix || isFuture) {\n                return result + (plural$1(number) ? 'hodiny' : 'hodin');\n            } else {\n                return result + 'hodinami';\n            }\n            break;\n        case 'd':  // a day / in a day / a day ago\n            return (withoutSuffix || isFuture) ? 'den' : 'dnem';\n        case 'dd': // 9 days / in 9 days / 9 days ago\n            if (withoutSuffix || isFuture) {\n                return result + (plural$1(number) ? 'dny' : 'dní');\n            } else {\n                return result + 'dny';\n            }\n            break;\n        case 'M':  // a month / in a month / a month ago\n            return (withoutSuffix || isFuture) ? 'měsíc' : 'měsícem';\n        case 'MM': // 9 months / in 9 months / 9 months ago\n            if (withoutSuffix || isFuture) {\n                return result + (plural$1(number) ? 'měsíce' : 'měsíců');\n            } else {\n                return result + 'měsíci';\n            }\n            break;\n        case 'y':  // a year / in a year / a year ago\n            return (withoutSuffix || isFuture) ? 'rok' : 'rokem';\n        case 'yy': // 9 years / in 9 years / 9 years ago\n            if (withoutSuffix || isFuture) {\n                return result + (plural$1(number) ? 'roky' : 'let');\n            } else {\n                return result + 'lety';\n            }\n            break;\n    }\n}\n\nmoment.defineLocale('cs', {\n    months : months$2,\n    monthsShort : monthsShort,\n    monthsParse : (function (months, monthsShort) {\n        var i, _monthsParse = [];\n        for (i = 0; i < 12; i++) {\n            // use custom parser to solve problem with July (červenec)\n            _monthsParse[i] = new RegExp('^' + months[i] + '$|^' + monthsShort[i] + '$', 'i');\n        }\n        return _monthsParse;\n    }(months$2, monthsShort)),\n    shortMonthsParse : (function (monthsShort) {\n        var i, _shortMonthsParse = [];\n        for (i = 0; i < 12; i++) {\n            _shortMonthsParse[i] = new RegExp('^' + monthsShort[i] + '$', 'i');\n        }\n        return _shortMonthsParse;\n    }(monthsShort)),\n    longMonthsParse : (function (months) {\n        var i, _longMonthsParse = [];\n        for (i = 0; i < 12; i++) {\n            _longMonthsParse[i] = new RegExp('^' + months[i] + '$', 'i');\n        }\n        return _longMonthsParse;\n    }(months$2)),\n    weekdays : 'neděle_pondělí_úterý_středa_čtvrtek_pátek_sobota'.split('_'),\n    weekdaysShort : 'ne_po_út_st_čt_pá_so'.split('_'),\n    weekdaysMin : 'ne_po_út_st_čt_pá_so'.split('_'),\n    longDateFormat : {\n        LT: 'H:mm',\n        LTS : 'H:mm:ss',\n        L : 'DD.MM.YYYY',\n        LL : 'D. MMMM YYYY',\n        LLL : 'D. MMMM YYYY H:mm',\n        LLLL : 'dddd D. MMMM YYYY H:mm',\n        l : 'D. M. YYYY'\n    },\n    calendar : {\n        sameDay: '[dnes v] LT',\n        nextDay: '[zítra v] LT',\n        nextWeek: function () {\n            switch (this.day()) {\n                case 0:\n                    return '[v neděli v] LT';\n                case 1:\n                case 2:\n                    return '[v] dddd [v] LT';\n                case 3:\n                    return '[ve středu v] LT';\n                case 4:\n                    return '[ve čtvrtek v] LT';\n                case 5:\n                    return '[v pátek v] LT';\n                case 6:\n                    return '[v sobotu v] LT';\n            }\n        },\n        lastDay: '[včera v] LT',\n        lastWeek: function () {\n            switch (this.day()) {\n                case 0:\n                    return '[minulou neděli v] LT';\n                case 1:\n                case 2:\n                    return '[minulé] dddd [v] LT';\n                case 3:\n                    return '[minulou středu v] LT';\n                case 4:\n                case 5:\n                    return '[minulý] dddd [v] LT';\n                case 6:\n                    return '[minulou sobotu v] LT';\n            }\n        },\n        sameElse: 'L'\n    },\n    relativeTime : {\n        future : 'za %s',\n        past : 'před %s',\n        s : translate$1,\n        m : translate$1,\n        mm : translate$1,\n        h : translate$1,\n        hh : translate$1,\n        d : translate$1,\n        dd : translate$1,\n        M : translate$1,\n        MM : translate$1,\n        y : translate$1,\n        yy : translate$1\n    },\n    dayOfMonthOrdinalParse : /\\d{1,2}\\./,\n    ordinal : '%d.',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Chuvash [cv]\n//! author : Anatoly Mironov : https://github.com/mirontoli\n\nmoment.defineLocale('cv', {\n    months : 'кӑрлач_нарӑс_пуш_ака_май_ҫӗртме_утӑ_ҫурла_авӑн_юпа_чӳк_раштав'.split('_'),\n    monthsShort : 'кӑр_нар_пуш_ака_май_ҫӗр_утӑ_ҫур_авн_юпа_чӳк_раш'.split('_'),\n    weekdays : 'вырсарникун_тунтикун_ытларикун_юнкун_кӗҫнерникун_эрнекун_шӑматкун'.split('_'),\n    weekdaysShort : 'выр_тун_ытл_юн_кӗҫ_эрн_шӑм'.split('_'),\n    weekdaysMin : 'вр_тн_ыт_юн_кҫ_эр_шм'.split('_'),\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD-MM-YYYY',\n        LL : 'YYYY [ҫулхи] MMMM [уйӑхӗн] D[-мӗшӗ]',\n        LLL : 'YYYY [ҫулхи] MMMM [уйӑхӗн] D[-мӗшӗ], HH:mm',\n        LLLL : 'dddd, YYYY [ҫулхи] MMMM [уйӑхӗн] D[-мӗшӗ], HH:mm'\n    },\n    calendar : {\n        sameDay: '[Паян] LT [сехетре]',\n        nextDay: '[Ыран] LT [сехетре]',\n        lastDay: '[Ӗнер] LT [сехетре]',\n        nextWeek: '[Ҫитес] dddd LT [сехетре]',\n        lastWeek: '[Иртнӗ] dddd LT [сехетре]',\n        sameElse: 'L'\n    },\n    relativeTime : {\n        future : function (output) {\n            var affix = /сехет$/i.exec(output) ? 'рен' : /ҫул$/i.exec(output) ? 'тан' : 'ран';\n            return output + affix;\n        },\n        past : '%s каялла',\n        s : 'пӗр-ик ҫеккунт',\n        m : 'пӗр минут',\n        mm : '%d минут',\n        h : 'пӗр сехет',\n        hh : '%d сехет',\n        d : 'пӗр кун',\n        dd : '%d кун',\n        M : 'пӗр уйӑх',\n        MM : '%d уйӑх',\n        y : 'пӗр ҫул',\n        yy : '%d ҫул'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}-мӗш/,\n    ordinal : '%d-мӗш',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 7  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Welsh [cy]\n//! author : Robert Allen : https://github.com/robgallen\n//! author : https://github.com/ryangreaves\n\nmoment.defineLocale('cy', {\n    months: 'Ionawr_Chwefror_Mawrth_Ebrill_Mai_Mehefin_Gorffennaf_Awst_Medi_Hydref_Tachwedd_Rhagfyr'.split('_'),\n    monthsShort: 'Ion_Chwe_Maw_Ebr_Mai_Meh_Gor_Aws_Med_Hyd_Tach_Rhag'.split('_'),\n    weekdays: 'Dydd Sul_Dydd Llun_Dydd Mawrth_Dydd Mercher_Dydd Iau_Dydd Gwener_Dydd Sadwrn'.split('_'),\n    weekdaysShort: 'Sul_Llun_Maw_Mer_Iau_Gwe_Sad'.split('_'),\n    weekdaysMin: 'Su_Ll_Ma_Me_Ia_Gw_Sa'.split('_'),\n    weekdaysParseExact : true,\n    // time formats are the same as en-gb\n    longDateFormat: {\n        LT: 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L: 'DD/MM/YYYY',\n        LL: 'D MMMM YYYY',\n        LLL: 'D MMMM YYYY HH:mm',\n        LLLL: 'dddd, D MMMM YYYY HH:mm'\n    },\n    calendar: {\n        sameDay: '[Heddiw am] LT',\n        nextDay: '[Yfory am] LT',\n        nextWeek: 'dddd [am] LT',\n        lastDay: '[Ddoe am] LT',\n        lastWeek: 'dddd [diwethaf am] LT',\n        sameElse: 'L'\n    },\n    relativeTime: {\n        future: 'mewn %s',\n        past: '%s yn ôl',\n        s: 'ychydig eiliadau',\n        m: 'munud',\n        mm: '%d munud',\n        h: 'awr',\n        hh: '%d awr',\n        d: 'diwrnod',\n        dd: '%d diwrnod',\n        M: 'mis',\n        MM: '%d mis',\n        y: 'blwyddyn',\n        yy: '%d flynedd'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}(fed|ain|af|il|ydd|ed|eg)/,\n    // traditional ordinal numbers above 31 are not commonly used in colloquial Welsh\n    ordinal: function (number) {\n        var b = number,\n            output = '',\n            lookup = [\n                '', 'af', 'il', 'ydd', 'ydd', 'ed', 'ed', 'ed', 'fed', 'fed', 'fed', // 1af to 10fed\n                'eg', 'fed', 'eg', 'eg', 'fed', 'eg', 'eg', 'fed', 'eg', 'fed' // 11eg to 20fed\n            ];\n        if (b > 20) {\n            if (b === 40 || b === 50 || b === 60 || b === 80 || b === 100) {\n                output = 'fed'; // not 30ain, 70ain or 90ain\n            } else {\n                output = 'ain';\n            }\n        } else if (b > 0) {\n            output = lookup[b];\n        }\n        return number + output;\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Danish [da]\n//! author : Ulrik Nielsen : https://github.com/mrbase\n\nmoment.defineLocale('da', {\n    months : 'januar_februar_marts_april_maj_juni_juli_august_september_oktober_november_december'.split('_'),\n    monthsShort : 'jan_feb_mar_apr_maj_jun_jul_aug_sep_okt_nov_dec'.split('_'),\n    weekdays : 'søndag_mandag_tirsdag_onsdag_torsdag_fredag_lørdag'.split('_'),\n    weekdaysShort : 'søn_man_tir_ons_tor_fre_lør'.split('_'),\n    weekdaysMin : 'sø_ma_ti_on_to_fr_lø'.split('_'),\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D. MMMM YYYY',\n        LLL : 'D. MMMM YYYY HH:mm',\n        LLLL : 'dddd [d.] D. MMMM YYYY [kl.] HH:mm'\n    },\n    calendar : {\n        sameDay : '[i dag kl.] LT',\n        nextDay : '[i morgen kl.] LT',\n        nextWeek : 'på dddd [kl.] LT',\n        lastDay : '[i går kl.] LT',\n        lastWeek : '[i] dddd[s kl.] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'om %s',\n        past : '%s siden',\n        s : 'få sekunder',\n        m : 'et minut',\n        mm : '%d minutter',\n        h : 'en time',\n        hh : '%d timer',\n        d : 'en dag',\n        dd : '%d dage',\n        M : 'en måned',\n        MM : '%d måneder',\n        y : 'et år',\n        yy : '%d år'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}\\./,\n    ordinal : '%d.',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : German (Austria) [de-at]\n//! author : lluchs : https://github.com/lluchs\n//! author: Menelion Elensúle: https://github.com/Oire\n//! author : Martin Groller : https://github.com/MadMG\n//! author : Mikolaj Dadela : https://github.com/mik01aj\n\nfunction processRelativeTime(number, withoutSuffix, key, isFuture) {\n    var format = {\n        'm': ['eine Minute', 'einer Minute'],\n        'h': ['eine Stunde', 'einer Stunde'],\n        'd': ['ein Tag', 'einem Tag'],\n        'dd': [number + ' Tage', number + ' Tagen'],\n        'M': ['ein Monat', 'einem Monat'],\n        'MM': [number + ' Monate', number + ' Monaten'],\n        'y': ['ein Jahr', 'einem Jahr'],\n        'yy': [number + ' Jahre', number + ' Jahren']\n    };\n    return withoutSuffix ? format[key][0] : format[key][1];\n}\n\nmoment.defineLocale('de-at', {\n    months : 'Jänner_Februar_März_April_Mai_Juni_Juli_August_September_Oktober_November_Dezember'.split('_'),\n    monthsShort : 'Jän._Febr._Mrz._Apr._Mai_Jun._Jul._Aug._Sept._Okt._Nov._Dez.'.split('_'),\n    monthsParseExact : true,\n    weekdays : 'Sonntag_Montag_Dienstag_Mittwoch_Donnerstag_Freitag_Samstag'.split('_'),\n    weekdaysShort : 'So._Mo._Di._Mi._Do._Fr._Sa.'.split('_'),\n    weekdaysMin : 'So_Mo_Di_Mi_Do_Fr_Sa'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat : {\n        LT: 'HH:mm',\n        LTS: 'HH:mm:ss',\n        L : 'DD.MM.YYYY',\n        LL : 'D. MMMM YYYY',\n        LLL : 'D. MMMM YYYY HH:mm',\n        LLLL : 'dddd, D. MMMM YYYY HH:mm'\n    },\n    calendar : {\n        sameDay: '[heute um] LT [Uhr]',\n        sameElse: 'L',\n        nextDay: '[morgen um] LT [Uhr]',\n        nextWeek: 'dddd [um] LT [Uhr]',\n        lastDay: '[gestern um] LT [Uhr]',\n        lastWeek: '[letzten] dddd [um] LT [Uhr]'\n    },\n    relativeTime : {\n        future : 'in %s',\n        past : 'vor %s',\n        s : 'ein paar Sekunden',\n        m : processRelativeTime,\n        mm : '%d Minuten',\n        h : processRelativeTime,\n        hh : '%d Stunden',\n        d : processRelativeTime,\n        dd : processRelativeTime,\n        M : processRelativeTime,\n        MM : processRelativeTime,\n        y : processRelativeTime,\n        yy : processRelativeTime\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}\\./,\n    ordinal : '%d.',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : German (Switzerland) [de-ch]\n//! author : sschueller : https://github.com/sschueller\n\n// based on: https://www.bk.admin.ch/dokumentation/sprachen/04915/05016/index.html?lang=de#\n\nfunction processRelativeTime$1(number, withoutSuffix, key, isFuture) {\n    var format = {\n        'm': ['eine Minute', 'einer Minute'],\n        'h': ['eine Stunde', 'einer Stunde'],\n        'd': ['ein Tag', 'einem Tag'],\n        'dd': [number + ' Tage', number + ' Tagen'],\n        'M': ['ein Monat', 'einem Monat'],\n        'MM': [number + ' Monate', number + ' Monaten'],\n        'y': ['ein Jahr', 'einem Jahr'],\n        'yy': [number + ' Jahre', number + ' Jahren']\n    };\n    return withoutSuffix ? format[key][0] : format[key][1];\n}\n\nmoment.defineLocale('de-ch', {\n    months : 'Januar_Februar_März_April_Mai_Juni_Juli_August_September_Oktober_November_Dezember'.split('_'),\n    monthsShort : 'Jan._Febr._März_April_Mai_Juni_Juli_Aug._Sept._Okt._Nov._Dez.'.split('_'),\n    monthsParseExact : true,\n    weekdays : 'Sonntag_Montag_Dienstag_Mittwoch_Donnerstag_Freitag_Samstag'.split('_'),\n    weekdaysShort : 'So_Mo_Di_Mi_Do_Fr_Sa'.split('_'),\n    weekdaysMin : 'So_Mo_Di_Mi_Do_Fr_Sa'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat : {\n        LT: 'HH.mm',\n        LTS: 'HH.mm.ss',\n        L : 'DD.MM.YYYY',\n        LL : 'D. MMMM YYYY',\n        LLL : 'D. MMMM YYYY HH.mm',\n        LLLL : 'dddd, D. MMMM YYYY HH.mm'\n    },\n    calendar : {\n        sameDay: '[heute um] LT [Uhr]',\n        sameElse: 'L',\n        nextDay: '[morgen um] LT [Uhr]',\n        nextWeek: 'dddd [um] LT [Uhr]',\n        lastDay: '[gestern um] LT [Uhr]',\n        lastWeek: '[letzten] dddd [um] LT [Uhr]'\n    },\n    relativeTime : {\n        future : 'in %s',\n        past : 'vor %s',\n        s : 'ein paar Sekunden',\n        m : processRelativeTime$1,\n        mm : '%d Minuten',\n        h : processRelativeTime$1,\n        hh : '%d Stunden',\n        d : processRelativeTime$1,\n        dd : processRelativeTime$1,\n        M : processRelativeTime$1,\n        MM : processRelativeTime$1,\n        y : processRelativeTime$1,\n        yy : processRelativeTime$1\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}\\./,\n    ordinal : '%d.',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : German [de]\n//! author : lluchs : https://github.com/lluchs\n//! author: Menelion Elensúle: https://github.com/Oire\n//! author : Mikolaj Dadela : https://github.com/mik01aj\n\nfunction processRelativeTime$2(number, withoutSuffix, key, isFuture) {\n    var format = {\n        'm': ['eine Minute', 'einer Minute'],\n        'h': ['eine Stunde', 'einer Stunde'],\n        'd': ['ein Tag', 'einem Tag'],\n        'dd': [number + ' Tage', number + ' Tagen'],\n        'M': ['ein Monat', 'einem Monat'],\n        'MM': [number + ' Monate', number + ' Monaten'],\n        'y': ['ein Jahr', 'einem Jahr'],\n        'yy': [number + ' Jahre', number + ' Jahren']\n    };\n    return withoutSuffix ? format[key][0] : format[key][1];\n}\n\nmoment.defineLocale('de', {\n    months : 'Januar_Februar_März_April_Mai_Juni_Juli_August_September_Oktober_November_Dezember'.split('_'),\n    monthsShort : 'Jan._Febr._Mrz._Apr._Mai_Jun._Jul._Aug._Sept._Okt._Nov._Dez.'.split('_'),\n    monthsParseExact : true,\n    weekdays : 'Sonntag_Montag_Dienstag_Mittwoch_Donnerstag_Freitag_Samstag'.split('_'),\n    weekdaysShort : 'So._Mo._Di._Mi._Do._Fr._Sa.'.split('_'),\n    weekdaysMin : 'So_Mo_Di_Mi_Do_Fr_Sa'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat : {\n        LT: 'HH:mm',\n        LTS: 'HH:mm:ss',\n        L : 'DD.MM.YYYY',\n        LL : 'D. MMMM YYYY',\n        LLL : 'D. MMMM YYYY HH:mm',\n        LLLL : 'dddd, D. MMMM YYYY HH:mm'\n    },\n    calendar : {\n        sameDay: '[heute um] LT [Uhr]',\n        sameElse: 'L',\n        nextDay: '[morgen um] LT [Uhr]',\n        nextWeek: 'dddd [um] LT [Uhr]',\n        lastDay: '[gestern um] LT [Uhr]',\n        lastWeek: '[letzten] dddd [um] LT [Uhr]'\n    },\n    relativeTime : {\n        future : 'in %s',\n        past : 'vor %s',\n        s : 'ein paar Sekunden',\n        m : processRelativeTime$2,\n        mm : '%d Minuten',\n        h : processRelativeTime$2,\n        hh : '%d Stunden',\n        d : processRelativeTime$2,\n        dd : processRelativeTime$2,\n        M : processRelativeTime$2,\n        MM : processRelativeTime$2,\n        y : processRelativeTime$2,\n        yy : processRelativeTime$2\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}\\./,\n    ordinal : '%d.',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Maldivian [dv]\n//! author : Jawish Hameed : https://github.com/jawish\n\nvar months$3 = [\n    'ޖެނުއަރީ',\n    'ފެބްރުއަރީ',\n    'މާރިޗު',\n    'އޭޕްރީލު',\n    'މޭ',\n    'ޖޫން',\n    'ޖުލައި',\n    'އޯގަސްޓު',\n    'ސެޕްޓެމްބަރު',\n    'އޮކްޓޯބަރު',\n    'ނޮވެމްބަރު',\n    'ޑިސެމްބަރު'\n];\nvar weekdays = [\n    'އާދިއްތަ',\n    'ހޯމަ',\n    'އަންގާރަ',\n    'ބުދަ',\n    'ބުރާސްފަތި',\n    'ހުކުރު',\n    'ހޮނިހިރު'\n];\n\nmoment.defineLocale('dv', {\n    months : months$3,\n    monthsShort : months$3,\n    weekdays : weekdays,\n    weekdaysShort : weekdays,\n    weekdaysMin : 'އާދި_ހޯމަ_އަން_ބުދަ_ބުރާ_ހުކު_ހޮނި'.split('_'),\n    longDateFormat : {\n\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'D/M/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY HH:mm',\n        LLLL : 'dddd D MMMM YYYY HH:mm'\n    },\n    meridiemParse: /މކ|މފ/,\n    isPM : function (input) {\n        return 'މފ' === input;\n    },\n    meridiem : function (hour, minute, isLower) {\n        if (hour < 12) {\n            return 'މކ';\n        } else {\n            return 'މފ';\n        }\n    },\n    calendar : {\n        sameDay : '[މިއަދު] LT',\n        nextDay : '[މާދަމާ] LT',\n        nextWeek : 'dddd LT',\n        lastDay : '[އިއްޔެ] LT',\n        lastWeek : '[ފާއިތުވި] dddd LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'ތެރޭގައި %s',\n        past : 'ކުރިން %s',\n        s : 'ސިކުންތުކޮޅެއް',\n        m : 'މިނިޓެއް',\n        mm : 'މިނިޓު %d',\n        h : 'ގަޑިއިރެއް',\n        hh : 'ގަޑިއިރު %d',\n        d : 'ދުވަހެއް',\n        dd : 'ދުވަސް %d',\n        M : 'މަހެއް',\n        MM : 'މަސް %d',\n        y : 'އަހަރެއް',\n        yy : 'އަހަރު %d'\n    },\n    preparse: function (string) {\n        return string.replace(/،/g, ',');\n    },\n    postformat: function (string) {\n        return string.replace(/,/g, '،');\n    },\n    week : {\n        dow : 7,  // Sunday is the first day of the week.\n        doy : 12  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\nfunction isFunction(input) {\n    return input instanceof Function || Object.prototype.toString.call(input) === '[object Function]';\n}\n\n//! moment.js locale configuration\n//! locale : Greek [el]\n//! author : Aggelos Karalias : https://github.com/mehiel\n\nmoment.defineLocale('el', {\n    monthsNominativeEl : 'Ιανουάριος_Φεβρουάριος_Μάρτιος_Απρίλιος_Μάιος_Ιούνιος_Ιούλιος_Αύγουστος_Σεπτέμβριος_Οκτώβριος_Νοέμβριος_Δεκέμβριος'.split('_'),\n    monthsGenitiveEl : 'Ιανουαρίου_Φεβρουαρίου_Μαρτίου_Απριλίου_Μαΐου_Ιουνίου_Ιουλίου_Αυγούστου_Σεπτεμβρίου_Οκτωβρίου_Νοεμβρίου_Δεκεμβρίου'.split('_'),\n    months : function (momentToFormat, format) {\n        if (!momentToFormat) {\n            return this._monthsNominativeEl;\n        } else if (/D/.test(format.substring(0, format.indexOf('MMMM')))) { // if there is a day number before 'MMMM'\n            return this._monthsGenitiveEl[momentToFormat.month()];\n        } else {\n            return this._monthsNominativeEl[momentToFormat.month()];\n        }\n    },\n    monthsShort : 'Ιαν_Φεβ_Μαρ_Απρ_Μαϊ_Ιουν_Ιουλ_Αυγ_Σεπ_Οκτ_Νοε_Δεκ'.split('_'),\n    weekdays : 'Κυριακή_Δευτέρα_Τρίτη_Τετάρτη_Πέμπτη_Παρασκευή_Σάββατο'.split('_'),\n    weekdaysShort : 'Κυρ_Δευ_Τρι_Τετ_Πεμ_Παρ_Σαβ'.split('_'),\n    weekdaysMin : 'Κυ_Δε_Τρ_Τε_Πε_Πα_Σα'.split('_'),\n    meridiem : function (hours, minutes, isLower) {\n        if (hours > 11) {\n            return isLower ? 'μμ' : 'ΜΜ';\n        } else {\n            return isLower ? 'πμ' : 'ΠΜ';\n        }\n    },\n    isPM : function (input) {\n        return ((input + '').toLowerCase()[0] === 'μ');\n    },\n    meridiemParse : /[ΠΜ]\\.?Μ?\\.?/i,\n    longDateFormat : {\n        LT : 'h:mm A',\n        LTS : 'h:mm:ss A',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY h:mm A',\n        LLLL : 'dddd, D MMMM YYYY h:mm A'\n    },\n    calendarEl : {\n        sameDay : '[Σήμερα {}] LT',\n        nextDay : '[Αύριο {}] LT',\n        nextWeek : 'dddd [{}] LT',\n        lastDay : '[Χθες {}] LT',\n        lastWeek : function () {\n            switch (this.day()) {\n                case 6:\n                    return '[το προηγούμενο] dddd [{}] LT';\n                default:\n                    return '[την προηγούμενη] dddd [{}] LT';\n            }\n        },\n        sameElse : 'L'\n    },\n    calendar : function (key, mom) {\n        var output = this._calendarEl[key],\n            hours = mom && mom.hours();\n        if (isFunction(output)) {\n            output = output.apply(mom);\n        }\n        return output.replace('{}', (hours % 12 === 1 ? 'στη' : 'στις'));\n    },\n    relativeTime : {\n        future : 'σε %s',\n        past : '%s πριν',\n        s : 'λίγα δευτερόλεπτα',\n        m : 'ένα λεπτό',\n        mm : '%d λεπτά',\n        h : 'μία ώρα',\n        hh : '%d ώρες',\n        d : 'μία μέρα',\n        dd : '%d μέρες',\n        M : 'ένας μήνας',\n        MM : '%d μήνες',\n        y : 'ένας χρόνος',\n        yy : '%d χρόνια'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}η/,\n    ordinal: '%dη',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4st is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : English (Australia) [en-au]\n//! author : Jared Morse : https://github.com/jarcoal\n\nmoment.defineLocale('en-au', {\n    months : 'January_February_March_April_May_June_July_August_September_October_November_December'.split('_'),\n    monthsShort : 'Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec'.split('_'),\n    weekdays : 'Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday'.split('_'),\n    weekdaysShort : 'Sun_Mon_Tue_Wed_Thu_Fri_Sat'.split('_'),\n    weekdaysMin : 'Su_Mo_Tu_We_Th_Fr_Sa'.split('_'),\n    longDateFormat : {\n        LT : 'h:mm A',\n        LTS : 'h:mm:ss A',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY h:mm A',\n        LLLL : 'dddd, D MMMM YYYY h:mm A'\n    },\n    calendar : {\n        sameDay : '[Today at] LT',\n        nextDay : '[Tomorrow at] LT',\n        nextWeek : 'dddd [at] LT',\n        lastDay : '[Yesterday at] LT',\n        lastWeek : '[Last] dddd [at] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'in %s',\n        past : '%s ago',\n        s : 'a few seconds',\n        m : 'a minute',\n        mm : '%d minutes',\n        h : 'an hour',\n        hh : '%d hours',\n        d : 'a day',\n        dd : '%d days',\n        M : 'a month',\n        MM : '%d months',\n        y : 'a year',\n        yy : '%d years'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}(st|nd|rd|th)/,\n    ordinal : function (number) {\n        var b = number % 10,\n            output = (~~(number % 100 / 10) === 1) ? 'th' :\n            (b === 1) ? 'st' :\n            (b === 2) ? 'nd' :\n            (b === 3) ? 'rd' : 'th';\n        return number + output;\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : English (Canada) [en-ca]\n//! author : Jonathan Abourbih : https://github.com/jonbca\n\nmoment.defineLocale('en-ca', {\n    months : 'January_February_March_April_May_June_July_August_September_October_November_December'.split('_'),\n    monthsShort : 'Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec'.split('_'),\n    weekdays : 'Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday'.split('_'),\n    weekdaysShort : 'Sun_Mon_Tue_Wed_Thu_Fri_Sat'.split('_'),\n    weekdaysMin : 'Su_Mo_Tu_We_Th_Fr_Sa'.split('_'),\n    longDateFormat : {\n        LT : 'h:mm A',\n        LTS : 'h:mm:ss A',\n        L : 'YYYY-MM-DD',\n        LL : 'MMMM D, YYYY',\n        LLL : 'MMMM D, YYYY h:mm A',\n        LLLL : 'dddd, MMMM D, YYYY h:mm A'\n    },\n    calendar : {\n        sameDay : '[Today at] LT',\n        nextDay : '[Tomorrow at] LT',\n        nextWeek : 'dddd [at] LT',\n        lastDay : '[Yesterday at] LT',\n        lastWeek : '[Last] dddd [at] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'in %s',\n        past : '%s ago',\n        s : 'a few seconds',\n        m : 'a minute',\n        mm : '%d minutes',\n        h : 'an hour',\n        hh : '%d hours',\n        d : 'a day',\n        dd : '%d days',\n        M : 'a month',\n        MM : '%d months',\n        y : 'a year',\n        yy : '%d years'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}(st|nd|rd|th)/,\n    ordinal : function (number) {\n        var b = number % 10,\n            output = (~~(number % 100 / 10) === 1) ? 'th' :\n            (b === 1) ? 'st' :\n            (b === 2) ? 'nd' :\n            (b === 3) ? 'rd' : 'th';\n        return number + output;\n    }\n});\n\n//! moment.js locale configuration\n//! locale : English (United Kingdom) [en-gb]\n//! author : Chris Gedrim : https://github.com/chrisgedrim\n\nmoment.defineLocale('en-gb', {\n    months : 'January_February_March_April_May_June_July_August_September_October_November_December'.split('_'),\n    monthsShort : 'Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec'.split('_'),\n    weekdays : 'Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday'.split('_'),\n    weekdaysShort : 'Sun_Mon_Tue_Wed_Thu_Fri_Sat'.split('_'),\n    weekdaysMin : 'Su_Mo_Tu_We_Th_Fr_Sa'.split('_'),\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY HH:mm',\n        LLLL : 'dddd, D MMMM YYYY HH:mm'\n    },\n    calendar : {\n        sameDay : '[Today at] LT',\n        nextDay : '[Tomorrow at] LT',\n        nextWeek : 'dddd [at] LT',\n        lastDay : '[Yesterday at] LT',\n        lastWeek : '[Last] dddd [at] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'in %s',\n        past : '%s ago',\n        s : 'a few seconds',\n        m : 'a minute',\n        mm : '%d minutes',\n        h : 'an hour',\n        hh : '%d hours',\n        d : 'a day',\n        dd : '%d days',\n        M : 'a month',\n        MM : '%d months',\n        y : 'a year',\n        yy : '%d years'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}(st|nd|rd|th)/,\n    ordinal : function (number) {\n        var b = number % 10,\n            output = (~~(number % 100 / 10) === 1) ? 'th' :\n            (b === 1) ? 'st' :\n            (b === 2) ? 'nd' :\n            (b === 3) ? 'rd' : 'th';\n        return number + output;\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : English (Ireland) [en-ie]\n//! author : Chris Cartlidge : https://github.com/chriscartlidge\n\nmoment.defineLocale('en-ie', {\n    months : 'January_February_March_April_May_June_July_August_September_October_November_December'.split('_'),\n    monthsShort : 'Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec'.split('_'),\n    weekdays : 'Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday'.split('_'),\n    weekdaysShort : 'Sun_Mon_Tue_Wed_Thu_Fri_Sat'.split('_'),\n    weekdaysMin : 'Su_Mo_Tu_We_Th_Fr_Sa'.split('_'),\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD-MM-YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY HH:mm',\n        LLLL : 'dddd D MMMM YYYY HH:mm'\n    },\n    calendar : {\n        sameDay : '[Today at] LT',\n        nextDay : '[Tomorrow at] LT',\n        nextWeek : 'dddd [at] LT',\n        lastDay : '[Yesterday at] LT',\n        lastWeek : '[Last] dddd [at] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'in %s',\n        past : '%s ago',\n        s : 'a few seconds',\n        m : 'a minute',\n        mm : '%d minutes',\n        h : 'an hour',\n        hh : '%d hours',\n        d : 'a day',\n        dd : '%d days',\n        M : 'a month',\n        MM : '%d months',\n        y : 'a year',\n        yy : '%d years'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}(st|nd|rd|th)/,\n    ordinal : function (number) {\n        var b = number % 10,\n            output = (~~(number % 100 / 10) === 1) ? 'th' :\n            (b === 1) ? 'st' :\n            (b === 2) ? 'nd' :\n            (b === 3) ? 'rd' : 'th';\n        return number + output;\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : English (New Zealand) [en-nz]\n//! author : Luke McGregor : https://github.com/lukemcgregor\n\nmoment.defineLocale('en-nz', {\n    months : 'January_February_March_April_May_June_July_August_September_October_November_December'.split('_'),\n    monthsShort : 'Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec'.split('_'),\n    weekdays : 'Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday'.split('_'),\n    weekdaysShort : 'Sun_Mon_Tue_Wed_Thu_Fri_Sat'.split('_'),\n    weekdaysMin : 'Su_Mo_Tu_We_Th_Fr_Sa'.split('_'),\n    longDateFormat : {\n        LT : 'h:mm A',\n        LTS : 'h:mm:ss A',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY h:mm A',\n        LLLL : 'dddd, D MMMM YYYY h:mm A'\n    },\n    calendar : {\n        sameDay : '[Today at] LT',\n        nextDay : '[Tomorrow at] LT',\n        nextWeek : 'dddd [at] LT',\n        lastDay : '[Yesterday at] LT',\n        lastWeek : '[Last] dddd [at] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'in %s',\n        past : '%s ago',\n        s : 'a few seconds',\n        m : 'a minute',\n        mm : '%d minutes',\n        h : 'an hour',\n        hh : '%d hours',\n        d : 'a day',\n        dd : '%d days',\n        M : 'a month',\n        MM : '%d months',\n        y : 'a year',\n        yy : '%d years'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}(st|nd|rd|th)/,\n    ordinal : function (number) {\n        var b = number % 10,\n            output = (~~(number % 100 / 10) === 1) ? 'th' :\n            (b === 1) ? 'st' :\n            (b === 2) ? 'nd' :\n            (b === 3) ? 'rd' : 'th';\n        return number + output;\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Esperanto [eo]\n//! author : Colin Dean : https://github.com/colindean\n//! author : Mia Nordentoft Imperatori : https://github.com/miestasmia\n//! comment : miestasmia corrected the translation by colindean\n\nmoment.defineLocale('eo', {\n    months : 'januaro_februaro_marto_aprilo_majo_junio_julio_aŭgusto_septembro_oktobro_novembro_decembro'.split('_'),\n    monthsShort : 'jan_feb_mar_apr_maj_jun_jul_aŭg_sep_okt_nov_dec'.split('_'),\n    weekdays : 'dimanĉo_lundo_mardo_merkredo_ĵaŭdo_vendredo_sabato'.split('_'),\n    weekdaysShort : 'dim_lun_mard_merk_ĵaŭ_ven_sab'.split('_'),\n    weekdaysMin : 'di_lu_ma_me_ĵa_ve_sa'.split('_'),\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'YYYY-MM-DD',\n        LL : 'D[-a de] MMMM, YYYY',\n        LLL : 'D[-a de] MMMM, YYYY HH:mm',\n        LLLL : 'dddd, [la] D[-a de] MMMM, YYYY HH:mm'\n    },\n    meridiemParse: /[ap]\\.t\\.m/i,\n    isPM: function (input) {\n        return input.charAt(0).toLowerCase() === 'p';\n    },\n    meridiem : function (hours, minutes, isLower) {\n        if (hours > 11) {\n            return isLower ? 'p.t.m.' : 'P.T.M.';\n        } else {\n            return isLower ? 'a.t.m.' : 'A.T.M.';\n        }\n    },\n    calendar : {\n        sameDay : '[Hodiaŭ je] LT',\n        nextDay : '[Morgaŭ je] LT',\n        nextWeek : 'dddd [je] LT',\n        lastDay : '[Hieraŭ je] LT',\n        lastWeek : '[pasinta] dddd [je] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'post %s',\n        past : 'antaŭ %s',\n        s : 'sekundoj',\n        m : 'minuto',\n        mm : '%d minutoj',\n        h : 'horo',\n        hh : '%d horoj',\n        d : 'tago',//ne 'diurno', ĉar estas uzita por proksimumo\n        dd : '%d tagoj',\n        M : 'monato',\n        MM : '%d monatoj',\n        y : 'jaro',\n        yy : '%d jaroj'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}a/,\n    ordinal : '%da',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 7  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Spanish (Dominican Republic) [es-do]\n\nvar monthsShortDot = 'ene._feb._mar._abr._may._jun._jul._ago._sep._oct._nov._dic.'.split('_');\nvar monthsShort$1 = 'ene_feb_mar_abr_may_jun_jul_ago_sep_oct_nov_dic'.split('_');\n\nmoment.defineLocale('es-do', {\n    months : 'enero_febrero_marzo_abril_mayo_junio_julio_agosto_septiembre_octubre_noviembre_diciembre'.split('_'),\n    monthsShort : function (m, format) {\n        if (!m) {\n            return monthsShortDot;\n        } else if (/-MMM-/.test(format)) {\n            return monthsShort$1[m.month()];\n        } else {\n            return monthsShortDot[m.month()];\n        }\n    },\n    monthsParseExact : true,\n    weekdays : 'domingo_lunes_martes_miércoles_jueves_viernes_sábado'.split('_'),\n    weekdaysShort : 'dom._lun._mar._mié._jue._vie._sáb.'.split('_'),\n    weekdaysMin : 'do_lu_ma_mi_ju_vi_sá'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat : {\n        LT : 'h:mm A',\n        LTS : 'h:mm:ss A',\n        L : 'DD/MM/YYYY',\n        LL : 'D [de] MMMM [de] YYYY',\n        LLL : 'D [de] MMMM [de] YYYY h:mm A',\n        LLLL : 'dddd, D [de] MMMM [de] YYYY h:mm A'\n    },\n    calendar : {\n        sameDay : function () {\n            return '[hoy a la' + ((this.hours() !== 1) ? 's' : '') + '] LT';\n        },\n        nextDay : function () {\n            return '[mañana a la' + ((this.hours() !== 1) ? 's' : '') + '] LT';\n        },\n        nextWeek : function () {\n            return 'dddd [a la' + ((this.hours() !== 1) ? 's' : '') + '] LT';\n        },\n        lastDay : function () {\n            return '[ayer a la' + ((this.hours() !== 1) ? 's' : '') + '] LT';\n        },\n        lastWeek : function () {\n            return '[el] dddd [pasado a la' + ((this.hours() !== 1) ? 's' : '') + '] LT';\n        },\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'en %s',\n        past : 'hace %s',\n        s : 'unos segundos',\n        m : 'un minuto',\n        mm : '%d minutos',\n        h : 'una hora',\n        hh : '%d horas',\n        d : 'un día',\n        dd : '%d días',\n        M : 'un mes',\n        MM : '%d meses',\n        y : 'un año',\n        yy : '%d años'\n    },\n    dayOfMonthOrdinalParse : /\\d{1,2}º/,\n    ordinal : '%dº',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Spanish [es]\n//! author : Julio Napurí : https://github.com/julionc\n\nvar monthsShortDot$1 = 'ene._feb._mar._abr._may._jun._jul._ago._sep._oct._nov._dic.'.split('_');\nvar monthsShort$2 = 'ene_feb_mar_abr_may_jun_jul_ago_sep_oct_nov_dic'.split('_');\n\nmoment.defineLocale('es', {\n    months : 'enero_febrero_marzo_abril_mayo_junio_julio_agosto_septiembre_octubre_noviembre_diciembre'.split('_'),\n    monthsShort : function (m, format) {\n        if (!m) {\n            return monthsShortDot$1;\n        } else if (/-MMM-/.test(format)) {\n            return monthsShort$2[m.month()];\n        } else {\n            return monthsShortDot$1[m.month()];\n        }\n    },\n    monthsParseExact : true,\n    weekdays : 'domingo_lunes_martes_miércoles_jueves_viernes_sábado'.split('_'),\n    weekdaysShort : 'dom._lun._mar._mié._jue._vie._sáb.'.split('_'),\n    weekdaysMin : 'do_lu_ma_mi_ju_vi_sá'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat : {\n        LT : 'H:mm',\n        LTS : 'H:mm:ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D [de] MMMM [de] YYYY',\n        LLL : 'D [de] MMMM [de] YYYY H:mm',\n        LLLL : 'dddd, D [de] MMMM [de] YYYY H:mm'\n    },\n    calendar : {\n        sameDay : function () {\n            return '[hoy a la' + ((this.hours() !== 1) ? 's' : '') + '] LT';\n        },\n        nextDay : function () {\n            return '[mañana a la' + ((this.hours() !== 1) ? 's' : '') + '] LT';\n        },\n        nextWeek : function () {\n            return 'dddd [a la' + ((this.hours() !== 1) ? 's' : '') + '] LT';\n        },\n        lastDay : function () {\n            return '[ayer a la' + ((this.hours() !== 1) ? 's' : '') + '] LT';\n        },\n        lastWeek : function () {\n            return '[el] dddd [pasado a la' + ((this.hours() !== 1) ? 's' : '') + '] LT';\n        },\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'en %s',\n        past : 'hace %s',\n        s : 'unos segundos',\n        m : 'un minuto',\n        mm : '%d minutos',\n        h : 'una hora',\n        hh : '%d horas',\n        d : 'un día',\n        dd : '%d días',\n        M : 'un mes',\n        MM : '%d meses',\n        y : 'un año',\n        yy : '%d años'\n    },\n    dayOfMonthOrdinalParse : /\\d{1,2}º/,\n    ordinal : '%dº',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Estonian [et]\n//! author : Henry Kehlmann : https://github.com/madhenry\n//! improvements : Illimar Tambek : https://github.com/ragulka\n\nfunction processRelativeTime$3(number, withoutSuffix, key, isFuture) {\n    var format = {\n        's' : ['mõne sekundi', 'mõni sekund', 'paar sekundit'],\n        'm' : ['ühe minuti', 'üks minut'],\n        'mm': [number + ' minuti', number + ' minutit'],\n        'h' : ['ühe tunni', 'tund aega', 'üks tund'],\n        'hh': [number + ' tunni', number + ' tundi'],\n        'd' : ['ühe päeva', 'üks päev'],\n        'M' : ['kuu aja', 'kuu aega', 'üks kuu'],\n        'MM': [number + ' kuu', number + ' kuud'],\n        'y' : ['ühe aasta', 'aasta', 'üks aasta'],\n        'yy': [number + ' aasta', number + ' aastat']\n    };\n    if (withoutSuffix) {\n        return format[key][2] ? format[key][2] : format[key][1];\n    }\n    return isFuture ? format[key][0] : format[key][1];\n}\n\nmoment.defineLocale('et', {\n    months        : 'jaanuar_veebruar_märts_aprill_mai_juuni_juuli_august_september_oktoober_november_detsember'.split('_'),\n    monthsShort   : 'jaan_veebr_märts_apr_mai_juuni_juuli_aug_sept_okt_nov_dets'.split('_'),\n    weekdays      : 'pühapäev_esmaspäev_teisipäev_kolmapäev_neljapäev_reede_laupäev'.split('_'),\n    weekdaysShort : 'P_E_T_K_N_R_L'.split('_'),\n    weekdaysMin   : 'P_E_T_K_N_R_L'.split('_'),\n    longDateFormat : {\n        LT   : 'H:mm',\n        LTS : 'H:mm:ss',\n        L    : 'DD.MM.YYYY',\n        LL   : 'D. MMMM YYYY',\n        LLL  : 'D. MMMM YYYY H:mm',\n        LLLL : 'dddd, D. MMMM YYYY H:mm'\n    },\n    calendar : {\n        sameDay  : '[Täna,] LT',\n        nextDay  : '[Homme,] LT',\n        nextWeek : '[Järgmine] dddd LT',\n        lastDay  : '[Eile,] LT',\n        lastWeek : '[Eelmine] dddd LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : '%s pärast',\n        past   : '%s tagasi',\n        s      : processRelativeTime$3,\n        m      : processRelativeTime$3,\n        mm     : processRelativeTime$3,\n        h      : processRelativeTime$3,\n        hh     : processRelativeTime$3,\n        d      : processRelativeTime$3,\n        dd     : '%d päeva',\n        M      : processRelativeTime$3,\n        MM     : processRelativeTime$3,\n        y      : processRelativeTime$3,\n        yy     : processRelativeTime$3\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}\\./,\n    ordinal : '%d.',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Basque [eu]\n//! author : Eneko Illarramendi : https://github.com/eillarra\n\nmoment.defineLocale('eu', {\n    months : 'urtarrila_otsaila_martxoa_apirila_maiatza_ekaina_uztaila_abuztua_iraila_urria_azaroa_abendua'.split('_'),\n    monthsShort : 'urt._ots._mar._api._mai._eka._uzt._abu._ira._urr._aza._abe.'.split('_'),\n    monthsParseExact : true,\n    weekdays : 'igandea_astelehena_asteartea_asteazkena_osteguna_ostirala_larunbata'.split('_'),\n    weekdaysShort : 'ig._al._ar._az._og._ol._lr.'.split('_'),\n    weekdaysMin : 'ig_al_ar_az_og_ol_lr'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'YYYY-MM-DD',\n        LL : 'YYYY[ko] MMMM[ren] D[a]',\n        LLL : 'YYYY[ko] MMMM[ren] D[a] HH:mm',\n        LLLL : 'dddd, YYYY[ko] MMMM[ren] D[a] HH:mm',\n        l : 'YYYY-M-D',\n        ll : 'YYYY[ko] MMM D[a]',\n        lll : 'YYYY[ko] MMM D[a] HH:mm',\n        llll : 'ddd, YYYY[ko] MMM D[a] HH:mm'\n    },\n    calendar : {\n        sameDay : '[gaur] LT[etan]',\n        nextDay : '[bihar] LT[etan]',\n        nextWeek : 'dddd LT[etan]',\n        lastDay : '[atzo] LT[etan]',\n        lastWeek : '[aurreko] dddd LT[etan]',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : '%s barru',\n        past : 'duela %s',\n        s : 'segundo batzuk',\n        m : 'minutu bat',\n        mm : '%d minutu',\n        h : 'ordu bat',\n        hh : '%d ordu',\n        d : 'egun bat',\n        dd : '%d egun',\n        M : 'hilabete bat',\n        MM : '%d hilabete',\n        y : 'urte bat',\n        yy : '%d urte'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}\\./,\n    ordinal : '%d.',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 7  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Persian [fa]\n//! author : Ebrahim Byagowi : https://github.com/ebraminio\n\nvar symbolMap$5 = {\n    '1': '۱',\n    '2': '۲',\n    '3': '۳',\n    '4': '۴',\n    '5': '۵',\n    '6': '۶',\n    '7': '۷',\n    '8': '۸',\n    '9': '۹',\n    '0': '۰'\n};\nvar numberMap$4 = {\n    '۱': '1',\n    '۲': '2',\n    '۳': '3',\n    '۴': '4',\n    '۵': '5',\n    '۶': '6',\n    '۷': '7',\n    '۸': '8',\n    '۹': '9',\n    '۰': '0'\n};\n\nmoment.defineLocale('fa', {\n    months : 'ژانویه_فوریه_مارس_آوریل_مه_ژوئن_ژوئیه_اوت_سپتامبر_اکتبر_نوامبر_دسامبر'.split('_'),\n    monthsShort : 'ژانویه_فوریه_مارس_آوریل_مه_ژوئن_ژوئیه_اوت_سپتامبر_اکتبر_نوامبر_دسامبر'.split('_'),\n    weekdays : 'یک\\u200cشنبه_دوشنبه_سه\\u200cشنبه_چهارشنبه_پنج\\u200cشنبه_جمعه_شنبه'.split('_'),\n    weekdaysShort : 'یک\\u200cشنبه_دوشنبه_سه\\u200cشنبه_چهارشنبه_پنج\\u200cشنبه_جمعه_شنبه'.split('_'),\n    weekdaysMin : 'ی_د_س_چ_پ_ج_ش'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY HH:mm',\n        LLLL : 'dddd, D MMMM YYYY HH:mm'\n    },\n    meridiemParse: /قبل از ظهر|بعد از ظهر/,\n    isPM: function (input) {\n        return /بعد از ظهر/.test(input);\n    },\n    meridiem : function (hour, minute, isLower) {\n        if (hour < 12) {\n            return 'قبل از ظهر';\n        } else {\n            return 'بعد از ظهر';\n        }\n    },\n    calendar : {\n        sameDay : '[امروز ساعت] LT',\n        nextDay : '[فردا ساعت] LT',\n        nextWeek : 'dddd [ساعت] LT',\n        lastDay : '[دیروز ساعت] LT',\n        lastWeek : 'dddd [پیش] [ساعت] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'در %s',\n        past : '%s پیش',\n        s : 'چند ثانیه',\n        m : 'یک دقیقه',\n        mm : '%d دقیقه',\n        h : 'یک ساعت',\n        hh : '%d ساعت',\n        d : 'یک روز',\n        dd : '%d روز',\n        M : 'یک ماه',\n        MM : '%d ماه',\n        y : 'یک سال',\n        yy : '%d سال'\n    },\n    preparse: function (string) {\n        return string.replace(/[۰-۹]/g, function (match) {\n            return numberMap$4[match];\n        }).replace(/،/g, ',');\n    },\n    postformat: function (string) {\n        return string.replace(/\\d/g, function (match) {\n            return symbolMap$5[match];\n        }).replace(/,/g, '،');\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}م/,\n    ordinal : '%dم',\n    week : {\n        dow : 6, // Saturday is the first day of the week.\n        doy : 12 // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Finnish [fi]\n//! author : Tarmo Aidantausta : https://github.com/bleadof\n\nvar numbersPast = 'nolla yksi kaksi kolme neljä viisi kuusi seitsemän kahdeksan yhdeksän'.split(' ');\nvar numbersFuture = [\n        'nolla', 'yhden', 'kahden', 'kolmen', 'neljän', 'viiden', 'kuuden',\n        numbersPast[7], numbersPast[8], numbersPast[9]\n    ];\nfunction translate$2(number, withoutSuffix, key, isFuture) {\n    var result = '';\n    switch (key) {\n        case 's':\n            return isFuture ? 'muutaman sekunnin' : 'muutama sekunti';\n        case 'm':\n            return isFuture ? 'minuutin' : 'minuutti';\n        case 'mm':\n            result = isFuture ? 'minuutin' : 'minuuttia';\n            break;\n        case 'h':\n            return isFuture ? 'tunnin' : 'tunti';\n        case 'hh':\n            result = isFuture ? 'tunnin' : 'tuntia';\n            break;\n        case 'd':\n            return isFuture ? 'päivän' : 'päivä';\n        case 'dd':\n            result = isFuture ? 'päivän' : 'päivää';\n            break;\n        case 'M':\n            return isFuture ? 'kuukauden' : 'kuukausi';\n        case 'MM':\n            result = isFuture ? 'kuukauden' : 'kuukautta';\n            break;\n        case 'y':\n            return isFuture ? 'vuoden' : 'vuosi';\n        case 'yy':\n            result = isFuture ? 'vuoden' : 'vuotta';\n            break;\n    }\n    result = verbalNumber(number, isFuture) + ' ' + result;\n    return result;\n}\nfunction verbalNumber(number, isFuture) {\n    return number < 10 ? (isFuture ? numbersFuture[number] : numbersPast[number]) : number;\n}\n\nmoment.defineLocale('fi', {\n    months : 'tammikuu_helmikuu_maaliskuu_huhtikuu_toukokuu_kesäkuu_heinäkuu_elokuu_syyskuu_lokakuu_marraskuu_joulukuu'.split('_'),\n    monthsShort : 'tammi_helmi_maalis_huhti_touko_kesä_heinä_elo_syys_loka_marras_joulu'.split('_'),\n    weekdays : 'sunnuntai_maanantai_tiistai_keskiviikko_torstai_perjantai_lauantai'.split('_'),\n    weekdaysShort : 'su_ma_ti_ke_to_pe_la'.split('_'),\n    weekdaysMin : 'su_ma_ti_ke_to_pe_la'.split('_'),\n    longDateFormat : {\n        LT : 'HH.mm',\n        LTS : 'HH.mm.ss',\n        L : 'DD.MM.YYYY',\n        LL : 'Do MMMM[ta] YYYY',\n        LLL : 'Do MMMM[ta] YYYY, [klo] HH.mm',\n        LLLL : 'dddd, Do MMMM[ta] YYYY, [klo] HH.mm',\n        l : 'D.M.YYYY',\n        ll : 'Do MMM YYYY',\n        lll : 'Do MMM YYYY, [klo] HH.mm',\n        llll : 'ddd, Do MMM YYYY, [klo] HH.mm'\n    },\n    calendar : {\n        sameDay : '[tänään] [klo] LT',\n        nextDay : '[huomenna] [klo] LT',\n        nextWeek : 'dddd [klo] LT',\n        lastDay : '[eilen] [klo] LT',\n        lastWeek : '[viime] dddd[na] [klo] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : '%s päästä',\n        past : '%s sitten',\n        s : translate$2,\n        m : translate$2,\n        mm : translate$2,\n        h : translate$2,\n        hh : translate$2,\n        d : translate$2,\n        dd : translate$2,\n        M : translate$2,\n        MM : translate$2,\n        y : translate$2,\n        yy : translate$2\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}\\./,\n    ordinal : '%d.',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Faroese [fo]\n//! author : Ragnar Johannesen : https://github.com/ragnar123\n\nmoment.defineLocale('fo', {\n    months : 'januar_februar_mars_apríl_mai_juni_juli_august_september_oktober_november_desember'.split('_'),\n    monthsShort : 'jan_feb_mar_apr_mai_jun_jul_aug_sep_okt_nov_des'.split('_'),\n    weekdays : 'sunnudagur_mánadagur_týsdagur_mikudagur_hósdagur_fríggjadagur_leygardagur'.split('_'),\n    weekdaysShort : 'sun_mán_týs_mik_hós_frí_ley'.split('_'),\n    weekdaysMin : 'su_má_tý_mi_hó_fr_le'.split('_'),\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY HH:mm',\n        LLLL : 'dddd D. MMMM, YYYY HH:mm'\n    },\n    calendar : {\n        sameDay : '[Í dag kl.] LT',\n        nextDay : '[Í morgin kl.] LT',\n        nextWeek : 'dddd [kl.] LT',\n        lastDay : '[Í gjár kl.] LT',\n        lastWeek : '[síðstu] dddd [kl] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'um %s',\n        past : '%s síðani',\n        s : 'fá sekund',\n        m : 'ein minutt',\n        mm : '%d minuttir',\n        h : 'ein tími',\n        hh : '%d tímar',\n        d : 'ein dagur',\n        dd : '%d dagar',\n        M : 'ein mánaði',\n        MM : '%d mánaðir',\n        y : 'eitt ár',\n        yy : '%d ár'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}\\./,\n    ordinal : '%d.',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : French (Canada) [fr-ca]\n//! author : Jonathan Abourbih : https://github.com/jonbca\n\nmoment.defineLocale('fr-ca', {\n    months : 'janvier_février_mars_avril_mai_juin_juillet_août_septembre_octobre_novembre_décembre'.split('_'),\n    monthsShort : 'janv._févr._mars_avr._mai_juin_juil._août_sept._oct._nov._déc.'.split('_'),\n    monthsParseExact : true,\n    weekdays : 'dimanche_lundi_mardi_mercredi_jeudi_vendredi_samedi'.split('_'),\n    weekdaysShort : 'dim._lun._mar._mer._jeu._ven._sam.'.split('_'),\n    weekdaysMin : 'Di_Lu_Ma_Me_Je_Ve_Sa'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'YYYY-MM-DD',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY HH:mm',\n        LLLL : 'dddd D MMMM YYYY HH:mm'\n    },\n    calendar : {\n        sameDay : '[Aujourd’hui à] LT',\n        nextDay : '[Demain à] LT',\n        nextWeek : 'dddd [à] LT',\n        lastDay : '[Hier à] LT',\n        lastWeek : 'dddd [dernier à] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'dans %s',\n        past : 'il y a %s',\n        s : 'quelques secondes',\n        m : 'une minute',\n        mm : '%d minutes',\n        h : 'une heure',\n        hh : '%d heures',\n        d : 'un jour',\n        dd : '%d jours',\n        M : 'un mois',\n        MM : '%d mois',\n        y : 'un an',\n        yy : '%d ans'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}(er|e)/,\n    ordinal : function (number, period) {\n        switch (period) {\n            // Words with masculine grammatical gender: mois, trimestre, jour\n            default:\n            case 'M':\n            case 'Q':\n            case 'D':\n            case 'DDD':\n            case 'd':\n                return number + (number === 1 ? 'er' : 'e');\n\n            // Words with feminine grammatical gender: semaine\n            case 'w':\n            case 'W':\n                return number + (number === 1 ? 're' : 'e');\n        }\n    }\n});\n\n//! moment.js locale configuration\n//! locale : French (Switzerland) [fr-ch]\n//! author : Gaspard Bucher : https://github.com/gaspard\n\nmoment.defineLocale('fr-ch', {\n    months : 'janvier_février_mars_avril_mai_juin_juillet_août_septembre_octobre_novembre_décembre'.split('_'),\n    monthsShort : 'janv._févr._mars_avr._mai_juin_juil._août_sept._oct._nov._déc.'.split('_'),\n    monthsParseExact : true,\n    weekdays : 'dimanche_lundi_mardi_mercredi_jeudi_vendredi_samedi'.split('_'),\n    weekdaysShort : 'dim._lun._mar._mer._jeu._ven._sam.'.split('_'),\n    weekdaysMin : 'Di_Lu_Ma_Me_Je_Ve_Sa'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD.MM.YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY HH:mm',\n        LLLL : 'dddd D MMMM YYYY HH:mm'\n    },\n    calendar : {\n        sameDay : '[Aujourd’hui à] LT',\n        nextDay : '[Demain à] LT',\n        nextWeek : 'dddd [à] LT',\n        lastDay : '[Hier à] LT',\n        lastWeek : 'dddd [dernier à] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'dans %s',\n        past : 'il y a %s',\n        s : 'quelques secondes',\n        m : 'une minute',\n        mm : '%d minutes',\n        h : 'une heure',\n        hh : '%d heures',\n        d : 'un jour',\n        dd : '%d jours',\n        M : 'un mois',\n        MM : '%d mois',\n        y : 'un an',\n        yy : '%d ans'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}(er|e)/,\n    ordinal : function (number, period) {\n        switch (period) {\n            // Words with masculine grammatical gender: mois, trimestre, jour\n            default:\n            case 'M':\n            case 'Q':\n            case 'D':\n            case 'DDD':\n            case 'd':\n                return number + (number === 1 ? 'er' : 'e');\n\n            // Words with feminine grammatical gender: semaine\n            case 'w':\n            case 'W':\n                return number + (number === 1 ? 're' : 'e');\n        }\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : French [fr]\n//! author : John Fischer : https://github.com/jfroffice\n\nmoment.defineLocale('fr', {\n    months : 'janvier_février_mars_avril_mai_juin_juillet_août_septembre_octobre_novembre_décembre'.split('_'),\n    monthsShort : 'janv._févr._mars_avr._mai_juin_juil._août_sept._oct._nov._déc.'.split('_'),\n    monthsParseExact : true,\n    weekdays : 'dimanche_lundi_mardi_mercredi_jeudi_vendredi_samedi'.split('_'),\n    weekdaysShort : 'dim._lun._mar._mer._jeu._ven._sam.'.split('_'),\n    weekdaysMin : 'Di_Lu_Ma_Me_Je_Ve_Sa'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY HH:mm',\n        LLLL : 'dddd D MMMM YYYY HH:mm'\n    },\n    calendar : {\n        sameDay : '[Aujourd’hui à] LT',\n        nextDay : '[Demain à] LT',\n        nextWeek : 'dddd [à] LT',\n        lastDay : '[Hier à] LT',\n        lastWeek : 'dddd [dernier à] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'dans %s',\n        past : 'il y a %s',\n        s : 'quelques secondes',\n        m : 'une minute',\n        mm : '%d minutes',\n        h : 'une heure',\n        hh : '%d heures',\n        d : 'un jour',\n        dd : '%d jours',\n        M : 'un mois',\n        MM : '%d mois',\n        y : 'un an',\n        yy : '%d ans'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}(er|)/,\n    ordinal : function (number, period) {\n        switch (period) {\n            // TODO: Return 'e' when day of month > 1. Move this case inside\n            // block for masculine words below.\n            // See https://github.com/moment/moment/issues/3375\n            case 'D':\n                return number + (number === 1 ? 'er' : '');\n\n            // Words with masculine grammatical gender: mois, trimestre, jour\n            default:\n            case 'M':\n            case 'Q':\n            case 'DDD':\n            case 'd':\n                return number + (number === 1 ? 'er' : 'e');\n\n            // Words with feminine grammatical gender: semaine\n            case 'w':\n            case 'W':\n                return number + (number === 1 ? 're' : 'e');\n        }\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Frisian [fy]\n//! author : Robin van der Vliet : https://github.com/robin0van0der0v\n\nvar monthsShortWithDots = 'jan._feb._mrt._apr._mai_jun._jul._aug._sep._okt._nov._des.'.split('_');\nvar monthsShortWithoutDots = 'jan_feb_mrt_apr_mai_jun_jul_aug_sep_okt_nov_des'.split('_');\n\nmoment.defineLocale('fy', {\n    months : 'jannewaris_febrewaris_maart_april_maaie_juny_july_augustus_septimber_oktober_novimber_desimber'.split('_'),\n    monthsShort : function (m, format) {\n        if (!m) {\n            return monthsShortWithDots;\n        } else if (/-MMM-/.test(format)) {\n            return monthsShortWithoutDots[m.month()];\n        } else {\n            return monthsShortWithDots[m.month()];\n        }\n    },\n    monthsParseExact : true,\n    weekdays : 'snein_moandei_tiisdei_woansdei_tongersdei_freed_sneon'.split('_'),\n    weekdaysShort : 'si._mo._ti._wo._to._fr._so.'.split('_'),\n    weekdaysMin : 'Si_Mo_Ti_Wo_To_Fr_So'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD-MM-YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY HH:mm',\n        LLLL : 'dddd D MMMM YYYY HH:mm'\n    },\n    calendar : {\n        sameDay: '[hjoed om] LT',\n        nextDay: '[moarn om] LT',\n        nextWeek: 'dddd [om] LT',\n        lastDay: '[juster om] LT',\n        lastWeek: '[ôfrûne] dddd [om] LT',\n        sameElse: 'L'\n    },\n    relativeTime : {\n        future : 'oer %s',\n        past : '%s lyn',\n        s : 'in pear sekonden',\n        m : 'ien minút',\n        mm : '%d minuten',\n        h : 'ien oere',\n        hh : '%d oeren',\n        d : 'ien dei',\n        dd : '%d dagen',\n        M : 'ien moanne',\n        MM : '%d moannen',\n        y : 'ien jier',\n        yy : '%d jierren'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}(ste|de)/,\n    ordinal : function (number) {\n        return number + ((number === 1 || number === 8 || number >= 20) ? 'ste' : 'de');\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Scottish Gaelic [gd]\n//! author : Jon Ashdown : https://github.com/jonashdown\n\nvar months$4 = [\n    'Am Faoilleach', 'An Gearran', 'Am Màrt', 'An Giblean', 'An Cèitean', 'An t-Ògmhios', 'An t-Iuchar', 'An Lùnastal', 'An t-Sultain', 'An Dàmhair', 'An t-Samhain', 'An Dùbhlachd'\n];\n\nvar monthsShort$3 = ['Faoi', 'Gear', 'Màrt', 'Gibl', 'Cèit', 'Ògmh', 'Iuch', 'Lùn', 'Sult', 'Dàmh', 'Samh', 'Dùbh'];\n\nvar weekdays$1 = ['Didòmhnaich', 'Diluain', 'Dimàirt', 'Diciadain', 'Diardaoin', 'Dihaoine', 'Disathairne'];\n\nvar weekdaysShort = ['Did', 'Dil', 'Dim', 'Dic', 'Dia', 'Dih', 'Dis'];\n\nvar weekdaysMin = ['Dò', 'Lu', 'Mà', 'Ci', 'Ar', 'Ha', 'Sa'];\n\nmoment.defineLocale('gd', {\n    months : months$4,\n    monthsShort : monthsShort$3,\n    monthsParseExact : true,\n    weekdays : weekdays$1,\n    weekdaysShort : weekdaysShort,\n    weekdaysMin : weekdaysMin,\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY HH:mm',\n        LLLL : 'dddd, D MMMM YYYY HH:mm'\n    },\n    calendar : {\n        sameDay : '[An-diugh aig] LT',\n        nextDay : '[A-màireach aig] LT',\n        nextWeek : 'dddd [aig] LT',\n        lastDay : '[An-dè aig] LT',\n        lastWeek : 'dddd [seo chaidh] [aig] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'ann an %s',\n        past : 'bho chionn %s',\n        s : 'beagan diogan',\n        m : 'mionaid',\n        mm : '%d mionaidean',\n        h : 'uair',\n        hh : '%d uairean',\n        d : 'latha',\n        dd : '%d latha',\n        M : 'mìos',\n        MM : '%d mìosan',\n        y : 'bliadhna',\n        yy : '%d bliadhna'\n    },\n    dayOfMonthOrdinalParse : /\\d{1,2}(d|na|mh)/,\n    ordinal : function (number) {\n        var output = number === 1 ? 'd' : number % 10 === 2 ? 'na' : 'mh';\n        return number + output;\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Galician [gl]\n//! author : Juan G. Hurtado : https://github.com/juanghurtado\n\nmoment.defineLocale('gl', {\n    months : 'xaneiro_febreiro_marzo_abril_maio_xuño_xullo_agosto_setembro_outubro_novembro_decembro'.split('_'),\n    monthsShort : 'xan._feb._mar._abr._mai._xuñ._xul._ago._set._out._nov._dec.'.split('_'),\n    monthsParseExact: true,\n    weekdays : 'domingo_luns_martes_mércores_xoves_venres_sábado'.split('_'),\n    weekdaysShort : 'dom._lun._mar._mér._xov._ven._sáb.'.split('_'),\n    weekdaysMin : 'do_lu_ma_mé_xo_ve_sá'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat : {\n        LT : 'H:mm',\n        LTS : 'H:mm:ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D [de] MMMM [de] YYYY',\n        LLL : 'D [de] MMMM [de] YYYY H:mm',\n        LLLL : 'dddd, D [de] MMMM [de] YYYY H:mm'\n    },\n    calendar : {\n        sameDay : function () {\n            return '[hoxe ' + ((this.hours() !== 1) ? 'ás' : 'á') + '] LT';\n        },\n        nextDay : function () {\n            return '[mañá ' + ((this.hours() !== 1) ? 'ás' : 'á') + '] LT';\n        },\n        nextWeek : function () {\n            return 'dddd [' + ((this.hours() !== 1) ? 'ás' : 'a') + '] LT';\n        },\n        lastDay : function () {\n            return '[onte ' + ((this.hours() !== 1) ? 'á' : 'a') + '] LT';\n        },\n        lastWeek : function () {\n            return '[o] dddd [pasado ' + ((this.hours() !== 1) ? 'ás' : 'a') + '] LT';\n        },\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : function (str) {\n            if (str.indexOf('un') === 0) {\n                return 'n' + str;\n            }\n            return 'en ' + str;\n        },\n        past : 'hai %s',\n        s : 'uns segundos',\n        m : 'un minuto',\n        mm : '%d minutos',\n        h : 'unha hora',\n        hh : '%d horas',\n        d : 'un día',\n        dd : '%d días',\n        M : 'un mes',\n        MM : '%d meses',\n        y : 'un ano',\n        yy : '%d anos'\n    },\n    dayOfMonthOrdinalParse : /\\d{1,2}º/,\n    ordinal : '%dº',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Konkani Latin script [gom-latn]\n//! author : The Discoverer : https://github.com/WikiDiscoverer\n\nfunction processRelativeTime$4(number, withoutSuffix, key, isFuture) {\n    var format = {\n        's': ['thodde secondanim', 'thodde second'],\n        'm': ['eka mintan', 'ek minute'],\n        'mm': [number + ' mintanim', number + ' mintam'],\n        'h': ['eka horan', 'ek hor'],\n        'hh': [number + ' horanim', number + ' hor'],\n        'd': ['eka disan', 'ek dis'],\n        'dd': [number + ' disanim', number + ' dis'],\n        'M': ['eka mhoinean', 'ek mhoino'],\n        'MM': [number + ' mhoineanim', number + ' mhoine'],\n        'y': ['eka vorsan', 'ek voros'],\n        'yy': [number + ' vorsanim', number + ' vorsam']\n    };\n    return withoutSuffix ? format[key][0] : format[key][1];\n}\n\nmoment.defineLocale('gom-latn', {\n    months : 'Janer_Febrer_Mars_Abril_Mai_Jun_Julai_Agost_Setembr_Otubr_Novembr_Dezembr'.split('_'),\n    monthsShort : 'Jan._Feb._Mars_Abr._Mai_Jun_Jul._Ago._Set._Otu._Nov._Dez.'.split('_'),\n    monthsParseExact : true,\n    weekdays : 'Aitar_Somar_Mongllar_Budvar_Brestar_Sukrar_Son\\'var'.split('_'),\n    weekdaysShort : 'Ait._Som._Mon._Bud._Bre._Suk._Son.'.split('_'),\n    weekdaysMin : 'Ai_Sm_Mo_Bu_Br_Su_Sn'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat : {\n        LT : 'A h:mm [vazta]',\n        LTS : 'A h:mm:ss [vazta]',\n        L : 'DD-MM-YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY A h:mm [vazta]',\n        LLLL : 'dddd, MMMM[achea] Do, YYYY, A h:mm [vazta]',\n        llll: 'ddd, D MMM YYYY, A h:mm [vazta]'\n    },\n    calendar : {\n        sameDay: '[Aiz] LT',\n        nextDay: '[Faleam] LT',\n        nextWeek: '[Ieta to] dddd[,] LT',\n        lastDay: '[Kal] LT',\n        lastWeek: '[Fatlo] dddd[,] LT',\n        sameElse: 'L'\n    },\n    relativeTime : {\n        future : '%s',\n        past : '%s adim',\n        s : processRelativeTime$4,\n        m : processRelativeTime$4,\n        mm : processRelativeTime$4,\n        h : processRelativeTime$4,\n        hh : processRelativeTime$4,\n        d : processRelativeTime$4,\n        dd : processRelativeTime$4,\n        M : processRelativeTime$4,\n        MM : processRelativeTime$4,\n        y : processRelativeTime$4,\n        yy : processRelativeTime$4\n    },\n    dayOfMonthOrdinalParse : /\\d{1,2}(er)/,\n    ordinal : function (number, period) {\n        switch (period) {\n            // the ordinal 'er' only applies to day of the month\n            case 'D':\n                return number + 'er';\n            default:\n            case 'M':\n            case 'Q':\n            case 'DDD':\n            case 'd':\n            case 'w':\n            case 'W':\n                return number;\n        }\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    },\n    meridiemParse: /rati|sokalli|donparam|sanje/,\n    meridiemHour : function (hour, meridiem) {\n        if (hour === 12) {\n            hour = 0;\n        }\n        if (meridiem === 'rati') {\n            return hour < 4 ? hour : hour + 12;\n        } else if (meridiem === 'sokalli') {\n            return hour;\n        } else if (meridiem === 'donparam') {\n            return hour > 12 ? hour : hour + 12;\n        } else if (meridiem === 'sanje') {\n            return hour + 12;\n        }\n    },\n    meridiem : function (hour, minute, isLower) {\n        if (hour < 4) {\n            return 'rati';\n        } else if (hour < 12) {\n            return 'sokalli';\n        } else if (hour < 16) {\n            return 'donparam';\n        } else if (hour < 20) {\n            return 'sanje';\n        } else {\n            return 'rati';\n        }\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Hebrew [he]\n//! author : Tomer Cohen : https://github.com/tomer\n//! author : Moshe Simantov : https://github.com/DevelopmentIL\n//! author : Tal Ater : https://github.com/TalAter\n\nmoment.defineLocale('he', {\n    months : 'ינואר_פברואר_מרץ_אפריל_מאי_יוני_יולי_אוגוסט_ספטמבר_אוקטובר_נובמבר_דצמבר'.split('_'),\n    monthsShort : 'ינו׳_פבר׳_מרץ_אפר׳_מאי_יוני_יולי_אוג׳_ספט׳_אוק׳_נוב׳_דצמ׳'.split('_'),\n    weekdays : 'ראשון_שני_שלישי_רביעי_חמישי_שישי_שבת'.split('_'),\n    weekdaysShort : 'א׳_ב׳_ג׳_ד׳_ה׳_ו׳_ש׳'.split('_'),\n    weekdaysMin : 'א_ב_ג_ד_ה_ו_ש'.split('_'),\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D [ב]MMMM YYYY',\n        LLL : 'D [ב]MMMM YYYY HH:mm',\n        LLLL : 'dddd, D [ב]MMMM YYYY HH:mm',\n        l : 'D/M/YYYY',\n        ll : 'D MMM YYYY',\n        lll : 'D MMM YYYY HH:mm',\n        llll : 'ddd, D MMM YYYY HH:mm'\n    },\n    calendar : {\n        sameDay : '[היום ב־]LT',\n        nextDay : '[מחר ב־]LT',\n        nextWeek : 'dddd [בשעה] LT',\n        lastDay : '[אתמול ב־]LT',\n        lastWeek : '[ביום] dddd [האחרון בשעה] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'בעוד %s',\n        past : 'לפני %s',\n        s : 'מספר שניות',\n        m : 'דקה',\n        mm : '%d דקות',\n        h : 'שעה',\n        hh : function (number) {\n            if (number === 2) {\n                return 'שעתיים';\n            }\n            return number + ' שעות';\n        },\n        d : 'יום',\n        dd : function (number) {\n            if (number === 2) {\n                return 'יומיים';\n            }\n            return number + ' ימים';\n        },\n        M : 'חודש',\n        MM : function (number) {\n            if (number === 2) {\n                return 'חודשיים';\n            }\n            return number + ' חודשים';\n        },\n        y : 'שנה',\n        yy : function (number) {\n            if (number === 2) {\n                return 'שנתיים';\n            } else if (number % 10 === 0 && number !== 10) {\n                return number + ' שנה';\n            }\n            return number + ' שנים';\n        }\n    },\n    meridiemParse: /אחה\"צ|לפנה\"צ|אחרי הצהריים|לפני הצהריים|לפנות בוקר|בבוקר|בערב/i,\n    isPM : function (input) {\n        return /^(אחה\"צ|אחרי הצהריים|בערב)$/.test(input);\n    },\n    meridiem : function (hour, minute, isLower) {\n        if (hour < 5) {\n            return 'לפנות בוקר';\n        } else if (hour < 10) {\n            return 'בבוקר';\n        } else if (hour < 12) {\n            return isLower ? 'לפנה\"צ' : 'לפני הצהריים';\n        } else if (hour < 18) {\n            return isLower ? 'אחה\"צ' : 'אחרי הצהריים';\n        } else {\n            return 'בערב';\n        }\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Hindi [hi]\n//! author : Mayank Singhal : https://github.com/mayanksinghal\n\nvar symbolMap$6 = {\n    '1': '१',\n    '2': '२',\n    '3': '३',\n    '4': '४',\n    '5': '५',\n    '6': '६',\n    '7': '७',\n    '8': '८',\n    '9': '९',\n    '0': '०'\n};\nvar numberMap$5 = {\n    '१': '1',\n    '२': '2',\n    '३': '3',\n    '४': '4',\n    '५': '5',\n    '६': '6',\n    '७': '7',\n    '८': '8',\n    '९': '9',\n    '०': '0'\n};\n\nmoment.defineLocale('hi', {\n    months : 'जनवरी_फ़रवरी_मार्च_अप्रैल_मई_जून_जुलाई_अगस्त_सितम्बर_अक्टूबर_नवम्बर_दिसम्बर'.split('_'),\n    monthsShort : 'जन._फ़र._मार्च_अप्रै._मई_जून_जुल._अग._सित._अक्टू._नव._दिस.'.split('_'),\n    monthsParseExact: true,\n    weekdays : 'रविवार_सोमवार_मंगलवार_बुधवार_गुरूवार_शुक्रवार_शनिवार'.split('_'),\n    weekdaysShort : 'रवि_सोम_मंगल_बुध_गुरू_शुक्र_शनि'.split('_'),\n    weekdaysMin : 'र_सो_मं_बु_गु_शु_श'.split('_'),\n    longDateFormat : {\n        LT : 'A h:mm बजे',\n        LTS : 'A h:mm:ss बजे',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY, A h:mm बजे',\n        LLLL : 'dddd, D MMMM YYYY, A h:mm बजे'\n    },\n    calendar : {\n        sameDay : '[आज] LT',\n        nextDay : '[कल] LT',\n        nextWeek : 'dddd, LT',\n        lastDay : '[कल] LT',\n        lastWeek : '[पिछले] dddd, LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : '%s में',\n        past : '%s पहले',\n        s : 'कुछ ही क्षण',\n        m : 'एक मिनट',\n        mm : '%d मिनट',\n        h : 'एक घंटा',\n        hh : '%d घंटे',\n        d : 'एक दिन',\n        dd : '%d दिन',\n        M : 'एक महीने',\n        MM : '%d महीने',\n        y : 'एक वर्ष',\n        yy : '%d वर्ष'\n    },\n    preparse: function (string) {\n        return string.replace(/[१२३४५६७८९०]/g, function (match) {\n            return numberMap$5[match];\n        });\n    },\n    postformat: function (string) {\n        return string.replace(/\\d/g, function (match) {\n            return symbolMap$6[match];\n        });\n    },\n    // Hindi notation for meridiems are quite fuzzy in practice. While there exists\n    // a rigid notion of a 'Pahar' it is not used as rigidly in modern Hindi.\n    meridiemParse: /रात|सुबह|दोपहर|शाम/,\n    meridiemHour : function (hour, meridiem) {\n        if (hour === 12) {\n            hour = 0;\n        }\n        if (meridiem === 'रात') {\n            return hour < 4 ? hour : hour + 12;\n        } else if (meridiem === 'सुबह') {\n            return hour;\n        } else if (meridiem === 'दोपहर') {\n            return hour >= 10 ? hour : hour + 12;\n        } else if (meridiem === 'शाम') {\n            return hour + 12;\n        }\n    },\n    meridiem : function (hour, minute, isLower) {\n        if (hour < 4) {\n            return 'रात';\n        } else if (hour < 10) {\n            return 'सुबह';\n        } else if (hour < 17) {\n            return 'दोपहर';\n        } else if (hour < 20) {\n            return 'शाम';\n        } else {\n            return 'रात';\n        }\n    },\n    week : {\n        dow : 0, // Sunday is the first day of the week.\n        doy : 6  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Croatian [hr]\n//! author : Bojan Marković : https://github.com/bmarkovic\n\nfunction translate$3(number, withoutSuffix, key) {\n    var result = number + ' ';\n    switch (key) {\n        case 'm':\n            return withoutSuffix ? 'jedna minuta' : 'jedne minute';\n        case 'mm':\n            if (number === 1) {\n                result += 'minuta';\n            } else if (number === 2 || number === 3 || number === 4) {\n                result += 'minute';\n            } else {\n                result += 'minuta';\n            }\n            return result;\n        case 'h':\n            return withoutSuffix ? 'jedan sat' : 'jednog sata';\n        case 'hh':\n            if (number === 1) {\n                result += 'sat';\n            } else if (number === 2 || number === 3 || number === 4) {\n                result += 'sata';\n            } else {\n                result += 'sati';\n            }\n            return result;\n        case 'dd':\n            if (number === 1) {\n                result += 'dan';\n            } else {\n                result += 'dana';\n            }\n            return result;\n        case 'MM':\n            if (number === 1) {\n                result += 'mjesec';\n            } else if (number === 2 || number === 3 || number === 4) {\n                result += 'mjeseca';\n            } else {\n                result += 'mjeseci';\n            }\n            return result;\n        case 'yy':\n            if (number === 1) {\n                result += 'godina';\n            } else if (number === 2 || number === 3 || number === 4) {\n                result += 'godine';\n            } else {\n                result += 'godina';\n            }\n            return result;\n    }\n}\n\nmoment.defineLocale('hr', {\n    months : {\n        format: 'siječnja_veljače_ožujka_travnja_svibnja_lipnja_srpnja_kolovoza_rujna_listopada_studenoga_prosinca'.split('_'),\n        standalone: 'siječanj_veljača_ožujak_travanj_svibanj_lipanj_srpanj_kolovoz_rujan_listopad_studeni_prosinac'.split('_')\n    },\n    monthsShort : 'sij._velj._ožu._tra._svi._lip._srp._kol._ruj._lis._stu._pro.'.split('_'),\n    monthsParseExact: true,\n    weekdays : 'nedjelja_ponedjeljak_utorak_srijeda_četvrtak_petak_subota'.split('_'),\n    weekdaysShort : 'ned._pon._uto._sri._čet._pet._sub.'.split('_'),\n    weekdaysMin : 'ne_po_ut_sr_če_pe_su'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat : {\n        LT : 'H:mm',\n        LTS : 'H:mm:ss',\n        L : 'DD.MM.YYYY',\n        LL : 'D. MMMM YYYY',\n        LLL : 'D. MMMM YYYY H:mm',\n        LLLL : 'dddd, D. MMMM YYYY H:mm'\n    },\n    calendar : {\n        sameDay  : '[danas u] LT',\n        nextDay  : '[sutra u] LT',\n        nextWeek : function () {\n            switch (this.day()) {\n                case 0:\n                    return '[u] [nedjelju] [u] LT';\n                case 3:\n                    return '[u] [srijedu] [u] LT';\n                case 6:\n                    return '[u] [subotu] [u] LT';\n                case 1:\n                case 2:\n                case 4:\n                case 5:\n                    return '[u] dddd [u] LT';\n            }\n        },\n        lastDay  : '[jučer u] LT',\n        lastWeek : function () {\n            switch (this.day()) {\n                case 0:\n                case 3:\n                    return '[prošlu] dddd [u] LT';\n                case 6:\n                    return '[prošle] [subote] [u] LT';\n                case 1:\n                case 2:\n                case 4:\n                case 5:\n                    return '[prošli] dddd [u] LT';\n            }\n        },\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'za %s',\n        past   : 'prije %s',\n        s      : 'par sekundi',\n        m      : translate$3,\n        mm     : translate$3,\n        h      : translate$3,\n        hh     : translate$3,\n        d      : 'dan',\n        dd     : translate$3,\n        M      : 'mjesec',\n        MM     : translate$3,\n        y      : 'godinu',\n        yy     : translate$3\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}\\./,\n    ordinal : '%d.',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 7  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Hungarian [hu]\n//! author : Adam Brunner : https://github.com/adambrunner\n\nvar weekEndings = 'vasárnap hétfőn kedden szerdán csütörtökön pénteken szombaton'.split(' ');\nfunction translate$4(number, withoutSuffix, key, isFuture) {\n    var num = number,\n        suffix;\n    switch (key) {\n        case 's':\n            return (isFuture || withoutSuffix) ? 'néhány másodperc' : 'néhány másodperce';\n        case 'm':\n            return 'egy' + (isFuture || withoutSuffix ? ' perc' : ' perce');\n        case 'mm':\n            return num + (isFuture || withoutSuffix ? ' perc' : ' perce');\n        case 'h':\n            return 'egy' + (isFuture || withoutSuffix ? ' óra' : ' órája');\n        case 'hh':\n            return num + (isFuture || withoutSuffix ? ' óra' : ' órája');\n        case 'd':\n            return 'egy' + (isFuture || withoutSuffix ? ' nap' : ' napja');\n        case 'dd':\n            return num + (isFuture || withoutSuffix ? ' nap' : ' napja');\n        case 'M':\n            return 'egy' + (isFuture || withoutSuffix ? ' hónap' : ' hónapja');\n        case 'MM':\n            return num + (isFuture || withoutSuffix ? ' hónap' : ' hónapja');\n        case 'y':\n            return 'egy' + (isFuture || withoutSuffix ? ' év' : ' éve');\n        case 'yy':\n            return num + (isFuture || withoutSuffix ? ' év' : ' éve');\n    }\n    return '';\n}\nfunction week(isFuture) {\n    return (isFuture ? '' : '[múlt] ') + '[' + weekEndings[this.day()] + '] LT[-kor]';\n}\n\nmoment.defineLocale('hu', {\n    months : 'január_február_március_április_május_június_július_augusztus_szeptember_október_november_december'.split('_'),\n    monthsShort : 'jan_feb_márc_ápr_máj_jún_júl_aug_szept_okt_nov_dec'.split('_'),\n    weekdays : 'vasárnap_hétfő_kedd_szerda_csütörtök_péntek_szombat'.split('_'),\n    weekdaysShort : 'vas_hét_kedd_sze_csüt_pén_szo'.split('_'),\n    weekdaysMin : 'v_h_k_sze_cs_p_szo'.split('_'),\n    longDateFormat : {\n        LT : 'H:mm',\n        LTS : 'H:mm:ss',\n        L : 'YYYY.MM.DD.',\n        LL : 'YYYY. MMMM D.',\n        LLL : 'YYYY. MMMM D. H:mm',\n        LLLL : 'YYYY. MMMM D., dddd H:mm'\n    },\n    meridiemParse: /de|du/i,\n    isPM: function (input) {\n        return input.charAt(1).toLowerCase() === 'u';\n    },\n    meridiem : function (hours, minutes, isLower) {\n        if (hours < 12) {\n            return isLower === true ? 'de' : 'DE';\n        } else {\n            return isLower === true ? 'du' : 'DU';\n        }\n    },\n    calendar : {\n        sameDay : '[ma] LT[-kor]',\n        nextDay : '[holnap] LT[-kor]',\n        nextWeek : function () {\n            return week.call(this, true);\n        },\n        lastDay : '[tegnap] LT[-kor]',\n        lastWeek : function () {\n            return week.call(this, false);\n        },\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : '%s múlva',\n        past : '%s',\n        s : translate$4,\n        m : translate$4,\n        mm : translate$4,\n        h : translate$4,\n        hh : translate$4,\n        d : translate$4,\n        dd : translate$4,\n        M : translate$4,\n        MM : translate$4,\n        y : translate$4,\n        yy : translate$4\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}\\./,\n    ordinal : '%d.',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Armenian [hy-am]\n//! author : Armendarabyan : https://github.com/armendarabyan\n\nmoment.defineLocale('hy-am', {\n    months : {\n        format: 'հունվարի_փետրվարի_մարտի_ապրիլի_մայիսի_հունիսի_հուլիսի_օգոստոսի_սեպտեմբերի_հոկտեմբերի_նոյեմբերի_դեկտեմբերի'.split('_'),\n        standalone: 'հունվար_փետրվար_մարտ_ապրիլ_մայիս_հունիս_հուլիս_օգոստոս_սեպտեմբեր_հոկտեմբեր_նոյեմբեր_դեկտեմբեր'.split('_')\n    },\n    monthsShort : 'հնվ_փտր_մրտ_ապր_մյս_հնս_հլս_օգս_սպտ_հկտ_նմբ_դկտ'.split('_'),\n    weekdays : 'կիրակի_երկուշաբթի_երեքշաբթի_չորեքշաբթի_հինգշաբթի_ուրբաթ_շաբաթ'.split('_'),\n    weekdaysShort : 'կրկ_երկ_երք_չրք_հնգ_ուրբ_շբթ'.split('_'),\n    weekdaysMin : 'կրկ_երկ_երք_չրք_հնգ_ուրբ_շբթ'.split('_'),\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD.MM.YYYY',\n        LL : 'D MMMM YYYY թ.',\n        LLL : 'D MMMM YYYY թ., HH:mm',\n        LLLL : 'dddd, D MMMM YYYY թ., HH:mm'\n    },\n    calendar : {\n        sameDay: '[այսօր] LT',\n        nextDay: '[վաղը] LT',\n        lastDay: '[երեկ] LT',\n        nextWeek: function () {\n            return 'dddd [օրը ժամը] LT';\n        },\n        lastWeek: function () {\n            return '[անցած] dddd [օրը ժամը] LT';\n        },\n        sameElse: 'L'\n    },\n    relativeTime : {\n        future : '%s հետո',\n        past : '%s առաջ',\n        s : 'մի քանի վայրկյան',\n        m : 'րոպե',\n        mm : '%d րոպե',\n        h : 'ժամ',\n        hh : '%d ժամ',\n        d : 'օր',\n        dd : '%d օր',\n        M : 'ամիս',\n        MM : '%d ամիս',\n        y : 'տարի',\n        yy : '%d տարի'\n    },\n    meridiemParse: /գիշերվա|առավոտվա|ցերեկվա|երեկոյան/,\n    isPM: function (input) {\n        return /^(ցերեկվա|երեկոյան)$/.test(input);\n    },\n    meridiem : function (hour) {\n        if (hour < 4) {\n            return 'գիշերվա';\n        } else if (hour < 12) {\n            return 'առավոտվա';\n        } else if (hour < 17) {\n            return 'ցերեկվա';\n        } else {\n            return 'երեկոյան';\n        }\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}|\\d{1,2}-(ին|րդ)/,\n    ordinal: function (number, period) {\n        switch (period) {\n            case 'DDD':\n            case 'w':\n            case 'W':\n            case 'DDDo':\n                if (number === 1) {\n                    return number + '-ին';\n                }\n                return number + '-րդ';\n            default:\n                return number;\n        }\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 7  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Indonesian [id]\n//! author : Mohammad Satrio Utomo : https://github.com/tyok\n//! reference: http://id.wikisource.org/wiki/Pedoman_Umum_Ejaan_Bahasa_Indonesia_yang_Disempurnakan\n\nmoment.defineLocale('id', {\n    months : 'Januari_Februari_Maret_April_Mei_Juni_Juli_Agustus_September_Oktober_November_Desember'.split('_'),\n    monthsShort : 'Jan_Feb_Mar_Apr_Mei_Jun_Jul_Ags_Sep_Okt_Nov_Des'.split('_'),\n    weekdays : 'Minggu_Senin_Selasa_Rabu_Kamis_Jumat_Sabtu'.split('_'),\n    weekdaysShort : 'Min_Sen_Sel_Rab_Kam_Jum_Sab'.split('_'),\n    weekdaysMin : 'Mg_Sn_Sl_Rb_Km_Jm_Sb'.split('_'),\n    longDateFormat : {\n        LT : 'HH.mm',\n        LTS : 'HH.mm.ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY [pukul] HH.mm',\n        LLLL : 'dddd, D MMMM YYYY [pukul] HH.mm'\n    },\n    meridiemParse: /pagi|siang|sore|malam/,\n    meridiemHour : function (hour, meridiem) {\n        if (hour === 12) {\n            hour = 0;\n        }\n        if (meridiem === 'pagi') {\n            return hour;\n        } else if (meridiem === 'siang') {\n            return hour >= 11 ? hour : hour + 12;\n        } else if (meridiem === 'sore' || meridiem === 'malam') {\n            return hour + 12;\n        }\n    },\n    meridiem : function (hours, minutes, isLower) {\n        if (hours < 11) {\n            return 'pagi';\n        } else if (hours < 15) {\n            return 'siang';\n        } else if (hours < 19) {\n            return 'sore';\n        } else {\n            return 'malam';\n        }\n    },\n    calendar : {\n        sameDay : '[Hari ini pukul] LT',\n        nextDay : '[Besok pukul] LT',\n        nextWeek : 'dddd [pukul] LT',\n        lastDay : '[Kemarin pukul] LT',\n        lastWeek : 'dddd [lalu pukul] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'dalam %s',\n        past : '%s yang lalu',\n        s : 'beberapa detik',\n        m : 'semenit',\n        mm : '%d menit',\n        h : 'sejam',\n        hh : '%d jam',\n        d : 'sehari',\n        dd : '%d hari',\n        M : 'sebulan',\n        MM : '%d bulan',\n        y : 'setahun',\n        yy : '%d tahun'\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 7  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Icelandic [is]\n//! author : Hinrik Örn Sigurðsson : https://github.com/hinrik\n\nfunction plural$2(n) {\n    if (n % 100 === 11) {\n        return true;\n    } else if (n % 10 === 1) {\n        return false;\n    }\n    return true;\n}\nfunction translate$5(number, withoutSuffix, key, isFuture) {\n    var result = number + ' ';\n    switch (key) {\n        case 's':\n            return withoutSuffix || isFuture ? 'nokkrar sekúndur' : 'nokkrum sekúndum';\n        case 'm':\n            return withoutSuffix ? 'mínúta' : 'mínútu';\n        case 'mm':\n            if (plural$2(number)) {\n                return result + (withoutSuffix || isFuture ? 'mínútur' : 'mínútum');\n            } else if (withoutSuffix) {\n                return result + 'mínúta';\n            }\n            return result + 'mínútu';\n        case 'hh':\n            if (plural$2(number)) {\n                return result + (withoutSuffix || isFuture ? 'klukkustundir' : 'klukkustundum');\n            }\n            return result + 'klukkustund';\n        case 'd':\n            if (withoutSuffix) {\n                return 'dagur';\n            }\n            return isFuture ? 'dag' : 'degi';\n        case 'dd':\n            if (plural$2(number)) {\n                if (withoutSuffix) {\n                    return result + 'dagar';\n                }\n                return result + (isFuture ? 'daga' : 'dögum');\n            } else if (withoutSuffix) {\n                return result + 'dagur';\n            }\n            return result + (isFuture ? 'dag' : 'degi');\n        case 'M':\n            if (withoutSuffix) {\n                return 'mánuður';\n            }\n            return isFuture ? 'mánuð' : 'mánuði';\n        case 'MM':\n            if (plural$2(number)) {\n                if (withoutSuffix) {\n                    return result + 'mánuðir';\n                }\n                return result + (isFuture ? 'mánuði' : 'mánuðum');\n            } else if (withoutSuffix) {\n                return result + 'mánuður';\n            }\n            return result + (isFuture ? 'mánuð' : 'mánuði');\n        case 'y':\n            return withoutSuffix || isFuture ? 'ár' : 'ári';\n        case 'yy':\n            if (plural$2(number)) {\n                return result + (withoutSuffix || isFuture ? 'ár' : 'árum');\n            }\n            return result + (withoutSuffix || isFuture ? 'ár' : 'ári');\n    }\n}\n\nmoment.defineLocale('is', {\n    months : 'janúar_febrúar_mars_apríl_maí_júní_júlí_ágúst_september_október_nóvember_desember'.split('_'),\n    monthsShort : 'jan_feb_mar_apr_maí_jún_júl_ágú_sep_okt_nóv_des'.split('_'),\n    weekdays : 'sunnudagur_mánudagur_þriðjudagur_miðvikudagur_fimmtudagur_föstudagur_laugardagur'.split('_'),\n    weekdaysShort : 'sun_mán_þri_mið_fim_fös_lau'.split('_'),\n    weekdaysMin : 'Su_Má_Þr_Mi_Fi_Fö_La'.split('_'),\n    longDateFormat : {\n        LT : 'H:mm',\n        LTS : 'H:mm:ss',\n        L : 'DD.MM.YYYY',\n        LL : 'D. MMMM YYYY',\n        LLL : 'D. MMMM YYYY [kl.] H:mm',\n        LLLL : 'dddd, D. MMMM YYYY [kl.] H:mm'\n    },\n    calendar : {\n        sameDay : '[í dag kl.] LT',\n        nextDay : '[á morgun kl.] LT',\n        nextWeek : 'dddd [kl.] LT',\n        lastDay : '[í gær kl.] LT',\n        lastWeek : '[síðasta] dddd [kl.] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'eftir %s',\n        past : 'fyrir %s síðan',\n        s : translate$5,\n        m : translate$5,\n        mm : translate$5,\n        h : 'klukkustund',\n        hh : translate$5,\n        d : translate$5,\n        dd : translate$5,\n        M : translate$5,\n        MM : translate$5,\n        y : translate$5,\n        yy : translate$5\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}\\./,\n    ordinal : '%d.',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Italian [it]\n//! author : Lorenzo : https://github.com/aliem\n//! author: Mattia Larentis: https://github.com/nostalgiaz\n\nmoment.defineLocale('it', {\n    months : 'gennaio_febbraio_marzo_aprile_maggio_giugno_luglio_agosto_settembre_ottobre_novembre_dicembre'.split('_'),\n    monthsShort : 'gen_feb_mar_apr_mag_giu_lug_ago_set_ott_nov_dic'.split('_'),\n    weekdays : 'domenica_lunedì_martedì_mercoledì_giovedì_venerdì_sabato'.split('_'),\n    weekdaysShort : 'dom_lun_mar_mer_gio_ven_sab'.split('_'),\n    weekdaysMin : 'do_lu_ma_me_gi_ve_sa'.split('_'),\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY HH:mm',\n        LLLL : 'dddd, D MMMM YYYY HH:mm'\n    },\n    calendar : {\n        sameDay: '[Oggi alle] LT',\n        nextDay: '[Domani alle] LT',\n        nextWeek: 'dddd [alle] LT',\n        lastDay: '[Ieri alle] LT',\n        lastWeek: function () {\n            switch (this.day()) {\n                case 0:\n                    return '[la scorsa] dddd [alle] LT';\n                default:\n                    return '[lo scorso] dddd [alle] LT';\n            }\n        },\n        sameElse: 'L'\n    },\n    relativeTime : {\n        future : function (s) {\n            return ((/^[0-9].+$/).test(s) ? 'tra' : 'in') + ' ' + s;\n        },\n        past : '%s fa',\n        s : 'alcuni secondi',\n        m : 'un minuto',\n        mm : '%d minuti',\n        h : 'un\\'ora',\n        hh : '%d ore',\n        d : 'un giorno',\n        dd : '%d giorni',\n        M : 'un mese',\n        MM : '%d mesi',\n        y : 'un anno',\n        yy : '%d anni'\n    },\n    dayOfMonthOrdinalParse : /\\d{1,2}º/,\n    ordinal: '%dº',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Japanese [ja]\n//! author : LI Long : https://github.com/baryon\n\nmoment.defineLocale('ja', {\n    months : '1月_2月_3月_4月_5月_6月_7月_8月_9月_10月_11月_12月'.split('_'),\n    monthsShort : '1月_2月_3月_4月_5月_6月_7月_8月_9月_10月_11月_12月'.split('_'),\n    weekdays : '日曜日_月曜日_火曜日_水曜日_木曜日_金曜日_土曜日'.split('_'),\n    weekdaysShort : '日_月_火_水_木_金_土'.split('_'),\n    weekdaysMin : '日_月_火_水_木_金_土'.split('_'),\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'YYYY/MM/DD',\n        LL : 'YYYY年M月D日',\n        LLL : 'YYYY年M月D日 HH:mm',\n        LLLL : 'YYYY年M月D日 HH:mm dddd',\n        l : 'YYYY/MM/DD',\n        ll : 'YYYY年M月D日',\n        lll : 'YYYY年M月D日 HH:mm',\n        llll : 'YYYY年M月D日 HH:mm dddd'\n    },\n    meridiemParse: /午前|午後/i,\n    isPM : function (input) {\n        return input === '午後';\n    },\n    meridiem : function (hour, minute, isLower) {\n        if (hour < 12) {\n            return '午前';\n        } else {\n            return '午後';\n        }\n    },\n    calendar : {\n        sameDay : '[今日] LT',\n        nextDay : '[明日] LT',\n        nextWeek : '[来週]dddd LT',\n        lastDay : '[昨日] LT',\n        lastWeek : '[前週]dddd LT',\n        sameElse : 'L'\n    },\n    dayOfMonthOrdinalParse : /\\d{1,2}日/,\n    ordinal : function (number, period) {\n        switch (period) {\n            case 'd':\n            case 'D':\n            case 'DDD':\n                return number + '日';\n            default:\n                return number;\n        }\n    },\n    relativeTime : {\n        future : '%s後',\n        past : '%s前',\n        s : '数秒',\n        m : '1分',\n        mm : '%d分',\n        h : '1時間',\n        hh : '%d時間',\n        d : '1日',\n        dd : '%d日',\n        M : '1ヶ月',\n        MM : '%dヶ月',\n        y : '1年',\n        yy : '%d年'\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Javanese [jv]\n//! author : Rony Lantip : https://github.com/lantip\n//! reference: http://jv.wikipedia.org/wiki/Basa_Jawa\n\nmoment.defineLocale('jv', {\n    months : 'Januari_Februari_Maret_April_Mei_Juni_Juli_Agustus_September_Oktober_Nopember_Desember'.split('_'),\n    monthsShort : 'Jan_Feb_Mar_Apr_Mei_Jun_Jul_Ags_Sep_Okt_Nop_Des'.split('_'),\n    weekdays : 'Minggu_Senen_Seloso_Rebu_Kemis_Jemuwah_Septu'.split('_'),\n    weekdaysShort : 'Min_Sen_Sel_Reb_Kem_Jem_Sep'.split('_'),\n    weekdaysMin : 'Mg_Sn_Sl_Rb_Km_Jm_Sp'.split('_'),\n    longDateFormat : {\n        LT : 'HH.mm',\n        LTS : 'HH.mm.ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY [pukul] HH.mm',\n        LLLL : 'dddd, D MMMM YYYY [pukul] HH.mm'\n    },\n    meridiemParse: /enjing|siyang|sonten|ndalu/,\n    meridiemHour : function (hour, meridiem) {\n        if (hour === 12) {\n            hour = 0;\n        }\n        if (meridiem === 'enjing') {\n            return hour;\n        } else if (meridiem === 'siyang') {\n            return hour >= 11 ? hour : hour + 12;\n        } else if (meridiem === 'sonten' || meridiem === 'ndalu') {\n            return hour + 12;\n        }\n    },\n    meridiem : function (hours, minutes, isLower) {\n        if (hours < 11) {\n            return 'enjing';\n        } else if (hours < 15) {\n            return 'siyang';\n        } else if (hours < 19) {\n            return 'sonten';\n        } else {\n            return 'ndalu';\n        }\n    },\n    calendar : {\n        sameDay : '[Dinten puniko pukul] LT',\n        nextDay : '[Mbenjang pukul] LT',\n        nextWeek : 'dddd [pukul] LT',\n        lastDay : '[Kala wingi pukul] LT',\n        lastWeek : 'dddd [kepengker pukul] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'wonten ing %s',\n        past : '%s ingkang kepengker',\n        s : 'sawetawis detik',\n        m : 'setunggal menit',\n        mm : '%d menit',\n        h : 'setunggal jam',\n        hh : '%d jam',\n        d : 'sedinten',\n        dd : '%d dinten',\n        M : 'sewulan',\n        MM : '%d wulan',\n        y : 'setaun',\n        yy : '%d taun'\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 7  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Georgian [ka]\n//! author : Irakli Janiashvili : https://github.com/irakli-janiashvili\n\nmoment.defineLocale('ka', {\n    months : {\n        standalone: 'იანვარი_თებერვალი_მარტი_აპრილი_მაისი_ივნისი_ივლისი_აგვისტო_სექტემბერი_ოქტომბერი_ნოემბერი_დეკემბერი'.split('_'),\n        format: 'იანვარს_თებერვალს_მარტს_აპრილის_მაისს_ივნისს_ივლისს_აგვისტს_სექტემბერს_ოქტომბერს_ნოემბერს_დეკემბერს'.split('_')\n    },\n    monthsShort : 'იან_თებ_მარ_აპრ_მაი_ივნ_ივლ_აგვ_სექ_ოქტ_ნოე_დეკ'.split('_'),\n    weekdays : {\n        standalone: 'კვირა_ორშაბათი_სამშაბათი_ოთხშაბათი_ხუთშაბათი_პარასკევი_შაბათი'.split('_'),\n        format: 'კვირას_ორშაბათს_სამშაბათს_ოთხშაბათს_ხუთშაბათს_პარასკევს_შაბათს'.split('_'),\n        isFormat: /(წინა|შემდეგ)/\n    },\n    weekdaysShort : 'კვი_ორშ_სამ_ოთხ_ხუთ_პარ_შაბ'.split('_'),\n    weekdaysMin : 'კვ_ორ_სა_ოთ_ხუ_პა_შა'.split('_'),\n    longDateFormat : {\n        LT : 'h:mm A',\n        LTS : 'h:mm:ss A',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY h:mm A',\n        LLLL : 'dddd, D MMMM YYYY h:mm A'\n    },\n    calendar : {\n        sameDay : '[დღეს] LT[-ზე]',\n        nextDay : '[ხვალ] LT[-ზე]',\n        lastDay : '[გუშინ] LT[-ზე]',\n        nextWeek : '[შემდეგ] dddd LT[-ზე]',\n        lastWeek : '[წინა] dddd LT-ზე',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : function (s) {\n            return (/(წამი|წუთი|საათი|წელი)/).test(s) ?\n                s.replace(/ი$/, 'ში') :\n                s + 'ში';\n        },\n        past : function (s) {\n            if ((/(წამი|წუთი|საათი|დღე|თვე)/).test(s)) {\n                return s.replace(/(ი|ე)$/, 'ის უკან');\n            }\n            if ((/წელი/).test(s)) {\n                return s.replace(/წელი$/, 'წლის უკან');\n            }\n        },\n        s : 'რამდენიმე წამი',\n        m : 'წუთი',\n        mm : '%d წუთი',\n        h : 'საათი',\n        hh : '%d საათი',\n        d : 'დღე',\n        dd : '%d დღე',\n        M : 'თვე',\n        MM : '%d თვე',\n        y : 'წელი',\n        yy : '%d წელი'\n    },\n    dayOfMonthOrdinalParse: /0|1-ლი|მე-\\d{1,2}|\\d{1,2}-ე/,\n    ordinal : function (number) {\n        if (number === 0) {\n            return number;\n        }\n        if (number === 1) {\n            return number + '-ლი';\n        }\n        if ((number < 20) || (number <= 100 && (number % 20 === 0)) || (number % 100 === 0)) {\n            return 'მე-' + number;\n        }\n        return number + '-ე';\n    },\n    week : {\n        dow : 1,\n        doy : 7\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Kazakh [kk]\n//! authors : Nurlan Rakhimzhanov : https://github.com/nurlan\n\nvar suffixes$1 = {\n    0: '-ші',\n    1: '-ші',\n    2: '-ші',\n    3: '-ші',\n    4: '-ші',\n    5: '-ші',\n    6: '-шы',\n    7: '-ші',\n    8: '-ші',\n    9: '-шы',\n    10: '-шы',\n    20: '-шы',\n    30: '-шы',\n    40: '-шы',\n    50: '-ші',\n    60: '-шы',\n    70: '-ші',\n    80: '-ші',\n    90: '-шы',\n    100: '-ші'\n};\n\nmoment.defineLocale('kk', {\n    months : 'қаңтар_ақпан_наурыз_сәуір_мамыр_маусым_шілде_тамыз_қыркүйек_қазан_қараша_желтоқсан'.split('_'),\n    monthsShort : 'қаң_ақп_нау_сәу_мам_мау_шіл_там_қыр_қаз_қар_жел'.split('_'),\n    weekdays : 'жексенбі_дүйсенбі_сейсенбі_сәрсенбі_бейсенбі_жұма_сенбі'.split('_'),\n    weekdaysShort : 'жек_дүй_сей_сәр_бей_жұм_сен'.split('_'),\n    weekdaysMin : 'жк_дй_сй_ср_бй_жм_сн'.split('_'),\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD.MM.YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY HH:mm',\n        LLLL : 'dddd, D MMMM YYYY HH:mm'\n    },\n    calendar : {\n        sameDay : '[Бүгін сағат] LT',\n        nextDay : '[Ертең сағат] LT',\n        nextWeek : 'dddd [сағат] LT',\n        lastDay : '[Кеше сағат] LT',\n        lastWeek : '[Өткен аптаның] dddd [сағат] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : '%s ішінде',\n        past : '%s бұрын',\n        s : 'бірнеше секунд',\n        m : 'бір минут',\n        mm : '%d минут',\n        h : 'бір сағат',\n        hh : '%d сағат',\n        d : 'бір күн',\n        dd : '%d күн',\n        M : 'бір ай',\n        MM : '%d ай',\n        y : 'бір жыл',\n        yy : '%d жыл'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}-(ші|шы)/,\n    ordinal : function (number) {\n        var a = number % 10,\n            b = number >= 100 ? 100 : null;\n        return number + (suffixes$1[number] || suffixes$1[a] || suffixes$1[b]);\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 7  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Cambodian [km]\n//! author : Kruy Vanna : https://github.com/kruyvanna\n\nmoment.defineLocale('km', {\n    months: 'មករា_កុម្ភៈ_មីនា_មេសា_ឧសភា_មិថុនា_កក្កដា_សីហា_កញ្ញា_តុលា_វិច្ឆិកា_ធ្នូ'.split('_'),\n    monthsShort: 'មករា_កុម្ភៈ_មីនា_មេសា_ឧសភា_មិថុនា_កក្កដា_សីហា_កញ្ញា_តុលា_វិច្ឆិកា_ធ្នូ'.split('_'),\n    weekdays: 'អាទិត្យ_ច័ន្ទ_អង្គារ_ពុធ_ព្រហស្បតិ៍_សុក្រ_សៅរ៍'.split('_'),\n    weekdaysShort: 'អាទិត្យ_ច័ន្ទ_អង្គារ_ពុធ_ព្រហស្បតិ៍_សុក្រ_សៅរ៍'.split('_'),\n    weekdaysMin: 'អាទិត្យ_ច័ន្ទ_អង្គារ_ពុធ_ព្រហស្បតិ៍_សុក្រ_សៅរ៍'.split('_'),\n    longDateFormat: {\n        LT: 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L: 'DD/MM/YYYY',\n        LL: 'D MMMM YYYY',\n        LLL: 'D MMMM YYYY HH:mm',\n        LLLL: 'dddd, D MMMM YYYY HH:mm'\n    },\n    calendar: {\n        sameDay: '[ថ្ងៃនេះ ម៉ោង] LT',\n        nextDay: '[ស្អែក ម៉ោង] LT',\n        nextWeek: 'dddd [ម៉ោង] LT',\n        lastDay: '[ម្សិលមិញ ម៉ោង] LT',\n        lastWeek: 'dddd [សប្តាហ៍មុន] [ម៉ោង] LT',\n        sameElse: 'L'\n    },\n    relativeTime: {\n        future: '%sទៀត',\n        past: '%sមុន',\n        s: 'ប៉ុន្មានវិនាទី',\n        m: 'មួយនាទី',\n        mm: '%d នាទី',\n        h: 'មួយម៉ោង',\n        hh: '%d ម៉ោង',\n        d: 'មួយថ្ងៃ',\n        dd: '%d ថ្ងៃ',\n        M: 'មួយខែ',\n        MM: '%d ខែ',\n        y: 'មួយឆ្នាំ',\n        yy: '%d ឆ្នាំ'\n    },\n    week: {\n        dow: 1, // Monday is the first day of the week.\n        doy: 4 // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Kannada [kn]\n//! author : Rajeev Naik : https://github.com/rajeevnaikte\n\nvar symbolMap$7 = {\n    '1': '೧',\n    '2': '೨',\n    '3': '೩',\n    '4': '೪',\n    '5': '೫',\n    '6': '೬',\n    '7': '೭',\n    '8': '೮',\n    '9': '೯',\n    '0': '೦'\n};\nvar numberMap$6 = {\n    '೧': '1',\n    '೨': '2',\n    '೩': '3',\n    '೪': '4',\n    '೫': '5',\n    '೬': '6',\n    '೭': '7',\n    '೮': '8',\n    '೯': '9',\n    '೦': '0'\n};\n\nmoment.defineLocale('kn', {\n    months : 'ಜನವರಿ_ಫೆಬ್ರವರಿ_ಮಾರ್ಚ್_ಏಪ್ರಿಲ್_ಮೇ_ಜೂನ್_ಜುಲೈ_ಆಗಸ್ಟ್_ಸೆಪ್ಟೆಂಬರ್_ಅಕ್ಟೋಬರ್_ನವೆಂಬರ್_ಡಿಸೆಂಬರ್'.split('_'),\n    monthsShort : 'ಜನ_ಫೆಬ್ರ_ಮಾರ್ಚ್_ಏಪ್ರಿಲ್_ಮೇ_ಜೂನ್_ಜುಲೈ_ಆಗಸ್ಟ್_ಸೆಪ್ಟೆಂಬ_ಅಕ್ಟೋಬ_ನವೆಂಬ_ಡಿಸೆಂಬ'.split('_'),\n    monthsParseExact: true,\n    weekdays : 'ಭಾನುವಾರ_ಸೋಮವಾರ_ಮಂಗಳವಾರ_ಬುಧವಾರ_ಗುರುವಾರ_ಶುಕ್ರವಾರ_ಶನಿವಾರ'.split('_'),\n    weekdaysShort : 'ಭಾನು_ಸೋಮ_ಮಂಗಳ_ಬುಧ_ಗುರು_ಶುಕ್ರ_ಶನಿ'.split('_'),\n    weekdaysMin : 'ಭಾ_ಸೋ_ಮಂ_ಬು_ಗು_ಶು_ಶ'.split('_'),\n    longDateFormat : {\n        LT : 'A h:mm',\n        LTS : 'A h:mm:ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY, A h:mm',\n        LLLL : 'dddd, D MMMM YYYY, A h:mm'\n    },\n    calendar : {\n        sameDay : '[ಇಂದು] LT',\n        nextDay : '[ನಾಳೆ] LT',\n        nextWeek : 'dddd, LT',\n        lastDay : '[ನಿನ್ನೆ] LT',\n        lastWeek : '[ಕೊನೆಯ] dddd, LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : '%s ನಂತರ',\n        past : '%s ಹಿಂದೆ',\n        s : 'ಕೆಲವು ಕ್ಷಣಗಳು',\n        m : 'ಒಂದು ನಿಮಿಷ',\n        mm : '%d ನಿಮಿಷ',\n        h : 'ಒಂದು ಗಂಟೆ',\n        hh : '%d ಗಂಟೆ',\n        d : 'ಒಂದು ದಿನ',\n        dd : '%d ದಿನ',\n        M : 'ಒಂದು ತಿಂಗಳು',\n        MM : '%d ತಿಂಗಳು',\n        y : 'ಒಂದು ವರ್ಷ',\n        yy : '%d ವರ್ಷ'\n    },\n    preparse: function (string) {\n        return string.replace(/[೧೨೩೪೫೬೭೮೯೦]/g, function (match) {\n            return numberMap$6[match];\n        });\n    },\n    postformat: function (string) {\n        return string.replace(/\\d/g, function (match) {\n            return symbolMap$7[match];\n        });\n    },\n    meridiemParse: /ರಾತ್ರಿ|ಬೆಳಿಗ್ಗೆ|ಮಧ್ಯಾಹ್ನ|ಸಂಜೆ/,\n    meridiemHour : function (hour, meridiem) {\n        if (hour === 12) {\n            hour = 0;\n        }\n        if (meridiem === 'ರಾತ್ರಿ') {\n            return hour < 4 ? hour : hour + 12;\n        } else if (meridiem === 'ಬೆಳಿಗ್ಗೆ') {\n            return hour;\n        } else if (meridiem === 'ಮಧ್ಯಾಹ್ನ') {\n            return hour >= 10 ? hour : hour + 12;\n        } else if (meridiem === 'ಸಂಜೆ') {\n            return hour + 12;\n        }\n    },\n    meridiem : function (hour, minute, isLower) {\n        if (hour < 4) {\n            return 'ರಾತ್ರಿ';\n        } else if (hour < 10) {\n            return 'ಬೆಳಿಗ್ಗೆ';\n        } else if (hour < 17) {\n            return 'ಮಧ್ಯಾಹ್ನ';\n        } else if (hour < 20) {\n            return 'ಸಂಜೆ';\n        } else {\n            return 'ರಾತ್ರಿ';\n        }\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}(ನೇ)/,\n    ordinal : function (number) {\n        return number + 'ನೇ';\n    },\n    week : {\n        dow : 0, // Sunday is the first day of the week.\n        doy : 6  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Korean [ko]\n//! author : Kyungwook, Park : https://github.com/kyungw00k\n//! author : Jeeeyul Lee <jeeeyul@gmail.com>\n\nmoment.defineLocale('ko', {\n    months : '1월_2월_3월_4월_5월_6월_7월_8월_9월_10월_11월_12월'.split('_'),\n    monthsShort : '1월_2월_3월_4월_5월_6월_7월_8월_9월_10월_11월_12월'.split('_'),\n    weekdays : '일요일_월요일_화요일_수요일_목요일_금요일_토요일'.split('_'),\n    weekdaysShort : '일_월_화_수_목_금_토'.split('_'),\n    weekdaysMin : '일_월_화_수_목_금_토'.split('_'),\n    longDateFormat : {\n        LT : 'A h:mm',\n        LTS : 'A h:mm:ss',\n        L : 'YYYY.MM.DD',\n        LL : 'YYYY년 MMMM D일',\n        LLL : 'YYYY년 MMMM D일 A h:mm',\n        LLLL : 'YYYY년 MMMM D일 dddd A h:mm',\n        l : 'YYYY.MM.DD',\n        ll : 'YYYY년 MMMM D일',\n        lll : 'YYYY년 MMMM D일 A h:mm',\n        llll : 'YYYY년 MMMM D일 dddd A h:mm'\n    },\n    calendar : {\n        sameDay : '오늘 LT',\n        nextDay : '내일 LT',\n        nextWeek : 'dddd LT',\n        lastDay : '어제 LT',\n        lastWeek : '지난주 dddd LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : '%s 후',\n        past : '%s 전',\n        s : '몇 초',\n        ss : '%d초',\n        m : '1분',\n        mm : '%d분',\n        h : '한 시간',\n        hh : '%d시간',\n        d : '하루',\n        dd : '%d일',\n        M : '한 달',\n        MM : '%d달',\n        y : '일 년',\n        yy : '%d년'\n    },\n    dayOfMonthOrdinalParse : /\\d{1,2}일/,\n    ordinal : '%d일',\n    meridiemParse : /오전|오후/,\n    isPM : function (token) {\n        return token === '오후';\n    },\n    meridiem : function (hour, minute, isUpper) {\n        return hour < 12 ? '오전' : '오후';\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Kyrgyz [ky]\n//! author : Chyngyz Arystan uulu : https://github.com/chyngyz\n\n\nvar suffixes$2 = {\n    0: '-чү',\n    1: '-чи',\n    2: '-чи',\n    3: '-чү',\n    4: '-чү',\n    5: '-чи',\n    6: '-чы',\n    7: '-чи',\n    8: '-чи',\n    9: '-чу',\n    10: '-чу',\n    20: '-чы',\n    30: '-чу',\n    40: '-чы',\n    50: '-чү',\n    60: '-чы',\n    70: '-чи',\n    80: '-чи',\n    90: '-чу',\n    100: '-чү'\n};\n\nmoment.defineLocale('ky', {\n    months : 'январь_февраль_март_апрель_май_июнь_июль_август_сентябрь_октябрь_ноябрь_декабрь'.split('_'),\n    monthsShort : 'янв_фев_март_апр_май_июнь_июль_авг_сен_окт_ноя_дек'.split('_'),\n    weekdays : 'Жекшемби_Дүйшөмбү_Шейшемби_Шаршемби_Бейшемби_Жума_Ишемби'.split('_'),\n    weekdaysShort : 'Жек_Дүй_Шей_Шар_Бей_Жум_Ише'.split('_'),\n    weekdaysMin : 'Жк_Дй_Шй_Шр_Бй_Жм_Иш'.split('_'),\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD.MM.YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY HH:mm',\n        LLLL : 'dddd, D MMMM YYYY HH:mm'\n    },\n    calendar : {\n        sameDay : '[Бүгүн саат] LT',\n        nextDay : '[Эртең саат] LT',\n        nextWeek : 'dddd [саат] LT',\n        lastDay : '[Кече саат] LT',\n        lastWeek : '[Өткен аптанын] dddd [күнү] [саат] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : '%s ичинде',\n        past : '%s мурун',\n        s : 'бирнече секунд',\n        m : 'бир мүнөт',\n        mm : '%d мүнөт',\n        h : 'бир саат',\n        hh : '%d саат',\n        d : 'бир күн',\n        dd : '%d күн',\n        M : 'бир ай',\n        MM : '%d ай',\n        y : 'бир жыл',\n        yy : '%d жыл'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}-(чи|чы|чү|чу)/,\n    ordinal : function (number) {\n        var a = number % 10,\n            b = number >= 100 ? 100 : null;\n        return number + (suffixes$2[number] || suffixes$2[a] || suffixes$2[b]);\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 7  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Luxembourgish [lb]\n//! author : mweimerskirch : https://github.com/mweimerskirch\n//! author : David Raison : https://github.com/kwisatz\n\nfunction processRelativeTime$5(number, withoutSuffix, key, isFuture) {\n    var format = {\n        'm': ['eng Minutt', 'enger Minutt'],\n        'h': ['eng Stonn', 'enger Stonn'],\n        'd': ['een Dag', 'engem Dag'],\n        'M': ['ee Mount', 'engem Mount'],\n        'y': ['ee Joer', 'engem Joer']\n    };\n    return withoutSuffix ? format[key][0] : format[key][1];\n}\nfunction processFutureTime(string) {\n    var number = string.substr(0, string.indexOf(' '));\n    if (eifelerRegelAppliesToNumber(number)) {\n        return 'a ' + string;\n    }\n    return 'an ' + string;\n}\nfunction processPastTime(string) {\n    var number = string.substr(0, string.indexOf(' '));\n    if (eifelerRegelAppliesToNumber(number)) {\n        return 'viru ' + string;\n    }\n    return 'virun ' + string;\n}\n/**\n * Returns true if the word before the given number loses the '-n' ending.\n * e.g. 'an 10 Deeg' but 'a 5 Deeg'\n *\n * @param number {integer}\n * @returns {boolean}\n */\nfunction eifelerRegelAppliesToNumber(number) {\n    number = parseInt(number, 10);\n    if (isNaN(number)) {\n        return false;\n    }\n    if (number < 0) {\n        // Negative Number --> always true\n        return true;\n    } else if (number < 10) {\n        // Only 1 digit\n        if (4 <= number && number <= 7) {\n            return true;\n        }\n        return false;\n    } else if (number < 100) {\n        // 2 digits\n        var lastDigit = number % 10, firstDigit = number / 10;\n        if (lastDigit === 0) {\n            return eifelerRegelAppliesToNumber(firstDigit);\n        }\n        return eifelerRegelAppliesToNumber(lastDigit);\n    } else if (number < 10000) {\n        // 3 or 4 digits --> recursively check first digit\n        while (number >= 10) {\n            number = number / 10;\n        }\n        return eifelerRegelAppliesToNumber(number);\n    } else {\n        // Anything larger than 4 digits: recursively check first n-3 digits\n        number = number / 1000;\n        return eifelerRegelAppliesToNumber(number);\n    }\n}\n\nmoment.defineLocale('lb', {\n    months: 'Januar_Februar_Mäerz_Abrëll_Mee_Juni_Juli_August_September_Oktober_November_Dezember'.split('_'),\n    monthsShort: 'Jan._Febr._Mrz._Abr._Mee_Jun._Jul._Aug._Sept._Okt._Nov._Dez.'.split('_'),\n    monthsParseExact : true,\n    weekdays: 'Sonndeg_Méindeg_Dënschdeg_Mëttwoch_Donneschdeg_Freideg_Samschdeg'.split('_'),\n    weekdaysShort: 'So._Mé._Dë._Më._Do._Fr._Sa.'.split('_'),\n    weekdaysMin: 'So_Mé_Dë_Më_Do_Fr_Sa'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat: {\n        LT: 'H:mm [Auer]',\n        LTS: 'H:mm:ss [Auer]',\n        L: 'DD.MM.YYYY',\n        LL: 'D. MMMM YYYY',\n        LLL: 'D. MMMM YYYY H:mm [Auer]',\n        LLLL: 'dddd, D. MMMM YYYY H:mm [Auer]'\n    },\n    calendar: {\n        sameDay: '[Haut um] LT',\n        sameElse: 'L',\n        nextDay: '[Muer um] LT',\n        nextWeek: 'dddd [um] LT',\n        lastDay: '[Gëschter um] LT',\n        lastWeek: function () {\n            // Different date string for 'Dënschdeg' (Tuesday) and 'Donneschdeg' (Thursday) due to phonological rule\n            switch (this.day()) {\n                case 2:\n                case 4:\n                    return '[Leschten] dddd [um] LT';\n                default:\n                    return '[Leschte] dddd [um] LT';\n            }\n        }\n    },\n    relativeTime : {\n        future : processFutureTime,\n        past : processPastTime,\n        s : 'e puer Sekonnen',\n        m : processRelativeTime$5,\n        mm : '%d Minutten',\n        h : processRelativeTime$5,\n        hh : '%d Stonnen',\n        d : processRelativeTime$5,\n        dd : '%d Deeg',\n        M : processRelativeTime$5,\n        MM : '%d Méint',\n        y : processRelativeTime$5,\n        yy : '%d Joer'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}\\./,\n    ordinal: '%d.',\n    week: {\n        dow: 1, // Monday is the first day of the week.\n        doy: 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Lao [lo]\n//! author : Ryan Hart : https://github.com/ryanhart2\n\nmoment.defineLocale('lo', {\n    months : 'ມັງກອນ_ກຸມພາ_ມີນາ_ເມສາ_ພຶດສະພາ_ມິຖຸນາ_ກໍລະກົດ_ສິງຫາ_ກັນຍາ_ຕຸລາ_ພະຈິກ_ທັນວາ'.split('_'),\n    monthsShort : 'ມັງກອນ_ກຸມພາ_ມີນາ_ເມສາ_ພຶດສະພາ_ມິຖຸນາ_ກໍລະກົດ_ສິງຫາ_ກັນຍາ_ຕຸລາ_ພະຈິກ_ທັນວາ'.split('_'),\n    weekdays : 'ອາທິດ_ຈັນ_ອັງຄານ_ພຸດ_ພະຫັດ_ສຸກ_ເສົາ'.split('_'),\n    weekdaysShort : 'ທິດ_ຈັນ_ອັງຄານ_ພຸດ_ພະຫັດ_ສຸກ_ເສົາ'.split('_'),\n    weekdaysMin : 'ທ_ຈ_ອຄ_ພ_ພຫ_ສກ_ສ'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY HH:mm',\n        LLLL : 'ວັນdddd D MMMM YYYY HH:mm'\n    },\n    meridiemParse: /ຕອນເຊົ້າ|ຕອນແລງ/,\n    isPM: function (input) {\n        return input === 'ຕອນແລງ';\n    },\n    meridiem : function (hour, minute, isLower) {\n        if (hour < 12) {\n            return 'ຕອນເຊົ້າ';\n        } else {\n            return 'ຕອນແລງ';\n        }\n    },\n    calendar : {\n        sameDay : '[ມື້ນີ້ເວລາ] LT',\n        nextDay : '[ມື້ອື່ນເວລາ] LT',\n        nextWeek : '[ວັນ]dddd[ໜ້າເວລາ] LT',\n        lastDay : '[ມື້ວານນີ້ເວລາ] LT',\n        lastWeek : '[ວັນ]dddd[ແລ້ວນີ້ເວລາ] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'ອີກ %s',\n        past : '%sຜ່ານມາ',\n        s : 'ບໍ່ເທົ່າໃດວິນາທີ',\n        m : '1 ນາທີ',\n        mm : '%d ນາທີ',\n        h : '1 ຊົ່ວໂມງ',\n        hh : '%d ຊົ່ວໂມງ',\n        d : '1 ມື້',\n        dd : '%d ມື້',\n        M : '1 ເດືອນ',\n        MM : '%d ເດືອນ',\n        y : '1 ປີ',\n        yy : '%d ປີ'\n    },\n    dayOfMonthOrdinalParse: /(ທີ່)\\d{1,2}/,\n    ordinal : function (number) {\n        return 'ທີ່' + number;\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Lithuanian [lt]\n//! author : Mindaugas Mozūras : https://github.com/mmozuras\n\nvar units = {\n    'm' : 'minutė_minutės_minutę',\n    'mm': 'minutės_minučių_minutes',\n    'h' : 'valanda_valandos_valandą',\n    'hh': 'valandos_valandų_valandas',\n    'd' : 'diena_dienos_dieną',\n    'dd': 'dienos_dienų_dienas',\n    'M' : 'mėnuo_mėnesio_mėnesį',\n    'MM': 'mėnesiai_mėnesių_mėnesius',\n    'y' : 'metai_metų_metus',\n    'yy': 'metai_metų_metus'\n};\nfunction translateSeconds(number, withoutSuffix, key, isFuture) {\n    if (withoutSuffix) {\n        return 'kelios sekundės';\n    } else {\n        return isFuture ? 'kelių sekundžių' : 'kelias sekundes';\n    }\n}\nfunction translateSingular(number, withoutSuffix, key, isFuture) {\n    return withoutSuffix ? forms(key)[0] : (isFuture ? forms(key)[1] : forms(key)[2]);\n}\nfunction special(number) {\n    return number % 10 === 0 || (number > 10 && number < 20);\n}\nfunction forms(key) {\n    return units[key].split('_');\n}\nfunction translate$6(number, withoutSuffix, key, isFuture) {\n    var result = number + ' ';\n    if (number === 1) {\n        return result + translateSingular(number, withoutSuffix, key[0], isFuture);\n    } else if (withoutSuffix) {\n        return result + (special(number) ? forms(key)[1] : forms(key)[0]);\n    } else {\n        if (isFuture) {\n            return result + forms(key)[1];\n        } else {\n            return result + (special(number) ? forms(key)[1] : forms(key)[2]);\n        }\n    }\n}\nmoment.defineLocale('lt', {\n    months : {\n        format: 'sausio_vasario_kovo_balandžio_gegužės_birželio_liepos_rugpjūčio_rugsėjo_spalio_lapkričio_gruodžio'.split('_'),\n        standalone: 'sausis_vasaris_kovas_balandis_gegužė_birželis_liepa_rugpjūtis_rugsėjis_spalis_lapkritis_gruodis'.split('_'),\n        isFormat: /D[oD]?(\\[[^\\[\\]]*\\]|\\s)+MMMM?|MMMM?(\\[[^\\[\\]]*\\]|\\s)+D[oD]?/\n    },\n    monthsShort : 'sau_vas_kov_bal_geg_bir_lie_rgp_rgs_spa_lap_grd'.split('_'),\n    weekdays : {\n        format: 'sekmadienį_pirmadienį_antradienį_trečiadienį_ketvirtadienį_penktadienį_šeštadienį'.split('_'),\n        standalone: 'sekmadienis_pirmadienis_antradienis_trečiadienis_ketvirtadienis_penktadienis_šeštadienis'.split('_'),\n        isFormat: /dddd HH:mm/\n    },\n    weekdaysShort : 'Sek_Pir_Ant_Tre_Ket_Pen_Šeš'.split('_'),\n    weekdaysMin : 'S_P_A_T_K_Pn_Š'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'YYYY-MM-DD',\n        LL : 'YYYY [m.] MMMM D [d.]',\n        LLL : 'YYYY [m.] MMMM D [d.], HH:mm [val.]',\n        LLLL : 'YYYY [m.] MMMM D [d.], dddd, HH:mm [val.]',\n        l : 'YYYY-MM-DD',\n        ll : 'YYYY [m.] MMMM D [d.]',\n        lll : 'YYYY [m.] MMMM D [d.], HH:mm [val.]',\n        llll : 'YYYY [m.] MMMM D [d.], ddd, HH:mm [val.]'\n    },\n    calendar : {\n        sameDay : '[Šiandien] LT',\n        nextDay : '[Rytoj] LT',\n        nextWeek : 'dddd LT',\n        lastDay : '[Vakar] LT',\n        lastWeek : '[Praėjusį] dddd LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'po %s',\n        past : 'prieš %s',\n        s : translateSeconds,\n        m : translateSingular,\n        mm : translate$6,\n        h : translateSingular,\n        hh : translate$6,\n        d : translateSingular,\n        dd : translate$6,\n        M : translateSingular,\n        MM : translate$6,\n        y : translateSingular,\n        yy : translate$6\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}-oji/,\n    ordinal : function (number) {\n        return number + '-oji';\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Latvian [lv]\n//! author : Kristaps Karlsons : https://github.com/skakri\n//! author : Jānis Elmeris : https://github.com/JanisE\n\nvar units$1 = {\n    'm': 'minūtes_minūtēm_minūte_minūtes'.split('_'),\n    'mm': 'minūtes_minūtēm_minūte_minūtes'.split('_'),\n    'h': 'stundas_stundām_stunda_stundas'.split('_'),\n    'hh': 'stundas_stundām_stunda_stundas'.split('_'),\n    'd': 'dienas_dienām_diena_dienas'.split('_'),\n    'dd': 'dienas_dienām_diena_dienas'.split('_'),\n    'M': 'mēneša_mēnešiem_mēnesis_mēneši'.split('_'),\n    'MM': 'mēneša_mēnešiem_mēnesis_mēneši'.split('_'),\n    'y': 'gada_gadiem_gads_gadi'.split('_'),\n    'yy': 'gada_gadiem_gads_gadi'.split('_')\n};\n/**\n * @param withoutSuffix boolean true = a length of time; false = before/after a period of time.\n */\nfunction format(forms, number, withoutSuffix) {\n    if (withoutSuffix) {\n        // E.g. \"21 minūte\", \"3 minūtes\".\n        return number % 10 === 1 && number % 100 !== 11 ? forms[2] : forms[3];\n    } else {\n        // E.g. \"21 minūtes\" as in \"pēc 21 minūtes\".\n        // E.g. \"3 minūtēm\" as in \"pēc 3 minūtēm\".\n        return number % 10 === 1 && number % 100 !== 11 ? forms[0] : forms[1];\n    }\n}\nfunction relativeTimeWithPlural$1(number, withoutSuffix, key) {\n    return number + ' ' + format(units$1[key], number, withoutSuffix);\n}\nfunction relativeTimeWithSingular(number, withoutSuffix, key) {\n    return format(units$1[key], number, withoutSuffix);\n}\nfunction relativeSeconds(number, withoutSuffix) {\n    return withoutSuffix ? 'dažas sekundes' : 'dažām sekundēm';\n}\n\nmoment.defineLocale('lv', {\n    months : 'janvāris_februāris_marts_aprīlis_maijs_jūnijs_jūlijs_augusts_septembris_oktobris_novembris_decembris'.split('_'),\n    monthsShort : 'jan_feb_mar_apr_mai_jūn_jūl_aug_sep_okt_nov_dec'.split('_'),\n    weekdays : 'svētdiena_pirmdiena_otrdiena_trešdiena_ceturtdiena_piektdiena_sestdiena'.split('_'),\n    weekdaysShort : 'Sv_P_O_T_C_Pk_S'.split('_'),\n    weekdaysMin : 'Sv_P_O_T_C_Pk_S'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD.MM.YYYY.',\n        LL : 'YYYY. [gada] D. MMMM',\n        LLL : 'YYYY. [gada] D. MMMM, HH:mm',\n        LLLL : 'YYYY. [gada] D. MMMM, dddd, HH:mm'\n    },\n    calendar : {\n        sameDay : '[Šodien pulksten] LT',\n        nextDay : '[Rīt pulksten] LT',\n        nextWeek : 'dddd [pulksten] LT',\n        lastDay : '[Vakar pulksten] LT',\n        lastWeek : '[Pagājušā] dddd [pulksten] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'pēc %s',\n        past : 'pirms %s',\n        s : relativeSeconds,\n        m : relativeTimeWithSingular,\n        mm : relativeTimeWithPlural$1,\n        h : relativeTimeWithSingular,\n        hh : relativeTimeWithPlural$1,\n        d : relativeTimeWithSingular,\n        dd : relativeTimeWithPlural$1,\n        M : relativeTimeWithSingular,\n        MM : relativeTimeWithPlural$1,\n        y : relativeTimeWithSingular,\n        yy : relativeTimeWithPlural$1\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}\\./,\n    ordinal : '%d.',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Montenegrin [me]\n//! author : Miodrag Nikač <miodrag@restartit.me> : https://github.com/miodragnikac\n\nvar translator = {\n    words: { //Different grammatical cases\n        m: ['jedan minut', 'jednog minuta'],\n        mm: ['minut', 'minuta', 'minuta'],\n        h: ['jedan sat', 'jednog sata'],\n        hh: ['sat', 'sata', 'sati'],\n        dd: ['dan', 'dana', 'dana'],\n        MM: ['mjesec', 'mjeseca', 'mjeseci'],\n        yy: ['godina', 'godine', 'godina']\n    },\n    correctGrammaticalCase: function (number, wordKey) {\n        return number === 1 ? wordKey[0] : (number >= 2 && number <= 4 ? wordKey[1] : wordKey[2]);\n    },\n    translate: function (number, withoutSuffix, key) {\n        var wordKey = translator.words[key];\n        if (key.length === 1) {\n            return withoutSuffix ? wordKey[0] : wordKey[1];\n        } else {\n            return number + ' ' + translator.correctGrammaticalCase(number, wordKey);\n        }\n    }\n};\n\nmoment.defineLocale('me', {\n    months: 'januar_februar_mart_april_maj_jun_jul_avgust_septembar_oktobar_novembar_decembar'.split('_'),\n    monthsShort: 'jan._feb._mar._apr._maj_jun_jul_avg._sep._okt._nov._dec.'.split('_'),\n    monthsParseExact : true,\n    weekdays: 'nedjelja_ponedjeljak_utorak_srijeda_četvrtak_petak_subota'.split('_'),\n    weekdaysShort: 'ned._pon._uto._sri._čet._pet._sub.'.split('_'),\n    weekdaysMin: 'ne_po_ut_sr_če_pe_su'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat: {\n        LT: 'H:mm',\n        LTS : 'H:mm:ss',\n        L: 'DD.MM.YYYY',\n        LL: 'D. MMMM YYYY',\n        LLL: 'D. MMMM YYYY H:mm',\n        LLLL: 'dddd, D. MMMM YYYY H:mm'\n    },\n    calendar: {\n        sameDay: '[danas u] LT',\n        nextDay: '[sjutra u] LT',\n\n        nextWeek: function () {\n            switch (this.day()) {\n                case 0:\n                    return '[u] [nedjelju] [u] LT';\n                case 3:\n                    return '[u] [srijedu] [u] LT';\n                case 6:\n                    return '[u] [subotu] [u] LT';\n                case 1:\n                case 2:\n                case 4:\n                case 5:\n                    return '[u] dddd [u] LT';\n            }\n        },\n        lastDay  : '[juče u] LT',\n        lastWeek : function () {\n            var lastWeekDays = [\n                '[prošle] [nedjelje] [u] LT',\n                '[prošlog] [ponedjeljka] [u] LT',\n                '[prošlog] [utorka] [u] LT',\n                '[prošle] [srijede] [u] LT',\n                '[prošlog] [četvrtka] [u] LT',\n                '[prošlog] [petka] [u] LT',\n                '[prošle] [subote] [u] LT'\n            ];\n            return lastWeekDays[this.day()];\n        },\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'za %s',\n        past   : 'prije %s',\n        s      : 'nekoliko sekundi',\n        m      : translator.translate,\n        mm     : translator.translate,\n        h      : translator.translate,\n        hh     : translator.translate,\n        d      : 'dan',\n        dd     : translator.translate,\n        M      : 'mjesec',\n        MM     : translator.translate,\n        y      : 'godinu',\n        yy     : translator.translate\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}\\./,\n    ordinal : '%d.',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 7  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Maori [mi]\n//! author : John Corrigan <robbiecloset@gmail.com> : https://github.com/johnideal\n\nmoment.defineLocale('mi', {\n    months: 'Kohi-tāte_Hui-tanguru_Poutū-te-rangi_Paenga-whāwhā_Haratua_Pipiri_Hōngoingoi_Here-turi-kōkā_Mahuru_Whiringa-ā-nuku_Whiringa-ā-rangi_Hakihea'.split('_'),\n    monthsShort: 'Kohi_Hui_Pou_Pae_Hara_Pipi_Hōngoi_Here_Mahu_Whi-nu_Whi-ra_Haki'.split('_'),\n    monthsRegex: /(?:['a-z\\u0101\\u014D\\u016B]+\\-?){1,3}/i,\n    monthsStrictRegex: /(?:['a-z\\u0101\\u014D\\u016B]+\\-?){1,3}/i,\n    monthsShortRegex: /(?:['a-z\\u0101\\u014D\\u016B]+\\-?){1,3}/i,\n    monthsShortStrictRegex: /(?:['a-z\\u0101\\u014D\\u016B]+\\-?){1,2}/i,\n    weekdays: 'Rātapu_Mane_Tūrei_Wenerei_Tāite_Paraire_Hātarei'.split('_'),\n    weekdaysShort: 'Ta_Ma_Tū_We_Tāi_Pa_Hā'.split('_'),\n    weekdaysMin: 'Ta_Ma_Tū_We_Tāi_Pa_Hā'.split('_'),\n    longDateFormat: {\n        LT: 'HH:mm',\n        LTS: 'HH:mm:ss',\n        L: 'DD/MM/YYYY',\n        LL: 'D MMMM YYYY',\n        LLL: 'D MMMM YYYY [i] HH:mm',\n        LLLL: 'dddd, D MMMM YYYY [i] HH:mm'\n    },\n    calendar: {\n        sameDay: '[i teie mahana, i] LT',\n        nextDay: '[apopo i] LT',\n        nextWeek: 'dddd [i] LT',\n        lastDay: '[inanahi i] LT',\n        lastWeek: 'dddd [whakamutunga i] LT',\n        sameElse: 'L'\n    },\n    relativeTime: {\n        future: 'i roto i %s',\n        past: '%s i mua',\n        s: 'te hēkona ruarua',\n        m: 'he meneti',\n        mm: '%d meneti',\n        h: 'te haora',\n        hh: '%d haora',\n        d: 'he ra',\n        dd: '%d ra',\n        M: 'he marama',\n        MM: '%d marama',\n        y: 'he tau',\n        yy: '%d tau'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}º/,\n    ordinal: '%dº',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Macedonian [mk]\n//! author : Borislav Mickov : https://github.com/B0k0\n\nmoment.defineLocale('mk', {\n    months : 'јануари_февруари_март_април_мај_јуни_јули_август_септември_октомври_ноември_декември'.split('_'),\n    monthsShort : 'јан_фев_мар_апр_мај_јун_јул_авг_сеп_окт_ное_дек'.split('_'),\n    weekdays : 'недела_понеделник_вторник_среда_четврток_петок_сабота'.split('_'),\n    weekdaysShort : 'нед_пон_вто_сре_чет_пет_саб'.split('_'),\n    weekdaysMin : 'нe_пo_вт_ср_че_пе_сa'.split('_'),\n    longDateFormat : {\n        LT : 'H:mm',\n        LTS : 'H:mm:ss',\n        L : 'D.MM.YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY H:mm',\n        LLLL : 'dddd, D MMMM YYYY H:mm'\n    },\n    calendar : {\n        sameDay : '[Денес во] LT',\n        nextDay : '[Утре во] LT',\n        nextWeek : '[Во] dddd [во] LT',\n        lastDay : '[Вчера во] LT',\n        lastWeek : function () {\n            switch (this.day()) {\n                case 0:\n                case 3:\n                case 6:\n                    return '[Изминатата] dddd [во] LT';\n                case 1:\n                case 2:\n                case 4:\n                case 5:\n                    return '[Изминатиот] dddd [во] LT';\n            }\n        },\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'после %s',\n        past : 'пред %s',\n        s : 'неколку секунди',\n        m : 'минута',\n        mm : '%d минути',\n        h : 'час',\n        hh : '%d часа',\n        d : 'ден',\n        dd : '%d дена',\n        M : 'месец',\n        MM : '%d месеци',\n        y : 'година',\n        yy : '%d години'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}-(ев|ен|ти|ви|ри|ми)/,\n    ordinal : function (number) {\n        var lastDigit = number % 10,\n            last2Digits = number % 100;\n        if (number === 0) {\n            return number + '-ев';\n        } else if (last2Digits === 0) {\n            return number + '-ен';\n        } else if (last2Digits > 10 && last2Digits < 20) {\n            return number + '-ти';\n        } else if (lastDigit === 1) {\n            return number + '-ви';\n        } else if (lastDigit === 2) {\n            return number + '-ри';\n        } else if (lastDigit === 7 || lastDigit === 8) {\n            return number + '-ми';\n        } else {\n            return number + '-ти';\n        }\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 7  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Malayalam [ml]\n//! author : Floyd Pink : https://github.com/floydpink\n\nmoment.defineLocale('ml', {\n    months : 'ജനുവരി_ഫെബ്രുവരി_മാർച്ച്_ഏപ്രിൽ_മേയ്_ജൂൺ_ജൂലൈ_ഓഗസ്റ്റ്_സെപ്റ്റംബർ_ഒക്ടോബർ_നവംബർ_ഡിസംബർ'.split('_'),\n    monthsShort : 'ജനു._ഫെബ്രു._മാർ._ഏപ്രി._മേയ്_ജൂൺ_ജൂലൈ._ഓഗ._സെപ്റ്റ._ഒക്ടോ._നവം._ഡിസം.'.split('_'),\n    monthsParseExact : true,\n    weekdays : 'ഞായറാഴ്ച_തിങ്കളാഴ്ച_ചൊവ്വാഴ്ച_ബുധനാഴ്ച_വ്യാഴാഴ്ച_വെള്ളിയാഴ്ച_ശനിയാഴ്ച'.split('_'),\n    weekdaysShort : 'ഞായർ_തിങ്കൾ_ചൊവ്വ_ബുധൻ_വ്യാഴം_വെള്ളി_ശനി'.split('_'),\n    weekdaysMin : 'ഞാ_തി_ചൊ_ബു_വ്യാ_വെ_ശ'.split('_'),\n    longDateFormat : {\n        LT : 'A h:mm -നു',\n        LTS : 'A h:mm:ss -നു',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY, A h:mm -നു',\n        LLLL : 'dddd, D MMMM YYYY, A h:mm -നു'\n    },\n    calendar : {\n        sameDay : '[ഇന്ന്] LT',\n        nextDay : '[നാളെ] LT',\n        nextWeek : 'dddd, LT',\n        lastDay : '[ഇന്നലെ] LT',\n        lastWeek : '[കഴിഞ്ഞ] dddd, LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : '%s കഴിഞ്ഞ്',\n        past : '%s മുൻപ്',\n        s : 'അൽപ നിമിഷങ്ങൾ',\n        m : 'ഒരു മിനിറ്റ്',\n        mm : '%d മിനിറ്റ്',\n        h : 'ഒരു മണിക്കൂർ',\n        hh : '%d മണിക്കൂർ',\n        d : 'ഒരു ദിവസം',\n        dd : '%d ദിവസം',\n        M : 'ഒരു മാസം',\n        MM : '%d മാസം',\n        y : 'ഒരു വർഷം',\n        yy : '%d വർഷം'\n    },\n    meridiemParse: /രാത്രി|രാവിലെ|ഉച്ച കഴിഞ്ഞ്|വൈകുന്നേരം|രാത്രി/i,\n    meridiemHour : function (hour, meridiem) {\n        if (hour === 12) {\n            hour = 0;\n        }\n        if ((meridiem === 'രാത്രി' && hour >= 4) ||\n                meridiem === 'ഉച്ച കഴിഞ്ഞ്' ||\n                meridiem === 'വൈകുന്നേരം') {\n            return hour + 12;\n        } else {\n            return hour;\n        }\n    },\n    meridiem : function (hour, minute, isLower) {\n        if (hour < 4) {\n            return 'രാത്രി';\n        } else if (hour < 12) {\n            return 'രാവിലെ';\n        } else if (hour < 17) {\n            return 'ഉച്ച കഴിഞ്ഞ്';\n        } else if (hour < 20) {\n            return 'വൈകുന്നേരം';\n        } else {\n            return 'രാത്രി';\n        }\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Marathi [mr]\n//! author : Harshad Kale : https://github.com/kalehv\n//! author : Vivek Athalye : https://github.com/vnathalye\n\nvar symbolMap$8 = {\n    '1': '१',\n    '2': '२',\n    '3': '३',\n    '4': '४',\n    '5': '५',\n    '6': '६',\n    '7': '७',\n    '8': '८',\n    '9': '९',\n    '0': '०'\n};\nvar numberMap$7 = {\n    '१': '1',\n    '२': '2',\n    '३': '3',\n    '४': '4',\n    '५': '5',\n    '६': '6',\n    '७': '7',\n    '८': '8',\n    '९': '9',\n    '०': '0'\n};\n\nfunction relativeTimeMr(number, withoutSuffix, string, isFuture)\n{\n    var output = '';\n    if (withoutSuffix) {\n        switch (string) {\n            case 's': output = 'काही सेकंद'; break;\n            case 'm': output = 'एक मिनिट'; break;\n            case 'mm': output = '%d मिनिटे'; break;\n            case 'h': output = 'एक तास'; break;\n            case 'hh': output = '%d तास'; break;\n            case 'd': output = 'एक दिवस'; break;\n            case 'dd': output = '%d दिवस'; break;\n            case 'M': output = 'एक महिना'; break;\n            case 'MM': output = '%d महिने'; break;\n            case 'y': output = 'एक वर्ष'; break;\n            case 'yy': output = '%d वर्षे'; break;\n        }\n    }\n    else {\n        switch (string) {\n            case 's': output = 'काही सेकंदां'; break;\n            case 'm': output = 'एका मिनिटा'; break;\n            case 'mm': output = '%d मिनिटां'; break;\n            case 'h': output = 'एका तासा'; break;\n            case 'hh': output = '%d तासां'; break;\n            case 'd': output = 'एका दिवसा'; break;\n            case 'dd': output = '%d दिवसां'; break;\n            case 'M': output = 'एका महिन्या'; break;\n            case 'MM': output = '%d महिन्यां'; break;\n            case 'y': output = 'एका वर्षा'; break;\n            case 'yy': output = '%d वर्षां'; break;\n        }\n    }\n    return output.replace(/%d/i, number);\n}\n\nmoment.defineLocale('mr', {\n    months : 'जानेवारी_फेब्रुवारी_मार्च_एप्रिल_मे_जून_जुलै_ऑगस्ट_सप्टेंबर_ऑक्टोबर_नोव्हेंबर_डिसेंबर'.split('_'),\n    monthsShort: 'जाने._फेब्रु._मार्च._एप्रि._मे._जून._जुलै._ऑग._सप्टें._ऑक्टो._नोव्हें._डिसें.'.split('_'),\n    monthsParseExact : true,\n    weekdays : 'रविवार_सोमवार_मंगळवार_बुधवार_गुरूवार_शुक्रवार_शनिवार'.split('_'),\n    weekdaysShort : 'रवि_सोम_मंगळ_बुध_गुरू_शुक्र_शनि'.split('_'),\n    weekdaysMin : 'र_सो_मं_बु_गु_शु_श'.split('_'),\n    longDateFormat : {\n        LT : 'A h:mm वाजता',\n        LTS : 'A h:mm:ss वाजता',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY, A h:mm वाजता',\n        LLLL : 'dddd, D MMMM YYYY, A h:mm वाजता'\n    },\n    calendar : {\n        sameDay : '[आज] LT',\n        nextDay : '[उद्या] LT',\n        nextWeek : 'dddd, LT',\n        lastDay : '[काल] LT',\n        lastWeek: '[मागील] dddd, LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future: '%sमध्ये',\n        past: '%sपूर्वी',\n        s: relativeTimeMr,\n        m: relativeTimeMr,\n        mm: relativeTimeMr,\n        h: relativeTimeMr,\n        hh: relativeTimeMr,\n        d: relativeTimeMr,\n        dd: relativeTimeMr,\n        M: relativeTimeMr,\n        MM: relativeTimeMr,\n        y: relativeTimeMr,\n        yy: relativeTimeMr\n    },\n    preparse: function (string) {\n        return string.replace(/[१२३४५६७८९०]/g, function (match) {\n            return numberMap$7[match];\n        });\n    },\n    postformat: function (string) {\n        return string.replace(/\\d/g, function (match) {\n            return symbolMap$8[match];\n        });\n    },\n    meridiemParse: /रात्री|सकाळी|दुपारी|सायंकाळी/,\n    meridiemHour : function (hour, meridiem) {\n        if (hour === 12) {\n            hour = 0;\n        }\n        if (meridiem === 'रात्री') {\n            return hour < 4 ? hour : hour + 12;\n        } else if (meridiem === 'सकाळी') {\n            return hour;\n        } else if (meridiem === 'दुपारी') {\n            return hour >= 10 ? hour : hour + 12;\n        } else if (meridiem === 'सायंकाळी') {\n            return hour + 12;\n        }\n    },\n    meridiem: function (hour, minute, isLower) {\n        if (hour < 4) {\n            return 'रात्री';\n        } else if (hour < 10) {\n            return 'सकाळी';\n        } else if (hour < 17) {\n            return 'दुपारी';\n        } else if (hour < 20) {\n            return 'सायंकाळी';\n        } else {\n            return 'रात्री';\n        }\n    },\n    week : {\n        dow : 0, // Sunday is the first day of the week.\n        doy : 6  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Malay [ms-my]\n//! note : DEPRECATED, the correct one is [ms]\n//! author : Weldan Jamili : https://github.com/weldan\n\nmoment.defineLocale('ms-my', {\n    months : 'Januari_Februari_Mac_April_Mei_Jun_Julai_Ogos_September_Oktober_November_Disember'.split('_'),\n    monthsShort : 'Jan_Feb_Mac_Apr_Mei_Jun_Jul_Ogs_Sep_Okt_Nov_Dis'.split('_'),\n    weekdays : 'Ahad_Isnin_Selasa_Rabu_Khamis_Jumaat_Sabtu'.split('_'),\n    weekdaysShort : 'Ahd_Isn_Sel_Rab_Kha_Jum_Sab'.split('_'),\n    weekdaysMin : 'Ah_Is_Sl_Rb_Km_Jm_Sb'.split('_'),\n    longDateFormat : {\n        LT : 'HH.mm',\n        LTS : 'HH.mm.ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY [pukul] HH.mm',\n        LLLL : 'dddd, D MMMM YYYY [pukul] HH.mm'\n    },\n    meridiemParse: /pagi|tengahari|petang|malam/,\n    meridiemHour: function (hour, meridiem) {\n        if (hour === 12) {\n            hour = 0;\n        }\n        if (meridiem === 'pagi') {\n            return hour;\n        } else if (meridiem === 'tengahari') {\n            return hour >= 11 ? hour : hour + 12;\n        } else if (meridiem === 'petang' || meridiem === 'malam') {\n            return hour + 12;\n        }\n    },\n    meridiem : function (hours, minutes, isLower) {\n        if (hours < 11) {\n            return 'pagi';\n        } else if (hours < 15) {\n            return 'tengahari';\n        } else if (hours < 19) {\n            return 'petang';\n        } else {\n            return 'malam';\n        }\n    },\n    calendar : {\n        sameDay : '[Hari ini pukul] LT',\n        nextDay : '[Esok pukul] LT',\n        nextWeek : 'dddd [pukul] LT',\n        lastDay : '[Kelmarin pukul] LT',\n        lastWeek : 'dddd [lepas pukul] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'dalam %s',\n        past : '%s yang lepas',\n        s : 'beberapa saat',\n        m : 'seminit',\n        mm : '%d minit',\n        h : 'sejam',\n        hh : '%d jam',\n        d : 'sehari',\n        dd : '%d hari',\n        M : 'sebulan',\n        MM : '%d bulan',\n        y : 'setahun',\n        yy : '%d tahun'\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 7  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Malay [ms]\n//! author : Weldan Jamili : https://github.com/weldan\n\nmoment.defineLocale('ms', {\n    months : 'Januari_Februari_Mac_April_Mei_Jun_Julai_Ogos_September_Oktober_November_Disember'.split('_'),\n    monthsShort : 'Jan_Feb_Mac_Apr_Mei_Jun_Jul_Ogs_Sep_Okt_Nov_Dis'.split('_'),\n    weekdays : 'Ahad_Isnin_Selasa_Rabu_Khamis_Jumaat_Sabtu'.split('_'),\n    weekdaysShort : 'Ahd_Isn_Sel_Rab_Kha_Jum_Sab'.split('_'),\n    weekdaysMin : 'Ah_Is_Sl_Rb_Km_Jm_Sb'.split('_'),\n    longDateFormat : {\n        LT : 'HH.mm',\n        LTS : 'HH.mm.ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY [pukul] HH.mm',\n        LLLL : 'dddd, D MMMM YYYY [pukul] HH.mm'\n    },\n    meridiemParse: /pagi|tengahari|petang|malam/,\n    meridiemHour: function (hour, meridiem) {\n        if (hour === 12) {\n            hour = 0;\n        }\n        if (meridiem === 'pagi') {\n            return hour;\n        } else if (meridiem === 'tengahari') {\n            return hour >= 11 ? hour : hour + 12;\n        } else if (meridiem === 'petang' || meridiem === 'malam') {\n            return hour + 12;\n        }\n    },\n    meridiem : function (hours, minutes, isLower) {\n        if (hours < 11) {\n            return 'pagi';\n        } else if (hours < 15) {\n            return 'tengahari';\n        } else if (hours < 19) {\n            return 'petang';\n        } else {\n            return 'malam';\n        }\n    },\n    calendar : {\n        sameDay : '[Hari ini pukul] LT',\n        nextDay : '[Esok pukul] LT',\n        nextWeek : 'dddd [pukul] LT',\n        lastDay : '[Kelmarin pukul] LT',\n        lastWeek : 'dddd [lepas pukul] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'dalam %s',\n        past : '%s yang lepas',\n        s : 'beberapa saat',\n        m : 'seminit',\n        mm : '%d minit',\n        h : 'sejam',\n        hh : '%d jam',\n        d : 'sehari',\n        dd : '%d hari',\n        M : 'sebulan',\n        MM : '%d bulan',\n        y : 'setahun',\n        yy : '%d tahun'\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 7  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Burmese [my]\n//! author : Squar team, mysquar.com\n//! author : David Rossellat : https://github.com/gholadr\n//! author : Tin Aung Lin : https://github.com/thanyawzinmin\n\nvar symbolMap$9 = {\n    '1': '၁',\n    '2': '၂',\n    '3': '၃',\n    '4': '၄',\n    '5': '၅',\n    '6': '၆',\n    '7': '၇',\n    '8': '၈',\n    '9': '၉',\n    '0': '၀'\n};\nvar numberMap$8 = {\n    '၁': '1',\n    '၂': '2',\n    '၃': '3',\n    '၄': '4',\n    '၅': '5',\n    '၆': '6',\n    '၇': '7',\n    '၈': '8',\n    '၉': '9',\n    '၀': '0'\n};\n\nmoment.defineLocale('my', {\n    months: 'ဇန်နဝါရီ_ဖေဖော်ဝါရီ_မတ်_ဧပြီ_မေ_ဇွန်_ဇူလိုင်_သြဂုတ်_စက်တင်ဘာ_အောက်တိုဘာ_နိုဝင်ဘာ_ဒီဇင်ဘာ'.split('_'),\n    monthsShort: 'ဇန်_ဖေ_မတ်_ပြီ_မေ_ဇွန်_လိုင်_သြ_စက်_အောက်_နို_ဒီ'.split('_'),\n    weekdays: 'တနင်္ဂနွေ_တနင်္လာ_အင်္ဂါ_ဗုဒ္ဓဟူး_ကြာသပတေး_သောကြာ_စနေ'.split('_'),\n    weekdaysShort: 'နွေ_လာ_ဂါ_ဟူး_ကြာ_သော_နေ'.split('_'),\n    weekdaysMin: 'နွေ_လာ_ဂါ_ဟူး_ကြာ_သော_နေ'.split('_'),\n\n    longDateFormat: {\n        LT: 'HH:mm',\n        LTS: 'HH:mm:ss',\n        L: 'DD/MM/YYYY',\n        LL: 'D MMMM YYYY',\n        LLL: 'D MMMM YYYY HH:mm',\n        LLLL: 'dddd D MMMM YYYY HH:mm'\n    },\n    calendar: {\n        sameDay: '[ယနေ.] LT [မှာ]',\n        nextDay: '[မနက်ဖြန်] LT [မှာ]',\n        nextWeek: 'dddd LT [မှာ]',\n        lastDay: '[မနေ.က] LT [မှာ]',\n        lastWeek: '[ပြီးခဲ့သော] dddd LT [မှာ]',\n        sameElse: 'L'\n    },\n    relativeTime: {\n        future: 'လာမည့် %s မှာ',\n        past: 'လွန်ခဲ့သော %s က',\n        s: 'စက္ကန်.အနည်းငယ်',\n        m: 'တစ်မိနစ်',\n        mm: '%d မိနစ်',\n        h: 'တစ်နာရီ',\n        hh: '%d နာရီ',\n        d: 'တစ်ရက်',\n        dd: '%d ရက်',\n        M: 'တစ်လ',\n        MM: '%d လ',\n        y: 'တစ်နှစ်',\n        yy: '%d နှစ်'\n    },\n    preparse: function (string) {\n        return string.replace(/[၁၂၃၄၅၆၇၈၉၀]/g, function (match) {\n            return numberMap$8[match];\n        });\n    },\n    postformat: function (string) {\n        return string.replace(/\\d/g, function (match) {\n            return symbolMap$9[match];\n        });\n    },\n    week: {\n        dow: 1, // Monday is the first day of the week.\n        doy: 4 // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Norwegian Bokmål [nb]\n//! authors : Espen Hovlandsdal : https://github.com/rexxars\n//!           Sigurd Gartmann : https://github.com/sigurdga\n\nmoment.defineLocale('nb', {\n    months : 'januar_februar_mars_april_mai_juni_juli_august_september_oktober_november_desember'.split('_'),\n    monthsShort : 'jan._feb._mars_april_mai_juni_juli_aug._sep._okt._nov._des.'.split('_'),\n    monthsParseExact : true,\n    weekdays : 'søndag_mandag_tirsdag_onsdag_torsdag_fredag_lørdag'.split('_'),\n    weekdaysShort : 'sø._ma._ti._on._to._fr._lø.'.split('_'),\n    weekdaysMin : 'sø_ma_ti_on_to_fr_lø'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD.MM.YYYY',\n        LL : 'D. MMMM YYYY',\n        LLL : 'D. MMMM YYYY [kl.] HH:mm',\n        LLLL : 'dddd D. MMMM YYYY [kl.] HH:mm'\n    },\n    calendar : {\n        sameDay: '[i dag kl.] LT',\n        nextDay: '[i morgen kl.] LT',\n        nextWeek: 'dddd [kl.] LT',\n        lastDay: '[i går kl.] LT',\n        lastWeek: '[forrige] dddd [kl.] LT',\n        sameElse: 'L'\n    },\n    relativeTime : {\n        future : 'om %s',\n        past : '%s siden',\n        s : 'noen sekunder',\n        m : 'ett minutt',\n        mm : '%d minutter',\n        h : 'en time',\n        hh : '%d timer',\n        d : 'en dag',\n        dd : '%d dager',\n        M : 'en måned',\n        MM : '%d måneder',\n        y : 'ett år',\n        yy : '%d år'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}\\./,\n    ordinal : '%d.',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Nepalese [ne]\n//! author : suvash : https://github.com/suvash\n\nvar symbolMap$10 = {\n    '1': '१',\n    '2': '२',\n    '3': '३',\n    '4': '४',\n    '5': '५',\n    '6': '६',\n    '7': '७',\n    '8': '८',\n    '9': '९',\n    '0': '०'\n};\nvar numberMap$9 = {\n    '१': '1',\n    '२': '2',\n    '३': '3',\n    '४': '4',\n    '५': '5',\n    '६': '6',\n    '७': '7',\n    '८': '8',\n    '९': '9',\n    '०': '0'\n};\n\nmoment.defineLocale('ne', {\n    months : 'जनवरी_फेब्रुवरी_मार्च_अप्रिल_मई_जुन_जुलाई_अगष्ट_सेप्टेम्बर_अक्टोबर_नोभेम्बर_डिसेम्बर'.split('_'),\n    monthsShort : 'जन._फेब्रु._मार्च_अप्रि._मई_जुन_जुलाई._अग._सेप्ट._अक्टो._नोभे._डिसे.'.split('_'),\n    monthsParseExact : true,\n    weekdays : 'आइतबार_सोमबार_मङ्गलबार_बुधबार_बिहिबार_शुक्रबार_शनिबार'.split('_'),\n    weekdaysShort : 'आइत._सोम._मङ्गल._बुध._बिहि._शुक्र._शनि.'.split('_'),\n    weekdaysMin : 'आ._सो._मं._बु._बि._शु._श.'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat : {\n        LT : 'Aको h:mm बजे',\n        LTS : 'Aको h:mm:ss बजे',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY, Aको h:mm बजे',\n        LLLL : 'dddd, D MMMM YYYY, Aको h:mm बजे'\n    },\n    preparse: function (string) {\n        return string.replace(/[१२३४५६७८९०]/g, function (match) {\n            return numberMap$9[match];\n        });\n    },\n    postformat: function (string) {\n        return string.replace(/\\d/g, function (match) {\n            return symbolMap$10[match];\n        });\n    },\n    meridiemParse: /राति|बिहान|दिउँसो|साँझ/,\n    meridiemHour : function (hour, meridiem) {\n        if (hour === 12) {\n            hour = 0;\n        }\n        if (meridiem === 'राति') {\n            return hour < 4 ? hour : hour + 12;\n        } else if (meridiem === 'बिहान') {\n            return hour;\n        } else if (meridiem === 'दिउँसो') {\n            return hour >= 10 ? hour : hour + 12;\n        } else if (meridiem === 'साँझ') {\n            return hour + 12;\n        }\n    },\n    meridiem : function (hour, minute, isLower) {\n        if (hour < 3) {\n            return 'राति';\n        } else if (hour < 12) {\n            return 'बिहान';\n        } else if (hour < 16) {\n            return 'दिउँसो';\n        } else if (hour < 20) {\n            return 'साँझ';\n        } else {\n            return 'राति';\n        }\n    },\n    calendar : {\n        sameDay : '[आज] LT',\n        nextDay : '[भोलि] LT',\n        nextWeek : '[आउँदो] dddd[,] LT',\n        lastDay : '[हिजो] LT',\n        lastWeek : '[गएको] dddd[,] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : '%sमा',\n        past : '%s अगाडि',\n        s : 'केही क्षण',\n        m : 'एक मिनेट',\n        mm : '%d मिनेट',\n        h : 'एक घण्टा',\n        hh : '%d घण्टा',\n        d : 'एक दिन',\n        dd : '%d दिन',\n        M : 'एक महिना',\n        MM : '%d महिना',\n        y : 'एक बर्ष',\n        yy : '%d बर्ष'\n    },\n    week : {\n        dow : 0, // Sunday is the first day of the week.\n        doy : 6  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Dutch (Belgium) [nl-be]\n//! author : Joris Röling : https://github.com/jorisroling\n//! author : Jacob Middag : https://github.com/middagj\n\nvar monthsShortWithDots$1 = 'jan._feb._mrt._apr._mei_jun._jul._aug._sep._okt._nov._dec.'.split('_');\nvar monthsShortWithoutDots$1 = 'jan_feb_mrt_apr_mei_jun_jul_aug_sep_okt_nov_dec'.split('_');\n\nvar monthsParse = [/^jan/i, /^feb/i, /^maart|mrt.?$/i, /^apr/i, /^mei$/i, /^jun[i.]?$/i, /^jul[i.]?$/i, /^aug/i, /^sep/i, /^okt/i, /^nov/i, /^dec/i];\nvar monthsRegex = /^(januari|februari|maart|april|mei|april|ju[nl]i|augustus|september|oktober|november|december|jan\\.?|feb\\.?|mrt\\.?|apr\\.?|ju[nl]\\.?|aug\\.?|sep\\.?|okt\\.?|nov\\.?|dec\\.?)/i;\n\nmoment.defineLocale('nl-be', {\n    months : 'januari_februari_maart_april_mei_juni_juli_augustus_september_oktober_november_december'.split('_'),\n    monthsShort : function (m, format) {\n        if (!m) {\n            return monthsShortWithDots$1;\n        } else if (/-MMM-/.test(format)) {\n            return monthsShortWithoutDots$1[m.month()];\n        } else {\n            return monthsShortWithDots$1[m.month()];\n        }\n    },\n\n    monthsRegex: monthsRegex,\n    monthsShortRegex: monthsRegex,\n    monthsStrictRegex: /^(januari|februari|maart|mei|ju[nl]i|april|augustus|september|oktober|november|december)/i,\n    monthsShortStrictRegex: /^(jan\\.?|feb\\.?|mrt\\.?|apr\\.?|mei|ju[nl]\\.?|aug\\.?|sep\\.?|okt\\.?|nov\\.?|dec\\.?)/i,\n\n    monthsParse : monthsParse,\n    longMonthsParse : monthsParse,\n    shortMonthsParse : monthsParse,\n\n    weekdays : 'zondag_maandag_dinsdag_woensdag_donderdag_vrijdag_zaterdag'.split('_'),\n    weekdaysShort : 'zo._ma._di._wo._do._vr._za.'.split('_'),\n    weekdaysMin : 'Zo_Ma_Di_Wo_Do_Vr_Za'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY HH:mm',\n        LLLL : 'dddd D MMMM YYYY HH:mm'\n    },\n    calendar : {\n        sameDay: '[vandaag om] LT',\n        nextDay: '[morgen om] LT',\n        nextWeek: 'dddd [om] LT',\n        lastDay: '[gisteren om] LT',\n        lastWeek: '[afgelopen] dddd [om] LT',\n        sameElse: 'L'\n    },\n    relativeTime : {\n        future : 'over %s',\n        past : '%s geleden',\n        s : 'een paar seconden',\n        m : 'één minuut',\n        mm : '%d minuten',\n        h : 'één uur',\n        hh : '%d uur',\n        d : 'één dag',\n        dd : '%d dagen',\n        M : 'één maand',\n        MM : '%d maanden',\n        y : 'één jaar',\n        yy : '%d jaar'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}(ste|de)/,\n    ordinal : function (number) {\n        return number + ((number === 1 || number === 8 || number >= 20) ? 'ste' : 'de');\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Dutch [nl]\n//! author : Joris Röling : https://github.com/jorisroling\n//! author : Jacob Middag : https://github.com/middagj\n\nvar monthsShortWithDots$2 = 'jan._feb._mrt._apr._mei_jun._jul._aug._sep._okt._nov._dec.'.split('_');\nvar monthsShortWithoutDots$2 = 'jan_feb_mrt_apr_mei_jun_jul_aug_sep_okt_nov_dec'.split('_');\n\nvar monthsParse$1 = [/^jan/i, /^feb/i, /^maart|mrt.?$/i, /^apr/i, /^mei$/i, /^jun[i.]?$/i, /^jul[i.]?$/i, /^aug/i, /^sep/i, /^okt/i, /^nov/i, /^dec/i];\nvar monthsRegex$1 = /^(januari|februari|maart|april|mei|april|ju[nl]i|augustus|september|oktober|november|december|jan\\.?|feb\\.?|mrt\\.?|apr\\.?|ju[nl]\\.?|aug\\.?|sep\\.?|okt\\.?|nov\\.?|dec\\.?)/i;\n\nmoment.defineLocale('nl', {\n    months : 'januari_februari_maart_april_mei_juni_juli_augustus_september_oktober_november_december'.split('_'),\n    monthsShort : function (m, format) {\n        if (!m) {\n            return monthsShortWithDots$2;\n        } else if (/-MMM-/.test(format)) {\n            return monthsShortWithoutDots$2[m.month()];\n        } else {\n            return monthsShortWithDots$2[m.month()];\n        }\n    },\n\n    monthsRegex: monthsRegex$1,\n    monthsShortRegex: monthsRegex$1,\n    monthsStrictRegex: /^(januari|februari|maart|mei|ju[nl]i|april|augustus|september|oktober|november|december)/i,\n    monthsShortStrictRegex: /^(jan\\.?|feb\\.?|mrt\\.?|apr\\.?|mei|ju[nl]\\.?|aug\\.?|sep\\.?|okt\\.?|nov\\.?|dec\\.?)/i,\n\n    monthsParse : monthsParse$1,\n    longMonthsParse : monthsParse$1,\n    shortMonthsParse : monthsParse$1,\n\n    weekdays : 'zondag_maandag_dinsdag_woensdag_donderdag_vrijdag_zaterdag'.split('_'),\n    weekdaysShort : 'zo._ma._di._wo._do._vr._za.'.split('_'),\n    weekdaysMin : 'Zo_Ma_Di_Wo_Do_Vr_Za'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD-MM-YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY HH:mm',\n        LLLL : 'dddd D MMMM YYYY HH:mm'\n    },\n    calendar : {\n        sameDay: '[vandaag om] LT',\n        nextDay: '[morgen om] LT',\n        nextWeek: 'dddd [om] LT',\n        lastDay: '[gisteren om] LT',\n        lastWeek: '[afgelopen] dddd [om] LT',\n        sameElse: 'L'\n    },\n    relativeTime : {\n        future : 'over %s',\n        past : '%s geleden',\n        s : 'een paar seconden',\n        m : 'één minuut',\n        mm : '%d minuten',\n        h : 'één uur',\n        hh : '%d uur',\n        d : 'één dag',\n        dd : '%d dagen',\n        M : 'één maand',\n        MM : '%d maanden',\n        y : 'één jaar',\n        yy : '%d jaar'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}(ste|de)/,\n    ordinal : function (number) {\n        return number + ((number === 1 || number === 8 || number >= 20) ? 'ste' : 'de');\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Nynorsk [nn]\n//! author : https://github.com/mechuwind\n\nmoment.defineLocale('nn', {\n    months : 'januar_februar_mars_april_mai_juni_juli_august_september_oktober_november_desember'.split('_'),\n    monthsShort : 'jan_feb_mar_apr_mai_jun_jul_aug_sep_okt_nov_des'.split('_'),\n    weekdays : 'sundag_måndag_tysdag_onsdag_torsdag_fredag_laurdag'.split('_'),\n    weekdaysShort : 'sun_mån_tys_ons_tor_fre_lau'.split('_'),\n    weekdaysMin : 'su_må_ty_on_to_fr_lø'.split('_'),\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD.MM.YYYY',\n        LL : 'D. MMMM YYYY',\n        LLL : 'D. MMMM YYYY [kl.] H:mm',\n        LLLL : 'dddd D. MMMM YYYY [kl.] HH:mm'\n    },\n    calendar : {\n        sameDay: '[I dag klokka] LT',\n        nextDay: '[I morgon klokka] LT',\n        nextWeek: 'dddd [klokka] LT',\n        lastDay: '[I går klokka] LT',\n        lastWeek: '[Føregåande] dddd [klokka] LT',\n        sameElse: 'L'\n    },\n    relativeTime : {\n        future : 'om %s',\n        past : '%s sidan',\n        s : 'nokre sekund',\n        m : 'eit minutt',\n        mm : '%d minutt',\n        h : 'ein time',\n        hh : '%d timar',\n        d : 'ein dag',\n        dd : '%d dagar',\n        M : 'ein månad',\n        MM : '%d månader',\n        y : 'eit år',\n        yy : '%d år'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}\\./,\n    ordinal : '%d.',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Punjabi (India) [pa-in]\n//! author : Harpreet Singh : https://github.com/harpreetkhalsagtbit\n\nvar symbolMap$11 = {\n    '1': '੧',\n    '2': '੨',\n    '3': '੩',\n    '4': '੪',\n    '5': '੫',\n    '6': '੬',\n    '7': '੭',\n    '8': '੮',\n    '9': '੯',\n    '0': '੦'\n};\nvar numberMap$10 = {\n    '੧': '1',\n    '੨': '2',\n    '੩': '3',\n    '੪': '4',\n    '੫': '5',\n    '੬': '6',\n    '੭': '7',\n    '੮': '8',\n    '੯': '9',\n    '੦': '0'\n};\n\nmoment.defineLocale('pa-in', {\n    // There are months name as per Nanakshahi Calender but they are not used as rigidly in modern Punjabi.\n    months : 'ਜਨਵਰੀ_ਫ਼ਰਵਰੀ_ਮਾਰਚ_ਅਪ੍ਰੈਲ_ਮਈ_ਜੂਨ_ਜੁਲਾਈ_ਅਗਸਤ_ਸਤੰਬਰ_ਅਕਤੂਬਰ_ਨਵੰਬਰ_ਦਸੰਬਰ'.split('_'),\n    monthsShort : 'ਜਨਵਰੀ_ਫ਼ਰਵਰੀ_ਮਾਰਚ_ਅਪ੍ਰੈਲ_ਮਈ_ਜੂਨ_ਜੁਲਾਈ_ਅਗਸਤ_ਸਤੰਬਰ_ਅਕਤੂਬਰ_ਨਵੰਬਰ_ਦਸੰਬਰ'.split('_'),\n    weekdays : 'ਐਤਵਾਰ_ਸੋਮਵਾਰ_ਮੰਗਲਵਾਰ_ਬੁਧਵਾਰ_ਵੀਰਵਾਰ_ਸ਼ੁੱਕਰਵਾਰ_ਸ਼ਨੀਚਰਵਾਰ'.split('_'),\n    weekdaysShort : 'ਐਤ_ਸੋਮ_ਮੰਗਲ_ਬੁਧ_ਵੀਰ_ਸ਼ੁਕਰ_ਸ਼ਨੀ'.split('_'),\n    weekdaysMin : 'ਐਤ_ਸੋਮ_ਮੰਗਲ_ਬੁਧ_ਵੀਰ_ਸ਼ੁਕਰ_ਸ਼ਨੀ'.split('_'),\n    longDateFormat : {\n        LT : 'A h:mm ਵਜੇ',\n        LTS : 'A h:mm:ss ਵਜੇ',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY, A h:mm ਵਜੇ',\n        LLLL : 'dddd, D MMMM YYYY, A h:mm ਵਜੇ'\n    },\n    calendar : {\n        sameDay : '[ਅਜ] LT',\n        nextDay : '[ਕਲ] LT',\n        nextWeek : 'dddd, LT',\n        lastDay : '[ਕਲ] LT',\n        lastWeek : '[ਪਿਛਲੇ] dddd, LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : '%s ਵਿੱਚ',\n        past : '%s ਪਿਛਲੇ',\n        s : 'ਕੁਝ ਸਕਿੰਟ',\n        m : 'ਇਕ ਮਿੰਟ',\n        mm : '%d ਮਿੰਟ',\n        h : 'ਇੱਕ ਘੰਟਾ',\n        hh : '%d ਘੰਟੇ',\n        d : 'ਇੱਕ ਦਿਨ',\n        dd : '%d ਦਿਨ',\n        M : 'ਇੱਕ ਮਹੀਨਾ',\n        MM : '%d ਮਹੀਨੇ',\n        y : 'ਇੱਕ ਸਾਲ',\n        yy : '%d ਸਾਲ'\n    },\n    preparse: function (string) {\n        return string.replace(/[੧੨੩੪੫੬੭੮੯੦]/g, function (match) {\n            return numberMap$10[match];\n        });\n    },\n    postformat: function (string) {\n        return string.replace(/\\d/g, function (match) {\n            return symbolMap$11[match];\n        });\n    },\n    // Punjabi notation for meridiems are quite fuzzy in practice. While there exists\n    // a rigid notion of a 'Pahar' it is not used as rigidly in modern Punjabi.\n    meridiemParse: /ਰਾਤ|ਸਵੇਰ|ਦੁਪਹਿਰ|ਸ਼ਾਮ/,\n    meridiemHour : function (hour, meridiem) {\n        if (hour === 12) {\n            hour = 0;\n        }\n        if (meridiem === 'ਰਾਤ') {\n            return hour < 4 ? hour : hour + 12;\n        } else if (meridiem === 'ਸਵੇਰ') {\n            return hour;\n        } else if (meridiem === 'ਦੁਪਹਿਰ') {\n            return hour >= 10 ? hour : hour + 12;\n        } else if (meridiem === 'ਸ਼ਾਮ') {\n            return hour + 12;\n        }\n    },\n    meridiem : function (hour, minute, isLower) {\n        if (hour < 4) {\n            return 'ਰਾਤ';\n        } else if (hour < 10) {\n            return 'ਸਵੇਰ';\n        } else if (hour < 17) {\n            return 'ਦੁਪਹਿਰ';\n        } else if (hour < 20) {\n            return 'ਸ਼ਾਮ';\n        } else {\n            return 'ਰਾਤ';\n        }\n    },\n    week : {\n        dow : 0, // Sunday is the first day of the week.\n        doy : 6  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Polish [pl]\n//! author : Rafal Hirsz : https://github.com/evoL\n\nvar monthsNominative = 'styczeń_luty_marzec_kwiecień_maj_czerwiec_lipiec_sierpień_wrzesień_październik_listopad_grudzień'.split('_');\nvar monthsSubjective = 'stycznia_lutego_marca_kwietnia_maja_czerwca_lipca_sierpnia_września_października_listopada_grudnia'.split('_');\nfunction plural$3(n) {\n    return (n % 10 < 5) && (n % 10 > 1) && ((~~(n / 10) % 10) !== 1);\n}\nfunction translate$7(number, withoutSuffix, key) {\n    var result = number + ' ';\n    switch (key) {\n        case 'm':\n            return withoutSuffix ? 'minuta' : 'minutę';\n        case 'mm':\n            return result + (plural$3(number) ? 'minuty' : 'minut');\n        case 'h':\n            return withoutSuffix  ? 'godzina'  : 'godzinę';\n        case 'hh':\n            return result + (plural$3(number) ? 'godziny' : 'godzin');\n        case 'MM':\n            return result + (plural$3(number) ? 'miesiące' : 'miesięcy');\n        case 'yy':\n            return result + (plural$3(number) ? 'lata' : 'lat');\n    }\n}\n\nmoment.defineLocale('pl', {\n    months : function (momentToFormat, format) {\n        if (!momentToFormat) {\n            return monthsNominative;\n        } else if (format === '') {\n            // Hack: if format empty we know this is used to generate\n            // RegExp by moment. Give then back both valid forms of months\n            // in RegExp ready format.\n            return '(' + monthsSubjective[momentToFormat.month()] + '|' + monthsNominative[momentToFormat.month()] + ')';\n        } else if (/D MMMM/.test(format)) {\n            return monthsSubjective[momentToFormat.month()];\n        } else {\n            return monthsNominative[momentToFormat.month()];\n        }\n    },\n    monthsShort : 'sty_lut_mar_kwi_maj_cze_lip_sie_wrz_paź_lis_gru'.split('_'),\n    weekdays : 'niedziela_poniedziałek_wtorek_środa_czwartek_piątek_sobota'.split('_'),\n    weekdaysShort : 'ndz_pon_wt_śr_czw_pt_sob'.split('_'),\n    weekdaysMin : 'Nd_Pn_Wt_Śr_Cz_Pt_So'.split('_'),\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD.MM.YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY HH:mm',\n        LLLL : 'dddd, D MMMM YYYY HH:mm'\n    },\n    calendar : {\n        sameDay: '[Dziś o] LT',\n        nextDay: '[Jutro o] LT',\n        nextWeek: '[W] dddd [o] LT',\n        lastDay: '[Wczoraj o] LT',\n        lastWeek: function () {\n            switch (this.day()) {\n                case 0:\n                    return '[W zeszłą niedzielę o] LT';\n                case 3:\n                    return '[W zeszłą środę o] LT';\n                case 6:\n                    return '[W zeszłą sobotę o] LT';\n                default:\n                    return '[W zeszły] dddd [o] LT';\n            }\n        },\n        sameElse: 'L'\n    },\n    relativeTime : {\n        future : 'za %s',\n        past : '%s temu',\n        s : 'kilka sekund',\n        m : translate$7,\n        mm : translate$7,\n        h : translate$7,\n        hh : translate$7,\n        d : '1 dzień',\n        dd : '%d dni',\n        M : 'miesiąc',\n        MM : translate$7,\n        y : 'rok',\n        yy : translate$7\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}\\./,\n    ordinal : '%d.',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Portuguese (Brazil) [pt-br]\n//! author : Caio Ribeiro Pereira : https://github.com/caio-ribeiro-pereira\n\nmoment.defineLocale('pt-br', {\n    months : 'Janeiro_Fevereiro_Março_Abril_Maio_Junho_Julho_Agosto_Setembro_Outubro_Novembro_Dezembro'.split('_'),\n    monthsShort : 'Jan_Fev_Mar_Abr_Mai_Jun_Jul_Ago_Set_Out_Nov_Dez'.split('_'),\n    weekdays : 'Domingo_Segunda-feira_Terça-feira_Quarta-feira_Quinta-feira_Sexta-feira_Sábado'.split('_'),\n    weekdaysShort : 'Dom_Seg_Ter_Qua_Qui_Sex_Sáb'.split('_'),\n    weekdaysMin : 'Do_2ª_3ª_4ª_5ª_6ª_Sá'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D [de] MMMM [de] YYYY',\n        LLL : 'D [de] MMMM [de] YYYY [às] HH:mm',\n        LLLL : 'dddd, D [de] MMMM [de] YYYY [às] HH:mm'\n    },\n    calendar : {\n        sameDay: '[Hoje às] LT',\n        nextDay: '[Amanhã às] LT',\n        nextWeek: 'dddd [às] LT',\n        lastDay: '[Ontem às] LT',\n        lastWeek: function () {\n            return (this.day() === 0 || this.day() === 6) ?\n                '[Último] dddd [às] LT' : // Saturday + Sunday\n                '[Última] dddd [às] LT'; // Monday - Friday\n        },\n        sameElse: 'L'\n    },\n    relativeTime : {\n        future : 'em %s',\n        past : '%s atrás',\n        s : 'poucos segundos',\n        m : 'um minuto',\n        mm : '%d minutos',\n        h : 'uma hora',\n        hh : '%d horas',\n        d : 'um dia',\n        dd : '%d dias',\n        M : 'um mês',\n        MM : '%d meses',\n        y : 'um ano',\n        yy : '%d anos'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}º/,\n    ordinal : '%dº'\n});\n\n//! moment.js locale configuration\n//! locale : Portuguese [pt]\n//! author : Jefferson : https://github.com/jalex79\n\nmoment.defineLocale('pt', {\n    months : 'Janeiro_Fevereiro_Março_Abril_Maio_Junho_Julho_Agosto_Setembro_Outubro_Novembro_Dezembro'.split('_'),\n    monthsShort : 'Jan_Fev_Mar_Abr_Mai_Jun_Jul_Ago_Set_Out_Nov_Dez'.split('_'),\n    weekdays : 'Domingo_Segunda-Feira_Terça-Feira_Quarta-Feira_Quinta-Feira_Sexta-Feira_Sábado'.split('_'),\n    weekdaysShort : 'Dom_Seg_Ter_Qua_Qui_Sex_Sáb'.split('_'),\n    weekdaysMin : 'Do_2ª_3ª_4ª_5ª_6ª_Sá'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D [de] MMMM [de] YYYY',\n        LLL : 'D [de] MMMM [de] YYYY HH:mm',\n        LLLL : 'dddd, D [de] MMMM [de] YYYY HH:mm'\n    },\n    calendar : {\n        sameDay: '[Hoje às] LT',\n        nextDay: '[Amanhã às] LT',\n        nextWeek: 'dddd [às] LT',\n        lastDay: '[Ontem às] LT',\n        lastWeek: function () {\n            return (this.day() === 0 || this.day() === 6) ?\n                '[Último] dddd [às] LT' : // Saturday + Sunday\n                '[Última] dddd [às] LT'; // Monday - Friday\n        },\n        sameElse: 'L'\n    },\n    relativeTime : {\n        future : 'em %s',\n        past : 'há %s',\n        s : 'segundos',\n        m : 'um minuto',\n        mm : '%d minutos',\n        h : 'uma hora',\n        hh : '%d horas',\n        d : 'um dia',\n        dd : '%d dias',\n        M : 'um mês',\n        MM : '%d meses',\n        y : 'um ano',\n        yy : '%d anos'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}º/,\n    ordinal : '%dº',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Romanian [ro]\n//! author : Vlad Gurdiga : https://github.com/gurdiga\n//! author : Valentin Agachi : https://github.com/avaly\n\nfunction relativeTimeWithPlural$2(number, withoutSuffix, key) {\n    var format = {\n            'mm': 'minute',\n            'hh': 'ore',\n            'dd': 'zile',\n            'MM': 'luni',\n            'yy': 'ani'\n        },\n        separator = ' ';\n    if (number % 100 >= 20 || (number >= 100 && number % 100 === 0)) {\n        separator = ' de ';\n    }\n    return number + separator + format[key];\n}\n\nmoment.defineLocale('ro', {\n    months : 'ianuarie_februarie_martie_aprilie_mai_iunie_iulie_august_septembrie_octombrie_noiembrie_decembrie'.split('_'),\n    monthsShort : 'ian._febr._mart._apr._mai_iun._iul._aug._sept._oct._nov._dec.'.split('_'),\n    monthsParseExact: true,\n    weekdays : 'duminică_luni_marți_miercuri_joi_vineri_sâmbătă'.split('_'),\n    weekdaysShort : 'Dum_Lun_Mar_Mie_Joi_Vin_Sâm'.split('_'),\n    weekdaysMin : 'Du_Lu_Ma_Mi_Jo_Vi_Sâ'.split('_'),\n    longDateFormat : {\n        LT : 'H:mm',\n        LTS : 'H:mm:ss',\n        L : 'DD.MM.YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY H:mm',\n        LLLL : 'dddd, D MMMM YYYY H:mm'\n    },\n    calendar : {\n        sameDay: '[azi la] LT',\n        nextDay: '[mâine la] LT',\n        nextWeek: 'dddd [la] LT',\n        lastDay: '[ieri la] LT',\n        lastWeek: '[fosta] dddd [la] LT',\n        sameElse: 'L'\n    },\n    relativeTime : {\n        future : 'peste %s',\n        past : '%s în urmă',\n        s : 'câteva secunde',\n        m : 'un minut',\n        mm : relativeTimeWithPlural$2,\n        h : 'o oră',\n        hh : relativeTimeWithPlural$2,\n        d : 'o zi',\n        dd : relativeTimeWithPlural$2,\n        M : 'o lună',\n        MM : relativeTimeWithPlural$2,\n        y : 'un an',\n        yy : relativeTimeWithPlural$2\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 7  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Russian [ru]\n//! author : Viktorminator : https://github.com/Viktorminator\n//! Author : Menelion Elensúle : https://github.com/Oire\n//! author : Коренберг Марк : https://github.com/socketpair\n\nfunction plural$4(word, num) {\n    var forms = word.split('_');\n    return num % 10 === 1 && num % 100 !== 11 ? forms[0] : (num % 10 >= 2 && num % 10 <= 4 && (num % 100 < 10 || num % 100 >= 20) ? forms[1] : forms[2]);\n}\nfunction relativeTimeWithPlural$3(number, withoutSuffix, key) {\n    var format = {\n        'mm': withoutSuffix ? 'минута_минуты_минут' : 'минуту_минуты_минут',\n        'hh': 'час_часа_часов',\n        'dd': 'день_дня_дней',\n        'MM': 'месяц_месяца_месяцев',\n        'yy': 'год_года_лет'\n    };\n    if (key === 'm') {\n        return withoutSuffix ? 'минута' : 'минуту';\n    }\n    else {\n        return number + ' ' + plural$4(format[key], +number);\n    }\n}\nvar monthsParse$2 = [/^янв/i, /^фев/i, /^мар/i, /^апр/i, /^ма[йя]/i, /^июн/i, /^июл/i, /^авг/i, /^сен/i, /^окт/i, /^ноя/i, /^дек/i];\n\n// http://new.gramota.ru/spravka/rules/139-prop : § 103\n// Сокращения месяцев: http://new.gramota.ru/spravka/buro/search-answer?s=242637\n// CLDR data:          http://www.unicode.org/cldr/charts/28/summary/ru.html#1753\nmoment.defineLocale('ru', {\n    months : {\n        format: 'января_февраля_марта_апреля_мая_июня_июля_августа_сентября_октября_ноября_декабря'.split('_'),\n        standalone: 'январь_февраль_март_апрель_май_июнь_июль_август_сентябрь_октябрь_ноябрь_декабрь'.split('_')\n    },\n    monthsShort : {\n        // по CLDR именно \"июл.\" и \"июн.\", но какой смысл менять букву на точку ?\n        format: 'янв._февр._мар._апр._мая_июня_июля_авг._сент._окт._нояб._дек.'.split('_'),\n        standalone: 'янв._февр._март_апр._май_июнь_июль_авг._сент._окт._нояб._дек.'.split('_')\n    },\n    weekdays : {\n        standalone: 'воскресенье_понедельник_вторник_среда_четверг_пятница_суббота'.split('_'),\n        format: 'воскресенье_понедельник_вторник_среду_четверг_пятницу_субботу'.split('_'),\n        isFormat: /\\[ ?[Вв] ?(?:прошлую|следующую|эту)? ?\\] ?dddd/\n    },\n    weekdaysShort : 'вс_пн_вт_ср_чт_пт_сб'.split('_'),\n    weekdaysMin : 'вс_пн_вт_ср_чт_пт_сб'.split('_'),\n    monthsParse : monthsParse$2,\n    longMonthsParse : monthsParse$2,\n    shortMonthsParse : monthsParse$2,\n\n    // полные названия с падежами, по три буквы, для некоторых, по 4 буквы, сокращения с точкой и без точки\n    monthsRegex: /^(январ[ья]|янв\\.?|феврал[ья]|февр?\\.?|марта?|мар\\.?|апрел[ья]|апр\\.?|ма[йя]|июн[ья]|июн\\.?|июл[ья]|июл\\.?|августа?|авг\\.?|сентябр[ья]|сент?\\.?|октябр[ья]|окт\\.?|ноябр[ья]|нояб?\\.?|декабр[ья]|дек\\.?)/i,\n\n    // копия предыдущего\n    monthsShortRegex: /^(январ[ья]|янв\\.?|феврал[ья]|февр?\\.?|марта?|мар\\.?|апрел[ья]|апр\\.?|ма[йя]|июн[ья]|июн\\.?|июл[ья]|июл\\.?|августа?|авг\\.?|сентябр[ья]|сент?\\.?|октябр[ья]|окт\\.?|ноябр[ья]|нояб?\\.?|декабр[ья]|дек\\.?)/i,\n\n    // полные названия с падежами\n    monthsStrictRegex: /^(январ[яь]|феврал[яь]|марта?|апрел[яь]|ма[яй]|июн[яь]|июл[яь]|августа?|сентябр[яь]|октябр[яь]|ноябр[яь]|декабр[яь])/i,\n\n    // Выражение, которое соотвествует только сокращённым формам\n    monthsShortStrictRegex: /^(янв\\.|февр?\\.|мар[т.]|апр\\.|ма[яй]|июн[ья.]|июл[ья.]|авг\\.|сент?\\.|окт\\.|нояб?\\.|дек\\.)/i,\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD.MM.YYYY',\n        LL : 'D MMMM YYYY г.',\n        LLL : 'D MMMM YYYY г., HH:mm',\n        LLLL : 'dddd, D MMMM YYYY г., HH:mm'\n    },\n    calendar : {\n        sameDay: '[Сегодня в] LT',\n        nextDay: '[Завтра в] LT',\n        lastDay: '[Вчера в] LT',\n        nextWeek: function (now) {\n            if (now.week() !== this.week()) {\n                switch (this.day()) {\n                    case 0:\n                        return '[В следующее] dddd [в] LT';\n                    case 1:\n                    case 2:\n                    case 4:\n                        return '[В следующий] dddd [в] LT';\n                    case 3:\n                    case 5:\n                    case 6:\n                        return '[В следующую] dddd [в] LT';\n                }\n            } else {\n                if (this.day() === 2) {\n                    return '[Во] dddd [в] LT';\n                } else {\n                    return '[В] dddd [в] LT';\n                }\n            }\n        },\n        lastWeek: function (now) {\n            if (now.week() !== this.week()) {\n                switch (this.day()) {\n                    case 0:\n                        return '[В прошлое] dddd [в] LT';\n                    case 1:\n                    case 2:\n                    case 4:\n                        return '[В прошлый] dddd [в] LT';\n                    case 3:\n                    case 5:\n                    case 6:\n                        return '[В прошлую] dddd [в] LT';\n                }\n            } else {\n                if (this.day() === 2) {\n                    return '[Во] dddd [в] LT';\n                } else {\n                    return '[В] dddd [в] LT';\n                }\n            }\n        },\n        sameElse: 'L'\n    },\n    relativeTime : {\n        future : 'через %s',\n        past : '%s назад',\n        s : 'несколько секунд',\n        m : relativeTimeWithPlural$3,\n        mm : relativeTimeWithPlural$3,\n        h : 'час',\n        hh : relativeTimeWithPlural$3,\n        d : 'день',\n        dd : relativeTimeWithPlural$3,\n        M : 'месяц',\n        MM : relativeTimeWithPlural$3,\n        y : 'год',\n        yy : relativeTimeWithPlural$3\n    },\n    meridiemParse: /ночи|утра|дня|вечера/i,\n    isPM : function (input) {\n        return /^(дня|вечера)$/.test(input);\n    },\n    meridiem : function (hour, minute, isLower) {\n        if (hour < 4) {\n            return 'ночи';\n        } else if (hour < 12) {\n            return 'утра';\n        } else if (hour < 17) {\n            return 'дня';\n        } else {\n            return 'вечера';\n        }\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}-(й|го|я)/,\n    ordinal: function (number, period) {\n        switch (period) {\n            case 'M':\n            case 'd':\n            case 'DDD':\n                return number + '-й';\n            case 'D':\n                return number + '-го';\n            case 'w':\n            case 'W':\n                return number + '-я';\n            default:\n                return number;\n        }\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 7  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Sindhi [sd]\n//! author : Narain Sagar : https://github.com/narainsagar\n\nvar months$5 = [\n    'جنوري',\n    'فيبروري',\n    'مارچ',\n    'اپريل',\n    'مئي',\n    'جون',\n    'جولاءِ',\n    'آگسٽ',\n    'سيپٽمبر',\n    'آڪٽوبر',\n    'نومبر',\n    'ڊسمبر'\n];\nvar days = [\n    'آچر',\n    'سومر',\n    'اڱارو',\n    'اربع',\n    'خميس',\n    'جمع',\n    'ڇنڇر'\n];\n\nmoment.defineLocale('sd', {\n    months : months$5,\n    monthsShort : months$5,\n    weekdays : days,\n    weekdaysShort : days,\n    weekdaysMin : days,\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY HH:mm',\n        LLLL : 'dddd، D MMMM YYYY HH:mm'\n    },\n    meridiemParse: /صبح|شام/,\n    isPM : function (input) {\n        return 'شام' === input;\n    },\n    meridiem : function (hour, minute, isLower) {\n        if (hour < 12) {\n            return 'صبح';\n        }\n        return 'شام';\n    },\n    calendar : {\n        sameDay : '[اڄ] LT',\n        nextDay : '[سڀاڻي] LT',\n        nextWeek : 'dddd [اڳين هفتي تي] LT',\n        lastDay : '[ڪالهه] LT',\n        lastWeek : '[گزريل هفتي] dddd [تي] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : '%s پوء',\n        past : '%s اڳ',\n        s : 'چند سيڪنڊ',\n        m : 'هڪ منٽ',\n        mm : '%d منٽ',\n        h : 'هڪ ڪلاڪ',\n        hh : '%d ڪلاڪ',\n        d : 'هڪ ڏينهن',\n        dd : '%d ڏينهن',\n        M : 'هڪ مهينو',\n        MM : '%d مهينا',\n        y : 'هڪ سال',\n        yy : '%d سال'\n    },\n    preparse: function (string) {\n        return string.replace(/،/g, ',');\n    },\n    postformat: function (string) {\n        return string.replace(/,/g, '،');\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Northern Sami [se]\n//! authors : Bård Rolstad Henriksen : https://github.com/karamell\n\n\nmoment.defineLocale('se', {\n    months : 'ođđajagemánnu_guovvamánnu_njukčamánnu_cuoŋománnu_miessemánnu_geassemánnu_suoidnemánnu_borgemánnu_čakčamánnu_golggotmánnu_skábmamánnu_juovlamánnu'.split('_'),\n    monthsShort : 'ođđj_guov_njuk_cuo_mies_geas_suoi_borg_čakč_golg_skáb_juov'.split('_'),\n    weekdays : 'sotnabeaivi_vuossárga_maŋŋebárga_gaskavahkku_duorastat_bearjadat_lávvardat'.split('_'),\n    weekdaysShort : 'sotn_vuos_maŋ_gask_duor_bear_láv'.split('_'),\n    weekdaysMin : 's_v_m_g_d_b_L'.split('_'),\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD.MM.YYYY',\n        LL : 'MMMM D. [b.] YYYY',\n        LLL : 'MMMM D. [b.] YYYY [ti.] HH:mm',\n        LLLL : 'dddd, MMMM D. [b.] YYYY [ti.] HH:mm'\n    },\n    calendar : {\n        sameDay: '[otne ti] LT',\n        nextDay: '[ihttin ti] LT',\n        nextWeek: 'dddd [ti] LT',\n        lastDay: '[ikte ti] LT',\n        lastWeek: '[ovddit] dddd [ti] LT',\n        sameElse: 'L'\n    },\n    relativeTime : {\n        future : '%s geažes',\n        past : 'maŋit %s',\n        s : 'moadde sekunddat',\n        m : 'okta minuhta',\n        mm : '%d minuhtat',\n        h : 'okta diimmu',\n        hh : '%d diimmut',\n        d : 'okta beaivi',\n        dd : '%d beaivvit',\n        M : 'okta mánnu',\n        MM : '%d mánut',\n        y : 'okta jahki',\n        yy : '%d jagit'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}\\./,\n    ordinal : '%d.',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Sinhalese [si]\n//! author : Sampath Sitinamaluwa : https://github.com/sampathsris\n\n/*jshint -W100*/\nmoment.defineLocale('si', {\n    months : 'ජනවාරි_පෙබරවාරි_මාර්තු_අප්‍රේල්_මැයි_ජූනි_ජූලි_අගෝස්තු_සැප්තැම්බර්_ඔක්තෝබර්_නොවැම්බර්_දෙසැම්බර්'.split('_'),\n    monthsShort : 'ජන_පෙබ_මාර්_අප්_මැයි_ජූනි_ජූලි_අගෝ_සැප්_ඔක්_නොවැ_දෙසැ'.split('_'),\n    weekdays : 'ඉරිදා_සඳුදා_අඟහරුවාදා_බදාදා_බ්‍රහස්පතින්දා_සිකුරාදා_සෙනසුරාදා'.split('_'),\n    weekdaysShort : 'ඉරි_සඳු_අඟ_බදා_බ්‍රහ_සිකු_සෙන'.split('_'),\n    weekdaysMin : 'ඉ_ස_අ_බ_බ්‍ර_සි_සෙ'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat : {\n        LT : 'a h:mm',\n        LTS : 'a h:mm:ss',\n        L : 'YYYY/MM/DD',\n        LL : 'YYYY MMMM D',\n        LLL : 'YYYY MMMM D, a h:mm',\n        LLLL : 'YYYY MMMM D [වැනි] dddd, a h:mm:ss'\n    },\n    calendar : {\n        sameDay : '[අද] LT[ට]',\n        nextDay : '[හෙට] LT[ට]',\n        nextWeek : 'dddd LT[ට]',\n        lastDay : '[ඊයේ] LT[ට]',\n        lastWeek : '[පසුගිය] dddd LT[ට]',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : '%sකින්',\n        past : '%sකට පෙර',\n        s : 'තත්පර කිහිපය',\n        m : 'මිනිත්තුව',\n        mm : 'මිනිත්තු %d',\n        h : 'පැය',\n        hh : 'පැය %d',\n        d : 'දිනය',\n        dd : 'දින %d',\n        M : 'මාසය',\n        MM : 'මාස %d',\n        y : 'වසර',\n        yy : 'වසර %d'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2} වැනි/,\n    ordinal : function (number) {\n        return number + ' වැනි';\n    },\n    meridiemParse : /පෙර වරු|පස් වරු|පෙ.ව|ප.ව./,\n    isPM : function (input) {\n        return input === 'ප.ව.' || input === 'පස් වරු';\n    },\n    meridiem : function (hours, minutes, isLower) {\n        if (hours > 11) {\n            return isLower ? 'ප.ව.' : 'පස් වරු';\n        } else {\n            return isLower ? 'පෙ.ව.' : 'පෙර වරු';\n        }\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Slovak [sk]\n//! author : Martin Minka : https://github.com/k2s\n//! based on work of petrbela : https://github.com/petrbela\n\nvar months$6 = 'január_február_marec_apríl_máj_jún_júl_august_september_október_november_december'.split('_');\nvar monthsShort$4 = 'jan_feb_mar_apr_máj_jún_júl_aug_sep_okt_nov_dec'.split('_');\nfunction plural$5(n) {\n    return (n > 1) && (n < 5);\n}\nfunction translate$8(number, withoutSuffix, key, isFuture) {\n    var result = number + ' ';\n    switch (key) {\n        case 's':  // a few seconds / in a few seconds / a few seconds ago\n            return (withoutSuffix || isFuture) ? 'pár sekúnd' : 'pár sekundami';\n        case 'm':  // a minute / in a minute / a minute ago\n            return withoutSuffix ? 'minúta' : (isFuture ? 'minútu' : 'minútou');\n        case 'mm': // 9 minutes / in 9 minutes / 9 minutes ago\n            if (withoutSuffix || isFuture) {\n                return result + (plural$5(number) ? 'minúty' : 'minút');\n            } else {\n                return result + 'minútami';\n            }\n            break;\n        case 'h':  // an hour / in an hour / an hour ago\n            return withoutSuffix ? 'hodina' : (isFuture ? 'hodinu' : 'hodinou');\n        case 'hh': // 9 hours / in 9 hours / 9 hours ago\n            if (withoutSuffix || isFuture) {\n                return result + (plural$5(number) ? 'hodiny' : 'hodín');\n            } else {\n                return result + 'hodinami';\n            }\n            break;\n        case 'd':  // a day / in a day / a day ago\n            return (withoutSuffix || isFuture) ? 'deň' : 'dňom';\n        case 'dd': // 9 days / in 9 days / 9 days ago\n            if (withoutSuffix || isFuture) {\n                return result + (plural$5(number) ? 'dni' : 'dní');\n            } else {\n                return result + 'dňami';\n            }\n            break;\n        case 'M':  // a month / in a month / a month ago\n            return (withoutSuffix || isFuture) ? 'mesiac' : 'mesiacom';\n        case 'MM': // 9 months / in 9 months / 9 months ago\n            if (withoutSuffix || isFuture) {\n                return result + (plural$5(number) ? 'mesiace' : 'mesiacov');\n            } else {\n                return result + 'mesiacmi';\n            }\n            break;\n        case 'y':  // a year / in a year / a year ago\n            return (withoutSuffix || isFuture) ? 'rok' : 'rokom';\n        case 'yy': // 9 years / in 9 years / 9 years ago\n            if (withoutSuffix || isFuture) {\n                return result + (plural$5(number) ? 'roky' : 'rokov');\n            } else {\n                return result + 'rokmi';\n            }\n            break;\n    }\n}\n\nmoment.defineLocale('sk', {\n    months : months$6,\n    monthsShort : monthsShort$4,\n    weekdays : 'nedeľa_pondelok_utorok_streda_štvrtok_piatok_sobota'.split('_'),\n    weekdaysShort : 'ne_po_ut_st_št_pi_so'.split('_'),\n    weekdaysMin : 'ne_po_ut_st_št_pi_so'.split('_'),\n    longDateFormat : {\n        LT: 'H:mm',\n        LTS : 'H:mm:ss',\n        L : 'DD.MM.YYYY',\n        LL : 'D. MMMM YYYY',\n        LLL : 'D. MMMM YYYY H:mm',\n        LLLL : 'dddd D. MMMM YYYY H:mm'\n    },\n    calendar : {\n        sameDay: '[dnes o] LT',\n        nextDay: '[zajtra o] LT',\n        nextWeek: function () {\n            switch (this.day()) {\n                case 0:\n                    return '[v nedeľu o] LT';\n                case 1:\n                case 2:\n                    return '[v] dddd [o] LT';\n                case 3:\n                    return '[v stredu o] LT';\n                case 4:\n                    return '[vo štvrtok o] LT';\n                case 5:\n                    return '[v piatok o] LT';\n                case 6:\n                    return '[v sobotu o] LT';\n            }\n        },\n        lastDay: '[včera o] LT',\n        lastWeek: function () {\n            switch (this.day()) {\n                case 0:\n                    return '[minulú nedeľu o] LT';\n                case 1:\n                case 2:\n                    return '[minulý] dddd [o] LT';\n                case 3:\n                    return '[minulú stredu o] LT';\n                case 4:\n                case 5:\n                    return '[minulý] dddd [o] LT';\n                case 6:\n                    return '[minulú sobotu o] LT';\n            }\n        },\n        sameElse: 'L'\n    },\n    relativeTime : {\n        future : 'za %s',\n        past : 'pred %s',\n        s : translate$8,\n        m : translate$8,\n        mm : translate$8,\n        h : translate$8,\n        hh : translate$8,\n        d : translate$8,\n        dd : translate$8,\n        M : translate$8,\n        MM : translate$8,\n        y : translate$8,\n        yy : translate$8\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}\\./,\n    ordinal : '%d.',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Slovenian [sl]\n//! author : Robert Sedovšek : https://github.com/sedovsek\n\nfunction processRelativeTime$6(number, withoutSuffix, key, isFuture) {\n    var result = number + ' ';\n    switch (key) {\n        case 's':\n            return withoutSuffix || isFuture ? 'nekaj sekund' : 'nekaj sekundami';\n        case 'm':\n            return withoutSuffix ? 'ena minuta' : 'eno minuto';\n        case 'mm':\n            if (number === 1) {\n                result += withoutSuffix ? 'minuta' : 'minuto';\n            } else if (number === 2) {\n                result += withoutSuffix || isFuture ? 'minuti' : 'minutama';\n            } else if (number < 5) {\n                result += withoutSuffix || isFuture ? 'minute' : 'minutami';\n            } else {\n                result += withoutSuffix || isFuture ? 'minut' : 'minutami';\n            }\n            return result;\n        case 'h':\n            return withoutSuffix ? 'ena ura' : 'eno uro';\n        case 'hh':\n            if (number === 1) {\n                result += withoutSuffix ? 'ura' : 'uro';\n            } else if (number === 2) {\n                result += withoutSuffix || isFuture ? 'uri' : 'urama';\n            } else if (number < 5) {\n                result += withoutSuffix || isFuture ? 'ure' : 'urami';\n            } else {\n                result += withoutSuffix || isFuture ? 'ur' : 'urami';\n            }\n            return result;\n        case 'd':\n            return withoutSuffix || isFuture ? 'en dan' : 'enim dnem';\n        case 'dd':\n            if (number === 1) {\n                result += withoutSuffix || isFuture ? 'dan' : 'dnem';\n            } else if (number === 2) {\n                result += withoutSuffix || isFuture ? 'dni' : 'dnevoma';\n            } else {\n                result += withoutSuffix || isFuture ? 'dni' : 'dnevi';\n            }\n            return result;\n        case 'M':\n            return withoutSuffix || isFuture ? 'en mesec' : 'enim mesecem';\n        case 'MM':\n            if (number === 1) {\n                result += withoutSuffix || isFuture ? 'mesec' : 'mesecem';\n            } else if (number === 2) {\n                result += withoutSuffix || isFuture ? 'meseca' : 'mesecema';\n            } else if (number < 5) {\n                result += withoutSuffix || isFuture ? 'mesece' : 'meseci';\n            } else {\n                result += withoutSuffix || isFuture ? 'mesecev' : 'meseci';\n            }\n            return result;\n        case 'y':\n            return withoutSuffix || isFuture ? 'eno leto' : 'enim letom';\n        case 'yy':\n            if (number === 1) {\n                result += withoutSuffix || isFuture ? 'leto' : 'letom';\n            } else if (number === 2) {\n                result += withoutSuffix || isFuture ? 'leti' : 'letoma';\n            } else if (number < 5) {\n                result += withoutSuffix || isFuture ? 'leta' : 'leti';\n            } else {\n                result += withoutSuffix || isFuture ? 'let' : 'leti';\n            }\n            return result;\n    }\n}\n\nmoment.defineLocale('sl', {\n    months : 'januar_februar_marec_april_maj_junij_julij_avgust_september_oktober_november_december'.split('_'),\n    monthsShort : 'jan._feb._mar._apr._maj._jun._jul._avg._sep._okt._nov._dec.'.split('_'),\n    monthsParseExact: true,\n    weekdays : 'nedelja_ponedeljek_torek_sreda_četrtek_petek_sobota'.split('_'),\n    weekdaysShort : 'ned._pon._tor._sre._čet._pet._sob.'.split('_'),\n    weekdaysMin : 'ne_po_to_sr_če_pe_so'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat : {\n        LT : 'H:mm',\n        LTS : 'H:mm:ss',\n        L : 'DD.MM.YYYY',\n        LL : 'D. MMMM YYYY',\n        LLL : 'D. MMMM YYYY H:mm',\n        LLLL : 'dddd, D. MMMM YYYY H:mm'\n    },\n    calendar : {\n        sameDay  : '[danes ob] LT',\n        nextDay  : '[jutri ob] LT',\n\n        nextWeek : function () {\n            switch (this.day()) {\n                case 0:\n                    return '[v] [nedeljo] [ob] LT';\n                case 3:\n                    return '[v] [sredo] [ob] LT';\n                case 6:\n                    return '[v] [soboto] [ob] LT';\n                case 1:\n                case 2:\n                case 4:\n                case 5:\n                    return '[v] dddd [ob] LT';\n            }\n        },\n        lastDay  : '[včeraj ob] LT',\n        lastWeek : function () {\n            switch (this.day()) {\n                case 0:\n                    return '[prejšnjo] [nedeljo] [ob] LT';\n                case 3:\n                    return '[prejšnjo] [sredo] [ob] LT';\n                case 6:\n                    return '[prejšnjo] [soboto] [ob] LT';\n                case 1:\n                case 2:\n                case 4:\n                case 5:\n                    return '[prejšnji] dddd [ob] LT';\n            }\n        },\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'čez %s',\n        past   : 'pred %s',\n        s      : processRelativeTime$6,\n        m      : processRelativeTime$6,\n        mm     : processRelativeTime$6,\n        h      : processRelativeTime$6,\n        hh     : processRelativeTime$6,\n        d      : processRelativeTime$6,\n        dd     : processRelativeTime$6,\n        M      : processRelativeTime$6,\n        MM     : processRelativeTime$6,\n        y      : processRelativeTime$6,\n        yy     : processRelativeTime$6\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}\\./,\n    ordinal : '%d.',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 7  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Albanian [sq]\n//! author : Flakërim Ismani : https://github.com/flakerimi\n//! author : Menelion Elensúle : https://github.com/Oire\n//! author : Oerd Cukalla : https://github.com/oerd\n\nmoment.defineLocale('sq', {\n    months : 'Janar_Shkurt_Mars_Prill_Maj_Qershor_Korrik_Gusht_Shtator_Tetor_Nëntor_Dhjetor'.split('_'),\n    monthsShort : 'Jan_Shk_Mar_Pri_Maj_Qer_Kor_Gus_Sht_Tet_Nën_Dhj'.split('_'),\n    weekdays : 'E Diel_E Hënë_E Martë_E Mërkurë_E Enjte_E Premte_E Shtunë'.split('_'),\n    weekdaysShort : 'Die_Hën_Mar_Mër_Enj_Pre_Sht'.split('_'),\n    weekdaysMin : 'D_H_Ma_Më_E_P_Sh'.split('_'),\n    weekdaysParseExact : true,\n    meridiemParse: /PD|MD/,\n    isPM: function (input) {\n        return input.charAt(0) === 'M';\n    },\n    meridiem : function (hours, minutes, isLower) {\n        return hours < 12 ? 'PD' : 'MD';\n    },\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY HH:mm',\n        LLLL : 'dddd, D MMMM YYYY HH:mm'\n    },\n    calendar : {\n        sameDay : '[Sot në] LT',\n        nextDay : '[Nesër në] LT',\n        nextWeek : 'dddd [në] LT',\n        lastDay : '[Dje në] LT',\n        lastWeek : 'dddd [e kaluar në] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'në %s',\n        past : '%s më parë',\n        s : 'disa sekonda',\n        m : 'një minutë',\n        mm : '%d minuta',\n        h : 'një orë',\n        hh : '%d orë',\n        d : 'një ditë',\n        dd : '%d ditë',\n        M : 'një muaj',\n        MM : '%d muaj',\n        y : 'një vit',\n        yy : '%d vite'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}\\./,\n    ordinal : '%d.',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Serbian Cyrillic [sr-cyrl]\n//! author : Milan Janačković<milanjanackovic@gmail.com> : https://github.com/milan-j\n\nvar translator$1 = {\n    words: { //Different grammatical cases\n        m: ['један минут', 'једне минуте'],\n        mm: ['минут', 'минуте', 'минута'],\n        h: ['један сат', 'једног сата'],\n        hh: ['сат', 'сата', 'сати'],\n        dd: ['дан', 'дана', 'дана'],\n        MM: ['месец', 'месеца', 'месеци'],\n        yy: ['година', 'године', 'година']\n    },\n    correctGrammaticalCase: function (number, wordKey) {\n        return number === 1 ? wordKey[0] : (number >= 2 && number <= 4 ? wordKey[1] : wordKey[2]);\n    },\n    translate: function (number, withoutSuffix, key) {\n        var wordKey = translator$1.words[key];\n        if (key.length === 1) {\n            return withoutSuffix ? wordKey[0] : wordKey[1];\n        } else {\n            return number + ' ' + translator$1.correctGrammaticalCase(number, wordKey);\n        }\n    }\n};\n\nmoment.defineLocale('sr-cyrl', {\n    months: 'јануар_фебруар_март_април_мај_јун_јул_август_септембар_октобар_новембар_децембар'.split('_'),\n    monthsShort: 'јан._феб._мар._апр._мај_јун_јул_авг._сеп._окт._нов._дец.'.split('_'),\n    monthsParseExact: true,\n    weekdays: 'недеља_понедељак_уторак_среда_четвртак_петак_субота'.split('_'),\n    weekdaysShort: 'нед._пон._уто._сре._чет._пет._суб.'.split('_'),\n    weekdaysMin: 'не_по_ут_ср_че_пе_су'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat: {\n        LT: 'H:mm',\n        LTS : 'H:mm:ss',\n        L: 'DD.MM.YYYY',\n        LL: 'D. MMMM YYYY',\n        LLL: 'D. MMMM YYYY H:mm',\n        LLLL: 'dddd, D. MMMM YYYY H:mm'\n    },\n    calendar: {\n        sameDay: '[данас у] LT',\n        nextDay: '[сутра у] LT',\n        nextWeek: function () {\n            switch (this.day()) {\n                case 0:\n                    return '[у] [недељу] [у] LT';\n                case 3:\n                    return '[у] [среду] [у] LT';\n                case 6:\n                    return '[у] [суботу] [у] LT';\n                case 1:\n                case 2:\n                case 4:\n                case 5:\n                    return '[у] dddd [у] LT';\n            }\n        },\n        lastDay  : '[јуче у] LT',\n        lastWeek : function () {\n            var lastWeekDays = [\n                '[прошле] [недеље] [у] LT',\n                '[прошлог] [понедељка] [у] LT',\n                '[прошлог] [уторка] [у] LT',\n                '[прошле] [среде] [у] LT',\n                '[прошлог] [четвртка] [у] LT',\n                '[прошлог] [петка] [у] LT',\n                '[прошле] [суботе] [у] LT'\n            ];\n            return lastWeekDays[this.day()];\n        },\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'за %s',\n        past   : 'пре %s',\n        s      : 'неколико секунди',\n        m      : translator$1.translate,\n        mm     : translator$1.translate,\n        h      : translator$1.translate,\n        hh     : translator$1.translate,\n        d      : 'дан',\n        dd     : translator$1.translate,\n        M      : 'месец',\n        MM     : translator$1.translate,\n        y      : 'годину',\n        yy     : translator$1.translate\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}\\./,\n    ordinal : '%d.',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 7  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Serbian [sr]\n//! author : Milan Janačković<milanjanackovic@gmail.com> : https://github.com/milan-j\n\nvar translator$2 = {\n    words: { //Different grammatical cases\n        m: ['jedan minut', 'jedne minute'],\n        mm: ['minut', 'minute', 'minuta'],\n        h: ['jedan sat', 'jednog sata'],\n        hh: ['sat', 'sata', 'sati'],\n        dd: ['dan', 'dana', 'dana'],\n        MM: ['mesec', 'meseca', 'meseci'],\n        yy: ['godina', 'godine', 'godina']\n    },\n    correctGrammaticalCase: function (number, wordKey) {\n        return number === 1 ? wordKey[0] : (number >= 2 && number <= 4 ? wordKey[1] : wordKey[2]);\n    },\n    translate: function (number, withoutSuffix, key) {\n        var wordKey = translator$2.words[key];\n        if (key.length === 1) {\n            return withoutSuffix ? wordKey[0] : wordKey[1];\n        } else {\n            return number + ' ' + translator$2.correctGrammaticalCase(number, wordKey);\n        }\n    }\n};\n\nmoment.defineLocale('sr', {\n    months: 'januar_februar_mart_april_maj_jun_jul_avgust_septembar_oktobar_novembar_decembar'.split('_'),\n    monthsShort: 'jan._feb._mar._apr._maj_jun_jul_avg._sep._okt._nov._dec.'.split('_'),\n    monthsParseExact: true,\n    weekdays: 'nedelja_ponedeljak_utorak_sreda_četvrtak_petak_subota'.split('_'),\n    weekdaysShort: 'ned._pon._uto._sre._čet._pet._sub.'.split('_'),\n    weekdaysMin: 'ne_po_ut_sr_če_pe_su'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat: {\n        LT: 'H:mm',\n        LTS : 'H:mm:ss',\n        L: 'DD.MM.YYYY',\n        LL: 'D. MMMM YYYY',\n        LLL: 'D. MMMM YYYY H:mm',\n        LLLL: 'dddd, D. MMMM YYYY H:mm'\n    },\n    calendar: {\n        sameDay: '[danas u] LT',\n        nextDay: '[sutra u] LT',\n        nextWeek: function () {\n            switch (this.day()) {\n                case 0:\n                    return '[u] [nedelju] [u] LT';\n                case 3:\n                    return '[u] [sredu] [u] LT';\n                case 6:\n                    return '[u] [subotu] [u] LT';\n                case 1:\n                case 2:\n                case 4:\n                case 5:\n                    return '[u] dddd [u] LT';\n            }\n        },\n        lastDay  : '[juče u] LT',\n        lastWeek : function () {\n            var lastWeekDays = [\n                '[prošle] [nedelje] [u] LT',\n                '[prošlog] [ponedeljka] [u] LT',\n                '[prošlog] [utorka] [u] LT',\n                '[prošle] [srede] [u] LT',\n                '[prošlog] [četvrtka] [u] LT',\n                '[prošlog] [petka] [u] LT',\n                '[prošle] [subote] [u] LT'\n            ];\n            return lastWeekDays[this.day()];\n        },\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'za %s',\n        past   : 'pre %s',\n        s      : 'nekoliko sekundi',\n        m      : translator$2.translate,\n        mm     : translator$2.translate,\n        h      : translator$2.translate,\n        hh     : translator$2.translate,\n        d      : 'dan',\n        dd     : translator$2.translate,\n        M      : 'mesec',\n        MM     : translator$2.translate,\n        y      : 'godinu',\n        yy     : translator$2.translate\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}\\./,\n    ordinal : '%d.',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 7  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : siSwati [ss]\n//! author : Nicolai Davies<mail@nicolai.io> : https://github.com/nicolaidavies\n\n\nmoment.defineLocale('ss', {\n    months : \"Bhimbidvwane_Indlovana_Indlov'lenkhulu_Mabasa_Inkhwekhweti_Inhlaba_Kholwane_Ingci_Inyoni_Imphala_Lweti_Ingongoni\".split('_'),\n    monthsShort : 'Bhi_Ina_Inu_Mab_Ink_Inh_Kho_Igc_Iny_Imp_Lwe_Igo'.split('_'),\n    weekdays : 'Lisontfo_Umsombuluko_Lesibili_Lesitsatfu_Lesine_Lesihlanu_Umgcibelo'.split('_'),\n    weekdaysShort : 'Lis_Umb_Lsb_Les_Lsi_Lsh_Umg'.split('_'),\n    weekdaysMin : 'Li_Us_Lb_Lt_Ls_Lh_Ug'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat : {\n        LT : 'h:mm A',\n        LTS : 'h:mm:ss A',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY h:mm A',\n        LLLL : 'dddd, D MMMM YYYY h:mm A'\n    },\n    calendar : {\n        sameDay : '[Namuhla nga] LT',\n        nextDay : '[Kusasa nga] LT',\n        nextWeek : 'dddd [nga] LT',\n        lastDay : '[Itolo nga] LT',\n        lastWeek : 'dddd [leliphelile] [nga] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'nga %s',\n        past : 'wenteka nga %s',\n        s : 'emizuzwana lomcane',\n        m : 'umzuzu',\n        mm : '%d emizuzu',\n        h : 'lihora',\n        hh : '%d emahora',\n        d : 'lilanga',\n        dd : '%d emalanga',\n        M : 'inyanga',\n        MM : '%d tinyanga',\n        y : 'umnyaka',\n        yy : '%d iminyaka'\n    },\n    meridiemParse: /ekuseni|emini|entsambama|ebusuku/,\n    meridiem : function (hours, minutes, isLower) {\n        if (hours < 11) {\n            return 'ekuseni';\n        } else if (hours < 15) {\n            return 'emini';\n        } else if (hours < 19) {\n            return 'entsambama';\n        } else {\n            return 'ebusuku';\n        }\n    },\n    meridiemHour : function (hour, meridiem) {\n        if (hour === 12) {\n            hour = 0;\n        }\n        if (meridiem === 'ekuseni') {\n            return hour;\n        } else if (meridiem === 'emini') {\n            return hour >= 11 ? hour : hour + 12;\n        } else if (meridiem === 'entsambama' || meridiem === 'ebusuku') {\n            if (hour === 0) {\n                return 0;\n            }\n            return hour + 12;\n        }\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}/,\n    ordinal : '%d',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Swedish [sv]\n//! author : Jens Alm : https://github.com/ulmus\n\nmoment.defineLocale('sv', {\n    months : 'januari_februari_mars_april_maj_juni_juli_augusti_september_oktober_november_december'.split('_'),\n    monthsShort : 'jan_feb_mar_apr_maj_jun_jul_aug_sep_okt_nov_dec'.split('_'),\n    weekdays : 'söndag_måndag_tisdag_onsdag_torsdag_fredag_lördag'.split('_'),\n    weekdaysShort : 'sön_mån_tis_ons_tor_fre_lör'.split('_'),\n    weekdaysMin : 'sö_må_ti_on_to_fr_lö'.split('_'),\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'YYYY-MM-DD',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY [kl.] HH:mm',\n        LLLL : 'dddd D MMMM YYYY [kl.] HH:mm',\n        lll : 'D MMM YYYY HH:mm',\n        llll : 'ddd D MMM YYYY HH:mm'\n    },\n    calendar : {\n        sameDay: '[Idag] LT',\n        nextDay: '[Imorgon] LT',\n        lastDay: '[Igår] LT',\n        nextWeek: '[På] dddd LT',\n        lastWeek: '[I] dddd[s] LT',\n        sameElse: 'L'\n    },\n    relativeTime : {\n        future : 'om %s',\n        past : 'för %s sedan',\n        s : 'några sekunder',\n        m : 'en minut',\n        mm : '%d minuter',\n        h : 'en timme',\n        hh : '%d timmar',\n        d : 'en dag',\n        dd : '%d dagar',\n        M : 'en månad',\n        MM : '%d månader',\n        y : 'ett år',\n        yy : '%d år'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}(e|a)/,\n    ordinal : function (number) {\n        var b = number % 10,\n            output = (~~(number % 100 / 10) === 1) ? 'e' :\n            (b === 1) ? 'a' :\n            (b === 2) ? 'a' :\n            (b === 3) ? 'e' : 'e';\n        return number + output;\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Swahili [sw]\n//! author : Fahad Kassim : https://github.com/fadsel\n\nmoment.defineLocale('sw', {\n    months : 'Januari_Februari_Machi_Aprili_Mei_Juni_Julai_Agosti_Septemba_Oktoba_Novemba_Desemba'.split('_'),\n    monthsShort : 'Jan_Feb_Mac_Apr_Mei_Jun_Jul_Ago_Sep_Okt_Nov_Des'.split('_'),\n    weekdays : 'Jumapili_Jumatatu_Jumanne_Jumatano_Alhamisi_Ijumaa_Jumamosi'.split('_'),\n    weekdaysShort : 'Jpl_Jtat_Jnne_Jtan_Alh_Ijm_Jmos'.split('_'),\n    weekdaysMin : 'J2_J3_J4_J5_Al_Ij_J1'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD.MM.YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY HH:mm',\n        LLLL : 'dddd, D MMMM YYYY HH:mm'\n    },\n    calendar : {\n        sameDay : '[leo saa] LT',\n        nextDay : '[kesho saa] LT',\n        nextWeek : '[wiki ijayo] dddd [saat] LT',\n        lastDay : '[jana] LT',\n        lastWeek : '[wiki iliyopita] dddd [saat] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : '%s baadaye',\n        past : 'tokea %s',\n        s : 'hivi punde',\n        m : 'dakika moja',\n        mm : 'dakika %d',\n        h : 'saa limoja',\n        hh : 'masaa %d',\n        d : 'siku moja',\n        dd : 'masiku %d',\n        M : 'mwezi mmoja',\n        MM : 'miezi %d',\n        y : 'mwaka mmoja',\n        yy : 'miaka %d'\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 7  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Tamil [ta]\n//! author : Arjunkumar Krishnamoorthy : https://github.com/tk120404\n\nvar symbolMap$12 = {\n    '1': '௧',\n    '2': '௨',\n    '3': '௩',\n    '4': '௪',\n    '5': '௫',\n    '6': '௬',\n    '7': '௭',\n    '8': '௮',\n    '9': '௯',\n    '0': '௦'\n};\nvar numberMap$11 = {\n    '௧': '1',\n    '௨': '2',\n    '௩': '3',\n    '௪': '4',\n    '௫': '5',\n    '௬': '6',\n    '௭': '7',\n    '௮': '8',\n    '௯': '9',\n    '௦': '0'\n};\n\nmoment.defineLocale('ta', {\n    months : 'ஜனவரி_பிப்ரவரி_மார்ச்_ஏப்ரல்_மே_ஜூன்_ஜூலை_ஆகஸ்ட்_செப்டெம்பர்_அக்டோபர்_நவம்பர்_டிசம்பர்'.split('_'),\n    monthsShort : 'ஜனவரி_பிப்ரவரி_மார்ச்_ஏப்ரல்_மே_ஜூன்_ஜூலை_ஆகஸ்ட்_செப்டெம்பர்_அக்டோபர்_நவம்பர்_டிசம்பர்'.split('_'),\n    weekdays : 'ஞாயிற்றுக்கிழமை_திங்கட்கிழமை_செவ்வாய்கிழமை_புதன்கிழமை_வியாழக்கிழமை_வெள்ளிக்கிழமை_சனிக்கிழமை'.split('_'),\n    weekdaysShort : 'ஞாயிறு_திங்கள்_செவ்வாய்_புதன்_வியாழன்_வெள்ளி_சனி'.split('_'),\n    weekdaysMin : 'ஞா_தி_செ_பு_வி_வெ_ச'.split('_'),\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY, HH:mm',\n        LLLL : 'dddd, D MMMM YYYY, HH:mm'\n    },\n    calendar : {\n        sameDay : '[இன்று] LT',\n        nextDay : '[நாளை] LT',\n        nextWeek : 'dddd, LT',\n        lastDay : '[நேற்று] LT',\n        lastWeek : '[கடந்த வாரம்] dddd, LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : '%s இல்',\n        past : '%s முன்',\n        s : 'ஒரு சில விநாடிகள்',\n        m : 'ஒரு நிமிடம்',\n        mm : '%d நிமிடங்கள்',\n        h : 'ஒரு மணி நேரம்',\n        hh : '%d மணி நேரம்',\n        d : 'ஒரு நாள்',\n        dd : '%d நாட்கள்',\n        M : 'ஒரு மாதம்',\n        MM : '%d மாதங்கள்',\n        y : 'ஒரு வருடம்',\n        yy : '%d ஆண்டுகள்'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}வது/,\n    ordinal : function (number) {\n        return number + 'வது';\n    },\n    preparse: function (string) {\n        return string.replace(/[௧௨௩௪௫௬௭௮௯௦]/g, function (match) {\n            return numberMap$11[match];\n        });\n    },\n    postformat: function (string) {\n        return string.replace(/\\d/g, function (match) {\n            return symbolMap$12[match];\n        });\n    },\n    // refer http://ta.wikipedia.org/s/1er1\n    meridiemParse: /யாமம்|வைகறை|காலை|நண்பகல்|எற்பாடு|மாலை/,\n    meridiem : function (hour, minute, isLower) {\n        if (hour < 2) {\n            return ' யாமம்';\n        } else if (hour < 6) {\n            return ' வைகறை';  // வைகறை\n        } else if (hour < 10) {\n            return ' காலை'; // காலை\n        } else if (hour < 14) {\n            return ' நண்பகல்'; // நண்பகல்\n        } else if (hour < 18) {\n            return ' எற்பாடு'; // எற்பாடு\n        } else if (hour < 22) {\n            return ' மாலை'; // மாலை\n        } else {\n            return ' யாமம்';\n        }\n    },\n    meridiemHour : function (hour, meridiem) {\n        if (hour === 12) {\n            hour = 0;\n        }\n        if (meridiem === 'யாமம்') {\n            return hour < 2 ? hour : hour + 12;\n        } else if (meridiem === 'வைகறை' || meridiem === 'காலை') {\n            return hour;\n        } else if (meridiem === 'நண்பகல்') {\n            return hour >= 10 ? hour : hour + 12;\n        } else {\n            return hour + 12;\n        }\n    },\n    week : {\n        dow : 0, // Sunday is the first day of the week.\n        doy : 6  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Telugu [te]\n//! author : Krishna Chaitanya Thota : https://github.com/kcthota\n\nmoment.defineLocale('te', {\n    months : 'జనవరి_ఫిబ్రవరి_మార్చి_ఏప్రిల్_మే_జూన్_జూలై_ఆగస్టు_సెప్టెంబర్_అక్టోబర్_నవంబర్_డిసెంబర్'.split('_'),\n    monthsShort : 'జన._ఫిబ్ర._మార్చి_ఏప్రి._మే_జూన్_జూలై_ఆగ._సెప్._అక్టో._నవ._డిసె.'.split('_'),\n    monthsParseExact : true,\n    weekdays : 'ఆదివారం_సోమవారం_మంగళవారం_బుధవారం_గురువారం_శుక్రవారం_శనివారం'.split('_'),\n    weekdaysShort : 'ఆది_సోమ_మంగళ_బుధ_గురు_శుక్ర_శని'.split('_'),\n    weekdaysMin : 'ఆ_సో_మం_బు_గు_శు_శ'.split('_'),\n    longDateFormat : {\n        LT : 'A h:mm',\n        LTS : 'A h:mm:ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY, A h:mm',\n        LLLL : 'dddd, D MMMM YYYY, A h:mm'\n    },\n    calendar : {\n        sameDay : '[నేడు] LT',\n        nextDay : '[రేపు] LT',\n        nextWeek : 'dddd, LT',\n        lastDay : '[నిన్న] LT',\n        lastWeek : '[గత] dddd, LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : '%s లో',\n        past : '%s క్రితం',\n        s : 'కొన్ని క్షణాలు',\n        m : 'ఒక నిమిషం',\n        mm : '%d నిమిషాలు',\n        h : 'ఒక గంట',\n        hh : '%d గంటలు',\n        d : 'ఒక రోజు',\n        dd : '%d రోజులు',\n        M : 'ఒక నెల',\n        MM : '%d నెలలు',\n        y : 'ఒక సంవత్సరం',\n        yy : '%d సంవత్సరాలు'\n    },\n    dayOfMonthOrdinalParse : /\\d{1,2}వ/,\n    ordinal : '%dవ',\n    meridiemParse: /రాత్రి|ఉదయం|మధ్యాహ్నం|సాయంత్రం/,\n    meridiemHour : function (hour, meridiem) {\n        if (hour === 12) {\n            hour = 0;\n        }\n        if (meridiem === 'రాత్రి') {\n            return hour < 4 ? hour : hour + 12;\n        } else if (meridiem === 'ఉదయం') {\n            return hour;\n        } else if (meridiem === 'మధ్యాహ్నం') {\n            return hour >= 10 ? hour : hour + 12;\n        } else if (meridiem === 'సాయంత్రం') {\n            return hour + 12;\n        }\n    },\n    meridiem : function (hour, minute, isLower) {\n        if (hour < 4) {\n            return 'రాత్రి';\n        } else if (hour < 10) {\n            return 'ఉదయం';\n        } else if (hour < 17) {\n            return 'మధ్యాహ్నం';\n        } else if (hour < 20) {\n            return 'సాయంత్రం';\n        } else {\n            return 'రాత్రి';\n        }\n    },\n    week : {\n        dow : 0, // Sunday is the first day of the week.\n        doy : 6  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Tetun Dili (East Timor) [tet]\n//! author : Joshua Brooks : https://github.com/joshbrooks\n//! author : Onorio De J. Afonso : https://github.com/marobo\n\nmoment.defineLocale('tet', {\n    months : 'Janeiru_Fevereiru_Marsu_Abril_Maiu_Juniu_Juliu_Augustu_Setembru_Outubru_Novembru_Dezembru'.split('_'),\n    monthsShort : 'Jan_Fev_Mar_Abr_Mai_Jun_Jul_Aug_Set_Out_Nov_Dez'.split('_'),\n    weekdays : 'Domingu_Segunda_Tersa_Kuarta_Kinta_Sexta_Sabadu'.split('_'),\n    weekdaysShort : 'Dom_Seg_Ters_Kua_Kint_Sext_Sab'.split('_'),\n    weekdaysMin : 'Do_Seg_Te_Ku_Ki_Sex_Sa'.split('_'),\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY HH:mm',\n        LLLL : 'dddd, D MMMM YYYY HH:mm'\n    },\n    calendar : {\n        sameDay: '[Ohin iha] LT',\n        nextDay: '[Aban iha] LT',\n        nextWeek: 'dddd [iha] LT',\n        lastDay: '[Horiseik iha] LT',\n        lastWeek: 'dddd [semana kotuk] [iha] LT',\n        sameElse: 'L'\n    },\n    relativeTime : {\n        future : 'iha %s',\n        past : '%s liuba',\n        s : 'minutu balun',\n        m : 'minutu ida',\n        mm : 'minutus %d',\n        h : 'horas ida',\n        hh : 'horas %d',\n        d : 'loron ida',\n        dd : 'loron %d',\n        M : 'fulan ida',\n        MM : 'fulan %d',\n        y : 'tinan ida',\n        yy : 'tinan %d'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}(st|nd|rd|th)/,\n    ordinal : function (number) {\n        var b = number % 10,\n            output = (~~(number % 100 / 10) === 1) ? 'th' :\n            (b === 1) ? 'st' :\n            (b === 2) ? 'nd' :\n            (b === 3) ? 'rd' : 'th';\n        return number + output;\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Thai [th]\n//! author : Kridsada Thanabulpong : https://github.com/sirn\n\nmoment.defineLocale('th', {\n    months : 'มกราคม_กุมภาพันธ์_มีนาคม_เมษายน_พฤษภาคม_มิถุนายน_กรกฎาคม_สิงหาคม_กันยายน_ตุลาคม_พฤศจิกายน_ธันวาคม'.split('_'),\n    monthsShort : 'ม.ค._ก.พ._มี.ค._เม.ย._พ.ค._มิ.ย._ก.ค._ส.ค._ก.ย._ต.ค._พ.ย._ธ.ค.'.split('_'),\n    monthsParseExact: true,\n    weekdays : 'อาทิตย์_จันทร์_อังคาร_พุธ_พฤหัสบดี_ศุกร์_เสาร์'.split('_'),\n    weekdaysShort : 'อาทิตย์_จันทร์_อังคาร_พุธ_พฤหัส_ศุกร์_เสาร์'.split('_'), // yes, three characters difference\n    weekdaysMin : 'อา._จ._อ._พ._พฤ._ศ._ส.'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat : {\n        LT : 'H:mm',\n        LTS : 'H:mm:ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY เวลา H:mm',\n        LLLL : 'วันddddที่ D MMMM YYYY เวลา H:mm'\n    },\n    meridiemParse: /ก่อนเที่ยง|หลังเที่ยง/,\n    isPM: function (input) {\n        return input === 'หลังเที่ยง';\n    },\n    meridiem : function (hour, minute, isLower) {\n        if (hour < 12) {\n            return 'ก่อนเที่ยง';\n        } else {\n            return 'หลังเที่ยง';\n        }\n    },\n    calendar : {\n        sameDay : '[วันนี้ เวลา] LT',\n        nextDay : '[พรุ่งนี้ เวลา] LT',\n        nextWeek : 'dddd[หน้า เวลา] LT',\n        lastDay : '[เมื่อวานนี้ เวลา] LT',\n        lastWeek : '[วัน]dddd[ที่แล้ว เวลา] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'อีก %s',\n        past : '%sที่แล้ว',\n        s : 'ไม่กี่วินาที',\n        m : '1 นาที',\n        mm : '%d นาที',\n        h : '1 ชั่วโมง',\n        hh : '%d ชั่วโมง',\n        d : '1 วัน',\n        dd : '%d วัน',\n        M : '1 เดือน',\n        MM : '%d เดือน',\n        y : '1 ปี',\n        yy : '%d ปี'\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Tagalog (Philippines) [tl-ph]\n//! author : Dan Hagman : https://github.com/hagmandan\n\nmoment.defineLocale('tl-ph', {\n    months : 'Enero_Pebrero_Marso_Abril_Mayo_Hunyo_Hulyo_Agosto_Setyembre_Oktubre_Nobyembre_Disyembre'.split('_'),\n    monthsShort : 'Ene_Peb_Mar_Abr_May_Hun_Hul_Ago_Set_Okt_Nob_Dis'.split('_'),\n    weekdays : 'Linggo_Lunes_Martes_Miyerkules_Huwebes_Biyernes_Sabado'.split('_'),\n    weekdaysShort : 'Lin_Lun_Mar_Miy_Huw_Biy_Sab'.split('_'),\n    weekdaysMin : 'Li_Lu_Ma_Mi_Hu_Bi_Sab'.split('_'),\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'MM/D/YYYY',\n        LL : 'MMMM D, YYYY',\n        LLL : 'MMMM D, YYYY HH:mm',\n        LLLL : 'dddd, MMMM DD, YYYY HH:mm'\n    },\n    calendar : {\n        sameDay: 'LT [ngayong araw]',\n        nextDay: '[Bukas ng] LT',\n        nextWeek: 'LT [sa susunod na] dddd',\n        lastDay: 'LT [kahapon]',\n        lastWeek: 'LT [noong nakaraang] dddd',\n        sameElse: 'L'\n    },\n    relativeTime : {\n        future : 'sa loob ng %s',\n        past : '%s ang nakalipas',\n        s : 'ilang segundo',\n        m : 'isang minuto',\n        mm : '%d minuto',\n        h : 'isang oras',\n        hh : '%d oras',\n        d : 'isang araw',\n        dd : '%d araw',\n        M : 'isang buwan',\n        MM : '%d buwan',\n        y : 'isang taon',\n        yy : '%d taon'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}/,\n    ordinal : function (number) {\n        return number;\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Klingon [tlh]\n//! author : Dominika Kruk : https://github.com/amaranthrose\n\nvar numbersNouns = 'pagh_wa’_cha’_wej_loS_vagh_jav_Soch_chorgh_Hut'.split('_');\n\nfunction translateFuture(output) {\n    var time = output;\n    time = (output.indexOf('jaj') !== -1) ?\n    time.slice(0, -3) + 'leS' :\n    (output.indexOf('jar') !== -1) ?\n    time.slice(0, -3) + 'waQ' :\n    (output.indexOf('DIS') !== -1) ?\n    time.slice(0, -3) + 'nem' :\n    time + ' pIq';\n    return time;\n}\n\nfunction translatePast(output) {\n    var time = output;\n    time = (output.indexOf('jaj') !== -1) ?\n    time.slice(0, -3) + 'Hu’' :\n    (output.indexOf('jar') !== -1) ?\n    time.slice(0, -3) + 'wen' :\n    (output.indexOf('DIS') !== -1) ?\n    time.slice(0, -3) + 'ben' :\n    time + ' ret';\n    return time;\n}\n\nfunction translate$9(number, withoutSuffix, string, isFuture) {\n    var numberNoun = numberAsNoun(number);\n    switch (string) {\n        case 'mm':\n            return numberNoun + ' tup';\n        case 'hh':\n            return numberNoun + ' rep';\n        case 'dd':\n            return numberNoun + ' jaj';\n        case 'MM':\n            return numberNoun + ' jar';\n        case 'yy':\n            return numberNoun + ' DIS';\n    }\n}\n\nfunction numberAsNoun(number) {\n    var hundred = Math.floor((number % 1000) / 100),\n    ten = Math.floor((number % 100) / 10),\n    one = number % 10,\n    word = '';\n    if (hundred > 0) {\n        word += numbersNouns[hundred] + 'vatlh';\n    }\n    if (ten > 0) {\n        word += ((word !== '') ? ' ' : '') + numbersNouns[ten] + 'maH';\n    }\n    if (one > 0) {\n        word += ((word !== '') ? ' ' : '') + numbersNouns[one];\n    }\n    return (word === '') ? 'pagh' : word;\n}\n\nmoment.defineLocale('tlh', {\n    months : 'tera’ jar wa’_tera’ jar cha’_tera’ jar wej_tera’ jar loS_tera’ jar vagh_tera’ jar jav_tera’ jar Soch_tera’ jar chorgh_tera’ jar Hut_tera’ jar wa’maH_tera’ jar wa’maH wa’_tera’ jar wa’maH cha’'.split('_'),\n    monthsShort : 'jar wa’_jar cha’_jar wej_jar loS_jar vagh_jar jav_jar Soch_jar chorgh_jar Hut_jar wa’maH_jar wa’maH wa’_jar wa’maH cha’'.split('_'),\n    monthsParseExact : true,\n    weekdays : 'lojmItjaj_DaSjaj_povjaj_ghItlhjaj_loghjaj_buqjaj_ghInjaj'.split('_'),\n    weekdaysShort : 'lojmItjaj_DaSjaj_povjaj_ghItlhjaj_loghjaj_buqjaj_ghInjaj'.split('_'),\n    weekdaysMin : 'lojmItjaj_DaSjaj_povjaj_ghItlhjaj_loghjaj_buqjaj_ghInjaj'.split('_'),\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD.MM.YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY HH:mm',\n        LLLL : 'dddd, D MMMM YYYY HH:mm'\n    },\n    calendar : {\n        sameDay: '[DaHjaj] LT',\n        nextDay: '[wa’leS] LT',\n        nextWeek: 'LLL',\n        lastDay: '[wa’Hu’] LT',\n        lastWeek: 'LLL',\n        sameElse: 'L'\n    },\n    relativeTime : {\n        future : translateFuture,\n        past : translatePast,\n        s : 'puS lup',\n        m : 'wa’ tup',\n        mm : translate$9,\n        h : 'wa’ rep',\n        hh : translate$9,\n        d : 'wa’ jaj',\n        dd : translate$9,\n        M : 'wa’ jar',\n        MM : translate$9,\n        y : 'wa’ DIS',\n        yy : translate$9\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}\\./,\n    ordinal : '%d.',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Turkish [tr]\n//! authors : Erhan Gundogan : https://github.com/erhangundogan,\n//!           Burak Yiğit Kaya: https://github.com/BYK\n\nvar suffixes$3 = {\n    1: '\\'inci',\n    5: '\\'inci',\n    8: '\\'inci',\n    70: '\\'inci',\n    80: '\\'inci',\n    2: '\\'nci',\n    7: '\\'nci',\n    20: '\\'nci',\n    50: '\\'nci',\n    3: '\\'üncü',\n    4: '\\'üncü',\n    100: '\\'üncü',\n    6: '\\'ncı',\n    9: '\\'uncu',\n    10: '\\'uncu',\n    30: '\\'uncu',\n    60: '\\'ıncı',\n    90: '\\'ıncı'\n};\n\nmoment.defineLocale('tr', {\n    months : 'Ocak_Şubat_Mart_Nisan_Mayıs_Haziran_Temmuz_Ağustos_Eylül_Ekim_Kasım_Aralık'.split('_'),\n    monthsShort : 'Oca_Şub_Mar_Nis_May_Haz_Tem_Ağu_Eyl_Eki_Kas_Ara'.split('_'),\n    weekdays : 'Pazar_Pazartesi_Salı_Çarşamba_Perşembe_Cuma_Cumartesi'.split('_'),\n    weekdaysShort : 'Paz_Pts_Sal_Çar_Per_Cum_Cts'.split('_'),\n    weekdaysMin : 'Pz_Pt_Sa_Ça_Pe_Cu_Ct'.split('_'),\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD.MM.YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY HH:mm',\n        LLLL : 'dddd, D MMMM YYYY HH:mm'\n    },\n    calendar : {\n        sameDay : '[bugün saat] LT',\n        nextDay : '[yarın saat] LT',\n        nextWeek : '[haftaya] dddd [saat] LT',\n        lastDay : '[dün] LT',\n        lastWeek : '[geçen hafta] dddd [saat] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : '%s sonra',\n        past : '%s önce',\n        s : 'birkaç saniye',\n        m : 'bir dakika',\n        mm : '%d dakika',\n        h : 'bir saat',\n        hh : '%d saat',\n        d : 'bir gün',\n        dd : '%d gün',\n        M : 'bir ay',\n        MM : '%d ay',\n        y : 'bir yıl',\n        yy : '%d yıl'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}'(inci|nci|üncü|ncı|uncu|ıncı)/,\n    ordinal : function (number) {\n        if (number === 0) {  // special case for zero\n            return number + '\\'ıncı';\n        }\n        var a = number % 10,\n            b = number % 100 - a,\n            c = number >= 100 ? 100 : null;\n        return number + (suffixes$3[a] || suffixes$3[b] || suffixes$3[c]);\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 7  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Talossan [tzl]\n//! author : Robin van der Vliet : https://github.com/robin0van0der0v\n//! author : Iustì Canun\n\n// After the year there should be a slash and the amount of years since December 26, 1979 in Roman numerals.\n// This is currently too difficult (maybe even impossible) to add.\nmoment.defineLocale('tzl', {\n    months : 'Januar_Fevraglh_Març_Avrïu_Mai_Gün_Julia_Guscht_Setemvar_Listopäts_Noemvar_Zecemvar'.split('_'),\n    monthsShort : 'Jan_Fev_Mar_Avr_Mai_Gün_Jul_Gus_Set_Lis_Noe_Zec'.split('_'),\n    weekdays : 'Súladi_Lúneçi_Maitzi_Márcuri_Xhúadi_Viénerçi_Sáturi'.split('_'),\n    weekdaysShort : 'Súl_Lún_Mai_Már_Xhú_Vié_Sát'.split('_'),\n    weekdaysMin : 'Sú_Lú_Ma_Má_Xh_Vi_Sá'.split('_'),\n    longDateFormat : {\n        LT : 'HH.mm',\n        LTS : 'HH.mm.ss',\n        L : 'DD.MM.YYYY',\n        LL : 'D. MMMM [dallas] YYYY',\n        LLL : 'D. MMMM [dallas] YYYY HH.mm',\n        LLLL : 'dddd, [li] D. MMMM [dallas] YYYY HH.mm'\n    },\n    meridiemParse: /d\\'o|d\\'a/i,\n    isPM : function (input) {\n        return 'd\\'o' === input.toLowerCase();\n    },\n    meridiem : function (hours, minutes, isLower) {\n        if (hours > 11) {\n            return isLower ? 'd\\'o' : 'D\\'O';\n        } else {\n            return isLower ? 'd\\'a' : 'D\\'A';\n        }\n    },\n    calendar : {\n        sameDay : '[oxhi à] LT',\n        nextDay : '[demà à] LT',\n        nextWeek : 'dddd [à] LT',\n        lastDay : '[ieiri à] LT',\n        lastWeek : '[sür el] dddd [lasteu à] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'osprei %s',\n        past : 'ja%s',\n        s : processRelativeTime$7,\n        m : processRelativeTime$7,\n        mm : processRelativeTime$7,\n        h : processRelativeTime$7,\n        hh : processRelativeTime$7,\n        d : processRelativeTime$7,\n        dd : processRelativeTime$7,\n        M : processRelativeTime$7,\n        MM : processRelativeTime$7,\n        y : processRelativeTime$7,\n        yy : processRelativeTime$7\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}\\./,\n    ordinal : '%d.',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\nfunction processRelativeTime$7(number, withoutSuffix, key, isFuture) {\n    var format = {\n        's': ['viensas secunds', '\\'iensas secunds'],\n        'm': ['\\'n míut', '\\'iens míut'],\n        'mm': [number + ' míuts', '' + number + ' míuts'],\n        'h': ['\\'n þora', '\\'iensa þora'],\n        'hh': [number + ' þoras', '' + number + ' þoras'],\n        'd': ['\\'n ziua', '\\'iensa ziua'],\n        'dd': [number + ' ziuas', '' + number + ' ziuas'],\n        'M': ['\\'n mes', '\\'iens mes'],\n        'MM': [number + ' mesen', '' + number + ' mesen'],\n        'y': ['\\'n ar', '\\'iens ar'],\n        'yy': [number + ' ars', '' + number + ' ars']\n    };\n    return isFuture ? format[key][0] : (withoutSuffix ? format[key][0] : format[key][1]);\n}\n\n//! moment.js locale configuration\n//! locale : Central Atlas Tamazight Latin [tzm-latn]\n//! author : Abdel Said : https://github.com/abdelsaid\n\nmoment.defineLocale('tzm-latn', {\n    months : 'innayr_brˤayrˤ_marˤsˤ_ibrir_mayyw_ywnyw_ywlywz_ɣwšt_šwtanbir_ktˤwbrˤ_nwwanbir_dwjnbir'.split('_'),\n    monthsShort : 'innayr_brˤayrˤ_marˤsˤ_ibrir_mayyw_ywnyw_ywlywz_ɣwšt_šwtanbir_ktˤwbrˤ_nwwanbir_dwjnbir'.split('_'),\n    weekdays : 'asamas_aynas_asinas_akras_akwas_asimwas_asiḍyas'.split('_'),\n    weekdaysShort : 'asamas_aynas_asinas_akras_akwas_asimwas_asiḍyas'.split('_'),\n    weekdaysMin : 'asamas_aynas_asinas_akras_akwas_asimwas_asiḍyas'.split('_'),\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY HH:mm',\n        LLLL : 'dddd D MMMM YYYY HH:mm'\n    },\n    calendar : {\n        sameDay: '[asdkh g] LT',\n        nextDay: '[aska g] LT',\n        nextWeek: 'dddd [g] LT',\n        lastDay: '[assant g] LT',\n        lastWeek: 'dddd [g] LT',\n        sameElse: 'L'\n    },\n    relativeTime : {\n        future : 'dadkh s yan %s',\n        past : 'yan %s',\n        s : 'imik',\n        m : 'minuḍ',\n        mm : '%d minuḍ',\n        h : 'saɛa',\n        hh : '%d tassaɛin',\n        d : 'ass',\n        dd : '%d ossan',\n        M : 'ayowr',\n        MM : '%d iyyirn',\n        y : 'asgas',\n        yy : '%d isgasn'\n    },\n    week : {\n        dow : 6, // Saturday is the first day of the week.\n        doy : 12  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Central Atlas Tamazight [tzm]\n//! author : Abdel Said : https://github.com/abdelsaid\n\nmoment.defineLocale('tzm', {\n    months : 'ⵉⵏⵏⴰⵢⵔ_ⴱⵕⴰⵢⵕ_ⵎⴰⵕⵚ_ⵉⴱⵔⵉⵔ_ⵎⴰⵢⵢⵓ_ⵢⵓⵏⵢⵓ_ⵢⵓⵍⵢⵓⵣ_ⵖⵓⵛⵜ_ⵛⵓⵜⴰⵏⴱⵉⵔ_ⴽⵟⵓⴱⵕ_ⵏⵓⵡⴰⵏⴱⵉⵔ_ⴷⵓⵊⵏⴱⵉⵔ'.split('_'),\n    monthsShort : 'ⵉⵏⵏⴰⵢⵔ_ⴱⵕⴰⵢⵕ_ⵎⴰⵕⵚ_ⵉⴱⵔⵉⵔ_ⵎⴰⵢⵢⵓ_ⵢⵓⵏⵢⵓ_ⵢⵓⵍⵢⵓⵣ_ⵖⵓⵛⵜ_ⵛⵓⵜⴰⵏⴱⵉⵔ_ⴽⵟⵓⴱⵕ_ⵏⵓⵡⴰⵏⴱⵉⵔ_ⴷⵓⵊⵏⴱⵉⵔ'.split('_'),\n    weekdays : 'ⴰⵙⴰⵎⴰⵙ_ⴰⵢⵏⴰⵙ_ⴰⵙⵉⵏⴰⵙ_ⴰⴽⵔⴰⵙ_ⴰⴽⵡⴰⵙ_ⴰⵙⵉⵎⵡⴰⵙ_ⴰⵙⵉⴹⵢⴰⵙ'.split('_'),\n    weekdaysShort : 'ⴰⵙⴰⵎⴰⵙ_ⴰⵢⵏⴰⵙ_ⴰⵙⵉⵏⴰⵙ_ⴰⴽⵔⴰⵙ_ⴰⴽⵡⴰⵙ_ⴰⵙⵉⵎⵡⴰⵙ_ⴰⵙⵉⴹⵢⴰⵙ'.split('_'),\n    weekdaysMin : 'ⴰⵙⴰⵎⴰⵙ_ⴰⵢⵏⴰⵙ_ⴰⵙⵉⵏⴰⵙ_ⴰⴽⵔⴰⵙ_ⴰⴽⵡⴰⵙ_ⴰⵙⵉⵎⵡⴰⵙ_ⴰⵙⵉⴹⵢⴰⵙ'.split('_'),\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS: 'HH:mm:ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY HH:mm',\n        LLLL : 'dddd D MMMM YYYY HH:mm'\n    },\n    calendar : {\n        sameDay: '[ⴰⵙⴷⵅ ⴴ] LT',\n        nextDay: '[ⴰⵙⴽⴰ ⴴ] LT',\n        nextWeek: 'dddd [ⴴ] LT',\n        lastDay: '[ⴰⵚⴰⵏⵜ ⴴ] LT',\n        lastWeek: 'dddd [ⴴ] LT',\n        sameElse: 'L'\n    },\n    relativeTime : {\n        future : 'ⴷⴰⴷⵅ ⵙ ⵢⴰⵏ %s',\n        past : 'ⵢⴰⵏ %s',\n        s : 'ⵉⵎⵉⴽ',\n        m : 'ⵎⵉⵏⵓⴺ',\n        mm : '%d ⵎⵉⵏⵓⴺ',\n        h : 'ⵙⴰⵄⴰ',\n        hh : '%d ⵜⴰⵙⵙⴰⵄⵉⵏ',\n        d : 'ⴰⵙⵙ',\n        dd : '%d oⵙⵙⴰⵏ',\n        M : 'ⴰⵢoⵓⵔ',\n        MM : '%d ⵉⵢⵢⵉⵔⵏ',\n        y : 'ⴰⵙⴳⴰⵙ',\n        yy : '%d ⵉⵙⴳⴰⵙⵏ'\n    },\n    week : {\n        dow : 6, // Saturday is the first day of the week.\n        doy : 12  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Ukrainian [uk]\n//! author : zemlanin : https://github.com/zemlanin\n//! Author : Menelion Elensúle : https://github.com/Oire\n\nfunction plural$6(word, num) {\n    var forms = word.split('_');\n    return num % 10 === 1 && num % 100 !== 11 ? forms[0] : (num % 10 >= 2 && num % 10 <= 4 && (num % 100 < 10 || num % 100 >= 20) ? forms[1] : forms[2]);\n}\nfunction relativeTimeWithPlural$4(number, withoutSuffix, key) {\n    var format = {\n        'mm': withoutSuffix ? 'хвилина_хвилини_хвилин' : 'хвилину_хвилини_хвилин',\n        'hh': withoutSuffix ? 'година_години_годин' : 'годину_години_годин',\n        'dd': 'день_дні_днів',\n        'MM': 'місяць_місяці_місяців',\n        'yy': 'рік_роки_років'\n    };\n    if (key === 'm') {\n        return withoutSuffix ? 'хвилина' : 'хвилину';\n    }\n    else if (key === 'h') {\n        return withoutSuffix ? 'година' : 'годину';\n    }\n    else {\n        return number + ' ' + plural$6(format[key], +number);\n    }\n}\nfunction weekdaysCaseReplace(m, format) {\n    var weekdays = {\n        'nominative': 'неділя_понеділок_вівторок_середа_четвер_п’ятниця_субота'.split('_'),\n        'accusative': 'неділю_понеділок_вівторок_середу_четвер_п’ятницю_суботу'.split('_'),\n        'genitive': 'неділі_понеділка_вівторка_середи_четверга_п’ятниці_суботи'.split('_')\n    };\n\n    if (!m) {\n        return weekdays['nominative'];\n    }\n\n    var nounCase = (/(\\[[ВвУу]\\]) ?dddd/).test(format) ?\n        'accusative' :\n        ((/\\[?(?:минулої|наступної)? ?\\] ?dddd/).test(format) ?\n            'genitive' :\n            'nominative');\n    return weekdays[nounCase][m.day()];\n}\nfunction processHoursFunction(str) {\n    return function () {\n        return str + 'о' + (this.hours() === 11 ? 'б' : '') + '] LT';\n    };\n}\n\nmoment.defineLocale('uk', {\n    months : {\n        'format': 'січня_лютого_березня_квітня_травня_червня_липня_серпня_вересня_жовтня_листопада_грудня'.split('_'),\n        'standalone': 'січень_лютий_березень_квітень_травень_червень_липень_серпень_вересень_жовтень_листопад_грудень'.split('_')\n    },\n    monthsShort : 'січ_лют_бер_квіт_трав_черв_лип_серп_вер_жовт_лист_груд'.split('_'),\n    weekdays : weekdaysCaseReplace,\n    weekdaysShort : 'нд_пн_вт_ср_чт_пт_сб'.split('_'),\n    weekdaysMin : 'нд_пн_вт_ср_чт_пт_сб'.split('_'),\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD.MM.YYYY',\n        LL : 'D MMMM YYYY р.',\n        LLL : 'D MMMM YYYY р., HH:mm',\n        LLLL : 'dddd, D MMMM YYYY р., HH:mm'\n    },\n    calendar : {\n        sameDay: processHoursFunction('[Сьогодні '),\n        nextDay: processHoursFunction('[Завтра '),\n        lastDay: processHoursFunction('[Вчора '),\n        nextWeek: processHoursFunction('[У] dddd ['),\n        lastWeek: function () {\n            switch (this.day()) {\n                case 0:\n                case 3:\n                case 5:\n                case 6:\n                    return processHoursFunction('[Минулої] dddd [').call(this);\n                case 1:\n                case 2:\n                case 4:\n                    return processHoursFunction('[Минулого] dddd [').call(this);\n            }\n        },\n        sameElse: 'L'\n    },\n    relativeTime : {\n        future : 'за %s',\n        past : '%s тому',\n        s : 'декілька секунд',\n        m : relativeTimeWithPlural$4,\n        mm : relativeTimeWithPlural$4,\n        h : 'годину',\n        hh : relativeTimeWithPlural$4,\n        d : 'день',\n        dd : relativeTimeWithPlural$4,\n        M : 'місяць',\n        MM : relativeTimeWithPlural$4,\n        y : 'рік',\n        yy : relativeTimeWithPlural$4\n    },\n    // M. E.: those two are virtually unused but a user might want to implement them for his/her website for some reason\n    meridiemParse: /ночі|ранку|дня|вечора/,\n    isPM: function (input) {\n        return /^(дня|вечора)$/.test(input);\n    },\n    meridiem : function (hour, minute, isLower) {\n        if (hour < 4) {\n            return 'ночі';\n        } else if (hour < 12) {\n            return 'ранку';\n        } else if (hour < 17) {\n            return 'дня';\n        } else {\n            return 'вечора';\n        }\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}-(й|го)/,\n    ordinal: function (number, period) {\n        switch (period) {\n            case 'M':\n            case 'd':\n            case 'DDD':\n            case 'w':\n            case 'W':\n                return number + '-й';\n            case 'D':\n                return number + '-го';\n            default:\n                return number;\n        }\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 7  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Urdu [ur]\n//! author : Sawood Alam : https://github.com/ibnesayeed\n//! author : Zack : https://github.com/ZackVision\n\nvar months$7 = [\n    'جنوری',\n    'فروری',\n    'مارچ',\n    'اپریل',\n    'مئی',\n    'جون',\n    'جولائی',\n    'اگست',\n    'ستمبر',\n    'اکتوبر',\n    'نومبر',\n    'دسمبر'\n];\nvar days$1 = [\n    'اتوار',\n    'پیر',\n    'منگل',\n    'بدھ',\n    'جمعرات',\n    'جمعہ',\n    'ہفتہ'\n];\n\nmoment.defineLocale('ur', {\n    months : months$7,\n    monthsShort : months$7,\n    weekdays : days$1,\n    weekdaysShort : days$1,\n    weekdaysMin : days$1,\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY HH:mm',\n        LLLL : 'dddd، D MMMM YYYY HH:mm'\n    },\n    meridiemParse: /صبح|شام/,\n    isPM : function (input) {\n        return 'شام' === input;\n    },\n    meridiem : function (hour, minute, isLower) {\n        if (hour < 12) {\n            return 'صبح';\n        }\n        return 'شام';\n    },\n    calendar : {\n        sameDay : '[آج بوقت] LT',\n        nextDay : '[کل بوقت] LT',\n        nextWeek : 'dddd [بوقت] LT',\n        lastDay : '[گذشتہ روز بوقت] LT',\n        lastWeek : '[گذشتہ] dddd [بوقت] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : '%s بعد',\n        past : '%s قبل',\n        s : 'چند سیکنڈ',\n        m : 'ایک منٹ',\n        mm : '%d منٹ',\n        h : 'ایک گھنٹہ',\n        hh : '%d گھنٹے',\n        d : 'ایک دن',\n        dd : '%d دن',\n        M : 'ایک ماہ',\n        MM : '%d ماہ',\n        y : 'ایک سال',\n        yy : '%d سال'\n    },\n    preparse: function (string) {\n        return string.replace(/،/g, ',');\n    },\n    postformat: function (string) {\n        return string.replace(/,/g, '،');\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Uzbek Latin [uz-latn]\n//! author : Rasulbek Mirzayev : github.com/Rasulbeeek\n\nmoment.defineLocale('uz-latn', {\n    months : 'Yanvar_Fevral_Mart_Aprel_May_Iyun_Iyul_Avgust_Sentabr_Oktabr_Noyabr_Dekabr'.split('_'),\n    monthsShort : 'Yan_Fev_Mar_Apr_May_Iyun_Iyul_Avg_Sen_Okt_Noy_Dek'.split('_'),\n    weekdays : 'Yakshanba_Dushanba_Seshanba_Chorshanba_Payshanba_Juma_Shanba'.split('_'),\n    weekdaysShort : 'Yak_Dush_Sesh_Chor_Pay_Jum_Shan'.split('_'),\n    weekdaysMin : 'Ya_Du_Se_Cho_Pa_Ju_Sha'.split('_'),\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY HH:mm',\n        LLLL : 'D MMMM YYYY, dddd HH:mm'\n    },\n    calendar : {\n        sameDay : '[Bugun soat] LT [da]',\n        nextDay : '[Ertaga] LT [da]',\n        nextWeek : 'dddd [kuni soat] LT [da]',\n        lastDay : '[Kecha soat] LT [da]',\n        lastWeek : '[O\\'tgan] dddd [kuni soat] LT [da]',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'Yaqin %s ichida',\n        past : 'Bir necha %s oldin',\n        s : 'soniya',\n        m : 'bir daqiqa',\n        mm : '%d daqiqa',\n        h : 'bir soat',\n        hh : '%d soat',\n        d : 'bir kun',\n        dd : '%d kun',\n        M : 'bir oy',\n        MM : '%d oy',\n        y : 'bir yil',\n        yy : '%d yil'\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 7  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Uzbek [uz]\n//! author : Sardor Muminov : https://github.com/muminoff\n\nmoment.defineLocale('uz', {\n    months : 'январ_феврал_март_апрел_май_июн_июл_август_сентябр_октябр_ноябр_декабр'.split('_'),\n    monthsShort : 'янв_фев_мар_апр_май_июн_июл_авг_сен_окт_ноя_дек'.split('_'),\n    weekdays : 'Якшанба_Душанба_Сешанба_Чоршанба_Пайшанба_Жума_Шанба'.split('_'),\n    weekdaysShort : 'Якш_Душ_Сеш_Чор_Пай_Жум_Шан'.split('_'),\n    weekdaysMin : 'Як_Ду_Се_Чо_Па_Жу_Ша'.split('_'),\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY HH:mm',\n        LLLL : 'D MMMM YYYY, dddd HH:mm'\n    },\n    calendar : {\n        sameDay : '[Бугун соат] LT [да]',\n        nextDay : '[Эртага] LT [да]',\n        nextWeek : 'dddd [куни соат] LT [да]',\n        lastDay : '[Кеча соат] LT [да]',\n        lastWeek : '[Утган] dddd [куни соат] LT [да]',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'Якин %s ичида',\n        past : 'Бир неча %s олдин',\n        s : 'фурсат',\n        m : 'бир дакика',\n        mm : '%d дакика',\n        h : 'бир соат',\n        hh : '%d соат',\n        d : 'бир кун',\n        dd : '%d кун',\n        M : 'бир ой',\n        MM : '%d ой',\n        y : 'бир йил',\n        yy : '%d йил'\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 7  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Vietnamese [vi]\n//! author : Bang Nguyen : https://github.com/bangnk\n\nmoment.defineLocale('vi', {\n    months : 'tháng 1_tháng 2_tháng 3_tháng 4_tháng 5_tháng 6_tháng 7_tháng 8_tháng 9_tháng 10_tháng 11_tháng 12'.split('_'),\n    monthsShort : 'Th01_Th02_Th03_Th04_Th05_Th06_Th07_Th08_Th09_Th10_Th11_Th12'.split('_'),\n    monthsParseExact : true,\n    weekdays : 'chủ nhật_thứ hai_thứ ba_thứ tư_thứ năm_thứ sáu_thứ bảy'.split('_'),\n    weekdaysShort : 'CN_T2_T3_T4_T5_T6_T7'.split('_'),\n    weekdaysMin : 'CN_T2_T3_T4_T5_T6_T7'.split('_'),\n    weekdaysParseExact : true,\n    meridiemParse: /sa|ch/i,\n    isPM : function (input) {\n        return /^ch$/i.test(input);\n    },\n    meridiem : function (hours, minutes, isLower) {\n        if (hours < 12) {\n            return isLower ? 'sa' : 'SA';\n        } else {\n            return isLower ? 'ch' : 'CH';\n        }\n    },\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM [năm] YYYY',\n        LLL : 'D MMMM [năm] YYYY HH:mm',\n        LLLL : 'dddd, D MMMM [năm] YYYY HH:mm',\n        l : 'DD/M/YYYY',\n        ll : 'D MMM YYYY',\n        lll : 'D MMM YYYY HH:mm',\n        llll : 'ddd, D MMM YYYY HH:mm'\n    },\n    calendar : {\n        sameDay: '[Hôm nay lúc] LT',\n        nextDay: '[Ngày mai lúc] LT',\n        nextWeek: 'dddd [tuần tới lúc] LT',\n        lastDay: '[Hôm qua lúc] LT',\n        lastWeek: 'dddd [tuần rồi lúc] LT',\n        sameElse: 'L'\n    },\n    relativeTime : {\n        future : '%s tới',\n        past : '%s trước',\n        s : 'vài giây',\n        m : 'một phút',\n        mm : '%d phút',\n        h : 'một giờ',\n        hh : '%d giờ',\n        d : 'một ngày',\n        dd : '%d ngày',\n        M : 'một tháng',\n        MM : '%d tháng',\n        y : 'một năm',\n        yy : '%d năm'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}/,\n    ordinal : function (number) {\n        return number;\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Pseudo [x-pseudo]\n//! author : Andrew Hood : https://github.com/andrewhood125\n\nmoment.defineLocale('x-pseudo', {\n    months : 'J~áñúá~rý_F~ébrú~árý_~Márc~h_Áp~ríl_~Máý_~Júñé~_Júl~ý_Áú~gúst~_Sép~témb~ér_Ó~ctób~ér_Ñ~óvém~bér_~Décé~mbér'.split('_'),\n    monthsShort : 'J~áñ_~Féb_~Már_~Ápr_~Máý_~Júñ_~Júl_~Áúg_~Sép_~Óct_~Ñóv_~Déc'.split('_'),\n    monthsParseExact : true,\n    weekdays : 'S~úñdá~ý_Mó~ñdáý~_Túé~sdáý~_Wéd~ñésd~áý_T~húrs~dáý_~Fríd~áý_S~átúr~dáý'.split('_'),\n    weekdaysShort : 'S~úñ_~Móñ_~Túé_~Wéd_~Thú_~Frí_~Sát'.split('_'),\n    weekdaysMin : 'S~ú_Mó~_Tú_~Wé_T~h_Fr~_Sá'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat : {\n        LT : 'HH:mm',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY HH:mm',\n        LLLL : 'dddd, D MMMM YYYY HH:mm'\n    },\n    calendar : {\n        sameDay : '[T~ódá~ý át] LT',\n        nextDay : '[T~ómó~rró~w át] LT',\n        nextWeek : 'dddd [át] LT',\n        lastDay : '[Ý~ést~érdá~ý át] LT',\n        lastWeek : '[L~ást] dddd [át] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'í~ñ %s',\n        past : '%s á~gó',\n        s : 'á ~féw ~sécó~ñds',\n        m : 'á ~míñ~úté',\n        mm : '%d m~íñú~tés',\n        h : 'á~ñ hó~úr',\n        hh : '%d h~óúrs',\n        d : 'á ~dáý',\n        dd : '%d d~áýs',\n        M : 'á ~móñ~th',\n        MM : '%d m~óñt~hs',\n        y : 'á ~ýéár',\n        yy : '%d ý~éárs'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}(th|st|nd|rd)/,\n    ordinal : function (number) {\n        var b = number % 10,\n            output = (~~(number % 100 / 10) === 1) ? 'th' :\n            (b === 1) ? 'st' :\n            (b === 2) ? 'nd' :\n            (b === 3) ? 'rd' : 'th';\n        return number + output;\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Yoruba Nigeria [yo]\n//! author : Atolagbe Abisoye : https://github.com/andela-batolagbe\n\nmoment.defineLocale('yo', {\n    months : 'Sẹ́rẹ́_Èrèlè_Ẹrẹ̀nà_Ìgbé_Èbibi_Òkùdu_Agẹmo_Ògún_Owewe_Ọ̀wàrà_Bélú_Ọ̀pẹ̀̀'.split('_'),\n    monthsShort : 'Sẹ́r_Èrl_Ẹrn_Ìgb_Èbi_Òkù_Agẹ_Ògú_Owe_Ọ̀wà_Bél_Ọ̀pẹ̀̀'.split('_'),\n    weekdays : 'Àìkú_Ajé_Ìsẹ́gun_Ọjọ́rú_Ọjọ́bọ_Ẹtì_Àbámẹ́ta'.split('_'),\n    weekdaysShort : 'Àìk_Ajé_Ìsẹ́_Ọjr_Ọjb_Ẹtì_Àbá'.split('_'),\n    weekdaysMin : 'Àì_Aj_Ìs_Ọr_Ọb_Ẹt_Àb'.split('_'),\n    longDateFormat : {\n        LT : 'h:mm A',\n        LTS : 'h:mm:ss A',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY h:mm A',\n        LLLL : 'dddd, D MMMM YYYY h:mm A'\n    },\n    calendar : {\n        sameDay : '[Ònì ni] LT',\n        nextDay : '[Ọ̀la ni] LT',\n        nextWeek : 'dddd [Ọsẹ̀ tón\\'bọ] [ni] LT',\n        lastDay : '[Àna ni] LT',\n        lastWeek : 'dddd [Ọsẹ̀ tólọ́] [ni] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'ní %s',\n        past : '%s kọjá',\n        s : 'ìsẹjú aayá die',\n        m : 'ìsẹjú kan',\n        mm : 'ìsẹjú %d',\n        h : 'wákati kan',\n        hh : 'wákati %d',\n        d : 'ọjọ́ kan',\n        dd : 'ọjọ́ %d',\n        M : 'osù kan',\n        MM : 'osù %d',\n        y : 'ọdún kan',\n        yy : 'ọdún %d'\n    },\n    dayOfMonthOrdinalParse : /ọjọ́\\s\\d{1,2}/,\n    ordinal : 'ọjọ́ %d',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4 // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Chinese (China) [zh-cn]\n//! author : suupic : https://github.com/suupic\n//! author : Zeno Zeng : https://github.com/zenozeng\n\nmoment.defineLocale('zh-cn', {\n    months : '一月_二月_三月_四月_五月_六月_七月_八月_九月_十月_十一月_十二月'.split('_'),\n    monthsShort : '1月_2月_3月_4月_5月_6月_7月_8月_9月_10月_11月_12月'.split('_'),\n    weekdays : '星期日_星期一_星期二_星期三_星期四_星期五_星期六'.split('_'),\n    weekdaysShort : '周日_周一_周二_周三_周四_周五_周六'.split('_'),\n    weekdaysMin : '日_一_二_三_四_五_六'.split('_'),\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'YYYY年MMMD日',\n        LL : 'YYYY年MMMD日',\n        LLL : 'YYYY年MMMD日Ah点mm分',\n        LLLL : 'YYYY年MMMD日ddddAh点mm分',\n        l : 'YYYY年MMMD日',\n        ll : 'YYYY年MMMD日',\n        lll : 'YYYY年MMMD日 HH:mm',\n        llll : 'YYYY年MMMD日dddd HH:mm'\n    },\n    meridiemParse: /凌晨|早上|上午|中午|下午|晚上/,\n    meridiemHour: function (hour, meridiem) {\n        if (hour === 12) {\n            hour = 0;\n        }\n        if (meridiem === '凌晨' || meridiem === '早上' ||\n                meridiem === '上午') {\n            return hour;\n        } else if (meridiem === '下午' || meridiem === '晚上') {\n            return hour + 12;\n        } else {\n            // '中午'\n            return hour >= 11 ? hour : hour + 12;\n        }\n    },\n    meridiem : function (hour, minute, isLower) {\n        var hm = hour * 100 + minute;\n        if (hm < 600) {\n            return '凌晨';\n        } else if (hm < 900) {\n            return '早上';\n        } else if (hm < 1130) {\n            return '上午';\n        } else if (hm < 1230) {\n            return '中午';\n        } else if (hm < 1800) {\n            return '下午';\n        } else {\n            return '晚上';\n        }\n    },\n    calendar : {\n        sameDay : '[今天]LT',\n        nextDay : '[明天]LT',\n        nextWeek : '[下]ddddLT',\n        lastDay : '[昨天]LT',\n        lastWeek : '[上]ddddLT',\n        sameElse : 'L'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}(日|月|周)/,\n    ordinal : function (number, period) {\n        switch (period) {\n            case 'd':\n            case 'D':\n            case 'DDD':\n                return number + '日';\n            case 'M':\n                return number + '月';\n            case 'w':\n            case 'W':\n                return number + '周';\n            default:\n                return number;\n        }\n    },\n    relativeTime : {\n        future : '%s内',\n        past : '%s前',\n        s : '几秒',\n        m : '1 分钟',\n        mm : '%d 分钟',\n        h : '1 小时',\n        hh : '%d 小时',\n        d : '1 天',\n        dd : '%d 天',\n        M : '1 个月',\n        MM : '%d 个月',\n        y : '1 年',\n        yy : '%d 年'\n    },\n    week : {\n        // GB/T 7408-1994《数据元和交换格式·信息交换·日期和时间表示法》与ISO 8601:1988等效\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Chinese (Hong Kong) [zh-hk]\n//! author : Ben : https://github.com/ben-lin\n//! author : Chris Lam : https://github.com/hehachris\n//! author : Konstantin : https://github.com/skfd\n\nmoment.defineLocale('zh-hk', {\n    months : '一月_二月_三月_四月_五月_六月_七月_八月_九月_十月_十一月_十二月'.split('_'),\n    monthsShort : '1月_2月_3月_4月_5月_6月_7月_8月_9月_10月_11月_12月'.split('_'),\n    weekdays : '星期日_星期一_星期二_星期三_星期四_星期五_星期六'.split('_'),\n    weekdaysShort : '週日_週一_週二_週三_週四_週五_週六'.split('_'),\n    weekdaysMin : '日_一_二_三_四_五_六'.split('_'),\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'YYYY年MMMD日',\n        LL : 'YYYY年MMMD日',\n        LLL : 'YYYY年MMMD日 HH:mm',\n        LLLL : 'YYYY年MMMD日dddd HH:mm',\n        l : 'YYYY年MMMD日',\n        ll : 'YYYY年MMMD日',\n        lll : 'YYYY年MMMD日 HH:mm',\n        llll : 'YYYY年MMMD日dddd HH:mm'\n    },\n    meridiemParse: /凌晨|早上|上午|中午|下午|晚上/,\n    meridiemHour : function (hour, meridiem) {\n        if (hour === 12) {\n            hour = 0;\n        }\n        if (meridiem === '凌晨' || meridiem === '早上' || meridiem === '上午') {\n            return hour;\n        } else if (meridiem === '中午') {\n            return hour >= 11 ? hour : hour + 12;\n        } else if (meridiem === '下午' || meridiem === '晚上') {\n            return hour + 12;\n        }\n    },\n    meridiem : function (hour, minute, isLower) {\n        var hm = hour * 100 + minute;\n        if (hm < 600) {\n            return '凌晨';\n        } else if (hm < 900) {\n            return '早上';\n        } else if (hm < 1130) {\n            return '上午';\n        } else if (hm < 1230) {\n            return '中午';\n        } else if (hm < 1800) {\n            return '下午';\n        } else {\n            return '晚上';\n        }\n    },\n    calendar : {\n        sameDay : '[今天]LT',\n        nextDay : '[明天]LT',\n        nextWeek : '[下]ddddLT',\n        lastDay : '[昨天]LT',\n        lastWeek : '[上]ddddLT',\n        sameElse : 'L'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}(日|月|週)/,\n    ordinal : function (number, period) {\n        switch (period) {\n            case 'd' :\n            case 'D' :\n            case 'DDD' :\n                return number + '日';\n            case 'M' :\n                return number + '月';\n            case 'w' :\n            case 'W' :\n                return number + '週';\n            default :\n                return number;\n        }\n    },\n    relativeTime : {\n        future : '%s內',\n        past : '%s前',\n        s : '幾秒',\n        m : '1 分鐘',\n        mm : '%d 分鐘',\n        h : '1 小時',\n        hh : '%d 小時',\n        d : '1 天',\n        dd : '%d 天',\n        M : '1 個月',\n        MM : '%d 個月',\n        y : '1 年',\n        yy : '%d 年'\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Chinese (Taiwan) [zh-tw]\n//! author : Ben : https://github.com/ben-lin\n//! author : Chris Lam : https://github.com/hehachris\n\nmoment.defineLocale('zh-tw', {\n    months : '一月_二月_三月_四月_五月_六月_七月_八月_九月_十月_十一月_十二月'.split('_'),\n    monthsShort : '1月_2月_3月_4月_5月_6月_7月_8月_9月_10月_11月_12月'.split('_'),\n    weekdays : '星期日_星期一_星期二_星期三_星期四_星期五_星期六'.split('_'),\n    weekdaysShort : '週日_週一_週二_週三_週四_週五_週六'.split('_'),\n    weekdaysMin : '日_一_二_三_四_五_六'.split('_'),\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'YYYY年MMMD日',\n        LL : 'YYYY年MMMD日',\n        LLL : 'YYYY年MMMD日 HH:mm',\n        LLLL : 'YYYY年MMMD日dddd HH:mm',\n        l : 'YYYY年MMMD日',\n        ll : 'YYYY年MMMD日',\n        lll : 'YYYY年MMMD日 HH:mm',\n        llll : 'YYYY年MMMD日dddd HH:mm'\n    },\n    meridiemParse: /凌晨|早上|上午|中午|下午|晚上/,\n    meridiemHour : function (hour, meridiem) {\n        if (hour === 12) {\n            hour = 0;\n        }\n        if (meridiem === '凌晨' || meridiem === '早上' || meridiem === '上午') {\n            return hour;\n        } else if (meridiem === '中午') {\n            return hour >= 11 ? hour : hour + 12;\n        } else if (meridiem === '下午' || meridiem === '晚上') {\n            return hour + 12;\n        }\n    },\n    meridiem : function (hour, minute, isLower) {\n        var hm = hour * 100 + minute;\n        if (hm < 600) {\n            return '凌晨';\n        } else if (hm < 900) {\n            return '早上';\n        } else if (hm < 1130) {\n            return '上午';\n        } else if (hm < 1230) {\n            return '中午';\n        } else if (hm < 1800) {\n            return '下午';\n        } else {\n            return '晚上';\n        }\n    },\n    calendar : {\n        sameDay : '[今天]LT',\n        nextDay : '[明天]LT',\n        nextWeek : '[下]ddddLT',\n        lastDay : '[昨天]LT',\n        lastWeek : '[上]ddddLT',\n        sameElse : 'L'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}(日|月|週)/,\n    ordinal : function (number, period) {\n        switch (period) {\n            case 'd' :\n            case 'D' :\n            case 'DDD' :\n                return number + '日';\n            case 'M' :\n                return number + '月';\n            case 'w' :\n            case 'W' :\n                return number + '週';\n            default :\n                return number;\n        }\n    },\n    relativeTime : {\n        future : '%s內',\n        past : '%s前',\n        s : '幾秒',\n        m : '1 分鐘',\n        mm : '%d 分鐘',\n        h : '1 小時',\n        hh : '%d 小時',\n        d : '1 天',\n        dd : '%d 天',\n        M : '1 個月',\n        MM : '%d 個月',\n        y : '1 年',\n        yy : '%d 年'\n    }\n});\n\nmoment.locale('en');\n\nreturn moment;\n\n})));\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/min/moment-with-locales.js",
    "content": ";(function (global, factory) {\n    typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :\n    typeof define === 'function' && define.amd ? define(factory) :\n    global.moment = factory()\n}(this, (function () { 'use strict';\n\nvar hookCallback;\n\nfunction hooks () {\n    return hookCallback.apply(null, arguments);\n}\n\n// This is done to register the method called with moment()\n// without creating circular dependencies.\nfunction setHookCallback (callback) {\n    hookCallback = callback;\n}\n\nfunction isArray(input) {\n    return input instanceof Array || Object.prototype.toString.call(input) === '[object Array]';\n}\n\nfunction isObject(input) {\n    // IE8 will treat undefined and null as object if it wasn't for\n    // input != null\n    return input != null && Object.prototype.toString.call(input) === '[object Object]';\n}\n\nfunction isObjectEmpty(obj) {\n    var k;\n    for (k in obj) {\n        // even if its not own property I'd still call it non-empty\n        return false;\n    }\n    return true;\n}\n\nfunction isUndefined(input) {\n    return input === void 0;\n}\n\nfunction isNumber(input) {\n    return typeof input === 'number' || Object.prototype.toString.call(input) === '[object Number]';\n}\n\nfunction isDate(input) {\n    return input instanceof Date || Object.prototype.toString.call(input) === '[object Date]';\n}\n\nfunction map(arr, fn) {\n    var res = [], i;\n    for (i = 0; i < arr.length; ++i) {\n        res.push(fn(arr[i], i));\n    }\n    return res;\n}\n\nfunction hasOwnProp(a, b) {\n    return Object.prototype.hasOwnProperty.call(a, b);\n}\n\nfunction extend(a, b) {\n    for (var i in b) {\n        if (hasOwnProp(b, i)) {\n            a[i] = b[i];\n        }\n    }\n\n    if (hasOwnProp(b, 'toString')) {\n        a.toString = b.toString;\n    }\n\n    if (hasOwnProp(b, 'valueOf')) {\n        a.valueOf = b.valueOf;\n    }\n\n    return a;\n}\n\nfunction createUTC (input, format, locale, strict) {\n    return createLocalOrUTC(input, format, locale, strict, true).utc();\n}\n\nfunction defaultParsingFlags() {\n    // We need to deep clone this object.\n    return {\n        empty           : false,\n        unusedTokens    : [],\n        unusedInput     : [],\n        overflow        : -2,\n        charsLeftOver   : 0,\n        nullInput       : false,\n        invalidMonth    : null,\n        invalidFormat   : false,\n        userInvalidated : false,\n        iso             : false,\n        parsedDateParts : [],\n        meridiem        : null,\n        rfc2822         : false,\n        weekdayMismatch : false\n    };\n}\n\nfunction getParsingFlags(m) {\n    if (m._pf == null) {\n        m._pf = defaultParsingFlags();\n    }\n    return m._pf;\n}\n\nvar some;\nif (Array.prototype.some) {\n    some = Array.prototype.some;\n} else {\n    some = function (fun) {\n        var t = Object(this);\n        var len = t.length >>> 0;\n\n        for (var i = 0; i < len; i++) {\n            if (i in t && fun.call(this, t[i], i, t)) {\n                return true;\n            }\n        }\n\n        return false;\n    };\n}\n\nvar some$1 = some;\n\nfunction isValid(m) {\n    if (m._isValid == null) {\n        var flags = getParsingFlags(m);\n        var parsedParts = some$1.call(flags.parsedDateParts, function (i) {\n            return i != null;\n        });\n        var isNowValid = !isNaN(m._d.getTime()) &&\n            flags.overflow < 0 &&\n            !flags.empty &&\n            !flags.invalidMonth &&\n            !flags.invalidWeekday &&\n            !flags.nullInput &&\n            !flags.invalidFormat &&\n            !flags.userInvalidated &&\n            (!flags.meridiem || (flags.meridiem && parsedParts));\n\n        if (m._strict) {\n            isNowValid = isNowValid &&\n                flags.charsLeftOver === 0 &&\n                flags.unusedTokens.length === 0 &&\n                flags.bigHour === undefined;\n        }\n\n        if (Object.isFrozen == null || !Object.isFrozen(m)) {\n            m._isValid = isNowValid;\n        }\n        else {\n            return isNowValid;\n        }\n    }\n    return m._isValid;\n}\n\nfunction createInvalid (flags) {\n    var m = createUTC(NaN);\n    if (flags != null) {\n        extend(getParsingFlags(m), flags);\n    }\n    else {\n        getParsingFlags(m).userInvalidated = true;\n    }\n\n    return m;\n}\n\n// Plugins that add properties should also add the key here (null value),\n// so we can properly clone ourselves.\nvar momentProperties = hooks.momentProperties = [];\n\nfunction copyConfig(to, from) {\n    var i, prop, val;\n\n    if (!isUndefined(from._isAMomentObject)) {\n        to._isAMomentObject = from._isAMomentObject;\n    }\n    if (!isUndefined(from._i)) {\n        to._i = from._i;\n    }\n    if (!isUndefined(from._f)) {\n        to._f = from._f;\n    }\n    if (!isUndefined(from._l)) {\n        to._l = from._l;\n    }\n    if (!isUndefined(from._strict)) {\n        to._strict = from._strict;\n    }\n    if (!isUndefined(from._tzm)) {\n        to._tzm = from._tzm;\n    }\n    if (!isUndefined(from._isUTC)) {\n        to._isUTC = from._isUTC;\n    }\n    if (!isUndefined(from._offset)) {\n        to._offset = from._offset;\n    }\n    if (!isUndefined(from._pf)) {\n        to._pf = getParsingFlags(from);\n    }\n    if (!isUndefined(from._locale)) {\n        to._locale = from._locale;\n    }\n\n    if (momentProperties.length > 0) {\n        for (i = 0; i < momentProperties.length; i++) {\n            prop = momentProperties[i];\n            val = from[prop];\n            if (!isUndefined(val)) {\n                to[prop] = val;\n            }\n        }\n    }\n\n    return to;\n}\n\nvar updateInProgress = false;\n\n// Moment prototype object\nfunction Moment(config) {\n    copyConfig(this, config);\n    this._d = new Date(config._d != null ? config._d.getTime() : NaN);\n    if (!this.isValid()) {\n        this._d = new Date(NaN);\n    }\n    // Prevent infinite loop in case updateOffset creates new moment\n    // objects.\n    if (updateInProgress === false) {\n        updateInProgress = true;\n        hooks.updateOffset(this);\n        updateInProgress = false;\n    }\n}\n\nfunction isMoment (obj) {\n    return obj instanceof Moment || (obj != null && obj._isAMomentObject != null);\n}\n\nfunction absFloor (number) {\n    if (number < 0) {\n        // -0 -> 0\n        return Math.ceil(number) || 0;\n    } else {\n        return Math.floor(number);\n    }\n}\n\nfunction toInt(argumentForCoercion) {\n    var coercedNumber = +argumentForCoercion,\n        value = 0;\n\n    if (coercedNumber !== 0 && isFinite(coercedNumber)) {\n        value = absFloor(coercedNumber);\n    }\n\n    return value;\n}\n\n// compare two arrays, return the number of differences\nfunction compareArrays(array1, array2, dontConvert) {\n    var len = Math.min(array1.length, array2.length),\n        lengthDiff = Math.abs(array1.length - array2.length),\n        diffs = 0,\n        i;\n    for (i = 0; i < len; i++) {\n        if ((dontConvert && array1[i] !== array2[i]) ||\n            (!dontConvert && toInt(array1[i]) !== toInt(array2[i]))) {\n            diffs++;\n        }\n    }\n    return diffs + lengthDiff;\n}\n\nfunction warn(msg) {\n    if (hooks.suppressDeprecationWarnings === false &&\n            (typeof console !==  'undefined') && console.warn) {\n        console.warn('Deprecation warning: ' + msg);\n    }\n}\n\nfunction deprecate(msg, fn) {\n    var firstTime = true;\n\n    return extend(function () {\n        if (hooks.deprecationHandler != null) {\n            hooks.deprecationHandler(null, msg);\n        }\n        if (firstTime) {\n            var args = [];\n            var arg;\n            for (var i = 0; i < arguments.length; i++) {\n                arg = '';\n                if (typeof arguments[i] === 'object') {\n                    arg += '\\n[' + i + '] ';\n                    for (var key in arguments[0]) {\n                        arg += key + ': ' + arguments[0][key] + ', ';\n                    }\n                    arg = arg.slice(0, -2); // Remove trailing comma and space\n                } else {\n                    arg = arguments[i];\n                }\n                args.push(arg);\n            }\n            warn(msg + '\\nArguments: ' + Array.prototype.slice.call(args).join('') + '\\n' + (new Error()).stack);\n            firstTime = false;\n        }\n        return fn.apply(this, arguments);\n    }, fn);\n}\n\nvar deprecations = {};\n\nfunction deprecateSimple(name, msg) {\n    if (hooks.deprecationHandler != null) {\n        hooks.deprecationHandler(name, msg);\n    }\n    if (!deprecations[name]) {\n        warn(msg);\n        deprecations[name] = true;\n    }\n}\n\nhooks.suppressDeprecationWarnings = false;\nhooks.deprecationHandler = null;\n\nfunction isFunction(input) {\n    return input instanceof Function || Object.prototype.toString.call(input) === '[object Function]';\n}\n\nfunction set (config) {\n    var prop, i;\n    for (i in config) {\n        prop = config[i];\n        if (isFunction(prop)) {\n            this[i] = prop;\n        } else {\n            this['_' + i] = prop;\n        }\n    }\n    this._config = config;\n    // Lenient ordinal parsing accepts just a number in addition to\n    // number + (possibly) stuff coming from _dayOfMonthOrdinalParse.\n    // TODO: Remove \"ordinalParse\" fallback in next major release.\n    this._dayOfMonthOrdinalParseLenient = new RegExp(\n        (this._dayOfMonthOrdinalParse.source || this._ordinalParse.source) +\n            '|' + (/\\d{1,2}/).source);\n}\n\nfunction mergeConfigs(parentConfig, childConfig) {\n    var res = extend({}, parentConfig), prop;\n    for (prop in childConfig) {\n        if (hasOwnProp(childConfig, prop)) {\n            if (isObject(parentConfig[prop]) && isObject(childConfig[prop])) {\n                res[prop] = {};\n                extend(res[prop], parentConfig[prop]);\n                extend(res[prop], childConfig[prop]);\n            } else if (childConfig[prop] != null) {\n                res[prop] = childConfig[prop];\n            } else {\n                delete res[prop];\n            }\n        }\n    }\n    for (prop in parentConfig) {\n        if (hasOwnProp(parentConfig, prop) &&\n                !hasOwnProp(childConfig, prop) &&\n                isObject(parentConfig[prop])) {\n            // make sure changes to properties don't modify parent config\n            res[prop] = extend({}, res[prop]);\n        }\n    }\n    return res;\n}\n\nfunction Locale(config) {\n    if (config != null) {\n        this.set(config);\n    }\n}\n\nvar keys;\n\nif (Object.keys) {\n    keys = Object.keys;\n} else {\n    keys = function (obj) {\n        var i, res = [];\n        for (i in obj) {\n            if (hasOwnProp(obj, i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    };\n}\n\nvar keys$1 = keys;\n\nvar defaultCalendar = {\n    sameDay : '[Today at] LT',\n    nextDay : '[Tomorrow at] LT',\n    nextWeek : 'dddd [at] LT',\n    lastDay : '[Yesterday at] LT',\n    lastWeek : '[Last] dddd [at] LT',\n    sameElse : 'L'\n};\n\nfunction calendar (key, mom, now) {\n    var output = this._calendar[key] || this._calendar['sameElse'];\n    return isFunction(output) ? output.call(mom, now) : output;\n}\n\nvar defaultLongDateFormat = {\n    LTS  : 'h:mm:ss A',\n    LT   : 'h:mm A',\n    L    : 'MM/DD/YYYY',\n    LL   : 'MMMM D, YYYY',\n    LLL  : 'MMMM D, YYYY h:mm A',\n    LLLL : 'dddd, MMMM D, YYYY h:mm A'\n};\n\nfunction longDateFormat (key) {\n    var format = this._longDateFormat[key],\n        formatUpper = this._longDateFormat[key.toUpperCase()];\n\n    if (format || !formatUpper) {\n        return format;\n    }\n\n    this._longDateFormat[key] = formatUpper.replace(/MMMM|MM|DD|dddd/g, function (val) {\n        return val.slice(1);\n    });\n\n    return this._longDateFormat[key];\n}\n\nvar defaultInvalidDate = 'Invalid date';\n\nfunction invalidDate () {\n    return this._invalidDate;\n}\n\nvar defaultOrdinal = '%d';\nvar defaultDayOfMonthOrdinalParse = /\\d{1,2}/;\n\nfunction ordinal (number) {\n    return this._ordinal.replace('%d', number);\n}\n\nvar defaultRelativeTime = {\n    future : 'in %s',\n    past   : '%s ago',\n    s  : 'a few seconds',\n    ss : '%d seconds',\n    m  : 'a minute',\n    mm : '%d minutes',\n    h  : 'an hour',\n    hh : '%d hours',\n    d  : 'a day',\n    dd : '%d days',\n    M  : 'a month',\n    MM : '%d months',\n    y  : 'a year',\n    yy : '%d years'\n};\n\nfunction relativeTime (number, withoutSuffix, string, isFuture) {\n    var output = this._relativeTime[string];\n    return (isFunction(output)) ?\n        output(number, withoutSuffix, string, isFuture) :\n        output.replace(/%d/i, number);\n}\n\nfunction pastFuture (diff, output) {\n    var format = this._relativeTime[diff > 0 ? 'future' : 'past'];\n    return isFunction(format) ? format(output) : format.replace(/%s/i, output);\n}\n\nvar aliases = {};\n\nfunction addUnitAlias (unit, shorthand) {\n    var lowerCase = unit.toLowerCase();\n    aliases[lowerCase] = aliases[lowerCase + 's'] = aliases[shorthand] = unit;\n}\n\nfunction normalizeUnits(units) {\n    return typeof units === 'string' ? aliases[units] || aliases[units.toLowerCase()] : undefined;\n}\n\nfunction normalizeObjectUnits(inputObject) {\n    var normalizedInput = {},\n        normalizedProp,\n        prop;\n\n    for (prop in inputObject) {\n        if (hasOwnProp(inputObject, prop)) {\n            normalizedProp = normalizeUnits(prop);\n            if (normalizedProp) {\n                normalizedInput[normalizedProp] = inputObject[prop];\n            }\n        }\n    }\n\n    return normalizedInput;\n}\n\nvar priorities = {};\n\nfunction addUnitPriority(unit, priority) {\n    priorities[unit] = priority;\n}\n\nfunction getPrioritizedUnits(unitsObj) {\n    var units = [];\n    for (var u in unitsObj) {\n        units.push({unit: u, priority: priorities[u]});\n    }\n    units.sort(function (a, b) {\n        return a.priority - b.priority;\n    });\n    return units;\n}\n\nfunction makeGetSet (unit, keepTime) {\n    return function (value) {\n        if (value != null) {\n            set$1(this, unit, value);\n            hooks.updateOffset(this, keepTime);\n            return this;\n        } else {\n            return get(this, unit);\n        }\n    };\n}\n\nfunction get (mom, unit) {\n    return mom.isValid() ?\n        mom._d['get' + (mom._isUTC ? 'UTC' : '') + unit]() : NaN;\n}\n\nfunction set$1 (mom, unit, value) {\n    if (mom.isValid()) {\n        mom._d['set' + (mom._isUTC ? 'UTC' : '') + unit](value);\n    }\n}\n\n// MOMENTS\n\nfunction stringGet (units) {\n    units = normalizeUnits(units);\n    if (isFunction(this[units])) {\n        return this[units]();\n    }\n    return this;\n}\n\n\nfunction stringSet (units, value) {\n    if (typeof units === 'object') {\n        units = normalizeObjectUnits(units);\n        var prioritized = getPrioritizedUnits(units);\n        for (var i = 0; i < prioritized.length; i++) {\n            this[prioritized[i].unit](units[prioritized[i].unit]);\n        }\n    } else {\n        units = normalizeUnits(units);\n        if (isFunction(this[units])) {\n            return this[units](value);\n        }\n    }\n    return this;\n}\n\nfunction zeroFill(number, targetLength, forceSign) {\n    var absNumber = '' + Math.abs(number),\n        zerosToFill = targetLength - absNumber.length,\n        sign = number >= 0;\n    return (sign ? (forceSign ? '+' : '') : '-') +\n        Math.pow(10, Math.max(0, zerosToFill)).toString().substr(1) + absNumber;\n}\n\nvar formattingTokens = /(\\[[^\\[]*\\])|(\\\\)?([Hh]mm(ss)?|Mo|MM?M?M?|Do|DDDo|DD?D?D?|ddd?d?|do?|w[o|w]?|W[o|W]?|Qo?|YYYYYY|YYYYY|YYYY|YY|gg(ggg?)?|GG(GGG?)?|e|E|a|A|hh?|HH?|kk?|mm?|ss?|S{1,9}|x|X|zz?|ZZ?|.)/g;\n\nvar localFormattingTokens = /(\\[[^\\[]*\\])|(\\\\)?(LTS|LT|LL?L?L?|l{1,4})/g;\n\nvar formatFunctions = {};\n\nvar formatTokenFunctions = {};\n\n// token:    'M'\n// padded:   ['MM', 2]\n// ordinal:  'Mo'\n// callback: function () { this.month() + 1 }\nfunction addFormatToken (token, padded, ordinal, callback) {\n    var func = callback;\n    if (typeof callback === 'string') {\n        func = function () {\n            return this[callback]();\n        };\n    }\n    if (token) {\n        formatTokenFunctions[token] = func;\n    }\n    if (padded) {\n        formatTokenFunctions[padded[0]] = function () {\n            return zeroFill(func.apply(this, arguments), padded[1], padded[2]);\n        };\n    }\n    if (ordinal) {\n        formatTokenFunctions[ordinal] = function () {\n            return this.localeData().ordinal(func.apply(this, arguments), token);\n        };\n    }\n}\n\nfunction removeFormattingTokens(input) {\n    if (input.match(/\\[[\\s\\S]/)) {\n        return input.replace(/^\\[|\\]$/g, '');\n    }\n    return input.replace(/\\\\/g, '');\n}\n\nfunction makeFormatFunction(format) {\n    var array = format.match(formattingTokens), i, length;\n\n    for (i = 0, length = array.length; i < length; i++) {\n        if (formatTokenFunctions[array[i]]) {\n            array[i] = formatTokenFunctions[array[i]];\n        } else {\n            array[i] = removeFormattingTokens(array[i]);\n        }\n    }\n\n    return function (mom) {\n        var output = '', i;\n        for (i = 0; i < length; i++) {\n            output += isFunction(array[i]) ? array[i].call(mom, format) : array[i];\n        }\n        return output;\n    };\n}\n\n// format date using native date object\nfunction formatMoment(m, format) {\n    if (!m.isValid()) {\n        return m.localeData().invalidDate();\n    }\n\n    format = expandFormat(format, m.localeData());\n    formatFunctions[format] = formatFunctions[format] || makeFormatFunction(format);\n\n    return formatFunctions[format](m);\n}\n\nfunction expandFormat(format, locale) {\n    var i = 5;\n\n    function replaceLongDateFormatTokens(input) {\n        return locale.longDateFormat(input) || input;\n    }\n\n    localFormattingTokens.lastIndex = 0;\n    while (i >= 0 && localFormattingTokens.test(format)) {\n        format = format.replace(localFormattingTokens, replaceLongDateFormatTokens);\n        localFormattingTokens.lastIndex = 0;\n        i -= 1;\n    }\n\n    return format;\n}\n\nvar match1         = /\\d/;            //       0 - 9\nvar match2         = /\\d\\d/;          //      00 - 99\nvar match3         = /\\d{3}/;         //     000 - 999\nvar match4         = /\\d{4}/;         //    0000 - 9999\nvar match6         = /[+-]?\\d{6}/;    // -999999 - 999999\nvar match1to2      = /\\d\\d?/;         //       0 - 99\nvar match3to4      = /\\d\\d\\d\\d?/;     //     999 - 9999\nvar match5to6      = /\\d\\d\\d\\d\\d\\d?/; //   99999 - 999999\nvar match1to3      = /\\d{1,3}/;       //       0 - 999\nvar match1to4      = /\\d{1,4}/;       //       0 - 9999\nvar match1to6      = /[+-]?\\d{1,6}/;  // -999999 - 999999\n\nvar matchUnsigned  = /\\d+/;           //       0 - inf\nvar matchSigned    = /[+-]?\\d+/;      //    -inf - inf\n\nvar matchOffset    = /Z|[+-]\\d\\d:?\\d\\d/gi; // +00:00 -00:00 +0000 -0000 or Z\nvar matchShortOffset = /Z|[+-]\\d\\d(?::?\\d\\d)?/gi; // +00 -00 +00:00 -00:00 +0000 -0000 or Z\n\nvar matchTimestamp = /[+-]?\\d+(\\.\\d{1,3})?/; // 123456789 123456789.123\n\n// any word (or two) characters or numbers including two/three word month in arabic.\n// includes scottish gaelic two word and hyphenated months\nvar matchWord = /[0-9]*['a-z\\u00A0-\\u05FF\\u0700-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF]+|[\\u0600-\\u06FF\\/]+(\\s*?[\\u0600-\\u06FF]+){1,2}/i;\n\n\nvar regexes = {};\n\nfunction addRegexToken (token, regex, strictRegex) {\n    regexes[token] = isFunction(regex) ? regex : function (isStrict, localeData) {\n        return (isStrict && strictRegex) ? strictRegex : regex;\n    };\n}\n\nfunction getParseRegexForToken (token, config) {\n    if (!hasOwnProp(regexes, token)) {\n        return new RegExp(unescapeFormat(token));\n    }\n\n    return regexes[token](config._strict, config._locale);\n}\n\n// Code from http://stackoverflow.com/questions/3561493/is-there-a-regexp-escape-function-in-javascript\nfunction unescapeFormat(s) {\n    return regexEscape(s.replace('\\\\', '').replace(/\\\\(\\[)|\\\\(\\])|\\[([^\\]\\[]*)\\]|\\\\(.)/g, function (matched, p1, p2, p3, p4) {\n        return p1 || p2 || p3 || p4;\n    }));\n}\n\nfunction regexEscape(s) {\n    return s.replace(/[-\\/\\\\^$*+?.()|[\\]{}]/g, '\\\\$&');\n}\n\nvar tokens = {};\n\nfunction addParseToken (token, callback) {\n    var i, func = callback;\n    if (typeof token === 'string') {\n        token = [token];\n    }\n    if (isNumber(callback)) {\n        func = function (input, array) {\n            array[callback] = toInt(input);\n        };\n    }\n    for (i = 0; i < token.length; i++) {\n        tokens[token[i]] = func;\n    }\n}\n\nfunction addWeekParseToken (token, callback) {\n    addParseToken(token, function (input, array, config, token) {\n        config._w = config._w || {};\n        callback(input, config._w, config, token);\n    });\n}\n\nfunction addTimeToArrayFromToken(token, input, config) {\n    if (input != null && hasOwnProp(tokens, token)) {\n        tokens[token](input, config._a, config, token);\n    }\n}\n\nvar YEAR = 0;\nvar MONTH = 1;\nvar DATE = 2;\nvar HOUR = 3;\nvar MINUTE = 4;\nvar SECOND = 5;\nvar MILLISECOND = 6;\nvar WEEK = 7;\nvar WEEKDAY = 8;\n\nvar indexOf;\n\nif (Array.prototype.indexOf) {\n    indexOf = Array.prototype.indexOf;\n} else {\n    indexOf = function (o) {\n        // I know\n        var i;\n        for (i = 0; i < this.length; ++i) {\n            if (this[i] === o) {\n                return i;\n            }\n        }\n        return -1;\n    };\n}\n\nvar indexOf$1 = indexOf;\n\nfunction daysInMonth(year, month) {\n    return new Date(Date.UTC(year, month + 1, 0)).getUTCDate();\n}\n\n// FORMATTING\n\naddFormatToken('M', ['MM', 2], 'Mo', function () {\n    return this.month() + 1;\n});\n\naddFormatToken('MMM', 0, 0, function (format) {\n    return this.localeData().monthsShort(this, format);\n});\n\naddFormatToken('MMMM', 0, 0, function (format) {\n    return this.localeData().months(this, format);\n});\n\n// ALIASES\n\naddUnitAlias('month', 'M');\n\n// PRIORITY\n\naddUnitPriority('month', 8);\n\n// PARSING\n\naddRegexToken('M',    match1to2);\naddRegexToken('MM',   match1to2, match2);\naddRegexToken('MMM',  function (isStrict, locale) {\n    return locale.monthsShortRegex(isStrict);\n});\naddRegexToken('MMMM', function (isStrict, locale) {\n    return locale.monthsRegex(isStrict);\n});\n\naddParseToken(['M', 'MM'], function (input, array) {\n    array[MONTH] = toInt(input) - 1;\n});\n\naddParseToken(['MMM', 'MMMM'], function (input, array, config, token) {\n    var month = config._locale.monthsParse(input, token, config._strict);\n    // if we didn't find a month name, mark the date as invalid.\n    if (month != null) {\n        array[MONTH] = month;\n    } else {\n        getParsingFlags(config).invalidMonth = input;\n    }\n});\n\n// LOCALES\n\nvar MONTHS_IN_FORMAT = /D[oD]?(\\[[^\\[\\]]*\\]|\\s)+MMMM?/;\nvar defaultLocaleMonths = 'January_February_March_April_May_June_July_August_September_October_November_December'.split('_');\nfunction localeMonths (m, format) {\n    if (!m) {\n        return isArray(this._months) ? this._months :\n            this._months['standalone'];\n    }\n    return isArray(this._months) ? this._months[m.month()] :\n        this._months[(this._months.isFormat || MONTHS_IN_FORMAT).test(format) ? 'format' : 'standalone'][m.month()];\n}\n\nvar defaultLocaleMonthsShort = 'Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec'.split('_');\nfunction localeMonthsShort (m, format) {\n    if (!m) {\n        return isArray(this._monthsShort) ? this._monthsShort :\n            this._monthsShort['standalone'];\n    }\n    return isArray(this._monthsShort) ? this._monthsShort[m.month()] :\n        this._monthsShort[MONTHS_IN_FORMAT.test(format) ? 'format' : 'standalone'][m.month()];\n}\n\nfunction handleStrictParse(monthName, format, strict) {\n    var i, ii, mom, llc = monthName.toLocaleLowerCase();\n    if (!this._monthsParse) {\n        // this is not used\n        this._monthsParse = [];\n        this._longMonthsParse = [];\n        this._shortMonthsParse = [];\n        for (i = 0; i < 12; ++i) {\n            mom = createUTC([2000, i]);\n            this._shortMonthsParse[i] = this.monthsShort(mom, '').toLocaleLowerCase();\n            this._longMonthsParse[i] = this.months(mom, '').toLocaleLowerCase();\n        }\n    }\n\n    if (strict) {\n        if (format === 'MMM') {\n            ii = indexOf$1.call(this._shortMonthsParse, llc);\n            return ii !== -1 ? ii : null;\n        } else {\n            ii = indexOf$1.call(this._longMonthsParse, llc);\n            return ii !== -1 ? ii : null;\n        }\n    } else {\n        if (format === 'MMM') {\n            ii = indexOf$1.call(this._shortMonthsParse, llc);\n            if (ii !== -1) {\n                return ii;\n            }\n            ii = indexOf$1.call(this._longMonthsParse, llc);\n            return ii !== -1 ? ii : null;\n        } else {\n            ii = indexOf$1.call(this._longMonthsParse, llc);\n            if (ii !== -1) {\n                return ii;\n            }\n            ii = indexOf$1.call(this._shortMonthsParse, llc);\n            return ii !== -1 ? ii : null;\n        }\n    }\n}\n\nfunction localeMonthsParse (monthName, format, strict) {\n    var i, mom, regex;\n\n    if (this._monthsParseExact) {\n        return handleStrictParse.call(this, monthName, format, strict);\n    }\n\n    if (!this._monthsParse) {\n        this._monthsParse = [];\n        this._longMonthsParse = [];\n        this._shortMonthsParse = [];\n    }\n\n    // TODO: add sorting\n    // Sorting makes sure if one month (or abbr) is a prefix of another\n    // see sorting in computeMonthsParse\n    for (i = 0; i < 12; i++) {\n        // make the regex if we don't have it already\n        mom = createUTC([2000, i]);\n        if (strict && !this._longMonthsParse[i]) {\n            this._longMonthsParse[i] = new RegExp('^' + this.months(mom, '').replace('.', '') + '$', 'i');\n            this._shortMonthsParse[i] = new RegExp('^' + this.monthsShort(mom, '').replace('.', '') + '$', 'i');\n        }\n        if (!strict && !this._monthsParse[i]) {\n            regex = '^' + this.months(mom, '') + '|^' + this.monthsShort(mom, '');\n            this._monthsParse[i] = new RegExp(regex.replace('.', ''), 'i');\n        }\n        // test the regex\n        if (strict && format === 'MMMM' && this._longMonthsParse[i].test(monthName)) {\n            return i;\n        } else if (strict && format === 'MMM' && this._shortMonthsParse[i].test(monthName)) {\n            return i;\n        } else if (!strict && this._monthsParse[i].test(monthName)) {\n            return i;\n        }\n    }\n}\n\n// MOMENTS\n\nfunction setMonth (mom, value) {\n    var dayOfMonth;\n\n    if (!mom.isValid()) {\n        // No op\n        return mom;\n    }\n\n    if (typeof value === 'string') {\n        if (/^\\d+$/.test(value)) {\n            value = toInt(value);\n        } else {\n            value = mom.localeData().monthsParse(value);\n            // TODO: Another silent failure?\n            if (!isNumber(value)) {\n                return mom;\n            }\n        }\n    }\n\n    dayOfMonth = Math.min(mom.date(), daysInMonth(mom.year(), value));\n    mom._d['set' + (mom._isUTC ? 'UTC' : '') + 'Month'](value, dayOfMonth);\n    return mom;\n}\n\nfunction getSetMonth (value) {\n    if (value != null) {\n        setMonth(this, value);\n        hooks.updateOffset(this, true);\n        return this;\n    } else {\n        return get(this, 'Month');\n    }\n}\n\nfunction getDaysInMonth () {\n    return daysInMonth(this.year(), this.month());\n}\n\nvar defaultMonthsShortRegex = matchWord;\nfunction monthsShortRegex (isStrict) {\n    if (this._monthsParseExact) {\n        if (!hasOwnProp(this, '_monthsRegex')) {\n            computeMonthsParse.call(this);\n        }\n        if (isStrict) {\n            return this._monthsShortStrictRegex;\n        } else {\n            return this._monthsShortRegex;\n        }\n    } else {\n        if (!hasOwnProp(this, '_monthsShortRegex')) {\n            this._monthsShortRegex = defaultMonthsShortRegex;\n        }\n        return this._monthsShortStrictRegex && isStrict ?\n            this._monthsShortStrictRegex : this._monthsShortRegex;\n    }\n}\n\nvar defaultMonthsRegex = matchWord;\nfunction monthsRegex (isStrict) {\n    if (this._monthsParseExact) {\n        if (!hasOwnProp(this, '_monthsRegex')) {\n            computeMonthsParse.call(this);\n        }\n        if (isStrict) {\n            return this._monthsStrictRegex;\n        } else {\n            return this._monthsRegex;\n        }\n    } else {\n        if (!hasOwnProp(this, '_monthsRegex')) {\n            this._monthsRegex = defaultMonthsRegex;\n        }\n        return this._monthsStrictRegex && isStrict ?\n            this._monthsStrictRegex : this._monthsRegex;\n    }\n}\n\nfunction computeMonthsParse () {\n    function cmpLenRev(a, b) {\n        return b.length - a.length;\n    }\n\n    var shortPieces = [], longPieces = [], mixedPieces = [],\n        i, mom;\n    for (i = 0; i < 12; i++) {\n        // make the regex if we don't have it already\n        mom = createUTC([2000, i]);\n        shortPieces.push(this.monthsShort(mom, ''));\n        longPieces.push(this.months(mom, ''));\n        mixedPieces.push(this.months(mom, ''));\n        mixedPieces.push(this.monthsShort(mom, ''));\n    }\n    // Sorting makes sure if one month (or abbr) is a prefix of another it\n    // will match the longer piece.\n    shortPieces.sort(cmpLenRev);\n    longPieces.sort(cmpLenRev);\n    mixedPieces.sort(cmpLenRev);\n    for (i = 0; i < 12; i++) {\n        shortPieces[i] = regexEscape(shortPieces[i]);\n        longPieces[i] = regexEscape(longPieces[i]);\n    }\n    for (i = 0; i < 24; i++) {\n        mixedPieces[i] = regexEscape(mixedPieces[i]);\n    }\n\n    this._monthsRegex = new RegExp('^(' + mixedPieces.join('|') + ')', 'i');\n    this._monthsShortRegex = this._monthsRegex;\n    this._monthsStrictRegex = new RegExp('^(' + longPieces.join('|') + ')', 'i');\n    this._monthsShortStrictRegex = new RegExp('^(' + shortPieces.join('|') + ')', 'i');\n}\n\n// FORMATTING\n\naddFormatToken('Y', 0, 0, function () {\n    var y = this.year();\n    return y <= 9999 ? '' + y : '+' + y;\n});\n\naddFormatToken(0, ['YY', 2], 0, function () {\n    return this.year() % 100;\n});\n\naddFormatToken(0, ['YYYY',   4],       0, 'year');\naddFormatToken(0, ['YYYYY',  5],       0, 'year');\naddFormatToken(0, ['YYYYYY', 6, true], 0, 'year');\n\n// ALIASES\n\naddUnitAlias('year', 'y');\n\n// PRIORITIES\n\naddUnitPriority('year', 1);\n\n// PARSING\n\naddRegexToken('Y',      matchSigned);\naddRegexToken('YY',     match1to2, match2);\naddRegexToken('YYYY',   match1to4, match4);\naddRegexToken('YYYYY',  match1to6, match6);\naddRegexToken('YYYYYY', match1to6, match6);\n\naddParseToken(['YYYYY', 'YYYYYY'], YEAR);\naddParseToken('YYYY', function (input, array) {\n    array[YEAR] = input.length === 2 ? hooks.parseTwoDigitYear(input) : toInt(input);\n});\naddParseToken('YY', function (input, array) {\n    array[YEAR] = hooks.parseTwoDigitYear(input);\n});\naddParseToken('Y', function (input, array) {\n    array[YEAR] = parseInt(input, 10);\n});\n\n// HELPERS\n\nfunction daysInYear(year) {\n    return isLeapYear(year) ? 366 : 365;\n}\n\nfunction isLeapYear(year) {\n    return (year % 4 === 0 && year % 100 !== 0) || year % 400 === 0;\n}\n\n// HOOKS\n\nhooks.parseTwoDigitYear = function (input) {\n    return toInt(input) + (toInt(input) > 68 ? 1900 : 2000);\n};\n\n// MOMENTS\n\nvar getSetYear = makeGetSet('FullYear', true);\n\nfunction getIsLeapYear () {\n    return isLeapYear(this.year());\n}\n\nfunction createDate (y, m, d, h, M, s, ms) {\n    // can't just apply() to create a date:\n    // https://stackoverflow.com/q/181348\n    var date = new Date(y, m, d, h, M, s, ms);\n\n    // the date constructor remaps years 0-99 to 1900-1999\n    if (y < 100 && y >= 0 && isFinite(date.getFullYear())) {\n        date.setFullYear(y);\n    }\n    return date;\n}\n\nfunction createUTCDate (y) {\n    var date = new Date(Date.UTC.apply(null, arguments));\n\n    // the Date.UTC function remaps years 0-99 to 1900-1999\n    if (y < 100 && y >= 0 && isFinite(date.getUTCFullYear())) {\n        date.setUTCFullYear(y);\n    }\n    return date;\n}\n\n// start-of-first-week - start-of-year\nfunction firstWeekOffset(year, dow, doy) {\n    var // first-week day -- which january is always in the first week (4 for iso, 1 for other)\n        fwd = 7 + dow - doy,\n        // first-week day local weekday -- which local weekday is fwd\n        fwdlw = (7 + createUTCDate(year, 0, fwd).getUTCDay() - dow) % 7;\n\n    return -fwdlw + fwd - 1;\n}\n\n// https://en.wikipedia.org/wiki/ISO_week_date#Calculating_a_date_given_the_year.2C_week_number_and_weekday\nfunction dayOfYearFromWeeks(year, week, weekday, dow, doy) {\n    var localWeekday = (7 + weekday - dow) % 7,\n        weekOffset = firstWeekOffset(year, dow, doy),\n        dayOfYear = 1 + 7 * (week - 1) + localWeekday + weekOffset,\n        resYear, resDayOfYear;\n\n    if (dayOfYear <= 0) {\n        resYear = year - 1;\n        resDayOfYear = daysInYear(resYear) + dayOfYear;\n    } else if (dayOfYear > daysInYear(year)) {\n        resYear = year + 1;\n        resDayOfYear = dayOfYear - daysInYear(year);\n    } else {\n        resYear = year;\n        resDayOfYear = dayOfYear;\n    }\n\n    return {\n        year: resYear,\n        dayOfYear: resDayOfYear\n    };\n}\n\nfunction weekOfYear(mom, dow, doy) {\n    var weekOffset = firstWeekOffset(mom.year(), dow, doy),\n        week = Math.floor((mom.dayOfYear() - weekOffset - 1) / 7) + 1,\n        resWeek, resYear;\n\n    if (week < 1) {\n        resYear = mom.year() - 1;\n        resWeek = week + weeksInYear(resYear, dow, doy);\n    } else if (week > weeksInYear(mom.year(), dow, doy)) {\n        resWeek = week - weeksInYear(mom.year(), dow, doy);\n        resYear = mom.year() + 1;\n    } else {\n        resYear = mom.year();\n        resWeek = week;\n    }\n\n    return {\n        week: resWeek,\n        year: resYear\n    };\n}\n\nfunction weeksInYear(year, dow, doy) {\n    var weekOffset = firstWeekOffset(year, dow, doy),\n        weekOffsetNext = firstWeekOffset(year + 1, dow, doy);\n    return (daysInYear(year) - weekOffset + weekOffsetNext) / 7;\n}\n\n// FORMATTING\n\naddFormatToken('w', ['ww', 2], 'wo', 'week');\naddFormatToken('W', ['WW', 2], 'Wo', 'isoWeek');\n\n// ALIASES\n\naddUnitAlias('week', 'w');\naddUnitAlias('isoWeek', 'W');\n\n// PRIORITIES\n\naddUnitPriority('week', 5);\naddUnitPriority('isoWeek', 5);\n\n// PARSING\n\naddRegexToken('w',  match1to2);\naddRegexToken('ww', match1to2, match2);\naddRegexToken('W',  match1to2);\naddRegexToken('WW', match1to2, match2);\n\naddWeekParseToken(['w', 'ww', 'W', 'WW'], function (input, week, config, token) {\n    week[token.substr(0, 1)] = toInt(input);\n});\n\n// HELPERS\n\n// LOCALES\n\nfunction localeWeek (mom) {\n    return weekOfYear(mom, this._week.dow, this._week.doy).week;\n}\n\nvar defaultLocaleWeek = {\n    dow : 0, // Sunday is the first day of the week.\n    doy : 6  // The week that contains Jan 1st is the first week of the year.\n};\n\nfunction localeFirstDayOfWeek () {\n    return this._week.dow;\n}\n\nfunction localeFirstDayOfYear () {\n    return this._week.doy;\n}\n\n// MOMENTS\n\nfunction getSetWeek (input) {\n    var week = this.localeData().week(this);\n    return input == null ? week : this.add((input - week) * 7, 'd');\n}\n\nfunction getSetISOWeek (input) {\n    var week = weekOfYear(this, 1, 4).week;\n    return input == null ? week : this.add((input - week) * 7, 'd');\n}\n\n// FORMATTING\n\naddFormatToken('d', 0, 'do', 'day');\n\naddFormatToken('dd', 0, 0, function (format) {\n    return this.localeData().weekdaysMin(this, format);\n});\n\naddFormatToken('ddd', 0, 0, function (format) {\n    return this.localeData().weekdaysShort(this, format);\n});\n\naddFormatToken('dddd', 0, 0, function (format) {\n    return this.localeData().weekdays(this, format);\n});\n\naddFormatToken('e', 0, 0, 'weekday');\naddFormatToken('E', 0, 0, 'isoWeekday');\n\n// ALIASES\n\naddUnitAlias('day', 'd');\naddUnitAlias('weekday', 'e');\naddUnitAlias('isoWeekday', 'E');\n\n// PRIORITY\naddUnitPriority('day', 11);\naddUnitPriority('weekday', 11);\naddUnitPriority('isoWeekday', 11);\n\n// PARSING\n\naddRegexToken('d',    match1to2);\naddRegexToken('e',    match1to2);\naddRegexToken('E',    match1to2);\naddRegexToken('dd',   function (isStrict, locale) {\n    return locale.weekdaysMinRegex(isStrict);\n});\naddRegexToken('ddd',   function (isStrict, locale) {\n    return locale.weekdaysShortRegex(isStrict);\n});\naddRegexToken('dddd',   function (isStrict, locale) {\n    return locale.weekdaysRegex(isStrict);\n});\n\naddWeekParseToken(['dd', 'ddd', 'dddd'], function (input, week, config, token) {\n    var weekday = config._locale.weekdaysParse(input, token, config._strict);\n    // if we didn't get a weekday name, mark the date as invalid\n    if (weekday != null) {\n        week.d = weekday;\n    } else {\n        getParsingFlags(config).invalidWeekday = input;\n    }\n});\n\naddWeekParseToken(['d', 'e', 'E'], function (input, week, config, token) {\n    week[token] = toInt(input);\n});\n\n// HELPERS\n\nfunction parseWeekday(input, locale) {\n    if (typeof input !== 'string') {\n        return input;\n    }\n\n    if (!isNaN(input)) {\n        return parseInt(input, 10);\n    }\n\n    input = locale.weekdaysParse(input);\n    if (typeof input === 'number') {\n        return input;\n    }\n\n    return null;\n}\n\nfunction parseIsoWeekday(input, locale) {\n    if (typeof input === 'string') {\n        return locale.weekdaysParse(input) % 7 || 7;\n    }\n    return isNaN(input) ? null : input;\n}\n\n// LOCALES\n\nvar defaultLocaleWeekdays = 'Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday'.split('_');\nfunction localeWeekdays (m, format) {\n    if (!m) {\n        return isArray(this._weekdays) ? this._weekdays :\n            this._weekdays['standalone'];\n    }\n    return isArray(this._weekdays) ? this._weekdays[m.day()] :\n        this._weekdays[this._weekdays.isFormat.test(format) ? 'format' : 'standalone'][m.day()];\n}\n\nvar defaultLocaleWeekdaysShort = 'Sun_Mon_Tue_Wed_Thu_Fri_Sat'.split('_');\nfunction localeWeekdaysShort (m) {\n    return (m) ? this._weekdaysShort[m.day()] : this._weekdaysShort;\n}\n\nvar defaultLocaleWeekdaysMin = 'Su_Mo_Tu_We_Th_Fr_Sa'.split('_');\nfunction localeWeekdaysMin (m) {\n    return (m) ? this._weekdaysMin[m.day()] : this._weekdaysMin;\n}\n\nfunction handleStrictParse$1(weekdayName, format, strict) {\n    var i, ii, mom, llc = weekdayName.toLocaleLowerCase();\n    if (!this._weekdaysParse) {\n        this._weekdaysParse = [];\n        this._shortWeekdaysParse = [];\n        this._minWeekdaysParse = [];\n\n        for (i = 0; i < 7; ++i) {\n            mom = createUTC([2000, 1]).day(i);\n            this._minWeekdaysParse[i] = this.weekdaysMin(mom, '').toLocaleLowerCase();\n            this._shortWeekdaysParse[i] = this.weekdaysShort(mom, '').toLocaleLowerCase();\n            this._weekdaysParse[i] = this.weekdays(mom, '').toLocaleLowerCase();\n        }\n    }\n\n    if (strict) {\n        if (format === 'dddd') {\n            ii = indexOf$1.call(this._weekdaysParse, llc);\n            return ii !== -1 ? ii : null;\n        } else if (format === 'ddd') {\n            ii = indexOf$1.call(this._shortWeekdaysParse, llc);\n            return ii !== -1 ? ii : null;\n        } else {\n            ii = indexOf$1.call(this._minWeekdaysParse, llc);\n            return ii !== -1 ? ii : null;\n        }\n    } else {\n        if (format === 'dddd') {\n            ii = indexOf$1.call(this._weekdaysParse, llc);\n            if (ii !== -1) {\n                return ii;\n            }\n            ii = indexOf$1.call(this._shortWeekdaysParse, llc);\n            if (ii !== -1) {\n                return ii;\n            }\n            ii = indexOf$1.call(this._minWeekdaysParse, llc);\n            return ii !== -1 ? ii : null;\n        } else if (format === 'ddd') {\n            ii = indexOf$1.call(this._shortWeekdaysParse, llc);\n            if (ii !== -1) {\n                return ii;\n            }\n            ii = indexOf$1.call(this._weekdaysParse, llc);\n            if (ii !== -1) {\n                return ii;\n            }\n            ii = indexOf$1.call(this._minWeekdaysParse, llc);\n            return ii !== -1 ? ii : null;\n        } else {\n            ii = indexOf$1.call(this._minWeekdaysParse, llc);\n            if (ii !== -1) {\n                return ii;\n            }\n            ii = indexOf$1.call(this._weekdaysParse, llc);\n            if (ii !== -1) {\n                return ii;\n            }\n            ii = indexOf$1.call(this._shortWeekdaysParse, llc);\n            return ii !== -1 ? ii : null;\n        }\n    }\n}\n\nfunction localeWeekdaysParse (weekdayName, format, strict) {\n    var i, mom, regex;\n\n    if (this._weekdaysParseExact) {\n        return handleStrictParse$1.call(this, weekdayName, format, strict);\n    }\n\n    if (!this._weekdaysParse) {\n        this._weekdaysParse = [];\n        this._minWeekdaysParse = [];\n        this._shortWeekdaysParse = [];\n        this._fullWeekdaysParse = [];\n    }\n\n    for (i = 0; i < 7; i++) {\n        // make the regex if we don't have it already\n\n        mom = createUTC([2000, 1]).day(i);\n        if (strict && !this._fullWeekdaysParse[i]) {\n            this._fullWeekdaysParse[i] = new RegExp('^' + this.weekdays(mom, '').replace('.', '\\.?') + '$', 'i');\n            this._shortWeekdaysParse[i] = new RegExp('^' + this.weekdaysShort(mom, '').replace('.', '\\.?') + '$', 'i');\n            this._minWeekdaysParse[i] = new RegExp('^' + this.weekdaysMin(mom, '').replace('.', '\\.?') + '$', 'i');\n        }\n        if (!this._weekdaysParse[i]) {\n            regex = '^' + this.weekdays(mom, '') + '|^' + this.weekdaysShort(mom, '') + '|^' + this.weekdaysMin(mom, '');\n            this._weekdaysParse[i] = new RegExp(regex.replace('.', ''), 'i');\n        }\n        // test the regex\n        if (strict && format === 'dddd' && this._fullWeekdaysParse[i].test(weekdayName)) {\n            return i;\n        } else if (strict && format === 'ddd' && this._shortWeekdaysParse[i].test(weekdayName)) {\n            return i;\n        } else if (strict && format === 'dd' && this._minWeekdaysParse[i].test(weekdayName)) {\n            return i;\n        } else if (!strict && this._weekdaysParse[i].test(weekdayName)) {\n            return i;\n        }\n    }\n}\n\n// MOMENTS\n\nfunction getSetDayOfWeek (input) {\n    if (!this.isValid()) {\n        return input != null ? this : NaN;\n    }\n    var day = this._isUTC ? this._d.getUTCDay() : this._d.getDay();\n    if (input != null) {\n        input = parseWeekday(input, this.localeData());\n        return this.add(input - day, 'd');\n    } else {\n        return day;\n    }\n}\n\nfunction getSetLocaleDayOfWeek (input) {\n    if (!this.isValid()) {\n        return input != null ? this : NaN;\n    }\n    var weekday = (this.day() + 7 - this.localeData()._week.dow) % 7;\n    return input == null ? weekday : this.add(input - weekday, 'd');\n}\n\nfunction getSetISODayOfWeek (input) {\n    if (!this.isValid()) {\n        return input != null ? this : NaN;\n    }\n\n    // behaves the same as moment#day except\n    // as a getter, returns 7 instead of 0 (1-7 range instead of 0-6)\n    // as a setter, sunday should belong to the previous week.\n\n    if (input != null) {\n        var weekday = parseIsoWeekday(input, this.localeData());\n        return this.day(this.day() % 7 ? weekday : weekday - 7);\n    } else {\n        return this.day() || 7;\n    }\n}\n\nvar defaultWeekdaysRegex = matchWord;\nfunction weekdaysRegex (isStrict) {\n    if (this._weekdaysParseExact) {\n        if (!hasOwnProp(this, '_weekdaysRegex')) {\n            computeWeekdaysParse.call(this);\n        }\n        if (isStrict) {\n            return this._weekdaysStrictRegex;\n        } else {\n            return this._weekdaysRegex;\n        }\n    } else {\n        if (!hasOwnProp(this, '_weekdaysRegex')) {\n            this._weekdaysRegex = defaultWeekdaysRegex;\n        }\n        return this._weekdaysStrictRegex && isStrict ?\n            this._weekdaysStrictRegex : this._weekdaysRegex;\n    }\n}\n\nvar defaultWeekdaysShortRegex = matchWord;\nfunction weekdaysShortRegex (isStrict) {\n    if (this._weekdaysParseExact) {\n        if (!hasOwnProp(this, '_weekdaysRegex')) {\n            computeWeekdaysParse.call(this);\n        }\n        if (isStrict) {\n            return this._weekdaysShortStrictRegex;\n        } else {\n            return this._weekdaysShortRegex;\n        }\n    } else {\n        if (!hasOwnProp(this, '_weekdaysShortRegex')) {\n            this._weekdaysShortRegex = defaultWeekdaysShortRegex;\n        }\n        return this._weekdaysShortStrictRegex && isStrict ?\n            this._weekdaysShortStrictRegex : this._weekdaysShortRegex;\n    }\n}\n\nvar defaultWeekdaysMinRegex = matchWord;\nfunction weekdaysMinRegex (isStrict) {\n    if (this._weekdaysParseExact) {\n        if (!hasOwnProp(this, '_weekdaysRegex')) {\n            computeWeekdaysParse.call(this);\n        }\n        if (isStrict) {\n            return this._weekdaysMinStrictRegex;\n        } else {\n            return this._weekdaysMinRegex;\n        }\n    } else {\n        if (!hasOwnProp(this, '_weekdaysMinRegex')) {\n            this._weekdaysMinRegex = defaultWeekdaysMinRegex;\n        }\n        return this._weekdaysMinStrictRegex && isStrict ?\n            this._weekdaysMinStrictRegex : this._weekdaysMinRegex;\n    }\n}\n\n\nfunction computeWeekdaysParse () {\n    function cmpLenRev(a, b) {\n        return b.length - a.length;\n    }\n\n    var minPieces = [], shortPieces = [], longPieces = [], mixedPieces = [],\n        i, mom, minp, shortp, longp;\n    for (i = 0; i < 7; i++) {\n        // make the regex if we don't have it already\n        mom = createUTC([2000, 1]).day(i);\n        minp = this.weekdaysMin(mom, '');\n        shortp = this.weekdaysShort(mom, '');\n        longp = this.weekdays(mom, '');\n        minPieces.push(minp);\n        shortPieces.push(shortp);\n        longPieces.push(longp);\n        mixedPieces.push(minp);\n        mixedPieces.push(shortp);\n        mixedPieces.push(longp);\n    }\n    // Sorting makes sure if one weekday (or abbr) is a prefix of another it\n    // will match the longer piece.\n    minPieces.sort(cmpLenRev);\n    shortPieces.sort(cmpLenRev);\n    longPieces.sort(cmpLenRev);\n    mixedPieces.sort(cmpLenRev);\n    for (i = 0; i < 7; i++) {\n        shortPieces[i] = regexEscape(shortPieces[i]);\n        longPieces[i] = regexEscape(longPieces[i]);\n        mixedPieces[i] = regexEscape(mixedPieces[i]);\n    }\n\n    this._weekdaysRegex = new RegExp('^(' + mixedPieces.join('|') + ')', 'i');\n    this._weekdaysShortRegex = this._weekdaysRegex;\n    this._weekdaysMinRegex = this._weekdaysRegex;\n\n    this._weekdaysStrictRegex = new RegExp('^(' + longPieces.join('|') + ')', 'i');\n    this._weekdaysShortStrictRegex = new RegExp('^(' + shortPieces.join('|') + ')', 'i');\n    this._weekdaysMinStrictRegex = new RegExp('^(' + minPieces.join('|') + ')', 'i');\n}\n\n// FORMATTING\n\nfunction hFormat() {\n    return this.hours() % 12 || 12;\n}\n\nfunction kFormat() {\n    return this.hours() || 24;\n}\n\naddFormatToken('H', ['HH', 2], 0, 'hour');\naddFormatToken('h', ['hh', 2], 0, hFormat);\naddFormatToken('k', ['kk', 2], 0, kFormat);\n\naddFormatToken('hmm', 0, 0, function () {\n    return '' + hFormat.apply(this) + zeroFill(this.minutes(), 2);\n});\n\naddFormatToken('hmmss', 0, 0, function () {\n    return '' + hFormat.apply(this) + zeroFill(this.minutes(), 2) +\n        zeroFill(this.seconds(), 2);\n});\n\naddFormatToken('Hmm', 0, 0, function () {\n    return '' + this.hours() + zeroFill(this.minutes(), 2);\n});\n\naddFormatToken('Hmmss', 0, 0, function () {\n    return '' + this.hours() + zeroFill(this.minutes(), 2) +\n        zeroFill(this.seconds(), 2);\n});\n\nfunction meridiem (token, lowercase) {\n    addFormatToken(token, 0, 0, function () {\n        return this.localeData().meridiem(this.hours(), this.minutes(), lowercase);\n    });\n}\n\nmeridiem('a', true);\nmeridiem('A', false);\n\n// ALIASES\n\naddUnitAlias('hour', 'h');\n\n// PRIORITY\naddUnitPriority('hour', 13);\n\n// PARSING\n\nfunction matchMeridiem (isStrict, locale) {\n    return locale._meridiemParse;\n}\n\naddRegexToken('a',  matchMeridiem);\naddRegexToken('A',  matchMeridiem);\naddRegexToken('H',  match1to2);\naddRegexToken('h',  match1to2);\naddRegexToken('k',  match1to2);\naddRegexToken('HH', match1to2, match2);\naddRegexToken('hh', match1to2, match2);\naddRegexToken('kk', match1to2, match2);\n\naddRegexToken('hmm', match3to4);\naddRegexToken('hmmss', match5to6);\naddRegexToken('Hmm', match3to4);\naddRegexToken('Hmmss', match5to6);\n\naddParseToken(['H', 'HH'], HOUR);\naddParseToken(['k', 'kk'], function (input, array, config) {\n    var kInput = toInt(input);\n    array[HOUR] = kInput === 24 ? 0 : kInput;\n});\naddParseToken(['a', 'A'], function (input, array, config) {\n    config._isPm = config._locale.isPM(input);\n    config._meridiem = input;\n});\naddParseToken(['h', 'hh'], function (input, array, config) {\n    array[HOUR] = toInt(input);\n    getParsingFlags(config).bigHour = true;\n});\naddParseToken('hmm', function (input, array, config) {\n    var pos = input.length - 2;\n    array[HOUR] = toInt(input.substr(0, pos));\n    array[MINUTE] = toInt(input.substr(pos));\n    getParsingFlags(config).bigHour = true;\n});\naddParseToken('hmmss', function (input, array, config) {\n    var pos1 = input.length - 4;\n    var pos2 = input.length - 2;\n    array[HOUR] = toInt(input.substr(0, pos1));\n    array[MINUTE] = toInt(input.substr(pos1, 2));\n    array[SECOND] = toInt(input.substr(pos2));\n    getParsingFlags(config).bigHour = true;\n});\naddParseToken('Hmm', function (input, array, config) {\n    var pos = input.length - 2;\n    array[HOUR] = toInt(input.substr(0, pos));\n    array[MINUTE] = toInt(input.substr(pos));\n});\naddParseToken('Hmmss', function (input, array, config) {\n    var pos1 = input.length - 4;\n    var pos2 = input.length - 2;\n    array[HOUR] = toInt(input.substr(0, pos1));\n    array[MINUTE] = toInt(input.substr(pos1, 2));\n    array[SECOND] = toInt(input.substr(pos2));\n});\n\n// LOCALES\n\nfunction localeIsPM (input) {\n    // IE8 Quirks Mode & IE7 Standards Mode do not allow accessing strings like arrays\n    // Using charAt should be more compatible.\n    return ((input + '').toLowerCase().charAt(0) === 'p');\n}\n\nvar defaultLocaleMeridiemParse = /[ap]\\.?m?\\.?/i;\nfunction localeMeridiem (hours, minutes, isLower) {\n    if (hours > 11) {\n        return isLower ? 'pm' : 'PM';\n    } else {\n        return isLower ? 'am' : 'AM';\n    }\n}\n\n\n// MOMENTS\n\n// Setting the hour should keep the time, because the user explicitly\n// specified which hour he wants. So trying to maintain the same hour (in\n// a new timezone) makes sense. Adding/subtracting hours does not follow\n// this rule.\nvar getSetHour = makeGetSet('Hours', true);\n\n// months\n// week\n// weekdays\n// meridiem\nvar baseConfig = {\n    calendar: defaultCalendar,\n    longDateFormat: defaultLongDateFormat,\n    invalidDate: defaultInvalidDate,\n    ordinal: defaultOrdinal,\n    dayOfMonthOrdinalParse: defaultDayOfMonthOrdinalParse,\n    relativeTime: defaultRelativeTime,\n\n    months: defaultLocaleMonths,\n    monthsShort: defaultLocaleMonthsShort,\n\n    week: defaultLocaleWeek,\n\n    weekdays: defaultLocaleWeekdays,\n    weekdaysMin: defaultLocaleWeekdaysMin,\n    weekdaysShort: defaultLocaleWeekdaysShort,\n\n    meridiemParse: defaultLocaleMeridiemParse\n};\n\n// internal storage for locale config files\nvar locales = {};\nvar localeFamilies = {};\nvar globalLocale;\n\nfunction normalizeLocale(key) {\n    return key ? key.toLowerCase().replace('_', '-') : key;\n}\n\n// pick the locale from the array\n// try ['en-au', 'en-gb'] as 'en-au', 'en-gb', 'en', as in move through the list trying each\n// substring from most specific to least, but move to the next array item if it's a more specific variant than the current root\nfunction chooseLocale(names) {\n    var i = 0, j, next, locale, split;\n\n    while (i < names.length) {\n        split = normalizeLocale(names[i]).split('-');\n        j = split.length;\n        next = normalizeLocale(names[i + 1]);\n        next = next ? next.split('-') : null;\n        while (j > 0) {\n            locale = loadLocale(split.slice(0, j).join('-'));\n            if (locale) {\n                return locale;\n            }\n            if (next && next.length >= j && compareArrays(split, next, true) >= j - 1) {\n                //the next array item is better than a shallower substring of this one\n                break;\n            }\n            j--;\n        }\n        i++;\n    }\n    return null;\n}\n\nfunction loadLocale(name) {\n    var oldLocale = null;\n    // TODO: Find a better way to register and load all the locales in Node\n    if (!locales[name] && (typeof module !== 'undefined') &&\n            module && module.exports) {\n        try {\n            oldLocale = globalLocale._abbr;\n            require('./locale/' + name);\n            // because defineLocale currently also sets the global locale, we\n            // want to undo that for lazy loaded locales\n            getSetGlobalLocale(oldLocale);\n        } catch (e) { }\n    }\n    return locales[name];\n}\n\n// This function will load locale and then set the global locale.  If\n// no arguments are passed in, it will simply return the current global\n// locale key.\nfunction getSetGlobalLocale (key, values) {\n    var data;\n    if (key) {\n        if (isUndefined(values)) {\n            data = getLocale(key);\n        }\n        else {\n            data = defineLocale(key, values);\n        }\n\n        if (data) {\n            // moment.duration._locale = moment._locale = data;\n            globalLocale = data;\n        }\n    }\n\n    return globalLocale._abbr;\n}\n\nfunction defineLocale (name, config) {\n    if (config !== null) {\n        var parentConfig = baseConfig;\n        config.abbr = name;\n        if (locales[name] != null) {\n            deprecateSimple('defineLocaleOverride',\n                    'use moment.updateLocale(localeName, config) to change ' +\n                    'an existing locale. moment.defineLocale(localeName, ' +\n                    'config) should only be used for creating a new locale ' +\n                    'See http://momentjs.com/guides/#/warnings/define-locale/ for more info.');\n            parentConfig = locales[name]._config;\n        } else if (config.parentLocale != null) {\n            if (locales[config.parentLocale] != null) {\n                parentConfig = locales[config.parentLocale]._config;\n            } else {\n                if (!localeFamilies[config.parentLocale]) {\n                    localeFamilies[config.parentLocale] = [];\n                }\n                localeFamilies[config.parentLocale].push({\n                    name: name,\n                    config: config\n                });\n                return null;\n            }\n        }\n        locales[name] = new Locale(mergeConfigs(parentConfig, config));\n\n        if (localeFamilies[name]) {\n            localeFamilies[name].forEach(function (x) {\n                defineLocale(x.name, x.config);\n            });\n        }\n\n        // backwards compat for now: also set the locale\n        // make sure we set the locale AFTER all child locales have been\n        // created, so we won't end up with the child locale set.\n        getSetGlobalLocale(name);\n\n\n        return locales[name];\n    } else {\n        // useful for testing\n        delete locales[name];\n        return null;\n    }\n}\n\nfunction updateLocale(name, config) {\n    if (config != null) {\n        var locale, parentConfig = baseConfig;\n        // MERGE\n        if (locales[name] != null) {\n            parentConfig = locales[name]._config;\n        }\n        config = mergeConfigs(parentConfig, config);\n        locale = new Locale(config);\n        locale.parentLocale = locales[name];\n        locales[name] = locale;\n\n        // backwards compat for now: also set the locale\n        getSetGlobalLocale(name);\n    } else {\n        // pass null for config to unupdate, useful for tests\n        if (locales[name] != null) {\n            if (locales[name].parentLocale != null) {\n                locales[name] = locales[name].parentLocale;\n            } else if (locales[name] != null) {\n                delete locales[name];\n            }\n        }\n    }\n    return locales[name];\n}\n\n// returns locale data\nfunction getLocale (key) {\n    var locale;\n\n    if (key && key._locale && key._locale._abbr) {\n        key = key._locale._abbr;\n    }\n\n    if (!key) {\n        return globalLocale;\n    }\n\n    if (!isArray(key)) {\n        //short-circuit everything else\n        locale = loadLocale(key);\n        if (locale) {\n            return locale;\n        }\n        key = [key];\n    }\n\n    return chooseLocale(key);\n}\n\nfunction listLocales() {\n    return keys$1(locales);\n}\n\nfunction checkOverflow (m) {\n    var overflow;\n    var a = m._a;\n\n    if (a && getParsingFlags(m).overflow === -2) {\n        overflow =\n            a[MONTH]       < 0 || a[MONTH]       > 11  ? MONTH :\n            a[DATE]        < 1 || a[DATE]        > daysInMonth(a[YEAR], a[MONTH]) ? DATE :\n            a[HOUR]        < 0 || a[HOUR]        > 24 || (a[HOUR] === 24 && (a[MINUTE] !== 0 || a[SECOND] !== 0 || a[MILLISECOND] !== 0)) ? HOUR :\n            a[MINUTE]      < 0 || a[MINUTE]      > 59  ? MINUTE :\n            a[SECOND]      < 0 || a[SECOND]      > 59  ? SECOND :\n            a[MILLISECOND] < 0 || a[MILLISECOND] > 999 ? MILLISECOND :\n            -1;\n\n        if (getParsingFlags(m)._overflowDayOfYear && (overflow < YEAR || overflow > DATE)) {\n            overflow = DATE;\n        }\n        if (getParsingFlags(m)._overflowWeeks && overflow === -1) {\n            overflow = WEEK;\n        }\n        if (getParsingFlags(m)._overflowWeekday && overflow === -1) {\n            overflow = WEEKDAY;\n        }\n\n        getParsingFlags(m).overflow = overflow;\n    }\n\n    return m;\n}\n\n// iso 8601 regex\n// 0000-00-00 0000-W00 or 0000-W00-0 + T + 00 or 00:00 or 00:00:00 or 00:00:00.000 + +00:00 or +0000 or +00)\nvar extendedIsoRegex = /^\\s*((?:[+-]\\d{6}|\\d{4})-(?:\\d\\d-\\d\\d|W\\d\\d-\\d|W\\d\\d|\\d\\d\\d|\\d\\d))(?:(T| )(\\d\\d(?::\\d\\d(?::\\d\\d(?:[.,]\\d+)?)?)?)([\\+\\-]\\d\\d(?::?\\d\\d)?|\\s*Z)?)?$/;\nvar basicIsoRegex = /^\\s*((?:[+-]\\d{6}|\\d{4})(?:\\d\\d\\d\\d|W\\d\\d\\d|W\\d\\d|\\d\\d\\d|\\d\\d))(?:(T| )(\\d\\d(?:\\d\\d(?:\\d\\d(?:[.,]\\d+)?)?)?)([\\+\\-]\\d\\d(?::?\\d\\d)?|\\s*Z)?)?$/;\n\nvar tzRegex = /Z|[+-]\\d\\d(?::?\\d\\d)?/;\n\nvar isoDates = [\n    ['YYYYYY-MM-DD', /[+-]\\d{6}-\\d\\d-\\d\\d/],\n    ['YYYY-MM-DD', /\\d{4}-\\d\\d-\\d\\d/],\n    ['GGGG-[W]WW-E', /\\d{4}-W\\d\\d-\\d/],\n    ['GGGG-[W]WW', /\\d{4}-W\\d\\d/, false],\n    ['YYYY-DDD', /\\d{4}-\\d{3}/],\n    ['YYYY-MM', /\\d{4}-\\d\\d/, false],\n    ['YYYYYYMMDD', /[+-]\\d{10}/],\n    ['YYYYMMDD', /\\d{8}/],\n    // YYYYMM is NOT allowed by the standard\n    ['GGGG[W]WWE', /\\d{4}W\\d{3}/],\n    ['GGGG[W]WW', /\\d{4}W\\d{2}/, false],\n    ['YYYYDDD', /\\d{7}/]\n];\n\n// iso time formats and regexes\nvar isoTimes = [\n    ['HH:mm:ss.SSSS', /\\d\\d:\\d\\d:\\d\\d\\.\\d+/],\n    ['HH:mm:ss,SSSS', /\\d\\d:\\d\\d:\\d\\d,\\d+/],\n    ['HH:mm:ss', /\\d\\d:\\d\\d:\\d\\d/],\n    ['HH:mm', /\\d\\d:\\d\\d/],\n    ['HHmmss.SSSS', /\\d\\d\\d\\d\\d\\d\\.\\d+/],\n    ['HHmmss,SSSS', /\\d\\d\\d\\d\\d\\d,\\d+/],\n    ['HHmmss', /\\d\\d\\d\\d\\d\\d/],\n    ['HHmm', /\\d\\d\\d\\d/],\n    ['HH', /\\d\\d/]\n];\n\nvar aspNetJsonRegex = /^\\/?Date\\((\\-?\\d+)/i;\n\n// date from iso format\nfunction configFromISO(config) {\n    var i, l,\n        string = config._i,\n        match = extendedIsoRegex.exec(string) || basicIsoRegex.exec(string),\n        allowTime, dateFormat, timeFormat, tzFormat;\n\n    if (match) {\n        getParsingFlags(config).iso = true;\n\n        for (i = 0, l = isoDates.length; i < l; i++) {\n            if (isoDates[i][1].exec(match[1])) {\n                dateFormat = isoDates[i][0];\n                allowTime = isoDates[i][2] !== false;\n                break;\n            }\n        }\n        if (dateFormat == null) {\n            config._isValid = false;\n            return;\n        }\n        if (match[3]) {\n            for (i = 0, l = isoTimes.length; i < l; i++) {\n                if (isoTimes[i][1].exec(match[3])) {\n                    // match[2] should be 'T' or space\n                    timeFormat = (match[2] || ' ') + isoTimes[i][0];\n                    break;\n                }\n            }\n            if (timeFormat == null) {\n                config._isValid = false;\n                return;\n            }\n        }\n        if (!allowTime && timeFormat != null) {\n            config._isValid = false;\n            return;\n        }\n        if (match[4]) {\n            if (tzRegex.exec(match[4])) {\n                tzFormat = 'Z';\n            } else {\n                config._isValid = false;\n                return;\n            }\n        }\n        config._f = dateFormat + (timeFormat || '') + (tzFormat || '');\n        configFromStringAndFormat(config);\n    } else {\n        config._isValid = false;\n    }\n}\n\n// RFC 2822 regex: For details see https://tools.ietf.org/html/rfc2822#section-3.3\nvar basicRfcRegex = /^((?:Mon|Tue|Wed|Thu|Fri|Sat|Sun),?\\s)?(\\d?\\d\\s(?:Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)\\s(?:\\d\\d)?\\d\\d\\s)(\\d\\d:\\d\\d)(\\:\\d\\d)?(\\s(?:UT|GMT|[ECMP][SD]T|[A-IK-Za-ik-z]|[+-]\\d{4}))$/;\n\n// date and time from ref 2822 format\nfunction configFromRFC2822(config) {\n    var string, match, dayFormat,\n        dateFormat, timeFormat, tzFormat;\n    var timezones = {\n        ' GMT': ' +0000',\n        ' EDT': ' -0400',\n        ' EST': ' -0500',\n        ' CDT': ' -0500',\n        ' CST': ' -0600',\n        ' MDT': ' -0600',\n        ' MST': ' -0700',\n        ' PDT': ' -0700',\n        ' PST': ' -0800'\n    };\n    var military = 'YXWVUTSRQPONZABCDEFGHIKLM';\n    var timezone, timezoneIndex;\n\n    string = config._i\n        .replace(/\\([^\\)]*\\)|[\\n\\t]/g, ' ') // Remove comments and folding whitespace\n        .replace(/(\\s\\s+)/g, ' ') // Replace multiple-spaces with a single space\n        .replace(/^\\s|\\s$/g, ''); // Remove leading and trailing spaces\n    match = basicRfcRegex.exec(string);\n\n    if (match) {\n        dayFormat = match[1] ? 'ddd' + ((match[1].length === 5) ? ', ' : ' ') : '';\n        dateFormat = 'D MMM ' + ((match[2].length > 10) ? 'YYYY ' : 'YY ');\n        timeFormat = 'HH:mm' + (match[4] ? ':ss' : '');\n\n        // TODO: Replace the vanilla JS Date object with an indepentent day-of-week check.\n        if (match[1]) { // day of week given\n            var momentDate = new Date(match[2]);\n            var momentDay = ['Sun','Mon','Tue','Wed','Thu','Fri','Sat'][momentDate.getDay()];\n\n            if (match[1].substr(0,3) !== momentDay) {\n                getParsingFlags(config).weekdayMismatch = true;\n                config._isValid = false;\n                return;\n            }\n        }\n\n        switch (match[5].length) {\n            case 2: // military\n                if (timezoneIndex === 0) {\n                    timezone = ' +0000';\n                } else {\n                    timezoneIndex = military.indexOf(match[5][1].toUpperCase()) - 12;\n                    timezone = ((timezoneIndex < 0) ? ' -' : ' +') +\n                        (('' + timezoneIndex).replace(/^-?/, '0')).match(/..$/)[0] + '00';\n                }\n                break;\n            case 4: // Zone\n                timezone = timezones[match[5]];\n                break;\n            default: // UT or +/-9999\n                timezone = timezones[' GMT'];\n        }\n        match[5] = timezone;\n        config._i = match.splice(1).join('');\n        tzFormat = ' ZZ';\n        config._f = dayFormat + dateFormat + timeFormat + tzFormat;\n        configFromStringAndFormat(config);\n        getParsingFlags(config).rfc2822 = true;\n    } else {\n        config._isValid = false;\n    }\n}\n\n// date from iso format or fallback\nfunction configFromString(config) {\n    var matched = aspNetJsonRegex.exec(config._i);\n\n    if (matched !== null) {\n        config._d = new Date(+matched[1]);\n        return;\n    }\n\n    configFromISO(config);\n    if (config._isValid === false) {\n        delete config._isValid;\n    } else {\n        return;\n    }\n\n    configFromRFC2822(config);\n    if (config._isValid === false) {\n        delete config._isValid;\n    } else {\n        return;\n    }\n\n    // Final attempt, use Input Fallback\n    hooks.createFromInputFallback(config);\n}\n\nhooks.createFromInputFallback = deprecate(\n    'value provided is not in a recognized RFC2822 or ISO format. moment construction falls back to js Date(), ' +\n    'which is not reliable across all browsers and versions. Non RFC2822/ISO date formats are ' +\n    'discouraged and will be removed in an upcoming major release. Please refer to ' +\n    'http://momentjs.com/guides/#/warnings/js-date/ for more info.',\n    function (config) {\n        config._d = new Date(config._i + (config._useUTC ? ' UTC' : ''));\n    }\n);\n\n// Pick the first defined of two or three arguments.\nfunction defaults(a, b, c) {\n    if (a != null) {\n        return a;\n    }\n    if (b != null) {\n        return b;\n    }\n    return c;\n}\n\nfunction currentDateArray(config) {\n    // hooks is actually the exported moment object\n    var nowValue = new Date(hooks.now());\n    if (config._useUTC) {\n        return [nowValue.getUTCFullYear(), nowValue.getUTCMonth(), nowValue.getUTCDate()];\n    }\n    return [nowValue.getFullYear(), nowValue.getMonth(), nowValue.getDate()];\n}\n\n// convert an array to a date.\n// the array should mirror the parameters below\n// note: all values past the year are optional and will default to the lowest possible value.\n// [year, month, day , hour, minute, second, millisecond]\nfunction configFromArray (config) {\n    var i, date, input = [], currentDate, yearToUse;\n\n    if (config._d) {\n        return;\n    }\n\n    currentDate = currentDateArray(config);\n\n    //compute day of the year from weeks and weekdays\n    if (config._w && config._a[DATE] == null && config._a[MONTH] == null) {\n        dayOfYearFromWeekInfo(config);\n    }\n\n    //if the day of the year is set, figure out what it is\n    if (config._dayOfYear != null) {\n        yearToUse = defaults(config._a[YEAR], currentDate[YEAR]);\n\n        if (config._dayOfYear > daysInYear(yearToUse) || config._dayOfYear === 0) {\n            getParsingFlags(config)._overflowDayOfYear = true;\n        }\n\n        date = createUTCDate(yearToUse, 0, config._dayOfYear);\n        config._a[MONTH] = date.getUTCMonth();\n        config._a[DATE] = date.getUTCDate();\n    }\n\n    // Default to current date.\n    // * if no year, month, day of month are given, default to today\n    // * if day of month is given, default month and year\n    // * if month is given, default only year\n    // * if year is given, don't default anything\n    for (i = 0; i < 3 && config._a[i] == null; ++i) {\n        config._a[i] = input[i] = currentDate[i];\n    }\n\n    // Zero out whatever was not defaulted, including time\n    for (; i < 7; i++) {\n        config._a[i] = input[i] = (config._a[i] == null) ? (i === 2 ? 1 : 0) : config._a[i];\n    }\n\n    // Check for 24:00:00.000\n    if (config._a[HOUR] === 24 &&\n            config._a[MINUTE] === 0 &&\n            config._a[SECOND] === 0 &&\n            config._a[MILLISECOND] === 0) {\n        config._nextDay = true;\n        config._a[HOUR] = 0;\n    }\n\n    config._d = (config._useUTC ? createUTCDate : createDate).apply(null, input);\n    // Apply timezone offset from input. The actual utcOffset can be changed\n    // with parseZone.\n    if (config._tzm != null) {\n        config._d.setUTCMinutes(config._d.getUTCMinutes() - config._tzm);\n    }\n\n    if (config._nextDay) {\n        config._a[HOUR] = 24;\n    }\n}\n\nfunction dayOfYearFromWeekInfo(config) {\n    var w, weekYear, week, weekday, dow, doy, temp, weekdayOverflow;\n\n    w = config._w;\n    if (w.GG != null || w.W != null || w.E != null) {\n        dow = 1;\n        doy = 4;\n\n        // TODO: We need to take the current isoWeekYear, but that depends on\n        // how we interpret now (local, utc, fixed offset). So create\n        // a now version of current config (take local/utc/offset flags, and\n        // create now).\n        weekYear = defaults(w.GG, config._a[YEAR], weekOfYear(createLocal(), 1, 4).year);\n        week = defaults(w.W, 1);\n        weekday = defaults(w.E, 1);\n        if (weekday < 1 || weekday > 7) {\n            weekdayOverflow = true;\n        }\n    } else {\n        dow = config._locale._week.dow;\n        doy = config._locale._week.doy;\n\n        var curWeek = weekOfYear(createLocal(), dow, doy);\n\n        weekYear = defaults(w.gg, config._a[YEAR], curWeek.year);\n\n        // Default to current week.\n        week = defaults(w.w, curWeek.week);\n\n        if (w.d != null) {\n            // weekday -- low day numbers are considered next week\n            weekday = w.d;\n            if (weekday < 0 || weekday > 6) {\n                weekdayOverflow = true;\n            }\n        } else if (w.e != null) {\n            // local weekday -- counting starts from begining of week\n            weekday = w.e + dow;\n            if (w.e < 0 || w.e > 6) {\n                weekdayOverflow = true;\n            }\n        } else {\n            // default to begining of week\n            weekday = dow;\n        }\n    }\n    if (week < 1 || week > weeksInYear(weekYear, dow, doy)) {\n        getParsingFlags(config)._overflowWeeks = true;\n    } else if (weekdayOverflow != null) {\n        getParsingFlags(config)._overflowWeekday = true;\n    } else {\n        temp = dayOfYearFromWeeks(weekYear, week, weekday, dow, doy);\n        config._a[YEAR] = temp.year;\n        config._dayOfYear = temp.dayOfYear;\n    }\n}\n\n// constant that refers to the ISO standard\nhooks.ISO_8601 = function () {};\n\n// constant that refers to the RFC 2822 form\nhooks.RFC_2822 = function () {};\n\n// date from string and format string\nfunction configFromStringAndFormat(config) {\n    // TODO: Move this to another part of the creation flow to prevent circular deps\n    if (config._f === hooks.ISO_8601) {\n        configFromISO(config);\n        return;\n    }\n    if (config._f === hooks.RFC_2822) {\n        configFromRFC2822(config);\n        return;\n    }\n    config._a = [];\n    getParsingFlags(config).empty = true;\n\n    // This array is used to make a Date, either with `new Date` or `Date.UTC`\n    var string = '' + config._i,\n        i, parsedInput, tokens, token, skipped,\n        stringLength = string.length,\n        totalParsedInputLength = 0;\n\n    tokens = expandFormat(config._f, config._locale).match(formattingTokens) || [];\n\n    for (i = 0; i < tokens.length; i++) {\n        token = tokens[i];\n        parsedInput = (string.match(getParseRegexForToken(token, config)) || [])[0];\n        // console.log('token', token, 'parsedInput', parsedInput,\n        //         'regex', getParseRegexForToken(token, config));\n        if (parsedInput) {\n            skipped = string.substr(0, string.indexOf(parsedInput));\n            if (skipped.length > 0) {\n                getParsingFlags(config).unusedInput.push(skipped);\n            }\n            string = string.slice(string.indexOf(parsedInput) + parsedInput.length);\n            totalParsedInputLength += parsedInput.length;\n        }\n        // don't parse if it's not a known token\n        if (formatTokenFunctions[token]) {\n            if (parsedInput) {\n                getParsingFlags(config).empty = false;\n            }\n            else {\n                getParsingFlags(config).unusedTokens.push(token);\n            }\n            addTimeToArrayFromToken(token, parsedInput, config);\n        }\n        else if (config._strict && !parsedInput) {\n            getParsingFlags(config).unusedTokens.push(token);\n        }\n    }\n\n    // add remaining unparsed input length to the string\n    getParsingFlags(config).charsLeftOver = stringLength - totalParsedInputLength;\n    if (string.length > 0) {\n        getParsingFlags(config).unusedInput.push(string);\n    }\n\n    // clear _12h flag if hour is <= 12\n    if (config._a[HOUR] <= 12 &&\n        getParsingFlags(config).bigHour === true &&\n        config._a[HOUR] > 0) {\n        getParsingFlags(config).bigHour = undefined;\n    }\n\n    getParsingFlags(config).parsedDateParts = config._a.slice(0);\n    getParsingFlags(config).meridiem = config._meridiem;\n    // handle meridiem\n    config._a[HOUR] = meridiemFixWrap(config._locale, config._a[HOUR], config._meridiem);\n\n    configFromArray(config);\n    checkOverflow(config);\n}\n\n\nfunction meridiemFixWrap (locale, hour, meridiem) {\n    var isPm;\n\n    if (meridiem == null) {\n        // nothing to do\n        return hour;\n    }\n    if (locale.meridiemHour != null) {\n        return locale.meridiemHour(hour, meridiem);\n    } else if (locale.isPM != null) {\n        // Fallback\n        isPm = locale.isPM(meridiem);\n        if (isPm && hour < 12) {\n            hour += 12;\n        }\n        if (!isPm && hour === 12) {\n            hour = 0;\n        }\n        return hour;\n    } else {\n        // this is not supposed to happen\n        return hour;\n    }\n}\n\n// date from string and array of format strings\nfunction configFromStringAndArray(config) {\n    var tempConfig,\n        bestMoment,\n\n        scoreToBeat,\n        i,\n        currentScore;\n\n    if (config._f.length === 0) {\n        getParsingFlags(config).invalidFormat = true;\n        config._d = new Date(NaN);\n        return;\n    }\n\n    for (i = 0; i < config._f.length; i++) {\n        currentScore = 0;\n        tempConfig = copyConfig({}, config);\n        if (config._useUTC != null) {\n            tempConfig._useUTC = config._useUTC;\n        }\n        tempConfig._f = config._f[i];\n        configFromStringAndFormat(tempConfig);\n\n        if (!isValid(tempConfig)) {\n            continue;\n        }\n\n        // if there is any input that was not parsed add a penalty for that format\n        currentScore += getParsingFlags(tempConfig).charsLeftOver;\n\n        //or tokens\n        currentScore += getParsingFlags(tempConfig).unusedTokens.length * 10;\n\n        getParsingFlags(tempConfig).score = currentScore;\n\n        if (scoreToBeat == null || currentScore < scoreToBeat) {\n            scoreToBeat = currentScore;\n            bestMoment = tempConfig;\n        }\n    }\n\n    extend(config, bestMoment || tempConfig);\n}\n\nfunction configFromObject(config) {\n    if (config._d) {\n        return;\n    }\n\n    var i = normalizeObjectUnits(config._i);\n    config._a = map([i.year, i.month, i.day || i.date, i.hour, i.minute, i.second, i.millisecond], function (obj) {\n        return obj && parseInt(obj, 10);\n    });\n\n    configFromArray(config);\n}\n\nfunction createFromConfig (config) {\n    var res = new Moment(checkOverflow(prepareConfig(config)));\n    if (res._nextDay) {\n        // Adding is smart enough around DST\n        res.add(1, 'd');\n        res._nextDay = undefined;\n    }\n\n    return res;\n}\n\nfunction prepareConfig (config) {\n    var input = config._i,\n        format = config._f;\n\n    config._locale = config._locale || getLocale(config._l);\n\n    if (input === null || (format === undefined && input === '')) {\n        return createInvalid({nullInput: true});\n    }\n\n    if (typeof input === 'string') {\n        config._i = input = config._locale.preparse(input);\n    }\n\n    if (isMoment(input)) {\n        return new Moment(checkOverflow(input));\n    } else if (isDate(input)) {\n        config._d = input;\n    } else if (isArray(format)) {\n        configFromStringAndArray(config);\n    } else if (format) {\n        configFromStringAndFormat(config);\n    }  else {\n        configFromInput(config);\n    }\n\n    if (!isValid(config)) {\n        config._d = null;\n    }\n\n    return config;\n}\n\nfunction configFromInput(config) {\n    var input = config._i;\n    if (isUndefined(input)) {\n        config._d = new Date(hooks.now());\n    } else if (isDate(input)) {\n        config._d = new Date(input.valueOf());\n    } else if (typeof input === 'string') {\n        configFromString(config);\n    } else if (isArray(input)) {\n        config._a = map(input.slice(0), function (obj) {\n            return parseInt(obj, 10);\n        });\n        configFromArray(config);\n    } else if (isObject(input)) {\n        configFromObject(config);\n    } else if (isNumber(input)) {\n        // from milliseconds\n        config._d = new Date(input);\n    } else {\n        hooks.createFromInputFallback(config);\n    }\n}\n\nfunction createLocalOrUTC (input, format, locale, strict, isUTC) {\n    var c = {};\n\n    if (locale === true || locale === false) {\n        strict = locale;\n        locale = undefined;\n    }\n\n    if ((isObject(input) && isObjectEmpty(input)) ||\n            (isArray(input) && input.length === 0)) {\n        input = undefined;\n    }\n    // object construction must be done this way.\n    // https://github.com/moment/moment/issues/1423\n    c._isAMomentObject = true;\n    c._useUTC = c._isUTC = isUTC;\n    c._l = locale;\n    c._i = input;\n    c._f = format;\n    c._strict = strict;\n\n    return createFromConfig(c);\n}\n\nfunction createLocal (input, format, locale, strict) {\n    return createLocalOrUTC(input, format, locale, strict, false);\n}\n\nvar prototypeMin = deprecate(\n    'moment().min is deprecated, use moment.max instead. http://momentjs.com/guides/#/warnings/min-max/',\n    function () {\n        var other = createLocal.apply(null, arguments);\n        if (this.isValid() && other.isValid()) {\n            return other < this ? this : other;\n        } else {\n            return createInvalid();\n        }\n    }\n);\n\nvar prototypeMax = deprecate(\n    'moment().max is deprecated, use moment.min instead. http://momentjs.com/guides/#/warnings/min-max/',\n    function () {\n        var other = createLocal.apply(null, arguments);\n        if (this.isValid() && other.isValid()) {\n            return other > this ? this : other;\n        } else {\n            return createInvalid();\n        }\n    }\n);\n\n// Pick a moment m from moments so that m[fn](other) is true for all\n// other. This relies on the function fn to be transitive.\n//\n// moments should either be an array of moment objects or an array, whose\n// first element is an array of moment objects.\nfunction pickBy(fn, moments) {\n    var res, i;\n    if (moments.length === 1 && isArray(moments[0])) {\n        moments = moments[0];\n    }\n    if (!moments.length) {\n        return createLocal();\n    }\n    res = moments[0];\n    for (i = 1; i < moments.length; ++i) {\n        if (!moments[i].isValid() || moments[i][fn](res)) {\n            res = moments[i];\n        }\n    }\n    return res;\n}\n\n// TODO: Use [].sort instead?\nfunction min () {\n    var args = [].slice.call(arguments, 0);\n\n    return pickBy('isBefore', args);\n}\n\nfunction max () {\n    var args = [].slice.call(arguments, 0);\n\n    return pickBy('isAfter', args);\n}\n\nvar now = function () {\n    return Date.now ? Date.now() : +(new Date());\n};\n\nvar ordering = ['year', 'quarter', 'month', 'week', 'day', 'hour', 'minute', 'second', 'millisecond'];\n\nfunction isDurationValid(m) {\n    for (var key in m) {\n        if (!(ordering.indexOf(key) !== -1 && (m[key] == null || !isNaN(m[key])))) {\n            return false;\n        }\n    }\n\n    var unitHasDecimal = false;\n    for (var i = 0; i < ordering.length; ++i) {\n        if (m[ordering[i]]) {\n            if (unitHasDecimal) {\n                return false; // only allow non-integers for smallest unit\n            }\n            if (parseFloat(m[ordering[i]]) !== toInt(m[ordering[i]])) {\n                unitHasDecimal = true;\n            }\n        }\n    }\n\n    return true;\n}\n\nfunction isValid$1() {\n    return this._isValid;\n}\n\nfunction createInvalid$1() {\n    return createDuration(NaN);\n}\n\nfunction Duration (duration) {\n    var normalizedInput = normalizeObjectUnits(duration),\n        years = normalizedInput.year || 0,\n        quarters = normalizedInput.quarter || 0,\n        months = normalizedInput.month || 0,\n        weeks = normalizedInput.week || 0,\n        days = normalizedInput.day || 0,\n        hours = normalizedInput.hour || 0,\n        minutes = normalizedInput.minute || 0,\n        seconds = normalizedInput.second || 0,\n        milliseconds = normalizedInput.millisecond || 0;\n\n    this._isValid = isDurationValid(normalizedInput);\n\n    // representation for dateAddRemove\n    this._milliseconds = +milliseconds +\n        seconds * 1e3 + // 1000\n        minutes * 6e4 + // 1000 * 60\n        hours * 1000 * 60 * 60; //using 1000 * 60 * 60 instead of 36e5 to avoid floating point rounding errors https://github.com/moment/moment/issues/2978\n    // Because of dateAddRemove treats 24 hours as different from a\n    // day when working around DST, we need to store them separately\n    this._days = +days +\n        weeks * 7;\n    // It is impossible translate months into days without knowing\n    // which months you are are talking about, so we have to store\n    // it separately.\n    this._months = +months +\n        quarters * 3 +\n        years * 12;\n\n    this._data = {};\n\n    this._locale = getLocale();\n\n    this._bubble();\n}\n\nfunction isDuration (obj) {\n    return obj instanceof Duration;\n}\n\nfunction absRound (number) {\n    if (number < 0) {\n        return Math.round(-1 * number) * -1;\n    } else {\n        return Math.round(number);\n    }\n}\n\n// FORMATTING\n\nfunction offset (token, separator) {\n    addFormatToken(token, 0, 0, function () {\n        var offset = this.utcOffset();\n        var sign = '+';\n        if (offset < 0) {\n            offset = -offset;\n            sign = '-';\n        }\n        return sign + zeroFill(~~(offset / 60), 2) + separator + zeroFill(~~(offset) % 60, 2);\n    });\n}\n\noffset('Z', ':');\noffset('ZZ', '');\n\n// PARSING\n\naddRegexToken('Z',  matchShortOffset);\naddRegexToken('ZZ', matchShortOffset);\naddParseToken(['Z', 'ZZ'], function (input, array, config) {\n    config._useUTC = true;\n    config._tzm = offsetFromString(matchShortOffset, input);\n});\n\n// HELPERS\n\n// timezone chunker\n// '+10:00' > ['10',  '00']\n// '-1530'  > ['-15', '30']\nvar chunkOffset = /([\\+\\-]|\\d\\d)/gi;\n\nfunction offsetFromString(matcher, string) {\n    var matches = (string || '').match(matcher);\n\n    if (matches === null) {\n        return null;\n    }\n\n    var chunk   = matches[matches.length - 1] || [];\n    var parts   = (chunk + '').match(chunkOffset) || ['-', 0, 0];\n    var minutes = +(parts[1] * 60) + toInt(parts[2]);\n\n    return minutes === 0 ?\n      0 :\n      parts[0] === '+' ? minutes : -minutes;\n}\n\n// Return a moment from input, that is local/utc/zone equivalent to model.\nfunction cloneWithOffset(input, model) {\n    var res, diff;\n    if (model._isUTC) {\n        res = model.clone();\n        diff = (isMoment(input) || isDate(input) ? input.valueOf() : createLocal(input).valueOf()) - res.valueOf();\n        // Use low-level api, because this fn is low-level api.\n        res._d.setTime(res._d.valueOf() + diff);\n        hooks.updateOffset(res, false);\n        return res;\n    } else {\n        return createLocal(input).local();\n    }\n}\n\nfunction getDateOffset (m) {\n    // On Firefox.24 Date#getTimezoneOffset returns a floating point.\n    // https://github.com/moment/moment/pull/1871\n    return -Math.round(m._d.getTimezoneOffset() / 15) * 15;\n}\n\n// HOOKS\n\n// This function will be called whenever a moment is mutated.\n// It is intended to keep the offset in sync with the timezone.\nhooks.updateOffset = function () {};\n\n// MOMENTS\n\n// keepLocalTime = true means only change the timezone, without\n// affecting the local hour. So 5:31:26 +0300 --[utcOffset(2, true)]-->\n// 5:31:26 +0200 It is possible that 5:31:26 doesn't exist with offset\n// +0200, so we adjust the time as needed, to be valid.\n//\n// Keeping the time actually adds/subtracts (one hour)\n// from the actual represented time. That is why we call updateOffset\n// a second time. In case it wants us to change the offset again\n// _changeInProgress == true case, then we have to adjust, because\n// there is no such time in the given timezone.\nfunction getSetOffset (input, keepLocalTime, keepMinutes) {\n    var offset = this._offset || 0,\n        localAdjust;\n    if (!this.isValid()) {\n        return input != null ? this : NaN;\n    }\n    if (input != null) {\n        if (typeof input === 'string') {\n            input = offsetFromString(matchShortOffset, input);\n            if (input === null) {\n                return this;\n            }\n        } else if (Math.abs(input) < 16 && !keepMinutes) {\n            input = input * 60;\n        }\n        if (!this._isUTC && keepLocalTime) {\n            localAdjust = getDateOffset(this);\n        }\n        this._offset = input;\n        this._isUTC = true;\n        if (localAdjust != null) {\n            this.add(localAdjust, 'm');\n        }\n        if (offset !== input) {\n            if (!keepLocalTime || this._changeInProgress) {\n                addSubtract(this, createDuration(input - offset, 'm'), 1, false);\n            } else if (!this._changeInProgress) {\n                this._changeInProgress = true;\n                hooks.updateOffset(this, true);\n                this._changeInProgress = null;\n            }\n        }\n        return this;\n    } else {\n        return this._isUTC ? offset : getDateOffset(this);\n    }\n}\n\nfunction getSetZone (input, keepLocalTime) {\n    if (input != null) {\n        if (typeof input !== 'string') {\n            input = -input;\n        }\n\n        this.utcOffset(input, keepLocalTime);\n\n        return this;\n    } else {\n        return -this.utcOffset();\n    }\n}\n\nfunction setOffsetToUTC (keepLocalTime) {\n    return this.utcOffset(0, keepLocalTime);\n}\n\nfunction setOffsetToLocal (keepLocalTime) {\n    if (this._isUTC) {\n        this.utcOffset(0, keepLocalTime);\n        this._isUTC = false;\n\n        if (keepLocalTime) {\n            this.subtract(getDateOffset(this), 'm');\n        }\n    }\n    return this;\n}\n\nfunction setOffsetToParsedOffset () {\n    if (this._tzm != null) {\n        this.utcOffset(this._tzm, false, true);\n    } else if (typeof this._i === 'string') {\n        var tZone = offsetFromString(matchOffset, this._i);\n        if (tZone != null) {\n            this.utcOffset(tZone);\n        }\n        else {\n            this.utcOffset(0, true);\n        }\n    }\n    return this;\n}\n\nfunction hasAlignedHourOffset (input) {\n    if (!this.isValid()) {\n        return false;\n    }\n    input = input ? createLocal(input).utcOffset() : 0;\n\n    return (this.utcOffset() - input) % 60 === 0;\n}\n\nfunction isDaylightSavingTime () {\n    return (\n        this.utcOffset() > this.clone().month(0).utcOffset() ||\n        this.utcOffset() > this.clone().month(5).utcOffset()\n    );\n}\n\nfunction isDaylightSavingTimeShifted () {\n    if (!isUndefined(this._isDSTShifted)) {\n        return this._isDSTShifted;\n    }\n\n    var c = {};\n\n    copyConfig(c, this);\n    c = prepareConfig(c);\n\n    if (c._a) {\n        var other = c._isUTC ? createUTC(c._a) : createLocal(c._a);\n        this._isDSTShifted = this.isValid() &&\n            compareArrays(c._a, other.toArray()) > 0;\n    } else {\n        this._isDSTShifted = false;\n    }\n\n    return this._isDSTShifted;\n}\n\nfunction isLocal () {\n    return this.isValid() ? !this._isUTC : false;\n}\n\nfunction isUtcOffset () {\n    return this.isValid() ? this._isUTC : false;\n}\n\nfunction isUtc () {\n    return this.isValid() ? this._isUTC && this._offset === 0 : false;\n}\n\n// ASP.NET json date format regex\nvar aspNetRegex = /^(\\-)?(?:(\\d*)[. ])?(\\d+)\\:(\\d+)(?:\\:(\\d+)(\\.\\d*)?)?$/;\n\n// from http://docs.closure-library.googlecode.com/git/closure_goog_date_date.js.source.html\n// somewhat more in line with 4.4.3.2 2004 spec, but allows decimal anywhere\n// and further modified to allow for strings containing both week and day\nvar isoRegex = /^(-)?P(?:(-?[0-9,.]*)Y)?(?:(-?[0-9,.]*)M)?(?:(-?[0-9,.]*)W)?(?:(-?[0-9,.]*)D)?(?:T(?:(-?[0-9,.]*)H)?(?:(-?[0-9,.]*)M)?(?:(-?[0-9,.]*)S)?)?$/;\n\nfunction createDuration (input, key) {\n    var duration = input,\n        // matching against regexp is expensive, do it on demand\n        match = null,\n        sign,\n        ret,\n        diffRes;\n\n    if (isDuration(input)) {\n        duration = {\n            ms : input._milliseconds,\n            d  : input._days,\n            M  : input._months\n        };\n    } else if (isNumber(input)) {\n        duration = {};\n        if (key) {\n            duration[key] = input;\n        } else {\n            duration.milliseconds = input;\n        }\n    } else if (!!(match = aspNetRegex.exec(input))) {\n        sign = (match[1] === '-') ? -1 : 1;\n        duration = {\n            y  : 0,\n            d  : toInt(match[DATE])                         * sign,\n            h  : toInt(match[HOUR])                         * sign,\n            m  : toInt(match[MINUTE])                       * sign,\n            s  : toInt(match[SECOND])                       * sign,\n            ms : toInt(absRound(match[MILLISECOND] * 1000)) * sign // the millisecond decimal point is included in the match\n        };\n    } else if (!!(match = isoRegex.exec(input))) {\n        sign = (match[1] === '-') ? -1 : 1;\n        duration = {\n            y : parseIso(match[2], sign),\n            M : parseIso(match[3], sign),\n            w : parseIso(match[4], sign),\n            d : parseIso(match[5], sign),\n            h : parseIso(match[6], sign),\n            m : parseIso(match[7], sign),\n            s : parseIso(match[8], sign)\n        };\n    } else if (duration == null) {// checks for null or undefined\n        duration = {};\n    } else if (typeof duration === 'object' && ('from' in duration || 'to' in duration)) {\n        diffRes = momentsDifference(createLocal(duration.from), createLocal(duration.to));\n\n        duration = {};\n        duration.ms = diffRes.milliseconds;\n        duration.M = diffRes.months;\n    }\n\n    ret = new Duration(duration);\n\n    if (isDuration(input) && hasOwnProp(input, '_locale')) {\n        ret._locale = input._locale;\n    }\n\n    return ret;\n}\n\ncreateDuration.fn = Duration.prototype;\ncreateDuration.invalid = createInvalid$1;\n\nfunction parseIso (inp, sign) {\n    // We'd normally use ~~inp for this, but unfortunately it also\n    // converts floats to ints.\n    // inp may be undefined, so careful calling replace on it.\n    var res = inp && parseFloat(inp.replace(',', '.'));\n    // apply sign while we're at it\n    return (isNaN(res) ? 0 : res) * sign;\n}\n\nfunction positiveMomentsDifference(base, other) {\n    var res = {milliseconds: 0, months: 0};\n\n    res.months = other.month() - base.month() +\n        (other.year() - base.year()) * 12;\n    if (base.clone().add(res.months, 'M').isAfter(other)) {\n        --res.months;\n    }\n\n    res.milliseconds = +other - +(base.clone().add(res.months, 'M'));\n\n    return res;\n}\n\nfunction momentsDifference(base, other) {\n    var res;\n    if (!(base.isValid() && other.isValid())) {\n        return {milliseconds: 0, months: 0};\n    }\n\n    other = cloneWithOffset(other, base);\n    if (base.isBefore(other)) {\n        res = positiveMomentsDifference(base, other);\n    } else {\n        res = positiveMomentsDifference(other, base);\n        res.milliseconds = -res.milliseconds;\n        res.months = -res.months;\n    }\n\n    return res;\n}\n\n// TODO: remove 'name' arg after deprecation is removed\nfunction createAdder(direction, name) {\n    return function (val, period) {\n        var dur, tmp;\n        //invert the arguments, but complain about it\n        if (period !== null && !isNaN(+period)) {\n            deprecateSimple(name, 'moment().' + name  + '(period, number) is deprecated. Please use moment().' + name + '(number, period). ' +\n            'See http://momentjs.com/guides/#/warnings/add-inverted-param/ for more info.');\n            tmp = val; val = period; period = tmp;\n        }\n\n        val = typeof val === 'string' ? +val : val;\n        dur = createDuration(val, period);\n        addSubtract(this, dur, direction);\n        return this;\n    };\n}\n\nfunction addSubtract (mom, duration, isAdding, updateOffset) {\n    var milliseconds = duration._milliseconds,\n        days = absRound(duration._days),\n        months = absRound(duration._months);\n\n    if (!mom.isValid()) {\n        // No op\n        return;\n    }\n\n    updateOffset = updateOffset == null ? true : updateOffset;\n\n    if (milliseconds) {\n        mom._d.setTime(mom._d.valueOf() + milliseconds * isAdding);\n    }\n    if (days) {\n        set$1(mom, 'Date', get(mom, 'Date') + days * isAdding);\n    }\n    if (months) {\n        setMonth(mom, get(mom, 'Month') + months * isAdding);\n    }\n    if (updateOffset) {\n        hooks.updateOffset(mom, days || months);\n    }\n}\n\nvar add      = createAdder(1, 'add');\nvar subtract = createAdder(-1, 'subtract');\n\nfunction getCalendarFormat(myMoment, now) {\n    var diff = myMoment.diff(now, 'days', true);\n    return diff < -6 ? 'sameElse' :\n            diff < -1 ? 'lastWeek' :\n            diff < 0 ? 'lastDay' :\n            diff < 1 ? 'sameDay' :\n            diff < 2 ? 'nextDay' :\n            diff < 7 ? 'nextWeek' : 'sameElse';\n}\n\nfunction calendar$1 (time, formats) {\n    // We want to compare the start of today, vs this.\n    // Getting start-of-today depends on whether we're local/utc/offset or not.\n    var now = time || createLocal(),\n        sod = cloneWithOffset(now, this).startOf('day'),\n        format = hooks.calendarFormat(this, sod) || 'sameElse';\n\n    var output = formats && (isFunction(formats[format]) ? formats[format].call(this, now) : formats[format]);\n\n    return this.format(output || this.localeData().calendar(format, this, createLocal(now)));\n}\n\nfunction clone () {\n    return new Moment(this);\n}\n\nfunction isAfter (input, units) {\n    var localInput = isMoment(input) ? input : createLocal(input);\n    if (!(this.isValid() && localInput.isValid())) {\n        return false;\n    }\n    units = normalizeUnits(!isUndefined(units) ? units : 'millisecond');\n    if (units === 'millisecond') {\n        return this.valueOf() > localInput.valueOf();\n    } else {\n        return localInput.valueOf() < this.clone().startOf(units).valueOf();\n    }\n}\n\nfunction isBefore (input, units) {\n    var localInput = isMoment(input) ? input : createLocal(input);\n    if (!(this.isValid() && localInput.isValid())) {\n        return false;\n    }\n    units = normalizeUnits(!isUndefined(units) ? units : 'millisecond');\n    if (units === 'millisecond') {\n        return this.valueOf() < localInput.valueOf();\n    } else {\n        return this.clone().endOf(units).valueOf() < localInput.valueOf();\n    }\n}\n\nfunction isBetween (from, to, units, inclusivity) {\n    inclusivity = inclusivity || '()';\n    return (inclusivity[0] === '(' ? this.isAfter(from, units) : !this.isBefore(from, units)) &&\n        (inclusivity[1] === ')' ? this.isBefore(to, units) : !this.isAfter(to, units));\n}\n\nfunction isSame (input, units) {\n    var localInput = isMoment(input) ? input : createLocal(input),\n        inputMs;\n    if (!(this.isValid() && localInput.isValid())) {\n        return false;\n    }\n    units = normalizeUnits(units || 'millisecond');\n    if (units === 'millisecond') {\n        return this.valueOf() === localInput.valueOf();\n    } else {\n        inputMs = localInput.valueOf();\n        return this.clone().startOf(units).valueOf() <= inputMs && inputMs <= this.clone().endOf(units).valueOf();\n    }\n}\n\nfunction isSameOrAfter (input, units) {\n    return this.isSame(input, units) || this.isAfter(input,units);\n}\n\nfunction isSameOrBefore (input, units) {\n    return this.isSame(input, units) || this.isBefore(input,units);\n}\n\nfunction diff (input, units, asFloat) {\n    var that,\n        zoneDelta,\n        delta, output;\n\n    if (!this.isValid()) {\n        return NaN;\n    }\n\n    that = cloneWithOffset(input, this);\n\n    if (!that.isValid()) {\n        return NaN;\n    }\n\n    zoneDelta = (that.utcOffset() - this.utcOffset()) * 6e4;\n\n    units = normalizeUnits(units);\n\n    if (units === 'year' || units === 'month' || units === 'quarter') {\n        output = monthDiff(this, that);\n        if (units === 'quarter') {\n            output = output / 3;\n        } else if (units === 'year') {\n            output = output / 12;\n        }\n    } else {\n        delta = this - that;\n        output = units === 'second' ? delta / 1e3 : // 1000\n            units === 'minute' ? delta / 6e4 : // 1000 * 60\n            units === 'hour' ? delta / 36e5 : // 1000 * 60 * 60\n            units === 'day' ? (delta - zoneDelta) / 864e5 : // 1000 * 60 * 60 * 24, negate dst\n            units === 'week' ? (delta - zoneDelta) / 6048e5 : // 1000 * 60 * 60 * 24 * 7, negate dst\n            delta;\n    }\n    return asFloat ? output : absFloor(output);\n}\n\nfunction monthDiff (a, b) {\n    // difference in months\n    var wholeMonthDiff = ((b.year() - a.year()) * 12) + (b.month() - a.month()),\n        // b is in (anchor - 1 month, anchor + 1 month)\n        anchor = a.clone().add(wholeMonthDiff, 'months'),\n        anchor2, adjust;\n\n    if (b - anchor < 0) {\n        anchor2 = a.clone().add(wholeMonthDiff - 1, 'months');\n        // linear across the month\n        adjust = (b - anchor) / (anchor - anchor2);\n    } else {\n        anchor2 = a.clone().add(wholeMonthDiff + 1, 'months');\n        // linear across the month\n        adjust = (b - anchor) / (anchor2 - anchor);\n    }\n\n    //check for negative zero, return zero if negative zero\n    return -(wholeMonthDiff + adjust) || 0;\n}\n\nhooks.defaultFormat = 'YYYY-MM-DDTHH:mm:ssZ';\nhooks.defaultFormatUtc = 'YYYY-MM-DDTHH:mm:ss[Z]';\n\nfunction toString () {\n    return this.clone().locale('en').format('ddd MMM DD YYYY HH:mm:ss [GMT]ZZ');\n}\n\nfunction toISOString() {\n    if (!this.isValid()) {\n        return null;\n    }\n    var m = this.clone().utc();\n    if (m.year() < 0 || m.year() > 9999) {\n        return formatMoment(m, 'YYYYYY-MM-DD[T]HH:mm:ss.SSS[Z]');\n    }\n    if (isFunction(Date.prototype.toISOString)) {\n        // native implementation is ~50x faster, use it when we can\n        return this.toDate().toISOString();\n    }\n    return formatMoment(m, 'YYYY-MM-DD[T]HH:mm:ss.SSS[Z]');\n}\n\n/**\n * Return a human readable representation of a moment that can\n * also be evaluated to get a new moment which is the same\n *\n * @link https://nodejs.org/dist/latest/docs/api/util.html#util_custom_inspect_function_on_objects\n */\nfunction inspect () {\n    if (!this.isValid()) {\n        return 'moment.invalid(/* ' + this._i + ' */)';\n    }\n    var func = 'moment';\n    var zone = '';\n    if (!this.isLocal()) {\n        func = this.utcOffset() === 0 ? 'moment.utc' : 'moment.parseZone';\n        zone = 'Z';\n    }\n    var prefix = '[' + func + '(\"]';\n    var year = (0 <= this.year() && this.year() <= 9999) ? 'YYYY' : 'YYYYYY';\n    var datetime = '-MM-DD[T]HH:mm:ss.SSS';\n    var suffix = zone + '[\")]';\n\n    return this.format(prefix + year + datetime + suffix);\n}\n\nfunction format (inputString) {\n    if (!inputString) {\n        inputString = this.isUtc() ? hooks.defaultFormatUtc : hooks.defaultFormat;\n    }\n    var output = formatMoment(this, inputString);\n    return this.localeData().postformat(output);\n}\n\nfunction from (time, withoutSuffix) {\n    if (this.isValid() &&\n            ((isMoment(time) && time.isValid()) ||\n             createLocal(time).isValid())) {\n        return createDuration({to: this, from: time}).locale(this.locale()).humanize(!withoutSuffix);\n    } else {\n        return this.localeData().invalidDate();\n    }\n}\n\nfunction fromNow (withoutSuffix) {\n    return this.from(createLocal(), withoutSuffix);\n}\n\nfunction to (time, withoutSuffix) {\n    if (this.isValid() &&\n            ((isMoment(time) && time.isValid()) ||\n             createLocal(time).isValid())) {\n        return createDuration({from: this, to: time}).locale(this.locale()).humanize(!withoutSuffix);\n    } else {\n        return this.localeData().invalidDate();\n    }\n}\n\nfunction toNow (withoutSuffix) {\n    return this.to(createLocal(), withoutSuffix);\n}\n\n// If passed a locale key, it will set the locale for this\n// instance.  Otherwise, it will return the locale configuration\n// variables for this instance.\nfunction locale (key) {\n    var newLocaleData;\n\n    if (key === undefined) {\n        return this._locale._abbr;\n    } else {\n        newLocaleData = getLocale(key);\n        if (newLocaleData != null) {\n            this._locale = newLocaleData;\n        }\n        return this;\n    }\n}\n\nvar lang = deprecate(\n    'moment().lang() is deprecated. Instead, use moment().localeData() to get the language configuration. Use moment().locale() to change languages.',\n    function (key) {\n        if (key === undefined) {\n            return this.localeData();\n        } else {\n            return this.locale(key);\n        }\n    }\n);\n\nfunction localeData () {\n    return this._locale;\n}\n\nfunction startOf (units) {\n    units = normalizeUnits(units);\n    // the following switch intentionally omits break keywords\n    // to utilize falling through the cases.\n    switch (units) {\n        case 'year':\n            this.month(0);\n            /* falls through */\n        case 'quarter':\n        case 'month':\n            this.date(1);\n            /* falls through */\n        case 'week':\n        case 'isoWeek':\n        case 'day':\n        case 'date':\n            this.hours(0);\n            /* falls through */\n        case 'hour':\n            this.minutes(0);\n            /* falls through */\n        case 'minute':\n            this.seconds(0);\n            /* falls through */\n        case 'second':\n            this.milliseconds(0);\n    }\n\n    // weeks are a special case\n    if (units === 'week') {\n        this.weekday(0);\n    }\n    if (units === 'isoWeek') {\n        this.isoWeekday(1);\n    }\n\n    // quarters are also special\n    if (units === 'quarter') {\n        this.month(Math.floor(this.month() / 3) * 3);\n    }\n\n    return this;\n}\n\nfunction endOf (units) {\n    units = normalizeUnits(units);\n    if (units === undefined || units === 'millisecond') {\n        return this;\n    }\n\n    // 'date' is an alias for 'day', so it should be considered as such.\n    if (units === 'date') {\n        units = 'day';\n    }\n\n    return this.startOf(units).add(1, (units === 'isoWeek' ? 'week' : units)).subtract(1, 'ms');\n}\n\nfunction valueOf () {\n    return this._d.valueOf() - ((this._offset || 0) * 60000);\n}\n\nfunction unix () {\n    return Math.floor(this.valueOf() / 1000);\n}\n\nfunction toDate () {\n    return new Date(this.valueOf());\n}\n\nfunction toArray () {\n    var m = this;\n    return [m.year(), m.month(), m.date(), m.hour(), m.minute(), m.second(), m.millisecond()];\n}\n\nfunction toObject () {\n    var m = this;\n    return {\n        years: m.year(),\n        months: m.month(),\n        date: m.date(),\n        hours: m.hours(),\n        minutes: m.minutes(),\n        seconds: m.seconds(),\n        milliseconds: m.milliseconds()\n    };\n}\n\nfunction toJSON () {\n    // new Date(NaN).toJSON() === null\n    return this.isValid() ? this.toISOString() : null;\n}\n\nfunction isValid$2 () {\n    return isValid(this);\n}\n\nfunction parsingFlags () {\n    return extend({}, getParsingFlags(this));\n}\n\nfunction invalidAt () {\n    return getParsingFlags(this).overflow;\n}\n\nfunction creationData() {\n    return {\n        input: this._i,\n        format: this._f,\n        locale: this._locale,\n        isUTC: this._isUTC,\n        strict: this._strict\n    };\n}\n\n// FORMATTING\n\naddFormatToken(0, ['gg', 2], 0, function () {\n    return this.weekYear() % 100;\n});\n\naddFormatToken(0, ['GG', 2], 0, function () {\n    return this.isoWeekYear() % 100;\n});\n\nfunction addWeekYearFormatToken (token, getter) {\n    addFormatToken(0, [token, token.length], 0, getter);\n}\n\naddWeekYearFormatToken('gggg',     'weekYear');\naddWeekYearFormatToken('ggggg',    'weekYear');\naddWeekYearFormatToken('GGGG',  'isoWeekYear');\naddWeekYearFormatToken('GGGGG', 'isoWeekYear');\n\n// ALIASES\n\naddUnitAlias('weekYear', 'gg');\naddUnitAlias('isoWeekYear', 'GG');\n\n// PRIORITY\n\naddUnitPriority('weekYear', 1);\naddUnitPriority('isoWeekYear', 1);\n\n\n// PARSING\n\naddRegexToken('G',      matchSigned);\naddRegexToken('g',      matchSigned);\naddRegexToken('GG',     match1to2, match2);\naddRegexToken('gg',     match1to2, match2);\naddRegexToken('GGGG',   match1to4, match4);\naddRegexToken('gggg',   match1to4, match4);\naddRegexToken('GGGGG',  match1to6, match6);\naddRegexToken('ggggg',  match1to6, match6);\n\naddWeekParseToken(['gggg', 'ggggg', 'GGGG', 'GGGGG'], function (input, week, config, token) {\n    week[token.substr(0, 2)] = toInt(input);\n});\n\naddWeekParseToken(['gg', 'GG'], function (input, week, config, token) {\n    week[token] = hooks.parseTwoDigitYear(input);\n});\n\n// MOMENTS\n\nfunction getSetWeekYear (input) {\n    return getSetWeekYearHelper.call(this,\n            input,\n            this.week(),\n            this.weekday(),\n            this.localeData()._week.dow,\n            this.localeData()._week.doy);\n}\n\nfunction getSetISOWeekYear (input) {\n    return getSetWeekYearHelper.call(this,\n            input, this.isoWeek(), this.isoWeekday(), 1, 4);\n}\n\nfunction getISOWeeksInYear () {\n    return weeksInYear(this.year(), 1, 4);\n}\n\nfunction getWeeksInYear () {\n    var weekInfo = this.localeData()._week;\n    return weeksInYear(this.year(), weekInfo.dow, weekInfo.doy);\n}\n\nfunction getSetWeekYearHelper(input, week, weekday, dow, doy) {\n    var weeksTarget;\n    if (input == null) {\n        return weekOfYear(this, dow, doy).year;\n    } else {\n        weeksTarget = weeksInYear(input, dow, doy);\n        if (week > weeksTarget) {\n            week = weeksTarget;\n        }\n        return setWeekAll.call(this, input, week, weekday, dow, doy);\n    }\n}\n\nfunction setWeekAll(weekYear, week, weekday, dow, doy) {\n    var dayOfYearData = dayOfYearFromWeeks(weekYear, week, weekday, dow, doy),\n        date = createUTCDate(dayOfYearData.year, 0, dayOfYearData.dayOfYear);\n\n    this.year(date.getUTCFullYear());\n    this.month(date.getUTCMonth());\n    this.date(date.getUTCDate());\n    return this;\n}\n\n// FORMATTING\n\naddFormatToken('Q', 0, 'Qo', 'quarter');\n\n// ALIASES\n\naddUnitAlias('quarter', 'Q');\n\n// PRIORITY\n\naddUnitPriority('quarter', 7);\n\n// PARSING\n\naddRegexToken('Q', match1);\naddParseToken('Q', function (input, array) {\n    array[MONTH] = (toInt(input) - 1) * 3;\n});\n\n// MOMENTS\n\nfunction getSetQuarter (input) {\n    return input == null ? Math.ceil((this.month() + 1) / 3) : this.month((input - 1) * 3 + this.month() % 3);\n}\n\n// FORMATTING\n\naddFormatToken('D', ['DD', 2], 'Do', 'date');\n\n// ALIASES\n\naddUnitAlias('date', 'D');\n\n// PRIOROITY\naddUnitPriority('date', 9);\n\n// PARSING\n\naddRegexToken('D',  match1to2);\naddRegexToken('DD', match1to2, match2);\naddRegexToken('Do', function (isStrict, locale) {\n    // TODO: Remove \"ordinalParse\" fallback in next major release.\n    return isStrict ?\n      (locale._dayOfMonthOrdinalParse || locale._ordinalParse) :\n      locale._dayOfMonthOrdinalParseLenient;\n});\n\naddParseToken(['D', 'DD'], DATE);\naddParseToken('Do', function (input, array) {\n    array[DATE] = toInt(input.match(match1to2)[0], 10);\n});\n\n// MOMENTS\n\nvar getSetDayOfMonth = makeGetSet('Date', true);\n\n// FORMATTING\n\naddFormatToken('DDD', ['DDDD', 3], 'DDDo', 'dayOfYear');\n\n// ALIASES\n\naddUnitAlias('dayOfYear', 'DDD');\n\n// PRIORITY\naddUnitPriority('dayOfYear', 4);\n\n// PARSING\n\naddRegexToken('DDD',  match1to3);\naddRegexToken('DDDD', match3);\naddParseToken(['DDD', 'DDDD'], function (input, array, config) {\n    config._dayOfYear = toInt(input);\n});\n\n// HELPERS\n\n// MOMENTS\n\nfunction getSetDayOfYear (input) {\n    var dayOfYear = Math.round((this.clone().startOf('day') - this.clone().startOf('year')) / 864e5) + 1;\n    return input == null ? dayOfYear : this.add((input - dayOfYear), 'd');\n}\n\n// FORMATTING\n\naddFormatToken('m', ['mm', 2], 0, 'minute');\n\n// ALIASES\n\naddUnitAlias('minute', 'm');\n\n// PRIORITY\n\naddUnitPriority('minute', 14);\n\n// PARSING\n\naddRegexToken('m',  match1to2);\naddRegexToken('mm', match1to2, match2);\naddParseToken(['m', 'mm'], MINUTE);\n\n// MOMENTS\n\nvar getSetMinute = makeGetSet('Minutes', false);\n\n// FORMATTING\n\naddFormatToken('s', ['ss', 2], 0, 'second');\n\n// ALIASES\n\naddUnitAlias('second', 's');\n\n// PRIORITY\n\naddUnitPriority('second', 15);\n\n// PARSING\n\naddRegexToken('s',  match1to2);\naddRegexToken('ss', match1to2, match2);\naddParseToken(['s', 'ss'], SECOND);\n\n// MOMENTS\n\nvar getSetSecond = makeGetSet('Seconds', false);\n\n// FORMATTING\n\naddFormatToken('S', 0, 0, function () {\n    return ~~(this.millisecond() / 100);\n});\n\naddFormatToken(0, ['SS', 2], 0, function () {\n    return ~~(this.millisecond() / 10);\n});\n\naddFormatToken(0, ['SSS', 3], 0, 'millisecond');\naddFormatToken(0, ['SSSS', 4], 0, function () {\n    return this.millisecond() * 10;\n});\naddFormatToken(0, ['SSSSS', 5], 0, function () {\n    return this.millisecond() * 100;\n});\naddFormatToken(0, ['SSSSSS', 6], 0, function () {\n    return this.millisecond() * 1000;\n});\naddFormatToken(0, ['SSSSSSS', 7], 0, function () {\n    return this.millisecond() * 10000;\n});\naddFormatToken(0, ['SSSSSSSS', 8], 0, function () {\n    return this.millisecond() * 100000;\n});\naddFormatToken(0, ['SSSSSSSSS', 9], 0, function () {\n    return this.millisecond() * 1000000;\n});\n\n\n// ALIASES\n\naddUnitAlias('millisecond', 'ms');\n\n// PRIORITY\n\naddUnitPriority('millisecond', 16);\n\n// PARSING\n\naddRegexToken('S',    match1to3, match1);\naddRegexToken('SS',   match1to3, match2);\naddRegexToken('SSS',  match1to3, match3);\n\nvar token;\nfor (token = 'SSSS'; token.length <= 9; token += 'S') {\n    addRegexToken(token, matchUnsigned);\n}\n\nfunction parseMs(input, array) {\n    array[MILLISECOND] = toInt(('0.' + input) * 1000);\n}\n\nfor (token = 'S'; token.length <= 9; token += 'S') {\n    addParseToken(token, parseMs);\n}\n// MOMENTS\n\nvar getSetMillisecond = makeGetSet('Milliseconds', false);\n\n// FORMATTING\n\naddFormatToken('z',  0, 0, 'zoneAbbr');\naddFormatToken('zz', 0, 0, 'zoneName');\n\n// MOMENTS\n\nfunction getZoneAbbr () {\n    return this._isUTC ? 'UTC' : '';\n}\n\nfunction getZoneName () {\n    return this._isUTC ? 'Coordinated Universal Time' : '';\n}\n\nvar proto = Moment.prototype;\n\nproto.add               = add;\nproto.calendar          = calendar$1;\nproto.clone             = clone;\nproto.diff              = diff;\nproto.endOf             = endOf;\nproto.format            = format;\nproto.from              = from;\nproto.fromNow           = fromNow;\nproto.to                = to;\nproto.toNow             = toNow;\nproto.get               = stringGet;\nproto.invalidAt         = invalidAt;\nproto.isAfter           = isAfter;\nproto.isBefore          = isBefore;\nproto.isBetween         = isBetween;\nproto.isSame            = isSame;\nproto.isSameOrAfter     = isSameOrAfter;\nproto.isSameOrBefore    = isSameOrBefore;\nproto.isValid           = isValid$2;\nproto.lang              = lang;\nproto.locale            = locale;\nproto.localeData        = localeData;\nproto.max               = prototypeMax;\nproto.min               = prototypeMin;\nproto.parsingFlags      = parsingFlags;\nproto.set               = stringSet;\nproto.startOf           = startOf;\nproto.subtract          = subtract;\nproto.toArray           = toArray;\nproto.toObject          = toObject;\nproto.toDate            = toDate;\nproto.toISOString       = toISOString;\nproto.inspect           = inspect;\nproto.toJSON            = toJSON;\nproto.toString          = toString;\nproto.unix              = unix;\nproto.valueOf           = valueOf;\nproto.creationData      = creationData;\n\n// Year\nproto.year       = getSetYear;\nproto.isLeapYear = getIsLeapYear;\n\n// Week Year\nproto.weekYear    = getSetWeekYear;\nproto.isoWeekYear = getSetISOWeekYear;\n\n// Quarter\nproto.quarter = proto.quarters = getSetQuarter;\n\n// Month\nproto.month       = getSetMonth;\nproto.daysInMonth = getDaysInMonth;\n\n// Week\nproto.week           = proto.weeks        = getSetWeek;\nproto.isoWeek        = proto.isoWeeks     = getSetISOWeek;\nproto.weeksInYear    = getWeeksInYear;\nproto.isoWeeksInYear = getISOWeeksInYear;\n\n// Day\nproto.date       = getSetDayOfMonth;\nproto.day        = proto.days             = getSetDayOfWeek;\nproto.weekday    = getSetLocaleDayOfWeek;\nproto.isoWeekday = getSetISODayOfWeek;\nproto.dayOfYear  = getSetDayOfYear;\n\n// Hour\nproto.hour = proto.hours = getSetHour;\n\n// Minute\nproto.minute = proto.minutes = getSetMinute;\n\n// Second\nproto.second = proto.seconds = getSetSecond;\n\n// Millisecond\nproto.millisecond = proto.milliseconds = getSetMillisecond;\n\n// Offset\nproto.utcOffset            = getSetOffset;\nproto.utc                  = setOffsetToUTC;\nproto.local                = setOffsetToLocal;\nproto.parseZone            = setOffsetToParsedOffset;\nproto.hasAlignedHourOffset = hasAlignedHourOffset;\nproto.isDST                = isDaylightSavingTime;\nproto.isLocal              = isLocal;\nproto.isUtcOffset          = isUtcOffset;\nproto.isUtc                = isUtc;\nproto.isUTC                = isUtc;\n\n// Timezone\nproto.zoneAbbr = getZoneAbbr;\nproto.zoneName = getZoneName;\n\n// Deprecations\nproto.dates  = deprecate('dates accessor is deprecated. Use date instead.', getSetDayOfMonth);\nproto.months = deprecate('months accessor is deprecated. Use month instead', getSetMonth);\nproto.years  = deprecate('years accessor is deprecated. Use year instead', getSetYear);\nproto.zone   = deprecate('moment().zone is deprecated, use moment().utcOffset instead. http://momentjs.com/guides/#/warnings/zone/', getSetZone);\nproto.isDSTShifted = deprecate('isDSTShifted is deprecated. See http://momentjs.com/guides/#/warnings/dst-shifted/ for more information', isDaylightSavingTimeShifted);\n\nfunction createUnix (input) {\n    return createLocal(input * 1000);\n}\n\nfunction createInZone () {\n    return createLocal.apply(null, arguments).parseZone();\n}\n\nfunction preParsePostFormat (string) {\n    return string;\n}\n\nvar proto$1 = Locale.prototype;\n\nproto$1.calendar        = calendar;\nproto$1.longDateFormat  = longDateFormat;\nproto$1.invalidDate     = invalidDate;\nproto$1.ordinal         = ordinal;\nproto$1.preparse        = preParsePostFormat;\nproto$1.postformat      = preParsePostFormat;\nproto$1.relativeTime    = relativeTime;\nproto$1.pastFuture      = pastFuture;\nproto$1.set             = set;\n\n// Month\nproto$1.months            =        localeMonths;\nproto$1.monthsShort       =        localeMonthsShort;\nproto$1.monthsParse       =        localeMonthsParse;\nproto$1.monthsRegex       = monthsRegex;\nproto$1.monthsShortRegex  = monthsShortRegex;\n\n// Week\nproto$1.week = localeWeek;\nproto$1.firstDayOfYear = localeFirstDayOfYear;\nproto$1.firstDayOfWeek = localeFirstDayOfWeek;\n\n// Day of Week\nproto$1.weekdays       =        localeWeekdays;\nproto$1.weekdaysMin    =        localeWeekdaysMin;\nproto$1.weekdaysShort  =        localeWeekdaysShort;\nproto$1.weekdaysParse  =        localeWeekdaysParse;\n\nproto$1.weekdaysRegex       =        weekdaysRegex;\nproto$1.weekdaysShortRegex  =        weekdaysShortRegex;\nproto$1.weekdaysMinRegex    =        weekdaysMinRegex;\n\n// Hours\nproto$1.isPM = localeIsPM;\nproto$1.meridiem = localeMeridiem;\n\nfunction get$1 (format, index, field, setter) {\n    var locale = getLocale();\n    var utc = createUTC().set(setter, index);\n    return locale[field](utc, format);\n}\n\nfunction listMonthsImpl (format, index, field) {\n    if (isNumber(format)) {\n        index = format;\n        format = undefined;\n    }\n\n    format = format || '';\n\n    if (index != null) {\n        return get$1(format, index, field, 'month');\n    }\n\n    var i;\n    var out = [];\n    for (i = 0; i < 12; i++) {\n        out[i] = get$1(format, i, field, 'month');\n    }\n    return out;\n}\n\n// ()\n// (5)\n// (fmt, 5)\n// (fmt)\n// (true)\n// (true, 5)\n// (true, fmt, 5)\n// (true, fmt)\nfunction listWeekdaysImpl (localeSorted, format, index, field) {\n    if (typeof localeSorted === 'boolean') {\n        if (isNumber(format)) {\n            index = format;\n            format = undefined;\n        }\n\n        format = format || '';\n    } else {\n        format = localeSorted;\n        index = format;\n        localeSorted = false;\n\n        if (isNumber(format)) {\n            index = format;\n            format = undefined;\n        }\n\n        format = format || '';\n    }\n\n    var locale = getLocale(),\n        shift = localeSorted ? locale._week.dow : 0;\n\n    if (index != null) {\n        return get$1(format, (index + shift) % 7, field, 'day');\n    }\n\n    var i;\n    var out = [];\n    for (i = 0; i < 7; i++) {\n        out[i] = get$1(format, (i + shift) % 7, field, 'day');\n    }\n    return out;\n}\n\nfunction listMonths (format, index) {\n    return listMonthsImpl(format, index, 'months');\n}\n\nfunction listMonthsShort (format, index) {\n    return listMonthsImpl(format, index, 'monthsShort');\n}\n\nfunction listWeekdays (localeSorted, format, index) {\n    return listWeekdaysImpl(localeSorted, format, index, 'weekdays');\n}\n\nfunction listWeekdaysShort (localeSorted, format, index) {\n    return listWeekdaysImpl(localeSorted, format, index, 'weekdaysShort');\n}\n\nfunction listWeekdaysMin (localeSorted, format, index) {\n    return listWeekdaysImpl(localeSorted, format, index, 'weekdaysMin');\n}\n\ngetSetGlobalLocale('en', {\n    dayOfMonthOrdinalParse: /\\d{1,2}(th|st|nd|rd)/,\n    ordinal : function (number) {\n        var b = number % 10,\n            output = (toInt(number % 100 / 10) === 1) ? 'th' :\n            (b === 1) ? 'st' :\n            (b === 2) ? 'nd' :\n            (b === 3) ? 'rd' : 'th';\n        return number + output;\n    }\n});\n\n// Side effect imports\nhooks.lang = deprecate('moment.lang is deprecated. Use moment.locale instead.', getSetGlobalLocale);\nhooks.langData = deprecate('moment.langData is deprecated. Use moment.localeData instead.', getLocale);\n\nvar mathAbs = Math.abs;\n\nfunction abs () {\n    var data           = this._data;\n\n    this._milliseconds = mathAbs(this._milliseconds);\n    this._days         = mathAbs(this._days);\n    this._months       = mathAbs(this._months);\n\n    data.milliseconds  = mathAbs(data.milliseconds);\n    data.seconds       = mathAbs(data.seconds);\n    data.minutes       = mathAbs(data.minutes);\n    data.hours         = mathAbs(data.hours);\n    data.months        = mathAbs(data.months);\n    data.years         = mathAbs(data.years);\n\n    return this;\n}\n\nfunction addSubtract$1 (duration, input, value, direction) {\n    var other = createDuration(input, value);\n\n    duration._milliseconds += direction * other._milliseconds;\n    duration._days         += direction * other._days;\n    duration._months       += direction * other._months;\n\n    return duration._bubble();\n}\n\n// supports only 2.0-style add(1, 's') or add(duration)\nfunction add$1 (input, value) {\n    return addSubtract$1(this, input, value, 1);\n}\n\n// supports only 2.0-style subtract(1, 's') or subtract(duration)\nfunction subtract$1 (input, value) {\n    return addSubtract$1(this, input, value, -1);\n}\n\nfunction absCeil (number) {\n    if (number < 0) {\n        return Math.floor(number);\n    } else {\n        return Math.ceil(number);\n    }\n}\n\nfunction bubble () {\n    var milliseconds = this._milliseconds;\n    var days         = this._days;\n    var months       = this._months;\n    var data         = this._data;\n    var seconds, minutes, hours, years, monthsFromDays;\n\n    // if we have a mix of positive and negative values, bubble down first\n    // check: https://github.com/moment/moment/issues/2166\n    if (!((milliseconds >= 0 && days >= 0 && months >= 0) ||\n            (milliseconds <= 0 && days <= 0 && months <= 0))) {\n        milliseconds += absCeil(monthsToDays(months) + days) * 864e5;\n        days = 0;\n        months = 0;\n    }\n\n    // The following code bubbles up values, see the tests for\n    // examples of what that means.\n    data.milliseconds = milliseconds % 1000;\n\n    seconds           = absFloor(milliseconds / 1000);\n    data.seconds      = seconds % 60;\n\n    minutes           = absFloor(seconds / 60);\n    data.minutes      = minutes % 60;\n\n    hours             = absFloor(minutes / 60);\n    data.hours        = hours % 24;\n\n    days += absFloor(hours / 24);\n\n    // convert days to months\n    monthsFromDays = absFloor(daysToMonths(days));\n    months += monthsFromDays;\n    days -= absCeil(monthsToDays(monthsFromDays));\n\n    // 12 months -> 1 year\n    years = absFloor(months / 12);\n    months %= 12;\n\n    data.days   = days;\n    data.months = months;\n    data.years  = years;\n\n    return this;\n}\n\nfunction daysToMonths (days) {\n    // 400 years have 146097 days (taking into account leap year rules)\n    // 400 years have 12 months === 4800\n    return days * 4800 / 146097;\n}\n\nfunction monthsToDays (months) {\n    // the reverse of daysToMonths\n    return months * 146097 / 4800;\n}\n\nfunction as (units) {\n    if (!this.isValid()) {\n        return NaN;\n    }\n    var days;\n    var months;\n    var milliseconds = this._milliseconds;\n\n    units = normalizeUnits(units);\n\n    if (units === 'month' || units === 'year') {\n        days   = this._days   + milliseconds / 864e5;\n        months = this._months + daysToMonths(days);\n        return units === 'month' ? months : months / 12;\n    } else {\n        // handle milliseconds separately because of floating point math errors (issue #1867)\n        days = this._days + Math.round(monthsToDays(this._months));\n        switch (units) {\n            case 'week'   : return days / 7     + milliseconds / 6048e5;\n            case 'day'    : return days         + milliseconds / 864e5;\n            case 'hour'   : return days * 24    + milliseconds / 36e5;\n            case 'minute' : return days * 1440  + milliseconds / 6e4;\n            case 'second' : return days * 86400 + milliseconds / 1000;\n            // Math.floor prevents floating point math errors here\n            case 'millisecond': return Math.floor(days * 864e5) + milliseconds;\n            default: throw new Error('Unknown unit ' + units);\n        }\n    }\n}\n\n// TODO: Use this.as('ms')?\nfunction valueOf$1 () {\n    if (!this.isValid()) {\n        return NaN;\n    }\n    return (\n        this._milliseconds +\n        this._days * 864e5 +\n        (this._months % 12) * 2592e6 +\n        toInt(this._months / 12) * 31536e6\n    );\n}\n\nfunction makeAs (alias) {\n    return function () {\n        return this.as(alias);\n    };\n}\n\nvar asMilliseconds = makeAs('ms');\nvar asSeconds      = makeAs('s');\nvar asMinutes      = makeAs('m');\nvar asHours        = makeAs('h');\nvar asDays         = makeAs('d');\nvar asWeeks        = makeAs('w');\nvar asMonths       = makeAs('M');\nvar asYears        = makeAs('y');\n\nfunction get$2 (units) {\n    units = normalizeUnits(units);\n    return this.isValid() ? this[units + 's']() : NaN;\n}\n\nfunction makeGetter(name) {\n    return function () {\n        return this.isValid() ? this._data[name] : NaN;\n    };\n}\n\nvar milliseconds = makeGetter('milliseconds');\nvar seconds      = makeGetter('seconds');\nvar minutes      = makeGetter('minutes');\nvar hours        = makeGetter('hours');\nvar days         = makeGetter('days');\nvar months       = makeGetter('months');\nvar years        = makeGetter('years');\n\nfunction weeks () {\n    return absFloor(this.days() / 7);\n}\n\nvar round = Math.round;\nvar thresholds = {\n    ss: 44,         // a few seconds to seconds\n    s : 45,         // seconds to minute\n    m : 45,         // minutes to hour\n    h : 22,         // hours to day\n    d : 26,         // days to month\n    M : 11          // months to year\n};\n\n// helper function for moment.fn.from, moment.fn.fromNow, and moment.duration.fn.humanize\nfunction substituteTimeAgo(string, number, withoutSuffix, isFuture, locale) {\n    return locale.relativeTime(number || 1, !!withoutSuffix, string, isFuture);\n}\n\nfunction relativeTime$1 (posNegDuration, withoutSuffix, locale) {\n    var duration = createDuration(posNegDuration).abs();\n    var seconds  = round(duration.as('s'));\n    var minutes  = round(duration.as('m'));\n    var hours    = round(duration.as('h'));\n    var days     = round(duration.as('d'));\n    var months   = round(duration.as('M'));\n    var years    = round(duration.as('y'));\n\n    var a = seconds <= thresholds.ss && ['s', seconds]  ||\n            seconds < thresholds.s   && ['ss', seconds] ||\n            minutes <= 1             && ['m']           ||\n            minutes < thresholds.m   && ['mm', minutes] ||\n            hours   <= 1             && ['h']           ||\n            hours   < thresholds.h   && ['hh', hours]   ||\n            days    <= 1             && ['d']           ||\n            days    < thresholds.d   && ['dd', days]    ||\n            months  <= 1             && ['M']           ||\n            months  < thresholds.M   && ['MM', months]  ||\n            years   <= 1             && ['y']           || ['yy', years];\n\n    a[2] = withoutSuffix;\n    a[3] = +posNegDuration > 0;\n    a[4] = locale;\n    return substituteTimeAgo.apply(null, a);\n}\n\n// This function allows you to set the rounding function for relative time strings\nfunction getSetRelativeTimeRounding (roundingFunction) {\n    if (roundingFunction === undefined) {\n        return round;\n    }\n    if (typeof(roundingFunction) === 'function') {\n        round = roundingFunction;\n        return true;\n    }\n    return false;\n}\n\n// This function allows you to set a threshold for relative time strings\nfunction getSetRelativeTimeThreshold (threshold, limit) {\n    if (thresholds[threshold] === undefined) {\n        return false;\n    }\n    if (limit === undefined) {\n        return thresholds[threshold];\n    }\n    thresholds[threshold] = limit;\n    if (threshold === 's') {\n        thresholds.ss = limit - 1;\n    }\n    return true;\n}\n\nfunction humanize (withSuffix) {\n    if (!this.isValid()) {\n        return this.localeData().invalidDate();\n    }\n\n    var locale = this.localeData();\n    var output = relativeTime$1(this, !withSuffix, locale);\n\n    if (withSuffix) {\n        output = locale.pastFuture(+this, output);\n    }\n\n    return locale.postformat(output);\n}\n\nvar abs$1 = Math.abs;\n\nfunction toISOString$1() {\n    // for ISO strings we do not use the normal bubbling rules:\n    //  * milliseconds bubble up until they become hours\n    //  * days do not bubble at all\n    //  * months bubble up until they become years\n    // This is because there is no context-free conversion between hours and days\n    // (think of clock changes)\n    // and also not between days and months (28-31 days per month)\n    if (!this.isValid()) {\n        return this.localeData().invalidDate();\n    }\n\n    var seconds = abs$1(this._milliseconds) / 1000;\n    var days         = abs$1(this._days);\n    var months       = abs$1(this._months);\n    var minutes, hours, years;\n\n    // 3600 seconds -> 60 minutes -> 1 hour\n    minutes           = absFloor(seconds / 60);\n    hours             = absFloor(minutes / 60);\n    seconds %= 60;\n    minutes %= 60;\n\n    // 12 months -> 1 year\n    years  = absFloor(months / 12);\n    months %= 12;\n\n\n    // inspired by https://github.com/dordille/moment-isoduration/blob/master/moment.isoduration.js\n    var Y = years;\n    var M = months;\n    var D = days;\n    var h = hours;\n    var m = minutes;\n    var s = seconds;\n    var total = this.asSeconds();\n\n    if (!total) {\n        // this is the same as C#'s (Noda) and python (isodate)...\n        // but not other JS (goog.date)\n        return 'P0D';\n    }\n\n    return (total < 0 ? '-' : '') +\n        'P' +\n        (Y ? Y + 'Y' : '') +\n        (M ? M + 'M' : '') +\n        (D ? D + 'D' : '') +\n        ((h || m || s) ? 'T' : '') +\n        (h ? h + 'H' : '') +\n        (m ? m + 'M' : '') +\n        (s ? s + 'S' : '');\n}\n\nvar proto$2 = Duration.prototype;\n\nproto$2.isValid        = isValid$1;\nproto$2.abs            = abs;\nproto$2.add            = add$1;\nproto$2.subtract       = subtract$1;\nproto$2.as             = as;\nproto$2.asMilliseconds = asMilliseconds;\nproto$2.asSeconds      = asSeconds;\nproto$2.asMinutes      = asMinutes;\nproto$2.asHours        = asHours;\nproto$2.asDays         = asDays;\nproto$2.asWeeks        = asWeeks;\nproto$2.asMonths       = asMonths;\nproto$2.asYears        = asYears;\nproto$2.valueOf        = valueOf$1;\nproto$2._bubble        = bubble;\nproto$2.get            = get$2;\nproto$2.milliseconds   = milliseconds;\nproto$2.seconds        = seconds;\nproto$2.minutes        = minutes;\nproto$2.hours          = hours;\nproto$2.days           = days;\nproto$2.weeks          = weeks;\nproto$2.months         = months;\nproto$2.years          = years;\nproto$2.humanize       = humanize;\nproto$2.toISOString    = toISOString$1;\nproto$2.toString       = toISOString$1;\nproto$2.toJSON         = toISOString$1;\nproto$2.locale         = locale;\nproto$2.localeData     = localeData;\n\n// Deprecations\nproto$2.toIsoString = deprecate('toIsoString() is deprecated. Please use toISOString() instead (notice the capitals)', toISOString$1);\nproto$2.lang = lang;\n\n// Side effect imports\n\n// FORMATTING\n\naddFormatToken('X', 0, 0, 'unix');\naddFormatToken('x', 0, 0, 'valueOf');\n\n// PARSING\n\naddRegexToken('x', matchSigned);\naddRegexToken('X', matchTimestamp);\naddParseToken('X', function (input, array, config) {\n    config._d = new Date(parseFloat(input, 10) * 1000);\n});\naddParseToken('x', function (input, array, config) {\n    config._d = new Date(toInt(input));\n});\n\n// Side effect imports\n\n//! moment.js\n//! version : 2.18.1\n//! authors : Tim Wood, Iskren Chernev, Moment.js contributors\n//! license : MIT\n//! momentjs.com\n\nhooks.version = '2.18.1';\n\nsetHookCallback(createLocal);\n\nhooks.fn                    = proto;\nhooks.min                   = min;\nhooks.max                   = max;\nhooks.now                   = now;\nhooks.utc                   = createUTC;\nhooks.unix                  = createUnix;\nhooks.months                = listMonths;\nhooks.isDate                = isDate;\nhooks.locale                = getSetGlobalLocale;\nhooks.invalid               = createInvalid;\nhooks.duration              = createDuration;\nhooks.isMoment              = isMoment;\nhooks.weekdays              = listWeekdays;\nhooks.parseZone             = createInZone;\nhooks.localeData            = getLocale;\nhooks.isDuration            = isDuration;\nhooks.monthsShort           = listMonthsShort;\nhooks.weekdaysMin           = listWeekdaysMin;\nhooks.defineLocale          = defineLocale;\nhooks.updateLocale          = updateLocale;\nhooks.locales               = listLocales;\nhooks.weekdaysShort         = listWeekdaysShort;\nhooks.normalizeUnits        = normalizeUnits;\nhooks.relativeTimeRounding = getSetRelativeTimeRounding;\nhooks.relativeTimeThreshold = getSetRelativeTimeThreshold;\nhooks.calendarFormat        = getCalendarFormat;\nhooks.prototype             = proto;\n\n//! moment.js locale configuration\n//! locale : Afrikaans [af]\n//! author : Werner Mollentze : https://github.com/wernerm\n\nhooks.defineLocale('af', {\n    months : 'Januarie_Februarie_Maart_April_Mei_Junie_Julie_Augustus_September_Oktober_November_Desember'.split('_'),\n    monthsShort : 'Jan_Feb_Mrt_Apr_Mei_Jun_Jul_Aug_Sep_Okt_Nov_Des'.split('_'),\n    weekdays : 'Sondag_Maandag_Dinsdag_Woensdag_Donderdag_Vrydag_Saterdag'.split('_'),\n    weekdaysShort : 'Son_Maa_Din_Woe_Don_Vry_Sat'.split('_'),\n    weekdaysMin : 'So_Ma_Di_Wo_Do_Vr_Sa'.split('_'),\n    meridiemParse: /vm|nm/i,\n    isPM : function (input) {\n        return /^nm$/i.test(input);\n    },\n    meridiem : function (hours, minutes, isLower) {\n        if (hours < 12) {\n            return isLower ? 'vm' : 'VM';\n        } else {\n            return isLower ? 'nm' : 'NM';\n        }\n    },\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY HH:mm',\n        LLLL : 'dddd, D MMMM YYYY HH:mm'\n    },\n    calendar : {\n        sameDay : '[Vandag om] LT',\n        nextDay : '[Môre om] LT',\n        nextWeek : 'dddd [om] LT',\n        lastDay : '[Gister om] LT',\n        lastWeek : '[Laas] dddd [om] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'oor %s',\n        past : '%s gelede',\n        s : '\\'n paar sekondes',\n        m : '\\'n minuut',\n        mm : '%d minute',\n        h : '\\'n uur',\n        hh : '%d ure',\n        d : '\\'n dag',\n        dd : '%d dae',\n        M : '\\'n maand',\n        MM : '%d maande',\n        y : '\\'n jaar',\n        yy : '%d jaar'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}(ste|de)/,\n    ordinal : function (number) {\n        return number + ((number === 1 || number === 8 || number >= 20) ? 'ste' : 'de'); // Thanks to Joris Röling : https://github.com/jjupiter\n    },\n    week : {\n        dow : 1, // Maandag is die eerste dag van die week.\n        doy : 4  // Die week wat die 4de Januarie bevat is die eerste week van die jaar.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Arabic (Algeria) [ar-dz]\n//! author : Noureddine LOUAHEDJ : https://github.com/noureddineme\n\nhooks.defineLocale('ar-dz', {\n    months : 'جانفي_فيفري_مارس_أفريل_ماي_جوان_جويلية_أوت_سبتمبر_أكتوبر_نوفمبر_ديسمبر'.split('_'),\n    monthsShort : 'جانفي_فيفري_مارس_أفريل_ماي_جوان_جويلية_أوت_سبتمبر_أكتوبر_نوفمبر_ديسمبر'.split('_'),\n    weekdays : 'الأحد_الإثنين_الثلاثاء_الأربعاء_الخميس_الجمعة_السبت'.split('_'),\n    weekdaysShort : 'احد_اثنين_ثلاثاء_اربعاء_خميس_جمعة_سبت'.split('_'),\n    weekdaysMin : 'أح_إث_ثلا_أر_خم_جم_سب'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY HH:mm',\n        LLLL : 'dddd D MMMM YYYY HH:mm'\n    },\n    calendar : {\n        sameDay: '[اليوم على الساعة] LT',\n        nextDay: '[غدا على الساعة] LT',\n        nextWeek: 'dddd [على الساعة] LT',\n        lastDay: '[أمس على الساعة] LT',\n        lastWeek: 'dddd [على الساعة] LT',\n        sameElse: 'L'\n    },\n    relativeTime : {\n        future : 'في %s',\n        past : 'منذ %s',\n        s : 'ثوان',\n        m : 'دقيقة',\n        mm : '%d دقائق',\n        h : 'ساعة',\n        hh : '%d ساعات',\n        d : 'يوم',\n        dd : '%d أيام',\n        M : 'شهر',\n        MM : '%d أشهر',\n        y : 'سنة',\n        yy : '%d سنوات'\n    },\n    week : {\n        dow : 0, // Sunday is the first day of the week.\n        doy : 4  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Arabic (Kuwait) [ar-kw]\n//! author : Nusret Parlak: https://github.com/nusretparlak\n\nhooks.defineLocale('ar-kw', {\n    months : 'يناير_فبراير_مارس_أبريل_ماي_يونيو_يوليوز_غشت_شتنبر_أكتوبر_نونبر_دجنبر'.split('_'),\n    monthsShort : 'يناير_فبراير_مارس_أبريل_ماي_يونيو_يوليوز_غشت_شتنبر_أكتوبر_نونبر_دجنبر'.split('_'),\n    weekdays : 'الأحد_الإتنين_الثلاثاء_الأربعاء_الخميس_الجمعة_السبت'.split('_'),\n    weekdaysShort : 'احد_اتنين_ثلاثاء_اربعاء_خميس_جمعة_سبت'.split('_'),\n    weekdaysMin : 'ح_ن_ث_ر_خ_ج_س'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY HH:mm',\n        LLLL : 'dddd D MMMM YYYY HH:mm'\n    },\n    calendar : {\n        sameDay: '[اليوم على الساعة] LT',\n        nextDay: '[غدا على الساعة] LT',\n        nextWeek: 'dddd [على الساعة] LT',\n        lastDay: '[أمس على الساعة] LT',\n        lastWeek: 'dddd [على الساعة] LT',\n        sameElse: 'L'\n    },\n    relativeTime : {\n        future : 'في %s',\n        past : 'منذ %s',\n        s : 'ثوان',\n        m : 'دقيقة',\n        mm : '%d دقائق',\n        h : 'ساعة',\n        hh : '%d ساعات',\n        d : 'يوم',\n        dd : '%d أيام',\n        M : 'شهر',\n        MM : '%d أشهر',\n        y : 'سنة',\n        yy : '%d سنوات'\n    },\n    week : {\n        dow : 0, // Sunday is the first day of the week.\n        doy : 12  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Arabic (Lybia) [ar-ly]\n//! author : Ali Hmer: https://github.com/kikoanis\n\nvar symbolMap = {\n    '1': '1',\n    '2': '2',\n    '3': '3',\n    '4': '4',\n    '5': '5',\n    '6': '6',\n    '7': '7',\n    '8': '8',\n    '9': '9',\n    '0': '0'\n};\nvar pluralForm = function (n) {\n    return n === 0 ? 0 : n === 1 ? 1 : n === 2 ? 2 : n % 100 >= 3 && n % 100 <= 10 ? 3 : n % 100 >= 11 ? 4 : 5;\n};\nvar plurals = {\n    s : ['أقل من ثانية', 'ثانية واحدة', ['ثانيتان', 'ثانيتين'], '%d ثوان', '%d ثانية', '%d ثانية'],\n    m : ['أقل من دقيقة', 'دقيقة واحدة', ['دقيقتان', 'دقيقتين'], '%d دقائق', '%d دقيقة', '%d دقيقة'],\n    h : ['أقل من ساعة', 'ساعة واحدة', ['ساعتان', 'ساعتين'], '%d ساعات', '%d ساعة', '%d ساعة'],\n    d : ['أقل من يوم', 'يوم واحد', ['يومان', 'يومين'], '%d أيام', '%d يومًا', '%d يوم'],\n    M : ['أقل من شهر', 'شهر واحد', ['شهران', 'شهرين'], '%d أشهر', '%d شهرا', '%d شهر'],\n    y : ['أقل من عام', 'عام واحد', ['عامان', 'عامين'], '%d أعوام', '%d عامًا', '%d عام']\n};\nvar pluralize = function (u) {\n    return function (number, withoutSuffix, string, isFuture) {\n        var f = pluralForm(number),\n            str = plurals[u][pluralForm(number)];\n        if (f === 2) {\n            str = str[withoutSuffix ? 0 : 1];\n        }\n        return str.replace(/%d/i, number);\n    };\n};\nvar months$1 = [\n    'يناير',\n    'فبراير',\n    'مارس',\n    'أبريل',\n    'مايو',\n    'يونيو',\n    'يوليو',\n    'أغسطس',\n    'سبتمبر',\n    'أكتوبر',\n    'نوفمبر',\n    'ديسمبر'\n];\n\nhooks.defineLocale('ar-ly', {\n    months : months$1,\n    monthsShort : months$1,\n    weekdays : 'الأحد_الإثنين_الثلاثاء_الأربعاء_الخميس_الجمعة_السبت'.split('_'),\n    weekdaysShort : 'أحد_إثنين_ثلاثاء_أربعاء_خميس_جمعة_سبت'.split('_'),\n    weekdaysMin : 'ح_ن_ث_ر_خ_ج_س'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'D/\\u200FM/\\u200FYYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY HH:mm',\n        LLLL : 'dddd D MMMM YYYY HH:mm'\n    },\n    meridiemParse: /ص|م/,\n    isPM : function (input) {\n        return 'م' === input;\n    },\n    meridiem : function (hour, minute, isLower) {\n        if (hour < 12) {\n            return 'ص';\n        } else {\n            return 'م';\n        }\n    },\n    calendar : {\n        sameDay: '[اليوم عند الساعة] LT',\n        nextDay: '[غدًا عند الساعة] LT',\n        nextWeek: 'dddd [عند الساعة] LT',\n        lastDay: '[أمس عند الساعة] LT',\n        lastWeek: 'dddd [عند الساعة] LT',\n        sameElse: 'L'\n    },\n    relativeTime : {\n        future : 'بعد %s',\n        past : 'منذ %s',\n        s : pluralize('s'),\n        m : pluralize('m'),\n        mm : pluralize('m'),\n        h : pluralize('h'),\n        hh : pluralize('h'),\n        d : pluralize('d'),\n        dd : pluralize('d'),\n        M : pluralize('M'),\n        MM : pluralize('M'),\n        y : pluralize('y'),\n        yy : pluralize('y')\n    },\n    preparse: function (string) {\n        return string.replace(/\\u200f/g, '').replace(/،/g, ',');\n    },\n    postformat: function (string) {\n        return string.replace(/\\d/g, function (match) {\n            return symbolMap[match];\n        }).replace(/,/g, '،');\n    },\n    week : {\n        dow : 6, // Saturday is the first day of the week.\n        doy : 12  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Arabic (Morocco) [ar-ma]\n//! author : ElFadili Yassine : https://github.com/ElFadiliY\n//! author : Abdel Said : https://github.com/abdelsaid\n\nhooks.defineLocale('ar-ma', {\n    months : 'يناير_فبراير_مارس_أبريل_ماي_يونيو_يوليوز_غشت_شتنبر_أكتوبر_نونبر_دجنبر'.split('_'),\n    monthsShort : 'يناير_فبراير_مارس_أبريل_ماي_يونيو_يوليوز_غشت_شتنبر_أكتوبر_نونبر_دجنبر'.split('_'),\n    weekdays : 'الأحد_الإتنين_الثلاثاء_الأربعاء_الخميس_الجمعة_السبت'.split('_'),\n    weekdaysShort : 'احد_اتنين_ثلاثاء_اربعاء_خميس_جمعة_سبت'.split('_'),\n    weekdaysMin : 'ح_ن_ث_ر_خ_ج_س'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY HH:mm',\n        LLLL : 'dddd D MMMM YYYY HH:mm'\n    },\n    calendar : {\n        sameDay: '[اليوم على الساعة] LT',\n        nextDay: '[غدا على الساعة] LT',\n        nextWeek: 'dddd [على الساعة] LT',\n        lastDay: '[أمس على الساعة] LT',\n        lastWeek: 'dddd [على الساعة] LT',\n        sameElse: 'L'\n    },\n    relativeTime : {\n        future : 'في %s',\n        past : 'منذ %s',\n        s : 'ثوان',\n        m : 'دقيقة',\n        mm : '%d دقائق',\n        h : 'ساعة',\n        hh : '%d ساعات',\n        d : 'يوم',\n        dd : '%d أيام',\n        M : 'شهر',\n        MM : '%d أشهر',\n        y : 'سنة',\n        yy : '%d سنوات'\n    },\n    week : {\n        dow : 6, // Saturday is the first day of the week.\n        doy : 12  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Arabic (Saudi Arabia) [ar-sa]\n//! author : Suhail Alkowaileet : https://github.com/xsoh\n\nvar symbolMap$1 = {\n    '1': '١',\n    '2': '٢',\n    '3': '٣',\n    '4': '٤',\n    '5': '٥',\n    '6': '٦',\n    '7': '٧',\n    '8': '٨',\n    '9': '٩',\n    '0': '٠'\n};\nvar numberMap = {\n    '١': '1',\n    '٢': '2',\n    '٣': '3',\n    '٤': '4',\n    '٥': '5',\n    '٦': '6',\n    '٧': '7',\n    '٨': '8',\n    '٩': '9',\n    '٠': '0'\n};\n\nhooks.defineLocale('ar-sa', {\n    months : 'يناير_فبراير_مارس_أبريل_مايو_يونيو_يوليو_أغسطس_سبتمبر_أكتوبر_نوفمبر_ديسمبر'.split('_'),\n    monthsShort : 'يناير_فبراير_مارس_أبريل_مايو_يونيو_يوليو_أغسطس_سبتمبر_أكتوبر_نوفمبر_ديسمبر'.split('_'),\n    weekdays : 'الأحد_الإثنين_الثلاثاء_الأربعاء_الخميس_الجمعة_السبت'.split('_'),\n    weekdaysShort : 'أحد_إثنين_ثلاثاء_أربعاء_خميس_جمعة_سبت'.split('_'),\n    weekdaysMin : 'ح_ن_ث_ر_خ_ج_س'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY HH:mm',\n        LLLL : 'dddd D MMMM YYYY HH:mm'\n    },\n    meridiemParse: /ص|م/,\n    isPM : function (input) {\n        return 'م' === input;\n    },\n    meridiem : function (hour, minute, isLower) {\n        if (hour < 12) {\n            return 'ص';\n        } else {\n            return 'م';\n        }\n    },\n    calendar : {\n        sameDay: '[اليوم على الساعة] LT',\n        nextDay: '[غدا على الساعة] LT',\n        nextWeek: 'dddd [على الساعة] LT',\n        lastDay: '[أمس على الساعة] LT',\n        lastWeek: 'dddd [على الساعة] LT',\n        sameElse: 'L'\n    },\n    relativeTime : {\n        future : 'في %s',\n        past : 'منذ %s',\n        s : 'ثوان',\n        m : 'دقيقة',\n        mm : '%d دقائق',\n        h : 'ساعة',\n        hh : '%d ساعات',\n        d : 'يوم',\n        dd : '%d أيام',\n        M : 'شهر',\n        MM : '%d أشهر',\n        y : 'سنة',\n        yy : '%d سنوات'\n    },\n    preparse: function (string) {\n        return string.replace(/[١٢٣٤٥٦٧٨٩٠]/g, function (match) {\n            return numberMap[match];\n        }).replace(/،/g, ',');\n    },\n    postformat: function (string) {\n        return string.replace(/\\d/g, function (match) {\n            return symbolMap$1[match];\n        }).replace(/,/g, '،');\n    },\n    week : {\n        dow : 0, // Sunday is the first day of the week.\n        doy : 6  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale  :  Arabic (Tunisia) [ar-tn]\n//! author : Nader Toukabri : https://github.com/naderio\n\nhooks.defineLocale('ar-tn', {\n    months: 'جانفي_فيفري_مارس_أفريل_ماي_جوان_جويلية_أوت_سبتمبر_أكتوبر_نوفمبر_ديسمبر'.split('_'),\n    monthsShort: 'جانفي_فيفري_مارس_أفريل_ماي_جوان_جويلية_أوت_سبتمبر_أكتوبر_نوفمبر_ديسمبر'.split('_'),\n    weekdays: 'الأحد_الإثنين_الثلاثاء_الأربعاء_الخميس_الجمعة_السبت'.split('_'),\n    weekdaysShort: 'أحد_إثنين_ثلاثاء_أربعاء_خميس_جمعة_سبت'.split('_'),\n    weekdaysMin: 'ح_ن_ث_ر_خ_ج_س'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat: {\n        LT: 'HH:mm',\n        LTS: 'HH:mm:ss',\n        L: 'DD/MM/YYYY',\n        LL: 'D MMMM YYYY',\n        LLL: 'D MMMM YYYY HH:mm',\n        LLLL: 'dddd D MMMM YYYY HH:mm'\n    },\n    calendar: {\n        sameDay: '[اليوم على الساعة] LT',\n        nextDay: '[غدا على الساعة] LT',\n        nextWeek: 'dddd [على الساعة] LT',\n        lastDay: '[أمس على الساعة] LT',\n        lastWeek: 'dddd [على الساعة] LT',\n        sameElse: 'L'\n    },\n    relativeTime: {\n        future: 'في %s',\n        past: 'منذ %s',\n        s: 'ثوان',\n        m: 'دقيقة',\n        mm: '%d دقائق',\n        h: 'ساعة',\n        hh: '%d ساعات',\n        d: 'يوم',\n        dd: '%d أيام',\n        M: 'شهر',\n        MM: '%d أشهر',\n        y: 'سنة',\n        yy: '%d سنوات'\n    },\n    week: {\n        dow: 1, // Monday is the first day of the week.\n        doy: 4 // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Arabic [ar]\n//! author : Abdel Said: https://github.com/abdelsaid\n//! author : Ahmed Elkhatib\n//! author : forabi https://github.com/forabi\n\nvar symbolMap$2 = {\n    '1': '١',\n    '2': '٢',\n    '3': '٣',\n    '4': '٤',\n    '5': '٥',\n    '6': '٦',\n    '7': '٧',\n    '8': '٨',\n    '9': '٩',\n    '0': '٠'\n};\nvar numberMap$1 = {\n    '١': '1',\n    '٢': '2',\n    '٣': '3',\n    '٤': '4',\n    '٥': '5',\n    '٦': '6',\n    '٧': '7',\n    '٨': '8',\n    '٩': '9',\n    '٠': '0'\n};\nvar pluralForm$1 = function (n) {\n    return n === 0 ? 0 : n === 1 ? 1 : n === 2 ? 2 : n % 100 >= 3 && n % 100 <= 10 ? 3 : n % 100 >= 11 ? 4 : 5;\n};\nvar plurals$1 = {\n    s : ['أقل من ثانية', 'ثانية واحدة', ['ثانيتان', 'ثانيتين'], '%d ثوان', '%d ثانية', '%d ثانية'],\n    m : ['أقل من دقيقة', 'دقيقة واحدة', ['دقيقتان', 'دقيقتين'], '%d دقائق', '%d دقيقة', '%d دقيقة'],\n    h : ['أقل من ساعة', 'ساعة واحدة', ['ساعتان', 'ساعتين'], '%d ساعات', '%d ساعة', '%d ساعة'],\n    d : ['أقل من يوم', 'يوم واحد', ['يومان', 'يومين'], '%d أيام', '%d يومًا', '%d يوم'],\n    M : ['أقل من شهر', 'شهر واحد', ['شهران', 'شهرين'], '%d أشهر', '%d شهرا', '%d شهر'],\n    y : ['أقل من عام', 'عام واحد', ['عامان', 'عامين'], '%d أعوام', '%d عامًا', '%d عام']\n};\nvar pluralize$1 = function (u) {\n    return function (number, withoutSuffix, string, isFuture) {\n        var f = pluralForm$1(number),\n            str = plurals$1[u][pluralForm$1(number)];\n        if (f === 2) {\n            str = str[withoutSuffix ? 0 : 1];\n        }\n        return str.replace(/%d/i, number);\n    };\n};\nvar months$2 = [\n    'كانون الثاني يناير',\n    'شباط فبراير',\n    'آذار مارس',\n    'نيسان أبريل',\n    'أيار مايو',\n    'حزيران يونيو',\n    'تموز يوليو',\n    'آب أغسطس',\n    'أيلول سبتمبر',\n    'تشرين الأول أكتوبر',\n    'تشرين الثاني نوفمبر',\n    'كانون الأول ديسمبر'\n];\n\nhooks.defineLocale('ar', {\n    months : months$2,\n    monthsShort : months$2,\n    weekdays : 'الأحد_الإثنين_الثلاثاء_الأربعاء_الخميس_الجمعة_السبت'.split('_'),\n    weekdaysShort : 'أحد_إثنين_ثلاثاء_أربعاء_خميس_جمعة_سبت'.split('_'),\n    weekdaysMin : 'ح_ن_ث_ر_خ_ج_س'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'D/\\u200FM/\\u200FYYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY HH:mm',\n        LLLL : 'dddd D MMMM YYYY HH:mm'\n    },\n    meridiemParse: /ص|م/,\n    isPM : function (input) {\n        return 'م' === input;\n    },\n    meridiem : function (hour, minute, isLower) {\n        if (hour < 12) {\n            return 'ص';\n        } else {\n            return 'م';\n        }\n    },\n    calendar : {\n        sameDay: '[اليوم عند الساعة] LT',\n        nextDay: '[غدًا عند الساعة] LT',\n        nextWeek: 'dddd [عند الساعة] LT',\n        lastDay: '[أمس عند الساعة] LT',\n        lastWeek: 'dddd [عند الساعة] LT',\n        sameElse: 'L'\n    },\n    relativeTime : {\n        future : 'بعد %s',\n        past : 'منذ %s',\n        s : pluralize$1('s'),\n        m : pluralize$1('m'),\n        mm : pluralize$1('m'),\n        h : pluralize$1('h'),\n        hh : pluralize$1('h'),\n        d : pluralize$1('d'),\n        dd : pluralize$1('d'),\n        M : pluralize$1('M'),\n        MM : pluralize$1('M'),\n        y : pluralize$1('y'),\n        yy : pluralize$1('y')\n    },\n    preparse: function (string) {\n        return string.replace(/\\u200f/g, '').replace(/[١٢٣٤٥٦٧٨٩٠]/g, function (match) {\n            return numberMap$1[match];\n        }).replace(/،/g, ',');\n    },\n    postformat: function (string) {\n        return string.replace(/\\d/g, function (match) {\n            return symbolMap$2[match];\n        }).replace(/,/g, '،');\n    },\n    week : {\n        dow : 6, // Saturday is the first day of the week.\n        doy : 12  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Azerbaijani [az]\n//! author : topchiyev : https://github.com/topchiyev\n\nvar suffixes = {\n    1: '-inci',\n    5: '-inci',\n    8: '-inci',\n    70: '-inci',\n    80: '-inci',\n    2: '-nci',\n    7: '-nci',\n    20: '-nci',\n    50: '-nci',\n    3: '-üncü',\n    4: '-üncü',\n    100: '-üncü',\n    6: '-ncı',\n    9: '-uncu',\n    10: '-uncu',\n    30: '-uncu',\n    60: '-ıncı',\n    90: '-ıncı'\n};\n\nhooks.defineLocale('az', {\n    months : 'yanvar_fevral_mart_aprel_may_iyun_iyul_avqust_sentyabr_oktyabr_noyabr_dekabr'.split('_'),\n    monthsShort : 'yan_fev_mar_apr_may_iyn_iyl_avq_sen_okt_noy_dek'.split('_'),\n    weekdays : 'Bazar_Bazar ertəsi_Çərşənbə axşamı_Çərşənbə_Cümə axşamı_Cümə_Şənbə'.split('_'),\n    weekdaysShort : 'Baz_BzE_ÇAx_Çər_CAx_Cüm_Şən'.split('_'),\n    weekdaysMin : 'Bz_BE_ÇA_Çə_CA_Cü_Şə'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD.MM.YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY HH:mm',\n        LLLL : 'dddd, D MMMM YYYY HH:mm'\n    },\n    calendar : {\n        sameDay : '[bugün saat] LT',\n        nextDay : '[sabah saat] LT',\n        nextWeek : '[gələn həftə] dddd [saat] LT',\n        lastDay : '[dünən] LT',\n        lastWeek : '[keçən həftə] dddd [saat] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : '%s sonra',\n        past : '%s əvvəl',\n        s : 'birneçə saniyyə',\n        m : 'bir dəqiqə',\n        mm : '%d dəqiqə',\n        h : 'bir saat',\n        hh : '%d saat',\n        d : 'bir gün',\n        dd : '%d gün',\n        M : 'bir ay',\n        MM : '%d ay',\n        y : 'bir il',\n        yy : '%d il'\n    },\n    meridiemParse: /gecə|səhər|gündüz|axşam/,\n    isPM : function (input) {\n        return /^(gündüz|axşam)$/.test(input);\n    },\n    meridiem : function (hour, minute, isLower) {\n        if (hour < 4) {\n            return 'gecə';\n        } else if (hour < 12) {\n            return 'səhər';\n        } else if (hour < 17) {\n            return 'gündüz';\n        } else {\n            return 'axşam';\n        }\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}-(ıncı|inci|nci|üncü|ncı|uncu)/,\n    ordinal : function (number) {\n        if (number === 0) {  // special case for zero\n            return number + '-ıncı';\n        }\n        var a = number % 10,\n            b = number % 100 - a,\n            c = number >= 100 ? 100 : null;\n        return number + (suffixes[a] || suffixes[b] || suffixes[c]);\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 7  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Belarusian [be]\n//! author : Dmitry Demidov : https://github.com/demidov91\n//! author: Praleska: http://praleska.pro/\n//! Author : Menelion Elensúle : https://github.com/Oire\n\nfunction plural(word, num) {\n    var forms = word.split('_');\n    return num % 10 === 1 && num % 100 !== 11 ? forms[0] : (num % 10 >= 2 && num % 10 <= 4 && (num % 100 < 10 || num % 100 >= 20) ? forms[1] : forms[2]);\n}\nfunction relativeTimeWithPlural(number, withoutSuffix, key) {\n    var format = {\n        'mm': withoutSuffix ? 'хвіліна_хвіліны_хвілін' : 'хвіліну_хвіліны_хвілін',\n        'hh': withoutSuffix ? 'гадзіна_гадзіны_гадзін' : 'гадзіну_гадзіны_гадзін',\n        'dd': 'дзень_дні_дзён',\n        'MM': 'месяц_месяцы_месяцаў',\n        'yy': 'год_гады_гадоў'\n    };\n    if (key === 'm') {\n        return withoutSuffix ? 'хвіліна' : 'хвіліну';\n    }\n    else if (key === 'h') {\n        return withoutSuffix ? 'гадзіна' : 'гадзіну';\n    }\n    else {\n        return number + ' ' + plural(format[key], +number);\n    }\n}\n\nhooks.defineLocale('be', {\n    months : {\n        format: 'студзеня_лютага_сакавіка_красавіка_траўня_чэрвеня_ліпеня_жніўня_верасня_кастрычніка_лістапада_снежня'.split('_'),\n        standalone: 'студзень_люты_сакавік_красавік_травень_чэрвень_ліпень_жнівень_верасень_кастрычнік_лістапад_снежань'.split('_')\n    },\n    monthsShort : 'студ_лют_сак_крас_трав_чэрв_ліп_жнів_вер_каст_ліст_снеж'.split('_'),\n    weekdays : {\n        format: 'нядзелю_панядзелак_аўторак_сераду_чацвер_пятніцу_суботу'.split('_'),\n        standalone: 'нядзеля_панядзелак_аўторак_серада_чацвер_пятніца_субота'.split('_'),\n        isFormat: /\\[ ?[Вв] ?(?:мінулую|наступную)? ?\\] ?dddd/\n    },\n    weekdaysShort : 'нд_пн_ат_ср_чц_пт_сб'.split('_'),\n    weekdaysMin : 'нд_пн_ат_ср_чц_пт_сб'.split('_'),\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD.MM.YYYY',\n        LL : 'D MMMM YYYY г.',\n        LLL : 'D MMMM YYYY г., HH:mm',\n        LLLL : 'dddd, D MMMM YYYY г., HH:mm'\n    },\n    calendar : {\n        sameDay: '[Сёння ў] LT',\n        nextDay: '[Заўтра ў] LT',\n        lastDay: '[Учора ў] LT',\n        nextWeek: function () {\n            return '[У] dddd [ў] LT';\n        },\n        lastWeek: function () {\n            switch (this.day()) {\n                case 0:\n                case 3:\n                case 5:\n                case 6:\n                    return '[У мінулую] dddd [ў] LT';\n                case 1:\n                case 2:\n                case 4:\n                    return '[У мінулы] dddd [ў] LT';\n            }\n        },\n        sameElse: 'L'\n    },\n    relativeTime : {\n        future : 'праз %s',\n        past : '%s таму',\n        s : 'некалькі секунд',\n        m : relativeTimeWithPlural,\n        mm : relativeTimeWithPlural,\n        h : relativeTimeWithPlural,\n        hh : relativeTimeWithPlural,\n        d : 'дзень',\n        dd : relativeTimeWithPlural,\n        M : 'месяц',\n        MM : relativeTimeWithPlural,\n        y : 'год',\n        yy : relativeTimeWithPlural\n    },\n    meridiemParse: /ночы|раніцы|дня|вечара/,\n    isPM : function (input) {\n        return /^(дня|вечара)$/.test(input);\n    },\n    meridiem : function (hour, minute, isLower) {\n        if (hour < 4) {\n            return 'ночы';\n        } else if (hour < 12) {\n            return 'раніцы';\n        } else if (hour < 17) {\n            return 'дня';\n        } else {\n            return 'вечара';\n        }\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}-(і|ы|га)/,\n    ordinal: function (number, period) {\n        switch (period) {\n            case 'M':\n            case 'd':\n            case 'DDD':\n            case 'w':\n            case 'W':\n                return (number % 10 === 2 || number % 10 === 3) && (number % 100 !== 12 && number % 100 !== 13) ? number + '-і' : number + '-ы';\n            case 'D':\n                return number + '-га';\n            default:\n                return number;\n        }\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 7  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Bulgarian [bg]\n//! author : Krasen Borisov : https://github.com/kraz\n\nhooks.defineLocale('bg', {\n    months : 'януари_февруари_март_април_май_юни_юли_август_септември_октомври_ноември_декември'.split('_'),\n    monthsShort : 'янр_фев_мар_апр_май_юни_юли_авг_сеп_окт_ное_дек'.split('_'),\n    weekdays : 'неделя_понеделник_вторник_сряда_четвъртък_петък_събота'.split('_'),\n    weekdaysShort : 'нед_пон_вто_сря_чет_пет_съб'.split('_'),\n    weekdaysMin : 'нд_пн_вт_ср_чт_пт_сб'.split('_'),\n    longDateFormat : {\n        LT : 'H:mm',\n        LTS : 'H:mm:ss',\n        L : 'D.MM.YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY H:mm',\n        LLLL : 'dddd, D MMMM YYYY H:mm'\n    },\n    calendar : {\n        sameDay : '[Днес в] LT',\n        nextDay : '[Утре в] LT',\n        nextWeek : 'dddd [в] LT',\n        lastDay : '[Вчера в] LT',\n        lastWeek : function () {\n            switch (this.day()) {\n                case 0:\n                case 3:\n                case 6:\n                    return '[В изминалата] dddd [в] LT';\n                case 1:\n                case 2:\n                case 4:\n                case 5:\n                    return '[В изминалия] dddd [в] LT';\n            }\n        },\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'след %s',\n        past : 'преди %s',\n        s : 'няколко секунди',\n        m : 'минута',\n        mm : '%d минути',\n        h : 'час',\n        hh : '%d часа',\n        d : 'ден',\n        dd : '%d дни',\n        M : 'месец',\n        MM : '%d месеца',\n        y : 'година',\n        yy : '%d години'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}-(ев|ен|ти|ви|ри|ми)/,\n    ordinal : function (number) {\n        var lastDigit = number % 10,\n            last2Digits = number % 100;\n        if (number === 0) {\n            return number + '-ев';\n        } else if (last2Digits === 0) {\n            return number + '-ен';\n        } else if (last2Digits > 10 && last2Digits < 20) {\n            return number + '-ти';\n        } else if (lastDigit === 1) {\n            return number + '-ви';\n        } else if (lastDigit === 2) {\n            return number + '-ри';\n        } else if (lastDigit === 7 || lastDigit === 8) {\n            return number + '-ми';\n        } else {\n            return number + '-ти';\n        }\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 7  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Bengali [bn]\n//! author : Kaushik Gandhi : https://github.com/kaushikgandhi\n\nvar symbolMap$3 = {\n    '1': '১',\n    '2': '২',\n    '3': '৩',\n    '4': '৪',\n    '5': '৫',\n    '6': '৬',\n    '7': '৭',\n    '8': '৮',\n    '9': '৯',\n    '0': '০'\n};\nvar numberMap$2 = {\n    '১': '1',\n    '২': '2',\n    '৩': '3',\n    '৪': '4',\n    '৫': '5',\n    '৬': '6',\n    '৭': '7',\n    '৮': '8',\n    '৯': '9',\n    '০': '0'\n};\n\nhooks.defineLocale('bn', {\n    months : 'জানুয়ারী_ফেব্রুয়ারি_মার্চ_এপ্রিল_মে_জুন_জুলাই_আগস্ট_সেপ্টেম্বর_অক্টোবর_নভেম্বর_ডিসেম্বর'.split('_'),\n    monthsShort : 'জানু_ফেব_মার্চ_এপ্র_মে_জুন_জুল_আগ_সেপ্ট_অক্টো_নভে_ডিসে'.split('_'),\n    weekdays : 'রবিবার_সোমবার_মঙ্গলবার_বুধবার_বৃহস্পতিবার_শুক্রবার_শনিবার'.split('_'),\n    weekdaysShort : 'রবি_সোম_মঙ্গল_বুধ_বৃহস্পতি_শুক্র_শনি'.split('_'),\n    weekdaysMin : 'রবি_সোম_মঙ্গ_বুধ_বৃহঃ_শুক্র_শনি'.split('_'),\n    longDateFormat : {\n        LT : 'A h:mm সময়',\n        LTS : 'A h:mm:ss সময়',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY, A h:mm সময়',\n        LLLL : 'dddd, D MMMM YYYY, A h:mm সময়'\n    },\n    calendar : {\n        sameDay : '[আজ] LT',\n        nextDay : '[আগামীকাল] LT',\n        nextWeek : 'dddd, LT',\n        lastDay : '[গতকাল] LT',\n        lastWeek : '[গত] dddd, LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : '%s পরে',\n        past : '%s আগে',\n        s : 'কয়েক সেকেন্ড',\n        m : 'এক মিনিট',\n        mm : '%d মিনিট',\n        h : 'এক ঘন্টা',\n        hh : '%d ঘন্টা',\n        d : 'এক দিন',\n        dd : '%d দিন',\n        M : 'এক মাস',\n        MM : '%d মাস',\n        y : 'এক বছর',\n        yy : '%d বছর'\n    },\n    preparse: function (string) {\n        return string.replace(/[১২৩৪৫৬৭৮৯০]/g, function (match) {\n            return numberMap$2[match];\n        });\n    },\n    postformat: function (string) {\n        return string.replace(/\\d/g, function (match) {\n            return symbolMap$3[match];\n        });\n    },\n    meridiemParse: /রাত|সকাল|দুপুর|বিকাল|রাত/,\n    meridiemHour : function (hour, meridiem) {\n        if (hour === 12) {\n            hour = 0;\n        }\n        if ((meridiem === 'রাত' && hour >= 4) ||\n                (meridiem === 'দুপুর' && hour < 5) ||\n                meridiem === 'বিকাল') {\n            return hour + 12;\n        } else {\n            return hour;\n        }\n    },\n    meridiem : function (hour, minute, isLower) {\n        if (hour < 4) {\n            return 'রাত';\n        } else if (hour < 10) {\n            return 'সকাল';\n        } else if (hour < 17) {\n            return 'দুপুর';\n        } else if (hour < 20) {\n            return 'বিকাল';\n        } else {\n            return 'রাত';\n        }\n    },\n    week : {\n        dow : 0, // Sunday is the first day of the week.\n        doy : 6  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Tibetan [bo]\n//! author : Thupten N. Chakrishar : https://github.com/vajradog\n\nvar symbolMap$4 = {\n    '1': '༡',\n    '2': '༢',\n    '3': '༣',\n    '4': '༤',\n    '5': '༥',\n    '6': '༦',\n    '7': '༧',\n    '8': '༨',\n    '9': '༩',\n    '0': '༠'\n};\nvar numberMap$3 = {\n    '༡': '1',\n    '༢': '2',\n    '༣': '3',\n    '༤': '4',\n    '༥': '5',\n    '༦': '6',\n    '༧': '7',\n    '༨': '8',\n    '༩': '9',\n    '༠': '0'\n};\n\nhooks.defineLocale('bo', {\n    months : 'ཟླ་བ་དང་པོ_ཟླ་བ་གཉིས་པ_ཟླ་བ་གསུམ་པ_ཟླ་བ་བཞི་པ_ཟླ་བ་ལྔ་པ_ཟླ་བ་དྲུག་པ_ཟླ་བ་བདུན་པ_ཟླ་བ་བརྒྱད་པ_ཟླ་བ་དགུ་པ_ཟླ་བ་བཅུ་པ_ཟླ་བ་བཅུ་གཅིག་པ_ཟླ་བ་བཅུ་གཉིས་པ'.split('_'),\n    monthsShort : 'ཟླ་བ་དང་པོ_ཟླ་བ་གཉིས་པ_ཟླ་བ་གསུམ་པ_ཟླ་བ་བཞི་པ_ཟླ་བ་ལྔ་པ_ཟླ་བ་དྲུག་པ_ཟླ་བ་བདུན་པ_ཟླ་བ་བརྒྱད་པ_ཟླ་བ་དགུ་པ_ཟླ་བ་བཅུ་པ_ཟླ་བ་བཅུ་གཅིག་པ_ཟླ་བ་བཅུ་གཉིས་པ'.split('_'),\n    weekdays : 'གཟའ་ཉི་མ་_གཟའ་ཟླ་བ་_གཟའ་མིག་དམར་_གཟའ་ལྷག་པ་_གཟའ་ཕུར་བུ_གཟའ་པ་སངས་_གཟའ་སྤེན་པ་'.split('_'),\n    weekdaysShort : 'ཉི་མ་_ཟླ་བ་_མིག་དམར་_ལྷག་པ་_ཕུར་བུ_པ་སངས་_སྤེན་པ་'.split('_'),\n    weekdaysMin : 'ཉི་མ་_ཟླ་བ་_མིག་དམར་_ལྷག་པ་_ཕུར་བུ_པ་སངས་_སྤེན་པ་'.split('_'),\n    longDateFormat : {\n        LT : 'A h:mm',\n        LTS : 'A h:mm:ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY, A h:mm',\n        LLLL : 'dddd, D MMMM YYYY, A h:mm'\n    },\n    calendar : {\n        sameDay : '[དི་རིང] LT',\n        nextDay : '[སང་ཉིན] LT',\n        nextWeek : '[བདུན་ཕྲག་རྗེས་མ], LT',\n        lastDay : '[ཁ་སང] LT',\n        lastWeek : '[བདུན་ཕྲག་མཐའ་མ] dddd, LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : '%s ལ་',\n        past : '%s སྔན་ལ',\n        s : 'ལམ་སང',\n        m : 'སྐར་མ་གཅིག',\n        mm : '%d སྐར་མ',\n        h : 'ཆུ་ཚོད་གཅིག',\n        hh : '%d ཆུ་ཚོད',\n        d : 'ཉིན་གཅིག',\n        dd : '%d ཉིན་',\n        M : 'ཟླ་བ་གཅིག',\n        MM : '%d ཟླ་བ',\n        y : 'ལོ་གཅིག',\n        yy : '%d ལོ'\n    },\n    preparse: function (string) {\n        return string.replace(/[༡༢༣༤༥༦༧༨༩༠]/g, function (match) {\n            return numberMap$3[match];\n        });\n    },\n    postformat: function (string) {\n        return string.replace(/\\d/g, function (match) {\n            return symbolMap$4[match];\n        });\n    },\n    meridiemParse: /མཚན་མོ|ཞོགས་ཀས|ཉིན་གུང|དགོང་དག|མཚན་མོ/,\n    meridiemHour : function (hour, meridiem) {\n        if (hour === 12) {\n            hour = 0;\n        }\n        if ((meridiem === 'མཚན་མོ' && hour >= 4) ||\n                (meridiem === 'ཉིན་གུང' && hour < 5) ||\n                meridiem === 'དགོང་དག') {\n            return hour + 12;\n        } else {\n            return hour;\n        }\n    },\n    meridiem : function (hour, minute, isLower) {\n        if (hour < 4) {\n            return 'མཚན་མོ';\n        } else if (hour < 10) {\n            return 'ཞོགས་ཀས';\n        } else if (hour < 17) {\n            return 'ཉིན་གུང';\n        } else if (hour < 20) {\n            return 'དགོང་དག';\n        } else {\n            return 'མཚན་མོ';\n        }\n    },\n    week : {\n        dow : 0, // Sunday is the first day of the week.\n        doy : 6  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Breton [br]\n//! author : Jean-Baptiste Le Duigou : https://github.com/jbleduigou\n\nfunction relativeTimeWithMutation(number, withoutSuffix, key) {\n    var format = {\n        'mm': 'munutenn',\n        'MM': 'miz',\n        'dd': 'devezh'\n    };\n    return number + ' ' + mutation(format[key], number);\n}\nfunction specialMutationForYears(number) {\n    switch (lastNumber(number)) {\n        case 1:\n        case 3:\n        case 4:\n        case 5:\n        case 9:\n            return number + ' bloaz';\n        default:\n            return number + ' vloaz';\n    }\n}\nfunction lastNumber(number) {\n    if (number > 9) {\n        return lastNumber(number % 10);\n    }\n    return number;\n}\nfunction mutation(text, number) {\n    if (number === 2) {\n        return softMutation(text);\n    }\n    return text;\n}\nfunction softMutation(text) {\n    var mutationTable = {\n        'm': 'v',\n        'b': 'v',\n        'd': 'z'\n    };\n    if (mutationTable[text.charAt(0)] === undefined) {\n        return text;\n    }\n    return mutationTable[text.charAt(0)] + text.substring(1);\n}\n\nhooks.defineLocale('br', {\n    months : 'Genver_C\\'hwevrer_Meurzh_Ebrel_Mae_Mezheven_Gouere_Eost_Gwengolo_Here_Du_Kerzu'.split('_'),\n    monthsShort : 'Gen_C\\'hwe_Meu_Ebr_Mae_Eve_Gou_Eos_Gwe_Her_Du_Ker'.split('_'),\n    weekdays : 'Sul_Lun_Meurzh_Merc\\'her_Yaou_Gwener_Sadorn'.split('_'),\n    weekdaysShort : 'Sul_Lun_Meu_Mer_Yao_Gwe_Sad'.split('_'),\n    weekdaysMin : 'Su_Lu_Me_Mer_Ya_Gw_Sa'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat : {\n        LT : 'h[e]mm A',\n        LTS : 'h[e]mm:ss A',\n        L : 'DD/MM/YYYY',\n        LL : 'D [a viz] MMMM YYYY',\n        LLL : 'D [a viz] MMMM YYYY h[e]mm A',\n        LLLL : 'dddd, D [a viz] MMMM YYYY h[e]mm A'\n    },\n    calendar : {\n        sameDay : '[Hiziv da] LT',\n        nextDay : '[Warc\\'hoazh da] LT',\n        nextWeek : 'dddd [da] LT',\n        lastDay : '[Dec\\'h da] LT',\n        lastWeek : 'dddd [paset da] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'a-benn %s',\n        past : '%s \\'zo',\n        s : 'un nebeud segondennoù',\n        m : 'ur vunutenn',\n        mm : relativeTimeWithMutation,\n        h : 'un eur',\n        hh : '%d eur',\n        d : 'un devezh',\n        dd : relativeTimeWithMutation,\n        M : 'ur miz',\n        MM : relativeTimeWithMutation,\n        y : 'ur bloaz',\n        yy : specialMutationForYears\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}(añ|vet)/,\n    ordinal : function (number) {\n        var output = (number === 1) ? 'añ' : 'vet';\n        return number + output;\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Bosnian [bs]\n//! author : Nedim Cholich : https://github.com/frontyard\n//! based on (hr) translation by Bojan Marković\n\nfunction translate(number, withoutSuffix, key) {\n    var result = number + ' ';\n    switch (key) {\n        case 'm':\n            return withoutSuffix ? 'jedna minuta' : 'jedne minute';\n        case 'mm':\n            if (number === 1) {\n                result += 'minuta';\n            } else if (number === 2 || number === 3 || number === 4) {\n                result += 'minute';\n            } else {\n                result += 'minuta';\n            }\n            return result;\n        case 'h':\n            return withoutSuffix ? 'jedan sat' : 'jednog sata';\n        case 'hh':\n            if (number === 1) {\n                result += 'sat';\n            } else if (number === 2 || number === 3 || number === 4) {\n                result += 'sata';\n            } else {\n                result += 'sati';\n            }\n            return result;\n        case 'dd':\n            if (number === 1) {\n                result += 'dan';\n            } else {\n                result += 'dana';\n            }\n            return result;\n        case 'MM':\n            if (number === 1) {\n                result += 'mjesec';\n            } else if (number === 2 || number === 3 || number === 4) {\n                result += 'mjeseca';\n            } else {\n                result += 'mjeseci';\n            }\n            return result;\n        case 'yy':\n            if (number === 1) {\n                result += 'godina';\n            } else if (number === 2 || number === 3 || number === 4) {\n                result += 'godine';\n            } else {\n                result += 'godina';\n            }\n            return result;\n    }\n}\n\nhooks.defineLocale('bs', {\n    months : 'januar_februar_mart_april_maj_juni_juli_august_septembar_oktobar_novembar_decembar'.split('_'),\n    monthsShort : 'jan._feb._mar._apr._maj._jun._jul._aug._sep._okt._nov._dec.'.split('_'),\n    monthsParseExact: true,\n    weekdays : 'nedjelja_ponedjeljak_utorak_srijeda_četvrtak_petak_subota'.split('_'),\n    weekdaysShort : 'ned._pon._uto._sri._čet._pet._sub.'.split('_'),\n    weekdaysMin : 'ne_po_ut_sr_če_pe_su'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat : {\n        LT : 'H:mm',\n        LTS : 'H:mm:ss',\n        L : 'DD.MM.YYYY',\n        LL : 'D. MMMM YYYY',\n        LLL : 'D. MMMM YYYY H:mm',\n        LLLL : 'dddd, D. MMMM YYYY H:mm'\n    },\n    calendar : {\n        sameDay  : '[danas u] LT',\n        nextDay  : '[sutra u] LT',\n        nextWeek : function () {\n            switch (this.day()) {\n                case 0:\n                    return '[u] [nedjelju] [u] LT';\n                case 3:\n                    return '[u] [srijedu] [u] LT';\n                case 6:\n                    return '[u] [subotu] [u] LT';\n                case 1:\n                case 2:\n                case 4:\n                case 5:\n                    return '[u] dddd [u] LT';\n            }\n        },\n        lastDay  : '[jučer u] LT',\n        lastWeek : function () {\n            switch (this.day()) {\n                case 0:\n                case 3:\n                    return '[prošlu] dddd [u] LT';\n                case 6:\n                    return '[prošle] [subote] [u] LT';\n                case 1:\n                case 2:\n                case 4:\n                case 5:\n                    return '[prošli] dddd [u] LT';\n            }\n        },\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'za %s',\n        past   : 'prije %s',\n        s      : 'par sekundi',\n        m      : translate,\n        mm     : translate,\n        h      : translate,\n        hh     : translate,\n        d      : 'dan',\n        dd     : translate,\n        M      : 'mjesec',\n        MM     : translate,\n        y      : 'godinu',\n        yy     : translate\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}\\./,\n    ordinal : '%d.',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 7  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Catalan [ca]\n//! author : Juan G. Hurtado : https://github.com/juanghurtado\n\nhooks.defineLocale('ca', {\n    months : {\n        standalone: 'gener_febrer_març_abril_maig_juny_juliol_agost_setembre_octubre_novembre_desembre'.split('_'),\n        format: 'de gener_de febrer_de març_d\\'abril_de maig_de juny_de juliol_d\\'agost_de setembre_d\\'octubre_de novembre_de desembre'.split('_'),\n        isFormat: /D[oD]?(\\s)+MMMM/\n    },\n    monthsShort : 'gen._febr._març_abr._maig_juny_jul._ag._set._oct._nov._des.'.split('_'),\n    monthsParseExact : true,\n    weekdays : 'diumenge_dilluns_dimarts_dimecres_dijous_divendres_dissabte'.split('_'),\n    weekdaysShort : 'dg._dl._dt._dc._dj._dv._ds.'.split('_'),\n    weekdaysMin : 'Dg_Dl_Dt_Dc_Dj_Dv_Ds'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat : {\n        LT : 'H:mm',\n        LTS : 'H:mm:ss',\n        L : 'DD/MM/YYYY',\n        LL : '[el] D MMMM [de] YYYY',\n        ll : 'D MMM YYYY',\n        LLL : '[el] D MMMM [de] YYYY [a les] H:mm',\n        lll : 'D MMM YYYY, H:mm',\n        LLLL : '[el] dddd D MMMM [de] YYYY [a les] H:mm',\n        llll : 'ddd D MMM YYYY, H:mm'\n    },\n    calendar : {\n        sameDay : function () {\n            return '[avui a ' + ((this.hours() !== 1) ? 'les' : 'la') + '] LT';\n        },\n        nextDay : function () {\n            return '[demà a ' + ((this.hours() !== 1) ? 'les' : 'la') + '] LT';\n        },\n        nextWeek : function () {\n            return 'dddd [a ' + ((this.hours() !== 1) ? 'les' : 'la') + '] LT';\n        },\n        lastDay : function () {\n            return '[ahir a ' + ((this.hours() !== 1) ? 'les' : 'la') + '] LT';\n        },\n        lastWeek : function () {\n            return '[el] dddd [passat a ' + ((this.hours() !== 1) ? 'les' : 'la') + '] LT';\n        },\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'd\\'aquí %s',\n        past : 'fa %s',\n        s : 'uns segons',\n        m : 'un minut',\n        mm : '%d minuts',\n        h : 'una hora',\n        hh : '%d hores',\n        d : 'un dia',\n        dd : '%d dies',\n        M : 'un mes',\n        MM : '%d mesos',\n        y : 'un any',\n        yy : '%d anys'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}(r|n|t|è|a)/,\n    ordinal : function (number, period) {\n        var output = (number === 1) ? 'r' :\n            (number === 2) ? 'n' :\n            (number === 3) ? 'r' :\n            (number === 4) ? 't' : 'è';\n        if (period === 'w' || period === 'W') {\n            output = 'a';\n        }\n        return number + output;\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Czech [cs]\n//! author : petrbela : https://github.com/petrbela\n\nvar months$3 = 'leden_únor_březen_duben_květen_červen_červenec_srpen_září_říjen_listopad_prosinec'.split('_');\nvar monthsShort = 'led_úno_bře_dub_kvě_čvn_čvc_srp_zář_říj_lis_pro'.split('_');\nfunction plural$1(n) {\n    return (n > 1) && (n < 5) && (~~(n / 10) !== 1);\n}\nfunction translate$1(number, withoutSuffix, key, isFuture) {\n    var result = number + ' ';\n    switch (key) {\n        case 's':  // a few seconds / in a few seconds / a few seconds ago\n            return (withoutSuffix || isFuture) ? 'pár sekund' : 'pár sekundami';\n        case 'm':  // a minute / in a minute / a minute ago\n            return withoutSuffix ? 'minuta' : (isFuture ? 'minutu' : 'minutou');\n        case 'mm': // 9 minutes / in 9 minutes / 9 minutes ago\n            if (withoutSuffix || isFuture) {\n                return result + (plural$1(number) ? 'minuty' : 'minut');\n            } else {\n                return result + 'minutami';\n            }\n            break;\n        case 'h':  // an hour / in an hour / an hour ago\n            return withoutSuffix ? 'hodina' : (isFuture ? 'hodinu' : 'hodinou');\n        case 'hh': // 9 hours / in 9 hours / 9 hours ago\n            if (withoutSuffix || isFuture) {\n                return result + (plural$1(number) ? 'hodiny' : 'hodin');\n            } else {\n                return result + 'hodinami';\n            }\n            break;\n        case 'd':  // a day / in a day / a day ago\n            return (withoutSuffix || isFuture) ? 'den' : 'dnem';\n        case 'dd': // 9 days / in 9 days / 9 days ago\n            if (withoutSuffix || isFuture) {\n                return result + (plural$1(number) ? 'dny' : 'dní');\n            } else {\n                return result + 'dny';\n            }\n            break;\n        case 'M':  // a month / in a month / a month ago\n            return (withoutSuffix || isFuture) ? 'měsíc' : 'měsícem';\n        case 'MM': // 9 months / in 9 months / 9 months ago\n            if (withoutSuffix || isFuture) {\n                return result + (plural$1(number) ? 'měsíce' : 'měsíců');\n            } else {\n                return result + 'měsíci';\n            }\n            break;\n        case 'y':  // a year / in a year / a year ago\n            return (withoutSuffix || isFuture) ? 'rok' : 'rokem';\n        case 'yy': // 9 years / in 9 years / 9 years ago\n            if (withoutSuffix || isFuture) {\n                return result + (plural$1(number) ? 'roky' : 'let');\n            } else {\n                return result + 'lety';\n            }\n            break;\n    }\n}\n\nhooks.defineLocale('cs', {\n    months : months$3,\n    monthsShort : monthsShort,\n    monthsParse : (function (months, monthsShort) {\n        var i, _monthsParse = [];\n        for (i = 0; i < 12; i++) {\n            // use custom parser to solve problem with July (červenec)\n            _monthsParse[i] = new RegExp('^' + months[i] + '$|^' + monthsShort[i] + '$', 'i');\n        }\n        return _monthsParse;\n    }(months$3, monthsShort)),\n    shortMonthsParse : (function (monthsShort) {\n        var i, _shortMonthsParse = [];\n        for (i = 0; i < 12; i++) {\n            _shortMonthsParse[i] = new RegExp('^' + monthsShort[i] + '$', 'i');\n        }\n        return _shortMonthsParse;\n    }(monthsShort)),\n    longMonthsParse : (function (months) {\n        var i, _longMonthsParse = [];\n        for (i = 0; i < 12; i++) {\n            _longMonthsParse[i] = new RegExp('^' + months[i] + '$', 'i');\n        }\n        return _longMonthsParse;\n    }(months$3)),\n    weekdays : 'neděle_pondělí_úterý_středa_čtvrtek_pátek_sobota'.split('_'),\n    weekdaysShort : 'ne_po_út_st_čt_pá_so'.split('_'),\n    weekdaysMin : 'ne_po_út_st_čt_pá_so'.split('_'),\n    longDateFormat : {\n        LT: 'H:mm',\n        LTS : 'H:mm:ss',\n        L : 'DD.MM.YYYY',\n        LL : 'D. MMMM YYYY',\n        LLL : 'D. MMMM YYYY H:mm',\n        LLLL : 'dddd D. MMMM YYYY H:mm',\n        l : 'D. M. YYYY'\n    },\n    calendar : {\n        sameDay: '[dnes v] LT',\n        nextDay: '[zítra v] LT',\n        nextWeek: function () {\n            switch (this.day()) {\n                case 0:\n                    return '[v neděli v] LT';\n                case 1:\n                case 2:\n                    return '[v] dddd [v] LT';\n                case 3:\n                    return '[ve středu v] LT';\n                case 4:\n                    return '[ve čtvrtek v] LT';\n                case 5:\n                    return '[v pátek v] LT';\n                case 6:\n                    return '[v sobotu v] LT';\n            }\n        },\n        lastDay: '[včera v] LT',\n        lastWeek: function () {\n            switch (this.day()) {\n                case 0:\n                    return '[minulou neděli v] LT';\n                case 1:\n                case 2:\n                    return '[minulé] dddd [v] LT';\n                case 3:\n                    return '[minulou středu v] LT';\n                case 4:\n                case 5:\n                    return '[minulý] dddd [v] LT';\n                case 6:\n                    return '[minulou sobotu v] LT';\n            }\n        },\n        sameElse: 'L'\n    },\n    relativeTime : {\n        future : 'za %s',\n        past : 'před %s',\n        s : translate$1,\n        m : translate$1,\n        mm : translate$1,\n        h : translate$1,\n        hh : translate$1,\n        d : translate$1,\n        dd : translate$1,\n        M : translate$1,\n        MM : translate$1,\n        y : translate$1,\n        yy : translate$1\n    },\n    dayOfMonthOrdinalParse : /\\d{1,2}\\./,\n    ordinal : '%d.',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Chuvash [cv]\n//! author : Anatoly Mironov : https://github.com/mirontoli\n\nhooks.defineLocale('cv', {\n    months : 'кӑрлач_нарӑс_пуш_ака_май_ҫӗртме_утӑ_ҫурла_авӑн_юпа_чӳк_раштав'.split('_'),\n    monthsShort : 'кӑр_нар_пуш_ака_май_ҫӗр_утӑ_ҫур_авн_юпа_чӳк_раш'.split('_'),\n    weekdays : 'вырсарникун_тунтикун_ытларикун_юнкун_кӗҫнерникун_эрнекун_шӑматкун'.split('_'),\n    weekdaysShort : 'выр_тун_ытл_юн_кӗҫ_эрн_шӑм'.split('_'),\n    weekdaysMin : 'вр_тн_ыт_юн_кҫ_эр_шм'.split('_'),\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD-MM-YYYY',\n        LL : 'YYYY [ҫулхи] MMMM [уйӑхӗн] D[-мӗшӗ]',\n        LLL : 'YYYY [ҫулхи] MMMM [уйӑхӗн] D[-мӗшӗ], HH:mm',\n        LLLL : 'dddd, YYYY [ҫулхи] MMMM [уйӑхӗн] D[-мӗшӗ], HH:mm'\n    },\n    calendar : {\n        sameDay: '[Паян] LT [сехетре]',\n        nextDay: '[Ыран] LT [сехетре]',\n        lastDay: '[Ӗнер] LT [сехетре]',\n        nextWeek: '[Ҫитес] dddd LT [сехетре]',\n        lastWeek: '[Иртнӗ] dddd LT [сехетре]',\n        sameElse: 'L'\n    },\n    relativeTime : {\n        future : function (output) {\n            var affix = /сехет$/i.exec(output) ? 'рен' : /ҫул$/i.exec(output) ? 'тан' : 'ран';\n            return output + affix;\n        },\n        past : '%s каялла',\n        s : 'пӗр-ик ҫеккунт',\n        m : 'пӗр минут',\n        mm : '%d минут',\n        h : 'пӗр сехет',\n        hh : '%d сехет',\n        d : 'пӗр кун',\n        dd : '%d кун',\n        M : 'пӗр уйӑх',\n        MM : '%d уйӑх',\n        y : 'пӗр ҫул',\n        yy : '%d ҫул'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}-мӗш/,\n    ordinal : '%d-мӗш',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 7  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Welsh [cy]\n//! author : Robert Allen : https://github.com/robgallen\n//! author : https://github.com/ryangreaves\n\nhooks.defineLocale('cy', {\n    months: 'Ionawr_Chwefror_Mawrth_Ebrill_Mai_Mehefin_Gorffennaf_Awst_Medi_Hydref_Tachwedd_Rhagfyr'.split('_'),\n    monthsShort: 'Ion_Chwe_Maw_Ebr_Mai_Meh_Gor_Aws_Med_Hyd_Tach_Rhag'.split('_'),\n    weekdays: 'Dydd Sul_Dydd Llun_Dydd Mawrth_Dydd Mercher_Dydd Iau_Dydd Gwener_Dydd Sadwrn'.split('_'),\n    weekdaysShort: 'Sul_Llun_Maw_Mer_Iau_Gwe_Sad'.split('_'),\n    weekdaysMin: 'Su_Ll_Ma_Me_Ia_Gw_Sa'.split('_'),\n    weekdaysParseExact : true,\n    // time formats are the same as en-gb\n    longDateFormat: {\n        LT: 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L: 'DD/MM/YYYY',\n        LL: 'D MMMM YYYY',\n        LLL: 'D MMMM YYYY HH:mm',\n        LLLL: 'dddd, D MMMM YYYY HH:mm'\n    },\n    calendar: {\n        sameDay: '[Heddiw am] LT',\n        nextDay: '[Yfory am] LT',\n        nextWeek: 'dddd [am] LT',\n        lastDay: '[Ddoe am] LT',\n        lastWeek: 'dddd [diwethaf am] LT',\n        sameElse: 'L'\n    },\n    relativeTime: {\n        future: 'mewn %s',\n        past: '%s yn ôl',\n        s: 'ychydig eiliadau',\n        m: 'munud',\n        mm: '%d munud',\n        h: 'awr',\n        hh: '%d awr',\n        d: 'diwrnod',\n        dd: '%d diwrnod',\n        M: 'mis',\n        MM: '%d mis',\n        y: 'blwyddyn',\n        yy: '%d flynedd'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}(fed|ain|af|il|ydd|ed|eg)/,\n    // traditional ordinal numbers above 31 are not commonly used in colloquial Welsh\n    ordinal: function (number) {\n        var b = number,\n            output = '',\n            lookup = [\n                '', 'af', 'il', 'ydd', 'ydd', 'ed', 'ed', 'ed', 'fed', 'fed', 'fed', // 1af to 10fed\n                'eg', 'fed', 'eg', 'eg', 'fed', 'eg', 'eg', 'fed', 'eg', 'fed' // 11eg to 20fed\n            ];\n        if (b > 20) {\n            if (b === 40 || b === 50 || b === 60 || b === 80 || b === 100) {\n                output = 'fed'; // not 30ain, 70ain or 90ain\n            } else {\n                output = 'ain';\n            }\n        } else if (b > 0) {\n            output = lookup[b];\n        }\n        return number + output;\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Danish [da]\n//! author : Ulrik Nielsen : https://github.com/mrbase\n\nhooks.defineLocale('da', {\n    months : 'januar_februar_marts_april_maj_juni_juli_august_september_oktober_november_december'.split('_'),\n    monthsShort : 'jan_feb_mar_apr_maj_jun_jul_aug_sep_okt_nov_dec'.split('_'),\n    weekdays : 'søndag_mandag_tirsdag_onsdag_torsdag_fredag_lørdag'.split('_'),\n    weekdaysShort : 'søn_man_tir_ons_tor_fre_lør'.split('_'),\n    weekdaysMin : 'sø_ma_ti_on_to_fr_lø'.split('_'),\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D. MMMM YYYY',\n        LLL : 'D. MMMM YYYY HH:mm',\n        LLLL : 'dddd [d.] D. MMMM YYYY [kl.] HH:mm'\n    },\n    calendar : {\n        sameDay : '[i dag kl.] LT',\n        nextDay : '[i morgen kl.] LT',\n        nextWeek : 'på dddd [kl.] LT',\n        lastDay : '[i går kl.] LT',\n        lastWeek : '[i] dddd[s kl.] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'om %s',\n        past : '%s siden',\n        s : 'få sekunder',\n        m : 'et minut',\n        mm : '%d minutter',\n        h : 'en time',\n        hh : '%d timer',\n        d : 'en dag',\n        dd : '%d dage',\n        M : 'en måned',\n        MM : '%d måneder',\n        y : 'et år',\n        yy : '%d år'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}\\./,\n    ordinal : '%d.',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : German (Austria) [de-at]\n//! author : lluchs : https://github.com/lluchs\n//! author: Menelion Elensúle: https://github.com/Oire\n//! author : Martin Groller : https://github.com/MadMG\n//! author : Mikolaj Dadela : https://github.com/mik01aj\n\nfunction processRelativeTime(number, withoutSuffix, key, isFuture) {\n    var format = {\n        'm': ['eine Minute', 'einer Minute'],\n        'h': ['eine Stunde', 'einer Stunde'],\n        'd': ['ein Tag', 'einem Tag'],\n        'dd': [number + ' Tage', number + ' Tagen'],\n        'M': ['ein Monat', 'einem Monat'],\n        'MM': [number + ' Monate', number + ' Monaten'],\n        'y': ['ein Jahr', 'einem Jahr'],\n        'yy': [number + ' Jahre', number + ' Jahren']\n    };\n    return withoutSuffix ? format[key][0] : format[key][1];\n}\n\nhooks.defineLocale('de-at', {\n    months : 'Jänner_Februar_März_April_Mai_Juni_Juli_August_September_Oktober_November_Dezember'.split('_'),\n    monthsShort : 'Jän._Febr._Mrz._Apr._Mai_Jun._Jul._Aug._Sept._Okt._Nov._Dez.'.split('_'),\n    monthsParseExact : true,\n    weekdays : 'Sonntag_Montag_Dienstag_Mittwoch_Donnerstag_Freitag_Samstag'.split('_'),\n    weekdaysShort : 'So._Mo._Di._Mi._Do._Fr._Sa.'.split('_'),\n    weekdaysMin : 'So_Mo_Di_Mi_Do_Fr_Sa'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat : {\n        LT: 'HH:mm',\n        LTS: 'HH:mm:ss',\n        L : 'DD.MM.YYYY',\n        LL : 'D. MMMM YYYY',\n        LLL : 'D. MMMM YYYY HH:mm',\n        LLLL : 'dddd, D. MMMM YYYY HH:mm'\n    },\n    calendar : {\n        sameDay: '[heute um] LT [Uhr]',\n        sameElse: 'L',\n        nextDay: '[morgen um] LT [Uhr]',\n        nextWeek: 'dddd [um] LT [Uhr]',\n        lastDay: '[gestern um] LT [Uhr]',\n        lastWeek: '[letzten] dddd [um] LT [Uhr]'\n    },\n    relativeTime : {\n        future : 'in %s',\n        past : 'vor %s',\n        s : 'ein paar Sekunden',\n        m : processRelativeTime,\n        mm : '%d Minuten',\n        h : processRelativeTime,\n        hh : '%d Stunden',\n        d : processRelativeTime,\n        dd : processRelativeTime,\n        M : processRelativeTime,\n        MM : processRelativeTime,\n        y : processRelativeTime,\n        yy : processRelativeTime\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}\\./,\n    ordinal : '%d.',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : German (Switzerland) [de-ch]\n//! author : sschueller : https://github.com/sschueller\n\n// based on: https://www.bk.admin.ch/dokumentation/sprachen/04915/05016/index.html?lang=de#\n\nfunction processRelativeTime$1(number, withoutSuffix, key, isFuture) {\n    var format = {\n        'm': ['eine Minute', 'einer Minute'],\n        'h': ['eine Stunde', 'einer Stunde'],\n        'd': ['ein Tag', 'einem Tag'],\n        'dd': [number + ' Tage', number + ' Tagen'],\n        'M': ['ein Monat', 'einem Monat'],\n        'MM': [number + ' Monate', number + ' Monaten'],\n        'y': ['ein Jahr', 'einem Jahr'],\n        'yy': [number + ' Jahre', number + ' Jahren']\n    };\n    return withoutSuffix ? format[key][0] : format[key][1];\n}\n\nhooks.defineLocale('de-ch', {\n    months : 'Januar_Februar_März_April_Mai_Juni_Juli_August_September_Oktober_November_Dezember'.split('_'),\n    monthsShort : 'Jan._Febr._März_April_Mai_Juni_Juli_Aug._Sept._Okt._Nov._Dez.'.split('_'),\n    monthsParseExact : true,\n    weekdays : 'Sonntag_Montag_Dienstag_Mittwoch_Donnerstag_Freitag_Samstag'.split('_'),\n    weekdaysShort : 'So_Mo_Di_Mi_Do_Fr_Sa'.split('_'),\n    weekdaysMin : 'So_Mo_Di_Mi_Do_Fr_Sa'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat : {\n        LT: 'HH.mm',\n        LTS: 'HH.mm.ss',\n        L : 'DD.MM.YYYY',\n        LL : 'D. MMMM YYYY',\n        LLL : 'D. MMMM YYYY HH.mm',\n        LLLL : 'dddd, D. MMMM YYYY HH.mm'\n    },\n    calendar : {\n        sameDay: '[heute um] LT [Uhr]',\n        sameElse: 'L',\n        nextDay: '[morgen um] LT [Uhr]',\n        nextWeek: 'dddd [um] LT [Uhr]',\n        lastDay: '[gestern um] LT [Uhr]',\n        lastWeek: '[letzten] dddd [um] LT [Uhr]'\n    },\n    relativeTime : {\n        future : 'in %s',\n        past : 'vor %s',\n        s : 'ein paar Sekunden',\n        m : processRelativeTime$1,\n        mm : '%d Minuten',\n        h : processRelativeTime$1,\n        hh : '%d Stunden',\n        d : processRelativeTime$1,\n        dd : processRelativeTime$1,\n        M : processRelativeTime$1,\n        MM : processRelativeTime$1,\n        y : processRelativeTime$1,\n        yy : processRelativeTime$1\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}\\./,\n    ordinal : '%d.',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : German [de]\n//! author : lluchs : https://github.com/lluchs\n//! author: Menelion Elensúle: https://github.com/Oire\n//! author : Mikolaj Dadela : https://github.com/mik01aj\n\nfunction processRelativeTime$2(number, withoutSuffix, key, isFuture) {\n    var format = {\n        'm': ['eine Minute', 'einer Minute'],\n        'h': ['eine Stunde', 'einer Stunde'],\n        'd': ['ein Tag', 'einem Tag'],\n        'dd': [number + ' Tage', number + ' Tagen'],\n        'M': ['ein Monat', 'einem Monat'],\n        'MM': [number + ' Monate', number + ' Monaten'],\n        'y': ['ein Jahr', 'einem Jahr'],\n        'yy': [number + ' Jahre', number + ' Jahren']\n    };\n    return withoutSuffix ? format[key][0] : format[key][1];\n}\n\nhooks.defineLocale('de', {\n    months : 'Januar_Februar_März_April_Mai_Juni_Juli_August_September_Oktober_November_Dezember'.split('_'),\n    monthsShort : 'Jan._Febr._Mrz._Apr._Mai_Jun._Jul._Aug._Sept._Okt._Nov._Dez.'.split('_'),\n    monthsParseExact : true,\n    weekdays : 'Sonntag_Montag_Dienstag_Mittwoch_Donnerstag_Freitag_Samstag'.split('_'),\n    weekdaysShort : 'So._Mo._Di._Mi._Do._Fr._Sa.'.split('_'),\n    weekdaysMin : 'So_Mo_Di_Mi_Do_Fr_Sa'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat : {\n        LT: 'HH:mm',\n        LTS: 'HH:mm:ss',\n        L : 'DD.MM.YYYY',\n        LL : 'D. MMMM YYYY',\n        LLL : 'D. MMMM YYYY HH:mm',\n        LLLL : 'dddd, D. MMMM YYYY HH:mm'\n    },\n    calendar : {\n        sameDay: '[heute um] LT [Uhr]',\n        sameElse: 'L',\n        nextDay: '[morgen um] LT [Uhr]',\n        nextWeek: 'dddd [um] LT [Uhr]',\n        lastDay: '[gestern um] LT [Uhr]',\n        lastWeek: '[letzten] dddd [um] LT [Uhr]'\n    },\n    relativeTime : {\n        future : 'in %s',\n        past : 'vor %s',\n        s : 'ein paar Sekunden',\n        m : processRelativeTime$2,\n        mm : '%d Minuten',\n        h : processRelativeTime$2,\n        hh : '%d Stunden',\n        d : processRelativeTime$2,\n        dd : processRelativeTime$2,\n        M : processRelativeTime$2,\n        MM : processRelativeTime$2,\n        y : processRelativeTime$2,\n        yy : processRelativeTime$2\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}\\./,\n    ordinal : '%d.',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Maldivian [dv]\n//! author : Jawish Hameed : https://github.com/jawish\n\nvar months$4 = [\n    'ޖެނުއަރީ',\n    'ފެބްރުއަރީ',\n    'މާރިޗު',\n    'އޭޕްރީލު',\n    'މޭ',\n    'ޖޫން',\n    'ޖުލައި',\n    'އޯގަސްޓު',\n    'ސެޕްޓެމްބަރު',\n    'އޮކްޓޯބަރު',\n    'ނޮވެމްބަރު',\n    'ޑިސެމްބަރު'\n];\nvar weekdays = [\n    'އާދިއްތަ',\n    'ހޯމަ',\n    'އަންގާރަ',\n    'ބުދަ',\n    'ބުރާސްފަތި',\n    'ހުކުރު',\n    'ހޮނިހިރު'\n];\n\nhooks.defineLocale('dv', {\n    months : months$4,\n    monthsShort : months$4,\n    weekdays : weekdays,\n    weekdaysShort : weekdays,\n    weekdaysMin : 'އާދި_ހޯމަ_އަން_ބުދަ_ބުރާ_ހުކު_ހޮނި'.split('_'),\n    longDateFormat : {\n\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'D/M/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY HH:mm',\n        LLLL : 'dddd D MMMM YYYY HH:mm'\n    },\n    meridiemParse: /މކ|މފ/,\n    isPM : function (input) {\n        return 'މފ' === input;\n    },\n    meridiem : function (hour, minute, isLower) {\n        if (hour < 12) {\n            return 'މކ';\n        } else {\n            return 'މފ';\n        }\n    },\n    calendar : {\n        sameDay : '[މިއަދު] LT',\n        nextDay : '[މާދަމާ] LT',\n        nextWeek : 'dddd LT',\n        lastDay : '[އިއްޔެ] LT',\n        lastWeek : '[ފާއިތުވި] dddd LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'ތެރޭގައި %s',\n        past : 'ކުރިން %s',\n        s : 'ސިކުންތުކޮޅެއް',\n        m : 'މިނިޓެއް',\n        mm : 'މިނިޓު %d',\n        h : 'ގަޑިއިރެއް',\n        hh : 'ގަޑިއިރު %d',\n        d : 'ދުވަހެއް',\n        dd : 'ދުވަސް %d',\n        M : 'މަހެއް',\n        MM : 'މަސް %d',\n        y : 'އަހަރެއް',\n        yy : 'އަހަރު %d'\n    },\n    preparse: function (string) {\n        return string.replace(/،/g, ',');\n    },\n    postformat: function (string) {\n        return string.replace(/,/g, '،');\n    },\n    week : {\n        dow : 7,  // Sunday is the first day of the week.\n        doy : 12  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Greek [el]\n//! author : Aggelos Karalias : https://github.com/mehiel\n\nhooks.defineLocale('el', {\n    monthsNominativeEl : 'Ιανουάριος_Φεβρουάριος_Μάρτιος_Απρίλιος_Μάιος_Ιούνιος_Ιούλιος_Αύγουστος_Σεπτέμβριος_Οκτώβριος_Νοέμβριος_Δεκέμβριος'.split('_'),\n    monthsGenitiveEl : 'Ιανουαρίου_Φεβρουαρίου_Μαρτίου_Απριλίου_Μαΐου_Ιουνίου_Ιουλίου_Αυγούστου_Σεπτεμβρίου_Οκτωβρίου_Νοεμβρίου_Δεκεμβρίου'.split('_'),\n    months : function (momentToFormat, format) {\n        if (!momentToFormat) {\n            return this._monthsNominativeEl;\n        } else if (/D/.test(format.substring(0, format.indexOf('MMMM')))) { // if there is a day number before 'MMMM'\n            return this._monthsGenitiveEl[momentToFormat.month()];\n        } else {\n            return this._monthsNominativeEl[momentToFormat.month()];\n        }\n    },\n    monthsShort : 'Ιαν_Φεβ_Μαρ_Απρ_Μαϊ_Ιουν_Ιουλ_Αυγ_Σεπ_Οκτ_Νοε_Δεκ'.split('_'),\n    weekdays : 'Κυριακή_Δευτέρα_Τρίτη_Τετάρτη_Πέμπτη_Παρασκευή_Σάββατο'.split('_'),\n    weekdaysShort : 'Κυρ_Δευ_Τρι_Τετ_Πεμ_Παρ_Σαβ'.split('_'),\n    weekdaysMin : 'Κυ_Δε_Τρ_Τε_Πε_Πα_Σα'.split('_'),\n    meridiem : function (hours, minutes, isLower) {\n        if (hours > 11) {\n            return isLower ? 'μμ' : 'ΜΜ';\n        } else {\n            return isLower ? 'πμ' : 'ΠΜ';\n        }\n    },\n    isPM : function (input) {\n        return ((input + '').toLowerCase()[0] === 'μ');\n    },\n    meridiemParse : /[ΠΜ]\\.?Μ?\\.?/i,\n    longDateFormat : {\n        LT : 'h:mm A',\n        LTS : 'h:mm:ss A',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY h:mm A',\n        LLLL : 'dddd, D MMMM YYYY h:mm A'\n    },\n    calendarEl : {\n        sameDay : '[Σήμερα {}] LT',\n        nextDay : '[Αύριο {}] LT',\n        nextWeek : 'dddd [{}] LT',\n        lastDay : '[Χθες {}] LT',\n        lastWeek : function () {\n            switch (this.day()) {\n                case 6:\n                    return '[το προηγούμενο] dddd [{}] LT';\n                default:\n                    return '[την προηγούμενη] dddd [{}] LT';\n            }\n        },\n        sameElse : 'L'\n    },\n    calendar : function (key, mom) {\n        var output = this._calendarEl[key],\n            hours = mom && mom.hours();\n        if (isFunction(output)) {\n            output = output.apply(mom);\n        }\n        return output.replace('{}', (hours % 12 === 1 ? 'στη' : 'στις'));\n    },\n    relativeTime : {\n        future : 'σε %s',\n        past : '%s πριν',\n        s : 'λίγα δευτερόλεπτα',\n        m : 'ένα λεπτό',\n        mm : '%d λεπτά',\n        h : 'μία ώρα',\n        hh : '%d ώρες',\n        d : 'μία μέρα',\n        dd : '%d μέρες',\n        M : 'ένας μήνας',\n        MM : '%d μήνες',\n        y : 'ένας χρόνος',\n        yy : '%d χρόνια'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}η/,\n    ordinal: '%dη',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4st is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : English (Australia) [en-au]\n//! author : Jared Morse : https://github.com/jarcoal\n\nhooks.defineLocale('en-au', {\n    months : 'January_February_March_April_May_June_July_August_September_October_November_December'.split('_'),\n    monthsShort : 'Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec'.split('_'),\n    weekdays : 'Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday'.split('_'),\n    weekdaysShort : 'Sun_Mon_Tue_Wed_Thu_Fri_Sat'.split('_'),\n    weekdaysMin : 'Su_Mo_Tu_We_Th_Fr_Sa'.split('_'),\n    longDateFormat : {\n        LT : 'h:mm A',\n        LTS : 'h:mm:ss A',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY h:mm A',\n        LLLL : 'dddd, D MMMM YYYY h:mm A'\n    },\n    calendar : {\n        sameDay : '[Today at] LT',\n        nextDay : '[Tomorrow at] LT',\n        nextWeek : 'dddd [at] LT',\n        lastDay : '[Yesterday at] LT',\n        lastWeek : '[Last] dddd [at] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'in %s',\n        past : '%s ago',\n        s : 'a few seconds',\n        m : 'a minute',\n        mm : '%d minutes',\n        h : 'an hour',\n        hh : '%d hours',\n        d : 'a day',\n        dd : '%d days',\n        M : 'a month',\n        MM : '%d months',\n        y : 'a year',\n        yy : '%d years'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}(st|nd|rd|th)/,\n    ordinal : function (number) {\n        var b = number % 10,\n            output = (~~(number % 100 / 10) === 1) ? 'th' :\n            (b === 1) ? 'st' :\n            (b === 2) ? 'nd' :\n            (b === 3) ? 'rd' : 'th';\n        return number + output;\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : English (Canada) [en-ca]\n//! author : Jonathan Abourbih : https://github.com/jonbca\n\nhooks.defineLocale('en-ca', {\n    months : 'January_February_March_April_May_June_July_August_September_October_November_December'.split('_'),\n    monthsShort : 'Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec'.split('_'),\n    weekdays : 'Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday'.split('_'),\n    weekdaysShort : 'Sun_Mon_Tue_Wed_Thu_Fri_Sat'.split('_'),\n    weekdaysMin : 'Su_Mo_Tu_We_Th_Fr_Sa'.split('_'),\n    longDateFormat : {\n        LT : 'h:mm A',\n        LTS : 'h:mm:ss A',\n        L : 'YYYY-MM-DD',\n        LL : 'MMMM D, YYYY',\n        LLL : 'MMMM D, YYYY h:mm A',\n        LLLL : 'dddd, MMMM D, YYYY h:mm A'\n    },\n    calendar : {\n        sameDay : '[Today at] LT',\n        nextDay : '[Tomorrow at] LT',\n        nextWeek : 'dddd [at] LT',\n        lastDay : '[Yesterday at] LT',\n        lastWeek : '[Last] dddd [at] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'in %s',\n        past : '%s ago',\n        s : 'a few seconds',\n        m : 'a minute',\n        mm : '%d minutes',\n        h : 'an hour',\n        hh : '%d hours',\n        d : 'a day',\n        dd : '%d days',\n        M : 'a month',\n        MM : '%d months',\n        y : 'a year',\n        yy : '%d years'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}(st|nd|rd|th)/,\n    ordinal : function (number) {\n        var b = number % 10,\n            output = (~~(number % 100 / 10) === 1) ? 'th' :\n            (b === 1) ? 'st' :\n            (b === 2) ? 'nd' :\n            (b === 3) ? 'rd' : 'th';\n        return number + output;\n    }\n});\n\n//! moment.js locale configuration\n//! locale : English (United Kingdom) [en-gb]\n//! author : Chris Gedrim : https://github.com/chrisgedrim\n\nhooks.defineLocale('en-gb', {\n    months : 'January_February_March_April_May_June_July_August_September_October_November_December'.split('_'),\n    monthsShort : 'Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec'.split('_'),\n    weekdays : 'Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday'.split('_'),\n    weekdaysShort : 'Sun_Mon_Tue_Wed_Thu_Fri_Sat'.split('_'),\n    weekdaysMin : 'Su_Mo_Tu_We_Th_Fr_Sa'.split('_'),\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY HH:mm',\n        LLLL : 'dddd, D MMMM YYYY HH:mm'\n    },\n    calendar : {\n        sameDay : '[Today at] LT',\n        nextDay : '[Tomorrow at] LT',\n        nextWeek : 'dddd [at] LT',\n        lastDay : '[Yesterday at] LT',\n        lastWeek : '[Last] dddd [at] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'in %s',\n        past : '%s ago',\n        s : 'a few seconds',\n        m : 'a minute',\n        mm : '%d minutes',\n        h : 'an hour',\n        hh : '%d hours',\n        d : 'a day',\n        dd : '%d days',\n        M : 'a month',\n        MM : '%d months',\n        y : 'a year',\n        yy : '%d years'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}(st|nd|rd|th)/,\n    ordinal : function (number) {\n        var b = number % 10,\n            output = (~~(number % 100 / 10) === 1) ? 'th' :\n            (b === 1) ? 'st' :\n            (b === 2) ? 'nd' :\n            (b === 3) ? 'rd' : 'th';\n        return number + output;\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : English (Ireland) [en-ie]\n//! author : Chris Cartlidge : https://github.com/chriscartlidge\n\nhooks.defineLocale('en-ie', {\n    months : 'January_February_March_April_May_June_July_August_September_October_November_December'.split('_'),\n    monthsShort : 'Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec'.split('_'),\n    weekdays : 'Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday'.split('_'),\n    weekdaysShort : 'Sun_Mon_Tue_Wed_Thu_Fri_Sat'.split('_'),\n    weekdaysMin : 'Su_Mo_Tu_We_Th_Fr_Sa'.split('_'),\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD-MM-YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY HH:mm',\n        LLLL : 'dddd D MMMM YYYY HH:mm'\n    },\n    calendar : {\n        sameDay : '[Today at] LT',\n        nextDay : '[Tomorrow at] LT',\n        nextWeek : 'dddd [at] LT',\n        lastDay : '[Yesterday at] LT',\n        lastWeek : '[Last] dddd [at] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'in %s',\n        past : '%s ago',\n        s : 'a few seconds',\n        m : 'a minute',\n        mm : '%d minutes',\n        h : 'an hour',\n        hh : '%d hours',\n        d : 'a day',\n        dd : '%d days',\n        M : 'a month',\n        MM : '%d months',\n        y : 'a year',\n        yy : '%d years'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}(st|nd|rd|th)/,\n    ordinal : function (number) {\n        var b = number % 10,\n            output = (~~(number % 100 / 10) === 1) ? 'th' :\n            (b === 1) ? 'st' :\n            (b === 2) ? 'nd' :\n            (b === 3) ? 'rd' : 'th';\n        return number + output;\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : English (New Zealand) [en-nz]\n//! author : Luke McGregor : https://github.com/lukemcgregor\n\nhooks.defineLocale('en-nz', {\n    months : 'January_February_March_April_May_June_July_August_September_October_November_December'.split('_'),\n    monthsShort : 'Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec'.split('_'),\n    weekdays : 'Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday'.split('_'),\n    weekdaysShort : 'Sun_Mon_Tue_Wed_Thu_Fri_Sat'.split('_'),\n    weekdaysMin : 'Su_Mo_Tu_We_Th_Fr_Sa'.split('_'),\n    longDateFormat : {\n        LT : 'h:mm A',\n        LTS : 'h:mm:ss A',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY h:mm A',\n        LLLL : 'dddd, D MMMM YYYY h:mm A'\n    },\n    calendar : {\n        sameDay : '[Today at] LT',\n        nextDay : '[Tomorrow at] LT',\n        nextWeek : 'dddd [at] LT',\n        lastDay : '[Yesterday at] LT',\n        lastWeek : '[Last] dddd [at] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'in %s',\n        past : '%s ago',\n        s : 'a few seconds',\n        m : 'a minute',\n        mm : '%d minutes',\n        h : 'an hour',\n        hh : '%d hours',\n        d : 'a day',\n        dd : '%d days',\n        M : 'a month',\n        MM : '%d months',\n        y : 'a year',\n        yy : '%d years'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}(st|nd|rd|th)/,\n    ordinal : function (number) {\n        var b = number % 10,\n            output = (~~(number % 100 / 10) === 1) ? 'th' :\n            (b === 1) ? 'st' :\n            (b === 2) ? 'nd' :\n            (b === 3) ? 'rd' : 'th';\n        return number + output;\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Esperanto [eo]\n//! author : Colin Dean : https://github.com/colindean\n//! author : Mia Nordentoft Imperatori : https://github.com/miestasmia\n//! comment : miestasmia corrected the translation by colindean\n\nhooks.defineLocale('eo', {\n    months : 'januaro_februaro_marto_aprilo_majo_junio_julio_aŭgusto_septembro_oktobro_novembro_decembro'.split('_'),\n    monthsShort : 'jan_feb_mar_apr_maj_jun_jul_aŭg_sep_okt_nov_dec'.split('_'),\n    weekdays : 'dimanĉo_lundo_mardo_merkredo_ĵaŭdo_vendredo_sabato'.split('_'),\n    weekdaysShort : 'dim_lun_mard_merk_ĵaŭ_ven_sab'.split('_'),\n    weekdaysMin : 'di_lu_ma_me_ĵa_ve_sa'.split('_'),\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'YYYY-MM-DD',\n        LL : 'D[-a de] MMMM, YYYY',\n        LLL : 'D[-a de] MMMM, YYYY HH:mm',\n        LLLL : 'dddd, [la] D[-a de] MMMM, YYYY HH:mm'\n    },\n    meridiemParse: /[ap]\\.t\\.m/i,\n    isPM: function (input) {\n        return input.charAt(0).toLowerCase() === 'p';\n    },\n    meridiem : function (hours, minutes, isLower) {\n        if (hours > 11) {\n            return isLower ? 'p.t.m.' : 'P.T.M.';\n        } else {\n            return isLower ? 'a.t.m.' : 'A.T.M.';\n        }\n    },\n    calendar : {\n        sameDay : '[Hodiaŭ je] LT',\n        nextDay : '[Morgaŭ je] LT',\n        nextWeek : 'dddd [je] LT',\n        lastDay : '[Hieraŭ je] LT',\n        lastWeek : '[pasinta] dddd [je] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'post %s',\n        past : 'antaŭ %s',\n        s : 'sekundoj',\n        m : 'minuto',\n        mm : '%d minutoj',\n        h : 'horo',\n        hh : '%d horoj',\n        d : 'tago',//ne 'diurno', ĉar estas uzita por proksimumo\n        dd : '%d tagoj',\n        M : 'monato',\n        MM : '%d monatoj',\n        y : 'jaro',\n        yy : '%d jaroj'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}a/,\n    ordinal : '%da',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 7  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Spanish (Dominican Republic) [es-do]\n\nvar monthsShortDot = 'ene._feb._mar._abr._may._jun._jul._ago._sep._oct._nov._dic.'.split('_');\nvar monthsShort$1 = 'ene_feb_mar_abr_may_jun_jul_ago_sep_oct_nov_dic'.split('_');\n\nhooks.defineLocale('es-do', {\n    months : 'enero_febrero_marzo_abril_mayo_junio_julio_agosto_septiembre_octubre_noviembre_diciembre'.split('_'),\n    monthsShort : function (m, format) {\n        if (!m) {\n            return monthsShortDot;\n        } else if (/-MMM-/.test(format)) {\n            return monthsShort$1[m.month()];\n        } else {\n            return monthsShortDot[m.month()];\n        }\n    },\n    monthsParseExact : true,\n    weekdays : 'domingo_lunes_martes_miércoles_jueves_viernes_sábado'.split('_'),\n    weekdaysShort : 'dom._lun._mar._mié._jue._vie._sáb.'.split('_'),\n    weekdaysMin : 'do_lu_ma_mi_ju_vi_sá'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat : {\n        LT : 'h:mm A',\n        LTS : 'h:mm:ss A',\n        L : 'DD/MM/YYYY',\n        LL : 'D [de] MMMM [de] YYYY',\n        LLL : 'D [de] MMMM [de] YYYY h:mm A',\n        LLLL : 'dddd, D [de] MMMM [de] YYYY h:mm A'\n    },\n    calendar : {\n        sameDay : function () {\n            return '[hoy a la' + ((this.hours() !== 1) ? 's' : '') + '] LT';\n        },\n        nextDay : function () {\n            return '[mañana a la' + ((this.hours() !== 1) ? 's' : '') + '] LT';\n        },\n        nextWeek : function () {\n            return 'dddd [a la' + ((this.hours() !== 1) ? 's' : '') + '] LT';\n        },\n        lastDay : function () {\n            return '[ayer a la' + ((this.hours() !== 1) ? 's' : '') + '] LT';\n        },\n        lastWeek : function () {\n            return '[el] dddd [pasado a la' + ((this.hours() !== 1) ? 's' : '') + '] LT';\n        },\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'en %s',\n        past : 'hace %s',\n        s : 'unos segundos',\n        m : 'un minuto',\n        mm : '%d minutos',\n        h : 'una hora',\n        hh : '%d horas',\n        d : 'un día',\n        dd : '%d días',\n        M : 'un mes',\n        MM : '%d meses',\n        y : 'un año',\n        yy : '%d años'\n    },\n    dayOfMonthOrdinalParse : /\\d{1,2}º/,\n    ordinal : '%dº',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Spanish [es]\n//! author : Julio Napurí : https://github.com/julionc\n\nvar monthsShortDot$1 = 'ene._feb._mar._abr._may._jun._jul._ago._sep._oct._nov._dic.'.split('_');\nvar monthsShort$2 = 'ene_feb_mar_abr_may_jun_jul_ago_sep_oct_nov_dic'.split('_');\n\nhooks.defineLocale('es', {\n    months : 'enero_febrero_marzo_abril_mayo_junio_julio_agosto_septiembre_octubre_noviembre_diciembre'.split('_'),\n    monthsShort : function (m, format) {\n        if (!m) {\n            return monthsShortDot$1;\n        } else if (/-MMM-/.test(format)) {\n            return monthsShort$2[m.month()];\n        } else {\n            return monthsShortDot$1[m.month()];\n        }\n    },\n    monthsParseExact : true,\n    weekdays : 'domingo_lunes_martes_miércoles_jueves_viernes_sábado'.split('_'),\n    weekdaysShort : 'dom._lun._mar._mié._jue._vie._sáb.'.split('_'),\n    weekdaysMin : 'do_lu_ma_mi_ju_vi_sá'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat : {\n        LT : 'H:mm',\n        LTS : 'H:mm:ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D [de] MMMM [de] YYYY',\n        LLL : 'D [de] MMMM [de] YYYY H:mm',\n        LLLL : 'dddd, D [de] MMMM [de] YYYY H:mm'\n    },\n    calendar : {\n        sameDay : function () {\n            return '[hoy a la' + ((this.hours() !== 1) ? 's' : '') + '] LT';\n        },\n        nextDay : function () {\n            return '[mañana a la' + ((this.hours() !== 1) ? 's' : '') + '] LT';\n        },\n        nextWeek : function () {\n            return 'dddd [a la' + ((this.hours() !== 1) ? 's' : '') + '] LT';\n        },\n        lastDay : function () {\n            return '[ayer a la' + ((this.hours() !== 1) ? 's' : '') + '] LT';\n        },\n        lastWeek : function () {\n            return '[el] dddd [pasado a la' + ((this.hours() !== 1) ? 's' : '') + '] LT';\n        },\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'en %s',\n        past : 'hace %s',\n        s : 'unos segundos',\n        m : 'un minuto',\n        mm : '%d minutos',\n        h : 'una hora',\n        hh : '%d horas',\n        d : 'un día',\n        dd : '%d días',\n        M : 'un mes',\n        MM : '%d meses',\n        y : 'un año',\n        yy : '%d años'\n    },\n    dayOfMonthOrdinalParse : /\\d{1,2}º/,\n    ordinal : '%dº',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Estonian [et]\n//! author : Henry Kehlmann : https://github.com/madhenry\n//! improvements : Illimar Tambek : https://github.com/ragulka\n\nfunction processRelativeTime$3(number, withoutSuffix, key, isFuture) {\n    var format = {\n        's' : ['mõne sekundi', 'mõni sekund', 'paar sekundit'],\n        'm' : ['ühe minuti', 'üks minut'],\n        'mm': [number + ' minuti', number + ' minutit'],\n        'h' : ['ühe tunni', 'tund aega', 'üks tund'],\n        'hh': [number + ' tunni', number + ' tundi'],\n        'd' : ['ühe päeva', 'üks päev'],\n        'M' : ['kuu aja', 'kuu aega', 'üks kuu'],\n        'MM': [number + ' kuu', number + ' kuud'],\n        'y' : ['ühe aasta', 'aasta', 'üks aasta'],\n        'yy': [number + ' aasta', number + ' aastat']\n    };\n    if (withoutSuffix) {\n        return format[key][2] ? format[key][2] : format[key][1];\n    }\n    return isFuture ? format[key][0] : format[key][1];\n}\n\nhooks.defineLocale('et', {\n    months        : 'jaanuar_veebruar_märts_aprill_mai_juuni_juuli_august_september_oktoober_november_detsember'.split('_'),\n    monthsShort   : 'jaan_veebr_märts_apr_mai_juuni_juuli_aug_sept_okt_nov_dets'.split('_'),\n    weekdays      : 'pühapäev_esmaspäev_teisipäev_kolmapäev_neljapäev_reede_laupäev'.split('_'),\n    weekdaysShort : 'P_E_T_K_N_R_L'.split('_'),\n    weekdaysMin   : 'P_E_T_K_N_R_L'.split('_'),\n    longDateFormat : {\n        LT   : 'H:mm',\n        LTS : 'H:mm:ss',\n        L    : 'DD.MM.YYYY',\n        LL   : 'D. MMMM YYYY',\n        LLL  : 'D. MMMM YYYY H:mm',\n        LLLL : 'dddd, D. MMMM YYYY H:mm'\n    },\n    calendar : {\n        sameDay  : '[Täna,] LT',\n        nextDay  : '[Homme,] LT',\n        nextWeek : '[Järgmine] dddd LT',\n        lastDay  : '[Eile,] LT',\n        lastWeek : '[Eelmine] dddd LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : '%s pärast',\n        past   : '%s tagasi',\n        s      : processRelativeTime$3,\n        m      : processRelativeTime$3,\n        mm     : processRelativeTime$3,\n        h      : processRelativeTime$3,\n        hh     : processRelativeTime$3,\n        d      : processRelativeTime$3,\n        dd     : '%d päeva',\n        M      : processRelativeTime$3,\n        MM     : processRelativeTime$3,\n        y      : processRelativeTime$3,\n        yy     : processRelativeTime$3\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}\\./,\n    ordinal : '%d.',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Basque [eu]\n//! author : Eneko Illarramendi : https://github.com/eillarra\n\nhooks.defineLocale('eu', {\n    months : 'urtarrila_otsaila_martxoa_apirila_maiatza_ekaina_uztaila_abuztua_iraila_urria_azaroa_abendua'.split('_'),\n    monthsShort : 'urt._ots._mar._api._mai._eka._uzt._abu._ira._urr._aza._abe.'.split('_'),\n    monthsParseExact : true,\n    weekdays : 'igandea_astelehena_asteartea_asteazkena_osteguna_ostirala_larunbata'.split('_'),\n    weekdaysShort : 'ig._al._ar._az._og._ol._lr.'.split('_'),\n    weekdaysMin : 'ig_al_ar_az_og_ol_lr'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'YYYY-MM-DD',\n        LL : 'YYYY[ko] MMMM[ren] D[a]',\n        LLL : 'YYYY[ko] MMMM[ren] D[a] HH:mm',\n        LLLL : 'dddd, YYYY[ko] MMMM[ren] D[a] HH:mm',\n        l : 'YYYY-M-D',\n        ll : 'YYYY[ko] MMM D[a]',\n        lll : 'YYYY[ko] MMM D[a] HH:mm',\n        llll : 'ddd, YYYY[ko] MMM D[a] HH:mm'\n    },\n    calendar : {\n        sameDay : '[gaur] LT[etan]',\n        nextDay : '[bihar] LT[etan]',\n        nextWeek : 'dddd LT[etan]',\n        lastDay : '[atzo] LT[etan]',\n        lastWeek : '[aurreko] dddd LT[etan]',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : '%s barru',\n        past : 'duela %s',\n        s : 'segundo batzuk',\n        m : 'minutu bat',\n        mm : '%d minutu',\n        h : 'ordu bat',\n        hh : '%d ordu',\n        d : 'egun bat',\n        dd : '%d egun',\n        M : 'hilabete bat',\n        MM : '%d hilabete',\n        y : 'urte bat',\n        yy : '%d urte'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}\\./,\n    ordinal : '%d.',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 7  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Persian [fa]\n//! author : Ebrahim Byagowi : https://github.com/ebraminio\n\nvar symbolMap$5 = {\n    '1': '۱',\n    '2': '۲',\n    '3': '۳',\n    '4': '۴',\n    '5': '۵',\n    '6': '۶',\n    '7': '۷',\n    '8': '۸',\n    '9': '۹',\n    '0': '۰'\n};\nvar numberMap$4 = {\n    '۱': '1',\n    '۲': '2',\n    '۳': '3',\n    '۴': '4',\n    '۵': '5',\n    '۶': '6',\n    '۷': '7',\n    '۸': '8',\n    '۹': '9',\n    '۰': '0'\n};\n\nhooks.defineLocale('fa', {\n    months : 'ژانویه_فوریه_مارس_آوریل_مه_ژوئن_ژوئیه_اوت_سپتامبر_اکتبر_نوامبر_دسامبر'.split('_'),\n    monthsShort : 'ژانویه_فوریه_مارس_آوریل_مه_ژوئن_ژوئیه_اوت_سپتامبر_اکتبر_نوامبر_دسامبر'.split('_'),\n    weekdays : 'یک\\u200cشنبه_دوشنبه_سه\\u200cشنبه_چهارشنبه_پنج\\u200cشنبه_جمعه_شنبه'.split('_'),\n    weekdaysShort : 'یک\\u200cشنبه_دوشنبه_سه\\u200cشنبه_چهارشنبه_پنج\\u200cشنبه_جمعه_شنبه'.split('_'),\n    weekdaysMin : 'ی_د_س_چ_پ_ج_ش'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY HH:mm',\n        LLLL : 'dddd, D MMMM YYYY HH:mm'\n    },\n    meridiemParse: /قبل از ظهر|بعد از ظهر/,\n    isPM: function (input) {\n        return /بعد از ظهر/.test(input);\n    },\n    meridiem : function (hour, minute, isLower) {\n        if (hour < 12) {\n            return 'قبل از ظهر';\n        } else {\n            return 'بعد از ظهر';\n        }\n    },\n    calendar : {\n        sameDay : '[امروز ساعت] LT',\n        nextDay : '[فردا ساعت] LT',\n        nextWeek : 'dddd [ساعت] LT',\n        lastDay : '[دیروز ساعت] LT',\n        lastWeek : 'dddd [پیش] [ساعت] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'در %s',\n        past : '%s پیش',\n        s : 'چند ثانیه',\n        m : 'یک دقیقه',\n        mm : '%d دقیقه',\n        h : 'یک ساعت',\n        hh : '%d ساعت',\n        d : 'یک روز',\n        dd : '%d روز',\n        M : 'یک ماه',\n        MM : '%d ماه',\n        y : 'یک سال',\n        yy : '%d سال'\n    },\n    preparse: function (string) {\n        return string.replace(/[۰-۹]/g, function (match) {\n            return numberMap$4[match];\n        }).replace(/،/g, ',');\n    },\n    postformat: function (string) {\n        return string.replace(/\\d/g, function (match) {\n            return symbolMap$5[match];\n        }).replace(/,/g, '،');\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}م/,\n    ordinal : '%dم',\n    week : {\n        dow : 6, // Saturday is the first day of the week.\n        doy : 12 // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Finnish [fi]\n//! author : Tarmo Aidantausta : https://github.com/bleadof\n\nvar numbersPast = 'nolla yksi kaksi kolme neljä viisi kuusi seitsemän kahdeksan yhdeksän'.split(' ');\nvar numbersFuture = [\n        'nolla', 'yhden', 'kahden', 'kolmen', 'neljän', 'viiden', 'kuuden',\n        numbersPast[7], numbersPast[8], numbersPast[9]\n    ];\nfunction translate$2(number, withoutSuffix, key, isFuture) {\n    var result = '';\n    switch (key) {\n        case 's':\n            return isFuture ? 'muutaman sekunnin' : 'muutama sekunti';\n        case 'm':\n            return isFuture ? 'minuutin' : 'minuutti';\n        case 'mm':\n            result = isFuture ? 'minuutin' : 'minuuttia';\n            break;\n        case 'h':\n            return isFuture ? 'tunnin' : 'tunti';\n        case 'hh':\n            result = isFuture ? 'tunnin' : 'tuntia';\n            break;\n        case 'd':\n            return isFuture ? 'päivän' : 'päivä';\n        case 'dd':\n            result = isFuture ? 'päivän' : 'päivää';\n            break;\n        case 'M':\n            return isFuture ? 'kuukauden' : 'kuukausi';\n        case 'MM':\n            result = isFuture ? 'kuukauden' : 'kuukautta';\n            break;\n        case 'y':\n            return isFuture ? 'vuoden' : 'vuosi';\n        case 'yy':\n            result = isFuture ? 'vuoden' : 'vuotta';\n            break;\n    }\n    result = verbalNumber(number, isFuture) + ' ' + result;\n    return result;\n}\nfunction verbalNumber(number, isFuture) {\n    return number < 10 ? (isFuture ? numbersFuture[number] : numbersPast[number]) : number;\n}\n\nhooks.defineLocale('fi', {\n    months : 'tammikuu_helmikuu_maaliskuu_huhtikuu_toukokuu_kesäkuu_heinäkuu_elokuu_syyskuu_lokakuu_marraskuu_joulukuu'.split('_'),\n    monthsShort : 'tammi_helmi_maalis_huhti_touko_kesä_heinä_elo_syys_loka_marras_joulu'.split('_'),\n    weekdays : 'sunnuntai_maanantai_tiistai_keskiviikko_torstai_perjantai_lauantai'.split('_'),\n    weekdaysShort : 'su_ma_ti_ke_to_pe_la'.split('_'),\n    weekdaysMin : 'su_ma_ti_ke_to_pe_la'.split('_'),\n    longDateFormat : {\n        LT : 'HH.mm',\n        LTS : 'HH.mm.ss',\n        L : 'DD.MM.YYYY',\n        LL : 'Do MMMM[ta] YYYY',\n        LLL : 'Do MMMM[ta] YYYY, [klo] HH.mm',\n        LLLL : 'dddd, Do MMMM[ta] YYYY, [klo] HH.mm',\n        l : 'D.M.YYYY',\n        ll : 'Do MMM YYYY',\n        lll : 'Do MMM YYYY, [klo] HH.mm',\n        llll : 'ddd, Do MMM YYYY, [klo] HH.mm'\n    },\n    calendar : {\n        sameDay : '[tänään] [klo] LT',\n        nextDay : '[huomenna] [klo] LT',\n        nextWeek : 'dddd [klo] LT',\n        lastDay : '[eilen] [klo] LT',\n        lastWeek : '[viime] dddd[na] [klo] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : '%s päästä',\n        past : '%s sitten',\n        s : translate$2,\n        m : translate$2,\n        mm : translate$2,\n        h : translate$2,\n        hh : translate$2,\n        d : translate$2,\n        dd : translate$2,\n        M : translate$2,\n        MM : translate$2,\n        y : translate$2,\n        yy : translate$2\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}\\./,\n    ordinal : '%d.',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Faroese [fo]\n//! author : Ragnar Johannesen : https://github.com/ragnar123\n\nhooks.defineLocale('fo', {\n    months : 'januar_februar_mars_apríl_mai_juni_juli_august_september_oktober_november_desember'.split('_'),\n    monthsShort : 'jan_feb_mar_apr_mai_jun_jul_aug_sep_okt_nov_des'.split('_'),\n    weekdays : 'sunnudagur_mánadagur_týsdagur_mikudagur_hósdagur_fríggjadagur_leygardagur'.split('_'),\n    weekdaysShort : 'sun_mán_týs_mik_hós_frí_ley'.split('_'),\n    weekdaysMin : 'su_má_tý_mi_hó_fr_le'.split('_'),\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY HH:mm',\n        LLLL : 'dddd D. MMMM, YYYY HH:mm'\n    },\n    calendar : {\n        sameDay : '[Í dag kl.] LT',\n        nextDay : '[Í morgin kl.] LT',\n        nextWeek : 'dddd [kl.] LT',\n        lastDay : '[Í gjár kl.] LT',\n        lastWeek : '[síðstu] dddd [kl] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'um %s',\n        past : '%s síðani',\n        s : 'fá sekund',\n        m : 'ein minutt',\n        mm : '%d minuttir',\n        h : 'ein tími',\n        hh : '%d tímar',\n        d : 'ein dagur',\n        dd : '%d dagar',\n        M : 'ein mánaði',\n        MM : '%d mánaðir',\n        y : 'eitt ár',\n        yy : '%d ár'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}\\./,\n    ordinal : '%d.',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : French (Canada) [fr-ca]\n//! author : Jonathan Abourbih : https://github.com/jonbca\n\nhooks.defineLocale('fr-ca', {\n    months : 'janvier_février_mars_avril_mai_juin_juillet_août_septembre_octobre_novembre_décembre'.split('_'),\n    monthsShort : 'janv._févr._mars_avr._mai_juin_juil._août_sept._oct._nov._déc.'.split('_'),\n    monthsParseExact : true,\n    weekdays : 'dimanche_lundi_mardi_mercredi_jeudi_vendredi_samedi'.split('_'),\n    weekdaysShort : 'dim._lun._mar._mer._jeu._ven._sam.'.split('_'),\n    weekdaysMin : 'Di_Lu_Ma_Me_Je_Ve_Sa'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'YYYY-MM-DD',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY HH:mm',\n        LLLL : 'dddd D MMMM YYYY HH:mm'\n    },\n    calendar : {\n        sameDay : '[Aujourd’hui à] LT',\n        nextDay : '[Demain à] LT',\n        nextWeek : 'dddd [à] LT',\n        lastDay : '[Hier à] LT',\n        lastWeek : 'dddd [dernier à] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'dans %s',\n        past : 'il y a %s',\n        s : 'quelques secondes',\n        m : 'une minute',\n        mm : '%d minutes',\n        h : 'une heure',\n        hh : '%d heures',\n        d : 'un jour',\n        dd : '%d jours',\n        M : 'un mois',\n        MM : '%d mois',\n        y : 'un an',\n        yy : '%d ans'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}(er|e)/,\n    ordinal : function (number, period) {\n        switch (period) {\n            // Words with masculine grammatical gender: mois, trimestre, jour\n            default:\n            case 'M':\n            case 'Q':\n            case 'D':\n            case 'DDD':\n            case 'd':\n                return number + (number === 1 ? 'er' : 'e');\n\n            // Words with feminine grammatical gender: semaine\n            case 'w':\n            case 'W':\n                return number + (number === 1 ? 're' : 'e');\n        }\n    }\n});\n\n//! moment.js locale configuration\n//! locale : French (Switzerland) [fr-ch]\n//! author : Gaspard Bucher : https://github.com/gaspard\n\nhooks.defineLocale('fr-ch', {\n    months : 'janvier_février_mars_avril_mai_juin_juillet_août_septembre_octobre_novembre_décembre'.split('_'),\n    monthsShort : 'janv._févr._mars_avr._mai_juin_juil._août_sept._oct._nov._déc.'.split('_'),\n    monthsParseExact : true,\n    weekdays : 'dimanche_lundi_mardi_mercredi_jeudi_vendredi_samedi'.split('_'),\n    weekdaysShort : 'dim._lun._mar._mer._jeu._ven._sam.'.split('_'),\n    weekdaysMin : 'Di_Lu_Ma_Me_Je_Ve_Sa'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD.MM.YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY HH:mm',\n        LLLL : 'dddd D MMMM YYYY HH:mm'\n    },\n    calendar : {\n        sameDay : '[Aujourd’hui à] LT',\n        nextDay : '[Demain à] LT',\n        nextWeek : 'dddd [à] LT',\n        lastDay : '[Hier à] LT',\n        lastWeek : 'dddd [dernier à] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'dans %s',\n        past : 'il y a %s',\n        s : 'quelques secondes',\n        m : 'une minute',\n        mm : '%d minutes',\n        h : 'une heure',\n        hh : '%d heures',\n        d : 'un jour',\n        dd : '%d jours',\n        M : 'un mois',\n        MM : '%d mois',\n        y : 'un an',\n        yy : '%d ans'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}(er|e)/,\n    ordinal : function (number, period) {\n        switch (period) {\n            // Words with masculine grammatical gender: mois, trimestre, jour\n            default:\n            case 'M':\n            case 'Q':\n            case 'D':\n            case 'DDD':\n            case 'd':\n                return number + (number === 1 ? 'er' : 'e');\n\n            // Words with feminine grammatical gender: semaine\n            case 'w':\n            case 'W':\n                return number + (number === 1 ? 're' : 'e');\n        }\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : French [fr]\n//! author : John Fischer : https://github.com/jfroffice\n\nhooks.defineLocale('fr', {\n    months : 'janvier_février_mars_avril_mai_juin_juillet_août_septembre_octobre_novembre_décembre'.split('_'),\n    monthsShort : 'janv._févr._mars_avr._mai_juin_juil._août_sept._oct._nov._déc.'.split('_'),\n    monthsParseExact : true,\n    weekdays : 'dimanche_lundi_mardi_mercredi_jeudi_vendredi_samedi'.split('_'),\n    weekdaysShort : 'dim._lun._mar._mer._jeu._ven._sam.'.split('_'),\n    weekdaysMin : 'Di_Lu_Ma_Me_Je_Ve_Sa'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY HH:mm',\n        LLLL : 'dddd D MMMM YYYY HH:mm'\n    },\n    calendar : {\n        sameDay : '[Aujourd’hui à] LT',\n        nextDay : '[Demain à] LT',\n        nextWeek : 'dddd [à] LT',\n        lastDay : '[Hier à] LT',\n        lastWeek : 'dddd [dernier à] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'dans %s',\n        past : 'il y a %s',\n        s : 'quelques secondes',\n        m : 'une minute',\n        mm : '%d minutes',\n        h : 'une heure',\n        hh : '%d heures',\n        d : 'un jour',\n        dd : '%d jours',\n        M : 'un mois',\n        MM : '%d mois',\n        y : 'un an',\n        yy : '%d ans'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}(er|)/,\n    ordinal : function (number, period) {\n        switch (period) {\n            // TODO: Return 'e' when day of month > 1. Move this case inside\n            // block for masculine words below.\n            // See https://github.com/moment/moment/issues/3375\n            case 'D':\n                return number + (number === 1 ? 'er' : '');\n\n            // Words with masculine grammatical gender: mois, trimestre, jour\n            default:\n            case 'M':\n            case 'Q':\n            case 'DDD':\n            case 'd':\n                return number + (number === 1 ? 'er' : 'e');\n\n            // Words with feminine grammatical gender: semaine\n            case 'w':\n            case 'W':\n                return number + (number === 1 ? 're' : 'e');\n        }\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Frisian [fy]\n//! author : Robin van der Vliet : https://github.com/robin0van0der0v\n\nvar monthsShortWithDots = 'jan._feb._mrt._apr._mai_jun._jul._aug._sep._okt._nov._des.'.split('_');\nvar monthsShortWithoutDots = 'jan_feb_mrt_apr_mai_jun_jul_aug_sep_okt_nov_des'.split('_');\n\nhooks.defineLocale('fy', {\n    months : 'jannewaris_febrewaris_maart_april_maaie_juny_july_augustus_septimber_oktober_novimber_desimber'.split('_'),\n    monthsShort : function (m, format) {\n        if (!m) {\n            return monthsShortWithDots;\n        } else if (/-MMM-/.test(format)) {\n            return monthsShortWithoutDots[m.month()];\n        } else {\n            return monthsShortWithDots[m.month()];\n        }\n    },\n    monthsParseExact : true,\n    weekdays : 'snein_moandei_tiisdei_woansdei_tongersdei_freed_sneon'.split('_'),\n    weekdaysShort : 'si._mo._ti._wo._to._fr._so.'.split('_'),\n    weekdaysMin : 'Si_Mo_Ti_Wo_To_Fr_So'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD-MM-YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY HH:mm',\n        LLLL : 'dddd D MMMM YYYY HH:mm'\n    },\n    calendar : {\n        sameDay: '[hjoed om] LT',\n        nextDay: '[moarn om] LT',\n        nextWeek: 'dddd [om] LT',\n        lastDay: '[juster om] LT',\n        lastWeek: '[ôfrûne] dddd [om] LT',\n        sameElse: 'L'\n    },\n    relativeTime : {\n        future : 'oer %s',\n        past : '%s lyn',\n        s : 'in pear sekonden',\n        m : 'ien minút',\n        mm : '%d minuten',\n        h : 'ien oere',\n        hh : '%d oeren',\n        d : 'ien dei',\n        dd : '%d dagen',\n        M : 'ien moanne',\n        MM : '%d moannen',\n        y : 'ien jier',\n        yy : '%d jierren'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}(ste|de)/,\n    ordinal : function (number) {\n        return number + ((number === 1 || number === 8 || number >= 20) ? 'ste' : 'de');\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Scottish Gaelic [gd]\n//! author : Jon Ashdown : https://github.com/jonashdown\n\nvar months$5 = [\n    'Am Faoilleach', 'An Gearran', 'Am Màrt', 'An Giblean', 'An Cèitean', 'An t-Ògmhios', 'An t-Iuchar', 'An Lùnastal', 'An t-Sultain', 'An Dàmhair', 'An t-Samhain', 'An Dùbhlachd'\n];\n\nvar monthsShort$3 = ['Faoi', 'Gear', 'Màrt', 'Gibl', 'Cèit', 'Ògmh', 'Iuch', 'Lùn', 'Sult', 'Dàmh', 'Samh', 'Dùbh'];\n\nvar weekdays$1 = ['Didòmhnaich', 'Diluain', 'Dimàirt', 'Diciadain', 'Diardaoin', 'Dihaoine', 'Disathairne'];\n\nvar weekdaysShort = ['Did', 'Dil', 'Dim', 'Dic', 'Dia', 'Dih', 'Dis'];\n\nvar weekdaysMin = ['Dò', 'Lu', 'Mà', 'Ci', 'Ar', 'Ha', 'Sa'];\n\nhooks.defineLocale('gd', {\n    months : months$5,\n    monthsShort : monthsShort$3,\n    monthsParseExact : true,\n    weekdays : weekdays$1,\n    weekdaysShort : weekdaysShort,\n    weekdaysMin : weekdaysMin,\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY HH:mm',\n        LLLL : 'dddd, D MMMM YYYY HH:mm'\n    },\n    calendar : {\n        sameDay : '[An-diugh aig] LT',\n        nextDay : '[A-màireach aig] LT',\n        nextWeek : 'dddd [aig] LT',\n        lastDay : '[An-dè aig] LT',\n        lastWeek : 'dddd [seo chaidh] [aig] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'ann an %s',\n        past : 'bho chionn %s',\n        s : 'beagan diogan',\n        m : 'mionaid',\n        mm : '%d mionaidean',\n        h : 'uair',\n        hh : '%d uairean',\n        d : 'latha',\n        dd : '%d latha',\n        M : 'mìos',\n        MM : '%d mìosan',\n        y : 'bliadhna',\n        yy : '%d bliadhna'\n    },\n    dayOfMonthOrdinalParse : /\\d{1,2}(d|na|mh)/,\n    ordinal : function (number) {\n        var output = number === 1 ? 'd' : number % 10 === 2 ? 'na' : 'mh';\n        return number + output;\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Galician [gl]\n//! author : Juan G. Hurtado : https://github.com/juanghurtado\n\nhooks.defineLocale('gl', {\n    months : 'xaneiro_febreiro_marzo_abril_maio_xuño_xullo_agosto_setembro_outubro_novembro_decembro'.split('_'),\n    monthsShort : 'xan._feb._mar._abr._mai._xuñ._xul._ago._set._out._nov._dec.'.split('_'),\n    monthsParseExact: true,\n    weekdays : 'domingo_luns_martes_mércores_xoves_venres_sábado'.split('_'),\n    weekdaysShort : 'dom._lun._mar._mér._xov._ven._sáb.'.split('_'),\n    weekdaysMin : 'do_lu_ma_mé_xo_ve_sá'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat : {\n        LT : 'H:mm',\n        LTS : 'H:mm:ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D [de] MMMM [de] YYYY',\n        LLL : 'D [de] MMMM [de] YYYY H:mm',\n        LLLL : 'dddd, D [de] MMMM [de] YYYY H:mm'\n    },\n    calendar : {\n        sameDay : function () {\n            return '[hoxe ' + ((this.hours() !== 1) ? 'ás' : 'á') + '] LT';\n        },\n        nextDay : function () {\n            return '[mañá ' + ((this.hours() !== 1) ? 'ás' : 'á') + '] LT';\n        },\n        nextWeek : function () {\n            return 'dddd [' + ((this.hours() !== 1) ? 'ás' : 'a') + '] LT';\n        },\n        lastDay : function () {\n            return '[onte ' + ((this.hours() !== 1) ? 'á' : 'a') + '] LT';\n        },\n        lastWeek : function () {\n            return '[o] dddd [pasado ' + ((this.hours() !== 1) ? 'ás' : 'a') + '] LT';\n        },\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : function (str) {\n            if (str.indexOf('un') === 0) {\n                return 'n' + str;\n            }\n            return 'en ' + str;\n        },\n        past : 'hai %s',\n        s : 'uns segundos',\n        m : 'un minuto',\n        mm : '%d minutos',\n        h : 'unha hora',\n        hh : '%d horas',\n        d : 'un día',\n        dd : '%d días',\n        M : 'un mes',\n        MM : '%d meses',\n        y : 'un ano',\n        yy : '%d anos'\n    },\n    dayOfMonthOrdinalParse : /\\d{1,2}º/,\n    ordinal : '%dº',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Konkani Latin script [gom-latn]\n//! author : The Discoverer : https://github.com/WikiDiscoverer\n\nfunction processRelativeTime$4(number, withoutSuffix, key, isFuture) {\n    var format = {\n        's': ['thodde secondanim', 'thodde second'],\n        'm': ['eka mintan', 'ek minute'],\n        'mm': [number + ' mintanim', number + ' mintam'],\n        'h': ['eka horan', 'ek hor'],\n        'hh': [number + ' horanim', number + ' hor'],\n        'd': ['eka disan', 'ek dis'],\n        'dd': [number + ' disanim', number + ' dis'],\n        'M': ['eka mhoinean', 'ek mhoino'],\n        'MM': [number + ' mhoineanim', number + ' mhoine'],\n        'y': ['eka vorsan', 'ek voros'],\n        'yy': [number + ' vorsanim', number + ' vorsam']\n    };\n    return withoutSuffix ? format[key][0] : format[key][1];\n}\n\nhooks.defineLocale('gom-latn', {\n    months : 'Janer_Febrer_Mars_Abril_Mai_Jun_Julai_Agost_Setembr_Otubr_Novembr_Dezembr'.split('_'),\n    monthsShort : 'Jan._Feb._Mars_Abr._Mai_Jun_Jul._Ago._Set._Otu._Nov._Dez.'.split('_'),\n    monthsParseExact : true,\n    weekdays : 'Aitar_Somar_Mongllar_Budvar_Brestar_Sukrar_Son\\'var'.split('_'),\n    weekdaysShort : 'Ait._Som._Mon._Bud._Bre._Suk._Son.'.split('_'),\n    weekdaysMin : 'Ai_Sm_Mo_Bu_Br_Su_Sn'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat : {\n        LT : 'A h:mm [vazta]',\n        LTS : 'A h:mm:ss [vazta]',\n        L : 'DD-MM-YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY A h:mm [vazta]',\n        LLLL : 'dddd, MMMM[achea] Do, YYYY, A h:mm [vazta]',\n        llll: 'ddd, D MMM YYYY, A h:mm [vazta]'\n    },\n    calendar : {\n        sameDay: '[Aiz] LT',\n        nextDay: '[Faleam] LT',\n        nextWeek: '[Ieta to] dddd[,] LT',\n        lastDay: '[Kal] LT',\n        lastWeek: '[Fatlo] dddd[,] LT',\n        sameElse: 'L'\n    },\n    relativeTime : {\n        future : '%s',\n        past : '%s adim',\n        s : processRelativeTime$4,\n        m : processRelativeTime$4,\n        mm : processRelativeTime$4,\n        h : processRelativeTime$4,\n        hh : processRelativeTime$4,\n        d : processRelativeTime$4,\n        dd : processRelativeTime$4,\n        M : processRelativeTime$4,\n        MM : processRelativeTime$4,\n        y : processRelativeTime$4,\n        yy : processRelativeTime$4\n    },\n    dayOfMonthOrdinalParse : /\\d{1,2}(er)/,\n    ordinal : function (number, period) {\n        switch (period) {\n            // the ordinal 'er' only applies to day of the month\n            case 'D':\n                return number + 'er';\n            default:\n            case 'M':\n            case 'Q':\n            case 'DDD':\n            case 'd':\n            case 'w':\n            case 'W':\n                return number;\n        }\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    },\n    meridiemParse: /rati|sokalli|donparam|sanje/,\n    meridiemHour : function (hour, meridiem) {\n        if (hour === 12) {\n            hour = 0;\n        }\n        if (meridiem === 'rati') {\n            return hour < 4 ? hour : hour + 12;\n        } else if (meridiem === 'sokalli') {\n            return hour;\n        } else if (meridiem === 'donparam') {\n            return hour > 12 ? hour : hour + 12;\n        } else if (meridiem === 'sanje') {\n            return hour + 12;\n        }\n    },\n    meridiem : function (hour, minute, isLower) {\n        if (hour < 4) {\n            return 'rati';\n        } else if (hour < 12) {\n            return 'sokalli';\n        } else if (hour < 16) {\n            return 'donparam';\n        } else if (hour < 20) {\n            return 'sanje';\n        } else {\n            return 'rati';\n        }\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Hebrew [he]\n//! author : Tomer Cohen : https://github.com/tomer\n//! author : Moshe Simantov : https://github.com/DevelopmentIL\n//! author : Tal Ater : https://github.com/TalAter\n\nhooks.defineLocale('he', {\n    months : 'ינואר_פברואר_מרץ_אפריל_מאי_יוני_יולי_אוגוסט_ספטמבר_אוקטובר_נובמבר_דצמבר'.split('_'),\n    monthsShort : 'ינו׳_פבר׳_מרץ_אפר׳_מאי_יוני_יולי_אוג׳_ספט׳_אוק׳_נוב׳_דצמ׳'.split('_'),\n    weekdays : 'ראשון_שני_שלישי_רביעי_חמישי_שישי_שבת'.split('_'),\n    weekdaysShort : 'א׳_ב׳_ג׳_ד׳_ה׳_ו׳_ש׳'.split('_'),\n    weekdaysMin : 'א_ב_ג_ד_ה_ו_ש'.split('_'),\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D [ב]MMMM YYYY',\n        LLL : 'D [ב]MMMM YYYY HH:mm',\n        LLLL : 'dddd, D [ב]MMMM YYYY HH:mm',\n        l : 'D/M/YYYY',\n        ll : 'D MMM YYYY',\n        lll : 'D MMM YYYY HH:mm',\n        llll : 'ddd, D MMM YYYY HH:mm'\n    },\n    calendar : {\n        sameDay : '[היום ב־]LT',\n        nextDay : '[מחר ב־]LT',\n        nextWeek : 'dddd [בשעה] LT',\n        lastDay : '[אתמול ב־]LT',\n        lastWeek : '[ביום] dddd [האחרון בשעה] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'בעוד %s',\n        past : 'לפני %s',\n        s : 'מספר שניות',\n        m : 'דקה',\n        mm : '%d דקות',\n        h : 'שעה',\n        hh : function (number) {\n            if (number === 2) {\n                return 'שעתיים';\n            }\n            return number + ' שעות';\n        },\n        d : 'יום',\n        dd : function (number) {\n            if (number === 2) {\n                return 'יומיים';\n            }\n            return number + ' ימים';\n        },\n        M : 'חודש',\n        MM : function (number) {\n            if (number === 2) {\n                return 'חודשיים';\n            }\n            return number + ' חודשים';\n        },\n        y : 'שנה',\n        yy : function (number) {\n            if (number === 2) {\n                return 'שנתיים';\n            } else if (number % 10 === 0 && number !== 10) {\n                return number + ' שנה';\n            }\n            return number + ' שנים';\n        }\n    },\n    meridiemParse: /אחה\"צ|לפנה\"צ|אחרי הצהריים|לפני הצהריים|לפנות בוקר|בבוקר|בערב/i,\n    isPM : function (input) {\n        return /^(אחה\"צ|אחרי הצהריים|בערב)$/.test(input);\n    },\n    meridiem : function (hour, minute, isLower) {\n        if (hour < 5) {\n            return 'לפנות בוקר';\n        } else if (hour < 10) {\n            return 'בבוקר';\n        } else if (hour < 12) {\n            return isLower ? 'לפנה\"צ' : 'לפני הצהריים';\n        } else if (hour < 18) {\n            return isLower ? 'אחה\"צ' : 'אחרי הצהריים';\n        } else {\n            return 'בערב';\n        }\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Hindi [hi]\n//! author : Mayank Singhal : https://github.com/mayanksinghal\n\nvar symbolMap$6 = {\n    '1': '१',\n    '2': '२',\n    '3': '३',\n    '4': '४',\n    '5': '५',\n    '6': '६',\n    '7': '७',\n    '8': '८',\n    '9': '९',\n    '0': '०'\n};\nvar numberMap$5 = {\n    '१': '1',\n    '२': '2',\n    '३': '3',\n    '४': '4',\n    '५': '5',\n    '६': '6',\n    '७': '7',\n    '८': '8',\n    '९': '9',\n    '०': '0'\n};\n\nhooks.defineLocale('hi', {\n    months : 'जनवरी_फ़रवरी_मार्च_अप्रैल_मई_जून_जुलाई_अगस्त_सितम्बर_अक्टूबर_नवम्बर_दिसम्बर'.split('_'),\n    monthsShort : 'जन._फ़र._मार्च_अप्रै._मई_जून_जुल._अग._सित._अक्टू._नव._दिस.'.split('_'),\n    monthsParseExact: true,\n    weekdays : 'रविवार_सोमवार_मंगलवार_बुधवार_गुरूवार_शुक्रवार_शनिवार'.split('_'),\n    weekdaysShort : 'रवि_सोम_मंगल_बुध_गुरू_शुक्र_शनि'.split('_'),\n    weekdaysMin : 'र_सो_मं_बु_गु_शु_श'.split('_'),\n    longDateFormat : {\n        LT : 'A h:mm बजे',\n        LTS : 'A h:mm:ss बजे',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY, A h:mm बजे',\n        LLLL : 'dddd, D MMMM YYYY, A h:mm बजे'\n    },\n    calendar : {\n        sameDay : '[आज] LT',\n        nextDay : '[कल] LT',\n        nextWeek : 'dddd, LT',\n        lastDay : '[कल] LT',\n        lastWeek : '[पिछले] dddd, LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : '%s में',\n        past : '%s पहले',\n        s : 'कुछ ही क्षण',\n        m : 'एक मिनट',\n        mm : '%d मिनट',\n        h : 'एक घंटा',\n        hh : '%d घंटे',\n        d : 'एक दिन',\n        dd : '%d दिन',\n        M : 'एक महीने',\n        MM : '%d महीने',\n        y : 'एक वर्ष',\n        yy : '%d वर्ष'\n    },\n    preparse: function (string) {\n        return string.replace(/[१२३४५६७८९०]/g, function (match) {\n            return numberMap$5[match];\n        });\n    },\n    postformat: function (string) {\n        return string.replace(/\\d/g, function (match) {\n            return symbolMap$6[match];\n        });\n    },\n    // Hindi notation for meridiems are quite fuzzy in practice. While there exists\n    // a rigid notion of a 'Pahar' it is not used as rigidly in modern Hindi.\n    meridiemParse: /रात|सुबह|दोपहर|शाम/,\n    meridiemHour : function (hour, meridiem) {\n        if (hour === 12) {\n            hour = 0;\n        }\n        if (meridiem === 'रात') {\n            return hour < 4 ? hour : hour + 12;\n        } else if (meridiem === 'सुबह') {\n            return hour;\n        } else if (meridiem === 'दोपहर') {\n            return hour >= 10 ? hour : hour + 12;\n        } else if (meridiem === 'शाम') {\n            return hour + 12;\n        }\n    },\n    meridiem : function (hour, minute, isLower) {\n        if (hour < 4) {\n            return 'रात';\n        } else if (hour < 10) {\n            return 'सुबह';\n        } else if (hour < 17) {\n            return 'दोपहर';\n        } else if (hour < 20) {\n            return 'शाम';\n        } else {\n            return 'रात';\n        }\n    },\n    week : {\n        dow : 0, // Sunday is the first day of the week.\n        doy : 6  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Croatian [hr]\n//! author : Bojan Marković : https://github.com/bmarkovic\n\nfunction translate$3(number, withoutSuffix, key) {\n    var result = number + ' ';\n    switch (key) {\n        case 'm':\n            return withoutSuffix ? 'jedna minuta' : 'jedne minute';\n        case 'mm':\n            if (number === 1) {\n                result += 'minuta';\n            } else if (number === 2 || number === 3 || number === 4) {\n                result += 'minute';\n            } else {\n                result += 'minuta';\n            }\n            return result;\n        case 'h':\n            return withoutSuffix ? 'jedan sat' : 'jednog sata';\n        case 'hh':\n            if (number === 1) {\n                result += 'sat';\n            } else if (number === 2 || number === 3 || number === 4) {\n                result += 'sata';\n            } else {\n                result += 'sati';\n            }\n            return result;\n        case 'dd':\n            if (number === 1) {\n                result += 'dan';\n            } else {\n                result += 'dana';\n            }\n            return result;\n        case 'MM':\n            if (number === 1) {\n                result += 'mjesec';\n            } else if (number === 2 || number === 3 || number === 4) {\n                result += 'mjeseca';\n            } else {\n                result += 'mjeseci';\n            }\n            return result;\n        case 'yy':\n            if (number === 1) {\n                result += 'godina';\n            } else if (number === 2 || number === 3 || number === 4) {\n                result += 'godine';\n            } else {\n                result += 'godina';\n            }\n            return result;\n    }\n}\n\nhooks.defineLocale('hr', {\n    months : {\n        format: 'siječnja_veljače_ožujka_travnja_svibnja_lipnja_srpnja_kolovoza_rujna_listopada_studenoga_prosinca'.split('_'),\n        standalone: 'siječanj_veljača_ožujak_travanj_svibanj_lipanj_srpanj_kolovoz_rujan_listopad_studeni_prosinac'.split('_')\n    },\n    monthsShort : 'sij._velj._ožu._tra._svi._lip._srp._kol._ruj._lis._stu._pro.'.split('_'),\n    monthsParseExact: true,\n    weekdays : 'nedjelja_ponedjeljak_utorak_srijeda_četvrtak_petak_subota'.split('_'),\n    weekdaysShort : 'ned._pon._uto._sri._čet._pet._sub.'.split('_'),\n    weekdaysMin : 'ne_po_ut_sr_če_pe_su'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat : {\n        LT : 'H:mm',\n        LTS : 'H:mm:ss',\n        L : 'DD.MM.YYYY',\n        LL : 'D. MMMM YYYY',\n        LLL : 'D. MMMM YYYY H:mm',\n        LLLL : 'dddd, D. MMMM YYYY H:mm'\n    },\n    calendar : {\n        sameDay  : '[danas u] LT',\n        nextDay  : '[sutra u] LT',\n        nextWeek : function () {\n            switch (this.day()) {\n                case 0:\n                    return '[u] [nedjelju] [u] LT';\n                case 3:\n                    return '[u] [srijedu] [u] LT';\n                case 6:\n                    return '[u] [subotu] [u] LT';\n                case 1:\n                case 2:\n                case 4:\n                case 5:\n                    return '[u] dddd [u] LT';\n            }\n        },\n        lastDay  : '[jučer u] LT',\n        lastWeek : function () {\n            switch (this.day()) {\n                case 0:\n                case 3:\n                    return '[prošlu] dddd [u] LT';\n                case 6:\n                    return '[prošle] [subote] [u] LT';\n                case 1:\n                case 2:\n                case 4:\n                case 5:\n                    return '[prošli] dddd [u] LT';\n            }\n        },\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'za %s',\n        past   : 'prije %s',\n        s      : 'par sekundi',\n        m      : translate$3,\n        mm     : translate$3,\n        h      : translate$3,\n        hh     : translate$3,\n        d      : 'dan',\n        dd     : translate$3,\n        M      : 'mjesec',\n        MM     : translate$3,\n        y      : 'godinu',\n        yy     : translate$3\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}\\./,\n    ordinal : '%d.',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 7  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Hungarian [hu]\n//! author : Adam Brunner : https://github.com/adambrunner\n\nvar weekEndings = 'vasárnap hétfőn kedden szerdán csütörtökön pénteken szombaton'.split(' ');\nfunction translate$4(number, withoutSuffix, key, isFuture) {\n    var num = number,\n        suffix;\n    switch (key) {\n        case 's':\n            return (isFuture || withoutSuffix) ? 'néhány másodperc' : 'néhány másodperce';\n        case 'm':\n            return 'egy' + (isFuture || withoutSuffix ? ' perc' : ' perce');\n        case 'mm':\n            return num + (isFuture || withoutSuffix ? ' perc' : ' perce');\n        case 'h':\n            return 'egy' + (isFuture || withoutSuffix ? ' óra' : ' órája');\n        case 'hh':\n            return num + (isFuture || withoutSuffix ? ' óra' : ' órája');\n        case 'd':\n            return 'egy' + (isFuture || withoutSuffix ? ' nap' : ' napja');\n        case 'dd':\n            return num + (isFuture || withoutSuffix ? ' nap' : ' napja');\n        case 'M':\n            return 'egy' + (isFuture || withoutSuffix ? ' hónap' : ' hónapja');\n        case 'MM':\n            return num + (isFuture || withoutSuffix ? ' hónap' : ' hónapja');\n        case 'y':\n            return 'egy' + (isFuture || withoutSuffix ? ' év' : ' éve');\n        case 'yy':\n            return num + (isFuture || withoutSuffix ? ' év' : ' éve');\n    }\n    return '';\n}\nfunction week(isFuture) {\n    return (isFuture ? '' : '[múlt] ') + '[' + weekEndings[this.day()] + '] LT[-kor]';\n}\n\nhooks.defineLocale('hu', {\n    months : 'január_február_március_április_május_június_július_augusztus_szeptember_október_november_december'.split('_'),\n    monthsShort : 'jan_feb_márc_ápr_máj_jún_júl_aug_szept_okt_nov_dec'.split('_'),\n    weekdays : 'vasárnap_hétfő_kedd_szerda_csütörtök_péntek_szombat'.split('_'),\n    weekdaysShort : 'vas_hét_kedd_sze_csüt_pén_szo'.split('_'),\n    weekdaysMin : 'v_h_k_sze_cs_p_szo'.split('_'),\n    longDateFormat : {\n        LT : 'H:mm',\n        LTS : 'H:mm:ss',\n        L : 'YYYY.MM.DD.',\n        LL : 'YYYY. MMMM D.',\n        LLL : 'YYYY. MMMM D. H:mm',\n        LLLL : 'YYYY. MMMM D., dddd H:mm'\n    },\n    meridiemParse: /de|du/i,\n    isPM: function (input) {\n        return input.charAt(1).toLowerCase() === 'u';\n    },\n    meridiem : function (hours, minutes, isLower) {\n        if (hours < 12) {\n            return isLower === true ? 'de' : 'DE';\n        } else {\n            return isLower === true ? 'du' : 'DU';\n        }\n    },\n    calendar : {\n        sameDay : '[ma] LT[-kor]',\n        nextDay : '[holnap] LT[-kor]',\n        nextWeek : function () {\n            return week.call(this, true);\n        },\n        lastDay : '[tegnap] LT[-kor]',\n        lastWeek : function () {\n            return week.call(this, false);\n        },\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : '%s múlva',\n        past : '%s',\n        s : translate$4,\n        m : translate$4,\n        mm : translate$4,\n        h : translate$4,\n        hh : translate$4,\n        d : translate$4,\n        dd : translate$4,\n        M : translate$4,\n        MM : translate$4,\n        y : translate$4,\n        yy : translate$4\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}\\./,\n    ordinal : '%d.',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Armenian [hy-am]\n//! author : Armendarabyan : https://github.com/armendarabyan\n\nhooks.defineLocale('hy-am', {\n    months : {\n        format: 'հունվարի_փետրվարի_մարտի_ապրիլի_մայիսի_հունիսի_հուլիսի_օգոստոսի_սեպտեմբերի_հոկտեմբերի_նոյեմբերի_դեկտեմբերի'.split('_'),\n        standalone: 'հունվար_փետրվար_մարտ_ապրիլ_մայիս_հունիս_հուլիս_օգոստոս_սեպտեմբեր_հոկտեմբեր_նոյեմբեր_դեկտեմբեր'.split('_')\n    },\n    monthsShort : 'հնվ_փտր_մրտ_ապր_մյս_հնս_հլս_օգս_սպտ_հկտ_նմբ_դկտ'.split('_'),\n    weekdays : 'կիրակի_երկուշաբթի_երեքշաբթի_չորեքշաբթի_հինգշաբթի_ուրբաթ_շաբաթ'.split('_'),\n    weekdaysShort : 'կրկ_երկ_երք_չրք_հնգ_ուրբ_շբթ'.split('_'),\n    weekdaysMin : 'կրկ_երկ_երք_չրք_հնգ_ուրբ_շբթ'.split('_'),\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD.MM.YYYY',\n        LL : 'D MMMM YYYY թ.',\n        LLL : 'D MMMM YYYY թ., HH:mm',\n        LLLL : 'dddd, D MMMM YYYY թ., HH:mm'\n    },\n    calendar : {\n        sameDay: '[այսօր] LT',\n        nextDay: '[վաղը] LT',\n        lastDay: '[երեկ] LT',\n        nextWeek: function () {\n            return 'dddd [օրը ժամը] LT';\n        },\n        lastWeek: function () {\n            return '[անցած] dddd [օրը ժամը] LT';\n        },\n        sameElse: 'L'\n    },\n    relativeTime : {\n        future : '%s հետո',\n        past : '%s առաջ',\n        s : 'մի քանի վայրկյան',\n        m : 'րոպե',\n        mm : '%d րոպե',\n        h : 'ժամ',\n        hh : '%d ժամ',\n        d : 'օր',\n        dd : '%d օր',\n        M : 'ամիս',\n        MM : '%d ամիս',\n        y : 'տարի',\n        yy : '%d տարի'\n    },\n    meridiemParse: /գիշերվա|առավոտվա|ցերեկվա|երեկոյան/,\n    isPM: function (input) {\n        return /^(ցերեկվա|երեկոյան)$/.test(input);\n    },\n    meridiem : function (hour) {\n        if (hour < 4) {\n            return 'գիշերվա';\n        } else if (hour < 12) {\n            return 'առավոտվա';\n        } else if (hour < 17) {\n            return 'ցերեկվա';\n        } else {\n            return 'երեկոյան';\n        }\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}|\\d{1,2}-(ին|րդ)/,\n    ordinal: function (number, period) {\n        switch (period) {\n            case 'DDD':\n            case 'w':\n            case 'W':\n            case 'DDDo':\n                if (number === 1) {\n                    return number + '-ին';\n                }\n                return number + '-րդ';\n            default:\n                return number;\n        }\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 7  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Indonesian [id]\n//! author : Mohammad Satrio Utomo : https://github.com/tyok\n//! reference: http://id.wikisource.org/wiki/Pedoman_Umum_Ejaan_Bahasa_Indonesia_yang_Disempurnakan\n\nhooks.defineLocale('id', {\n    months : 'Januari_Februari_Maret_April_Mei_Juni_Juli_Agustus_September_Oktober_November_Desember'.split('_'),\n    monthsShort : 'Jan_Feb_Mar_Apr_Mei_Jun_Jul_Ags_Sep_Okt_Nov_Des'.split('_'),\n    weekdays : 'Minggu_Senin_Selasa_Rabu_Kamis_Jumat_Sabtu'.split('_'),\n    weekdaysShort : 'Min_Sen_Sel_Rab_Kam_Jum_Sab'.split('_'),\n    weekdaysMin : 'Mg_Sn_Sl_Rb_Km_Jm_Sb'.split('_'),\n    longDateFormat : {\n        LT : 'HH.mm',\n        LTS : 'HH.mm.ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY [pukul] HH.mm',\n        LLLL : 'dddd, D MMMM YYYY [pukul] HH.mm'\n    },\n    meridiemParse: /pagi|siang|sore|malam/,\n    meridiemHour : function (hour, meridiem) {\n        if (hour === 12) {\n            hour = 0;\n        }\n        if (meridiem === 'pagi') {\n            return hour;\n        } else if (meridiem === 'siang') {\n            return hour >= 11 ? hour : hour + 12;\n        } else if (meridiem === 'sore' || meridiem === 'malam') {\n            return hour + 12;\n        }\n    },\n    meridiem : function (hours, minutes, isLower) {\n        if (hours < 11) {\n            return 'pagi';\n        } else if (hours < 15) {\n            return 'siang';\n        } else if (hours < 19) {\n            return 'sore';\n        } else {\n            return 'malam';\n        }\n    },\n    calendar : {\n        sameDay : '[Hari ini pukul] LT',\n        nextDay : '[Besok pukul] LT',\n        nextWeek : 'dddd [pukul] LT',\n        lastDay : '[Kemarin pukul] LT',\n        lastWeek : 'dddd [lalu pukul] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'dalam %s',\n        past : '%s yang lalu',\n        s : 'beberapa detik',\n        m : 'semenit',\n        mm : '%d menit',\n        h : 'sejam',\n        hh : '%d jam',\n        d : 'sehari',\n        dd : '%d hari',\n        M : 'sebulan',\n        MM : '%d bulan',\n        y : 'setahun',\n        yy : '%d tahun'\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 7  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Icelandic [is]\n//! author : Hinrik Örn Sigurðsson : https://github.com/hinrik\n\nfunction plural$2(n) {\n    if (n % 100 === 11) {\n        return true;\n    } else if (n % 10 === 1) {\n        return false;\n    }\n    return true;\n}\nfunction translate$5(number, withoutSuffix, key, isFuture) {\n    var result = number + ' ';\n    switch (key) {\n        case 's':\n            return withoutSuffix || isFuture ? 'nokkrar sekúndur' : 'nokkrum sekúndum';\n        case 'm':\n            return withoutSuffix ? 'mínúta' : 'mínútu';\n        case 'mm':\n            if (plural$2(number)) {\n                return result + (withoutSuffix || isFuture ? 'mínútur' : 'mínútum');\n            } else if (withoutSuffix) {\n                return result + 'mínúta';\n            }\n            return result + 'mínútu';\n        case 'hh':\n            if (plural$2(number)) {\n                return result + (withoutSuffix || isFuture ? 'klukkustundir' : 'klukkustundum');\n            }\n            return result + 'klukkustund';\n        case 'd':\n            if (withoutSuffix) {\n                return 'dagur';\n            }\n            return isFuture ? 'dag' : 'degi';\n        case 'dd':\n            if (plural$2(number)) {\n                if (withoutSuffix) {\n                    return result + 'dagar';\n                }\n                return result + (isFuture ? 'daga' : 'dögum');\n            } else if (withoutSuffix) {\n                return result + 'dagur';\n            }\n            return result + (isFuture ? 'dag' : 'degi');\n        case 'M':\n            if (withoutSuffix) {\n                return 'mánuður';\n            }\n            return isFuture ? 'mánuð' : 'mánuði';\n        case 'MM':\n            if (plural$2(number)) {\n                if (withoutSuffix) {\n                    return result + 'mánuðir';\n                }\n                return result + (isFuture ? 'mánuði' : 'mánuðum');\n            } else if (withoutSuffix) {\n                return result + 'mánuður';\n            }\n            return result + (isFuture ? 'mánuð' : 'mánuði');\n        case 'y':\n            return withoutSuffix || isFuture ? 'ár' : 'ári';\n        case 'yy':\n            if (plural$2(number)) {\n                return result + (withoutSuffix || isFuture ? 'ár' : 'árum');\n            }\n            return result + (withoutSuffix || isFuture ? 'ár' : 'ári');\n    }\n}\n\nhooks.defineLocale('is', {\n    months : 'janúar_febrúar_mars_apríl_maí_júní_júlí_ágúst_september_október_nóvember_desember'.split('_'),\n    monthsShort : 'jan_feb_mar_apr_maí_jún_júl_ágú_sep_okt_nóv_des'.split('_'),\n    weekdays : 'sunnudagur_mánudagur_þriðjudagur_miðvikudagur_fimmtudagur_föstudagur_laugardagur'.split('_'),\n    weekdaysShort : 'sun_mán_þri_mið_fim_fös_lau'.split('_'),\n    weekdaysMin : 'Su_Má_Þr_Mi_Fi_Fö_La'.split('_'),\n    longDateFormat : {\n        LT : 'H:mm',\n        LTS : 'H:mm:ss',\n        L : 'DD.MM.YYYY',\n        LL : 'D. MMMM YYYY',\n        LLL : 'D. MMMM YYYY [kl.] H:mm',\n        LLLL : 'dddd, D. MMMM YYYY [kl.] H:mm'\n    },\n    calendar : {\n        sameDay : '[í dag kl.] LT',\n        nextDay : '[á morgun kl.] LT',\n        nextWeek : 'dddd [kl.] LT',\n        lastDay : '[í gær kl.] LT',\n        lastWeek : '[síðasta] dddd [kl.] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'eftir %s',\n        past : 'fyrir %s síðan',\n        s : translate$5,\n        m : translate$5,\n        mm : translate$5,\n        h : 'klukkustund',\n        hh : translate$5,\n        d : translate$5,\n        dd : translate$5,\n        M : translate$5,\n        MM : translate$5,\n        y : translate$5,\n        yy : translate$5\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}\\./,\n    ordinal : '%d.',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Italian [it]\n//! author : Lorenzo : https://github.com/aliem\n//! author: Mattia Larentis: https://github.com/nostalgiaz\n\nhooks.defineLocale('it', {\n    months : 'gennaio_febbraio_marzo_aprile_maggio_giugno_luglio_agosto_settembre_ottobre_novembre_dicembre'.split('_'),\n    monthsShort : 'gen_feb_mar_apr_mag_giu_lug_ago_set_ott_nov_dic'.split('_'),\n    weekdays : 'domenica_lunedì_martedì_mercoledì_giovedì_venerdì_sabato'.split('_'),\n    weekdaysShort : 'dom_lun_mar_mer_gio_ven_sab'.split('_'),\n    weekdaysMin : 'do_lu_ma_me_gi_ve_sa'.split('_'),\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY HH:mm',\n        LLLL : 'dddd, D MMMM YYYY HH:mm'\n    },\n    calendar : {\n        sameDay: '[Oggi alle] LT',\n        nextDay: '[Domani alle] LT',\n        nextWeek: 'dddd [alle] LT',\n        lastDay: '[Ieri alle] LT',\n        lastWeek: function () {\n            switch (this.day()) {\n                case 0:\n                    return '[la scorsa] dddd [alle] LT';\n                default:\n                    return '[lo scorso] dddd [alle] LT';\n            }\n        },\n        sameElse: 'L'\n    },\n    relativeTime : {\n        future : function (s) {\n            return ((/^[0-9].+$/).test(s) ? 'tra' : 'in') + ' ' + s;\n        },\n        past : '%s fa',\n        s : 'alcuni secondi',\n        m : 'un minuto',\n        mm : '%d minuti',\n        h : 'un\\'ora',\n        hh : '%d ore',\n        d : 'un giorno',\n        dd : '%d giorni',\n        M : 'un mese',\n        MM : '%d mesi',\n        y : 'un anno',\n        yy : '%d anni'\n    },\n    dayOfMonthOrdinalParse : /\\d{1,2}º/,\n    ordinal: '%dº',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Japanese [ja]\n//! author : LI Long : https://github.com/baryon\n\nhooks.defineLocale('ja', {\n    months : '1月_2月_3月_4月_5月_6月_7月_8月_9月_10月_11月_12月'.split('_'),\n    monthsShort : '1月_2月_3月_4月_5月_6月_7月_8月_9月_10月_11月_12月'.split('_'),\n    weekdays : '日曜日_月曜日_火曜日_水曜日_木曜日_金曜日_土曜日'.split('_'),\n    weekdaysShort : '日_月_火_水_木_金_土'.split('_'),\n    weekdaysMin : '日_月_火_水_木_金_土'.split('_'),\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'YYYY/MM/DD',\n        LL : 'YYYY年M月D日',\n        LLL : 'YYYY年M月D日 HH:mm',\n        LLLL : 'YYYY年M月D日 HH:mm dddd',\n        l : 'YYYY/MM/DD',\n        ll : 'YYYY年M月D日',\n        lll : 'YYYY年M月D日 HH:mm',\n        llll : 'YYYY年M月D日 HH:mm dddd'\n    },\n    meridiemParse: /午前|午後/i,\n    isPM : function (input) {\n        return input === '午後';\n    },\n    meridiem : function (hour, minute, isLower) {\n        if (hour < 12) {\n            return '午前';\n        } else {\n            return '午後';\n        }\n    },\n    calendar : {\n        sameDay : '[今日] LT',\n        nextDay : '[明日] LT',\n        nextWeek : '[来週]dddd LT',\n        lastDay : '[昨日] LT',\n        lastWeek : '[前週]dddd LT',\n        sameElse : 'L'\n    },\n    dayOfMonthOrdinalParse : /\\d{1,2}日/,\n    ordinal : function (number, period) {\n        switch (period) {\n            case 'd':\n            case 'D':\n            case 'DDD':\n                return number + '日';\n            default:\n                return number;\n        }\n    },\n    relativeTime : {\n        future : '%s後',\n        past : '%s前',\n        s : '数秒',\n        m : '1分',\n        mm : '%d分',\n        h : '1時間',\n        hh : '%d時間',\n        d : '1日',\n        dd : '%d日',\n        M : '1ヶ月',\n        MM : '%dヶ月',\n        y : '1年',\n        yy : '%d年'\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Javanese [jv]\n//! author : Rony Lantip : https://github.com/lantip\n//! reference: http://jv.wikipedia.org/wiki/Basa_Jawa\n\nhooks.defineLocale('jv', {\n    months : 'Januari_Februari_Maret_April_Mei_Juni_Juli_Agustus_September_Oktober_Nopember_Desember'.split('_'),\n    monthsShort : 'Jan_Feb_Mar_Apr_Mei_Jun_Jul_Ags_Sep_Okt_Nop_Des'.split('_'),\n    weekdays : 'Minggu_Senen_Seloso_Rebu_Kemis_Jemuwah_Septu'.split('_'),\n    weekdaysShort : 'Min_Sen_Sel_Reb_Kem_Jem_Sep'.split('_'),\n    weekdaysMin : 'Mg_Sn_Sl_Rb_Km_Jm_Sp'.split('_'),\n    longDateFormat : {\n        LT : 'HH.mm',\n        LTS : 'HH.mm.ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY [pukul] HH.mm',\n        LLLL : 'dddd, D MMMM YYYY [pukul] HH.mm'\n    },\n    meridiemParse: /enjing|siyang|sonten|ndalu/,\n    meridiemHour : function (hour, meridiem) {\n        if (hour === 12) {\n            hour = 0;\n        }\n        if (meridiem === 'enjing') {\n            return hour;\n        } else if (meridiem === 'siyang') {\n            return hour >= 11 ? hour : hour + 12;\n        } else if (meridiem === 'sonten' || meridiem === 'ndalu') {\n            return hour + 12;\n        }\n    },\n    meridiem : function (hours, minutes, isLower) {\n        if (hours < 11) {\n            return 'enjing';\n        } else if (hours < 15) {\n            return 'siyang';\n        } else if (hours < 19) {\n            return 'sonten';\n        } else {\n            return 'ndalu';\n        }\n    },\n    calendar : {\n        sameDay : '[Dinten puniko pukul] LT',\n        nextDay : '[Mbenjang pukul] LT',\n        nextWeek : 'dddd [pukul] LT',\n        lastDay : '[Kala wingi pukul] LT',\n        lastWeek : 'dddd [kepengker pukul] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'wonten ing %s',\n        past : '%s ingkang kepengker',\n        s : 'sawetawis detik',\n        m : 'setunggal menit',\n        mm : '%d menit',\n        h : 'setunggal jam',\n        hh : '%d jam',\n        d : 'sedinten',\n        dd : '%d dinten',\n        M : 'sewulan',\n        MM : '%d wulan',\n        y : 'setaun',\n        yy : '%d taun'\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 7  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Georgian [ka]\n//! author : Irakli Janiashvili : https://github.com/irakli-janiashvili\n\nhooks.defineLocale('ka', {\n    months : {\n        standalone: 'იანვარი_თებერვალი_მარტი_აპრილი_მაისი_ივნისი_ივლისი_აგვისტო_სექტემბერი_ოქტომბერი_ნოემბერი_დეკემბერი'.split('_'),\n        format: 'იანვარს_თებერვალს_მარტს_აპრილის_მაისს_ივნისს_ივლისს_აგვისტს_სექტემბერს_ოქტომბერს_ნოემბერს_დეკემბერს'.split('_')\n    },\n    monthsShort : 'იან_თებ_მარ_აპრ_მაი_ივნ_ივლ_აგვ_სექ_ოქტ_ნოე_დეკ'.split('_'),\n    weekdays : {\n        standalone: 'კვირა_ორშაბათი_სამშაბათი_ოთხშაბათი_ხუთშაბათი_პარასკევი_შაბათი'.split('_'),\n        format: 'კვირას_ორშაბათს_სამშაბათს_ოთხშაბათს_ხუთშაბათს_პარასკევს_შაბათს'.split('_'),\n        isFormat: /(წინა|შემდეგ)/\n    },\n    weekdaysShort : 'კვი_ორშ_სამ_ოთხ_ხუთ_პარ_შაბ'.split('_'),\n    weekdaysMin : 'კვ_ორ_სა_ოთ_ხუ_პა_შა'.split('_'),\n    longDateFormat : {\n        LT : 'h:mm A',\n        LTS : 'h:mm:ss A',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY h:mm A',\n        LLLL : 'dddd, D MMMM YYYY h:mm A'\n    },\n    calendar : {\n        sameDay : '[დღეს] LT[-ზე]',\n        nextDay : '[ხვალ] LT[-ზე]',\n        lastDay : '[გუშინ] LT[-ზე]',\n        nextWeek : '[შემდეგ] dddd LT[-ზე]',\n        lastWeek : '[წინა] dddd LT-ზე',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : function (s) {\n            return (/(წამი|წუთი|საათი|წელი)/).test(s) ?\n                s.replace(/ი$/, 'ში') :\n                s + 'ში';\n        },\n        past : function (s) {\n            if ((/(წამი|წუთი|საათი|დღე|თვე)/).test(s)) {\n                return s.replace(/(ი|ე)$/, 'ის უკან');\n            }\n            if ((/წელი/).test(s)) {\n                return s.replace(/წელი$/, 'წლის უკან');\n            }\n        },\n        s : 'რამდენიმე წამი',\n        m : 'წუთი',\n        mm : '%d წუთი',\n        h : 'საათი',\n        hh : '%d საათი',\n        d : 'დღე',\n        dd : '%d დღე',\n        M : 'თვე',\n        MM : '%d თვე',\n        y : 'წელი',\n        yy : '%d წელი'\n    },\n    dayOfMonthOrdinalParse: /0|1-ლი|მე-\\d{1,2}|\\d{1,2}-ე/,\n    ordinal : function (number) {\n        if (number === 0) {\n            return number;\n        }\n        if (number === 1) {\n            return number + '-ლი';\n        }\n        if ((number < 20) || (number <= 100 && (number % 20 === 0)) || (number % 100 === 0)) {\n            return 'მე-' + number;\n        }\n        return number + '-ე';\n    },\n    week : {\n        dow : 1,\n        doy : 7\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Kazakh [kk]\n//! authors : Nurlan Rakhimzhanov : https://github.com/nurlan\n\nvar suffixes$1 = {\n    0: '-ші',\n    1: '-ші',\n    2: '-ші',\n    3: '-ші',\n    4: '-ші',\n    5: '-ші',\n    6: '-шы',\n    7: '-ші',\n    8: '-ші',\n    9: '-шы',\n    10: '-шы',\n    20: '-шы',\n    30: '-шы',\n    40: '-шы',\n    50: '-ші',\n    60: '-шы',\n    70: '-ші',\n    80: '-ші',\n    90: '-шы',\n    100: '-ші'\n};\n\nhooks.defineLocale('kk', {\n    months : 'қаңтар_ақпан_наурыз_сәуір_мамыр_маусым_шілде_тамыз_қыркүйек_қазан_қараша_желтоқсан'.split('_'),\n    monthsShort : 'қаң_ақп_нау_сәу_мам_мау_шіл_там_қыр_қаз_қар_жел'.split('_'),\n    weekdays : 'жексенбі_дүйсенбі_сейсенбі_сәрсенбі_бейсенбі_жұма_сенбі'.split('_'),\n    weekdaysShort : 'жек_дүй_сей_сәр_бей_жұм_сен'.split('_'),\n    weekdaysMin : 'жк_дй_сй_ср_бй_жм_сн'.split('_'),\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD.MM.YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY HH:mm',\n        LLLL : 'dddd, D MMMM YYYY HH:mm'\n    },\n    calendar : {\n        sameDay : '[Бүгін сағат] LT',\n        nextDay : '[Ертең сағат] LT',\n        nextWeek : 'dddd [сағат] LT',\n        lastDay : '[Кеше сағат] LT',\n        lastWeek : '[Өткен аптаның] dddd [сағат] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : '%s ішінде',\n        past : '%s бұрын',\n        s : 'бірнеше секунд',\n        m : 'бір минут',\n        mm : '%d минут',\n        h : 'бір сағат',\n        hh : '%d сағат',\n        d : 'бір күн',\n        dd : '%d күн',\n        M : 'бір ай',\n        MM : '%d ай',\n        y : 'бір жыл',\n        yy : '%d жыл'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}-(ші|шы)/,\n    ordinal : function (number) {\n        var a = number % 10,\n            b = number >= 100 ? 100 : null;\n        return number + (suffixes$1[number] || suffixes$1[a] || suffixes$1[b]);\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 7  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Cambodian [km]\n//! author : Kruy Vanna : https://github.com/kruyvanna\n\nhooks.defineLocale('km', {\n    months: 'មករា_កុម្ភៈ_មីនា_មេសា_ឧសភា_មិថុនា_កក្កដា_សីហា_កញ្ញា_តុលា_វិច្ឆិកា_ធ្នូ'.split('_'),\n    monthsShort: 'មករា_កុម្ភៈ_មីនា_មេសា_ឧសភា_មិថុនា_កក្កដា_សីហា_កញ្ញា_តុលា_វិច្ឆិកា_ធ្នូ'.split('_'),\n    weekdays: 'អាទិត្យ_ច័ន្ទ_អង្គារ_ពុធ_ព្រហស្បតិ៍_សុក្រ_សៅរ៍'.split('_'),\n    weekdaysShort: 'អាទិត្យ_ច័ន្ទ_អង្គារ_ពុធ_ព្រហស្បតិ៍_សុក្រ_សៅរ៍'.split('_'),\n    weekdaysMin: 'អាទិត្យ_ច័ន្ទ_អង្គារ_ពុធ_ព្រហស្បតិ៍_សុក្រ_សៅរ៍'.split('_'),\n    longDateFormat: {\n        LT: 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L: 'DD/MM/YYYY',\n        LL: 'D MMMM YYYY',\n        LLL: 'D MMMM YYYY HH:mm',\n        LLLL: 'dddd, D MMMM YYYY HH:mm'\n    },\n    calendar: {\n        sameDay: '[ថ្ងៃនេះ ម៉ោង] LT',\n        nextDay: '[ស្អែក ម៉ោង] LT',\n        nextWeek: 'dddd [ម៉ោង] LT',\n        lastDay: '[ម្សិលមិញ ម៉ោង] LT',\n        lastWeek: 'dddd [សប្តាហ៍មុន] [ម៉ោង] LT',\n        sameElse: 'L'\n    },\n    relativeTime: {\n        future: '%sទៀត',\n        past: '%sមុន',\n        s: 'ប៉ុន្មានវិនាទី',\n        m: 'មួយនាទី',\n        mm: '%d នាទី',\n        h: 'មួយម៉ោង',\n        hh: '%d ម៉ោង',\n        d: 'មួយថ្ងៃ',\n        dd: '%d ថ្ងៃ',\n        M: 'មួយខែ',\n        MM: '%d ខែ',\n        y: 'មួយឆ្នាំ',\n        yy: '%d ឆ្នាំ'\n    },\n    week: {\n        dow: 1, // Monday is the first day of the week.\n        doy: 4 // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Kannada [kn]\n//! author : Rajeev Naik : https://github.com/rajeevnaikte\n\nvar symbolMap$7 = {\n    '1': '೧',\n    '2': '೨',\n    '3': '೩',\n    '4': '೪',\n    '5': '೫',\n    '6': '೬',\n    '7': '೭',\n    '8': '೮',\n    '9': '೯',\n    '0': '೦'\n};\nvar numberMap$6 = {\n    '೧': '1',\n    '೨': '2',\n    '೩': '3',\n    '೪': '4',\n    '೫': '5',\n    '೬': '6',\n    '೭': '7',\n    '೮': '8',\n    '೯': '9',\n    '೦': '0'\n};\n\nhooks.defineLocale('kn', {\n    months : 'ಜನವರಿ_ಫೆಬ್ರವರಿ_ಮಾರ್ಚ್_ಏಪ್ರಿಲ್_ಮೇ_ಜೂನ್_ಜುಲೈ_ಆಗಸ್ಟ್_ಸೆಪ್ಟೆಂಬರ್_ಅಕ್ಟೋಬರ್_ನವೆಂಬರ್_ಡಿಸೆಂಬರ್'.split('_'),\n    monthsShort : 'ಜನ_ಫೆಬ್ರ_ಮಾರ್ಚ್_ಏಪ್ರಿಲ್_ಮೇ_ಜೂನ್_ಜುಲೈ_ಆಗಸ್ಟ್_ಸೆಪ್ಟೆಂಬ_ಅಕ್ಟೋಬ_ನವೆಂಬ_ಡಿಸೆಂಬ'.split('_'),\n    monthsParseExact: true,\n    weekdays : 'ಭಾನುವಾರ_ಸೋಮವಾರ_ಮಂಗಳವಾರ_ಬುಧವಾರ_ಗುರುವಾರ_ಶುಕ್ರವಾರ_ಶನಿವಾರ'.split('_'),\n    weekdaysShort : 'ಭಾನು_ಸೋಮ_ಮಂಗಳ_ಬುಧ_ಗುರು_ಶುಕ್ರ_ಶನಿ'.split('_'),\n    weekdaysMin : 'ಭಾ_ಸೋ_ಮಂ_ಬು_ಗು_ಶು_ಶ'.split('_'),\n    longDateFormat : {\n        LT : 'A h:mm',\n        LTS : 'A h:mm:ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY, A h:mm',\n        LLLL : 'dddd, D MMMM YYYY, A h:mm'\n    },\n    calendar : {\n        sameDay : '[ಇಂದು] LT',\n        nextDay : '[ನಾಳೆ] LT',\n        nextWeek : 'dddd, LT',\n        lastDay : '[ನಿನ್ನೆ] LT',\n        lastWeek : '[ಕೊನೆಯ] dddd, LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : '%s ನಂತರ',\n        past : '%s ಹಿಂದೆ',\n        s : 'ಕೆಲವು ಕ್ಷಣಗಳು',\n        m : 'ಒಂದು ನಿಮಿಷ',\n        mm : '%d ನಿಮಿಷ',\n        h : 'ಒಂದು ಗಂಟೆ',\n        hh : '%d ಗಂಟೆ',\n        d : 'ಒಂದು ದಿನ',\n        dd : '%d ದಿನ',\n        M : 'ಒಂದು ತಿಂಗಳು',\n        MM : '%d ತಿಂಗಳು',\n        y : 'ಒಂದು ವರ್ಷ',\n        yy : '%d ವರ್ಷ'\n    },\n    preparse: function (string) {\n        return string.replace(/[೧೨೩೪೫೬೭೮೯೦]/g, function (match) {\n            return numberMap$6[match];\n        });\n    },\n    postformat: function (string) {\n        return string.replace(/\\d/g, function (match) {\n            return symbolMap$7[match];\n        });\n    },\n    meridiemParse: /ರಾತ್ರಿ|ಬೆಳಿಗ್ಗೆ|ಮಧ್ಯಾಹ್ನ|ಸಂಜೆ/,\n    meridiemHour : function (hour, meridiem) {\n        if (hour === 12) {\n            hour = 0;\n        }\n        if (meridiem === 'ರಾತ್ರಿ') {\n            return hour < 4 ? hour : hour + 12;\n        } else if (meridiem === 'ಬೆಳಿಗ್ಗೆ') {\n            return hour;\n        } else if (meridiem === 'ಮಧ್ಯಾಹ್ನ') {\n            return hour >= 10 ? hour : hour + 12;\n        } else if (meridiem === 'ಸಂಜೆ') {\n            return hour + 12;\n        }\n    },\n    meridiem : function (hour, minute, isLower) {\n        if (hour < 4) {\n            return 'ರಾತ್ರಿ';\n        } else if (hour < 10) {\n            return 'ಬೆಳಿಗ್ಗೆ';\n        } else if (hour < 17) {\n            return 'ಮಧ್ಯಾಹ್ನ';\n        } else if (hour < 20) {\n            return 'ಸಂಜೆ';\n        } else {\n            return 'ರಾತ್ರಿ';\n        }\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}(ನೇ)/,\n    ordinal : function (number) {\n        return number + 'ನೇ';\n    },\n    week : {\n        dow : 0, // Sunday is the first day of the week.\n        doy : 6  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Korean [ko]\n//! author : Kyungwook, Park : https://github.com/kyungw00k\n//! author : Jeeeyul Lee <jeeeyul@gmail.com>\n\nhooks.defineLocale('ko', {\n    months : '1월_2월_3월_4월_5월_6월_7월_8월_9월_10월_11월_12월'.split('_'),\n    monthsShort : '1월_2월_3월_4월_5월_6월_7월_8월_9월_10월_11월_12월'.split('_'),\n    weekdays : '일요일_월요일_화요일_수요일_목요일_금요일_토요일'.split('_'),\n    weekdaysShort : '일_월_화_수_목_금_토'.split('_'),\n    weekdaysMin : '일_월_화_수_목_금_토'.split('_'),\n    longDateFormat : {\n        LT : 'A h:mm',\n        LTS : 'A h:mm:ss',\n        L : 'YYYY.MM.DD',\n        LL : 'YYYY년 MMMM D일',\n        LLL : 'YYYY년 MMMM D일 A h:mm',\n        LLLL : 'YYYY년 MMMM D일 dddd A h:mm',\n        l : 'YYYY.MM.DD',\n        ll : 'YYYY년 MMMM D일',\n        lll : 'YYYY년 MMMM D일 A h:mm',\n        llll : 'YYYY년 MMMM D일 dddd A h:mm'\n    },\n    calendar : {\n        sameDay : '오늘 LT',\n        nextDay : '내일 LT',\n        nextWeek : 'dddd LT',\n        lastDay : '어제 LT',\n        lastWeek : '지난주 dddd LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : '%s 후',\n        past : '%s 전',\n        s : '몇 초',\n        ss : '%d초',\n        m : '1분',\n        mm : '%d분',\n        h : '한 시간',\n        hh : '%d시간',\n        d : '하루',\n        dd : '%d일',\n        M : '한 달',\n        MM : '%d달',\n        y : '일 년',\n        yy : '%d년'\n    },\n    dayOfMonthOrdinalParse : /\\d{1,2}일/,\n    ordinal : '%d일',\n    meridiemParse : /오전|오후/,\n    isPM : function (token) {\n        return token === '오후';\n    },\n    meridiem : function (hour, minute, isUpper) {\n        return hour < 12 ? '오전' : '오후';\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Kyrgyz [ky]\n//! author : Chyngyz Arystan uulu : https://github.com/chyngyz\n\n\nvar suffixes$2 = {\n    0: '-чү',\n    1: '-чи',\n    2: '-чи',\n    3: '-чү',\n    4: '-чү',\n    5: '-чи',\n    6: '-чы',\n    7: '-чи',\n    8: '-чи',\n    9: '-чу',\n    10: '-чу',\n    20: '-чы',\n    30: '-чу',\n    40: '-чы',\n    50: '-чү',\n    60: '-чы',\n    70: '-чи',\n    80: '-чи',\n    90: '-чу',\n    100: '-чү'\n};\n\nhooks.defineLocale('ky', {\n    months : 'январь_февраль_март_апрель_май_июнь_июль_август_сентябрь_октябрь_ноябрь_декабрь'.split('_'),\n    monthsShort : 'янв_фев_март_апр_май_июнь_июль_авг_сен_окт_ноя_дек'.split('_'),\n    weekdays : 'Жекшемби_Дүйшөмбү_Шейшемби_Шаршемби_Бейшемби_Жума_Ишемби'.split('_'),\n    weekdaysShort : 'Жек_Дүй_Шей_Шар_Бей_Жум_Ише'.split('_'),\n    weekdaysMin : 'Жк_Дй_Шй_Шр_Бй_Жм_Иш'.split('_'),\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD.MM.YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY HH:mm',\n        LLLL : 'dddd, D MMMM YYYY HH:mm'\n    },\n    calendar : {\n        sameDay : '[Бүгүн саат] LT',\n        nextDay : '[Эртең саат] LT',\n        nextWeek : 'dddd [саат] LT',\n        lastDay : '[Кече саат] LT',\n        lastWeek : '[Өткен аптанын] dddd [күнү] [саат] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : '%s ичинде',\n        past : '%s мурун',\n        s : 'бирнече секунд',\n        m : 'бир мүнөт',\n        mm : '%d мүнөт',\n        h : 'бир саат',\n        hh : '%d саат',\n        d : 'бир күн',\n        dd : '%d күн',\n        M : 'бир ай',\n        MM : '%d ай',\n        y : 'бир жыл',\n        yy : '%d жыл'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}-(чи|чы|чү|чу)/,\n    ordinal : function (number) {\n        var a = number % 10,\n            b = number >= 100 ? 100 : null;\n        return number + (suffixes$2[number] || suffixes$2[a] || suffixes$2[b]);\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 7  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Luxembourgish [lb]\n//! author : mweimerskirch : https://github.com/mweimerskirch\n//! author : David Raison : https://github.com/kwisatz\n\nfunction processRelativeTime$5(number, withoutSuffix, key, isFuture) {\n    var format = {\n        'm': ['eng Minutt', 'enger Minutt'],\n        'h': ['eng Stonn', 'enger Stonn'],\n        'd': ['een Dag', 'engem Dag'],\n        'M': ['ee Mount', 'engem Mount'],\n        'y': ['ee Joer', 'engem Joer']\n    };\n    return withoutSuffix ? format[key][0] : format[key][1];\n}\nfunction processFutureTime(string) {\n    var number = string.substr(0, string.indexOf(' '));\n    if (eifelerRegelAppliesToNumber(number)) {\n        return 'a ' + string;\n    }\n    return 'an ' + string;\n}\nfunction processPastTime(string) {\n    var number = string.substr(0, string.indexOf(' '));\n    if (eifelerRegelAppliesToNumber(number)) {\n        return 'viru ' + string;\n    }\n    return 'virun ' + string;\n}\n/**\n * Returns true if the word before the given number loses the '-n' ending.\n * e.g. 'an 10 Deeg' but 'a 5 Deeg'\n *\n * @param number {integer}\n * @returns {boolean}\n */\nfunction eifelerRegelAppliesToNumber(number) {\n    number = parseInt(number, 10);\n    if (isNaN(number)) {\n        return false;\n    }\n    if (number < 0) {\n        // Negative Number --> always true\n        return true;\n    } else if (number < 10) {\n        // Only 1 digit\n        if (4 <= number && number <= 7) {\n            return true;\n        }\n        return false;\n    } else if (number < 100) {\n        // 2 digits\n        var lastDigit = number % 10, firstDigit = number / 10;\n        if (lastDigit === 0) {\n            return eifelerRegelAppliesToNumber(firstDigit);\n        }\n        return eifelerRegelAppliesToNumber(lastDigit);\n    } else if (number < 10000) {\n        // 3 or 4 digits --> recursively check first digit\n        while (number >= 10) {\n            number = number / 10;\n        }\n        return eifelerRegelAppliesToNumber(number);\n    } else {\n        // Anything larger than 4 digits: recursively check first n-3 digits\n        number = number / 1000;\n        return eifelerRegelAppliesToNumber(number);\n    }\n}\n\nhooks.defineLocale('lb', {\n    months: 'Januar_Februar_Mäerz_Abrëll_Mee_Juni_Juli_August_September_Oktober_November_Dezember'.split('_'),\n    monthsShort: 'Jan._Febr._Mrz._Abr._Mee_Jun._Jul._Aug._Sept._Okt._Nov._Dez.'.split('_'),\n    monthsParseExact : true,\n    weekdays: 'Sonndeg_Méindeg_Dënschdeg_Mëttwoch_Donneschdeg_Freideg_Samschdeg'.split('_'),\n    weekdaysShort: 'So._Mé._Dë._Më._Do._Fr._Sa.'.split('_'),\n    weekdaysMin: 'So_Mé_Dë_Më_Do_Fr_Sa'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat: {\n        LT: 'H:mm [Auer]',\n        LTS: 'H:mm:ss [Auer]',\n        L: 'DD.MM.YYYY',\n        LL: 'D. MMMM YYYY',\n        LLL: 'D. MMMM YYYY H:mm [Auer]',\n        LLLL: 'dddd, D. MMMM YYYY H:mm [Auer]'\n    },\n    calendar: {\n        sameDay: '[Haut um] LT',\n        sameElse: 'L',\n        nextDay: '[Muer um] LT',\n        nextWeek: 'dddd [um] LT',\n        lastDay: '[Gëschter um] LT',\n        lastWeek: function () {\n            // Different date string for 'Dënschdeg' (Tuesday) and 'Donneschdeg' (Thursday) due to phonological rule\n            switch (this.day()) {\n                case 2:\n                case 4:\n                    return '[Leschten] dddd [um] LT';\n                default:\n                    return '[Leschte] dddd [um] LT';\n            }\n        }\n    },\n    relativeTime : {\n        future : processFutureTime,\n        past : processPastTime,\n        s : 'e puer Sekonnen',\n        m : processRelativeTime$5,\n        mm : '%d Minutten',\n        h : processRelativeTime$5,\n        hh : '%d Stonnen',\n        d : processRelativeTime$5,\n        dd : '%d Deeg',\n        M : processRelativeTime$5,\n        MM : '%d Méint',\n        y : processRelativeTime$5,\n        yy : '%d Joer'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}\\./,\n    ordinal: '%d.',\n    week: {\n        dow: 1, // Monday is the first day of the week.\n        doy: 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Lao [lo]\n//! author : Ryan Hart : https://github.com/ryanhart2\n\nhooks.defineLocale('lo', {\n    months : 'ມັງກອນ_ກຸມພາ_ມີນາ_ເມສາ_ພຶດສະພາ_ມິຖຸນາ_ກໍລະກົດ_ສິງຫາ_ກັນຍາ_ຕຸລາ_ພະຈິກ_ທັນວາ'.split('_'),\n    monthsShort : 'ມັງກອນ_ກຸມພາ_ມີນາ_ເມສາ_ພຶດສະພາ_ມິຖຸນາ_ກໍລະກົດ_ສິງຫາ_ກັນຍາ_ຕຸລາ_ພະຈິກ_ທັນວາ'.split('_'),\n    weekdays : 'ອາທິດ_ຈັນ_ອັງຄານ_ພຸດ_ພະຫັດ_ສຸກ_ເສົາ'.split('_'),\n    weekdaysShort : 'ທິດ_ຈັນ_ອັງຄານ_ພຸດ_ພະຫັດ_ສຸກ_ເສົາ'.split('_'),\n    weekdaysMin : 'ທ_ຈ_ອຄ_ພ_ພຫ_ສກ_ສ'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY HH:mm',\n        LLLL : 'ວັນdddd D MMMM YYYY HH:mm'\n    },\n    meridiemParse: /ຕອນເຊົ້າ|ຕອນແລງ/,\n    isPM: function (input) {\n        return input === 'ຕອນແລງ';\n    },\n    meridiem : function (hour, minute, isLower) {\n        if (hour < 12) {\n            return 'ຕອນເຊົ້າ';\n        } else {\n            return 'ຕອນແລງ';\n        }\n    },\n    calendar : {\n        sameDay : '[ມື້ນີ້ເວລາ] LT',\n        nextDay : '[ມື້ອື່ນເວລາ] LT',\n        nextWeek : '[ວັນ]dddd[ໜ້າເວລາ] LT',\n        lastDay : '[ມື້ວານນີ້ເວລາ] LT',\n        lastWeek : '[ວັນ]dddd[ແລ້ວນີ້ເວລາ] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'ອີກ %s',\n        past : '%sຜ່ານມາ',\n        s : 'ບໍ່ເທົ່າໃດວິນາທີ',\n        m : '1 ນາທີ',\n        mm : '%d ນາທີ',\n        h : '1 ຊົ່ວໂມງ',\n        hh : '%d ຊົ່ວໂມງ',\n        d : '1 ມື້',\n        dd : '%d ມື້',\n        M : '1 ເດືອນ',\n        MM : '%d ເດືອນ',\n        y : '1 ປີ',\n        yy : '%d ປີ'\n    },\n    dayOfMonthOrdinalParse: /(ທີ່)\\d{1,2}/,\n    ordinal : function (number) {\n        return 'ທີ່' + number;\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Lithuanian [lt]\n//! author : Mindaugas Mozūras : https://github.com/mmozuras\n\nvar units = {\n    'm' : 'minutė_minutės_minutę',\n    'mm': 'minutės_minučių_minutes',\n    'h' : 'valanda_valandos_valandą',\n    'hh': 'valandos_valandų_valandas',\n    'd' : 'diena_dienos_dieną',\n    'dd': 'dienos_dienų_dienas',\n    'M' : 'mėnuo_mėnesio_mėnesį',\n    'MM': 'mėnesiai_mėnesių_mėnesius',\n    'y' : 'metai_metų_metus',\n    'yy': 'metai_metų_metus'\n};\nfunction translateSeconds(number, withoutSuffix, key, isFuture) {\n    if (withoutSuffix) {\n        return 'kelios sekundės';\n    } else {\n        return isFuture ? 'kelių sekundžių' : 'kelias sekundes';\n    }\n}\nfunction translateSingular(number, withoutSuffix, key, isFuture) {\n    return withoutSuffix ? forms(key)[0] : (isFuture ? forms(key)[1] : forms(key)[2]);\n}\nfunction special(number) {\n    return number % 10 === 0 || (number > 10 && number < 20);\n}\nfunction forms(key) {\n    return units[key].split('_');\n}\nfunction translate$6(number, withoutSuffix, key, isFuture) {\n    var result = number + ' ';\n    if (number === 1) {\n        return result + translateSingular(number, withoutSuffix, key[0], isFuture);\n    } else if (withoutSuffix) {\n        return result + (special(number) ? forms(key)[1] : forms(key)[0]);\n    } else {\n        if (isFuture) {\n            return result + forms(key)[1];\n        } else {\n            return result + (special(number) ? forms(key)[1] : forms(key)[2]);\n        }\n    }\n}\nhooks.defineLocale('lt', {\n    months : {\n        format: 'sausio_vasario_kovo_balandžio_gegužės_birželio_liepos_rugpjūčio_rugsėjo_spalio_lapkričio_gruodžio'.split('_'),\n        standalone: 'sausis_vasaris_kovas_balandis_gegužė_birželis_liepa_rugpjūtis_rugsėjis_spalis_lapkritis_gruodis'.split('_'),\n        isFormat: /D[oD]?(\\[[^\\[\\]]*\\]|\\s)+MMMM?|MMMM?(\\[[^\\[\\]]*\\]|\\s)+D[oD]?/\n    },\n    monthsShort : 'sau_vas_kov_bal_geg_bir_lie_rgp_rgs_spa_lap_grd'.split('_'),\n    weekdays : {\n        format: 'sekmadienį_pirmadienį_antradienį_trečiadienį_ketvirtadienį_penktadienį_šeštadienį'.split('_'),\n        standalone: 'sekmadienis_pirmadienis_antradienis_trečiadienis_ketvirtadienis_penktadienis_šeštadienis'.split('_'),\n        isFormat: /dddd HH:mm/\n    },\n    weekdaysShort : 'Sek_Pir_Ant_Tre_Ket_Pen_Šeš'.split('_'),\n    weekdaysMin : 'S_P_A_T_K_Pn_Š'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'YYYY-MM-DD',\n        LL : 'YYYY [m.] MMMM D [d.]',\n        LLL : 'YYYY [m.] MMMM D [d.], HH:mm [val.]',\n        LLLL : 'YYYY [m.] MMMM D [d.], dddd, HH:mm [val.]',\n        l : 'YYYY-MM-DD',\n        ll : 'YYYY [m.] MMMM D [d.]',\n        lll : 'YYYY [m.] MMMM D [d.], HH:mm [val.]',\n        llll : 'YYYY [m.] MMMM D [d.], ddd, HH:mm [val.]'\n    },\n    calendar : {\n        sameDay : '[Šiandien] LT',\n        nextDay : '[Rytoj] LT',\n        nextWeek : 'dddd LT',\n        lastDay : '[Vakar] LT',\n        lastWeek : '[Praėjusį] dddd LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'po %s',\n        past : 'prieš %s',\n        s : translateSeconds,\n        m : translateSingular,\n        mm : translate$6,\n        h : translateSingular,\n        hh : translate$6,\n        d : translateSingular,\n        dd : translate$6,\n        M : translateSingular,\n        MM : translate$6,\n        y : translateSingular,\n        yy : translate$6\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}-oji/,\n    ordinal : function (number) {\n        return number + '-oji';\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Latvian [lv]\n//! author : Kristaps Karlsons : https://github.com/skakri\n//! author : Jānis Elmeris : https://github.com/JanisE\n\nvar units$1 = {\n    'm': 'minūtes_minūtēm_minūte_minūtes'.split('_'),\n    'mm': 'minūtes_minūtēm_minūte_minūtes'.split('_'),\n    'h': 'stundas_stundām_stunda_stundas'.split('_'),\n    'hh': 'stundas_stundām_stunda_stundas'.split('_'),\n    'd': 'dienas_dienām_diena_dienas'.split('_'),\n    'dd': 'dienas_dienām_diena_dienas'.split('_'),\n    'M': 'mēneša_mēnešiem_mēnesis_mēneši'.split('_'),\n    'MM': 'mēneša_mēnešiem_mēnesis_mēneši'.split('_'),\n    'y': 'gada_gadiem_gads_gadi'.split('_'),\n    'yy': 'gada_gadiem_gads_gadi'.split('_')\n};\n/**\n * @param withoutSuffix boolean true = a length of time; false = before/after a period of time.\n */\nfunction format$1(forms, number, withoutSuffix) {\n    if (withoutSuffix) {\n        // E.g. \"21 minūte\", \"3 minūtes\".\n        return number % 10 === 1 && number % 100 !== 11 ? forms[2] : forms[3];\n    } else {\n        // E.g. \"21 minūtes\" as in \"pēc 21 minūtes\".\n        // E.g. \"3 minūtēm\" as in \"pēc 3 minūtēm\".\n        return number % 10 === 1 && number % 100 !== 11 ? forms[0] : forms[1];\n    }\n}\nfunction relativeTimeWithPlural$1(number, withoutSuffix, key) {\n    return number + ' ' + format$1(units$1[key], number, withoutSuffix);\n}\nfunction relativeTimeWithSingular(number, withoutSuffix, key) {\n    return format$1(units$1[key], number, withoutSuffix);\n}\nfunction relativeSeconds(number, withoutSuffix) {\n    return withoutSuffix ? 'dažas sekundes' : 'dažām sekundēm';\n}\n\nhooks.defineLocale('lv', {\n    months : 'janvāris_februāris_marts_aprīlis_maijs_jūnijs_jūlijs_augusts_septembris_oktobris_novembris_decembris'.split('_'),\n    monthsShort : 'jan_feb_mar_apr_mai_jūn_jūl_aug_sep_okt_nov_dec'.split('_'),\n    weekdays : 'svētdiena_pirmdiena_otrdiena_trešdiena_ceturtdiena_piektdiena_sestdiena'.split('_'),\n    weekdaysShort : 'Sv_P_O_T_C_Pk_S'.split('_'),\n    weekdaysMin : 'Sv_P_O_T_C_Pk_S'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD.MM.YYYY.',\n        LL : 'YYYY. [gada] D. MMMM',\n        LLL : 'YYYY. [gada] D. MMMM, HH:mm',\n        LLLL : 'YYYY. [gada] D. MMMM, dddd, HH:mm'\n    },\n    calendar : {\n        sameDay : '[Šodien pulksten] LT',\n        nextDay : '[Rīt pulksten] LT',\n        nextWeek : 'dddd [pulksten] LT',\n        lastDay : '[Vakar pulksten] LT',\n        lastWeek : '[Pagājušā] dddd [pulksten] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'pēc %s',\n        past : 'pirms %s',\n        s : relativeSeconds,\n        m : relativeTimeWithSingular,\n        mm : relativeTimeWithPlural$1,\n        h : relativeTimeWithSingular,\n        hh : relativeTimeWithPlural$1,\n        d : relativeTimeWithSingular,\n        dd : relativeTimeWithPlural$1,\n        M : relativeTimeWithSingular,\n        MM : relativeTimeWithPlural$1,\n        y : relativeTimeWithSingular,\n        yy : relativeTimeWithPlural$1\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}\\./,\n    ordinal : '%d.',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Montenegrin [me]\n//! author : Miodrag Nikač <miodrag@restartit.me> : https://github.com/miodragnikac\n\nvar translator = {\n    words: { //Different grammatical cases\n        m: ['jedan minut', 'jednog minuta'],\n        mm: ['minut', 'minuta', 'minuta'],\n        h: ['jedan sat', 'jednog sata'],\n        hh: ['sat', 'sata', 'sati'],\n        dd: ['dan', 'dana', 'dana'],\n        MM: ['mjesec', 'mjeseca', 'mjeseci'],\n        yy: ['godina', 'godine', 'godina']\n    },\n    correctGrammaticalCase: function (number, wordKey) {\n        return number === 1 ? wordKey[0] : (number >= 2 && number <= 4 ? wordKey[1] : wordKey[2]);\n    },\n    translate: function (number, withoutSuffix, key) {\n        var wordKey = translator.words[key];\n        if (key.length === 1) {\n            return withoutSuffix ? wordKey[0] : wordKey[1];\n        } else {\n            return number + ' ' + translator.correctGrammaticalCase(number, wordKey);\n        }\n    }\n};\n\nhooks.defineLocale('me', {\n    months: 'januar_februar_mart_april_maj_jun_jul_avgust_septembar_oktobar_novembar_decembar'.split('_'),\n    monthsShort: 'jan._feb._mar._apr._maj_jun_jul_avg._sep._okt._nov._dec.'.split('_'),\n    monthsParseExact : true,\n    weekdays: 'nedjelja_ponedjeljak_utorak_srijeda_četvrtak_petak_subota'.split('_'),\n    weekdaysShort: 'ned._pon._uto._sri._čet._pet._sub.'.split('_'),\n    weekdaysMin: 'ne_po_ut_sr_če_pe_su'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat: {\n        LT: 'H:mm',\n        LTS : 'H:mm:ss',\n        L: 'DD.MM.YYYY',\n        LL: 'D. MMMM YYYY',\n        LLL: 'D. MMMM YYYY H:mm',\n        LLLL: 'dddd, D. MMMM YYYY H:mm'\n    },\n    calendar: {\n        sameDay: '[danas u] LT',\n        nextDay: '[sjutra u] LT',\n\n        nextWeek: function () {\n            switch (this.day()) {\n                case 0:\n                    return '[u] [nedjelju] [u] LT';\n                case 3:\n                    return '[u] [srijedu] [u] LT';\n                case 6:\n                    return '[u] [subotu] [u] LT';\n                case 1:\n                case 2:\n                case 4:\n                case 5:\n                    return '[u] dddd [u] LT';\n            }\n        },\n        lastDay  : '[juče u] LT',\n        lastWeek : function () {\n            var lastWeekDays = [\n                '[prošle] [nedjelje] [u] LT',\n                '[prošlog] [ponedjeljka] [u] LT',\n                '[prošlog] [utorka] [u] LT',\n                '[prošle] [srijede] [u] LT',\n                '[prošlog] [četvrtka] [u] LT',\n                '[prošlog] [petka] [u] LT',\n                '[prošle] [subote] [u] LT'\n            ];\n            return lastWeekDays[this.day()];\n        },\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'za %s',\n        past   : 'prije %s',\n        s      : 'nekoliko sekundi',\n        m      : translator.translate,\n        mm     : translator.translate,\n        h      : translator.translate,\n        hh     : translator.translate,\n        d      : 'dan',\n        dd     : translator.translate,\n        M      : 'mjesec',\n        MM     : translator.translate,\n        y      : 'godinu',\n        yy     : translator.translate\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}\\./,\n    ordinal : '%d.',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 7  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Maori [mi]\n//! author : John Corrigan <robbiecloset@gmail.com> : https://github.com/johnideal\n\nhooks.defineLocale('mi', {\n    months: 'Kohi-tāte_Hui-tanguru_Poutū-te-rangi_Paenga-whāwhā_Haratua_Pipiri_Hōngoingoi_Here-turi-kōkā_Mahuru_Whiringa-ā-nuku_Whiringa-ā-rangi_Hakihea'.split('_'),\n    monthsShort: 'Kohi_Hui_Pou_Pae_Hara_Pipi_Hōngoi_Here_Mahu_Whi-nu_Whi-ra_Haki'.split('_'),\n    monthsRegex: /(?:['a-z\\u0101\\u014D\\u016B]+\\-?){1,3}/i,\n    monthsStrictRegex: /(?:['a-z\\u0101\\u014D\\u016B]+\\-?){1,3}/i,\n    monthsShortRegex: /(?:['a-z\\u0101\\u014D\\u016B]+\\-?){1,3}/i,\n    monthsShortStrictRegex: /(?:['a-z\\u0101\\u014D\\u016B]+\\-?){1,2}/i,\n    weekdays: 'Rātapu_Mane_Tūrei_Wenerei_Tāite_Paraire_Hātarei'.split('_'),\n    weekdaysShort: 'Ta_Ma_Tū_We_Tāi_Pa_Hā'.split('_'),\n    weekdaysMin: 'Ta_Ma_Tū_We_Tāi_Pa_Hā'.split('_'),\n    longDateFormat: {\n        LT: 'HH:mm',\n        LTS: 'HH:mm:ss',\n        L: 'DD/MM/YYYY',\n        LL: 'D MMMM YYYY',\n        LLL: 'D MMMM YYYY [i] HH:mm',\n        LLLL: 'dddd, D MMMM YYYY [i] HH:mm'\n    },\n    calendar: {\n        sameDay: '[i teie mahana, i] LT',\n        nextDay: '[apopo i] LT',\n        nextWeek: 'dddd [i] LT',\n        lastDay: '[inanahi i] LT',\n        lastWeek: 'dddd [whakamutunga i] LT',\n        sameElse: 'L'\n    },\n    relativeTime: {\n        future: 'i roto i %s',\n        past: '%s i mua',\n        s: 'te hēkona ruarua',\n        m: 'he meneti',\n        mm: '%d meneti',\n        h: 'te haora',\n        hh: '%d haora',\n        d: 'he ra',\n        dd: '%d ra',\n        M: 'he marama',\n        MM: '%d marama',\n        y: 'he tau',\n        yy: '%d tau'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}º/,\n    ordinal: '%dº',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Macedonian [mk]\n//! author : Borislav Mickov : https://github.com/B0k0\n\nhooks.defineLocale('mk', {\n    months : 'јануари_февруари_март_април_мај_јуни_јули_август_септември_октомври_ноември_декември'.split('_'),\n    monthsShort : 'јан_фев_мар_апр_мај_јун_јул_авг_сеп_окт_ное_дек'.split('_'),\n    weekdays : 'недела_понеделник_вторник_среда_четврток_петок_сабота'.split('_'),\n    weekdaysShort : 'нед_пон_вто_сре_чет_пет_саб'.split('_'),\n    weekdaysMin : 'нe_пo_вт_ср_че_пе_сa'.split('_'),\n    longDateFormat : {\n        LT : 'H:mm',\n        LTS : 'H:mm:ss',\n        L : 'D.MM.YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY H:mm',\n        LLLL : 'dddd, D MMMM YYYY H:mm'\n    },\n    calendar : {\n        sameDay : '[Денес во] LT',\n        nextDay : '[Утре во] LT',\n        nextWeek : '[Во] dddd [во] LT',\n        lastDay : '[Вчера во] LT',\n        lastWeek : function () {\n            switch (this.day()) {\n                case 0:\n                case 3:\n                case 6:\n                    return '[Изминатата] dddd [во] LT';\n                case 1:\n                case 2:\n                case 4:\n                case 5:\n                    return '[Изминатиот] dddd [во] LT';\n            }\n        },\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'после %s',\n        past : 'пред %s',\n        s : 'неколку секунди',\n        m : 'минута',\n        mm : '%d минути',\n        h : 'час',\n        hh : '%d часа',\n        d : 'ден',\n        dd : '%d дена',\n        M : 'месец',\n        MM : '%d месеци',\n        y : 'година',\n        yy : '%d години'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}-(ев|ен|ти|ви|ри|ми)/,\n    ordinal : function (number) {\n        var lastDigit = number % 10,\n            last2Digits = number % 100;\n        if (number === 0) {\n            return number + '-ев';\n        } else if (last2Digits === 0) {\n            return number + '-ен';\n        } else if (last2Digits > 10 && last2Digits < 20) {\n            return number + '-ти';\n        } else if (lastDigit === 1) {\n            return number + '-ви';\n        } else if (lastDigit === 2) {\n            return number + '-ри';\n        } else if (lastDigit === 7 || lastDigit === 8) {\n            return number + '-ми';\n        } else {\n            return number + '-ти';\n        }\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 7  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Malayalam [ml]\n//! author : Floyd Pink : https://github.com/floydpink\n\nhooks.defineLocale('ml', {\n    months : 'ജനുവരി_ഫെബ്രുവരി_മാർച്ച്_ഏപ്രിൽ_മേയ്_ജൂൺ_ജൂലൈ_ഓഗസ്റ്റ്_സെപ്റ്റംബർ_ഒക്ടോബർ_നവംബർ_ഡിസംബർ'.split('_'),\n    monthsShort : 'ജനു._ഫെബ്രു._മാർ._ഏപ്രി._മേയ്_ജൂൺ_ജൂലൈ._ഓഗ._സെപ്റ്റ._ഒക്ടോ._നവം._ഡിസം.'.split('_'),\n    monthsParseExact : true,\n    weekdays : 'ഞായറാഴ്ച_തിങ്കളാഴ്ച_ചൊവ്വാഴ്ച_ബുധനാഴ്ച_വ്യാഴാഴ്ച_വെള്ളിയാഴ്ച_ശനിയാഴ്ച'.split('_'),\n    weekdaysShort : 'ഞായർ_തിങ്കൾ_ചൊവ്വ_ബുധൻ_വ്യാഴം_വെള്ളി_ശനി'.split('_'),\n    weekdaysMin : 'ഞാ_തി_ചൊ_ബു_വ്യാ_വെ_ശ'.split('_'),\n    longDateFormat : {\n        LT : 'A h:mm -നു',\n        LTS : 'A h:mm:ss -നു',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY, A h:mm -നു',\n        LLLL : 'dddd, D MMMM YYYY, A h:mm -നു'\n    },\n    calendar : {\n        sameDay : '[ഇന്ന്] LT',\n        nextDay : '[നാളെ] LT',\n        nextWeek : 'dddd, LT',\n        lastDay : '[ഇന്നലെ] LT',\n        lastWeek : '[കഴിഞ്ഞ] dddd, LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : '%s കഴിഞ്ഞ്',\n        past : '%s മുൻപ്',\n        s : 'അൽപ നിമിഷങ്ങൾ',\n        m : 'ഒരു മിനിറ്റ്',\n        mm : '%d മിനിറ്റ്',\n        h : 'ഒരു മണിക്കൂർ',\n        hh : '%d മണിക്കൂർ',\n        d : 'ഒരു ദിവസം',\n        dd : '%d ദിവസം',\n        M : 'ഒരു മാസം',\n        MM : '%d മാസം',\n        y : 'ഒരു വർഷം',\n        yy : '%d വർഷം'\n    },\n    meridiemParse: /രാത്രി|രാവിലെ|ഉച്ച കഴിഞ്ഞ്|വൈകുന്നേരം|രാത്രി/i,\n    meridiemHour : function (hour, meridiem) {\n        if (hour === 12) {\n            hour = 0;\n        }\n        if ((meridiem === 'രാത്രി' && hour >= 4) ||\n                meridiem === 'ഉച്ച കഴിഞ്ഞ്' ||\n                meridiem === 'വൈകുന്നേരം') {\n            return hour + 12;\n        } else {\n            return hour;\n        }\n    },\n    meridiem : function (hour, minute, isLower) {\n        if (hour < 4) {\n            return 'രാത്രി';\n        } else if (hour < 12) {\n            return 'രാവിലെ';\n        } else if (hour < 17) {\n            return 'ഉച്ച കഴിഞ്ഞ്';\n        } else if (hour < 20) {\n            return 'വൈകുന്നേരം';\n        } else {\n            return 'രാത്രി';\n        }\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Marathi [mr]\n//! author : Harshad Kale : https://github.com/kalehv\n//! author : Vivek Athalye : https://github.com/vnathalye\n\nvar symbolMap$8 = {\n    '1': '१',\n    '2': '२',\n    '3': '३',\n    '4': '४',\n    '5': '५',\n    '6': '६',\n    '7': '७',\n    '8': '८',\n    '9': '९',\n    '0': '०'\n};\nvar numberMap$7 = {\n    '१': '1',\n    '२': '2',\n    '३': '3',\n    '४': '4',\n    '५': '5',\n    '६': '6',\n    '७': '7',\n    '८': '8',\n    '९': '9',\n    '०': '0'\n};\n\nfunction relativeTimeMr(number, withoutSuffix, string, isFuture)\n{\n    var output = '';\n    if (withoutSuffix) {\n        switch (string) {\n            case 's': output = 'काही सेकंद'; break;\n            case 'm': output = 'एक मिनिट'; break;\n            case 'mm': output = '%d मिनिटे'; break;\n            case 'h': output = 'एक तास'; break;\n            case 'hh': output = '%d तास'; break;\n            case 'd': output = 'एक दिवस'; break;\n            case 'dd': output = '%d दिवस'; break;\n            case 'M': output = 'एक महिना'; break;\n            case 'MM': output = '%d महिने'; break;\n            case 'y': output = 'एक वर्ष'; break;\n            case 'yy': output = '%d वर्षे'; break;\n        }\n    }\n    else {\n        switch (string) {\n            case 's': output = 'काही सेकंदां'; break;\n            case 'm': output = 'एका मिनिटा'; break;\n            case 'mm': output = '%d मिनिटां'; break;\n            case 'h': output = 'एका तासा'; break;\n            case 'hh': output = '%d तासां'; break;\n            case 'd': output = 'एका दिवसा'; break;\n            case 'dd': output = '%d दिवसां'; break;\n            case 'M': output = 'एका महिन्या'; break;\n            case 'MM': output = '%d महिन्यां'; break;\n            case 'y': output = 'एका वर्षा'; break;\n            case 'yy': output = '%d वर्षां'; break;\n        }\n    }\n    return output.replace(/%d/i, number);\n}\n\nhooks.defineLocale('mr', {\n    months : 'जानेवारी_फेब्रुवारी_मार्च_एप्रिल_मे_जून_जुलै_ऑगस्ट_सप्टेंबर_ऑक्टोबर_नोव्हेंबर_डिसेंबर'.split('_'),\n    monthsShort: 'जाने._फेब्रु._मार्च._एप्रि._मे._जून._जुलै._ऑग._सप्टें._ऑक्टो._नोव्हें._डिसें.'.split('_'),\n    monthsParseExact : true,\n    weekdays : 'रविवार_सोमवार_मंगळवार_बुधवार_गुरूवार_शुक्रवार_शनिवार'.split('_'),\n    weekdaysShort : 'रवि_सोम_मंगळ_बुध_गुरू_शुक्र_शनि'.split('_'),\n    weekdaysMin : 'र_सो_मं_बु_गु_शु_श'.split('_'),\n    longDateFormat : {\n        LT : 'A h:mm वाजता',\n        LTS : 'A h:mm:ss वाजता',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY, A h:mm वाजता',\n        LLLL : 'dddd, D MMMM YYYY, A h:mm वाजता'\n    },\n    calendar : {\n        sameDay : '[आज] LT',\n        nextDay : '[उद्या] LT',\n        nextWeek : 'dddd, LT',\n        lastDay : '[काल] LT',\n        lastWeek: '[मागील] dddd, LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future: '%sमध्ये',\n        past: '%sपूर्वी',\n        s: relativeTimeMr,\n        m: relativeTimeMr,\n        mm: relativeTimeMr,\n        h: relativeTimeMr,\n        hh: relativeTimeMr,\n        d: relativeTimeMr,\n        dd: relativeTimeMr,\n        M: relativeTimeMr,\n        MM: relativeTimeMr,\n        y: relativeTimeMr,\n        yy: relativeTimeMr\n    },\n    preparse: function (string) {\n        return string.replace(/[१२३४५६७८९०]/g, function (match) {\n            return numberMap$7[match];\n        });\n    },\n    postformat: function (string) {\n        return string.replace(/\\d/g, function (match) {\n            return symbolMap$8[match];\n        });\n    },\n    meridiemParse: /रात्री|सकाळी|दुपारी|सायंकाळी/,\n    meridiemHour : function (hour, meridiem) {\n        if (hour === 12) {\n            hour = 0;\n        }\n        if (meridiem === 'रात्री') {\n            return hour < 4 ? hour : hour + 12;\n        } else if (meridiem === 'सकाळी') {\n            return hour;\n        } else if (meridiem === 'दुपारी') {\n            return hour >= 10 ? hour : hour + 12;\n        } else if (meridiem === 'सायंकाळी') {\n            return hour + 12;\n        }\n    },\n    meridiem: function (hour, minute, isLower) {\n        if (hour < 4) {\n            return 'रात्री';\n        } else if (hour < 10) {\n            return 'सकाळी';\n        } else if (hour < 17) {\n            return 'दुपारी';\n        } else if (hour < 20) {\n            return 'सायंकाळी';\n        } else {\n            return 'रात्री';\n        }\n    },\n    week : {\n        dow : 0, // Sunday is the first day of the week.\n        doy : 6  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Malay [ms-my]\n//! note : DEPRECATED, the correct one is [ms]\n//! author : Weldan Jamili : https://github.com/weldan\n\nhooks.defineLocale('ms-my', {\n    months : 'Januari_Februari_Mac_April_Mei_Jun_Julai_Ogos_September_Oktober_November_Disember'.split('_'),\n    monthsShort : 'Jan_Feb_Mac_Apr_Mei_Jun_Jul_Ogs_Sep_Okt_Nov_Dis'.split('_'),\n    weekdays : 'Ahad_Isnin_Selasa_Rabu_Khamis_Jumaat_Sabtu'.split('_'),\n    weekdaysShort : 'Ahd_Isn_Sel_Rab_Kha_Jum_Sab'.split('_'),\n    weekdaysMin : 'Ah_Is_Sl_Rb_Km_Jm_Sb'.split('_'),\n    longDateFormat : {\n        LT : 'HH.mm',\n        LTS : 'HH.mm.ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY [pukul] HH.mm',\n        LLLL : 'dddd, D MMMM YYYY [pukul] HH.mm'\n    },\n    meridiemParse: /pagi|tengahari|petang|malam/,\n    meridiemHour: function (hour, meridiem) {\n        if (hour === 12) {\n            hour = 0;\n        }\n        if (meridiem === 'pagi') {\n            return hour;\n        } else if (meridiem === 'tengahari') {\n            return hour >= 11 ? hour : hour + 12;\n        } else if (meridiem === 'petang' || meridiem === 'malam') {\n            return hour + 12;\n        }\n    },\n    meridiem : function (hours, minutes, isLower) {\n        if (hours < 11) {\n            return 'pagi';\n        } else if (hours < 15) {\n            return 'tengahari';\n        } else if (hours < 19) {\n            return 'petang';\n        } else {\n            return 'malam';\n        }\n    },\n    calendar : {\n        sameDay : '[Hari ini pukul] LT',\n        nextDay : '[Esok pukul] LT',\n        nextWeek : 'dddd [pukul] LT',\n        lastDay : '[Kelmarin pukul] LT',\n        lastWeek : 'dddd [lepas pukul] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'dalam %s',\n        past : '%s yang lepas',\n        s : 'beberapa saat',\n        m : 'seminit',\n        mm : '%d minit',\n        h : 'sejam',\n        hh : '%d jam',\n        d : 'sehari',\n        dd : '%d hari',\n        M : 'sebulan',\n        MM : '%d bulan',\n        y : 'setahun',\n        yy : '%d tahun'\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 7  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Malay [ms]\n//! author : Weldan Jamili : https://github.com/weldan\n\nhooks.defineLocale('ms', {\n    months : 'Januari_Februari_Mac_April_Mei_Jun_Julai_Ogos_September_Oktober_November_Disember'.split('_'),\n    monthsShort : 'Jan_Feb_Mac_Apr_Mei_Jun_Jul_Ogs_Sep_Okt_Nov_Dis'.split('_'),\n    weekdays : 'Ahad_Isnin_Selasa_Rabu_Khamis_Jumaat_Sabtu'.split('_'),\n    weekdaysShort : 'Ahd_Isn_Sel_Rab_Kha_Jum_Sab'.split('_'),\n    weekdaysMin : 'Ah_Is_Sl_Rb_Km_Jm_Sb'.split('_'),\n    longDateFormat : {\n        LT : 'HH.mm',\n        LTS : 'HH.mm.ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY [pukul] HH.mm',\n        LLLL : 'dddd, D MMMM YYYY [pukul] HH.mm'\n    },\n    meridiemParse: /pagi|tengahari|petang|malam/,\n    meridiemHour: function (hour, meridiem) {\n        if (hour === 12) {\n            hour = 0;\n        }\n        if (meridiem === 'pagi') {\n            return hour;\n        } else if (meridiem === 'tengahari') {\n            return hour >= 11 ? hour : hour + 12;\n        } else if (meridiem === 'petang' || meridiem === 'malam') {\n            return hour + 12;\n        }\n    },\n    meridiem : function (hours, minutes, isLower) {\n        if (hours < 11) {\n            return 'pagi';\n        } else if (hours < 15) {\n            return 'tengahari';\n        } else if (hours < 19) {\n            return 'petang';\n        } else {\n            return 'malam';\n        }\n    },\n    calendar : {\n        sameDay : '[Hari ini pukul] LT',\n        nextDay : '[Esok pukul] LT',\n        nextWeek : 'dddd [pukul] LT',\n        lastDay : '[Kelmarin pukul] LT',\n        lastWeek : 'dddd [lepas pukul] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'dalam %s',\n        past : '%s yang lepas',\n        s : 'beberapa saat',\n        m : 'seminit',\n        mm : '%d minit',\n        h : 'sejam',\n        hh : '%d jam',\n        d : 'sehari',\n        dd : '%d hari',\n        M : 'sebulan',\n        MM : '%d bulan',\n        y : 'setahun',\n        yy : '%d tahun'\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 7  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Burmese [my]\n//! author : Squar team, mysquar.com\n//! author : David Rossellat : https://github.com/gholadr\n//! author : Tin Aung Lin : https://github.com/thanyawzinmin\n\nvar symbolMap$9 = {\n    '1': '၁',\n    '2': '၂',\n    '3': '၃',\n    '4': '၄',\n    '5': '၅',\n    '6': '၆',\n    '7': '၇',\n    '8': '၈',\n    '9': '၉',\n    '0': '၀'\n};\nvar numberMap$8 = {\n    '၁': '1',\n    '၂': '2',\n    '၃': '3',\n    '၄': '4',\n    '၅': '5',\n    '၆': '6',\n    '၇': '7',\n    '၈': '8',\n    '၉': '9',\n    '၀': '0'\n};\n\nhooks.defineLocale('my', {\n    months: 'ဇန်နဝါရီ_ဖေဖော်ဝါရီ_မတ်_ဧပြီ_မေ_ဇွန်_ဇူလိုင်_သြဂုတ်_စက်တင်ဘာ_အောက်တိုဘာ_နိုဝင်ဘာ_ဒီဇင်ဘာ'.split('_'),\n    monthsShort: 'ဇန်_ဖေ_မတ်_ပြီ_မေ_ဇွန်_လိုင်_သြ_စက်_အောက်_နို_ဒီ'.split('_'),\n    weekdays: 'တနင်္ဂနွေ_တနင်္လာ_အင်္ဂါ_ဗုဒ္ဓဟူး_ကြာသပတေး_သောကြာ_စနေ'.split('_'),\n    weekdaysShort: 'နွေ_လာ_ဂါ_ဟူး_ကြာ_သော_နေ'.split('_'),\n    weekdaysMin: 'နွေ_လာ_ဂါ_ဟူး_ကြာ_သော_နေ'.split('_'),\n\n    longDateFormat: {\n        LT: 'HH:mm',\n        LTS: 'HH:mm:ss',\n        L: 'DD/MM/YYYY',\n        LL: 'D MMMM YYYY',\n        LLL: 'D MMMM YYYY HH:mm',\n        LLLL: 'dddd D MMMM YYYY HH:mm'\n    },\n    calendar: {\n        sameDay: '[ယနေ.] LT [မှာ]',\n        nextDay: '[မနက်ဖြန်] LT [မှာ]',\n        nextWeek: 'dddd LT [မှာ]',\n        lastDay: '[မနေ.က] LT [မှာ]',\n        lastWeek: '[ပြီးခဲ့သော] dddd LT [မှာ]',\n        sameElse: 'L'\n    },\n    relativeTime: {\n        future: 'လာမည့် %s မှာ',\n        past: 'လွန်ခဲ့သော %s က',\n        s: 'စက္ကန်.အနည်းငယ်',\n        m: 'တစ်မိနစ်',\n        mm: '%d မိနစ်',\n        h: 'တစ်နာရီ',\n        hh: '%d နာရီ',\n        d: 'တစ်ရက်',\n        dd: '%d ရက်',\n        M: 'တစ်လ',\n        MM: '%d လ',\n        y: 'တစ်နှစ်',\n        yy: '%d နှစ်'\n    },\n    preparse: function (string) {\n        return string.replace(/[၁၂၃၄၅၆၇၈၉၀]/g, function (match) {\n            return numberMap$8[match];\n        });\n    },\n    postformat: function (string) {\n        return string.replace(/\\d/g, function (match) {\n            return symbolMap$9[match];\n        });\n    },\n    week: {\n        dow: 1, // Monday is the first day of the week.\n        doy: 4 // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Norwegian Bokmål [nb]\n//! authors : Espen Hovlandsdal : https://github.com/rexxars\n//!           Sigurd Gartmann : https://github.com/sigurdga\n\nhooks.defineLocale('nb', {\n    months : 'januar_februar_mars_april_mai_juni_juli_august_september_oktober_november_desember'.split('_'),\n    monthsShort : 'jan._feb._mars_april_mai_juni_juli_aug._sep._okt._nov._des.'.split('_'),\n    monthsParseExact : true,\n    weekdays : 'søndag_mandag_tirsdag_onsdag_torsdag_fredag_lørdag'.split('_'),\n    weekdaysShort : 'sø._ma._ti._on._to._fr._lø.'.split('_'),\n    weekdaysMin : 'sø_ma_ti_on_to_fr_lø'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD.MM.YYYY',\n        LL : 'D. MMMM YYYY',\n        LLL : 'D. MMMM YYYY [kl.] HH:mm',\n        LLLL : 'dddd D. MMMM YYYY [kl.] HH:mm'\n    },\n    calendar : {\n        sameDay: '[i dag kl.] LT',\n        nextDay: '[i morgen kl.] LT',\n        nextWeek: 'dddd [kl.] LT',\n        lastDay: '[i går kl.] LT',\n        lastWeek: '[forrige] dddd [kl.] LT',\n        sameElse: 'L'\n    },\n    relativeTime : {\n        future : 'om %s',\n        past : '%s siden',\n        s : 'noen sekunder',\n        m : 'ett minutt',\n        mm : '%d minutter',\n        h : 'en time',\n        hh : '%d timer',\n        d : 'en dag',\n        dd : '%d dager',\n        M : 'en måned',\n        MM : '%d måneder',\n        y : 'ett år',\n        yy : '%d år'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}\\./,\n    ordinal : '%d.',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Nepalese [ne]\n//! author : suvash : https://github.com/suvash\n\nvar symbolMap$10 = {\n    '1': '१',\n    '2': '२',\n    '3': '३',\n    '4': '४',\n    '5': '५',\n    '6': '६',\n    '7': '७',\n    '8': '८',\n    '9': '९',\n    '0': '०'\n};\nvar numberMap$9 = {\n    '१': '1',\n    '२': '2',\n    '३': '3',\n    '४': '4',\n    '५': '5',\n    '६': '6',\n    '७': '7',\n    '८': '8',\n    '९': '9',\n    '०': '0'\n};\n\nhooks.defineLocale('ne', {\n    months : 'जनवरी_फेब्रुवरी_मार्च_अप्रिल_मई_जुन_जुलाई_अगष्ट_सेप्टेम्बर_अक्टोबर_नोभेम्बर_डिसेम्बर'.split('_'),\n    monthsShort : 'जन._फेब्रु._मार्च_अप्रि._मई_जुन_जुलाई._अग._सेप्ट._अक्टो._नोभे._डिसे.'.split('_'),\n    monthsParseExact : true,\n    weekdays : 'आइतबार_सोमबार_मङ्गलबार_बुधबार_बिहिबार_शुक्रबार_शनिबार'.split('_'),\n    weekdaysShort : 'आइत._सोम._मङ्गल._बुध._बिहि._शुक्र._शनि.'.split('_'),\n    weekdaysMin : 'आ._सो._मं._बु._बि._शु._श.'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat : {\n        LT : 'Aको h:mm बजे',\n        LTS : 'Aको h:mm:ss बजे',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY, Aको h:mm बजे',\n        LLLL : 'dddd, D MMMM YYYY, Aको h:mm बजे'\n    },\n    preparse: function (string) {\n        return string.replace(/[१२३४५६७८९०]/g, function (match) {\n            return numberMap$9[match];\n        });\n    },\n    postformat: function (string) {\n        return string.replace(/\\d/g, function (match) {\n            return symbolMap$10[match];\n        });\n    },\n    meridiemParse: /राति|बिहान|दिउँसो|साँझ/,\n    meridiemHour : function (hour, meridiem) {\n        if (hour === 12) {\n            hour = 0;\n        }\n        if (meridiem === 'राति') {\n            return hour < 4 ? hour : hour + 12;\n        } else if (meridiem === 'बिहान') {\n            return hour;\n        } else if (meridiem === 'दिउँसो') {\n            return hour >= 10 ? hour : hour + 12;\n        } else if (meridiem === 'साँझ') {\n            return hour + 12;\n        }\n    },\n    meridiem : function (hour, minute, isLower) {\n        if (hour < 3) {\n            return 'राति';\n        } else if (hour < 12) {\n            return 'बिहान';\n        } else if (hour < 16) {\n            return 'दिउँसो';\n        } else if (hour < 20) {\n            return 'साँझ';\n        } else {\n            return 'राति';\n        }\n    },\n    calendar : {\n        sameDay : '[आज] LT',\n        nextDay : '[भोलि] LT',\n        nextWeek : '[आउँदो] dddd[,] LT',\n        lastDay : '[हिजो] LT',\n        lastWeek : '[गएको] dddd[,] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : '%sमा',\n        past : '%s अगाडि',\n        s : 'केही क्षण',\n        m : 'एक मिनेट',\n        mm : '%d मिनेट',\n        h : 'एक घण्टा',\n        hh : '%d घण्टा',\n        d : 'एक दिन',\n        dd : '%d दिन',\n        M : 'एक महिना',\n        MM : '%d महिना',\n        y : 'एक बर्ष',\n        yy : '%d बर्ष'\n    },\n    week : {\n        dow : 0, // Sunday is the first day of the week.\n        doy : 6  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Dutch (Belgium) [nl-be]\n//! author : Joris Röling : https://github.com/jorisroling\n//! author : Jacob Middag : https://github.com/middagj\n\nvar monthsShortWithDots$1 = 'jan._feb._mrt._apr._mei_jun._jul._aug._sep._okt._nov._dec.'.split('_');\nvar monthsShortWithoutDots$1 = 'jan_feb_mrt_apr_mei_jun_jul_aug_sep_okt_nov_dec'.split('_');\n\nvar monthsParse = [/^jan/i, /^feb/i, /^maart|mrt.?$/i, /^apr/i, /^mei$/i, /^jun[i.]?$/i, /^jul[i.]?$/i, /^aug/i, /^sep/i, /^okt/i, /^nov/i, /^dec/i];\nvar monthsRegex$1 = /^(januari|februari|maart|april|mei|april|ju[nl]i|augustus|september|oktober|november|december|jan\\.?|feb\\.?|mrt\\.?|apr\\.?|ju[nl]\\.?|aug\\.?|sep\\.?|okt\\.?|nov\\.?|dec\\.?)/i;\n\nhooks.defineLocale('nl-be', {\n    months : 'januari_februari_maart_april_mei_juni_juli_augustus_september_oktober_november_december'.split('_'),\n    monthsShort : function (m, format) {\n        if (!m) {\n            return monthsShortWithDots$1;\n        } else if (/-MMM-/.test(format)) {\n            return monthsShortWithoutDots$1[m.month()];\n        } else {\n            return monthsShortWithDots$1[m.month()];\n        }\n    },\n\n    monthsRegex: monthsRegex$1,\n    monthsShortRegex: monthsRegex$1,\n    monthsStrictRegex: /^(januari|februari|maart|mei|ju[nl]i|april|augustus|september|oktober|november|december)/i,\n    monthsShortStrictRegex: /^(jan\\.?|feb\\.?|mrt\\.?|apr\\.?|mei|ju[nl]\\.?|aug\\.?|sep\\.?|okt\\.?|nov\\.?|dec\\.?)/i,\n\n    monthsParse : monthsParse,\n    longMonthsParse : monthsParse,\n    shortMonthsParse : monthsParse,\n\n    weekdays : 'zondag_maandag_dinsdag_woensdag_donderdag_vrijdag_zaterdag'.split('_'),\n    weekdaysShort : 'zo._ma._di._wo._do._vr._za.'.split('_'),\n    weekdaysMin : 'Zo_Ma_Di_Wo_Do_Vr_Za'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY HH:mm',\n        LLLL : 'dddd D MMMM YYYY HH:mm'\n    },\n    calendar : {\n        sameDay: '[vandaag om] LT',\n        nextDay: '[morgen om] LT',\n        nextWeek: 'dddd [om] LT',\n        lastDay: '[gisteren om] LT',\n        lastWeek: '[afgelopen] dddd [om] LT',\n        sameElse: 'L'\n    },\n    relativeTime : {\n        future : 'over %s',\n        past : '%s geleden',\n        s : 'een paar seconden',\n        m : 'één minuut',\n        mm : '%d minuten',\n        h : 'één uur',\n        hh : '%d uur',\n        d : 'één dag',\n        dd : '%d dagen',\n        M : 'één maand',\n        MM : '%d maanden',\n        y : 'één jaar',\n        yy : '%d jaar'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}(ste|de)/,\n    ordinal : function (number) {\n        return number + ((number === 1 || number === 8 || number >= 20) ? 'ste' : 'de');\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Dutch [nl]\n//! author : Joris Röling : https://github.com/jorisroling\n//! author : Jacob Middag : https://github.com/middagj\n\nvar monthsShortWithDots$2 = 'jan._feb._mrt._apr._mei_jun._jul._aug._sep._okt._nov._dec.'.split('_');\nvar monthsShortWithoutDots$2 = 'jan_feb_mrt_apr_mei_jun_jul_aug_sep_okt_nov_dec'.split('_');\n\nvar monthsParse$1 = [/^jan/i, /^feb/i, /^maart|mrt.?$/i, /^apr/i, /^mei$/i, /^jun[i.]?$/i, /^jul[i.]?$/i, /^aug/i, /^sep/i, /^okt/i, /^nov/i, /^dec/i];\nvar monthsRegex$2 = /^(januari|februari|maart|april|mei|april|ju[nl]i|augustus|september|oktober|november|december|jan\\.?|feb\\.?|mrt\\.?|apr\\.?|ju[nl]\\.?|aug\\.?|sep\\.?|okt\\.?|nov\\.?|dec\\.?)/i;\n\nhooks.defineLocale('nl', {\n    months : 'januari_februari_maart_april_mei_juni_juli_augustus_september_oktober_november_december'.split('_'),\n    monthsShort : function (m, format) {\n        if (!m) {\n            return monthsShortWithDots$2;\n        } else if (/-MMM-/.test(format)) {\n            return monthsShortWithoutDots$2[m.month()];\n        } else {\n            return monthsShortWithDots$2[m.month()];\n        }\n    },\n\n    monthsRegex: monthsRegex$2,\n    monthsShortRegex: monthsRegex$2,\n    monthsStrictRegex: /^(januari|februari|maart|mei|ju[nl]i|april|augustus|september|oktober|november|december)/i,\n    monthsShortStrictRegex: /^(jan\\.?|feb\\.?|mrt\\.?|apr\\.?|mei|ju[nl]\\.?|aug\\.?|sep\\.?|okt\\.?|nov\\.?|dec\\.?)/i,\n\n    monthsParse : monthsParse$1,\n    longMonthsParse : monthsParse$1,\n    shortMonthsParse : monthsParse$1,\n\n    weekdays : 'zondag_maandag_dinsdag_woensdag_donderdag_vrijdag_zaterdag'.split('_'),\n    weekdaysShort : 'zo._ma._di._wo._do._vr._za.'.split('_'),\n    weekdaysMin : 'Zo_Ma_Di_Wo_Do_Vr_Za'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD-MM-YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY HH:mm',\n        LLLL : 'dddd D MMMM YYYY HH:mm'\n    },\n    calendar : {\n        sameDay: '[vandaag om] LT',\n        nextDay: '[morgen om] LT',\n        nextWeek: 'dddd [om] LT',\n        lastDay: '[gisteren om] LT',\n        lastWeek: '[afgelopen] dddd [om] LT',\n        sameElse: 'L'\n    },\n    relativeTime : {\n        future : 'over %s',\n        past : '%s geleden',\n        s : 'een paar seconden',\n        m : 'één minuut',\n        mm : '%d minuten',\n        h : 'één uur',\n        hh : '%d uur',\n        d : 'één dag',\n        dd : '%d dagen',\n        M : 'één maand',\n        MM : '%d maanden',\n        y : 'één jaar',\n        yy : '%d jaar'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}(ste|de)/,\n    ordinal : function (number) {\n        return number + ((number === 1 || number === 8 || number >= 20) ? 'ste' : 'de');\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Nynorsk [nn]\n//! author : https://github.com/mechuwind\n\nhooks.defineLocale('nn', {\n    months : 'januar_februar_mars_april_mai_juni_juli_august_september_oktober_november_desember'.split('_'),\n    monthsShort : 'jan_feb_mar_apr_mai_jun_jul_aug_sep_okt_nov_des'.split('_'),\n    weekdays : 'sundag_måndag_tysdag_onsdag_torsdag_fredag_laurdag'.split('_'),\n    weekdaysShort : 'sun_mån_tys_ons_tor_fre_lau'.split('_'),\n    weekdaysMin : 'su_må_ty_on_to_fr_lø'.split('_'),\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD.MM.YYYY',\n        LL : 'D. MMMM YYYY',\n        LLL : 'D. MMMM YYYY [kl.] H:mm',\n        LLLL : 'dddd D. MMMM YYYY [kl.] HH:mm'\n    },\n    calendar : {\n        sameDay: '[I dag klokka] LT',\n        nextDay: '[I morgon klokka] LT',\n        nextWeek: 'dddd [klokka] LT',\n        lastDay: '[I går klokka] LT',\n        lastWeek: '[Føregåande] dddd [klokka] LT',\n        sameElse: 'L'\n    },\n    relativeTime : {\n        future : 'om %s',\n        past : '%s sidan',\n        s : 'nokre sekund',\n        m : 'eit minutt',\n        mm : '%d minutt',\n        h : 'ein time',\n        hh : '%d timar',\n        d : 'ein dag',\n        dd : '%d dagar',\n        M : 'ein månad',\n        MM : '%d månader',\n        y : 'eit år',\n        yy : '%d år'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}\\./,\n    ordinal : '%d.',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Punjabi (India) [pa-in]\n//! author : Harpreet Singh : https://github.com/harpreetkhalsagtbit\n\nvar symbolMap$11 = {\n    '1': '੧',\n    '2': '੨',\n    '3': '੩',\n    '4': '੪',\n    '5': '੫',\n    '6': '੬',\n    '7': '੭',\n    '8': '੮',\n    '9': '੯',\n    '0': '੦'\n};\nvar numberMap$10 = {\n    '੧': '1',\n    '੨': '2',\n    '੩': '3',\n    '੪': '4',\n    '੫': '5',\n    '੬': '6',\n    '੭': '7',\n    '੮': '8',\n    '੯': '9',\n    '੦': '0'\n};\n\nhooks.defineLocale('pa-in', {\n    // There are months name as per Nanakshahi Calender but they are not used as rigidly in modern Punjabi.\n    months : 'ਜਨਵਰੀ_ਫ਼ਰਵਰੀ_ਮਾਰਚ_ਅਪ੍ਰੈਲ_ਮਈ_ਜੂਨ_ਜੁਲਾਈ_ਅਗਸਤ_ਸਤੰਬਰ_ਅਕਤੂਬਰ_ਨਵੰਬਰ_ਦਸੰਬਰ'.split('_'),\n    monthsShort : 'ਜਨਵਰੀ_ਫ਼ਰਵਰੀ_ਮਾਰਚ_ਅਪ੍ਰੈਲ_ਮਈ_ਜੂਨ_ਜੁਲਾਈ_ਅਗਸਤ_ਸਤੰਬਰ_ਅਕਤੂਬਰ_ਨਵੰਬਰ_ਦਸੰਬਰ'.split('_'),\n    weekdays : 'ਐਤਵਾਰ_ਸੋਮਵਾਰ_ਮੰਗਲਵਾਰ_ਬੁਧਵਾਰ_ਵੀਰਵਾਰ_ਸ਼ੁੱਕਰਵਾਰ_ਸ਼ਨੀਚਰਵਾਰ'.split('_'),\n    weekdaysShort : 'ਐਤ_ਸੋਮ_ਮੰਗਲ_ਬੁਧ_ਵੀਰ_ਸ਼ੁਕਰ_ਸ਼ਨੀ'.split('_'),\n    weekdaysMin : 'ਐਤ_ਸੋਮ_ਮੰਗਲ_ਬੁਧ_ਵੀਰ_ਸ਼ੁਕਰ_ਸ਼ਨੀ'.split('_'),\n    longDateFormat : {\n        LT : 'A h:mm ਵਜੇ',\n        LTS : 'A h:mm:ss ਵਜੇ',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY, A h:mm ਵਜੇ',\n        LLLL : 'dddd, D MMMM YYYY, A h:mm ਵਜੇ'\n    },\n    calendar : {\n        sameDay : '[ਅਜ] LT',\n        nextDay : '[ਕਲ] LT',\n        nextWeek : 'dddd, LT',\n        lastDay : '[ਕਲ] LT',\n        lastWeek : '[ਪਿਛਲੇ] dddd, LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : '%s ਵਿੱਚ',\n        past : '%s ਪਿਛਲੇ',\n        s : 'ਕੁਝ ਸਕਿੰਟ',\n        m : 'ਇਕ ਮਿੰਟ',\n        mm : '%d ਮਿੰਟ',\n        h : 'ਇੱਕ ਘੰਟਾ',\n        hh : '%d ਘੰਟੇ',\n        d : 'ਇੱਕ ਦਿਨ',\n        dd : '%d ਦਿਨ',\n        M : 'ਇੱਕ ਮਹੀਨਾ',\n        MM : '%d ਮਹੀਨੇ',\n        y : 'ਇੱਕ ਸਾਲ',\n        yy : '%d ਸਾਲ'\n    },\n    preparse: function (string) {\n        return string.replace(/[੧੨੩੪੫੬੭੮੯੦]/g, function (match) {\n            return numberMap$10[match];\n        });\n    },\n    postformat: function (string) {\n        return string.replace(/\\d/g, function (match) {\n            return symbolMap$11[match];\n        });\n    },\n    // Punjabi notation for meridiems are quite fuzzy in practice. While there exists\n    // a rigid notion of a 'Pahar' it is not used as rigidly in modern Punjabi.\n    meridiemParse: /ਰਾਤ|ਸਵੇਰ|ਦੁਪਹਿਰ|ਸ਼ਾਮ/,\n    meridiemHour : function (hour, meridiem) {\n        if (hour === 12) {\n            hour = 0;\n        }\n        if (meridiem === 'ਰਾਤ') {\n            return hour < 4 ? hour : hour + 12;\n        } else if (meridiem === 'ਸਵੇਰ') {\n            return hour;\n        } else if (meridiem === 'ਦੁਪਹਿਰ') {\n            return hour >= 10 ? hour : hour + 12;\n        } else if (meridiem === 'ਸ਼ਾਮ') {\n            return hour + 12;\n        }\n    },\n    meridiem : function (hour, minute, isLower) {\n        if (hour < 4) {\n            return 'ਰਾਤ';\n        } else if (hour < 10) {\n            return 'ਸਵੇਰ';\n        } else if (hour < 17) {\n            return 'ਦੁਪਹਿਰ';\n        } else if (hour < 20) {\n            return 'ਸ਼ਾਮ';\n        } else {\n            return 'ਰਾਤ';\n        }\n    },\n    week : {\n        dow : 0, // Sunday is the first day of the week.\n        doy : 6  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Polish [pl]\n//! author : Rafal Hirsz : https://github.com/evoL\n\nvar monthsNominative = 'styczeń_luty_marzec_kwiecień_maj_czerwiec_lipiec_sierpień_wrzesień_październik_listopad_grudzień'.split('_');\nvar monthsSubjective = 'stycznia_lutego_marca_kwietnia_maja_czerwca_lipca_sierpnia_września_października_listopada_grudnia'.split('_');\nfunction plural$3(n) {\n    return (n % 10 < 5) && (n % 10 > 1) && ((~~(n / 10) % 10) !== 1);\n}\nfunction translate$7(number, withoutSuffix, key) {\n    var result = number + ' ';\n    switch (key) {\n        case 'm':\n            return withoutSuffix ? 'minuta' : 'minutę';\n        case 'mm':\n            return result + (plural$3(number) ? 'minuty' : 'minut');\n        case 'h':\n            return withoutSuffix  ? 'godzina'  : 'godzinę';\n        case 'hh':\n            return result + (plural$3(number) ? 'godziny' : 'godzin');\n        case 'MM':\n            return result + (plural$3(number) ? 'miesiące' : 'miesięcy');\n        case 'yy':\n            return result + (plural$3(number) ? 'lata' : 'lat');\n    }\n}\n\nhooks.defineLocale('pl', {\n    months : function (momentToFormat, format) {\n        if (!momentToFormat) {\n            return monthsNominative;\n        } else if (format === '') {\n            // Hack: if format empty we know this is used to generate\n            // RegExp by moment. Give then back both valid forms of months\n            // in RegExp ready format.\n            return '(' + monthsSubjective[momentToFormat.month()] + '|' + monthsNominative[momentToFormat.month()] + ')';\n        } else if (/D MMMM/.test(format)) {\n            return monthsSubjective[momentToFormat.month()];\n        } else {\n            return monthsNominative[momentToFormat.month()];\n        }\n    },\n    monthsShort : 'sty_lut_mar_kwi_maj_cze_lip_sie_wrz_paź_lis_gru'.split('_'),\n    weekdays : 'niedziela_poniedziałek_wtorek_środa_czwartek_piątek_sobota'.split('_'),\n    weekdaysShort : 'ndz_pon_wt_śr_czw_pt_sob'.split('_'),\n    weekdaysMin : 'Nd_Pn_Wt_Śr_Cz_Pt_So'.split('_'),\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD.MM.YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY HH:mm',\n        LLLL : 'dddd, D MMMM YYYY HH:mm'\n    },\n    calendar : {\n        sameDay: '[Dziś o] LT',\n        nextDay: '[Jutro o] LT',\n        nextWeek: '[W] dddd [o] LT',\n        lastDay: '[Wczoraj o] LT',\n        lastWeek: function () {\n            switch (this.day()) {\n                case 0:\n                    return '[W zeszłą niedzielę o] LT';\n                case 3:\n                    return '[W zeszłą środę o] LT';\n                case 6:\n                    return '[W zeszłą sobotę o] LT';\n                default:\n                    return '[W zeszły] dddd [o] LT';\n            }\n        },\n        sameElse: 'L'\n    },\n    relativeTime : {\n        future : 'za %s',\n        past : '%s temu',\n        s : 'kilka sekund',\n        m : translate$7,\n        mm : translate$7,\n        h : translate$7,\n        hh : translate$7,\n        d : '1 dzień',\n        dd : '%d dni',\n        M : 'miesiąc',\n        MM : translate$7,\n        y : 'rok',\n        yy : translate$7\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}\\./,\n    ordinal : '%d.',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Portuguese (Brazil) [pt-br]\n//! author : Caio Ribeiro Pereira : https://github.com/caio-ribeiro-pereira\n\nhooks.defineLocale('pt-br', {\n    months : 'Janeiro_Fevereiro_Março_Abril_Maio_Junho_Julho_Agosto_Setembro_Outubro_Novembro_Dezembro'.split('_'),\n    monthsShort : 'Jan_Fev_Mar_Abr_Mai_Jun_Jul_Ago_Set_Out_Nov_Dez'.split('_'),\n    weekdays : 'Domingo_Segunda-feira_Terça-feira_Quarta-feira_Quinta-feira_Sexta-feira_Sábado'.split('_'),\n    weekdaysShort : 'Dom_Seg_Ter_Qua_Qui_Sex_Sáb'.split('_'),\n    weekdaysMin : 'Do_2ª_3ª_4ª_5ª_6ª_Sá'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D [de] MMMM [de] YYYY',\n        LLL : 'D [de] MMMM [de] YYYY [às] HH:mm',\n        LLLL : 'dddd, D [de] MMMM [de] YYYY [às] HH:mm'\n    },\n    calendar : {\n        sameDay: '[Hoje às] LT',\n        nextDay: '[Amanhã às] LT',\n        nextWeek: 'dddd [às] LT',\n        lastDay: '[Ontem às] LT',\n        lastWeek: function () {\n            return (this.day() === 0 || this.day() === 6) ?\n                '[Último] dddd [às] LT' : // Saturday + Sunday\n                '[Última] dddd [às] LT'; // Monday - Friday\n        },\n        sameElse: 'L'\n    },\n    relativeTime : {\n        future : 'em %s',\n        past : '%s atrás',\n        s : 'poucos segundos',\n        m : 'um minuto',\n        mm : '%d minutos',\n        h : 'uma hora',\n        hh : '%d horas',\n        d : 'um dia',\n        dd : '%d dias',\n        M : 'um mês',\n        MM : '%d meses',\n        y : 'um ano',\n        yy : '%d anos'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}º/,\n    ordinal : '%dº'\n});\n\n//! moment.js locale configuration\n//! locale : Portuguese [pt]\n//! author : Jefferson : https://github.com/jalex79\n\nhooks.defineLocale('pt', {\n    months : 'Janeiro_Fevereiro_Março_Abril_Maio_Junho_Julho_Agosto_Setembro_Outubro_Novembro_Dezembro'.split('_'),\n    monthsShort : 'Jan_Fev_Mar_Abr_Mai_Jun_Jul_Ago_Set_Out_Nov_Dez'.split('_'),\n    weekdays : 'Domingo_Segunda-Feira_Terça-Feira_Quarta-Feira_Quinta-Feira_Sexta-Feira_Sábado'.split('_'),\n    weekdaysShort : 'Dom_Seg_Ter_Qua_Qui_Sex_Sáb'.split('_'),\n    weekdaysMin : 'Do_2ª_3ª_4ª_5ª_6ª_Sá'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D [de] MMMM [de] YYYY',\n        LLL : 'D [de] MMMM [de] YYYY HH:mm',\n        LLLL : 'dddd, D [de] MMMM [de] YYYY HH:mm'\n    },\n    calendar : {\n        sameDay: '[Hoje às] LT',\n        nextDay: '[Amanhã às] LT',\n        nextWeek: 'dddd [às] LT',\n        lastDay: '[Ontem às] LT',\n        lastWeek: function () {\n            return (this.day() === 0 || this.day() === 6) ?\n                '[Último] dddd [às] LT' : // Saturday + Sunday\n                '[Última] dddd [às] LT'; // Monday - Friday\n        },\n        sameElse: 'L'\n    },\n    relativeTime : {\n        future : 'em %s',\n        past : 'há %s',\n        s : 'segundos',\n        m : 'um minuto',\n        mm : '%d minutos',\n        h : 'uma hora',\n        hh : '%d horas',\n        d : 'um dia',\n        dd : '%d dias',\n        M : 'um mês',\n        MM : '%d meses',\n        y : 'um ano',\n        yy : '%d anos'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}º/,\n    ordinal : '%dº',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Romanian [ro]\n//! author : Vlad Gurdiga : https://github.com/gurdiga\n//! author : Valentin Agachi : https://github.com/avaly\n\nfunction relativeTimeWithPlural$2(number, withoutSuffix, key) {\n    var format = {\n            'mm': 'minute',\n            'hh': 'ore',\n            'dd': 'zile',\n            'MM': 'luni',\n            'yy': 'ani'\n        },\n        separator = ' ';\n    if (number % 100 >= 20 || (number >= 100 && number % 100 === 0)) {\n        separator = ' de ';\n    }\n    return number + separator + format[key];\n}\n\nhooks.defineLocale('ro', {\n    months : 'ianuarie_februarie_martie_aprilie_mai_iunie_iulie_august_septembrie_octombrie_noiembrie_decembrie'.split('_'),\n    monthsShort : 'ian._febr._mart._apr._mai_iun._iul._aug._sept._oct._nov._dec.'.split('_'),\n    monthsParseExact: true,\n    weekdays : 'duminică_luni_marți_miercuri_joi_vineri_sâmbătă'.split('_'),\n    weekdaysShort : 'Dum_Lun_Mar_Mie_Joi_Vin_Sâm'.split('_'),\n    weekdaysMin : 'Du_Lu_Ma_Mi_Jo_Vi_Sâ'.split('_'),\n    longDateFormat : {\n        LT : 'H:mm',\n        LTS : 'H:mm:ss',\n        L : 'DD.MM.YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY H:mm',\n        LLLL : 'dddd, D MMMM YYYY H:mm'\n    },\n    calendar : {\n        sameDay: '[azi la] LT',\n        nextDay: '[mâine la] LT',\n        nextWeek: 'dddd [la] LT',\n        lastDay: '[ieri la] LT',\n        lastWeek: '[fosta] dddd [la] LT',\n        sameElse: 'L'\n    },\n    relativeTime : {\n        future : 'peste %s',\n        past : '%s în urmă',\n        s : 'câteva secunde',\n        m : 'un minut',\n        mm : relativeTimeWithPlural$2,\n        h : 'o oră',\n        hh : relativeTimeWithPlural$2,\n        d : 'o zi',\n        dd : relativeTimeWithPlural$2,\n        M : 'o lună',\n        MM : relativeTimeWithPlural$2,\n        y : 'un an',\n        yy : relativeTimeWithPlural$2\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 7  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Russian [ru]\n//! author : Viktorminator : https://github.com/Viktorminator\n//! Author : Menelion Elensúle : https://github.com/Oire\n//! author : Коренберг Марк : https://github.com/socketpair\n\nfunction plural$4(word, num) {\n    var forms = word.split('_');\n    return num % 10 === 1 && num % 100 !== 11 ? forms[0] : (num % 10 >= 2 && num % 10 <= 4 && (num % 100 < 10 || num % 100 >= 20) ? forms[1] : forms[2]);\n}\nfunction relativeTimeWithPlural$3(number, withoutSuffix, key) {\n    var format = {\n        'mm': withoutSuffix ? 'минута_минуты_минут' : 'минуту_минуты_минут',\n        'hh': 'час_часа_часов',\n        'dd': 'день_дня_дней',\n        'MM': 'месяц_месяца_месяцев',\n        'yy': 'год_года_лет'\n    };\n    if (key === 'm') {\n        return withoutSuffix ? 'минута' : 'минуту';\n    }\n    else {\n        return number + ' ' + plural$4(format[key], +number);\n    }\n}\nvar monthsParse$2 = [/^янв/i, /^фев/i, /^мар/i, /^апр/i, /^ма[йя]/i, /^июн/i, /^июл/i, /^авг/i, /^сен/i, /^окт/i, /^ноя/i, /^дек/i];\n\n// http://new.gramota.ru/spravka/rules/139-prop : § 103\n// Сокращения месяцев: http://new.gramota.ru/spravka/buro/search-answer?s=242637\n// CLDR data:          http://www.unicode.org/cldr/charts/28/summary/ru.html#1753\nhooks.defineLocale('ru', {\n    months : {\n        format: 'января_февраля_марта_апреля_мая_июня_июля_августа_сентября_октября_ноября_декабря'.split('_'),\n        standalone: 'январь_февраль_март_апрель_май_июнь_июль_август_сентябрь_октябрь_ноябрь_декабрь'.split('_')\n    },\n    monthsShort : {\n        // по CLDR именно \"июл.\" и \"июн.\", но какой смысл менять букву на точку ?\n        format: 'янв._февр._мар._апр._мая_июня_июля_авг._сент._окт._нояб._дек.'.split('_'),\n        standalone: 'янв._февр._март_апр._май_июнь_июль_авг._сент._окт._нояб._дек.'.split('_')\n    },\n    weekdays : {\n        standalone: 'воскресенье_понедельник_вторник_среда_четверг_пятница_суббота'.split('_'),\n        format: 'воскресенье_понедельник_вторник_среду_четверг_пятницу_субботу'.split('_'),\n        isFormat: /\\[ ?[Вв] ?(?:прошлую|следующую|эту)? ?\\] ?dddd/\n    },\n    weekdaysShort : 'вс_пн_вт_ср_чт_пт_сб'.split('_'),\n    weekdaysMin : 'вс_пн_вт_ср_чт_пт_сб'.split('_'),\n    monthsParse : monthsParse$2,\n    longMonthsParse : monthsParse$2,\n    shortMonthsParse : monthsParse$2,\n\n    // полные названия с падежами, по три буквы, для некоторых, по 4 буквы, сокращения с точкой и без точки\n    monthsRegex: /^(январ[ья]|янв\\.?|феврал[ья]|февр?\\.?|марта?|мар\\.?|апрел[ья]|апр\\.?|ма[йя]|июн[ья]|июн\\.?|июл[ья]|июл\\.?|августа?|авг\\.?|сентябр[ья]|сент?\\.?|октябр[ья]|окт\\.?|ноябр[ья]|нояб?\\.?|декабр[ья]|дек\\.?)/i,\n\n    // копия предыдущего\n    monthsShortRegex: /^(январ[ья]|янв\\.?|феврал[ья]|февр?\\.?|марта?|мар\\.?|апрел[ья]|апр\\.?|ма[йя]|июн[ья]|июн\\.?|июл[ья]|июл\\.?|августа?|авг\\.?|сентябр[ья]|сент?\\.?|октябр[ья]|окт\\.?|ноябр[ья]|нояб?\\.?|декабр[ья]|дек\\.?)/i,\n\n    // полные названия с падежами\n    monthsStrictRegex: /^(январ[яь]|феврал[яь]|марта?|апрел[яь]|ма[яй]|июн[яь]|июл[яь]|августа?|сентябр[яь]|октябр[яь]|ноябр[яь]|декабр[яь])/i,\n\n    // Выражение, которое соотвествует только сокращённым формам\n    monthsShortStrictRegex: /^(янв\\.|февр?\\.|мар[т.]|апр\\.|ма[яй]|июн[ья.]|июл[ья.]|авг\\.|сент?\\.|окт\\.|нояб?\\.|дек\\.)/i,\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD.MM.YYYY',\n        LL : 'D MMMM YYYY г.',\n        LLL : 'D MMMM YYYY г., HH:mm',\n        LLLL : 'dddd, D MMMM YYYY г., HH:mm'\n    },\n    calendar : {\n        sameDay: '[Сегодня в] LT',\n        nextDay: '[Завтра в] LT',\n        lastDay: '[Вчера в] LT',\n        nextWeek: function (now) {\n            if (now.week() !== this.week()) {\n                switch (this.day()) {\n                    case 0:\n                        return '[В следующее] dddd [в] LT';\n                    case 1:\n                    case 2:\n                    case 4:\n                        return '[В следующий] dddd [в] LT';\n                    case 3:\n                    case 5:\n                    case 6:\n                        return '[В следующую] dddd [в] LT';\n                }\n            } else {\n                if (this.day() === 2) {\n                    return '[Во] dddd [в] LT';\n                } else {\n                    return '[В] dddd [в] LT';\n                }\n            }\n        },\n        lastWeek: function (now) {\n            if (now.week() !== this.week()) {\n                switch (this.day()) {\n                    case 0:\n                        return '[В прошлое] dddd [в] LT';\n                    case 1:\n                    case 2:\n                    case 4:\n                        return '[В прошлый] dddd [в] LT';\n                    case 3:\n                    case 5:\n                    case 6:\n                        return '[В прошлую] dddd [в] LT';\n                }\n            } else {\n                if (this.day() === 2) {\n                    return '[Во] dddd [в] LT';\n                } else {\n                    return '[В] dddd [в] LT';\n                }\n            }\n        },\n        sameElse: 'L'\n    },\n    relativeTime : {\n        future : 'через %s',\n        past : '%s назад',\n        s : 'несколько секунд',\n        m : relativeTimeWithPlural$3,\n        mm : relativeTimeWithPlural$3,\n        h : 'час',\n        hh : relativeTimeWithPlural$3,\n        d : 'день',\n        dd : relativeTimeWithPlural$3,\n        M : 'месяц',\n        MM : relativeTimeWithPlural$3,\n        y : 'год',\n        yy : relativeTimeWithPlural$3\n    },\n    meridiemParse: /ночи|утра|дня|вечера/i,\n    isPM : function (input) {\n        return /^(дня|вечера)$/.test(input);\n    },\n    meridiem : function (hour, minute, isLower) {\n        if (hour < 4) {\n            return 'ночи';\n        } else if (hour < 12) {\n            return 'утра';\n        } else if (hour < 17) {\n            return 'дня';\n        } else {\n            return 'вечера';\n        }\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}-(й|го|я)/,\n    ordinal: function (number, period) {\n        switch (period) {\n            case 'M':\n            case 'd':\n            case 'DDD':\n                return number + '-й';\n            case 'D':\n                return number + '-го';\n            case 'w':\n            case 'W':\n                return number + '-я';\n            default:\n                return number;\n        }\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 7  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Sindhi [sd]\n//! author : Narain Sagar : https://github.com/narainsagar\n\nvar months$6 = [\n    'جنوري',\n    'فيبروري',\n    'مارچ',\n    'اپريل',\n    'مئي',\n    'جون',\n    'جولاءِ',\n    'آگسٽ',\n    'سيپٽمبر',\n    'آڪٽوبر',\n    'نومبر',\n    'ڊسمبر'\n];\nvar days$1 = [\n    'آچر',\n    'سومر',\n    'اڱارو',\n    'اربع',\n    'خميس',\n    'جمع',\n    'ڇنڇر'\n];\n\nhooks.defineLocale('sd', {\n    months : months$6,\n    monthsShort : months$6,\n    weekdays : days$1,\n    weekdaysShort : days$1,\n    weekdaysMin : days$1,\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY HH:mm',\n        LLLL : 'dddd، D MMMM YYYY HH:mm'\n    },\n    meridiemParse: /صبح|شام/,\n    isPM : function (input) {\n        return 'شام' === input;\n    },\n    meridiem : function (hour, minute, isLower) {\n        if (hour < 12) {\n            return 'صبح';\n        }\n        return 'شام';\n    },\n    calendar : {\n        sameDay : '[اڄ] LT',\n        nextDay : '[سڀاڻي] LT',\n        nextWeek : 'dddd [اڳين هفتي تي] LT',\n        lastDay : '[ڪالهه] LT',\n        lastWeek : '[گزريل هفتي] dddd [تي] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : '%s پوء',\n        past : '%s اڳ',\n        s : 'چند سيڪنڊ',\n        m : 'هڪ منٽ',\n        mm : '%d منٽ',\n        h : 'هڪ ڪلاڪ',\n        hh : '%d ڪلاڪ',\n        d : 'هڪ ڏينهن',\n        dd : '%d ڏينهن',\n        M : 'هڪ مهينو',\n        MM : '%d مهينا',\n        y : 'هڪ سال',\n        yy : '%d سال'\n    },\n    preparse: function (string) {\n        return string.replace(/،/g, ',');\n    },\n    postformat: function (string) {\n        return string.replace(/,/g, '،');\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Northern Sami [se]\n//! authors : Bård Rolstad Henriksen : https://github.com/karamell\n\n\nhooks.defineLocale('se', {\n    months : 'ođđajagemánnu_guovvamánnu_njukčamánnu_cuoŋománnu_miessemánnu_geassemánnu_suoidnemánnu_borgemánnu_čakčamánnu_golggotmánnu_skábmamánnu_juovlamánnu'.split('_'),\n    monthsShort : 'ođđj_guov_njuk_cuo_mies_geas_suoi_borg_čakč_golg_skáb_juov'.split('_'),\n    weekdays : 'sotnabeaivi_vuossárga_maŋŋebárga_gaskavahkku_duorastat_bearjadat_lávvardat'.split('_'),\n    weekdaysShort : 'sotn_vuos_maŋ_gask_duor_bear_láv'.split('_'),\n    weekdaysMin : 's_v_m_g_d_b_L'.split('_'),\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD.MM.YYYY',\n        LL : 'MMMM D. [b.] YYYY',\n        LLL : 'MMMM D. [b.] YYYY [ti.] HH:mm',\n        LLLL : 'dddd, MMMM D. [b.] YYYY [ti.] HH:mm'\n    },\n    calendar : {\n        sameDay: '[otne ti] LT',\n        nextDay: '[ihttin ti] LT',\n        nextWeek: 'dddd [ti] LT',\n        lastDay: '[ikte ti] LT',\n        lastWeek: '[ovddit] dddd [ti] LT',\n        sameElse: 'L'\n    },\n    relativeTime : {\n        future : '%s geažes',\n        past : 'maŋit %s',\n        s : 'moadde sekunddat',\n        m : 'okta minuhta',\n        mm : '%d minuhtat',\n        h : 'okta diimmu',\n        hh : '%d diimmut',\n        d : 'okta beaivi',\n        dd : '%d beaivvit',\n        M : 'okta mánnu',\n        MM : '%d mánut',\n        y : 'okta jahki',\n        yy : '%d jagit'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}\\./,\n    ordinal : '%d.',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Sinhalese [si]\n//! author : Sampath Sitinamaluwa : https://github.com/sampathsris\n\n/*jshint -W100*/\nhooks.defineLocale('si', {\n    months : 'ජනවාරි_පෙබරවාරි_මාර්තු_අප්‍රේල්_මැයි_ජූනි_ජූලි_අගෝස්තු_සැප්තැම්බර්_ඔක්තෝබර්_නොවැම්බර්_දෙසැම්බර්'.split('_'),\n    monthsShort : 'ජන_පෙබ_මාර්_අප්_මැයි_ජූනි_ජූලි_අගෝ_සැප්_ඔක්_නොවැ_දෙසැ'.split('_'),\n    weekdays : 'ඉරිදා_සඳුදා_අඟහරුවාදා_බදාදා_බ්‍රහස්පතින්දා_සිකුරාදා_සෙනසුරාදා'.split('_'),\n    weekdaysShort : 'ඉරි_සඳු_අඟ_බදා_බ්‍රහ_සිකු_සෙන'.split('_'),\n    weekdaysMin : 'ඉ_ස_අ_බ_බ්‍ර_සි_සෙ'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat : {\n        LT : 'a h:mm',\n        LTS : 'a h:mm:ss',\n        L : 'YYYY/MM/DD',\n        LL : 'YYYY MMMM D',\n        LLL : 'YYYY MMMM D, a h:mm',\n        LLLL : 'YYYY MMMM D [වැනි] dddd, a h:mm:ss'\n    },\n    calendar : {\n        sameDay : '[අද] LT[ට]',\n        nextDay : '[හෙට] LT[ට]',\n        nextWeek : 'dddd LT[ට]',\n        lastDay : '[ඊයේ] LT[ට]',\n        lastWeek : '[පසුගිය] dddd LT[ට]',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : '%sකින්',\n        past : '%sකට පෙර',\n        s : 'තත්පර කිහිපය',\n        m : 'මිනිත්තුව',\n        mm : 'මිනිත්තු %d',\n        h : 'පැය',\n        hh : 'පැය %d',\n        d : 'දිනය',\n        dd : 'දින %d',\n        M : 'මාසය',\n        MM : 'මාස %d',\n        y : 'වසර',\n        yy : 'වසර %d'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2} වැනි/,\n    ordinal : function (number) {\n        return number + ' වැනි';\n    },\n    meridiemParse : /පෙර වරු|පස් වරු|පෙ.ව|ප.ව./,\n    isPM : function (input) {\n        return input === 'ප.ව.' || input === 'පස් වරු';\n    },\n    meridiem : function (hours, minutes, isLower) {\n        if (hours > 11) {\n            return isLower ? 'ප.ව.' : 'පස් වරු';\n        } else {\n            return isLower ? 'පෙ.ව.' : 'පෙර වරු';\n        }\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Slovak [sk]\n//! author : Martin Minka : https://github.com/k2s\n//! based on work of petrbela : https://github.com/petrbela\n\nvar months$7 = 'január_február_marec_apríl_máj_jún_júl_august_september_október_november_december'.split('_');\nvar monthsShort$4 = 'jan_feb_mar_apr_máj_jún_júl_aug_sep_okt_nov_dec'.split('_');\nfunction plural$5(n) {\n    return (n > 1) && (n < 5);\n}\nfunction translate$8(number, withoutSuffix, key, isFuture) {\n    var result = number + ' ';\n    switch (key) {\n        case 's':  // a few seconds / in a few seconds / a few seconds ago\n            return (withoutSuffix || isFuture) ? 'pár sekúnd' : 'pár sekundami';\n        case 'm':  // a minute / in a minute / a minute ago\n            return withoutSuffix ? 'minúta' : (isFuture ? 'minútu' : 'minútou');\n        case 'mm': // 9 minutes / in 9 minutes / 9 minutes ago\n            if (withoutSuffix || isFuture) {\n                return result + (plural$5(number) ? 'minúty' : 'minút');\n            } else {\n                return result + 'minútami';\n            }\n            break;\n        case 'h':  // an hour / in an hour / an hour ago\n            return withoutSuffix ? 'hodina' : (isFuture ? 'hodinu' : 'hodinou');\n        case 'hh': // 9 hours / in 9 hours / 9 hours ago\n            if (withoutSuffix || isFuture) {\n                return result + (plural$5(number) ? 'hodiny' : 'hodín');\n            } else {\n                return result + 'hodinami';\n            }\n            break;\n        case 'd':  // a day / in a day / a day ago\n            return (withoutSuffix || isFuture) ? 'deň' : 'dňom';\n        case 'dd': // 9 days / in 9 days / 9 days ago\n            if (withoutSuffix || isFuture) {\n                return result + (plural$5(number) ? 'dni' : 'dní');\n            } else {\n                return result + 'dňami';\n            }\n            break;\n        case 'M':  // a month / in a month / a month ago\n            return (withoutSuffix || isFuture) ? 'mesiac' : 'mesiacom';\n        case 'MM': // 9 months / in 9 months / 9 months ago\n            if (withoutSuffix || isFuture) {\n                return result + (plural$5(number) ? 'mesiace' : 'mesiacov');\n            } else {\n                return result + 'mesiacmi';\n            }\n            break;\n        case 'y':  // a year / in a year / a year ago\n            return (withoutSuffix || isFuture) ? 'rok' : 'rokom';\n        case 'yy': // 9 years / in 9 years / 9 years ago\n            if (withoutSuffix || isFuture) {\n                return result + (plural$5(number) ? 'roky' : 'rokov');\n            } else {\n                return result + 'rokmi';\n            }\n            break;\n    }\n}\n\nhooks.defineLocale('sk', {\n    months : months$7,\n    monthsShort : monthsShort$4,\n    weekdays : 'nedeľa_pondelok_utorok_streda_štvrtok_piatok_sobota'.split('_'),\n    weekdaysShort : 'ne_po_ut_st_št_pi_so'.split('_'),\n    weekdaysMin : 'ne_po_ut_st_št_pi_so'.split('_'),\n    longDateFormat : {\n        LT: 'H:mm',\n        LTS : 'H:mm:ss',\n        L : 'DD.MM.YYYY',\n        LL : 'D. MMMM YYYY',\n        LLL : 'D. MMMM YYYY H:mm',\n        LLLL : 'dddd D. MMMM YYYY H:mm'\n    },\n    calendar : {\n        sameDay: '[dnes o] LT',\n        nextDay: '[zajtra o] LT',\n        nextWeek: function () {\n            switch (this.day()) {\n                case 0:\n                    return '[v nedeľu o] LT';\n                case 1:\n                case 2:\n                    return '[v] dddd [o] LT';\n                case 3:\n                    return '[v stredu o] LT';\n                case 4:\n                    return '[vo štvrtok o] LT';\n                case 5:\n                    return '[v piatok o] LT';\n                case 6:\n                    return '[v sobotu o] LT';\n            }\n        },\n        lastDay: '[včera o] LT',\n        lastWeek: function () {\n            switch (this.day()) {\n                case 0:\n                    return '[minulú nedeľu o] LT';\n                case 1:\n                case 2:\n                    return '[minulý] dddd [o] LT';\n                case 3:\n                    return '[minulú stredu o] LT';\n                case 4:\n                case 5:\n                    return '[minulý] dddd [o] LT';\n                case 6:\n                    return '[minulú sobotu o] LT';\n            }\n        },\n        sameElse: 'L'\n    },\n    relativeTime : {\n        future : 'za %s',\n        past : 'pred %s',\n        s : translate$8,\n        m : translate$8,\n        mm : translate$8,\n        h : translate$8,\n        hh : translate$8,\n        d : translate$8,\n        dd : translate$8,\n        M : translate$8,\n        MM : translate$8,\n        y : translate$8,\n        yy : translate$8\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}\\./,\n    ordinal : '%d.',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Slovenian [sl]\n//! author : Robert Sedovšek : https://github.com/sedovsek\n\nfunction processRelativeTime$6(number, withoutSuffix, key, isFuture) {\n    var result = number + ' ';\n    switch (key) {\n        case 's':\n            return withoutSuffix || isFuture ? 'nekaj sekund' : 'nekaj sekundami';\n        case 'm':\n            return withoutSuffix ? 'ena minuta' : 'eno minuto';\n        case 'mm':\n            if (number === 1) {\n                result += withoutSuffix ? 'minuta' : 'minuto';\n            } else if (number === 2) {\n                result += withoutSuffix || isFuture ? 'minuti' : 'minutama';\n            } else if (number < 5) {\n                result += withoutSuffix || isFuture ? 'minute' : 'minutami';\n            } else {\n                result += withoutSuffix || isFuture ? 'minut' : 'minutami';\n            }\n            return result;\n        case 'h':\n            return withoutSuffix ? 'ena ura' : 'eno uro';\n        case 'hh':\n            if (number === 1) {\n                result += withoutSuffix ? 'ura' : 'uro';\n            } else if (number === 2) {\n                result += withoutSuffix || isFuture ? 'uri' : 'urama';\n            } else if (number < 5) {\n                result += withoutSuffix || isFuture ? 'ure' : 'urami';\n            } else {\n                result += withoutSuffix || isFuture ? 'ur' : 'urami';\n            }\n            return result;\n        case 'd':\n            return withoutSuffix || isFuture ? 'en dan' : 'enim dnem';\n        case 'dd':\n            if (number === 1) {\n                result += withoutSuffix || isFuture ? 'dan' : 'dnem';\n            } else if (number === 2) {\n                result += withoutSuffix || isFuture ? 'dni' : 'dnevoma';\n            } else {\n                result += withoutSuffix || isFuture ? 'dni' : 'dnevi';\n            }\n            return result;\n        case 'M':\n            return withoutSuffix || isFuture ? 'en mesec' : 'enim mesecem';\n        case 'MM':\n            if (number === 1) {\n                result += withoutSuffix || isFuture ? 'mesec' : 'mesecem';\n            } else if (number === 2) {\n                result += withoutSuffix || isFuture ? 'meseca' : 'mesecema';\n            } else if (number < 5) {\n                result += withoutSuffix || isFuture ? 'mesece' : 'meseci';\n            } else {\n                result += withoutSuffix || isFuture ? 'mesecev' : 'meseci';\n            }\n            return result;\n        case 'y':\n            return withoutSuffix || isFuture ? 'eno leto' : 'enim letom';\n        case 'yy':\n            if (number === 1) {\n                result += withoutSuffix || isFuture ? 'leto' : 'letom';\n            } else if (number === 2) {\n                result += withoutSuffix || isFuture ? 'leti' : 'letoma';\n            } else if (number < 5) {\n                result += withoutSuffix || isFuture ? 'leta' : 'leti';\n            } else {\n                result += withoutSuffix || isFuture ? 'let' : 'leti';\n            }\n            return result;\n    }\n}\n\nhooks.defineLocale('sl', {\n    months : 'januar_februar_marec_april_maj_junij_julij_avgust_september_oktober_november_december'.split('_'),\n    monthsShort : 'jan._feb._mar._apr._maj._jun._jul._avg._sep._okt._nov._dec.'.split('_'),\n    monthsParseExact: true,\n    weekdays : 'nedelja_ponedeljek_torek_sreda_četrtek_petek_sobota'.split('_'),\n    weekdaysShort : 'ned._pon._tor._sre._čet._pet._sob.'.split('_'),\n    weekdaysMin : 'ne_po_to_sr_če_pe_so'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat : {\n        LT : 'H:mm',\n        LTS : 'H:mm:ss',\n        L : 'DD.MM.YYYY',\n        LL : 'D. MMMM YYYY',\n        LLL : 'D. MMMM YYYY H:mm',\n        LLLL : 'dddd, D. MMMM YYYY H:mm'\n    },\n    calendar : {\n        sameDay  : '[danes ob] LT',\n        nextDay  : '[jutri ob] LT',\n\n        nextWeek : function () {\n            switch (this.day()) {\n                case 0:\n                    return '[v] [nedeljo] [ob] LT';\n                case 3:\n                    return '[v] [sredo] [ob] LT';\n                case 6:\n                    return '[v] [soboto] [ob] LT';\n                case 1:\n                case 2:\n                case 4:\n                case 5:\n                    return '[v] dddd [ob] LT';\n            }\n        },\n        lastDay  : '[včeraj ob] LT',\n        lastWeek : function () {\n            switch (this.day()) {\n                case 0:\n                    return '[prejšnjo] [nedeljo] [ob] LT';\n                case 3:\n                    return '[prejšnjo] [sredo] [ob] LT';\n                case 6:\n                    return '[prejšnjo] [soboto] [ob] LT';\n                case 1:\n                case 2:\n                case 4:\n                case 5:\n                    return '[prejšnji] dddd [ob] LT';\n            }\n        },\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'čez %s',\n        past   : 'pred %s',\n        s      : processRelativeTime$6,\n        m      : processRelativeTime$6,\n        mm     : processRelativeTime$6,\n        h      : processRelativeTime$6,\n        hh     : processRelativeTime$6,\n        d      : processRelativeTime$6,\n        dd     : processRelativeTime$6,\n        M      : processRelativeTime$6,\n        MM     : processRelativeTime$6,\n        y      : processRelativeTime$6,\n        yy     : processRelativeTime$6\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}\\./,\n    ordinal : '%d.',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 7  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Albanian [sq]\n//! author : Flakërim Ismani : https://github.com/flakerimi\n//! author : Menelion Elensúle : https://github.com/Oire\n//! author : Oerd Cukalla : https://github.com/oerd\n\nhooks.defineLocale('sq', {\n    months : 'Janar_Shkurt_Mars_Prill_Maj_Qershor_Korrik_Gusht_Shtator_Tetor_Nëntor_Dhjetor'.split('_'),\n    monthsShort : 'Jan_Shk_Mar_Pri_Maj_Qer_Kor_Gus_Sht_Tet_Nën_Dhj'.split('_'),\n    weekdays : 'E Diel_E Hënë_E Martë_E Mërkurë_E Enjte_E Premte_E Shtunë'.split('_'),\n    weekdaysShort : 'Die_Hën_Mar_Mër_Enj_Pre_Sht'.split('_'),\n    weekdaysMin : 'D_H_Ma_Më_E_P_Sh'.split('_'),\n    weekdaysParseExact : true,\n    meridiemParse: /PD|MD/,\n    isPM: function (input) {\n        return input.charAt(0) === 'M';\n    },\n    meridiem : function (hours, minutes, isLower) {\n        return hours < 12 ? 'PD' : 'MD';\n    },\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY HH:mm',\n        LLLL : 'dddd, D MMMM YYYY HH:mm'\n    },\n    calendar : {\n        sameDay : '[Sot në] LT',\n        nextDay : '[Nesër në] LT',\n        nextWeek : 'dddd [në] LT',\n        lastDay : '[Dje në] LT',\n        lastWeek : 'dddd [e kaluar në] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'në %s',\n        past : '%s më parë',\n        s : 'disa sekonda',\n        m : 'një minutë',\n        mm : '%d minuta',\n        h : 'një orë',\n        hh : '%d orë',\n        d : 'një ditë',\n        dd : '%d ditë',\n        M : 'një muaj',\n        MM : '%d muaj',\n        y : 'një vit',\n        yy : '%d vite'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}\\./,\n    ordinal : '%d.',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Serbian Cyrillic [sr-cyrl]\n//! author : Milan Janačković<milanjanackovic@gmail.com> : https://github.com/milan-j\n\nvar translator$1 = {\n    words: { //Different grammatical cases\n        m: ['један минут', 'једне минуте'],\n        mm: ['минут', 'минуте', 'минута'],\n        h: ['један сат', 'једног сата'],\n        hh: ['сат', 'сата', 'сати'],\n        dd: ['дан', 'дана', 'дана'],\n        MM: ['месец', 'месеца', 'месеци'],\n        yy: ['година', 'године', 'година']\n    },\n    correctGrammaticalCase: function (number, wordKey) {\n        return number === 1 ? wordKey[0] : (number >= 2 && number <= 4 ? wordKey[1] : wordKey[2]);\n    },\n    translate: function (number, withoutSuffix, key) {\n        var wordKey = translator$1.words[key];\n        if (key.length === 1) {\n            return withoutSuffix ? wordKey[0] : wordKey[1];\n        } else {\n            return number + ' ' + translator$1.correctGrammaticalCase(number, wordKey);\n        }\n    }\n};\n\nhooks.defineLocale('sr-cyrl', {\n    months: 'јануар_фебруар_март_април_мај_јун_јул_август_септембар_октобар_новембар_децембар'.split('_'),\n    monthsShort: 'јан._феб._мар._апр._мај_јун_јул_авг._сеп._окт._нов._дец.'.split('_'),\n    monthsParseExact: true,\n    weekdays: 'недеља_понедељак_уторак_среда_четвртак_петак_субота'.split('_'),\n    weekdaysShort: 'нед._пон._уто._сре._чет._пет._суб.'.split('_'),\n    weekdaysMin: 'не_по_ут_ср_че_пе_су'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat: {\n        LT: 'H:mm',\n        LTS : 'H:mm:ss',\n        L: 'DD.MM.YYYY',\n        LL: 'D. MMMM YYYY',\n        LLL: 'D. MMMM YYYY H:mm',\n        LLLL: 'dddd, D. MMMM YYYY H:mm'\n    },\n    calendar: {\n        sameDay: '[данас у] LT',\n        nextDay: '[сутра у] LT',\n        nextWeek: function () {\n            switch (this.day()) {\n                case 0:\n                    return '[у] [недељу] [у] LT';\n                case 3:\n                    return '[у] [среду] [у] LT';\n                case 6:\n                    return '[у] [суботу] [у] LT';\n                case 1:\n                case 2:\n                case 4:\n                case 5:\n                    return '[у] dddd [у] LT';\n            }\n        },\n        lastDay  : '[јуче у] LT',\n        lastWeek : function () {\n            var lastWeekDays = [\n                '[прошле] [недеље] [у] LT',\n                '[прошлог] [понедељка] [у] LT',\n                '[прошлог] [уторка] [у] LT',\n                '[прошле] [среде] [у] LT',\n                '[прошлог] [четвртка] [у] LT',\n                '[прошлог] [петка] [у] LT',\n                '[прошле] [суботе] [у] LT'\n            ];\n            return lastWeekDays[this.day()];\n        },\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'за %s',\n        past   : 'пре %s',\n        s      : 'неколико секунди',\n        m      : translator$1.translate,\n        mm     : translator$1.translate,\n        h      : translator$1.translate,\n        hh     : translator$1.translate,\n        d      : 'дан',\n        dd     : translator$1.translate,\n        M      : 'месец',\n        MM     : translator$1.translate,\n        y      : 'годину',\n        yy     : translator$1.translate\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}\\./,\n    ordinal : '%d.',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 7  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Serbian [sr]\n//! author : Milan Janačković<milanjanackovic@gmail.com> : https://github.com/milan-j\n\nvar translator$2 = {\n    words: { //Different grammatical cases\n        m: ['jedan minut', 'jedne minute'],\n        mm: ['minut', 'minute', 'minuta'],\n        h: ['jedan sat', 'jednog sata'],\n        hh: ['sat', 'sata', 'sati'],\n        dd: ['dan', 'dana', 'dana'],\n        MM: ['mesec', 'meseca', 'meseci'],\n        yy: ['godina', 'godine', 'godina']\n    },\n    correctGrammaticalCase: function (number, wordKey) {\n        return number === 1 ? wordKey[0] : (number >= 2 && number <= 4 ? wordKey[1] : wordKey[2]);\n    },\n    translate: function (number, withoutSuffix, key) {\n        var wordKey = translator$2.words[key];\n        if (key.length === 1) {\n            return withoutSuffix ? wordKey[0] : wordKey[1];\n        } else {\n            return number + ' ' + translator$2.correctGrammaticalCase(number, wordKey);\n        }\n    }\n};\n\nhooks.defineLocale('sr', {\n    months: 'januar_februar_mart_april_maj_jun_jul_avgust_septembar_oktobar_novembar_decembar'.split('_'),\n    monthsShort: 'jan._feb._mar._apr._maj_jun_jul_avg._sep._okt._nov._dec.'.split('_'),\n    monthsParseExact: true,\n    weekdays: 'nedelja_ponedeljak_utorak_sreda_četvrtak_petak_subota'.split('_'),\n    weekdaysShort: 'ned._pon._uto._sre._čet._pet._sub.'.split('_'),\n    weekdaysMin: 'ne_po_ut_sr_če_pe_su'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat: {\n        LT: 'H:mm',\n        LTS : 'H:mm:ss',\n        L: 'DD.MM.YYYY',\n        LL: 'D. MMMM YYYY',\n        LLL: 'D. MMMM YYYY H:mm',\n        LLLL: 'dddd, D. MMMM YYYY H:mm'\n    },\n    calendar: {\n        sameDay: '[danas u] LT',\n        nextDay: '[sutra u] LT',\n        nextWeek: function () {\n            switch (this.day()) {\n                case 0:\n                    return '[u] [nedelju] [u] LT';\n                case 3:\n                    return '[u] [sredu] [u] LT';\n                case 6:\n                    return '[u] [subotu] [u] LT';\n                case 1:\n                case 2:\n                case 4:\n                case 5:\n                    return '[u] dddd [u] LT';\n            }\n        },\n        lastDay  : '[juče u] LT',\n        lastWeek : function () {\n            var lastWeekDays = [\n                '[prošle] [nedelje] [u] LT',\n                '[prošlog] [ponedeljka] [u] LT',\n                '[prošlog] [utorka] [u] LT',\n                '[prošle] [srede] [u] LT',\n                '[prošlog] [četvrtka] [u] LT',\n                '[prošlog] [petka] [u] LT',\n                '[prošle] [subote] [u] LT'\n            ];\n            return lastWeekDays[this.day()];\n        },\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'za %s',\n        past   : 'pre %s',\n        s      : 'nekoliko sekundi',\n        m      : translator$2.translate,\n        mm     : translator$2.translate,\n        h      : translator$2.translate,\n        hh     : translator$2.translate,\n        d      : 'dan',\n        dd     : translator$2.translate,\n        M      : 'mesec',\n        MM     : translator$2.translate,\n        y      : 'godinu',\n        yy     : translator$2.translate\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}\\./,\n    ordinal : '%d.',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 7  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : siSwati [ss]\n//! author : Nicolai Davies<mail@nicolai.io> : https://github.com/nicolaidavies\n\n\nhooks.defineLocale('ss', {\n    months : \"Bhimbidvwane_Indlovana_Indlov'lenkhulu_Mabasa_Inkhwekhweti_Inhlaba_Kholwane_Ingci_Inyoni_Imphala_Lweti_Ingongoni\".split('_'),\n    monthsShort : 'Bhi_Ina_Inu_Mab_Ink_Inh_Kho_Igc_Iny_Imp_Lwe_Igo'.split('_'),\n    weekdays : 'Lisontfo_Umsombuluko_Lesibili_Lesitsatfu_Lesine_Lesihlanu_Umgcibelo'.split('_'),\n    weekdaysShort : 'Lis_Umb_Lsb_Les_Lsi_Lsh_Umg'.split('_'),\n    weekdaysMin : 'Li_Us_Lb_Lt_Ls_Lh_Ug'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat : {\n        LT : 'h:mm A',\n        LTS : 'h:mm:ss A',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY h:mm A',\n        LLLL : 'dddd, D MMMM YYYY h:mm A'\n    },\n    calendar : {\n        sameDay : '[Namuhla nga] LT',\n        nextDay : '[Kusasa nga] LT',\n        nextWeek : 'dddd [nga] LT',\n        lastDay : '[Itolo nga] LT',\n        lastWeek : 'dddd [leliphelile] [nga] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'nga %s',\n        past : 'wenteka nga %s',\n        s : 'emizuzwana lomcane',\n        m : 'umzuzu',\n        mm : '%d emizuzu',\n        h : 'lihora',\n        hh : '%d emahora',\n        d : 'lilanga',\n        dd : '%d emalanga',\n        M : 'inyanga',\n        MM : '%d tinyanga',\n        y : 'umnyaka',\n        yy : '%d iminyaka'\n    },\n    meridiemParse: /ekuseni|emini|entsambama|ebusuku/,\n    meridiem : function (hours, minutes, isLower) {\n        if (hours < 11) {\n            return 'ekuseni';\n        } else if (hours < 15) {\n            return 'emini';\n        } else if (hours < 19) {\n            return 'entsambama';\n        } else {\n            return 'ebusuku';\n        }\n    },\n    meridiemHour : function (hour, meridiem) {\n        if (hour === 12) {\n            hour = 0;\n        }\n        if (meridiem === 'ekuseni') {\n            return hour;\n        } else if (meridiem === 'emini') {\n            return hour >= 11 ? hour : hour + 12;\n        } else if (meridiem === 'entsambama' || meridiem === 'ebusuku') {\n            if (hour === 0) {\n                return 0;\n            }\n            return hour + 12;\n        }\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}/,\n    ordinal : '%d',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Swedish [sv]\n//! author : Jens Alm : https://github.com/ulmus\n\nhooks.defineLocale('sv', {\n    months : 'januari_februari_mars_april_maj_juni_juli_augusti_september_oktober_november_december'.split('_'),\n    monthsShort : 'jan_feb_mar_apr_maj_jun_jul_aug_sep_okt_nov_dec'.split('_'),\n    weekdays : 'söndag_måndag_tisdag_onsdag_torsdag_fredag_lördag'.split('_'),\n    weekdaysShort : 'sön_mån_tis_ons_tor_fre_lör'.split('_'),\n    weekdaysMin : 'sö_må_ti_on_to_fr_lö'.split('_'),\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'YYYY-MM-DD',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY [kl.] HH:mm',\n        LLLL : 'dddd D MMMM YYYY [kl.] HH:mm',\n        lll : 'D MMM YYYY HH:mm',\n        llll : 'ddd D MMM YYYY HH:mm'\n    },\n    calendar : {\n        sameDay: '[Idag] LT',\n        nextDay: '[Imorgon] LT',\n        lastDay: '[Igår] LT',\n        nextWeek: '[På] dddd LT',\n        lastWeek: '[I] dddd[s] LT',\n        sameElse: 'L'\n    },\n    relativeTime : {\n        future : 'om %s',\n        past : 'för %s sedan',\n        s : 'några sekunder',\n        m : 'en minut',\n        mm : '%d minuter',\n        h : 'en timme',\n        hh : '%d timmar',\n        d : 'en dag',\n        dd : '%d dagar',\n        M : 'en månad',\n        MM : '%d månader',\n        y : 'ett år',\n        yy : '%d år'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}(e|a)/,\n    ordinal : function (number) {\n        var b = number % 10,\n            output = (~~(number % 100 / 10) === 1) ? 'e' :\n            (b === 1) ? 'a' :\n            (b === 2) ? 'a' :\n            (b === 3) ? 'e' : 'e';\n        return number + output;\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Swahili [sw]\n//! author : Fahad Kassim : https://github.com/fadsel\n\nhooks.defineLocale('sw', {\n    months : 'Januari_Februari_Machi_Aprili_Mei_Juni_Julai_Agosti_Septemba_Oktoba_Novemba_Desemba'.split('_'),\n    monthsShort : 'Jan_Feb_Mac_Apr_Mei_Jun_Jul_Ago_Sep_Okt_Nov_Des'.split('_'),\n    weekdays : 'Jumapili_Jumatatu_Jumanne_Jumatano_Alhamisi_Ijumaa_Jumamosi'.split('_'),\n    weekdaysShort : 'Jpl_Jtat_Jnne_Jtan_Alh_Ijm_Jmos'.split('_'),\n    weekdaysMin : 'J2_J3_J4_J5_Al_Ij_J1'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD.MM.YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY HH:mm',\n        LLLL : 'dddd, D MMMM YYYY HH:mm'\n    },\n    calendar : {\n        sameDay : '[leo saa] LT',\n        nextDay : '[kesho saa] LT',\n        nextWeek : '[wiki ijayo] dddd [saat] LT',\n        lastDay : '[jana] LT',\n        lastWeek : '[wiki iliyopita] dddd [saat] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : '%s baadaye',\n        past : 'tokea %s',\n        s : 'hivi punde',\n        m : 'dakika moja',\n        mm : 'dakika %d',\n        h : 'saa limoja',\n        hh : 'masaa %d',\n        d : 'siku moja',\n        dd : 'masiku %d',\n        M : 'mwezi mmoja',\n        MM : 'miezi %d',\n        y : 'mwaka mmoja',\n        yy : 'miaka %d'\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 7  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Tamil [ta]\n//! author : Arjunkumar Krishnamoorthy : https://github.com/tk120404\n\nvar symbolMap$12 = {\n    '1': '௧',\n    '2': '௨',\n    '3': '௩',\n    '4': '௪',\n    '5': '௫',\n    '6': '௬',\n    '7': '௭',\n    '8': '௮',\n    '9': '௯',\n    '0': '௦'\n};\nvar numberMap$11 = {\n    '௧': '1',\n    '௨': '2',\n    '௩': '3',\n    '௪': '4',\n    '௫': '5',\n    '௬': '6',\n    '௭': '7',\n    '௮': '8',\n    '௯': '9',\n    '௦': '0'\n};\n\nhooks.defineLocale('ta', {\n    months : 'ஜனவரி_பிப்ரவரி_மார்ச்_ஏப்ரல்_மே_ஜூன்_ஜூலை_ஆகஸ்ட்_செப்டெம்பர்_அக்டோபர்_நவம்பர்_டிசம்பர்'.split('_'),\n    monthsShort : 'ஜனவரி_பிப்ரவரி_மார்ச்_ஏப்ரல்_மே_ஜூன்_ஜூலை_ஆகஸ்ட்_செப்டெம்பர்_அக்டோபர்_நவம்பர்_டிசம்பர்'.split('_'),\n    weekdays : 'ஞாயிற்றுக்கிழமை_திங்கட்கிழமை_செவ்வாய்கிழமை_புதன்கிழமை_வியாழக்கிழமை_வெள்ளிக்கிழமை_சனிக்கிழமை'.split('_'),\n    weekdaysShort : 'ஞாயிறு_திங்கள்_செவ்வாய்_புதன்_வியாழன்_வெள்ளி_சனி'.split('_'),\n    weekdaysMin : 'ஞா_தி_செ_பு_வி_வெ_ச'.split('_'),\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY, HH:mm',\n        LLLL : 'dddd, D MMMM YYYY, HH:mm'\n    },\n    calendar : {\n        sameDay : '[இன்று] LT',\n        nextDay : '[நாளை] LT',\n        nextWeek : 'dddd, LT',\n        lastDay : '[நேற்று] LT',\n        lastWeek : '[கடந்த வாரம்] dddd, LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : '%s இல்',\n        past : '%s முன்',\n        s : 'ஒரு சில விநாடிகள்',\n        m : 'ஒரு நிமிடம்',\n        mm : '%d நிமிடங்கள்',\n        h : 'ஒரு மணி நேரம்',\n        hh : '%d மணி நேரம்',\n        d : 'ஒரு நாள்',\n        dd : '%d நாட்கள்',\n        M : 'ஒரு மாதம்',\n        MM : '%d மாதங்கள்',\n        y : 'ஒரு வருடம்',\n        yy : '%d ஆண்டுகள்'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}வது/,\n    ordinal : function (number) {\n        return number + 'வது';\n    },\n    preparse: function (string) {\n        return string.replace(/[௧௨௩௪௫௬௭௮௯௦]/g, function (match) {\n            return numberMap$11[match];\n        });\n    },\n    postformat: function (string) {\n        return string.replace(/\\d/g, function (match) {\n            return symbolMap$12[match];\n        });\n    },\n    // refer http://ta.wikipedia.org/s/1er1\n    meridiemParse: /யாமம்|வைகறை|காலை|நண்பகல்|எற்பாடு|மாலை/,\n    meridiem : function (hour, minute, isLower) {\n        if (hour < 2) {\n            return ' யாமம்';\n        } else if (hour < 6) {\n            return ' வைகறை';  // வைகறை\n        } else if (hour < 10) {\n            return ' காலை'; // காலை\n        } else if (hour < 14) {\n            return ' நண்பகல்'; // நண்பகல்\n        } else if (hour < 18) {\n            return ' எற்பாடு'; // எற்பாடு\n        } else if (hour < 22) {\n            return ' மாலை'; // மாலை\n        } else {\n            return ' யாமம்';\n        }\n    },\n    meridiemHour : function (hour, meridiem) {\n        if (hour === 12) {\n            hour = 0;\n        }\n        if (meridiem === 'யாமம்') {\n            return hour < 2 ? hour : hour + 12;\n        } else if (meridiem === 'வைகறை' || meridiem === 'காலை') {\n            return hour;\n        } else if (meridiem === 'நண்பகல்') {\n            return hour >= 10 ? hour : hour + 12;\n        } else {\n            return hour + 12;\n        }\n    },\n    week : {\n        dow : 0, // Sunday is the first day of the week.\n        doy : 6  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Telugu [te]\n//! author : Krishna Chaitanya Thota : https://github.com/kcthota\n\nhooks.defineLocale('te', {\n    months : 'జనవరి_ఫిబ్రవరి_మార్చి_ఏప్రిల్_మే_జూన్_జూలై_ఆగస్టు_సెప్టెంబర్_అక్టోబర్_నవంబర్_డిసెంబర్'.split('_'),\n    monthsShort : 'జన._ఫిబ్ర._మార్చి_ఏప్రి._మే_జూన్_జూలై_ఆగ._సెప్._అక్టో._నవ._డిసె.'.split('_'),\n    monthsParseExact : true,\n    weekdays : 'ఆదివారం_సోమవారం_మంగళవారం_బుధవారం_గురువారం_శుక్రవారం_శనివారం'.split('_'),\n    weekdaysShort : 'ఆది_సోమ_మంగళ_బుధ_గురు_శుక్ర_శని'.split('_'),\n    weekdaysMin : 'ఆ_సో_మం_బు_గు_శు_శ'.split('_'),\n    longDateFormat : {\n        LT : 'A h:mm',\n        LTS : 'A h:mm:ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY, A h:mm',\n        LLLL : 'dddd, D MMMM YYYY, A h:mm'\n    },\n    calendar : {\n        sameDay : '[నేడు] LT',\n        nextDay : '[రేపు] LT',\n        nextWeek : 'dddd, LT',\n        lastDay : '[నిన్న] LT',\n        lastWeek : '[గత] dddd, LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : '%s లో',\n        past : '%s క్రితం',\n        s : 'కొన్ని క్షణాలు',\n        m : 'ఒక నిమిషం',\n        mm : '%d నిమిషాలు',\n        h : 'ఒక గంట',\n        hh : '%d గంటలు',\n        d : 'ఒక రోజు',\n        dd : '%d రోజులు',\n        M : 'ఒక నెల',\n        MM : '%d నెలలు',\n        y : 'ఒక సంవత్సరం',\n        yy : '%d సంవత్సరాలు'\n    },\n    dayOfMonthOrdinalParse : /\\d{1,2}వ/,\n    ordinal : '%dవ',\n    meridiemParse: /రాత్రి|ఉదయం|మధ్యాహ్నం|సాయంత్రం/,\n    meridiemHour : function (hour, meridiem) {\n        if (hour === 12) {\n            hour = 0;\n        }\n        if (meridiem === 'రాత్రి') {\n            return hour < 4 ? hour : hour + 12;\n        } else if (meridiem === 'ఉదయం') {\n            return hour;\n        } else if (meridiem === 'మధ్యాహ్నం') {\n            return hour >= 10 ? hour : hour + 12;\n        } else if (meridiem === 'సాయంత్రం') {\n            return hour + 12;\n        }\n    },\n    meridiem : function (hour, minute, isLower) {\n        if (hour < 4) {\n            return 'రాత్రి';\n        } else if (hour < 10) {\n            return 'ఉదయం';\n        } else if (hour < 17) {\n            return 'మధ్యాహ్నం';\n        } else if (hour < 20) {\n            return 'సాయంత్రం';\n        } else {\n            return 'రాత్రి';\n        }\n    },\n    week : {\n        dow : 0, // Sunday is the first day of the week.\n        doy : 6  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Tetun Dili (East Timor) [tet]\n//! author : Joshua Brooks : https://github.com/joshbrooks\n//! author : Onorio De J. Afonso : https://github.com/marobo\n\nhooks.defineLocale('tet', {\n    months : 'Janeiru_Fevereiru_Marsu_Abril_Maiu_Juniu_Juliu_Augustu_Setembru_Outubru_Novembru_Dezembru'.split('_'),\n    monthsShort : 'Jan_Fev_Mar_Abr_Mai_Jun_Jul_Aug_Set_Out_Nov_Dez'.split('_'),\n    weekdays : 'Domingu_Segunda_Tersa_Kuarta_Kinta_Sexta_Sabadu'.split('_'),\n    weekdaysShort : 'Dom_Seg_Ters_Kua_Kint_Sext_Sab'.split('_'),\n    weekdaysMin : 'Do_Seg_Te_Ku_Ki_Sex_Sa'.split('_'),\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY HH:mm',\n        LLLL : 'dddd, D MMMM YYYY HH:mm'\n    },\n    calendar : {\n        sameDay: '[Ohin iha] LT',\n        nextDay: '[Aban iha] LT',\n        nextWeek: 'dddd [iha] LT',\n        lastDay: '[Horiseik iha] LT',\n        lastWeek: 'dddd [semana kotuk] [iha] LT',\n        sameElse: 'L'\n    },\n    relativeTime : {\n        future : 'iha %s',\n        past : '%s liuba',\n        s : 'minutu balun',\n        m : 'minutu ida',\n        mm : 'minutus %d',\n        h : 'horas ida',\n        hh : 'horas %d',\n        d : 'loron ida',\n        dd : 'loron %d',\n        M : 'fulan ida',\n        MM : 'fulan %d',\n        y : 'tinan ida',\n        yy : 'tinan %d'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}(st|nd|rd|th)/,\n    ordinal : function (number) {\n        var b = number % 10,\n            output = (~~(number % 100 / 10) === 1) ? 'th' :\n            (b === 1) ? 'st' :\n            (b === 2) ? 'nd' :\n            (b === 3) ? 'rd' : 'th';\n        return number + output;\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Thai [th]\n//! author : Kridsada Thanabulpong : https://github.com/sirn\n\nhooks.defineLocale('th', {\n    months : 'มกราคม_กุมภาพันธ์_มีนาคม_เมษายน_พฤษภาคม_มิถุนายน_กรกฎาคม_สิงหาคม_กันยายน_ตุลาคม_พฤศจิกายน_ธันวาคม'.split('_'),\n    monthsShort : 'ม.ค._ก.พ._มี.ค._เม.ย._พ.ค._มิ.ย._ก.ค._ส.ค._ก.ย._ต.ค._พ.ย._ธ.ค.'.split('_'),\n    monthsParseExact: true,\n    weekdays : 'อาทิตย์_จันทร์_อังคาร_พุธ_พฤหัสบดี_ศุกร์_เสาร์'.split('_'),\n    weekdaysShort : 'อาทิตย์_จันทร์_อังคาร_พุธ_พฤหัส_ศุกร์_เสาร์'.split('_'), // yes, three characters difference\n    weekdaysMin : 'อา._จ._อ._พ._พฤ._ศ._ส.'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat : {\n        LT : 'H:mm',\n        LTS : 'H:mm:ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY เวลา H:mm',\n        LLLL : 'วันddddที่ D MMMM YYYY เวลา H:mm'\n    },\n    meridiemParse: /ก่อนเที่ยง|หลังเที่ยง/,\n    isPM: function (input) {\n        return input === 'หลังเที่ยง';\n    },\n    meridiem : function (hour, minute, isLower) {\n        if (hour < 12) {\n            return 'ก่อนเที่ยง';\n        } else {\n            return 'หลังเที่ยง';\n        }\n    },\n    calendar : {\n        sameDay : '[วันนี้ เวลา] LT',\n        nextDay : '[พรุ่งนี้ เวลา] LT',\n        nextWeek : 'dddd[หน้า เวลา] LT',\n        lastDay : '[เมื่อวานนี้ เวลา] LT',\n        lastWeek : '[วัน]dddd[ที่แล้ว เวลา] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'อีก %s',\n        past : '%sที่แล้ว',\n        s : 'ไม่กี่วินาที',\n        m : '1 นาที',\n        mm : '%d นาที',\n        h : '1 ชั่วโมง',\n        hh : '%d ชั่วโมง',\n        d : '1 วัน',\n        dd : '%d วัน',\n        M : '1 เดือน',\n        MM : '%d เดือน',\n        y : '1 ปี',\n        yy : '%d ปี'\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Tagalog (Philippines) [tl-ph]\n//! author : Dan Hagman : https://github.com/hagmandan\n\nhooks.defineLocale('tl-ph', {\n    months : 'Enero_Pebrero_Marso_Abril_Mayo_Hunyo_Hulyo_Agosto_Setyembre_Oktubre_Nobyembre_Disyembre'.split('_'),\n    monthsShort : 'Ene_Peb_Mar_Abr_May_Hun_Hul_Ago_Set_Okt_Nob_Dis'.split('_'),\n    weekdays : 'Linggo_Lunes_Martes_Miyerkules_Huwebes_Biyernes_Sabado'.split('_'),\n    weekdaysShort : 'Lin_Lun_Mar_Miy_Huw_Biy_Sab'.split('_'),\n    weekdaysMin : 'Li_Lu_Ma_Mi_Hu_Bi_Sab'.split('_'),\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'MM/D/YYYY',\n        LL : 'MMMM D, YYYY',\n        LLL : 'MMMM D, YYYY HH:mm',\n        LLLL : 'dddd, MMMM DD, YYYY HH:mm'\n    },\n    calendar : {\n        sameDay: 'LT [ngayong araw]',\n        nextDay: '[Bukas ng] LT',\n        nextWeek: 'LT [sa susunod na] dddd',\n        lastDay: 'LT [kahapon]',\n        lastWeek: 'LT [noong nakaraang] dddd',\n        sameElse: 'L'\n    },\n    relativeTime : {\n        future : 'sa loob ng %s',\n        past : '%s ang nakalipas',\n        s : 'ilang segundo',\n        m : 'isang minuto',\n        mm : '%d minuto',\n        h : 'isang oras',\n        hh : '%d oras',\n        d : 'isang araw',\n        dd : '%d araw',\n        M : 'isang buwan',\n        MM : '%d buwan',\n        y : 'isang taon',\n        yy : '%d taon'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}/,\n    ordinal : function (number) {\n        return number;\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Klingon [tlh]\n//! author : Dominika Kruk : https://github.com/amaranthrose\n\nvar numbersNouns = 'pagh_wa’_cha’_wej_loS_vagh_jav_Soch_chorgh_Hut'.split('_');\n\nfunction translateFuture(output) {\n    var time = output;\n    time = (output.indexOf('jaj') !== -1) ?\n    time.slice(0, -3) + 'leS' :\n    (output.indexOf('jar') !== -1) ?\n    time.slice(0, -3) + 'waQ' :\n    (output.indexOf('DIS') !== -1) ?\n    time.slice(0, -3) + 'nem' :\n    time + ' pIq';\n    return time;\n}\n\nfunction translatePast(output) {\n    var time = output;\n    time = (output.indexOf('jaj') !== -1) ?\n    time.slice(0, -3) + 'Hu’' :\n    (output.indexOf('jar') !== -1) ?\n    time.slice(0, -3) + 'wen' :\n    (output.indexOf('DIS') !== -1) ?\n    time.slice(0, -3) + 'ben' :\n    time + ' ret';\n    return time;\n}\n\nfunction translate$9(number, withoutSuffix, string, isFuture) {\n    var numberNoun = numberAsNoun(number);\n    switch (string) {\n        case 'mm':\n            return numberNoun + ' tup';\n        case 'hh':\n            return numberNoun + ' rep';\n        case 'dd':\n            return numberNoun + ' jaj';\n        case 'MM':\n            return numberNoun + ' jar';\n        case 'yy':\n            return numberNoun + ' DIS';\n    }\n}\n\nfunction numberAsNoun(number) {\n    var hundred = Math.floor((number % 1000) / 100),\n    ten = Math.floor((number % 100) / 10),\n    one = number % 10,\n    word = '';\n    if (hundred > 0) {\n        word += numbersNouns[hundred] + 'vatlh';\n    }\n    if (ten > 0) {\n        word += ((word !== '') ? ' ' : '') + numbersNouns[ten] + 'maH';\n    }\n    if (one > 0) {\n        word += ((word !== '') ? ' ' : '') + numbersNouns[one];\n    }\n    return (word === '') ? 'pagh' : word;\n}\n\nhooks.defineLocale('tlh', {\n    months : 'tera’ jar wa’_tera’ jar cha’_tera’ jar wej_tera’ jar loS_tera’ jar vagh_tera’ jar jav_tera’ jar Soch_tera’ jar chorgh_tera’ jar Hut_tera’ jar wa’maH_tera’ jar wa’maH wa’_tera’ jar wa’maH cha’'.split('_'),\n    monthsShort : 'jar wa’_jar cha’_jar wej_jar loS_jar vagh_jar jav_jar Soch_jar chorgh_jar Hut_jar wa’maH_jar wa’maH wa’_jar wa’maH cha’'.split('_'),\n    monthsParseExact : true,\n    weekdays : 'lojmItjaj_DaSjaj_povjaj_ghItlhjaj_loghjaj_buqjaj_ghInjaj'.split('_'),\n    weekdaysShort : 'lojmItjaj_DaSjaj_povjaj_ghItlhjaj_loghjaj_buqjaj_ghInjaj'.split('_'),\n    weekdaysMin : 'lojmItjaj_DaSjaj_povjaj_ghItlhjaj_loghjaj_buqjaj_ghInjaj'.split('_'),\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD.MM.YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY HH:mm',\n        LLLL : 'dddd, D MMMM YYYY HH:mm'\n    },\n    calendar : {\n        sameDay: '[DaHjaj] LT',\n        nextDay: '[wa’leS] LT',\n        nextWeek: 'LLL',\n        lastDay: '[wa’Hu’] LT',\n        lastWeek: 'LLL',\n        sameElse: 'L'\n    },\n    relativeTime : {\n        future : translateFuture,\n        past : translatePast,\n        s : 'puS lup',\n        m : 'wa’ tup',\n        mm : translate$9,\n        h : 'wa’ rep',\n        hh : translate$9,\n        d : 'wa’ jaj',\n        dd : translate$9,\n        M : 'wa’ jar',\n        MM : translate$9,\n        y : 'wa’ DIS',\n        yy : translate$9\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}\\./,\n    ordinal : '%d.',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Turkish [tr]\n//! authors : Erhan Gundogan : https://github.com/erhangundogan,\n//!           Burak Yiğit Kaya: https://github.com/BYK\n\nvar suffixes$3 = {\n    1: '\\'inci',\n    5: '\\'inci',\n    8: '\\'inci',\n    70: '\\'inci',\n    80: '\\'inci',\n    2: '\\'nci',\n    7: '\\'nci',\n    20: '\\'nci',\n    50: '\\'nci',\n    3: '\\'üncü',\n    4: '\\'üncü',\n    100: '\\'üncü',\n    6: '\\'ncı',\n    9: '\\'uncu',\n    10: '\\'uncu',\n    30: '\\'uncu',\n    60: '\\'ıncı',\n    90: '\\'ıncı'\n};\n\nhooks.defineLocale('tr', {\n    months : 'Ocak_Şubat_Mart_Nisan_Mayıs_Haziran_Temmuz_Ağustos_Eylül_Ekim_Kasım_Aralık'.split('_'),\n    monthsShort : 'Oca_Şub_Mar_Nis_May_Haz_Tem_Ağu_Eyl_Eki_Kas_Ara'.split('_'),\n    weekdays : 'Pazar_Pazartesi_Salı_Çarşamba_Perşembe_Cuma_Cumartesi'.split('_'),\n    weekdaysShort : 'Paz_Pts_Sal_Çar_Per_Cum_Cts'.split('_'),\n    weekdaysMin : 'Pz_Pt_Sa_Ça_Pe_Cu_Ct'.split('_'),\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD.MM.YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY HH:mm',\n        LLLL : 'dddd, D MMMM YYYY HH:mm'\n    },\n    calendar : {\n        sameDay : '[bugün saat] LT',\n        nextDay : '[yarın saat] LT',\n        nextWeek : '[haftaya] dddd [saat] LT',\n        lastDay : '[dün] LT',\n        lastWeek : '[geçen hafta] dddd [saat] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : '%s sonra',\n        past : '%s önce',\n        s : 'birkaç saniye',\n        m : 'bir dakika',\n        mm : '%d dakika',\n        h : 'bir saat',\n        hh : '%d saat',\n        d : 'bir gün',\n        dd : '%d gün',\n        M : 'bir ay',\n        MM : '%d ay',\n        y : 'bir yıl',\n        yy : '%d yıl'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}'(inci|nci|üncü|ncı|uncu|ıncı)/,\n    ordinal : function (number) {\n        if (number === 0) {  // special case for zero\n            return number + '\\'ıncı';\n        }\n        var a = number % 10,\n            b = number % 100 - a,\n            c = number >= 100 ? 100 : null;\n        return number + (suffixes$3[a] || suffixes$3[b] || suffixes$3[c]);\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 7  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Talossan [tzl]\n//! author : Robin van der Vliet : https://github.com/robin0van0der0v\n//! author : Iustì Canun\n\n// After the year there should be a slash and the amount of years since December 26, 1979 in Roman numerals.\n// This is currently too difficult (maybe even impossible) to add.\nhooks.defineLocale('tzl', {\n    months : 'Januar_Fevraglh_Març_Avrïu_Mai_Gün_Julia_Guscht_Setemvar_Listopäts_Noemvar_Zecemvar'.split('_'),\n    monthsShort : 'Jan_Fev_Mar_Avr_Mai_Gün_Jul_Gus_Set_Lis_Noe_Zec'.split('_'),\n    weekdays : 'Súladi_Lúneçi_Maitzi_Márcuri_Xhúadi_Viénerçi_Sáturi'.split('_'),\n    weekdaysShort : 'Súl_Lún_Mai_Már_Xhú_Vié_Sát'.split('_'),\n    weekdaysMin : 'Sú_Lú_Ma_Má_Xh_Vi_Sá'.split('_'),\n    longDateFormat : {\n        LT : 'HH.mm',\n        LTS : 'HH.mm.ss',\n        L : 'DD.MM.YYYY',\n        LL : 'D. MMMM [dallas] YYYY',\n        LLL : 'D. MMMM [dallas] YYYY HH.mm',\n        LLLL : 'dddd, [li] D. MMMM [dallas] YYYY HH.mm'\n    },\n    meridiemParse: /d\\'o|d\\'a/i,\n    isPM : function (input) {\n        return 'd\\'o' === input.toLowerCase();\n    },\n    meridiem : function (hours, minutes, isLower) {\n        if (hours > 11) {\n            return isLower ? 'd\\'o' : 'D\\'O';\n        } else {\n            return isLower ? 'd\\'a' : 'D\\'A';\n        }\n    },\n    calendar : {\n        sameDay : '[oxhi à] LT',\n        nextDay : '[demà à] LT',\n        nextWeek : 'dddd [à] LT',\n        lastDay : '[ieiri à] LT',\n        lastWeek : '[sür el] dddd [lasteu à] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'osprei %s',\n        past : 'ja%s',\n        s : processRelativeTime$7,\n        m : processRelativeTime$7,\n        mm : processRelativeTime$7,\n        h : processRelativeTime$7,\n        hh : processRelativeTime$7,\n        d : processRelativeTime$7,\n        dd : processRelativeTime$7,\n        M : processRelativeTime$7,\n        MM : processRelativeTime$7,\n        y : processRelativeTime$7,\n        yy : processRelativeTime$7\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}\\./,\n    ordinal : '%d.',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\nfunction processRelativeTime$7(number, withoutSuffix, key, isFuture) {\n    var format = {\n        's': ['viensas secunds', '\\'iensas secunds'],\n        'm': ['\\'n míut', '\\'iens míut'],\n        'mm': [number + ' míuts', '' + number + ' míuts'],\n        'h': ['\\'n þora', '\\'iensa þora'],\n        'hh': [number + ' þoras', '' + number + ' þoras'],\n        'd': ['\\'n ziua', '\\'iensa ziua'],\n        'dd': [number + ' ziuas', '' + number + ' ziuas'],\n        'M': ['\\'n mes', '\\'iens mes'],\n        'MM': [number + ' mesen', '' + number + ' mesen'],\n        'y': ['\\'n ar', '\\'iens ar'],\n        'yy': [number + ' ars', '' + number + ' ars']\n    };\n    return isFuture ? format[key][0] : (withoutSuffix ? format[key][0] : format[key][1]);\n}\n\n//! moment.js locale configuration\n//! locale : Central Atlas Tamazight Latin [tzm-latn]\n//! author : Abdel Said : https://github.com/abdelsaid\n\nhooks.defineLocale('tzm-latn', {\n    months : 'innayr_brˤayrˤ_marˤsˤ_ibrir_mayyw_ywnyw_ywlywz_ɣwšt_šwtanbir_ktˤwbrˤ_nwwanbir_dwjnbir'.split('_'),\n    monthsShort : 'innayr_brˤayrˤ_marˤsˤ_ibrir_mayyw_ywnyw_ywlywz_ɣwšt_šwtanbir_ktˤwbrˤ_nwwanbir_dwjnbir'.split('_'),\n    weekdays : 'asamas_aynas_asinas_akras_akwas_asimwas_asiḍyas'.split('_'),\n    weekdaysShort : 'asamas_aynas_asinas_akras_akwas_asimwas_asiḍyas'.split('_'),\n    weekdaysMin : 'asamas_aynas_asinas_akras_akwas_asimwas_asiḍyas'.split('_'),\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY HH:mm',\n        LLLL : 'dddd D MMMM YYYY HH:mm'\n    },\n    calendar : {\n        sameDay: '[asdkh g] LT',\n        nextDay: '[aska g] LT',\n        nextWeek: 'dddd [g] LT',\n        lastDay: '[assant g] LT',\n        lastWeek: 'dddd [g] LT',\n        sameElse: 'L'\n    },\n    relativeTime : {\n        future : 'dadkh s yan %s',\n        past : 'yan %s',\n        s : 'imik',\n        m : 'minuḍ',\n        mm : '%d minuḍ',\n        h : 'saɛa',\n        hh : '%d tassaɛin',\n        d : 'ass',\n        dd : '%d ossan',\n        M : 'ayowr',\n        MM : '%d iyyirn',\n        y : 'asgas',\n        yy : '%d isgasn'\n    },\n    week : {\n        dow : 6, // Saturday is the first day of the week.\n        doy : 12  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Central Atlas Tamazight [tzm]\n//! author : Abdel Said : https://github.com/abdelsaid\n\nhooks.defineLocale('tzm', {\n    months : 'ⵉⵏⵏⴰⵢⵔ_ⴱⵕⴰⵢⵕ_ⵎⴰⵕⵚ_ⵉⴱⵔⵉⵔ_ⵎⴰⵢⵢⵓ_ⵢⵓⵏⵢⵓ_ⵢⵓⵍⵢⵓⵣ_ⵖⵓⵛⵜ_ⵛⵓⵜⴰⵏⴱⵉⵔ_ⴽⵟⵓⴱⵕ_ⵏⵓⵡⴰⵏⴱⵉⵔ_ⴷⵓⵊⵏⴱⵉⵔ'.split('_'),\n    monthsShort : 'ⵉⵏⵏⴰⵢⵔ_ⴱⵕⴰⵢⵕ_ⵎⴰⵕⵚ_ⵉⴱⵔⵉⵔ_ⵎⴰⵢⵢⵓ_ⵢⵓⵏⵢⵓ_ⵢⵓⵍⵢⵓⵣ_ⵖⵓⵛⵜ_ⵛⵓⵜⴰⵏⴱⵉⵔ_ⴽⵟⵓⴱⵕ_ⵏⵓⵡⴰⵏⴱⵉⵔ_ⴷⵓⵊⵏⴱⵉⵔ'.split('_'),\n    weekdays : 'ⴰⵙⴰⵎⴰⵙ_ⴰⵢⵏⴰⵙ_ⴰⵙⵉⵏⴰⵙ_ⴰⴽⵔⴰⵙ_ⴰⴽⵡⴰⵙ_ⴰⵙⵉⵎⵡⴰⵙ_ⴰⵙⵉⴹⵢⴰⵙ'.split('_'),\n    weekdaysShort : 'ⴰⵙⴰⵎⴰⵙ_ⴰⵢⵏⴰⵙ_ⴰⵙⵉⵏⴰⵙ_ⴰⴽⵔⴰⵙ_ⴰⴽⵡⴰⵙ_ⴰⵙⵉⵎⵡⴰⵙ_ⴰⵙⵉⴹⵢⴰⵙ'.split('_'),\n    weekdaysMin : 'ⴰⵙⴰⵎⴰⵙ_ⴰⵢⵏⴰⵙ_ⴰⵙⵉⵏⴰⵙ_ⴰⴽⵔⴰⵙ_ⴰⴽⵡⴰⵙ_ⴰⵙⵉⵎⵡⴰⵙ_ⴰⵙⵉⴹⵢⴰⵙ'.split('_'),\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS: 'HH:mm:ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY HH:mm',\n        LLLL : 'dddd D MMMM YYYY HH:mm'\n    },\n    calendar : {\n        sameDay: '[ⴰⵙⴷⵅ ⴴ] LT',\n        nextDay: '[ⴰⵙⴽⴰ ⴴ] LT',\n        nextWeek: 'dddd [ⴴ] LT',\n        lastDay: '[ⴰⵚⴰⵏⵜ ⴴ] LT',\n        lastWeek: 'dddd [ⴴ] LT',\n        sameElse: 'L'\n    },\n    relativeTime : {\n        future : 'ⴷⴰⴷⵅ ⵙ ⵢⴰⵏ %s',\n        past : 'ⵢⴰⵏ %s',\n        s : 'ⵉⵎⵉⴽ',\n        m : 'ⵎⵉⵏⵓⴺ',\n        mm : '%d ⵎⵉⵏⵓⴺ',\n        h : 'ⵙⴰⵄⴰ',\n        hh : '%d ⵜⴰⵙⵙⴰⵄⵉⵏ',\n        d : 'ⴰⵙⵙ',\n        dd : '%d oⵙⵙⴰⵏ',\n        M : 'ⴰⵢoⵓⵔ',\n        MM : '%d ⵉⵢⵢⵉⵔⵏ',\n        y : 'ⴰⵙⴳⴰⵙ',\n        yy : '%d ⵉⵙⴳⴰⵙⵏ'\n    },\n    week : {\n        dow : 6, // Saturday is the first day of the week.\n        doy : 12  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Ukrainian [uk]\n//! author : zemlanin : https://github.com/zemlanin\n//! Author : Menelion Elensúle : https://github.com/Oire\n\nfunction plural$6(word, num) {\n    var forms = word.split('_');\n    return num % 10 === 1 && num % 100 !== 11 ? forms[0] : (num % 10 >= 2 && num % 10 <= 4 && (num % 100 < 10 || num % 100 >= 20) ? forms[1] : forms[2]);\n}\nfunction relativeTimeWithPlural$4(number, withoutSuffix, key) {\n    var format = {\n        'mm': withoutSuffix ? 'хвилина_хвилини_хвилин' : 'хвилину_хвилини_хвилин',\n        'hh': withoutSuffix ? 'година_години_годин' : 'годину_години_годин',\n        'dd': 'день_дні_днів',\n        'MM': 'місяць_місяці_місяців',\n        'yy': 'рік_роки_років'\n    };\n    if (key === 'm') {\n        return withoutSuffix ? 'хвилина' : 'хвилину';\n    }\n    else if (key === 'h') {\n        return withoutSuffix ? 'година' : 'годину';\n    }\n    else {\n        return number + ' ' + plural$6(format[key], +number);\n    }\n}\nfunction weekdaysCaseReplace(m, format) {\n    var weekdays = {\n        'nominative': 'неділя_понеділок_вівторок_середа_четвер_п’ятниця_субота'.split('_'),\n        'accusative': 'неділю_понеділок_вівторок_середу_четвер_п’ятницю_суботу'.split('_'),\n        'genitive': 'неділі_понеділка_вівторка_середи_четверга_п’ятниці_суботи'.split('_')\n    };\n\n    if (!m) {\n        return weekdays['nominative'];\n    }\n\n    var nounCase = (/(\\[[ВвУу]\\]) ?dddd/).test(format) ?\n        'accusative' :\n        ((/\\[?(?:минулої|наступної)? ?\\] ?dddd/).test(format) ?\n            'genitive' :\n            'nominative');\n    return weekdays[nounCase][m.day()];\n}\nfunction processHoursFunction(str) {\n    return function () {\n        return str + 'о' + (this.hours() === 11 ? 'б' : '') + '] LT';\n    };\n}\n\nhooks.defineLocale('uk', {\n    months : {\n        'format': 'січня_лютого_березня_квітня_травня_червня_липня_серпня_вересня_жовтня_листопада_грудня'.split('_'),\n        'standalone': 'січень_лютий_березень_квітень_травень_червень_липень_серпень_вересень_жовтень_листопад_грудень'.split('_')\n    },\n    monthsShort : 'січ_лют_бер_квіт_трав_черв_лип_серп_вер_жовт_лист_груд'.split('_'),\n    weekdays : weekdaysCaseReplace,\n    weekdaysShort : 'нд_пн_вт_ср_чт_пт_сб'.split('_'),\n    weekdaysMin : 'нд_пн_вт_ср_чт_пт_сб'.split('_'),\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD.MM.YYYY',\n        LL : 'D MMMM YYYY р.',\n        LLL : 'D MMMM YYYY р., HH:mm',\n        LLLL : 'dddd, D MMMM YYYY р., HH:mm'\n    },\n    calendar : {\n        sameDay: processHoursFunction('[Сьогодні '),\n        nextDay: processHoursFunction('[Завтра '),\n        lastDay: processHoursFunction('[Вчора '),\n        nextWeek: processHoursFunction('[У] dddd ['),\n        lastWeek: function () {\n            switch (this.day()) {\n                case 0:\n                case 3:\n                case 5:\n                case 6:\n                    return processHoursFunction('[Минулої] dddd [').call(this);\n                case 1:\n                case 2:\n                case 4:\n                    return processHoursFunction('[Минулого] dddd [').call(this);\n            }\n        },\n        sameElse: 'L'\n    },\n    relativeTime : {\n        future : 'за %s',\n        past : '%s тому',\n        s : 'декілька секунд',\n        m : relativeTimeWithPlural$4,\n        mm : relativeTimeWithPlural$4,\n        h : 'годину',\n        hh : relativeTimeWithPlural$4,\n        d : 'день',\n        dd : relativeTimeWithPlural$4,\n        M : 'місяць',\n        MM : relativeTimeWithPlural$4,\n        y : 'рік',\n        yy : relativeTimeWithPlural$4\n    },\n    // M. E.: those two are virtually unused but a user might want to implement them for his/her website for some reason\n    meridiemParse: /ночі|ранку|дня|вечора/,\n    isPM: function (input) {\n        return /^(дня|вечора)$/.test(input);\n    },\n    meridiem : function (hour, minute, isLower) {\n        if (hour < 4) {\n            return 'ночі';\n        } else if (hour < 12) {\n            return 'ранку';\n        } else if (hour < 17) {\n            return 'дня';\n        } else {\n            return 'вечора';\n        }\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}-(й|го)/,\n    ordinal: function (number, period) {\n        switch (period) {\n            case 'M':\n            case 'd':\n            case 'DDD':\n            case 'w':\n            case 'W':\n                return number + '-й';\n            case 'D':\n                return number + '-го';\n            default:\n                return number;\n        }\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 7  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Urdu [ur]\n//! author : Sawood Alam : https://github.com/ibnesayeed\n//! author : Zack : https://github.com/ZackVision\n\nvar months$8 = [\n    'جنوری',\n    'فروری',\n    'مارچ',\n    'اپریل',\n    'مئی',\n    'جون',\n    'جولائی',\n    'اگست',\n    'ستمبر',\n    'اکتوبر',\n    'نومبر',\n    'دسمبر'\n];\nvar days$2 = [\n    'اتوار',\n    'پیر',\n    'منگل',\n    'بدھ',\n    'جمعرات',\n    'جمعہ',\n    'ہفتہ'\n];\n\nhooks.defineLocale('ur', {\n    months : months$8,\n    monthsShort : months$8,\n    weekdays : days$2,\n    weekdaysShort : days$2,\n    weekdaysMin : days$2,\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY HH:mm',\n        LLLL : 'dddd، D MMMM YYYY HH:mm'\n    },\n    meridiemParse: /صبح|شام/,\n    isPM : function (input) {\n        return 'شام' === input;\n    },\n    meridiem : function (hour, minute, isLower) {\n        if (hour < 12) {\n            return 'صبح';\n        }\n        return 'شام';\n    },\n    calendar : {\n        sameDay : '[آج بوقت] LT',\n        nextDay : '[کل بوقت] LT',\n        nextWeek : 'dddd [بوقت] LT',\n        lastDay : '[گذشتہ روز بوقت] LT',\n        lastWeek : '[گذشتہ] dddd [بوقت] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : '%s بعد',\n        past : '%s قبل',\n        s : 'چند سیکنڈ',\n        m : 'ایک منٹ',\n        mm : '%d منٹ',\n        h : 'ایک گھنٹہ',\n        hh : '%d گھنٹے',\n        d : 'ایک دن',\n        dd : '%d دن',\n        M : 'ایک ماہ',\n        MM : '%d ماہ',\n        y : 'ایک سال',\n        yy : '%d سال'\n    },\n    preparse: function (string) {\n        return string.replace(/،/g, ',');\n    },\n    postformat: function (string) {\n        return string.replace(/,/g, '،');\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Uzbek Latin [uz-latn]\n//! author : Rasulbek Mirzayev : github.com/Rasulbeeek\n\nhooks.defineLocale('uz-latn', {\n    months : 'Yanvar_Fevral_Mart_Aprel_May_Iyun_Iyul_Avgust_Sentabr_Oktabr_Noyabr_Dekabr'.split('_'),\n    monthsShort : 'Yan_Fev_Mar_Apr_May_Iyun_Iyul_Avg_Sen_Okt_Noy_Dek'.split('_'),\n    weekdays : 'Yakshanba_Dushanba_Seshanba_Chorshanba_Payshanba_Juma_Shanba'.split('_'),\n    weekdaysShort : 'Yak_Dush_Sesh_Chor_Pay_Jum_Shan'.split('_'),\n    weekdaysMin : 'Ya_Du_Se_Cho_Pa_Ju_Sha'.split('_'),\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY HH:mm',\n        LLLL : 'D MMMM YYYY, dddd HH:mm'\n    },\n    calendar : {\n        sameDay : '[Bugun soat] LT [da]',\n        nextDay : '[Ertaga] LT [da]',\n        nextWeek : 'dddd [kuni soat] LT [da]',\n        lastDay : '[Kecha soat] LT [da]',\n        lastWeek : '[O\\'tgan] dddd [kuni soat] LT [da]',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'Yaqin %s ichida',\n        past : 'Bir necha %s oldin',\n        s : 'soniya',\n        m : 'bir daqiqa',\n        mm : '%d daqiqa',\n        h : 'bir soat',\n        hh : '%d soat',\n        d : 'bir kun',\n        dd : '%d kun',\n        M : 'bir oy',\n        MM : '%d oy',\n        y : 'bir yil',\n        yy : '%d yil'\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 7  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Uzbek [uz]\n//! author : Sardor Muminov : https://github.com/muminoff\n\nhooks.defineLocale('uz', {\n    months : 'январ_феврал_март_апрел_май_июн_июл_август_сентябр_октябр_ноябр_декабр'.split('_'),\n    monthsShort : 'янв_фев_мар_апр_май_июн_июл_авг_сен_окт_ноя_дек'.split('_'),\n    weekdays : 'Якшанба_Душанба_Сешанба_Чоршанба_Пайшанба_Жума_Шанба'.split('_'),\n    weekdaysShort : 'Якш_Душ_Сеш_Чор_Пай_Жум_Шан'.split('_'),\n    weekdaysMin : 'Як_Ду_Се_Чо_Па_Жу_Ша'.split('_'),\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY HH:mm',\n        LLLL : 'D MMMM YYYY, dddd HH:mm'\n    },\n    calendar : {\n        sameDay : '[Бугун соат] LT [да]',\n        nextDay : '[Эртага] LT [да]',\n        nextWeek : 'dddd [куни соат] LT [да]',\n        lastDay : '[Кеча соат] LT [да]',\n        lastWeek : '[Утган] dddd [куни соат] LT [да]',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'Якин %s ичида',\n        past : 'Бир неча %s олдин',\n        s : 'фурсат',\n        m : 'бир дакика',\n        mm : '%d дакика',\n        h : 'бир соат',\n        hh : '%d соат',\n        d : 'бир кун',\n        dd : '%d кун',\n        M : 'бир ой',\n        MM : '%d ой',\n        y : 'бир йил',\n        yy : '%d йил'\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 7  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Vietnamese [vi]\n//! author : Bang Nguyen : https://github.com/bangnk\n\nhooks.defineLocale('vi', {\n    months : 'tháng 1_tháng 2_tháng 3_tháng 4_tháng 5_tháng 6_tháng 7_tháng 8_tháng 9_tháng 10_tháng 11_tháng 12'.split('_'),\n    monthsShort : 'Th01_Th02_Th03_Th04_Th05_Th06_Th07_Th08_Th09_Th10_Th11_Th12'.split('_'),\n    monthsParseExact : true,\n    weekdays : 'chủ nhật_thứ hai_thứ ba_thứ tư_thứ năm_thứ sáu_thứ bảy'.split('_'),\n    weekdaysShort : 'CN_T2_T3_T4_T5_T6_T7'.split('_'),\n    weekdaysMin : 'CN_T2_T3_T4_T5_T6_T7'.split('_'),\n    weekdaysParseExact : true,\n    meridiemParse: /sa|ch/i,\n    isPM : function (input) {\n        return /^ch$/i.test(input);\n    },\n    meridiem : function (hours, minutes, isLower) {\n        if (hours < 12) {\n            return isLower ? 'sa' : 'SA';\n        } else {\n            return isLower ? 'ch' : 'CH';\n        }\n    },\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM [năm] YYYY',\n        LLL : 'D MMMM [năm] YYYY HH:mm',\n        LLLL : 'dddd, D MMMM [năm] YYYY HH:mm',\n        l : 'DD/M/YYYY',\n        ll : 'D MMM YYYY',\n        lll : 'D MMM YYYY HH:mm',\n        llll : 'ddd, D MMM YYYY HH:mm'\n    },\n    calendar : {\n        sameDay: '[Hôm nay lúc] LT',\n        nextDay: '[Ngày mai lúc] LT',\n        nextWeek: 'dddd [tuần tới lúc] LT',\n        lastDay: '[Hôm qua lúc] LT',\n        lastWeek: 'dddd [tuần rồi lúc] LT',\n        sameElse: 'L'\n    },\n    relativeTime : {\n        future : '%s tới',\n        past : '%s trước',\n        s : 'vài giây',\n        m : 'một phút',\n        mm : '%d phút',\n        h : 'một giờ',\n        hh : '%d giờ',\n        d : 'một ngày',\n        dd : '%d ngày',\n        M : 'một tháng',\n        MM : '%d tháng',\n        y : 'một năm',\n        yy : '%d năm'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}/,\n    ordinal : function (number) {\n        return number;\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Pseudo [x-pseudo]\n//! author : Andrew Hood : https://github.com/andrewhood125\n\nhooks.defineLocale('x-pseudo', {\n    months : 'J~áñúá~rý_F~ébrú~árý_~Márc~h_Áp~ríl_~Máý_~Júñé~_Júl~ý_Áú~gúst~_Sép~témb~ér_Ó~ctób~ér_Ñ~óvém~bér_~Décé~mbér'.split('_'),\n    monthsShort : 'J~áñ_~Féb_~Már_~Ápr_~Máý_~Júñ_~Júl_~Áúg_~Sép_~Óct_~Ñóv_~Déc'.split('_'),\n    monthsParseExact : true,\n    weekdays : 'S~úñdá~ý_Mó~ñdáý~_Túé~sdáý~_Wéd~ñésd~áý_T~húrs~dáý_~Fríd~áý_S~átúr~dáý'.split('_'),\n    weekdaysShort : 'S~úñ_~Móñ_~Túé_~Wéd_~Thú_~Frí_~Sát'.split('_'),\n    weekdaysMin : 'S~ú_Mó~_Tú_~Wé_T~h_Fr~_Sá'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat : {\n        LT : 'HH:mm',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY HH:mm',\n        LLLL : 'dddd, D MMMM YYYY HH:mm'\n    },\n    calendar : {\n        sameDay : '[T~ódá~ý át] LT',\n        nextDay : '[T~ómó~rró~w át] LT',\n        nextWeek : 'dddd [át] LT',\n        lastDay : '[Ý~ést~érdá~ý át] LT',\n        lastWeek : '[L~ást] dddd [át] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'í~ñ %s',\n        past : '%s á~gó',\n        s : 'á ~féw ~sécó~ñds',\n        m : 'á ~míñ~úté',\n        mm : '%d m~íñú~tés',\n        h : 'á~ñ hó~úr',\n        hh : '%d h~óúrs',\n        d : 'á ~dáý',\n        dd : '%d d~áýs',\n        M : 'á ~móñ~th',\n        MM : '%d m~óñt~hs',\n        y : 'á ~ýéár',\n        yy : '%d ý~éárs'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}(th|st|nd|rd)/,\n    ordinal : function (number) {\n        var b = number % 10,\n            output = (~~(number % 100 / 10) === 1) ? 'th' :\n            (b === 1) ? 'st' :\n            (b === 2) ? 'nd' :\n            (b === 3) ? 'rd' : 'th';\n        return number + output;\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Yoruba Nigeria [yo]\n//! author : Atolagbe Abisoye : https://github.com/andela-batolagbe\n\nhooks.defineLocale('yo', {\n    months : 'Sẹ́rẹ́_Èrèlè_Ẹrẹ̀nà_Ìgbé_Èbibi_Òkùdu_Agẹmo_Ògún_Owewe_Ọ̀wàrà_Bélú_Ọ̀pẹ̀̀'.split('_'),\n    monthsShort : 'Sẹ́r_Èrl_Ẹrn_Ìgb_Èbi_Òkù_Agẹ_Ògú_Owe_Ọ̀wà_Bél_Ọ̀pẹ̀̀'.split('_'),\n    weekdays : 'Àìkú_Ajé_Ìsẹ́gun_Ọjọ́rú_Ọjọ́bọ_Ẹtì_Àbámẹ́ta'.split('_'),\n    weekdaysShort : 'Àìk_Ajé_Ìsẹ́_Ọjr_Ọjb_Ẹtì_Àbá'.split('_'),\n    weekdaysMin : 'Àì_Aj_Ìs_Ọr_Ọb_Ẹt_Àb'.split('_'),\n    longDateFormat : {\n        LT : 'h:mm A',\n        LTS : 'h:mm:ss A',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY h:mm A',\n        LLLL : 'dddd, D MMMM YYYY h:mm A'\n    },\n    calendar : {\n        sameDay : '[Ònì ni] LT',\n        nextDay : '[Ọ̀la ni] LT',\n        nextWeek : 'dddd [Ọsẹ̀ tón\\'bọ] [ni] LT',\n        lastDay : '[Àna ni] LT',\n        lastWeek : 'dddd [Ọsẹ̀ tólọ́] [ni] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'ní %s',\n        past : '%s kọjá',\n        s : 'ìsẹjú aayá die',\n        m : 'ìsẹjú kan',\n        mm : 'ìsẹjú %d',\n        h : 'wákati kan',\n        hh : 'wákati %d',\n        d : 'ọjọ́ kan',\n        dd : 'ọjọ́ %d',\n        M : 'osù kan',\n        MM : 'osù %d',\n        y : 'ọdún kan',\n        yy : 'ọdún %d'\n    },\n    dayOfMonthOrdinalParse : /ọjọ́\\s\\d{1,2}/,\n    ordinal : 'ọjọ́ %d',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4 // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Chinese (China) [zh-cn]\n//! author : suupic : https://github.com/suupic\n//! author : Zeno Zeng : https://github.com/zenozeng\n\nhooks.defineLocale('zh-cn', {\n    months : '一月_二月_三月_四月_五月_六月_七月_八月_九月_十月_十一月_十二月'.split('_'),\n    monthsShort : '1月_2月_3月_4月_5月_6月_7月_8月_9月_10月_11月_12月'.split('_'),\n    weekdays : '星期日_星期一_星期二_星期三_星期四_星期五_星期六'.split('_'),\n    weekdaysShort : '周日_周一_周二_周三_周四_周五_周六'.split('_'),\n    weekdaysMin : '日_一_二_三_四_五_六'.split('_'),\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'YYYY年MMMD日',\n        LL : 'YYYY年MMMD日',\n        LLL : 'YYYY年MMMD日Ah点mm分',\n        LLLL : 'YYYY年MMMD日ddddAh点mm分',\n        l : 'YYYY年MMMD日',\n        ll : 'YYYY年MMMD日',\n        lll : 'YYYY年MMMD日 HH:mm',\n        llll : 'YYYY年MMMD日dddd HH:mm'\n    },\n    meridiemParse: /凌晨|早上|上午|中午|下午|晚上/,\n    meridiemHour: function (hour, meridiem) {\n        if (hour === 12) {\n            hour = 0;\n        }\n        if (meridiem === '凌晨' || meridiem === '早上' ||\n                meridiem === '上午') {\n            return hour;\n        } else if (meridiem === '下午' || meridiem === '晚上') {\n            return hour + 12;\n        } else {\n            // '中午'\n            return hour >= 11 ? hour : hour + 12;\n        }\n    },\n    meridiem : function (hour, minute, isLower) {\n        var hm = hour * 100 + minute;\n        if (hm < 600) {\n            return '凌晨';\n        } else if (hm < 900) {\n            return '早上';\n        } else if (hm < 1130) {\n            return '上午';\n        } else if (hm < 1230) {\n            return '中午';\n        } else if (hm < 1800) {\n            return '下午';\n        } else {\n            return '晚上';\n        }\n    },\n    calendar : {\n        sameDay : '[今天]LT',\n        nextDay : '[明天]LT',\n        nextWeek : '[下]ddddLT',\n        lastDay : '[昨天]LT',\n        lastWeek : '[上]ddddLT',\n        sameElse : 'L'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}(日|月|周)/,\n    ordinal : function (number, period) {\n        switch (period) {\n            case 'd':\n            case 'D':\n            case 'DDD':\n                return number + '日';\n            case 'M':\n                return number + '月';\n            case 'w':\n            case 'W':\n                return number + '周';\n            default:\n                return number;\n        }\n    },\n    relativeTime : {\n        future : '%s内',\n        past : '%s前',\n        s : '几秒',\n        m : '1 分钟',\n        mm : '%d 分钟',\n        h : '1 小时',\n        hh : '%d 小时',\n        d : '1 天',\n        dd : '%d 天',\n        M : '1 个月',\n        MM : '%d 个月',\n        y : '1 年',\n        yy : '%d 年'\n    },\n    week : {\n        // GB/T 7408-1994《数据元和交换格式·信息交换·日期和时间表示法》与ISO 8601:1988等效\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Chinese (Hong Kong) [zh-hk]\n//! author : Ben : https://github.com/ben-lin\n//! author : Chris Lam : https://github.com/hehachris\n//! author : Konstantin : https://github.com/skfd\n\nhooks.defineLocale('zh-hk', {\n    months : '一月_二月_三月_四月_五月_六月_七月_八月_九月_十月_十一月_十二月'.split('_'),\n    monthsShort : '1月_2月_3月_4月_5月_6月_7月_8月_9月_10月_11月_12月'.split('_'),\n    weekdays : '星期日_星期一_星期二_星期三_星期四_星期五_星期六'.split('_'),\n    weekdaysShort : '週日_週一_週二_週三_週四_週五_週六'.split('_'),\n    weekdaysMin : '日_一_二_三_四_五_六'.split('_'),\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'YYYY年MMMD日',\n        LL : 'YYYY年MMMD日',\n        LLL : 'YYYY年MMMD日 HH:mm',\n        LLLL : 'YYYY年MMMD日dddd HH:mm',\n        l : 'YYYY年MMMD日',\n        ll : 'YYYY年MMMD日',\n        lll : 'YYYY年MMMD日 HH:mm',\n        llll : 'YYYY年MMMD日dddd HH:mm'\n    },\n    meridiemParse: /凌晨|早上|上午|中午|下午|晚上/,\n    meridiemHour : function (hour, meridiem) {\n        if (hour === 12) {\n            hour = 0;\n        }\n        if (meridiem === '凌晨' || meridiem === '早上' || meridiem === '上午') {\n            return hour;\n        } else if (meridiem === '中午') {\n            return hour >= 11 ? hour : hour + 12;\n        } else if (meridiem === '下午' || meridiem === '晚上') {\n            return hour + 12;\n        }\n    },\n    meridiem : function (hour, minute, isLower) {\n        var hm = hour * 100 + minute;\n        if (hm < 600) {\n            return '凌晨';\n        } else if (hm < 900) {\n            return '早上';\n        } else if (hm < 1130) {\n            return '上午';\n        } else if (hm < 1230) {\n            return '中午';\n        } else if (hm < 1800) {\n            return '下午';\n        } else {\n            return '晚上';\n        }\n    },\n    calendar : {\n        sameDay : '[今天]LT',\n        nextDay : '[明天]LT',\n        nextWeek : '[下]ddddLT',\n        lastDay : '[昨天]LT',\n        lastWeek : '[上]ddddLT',\n        sameElse : 'L'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}(日|月|週)/,\n    ordinal : function (number, period) {\n        switch (period) {\n            case 'd' :\n            case 'D' :\n            case 'DDD' :\n                return number + '日';\n            case 'M' :\n                return number + '月';\n            case 'w' :\n            case 'W' :\n                return number + '週';\n            default :\n                return number;\n        }\n    },\n    relativeTime : {\n        future : '%s內',\n        past : '%s前',\n        s : '幾秒',\n        m : '1 分鐘',\n        mm : '%d 分鐘',\n        h : '1 小時',\n        hh : '%d 小時',\n        d : '1 天',\n        dd : '%d 天',\n        M : '1 個月',\n        MM : '%d 個月',\n        y : '1 年',\n        yy : '%d 年'\n    }\n});\n\n//! moment.js locale configuration\n//! locale : Chinese (Taiwan) [zh-tw]\n//! author : Ben : https://github.com/ben-lin\n//! author : Chris Lam : https://github.com/hehachris\n\nhooks.defineLocale('zh-tw', {\n    months : '一月_二月_三月_四月_五月_六月_七月_八月_九月_十月_十一月_十二月'.split('_'),\n    monthsShort : '1月_2月_3月_4月_5月_6月_7月_8月_9月_10月_11月_12月'.split('_'),\n    weekdays : '星期日_星期一_星期二_星期三_星期四_星期五_星期六'.split('_'),\n    weekdaysShort : '週日_週一_週二_週三_週四_週五_週六'.split('_'),\n    weekdaysMin : '日_一_二_三_四_五_六'.split('_'),\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'YYYY年MMMD日',\n        LL : 'YYYY年MMMD日',\n        LLL : 'YYYY年MMMD日 HH:mm',\n        LLLL : 'YYYY年MMMD日dddd HH:mm',\n        l : 'YYYY年MMMD日',\n        ll : 'YYYY年MMMD日',\n        lll : 'YYYY年MMMD日 HH:mm',\n        llll : 'YYYY年MMMD日dddd HH:mm'\n    },\n    meridiemParse: /凌晨|早上|上午|中午|下午|晚上/,\n    meridiemHour : function (hour, meridiem) {\n        if (hour === 12) {\n            hour = 0;\n        }\n        if (meridiem === '凌晨' || meridiem === '早上' || meridiem === '上午') {\n            return hour;\n        } else if (meridiem === '中午') {\n            return hour >= 11 ? hour : hour + 12;\n        } else if (meridiem === '下午' || meridiem === '晚上') {\n            return hour + 12;\n        }\n    },\n    meridiem : function (hour, minute, isLower) {\n        var hm = hour * 100 + minute;\n        if (hm < 600) {\n            return '凌晨';\n        } else if (hm < 900) {\n            return '早上';\n        } else if (hm < 1130) {\n            return '上午';\n        } else if (hm < 1230) {\n            return '中午';\n        } else if (hm < 1800) {\n            return '下午';\n        } else {\n            return '晚上';\n        }\n    },\n    calendar : {\n        sameDay : '[今天]LT',\n        nextDay : '[明天]LT',\n        nextWeek : '[下]ddddLT',\n        lastDay : '[昨天]LT',\n        lastWeek : '[上]ddddLT',\n        sameElse : 'L'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}(日|月|週)/,\n    ordinal : function (number, period) {\n        switch (period) {\n            case 'd' :\n            case 'D' :\n            case 'DDD' :\n                return number + '日';\n            case 'M' :\n                return number + '月';\n            case 'w' :\n            case 'W' :\n                return number + '週';\n            default :\n                return number;\n        }\n    },\n    relativeTime : {\n        future : '%s內',\n        past : '%s前',\n        s : '幾秒',\n        m : '1 分鐘',\n        mm : '%d 分鐘',\n        h : '1 小時',\n        hh : '%d 小時',\n        d : '1 天',\n        dd : '%d 天',\n        M : '1 個月',\n        MM : '%d 個月',\n        y : '1 年',\n        yy : '%d 年'\n    }\n});\n\nhooks.locale('en');\n\nreturn hooks;\n\n})));\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/min/tests.js",
    "content": "\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\n\n\nfunction localeModule (name, lifecycle) {\n    QUnit.module('locale:' + name, {\n        setup : function () {\n            moment.locale(name);\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            moment.locale('en');\n            teardownDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n    defineCommonLocaleTests(name, -1, -1);\n}\n\nlocaleModule('af');\n\ntest('parse', function (assert) {\n    var tests = 'Januarie Jan_Februarie Feb_Maart Mrt_April Apr_Mei Mei_Junie Jun_Julie Jul_Augustus Aug_September Sep_Oktober Okt_November Nov_Desember Des'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, MMMM Do YYYY, h:mm:ss a',      'Sondag, Februarie 14de 2010, 3:25:50 nm'],\n            ['ddd, hA',                            'Son, 3NM'],\n            ['M Mo MM MMMM MMM',                   '2 2de 02 Februarie Feb'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14de 14'],\n            ['d do dddd ddd dd',                   '0 0de Sondag Son So'],\n            ['DDD DDDo DDDD',                      '45 45ste 045'],\n            ['w wo ww',                            '6 6de 06'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'nm NM'],\n            ['[the] DDDo [day of the year]',       'the 45ste day of the year'],\n            ['LT',                                 '15:25'],\n            ['LTS',                                '15:25:50'],\n            ['L',                                  '14/02/2010'],\n            ['LL',                                 '14 Februarie 2010'],\n            ['LLL',                                '14 Februarie 2010 15:25'],\n            ['LLLL',                               'Sondag, 14 Februarie 2010 15:25'],\n            ['l',                                  '14/2/2010'],\n            ['ll',                                 '14 Feb 2010'],\n            ['lll',                                '14 Feb 2010 15:25'],\n            ['llll',                               'Son, 14 Feb 2010 15:25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1ste', '1ste');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2de', '2de');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3de', '3de');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4de', '4de');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5de', '5de');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6de', '6de');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7de', '7de');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8ste', '8ste');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9de', '9de');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10de', '10de');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11de', '11de');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12de', '12de');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13de', '13de');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14de', '14de');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15de', '15de');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16de', '16de');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17de', '17de');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18de', '18de');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19de', '19de');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20ste', '20ste');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21ste', '21ste');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22ste', '22ste');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23ste', '23ste');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24ste', '24ste');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25ste', '25ste');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26ste', '26ste');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27ste', '27ste');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28ste', '28ste');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29ste', '29ste');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30ste', '30ste');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31ste', '31ste');\n});\n\ntest('format month', function (assert) {\n    var expected = 'Januarie Jan_Februarie Feb_Maart Mrt_April Apr_Mei Mei_Junie Jun_Julie Jul_Augustus Aug_September Sep_Oktober Okt_November Nov_Desember Des'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'Sondag Son So_Maandag Maa Ma_Dinsdag Din Di_Woensdag Woe Wo_Donderdag Don Do_Vrydag Vry Vr_Saterdag Sat Sa'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  '\\'n paar sekondes', '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  '\\'n minuut',      '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  '\\'n minuut',      '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 minute',     '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 minute',    '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  '\\'n uur',       '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  '\\'n uur',       '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 ure',       '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 ure',       '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 ure',      '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  '\\'n dag',         '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  '\\'n dag',         '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 dae',        '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   '\\'n dag',         '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 dae',        '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 dae',       '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  '\\'n maand',       '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  '\\'n maand',       '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  '\\'n maand',       '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 maande',      '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 maande',      '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 maande',      '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   '\\'n maand',       '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 maande',      '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), '\\'n jaar',        '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 jaar',       '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   '\\'n jaar',        '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 jaar',       '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'oor \\'n paar sekondes',  'prefix');\n    assert.equal(moment(0).from(30000), '\\'n paar sekondes gelede', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), '\\'n paar sekondes gelede',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'oor \\'n paar sekondes', 'in a few seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), 'oor 5 dae', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'Vandag om 12:00',     'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'Vandag om 12:25',     'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'Vandag om 13:00',     'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'Môre om 12:00',       'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'Vandag om 11:00',     'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'Gister om 12:00',     'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('dddd [om] LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd [om] LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd [om] LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('[Laas] dddd [om] LT'),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[Laas] dddd [om] LT'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[Laas] dddd [om] LT'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2012, 0,  1]).format('w ww wo'), '52 52 52ste', 'Jan  1 2012 should be week 52');\n    assert.equal(moment([2012, 0,  2]).format('w ww wo'),   '1 01 1ste', 'Jan  2 2012 should be week 1');\n    assert.equal(moment([2012, 0,  8]).format('w ww wo'),   '1 01 1ste', 'Jan  8 2012 should be week 1');\n    assert.equal(moment([2012, 0,  9]).format('w ww wo'),    '2 02 2de', 'Jan  9 2012 should be week 2');\n    assert.equal(moment([2012, 0, 15]).format('w ww wo'),    '2 02 2de', 'Jan 15 2012 should be week 2');\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\n\n\nfunction localeModule (name, lifecycle) {\n    QUnit.module('locale:' + name, {\n        setup : function () {\n            moment.locale(name);\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            moment.locale('en');\n            teardownDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n    defineCommonLocaleTests(name, -1, -1);\n}\n\nlocaleModule('ar-dz');\n\ntest('parse', function (assert) {\n    var tests = 'جانفي:جانفي_فيفري:فيفري_مارس:مارس_أفريل:أفريل_ماي:ماي_جوان:جوان_جويلية:جويلية_أوت:أوت_سبتمبر:سبتمبر_أكتوبر:أكتوبر_نوفمبر:نوفمبر_ديسمبر:ديسمبر'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(':');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, MMMM Do YYYY, h:mm:ss a',      'الأحد, فيفري 14 2010, 3:25:50 pm'],\n            ['ddd, hA',                            'احد, 3PM'],\n            ['M Mo MM MMMM MMM',                   '2 2 02 فيفري فيفري'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14 14'],\n            ['d do dddd ddd dd',                   '0 0 الأحد احد أح'],\n            ['DDD DDDo DDDD',                      '45 45 045'],\n            ['w wo ww',                            '7 7 07'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'pm PM'],\n            ['[the] DDDo [day of the year]',       'the 45 day of the year'],\n            ['LT',                                 '15:25'],\n            ['LTS',                                '15:25:50'],\n            ['L',                                  '14/02/2010'],\n            ['LL',                                 '14 فيفري 2010'],\n            ['LLL',                                '14 فيفري 2010 15:25'],\n            ['LLLL',                               'الأحد 14 فيفري 2010 15:25'],\n            ['l',                                  '14/2/2010'],\n            ['ll',                                 '14 فيفري 2010'],\n            ['lll',                                '14 فيفري 2010 15:25'],\n            ['llll',                               'احد 14 فيفري 2010 15:25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1', '1');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2', '2');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3', '3');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4', '4');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5', '5');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6', '6');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7', '7');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8', '8');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9', '9');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10', '10');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11', '11');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12', '12');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13', '13');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14', '14');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15', '15');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16', '16');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17', '17');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18', '18');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19', '19');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20', '20');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21', '21');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22', '22');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23', '23');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24', '24');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25', '25');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26', '26');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27', '27');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28', '28');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29', '29');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30', '30');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31', '31');\n});\n\ntest('format month', function (assert) {\n    var expected = 'جانفي جانفي_فيفري فيفري_مارس مارس_أفريل أفريل_ماي ماي_جوان جوان_جويلية جويلية_أوت أوت_سبتمبر سبتمبر_أكتوبر أكتوبر_نوفمبر نوفمبر_ديسمبر ديسمبر'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'الأحد احد أح_الإثنين اثنين إث_الثلاثاء ثلاثاء ثلا_الأربعاء اربعاء أر_الخميس خميس خم_الجمعة جمعة جم_السبت سبت سب'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'ثوان', '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'دقيقة',      '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'دقيقة',      '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 دقائق',     '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 دقائق',    '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'ساعة',       '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'ساعة',       '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 ساعات',       '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 ساعات',       '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 ساعات',      '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'يوم',         '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'يوم',         '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 أيام',        '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'يوم',         '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 أيام',        '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 أيام',       '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'شهر',       '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'شهر',       '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'شهر',       '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 أشهر',      '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 أشهر',      '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 أشهر',      '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'شهر',       '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 أشهر',      '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'سنة',        '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 سنوات',       '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'سنة',        '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 سنوات',       '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'في ثوان',  'prefix');\n    assert.equal(moment(0).from(30000), 'منذ ثوان', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'منذ ثوان',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'في ثوان', 'in a few seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), 'في 5 أيام', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'اليوم على الساعة 12:00',     'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'اليوم على الساعة 12:25',     'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'اليوم على الساعة 13:00',     'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'غدا على الساعة 12:00',      'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'اليوم على الساعة 11:00',     'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'أمس على الساعة 12:00',     'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('dddd [على الساعة] LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd [على الساعة] LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd [على الساعة] LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('dddd [على الساعة] LT'),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd [على الساعة] LT'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd [على الساعة] LT'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2016, 1, 4]).format('w ww wo'), '5 05 5', 'Feb 4 2016 should be week 5');\n    assert.equal(moment([2016,  0,  6]).format('w ww wo'), '1 01 1', 'Jan  6 2016 should be week 1');\n    assert.equal(moment([2016,  0,  7]).format('w ww wo'), '1 01 1', 'Jan  7 2016 should be week 1');\n    assert.equal(moment([2016,  0, 13]).format('w ww wo'), '2 02 2', 'Jan 13 2016 should be week 2');\n    assert.equal(moment([2016,  0, 14]).format('w ww wo'), '2 02 2', 'Jan 14 2016 should be week 2');\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\n\n\nfunction localeModule (name, lifecycle) {\n    QUnit.module('locale:' + name, {\n        setup : function () {\n            moment.locale(name);\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            moment.locale('en');\n            teardownDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n    defineCommonLocaleTests(name, -1, -1);\n}\n\nlocaleModule('ar-kw');\n\ntest('parse', function (assert) {\n    var tests = 'يناير:يناير_فبراير:فبراير_مارس:مارس_أبريل:أبريل_ماي:ماي_يونيو:يونيو_يوليوز:يوليوز_غشت:غشت_شتنبر:شتنبر_أكتوبر:أكتوبر_نونبر:نونبر_دجنبر:دجنبر'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(':');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, MMMM Do YYYY, h:mm:ss a',      'الأحد, فبراير 14 2010, 3:25:50 pm'],\n            ['ddd, hA',                            'احد, 3PM'],\n            ['M Mo MM MMMM MMM',                   '2 2 02 فبراير فبراير'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14 14'],\n            ['d do dddd ddd dd',                   '0 0 الأحد احد ح'],\n            ['DDD DDDo DDDD',                      '45 45 045'],\n            ['w wo ww',                            '9 9 09'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'pm PM'],\n            ['[the] DDDo [day of the year]',       'the 45 day of the year'],\n            ['LT',                                 '15:25'],\n            ['LTS',                                '15:25:50'],\n            ['L',                                  '14/02/2010'],\n            ['LL',                                 '14 فبراير 2010'],\n            ['LLL',                                '14 فبراير 2010 15:25'],\n            ['LLLL',                               'الأحد 14 فبراير 2010 15:25'],\n            ['l',                                  '14/2/2010'],\n            ['ll',                                 '14 فبراير 2010'],\n            ['lll',                                '14 فبراير 2010 15:25'],\n            ['llll',                               'احد 14 فبراير 2010 15:25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1', '1');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2', '2');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3', '3');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4', '4');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5', '5');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6', '6');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7', '7');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8', '8');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9', '9');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10', '10');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11', '11');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12', '12');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13', '13');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14', '14');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15', '15');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16', '16');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17', '17');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18', '18');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19', '19');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20', '20');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21', '21');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22', '22');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23', '23');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24', '24');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25', '25');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26', '26');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27', '27');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28', '28');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29', '29');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30', '30');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31', '31');\n});\n\ntest('format month', function (assert) {\n    var expected = 'يناير يناير_فبراير فبراير_مارس مارس_أبريل أبريل_ماي ماي_يونيو يونيو_يوليوز يوليوز_غشت غشت_شتنبر شتنبر_أكتوبر أكتوبر_نونبر نونبر_دجنبر دجنبر'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'الأحد احد ح_الإتنين اتنين ن_الثلاثاء ثلاثاء ث_الأربعاء اربعاء ر_الخميس خميس خ_الجمعة جمعة ج_السبت سبت س'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'ثوان', '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'دقيقة',      '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'دقيقة',      '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 دقائق',     '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 دقائق',    '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'ساعة',       '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'ساعة',       '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 ساعات',       '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 ساعات',       '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 ساعات',      '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'يوم',         '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'يوم',         '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 أيام',        '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'يوم',         '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 أيام',        '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 أيام',       '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'شهر',       '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'شهر',       '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'شهر',       '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 أشهر',      '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 أشهر',      '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 أشهر',      '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'شهر',       '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 أشهر',      '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'سنة',        '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 سنوات',       '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'سنة',        '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 سنوات',       '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'في ثوان',  'prefix');\n    assert.equal(moment(0).from(30000), 'منذ ثوان', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'منذ ثوان',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'في ثوان', 'in a few seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), 'في 5 أيام', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'اليوم على الساعة 12:00',     'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'اليوم على الساعة 12:25',     'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'اليوم على الساعة 13:00',     'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'غدا على الساعة 12:00',      'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'اليوم على الساعة 11:00',     'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'أمس على الساعة 12:00',     'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('dddd [على الساعة] LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd [على الساعة] LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd [على الساعة] LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('dddd [على الساعة] LT'),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd [على الساعة] LT'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd [على الساعة] LT'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2011, 11, 31]).format('w ww wo'), '1 01 1', 'Dec 31 2011 should be week 1');\n    assert.equal(moment([2012,  0,  1]).format('w ww wo'), '2 02 2', 'Jan  1 2012 should be week 2');\n    assert.equal(moment([2012,  0,  8]).format('w ww wo'), '3 03 3', 'Jan  8 2012 should be week 3');\n    assert.equal(moment([2012,  0, 14]).format('w ww wo'), '3 03 3', 'Jan 14 2012 should be week 3');\n    assert.equal(moment([2012,  0, 15]).format('w ww wo'), '4 04 4', 'Jan 15 2012 should be week 4');\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\n\n\nfunction localeModule (name, lifecycle) {\n    QUnit.module('locale:' + name, {\n        setup : function () {\n            moment.locale(name);\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            moment.locale('en');\n            teardownDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n    defineCommonLocaleTests(name, -1, -1);\n}\n\nlocaleModule('ar-ly');\n\nvar months = [\n    'يناير',\n    'فبراير',\n    'مارس',\n    'أبريل',\n    'مايو',\n    'يونيو',\n    'يوليو',\n    'أغسطس',\n    'سبتمبر',\n    'أكتوبر',\n    'نوفمبر',\n    'ديسمبر'\n];\n\ntest('parse', function (assert) {\n    var tests = months, i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1) + ' instead is month ' + moment(input, mmm).month());\n    }\n    for (i = 0; i < 12; i++) {\n        equalTest(tests[i], 'MMM', i);\n        equalTest(tests[i], 'MMM', i);\n        equalTest(tests[i], 'MMMM', i);\n        equalTest(tests[i], 'MMMM', i);\n        equalTest(tests[i].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, MMMM Do YYYY, h:mm:ss a',      'الأحد، فبراير 14 2010، 3:25:50 م'],\n            ['ddd, hA',                            'أحد، 3م'],\n            ['M Mo MM MMMM MMM',                   '2 2 02 فبراير فبراير'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14 14'],\n            ['d do dddd ddd dd',                   '0 0 الأحد أحد ح'],\n            ['DDD DDDo DDDD',                      '45 45 045'],\n            ['w wo ww',                            '8 8 08'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'م م'],\n            ['[the] DDDo [day of the year]',       'the 45 day of the year'],\n            ['LT',                                 '15:25'],\n            ['LTS',                                '15:25:50'],\n            ['L',                                  '14/\\u200f2/\\u200f2010'],\n            ['LL',                                 '14 فبراير 2010'],\n            ['LLL',                                '14 فبراير 2010 15:25'],\n            ['LLLL',                               'الأحد 14 فبراير 2010 15:25'],\n            ['l',                                  '14/\\u200f2/\\u200f2010'],\n            ['ll',                                 '14 فبراير 2010'],\n            ['lll',                                '14 فبراير 2010 15:25'],\n            ['llll',                               'أحد 14 فبراير 2010 15:25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1', '1');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2', '2');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3', '3');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4', '4');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5', '5');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6', '6');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7', '7');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8', '8');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9', '9');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10', '10');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11', '11');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12', '12');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13', '13');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14', '14');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15', '15');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16', '16');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17', '17');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18', '18');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19', '19');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20', '20');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21', '21');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22', '22');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23', '23');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24', '24');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25', '25');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26', '26');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27', '27');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28', '28');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29', '29');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30', '30');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31', '31');\n});\n\ntest('format month', function (assert) {\n    var expected = months, i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM'), expected[i], expected[i]);\n        assert.equal(moment([2011, i, 1]).format('MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'الأحد أحد ح_الإثنين إثنين ن_الثلاثاء ثلاثاء ث_الأربعاء أربعاء ر_الخميس خميس خ_الجمعة جمعة ج_السبت سبت س'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  '44 ثانية', '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'دقيقة واحدة',      '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'دقيقة واحدة',      '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  'دقيقتان',     '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 دقيقة',    '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'ساعة واحدة',       '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'ساعة واحدة',       '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  'ساعتان',       '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 ساعات',       '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 ساعة',      '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'يوم واحد',         '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'يوم واحد',         '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  'يومان',        '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'يوم واحد',         '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 أيام',        '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 يومًا',       '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'شهر واحد',       '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'شهر واحد',       '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'شهر واحد',       '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  'شهران',      '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  'شهران',      '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 أشهر',      '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'شهر واحد',       '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 أشهر',      '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'عام واحد',        '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), 'عامان',       '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'عام واحد',        '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 أعوام',       '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'بعد 30 ثانية',  'prefix');\n    assert.equal(moment(0).from(30000), 'منذ 30 ثانية', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'منذ ثانية واحدة',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'بعد 30 ثانية', 'in a few seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), 'بعد 5 أيام', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'اليوم عند الساعة 12:00',     'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'اليوم عند الساعة 12:25',     'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'اليوم عند الساعة 13:00',     'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'غدًا عند الساعة 12:00',      'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'اليوم عند الساعة 11:00',     'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'أمس عند الساعة 12:00',       'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('dddd [عند الساعة] LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd [عند الساعة] LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd [عند الساعة] LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('dddd [عند الساعة] LT'),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd [عند الساعة] LT'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd [عند الساعة] LT'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('weeks year starting wednesday custom', function (assert) {\n    assert.equal(moment('2003 1 6', 'gggg w d').format('YYYY-MM-DD'), '2002-12-28', 'Week 1 of 2003 should be Dec 28 2002');\n    assert.equal(moment('2003 1 0', 'gggg w e').format('YYYY-MM-DD'), '2002-12-28', 'Week 1 of 2003 should be Dec 28 2002');\n    assert.equal(moment('2003 1 6', 'gggg w d').format('gggg w d'), '2003 1 6', 'Saturday of week 1 of 2003 parsed should be formatted as 2003 1 6');\n    assert.equal(moment('2003 1 0', 'gggg w e').format('gggg w e'), '2003 1 0', '1st day of week 1 of 2003 parsed should be formatted as 2003 1 0');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2011, 11, 31]).format('w ww wo'), '1 01 1', 'Dec 31 2011 should be week 1');\n    assert.equal(moment([2012,  0,  6]).format('w ww wo'), '1 01 1', 'Jan  6 2012 should be week 1');\n    assert.equal(moment([2012,  0,  7]).format('w ww wo'), '2 02 2', 'Jan  7 2012 should be week 2');\n    assert.equal(moment([2012,  0, 13]).format('w ww wo'), '2 02 2', 'Jan 13 2012 should be week 2');\n    assert.equal(moment([2012,  0, 14]).format('w ww wo'), '3 03 3', 'Jan 14 2012 should be week 3');\n});\n\ntest('no leading zeros in long date formats', function (assert) {\n    var i, j, longDateStr, shortDateStr;\n    for (i = 1; i <= 9; ++i) {\n        for (j = 1; j <= 9; ++j) {\n            longDateStr = moment([2014, i, j]).format('L');\n            shortDateStr = moment([2014, i, j]).format('l');\n            assert.equal(longDateStr, shortDateStr, 'should not have leading zeros in month or day');\n        }\n    }\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\n\n\nfunction localeModule (name, lifecycle) {\n    QUnit.module('locale:' + name, {\n        setup : function () {\n            moment.locale(name);\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            moment.locale('en');\n            teardownDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n    defineCommonLocaleTests(name, -1, -1);\n}\n\nlocaleModule('ar-ma');\n\ntest('parse', function (assert) {\n    var tests = 'يناير:يناير_فبراير:فبراير_مارس:مارس_أبريل:أبريل_ماي:ماي_يونيو:يونيو_يوليوز:يوليوز_غشت:غشت_شتنبر:شتنبر_أكتوبر:أكتوبر_نونبر:نونبر_دجنبر:دجنبر'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(':');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, MMMM Do YYYY, h:mm:ss a',      'الأحد, فبراير 14 2010, 3:25:50 pm'],\n            ['ddd, hA',                            'احد, 3PM'],\n            ['M Mo MM MMMM MMM',                   '2 2 02 فبراير فبراير'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14 14'],\n            ['d do dddd ddd dd',                   '0 0 الأحد احد ح'],\n            ['DDD DDDo DDDD',                      '45 45 045'],\n            ['w wo ww',                            '8 8 08'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'pm PM'],\n            ['[the] DDDo [day of the year]',       'the 45 day of the year'],\n            ['LT',                                 '15:25'],\n            ['LTS',                                '15:25:50'],\n            ['L',                                  '14/02/2010'],\n            ['LL',                                 '14 فبراير 2010'],\n            ['LLL',                                '14 فبراير 2010 15:25'],\n            ['LLLL',                               'الأحد 14 فبراير 2010 15:25'],\n            ['l',                                  '14/2/2010'],\n            ['ll',                                 '14 فبراير 2010'],\n            ['lll',                                '14 فبراير 2010 15:25'],\n            ['llll',                               'احد 14 فبراير 2010 15:25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1', '1');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2', '2');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3', '3');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4', '4');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5', '5');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6', '6');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7', '7');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8', '8');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9', '9');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10', '10');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11', '11');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12', '12');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13', '13');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14', '14');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15', '15');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16', '16');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17', '17');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18', '18');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19', '19');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20', '20');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21', '21');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22', '22');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23', '23');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24', '24');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25', '25');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26', '26');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27', '27');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28', '28');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29', '29');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30', '30');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31', '31');\n});\n\ntest('format month', function (assert) {\n    var expected = 'يناير يناير_فبراير فبراير_مارس مارس_أبريل أبريل_ماي ماي_يونيو يونيو_يوليوز يوليوز_غشت غشت_شتنبر شتنبر_أكتوبر أكتوبر_نونبر نونبر_دجنبر دجنبر'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'الأحد احد ح_الإتنين اتنين ن_الثلاثاء ثلاثاء ث_الأربعاء اربعاء ر_الخميس خميس خ_الجمعة جمعة ج_السبت سبت س'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'ثوان', '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'دقيقة',      '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'دقيقة',      '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 دقائق',     '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 دقائق',    '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'ساعة',       '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'ساعة',       '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 ساعات',       '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 ساعات',       '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 ساعات',      '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'يوم',         '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'يوم',         '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 أيام',        '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'يوم',         '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 أيام',        '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 أيام',       '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'شهر',       '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'شهر',       '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'شهر',       '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 أشهر',      '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 أشهر',      '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 أشهر',      '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'شهر',       '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 أشهر',      '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'سنة',        '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 سنوات',       '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'سنة',        '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 سنوات',       '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'في ثوان',  'prefix');\n    assert.equal(moment(0).from(30000), 'منذ ثوان', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'منذ ثوان',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'في ثوان', 'in a few seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), 'في 5 أيام', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'اليوم على الساعة 12:00',     'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'اليوم على الساعة 12:25',     'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'اليوم على الساعة 13:00',     'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'غدا على الساعة 12:00',      'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'اليوم على الساعة 11:00',     'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'أمس على الساعة 12:00',     'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('dddd [على الساعة] LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd [على الساعة] LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd [على الساعة] LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('dddd [على الساعة] LT'),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd [على الساعة] LT'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd [على الساعة] LT'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2011, 11, 31]).format('w ww wo'), '1 01 1', 'Dec 31 2011 should be week 1');\n    assert.equal(moment([2012,  0,  6]).format('w ww wo'), '1 01 1', 'Jan  6 2012 should be week 1');\n    assert.equal(moment([2012,  0,  7]).format('w ww wo'), '2 02 2', 'Jan  7 2012 should be week 2');\n    assert.equal(moment([2012,  0, 13]).format('w ww wo'), '2 02 2', 'Jan 13 2012 should be week 2');\n    assert.equal(moment([2012,  0, 14]).format('w ww wo'), '3 03 3', 'Jan 14 2012 should be week 3');\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\n\n\nfunction localeModule (name, lifecycle) {\n    QUnit.module('locale:' + name, {\n        setup : function () {\n            moment.locale(name);\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            moment.locale('en');\n            teardownDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n    defineCommonLocaleTests(name, -1, -1);\n}\n\nlocaleModule('ar-sa');\n\ntest('parse', function (assert) {\n    var tests = 'يناير:يناير_فبراير:فبراير_مارس:مارس_أبريل:أبريل_مايو:مايو_يونيو:يونيو_يوليو:يوليو_أغسطس:أغسطس_سبتمبر:سبتمبر_أكتوبر:أكتوبر_نوفمبر:نوفمبر_ديسمبر:ديسمبر'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1) + ' instead is month ' + moment(input, mmm).month());\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(':');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, MMMM Do YYYY, h:mm:ss a',      'الأحد، فبراير ١٤ ٢٠١٠، ٣:٢٥:٥٠ م'],\n            ['ddd, hA',                            'أحد، ٣م'],\n            ['M Mo MM MMMM MMM',                   '٢ ٢ ٠٢ فبراير فبراير'],\n            ['YYYY YY',                            '٢٠١٠ ١٠'],\n            ['D Do DD',                            '١٤ ١٤ ١٤'],\n            ['d do dddd ddd dd',                   '٠ ٠ الأحد أحد ح'],\n            ['DDD DDDo DDDD',                      '٤٥ ٤٥ ٠٤٥'],\n            ['w wo ww',                            '٨ ٨ ٠٨'],\n            ['h hh',                               '٣ ٠٣'],\n            ['H HH',                               '١٥ ١٥'],\n            ['m mm',                               '٢٥ ٢٥'],\n            ['s ss',                               '٥٠ ٥٠'],\n            ['a A',                                'م م'],\n            ['[the] DDDo [day of the year]',       'the ٤٥ day of the year'],\n            ['LT',                                 '١٥:٢٥'],\n            ['LTS',                                '١٥:٢٥:٥٠'],\n            ['L',                                  '١٤/٠٢/٢٠١٠'],\n            ['LL',                                 '١٤ فبراير ٢٠١٠'],\n            ['LLL',                                '١٤ فبراير ٢٠١٠ ١٥:٢٥'],\n            ['LLLL',                               'الأحد ١٤ فبراير ٢٠١٠ ١٥:٢٥'],\n            ['l',                                  '١٤/٢/٢٠١٠'],\n            ['ll',                                 '١٤ فبراير ٢٠١٠'],\n            ['lll',                                '١٤ فبراير ٢٠١٠ ١٥:٢٥'],\n            ['llll',                               'أحد ١٤ فبراير ٢٠١٠ ١٥:٢٥']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '١', '1');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '٢', '2');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '٣', '3');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '٤', '4');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '٥', '5');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '٦', '6');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '٧', '7');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '٨', '8');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '٩', '9');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '١٠', '10');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '١١', '11');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '١٢', '12');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '١٣', '13');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '١٤', '14');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '١٥', '15');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '١٦', '16');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '١٧', '17');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '١٨', '18');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '١٩', '19');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '٢٠', '20');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '٢١', '21');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '٢٢', '22');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '٢٣', '23');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '٢٤', '24');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '٢٥', '25');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '٢٦', '26');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '٢٧', '27');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '٢٨', '28');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '٢٩', '29');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '٣٠', '30');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '٣١', '31');\n});\n\ntest('format month', function (assert) {\n    var expected = 'يناير يناير_فبراير فبراير_مارس مارس_أبريل أبريل_مايو مايو_يونيو يونيو_يوليو يوليو_أغسطس أغسطس_سبتمبر سبتمبر_أكتوبر أكتوبر_نوفمبر نوفمبر_ديسمبر ديسمبر'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'الأحد أحد ح_الإثنين إثنين ن_الثلاثاء ثلاثاء ث_الأربعاء أربعاء ر_الخميس خميس خ_الجمعة جمعة ج_السبت سبت س'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'ثوان', '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'دقيقة',      '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'دقيقة',      '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '٢ دقائق',     '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '٤٤ دقائق',    '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'ساعة',       '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'ساعة',       '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '٢ ساعات',       '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '٥ ساعات',       '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '٢١ ساعات',      '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'يوم',         '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'يوم',         '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '٢ أيام',        '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'يوم',         '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '٥ أيام',        '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '٢٥ أيام',       '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'شهر',       '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'شهر',       '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'شهر',       '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '٢ أشهر',      '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '٢ أشهر',      '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '٣ أشهر',      '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'شهر',       '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '٥ أشهر',      '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'سنة',        '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '٢ سنوات',       '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'سنة',        '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '٥ سنوات',       '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'في ثوان',  'prefix');\n    assert.equal(moment(0).from(30000), 'منذ ثوان', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'منذ ثوان',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'في ثوان', 'in a few seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), 'في ٥ أيام', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'اليوم على الساعة ١٢:٠٠',     'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'اليوم على الساعة ١٢:٢٥',     'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'اليوم على الساعة ١٣:٠٠',     'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'غدا على الساعة ١٢:٠٠',       'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'اليوم على الساعة ١١:٠٠',     'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'أمس على الساعة ١٢:٠٠',      'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('dddd [على الساعة] LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd [على الساعة] LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd [على الساعة] LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('dddd [على الساعة] LT'),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd [على الساعة] LT'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd [على الساعة] LT'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('weeks year starting wednesday custom', function (assert) {\n    assert.equal(moment('2003 1 6', 'gggg w d').format('YYYY-MM-DD'), '٢٠٠٣-٠١-٠٤', '2003 1 6 : gggg w d');\n    assert.equal(moment('2003 1 0', 'gggg w e').format('YYYY-MM-DD'), '٢٠٠٢-١٢-٢٩', '2003 1 0 : gggg w e');\n    assert.equal(moment('2003 1 6', 'gggg w d').format('gggg w d'), '٢٠٠٣ ١ ٦', '2003 1 6 : gggg w d');\n    assert.equal(moment('2003 1 0', 'gggg w e').format('gggg w e'), '٢٠٠٣ ١ ٠', '2003 1 0 : gggg w e');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2011, 11, 31]).format('w ww wo'), '٥٣ ٥٣ ٥٣', '2011 11 31');\n    assert.equal(moment([2012,  0,  6]).format('w ww wo'), '١ ٠١ ١', '2012 0 6');\n    assert.equal(moment([2012,  0,  7]).format('w ww wo'), '١ ٠١ ١', '2012 0 7');\n    assert.equal(moment([2012,  0, 13]).format('w ww wo'), '٢ ٠٢ ٢', '2012 0 13');\n    assert.equal(moment([2012,  0, 14]).format('w ww wo'), '٢ ٠٢ ٢', '2012 0 14');\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\n\n\nfunction localeModule (name, lifecycle) {\n    QUnit.module('locale:' + name, {\n        setup : function () {\n            moment.locale(name);\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            moment.locale('en');\n            teardownDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n    defineCommonLocaleTests(name, -1, -1);\n}\n\nlocaleModule('ar-tn');\n\ntest('parse', function (assert) {\n    var tests = 'جانفي:جانفي_فيفري:فيفري_مارس:مارس_أفريل:أفريل_ماي:ماي_جوان:جوان_جويلية:جويلية_أوت:أوت_سبتمبر:سبتمبر_أكتوبر:أكتوبر_نوفمبر:نوفمبر_ديسمبر:ديسمبر'.split('_'),\n        i;\n\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(':');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, MMMM Do YYYY, h:mm:ss a', 'الأحد, فيفري 14 2010, 3:25:50 pm'],\n            ['ddd, hA', 'أحد, 3PM'],\n            ['M Mo MM MMMM MMM', '2 2 02 فيفري فيفري'],\n            ['YYYY YY', '2010 10'],\n            ['D Do DD', '14 14 14'],\n            ['d do dddd ddd dd', '0 0 الأحد أحد ح'],\n            ['DDD DDDo DDDD', '45 45 045'],\n            ['w wo ww', '6 6 06'],\n            ['h hh', '3 03'],\n            ['H HH', '15 15'],\n            ['m mm', '25 25'],\n            ['s ss', '50 50'],\n            ['a A', 'pm PM'],\n            ['[the] DDDo [day of the year]', 'the 45 day of the year'],\n            ['LT', '15:25'],\n            ['LTS', '15:25:50'],\n            ['L', '14/02/2010'],\n            ['LL', '14 فيفري 2010'],\n            ['LLL', '14 فيفري 2010 15:25'],\n            ['LLLL', 'الأحد 14 فيفري 2010 15:25'],\n            ['l', '14/2/2010'],\n            ['ll', '14 فيفري 2010'],\n            ['lll', '14 فيفري 2010 15:25'],\n            ['llll', 'أحد 14 فيفري 2010 15:25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1', '1');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2', '2');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3', '3');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4', '4');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5', '5');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6', '6');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7', '7');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8', '8');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9', '9');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10', '10');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11', '11');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12', '12');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13', '13');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14', '14');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15', '15');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16', '16');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17', '17');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18', '18');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19', '19');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20', '20');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21', '21');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22', '22');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23', '23');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24', '24');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25', '25');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26', '26');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27', '27');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28', '28');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29', '29');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30', '30');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31', '31');\n});\n\ntest('format month', function (assert) {\n    var expected = 'جانفي جانفي_فيفري فيفري_مارس مارس_أفريل أفريل_ماي ماي_جوان جوان_جويلية جويلية_أوت أوت_سبتمبر سبتمبر_أكتوبر أكتوبر_نوفمبر نوفمبر_ديسمبر ديسمبر'.split('_'),\n        i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'الأحد أحد ح_الإثنين إثنين ن_الثلاثاء ثلاثاء ث_الأربعاء أربعاء ر_الخميس خميس خ_الجمعة جمعة ج_السبت سبت س'.split('_'),\n        i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({\n        s: 44\n    }), true), 'ثوان', '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({\n        s: 45\n    }), true), 'دقيقة', '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({\n        s: 89\n    }), true), 'دقيقة', '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({\n        s: 90\n    }), true), '2 دقائق', '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({\n        m: 44\n    }), true), '44 دقائق', '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({\n        m: 45\n    }), true), 'ساعة', '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({\n        m: 89\n    }), true), 'ساعة', '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({\n        m: 90\n    }), true), '2 ساعات', '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({\n        h: 5\n    }), true), '5 ساعات', '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({\n        h: 21\n    }), true), '21 ساعات', '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({\n        h: 22\n    }), true), 'يوم', '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({\n        h: 35\n    }), true), 'يوم', '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({\n        h: 36\n    }), true), '2 أيام', '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({\n        d: 1\n    }), true), 'يوم', '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({\n        d: 5\n    }), true), '5 أيام', '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({\n        d: 25\n    }), true), '25 أيام', '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({\n        d: 26\n    }), true), 'شهر', '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({\n        d: 30\n    }), true), 'شهر', '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({\n        d: 43\n    }), true), 'شهر', '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({\n        d: 46\n    }), true), '2 أشهر', '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({\n        d: 74\n    }), true), '2 أشهر', '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({\n        d: 76\n    }), true), '3 أشهر', '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({\n        M: 1\n    }), true), 'شهر', '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({\n        M: 5\n    }), true), '5 أشهر', '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({\n        d: 345\n    }), true), 'سنة', '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({\n        d: 548\n    }), true), '2 سنوات', '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({\n        y: 1\n    }), true), 'سنة', '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({\n        y: 5\n    }), true), '5 سنوات', '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'في ثوان', 'prefix');\n    assert.equal(moment(0).from(30000), 'منذ ثوان', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'منذ ثوان', 'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({\n        s: 30\n    }).fromNow(), 'في ثوان', 'in a few seconds');\n    assert.equal(moment().add({\n        d: 5\n    }).fromNow(), 'في 5 أيام', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                  'اليوم على الساعة 12:00', 'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),     'اليوم على الساعة 12:25', 'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),      'اليوم على الساعة 13:00', 'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),      'غدا على الساعة 12:00',  'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(), 'اليوم على الساعة 11:00', 'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(), 'أمس على الساعة 12:00',  'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({\n            d: i\n        });\n        assert.equal(m.calendar(), m.format('dddd [على الساعة] LT'), 'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(), m.format('dddd [على الساعة] LT'), 'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(), m.format('dddd [على الساعة] LT'), 'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({\n            d: i\n        });\n        assert.equal(m.calendar(), m.format('dddd [على الساعة] LT'), 'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(), m.format('dddd [على الساعة] LT'), 'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(), m.format('dddd [على الساعة] LT'), 'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({\n            w: 1\n        }),\n        weeksFromNow = moment().add({\n            w: 1\n        });\n\n    assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '1 week ago');\n    assert.equal(weeksFromNow.calendar(), weeksFromNow.format('L'), 'in 1 week');\n\n    weeksAgo = moment().subtract({\n        w: 2\n    });\n    weeksFromNow = moment().add({\n        w: 2\n    });\n\n    assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(), weeksFromNow.format('L'), 'in 2 weeks');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2012, 0,  1]).format('w ww wo'), '52 52 52', 'Jan  1 2012 should be week 52');\n    assert.equal(moment([2012, 0,  2]).format('w ww wo'), '1 01 1', 'Jan  2 2012 should be week 1');\n    assert.equal(moment([2012, 0,  8]).format('w ww wo'), '1 01 1', 'Jan  8 2012 should be week 1');\n    assert.equal(moment([2012, 0,  9]).format('w ww wo'),   '2 02 2', 'Jan  9 2012 should be week 2');\n    assert.equal(moment([2012, 0, 15]).format('w ww wo'),   '2 02 2', 'Jan 15 2012 should be week 2');\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\n\n\nfunction localeModule (name, lifecycle) {\n    QUnit.module('locale:' + name, {\n        setup : function () {\n            moment.locale(name);\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            moment.locale('en');\n            teardownDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n    defineCommonLocaleTests(name, -1, -1);\n}\n\nlocaleModule('ar');\n\nvar months = [\n    'كانون الثاني يناير',\n    'شباط فبراير',\n    'آذار مارس',\n    'نيسان أبريل',\n    'أيار مايو',\n    'حزيران يونيو',\n    'تموز يوليو',\n    'آب أغسطس',\n    'أيلول سبتمبر',\n    'تشرين الأول أكتوبر',\n    'تشرين الثاني نوفمبر',\n    'كانون الأول ديسمبر'\n];\n\ntest('parse', function (assert) {\n    var tests = months, i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1) + ' instead is month ' + moment(input, mmm).month());\n    }\n    for (i = 0; i < 12; i++) {\n        equalTest(tests[i], 'MMM', i);\n        equalTest(tests[i], 'MMM', i);\n        equalTest(tests[i], 'MMMM', i);\n        equalTest(tests[i], 'MMMM', i);\n        equalTest(tests[i].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, MMMM Do YYYY, h:mm:ss a',      'الأحد، شباط فبراير ١٤ ٢٠١٠، ٣:٢٥:٥٠ م'],\n            ['ddd, hA',                            'أحد، ٣م'],\n            ['M Mo MM MMMM MMM',                   '٢ ٢ ٠٢ شباط فبراير شباط فبراير'],\n            ['YYYY YY',                            '٢٠١٠ ١٠'],\n            ['D Do DD',                            '١٤ ١٤ ١٤'],\n            ['d do dddd ddd dd',                   '٠ ٠ الأحد أحد ح'],\n            ['DDD DDDo DDDD',                      '٤٥ ٤٥ ٠٤٥'],\n            ['w wo ww',                            '٨ ٨ ٠٨'],\n            ['h hh',                               '٣ ٠٣'],\n            ['H HH',                               '١٥ ١٥'],\n            ['m mm',                               '٢٥ ٢٥'],\n            ['s ss',                               '٥٠ ٥٠'],\n            ['a A',                                'م م'],\n            ['[the] DDDo [day of the year]',       'the ٤٥ day of the year'],\n            ['LT',                                 '١٥:٢٥'],\n            ['LTS',                                '١٥:٢٥:٥٠'],\n            ['L',                                  '١٤/\\u200f٢/\\u200f٢٠١٠'],\n            ['LL',                                 '١٤ شباط فبراير ٢٠١٠'],\n            ['LLL',                                '١٤ شباط فبراير ٢٠١٠ ١٥:٢٥'],\n            ['LLLL',                               'الأحد ١٤ شباط فبراير ٢٠١٠ ١٥:٢٥'],\n            ['l',                                  '١٤/\\u200f٢/\\u200f٢٠١٠'],\n            ['ll',                                 '١٤ شباط فبراير ٢٠١٠'],\n            ['lll',                                '١٤ شباط فبراير ٢٠١٠ ١٥:٢٥'],\n            ['llll',                               'أحد ١٤ شباط فبراير ٢٠١٠ ١٥:٢٥']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '١', '1');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '٢', '2');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '٣', '3');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '٤', '4');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '٥', '5');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '٦', '6');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '٧', '7');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '٨', '8');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '٩', '9');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '١٠', '10');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '١١', '11');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '١٢', '12');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '١٣', '13');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '١٤', '14');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '١٥', '15');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '١٦', '16');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '١٧', '17');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '١٨', '18');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '١٩', '19');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '٢٠', '20');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '٢١', '21');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '٢٢', '22');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '٢٣', '23');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '٢٤', '24');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '٢٥', '25');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '٢٦', '26');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '٢٧', '27');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '٢٨', '28');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '٢٩', '29');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '٣٠', '30');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '٣١', '31');\n});\n\ntest('format month', function (assert) {\n    var expected = months, i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM'), expected[i], expected[i]);\n        assert.equal(moment([2011, i, 1]).format('MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'الأحد أحد ح_الإثنين إثنين ن_الثلاثاء ثلاثاء ث_الأربعاء أربعاء ر_الخميس خميس خ_الجمعة جمعة ج_السبت سبت س'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  '٤٤ ثانية', '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'دقيقة واحدة',      '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'دقيقة واحدة',      '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  'دقيقتان',     '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '٤٤ دقيقة',    '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'ساعة واحدة',       '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'ساعة واحدة',       '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  'ساعتان',       '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '٥ ساعات',       '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '٢١ ساعة',      '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'يوم واحد',         '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'يوم واحد',         '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  'يومان',        '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'يوم واحد',         '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '٥ أيام',        '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '٢٥ يومًا',       '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'شهر واحد',       '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'شهر واحد',       '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'شهر واحد',       '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  'شهران',      '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  'شهران',      '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '٣ أشهر',      '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'شهر واحد',       '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '٥ أشهر',      '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'عام واحد',        '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), 'عامان',       '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'عام واحد',        '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '٥ أعوام',       '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'بعد ٣٠ ثانية',  'prefix');\n    assert.equal(moment(0).from(30000), 'منذ ٣٠ ثانية', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'منذ ثانية واحدة',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'بعد ٣٠ ثانية', 'in a few seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), 'بعد ٥ أيام', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'اليوم عند الساعة ١٢:٠٠',     'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'اليوم عند الساعة ١٢:٢٥',     'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'اليوم عند الساعة ١٣:٠٠',     'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'غدًا عند الساعة ١٢:٠٠',      'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'اليوم عند الساعة ١١:٠٠',     'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'أمس عند الساعة ١٢:٠٠',       'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('dddd [عند الساعة] LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd [عند الساعة] LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd [عند الساعة] LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('dddd [عند الساعة] LT'),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd [عند الساعة] LT'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd [عند الساعة] LT'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('weeks year starting wednesday custom', function (assert) {\n    assert.equal(moment('2003 1 6', 'gggg w d').format('YYYY-MM-DD'), '٢٠٠٢-١٢-٢٨', 'Week 1 of 2003 should be Dec 28 2002');\n    assert.equal(moment('2003 1 0', 'gggg w e').format('YYYY-MM-DD'), '٢٠٠٢-١٢-٢٨', 'Week 1 of 2003 should be Dec 28 2002');\n    assert.equal(moment('2003 1 6', 'gggg w d').format('gggg w d'), '٢٠٠٣ ١ ٦', 'Saturday of week 1 of 2003 parsed should be formatted as 2003 1 6');\n    assert.equal(moment('2003 1 0', 'gggg w e').format('gggg w e'), '٢٠٠٣ ١ ٠', '1st day of week 1 of 2003 parsed should be formatted as 2003 1 0');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2011, 11, 31]).format('w ww wo'), '١ ٠١ ١', 'Dec 31 2011 should be week 1');\n    assert.equal(moment([2012,  0,  6]).format('w ww wo'), '١ ٠١ ١', 'Jan  6 2012 should be week 1');\n    assert.equal(moment([2012,  0,  7]).format('w ww wo'), '٢ ٠٢ ٢', 'Jan  7 2012 should be week 2');\n    assert.equal(moment([2012,  0, 13]).format('w ww wo'), '٢ ٠٢ ٢', 'Jan 13 2012 should be week 2');\n    assert.equal(moment([2012,  0, 14]).format('w ww wo'), '٣ ٠٣ ٣', 'Jan 14 2012 should be week 3');\n});\n\ntest('no leading zeros in long date formats', function (assert) {\n    var i, j, longDateStr, shortDateStr;\n    for (i = 1; i <= 9; ++i) {\n        for (j = 1; j <= 9; ++j) {\n            longDateStr = moment([2014, i, j]).format('L');\n            shortDateStr = moment([2014, i, j]).format('l');\n            assert.equal(longDateStr, shortDateStr, 'should not have leading zeros in month or day');\n        }\n    }\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\n\n\nfunction localeModule (name, lifecycle) {\n    QUnit.module('locale:' + name, {\n        setup : function () {\n            moment.locale(name);\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            moment.locale('en');\n            teardownDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n    defineCommonLocaleTests(name, -1, -1);\n}\n\nlocaleModule('az');\n\ntest('parse', function (assert) {\n    var tests = 'yanvar yan_fevral fev_mart mar_Aprel apr_may may_iyun iyn_iyul iyl_Avqust avq_sentyabr sen_oktyabr okt_noyabr noy_dekabr dek'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, D MMMM YYYY, HH:mm:ss',        'Bazar, 14 fevral 2010, 15:25:50'],\n            ['ddd, A h',                           'Baz, gündüz 3'],\n            ['M Mo MM MMMM MMM',                   '2 2-nci 02 fevral fev'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14-üncü 14'],\n            ['d do dddd ddd dd',                   '0 0-ıncı Bazar Baz Bz'],\n            ['DDD DDDo DDDD',                      '45 45-inci 045'],\n            ['w wo ww',                            '7 7-nci 07'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'gündüz gündüz'],\n            ['[ilin] DDDo [günü]',                 'ilin 45-inci günü'],\n            ['LT',                                 '15:25'],\n            ['LTS',                                '15:25:50'],\n            ['L',                                  '14.02.2010'],\n            ['LL',                                 '14 fevral 2010'],\n            ['LLL',                                '14 fevral 2010 15:25'],\n            ['LLLL',                               'Bazar, 14 fevral 2010 15:25'],\n            ['l',                                  '14.2.2010'],\n            ['ll',                                 '14 fev 2010'],\n            ['lll',                                '14 fev 2010 15:25'],\n            ['llll',                               'Baz, 14 fev 2010 15:25']\n        ],\n        DDDo = [\n            [359, '360-ıncı'],\n            [199, '200-üncü'],\n            [149, '150-nci']\n        ],\n        dt = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        DDDoDt,\n        i;\n\n    for (i = 0; i < a.length; i++) {\n        assert.equal(dt.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n    for (i = 0; i < DDDo.length; i++) {\n        DDDoDt = moment([2010]);\n        assert.equal(DDDoDt.add(DDDo[i][0], 'days').format('DDDo'), DDDo[i][1], DDDo[i][0] + ' ---> ' + DDDo[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1-inci', '1st');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2-nci', '2nd');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3-üncü', '3rd');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4-üncü', '4th');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5-inci', '5th');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6-ncı', '6th');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7-nci', '7th');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8-inci', '8th');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9-uncu', '9th');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10-uncu', '10th');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11-inci', '11th');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12-nci', '12th');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13-üncü', '13th');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14-üncü', '14th');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15-inci', '15th');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16-ncı', '16th');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17-nci', '17th');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18-inci', '18th');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19-uncu', '19th');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20-nci', '20th');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21-inci', '21th');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22-nci', '22th');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23-üncü', '23th');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24-üncü', '24th');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25-inci', '25th');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26-ncı', '26th');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27-nci', '27th');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28-inci', '28th');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29-uncu', '29th');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30-uncu', '30th');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31-inci', '31st');\n});\n\ntest('format month', function (assert) {\n    var expected = 'yanvar yan_fevral fev_mart mar_aprel apr_may may_iyun iyn_iyul iyl_avqust avq_sentyabr sen_oktyabr okt_noyabr noy_dekabr dek'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'Bazar Baz Bz_Bazar ertəsi BzE BE_Çərşənbə axşamı ÇAx ÇA_Çərşənbə Çər Çə_Cümə axşamı CAx CA_Cümə Cüm Cü_Şənbə Şən Şə'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'birneçə saniyyə', '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'bir dəqiqə',      '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'bir dəqiqə',      '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 dəqiqə',     '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 dəqiqə',    '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'bir saat',       '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'bir saat',       '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 saat',       '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 saat',       '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 saat',      '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'bir gün',         '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'bir gün',         '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 gün',        '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'bir gün',         '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 gün',        '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 gün',       '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'bir ay',       '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'bir ay',       '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 ay',      '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 ay',      '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 ay',      '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'bir ay',       '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 ay',      '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'bir il',        '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 il',       '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'bir il',        '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 il',       '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'birneçə saniyyə sonra',  'prefix');\n    assert.equal(moment(0).from(30000), 'birneçə saniyyə əvvəl', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'birneçə saniyyə əvvəl',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'birneçə saniyyə sonra', 'in a few seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), '5 gün sonra', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'bugün saat 12:00',     'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'bugün saat 12:25',     'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'bugün saat 13:00',     'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'sabah saat 12:00',     'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'bugün saat 11:00',     'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'dünən 12:00',          'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('[gələn həftə] dddd [saat] LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[gələn həftə] dddd [saat] LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[gələn həftə] dddd [saat] LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('[keçən həftə] dddd [saat] LT'),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[keçən həftə] dddd [saat] LT'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[keçən həftə] dddd [saat] LT'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2011, 11, 26]).format('w ww wo'), '1 01 1-inci', 'Dec 26 2011 should be week 1');\n    assert.equal(moment([2012,  0,  1]).format('w ww wo'), '1 01 1-inci', 'Jan  1 2012 should be week 1');\n    assert.equal(moment([2012,  0,  2]).format('w ww wo'), '2 02 2-nci', 'Jan  2 2012 should be week 2');\n    assert.equal(moment([2012,  0,  8]).format('w ww wo'), '2 02 2-nci', 'Jan  8 2012 should be week 2');\n    assert.equal(moment([2012,  0,  9]).format('w ww wo'), '3 03 3-üncü', 'Jan  9 2012 should be week 3');\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\n\n\nfunction localeModule (name, lifecycle) {\n    QUnit.module('locale:' + name, {\n        setup : function () {\n            moment.locale(name);\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            moment.locale('en');\n            teardownDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n    defineCommonLocaleTests(name, -1, -1);\n}\n\nlocaleModule('be');\n\ntest('parse', function (assert) {\n    var tests = 'студзень студ_люты лют_сакавік сак_красавік крас_травень трав_чэрвень чэрв_ліпень ліп_жнівень жнів_верасень вер_кастрычнік каст_лістапад ліст_снежань снеж'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, Do MMMM YYYY, HH:mm:ss',       'нядзеля, 14-га лютага 2010, 15:25:50'],\n            ['ddd, h A',                           'нд, 3 дня'],\n            ['M Mo MM MMMM MMM',                   '2 2-і 02 люты лют'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14-га 14'],\n            ['d do dddd ddd dd',                   '0 0-ы нядзеля нд нд'],\n            ['DDD DDDo DDDD',                      '45 45-ы 045'],\n            ['w wo ww',                            '7 7-ы 07'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'дня дня'],\n            ['DDDo [дзень года]',                   '45-ы дзень года'],\n            ['LT',                                 '15:25'],\n            ['LTS',                                '15:25:50'],\n            ['L',                                  '14.02.2010'],\n            ['LL',                                 '14 лютага 2010 г.'],\n            ['LLL',                                '14 лютага 2010 г., 15:25'],\n            ['LLLL',                               'нядзеля, 14 лютага 2010 г., 15:25'],\n            ['l',                                  '14.2.2010'],\n            ['ll',                                 '14 лют 2010 г.'],\n            ['lll',                                '14 лют 2010 г., 15:25'],\n            ['llll',                               'нд, 14 лют 2010 г., 15:25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format meridiem', function (assert) {\n    assert.equal(moment([2012, 11, 28, 0, 0]).format('A'), 'ночы', 'night');\n    assert.equal(moment([2012, 11, 28, 3, 59]).format('A'), 'ночы', 'night');\n    assert.equal(moment([2012, 11, 28, 4, 0]).format('A'), 'раніцы', 'morning');\n    assert.equal(moment([2012, 11, 28, 11, 59]).format('A'), 'раніцы', 'morning');\n    assert.equal(moment([2012, 11, 28, 12, 0]).format('A'), 'дня', 'afternoon');\n    assert.equal(moment([2012, 11, 28, 16, 59]).format('A'), 'дня', 'afternoon');\n    assert.equal(moment([2012, 11, 28, 17, 0]).format('A'), 'вечара', 'evening');\n    assert.equal(moment([2012, 11, 28, 23, 59]).format('A'), 'вечара', 'evening');\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1-ы', '1-ы');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2-і', '2-і');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3-і', '3-і');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4-ы', '4-ы');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5-ы', '5-ы');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6-ы', '6-ы');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7-ы', '7-ы');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8-ы', '8-ы');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9-ы', '9-ы');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10-ы', '10-ы');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11-ы', '11-ы');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12-ы', '12-ы');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13-ы', '13-ы');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14-ы', '14-ы');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15-ы', '15-ы');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16-ы', '16-ы');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17-ы', '17-ы');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18-ы', '18-ы');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19-ы', '19-ы');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20-ы', '20-ы');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21-ы', '21-ы');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22-і', '22-і');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23-і', '23-і');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24-ы', '24-ы');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25-ы', '25-ы');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26-ы', '26-ы');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27-ы', '27-ы');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28-ы', '28-ы');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29-ы', '29-ы');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30-ы', '30-ы');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31-ы', '31-ы');\n});\n\ntest('format month', function (assert) {\n    var expected = 'студзень студ_люты лют_сакавік сак_красавік крас_травень трав_чэрвень чэрв_ліпень ліп_жнівень жнів_верасень вер_кастрычнік каст_лістапад ліст_снежань снеж'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format month case', function (assert) {\n    var months = {\n        'nominative': 'студзень_люты_сакавік_красавік_травень_чэрвень_ліпень_жнівень_верасень_кастрычнік_лістапад_снежань'.split('_'),\n        'accusative': 'студзеня_лютага_сакавіка_красавіка_траўня_чэрвеня_ліпеня_жніўня_верасня_кастрычніка_лістапада_снежня'.split('_')\n    }, i;\n    for (i = 0; i < 12; i++) {\n        assert.equal(moment([2011, i, 1]).format('D MMMM'), '1 ' + months.accusative[i], '1 ' + months.accusative[i]);\n        assert.equal(moment([2011, i, 1]).format('MMMM'), months.nominative[i], '1 ' + months.nominative[i]);\n    }\n});\n\ntest('format month case with escaped symbols', function (assert) {\n    var months = {\n        'nominative': 'студзень_люты_сакавік_красавік_травень_чэрвень_ліпень_жнівень_верасень_кастрычнік_лістапад_снежань'.split('_'),\n        'accusative': 'студзеня_лютага_сакавіка_красавіка_траўня_чэрвеня_ліпеня_жніўня_верасня_кастрычніка_лістапада_снежня'.split('_')\n    }, i;\n    for (i = 0; i < 12; i++) {\n        assert.equal(moment([2013, i, 1]).format('D[] MMMM'), '1 ' + months.accusative[i], '1 ' + months.accusative[i]);\n        assert.equal(moment([2013, i, 1]).format('[<i>]D[</i>] [<b>]MMMM[</b>]'), '<i>1</i> <b>' + months.accusative[i] + '</b>', '1 <b>' + months.accusative[i] + '</b>');\n        assert.equal(moment([2013, i, 1]).format('D[-ы дзень] MMMM'), '1-ы дзень ' + months.accusative[i], '1-ы дзень ' + months.accusative[i]);\n        assert.equal(moment([2013, i, 1]).format('D, MMMM'), '1, ' + months.nominative[i], '1, ' + months.nominative[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'нядзеля нд нд_панядзелак пн пн_аўторак ат ат_серада ср ср_чацвер чц чц_пятніца пт пт_субота сб сб'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'некалькі секунд',    '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'хвіліна',   '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'хвіліна',   '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 хвіліны',  '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 31}), true),  '31 хвіліна',  '31 minutes = 31 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 хвіліны', '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'гадзіна',    '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'гадзіна',    '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 гадзіны',    '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 гадзін',    '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 гадзіна',   '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'дзень',      '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'дзень',      '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 дні',     '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'дзень',      '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 дзён',     '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 11}), true),  '11 дзён',     '11 days = 11 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 21}), true),  '21 дзень',     '21 days = 21 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 дзён',    '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'месяц',    '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'месяц',    '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'месяц',    '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 месяцы',   '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 месяцы',   '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 месяцы',   '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'месяц',    '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 месяцаў',   '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'год',     '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 гады',    '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'год',     '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 гадоў',    '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'праз некалькі секунд', 'prefix');\n    assert.equal(moment(0).from(30000), 'некалькі секунд таму', 'suffix');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'праз некалькі секунд', 'in a few seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), 'праз 5 дзён', 'in 5 days');\n    assert.equal(moment().add({m: 31}).fromNow(), 'праз 31 хвіліну', 'in 31 minutes = in 31 minutes');\n    assert.equal(moment().subtract({m: 31}).fromNow(), '31 хвіліну таму', '31 minutes ago = 31 minutes ago');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'Сёння ў 12:00',     'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'Сёння ў 12:25',     'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'Сёння ў 13:00',     'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'Заўтра ў 12:00',    'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'Сёння ў 11:00',     'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'Учора ў 12:00',     'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    function makeFormat(d) {\n        return '[У] dddd [ў] LT';\n    }\n\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format(makeFormat(m)),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format(makeFormat(m)),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format(makeFormat(m)),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n\n    function makeFormat(d) {\n        switch (d.day()) {\n            case 0:\n            case 3:\n            case 5:\n            case 6:\n                return '[У мінулую] dddd [ў] LT';\n            case 1:\n            case 2:\n            case 4:\n                return '[У мінулы] dddd [ў] LT';\n        }\n    }\n\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format(makeFormat(m)),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format(makeFormat(m)),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format(makeFormat(m)),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2011, 11, 26]).format('w ww wo'), '1 01 1-ы', 'Dec 26 2011 should be week 1');\n    assert.equal(moment([2012,  0,  1]).format('w ww wo'), '1 01 1-ы', 'Jan  1 2012 should be week 1');\n    assert.equal(moment([2012,  0,  2]).format('w ww wo'), '2 02 2-і', 'Jan  2 2012 should be week 2');\n    assert.equal(moment([2012,  0,  8]).format('w ww wo'), '2 02 2-і', 'Jan  8 2012 should be week 2');\n    assert.equal(moment([2012,  0,  9]).format('w ww wo'), '3 03 3-і', 'Jan  9 2012 should be week 3');\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\n\n\nfunction localeModule (name, lifecycle) {\n    QUnit.module('locale:' + name, {\n        setup : function () {\n            moment.locale(name);\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            moment.locale('en');\n            teardownDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n    defineCommonLocaleTests(name, -1, -1);\n}\n\nlocaleModule('bg');\n\ntest('parse', function (assert) {\n    var tests = 'януари янр_февруари фев_март мар_април апр_май май_юни юни_юли юли_август авг_септември сеп_октомври окт_ноември ное_декември дек'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, MMMM Do YYYY, H:mm:ss',        'неделя, февруари 14-ти 2010, 15:25:50'],\n            ['ddd, hA',                            'нед, 3PM'],\n            ['M Mo MM MMMM MMM',                   '2 2-ри 02 февруари фев'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14-ти 14'],\n            ['d do dddd ddd dd',                   '0 0-ев неделя нед нд'],\n            ['DDD DDDo DDDD',                      '45 45-ти 045'],\n            ['w wo ww',                            '7 7-ми 07'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'pm PM'],\n            ['[the] DDDo [day of the year]',       'the 45-ти day of the year'],\n            ['LT',                                 '15:25'],\n            ['LTS',                                '15:25:50'],\n            ['L',                                  '14.02.2010'],\n            ['LL',                                 '14 февруари 2010'],\n            ['LLL',                                '14 февруари 2010 15:25'],\n            ['LLLL',                               'неделя, 14 февруари 2010 15:25'],\n            ['l',                                  '14.2.2010'],\n            ['ll',                                 '14 фев 2010'],\n            ['lll',                                '14 фев 2010 15:25'],\n            ['llll',                               'нед, 14 фев 2010 15:25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1-ви', '1-ви');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2-ри', '2-ри');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3-ти', '3-ти');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4-ти', '4-ти');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5-ти', '5-ти');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6-ти', '6-ти');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7-ми', '7-ми');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8-ми', '8-ми');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9-ти', '9-ти');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10-ти', '10-ти');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11-ти', '11-ти');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12-ти', '12-ти');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13-ти', '13-ти');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14-ти', '14-ти');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15-ти', '15-ти');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16-ти', '16-ти');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17-ти', '17-ти');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18-ти', '18-ти');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19-ти', '19-ти');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20-ти', '20-ти');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21-ви', '21-ви');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22-ри', '22-ри');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23-ти', '23-ти');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24-ти', '24-ти');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25-ти', '25-ти');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26-ти', '26-ти');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27-ми', '27-ми');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28-ми', '28-ми');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29-ти', '29-ти');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30-ти', '30-ти');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31-ви', '31-ви');\n});\n\ntest('format month', function (assert) {\n    var expected = 'януари янр_февруари фев_март мар_април апр_май май_юни юни_юли юли_август авг_септември сеп_октомври окт_ноември ное_декември дек'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'неделя нед нд_понеделник пон пн_вторник вто вт_сряда сря ср_четвъртък чет чт_петък пет пт_събота съб сб'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'няколко секунди', '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'минута',          '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'минута',          '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 минути',        '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 минути',       '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'час',             '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'час',             '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 часа',          '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 часа',          '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 часа',         '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'ден',             '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'ден',             '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 дни',           '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'ден',             '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 дни',           '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 дни',          '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'месец',           '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'месец',           '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'месец',           '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 месеца',        '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 месеца',        '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 месеца',        '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'месец',           '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 месеца',        '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'година',          '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 години',        '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'година',          '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 години',        '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'след няколко секунди',  'prefix');\n    assert.equal(moment(0).from(30000), 'преди няколко секунди', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'преди няколко секунди',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'след няколко секунди', 'in a few seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), 'след 5 дни', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'Днес в 12:00',  'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'Днес в 12:25',  'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'Днес в 13:00',  'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'Утре в 12:00',  'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'Днес в 11:00',  'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'Вчера в 12:00', 'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('dddd [в] LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd [в] LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd [в] LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n\n    function makeFormat(d) {\n        switch (d.day()) {\n            case 0:\n            case 3:\n            case 6:\n                return '[В изминалата] dddd [в] LT';\n            case 1:\n            case 2:\n            case 4:\n            case 5:\n                return '[В изминалия] dddd [в] LT';\n        }\n    }\n\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format(makeFormat(m)),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format(makeFormat(m)),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format(makeFormat(m)),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2011, 11, 26]).format('w ww wo'), '1 01 1-ви', 'Dec 26 2011 should be week 1');\n    assert.equal(moment([2012,  0,  1]).format('w ww wo'), '1 01 1-ви', 'Jan  1 2012 should be week 1');\n    assert.equal(moment([2012,  0,  2]).format('w ww wo'), '2 02 2-ри', 'Jan  2 2012 should be week 2');\n    assert.equal(moment([2012,  0,  8]).format('w ww wo'), '2 02 2-ри', 'Jan  8 2012 should be week 2');\n    assert.equal(moment([2012,  0,  9]).format('w ww wo'), '3 03 3-ти', 'Jan  9 2012 should be week 3');\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\n\n\nfunction localeModule (name, lifecycle) {\n    QUnit.module('locale:' + name, {\n        setup : function () {\n            moment.locale(name);\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            moment.locale('en');\n            teardownDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n    defineCommonLocaleTests(name, -1, -1);\n}\n\nlocaleModule('bn');\n\ntest('parse', function (assert) {\n    var tests = 'জানুয়ারী জানু_ফেব্রুয়ারি ফেব_মার্চ মার্চ_এপ্রিল এপ্র_মে মে_জুন জুন_জুলাই জুল_আগস্ট আগ_সেপ্টেম্বর সেপ্ট_অক্টোবর অক্টো_নভেম্বর নভে_ডিসেম্বর ডিসে'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, Do MMMM YYYY, a h:mm:ss সময়',  'রবিবার, ১৪ ফেব্রুয়ারি ২০১০, দুপুর ৩:২৫:৫০ সময়'],\n            ['ddd, a h সময়',                       'রবি, দুপুর ৩ সময়'],\n            ['M Mo MM MMMM MMM',                   '২ ২ ০২ ফেব্রুয়ারি ফেব'],\n            ['YYYY YY',                            '২০১০ ১০'],\n            ['D Do DD',                            '১৪ ১৪ ১৪'],\n            ['d do dddd ddd dd',                   '০ ০ রবিবার রবি রবি'],\n            ['DDD DDDo DDDD',                      '৪৫ ৪৫ ০৪৫'],\n            ['w wo ww',                            '৮ ৮ ০৮'],\n            ['h hh',                               '৩ ০৩'],\n            ['H HH',                               '১৫ ১৫'],\n            ['m mm',                               '২৫ ২৫'],\n            ['s ss',                               '৫০ ৫০'],\n            ['a A',                                'দুপুর দুপুর'],\n            ['LT',                                 'দুপুর ৩:২৫ সময়'],\n            ['LTS',                                'দুপুর ৩:২৫:৫০ সময়'],\n            ['L',                                  '১৪/০২/২০১০'],\n            ['LL',                                 '১৪ ফেব্রুয়ারি ২০১০'],\n            ['LLL',                                '১৪ ফেব্রুয়ারি ২০১০, দুপুর ৩:২৫ সময়'],\n            ['LLLL',                               'রবিবার, ১৪ ফেব্রুয়ারি ২০১০, দুপুর ৩:২৫ সময়'],\n            ['l',                                  '১৪/২/২০১০'],\n            ['ll',                                 '১৪ ফেব ২০১০'],\n            ['lll',                                '১৪ ফেব ২০১০, দুপুর ৩:২৫ সময়'],\n            ['llll',                               'রবি, ১৪ ফেব ২০১০, দুপুর ৩:২৫ সময়']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '১', '১');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '২', '২');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '৩', '৩');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '৪', '৪');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '৫', '৫');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '৬', '৬');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '৭', '৭');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '৮', '৮');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '৯', '৯');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '১০', '১০');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '১১', '১১');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '১২', '১২');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '১৩', '১৩');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '১৪', '১৪');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '১৫', '১৫');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '১৬', '১৬');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '১৭', '১৭');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '১৮', '১৮');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '১৯', '১৯');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '২০', '২০');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '২১', '২১');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '২২', '২২');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '২৩', '২৩');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '২৪', '২৪');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '২৫', '২৫');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '২৬', '২৬');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '২৭', '২৭');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '২৮', '२৮');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '২৯', '২৯');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '৩০', '৩০');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '৩১', '৩১');\n});\n\ntest('format month', function (assert) {\n    var expected = 'জানুয়ারী জানু_ফেব্রুয়ারি ফেব_মার্চ মার্চ_এপ্রিল এপ্র_মে মে_জুন জুন_জুলাই জুল_আগস্ট আগ_সেপ্টেম্বর সেপ্ট_অক্টোবর অক্টো_নভেম্বর নভে_ডিসেম্বর ডিসে'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'রবিবার রবি রবি_সোমবার সোম সোম_মঙ্গলবার মঙ্গল মঙ্গ_বুধবার বুধ বুধ_বৃহস্পতিবার বৃহস্পতি বৃহঃ_শুক্রবার শুক্র শুক্র_শনিবার শনি শনি'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'কয়েক সেকেন্ড', '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'এক মিনিট',      '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'এক মিনিট',      '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '২ মিনিট',     '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '৪৪ মিনিট',    '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'এক ঘন্টা',       '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'এক ঘন্টা',       '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '২ ঘন্টা',       '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '৫ ঘন্টা',       '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '২১ ঘন্টা',      '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'এক দিন',         '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'এক দিন',         '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '২ দিন',        '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'এক দিন',         '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '৫ দিন',        '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '২৫ দিন',       '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'এক মাস',       '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'এক মাস',       '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '২ মাস',      '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '২ মাস',      '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '৩ মাস',      '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'এক মাস',       '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '৫ মাস',      '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'এক বছর',        '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '২ বছর',       '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'এক বছর',        '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '৫ বছর',       '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'কয়েক সেকেন্ড পরে',  'prefix');\n    assert.equal(moment(0).from(30000), 'কয়েক সেকেন্ড আগে', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'কয়েক সেকেন্ড আগে',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'কয়েক সেকেন্ড পরে', 'কয়েক সেকেন্ড পরে');\n    assert.equal(moment().add({d: 5}).fromNow(), '৫ দিন পরে', '৫ দিন পরে');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'আজ দুপুর ১২:০০ সময়',       'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'আজ দুপুর ১২:২৫ সময়',       'Now plus 25 min');\n    assert.equal(moment(a).add({h: 3}).calendar(),       'আজ দুপুর ৩:০০ সময়',        'Now plus 3 hours');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'আগামীকাল দুপুর ১২:০০ সময়', 'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'আজ দুপুর ১১:০০ সময়',       'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'গতকাল দুপুর ১২:০০ সময়',    'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('dddd[,] LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd[,] LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd[,] LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('[গত] dddd[,] LT'),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[গত] dddd[,] LT'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[গত] dddd[,] LT'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('meridiem', function (assert) {\n    assert.equal(moment([2011, 2, 23,  2, 30]).format('a'), 'রাত', 'before dawn');\n    assert.equal(moment([2011, 2, 23,  9, 30]).format('a'), 'সকাল', 'morning');\n    assert.equal(moment([2011, 2, 23, 14, 30]).format('a'), 'দুপুর', 'during day');\n    assert.equal(moment([2011, 2, 23, 17, 30]).format('a'), 'বিকাল', 'evening');\n    assert.equal(moment([2011, 2, 23, 19, 30]).format('a'), 'বিকাল', 'late evening');\n    assert.equal(moment([2011, 2, 23, 21, 20]).format('a'), 'রাত', 'night');\n\n    assert.equal(moment([2011, 2, 23,  2, 30]).format('A'), 'রাত', 'before dawn');\n    assert.equal(moment([2011, 2, 23,  9, 30]).format('A'), 'সকাল', 'morning');\n    assert.equal(moment([2011, 2, 23, 14, 30]).format('A'), 'দুপুর', ' during day');\n    assert.equal(moment([2011, 2, 23, 17, 30]).format('A'), 'বিকাল', 'evening');\n    assert.equal(moment([2011, 2, 23, 19, 30]).format('A'), 'বিকাল', 'late evening');\n    assert.equal(moment([2011, 2, 23, 21, 20]).format('A'), 'রাত', 'night');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2012, 0,  1]).format('w ww wo'), '১ ০১ ১', 'Jan  1 2012 should be week 1');\n    assert.equal(moment([2012, 0,  7]).format('w ww wo'), '১ ০১ ১', 'Jan  7 2012 should be week 1');\n    assert.equal(moment([2012, 0,  8]).format('w ww wo'), '২ ০২ ২', 'Jan  8 2012 should be week 2');\n    assert.equal(moment([2012, 0, 14]).format('w ww wo'), '২ ০২ ২', 'Jan 14 2012 should be week 2');\n    assert.equal(moment([2012, 0, 15]).format('w ww wo'), '৩ ০৩ ৩', 'Jan 15 2012 should be week 3');\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\n\n\nfunction localeModule (name, lifecycle) {\n    QUnit.module('locale:' + name, {\n        setup : function () {\n            moment.locale(name);\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            moment.locale('en');\n            teardownDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n    defineCommonLocaleTests(name, -1, -1);\n}\n\nlocaleModule('bo');\n\ntest('parse', function (assert) {\n    var tests = 'ཟླ་བ་དང་པོ ཟླ་བ་དང་པོ._ཟླ་བ་གཉིས་པ ཟླ་བ་གཉིས་པ_ཟླ་བ་གསུམ་པ ཟླ་བ་གསུམ་པ_ཟླ་བ་བཞི་པ ཟླ་བ་བཞི་པ_ཟླ་བ་ལྔ་པ ཟླ་བ་ལྔ་པ_ཟླ་བ་དྲུག་པ ཟླ་བ་དྲུག་པ_ཟླ་བ་བདུན་པ ཟླ་བ་བདུན་པ_ཟླ་བ་བརྒྱད་པ ཟླ་བ་བརྒྱད་པ_ཟླ་བ་དགུ་པ ཟླ་བ་དགུ་པ_ཟླ་བ་བཅུ་པ ཟླ་བ་བཅུ་པ_ཟླ་བ་བཅུ་གཅིག་པ ཟླ་བ་བཅུ་གཅིག་པ_ཟླ་བ་བཅུ་གཉིས་པ ཟླ་བ་བཅུ་གཉིས་པ'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, Do MMMM YYYY, a h:mm:ss ལ་',  'གཟའ་ཉི་མ་, ༡༤ ཟླ་བ་གཉིས་པ ༢༠༡༠, ཉིན་གུང ༣:༢༥:༥༠ ལ་'],\n            ['ddd, a h ལ་',                       'ཉི་མ་, ཉིན་གུང ༣ ལ་'],\n            ['M Mo MM MMMM MMM',                   '༢ ༢ ༠༢ ཟླ་བ་གཉིས་པ ཟླ་བ་གཉིས་པ'],\n            ['YYYY YY',                            '༢༠༡༠ ༡༠'],\n            ['D Do DD',                            '༡༤ ༡༤ ༡༤'],\n            ['d do dddd ddd dd',                   '༠ ༠ གཟའ་ཉི་མ་ ཉི་མ་ ཉི་མ་'],\n            ['DDD DDDo DDDD',                      '༤༥ ༤༥ ༠༤༥'],\n            ['w wo ww',                            '༨ ༨ ༠༨'],\n            ['h hh',                               '༣ ༠༣'],\n            ['H HH',                               '༡༥ ༡༥'],\n            ['m mm',                               '༢༥ ༢༥'],\n            ['s ss',                               '༥༠ ༥༠'],\n            ['a A',                                'ཉིན་གུང ཉིན་གུང'],\n            ['LT',                                 'ཉིན་གུང ༣:༢༥'],\n            ['LTS',                                'ཉིན་གུང ༣:༢༥:༥༠'],\n            ['L',                                  '༡༤/༠༢/༢༠༡༠'],\n            ['LL',                                 '༡༤ ཟླ་བ་གཉིས་པ ༢༠༡༠'],\n            ['LLL',                                '༡༤ ཟླ་བ་གཉིས་པ ༢༠༡༠, ཉིན་གུང ༣:༢༥'],\n            ['LLLL',                               'གཟའ་ཉི་མ་, ༡༤ ཟླ་བ་གཉིས་པ ༢༠༡༠, ཉིན་གུང ༣:༢༥'],\n            ['l',                                  '༡༤/༢/༢༠༡༠'],\n            ['ll',                                 '༡༤ ཟླ་བ་གཉིས་པ ༢༠༡༠'],\n            ['lll',                                '༡༤ ཟླ་བ་གཉིས་པ ༢༠༡༠, ཉིན་གུང ༣:༢༥'],\n            ['llll',                               'ཉི་མ་, ༡༤ ཟླ་བ་གཉིས་པ ༢༠༡༠, ཉིན་གུང ༣:༢༥']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '༡', '༡');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '༢', '༢');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '༣', '༣');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '༤', '༤');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '༥', '༥');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '༦', '༦');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '༧', '༧');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '༨', '༨');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '༩', '༩');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '༡༠', '༡༠');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '༡༡', '༡༡');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '༡༢', '༡༢');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '༡༣', '༡༣');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '༡༤', '༡༤');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '༡༥', '༡༥');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '༡༦', '༡༦');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '༡༧', '༡༧');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '༡༨', '༡༨');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '༡༩', '༡༩');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '༢༠', '༢༠');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '༢༡', '༢༡');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '༢༢', '༢༢');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '༢༣', '༢༣');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '༢༤', '༢༤');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '༢༥', '༢༥');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '༢༦', '༢༦');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '༢༧', '༢༧');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '༢༨', '༢༨');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '༢༩', '༢༩');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '༣༠', '༣༠');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '༣༡', '༣༡');\n});\n\ntest('format month', function (assert) {\n    var expected = 'ཟླ་བ་དང་པོ ཟླ་བ་དང་པོ_ཟླ་བ་གཉིས་པ ཟླ་བ་གཉིས་པ_ཟླ་བ་གསུམ་པ ཟླ་བ་གསུམ་པ_ཟླ་བ་བཞི་པ ཟླ་བ་བཞི་པ_ཟླ་བ་ལྔ་པ ཟླ་བ་ལྔ་པ_ཟླ་བ་དྲུག་པ ཟླ་བ་དྲུག་པ_ཟླ་བ་བདུན་པ ཟླ་བ་བདུན་པ_ཟླ་བ་བརྒྱད་པ ཟླ་བ་བརྒྱད་པ_ཟླ་བ་དགུ་པ ཟླ་བ་དགུ་པ_ཟླ་བ་བཅུ་པ ཟླ་བ་བཅུ་པ_ཟླ་བ་བཅུ་གཅིག་པ ཟླ་བ་བཅུ་གཅིག་པ_ཟླ་བ་བཅུ་གཉིས་པ ཟླ་བ་བཅུ་གཉིས་པ'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'གཟའ་ཉི་མ་ ཉི་མ་ ཉི་མ་_གཟའ་ཟླ་བ་ ཟླ་བ་ ཟླ་བ་_གཟའ་མིག་དམར་ མིག་དམར་ མིག་དམར་_གཟའ་ལྷག་པ་ ལྷག་པ་ ལྷག་པ་_གཟའ་ཕུར་བུ ཕུར་བུ ཕུར་བུ_གཟའ་པ་སངས་ པ་སངས་ པ་སངས་_གཟའ་སྤེན་པ་ སྤེན་པ་ སྤེན་པ་'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'ལམ་སང', '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'སྐར་མ་གཅིག',      '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'སྐར་མ་གཅིག',      '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '༢ སྐར་མ',     '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '༤༤ སྐར་མ',    '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'ཆུ་ཚོད་གཅིག',       '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'ཆུ་ཚོད་གཅིག',       '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '༢ ཆུ་ཚོད',       '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '༥ ཆུ་ཚོད',       '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '༢༡ ཆུ་ཚོད',      '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'ཉིན་གཅིག',         '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'ཉིན་གཅིག',         '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '༢ ཉིན་',        '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'ཉིན་གཅིག',         '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '༥ ཉིན་',        '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '༢༥ ཉིན་',       '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'ཟླ་བ་གཅིག',       '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'ཟླ་བ་གཅིག',       '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'ཟླ་བ་གཅིག',       '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '༢ ཟླ་བ',      '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '༢ ཟླ་བ',      '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '༣ ཟླ་བ',      '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'ཟླ་བ་གཅིག',       '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '༥ ཟླ་བ',      '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'ལོ་གཅིག',        '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '༢ ལོ',       '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'ལོ་གཅིག',        '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '༥ ལོ',       '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'ལམ་སང ལ་',  'prefix');\n    assert.equal(moment(0).from(30000), 'ལམ་སང སྔན་ལ', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'ལམ་སང སྔན་ལ',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'ལམ་སང ལ་', 'ལམ་སང ལ་');\n    assert.equal(moment().add({d: 5}).fromNow(), '༥ ཉིན་ ལ་', '༥ ཉིན་ ལ་');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'དི་རིང ཉིན་གུང ༡༢:༠༠',  'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'དི་རིང ཉིན་གུང ༡༢:༢༥',  'Now plus 25 min');\n    assert.equal(moment(a).add({h: 3}).calendar(),       'དི་རིང ཉིན་གུང ༣:༠༠',   'Now plus 3 hours');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'སང་ཉིན ཉིན་གུང ༡༢:༠༠',  'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'དི་རིང ཉིན་གུང ༡༡:༠༠',  'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'ཁ་སང ཉིན་གུང ༡༢:༠༠',    'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('[བདུན་ཕྲག་རྗེས་མ][,] LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[བདུན་ཕྲག་རྗེས་མ][,] LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[བདུན་ཕྲག་རྗེས་མ][,] LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('[བདུན་ཕྲག་མཐའ་མ] dddd[,] LT'),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[བདུན་ཕྲག་མཐའ་མ] dddd[,] LT'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[བདུན་ཕྲག་མཐའ་མ] dddd[,] LT'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('meridiem', function (assert) {\n    assert.equal(moment([2011, 2, 23,  2, 30]).format('a'), 'མཚན་མོ', 'before dawn');\n    assert.equal(moment([2011, 2, 23,  9, 30]).format('a'), 'ཞོགས་ཀས', 'morning');\n    assert.equal(moment([2011, 2, 23, 14, 30]).format('a'), 'ཉིན་གུང', 'during day');\n    assert.equal(moment([2011, 2, 23, 17, 30]).format('a'), 'དགོང་དག', 'evening');\n    assert.equal(moment([2011, 2, 23, 19, 30]).format('a'), 'དགོང་དག', 'late evening');\n    assert.equal(moment([2011, 2, 23, 21, 20]).format('a'), 'མཚན་མོ', 'night');\n\n    assert.equal(moment([2011, 2, 23,  2, 30]).format('A'), 'མཚན་མོ', 'before dawn');\n    assert.equal(moment([2011, 2, 23,  9, 30]).format('A'), 'ཞོགས་ཀས', 'morning');\n    assert.equal(moment([2011, 2, 23, 14, 30]).format('A'), 'ཉིན་གུང', ' during day');\n    assert.equal(moment([2011, 2, 23, 17, 30]).format('A'), 'དགོང་དག', 'evening');\n    assert.equal(moment([2011, 2, 23, 19, 30]).format('A'), 'དགོང་དག', 'late evening');\n    assert.equal(moment([2011, 2, 23, 21, 20]).format('A'), 'མཚན་མོ', 'night');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2012, 0,  1]).format('w ww wo'), '༡ ༠༡ ༡', 'Jan  1 2012 should be week 1');\n    assert.equal(moment([2012, 0,  7]).format('w ww wo'), '༡ ༠༡ ༡', 'Jan  7 2012 should be week 1');\n    assert.equal(moment([2012, 0,  8]).format('w ww wo'), '༢ ༠༢ ༢', 'Jan  8 2012 should be week 2');\n    assert.equal(moment([2012, 0, 14]).format('w ww wo'), '༢ ༠༢ ༢', 'Jan 14 2012 should be week 2');\n    assert.equal(moment([2012, 0, 15]).format('w ww wo'), '༣ ༠༣ ༣', 'Jan 15 2012 should be week 3');\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\n\n\nfunction localeModule (name, lifecycle) {\n    QUnit.module('locale:' + name, {\n        setup : function () {\n            moment.locale(name);\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            moment.locale('en');\n            teardownDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n    defineCommonLocaleTests(name, -1, -1);\n}\n\nlocaleModule('br');\n\ntest('parse', function (assert) {\n    var tests = 'Genver Gen_C\\'hwevrer C\\'hwe_Meurzh Meu_Ebrel Ebr_Mae Mae_Mezheven Eve_Gouere Gou_Eost Eos_Gwengolo Gwe_Here Her_Du Du_Kerzu Ker'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    moment.locale('br');\n    var a = [\n            ['dddd, MMMM Do YYYY, h:mm:ss a',      'Sul, C\\'hwevrer 14vet 2010, 3:25:50 pm'],\n            ['ddd, h A',                            'Sul, 3 PM'],\n            ['M Mo MM MMMM MMM',                   '2 2vet 02 C\\'hwevrer C\\'hwe'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14vet 14'],\n            ['d do dddd ddd dd',                   '0 0vet Sul Sul Su'],\n            ['DDD DDDo DDDD',                      '45 45vet 045'],\n            ['w wo ww',                            '6 6vet 06'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['DDDo [devezh] [ar] [vloaz]',       '45vet devezh ar vloaz'],\n            ['L',                                  '14/02/2010'],\n            ['LL',                                 '14 a viz C\\'hwevrer 2010'],\n            ['LLL',                                '14 a viz C\\'hwevrer 2010 3e25 PM'],\n            ['LLLL',                               'Sul, 14 a viz C\\'hwevrer 2010 3e25 PM']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    moment.locale('br');\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1añ', '1añ');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2vet', '2vet');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3vet', '3vet');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4vet', '4vet');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5vet', '5vet');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6vet', '6vet');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7vet', '7vet');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8vet', '8vet');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9vet', '9vet');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10vet', '10vet');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11vet', '11vet');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12vet', '12vet');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13vet', '13vet');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14vet', '14vet');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15vet', '15vet');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16vet', '16vet');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17vet', '17vet');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18vet', '18vet');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19vet', '19vet');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20vet', '20vet');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21vet', '21vet');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22vet', '22vet');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23vet', '23vet');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24vet', '24vet');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25vet', '25vet');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26vet', '26vet');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27vet', '27vet');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28vet', '28vet');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29vet', '29vet');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30vet', '30vet');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31vet', '31vet');\n});\n\ntest('format month', function (assert) {\n    moment.locale('br');\n    var expected = 'Genver Gen_C\\'hwevrer C\\'hwe_Meurzh Meu_Ebrel Ebr_Mae Mae_Mezheven Eve_Gouere Gou_Eost Eos_Gwengolo Gwe_Here Her_Du Du_Kerzu Ker'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    moment.locale('br');\n    var expected = 'Sul Sul Su_Lun Lun Lu_Meurzh Meu Me_Merc\\'her Mer Mer_Yaou Yao Ya_Gwener Gwe Gw_Sadorn Sad Sa'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    moment.locale('br');\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'un nebeud segondennoù', '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'ur vunutenn',      '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'ur vunutenn',      '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 vunutenn',     '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 munutenn',    '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'un eur',       '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'un eur',       '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 eur',       '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 eur',       '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 eur',      '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'un devezh',         '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'un devezh',         '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 zevezh',        '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'un devezh',         '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 devezh',        '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 devezh',       '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'ur miz',       '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'ur miz',       '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'ur miz',       '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 viz',      '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 viz',      '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 miz',      '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'ur miz',       '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 miz',      '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'ur bloaz',        '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 vloaz',       '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'ur bloaz',        '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 bloaz',       '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    moment.locale('br');\n    assert.equal(moment(30000).from(0), 'a-benn un nebeud segondennoù',  'prefix');\n    assert.equal(moment(0).from(30000), 'un nebeud segondennoù \\'zo', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    moment.locale('br');\n    assert.equal(moment().fromNow(), 'un nebeud segondennoù \\'zo',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    moment.locale('br');\n    assert.equal(moment().add({s: 30}).fromNow(), 'a-benn un nebeud segondennoù', 'in a few seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), 'a-benn 5 devezh', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    moment.locale('br');\n\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'Hiziv da 12e00 PM',        'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'Hiziv da 12e25 PM',        'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'Hiziv da 1e00 PM',         'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'Warc\\'hoazh da 12e00 PM',  'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'Hiziv da 11e00 AM',        'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'Dec\\'h da 12e00 PM',       'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    moment.locale('br');\n\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('dddd [da] LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd [da] LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd [da] LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    moment.locale('br');\n\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('dddd [paset da] LT'),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd [paset da] LT'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd [paset da] LT'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    moment.locale('br');\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('special mutations for years', function (assert) {\n    moment.locale('br');\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true), 'ur bloaz', 'mutation 1 year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 2}), true), '2 vloaz', 'mutation 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 3}), true), '3 bloaz', 'mutation 3 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 4}), true), '4 bloaz', 'mutation 4 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true), '5 bloaz', 'mutation 5 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 9}), true), '9 bloaz', 'mutation 9 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 10}), true), '10 vloaz', 'mutation 10 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 21}), true), '21 bloaz', 'mutation 21 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 22}), true), '22 vloaz', 'mutation 22 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 133}), true), '133 bloaz', 'mutation 133 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 148}), true), '148 vloaz', 'mutation 148 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 261}), true), '261 bloaz', 'mutation 261 years');\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\n\n\nfunction localeModule (name, lifecycle) {\n    QUnit.module('locale:' + name, {\n        setup : function () {\n            moment.locale(name);\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            moment.locale('en');\n            teardownDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n    defineCommonLocaleTests(name, -1, -1);\n}\n\nlocaleModule('bs');\n\ntest('parse', function (assert) {\n    var tests = 'januar jan._februar feb._mart mar._april apr._maj maj._juni jun._juli jul._august aug._septembar sep._oktobar okt._novembar nov._decembar dec.'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1) + ' inp ' + mmm);\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, Do MMMM YYYY, h:mm:ss a',      'nedjelja, 14. februar 2010, 3:25:50 pm'],\n            ['ddd, hA',                            'ned., 3PM'],\n            ['M Mo MM MMMM MMM',                   '2 2. 02 februar feb.'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14. 14'],\n            ['d do dddd ddd dd',                   '0 0. nedjelja ned. ne'],\n            ['DDD DDDo DDDD',                      '45 45. 045'],\n            ['w wo ww',                            '7 7. 07'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'pm PM'],\n            ['[the] DDDo [day of the year]',       'the 45. day of the year'],\n            ['LTS',                                '15:25:50'],\n            ['L',                                  '14.02.2010'],\n            ['LL',                                 '14. februar 2010'],\n            ['LLL',                                '14. februar 2010 15:25'],\n            ['LLLL',                               'nedjelja, 14. februar 2010 15:25'],\n            ['l',                                  '14.2.2010'],\n            ['ll',                                 '14. feb. 2010'],\n            ['lll',                                '14. feb. 2010 15:25'],\n            ['llll',                               'ned., 14. feb. 2010 15:25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1.', '1.');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2.', '2.');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3.', '3.');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4.', '4.');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5.', '5.');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6.', '6.');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7.', '7.');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8.', '8.');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9.', '9.');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10.', '10.');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11.', '11.');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12.', '12.');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13.', '13.');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14.', '14.');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15.', '15.');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16.', '16.');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17.', '17.');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18.', '18.');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19.', '19.');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20.', '20.');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21.', '21.');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22.', '22.');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23.', '23.');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24.', '24.');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25.', '25.');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26.', '26.');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27.', '27.');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28.', '28.');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29.', '29.');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30.', '30.');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31.', '31.');\n});\n\ntest('format month', function (assert) {\n    var expected = 'januar jan._februar feb._mart mar._april apr._maj maj._juni jun._juli jul._august aug._septembar sep._oktobar okt._novembar nov._decembar dec.'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'nedjelja ned. ne_ponedjeljak pon. po_utorak uto. ut_srijeda sri. sr_četvrtak čet. če_petak pet. pe_subota sub. su'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'par sekundi', '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'jedna minuta',   '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'jedna minuta',   '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 minute',     '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 minuta',     '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'jedan sat',      '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'jedan sat',      '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 sata',        '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 sati',         '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 sati',        '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'dan',       '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'dan',       '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 dana',        '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'dan',       '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 dana',        '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 dana',       '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'mjesec',     '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'mjesec',     '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'mjesec',     '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 mjeseca',     '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 mjeseca',     '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 mjeseca',     '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'mjesec',     '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 mjeseci',    '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'godinu',     '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 godine',       '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'godinu',     '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 godina',        '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'za par sekundi',  'prefix');\n    assert.equal(moment(0).from(30000), 'prije par sekundi', 'prefix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'prije par sekundi',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'za par sekundi', 'in a few seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), 'za 5 dana', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'danas u 12:00',  'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'danas u 12:25',  'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'danas u 13:00',  'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'sutra u 12:00',  'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'danas u 11:00',  'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'jučer u 12:00',  'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n\n    function makeFormat(d) {\n        switch (d.day()) {\n            case 0:\n                return '[u] [nedjelju] [u] LT';\n            case 3:\n                return '[u] [srijedu] [u] LT';\n            case 6:\n                return '[u] [subotu] [u] LT';\n            case 1:\n            case 2:\n            case 4:\n            case 5:\n                return '[u] dddd [u] LT';\n        }\n    }\n\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format(makeFormat(m)),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format(makeFormat(m)),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format(makeFormat(m)),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n\n    function makeFormat(d) {\n        switch (d.day()) {\n            case 0:\n            case 3:\n                return '[prošlu] dddd [u] LT';\n            case 6:\n                return '[prošle] [subote] [u] LT';\n            case 1:\n            case 2:\n            case 4:\n            case 5:\n                return '[prošli] dddd [u] LT';\n        }\n    }\n\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format(makeFormat(m)),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format(makeFormat(m)),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format(makeFormat(m)),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2011, 11, 26]).format('w ww wo'), '1 01 1.', 'Dec 26 2011 should be week 1');\n    assert.equal(moment([2012,  0,  1]).format('w ww wo'), '1 01 1.', 'Jan  1 2012 should be week 1');\n    assert.equal(moment([2012,  0,  2]).format('w ww wo'), '2 02 2.', 'Jan  2 2012 should be week 2');\n    assert.equal(moment([2012,  0,  8]).format('w ww wo'), '2 02 2.', 'Jan  8 2012 should be week 2');\n    assert.equal(moment([2012,  0,  9]).format('w ww wo'), '3 03 3.', 'Jan  9 2012 should be week 3');\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\n\n\nfunction localeModule (name, lifecycle) {\n    QUnit.module('locale:' + name, {\n        setup : function () {\n            moment.locale(name);\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            moment.locale('en');\n            teardownDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n    defineCommonLocaleTests(name, -1, -1);\n}\n\nlocaleModule('ca');\n\ntest('parse', function (assert) {\n    var tests = 'gener gen._febrer febr._març març_abril abr._maig maig_juny juny_juliol jul._agost ag._setembre set._octubre oct._novembre nov._desembre des.'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, Do MMMM YYYY, h:mm:ss a',      'diumenge, 14è de febrer 2010, 3:25:50 pm'],\n            ['ddd, hA',                            'dg., 3PM'],\n            ['M Mo MM MMMM MMM',                   '2 2n 02 febrer febr.'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14è 14'],\n            ['d do dddd ddd dd',                   '0 0è diumenge dg. Dg'],\n            ['DDD DDDo DDDD',                      '45 45è 045'],\n            ['w wo ww',                            '6 6a 06'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'pm PM'],\n            ['[the] DDDo [day of the year]',       'the 45è day of the year'],\n            ['LTS',                                '15:25:50'],\n            ['L',                                  '14/02/2010'],\n            ['LL',                                 'el 14 de febrer de 2010'],\n            ['LLL',                                'el 14 de febrer de 2010 a les 15:25'],\n            ['LLLL',                               'el diumenge 14 de febrer de 2010 a les 15:25'],\n            ['l',                                  '14/2/2010'],\n            ['ll',                                 '14 febr. 2010'],\n            ['lll',                                '14 febr. 2010, 15:25'],\n            ['llll',                               'dg. 14 febr. 2010, 15:25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1r', '1r');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2n', '2n');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3r', '3r');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4t', '4t');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5è', '5è');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6è', '6è');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7è', '7è');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8è', '8è');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9è', '9è');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10è', '10è');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11è', '11è');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12è', '12è');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13è', '13è');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14è', '14è');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15è', '15è');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16è', '16è');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17è', '17è');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18è', '18è');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19è', '19è');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20è', '20è');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21è', '21è');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22è', '22è');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23è', '23è');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24è', '24è');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25è', '25è');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26è', '26è');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27è', '27è');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28è', '28è');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29è', '29è');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30è', '30è');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31è', '31è');\n});\n\ntest('format month', function (assert) {\n    var expected = 'gener gen._febrer febr._març març_abril abr._maig maig_juny juny_juliol jul._agost ag._setembre set._octubre oct._novembre nov._desembre des.'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'diumenge dg. Dg_dilluns dl. Dl_dimarts dt. Dt_dimecres dc. Dc_dijous dj. Dj_divendres dv. Dv_dissabte ds. Ds'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'uns segons', '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'un minut',      '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'un minut',      '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 minuts',     '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 minuts',    '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'una hora',       '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'una hora',       '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 hores',       '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 hores',       '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 hores',      '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'un dia',         '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'un dia',         '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 dies',        '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'un dia',         '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 dies',        '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 dies',       '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'un mes',       '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'un mes',       '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'un mes',       '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 mesos',      '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 mesos',      '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 mesos',      '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'un mes',       '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 mesos',      '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'un any',        '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 anys',       '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'un any',        '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 anys',       '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'd\\'aquí uns segons',  'prefix');\n    assert.equal(moment(0).from(30000), 'fa uns segons', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'fa uns segons',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'd\\'aquí uns segons', 'd\\'aquí uns segons');\n    assert.equal(moment().add({d: 5}).fromNow(), 'd\\'aquí 5 dies', 'd\\'aquí 5 dies');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                       'avui a les 12:00',     'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),          'avui a les 12:25',     'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),           'avui a les 13:00',     'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),           'demà a les 12:00',     'tomorrow at the same time');\n    assert.equal(moment(a).add({d: 1, h : -1}).calendar(),   'demà a les 11:00',     'tomorrow minus 1 hour');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),      'avui a les 11:00',     'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),      'ahir a les 12:00',     'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('dddd [a ' + ((m.hours() !== 1) ? 'les' : 'la') + '] LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd [a ' + ((m.hours() !== 1) ? 'les' : 'la') + '] LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd [a ' + ((m.hours() !== 1) ? 'les' : 'la') + '] LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('[el] dddd [passat a ' + ((m.hours() !== 1) ? 'les' : 'la') + '] LT'),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[el] dddd [passat a ' + ((m.hours() !== 1) ? 'les' : 'la') + '] LT'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[el] dddd [passat a ' + ((m.hours() !== 1) ? 'les' : 'la') + '] LT'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2012, 0,  1]).format('w ww wo'), '52 52 52a', 'Jan  1 2012 should be week 52');\n    assert.equal(moment([2012, 0,  2]).format('w ww wo'),   '1 01 1a', 'Jan  2 2012 should be week 1');\n    assert.equal(moment([2012, 0,  8]).format('w ww wo'),   '1 01 1a', 'Jan  8 2012 should be week 1');\n    assert.equal(moment([2012, 0,  9]).format('w ww wo'),   '2 02 2a', 'Jan  9 2012 should be week 2');\n    assert.equal(moment([2012, 0, 15]).format('w ww wo'),   '2 02 2a', 'Jan 15 2012 should be week 2');\n});\n\ntest('day and month', function (assert) {\n    assert.equal(moment([2012, 1, 15]).format('D MMMM'), '15 de febrer');\n    assert.equal(moment([2012, 9, 15]).format('D MMMM'), '15 d\\'octubre');\n    assert.equal(moment([2012, 9, 15]).format('MMMM, D'), 'octubre, 15');\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\n\n\nfunction localeModule (name, lifecycle) {\n    QUnit.module('locale:' + name, {\n        setup : function () {\n            moment.locale(name);\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            moment.locale('en');\n            teardownDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n    defineCommonLocaleTests(name, -1, -1);\n}\n\nlocaleModule('cs');\n\ntest('parse', function (assert) {\n    var tests = 'leden led_únor úno_březen bře_duben dub_květen kvě_červen čvn_červenec čvc_srpen srp_září zář_říjen říj_listopad lis_prosinec pro'.split('_'), i;\n    function equalTest(input, mmm, monthIndex) {\n        assert.equal(moment(input, mmm).month(), monthIndex, input + ' ' + mmm + ' should be month ' + (monthIndex + 1));\n    }\n    function equalTestStrict(input, mmm, monthIndex) {\n        assert.equal(moment(input, mmm, true).month(), monthIndex, input + ' ' + mmm + ' should be strict month ' + (monthIndex + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n\n        equalTestStrict(tests[i][1], 'MMM', i);\n        equalTestStrict(tests[i][0], 'MMMM', i);\n        equalTestStrict(tests[i][1].toLocaleLowerCase(), 'MMM', i);\n        equalTestStrict(tests[i][1].toLocaleUpperCase(), 'MMM', i);\n        equalTestStrict(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTestStrict(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, MMMM Do YYYY, h:mm:ss',  'neděle, únor 14. 2010, 3:25:50'],\n            ['ddd, h',                       'ne, 3'],\n            ['M Mo MM MMMM MMM',             '2 2. 02 únor úno'],\n            ['YYYY YY',                      '2010 10'],\n            ['D Do DD',                      '14 14. 14'],\n            ['d do dddd ddd dd',             '0 0. neděle ne ne'],\n            ['DDD DDDo DDDD',                '45 45. 045'],\n            ['w wo ww',                      '6 6. 06'],\n            ['h hh',                         '3 03'],\n            ['H HH',                         '15 15'],\n            ['m mm',                         '25 25'],\n            ['s ss',                         '50 50'],\n            ['a A',                          'pm PM'],\n            ['DDDo [den v roce]',            '45. den v roce'],\n            ['LTS',                          '15:25:50'],\n            ['L',                            '14.02.2010'],\n            ['LL',                           '14. únor 2010'],\n            ['LLL',                          '14. únor 2010 15:25'],\n            ['LLLL',                         'neděle 14. únor 2010 15:25'],\n            ['l',                            '14. 2. 2010'],\n            ['ll',                           '14. úno 2010'],\n            ['lll',                          '14. úno 2010 15:25'],\n            ['llll',                         'ne 14. úno 2010 15:25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1.', '1.');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2.', '2.');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3.', '3.');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4.', '4.');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5.', '5.');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6.', '6.');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7.', '7.');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8.', '8.');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9.', '9.');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10.', '10.');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11.', '11.');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12.', '12.');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13.', '13.');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14.', '14.');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15.', '15.');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16.', '16.');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17.', '17.');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18.', '18.');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19.', '19.');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20.', '20.');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21.', '21.');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22.', '22.');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23.', '23.');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24.', '24.');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25.', '25.');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26.', '26.');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27.', '27.');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28.', '28.');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29.', '29.');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30.', '30.');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31.', '31.');\n});\n\ntest('format month', function (assert) {\n    var expected = 'leden led_únor úno_březen bře_duben dub_květen kvě_červen čvn_červenec čvc_srpen srp_září zář_říjen říj_listopad lis_prosinec pro'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'neděle ne ne_pondělí po po_úterý út út_středa st st_čtvrtek čt čt_pátek pá pá_sobota so so'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'pár sekund',  '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'minuta',        '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'minuta',        '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 minuty',      '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 minut',     '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'hodina',       '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'hodina',       '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 hodiny',     '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 hodin',      '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 hodin',     '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'den',       '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'den',       '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 dny',         '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'den',       '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 dní',         '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 dní',        '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'měsíc',       '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'měsíc',       '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'měsíc',       '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 měsíce',    '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 měsíce',    '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 měsíce',    '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'měsíc',       '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 měsíců',    '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'rok',           '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 roky',        '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'rok',           '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 let',         '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'za pár sekund',  'prefix');\n    assert.equal(moment(0).from(30000), 'před pár sekundami', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'před pár sekundami',  'now from now should display as in the past');\n});\n\ntest('fromNow (future)', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'za pár sekund', 'in a few seconds');\n    assert.equal(moment().add({m: 1}).fromNow(), 'za minutu', 'in a minute');\n    assert.equal(moment().add({m: 3}).fromNow(), 'za 3 minuty', 'in 3 minutes');\n    assert.equal(moment().add({m: 10}).fromNow(), 'za 10 minut', 'in 10 minutes');\n    assert.equal(moment().add({h: 1}).fromNow(), 'za hodinu', 'in an hour');\n    assert.equal(moment().add({h: 3}).fromNow(), 'za 3 hodiny', 'in 3 hours');\n    assert.equal(moment().add({h: 10}).fromNow(), 'za 10 hodin', 'in 10 hours');\n    assert.equal(moment().add({d: 1}).fromNow(), 'za den', 'in a day');\n    assert.equal(moment().add({d: 3}).fromNow(), 'za 3 dny', 'in 3 days');\n    assert.equal(moment().add({d: 10}).fromNow(), 'za 10 dní', 'in 10 days');\n    assert.equal(moment().add({M: 1}).fromNow(), 'za měsíc', 'in a month');\n    assert.equal(moment().add({M: 3}).fromNow(), 'za 3 měsíce', 'in 3 months');\n    assert.equal(moment().add({M: 10}).fromNow(), 'za 10 měsíců', 'in 10 months');\n    assert.equal(moment().add({y: 1}).fromNow(), 'za rok', 'in a year');\n    assert.equal(moment().add({y: 3}).fromNow(), 'za 3 roky', 'in 3 years');\n    assert.equal(moment().add({y: 10}).fromNow(), 'za 10 let', 'in 10 years');\n});\n\ntest('fromNow (past)', function (assert) {\n    assert.equal(moment().subtract({s: 30}).fromNow(), 'před pár sekundami', 'a few seconds ago');\n    assert.equal(moment().subtract({m: 1}).fromNow(), 'před minutou', 'a minute ago');\n    assert.equal(moment().subtract({m: 3}).fromNow(), 'před 3 minutami', '3 minutes ago');\n    assert.equal(moment().subtract({m: 10}).fromNow(), 'před 10 minutami', '10 minutes ago');\n    assert.equal(moment().subtract({h: 1}).fromNow(), 'před hodinou', 'an hour ago');\n    assert.equal(moment().subtract({h: 3}).fromNow(), 'před 3 hodinami', '3 hours ago');\n    assert.equal(moment().subtract({h: 10}).fromNow(), 'před 10 hodinami', '10 hours ago');\n    assert.equal(moment().subtract({d: 1}).fromNow(), 'před dnem', 'a day ago');\n    assert.equal(moment().subtract({d: 3}).fromNow(), 'před 3 dny', '3 days ago');\n    assert.equal(moment().subtract({d: 10}).fromNow(), 'před 10 dny', '10 days ago');\n    assert.equal(moment().subtract({M: 1}).fromNow(), 'před měsícem', 'a month ago');\n    assert.equal(moment().subtract({M: 3}).fromNow(), 'před 3 měsíci', '3 months ago');\n    assert.equal(moment().subtract({M: 10}).fromNow(), 'před 10 měsíci', '10 months ago');\n    assert.equal(moment().subtract({y: 1}).fromNow(), 'před rokem', 'a year ago');\n    assert.equal(moment().subtract({y: 3}).fromNow(), 'před 3 lety', '3 years ago');\n    assert.equal(moment().subtract({y: 10}).fromNow(), 'před 10 lety', '10 years ago');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'dnes v 12:00',     'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'dnes v 12:25',     'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'dnes v 13:00',     'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'zítra v 12:00',    'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'dnes v 11:00',     'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'včera v 12:00',    'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m, nextDay;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        nextDay = '';\n        switch (m.day()) {\n            case 0:\n                nextDay = 'v neděli';\n                break;\n            case 1:\n                nextDay = 'v pondělí';\n                break;\n            case 2:\n                nextDay = 'v úterý';\n                break;\n            case 3:\n                nextDay = 've středu';\n                break;\n            case 4:\n                nextDay = 've čtvrtek';\n                break;\n            case 5:\n                nextDay = 'v pátek';\n                break;\n            case 6:\n                nextDay = 'v sobotu';\n                break;\n        }\n        assert.equal(m.calendar(),       m.format('[' + nextDay + '] [v] LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[' + nextDay + '] [v] LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[' + nextDay + '] [v] LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m, lastDay;\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        lastDay = '';\n        switch (m.day()) {\n            case 0:\n                lastDay = 'minulou neděli';\n                break;\n            case 1:\n                lastDay = 'minulé pondělí';\n                break;\n            case 2:\n                lastDay = 'minulé úterý';\n                break;\n            case 3:\n                lastDay = 'minulou středu';\n                break;\n            case 4:\n                lastDay = 'minulý čtvrtek';\n                break;\n            case 5:\n                lastDay = 'minulý pátek';\n                break;\n            case 6:\n                lastDay = 'minulou sobotu';\n                break;\n        }\n        assert.equal(m.calendar(),       m.format('[' + lastDay + '] [v] LT'),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[' + lastDay + '] [v] LT'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[' + lastDay + '] [v] LT'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('humanize duration', function (assert) {\n    assert.equal(moment.duration(1, 'minutes').humanize(), 'minuta', 'a minute (future)');\n    assert.equal(moment.duration(1, 'minutes').humanize(true), 'za minutu', 'in a minute');\n    assert.equal(moment.duration(-1, 'minutes').humanize(), 'minuta', 'a minute (past)');\n    assert.equal(moment.duration(-1, 'minutes').humanize(true), 'před minutou', 'a minute ago');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2012, 0,  1]).format('w ww wo'), '52 52 52.', 'Jan  1 2012 should be week 52');\n    assert.equal(moment([2012, 0,  2]).format('w ww wo'),   '1 01 1.', 'Jan  2 2012 should be week 1');\n    assert.equal(moment([2012, 0,  8]).format('w ww wo'),   '1 01 1.', 'Jan  8 2012 should be week 1');\n    assert.equal(moment([2012, 0,  9]).format('w ww wo'),   '2 02 2.', 'Jan  9 2012 should be week 2');\n    assert.equal(moment([2012, 0, 15]).format('w ww wo'),   '2 02 2.', 'Jan 15 2012 should be week 2');\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\n\n\nfunction localeModule (name, lifecycle) {\n    QUnit.module('locale:' + name, {\n        setup : function () {\n            moment.locale(name);\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            moment.locale('en');\n            teardownDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n    defineCommonLocaleTests(name, -1, -1);\n}\n\nlocaleModule('cv');\n\ntest('parse', function (assert) {\n    var tests = 'кӑрлач кӑр_нарӑс нар_пуш пуш_ака ака_май май_ҫӗртме ҫӗр_утӑ утӑ_ҫурла ҫур_авӑн авн_юпа юпа_чӳк чӳк_раштав раш'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, MMMM Do YYYY, h:mm:ss a',      'вырсарникун, нарӑс 14-мӗш 2010, 3:25:50 pm'],\n            ['ddd, hA',                            'выр, 3PM'],\n            ['M Mo MM MMMM MMM',                   '2 2-мӗш 02 нарӑс нар'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14-мӗш 14'],\n            ['d do dddd ddd dd',                   '0 0-мӗш вырсарникун выр вр'],\n            ['DDD DDDo DDDD',                      '45 45-мӗш 045'],\n            ['w wo ww',                            '7 7-мӗш 07'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'pm PM'],\n            ['Ҫулӑн DDDo кунӗ',                    'Ҫулӑн 45-мӗш кунӗ'],\n            ['LTS',                                '15:25:50'],\n            ['L',                                  '14-02-2010'],\n            ['LL',                                 '2010 ҫулхи нарӑс уйӑхӗн 14-мӗшӗ'],\n            ['LLL',                                '2010 ҫулхи нарӑс уйӑхӗн 14-мӗшӗ, 15:25'],\n            ['LLLL',                               'вырсарникун, 2010 ҫулхи нарӑс уйӑхӗн 14-мӗшӗ, 15:25'],\n            ['l',                                  '14-2-2010'],\n            ['ll',                                 '2010 ҫулхи нар уйӑхӗн 14-мӗшӗ'],\n            ['lll',                                '2010 ҫулхи нар уйӑхӗн 14-мӗшӗ, 15:25'],\n            ['llll',                               'выр, 2010 ҫулхи нар уйӑхӗн 14-мӗшӗ, 15:25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1-мӗш', '1-мӗш');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2-мӗш', '2-мӗш');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3-мӗш', '3-мӗш');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4-мӗш', '4-мӗш');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5-мӗш', '5-мӗш');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6-мӗш', '6-мӗш');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7-мӗш', '7-мӗш');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8-мӗш', '8-мӗш');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9-мӗш', '9-мӗш');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10-мӗш', '10-мӗш');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11-мӗш', '11-мӗш');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12-мӗш', '12-мӗш');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13-мӗш', '13-мӗш');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14-мӗш', '14-мӗш');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15-мӗш', '15-мӗш');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16-мӗш', '16-мӗш');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17-мӗш', '17-мӗш');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18-мӗш', '18-мӗш');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19-мӗш', '19-мӗш');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20-мӗш', '20-мӗш');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21-мӗш', '21-мӗш');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22-мӗш', '22-мӗш');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23-мӗш', '23-мӗш');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24-мӗш', '24-мӗш');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25-мӗш', '25-мӗш');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26-мӗш', '26-мӗш');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27-мӗш', '27-мӗш');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28-мӗш', '28-мӗш');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29-мӗш', '29-мӗш');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30-мӗш', '30-мӗш');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31-мӗш', '31-мӗш');\n});\n\ntest('format month', function (assert) {\n    var expected = 'кӑрлач кӑр_нарӑс нар_пуш пуш_ака ака_май май_ҫӗртме ҫӗр_утӑ утӑ_ҫурла ҫур_авӑн авн_юпа юпа_чӳк чӳк_раштав раш'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'вырсарникун выр вр_тунтикун тун тн_ытларикун ытл ыт_юнкун юн юн_кӗҫнерникун кӗҫ кҫ_эрнекун эрн эр_шӑматкун шӑм шм'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'пӗр-ик ҫеккунт', '44 sekunder = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'пӗр минут',      '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'пӗр минут',      '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 минут',     '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 минут',    '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'пӗр сехет',       '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'пӗр сехет',       '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 сехет',       '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 сехет',       '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 сехет',      '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'пӗр кун',         '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'пӗр кун',         '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 кун',        '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'пӗр кун',         '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 кун',        '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 кун',       '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'пӗр уйӑх',       '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'пӗр уйӑх',       '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'пӗр уйӑх',       '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 уйӑх',      '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 уйӑх',      '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 уйӑх',      '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'пӗр уйӑх',       '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 уйӑх',      '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'пӗр ҫул',        '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 ҫул',       '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'пӗр ҫул',        '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 ҫул',       '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'пӗр-ик ҫеккунтран',  'prefix');\n    assert.equal(moment(0).from(30000), 'пӗр-ик ҫеккунт каялла', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'пӗр-ик ҫеккунт каялла',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'пӗр-ик ҫеккунтран', 'in a few seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), '5 кунран', 'in 5 days');\n    assert.equal(moment().add({h: 2}).fromNow(), '2 сехетрен', 'in 2 hours, the right suffix!');\n    assert.equal(moment().add({y: 3}).fromNow(), '3 ҫултан', 'in 3 years, the right suffix!');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n    assert.equal(moment(a).calendar(),                   'Паян 12:00 сехетре',     'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'Паян 12:25 сехетре',     'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'Паян 13:00 сехетре',     'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'Ыран 12:00 сехетре',     'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'Паян 11:00 сехетре',     'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'Ӗнер 12:00 сехетре',     'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('[Ҫитес] dddd LT [сехетре]'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[Ҫитес] dddd LT [сехетре]'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[Ҫитес] dddd LT [сехетре]'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('[Иртнӗ] dddd LT [сехетре]'),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[Иртнӗ] dddd LT [сехетре]'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[Иртнӗ] dddd LT [сехетре]'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\n// Monday is the first day of the week.\n// The week that contains Jan 1st is the first week of the year.\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2011, 11, 26]).format('w ww wo'), '1 01 1-мӗш', 'Dec 26 2011 should be week 1');\n    assert.equal(moment([2012,  0,  1]).format('w ww wo'), '1 01 1-мӗш', 'Jan  1 2012 should be week 1');\n    assert.equal(moment([2012,  0,  2]).format('w ww wo'), '2 02 2-мӗш', 'Jan  2 2012 should be week 2');\n    assert.equal(moment([2012,  0,  8]).format('w ww wo'), '2 02 2-мӗш', 'Jan  8 2012 should be week 2');\n    assert.equal(moment([2012,  0,  9]).format('w ww wo'), '3 03 3-мӗш', 'Jan  9 2012 should be week 3');\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\n\n\nfunction localeModule (name, lifecycle) {\n    QUnit.module('locale:' + name, {\n        setup : function () {\n            moment.locale(name);\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            moment.locale('en');\n            teardownDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n    defineCommonLocaleTests(name, -1, -1);\n}\n\nlocaleModule('cy');\n\ntest('parse', function (assert) {\n    var tests = 'Ionawr Ion_Chwefror Chwe_Mawrth Maw_Ebrill Ebr_Mai Mai_Mehefin Meh_Gorffennaf Gor_Awst Aws_Medi Med_Hydref Hyd_Tachwedd Tach_Rhagfyr Rhag'.split('_'),\n        i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, MMMM Do YYYY, h:mm:ss a',      'Dydd Sul, Chwefror 14eg 2010, 3:25:50 pm'],\n            ['ddd, hA',                            'Sul, 3PM'],\n            ['M Mo MM MMMM MMM',                   '2 2il 02 Chwefror Chwe'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14eg 14'],\n            ['d do dddd ddd dd',                   '0 0 Dydd Sul Sul Su'],\n            ['DDD DDDo DDDD',                      '45 45ain 045'],\n            ['w wo ww',                            '6 6ed 06'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'pm PM'],\n            ['[the] DDDo [day of the year]',       'the 45ain day of the year'],\n            ['LTS',                                '15:25:50'],\n            ['L',                                  '14/02/2010'],\n            ['LL',                                 '14 Chwefror 2010'],\n            ['LLL',                                '14 Chwefror 2010 15:25'],\n            ['LLLL',                               'Dydd Sul, 14 Chwefror 2010 15:25'],\n            ['l',                                  '14/2/2010'],\n            ['ll',                                 '14 Chwe 2010'],\n            ['lll',                                '14 Chwe 2010 15:25'],\n            ['llll',                               'Sul, 14 Chwe 2010 15:25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1af', '1af');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2il', '2il');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3ydd', '3ydd');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4ydd', '4ydd');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5ed', '5ed');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6ed', '6ed');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7ed', '7ed');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8fed', '8fed');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9fed', '9fed');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10fed', '10fed');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11eg', '11eg');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12fed', '12fed');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13eg', '13eg');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14eg', '14eg');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15fed', '15fed');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16eg', '16eg');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17eg', '17eg');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18fed', '18fed');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19eg', '19eg');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20fed', '20fed');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21ain', '21ain');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22ain', '22ain');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23ain', '23ain');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24ain', '24ain');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25ain', '25ain');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26ain', '26ain');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27ain', '27ain');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28ain', '28ain');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29ain', '29ain');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30ain', '30ain');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31ain', '31ain');\n});\n\ntest('format month', function (assert) {\n    var expected = 'Ionawr Ion_Chwefror Chwe_Mawrth Maw_Ebrill Ebr_Mai Mai_Mehefin Meh_Gorffennaf Gor_Awst Aws_Medi Med_Hydref Hyd_Tachwedd Tach_Rhagfyr Rhag'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'Dydd Sul Sul Su_Dydd Llun Llun Ll_Dydd Mawrth Maw Ma_Dydd Mercher Mer Me_Dydd Iau Iau Ia_Dydd Gwener Gwe Gw_Dydd Sadwrn Sad Sa'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'ychydig eiliadau', '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'munud',   '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'munud',   '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 munud',  '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 munud', '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'awr',    '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'awr',    '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 awr',    '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 awr',    '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 awr',   '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'diwrnod',      '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'diwrnod',      '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 diwrnod',     '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'diwrnod',      '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 diwrnod',     '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 diwrnod',    '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'mis',    '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'mis',    '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'mis',    '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 mis',   '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 mis',   '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 mis',   '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'mis',    '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 mis',   '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'blwyddyn',     '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 flynedd',    '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'blwyddyn',     '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 flynedd',    '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'mewn ychydig eiliadau', 'prefix');\n    assert.equal(moment(0).from(30000), 'ychydig eiliadau yn ôl', 'suffix');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'mewn ychydig eiliadau', 'in a few seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), 'mewn 5 diwrnod', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'Heddiw am 12:00',    'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'Heddiw am 12:25',    'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'Heddiw am 13:00',    'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'Yfory am 12:00',     'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'Heddiw am 11:00',    'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'Ddoe am 12:00',      'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('dddd [am] LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd [am] LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd [am] LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('dddd [diwethaf am] LT'),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd [diwethaf am] LT'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd [diwethaf am] LT'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2012, 0,  1]).format('w ww wo'), '52 52 52ain', 'Jan  1 2012 should be week 52');\n    assert.equal(moment([2012, 0,  2]).format('w ww wo'), '1 01 1af', 'Jan  2 2012 should be week 1');\n    assert.equal(moment([2012, 0,  8]).format('w ww wo'), '1 01 1af', 'Jan  8 2012 should be week 1');\n    assert.equal(moment([2012, 0,  9]).format('w ww wo'),   '2 02 2il', 'Jan  9 2012 should be week 2');\n    assert.equal(moment([2012, 0, 15]).format('w ww wo'),   '2 02 2il', 'Jan 15 2012 should be week 2');\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\n\n\nfunction localeModule (name, lifecycle) {\n    QUnit.module('locale:' + name, {\n        setup : function () {\n            moment.locale(name);\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            moment.locale('en');\n            teardownDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n    defineCommonLocaleTests(name, -1, -1);\n}\n\nlocaleModule('da');\n\ntest('parse', function (assert) {\n    var tests = 'januar jan_februar feb_marts mar_april apr_maj maj_juni jun_juli jul_august aug_september sep_oktober okt_november nov_december dec'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd [den] Do MMMM YYYY, h:mm:ss a', 'søndag den 14. februar 2010, 3:25:50 pm'],\n            ['ddd hA',                             'søn 3PM'],\n            ['M Mo MM MMMM MMM',                   '2 2. 02 februar feb'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14. 14'],\n            ['d do dddd ddd dd',                   '0 0. søndag søn sø'],\n            ['DDD DDDo DDDD',                      '45 45. 045'],\n            ['w wo ww',                            '6 6. 06'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'pm PM'],\n            ['[den] DDDo [dag på året]',           'den 45. dag på året'],\n            ['LTS',                                '15:25:50'],\n            ['L',                                  '14/02/2010'],\n            ['LL',                                 '14. februar 2010'],\n            ['LLL',                                '14. februar 2010 15:25'],\n            ['LLLL',                               'søndag d. 14. februar 2010 kl. 15:25'],\n            ['l',                                  '14/2/2010'],\n            ['ll',                                 '14. feb 2010'],\n            ['lll',                                '14. feb 2010 15:25'],\n            ['llll',                               'søn d. 14. feb 2010 kl. 15:25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1.', '1.');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2.', '2.');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3.', '3.');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4.', '4.');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5.', '5.');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6.', '6.');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7.', '7.');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8.', '8.');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9.', '9.');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10.', '10.');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11.', '11.');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12.', '12.');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13.', '13.');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14.', '14.');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15.', '15.');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16.', '16.');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17.', '17.');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18.', '18.');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19.', '19.');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20.', '20.');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21.', '21.');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22.', '22.');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23.', '23.');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24.', '24.');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25.', '25.');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26.', '26.');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27.', '27.');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28.', '28.');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29.', '29.');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30.', '30.');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31.', '31.');\n});\n\ntest('format month', function (assert) {\n    var expected = 'januar jan_februar feb_marts mar_april apr_maj maj_juni jun_juli jul_august aug_september sep_oktober okt_november nov_december dec'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'søndag søn sø_mandag man ma_tirsdag tir ti_onsdag ons on_torsdag tor to_fredag fre fr_lørdag lør lø'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'få sekunder', '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'et minut',    '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'et minut',    '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 minutter',  '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 minutter', '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'en time',     '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'en time',     '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 timer',     '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 timer',     '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 timer',    '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'en dag',      '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'en dag',      '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 dage',      '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'en dag',      '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 dage',      '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 dage',     '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'en måned',    '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'en måned',    '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'en måned',    '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 måneder',   '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 måneder',   '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 måneder',   '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'en måned',    '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 måneder',   '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'et år',       '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 år',        '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'et år',       '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 år',        '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'om få sekunder',  'prefix');\n    assert.equal(moment(0).from(30000), 'få sekunder siden', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'få sekunder siden',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'om få sekunder', 'in a few seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), 'om 5 dage', 'in 5 days');\n});\n\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'i dag kl. 12:00',    'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'i dag kl. 12:25',    'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'i dag kl. 13:00',    'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'i morgen kl. 12:00', 'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'i dag kl. 11:00',    'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'i går kl. 12:00',    'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('på dddd [kl.] LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('på dddd [kl.] LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('på dddd [kl.] LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('[i] dddd[s kl.] LT'),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[i] dddd[s kl.] LT'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[i] dddd[s kl.] LT'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2012, 0,  1]).format('w ww wo'), '52 52 52.', 'Jan  1 2012 should be week 52');\n    assert.equal(moment([2012, 0,  2]).format('w ww wo'),   '1 01 1.', 'Jan  2 2012 should be week 1');\n    assert.equal(moment([2012, 0,  8]).format('w ww wo'),   '1 01 1.', 'Jan  8 2012 should be week 1');\n    assert.equal(moment([2012, 0,  9]).format('w ww wo'),   '2 02 2.', 'Jan  9 2012 should be week 2');\n    assert.equal(moment([2012, 0, 15]).format('w ww wo'),   '2 02 2.', 'Jan 15 2012 should be week 2');\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\n\n\nfunction localeModule (name, lifecycle) {\n    QUnit.module('locale:' + name, {\n        setup : function () {\n            moment.locale(name);\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            moment.locale('en');\n            teardownDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n    defineCommonLocaleTests(name, -1, -1);\n}\n\nlocaleModule('de-at');\n\ntest('parse', function (assert) {\n    var tests = 'Jänner Jän._Februar Febr._März Mrz._April Apr._Mai Mai_Juni Jun._Juli Jul._August Aug._September Sept._Oktober Okt._November Nov._Dezember Dez.'.split('_'), i;\n\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, Do MMMM YYYY, h:mm:ss a', 'Sonntag, 14. Februar 2010, 3:25:50 pm'],\n            ['ddd, hA', 'So., 3PM'],\n            ['M Mo MM MMMM MMM', '2 2. 02 Februar Febr.'],\n            ['YYYY YY', '2010 10'],\n            ['D Do DD', '14 14. 14'],\n            ['d do dddd ddd dd', '0 0. Sonntag So. So'],\n            ['DDD DDDo DDDD', '45 45. 045'],\n            ['w wo ww', '6 6. 06'],\n            ['h hh', '3 03'],\n            ['H HH', '15 15'],\n            ['m mm', '25 25'],\n            ['s ss', '50 50'],\n            ['a A', 'pm PM'],\n            ['[the] DDDo [day of the year]', 'the 45. day of the year'],\n            ['LTS', '15:25:50'],\n            ['L', '14.02.2010'],\n            ['LL', '14. Februar 2010'],\n            ['LLL', '14. Februar 2010 15:25'],\n            ['LLLL', 'Sonntag, 14. Februar 2010 15:25'],\n            ['l', '14.2.2010'],\n            ['ll', '14. Febr. 2010'],\n            ['lll', '14. Febr. 2010 15:25'],\n            ['llll', 'So., 14. Febr. 2010 15:25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1.', '1.');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2.', '2.');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3.', '3.');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4.', '4.');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5.', '5.');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6.', '6.');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7.', '7.');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8.', '8.');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9.', '9.');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10.', '10.');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11.', '11.');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12.', '12.');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13.', '13.');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14.', '14.');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15.', '15.');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16.', '16.');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17.', '17.');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18.', '18.');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19.', '19.');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20.', '20.');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21.', '21.');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22.', '22.');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23.', '23.');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24.', '24.');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25.', '25.');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26.', '26.');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27.', '27.');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28.', '28.');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29.', '29.');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30.', '30.');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31.', '31.');\n});\n\ntest('format month', function (assert) {\n    var expected = 'Jänner Jän._Februar Febr._März Mrz._April Apr._Mai Mai_Juni Jun._Juli Jul._August Aug._September Sept._Oktober Okt._November Nov._Dezember Dez.'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'Sonntag So. So_Montag Mo. Mo_Dienstag Di. Di_Mittwoch Mi. Mi_Donnerstag Do. Do_Freitag Fr. Fr_Samstag Sa. Sa'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true), 'ein paar Sekunden', '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true), 'eine Minute', '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true), 'eine Minute', '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true), '2 Minuten', '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true), '44 Minuten', '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true), 'eine Stunde', '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true), 'eine Stunde', '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true), '2 Stunden', '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true), '5 Stunden', '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true), '21 Stunden', '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true), 'ein Tag', '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true), 'ein Tag', '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true), '2 Tage', '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true), 'ein Tag', '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true), '5 Tage', '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true), '25 Tage', '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true), 'ein Monat', '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true), 'ein Monat', '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true), '2 Monate', '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true), '2 Monate', '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true), '3 Monate', '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true), 'ein Monat', '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true), '5 Monate', '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'ein Jahr', '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 Jahre', '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true), 'ein Jahr', '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true), '5 Jahre', '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'in ein paar Sekunden', 'prefix');\n    assert.equal(moment(0).from(30000), 'vor ein paar Sekunden', 'suffix');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'in ein paar Sekunden', 'in a few seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), 'in 5 Tagen', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                  'heute um 12:00 Uhr',   'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),     'heute um 12:25 Uhr',   'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),      'heute um 13:00 Uhr',   'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),      'morgen um 12:00 Uhr',  'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(), 'heute um 11:00 Uhr',   'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(), 'gestern um 12:00 Uhr', 'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(), m.format('dddd [um] LT [Uhr]'), 'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(), m.format('dddd [um] LT [Uhr]'), 'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(), m.format('dddd [um] LT [Uhr]'), 'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(), m.format('[letzten] dddd [um] LT [Uhr]'), 'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(), m.format('[letzten] dddd [um] LT [Uhr]'), 'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(), m.format('[letzten] dddd [um] LT [Uhr]'), 'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '1 week ago');\n    assert.equal(weeksFromNow.calendar(), weeksFromNow.format('L'), 'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(), weeksFromNow.format('L'), 'in 2 weeks');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2012, 0, 1]).format('w ww wo'), '52 52 52.', 'Jan  1 2012 should be week 52');\n    assert.equal(moment([2012, 0, 2]).format('w ww wo'), '1 01 1.', 'Jan  2 2012 should be week 1');\n    assert.equal(moment([2012, 0, 8]).format('w ww wo'), '1 01 1.', 'Jan  8 2012 should be week 1');\n    assert.equal(moment([2012, 0, 9]).format('w ww wo'), '2 02 2.', 'Jan  9 2012 should be week 2');\n    assert.equal(moment([2012, 0, 15]).format('w ww wo'), '2 02 2.', 'Jan 15 2012 should be week 2');\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\n\n\nfunction localeModule (name, lifecycle) {\n    QUnit.module('locale:' + name, {\n        setup : function () {\n            moment.locale(name);\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            moment.locale('en');\n            teardownDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n    defineCommonLocaleTests(name, -1, -1);\n}\n\nlocaleModule('de-ch');\n\ntest('parse', function (assert) {\n    var tests = 'Januar Jan._Februar Febr._März März_April April_Mai Mai_Juni Juni_Juli Juli_August Aug._September Sept._Oktober Okt._November Nov._Dezember Dez.'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, Do MMMM YYYY, h.mm.ss a',      'Sonntag, 14. Februar 2010, 3.25.50 pm'],\n            ['ddd, hA',                            'So, 3PM'],\n            ['M Mo MM MMMM MMM',                   '2 2. 02 Februar Febr.'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14. 14'],\n            ['d do dddd ddd dd',                   '0 0. Sonntag So So'],\n            ['DDD DDDo DDDD',                      '45 45. 045'],\n            ['w wo ww',                            '6 6. 06'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'pm PM'],\n            ['[the] DDDo [day of the year]',       'the 45. day of the year'],\n            ['LTS',                                '15.25.50'],\n            ['L',                                  '14.02.2010'],\n            ['LL',                                 '14. Februar 2010'],\n            ['LLL',                                '14. Februar 2010 15.25'],\n            ['LLLL',                               'Sonntag, 14. Februar 2010 15.25'],\n            ['l',                                  '14.2.2010'],\n            ['ll',                                 '14. Febr. 2010'],\n            ['lll',                                '14. Febr. 2010 15.25'],\n            ['llll',                               'So, 14. Febr. 2010 15.25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1.', '1.');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2.', '2.');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3.', '3.');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4.', '4.');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5.', '5.');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6.', '6.');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7.', '7.');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8.', '8.');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9.', '9.');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10.', '10.');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11.', '11.');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12.', '12.');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13.', '13.');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14.', '14.');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15.', '15.');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16.', '16.');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17.', '17.');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18.', '18.');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19.', '19.');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20.', '20.');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21.', '21.');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22.', '22.');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23.', '23.');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24.', '24.');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25.', '25.');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26.', '26.');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27.', '27.');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28.', '28.');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29.', '29.');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30.', '30.');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31.', '31.');\n});\n\ntest('format month', function (assert) {\n    var expected = 'Januar Jan._Februar Febr._März März_April April_Mai Mai_Juni Juni_Juli Juli_August Aug._September Sept._Oktober Okt._November Nov._Dezember Dez.'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'Sonntag So So_Montag Mo Mo_Dienstag Di Di_Mittwoch Mi Mi_Donnerstag Do Do_Freitag Fr Fr_Samstag Sa Sa'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'ein paar Sekunden',  '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'eine Minute',       '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'eine Minute',       '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 Minuten',          '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 Minuten',         '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'eine Stunde',       '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'eine Stunde',       '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 Stunden',          '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 Stunden',          '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 Stunden',         '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'ein Tag',          '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'ein Tag',          '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 Tage',            '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'ein Tag',          '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 Tage',            '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 Tage',           '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'ein Monat',        '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'ein Monat',        '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'ein Monat',        '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 Monate',          '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 Monate',          '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 Monate',          '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'ein Monat',        '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 Monate',          '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'ein Jahr',         '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 Jahre',           '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'ein Jahr',         '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 Jahre',           '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'in ein paar Sekunden', 'prefix');\n    assert.equal(moment(0).from(30000), 'vor ein paar Sekunden', 'suffix');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'in ein paar Sekunden', 'in a few seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), 'in 5 Tagen', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'heute um 12.00 Uhr',   'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'heute um 12.25 Uhr',   'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'heute um 13.00 Uhr',   'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'morgen um 12.00 Uhr',  'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'heute um 11.00 Uhr',   'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'gestern um 12.00 Uhr', 'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('dddd [um] LT [Uhr]'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd [um] LT [Uhr]'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd [um] LT [Uhr]'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('[letzten] dddd [um] LT [Uhr]'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[letzten] dddd [um] LT [Uhr]'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[letzten] dddd [um] LT [Uhr]'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2012, 0,  1]).format('w ww wo'), '52 52 52.', 'Jan  1 2012 should be week 52');\n    assert.equal(moment([2012, 0,  2]).format('w ww wo'),   '1 01 1.', 'Jan  2 2012 should be week 1');\n    assert.equal(moment([2012, 0,  8]).format('w ww wo'),   '1 01 1.', 'Jan  8 2012 should be week 1');\n    assert.equal(moment([2012, 0,  9]).format('w ww wo'),   '2 02 2.', 'Jan  9 2012 should be week 2');\n    assert.equal(moment([2012, 0, 15]).format('w ww wo'),   '2 02 2.', 'Jan 15 2012 should be week 2');\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\n\n\nfunction localeModule (name, lifecycle) {\n    QUnit.module('locale:' + name, {\n        setup : function () {\n            moment.locale(name);\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            moment.locale('en');\n            teardownDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n    defineCommonLocaleTests(name, -1, -1);\n}\n\nlocaleModule('de');\n\ntest('parse', function (assert) {\n    var tests = 'Januar Jan._Februar Febr._März Mrz._April Apr._Mai Mai_Juni Jun._Juli Jul._August Aug._September Sept._Oktober Okt._November Nov._Dezember Dez.'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, Do MMMM YYYY, h:mm:ss a',      'Sonntag, 14. Februar 2010, 3:25:50 pm'],\n            ['ddd, hA',                            'So., 3PM'],\n            ['M Mo MM MMMM MMM',                   '2 2. 02 Februar Febr.'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14. 14'],\n            ['d do dddd ddd dd',                   '0 0. Sonntag So. So'],\n            ['DDD DDDo DDDD',                      '45 45. 045'],\n            ['w wo ww',                            '6 6. 06'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'pm PM'],\n            ['[the] DDDo [day of the year]',       'the 45. day of the year'],\n            ['LTS',                                '15:25:50'],\n            ['L',                                  '14.02.2010'],\n            ['LL',                                 '14. Februar 2010'],\n            ['LLL',                                '14. Februar 2010 15:25'],\n            ['LLLL',                               'Sonntag, 14. Februar 2010 15:25'],\n            ['l',                                  '14.2.2010'],\n            ['ll',                                 '14. Febr. 2010'],\n            ['lll',                                '14. Febr. 2010 15:25'],\n            ['llll',                               'So., 14. Febr. 2010 15:25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1.', '1.');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2.', '2.');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3.', '3.');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4.', '4.');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5.', '5.');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6.', '6.');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7.', '7.');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8.', '8.');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9.', '9.');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10.', '10.');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11.', '11.');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12.', '12.');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13.', '13.');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14.', '14.');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15.', '15.');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16.', '16.');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17.', '17.');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18.', '18.');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19.', '19.');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20.', '20.');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21.', '21.');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22.', '22.');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23.', '23.');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24.', '24.');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25.', '25.');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26.', '26.');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27.', '27.');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28.', '28.');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29.', '29.');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30.', '30.');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31.', '31.');\n});\n\ntest('format month', function (assert) {\n    var expected = 'Januar Jan._Februar Febr._März Mrz._April Apr._Mai Mai_Juni Jun._Juli Jul._August Aug._September Sept._Oktober Okt._November Nov._Dezember Dez.'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'Sonntag So. So_Montag Mo. Mo_Dienstag Di. Di_Mittwoch Mi. Mi_Donnerstag Do. Do_Freitag Fr. Fr_Samstag Sa. Sa'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'ein paar Sekunden',  '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'eine Minute',       '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'eine Minute',       '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 Minuten',          '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 Minuten',         '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'eine Stunde',       '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'eine Stunde',       '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 Stunden',          '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 Stunden',          '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 Stunden',         '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'ein Tag',          '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'ein Tag',          '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 Tage',            '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'ein Tag',          '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 Tage',            '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 Tage',           '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'ein Monat',        '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'ein Monat',        '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'ein Monat',        '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 Monate',          '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 Monate',          '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 Monate',          '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'ein Monat',        '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 Monate',          '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'ein Jahr',         '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 Jahre',           '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'ein Jahr',         '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 Jahre',           '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'in ein paar Sekunden', 'prefix');\n    assert.equal(moment(0).from(30000), 'vor ein paar Sekunden', 'suffix');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'in ein paar Sekunden', 'in a few seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), 'in 5 Tagen', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'heute um 12:00 Uhr',   'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'heute um 12:25 Uhr',   'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'heute um 13:00 Uhr',   'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'morgen um 12:00 Uhr',  'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'heute um 11:00 Uhr',   'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'gestern um 12:00 Uhr', 'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('dddd [um] LT [Uhr]'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd [um] LT [Uhr]'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd [um] LT [Uhr]'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('[letzten] dddd [um] LT [Uhr]'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[letzten] dddd [um] LT [Uhr]'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[letzten] dddd [um] LT [Uhr]'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2012, 0,  1]).format('w ww wo'), '52 52 52.', 'Jan  1 2012 should be week 52');\n    assert.equal(moment([2012, 0,  2]).format('w ww wo'),   '1 01 1.', 'Jan  2 2012 should be week 1');\n    assert.equal(moment([2012, 0,  8]).format('w ww wo'),   '1 01 1.', 'Jan  8 2012 should be week 1');\n    assert.equal(moment([2012, 0,  9]).format('w ww wo'),   '2 02 2.', 'Jan  9 2012 should be week 2');\n    assert.equal(moment([2012, 0, 15]).format('w ww wo'),   '2 02 2.', 'Jan 15 2012 should be week 2');\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\n\n\nfunction localeModule (name, lifecycle) {\n    QUnit.module('locale:' + name, {\n        setup : function () {\n            moment.locale(name);\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            moment.locale('en');\n            teardownDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n    defineCommonLocaleTests(name, -1, -1);\n}\n\nlocaleModule('dv');\n\ntest('parse', function (assert) {\n    var i,\n        tests = [\n            'ޖެނުއަރީ',\n            'ފެބްރުއަރީ',\n            'މާރިޗު',\n            'އޭޕްރީލު',\n            'މޭ',\n            'ޖޫން',\n            'ޖުލައި',\n            'އޯގަސްޓު',\n            'ސެޕްޓެމްބަރު',\n            'އޮކްޓޯބަރު',\n            'ނޮވެމްބަރު',\n            'ޑިސެމްބަރު'\n        ];\n\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n\n    for (i = 0; i < 12; i++) {\n        equalTest(tests[i], 'MMM', i);\n        equalTest(tests[i], 'MMMM', i);\n        equalTest(tests[i].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, MMMM Do YYYY, h:mm:ss a',      'އާދިއްތަ، ފެބްރުއަރީ 14 2010، 3:25:50 މފ'],\n            ['ddd, hA',                            'އާދިއްތަ، 3މފ'],\n            ['M Mo MM MMMM MMM',                   '2 2 02 ފެބްރުއަރީ ފެބްރުއަރީ'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14 14'],\n            ['d do dddd ddd dd',                   '0 0 އާދިއްތަ އާދިއްތަ އާދި'],\n            ['DDD DDDo DDDD',                      '45 45 045'],\n            ['w wo ww',                            '8 8 08'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'މފ މފ'],\n            ['LTS',                                '15:25:50'],\n            ['L',                                  '14/2/2010'],\n            ['LL',                                 '14 ފެބްރުއަރީ 2010'],\n            ['LLL',                                '14 ފެބްރުއަރީ 2010 15:25'],\n            ['LLLL',                               'އާދިއްތަ 14 ފެބްރުއަރީ 2010 15:25'],\n            ['l',                                  '14/2/2010'],\n            ['ll',                                 '14 ފެބްރުއަރީ 2010'],\n            ['lll',                                '14 ފެބްރުއަރީ 2010 15:25'],\n            ['llll',                               'އާދިއްތަ 14 ފެބްރުއަރީ 2010 15:25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format month', function (assert) {\n    var i,\n        expected = [\n            'ޖެނުއަރީ',\n            'ފެބްރުއަރީ',\n            'މާރިޗު',\n            'އޭޕްރީލު',\n            'މޭ',\n            'ޖޫން',\n            'ޖުލައި',\n            'އޯގަސްޓު',\n            'ސެޕްޓެމްބަރު',\n            'އޮކްޓޯބަރު',\n            'ނޮވެމްބަރު',\n            'ޑިސެމްބަރު'\n        ];\n\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM'), expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var i,\n        expected = [\n            'އާދިއްތަ',\n            'ހޯމަ',\n            'އަންގާރަ',\n            'ބުދަ',\n            'ބުރާސްފަތި',\n            'ހުކުރު',\n            'ހޮނިހިރު'\n        ];\n\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd'), expected[i]);\n    }\n});\n\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'ސިކުންތުކޮޅެއް',  '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'މިނިޓެއް',        '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'މިނިޓެއް',        '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  'މިނިޓު 2',        '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  'މިނިޓު 44',       '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'ގަޑިއިރެއް',      '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'ގަޑިއިރެއް',      '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  'ގަޑިއިރު 2',      '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   'ގަޑިއިރު 5',      '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  'ގަޑިއިރު 21',     '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'ދުވަހެއް',        '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'ދުވަހެއް',        '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  'ދުވަސް 2',        '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'ދުވަހެއް',        '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   'ދުވަސް 5',        '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  'ދުވަސް 25',       '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'މަހެއް',          '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'މަހެއް',          '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'މަހެއް',          '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  'މަސް 2',          '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  'މަސް 2',          '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  'މަސް 3',          '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'މަހެއް',          '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   'މަސް 5',          '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'އަހަރެއް',        '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), 'އަހަރު 2',        '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'އަހަރެއް',        '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   'އަހަރު 5',        '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'ތެރޭގައި ސިކުންތުކޮޅެއް', 'prefix');\n    assert.equal(moment(0).from(30000), 'ކުރިން ސިކުންތުކޮޅެއް', 'suffix');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'ތެރޭގައި ސިކުންތުކޮޅެއް', 'in a few seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), 'ތެރޭގައި ދުވަސް 5', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'މިއަދު 12:00',  'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'މިއަދު 12:25',  'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'މިއަދު 13:00',  'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'މާދަމާ 12:00',  'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'މިއަދު 11:00',  'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'އިއްޔެ 12:00',  'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('dddd LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('[ފާއިތުވި] dddd LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[ފާއިތުވި] dddd LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[ފާއިތުވި] dddd LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2012, 0,  1]).format('w ww wo'),   '1 01 1', 'Jan  1 2012 should be week 1');\n    assert.equal(moment([2012, 0,  2]).format('w ww wo'),   '1 01 1', 'Jan  2 2012 should be week 1');\n    assert.equal(moment([2012, 0,  8]).format('w ww wo'),   '2 02 2', 'Jan  8 2012 should be week 2');\n    assert.equal(moment([2012, 0,  9]).format('w ww wo'),   '2 02 2', 'Jan  9 2012 should be week 2');\n    assert.equal(moment([2012, 0, 15]).format('w ww wo'),   '3 03 3', 'Jan 15 2012 should be week 3');\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\n\n\nfunction localeModule (name, lifecycle) {\n    QUnit.module('locale:' + name, {\n        setup : function () {\n            moment.locale(name);\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            moment.locale('en');\n            teardownDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n    defineCommonLocaleTests(name, -1, -1);\n}\n\nlocaleModule('el');\n\ntest('parse', function (assert) {\n    var i,\n        tests = 'Ιανουάριος Ιαν_Φεβρουάριος Φεβ_Μάρτιος Μαρ_Απρίλιος Απρ_Μάιος Μαϊ_Ιούνιος Ιουν_Ιούλιος Ιουλ_Αύγουστος Αυγ_Σεπτέμβριος Σεπ_Οκτώβριος Οκτ_Νοέμβριος Νοε_Δεκέμβριος Δεκ'.split('_');\n\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('parse meridiem', function (assert) {\n    var i,\n        b = moment(),\n        meridiemTests = [\n            // h a patterns, expected hours, isValid\n            ['10 πμ',   10, true],\n            ['10 μμ',   22, true],\n            ['10 π.μ.', 10, true],\n            ['10 μ.μ.', 22, true],\n            ['10 π',    10, true],\n            ['10 μ',    22, true],\n            ['10 ΠΜ',   10, true],\n            ['10 ΜΜ',   22, true],\n            ['10 Π.Μ.', 10, true],\n            ['10 Μ.Μ.', 22, true],\n            ['10 Π',    10, true],\n            ['10 Μ',    22, true],\n            ['10 am',   10, false],\n            ['10 pm',   10, false]\n        ],\n        parsed;\n\n    // test that a formatted moment including meridiem string can be parsed back to the same moment\n    assert.ok(b.isSame(moment(b.format('h:mm:ss a'), 'h:mm:ss a', 'el', true), 'seconds'), b.format('h:mm:ss a') + ' should be equal to ' + moment(b.format('h:mm:ss a'), 'h:mm:ss a', 'el', true).format('h:mm:ss a'));\n\n    // test that a formatted moment having a meridiem string can be parsed with strict flag\n    assert.ok(moment(b.format('h:mm:ss a'), 'h:mm:ss a', 'el', true).isValid(), b.format('h:mm:ss a') + ' should be parsed as valid');\n\n    for (i = 0; i < meridiemTests.length; i++) {\n        parsed = moment(meridiemTests[i][0], 'h a', 'el', true);\n        assert.equal(parsed.isValid(), meridiemTests[i][2], 'validity for ' + meridiemTests[i][0]);\n        if (parsed.isValid()) {\n            assert.equal(parsed.hours(), meridiemTests[i][1], 'hours for ' + meridiemTests[i][0]);\n        }\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, MMMM Do YYYY, h:mm:ss a',      'Κυριακή, Φεβρουάριος 14η 2010, 3:25:50 μμ'],\n            ['dddd, D MMMM YYYY, h:mm:ss a',       'Κυριακή, 14 Φεβρουαρίου 2010, 3:25:50 μμ'],\n            ['ddd, hA',                            'Κυρ, 3ΜΜ'],\n            ['dddd, MMMM YYYY',                    'Κυριακή, Φεβρουάριος 2010'],\n            ['M Mo MM MMMM MMM',                   '2 2η 02 Φεβρουάριος Φεβ'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14η 14'],\n            ['d do dddd ddd dd',                   '0 0η Κυριακή Κυρ Κυ'],\n            ['DDD DDDo DDDD',                      '45 45η 045'],\n            ['w wo ww',                            '6 6η 06'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'μμ ΜΜ'],\n            ['[the] DDDo [day of the year]',       'the 45η day of the year'],\n            ['LTS',                                '3:25:50 ΜΜ'],\n            ['L',                                  '14/02/2010'],\n            ['LL',                                 '14 Φεβρουαρίου 2010'],\n            ['LLL',                                '14 Φεβρουαρίου 2010 3:25 ΜΜ'],\n            ['LLLL',                               'Κυριακή, 14 Φεβρουαρίου 2010 3:25 ΜΜ'],\n            ['l',                                  '14/2/2010'],\n            ['ll',                                 '14 Φεβ 2010'],\n            ['lll',                                '14 Φεβ 2010 3:25 ΜΜ'],\n            ['llll',                               'Κυρ, 14 Φεβ 2010 3:25 ΜΜ']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1η', '1η');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2η', '2η');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3η', '3η');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4η', '4η');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5η', '5η');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6η', '6η');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7η', '7η');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8η', '8η');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9η', '9η');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10η', '10η');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11η', '11η');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12η', '12η');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13η', '13η');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14η', '14η');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15η', '15η');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16η', '16η');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17η', '17η');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18η', '18η');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19η', '19η');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20η', '20η');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21η', '21η');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22η', '22η');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23η', '23η');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24η', '24η');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25η', '25η');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26η', '26η');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27η', '27η');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28η', '28η');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29η', '29η');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30η', '30η');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31η', '31η');\n});\n\ntest('format month', function (assert) {\n    var i,\n        expected = 'Ιανουάριος Ιαν_Φεβρουάριος Φεβ_Μάρτιος Μαρ_Απρίλιος Απρ_Μάιος Μαϊ_Ιούνιος Ιουν_Ιούλιος Ιουλ_Αύγουστος Αυγ_Σεπτέμβριος Σεπ_Οκτώβριος Οκτ_Νοέμβριος Νοε_Δεκέμβριος Δεκ'.split('_');\n\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var i,\n        expected = 'Κυριακή Κυρ Κυ_Δευτέρα Δευ Δε_Τρίτη Τρι Τρ_Τετάρτη Τετ Τε_Πέμπτη Πεμ Πε_Παρασκευή Παρ Πα_Σάββατο Σαβ Σα'.split('_');\n\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'λίγα δευτερόλεπτα',   '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'ένα λεπτό',           '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'ένα λεπτό',           '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 λεπτά',             '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 λεπτά',            '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'μία ώρα',             '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'μία ώρα',             '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 ώρες',              '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 ώρες',              '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 ώρες',             '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'μία μέρα',            '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'μία μέρα',            '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 μέρες',             '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'μία μέρα',            '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 μέρες',             '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 μέρες',            '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'ένας μήνας',          '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'ένας μήνας',          '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'ένας μήνας',          '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 μήνες',             '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 μήνες',             '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 μήνες',             '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'ένας μήνας',          '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 μήνες',             '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'ένας χρόνος',         '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 χρόνια',            '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'ένας χρόνος',         '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 χρόνια',            '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'σε λίγα δευτερόλεπτα',  'prefix');\n    assert.equal(moment(0).from(30000), 'λίγα δευτερόλεπτα πριν', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'λίγα δευτερόλεπτα πριν',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'σε λίγα δευτερόλεπτα', 'in a few seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), 'σε 5 μέρες', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'Σήμερα στις 12:00 ΜΜ',     'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'Σήμερα στις 12:25 ΜΜ',     'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'Σήμερα στη 1:00 ΜΜ',      'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'Αύριο στις 12:00 ΜΜ',      'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'Σήμερα στις 11:00 ΠΜ',      'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'Χθες στις 12:00 ΜΜ',       'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('dddd [' + (m.hours() % 12 === 1 ? 'στη' : 'στις') + '] LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd [στις] LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd [στις] LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m, dayString;\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        dayString = m.day() === 6 ? '[το προηγούμενο Σάββατο]' : '[την προηγούμενη] dddd';\n        assert.equal(m.calendar(),       m.format(dayString + ' [' + (m.hours() % 12 === 1 ? 'στη' : 'στις') + '] LT'),  'Today - ' + i + ' days current time');\n        m.hours(1).minutes(30).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format(dayString + ' [στη] LT'),  'Today - ' + i + ' days one o clock');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format(dayString + ' [στις] LT'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format(dayString + ' [στις] LT'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('weeks year starting sunday format', function (assert) {\n    assert.equal(moment([2012, 0,  1]).format('w ww wo'), '52 52 52η', 'Jan  1 2012 should be week 52');\n    assert.equal(moment([2012, 0,  7]).format('w ww wo'),   '1 01 1η', 'Jan  7 2012 should be week 1');\n    assert.equal(moment([2012, 0,  8]).format('w ww wo'),   '1 01 1η', 'Jan  8 2012 should be week 1');\n    assert.equal(moment([2012, 0, 14]).format('w ww wo'),   '2 02 2η', 'Jan 14 2012 should be week 2');\n    assert.equal(moment([2012, 0, 15]).format('w ww wo'),   '2 02 2η', 'Jan 15 2012 should be week 2');\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\n\n\nfunction localeModule (name, lifecycle) {\n    QUnit.module('locale:' + name, {\n        setup : function () {\n            moment.locale(name);\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            moment.locale('en');\n            teardownDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n    defineCommonLocaleTests(name, -1, -1);\n}\n\nlocaleModule('en-au');\n\ntest('parse', function (assert) {\n    var tests = 'January Jan_February Feb_March Mar_April Apr_May May_June Jun_July Jul_August Aug_September Sep_October Oct_November Nov_December Dec'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, MMMM Do YYYY, h:mm:ss a',      'Sunday, February 14th 2010, 3:25:50 pm'],\n            ['ddd, hA',                            'Sun, 3PM'],\n            ['M Mo MM MMMM MMM',                   '2 2nd 02 February Feb'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14th 14'],\n            ['d do dddd ddd dd',                   '0 0th Sunday Sun Su'],\n            ['DDD DDDo DDDD',                      '45 45th 045'],\n            ['w wo ww',                            '6 6th 06'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'pm PM'],\n            ['[the] DDDo [day of the year]',       'the 45th day of the year'],\n            ['LTS',                                '3:25:50 PM'],\n            ['L',                                  '14/02/2010'],\n            ['LL',                                 '14 February 2010'],\n            ['LLL',                                '14 February 2010 3:25 PM'],\n            ['LLLL',                               'Sunday, 14 February 2010 3:25 PM'],\n            ['l',                                  '14/2/2010'],\n            ['ll',                                 '14 Feb 2010'],\n            ['lll',                                '14 Feb 2010 3:25 PM'],\n            ['llll',                               'Sun, 14 Feb 2010 3:25 PM']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1st', '1st');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2nd', '2nd');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3rd', '3rd');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4th', '4th');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5th', '5th');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6th', '6th');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7th', '7th');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8th', '8th');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9th', '9th');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10th', '10th');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11th', '11th');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12th', '12th');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13th', '13th');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14th', '14th');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15th', '15th');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16th', '16th');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17th', '17th');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18th', '18th');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19th', '19th');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20th', '20th');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21st', '21st');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22nd', '22nd');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23rd', '23rd');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24th', '24th');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25th', '25th');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26th', '26th');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27th', '27th');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28th', '28th');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29th', '29th');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30th', '30th');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31st', '31st');\n});\n\ntest('format month', function (assert) {\n    var expected = 'January Jan_February Feb_March Mar_April Apr_May May_June Jun_July Jul_August Aug_September Sep_October Oct_November Nov_December Dec'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'Sunday Sun Su_Monday Mon Mo_Tuesday Tue Tu_Wednesday Wed We_Thursday Thu Th_Friday Fri Fr_Saturday Sat Sa'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'a few seconds', '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'a minute',      '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'a minute',      '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 minutes',     '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 minutes',    '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'an hour',       '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'an hour',       '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 hours',       '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 hours',       '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 hours',      '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'a day',         '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'a day',         '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 days',        '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'a day',         '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 days',        '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 days',       '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'a month',       '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'a month',       '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'a month',       '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 months',      '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 months',      '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 months',      '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'a month',       '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 months',      '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'a year',        '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 years',       '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'a year',        '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 years',       '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'in a few seconds',  'prefix');\n    assert.equal(moment(0).from(30000), 'a few seconds ago', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'a few seconds ago',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'in a few seconds', 'in a few seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), 'in 5 days', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'Today at 12:00 PM',     'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'Today at 12:25 PM',     'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'Today at 1:00 PM',      'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'Tomorrow at 12:00 PM',  'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'Today at 11:00 AM',     'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'Yesterday at 12:00 PM', 'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('dddd [at] LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd [at] LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd [at] LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('[Last] dddd [at] LT'),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[Last] dddd [at] LT'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[Last] dddd [at] LT'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2012, 0,  1]).format('w ww wo'), '52 52 52nd', 'Jan  1 2012 should be week 52');\n    assert.equal(moment([2012, 0,  2]).format('w ww wo'),   '1 01 1st', 'Jan  2 2012 should be week 1');\n    assert.equal(moment([2012, 0,  8]).format('w ww wo'),   '1 01 1st', 'Jan  8 2012 should be week 1');\n    assert.equal(moment([2012, 0,  9]).format('w ww wo'),   '2 02 2nd', 'Jan  9 2012 should be week 2');\n    assert.equal(moment([2012, 0, 15]).format('w ww wo'),   '2 02 2nd', 'Jan 15 2012 should be week 2');\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\n\n\nfunction localeModule (name, lifecycle) {\n    QUnit.module('locale:' + name, {\n        setup : function () {\n            moment.locale(name);\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            moment.locale('en');\n            teardownDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n    defineCommonLocaleTests(name, -1, -1);\n}\n\nlocaleModule('en-ca');\n\ntest('parse', function (assert) {\n    var i,\n        tests = 'January Jan_February Feb_March Mar_April Apr_May May_June Jun_July Jul_August Aug_September Sep_October Oct_November Nov_December Dec'.split('_');\n\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, MMMM Do YYYY, h:mm:ss a',      'Sunday, February 14th 2010, 3:25:50 pm'],\n            ['ddd, hA',                            'Sun, 3PM'],\n            ['M Mo MM MMMM MMM',                   '2 2nd 02 February Feb'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14th 14'],\n            ['d do dddd ddd dd',                   '0 0th Sunday Sun Su'],\n            ['DDD DDDo DDDD',                      '45 45th 045'],\n            ['w wo ww',                            '8 8th 08'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'pm PM'],\n            ['[the] DDDo [day of the year]',       'the 45th day of the year'],\n            ['L',                                  '2010-02-14'],\n            ['LTS',                                '3:25:50 PM'],\n            ['LL',                                 'February 14, 2010'],\n            ['LLL',                                'February 14, 2010 3:25 PM'],\n            ['LLLL',                               'Sunday, February 14, 2010 3:25 PM'],\n            ['l',                                  '2010-2-14'],\n            ['ll',                                 'Feb 14, 2010'],\n            ['lll',                                'Feb 14, 2010 3:25 PM'],\n            ['llll',                               'Sun, Feb 14, 2010 3:25 PM']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1st', '1st');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2nd', '2nd');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3rd', '3rd');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4th', '4th');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5th', '5th');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6th', '6th');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7th', '7th');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8th', '8th');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9th', '9th');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10th', '10th');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11th', '11th');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12th', '12th');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13th', '13th');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14th', '14th');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15th', '15th');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16th', '16th');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17th', '17th');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18th', '18th');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19th', '19th');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20th', '20th');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21st', '21st');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22nd', '22nd');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23rd', '23rd');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24th', '24th');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25th', '25th');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26th', '26th');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27th', '27th');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28th', '28th');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29th', '29th');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30th', '30th');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31st', '31st');\n});\n\ntest('format month', function (assert) {\n    var i,\n        expected = 'January Jan_February Feb_March Mar_April Apr_May May_June Jun_July Jul_August Aug_September Sep_October Oct_November Nov_December Dec'.split('_');\n\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var i,\n        expected = 'Sunday Sun Su_Monday Mon Mo_Tuesday Tue Tu_Wednesday Wed We_Thursday Thu Th_Friday Fri Fr_Saturday Sat Sa'.split('_');\n\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'a few seconds', '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'a minute',      '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'a minute',      '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 minutes',     '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 minutes',    '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'an hour',       '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'an hour',       '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 hours',       '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 hours',       '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 hours',      '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'a day',         '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'a day',         '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 days',        '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'a day',         '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 days',        '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 days',       '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'a month',       '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'a month',       '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'a month',       '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 months',      '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 months',      '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 months',      '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'a month',       '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 months',      '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'a year',        '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 years',       '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'a year',        '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 years',       '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'in a few seconds',  'prefix');\n    assert.equal(moment(0).from(30000), 'a few seconds ago', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'a few seconds ago',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'in a few seconds', 'in a few seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), 'in 5 days', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'Today at 12:00 PM',     'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'Today at 12:25 PM',     'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'Today at 1:00 PM',      'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'Tomorrow at 12:00 PM',  'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'Today at 11:00 AM',     'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'Yesterday at 12:00 PM', 'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('dddd [at] LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd [at] LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd [at] LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('[Last] dddd [at] LT'),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[Last] dddd [at] LT'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[Last] dddd [at] LT'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('weeks year starting sunday format', function (assert) {\n    assert.equal(moment([2012, 0,  1]).format('w ww wo'), '1 01 1st', 'Jan  1 2012 should be week 1');\n    assert.equal(moment([2012, 0,  7]).format('w ww wo'), '1 01 1st', 'Jan  7 2012 should be week 1');\n    assert.equal(moment([2012, 0,  8]).format('w ww wo'), '2 02 2nd', 'Jan  8 2012 should be week 2');\n    assert.equal(moment([2012, 0, 14]).format('w ww wo'), '2 02 2nd', 'Jan 14 2012 should be week 2');\n    assert.equal(moment([2012, 0, 15]).format('w ww wo'), '3 03 3rd', 'Jan 15 2012 should be week 3');\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\n\n\nfunction localeModule (name, lifecycle) {\n    QUnit.module('locale:' + name, {\n        setup : function () {\n            moment.locale(name);\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            moment.locale('en');\n            teardownDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n    defineCommonLocaleTests(name, -1, -1);\n}\n\nlocaleModule('en-gb');\n\ntest('parse', function (assert) {\n    var tests = 'January Jan_February Feb_March Mar_April Apr_May May_June Jun_July Jul_August Aug_September Sep_October Oct_November Nov_December Dec'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, MMMM Do YYYY, h:mm:ss a',      'Sunday, February 14th 2010, 3:25:50 pm'],\n            ['ddd, hA',                            'Sun, 3PM'],\n            ['M Mo MM MMMM MMM',                   '2 2nd 02 February Feb'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14th 14'],\n            ['d do dddd ddd dd',                   '0 0th Sunday Sun Su'],\n            ['DDD DDDo DDDD',                      '45 45th 045'],\n            ['w wo ww',                            '6 6th 06'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'pm PM'],\n            ['[the] DDDo [day of the year]',       'the 45th day of the year'],\n            ['LTS',                                '15:25:50'],\n            ['L',                                  '14/02/2010'],\n            ['LL',                                 '14 February 2010'],\n            ['LLL',                                '14 February 2010 15:25'],\n            ['LLLL',                               'Sunday, 14 February 2010 15:25'],\n            ['l',                                  '14/2/2010'],\n            ['ll',                                 '14 Feb 2010'],\n            ['lll',                                '14 Feb 2010 15:25'],\n            ['llll',                               'Sun, 14 Feb 2010 15:25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1st', '1st');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2nd', '2nd');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3rd', '3rd');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4th', '4th');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5th', '5th');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6th', '6th');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7th', '7th');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8th', '8th');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9th', '9th');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10th', '10th');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11th', '11th');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12th', '12th');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13th', '13th');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14th', '14th');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15th', '15th');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16th', '16th');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17th', '17th');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18th', '18th');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19th', '19th');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20th', '20th');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21st', '21st');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22nd', '22nd');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23rd', '23rd');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24th', '24th');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25th', '25th');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26th', '26th');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27th', '27th');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28th', '28th');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29th', '29th');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30th', '30th');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31st', '31st');\n});\n\ntest('format month', function (assert) {\n    var expected = 'January Jan_February Feb_March Mar_April Apr_May May_June Jun_July Jul_August Aug_September Sep_October Oct_November Nov_December Dec'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'Sunday Sun Su_Monday Mon Mo_Tuesday Tue Tu_Wednesday Wed We_Thursday Thu Th_Friday Fri Fr_Saturday Sat Sa'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'a few seconds', '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'a minute',      '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'a minute',      '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 minutes',     '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 minutes',    '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'an hour',       '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'an hour',       '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 hours',       '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 hours',       '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 hours',      '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'a day',         '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'a day',         '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 days',        '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'a day',         '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 days',        '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 days',       '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'a month',       '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'a month',       '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'a month',       '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 months',      '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 months',      '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 months',      '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'a month',       '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 months',      '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'a year',        '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 years',       '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'a year',        '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 years',       '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'in a few seconds',  'prefix');\n    assert.equal(moment(0).from(30000), 'a few seconds ago', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'a few seconds ago',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'in a few seconds', 'in a few seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), 'in 5 days', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'Today at 12:00',      'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'Today at 12:25',      'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'Today at 13:00',      'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'Tomorrow at 12:00',   'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'Today at 11:00',      'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'Yesterday at 12:00',  'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('dddd [at] LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd [at] LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd [at] LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('[Last] dddd [at] LT'),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[Last] dddd [at] LT'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[Last] dddd [at] LT'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2012, 0,  1]).format('w ww wo'), '52 52 52nd', 'Jan  1 2012 should be week 52');\n    assert.equal(moment([2012, 0,  2]).format('w ww wo'),   '1 01 1st', 'Jan  2 2012 should be week 1');\n    assert.equal(moment([2012, 0,  8]).format('w ww wo'),   '1 01 1st', 'Jan  8 2012 should be week 1');\n    assert.equal(moment([2012, 0,  9]).format('w ww wo'),   '2 02 2nd', 'Jan  9 2012 should be week 2');\n    assert.equal(moment([2012, 0, 15]).format('w ww wo'),   '2 02 2nd', 'Jan 15 2012 should be week 2');\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\n\n\nfunction localeModule (name, lifecycle) {\n    QUnit.module('locale:' + name, {\n        setup : function () {\n            moment.locale(name);\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            moment.locale('en');\n            teardownDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n    defineCommonLocaleTests(name, -1, -1);\n}\n\nlocaleModule('en-ie');\n\ntest('parse', function (assert) {\n    var tests = 'January Jan_February Feb_March Mar_April Apr_May May_June Jun_July Jul_August Aug_September Sep_October Oct_November Nov_December Dec'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, MMMM Do YYYY, h:mm:ss a',      'Sunday, February 14th 2010, 3:25:50 pm'],\n            ['ddd, hA',                            'Sun, 3PM'],\n            ['M Mo MM MMMM MMM',                   '2 2nd 02 February Feb'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14th 14'],\n            ['d do dddd ddd dd',                   '0 0th Sunday Sun Su'],\n            ['DDD DDDo DDDD',                      '45 45th 045'],\n            ['w wo ww',                            '6 6th 06'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'pm PM'],\n            ['[the] DDDo [day of the year]',       'the 45th day of the year'],\n            ['LTS',                                '15:25:50'],\n            ['L',                                  '14-02-2010'],\n            ['LL',                                 '14 February 2010'],\n            ['LLL',                                '14 February 2010 15:25'],\n            ['LLLL',                               'Sunday 14 February 2010 15:25'],\n            ['l',                                  '14-2-2010'],\n            ['ll',                                 '14 Feb 2010'],\n            ['lll',                                '14 Feb 2010 15:25'],\n            ['llll',                               'Sun 14 Feb 2010 15:25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1st', '1st');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2nd', '2nd');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3rd', '3rd');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4th', '4th');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5th', '5th');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6th', '6th');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7th', '7th');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8th', '8th');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9th', '9th');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10th', '10th');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11th', '11th');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12th', '12th');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13th', '13th');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14th', '14th');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15th', '15th');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16th', '16th');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17th', '17th');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18th', '18th');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19th', '19th');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20th', '20th');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21st', '21st');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22nd', '22nd');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23rd', '23rd');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24th', '24th');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25th', '25th');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26th', '26th');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27th', '27th');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28th', '28th');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29th', '29th');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30th', '30th');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31st', '31st');\n});\n\ntest('format month', function (assert) {\n    var expected = 'January Jan_February Feb_March Mar_April Apr_May May_June Jun_July Jul_August Aug_September Sep_October Oct_November Nov_December Dec'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'Sunday Sun Su_Monday Mon Mo_Tuesday Tue Tu_Wednesday Wed We_Thursday Thu Th_Friday Fri Fr_Saturday Sat Sa'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'a few seconds', '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'a minute',      '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'a minute',      '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 minutes',     '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 minutes',    '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'an hour',       '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'an hour',       '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 hours',       '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 hours',       '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 hours',      '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'a day',         '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'a day',         '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 days',        '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'a day',         '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 days',        '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 days',       '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'a month',       '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'a month',       '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'a month',       '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 months',      '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 months',      '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 months',      '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'a month',       '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 months',      '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'a year',        '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 years',       '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'a year',        '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 years',       '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'in a few seconds',  'prefix');\n    assert.equal(moment(0).from(30000), 'a few seconds ago', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'a few seconds ago',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'in a few seconds', 'in a few seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), 'in 5 days', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'Today at 12:00',      'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'Today at 12:25',      'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'Today at 13:00',      'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'Tomorrow at 12:00',   'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'Today at 11:00',      'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'Yesterday at 12:00',  'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('dddd [at] LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd [at] LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd [at] LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('[Last] dddd [at] LT'),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[Last] dddd [at] LT'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[Last] dddd [at] LT'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2012, 0,  1]).format('w ww wo'), '52 52 52nd', 'Jan  1 2012 should be week 52');\n    assert.equal(moment([2012, 0,  2]).format('w ww wo'),   '1 01 1st', 'Jan  2 2012 should be week 1');\n    assert.equal(moment([2012, 0,  8]).format('w ww wo'),   '1 01 1st', 'Jan  8 2012 should be week 1');\n    assert.equal(moment([2012, 0,  9]).format('w ww wo'),   '2 02 2nd', 'Jan  9 2012 should be week 2');\n    assert.equal(moment([2012, 0, 15]).format('w ww wo'),   '2 02 2nd', 'Jan 15 2012 should be week 2');\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\n\n\nfunction localeModule (name, lifecycle) {\n    QUnit.module('locale:' + name, {\n        setup : function () {\n            moment.locale(name);\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            moment.locale('en');\n            teardownDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n    defineCommonLocaleTests(name, -1, -1);\n}\n\nlocaleModule('en-nz');\n\ntest('parse', function (assert) {\n    var tests = 'January Jan_February Feb_March Mar_April Apr_May May_June Jun_July Jul_August Aug_September Sep_October Oct_November Nov_December Dec'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, MMMM Do YYYY, h:mm:ss a',      'Sunday, February 14th 2010, 3:25:50 pm'],\n            ['ddd, hA',                            'Sun, 3PM'],\n            ['M Mo MM MMMM MMM',                   '2 2nd 02 February Feb'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14th 14'],\n            ['d do dddd ddd dd',                   '0 0th Sunday Sun Su'],\n            ['DDD DDDo DDDD',                      '45 45th 045'],\n            ['w wo ww',                            '6 6th 06'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'pm PM'],\n            ['[the] DDDo [day of the year]',       'the 45th day of the year'],\n            ['LTS',                                '3:25:50 PM'],\n            ['L',                                  '14/02/2010'],\n            ['LL',                                 '14 February 2010'],\n            ['LLL',                                '14 February 2010 3:25 PM'],\n            ['LLLL',                               'Sunday, 14 February 2010 3:25 PM'],\n            ['l',                                  '14/2/2010'],\n            ['ll',                                 '14 Feb 2010'],\n            ['lll',                                '14 Feb 2010 3:25 PM'],\n            ['llll',                               'Sun, 14 Feb 2010 3:25 PM']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1st', '1st');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2nd', '2nd');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3rd', '3rd');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4th', '4th');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5th', '5th');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6th', '6th');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7th', '7th');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8th', '8th');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9th', '9th');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10th', '10th');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11th', '11th');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12th', '12th');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13th', '13th');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14th', '14th');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15th', '15th');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16th', '16th');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17th', '17th');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18th', '18th');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19th', '19th');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20th', '20th');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21st', '21st');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22nd', '22nd');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23rd', '23rd');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24th', '24th');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25th', '25th');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26th', '26th');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27th', '27th');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28th', '28th');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29th', '29th');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30th', '30th');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31st', '31st');\n});\n\ntest('format month', function (assert) {\n    var expected = 'January Jan_February Feb_March Mar_April Apr_May May_June Jun_July Jul_August Aug_September Sep_October Oct_November Nov_December Dec'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'Sunday Sun Su_Monday Mon Mo_Tuesday Tue Tu_Wednesday Wed We_Thursday Thu Th_Friday Fri Fr_Saturday Sat Sa'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'a few seconds', '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'a minute',      '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'a minute',      '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 minutes',     '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 minutes',    '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'an hour',       '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'an hour',       '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 hours',       '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 hours',       '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 hours',      '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'a day',         '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'a day',         '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 days',        '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'a day',         '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 days',        '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 days',       '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'a month',       '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'a month',       '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'a month',       '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 months',      '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 months',      '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 months',      '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'a month',       '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 months',      '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'a year',        '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 years',       '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'a year',        '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 years',       '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'in a few seconds',  'prefix');\n    assert.equal(moment(0).from(30000), 'a few seconds ago', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'a few seconds ago',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'in a few seconds', 'in a few seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), 'in 5 days', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'Today at 12:00 PM',     'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'Today at 12:25 PM',     'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'Today at 1:00 PM',      'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'Tomorrow at 12:00 PM',  'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'Today at 11:00 AM',     'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'Yesterday at 12:00 PM', 'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('dddd [at] LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd [at] LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd [at] LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('[Last] dddd [at] LT'),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[Last] dddd [at] LT'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[Last] dddd [at] LT'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2012, 0,  1]).format('w ww wo'), '52 52 52nd', 'Jan  1 2012 should be week 52');\n    assert.equal(moment([2012, 0,  2]).format('w ww wo'),   '1 01 1st', 'Jan  2 2012 should be week 1');\n    assert.equal(moment([2012, 0,  8]).format('w ww wo'),   '1 01 1st', 'Jan  8 2012 should be week 1');\n    assert.equal(moment([2012, 0,  9]).format('w ww wo'),   '2 02 2nd', 'Jan  9 2012 should be week 2');\n    assert.equal(moment([2012, 0, 15]).format('w ww wo'),   '2 02 2nd', 'Jan 15 2012 should be week 2');\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\n\n\nfunction localeModule (name, lifecycle) {\n    QUnit.module('locale:' + name, {\n        setup : function () {\n            moment.locale(name);\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            moment.locale('en');\n            teardownDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n    defineCommonLocaleTests(name, -1, -1);\n}\n\nlocaleModule('en');\n\ntest('parse', function (assert) {\n    var i,\n        tests = 'January Jan_February Feb_March Mar_April Apr_May May_June Jun_July Jul_August Aug_September Sep_October Oct_November Nov_December Dec'.split('_');\n\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, MMMM Do YYYY, h:mm:ss a',      'Sunday, February 14th 2010, 3:25:50 pm'],\n            ['ddd, hA',                            'Sun, 3PM'],\n            ['M Mo MM MMMM MMM',                   '2 2nd 02 February Feb'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14th 14'],\n            ['d do dddd ddd dd',                   '0 0th Sunday Sun Su'],\n            ['DDD DDDo DDDD',                      '45 45th 045'],\n            ['w wo ww',                            '8 8th 08'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'pm PM'],\n            ['[the] DDDo [day of the year]',       'the 45th day of the year'],\n            ['LTS',                                '3:25:50 PM'],\n            ['L',                                  '02/14/2010'],\n            ['LL',                                 'February 14, 2010'],\n            ['LLL',                                'February 14, 2010 3:25 PM'],\n            ['LLLL',                               'Sunday, February 14, 2010 3:25 PM'],\n            ['l',                                  '2/14/2010'],\n            ['ll',                                 'Feb 14, 2010'],\n            ['lll',                                'Feb 14, 2010 3:25 PM'],\n            ['llll',                               'Sun, Feb 14, 2010 3:25 PM']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1st', '1st');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2nd', '2nd');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3rd', '3rd');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4th', '4th');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5th', '5th');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6th', '6th');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7th', '7th');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8th', '8th');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9th', '9th');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10th', '10th');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11th', '11th');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12th', '12th');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13th', '13th');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14th', '14th');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15th', '15th');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16th', '16th');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17th', '17th');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18th', '18th');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19th', '19th');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20th', '20th');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21st', '21st');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22nd', '22nd');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23rd', '23rd');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24th', '24th');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25th', '25th');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26th', '26th');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27th', '27th');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28th', '28th');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29th', '29th');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30th', '30th');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31st', '31st');\n});\n\ntest('format month', function (assert) {\n    var i,\n        expected = 'January Jan_February Feb_March Mar_April Apr_May May_June Jun_July Jul_August Aug_September Sep_October Oct_November Nov_December Dec'.split('_');\n\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var i,\n        expected = 'Sunday Sun Su_Monday Mon Mo_Tuesday Tue Tu_Wednesday Wed We_Thursday Thu Th_Friday Fri Fr_Saturday Sat Sa'.split('_');\n\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'a few seconds', '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'a minute',      '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'a minute',      '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 minutes',     '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 minutes',    '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'an hour',       '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'an hour',       '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 hours',       '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 hours',       '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 hours',      '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'a day',         '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'a day',         '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 days',        '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'a day',         '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 days',        '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 days',       '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'a month',       '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'a month',       '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'a month',       '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 months',      '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 months',      '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 months',      '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'a month',       '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 months',      '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'a year',        '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 years',       '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'a year',        '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 years',       '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'in a few seconds',  'prefix');\n    assert.equal(moment(0).from(30000), 'a few seconds ago', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'a few seconds ago',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'in a few seconds', 'in a few seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), 'in 5 days', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'Today at 12:00 PM',     'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'Today at 12:25 PM',     'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'Today at 1:00 PM',      'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'Tomorrow at 12:00 PM',  'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'Today at 11:00 AM',     'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'Yesterday at 12:00 PM', 'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('dddd [at] LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd [at] LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd [at] LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('[Last] dddd [at] LT'),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[Last] dddd [at] LT'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[Last] dddd [at] LT'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('weeks year starting sunday format', function (assert) {\n    assert.equal(moment([2012, 0,  1]).format('w ww wo'), '1 01 1st', 'Jan  1 2012 should be week 1');\n    assert.equal(moment([2012, 0,  7]).format('w ww wo'), '1 01 1st', 'Jan  7 2012 should be week 1');\n    assert.equal(moment([2012, 0,  8]).format('w ww wo'), '2 02 2nd', 'Jan  8 2012 should be week 2');\n    assert.equal(moment([2012, 0, 14]).format('w ww wo'), '2 02 2nd', 'Jan 14 2012 should be week 2');\n    assert.equal(moment([2012, 0, 15]).format('w ww wo'), '3 03 3rd', 'Jan 15 2012 should be week 3');\n});\n\ntest('weekdays strict parsing', function (assert) {\n    var m = moment('2015-01-01T12', moment.ISO_8601, true),\n        enLocale = moment.localeData('en');\n\n    for (var i = 0; i < 7; ++i) {\n        assert.equal(moment(enLocale.weekdays(m.day(i), ''), 'dddd', true).isValid(), true, 'parse weekday ' + i);\n        assert.equal(moment(enLocale.weekdaysShort(m.day(i), ''), 'ddd', true).isValid(), true, 'parse short weekday ' + i);\n        assert.equal(moment(enLocale.weekdaysMin(m.day(i), ''), 'dd', true).isValid(), true, 'parse min weekday ' + i);\n\n        // negative tests\n        assert.equal(moment(enLocale.weekdaysMin(m.day(i), ''), 'ddd', true).isValid(), false, 'parse short weekday ' + i);\n        assert.equal(moment(enLocale.weekdaysShort(m.day(i), ''), 'dd', true).isValid(), false, 'parse min weekday ' + i);\n    }\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\n\n\nfunction localeModule (name, lifecycle) {\n    QUnit.module('locale:' + name, {\n        setup : function () {\n            moment.locale(name);\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            moment.locale('en');\n            teardownDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n    defineCommonLocaleTests(name, -1, -1);\n}\n\nlocaleModule('eo');\n\ntest('parse', function (assert) {\n    var tests = 'januaro jan_februaro feb_marto mar_aprilo apr_majo maj_junio jun_julio jul_aŭgusto aŭg_septembro sep_oktobro okt_novembro nov_decembro dec'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, MMMM Do YYYY, h:mm:ss a',      'dimanĉo, februaro 14a 2010, 3:25:50 p.t.m.'],\n            ['ddd, hA',                            'dim, 3P.T.M.'],\n            ['M Mo MM MMMM MMM',                   '2 2a 02 februaro feb'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14a 14'],\n            ['d do dddd ddd dd',                   '0 0a dimanĉo dim di'],\n            ['DDD DDDo DDDD',                      '45 45a 045'],\n            ['w wo ww',                            '7 7a 07'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'p.t.m. P.T.M.'],\n            ['[la] DDDo [tago] [de] [la] [jaro]',  'la 45a tago de la jaro'],\n            ['LTS',                                '15:25:50'],\n            ['L',                                  '2010-02-14'],\n            ['LL',                                 '14-a de februaro, 2010'],\n            ['LLL',                                '14-a de februaro, 2010 15:25'],\n            ['LLLL',                               'dimanĉo, la 14-a de februaro, 2010 15:25'],\n            ['l',                                  '2010-2-14'],\n            ['ll',                                 '14-a de feb, 2010'],\n            ['lll',                                '14-a de feb, 2010 15:25'],\n            ['llll',                               'dim, la 14-a de feb, 2010 15:25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1a', '1a');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2a', '2a');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3a', '3a');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4a', '4a');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5a', '5a');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6a', '6a');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7a', '7a');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8a', '8a');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9a', '9a');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10a', '10a');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11a', '11a');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12a', '12a');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13a', '13a');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14a', '14a');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15a', '15a');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16a', '16a');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17a', '17a');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18a', '18a');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19a', '19a');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20a', '20a');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21a', '21a');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22a', '22a');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23a', '23a');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24a', '24a');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25a', '25a');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26a', '26a');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27a', '27a');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28a', '28a');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29a', '29a');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30a', '30a');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31a', '31a');\n});\n\ntest('format month', function (assert) {\n    var expected = 'januaro jan_februaro feb_marto mar_aprilo apr_majo maj_junio jun_julio jul_aŭgusto aŭg_septembro sep_oktobro okt_novembro nov_decembro dec'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'dimanĉo dim di_lundo lun lu_mardo mard ma_merkredo merk me_ĵaŭdo ĵaŭ ĵa_vendredo ven ve_sabato sab sa'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'sekundoj', '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'minuto',      '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'minuto',      '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 minutoj',     '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 minutoj',    '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'horo',       '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'horo',       '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 horoj',       '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 horoj',       '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 horoj',      '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'tago',         '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'tago',         '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 tagoj',        '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'tago',         '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 tagoj',        '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 tagoj',       '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'monato',       '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'monato',       '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'monato',       '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 monatoj',      '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 monatoj',      '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 monatoj',      '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'monato',       '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 monatoj',      '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'jaro',        '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 jaroj',       '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'jaro',        '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 jaroj',       '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'post sekundoj',  'post prefix');\n    assert.equal(moment(0).from(30000), 'antaŭ sekundoj', 'antaŭ prefix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'antaŭ sekundoj',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'post sekundoj', 'post sekundoj');\n    assert.equal(moment().add({d: 5}).fromNow(), 'post 5 tagoj', 'post 5 tagoj');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'Hodiaŭ je 12:00',     'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'Hodiaŭ je 12:25',     'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'Hodiaŭ je 13:00',     'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'Morgaŭ je 12:00',     'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'Hodiaŭ je 11:00',     'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'Hieraŭ je 12:00',     'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('dddd [je] LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd [je] LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd [je] LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('[pasinta] dddd [je] LT'),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[pasinta] dddd [je] LT'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[pasinta] dddd [je] LT'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2011, 11, 26]).format('w ww wo'), '1 01 1a', 'Dec 26 2011 should be week 1');\n    assert.equal(moment([2012,  0,  1]).format('w ww wo'), '1 01 1a', 'Jan  1 2012 should be week 1');\n    assert.equal(moment([2012,  0,  2]).format('w ww wo'), '2 02 2a', 'Jan  2 2012 should be week 2');\n    assert.equal(moment([2012,  0,  8]).format('w ww wo'), '2 02 2a', 'Jan  8 2012 should be week 2');\n    assert.equal(moment([2012,  0,  9]).format('w ww wo'), '3 03 3a', 'Jan  9 2012 should be week 3');\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\n\n\nfunction localeModule (name, lifecycle) {\n    QUnit.module('locale:' + name, {\n        setup : function () {\n            moment.locale(name);\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            moment.locale('en');\n            teardownDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n    defineCommonLocaleTests(name, -1, -1);\n}\n\nlocaleModule('es-do');\n\ntest('parse', function (assert) {\n    var tests = 'enero ene._febrero feb._marzo mar._abril abr._mayo may._junio jun._julio jul._agosto ago._septiembre sep._octubre oct._noviembre nov._diciembre dic.'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, MMMM Do YYYY, h:mm:ss a',      'domingo, febrero 14º 2010, 3:25:50 pm'],\n            ['ddd, hA',                            'dom., 3PM'],\n            ['M Mo MM MMMM MMM',                   '2 2º 02 febrero feb.'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14º 14'],\n            ['d do dddd ddd dd',                   '0 0º domingo dom. do'],\n            ['DDD DDDo DDDD',                      '45 45º 045'],\n            ['w wo ww',                            '6 6º 06'],\n            ['YYYY-MMM-DD',                        '2010-feb-14'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'pm PM'],\n            ['[the] DDDo [day of the year]',       'the 45º day of the year'],\n            ['LTS',                                '3:25:50 PM'],\n            ['L',                                  '14/02/2010'],\n            ['LL',                                 '14 de febrero de 2010'],\n            ['LLL',                                '14 de febrero de 2010 3:25 PM'],\n            ['LLLL',                               'domingo, 14 de febrero de 2010 3:25 PM'],\n            ['l',                                  '14/2/2010'],\n            ['ll',                                 '14 de feb. de 2010'],\n            ['lll',                                '14 de feb. de 2010 3:25 PM'],\n            ['llll',                               'dom., 14 de feb. de 2010 3:25 PM']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1º', '1º');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2º', '2º');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3º', '3º');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4º', '4º');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5º', '5º');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6º', '6º');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7º', '7º');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8º', '8º');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9º', '9º');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10º', '10º');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11º', '11º');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12º', '12º');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13º', '13º');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14º', '14º');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15º', '15º');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16º', '16º');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17º', '17º');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18º', '18º');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19º', '19º');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20º', '20º');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21º', '21º');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22º', '22º');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23º', '23º');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24º', '24º');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25º', '25º');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26º', '26º');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27º', '27º');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28º', '28º');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29º', '29º');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30º', '30º');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31º', '31º');\n});\n\ntest('format month', function (assert) {\n    var expected = 'enero ene._febrero feb._marzo mar._abril abr._mayo may._junio jun._julio jul._agosto ago._septiembre sep._octubre oct._noviembre nov._diciembre dic.'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'domingo dom. do_lunes lun. lu_martes mar. ma_miércoles mié. mi_jueves jue. ju_viernes vie. vi_sábado sáb. sá'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'unos segundos', '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'un minuto',      '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'un minuto',      '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 minutos',     '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 minutos',    '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'una hora',       '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'una hora',       '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 horas',       '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 horas',       '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 horas',      '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'un día',         '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'un día',         '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 días',        '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'un día',         '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 días',        '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 días',       '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'un mes',       '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'un mes',       '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'un mes',       '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 meses',      '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 meses',      '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 meses',      '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'un mes',       '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 meses',      '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'un año',        '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 años',       '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'un año',        '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 años',       '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'en unos segundos',  'prefix');\n    assert.equal(moment(0).from(30000), 'hace unos segundos', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'hace unos segundos',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'en unos segundos', 'en unos segundos');\n    assert.equal(moment().add({d: 5}).fromNow(), 'en 5 días', 'en 5 días');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                       'hoy a las 12:00 PM',     'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),          'hoy a las 12:25 PM',     'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),           'hoy a las 1:00 PM',     'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),           'mañana a las 12:00 PM',  'tomorrow at the same time');\n    assert.equal(moment(a).add({d: 1, h : -1}).calendar(),   'mañana a las 11:00 AM',   'tomorrow minus 1 hour');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),      'hoy a las 11:00 AM',     'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),      'ayer a las 12:00 PM',    'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('dddd [a la' + ((m.hours() !== 1) ? 's' : '') + '] LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd [a la' + ((m.hours() !== 1) ? 's' : '') + '] LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd [a la' + ((m.hours() !== 1) ? 's' : '') + '] LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('[el] dddd [pasado a la' + ((m.hours() !== 1) ? 's' : '') + '] LT'),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[el] dddd [pasado a la' + ((m.hours() !== 1) ? 's' : '') + '] LT'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[el] dddd [pasado a la' + ((m.hours() !== 1) ? 's' : '') + '] LT'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2012, 0,  1]).format('w ww wo'), '52 52 52º', 'Jan  1 2012 should be week 52');\n    assert.equal(moment([2012, 0,  2]).format('w ww wo'),   '1 01 1º', 'Jan  2 2012 should be week 1');\n    assert.equal(moment([2012, 0,  8]).format('w ww wo'),   '1 01 1º', 'Jan  8 2012 should be week 1');\n    assert.equal(moment([2012, 0,  9]).format('w ww wo'),   '2 02 2º', 'Jan  9 2012 should be week 2');\n    assert.equal(moment([2012, 0, 15]).format('w ww wo'),   '2 02 2º', 'Jan 15 2012 should be week 2');\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\n\n\nfunction localeModule (name, lifecycle) {\n    QUnit.module('locale:' + name, {\n        setup : function () {\n            moment.locale(name);\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            moment.locale('en');\n            teardownDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n    defineCommonLocaleTests(name, -1, -1);\n}\n\nlocaleModule('es');\n\ntest('parse', function (assert) {\n    var tests = 'enero ene._febrero feb._marzo mar._abril abr._mayo may._junio jun._julio jul._agosto ago._septiembre sep._octubre oct._noviembre nov._diciembre dic.'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, MMMM Do YYYY, h:mm:ss a',      'domingo, febrero 14º 2010, 3:25:50 pm'],\n            ['ddd, hA',                            'dom., 3PM'],\n            ['M Mo MM MMMM MMM',                   '2 2º 02 febrero feb.'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14º 14'],\n            ['d do dddd ddd dd',                   '0 0º domingo dom. do'],\n            ['DDD DDDo DDDD',                      '45 45º 045'],\n            ['w wo ww',                            '6 6º 06'],\n            ['YYYY-MMM-DD',                        '2010-feb-14'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'pm PM'],\n            ['[the] DDDo [day of the year]',       'the 45º day of the year'],\n            ['LTS',                                '15:25:50'],\n            ['L',                                  '14/02/2010'],\n            ['LL',                                 '14 de febrero de 2010'],\n            ['LLL',                                '14 de febrero de 2010 15:25'],\n            ['LLLL',                               'domingo, 14 de febrero de 2010 15:25'],\n            ['l',                                  '14/2/2010'],\n            ['ll',                                 '14 de feb. de 2010'],\n            ['lll',                                '14 de feb. de 2010 15:25'],\n            ['llll',                               'dom., 14 de feb. de 2010 15:25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1º', '1º');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2º', '2º');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3º', '3º');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4º', '4º');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5º', '5º');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6º', '6º');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7º', '7º');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8º', '8º');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9º', '9º');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10º', '10º');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11º', '11º');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12º', '12º');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13º', '13º');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14º', '14º');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15º', '15º');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16º', '16º');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17º', '17º');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18º', '18º');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19º', '19º');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20º', '20º');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21º', '21º');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22º', '22º');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23º', '23º');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24º', '24º');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25º', '25º');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26º', '26º');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27º', '27º');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28º', '28º');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29º', '29º');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30º', '30º');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31º', '31º');\n});\n\ntest('format month', function (assert) {\n    var expected = 'enero ene._febrero feb._marzo mar._abril abr._mayo may._junio jun._julio jul._agosto ago._septiembre sep._octubre oct._noviembre nov._diciembre dic.'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'domingo dom. do_lunes lun. lu_martes mar. ma_miércoles mié. mi_jueves jue. ju_viernes vie. vi_sábado sáb. sá'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'unos segundos', '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'un minuto',      '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'un minuto',      '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 minutos',     '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 minutos',    '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'una hora',       '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'una hora',       '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 horas',       '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 horas',       '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 horas',      '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'un día',         '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'un día',         '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 días',        '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'un día',         '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 días',        '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 días',       '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'un mes',       '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'un mes',       '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'un mes',       '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 meses',      '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 meses',      '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 meses',      '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'un mes',       '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 meses',      '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'un año',        '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 años',       '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'un año',        '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 años',       '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'en unos segundos',  'prefix');\n    assert.equal(moment(0).from(30000), 'hace unos segundos', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'hace unos segundos',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'en unos segundos', 'en unos segundos');\n    assert.equal(moment().add({d: 5}).fromNow(), 'en 5 días', 'en 5 días');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                       'hoy a las 12:00',     'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),          'hoy a las 12:25',     'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),           'hoy a las 13:00',     'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),           'mañana a las 12:00',  'tomorrow at the same time');\n    assert.equal(moment(a).add({d: 1, h : -1}).calendar(),   'mañana a las 11:00',   'tomorrow minus 1 hour');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),      'hoy a las 11:00',     'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),      'ayer a las 12:00',    'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('dddd [a la' + ((m.hours() !== 1) ? 's' : '') + '] LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd [a la' + ((m.hours() !== 1) ? 's' : '') + '] LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd [a la' + ((m.hours() !== 1) ? 's' : '') + '] LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('[el] dddd [pasado a la' + ((m.hours() !== 1) ? 's' : '') + '] LT'),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[el] dddd [pasado a la' + ((m.hours() !== 1) ? 's' : '') + '] LT'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[el] dddd [pasado a la' + ((m.hours() !== 1) ? 's' : '') + '] LT'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2012, 0,  1]).format('w ww wo'), '52 52 52º', 'Jan  1 2012 should be week 52');\n    assert.equal(moment([2012, 0,  2]).format('w ww wo'),   '1 01 1º', 'Jan  2 2012 should be week 1');\n    assert.equal(moment([2012, 0,  8]).format('w ww wo'),   '1 01 1º', 'Jan  8 2012 should be week 1');\n    assert.equal(moment([2012, 0,  9]).format('w ww wo'),   '2 02 2º', 'Jan  9 2012 should be week 2');\n    assert.equal(moment([2012, 0, 15]).format('w ww wo'),   '2 02 2º', 'Jan 15 2012 should be week 2');\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\n\n\nfunction localeModule (name, lifecycle) {\n    QUnit.module('locale:' + name, {\n        setup : function () {\n            moment.locale(name);\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            moment.locale('en');\n            teardownDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n    defineCommonLocaleTests(name, -1, -1);\n}\n\nlocaleModule('et');\n\ntest('parse', function (assert) {\n    var tests = 'jaanuar jaan_veebruar veebr_märts märts_aprill apr_mai mai_juuni juuni_juuli juuli_august aug_september sept_oktoober okt_november nov_detsember dets'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' peaks olema kuu ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, Do MMMM YYYY, H:mm:ss',      'pühapäev, 14. veebruar 2010, 15:25:50'],\n            ['ddd, h',                           'P, 3'],\n            ['M Mo MM MMMM MMM',                 '2 2. 02 veebruar veebr'],\n            ['YYYY YY',                          '2010 10'],\n            ['D Do DD',                          '14 14. 14'],\n            ['d do dddd ddd dd',                 '0 0. pühapäev P P'],\n            ['DDD DDDo DDDD',                    '45 45. 045'],\n            ['w wo ww',                          '6 6. 06'],\n            ['h hh',                             '3 03'],\n            ['H HH',                             '15 15'],\n            ['m mm',                             '25 25'],\n            ['s ss',                             '50 50'],\n            ['a A',                              'pm PM'],\n            ['[aasta] DDDo [päev]',              'aasta 45. päev'],\n            ['LTS',                              '15:25:50'],\n            ['L',                                '14.02.2010'],\n            ['LL',                               '14. veebruar 2010'],\n            ['LLL',                              '14. veebruar 2010 15:25'],\n            ['LLLL',                             'pühapäev, 14. veebruar 2010 15:25'],\n            ['l',                                '14.2.2010'],\n            ['ll',                               '14. veebr 2010'],\n            ['lll',                              '14. veebr 2010 15:25'],\n            ['llll',                             'P, 14. veebr 2010 15:25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1.', '1.');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2.', '2.');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3.', '3.');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4.', '4.');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5.', '5.');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6.', '6.');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7.', '7.');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8.', '8.');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9.', '9.');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10.', '10.');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11.', '11.');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12.', '12.');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13.', '13.');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14.', '14.');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15.', '15.');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16.', '16.');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17.', '17.');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18.', '18.');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19.', '19.');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20.', '20.');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21.', '21.');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22.', '22.');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23.', '23.');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24.', '24.');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25.', '25.');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26.', '26.');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27.', '27.');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28.', '28.');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29.', '29.');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30.', '30.');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31.', '31.');\n});\n\ntest('format month', function (assert) {\n    var expected = 'jaanuar jaan_veebruar veebr_märts märts_aprill apr_mai mai_juuni juuni_juuli juuli_august aug_september sept_oktoober okt_november nov_detsember dets'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'pühapäev P P_esmaspäev E E_teisipäev T T_kolmapäev K K_neljapäev N N_reede R R_laupäev L L'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'paar sekundit',  '44 seconds = paar sekundit');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'üks minut',      '45 seconds = üks minut');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'üks minut',      '89 seconds = üks minut');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 minutit',      '90 seconds = 2 minutit');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 minutit',     '44 minutes = 44 minutit');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'üks tund',       '45 minutes = tund aega');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'üks tund',       '89 minutes = üks tund');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 tundi',        '90 minutes = 2 tundi');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 tundi',        '5 hours = 5 tundi');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 tundi',       '21 hours = 21 tundi');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'üks päev',       '22 hours = üks päev');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'üks päev',       '35 hours = üks päev');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 päeva',        '36 hours = 2 päeva');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'üks päev',       '1 day = üks päev');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 päeva',        '5 days = 5 päeva');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 päeva',       '25 days = 25 päeva');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'üks kuu',        '26 days = üks kuu');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'üks kuu',        '30 days = üks kuu');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'üks kuu',        '43 days = üks kuu');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 kuud',         '46 days = 2 kuud');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 kuud',         '75 days = 2 kuud');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 kuud',         '76 days = 3 kuud');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'üks kuu',        '1 month = üks kuu');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 kuud',         '5 months = 5 kuud');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'üks aasta',      '345 days = üks aasta');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 aastat',       '548 days = 2 aastat');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'üks aasta',      '1 year = üks aasta');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 aastat',       '5 years = 5 aastat');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'mõne sekundi pärast',  'prefix');\n    assert.equal(moment(0).from(30000), 'mõni sekund tagasi', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'mõni sekund tagasi',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'mõne sekundi pärast', 'in a few seconds');\n    assert.equal(moment().subtract({s: 30}).fromNow(), 'mõni sekund tagasi', 'a few seconds ago');\n\n    assert.equal(moment().add({m: 1}).fromNow(), 'ühe minuti pärast', 'in a minute');\n    assert.equal(moment().subtract({m: 1}).fromNow(), 'üks minut tagasi', 'a minute ago');\n\n    assert.equal(moment().add({m: 5}).fromNow(), '5 minuti pärast', 'in 5 minutes');\n    assert.equal(moment().subtract({m: 5}).fromNow(), '5 minutit tagasi', '5 minutes ago');\n\n    assert.equal(moment().add({d: 1}).fromNow(), 'ühe päeva pärast', 'in one day');\n    assert.equal(moment().subtract({d: 1}).fromNow(), 'üks päev tagasi', 'one day ago');\n\n    assert.equal(moment().add({d: 5}).fromNow(), '5 päeva pärast', 'in 5 days');\n    assert.equal(moment().subtract({d: 5}).fromNow(), '5 päeva tagasi', '5 days ago');\n\n    assert.equal(moment().add({M: 1}).fromNow(), 'kuu aja pärast', 'in a month');\n    assert.equal(moment().subtract({M: 1}).fromNow(), 'kuu aega tagasi', 'a month ago');\n\n    assert.equal(moment().add({M: 5}).fromNow(), '5 kuu pärast', 'in 5 months');\n    assert.equal(moment().subtract({M: 5}).fromNow(), '5 kuud tagasi', '5 months ago');\n\n    assert.equal(moment().add({y: 1}).fromNow(), 'ühe aasta pärast', 'in a year');\n    assert.equal(moment().subtract({y: 1}).fromNow(), 'aasta tagasi', 'a year ago');\n\n    assert.equal(moment().add({y: 5}).fromNow(), '5 aasta pärast', 'in 5 years');\n    assert.equal(moment().subtract({y: 5}).fromNow(), '5 aastat tagasi', '5 years ago');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'Täna, 12:00',     'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'Täna, 12:25',     'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'Täna, 13:00',     'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'Homme, 12:00',    'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'Täna, 11:00',     'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'Eile, 12:00',     'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('[Järgmine] dddd LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[Järgmine] dddd LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[Järgmine] dddd LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('[Eelmine] dddd LT'),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[Eelmine] dddd LT'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[Eelmine] dddd LT'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 nädal tagasi');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  '1 nädala pärast');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 nädalat tagasi');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  '2 nädala pärast');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2012, 0,  1]).format('w ww wo'), '52 52 52.', 'Jan  1 2012 should be week 52');\n    assert.equal(moment([2012, 0,  2]).format('w ww wo'),   '1 01 1.', 'Jan  2 2012 should be week 1');\n    assert.equal(moment([2012, 0,  8]).format('w ww wo'),   '1 01 1.', 'Jan  8 2012 should be week 1');\n    assert.equal(moment([2012, 0,  9]).format('w ww wo'),   '2 02 2.', 'Jan  9 2012 should be week 2');\n    assert.equal(moment([2012, 0, 15]).format('w ww wo'),   '2 02 2.', 'Jan 15 2012 should be week 2');\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\n\n\nfunction localeModule (name, lifecycle) {\n    QUnit.module('locale:' + name, {\n        setup : function () {\n            moment.locale(name);\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            moment.locale('en');\n            teardownDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n    defineCommonLocaleTests(name, -1, -1);\n}\n\nlocaleModule('eu');\n\ntest('parse', function (assert) {\n    var tests = 'urtarrila urt._otsaila ots._martxoa mar._apirila api._maiatza mai._ekaina eka._uztaila uzt._abuztua abu._iraila ira._urria urr._azaroa aza._abendua abe.'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, MMMM Do YYYY, h:mm:ss a',      'igandea, otsaila 14. 2010, 3:25:50 pm'],\n            ['ddd, hA',                            'ig., 3PM'],\n            ['M Mo MM MMMM MMM',                   '2 2. 02 otsaila ots.'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14. 14'],\n            ['d do dddd ddd dd',                   '0 0. igandea ig. ig'],\n            ['DDD DDDo DDDD',                      '45 45. 045'],\n            ['w wo ww',                            '7 7. 07'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'pm PM'],\n            ['[the] DDDo [day of the year]',       'the 45. day of the year'],\n            ['LTS',                                '15:25:50'],\n            ['L',                                  '2010-02-14'],\n            ['LL',                                 '2010ko otsailaren 14a'],\n            ['LLL',                                '2010ko otsailaren 14a 15:25'],\n            ['LLLL',                               'igandea, 2010ko otsailaren 14a 15:25'],\n            ['l',                                  '2010-2-14'],\n            ['ll',                                 '2010ko ots. 14a'],\n            ['lll',                                '2010ko ots. 14a 15:25'],\n            ['llll',                               'ig., 2010ko ots. 14a 15:25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1.', '1.');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2.', '2.');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3.', '3.');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4.', '4.');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5.', '5.');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6.', '6.');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7.', '7.');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8.', '8.');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9.', '9.');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10.', '10.');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11.', '11.');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12.', '12.');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13.', '13.');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14.', '14.');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15.', '15.');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16.', '16.');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17.', '17.');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18.', '18.');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19.', '19.');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20.', '20.');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21.', '21.');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22.', '22.');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23.', '23.');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24.', '24.');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25.', '25.');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26.', '26.');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27.', '27.');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28.', '28.');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29.', '29.');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30.', '30.');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31.', '31.');\n});\n\ntest('format month', function (assert) {\n    var expected = 'urtarrila urt._otsaila ots._martxoa mar._apirila api._maiatza mai._ekaina eka._uztaila uzt._abuztua abu._iraila ira._urria urr._azaroa aza._abendua abe.'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'igandea ig. ig_astelehena al. al_asteartea ar. ar_asteazkena az. az_osteguna og. og_ostirala ol. ol_larunbata lr. lr'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'segundo batzuk', '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'minutu bat',     '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'minutu bat',     '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 minutu',       '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 minutu',      '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'ordu bat',       '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'ordu bat',       '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 ordu',         '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 ordu',         '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 ordu',        '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'egun bat',       '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'egun bat',       '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 egun',         '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'egun bat',       '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 egun',         '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 egun',        '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'hilabete bat',   '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'hilabete bat',   '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'hilabete bat',   '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 hilabete',     '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 hilabete',     '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 hilabete',     '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'hilabete bat',   '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 hilabete',     '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'urte bat',       '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 urte',         '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'urte bat',       '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 urte',         '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'segundo batzuk barru',  'prefix');\n    assert.equal(moment(0).from(30000), 'duela segundo batzuk', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'duela segundo batzuk',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'segundo batzuk barru', 'in seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), '5 egun barru', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'gaur 12:00etan',  'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'gaur 12:25etan',  'now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'gaur 13:00etan',  'now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'bihar 12:00etan', 'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'gaur 11:00etan',  'now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'atzo 12:00etan',  'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('dddd LT[etan]'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd LT[etan]'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd LT[etan]'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('[aurreko] dddd LT[etan]'),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[aurreko] dddd LT[etan]'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[aurreko] dddd LT[etan]'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2011, 11, 26]).format('w ww wo'), '1 01 1.', 'Dec 26 2011 should be week 1');\n    assert.equal(moment([2012,  0,  1]).format('w ww wo'), '1 01 1.', 'Jan  1 2012 should be week 1');\n    assert.equal(moment([2012,  0,  2]).format('w ww wo'), '2 02 2.', 'Jan  2 2012 should be week 2');\n    assert.equal(moment([2012,  0,  8]).format('w ww wo'), '2 02 2.', 'Jan  8 2012 should be week 2');\n    assert.equal(moment([2012,  0,  9]).format('w ww wo'), '3 03 3.', 'Jan  9 2012 should be week 3');\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\n\n\nfunction localeModule (name, lifecycle) {\n    QUnit.module('locale:' + name, {\n        setup : function () {\n            moment.locale(name);\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            moment.locale('en');\n            teardownDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n    defineCommonLocaleTests(name, -1, -1);\n}\n\nlocaleModule('fa');\n\ntest('parse', function (assert) {\n    var tests = 'ژانویه_فوریه_مارس_آوریل_مه_ژوئن_ژوئیه_اوت_سپتامبر_اکتبر_نوامبر_دسامبر'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1) + ' instead is month ' + moment(input, mmm).month());\n    }\n    for (i = 0; i < 12; i++) {\n        equalTest(tests[i], 'MMM', i);\n        equalTest(tests[i], 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, MMMM Do YYYY, h:mm:ss a',      'یک\\u200cشنبه، فوریه ۱۴م ۲۰۱۰، ۳:۲۵:۵۰ بعد از ظهر'],\n            ['ddd, hA',                            'یک\\u200cشنبه، ۳بعد از ظهر'],\n            ['M Mo MM MMMM MMM',                   '۲ ۲م ۰۲ فوریه فوریه'],\n            ['YYYY YY',                            '۲۰۱۰ ۱۰'],\n            ['D Do DD',                            '۱۴ ۱۴م ۱۴'],\n            ['d do dddd ddd dd',                   '۰ ۰م یک\\u200cشنبه یک\\u200cشنبه ی'],\n            ['DDD DDDo DDDD',                      '۴۵ ۴۵م ۰۴۵'],\n            ['w wo ww',                            '۸ ۸م ۰۸'],\n            ['h hh',                               '۳ ۰۳'],\n            ['H HH',                               '۱۵ ۱۵'],\n            ['m mm',                               '۲۵ ۲۵'],\n            ['s ss',                               '۵۰ ۵۰'],\n            ['a A',                                'بعد از ظهر بعد از ظهر'],\n            ['DDDo [روز سال]',             '۴۵م روز سال'],\n            ['LTS',                                '۱۵:۲۵:۵۰'],\n            ['L',                                  '۱۴/۰۲/۲۰۱۰'],\n            ['LL',                                 '۱۴ فوریه ۲۰۱۰'],\n            ['LLL',                                '۱۴ فوریه ۲۰۱۰ ۱۵:۲۵'],\n            ['LLLL',                               'یک\\u200cشنبه، ۱۴ فوریه ۲۰۱۰ ۱۵:۲۵'],\n            ['l',                                  '۱۴/۲/۲۰۱۰'],\n            ['ll',                                 '۱۴ فوریه ۲۰۱۰'],\n            ['lll',                                '۱۴ فوریه ۲۰۱۰ ۱۵:۲۵'],\n            ['llll',                               'یک\\u200cشنبه، ۱۴ فوریه ۲۰۱۰ ۱۵:۲۵']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '۱م', '1');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '۲م', '2');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '۳م', '3');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '۴م', '4');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '۵م', '5');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '۶م', '6');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '۷م', '7');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '۸م', '8');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '۹م', '9');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '۱۰م', '10');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '۱۱م', '11');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '۱۲م', '12');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '۱۳م', '13');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '۱۴م', '14');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '۱۵م', '15');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '۱۶م', '16');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '۱۷م', '17');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '۱۸م', '18');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '۱۹م', '19');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '۲۰م', '20');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '۲۱م', '21');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '۲۲م', '22');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '۲۳م', '23');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '۲۴م', '24');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '۲۵م', '25');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '۲۶م', '26');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '۲۷م', '27');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '۲۸م', '28');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '۲۹م', '29');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '۳۰م', '30');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '۳۱م', '31');\n});\n\ntest('format month', function (assert) {\n    var expected = 'ژانویه ژانویه_فوریه فوریه_مارس مارس_آوریل آوریل_مه مه_ژوئن ژوئن_ژوئیه ژوئیه_اوت اوت_سپتامبر سپتامبر_اکتبر اکتبر_نوامبر نوامبر_دسامبر دسامبر'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'یک\\u200cشنبه یک\\u200cشنبه ی_دوشنبه دوشنبه د_سه\\u200cشنبه سه\\u200cشنبه س_چهارشنبه چهارشنبه چ_پنج\\u200cشنبه پنج\\u200cشنبه پ_جمعه جمعه ج_شنبه شنبه ش'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'چند ثانیه', '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'یک دقیقه',       '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'یک دقیقه',       '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '۲ دقیقه',     '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '۴۴ دقیقه',    '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'یک ساعت',     '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'یک ساعت',     '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '۲ ساعت',      '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '۵ ساعت',      '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '۲۱ ساعت',     '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'یک روز',      '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'یک روز',      '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '۲ روز',       '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'یک روز',      '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '۵ روز',       '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '۲۵ روز',      '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'یک ماه',      '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'یک ماه',      '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'یک ماه',      '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '۲ ماه',       '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '۲ ماه',       '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '۳ ماه',       '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'یک ماه',      '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '۵ ماه',       '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'یک سال',      '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '۲ سال',       '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'یک سال',      '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '۵ سال',       '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'در چند ثانیه', 'prefix');\n    assert.equal(moment(0).from(30000), 'چند ثانیه پیش', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'چند ثانیه پیش',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'در چند ثانیه', 'in a few seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), 'در ۵ روز', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'امروز ساعت ۱۲:۰۰', 'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'امروز ساعت ۱۲:۲۵', 'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'امروز ساعت ۱۳:۰۰', 'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'فردا ساعت ۱۲:۰۰', 'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'امروز ساعت ۱۱:۰۰', 'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'دیروز ساعت ۱۲:۰۰', 'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('dddd [ساعت] LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd [ساعت] LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd [ساعت] LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('dddd [پیش ساعت] LT'),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd [پیش ساعت] LT'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd [پیش ساعت] LT'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2011, 11, 31]).format('w ww wo'), '۱ ۰۱ ۱م', 'Dec 31 2011 should be week 1');\n    assert.equal(moment([2012,  0,  6]).format('w ww wo'), '۱ ۰۱ ۱م', 'Jan  6 2012 should be week 1');\n    assert.equal(moment([2012,  0,  7]).format('w ww wo'), '۲ ۰۲ ۲م', 'Jan  7 2012 should be week 2');\n    assert.equal(moment([2012,  0, 13]).format('w ww wo'), '۲ ۰۲ ۲م', 'Jan 13 2012 should be week 2');\n    assert.equal(moment([2012,  0, 14]).format('w ww wo'), '۳ ۰۳ ۳م', 'Jan 14 2012 should be week 3');\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\n\n\nfunction localeModule (name, lifecycle) {\n    QUnit.module('locale:' + name, {\n        setup : function () {\n            moment.locale(name);\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            moment.locale('en');\n            teardownDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n    defineCommonLocaleTests(name, -1, -1);\n}\n\nlocaleModule('fi');\n\ntest('parse', function (assert) {\n    var tests = 'tammikuu tammi_helmikuu helmi_maaliskuu maalis_huhtikuu huhti_toukokuu touko_kesäkuu kesä_heinäkuu heinä_elokuu elo_syyskuu syys_lokakuu loka_marraskuu marras_joulukuu joulu'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, MMMM Do YYYY, h:mm:ss a',      'sunnuntai, helmikuu 14. 2010, 3:25:50 pm'],\n            ['ddd, hA',                            'su, 3PM'],\n            ['M Mo MM MMMM MMM',                   '2 2. 02 helmikuu helmi'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14. 14'],\n            ['d do dddd ddd dd',                   '0 0. sunnuntai su su'],\n            ['DDD DDDo DDDD',                      '45 45. 045'],\n            ['w wo ww',                            '6 6. 06'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'pm PM'],\n            ['[vuoden] DDDo [päivä]',              'vuoden 45. päivä'],\n            ['LTS',                                '15.25.50'],\n            ['L',                                  '14.02.2010'],\n            ['LL',                                 '14. helmikuuta 2010'],\n            ['LLL',                                '14. helmikuuta 2010, klo 15.25'],\n            ['LLLL',                               'sunnuntai, 14. helmikuuta 2010, klo 15.25'],\n            ['l',                                  '14.2.2010'],\n            ['ll',                                 '14. helmi 2010'],\n            ['lll',                                '14. helmi 2010, klo 15.25'],\n            ['llll',                               'su, 14. helmi 2010, klo 15.25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1.', '1st');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2.', '2nd');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3.', '3rd');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4.', '4th');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5.', '5th');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6.', '6th');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7.', '7th');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8.', '8th');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9.', '9th');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10.', '10th');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11.', '11th');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12.', '12th');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13.', '13th');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14.', '14th');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15.', '15th');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16.', '16th');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17.', '17th');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18.', '18th');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19.', '19th');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20.', '20th');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21.', '21st');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22.', '22nd');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23.', '23rd');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24.', '24th');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25.', '25th');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26.', '26th');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27.', '27th');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28.', '28th');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29.', '29th');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30.', '30th');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31.', '31st');\n});\n\ntest('format month', function (assert) {\n    var expected = 'tammikuu tammi_helmikuu helmi_maaliskuu maalis_huhtikuu huhti_toukokuu touko_kesäkuu kesä_heinäkuu heinä_elokuu elo_syyskuu syys_lokakuu loka_marraskuu marras_joulukuu joulu'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'sunnuntai su su_maanantai ma ma_tiistai ti ti_keskiviikko ke ke_torstai to to_perjantai pe pe_lauantai la la'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'muutama sekunti', '44 seconds = few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'minuutti',      '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'minuutti',      '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  'kaksi minuuttia',     '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 minuuttia',    '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'tunti',       '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'tunti',       '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  'kaksi tuntia',       '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   'viisi tuntia',       '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 tuntia',      '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'päivä',         '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'päivä',         '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  'kaksi päivää',        '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'päivä',         '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   'viisi päivää',        '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 päivää',       '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'kuukausi',       '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'kuukausi',       '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'kuukausi',       '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  'kaksi kuukautta',      '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  'kaksi kuukautta',      '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  'kolme kuukautta',      '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'kuukausi',       '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   'viisi kuukautta',      '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'vuosi',        '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), 'kaksi vuotta',       '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'vuosi',        '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   'viisi vuotta',       '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'muutaman sekunnin päästä',  'prefix');\n    assert.equal(moment(0).from(30000), 'muutama sekunti sitten', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'muutama sekunti sitten',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'muutaman sekunnin päästä', 'in a few seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), 'viiden päivän päästä', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'tänään klo 12.00',    'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'tänään klo 12.25',    'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'tänään klo 13.00',    'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'huomenna klo 12.00',  'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'tänään klo 11.00',    'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'eilen klo 12.00',     'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('dddd [klo] LT'),  'today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd [klo] LT'),  'today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd [klo] LT'),  'today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('[viime] dddd[na] [klo] LT'),  'today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[viime] dddd[na] [klo] LT'),  'today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[viime] dddd[na] [klo] LT'),  'today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  'yksi viikko sitten');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'yhden viikon päästä');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  'kaksi viikkoa sitten');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'kaden viikon päästä');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2012, 0,  1]).format('w ww wo'), '52 52 52.', 'Jan  1 2012 should be week 52');\n    assert.equal(moment([2012, 0,  2]).format('w ww wo'),   '1 01 1.', 'Jan  2 2012 should be week 1');\n    assert.equal(moment([2012, 0,  8]).format('w ww wo'),   '1 01 1.', 'Jan  8 2012 should be week 1');\n    assert.equal(moment([2012, 0,  9]).format('w ww wo'),   '2 02 2.', 'Jan  9 2012 should be week 2');\n    assert.equal(moment([2012, 0, 15]).format('w ww wo'),   '2 02 2.', 'Jan 15 2012 should be week 2');\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\n\n\nfunction localeModule (name, lifecycle) {\n    QUnit.module('locale:' + name, {\n        setup : function () {\n            moment.locale(name);\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            moment.locale('en');\n            teardownDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n    defineCommonLocaleTests(name, -1, -1);\n}\n\nlocaleModule('fo');\n\ntest('parse', function (assert) {\n    var tests = 'januar jan_februar feb_mars mar_apríl apr_mai mai_juni jun_juli jul_august aug_september sep_oktober okt_november nov_desember des'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd [tann] Do MMMM YYYY, h:mm:ss a', 'sunnudagur tann 14. februar 2010, 3:25:50 pm'],\n            ['ddd hA',                             'sun 3PM'],\n            ['M Mo MM MMMM MMM',                   '2 2. 02 februar feb'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14. 14'],\n            ['d do dddd ddd dd',                   '0 0. sunnudagur sun su'],\n            ['DDD DDDo DDDD',                      '45 45. 045'],\n            ['w wo ww',                            '6 6. 06'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'pm PM'],\n            ['[tann] DDDo [dagin á árinum]',       'tann 45. dagin á árinum'],\n            ['LTS',                                '15:25:50'],\n            ['L',                                  '14/02/2010'],\n            ['LL',                                 '14 februar 2010'],\n            ['LLL',                                '14 februar 2010 15:25'],\n            ['LLLL',                               'sunnudagur 14. februar, 2010 15:25'],\n            ['l',                                  '14/2/2010'],\n            ['ll',                                 '14 feb 2010'],\n            ['lll',                                '14 feb 2010 15:25'],\n            ['llll',                               'sun 14. feb, 2010 15:25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1.', '1.');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2.', '2.');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3.', '3.');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4.', '4.');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5.', '5.');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6.', '6.');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7.', '7.');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8.', '8.');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9.', '9.');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10.', '10.');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11.', '11.');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12.', '12.');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13.', '13.');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14.', '14.');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15.', '15.');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16.', '16.');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17.', '17.');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18.', '18.');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19.', '19.');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20.', '20.');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21.', '21.');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22.', '22.');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23.', '23.');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24.', '24.');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25.', '25.');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26.', '26.');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27.', '27.');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28.', '28.');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29.', '29.');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30.', '30.');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31.', '31.');\n});\n\ntest('format month', function (assert) {\n    var expected = 'januar jan_februar feb_mars mar_apríl apr_mai mai_juni jun_juli jul_august aug_september sep_oktober okt_november nov_desember des'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'sunnudagur sun su_mánadagur mán má_týsdagur týs tý_mikudagur mik mi_hósdagur hós hó_fríggjadagur frí fr_leygardagur ley le'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'fá sekund', '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'ein minutt',    '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'ein minutt',    '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 minuttir',  '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 minuttir', '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'ein tími',     '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'ein tími',     '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 tímar',     '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 tímar',     '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 tímar',    '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'ein dagur',      '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'ein dagur',      '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 dagar',      '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'ein dagur',      '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 dagar',      '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 dagar',     '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'ein mánaði',    '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'ein mánaði',    '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'ein mánaði',    '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 mánaðir',   '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 mánaðir',   '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 mánaðir',   '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'ein mánaði',    '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 mánaðir',   '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'eitt ár',       '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 ár',        '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'eitt ár',       '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 ár',        '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'um fá sekund',  'prefix');\n    assert.equal(moment(0).from(30000), 'fá sekund síðani', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'fá sekund síðani',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'um fá sekund', 'in a few seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), 'um 5 dagar', 'in 5 days');\n});\n\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'Í dag kl. 12:00',    'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'Í dag kl. 12:25',    'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'Í dag kl. 13:00',    'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'Í morgin kl. 12:00', 'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'Í dag kl. 11:00',    'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'Í gjár kl. 12:00',   'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('dddd [kl.] LT'),  'today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd [kl.] LT'),  'today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd [kl.] LT'),  'today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('[síðstu] dddd [kl] LT'),  'today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[síðstu] dddd [kl] LT'),  'today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[síðstu] dddd [kl] LT'),  'today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  'yksi viikko sitten');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'yhden viikon päästä');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  'kaksi viikkoa sitten');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'kaden viikon päästä');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2012, 0,  1]).format('w ww wo'), '52 52 52.', 'Jan  1 2012 should be week 52');\n    assert.equal(moment([2012, 0,  2]).format('w ww wo'),   '1 01 1.', 'Jan  2 2012 should be week 1');\n    assert.equal(moment([2012, 0,  8]).format('w ww wo'),   '1 01 1.', 'Jan  8 2012 should be week 1');\n    assert.equal(moment([2012, 0,  9]).format('w ww wo'),   '2 02 2.', 'Jan  9 2012 should be week 2');\n    assert.equal(moment([2012, 0, 15]).format('w ww wo'),   '2 02 2.', 'Jan 15 2012 should be week 2');\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\n\n\nfunction localeModule (name, lifecycle) {\n    QUnit.module('locale:' + name, {\n        setup : function () {\n            moment.locale(name);\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            moment.locale('en');\n            teardownDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n    defineCommonLocaleTests(name, -1, -1);\n}\n\nlocaleModule('fr-ca');\n\ntest('parse', function (assert) {\n    var i,\n        tests = 'janvier janv._février févr._mars mars_avril avr._mai mai_juin juin_juillet juil._août août_septembre sept._octobre oct._novembre nov._décembre déc.'.split('_');\n\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, MMMM Do YYYY, h:mm:ss a', 'dimanche, février 14e 2010, 3:25:50 pm'],\n            ['ddd, hA',                       'dim., 3PM'],\n            ['M Mo MM MMMM MMM',              '2 2e 02 février févr.'],\n            ['YYYY YY',                       '2010 10'],\n            ['D Do DD',                       '14 14e 14'],\n            ['d do dddd ddd dd',              '0 0e dimanche dim. Di'],\n            ['DDD DDDo DDDD',                 '45 45e 045'],\n            ['w wo ww',                       '8 8e 08'],\n            ['h hh',                          '3 03'],\n            ['H HH',                          '15 15'],\n            ['m mm',                          '25 25'],\n            ['s ss',                          '50 50'],\n            ['a A',                           'pm PM'],\n            ['[le] Do [jour du mois]',        'le 14e jour du mois'],\n            ['[le] DDDo [jour de l’année]',   'le 45e jour de l’année'],\n            ['LTS',                           '15:25:50'],\n            ['L',                             '2010-02-14'],\n            ['LL',                            '14 février 2010'],\n            ['LLL',                           '14 février 2010 15:25'],\n            ['LLLL',                          'dimanche 14 février 2010 15:25'],\n            ['l',                             '2010-2-14'],\n            ['ll',                            '14 févr. 2010'],\n            ['lll',                           '14 févr. 2010 15:25'],\n            ['llll',                          'dim. 14 févr. 2010 15:25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2017, 0, 1]).format('Mo'),     '1er',     '1er');\n    assert.equal(moment([2017, 1, 1]).format('Mo'),     '2e',      '2e');\n\n    assert.equal(moment([2017, 0, 1]).format('Qo'),     '1er',     '1er');\n    assert.equal(moment([2017, 3, 1]).format('Qo'),     '2e',      '2e');\n\n    assert.equal(moment([2017, 0, 1]).format('Do'),     '1er',     '1er');\n    assert.equal(moment([2017, 0, 2]).format('Do'),     '2e',      '2e');\n\n    assert.equal(moment([2011, 0, 1]).format('DDDo'),   '1er',     '1er');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'),   '2e',      '2e');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'),   '3e',      '3e');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'),   '4e',      '4e');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'),   '5e',      '5e');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'),   '6e',      '6e');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'),   '7e',      '7e');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'),   '8e',      '8e');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'),   '9e',      '9e');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'),  '10e',     '10e');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'),  '11e',     '11e');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'),  '12e',     '12e');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'),  '13e',     '13e');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'),  '14e',     '14e');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'),  '15e',     '15e');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'),  '16e',     '16e');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'),  '17e',     '17e');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'),  '18e',     '18e');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'),  '19e',     '19e');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'),  '20e',     '20e');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'),  '21e',     '21e');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'),  '22e',     '22e');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'),  '23e',     '23e');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'),  '24e',     '24e');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'),  '25e',     '25e');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'),  '26e',     '26e');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'),  '27e',     '27e');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'),  '28e',     '28e');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'),  '29e',     '29e');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'),  '30e',     '30e');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'),  '31e',     '31e');\n\n    assert.equal(moment([2017, 0, 1]).format('do'),     '0e',      '0e');\n    assert.equal(moment([2017, 0, 2]).format('do'),     '1er',     '1er');\n\n    assert.equal(moment([2017, 0, 4]).format('wo Wo'),  '1re 1re', '1re 1re');\n    assert.equal(moment([2017, 0, 11]).format('wo Wo'), '2e 2e',   '2e 2e');\n});\n\ntest('format month', function (assert) {\n    var i,\n        expected = 'janvier janv._février févr._mars mars_avril avr._mai mai_juin juin_juillet juil._août août_septembre sept._octobre oct._novembre nov._décembre déc.'.split('_');\n\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var i,\n        expected = 'dimanche dim. Di_lundi lun. Lu_mardi mar. Ma_mercredi mer. Me_jeudi jeu. Je_vendredi ven. Ve_samedi sam. Sa'.split('_');\n\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'quelques secondes', '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'une minute',        '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'une minute',        '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 minutes',         '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 minutes',        '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'une heure',         '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'une heure',         '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 heures',          '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 heures',          '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 heures',         '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'un jour',           '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'un jour',           '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 jours',           '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'un jour',           '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 jours',           '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 jours',          '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'un mois',           '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'un mois',           '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'un mois',           '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 mois',            '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 mois',            '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 mois',            '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'un mois',           '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 mois',            '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'un an',             '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 ans',             '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'un an',             '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 ans',             '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'dans quelques secondes',   'prefix');\n    assert.equal(moment(0).from(30000), 'il y a quelques secondes', 'suffix');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'dans quelques secondes', 'in a few seconds');\n    assert.equal(moment().add({d: 5}).fromNow(),  'dans 5 jours',           'in 5 days');\n});\n\ntest('same day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                  'Aujourd’hui à 12:00', 'Today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),     'Aujourd’hui à 12:25', 'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),      'Aujourd’hui à 13:00', 'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),      'Demain à 12:00',      'Tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(), 'Aujourd’hui à 11:00', 'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(), 'Hier à 12:00',        'Yesterday at the same time');\n});\n\ntest('same next week', function (assert) {\n    var i, m;\n\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(), m.format('dddd [à] LT'), 'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(), m.format('dddd [à] LT'), 'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(), m.format('dddd [à] LT'), 'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('same last week', function (assert) {\n    var i, m;\n\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(), m.format('dddd [dernier à] LT'), 'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(), m.format('dddd [dernier à] LT'), 'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(), m.format('dddd [dernier à] LT'), 'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('same all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),     weeksAgo.format('L'),     '1 week ago');\n    assert.equal(weeksFromNow.calendar(), weeksFromNow.format('L'), 'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),     weeksAgo.format('L'),     '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(), weeksFromNow.format('L'), 'in 2 weeks');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2012, 0,  1]).format('w ww wo'), '1 01 1re', 'Jan  1 2012 should be week 1');\n    assert.equal(moment([2012, 0,  7]).format('w ww wo'), '1 01 1re', 'Jan  7 2012 should be week 1');\n    assert.equal(moment([2012, 0,  8]).format('w ww wo'), '2 02 2e',  'Jan  8 2012 should be week 2');\n    assert.equal(moment([2012, 0, 14]).format('w ww wo'), '2 02 2e',  'Jan 14 2012 should be week 2');\n    assert.equal(moment([2012, 0, 15]).format('w ww wo'), '3 03 3e',  'Jan 15 2012 should be week 3');\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\n\n\nfunction localeModule (name, lifecycle) {\n    QUnit.module('locale:' + name, {\n        setup : function () {\n            moment.locale(name);\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            moment.locale('en');\n            teardownDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n    defineCommonLocaleTests(name, -1, -1);\n}\n\nlocaleModule('fr-ch');\n\ntest('parse', function (assert) {\n    var i,\n        tests = 'janvier janv._février févr._mars mars_avril avr._mai mai_juin juin_juillet juil._août août_septembre sept._octobre oct._novembre nov._décembre déc.'.split('_');\n\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, MMMM Do YYYY, h:mm:ss a', 'dimanche, février 14e 2010, 3:25:50 pm'],\n            ['ddd, hA',                       'dim., 3PM'],\n            ['M Mo MM MMMM MMM',              '2 2e 02 février févr.'],\n            ['YYYY YY',                       '2010 10'],\n            ['D Do DD',                       '14 14e 14'],\n            ['d do dddd ddd dd',              '0 0e dimanche dim. Di'],\n            ['DDD DDDo DDDD',                 '45 45e 045'],\n            ['w wo ww',                       '6 6e 06'],\n            ['h hh',                          '3 03'],\n            ['H HH',                          '15 15'],\n            ['m mm',                          '25 25'],\n            ['s ss',                          '50 50'],\n            ['a A',                           'pm PM'],\n            ['[le] Do [jour du mois]',        'le 14e jour du mois'],\n            ['[le] DDDo [jour de l’année]',   'le 45e jour de l’année'],\n            ['LTS',                           '15:25:50'],\n            ['L',                             '14.02.2010'],\n            ['LL',                            '14 février 2010'],\n            ['LLL',                           '14 février 2010 15:25'],\n            ['LLLL',                          'dimanche 14 février 2010 15:25'],\n            ['l',                             '14.2.2010'],\n            ['ll',                            '14 févr. 2010'],\n            ['lll',                           '14 févr. 2010 15:25'],\n            ['llll',                          'dim. 14 févr. 2010 15:25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2017, 0, 1]).format('Mo'),     '1er',     '1er');\n    assert.equal(moment([2017, 1, 1]).format('Mo'),     '2e',      '2e');\n\n    assert.equal(moment([2017, 0, 1]).format('Qo'),     '1er',     '1er');\n    assert.equal(moment([2017, 3, 1]).format('Qo'),     '2e',      '2e');\n\n    assert.equal(moment([2017, 0, 1]).format('Do'),     '1er',     '1er');\n    assert.equal(moment([2017, 0, 2]).format('Do'),     '2e',      '2e');\n\n    assert.equal(moment([2011, 0, 1]).format('DDDo'),   '1er',     '1er');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'),   '2e',      '2e');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'),   '3e',      '3e');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'),   '4e',      '4e');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'),   '5e',      '5e');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'),   '6e',      '6e');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'),   '7e',      '7e');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'),   '8e',      '8e');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'),   '9e',      '9e');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'),  '10e',     '10e');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'),  '11e',     '11e');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'),  '12e',     '12e');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'),  '13e',     '13e');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'),  '14e',     '14e');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'),  '15e',     '15e');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'),  '16e',     '16e');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'),  '17e',     '17e');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'),  '18e',     '18e');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'),  '19e',     '19e');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'),  '20e',     '20e');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'),  '21e',     '21e');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'),  '22e',     '22e');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'),  '23e',     '23e');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'),  '24e',     '24e');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'),  '25e',     '25e');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'),  '26e',     '26e');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'),  '27e',     '27e');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'),  '28e',     '28e');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'),  '29e',     '29e');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'),  '30e',     '30e');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'),  '31e',     '31e');\n\n    assert.equal(moment([2017, 0, 1]).format('do'),     '0e',      '0e');\n    assert.equal(moment([2017, 0, 2]).format('do'),     '1er',     '1er');\n\n    assert.equal(moment([2017, 0, 4]).format('wo Wo'),  '1re 1re', '1re 1re');\n    assert.equal(moment([2017, 0, 11]).format('wo Wo'), '2e 2e',   '2e 2e');\n});\n\ntest('format month', function (assert) {\n    var i,\n        expected = 'janvier janv._février févr._mars mars_avril avr._mai mai_juin juin_juillet juil._août août_septembre sept._octobre oct._novembre nov._décembre déc.'.split('_');\n\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var i,\n        expected = 'dimanche dim. Di_lundi lun. Lu_mardi mar. Ma_mercredi mer. Me_jeudi jeu. Je_vendredi ven. Ve_samedi sam. Sa'.split('_');\n\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'quelques secondes', '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'une minute',        '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'une minute',        '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 minutes',         '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 minutes',        '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'une heure',         '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'une heure',         '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 heures',          '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 heures',          '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 heures',         '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'un jour',           '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'un jour',           '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 jours',           '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'un jour',           '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 jours',           '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 jours',          '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'un mois',           '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'un mois',           '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'un mois',           '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 mois',            '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 mois',            '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 mois',            '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'un mois',           '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 mois',            '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'un an',             '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 ans',             '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'un an',             '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 ans',             '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'dans quelques secondes',   'prefix');\n    assert.equal(moment(0).from(30000), 'il y a quelques secondes', 'suffix');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'dans quelques secondes', 'in a few seconds');\n    assert.equal(moment().add({d: 5}).fromNow(),  'dans 5 jours',           'in 5 days');\n});\n\ntest('same day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                  'Aujourd’hui à 12:00', 'Today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),     'Aujourd’hui à 12:25', 'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),      'Aujourd’hui à 13:00', 'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),      'Demain à 12:00',      'Tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(), 'Aujourd’hui à 11:00', 'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(), 'Hier à 12:00',        'Yesterday at the same time');\n});\n\ntest('same next week', function (assert) {\n    var i, m;\n\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(), m.format('dddd [à] LT'), 'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(), m.format('dddd [à] LT'), 'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(), m.format('dddd [à] LT'), 'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('same last week', function (assert) {\n    var i, m;\n\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(), m.format('dddd [dernier à] LT'), 'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(), m.format('dddd [dernier à] LT'), 'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(), m.format('dddd [dernier à] LT'), 'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('same all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),     weeksAgo.format('L'),     '1 week ago');\n    assert.equal(weeksFromNow.calendar(), weeksFromNow.format('L'), 'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),     weeksAgo.format('L'),     '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(), weeksFromNow.format('L'), 'in 2 weeks');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2012, 0,  1]).format('w ww wo'), '52 52 52e', 'Jan  1 2012 should be week 52');\n    assert.equal(moment([2012, 0,  2]).format('w ww wo'), '1 01 1re',  'Jan  2 2012 should be week 1');\n    assert.equal(moment([2012, 0,  8]).format('w ww wo'), '1 01 1re',  'Jan  8 2012 should be week 1');\n    assert.equal(moment([2012, 0,  9]).format('w ww wo'), '2 02 2e',   'Jan  9 2012 should be week 2');\n    assert.equal(moment([2012, 0, 15]).format('w ww wo'), '2 02 2e',   'Jan 15 2012 should be week 2');\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\n\n\nfunction localeModule (name, lifecycle) {\n    QUnit.module('locale:' + name, {\n        setup : function () {\n            moment.locale(name);\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            moment.locale('en');\n            teardownDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n    defineCommonLocaleTests(name, -1, -1);\n}\n\nlocaleModule('fr');\n\ntest('parse', function (assert) {\n    var i,\n        tests = 'janvier janv._février févr._mars mars_avril avr._mai mai_juin juin_juillet juil._août août_septembre sept._octobre oct._novembre nov._décembre déc.'.split('_');\n\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, MMMM Do YYYY, h:mm:ss a', 'dimanche, février 14 2010, 3:25:50 pm'],\n            ['ddd, hA',                       'dim., 3PM'],\n            ['M Mo MM MMMM MMM',              '2 2e 02 février févr.'],\n            ['YYYY YY',                       '2010 10'],\n            ['D Do DD',                       '14 14 14'],\n            ['d do dddd ddd dd',              '0 0e dimanche dim. Di'],\n            ['DDD DDDo DDDD',                 '45 45e 045'],\n            ['w wo ww',                       '6 6e 06'],\n            ['h hh',                          '3 03'],\n            ['H HH',                          '15 15'],\n            ['m mm',                          '25 25'],\n            ['s ss',                          '50 50'],\n            ['a A',                           'pm PM'],\n            ['[le] Do [jour du mois]',        'le 14 jour du mois'],\n            ['[le] DDDo [jour de l’année]',   'le 45e jour de l’année'],\n            ['LTS',                           '15:25:50'],\n            ['L',                             '14/02/2010'],\n            ['LL',                            '14 février 2010'],\n            ['LLL',                           '14 février 2010 15:25'],\n            ['LLLL',                          'dimanche 14 février 2010 15:25'],\n            ['l',                             '14/2/2010'],\n            ['ll',                            '14 févr. 2010'],\n            ['lll',                           '14 févr. 2010 15:25'],\n            ['llll',                          'dim. 14 févr. 2010 15:25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2017, 0, 1]).format('Mo'),     '1er',     '1er');\n    assert.equal(moment([2017, 1, 1]).format('Mo'),     '2e',      '2e');\n\n    assert.equal(moment([2017, 0, 1]).format('Qo'),     '1er',     '1er');\n    assert.equal(moment([2017, 3, 1]).format('Qo'),     '2e',      '2e');\n\n    assert.equal(moment([2017, 0, 1]).format('Do'),     '1er',     '1er');\n    assert.equal(moment([2017, 0, 2]).format('Do'),     '2',       '2');\n\n    assert.equal(moment([2011, 0, 1]).format('DDDo'),   '1er',     '1er');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'),   '2e',      '2e');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'),   '3e',      '3e');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'),   '4e',      '4e');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'),   '5e',      '5e');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'),   '6e',      '6e');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'),   '7e',      '7e');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'),   '8e',      '8e');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'),   '9e',      '9e');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'),  '10e',     '10e');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'),  '11e',     '11e');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'),  '12e',     '12e');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'),  '13e',     '13e');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'),  '14e',     '14e');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'),  '15e',     '15e');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'),  '16e',     '16e');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'),  '17e',     '17e');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'),  '18e',     '18e');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'),  '19e',     '19e');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'),  '20e',     '20e');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'),  '21e',     '21e');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'),  '22e',     '22e');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'),  '23e',     '23e');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'),  '24e',     '24e');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'),  '25e',     '25e');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'),  '26e',     '26e');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'),  '27e',     '27e');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'),  '28e',     '28e');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'),  '29e',     '29e');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'),  '30e',     '30e');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'),  '31e',     '31e');\n\n    assert.equal(moment([2017, 0, 1]).format('do'),     '0e',      '0e');\n    assert.equal(moment([2017, 0, 2]).format('do'),     '1er',     '1er');\n\n    assert.equal(moment([2017, 0, 4]).format('wo Wo'),  '1re 1re', '1re 1re');\n    assert.equal(moment([2017, 0, 11]).format('wo Wo'), '2e 2e',   '2e 2e');\n});\n\ntest('format month', function (assert) {\n    var i,\n        expected = 'janvier janv._février févr._mars mars_avril avr._mai mai_juin juin_juillet juil._août août_septembre sept._octobre oct._novembre nov._décembre déc.'.split('_');\n\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var i,\n        expected = 'dimanche dim. Di_lundi lun. Lu_mardi mar. Ma_mercredi mer. Me_jeudi jeu. Je_vendredi ven. Ve_samedi sam. Sa'.split('_');\n\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'quelques secondes', '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'une minute',        '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'une minute',        '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 minutes',         '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 minutes',        '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'une heure',         '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'une heure',         '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 heures',          '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 heures',          '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 heures',         '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'un jour',           '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'un jour',           '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 jours',           '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'un jour',           '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 jours',           '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 jours',          '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'un mois',           '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'un mois',           '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'un mois',           '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 mois',            '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 mois',            '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 mois',            '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'un mois',           '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 mois',            '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'un an',             '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 ans',             '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'un an',             '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 ans',             '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'dans quelques secondes',   'prefix');\n    assert.equal(moment(0).from(30000), 'il y a quelques secondes', 'suffix');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'dans quelques secondes', 'in a few seconds');\n    assert.equal(moment().add({d: 5}).fromNow(),  'dans 5 jours',           'in 5 days');\n});\n\ntest('same day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                  'Aujourd’hui à 12:00', 'Today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),     'Aujourd’hui à 12:25', 'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),      'Aujourd’hui à 13:00', 'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),      'Demain à 12:00',      'Tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(), 'Aujourd’hui à 11:00', 'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(), 'Hier à 12:00',        'Yesterday at the same time');\n});\n\ntest('same next week', function (assert) {\n    var i, m;\n\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(), m.format('dddd [à] LT'), 'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(), m.format('dddd [à] LT'), 'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(), m.format('dddd [à] LT'), 'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('same last week', function (assert) {\n    var i, m;\n\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(), m.format('dddd [dernier à] LT'), 'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(), m.format('dddd [dernier à] LT'), 'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(), m.format('dddd [dernier à] LT'), 'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('same all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),     weeksAgo.format('L'),     '1 week ago');\n    assert.equal(weeksFromNow.calendar(), weeksFromNow.format('L'), 'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),     weeksAgo.format('L'),     '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(), weeksFromNow.format('L'), 'in 2 weeks');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2012, 0,  1]).format('w ww wo'), '52 52 52e', 'Jan  1 2012 should be week 52');\n    assert.equal(moment([2012, 0,  2]).format('w ww wo'), '1 01 1re',  'Jan  2 2012 should be week 1');\n    assert.equal(moment([2012, 0,  8]).format('w ww wo'), '1 01 1re',  'Jan  8 2012 should be week 1');\n    assert.equal(moment([2012, 0,  9]).format('w ww wo'), '2 02 2e',   'Jan  9 2012 should be week 2');\n    assert.equal(moment([2012, 0, 15]).format('w ww wo'), '2 02 2e',   'Jan 15 2012 should be week 2');\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\n\n\nfunction localeModule (name, lifecycle) {\n    QUnit.module('locale:' + name, {\n        setup : function () {\n            moment.locale(name);\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            moment.locale('en');\n            teardownDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n    defineCommonLocaleTests(name, -1, -1);\n}\n\nlocaleModule('fy');\n\ntest('parse', function (assert) {\n    var tests = 'jannewaris jan._febrewaris feb._maart mrt._april apr._maaie mai._juny jun._july jul._augustus aug._septimber sep._oktober okt._novimber nov._desimber des.'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, MMMM Do YYYY, HH:mm:ss',       'snein, febrewaris 14de 2010, 15:25:50'],\n            ['ddd, HH',                            'si., 15'],\n            ['M Mo MM MMMM MMM',                   '2 2de 02 febrewaris feb.'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14de 14'],\n            ['d do dddd ddd dd',                   '0 0de snein si. Si'],\n            ['DDD DDDo DDDD',                      '45 45ste 045'],\n            ['w wo ww',                            '6 6de 06'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'pm PM'],\n            ['[the] DDDo [day of the year]',       'the 45ste day of the year'],\n            ['LTS',                                '15:25:50'],\n            ['L',                                  '14-02-2010'],\n            ['LL',                                 '14 febrewaris 2010'],\n            ['LLL',                                '14 febrewaris 2010 15:25'],\n            ['LLLL',                               'snein 14 febrewaris 2010 15:25'],\n            ['l',                                  '14-2-2010'],\n            ['ll',                                 '14 feb. 2010'],\n            ['lll',                                '14 feb. 2010 15:25'],\n            ['llll',                               'si. 14 feb. 2010 15:25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1ste', '1ste');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2de', '2de');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3de', '3de');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4de', '4de');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5de', '5de');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6de', '6de');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7de', '7de');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8ste', '8ste');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9de', '9de');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10de', '10de');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11de', '11de');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12de', '12de');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13de', '13de');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14de', '14de');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15de', '15de');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16de', '16de');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17de', '17de');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18de', '18de');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19de', '19de');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20ste', '20ste');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21ste', '21ste');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22ste', '22ste');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23ste', '23ste');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24ste', '24ste');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25ste', '25ste');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26ste', '26ste');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27ste', '27ste');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28ste', '28ste');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29ste', '29ste');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30ste', '30ste');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31ste', '31ste');\n});\n\ntest('format month', function (assert) {\n    var expected = 'jannewaris jan._febrewaris feb._maart mrt._april apr._maaie mai_juny jun._july jul._augustus aug._septimber sep._oktober okt._novimber nov._desimber des.'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'snein si. Si_moandei mo. Mo_tiisdei ti. Ti_woansdei wo. Wo_tongersdei to. To_freed fr. Fr_sneon so. So'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'in pear sekonden', '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'ien minút',      '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'ien minút',      '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 minuten',     '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 minuten',    '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'ien oere',       '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'ien oere',       '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 oeren',       '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 oeren',       '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 oeren',      '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'ien dei',         '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'ien dei',         '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 dagen',        '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'ien dei',         '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 dagen',        '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 dagen',       '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'ien moanne',       '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'ien moanne',       '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'ien moanne',       '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 moannen',      '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 moannen',      '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 moannen',      '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'ien moanne',       '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 moannen',      '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'ien jier',        '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 jierren',       '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'ien jier',        '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 jierren',       '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'oer in pear sekonden',  'prefix');\n    assert.equal(moment(0).from(30000), 'in pear sekonden lyn', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'in pear sekonden lyn',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'oer in pear sekonden', 'in a few seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), 'oer 5 dagen', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'hjoed om 12:00',     'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'hjoed om 12:25',     'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'hjoed om 13:00',     'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'moarn om 12:00',     'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'hjoed om 11:00',     'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'juster om 12:00',    'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('dddd [om] LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd [om] LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd [om] LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('[ôfrûne] dddd [om] LT'),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[ôfrûne] dddd [om] LT'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[ôfrûne] dddd [om] LT'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('month abbreviation', function (assert) {\n    assert.equal(moment([2012, 5, 23]).format('D-MMM-YYYY'), '23-jun-2012', 'format month abbreviation surrounded by dashes should not include a dot');\n    assert.equal(moment([2012, 5, 23]).format('D MMM YYYY'), '23 jun. 2012', 'format month abbreviation not surrounded by dashes should include a dot');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2012, 0,  1]).format('w ww wo'), '52 52 52ste', 'Jan  1 2012 should be week 52');\n    assert.equal(moment([2012, 0,  2]).format('w ww wo'),   '1 01 1ste', 'Jan  2 2012 should be week 1');\n    assert.equal(moment([2012, 0,  8]).format('w ww wo'),   '1 01 1ste', 'Jan  8 2012 should be week 1');\n    assert.equal(moment([2012, 0,  9]).format('w ww wo'),    '2 02 2de', 'Jan  9 2012 should be week 2');\n    assert.equal(moment([2012, 0, 15]).format('w ww wo'),    '2 02 2de', 'Jan 15 2012 should be week 2');\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\n\n\nfunction localeModule (name, lifecycle) {\n    QUnit.module('locale:' + name, {\n        setup : function () {\n            moment.locale(name);\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            moment.locale('en');\n            teardownDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n    defineCommonLocaleTests(name, -1, -1);\n}\n\nlocaleModule('gd');\n\nvar months = [\n    'Am Faoilleach,Faoi',\n    'An Gearran,Gear',\n    'Am Màrt,Màrt',\n    'An Giblean,Gibl',\n    'An Cèitean,Cèit',\n    'An t-Ògmhios,Ògmh',\n    'An t-Iuchar,Iuch',\n    'An Lùnastal,Lùn',\n    'An t-Sultain,Sult',\n    'An Dàmhair,Dàmh',\n    'An t-Samhain,Samh',\n    'An Dùbhlachd,Dùbh'\n];\n\ntest('parse', function (assert) {\n    function equalTest(monthName, monthFormat, monthNum) {\n        assert.equal(moment(monthName, monthFormat).month(), monthNum, monthName + ' should be month ' + (monthNum + 1));\n    }\n\n    for (var i = 0; i < 12; i++) {\n        var testMonth = months[i].split(',');\n        equalTest(testMonth[0], 'MMM', i);\n        equalTest(testMonth[1], 'MMM', i);\n        equalTest(testMonth[0], 'MMMM', i);\n        equalTest(testMonth[1], 'MMMM', i);\n        equalTest(testMonth[0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(testMonth[1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(testMonth[0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(testMonth[1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n        ['dddd, MMMM Do YYYY, h:mm:ss a', 'Didòmhnaich, An Gearran 14mh 2010, 3:25:50 pm'],\n        ['ddd, hA', 'Did, 3PM'],\n        ['M Mo MM MMMM MMM', '2 2na 02 An Gearran Gear'],\n        ['YYYY YY', '2010 10'],\n        ['D Do DD', '14 14mh 14'],\n        ['d do dddd ddd dd', '0 0mh Didòmhnaich Did Dò'],\n        ['DDD DDDo DDDD', '45 45mh 045'],\n        ['w wo ww', '6 6mh 06'],\n        ['h hh', '3 03'],\n        ['H HH', '15 15'],\n        ['m mm', '25 25'],\n        ['s ss', '50 50'],\n        ['a A', 'pm PM'],\n        ['[an] DDDo [latha den bhliadhna]', 'an 45mh latha den bhliadhna'],\n        ['LTS', '15:25:50'],\n        ['L', '14/02/2010'],\n        ['LL', '14 An Gearran 2010'],\n        ['LLL', '14 An Gearran 2010 15:25'],\n        ['LLLL', 'Didòmhnaich, 14 An Gearran 2010 15:25'],\n        ['l', '14/2/2010'],\n        ['ll', '14 Gear 2010'],\n        ['lll', '14 Gear 2010 15:25'],\n        ['llll', 'Did, 14 Gear 2010 15:25']\n    ],\n    b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n    i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1d', '1d');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2na', '2na');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3mh', '3mh');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4mh', '4mh');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5mh', '5mh');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6mh', '6mh');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7mh', '7mh');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8mh', '8mh');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9mh', '9mh');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10mh', '10mh');\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11mh', '11mh');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12na', '12na');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13mh', '13mh');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14mh', '14mh');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15mh', '15mh');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16mh', '16mh');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17mh', '17mh');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18mh', '18mh');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19mh', '19mh');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20mh', '20mh');\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21mh', '21mh');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22na', '22na');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23mh', '23mh');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24mh', '24mh');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25mh', '25mh');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26mh', '26mh');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27mh', '27mh');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28mh', '28mh');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29mh', '29mh');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30mh', '30mh');\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31mh', '31mh');\n});\n\ntest('format month', function (assert) {\n    var expected = months;\n    for (var i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM,MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = ['Didòmhnaich Did Dò', 'Diluain Dil Lu', 'Dimàirt Dim Mà', 'Diciadain Dic Ci', 'Diardaoin Dia Ar', 'Dihaoine Dih Ha', 'Disathairne Dis Sa'];\n    for (var i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true), 'beagan diogan', '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true), 'mionaid', '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true), 'mionaid', '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true), '2 mionaidean', '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true), '44 mionaidean', '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true), 'uair', '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true), 'uair', '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true), '2 uairean', '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true), '5 uairean', '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true), '21 uairean', '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true), 'latha', '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true), 'latha', '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true), '2 latha', '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true), 'latha', '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true), '5 latha', '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true), '25 latha', '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true), 'mìos', '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true), 'mìos', '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true), 'mìos', '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true), '2 mìosan', '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true), '2 mìosan', '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true), '3 mìosan', '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true), 'mìos', '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true), '5 mìosan', '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'bliadhna', '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 bliadhna', '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true), 'bliadhna', '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true), '5 bliadhna', '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'ann an beagan diogan', 'prefix');\n    assert.equal(moment(0).from(30000), 'bho chionn beagan diogan', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'bho chionn beagan diogan', 'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'ann an beagan diogan', 'in a few seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), 'ann an 5 latha', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                  'An-diugh aig 12:00',   'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),     'An-diugh aig 12:25',   'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),      'An-diugh aig 13:00',   'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),      'A-màireach aig 12:00', 'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(), 'An-diugh aig 11:00',   'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(), 'An-dè aig 12:00',      'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(), m.format('dddd [aig] LT'), 'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(), m.format('dddd [aig] LT'), 'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(), m.format('dddd [aig] LT'), 'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(), m.format('dddd [seo chaidh] [aig] LT'), 'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(), m.format('dddd [seo chaidh] [aig] LT'), 'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(), m.format('dddd [seo chaidh] [aig] LT'), 'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n       weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '1 week ago');\n    assert.equal(weeksFromNow.calendar(), weeksFromNow.format('L'), 'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(), weeksFromNow.format('L'), 'in 2 weeks');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2012, 0, 1]).format('w ww wo'), '52 52 52na', 'Faoi  1 2012 should be week 52');\n    assert.equal(moment([2012, 0, 2]).format('w ww wo'), '1 01 1d', 'Faoi  2 2012 should be week 1');\n    assert.equal(moment([2012, 0, 8]).format('w ww wo'), '1 01 1d', 'Faoi  8 2012 should be week 1');\n    assert.equal(moment([2012, 0, 9]).format('w ww wo'), '2 02 2na', 'Faoi  9 2012 should be week 2');\n    assert.equal(moment([2012, 0, 15]).format('w ww wo'), '2 02 2na', 'Faoi 15 2012 should be week 2');\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\n\n\nfunction localeModule (name, lifecycle) {\n    QUnit.module('locale:' + name, {\n        setup : function () {\n            moment.locale(name);\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            moment.locale('en');\n            teardownDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n    defineCommonLocaleTests(name, -1, -1);\n}\n\nlocaleModule('gl');\n\ntest('parse', function (assert) {\n    var tests = 'xaneiro xan._febreiro feb._marzo mar._abril abr._maio mai._xuño xuñ._xullo xul._agosto ago._setembro set._outubro out._novembro nov._decembro dec.'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, MMMM Do YYYY, h:mm:ss a',      'domingo, febreiro 14º 2010, 3:25:50 pm'],\n            ['ddd, hA',                            'dom., 3PM'],\n            ['M Mo MM MMMM MMM',                   '2 2º 02 febreiro feb.'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14º 14'],\n            ['d do dddd ddd dd',                   '0 0º domingo dom. do'],\n            ['DDD DDDo DDDD',                      '45 45º 045'],\n            ['w wo ww',                            '6 6º 06'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'pm PM'],\n            ['[the] DDDo [day of the year]',       'the 45º day of the year'],\n            ['LTS',                                '15:25:50'],\n            ['L',                                  '14/02/2010'],\n            ['LL',                                 '14 de febreiro de 2010'],\n            ['LLL',                                '14 de febreiro de 2010 15:25'],\n            ['LLLL',                               'domingo, 14 de febreiro de 2010 15:25'],\n            ['l',                                  '14/2/2010'],\n            ['ll',                                 '14 de feb. de 2010'],\n            ['lll',                                '14 de feb. de 2010 15:25'],\n            ['llll',                               'dom., 14 de feb. de 2010 15:25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1º', '1º');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2º', '2º');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3º', '3º');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4º', '4º');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5º', '5º');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6º', '6º');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7º', '7º');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8º', '8º');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9º', '9º');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10º', '10º');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11º', '11º');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12º', '12º');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13º', '13º');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14º', '14º');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15º', '15º');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16º', '16º');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17º', '17º');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18º', '18º');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19º', '19º');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20º', '20º');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21º', '21º');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22º', '22º');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23º', '23º');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24º', '24º');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25º', '25º');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26º', '26º');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27º', '27º');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28º', '28º');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29º', '29º');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30º', '30º');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31º', '31º');\n});\n\ntest('format month', function (assert) {\n    var expected = 'xaneiro xan._febreiro feb._marzo mar._abril abr._maio mai._xuño xuñ._xullo xul._agosto ago._setembro set._outubro out._novembro nov._decembro dec.'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'domingo dom. do_luns lun. lu_martes mar. ma_mércores mér. mé_xoves xov. xo_venres ven. ve_sábado sáb. sá'.split('_'),\n    i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'uns segundos', '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'un minuto',      '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'un minuto',      '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 minutos',     '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 minutos',    '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'unha hora',       '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'unha hora',       '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 horas',       '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 horas',       '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 horas',      '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'un día',         '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'un día',         '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 días',        '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'un día',         '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 días',        '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 días',       '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'un mes',       '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'un mes',       '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'un mes',       '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 meses',      '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 meses',      '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 meses',      '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'un mes',       '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 meses',      '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'un ano',        '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 anos',       '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'un ano',        '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 anos',       '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'nuns segundos',  'prefix');\n    assert.equal(moment(0).from(30000), 'hai uns segundos', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'hai uns segundos',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'nuns segundos', 'nuns segundos');\n    assert.equal(moment().add({d: 5}).fromNow(), 'en 5 días', 'en 5 días');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                       'hoxe ás 12:00',  'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),          'hoxe ás 12:25',  'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),           'hoxe ás 13:00',  'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),           'mañá ás 12:00',  'tomorrow at the same time');\n    assert.equal(moment(a).add({d: 1, h : -1}).calendar(),   'mañá ás 11:00',   'tomorrow minus 1 hour');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),      'hoxe ás 11:00',   'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),      'onte á 12:00',   'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('dddd [' + ((m.hours() !== 1) ? 'ás' : 'a') + '] LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd [' + ((m.hours() !== 1) ? 'ás' : 'a') + '] LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd [' + ((m.hours() !== 1) ? 'ás' : 'a') + '] LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('[o] dddd [pasado ' + ((m.hours() !== 1) ? 'ás' : 'a') + '] LT'),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[o] dddd [pasado ' + ((m.hours() !== 1) ? 'ás' : 'a') + '] LT'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[o] dddd [pasado ' + ((m.hours() !== 1) ? 'ás' : 'a') + '] LT'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('regression tests', function (assert) {\n    var lastWeek = moment().subtract({d: 4}).hours(1);\n    assert.equal(lastWeek.calendar(), lastWeek.format('[o] dddd [pasado a] LT'), '1 o\\'clock bug');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2012, 0,  1]).format('w ww wo'), '52 52 52º', 'Jan  1 2012 should be week 52');\n    assert.equal(moment([2012, 0,  2]).format('w ww wo'),   '1 01 1º', 'Jan  2 2012 should be week 1');\n    assert.equal(moment([2012, 0,  8]).format('w ww wo'),   '1 01 1º', 'Jan  8 2012 should be week 1');\n    assert.equal(moment([2012, 0,  9]).format('w ww wo'),   '2 02 2º', 'Jan  9 2012 should be week 2');\n    assert.equal(moment([2012, 0, 15]).format('w ww wo'),   '2 02 2º', 'Jan 15 2012 should be week 2');\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\n\n\nfunction localeModule (name, lifecycle) {\n    QUnit.module('locale:' + name, {\n        setup : function () {\n            moment.locale(name);\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            moment.locale('en');\n            teardownDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n    defineCommonLocaleTests(name, -1, -1);\n}\n\nlocaleModule('gom-latn');\n\ntest('parse', function (assert) {\n    var i,\n        tests = 'Janer Jan._Febrer Feb._Mars Mars_Abril Abr._Mai Mai_Jun Jun_Julai Jul._Agost Ago._Setembr Set._Otubr Otu._Novembr Nov._Dezembr Dez.'.split('_');\n\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, MMMM Do YYYY, h:mm:ss a',      'Aitar, Febrer 14er 2010, 3:25:50 donparam'],\n            ['ddd, hA',                            'Ait., 3donparam'],\n            ['M Mo MM MMMM MMM',                   '2 2 02 Febrer Feb.'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14er 14'],\n            ['d do dddd ddd dd',                   '0 0 Aitar Ait. Ai'],\n            ['DDD DDDo DDDD',                      '45 45 045'],\n            ['w wo ww',                            '6 6 06'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'donparam donparam'],\n            ['[the] DDDo [day of the year]',       'the 45 day of the year'],\n            ['LTS',                                'donparam 3:25:50 vazta'],\n            ['L',                                  '14-02-2010'],\n            ['LL',                                 '14 Febrer 2010'],\n            ['LLL',                                '14 Febrer 2010 donparam 3:25 vazta'],\n            ['LLLL',                               'Aitar, Febrerachea 14er, 2010, donparam 3:25 vazta'],\n            ['l',                                  '14-2-2010'],\n            ['ll',                                 '14 Feb. 2010'],\n            ['lll',                                '14 Feb. 2010 donparam 3:25 vazta'],\n            ['llll',                               'Ait., 14 Feb. 2010, donparam 3:25 vazta']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1', '1');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2', '2');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3', '3');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4', '4');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5', '5');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6', '6');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7', '7');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8', '8');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9', '9');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10', '10');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11', '11');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12', '12');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13', '13');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14', '14');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15', '15');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16', '16');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17', '17');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18', '18');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19', '19');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20', '20');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21', '21');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22', '22');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23', '23');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24', '24');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25', '25');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26', '26');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27', '27');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28', '28');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29', '29');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30', '30');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31', '31');\n});\n\ntest('format month', function (assert) {\n    var i,\n        expected = 'Janer Jan._Febrer Feb._Mars Mars_Abril Abr._Mai Mai_Jun Jun_Julai Jul._Agost Ago._Setembr Set._Otubr Otu._Novembr Nov._Dezembr Dez.'.split('_');\n\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var i,\n        expected = 'Aitar Ait. Ai_Somar Som. Sm_Mongllar Mon. Mo_Budvar Bud. Bu_Brestar Bre. Br_Sukrar Suk. Su_Son\\'var Son. Sn'.split('_');\n\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'thodde secondanim', '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'eka mintan',      '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'eka mintan',      '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 mintanim',     '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 mintanim',    '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'eka horan',       '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'eka horan',       '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 horanim',       '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 horanim',       '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 horanim',      '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'eka disan',         '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'eka disan',         '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 disanim',        '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'eka disan',         '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 disanim',        '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 disanim',       '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'eka mhoinean',       '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'eka mhoinean',       '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'eka mhoinean',       '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 mhoineanim',      '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 mhoineanim',      '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 mhoineanim',      '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'eka mhoinean',       '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 mhoineanim',      '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'eka vorsan',        '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 vorsanim',       '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'eka vorsan',        '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 vorsanim',       '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'thodde second',  'prefix');\n    assert.equal(moment(0).from(30000), 'thodde second adim', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'thodde second adim',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'thodde second', 'in a few seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), '5 dis', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'Aiz donparam 12:00 vazta',     'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'Aiz donparam 12:25 vazta',     'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'Aiz donparam 1:00 vazta',      'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'Faleam donparam 12:00 vazta',  'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'Aiz sokalli 11:00 vazta',     'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'Kal donparam 12:00 vazta', 'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('[Ieta to] dddd[,] LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[Ieta to] dddd[,] LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[Ieta to] dddd[,] LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('[Fatlo] dddd[,] LT'),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[Fatlo] dddd[,] LT'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[Fatlo] dddd[,] LT'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('weeks year starting sunday format', function (assert) {\n    assert.equal(moment([2012, 0,  1]).format('w ww wo'), '52 52 52', 'Jan  1 2012 should be week 52');\n    assert.equal(moment([2012, 0,  2]).format('w ww wo'), '1 01 1', 'Jan  2 2012 should be week 1');\n    assert.equal(moment([2012, 0,  8]).format('w ww wo'), '1 01 1', 'Jan  8 2012 should be week 1');\n    assert.equal(moment([2012, 0, 14]).format('w ww wo'), '2 02 2', 'Jan 14 2012 should be week 2');\n    assert.equal(moment([2012, 0, 15]).format('w ww wo'), '2 02 2', 'Jan 15 2012 should be week 2');\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\n\n\nfunction localeModule (name, lifecycle) {\n    QUnit.module('locale:' + name, {\n        setup : function () {\n            moment.locale(name);\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            moment.locale('en');\n            teardownDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n    defineCommonLocaleTests(name, -1, -1);\n}\n\nlocaleModule('he');\n\ntest('parse', function (assert) {\n    var tests = 'ינואר ינו׳_פברואר פבר׳_מרץ מרץ_אפריל אפר׳_מאי מאי_יוני יוני_יולי יולי_אוגוסט אוג׳_ספטמבר ספט׳_אוקטובר אוק׳_נובמבר נוב׳_דצמבר דצמ׳'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, MMMM Do YYYY, h:mm:ss a',      'ראשון, פברואר 14 2010, 3:25:50 אחה\"צ'],\n            ['ddd, h A',                           'א׳, 3 אחרי הצהריים'],\n            ['M Mo MM MMMM MMM',                   '2 2 02 פברואר פבר׳'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14 14'],\n            ['d do dddd ddd dd',                   '0 0 ראשון א׳ א'],\n            ['DDD DDDo DDDD',                      '45 45 045'],\n            ['w wo ww',                            '8 8 08'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'אחה\"צ אחרי הצהריים'],\n            ['[the] DDDo [day of the year]',       'the 45 day of the year'],\n            ['LTS',                                '15:25:50'],\n            ['L',                                  '14/02/2010'],\n            ['LL',                                 '14 בפברואר 2010'],\n            ['LLL',                                '14 בפברואר 2010 15:25'],\n            ['LLLL',                               'ראשון, 14 בפברואר 2010 15:25'],\n            ['l',                                  '14/2/2010'],\n            ['ll',                                 '14 פבר׳ 2010'],\n            ['lll',                                '14 פבר׳ 2010 15:25'],\n            ['llll',                               'א׳, 14 פבר׳ 2010 15:25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format month', function (assert) {\n    var expected = 'ינואר ינו׳_פברואר פבר׳_מרץ מרץ_אפריל אפר׳_מאי מאי_יוני יוני_יולי יולי_אוגוסט אוג׳_ספטמבר ספט׳_אוקטובר אוק׳_נובמבר נוב׳_דצמבר דצמ׳'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'ראשון א׳ א|שני ב׳ ב|שלישי ג׳ ג|רביעי ד׳ ד|חמישי ה׳ ה|שישי ו׳ ו|שבת ש׳ ש'.split('|'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'מספר שניות', '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'דקה',      '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'דקה',      '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 דקות',     '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 דקות',    '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'שעה',       '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'שעה',       '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  'שעתיים',       '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 שעות',       '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 שעות',      '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'יום',         '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'יום',         '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  'יומיים',        '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'יום',         '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 ימים',        '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 ימים',       '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'חודש',       '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'חודש',       '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'חודש',       '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  'חודשיים',      '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  'חודשיים',      '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 חודשים',      '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'חודש',       '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 חודשים',      '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'שנה',        '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), 'שנתיים',       '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 3699}), true), '10 שנים',        '345 days = 10 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 7340}), true), '20 שנה',       '548 days = 20 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'שנה',        '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 שנים',       '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'בעוד מספר שניות',  'prefix');\n    assert.equal(moment(0).from(30000), 'לפני מספר שניות', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'לפני מספר שניות',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'בעוד מספר שניות', 'in a few seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), 'בעוד 5 ימים', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'היום ב־12:00',   'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'היום ב־12:25',   'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'היום ב־13:00',   'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'מחר ב־12:00',   'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'היום ב־11:00',   'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'אתמול ב־12:00',  'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('dddd [בשעה] LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd [בשעה] LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd [בשעה] LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('[ביום] dddd [האחרון בשעה] LT'),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[ביום] dddd [האחרון בשעה] LT'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[ביום] dddd [האחרון בשעה] LT'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('weeks year starting sunday format', function (assert) {\n    assert.equal(moment([2012, 0,  1]).format('w ww wo'), '1 01 1', 'Jan  1 2012 should be week 1');\n    assert.equal(moment([2012, 0,  7]).format('w ww wo'), '1 01 1', 'Jan  7 2012 should be week 1');\n    assert.equal(moment([2012, 0,  8]).format('w ww wo'), '2 02 2', 'Jan  8 2012 should be week 2');\n    assert.equal(moment([2012, 0, 14]).format('w ww wo'), '2 02 2', 'Jan 14 2012 should be week 2');\n    assert.equal(moment([2012, 0, 15]).format('w ww wo'), '3 03 3', 'Jan 15 2012 should be week 3');\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\n\n\nfunction localeModule (name, lifecycle) {\n    QUnit.module('locale:' + name, {\n        setup : function () {\n            moment.locale(name);\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            moment.locale('en');\n            teardownDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n    defineCommonLocaleTests(name, -1, -1);\n}\n\nlocaleModule('hi');\n\ntest('parse', function (assert) {\n    var tests = 'जनवरी जन._फ़रवरी फ़र._मार्च मार्च_अप्रैल अप्रै._मई मई_जून जून_जुलाई जुल._अगस्त अग._सितम्बर सित._अक्टूबर अक्टू._नवम्बर नव._दिसम्बर दिस.'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, Do MMMM YYYY, a h:mm:ss बजे',  'रविवार, १४ फ़रवरी २०१०, दोपहर ३:२५:५० बजे'],\n            ['ddd, a h बजे',                       'रवि, दोपहर ३ बजे'],\n            ['M Mo MM MMMM MMM',                   '२ २ ०२ फ़रवरी फ़र.'],\n            ['YYYY YY',                            '२०१० १०'],\n            ['D Do DD',                            '१४ १४ १४'],\n            ['d do dddd ddd dd',                   '० ० रविवार रवि र'],\n            ['DDD DDDo DDDD',                      '४५ ४५ ०४५'],\n            ['w wo ww',                            '८ ८ ०८'],\n            ['h hh',                               '३ ०३'],\n            ['H HH',                               '१५ १५'],\n            ['m mm',                               '२५ २५'],\n            ['s ss',                               '५० ५०'],\n            ['a A',                                'दोपहर दोपहर'],\n            ['LTS',                                'दोपहर ३:२५:५० बजे'],\n            ['L',                                  '१४/०२/२०१०'],\n            ['LL',                                 '१४ फ़रवरी २०१०'],\n            ['LLL',                                '१४ फ़रवरी २०१०, दोपहर ३:२५ बजे'],\n            ['LLLL',                               'रविवार, १४ फ़रवरी २०१०, दोपहर ३:२५ बजे'],\n            ['l',                                  '१४/२/२०१०'],\n            ['ll',                                 '१४ फ़र. २०१०'],\n            ['lll',                                '१४ फ़र. २०१०, दोपहर ३:२५ बजे'],\n            ['llll',                               'रवि, १४ फ़र. २०१०, दोपहर ३:२५ बजे']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '१', '१');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '२', '२');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '३', '३');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '४', '४');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '५', '५');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '६', '६');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '७', '७');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '८', '८');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '९', '९');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '१०', '१०');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '११', '११');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '१२', '१२');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '१३', '१३');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '१४', '१४');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '१५', '१५');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '१६', '१६');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '१७', '१७');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '१८', '१८');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '१९', '१९');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '२०', '२०');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '२१', '२१');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '२२', '२२');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '२३', '२३');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '२४', '२४');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '२५', '२५');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '२६', '२६');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '२७', '२७');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '२८', '२८');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '२९', '२९');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '३०', '३०');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '३१', '३१');\n});\n\ntest('format month', function (assert) {\n    var expected = 'जनवरी जन._फ़रवरी फ़र._मार्च मार्च_अप्रैल अप्रै._मई मई_जून जून_जुलाई जुल._अगस्त अग._सितम्बर सित._अक्टूबर अक्टू._नवम्बर नव._दिसम्बर दिस.'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'रविवार रवि र_सोमवार सोम सो_मंगलवार मंगल मं_बुधवार बुध बु_गुरूवार गुरू गु_शुक्रवार शुक्र शु_शनिवार शनि श'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'कुछ ही क्षण', '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'एक मिनट',      '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'एक मिनट',      '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '२ मिनट',     '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '४४ मिनट',    '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'एक घंटा',       '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'एक घंटा',       '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '२ घंटे',       '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '५ घंटे',       '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '२१ घंटे',      '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'एक दिन',         '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'एक दिन',         '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '२ दिन',        '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'एक दिन',         '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '५ दिन',        '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '२५ दिन',       '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'एक महीने',       '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'एक महीने',       '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'एक महीने',       '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '२ महीने',      '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '२ महीने',      '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '३ महीने',      '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'एक महीने',       '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '५ महीने',      '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'एक वर्ष',        '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '२ वर्ष',       '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'एक वर्ष',        '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '५ वर्ष',       '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'कुछ ही क्षण में',  'prefix');\n    assert.equal(moment(0).from(30000), 'कुछ ही क्षण पहले', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'कुछ ही क्षण पहले',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'कुछ ही क्षण में', 'कुछ ही क्षण में');\n    assert.equal(moment().add({d: 5}).fromNow(), '५ दिन में', '५ दिन में');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'आज दोपहर १२:०० बजे',    'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'आज दोपहर १२:२५ बजे',    'Now plus 25 min');\n    assert.equal(moment(a).add({h: 3}).calendar(),       'आज दोपहर ३:०० बजे',     'Now plus 3 hours');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'कल दोपहर १२:०० बजे',    'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'आज दोपहर ११:०० बजे',    'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'कल दोपहर १२:०० बजे',    'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('dddd[,] LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd[,] LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd[,] LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('[पिछले] dddd[,] LT'),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[पिछले] dddd[,] LT'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[पिछले] dddd[,] LT'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('meridiem', function (assert) {\n    assert.equal(moment([2011, 2, 23,  2, 30]).format('a'), 'रात', 'before dawn');\n    assert.equal(moment([2011, 2, 23,  9, 30]).format('a'), 'सुबह', 'morning');\n    assert.equal(moment([2011, 2, 23, 14, 30]).format('a'), 'दोपहर', 'during day');\n    assert.equal(moment([2011, 2, 23, 17, 30]).format('a'), 'शाम', 'evening');\n    assert.equal(moment([2011, 2, 23, 19, 30]).format('a'), 'शाम', 'late evening');\n    assert.equal(moment([2011, 2, 23, 21, 20]).format('a'), 'रात', 'night');\n\n    assert.equal(moment([2011, 2, 23,  2, 30]).format('A'), 'रात', 'before dawn');\n    assert.equal(moment([2011, 2, 23,  9, 30]).format('A'), 'सुबह', 'morning');\n    assert.equal(moment([2011, 2, 23, 14, 30]).format('A'), 'दोपहर', ' during day');\n    assert.equal(moment([2011, 2, 23, 17, 30]).format('A'), 'शाम', 'evening');\n    assert.equal(moment([2011, 2, 23, 19, 30]).format('A'), 'शाम', 'late evening');\n    assert.equal(moment([2011, 2, 23, 21, 20]).format('A'), 'रात', 'night');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2012, 0,  1]).format('w ww wo'), '१ ०१ १', 'Jan  1 2012 should be week 1');\n    assert.equal(moment([2012, 0,  7]).format('w ww wo'), '१ ०१ १', 'Jan  7 2012 should be week 1');\n    assert.equal(moment([2012, 0,  8]).format('w ww wo'), '२ ०२ २', 'Jan  8 2012 should be week 2');\n    assert.equal(moment([2012, 0, 14]).format('w ww wo'), '२ ०२ २', 'Jan 14 2012 should be week 2');\n    assert.equal(moment([2012, 0, 15]).format('w ww wo'), '३ ०३ ३', 'Jan 15 2012 should be week 3');\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\n\n\nfunction localeModule (name, lifecycle) {\n    QUnit.module('locale:' + name, {\n        setup : function () {\n            moment.locale(name);\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            moment.locale('en');\n            teardownDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n    defineCommonLocaleTests(name, -1, -1);\n}\n\nlocaleModule('hr');\n\ntest('parse', function (assert) {\n    var tests = 'siječanj sij._veljača velj._ožujak ožu._travanj tra._svibanj svi._lipanj lip._srpanj srp._kolovoz kol._rujan ruj._listopad lis._studeni stu._prosinac pro.'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, Do MMMM YYYY, h:mm:ss a',      'nedjelja, 14. veljače 2010, 3:25:50 pm'],\n            ['ddd, hA',                            'ned., 3PM'],\n            ['M Mo MM MMMM MMM',                   '2 2. 02 veljača velj.'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14. 14'],\n            ['d do dddd ddd dd',                   '0 0. nedjelja ned. ne'],\n            ['DDD DDDo DDDD',                      '45 45. 045'],\n            ['w wo ww',                            '7 7. 07'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'pm PM'],\n            ['[the] DDDo [day of the year]',       'the 45. day of the year'],\n            ['LTS',                                '15:25:50'],\n            ['L',                                  '14.02.2010'],\n            ['LL',                                 '14. veljača 2010'],\n            ['LLL',                                '14. veljača 2010 15:25'],\n            ['LLLL',                               'nedjelja, 14. veljača 2010 15:25'],\n            ['l',                                  '14.2.2010'],\n            ['ll',                                 '14. velj. 2010'],\n            ['lll',                                '14. velj. 2010 15:25'],\n            ['llll',                               'ned., 14. velj. 2010 15:25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1.', '1.');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2.', '2.');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3.', '3.');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4.', '4.');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5.', '5.');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6.', '6.');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7.', '7.');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8.', '8.');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9.', '9.');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10.', '10.');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11.', '11.');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12.', '12.');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13.', '13.');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14.', '14.');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15.', '15.');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16.', '16.');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17.', '17.');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18.', '18.');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19.', '19.');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20.', '20.');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21.', '21.');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22.', '22.');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23.', '23.');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24.', '24.');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25.', '25.');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26.', '26.');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27.', '27.');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28.', '28.');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29.', '29.');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30.', '30.');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31.', '31.');\n});\n\ntest('format month', function (assert) {\n    var expected = 'siječanj sij._veljača velj._ožujak ožu._travanj tra._svibanj svi._lipanj lip._srpanj srp._kolovoz kol._rujan ruj._listopad lis._studeni stu._prosinac pro.'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'nedjelja ned. ne_ponedjeljak pon. po_utorak uto. ut_srijeda sri. sr_četvrtak čet. če_petak pet. pe_subota sub. su'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'par sekundi', '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'jedna minuta',   '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'jedna minuta',   '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 minute',     '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 minuta',     '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'jedan sat',      '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'jedan sat',      '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 sata',        '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 sati',         '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 sati',        '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'dan',       '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'dan',       '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 dana',        '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'dan',       '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 dana',        '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 dana',       '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'mjesec',     '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'mjesec',     '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'mjesec',     '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 mjeseca',     '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 mjeseca',     '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 mjeseca',     '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'mjesec',     '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 mjeseci',    '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'godinu',     '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 godine',       '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'godinu',     '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 godina',        '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'za par sekundi',  'prefix');\n    assert.equal(moment(0).from(30000), 'prije par sekundi', 'prefix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'prije par sekundi',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'za par sekundi', 'in a few seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), 'za 5 dana', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'danas u 12:00',  'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'danas u 12:25',  'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'danas u 13:00',  'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'sutra u 12:00',  'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'danas u 11:00',  'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'jučer u 12:00',  'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n\n    function makeFormat(d) {\n        switch (d.day()) {\n            case 0:\n                return '[u] [nedjelju] [u] LT';\n            case 3:\n                return '[u] [srijedu] [u] LT';\n            case 6:\n                return '[u] [subotu] [u] LT';\n            case 1:\n            case 2:\n            case 4:\n            case 5:\n                return '[u] dddd [u] LT';\n        }\n    }\n\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format(makeFormat(m)),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format(makeFormat(m)),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format(makeFormat(m)),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n\n    function makeFormat(d) {\n        switch (d.day()) {\n            case 0:\n            case 3:\n                return '[prošlu] dddd [u] LT';\n            case 6:\n                return '[prošle] [subote] [u] LT';\n            case 1:\n            case 2:\n            case 4:\n            case 5:\n                return '[prošli] dddd [u] LT';\n        }\n    }\n\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format(makeFormat(m)),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format(makeFormat(m)),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format(makeFormat(m)),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2011, 11, 26]).format('w ww wo'), '1 01 1.', 'Dec 26 2011 should be week 1');\n    assert.equal(moment([2012,  0,  1]).format('w ww wo'), '1 01 1.', 'Jan  1 2012 should be week 1');\n    assert.equal(moment([2012,  0,  2]).format('w ww wo'), '2 02 2.', 'Jan  2 2012 should be week 2');\n    assert.equal(moment([2012,  0,  8]).format('w ww wo'), '2 02 2.', 'Jan  8 2012 should be week 2');\n    assert.equal(moment([2012,  0,  9]).format('w ww wo'), '3 03 3.', 'Jan  9 2012 should be week 3');\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\n\n\nfunction localeModule (name, lifecycle) {\n    QUnit.module('locale:' + name, {\n        setup : function () {\n            moment.locale(name);\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            moment.locale('en');\n            teardownDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n    defineCommonLocaleTests(name, -1, -1);\n}\n\nlocaleModule('hu');\n\ntest('parse', function (assert) {\n    var tests = 'január jan_február feb_március márc_április ápr_május máj_június jún_július júl_augusztus aug_szeptember szept_október okt_november nov_december dec'.split('_'),\n        i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, MMMM Do YYYY, HH:mm:ss',      'vasárnap, február 14. 2010, 15:25:50'],\n            ['ddd, HH',                            'vas, 15'],\n            ['M Mo MM MMMM MMM',                   '2 2. 02 február feb'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14. 14'],\n            ['d do dddd ddd dd',                   '0 0. vasárnap vas v'],\n            ['DDD DDDo DDDD',                      '45 45. 045'],\n            ['w wo ww',                            '6 6. 06'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['[az év] DDDo [napja]',               'az év 45. napja'],\n            ['LTS',                                '15:25:50'],\n            ['L',                                  '2010.02.14.'],\n            ['LL',                                 '2010. február 14.'],\n            ['LLL',                                '2010. február 14. 15:25'],\n            ['LLLL',                               '2010. február 14., vasárnap 15:25'],\n            ['l',                                  '2010.2.14.'],\n            ['ll',                                 '2010. feb 14.'],\n            ['lll',                                '2010. feb 14. 15:25'],\n            ['llll',                               '2010. feb 14., vas 15:25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('meridiem', function (assert) {\n    assert.equal(moment([2011, 2, 23,  0,  0]).format('a'), 'de', 'am');\n    assert.equal(moment([2011, 2, 23, 11, 59]).format('a'), 'de', 'am');\n    assert.equal(moment([2011, 2, 23, 12,  0]).format('a'), 'du', 'pm');\n    assert.equal(moment([2011, 2, 23, 23, 59]).format('a'), 'du', 'pm');\n\n    assert.equal(moment([2011, 2, 23,  0,  0]).format('A'), 'DE', 'AM');\n    assert.equal(moment([2011, 2, 23, 11, 59]).format('A'), 'DE', 'AM');\n    assert.equal(moment([2011, 2, 23, 12,  0]).format('A'), 'DU', 'PM');\n    assert.equal(moment([2011, 2, 23, 23, 59]).format('A'), 'DU', 'PM');\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1.', '1.');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2.', '2.');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3.', '3.');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4.', '4.');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5.', '5.');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6.', '6.');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7.', '7.');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8.', '8.');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9.', '9.');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10.', '10.');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11.', '11.');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12.', '12.');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13.', '13.');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14.', '14.');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15.', '15.');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16.', '16.');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17.', '17.');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18.', '18.');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19.', '19.');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20.', '20.');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21.', '21.');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22.', '22.');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23.', '23.');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24.', '24.');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25.', '25.');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26.', '26.');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27.', '27.');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28.', '28.');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29.', '29.');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30.', '30.');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31.', '31.');\n});\n\ntest('format month', function (assert) {\n    var expected = 'január jan_február feb_március márc_április ápr_május máj_június jún_július júl_augusztus aug_szeptember szept_október okt_november nov_december dec'.split('_'),\n        i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'vasárnap vas_hétfő hét_kedd kedd_szerda sze_csütörtök csüt_péntek pén_szombat szo'.split('_'),\n        i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'néhány másodperc', '44 másodperc = néhány másodperc');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'egy perc',         '45 másodperc = egy perc');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'egy perc',         '89 másodperc = egy perc');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 perc',           '90 másodperc = 2 perc');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 perc',          '44 perc = 44 perc');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'egy óra',          '45 perc = egy óra');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'egy óra',          '89 perc = egy óra');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 óra',            '90 perc = 2 óra');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 óra',            '5 óra = 5 óra');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 óra',           '21 óra = 21 óra');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'egy nap',          '22 óra = egy nap');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'egy nap',          '35 óra = egy nap');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 nap',            '36 óra = 2 nap');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'egy nap',          '1 nap = egy nap');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 nap',            '5 nap = 5 nap');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 nap',           '25 nap = 25 nap');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'egy hónap',        '26 nap = egy hónap');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'egy hónap',        '30 nap = egy hónap');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'egy hónap',        '45 nap = egy hónap');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 hónap',          '46 nap = 2 hónap');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 hónap',          '75 nap = 2 hónap');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 hónap',          '76 nap = 3 hónap');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'egy hónap',        '1 hónap = egy hónap');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 hónap',          '5 hónap = 5 hónap');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'egy év',           '345 nap = egy év');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 év',             '548 nap = 2 év');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'egy év',           '1 év = egy év');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 év',             '5 év = 5 év');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'néhány másodperc múlva',  'prefix');\n    assert.equal(moment(0).from(30000), 'néhány másodperce', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'néhány másodperce',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'néhány másodperc múlva', 'néhány másodperc múlva');\n    assert.equal(moment().add({d: 5}).fromNow(), '5 nap múlva', '5 nap múlva');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'ma 12:00-kor',     'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'ma 12:25-kor',     'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'ma 13:00-kor',     'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'holnap 12:00-kor', 'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'ma 11:00-kor',     'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'tegnap 12:00-kor', 'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m, days = 'vasárnap_hétfőn_kedden_szerdán_csütörtökön_pénteken_szombaton'.split('_');\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('[' + days[m.day()] + '] LT[-kor]'),  'today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[' + days[m.day()] + '] LT[-kor]'),  'today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[' + days[m.day()] + '] LT[-kor]'),  'today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m, days = 'vasárnap_hétfőn_kedden_szerdán_csütörtökön_pénteken_szombaton'.split('_');\n\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('[múlt ' + days[m.day()] + '] LT[-kor]'),  'today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[múlt ' + days[m.day()] + '] LT[-kor]'),  'today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[múlt ' + days[m.day()] + '] LT[-kor]'),  'today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  'egy héte');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'egy hét múlva');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 hete');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  '2 hét múlva');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2011, 11, 26]).format('w ww wo'), '52 52 52.', 'Dec 26 2011 should be week 52');\n    assert.equal(moment([2012,  0,  1]).format('w ww wo'), '52 52 52.', 'Jan  1 2012 should be week 52');\n    assert.equal(moment([2012,  0,  2]).format('w ww wo'), '1 01 1.', 'Jan  2 2012 should be week 1');\n    assert.equal(moment([2012,  0,  8]).format('w ww wo'), '1 01 1.', 'Jan  8 2012 should be week 1');\n    assert.equal(moment([2012,  0,  9]).format('w ww wo'), '2 02 2.', 'Jan  9 2012 should be week 2');\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\n\n\nfunction localeModule (name, lifecycle) {\n    QUnit.module('locale:' + name, {\n        setup : function () {\n            moment.locale(name);\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            moment.locale('en');\n            teardownDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n    defineCommonLocaleTests(name, -1, -1);\n}\n\nlocaleModule('hy-am');\n\ntest('parse', function (assert) {\n    var tests = 'հունվար հնվ_փետրվար փտր_մարտ մրտ_ապրիլ ապր_մայիս մյս_հունիս հնս_հուլիս հլս_օգոստոս օգս_սեպտեմբեր սպտ_հոկտեմբեր հկտ_նոյեմբեր նմբ_դեկտեմբեր դկտ'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('parse exceptional case', function (assert) {\n    assert.equal(moment('11 մայիսի 1989', ['DD MMMM YYYY']).format('DD-MM-YYYY'), '11-05-1989');\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, Do MMMM YYYY, HH:mm:ss',       'կիրակի, 14 փետրվարի 2010, 15:25:50'],\n            ['ddd, h A',                           'կրկ, 3 ցերեկվա'],\n            ['M Mo MM MMMM MMM',                   '2 2 02 փետրվար փտր'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14 14'],\n            ['d do dddd ddd dd',                   '0 0 կիրակի կրկ կրկ'],\n            ['DDD DDDo DDDD',                      '45 45-րդ 045'],\n            ['w wo ww',                            '7 7-րդ 07'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'ցերեկվա ցերեկվա'],\n            ['[տարվա] DDDo [օրը]',                 'տարվա 45-րդ օրը'],\n            ['LTS',                                '15:25:50'],\n            ['L',                                  '14.02.2010'],\n            ['LL',                                 '14 փետրվարի 2010 թ.'],\n            ['LLL',                                '14 փետրվարի 2010 թ., 15:25'],\n            ['LLLL',                               'կիրակի, 14 փետրվարի 2010 թ., 15:25'],\n            ['l',                                  '14.2.2010'],\n            ['ll',                                 '14 փտր 2010 թ.'],\n            ['lll',                                '14 փտր 2010 թ., 15:25'],\n            ['llll',                               'կրկ, 14 փտր 2010 թ., 15:25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format meridiem', function (assert) {\n    assert.equal(moment([2012, 11, 28, 0, 0]).format('A'), 'գիշերվա', 'night');\n    assert.equal(moment([2012, 11, 28, 3, 59]).format('A'), 'գիշերվա', 'night');\n    assert.equal(moment([2012, 11, 28, 4, 0]).format('A'), 'առավոտվա', 'morning');\n    assert.equal(moment([2012, 11, 28, 11, 59]).format('A'), 'առավոտվա', 'morning');\n    assert.equal(moment([2012, 11, 28, 12, 0]).format('A'), 'ցերեկվա', 'afternoon');\n    assert.equal(moment([2012, 11, 28, 16, 59]).format('A'), 'ցերեկվա', 'afternoon');\n    assert.equal(moment([2012, 11, 28, 17, 0]).format('A'), 'երեկոյան', 'evening');\n    assert.equal(moment([2012, 11, 28, 23, 59]).format('A'), 'երեկոյան', 'evening');\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1-ին', '1-ին');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2-րդ', '2-րդ');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3-րդ', '3-րդ');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4-րդ', '4-րդ');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5-րդ', '5-րդ');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6-րդ', '6-րդ');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7-րդ', '7-րդ');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8-րդ', '8-րդ');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9-րդ', '9-րդ');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10-րդ', '10-րդ');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11-րդ', '11-րդ');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12-րդ', '12-րդ');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13-րդ', '13-րդ');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14-րդ', '14-րդ');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15-րդ', '15-րդ');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16-րդ', '16-րդ');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17-րդ', '17-րդ');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18-րդ', '18-րդ');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19-րդ', '19-րդ');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20-րդ', '20-րդ');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21-րդ', '21-րդ');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22-րդ', '22-րդ');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23-րդ', '23-րդ');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24-րդ', '24-րդ');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25-րդ', '25-րդ');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26-րդ', '26-րդ');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27-րդ', '27-րդ');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28-րդ', '28-րդ');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29-րդ', '29-րդ');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30-րդ', '30-րդ');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31-րդ', '31-րդ');\n});\n\ntest('format month', function (assert) {\n    var expected = 'հունվար հնվ_փետրվար փտր_մարտ մրտ_ապրիլ ապր_մայիս մյս_հունիս հնս_հուլիս հլս_օգոստոս օգս_սեպտեմբեր սպտ_հոկտեմբեր հկտ_նոյեմբեր նմբ_դեկտեմբեր դկտ'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format month case', function (assert) {\n    var months = {\n        'nominative': 'հունվար_փետրվար_մարտ_ապրիլ_մայիս_հունիս_հուլիս_օգոստոս_սեպտեմբեր_հոկտեմբեր_նոյեմբեր_դեկտեմբեր'.split('_'),\n        'accusative': 'հունվարի_փետրվարի_մարտի_ապրիլի_մայիսի_հունիսի_հուլիսի_օգոստոսի_սեպտեմբերի_հոկտեմբերի_նոյեմբերի_դեկտեմբերի'.split('_')\n    }, i;\n    for (i = 0; i < 12; i++) {\n        assert.equal(moment([2011, i, 1]).format('D MMMM'), '1 ' + months.accusative[i], '1 ' + months.accusative[i]);\n        assert.equal(moment([2011, i, 1]).format('MMMM'), months.nominative[i], '1 ' + months.nominative[i]);\n    }\n});\n\ntest('format month short case', function (assert) {\n    var monthsShort = {\n        'nominative': 'հնվ_փտր_մրտ_ապր_մյս_հնս_հլս_օգս_սպտ_հկտ_նմբ_դկտ'.split('_'),\n        'accusative': 'հնվ_փտր_մրտ_ապր_մյս_հնս_հլս_օգս_սպտ_հկտ_նմբ_դկտ'.split('_')\n    }, i;\n    for (i = 0; i < 12; i++) {\n        assert.equal(moment([2011, i, 1]).format('D MMM'), '1 ' + monthsShort.accusative[i], '1 ' + monthsShort.accusative[i]);\n        assert.equal(moment([2011, i, 1]).format('MMM'), monthsShort.nominative[i], '1 ' + monthsShort.nominative[i]);\n    }\n});\n\ntest('format month case with escaped symbols', function (assert) {\n    var months = {\n        'nominative': 'հունվար_փետրվար_մարտ_ապրիլ_մայիս_հունիս_հուլիս_օգոստոս_սեպտեմբեր_հոկտեմբեր_նոյեմբեր_դեկտեմբեր'.split('_'),\n        'accusative': 'հունվարի_փետրվարի_մարտի_ապրիլի_մայիսի_հունիսի_հուլիսի_օգոստոսի_սեպտեմբերի_հոկտեմբերի_նոյեմբերի_դեկտեմբերի'.split('_')\n    }, i;\n    for (i = 0; i < 12; i++) {\n        assert.equal(moment([2013, i, 1]).format('D[] MMMM'), '1 ' + months.accusative[i], '1 ' + months.accusative[i]);\n        assert.equal(moment([2013, i, 1]).format('[<i>]D[</i>] [<b>]MMMM[</b>]'), '<i>1</i> <b>' + months.accusative[i] + '</b>', '1 <b>' + months.accusative[i] + '</b>');\n        assert.equal(moment([2013, i, 1]).format('D[-ին օրը] MMMM'), '1-ին օրը ' + months.accusative[i], '1-ին օրը ' + months.accusative[i]);\n        assert.equal(moment([2013, i, 1]).format('D, MMMM'), '1, ' + months.nominative[i], '1, ' + months.nominative[i]);\n    }\n});\n\ntest('format month short case with escaped symbols', function (assert) {\n    var monthsShort = {\n        'nominative': 'հնվ_փտր_մրտ_ապր_մյս_հնս_հլս_օգս_սպտ_հկտ_նմբ_դկտ'.split('_'),\n        'accusative': 'հնվ_փտր_մրտ_ապր_մյս_հնս_հլս_օգս_սպտ_հկտ_նմբ_դկտ'.split('_')\n    }, i;\n    for (i = 0; i < 12; i++) {\n        assert.equal(moment([2013, i, 1]).format('D[] MMM'), '1 ' + monthsShort.accusative[i], '1 ' + monthsShort.accusative[i]);\n        assert.equal(moment([2013, i, 1]).format('[<i>]D[</i>] [<b>]MMM[</b>]'), '<i>1</i> <b>' + monthsShort.accusative[i] + '</b>', '1 <b>' + monthsShort.accusative[i] + '</b>');\n        assert.equal(moment([2013, i, 1]).format('D[-ին օրը] MMM'), '1-ին օրը ' + monthsShort.accusative[i], '1-ին օրը ' + monthsShort.accusative[i]);\n        assert.equal(moment([2013, i, 1]).format('D, MMM'), '1, ' + monthsShort.nominative[i], '1, ' + monthsShort.nominative[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'կիրակի կրկ կրկ_երկուշաբթի երկ երկ_երեքշաբթի երք երք_չորեքշաբթի չրք չրք_հինգշաբթի հնգ հնգ_ուրբաթ ուրբ ուրբ_շաբաթ շբթ շբթ'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'մի քանի վայրկյան',    '44 seconds = seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'րոպե',   '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'րոպե',   '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 րոպե',  '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 րոպե', '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'ժամ',    '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'ժամ',    '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 ժամ',    '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 ժամ',    '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 ժամ',   '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'օր',      '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'օր',      '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 օր',     '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'օր',      '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 օր',     '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 11}), true),  '11 օր',     '11 days = 11 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 21}), true),  '21 օր',     '21 days = 21 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 օր',    '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'ամիս',    '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'ամիս',    '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'ամիս',    '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 ամիս',   '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 ամիս',   '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 ամիս',   '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'ամիս',    '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 ամիս',   '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'տարի',     '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 տարի',    '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'տարի',     '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 տարի',    '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'մի քանի վայրկյան հետո', 'prefix');\n    assert.equal(moment(0).from(30000), 'մի քանի վայրկյան առաջ', 'suffix');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'մի քանի վայրկյան հետո', 'in seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), '5 օր հետո', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'այսօր 12:00',   'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'այսօր 12:25',   'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'այսօր 13:00',   'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'վաղը 12:00',    'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'այսօր 11:00',   'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'երեկ 12:00',    'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    function makeFormat(d) {\n        return 'dddd [օրը ժամը] LT';\n    }\n\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format(makeFormat(m)),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format(makeFormat(m)),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format(makeFormat(m)),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n\n    function makeFormat(d) {\n        return '[անցած] dddd [օրը ժամը] LT';\n    }\n\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format(makeFormat(m)),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format(makeFormat(m)),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format(makeFormat(m)),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2011, 11, 26]).format('w ww wo'), '1 01 1-ին', 'Dec 26 2011 should be week 1');\n    assert.equal(moment([2012,  0,  1]).format('w ww wo'), '1 01 1-ին', 'Jan  1 2012 should be week 1');\n    assert.equal(moment([2012,  0,  2]).format('w ww wo'), '2 02 2-րդ', 'Jan  2 2012 should be week 2');\n    assert.equal(moment([2012,  0,  8]).format('w ww wo'), '2 02 2-րդ', 'Jan  8 2012 should be week 2');\n    assert.equal(moment([2012,  0,  9]).format('w ww wo'), '3 03 3-րդ', 'Jan  9 2012 should be week 3');\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\n\n\nfunction localeModule (name, lifecycle) {\n    QUnit.module('locale:' + name, {\n        setup : function () {\n            moment.locale(name);\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            moment.locale('en');\n            teardownDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n    defineCommonLocaleTests(name, -1, -1);\n}\n\nlocaleModule('id');\n\ntest('parse', function (assert) {\n    var tests = 'Januari Jan_Februari Feb_Maret Mar_April Apr_Mei Mei_Juni Jun_Juli Jul_Agustus Ags_September Sep_Oktober Okt_November Nov_Desember Des'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, MMMM Do YYYY, h:mm:ss a',      'Minggu, Februari 14 2010, 3:25:50 sore'],\n            ['ddd, hA',                            'Min, 3sore'],\n            ['M Mo MM MMMM MMM',                   '2 2 02 Februari Feb'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14 14'],\n            ['d do dddd ddd dd',                   '0 0 Minggu Min Mg'],\n            ['DDD DDDo DDDD',                      '45 45 045'],\n            ['w wo ww',                            '7 7 07'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'sore sore'],\n            ['[the] DDDo [day of the year]',       'the 45 day of the year'],\n            ['LTS',                                '15.25.50'],\n            ['L',                                  '14/02/2010'],\n            ['LL',                                 '14 Februari 2010'],\n            ['LLL',                                '14 Februari 2010 pukul 15.25'],\n            ['LLLL',                               'Minggu, 14 Februari 2010 pukul 15.25'],\n            ['l',                                  '14/2/2010'],\n            ['ll',                                 '14 Feb 2010'],\n            ['lll',                                '14 Feb 2010 pukul 15.25'],\n            ['llll',                               'Min, 14 Feb 2010 pukul 15.25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format month', function (assert) {\n    var expected = 'Januari Jan_Februari Feb_Maret Mar_April Apr_Mei Mei_Juni Jun_Juli Jul_Agustus Ags_September Sep_Oktober Okt_November Nov_Desember Des'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'Minggu Min Mg_Senin Sen Sn_Selasa Sel Sl_Rabu Rab Rb_Kamis Kam Km_Jumat Jum Jm_Sabtu Sab Sb'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'beberapa detik', '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'semenit',      '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'semenit',      '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 menit',     '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 menit',    '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'sejam',       '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'sejam',       '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 jam',       '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 jam',       '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 jam',      '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'sehari',         '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'sehari',         '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 hari',        '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'sehari',         '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 hari',        '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 hari',       '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'sebulan',       '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'sebulan',       '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'sebulan',       '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 bulan',      '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 bulan',      '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 bulan',      '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'sebulan',       '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 bulan',      '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'setahun',        '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 tahun',       '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'setahun',        '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 tahun',       '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'dalam beberapa detik',  'prefix');\n    assert.equal(moment(0).from(30000), 'beberapa detik yang lalu', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'beberapa detik yang lalu',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'dalam beberapa detik', 'in a few seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), 'dalam 5 hari', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'Hari ini pukul 12.00', 'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'Hari ini pukul 12.25', 'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'Hari ini pukul 13.00', 'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'Besok pukul 12.00',    'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'Hari ini pukul 11.00', 'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'Kemarin pukul 12.00',  'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('dddd [pukul] LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd [pukul] LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd [pukul] LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('dddd [lalu pukul] LT'),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd [lalu pukul] LT'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd [lalu pukul] LT'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2011, 11, 26]).format('w ww wo'), '1 01 1', 'Dec 26 2011 should be week 1');\n    assert.equal(moment([2012,  0,  1]).format('w ww wo'), '1 01 1', 'Jan  1 2012 should be week 1');\n    assert.equal(moment([2012,  0,  2]).format('w ww wo'), '2 02 2', 'Jan  2 2012 should be week 2');\n    assert.equal(moment([2012,  0,  8]).format('w ww wo'), '2 02 2', 'Jan  8 2012 should be week 2');\n    assert.equal(moment([2012,  0,  9]).format('w ww wo'), '3 03 3', 'Jan  9 2012 should be week 3');\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\n\n\nfunction localeModule (name, lifecycle) {\n    QUnit.module('locale:' + name, {\n        setup : function () {\n            moment.locale(name);\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            moment.locale('en');\n            teardownDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n    defineCommonLocaleTests(name, -1, -1);\n}\n\nlocaleModule('is');\n\ntest('parse', function (assert) {\n    var tests = 'janúar jan_febrúar feb_mars mar_apríl apr_maí maí_júní jún_júlí júl_ágúst ágú_september sep_október okt_nóvember nóv_desember des'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, Do MMMM YYYY, h:mm:ss a',      'sunnudagur, 14. febrúar 2010, 3:25:50 pm'],\n            ['ddd, hA',                            'sun, 3PM'],\n            ['M Mo MM MMMM MMM',                   '2 2. 02 febrúar feb'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14. 14'],\n            ['d do dddd ddd dd',                   '0 0. sunnudagur sun Su'],\n            ['DDD DDDo DDDD',                      '45 45. 045'],\n            ['w wo ww',                            '6 6. 06'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'pm PM'],\n            ['[the] DDDo [day of the year]',       'the 45. day of the year'],\n            ['LTS',                                '15:25:50'],\n            ['L',                                  '14.02.2010'],\n            ['LL',                                 '14. febrúar 2010'],\n            ['LLL',                                '14. febrúar 2010 kl. 15:25'],\n            ['LLLL',                               'sunnudagur, 14. febrúar 2010 kl. 15:25'],\n            ['l',                                  '14.2.2010'],\n            ['ll',                                 '14. feb 2010'],\n            ['lll',                                '14. feb 2010 kl. 15:25'],\n            ['llll',                               'sun, 14. feb 2010 kl. 15:25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1.', '1.');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2.', '2.');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3.', '3.');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4.', '4.');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5.', '5.');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6.', '6.');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7.', '7.');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8.', '8.');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9.', '9.');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10.', '10.');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11.', '11.');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12.', '12.');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13.', '13.');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14.', '14.');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15.', '15.');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16.', '16.');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17.', '17.');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18.', '18.');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19.', '19.');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20.', '20.');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21.', '21.');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22.', '22.');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23.', '23.');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24.', '24.');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25.', '25.');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26.', '26.');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27.', '27.');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28.', '28.');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29.', '29.');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30.', '30.');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31.', '31.');\n});\n\ntest('format month', function (assert) {\n    var expected = 'janúar jan_febrúar feb_mars mar_apríl apr_maí maí_júní jún_júlí júl_ágúst ágú_september sep_október okt_nóvember nóv_desember des'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'sunnudagur sun Su_mánudagur mán Má_þriðjudagur þri Þr_miðvikudagur mið Mi_fimmtudagur fim Fi_föstudagur fös Fö_laugardagur lau La'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'nokkrar sekúndur', '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'mínúta',      '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'mínúta',      '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 mínútur',     '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 mínútur',    '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 21}), true),  '21 mínúta',    '21 minutes = 21 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'klukkustund',       '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'klukkustund',       '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 klukkustundir',       '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 klukkustundir',       '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 klukkustund',      '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'dagur',         '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'dagur',         '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 dagar',        '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'dagur',         '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 dagar',        '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 dagar',       '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 11}), true),  '11 dagar',       '11 days = 11 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 21}), true),  '21 dagur',       '21 days = 21 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'mánuður',       '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'mánuður',       '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'mánuður',       '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 mánuðir',      '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 mánuðir',      '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 mánuðir',      '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'mánuður',       '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 mánuðir',      '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'ár',        '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 ár',       '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'ár',        '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 ár',       '5 years = 5 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 21}), true),  '21 ár',       '21 years = 21 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'eftir nokkrar sekúndur',  'prefix');\n    assert.equal(moment(0).from(30000), 'fyrir nokkrum sekúndum síðan', 'suffix');\n    assert.equal(moment().subtract({m: 1}).fromNow(), 'fyrir mínútu síðan', 'a minute ago');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'fyrir nokkrum sekúndum síðan',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'eftir nokkrar sekúndur', 'in a few seconds');\n    assert.equal(moment().add({m: 1}).fromNow(), 'eftir mínútu', 'in a minute');\n    assert.equal(moment().add({d: 5}).fromNow(), 'eftir 5 daga', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'í dag kl. 12:00',     'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'í dag kl. 12:25',     'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'í dag kl. 13:00',     'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'á morgun kl. 12:00',  'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'í dag kl. 11:00',     'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'í gær kl. 12:00',     'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('dddd [kl.] LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd [kl.] LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd [kl.] LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('[síðasta] dddd [kl.] LT'),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[síðasta] dddd [kl.] LT'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[síðasta] dddd [kl.] LT'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2012, 0,  1]).format('w ww wo'), '52 52 52.', 'Jan  1 2012 should be week 52');\n    assert.equal(moment([2012, 0,  2]).format('w ww wo'),  '1 01 1.', 'Jan  2 2012 should be week 1');\n    assert.equal(moment([2012, 0,  8]).format('w ww wo'),  '1 01 1.', 'Jan  8 2012 should be week 1');\n    assert.equal(moment([2012, 0,  9]).format('w ww wo'),  '2 02 2.', 'Jan  9 2012 should be week 2');\n    assert.equal(moment([2012, 0, 15]).format('w ww wo'),  '2 02 2.', 'Jan 15 2012 should be week 2');\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\n\n\nfunction localeModule (name, lifecycle) {\n    QUnit.module('locale:' + name, {\n        setup : function () {\n            moment.locale(name);\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            moment.locale('en');\n            teardownDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n    defineCommonLocaleTests(name, -1, -1);\n}\n\nlocaleModule('it');\n\ntest('parse', function (assert) {\n    var tests = 'gennaio gen_febbraio feb_marzo mar_aprile apr_maggio mag_giugno giu_luglio lug_agosto ago_settembre set_ottobre ott_novembre nov_dicembre dic'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, MMMM Do YYYY, h:mm:ss a',      'domenica, febbraio 14º 2010, 3:25:50 pm'],\n            ['ddd, hA',                            'dom, 3PM'],\n            ['M Mo MM MMMM MMM',                   '2 2º 02 febbraio feb'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14º 14'],\n            ['d do dddd ddd dd',                   '0 0º domenica dom do'],\n            ['DDD DDDo DDDD',                      '45 45º 045'],\n            ['w wo ww',                            '6 6º 06'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'pm PM'],\n            ['[the] DDDo [day of the year]',       'the 45º day of the year'],\n            ['LTS',                                '15:25:50'],\n            ['L',                                  '14/02/2010'],\n            ['LL',                                 '14 febbraio 2010'],\n            ['LLL',                                '14 febbraio 2010 15:25'],\n            ['LLLL',                               'domenica, 14 febbraio 2010 15:25'],\n            ['l',                                  '14/2/2010'],\n            ['ll',                                 '14 feb 2010'],\n            ['lll',                                '14 feb 2010 15:25'],\n            ['llll',                               'dom, 14 feb 2010 15:25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1º', '1º');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2º', '2º');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3º', '3º');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4º', '4º');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5º', '5º');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6º', '6º');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7º', '7º');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8º', '8º');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9º', '9º');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10º', '10º');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11º', '11º');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12º', '12º');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13º', '13º');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14º', '14º');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15º', '15º');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16º', '16º');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17º', '17º');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18º', '18º');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19º', '19º');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20º', '20º');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21º', '21º');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22º', '22º');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23º', '23º');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24º', '24º');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25º', '25º');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26º', '26º');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27º', '27º');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28º', '28º');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29º', '29º');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30º', '30º');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31º', '31º');\n});\n\ntest('format month', function (assert) {\n    var expected = 'gennaio gen_febbraio feb_marzo mar_aprile apr_maggio mag_giugno giu_luglio lug_agosto ago_settembre set_ottobre ott_novembre nov_dicembre dic'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'domenica dom do_lunedì lun lu_martedì mar ma_mercoledì mer me_giovedì gio gi_venerdì ven ve_sabato sab sa'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'alcuni secondi', '44 seconds = seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'un minuto',      '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'un minuto',      '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 minuti',       '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 minuti',      '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'un\\'ora',        '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'un\\'ora',        '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 ore',          '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 ore',          '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 ore',         '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'un giorno',      '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'un giorno',      '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 giorni',       '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'un giorno',      '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 giorni',       '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 giorni',      '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'un mese',        '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'un mese',        '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'un mese',        '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 mesi',         '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 mesi',         '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 mesi',         '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'un mese',        '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 mesi',         '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'un anno',        '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 anni',         '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'un anno',        '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 anni',         '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'in alcuni secondi', 'prefix');\n    assert.equal(moment(0).from(30000), 'alcuni secondi fa', 'suffix');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'in alcuni secondi', 'in seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), 'tra 5 giorni', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'Oggi alle 12:00',     'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'Oggi alle 12:25',     'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'Oggi alle 13:00',     'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'Domani alle 12:00',   'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'Oggi alle 11:00',     'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'Ieri alle 12:00',     'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('dddd [alle] LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd [alle] LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd [alle] LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m, weekday, datestring;\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        // Different date string\n        weekday = parseInt(m.format('d'), 10);\n        datestring = (weekday === 0) ? '[la scorsa] dddd [alle] LT' : '[lo scorso] dddd [alle] LT';\n        assert.equal(m.calendar(), m.format(datestring), 'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(), m.format(datestring), 'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(), m.format(datestring), 'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2012, 0,  1]).format('w ww wo'), '52 52 52º', 'Jan  1 2012 should be week 52');\n    assert.equal(moment([2012, 0,  2]).format('w ww wo'),  '1 01 1º', 'Jan  2 2012 should be week 1');\n    assert.equal(moment([2012, 0,  8]).format('w ww wo'),  '1 01 1º', 'Jan  8 2012 should be week 1');\n    assert.equal(moment([2012, 0,  9]).format('w ww wo'),  '2 02 2º', 'Jan  9 2012 should be week 2');\n    assert.equal(moment([2012, 0, 15]).format('w ww wo'),  '2 02 2º', 'Jan 15 2012 should be week 2');\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\n\n\nfunction localeModule (name, lifecycle) {\n    QUnit.module('locale:' + name, {\n        setup : function () {\n            moment.locale(name);\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            moment.locale('en');\n            teardownDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n    defineCommonLocaleTests(name, -1, -1);\n}\n\nlocaleModule('ja');\n\ntest('parse', function (assert) {\n    var tests = '1月 1月_2月 2月_3月 3月_4月 4月_5月 5月_6月 6月_7月 7月_8月 8月_9月 9月_10月 10月_11月 11月_12月 12月'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, MMMM Do YYYY, a h:mm:ss',      '日曜日, 2月 14日 2010, 午後 3:25:50'],\n            ['ddd, Ah',                            '日, 午後3'],\n            ['M Mo MM MMMM MMM',                   '2 2 02 2月 2月'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14日 14'],\n            ['d do dddd ddd dd',                   '0 0日 日曜日 日 日'],\n            ['DDD DDDo DDDD',                      '45 45日 045'],\n            ['w wo ww',                            '8 8 08'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                '午後 午後'],\n            ['[the] DDDo [day of the year]',       'the 45日 day of the year'],\n            ['LTS',                                '15:25:50'],\n            ['L',                                  '2010/02/14'],\n            ['LL',                                 '2010年2月14日'],\n            ['LLL',                                '2010年2月14日 15:25'],\n            ['LLLL',                               '2010年2月14日 15:25 日曜日'],\n            ['l',                                  '2010/02/14'],\n            ['ll',                                 '2010年2月14日'],\n            ['lll',                                '2010年2月14日 15:25'],\n            ['llll',                               '2010年2月14日 15:25 日曜日']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format month', function (assert) {\n    var expected = '1月 1月_2月 2月_3月 3月_4月 4月_5月 5月_6月 6月_7月 7月_8月 8月_9月 9月_10月 10月_11月 11月_12月 12月'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = '日曜日 日 日_月曜日 月 月_火曜日 火 火_水曜日 水 水_木曜日 木 木_金曜日 金 金_土曜日 土 土'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  '数秒',   '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  '1分', '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  '1分', '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2分',  '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44分', '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  '1時間', '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  '1時間', '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2時間',  '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5時間',  '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21時間', '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  '1日',   '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  '1日',   '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2日',   '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   '1日',   '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5日',   '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25日',  '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  '1ヶ月', '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  '1ヶ月', '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  '1ヶ月', '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2ヶ月',  '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2ヶ月',  '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3ヶ月',  '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   '1ヶ月', '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5ヶ月',  '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), '1年',   '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2年',   '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   '1年',   '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5年',   '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), '数秒後',  'prefix');\n    assert.equal(moment(0).from(30000), '数秒前', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), '数秒前',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), '数秒後', 'in a few seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), '5日後', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   '今日 12:00', 'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      '今日 12:25', 'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       '今日 13:00', 'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       '明日 12:00', 'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  '今日 11:00', 'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  '昨日 12:00', 'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('[来週]dddd LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[来週]dddd LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[来週]dddd LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('[前週]dddd LT'),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[前週]dddd LT'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[前週]dddd LT'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),      '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),      '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('weeks year starting sunday format', function (assert) {\n    assert.equal(moment([2012, 0,  1]).format('w ww wo'), '1 01 1', 'Jan  1 2012 should be week 1');\n    assert.equal(moment([2012, 0,  7]).format('w ww wo'), '1 01 1', 'Jan  7 2012 should be week 1');\n    assert.equal(moment([2012, 0,  8]).format('w ww wo'), '2 02 2', 'Jan  8 2012 should be week 2');\n    assert.equal(moment([2012, 0, 14]).format('w ww wo'), '2 02 2', 'Jan 14 2012 should be week 2');\n    assert.equal(moment([2012, 0, 15]).format('w ww wo'), '3 03 3', 'Jan 15 2012 should be week 3');\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\n\n\nfunction localeModule (name, lifecycle) {\n    QUnit.module('locale:' + name, {\n        setup : function () {\n            moment.locale(name);\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            moment.locale('en');\n            teardownDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n    defineCommonLocaleTests(name, -1, -1);\n}\n\nlocaleModule('jv');\n\ntest('parse', function (assert) {\n    var tests = 'Januari Jan_Februari Feb_Maret Mar_April Apr_Mei Mei_Juni Jun_Juli Jul_Agustus Ags_September Sep_Oktober Okt_Nopember Nop_Desember Des'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, MMMM Do YYYY, h:mm:ss a',      'Minggu, Februari 14 2010, 3:25:50 sonten'],\n            ['ddd, hA',                            'Min, 3sonten'],\n            ['M Mo MM MMMM MMM',                   '2 2 02 Februari Feb'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14 14'],\n            ['d do dddd ddd dd',                   '0 0 Minggu Min Mg'],\n            ['DDD DDDo DDDD',                      '45 45 045'],\n            ['w wo ww',                            '7 7 07'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'sonten sonten'],\n            ['[the] DDDo [day of the year]',       'the 45 day of the year'],\n            ['LTS',                                '15.25.50'],\n            ['L',                                  '14/02/2010'],\n            ['LL',                                 '14 Februari 2010'],\n            ['LLL',                                '14 Februari 2010 pukul 15.25'],\n            ['LLLL',                               'Minggu, 14 Februari 2010 pukul 15.25'],\n            ['l',                                  '14/2/2010'],\n            ['ll',                                 '14 Feb 2010'],\n            ['lll',                                '14 Feb 2010 pukul 15.25'],\n            ['llll',                               'Min, 14 Feb 2010 pukul 15.25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format month', function (assert) {\n    var expected = 'Januari Jan_Februari Feb_Maret Mar_April Apr_Mei Mei_Juni Jun_Juli Jul_Agustus Ags_September Sep_Oktober Okt_Nopember Nop_Desember Des'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'Minggu Min Mg_Senen Sen Sn_Seloso Sel Sl_Rebu Reb Rb_Kemis Kem Km_Jemuwah Jem Jm_Septu Sep Sp'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'sawetawis detik', '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'setunggal menit',      '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'setunggal menit',      '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 menit',     '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 menit',    '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'setunggal jam',       '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'setunggal jam',       '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 jam',       '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 jam',       '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 jam',      '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'sedinten',         '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'sedinten',         '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 dinten',        '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'sedinten',         '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 dinten',        '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 dinten',       '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'sewulan',       '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'sewulan',       '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'sewulan',       '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 wulan',      '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 wulan',      '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 wulan',      '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'sewulan',       '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 wulan',      '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'setaun',        '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 taun',       '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'setaun',        '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 taun',       '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'wonten ing sawetawis detik',  'prefix');\n    assert.equal(moment(0).from(30000), 'sawetawis detik ingkang kepengker', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'sawetawis detik ingkang kepengker',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'wonten ing sawetawis detik', 'in a few seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), 'wonten ing 5 dinten', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'Dinten puniko pukul 12.00', 'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'Dinten puniko pukul 12.25', 'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'Dinten puniko pukul 13.00', 'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'Mbenjang pukul 12.00',      'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'Dinten puniko pukul 11.00', 'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'Kala wingi pukul 12.00',    'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('dddd [pukul] LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd [pukul] LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd [pukul] LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('dddd [kepengker pukul] LT'),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd [kepengker pukul] LT'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd [kepengker pukul] LT'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\n// Monday is the first day of the week.\n// The week that contains Jan 1st is the first week of the year.\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2011, 11, 26]).format('w ww wo'), '1 01 1', 'Dec 26 2011 should be week 1');\n    assert.equal(moment([2012,  0,  1]).format('w ww wo'), '1 01 1', 'Jan  1 2012 should be week 1');\n    assert.equal(moment([2012,  0,  2]).format('w ww wo'), '2 02 2', 'Jan  2 2012 should be week 2');\n    assert.equal(moment([2012,  0,  8]).format('w ww wo'), '2 02 2', 'Jan  8 2012 should be week 2');\n    assert.equal(moment([2012,  0,  9]).format('w ww wo'), '3 03 3', 'Jan  9 2012 should be week 3');\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\n\n\nfunction localeModule (name, lifecycle) {\n    QUnit.module('locale:' + name, {\n        setup : function () {\n            moment.locale(name);\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            moment.locale('en');\n            teardownDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n    defineCommonLocaleTests(name, -1, -1);\n}\n\nlocaleModule('ka');\n\ntest('parse', function (assert) {\n    var i,\n        tests = 'იანვარი იან_თებერვალი თებ_მარტი მარ_აპრილი აპრ_მაისი მაი_ივნისი ივნ_ივლისი ივლ_აგვისტო აგვ_სექტემბერი სექ_ოქტომბერი ოქტ_ნოემბერი ნოე_დეკემბერი დეკ'.split('_');\n\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' უნდა იყოს თვე ' + (i + 1));\n    }\n\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, MMMM Do YYYY, h:mm:ss a', 'კვირა, თებერვალი მე-14 2010, 3:25:50 pm'],\n            ['ddd, hA',                       'კვი, 3PM'],\n            ['M Mo MM MMMM MMM',              '2 მე-2 02 თებერვალი თებ'],\n            ['YYYY YY',                       '2010 10'],\n            ['D Do DD',                       '14 მე-14 14'],\n            ['d do dddd ddd dd',              '0 0 კვირა კვი კვ'],\n            ['DDD DDDo DDDD',                 '45 45-ე 045'],\n            ['w wo ww',                       '7 მე-7 07'],\n            ['h hh',                          '3 03'],\n            ['H HH',                          '15 15'],\n            ['m mm',                          '25 25'],\n            ['s ss',                          '50 50'],\n            ['a A',                           'pm PM'],\n            ['წლის DDDo დღე',                 'წლის 45-ე დღე'],\n            ['LTS',                           '3:25:50 PM'],\n            ['L',                             '14/02/2010'],\n            ['LL',                            '14 თებერვალს 2010'],\n            ['LLL',                           '14 თებერვალს 2010 3:25 PM'],\n            ['LLLL',                          'კვირა, 14 თებერვალს 2010 3:25 PM'],\n            ['l',                             '14/2/2010'],\n            ['ll',                            '14 თებ 2010'],\n            ['lll',                           '14 თებ 2010 3:25 PM'],\n            ['llll',                          'კვი, 14 თებ 2010 3:25 PM']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'),  '1-ლი',  '1-ლი');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'),  'მე-2',  'მე-2');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'),  'მე-3',  'მე-3');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'),  'მე-4',  'მე-4');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'),  'მე-5',  'მე-5');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'),  'მე-6',  'მე-6');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'),  'მე-7',  'მე-7');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'),  'მე-8',  'მე-8');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'),  'მე-9',  'მე-9');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), 'მე-10', 'მე-10');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), 'მე-11', 'მე-11');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), 'მე-12', 'მე-12');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), 'მე-13', 'მე-13');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), 'მე-14', 'მე-14');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), 'მე-15', 'მე-15');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), 'მე-16', 'მე-16');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), 'მე-17', 'მე-17');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), 'მე-18', 'მე-18');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), 'მე-19', 'მე-19');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), 'მე-20', 'მე-20');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21-ე', '21-ე');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22-ე', '22-ე');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23-ე', '23-ე');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24-ე', '24-ე');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25-ე', '25-ე');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26-ე', '26-ე');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27-ე', '27-ე');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28-ე', '28-ე');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29-ე', '29-ე');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30-ე', '30-ე');\n\n    assert.equal(moment('2011 40', 'YYYY DDD').format('DDDo'),  'მე-40',  'მე-40');\n    assert.equal(moment('2011 50', 'YYYY DDD').format('DDDo'),  '50-ე',   '50-ე');\n    assert.equal(moment('2011 60', 'YYYY DDD').format('DDDo'),  'მე-60',  'მე-60');\n    assert.equal(moment('2011 100', 'YYYY DDD').format('DDDo'), 'მე-100', 'მე-100');\n    assert.equal(moment('2011 101', 'YYYY DDD').format('DDDo'), '101-ე',  '101-ე');\n});\n\ntest('format month', function (assert) {\n    var i,\n        expected = 'იანვარი იან_თებერვალი თებ_მარტი მარ_აპრილი აპრ_მაისი მაი_ივნისი ივნ_ივლისი ივლ_აგვისტო აგვ_სექტემბერი სექ_ოქტომბერი ოქტ_ნოემბერი ნოე_დეკემბერი დეკ'.split('_');\n\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var i,\n        expected = 'კვირა კვი კვ_ორშაბათი ორშ ორ_სამშაბათი სამ სა_ოთხშაბათი ოთხ ოთ_ხუთშაბათი ხუთ ხუ_პარასკევი პარ პა_შაბათი შაბ შა'.split('_');\n\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}),  true), 'რამდენიმე წამი', '44 წამი  = რამდენიმე წამი');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}),  true), 'წუთი',           '45 წამი  = წუთი');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}),  true), 'წუთი',           '89 წამი  = წუთი');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}),  true), '2 წუთი',         '90 წამი  = 2 წუთი');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}),  true), '44 წუთი',        '44 წამი  = 44 წუთი');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}),  true), 'საათი',          '45 წამი  = საათი');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}),  true), 'საათი',          '89 წამი  = საათი');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}),  true), '2 საათი',        '90 წამი  = 2 საათი');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}),   true), '5 საათი',        '5 საათი  = 5 საათი');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}),  true), '21 საათი',       '21 საათი = 21 საათი');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}),  true), 'დღე',            '22 საათი = დღე');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}),  true), 'დღე',            '35 საათი = დღე');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}),  true), '2 დღე',          '36 საათი = 2 დღე');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}),   true), 'დღე',            '1 დღე    = დღე');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}),   true), '5 დღე',          '5 დღე    = 5 დღე');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}),  true), '25 დღე',         '25 დღე   = 25 დღე');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}),  true), 'თვე',            '26 დღე   = თვე');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}),  true), 'თვე',            '30 დღე   = თვე');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}),  true), 'თვე',            '45 დღე   = თვე');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}),  true), '2 თვე',          '46 დღე   = 2 თვე');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}),  true), '2 თვე',          '75 დღე   = 2 თვე');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}),  true), '3 თვე',          '76 დღე   = 3 თვე');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}),   true), 'თვე',            '1 თვე    = თვე');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}),   true), '5 თვე',          '5 თვე    = 5 თვე');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'წელი',           '345 დღე  = წელი');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 წელი',         '548 დღე  = 2 წელი');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}),   true), 'წელი',           '1 წელი   = წელი');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}),   true), '5 წელი',         '5 წელი   = 5 წელი');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'რამდენიმე წამში',     'ში სუფიქსი');\n    assert.equal(moment(0).from(30000), 'რამდენიმე წამის უკან', 'უკან სუფიქსი');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'რამდენიმე წამის უკან', 'უნდა აჩვენოს როგორც წარსული');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'რამდენიმე წამში', 'რამდენიმე წამში');\n    assert.equal(moment().add({d: 5}).fromNow(), '5 დღეში', '5 დღეში');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'დღეს 12:00 PM-ზე',  'დღეს ამავე დროს');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'დღეს 12:25 PM-ზე',  'ახლანდელ დროს დამატებული 25 წუთი');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'დღეს 1:00 PM-ზე',   'ახლანდელ დროს დამატებული 1 საათი');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'ხვალ 12:00 PM-ზე',  'ხვალ ამავე დროს');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'დღეს 11:00 AM-ზე',  'ახლანდელ დროს გამოკლებული 1 საათი');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'გუშინ 12:00 PM-ზე', 'გუშინ ამავე დროს');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('[შემდეგ] dddd LT[-ზე]'),  'დღეს + ' + i + ' დღე ახლანდელ დროს');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[შემდეგ] dddd LT[-ზე]'),  'დღეს + ' + i + ' დღე დღის დასაწყისში');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[შემდეგ] dddd LT[-ზე]'),  'დღეს + ' + i + ' დღე დღის დასასრულს');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('[წინა] dddd LT[-ზე]'),  'დღეს - ' + i + ' დღე ახლანდელ დროს');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[წინა] dddd LT[-ზე]'),  'დღეს - ' + i + ' დღე დღის დასაწყისში');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[წინა] dddd LT[-ზე]'),  'დღეს - ' + i + ' დღე დღის დასასრულს');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 კვირის უკან');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  '1 კვირაში');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 კვირის წინ');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  '2 კვირაში');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2011, 11, 26]).format('w ww wo'), '1 01 1-ლი', 'დეკ 26 2011 უნდა იყოს კვირა 1');\n    assert.equal(moment([2012,  0,  1]).format('w ww wo'), '1 01 1-ლი', 'იან  1 2012 უნდა იყოს კვირა 1');\n    assert.equal(moment([2012,  0,  2]).format('w ww wo'), '2 02 მე-2', 'იან  2 2012 უნდა იყოს კვირა 2');\n    assert.equal(moment([2012,  0,  8]).format('w ww wo'), '2 02 მე-2', 'იან  8 2012 უნდა იყოს კვირა 2');\n    assert.equal(moment([2012,  0,  9]).format('w ww wo'), '3 03 მე-3', 'იან  9 2012 უნდა იყოს კვირა 3');\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\n\n\nfunction localeModule (name, lifecycle) {\n    QUnit.module('locale:' + name, {\n        setup : function () {\n            moment.locale(name);\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            moment.locale('en');\n            teardownDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n    defineCommonLocaleTests(name, -1, -1);\n}\n\nlocaleModule('kk');\n\ntest('parse', function (assert) {\n    var tests = 'қаңтар қаң_ақпан ақп_наурыз нау_сәуір сәу_мамыр мам_маусым мау_шілде шіл_тамыз там_қыркүйек қыр_қазан қаз_қараша қар_желтоқсан жел'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, Do MMMM YYYY, HH:mm:ss',       'жексенбі, 14-ші ақпан 2010, 15:25:50'],\n            ['ddd, hA',                            'жек, 3PM'],\n            ['M Mo MM MMMM MMM',                   '2 2-ші 02 ақпан ақп'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14-ші 14'],\n            ['d do dddd ddd dd',                   '0 0-ші жексенбі жек жк'],\n            ['DDD DDDo DDDD',                      '45 45-ші 045'],\n            ['w wo ww',                            '7 7-ші 07'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'pm PM'],\n            ['[жылдың] DDDo [күні]',               'жылдың 45-ші күні'],\n            ['LTS',                                '15:25:50'],\n            ['L',                                  '14.02.2010'],\n            ['LL',                                 '14 ақпан 2010'],\n            ['LLL',                                '14 ақпан 2010 15:25'],\n            ['LLLL',                               'жексенбі, 14 ақпан 2010 15:25'],\n            ['l',                                  '14.2.2010'],\n            ['ll',                                 '14 ақп 2010'],\n            ['lll',                                '14 ақп 2010 15:25'],\n            ['llll',                               'жек, 14 ақп 2010 15:25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1-ші', '1st');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2-ші', '2nd');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3-ші', '3rd');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4-ші', '4th');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5-ші', '5th');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6-шы', '6th');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7-ші', '7th');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8-ші', '8th');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9-шы', '9th');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10-шы', '10th');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11-ші', '11th');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12-ші', '12th');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13-ші', '13th');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14-ші', '14th');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15-ші', '15th');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16-шы', '16th');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17-ші', '17th');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18-ші', '18th');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19-шы', '19th');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20-шы', '20th');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21-ші', '21st');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22-ші', '22nd');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23-ші', '23rd');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24-ші', '24th');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25-ші', '25th');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26-шы', '26th');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27-ші', '27th');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28-ші', '28th');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29-шы', '29th');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30-шы', '30th');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31-ші', '31st');\n});\n\ntest('format month', function (assert) {\n    var expected = 'қаңтар қаң_ақпан ақп_наурыз нау_сәуір сәу_мамыр мам_маусым мау_шілде шіл_тамыз там_қыркүйек қыр_қазан қаз_қараша қар_желтоқсан жел'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'жексенбі жек жк_дүйсенбі дүй дй_сейсенбі сей сй_сәрсенбі сәр ср_бейсенбі бей бй_жұма жұм жм_сенбі сен сн'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'бірнеше секунд', '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'бір минут',      '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'бір минут',      '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 минут',     '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 минут',    '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'бір сағат',       '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'бір сағат',       '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 сағат',       '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 сағат',       '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 сағат',      '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'бір күн',         '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'бір күн',         '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 күн',        '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'бір күн',         '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 күн',        '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 күн',       '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'бір ай',       '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'бір ай',       '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'бір ай',       '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 ай',      '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 ай',      '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 ай',      '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'бір ай',       '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 ай',      '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'бір жыл',        '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 жыл',       '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'бір жыл',        '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 жыл',       '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'бірнеше секунд ішінде',  'prefix');\n    assert.equal(moment(0).from(30000), 'бірнеше секунд бұрын', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'бірнеше секунд бұрын',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'бірнеше секунд ішінде', 'in a few seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), '5 күн ішінде', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'Бүгін сағат 12:00',  'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'Бүгін сағат 12:25',  'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'Бүгін сағат 13:00',  'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'Ертең сағат 12:00',  'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'Бүгін сағат 11:00',  'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'Кеше сағат 12:00',   'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('dddd [сағат] LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd [сағат] LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd [сағат] LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('[Өткен аптаның] dddd [сағат] LT'),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[Өткен аптаның] dddd [сағат] LT'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[Өткен аптаның] dddd [сағат] LT'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2012, 0,  1]).format('w ww wo'),   '1 01 1-ші', 'Jan  1 2012 should be week 1');\n    assert.equal(moment([2012, 0,  2]).format('w ww wo'),   '2 02 2-ші', 'Jan  2 2012 should be week 2');\n    assert.equal(moment([2012, 0,  8]).format('w ww wo'),   '2 02 2-ші', 'Jan  8 2012 should be week 2');\n    assert.equal(moment([2012, 0,  9]).format('w ww wo'),   '3 03 3-ші', 'Jan  9 2012 should be week 3');\n    assert.equal(moment([2012, 0, 15]).format('w ww wo'),   '3 03 3-ші', 'Jan 15 2012 should be week 3');\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\n\n\nfunction localeModule (name, lifecycle) {\n    QUnit.module('locale:' + name, {\n        setup : function () {\n            moment.locale(name);\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            moment.locale('en');\n            teardownDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n    defineCommonLocaleTests(name, -1, -1);\n}\n\nlocaleModule('km');\n\ntest('parse', function (assert) {\n    var tests = 'មករា មករា_កុម្ភៈ កុម្ភៈ_មីនា មីនា_មេសា មេសា_ឧសភា ឧសភា_មិថុនា មិថុនា_កក្កដា កក្កដា_សីហា សីហា_កញ្ញា កញ្ញា_តុលា តុលា_វិច្ឆិកា វិច្ឆិកា_ធ្នូ ធ្នូ'.split('_'),\n        i;\n\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, MMMM Do YYYY, h:mm:ss a', 'អាទិត្យ, កុម្ភៈ 14 2010, 3:25:50 pm'],\n            ['ddd, hA', 'អាទិត្យ, 3PM'],\n            ['M Mo MM MMMM MMM', '2 2 02 កុម្ភៈ កុម្ភៈ'],\n            ['YYYY YY', '2010 10'],\n            ['D Do DD', '14 14 14'],\n            ['d do dddd ddd dd', '0 0 អាទិត្យ អាទិត្យ អាទិត្យ'],\n            ['DDD DDDo DDDD', '45 45 045'],\n            ['w wo ww', '6 6 06'],\n            ['h hh', '3 03'],\n            ['H HH', '15 15'],\n            ['m mm', '25 25'],\n            ['s ss', '50 50'],\n            ['a A', 'pm PM'],\n            ['[the] DDDo [day of the year]', 'the 45 day of the year'],\n            ['LTS', '15:25:50'],\n            ['L', '14/02/2010'],\n            ['LL', '14 កុម្ភៈ 2010'],\n            ['LLL', '14 កុម្ភៈ 2010 15:25'],\n            ['LLLL', 'អាទិត្យ, 14 កុម្ភៈ 2010 15:25'],\n            ['l', '14/2/2010'],\n            ['ll', '14 កុម្ភៈ 2010'],\n            ['lll', '14 កុម្ភៈ 2010 15:25'],\n            ['llll', 'អាទិត្យ, 14 កុម្ភៈ 2010 15:25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1', '1st');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2', '2nd');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3', '3rd');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4', '4th');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5', '5th');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6', '6th');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7', '7th');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8', '8th');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9', '9th');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10', '10th');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11', '11th');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12', '12th');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13', '13th');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14', '14th');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15', '15th');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16', '16th');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17', '17th');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18', '18th');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19', '19th');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20', '20th');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21', '21st');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22', '22nd');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23', '23rd');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24', '24th');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25', '25th');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26', '26th');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27', '27th');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28', '28th');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29', '29th');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30', '30th');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31', '31st');\n});\n\ntest('format month', function (assert) {\n    var expected = 'មករា មករា_កុម្ភៈ កុម្ភៈ_មីនា មីនា_មេសា មេសា_ឧសភា ឧសភា_មិថុនា មិថុនា_កក្កដា កក្កដា_សីហា សីហា_កញ្ញា កញ្ញា_តុលា តុលា_វិច្ឆិកា វិច្ឆិកា_ធ្នូ ធ្នូ'.split('_'),\n        i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'អាទិត្យ អាទិត្យ អាទិត្យ_ច័ន្ទ ច័ន្ទ ច័ន្ទ_អង្គារ អង្គារ អង្គារ_ពុធ ពុធ ពុធ_ព្រហស្បតិ៍ ព្រហស្បតិ៍ ព្រហស្បតិ៍_សុក្រ សុក្រ សុក្រ_សៅរ៍ សៅរ៍ សៅរ៍'.split('_'),\n        i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true), 'ប៉ុន្មានវិនាទី', '44 seconds = ប៉ុន្មានវិនាទី');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true), 'មួយនាទី', '45 seconds = មួយនាទី');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true), 'មួយនាទី', '89 seconds = មួយនាទី');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true), '2 នាទី', '90 seconds = 2 នាទី');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true), '44 នាទី', '44 minutes = 44 នាទី');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true), 'មួយម៉ោង', '45 minutes = មួយម៉ោង');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true), 'មួយម៉ោង', '89 minutes = មួយម៉ោង');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true), '2 ម៉ោង', '90 minutes = 2 ម៉ោង');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true), '5 ម៉ោង', '5 hours = 5 ម៉ោង');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true), '21 ម៉ោង', '21 hours = 21 ម៉ោង');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true), 'មួយថ្ងៃ', '22 hours = មួយថ្ងៃ');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true), 'មួយថ្ងៃ', '35 hours = មួយថ្ងៃ');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true), '2 ថ្ងៃ', '36 hours = 2 ថ្ងៃ');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true), 'មួយថ្ងៃ', '1 day = មួយថ្ងៃ');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true), '5 ថ្ងៃ', '5 days = 5 ថ្ងៃ');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true), '25 ថ្ងៃ', '25 days = 25 ថ្ងៃ');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true), 'មួយខែ', '26 days = មួយខែ');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true), 'មួយខែ', '30 days = មួយខែ');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true), 'មួយខែ', '43 days = មួយខែ');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true), '2 ខែ', '46 days = 2 ខែ');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true), '2 ខែ', '75 days = 2 ខែ');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true), '3 ខែ', '76 days = 3 ខែ');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true), 'មួយខែ', '1 month = មួយខែ');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true), '5 ខែ', '5 months = 5 ខែ');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'មួយឆ្នាំ', '345 days = មួយឆ្នាំ');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 ឆ្នាំ', '548 days = 2 ឆ្នាំ');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true), 'មួយឆ្នាំ', '1 year = មួយឆ្នាំ');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true), '5 ឆ្នាំ', '5 years = 5 ឆ្នាំ');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'ប៉ុន្មានវិនាទីទៀត', 'prefix');\n    assert.equal(moment(0).from(30000), 'ប៉ុន្មានវិនាទីមុន', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'ប៉ុន្មានវិនាទីមុន', 'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({\n        s: 30\n    }).fromNow(), 'ប៉ុន្មានវិនាទីទៀត', 'in a few seconds');\n    assert.equal(moment().add({\n        d: 5\n    }).fromNow(), '5 ថ្ងៃទៀត', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                  'ថ្ងៃនេះ ម៉ោង 12:00',  'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),     'ថ្ងៃនេះ ម៉ោង 12:25',  'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),      'ថ្ងៃនេះ ម៉ោង 13:00',  'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),      'ស្អែក ម៉ោង 12:00',    'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(), 'ថ្ងៃនេះ ម៉ោង 11:00',  'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(), 'ម្សិលមិញ ម៉ោង 12:00', 'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({\n            d: i\n        });\n        assert.equal(m.calendar(), m.format('dddd [ម៉ោង] LT'), 'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(), m.format('dddd [ម៉ោង] LT'), 'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(), m.format('dddd [ម៉ោង] LT'), 'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({\n            d: i\n        });\n        assert.equal(m.calendar(), m.format('dddd [សប្តាហ៍មុន] [ម៉ោង] LT'), 'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(), m.format('dddd [សប្តាហ៍មុន] [ម៉ោង] LT'), 'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(), m.format('dddd [សប្តាហ៍មុន] [ម៉ោង] LT'), 'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({\n            w: 1\n        }),\n        weeksFromNow = moment().add({\n            w: 1\n        });\n\n    assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '1 week ago');\n    assert.equal(weeksFromNow.calendar(), weeksFromNow.format('L'), 'in 1 week');\n\n    weeksAgo = moment().subtract({\n        w: 2\n    });\n    weeksFromNow = moment().add({\n        w: 2\n    });\n\n    assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(), weeksFromNow.format('L'), 'in 2 weeks');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2012, 0, 1]).format('w ww wo'), '52 52 52', 'Jan  1 2012 should be week 52');\n    assert.equal(moment([2012, 0, 2]).format('w ww wo'), '1 01 1', 'Jan  2 2012 should be week 1');\n    assert.equal(moment([2012, 0, 8]).format('w ww wo'), '1 01 1', 'Jan  8 2012 should be week 1');\n    assert.equal(moment([2012, 0, 9]).format('w ww wo'), '2 02 2', 'Jan  9 2012 should be week 2');\n    assert.equal(moment([2012, 0, 15]).format('w ww wo'), '2 02 2', 'Jan 15 2012 should be week 2');\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\n\n\nfunction localeModule (name, lifecycle) {\n    QUnit.module('locale:' + name, {\n        setup : function () {\n            moment.locale(name);\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            moment.locale('en');\n            teardownDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n    defineCommonLocaleTests(name, -1, -1);\n}\n\nlocaleModule('kn');\n\ntest('parse', function (assert) {\n    var tests = 'ಜನವರಿ ಜನ_ಫೆಬ್ರವರಿ ಫೆಬ್ರ_ಮಾರ್ಚ್ ಮಾರ್ಚ್_ಏಪ್ರಿಲ್ ಏಪ್ರಿಲ್_ಮೇ ಮೇ_ಜೂನ್ ಜೂನ್_ಜುಲೈ ಜುಲೈ_ಆಗಸ್ಟ್ ಆಗಸ್ಟ್_ಸೆಪ್ಟೆಂಬರ್ ಸೆಪ್ಟೆಂಬ_ಅಕ್ಟೋಬರ್ ಅಕ್ಟೋಬ_ನವೆಂಬರ್ ನವೆಂಬ_ಡಿಸೆಂಬರ್ ಡಿಸೆಂಬ'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, Do MMMM YYYY, a h:mm:ss',      'ಭಾನುವಾರ, ೧೪ನೇ ಫೆಬ್ರವರಿ ೨೦೧೦, ಮಧ್ಯಾಹ್ನ ೩:೨೫:೫೦'],\n            ['ddd, a h ಗಂಟೆ',                      'ಭಾನು, ಮಧ್ಯಾಹ್ನ ೩ ಗಂಟೆ'],\n            ['M Mo MM MMMM MMM',                   '೨ ೨ನೇ ೦೨ ಫೆಬ್ರವರಿ ಫೆಬ್ರ'],\n            ['YYYY YY',                            '೨೦೧೦ ೧೦'],\n            ['D Do DD',                            '೧೪ ೧೪ನೇ ೧೪'],\n            ['d do dddd ddd dd',                   '೦ ೦ನೇ ಭಾನುವಾರ ಭಾನು ಭಾ'],\n            ['DDD DDDo DDDD',                      '೪೫ ೪೫ನೇ ೦೪೫'],\n            ['w wo ww',                            '೮ ೮ನೇ ೦೮'],\n            ['h hh',                               '೩ ೦೩'],\n            ['H HH',                               '೧೫ ೧೫'],\n            ['m mm',                               '೨೫ ೨೫'],\n            ['s ss',                               '೫೦ ೫೦'],\n            ['a A',                                'ಮಧ್ಯಾಹ್ನ ಮಧ್ಯಾಹ್ನ'],\n            ['LTS',                                'ಮಧ್ಯಾಹ್ನ ೩:೨೫:೫೦'],\n            ['L',                                  '೧೪/೦೨/೨೦೧೦'],\n            ['LL',                                 '೧೪ ಫೆಬ್ರವರಿ ೨೦೧೦'],\n            ['LLL',                                '೧೪ ಫೆಬ್ರವರಿ ೨೦೧೦, ಮಧ್ಯಾಹ್ನ ೩:೨೫'],\n            ['LLLL',                               'ಭಾನುವಾರ, ೧೪ ಫೆಬ್ರವರಿ ೨೦೧೦, ಮಧ್ಯಾಹ್ನ ೩:೨೫'],\n            ['l',                                  '೧೪/೨/೨೦೧೦'],\n            ['ll',                                 '೧೪ ಫೆಬ್ರ ೨೦೧೦'],\n            ['lll',                                '೧೪ ಫೆಬ್ರ ೨೦೧೦, ಮಧ್ಯಾಹ್ನ ೩:೨೫'],\n            ['llll',                               'ಭಾನು, ೧೪ ಫೆಬ್ರ ೨೦೧೦, ಮಧ್ಯಾಹ್ನ ೩:೨೫']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '೧ನೇ', '೧ನೇ');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '೨ನೇ', '೨ನೇ');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '೩ನೇ', '೩ನೇ');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '೪ನೇ', '೪ನೇ');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '೫ನೇ', '೫ನೇ');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '೬ನೇ', '೬ನೇ');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '೭ನೇ', '೭ನೇ');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '೮ನೇ', '೮ನೇ');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '೯ನೇ', '೯ನೇ');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '೧೦ನೇ', '೧೦ನೇ');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '೧೧ನೇ', '೧೧ನೇ');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '೧೨ನೇ', '೧೨ನೇ');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '೧೩ನೇ', '೧೩ನೇ');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '೧೪ನೇ', '೧೪ನೇ');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '೧೫ನೇ', '೧೫ನೇ');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '೧೬ನೇ', '೧೬ನೇ');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '೧೭ನೇ', '೧೭ನೇ');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '೧೮ನೇ', '೧೮ನೇ');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '೧೯ನೇ', '೧೯ನೇ');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '೨೦ನೇ', '೨೦ನೇ');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '೨೧ನೇ', '೨೧ನೇ');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '೨೨ನೇ', '೨೨ನೇ');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '೨೩ನೇ', '೨೩ನೇ');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '೨೪ನೇ', '೨೪ನೇ');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '೨೫ನೇ', '೨೫ನೇ');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '೨೬ನೇ', '೨೬ನೇ');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '೨೭ನೇ', '೨೭ನೇ');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '೨೮ನೇ', '೨೮ನೇ');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '೨೯ನೇ', '೨೯ನೇ');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '೩೦ನೇ', '೩೦ನೇ');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '೩೧ನೇ', '೩೧ನೇ');\n});\n\ntest('format month', function (assert) {\n    var expected = 'ಜನವರಿ ಜನ_ಫೆಬ್ರವರಿ ಫೆಬ್ರ_ಮಾರ್ಚ್ ಮಾರ್ಚ್_ಏಪ್ರಿಲ್ ಏಪ್ರಿಲ್_ಮೇ ಮೇ_ಜೂನ್ ಜೂನ್_ಜುಲೈ ಜುಲೈ_ಆಗಸ್ಟ್ ಆಗಸ್ಟ್_ಸೆಪ್ಟೆಂಬರ್ ಸೆಪ್ಟೆಂಬ_ಅಕ್ಟೋಬರ್ ಅಕ್ಟೋಬ_ನವೆಂಬರ್ ನವೆಂಬ_ಡಿಸೆಂಬರ್ ಡಿಸೆಂಬ'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'ಭಾನುವಾರ ಭಾನು ಭಾ_ಸೋಮವಾರ ಸೋಮ ಸೋ_ಮಂಗಳವಾರ ಮಂಗಳ ಮಂ_ಬುಧವಾರ ಬುಧ ಬು_ಗುರುವಾರ ಗುರು ಗು_ಶುಕ್ರವಾರ ಶುಕ್ರ ಶು_ಶನಿವಾರ ಶನಿ ಶ'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'ಕೆಲವು ಕ್ಷಣಗಳು', '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'ಒಂದು ನಿಮಿಷ',      '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'ಒಂದು ನಿಮಿಷ',      '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '೨ ನಿಮಿಷ',     '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '೪೪ ನಿಮಿಷ',    '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'ಒಂದು ಗಂಟೆ',       '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'ಒಂದು ಗಂಟೆ',       '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '೨ ಗಂಟೆ',       '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '೫ ಗಂಟೆ',       '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '೨೧ ಗಂಟೆ',      '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'ಒಂದು ದಿನ',         '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'ಒಂದು ದಿನ',         '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '೨ ದಿನ',        '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'ಒಂದು ದಿನ',         '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '೫ ದಿನ',        '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '೨೫ ದಿನ',       '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'ಒಂದು ತಿಂಗಳು',       '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'ಒಂದು ತಿಂಗಳು',       '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'ಒಂದು ತಿಂಗಳು',       '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '೨ ತಿಂಗಳು',      '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '೨ ತಿಂಗಳು',      '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '೩ ತಿಂಗಳು',      '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'ಒಂದು ತಿಂಗಳು',       '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '೫ ತಿಂಗಳು',      '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'ಒಂದು ವರ್ಷ',        '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '೨ ವರ್ಷ',       '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'ಒಂದು ವರ್ಷ',        '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '೫ ವರ್ಷ',       '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'ಕೆಲವು ಕ್ಷಣಗಳು ನಂತರ',  'prefix');\n    assert.equal(moment(0).from(30000), 'ಕೆಲವು ಕ್ಷಣಗಳು ಹಿಂದೆ', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'ಕೆಲವು ಕ್ಷಣಗಳು ಹಿಂದೆ',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'ಕೆಲವು ಕ್ಷಣಗಳು ನಂತರ', 'ಕೆಲವು ಕ್ಷಣಗಳು ನಂತರ');\n    assert.equal(moment().add({d: 5}).fromNow(), '೫ ದಿನ ನಂತರ', '೫ ದಿನ ನಂತರ');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'ಇಂದು ಮಧ್ಯಾಹ್ನ ೧೨:೦೦',    'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'ಇಂದು ಮಧ್ಯಾಹ್ನ ೧೨:೨೫',    'Now plus 25 min');\n    assert.equal(moment(a).add({h: 3}).calendar(),       'ಇಂದು ಮಧ್ಯಾಹ್ನ ೩:೦೦',     'Now plus 3 hours');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'ನಾಳೆ ಮಧ್ಯಾಹ್ನ ೧೨:೦೦',    'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'ಇಂದು ಮಧ್ಯಾಹ್ನ ೧೧:೦೦',    'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'ನಿನ್ನೆ ಮಧ್ಯಾಹ್ನ ೧೨:೦೦',    'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('dddd[,] LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd[,] LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd[,] LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('[ಕೊನೆಯ] dddd[,] LT'),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[ಕೊನೆಯ] dddd[,] LT'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[ಕೊನೆಯ] dddd[,] LT'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('meridiem', function (assert) {\n    assert.equal(moment([2011, 2, 23,  2, 30]).format('a'), 'ರಾತ್ರಿ', 'before dawn');\n    assert.equal(moment([2011, 2, 23,  9, 30]).format('a'), 'ಬೆಳಿಗ್ಗೆ', 'morning');\n    assert.equal(moment([2011, 2, 23, 14, 30]).format('a'), 'ಮಧ್ಯಾಹ್ನ', 'during day');\n    assert.equal(moment([2011, 2, 23, 17, 30]).format('a'), 'ಸಂಜೆ', 'evening');\n    assert.equal(moment([2011, 2, 23, 19, 30]).format('a'), 'ಸಂಜೆ', 'late evening');\n    assert.equal(moment([2011, 2, 23, 21, 20]).format('a'), 'ರಾತ್ರಿ', 'night');\n\n    assert.equal(moment([2011, 2, 23,  2, 30]).format('A'), 'ರಾತ್ರಿ', 'before dawn');\n    assert.equal(moment([2011, 2, 23,  9, 30]).format('A'), 'ಬೆಳಿಗ್ಗೆ', 'morning');\n    assert.equal(moment([2011, 2, 23, 14, 30]).format('A'), 'ಮಧ್ಯಾಹ್ನ', ' during day');\n    assert.equal(moment([2011, 2, 23, 17, 30]).format('A'), 'ಸಂಜೆ', 'evening');\n    assert.equal(moment([2011, 2, 23, 19, 30]).format('A'), 'ಸಂಜೆ', 'late evening');\n    assert.equal(moment([2011, 2, 23, 21, 20]).format('A'), 'ರಾತ್ರಿ', 'night');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2012, 0,  1]).format('w ww wo'), '೧ ೦೧ ೧ನೇ', 'Jan  1 2012 should be week 1');\n    assert.equal(moment([2012, 0,  7]).format('w ww wo'), '೧ ೦೧ ೧ನೇ', 'Jan  7 2012 should be week 1');\n    assert.equal(moment([2012, 0,  8]).format('w ww wo'), '೨ ೦೨ ೨ನೇ', 'Jan  8 2012 should be week 2');\n    assert.equal(moment([2012, 0, 14]).format('w ww wo'), '೨ ೦೨ ೨ನೇ', 'Jan 14 2012 should be week 2');\n    assert.equal(moment([2012, 0, 15]).format('w ww wo'), '೩ ೦೩ ೩ನೇ', 'Jan 15 2012 should be week 3');\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\n\n\nfunction localeModule (name, lifecycle) {\n    QUnit.module('locale:' + name, {\n        setup : function () {\n            moment.locale(name);\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            moment.locale('en');\n            teardownDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n    defineCommonLocaleTests(name, -1, -1);\n}\n\nlocaleModule('ko');\n\ntest('parse', function (assert) {\n    var tests = '1월 1월_2월 2월_3월 3월_4월 4월_5월 5월_6월 6월_7월 7월_8월 8월_9월 9월_10월 10월_11월 11월_12월 12월'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('parse meridiem', function (assert) {\n    var elements = [{\n        expression : '1981년 9월 8일 오후 2시 30분',\n        inputFormat : 'YYYY[년] M[월] D[일] A h[시] m[분]',\n        outputFormat : 'A',\n        expected : '오후'\n    }, {\n        expression : '1981년 9월 8일 오전 2시 30분',\n        inputFormat : 'YYYY[년] M[월] D[일] A h[시] m[분]',\n        outputFormat : 'A h시',\n        expected : '오전 2시'\n    }, {\n        expression : '14시 30분',\n        inputFormat : 'H[시] m[분]',\n        outputFormat : 'A',\n        expected : '오후'\n    }, {\n        expression : '오후 4시',\n        inputFormat : 'A h[시]',\n        outputFormat : 'H',\n        expected : '16'\n    }], i, l, it, actual;\n\n    for (i = 0, l = elements.length; i < l; ++i) {\n        it = elements[i];\n        actual = moment(it.expression, it.inputFormat).format(it.outputFormat);\n\n        assert.equal(\n            actual,\n            it.expected,\n            '\\'' + it.outputFormat + '\\' of \\'' + it.expression + '\\' must be \\'' + it.expected + '\\' but was \\'' + actual + '\\'.'\n        );\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['YYYY년 MMMM Do dddd a h:mm:ss',      '2010년 2월 14일 일요일 오후 3:25:50'],\n            ['ddd A h',                            '일 오후 3'],\n            ['M Mo MM MMMM MMM',                   '2 2일 02 2월 2월'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14일 14'],\n            ['d do dddd ddd dd',                   '0 0일 일요일 일 일'],\n            ['DDD DDDo DDDD',                      '45 45일 045'],\n            ['w wo ww',                            '8 8일 08'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                '오후 오후'],\n            ['일년 중 DDDo째 되는 날',                 '일년 중 45일째 되는 날'],\n            ['LTS',                                '오후 3:25:50'],\n            ['L',                                  '2010.02.14'],\n            ['LL',                                 '2010년 2월 14일'],\n            ['LLL',                                '2010년 2월 14일 오후 3:25'],\n            ['LLLL',                               '2010년 2월 14일 일요일 오후 3:25'],\n            ['l',                                  '2010.02.14'],\n            ['ll',                                 '2010년 2월 14일'],\n            ['lll',                                '2010년 2월 14일 오후 3:25'],\n            ['llll',                               '2010년 2월 14일 일요일 오후 3:25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1일', '1일');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2일', '2일');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3일', '3일');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4일', '4일');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5일', '5일');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6일', '6일');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7일', '7일');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8일', '8일');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9일', '9일');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10일', '10일');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11일', '11일');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12일', '12일');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13일', '13일');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14일', '14일');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15일', '15일');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16일', '16일');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17일', '17일');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18일', '18일');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19일', '19일');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20일', '20일');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21일', '21일');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22일', '22일');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23일', '23일');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24일', '24일');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25일', '25일');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26일', '26일');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27일', '27일');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28일', '28일');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29일', '29일');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30일', '30일');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31일', '31일');\n});\n\ntest('format month', function (assert) {\n    var expected = '1월 1월_2월 2월_3월 3월_4월 4월_5월 5월_6월 6월_7월 7월_8월 8월_9월 9월_10월 10월_11월 11월_12월 12월'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = '일요일 일 일_월요일 월 월_화요일 화 화_수요일 수 수_목요일 목 목_금요일 금 금_토요일 토 토'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  '몇 초', '44초 = 몇 초');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  '1분',      '45초 = 1분');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  '1분',      '89초 = 1분');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2분',     '90초 = 2분');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44분',    '44분 = 44분');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  '한 시간',       '45분 = 한 시간');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  '한 시간',       '89분 = 한 시간');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2시간',       '90분 = 2시간');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5시간',       '5시간 = 5시간');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21시간',      '21시간 = 21시간');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  '하루',         '22시간 = 하루');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  '하루',         '35시간 = 하루');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2일',        '36시간 = 2일');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   '하루',         '하루 = 하루');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5일',        '5일 = 5일');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25일',       '25일 = 25일');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  '한 달',       '26일 = 한 달');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  '한 달',       '30일 = 한 달');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  '한 달',       '45일 = 한 달');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2달',      '46일 = 2달');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2달',      '75일 = 2달');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3달',      '76일 = 3달');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   '한 달',       '1달 = 한 달');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5달',      '5달 = 5달');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), '일 년',        '345일 = 일 년');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2년',       '548일 = 2년');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   '일 년',        '일 년 = 일 년');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5년',       '5년 = 5년');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), '몇 초 후',  'prefix');\n    assert.equal(moment(0).from(30000), '몇 초 전', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), '몇 초 전',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), '몇 초 후', 'in a few seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), '5일 후', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   '오늘 오후 12:00', 'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      '오늘 오후 12:25', 'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       '오늘 오후 1:00',  'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       '내일 오후 12:00', 'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  '오늘 오전 11:00', 'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  '어제 오후 12:00', 'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('dddd LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('지난주 dddd LT'),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('지난주 dddd LT'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('지난주 dddd LT'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('weeks year starting sunday format', function (assert) {\n    assert.equal(moment([2012, 0,  1]).format('w ww wo'), '1 01 1일', 'Jan  1 2012 should be week 1');\n    assert.equal(moment([2012, 0,  7]).format('w ww wo'), '1 01 1일', 'Jan  7 2012 should be week 1');\n    assert.equal(moment([2012, 0,  8]).format('w ww wo'), '2 02 2일', 'Jan  8 2012 should be week 2');\n    assert.equal(moment([2012, 0, 14]).format('w ww wo'), '2 02 2일', 'Jan 14 2012 should be week 2');\n    assert.equal(moment([2012, 0, 15]).format('w ww wo'), '3 03 3일', 'Jan 15 2012 should be week 3');\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\n\n\nfunction localeModule (name, lifecycle) {\n    QUnit.module('locale:' + name, {\n        setup : function () {\n            moment.locale(name);\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            moment.locale('en');\n            teardownDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n    defineCommonLocaleTests(name, -1, -1);\n}\n\nlocaleModule('ky');\n\ntest('parse', function (assert) {\n    var tests = 'январь янв_февраль фев_март март_апрель апр_май май_июнь июнь_июль июль_август авг_сентябрь сен_октябрь окт_ноябрь ноя_декабрь дек'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, Do MMMM YYYY, HH:mm:ss',       'Жекшемби, 14-чү февраль 2010, 15:25:50'],\n            ['ddd, hA',                            'Жек, 3PM'],\n            ['M Mo MM MMMM MMM',                   '2 2-чи 02 февраль фев'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14-чү 14'],\n            ['d do dddd ddd dd',                   '0 0-чү Жекшемби Жек Жк'],\n            ['DDD DDDo DDDD',                      '45 45-чи 045'],\n            ['w wo ww',                            '7 7-чи 07'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'pm PM'],\n            ['[жылдын] DDDo [күнү]',               'жылдын 45-чи күнү'],\n            ['LTS',                                '15:25:50'],\n            ['L',                                  '14.02.2010'],\n            ['LL',                                 '14 февраль 2010'],\n            ['LLL',                                '14 февраль 2010 15:25'],\n            ['LLLL',                               'Жекшемби, 14 февраль 2010 15:25'],\n            ['l',                                  '14.2.2010'],\n            ['ll',                                 '14 фев 2010'],\n            ['lll',                                '14 фев 2010 15:25'],\n            ['llll',                               'Жек, 14 фев 2010 15:25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1-чи', '1st');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2-чи', '2nd');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3-чү', '3rd');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4-чү', '4th');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5-чи', '5th');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6-чы', '6th');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7-чи', '7th');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8-чи', '8th');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9-чу', '9th');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10-чу', '10th');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11-чи', '11th');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12-чи', '12th');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13-чү', '13th');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14-чү', '14th');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15-чи', '15th');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16-чы', '16th');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17-чи', '17th');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18-чи', '18th');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19-чу', '19th');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20-чы', '20th');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21-чи', '21st');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22-чи', '22nd');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23-чү', '23rd');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24-чү', '24th');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25-чи', '25th');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26-чы', '26th');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27-чи', '27th');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28-чи', '28th');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29-чу', '29th');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30-чу', '30th');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31-чи', '31st');\n});\n\ntest('format month', function (assert) {\n    var expected = 'январь янв_февраль фев_март март_апрель апр_май май_июнь июнь_июль июль_август авг_сентябрь сен_октябрь окт_ноябрь ноя_декабрь дек'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'Жекшемби Жек Жк_Дүйшөмбү Дүй Дй_Шейшемби Шей Шй_Шаршемби Шар Шр_Бейшемби Бей Бй_Жума Жум Жм_Ишемби Ише Иш'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'бирнече секунд', '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'бир мүнөт',      '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'бир мүнөт',      '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 мүнөт',     '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 мүнөт',    '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'бир саат',       '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'бир саат',       '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 саат',       '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 саат',       '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 саат',      '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'бир күн',         '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'бир күн',         '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 күн',        '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'бир күн',         '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 күн',        '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 күн',       '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'бир ай',       '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'бир ай',       '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'бир ай',       '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 ай',      '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 ай',      '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 ай',      '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'бир ай',       '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 ай',      '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'бир жыл',        '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 жыл',       '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'бир жыл',        '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 жыл',       '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'бирнече секунд ичинде',  'prefix');\n    assert.equal(moment(0).from(30000), 'бирнече секунд мурун', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'бирнече секунд мурун',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'бирнече секунд ичинде', 'in a few seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), '5 күн ичинде', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'Бүгүн саат 12:00',  'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'Бүгүн саат 12:25',  'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'Бүгүн саат 13:00',  'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'Эртең саат 12:00',  'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'Бүгүн саат 11:00',  'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'Кече саат 12:00',   'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('dddd [саат] LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd [саат] LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd [саат] LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('[Өткен аптанын] dddd [күнү] [саат] LT'),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[Өткен аптанын] dddd [күнү] [саат] LT'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[Өткен аптанын] dddd [күнү] [саат] LT'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2012, 0,  1]).format('w ww wo'),   '1 01 1-чи', 'Jan  1 2012 should be week 1');\n    assert.equal(moment([2012, 0,  2]).format('w ww wo'),   '2 02 2-чи', 'Jan  2 2012 should be week 2');\n    assert.equal(moment([2012, 0,  8]).format('w ww wo'),   '2 02 2-чи', 'Jan  8 2012 should be week 2');\n    assert.equal(moment([2012, 0,  9]).format('w ww wo'),   '3 03 3-чү', 'Jan  9 2012 should be week 3');\n    assert.equal(moment([2012, 0, 15]).format('w ww wo'),   '3 03 3-чү', 'Jan 15 2012 should be week 3');\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\n\n\nfunction localeModule (name, lifecycle) {\n    QUnit.module('locale:' + name, {\n        setup : function () {\n            moment.locale(name);\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            moment.locale('en');\n            teardownDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n    defineCommonLocaleTests(name, -1, -1);\n}\n\nlocaleModule('lb');\n\ntest('parse', function (assert) {\n    var tests = 'Januar Jan._Februar Febr._Mäerz Mrz._Abrëll Abr._Mee Mee_Juni Jun._Juli Jul._August Aug._September Sept._Oktober Okt._November Nov._Dezember Dez.'.split('_'), i;\n\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, Do MMMM YYYY, HH:mm:ss', 'Sonndeg, 14. Februar 2010, 15:25:50'],\n            ['ddd, HH:mm', 'So., 15:25'],\n            ['M Mo MM MMMM MMM', '2 2. 02 Februar Febr.'],\n            ['YYYY YY', '2010 10'],\n            ['D Do DD', '14 14. 14'],\n            ['d do dddd ddd dd', '0 0. Sonndeg So. So'],\n            ['DDD DDDo DDDD', '45 45. 045'],\n            ['w wo ww', '6 6. 06'],\n            ['h hh', '3 03'],\n            ['H HH', '15 15'],\n            ['m mm', '25 25'],\n            ['s ss', '50 50'],\n            ['a A', 'pm PM'],\n            ['[the] DDDo [day of the year]', 'the 45. day of the year'],\n            ['LTS', '15:25:50 Auer'],\n            ['L', '14.02.2010'],\n            ['LL', '14. Februar 2010'],\n            ['LLL', '14. Februar 2010 15:25 Auer'],\n            ['LLLL', 'Sonndeg, 14. Februar 2010 15:25 Auer'],\n            ['l', '14.2.2010'],\n            ['ll', '14. Febr. 2010'],\n            ['lll', '14. Febr. 2010 15:25 Auer'],\n            ['llll', 'So., 14. Febr. 2010 15:25 Auer']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format month', function (assert) {\n    var expected = 'Januar Jan._Februar Febr._Mäerz Mrz._Abrëll Abr._Mee Mee_Juni Jun._Juli Jul._August Aug._September Sept._Oktober Okt._November Nov._Dezember Dez.'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'Sonndeg So. So_Méindeg Mé. Mé_Dënschdeg Dë. Dë_Mëttwoch Më. Më_Donneschdeg Do. Do_Freideg Fr. Fr_Samschdeg Sa. Sa'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true), 'e puer Sekonnen', '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true), 'eng Minutt', '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true), 'eng Minutt', '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true), '2 Minutten', '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true), '44 Minutten', '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true), 'eng Stonn', '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true), 'eng Stonn', '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true), '2 Stonnen', '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true), '5 Stonnen', '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true), '21 Stonnen', '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true), 'een Dag', '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true), 'een Dag', '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true), '2 Deeg', '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true), 'een Dag', '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true), '5 Deeg', '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true), '25 Deeg', '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true), 'ee Mount', '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true), 'ee Mount', '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true), 'ee Mount', '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true), '2 Méint', '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true), '2 Méint', '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true), '3 Méint', '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true), 'ee Mount', '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true), '5 Méint', '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'ee Joer', '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 Joer', '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true), 'ee Joer', '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true), '5 Joer', '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'an e puer Sekonnen', 'prefix');\n    assert.equal(moment(0).from(30000), 'virun e puer Sekonnen', 'suffix');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'an e puer Sekonnen', 'in a few seconds');\n    assert.equal(moment().add({d: 1}).fromNow(), 'an engem Dag', 'in one day');\n    assert.equal(moment().add({d: 2}).fromNow(), 'an 2 Deeg', 'in 2 days');\n    assert.equal(moment().add({d: 3}).fromNow(), 'an 3 Deeg', 'in 3 days');\n    assert.equal(moment().add({d: 4}).fromNow(), 'a 4 Deeg', 'in 4 days');\n    assert.equal(moment().add({d: 5}).fromNow(), 'a 5 Deeg', 'in 5 days');\n    assert.equal(moment().add({d: 6}).fromNow(), 'a 6 Deeg', 'in 6 days');\n    assert.equal(moment().add({d: 7}).fromNow(), 'a 7 Deeg', 'in 7 days');\n    assert.equal(moment().add({d: 8}).fromNow(), 'an 8 Deeg', 'in 8 days');\n    assert.equal(moment().add({d: 9}).fromNow(), 'an 9 Deeg', 'in 9 days');\n    assert.equal(moment().add({d: 10}).fromNow(), 'an 10 Deeg', 'in 10 days');\n    assert.equal(moment().add({y: 100}).fromNow(), 'an 100 Joer', 'in 100 years');\n    assert.equal(moment().add({y: 400}).fromNow(), 'a 400 Joer', 'in 400 years');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'Haut um 12:00 Auer',     'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'Haut um 12:25 Auer',     'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'Haut um 13:00 Auer',     'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'Muer um 12:00 Auer',     'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'Haut um 11:00 Auer',     'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'Gëschter um 12:00 Auer', 'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('dddd [um] LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd [um] LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd [um] LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m, weekday, datestring;\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n\n        // Different date string for 'Dënschdeg' (Tuesday) and 'Donneschdeg' (Thursday)\n        weekday = parseInt(m.format('d'), 10);\n        datestring = (weekday === 2 || weekday === 4 ? '[Leschten] dddd [um] LT' : '[Leschte] dddd [um] LT');\n\n        assert.equal(m.calendar(), m.format(datestring), 'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(), m.format(datestring), 'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(), m.format(datestring), 'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('weeks year starting sunday format', function (assert) {\n    assert.equal(moment([2012, 0,  1]).format('w ww wo'), '52 52 52.', 'Jan  1 2012 should be week 52');\n    assert.equal(moment([2012, 0,  7]).format('w ww wo'), '1 01 1.',   'Jan  7 2012 should be week 1');\n    assert.equal(moment([2012, 0,  8]).format('w ww wo'), '1 01 1.',   'Jan  8 2012 should be week 1');\n    assert.equal(moment([2012, 0, 14]).format('w ww wo'), '2 02 2.',   'Jan 14 2012 should be week 2');\n    assert.equal(moment([2012, 0, 15]).format('w ww wo'), '2 02 2.',   'Jan 15 2012 should be week 2');\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\n\n\nfunction localeModule (name, lifecycle) {\n    QUnit.module('locale:' + name, {\n        setup : function () {\n            moment.locale(name);\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            moment.locale('en');\n            teardownDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n    defineCommonLocaleTests(name, -1, -1);\n}\n\nlocaleModule('lo');\n\ntest('parse', function (assert) {\n    var tests = 'ມັງກອນ ມັງກອນ_ກຸມພາ ກຸມພາ_ມີນາ ມີນາ_ເມສາ ເມສາ_ພຶດສະພາ ພຶດສະພາ_ມິຖຸນາ ມິຖຸນາ_ກໍລະກົດ ກໍລະກົດ_ສິງຫາ ສິງຫາ_ກັນຍາ ກັນຍາ_ຕຸລາ ຕຸລາ_ພະຈິກ ພະຈິກ_ທັນວາ ທັນວາ'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, MMMM Do YYYY, h:mm:ss a',      'ອາທິດ, ກຸມພາ ທີ່14 2010, 3:25:50 ຕອນແລງ'],\n            ['ddd, hA',                            'ທິດ, 3ຕອນແລງ'],\n            ['M Mo MM MMMM MMM',                   '2 ທີ່2 02 ກຸມພາ ກຸມພາ'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 ທີ່14 14'],\n            ['d do dddd ddd dd',                   '0 ທີ່0 ອາທິດ ທິດ ທ'],\n            ['DDD DDDo DDDD',                      '45 ທີ່45 045'],\n            ['w wo ww',                            '8 ທີ່8 08'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'ຕອນແລງ ຕອນແລງ'],\n            ['[ວັນ]DDDo [ຂອງປີ]',                   'ວັນທີ່45 ຂອງປີ'],\n            ['LTS',                                '15:25:50'],\n            ['L',                                  '14/02/2010'],\n            ['LL',                                 '14 ກຸມພາ 2010'],\n            ['LLL',                                '14 ກຸມພາ 2010 15:25'],\n            ['LLLL',                               'ວັນອາທິດ 14 ກຸມພາ 2010 15:25'],\n            ['l',                                  '14/2/2010'],\n            ['ll',                                 '14 ກຸມພາ 2010'],\n            ['lll',                                '14 ກຸມພາ 2010 15:25'],\n            ['llll',                               'ວັນທິດ 14 ກຸມພາ 2010 15:25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), 'ທີ່1', 'ທີ່1');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), 'ທີ່2', 'ທີ່2');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), 'ທີ່3', 'ທີ່3');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), 'ທີ່4', 'ທີ່4');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), 'ທີ່5', 'ທີ່5');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), 'ທີ່6', 'ທີ່6');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), 'ທີ່7', 'ທີ່7');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), 'ທີ່8', 'ທີ່8');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), 'ທີ່9', 'ທີ່9');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), 'ທີ່10', 'ທີ່10');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), 'ທີ່11', 'ທີ່11');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), 'ທີ່12', 'ທີ່12');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), 'ທີ່13', 'ທີ່13');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), 'ທີ່14', 'ທີ່14');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), 'ທີ່15', 'ທີ່15');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), 'ທີ່16', 'ທີ່16');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), 'ທີ່17', 'ທີ່17');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), 'ທີ່18', 'ທີ່18');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), 'ທີ່19', 'ທີ່19');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), 'ທີ່20', 'ທີ່20');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), 'ທີ່21', 'ທີ່21');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), 'ທີ່22', 'ທີ່22');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), 'ທີ່23', 'ທີ່23');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), 'ທີ່24', 'ທີ່24');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), 'ທີ່25', 'ທີ່25');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), 'ທີ່26', 'ທີ່26');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), 'ທີ່27', 'ທີ່27');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), 'ທີ່28', 'ທີ່28');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), 'ທີ່29', 'ທີ່29');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), 'ທີ່30', 'ທີ່30');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), 'ທີ່31', 'ທີ່31');\n});\n\ntest('format month', function (assert) {\n    var expected = 'ມັງກອນ ມັງກອນ_ກຸມພາ ກຸມພາ_ມີນາ ມີນາ_ເມສາ ເມສາ_ພຶດສະພາ ພຶດສະພາ_ມິຖຸນາ ມິຖຸນາ_ກໍລະກົດ ກໍລະກົດ_ສິງຫາ ສິງຫາ_ກັນຍາ ກັນຍາ_ຕຸລາ ຕຸລາ_ພະຈິກ ພະຈິກ_ທັນວາ ທັນວາ'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'ອາທິດ ທິດ ທ_ຈັນ ຈັນ ຈ_ອັງຄານ ອັງຄານ ອຄ_ພຸດ ພຸດ ພ_ພະຫັດ ພະຫັດ ພຫ_ສຸກ ສຸກ ສກ_ເສົາ ເສົາ ສ'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'ບໍ່ເທົ່າໃດວິນາທີ', '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  '1 ນາທີ',      '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  '1 ນາທີ',      '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 ນາທີ',     '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 ນາທີ',    '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  '1 ຊົ່ວໂມງ',       '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  '1 ຊົ່ວໂມງ',       '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 ຊົ່ວໂມງ',       '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 ຊົ່ວໂມງ',       '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 ຊົ່ວໂມງ',      '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  '1 ມື້',         '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  '1 ມື້',         '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 ມື້',        '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   '1 ມື້',         '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 ມື້',        '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 ມື້',       '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  '1 ເດືອນ',       '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  '1 ເດືອນ',       '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  '1 ເດືອນ',       '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 ເດືອນ',      '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 ເດືອນ',      '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 ເດືອນ',      '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   '1 ເດືອນ',       '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 ເດືອນ',      '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), '1 ປີ',        '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 ປີ',       '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   '1 ປີ',        '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 ປີ',       '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'ອີກ ບໍ່ເທົ່າໃດວິນາທີ',  'prefix');\n    assert.equal(moment(0).from(30000), 'ບໍ່ເທົ່າໃດວິນາທີຜ່ານມາ', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'ບໍ່ເທົ່າໃດວິນາທີຜ່ານມາ',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'ອີກ ບໍ່ເທົ່າໃດວິນາທີ', 'in a few seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), 'ອີກ 5 ມື້', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'ມື້ນີ້ເວລາ 12:00',    'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'ມື້ນີ້ເວລາ 12:25',    'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'ມື້ນີ້ເວລາ 13:00',    'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'ມື້ອື່ນເວລາ 12:00',   'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'ມື້ນີ້ເວລາ 11:00',    'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'ມື້ວານນີ້ເວລາ 12:00',  'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('[ວັນ]dddd[ໜ້າເວລາ] LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[ວັນ]dddd[ໜ້າເວລາ] LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[ວັນ]dddd[ໜ້າເວລາ] LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('[ວັນ]dddd[ແລ້ວນີ້ເວລາ] LT'),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[ວັນ]dddd[ແລ້ວນີ້ເວລາ] LT'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[ວັນ]dddd[ແລ້ວນີ້ເວລາ] LT'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('weeks year starting sunday format', function (assert) {\n    assert.equal(moment([2012, 0,  1]).format('w ww wo'), '1 01 ທີ່1', 'Jan  1 2012 should be week 1');\n    assert.equal(moment([2012, 0,  7]).format('w ww wo'), '1 01 ທີ່1', 'Jan  7 2012 should be week 1');\n    assert.equal(moment([2012, 0,  8]).format('w ww wo'), '2 02 ທີ່2', 'Jan  8 2012 should be week 2');\n    assert.equal(moment([2012, 0, 14]).format('w ww wo'), '2 02 ທີ່2', 'Jan 14 2012 should be week 2');\n    assert.equal(moment([2012, 0, 15]).format('w ww wo'), '3 03 ທີ່3', 'Jan 15 2012 should be week 3');\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\n\n\nfunction localeModule (name, lifecycle) {\n    QUnit.module('locale:' + name, {\n        setup : function () {\n            moment.locale(name);\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            moment.locale('en');\n            teardownDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n    defineCommonLocaleTests(name, -1, -1);\n}\n\nlocaleModule('lt');\n\ntest('parse', function (assert) {\n    var tests = 'sausis sau_vasaris vas_kovas kov_balandis bal_gegužė geg_birželis bir_liepa lie_rugpjūtis rgp_rugsėjis rgs_spalis spa_lapkritis lap_gruodis grd'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, Do MMMM YYYY, h:mm:ss a',      'sekmadienis, 14-oji vasario 2010, 3:25:50 pm'],\n            ['ddd, hA',                            'Sek, 3PM'],\n            ['M Mo MM MMMM MMM',                   '2 2-oji 02 vasaris vas'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14-oji 14'],\n            ['d do dddd ddd dd',                   '0 0-oji sekmadienis Sek S'],\n            ['DDD DDDo DDDD',                      '45 45-oji 045'],\n            ['w wo ww',                            '6 6-oji 06'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'pm PM'],\n            ['DDDo [metų diena]',                  '45-oji metų diena'],\n            ['LTS',                                '15:25:50'],\n            ['L',                                  '2010-02-14'],\n            ['LL',                                 '2010 m. vasario 14 d.'],\n            ['LLL',                                '2010 m. vasario 14 d., 15:25 val.'],\n            ['LLLL',                               '2010 m. vasario 14 d., sekmadienis, 15:25 val.'],\n            ['l',                                  '2010-02-14'],\n            ['ll',                                 '2010 m. vasario 14 d.'],\n            ['lll',                                '2010 m. vasario 14 d., 15:25 val.'],\n            ['llll',                               '2010 m. vasario 14 d., Sek, 15:25 val.']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1-oji', '1-oji');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2-oji', '2-oji');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3-oji', '3-oji');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4-oji', '4-oji');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5-oji', '5-oji');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6-oji', '6-oji');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7-oji', '7-oji');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8-oji', '8-oji');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9-oji', '9-oji');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10-oji', '10-oji');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11-oji', '11-oji');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12-oji', '12-oji');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13-oji', '13-oji');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14-oji', '14-oji');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15-oji', '15-oji');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16-oji', '16-oji');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17-oji', '17-oji');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18-oji', '18-oji');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19-oji', '19-oji');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20-oji', '20-oji');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21-oji', '21-oji');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22-oji', '22-oji');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23-oji', '23-oji');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24-oji', '24-oji');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25-oji', '25-oji');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26-oji', '26-oji');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27-oji', '27-oji');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28-oji', '28-oji');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29-oji', '29-oji');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30-oji', '30-oji');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31-oji', '31-oji');\n});\n\ntest('format month', function (assert) {\n    var expected = 'sausis sau_vasaris vas_kovas kov_balandis bal_gegužė geg_birželis bir_liepa lie_rugpjūtis rgp_rugsėjis rgs_spalis spa_lapkritis lap_gruodis grd'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'sekmadienis Sek S_pirmadienis Pir P_antradienis Ant A_trečiadienis Tre T_ketvirtadienis Ket K_penktadienis Pen Pn_šeštadienis Šeš Š'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('format week on US calendar', function (assert) {\n    // Tests, whether the weekday names are correct, even if the week does not start on Monday\n    moment.updateLocale('lt', {week: {dow: 0, doy: 6}});\n    var expected = 'sekmadienis Sek S_pirmadienis Pir P_antradienis Ant A_trečiadienis Tre T_ketvirtadienis Ket K_penktadienis Pen Pn_šeštadienis Šeš Š'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n    moment.updateLocale('lt', null);\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'kelios sekundės', '44 seconds = seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'minutė',          '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'minutė',          '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 minutės',       '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 10}), true),  '10 minučių',       '10 minutes = 10 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 11}), true),  '11 minučių',       '11 minutes = 11 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 19}), true),  '19 minučių',       '19 minutes = 19 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 20}), true),  '20 minučių',       '20 minutes = 20 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 minutės',      '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'valanda',         '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'valanda',         '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 valandos',      '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 valandos',      '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 10}), true),  '10 valandų',      '10 hours = 10 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 valandos',     '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'diena',           '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'diena',           '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 dienos',        '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'diena',           '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 dienos',        '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 10}), true),  '10 dienų',        '10 days = 10 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 dienos',       '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'mėnuo',           '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'mėnuo',           '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'mėnuo',           '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 mėnesiai',      '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 mėnesiai',      '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 mėnesiai',      '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'mėnuo',           '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 mėnesiai',      '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 10}), true),  '10 mėnesių',      '10 months = 10 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'metai',           '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 metai',         '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'metai',           '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 metai',         '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'po kelių sekundžių',  'prefix');\n    assert.equal(moment(0).from(30000), 'prieš kelias sekundes', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'prieš kelias sekundes',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'po kelių sekundžių', 'in seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), 'po 5 dienų', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'Šiandien 12:00',  'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'Šiandien 12:25',  'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'Šiandien 13:00',  'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'Rytoj 12:00',     'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'Šiandien 11:00',  'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'Vakar 12:00',     'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('dddd LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('[Praėjusį] dddd LT'),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[Praėjusį] dddd LT'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[Praėjusį] dddd LT'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2012, 0,  1]).format('w ww wo'), '52 52 52-oji', 'Jan  1 2012 should be week 52');\n    assert.equal(moment([2012, 0,  2]).format('w ww wo'),  '1 01 1-oji', 'Jan  2 2012 should be week 1');\n    assert.equal(moment([2012, 0,  8]).format('w ww wo'),  '1 01 1-oji', 'Jan  8 2012 should be week 1');\n    assert.equal(moment([2012, 0,  9]).format('w ww wo'),  '2 02 2-oji', 'Jan  9 2012 should be week 2');\n    assert.equal(moment([2012, 0, 15]).format('w ww wo'),  '2 02 2-oji', 'Jan 15 2012 should be week 2');\n});\n\ntest('month cases', function (assert) {\n    assert.equal(moment([2015, 4, 1]).format('LL'), '2015 m. gegužės 1 d.', 'uses format instead of standalone form');\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\n\n\nfunction localeModule (name, lifecycle) {\n    QUnit.module('locale:' + name, {\n        setup : function () {\n            moment.locale(name);\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            moment.locale('en');\n            teardownDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n    defineCommonLocaleTests(name, -1, -1);\n}\n\nlocaleModule('lv');\n\ntest('parse', function (assert) {\n    var tests = 'janvāris jan_februāris feb_marts mar_aprīlis apr_maijs mai_jūnijs jūn_jūlijs jūl_augusts aug_septembris sep_oktobris okt_novembris nov_decembris dec'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, Do MMMM YYYY, h:mm:ss a',      'svētdiena, 14. februāris 2010, 3:25:50 pm'],\n            ['ddd, hA',                            'Sv, 3PM'],\n            ['M Mo MM MMMM MMM',                   '2 2. 02 februāris feb'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14. 14'],\n            ['d do dddd ddd dd',                   '0 0. svētdiena Sv Sv'],\n            ['DDD DDDo DDDD',                      '45 45. 045'],\n            ['w wo ww',                            '6 6. 06'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'pm PM'],\n            ['[the] DDDo [day of the year]',       'the 45. day of the year'],\n            ['LTS',                                '15:25:50'],\n            ['L',                                  '14.02.2010.'],\n            ['LL',                                 '2010. gada 14. februāris'],\n            ['LLL',                                '2010. gada 14. februāris, 15:25'],\n            ['LLLL',                               '2010. gada 14. februāris, svētdiena, 15:25'],\n            ['l',                                  '14.2.2010.'],\n            ['ll',                                 '2010. gada 14. feb'],\n            ['lll',                                '2010. gada 14. feb, 15:25'],\n            ['llll',                               '2010. gada 14. feb, Sv, 15:25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1.', '1.');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2.', '2.');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3.', '3.');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4.', '4.');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5.', '5.');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6.', '6.');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7.', '7.');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8.', '8.');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9.', '9.');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10.', '10.');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11.', '11.');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12.', '12.');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13.', '13.');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14.', '14.');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15.', '15.');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16.', '16.');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17.', '17.');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18.', '18.');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19.', '19.');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20.', '20.');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21.', '21.');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22.', '22.');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23.', '23.');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24.', '24.');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25.', '25.');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26.', '26.');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27.', '27.');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28.', '28.');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29.', '29.');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30.', '30.');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31.', '31.');\n});\n\ntest('format month', function (assert) {\n    var expected = 'janvāris jan_februāris feb_marts mar_aprīlis apr_maijs mai_jūnijs jūn_jūlijs jūl_augusts aug_septembris sep_oktobris okt_novembris nov_decembris dec'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'svētdiena Sv Sv_pirmdiena P P_otrdiena O O_trešdiena T T_ceturtdiena C C_piektdiena Pk Pk_sestdiena S S'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\n// Includes testing the cases of withoutSuffix = true and false.\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),   'dažas sekundes',       '44 seconds = seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), false),  'pirms dažām sekundēm', '44 seconds with suffix = seconds ago');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),   'minūte',               '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), false),  'pirms minūtes',        '45 seconds with suffix = a minute ago');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),   'minūte',               '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: -89}), false), 'pēc minūtes',          '89 seconds with suffix/prefix = in a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),   '2 minūtes',            '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), false),  'pirms 2 minūtēm',      '90 seconds with suffix = 2 minutes ago');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),   '44 minūtes',           '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), false),  'pirms 44 minūtēm',     '44 minutes with suffix = 44 minutes ago');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),   'stunda',               '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), false),  'pirms stundas',        '45 minutes with suffix = an hour ago');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),   'stunda',               '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),   '2 stundas',            '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: -90}), false), 'pēc 2 stundām',        '90 minutes with suffix = in 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),    '5 stundas',            '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), false),   'pirms 5 stundām',      '5 hours with suffix = 5 hours ago');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),   '21 stunda',            '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), false),  'pirms 21 stundas',     '21 hours with suffix = 21 hours ago');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),   'diena',                '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), false),  'pirms dienas',         '22 hours with suffix = a day ago');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),   'diena',                '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),   '2 dienas',             '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), false),  'pirms 2 dienām',       '36 hours with suffix = 2 days ago');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),    'diena',                '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),    '5 dienas',             '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), false),   'pirms 5 dienām',       '5 days with suffix = 5 days ago');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),   '25 dienas',            '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), false),  'pirms 25 dienām',      '25 days with suffix = 25 days ago');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),   'mēnesis',              '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), false),  'pirms mēneša',         '26 days with suffix = a month ago');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),   'mēnesis',              '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),   'mēnesis',              '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),   '2 mēneši',             '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), false),  'pirms 2 mēnešiem',     '46 days with suffix = 2 months ago');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),   '2 mēneši',             '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),   '3 mēneši',             '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), false),  'pirms 3 mēnešiem',     '76 days with suffix = 3 months ago');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),    'mēnesis',              '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),    '5 mēneši',             '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), false),   'pirms 5 mēnešiem',     '5 months with suffix = 5 months ago');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true),  'gads',                 '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), false), 'pirms gada',           '345 days with suffix = a year ago');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true),  '2 gadi',               '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), false), 'pirms 2 gadiem',       '548 days with suffix = 2 years ago');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),    'gads',                 '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),    '5 gadi',               '5 years = 5 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), false),   'pirms 5 gadiem',       '5 years with suffix = 5 years ago');\n\n    // test that numbers ending with 1 are singular except for when they end with 11 in which case they are plural\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 11}), true),   '11 gadi',              '11 years = 11 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 21}), true),   '21 gads',              '21 year = 21 year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 211}), true),  '211 gadi',             '211 years = 211 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 221}), false), 'pirms 221 gada',       '221 year with suffix = 221 years ago');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'pēc dažām sekundēm',  'prefix');\n    assert.equal(moment(0).from(30000), 'pirms dažām sekundēm', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'pirms dažām sekundēm',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'pēc dažām sekundēm', 'in seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), 'pēc 5 dienām', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'Šodien pulksten 12:00',  'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'Šodien pulksten 12:25',  'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'Šodien pulksten 13:00',  'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'Rīt pulksten 12:00',     'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'Šodien pulksten 11:00',  'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'Vakar pulksten 12:00',   'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('dddd [pulksten] LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd [pulksten] LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd [pulksten] LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('[Pagājušā] dddd [pulksten] LT'),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[Pagājušā] dddd [pulksten] LT'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[Pagājušā] dddd [pulksten] LT'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2012, 0,  1]).format('w ww wo'), '52 52 52.', 'Jan  1 2012 should be week 52');\n    assert.equal(moment([2012, 0,  2]).format('w ww wo'),  '1 01 1.', 'Jan  2 2012 should be week 1');\n    assert.equal(moment([2012, 0,  8]).format('w ww wo'),  '1 01 1.', 'Jan  8 2012 should be week 1');\n    assert.equal(moment([2012, 0,  9]).format('w ww wo'),  '2 02 2.', 'Jan  9 2012 should be week 2');\n    assert.equal(moment([2012, 0, 15]).format('w ww wo'),  '2 02 2.', 'Jan 15 2012 should be week 2');\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\n\n\nfunction localeModule (name, lifecycle) {\n    QUnit.module('locale:' + name, {\n        setup : function () {\n            moment.locale(name);\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            moment.locale('en');\n            teardownDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n    defineCommonLocaleTests(name, -1, -1);\n}\n\nlocaleModule('me');\n\ntest('parse', function (assert) {\n    var tests = 'januar jan._februar feb._mart mar._april apr._maj maj_jun jun_jul jul_avgust avg._septembar sep._oktobar okt._novembar nov._decembar dec.'.split('_'),\n        i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, Do MMMM YYYY, h:mm:ss a',      'nedjelja, 14. februar 2010, 3:25:50 pm'],\n            ['ddd, hA',                            'ned., 3PM'],\n            ['M Mo MM MMMM MMM',                   '2 2. 02 februar feb.'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14. 14'],\n            ['d do dddd ddd dd',                   '0 0. nedjelja ned. ne'],\n            ['DDD DDDo DDDD',                      '45 45. 045'],\n            ['w wo ww',                            '7 7. 07'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'pm PM'],\n            ['[the] DDDo [day of the year]',       'the 45. day of the year'],\n            ['LTS',                                '15:25:50'],\n            ['L',                                  '14.02.2010'],\n            ['LL',                                 '14. februar 2010'],\n            ['LLL',                                '14. februar 2010 15:25'],\n            ['LLLL',                               'nedjelja, 14. februar 2010 15:25'],\n            ['l',                                  '14.2.2010'],\n            ['ll',                                 '14. feb. 2010'],\n            ['lll',                                '14. feb. 2010 15:25'],\n            ['llll',                               'ned., 14. feb. 2010 15:25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1.', '1.');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2.', '2.');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3.', '3.');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4.', '4.');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5.', '5.');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6.', '6.');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7.', '7.');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8.', '8.');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9.', '9.');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10.', '10.');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11.', '11.');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12.', '12.');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13.', '13.');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14.', '14.');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15.', '15.');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16.', '16.');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17.', '17.');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18.', '18.');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19.', '19.');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20.', '20.');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21.', '21.');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22.', '22.');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23.', '23.');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24.', '24.');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25.', '25.');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26.', '26.');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27.', '27.');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28.', '28.');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29.', '29.');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30.', '30.');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31.', '31.');\n});\n\ntest('format month', function (assert) {\n    var expected = 'januar jan._februar feb._mart mar._april apr._maj maj_jun jun_jul jul_avgust avg._septembar sep._oktobar okt._novembar nov._decembar dec.'.split('_'),\n        i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'nedjelja ned. ne_ponedjeljak pon. po_utorak uto. ut_srijeda sri. sr_četvrtak čet. če_petak pet. pe_subota sub. su'.split('_'),\n        i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'nekoliko sekundi', '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'jedan minut',   '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'jedan minut',   '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 minuta',     '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 minuta',     '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'jedan sat',      '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'jedan sat',      '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 sata',        '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 sati',         '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 sati',        '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'dan',       '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'dan',       '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 dana',        '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'dan',       '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 dana',        '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 dana',       '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'mjesec',     '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'mjesec',     '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'mjesec',     '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 mjeseca',     '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 mjeseca',     '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 mjeseca',     '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'mjesec',     '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 mjeseci',    '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'godinu',     '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 godine',       '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'godinu',     '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 godina',        '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'za nekoliko sekundi',  'prefix');\n    assert.equal(moment(0).from(30000), 'prije nekoliko sekundi', 'prefix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'prije nekoliko sekundi',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'za nekoliko sekundi', 'in a few seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), 'za 5 dana', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'danas u 12:00',  'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'danas u 12:25',  'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'danas u 13:00',  'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'sjutra u 12:00', 'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'danas u 11:00',  'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'juče u 12:00',   'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n\n    function makeFormat(d) {\n        switch (d.day()) {\n            case 0:\n                return '[u] [nedjelju] [u] LT';\n            case 3:\n                return '[u] [srijedu] [u] LT';\n            case 6:\n                return '[u] [subotu] [u] LT';\n            case 1:\n            case 2:\n            case 4:\n            case 5:\n                return '[u] dddd [u] LT';\n        }\n    }\n\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format(makeFormat(m)),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format(makeFormat(m)),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format(makeFormat(m)),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n\n    function makeFormat(d) {\n        var lastWeekDay = [\n                '[prošle] [nedjelje] [u] LT',\n                '[prošlog] [ponedjeljka] [u] LT',\n                '[prošlog] [utorka] [u] LT',\n                '[prošle] [srijede] [u] LT',\n                '[prošlog] [četvrtka] [u] LT',\n                '[prošlog] [petka] [u] LT',\n                '[prošle] [subote] [u] LT'\n            ];\n\n        return lastWeekDay[d.day()];\n    }\n\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format(makeFormat(m)),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format(makeFormat(m)),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format(makeFormat(m)),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\n// Monday is the first day of the week.\n// The week that contains Jan 1st is the first week of the year.\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2011, 11, 26]).format('w ww wo'), '1 01 1.', 'Dec 26 2011 should be week 1');\n    assert.equal(moment([2012,  0,  1]).format('w ww wo'), '1 01 1.', 'Jan  1 2012 should be week 1');\n    assert.equal(moment([2012,  0,  2]).format('w ww wo'), '2 02 2.', 'Jan  2 2012 should be week 2');\n    assert.equal(moment([2012,  0,  8]).format('w ww wo'), '2 02 2.', 'Jan  8 2012 should be week 2');\n    assert.equal(moment([2012,  0,  9]).format('w ww wo'), '3 03 3.', 'Jan  9 2012 should be week 3');\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\n\n\nfunction localeModule (name, lifecycle) {\n    QUnit.module('locale:' + name, {\n        setup : function () {\n            moment.locale(name);\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            moment.locale('en');\n            teardownDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n    defineCommonLocaleTests(name, -1, -1);\n}\n\nlocaleModule('mi');\n\ntest('parse', function (assert) {\n    var tests = 'Kohi-tāte Kohi_Hui-tanguru Hui_Poutū-te-rangi Pou_Paenga-whāwhā Pae_Haratua Hara_Pipiri Pipi_Hōngoingoi Hōngoi_Here-turi-kōkā Here_Mahuru Mahu_Whiringa-ā-nuku Whi-nu_Whiringa-ā-rangi Whi-ra_Hakihea Haki'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, MMMM Do YYYY, h:mm:ss a',      'Rātapu, Hui-tanguru 14º 2010, 3:25:50 pm'],\n            ['ddd, hA',                            'Ta, 3PM'],\n            ['M Mo MM MMMM MMM',                   '2 2º 02 Hui-tanguru Hui'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14º 14'],\n            ['d do dddd ddd dd',                   '0 0º Rātapu Ta Ta'],\n            ['DDD DDDo DDDD',                      '45 45º 045'],\n            ['w wo ww',                            '6 6º 06'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'pm PM'],\n            ['[the] DDDo [day of the year]',       'the 45º day of the year'],\n            ['LTS',                                '15:25:50'],\n            ['L',                                  '14/02/2010'],\n            ['LL',                                 '14 Hui-tanguru 2010'],\n            ['LLL',                                '14 Hui-tanguru 2010 i 15:25'],\n            ['LLLL',                               'Rātapu, 14 Hui-tanguru 2010 i 15:25'],\n            ['l',                                  '14/2/2010'],\n            ['ll',                                 '14 Hui 2010'],\n            ['lll',                                '14 Hui 2010 i 15:25'],\n            ['llll',                               'Ta, 14 Hui 2010 i 15:25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1º', '1º');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2º', '2º');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3º', '3º');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4º', '4º');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5º', '5º');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6º', '6º');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7º', '7º');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8º', '8º');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9º', '9º');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10º', '10º');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11º', '11º');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12º', '12º');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13º', '13º');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14º', '14º');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15º', '15º');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16º', '16º');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17º', '17º');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18º', '18º');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19º', '19º');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20º', '20º');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21º', '21º');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22º', '22º');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23º', '23º');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24º', '24º');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25º', '25º');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26º', '26º');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27º', '27º');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28º', '28º');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29º', '29º');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30º', '30º');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31º', '31º');\n});\n\ntest('format month', function (assert) {\n    var expected = 'Kohi-tāte Kohi_Hui-tanguru Hui_Poutū-te-rangi Pou_Paenga-whāwhā Pae_Haratua Hara_Pipiri Pipi_Hōngoingoi Hōngoi_Here-turi-kōkā Here_Mahuru Mahu_Whiringa-ā-nuku Whi-nu_Whiringa-ā-rangi Whi-ra_Hakihea Haki'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'Rātapu Ta Ta_Mane Ma Ma_Tūrei Tū Tū_Wenerei We We_Tāite Tāi Tāi_Paraire Pa Pa_Hātarei Hā Hā'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'te hēkona ruarua', '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'he meneti',        '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'he meneti',        '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 meneti',         '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 meneti',        '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'te haora',         '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'te haora',         '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 haora',          '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 haora',          '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 haora',         '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'he ra',            '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'he ra',            '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 ra',             '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'he ra',            '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 ra',             '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 ra',            '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'he marama',        '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'he marama',        '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'he marama',        '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 marama',         '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 marama',         '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 marama',         '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'he marama',         '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 marama',         '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'he tau',           '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 tau',            '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'he tau',           '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 tau',            '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'i roto i te hēkona ruarua',  'prefix');\n    assert.equal(moment(0).from(30000), 'te hēkona ruarua i mua', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'te hēkona ruarua i mua',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'i roto i te hēkona ruarua', 'in a few seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), 'i roto i 5 ra', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'i teie mahana, i 12:00', 'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'i teie mahana, i 12:25', 'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'i teie mahana, i 13:00', 'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'apopo i 12:00',       'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'i teie mahana, i 11:00', 'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'inanahi i 12:00',     'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('dddd [i] LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd [i] LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd [i] LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('dddd [whakamutunga i] LT'), 'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd [whakamutunga i] LT'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd [whakamutunga i] LT'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2012, 0,  1]).format('w ww wo'), '52 52 52º', 'Jan  1 2012 should be week 52');\n    assert.equal(moment([2012, 0,  2]).format('w ww wo'),   '1 01 1º', 'Jan  2 2012 should be week 1');\n    assert.equal(moment([2012, 0,  8]).format('w ww wo'),   '1 01 1º', 'Jan  8 2012 should be week 1');\n    assert.equal(moment([2012, 0,  9]).format('w ww wo'),   '2 02 2º', 'Jan  9 2012 should be week 2');\n    assert.equal(moment([2012, 0, 15]).format('w ww wo'),   '2 02 2º', 'Jan 15 2012 should be week 2');\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\n\n\nfunction localeModule (name, lifecycle) {\n    QUnit.module('locale:' + name, {\n        setup : function () {\n            moment.locale(name);\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            moment.locale('en');\n            teardownDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n    defineCommonLocaleTests(name, -1, -1);\n}\n\nlocaleModule('mk');\n\ntest('parse', function (assert) {\n    var tests = 'јануари јан_февруари фев_март мар_април апр_мај мај_јуни јун_јули јул_август авг_септември сеп_октомври окт_ноември ное_декември дек'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, MMMM Do YYYY, H:mm:ss',        'недела, февруари 14-ти 2010, 15:25:50'],\n            ['ddd, hA',                            'нед, 3PM'],\n            ['M Mo MM MMMM MMM',                   '2 2-ри 02 февруари фев'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14-ти 14'],\n            ['d do dddd ddd dd',                   '0 0-ев недела нед нe'],\n            ['DDD DDDo DDDD',                      '45 45-ти 045'],\n            ['w wo ww',                            '7 7-ми 07'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'pm PM'],\n            ['[the] DDDo [day of the year]',       'the 45-ти day of the year'],\n            ['LTS',                                '15:25:50'],\n            ['L',                                  '14.02.2010'],\n            ['LL',                                 '14 февруари 2010'],\n            ['LLL',                                '14 февруари 2010 15:25'],\n            ['LLLL',                               'недела, 14 февруари 2010 15:25'],\n            ['l',                                  '14.2.2010'],\n            ['ll',                                 '14 фев 2010'],\n            ['lll',                                '14 фев 2010 15:25'],\n            ['llll',                               'нед, 14 фев 2010 15:25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1-ви', '1-ви');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2-ри', '2-ри');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3-ти', '3-ти');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4-ти', '4-ти');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5-ти', '5-ти');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6-ти', '6-ти');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7-ми', '7-ми');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8-ми', '8-ми');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9-ти', '9-ти');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10-ти', '10-ти');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11-ти', '11-ти');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12-ти', '12-ти');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13-ти', '13-ти');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14-ти', '14-ти');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15-ти', '15-ти');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16-ти', '16-ти');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17-ти', '17-ти');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18-ти', '18-ти');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19-ти', '19-ти');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20-ти', '20-ти');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21-ви', '21-ви');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22-ри', '22-ри');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23-ти', '23-ти');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24-ти', '24-ти');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25-ти', '25-ти');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26-ти', '26-ти');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27-ми', '27-ми');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28-ми', '28-ми');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29-ти', '29-ти');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30-ти', '30-ти');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31-ви', '31-ви');\n});\n\ntest('format month', function (assert) {\n    var expected = 'јануари јан_февруари фев_март мар_април апр_мај мај_јуни јун_јули јул_август авг_септември сеп_октомври окт_ноември ное_декември дек'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'недела нед нe_понеделник пон пo_вторник вто вт_среда сре ср_четврток чет че_петок пет пе_сабота саб сa'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'неколку секунди', '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'минута',          '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'минута',          '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 минути',        '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 минути',       '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'час',             '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'час',             '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 часа',          '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 часа',          '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 часа',         '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'ден',             '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'ден',             '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 дена',          '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'ден',             '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 дена',          '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 дена',         '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'месец',           '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'месец',           '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'месец',           '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 месеци',        '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 месеци',        '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 месеци',        '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'месец',           '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 месеци',        '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'година',          '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 години',        '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'година',          '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 години',        '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'после неколку секунди', 'prefix');\n    assert.equal(moment(0).from(30000), 'пред неколку секунди',  'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'пред неколку секунди',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'после неколку секунди', 'in a few seconds');\n    assert.equal(moment().add({d: 5}).fromNow(),  'после 5 дена', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'Денес во 12:00',  'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'Денес во 12:25',  'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'Денес во 13:00',  'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'Утре во 12:00',   'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'Денес во 11:00',  'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'Вчера во 12:00',  'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('[Во] dddd [во] LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[Во] dddd [во] LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[Во] dddd [во] LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n\n    function makeFormat(d) {\n        switch (d.day()) {\n            case 0:\n            case 3:\n            case 6:\n                return '[Изминатата] dddd [во] LT';\n            case 1:\n            case 2:\n            case 4:\n            case 5:\n                return '[Изминатиот] dddd [во] LT';\n        }\n    }\n\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format(makeFormat(m)),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format(makeFormat(m)),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format(makeFormat(m)),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2011, 11, 26]).format('w ww wo'), '1 01 1-ви', 'Dec 26 2011 should be week 1');\n    assert.equal(moment([2012,  0,  1]).format('w ww wo'), '1 01 1-ви', 'Jan  1 2012 should be week 1');\n    assert.equal(moment([2012,  0,  2]).format('w ww wo'), '2 02 2-ри', 'Jan  2 2012 should be week 2');\n    assert.equal(moment([2012,  0,  8]).format('w ww wo'), '2 02 2-ри', 'Jan  8 2012 should be week 2');\n    assert.equal(moment([2012,  0,  9]).format('w ww wo'), '3 03 3-ти', 'Jan  9 2012 should be week 3');\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\n\n\nfunction localeModule (name, lifecycle) {\n    QUnit.module('locale:' + name, {\n        setup : function () {\n            moment.locale(name);\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            moment.locale('en');\n            teardownDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n    defineCommonLocaleTests(name, -1, -1);\n}\n\nlocaleModule('ml');\n\ntest('parse', function (assert) {\n    var tests = 'ജനുവരി ജനു._ഫെബ്രുവരി ഫെബ്രു._മാർച്ച് മാർ._ഏപ്രിൽ ഏപ്രി._മേയ് മേയ്_ജൂൺ ജൂൺ_ജൂലൈ ജൂലൈ._ഓഗസ്റ്റ് ഓഗ._സെപ്റ്റംബർ സെപ്റ്റ._ഒക്ടോബർ ഒക്ടോ._നവംബർ നവം._ഡിസംബർ ഡിസം.'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, Do MMMM YYYY, a h:mm:ss -നു',  'ഞായറാഴ്ച, 14 ഫെബ്രുവരി 2010, ഉച്ച കഴിഞ്ഞ് 3:25:50 -നു'],\n            ['ddd, a h -നു',                       'ഞായർ, ഉച്ച കഴിഞ്ഞ് 3 -നു'],\n            ['M Mo MM MMMM MMM',                   '2 2 02 ഫെബ്രുവരി ഫെബ്രു.'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14 14'],\n            ['d do dddd ddd dd',                   '0 0 ഞായറാഴ്ച ഞായർ ഞാ'],\n            ['DDD DDDo DDDD',                      '45 45 045'],\n            ['w wo ww',                            '8 8 08'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'ഉച്ച കഴിഞ്ഞ് ഉച്ച കഴിഞ്ഞ്'],\n            ['LTS',                                'ഉച്ച കഴിഞ്ഞ് 3:25:50 -നു'],\n            ['L',                                  '14/02/2010'],\n            ['LL',                                 '14 ഫെബ്രുവരി 2010'],\n            ['LLL',                                '14 ഫെബ്രുവരി 2010, ഉച്ച കഴിഞ്ഞ് 3:25 -നു'],\n            ['LLLL',                               'ഞായറാഴ്ച, 14 ഫെബ്രുവരി 2010, ഉച്ച കഴിഞ്ഞ് 3:25 -നു'],\n            ['l',                                  '14/2/2010'],\n            ['ll',                                 '14 ഫെബ്രു. 2010'],\n            ['lll',                                '14 ഫെബ്രു. 2010, ഉച്ച കഴിഞ്ഞ് 3:25 -നു'],\n            ['llll',                               'ഞായർ, 14 ഫെബ്രു. 2010, ഉച്ച കഴിഞ്ഞ് 3:25 -നു']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1', '1');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2', '2');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3', '3');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4', '4');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5', '5');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6', '6');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7', '7');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8', '8');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9', '9');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10', '10');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11', '11');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12', '12');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13', '13');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14', '14');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15', '15');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16', '16');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17', '17');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18', '18');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19', '19');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20', '20');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21', '21');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22', '22');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23', '23');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24', '24');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25', '25');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26', '26');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27', '27');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28', '28');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29', '29');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30', '30');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31', '31');\n});\n\ntest('format month', function (assert) {\n    var expected = 'ജനുവരി ജനു._ഫെബ്രുവരി ഫെബ്രു._മാർച്ച് മാർ._ഏപ്രിൽ ഏപ്രി._മേയ് മേയ്_ജൂൺ ജൂൺ_ജൂലൈ ജൂലൈ._ഓഗസ്റ്റ് ഓഗ._സെപ്റ്റംബർ സെപ്റ്റ._ഒക്ടോബർ ഒക്ടോ._നവംബർ നവം._ഡിസംബർ ഡിസം.'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'ഞായറാഴ്ച ഞായർ ഞാ_തിങ്കളാഴ്ച തിങ്കൾ തി_ചൊവ്വാഴ്ച ചൊവ്വ ചൊ_ബുധനാഴ്ച ബുധൻ ബു_വ്യാഴാഴ്ച വ്യാഴം വ്യാ_വെള്ളിയാഴ്ച വെള്ളി വെ_ശനിയാഴ്ച ശനി ശ'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'അൽപ നിമിഷങ്ങൾ', '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'ഒരു മിനിറ്റ്',      '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'ഒരു മിനിറ്റ്',      '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 മിനിറ്റ്',     '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 മിനിറ്റ്',    '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'ഒരു മണിക്കൂർ',       '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'ഒരു മണിക്കൂർ',       '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 മണിക്കൂർ',       '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 മണിക്കൂർ',       '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 മണിക്കൂർ',      '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'ഒരു ദിവസം',         '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'ഒരു ദിവസം',         '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 ദിവസം',        '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'ഒരു ദിവസം',         '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 ദിവസം',        '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 ദിവസം',       '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'ഒരു മാസം',       '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'ഒരു മാസം',       '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'ഒരു മാസം',       '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 മാസം',      '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 മാസം',      '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 മാസം',      '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'ഒരു മാസം',       '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 മാസം',      '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'ഒരു വർഷം',        '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 വർഷം',       '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'ഒരു വർഷം',        '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 വർഷം',       '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'അൽപ നിമിഷങ്ങൾ കഴിഞ്ഞ്',  'prefix');\n    assert.equal(moment(0).from(30000), 'അൽപ നിമിഷങ്ങൾ മുൻപ്', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'അൽപ നിമിഷങ്ങൾ മുൻപ്',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'അൽപ നിമിഷങ്ങൾ കഴിഞ്ഞ്', 'അൽപ നിമിഷങ്ങൾ കഴിഞ്ഞ്');\n    assert.equal(moment().add({d: 5}).fromNow(), '5 ദിവസം കഴിഞ്ഞ്', '5 ദിവസം കഴിഞ്ഞ്');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'ഇന്ന് ഉച്ച കഴിഞ്ഞ് 12:00 -നു',   'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'ഇന്ന് ഉച്ച കഴിഞ്ഞ് 12:25 -നു',   'Now plus 25 min');\n    assert.equal(moment(a).add({h: 3}).calendar(),       'ഇന്ന് ഉച്ച കഴിഞ്ഞ് 3:00 -നു',    'Now plus 3 hours');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'നാളെ ഉച്ച കഴിഞ്ഞ് 12:00 -നു',    'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'ഇന്ന് രാവിലെ 11:00 -നു',         'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'ഇന്നലെ ഉച്ച കഴിഞ്ഞ് 12:00 -നു',  'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('dddd[,] LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd[,] LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd[,] LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('[കഴിഞ്ഞ] dddd[,] LT'),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[കഴിഞ്ഞ] dddd[,] LT'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[കഴിഞ്ഞ] dddd[,] LT'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('meridiem', function (assert) {\n    assert.equal(moment([2011, 2, 23,  2, 30]).format('a'), 'രാത്രി', 'before dawn');\n    assert.equal(moment([2011, 2, 23,  9, 30]).format('a'), 'രാവിലെ', 'morning');\n    assert.equal(moment([2011, 2, 23, 14, 30]).format('a'), 'ഉച്ച കഴിഞ്ഞ്', 'during day');\n    assert.equal(moment([2011, 2, 23, 17, 30]).format('a'), 'വൈകുന്നേരം', 'evening');\n    assert.equal(moment([2011, 2, 23, 19, 30]).format('a'), 'വൈകുന്നേരം', 'late evening');\n    assert.equal(moment([2011, 2, 23, 21, 20]).format('a'), 'രാത്രി', 'night');\n\n    assert.equal(moment([2011, 2, 23,  2, 30]).format('A'), 'രാത്രി', 'before dawn');\n    assert.equal(moment([2011, 2, 23,  9, 30]).format('A'), 'രാവിലെ', 'morning');\n    assert.equal(moment([2011, 2, 23, 14, 30]).format('A'), 'ഉച്ച കഴിഞ്ഞ്', ' during day');\n    assert.equal(moment([2011, 2, 23, 17, 30]).format('A'), 'വൈകുന്നേരം', 'evening');\n    assert.equal(moment([2011, 2, 23, 19, 30]).format('A'), 'വൈകുന്നേരം', 'late evening');\n    assert.equal(moment([2011, 2, 23, 21, 20]).format('A'), 'രാത്രി', 'night');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2012, 0,  1]).format('w ww wo'), '1 01 1', 'Jan  1 2012 should be week 1');\n    assert.equal(moment([2012, 0,  7]).format('w ww wo'), '1 01 1', 'Jan  7 2012 should be week 1');\n    assert.equal(moment([2012, 0,  8]).format('w ww wo'), '2 02 2', 'Jan  8 2012 should be week 2');\n    assert.equal(moment([2012, 0, 14]).format('w ww wo'), '2 02 2', 'Jan 14 2012 should be week 2');\n    assert.equal(moment([2012, 0, 15]).format('w ww wo'), '3 03 3', 'Jan 15 2012 should be week 3');\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\n\n\nfunction localeModule (name, lifecycle) {\n    QUnit.module('locale:' + name, {\n        setup : function () {\n            moment.locale(name);\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            moment.locale('en');\n            teardownDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n    defineCommonLocaleTests(name, -1, -1);\n}\n\nlocaleModule('mr');\n\ntest('parse', function (assert) {\n    var tests = 'जानेवारी जाने._फेब्रुवारी फेब्रु._मार्च मार्च._एप्रिल एप्रि._मे मे._जून जून._जुलै जुलै._ऑगस्ट ऑग._सप्टेंबर सप्टें._ऑक्टोबर ऑक्टो._नोव्हेंबर नोव्हें._डिसेंबर डिसें.'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, Do MMMM YYYY, a h:mm:ss वाजता', 'रविवार, १४ फेब्रुवारी २०१०, दुपारी ३:२५:५० वाजता'],\n            ['ddd, a h वाजता',                       'रवि, दुपारी ३ वाजता'],\n            ['M Mo MM MMMM MMM',                   '२ २ ०२ फेब्रुवारी फेब्रु.'],\n            ['YYYY YY',                            '२०१० १०'],\n            ['D Do DD',                            '१४ १४ १४'],\n            ['d do dddd ddd dd',                   '० ० रविवार रवि र'],\n            ['DDD DDDo DDDD',                      '४५ ४५ ०४५'],\n            ['w wo ww',                            '८ ८ ०८'],\n            ['h hh',                               '३ ०३'],\n            ['H HH',                               '१५ १५'],\n            ['m mm',                               '२५ २५'],\n            ['s ss',                               '५० ५०'],\n            ['a A',                                'दुपारी दुपारी'],\n            ['LTS',                                'दुपारी ३:२५:५० वाजता'],\n            ['L',                                  '१४/०२/२०१०'],\n            ['LL',                                 '१४ फेब्रुवारी २०१०'],\n            ['LLL',                                '१४ फेब्रुवारी २०१०, दुपारी ३:२५ वाजता'],\n            ['LLLL',                               'रविवार, १४ फेब्रुवारी २०१०, दुपारी ३:२५ वाजता'],\n            ['l',                                  '१४/२/२०१०'],\n            ['ll',                                 '१४ फेब्रु. २०१०'],\n            ['lll',                                '१४ फेब्रु. २०१०, दुपारी ३:२५ वाजता'],\n            ['llll',                               'रवि, १४ फेब्रु. २०१०, दुपारी ३:२५ वाजता']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '१', '१');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '२', '२');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '३', '३');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '४', '४');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '५', '५');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '६', '६');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '७', '७');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '८', '८');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '९', '९');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '१०', '१०');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '११', '११');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '१२', '१२');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '१३', '१३');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '१४', '१४');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '१५', '१५');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '१६', '१६');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '१७', '१७');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '१८', '१८');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '१९', '१९');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '२०', '२०');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '२१', '२१');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '२२', '२२');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '२३', '२३');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '२४', '२४');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '२५', '२५');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '२६', '२६');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '२७', '२७');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '२८', '२८');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '२९', '२९');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '३०', '३०');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '३१', '३१');\n});\n\ntest('format month', function (assert) {\n    var expected = 'जानेवारी जाने._फेब्रुवारी फेब्रु._मार्च मार्च._एप्रिल एप्रि._मे मे._जून जून._जुलै जुलै._ऑगस्ट ऑग._सप्टेंबर सप्टें._ऑक्टोबर ऑक्टो._नोव्हेंबर नोव्हें._डिसेंबर डिसें.'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'रविवार रवि र_सोमवार सोम सो_मंगळवार मंगळ मं_बुधवार बुध बु_गुरूवार गुरू गु_शुक्रवार शुक्र शु_शनिवार शनि श'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'काही सेकंद', '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'एक मिनिट',      '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'एक मिनिट',      '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '२ मिनिटे',     '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true), '४४ मिनिटे', '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'एक तास',       '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'एक तास',       '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '२ तास',       '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '५ तास',       '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '२१ तास',      '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'एक दिवस',         '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'एक दिवस',         '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '२ दिवस',        '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'एक दिवस',         '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '५ दिवस',        '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '२५ दिवस',       '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true), 'एक महिना', '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true), 'एक महिना', '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true), 'एक महिना', '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true), '२ महिने', '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true), '२ महिने', '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true), '३ महिने', '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true), 'एक महिना', '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true), '५ महिने', '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'एक वर्ष',        '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '२ वर्षे',       '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'एक वर्ष',        '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true), '५ वर्षे', '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'काही सेकंदांमध्ये', 'prefix');\n    assert.equal(moment(0).from(30000), 'काही सेकंदांपूर्वी', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'काही सेकंदांपूर्वी',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'काही सेकंदांमध्ये', 'in a few seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), '५ दिवसांमध्ये', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'आज दुपारी १२:०० वाजता',    'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'आज दुपारी १२:२५ वाजता',    'Now plus 25 min');\n    assert.equal(moment(a).add({h: 3}).calendar(),       'आज दुपारी ३:०० वाजता',     'Now plus 3 hours');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'उद्या दुपारी १२:०० वाजता', 'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'आज दुपारी ११:०० वाजता',    'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'काल दुपारी १२:०० वाजता',   'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('dddd[,] LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd[,] LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd[,] LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(), m.format('[मागील] dddd[,] LT'), 'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(), m.format('[मागील] dddd[,] LT'), 'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(), m.format('[मागील] dddd[,] LT'), 'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('meridiem', function (assert) {\n    assert.equal(moment([2011, 2, 23,  2, 30]).format('a'), 'रात्री', 'before dawn');\n    assert.equal(moment([2011, 2, 23,  9, 30]).format('a'), 'सकाळी', 'morning');\n    assert.equal(moment([2011, 2, 23, 14, 30]).format('a'), 'दुपारी', 'during day');\n    assert.equal(moment([2011, 2, 23, 17, 30]).format('a'), 'सायंकाळी', 'evening');\n    assert.equal(moment([2011, 2, 23, 19, 30]).format('a'), 'सायंकाळी', 'late evening');\n    assert.equal(moment([2011, 2, 23, 21, 20]).format('a'), 'रात्री', 'night');\n\n    assert.equal(moment([2011, 2, 23,  2, 30]).format('A'), 'रात्री', 'before dawn');\n    assert.equal(moment([2011, 2, 23,  9, 30]).format('A'), 'सकाळी', 'morning');\n    assert.equal(moment([2011, 2, 23, 14, 30]).format('A'), 'दुपारी', ' during day');\n    assert.equal(moment([2011, 2, 23, 17, 30]).format('A'), 'सायंकाळी', 'evening');\n    assert.equal(moment([2011, 2, 23, 19, 30]).format('A'), 'सायंकाळी', 'late evening');\n    assert.equal(moment([2011, 2, 23, 21, 20]).format('A'), 'रात्री', 'night');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2012, 0,  1]).format('w ww wo'), '१ ०१ १', 'Jan  1 2012 should be week 1');\n    assert.equal(moment([2012, 0,  7]).format('w ww wo'), '१ ०१ १', 'Jan  7 2012 should be week 1');\n    assert.equal(moment([2012, 0,  8]).format('w ww wo'), '२ ०२ २', 'Jan  8 2012 should be week 2');\n    assert.equal(moment([2012, 0, 14]).format('w ww wo'), '२ ०२ २', 'Jan 14 2012 should be week 2');\n    assert.equal(moment([2012, 0, 15]).format('w ww wo'), '३ ०३ ३', 'Jan 15 2012 should be week 3');\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\n\n\nfunction localeModule (name, lifecycle) {\n    QUnit.module('locale:' + name, {\n        setup : function () {\n            moment.locale(name);\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            moment.locale('en');\n            teardownDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n    defineCommonLocaleTests(name, -1, -1);\n}\n\nlocaleModule('ms-my');\n\ntest('parse', function (assert) {\n    var i,\n        tests = 'Januari Jan_Februari Feb_Mac Mac_April Apr_Mei Mei_Jun Jun_Julai Jul_Ogos Ogs_September Sep_Oktober Okt_November Nov_Disember Dis'.split('_');\n\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' sepatutnya bulan ' + (i + 1));\n    }\n\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, MMMM Do YYYY, h:mm:ss a',      'Ahad, Februari 14 2010, 3:25:50 petang'],\n            ['ddd, hA',                            'Ahd, 3petang'],\n            ['M Mo MM MMMM MMM',                   '2 2 02 Februari Feb'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14 14'],\n            ['d do dddd ddd dd',                   '0 0 Ahad Ahd Ah'],\n            ['DDD DDDo DDDD',                      '45 45 045'],\n            ['w wo ww',                            '7 7 07'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'petang petang'],\n            ['[hari] [ke] DDDo [tahun] ini', 'hari ke 45 tahun ini'],\n            ['LTS',                                '15.25.50'],\n            ['L',                                  '14/02/2010'],\n            ['LL',                                 '14 Februari 2010'],\n            ['LLL',                                '14 Februari 2010 pukul 15.25'],\n            ['LLLL',                               'Ahad, 14 Februari 2010 pukul 15.25'],\n            ['l',                                  '14/2/2010'],\n            ['ll',                                 '14 Feb 2010'],\n            ['lll',                                '14 Feb 2010 pukul 15.25'],\n            ['llll',                               'Ahd, 14 Feb 2010 pukul 15.25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1', '1');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2', '2');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3', '3');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4', '4');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5', '5');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6', '6');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7', '7');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8', '8');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9', '9');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10', '10');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11', '11');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12', '12');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13', '13');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14', '14');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15', '15');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16', '16');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17', '17');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18', '18');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19', '19');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20', '20');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21', '21');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22', '22');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23', '23');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24', '24');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25', '25');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26', '26');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27', '27');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28', '28');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29', '29');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30', '30');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31', '31');\n});\n\ntest('format month', function (assert) {\n    var i,\n        expected = 'Januari Jan_Februari Feb_Mac Mac_April Apr_Mei Mei_Jun Jun_Julai Jul_Ogos Ogs_September Sep_Oktober Okt_November Nov_Disember Dis'.split('_');\n\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var i,\n        expected = 'Ahad Ahd Ah_Isnin Isn Is_Selasa Sel Sl_Rabu Rab Rb_Khamis Kha Km_Jumaat Jum Jm_Sabtu Sab Sb'.split('_');\n\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'beberapa saat', '44 saat = beberapa saat');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'seminit',      '45 saat = seminit');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'seminit',      '89 saat = seminit');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 minit',     '90 saat = 2 minit');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 minit',    '44 minit = 44 minit');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'sejam',       '45 minit = sejam');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'sejam',       '89 minit = sejam');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 jam',       '90 minit = 2 jam');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 jam',       '5 jam = 5 jam');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 jam',      '21 jam = 21 jam');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'sehari',         '22 jam = sehari');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'sehari',         '35 jam = sehari');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 hari',        '36 jam = 2 hari');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'sehari',         '1 hari = sehari');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 hari',        '5 hari = 5 hari');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 hari',       '25 hari = 25 hari');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'sebulan',       '26 hari = sebulan');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'sebulan',       '30 hari = sebulan');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'sebulan',       '45 hari = sebulan');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 bulan',      '46 hari = 2 bulan');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 bulan',      '75 hari = 2 bulan');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 bulan',      '76 hari = 3 bulan');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'sebulan',       '1 bulan = sebulan');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 bulan',      '5 bulan = 5 bulan');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'setahun',        '345 hari = setahun');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 tahun',       '548 hari = 2 tahun');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'setahun',        '1 tahun = setahun');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 tahun',       '5 tahun = 5 tahun');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'dalam beberapa saat',  'prefix');\n    assert.equal(moment(0).from(30000), 'beberapa saat yang lepas', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'beberapa saat yang lepas',  'waktu sekarang dari sekarang sepatutnya menunjukkan sebagai telah lepas');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'dalam beberapa saat', 'dalam beberapa saat');\n    assert.equal(moment().add({d: 5}).fromNow(), 'dalam 5 hari', 'dalam 5 hari');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'Hari ini pukul 12.00',  'hari ini pada waktu yang sama');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'Hari ini pukul 12.25',  'Sekarang tambah 25 minit');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'Hari ini pukul 13.00',  'Sekarang tambah 1 jam');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'Esok pukul 12.00',      'esok pada waktu yang sama');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'Hari ini pukul 11.00',  'Sekarang tolak 1 jam');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'Kelmarin pukul 12.00',  'kelmarin pada waktu yang sama');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('dddd [pukul] LT'),  'Hari ini + ' + i + ' hari waktu sekarang');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd [pukul] LT'),  'Hari ini + ' + i + ' hari permulaan hari');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd [pukul] LT'),  'Hari ini + ' + i + ' hari tamat hari');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('dddd [lepas] [pukul] LT'),  'Hari ini - ' + i + ' hari waktu sekarang');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd [lepas] [pukul] LT'),  'Hari ini - ' + i + ' hari permulaan hari');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd [lepas] [pukul] LT'),  'Hari ini - ' + i + ' hari tamat hari');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 minggu lepas');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'dalam 1 minggu');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 minggu lepas');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'dalam 2 minggu');\n});\n\ntest('weeks year starting sunday format', function (assert) {\n    assert.equal(moment([2012, 0,  1]).format('w ww wo'), '1 01 1', 'Jan  1 2012 sepatutnya minggu 1');\n    assert.equal(moment([2012, 0,  7]).format('w ww wo'), '2 02 2', 'Jan  7 2012 sepatutnya minggu 2');\n    assert.equal(moment([2012, 0,  8]).format('w ww wo'), '2 02 2', 'Jan  8 2012 sepatutnya minggu 2');\n    assert.equal(moment([2012, 0, 14]).format('w ww wo'), '3 03 3', 'Jan 14 2012 sepatutnya minggu 3');\n    assert.equal(moment([2012, 0, 15]).format('w ww wo'), '3 03 3', 'Jan 15 2012 sepatutnya minggu 3');\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\n\n\nfunction localeModule (name, lifecycle) {\n    QUnit.module('locale:' + name, {\n        setup : function () {\n            moment.locale(name);\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            moment.locale('en');\n            teardownDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n    defineCommonLocaleTests(name, -1, -1);\n}\n\nlocaleModule('ms');\n\ntest('parse', function (assert) {\n    var i,\n        tests = 'Januari Jan_Februari Feb_Mac Mac_April Apr_Mei Mei_Jun Jun_Julai Jul_Ogos Ogs_September Sep_Oktober Okt_November Nov_Disember Dis'.split('_');\n\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' sepatutnya bulan ' + (i + 1));\n    }\n\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, MMMM Do YYYY, h:mm:ss a',      'Ahad, Februari 14 2010, 3:25:50 petang'],\n            ['ddd, hA',                            'Ahd, 3petang'],\n            ['M Mo MM MMMM MMM',                   '2 2 02 Februari Feb'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14 14'],\n            ['d do dddd ddd dd',                   '0 0 Ahad Ahd Ah'],\n            ['DDD DDDo DDDD',                      '45 45 045'],\n            ['w wo ww',                            '7 7 07'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'petang petang'],\n            ['[hari] [ke] DDDo [tahun] ini', 'hari ke 45 tahun ini'],\n            ['LTS',                                '15.25.50'],\n            ['L',                                  '14/02/2010'],\n            ['LL',                                 '14 Februari 2010'],\n            ['LLL',                                '14 Februari 2010 pukul 15.25'],\n            ['LLLL',                               'Ahad, 14 Februari 2010 pukul 15.25'],\n            ['l',                                  '14/2/2010'],\n            ['ll',                                 '14 Feb 2010'],\n            ['lll',                                '14 Feb 2010 pukul 15.25'],\n            ['llll',                               'Ahd, 14 Feb 2010 pukul 15.25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1', '1');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2', '2');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3', '3');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4', '4');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5', '5');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6', '6');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7', '7');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8', '8');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9', '9');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10', '10');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11', '11');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12', '12');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13', '13');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14', '14');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15', '15');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16', '16');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17', '17');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18', '18');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19', '19');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20', '20');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21', '21');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22', '22');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23', '23');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24', '24');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25', '25');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26', '26');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27', '27');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28', '28');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29', '29');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30', '30');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31', '31');\n});\n\ntest('format month', function (assert) {\n    var i,\n        expected = 'Januari Jan_Februari Feb_Mac Mac_April Apr_Mei Mei_Jun Jun_Julai Jul_Ogos Ogs_September Sep_Oktober Okt_November Nov_Disember Dis'.split('_');\n\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var i,\n        expected = 'Ahad Ahd Ah_Isnin Isn Is_Selasa Sel Sl_Rabu Rab Rb_Khamis Kha Km_Jumaat Jum Jm_Sabtu Sab Sb'.split('_');\n\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'beberapa saat', '44 saat = beberapa saat');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'seminit',      '45 saat = seminit');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'seminit',      '89 saat = seminit');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 minit',     '90 saat = 2 minit');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 minit',    '44 minit = 44 minit');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'sejam',       '45 minit = sejam');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'sejam',       '89 minit = sejam');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 jam',       '90 minit = 2 jam');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 jam',       '5 jam = 5 jam');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 jam',      '21 jam = 21 jam');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'sehari',         '22 jam = sehari');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'sehari',         '35 jam = sehari');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 hari',        '36 jam = 2 hari');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'sehari',         '1 hari = sehari');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 hari',        '5 hari = 5 hari');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 hari',       '25 hari = 25 hari');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'sebulan',       '26 hari = sebulan');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'sebulan',       '30 hari = sebulan');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'sebulan',       '45 hari = sebulan');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 bulan',      '46 hari = 2 bulan');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 bulan',      '75 hari = 2 bulan');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 bulan',      '76 hari = 3 bulan');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'sebulan',       '1 bulan = sebulan');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 bulan',      '5 bulan = 5 bulan');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'setahun',        '345 hari = setahun');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 tahun',       '548 hari = 2 tahun');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'setahun',        '1 tahun = setahun');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 tahun',       '5 tahun = 5 tahun');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'dalam beberapa saat',  'prefix');\n    assert.equal(moment(0).from(30000), 'beberapa saat yang lepas', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'beberapa saat yang lepas',  'waktu sekarang dari sekarang sepatutnya menunjukkan sebagai telah lepas');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'dalam beberapa saat', 'dalam beberapa saat');\n    assert.equal(moment().add({d: 5}).fromNow(), 'dalam 5 hari', 'dalam 5 hari');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'Hari ini pukul 12.00',  'hari ini pada waktu yang sama');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'Hari ini pukul 12.25',  'Sekarang tambah 25 minit');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'Hari ini pukul 13.00',  'Sekarang tambah 1 jam');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'Esok pukul 12.00',      'esok pada waktu yang sama');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'Hari ini pukul 11.00',  'Sekarang tolak 1 jam');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'Kelmarin pukul 12.00',  'kelmarin pada waktu yang sama');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('dddd [pukul] LT'),  'Hari ini + ' + i + ' hari waktu sekarang');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd [pukul] LT'),  'Hari ini + ' + i + ' hari permulaan hari');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd [pukul] LT'),  'Hari ini + ' + i + ' hari tamat hari');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('dddd [lepas] [pukul] LT'),  'Hari ini - ' + i + ' hari waktu sekarang');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd [lepas] [pukul] LT'),  'Hari ini - ' + i + ' hari permulaan hari');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd [lepas] [pukul] LT'),  'Hari ini - ' + i + ' hari tamat hari');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 minggu lepas');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'dalam 1 minggu');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 minggu lepas');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'dalam 2 minggu');\n});\n\ntest('weeks year starting sunday format', function (assert) {\n    assert.equal(moment([2012, 0,  1]).format('w ww wo'), '1 01 1', 'Jan  1 2012 sepatutnya minggu 1');\n    assert.equal(moment([2012, 0,  7]).format('w ww wo'), '2 02 2', 'Jan  7 2012 sepatutnya minggu 2');\n    assert.equal(moment([2012, 0,  8]).format('w ww wo'), '2 02 2', 'Jan  8 2012 sepatutnya minggu 2');\n    assert.equal(moment([2012, 0, 14]).format('w ww wo'), '3 03 3', 'Jan 14 2012 sepatutnya minggu 3');\n    assert.equal(moment([2012, 0, 15]).format('w ww wo'), '3 03 3', 'Jan 15 2012 sepatutnya minggu 3');\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\n\n\nfunction localeModule (name, lifecycle) {\n    QUnit.module('locale:' + name, {\n        setup : function () {\n            moment.locale(name);\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            moment.locale('en');\n            teardownDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n    defineCommonLocaleTests(name, -1, -1);\n}\n\nlocaleModule('my');\n\ntest('parse', function (assert) {\n    var tests = 'ဇန်နဝါရီ ဇန်_ဖေဖော်ဝါရီ ဖေ_မတ် မတ်_ဧပြီ ပြီ_မေ မေ_ဇွန် ဇွန်_ဇူလိုင် လိုင်_သြဂုတ် သြ_စက်တင်ဘာ စက်_အောက်တိုဘာ အောက်_နိုဝင်ဘာ နို_ဒီဇင်ဘာ ဒီ'.split('_'),\n        i;\n\n    function equalTest (input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, MMMM Do YYYY, h:mm:ss a', 'တနင်္ဂနွေ, ဖေဖော်ဝါရီ ၁၄ ၂၀၁၀, ၃:၂၅:၅၀ pm'],\n            ['ddd, hA', 'နွေ, ၃PM'],\n            ['M Mo MM MMMM MMM', '၂ ၂ ၀၂ ဖေဖော်ဝါရီ ဖေ'],\n            ['YYYY YY', '၂၀၁၀ ၁၀'],\n            ['D Do DD', '၁၄ ၁၄ ၁၄'],\n            ['d do dddd ddd dd', '၀ ၀ တနင်္ဂနွေ နွေ နွေ'],\n            ['DDD DDDo DDDD', '၄၅ ၄၅ ၀၄၅'],\n            ['w wo ww', '၆ ၆ ၀၆'],\n            ['h hh', '၃ ၀၃'],\n            ['H HH', '၁၅ ၁၅'],\n            ['m mm', '၂၅ ၂၅'],\n            ['s ss', '၅၀ ၅၀'],\n            ['a A', 'pm PM'],\n            ['[နှစ်၏] DDDo [ရက်မြောက်]', 'နှစ်၏ ၄၅ ရက်မြောက်'],\n            ['LTS', '၁၅:၂၅:၅၀'],\n            ['L', '၁၄/၀၂/၂၀၁၀'],\n            ['LL', '၁၄ ဖေဖော်ဝါရီ ၂၀၁၀'],\n            ['LLL', '၁၄ ဖေဖော်ဝါရီ ၂၀၁၀ ၁၅:၂၅'],\n            ['LLLL', 'တနင်္ဂနွေ ၁၄ ဖေဖော်ဝါရီ ၂၀၁၀ ၁၅:၂၅'],\n            ['l', '၁၄/၂/၂၀၁၀'],\n            ['ll', '၁၄ ဖေ ၂၀၁၀'],\n            ['lll', '၁၄ ဖေ ၂၀၁၀ ၁၅:၂၅'],\n            ['llll', 'နွေ ၁၄ ဖေ ၂၀၁၀ ၁၅:၂၅']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '၁', '၁');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '၂', '၂');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '၃', '၃');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '၄', '၄');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '၅', '၅');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '၆', '၆');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '၇', '၇');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '၈', '၈');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '၉', '၉');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '၁၀', '၁၀');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '၁၁', '၁၁');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '၁၂', '၁၂');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '၁၃', '၁၃');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '၁၄', '၁၄');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '၁၅', '၁၅');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '၁၆', '၁၆');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '၁၇', '၁၇');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '၁၈', '၁၈');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '၁၉', '၁၉');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '၂၀', '၂၀');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '၂၁', '၂၁');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '၂၂', '၂၂');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '၂၃', '၂၃');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '၂၄', '၂၄');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '၂၅', '၂၅');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '၂၆', '၂၆');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '၂၇', '၂၇');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '၂၈', '၂၈');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '၂၉', '၂၉');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '၃၀', '၃၀');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '၃၁', '၃၁');\n});\n\ntest('format month', function (assert) {\n    var expected = 'ဇန်နဝါရီ ဇန်_ဖေဖော်ဝါရီ ဖေ_မတ် မတ်_ဧပြီ ပြီ_မေ မေ_ဇွန် ဇွန်_ဇူလိုင် လိုင်_သြဂုတ် သြ_စက်တင်ဘာ စက်_အောက်တိုဘာ အောက်_နိုဝင်ဘာ နို_ဒီဇင်ဘာ ဒီ'.split('_'),\n        i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'တနင်္ဂနွေ နွေ နွေ_တနင်္လာ လာ လာ_အင်္ဂါ ဂါ ဂါ_ဗုဒ္ဓဟူး ဟူး ဟူး_ကြာသပတေး ကြာ ကြာ_သောကြာ သော သော_စနေ နေ နေ'.split('_'),\n        i;\n\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({\n        s: 44\n    }), true), 'စက္ကန်.အနည်းငယ်', '၄၄ စက္ကန်. = စက္ကန်.အနည်းငယ်');\n    assert.equal(start.from(moment([2007, 1, 28]).add({\n        s: 45\n    }), true), 'တစ်မိနစ်', '၄၅ စက္ကန်. = တစ်မိနစ်');\n    assert.equal(start.from(moment([2007, 1, 28]).add({\n        s: 89\n    }), true), 'တစ်မိနစ်', '၈၉ စက္ကန်. = တစ်မိနစ်');\n    assert.equal(start.from(moment([2007, 1, 28]).add({\n        s: 90\n    }), true), '၂ မိနစ်', '၉၀ စက္ကန်. =  ၂ မိနစ်');\n    assert.equal(start.from(moment([2007, 1, 28]).add({\n        m: 44\n    }), true), '၄၄ မိနစ်', '၄၄ မိနစ် = ၄၄ မိနစ်');\n    assert.equal(start.from(moment([2007, 1, 28]).add({\n        m: 45\n    }), true), 'တစ်နာရီ', '၄၅ မိနစ် = ၁ နာရီ');\n    assert.equal(start.from(moment([2007, 1, 28]).add({\n        m: 89\n    }), true), 'တစ်နာရီ', '၈၉ မိနစ် = တစ်နာရီ');\n    assert.equal(start.from(moment([2007, 1, 28]).add({\n        m: 90\n    }), true), '၂ နာရီ', 'မိနစ် ၉၀= ၂ နာရီ');\n    assert.equal(start.from(moment([2007, 1, 28]).add({\n        h: 5\n    }), true), '၅ နာရီ', '၅ နာရီ= ၅ နာရီ');\n    assert.equal(start.from(moment([2007, 1, 28]).add({\n        h: 21\n    }), true), '၂၁ နာရီ', '၂၁ နာရီ =၂၁ နာရီ');\n    assert.equal(start.from(moment([2007, 1, 28]).add({\n        h: 22\n    }), true), 'တစ်ရက်', '၂၂ နာရီ =တစ်ရက်');\n    assert.equal(start.from(moment([2007, 1, 28]).add({\n        h: 35\n    }), true), 'တစ်ရက်', '၃၅ နာရီ =တစ်ရက်');\n    assert.equal(start.from(moment([2007, 1, 28]).add({\n        h: 36\n    }), true), '၂ ရက်', '၃၆ နာရီ = ၂ ရက်');\n    assert.equal(start.from(moment([2007, 1, 28]).add({\n        d: 1\n    }), true), 'တစ်ရက်', '၁ ရက်= တစ်ရက်');\n    assert.equal(start.from(moment([2007, 1, 28]).add({\n        d: 5\n    }), true), '၅ ရက်', '၅ ရက် = ၅ ရက်');\n    assert.equal(start.from(moment([2007, 1, 28]).add({\n        d: 25\n    }), true), '၂၅ ရက်', '၂၅ ရက်= ၂၅ ရက်');\n    assert.equal(start.from(moment([2007, 1, 28]).add({\n        d: 26\n    }), true), 'တစ်လ', '၂၆ ရက် = တစ်လ');\n    assert.equal(start.from(moment([2007, 1, 28]).add({\n        d: 30\n    }), true), 'တစ်လ', 'ရက် ၃၀ = တစ်လ');\n    assert.equal(start.from(moment([2007, 1, 28]).add({\n        d: 43\n    }), true), 'တစ်လ', '၄၃ ရက် = တစ်လ');\n    assert.equal(start.from(moment([2007, 1, 28]).add({\n        d: 46\n    }), true), '၂ လ', '၄၆ ရက် = ၂ လ');\n    assert.equal(start.from(moment([2007, 1, 28]).add({\n        d: 74\n    }), true), '၂ လ', '၇၅ ရက်= ၂ လ');\n    assert.equal(start.from(moment([2007, 1, 28]).add({\n        d: 76\n    }), true), '၃ လ', '၇၆ ရက် = ၃ လ');\n    assert.equal(start.from(moment([2007, 1, 28]).add({\n        M: 1\n    }), true), 'တစ်လ', '၁ လ = တစ်လ');\n    assert.equal(start.from(moment([2007, 1, 28]).add({\n        M: 5\n    }), true), '၅ လ', '၅ လ = ၅ လ');\n    assert.equal(start.from(moment([2007, 1, 28]).add({\n        d: 345\n    }), true), 'တစ်နှစ်', '၃၄၅ ရက် = တစ်နှစ်');\n    assert.equal(start.from(moment([2007, 1, 28]).add({\n        d: 548\n    }), true), '၂ နှစ်', '၅၄၈ ရက် = ၂ နှစ်');\n    assert.equal(start.from(moment([2007, 1, 28]).add({\n        y: 1\n    }), true), 'တစ်နှစ်', '၁ နှစ် = တစ်နှစ်');\n    assert.equal(start.from(moment([2007, 1, 28]).add({\n        y: 5\n    }), true), '၅ နှစ်', '၅ နှစ် = ၅ နှစ်');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'လာမည့် စက္ကန်.အနည်းငယ် မှာ', 'prefix');\n    assert.equal(moment(0).from(30000), 'လွန်ခဲ့သော စက္ကန်.အနည်းငယ် က', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'လွန်ခဲ့သော စက္ကန်.အနည်းငယ် က', 'ယခုမှစပြီး အတိတ်တွင်ဖော်ပြသလိုဖော်ပြမည်');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({\n        s: 30\n    }).fromNow(), 'လာမည့် စက္ကန်.အနည်းငယ် မှာ', 'လာမည့် စက္ကန်.အနည်းငယ် မှာ');\n    assert.equal(moment().add({\n        d: 5\n    }).fromNow(), 'လာမည့် ၅ ရက် မှာ', 'လာမည့် ၅ ရက် မှာ');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                  'ယနေ. ၁၂:၀၀ မှာ',      'ယနေ. ဒီအချိန်');\n    assert.equal(moment(a).add({m: 25}).calendar(),     'ယနေ. ၁၂:၂၅ မှာ',      'ယခုမှ ၂၅ မိနစ်ပေါင်းထည့်');\n    assert.equal(moment(a).add({h: 1}).calendar(),      'ယနေ. ၁၃:၀၀ မှာ',      'ယခုမှ ၁ နာရီပေါင်းထည့်');\n    assert.equal(moment(a).add({d: 1}).calendar(),      'မနက်ဖြန် ၁၂:၀၀ မှာ',  'မနက်ဖြန် ဒီအချိန်');\n    assert.equal(moment(a).subtract({h: 1}).calendar(), 'ယနေ. ၁၁:၀၀ မှာ',      'ယခုမှ ၁ နာရီနှုတ်');\n    assert.equal(moment(a).subtract({d: 1}).calendar(), 'မနေ.က ၁၂:၀၀ မှာ',     'မနေ.က ဒီအချိန်');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({\n            d: i\n        });\n        assert.equal(m.calendar(), m.format('dddd LT [မှာ]'), 'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(), m.format('dddd LT [မှာ]'), 'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(), m.format('dddd LT [မှာ]'), 'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({\n            d: i\n        });\n        assert.equal(m.calendar(), m.format('[ပြီးခဲ့သော] dddd LT [မှာ]'), 'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(), m.format('[ပြီးခဲ့သော] dddd LT [မှာ]'), 'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(), m.format('[ပြီးခဲ့သော] dddd LT [မှာ]'), 'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({\n            w: 1\n        }),\n        weeksFromNow = moment().add({\n            w: 1\n        });\n\n    assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), 'လွန်ခဲ့သော ၁ ပတ်က');\n    assert.equal(weeksFromNow.calendar(), weeksFromNow.format('L'), '၁ ပတ်အတွင်း');\n\n    weeksAgo = moment().subtract({\n        w: 2\n    });\n    weeksFromNow = moment().add({\n        w: 2\n    });\n\n    assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '၂ ပတ် အရင်က');\n    assert.equal(weeksFromNow.calendar(), weeksFromNow.format('L'), '၂ ပတ် အတွင်း');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2012, 0, 1]).format('w ww wo'), '၅၂ ၅၂ ၅၂', 'Jan  1 2012 should be week 52');\n    assert.equal(moment([2012, 0, 2]).format('w ww wo'), '၁ ၀၁ ၁', 'Jan  2 2012 should be week 1');\n    assert.equal(moment([2012, 0, 8]).format('w ww wo'), '၁ ၀၁ ၁', 'Jan  8 2012 should be week 1');\n    assert.equal(moment([2012, 0, 9]).format('w ww wo'), '၂ ၀၂ ၂', 'Jan  9 2012 should be week 2');\n    assert.equal(moment([2012, 0, 15]).format('w ww wo'), '၂ ၀၂ ၂', 'Jan 15 2012 should be week 2');\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\n\n\nfunction localeModule (name, lifecycle) {\n    QUnit.module('locale:' + name, {\n        setup : function () {\n            moment.locale(name);\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            moment.locale('en');\n            teardownDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n    defineCommonLocaleTests(name, -1, -1);\n}\n\nlocaleModule('nb');\n\ntest('parse', function (assert) {\n    var tests = 'januar jan._februar feb._mars mars_april april_mai mai_juni juni_juli juli_august aug._september sep._oktober okt._november nov._desember des.'.split('_'),\n        i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, MMMM Do YYYY, h:mm:ss a',      'søndag, februar 14. 2010, 3:25:50 pm'],\n            ['ddd, hA',                            'sø., 3PM'],\n            ['M Mo MM MMMM MMM',                   '2 2. 02 februar feb.'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14. 14'],\n            ['d do dddd ddd dd',                   '0 0. søndag sø. sø'],\n            ['DDD DDDo DDDD',                      '45 45. 045'],\n            ['w wo ww',                            '6 6. 06'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'pm PM'],\n            ['[den] DDDo [dagen i året]',          'den 45. dagen i året'],\n            ['LTS',                                '15:25:50'],\n            ['L',                                  '14.02.2010'],\n            ['LL',                                 '14. februar 2010'],\n            ['LLL',                                '14. februar 2010 kl. 15:25'],\n            ['LLLL',                               'søndag 14. februar 2010 kl. 15:25'],\n            ['l',                                  '14.2.2010'],\n            ['ll',                                 '14. feb. 2010'],\n            ['lll',                                '14. feb. 2010 kl. 15:25'],\n            ['llll',                               'sø. 14. feb. 2010 kl. 15:25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1.', '1.');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2.', '2.');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3.', '3.');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4.', '4.');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5.', '5.');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6.', '6.');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7.', '7.');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8.', '8.');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9.', '9.');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10.', '10.');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11.', '11.');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12.', '12.');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13.', '13.');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14.', '14.');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15.', '15.');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16.', '16.');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17.', '17.');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18.', '18.');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19.', '19.');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20.', '20.');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21.', '21.');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22.', '22.');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23.', '23.');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24.', '24.');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25.', '25.');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26.', '26.');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27.', '27.');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28.', '28.');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29.', '29.');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30.', '30.');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31.', '31.');\n});\n\ntest('format month', function (assert) {\n    var expected = 'januar jan._februar feb._mars mars_april april_mai mai_juni juni_juli juli_august aug._september sep._oktober okt._november nov._desember des.'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'søndag sø. sø_mandag ma. ma_tirsdag ti. ti_onsdag on. on_torsdag to. to_fredag fr. fr_lørdag lø. lø'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'noen sekunder', '44 sekunder = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'ett minutt',      '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'ett minutt',      '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 minutter',     '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 minutter',    '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'en time',       '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'en time',       '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 timer',       '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 timer',       '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 timer',      '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'en dag',         '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'en dag',         '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 dager',        '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'en dag',         '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 dager',        '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 dager',       '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'en måned',       '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'en måned',       '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'en måned',       '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 måneder',      '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 måneder',      '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 måneder',      '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'en måned',       '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 måneder',      '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'ett år',        '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 år',       '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'ett år',        '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 år',       '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'om noen sekunder',  'prefix');\n    assert.equal(moment(0).from(30000), 'noen sekunder siden', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'noen sekunder siden',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'om noen sekunder', 'in a few seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), 'om 5 dager', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'i dag kl. 12:00',     'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'i dag kl. 12:25',     'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'i dag kl. 13:00',     'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'i morgen kl. 12:00',  'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'i dag kl. 11:00',     'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'i går kl. 12:00',     'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('dddd [kl.] LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd [kl.] LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd [kl.] LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('[forrige] dddd [kl.] LT'),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[forrige] dddd [kl.] LT'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[forrige] dddd [kl.] LT'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2012, 0,  1]).format('w ww wo'), '52 52 52.', 'Jan  1 2012 should be week 52');\n    assert.equal(moment([2012, 0,  2]).format('w ww wo'),  '1 01 1.', 'Jan  2 2012 should be week 1');\n    assert.equal(moment([2012, 0,  8]).format('w ww wo'),  '1 01 1.', 'Jan  8 2012 should be week 1');\n    assert.equal(moment([2012, 0,  9]).format('w ww wo'),  '2 02 2.', 'Jan  9 2012 should be week 2');\n    assert.equal(moment([2012, 0, 15]).format('w ww wo'),  '2 02 2.', 'Jan 15 2012 should be week 2');\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\n\n\nfunction localeModule (name, lifecycle) {\n    QUnit.module('locale:' + name, {\n        setup : function () {\n            moment.locale(name);\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            moment.locale('en');\n            teardownDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n    defineCommonLocaleTests(name, -1, -1);\n}\n\nlocaleModule('ne');\n\ntest('parse', function (assert) {\n    var tests = 'जनवरी जन._फेब्रुवरी फेब्रु._मार्च मार्च_अप्रिल अप्रि._मई मई_जुन जुन_जुलाई जुलाई._अगष्ट अग._सेप्टेम्बर सेप्ट._अक्टोबर अक्टो._नोभेम्बर नोभे._डिसेम्बर डिसे.'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, Do MMMM YYYY, aको h:mm:ss बजे',      'आइतबार, १४ फेब्रुवरी २०१०, दिउँसोको ३:२५:५० बजे'],\n            ['ddd, aको h बजे',                                                'आइत., दिउँसोको ३ बजे'],\n            ['M Mo MM MMMM MMM',                   '२ २ ०२ फेब्रुवरी फेब्रु.'],\n            ['YYYY YY',                            '२०१० १०'],\n            ['D Do DD',                            '१४ १४ १४'],\n            ['d do dddd ddd dd',                   '० ० आइतबार आइत. आ.'],\n            ['DDD DDDo DDDD',                      '४५ ४५ ०४५'],\n            ['w wo ww',                            '८ ८ ०८'],\n            ['h hh',                               '३ ०३'],\n            ['H HH',                               '१५ १५'],\n            ['m mm',                               '२५ २५'],\n            ['s ss',                               '५० ५०'],\n            ['a A',                                'दिउँसो दिउँसो'],\n            ['LTS',                                'दिउँसोको ३:२५:५० बजे'],\n            ['L',                                  '१४/०२/२०१०'],\n            ['LL',                                 '१४ फेब्रुवरी २०१०'],\n            ['LLL',                                '१४ फेब्रुवरी २०१०, दिउँसोको ३:२५ बजे'],\n            ['LLLL',                               'आइतबार, १४ फेब्रुवरी २०१०, दिउँसोको ३:२५ बजे'],\n            ['l',                                  '१४/२/२०१०'],\n            ['ll',                                 '१४ फेब्रु. २०१०'],\n            ['lll',                                '१४ फेब्रु. २०१०, दिउँसोको ३:२५ बजे'],\n            ['llll',                               'आइत., १४ फेब्रु. २०१०, दिउँसोको ३:२५ बजे']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '१', '१');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '२', '२');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '३', '३');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '४', '४');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '५', '५');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '६', '६');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '७', '७');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '८', '८');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '९', '९');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '१०', '१०');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '११', '११');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '१२', '१२');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '१३', '१३');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '१४', '१४');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '१५', '१५');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '१६', '१६');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '१७', '१७');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '१८', '१८');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '१९', '१९');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '२०', '२०');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '२१', '२१');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '२२', '२२');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '२३', '२३');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '२४', '२४');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '२५', '२५');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '२६', '२६');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '२७', '२७');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '२८', '२८');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '२९', '२९');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '३०', '३०');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '३१', '३१');\n});\n\ntest('format month', function (assert) {\n    var expected = 'जनवरी जन._फेब्रुवरी फेब्रु._मार्च मार्च_अप्रिल अप्रि._मई मई_जुन जुन_जुलाई जुलाई._अगष्ट अग._सेप्टेम्बर सेप्ट._अक्टोबर अक्टो._नोभेम्बर नोभे._डिसेम्बर डिसे.'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'आइतबार आइत. आ._सोमबार सोम. सो._मङ्गलबार मङ्गल. मं._बुधबार बुध. बु._बिहिबार बिहि. बि._शुक्रबार शुक्र. शु._शनिबार शनि. श.'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'केही क्षण', '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'एक मिनेट',      '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'एक मिनेट',      '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '२ मिनेट',     '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '४४ मिनेट',    '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'एक घण्टा',       '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'एक घण्टा',       '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '२ घण्टा',       '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '५ घण्टा',       '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '२१ घण्टा',      '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'एक दिन',         '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'एक दिन',         '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '२ दिन',        '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'एक दिन',         '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '५ दिन',        '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '२५ दिन',       '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'एक महिना',       '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'एक महिना',       '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'एक महिना',       '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '२ महिना',      '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '२ महिना',      '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '३ महिना',      '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'एक महिना',       '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '५ महिना',      '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'एक बर्ष',        '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '२ बर्ष',       '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'एक बर्ष',        '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '५ बर्ष',       '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'केही क्षणमा',  'prefix');\n    assert.equal(moment(0).from(30000), 'केही क्षण अगाडि', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'केही क्षण अगाडि',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'केही क्षणमा', 'केही क्षणमा');\n    assert.equal(moment().add({d: 5}).fromNow(), '५ दिनमा', '५ दिनमा');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'आज दिउँसोको १२:०० बजे',    'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'आज दिउँसोको १२:२५ बजे',    'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'आज दिउँसोको १:०० बजे',     'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'भोलि दिउँसोको १२:०० बजे',  'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'आज बिहानको ११:०० बजे',     'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'हिजो दिउँसोको १२:०० बजे',  'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('[आउँदो] dddd[,] LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[आउँदो] dddd[,] LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[आउँदो] dddd[,] LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('[गएको] dddd[,] LT'),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[गएको] dddd[,] LT'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[गएको] dddd[,] LT'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('meridiem', function (assert) {\n    assert.equal(moment([2011, 2, 23,  2, 30]).format('a'), 'राति', 'before dawn');\n    assert.equal(moment([2011, 2, 23,  9, 30]).format('a'), 'बिहान', 'morning');\n    assert.equal(moment([2011, 2, 23, 14, 30]).format('a'), 'दिउँसो', 'during day');\n    assert.equal(moment([2011, 2, 23, 17, 30]).format('a'), 'साँझ', 'evening');\n    assert.equal(moment([2011, 2, 23, 19, 30]).format('a'), 'साँझ', 'late evening');\n    assert.equal(moment([2011, 2, 23, 21, 20]).format('a'), 'राति', 'night');\n\n    assert.equal(moment([2011, 2, 23,  2, 30]).format('A'), 'राति', 'before dawn');\n    assert.equal(moment([2011, 2, 23,  9, 30]).format('A'), 'बिहान', 'morning');\n    assert.equal(moment([2011, 2, 23, 14, 30]).format('A'), 'दिउँसो', 'during day');\n    assert.equal(moment([2011, 2, 23, 17, 30]).format('A'), 'साँझ', 'evening');\n    assert.equal(moment([2011, 2, 23, 19, 30]).format('A'), 'साँझ', 'late evening');\n    assert.equal(moment([2011, 2, 23, 21, 20]).format('A'), 'राति', 'night');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2011, 11, 26]).format('w ww wo'), '५३ ५३ ५३', 'Dec 26 2011 should be week 53');\n    assert.equal(moment([2012,  0,  1]).format('w ww wo'), '१ ०१ १', 'Jan  1 2012 should be week 1');\n    assert.equal(moment([2012,  0,  2]).format('w ww wo'), '१ ०१ १', 'Jan  2 2012 should be week 1');\n    assert.equal(moment([2012,  0,  8]).format('w ww wo'), '२ ०२ २', 'Jan  8 2012 should be week 2');\n    assert.equal(moment([2012,  0,  9]).format('w ww wo'), '२ ०२ २', 'Jan  9 2012 should be week 2');\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\n\n\nfunction localeModule (name, lifecycle) {\n    QUnit.module('locale:' + name, {\n        setup : function () {\n            moment.locale(name);\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            moment.locale('en');\n            teardownDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n    defineCommonLocaleTests(name, -1, -1);\n}\n\nlocaleModule('nl-be');\n\ntest('parse', function (assert) {\n    var tests = 'januari jan._februari feb._maart mrt._april apr._mei mei._juni jun._juli jul._augustus aug._september sep._oktober okt._november nov._december dec.'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, MMMM Do YYYY, HH:mm:ss',       'zondag, februari 14de 2010, 15:25:50'],\n            ['ddd, HH',                            'zo., 15'],\n            ['M Mo MM MMMM MMM',                   '2 2de 02 februari feb.'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14de 14'],\n            ['d do dddd ddd dd',                   '0 0de zondag zo. Zo'],\n            ['DDD DDDo DDDD',                      '45 45ste 045'],\n            ['w wo ww',                            '6 6de 06'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'pm PM'],\n            ['[the] DDDo [day of the year]',       'the 45ste day of the year'],\n            ['LTS',                                '15:25:50'],\n            ['L',                                  '14/02/2010'],\n            ['LL',                                 '14 februari 2010'],\n            ['LLL',                                '14 februari 2010 15:25'],\n            ['LLLL',                               'zondag 14 februari 2010 15:25'],\n            ['l',                                  '14/2/2010'],\n            ['ll',                                 '14 feb. 2010'],\n            ['lll',                                '14 feb. 2010 15:25'],\n            ['llll',                               'zo. 14 feb. 2010 15:25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1ste', '1ste');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2de', '2de');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3de', '3de');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4de', '4de');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5de', '5de');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6de', '6de');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7de', '7de');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8ste', '8ste');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9de', '9de');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10de', '10de');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11de', '11de');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12de', '12de');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13de', '13de');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14de', '14de');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15de', '15de');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16de', '16de');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17de', '17de');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18de', '18de');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19de', '19de');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20ste', '20ste');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21ste', '21ste');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22ste', '22ste');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23ste', '23ste');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24ste', '24ste');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25ste', '25ste');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26ste', '26ste');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27ste', '27ste');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28ste', '28ste');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29ste', '29ste');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30ste', '30ste');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31ste', '31ste');\n});\n\ntest('format month', function (assert) {\n    var expected = 'januari jan._februari feb._maart mrt._april apr._mei mei_juni jun._juli jul._augustus aug._september sep._oktober okt._november nov._december dec.'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'zondag zo. Zo_maandag ma. Ma_dinsdag di. Di_woensdag wo. Wo_donderdag do. Do_vrijdag vr. Vr_zaterdag za. Za'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'een paar seconden', '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'één minuut',      '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'één minuut',      '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 minuten',     '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 minuten',    '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'één uur',       '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'één uur',       '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 uur',       '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 uur',       '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 uur',      '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'één dag',         '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'één dag',         '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 dagen',        '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'één dag',         '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 dagen',        '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 dagen',       '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'één maand',       '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'één maand',       '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'één maand',       '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 maanden',      '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 maanden',      '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 maanden',      '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'één maand',       '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 maanden',      '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'één jaar',        '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 jaar',       '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'één jaar',        '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 jaar',       '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'over een paar seconden',  'prefix');\n    assert.equal(moment(0).from(30000), 'een paar seconden geleden', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'een paar seconden geleden',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'over een paar seconden', 'in a few seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), 'over 5 dagen', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'vandaag om 12:00',   'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'vandaag om 12:25',   'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'vandaag om 13:00',   'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'morgen om 12:00',    'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'vandaag om 11:00',   'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'gisteren om 12:00',  'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('dddd [om] LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd [om] LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd [om] LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('[afgelopen] dddd [om] LT'),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[afgelopen] dddd [om] LT'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[afgelopen] dddd [om] LT'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('month abbreviation', function (assert) {\n    assert.equal(moment([2012, 5, 23]).format('D-MMM-YYYY'), '23-jun-2012', 'format month abbreviation surrounded by dashes should not include a dot');\n    assert.equal(moment([2012, 5, 23]).unix(), moment('23-jun-2012', 'D-MMM-YYYY').unix(), 'parse month abbreviation surrounded by dashes without dot');\n    assert.equal(moment([2012, 5, 23]).format('D MMM YYYY'), '23 jun. 2012', 'format month abbreviation not surrounded by dashes should include a dot');\n    assert.equal(moment([2012, 5, 23]).unix(), moment('23 jun. 2012', 'D MMM YYYY').unix(), 'parse month abbreviation not surrounded by dashes with dot');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2012, 0,  1]).format('w ww wo'), '52 52 52ste', 'Jan  1 2012 should be week 52');\n    assert.equal(moment([2012, 0,  2]).format('w ww wo'),   '1 01 1ste', 'Jan  2 2012 should be week 1');\n    assert.equal(moment([2012, 0,  8]).format('w ww wo'),   '1 01 1ste', 'Jan  8 2012 should be week 1');\n    assert.equal(moment([2012, 0,  9]).format('w ww wo'),    '2 02 2de', 'Jan  9 2012 should be week 2');\n    assert.equal(moment([2012, 0, 15]).format('w ww wo'),    '2 02 2de', 'Jan 15 2012 should be week 2');\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\n\n\nfunction localeModule (name, lifecycle) {\n    QUnit.module('locale:' + name, {\n        setup : function () {\n            moment.locale(name);\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            moment.locale('en');\n            teardownDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n    defineCommonLocaleTests(name, -1, -1);\n}\n\nlocaleModule('nl');\n\ntest('parse', function (assert) {\n    var tests = 'januari jan._februari feb._maart mrt._april apr._mei mei._juni jun._juli jul._augustus aug._september sep._oktober okt._november nov._december dec.'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, MMMM Do YYYY, HH:mm:ss',       'zondag, februari 14de 2010, 15:25:50'],\n            ['ddd, HH',                            'zo., 15'],\n            ['M Mo MM MMMM MMM',                   '2 2de 02 februari feb.'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14de 14'],\n            ['d do dddd ddd dd',                   '0 0de zondag zo. Zo'],\n            ['DDD DDDo DDDD',                      '45 45ste 045'],\n            ['w wo ww',                            '6 6de 06'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'pm PM'],\n            ['[the] DDDo [day of the year]',       'the 45ste day of the year'],\n            ['LTS',                                '15:25:50'],\n            ['L',                                  '14-02-2010'],\n            ['LL',                                 '14 februari 2010'],\n            ['LLL',                                '14 februari 2010 15:25'],\n            ['LLLL',                               'zondag 14 februari 2010 15:25'],\n            ['l',                                  '14-2-2010'],\n            ['ll',                                 '14 feb. 2010'],\n            ['lll',                                '14 feb. 2010 15:25'],\n            ['llll',                               'zo. 14 feb. 2010 15:25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1ste', '1ste');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2de', '2de');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3de', '3de');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4de', '4de');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5de', '5de');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6de', '6de');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7de', '7de');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8ste', '8ste');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9de', '9de');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10de', '10de');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11de', '11de');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12de', '12de');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13de', '13de');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14de', '14de');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15de', '15de');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16de', '16de');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17de', '17de');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18de', '18de');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19de', '19de');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20ste', '20ste');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21ste', '21ste');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22ste', '22ste');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23ste', '23ste');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24ste', '24ste');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25ste', '25ste');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26ste', '26ste');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27ste', '27ste');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28ste', '28ste');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29ste', '29ste');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30ste', '30ste');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31ste', '31ste');\n});\n\ntest('format month', function (assert) {\n    var expected = 'januari jan._februari feb._maart mrt._april apr._mei mei_juni jun._juli jul._augustus aug._september sep._oktober okt._november nov._december dec.'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'zondag zo. Zo_maandag ma. Ma_dinsdag di. Di_woensdag wo. Wo_donderdag do. Do_vrijdag vr. Vr_zaterdag za. Za'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'een paar seconden', '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'één minuut',      '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'één minuut',      '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 minuten',     '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 minuten',    '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'één uur',       '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'één uur',       '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 uur',       '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 uur',       '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 uur',      '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'één dag',         '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'één dag',         '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 dagen',        '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'één dag',         '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 dagen',        '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 dagen',       '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'één maand',       '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'één maand',       '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'één maand',       '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 maanden',      '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 maanden',      '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 maanden',      '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'één maand',       '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 maanden',      '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'één jaar',        '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 jaar',       '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'één jaar',        '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 jaar',       '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'over een paar seconden',  'prefix');\n    assert.equal(moment(0).from(30000), 'een paar seconden geleden', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'een paar seconden geleden',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'over een paar seconden', 'in a few seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), 'over 5 dagen', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'vandaag om 12:00',   'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'vandaag om 12:25',   'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'vandaag om 13:00',   'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'morgen om 12:00',    'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'vandaag om 11:00',   'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'gisteren om 12:00',  'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('dddd [om] LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd [om] LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd [om] LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('[afgelopen] dddd [om] LT'),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[afgelopen] dddd [om] LT'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[afgelopen] dddd [om] LT'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('month abbreviation', function (assert) {\n    assert.equal(moment([2012, 5, 23]).format('D-MMM-YYYY'), '23-jun-2012', 'format month abbreviation surrounded by dashes should not include a dot');\n    assert.equal(moment([2012, 5, 23]).unix(), moment('23-jun-2012', 'D-MMM-YYYY').unix(), 'parse month abbreviation surrounded by dashes without dot');\n    assert.equal(moment([2012, 5, 23]).format('D MMM YYYY'), '23 jun. 2012', 'format month abbreviation not surrounded by dashes should include a dot');\n    assert.equal(moment([2012, 5, 23]).unix(), moment('23 jun. 2012', 'D MMM YYYY').unix(), 'parse month abbreviation not surrounded by dashes with dot');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2012, 0,  1]).format('w ww wo'), '52 52 52ste', 'Jan  1 2012 should be week 52');\n    assert.equal(moment([2012, 0,  2]).format('w ww wo'),   '1 01 1ste', 'Jan  2 2012 should be week 1');\n    assert.equal(moment([2012, 0,  8]).format('w ww wo'),   '1 01 1ste', 'Jan  8 2012 should be week 1');\n    assert.equal(moment([2012, 0,  9]).format('w ww wo'),    '2 02 2de', 'Jan  9 2012 should be week 2');\n    assert.equal(moment([2012, 0, 15]).format('w ww wo'),    '2 02 2de', 'Jan 15 2012 should be week 2');\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\n\n\nfunction localeModule (name, lifecycle) {\n    QUnit.module('locale:' + name, {\n        setup : function () {\n            moment.locale(name);\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            moment.locale('en');\n            teardownDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n    defineCommonLocaleTests(name, -1, -1);\n}\n\nlocaleModule('nn');\n\ntest('parse', function (assert) {\n    var tests = 'januar jan_februar feb_mars mar_april apr_mai mai_juni jun_juli jul_august aug_september sep_oktober okt_november nov_desember des'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, MMMM Do YYYY, h:mm:ss a',      'sundag, februar 14. 2010, 3:25:50 pm'],\n            ['ddd, hA',                            'sun, 3PM'],\n            ['M Mo MM MMMM MMM',                   '2 2. 02 februar feb'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14. 14'],\n            ['d do dddd ddd dd',                   '0 0. sundag sun su'],\n            ['DDD DDDo DDDD',                      '45 45. 045'],\n            ['w wo ww',                            '6 6. 06'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'pm PM'],\n            ['[the] DDDo [day of the year]',       'the 45. day of the year'],\n            ['LTS',                                '15:25:50'],\n            ['L',                                  '14.02.2010'],\n            ['LL',                                 '14. februar 2010'],\n            ['LLL',                                '14. februar 2010 kl. 15:25'],\n            ['LLLL',                               'sundag 14. februar 2010 kl. 15:25'],\n            ['l',                                  '14.2.2010'],\n            ['ll',                                 '14. feb 2010'],\n            ['lll',                                '14. feb 2010 kl. 15:25'],\n            ['llll',                               'sun 14. feb 2010 kl. 15:25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1.', '1.');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2.', '2.');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3.', '3.');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4.', '4.');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5.', '5.');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6.', '6.');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7.', '7.');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8.', '8.');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9.', '9.');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10.', '10.');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11.', '11.');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12.', '12.');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13.', '13.');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14.', '14.');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15.', '15.');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16.', '16.');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17.', '17.');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18.', '18.');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19.', '19.');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20.', '20.');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21.', '21.');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22.', '22.');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23.', '23.');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24.', '24.');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25.', '25.');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26.', '26.');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27.', '27.');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28.', '28.');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29.', '29.');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30.', '30.');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31.', '31.');\n});\n\ntest('format month', function (assert) {\n    var expected = 'januar jan_februar feb_mars mar_april apr_mai mai_juni jun_juli jul_august aug_september sep_oktober okt_november nov_desember des'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'sundag sun su_måndag mån må_tysdag tys ty_onsdag ons on_torsdag tor to_fredag fre fr_laurdag lau lø'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'nokre sekund', '44 sekunder = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'eit minutt',   '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'eit minutt',   '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 minutt',     '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 minutt',    '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'ein time',     '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'ein time',     '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 timar',      '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 timar',      '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 timar',     '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'ein dag',      '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'ein dag',      '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 dagar',      '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'ein dag',      '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 dagar',      '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 dagar',     '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'ein månad',    '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'ein månad',    '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'ein månad',    '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 månader',    '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 månader',    '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 månader',    '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'ein månad',    '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 månader',    '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'eit år',       '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 år',         '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'eit år',       '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 år',         '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'om nokre sekund',  'prefix');\n    assert.equal(moment(0).from(30000), 'nokre sekund sidan', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'nokre sekund sidan',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'om nokre sekund', 'in a few seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), 'om 5 dagar', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'I dag klokka 12:00',     'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'I dag klokka 12:25',     'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'I dag klokka 13:00',     'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'I morgon klokka 12:00',  'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'I dag klokka 11:00',     'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'I går klokka 12:00',     'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('dddd [klokka] LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd [klokka] LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd [klokka] LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('[Føregåande] dddd [klokka] LT'),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[Føregåande] dddd [klokka] LT'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[Føregåande] dddd [klokka] LT'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2012, 0,  1]).format('w ww wo'), '52 52 52.', 'Jan  1 2012 should be week 52');\n    assert.equal(moment([2012, 0,  2]).format('w ww wo'),   '1 01 1.', 'Jan  2 2012 should be week 1');\n    assert.equal(moment([2012, 0,  8]).format('w ww wo'),   '1 01 1.', 'Jan  8 2012 should be week 1');\n    assert.equal(moment([2012, 0,  9]).format('w ww wo'),   '2 02 2.', 'Jan  9 2012 should be week 2');\n    assert.equal(moment([2012, 0, 15]).format('w ww wo'),   '2 02 2.', 'Jan 15 2012 should be week 2');\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\n\n\nfunction localeModule (name, lifecycle) {\n    QUnit.module('locale:' + name, {\n        setup : function () {\n            moment.locale(name);\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            moment.locale('en');\n            teardownDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n    defineCommonLocaleTests(name, -1, -1);\n}\n\nlocaleModule('pa-in');\n\ntest('parse', function (assert) {\n    var tests = 'ਜਨਵਰੀ ਜਨਵਰੀ_ਫ਼ਰਵਰੀ ਫ਼ਰਵਰੀ_ਮਾਰਚ ਮਾਰਚ_ਅਪ੍ਰੈਲ ਅਪ੍ਰੈਲ_ਮਈ ਮਈ_ਜੂਨ ਜੂਨ_ਜੁਲਾਈ ਜੁਲਾਈ_ਅਗਸਤ ਅਗਸਤ_ਸਤੰਬਰ ਸਤੰਬਰ_ਅਕਤੂਬਰ ਅਕਤੂਬਰ_ਨਵੰਬਰ ਨਵੰਬਰ_ਦਸੰਬਰ ਦਸੰਬਰ'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, Do MMMM YYYY, a h:mm:ss ਵਜੇ',  'ਐਤਵਾਰ, ੧੪ ਫ਼ਰਵਰੀ ੨੦੧੦, ਦੁਪਹਿਰ ੩:੨੫:੫੦ ਵਜੇ'],\n            ['ddd, a h ਵਜੇ',                       'ਐਤ, ਦੁਪਹਿਰ ੩ ਵਜੇ'],\n            ['M Mo MM MMMM MMM',                   '੨ ੨ ੦੨ ਫ਼ਰਵਰੀ ਫ਼ਰਵਰੀ'],\n            ['YYYY YY',                            '੨੦੧੦ ੧੦'],\n            ['D Do DD',                            '੧੪ ੧੪ ੧੪'],\n            ['d do dddd ddd dd',                   '੦ ੦ ਐਤਵਾਰ ਐਤ ਐਤ'],\n            ['DDD DDDo DDDD',                      '੪੫ ੪੫ ੦੪੫'],\n            ['w wo ww',                            '੮ ੮ ੦੮'],\n            ['h hh',                               '੩ ੦੩'],\n            ['H HH',                               '੧੫ ੧੫'],\n            ['m mm',                               '੨੫ ੨੫'],\n            ['s ss',                               '੫੦ ੫੦'],\n            ['a A',                                'ਦੁਪਹਿਰ ਦੁਪਹਿਰ'],\n            ['LTS',                                'ਦੁਪਹਿਰ ੩:੨੫:੫੦ ਵਜੇ'],\n            ['L',                                  '੧੪/੦੨/੨੦੧੦'],\n            ['LL',                                 '੧੪ ਫ਼ਰਵਰੀ ੨੦੧੦'],\n            ['LLL',                                '੧੪ ਫ਼ਰਵਰੀ ੨੦੧੦, ਦੁਪਹਿਰ ੩:੨੫ ਵਜੇ'],\n            ['LLLL',                               'ਐਤਵਾਰ, ੧੪ ਫ਼ਰਵਰੀ ੨੦੧੦, ਦੁਪਹਿਰ ੩:੨੫ ਵਜੇ'],\n            ['l',                                  '੧੪/੨/੨੦੧੦'],\n            ['ll',                                 '੧੪ ਫ਼ਰਵਰੀ ੨੦੧੦'],\n            ['lll',                                '੧੪ ਫ਼ਰਵਰੀ ੨੦੧੦, ਦੁਪਹਿਰ ੩:੨੫ ਵਜੇ'],\n            ['llll',                               'ਐਤ, ੧੪ ਫ਼ਰਵਰੀ ੨੦੧੦, ਦੁਪਹਿਰ ੩:੨੫ ਵਜੇ']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '੧', '੧');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '੨', '੨');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '੩', '੩');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '੪', '੪');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '੫', '੫');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '੬', '੬');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '੭', '੭');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '੮', '੮');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '੯', '੯');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '੧੦', '੧੦');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '੧੧', '੧੧');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '੧੨', '੧੨');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '੧੩', '੧੩');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '੧੪', '੧੪');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '੧੫', '੧੫');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '੧੬', '੧੬');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '੧੭', '੧੭');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '੧੮', '੧੮');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '੧੯', '੧੯');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '੨੦', '੨੦');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '੨੧', '੨੧');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '੨੨', '੨੨');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '੨੩', '੨੩');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '੨੪', '੨੪');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '੨੫', '੨੫');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '੨੬', '੨੬');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '੨੭', '੨੭');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '੨੮', '੨੮');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '੨੯', '੨੯');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '੩੦', '੩੦');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '੩੧', '੩੧');\n});\n\ntest('format month', function (assert) {\n    var expected = 'ਜਨਵਰੀ ਜਨਵਰੀ_ਫ਼ਰਵਰੀ ਫ਼ਰਵਰੀ_ਮਾਰਚ ਮਾਰਚ_ਅਪ੍ਰੈਲ ਅਪ੍ਰੈਲ_ਮਈ ਮਈ_ਜੂਨ ਜੂਨ_ਜੁਲਾਈ ਜੁਲਾਈ_ਅਗਸਤ ਅਗਸਤ_ਸਤੰਬਰ ਸਤੰਬਰ_ਅਕਤੂਬਰ ਅਕਤੂਬਰ_ਨਵੰਬਰ ਨਵੰਬਰ_ਦਸੰਬਰ ਦਸੰਬਰ'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'ਐਤਵਾਰ ਐਤ ਐਤ_ਸੋਮਵਾਰ ਸੋਮ ਸੋਮ_ਮੰਗਲਵਾਰ ਮੰਗਲ ਮੰਗਲ_ਬੁਧਵਾਰ ਬੁਧ ਬੁਧ_ਵੀਰਵਾਰ ਵੀਰ ਵੀਰ_ਸ਼ੁੱਕਰਵਾਰ ਸ਼ੁਕਰ ਸ਼ੁਕਰ_ਸ਼ਨੀਚਰਵਾਰ ਸ਼ਨੀ ਸ਼ਨੀ'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'ਕੁਝ ਸਕਿੰਟ', '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'ਇਕ ਮਿੰਟ',      '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'ਇਕ ਮਿੰਟ',      '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '੨ ਮਿੰਟ',     '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '੪੪ ਮਿੰਟ',    '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'ਇੱਕ ਘੰਟਾ',       '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'ਇੱਕ ਘੰਟਾ',       '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '੨ ਘੰਟੇ',       '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '੫ ਘੰਟੇ',       '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '੨੧ ਘੰਟੇ',      '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'ਇੱਕ ਦਿਨ',         '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'ਇੱਕ ਦਿਨ',         '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '੨ ਦਿਨ',        '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'ਇੱਕ ਦਿਨ',         '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '੫ ਦਿਨ',        '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '੨੫ ਦਿਨ',       '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'ਇੱਕ ਮਹੀਨਾ',       '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'ਇੱਕ ਮਹੀਨਾ',       '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'ਇੱਕ ਮਹੀਨਾ',       '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '੨ ਮਹੀਨੇ',      '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '੨ ਮਹੀਨੇ',      '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '੩ ਮਹੀਨੇ',      '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'ਇੱਕ ਮਹੀਨਾ',       '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '੫ ਮਹੀਨੇ',      '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'ਇੱਕ ਸਾਲ',        '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '੨ ਸਾਲ',       '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'ਇੱਕ ਸਾਲ',        '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '੫ ਸਾਲ',       '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'ਕੁਝ ਸਕਿੰਟ ਵਿੱਚ',  'prefix');\n    assert.equal(moment(0).from(30000), 'ਕੁਝ ਸਕਿੰਟ ਪਿਛਲੇ', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'ਕੁਝ ਸਕਿੰਟ ਪਿਛਲੇ',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'ਕੁਝ ਸਕਿੰਟ ਵਿੱਚ', 'ਕੁਝ ਸਕਿੰਟ ਵਿੱਚ');\n    assert.equal(moment().add({d: 5}).fromNow(), '੫ ਦਿਨ ਵਿੱਚ', '੫ ਦਿਨ ਵਿੱਚ');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'ਅਜ ਦੁਪਹਿਰ ੧੨:੦੦ ਵਜੇ',  'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'ਅਜ ਦੁਪਹਿਰ ੧੨:੨੫ ਵਜੇ',  'Now plus 25 min');\n    assert.equal(moment(a).add({h: 3}).calendar(),       'ਅਜ ਦੁਪਹਿਰ ੩:੦੦ ਵਜੇ',   'Now plus 3 hours');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'ਕਲ ਦੁਪਹਿਰ ੧੨:੦੦ ਵਜੇ',  'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'ਅਜ ਦੁਪਹਿਰ ੧੧:੦੦ ਵਜੇ',  'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'ਕਲ ਦੁਪਹਿਰ ੧੨:੦੦ ਵਜੇ',  'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('dddd[,] LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd[,] LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd[,] LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('[ਪਿਛਲੇ] dddd[,] LT'),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[ਪਿਛਲੇ] dddd[,] LT'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[ਪਿਛਲੇ] dddd[,] LT'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('meridiem invariant', function (assert) {\n    assert.equal(moment([2011, 2, 23,  2, 30]).format('a'), 'ਰਾਤ', 'before dawn');\n    assert.equal(moment([2011, 2, 23,  9, 30]).format('a'), 'ਸਵੇਰ', 'morning');\n    assert.equal(moment([2011, 2, 23, 14, 30]).format('a'), 'ਦੁਪਹਿਰ', 'during day');\n    assert.equal(moment([2011, 2, 23, 17, 30]).format('a'), 'ਸ਼ਾਮ', 'evening');\n    assert.equal(moment([2011, 2, 23, 19, 30]).format('a'), 'ਸ਼ਾਮ', 'late evening');\n    assert.equal(moment([2011, 2, 23, 21, 20]).format('a'), 'ਰਾਤ', 'night');\n\n    assert.equal(moment([2011, 2, 23,  2, 30]).format('A'), 'ਰਾਤ', 'before dawn');\n    assert.equal(moment([2011, 2, 23,  9, 30]).format('A'), 'ਸਵੇਰ', 'morning');\n    assert.equal(moment([2011, 2, 23, 14, 30]).format('A'), 'ਦੁਪਹਿਰ', ' during day');\n    assert.equal(moment([2011, 2, 23, 17, 30]).format('A'), 'ਸ਼ਾਮ', 'evening');\n    assert.equal(moment([2011, 2, 23, 19, 30]).format('A'), 'ਸ਼ਾਮ', 'late evening');\n    assert.equal(moment([2011, 2, 23, 21, 20]).format('A'), 'ਰਾਤ', 'night');\n});\n\ntest('weeks year starting sunday', function (assert) {\n    assert.equal(moment([2012, 0,  1]).week(), 1, 'Jan  1 2012 should be week 1');\n    assert.equal(moment([2012, 0,  7]).week(), 1, 'Jan  7 2012 should be week 1');\n    assert.equal(moment([2012, 0,  8]).week(), 2, 'Jan  8 2012 should be week 2');\n    assert.equal(moment([2012, 0, 14]).week(), 2, 'Jan 14 2012 should be week 2');\n    assert.equal(moment([2012, 0, 15]).week(), 3, 'Jan 15 2012 should be week 3');\n});\n\ntest('weeks year starting monday', function (assert) {\n    assert.equal(moment([2006, 11, 31]).week(), 1, 'Dec 31 2006 should be week 1');\n    assert.equal(moment([2007,  0,  1]).week(), 1, 'Jan  1 2007 should be week 1');\n    assert.equal(moment([2007,  0,  6]).week(), 1, 'Jan  6 2007 should be week 1');\n    assert.equal(moment([2007,  0,  7]).week(), 2, 'Jan  7 2007 should be week 2');\n    assert.equal(moment([2007,  0, 13]).week(), 2, 'Jan 13 2007 should be week 2');\n    assert.equal(moment([2007,  0, 14]).week(), 3, 'Jan 14 2007 should be week 3');\n});\n\ntest('weeks year starting tuesday', function (assert) {\n    assert.equal(moment([2007, 11, 29]).week(), 52, 'Dec 29 2007 should be week 52');\n    assert.equal(moment([2008,  0,  1]).week(), 1, 'Jan  1 2008 should be week 1');\n    assert.equal(moment([2008,  0,  5]).week(), 1, 'Jan  5 2008 should be week 1');\n    assert.equal(moment([2008,  0,  6]).week(), 2, 'Jan  6 2008 should be week 2');\n    assert.equal(moment([2008,  0, 12]).week(), 2, 'Jan 12 2008 should be week 2');\n    assert.equal(moment([2008,  0, 13]).week(), 3, 'Jan 13 2008 should be week 3');\n});\n\ntest('weeks year starting wednesday', function (assert) {\n    assert.equal(moment([2002, 11, 29]).week(), 1, 'Dec 29 2002 should be week 1');\n    assert.equal(moment([2003,  0,  1]).week(), 1, 'Jan  1 2003 should be week 1');\n    assert.equal(moment([2003,  0,  4]).week(), 1, 'Jan  4 2003 should be week 1');\n    assert.equal(moment([2003,  0,  5]).week(), 2, 'Jan  5 2003 should be week 2');\n    assert.equal(moment([2003,  0, 11]).week(), 2, 'Jan 11 2003 should be week 2');\n    assert.equal(moment([2003,  0, 12]).week(), 3, 'Jan 12 2003 should be week 3');\n});\n\ntest('weeks year starting thursday', function (assert) {\n    assert.equal(moment([2008, 11, 28]).week(), 1, 'Dec 28 2008 should be week 1');\n    assert.equal(moment([2009,  0,  1]).week(), 1, 'Jan  1 2009 should be week 1');\n    assert.equal(moment([2009,  0,  3]).week(), 1, 'Jan  3 2009 should be week 1');\n    assert.equal(moment([2009,  0,  4]).week(), 2, 'Jan  4 2009 should be week 2');\n    assert.equal(moment([2009,  0, 10]).week(), 2, 'Jan 10 2009 should be week 2');\n    assert.equal(moment([2009,  0, 11]).week(), 3, 'Jan 11 2009 should be week 3');\n});\n\ntest('weeks year starting friday', function (assert) {\n    assert.equal(moment([2009, 11, 27]).week(), 1, 'Dec 27 2009 should be week 1');\n    assert.equal(moment([2010,  0,  1]).week(), 1, 'Jan  1 2010 should be week 1');\n    assert.equal(moment([2010,  0,  2]).week(), 1, 'Jan  2 2010 should be week 1');\n    assert.equal(moment([2010,  0,  3]).week(), 2, 'Jan  3 2010 should be week 2');\n    assert.equal(moment([2010,  0,  9]).week(), 2, 'Jan  9 2010 should be week 2');\n    assert.equal(moment([2010,  0, 10]).week(), 3, 'Jan 10 2010 should be week 3');\n});\n\ntest('weeks year starting saturday', function (assert) {\n    assert.equal(moment([2010, 11, 26]).week(), 1, 'Dec 26 2010 should be week 1');\n    assert.equal(moment([2011,  0,  1]).week(), 1, 'Jan  1 2011 should be week 1');\n    assert.equal(moment([2011,  0,  2]).week(), 2, 'Jan  2 2011 should be week 2');\n    assert.equal(moment([2011,  0,  8]).week(), 2, 'Jan  8 2011 should be week 2');\n    assert.equal(moment([2011,  0,  9]).week(), 3, 'Jan  9 2011 should be week 3');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2012, 0,  1]).format('w ww wo'), '੧ ੦੧ ੧', 'Jan  1 2012 should be week 1');\n    assert.equal(moment([2012, 0,  7]).format('w ww wo'), '੧ ੦੧ ੧', 'Jan  7 2012 should be week 1');\n    assert.equal(moment([2012, 0,  8]).format('w ww wo'), '੨ ੦੨ ੨', 'Jan  8 2012 should be week 2');\n    assert.equal(moment([2012, 0, 14]).format('w ww wo'), '੨ ੦੨ ੨', 'Jan 14 2012 should be week 2');\n    assert.equal(moment([2012, 0, 15]).format('w ww wo'), '੩ ੦੩ ੩', 'Jan 15 2012 should be week 3');\n});\n\ntest('lenient day of month ordinal parsing', function (assert) {\n    var i, ordinalStr, testMoment;\n    for (i = 1; i <= 31; ++i) {\n        ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n        testMoment = moment(ordinalStr, 'YYYY MM Do');\n        assert.equal(testMoment.year(), 2014,\n                'lenient day of month ordinal parsing ' + i + ' year check');\n        assert.equal(testMoment.month(), 0,\n                'lenient day of month ordinal parsing ' + i + ' month check');\n        assert.equal(testMoment.date(), i,\n                'lenient day of month ordinal parsing ' + i + ' date check');\n    }\n});\n\ntest('lenient day of month ordinal parsing of number', function (assert) {\n    var i, testMoment;\n    for (i = 1; i <= 31; ++i) {\n        testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n        assert.equal(testMoment.year(), 2014,\n                'lenient day of month ordinal parsing of number ' + i + ' year check');\n        assert.equal(testMoment.month(), 0,\n                'lenient day of month ordinal parsing of number ' + i + ' month check');\n        assert.equal(testMoment.date(), i,\n                'lenient day of month ordinal parsing of number ' + i + ' date check');\n    }\n});\n\ntest('strict day of month ordinal parsing', function (assert) {\n    var i, ordinalStr, testMoment;\n    for (i = 1; i <= 31; ++i) {\n        ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n        testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n        assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n    }\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\n\n\nfunction localeModule (name, lifecycle) {\n    QUnit.module('locale:' + name, {\n        setup : function () {\n            moment.locale(name);\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            moment.locale('en');\n            teardownDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n    defineCommonLocaleTests(name, -1, -1);\n}\n\nlocaleModule('pl');\n\ntest('parse', function (assert) {\n    var tests = 'styczeń stycznia sty_luty lutego lut_marzec marca mar_kwiecień kwietnia kwi_maj maja maj_czerwiec czerwca cze_lipiec lipca lip_sierpień sierpnia sie_wrzesień września wrz_październik października paź_listopad listopada lis_grudzień grudnia gru'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][2], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][2], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][2].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][2].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('parse strict', function (assert) {\n    var tests = 'styczeń stycznia sty_luty lutego lut_marzec marca mar_kwiecień kwietnia kwi_maj maja maj_czerwiec czerwca cze_lipiec lipca lip_sierpień sierpnia sie_wrzesień września wrz_październik października paź_listopad listopada lis_grudzień grudnia gru'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm, true).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][2], 'MMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][2].toLocaleLowerCase(), 'MMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][2].toLocaleUpperCase(), 'MMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, MMMM Do YYYY, h:mm:ss a',      'niedziela, luty 14. 2010, 3:25:50 pm'],\n            ['ddd, hA',                            'ndz, 3PM'],\n            ['M Mo MM MMMM MMM',                   '2 2. 02 luty lut'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14. 14'],\n            ['d do dddd ddd dd',                   '0 0. niedziela ndz Nd'],\n            ['DDD DDDo DDDD',                      '45 45. 045'],\n            ['w wo ww',                            '6 6. 06'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'pm PM'],\n            ['[the] DDDo [day of the year]',       'the 45. day of the year'],\n            ['LTS',                                '15:25:50'],\n            ['L',                                  '14.02.2010'],\n            ['LL',                                 '14 lutego 2010'],\n            ['LLL',                                '14 lutego 2010 15:25'],\n            ['LLLL',                               'niedziela, 14 lutego 2010 15:25'],\n            ['l',                                  '14.2.2010'],\n            ['ll',                                 '14 lut 2010'],\n            ['lll',                                '14 lut 2010 15:25'],\n            ['llll',                               'ndz, 14 lut 2010 15:25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1.', '1.');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2.', '2.');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3.', '3.');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4.', '4.');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5.', '5.');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6.', '6.');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7.', '7.');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8.', '8.');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9.', '9.');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10.', '10.');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11.', '11.');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12.', '12.');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13.', '13.');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14.', '14.');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15.', '15.');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16.', '16.');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17.', '17.');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18.', '18.');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19.', '19.');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20.', '20.');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21.', '21.');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22.', '22.');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23.', '23.');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24.', '24.');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25.', '25.');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26.', '26.');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27.', '27.');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28.', '28.');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29.', '29.');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30.', '30.');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31.', '31.');\n});\n\ntest('format month', function (assert) {\n    var expected = 'styczeń sty_luty lut_marzec mar_kwiecień kwi_maj maj_czerwiec cze_lipiec lip_sierpień sie_wrzesień wrz_październik paź_listopad lis_grudzień gru'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'niedziela ndz Nd_poniedziałek pon Pn_wtorek wt Wt_środa śr Śr_czwartek czw Cz_piątek pt Pt_sobota sob So'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'kilka sekund',  '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'minuta',        '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'minuta',        '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 minuty',      '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 minuty',     '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'godzina',       '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'godzina',       '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 godziny',     '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 godzin',      '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 godzin',     '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  '1 dzień',       '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  '1 dzień',       '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 dni',         '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   '1 dzień',       '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 dni',         '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 dni',        '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'miesiąc',       '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'miesiąc',       '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'miesiąc',       '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 miesiące',    '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 miesiące',    '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 miesiące',    '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'miesiąc',       '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 miesięcy',    '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'rok',           '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 lata',        '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'rok',           '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 lat',         '5 years = 5 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 112}), true), '112 lat',       '112 years = 112 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 122}), true), '122 lata',      '122 years = 122 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 213}), true), '213 lat',       '213 years = 213 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 223}), true), '223 lata',      '223 years = 223 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'za kilka sekund',  'prefix');\n    assert.equal(moment(0).from(30000), 'kilka sekund temu', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'kilka sekund temu',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'za kilka sekund', 'in a few seconds');\n    assert.equal(moment().add({h: 1}).fromNow(), 'za godzinę', 'in an hour');\n    assert.equal(moment().add({d: 5}).fromNow(), 'za 5 dni', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'Dziś o 12:00',    'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'Dziś o 12:25',    'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'Dziś o 13:00',    'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'Jutro o 12:00',   'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'Dziś o 11:00',    'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'Wczoraj o 12:00', 'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('[W] dddd [o] LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[W] dddd [o] LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[W] dddd [o] LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n\n    function makeFormat(d) {\n        switch (d.day()) {\n            case 0:\n                return '[W zeszłą niedzielę o] LT';\n            case 3:\n                return '[W zeszłą środę o] LT';\n            case 6:\n                return '[W zeszłą sobotę o] LT';\n            default:\n                return '[W zeszły] dddd [o] LT';\n        }\n    }\n\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(), m.format(makeFormat(m)), 'Today - ' + i + ' days current time');\n\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(), m.format(makeFormat(m)), 'Today - ' + i + ' days beginning of day');\n\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(), m.format(makeFormat(m)), 'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2012, 0,  1]).format('w ww wo'), '52 52 52.', 'Jan  1 2012 should be week 52');\n    assert.equal(moment([2012, 0,  2]).format('w ww wo'),   '1 01 1.', 'Jan  2 2012 should be week 1');\n    assert.equal(moment([2012, 0,  8]).format('w ww wo'),   '1 01 1.', 'Jan  8 2012 should be week 1');\n    assert.equal(moment([2012, 0,  9]).format('w ww wo'),   '2 02 2.', 'Jan  9 2012 should be week 2');\n    assert.equal(moment([2012, 0, 15]).format('w ww wo'),   '2 02 2.', 'Jan 15 2012 should be week 2');\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\n\n\nfunction localeModule (name, lifecycle) {\n    QUnit.module('locale:' + name, {\n        setup : function () {\n            moment.locale(name);\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            moment.locale('en');\n            teardownDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n    defineCommonLocaleTests(name, -1, -1);\n}\n\nlocaleModule('pt-br');\n\ntest('parse', function (assert) {\n    var tests = 'janeiro jan_fevereiro fev_março mar_abril abr_maio mai_junho jun_julho jul_agosto ago_setembro set_outubro out_novembro nov_dezembro dez'.split('_'), i;\n\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, MMMM Do YYYY, h:mm:ss a',      'Domingo, Fevereiro 14º 2010, 3:25:50 pm'],\n            ['ddd, hA',                            'Dom, 3PM'],\n            ['M Mo MM MMMM MMM',                   '2 2º 02 Fevereiro Fev'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14º 14'],\n            ['d do dddd ddd',                      '0 0º Domingo Dom'],\n            ['DDD DDDo DDDD',                      '45 45º 045'],\n            ['w wo ww',                            '8 8º 08'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'pm PM'],\n            ['[the] DDDo [day of the year]',       'the 45º day of the year'],\n            ['LTS',                                '15:25:50'],\n            ['L',                                  '14/02/2010'],\n            ['LL',                                 '14 de Fevereiro de 2010'],\n            ['LLL',                                '14 de Fevereiro de 2010 às 15:25'],\n            ['LLLL',                               'Domingo, 14 de Fevereiro de 2010 às 15:25'],\n            ['l',                                  '14/2/2010'],\n            ['ll',                                 '14 de Fev de 2010'],\n            ['lll',                                '14 de Fev de 2010 às 15:25'],\n            ['llll',                               'Dom, 14 de Fev de 2010 às 15:25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1º', '1º');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2º', '2º');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3º', '3º');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4º', '4º');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5º', '5º');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6º', '6º');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7º', '7º');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8º', '8º');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9º', '9º');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10º', '10º');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11º', '11º');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12º', '12º');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13º', '13º');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14º', '14º');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15º', '15º');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16º', '16º');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17º', '17º');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18º', '18º');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19º', '19º');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20º', '20º');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21º', '21º');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22º', '22º');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23º', '23º');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24º', '24º');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25º', '25º');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26º', '26º');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27º', '27º');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28º', '28º');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29º', '29º');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30º', '30º');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31º', '31º');\n});\n\ntest('format month', function (assert) {\n    var expected = 'Janeiro Jan_Fevereiro Fev_Março Mar_Abril Abr_Maio Mai_Junho Jun_Julho Jul_Agosto Ago_Setembro Set_Outubro Out_Novembro Nov_Dezembro Dez'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'Domingo Dom Do_Segunda-feira Seg 2ª_Terça-feira Ter 3ª_Quarta-feira Qua 4ª_Quinta-feira Qui 5ª_Sexta-feira Sex 6ª_Sábado Sáb Sá'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'poucos segundos', '44 seconds = seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'um minuto',   '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'um minuto',   '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 minutos',  '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 minutos', '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'uma hora',    '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'uma hora',    '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 horas',    '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 horas',    '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 horas',   '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'um dia',      '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'um dia',      '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 dias',     '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'um dia',      '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 dias',     '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 dias',    '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'um mês',    '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'um mês',    '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'um mês',    '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 meses',   '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 meses',   '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 meses',   '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'um mês',    '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 meses',   '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'um ano',     '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 anos',    '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'um ano',     '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 anos',    '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'em poucos segundos', 'prefix');\n    assert.equal(moment(0).from(30000), 'poucos segundos atrás', 'suffix');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'em poucos segundos', 'in seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), 'em 5 dias', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'Hoje às 12:00',    'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'Hoje às 12:25',    'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'Hoje às 13:00',    'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'Amanhã às 12:00',  'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'Hoje às 11:00',    'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'Ontem às 12:00',   'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('dddd [às] LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd [às] LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd [às] LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format((m.day() === 0 || m.day() === 6) ? '[Último] dddd [às] LT' : '[Última] dddd [às] LT'),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format((m.day() === 0 || m.day() === 6) ? '[Último] dddd [às] LT' : '[Última] dddd [às] LT'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format((m.day() === 0 || m.day() === 6) ? '[Último] dddd [às] LT' : '[Última] dddd [às] LT'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('weeks year starting sunday format', function (assert) {\n    assert.equal(moment([2012, 0,  1]).format('w ww wo'), '1 01 1º', 'Jan  1 2012 should be week 1');\n    assert.equal(moment([2012, 0,  7]).format('w ww wo'), '1 01 1º', 'Jan  7 2012 should be week 1');\n    assert.equal(moment([2012, 0,  8]).format('w ww wo'), '2 02 2º', 'Jan  8 2012 should be week 2');\n    assert.equal(moment([2012, 0, 14]).format('w ww wo'), '2 02 2º', 'Jan 14 2012 should be week 2');\n    assert.equal(moment([2012, 0, 15]).format('w ww wo'), '3 03 3º', 'Jan 15 2012 should be week 3');\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\n\n\nfunction localeModule (name, lifecycle) {\n    QUnit.module('locale:' + name, {\n        setup : function () {\n            moment.locale(name);\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            moment.locale('en');\n            teardownDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n    defineCommonLocaleTests(name, -1, -1);\n}\n\nlocaleModule('pt');\n\ntest('parse', function (assert) {\n    var tests = 'Janeiro Jan_Fevereiro Fev_Março Mar_Abril Abr_Maio Mai_Junho Jun_Julho Jul_Agosto Ago_Setembro Set_Outubro Out_Novembro Nov_Dezembro Dez'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, MMMM Do YYYY, h:mm:ss a',      'Domingo, Fevereiro 14º 2010, 3:25:50 pm'],\n            ['ddd, hA',                            'Dom, 3PM'],\n            ['M Mo MM MMMM MMM',                   '2 2º 02 Fevereiro Fev'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14º 14'],\n            ['d do dddd ddd',                      '0 0º Domingo Dom'],\n            ['DDD DDDo DDDD',                      '45 45º 045'],\n            ['w wo ww',                            '6 6º 06'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'pm PM'],\n            ['[the] DDDo [day of the year]',       'the 45º day of the year'],\n            ['LTS',                                '15:25:50'],\n            ['L',                                  '14/02/2010'],\n            ['LL',                                 '14 de Fevereiro de 2010'],\n            ['LLL',                                '14 de Fevereiro de 2010 15:25'],\n            ['LLLL',                               'Domingo, 14 de Fevereiro de 2010 15:25'],\n            ['l',                                  '14/2/2010'],\n            ['ll',                                 '14 de Fev de 2010'],\n            ['lll',                                '14 de Fev de 2010 15:25'],\n            ['llll',                               'Dom, 14 de Fev de 2010 15:25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1º', '1º');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2º', '2º');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3º', '3º');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4º', '4º');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5º', '5º');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6º', '6º');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7º', '7º');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8º', '8º');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9º', '9º');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10º', '10º');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11º', '11º');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12º', '12º');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13º', '13º');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14º', '14º');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15º', '15º');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16º', '16º');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17º', '17º');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18º', '18º');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19º', '19º');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20º', '20º');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21º', '21º');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22º', '22º');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23º', '23º');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24º', '24º');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25º', '25º');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26º', '26º');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27º', '27º');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28º', '28º');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29º', '29º');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30º', '30º');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31º', '31º');\n});\n\ntest('format month', function (assert) {\n    var expected = 'Janeiro Jan_Fevereiro Fev_Março Mar_Abril Abr_Maio Mai_Junho Jun_Julho Jul_Agosto Ago_Setembro Set_Outubro Out_Novembro Nov_Dezembro Dez'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'Domingo Dom Do_Segunda-Feira Seg 2ª_Terça-Feira Ter 3ª_Quarta-Feira Qua 4ª_Quinta-Feira Qui 5ª_Sexta-Feira Sex 6ª_Sábado Sáb Sá'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'segundos',    '44 seconds = seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'um minuto',   '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'um minuto',   '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 minutos',  '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 minutos', '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'uma hora',    '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'uma hora',    '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 horas',    '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 horas',    '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 horas',   '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'um dia',      '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'um dia',      '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 dias',     '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'um dia',      '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 dias',     '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 dias',    '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'um mês',    '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'um mês',    '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'um mês',    '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 meses',   '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 meses',   '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 meses',   '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'um mês',    '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 meses',   '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'um ano',     '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 anos',    '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'um ano',     '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 anos',    '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'em segundos', 'prefix');\n    assert.equal(moment(0).from(30000), 'há segundos', 'suffix');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'em segundos', 'in seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), 'em 5 dias', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'Hoje às 12:00',    'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'Hoje às 12:25',    'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'Hoje às 13:00',    'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'Amanhã às 12:00',  'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'Hoje às 11:00',    'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'Ontem às 12:00',   'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('dddd [às] LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd [às] LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd [às] LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format((m.day() === 0 || m.day() === 6) ? '[Último] dddd [às] LT' : '[Última] dddd [às] LT'),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format((m.day() === 0 || m.day() === 6) ? '[Último] dddd [às] LT' : '[Última] dddd [às] LT'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format((m.day() === 0 || m.day() === 6) ? '[Último] dddd [às] LT' : '[Última] dddd [às] LT'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2012, 0,  1]).format('w ww wo'), '52 52 52º', 'Jan  1 2012 should be week 52');\n    assert.equal(moment([2012, 0,  2]).format('w ww wo'),  '1 01 1º', 'Jan  2 2012 should be week 1');\n    assert.equal(moment([2012, 0,  8]).format('w ww wo'),  '1 01 1º', 'Jan  8 2012 should be week 1');\n    assert.equal(moment([2012, 0,  9]).format('w ww wo'),  '2 02 2º', 'Jan  9 2012 should be week 2');\n    assert.equal(moment([2012, 0, 15]).format('w ww wo'),  '2 02 2º', 'Jan 15 2012 should be week 2');\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\n\n\nfunction localeModule (name, lifecycle) {\n    QUnit.module('locale:' + name, {\n        setup : function () {\n            moment.locale(name);\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            moment.locale('en');\n            teardownDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n    defineCommonLocaleTests(name, -1, -1);\n}\n\nlocaleModule('ro');\n\ntest('parse', function (assert) {\n    var tests = 'ianuarie ian._februarie febr._martie mart._aprilie apr._mai mai_iunie iun._iulie iul._august aug._septembrie sept._octombrie oct._noiembrie nov._decembrie dec.'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, MMMM Do YYYY, h:mm:ss A',  'duminică, februarie 14 2010, 3:25:50 PM'],\n            ['ddd, hA',                        'Dum, 3PM'],\n            ['M Mo MM MMMM MMM',               '2 2 02 februarie febr.'],\n            ['YYYY YY',                        '2010 10'],\n            ['D Do DD',                        '14 14 14'],\n            ['d do dddd ddd dd',               '0 0 duminică Dum Du'],\n            ['DDD DDDo DDDD',                  '45 45 045'],\n            ['w wo ww',                        '7 7 07'],\n            ['h hh',                           '3 03'],\n            ['H HH',                           '15 15'],\n            ['m mm',                           '25 25'],\n            ['s ss',                           '50 50'],\n            ['a A',                            'pm PM'],\n            ['[a] DDDo[a zi a anului]',        'a 45a zi a anului'],\n            ['LTS',                            '15:25:50'],\n            ['L',                              '14.02.2010'],\n            ['LL',                             '14 februarie 2010'],\n            ['LLL',                            '14 februarie 2010 15:25'],\n            ['LLLL',                           'duminică, 14 februarie 2010 15:25'],\n            ['l',                              '14.2.2010'],\n            ['ll',                             '14 febr. 2010'],\n            ['lll',                            '14 febr. 2010 15:25'],\n            ['llll',                           'Dum, 14 febr. 2010 15:25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1', '1');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2', '2');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3', '3');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4', '4');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5', '5');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6', '6');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7', '7');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8', '8');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9', '9');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10', '10');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11', '11');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12', '12');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13', '13');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14', '14');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15', '15');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16', '16');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17', '17');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18', '18');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19', '19');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20', '20');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21', '21');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22', '22');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23', '23');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24', '24');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25', '25');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26', '26');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27', '27');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28', '28');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29', '29');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30', '30');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31', '31');\n});\n\ntest('format month', function (assert) {\n    var expected = 'ianuarie ian._februarie febr._martie mart._aprilie apr._mai mai_iunie iun._iulie iul._august aug._septembrie sept._octombrie oct._noiembrie nov._decembrie dec.'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'duminică Dum Du_luni Lun Lu_marți Mar Ma_miercuri Mie Mi_joi Joi Jo_vineri Vin Vi_sâmbătă Sâm Sâ'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'câteva secunde', '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'un minut',       '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'un minut',       '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 minute',       '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 de minute',   '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'o oră',          '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'o oră',          '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 ore',          '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 ore',          '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 de ore',      '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'o zi',           '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'o zi',           '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 zile',         '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'o zi',           '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 zile',         '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 de zile',     '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'o lună',         '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'o lună',         '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'o lună',         '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 luni',         '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 luni',         '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 luni',         '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'o lună',         '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 luni',         '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'un an',          '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 ani',          '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'un an',          '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 ani',          '5 years = 5 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 19}), true),   '19 ani',        '19 years = 19 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 20}), true),   '20 de ani',     '20 years = 20 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 100}), true),   '100 de ani',   '100 years = 100 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 101}), true),   '101 ani',      '101 years = 101 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 119}), true),   '119 ani',      '119 years = 119 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 120}), true),   '120 de ani',   '120 years = 120 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 219}), true),   '219 ani',      '219 years = 219 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 220}), true),   '220 de ani',   '220 years = 220 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'peste câteva secunde',   'prefix');\n    assert.equal(moment(0).from(30000), 'câteva secunde în urmă', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'câteva secunde în urmă',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'peste câteva secunde', 'in a few seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), 'peste 5 zile', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'azi la 12:00',     'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'azi la 12:25',     'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'azi la 13:00',     'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'mâine la 12:00',   'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'azi la 11:00',     'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'ieri la 12:00',    'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('dddd [la] LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd [la] LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd [la] LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('[fosta] dddd [la] LT'),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[fosta] dddd [la] LT'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[fosta] dddd [la] LT'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2011, 11, 26]).format('w ww wo'), '1 01 1', 'Dec 26 2011 should be week 1');\n    assert.equal(moment([2012,  0,  1]).format('w ww wo'), '1 01 1', 'Jan  1 2012 should be week 1');\n    assert.equal(moment([2012,  0,  2]).format('w ww wo'), '2 02 2', 'Jan  2 2012 should be week 2');\n    assert.equal(moment([2012,  0,  8]).format('w ww wo'), '2 02 2', 'Jan  8 2012 should be week 2');\n    assert.equal(moment([2012,  0,  9]).format('w ww wo'), '3 03 3', 'Jan  9 2012 should be week 3');\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\n\n\nfunction localeModule (name, lifecycle) {\n    QUnit.module('locale:' + name, {\n        setup : function () {\n            moment.locale(name);\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            moment.locale('en');\n            teardownDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n    defineCommonLocaleTests(name, -1, -1);\n}\n\nlocaleModule('ru');\n\ntest('parse', function (assert) {\n    var tests = 'январь янв._февраль февр._март март_апрель апр._май май_июнь июнь_июль июль_август авг._сентябрь сент._октябрь окт._ноябрь нояб._декабрь дек.'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    function equalTestStrict(input, mmm, monthIndex) {\n        assert.equal(moment(input, mmm, true).month(), monthIndex, input + ' ' + mmm + ' should be strict month ' + (monthIndex + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n\n        equalTestStrict(tests[i][1], 'MMM', i);\n        equalTestStrict(tests[i][0], 'MMMM', i);\n        equalTestStrict(tests[i][1].toLocaleLowerCase(), 'MMM', i);\n        equalTestStrict(tests[i][1].toLocaleUpperCase(), 'MMM', i);\n        equalTestStrict(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTestStrict(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('parse exceptional case', function (assert) {\n    assert.equal(moment('11 Мая 1989', ['DD MMMM YYYY']).format('DD-MM-YYYY'), '11-05-1989');\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, Do MMMM YYYY, HH:mm:ss',       'воскресенье, 14-го февраля 2010, 15:25:50'],\n            ['ddd, h A',                           'вс, 3 дня'],\n            ['M Mo MM MMMM MMM',                   '2 2-й 02 февраль февр.'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14-го 14'],\n            ['d do dddd ddd dd',                   '0 0-й воскресенье вс вс'],\n            ['DDD DDDo DDDD',                      '45 45-й 045'],\n            ['w wo ww',                            '7 7-я 07'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'дня дня'],\n            ['DDDo [день года]',                   '45-й день года'],\n            ['LTS',                                '15:25:50'],\n            ['L',                                  '14.02.2010'],\n            ['LL',                                 '14 февраля 2010 г.'],\n            ['LLL',                                '14 февраля 2010 г., 15:25'],\n            ['LLLL',                               'воскресенье, 14 февраля 2010 г., 15:25'],\n            ['l',                                  '14.2.2010'],\n            ['ll',                                 '14 февр. 2010 г.'],\n            ['lll',                                '14 февр. 2010 г., 15:25'],\n            ['llll',                               'вс, 14 февр. 2010 г., 15:25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format meridiem', function (assert) {\n    assert.equal(moment([2012, 11, 28, 0, 0]).format('A'), 'ночи', 'night');\n    assert.equal(moment([2012, 11, 28, 3, 59]).format('A'), 'ночи', 'night');\n    assert.equal(moment([2012, 11, 28, 4, 0]).format('A'), 'утра', 'morning');\n    assert.equal(moment([2012, 11, 28, 11, 59]).format('A'), 'утра', 'morning');\n    assert.equal(moment([2012, 11, 28, 12, 0]).format('A'), 'дня', 'afternoon');\n    assert.equal(moment([2012, 11, 28, 16, 59]).format('A'), 'дня', 'afternoon');\n    assert.equal(moment([2012, 11, 28, 17, 0]).format('A'), 'вечера', 'evening');\n    assert.equal(moment([2012, 11, 28, 23, 59]).format('A'), 'вечера', 'evening');\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1-й', '1-й');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2-й', '2-й');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3-й', '3-й');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4-й', '4-й');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5-й', '5-й');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6-й', '6-й');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7-й', '7-й');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8-й', '8-й');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9-й', '9-й');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10-й', '10-й');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11-й', '11-й');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12-й', '12-й');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13-й', '13-й');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14-й', '14-й');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15-й', '15-й');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16-й', '16-й');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17-й', '17-й');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18-й', '18-й');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19-й', '19-й');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20-й', '20-й');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21-й', '21-й');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22-й', '22-й');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23-й', '23-й');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24-й', '24-й');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25-й', '25-й');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26-й', '26-й');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27-й', '27-й');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28-й', '28-й');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29-й', '29-й');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30-й', '30-й');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31-й', '31-й');\n});\n\ntest('format month', function (assert) {\n    var expected = 'январь янв._февраль февр._март март_апрель апр._май май_июнь июнь_июль июль_август авг._сентябрь сент._октябрь окт._ноябрь нояб._декабрь дек.'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format month case', function (assert) {\n    var months = {\n        'nominative': 'январь_февраль_март_апрель_май_июнь_июль_август_сентябрь_октябрь_ноябрь_декабрь'.split('_'),\n        'accusative': 'января_февраля_марта_апреля_мая_июня_июля_августа_сентября_октября_ноября_декабря'.split('_')\n    }, i;\n    for (i = 0; i < 12; i++) {\n        assert.equal(moment([2011, i, 1]).format('D MMMM'), '1 ' + months.accusative[i], '1 ' + months.accusative[i]);\n        assert.equal(moment([2011, i, 1]).format('MMMM'), months.nominative[i], '1 ' + months.nominative[i]);\n    }\n});\n\ntest('format month short case', function (assert) {\n    var monthsShort = {\n        'nominative': 'янв._февр._март_апр._май_июнь_июль_авг._сент._окт._нояб._дек.'.split('_'),\n        'accusative': 'янв._февр._мар._апр._мая_июня_июля_авг._сент._окт._нояб._дек.'.split('_')\n    }, i;\n    for (i = 0; i < 12; i++) {\n        assert.equal(moment([2011, i, 1]).format('D MMM'), '1 ' + monthsShort.accusative[i], '1 ' + monthsShort.accusative[i]);\n        assert.equal(moment([2011, i, 1]).format('MMM'), monthsShort.nominative[i], '1 ' + monthsShort.nominative[i]);\n    }\n});\n\ntest('format month case with escaped symbols', function (assert) {\n    var months = {\n        'nominative': 'январь_февраль_март_апрель_май_июнь_июль_август_сентябрь_октябрь_ноябрь_декабрь'.split('_'),\n        'accusative': 'января_февраля_марта_апреля_мая_июня_июля_августа_сентября_октября_ноября_декабря'.split('_')\n    }, i;\n    for (i = 0; i < 12; i++) {\n        assert.equal(moment([2013, i, 1]).format('D[] MMMM'), '1 ' + months.accusative[i], '1 ' + months.accusative[i]);\n        assert.equal(moment([2013, i, 1]).format('[<i>]D[</i>] [<b>]MMMM[</b>]'), '<i>1</i> <b>' + months.accusative[i] + '</b>', '1 <b>' + months.accusative[i] + '</b>');\n        assert.equal(moment([2013, i, 1]).format('D[-й день] MMMM'), '1-й день ' + months.accusative[i], '1-й день ' + months.accusative[i]);\n        assert.equal(moment([2013, i, 1]).format('D, MMMM'), '1, ' + months.nominative[i], '1, ' + months.nominative[i]);\n    }\n});\n\ntest('format month short case with escaped symbols', function (assert) {\n    var monthsShort = {\n        'nominative': 'янв._февр._март_апр._май_июнь_июль_авг._сент._окт._нояб._дек.'.split('_'),\n        'accusative': 'янв._февр._мар._апр._мая_июня_июля_авг._сент._окт._нояб._дек.'.split('_')\n    }, i;\n    for (i = 0; i < 12; i++) {\n        assert.equal(moment([2013, i, 1]).format('D[] MMM'), '1 ' + monthsShort.accusative[i], '1 ' + monthsShort.accusative[i]);\n        assert.equal(moment([2013, i, 1]).format('[<i>]D[</i>] [<b>]MMM[</b>]'), '<i>1</i> <b>' + monthsShort.accusative[i] + '</b>', '1 <b>' + monthsShort.accusative[i] + '</b>');\n        assert.equal(moment([2013, i, 1]).format('D[-й день] MMM'), '1-й день ' + monthsShort.accusative[i], '1-й день ' + monthsShort.accusative[i]);\n        assert.equal(moment([2013, i, 1]).format('D, MMM'), '1, ' + monthsShort.nominative[i], '1, ' + monthsShort.nominative[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'воскресенье вс вс_понедельник пн пн_вторник вт вт_среда ср ср_четверг чт чт_пятница пт пт_суббота сб сб'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'несколько секунд',    '44 seconds = seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'минута',   '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'минута',   '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 минуты',  '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 31}), true),  '31 минута',  '31 minutes = 31 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 минуты', '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'час',    '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'час',    '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 часа',    '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 часов',    '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 час',   '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'день',      '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'день',      '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 дня',     '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'день',      '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 дней',     '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 11}), true),  '11 дней',     '11 days = 11 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 21}), true),  '21 день',     '21 days = 21 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 дней',    '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'месяц',    '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'месяц',    '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'месяц',    '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 месяца',   '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 месяца',   '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 месяца',   '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'месяц',    '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 месяцев',   '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'год',     '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 года',    '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'год',     '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 лет',    '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'через несколько секунд', 'prefix');\n    assert.equal(moment(0).from(30000), 'несколько секунд назад', 'suffix');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'через несколько секунд', 'in seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), 'через 5 дней', 'in 5 days');\n    assert.equal(moment().add({m: 31}).fromNow(), 'через 31 минуту', 'in 31 minutes = in 31 minutes');\n    assert.equal(moment().subtract({m: 31}).fromNow(), '31 минуту назад', '31 minutes ago = 31 minutes ago');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'Сегодня в 12:00',     'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'Сегодня в 12:25',     'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'Сегодня в 13:00',     'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'Завтра в 12:00',      'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'Сегодня в 11:00',     'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'Вчера в 12:00',       'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m, now;\n\n    function makeFormatNext(d) {\n        switch (d.day()) {\n            case 0:\n                return '[В следующее] dddd [в] LT';\n            case 1:\n            case 2:\n            case 4:\n                return '[В следующий] dddd [в] LT';\n            case 3:\n            case 5:\n            case 6:\n                return '[В следующую] dddd [в] LT';\n        }\n    }\n\n    function makeFormatThis(d) {\n        if (d.day() === 2) {\n            return '[Во] dddd [в] LT';\n        }\n        else {\n            return '[В] dddd [в] LT';\n        }\n    }\n\n    now = moment().startOf('week');\n    for (i = 2; i < 7; i++) {\n        m = moment(now).add({d: i});\n        assert.equal(m.calendar(now),       m.format(makeFormatThis(m)),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(now),       m.format(makeFormatThis(m)),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(now),       m.format(makeFormatThis(m)),  'Today + ' + i + ' days end of day');\n    }\n\n    now = moment().endOf('week');\n    for (i = 2; i < 7; i++) {\n        m = moment(now).add({d: i});\n        assert.equal(m.calendar(now),       m.format(makeFormatNext(m)),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(now),       m.format(makeFormatNext(m)),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(now),       m.format(makeFormatNext(m)),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m, now;\n\n    function makeFormatLast(d) {\n        switch (d.day()) {\n            case 0:\n                return '[В прошлое] dddd [в] LT';\n            case 1:\n            case 2:\n            case 4:\n                return '[В прошлый] dddd [в] LT';\n            case 3:\n            case 5:\n            case 6:\n                return '[В прошлую] dddd [в] LT';\n        }\n    }\n\n    function makeFormatThis(d) {\n        if (d.day() === 2) {\n            return '[Во] dddd [в] LT';\n        }\n        else {\n            return '[В] dddd [в] LT';\n        }\n    }\n\n    now = moment().startOf('week');\n    for (i = 2; i < 7; i++) {\n        m = moment(now).subtract({d: i});\n        assert.equal(m.calendar(now),       m.format(makeFormatLast(m)),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(now),       m.format(makeFormatLast(m)),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(now),       m.format(makeFormatLast(m)),  'Today - ' + i + ' days end of day');\n    }\n\n    now = moment().endOf('week');\n    for (i = 2; i < 7; i++) {\n        m = moment(now).subtract({d: i});\n        assert.equal(m.calendar(now),       m.format(makeFormatThis(m)),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(now),       m.format(makeFormatThis(m)),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(now),       m.format(makeFormatThis(m)),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2011, 11, 26]).format('w ww wo'), '1 01 1-я', 'Dec 26 2011 should be week 1');\n    assert.equal(moment([2012,  0,  1]).format('w ww wo'), '1 01 1-я', 'Jan  1 2012 should be week 1');\n    assert.equal(moment([2012,  0,  2]).format('w ww wo'), '2 02 2-я', 'Jan  2 2012 should be week 2');\n    assert.equal(moment([2012,  0,  8]).format('w ww wo'), '2 02 2-я', 'Jan  8 2012 should be week 2');\n    assert.equal(moment([2012,  0,  9]).format('w ww wo'), '3 03 3-я', 'Jan  9 2012 should be week 3');\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\n\n\nfunction localeModule (name, lifecycle) {\n    QUnit.module('locale:' + name, {\n        setup : function () {\n            moment.locale(name);\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            moment.locale('en');\n            teardownDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n    defineCommonLocaleTests(name, -1, -1);\n}\n\nlocaleModule('sd');\n\nvar months = [\n    'جنوري',\n    'فيبروري',\n    'مارچ',\n    'اپريل',\n    'مئي',\n    'جون',\n    'جولاءِ',\n    'آگسٽ',\n    'سيپٽمبر',\n    'آڪٽوبر',\n    'نومبر',\n    'ڊسمبر'\n];\nvar days = [\n    'آچر',\n    'سومر',\n    'اڱارو',\n    'اربع',\n    'خميس',\n    'جمع',\n    'ڇنڇر'\n];\n\ntest('parse', function (assert) {\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (var i = 0; i < 12; i++) {\n        equalTest(months[i], 'MMM', i);\n        equalTest(months[i], 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, MMMM Do YYYY, h:mm:ss a',      'آچر، فيبروري 14 2010، 3:25:50 شام'],\n            ['ddd, hA',                            'آچر، 3شام'],\n            ['M Mo MM MMMM MMM',                   '2 2 02 فيبروري فيبروري'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14 14'],\n            ['d do dddd ddd dd',                   '0 0 آچر آچر آچر'],\n            ['DDD DDDo DDDD',                      '45 45 045'],\n            ['w wo ww',                            '6 6 06'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'شام شام'],\n            ['[سال جو] DDDo[ڏينهن]',       'سال جو 45ڏينهن'],\n            ['LTS',                                '15:25:50'],\n            ['L',                                  '14/02/2010'],\n            ['LL',                                 '14 فيبروري 2010'],\n            ['LLL',                                '14 فيبروري 2010 15:25'],\n            ['LLLL',                               'آچر، 14 فيبروري 2010 15:25'],\n            ['l',                                  '14/2/2010'],\n            ['ll',                                 '14 فيبروري 2010'],\n            ['lll',                                '14 فيبروري 2010 15:25'],\n            ['llll',                               'آچر، 14 فيبروري 2010 15:25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1', '1');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2', '2');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3', '3');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4', '4');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5', '5');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6', '6');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7', '7');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8', '8');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9', '9');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10', '10');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11', '11');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12', '12');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13', '13');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14', '14');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15', '15');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16', '16');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17', '17');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18', '18');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19', '19');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20', '20');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21', '21');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22', '22');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23', '23');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24', '24');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25', '25');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26', '26');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27', '27');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28', '28');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29', '29');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30', '30');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31', '31');\n});\n\ntest('format month', function (assert) {\n    for (var i = 0; i < months.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), months[i] + ' ' + months[i], months[i] + ' ' + months[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    for (var i = 0; i < days.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), days[i] + ' ' + days[i] + ' ' + days[i], days[i] + ' ' + days[i] + ' ' + days[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'چند سيڪنڊ', '44 seconds = چند سيڪنڊ');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'هڪ منٽ',      '45 seconds = هڪ منٽ');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'هڪ منٽ',      '89 seconds = هڪ منٽ');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 منٽ',     '90 seconds = 2 منٽ');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 منٽ',    '44 minutes = 44 منٽ');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'هڪ ڪلاڪ',       '45 minutes = هڪ ڪلاڪ');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'هڪ ڪلاڪ',       '89 minutes = هڪ ڪلاڪ');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 ڪلاڪ',       '90 minutes = 2 ڪلاڪ');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 ڪلاڪ',       '5 hours = 5 ڪلاڪ');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 ڪلاڪ',      '21 hours = 21 ڪلاڪ');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'هڪ ڏينهن',         '22 hours = هڪ ڏينهن');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'هڪ ڏينهن',         '35 hours = هڪ ڏينهن');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 ڏينهن',        '36 hours = 2 ڏينهن');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'هڪ ڏينهن',         '1 day = هڪ ڏينهن');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 ڏينهن',        '5 days = 5 ڏينهن');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 ڏينهن',       '25 days = 25 ڏينهن');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'هڪ مهينو',       '26 days = هڪ مهينو');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'هڪ مهينو',       '30 days = هڪ مهينو');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'هڪ مهينو',       '43 days = هڪ مهينو');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 مهينا',      '46 days = 2 مهينا');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 مهينا',      '75 days = 2 مهينا');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 مهينا',      '76 days = 3 مهينا');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'هڪ مهينو',       '1 month = هڪ مهينو');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 مهينا',      '5 months = 5 مهينا');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'هڪ سال',        '345 days = هڪ سال');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 سال',       '548 days = 2 سال');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'هڪ سال',        '1 year = هڪ سال');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 سال',       '5 years = 5 سال');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'چند سيڪنڊ پوء',  'prefix');\n    assert.equal(moment(0).from(30000), 'چند سيڪنڊ اڳ', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'چند سيڪنڊ اڳ',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'چند سيڪنڊ پوء', 'in a few seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), '5 ڏينهن پوء', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'اڄ 12:00',      'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'اڄ 12:25',      'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'اڄ 13:00',      'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'سڀاڻي 12:00',   'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'اڄ 11:00',      'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'ڪالهه 12:00',  'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('dddd [اڳين هفتي تي] LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd [اڳين هفتي تي] LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd [اڳين هفتي تي] LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('[گزريل هفتي] dddd [تي] LT'),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[گزريل هفتي] dddd [تي] LT'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[گزريل هفتي] dddd [تي] LT'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2012, 0,  1]).format('w ww wo'), '52 52 52', 'Jan  1 2012 should be week 52');\n    assert.equal(moment([2012, 0,  2]).format('w ww wo'),   '1 01 1', 'Jan  2 2012 should be week 1');\n    assert.equal(moment([2012, 0,  8]).format('w ww wo'),   '1 01 1', 'Jan  8 2012 should be week 1');\n    assert.equal(moment([2012, 0,  9]).format('w ww wo'),   '2 02 2', 'Jan  9 2012 should be week 2');\n    assert.equal(moment([2012, 0, 15]).format('w ww wo'),   '2 02 2', 'Jan 15 2012 should be week 2');\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\n\n\nfunction localeModule (name, lifecycle) {\n    QUnit.module('locale:' + name, {\n        setup : function () {\n            moment.locale(name);\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            moment.locale('en');\n            teardownDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n    defineCommonLocaleTests(name, -1, -1);\n}\n\nlocaleModule('se');\n\ntest('parse', function (assert) {\n    var i,\n        tests = 'ođđajagemánnu ođđj_guovvamánnu guov_njukčamánnu njuk_cuoŋománnu cuo_miessemánnu mies_geassemánnu geas_suoidnemánnu suoi_borgemánnu borg_čakčamánnu čakč_golggotmánnu golg_skábmamánnu skáb_juovlamánnu juov'.split('_');\n\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, MMMM Do YYYY, h:mm:ss a',      'sotnabeaivi, guovvamánnu 14. 2010, 3:25:50 pm'],\n            ['ddd, hA',                            'sotn, 3PM'],\n            ['M Mo MM MMMM MMM',                   '2 2. 02 guovvamánnu guov'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14. 14'],\n            ['d do dddd ddd dd',                   '0 0. sotnabeaivi sotn s'],\n            ['DDD DDDo DDDD',                      '45 45. 045'],\n            ['w wo ww',                            '6 6. 06'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'pm PM'],\n            ['[jagi] DDDo [beaivi]',               'jagi 45. beaivi'],\n            ['LTS',                                '15:25:50'],\n            ['L',                                  '14.02.2010'],\n            ['LL',                                 'guovvamánnu 14. b. 2010'],\n            ['LLL',                                'guovvamánnu 14. b. 2010 ti. 15:25'],\n            ['LLLL',                               'sotnabeaivi, guovvamánnu 14. b. 2010 ti. 15:25'],\n            ['l',                                  '14.2.2010'],\n            ['ll',                                 'guov 14. b. 2010'],\n            ['lll',                                'guov 14. b. 2010 ti. 15:25'],\n            ['llll',                               'sotn, guov 14. b. 2010 ti. 15:25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1.', '1.');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2.', '2.');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3.', '3.');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4.', '4.');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5.', '5.');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6.', '6.');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7.', '7.');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8.', '8.');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9.', '9.');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10.', '10.');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11.', '11.');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12.', '12.');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13.', '13.');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14.', '14.');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15.', '15.');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16.', '16.');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17.', '17.');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18.', '18.');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19.', '19.');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20.', '20.');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21.', '21.');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22.', '22.');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23.', '23.');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24.', '24.');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25.', '25.');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26.', '26.');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27.', '27.');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28.', '28.');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29.', '29.');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30.', '30.');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31.', '31.');\n});\n\ntest('format month', function (assert) {\n    var i,\n        expected = 'ođđajagemánnu ođđj_guovvamánnu guov_njukčamánnu njuk_cuoŋománnu cuo_miessemánnu mies_geassemánnu geas_suoidnemánnu suoi_borgemánnu borg_čakčamánnu čakč_golggotmánnu golg_skábmamánnu skáb_juovlamánnu juov'.split('_');\n\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var i,\n        expected = 'sotnabeaivi sotn s_vuossárga vuos v_maŋŋebárga maŋ m_gaskavahkku gask g_duorastat duor d_bearjadat bear b_lávvardat láv L'.split('_');\n\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'moadde sekunddat', '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'okta minuhta',  '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'okta minuhta',  '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 minuhtat',    '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 minuhtat',   '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'okta diimmu',   '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'okta diimmu',   '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 diimmut',     '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 diimmut',     '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 diimmut',    '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'okta beaivi',   '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'okta beaivi',   '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 beaivvit',    '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'okta beaivi',   '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 beaivvit',    '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 beaivvit',   '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'okta mánnu',    '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'okta mánnu',    '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'okta mánnu',    '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 mánut',       '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 mánut',       '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 mánut',       '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'okta mánnu',    '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 mánut',       '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'okta jahki',    '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 jagit',       '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'okta jahki',    '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 jagit',       '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'moadde sekunddat geažes',  'prefix');\n    assert.equal(moment(0).from(30000), 'maŋit moadde sekunddat', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'maŋit moadde sekunddat',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'moadde sekunddat geažes', 'in a few seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), '5 beaivvit geažes', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'otne ti 12:00',     'Today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'otne ti 12:25',     'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'otne ti 13:00',     'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'ihttin ti 12:00',   'Tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'otne ti 11:00',     'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'ikte ti 12:00',     'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('dddd [ti] LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd [ti] LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd [ti] LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('[ovddit] dddd [ti] LT'),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[ovddit] dddd [ti] LT'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[ovddit] dddd [ti] LT'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2012, 0,  1]).format('w ww wo'), '52 52 52.', 'Jan  1 2012 should be week 52');\n    assert.equal(moment([2012, 0,  2]).format('w ww wo'),  '1 01 1.', 'Jan  2 2012 should be week 1');\n    assert.equal(moment([2012, 0,  8]).format('w ww wo'),  '1 01 1.', 'Jan  8 2012 should be week 1');\n    assert.equal(moment([2012, 0,  9]).format('w ww wo'),  '2 02 2.', 'Jan  9 2012 should be week 2');\n    assert.equal(moment([2012, 0, 15]).format('w ww wo'),  '2 02 2.', 'Jan 15 2012 should be week 2');\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\n\n\nfunction localeModule (name, lifecycle) {\n    QUnit.module('locale:' + name, {\n        setup : function () {\n            moment.locale(name);\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            moment.locale('en');\n            teardownDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n    defineCommonLocaleTests(name, -1, -1);\n}\n\nlocaleModule('si');\n\n/*jshint -W100*/\ntest('parse', function (assert) {\n    var tests = 'ජනවාරි ජන_පෙබරවාරි පෙබ_මාර්තු මාර්_අප්‍රේල් අප්_මැයි මැයි_ජූනි ජූනි_ජූලි ජූලි_අගෝස්තු අගෝ_සැප්තැම්බර් සැප්_ඔක්තෝබර් ඔක්_නොවැම්බර් නොවැ_දෙසැම්බර් දෙසැ'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['YYYY MMMM Do dddd, a h:mm:ss',       '2010 පෙබරවාරි 14 වැනි ඉරිදා, ප.ව. 3:25:50'],\n            ['YYYY MMMM Do dddd, a h:mm:ss',       '2010 පෙබරවාරි 14 වැනි ඉරිදා, ප.ව. 3:25:50'],\n            ['ddd, A h',                            'ඉරි, පස් වරු 3'],\n            ['M Mo MM MMMM MMM',                   '2 2 වැනි 02 පෙබරවාරි පෙබ'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14 වැනි 14'],\n            ['d do dddd ddd dd',                   '0 0 වැනි ඉරිදා ඉරි ඉ'],\n            ['DDD DDDo DDDD',                      '45 45 වැනි 045'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'ප.ව. පස් වරු'],\n            ['[වසරේ] DDDo [දිනය]',                      'වසරේ 45 වැනි දිනය'],\n            ['LTS',                                'ප.ව. 3:25:50'],\n            ['LT',                                 'ප.ව. 3:25'],\n            ['L',                                  '2010/02/14'],\n            ['LL',                                 '2010 පෙබරවාරි 14'],\n            ['LLL',                                '2010 පෙබරවාරි 14, ප.ව. 3:25'],\n            ['LLLL',                               '2010 පෙබරවාරි 14 වැනි ඉරිදා, ප.ව. 3:25:50'],\n            ['l',                                  '2010/2/14'],\n            ['ll',                                 '2010 පෙබ 14'],\n            ['lll',                                '2010 පෙබ 14, ප.ව. 3:25'],\n            ['llll',                               '2010 පෙබ 14 වැනි ඉරි, ප.ව. 3:25:50']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1 වැනි', '1 වැනි');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2 වැනි', '2 වැනි');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3 වැනි', '3 වැනි');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4 වැනි', '4 වැනි');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5 වැනි', '5 වැනි');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6 වැනි', '6 වැනි');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7 වැනි', '7 වැනි');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8 වැනි', '8 වැනි');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9 වැනි', '9 වැනි');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10 වැනි', '10 වැනි');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11 වැනි', '11 වැනි');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12 වැනි', '12 වැනි');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13 වැනි', '13 වැනි');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14 වැනි', '14 වැනි');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15 වැනි', '15 වැනි');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16 වැනි', '16 වැනි');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17 වැනි', '17 වැනි');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18 වැනි', '18 වැනි');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19 වැනි', '19 වැනි');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20 වැනි', '20 වැනි');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21 වැනි', '21 වැනි');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22 වැනි', '22 වැනි');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23 වැනි', '23 වැනි');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24 වැනි', '24 වැනි');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25 වැනි', '25 වැනි');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26 වැනි', '26 වැනි');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27 වැනි', '27 වැනි');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28 වැනි', '28 වැනි');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29 වැනි', '29 වැනි');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30 වැනි', '30 වැනි');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31 වැනි', '31 වැනි');\n});\n\ntest('format month', function (assert) {\n    var expected = 'ජනවාරි ජන_පෙබරවාරි පෙබ_මාර්තු මාර්_අප්‍රේල් අප්_මැයි මැයි_ජූනි ජූනි_ජූලි ජූලි_අගෝස්තු අගෝ_සැප්තැම්බර් සැප්_ඔක්තෝබර් ඔක්_නොවැම්බර් නොවැ_දෙසැම්බර් දෙසැ'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'ඉරිදා ඉරි ඉ_සඳුදා සඳු ස_අඟහරුවාදා අඟ අ_බදාදා බදා බ_බ්‍රහස්පතින්දා බ්‍රහ බ්‍ර_සිකුරාදා සිකු සි_සෙනසුරාදා සෙන සෙ'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'තත්පර කිහිපය', '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'මිනිත්තුව',      '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'මිනිත්තුව',      '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  'මිනිත්තු 2',     '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  'මිනිත්තු 44',    '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'පැය',       '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'පැය',       '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  'පැය 2',       '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   'පැය 5',       '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  'පැය 21',      '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'දිනය',         '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'දිනය',         '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  'දින 2',        '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'දිනය',         '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   'දින 5',        '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  'දින 25',       '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'මාසය',       '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'මාසය',       '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'මාසය',       '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  'මාස 2',      '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  'මාස 2',      '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  'මාස 3',      '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'මාසය',       '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   'මාස 5',      '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'වසර',        '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), 'වසර 2',       '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'වසර',        '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   'වසර 5',       '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'තත්පර කිහිපයකින්',  'prefix');\n    assert.equal(moment(0).from(30000), 'තත්පර කිහිපයකට පෙර', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'තත්පර කිහිපයකට පෙර',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'තත්පර කිහිපයකින්', 'in a few seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), 'දින 5කින්', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'අද ප.ව. 12:00ට',     'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'අද ප.ව. 12:25ට',     'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'අද ප.ව. 1:00ට',      'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'හෙට ප.ව. 12:00ට',   'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'අද පෙ.ව. 11:00ට',    'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'ඊයේ ප.ව. 12:00ට',   'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('dddd LT[ට]'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd LT[ට]'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd LT[ට]'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('[පසුගිය] dddd LT[ට]'),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[පසුගිය] dddd LT[ට]'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[පසුගිය] dddd LT[ට]'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\n\n\nfunction localeModule (name, lifecycle) {\n    QUnit.module('locale:' + name, {\n        setup : function () {\n            moment.locale(name);\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            moment.locale('en');\n            teardownDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n    defineCommonLocaleTests(name, -1, -1);\n}\n\nlocaleModule('sk');\n\ntest('parse', function (assert) {\n    var tests = 'január jan._február feb._marec mar._apríl apr._máj máj_jún jún._júl júl._august aug._september sep._október okt._november nov._december dec.'.split('_'), i;\n    function equalTest(input, mmm, monthIndex) {\n        assert.equal(moment(input, mmm).month(), monthIndex, input + ' should be month ' + (monthIndex + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, MMMM Do YYYY, h:mm:ss',  'nedeľa, február 14. 2010, 3:25:50'],\n            ['ddd, h',                       'ne, 3'],\n            ['M Mo MM MMMM MMM',             '2 2. 02 február feb'],\n            ['YYYY YY',                      '2010 10'],\n            ['D Do DD',                      '14 14. 14'],\n            ['d do dddd ddd dd',             '0 0. nedeľa ne ne'],\n            ['DDD DDDo DDDD',                '45 45. 045'],\n            ['w wo ww',                      '6 6. 06'],\n            ['h hh',                         '3 03'],\n            ['H HH',                         '15 15'],\n            ['m mm',                         '25 25'],\n            ['s ss',                         '50 50'],\n            ['a A',                          'pm PM'],\n            ['DDDo [deň v roku]',            '45. deň v roku'],\n            ['LTS',                          '15:25:50'],\n            ['L',                            '14.02.2010'],\n            ['LL',                           '14. február 2010'],\n            ['LLL',                          '14. február 2010 15:25'],\n            ['LLLL',                         'nedeľa 14. február 2010 15:25'],\n            ['l',                            '14.2.2010'],\n            ['ll',                           '14. feb 2010'],\n            ['lll',                          '14. feb 2010 15:25'],\n            ['llll',                         'ne 14. feb 2010 15:25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1.', '1.');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2.', '2.');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3.', '3.');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4.', '4.');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5.', '5.');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6.', '6.');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7.', '7.');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8.', '8.');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9.', '9.');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10.', '10.');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11.', '11.');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12.', '12.');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13.', '13.');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14.', '14.');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15.', '15.');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16.', '16.');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17.', '17.');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18.', '18.');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19.', '19.');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20.', '20.');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21.', '21.');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22.', '22.');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23.', '23.');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24.', '24.');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25.', '25.');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26.', '26.');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27.', '27.');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28.', '28.');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29.', '29.');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30.', '30.');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31.', '31.');\n});\n\ntest('format month', function (assert) {\n    var expected = 'január jan_február feb_marec mar_apríl apr_máj máj_jún jún_júl júl_august aug_september sep_október okt_november nov_december dec'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'nedeľa ne ne_pondelok po po_utorok ut ut_streda st st_štvrtok št št_piatok pi pi_sobota so so'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'pár sekúnd',  '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'minúta',        '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'minúta',        '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 minúty',      '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 minút',     '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'hodina',       '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'hodina',       '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 hodiny',     '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 hodín',      '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 hodín',     '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'deň',       '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'deň',       '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 dni',         '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'deň',       '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 dní',         '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 dní',        '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'mesiac',       '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'mesiac',       '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'mesiac',       '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 mesiace',    '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 mesiace',    '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 mesiace',    '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'mesiac',       '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 mesiacov',    '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'rok',           '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 roky',        '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'rok',           '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 rokov',         '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'za pár sekúnd',  'prefix');\n    assert.equal(moment(0).from(30000), 'pred pár sekundami', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'pred pár sekundami',  'now from now should display as in the past');\n});\n\ntest('fromNow (future)', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'za pár sekúnd', 'in a few seconds');\n    assert.equal(moment().add({m: 1}).fromNow(), 'za minútu', 'in a minute');\n    assert.equal(moment().add({m: 3}).fromNow(), 'za 3 minúty', 'in 3 minutes');\n    assert.equal(moment().add({m: 10}).fromNow(), 'za 10 minút', 'in 10 minutes');\n    assert.equal(moment().add({h: 1}).fromNow(), 'za hodinu', 'in an hour');\n    assert.equal(moment().add({h: 3}).fromNow(), 'za 3 hodiny', 'in 3 hours');\n    assert.equal(moment().add({h: 10}).fromNow(), 'za 10 hodín', 'in 10 hours');\n    assert.equal(moment().add({d: 1}).fromNow(), 'za deň', 'in a day');\n    assert.equal(moment().add({d: 3}).fromNow(), 'za 3 dni', 'in 3 days');\n    assert.equal(moment().add({d: 10}).fromNow(), 'za 10 dní', 'in 10 days');\n    assert.equal(moment().add({M: 1}).fromNow(), 'za mesiac', 'in a month');\n    assert.equal(moment().add({M: 3}).fromNow(), 'za 3 mesiace', 'in 3 months');\n    assert.equal(moment().add({M: 10}).fromNow(), 'za 10 mesiacov', 'in 10 months');\n    assert.equal(moment().add({y: 1}).fromNow(), 'za rok', 'in a year');\n    assert.equal(moment().add({y: 3}).fromNow(), 'za 3 roky', 'in 3 years');\n    assert.equal(moment().add({y: 10}).fromNow(), 'za 10 rokov', 'in 10 years');\n});\n\ntest('fromNow (past)', function (assert) {\n    assert.equal(moment().subtract({s: 30}).fromNow(), 'pred pár sekundami', 'a few seconds ago');\n    assert.equal(moment().subtract({m: 1}).fromNow(), 'pred minútou', 'a minute ago');\n    assert.equal(moment().subtract({m: 3}).fromNow(), 'pred 3 minútami', '3 minutes ago');\n    assert.equal(moment().subtract({m: 10}).fromNow(), 'pred 10 minútami', '10 minutes ago');\n    assert.equal(moment().subtract({h: 1}).fromNow(), 'pred hodinou', 'an hour ago');\n    assert.equal(moment().subtract({h: 3}).fromNow(), 'pred 3 hodinami', '3 hours ago');\n    assert.equal(moment().subtract({h: 10}).fromNow(), 'pred 10 hodinami', '10 hours ago');\n    assert.equal(moment().subtract({d: 1}).fromNow(), 'pred dňom', 'a day ago');\n    assert.equal(moment().subtract({d: 3}).fromNow(), 'pred 3 dňami', '3 days ago');\n    assert.equal(moment().subtract({d: 10}).fromNow(), 'pred 10 dňami', '10 days ago');\n    assert.equal(moment().subtract({M: 1}).fromNow(), 'pred mesiacom', 'a month ago');\n    assert.equal(moment().subtract({M: 3}).fromNow(), 'pred 3 mesiacmi', '3 months ago');\n    assert.equal(moment().subtract({M: 10}).fromNow(), 'pred 10 mesiacmi', '10 months ago');\n    assert.equal(moment().subtract({y: 1}).fromNow(), 'pred rokom', 'a year ago');\n    assert.equal(moment().subtract({y: 3}).fromNow(), 'pred 3 rokmi', '3 years ago');\n    assert.equal(moment().subtract({y: 10}).fromNow(), 'pred 10 rokmi', '10 years ago');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'dnes o 12:00',     'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'dnes o 12:25',     'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'dnes o 13:00',     'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'zajtra o 12:00',   'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'dnes o 11:00',     'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'včera o 12:00',    'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m, nextDay;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        nextDay = '';\n        switch (m.day()) {\n            case 0:\n                nextDay = 'v nedeľu';\n                break;\n            case 1:\n                nextDay = 'v pondelok';\n                break;\n            case 2:\n                nextDay = 'v utorok';\n                break;\n            case 3:\n                nextDay = 'v stredu';\n                break;\n            case 4:\n                nextDay = 'vo štvrtok';\n                break;\n            case 5:\n                nextDay = 'v piatok';\n                break;\n            case 6:\n                nextDay = 'v sobotu';\n                break;\n        }\n        assert.equal(m.calendar(),       m.format('[' + nextDay + '] [o] LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[' + nextDay + '] [o] LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[' + nextDay + '] [o] LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m, lastDay;\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        lastDay = '';\n        switch (m.day()) {\n            case 0:\n                lastDay = 'minulú nedeľu';\n                break;\n            case 1:\n                lastDay = 'minulý pondelok';\n                break;\n            case 2:\n                lastDay = 'minulý utorok';\n                break;\n            case 3:\n                lastDay = 'minulú stredu';\n                break;\n            case 4:\n                lastDay = 'minulý štvrtok';\n                break;\n            case 5:\n                lastDay = 'minulý piatok';\n                break;\n            case 6:\n                lastDay = 'minulú sobotu';\n                break;\n        }\n        assert.equal(m.calendar(),       m.format('[' + lastDay + '] [o] LT'),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[' + lastDay + '] [o] LT'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[' + lastDay + '] [o] LT'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('humanize duration', function (assert) {\n    assert.equal(moment.duration(1, 'minutes').humanize(), 'minúta', 'a minute (future)');\n    assert.equal(moment.duration(1, 'minutes').humanize(true), 'za minútu', 'in a minute');\n    assert.equal(moment.duration(-1, 'minutes').humanize(), 'minúta', 'a minute (past)');\n    assert.equal(moment.duration(-1, 'minutes').humanize(true), 'pred minútou', 'a minute ago');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2012, 0,  1]).format('w ww wo'), '52 52 52.', 'Jan  1 2012 should be week 52');\n    assert.equal(moment([2012, 0,  2]).format('w ww wo'),   '1 01 1.', 'Jan  2 2012 should be week 1');\n    assert.equal(moment([2012, 0,  8]).format('w ww wo'),   '1 01 1.', 'Jan  8 2012 should be week 1');\n    assert.equal(moment([2012, 0,  9]).format('w ww wo'),   '2 02 2.', 'Jan  9 2012 should be week 2');\n    assert.equal(moment([2012, 0, 15]).format('w ww wo'),   '2 02 2.', 'Jan 15 2012 should be week 2');\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\n\n\nfunction localeModule (name, lifecycle) {\n    QUnit.module('locale:' + name, {\n        setup : function () {\n            moment.locale(name);\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            moment.locale('en');\n            teardownDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n    defineCommonLocaleTests(name, -1, -1);\n}\n\nlocaleModule('sl');\n\ntest('parse', function (assert) {\n    var tests = 'januar jan._februar feb._marec mar._april apr._maj maj_junij jun._julij jul._avgust avg._september sep._oktober okt._november nov._december dec.'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, Do MMMM YYYY, h:mm:ss a',      'nedelja, 14. februar 2010, 3:25:50 pm'],\n            ['ddd, hA',                            'ned., 3PM'],\n            ['M Mo MM MMMM MMM',                   '2 2. 02 februar feb.'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14. 14'],\n            ['d do dddd ddd dd',                   '0 0. nedelja ned. ne'],\n            ['DDD DDDo DDDD',                      '45 45. 045'],\n            ['w wo ww',                            '7 7. 07'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'pm PM'],\n            ['[the] DDDo [day of the year]',       'the 45. day of the year'],\n            ['LTS',                                '15:25:50'],\n            ['L',                                  '14.02.2010'],\n            ['LL',                                 '14. februar 2010'],\n            ['LLL',                                '14. februar 2010 15:25'],\n            ['LLLL',                               'nedelja, 14. februar 2010 15:25'],\n            ['l',                                  '14.2.2010'],\n            ['ll',                                 '14. feb. 2010'],\n            ['lll',                                '14. feb. 2010 15:25'],\n            ['llll',                               'ned., 14. feb. 2010 15:25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1.', '1.');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2.', '2.');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3.', '3.');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4.', '4.');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5.', '5.');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6.', '6.');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7.', '7.');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8.', '8.');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9.', '9.');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10.', '10.');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11.', '11.');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12.', '12.');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13.', '13.');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14.', '14.');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15.', '15.');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16.', '16.');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17.', '17.');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18.', '18.');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19.', '19.');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20.', '20.');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21.', '21.');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22.', '22.');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23.', '23.');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24.', '24.');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25.', '25.');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26.', '26.');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27.', '27.');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28.', '28.');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29.', '29.');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30.', '30.');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31.', '31.');\n});\n\ntest('format month', function (assert) {\n    var expected = 'januar jan._februar feb._marec mar._april apr._maj maj._junij jun._julij jul._avgust avg._september sep._oktober okt._november nov._december dec.'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'nedelja ned. ne_ponedeljek pon. po_torek tor. to_sreda sre. sr_četrtek čet. če_petek pet. pe_sobota sob. so'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'nekaj sekund', '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'ena minuta',   '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'ena minuta',   '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 minuti',     '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 minut',     '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'ena ura',      '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'ena ura',      '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 uri',        '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 ur',         '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 ur',        '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'en dan',       '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'en dan',       '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 dni',        '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'en dan',       '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 dni',        '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 dni',       '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'en mesec',     '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'en mesec',     '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'en mesec',     '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 meseca',     '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 meseca',     '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 mesece',     '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'en mesec',     '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 mesecev',    '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'eno leto',     '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 leti',       '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'eno leto',     '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 let',        '5 years = 5 years');\n\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 1}), true),  'ena minuta', 'a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 2}), true),  '2 minuti',   '2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 3}), true),  '3 minute',   '3 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 4}), true),  '4 minute',   '4 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 5}), true),  '5 minut',    '5 minutes');\n\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 1}), true),  'ena ura', 'an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 2}), true),  '2 uri',   '2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 3}), true),  '3 ure',   '3 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 4}), true),  '4 ure',   '4 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),  '5 ur',    '5 hours');\n\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),  'en dan', 'a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 2}), true),  '2 dni',  '2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 3}), true),  '3 dni',  '3 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 4}), true),  '4 dni',  '4 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),  '5 dni',  '5 days');\n\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),  'en mesec',  'a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 2}), true),  '2 meseca',  '2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 3}), true),  '3 mesece',  '3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 4}), true),  '4 mesece',  '4 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),  '5 mesecev', '5 months');\n\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),  'eno leto', 'a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 2}), true),  '2 leti',   '2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 3}), true),  '3 leta',   '3 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 4}), true),  '4 leta',   '4 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),  '5 let',    '5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'čez nekaj sekund',  'prefix');\n    assert.equal(moment(0).from(30000), 'pred nekaj sekundami', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'pred nekaj sekundami',  'now from now should display as in the past');\n});\n\ntest('fromNow (future)', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'čez nekaj sekund', 'in a few seconds');\n    assert.equal(moment().add({m: 1}).fromNow(),  'čez eno minuto', 'in a minute');\n    assert.equal(moment().add({m: 2}).fromNow(),  'čez 2 minuti',   'in 2 minutes');\n    assert.equal(moment().add({m: 3}).fromNow(),  'čez 3 minute',   'in 3 minutes');\n    assert.equal(moment().add({m: 4}).fromNow(),  'čez 4 minute',   'in 4 minutes');\n    assert.equal(moment().add({m: 5}).fromNow(),  'čez 5 minut',    'in 5 minutes');\n\n    assert.equal(moment().add({h: 1}).fromNow(),  'čez eno uro', 'in an hour');\n    assert.equal(moment().add({h: 2}).fromNow(),  'čez 2 uri',   'in 2 hours');\n    assert.equal(moment().add({h: 3}).fromNow(),  'čez 3 ure',   'in 3 hours');\n    assert.equal(moment().add({h: 4}).fromNow(),  'čez 4 ure',   'in 4 hours');\n    assert.equal(moment().add({h: 5}).fromNow(),  'čez 5 ur',    'in 5 hours');\n\n    assert.equal(moment().add({d: 1}).fromNow(),  'čez en dan', 'in a day');\n    assert.equal(moment().add({d: 2}).fromNow(),  'čez 2 dni',  'in 2 days');\n    assert.equal(moment().add({d: 3}).fromNow(),  'čez 3 dni',  'in 3 days');\n    assert.equal(moment().add({d: 4}).fromNow(),  'čez 4 dni',  'in 4 days');\n    assert.equal(moment().add({d: 5}).fromNow(),  'čez 5 dni',  'in 5 days');\n\n    assert.equal(moment().add({M: 1}).fromNow(),  'čez en mesec',  'in a month');\n    assert.equal(moment().add({M: 2}).fromNow(),  'čez 2 meseca',  'in 2 months');\n    assert.equal(moment().add({M: 3}).fromNow(),  'čez 3 mesece',  'in 3 months');\n    assert.equal(moment().add({M: 4}).fromNow(),  'čez 4 mesece',  'in 4 months');\n    assert.equal(moment().add({M: 5}).fromNow(),  'čez 5 mesecev', 'in 5 months');\n\n    assert.equal(moment().add({y: 1}).fromNow(),  'čez eno leto', 'in a year');\n    assert.equal(moment().add({y: 2}).fromNow(),  'čez 2 leti',   'in 2 years');\n    assert.equal(moment().add({y: 3}).fromNow(),  'čez 3 leta',   'in 3 years');\n    assert.equal(moment().add({y: 4}).fromNow(),  'čez 4 leta',   'in 4 years');\n    assert.equal(moment().add({y: 5}).fromNow(),  'čez 5 let',    'in 5 years');\n\n    assert.equal(moment().subtract({s: 30}).fromNow(), 'pred nekaj sekundami', 'a few seconds ago');\n\n    assert.equal(moment().subtract({m: 1}).fromNow(),  'pred eno minuto', 'a minute ago');\n    assert.equal(moment().subtract({m: 2}).fromNow(),  'pred 2 minutama', '2 minutes ago');\n    assert.equal(moment().subtract({m: 3}).fromNow(),  'pred 3 minutami', '3 minutes ago');\n    assert.equal(moment().subtract({m: 4}).fromNow(),  'pred 4 minutami', '4 minutes ago');\n    assert.equal(moment().subtract({m: 5}).fromNow(),  'pred 5 minutami', '5 minutes ago');\n\n    assert.equal(moment().subtract({h: 1}).fromNow(),  'pred eno uro', 'an hour ago');\n    assert.equal(moment().subtract({h: 2}).fromNow(),  'pred 2 urama', '2 hours ago');\n    assert.equal(moment().subtract({h: 3}).fromNow(),  'pred 3 urami', '3 hours ago');\n    assert.equal(moment().subtract({h: 4}).fromNow(),  'pred 4 urami', '4 hours ago');\n    assert.equal(moment().subtract({h: 5}).fromNow(),  'pred 5 urami', '5 hours ago');\n\n    assert.equal(moment().subtract({d: 1}).fromNow(),  'pred enim dnem', 'a day ago');\n    assert.equal(moment().subtract({d: 2}).fromNow(),  'pred 2 dnevoma', '2 days ago');\n    assert.equal(moment().subtract({d: 3}).fromNow(),  'pred 3 dnevi',   '3 days ago');\n    assert.equal(moment().subtract({d: 4}).fromNow(),  'pred 4 dnevi',   '4 days ago');\n    assert.equal(moment().subtract({d: 5}).fromNow(),  'pred 5 dnevi',   '5 days ago');\n\n    assert.equal(moment().subtract({M: 1}).fromNow(),  'pred enim mesecem', 'a month ago');\n    assert.equal(moment().subtract({M: 2}).fromNow(),  'pred 2 mesecema',   '2 months ago');\n    assert.equal(moment().subtract({M: 3}).fromNow(),  'pred 3 meseci',     '3 months ago');\n    assert.equal(moment().subtract({M: 4}).fromNow(),  'pred 4 meseci',     '4 months ago');\n    assert.equal(moment().subtract({M: 5}).fromNow(),  'pred 5 meseci',     '5 months ago');\n\n    assert.equal(moment().subtract({y: 1}).fromNow(),  'pred enim letom', 'a year ago');\n    assert.equal(moment().subtract({y: 2}).fromNow(),  'pred 2 letoma',   '2 years ago');\n    assert.equal(moment().subtract({y: 3}).fromNow(),  'pred 3 leti',     '3 years ago');\n    assert.equal(moment().subtract({y: 4}).fromNow(),  'pred 4 leti',     '4 years ago');\n    assert.equal(moment().subtract({y: 5}).fromNow(),  'pred 5 leti',     '5 years ago');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'danes ob 12:00',  'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'danes ob 12:25',  'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'danes ob 13:00',  'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'jutri ob 12:00',  'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'danes ob 11:00',  'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'včeraj ob 12:00', 'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n\n    function makeFormat(d) {\n        switch (d.day()) {\n            case 0:\n                return '[v] [nedeljo] [ob] LT';\n            case 3:\n                return '[v] [sredo] [ob] LT';\n            case 6:\n                return '[v] [soboto] [ob] LT';\n            case 1:\n            case 2:\n            case 4:\n            case 5:\n                return '[v] dddd [ob] LT';\n        }\n    }\n\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format(makeFormat(m)),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format(makeFormat(m)),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format(makeFormat(m)),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n\n    function makeFormat(d) {\n        switch (d.day()) {\n            case 0:\n                return '[prejšnjo] [nedeljo] [ob] LT';\n            case 3:\n                return '[prejšnjo] [sredo] [ob] LT';\n            case 6:\n                return '[prejšnjo] [soboto] [ob] LT';\n            case 1:\n            case 2:\n            case 4:\n            case 5:\n                return '[prejšnji] dddd [ob] LT';\n        }\n    }\n\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format(makeFormat(m)),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format(makeFormat(m)),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format(makeFormat(m)),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2011, 11, 26]).format('w ww wo'), '1 01 1.', 'Dec 26 2011 should be week 1');\n    assert.equal(moment([2012,  0,  1]).format('w ww wo'), '1 01 1.', 'Jan  1 2012 should be week 1');\n    assert.equal(moment([2012,  0,  2]).format('w ww wo'), '2 02 2.', 'Jan  2 2012 should be week 2');\n    assert.equal(moment([2012,  0,  8]).format('w ww wo'), '2 02 2.', 'Jan  8 2012 should be week 2');\n    assert.equal(moment([2012,  0,  9]).format('w ww wo'), '3 03 3.', 'Jan  9 2012 should be week 3');\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\n\n\nfunction localeModule (name, lifecycle) {\n    QUnit.module('locale:' + name, {\n        setup : function () {\n            moment.locale(name);\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            moment.locale('en');\n            teardownDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n    defineCommonLocaleTests(name, -1, -1);\n}\n\nlocaleModule('sq');\n\ntest('parse', function (assert) {\n    var i,\n        tests = 'Janar Jan_Shkurt Shk_Mars Mar_Prill Pri_Maj Maj_Qershor Qer_Korrik Kor_Gusht Gus_Shtator Sht_Tetor Tet_Nëntor Nën_Dhjetor Dhj'.split('_');\n\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, MMMM Do YYYY, HH:mm:ss',       'E Diel, Shkurt 14. 2010, 15:25:50'],\n            ['ddd, HH',                            'Die, 15'],\n            ['M Mo MM MMMM MMM',                   '2 2. 02 Shkurt Shk'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14. 14'],\n            ['d do dddd ddd dd',                   '0 0. E Diel Die D'],\n            ['DDD DDDo DDDD',                      '45 45. 045'],\n            ['w wo ww',                            '6 6. 06'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'MD MD'],\n            ['[the] DDDo [day of the year]',       'the 45. day of the year'],\n            ['LTS',                                '15:25:50'],\n            ['L',                                  '14/02/2010'],\n            ['LL',                                 '14 Shkurt 2010'],\n            ['LLL',                                '14 Shkurt 2010 15:25'],\n            ['LLLL',                               'E Diel, 14 Shkurt 2010 15:25'],\n            ['l',                                  '14/2/2010'],\n            ['ll',                                 '14 Shk 2010'],\n            ['lll',                                '14 Shk 2010 15:25'],\n            ['llll',                               'Die, 14 Shk 2010 15:25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('meridiem', function (assert) {\n    assert.equal(moment([2011, 2, 23,  0, 0]).format('A'), 'PD', 'before dawn');\n    assert.equal(moment([2011, 2, 23, 12, 0]).format('A'), 'MD', 'noon');\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1.', '1.');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2.', '2.');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3.', '3.');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4.', '4.');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5.', '5.');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6.', '6.');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7.', '7.');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8.', '8.');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9.', '9.');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10.', '10.');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11.', '11.');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12.', '12.');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13.', '13.');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14.', '14.');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15.', '15.');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16.', '16.');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17.', '17.');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18.', '18.');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19.', '19.');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20.', '20.');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21.', '21.');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22.', '22.');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23.', '23.');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24.', '24.');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25.', '25.');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26.', '26.');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27.', '27.');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28.', '28.');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29.', '29.');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30.', '30.');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31.', '31.');\n});\n\ntest('format month', function (assert) {\n    var i,\n        expected = 'Janar Jan_Shkurt Shk_Mars Mar_Prill Pri_Maj Maj_Qershor Qer_Korrik Kor_Gusht Gus_Shtator Sht_Tetor Tet_Nëntor Nën_Dhjetor Dhj'.split('_');\n\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var i,\n        expected = 'E Diel Die D_E Hënë Hën H_E Martë Mar Ma_E Mërkurë Mër Më_E Enjte Enj E_E Premte Pre P_E Shtunë Sht Sh'.split('_');\n\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'disa sekonda', '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'një minutë',      '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'një minutë',      '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 minuta',     '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 minuta',    '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'një orë',       '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'një orë',       '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 orë',       '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 orë',       '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 orë',      '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'një ditë',         '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'një ditë',         '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 ditë',        '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'një ditë',         '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 ditë',        '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 ditë',       '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'një muaj',       '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'një muaj',       '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'një muaj',       '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 muaj',      '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 muaj',      '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 muaj',      '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'një muaj',       '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 muaj',      '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'një vit',        '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 vite',       '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'një vit',        '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 vite',       '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'në disa sekonda',  'prefix');\n    assert.equal(moment(0).from(30000), 'disa sekonda më parë', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'disa sekonda më parë',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'në disa sekonda', 'in a few seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), 'në 5 ditë', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'Sot në 12:00',   'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'Sot në 12:25',   'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'Sot në 13:00',   'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'Nesër në 12:00', 'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'Sot në 11:00',   'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'Dje në 12:00',   'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('dddd [në] LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd [në] LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd [në] LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('dddd [e kaluar në] LT'),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd [e kaluar në] LT'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd [e kaluar në] LT'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2012, 0,  1]).format('w ww wo'), '52 52 52.', 'Jan  1 2012 should be week 52');\n    assert.equal(moment([2012, 0,  2]).format('w ww wo'),   '1 01 1.', 'Jan  2 2012 should be week 1');\n    assert.equal(moment([2012, 0,  8]).format('w ww wo'),   '1 01 1.', 'Jan  8 2012 should be week 1');\n    assert.equal(moment([2012, 0,  9]).format('w ww wo'),   '2 02 2.', 'Jan  9 2012 should be week 2');\n    assert.equal(moment([2012, 0, 15]).format('w ww wo'),   '2 02 2.', 'Jan 15 2012 should be week 2');\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\n\n\nfunction localeModule (name, lifecycle) {\n    QUnit.module('locale:' + name, {\n        setup : function () {\n            moment.locale(name);\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            moment.locale('en');\n            teardownDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n    defineCommonLocaleTests(name, -1, -1);\n}\n\nlocaleModule('sr-cyrl');\n\ntest('parse', function (assert) {\n    var tests = 'јануар јан._фебруар феб._март мар._април апр._мај мај_јун јун_јул јул_август авг._септембар сеп._октобар окт._новембар нов._децембар дец.'.split('_'),\n        i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, Do MMMM YYYY, h:mm:ss a',      'недеља, 14. фебруар 2010, 3:25:50 pm'],\n            ['ddd, hA',                            'нед., 3PM'],\n            ['M Mo MM MMMM MMM',                   '2 2. 02 фебруар феб.'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14. 14'],\n            ['d do dddd ddd dd',                   '0 0. недеља нед. не'],\n            ['DDD DDDo DDDD',                      '45 45. 045'],\n            ['w wo ww',                            '7 7. 07'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'pm PM'],\n            ['[the] DDDo [day of the year]',       'the 45. day of the year'],\n            ['LTS',                                '15:25:50'],\n            ['L',                                  '14.02.2010'],\n            ['LL',                                 '14. фебруар 2010'],\n            ['LLL',                                '14. фебруар 2010 15:25'],\n            ['LLLL',                               'недеља, 14. фебруар 2010 15:25'],\n            ['l',                                  '14.2.2010'],\n            ['ll',                                 '14. феб. 2010'],\n            ['lll',                                '14. феб. 2010 15:25'],\n            ['llll',                               'нед., 14. феб. 2010 15:25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1.', '1.');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2.', '2.');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3.', '3.');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4.', '4.');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5.', '5.');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6.', '6.');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7.', '7.');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8.', '8.');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9.', '9.');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10.', '10.');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11.', '11.');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12.', '12.');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13.', '13.');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14.', '14.');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15.', '15.');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16.', '16.');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17.', '17.');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18.', '18.');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19.', '19.');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20.', '20.');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21.', '21.');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22.', '22.');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23.', '23.');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24.', '24.');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25.', '25.');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26.', '26.');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27.', '27.');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28.', '28.');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29.', '29.');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30.', '30.');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31.', '31.');\n});\n\ntest('format month', function (assert) {\n    var expected = 'јануар јан._фебруар феб._март мар._април апр._мај мај_јун јун_јул јул_август авг._септембар сеп._октобар окт._новембар нов._децембар дец.'.split('_'),\n        i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'недеља нед. не_понедељак пон. по_уторак уто. ут_среда сре. ср_четвртак чет. че_петак пет. пе_субота суб. су'.split('_'),\n        i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'неколико секунди', '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'један минут',   '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'један минут',   '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 минуте',     '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 минута',     '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'један сат',      '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'један сат',      '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 сата',        '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 сати',         '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 сати',        '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'дан',       '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'дан',       '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 дана',        '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'дан',       '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 дана',        '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 дана',       '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'месец',     '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'месец',     '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'месец',     '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 месеца',     '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 месеца',     '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 месеца',     '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'месец',     '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 месеци',    '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'годину',     '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 године',       '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'годину',     '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 година',        '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'за неколико секунди',  'prefix');\n    assert.equal(moment(0).from(30000), 'пре неколико секунди', 'prefix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'пре неколико секунди',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'за неколико секунди', 'in a few seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), 'за 5 дана', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'данас у 12:00',  'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'данас у 12:25',  'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'данас у 13:00',  'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'сутра у 12:00',  'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'данас у 11:00',  'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'јуче у 12:00',   'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n\n    function makeFormat(d) {\n        switch (d.day()) {\n            case 0:\n                return '[у] [недељу] [у] LT';\n            case 3:\n                return '[у] [среду] [у] LT';\n            case 6:\n                return '[у] [суботу] [у] LT';\n            case 1:\n            case 2:\n            case 4:\n            case 5:\n                return '[у] dddd [у] LT';\n        }\n    }\n\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format(makeFormat(m)),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format(makeFormat(m)),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format(makeFormat(m)),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n\n    function makeFormat(d) {\n        var lastWeekDay = [\n                '[прошле] [недеље] [у] LT',\n                '[прошлог] [понедељка] [у] LT',\n                '[прошлог] [уторка] [у] LT',\n                '[прошле] [среде] [у] LT',\n                '[прошлог] [четвртка] [у] LT',\n                '[прошлог] [петка] [у] LT',\n                '[прошле] [суботе] [у] LT'\n            ];\n\n        return lastWeekDay[d.day()];\n    }\n\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format(makeFormat(m)),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format(makeFormat(m)),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format(makeFormat(m)),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2011, 11, 26]).format('w ww wo'), '1 01 1.', 'Dec 26 2011 should be week 1');\n    assert.equal(moment([2012,  0,  1]).format('w ww wo'), '1 01 1.', 'Jan  1 2012 should be week 1');\n    assert.equal(moment([2012,  0,  2]).format('w ww wo'), '2 02 2.', 'Jan  2 2012 should be week 2');\n    assert.equal(moment([2012,  0,  8]).format('w ww wo'), '2 02 2.', 'Jan  8 2012 should be week 2');\n    assert.equal(moment([2012,  0,  9]).format('w ww wo'), '3 03 3.', 'Jan  9 2012 should be week 3');\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\n\n\nfunction localeModule (name, lifecycle) {\n    QUnit.module('locale:' + name, {\n        setup : function () {\n            moment.locale(name);\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            moment.locale('en');\n            teardownDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n    defineCommonLocaleTests(name, -1, -1);\n}\n\nlocaleModule('sr');\n\ntest('parse', function (assert) {\n    var tests = 'januar jan._februar feb._mart mar._april apr._maj maj_jun jun_jul jul_avgust avg._septembar sep._oktobar okt._novembar nov._decembar dec.'.split('_'),\n        i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, Do MMMM YYYY, h:mm:ss a',      'nedelja, 14. februar 2010, 3:25:50 pm'],\n            ['ddd, hA',                            'ned., 3PM'],\n            ['M Mo MM MMMM MMM',                   '2 2. 02 februar feb.'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14. 14'],\n            ['d do dddd ddd dd',                   '0 0. nedelja ned. ne'],\n            ['DDD DDDo DDDD',                      '45 45. 045'],\n            ['w wo ww',                            '7 7. 07'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'pm PM'],\n            ['[the] DDDo [day of the year]',       'the 45. day of the year'],\n            ['LTS',                                '15:25:50'],\n            ['L',                                  '14.02.2010'],\n            ['LL',                                 '14. februar 2010'],\n            ['LLL',                                '14. februar 2010 15:25'],\n            ['LLLL',                               'nedelja, 14. februar 2010 15:25'],\n            ['l',                                  '14.2.2010'],\n            ['ll',                                 '14. feb. 2010'],\n            ['lll',                                '14. feb. 2010 15:25'],\n            ['llll',                               'ned., 14. feb. 2010 15:25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1.', '1.');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2.', '2.');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3.', '3.');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4.', '4.');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5.', '5.');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6.', '6.');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7.', '7.');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8.', '8.');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9.', '9.');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10.', '10.');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11.', '11.');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12.', '12.');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13.', '13.');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14.', '14.');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15.', '15.');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16.', '16.');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17.', '17.');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18.', '18.');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19.', '19.');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20.', '20.');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21.', '21.');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22.', '22.');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23.', '23.');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24.', '24.');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25.', '25.');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26.', '26.');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27.', '27.');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28.', '28.');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29.', '29.');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30.', '30.');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31.', '31.');\n});\n\ntest('format month', function (assert) {\n    var expected = 'januar jan._februar feb._mart mar._april apr._maj maj_jun jun_jul jul_avgust avg._septembar sep._oktobar okt._novembar nov._decembar dec.'.split('_'),\n        i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'nedelja ned. ne_ponedeljak pon. po_utorak uto. ut_sreda sre. sr_četvrtak čet. če_petak pet. pe_subota sub. su'.split('_'),\n        i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'nekoliko sekundi', '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'jedan minut',   '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'jedan minut',   '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 minute',     '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 minuta',     '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'jedan sat',      '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'jedan sat',      '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 sata',        '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 sati',         '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 sati',        '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'dan',       '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'dan',       '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 dana',        '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'dan',       '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 dana',        '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 dana',       '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'mesec',     '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'mesec',     '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'mesec',     '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 meseca',     '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 meseca',     '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 meseca',     '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'mesec',     '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 meseci',    '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'godinu',     '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 godine',       '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'godinu',     '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 godina',        '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'za nekoliko sekundi',  'prefix');\n    assert.equal(moment(0).from(30000), 'pre nekoliko sekundi', 'prefix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'pre nekoliko sekundi',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'za nekoliko sekundi', 'in a few seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), 'za 5 dana', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'danas u 12:00',  'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'danas u 12:25',  'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'danas u 13:00',  'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'sutra u 12:00',  'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'danas u 11:00',  'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'juče u 12:00',   'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n\n    function makeFormat(d) {\n        switch (d.day()) {\n            case 0:\n                return '[u] [nedelju] [u] LT';\n            case 3:\n                return '[u] [sredu] [u] LT';\n            case 6:\n                return '[u] [subotu] [u] LT';\n            case 1:\n            case 2:\n            case 4:\n            case 5:\n                return '[u] dddd [u] LT';\n        }\n    }\n\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format(makeFormat(m)),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format(makeFormat(m)),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format(makeFormat(m)),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n\n    function makeFormat(d) {\n        var lastWeekDay = [\n                '[prošle] [nedelje] [u] LT',\n                '[prošlog] [ponedeljka] [u] LT',\n                '[prošlog] [utorka] [u] LT',\n                '[prošle] [srede] [u] LT',\n                '[prošlog] [četvrtka] [u] LT',\n                '[prošlog] [petka] [u] LT',\n                '[prošle] [subote] [u] LT'\n            ];\n\n        return lastWeekDay[d.day()];\n    }\n\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format(makeFormat(m)),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format(makeFormat(m)),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format(makeFormat(m)),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2011, 11, 26]).format('w ww wo'), '1 01 1.', 'Dec 26 2011 should be week 1');\n    assert.equal(moment([2012,  0,  1]).format('w ww wo'), '1 01 1.', 'Jan  1 2012 should be week 1');\n    assert.equal(moment([2012,  0,  2]).format('w ww wo'), '2 02 2.', 'Jan  2 2012 should be week 2');\n    assert.equal(moment([2012,  0,  8]).format('w ww wo'), '2 02 2.', 'Jan  8 2012 should be week 2');\n    assert.equal(moment([2012,  0,  9]).format('w ww wo'), '3 03 3.', 'Jan  9 2012 should be week 3');\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\n\n\nfunction localeModule (name, lifecycle) {\n    QUnit.module('locale:' + name, {\n        setup : function () {\n            moment.locale(name);\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            moment.locale('en');\n            teardownDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n    defineCommonLocaleTests(name, -1, -1);\n}\n\nlocaleModule('ss');\n\ntest('parse', function (assert) {\n    var tests = \"Bhimbidvwane Bhi_Indlovana Ina_Indlov'lenkhulu Inu_Mabasa Mab_Inkhwekhweti Ink_Inhlaba Inh_Kholwane Kho_Ingci Igc_Inyoni Iny_Imphala Imp_Lweti lwe_Ingongoni Igo\".split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('parse meridiem', function (assert) {\n    var i,\n        b = moment(),\n        meridiemTests = [\n            // h a patterns, expected hours, isValid\n            ['10 ekuseni',   10, true],\n            ['11 emini',   11, true],\n            ['3 entsambama',   15, true],\n            ['4 entsambama',   16, true],\n            ['6 entsambama',   18, true],\n            ['7 ebusuku',   19, true],\n            ['12 ebusuku',   0, true],\n            ['10 am',   10, false],\n            ['10 pm',   10, false]\n        ],\n        parsed;\n\n    // test that a formatted moment including meridiem string can be parsed back to the same moment\n    assert.ok(b.isSame(moment(b.format('h:mm:ss a'), 'h:mm:ss a', 'ss', true), 'seconds'), b.format('h:mm:ss a') + ' should be equal to ' + moment(b.format('h:mm:ss a'), 'h:mm:ss a', 'ss', true).format('h:mm:ss a'));\n\n    // test that a formatted moment having a meridiem string can be parsed with strict flag\n    assert.ok(moment(b.format('h:mm:ss a'), 'h:mm:ss a', 'ss', true).isValid(), b.format('h:mm:ss a') + ' should be parsed as valid');\n\n    for (i = 0; i < meridiemTests.length; i++) {\n        parsed = moment(meridiemTests[i][0], 'h a', 'ss', true);\n        assert.equal(parsed.isValid(), meridiemTests[i][2], 'validity for ' + meridiemTests[i][0]);\n        if (parsed.isValid()) {\n            assert.equal(parsed.hours(), meridiemTests[i][1], 'hours for ' + meridiemTests[i][0]);\n        }\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, MMMM Do YYYY, h:mm:ss a',      'Lisontfo, Indlovana 14 2010, 3:25:50 entsambama'],\n            ['ddd, h A',                            'Lis, 3 entsambama'],\n            ['M Mo MM MMMM MMM',                   '2 2 02 Indlovana Ina'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14 14'],\n            ['d do dddd ddd dd',                   '0 0 Lisontfo Lis Li'],\n            ['DDD DDDo DDDD',                      '45 45 045'],\n            ['w wo ww',                            '6 6 06'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'entsambama entsambama'],\n            ['[Lilanga] DDDo [lilanga lelinyaka]', 'Lilanga 45 lilanga lelinyaka'],\n            ['LTS',                                '3:25:50 entsambama'],\n            ['L',                                  '14/02/2010'],\n            ['LL',                                 '14 Indlovana 2010'],\n            ['LLL',                                '14 Indlovana 2010 3:25 entsambama'],\n            ['LLLL',                               'Lisontfo, 14 Indlovana 2010 3:25 entsambama'],\n            ['l',                                  '14/2/2010'],\n            ['ll',                                 '14 Ina 2010'],\n            ['lll',                                '14 Ina 2010 3:25 entsambama'],\n            ['llll',                               'Lis, 14 Ina 2010 3:25 entsambama']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1', '1');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2', '2');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3', '3');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4', '4');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5', '5');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6', '6');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7', '7');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8', '8');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9', '9');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10', '10');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11', '11');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12', '12');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13', '13');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14', '14');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15', '15');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16', '16');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17', '17');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18', '18');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19', '19');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20', '20');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21', '21');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22', '22');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23', '23');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24', '24');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25', '25');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26', '26');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27', '27');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28', '28');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29', '29');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30', '30');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31', '31');\n});\n\ntest('format month', function (assert) {\n    var expected = \"Bhimbidvwane Bhi_Indlovana Ina_Indlov'lenkhulu Inu_Mabasa Mab_Inkhwekhweti Ink_Inhlaba Inh_Kholwane Kho_Ingci Igc_Inyoni Iny_Imphala Imp_Lweti Lwe_Ingongoni Igo\".split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'Lisontfo Lis Li_Umsombuluko Umb Us_Lesibili Lsb Lb_Lesitsatfu Les Lt_Lesine Lsi Ls_Lesihlanu Lsh Lh_Umgcibelo Umg Ug'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'emizuzwana lomcane', '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'umzuzu',      '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'umzuzu',      '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 emizuzu',     '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 emizuzu',    '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'lihora',       '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'lihora',       '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 emahora',       '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 emahora',       '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 emahora',      '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'lilanga',         '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'lilanga',         '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 emalanga',        '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'lilanga',         '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 emalanga',        '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 emalanga',       '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'inyanga',       '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'inyanga',       '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'inyanga',       '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 tinyanga',      '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 tinyanga',      '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 tinyanga',      '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'inyanga',       '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 tinyanga',      '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'umnyaka',        '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 iminyaka',       '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'umnyaka',        '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 iminyaka',       '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'nga emizuzwana lomcane',  'prefix');\n    assert.equal(moment(0).from(30000), 'wenteka nga emizuzwana lomcane', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'wenteka nga emizuzwana lomcane',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'nga emizuzwana lomcane', 'in a few seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), 'nga 5 emalanga', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'Namuhla nga 12:00 emini',      'Today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'Namuhla nga 12:25 emini',      'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'Namuhla nga 1:00 emini',      'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'Kusasa nga 12:00 emini',   'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'Namuhla nga 11:00 emini',      'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'Itolo nga 12:00 emini',  'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('dddd [nga] LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd [nga] LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd [nga] LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('dddd [leliphelile] [nga] LT'),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd [leliphelile] [nga] LT'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd [leliphelile] [nga] LT'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2012, 0,  1]).format('w ww wo'), '52 52 52', 'Jan  1 2012 should be week 52');\n    assert.equal(moment([2012, 0,  2]).format('w ww wo'),   '1 01 1', 'Jan  4 2012 should be week 1');\n    assert.equal(moment([2012, 0,  8]).format('w ww wo'),   '1 01 1', 'Jan  8 2012 should be week 1');\n    assert.equal(moment([2012, 0,  9]).format('w ww wo'),   '2 02 2', 'Jan  9 2012 should be week 2');\n    assert.equal(moment([2012, 0, 15]).format('w ww wo'),   '2 02 2', 'Jan 15 2012 should be week 2');\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\n\n\nfunction localeModule (name, lifecycle) {\n    QUnit.module('locale:' + name, {\n        setup : function () {\n            moment.locale(name);\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            moment.locale('en');\n            teardownDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n    defineCommonLocaleTests(name, -1, -1);\n}\n\nlocaleModule('sv');\n\ntest('parse', function (assert) {\n    var tests = 'januari jan_februari feb_mars mar_april apr_maj maj_juni jun_juli jul_augusti aug_september sep_oktober okt_november nov_december dec'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, MMMM Do YYYY, h:mm:ss a',      'söndag, februari 14e 2010, 3:25:50 pm'],\n            ['ddd, hA',                            'sön, 3PM'],\n            ['M Mo MM MMMM MMM',                   '2 2a 02 februari feb'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14e 14'],\n            ['d do dddd ddd dd',                   '0 0e söndag sön sö'],\n            ['DDD DDDo DDDD',                      '45 45e 045'],\n            ['w wo ww',                            '6 6e 06'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'pm PM'],\n            ['[the] DDDo [day of the year]',       'the 45e day of the year'],\n            ['LTS',                                '15:25:50'],\n            ['L',                                  '2010-02-14'],\n            ['LL',                                 '14 februari 2010'],\n            ['LLL',                                '14 februari 2010 kl. 15:25'],\n            ['LLLL',                               'söndag 14 februari 2010 kl. 15:25'],\n            ['l',                                  '2010-2-14'],\n            ['ll',                                 '14 feb 2010'],\n            ['lll',                                '14 feb 2010 15:25'],\n            ['llll',                               'sön 14 feb 2010 15:25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1a', '1a');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2a', '2a');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3e', '3e');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4e', '4e');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5e', '5e');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6e', '6e');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7e', '7e');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8e', '8e');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9e', '9e');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10e', '10e');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11e', '11e');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12e', '12e');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13e', '13e');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14e', '14e');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15e', '15e');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16e', '16e');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17e', '17e');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18e', '18e');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19e', '19e');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20e', '20e');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21a', '21a');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22a', '22a');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23e', '23e');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24e', '24e');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25e', '25e');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26e', '26e');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27e', '27e');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28e', '28e');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29e', '29e');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30e', '30e');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31a', '31a');\n});\n\ntest('format month', function (assert) {\n    var expected = 'januari jan_februari feb_mars mar_april apr_maj maj_juni jun_juli jul_augusti aug_september sep_oktober okt_november nov_december dec'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'söndag sön sö_måndag mån må_tisdag tis ti_onsdag ons on_torsdag tor to_fredag fre fr_lördag lör lö'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'några sekunder', '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'en minut',      '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'en minut',      '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 minuter',     '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 minuter',    '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'en timme',       '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'en timme',       '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 timmar',       '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 timmar',       '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 timmar',      '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'en dag',         '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'en dag',         '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 dagar',        '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'en dag',         '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 dagar',        '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 dagar',       '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'en månad',       '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'en månad',       '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'en månad',       '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 månader',      '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 månader',      '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 månader',      '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'en månad',       '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 månader',      '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'ett år',        '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 år',       '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'ett år',        '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 år',       '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'om några sekunder',  'prefix');\n    assert.equal(moment(0).from(30000), 'för några sekunder sedan', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'för några sekunder sedan',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'om några sekunder', 'in a few seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), 'om 5 dagar', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'Idag 12:00',     'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'Idag 12:25',     'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'Idag 13:00',     'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'Imorgon 12:00',  'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'Idag 11:00',     'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'Igår 12:00',     'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('[På] dddd LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[På] dddd LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[På] dddd LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('[I] dddd[s] LT'),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[I] dddd[s] LT'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[I] dddd[s] LT'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2012, 0,  1]).format('w ww wo'), '52 52 52a', 'Jan  1 2012 should be week 52');\n    assert.equal(moment([2012, 0,  2]).format('w ww wo'),   '1 01 1a', 'Jan  2 2012 should be week 1');\n    assert.equal(moment([2012, 0,  8]).format('w ww wo'),   '1 01 1a', 'Jan  8 2012 should be week 1');\n    assert.equal(moment([2012, 0,  9]).format('w ww wo'),   '2 02 2a', 'Jan  9 2012 should be week 2');\n    assert.equal(moment([2012, 0, 15]).format('w ww wo'),   '2 02 2a', 'Jan 15 2012 should be week 2');\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\n\n\nfunction localeModule (name, lifecycle) {\n    QUnit.module('locale:' + name, {\n        setup : function () {\n            moment.locale(name);\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            moment.locale('en');\n            teardownDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n    defineCommonLocaleTests(name, -1, -1);\n}\n\nlocaleModule('sw');\n\ntest('parse', function (assert) {\n    var tests = 'Januari Jan_Februari Feb_Machi Mac_Aprili Apr_Mei Mei_Juni Jun_Julai Jul_Agosti Ago_Septemba Sep_Oktoba Okt_Novemba Nov_Desemba Des'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, MMMM Do YYYY, h:mm:ss a',      'Jumapili, Februari 14 2010, 3:25:50 pm'],\n            ['ddd, hA',                            'Jpl, 3PM'],\n            ['M Mo MM MMMM MMM',                   '2 2 02 Februari Feb'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14 14'],\n            ['d do dddd ddd dd',                   '0 0 Jumapili Jpl J2'],\n            ['DDD DDDo DDDD',                      '45 45 045'],\n            ['w wo ww',                            '7 7 07'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'pm PM'],\n            ['[siku] DDDo [ya mwaka]',             'siku 45 ya mwaka'],\n            ['LTS',                                '15:25:50'],\n            ['L',                                  '14.02.2010'],\n            ['LL',                                 '14 Februari 2010'],\n            ['LLL',                                '14 Februari 2010 15:25'],\n            ['LLLL',                               'Jumapili, 14 Februari 2010 15:25'],\n            ['l',                                  '14.2.2010'],\n            ['ll',                                 '14 Feb 2010'],\n            ['lll',                                '14 Feb 2010 15:25'],\n            ['llll',                               'Jpl, 14 Feb 2010 15:25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1', '1');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2', '2');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3', '3');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4', '4');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5', '5');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6', '6');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7', '7');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8', '8');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9', '9');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10', '10');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11', '11');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12', '12');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13', '13');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14', '14');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15', '15');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16', '16');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17', '17');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18', '18');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19', '19');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20', '20');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21', '21');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22', '22');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23', '23');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24', '24');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25', '25');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26', '26');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27', '27');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28', '28');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29', '29');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30', '30');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31', '31');\n});\n\ntest('format month', function (assert) {\n    var expected = 'Januari Jan_Februari Feb_Machi Mac_Aprili Apr_Mei Mei_Juni Jun_Julai Jul_Agosti Ago_Septemba Sep_Oktoba Okt_Novemba Nov_Desemba Des'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'Jumapili Jpl J2_Jumatatu Jtat J3_Jumanne Jnne J4_Jumatano Jtan J5_Alhamisi Alh Al_Ijumaa Ijm Ij_Jumamosi Jmos J1'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'hivi punde',   '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'dakika moja',  '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'dakika moja',  '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  'dakika 2',     '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  'dakika 44',    '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'saa limoja',   '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'saa limoja',   '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  'masaa 2',      '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   'masaa 5',      '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  'masaa 21',     '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'siku moja',    '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'siku moja',    '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  'masiku 2',     '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'siku moja',    '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   'masiku 5',     '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  'masiku 25',    '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'mwezi mmoja',  '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'mwezi mmoja',  '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'mwezi mmoja',  '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  'miezi 2',      '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  'miezi 2',      '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  'miezi 3',      '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'mwezi mmoja',  '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   'miezi 5',      '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'mwaka mmoja',  '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), 'miaka 2',      '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'mwaka mmoja',  '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   'miaka 5',      '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'hivi punde baadaye',  'prefix');\n    assert.equal(moment(0).from(30000), 'tokea hivi punde', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'tokea hivi punde',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'hivi punde baadaye', 'in a few seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), 'masiku 5 baadaye', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n    assert.equal(moment(a).calendar(),                   'leo saa 12:00',      'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'leo saa 12:25',      'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'leo saa 13:00',      'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'kesho saa 12:00',    'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'leo saa 11:00',      'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'jana 12:00',         'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('[wiki ijayo] dddd [saat] LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[wiki ijayo] dddd [saat] LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[wiki ijayo] dddd [saat] LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('[wiki iliyopita] dddd [saat] LT'),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[wiki iliyopita] dddd [saat] LT'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[wiki iliyopita] dddd [saat] LT'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),      '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('weeks year starting sunday format', function (assert) {\n    assert.equal(moment([2011, 11, 26]).format('w ww wo'), '1 01 1', 'Dec 26 2011 should be week 1');\n    assert.equal(moment([2012,  0,  1]).format('w ww wo'), '1 01 1', 'Jan  1 2012 should be week 1');\n    assert.equal(moment([2012,  0,  2]).format('w ww wo'), '2 02 2', 'Jan  2 2012 should be week 2');\n    assert.equal(moment([2012,  0,  8]).format('w ww wo'), '2 02 2', 'Jan  8 2012 should be week 2');\n    assert.equal(moment([2012,  0,  9]).format('w ww wo'), '3 03 3', 'Jan  9 2012 should be week 3');\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\n\n\nfunction localeModule (name, lifecycle) {\n    QUnit.module('locale:' + name, {\n        setup : function () {\n            moment.locale(name);\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            moment.locale('en');\n            teardownDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n    defineCommonLocaleTests(name, -1, -1);\n}\n\nlocaleModule('ta');\n\ntest('parse', function (assert) {\n    var tests = 'ஜனவரி ஜனவரி_பிப்ரவரி பிப்ரவரி_மார்ச் மார்ச்_ஏப்ரல் ஏப்ரல்_மே மே_ஜூன் ஜூன்_ஜூலை ஜூலை_ஆகஸ்ட் ஆகஸ்ட்_செப்டெம்பர் செப்டெம்பர்_அக்டோபர் அக்டோபர்_நவம்பர் நவம்பர்_டிசம்பர் டிசம்பர்'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, MMMM Do YYYY, h:mm:ss a', 'ஞாயிற்றுக்கிழமை, பிப்ரவரி ௧௪வது ௨௦௧௦, ௩:௨௫:௫௦  எற்பாடு'],\n            ['ddd, hA',                       'ஞாயிறு, ௩ எற்பாடு'],\n            ['M Mo MM MMMM MMM',              '௨ ௨வது ௦௨ பிப்ரவரி பிப்ரவரி'],\n            ['YYYY YY',                       '௨௦௧௦ ௧௦'],\n            ['D Do DD',                       '௧௪ ௧௪வது ௧௪'],\n            ['d do dddd ddd dd',              '௦ ௦வது ஞாயிற்றுக்கிழமை ஞாயிறு ஞா'],\n            ['DDD DDDo DDDD',                 '௪௫ ௪௫வது ௦௪௫'],\n            ['w wo ww',                       '௮ ௮வது ௦௮'],\n            ['h hh',                          '௩ ௦௩'],\n            ['H HH',                          '௧௫ ௧௫'],\n            ['m mm',                          '௨௫ ௨௫'],\n            ['s ss',                          '௫௦ ௫௦'],\n            ['a A',                           ' எற்பாடு  எற்பாடு'],\n            ['[ஆண்டின்] DDDo  [நாள்]', 'ஆண்டின் ௪௫வது  நாள்'],\n            ['LTS',                           '௧௫:௨௫:௫௦'],\n            ['L',                             '௧௪/௦௨/௨௦௧௦'],\n            ['LL',                            '௧௪ பிப்ரவரி ௨௦௧௦'],\n            ['LLL',                           '௧௪ பிப்ரவரி ௨௦௧௦, ௧௫:௨௫'],\n            ['LLLL',                          'ஞாயிற்றுக்கிழமை, ௧௪ பிப்ரவரி ௨௦௧௦, ௧௫:௨௫'],\n            ['l',                             '௧௪/௨/௨௦௧௦'],\n            ['ll',                            '௧௪ பிப்ரவரி ௨௦௧௦'],\n            ['lll',                           '௧௪ பிப்ரவரி ௨௦௧௦, ௧௫:௨௫'],\n            ['llll',                          'ஞாயிறு, ௧௪ பிப்ரவரி ௨௦௧௦, ௧௫:௨௫']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '௧வது', '௧வது');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '௨வது', '௨வது');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '௩வது', '௩வது');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '௪வது', '௪வது');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '௫வது', '௫வது');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '௬வது', '௬வது');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '௭வது', '௭வது');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '௮வது', '௮வது');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '௯வது', '௯வது');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '௧௦வது', '௧௦வது');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '௧௧வது', '௧௧வது');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '௧௨வது', '௧௨வது');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '௧௩வது', '௧௩வது');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '௧௪வது', '௧௪வது');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '௧௫வது', '௧௫வது');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '௧௬வது', '௧௬வது');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '௧௭வது', '௧௭வது');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '௧௮வது', '௧௮வது');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '௧௯வது', '௧௯வது');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '௨௦வது', '௨௦வது');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '௨௧வது', '௨௧வது');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '௨௨வது', '௨௨வது');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '௨௩வது', '௨௩வது');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '௨௪வது', '௨௪வது');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '௨௫வது', '௨௫வது');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '௨௬வது', '௨௬வது');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '௨௭வது', '௨௭வது');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '௨௮வது', '௨௮வது');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '௨௯வது', '௨௯வது');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '௩௦வது', '௩௦வது');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '௩௧வது', '௩௧வது');\n});\n\ntest('format month', function (assert) {\n    var expected = 'ஜனவரி ஜனவரி_பிப்ரவரி பிப்ரவரி_மார்ச் மார்ச்_ஏப்ரல் ஏப்ரல்_மே மே_ஜூன் ஜூன்_ஜூலை ஜூலை_ஆகஸ்ட் ஆகஸ்ட்_செப்டெம்பர் செப்டெம்பர்_அக்டோபர் அக்டோபர்_நவம்பர் நவம்பர்_டிசம்பர் டிசம்பர்'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'ஞாயிற்றுக்கிழமை ஞாயிறு ஞா_திங்கட்கிழமை திங்கள் தி_செவ்வாய்கிழமை செவ்வாய் செ_புதன்கிழமை புதன் பு_வியாழக்கிழமை வியாழன் வி_வெள்ளிக்கிழமை வெள்ளி வெ_சனிக்கிழமை சனி ச'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'ஒரு சில விநாடிகள்', '44 விநாடிகள் = ஒரு சில விநாடிகள்');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'ஒரு நிமிடம்',      '45 விநாடிகள் = ஒரு நிமிடம்');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'ஒரு நிமிடம்',      '89 விநாடிகள் = ஒரு நிமிடம்');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '௨ நிமிடங்கள்',     '90 விநாடிகள் = ௨ நிமிடங்கள்');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '௪௪ நிமிடங்கள்',    '44 நிமிடங்கள் = 44 நிமிடங்கள்');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'ஒரு மணி நேரம்',       '45 நிமிடங்கள் = ஒரு மணி நேரம்');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'ஒரு மணி நேரம்',       '89 நிமிடங்கள் = ஒரு மணி நேரம்');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '௨ மணி நேரம்',       '90 நிமிடங்கள் = ௨ மணி நேரம்');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '௫ மணி நேரம்',       '5 மணி நேரம் = 5 மணி நேரம்');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '௨௧ மணி நேரம்',      '௨௧ மணி நேரம் = ௨௧ மணி நேரம்');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'ஒரு நாள்',         '௨௨ மணி நேரம் = ஒரு நாள்');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'ஒரு நாள்',         '௩5 மணி நேரம் = ஒரு நாள்');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '௨ நாட்கள்',        '௩6 மணி நேரம் = ௨ days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'ஒரு நாள்',         '௧ நாள் = ஒரு நாள்');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '௫ நாட்கள்',        '5 நாட்கள் = 5 நாட்கள்');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '௨௫ நாட்கள்',       '௨5 நாட்கள் = ௨5 நாட்கள்');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'ஒரு மாதம்',       '௨6 நாட்கள் = ஒரு மாதம்');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'ஒரு மாதம்',       '௩0 நாட்கள் = ஒரு மாதம்');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'ஒரு மாதம்',       '45 நாட்கள் = ஒரு மாதம்');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '௨ மாதங்கள்',      '46 நாட்கள் = ௨ மாதங்கள்');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '௨ மாதங்கள்',      '75 நாட்கள் = ௨ மாதங்கள்');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '௩ மாதங்கள்',      '76 நாட்கள் = ௩ மாதங்கள்');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'ஒரு மாதம்',       '௧ மாதம் = ஒரு மாதம்');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '௫ மாதங்கள்',      '5 மாதங்கள் = 5 மாதங்கள்');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'ஒரு வருடம்',        '௩45 நாட்கள் = ஒரு வருடம்');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '௨ ஆண்டுகள்',       '548 நாட்கள் = ௨ ஆண்டுகள்');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'ஒரு வருடம்',        '௧ வருடம் = ஒரு வருடம்');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '௫ ஆண்டுகள்',       '5 ஆண்டுகள் = 5 ஆண்டுகள்');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'ஒரு சில விநாடிகள் இல்',  'prefix');\n    assert.equal(moment(0).from(30000), 'ஒரு சில விநாடிகள் முன்', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'ஒரு சில விநாடிகள் முன்',  'இப்போது இருந்து கடந்த காலத்தில் காட்ட வேண்டும்');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'ஒரு சில விநாடிகள் இல்', 'ஒரு சில விநாடிகள் இல்');\n    assert.equal(moment().add({d: 5}).fromNow(), '௫ நாட்கள் இல்', '5 நாட்கள் இல்');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'இன்று ௧௨:௦௦',   'இன்று  12:00');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'இன்று ௧௨:௨௫',   'இன்று  12:25');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'இன்று ௧௩:௦௦',   'இன்று  13:00');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'நாளை ௧௨:௦௦',    'நாளை  12:00');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'இன்று ௧௧:௦௦',   'இன்று  11:00');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'நேற்று ௧௨:௦௦',  'நேற்று  12:00');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('dddd, LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd, LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd, LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('[கடந்த வாரம்] dddd, LT'),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[கடந்த வாரம்] dddd, LT'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[கடந்த வாரம்] dddd, LT'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('meridiem', function (assert) {\n    assert.equal(moment([2011, 2, 23,  0, 30]).format('a'), ' யாமம்', '(after) midnight');\n    assert.equal(moment([2011, 2, 23,  2, 30]).format('a'), ' வைகறை', 'before dawn');\n    assert.equal(moment([2011, 2, 23,  9, 30]).format('a'), ' காலை', 'morning');\n    assert.equal(moment([2011, 2, 23, 14, 30]).format('a'), ' எற்பாடு', 'during day');\n    assert.equal(moment([2011, 2, 23, 17, 30]).format('a'), ' எற்பாடு', 'evening');\n    assert.equal(moment([2011, 2, 23, 19, 30]).format('a'), ' மாலை', 'late evening');\n    assert.equal(moment([2011, 2, 23, 23, 30]).format('a'), ' யாமம்', '(before) midnight');\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\n\n\nfunction localeModule (name, lifecycle) {\n    QUnit.module('locale:' + name, {\n        setup : function () {\n            moment.locale(name);\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            moment.locale('en');\n            teardownDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n    defineCommonLocaleTests(name, -1, -1);\n}\n\nlocaleModule('te');\n\ntest('parse', function (assert) {\n    var tests = 'జనవరి జన._ఫిబ్రవరి ఫిబ్ర._మార్చి మార్చి_ఏప్రిల్ ఏప్రి._మే మే_జూన్ జూన్_జూలై జూలై_ఆగస్టు ఆగ._సెప్టెంబర్ సెప్._అక్టోబర్ అక్టో._నవంబర్ నవ._డిసెంబర్ డిసె.'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, Do తేదీ MMMM YYYY, a h:mm:ss',  'ఆదివారం, 14వ తేదీ ఫిబ్రవరి 2010, మధ్యాహ్నం 3:25:50'],\n            ['ddd, a h గంటలు',                 'ఆది, మధ్యాహ్నం 3 గంటలు'],\n            ['M Mo నెల MM MMMM MMM',                   '2 2వ నెల 02 ఫిబ్రవరి ఫిబ్ర.'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14వ 14'],\n            ['d do dddd ddd dd',                   '0 0వ ఆదివారం ఆది ఆ'],\n            ['DDD DDDo DDDD',                      '45 45వ 045'],\n            ['w wo ww',                            '8 8వ 08'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'మధ్యాహ్నం మధ్యాహ్నం'],\n            ['LTS',                                'మధ్యాహ్నం 3:25:50'],\n            ['L',                                  '14/02/2010'],\n            ['LL',                                 '14 ఫిబ్రవరి 2010'],\n            ['LLL',                                '14 ఫిబ్రవరి 2010, మధ్యాహ్నం 3:25'],\n            ['LLLL',                               'ఆదివారం, 14 ఫిబ్రవరి 2010, మధ్యాహ్నం 3:25'],\n            ['l',                                  '14/2/2010'],\n            ['ll',                                 '14 ఫిబ్ర. 2010'],\n            ['lll',                                '14 ఫిబ్ర. 2010, మధ్యాహ్నం 3:25'],\n            ['llll',                               'ఆది, 14 ఫిబ్ర. 2010, మధ్యాహ్నం 3:25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1వ', '1వ');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2వ', '2వ');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3వ', '3వ');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4వ', '4వ');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5వ', '5వ');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6వ', '6వ');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7వ', '7వ');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8వ', '8వ');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9వ', '9వ');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10వ', '10వ');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11వ', '11వ');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12వ', '12వ');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13వ', '13వ');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14వ', '14వ');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15వ', '15వ');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16వ', '16వ');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17వ', '17వ');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18వ', '18వ');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19వ', '19వ');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20వ', '20వ');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21వ', '21వ');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22వ', '22వ');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23వ', '23వ');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24వ', '24వ');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25వ', '25వ');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26వ', '26వ');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27వ', '27వ');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28వ', '28వ');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29వ', '29వ');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30వ', '30వ');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31వ', '31వ');\n});\n\ntest('format month', function (assert) {\n    var expected = 'జనవరి జన._ఫిబ్రవరి ఫిబ్ర._మార్చి మార్చి_ఏప్రిల్ ఏప్రి._మే మే_జూన్ జూన్_జూలై జూలై_ఆగస్టు ఆగ._సెప్టెంబర్ సెప్._అక్టోబర్ అక్టో._నవంబర్ నవ._డిసెంబర్ డిసె.'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'ఆదివారం ఆది ఆ_సోమవారం సోమ సో_మంగళవారం మంగళ మం_బుధవారం బుధ బు_గురువారం గురు గు_శుక్రవారం శుక్ర శు_శనివారం శని శ'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'కొన్ని క్షణాలు', '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'ఒక నిమిషం',      '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'ఒక నిమిషం',      '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 నిమిషాలు',     '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 నిమిషాలు',    '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'ఒక గంట',       '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'ఒక గంట',       '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 గంటలు',       '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 గంటలు',       '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 గంటలు',      '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'ఒక రోజు',         '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'ఒక రోజు',         '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 రోజులు',        '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'ఒక రోజు',         '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 రోజులు',        '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 రోజులు',       '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'ఒక నెల',       '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'ఒక నెల',       '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'ఒక నెల',       '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 నెలలు',      '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 నెలలు',      '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 నెలలు',      '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'ఒక నెల',       '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 నెలలు',      '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'ఒక సంవత్సరం',        '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 సంవత్సరాలు',       '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'ఒక సంవత్సరం',        '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 సంవత్సరాలు',       '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'కొన్ని క్షణాలు లో',  'prefix');\n    assert.equal(moment(0).from(30000), 'కొన్ని క్షణాలు క్రితం', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'కొన్ని క్షణాలు క్రితం',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'కొన్ని క్షణాలు లో', 'కొన్ని క్షణాలు లో');\n    assert.equal(moment().add({d: 5}).fromNow(), '5 రోజులు లో', '5 రోజులు లో');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'నేడు మధ్యాహ్నం 12:00',   'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'నేడు మధ్యాహ్నం 12:25',   'Now plus 25 min');\n    assert.equal(moment(a).add({h: 3}).calendar(),       'నేడు మధ్యాహ్నం 3:00',    'Now plus 3 hours');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'రేపు మధ్యాహ్నం 12:00',   'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'నేడు మధ్యాహ్నం 11:00',   'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'నిన్న మధ్యాహ్నం 12:00',  'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('dddd[,] LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd[,] LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd[,] LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('[గత] dddd[,] LT'),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[గత] dddd[,] LT'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[గత] dddd[,] LT'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('meridiem', function (assert) {\n    assert.equal(moment([2011, 2, 23,  2, 30]).format('a'), 'రాత్రి', 'before dawn');\n    assert.equal(moment([2011, 2, 23,  9, 30]).format('a'), 'ఉదయం', 'morning');\n    assert.equal(moment([2011, 2, 23, 14, 30]).format('a'), 'మధ్యాహ్నం', 'during day');\n    assert.equal(moment([2011, 2, 23, 17, 30]).format('a'), 'సాయంత్రం', 'evening');\n    assert.equal(moment([2011, 2, 23, 19, 30]).format('a'), 'సాయంత్రం', 'late evening');\n    assert.equal(moment([2011, 2, 23, 21, 20]).format('a'), 'రాత్రి', 'night');\n\n    assert.equal(moment([2011, 2, 23,  2, 30]).format('A'), 'రాత్రి', 'before dawn');\n    assert.equal(moment([2011, 2, 23,  9, 30]).format('A'), 'ఉదయం', 'morning');\n    assert.equal(moment([2011, 2, 23, 14, 30]).format('A'), 'మధ్యాహ్నం', ' during day');\n    assert.equal(moment([2011, 2, 23, 17, 30]).format('A'), 'సాయంత్రం', 'evening');\n    assert.equal(moment([2011, 2, 23, 19, 30]).format('A'), 'సాయంత్రం', 'late evening');\n    assert.equal(moment([2011, 2, 23, 21, 20]).format('A'), 'రాత్రి', 'night');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2012, 0,  1]).format('w ww wo'), '1 01 1వ', 'Jan  1 2012 should be week 1');\n    assert.equal(moment([2012, 0,  7]).format('w ww wo'), '1 01 1వ', 'Jan  7 2012 should be week 1');\n    assert.equal(moment([2012, 0,  8]).format('w ww wo'), '2 02 2వ', 'Jan  8 2012 should be week 2');\n    assert.equal(moment([2012, 0, 14]).format('w ww wo'), '2 02 2వ', 'Jan 14 2012 should be week 2');\n    assert.equal(moment([2012, 0, 15]).format('w ww wo'), '3 03 3వ', 'Jan 15 2012 should be week 3');\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\n\n\nfunction localeModule (name, lifecycle) {\n    QUnit.module('locale:' + name, {\n        setup : function () {\n            moment.locale(name);\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            moment.locale('en');\n            teardownDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n    defineCommonLocaleTests(name, -1, -1);\n}\n\nlocaleModule('tet');\n\ntest('parse', function (assert) {\n    var tests = 'Janeiru Jan_Fevereiru Fev_Marsu Mar_Abril Abr_Maiu Mai_Juniu Jun_Juliu Jul_Augustu Aug_Setembru Set_Outubru Out_Novembru Nov_Dezembru Dez'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, MMMM Do YYYY, h:mm:ss a',      'Domingu, Fevereiru 14th 2010, 3:25:50 pm'],\n            ['ddd, hA',                            'Dom, 3PM'],\n            ['M Mo MM MMMM MMM',                   '2 2nd 02 Fevereiru Fev'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14th 14'],\n            ['d do dddd ddd dd',                   '0 0th Domingu Dom Do'],\n            ['DDD DDDo DDDD',                      '45 45th 045'],\n            ['w wo ww',                            '6 6th 06'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'pm PM'],\n            ['[the] DDDo [day of the year]',       'the 45th day of the year'],\n            ['LTS',                                '15:25:50'],\n            ['L',                                  '14/02/2010'],\n            ['LL',                                 '14 Fevereiru 2010'],\n            ['LLL',                                '14 Fevereiru 2010 15:25'],\n            ['LLLL',                               'Domingu, 14 Fevereiru 2010 15:25'],\n            ['l',                                  '14/2/2010'],\n            ['ll',                                 '14 Fev 2010'],\n            ['lll',                                '14 Fev 2010 15:25'],\n            ['llll',                               'Dom, 14 Fev 2010 15:25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1st', '1st');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2nd', '2nd');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3rd', '3rd');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4th', '4th');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5th', '5th');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6th', '6th');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7th', '7th');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8th', '8th');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9th', '9th');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10th', '10th');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11th', '11th');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12th', '12th');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13th', '13th');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14th', '14th');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15th', '15th');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16th', '16th');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17th', '17th');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18th', '18th');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19th', '19th');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20th', '20th');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21st', '21st');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22nd', '22nd');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23rd', '23rd');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24th', '24th');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25th', '25th');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26th', '26th');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27th', '27th');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28th', '28th');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29th', '29th');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30th', '30th');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31st', '31st');\n});\n\ntest('format month', function (assert) {\n    var expected = 'Janeiru Jan_Fevereiru Fev_Marsu Mar_Abril Abr_Maiu Mai_Juniu Jun_Juliu Jul_Augustu Aug_Setembru Set_Outubru Out_Novembru Nov_Dezembru Dez'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'Domingu Dom Do_Segunda Seg Seg_Tersa Ters Te_Kuarta Kua Ku_Kinta Kint Ki_Sexta Sext Sex_Sabadu Sab Sa'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'minutu balun', '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'minutu ida',      '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'minutu ida',      '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  'minutus 2',     '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  'minutus 44',    '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'horas ida',       '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'horas ida',       '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  'horas 2',       '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   'horas 5',       '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  'horas 21',      '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'loron ida',         '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'loron ida',         '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  'loron 2',        '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'loron ida',         '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   'loron 5',        '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  'loron 25',       '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'fulan ida',       '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'fulan ida',       '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'fulan ida',       '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  'fulan 2',      '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  'fulan 2',      '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  'fulan 3',      '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'fulan ida',       '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   'fulan 5',      '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'tinan ida',        '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), 'tinan 2',       '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'tinan ida',        '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   'tinan 5',       '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'iha minutu balun',  'prefix');\n    assert.equal(moment(0).from(30000), 'minutu balun liuba', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'minutu balun liuba',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'iha minutu balun', 'in a few seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), 'iha loron 5', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'Ohin iha 12:00',      'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'Ohin iha 12:25',      'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'Ohin iha 13:00',      'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'Aban iha 12:00',   'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'Ohin iha 11:00',      'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'Horiseik iha 12:00',  'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('dddd [iha] LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd [iha] LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd [iha] LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('dddd [semana kotuk] [iha] LT'),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd [semana kotuk] [iha] LT'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd [semana kotuk] [iha] LT'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2012, 0,  1]).format('w ww wo'), '52 52 52nd', 'Jan  1 2012 should be week 52');\n    assert.equal(moment([2012, 0,  2]).format('w ww wo'),   '1 01 1st', 'Jan  2 2012 should be week 1');\n    assert.equal(moment([2012, 0,  8]).format('w ww wo'),   '1 01 1st', 'Jan  8 2012 should be week 1');\n    assert.equal(moment([2012, 0,  9]).format('w ww wo'),   '2 02 2nd', 'Jan  9 2012 should be week 2');\n    assert.equal(moment([2012, 0, 15]).format('w ww wo'),   '2 02 2nd', 'Jan 15 2012 should be week 2');\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\n\n\nfunction localeModule (name, lifecycle) {\n    QUnit.module('locale:' + name, {\n        setup : function () {\n            moment.locale(name);\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            moment.locale('en');\n            teardownDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n    defineCommonLocaleTests(name, -1, -1);\n}\n\nlocaleModule('th');\n\ntest('parse', function (assert) {\n    var tests = 'มกราคม ม.ค._กุมภาพันธ์ ก.พ._มีนาคม มี.ค._เมษายน เม.ย._พฤษภาคม พ.ค._มิถุนายน มิ.ย._กรกฎาคม ก.ค._สิงหาคม ส.ค._กันยายน ก.ย._ตุลาคม ต.ค._พฤศจิกายน พ.ย._ธันวาคม ธ.ค.'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, Do MMMM YYYY, h:mm:ss a',      'อาทิตย์, 14 กุมภาพันธ์ 2010, 3:25:50 หลังเที่ยง'],\n            ['ddd, h A',                           'อาทิตย์, 3 หลังเที่ยง'],\n            ['M Mo MM MMMM MMM',                   '2 2 02 กุมภาพันธ์ ก.พ.'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14 14'],\n            ['d do dddd ddd dd',                   '0 0 อาทิตย์ อาทิตย์ อา.'],\n            ['DDD DDDo DDDD',                      '45 45 045'],\n            ['w wo ww',                            '8 8 08'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'หลังเที่ยง หลังเที่ยง'],\n            ['[the] DDDo [day of the year]',       'the 45 day of the year'],\n            ['LTS',                                '15:25:50'],\n            ['L',                                  '14/02/2010'],\n            ['LL',                                 '14 กุมภาพันธ์ 2010'],\n            ['LLL',                                '14 กุมภาพันธ์ 2010 เวลา 15:25'],\n            ['LLLL',                               'วันอาทิตย์ที่ 14 กุมภาพันธ์ 2010 เวลา 15:25'],\n            ['l',                                  '14/2/2010'],\n            ['ll',                                 '14 ก.พ. 2010'],\n            ['lll',                                '14 ก.พ. 2010 เวลา 15:25'],\n            ['llll',                               'วันอาทิตย์ที่ 14 ก.พ. 2010 เวลา 15:25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format month', function (assert) {\n    var expected = 'มกราคม ม.ค._กุมภาพันธ์ ก.พ._มีนาคม มี.ค._เมษายน เม.ย._พฤษภาคม พ.ค._มิถุนายน มิ.ย._กรกฎาคม ก.ค._สิงหาคม ส.ค._กันยายน ก.ย._ตุลาคม ต.ค._พฤศจิกายน พ.ย._ธันวาคม ธ.ค.'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'อาทิตย์ อาทิตย์ อา._จันทร์ จันทร์ จ._อังคาร อังคาร อ._พุธ พุธ พ._พฤหัสบดี พฤหัส พฤ._ศุกร์ ศุกร์ ศ._เสาร์ เสาร์ ส.'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'ไม่กี่วินาที',   '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  '1 นาที', '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  '1 นาที', '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 นาที',  '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 นาที', '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  '1 ชั่วโมง', '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  '1 ชั่วโมง', '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 ชั่วโมง',  '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 ชั่วโมง',  '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 ชั่วโมง', '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  '1 วัน',   '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  '1 วัน',   '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 วัน',   '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   '1 วัน',   '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 วัน',   '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 วัน',  '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  '1 เดือน', '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  '1 เดือน', '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  '1 เดือน', '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 เดือน',  '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 เดือน',  '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 เดือน',  '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   '1 เดือน', '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 เดือน',  '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), '1 ปี',   '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 ปี',   '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   '1 ปี',   '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 ปี',   '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'อีก ไม่กี่วินาที',  'prefix');\n    assert.equal(moment(0).from(30000), 'ไม่กี่วินาทีที่แล้ว', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'ไม่กี่วินาทีที่แล้ว',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'อีก ไม่กี่วินาที', 'in a few seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), 'อีก 5 วัน', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'วันนี้ เวลา 12:00',      'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'วันนี้ เวลา 12:25',     'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'วันนี้ เวลา 13:00',      'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'พรุ่งนี้ เวลา 12:00',    'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'วันนี้ เวลา 11:00',      'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'เมื่อวานนี้ เวลา 12:00', 'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('dddd[หน้า เวลา] LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd[หน้า เวลา] LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd[หน้า เวลา] LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('[วัน]dddd[ที่แล้ว เวลา] LT'),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[วัน]dddd[ที่แล้ว เวลา] LT'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[วัน]dddd[ที่แล้ว เวลา] LT'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),      '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),      '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('weeks year starting sunday format', function (assert) {\n    assert.equal(moment([2012, 0,  1]).format('w ww wo'), '1 01 1', 'Jan  1 2012 should be week 1');\n    assert.equal(moment([2012, 0,  7]).format('w ww wo'), '1 01 1', 'Jan  7 2012 should be week 1');\n    assert.equal(moment([2012, 0,  8]).format('w ww wo'), '2 02 2', 'Jan  8 2012 should be week 2');\n    assert.equal(moment([2012, 0, 14]).format('w ww wo'), '2 02 2', 'Jan 14 2012 should be week 2');\n    assert.equal(moment([2012, 0, 15]).format('w ww wo'), '3 03 3', 'Jan 15 2012 should be week 3');\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\n\n\nfunction localeModule (name, lifecycle) {\n    QUnit.module('locale:' + name, {\n        setup : function () {\n            moment.locale(name);\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            moment.locale('en');\n            teardownDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n    defineCommonLocaleTests(name, -1, -1);\n}\n\nlocaleModule('tl-ph');\n\ntest('parse', function (assert) {\n    var tests = 'Enero Ene_Pebrero Peb_Marso Mar_Abril Abr_Mayo May_Hunyo Hun_Hulyo Hul_Agosto Ago_Setyembre Set_Oktubre Okt_Nobyembre Nob_Disyembre Dis'.split('_'),\n        i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, MMMM Do YYYY, h:mm:ss a',      'Linggo, Pebrero 14 2010, 3:25:50 pm'],\n            ['ddd, hA',                            'Lin, 3PM'],\n            ['M Mo MM MMMM MMM',                   '2 2 02 Pebrero Peb'],\n            ['YYYY YY',                             '2010 10'],\n            ['D Do DD',                            '14 14 14'],\n            ['d do dddd ddd dd',                   '0 0 Linggo Lin Li'],\n            ['DDD DDDo DDDD',                      '45 45 045'],\n            ['w wo ww',                            '6 6 06'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'pm PM'],\n            ['[the] DDDo [day of the year]',       'the 45 day of the year'],\n            ['LTS',                                '15:25:50'],\n            ['L',                                  '02/14/2010'],\n            ['LL',                                 'Pebrero 14, 2010'],\n            ['LLL',                                'Pebrero 14, 2010 15:25'],\n            ['LLLL',                               'Linggo, Pebrero 14, 2010 15:25'],\n            ['l',                                  '2/14/2010'],\n            ['ll',                                 'Peb 14, 2010'],\n            ['lll',                                'Peb 14, 2010 15:25'],\n            ['llll',                               'Lin, Peb 14, 2010 15:25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1', '1');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2', '2');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3', '3');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4', '4');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5', '5');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6', '6');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7', '7');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8', '8');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9', '9');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10', '10');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11', '11');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12', '12');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13', '13');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14', '14');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15', '15');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16', '16');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17', '17');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18', '18');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19', '19');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20', '20');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21', '21');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22', '22');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23', '23');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24', '24');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25', '25');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26', '26');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27', '27');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28', '28');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29', '29');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30', '30');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31', '31');\n});\n\ntest('format month', function (assert) {\n    var expected = 'Enero Ene_Pebrero Peb_Marso Mar_Abril Abr_Mayo May_Hunyo Hun_Hulyo Hul_Agosto Ago_Setyembre Set_Oktubre Okt_Nobyembre Nob_Disyembre Dis'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'Linggo Lin Li_Lunes Lun Lu_Martes Mar Ma_Miyerkules Miy Mi_Huwebes Huw Hu_Biyernes Biy Bi_Sabado Sab Sab'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'ilang segundo', '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'isang minuto',   '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'isang minuto',   '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 minuto',  '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 minuto', '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'isang oras',    '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'isang oras',    '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 oras',    '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 oras',    '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 oras',   '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'isang araw',      '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'isang araw',      '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 araw',     '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'isang araw',      '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 araw',     '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 araw',    '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'isang buwan',    '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'isang buwan',    '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'isang buwan',    '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 buwan',   '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 buwan',   '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 buwan',   '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'isang buwan',    '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 buwan',   '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'isang taon',     '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 taon',    '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'isang taon',     '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 taon',    '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'sa loob ng ilang segundo', 'prefix');\n    assert.equal(moment(0).from(30000), 'ilang segundo ang nakalipas', 'suffix');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'sa loob ng ilang segundo', 'in a few seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), 'sa loob ng 5 araw', 'in 5 days');\n});\n\ntest('same day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   '12:00 ngayong araw',    'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      '12:25 ngayong araw',    'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       '13:00 ngayong araw',    'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'Bukas ng 12:00',     'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  '11:00 ngayong araw',    'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  '12:00 kahapon',   'yesterday at the same time');\n});\n\ntest('same next week', function (assert) {\n    var i, m;\n\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('LT [sa susunod na] dddd'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('LT [sa susunod na] dddd'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('LT [sa susunod na] dddd'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('same last week', function (assert) {\n    var i, m;\n\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('LT [noong nakaraang] dddd'),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('LT [noong nakaraang] dddd'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('LT [noong nakaraang] dddd'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('same all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2012, 0,  1]).format('w ww wo'), '52 52 52', 'Jan  1 2012 should be week 52');\n    assert.equal(moment([2012, 0,  2]).format('w ww wo'), '1 01 1', 'Jan  2 2012 should be week 1');\n    assert.equal(moment([2012, 0,  8]).format('w ww wo'), '1 01 1', 'Jan  8 2012 should be week 1');\n    assert.equal(moment([2012, 0,  9]).format('w ww wo'),   '2 02 2', 'Jan  9 2012 should be week 2');\n    assert.equal(moment([2012, 0, 15]).format('w ww wo'),   '2 02 2', 'Jan 15 2012 should be week 2');\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\n\n\nfunction localeModule (name, lifecycle) {\n    QUnit.module('locale:' + name, {\n        setup : function () {\n            moment.locale(name);\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            moment.locale('en');\n            teardownDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n    defineCommonLocaleTests(name, -1, -1);\n}\n\nlocaleModule('tlh');\n\n//Current parsing method doesn't allow parsing correctly months 10, 11 and 12.\n/*\n * test('parse', function (assert) {\n    var tests = 'tera’ jar wa’.jar wa’_tera’ jar cha’.jar cha’_tera’ jar wej.jar wej_tera’ jar loS.jar loS_tera’ jar vagh.jar vagh_tera’ jar jav.jar jav_tera’ jar Soch.jar Soch_tera’ jar chorgh.jar chorgh_tera’ jar Hut.jar Hut_tera’ jar wa’maH.jar wa’maH_tera’ jar wa’maH wa’.jar wa’maH wa’_tera’ jar wa’maH cha’.jar wa’maH cha’'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split('.');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n*/\ntest('format', function (assert) {\n    var a = [\n            ['dddd, MMMM Do YYYY, h:mm:ss a',      'lojmItjaj, tera’ jar cha’ 14. 2010, 3:25:50 pm'],\n            ['ddd, hA',                            'lojmItjaj, 3PM'],\n            ['M Mo MM MMMM MMM',                   '2 2. 02 tera’ jar cha’ jar cha’'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14. 14'],\n            ['d do dddd ddd dd',                   '0 0. lojmItjaj lojmItjaj lojmItjaj'],\n            ['DDD DDDo DDDD',                      '45 45. 045'],\n            ['w wo ww',                            '6 6. 06'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'pm PM'],\n            ['[DIS jaj] DDDo',                     'DIS jaj 45.'],\n            ['LTS',                                '15:25:50'],\n            ['L',                                  '14.02.2010'],\n            ['LL',                                 '14 tera’ jar cha’ 2010'],\n            ['LLL',                                '14 tera’ jar cha’ 2010 15:25'],\n            ['LLLL',                               'lojmItjaj, 14 tera’ jar cha’ 2010 15:25'],\n            ['l',                                  '14.2.2010'],\n            ['ll',                                 '14 jar cha’ 2010'],\n            ['lll',                                '14 jar cha’ 2010 15:25'],\n            ['llll',                               'lojmItjaj, 14 jar cha’ 2010 15:25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1.', '1.');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2.', '2.');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3.', '3.');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4.', '4.');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5.', '5.');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6.', '6.');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7.', '7.');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8.', '8.');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9.', '9.');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10.', '10.');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11.', '11.');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12.', '12.');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13.', '13.');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14.', '14.');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15.', '15.');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16.', '16.');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17.', '17.');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18.', '18.');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19.', '19.');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20.', '20.');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21.', '21.');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22.', '22.');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23.', '23.');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24.', '24.');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25.', '25.');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26.', '26.');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27.', '27.');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28.', '28.');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29.', '29.');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30.', '30.');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31.', '31.');\n});\n\ntest('format month', function (assert) {\n    var expected = 'tera’ jar wa’ jar wa’_tera’ jar cha’ jar cha’_tera’ jar wej jar wej_tera’ jar loS jar loS_tera’ jar vagh jar vagh_tera’ jar jav jar jav_tera’ jar Soch jar Soch_tera’ jar chorgh jar chorgh_tera’ jar Hut jar Hut_tera’ jar wa’maH jar wa’maH_tera’ jar wa’maH wa’ jar wa’maH wa’_tera’ jar wa’maH cha’ jar wa’maH cha’'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'lojmItjaj lojmItjaj lojmItjaj_DaSjaj DaSjaj DaSjaj_povjaj povjaj povjaj_ghItlhjaj ghItlhjaj ghItlhjaj_loghjaj loghjaj loghjaj_buqjaj buqjaj buqjaj_ghInjaj ghInjaj ghInjaj'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'puS lup',  '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'wa’ tup',        '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'wa’ tup',        '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  'cha’ tup',      '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  'loSmaH loS tup',     '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'wa’ rep',       '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'wa’ rep',       '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  'cha’ rep',     '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   'vagh rep',      '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  'cha’maH wa’ rep',     '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'wa’ jaj',       '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'wa’ jaj',       '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  'cha’ jaj',         '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'wa’ jaj',       '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   'vagh jaj',         '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  'cha’maH vagh jaj',        '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'wa’ jar',       '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'wa’ jar',       '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'wa’ jar',       '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  'cha’ jar',    '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  'cha’ jar',    '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  'wej jar',    '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'wa’ jar',       '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   'vagh jar',    '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'wa’ DIS',           '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), 'cha’ DIS',        '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'wa’ DIS',           '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   'vagh DIS',         '5 years = 5 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 112}), true), 'wa’vatlh wa’maH cha’ DIS',       '112 years = 112 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 122}), true), 'wa’vatlh cha’maH cha’ DIS',      '122 years = 122 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 213}), true), 'cha’vatlh wa’maH wej DIS',       '213 years = 213 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 223}), true), 'cha’vatlh cha’maH wej DIS',      '223 years = 223 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'puS lup pIq',  'suffix');\n    assert.equal(moment(0).from(30000), 'puS lup ret', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'puS lup ret',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'puS lup pIq', 'in a few seconds');\n    assert.equal(moment().add({h: 1}).fromNow(), 'wa’ rep pIq', 'in an hour');\n    assert.equal(moment().add({d: 5}).fromNow(), 'vagh leS', 'in 5 days');\n    assert.equal(moment().add({M: 2}).fromNow(), 'cha’ waQ', 'in 2 months');\n    assert.equal(moment().add({y: 1}).fromNow(), 'wa’ nem', 'in a year');\n    assert.equal(moment().add({s: -30}).fromNow(), 'puS lup ret', 'a few seconds ago');\n    assert.equal(moment().add({h: -1}).fromNow(), 'wa’ rep ret', 'an hour ago');\n    assert.equal(moment().add({d: -5}).fromNow(), 'vagh Hu’', '5 days ago');\n    assert.equal(moment().add({M: -2}).fromNow(), 'cha’ wen', '2 months ago');\n    assert.equal(moment().add({y: -1}).fromNow(), 'wa’ ben', 'a year ago');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'DaHjaj 12:00',     'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'DaHjaj 12:25',     'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'DaHjaj 13:00',     'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'wa’leS 12:00',     'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'DaHjaj 11:00',     'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'wa’Hu’ 12:00',     'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('LLL'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('LLL'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('LLL'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(), m.format('LLL'), 'Today - ' + i + ' days current time');\n\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(), m.format('LLL'), 'Today - ' + i + ' days beginning of day');\n\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(), m.format('LLL'), 'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2012, 0,  1]).format('w ww wo'), '52 52 52.', 'Jan  1 2012 should be week 52');\n    assert.equal(moment([2012, 0,  2]).format('w ww wo'),   '1 01 1.', 'Jan  2 2012 should be week 1');\n    assert.equal(moment([2012, 0,  8]).format('w ww wo'),   '1 01 1.', 'Jan  8 2012 should be week 1');\n    assert.equal(moment([2012, 0,  9]).format('w ww wo'),   '2 02 2.', 'Jan  9 2012 should be week 2');\n    assert.equal(moment([2012, 0, 15]).format('w ww wo'),   '2 02 2.', 'Jan 15 2012 should be week 2');\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\n\n\nfunction localeModule (name, lifecycle) {\n    QUnit.module('locale:' + name, {\n        setup : function () {\n            moment.locale(name);\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            moment.locale('en');\n            teardownDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n    defineCommonLocaleTests(name, -1, -1);\n}\n\nlocaleModule('tr');\n\ntest('parse', function (assert) {\n    var tests = 'Ocak Oca_Şubat Şub_Mart Mar_Nisan Nis_Mayıs May_Haziran Haz_Temmuz Tem_Ağustos Ağu_Eylül Eyl_Ekim Eki_Kasım Kas_Aralık Ara'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, MMMM Do YYYY, h:mm:ss a',      'Pazar, Şubat 14\\'üncü 2010, 3:25:50 pm'],\n            ['ddd, hA',                            'Paz, 3PM'],\n            ['M Mo MM MMMM MMM',                   '2 2\\'nci 02 Şubat Şub'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14\\'üncü 14'],\n            ['d do dddd ddd dd',                   '0 0\\'ıncı Pazar Paz Pz'],\n            ['DDD DDDo DDDD',                      '45 45\\'inci 045'],\n            ['w wo ww',                            '7 7\\'nci 07'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'pm PM'],\n            ['[yılın] DDDo [günü]',                'yılın 45\\'inci günü'],\n            ['LTS',                                '15:25:50'],\n            ['L',                                  '14.02.2010'],\n            ['LL',                                 '14 Şubat 2010'],\n            ['LLL',                                '14 Şubat 2010 15:25'],\n            ['LLLL',                               'Pazar, 14 Şubat 2010 15:25'],\n            ['l',                                  '14.2.2010'],\n            ['ll',                                 '14 Şub 2010'],\n            ['lll',                                '14 Şub 2010 15:25'],\n            ['llll',                               'Paz, 14 Şub 2010 15:25']\n        ],\n        DDDo = [\n            [359, '360\\'ıncı'],\n            [199, '200\\'üncü'],\n            [149, '150\\'nci']\n        ],\n        dt = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        DDDoDt,\n        i;\n\n    for (i = 0; i < a.length; i++) {\n        assert.equal(dt.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n    for (i = 0; i < DDDo.length; i++) {\n        DDDoDt = moment([2010]);\n        assert.equal(DDDoDt.add(DDDo[i][0], 'days').format('DDDo'), DDDo[i][1], DDDo[i][0] + ' ---> ' + DDDo[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1\\'inci', '1st');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2\\'nci', '2nd');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3\\'üncü', '3rd');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4\\'üncü', '4th');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5\\'inci', '5th');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6\\'ncı', '6th');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7\\'nci', '7th');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8\\'inci', '8th');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9\\'uncu', '9th');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10\\'uncu', '10th');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11\\'inci', '11th');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12\\'nci', '12th');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13\\'üncü', '13th');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14\\'üncü', '14th');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15\\'inci', '15th');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16\\'ncı', '16th');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17\\'nci', '17th');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18\\'inci', '18th');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19\\'uncu', '19th');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20\\'nci', '20th');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21\\'inci', '21th');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22\\'nci', '22th');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23\\'üncü', '23th');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24\\'üncü', '24th');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25\\'inci', '25th');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26\\'ncı', '26th');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27\\'nci', '27th');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28\\'inci', '28th');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29\\'uncu', '29th');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30\\'uncu', '30th');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31\\'inci', '31st');\n});\n\ntest('format month', function (assert) {\n    var expected = 'Ocak Oca_Şubat Şub_Mart Mar_Nisan Nis_Mayıs May_Haziran Haz_Temmuz Tem_Ağustos Ağu_Eylül Eyl_Ekim Eki_Kasım Kas_Aralık Ara'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'Pazar Paz Pz_Pazartesi Pts Pt_Salı Sal Sa_Çarşamba Çar Ça_Perşembe Per Pe_Cuma Cum Cu_Cumartesi Cts Ct'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'birkaç saniye', '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'bir dakika',      '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'bir dakika',      '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 dakika',     '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 dakika',    '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'bir saat',       '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'bir saat',       '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 saat',       '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 saat',       '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 saat',      '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'bir gün',         '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'bir gün',         '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 gün',        '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'bir gün',         '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 gün',        '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 gün',       '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'bir ay',       '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'bir ay',       '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'bir ay',       '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 ay',      '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 ay',      '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 ay',      '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'bir ay',       '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 ay',      '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'bir yıl',        '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 yıl',       '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'bir yıl',        '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 yıl',       '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'birkaç saniye sonra',  'prefix');\n    assert.equal(moment(0).from(30000), 'birkaç saniye önce', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'birkaç saniye önce',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'birkaç saniye sonra', 'in a few seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), '5 gün sonra', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'bugün saat 12:00',     'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'bugün saat 12:25',     'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'bugün saat 13:00',     'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'yarın saat 12:00',     'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'bugün saat 11:00',     'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'dün 12:00',            'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('[haftaya] dddd [saat] LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[haftaya] dddd [saat] LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[haftaya] dddd [saat] LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('[geçen hafta] dddd [saat] LT'),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[geçen hafta] dddd [saat] LT'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[geçen hafta] dddd [saat] LT'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2011, 11, 26]).format('w ww wo'), '1 01 1\\'inci', 'Dec 26 2011 should be week 1');\n    assert.equal(moment([2012,  0,  1]).format('w ww wo'), '1 01 1\\'inci', 'Jan  1 2012 should be week 1');\n    assert.equal(moment([2012,  0,  2]).format('w ww wo'), '2 02 2\\'nci', 'Jan  2 2012 should be week 2');\n    assert.equal(moment([2012,  0,  8]).format('w ww wo'), '2 02 2\\'nci', 'Jan  8 2012 should be week 2');\n    assert.equal(moment([2012,  0,  9]).format('w ww wo'), '3 03 3\\'üncü', 'Jan  9 2012 should be week 3');\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\n\n\nfunction localeModule (name, lifecycle) {\n    QUnit.module('locale:' + name, {\n        setup : function () {\n            moment.locale(name);\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            moment.locale('en');\n            teardownDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n    defineCommonLocaleTests(name, -1, -1);\n}\n\nlocaleModule('tzl');\n\ntest('parse', function (assert) {\n    var tests = 'Januar Jan_Fevraglh Fev_Març Mar_Avrïu Avr_Mai Mai_Gün Gün_Julia Jul_Guscht Gus_Setemvar Set_Listopäts Lis_Noemvar Noe_Zecemvar Zec'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, MMMM Do YYYY, h.mm.ss a',      'Súladi, Fevraglh 14. 2010, 3.25.50 d\\'o'],\n            ['ddd, hA',                            'Súl, 3D\\'O'],\n            ['M Mo MM MMMM MMM',                   '2 2. 02 Fevraglh Fev'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14. 14'],\n            ['d do dddd ddd dd',                   '0 0. Súladi Súl Sú'],\n            ['DDD DDDo DDDD',                      '45 45. 045'],\n            ['w wo ww',                            '6 6. 06'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'd\\'o D\\'O'],\n            ['[the] DDDo [day of the year]',       'the 45. day of the year'],\n            ['LTS',                                '15.25.50'],\n            ['L',                                  '14.02.2010'],\n            ['LL',                                 '14. Fevraglh dallas 2010'],\n            ['LLL',                                '14. Fevraglh dallas 2010 15.25'],\n            ['LLLL',                               'Súladi, li 14. Fevraglh dallas 2010 15.25'],\n            ['l',                                  '14.2.2010'],\n            ['ll',                                 '14. Fev dallas 2010'],\n            ['lll',                                '14. Fev dallas 2010 15.25'],\n            ['llll',                               'Súl, li 14. Fev dallas 2010 15.25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1.', '1.');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2.', '2.');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3.', '3.');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4.', '4.');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5.', '5.');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6.', '6.');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7.', '7.');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8.', '8.');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9.', '9.');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10.', '10.');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11.', '11.');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12.', '12.');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13.', '13.');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14.', '14.');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15.', '15.');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16.', '16.');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17.', '17.');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18.', '18.');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19.', '19.');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20.', '20.');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21.', '21.');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22.', '22.');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23.', '23.');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24.', '24.');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25.', '25.');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26.', '26.');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27.', '27.');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28.', '28.');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29.', '29.');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30.', '30.');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31.', '31.');\n});\n\ntest('format month', function (assert) {\n    var expected = 'Januar Jan_Fevraglh Fev_Març Mar_Avrïu Avr_Mai Mai_Gün Gün_Julia Jul_Guscht Gus_Setemvar Set_Listopäts Lis_Noemvar Noe_Zecemvar Zec'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'Súladi Súl Sú_Lúneçi Lún Lú_Maitzi Mai Ma_Márcuri Már Má_Xhúadi Xhú Xh_Viénerçi Vié Vi_Sáturi Sát Sá'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'viensas secunds', '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  '\\'n míut',      '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  '\\'n míut',      '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 míuts',     '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 míuts',    '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  '\\'n þora',       '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  '\\'n þora',       '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 þoras',       '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 þoras',       '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 þoras',      '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  '\\'n ziua',         '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  '\\'n ziua',         '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 ziuas',        '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   '\\'n ziua',         '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 ziuas',        '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 ziuas',       '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  '\\'n mes',       '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  '\\'n mes',       '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  '\\'n mes',       '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 mesen',      '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 mesen',      '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 mesen',      '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   '\\'n mes',       '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 mesen',      '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), '\\'n ar',        '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 ars',       '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   '\\'n ar',        '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 ars',       '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'osprei viensas secunds',  'prefix');\n    assert.equal(moment(0).from(30000), 'ja\\'iensas secunds', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'ja\\'iensas secunds',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'osprei viensas secunds', 'in a few seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), 'osprei 5 ziuas', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'oxhi à 12.00',      'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'oxhi à 12.25',      'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'oxhi à 13.00',      'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'demà à 12.00',      'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'oxhi à 11.00',      'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'ieiri à 12.00',     'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('dddd [à] LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd [à] LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd [à] LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('[sür el] dddd [lasteu à] LT'),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[sür el] dddd [lasteu à] LT'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[sür el] dddd [lasteu à] LT'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\n// Monday is the first day of the week.\n// The week that contains Jan 4th is the first week of the year.\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2012, 0,  1]).format('w ww wo'), '52 52 52.', 'Jan  1 2012 should be week 52');\n    assert.equal(moment([2012, 0,  2]).format('w ww wo'),   '1 01 1.', 'Jan  2 2012 should be week 1');\n    assert.equal(moment([2012, 0,  8]).format('w ww wo'),   '1 01 1.', 'Jan  8 2012 should be week 1');\n    assert.equal(moment([2012, 0,  9]).format('w ww wo'),   '2 02 2.', 'Jan  9 2012 should be week 2');\n    assert.equal(moment([2012, 0, 15]).format('w ww wo'),   '2 02 2.', 'Jan 15 2012 should be week 2');\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\n\n\nfunction localeModule (name, lifecycle) {\n    QUnit.module('locale:' + name, {\n        setup : function () {\n            moment.locale(name);\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            moment.locale('en');\n            teardownDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n    defineCommonLocaleTests(name, -1, -1);\n}\n\nlocaleModule('tzm-latn');\n\ntest('parse', function (assert) {\n    var tests = 'innayr innayr_brˤayrˤ brˤayrˤ_marˤsˤ marˤsˤ_ibrir ibrir_mayyw mayyw_ywnyw ywnyw_ywlywz ywlywz_ɣwšt ɣwšt_šwtanbir šwtanbir_ktˤwbrˤ ktˤwbrˤ_nwwanbir nwwanbir_dwjnbir dwjnbir'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, MMMM Do YYYY, h:mm:ss a',      'asamas, brˤayrˤ 14 2010, 3:25:50 pm'],\n            ['ddd, hA',                            'asamas, 3PM'],\n            ['M Mo MM MMMM MMM',                   '2 2 02 brˤayrˤ brˤayrˤ'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14 14'],\n            ['d do dddd ddd dd',                   '0 0 asamas asamas asamas'],\n            ['DDD DDDo DDDD',                      '45 45 045'],\n            ['w wo ww',                            '8 8 08'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'pm PM'],\n            ['[the] DDDo [day of the year]',       'the 45 day of the year'],\n            ['LTS',                                '15:25:50'],\n            ['L',                                  '14/02/2010'],\n            ['LL',                                 '14 brˤayrˤ 2010'],\n            ['LLL',                                '14 brˤayrˤ 2010 15:25'],\n            ['LLLL',                               'asamas 14 brˤayrˤ 2010 15:25'],\n            ['l',                                  '14/2/2010'],\n            ['ll',                                 '14 brˤayrˤ 2010'],\n            ['lll',                                '14 brˤayrˤ 2010 15:25'],\n            ['llll',                               'asamas 14 brˤayrˤ 2010 15:25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1', '1');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2', '2');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3', '3');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4', '4');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5', '5');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6', '6');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7', '7');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8', '8');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9', '9');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10', '10');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11', '11');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12', '12');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13', '13');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14', '14');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15', '15');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16', '16');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17', '17');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18', '18');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19', '19');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20', '20');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21', '21');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22', '22');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23', '23');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24', '24');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25', '25');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26', '26');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27', '27');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28', '28');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29', '29');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30', '30');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31', '31');\n});\n\ntest('format month', function (assert) {\n    var expected = 'innayr innayr_brˤayrˤ brˤayrˤ_marˤsˤ marˤsˤ_ibrir ibrir_mayyw mayyw_ywnyw ywnyw_ywlywz ywlywz_ɣwšt ɣwšt_šwtanbir šwtanbir_ktˤwbrˤ ktˤwbrˤ_nwwanbir nwwanbir_dwjnbir dwjnbir'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'asamas asamas asamas_aynas aynas aynas_asinas asinas asinas_akras akras akras_akwas akwas akwas_asimwas asimwas asimwas_asiḍyas asiḍyas asiḍyas'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'imik', '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'minuḍ',      '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'minuḍ',      '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 minuḍ',     '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 minuḍ',    '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'saɛa',       '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'saɛa',       '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 tassaɛin',       '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 tassaɛin',       '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 tassaɛin',      '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'ass',         '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'ass',         '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 ossan',        '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'ass',         '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 ossan',        '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 ossan',       '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'ayowr',       '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'ayowr',       '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'ayowr',       '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 iyyirn',      '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 iyyirn',      '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 iyyirn',      '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'ayowr',       '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 iyyirn',      '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'asgas',        '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 isgasn',       '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'asgas',        '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 isgasn',       '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'dadkh s yan imik',  'prefix');\n    assert.equal(moment(0).from(30000), 'yan imik', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'yan imik',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'dadkh s yan imik', 'in a few seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), 'dadkh s yan 5 ossan', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'asdkh g 12:00',   'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'asdkh g 12:25',   'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'asdkh g 13:00',   'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'aska g 12:00',    'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'asdkh g 11:00',   'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'assant g 12:00',  'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('dddd [g] LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd [g] LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd [g] LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('dddd [g] LT'),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd [g] LT'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd [g] LT'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2011, 11, 31]).format('w ww wo'), '1 01 1', 'Dec 31 2011 should be week 1');\n    assert.equal(moment([2012,  0,  6]).format('w ww wo'), '1 01 1', 'Jan  6 2012 should be week 1');\n    assert.equal(moment([2012,  0,  7]).format('w ww wo'), '2 02 2', 'Jan  7 2012 should be week 2');\n    assert.equal(moment([2012,  0, 13]).format('w ww wo'), '2 02 2', 'Jan 13 2012 should be week 2');\n    assert.equal(moment([2012,  0, 14]).format('w ww wo'), '3 03 3', 'Jan 14 2012 should be week 3');\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\n\n\nfunction localeModule (name, lifecycle) {\n    QUnit.module('locale:' + name, {\n        setup : function () {\n            moment.locale(name);\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            moment.locale('en');\n            teardownDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n    defineCommonLocaleTests(name, -1, -1);\n}\n\nlocaleModule('tzm');\n\ntest('parse', function (assert) {\n    var tests = 'ⵉⵏⵏⴰⵢⵔ ⵉⵏⵏⴰⵢⵔ_ⴱⵕⴰⵢⵕ ⴱⵕⴰⵢⵕ_ⵎⴰⵕⵚ ⵎⴰⵕⵚ_ⵉⴱⵔⵉⵔ ⵉⴱⵔⵉⵔ_ⵎⴰⵢⵢⵓ ⵎⴰⵢⵢⵓ_ⵢⵓⵏⵢⵓ ⵢⵓⵏⵢⵓ_ⵢⵓⵍⵢⵓⵣ ⵢⵓⵍⵢⵓⵣ_ⵖⵓⵛⵜ ⵖⵓⵛⵜ_ⵛⵓⵜⴰⵏⴱⵉⵔ ⵛⵓⵜⴰⵏⴱⵉⵔ_ⴽⵟⵓⴱⵕ ⴽⵟⵓⴱⵕ_ⵏⵓⵡⴰⵏⴱⵉⵔ ⵏⵓⵡⴰⵏⴱⵉⵔ_ⴷⵓⵊⵏⴱⵉⵔ ⴷⵓⵊⵏⴱⵉⵔ'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, MMMM Do YYYY, h:mm:ss a',      'ⴰⵙⴰⵎⴰⵙ, ⴱⵕⴰⵢⵕ 14 2010, 3:25:50 pm'],\n            ['ddd, hA',                            'ⴰⵙⴰⵎⴰⵙ, 3PM'],\n            ['M Mo MM MMMM MMM',                   '2 2 02 ⴱⵕⴰⵢⵕ ⴱⵕⴰⵢⵕ'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14 14'],\n            ['d do dddd ddd dd',                   '0 0 ⴰⵙⴰⵎⴰⵙ ⴰⵙⴰⵎⴰⵙ ⴰⵙⴰⵎⴰⵙ'],\n            ['DDD DDDo DDDD',                      '45 45 045'],\n            ['w wo ww',                            '8 8 08'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'pm PM'],\n            ['[the] DDDo [day of the year]',       'the 45 day of the year'],\n            ['LTS',                                '15:25:50'],\n            ['L',                                  '14/02/2010'],\n            ['LL',                                 '14 ⴱⵕⴰⵢⵕ 2010'],\n            ['LLL',                                '14 ⴱⵕⴰⵢⵕ 2010 15:25'],\n            ['LLLL',                               'ⴰⵙⴰⵎⴰⵙ 14 ⴱⵕⴰⵢⵕ 2010 15:25'],\n            ['l',                                  '14/2/2010'],\n            ['ll',                                 '14 ⴱⵕⴰⵢⵕ 2010'],\n            ['lll',                                '14 ⴱⵕⴰⵢⵕ 2010 15:25'],\n            ['llll',                               'ⴰⵙⴰⵎⴰⵙ 14 ⴱⵕⴰⵢⵕ 2010 15:25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1', '1');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2', '2');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3', '3');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4', '4');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5', '5');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6', '6');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7', '7');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8', '8');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9', '9');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10', '10');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11', '11');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12', '12');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13', '13');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14', '14');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15', '15');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16', '16');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17', '17');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18', '18');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19', '19');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20', '20');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21', '21');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22', '22');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23', '23');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24', '24');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25', '25');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26', '26');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27', '27');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28', '28');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29', '29');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30', '30');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31', '31');\n});\n\ntest('format month', function (assert) {\n    var expected = 'ⵉⵏⵏⴰⵢⵔ ⵉⵏⵏⴰⵢⵔ_ⴱⵕⴰⵢⵕ ⴱⵕⴰⵢⵕ_ⵎⴰⵕⵚ ⵎⴰⵕⵚ_ⵉⴱⵔⵉⵔ ⵉⴱⵔⵉⵔ_ⵎⴰⵢⵢⵓ ⵎⴰⵢⵢⵓ_ⵢⵓⵏⵢⵓ ⵢⵓⵏⵢⵓ_ⵢⵓⵍⵢⵓⵣ ⵢⵓⵍⵢⵓⵣ_ⵖⵓⵛⵜ ⵖⵓⵛⵜ_ⵛⵓⵜⴰⵏⴱⵉⵔ ⵛⵓⵜⴰⵏⴱⵉⵔ_ⴽⵟⵓⴱⵕ ⴽⵟⵓⴱⵕ_ⵏⵓⵡⴰⵏⴱⵉⵔ ⵏⵓⵡⴰⵏⴱⵉⵔ_ⴷⵓⵊⵏⴱⵉⵔ ⴷⵓⵊⵏⴱⵉⵔ'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'ⴰⵙⴰⵎⴰⵙ ⴰⵙⴰⵎⴰⵙ ⴰⵙⴰⵎⴰⵙ_ⴰⵢⵏⴰⵙ ⴰⵢⵏⴰⵙ ⴰⵢⵏⴰⵙ_ⴰⵙⵉⵏⴰⵙ ⴰⵙⵉⵏⴰⵙ ⴰⵙⵉⵏⴰⵙ_ⴰⴽⵔⴰⵙ ⴰⴽⵔⴰⵙ ⴰⴽⵔⴰⵙ_ⴰⴽⵡⴰⵙ ⴰⴽⵡⴰⵙ ⴰⴽⵡⴰⵙ_ⴰⵙⵉⵎⵡⴰⵙ ⴰⵙⵉⵎⵡⴰⵙ ⴰⵙⵉⵎⵡⴰⵙ_ⴰⵙⵉⴹⵢⴰⵙ ⴰⵙⵉⴹⵢⴰⵙ ⴰⵙⵉⴹⵢⴰⵙ'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'ⵉⵎⵉⴽ', '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'ⵎⵉⵏⵓⴺ',      '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'ⵎⵉⵏⵓⴺ',      '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 ⵎⵉⵏⵓⴺ',     '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 ⵎⵉⵏⵓⴺ',    '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'ⵙⴰⵄⴰ',       '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'ⵙⴰⵄⴰ',       '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 ⵜⴰⵙⵙⴰⵄⵉⵏ',       '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 ⵜⴰⵙⵙⴰⵄⵉⵏ',       '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 ⵜⴰⵙⵙⴰⵄⵉⵏ',      '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'ⴰⵙⵙ',         '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'ⴰⵙⵙ',         '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 oⵙⵙⴰⵏ',        '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'ⴰⵙⵙ',         '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 oⵙⵙⴰⵏ',        '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 oⵙⵙⴰⵏ',       '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'ⴰⵢoⵓⵔ',       '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'ⴰⵢoⵓⵔ',       '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'ⴰⵢoⵓⵔ',       '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 ⵉⵢⵢⵉⵔⵏ',      '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 ⵉⵢⵢⵉⵔⵏ',      '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 ⵉⵢⵢⵉⵔⵏ',      '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'ⴰⵢoⵓⵔ',       '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 ⵉⵢⵢⵉⵔⵏ',      '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'ⴰⵙⴳⴰⵙ',        '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 ⵉⵙⴳⴰⵙⵏ',       '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'ⴰⵙⴳⴰⵙ',        '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 ⵉⵙⴳⴰⵙⵏ',       '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'ⴷⴰⴷⵅ ⵙ ⵢⴰⵏ ⵉⵎⵉⴽ',  'prefix');\n    assert.equal(moment(0).from(30000), 'ⵢⴰⵏ ⵉⵎⵉⴽ', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'ⵢⴰⵏ ⵉⵎⵉⴽ',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'ⴷⴰⴷⵅ ⵙ ⵢⴰⵏ ⵉⵎⵉⴽ', 'in a few seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), 'ⴷⴰⴷⵅ ⵙ ⵢⴰⵏ 5 oⵙⵙⴰⵏ', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'ⴰⵙⴷⵅ ⴴ 12:00',  'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'ⴰⵙⴷⵅ ⴴ 12:25',  'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'ⴰⵙⴷⵅ ⴴ 13:00',  'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'ⴰⵙⴽⴰ ⴴ 12:00',  'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'ⴰⵙⴷⵅ ⴴ 11:00',  'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'ⴰⵚⴰⵏⵜ ⴴ 12:00',  'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('dddd [ⴴ] LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd [ⴴ] LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd [ⴴ] LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('dddd [ⴴ] LT'),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd [ⴴ] LT'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd [ⴴ] LT'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2011, 11, 31]).format('w ww wo'), '1 01 1', 'Dec 31 2011 should be week 1');\n    assert.equal(moment([2012,  0,  6]).format('w ww wo'), '1 01 1', 'Jan  6 2012 should be week 1');\n    assert.equal(moment([2012,  0,  7]).format('w ww wo'), '2 02 2', 'Jan  7 2012 should be week 2');\n    assert.equal(moment([2012,  0, 13]).format('w ww wo'), '2 02 2', 'Jan 13 2012 should be week 2');\n    assert.equal(moment([2012,  0, 14]).format('w ww wo'), '3 03 3', 'Jan 14 2012 should be week 3');\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\n\n\nfunction localeModule (name, lifecycle) {\n    QUnit.module('locale:' + name, {\n        setup : function () {\n            moment.locale(name);\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            moment.locale('en');\n            teardownDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n    defineCommonLocaleTests(name, -1, -1);\n}\n\nlocaleModule('uk');\n\ntest('parse', function (assert) {\n    var tests = 'січень січ_лютий лют_березень бер_квітень квіт_травень трав_червень черв_липень лип_серпень серп_вересень вер_жовтень жовт_листопад лист_грудень груд'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, Do MMMM YYYY, HH:mm:ss',       'неділя, 14-го лютого 2010, 15:25:50'],\n            ['ddd, h A',                           'нд, 3 дня'],\n            ['M Mo MM MMMM MMM',                   '2 2-й 02 лютий лют'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14-го 14'],\n            ['d do dddd ddd dd',                   '0 0-й неділя нд нд'],\n            ['DDD DDDo DDDD',                      '45 45-й 045'],\n            ['w wo ww',                            '7 7-й 07'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'дня дня'],\n            ['DDDo [день року]',                  '45-й день року'],\n            ['LTS',                                '15:25:50'],\n            ['L',                                  '14.02.2010'],\n            ['LL',                                 '14 лютого 2010 р.'],\n            ['LLL',                                '14 лютого 2010 р., 15:25'],\n            ['LLLL',                               'неділя, 14 лютого 2010 р., 15:25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format meridiem', function (assert) {\n    assert.equal(moment([2012, 11, 28, 0, 0]).format('A'), 'ночі', 'night');\n    assert.equal(moment([2012, 11, 28, 3, 59]).format('A'), 'ночі', 'night');\n    assert.equal(moment([2012, 11, 28, 4, 0]).format('A'), 'ранку', 'morning');\n    assert.equal(moment([2012, 11, 28, 11, 59]).format('A'), 'ранку', 'morning');\n    assert.equal(moment([2012, 11, 28, 12, 0]).format('A'), 'дня', 'afternoon');\n    assert.equal(moment([2012, 11, 28, 16, 59]).format('A'), 'дня', 'afternoon');\n    assert.equal(moment([2012, 11, 28, 17, 0]).format('A'), 'вечора', 'evening');\n    assert.equal(moment([2012, 11, 28, 23, 59]).format('A'), 'вечора', 'evening');\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1-й', '1-й');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2-й', '2-й');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3-й', '3-й');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4-й', '4-й');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5-й', '5-й');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6-й', '6-й');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7-й', '7-й');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8-й', '8-й');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9-й', '9-й');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10-й', '10-й');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11-й', '11-й');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12-й', '12-й');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13-й', '13-й');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14-й', '14-й');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15-й', '15-й');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16-й', '16-й');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17-й', '17-й');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18-й', '18-й');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19-й', '19-й');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20-й', '20-й');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21-й', '21-й');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22-й', '22-й');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23-й', '23-й');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24-й', '24-й');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25-й', '25-й');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26-й', '26-й');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27-й', '27-й');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28-й', '28-й');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29-й', '29-й');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30-й', '30-й');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31-й', '31-й');\n});\n\ntest('format month', function (assert) {\n    var expected = 'січень січ_лютий лют_березень бер_квітень квіт_травень трав_червень черв_липень лип_серпень серп_вересень вер_жовтень жовт_листопад лист_грудень груд'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format month case', function (assert) {\n    var months = {\n        'nominative': 'січень_лютий_березень_квітень_травень_червень_липень_серпень_вересень_жовтень_листопад_грудень'.split('_'),\n        'accusative': 'січня_лютого_березня_квітня_травня_червня_липня_серпня_вересня_жовтня_листопада_грудня'.split('_')\n    }, i;\n    for (i = 0; i < 12; i++) {\n        assert.equal(moment([2011, i, 1]).format('D MMMM'), '1 ' + months.accusative[i], '1 ' + months.accusative[i]);\n        assert.equal(moment([2011, i, 1]).format('MMMM'), months.nominative[i], '1 ' + months.nominative[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'неділя нд нд_понеділок пн пн_вівторок вт вт_середа ср ср_четвер чт чт_п’ятниця пт пт_субота сб сб'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'декілька секунд',    '44 seconds = seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'хвилина',   '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'хвилина',   '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 хвилини',  '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 хвилини', '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'годину',    '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'годину',    '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 години',    '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 годин',    '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 година',   '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'день',      '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'день',      '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 дні',     '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'день',      '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 днів',     '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 11}), true),  '11 днів',     '11 days = 11 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 21}), true),  '21 день',     '21 days = 21 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 днів',    '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'місяць',    '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'місяць',    '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'місяць',    '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 місяці',   '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 місяці',   '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 місяці',   '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'місяць',    '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 місяців',   '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'рік',     '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 роки',    '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'рік',     '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 років',    '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'за декілька секунд', 'prefix');\n    assert.equal(moment(0).from(30000), 'декілька секунд тому', 'suffix');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'за декілька секунд', 'in seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), 'за 5 днів', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'Сьогодні о 12:00',   'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'Сьогодні о 12:25',   'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'Сьогодні о 13:00',   'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'Завтра о 12:00',     'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 2}).calendar(),  'Сьогодні о 10:00',   'Now minus 2 hours');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'Вчора о 12:00',      'yesterday at the same time');\n    // A special case for Ukrainian since 11 hours have different preposition\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'Сьогодні об 11:00',  'same day at 11 o\\'clock');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('[У] dddd [о' + (m.hours() === 11 ? 'б' : '') + '] LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[У] dddd [о] LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[У] dddd [о] LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n\n    function makeFormat(d) {\n        switch (d.day()) {\n            case 0:\n            case 3:\n            case 5:\n            case 6:\n                return '[Минулої] dddd [о' + (d.hours() === 11 ? 'б' : '') + '] LT';\n            case 1:\n            case 2:\n            case 4:\n                return '[Минулого] dddd [о' + (d.hours() === 11 ? 'б' : '') + '] LT';\n        }\n    }\n\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format(makeFormat(m)),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format(makeFormat(m)),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format(makeFormat(m)),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2011, 11, 26]).format('w ww wo'), '1 01 1-й', 'Dec 26 2011 should be week 1');\n    assert.equal(moment([2012,  0,  1]).format('w ww wo'), '1 01 1-й', 'Jan  1 2012 should be week 1');\n    assert.equal(moment([2012,  0,  2]).format('w ww wo'), '2 02 2-й', 'Jan  2 2012 should be week 2');\n    assert.equal(moment([2012,  0,  8]).format('w ww wo'), '2 02 2-й', 'Jan  8 2012 should be week 2');\n    assert.equal(moment([2012,  0,  9]).format('w ww wo'), '3 03 3-й', 'Jan  9 2012 should be week 3');\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\n\n\nfunction localeModule (name, lifecycle) {\n    QUnit.module('locale:' + name, {\n        setup : function () {\n            moment.locale(name);\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            moment.locale('en');\n            teardownDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n    defineCommonLocaleTests(name, -1, -1);\n}\n\nlocaleModule('ur');\n\nvar months = [\n    'جنوری',\n    'فروری',\n    'مارچ',\n    'اپریل',\n    'مئی',\n    'جون',\n    'جولائی',\n    'اگست',\n    'ستمبر',\n    'اکتوبر',\n    'نومبر',\n    'دسمبر'\n];\nvar days = [\n    'اتوار',\n    'پیر',\n    'منگل',\n    'بدھ',\n    'جمعرات',\n    'جمعہ',\n    'ہفتہ'\n];\n\ntest('parse', function (assert) {\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (var i = 0; i < 12; i++) {\n        equalTest(months[i], 'MMM', i);\n        equalTest(months[i], 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, MMMM Do YYYY, h:mm:ss a',      'اتوار، فروری 14 2010، 3:25:50 شام'],\n            ['ddd, hA',                            'اتوار، 3شام'],\n            ['M Mo MM MMMM MMM',                   '2 2 02 فروری فروری'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14 14'],\n            ['d do dddd ddd dd',                   '0 0 اتوار اتوار اتوار'],\n            ['DDD DDDo DDDD',                      '45 45 045'],\n            ['w wo ww',                            '6 6 06'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'شام شام'],\n            ['[سال کا] DDDo[واں دن]',       'سال کا 45واں دن'],\n            ['LTS',                                '15:25:50'],\n            ['L',                                  '14/02/2010'],\n            ['LL',                                 '14 فروری 2010'],\n            ['LLL',                                '14 فروری 2010 15:25'],\n            ['LLLL',                               'اتوار، 14 فروری 2010 15:25'],\n            ['l',                                  '14/2/2010'],\n            ['ll',                                 '14 فروری 2010'],\n            ['lll',                                '14 فروری 2010 15:25'],\n            ['llll',                               'اتوار، 14 فروری 2010 15:25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1', '1');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2', '2');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3', '3');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4', '4');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5', '5');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6', '6');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7', '7');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8', '8');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9', '9');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10', '10');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11', '11');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12', '12');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13', '13');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14', '14');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15', '15');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16', '16');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17', '17');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18', '18');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19', '19');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20', '20');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21', '21');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22', '22');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23', '23');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24', '24');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25', '25');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26', '26');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27', '27');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28', '28');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29', '29');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30', '30');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31', '31');\n});\n\ntest('format month', function (assert) {\n    for (var i = 0; i < months.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), months[i] + ' ' + months[i], months[i] + ' ' + months[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    for (var i = 0; i < days.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), days[i] + ' ' + days[i] + ' ' + days[i], days[i] + ' ' + days[i] + ' ' + days[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'چند سیکنڈ', '44 seconds = چند سیکنڈ');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'ایک منٹ',      '45 seconds = ایک منٹ');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'ایک منٹ',      '89 seconds = ایک منٹ');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 منٹ',     '90 seconds = 2 منٹ');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 منٹ',    '44 minutes = 44 منٹ');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'ایک گھنٹہ',       '45 minutes = ایک گھنٹہ');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'ایک گھنٹہ',       '89 minutes = ایک گھنٹہ');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 گھنٹے',       '90 minutes = 2 گھنٹے');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 گھنٹے',       '5 hours = 5 گھنٹے');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 گھنٹے',      '21 hours = 21 گھنٹے');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'ایک دن',         '22 hours = ایک دن');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'ایک دن',         '35 hours = ایک دن');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 دن',        '36 hours = 2 دن');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'ایک دن',         '1 day = ایک دن');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 دن',        '5 days = 5 دن');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 دن',       '25 days = 25 دن');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'ایک ماہ',       '26 days = ایک ماہ');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'ایک ماہ',       '30 days = ایک ماہ');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'ایک ماہ',       '43 days = ایک ماہ');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 ماہ',      '46 days = 2 ماہ');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 ماہ',      '75 days = 2 ماہ');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 ماہ',      '76 days = 3 ماہ');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'ایک ماہ',       '1 month = ایک ماہ');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 ماہ',      '5 months = 5 ماہ');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'ایک سال',        '345 days = ایک سال');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 سال',       '548 days = 2 سال');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'ایک سال',        '1 year = ایک سال');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 سال',       '5 years = 5 سال');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'چند سیکنڈ بعد',  'prefix');\n    assert.equal(moment(0).from(30000), 'چند سیکنڈ قبل', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'چند سیکنڈ قبل',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'چند سیکنڈ بعد', 'in a few seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), '5 دن بعد', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'آج بوقت 12:00',      'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'آج بوقت 12:25',      'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'آج بوقت 13:00',      'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'کل بوقت 12:00',   'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'آج بوقت 11:00',      'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'گذشتہ روز بوقت 12:00',  'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('dddd [بوقت] LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd [بوقت] LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd [بوقت] LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('[گذشتہ] dddd [بوقت] LT'),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[گذشتہ] dddd [بوقت] LT'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[گذشتہ] dddd [بوقت] LT'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2012, 0,  1]).format('w ww wo'), '52 52 52', 'Jan  1 2012 should be week 52');\n    assert.equal(moment([2012, 0,  2]).format('w ww wo'),   '1 01 1', 'Jan  2 2012 should be week 1');\n    assert.equal(moment([2012, 0,  8]).format('w ww wo'),   '1 01 1', 'Jan  8 2012 should be week 1');\n    assert.equal(moment([2012, 0,  9]).format('w ww wo'),   '2 02 2', 'Jan  9 2012 should be week 2');\n    assert.equal(moment([2012, 0, 15]).format('w ww wo'),   '2 02 2', 'Jan 15 2012 should be week 2');\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\n\n\nfunction localeModule (name, lifecycle) {\n    QUnit.module('locale:' + name, {\n        setup : function () {\n            moment.locale(name);\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            moment.locale('en');\n            teardownDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n    defineCommonLocaleTests(name, -1, -1);\n}\n\nlocaleModule('uz-latn');\n\ntest('parse', function (assert) {\n    var tests = 'Yanvar Yan_Fevral Fev_Mart Mar_Aprel Apr_May May_Iyun Iyun_Iyul Iyul_Avgust Avg_Sentabr Sen_Oktabr Okt_Noyabr Noy_Dekabr Dek'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, Do-MMMM YYYY, h:mm:ss',        'Yakshanba, 14-Fevral 2010, 3:25:50'],\n            ['ddd, h:mm',                          'Yak, 3:25'],\n            ['M Mo MM MMMM MMM',                   '2 2 02 Fevral Fev'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14 14'],\n            ['d do dddd ddd dd',                   '0 0 Yakshanba Yak Ya'],\n            ['DDD DDDo DDDD',                      '45 45 045'],\n            ['w wo ww',                            '7 7 07'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'pm PM'],\n            ['[yilning] DDDo-[kuni]',             'yilning 45-kuni'],\n            ['LTS',                                '15:25:50'],\n            ['L',                                  '14/02/2010'],\n            ['LL',                                 '14 Fevral 2010'],\n            ['LLL',                                '14 Fevral 2010 15:25'],\n            ['LLLL',                               '14 Fevral 2010, Yakshanba 15:25'],\n            ['l',                                  '14/2/2010'],\n            ['ll',                                 '14 Fev 2010'],\n            ['lll',                                '14 Fev 2010 15:25'],\n            ['llll',                               '14 Fev 2010, Yak 15:25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2016, 0, 1]).format('DDDo'), '1', '1');\n    assert.equal(moment([2016, 0, 2]).format('DDDo'), '2', '2');\n    assert.equal(moment([2016, 0, 3]).format('DDDo'), '3', '3');\n    assert.equal(moment([2016, 0, 4]).format('DDDo'), '4', '4');\n    assert.equal(moment([2016, 0, 5]).format('DDDo'), '5', '5');\n    assert.equal(moment([2016, 0, 6]).format('DDDo'), '6', '6');\n    assert.equal(moment([2016, 0, 7]).format('DDDo'), '7', '7');\n    assert.equal(moment([2016, 0, 8]).format('DDDo'), '8', '8');\n    assert.equal(moment([2016, 0, 9]).format('DDDo'), '9', '9');\n    assert.equal(moment([2016, 0, 10]).format('DDDo'), '10', '10');\n\n    assert.equal(moment([2016, 0, 11]).format('DDDo'), '11', '11');\n    assert.equal(moment([2016, 0, 12]).format('DDDo'), '12', '12');\n    assert.equal(moment([2016, 0, 13]).format('DDDo'), '13', '13');\n    assert.equal(moment([2016, 0, 14]).format('DDDo'), '14', '14');\n    assert.equal(moment([2016, 0, 15]).format('DDDo'), '15', '15');\n    assert.equal(moment([2016, 0, 16]).format('DDDo'), '16', '16');\n    assert.equal(moment([2016, 0, 17]).format('DDDo'), '17', '17');\n    assert.equal(moment([2016, 0, 18]).format('DDDo'), '18', '18');\n    assert.equal(moment([2016, 0, 19]).format('DDDo'), '19', '19');\n    assert.equal(moment([2016, 0, 20]).format('DDDo'), '20', '20');\n\n    assert.equal(moment([2016, 0, 21]).format('DDDo'), '21', '21');\n    assert.equal(moment([2016, 0, 22]).format('DDDo'), '22', '22');\n    assert.equal(moment([2016, 0, 23]).format('DDDo'), '23', '23');\n    assert.equal(moment([2016, 0, 24]).format('DDDo'), '24', '24');\n    assert.equal(moment([2016, 0, 25]).format('DDDo'), '25', '25');\n    assert.equal(moment([2016, 0, 26]).format('DDDo'), '26', '26');\n    assert.equal(moment([2016, 0, 27]).format('DDDo'), '27', '27');\n    assert.equal(moment([2016, 0, 28]).format('DDDo'), '28', '28');\n    assert.equal(moment([2016, 0, 29]).format('DDDo'), '29', '29');\n    assert.equal(moment([2016, 0, 30]).format('DDDo'), '30', '30');\n\n    assert.equal(moment([2016, 0, 31]).format('DDDo'), '31', '31');\n});\n\ntest('format month', function (assert) {\n    var expected = 'Yanvar Yan_Fevral Fev_Mart Mar_Aprel Apr_May May_Iyun Iyun_Iyul Iyul_Avgust Avg_Sentabr Sen_Oktabr Okt_Noyabr Noy_Dekabr Dek'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2016, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'Yakshanba Yak Ya_Dushanba Dush Du_Seshanba Sesh Se_Chorshanba Chor Cho_Payshanba Pay Pa_Juma Jum Ju_Shanba Shan Sha'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2016, 0, 3 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2017, 1, 28]);\n    assert.equal(start.from(moment([2017, 1, 28]).add({s: 44}), true),  'soniya', '44 soniya = soniya');\n    assert.equal(start.from(moment([2017, 1, 28]).add({s: 45}), true),  'bir daqiqa',      '45 soniya = bir daqiqa');\n    assert.equal(start.from(moment([2017, 1, 28]).add({s: 89}), true),  'bir daqiqa',      '89 soniya = bir daqiqa');\n    assert.equal(start.from(moment([2017, 1, 28]).add({s: 90}), true),  '2 daqiqa',     '90 soniya = 2 daqiqa');\n    assert.equal(start.from(moment([2017, 1, 28]).add({m: 44}), true),  '44 daqiqa',    '44 daqiqa = 44 daqiqa');\n    assert.equal(start.from(moment([2017, 1, 28]).add({m: 45}), true),  'bir soat',       '45 minut = bir soat');\n    assert.equal(start.from(moment([2017, 1, 28]).add({m: 89}), true),  'bir soat',       '89 minut = bir soat');\n    assert.equal(start.from(moment([2017, 1, 28]).add({m: 90}), true),  '2 soat',       '90 minut = 2 soat');\n    assert.equal(start.from(moment([2017, 1, 28]).add({h: 5}), true),   '5 soat',       '5 soat = 5 soat');\n    assert.equal(start.from(moment([2017, 1, 28]).add({h: 21}), true),  '21 soat',      '21 soat = 21 soat');\n    assert.equal(start.from(moment([2017, 1, 28]).add({h: 22}), true),  'bir kun',         '22 soat = bir kun');\n    assert.equal(start.from(moment([2017, 1, 28]).add({h: 35}), true),  'bir kun',         '35 soat = bir kun');\n    assert.equal(start.from(moment([2017, 1, 28]).add({h: 36}), true),  '2 kun',        '36 soat = 2 kun');\n    assert.equal(start.from(moment([2017, 1, 28]).add({d: 1}), true),   'bir kun',         '1 kun = 1 kun');\n    assert.equal(start.from(moment([2017, 1, 28]).add({d: 5}), true),   '5 kun',        '5 kun = 5 kun');\n    assert.equal(start.from(moment([2017, 1, 28]).add({d: 25}), true),  '25 kun',       '25 kun = 25 kun');\n    assert.equal(start.from(moment([2017, 1, 28]).add({d: 26}), true),  'bir oy',       '26 kun = bir oy');\n    assert.equal(start.from(moment([2017, 1, 28]).add({d: 30}), true),  'bir oy',       '30 kun = bir oy');\n    assert.equal(start.from(moment([2017, 1, 28]).add({d: 43}), true),  'bir oy',       '45 kun = bir oy');\n    assert.equal(start.from(moment([2017, 1, 28]).add({d: 46}), true),  '2 oy',      '46 kun = 2 oy');\n    assert.equal(start.from(moment([2017, 1, 28]).add({d: 74}), true),  '2 oy',      '75 kun = 2 oy');\n    assert.equal(start.from(moment([2017, 1, 28]).add({d: 76}), true),  '3 oy',      '76 kun = 3 oy');\n    assert.equal(start.from(moment([2017, 1, 28]).add({M: 1}), true),   'bir oy',       'bir oy = bir oy');\n    assert.equal(start.from(moment([2017, 1, 28]).add({M: 5}), true),   '5 oy',      '5 oy = 5 oy');\n    assert.equal(start.from(moment([2017, 1, 28]).add({d: 345}), true), 'bir yil',        '345 kun = bir yil');\n    assert.equal(start.from(moment([2017, 1, 28]).add({d: 548}), true), '2 yil',       '548 kun = 2 yil');\n    assert.equal(start.from(moment([2017, 1, 28]).add({y: 1}), true),   'bir yil',        '1 yil = bir yil');\n    assert.equal(start.from(moment([2017, 1, 28]).add({y: 5}), true),   '5 yil',       '5 yil = 5 yil');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'Yaqin soniya ichida',  'prefix');\n    assert.equal(moment(0).from(30000), 'Bir necha soniya oldin', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'Bir necha soniya oldin',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'Yaqin soniya ichida', 'in a few seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), 'Yaqin 5 kun ichida', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'Bugun soat 12:00 da',  'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'Bugun soat 12:25 da',  'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'Bugun soat 13:00 da',  'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'Ertaga 12:00 da',      'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'Bugun soat 11:00 da',  'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'Kecha soat 12:00 da',   'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('dddd [kuni soat] LT [da]'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd [kuni soat] LT [da]'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd [kuni soat] LT [da]'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('[O\\'tgan] dddd [kuni soat] LT [da]'),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[O\\'tgan] dddd [kuni soat] LT [da]'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[O\\'tgan] dddd [kuni soat] LT [da]'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2012, 0,  1]).format('w ww wo'), '1 01 1', 'Jan  1 2012 should be week 52');\n    assert.equal(moment([2012, 0,  2]).format('w ww wo'),   '2 02 2', 'Jan  2 2012 should be week 1');\n    assert.equal(moment([2012, 0,  8]).format('w ww wo'),   '2 02 2', 'Jan  8 2012 should be week 1');\n    assert.equal(moment([2012, 0,  9]).format('w ww wo'),   '3 03 3', 'Jan  9 2012 should be week 2');\n    assert.equal(moment([2012, 0, 15]).format('w ww wo'),   '3 03 3', 'Jan 15 2012 should be week 2');\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\n\n\nfunction localeModule (name, lifecycle) {\n    QUnit.module('locale:' + name, {\n        setup : function () {\n            moment.locale(name);\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            moment.locale('en');\n            teardownDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n    defineCommonLocaleTests(name, -1, -1);\n}\n\nlocaleModule('uz');\n\ntest('parse', function (assert) {\n    var tests = 'январ янв_феврал фев_март мар_апрел апр_май май_июн июн_июл июл_август авг_сентябр сен_октябр окт_ноябр ноя_декабр дек'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, Do-MMMM YYYY, h:mm:ss',        'Якшанба, 14-феврал 2010, 3:25:50'],\n            ['ddd, h:mm',                          'Якш, 3:25'],\n            ['M Mo MM MMMM MMM',                   '2 2 02 феврал фев'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14 14'],\n            ['d do dddd ddd dd',                   '0 0 Якшанба Якш Як'],\n            ['DDD DDDo DDDD',                      '45 45 045'],\n            ['w wo ww',                            '7 7 07'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'pm PM'],\n            ['[йилнинг] DDDo-[куни]',             'йилнинг 45-куни'],\n            ['LTS',                                '15:25:50'],\n            ['L',                                  '14/02/2010'],\n            ['LL',                                 '14 феврал 2010'],\n            ['LLL',                                '14 феврал 2010 15:25'],\n            ['LLLL',                               '14 феврал 2010, Якшанба 15:25'],\n            ['l',                                  '14/2/2010'],\n            ['ll',                                 '14 фев 2010'],\n            ['lll',                                '14 фев 2010 15:25'],\n            ['llll',                               '14 фев 2010, Якш 15:25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1', '1');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2', '2');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3', '3');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4', '4');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5', '5');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6', '6');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7', '7');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8', '8');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9', '9');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10', '10');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11', '11');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12', '12');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13', '13');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14', '14');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15', '15');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16', '16');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17', '17');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18', '18');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19', '19');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20', '20');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21', '21');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22', '22');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23', '23');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24', '24');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25', '25');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26', '26');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27', '27');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28', '28');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29', '29');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30', '30');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31', '31');\n});\n\ntest('format month', function (assert) {\n    var expected = 'январ янв_феврал фев_март мар_апрел апр_май май_июн июн_июл июл_август авг_сентябр сен_октябр окт_ноябр ноя_декабр дек'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'Якшанба Якш Як_Душанба Душ Ду_Сешанба Сеш Се_Чоршанба Чор Чо_Пайшанба Пай Па_Жума Жум Жу_Шанба Шан Ша'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'фурсат', '44 секунд = фурсат');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'бир дакика',      '45 секунд = бир дакика');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'бир дакика',      '89 секунд = бир дакика');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 дакика',     '90 секунд = 2 дакика');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 дакика',    '44 дакика = 44 дакика');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'бир соат',       '45 минут = бир соат');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'бир соат',       '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 соат',       '90 минут = 2 соат');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 соат',       '5 соат = 5 соат');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 соат',      '21 соат = 21 соат');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'бир кун',         '22 соат = бир кун');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'бир кун',         '35 соат = бир кун');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 кун',        '36 соат = 2 кун');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'бир кун',         '1 кун = 1 кун');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 кун',        '5 кун = 5 кун');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 кун',       '25 кун = 25 кун');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'бир ой',       '26 кун = бир ой');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'бир ой',       '30 кун = бир ой');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'бир ой',       '45 кун = бир ой');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 ой',      '46 кун = 2 ой');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 ой',      '75 кун = 2 ой');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 ой',      '76 кун = 3 ой');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'бир ой',       'бир ой = бир ой');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 ой',      '5 ой = 5 ой');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'бир йил',        '345 кун = бир йил');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 йил',       '548 кун = 2 йил');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'бир йил',        '1 йил = бир йил');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 йил',       '5 йил = 5 йил');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'Якин фурсат ичида',  'prefix');\n    assert.equal(moment(0).from(30000), 'Бир неча фурсат олдин', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'Бир неча фурсат олдин',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'Якин фурсат ичида', 'in a few seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), 'Якин 5 кун ичида', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'Бугун соат 12:00 да',  'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'Бугун соат 12:25 да',  'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'Бугун соат 13:00 да',  'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'Эртага 12:00 да',      'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'Бугун соат 11:00 да',  'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'Кеча соат 12:00 да',   'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('dddd [куни соат] LT [да]'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd [куни соат] LT [да]'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd [куни соат] LT [да]'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('[Утган] dddd [куни соат] LT [да]'),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[Утган] dddd [куни соат] LT [да]'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[Утган] dddd [куни соат] LT [да]'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2012, 0,  1]).format('w ww wo'), '1 01 1', 'Jan  1 2012 should be week 52');\n    assert.equal(moment([2012, 0,  2]).format('w ww wo'),   '2 02 2', 'Jan  2 2012 should be week 1');\n    assert.equal(moment([2012, 0,  8]).format('w ww wo'),   '2 02 2', 'Jan  8 2012 should be week 1');\n    assert.equal(moment([2012, 0,  9]).format('w ww wo'),   '3 03 3', 'Jan  9 2012 should be week 2');\n    assert.equal(moment([2012, 0, 15]).format('w ww wo'),   '3 03 3', 'Jan 15 2012 should be week 2');\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\n\n\nfunction localeModule (name, lifecycle) {\n    QUnit.module('locale:' + name, {\n        setup : function () {\n            moment.locale(name);\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            moment.locale('en');\n            teardownDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n    defineCommonLocaleTests(name, -1, -1);\n}\n\nlocaleModule('vi');\n\ntest('parse', function (assert) {\n    var i,\n        tests = 'tháng 1,Th01_tháng 2,Th02_tháng 3,Th03_tháng 4,Th04_tháng 5,Th05_tháng 6,Th06_tháng 7,Th07_tháng 8,Th08_tháng 9,Th09_tháng 10,Th10_tháng 11,Th11_tháng 12,Th12'.split('_');\n\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + i);\n    }\n\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(',');\n        equalTest(tests[i][0], '[tháng] M', i);\n        equalTest(tests[i][1], '[Th]M', i);\n        equalTest(tests[i][0], '[tháng] MM', i);\n        equalTest(tests[i][1], '[Th]MM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), '[THÁNG] M', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), '[TH]M', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), '[THÁNG] MM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), '[TH]MM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, MMMM Do YYYY, h:mm:ss a',      'chủ nhật, tháng 2 14 2010, 3:25:50 ch'],\n            ['ddd, hA',                            'CN, 3CH'],\n            ['M Mo MM MMMM MMM',                   '2 2 02 tháng 2 Th02'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14 14'],\n            ['d do dddd ddd dd',                   '0 0 chủ nhật CN CN'],\n            ['DDD DDDo DDDD',                      '45 45 045'],\n            ['w wo ww',                            '6 6 06'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'ch CH'],\n            ['[ngày thứ] DDDo [của năm]',          'ngày thứ 45 của năm'],\n            ['LTS',                                '15:25:50'],\n            ['L',                                  '14/02/2010'],\n            ['LL',                                 '14 tháng 2 năm 2010'],\n            ['LLL',                                '14 tháng 2 năm 2010 15:25'],\n            ['LLLL',                               'chủ nhật, 14 tháng 2 năm 2010 15:25'],\n            ['l',                                  '14/2/2010'],\n            ['ll',                                 '14 Th02 2010'],\n            ['lll',                                '14 Th02 2010 15:25'],\n            ['llll',                               'CN, 14 Th02 2010 15:25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1', '1');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2', '2');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3', '3');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4', '4');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5', '5');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6', '6');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7', '7');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8', '8');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9', '9');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10', '10');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11', '11');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12', '12');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13', '13');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14', '14');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15', '15');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16', '16');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17', '17');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18', '18');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19', '19');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20', '20');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21', '21');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22', '22');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23', '23');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24', '24');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25', '25');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26', '26');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27', '27');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28', '28');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29', '29');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30', '30');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31', '31');\n});\n\ntest('format month', function (assert) {\n    var i,\n        expected = 'tháng 1,Th01_tháng 2,Th02_tháng 3,Th03_tháng 4,Th04_tháng 5,Th05_tháng 6,Th06_tháng 7,Th07_tháng 8,Th08_tháng 9,Th09_tháng 10,Th10_tháng 11,Th11_tháng 12,Th12'.split('_');\n\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM,MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var i,\n        expected = 'chủ nhật CN CN_thứ hai T2 T2_thứ ba T3 T3_thứ tư T4 T4_thứ năm T5 T5_thứ sáu T6 T6_thứ bảy T7 T7'.split('_');\n\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'vài giây', '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'một phút',      '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'một phút',      '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 phút',     '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 phút',    '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'một giờ',       '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'một giờ',       '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 giờ',       '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 giờ',       '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 giờ',      '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'một ngày',         '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'một ngày',         '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 ngày',        '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'một ngày',         '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 ngày',        '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 ngày',       '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'một tháng',       '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'một tháng',       '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'một tháng',       '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 tháng',      '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 tháng',      '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 tháng',      '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'một tháng',       '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 tháng',      '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'một năm',        '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 năm',       '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'một năm',        '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 năm',       '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'vài giây tới',  'prefix');\n    assert.equal(moment(0).from(30000), 'vài giây trước', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'vài giây trước',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'vài giây tới', 'in a few seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), '5 ngày tới', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'Hôm nay lúc 12:00',   'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'Hôm nay lúc 12:25',   'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'Hôm nay lúc 13:00',   'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'Ngày mai lúc 12:00',  'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'Hôm nay lúc 11:00',   'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'Hôm qua lúc 12:00',   'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('dddd [tuần tới lúc] LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd [tuần tới lúc] LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd [tuần tới lúc] LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('dddd [tuần rồi lúc] LT'),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd [tuần rồi lúc] LT'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd [tuần rồi lúc] LT'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2012, 0,  1]).format('w ww wo'), '52 52 52', 'Jan  1 2012 should be week 52');\n    assert.equal(moment([2012, 0,  2]).format('w ww wo'),   '1 01 1', 'Jan  2 2012 should be week 1');\n    assert.equal(moment([2012, 0,  8]).format('w ww wo'),   '1 01 1', 'Jan  8 2012 should be week 1');\n    assert.equal(moment([2012, 0,  9]).format('w ww wo'),   '2 02 2', 'Jan  9 2012 should be week 2');\n    assert.equal(moment([2012, 0, 15]).format('w ww wo'),   '2 02 2', 'Jan 15 2012 should be week 2');\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\n\n\nfunction localeModule (name, lifecycle) {\n    QUnit.module('locale:' + name, {\n        setup : function () {\n            moment.locale(name);\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            moment.locale('en');\n            teardownDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n    defineCommonLocaleTests(name, -1, -1);\n}\n\nlocaleModule('x-pseudo');\n\ntest('parse', function (assert) {\n    var tests = 'J~áñúá~rý J~áñ_F~ébrú~árý ~Féb_~Márc~h ~Már_Áp~ríl ~Ápr_~Máý ~Máý_~Júñé~ ~Júñ_Júl~ý ~Júl_Áú~gúst~ ~Áúg_Sép~témb~ér ~Sép_Ó~ctób~ér ~Óct_Ñ~óvém~bér ~Ñóv_~Décé~mbér ~Déc'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, MMMM Do YYYY, h:mm:ss a',      'S~úñdá~ý, F~ébrú~árý 14th 2010, 3:25:50 pm'],\n            ['ddd, hA',                            'S~úñ, 3PM'],\n            ['M Mo MM MMMM MMM',                   '2 2nd 02 F~ébrú~árý ~Féb'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14th 14'],\n            ['d do dddd ddd dd',                   '0 0th S~úñdá~ý S~úñ S~ú'],\n            ['DDD DDDo DDDD',                      '45 45th 045'],\n            ['w wo ww',                            '6 6th 06'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'pm PM'],\n            ['[the] DDDo [day of the year]',       'the 45th day of the year'],\n            ['LT',                                 '15:25'],\n            ['L',                                  '14/02/2010'],\n            ['LL',                                 '14 F~ébrú~árý 2010'],\n            ['LLL',                                '14 F~ébrú~árý 2010 15:25'],\n            ['LLLL',                               'S~úñdá~ý, 14 F~ébrú~árý 2010 15:25'],\n            ['l',                                  '14/2/2010'],\n            ['ll',                                 '14 ~Féb 2010'],\n            ['lll',                                '14 ~Féb 2010 15:25'],\n            ['llll',                               'S~úñ, 14 ~Féb 2010 15:25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1st', '1st');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2nd', '2nd');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3rd', '3rd');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4th', '4th');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5th', '5th');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6th', '6th');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7th', '7th');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8th', '8th');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9th', '9th');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10th', '10th');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11th', '11th');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12th', '12th');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13th', '13th');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14th', '14th');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15th', '15th');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16th', '16th');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17th', '17th');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18th', '18th');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19th', '19th');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20th', '20th');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21st', '21st');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22nd', '22nd');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23rd', '23rd');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24th', '24th');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25th', '25th');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26th', '26th');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27th', '27th');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28th', '28th');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29th', '29th');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30th', '30th');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31st', '31st');\n});\n\ntest('format month', function (assert) {\n    var expected = 'J~áñúá~rý J~áñ_F~ébrú~árý ~Féb_~Márc~h ~Már_Áp~ríl ~Ápr_~Máý ~Máý_~Júñé~ ~Júñ_Júl~ý ~Júl_Áú~gúst~ ~Áúg_Sép~témb~ér ~Sép_Ó~ctób~ér ~Óct_Ñ~óvém~bér ~Ñóv_~Décé~mbér ~Déc'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'S~úñdá~ý S~úñ S~ú_Mó~ñdáý~ ~Móñ Mó~_Túé~sdáý~ ~Túé Tú_Wéd~ñésd~áý ~Wéd ~Wé_T~húrs~dáý ~Thú T~h_~Fríd~áý ~Frí Fr~_S~átúr~dáý ~Sát Sá'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'á ~féw ~sécó~ñds', '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'á ~míñ~úté',      '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'á ~míñ~úté',      '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 m~íñú~tés',     '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 m~íñú~tés',    '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'á~ñ hó~úr',       '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'á~ñ hó~úr',       '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 h~óúrs',       '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 h~óúrs',       '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 h~óúrs',      '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'á ~dáý',         '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'á ~dáý',         '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 d~áýs',        '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'á ~dáý',         '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 d~áýs',        '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 d~áýs',       '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'á ~móñ~th',       '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'á ~móñ~th',       '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'á ~móñ~th',       '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 m~óñt~hs',      '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 m~óñt~hs',      '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 m~óñt~hs',      '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'á ~móñ~th',       '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 m~óñt~hs',      '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'á ~ýéár',        '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 ý~éárs',       '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'á ~ýéár',        '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 ý~éárs',       '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'í~ñ á ~féw ~sécó~ñds',  'prefix');\n    assert.equal(moment(0).from(30000), 'á ~féw ~sécó~ñds á~gó', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'á ~féw ~sécó~ñds á~gó',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'í~ñ á ~féw ~sécó~ñds', 'in a few seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), 'í~ñ 5 d~áýs', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(2).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                     'T~ódá~ý át 02:00',      'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'T~ódá~ý át 02:25',      'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'T~ódá~ý át 03:00',      'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'T~ómó~rró~w át 02:00',   'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'T~ódá~ý át 01:00',      'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'Ý~ést~érdá~ý át 02:00',  'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('dddd [át] LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd [át] LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd [át] LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('[L~ást] dddd [át] LT'),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[L~ást] dddd [át] LT'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[L~ást] dddd [át] LT'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2012, 0,  1]).format('w ww wo'), '52 52 52nd', 'Jan  1 2012 should be week 52');\n    assert.equal(moment([2012, 0,  2]).format('w ww wo'),   '1 01 1st', 'Jan  2 2012 should be week 1');\n    assert.equal(moment([2012, 0,  8]).format('w ww wo'),   '1 01 1st', 'Jan  8 2012 should be week 1');\n    assert.equal(moment([2012, 0,  9]).format('w ww wo'),   '2 02 2nd', 'Jan  9 2012 should be week 2');\n    assert.equal(moment([2012, 0, 15]).format('w ww wo'),   '2 02 2nd', 'Jan 15 2012 should be week 2');\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\n\n\nfunction localeModule (name, lifecycle) {\n    QUnit.module('locale:' + name, {\n        setup : function () {\n            moment.locale(name);\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            moment.locale('en');\n            teardownDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n    defineCommonLocaleTests(name, -1, -1);\n}\n\nlocaleModule('yo');\n\ntest('parse', function (assert) {\n    var tests = 'Sẹ́rẹ́ Sẹ́r_Èrèlè Èrl_Ẹrẹ̀nà Ẹrn_Ìgbé Ìgb_Èbibi Èbi_Òkùdu Òkù_Agẹmo Agẹ_Ògún Ògú_Owewe Owe_Ọ̀wàrà Ọ̀wà_Bélú Bél_Ọ̀pẹ̀̀ Ọ̀pẹ̀̀'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, MMMM Do YYYY, h:mm:ss a', 'Àìkú, Èrèlè ọjọ́ 14 2010, 3:25:50 pm'],\n            ['ddd, hA', 'Àìk, 3PM'],\n            ['M Mo MM MMMM MMM', '2 ọjọ́ 2 02 Èrèlè Èrl'],\n            ['YYYY YY', '2010 10'],\n            ['D Do DD', '14 ọjọ́ 14 14'],\n            ['d do dddd ddd dd', '0 ọjọ́ 0 Àìkú Àìk Àì'],\n            ['DDD DDDo DDDD', '45 ọjọ́ 45 045'],\n            ['w wo ww', '6 ọjọ́ 6 06'],\n            ['h hh', '3 03'],\n            ['H HH', '15 15'],\n            ['m mm', '25 25'],\n            ['s ss', '50 50'],\n            ['a A', 'pm PM'],\n            ['[the] DDDo [day of the year]', 'the ọjọ́ 45 day of the year'],\n            ['LTS', '3:25:50 PM'],\n            ['L', '14/02/2010'],\n            ['LL', '14 Èrèlè 2010'],\n            ['LLL', '14 Èrèlè 2010 3:25 PM'],\n            ['LLLL', 'Àìkú, 14 Èrèlè 2010 3:25 PM'],\n            ['l', '14/2/2010'],\n            ['ll', '14 Èrl 2010'],\n            ['lll', '14 Èrl 2010 3:25 PM'],\n            ['llll', 'Àìk, 14 Èrl 2010 3:25 PM']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), 'ọjọ́ 1', 'ọjọ́ 1');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), 'ọjọ́ 2', 'ọjọ́ 2');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), 'ọjọ́ 3', 'ọjọ́ 3');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), 'ọjọ́ 4', 'ọjọ́ 4');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), 'ọjọ́ 5', 'ọjọ́ 5');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), 'ọjọ́ 6', 'ọjọ́ 6');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), 'ọjọ́ 7', 'ọjọ́ 7');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), 'ọjọ́ 8', 'ọjọ́ 8');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), 'ọjọ́ 9', 'ọjọ́ 9');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), 'ọjọ́ 10', 'ọjọ́ 10');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), 'ọjọ́ 11', 'ọjọ́ 11');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), 'ọjọ́ 12', 'ọjọ́ 12');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), 'ọjọ́ 13', 'ọjọ́ 13');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), 'ọjọ́ 14', 'ọjọ́ 14');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), 'ọjọ́ 15', 'ọjọ́ 15');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), 'ọjọ́ 16', 'ọjọ́ 16');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), 'ọjọ́ 17', 'ọjọ́ 17');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), 'ọjọ́ 18', 'ọjọ́ 18');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), 'ọjọ́ 19', 'ọjọ́ 19');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), 'ọjọ́ 20', 'ọjọ́ 20');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), 'ọjọ́ 21', 'ọjọ́ 21');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), 'ọjọ́ 22', 'ọjọ́ 22');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), 'ọjọ́ 23', 'ọjọ́ 23');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), 'ọjọ́ 24', 'ọjọ́ 24');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), 'ọjọ́ 25', 'ọjọ́ 25');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), 'ọjọ́ 26', 'ọjọ́ 26');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), 'ọjọ́ 27', 'ọjọ́ 27');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), 'ọjọ́ 28', 'ọjọ́ 28');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), 'ọjọ́ 29', 'ọjọ́ 29');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), 'ọjọ́ 30', 'ọjọ́ 30');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), 'ọjọ́ 31', 'ọjọ́ 31');\n});\n\ntest('format month', function (assert) {\n    var expected = 'Sẹ́rẹ́ Sẹ́r_Èrèlè Èrl_Ẹrẹ̀nà Ẹrn_Ìgbé Ìgb_Èbibi Èbi_Òkùdu Òkù_Agẹmo Agẹ_Ògún Ògú_Owewe Owe_Ọ̀wàrà Ọ̀wà_Bélú Bél_Ọ̀pẹ̀̀ Ọ̀pẹ̀̀'.split('_'),\n        i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'Àìkú Àìk Àì_Ajé Ajé Aj_Ìsẹ́gun Ìsẹ́ Ìs_Ọjọ́rú Ọjr Ọr_Ọjọ́bọ Ọjb Ọb_Ẹtì Ẹtì Ẹt_Àbámẹ́ta Àbá Àb'.split('_'),\n        i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'ìsẹjú aayá die', '44 seconds = ìsẹjú aayá die');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'ìsẹjú kan',      '45 seconds = ìsẹjú kan');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'ìsẹjú kan',      '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  'ìsẹjú 2',        '90 seconds = ìsẹjú 2');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  'ìsẹjú 44',       'ìsẹjú 44 = ìsẹjú 44');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'wákati kan',     'ìsẹjú 45 = wákati kan');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'wákati kan',     'ìsẹjú 89 = wákati kan');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  'wákati 2',       'ìsẹjú 90 = wákati 2');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   'wákati 5',       'wákati 5 = wákati 5');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  'wákati 21',      'wákati 21 = wákati 21');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'ọjọ́ kan',        '22 wákati = ọjọ́ kan');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'ọjọ́ kan',        '35 wákati = ọjọ́ kan');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  'ọjọ́ 2',          'wákati 36 = ọjọ́ 2');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'ọjọ́ kan',        '1  = ọjọ́ kan');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   'ọjọ́ 5',          'ọjọ́ 5 = ọjọ́  5');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  'ọjọ́ 25',         'ọjọ́ 25 = ọjọ́ 25');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'osù kan',        'ọjọ́ 26 = osù kan');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'osù kan',        'ọjọ́ 30 = osù kan');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'osù kan',        'ọjọ́ 43 = osù kan');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  'osù 2',          'ọjọ́ 46 = osù 2');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  'osù 2',          'ọjọ́ 75 = osù 2');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  'osù 3',          'ọjọ́ 76 = osù 3');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'osù kan',        'osù 1 = osù kan');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   'osù 5',          'osù 5 = osù 5');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'ọdún kan',       'ọjọ 345 = ọdún kan');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), 'ọdún 2',         'ọjọ 548 = ọdún 2');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'ọdún kan',       'ọdún 1 = ọdún kan');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   'ọdún 5',         'ọdún 5 = ọdún 5');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'ní ìsẹjú aayá die', 'prefix');\n    assert.equal(moment(0).from(30000), 'ìsẹjú aayá die kọjá', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'ìsẹjú aayá die kọjá', 'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'ní ìsẹjú aayá die', 'ní ìsẹjú aayá die');\n    assert.equal(moment().add({d: 5}).fromNow(), 'ní ọjọ́ 5', 'ní ọjọ́ 5');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                     'Ònì ni 12:00 PM',   'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'Ònì ni 12:25 PM',   'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'Ònì ni 1:00 PM',    'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'Ọ̀la ni 12:00 PM',   'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'Ònì ni 11:00 AM',   'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'Àna ni 12:00 PM',   'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(), m.format('dddd [Ọsẹ̀ tón\\'bọ] [ni] LT'), 'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(), m.format('dddd [Ọsẹ̀ tón\\'bọ] [ni] LT'), 'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(), m.format('dddd [Ọsẹ̀ tón\\'bọ] [ni] LT'), 'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(), m.format('dddd [Ọsẹ̀ tólọ́] [ni] LT'), 'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(), m.format('dddd [Ọsẹ̀ tólọ́] [ni] LT'), 'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(), m.format('dddd [Ọsẹ̀ tólọ́] [ni] LT'), 'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '1 week ago');\n    assert.equal(weeksFromNow.calendar(), weeksFromNow.format('L'), 'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(), weeksFromNow.format('L'), 'in 2 weeks');\n});\n\ntest('weeks year starting sunday format', function (assert) {\n    assert.equal(moment([2012, 0,  1]).format('w ww wo'), '52 52 ọjọ́ 52', 'Jan  1 2012 should be week 52');\n    assert.equal(moment([2012, 0,  2]).format('w ww wo'),   '1 01 ọjọ́ 1', 'Jan  2 2012 should be week 1');\n    assert.equal(moment([2012, 0,  8]).format('w ww wo'),   '1 01 ọjọ́ 1', 'Jan  8 2012 should be week 1');\n    assert.equal(moment([2012, 0,  9]).format('w ww wo'),   '2 02 ọjọ́ 2', 'Jan  9 2012 should be week 2');\n    assert.equal(moment([2012, 0, 15]).format('w ww wo'),   '2 02 ọjọ́ 2', 'Jan 15 2012 should be week 2');\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\n\n\nfunction localeModule (name, lifecycle) {\n    QUnit.module('locale:' + name, {\n        setup : function () {\n            moment.locale(name);\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            moment.locale('en');\n            teardownDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n    defineCommonLocaleTests(name, -1, -1);\n}\n\nlocaleModule('zh-cn');\n\ntest('parse', function (assert) {\n    var tests = '一月 1月_二月 2月_三月 3月_四月 4月_五月 5月_六月 6月_七月 7月_八月 8月_九月 9月_十月 10月_十一月 11月_十二月 12月'.split('_'), i;\n\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, MMMM Do YYYY, a h:mm:ss',      '星期日, 二月 14日 2010, 下午 3:25:50'],\n            ['ddd, Ah',                            '周日, 下午3'],\n            ['M Mo MM MMMM MMM',                   '2 2月 02 二月 2月'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14日 14'],\n            ['d do dddd ddd dd',                   '0 0日 星期日 周日 日'],\n            ['DDD DDDo DDDD',                      '45 45日 045'],\n            ['w wo ww',                            '6 6周 06'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                '下午 下午'],\n            ['[这年的第] DDDo',                    '这年的第 45日'],\n            ['LTS',                                '15:25:50'],\n            ['L',                                  '2010年2月14日'],\n            ['LL',                                 '2010年2月14日'],\n            ['LLL',                                '2010年2月14日下午3点25分'],\n            ['LLLL',                               '2010年2月14日星期日下午3点25分'],\n            ['l',                                  '2010年2月14日'],\n            ['ll',                                 '2010年2月14日'],\n            ['lll',                                '2010年2月14日 15:25'],\n            ['llll',                               '2010年2月14日星期日 15:25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format month', function (assert) {\n    var expected = '一月 1月_二月 2月_三月 3月_四月 4月_五月 5月_六月 6月_七月 7月_八月 8月_九月 9月_十月 10月_十一月 11月_十二月 12月'.split('_'), i;\n\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = '星期日 周日 日_星期一 周一 一_星期二 周二 二_星期三 周三 三_星期四 周四 四_星期五 周五 五_星期六 周六 六'.split('_'), i;\n\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  '几秒',   '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  '1 分钟', '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  '1 分钟', '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 分钟',  '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 分钟', '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  '1 小时', '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  '1 小时', '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 小时',  '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 小时',  '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 小时', '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  '1 天',   '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  '1 天',   '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 天',   '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   '1 天',   '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 天',   '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 天',  '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  '1 个月', '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  '1 个月', '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  '1 个月', '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 个月',  '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 个月',  '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 个月',  '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   '1 个月', '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 个月',  '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), '1 年',   '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 年',   '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   '1 年',   '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 年',   '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), '几秒内',  'prefix');\n    assert.equal(moment(0).from(30000), '几秒前', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), '几秒前',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), '几秒内', 'in a few seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), '5 天内', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   '今天12:00', 'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      '今天12:25', 'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       '今天13:00', 'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       '明天12:00', 'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  '今天11:00', 'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  '昨天12:00', 'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('[下]ddddLT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[下]ddddLT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[下]ddddLT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('[上]ddddLT'),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[上]ddddLT'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[上]ddddLT'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),      '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),      '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('meridiem', function (assert) {\n    assert.equal(moment([2011, 2, 23,  0, 0]).format('A'), '凌晨', 'before dawn');\n    assert.equal(moment([2011, 2, 23,  6, 0]).format('A'), '早上', 'morning');\n    assert.equal(moment([2011, 2, 23,  9, 0]).format('A'), '上午', 'before noon');\n    assert.equal(moment([2011, 2, 23, 12, 0]).format('A'), '中午', 'noon');\n    assert.equal(moment([2011, 2, 23, 13, 0]).format('A'), '下午', 'afternoon');\n    assert.equal(moment([2011, 2, 23, 18, 0]).format('A'), '晚上', 'night');\n});\n\ntest('weeks year starting sunday format', function (assert) {\n    assert.equal(moment([2012, 0,  1]).format('w ww wo'), '52 52 52周', 'Jan  1 2012 应该是第52周');\n    assert.equal(moment([2012, 0,  7]).format('w ww wo'), '1 01 1周', 'Jan  7 2012 应该是第 1周');\n    assert.equal(moment([2012, 0, 14]).format('w ww wo'), '2 02 2周', 'Jan 14 2012 应该是第 2周');\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\n\n\nfunction localeModule (name, lifecycle) {\n    QUnit.module('locale:' + name, {\n        setup : function () {\n            moment.locale(name);\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            moment.locale('en');\n            teardownDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n    defineCommonLocaleTests(name, -1, -1);\n}\n\nlocaleModule('zh-hk');\n\ntest('parse', function (assert) {\n    var tests = '一月 1月_二月 2月_三月 3月_四月 4月_五月 5月_六月 6月_七月 7月_八月 8月_九月 9月_十月 10月_十一月 11月_十二月 12月'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, MMMM Do YYYY, a h:mm:ss',      '星期日, 二月 14日 2010, 下午 3:25:50'],\n            ['ddd, Ah',                            '週日, 下午3'],\n            ['M Mo MM MMMM MMM',                   '2 2月 02 二月 2月'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14日 14'],\n            ['d do dddd ddd dd',                   '0 0日 星期日 週日 日'],\n            ['DDD DDDo DDDD',                      '45 45日 045'],\n            ['w wo ww',                            '8 8週 08'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                '下午 下午'],\n            ['[這年的第] DDDo',                    '這年的第 45日'],\n            ['LTS',                                '15:25:50'],\n            ['L',                                  '2010年2月14日'],\n            ['LL',                                 '2010年2月14日'],\n            ['LLL',                                '2010年2月14日 15:25'],\n            ['LLLL',                               '2010年2月14日星期日 15:25'],\n            ['l',                                  '2010年2月14日'],\n            ['ll',                                 '2010年2月14日'],\n            ['lll',                                '2010年2月14日 15:25'],\n            ['llll',                               '2010年2月14日星期日 15:25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format month', function (assert) {\n    var expected = '一月 1月_二月 2月_三月 3月_四月 4月_五月 5月_六月 6月_七月 7月_八月 8月_九月 9月_十月 10月_十一月 11月_十二月 12月'.split('_'), i;\n\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = '星期日 週日 日_星期一 週一 一_星期二 週二 二_星期三 週三 三_星期四 週四 四_星期五 週五 五_星期六 週六 六'.split('_'), i;\n\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  '幾秒',   '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  '1 分鐘', '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  '1 分鐘', '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 分鐘',  '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 分鐘', '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  '1 小時', '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  '1 小時', '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 小時',  '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 小時',  '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 小時', '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  '1 天',   '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  '1 天',   '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 天',   '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   '1 天',   '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 天',   '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 天',  '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  '1 個月', '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  '1 個月', '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  '1 個月', '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 個月',  '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 個月',  '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 個月',  '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   '1 個月', '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 個月',  '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), '1 年',   '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 年',   '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   '1 年',   '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 年',   '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), '幾秒內',  'prefix');\n    assert.equal(moment(0).from(30000), '幾秒前', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), '幾秒前',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), '幾秒內', 'in a few seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), '5 天內', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   '今天12:00', 'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      '今天12:25', 'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       '今天13:00', 'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       '明天12:00', 'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  '今天11:00', 'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  '昨天12:00', 'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('[下]ddddLT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[下]ddddLT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[下]ddddLT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('[上]ddddLT'),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[上]ddddLT'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[上]ddddLT'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),      '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),      '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('meridiem', function (assert) {\n    assert.equal(moment([2011, 2, 23,  0, 0]).format('a'), '凌晨', 'before dawn');\n    assert.equal(moment([2011, 2, 23,  6, 0]).format('a'), '早上', 'morning');\n    assert.equal(moment([2011, 2, 23,  9, 0]).format('a'), '上午', 'before noon');\n    assert.equal(moment([2011, 2, 23, 12, 0]).format('a'), '中午', 'noon');\n    assert.equal(moment([2011, 2, 23, 13, 0]).format('a'), '下午', 'after noon');\n    assert.equal(moment([2011, 2, 23, 18, 0]).format('a'), '晚上', 'night');\n\n    assert.equal(moment([2011, 2, 23,  0, 0]).format('A'), '凌晨', 'before dawn');\n    assert.equal(moment([2011, 2, 23,  6, 0]).format('A'), '早上', 'morning');\n    assert.equal(moment([2011, 2, 23,  9, 0]).format('A'), '上午', 'before noon');\n    assert.equal(moment([2011, 2, 23, 12, 0]).format('A'), '中午', 'noon');\n    assert.equal(moment([2011, 2, 23, 13, 0]).format('A'), '下午', 'afternoon');\n    assert.equal(moment([2011, 2, 23, 18, 0]).format('A'), '晚上', 'night');\n});\n\ntest('weeks year starting sunday format', function (assert) {\n    assert.equal(moment([2012, 0,  1]).format('w ww wo'), '1 01 1週', 'Jan  1 2012 應該是第 1週');\n    assert.equal(moment([2012, 0,  7]).format('w ww wo'), '1 01 1週', 'Jan  7 2012 應該是第 1週');\n    assert.equal(moment([2012, 0,  8]).format('w ww wo'), '2 02 2週', 'Jan  8 2012 應該是第 2週');\n    assert.equal(moment([2012, 0, 14]).format('w ww wo'), '2 02 2週', 'Jan 14 2012 應該是第 2週');\n    assert.equal(moment([2012, 0, 15]).format('w ww wo'), '3 03 3週', 'Jan 15 2012 應該是第 3週');\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\n\n\nfunction localeModule (name, lifecycle) {\n    QUnit.module('locale:' + name, {\n        setup : function () {\n            moment.locale(name);\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            moment.locale('en');\n            teardownDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n    defineCommonLocaleTests(name, -1, -1);\n}\n\nlocaleModule('zh-tw');\n\ntest('parse', function (assert) {\n    var tests = '一月 1月_二月 2月_三月 3月_四月 4月_五月 5月_六月 6月_七月 7月_八月 8月_九月 9月_十月 10月_十一月 11月_十二月 12月'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, MMMM Do YYYY, a h:mm:ss',      '星期日, 二月 14日 2010, 下午 3:25:50'],\n            ['ddd, Ah',                            '週日, 下午3'],\n            ['M Mo MM MMMM MMM',                   '2 2月 02 二月 2月'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14日 14'],\n            ['d do dddd ddd dd',                   '0 0日 星期日 週日 日'],\n            ['DDD DDDo DDDD',                      '45 45日 045'],\n            ['w wo ww',                            '8 8週 08'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                '下午 下午'],\n            ['[這年的第] DDDo',                    '這年的第 45日'],\n            ['LTS',                                '15:25:50'],\n            ['L',                                  '2010年2月14日'],\n            ['LL',                                 '2010年2月14日'],\n            ['LLL',                                '2010年2月14日 15:25'],\n            ['LLLL',                               '2010年2月14日星期日 15:25'],\n            ['l',                                  '2010年2月14日'],\n            ['ll',                                 '2010年2月14日'],\n            ['lll',                                '2010年2月14日 15:25'],\n            ['llll',                               '2010年2月14日星期日 15:25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format month', function (assert) {\n    var expected = '一月 1月_二月 2月_三月 3月_四月 4月_五月 5月_六月 6月_七月 7月_八月 8月_九月 9月_十月 10月_十一月 11月_十二月 12月'.split('_'), i;\n\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = '星期日 週日 日_星期一 週一 一_星期二 週二 二_星期三 週三 三_星期四 週四 四_星期五 週五 五_星期六 週六 六'.split('_'), i;\n\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  '幾秒',   '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  '1 分鐘', '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  '1 分鐘', '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 分鐘',  '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 分鐘', '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  '1 小時', '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  '1 小時', '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 小時',  '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 小時',  '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 小時', '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  '1 天',   '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  '1 天',   '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 天',   '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   '1 天',   '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 天',   '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 天',  '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  '1 個月', '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  '1 個月', '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  '1 個月', '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 個月',  '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 個月',  '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 個月',  '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   '1 個月', '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 個月',  '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), '1 年',   '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 年',   '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   '1 年',   '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 年',   '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), '幾秒內',  'prefix');\n    assert.equal(moment(0).from(30000), '幾秒前', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), '幾秒前',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), '幾秒內', 'in a few seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), '5 天內', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   '今天12:00', 'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      '今天12:25', 'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       '今天13:00', 'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       '明天12:00', 'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  '今天11:00', 'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  '昨天12:00', 'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('[下]ddddLT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[下]ddddLT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[下]ddddLT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('[上]ddddLT'),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[上]ddddLT'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[上]ddddLT'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),      '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),      '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('meridiem', function (assert) {\n    assert.equal(moment([2011, 2, 23,  0, 0]).format('a'), '凌晨', 'before dawn');\n    assert.equal(moment([2011, 2, 23,  6, 0]).format('a'), '早上', 'morning');\n    assert.equal(moment([2011, 2, 23,  9, 0]).format('a'), '上午', 'before noon');\n    assert.equal(moment([2011, 2, 23, 12, 0]).format('a'), '中午', 'noon');\n    assert.equal(moment([2011, 2, 23, 13, 0]).format('a'), '下午', 'after noon');\n    assert.equal(moment([2011, 2, 23, 18, 0]).format('a'), '晚上', 'night');\n\n    assert.equal(moment([2011, 2, 23,  0, 0]).format('A'), '凌晨', 'before dawn');\n    assert.equal(moment([2011, 2, 23,  6, 0]).format('A'), '早上', 'morning');\n    assert.equal(moment([2011, 2, 23,  9, 0]).format('A'), '上午', 'before noon');\n    assert.equal(moment([2011, 2, 23, 12, 0]).format('A'), '中午', 'noon');\n    assert.equal(moment([2011, 2, 23, 13, 0]).format('A'), '下午', 'afternoon');\n    assert.equal(moment([2011, 2, 23, 18, 0]).format('A'), '晚上', 'night');\n});\n\ntest('weeks year starting sunday format', function (assert) {\n    assert.equal(moment([2012, 0,  1]).format('w ww wo'), '1 01 1週', 'Jan  1 2012 應該是第 1週');\n    assert.equal(moment([2012, 0,  7]).format('w ww wo'), '1 01 1週', 'Jan  7 2012 應該是第 1週');\n    assert.equal(moment([2012, 0,  8]).format('w ww wo'), '2 02 2週', 'Jan  8 2012 應該是第 2週');\n    assert.equal(moment([2012, 0, 14]).format('w ww wo'), '2 02 2週', 'Jan 14 2012 應該是第 2週');\n    assert.equal(moment([2012, 0, 15]).format('w ww wo'), '3 03 3週', 'Jan 15 2012 應該是第 3週');\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\nfunction module$1 (name, lifecycle) {\n    QUnit.module(name, {\n        setup : function () {\n            moment.locale('en');\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'core');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            teardownDeprecationHandler(test, moment, 'core');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n}\n\nmodule$1('add and subtract');\n\ntest('add short reverse args', function (assert) {\n    var a = moment(), b, c, d;\n    a.year(2011);\n    a.month(9);\n    a.date(12);\n    a.hours(6);\n    a.minutes(7);\n    a.seconds(8);\n    a.milliseconds(500);\n\n    assert.equal(a.add({ms: 50}).milliseconds(), 550, 'Add milliseconds');\n    assert.equal(a.add({s: 1}).seconds(), 9, 'Add seconds');\n    assert.equal(a.add({m: 1}).minutes(), 8, 'Add minutes');\n    assert.equal(a.add({h: 1}).hours(), 7, 'Add hours');\n    assert.equal(a.add({d: 1}).date(), 13, 'Add date');\n    assert.equal(a.add({w: 1}).date(), 20, 'Add week');\n    assert.equal(a.add({M: 1}).month(), 10, 'Add month');\n    assert.equal(a.add({y: 1}).year(), 2012, 'Add year');\n    assert.equal(a.add({Q: 1}).month(), 1, 'Add quarter');\n\n    b = moment([2010, 0, 31]).add({M: 1});\n    c = moment([2010, 1, 28]).subtract({M: 1});\n    d = moment([2010, 1, 28]).subtract({Q: 1});\n\n    assert.equal(b.month(), 1, 'add month, jan 31st to feb 28th');\n    assert.equal(b.date(), 28, 'add month, jan 31st to feb 28th');\n    assert.equal(c.month(), 0, 'subtract month, feb 28th to jan 28th');\n    assert.equal(c.date(), 28, 'subtract month, feb 28th to jan 28th');\n    assert.equal(d.month(), 10, 'subtract quarter, feb 28th 2010 to nov 28th 2009');\n    assert.equal(d.date(), 28, 'subtract quarter, feb 28th 2010 to nov 28th 2009');\n    assert.equal(d.year(), 2009, 'subtract quarter, feb 28th 2010 to nov 28th 2009');\n});\n\ntest('add long reverse args', function (assert) {\n    var a = moment();\n    a.year(2011);\n    a.month(9);\n    a.date(12);\n    a.hours(6);\n    a.minutes(7);\n    a.seconds(8);\n    a.milliseconds(500);\n\n    assert.equal(a.add({milliseconds: 50}).milliseconds(), 550, 'Add milliseconds');\n    assert.equal(a.add({seconds: 1}).seconds(), 9, 'Add seconds');\n    assert.equal(a.add({minutes: 1}).minutes(), 8, 'Add minutes');\n    assert.equal(a.add({hours: 1}).hours(), 7, 'Add hours');\n    assert.equal(a.add({days: 1}).date(), 13, 'Add date');\n    assert.equal(a.add({weeks: 1}).date(), 20, 'Add week');\n    assert.equal(a.add({months: 1}).month(), 10, 'Add month');\n    assert.equal(a.add({years: 1}).year(), 2012, 'Add year');\n    assert.equal(a.add({quarters: 1}).month(), 1, 'Add quarter');\n});\n\ntest('add long singular reverse args', function (assert) {\n    var a = moment();\n    a.year(2011);\n    a.month(9);\n    a.date(12);\n    a.hours(6);\n    a.minutes(7);\n    a.seconds(8);\n    a.milliseconds(500);\n\n    assert.equal(a.add({millisecond: 50}).milliseconds(), 550, 'Add milliseconds');\n    assert.equal(a.add({second: 1}).seconds(), 9, 'Add seconds');\n    assert.equal(a.add({minute: 1}).minutes(), 8, 'Add minutes');\n    assert.equal(a.add({hour: 1}).hours(), 7, 'Add hours');\n    assert.equal(a.add({day: 1}).date(), 13, 'Add date');\n    assert.equal(a.add({week: 1}).date(), 20, 'Add week');\n    assert.equal(a.add({month: 1}).month(), 10, 'Add month');\n    assert.equal(a.add({year: 1}).year(), 2012, 'Add year');\n    assert.equal(a.add({quarter: 1}).month(), 1, 'Add quarter');\n});\n\ntest('add string long reverse args', function (assert) {\n    var a = moment(), b;\n\n    test.expectedDeprecations('moment().add(period, number)');\n\n    a.year(2011);\n    a.month(9);\n    a.date(12);\n    a.hours(6);\n    a.minutes(7);\n    a.seconds(8);\n    a.milliseconds(500);\n\n    b = a.clone();\n\n    assert.equal(a.add('millisecond', 50).milliseconds(), 550, 'Add milliseconds');\n    assert.equal(a.add('second', 1).seconds(), 9, 'Add seconds');\n    assert.equal(a.add('minute', 1).minutes(), 8, 'Add minutes');\n    assert.equal(a.add('hour', 1).hours(), 7, 'Add hours');\n    assert.equal(a.add('day', 1).date(), 13, 'Add date');\n    assert.equal(a.add('week', 1).date(), 20, 'Add week');\n    assert.equal(a.add('month', 1).month(), 10, 'Add month');\n    assert.equal(a.add('year', 1).year(), 2012, 'Add year');\n    assert.equal(b.add('day', '01').date(), 13, 'Add date');\n    assert.equal(a.add('quarter', 1).month(), 1, 'Add quarter');\n});\n\ntest('add string long singular reverse args', function (assert) {\n    var a = moment(), b;\n\n    test.expectedDeprecations('moment().add(period, number)');\n\n    a.year(2011);\n    a.month(9);\n    a.date(12);\n    a.hours(6);\n    a.minutes(7);\n    a.seconds(8);\n    a.milliseconds(500);\n\n    b = a.clone();\n\n    assert.equal(a.add('milliseconds', 50).milliseconds(), 550, 'Add milliseconds');\n    assert.equal(a.add('seconds', 1).seconds(), 9, 'Add seconds');\n    assert.equal(a.add('minutes', 1).minutes(), 8, 'Add minutes');\n    assert.equal(a.add('hours', 1).hours(), 7, 'Add hours');\n    assert.equal(a.add('days', 1).date(), 13, 'Add date');\n    assert.equal(a.add('weeks', 1).date(), 20, 'Add week');\n    assert.equal(a.add('months', 1).month(), 10, 'Add month');\n    assert.equal(a.add('years', 1).year(), 2012, 'Add year');\n    assert.equal(b.add('days', '01').date(), 13, 'Add date');\n    assert.equal(a.add('quarters', 1).month(), 1, 'Add quarter');\n});\n\ntest('add string short reverse args', function (assert) {\n    var a = moment();\n    test.expectedDeprecations('moment().add(period, number)');\n\n    a.year(2011);\n    a.month(9);\n    a.date(12);\n    a.hours(6);\n    a.minutes(7);\n    a.seconds(8);\n    a.milliseconds(500);\n\n    assert.equal(a.add('ms', 50).milliseconds(), 550, 'Add milliseconds');\n    assert.equal(a.add('s', 1).seconds(), 9, 'Add seconds');\n    assert.equal(a.add('m', 1).minutes(), 8, 'Add minutes');\n    assert.equal(a.add('h', 1).hours(), 7, 'Add hours');\n    assert.equal(a.add('d', 1).date(), 13, 'Add date');\n    assert.equal(a.add('w', 1).date(), 20, 'Add week');\n    assert.equal(a.add('M', 1).month(), 10, 'Add month');\n    assert.equal(a.add('y', 1).year(), 2012, 'Add year');\n    assert.equal(a.add('Q', 1).month(), 1, 'Add quarter');\n});\n\ntest('add string long', function (assert) {\n    var a = moment();\n    a.year(2011);\n    a.month(9);\n    a.date(12);\n    a.hours(6);\n    a.minutes(7);\n    a.seconds(8);\n    a.milliseconds(500);\n\n    assert.equal(a.add(50, 'millisecond').milliseconds(), 550, 'Add milliseconds');\n    assert.equal(a.add(1, 'second').seconds(), 9, 'Add seconds');\n    assert.equal(a.add(1, 'minute').minutes(), 8, 'Add minutes');\n    assert.equal(a.add(1, 'hour').hours(), 7, 'Add hours');\n    assert.equal(a.add(1, 'day').date(), 13, 'Add date');\n    assert.equal(a.add(1, 'week').date(), 20, 'Add week');\n    assert.equal(a.add(1, 'month').month(), 10, 'Add month');\n    assert.equal(a.add(1, 'year').year(), 2012, 'Add year');\n    assert.equal(a.add(1, 'quarter').month(), 1, 'Add quarter');\n});\n\ntest('add string long singular', function (assert) {\n    var a = moment();\n    a.year(2011);\n    a.month(9);\n    a.date(12);\n    a.hours(6);\n    a.minutes(7);\n    a.seconds(8);\n    a.milliseconds(500);\n\n    assert.equal(a.add(50, 'milliseconds').milliseconds(), 550, 'Add milliseconds');\n    assert.equal(a.add(1, 'seconds').seconds(), 9, 'Add seconds');\n    assert.equal(a.add(1, 'minutes').minutes(), 8, 'Add minutes');\n    assert.equal(a.add(1, 'hours').hours(), 7, 'Add hours');\n    assert.equal(a.add(1, 'days').date(), 13, 'Add date');\n    assert.equal(a.add(1, 'weeks').date(), 20, 'Add week');\n    assert.equal(a.add(1, 'months').month(), 10, 'Add month');\n    assert.equal(a.add(1, 'years').year(), 2012, 'Add year');\n    assert.equal(a.add(1, 'quarters').month(), 1, 'Add quarter');\n});\n\ntest('add string short', function (assert) {\n    var a = moment();\n    a.year(2011);\n    a.month(9);\n    a.date(12);\n    a.hours(6);\n    a.minutes(7);\n    a.seconds(8);\n    a.milliseconds(500);\n\n    assert.equal(a.add(50, 'ms').milliseconds(), 550, 'Add milliseconds');\n    assert.equal(a.add(1, 's').seconds(), 9, 'Add seconds');\n    assert.equal(a.add(1, 'm').minutes(), 8, 'Add minutes');\n    assert.equal(a.add(1, 'h').hours(), 7, 'Add hours');\n    assert.equal(a.add(1, 'd').date(), 13, 'Add date');\n    assert.equal(a.add(1, 'w').date(), 20, 'Add week');\n    assert.equal(a.add(1, 'M').month(), 10, 'Add month');\n    assert.equal(a.add(1, 'y').year(), 2012, 'Add year');\n    assert.equal(a.add(1, 'Q').month(), 1, 'Add quarter');\n});\n\ntest('add strings string short reversed', function (assert) {\n    var a = moment();\n    test.expectedDeprecations('moment().add(period, number)');\n\n    a.year(2011);\n    a.month(9);\n    a.date(12);\n    a.hours(6);\n    a.minutes(7);\n    a.seconds(8);\n    a.milliseconds(500);\n\n    assert.equal(a.add('ms', '50').milliseconds(), 550, 'Add milliseconds');\n    assert.equal(a.add('s', '1').seconds(), 9, 'Add seconds');\n    assert.equal(a.add('m', '1').minutes(), 8, 'Add minutes');\n    assert.equal(a.add('h', '1').hours(), 7, 'Add hours');\n    assert.equal(a.add('d', '1').date(), 13, 'Add date');\n    assert.equal(a.add('w', '1').date(), 20, 'Add week');\n    assert.equal(a.add('M', '1').month(), 10, 'Add month');\n    assert.equal(a.add('y', '1').year(), 2012, 'Add year');\n    assert.equal(a.add('Q', '1').month(), 1, 'Add quarter');\n});\n\ntest('subtract strings string short reversed', function (assert) {\n    var a = moment();\n    test.expectedDeprecations('moment().subtract(period, number)');\n\n    a.year(2011);\n    a.month(9);\n    a.date(12);\n    a.hours(6);\n    a.minutes(7);\n    a.seconds(8);\n    a.milliseconds(500);\n\n    assert.equal(a.subtract('ms', '50').milliseconds(), 450, 'Subtract milliseconds');\n    assert.equal(a.subtract('s', '1').seconds(), 7, 'Subtract seconds');\n    assert.equal(a.subtract('m', '1').minutes(), 6, 'Subtract minutes');\n    assert.equal(a.subtract('h', '1').hours(), 5, 'Subtract hours');\n    assert.equal(a.subtract('d', '1').date(), 11, 'Subtract date');\n    assert.equal(a.subtract('w', '1').date(), 4, 'Subtract week');\n    assert.equal(a.subtract('M', '1').month(), 8, 'Subtract month');\n    assert.equal(a.subtract('y', '1').year(), 2010, 'Subtract year');\n    assert.equal(a.subtract('Q', '1').month(), 5, 'Subtract quarter');\n});\n\ntest('add strings string short', function (assert) {\n    var a = moment();\n    a.year(2011);\n    a.month(9);\n    a.date(12);\n    a.hours(6);\n    a.minutes(7);\n    a.seconds(8);\n    a.milliseconds(500);\n\n    assert.equal(a.add('50', 'ms').milliseconds(), 550, 'Add milliseconds');\n    assert.equal(a.add('1', 's').seconds(), 9, 'Add seconds');\n    assert.equal(a.add('1', 'm').minutes(), 8, 'Add minutes');\n    assert.equal(a.add('1', 'h').hours(), 7, 'Add hours');\n    assert.equal(a.add('1', 'd').date(), 13, 'Add date');\n    assert.equal(a.add('1', 'w').date(), 20, 'Add week');\n    assert.equal(a.add('1', 'M').month(), 10, 'Add month');\n    assert.equal(a.add('1', 'y').year(), 2012, 'Add year');\n    assert.equal(a.add('1', 'Q').month(), 1, 'Add quarter');\n});\n\ntest('add no string with milliseconds default', function (assert) {\n    var a = moment();\n    a.year(2011);\n    a.month(9);\n    a.date(12);\n    a.hours(6);\n    a.minutes(7);\n    a.seconds(8);\n    a.milliseconds(500);\n\n    assert.equal(a.add(50).milliseconds(), 550, 'Add milliseconds');\n});\n\ntest('subtract strings string short', function (assert) {\n    var a = moment();\n    a.year(2011);\n    a.month(9);\n    a.date(12);\n    a.hours(6);\n    a.minutes(7);\n    a.seconds(8);\n    a.milliseconds(500);\n\n    assert.equal(a.subtract('50', 'ms').milliseconds(), 450, 'Subtract milliseconds');\n    assert.equal(a.subtract('1', 's').seconds(), 7, 'Subtract seconds');\n    assert.equal(a.subtract('1', 'm').minutes(), 6, 'Subtract minutes');\n    assert.equal(a.subtract('1', 'h').hours(), 5, 'Subtract hours');\n    assert.equal(a.subtract('1', 'd').date(), 11, 'Subtract date');\n    assert.equal(a.subtract('1', 'w').date(), 4, 'Subtract week');\n    assert.equal(a.subtract('1', 'M').month(), 8, 'Subtract month');\n    assert.equal(a.subtract('1', 'y').year(), 2010, 'Subtract year');\n    assert.equal(a.subtract('1', 'Q').month(), 5, 'Subtract quarter');\n});\n\ntest('add across DST', function (assert) {\n    // Detect Safari bug and bail. Hours on 13th March 2011 are shifted\n    // with 1 ahead.\n    if (new Date(2011, 2, 13, 5, 0, 0).getHours() !== 5) {\n        expect(0);\n        return;\n    }\n\n    var a = moment(new Date(2011, 2, 12, 5, 0, 0)),\n        b = moment(new Date(2011, 2, 12, 5, 0, 0)),\n        c = moment(new Date(2011, 2, 12, 5, 0, 0)),\n        d = moment(new Date(2011, 2, 12, 5, 0, 0)),\n        e = moment(new Date(2011, 2, 12, 5, 0, 0));\n    a.add(1, 'days');\n    b.add(24, 'hours');\n    c.add(1, 'months');\n    e.add(1, 'quarter');\n\n    assert.equal(a.hours(), 5, 'adding days over DST difference should result in the same hour');\n    if (b.isDST() && !d.isDST()) {\n        assert.equal(b.hours(), 6, 'adding hours over DST difference should result in a different hour');\n    } else if (!b.isDST() && d.isDST()) {\n        assert.equal(b.hours(), 4, 'adding hours over DST difference should result in a different hour');\n    } else {\n        assert.equal(b.hours(), 5, 'adding hours over DST difference should result in a same hour if the timezone does not have daylight savings time');\n    }\n    assert.equal(c.hours(), 5, 'adding months over DST difference should result in the same hour');\n    assert.equal(e.hours(), 5, 'adding quarters over DST difference should result in the same hour');\n});\n\ntest('add decimal values of days and months', function (assert) {\n    assert.equal(moment([2016,3,3]).add(1.5, 'days').date(), 5, 'adding 1.5 days is rounded to adding 2 day');\n    assert.equal(moment([2016,3,3]).add(-1.5, 'days').date(), 1, 'adding -1.5 days is rounded to adding -2 day');\n    assert.equal(moment([2016,3,1]).add(-1.5, 'days').date(), 30, 'adding -1.5 days on first of month wraps around');\n    assert.equal(moment([2016,3,3]).add(1.5, 'months').month(), 5, 'adding 1.5 months adds 2 months');\n    assert.equal(moment([2016,3,3]).add(-1.5, 'months').month(), 1, 'adding -1.5 months adds -2 months');\n    assert.equal(moment([2016,0,3]).add(-1.5, 'months').month(), 10, 'adding -1.5 months at start of year wraps back');\n    assert.equal(moment([2016,3,3]).subtract(1.5, 'days').date(),1, 'subtract 1.5 days is rounded to subtract 2 day');\n    assert.equal(moment([2016,3,2]).subtract(1.5, 'days').date(), 31, 'subtract 1.5 days subtracts 2 days');\n    assert.equal(moment([2016,1,1]).subtract(1.1, 'days').date(), 31, 'subtract 1.1 days wraps to previous month');\n    assert.equal(moment([2016,3,3]).subtract(-1.5, 'days').date(), 5, 'subtract -1.5 days is rounded to subtract -2 day');\n    assert.equal(moment([2016,3,30]).subtract(-1.5, 'days').date(), 2, 'subtract -1.5 days on last of month wraps around');\n    assert.equal(moment([2016,3,3]).subtract(1.5, 'months').month(), 1, 'subtract 1.5 months subtract 2 months');\n    assert.equal(moment([2016,3,3]).subtract(-1.5, 'months').month(), 5, 'subtract -1.5 months subtract -2 month');\n    assert.equal(moment([2016,11,31]).subtract(-1.5, 'months').month(),1, 'subtract -1.5 months at end of year wraps back');\n    assert.equal(moment([2016, 0,1]).add(1.5, 'years').format('YYYY-MM-DD'), '2017-07-01', 'add 1.5 years adds 1 year six months');\n    assert.equal(moment([2016, 0,1]).add(1.6, 'years').format('YYYY-MM-DD'), '2017-08-01', 'add 1.6 years becomes 1.6*12 = 19.2, round, 19 months');\n    assert.equal(moment([2016,0,1]).add(1.1, 'quarters').format('YYYY-MM-DD'), '2016-04-01', 'add 1.1 quarters 1.1*3=3.3, round, 3 months');\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\nfunction module$1 (name, lifecycle) {\n    QUnit.module(name, {\n        setup : function () {\n            moment.locale('en');\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'core');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            teardownDeprecationHandler(test, moment, 'core');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n}\n\n// These tests are for locale independent features\n// locale dependent tests would be in locale test folder\nmodule$1('calendar');\n\ntest('passing a function', function (assert) {\n    var a  = moment().hours(13).minutes(0).seconds(0);\n    assert.equal(moment(a).calendar(null, {\n        'sameDay': function () {\n            return 'h:mmA';\n        }\n    }), '1:00PM', 'should equate');\n});\n\ntest('extending calendar options', function (assert) {\n    var calendarFormat = moment.calendarFormat;\n\n    moment.calendarFormat = function (myMoment, now) {\n        var diff = myMoment.diff(now, 'days', true);\n        var nextMonth = now.clone().add(1, 'month');\n\n        var retVal =  diff < -6 ? 'sameElse' :\n            diff < -1 ? 'lastWeek' :\n            diff < 0 ? 'lastDay' :\n            diff < 1 ? 'sameDay' :\n            diff < 2 ? 'nextDay' :\n            diff < 7 ? 'nextWeek' :\n            (myMoment.month() === now.month() && myMoment.year() === now.year()) ? 'thisMonth' :\n            (nextMonth.month() === myMoment.month() && nextMonth.year() === myMoment.year()) ? 'nextMonth' : 'sameElse';\n        return retVal;\n    };\n\n    moment.updateLocale('en', {\n        calendar : {\n                sameDay : '[Today at] LT',\n                nextDay : '[Tomorrow at] LT',\n                nextWeek : 'dddd [at] LT',\n                lastDay : '[Yesterday at] LT',\n                lastWeek : '[Last] dddd [at] LT',\n                thisMonth : '[This month on the] Do',\n                nextMonth : '[Next month on the] Do',\n                sameElse : 'L'\n            }\n    });\n    var a = moment('2016-01-01').add(28, 'days');\n    var b = moment('2016-01-01').add(1, 'month');\n    try {\n        assert.equal(a.calendar('2016-01-01'), 'This month on the 29th', 'Ad hoc calendar format for this month');\n        assert.equal(b.calendar('2016-01-01'), 'Next month on the 1st', 'Ad hoc calendar format for next month');\n        assert.equal(a.locale('fr').calendar('2016-01-01'), a.locale('fr').format('L'), 'French falls back to default because thisMonth is not defined in that locale');\n    } finally {\n        moment.calendarFormat = calendarFormat;\n        moment.updateLocale('en', null);\n    }\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\nfunction module$1 (name, lifecycle) {\n    QUnit.module(name, {\n        setup : function () {\n            moment.locale('en');\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'core');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            teardownDeprecationHandler(test, moment, 'core');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n}\n\nmodule$1('create');\n\ntest('array', function (assert) {\n    assert.ok(moment([2010]).toDate() instanceof Date, '[2010]');\n    assert.ok(moment([2010, 1]).toDate() instanceof Date, '[2010, 1]');\n    assert.ok(moment([2010, 1, 12]).toDate() instanceof Date, '[2010, 1, 12]');\n    assert.ok(moment([2010, 1, 12, 1]).toDate() instanceof Date, '[2010, 1, 12, 1]');\n    assert.ok(moment([2010, 1, 12, 1, 1]).toDate() instanceof Date, '[2010, 1, 12, 1, 1]');\n    assert.ok(moment([2010, 1, 12, 1, 1, 1]).toDate() instanceof Date, '[2010, 1, 12, 1, 1, 1]');\n    assert.ok(moment([2010, 1, 12, 1, 1, 1, 1]).toDate() instanceof Date, '[2010, 1, 12, 1, 1, 1, 1]');\n    assert.equal(+moment(new Date(2010, 1, 14, 15, 25, 50, 125)), +moment([2010, 1, 14, 15, 25, 50, 125]), 'constructing with array === constructing with new Date()');\n});\n\ntest('array with invalid arguments', function (assert) {\n    assert.ok(!moment([2010, null, null]).isValid(), '[2010, null, null]');\n    assert.ok(!moment([1945, null, null]).isValid(), '[1945, null, null] (pre-1970)');\n});\n\ntest('array copying', function (assert) {\n    var importantArray = [2009, 11];\n    moment(importantArray);\n    assert.deepEqual(importantArray, [2009, 11], 'initializer should not mutate the original array');\n});\n\ntest('object', function (assert) {\n    var fmt = 'YYYY-MM-DD HH:mm:ss.SSS',\n        tests = [\n            [{year: 2010}, '2010-01-01 00:00:00.000'],\n            [{year: 2010, month: 1}, '2010-02-01 00:00:00.000'],\n            [{year: 2010, month: 1, day: 12}, '2010-02-12 00:00:00.000'],\n            [{year: 2010, month: 1, date: 12}, '2010-02-12 00:00:00.000'],\n            [{year: 2010, month: 1, day: 12, hours: 1}, '2010-02-12 01:00:00.000'],\n            [{year: 2010, month: 1, date: 12, hours: 1}, '2010-02-12 01:00:00.000'],\n            [{year: 2010, month: 1, day: 12, hours: 1, minutes: 1}, '2010-02-12 01:01:00.000'],\n            [{year: 2010, month: 1, date: 12, hours: 1, minutes: 1}, '2010-02-12 01:01:00.000'],\n            [{year: 2010, month: 1, day: 12, hours: 1, minutes: 1, seconds: 1}, '2010-02-12 01:01:01.000'],\n            [{year: 2010, month: 1, day: 12, hours: 1, minutes: 1, seconds: 1, milliseconds: 1}, '2010-02-12 01:01:01.001'],\n            [{years: 2010, months: 1, days: 14, hours: 15, minutes: 25, seconds: 50, milliseconds: 125}, '2010-02-14 15:25:50.125'],\n            [{year: 2010, month: 1, day: 14, hour: 15, minute: 25, second: 50, millisecond: 125}, '2010-02-14 15:25:50.125'],\n            [{y: 2010, M: 1, d: 14, h: 15, m: 25, s: 50, ms: 125}, '2010-02-14 15:25:50.125']\n        ], i;\n    for (i = 0; i < tests.length; ++i) {\n        assert.equal(moment(tests[i][0]).format(fmt), tests[i][1]);\n    }\n});\n\ntest('multi format array copying', function (assert) {\n    var importantArray = ['MM/DD/YYYY', 'YYYY-MM-DD', 'MM-DD-YYYY'];\n    moment('1999-02-13', importantArray);\n    assert.deepEqual(importantArray, ['MM/DD/YYYY', 'YYYY-MM-DD', 'MM-DD-YYYY'], 'initializer should not mutate the original array');\n});\n\ntest('number', function (assert) {\n    assert.ok(moment(1000).toDate() instanceof Date, '1000');\n    assert.equal(moment(1000).valueOf(), 1000, 'asserting valueOf');\n    assert.equal(moment.utc(1000).valueOf(), 1000, 'asserting valueOf');\n});\n\ntest('unix', function (assert) {\n    assert.equal(moment.unix(1).valueOf(), 1000, '1 unix timestamp == 1000 Date.valueOf');\n    assert.equal(moment(1000).unix(), 1, '1000 Date.valueOf == 1 unix timestamp');\n    assert.equal(moment.unix(1000).valueOf(), 1000000, '1000 unix timestamp == 1000000 Date.valueOf');\n    assert.equal(moment(1500).unix(), 1, '1500 Date.valueOf == 1 unix timestamp');\n    assert.equal(moment(1900).unix(), 1, '1900 Date.valueOf == 1 unix timestamp');\n    assert.equal(moment(2100).unix(), 2, '2100 Date.valueOf == 2 unix timestamp');\n    assert.equal(moment(1333129333524).unix(), 1333129333, '1333129333524 Date.valueOf == 1333129333 unix timestamp');\n    assert.equal(moment(1333129333524000).unix(), 1333129333524, '1333129333524000 Date.valueOf == 1333129333524 unix timestamp');\n});\n\ntest('date', function (assert) {\n    assert.ok(moment(new Date()).toDate() instanceof Date, 'new Date()');\n    assert.equal(moment(new Date(2016,0,1), 'YYYY-MM-DD').format('YYYY-MM-DD'), '2016-01-01', 'If date is provided, format string is ignored');\n});\n\ntest('date with a format as an array', function (assert) {\n    var tests = [\n        new Date(2016, 9, 27),\n        new Date(2016, 9, 28),\n        new Date(2016, 9, 29),\n        new Date(2016, 9, 30),\n        new Date(2016, 9, 31)\n    ], i;\n\n    for (i = 0; i < tests.length; i++) {\n        assert.equal(moment(tests[i]).format(), moment(tests[i], ['MM/DD/YYYY'], false).format(), 'Passing date with a format array should still return the correct date');\n    }\n});\n\ntest('date mutation', function (assert) {\n    var a = new Date();\n    assert.ok(moment(a).toDate() !== a, 'the date moment uses should not be the date passed in');\n});\n\ntest('moment', function (assert) {\n    assert.ok(moment(moment()).toDate() instanceof Date, 'moment(moment())');\n    assert.ok(moment(moment(moment())).toDate() instanceof Date, 'moment(moment(moment()))');\n});\n\ntest('cloning moment should only copy own properties', function (assert) {\n    assert.ok(!moment().clone().hasOwnProperty('month'), 'Should not clone prototype methods');\n});\n\ntest('cloning moment works with weird clones', function (assert) {\n    var extend = function (a, b) {\n        var i;\n        for (i in b) {\n            a[i] = b[i];\n        }\n        return a;\n    },\n    now = moment(),\n    nowu = moment.utc();\n\n    assert.equal(+extend({}, now).clone(), +now, 'cloning extend-ed now is now');\n    assert.equal(+extend({}, nowu).clone(), +nowu, 'cloning extend-ed utc now is utc now');\n});\n\ntest('cloning respects moment.momentProperties', function (assert) {\n    var m = moment();\n\n    assert.equal(m.clone()._special, undefined, 'cloning ignores extra properties');\n    m._special = 'bacon';\n    moment.momentProperties.push('_special');\n    assert.equal(m.clone()._special, 'bacon', 'cloning respects momentProperties');\n    moment.momentProperties.pop();\n});\n\ntest('undefined', function (assert) {\n    assert.ok(moment().toDate() instanceof Date, 'undefined');\n});\n\ntest('iso with bad input', function (assert) {\n    assert.ok(!moment('a', moment.ISO_8601).isValid(), 'iso parsing with invalid string');\n    assert.ok(!moment('a', moment.ISO_8601, true).isValid(), 'iso parsing with invalid string, strict');\n});\n\ntest('iso format 24hrs', function (assert) {\n    assert.equal(moment('2014-01-01T24:00:00.000').format('YYYY-MM-DD[T]HH:mm:ss.SSS'),\n            '2014-01-02T00:00:00.000', 'iso format with 24:00 localtime');\n    assert.equal(moment.utc('2014-01-01T24:00:00.000').format('YYYY-MM-DD[T]HH:mm:ss.SSS'),\n            '2014-01-02T00:00:00.000', 'iso format with 24:00 utc');\n});\n\ntest('string without format - json', function (assert) {\n    assert.equal(moment('Date(1325132654000)').valueOf(), 1325132654000, 'Date(1325132654000)');\n    assert.equal(moment('Date(-1325132654000)').valueOf(), -1325132654000, 'Date(-1325132654000)');\n    assert.equal(moment('/Date(1325132654000)/').valueOf(), 1325132654000, '/Date(1325132654000)/');\n    assert.equal(moment('/Date(1325132654000+0700)/').valueOf(), 1325132654000, '/Date(1325132654000+0700)/');\n    assert.equal(moment('/Date(1325132654000-0700)/').valueOf(), 1325132654000, '/Date(1325132654000-0700)/');\n});\n\ntest('string with format dropped am/pm bug', function (assert) {\n    moment.locale('en');\n\n    assert.equal(moment('05/1/2012 12:25:00', 'MM/DD/YYYY h:m:s a').format('MM/DD/YYYY'), '05/01/2012', 'should not break if am/pm is left off from the parsing tokens');\n    assert.equal(moment('05/1/2012 12:25:00 am', 'MM/DD/YYYY h:m:s a').format('MM/DD/YYYY'), '05/01/2012', 'should not break if am/pm is left off from the parsing tokens');\n    assert.equal(moment('05/1/2012 12:25:00 pm', 'MM/DD/YYYY h:m:s a').format('MM/DD/YYYY'), '05/01/2012', 'should not break if am/pm is left off from the parsing tokens');\n\n    assert.ok(moment('05/1/2012 12:25:00', 'MM/DD/YYYY h:m:s a').isValid());\n    assert.ok(moment('05/1/2012 12:25:00 am', 'MM/DD/YYYY h:m:s a').isValid());\n    assert.ok(moment('05/1/2012 12:25:00 pm', 'MM/DD/YYYY h:m:s a').isValid());\n});\n\ntest('empty string with formats', function (assert) {\n    assert.equal(moment('', 'MM').format('YYYY-MM-DD HH:mm:ss'), 'Invalid date');\n    assert.equal(moment(' ', 'MM').format('YYYY-MM-DD HH:mm:ss'), 'Invalid date');\n    assert.equal(moment(' ', 'DD').format('YYYY-MM-DD HH:mm:ss'), 'Invalid date');\n    assert.equal(moment(' ', ['MM', 'DD']).format('YYYY-MM-DD HH:mm:ss'), 'Invalid date');\n\n    assert.ok(!moment('', 'MM').isValid());\n    assert.ok(!moment(' ', 'MM').isValid());\n    assert.ok(!moment(' ', 'DD').isValid());\n    assert.ok(!moment(' ', ['MM', 'DD']).isValid());\n});\n\ntest('undefined argument with formats', function (assert) {\n    assert.equal(moment(undefined, 'MM').format('YYYY-MM-DD HH:mm:ss'), 'Invalid date');\n    assert.equal(moment(undefined, 'DD').format('YYYY-MM-DD HH:mm:ss'), 'Invalid date');\n    assert.equal(moment(undefined, ['MM', 'DD']).format('YYYY-MM-DD HH:mm:ss'), 'Invalid date');\n\n    assert.ok(!moment(undefined, 'MM').isValid());\n    assert.ok(!moment(undefined, 'MM').isValid());\n    assert.ok(!moment(undefined, 'DD').isValid());\n    assert.ok(!moment(undefined, ['MM', 'DD']).isValid());\n});\n\ntest('defaulting to current date', function (assert) {\n    var now = moment();\n    assert.equal(moment('12:13:14', 'hh:mm:ss').format('YYYY-MM-DD hh:mm:ss'),\n                 now.clone().hour(12).minute(13).second(14).format('YYYY-MM-DD hh:mm:ss'),\n                 'given only time default to current date');\n    assert.equal(moment('05', 'DD').format('YYYY-MM-DD'),\n                 now.clone().date(5).format('YYYY-MM-DD'),\n                 'given day of month default to current month, year');\n    assert.equal(moment('05', 'MM').format('YYYY-MM-DD'),\n                 now.clone().month(4).date(1).format('YYYY-MM-DD'),\n                 'given month default to current year');\n    assert.equal(moment('1996', 'YYYY').format('YYYY-MM-DD'),\n                 now.clone().year(1996).month(0).date(1).format('YYYY-MM-DD'),\n                 'given year do not default');\n});\n\ntest('matching am/pm', function (assert) {\n    assert.equal(moment('2012-09-03T03:00PM',   'YYYY-MM-DDThh:mmA').format('YYYY-MM-DDThh:mmA'), '2012-09-03T03:00PM', 'am/pm should parse correctly for PM');\n    assert.equal(moment('2012-09-03T03:00P.M.', 'YYYY-MM-DDThh:mmA').format('YYYY-MM-DDThh:mmA'), '2012-09-03T03:00PM', 'am/pm should parse correctly for P.M.');\n    assert.equal(moment('2012-09-03T03:00P',    'YYYY-MM-DDThh:mmA').format('YYYY-MM-DDThh:mmA'), '2012-09-03T03:00PM', 'am/pm should parse correctly for P');\n    assert.equal(moment('2012-09-03T03:00pm',   'YYYY-MM-DDThh:mmA').format('YYYY-MM-DDThh:mmA'), '2012-09-03T03:00PM', 'am/pm should parse correctly for pm');\n    assert.equal(moment('2012-09-03T03:00p.m.', 'YYYY-MM-DDThh:mmA').format('YYYY-MM-DDThh:mmA'), '2012-09-03T03:00PM', 'am/pm should parse correctly for p.m.');\n    assert.equal(moment('2012-09-03T03:00p',    'YYYY-MM-DDThh:mmA').format('YYYY-MM-DDThh:mmA'), '2012-09-03T03:00PM', 'am/pm should parse correctly for p');\n\n    assert.equal(moment('2012-09-03T03:00AM',   'YYYY-MM-DDThh:mmA').format('YYYY-MM-DDThh:mmA'), '2012-09-03T03:00AM', 'am/pm should parse correctly for AM');\n    assert.equal(moment('2012-09-03T03:00A.M.', 'YYYY-MM-DDThh:mmA').format('YYYY-MM-DDThh:mmA'), '2012-09-03T03:00AM', 'am/pm should parse correctly for A.M.');\n    assert.equal(moment('2012-09-03T03:00A',    'YYYY-MM-DDThh:mmA').format('YYYY-MM-DDThh:mmA'), '2012-09-03T03:00AM', 'am/pm should parse correctly for A');\n    assert.equal(moment('2012-09-03T03:00am',   'YYYY-MM-DDThh:mmA').format('YYYY-MM-DDThh:mmA'), '2012-09-03T03:00AM', 'am/pm should parse correctly for am');\n    assert.equal(moment('2012-09-03T03:00a.m.', 'YYYY-MM-DDThh:mmA').format('YYYY-MM-DDThh:mmA'), '2012-09-03T03:00AM', 'am/pm should parse correctly for a.m.');\n    assert.equal(moment('2012-09-03T03:00a',    'YYYY-MM-DDThh:mmA').format('YYYY-MM-DDThh:mmA'), '2012-09-03T03:00AM', 'am/pm should parse correctly for a');\n\n    assert.equal(moment('5:00p.m.March 4 2012', 'h:mmAMMMM D YYYY').format('YYYY-MM-DDThh:mmA'), '2012-03-04T05:00PM', 'am/pm should parse correctly before month names');\n});\n\ntest('string with format', function (assert) {\n    moment.locale('en');\n    var a = [\n        ['YYYY-Q',              '2014-4'],\n        ['MM-DD-YYYY',          '12-02-1999'],\n        ['DD-MM-YYYY',          '12-02-1999'],\n        ['DD/MM/YYYY',          '12/02/1999'],\n        ['DD_MM_YYYY',          '12_02_1999'],\n        ['DD:MM:YYYY',          '12:02:1999'],\n        ['D-M-YY',              '2-2-99'],\n        ['YY',                  '99'],\n        ['DDD-YYYY',            '300-1999'],\n        ['DD-MM-YYYY h:m:s',    '12-02-1999 2:45:10'],\n        ['DD-MM-YYYY h:m:s a',  '12-02-1999 2:45:10 am'],\n        ['DD-MM-YYYY h:m:s a',  '12-02-1999 2:45:10 pm'],\n        ['h:mm a',              '12:00 pm'],\n        ['h:mm a',              '12:30 pm'],\n        ['h:mm a',              '12:00 am'],\n        ['h:mm a',              '12:30 am'],\n        ['HH:mm',               '12:00'],\n        ['kk:mm',               '12:00'],\n        ['YYYY-MM-DDTHH:mm:ss', '2011-11-11T11:11:11'],\n        ['MM-DD-YYYY [M]',      '12-02-1999 M'],\n        ['ddd MMM DD HH:mm:ss YYYY', 'Tue Apr 07 22:52:51 2009'],\n        ['HH:mm:ss',            '12:00:00'],\n        ['HH:mm:ss',            '12:30:00'],\n        ['HH:mm:ss',            '00:00:00'],\n        ['HH:mm:ss S',          '00:30:00 1'],\n        ['HH:mm:ss SS',         '00:30:00 12'],\n        ['HH:mm:ss SSS',        '00:30:00 123'],\n        ['HH:mm:ss S',          '00:30:00 7'],\n        ['HH:mm:ss SS',         '00:30:00 78'],\n        ['HH:mm:ss SSS',        '00:30:00 789'],\n        ['kk:mm:ss',            '12:00:00'],\n        ['kk:mm:ss',            '12:30:00'],\n        ['kk:mm:ss',            '24:00:00'],\n        ['kk:mm:ss S',          '24:30:00 1'],\n        ['kk:mm:ss SS',         '24:30:00 12'],\n        ['kk:mm:ss SSS',        '24:30:00 123'],\n        ['kk:mm:ss S',          '24:30:00 7'],\n        ['kk:mm:ss SS',         '24:30:00 78'],\n        ['kk:mm:ss SSS',        '24:30:00 789'],\n        ['X',                   '1234567890'],\n        ['x',                   '1234567890123'],\n        ['LT',                  '12:30 AM'],\n        ['LTS',                 '12:30:29 AM'],\n        ['L',                   '09/02/1999'],\n        ['l',                   '9/2/1999'],\n        ['LL',                  'September 2, 1999'],\n        ['ll',                  'Sep 2, 1999'],\n        ['LLL',                 'September 2, 1999 12:30 AM'],\n        ['lll',                 'Sep 2, 1999 12:30 AM'],\n        ['LLLL',                'Thursday, September 2, 1999 12:30 AM'],\n        ['llll',                'Thu, Sep 2, 1999 12:30 AM']\n    ],\n    m,\n    i;\n\n    for (i = 0; i < a.length; i++) {\n        m = moment(a[i][1], a[i][0]);\n        assert.ok(m.isValid());\n        assert.equal(m.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('2 digit year with YYYY format', function (assert) {\n    assert.equal(moment('9/2/99', 'D/M/YYYY').format('DD/MM/YYYY'), '09/02/1999', 'D/M/YYYY ---> 9/2/99');\n    assert.equal(moment('9/2/1999', 'D/M/YYYY').format('DD/MM/YYYY'), '09/02/1999', 'D/M/YYYY ---> 9/2/1999');\n    assert.equal(moment('9/2/68', 'D/M/YYYY').format('DD/MM/YYYY'), '09/02/2068', 'D/M/YYYY ---> 9/2/68');\n    assert.equal(moment('9/2/69', 'D/M/YYYY').format('DD/MM/YYYY'), '09/02/1969', 'D/M/YYYY ---> 9/2/69');\n});\n\ntest('unix timestamp format', function (assert) {\n    var formats = ['X', 'X.S', 'X.SS', 'X.SSS'], i, format;\n\n    for (i = 0; i < formats.length; i++) {\n        format = formats[i];\n        assert.equal(moment('1234567890',     format).valueOf(), 1234567890 * 1000,       format + ' matches timestamp without milliseconds');\n        assert.equal(moment('1234567890.1',   format).valueOf(), 1234567890 * 1000 + 100, format + ' matches timestamp with deciseconds');\n        assert.equal(moment('1234567890.12',  format).valueOf(), 1234567890 * 1000 + 120, format + ' matches timestamp with centiseconds');\n        assert.equal(moment('1234567890.123', format).valueOf(), 1234567890 * 1000 + 123, format + ' matches timestamp with milliseconds');\n    }\n});\n\ntest('unix offset milliseconds', function (assert) {\n    assert.equal(moment('1234567890123', 'x').valueOf(), 1234567890123, 'x matches unix offset in milliseconds');\n});\n\ntest('milliseconds format', function (assert) {\n    assert.equal(moment('1', 'S').get('ms'), 100, 'deciseconds');\n    // assert.equal(moment('10', 'S', true).isValid(), false, 'deciseconds with two digits');\n    // assert.equal(moment('1', 'SS', true).isValid(), false, 'centiseconds with one digits');\n    assert.equal(moment('12', 'SS').get('ms'), 120, 'centiseconds');\n    // assert.equal(moment('123', 'SS', true).isValid(), false, 'centiseconds with three digits');\n    assert.equal(moment('123', 'SSS').get('ms'), 123, 'milliseconds');\n    assert.equal(moment('1234', 'SSSS').get('ms'), 123, 'milliseconds with SSSS');\n    assert.equal(moment('123456789101112', 'SSSS').get('ms'), 123, 'milliseconds with SSSS');\n});\n\ntest('string with format no separators', function (assert) {\n    moment.locale('en');\n    var a = [\n        ['MMDDYYYY',          '12021999'],\n        ['DDMMYYYY',          '12021999'],\n        ['YYYYMMDD',          '19991202'],\n        ['DDMMMYYYY',         '10Sep2001']\n    ], i;\n\n    for (i = 0; i < a.length; i++) {\n        assert.equal(moment(a[i][1], a[i][0]).format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('string with format (timezone)', function (assert) {\n    assert.equal(moment('5 -0700', 'H ZZ').toDate().getUTCHours(), 12, 'parse hours \\'5 -0700\\' ---> \\'H ZZ\\'');\n    assert.equal(moment('5 -07:00', 'H Z').toDate().getUTCHours(), 12, 'parse hours \\'5 -07:00\\' ---> \\'H Z\\'');\n    assert.equal(moment('5 -0730', 'H ZZ').toDate().getUTCMinutes(), 30, 'parse hours \\'5 -0730\\' ---> \\'H ZZ\\'');\n    assert.equal(moment('5 -07:30', 'H Z').toDate().getUTCMinutes(), 30, 'parse hours \\'5 -07:0\\' ---> \\'H Z\\'');\n    assert.equal(moment('5 +0100', 'H ZZ').toDate().getUTCHours(), 4, 'parse hours \\'5 +0100\\' ---> \\'H ZZ\\'');\n    assert.equal(moment('5 +01:00', 'H Z').toDate().getUTCHours(), 4, 'parse hours \\'5 +01:00\\' ---> \\'H Z\\'');\n    assert.equal(moment('5 +0130', 'H ZZ').toDate().getUTCMinutes(), 30, 'parse hours \\'5 +0130\\' ---> \\'H ZZ\\'');\n    assert.equal(moment('5 +01:30', 'H Z').toDate().getUTCMinutes(), 30, 'parse hours \\'5 +01:30\\' ---> \\'H Z\\'');\n});\n\ntest('string with format (timezone offset)', function (assert) {\n    var a, b, c, d, e, f;\n    a = new Date(Date.UTC(2011, 0, 1, 1));\n    b = moment('2011 1 1 0 -01:00', 'YYYY MM DD HH Z');\n    assert.equal(a.getHours(), b.hours(), 'date created with utc == parsed string with timezone offset');\n    assert.equal(+a, +b, 'date created with utc == parsed string with timezone offset');\n    c = moment('2011 2 1 10 -05:00', 'YYYY MM DD HH Z');\n    d = moment('2011 2 1 8 -07:00', 'YYYY MM DD HH Z');\n    assert.equal(c.hours(), d.hours(), '10 am central time == 8 am pacific time');\n    e = moment.utc('Fri, 20 Jul 2012 17:15:00', 'ddd, DD MMM YYYY HH:mm:ss');\n    f = moment.utc('Fri, 20 Jul 2012 10:15:00 -0700', 'ddd, DD MMM YYYY HH:mm:ss ZZ');\n    assert.equal(e.hours(), f.hours(), 'parse timezone offset in utc');\n});\n\ntest('string with timezone around start of year', function (assert) {\n    assert.equal(moment('2000-01-01T00:00:00.000+01:00').toISOString(), '1999-12-31T23:00:00.000Z', '+1:00 around 2000');\n    assert.equal(moment('2000-01-01T00:00:00.000-01:00').toISOString(), '2000-01-01T01:00:00.000Z', '-1:00 around 2000');\n    assert.equal(moment('1970-01-01T00:00:00.000+01:00').toISOString(), '1969-12-31T23:00:00.000Z', '+1:00 around 1970');\n    assert.equal(moment('1970-01-01T00:00:00.000-01:00').toISOString(), '1970-01-01T01:00:00.000Z', '-1:00 around 1970');\n    assert.equal(moment('1200-01-01T00:00:00.000+01:00').toISOString(), '1199-12-31T23:00:00.000Z', '+1:00 around 1200');\n    assert.equal(moment('1200-01-01T00:00:00.000-01:00').toISOString(), '1200-01-01T01:00:00.000Z', '-1:00 around 1200');\n});\n\ntest('string with array of formats', function (assert) {\n    var thursdayForCurrentWeek = moment()\n      .day(4)\n      .format('YYYY MM DD');\n\n    assert.equal(moment('11-02-1999', ['MM-DD-YYYY', 'DD-MM-YYYY']).format('MM DD YYYY'), '11 02 1999', 'switching month and day');\n    assert.equal(moment('02-11-1999', ['MM/DD/YYYY', 'YYYY MM DD', 'MM-DD-YYYY']).format('MM DD YYYY'), '02 11 1999', 'year last');\n    assert.equal(moment('1999-02-11', ['MM/DD/YYYY', 'YYYY MM DD', 'MM-DD-YYYY']).format('MM DD YYYY'), '02 11 1999', 'year first');\n\n    assert.equal(moment('02-11-1999', ['MM/DD/YYYY', 'YYYY MM DD']).format('MM DD YYYY'), '02 11 1999', 'year last');\n    assert.equal(moment('1999-02-11', ['MM/DD/YYYY', 'YYYY MM DD']).format('MM DD YYYY'), '02 11 1999', 'year first');\n    assert.equal(moment('02-11-1999', ['YYYY MM DD', 'MM/DD/YYYY']).format('MM DD YYYY'), '02 11 1999', 'year last');\n    assert.equal(moment('1999-02-11', ['YYYY MM DD', 'MM/DD/YYYY']).format('MM DD YYYY'), '02 11 1999', 'year first');\n\n    assert.equal(moment('13-11-1999', ['MM/DD/YYYY', 'DD/MM/YYYY']).format('MM DD YYYY'), '11 13 1999', 'second must be month');\n    assert.equal(moment('11-13-1999', ['MM/DD/YYYY', 'DD/MM/YYYY']).format('MM DD YYYY'), '11 13 1999', 'first must be month');\n    assert.equal(moment('01-02-2000', ['MM/DD/YYYY', 'DD/MM/YYYY']).format('MM DD YYYY'), '01 02 2000', 'either can be a month, month first format');\n    assert.equal(moment('02-01-2000', ['DD/MM/YYYY', 'MM/DD/YYYY']).format('MM DD YYYY'), '01 02 2000', 'either can be a month, day first format');\n\n    assert.equal(moment('11-02-10', ['MM/DD/YY', 'YY MM DD', 'DD-MM-YY']).format('MM DD YYYY'), '02 11 2010', 'all unparsed substrings have influence on format penalty');\n    assert.equal(moment('11-02-10', ['MM-DD-YY HH:mm', 'YY MM DD']).format('MM DD YYYY'), '02 10 2011', 'prefer formats without extra tokens');\n    assert.equal(moment('11-02-10 junk', ['MM-DD-YY', 'YY.MM.DD [junk]']).format('MM DD YYYY'), '02 10 2011', 'prefer formats that dont result in extra characters');\n    assert.equal(moment('11-22-10', ['YY-MM-DD', 'YY-DD-MM']).format('MM DD YYYY'), '10 22 2011', 'prefer valid results');\n\n    assert.equal(moment('gibberish', ['YY-MM-DD', 'YY-DD-MM']).format('MM DD YYYY'), 'Invalid date', 'doest throw for invalid strings');\n    assert.equal(moment('gibberish', []).format('MM DD YYYY'), 'Invalid date', 'doest throw for an empty array');\n\n    // https://github.com/moment/moment/issues/1143\n    assert.equal(moment(\n        'System Administrator and Database Assistant (7/1/2011), System Administrator and Database Assistant (7/1/2011), Database Coordinator (7/1/2011), Vice President (7/1/2011), System Administrator and Database Assistant (5/31/2012), Database Coordinator (7/1/2012), System Administrator and Database Assistant (7/1/2013)',\n        ['MM/DD/YYYY', 'MM-DD-YYYY', 'YYYY-MM-DD', 'YYYY-MM-DDTHH:mm:ssZ'])\n        .format('YYYY-MM-DD'), '2011-07-01', 'Works for long strings');\n\n    assert.equal(moment('11-02-10', ['MM.DD.YY', 'DD-MM-YY']).format('MM DD YYYY'), '02 11 2010', 'escape RegExp special characters on comparing');\n\n    assert.equal(moment('13-10-98', ['DD MM YY', 'DD MM YYYY'])._f, 'DD MM YY', 'use two digit year');\n    assert.equal(moment('13-10-1998', ['DD MM YY', 'DD MM YYYY'])._f, 'DD MM YYYY', 'use four digit year');\n\n    assert.equal(moment('01', ['MM', 'DD'])._f, 'MM', 'Should use first valid format');\n\n    assert.equal(moment('Thursday 8:30pm', ['dddd h:mma']).format('YYYY MM DD dddd h:mma'), thursdayForCurrentWeek + ' Thursday 8:30pm', 'Default to current week');\n});\n\ntest('string with array of formats + ISO', function (assert) {\n    assert.equal(moment('1994', [moment.ISO_8601, 'MM', 'HH:mm', 'YYYY']).year(), 1994, 'iso: assert parse YYYY');\n    assert.equal(moment('17:15', [moment.ISO_8601, 'MM', 'HH:mm', 'YYYY']).hour(), 17, 'iso: assert parse HH:mm (1)');\n    assert.equal(moment('24:15', [moment.ISO_8601, 'MM', 'kk:mm', 'YYYY']).hour(), 0, 'iso: assert parse kk:mm');\n    assert.equal(moment('17:15', [moment.ISO_8601, 'MM', 'HH:mm', 'YYYY']).minutes(), 15, 'iso: assert parse HH:mm (2)');\n    assert.equal(moment('06', [moment.ISO_8601, 'MM', 'HH:mm', 'YYYY']).month(), 6 - 1, 'iso: assert parse MM');\n    assert.equal(moment('2012-06-01', [moment.ISO_8601, 'MM', 'HH:mm', 'YYYY']).parsingFlags().iso, true, 'iso: assert parse iso');\n    assert.equal(moment('2014-05-05', [moment.ISO_8601, 'YYYY-MM-DD']).parsingFlags().iso, true, 'iso: edge case array precedence iso');\n    assert.equal(moment('2014-05-05', ['YYYY-MM-DD', moment.ISO_8601]).parsingFlags().iso, false, 'iso: edge case array precedence not iso');\n});\n\ntest('string with format - years', function (assert) {\n    assert.equal(moment('67', 'YY').format('YYYY'), '2067', '67 > 2067');\n    assert.equal(moment('68', 'YY').format('YYYY'), '2068', '68 > 2068');\n    assert.equal(moment('69', 'YY').format('YYYY'), '1969', '69 > 1969');\n    assert.equal(moment('70', 'YY').format('YYYY'), '1970', '70 > 1970');\n});\n\ntest('implicit cloning', function (assert) {\n    var momentA = moment([2011, 10, 10]),\n    momentB = moment(momentA);\n    momentA.month(5);\n    assert.equal(momentB.month(), 10, 'Calling moment() on a moment will create a clone');\n    assert.equal(momentA.month(), 5, 'Calling moment() on a moment will create a clone');\n});\n\ntest('explicit cloning', function (assert) {\n    var momentA = moment([2011, 10, 10]),\n    momentB = momentA.clone();\n    momentA.month(5);\n    assert.equal(momentB.month(), 10, 'Calling moment() on a moment will create a clone');\n    assert.equal(momentA.month(), 5, 'Calling moment() on a moment will create a clone');\n});\n\ntest('cloning carrying over utc mode', function (assert) {\n    assert.equal(moment().local().clone()._isUTC, false, 'An explicit cloned local moment should have _isUTC == false');\n    assert.equal(moment().utc().clone()._isUTC, true, 'An cloned utc moment should have _isUTC == true');\n    assert.equal(moment().clone()._isUTC, false, 'An explicit cloned local moment should have _isUTC == false');\n    assert.equal(moment.utc().clone()._isUTC, true, 'An explicit cloned utc moment should have _isUTC == true');\n    assert.equal(moment(moment().local())._isUTC, false, 'An implicit cloned local moment should have _isUTC == false');\n    assert.equal(moment(moment().utc())._isUTC, true, 'An implicit cloned utc moment should have _isUTC == true');\n    assert.equal(moment(moment())._isUTC, false, 'An implicit cloned local moment should have _isUTC == false');\n    assert.equal(moment(moment.utc())._isUTC, true, 'An implicit cloned utc moment should have _isUTC == true');\n});\n\ntest('parsing RFC 2822', function (assert) {\n    var testCases = {\n        'clean RFC2822 datetime with all options': 'Tue, 01 Nov 2016 01:23:45 UT',\n        'clean RFC2822 datetime without comma': 'Tue 01 Nov 2016 02:23:45 GMT',\n        'clean RFC2822 datetime without seconds': 'Tue, 01 Nov 2016 03:23 +0000',\n        'clean RFC2822 datetime without century': 'Tue, 01 Nov 16 04:23:45 Z',\n        'clean RFC2822 datetime without day': '01 Nov 2016 05:23:45 z',\n        'clean RFC2822 datetime with single-digit day-of-month': 'Tue, 1 Nov 2016 06:23:45 GMT',\n        'RFC2822 datetime with CFWSs': '(Init Comment) Tue,\\n 1 Nov              2016 (Split\\n Comment)  07:23:45 +0000 (GMT)'\n    };\n    var testCase;\n\n    for (testCase in testCases) {\n        var testResult = moment(testCases[testCase], moment.RFC_2822, true);\n        assert.ok(testResult.isValid(), testResult);\n        assert.ok(testResult.parsingFlags().rfc2822, testResult + ' - rfc2822 parsingFlag');\n    }\n});\n\ntest('non RFC 2822 strings', function (assert) {\n    var testCases = {\n        'RFC2822 datetime with all options but invalid day delimiter': 'Tue. 01 Nov 2016 01:23:45 GMT',\n        'RFC2822 datetime with mismatching Day (week v date)': 'Mon, 01 Nov 2016 01:23:45 GMT'\n    };\n    var testCase;\n\n    for (testCase in testCases) {\n        var testResult = moment(testCases[testCase], moment.RFC_2822, true);\n        assert.ok(!testResult.isValid(), testResult);\n        assert.ok(!testResult.parsingFlags().rfc2822, testResult + ' - rfc2822 parsingFlag');\n    }\n});\n\ntest('parsing iso', function (assert) {\n    var offset = moment([2011, 9, 8]).utcOffset(),\n    pad = function (input) {\n        if (input < 10) {\n            return '0' + input;\n        }\n        return '' + input;\n    },\n    hourOffset = (offset > 0 ? Math.floor(offset / 60) : Math.ceil(offset / 60)),\n    minOffset = offset - (hourOffset * 60),\n    tz = (offset >= 0) ?\n        '+' + pad(hourOffset) + ':' + pad(minOffset) :\n        '-' + pad(-hourOffset) + ':' + pad(-minOffset),\n    tz2 = tz.replace(':', ''),\n    tz3 = tz2.slice(0, 3),\n    //Tz3 removes minutes digit so will break the tests when parsed if they all use the same minutes digit\n    minutesForTz3 = pad((4 + minOffset) % 60),\n    minute = pad(4 + minOffset),\n\n    formats = [\n        ['2011-10-08',                    '2011-10-08T00:00:00.000' + tz],\n        ['2011-10-08T18',                 '2011-10-08T18:00:00.000' + tz],\n        ['2011-10-08T18:04',              '2011-10-08T18:04:00.000' + tz],\n        ['2011-10-08T18:04:20',           '2011-10-08T18:04:20.000' + tz],\n        ['2011-10-08T18:04' + tz,         '2011-10-08T18:04:00.000' + tz],\n        ['2011-10-08T18:04:20' + tz,      '2011-10-08T18:04:20.000' + tz],\n        ['2011-10-08T18:04' + tz2,        '2011-10-08T18:04:00.000' + tz],\n        ['2011-10-08T18:04:20' + tz2,     '2011-10-08T18:04:20.000' + tz],\n        ['2011-10-08T18:04' + tz3,        '2011-10-08T18:' + minutesForTz3 + ':00.000' + tz],\n        ['2011-10-08T18:04:20' + tz3,     '2011-10-08T18:' + minutesForTz3 + ':20.000' + tz],\n        ['2011-10-08T18:04:20.1' + tz2,   '2011-10-08T18:04:20.100' + tz],\n        ['2011-10-08T18:04:20.11' + tz2,  '2011-10-08T18:04:20.110' + tz],\n        ['2011-10-08T18:04:20.111' + tz2, '2011-10-08T18:04:20.111' + tz],\n        ['2011-10-08 18',                 '2011-10-08T18:00:00.000' + tz],\n        ['2011-10-08 18:04',              '2011-10-08T18:04:00.000' + tz],\n        ['2011-10-08 18:04:20',           '2011-10-08T18:04:20.000' + tz],\n        ['2011-10-08 18:04' + tz,         '2011-10-08T18:04:00.000' + tz],\n        ['2011-10-08 18:04:20' + tz,      '2011-10-08T18:04:20.000' + tz],\n        ['2011-10-08 18:04' + tz2,        '2011-10-08T18:04:00.000' + tz],\n        ['2011-10-08 18:04:20' + tz2,     '2011-10-08T18:04:20.000' + tz],\n        ['2011-10-08 18:04' + tz3,        '2011-10-08T18:' + minutesForTz3 + ':00.000' + tz],\n        ['2011-10-08 18:04:20' + tz3,     '2011-10-08T18:' + minutesForTz3 + ':20.000' + tz],\n        ['2011-10-08 18:04:20.1' + tz2,   '2011-10-08T18:04:20.100' + tz],\n        ['2011-10-08 18:04:20.11' + tz2,  '2011-10-08T18:04:20.110' + tz],\n        ['2011-10-08 18:04:20.111' + tz2, '2011-10-08T18:04:20.111' + tz],\n        ['2011-W40',                      '2011-10-03T00:00:00.000' + tz],\n        ['2011-W40-6',                    '2011-10-08T00:00:00.000' + tz],\n        ['2011-W40-6T18',                 '2011-10-08T18:00:00.000' + tz],\n        ['2011-W40-6T18:04',              '2011-10-08T18:04:00.000' + tz],\n        ['2011-W40-6T18:04:20',           '2011-10-08T18:04:20.000' + tz],\n        ['2011-W40-6T18:04' + tz,         '2011-10-08T18:04:00.000' + tz],\n        ['2011-W40-6T18:04:20' + tz,      '2011-10-08T18:04:20.000' + tz],\n        ['2011-W40-6T18:04' + tz2,        '2011-10-08T18:04:00.000' + tz],\n        ['2011-W40-6T18:04:20' + tz2,     '2011-10-08T18:04:20.000' + tz],\n        ['2011-W40-6T18:04' + tz3,        '2011-10-08T18:' + minutesForTz3 + ':00.000' + tz],\n        ['2011-W40-6T18:04:20' + tz3,     '2011-10-08T18:' + minutesForTz3 + ':20.000' + tz],\n        ['2011-W40-6T18:04:20.1' + tz2,   '2011-10-08T18:04:20.100' + tz],\n        ['2011-W40-6T18:04:20.11' + tz2,  '2011-10-08T18:04:20.110' + tz],\n        ['2011-W40-6T18:04:20.111' + tz2, '2011-10-08T18:04:20.111' + tz],\n        ['2011-W40-6 18',                 '2011-10-08T18:00:00.000' + tz],\n        ['2011-W40-6 18:04',              '2011-10-08T18:04:00.000' + tz],\n        ['2011-W40-6 18:04:20',           '2011-10-08T18:04:20.000' + tz],\n        ['2011-W40-6 18:04' + tz,         '2011-10-08T18:04:00.000' + tz],\n        ['2011-W40-6 18:04:20' + tz,      '2011-10-08T18:04:20.000' + tz],\n        ['2011-W40-6 18:04' + tz2,        '2011-10-08T18:04:00.000' + tz],\n        ['2011-W40-6 18:04:20' + tz2,     '2011-10-08T18:04:20.000' + tz],\n        ['2011-W40-6 18:04' + tz3,        '2011-10-08T18:' + minutesForTz3 + ':00.000' + tz],\n        ['2011-W40-6 18:04:20' + tz3,     '2011-10-08T18:' + minutesForTz3 + ':20.000' + tz],\n        ['2011-W40-6 18:04:20.1' + tz2,   '2011-10-08T18:04:20.100' + tz],\n        ['2011-W40-6 18:04:20.11' + tz2,  '2011-10-08T18:04:20.110' + tz],\n        ['2011-W40-6 18:04:20.111' + tz2, '2011-10-08T18:04:20.111' + tz],\n        ['2011-281',                      '2011-10-08T00:00:00.000' + tz],\n        ['2011-281T18',                   '2011-10-08T18:00:00.000' + tz],\n        ['2011-281T18:04',                '2011-10-08T18:04:00.000' + tz],\n        ['2011-281T18:04:20',             '2011-10-08T18:04:20.000' + tz],\n        ['2011-281T18:04' + tz,           '2011-10-08T18:04:00.000' + tz],\n        ['2011-281T18:04:20' + tz,        '2011-10-08T18:04:20.000' + tz],\n        ['2011-281T18:04' + tz2,          '2011-10-08T18:04:00.000' + tz],\n        ['2011-281T18:04:20' + tz2,       '2011-10-08T18:04:20.000' + tz],\n        ['2011-281T18:04' + tz3,          '2011-10-08T18:' + minutesForTz3 + ':00.000' + tz],\n        ['2011-281T18:04:20' + tz3,       '2011-10-08T18:' + minutesForTz3 + ':20.000' + tz],\n        ['2011-281T18:04:20.1' + tz2,     '2011-10-08T18:04:20.100' + tz],\n        ['2011-281T18:04:20.11' + tz2,    '2011-10-08T18:04:20.110' + tz],\n        ['2011-281T18:04:20.111' + tz2,   '2011-10-08T18:04:20.111' + tz],\n        ['2011-281 18',                   '2011-10-08T18:00:00.000' + tz],\n        ['2011-281 18:04',                '2011-10-08T18:04:00.000' + tz],\n        ['2011-281 18:04:20',             '2011-10-08T18:04:20.000' + tz],\n        ['2011-281 18:04' + tz,           '2011-10-08T18:04:00.000' + tz],\n        ['2011-281 18:04:20' + tz,        '2011-10-08T18:04:20.000' + tz],\n        ['2011-281 18:04' + tz2,          '2011-10-08T18:04:00.000' + tz],\n        ['2011-281 18:04:20' + tz2,       '2011-10-08T18:04:20.000' + tz],\n        ['2011-281 18:04' + tz3,          '2011-10-08T18:' + minutesForTz3 + ':00.000' + tz],\n        ['2011-281 18:04:20' + tz3,       '2011-10-08T18:' + minutesForTz3 + ':20.000' + tz],\n        ['2011-281 18:04:20.1' + tz2,     '2011-10-08T18:04:20.100' + tz],\n        ['2011-281 18:04:20.11' + tz2,    '2011-10-08T18:04:20.110' + tz],\n        ['2011-281 18:04:20.111' + tz2,   '2011-10-08T18:04:20.111' + tz],\n        ['20111008T18',                   '2011-10-08T18:00:00.000' + tz],\n        ['20111008T1804',                 '2011-10-08T18:04:00.000' + tz],\n        ['20111008T180420',               '2011-10-08T18:04:20.000' + tz],\n        ['20111008T1804' + tz,            '2011-10-08T18:04:00.000' + tz],\n        ['20111008T180420' + tz,          '2011-10-08T18:04:20.000' + tz],\n        ['20111008T1804' + tz2,           '2011-10-08T18:04:00.000' + tz],\n        ['20111008T180420' + tz2,         '2011-10-08T18:04:20.000' + tz],\n        ['20111008T1804' + tz3,           '2011-10-08T18:' + minutesForTz3 + ':00.000' + tz],\n        ['20111008T180420' + tz3,         '2011-10-08T18:' + minutesForTz3 + ':20.000' + tz],\n        ['20111008T180420,1' + tz2,       '2011-10-08T18:04:20.100' + tz],\n        ['20111008T180420,11' + tz2,      '2011-10-08T18:04:20.110' + tz],\n        ['20111008T180420,111' + tz2,     '2011-10-08T18:04:20.111' + tz],\n        ['20111008 18',                   '2011-10-08T18:00:00.000' + tz],\n        ['20111008 1804',                 '2011-10-08T18:04:00.000' + tz],\n        ['20111008 180420',               '2011-10-08T18:04:20.000' + tz],\n        ['20111008 1804' + tz,            '2011-10-08T18:04:00.000' + tz],\n        ['20111008 180420' + tz,          '2011-10-08T18:04:20.000' + tz],\n        ['20111008 1804' + tz2,           '2011-10-08T18:04:00.000' + tz],\n        ['20111008 180420' + tz2,         '2011-10-08T18:04:20.000' + tz],\n        ['20111008 1804' + tz3,           '2011-10-08T18:' + minutesForTz3 + ':00.000' + tz],\n        ['20111008 180420' + tz3,         '2011-10-08T18:' + minutesForTz3 + ':20.000' + tz],\n        ['20111008 180420,1' + tz2,       '2011-10-08T18:04:20.100' + tz],\n        ['20111008 180420,11' + tz2,      '2011-10-08T18:04:20.110' + tz],\n        ['20111008 180420,111' + tz2,     '2011-10-08T18:04:20.111' + tz],\n        ['2011W40',                       '2011-10-03T00:00:00.000' + tz],\n        ['2011W406',                      '2011-10-08T00:00:00.000' + tz],\n        ['2011W406T18',                   '2011-10-08T18:00:00.000' + tz],\n        ['2011W406T1804',                 '2011-10-08T18:04:00.000' + tz],\n        ['2011W406T180420',               '2011-10-08T18:04:20.000' + tz],\n        ['2011W406 1804' + tz2,           '2011-10-08T18:04:00.000' + tz],\n        ['2011W406T1804' + tz,            '2011-10-08T18:04:00.000' + tz],\n        ['2011W406T180420' + tz,          '2011-10-08T18:04:20.000' + tz],\n        ['2011W406T1804' + tz2,           '2011-10-08T18:04:00.000' + tz],\n        ['2011W406T180420' + tz2,         '2011-10-08T18:04:20.000' + tz],\n        ['2011W406T1804' + tz3,           '2011-10-08T18:' + minutesForTz3 + ':00.000' + tz],\n        ['2011W406T180420' + tz3,         '2011-10-08T18:' + minutesForTz3 + ':20.000' + tz],\n        ['2011W406T180420,1' + tz2,       '2011-10-08T18:04:20.100' + tz],\n        ['2011W406T180420,11' + tz2,      '2011-10-08T18:04:20.110' + tz],\n        ['2011W406T180420,111' + tz2,     '2011-10-08T18:04:20.111' + tz],\n        ['2011W406 18',                   '2011-10-08T18:00:00.000' + tz],\n        ['2011W406 1804',                 '2011-10-08T18:04:00.000' + tz],\n        ['2011W406 180420',               '2011-10-08T18:04:20.000' + tz],\n        ['2011W406 1804' + tz,            '2011-10-08T18:04:00.000' + tz],\n        ['2011W406 180420' + tz,          '2011-10-08T18:04:20.000' + tz],\n        ['2011W406 180420' + tz2,         '2011-10-08T18:04:20.000' + tz],\n        ['2011W406 1804' + tz3,           '2011-10-08T18:' + minutesForTz3 + ':00.000' + tz],\n        ['2011W406 180420' + tz3,         '2011-10-08T18:' + minutesForTz3 + ':20.000' + tz],\n        ['2011W406 180420,1' + tz2,       '2011-10-08T18:04:20.100' + tz],\n        ['2011W406 180420,11' + tz2,      '2011-10-08T18:04:20.110' + tz],\n        ['2011W406 180420,111' + tz2,     '2011-10-08T18:04:20.111' + tz],\n        ['2011281',                       '2011-10-08T00:00:00.000' + tz],\n        ['2011281T18',                    '2011-10-08T18:00:00.000' + tz],\n        ['2011281T1804',                  '2011-10-08T18:04:00.000' + tz],\n        ['2011281T180420',                '2011-10-08T18:04:20.000' + tz],\n        ['2011281T1804' + tz,             '2011-10-08T18:04:00.000' + tz],\n        ['2011281T180420' + tz,           '2011-10-08T18:04:20.000' + tz],\n        ['2011281T1804' + tz2,            '2011-10-08T18:04:00.000' + tz],\n        ['2011281T180420' + tz2,          '2011-10-08T18:04:20.000' + tz],\n        ['2011281T1804' + tz3,            '2011-10-08T18:' + minutesForTz3 + ':00.000' + tz],\n        ['2011281T180420' + tz3,          '2011-10-08T18:' + minutesForTz3 + ':20.000' + tz],\n        ['2011281T180420,1' + tz2,        '2011-10-08T18:04:20.100' + tz],\n        ['2011281T180420,11' + tz2,       '2011-10-08T18:04:20.110' + tz],\n        ['2011281T180420,111' + tz2,      '2011-10-08T18:04:20.111' + tz],\n        ['2011281 18',                    '2011-10-08T18:00:00.000' + tz],\n        ['2011281 1804',                  '2011-10-08T18:04:00.000' + tz],\n        ['2011281 180420',                '2011-10-08T18:04:20.000' + tz],\n        ['2011281 1804' + tz,             '2011-10-08T18:04:00.000' + tz],\n        ['2011281 180420' + tz,           '2011-10-08T18:04:20.000' + tz],\n        ['2011281 1804' + tz2,            '2011-10-08T18:04:00.000' + tz],\n        ['2011281 180420' + tz2,          '2011-10-08T18:04:20.000' + tz],\n        ['2011281 1804' + tz3,            '2011-10-08T18:' + minutesForTz3 + ':00.000' + tz],\n        ['2011281 180420' + tz3,          '2011-10-08T18:' + minutesForTz3 + ':20.000' + tz],\n        ['2011281 180420,1' + tz2,        '2011-10-08T18:04:20.100' + tz],\n        ['2011281 180420,11' + tz2,       '2011-10-08T18:04:20.110' + tz],\n        ['2011281 180420,111' + tz2,      '2011-10-08T18:04:20.111' + tz]\n    ], i;\n    for (i = 0; i < formats.length; i++) {\n        assert.equal(moment(formats[i][0]).format('YYYY-MM-DDTHH:mm:ss.SSSZ'),\n                formats[i][1], 'moment should be able to parse ISO ' + formats[i][0]);\n        assert.equal(moment(formats[i][0], moment.ISO_8601).format('YYYY-MM-DDTHH:mm:ss.SSSZ'),\n                formats[i][1], 'moment should be able to parse specified ISO ' + formats[i][0]);\n        assert.equal(moment(formats[i][0], moment.ISO_8601, true).format('YYYY-MM-DDTHH:mm:ss.SSSZ'),\n                formats[i][1], 'moment should be able to parse specified strict ISO ' + formats[i][0]);\n    }\n});\n\ntest('non iso 8601 strings', function (assert) {\n    assert.ok(!moment('2015-10T10:15', moment.ISO_8601, true).isValid(), 'incomplete date with time');\n    assert.ok(!moment('2015-W10T10:15', moment.ISO_8601, true).isValid(), 'incomplete week date with time');\n    assert.ok(!moment('201510', moment.ISO_8601, true).isValid(), 'basic YYYYMM is not allowed');\n    assert.ok(!moment('2015W10T1015', moment.ISO_8601, true).isValid(), 'incomplete week date with time (basic)');\n    assert.ok(!moment('2015-10-08T1015', moment.ISO_8601, true).isValid(), 'mixing extended and basic format');\n    assert.ok(!moment('20151008T10:15', moment.ISO_8601, true).isValid(), 'mixing basic and extended format');\n    assert.ok(!moment('2015-10-1', moment.ISO_8601, true).isValid(), 'missing zero padding for day');\n});\n\ntest('parsing iso week year/week/weekday', function (assert) {\n    assert.equal(moment.utc('2007-W01').format(), '2007-01-01T00:00:00Z', '2008 week 1 (1st Jan Mon)');\n    assert.equal(moment.utc('2008-W01').format(), '2007-12-31T00:00:00Z', '2008 week 1 (1st Jan Tue)');\n    assert.equal(moment.utc('2003-W01').format(), '2002-12-30T00:00:00Z', '2008 week 1 (1st Jan Wed)');\n    assert.equal(moment.utc('2009-W01').format(), '2008-12-29T00:00:00Z', '2009 week 1 (1st Jan Thu)');\n    assert.equal(moment.utc('2010-W01').format(), '2010-01-04T00:00:00Z', '2010 week 1 (1st Jan Fri)');\n    assert.equal(moment.utc('2011-W01').format(), '2011-01-03T00:00:00Z', '2011 week 1 (1st Jan Sat)');\n    assert.equal(moment.utc('2012-W01').format(), '2012-01-02T00:00:00Z', '2012 week 1 (1st Jan Sun)');\n});\n\ntest('parsing week year/week/weekday (dow 1, doy 4)', function (assert) {\n    moment.locale('dow:1,doy:4', {week: {dow: 1, doy: 4}});\n\n    assert.equal(moment.utc('2007-01', 'gggg-ww').format(), '2007-01-01T00:00:00Z', '2007 week 1 (1st Jan Mon)');\n    assert.equal(moment.utc('2008-01', 'gggg-ww').format(), '2007-12-31T00:00:00Z', '2008 week 1 (1st Jan Tue)');\n    assert.equal(moment.utc('2003-01', 'gggg-ww').format(), '2002-12-30T00:00:00Z', '2003 week 1 (1st Jan Wed)');\n    assert.equal(moment.utc('2009-01', 'gggg-ww').format(), '2008-12-29T00:00:00Z', '2009 week 1 (1st Jan Thu)');\n    assert.equal(moment.utc('2010-01', 'gggg-ww').format(), '2010-01-04T00:00:00Z', '2010 week 1 (1st Jan Fri)');\n    assert.equal(moment.utc('2011-01', 'gggg-ww').format(), '2011-01-03T00:00:00Z', '2011 week 1 (1st Jan Sat)');\n    assert.equal(moment.utc('2012-01', 'gggg-ww').format(), '2012-01-02T00:00:00Z', '2012 week 1 (1st Jan Sun)');\n\n    moment.defineLocale('dow:1,doy:4', null);\n});\n\ntest('parsing week year/week/weekday (dow 1, doy 7)', function (assert) {\n    moment.locale('dow:1,doy:7', {week: {dow: 1, doy: 7}});\n\n    assert.equal(moment.utc('2007-01', 'gggg-ww').format(), '2007-01-01T00:00:00Z', '2007 week 1 (1st Jan Mon)');\n    assert.equal(moment.utc('2008-01', 'gggg-ww').format(), '2007-12-31T00:00:00Z', '2008 week 1 (1st Jan Tue)');\n    assert.equal(moment.utc('2003-01', 'gggg-ww').format(), '2002-12-30T00:00:00Z', '2003 week 1 (1st Jan Wed)');\n    assert.equal(moment.utc('2009-01', 'gggg-ww').format(), '2008-12-29T00:00:00Z', '2009 week 1 (1st Jan Thu)');\n    assert.equal(moment.utc('2010-01', 'gggg-ww').format(), '2009-12-28T00:00:00Z', '2010 week 1 (1st Jan Fri)');\n    assert.equal(moment.utc('2011-01', 'gggg-ww').format(), '2010-12-27T00:00:00Z', '2011 week 1 (1st Jan Sat)');\n    assert.equal(moment.utc('2012-01', 'gggg-ww').format(), '2011-12-26T00:00:00Z', '2012 week 1 (1st Jan Sun)');\n    moment.defineLocale('dow:1,doy:7', null);\n});\n\ntest('parsing week year/week/weekday (dow 0, doy 6)', function (assert) {\n    moment.locale('dow:0,doy:6', {week: {dow: 0, doy: 6}});\n\n    assert.equal(moment.utc('2007-01', 'gggg-ww').format(), '2006-12-31T00:00:00Z', '2007 week 1 (1st Jan Mon)');\n    assert.equal(moment.utc('2008-01', 'gggg-ww').format(), '2007-12-30T00:00:00Z', '2008 week 1 (1st Jan Tue)');\n    assert.equal(moment.utc('2003-01', 'gggg-ww').format(), '2002-12-29T00:00:00Z', '2003 week 1 (1st Jan Wed)');\n    assert.equal(moment.utc('2009-01', 'gggg-ww').format(), '2008-12-28T00:00:00Z', '2009 week 1 (1st Jan Thu)');\n    assert.equal(moment.utc('2010-01', 'gggg-ww').format(), '2009-12-27T00:00:00Z', '2010 week 1 (1st Jan Fri)');\n    assert.equal(moment.utc('2011-01', 'gggg-ww').format(), '2010-12-26T00:00:00Z', '2011 week 1 (1st Jan Sat)');\n    assert.equal(moment.utc('2012-01', 'gggg-ww').format(), '2012-01-01T00:00:00Z', '2012 week 1 (1st Jan Sun)');\n    moment.defineLocale('dow:0,doy:6', null);\n});\n\ntest('parsing week year/week/weekday (dow 6, doy 12)', function (assert) {\n    moment.locale('dow:6,doy:12', {week: {dow: 6, doy: 12}});\n\n    assert.equal(moment.utc('2007-01', 'gggg-ww').format(), '2006-12-30T00:00:00Z', '2007 week 1 (1st Jan Mon)');\n    assert.equal(moment.utc('2008-01', 'gggg-ww').format(), '2007-12-29T00:00:00Z', '2008 week 1 (1st Jan Tue)');\n    assert.equal(moment.utc('2003-01', 'gggg-ww').format(), '2002-12-28T00:00:00Z', '2003 week 1 (1st Jan Wed)');\n    assert.equal(moment.utc('2009-01', 'gggg-ww').format(), '2008-12-27T00:00:00Z', '2009 week 1 (1st Jan Thu)');\n    assert.equal(moment.utc('2010-01', 'gggg-ww').format(), '2009-12-26T00:00:00Z', '2010 week 1 (1st Jan Fri)');\n    assert.equal(moment.utc('2011-01', 'gggg-ww').format(), '2011-01-01T00:00:00Z', '2011 week 1 (1st Jan Sat)');\n    assert.equal(moment.utc('2012-01', 'gggg-ww').format(), '2011-12-31T00:00:00Z', '2012 week 1 (1st Jan Sun)');\n    moment.defineLocale('dow:6,doy:12', null);\n});\n\ntest('parsing ISO with Z', function (assert) {\n    var i, mom, formats = [\n        ['2011-10-08T18:04',             '2011-10-08T18:04:00.000'],\n        ['2011-10-08T18:04:20',          '2011-10-08T18:04:20.000'],\n        ['2011-10-08T18:04:20.1',        '2011-10-08T18:04:20.100'],\n        ['2011-10-08T18:04:20.11',       '2011-10-08T18:04:20.110'],\n        ['2011-10-08T18:04:20.111',      '2011-10-08T18:04:20.111'],\n        ['2011-W40-6T18',                '2011-10-08T18:00:00.000'],\n        ['2011-W40-6T18:04',             '2011-10-08T18:04:00.000'],\n        ['2011-W40-6T18:04:20',          '2011-10-08T18:04:20.000'],\n        ['2011-W40-6T18:04:20.1',        '2011-10-08T18:04:20.100'],\n        ['2011-W40-6T18:04:20.11',       '2011-10-08T18:04:20.110'],\n        ['2011-W40-6T18:04:20.111',      '2011-10-08T18:04:20.111'],\n        ['2011-281T18',                  '2011-10-08T18:00:00.000'],\n        ['2011-281T18:04',               '2011-10-08T18:04:00.000'],\n        ['2011-281T18:04:20',            '2011-10-08T18:04:20.000'],\n        ['2011-281T18:04:20',            '2011-10-08T18:04:20.000'],\n        ['2011-281T18:04:20.1',          '2011-10-08T18:04:20.100'],\n        ['2011-281T18:04:20.11',         '2011-10-08T18:04:20.110'],\n        ['2011-281T18:04:20.111',        '2011-10-08T18:04:20.111']\n    ];\n\n    for (i = 0; i < formats.length; i++) {\n        mom = moment(formats[i][0] + 'Z').utc();\n        assert.equal(mom.format('YYYY-MM-DDTHH:mm:ss.SSS'), formats[i][1], 'moment should be able to parse ISO in UTC ' + formats[i][0] + 'Z');\n\n        mom = moment(formats[i][0] + ' Z').utc();\n        assert.equal(mom.format('YYYY-MM-DDTHH:mm:ss.SSS'), formats[i][1], 'moment should be able to parse ISO in UTC ' + formats[i][0] + ' Z');\n    }\n});\n\ntest('parsing iso with T', function (assert) {\n    assert.equal(moment('2011-10-08T18')._f, 'YYYY-MM-DDTHH', 'should include \\'T\\' in the format');\n    assert.equal(moment('2011-10-08T18:20')._f, 'YYYY-MM-DDTHH:mm', 'should include \\'T\\' in the format');\n    assert.equal(moment('2011-10-08T18:20:13')._f, 'YYYY-MM-DDTHH:mm:ss', 'should include \\'T\\' in the format');\n    assert.equal(moment('2011-10-08T18:20:13.321')._f, 'YYYY-MM-DDTHH:mm:ss.SSSS', 'should include \\'T\\' in the format');\n\n    assert.equal(moment('2011-10-08 18')._f, 'YYYY-MM-DD HH', 'should not include \\'T\\' in the format');\n    assert.equal(moment('2011-10-08 18:20')._f, 'YYYY-MM-DD HH:mm', 'should not include \\'T\\' in the format');\n    assert.equal(moment('2011-10-08 18:20:13')._f, 'YYYY-MM-DD HH:mm:ss', 'should not include \\'T\\' in the format');\n    assert.equal(moment('2011-10-08 18:20:13.321')._f, 'YYYY-MM-DD HH:mm:ss.SSSS', 'should not include \\'T\\' in the format');\n});\n\ntest('parsing iso Z timezone', function (assert) {\n    var i,\n    formats = [\n        ['2011-10-08T18:04Z',             '2011-10-08T18:04:00.000+00:00'],\n        ['2011-10-08T18:04:20Z',          '2011-10-08T18:04:20.000+00:00'],\n        ['2011-10-08T18:04:20.111Z',      '2011-10-08T18:04:20.111+00:00']\n    ];\n    for (i = 0; i < formats.length; i++) {\n        assert.equal(moment.utc(formats[i][0]).format('YYYY-MM-DDTHH:mm:ss.SSSZ'), formats[i][1], 'moment should be able to parse ISO ' + formats[i][0]);\n    }\n});\n\ntest('parsing iso Z timezone into local', function (assert) {\n    var m = moment('2011-10-08T18:04:20.111Z');\n\n    assert.equal(m.utc().format('YYYY-MM-DDTHH:mm:ss.SSS'), '2011-10-08T18:04:20.111', 'moment should be able to parse ISO 2011-10-08T18:04:20.111Z');\n});\n\ntest('parsing iso with more subsecond precision digits', function (assert) {\n    assert.equal(moment.utc('2013-07-31T22:00:00.0000000Z').format(), '2013-07-31T22:00:00Z', 'more than 3 subsecond digits');\n});\n\ntest('null or empty', function (assert) {\n    assert.equal(moment('').isValid(), false, 'moment(\\'\\') is not valid');\n    assert.equal(moment(null).isValid(), false, 'moment(null) is not valid');\n    assert.equal(moment(null, 'YYYY-MM-DD').isValid(), false, 'moment(\\'\\', \\'format\\') is not valid');\n    assert.equal(moment('', 'YYYY-MM-DD').isValid(), false, 'moment(\\'\\', \\'format\\') is not valid');\n    assert.equal(moment.utc('').isValid(), false, 'moment.utc(\\'\\') is not valid');\n    assert.equal(moment.utc(null).isValid(), false, 'moment.utc(null) is not valid');\n    assert.equal(moment.utc(null, 'YYYY-MM-DD').isValid(), false, 'moment.utc(null) is not valid');\n    assert.equal(moment.utc('', 'YYYY-MM-DD').isValid(), false, 'moment.utc(\\'\\', \\'YYYY-MM-DD\\') is not valid');\n});\n\ntest('first century', function (assert) {\n    assert.equal(moment([0, 0, 1]).format('YYYY-MM-DD'), '0000-01-01', 'Year AD 0');\n    assert.equal(moment([99, 0, 1]).format('YYYY-MM-DD'), '0099-01-01', 'Year AD 99');\n    assert.equal(moment([999, 0, 1]).format('YYYY-MM-DD'), '0999-01-01', 'Year AD 999');\n    assert.equal(moment('0 1 1', 'YYYY MM DD').format('YYYY-MM-DD'), '0000-01-01', 'Year AD 0');\n    assert.equal(moment('999 1 1', 'YYYY MM DD').format('YYYY-MM-DD'), '0999-01-01', 'Year AD 999');\n    assert.equal(moment('0 1 1', 'YYYYY MM DD').format('YYYYY-MM-DD'), '00000-01-01', 'Year AD 0');\n    assert.equal(moment('99 1 1', 'YYYYY MM DD').format('YYYYY-MM-DD'), '00099-01-01', 'Year AD 99');\n    assert.equal(moment('999 1 1', 'YYYYY MM DD').format('YYYYY-MM-DD'), '00999-01-01', 'Year AD 999');\n});\n\ntest('six digit years', function (assert) {\n    assert.equal(moment([-270000, 0, 1]).format('YYYYY-MM-DD'), '-270000-01-01', 'format BC 270,001');\n    assert.equal(moment([270000, 0, 1]).format('YYYYY-MM-DD'), '270000-01-01', 'format AD 270,000');\n    assert.equal(moment('-270000-01-01', 'YYYYY-MM-DD').toDate().getFullYear(), -270000, 'parse BC 270,001');\n    assert.equal(moment('270000-01-01',  'YYYYY-MM-DD').toDate().getFullYear(), 270000, 'parse AD 270,000');\n    assert.equal(moment('+270000-01-01', 'YYYYY-MM-DD').toDate().getFullYear(), 270000, 'parse AD +270,000');\n    assert.equal(moment.utc('-270000-01-01', 'YYYYY-MM-DD').toDate().getUTCFullYear(), -270000, 'parse utc BC 270,001');\n    assert.equal(moment.utc('270000-01-01',  'YYYYY-MM-DD').toDate().getUTCFullYear(), 270000, 'parse utc AD 270,000');\n    assert.equal(moment.utc('+270000-01-01', 'YYYYY-MM-DD').toDate().getUTCFullYear(), 270000, 'parse utc AD +270,000');\n});\n\ntest('negative four digit years', function (assert) {\n    assert.equal(moment('-1000-01-01', 'YYYYY-MM-DD').toDate().getFullYear(), -1000, 'parse BC 1,001');\n    assert.equal(moment.utc('-1000-01-01', 'YYYYY-MM-DD').toDate().getUTCFullYear(), -1000, 'parse utc BC 1,001');\n});\n\ntest('strict parsing', function (assert) {\n    assert.equal(moment('2014-', 'YYYY-Q', true).isValid(), false, 'fail missing quarter');\n\n    assert.equal(moment('2012-05', 'YYYY-MM', true).format('YYYY-MM'), '2012-05', 'parse correct string');\n    assert.equal(moment(' 2012-05', 'YYYY-MM', true).isValid(), false, 'fail on extra whitespace');\n    assert.equal(moment('foo 2012-05', '[foo] YYYY-MM', true).format('YYYY-MM'), '2012-05', 'handle fixed text');\n    assert.equal(moment('2012 05', 'YYYY-MM', true).isValid(), false, 'fail on different separator');\n    assert.equal(moment('2012 05', 'YYYY MM DD', true).isValid(), false, 'fail on too many tokens');\n\n    assert.equal(moment('05 30 2010', ['DD MM YYYY', 'MM DD YYYY'], true).format('MM DD YYYY'), '05 30 2010', 'array with bad date');\n    assert.equal(moment('05 30 2010', ['', 'MM DD YYYY'], true).format('MM DD YYYY'), '05 30 2010', 'array with invalid format');\n    assert.equal(moment('05 30 2010', [' DD MM YYYY', 'MM DD YYYY'], true).format('MM DD YYYY'), '05 30 2010', 'array with non-matching format');\n\n    assert.equal(moment('2010.*...', 'YYYY.*', true).isValid(), false, 'invalid format with regex chars');\n    assert.equal(moment('2010.*', 'YYYY.*', true).year(), 2010, 'valid format with regex chars');\n    assert.equal(moment('.*2010.*', '.*YYYY.*', true).year(), 2010, 'valid format with regex chars on both sides');\n\n    //strict tokens\n    assert.equal(moment('-5-05-25', 'YYYY-MM-DD', true).isValid(), false, 'invalid negative year');\n    assert.equal(moment('2-05-25', 'YYYY-MM-DD', true).isValid(), false, 'invalid one-digit year');\n    assert.equal(moment('20-05-25', 'YYYY-MM-DD', true).isValid(), false, 'invalid two-digit year');\n    assert.equal(moment('201-05-25', 'YYYY-MM-DD', true).isValid(), false, 'invalid three-digit year');\n    assert.equal(moment('2010-05-25', 'YYYY-MM-DD', true).isValid(), true, 'valid four-digit year');\n    assert.equal(moment('22010-05-25', 'YYYY-MM-DD', true).isValid(), false, 'invalid five-digit year');\n\n    assert.equal(moment('12-05-25', 'YY-MM-DD', true).isValid(), true, 'valid two-digit year');\n    assert.equal(moment('2012-05-25', 'YY-MM-DD', true).isValid(), false, 'invalid four-digit year');\n\n    assert.equal(moment('-5-05-25', 'Y-MM-DD', true).isValid(), true, 'valid negative year');\n    assert.equal(moment('2-05-25', 'Y-MM-DD', true).isValid(), true, 'valid one-digit year');\n    assert.equal(moment('20-05-25', 'Y-MM-DD', true).isValid(), true, 'valid two-digit year');\n    assert.equal(moment('201-05-25', 'Y-MM-DD', true).isValid(), true, 'valid three-digit year');\n\n    assert.equal(moment('2012-5-25', 'YYYY-M-DD', true).isValid(), true, 'valid one-digit month');\n    assert.equal(moment('2012-5-25', 'YYYY-MM-DD', true).isValid(), false, 'invalid one-digit month');\n    assert.equal(moment('2012-05-25', 'YYYY-M-DD', true).isValid(), true, 'valid one-digit month');\n    assert.equal(moment('2012-05-25', 'YYYY-MM-DD', true).isValid(), true, 'valid one-digit month');\n\n    assert.equal(moment('2012-05-2', 'YYYY-MM-D', true).isValid(), true, 'valid one-digit day');\n    assert.equal(moment('2012-05-2', 'YYYY-MM-DD', true).isValid(), false, 'invalid one-digit day');\n    assert.equal(moment('2012-05-02', 'YYYY-MM-D', true).isValid(), true, 'valid two-digit day');\n    assert.equal(moment('2012-05-02', 'YYYY-MM-DD', true).isValid(), true, 'valid two-digit day');\n\n    assert.equal(moment('+002012-05-25', 'YYYYY-MM-DD', true).isValid(), true, 'valid six-digit year');\n    assert.equal(moment('+2012-05-25', 'YYYYY-MM-DD', true).isValid(), false, 'invalid four-digit year');\n\n    //thse are kinda pointless, but they should work as expected\n    assert.equal(moment('1', 'S', true).isValid(), true, 'valid one-digit milisecond');\n    assert.equal(moment('12', 'S', true).isValid(), false, 'invalid two-digit milisecond');\n    assert.equal(moment('123', 'S', true).isValid(), false, 'invalid three-digit milisecond');\n\n    assert.equal(moment('1', 'SS', true).isValid(), false, 'invalid one-digit milisecond');\n    assert.equal(moment('12', 'SS', true).isValid(), true, 'valid two-digit milisecond');\n    assert.equal(moment('123', 'SS', true).isValid(), false, 'invalid three-digit milisecond');\n\n    assert.equal(moment('1', 'SSS', true).isValid(), false, 'invalid one-digit milisecond');\n    assert.equal(moment('12', 'SSS', true).isValid(), false, 'invalid two-digit milisecond');\n    assert.equal(moment('123', 'SSS', true).isValid(), true, 'valid three-digit milisecond');\n\n    // strict parsing respects month length\n    assert.ok(moment('1 January 2000', 'D MMMM YYYY', true).isValid(), 'capital long-month + MMMM');\n    assert.ok(!moment('1 January 2000', 'D MMM YYYY', true).isValid(), 'capital long-month + MMM');\n    assert.ok(!moment('1 Jan 2000', 'D MMMM YYYY', true).isValid(), 'capital short-month + MMMM');\n    assert.ok(moment('1 Jan 2000', 'D MMM YYYY', true).isValid(), 'capital short-month + MMM');\n    assert.ok(moment('1 january 2000', 'D MMMM YYYY', true).isValid(), 'lower long-month + MMMM');\n    assert.ok(!moment('1 january 2000', 'D MMM YYYY', true).isValid(), 'lower long-month + MMM');\n    assert.ok(!moment('1 jan 2000', 'D MMMM YYYY', true).isValid(), 'lower short-month + MMMM');\n    assert.ok(moment('1 jan 2000', 'D MMM YYYY', true).isValid(), 'lower short-month + MMM');\n});\n\ntest('parsing into a locale', function (assert) {\n    moment.defineLocale('parselocale', {\n        months : 'one_two_three_four_five_six_seven_eight_nine_ten_eleven_twelve'.split('_'),\n        monthsShort : 'one_two_three_four_five_six_seven_eight_nine_ten_eleven_twelve'.split('_')\n    });\n\n    moment.locale('en');\n\n    assert.equal(moment('2012 seven', 'YYYY MMM', 'parselocale').month(), 6, 'should be able to parse in a specific locale');\n\n    moment.locale('parselocale');\n\n    assert.equal(moment('2012 july', 'YYYY MMM', 'en').month(), 6, 'should be able to parse in a specific locale');\n\n    moment.defineLocale('parselocale', null);\n});\n\nfunction getVerifier(test$$1) {\n    return function (input, format, expected, description, asymetrical) {\n        var m = moment(input, format);\n        test$$1.equal(m.format('YYYY MM DD'), expected, 'compare: ' + description);\n\n        //test round trip\n        if (!asymetrical) {\n            test$$1.equal(m.format(format), input, 'round trip: ' + description);\n        }\n    };\n}\n\ntest('parsing week and weekday information', function (assert) {\n    var ver = getVerifier(assert);\n    var currentWeekOfYear = moment().weeks();\n    var expectedDate2012 = moment([2012, 0, 1])\n      .day(0)\n      .add((currentWeekOfYear - 1), 'weeks')\n      .format('YYYY MM DD');\n    var expectedDate1999 = moment([1999, 0, 1])\n      .day(0)\n      .add((currentWeekOfYear - 1), 'weeks')\n      .format('YYYY MM DD');\n\n    // year\n    ver('12', 'gg', expectedDate2012, 'week-year two digits');\n    ver('2012', 'gggg', expectedDate2012, 'week-year four digits');\n    ver('99', 'gg', expectedDate1999, 'week-year two digits previous year');\n    ver('1999', 'gggg', expectedDate1999, 'week-year four digits previous year');\n\n    ver('99', 'GG', '1999 01 04', 'iso week-year two digits');\n    ver('1999', 'GGGG', '1999 01 04', 'iso week-year four digits');\n\n    ver('13', 'GG', '2012 12 31', 'iso week-year two digits previous year');\n    ver('2013', 'GGGG', '2012 12 31', 'iso week-year four digits previous year');\n\n    // year + week\n    ver('1999 37', 'gggg w', '1999 09 05', 'week');\n    ver('1999 37', 'gggg ww', '1999 09 05', 'week double');\n    ver('1999 37', 'GGGG W', '1999 09 13', 'iso week');\n    ver('1999 37', 'GGGG WW', '1999 09 13', 'iso week double');\n\n    ver('1999 37 4', 'GGGG WW E', '1999 09 16', 'iso day');\n    ver('1999 37 04', 'GGGG WW E', '1999 09 16', 'iso day wide', true);\n\n    ver('1999 37 4', 'gggg ww e', '1999 09 09', 'day');\n    ver('1999 37 04', 'gggg ww e', '1999 09 09', 'day wide', true);\n\n    // year + week + day\n    ver('1999 37 4', 'gggg ww d', '1999 09 09', 'd');\n    ver('1999 37 Th', 'gggg ww dd', '1999 09 09', 'dd');\n    ver('1999 37 Thu', 'gggg ww ddd', '1999 09 09', 'ddd');\n    ver('1999 37 Thursday', 'gggg ww dddd', '1999 09 09', 'dddd');\n\n    // lower-order only\n    assert.equal(moment('22', 'ww').week(), 22, 'week sets the week by itself');\n    assert.equal(moment('22', 'ww').weekYear(), moment().weekYear(), 'week keeps this year');\n    assert.equal(moment('2012 22', 'YYYY ww').weekYear(), 2012, 'week keeps parsed year');\n\n    assert.equal(moment('22', 'WW').isoWeek(), 22, 'iso week sets the week by itself');\n    assert.equal(moment('2012 22', 'YYYY WW').weekYear(), 2012, 'iso week keeps parsed year');\n    assert.equal(moment('22', 'WW').isoWeekYear(), moment().isoWeekYear(), 'iso week keeps this year');\n\n    // order\n    ver('6 2013 2', 'e gggg w', '2013 01 12', 'order doesn\\'t matter');\n    ver('6 2013 2', 'E GGGG W', '2013 01 12', 'iso order doesn\\'t matter');\n\n    //can parse other stuff too\n    assert.equal(moment('1999-W37-4 3:30', 'GGGG-[W]WW-E HH:mm').format('YYYY MM DD HH:mm'), '1999 09 16 03:30', 'parsing weeks and hours');\n\n    // In safari, all years before 1300 are shifted back with one day.\n    // http://stackoverflow.com/questions/20768975/safari-subtracts-1-day-from-dates-before-1300\n    if (new Date('1300-01-01').getUTCFullYear() === 1300) {\n        // Years less than 100\n        ver('0098-06', 'GGGG-WW', '0098 02 03', 'small years work', true);\n    }\n});\n\ntest('parsing localized weekdays', function (assert) {\n    var ver = getVerifier(assert);\n    try {\n        moment.locale('dow:1,doy:4', {\n            weekdays : 'dimanche_lundi_mardi_mercredi_jeudi_vendredi_samedi'.split('_'),\n            weekdaysShort : 'dim._lun._mar._mer._jeu._ven._sam.'.split('_'),\n            weekdaysMin : 'Di_Lu_Ma_Me_Je_Ve_Sa'.split('_'),\n            week: {dow: 1, doy: 4}\n        });\n        ver('1999 37 4', 'GGGG WW E', '1999 09 16', 'iso ignores locale');\n        ver('1999 37 7', 'GGGG WW E', '1999 09 19', 'iso ignores locale');\n\n        ver('1999 37 0', 'gggg ww e', '1999 09 13', 'localized e uses local doy and dow: 0 = monday');\n        ver('1999 37 4', 'gggg ww e', '1999 09 17', 'localized e uses local doy and dow: 4 = friday');\n\n        ver('1999 37 1', 'gggg ww d', '1999 09 13', 'localized d uses 0-indexed days: 1 = monday');\n        ver('1999 37 Lu', 'gggg ww dd', '1999 09 13', 'localized d uses 0-indexed days: Mo');\n        ver('1999 37 lun.', 'gggg ww ddd', '1999 09 13', 'localized d uses 0-indexed days: Mon');\n        ver('1999 37 lundi', 'gggg ww dddd', '1999 09 13', 'localized d uses 0-indexed days: Monday');\n        ver('1999 37 4', 'gggg ww d', '1999 09 16', 'localized d uses 0-indexed days: 4');\n\n        //sunday goes at the end of the week\n        ver('1999 37 0', 'gggg ww d', '1999 09 19', 'localized d uses 0-indexed days: 0 = sund');\n        ver('1999 37 Di', 'gggg ww dd', '1999 09 19', 'localized d uses 0-indexed days: 0 = sund');\n    }\n    finally {\n        moment.defineLocale('dow:1,doy:4', null);\n        moment.locale('en');\n    }\n});\n\ntest('parsing with customized two-digit year', function (assert) {\n    var original = moment.parseTwoDigitYear;\n    try {\n        assert.equal(moment('68', 'YY').year(), 2068);\n        assert.equal(moment('69', 'YY').year(), 1969);\n        moment.parseTwoDigitYear = function (input) {\n            return +input + (+input > 30 ? 1900 : 2000);\n        };\n        assert.equal(moment('68', 'YY').year(), 1968);\n        assert.equal(moment('67', 'YY').year(), 1967);\n        assert.equal(moment('31', 'YY').year(), 1931);\n        assert.equal(moment('30', 'YY').year(), 2030);\n    }\n    finally {\n        moment.parseTwoDigitYear = original;\n    }\n});\n\ntest('array with strings', function (assert) {\n    assert.equal(moment(['2014', '7', '31']).isValid(), true, 'string array + isValid');\n});\n\ntest('object with strings', function (assert) {\n    assert.equal(moment({year: '2014', month: '7', day: '31'}).isValid(), true, 'string object + isValid');\n});\n\ntest('utc with array of formats', function (assert) {\n    assert.equal(moment.utc('2014-01-01', ['YYYY-MM-DD', 'YYYY-MM']).format(), '2014-01-01T00:00:00Z', 'moment.utc works with array of formats');\n});\n\ntest('parsing invalid string weekdays', function (assert) {\n    assert.equal(false, moment('a', 'dd').isValid(),\n            'dd with invalid weekday, non-strict');\n    assert.equal(false, moment('a', 'dd', true).isValid(),\n            'dd with invalid weekday, strict');\n    assert.equal(false, moment('a', 'ddd').isValid(),\n            'ddd with invalid weekday, non-strict');\n    assert.equal(false, moment('a', 'ddd', true).isValid(),\n            'ddd with invalid weekday, strict');\n    assert.equal(false, moment('a', 'dddd').isValid(),\n            'dddd with invalid weekday, non-strict');\n    assert.equal(false, moment('a', 'dddd', true).isValid(),\n            'dddd with invalid weekday, strict');\n});\n\ntest('milliseconds', function (assert) {\n    assert.equal(moment('1', 'S').millisecond(), 100);\n    assert.equal(moment('12', 'SS').millisecond(), 120);\n    assert.equal(moment('123', 'SSS').millisecond(), 123);\n    assert.equal(moment('1234', 'SSSS').millisecond(), 123);\n    assert.equal(moment('12345', 'SSSSS').millisecond(), 123);\n    assert.equal(moment('123456', 'SSSSSS').millisecond(), 123);\n    assert.equal(moment('1234567', 'SSSSSSS').millisecond(), 123);\n    assert.equal(moment('12345678', 'SSSSSSSS').millisecond(), 123);\n    assert.equal(moment('123456789', 'SSSSSSSSS').millisecond(), 123);\n});\n\ntest('hmm', function (assert) {\n    assert.equal(moment('123', 'hmm', true).format('HH:mm:ss'), '01:23:00', '123 with hmm');\n    assert.equal(moment('123a', 'hmmA', true).format('HH:mm:ss'), '01:23:00', '123a with hmmA');\n    assert.equal(moment('123p', 'hmmA', true).format('HH:mm:ss'), '13:23:00', '123p with hmmA');\n\n    assert.equal(moment('1234', 'hmm', true).format('HH:mm:ss'), '12:34:00', '1234 with hmm');\n    assert.equal(moment('1234a', 'hmmA', true).format('HH:mm:ss'), '00:34:00', '1234a with hmmA');\n    assert.equal(moment('1234p', 'hmmA', true).format('HH:mm:ss'), '12:34:00', '1234p with hmmA');\n\n    assert.equal(moment('12345', 'hmmss', true).format('HH:mm:ss'), '01:23:45', '12345 with hmmss');\n    assert.equal(moment('12345a', 'hmmssA', true).format('HH:mm:ss'), '01:23:45', '12345a with hmmssA');\n    assert.equal(moment('12345p', 'hmmssA', true).format('HH:mm:ss'), '13:23:45', '12345p with hmmssA');\n    assert.equal(moment('112345', 'hmmss', true).format('HH:mm:ss'), '11:23:45', '112345 with hmmss');\n    assert.equal(moment('112345a', 'hmmssA', true).format('HH:mm:ss'), '11:23:45', '112345a with hmmssA');\n    assert.equal(moment('112345p', 'hmmssA', true).format('HH:mm:ss'), '23:23:45', '112345p with hmmssA');\n\n    assert.equal(moment('023', 'Hmm', true).format('HH:mm:ss'), '00:23:00', '023 with Hmm');\n    assert.equal(moment('123', 'Hmm', true).format('HH:mm:ss'), '01:23:00', '123 with Hmm');\n    assert.equal(moment('1234', 'Hmm', true).format('HH:mm:ss'), '12:34:00', '1234 with Hmm');\n    assert.equal(moment('1534', 'Hmm', true).format('HH:mm:ss'), '15:34:00', '1234 with Hmm');\n    assert.equal(moment('12345', 'Hmmss', true).format('HH:mm:ss'), '01:23:45', '12345 with Hmmss');\n    assert.equal(moment('112345', 'Hmmss', true).format('HH:mm:ss'), '11:23:45', '112345 with Hmmss');\n    assert.equal(moment('172345', 'Hmmss', true).format('HH:mm:ss'), '17:23:45', '112345 with Hmmss');\n});\n\ntest('Y token', function (assert) {\n    assert.equal(moment('1-1-2010', 'M-D-Y', true).year(), 2010, 'parsing Y');\n});\n\ntest('parsing flags retain parsed date parts', function (assert) {\n    var a = moment('10 p', 'hh:mm a');\n    assert.equal(a.parsingFlags().parsedDateParts[3], 10, 'parsed 10 as the hour');\n    assert.equal(a.parsingFlags().parsedDateParts[0], undefined, 'year was not parsed');\n    assert.equal(a.parsingFlags().meridiem, 'p', 'meridiem flag was added');\n    var b = moment('10:30', ['MMDDYY', 'HH:mm']);\n    assert.equal(b.parsingFlags().parsedDateParts[3], 10, 'multiple format parshing matched hour');\n    assert.equal(b.parsingFlags().parsedDateParts[0], undefined, 'array is properly copied, no residual data from first token parse');\n});\n\ntest('parsing only meridiem results in invalid date', function (assert) {\n    assert.ok(!moment('alkj', 'hh:mm a').isValid(), 'because an a token is used, a meridiem will be parsed but nothing else was so invalid');\n    assert.ok(moment('02:30 p more extra stuff', 'hh:mm a').isValid(), 'because other tokens were parsed, date is valid');\n    assert.ok(moment('1/1/2016 extra data', ['a', 'M/D/YYYY']).isValid(), 'took second format, does not pick up on meridiem parsed from first format (good copy)');\n});\n\ntest('invalid dates return invalid for methods that access the _d prop', function (assert) {\n    var momentAsDate = moment(['2015', '12', '1']).toDate();\n    assert.ok(momentAsDate instanceof Date, 'toDate returns a Date object');\n    assert.ok(isNaN(momentAsDate.getTime()), 'toDate returns an invalid Date invalid');\n});\n\ntest('k, kk', function (assert) {\n    for (var i = -1; i <= 24; i++) {\n        var kVal = i + ':15:59';\n        var kkVal = (i < 10 ? '0' : '') + i + ':15:59';\n        if (i !== 24) {\n            assert.ok(moment(kVal, 'k:mm:ss').isSame(moment(kVal, 'H:mm:ss')), kVal + ' k parsing');\n            assert.ok(moment(kkVal, 'kk:mm:ss').isSame(moment(kkVal, 'HH:mm:ss')), kkVal + ' kk parsing');\n        } else {\n            assert.equal(moment(kVal, 'k:mm:ss').format('k:mm:ss'), kVal, kVal + ' k parsing');\n            assert.equal(moment(kkVal, 'kk:mm:ss').format('kk:mm:ss'), kkVal, kkVal + ' skk parsing');\n        }\n    }\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\nfunction module$1 (name, lifecycle) {\n    QUnit.module(name, {\n        setup : function () {\n            moment.locale('en');\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'core');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            teardownDeprecationHandler(test, moment, 'core');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n}\n\nmodule$1('creation data');\n\ntest('valid date', function (assert) {\n    var dat = moment('1992-10-22');\n    var orig = dat.creationData();\n\n    assert.equal(dat.isValid(), true, '1992-10-22 is valid');\n    assert.equal(orig.input, '1992-10-22', 'original input is not correct.');\n    assert.equal(orig.format, 'YYYY-MM-DD', 'original format is defined.');\n    assert.equal(orig.locale._abbr, 'en', 'default locale is en');\n    assert.equal(orig.isUTC, false, 'not a UTC date');\n});\n\ntest('valid date at fr locale', function (assert) {\n    var dat = moment('1992-10-22', 'YYYY-MM-DD', 'fr');\n    var orig = dat.creationData();\n\n    assert.equal(orig.locale._abbr, 'fr', 'locale is fr');\n});\n\ntest('valid date with formats', function (assert) {\n    var dat = moment('29-06-1995', ['MM-DD-YYYY', 'DD-MM', 'DD-MM-YYYY']);\n    var orig = dat.creationData();\n\n    assert.equal(orig.format, 'DD-MM-YYYY', 'DD-MM-YYYY format is defined.');\n});\n\ntest('strict', function (assert) {\n    assert.ok(moment('2015-01-02', 'YYYY-MM-DD', true).creationData().strict, 'strict is true');\n    assert.ok(!moment('2015-01-02', 'YYYY-MM-DD').creationData().strict, 'strict is true');\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\nfunction module$1 (name, lifecycle) {\n    QUnit.module(name, {\n        setup : function () {\n            moment.locale('en');\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'core');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            teardownDeprecationHandler(test, moment, 'core');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n}\n\nmodule$1('days in month');\n\ntest('days in month', function (assert) {\n    each([31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31], function (days, i) {\n        var firstDay = moment([2012, i]),\n            lastDay  = moment([2012, i, days]);\n        assert.equal(firstDay.daysInMonth(), days, firstDay.format('L') + ' should have ' + days + ' days.');\n        assert.equal(lastDay.daysInMonth(), days, lastDay.format('L') + ' should have ' + days + ' days.');\n    });\n});\n\ntest('days in month leap years', function (assert) {\n    assert.equal(moment([2010, 1]).daysInMonth(), 28, 'Feb 2010 should have 28 days');\n    assert.equal(moment([2100, 1]).daysInMonth(), 28, 'Feb 2100 should have 28 days');\n    assert.equal(moment([2008, 1]).daysInMonth(), 29, 'Feb 2008 should have 29 days');\n    assert.equal(moment([2000, 1]).daysInMonth(), 29, 'Feb 2000 should have 29 days');\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\nfunction module$1 (name, lifecycle) {\n    QUnit.module(name, {\n        setup : function () {\n            moment.locale('en');\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'core');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            teardownDeprecationHandler(test, moment, 'core');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n}\n\nmodule$1('days in year');\n\n// https://github.com/moment/moment/issues/3717\ntest('YYYYDDD should not parse DDD=000', function (assert) {\n    assert.equal(moment(7000000, moment.ISO_8601, true).isValid(), false);\n    assert.equal(moment('7000000', moment.ISO_8601, true).isValid(), false);\n    assert.equal(moment(7000000, moment.ISO_8601, false).isValid(), false);\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\nfunction module$1 (name, lifecycle) {\n    QUnit.module(name, {\n        setup : function () {\n            moment.locale('en');\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'core');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            teardownDeprecationHandler(test, moment, 'core');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n}\n\nfunction hasOwnProp(a, b) {\n    return Object.prototype.hasOwnProperty.call(a, b);\n}\n\nfunction extend(a, b) {\n    for (var i in b) {\n        if (hasOwnProp(b, i)) {\n            a[i] = b[i];\n        }\n    }\n\n    if (hasOwnProp(b, 'toString')) {\n        a.toString = b.toString;\n    }\n\n    if (hasOwnProp(b, 'valueOf')) {\n        a.valueOf = b.valueOf;\n    }\n\n    return a;\n}\n\nvar hookCallback;\n\nfunction hooks () {\n    return hookCallback.apply(null, arguments);\n}\n\nfunction warn(msg) {\n    if (hooks.suppressDeprecationWarnings === false &&\n            (typeof console !==  'undefined') && console.warn) {\n        console.warn('Deprecation warning: ' + msg);\n    }\n}\n\nfunction deprecate(msg, fn) {\n    var firstTime = true;\n\n    return extend(function () {\n        if (hooks.deprecationHandler != null) {\n            hooks.deprecationHandler(null, msg);\n        }\n        if (firstTime) {\n            var args = [];\n            var arg;\n            for (var i = 0; i < arguments.length; i++) {\n                arg = '';\n                if (typeof arguments[i] === 'object') {\n                    arg += '\\n[' + i + '] ';\n                    for (var key in arguments[0]) {\n                        arg += key + ': ' + arguments[0][key] + ', ';\n                    }\n                    arg = arg.slice(0, -2); // Remove trailing comma and space\n                } else {\n                    arg = arguments[i];\n                }\n                args.push(arg);\n            }\n            warn(msg + '\\nArguments: ' + Array.prototype.slice.call(args).join('') + '\\n' + (new Error()).stack);\n            firstTime = false;\n        }\n        return fn.apply(this, arguments);\n    }, fn);\n}\n\nvar deprecations = {};\n\n\n\nhooks.suppressDeprecationWarnings = false;\nhooks.deprecationHandler = null;\n\nmodule$1('deprecate');\n\ntest('deprecate', function (assert) {\n    // NOTE: hooks inside deprecate.js and moment are different, so this is can\n    // not be test.expectedDeprecations(...)\n    var fn = function () {};\n    var deprecatedFn = deprecate('testing deprecation', fn);\n    deprecatedFn();\n\n    expect(0);\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\nfunction module$1 (name, lifecycle) {\n    QUnit.module(name, {\n        setup : function () {\n            moment.locale('en');\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'core');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            teardownDeprecationHandler(test, moment, 'core');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n}\n\nfunction equal(assert, a, b, message) {\n    assert.ok(Math.abs(a - b) < 0.00000001, '(' + a + ' === ' + b + ') ' + message);\n}\n\nfunction dstForYear(year) {\n    var start = moment([year]),\n        end = moment([year + 1]),\n        current = start.clone(),\n        last;\n\n    while (current < end) {\n        last = current.clone();\n        current.add(24, 'hour');\n        if (last.utcOffset() !== current.utcOffset()) {\n            end = current.clone();\n            current = last.clone();\n            break;\n        }\n    }\n\n    while (current < end) {\n        last = current.clone();\n        current.add(1, 'hour');\n        if (last.utcOffset() !== current.utcOffset()) {\n            return {\n                moment : last,\n                diff : -(current.utcOffset() - last.utcOffset()) / 60\n            };\n        }\n    }\n}\n\nmodule$1('diff');\n\ntest('diff', function (assert) {\n    assert.equal(moment(1000).diff(0), 1000, '1 second - 0 = 1000');\n    assert.equal(moment(1000).diff(500), 500, '1 second - 0.5 seconds = 500');\n    assert.equal(moment(0).diff(1000), -1000, '0 - 1 second = -1000');\n    assert.equal(moment(new Date(1000)).diff(1000), 0, '1 second - 1 second = 0');\n    var oneHourDate = new Date(2015, 5, 21),\n    nowDate = new Date(+oneHourDate);\n    oneHourDate.setHours(oneHourDate.getHours() + 1);\n    assert.equal(moment(oneHourDate).diff(nowDate), 60 * 60 * 1000, '1 hour from now = 3600000');\n});\n\ntest('diff key after', function (assert) {\n    assert.equal(moment([2010]).diff([2011], 'years'), -1, 'year diff');\n    assert.equal(moment([2010]).diff([2010, 2], 'months'), -2, 'month diff');\n    assert.equal(moment([2010]).diff([2010, 0, 7], 'weeks'), 0, 'week diff');\n    assert.equal(moment([2010]).diff([2010, 0, 8], 'weeks'), -1, 'week diff');\n    assert.equal(moment([2010]).diff([2010, 0, 21], 'weeks'), -2, 'week diff');\n    assert.equal(moment([2010]).diff([2010, 0, 22], 'weeks'), -3, 'week diff');\n    assert.equal(moment([2010]).diff([2010, 0, 4], 'days'), -3, 'day diff');\n    assert.equal(moment([2010]).diff([2010, 0, 1, 4], 'hours'), -4, 'hour diff');\n    assert.equal(moment([2010]).diff([2010, 0, 1, 0, 5], 'minutes'), -5, 'minute diff');\n    assert.equal(moment([2010]).diff([2010, 0, 1, 0, 0, 6], 'seconds'), -6, 'second diff');\n});\n\ntest('diff key before', function (assert) {\n    assert.equal(moment([2011]).diff([2010], 'years'), 1, 'year diff');\n    assert.equal(moment([2010, 2]).diff([2010], 'months'), 2, 'month diff');\n    assert.equal(moment([2010, 0, 4]).diff([2010], 'days'), 3, 'day diff');\n    assert.equal(moment([2010, 0, 7]).diff([2010], 'weeks'), 0, 'week diff');\n    assert.equal(moment([2010, 0, 8]).diff([2010], 'weeks'), 1, 'week diff');\n    assert.equal(moment([2010, 0, 21]).diff([2010], 'weeks'), 2, 'week diff');\n    assert.equal(moment([2010, 0, 22]).diff([2010], 'weeks'), 3, 'week diff');\n    assert.equal(moment([2010, 0, 1, 4]).diff([2010], 'hours'), 4, 'hour diff');\n    assert.equal(moment([2010, 0, 1, 0, 5]).diff([2010], 'minutes'), 5, 'minute diff');\n    assert.equal(moment([2010, 0, 1, 0, 0, 6]).diff([2010], 'seconds'), 6, 'second diff');\n});\n\ntest('diff key before singular', function (assert) {\n    assert.equal(moment([2011]).diff([2010], 'year'), 1, 'year diff singular');\n    assert.equal(moment([2010, 2]).diff([2010], 'month'), 2, 'month diff singular');\n    assert.equal(moment([2010, 0, 4]).diff([2010], 'day'), 3, 'day diff singular');\n    assert.equal(moment([2010, 0, 7]).diff([2010], 'week'), 0, 'week diff singular');\n    assert.equal(moment([2010, 0, 8]).diff([2010], 'week'), 1, 'week diff singular');\n    assert.equal(moment([2010, 0, 21]).diff([2010], 'week'), 2, 'week diff singular');\n    assert.equal(moment([2010, 0, 22]).diff([2010], 'week'), 3, 'week diff singular');\n    assert.equal(moment([2010, 0, 1, 4]).diff([2010], 'hour'), 4, 'hour diff singular');\n    assert.equal(moment([2010, 0, 1, 0, 5]).diff([2010], 'minute'), 5, 'minute diff singular');\n    assert.equal(moment([2010, 0, 1, 0, 0, 6]).diff([2010], 'second'), 6, 'second diff singular');\n});\n\ntest('diff key before abbreviated', function (assert) {\n    assert.equal(moment([2011]).diff([2010], 'y'), 1, 'year diff abbreviated');\n    assert.equal(moment([2010, 2]).diff([2010], 'M'), 2, 'month diff abbreviated');\n    assert.equal(moment([2010, 0, 4]).diff([2010], 'd'), 3, 'day diff abbreviated');\n    assert.equal(moment([2010, 0, 7]).diff([2010], 'w'), 0, 'week diff abbreviated');\n    assert.equal(moment([2010, 0, 8]).diff([2010], 'w'), 1, 'week diff abbreviated');\n    assert.equal(moment([2010, 0, 21]).diff([2010], 'w'), 2, 'week diff abbreviated');\n    assert.equal(moment([2010, 0, 22]).diff([2010], 'w'), 3, 'week diff abbreviated');\n    assert.equal(moment([2010, 0, 1, 4]).diff([2010], 'h'), 4, 'hour diff abbreviated');\n    assert.equal(moment([2010, 0, 1, 0, 5]).diff([2010], 'm'), 5, 'minute diff abbreviated');\n    assert.equal(moment([2010, 0, 1, 0, 0, 6]).diff([2010], 's'), 6, 'second diff abbreviated');\n});\n\ntest('diff month', function (assert) {\n    assert.equal(moment([2011, 0, 31]).diff([2011, 2, 1], 'months'), -1, 'month diff');\n});\n\ntest('diff across DST', function (assert) {\n    var dst = dstForYear(2012), a, b, daysInMonth;\n    if (!dst) {\n        assert.equal(42, 42, 'at least one assertion');\n        return;\n    }\n\n    a = dst.moment;\n    b = a.clone().utc().add(12, 'hours').local();\n    daysInMonth = (a.daysInMonth() + b.daysInMonth()) / 2;\n    assert.equal(b.diff(a, 'milliseconds', true), 12 * 60 * 60 * 1000,\n            'ms diff across DST');\n    assert.equal(b.diff(a, 'seconds', true), 12 * 60 * 60,\n            'second diff across DST');\n    assert.equal(b.diff(a, 'minutes', true), 12 * 60,\n            'minute diff across DST');\n    assert.equal(b.diff(a, 'hours', true), 12,\n            'hour diff across DST');\n    assert.equal(b.diff(a, 'days', true), (12 - dst.diff) / 24,\n            'day diff across DST');\n    equal(assert, b.diff(a, 'weeks', true),  (12 - dst.diff) / 24 / 7,\n            'week diff across DST');\n    assert.ok(0.95 / (2 * 31) < b.diff(a, 'months', true),\n            'month diff across DST, lower bound');\n    assert.ok(b.diff(a, 'month', true) < 1.05 / (2 * 28),\n            'month diff across DST, upper bound');\n    assert.ok(0.95 / (2 * 31 * 12) < b.diff(a, 'years', true),\n            'year diff across DST, lower bound');\n    assert.ok(b.diff(a, 'year', true) < 1.05 / (2 * 28 * 12),\n            'year diff across DST, upper bound');\n\n    a = dst.moment;\n    b = a.clone().utc().add(12 + dst.diff, 'hours').local();\n    daysInMonth = (a.daysInMonth() + b.daysInMonth()) / 2;\n\n    assert.equal(b.diff(a, 'milliseconds', true),\n            (12 + dst.diff) * 60 * 60 * 1000,\n            'ms diff across DST');\n    assert.equal(b.diff(a, 'seconds', true),  (12 + dst.diff) * 60 * 60,\n            'second diff across DST');\n    assert.equal(b.diff(a, 'minutes', true),  (12 + dst.diff) * 60,\n            'minute diff across DST');\n    assert.equal(b.diff(a, 'hours', true),  (12 + dst.diff),\n            'hour diff across DST');\n    assert.equal(b.diff(a, 'days', true),  12 / 24, 'day diff across DST');\n    equal(assert, b.diff(a, 'weeks', true),  12 / 24 / 7,\n            'week diff across DST');\n    assert.ok(0.95 / (2 * 31) < b.diff(a, 'months', true),\n            'month diff across DST, lower bound');\n    assert.ok(b.diff(a, 'month', true) < 1.05 / (2 * 28),\n            'month diff across DST, upper bound');\n    assert.ok(0.95 / (2 * 31 * 12) < b.diff(a, 'years', true),\n            'year diff across DST, lower bound');\n    assert.ok(b.diff(a, 'year', true) < 1.05 / (2 * 28 * 12),\n            'year diff across DST, upper bound');\n});\n\ntest('diff overflow', function (assert) {\n    assert.equal(moment([2011]).diff([2010], 'months'), 12, 'month diff');\n    assert.equal(moment([2010, 0, 2]).diff([2010], 'hours'), 24, 'hour diff');\n    assert.equal(moment([2010, 0, 1, 2]).diff([2010], 'minutes'), 120, 'minute diff');\n    assert.equal(moment([2010, 0, 1, 0, 4]).diff([2010], 'seconds'), 240, 'second diff');\n});\n\ntest('diff between utc and local', function (assert) {\n    if (moment([2012]).utcOffset() === moment([2011]).utcOffset()) {\n        // Russia's utc offset on 1st of Jan 2012 vs 2011 is different\n        assert.equal(moment([2012]).utc().diff([2011], 'years'), 1, 'year diff');\n    }\n    assert.equal(moment([2010, 2, 2]).utc().diff([2010, 0, 2], 'months'), 2, 'month diff');\n    assert.equal(moment([2010, 0, 4]).utc().diff([2010], 'days'), 3, 'day diff');\n    assert.equal(moment([2010, 0, 22]).utc().diff([2010], 'weeks'), 3, 'week diff');\n    assert.equal(moment([2010, 0, 1, 4]).utc().diff([2010], 'hours'), 4, 'hour diff');\n    assert.equal(moment([2010, 0, 1, 0, 5]).utc().diff([2010], 'minutes'), 5, 'minute diff');\n    assert.equal(moment([2010, 0, 1, 0, 0, 6]).utc().diff([2010], 'seconds'), 6, 'second diff');\n});\n\ntest('diff floored', function (assert) {\n    assert.equal(moment([2010, 0, 1, 23]).diff([2010], 'day'), 0, '23 hours = 0 days');\n    assert.equal(moment([2010, 0, 1, 23, 59]).diff([2010], 'day'), 0, '23:59 hours = 0 days');\n    assert.equal(moment([2010, 0, 1, 24]).diff([2010], 'day'), 1, '24 hours = 1 day');\n    assert.equal(moment([2010, 0, 2]).diff([2011, 0, 1], 'year'), 0, 'year rounded down');\n    assert.equal(moment([2011, 0, 1]).diff([2010, 0, 2], 'year'), 0, 'year rounded down');\n    assert.equal(moment([2010, 0, 2]).diff([2011, 0, 2], 'year'), -1, 'year rounded down');\n    assert.equal(moment([2011, 0, 2]).diff([2010, 0, 2], 'year'), 1, 'year rounded down');\n});\n\ntest('year diffs include dates', function (assert) {\n    assert.ok(moment([2012, 1, 19]).diff(moment([2002, 1, 20]), 'years', true) < 10, 'year diff should include date of month');\n});\n\ntest('month diffs', function (assert) {\n    // due to floating point math errors, these tests just need to be accurate within 0.00000001\n    assert.equal(moment([2012, 0, 1]).diff([2012, 1, 1], 'months', true), -1, 'Jan 1 to Feb 1 should be 1 month');\n    equal(assert, moment([2012, 0, 1]).diff([2012, 0, 1, 12], 'months', true), -0.5 / 31, 'Jan 1 to Jan 1 noon should be 0.5 / 31 months');\n    assert.equal(moment([2012, 0, 15]).diff([2012, 1, 15], 'months', true), -1, 'Jan 15 to Feb 15 should be 1 month');\n    assert.equal(moment([2012, 0, 28]).diff([2012, 1, 28], 'months', true), -1, 'Jan 28 to Feb 28 should be 1 month');\n    assert.ok(moment([2012, 0, 31]).diff([2012, 1, 29], 'months', true), -1, 'Jan 31 to Feb 29 should be 1 month');\n    assert.ok(-1 > moment([2012, 0, 31]).diff([2012, 2, 1], 'months', true), 'Jan 31 to Mar 1 should be more than 1 month');\n    assert.ok(-30 / 28 < moment([2012, 0, 31]).diff([2012, 2, 1], 'months', true), 'Jan 31 to Mar 1 should be less than 1 month and 1 day');\n    equal(assert, moment([2012, 0, 1]).diff([2012, 0, 31], 'months', true), -(30 / 31), 'Jan 1 to Jan 31 should be 30 / 31 months');\n    assert.ok(0 < moment('2014-02-01').diff(moment('2014-01-31'), 'months', true), 'jan-31 to feb-1 diff is positive');\n});\n\ntest('exact month diffs', function (assert) {\n    // generate all pairs of months and compute month diff, with fixed day\n    // of month = 15.\n\n    var m1, m2;\n    for (m1 = 0; m1 < 12; ++m1) {\n        for (m2 = m1; m2 < 12; ++m2) {\n            assert.equal(moment([2013, m2, 15]).diff(moment([2013, m1, 15]), 'months', true), m2 - m1,\n                         'month diff from 2013-' + m1 + '-15 to 2013-' + m2 + '-15');\n        }\n    }\n});\n\ntest('year diffs', function (assert) {\n    // due to floating point math errors, these tests just need to be accurate within 0.00000001\n    equal(assert, moment([2012, 0, 1]).diff([2013, 0, 1], 'years', true), -1, 'Jan 1 2012 to Jan 1 2013 should be 1 year');\n    equal(assert, moment([2012, 1, 28]).diff([2013, 1, 28], 'years', true), -1, 'Feb 28 2012 to Feb 28 2013 should be 1 year');\n    equal(assert, moment([2012, 2, 1]).diff([2013, 2, 1], 'years', true), -1, 'Mar 1 2012 to Mar 1 2013 should be 1 year');\n    equal(assert, moment([2012, 11, 1]).diff([2013, 11, 1], 'years', true), -1, 'Dec 1 2012 to Dec 1 2013 should be 1 year');\n    equal(assert, moment([2012, 11, 31]).diff([2013, 11, 31], 'years', true), -1, 'Dec 31 2012 to Dec 31 2013 should be 1 year');\n    equal(assert, moment([2012, 0, 1]).diff([2013, 6, 1], 'years', true), -1.5, 'Jan 1 2012 to Jul 1 2013 should be 1.5 years');\n    equal(assert, moment([2012, 0, 31]).diff([2013, 6, 31], 'years', true), -1.5, 'Jan 31 2012 to Jul 31 2013 should be 1.5 years');\n    equal(assert, moment([2012, 0, 1]).diff([2013, 0, 1, 12], 'years', true), -1 - (0.5 / 31) / 12, 'Jan 1 2012 to Jan 1 2013 noon should be 1+(0.5 / 31) / 12 years');\n    equal(assert, moment([2012, 0, 1]).diff([2013, 6, 1, 12], 'years', true), -1.5 - (0.5 / 31) / 12, 'Jan 1 2012 to Jul 1 2013 noon should be 1.5+(0.5 / 31) / 12 years');\n    equal(assert, moment([2012, 1, 29]).diff([2013, 1, 28], 'years', true), -1, 'Feb 29 2012 to Feb 28 2013 should be 1-(1 / 28.5) / 12 years');\n});\n\ntest('negative zero', function (assert) {\n    function isNegative (n) {\n        return (1 / n) < 0;\n    }\n    assert.ok(!isNegative(moment([2012, 0, 1]).diff(moment([2012, 0, 1]), 'months')), 'month diff on same date is zero, not -0');\n    assert.ok(!isNegative(moment([2012, 0, 1]).diff(moment([2012, 0, 1]), 'years')), 'year diff on same date is zero, not -0');\n    assert.ok(!isNegative(moment([2012, 0, 1]).diff(moment([2012, 0, 1]), 'quarters')), 'quarter diff on same date is zero, not -0');\n    assert.ok(!isNegative(moment([2012, 0, 1]).diff(moment([2012, 0, 1, 1]), 'days')), 'days diff on same date is zero, not -0');\n    assert.ok(!isNegative(moment([2012, 0, 1]).diff(moment([2012, 0, 1, 0, 1]), 'hours')), 'hour diff on same hour is zero, not -0');\n    assert.ok(!isNegative(moment([2012, 0, 1]).diff(moment([2012, 0, 1, 0, 0, 1]), 'minutes')), 'minute diff on same minute is zero, not -0');\n    assert.ok(!isNegative(moment([2012, 0, 1]).diff(moment([2012, 0, 1, 0, 0, 0, 1]), 'seconds')), 'second diff on same second is zero, not -0');\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\nfunction module$1 (name, lifecycle) {\n    QUnit.module(name, {\n        setup : function () {\n            moment.locale('en');\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'core');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            teardownDeprecationHandler(test, moment, 'core');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n}\n\nmodule$1('duration');\n\ntest('object instantiation', function (assert) {\n    var d = moment.duration({\n        years: 2,\n        months: 3,\n        weeks: 2,\n        days: 1,\n        hours: 8,\n        minutes: 9,\n        seconds: 20,\n        milliseconds: 12\n    });\n\n    assert.equal(d.years(),        2,  'years');\n    assert.equal(d.months(),       3,  'months');\n    assert.equal(d.weeks(),        2,  'weeks');\n    assert.equal(d.days(),         15, 'days'); // two weeks + 1 day\n    assert.equal(d.hours(),        8,  'hours');\n    assert.equal(d.minutes(),      9,  'minutes');\n    assert.equal(d.seconds(),      20, 'seconds');\n    assert.equal(d.milliseconds(), 12, 'milliseconds');\n});\n\ntest('object instantiation with strings', function (assert) {\n    var d = moment.duration({\n        years: '2',\n        months: '3',\n        weeks: '2',\n        days: '1',\n        hours: '8',\n        minutes: '9',\n        seconds: '20',\n        milliseconds: '12'\n    });\n\n    assert.equal(d.years(),        2,  'years');\n    assert.equal(d.months(),       3,  'months');\n    assert.equal(d.weeks(),        2,  'weeks');\n    assert.equal(d.days(),         15, 'days'); // two weeks + 1 day\n    assert.equal(d.hours(),        8,  'hours');\n    assert.equal(d.minutes(),      9,  'minutes');\n    assert.equal(d.seconds(),      20, 'seconds');\n    assert.equal(d.milliseconds(), 12, 'milliseconds');\n});\n\ntest('milliseconds instantiation', function (assert) {\n    assert.equal(moment.duration(72).milliseconds(), 72, 'milliseconds');\n    assert.equal(moment.duration(72).humanize(), 'a few seconds', 'Duration should be valid');\n});\n\ntest('undefined instantiation', function (assert) {\n    assert.equal(moment.duration(undefined).milliseconds(), 0, 'milliseconds');\n    assert.equal(moment.duration(undefined).isValid(), true, '_isValid');\n    assert.equal(moment.duration(undefined).humanize(), 'a few seconds', 'Duration should be valid');\n});\n\ntest('null instantiation', function (assert) {\n    assert.equal(moment.duration(null).milliseconds(), 0, 'milliseconds');\n    assert.equal(moment.duration(null).isValid(), true, '_isValid');\n    assert.equal(moment.duration(null).humanize(), 'a few seconds', 'Duration should be valid');\n});\n\ntest('NaN instantiation', function (assert) {\n    assert.ok(isNaN(moment.duration(NaN).milliseconds()), 'milliseconds should be NaN');\n    assert.equal(moment.duration(NaN).isValid(), false, '_isValid');\n    assert.equal(moment.duration(NaN).humanize(), 'Invalid date', 'Duration should be invalid');\n});\n\ntest('instantiation by type', function (assert) {\n    assert.equal(moment.duration(1, 'years').years(),                 1, 'years');\n    assert.equal(moment.duration(1, 'y').years(),                     1, 'y');\n    assert.equal(moment.duration(2, 'months').months(),               2, 'months');\n    assert.equal(moment.duration(2, 'M').months(),                    2, 'M');\n    assert.equal(moment.duration(3, 'weeks').weeks(),                 3, 'weeks');\n    assert.equal(moment.duration(3, 'w').weeks(),                     3, 'weeks');\n    assert.equal(moment.duration(4, 'days').days(),                   4, 'days');\n    assert.equal(moment.duration(4, 'd').days(),                      4, 'd');\n    assert.equal(moment.duration(5, 'hours').hours(),                 5, 'hours');\n    assert.equal(moment.duration(5, 'h').hours(),                     5, 'h');\n    assert.equal(moment.duration(6, 'minutes').minutes(),             6, 'minutes');\n    assert.equal(moment.duration(6, 'm').minutes(),                   6, 'm');\n    assert.equal(moment.duration(7, 'seconds').seconds(),             7, 'seconds');\n    assert.equal(moment.duration(7, 's').seconds(),                   7, 's');\n    assert.equal(moment.duration(8, 'milliseconds').milliseconds(),   8, 'milliseconds');\n    assert.equal(moment.duration(8, 'ms').milliseconds(),             8, 'ms');\n});\n\ntest('shortcuts', function (assert) {\n    assert.equal(moment.duration({y: 1}).years(),         1, 'years = y');\n    assert.equal(moment.duration({M: 2}).months(),        2, 'months = M');\n    assert.equal(moment.duration({w: 3}).weeks(),         3, 'weeks = w');\n    assert.equal(moment.duration({d: 4}).days(),          4, 'days = d');\n    assert.equal(moment.duration({h: 5}).hours(),         5, 'hours = h');\n    assert.equal(moment.duration({m: 6}).minutes(),       6, 'minutes = m');\n    assert.equal(moment.duration({s: 7}).seconds(),       7, 'seconds = s');\n    assert.equal(moment.duration({ms: 8}).milliseconds(), 8, 'milliseconds = ms');\n});\n\ntest('generic getter', function (assert) {\n    assert.equal(moment.duration(1, 'years').get('years'),                1, 'years');\n    assert.equal(moment.duration(1, 'years').get('year'),                 1, 'years = year');\n    assert.equal(moment.duration(1, 'years').get('y'),                    1, 'years = y');\n    assert.equal(moment.duration(2, 'months').get('months'),              2, 'months');\n    assert.equal(moment.duration(2, 'months').get('month'),               2, 'months = month');\n    assert.equal(moment.duration(2, 'months').get('M'),                   2, 'months = M');\n    assert.equal(moment.duration(3, 'weeks').get('weeks'),                3, 'weeks');\n    assert.equal(moment.duration(3, 'weeks').get('week'),                 3, 'weeks = week');\n    assert.equal(moment.duration(3, 'weeks').get('w'),                    3, 'weeks = w');\n    assert.equal(moment.duration(4, 'days').get('days'),                  4, 'days');\n    assert.equal(moment.duration(4, 'days').get('day'),                   4, 'days = day');\n    assert.equal(moment.duration(4, 'days').get('d'),                     4, 'days = d');\n    assert.equal(moment.duration(5, 'hours').get('hours'),                5, 'hours');\n    assert.equal(moment.duration(5, 'hours').get('hour'),                 5, 'hours = hour');\n    assert.equal(moment.duration(5, 'hours').get('h'),                    5, 'hours = h');\n    assert.equal(moment.duration(6, 'minutes').get('minutes'),            6, 'minutes');\n    assert.equal(moment.duration(6, 'minutes').get('minute'),             6, 'minutes = minute');\n    assert.equal(moment.duration(6, 'minutes').get('m'),                  6, 'minutes = m');\n    assert.equal(moment.duration(7, 'seconds').get('seconds'),            7, 'seconds');\n    assert.equal(moment.duration(7, 'seconds').get('second'),             7, 'seconds = second');\n    assert.equal(moment.duration(7, 'seconds').get('s'),                  7, 'seconds = s');\n    assert.equal(moment.duration(8, 'milliseconds').get('milliseconds'),  8, 'milliseconds');\n    assert.equal(moment.duration(8, 'milliseconds').get('millisecond'),   8, 'milliseconds = millisecond');\n    assert.equal(moment.duration(8, 'milliseconds').get('ms'),            8, 'milliseconds = ms');\n});\n\ntest('instantiation from another duration', function (assert) {\n    var simple = moment.duration(1234),\n        lengthy = moment.duration(60 * 60 * 24 * 360 * 1e3),\n        complicated = moment.duration({\n            years: 2,\n            months: 3,\n            weeks: 4,\n            days: 1,\n            hours: 8,\n            minutes: 9,\n            seconds: 20,\n            milliseconds: 12\n        }),\n        modified = moment.duration(1, 'day').add(moment.duration(1, 'day'));\n\n    assert.deepEqual(moment.duration(simple), simple, 'simple clones are equal');\n    assert.deepEqual(moment.duration(lengthy), lengthy, 'lengthy clones are equal');\n    assert.deepEqual(moment.duration(complicated), complicated, 'complicated clones are equal');\n    assert.deepEqual(moment.duration(modified), modified, 'cloning modified duration works');\n});\n\ntest('instantiation from 24-hour time zero', function (assert) {\n    assert.equal(moment.duration('00:00').years(), 0, '0 years');\n    assert.equal(moment.duration('00:00').days(), 0, '0 days');\n    assert.equal(moment.duration('00:00').hours(), 0, '0 hours');\n    assert.equal(moment.duration('00:00').minutes(), 0, '0 minutes');\n    assert.equal(moment.duration('00:00').seconds(), 0, '0 seconds');\n    assert.equal(moment.duration('00:00').milliseconds(), 0, '0 milliseconds');\n});\n\ntest('instantiation from 24-hour time <24 hours', function (assert) {\n    assert.equal(moment.duration('06:45').years(), 0, '0 years');\n    assert.equal(moment.duration('06:45').days(), 0, '0 days');\n    assert.equal(moment.duration('06:45').hours(), 6, '6 hours');\n    assert.equal(moment.duration('06:45').minutes(), 45, '45 minutes');\n    assert.equal(moment.duration('06:45').seconds(), 0, '0 seconds');\n    assert.equal(moment.duration('06:45').milliseconds(), 0, '0 milliseconds');\n});\n\ntest('instantiation from 24-hour time >24 hours', function (assert) {\n    assert.equal(moment.duration('26:45').years(), 0, '0 years');\n    assert.equal(moment.duration('26:45').days(), 1, '0 days');\n    assert.equal(moment.duration('26:45').hours(), 2, '2 hours');\n    assert.equal(moment.duration('26:45').minutes(), 45, '45 minutes');\n    assert.equal(moment.duration('26:45').seconds(), 0, '0 seconds');\n    assert.equal(moment.duration('26:45').milliseconds(), 0, '0 milliseconds');\n});\n\ntest('instatiation from serialized C# TimeSpan zero', function (assert) {\n    assert.equal(moment.duration('00:00:00').years(), 0, '0 years');\n    assert.equal(moment.duration('00:00:00').days(), 0, '0 days');\n    assert.equal(moment.duration('00:00:00').hours(), 0, '0 hours');\n    assert.equal(moment.duration('00:00:00').minutes(), 0, '0 minutes');\n    assert.equal(moment.duration('00:00:00').seconds(), 0, '0 seconds');\n    assert.equal(moment.duration('00:00:00').milliseconds(), 0, '0 milliseconds');\n});\n\ntest('instatiation from serialized C# TimeSpan with days', function (assert) {\n    assert.equal(moment.duration('1.02:03:04.9999999').years(), 0, '0 years');\n    assert.equal(moment.duration('1.02:03:04.9999999').days(), 1, '1 day');\n    assert.equal(moment.duration('1.02:03:04.9999999').hours(), 2, '2 hours');\n    assert.equal(moment.duration('1.02:03:04.9999999').minutes(), 3, '3 minutes');\n    assert.equal(moment.duration('1.02:03:04.9999999').seconds(), 5, '5 seconds');\n    assert.equal(moment.duration('1.02:03:04.9999999').milliseconds(), 0, '0 milliseconds');\n\n    assert.equal(moment.duration('1 02:03:04.9999999').years(), 0, '0 years');\n    assert.equal(moment.duration('1 02:03:04.9999999').days(), 1, '1 day');\n    assert.equal(moment.duration('1 02:03:04.9999999').hours(), 2, '2 hours');\n    assert.equal(moment.duration('1 02:03:04.9999999').minutes(), 3, '3 minutes');\n    assert.equal(moment.duration('1 02:03:04.9999999').seconds(), 5, '5 seconds');\n    assert.equal(moment.duration('1 02:03:04.9999999').milliseconds(), 0, '0 milliseconds');\n});\n\ntest('instatiation from serialized C# TimeSpan without days', function (assert) {\n    assert.equal(moment.duration('01:02:03.9999999').years(), 0, '0 years');\n    assert.equal(moment.duration('01:02:03.9999999').days(), 0, '0 days');\n    assert.equal(moment.duration('01:02:03.9999999').hours(), 1, '1 hour');\n    assert.equal(moment.duration('01:02:03.9999999').minutes(), 2, '2 minutes');\n    assert.equal(moment.duration('01:02:03.9999999').seconds(), 4, '4 seconds');\n    assert.equal(moment.duration('01:02:03.9999999').milliseconds(), 0, '0 milliseconds');\n\n    assert.equal(moment.duration('23:59:59.9999999').days(), 1, '1 days');\n    assert.equal(moment.duration('23:59:59.9999999').hours(), 0, '0 hours');\n    assert.equal(moment.duration('23:59:59.9999999').minutes(), 0, '0 minutes');\n    assert.equal(moment.duration('23:59:59.9999999').seconds(), 0, '0 seconds');\n    assert.equal(moment.duration('23:59:59.9999999').milliseconds(), 0, '0 milliseconds');\n\n    assert.equal(moment.duration('500:59:59.8888888').days(), 20, '500 hours overflows to 20 days');\n    assert.equal(moment.duration('500:59:59.8888888').hours(), 20, '500 hours overflows to 20 hours');\n});\n\ntest('instatiation from serialized C# TimeSpan without days or milliseconds', function (assert) {\n    assert.equal(moment.duration('01:02:03').years(), 0, '0 years');\n    assert.equal(moment.duration('01:02:03').days(), 0, '0 days');\n    assert.equal(moment.duration('01:02:03').hours(), 1, '1 hour');\n    assert.equal(moment.duration('01:02:03').minutes(), 2, '2 minutes');\n    assert.equal(moment.duration('01:02:03').seconds(), 3, '3 seconds');\n    assert.equal(moment.duration('01:02:03').milliseconds(), 0, '0 milliseconds');\n});\n\ntest('instatiation from serialized C# TimeSpan without milliseconds', function (assert) {\n    assert.equal(moment.duration('1.02:03:04').years(), 0, '0 years');\n    assert.equal(moment.duration('1.02:03:04').days(), 1, '1 day');\n    assert.equal(moment.duration('1.02:03:04').hours(), 2, '2 hours');\n    assert.equal(moment.duration('1.02:03:04').minutes(), 3, '3 minutes');\n    assert.equal(moment.duration('1.02:03:04').seconds(), 4, '4 seconds');\n    assert.equal(moment.duration('1.02:03:04').milliseconds(), 0, '0 milliseconds');\n});\n\ntest('instantiation from serialized C# TimeSpan with low millisecond precision', function (assert) {\n    assert.equal(moment.duration('00:00:15.72').years(), 0, '0 years');\n    assert.equal(moment.duration('00:00:15.72').days(), 0, '0 days');\n    assert.equal(moment.duration('00:00:15.72').hours(), 0, '0 hours');\n    assert.equal(moment.duration('00:00:15.72').minutes(), 0, '0 minutes');\n    assert.equal(moment.duration('00:00:15.72').seconds(), 15, '15 seconds');\n    assert.equal(moment.duration('00:00:15.72').milliseconds(), 720, '720 milliseconds');\n\n    assert.equal(moment.duration('00:00:15.7').milliseconds(), 700, '700 milliseconds');\n\n    assert.equal(moment.duration('00:00:15.').milliseconds(), 0, '0 milliseconds');\n});\n\ntest('instantiation from serialized C# TimeSpan with high millisecond precision', function (assert) {\n    assert.equal(moment.duration('00:00:15.7200000').seconds(), 15, '15 seconds');\n    assert.equal(moment.duration('00:00:15.7200000').milliseconds(), 720, '720 milliseconds');\n\n    assert.equal(moment.duration('00:00:15.7209999').seconds(), 15, '15 seconds');\n    assert.equal(moment.duration('00:00:15.7209999').milliseconds(), 721, '721 milliseconds');\n\n    assert.equal(moment.duration('00:00:15.7205000').seconds(), 15, '15 seconds');\n    assert.equal(moment.duration('00:00:15.7205000').milliseconds(), 721, '721 milliseconds');\n\n    assert.equal(moment.duration('-00:00:15.7205000').seconds(), -15, '15 seconds');\n    assert.equal(moment.duration('-00:00:15.7205000').milliseconds(), -721, '721 milliseconds');\n});\n\ntest('instatiation from serialized C# TimeSpan maxValue', function (assert) {\n    var d = moment.duration('10675199.02:48:05.4775807');\n\n    assert.equal(d.years(), 29227, '29227 years');\n    assert.equal(d.months(), 8, '8 months');\n    assert.equal(d.days(), 12, '12 day');  // if you have to change this value -- just do it\n\n    assert.equal(d.hours(), 2, '2 hours');\n    assert.equal(d.minutes(), 48, '48 minutes');\n    assert.equal(d.seconds(), 5, '5 seconds');\n    assert.equal(d.milliseconds(), 478, '478 milliseconds');\n});\n\ntest('instatiation from serialized C# TimeSpan minValue', function (assert) {\n    var d = moment.duration('-10675199.02:48:05.4775808');\n\n    assert.equal(d.years(), -29227, '29653 years');\n    assert.equal(d.months(), -8, '8 day');\n    assert.equal(d.days(), -12, '12 day');  // if you have to change this value -- just do it\n\n    assert.equal(d.hours(), -2, '2 hours');\n    assert.equal(d.minutes(), -48, '48 minutes');\n    assert.equal(d.seconds(), -5, '5 seconds');\n    assert.equal(d.milliseconds(), -478, '478 milliseconds');\n});\n\ntest('instantiation from ISO 8601 duration', function (assert) {\n    assert.equal(moment.duration('P1Y2M3DT4H5M6S').asSeconds(), moment.duration({y: 1, M: 2, d: 3, h: 4, m: 5, s: 6}).asSeconds(), 'all fields');\n    assert.equal(moment.duration('P3W3D').asSeconds(), moment.duration({w: 3, d: 3}).asSeconds(), 'week and day fields');\n    assert.equal(moment.duration('P1M').asSeconds(), moment.duration({M: 1}).asSeconds(), 'single month field');\n    assert.equal(moment.duration('PT1M').asSeconds(), moment.duration({m: 1}).asSeconds(), 'single minute field');\n    assert.equal(moment.duration('P1MT2H').asSeconds(), moment.duration({M: 1, h: 2}).asSeconds(), 'random fields missing');\n    assert.equal(moment.duration('-P60D').asSeconds(), moment.duration({d: -60}).asSeconds(), 'negative days');\n    assert.equal(moment.duration('PT0.5S').asSeconds(), moment.duration({s: 0.5}).asSeconds(), 'fractional seconds');\n    assert.equal(moment.duration('PT0,5S').asSeconds(), moment.duration({s: 0.5}).asSeconds(), 'fractional seconds (comma)');\n});\n\ntest('serialization to ISO 8601 duration strings', function (assert) {\n    assert.equal(moment.duration({y: 1, M: 2, d: 3, h: 4, m: 5, s: 6}).toISOString(), 'P1Y2M3DT4H5M6S', 'all fields');\n    assert.equal(moment.duration({M: -1}).toISOString(), '-P1M', 'one month ago');\n    assert.equal(moment.duration({m: -1}).toISOString(), '-PT1M', 'one minute ago');\n    assert.equal(moment.duration({s: -0.5}).toISOString(), '-PT0.5S', 'one half second ago');\n    assert.equal(moment.duration({y: -1, M: 1}).toISOString(), '-P11M', 'a month after a year ago');\n    assert.equal(moment.duration({}).toISOString(), 'P0D', 'zero duration');\n    assert.equal(moment.duration({M: 16, d:40, s: 86465}).toISOString(), 'P1Y4M40DT24H1M5S', 'all fields');\n});\n\ntest('toString acts as toISOString', function (assert) {\n    assert.equal(moment.duration({y: 1, M: 2, d: 3, h: 4, m: 5, s: 6}).toString(), 'P1Y2M3DT4H5M6S', 'all fields');\n    assert.equal(moment.duration({M: -1}).toString(), '-P1M', 'one month ago');\n    assert.equal(moment.duration({m: -1}).toString(), '-PT1M', 'one minute ago');\n    assert.equal(moment.duration({s: -0.5}).toString(), '-PT0.5S', 'one half second ago');\n    assert.equal(moment.duration({y: -1, M: 1}).toString(), '-P11M', 'a month after a year ago');\n    assert.equal(moment.duration({}).toString(), 'P0D', 'zero duration');\n    assert.equal(moment.duration({M: 16, d:40, s: 86465}).toString(), 'P1Y4M40DT24H1M5S', 'all fields');\n});\n\ntest('toIsoString deprecation', function (assert) {\n    test.expectedDeprecations('toIsoString()');\n\n    assert.equal(moment.duration({}).toIsoString(), moment.duration({}).toISOString(), 'toIsoString delegates to toISOString');\n});\n\ntest('`isodate` (python) test cases', function (assert) {\n    assert.equal(moment.duration('P18Y9M4DT11H9M8S').asSeconds(), moment.duration({y: 18, M: 9, d: 4, h: 11, m: 9, s: 8}).asSeconds(), 'python isodate 1');\n    assert.equal(moment.duration('P2W').asSeconds(), moment.duration({w: 2}).asSeconds(), 'python isodate 2');\n    assert.equal(moment.duration('P3Y6M4DT12H30M5S').asSeconds(), moment.duration({y: 3, M: 6, d: 4, h: 12, m: 30, s: 5}).asSeconds(), 'python isodate 3');\n    assert.equal(moment.duration('P23DT23H').asSeconds(), moment.duration({d: 23, h: 23}).asSeconds(), 'python isodate 4');\n    assert.equal(moment.duration('P4Y').asSeconds(), moment.duration({y: 4}).asSeconds(), 'python isodate 5');\n    assert.equal(moment.duration('P1M').asSeconds(), moment.duration({M: 1}).asSeconds(), 'python isodate 6');\n    assert.equal(moment.duration('PT1M').asSeconds(), moment.duration({m: 1}).asSeconds(), 'python isodate 7');\n    assert.equal(moment.duration('P0.5Y').asSeconds(), moment.duration({y: 0.5}).asSeconds(), 'python isodate 8');\n    assert.equal(moment.duration('PT36H').asSeconds(), moment.duration({h: 36}).asSeconds(), 'python isodate 9');\n    assert.equal(moment.duration('P1DT12H').asSeconds(), moment.duration({d: 1, h: 12}).asSeconds(), 'python isodate 10');\n    assert.equal(moment.duration('-P2W').asSeconds(), moment.duration({w: -2}).asSeconds(), 'python isodate 11');\n    assert.equal(moment.duration('-P2.2W').asSeconds(), moment.duration({w: -2.2}).asSeconds(), 'python isodate 12');\n    assert.equal(moment.duration('P1DT2H3M4S').asSeconds(), moment.duration({d: 1, h: 2, m: 3, s: 4}).asSeconds(), 'python isodate 13');\n    assert.equal(moment.duration('P1DT2H3M').asSeconds(), moment.duration({d: 1, h: 2, m: 3}).asSeconds(), 'python isodate 14');\n    assert.equal(moment.duration('P1DT2H').asSeconds(), moment.duration({d: 1, h: 2}).asSeconds(), 'python isodate 15');\n    assert.equal(moment.duration('PT2H').asSeconds(), moment.duration({h: 2}).asSeconds(), 'python isodate 16');\n    assert.equal(moment.duration('PT2.3H').asSeconds(), moment.duration({h: 2.3}).asSeconds(), 'python isodate 17');\n    assert.equal(moment.duration('PT2H3M4S').asSeconds(), moment.duration({h: 2, m: 3, s: 4}).asSeconds(), 'python isodate 18');\n    assert.equal(moment.duration('PT3M4S').asSeconds(), moment.duration({m: 3, s: 4}).asSeconds(), 'python isodate 19');\n    assert.equal(moment.duration('PT22S').asSeconds(), moment.duration({s: 22}).asSeconds(), 'python isodate 20');\n    assert.equal(moment.duration('PT22.22S').asSeconds(), moment.duration({s: 22.22}).asSeconds(), 'python isodate 21');\n    assert.equal(moment.duration('-P2Y').asSeconds(), moment.duration({y: -2}).asSeconds(), 'python isodate 22');\n    assert.equal(moment.duration('-P3Y6M4DT12H30M5S').asSeconds(), moment.duration({y: -3, M: -6, d: -4, h: -12, m: -30, s: -5}).asSeconds(), 'python isodate 23');\n    assert.equal(moment.duration('-P1DT2H3M4S').asSeconds(), moment.duration({d: -1, h: -2, m: -3, s: -4}).asSeconds(), 'python isodate 24');\n    assert.equal(moment.duration('PT-6H3M').asSeconds(), moment.duration({h: -6, m: 3}).asSeconds(), 'python isodate 25');\n    assert.equal(moment.duration('-PT-6H3M').asSeconds(), moment.duration({h: 6, m: -3}).asSeconds(), 'python isodate 26');\n    assert.equal(moment.duration('-P-3Y-6M-4DT-12H-30M-5S').asSeconds(), moment.duration({y: 3, M: 6, d: 4, h: 12, m: 30, s: 5}).asSeconds(), 'python isodate 27');\n    assert.equal(moment.duration('P-3Y-6M-4DT-12H-30M-5S').asSeconds(), moment.duration({y: -3, M: -6, d: -4, h: -12, m: -30, s: -5}).asSeconds(), 'python isodate 28');\n    assert.equal(moment.duration('-P-2W').asSeconds(), moment.duration({w: 2}).asSeconds(), 'python isodate 29');\n    assert.equal(moment.duration('P-2W').asSeconds(), moment.duration({w: -2}).asSeconds(), 'python isodate 30');\n});\n\ntest('ISO 8601 misuse cases', function (assert) {\n    assert.equal(moment.duration('P').asSeconds(), 0, 'lonely P');\n    assert.equal(moment.duration('PT').asSeconds(), 0, 'just P and T');\n    assert.equal(moment.duration('P1H').asSeconds(), 0, 'missing T');\n    assert.equal(moment.duration('P1D1Y').asSeconds(), 0, 'out of order');\n    assert.equal(moment.duration('PT.5S').asSeconds(), 0.5, 'accept no leading zero for decimal');\n    assert.equal(moment.duration('PT1,S').asSeconds(), 1, 'accept trailing decimal separator');\n    assert.equal(moment.duration('PT1M0,,5S').asSeconds(), 60, 'extra decimal separators are ignored as 0');\n});\n\ntest('humanize', function (assert) {\n    moment.locale('en');\n    assert.equal(moment.duration({seconds: 44}).humanize(),  'a few seconds', '44 seconds = a few seconds');\n    assert.equal(moment.duration({seconds: 45}).humanize(),  'a minute',      '45 seconds = a minute');\n    assert.equal(moment.duration({seconds: 89}).humanize(),  'a minute',      '89 seconds = a minute');\n    assert.equal(moment.duration({seconds: 90}).humanize(),  '2 minutes',     '90 seconds = 2 minutes');\n    assert.equal(moment.duration({minutes: 44}).humanize(),  '44 minutes',    '44 minutes = 44 minutes');\n    assert.equal(moment.duration({minutes: 45}).humanize(),  'an hour',       '45 minutes = an hour');\n    assert.equal(moment.duration({minutes: 89}).humanize(),  'an hour',       '89 minutes = an hour');\n    assert.equal(moment.duration({minutes: 90}).humanize(),  '2 hours',       '90 minutes = 2 hours');\n    assert.equal(moment.duration({hours: 5}).humanize(),     '5 hours',       '5 hours = 5 hours');\n    assert.equal(moment.duration({hours: 21}).humanize(),    '21 hours',      '21 hours = 21 hours');\n    assert.equal(moment.duration({hours: 22}).humanize(),    'a day',         '22 hours = a day');\n    assert.equal(moment.duration({hours: 35}).humanize(),    'a day',         '35 hours = a day');\n    assert.equal(moment.duration({hours: 36}).humanize(),    '2 days',        '36 hours = 2 days');\n    assert.equal(moment.duration({days: 1}).humanize(),      'a day',         '1 day = a day');\n    assert.equal(moment.duration({days: 5}).humanize(),      '5 days',        '5 days = 5 days');\n    assert.equal(moment.duration({weeks: 1}).humanize(),     '7 days',        '1 week = 7 days');\n    assert.equal(moment.duration({days: 25}).humanize(),     '25 days',       '25 days = 25 days');\n    assert.equal(moment.duration({days: 26}).humanize(),     'a month',       '26 days = a month');\n    assert.equal(moment.duration({days: 30}).humanize(),     'a month',       '30 days = a month');\n    assert.equal(moment.duration({days: 45}).humanize(),     'a month',       '45 days = a month');\n    assert.equal(moment.duration({days: 46}).humanize(),     '2 months',      '46 days = 2 months');\n    assert.equal(moment.duration({days: 74}).humanize(),     '2 months',      '74 days = 2 months');\n    assert.equal(moment.duration({days: 77}).humanize(),     '3 months',      '77 days = 3 months');\n    assert.equal(moment.duration({months: 1}).humanize(),    'a month',       '1 month = a month');\n    assert.equal(moment.duration({months: 5}).humanize(),    '5 months',      '5 months = 5 months');\n    assert.equal(moment.duration({days: 344}).humanize(),    'a year',        '344 days = a year');\n    assert.equal(moment.duration({days: 345}).humanize(),    'a year',        '345 days = a year');\n    assert.equal(moment.duration({days: 547}).humanize(),    'a year',        '547 days = a year');\n    assert.equal(moment.duration({days: 548}).humanize(),    '2 years',       '548 days = 2 years');\n    assert.equal(moment.duration({years: 1}).humanize(),     'a year',        '1 year = a year');\n    assert.equal(moment.duration({years: 5}).humanize(),     '5 years',       '5 years = 5 years');\n    assert.equal(moment.duration(7200000).humanize(),        '2 hours',       '7200000 = 2 minutes');\n});\n\ntest('humanize duration with suffix', function (assert) {\n    moment.locale('en');\n    assert.equal(moment.duration({seconds:  44}).humanize(true),  'in a few seconds', '44 seconds = a few seconds');\n    assert.equal(moment.duration({seconds: -44}).humanize(true),  'a few seconds ago', '44 seconds = a few seconds');\n});\n\ntest('bubble value up', function (assert) {\n    assert.equal(moment.duration({milliseconds: 61001}).milliseconds(), 1, '61001 milliseconds has 1 millisecond left over');\n    assert.equal(moment.duration({milliseconds: 61001}).seconds(),      1, '61001 milliseconds has 1 second left over');\n    assert.equal(moment.duration({milliseconds: 61001}).minutes(),      1, '61001 milliseconds has 1 minute left over');\n\n    assert.equal(moment.duration({minutes: 350}).minutes(), 50, '350 minutes has 50 minutes left over');\n    assert.equal(moment.duration({minutes: 350}).hours(),   5,  '350 minutes has 5 hours left over');\n});\n\ntest('clipping', function (assert) {\n    assert.equal(moment.duration({months: 11}).months(), 11, '11 months is 11 months');\n    assert.equal(moment.duration({months: 11}).years(),  0,  '11 months makes no year');\n    assert.equal(moment.duration({months: 12}).months(), 0,  '12 months is 0 months left over');\n    assert.equal(moment.duration({months: 12}).years(),  1,  '12 months makes 1 year');\n    assert.equal(moment.duration({months: 13}).months(), 1,  '13 months is 1 month left over');\n    assert.equal(moment.duration({months: 13}).years(),  1,  '13 months makes 1 year');\n\n    assert.equal(moment.duration({days: 30}).days(),   30, '30 days is 30 days');\n    assert.equal(moment.duration({days: 30}).months(), 0,  '30 days makes no month');\n    assert.equal(moment.duration({days: 31}).days(),   0,  '31 days is 0 days left over');\n    assert.equal(moment.duration({days: 31}).months(), 1,  '31 days is a month');\n    assert.equal(moment.duration({days: 32}).days(),   1,  '32 days is 1 day left over');\n    assert.equal(moment.duration({days: 32}).months(), 1,  '32 days is a month');\n\n    assert.equal(moment.duration({hours: 23}).hours(), 23, '23 hours is 23 hours');\n    assert.equal(moment.duration({hours: 23}).days(),  0,  '23 hours makes no day');\n    assert.equal(moment.duration({hours: 24}).hours(), 0,  '24 hours is 0 hours left over');\n    assert.equal(moment.duration({hours: 24}).days(),  1,  '24 hours makes 1 day');\n    assert.equal(moment.duration({hours: 25}).hours(), 1,  '25 hours is 1 hour left over');\n    assert.equal(moment.duration({hours: 25}).days(),  1,  '25 hours makes 1 day');\n});\n\ntest('bubbling consistency', function (assert) {\n    var days = 0, months = 0, newDays, newMonths, totalDays, d;\n    for (totalDays = 1; totalDays <= 500; ++totalDays) {\n        d = moment.duration(totalDays, 'days');\n        newDays = d.days();\n        newMonths = d.months() + d.years() * 12;\n        assert.ok(\n                (months === newMonths && days + 1 === newDays) ||\n                (months + 1 === newMonths && newDays === 0),\n                'consistent total days ' + totalDays +\n                ' was ' + months + ' ' + days +\n                ' now ' + newMonths + ' ' + newDays);\n        days = newDays;\n        months = newMonths;\n    }\n});\n\ntest('effective equivalency', function (assert) {\n    assert.deepEqual(moment.duration({seconds: 1})._data,  moment.duration({milliseconds: 1000})._data, '1 second is the same as 1000 milliseconds');\n    assert.deepEqual(moment.duration({seconds: 60})._data, moment.duration({minutes: 1})._data,         '1 minute is the same as 60 seconds');\n    assert.deepEqual(moment.duration({minutes: 60})._data, moment.duration({hours: 1})._data,           '1 hour is the same as 60 minutes');\n    assert.deepEqual(moment.duration({hours: 24})._data,   moment.duration({days: 1})._data,            '1 day is the same as 24 hours');\n    assert.deepEqual(moment.duration({days: 7})._data,     moment.duration({weeks: 1})._data,           '1 week is the same as 7 days');\n    assert.deepEqual(moment.duration({days: 31})._data,    moment.duration({months: 1})._data,          '1 month is the same as 30 days');\n    assert.deepEqual(moment.duration({months: 12})._data,  moment.duration({years: 1})._data,           '1 years is the same as 12 months');\n});\n\ntest('asGetters', function (assert) {\n    // 400 years have exactly 146097 days\n\n    // years\n    assert.equal(moment.duration(1, 'year').asYears(),            1,           '1 year as years');\n    assert.equal(moment.duration(1, 'year').asMonths(),           12,          '1 year as months');\n    assert.equal(moment.duration(400, 'year').asMonths(),         4800,        '400 years as months');\n    assert.equal(moment.duration(1, 'year').asWeeks().toFixed(3), 52.143,      '1 year as weeks');\n    assert.equal(moment.duration(1, 'year').asDays(),             365,         '1 year as days');\n    assert.equal(moment.duration(2, 'year').asDays(),             730,         '2 years as days');\n    assert.equal(moment.duration(3, 'year').asDays(),             1096,        '3 years as days');\n    assert.equal(moment.duration(4, 'year').asDays(),             1461,        '4 years as days');\n    assert.equal(moment.duration(400, 'year').asDays(),           146097,      '400 years as days');\n    assert.equal(moment.duration(1, 'year').asHours(),            8760,        '1 year as hours');\n    assert.equal(moment.duration(1, 'year').asMinutes(),          525600,      '1 year as minutes');\n    assert.equal(moment.duration(1, 'year').asSeconds(),          31536000,    '1 year as seconds');\n    assert.equal(moment.duration(1, 'year').asMilliseconds(),     31536000000, '1 year as milliseconds');\n\n    // months\n    assert.equal(moment.duration(1, 'month').asYears().toFixed(4), 0.0833,     '1 month as years');\n    assert.equal(moment.duration(1, 'month').asMonths(),           1,          '1 month as months');\n    assert.equal(moment.duration(1, 'month').asWeeks().toFixed(3), 4.286,      '1 month as weeks');\n    assert.equal(moment.duration(1, 'month').asDays(),             30,         '1 month as days');\n    assert.equal(moment.duration(2, 'month').asDays(),             61,         '2 months as days');\n    assert.equal(moment.duration(3, 'month').asDays(),             91,         '3 months as days');\n    assert.equal(moment.duration(4, 'month').asDays(),             122,        '4 months as days');\n    assert.equal(moment.duration(5, 'month').asDays(),             152,        '5 months as days');\n    assert.equal(moment.duration(6, 'month').asDays(),             183,        '6 months as days');\n    assert.equal(moment.duration(7, 'month').asDays(),             213,        '7 months as days');\n    assert.equal(moment.duration(8, 'month').asDays(),             243,        '8 months as days');\n    assert.equal(moment.duration(9, 'month').asDays(),             274,        '9 months as days');\n    assert.equal(moment.duration(10, 'month').asDays(),            304,        '10 months as days');\n    assert.equal(moment.duration(11, 'month').asDays(),            335,        '11 months as days');\n    assert.equal(moment.duration(12, 'month').asDays(),            365,        '12 months as days');\n    assert.equal(moment.duration(24, 'month').asDays(),            730,        '24 months as days');\n    assert.equal(moment.duration(36, 'month').asDays(),            1096,       '36 months as days');\n    assert.equal(moment.duration(48, 'month').asDays(),            1461,       '48 months as days');\n    assert.equal(moment.duration(4800, 'month').asDays(),          146097,     '4800 months as days');\n    assert.equal(moment.duration(1, 'month').asHours(),            720,        '1 month as hours');\n    assert.equal(moment.duration(1, 'month').asMinutes(),          43200,      '1 month as minutes');\n    assert.equal(moment.duration(1, 'month').asSeconds(),          2592000,    '1 month as seconds');\n    assert.equal(moment.duration(1, 'month').asMilliseconds(),     2592000000, '1 month as milliseconds');\n\n    // weeks\n    assert.equal(moment.duration(1, 'week').asYears().toFixed(4),  0.0192,    '1 week as years');\n    assert.equal(moment.duration(1, 'week').asMonths().toFixed(3), 0.230,     '1 week as months');\n    assert.equal(moment.duration(1, 'week').asWeeks(),             1,         '1 week as weeks');\n    assert.equal(moment.duration(1, 'week').asDays(),              7,         '1 week as days');\n    assert.equal(moment.duration(1, 'week').asHours(),             168,       '1 week as hours');\n    assert.equal(moment.duration(1, 'week').asMinutes(),           10080,     '1 week as minutes');\n    assert.equal(moment.duration(1, 'week').asSeconds(),           604800,    '1 week as seconds');\n    assert.equal(moment.duration(1, 'week').asMilliseconds(),      604800000, '1 week as milliseconds');\n\n    // days\n    assert.equal(moment.duration(1, 'day').asYears().toFixed(4),  0.0027,   '1 day as years');\n    assert.equal(moment.duration(1, 'day').asMonths().toFixed(3), 0.033,    '1 day as months');\n    assert.equal(moment.duration(1, 'day').asWeeks().toFixed(3),  0.143,    '1 day as weeks');\n    assert.equal(moment.duration(1, 'day').asDays(),              1,        '1 day as days');\n    assert.equal(moment.duration(1, 'day').asHours(),             24,       '1 day as hours');\n    assert.equal(moment.duration(1, 'day').asMinutes(),           1440,     '1 day as minutes');\n    assert.equal(moment.duration(1, 'day').asSeconds(),           86400,    '1 day as seconds');\n    assert.equal(moment.duration(1, 'day').asMilliseconds(),      86400000, '1 day as milliseconds');\n\n    // hours\n    assert.equal(moment.duration(1, 'hour').asYears().toFixed(6),  0.000114, '1 hour as years');\n    assert.equal(moment.duration(1, 'hour').asMonths().toFixed(5), 0.00137,  '1 hour as months');\n    assert.equal(moment.duration(1, 'hour').asWeeks().toFixed(5),  0.00595,  '1 hour as weeks');\n    assert.equal(moment.duration(1, 'hour').asDays().toFixed(4),   0.0417,   '1 hour as days');\n    assert.equal(moment.duration(1, 'hour').asHours(),             1,        '1 hour as hours');\n    assert.equal(moment.duration(1, 'hour').asMinutes(),           60,       '1 hour as minutes');\n    assert.equal(moment.duration(1, 'hour').asSeconds(),           3600,     '1 hour as seconds');\n    assert.equal(moment.duration(1, 'hour').asMilliseconds(),      3600000,  '1 hour as milliseconds');\n\n    // minutes\n    assert.equal(moment.duration(1, 'minute').asYears().toFixed(8),  0.00000190, '1 minute as years');\n    assert.equal(moment.duration(1, 'minute').asMonths().toFixed(7), 0.0000228,  '1 minute as months');\n    assert.equal(moment.duration(1, 'minute').asWeeks().toFixed(7),  0.0000992,  '1 minute as weeks');\n    assert.equal(moment.duration(1, 'minute').asDays().toFixed(6),   0.000694,   '1 minute as days');\n    assert.equal(moment.duration(1, 'minute').asHours().toFixed(4),  0.0167,     '1 minute as hours');\n    assert.equal(moment.duration(1, 'minute').asMinutes(),           1,          '1 minute as minutes');\n    assert.equal(moment.duration(1, 'minute').asSeconds(),           60,         '1 minute as seconds');\n    assert.equal(moment.duration(1, 'minute').asMilliseconds(),      60000,      '1 minute as milliseconds');\n\n    // seconds\n    assert.equal(moment.duration(1, 'second').asYears().toFixed(10),  0.0000000317, '1 second as years');\n    assert.equal(moment.duration(1, 'second').asMonths().toFixed(9),  0.000000380,  '1 second as months');\n    assert.equal(moment.duration(1, 'second').asWeeks().toFixed(8),   0.00000165,   '1 second as weeks');\n    assert.equal(moment.duration(1, 'second').asDays().toFixed(7),    0.0000116,    '1 second as days');\n    assert.equal(moment.duration(1, 'second').asHours().toFixed(6),   0.000278,     '1 second as hours');\n    assert.equal(moment.duration(1, 'second').asMinutes().toFixed(4), 0.0167,       '1 second as minutes');\n    assert.equal(moment.duration(1, 'second').asSeconds(),            1,            '1 second as seconds');\n    assert.equal(moment.duration(1, 'second').asMilliseconds(),       1000,         '1 second as milliseconds');\n\n    // milliseconds\n    assert.equal(moment.duration(1, 'millisecond').asYears().toFixed(13),  0.0000000000317, '1 millisecond as years');\n    assert.equal(moment.duration(1, 'millisecond').asMonths().toFixed(12), 0.000000000380,  '1 millisecond as months');\n    assert.equal(moment.duration(1, 'millisecond').asWeeks().toFixed(11),  0.00000000165,   '1 millisecond as weeks');\n    assert.equal(moment.duration(1, 'millisecond').asDays().toFixed(10),   0.0000000116,    '1 millisecond as days');\n    assert.equal(moment.duration(1, 'millisecond').asHours().toFixed(9),   0.000000278,     '1 millisecond as hours');\n    assert.equal(moment.duration(1, 'millisecond').asMinutes().toFixed(7), 0.0000167,       '1 millisecond as minutes');\n    assert.equal(moment.duration(1, 'millisecond').asSeconds(),            0.001,           '1 millisecond as seconds');\n    assert.equal(moment.duration(1, 'millisecond').asMilliseconds(),       1,               '1 millisecond as milliseconds');\n});\n\ntest('as getters for small units', function (assert) {\n    var dS = moment.duration(1, 'milliseconds'),\n        ds = moment.duration(3, 'seconds'),\n        dm = moment.duration(13, 'minutes');\n\n    // Tests for issue #1867.\n    // Floating point errors for small duration units were introduced in version 2.8.0.\n    assert.equal(dS.as('milliseconds'), 1, 'as(\"milliseconds\")');\n    assert.equal(dS.asMilliseconds(),   1, 'asMilliseconds()');\n    assert.equal(ds.as('seconds'),      3, 'as(\"seconds\")');\n    assert.equal(ds.asSeconds(),        3, 'asSeconds()');\n    assert.equal(dm.as('minutes'),      13, 'as(\"minutes\")');\n    assert.equal(dm.asMinutes(),        13, 'asMinutes()');\n});\n\ntest('minutes getter for floating point hours', function (assert) {\n    // Tests for issue #2978.\n    // For certain floating point hours, .minutes() getter produced incorrect values due to the rounding errors\n    assert.equal(moment.duration(2.3, 'h').minutes(), 18, 'minutes()');\n    assert.equal(moment.duration(4.1, 'h').minutes(), 6, 'minutes()');\n});\n\ntest('isDuration', function (assert) {\n    assert.ok(moment.isDuration(moment.duration(12345678)), 'correctly says true');\n    assert.ok(!moment.isDuration(moment()), 'moment object is not a duration');\n    assert.ok(!moment.isDuration({milliseconds: 1}), 'plain object is not a duration');\n});\n\ntest('add', function (assert) {\n    var d = moment.duration({months: 4, weeks: 3, days: 2});\n    // for some reason, d._data._months does not get updated; use d._months instead.\n    assert.equal(d.add(1, 'month')._months, 5, 'Add months');\n    assert.equal(d.add(5, 'days')._days, 28, 'Add days');\n    assert.equal(d.add(10000)._milliseconds, 10000, 'Add milliseconds');\n    assert.equal(d.add({h: 23, m: 59})._milliseconds, 23 * 60 * 60 * 1000 + 59 * 60 * 1000 + 10000, 'Add hour:minute');\n});\n\ntest('add and bubble', function (assert) {\n    var d;\n\n    assert.equal(moment.duration(1, 'second').add(1000, 'milliseconds').seconds(), 2, 'Adding milliseconds should bubble up to seconds');\n    assert.equal(moment.duration(1, 'minute').add(60, 'second').minutes(), 2, 'Adding seconds should bubble up to minutes');\n    assert.equal(moment.duration(1, 'hour').add(60, 'minutes').hours(), 2, 'Adding minutes should bubble up to hours');\n    assert.equal(moment.duration(1, 'day').add(24, 'hours').days(), 2, 'Adding hours should bubble up to days');\n\n    d = moment.duration(-1, 'day').add(1, 'hour');\n    assert.equal(d.hours(), -23, '-1 day + 1 hour == -23 hour (component)');\n    assert.equal(d.asHours(), -23, '-1 day + 1 hour == -23 hours');\n\n    d = moment.duration(-1, 'year').add(1, 'day');\n    assert.equal(d.days(), -30, '- 1 year + 1 day == -30 days (component)');\n    assert.equal(d.months(), -11, '- 1 year + 1 day == -11 months (component)');\n    assert.equal(d.years(), 0, '- 1 year + 1 day == 0 years (component)');\n    assert.equal(d.asDays(), -364, '- 1 year + 1 day == -364 days');\n\n    d = moment.duration(-1, 'year').add(1, 'hour');\n    assert.equal(d.hours(), -23, '- 1 year + 1 hour == -23 hours (component)');\n    assert.equal(d.days(), -30, '- 1 year + 1 hour == -30 days (component)');\n    assert.equal(d.months(), -11, '- 1 year + 1 hour == -11 months (component)');\n    assert.equal(d.years(), 0, '- 1 year + 1 hour == 0 years (component)');\n});\n\ntest('subtract and bubble', function (assert) {\n    var d;\n\n    assert.equal(moment.duration(2, 'second').subtract(1000, 'milliseconds').seconds(), 1, 'Subtracting milliseconds should bubble up to seconds');\n    assert.equal(moment.duration(2, 'minute').subtract(60, 'second').minutes(), 1, 'Subtracting seconds should bubble up to minutes');\n    assert.equal(moment.duration(2, 'hour').subtract(60, 'minutes').hours(), 1, 'Subtracting minutes should bubble up to hours');\n    assert.equal(moment.duration(2, 'day').subtract(24, 'hours').days(), 1, 'Subtracting hours should bubble up to days');\n\n    d = moment.duration(1, 'day').subtract(1, 'hour');\n    assert.equal(d.hours(), 23, '1 day - 1 hour == 23 hour (component)');\n    assert.equal(d.asHours(), 23, '1 day - 1 hour == 23 hours');\n\n    d = moment.duration(1, 'year').subtract(1, 'day');\n    assert.equal(d.days(), 30, '1 year - 1 day == 30 days (component)');\n    assert.equal(d.months(), 11, '1 year - 1 day == 11 months (component)');\n    assert.equal(d.years(), 0, '1 year - 1 day == 0 years (component)');\n    assert.equal(d.asDays(), 364, '1 year - 1 day == 364 days');\n\n    d = moment.duration(1, 'year').subtract(1, 'hour');\n    assert.equal(d.hours(), 23, '1 year - 1 hour == 23 hours (component)');\n    assert.equal(d.days(), 30, '1 year - 1 hour == 30 days (component)');\n    assert.equal(d.months(), 11, '1 year - 1 hour == 11 months (component)');\n    assert.equal(d.years(), 0, '1 year - 1 hour == 0 years (component)');\n});\n\ntest('subtract', function (assert) {\n    var d = moment.duration({months: 2, weeks: 2, days: 0, hours: 5});\n    // for some reason, d._data._months does not get updated; use d._months instead.\n    assert.equal(d.subtract(1, 'months')._months, 1, 'Subtract months');\n    assert.equal(d.subtract(14, 'days')._days, 0, 'Subtract days');\n    assert.equal(d.subtract(10000)._milliseconds, 5 * 60 * 60 * 1000 - 10000, 'Subtract milliseconds');\n    assert.equal(d.subtract({h: 1, m: 59})._milliseconds, 3 * 60 * 60 * 1000 + 1 * 60 * 1000 - 10000, 'Subtract hour:minute');\n});\n\ntest('JSON.stringify duration', function (assert) {\n    var d = moment.duration(1024, 'h');\n\n    assert.equal(JSON.stringify(d), '\"' + d.toISOString() + '\"', 'JSON.stringify on duration should return ISO string');\n});\n\ntest('duration plugins', function (assert) {\n    var durationObject = moment.duration();\n    moment.duration.fn.foo = function (arg) {\n        assert.equal(this, durationObject);\n        assert.equal(arg, 5);\n    };\n    durationObject.foo(5);\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\nfunction module$1 (name, lifecycle) {\n    QUnit.module(name, {\n        setup : function () {\n            moment.locale('en');\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'core');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            teardownDeprecationHandler(test, moment, 'core');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n}\n\nmodule$1('duration from moments');\n\ntest('pure year diff', function (assert) {\n    var m1 = moment('2012-01-01T00:00:00.000Z'),\n        m2 = moment('2013-01-01T00:00:00.000Z');\n\n    assert.equal(moment.duration({from: m1, to: m2}).as('years'), 1, 'year moment difference');\n    assert.equal(moment.duration({from: m2, to: m1}).as('years'), -1, 'negative year moment difference');\n});\n\ntest('month and day diff', function (assert) {\n    var m1 = moment('2012-01-15T00:00:00.000Z'),\n        m2 = moment('2012-02-17T00:00:00.000Z'),\n        d = moment.duration({from: m1, to: m2});\n\n    assert.equal(d.get('days'), 2);\n    assert.equal(d.get('months'), 1);\n});\n\ntest('day diff, separate months', function (assert) {\n    var m1 = moment('2012-01-15T00:00:00.000Z'),\n        m2 = moment('2012-02-13T00:00:00.000Z'),\n        d = moment.duration({from: m1, to: m2});\n\n    assert.equal(d.as('days'), 29);\n});\n\ntest('hour diff', function (assert) {\n    var m1 = moment('2012-01-15T17:00:00.000Z'),\n        m2 = moment('2012-01-16T03:00:00.000Z'),\n        d = moment.duration({from: m1, to: m2});\n\n    assert.equal(d.as('hours'), 10);\n});\n\ntest('minute diff', function (assert) {\n    var m1 = moment('2012-01-15T17:45:00.000Z'),\n        m2 = moment('2012-01-16T03:15:00.000Z'),\n        d = moment.duration({from: m1, to: m2});\n\n    assert.equal(d.as('hours'), 9.5);\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\nfunction module$1 (name, lifecycle) {\n    QUnit.module(name, {\n        setup : function () {\n            moment.locale('en');\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'core');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            teardownDeprecationHandler(test, moment, 'core');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n}\n\nmodule$1('invalid');\n\ntest('invalid duration', function (assert) {\n    var m = moment.duration.invalid(); // should be invalid\n    assert.equal(m.isValid(), false);\n    assert.ok(isNaN(m.valueOf()));\n});\n\ntest('valid duration', function (assert) {\n    var m = moment.duration({d: null}); // should be valid, for now\n    assert.equal(m.isValid(), true);\n    assert.equal(m.valueOf(), 0);\n});\n\ntest('invalid duration - only smallest unit can have decimal', function (assert) {\n    var m = moment.duration({'days': 3.5, 'hours': 1.1}); // should be invalid\n    assert.equal(m.isValid(), false);\n    assert.ok(isNaN(m.valueOf())); // .valueOf() returns NaN for invalid durations\n});\n\ntest('valid duration - smallest unit can have decimal', function (assert) {\n    var m = moment.duration({'days': 3, 'hours': 1.1}); // should be valid\n    assert.equal(m.isValid(), true);\n    assert.equal(m.asHours(), 73.1);\n});\n\ntest('invalid duration with two arguments', function (assert) {\n    var m = moment.duration(NaN, 'days');\n    assert.equal(m.isValid(), false);\n    assert.ok(isNaN(m.valueOf()));\n});\n\ntest('invalid duration operations', function (assert) {\n    var invalids = [\n            moment.duration(NaN),\n            moment.duration(NaN, 'days'),\n            moment.duration.invalid()\n        ],\n        i,\n        invalid,\n        valid = moment.duration();\n\n    for (i = 0; i < invalids.length; ++i) {\n        invalid = invalids[i];\n\n        assert.ok(!invalid.add(5, 'hours').isValid(), 'invalid.add is invalid; i=' + i);\n        assert.ok(!invalid.subtract(30, 'days').isValid(), 'invalid.subtract is invalid; i=' + i);\n        assert.ok(!invalid.abs().isValid(), 'invalid.abs is invalid; i=' + i);\n        assert.ok(isNaN(invalid.as('years')), 'invalid.as is NaN; i=' + i);\n        assert.ok(isNaN(invalid.asMilliseconds()), 'invalid.asMilliseconds is NaN; i=' + i);\n        assert.ok(isNaN(invalid.asSeconds()), 'invalid.asSeconds is NaN; i=' + i);\n        assert.ok(isNaN(invalid.asMinutes()), 'invalid.asMinutes is NaN; i=' + i);\n        assert.ok(isNaN(invalid.asHours()), 'invalid.asHours is NaN; i=' + i);\n        assert.ok(isNaN(invalid.asDays()), 'invalid.asDays is NaN; i=' + i);\n        assert.ok(isNaN(invalid.asWeeks()), 'invalid.asWeeks is NaN; i=' + i);\n        assert.ok(isNaN(invalid.asMonths()), 'invalid.asMonths is NaN; i=' + i);\n        assert.ok(isNaN(invalid.asYears()), 'invalid.asYears is NaN; i=' + i);\n        assert.ok(isNaN(invalid.valueOf()), 'invalid.valueOf is NaN; i=' + i);\n        assert.ok(isNaN(invalid.get('hours')), 'invalid.get is NaN; i=' + i);\n\n        assert.ok(isNaN(invalid.milliseconds()), 'invalid.milliseconds is NaN; i=' + i);\n        assert.ok(isNaN(invalid.seconds()), 'invalid.seconds is NaN; i=' + i);\n        assert.ok(isNaN(invalid.minutes()), 'invalid.minutes is NaN; i=' + i);\n        assert.ok(isNaN(invalid.hours()), 'invalid.hours is NaN; i=' + i);\n        assert.ok(isNaN(invalid.days()), 'invalid.days is NaN; i=' + i);\n        assert.ok(isNaN(invalid.weeks()), 'invalid.weeks is NaN; i=' + i);\n        assert.ok(isNaN(invalid.months()), 'invalid.months is NaN; i=' + i);\n        assert.ok(isNaN(invalid.years()), 'invalid.years is NaN; i=' + i);\n\n        assert.equal(invalid.humanize(),\n                     invalid.localeData().invalidDate(),\n                     'invalid.humanize is localized invalid duration string; i=' + i);\n        assert.equal(invalid.toISOString(),\n                     invalid.localeData().invalidDate(),\n                     'invalid.toISOString is localized invalid duration string; i=' + i);\n        assert.equal(invalid.toString(),\n                     invalid.localeData().invalidDate(),\n                     'invalid.toString is localized invalid duration string; i=' + i);\n        assert.equal(invalid.toJSON(), invalid.localeData().invalidDate(), 'invalid.toJSON is null; i=' + i);\n        assert.equal(invalid.locale(), 'en', 'invalid.locale; i=' + i);\n        assert.equal(invalid.localeData()._abbr, 'en', 'invalid.localeData()._abbr; i=' + i);\n    }\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\nfunction module$1 (name, lifecycle) {\n    QUnit.module(name, {\n        setup : function () {\n            moment.locale('en');\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'core');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            teardownDeprecationHandler(test, moment, 'core');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n}\n\nmodule$1('format');\n\ntest('format YY', function (assert) {\n    var b = moment(new Date(2009, 1, 14, 15, 25, 50, 125));\n    assert.equal(b.format('YY'), '09', 'YY ---> 09');\n});\n\ntest('format escape brackets', function (assert) {\n    moment.locale('en');\n\n    var b = moment(new Date(2009, 1, 14, 15, 25, 50, 125));\n    assert.equal(b.format('[day]'), 'day', 'Single bracket');\n    assert.equal(b.format('[day] YY [YY]'), 'day 09 YY', 'Double bracket');\n    assert.equal(b.format('[YY'), '[09', 'Un-ended bracket');\n    assert.equal(b.format('[[YY]]'), '[YY]', 'Double nested brackets');\n    assert.equal(b.format('[[]'), '[', 'Escape open bracket');\n    assert.equal(b.format('[Last]'), 'Last', 'localized tokens');\n    assert.equal(b.format('[L] L'), 'L 02/14/2009', 'localized tokens with escaped localized tokens');\n    assert.equal(b.format('[L LL LLL LLLL aLa]'), 'L LL LLL LLLL aLa', 'localized tokens with escaped localized tokens');\n    assert.equal(b.format('[LLL] LLL'), 'LLL February 14, 2009 3:25 PM', 'localized tokens with escaped localized tokens (recursion)');\n    assert.equal(b.format('YYYY[\\n]DD[\\n]'), '2009\\n14\\n', 'Newlines');\n});\n\ntest('handle negative years', function (assert) {\n    moment.locale('en');\n    assert.equal(moment.utc().year(-1).format('YY'), '-01', 'YY with negative year');\n    assert.equal(moment.utc().year(-1).format('YYYY'), '-0001', 'YYYY with negative year');\n    assert.equal(moment.utc().year(-12).format('YY'), '-12', 'YY with negative year');\n    assert.equal(moment.utc().year(-12).format('YYYY'), '-0012', 'YYYY with negative year');\n    assert.equal(moment.utc().year(-123).format('YY'), '-23', 'YY with negative year');\n    assert.equal(moment.utc().year(-123).format('YYYY'), '-0123', 'YYYY with negative year');\n    assert.equal(moment.utc().year(-1234).format('YY'), '-34', 'YY with negative year');\n    assert.equal(moment.utc().year(-1234).format('YYYY'), '-1234', 'YYYY with negative year');\n    assert.equal(moment.utc().year(-12345).format('YY'), '-45', 'YY with negative year');\n    assert.equal(moment.utc().year(-12345).format('YYYY'), '-12345', 'YYYY with negative year');\n});\n\ntest('format milliseconds', function (assert) {\n    var b = moment(new Date(2009, 1, 14, 15, 25, 50, 123));\n    assert.equal(b.format('S'), '1', 'Deciseconds');\n    assert.equal(b.format('SS'), '12', 'Centiseconds');\n    assert.equal(b.format('SSS'), '123', 'Milliseconds');\n    b.milliseconds(789);\n    assert.equal(b.format('S'), '7', 'Deciseconds');\n    assert.equal(b.format('SS'), '78', 'Centiseconds');\n    assert.equal(b.format('SSS'), '789', 'Milliseconds');\n});\n\ntest('format timezone', function (assert) {\n    var b = moment(new Date(2010, 1, 14, 15, 25, 50, 125));\n    assert.ok(b.format('Z').match(/^[\\+\\-]\\d\\d:\\d\\d$/), b.format('Z') + ' should be something like \\'+07:30\\'');\n    assert.ok(b.format('ZZ').match(/^[\\+\\-]\\d{4}$/), b.format('ZZ') + ' should be something like \\'+0700\\'');\n});\n\ntest('format multiple with utc offset', function (assert) {\n    var b = moment('2012-10-08 -1200', ['YYYY-MM-DD HH:mm ZZ', 'YYYY-MM-DD ZZ', 'YYYY-MM-DD']);\n    assert.equal(b.format('YYYY-MM'), '2012-10', 'Parsing multiple formats should not crash with different sized formats');\n});\n\ntest('isDST', function (assert) {\n    var janOffset = new Date(2011, 0, 1).getTimezoneOffset(),\n        julOffset = new Date(2011, 6, 1).getTimezoneOffset(),\n        janIsDst = janOffset < julOffset,\n        julIsDst = julOffset < janOffset,\n        jan1 = moment([2011]),\n        jul1 = moment([2011, 6]);\n\n    if (janIsDst && julIsDst) {\n        assert.ok(0, 'January and July cannot both be in DST');\n        assert.ok(0, 'January and July cannot both be in DST');\n    } else if (janIsDst) {\n        assert.ok(jan1.isDST(), 'January 1 is DST');\n        assert.ok(!jul1.isDST(), 'July 1 is not DST');\n    } else if (julIsDst) {\n        assert.ok(!jan1.isDST(), 'January 1 is not DST');\n        assert.ok(jul1.isDST(), 'July 1 is DST');\n    } else {\n        assert.ok(!jan1.isDST(), 'January 1 is not DST');\n        assert.ok(!jul1.isDST(), 'July 1 is not DST');\n    }\n});\n\ntest('unix timestamp', function (assert) {\n    var m = moment('1234567890.123', 'X');\n    assert.equal(m.format('X'), '1234567890', 'unix timestamp without milliseconds');\n    assert.equal(m.format('X.S'), '1234567890.1', 'unix timestamp with deciseconds');\n    assert.equal(m.format('X.SS'), '1234567890.12', 'unix timestamp with centiseconds');\n    assert.equal(m.format('X.SSS'), '1234567890.123', 'unix timestamp with milliseconds');\n\n    m = moment(1234567890.123, 'X');\n    assert.equal(m.format('X'), '1234567890', 'unix timestamp as integer');\n});\n\ntest('unix offset milliseconds', function (assert) {\n    var m = moment('1234567890123', 'x');\n    assert.equal(m.format('x'), '1234567890123', 'unix offset in milliseconds');\n\n    m = moment(1234567890123, 'x');\n    assert.equal(m.format('x'), '1234567890123', 'unix offset in milliseconds as integer');\n});\n\ntest('utcOffset sanity checks', function (assert) {\n    assert.equal(moment().utcOffset() % 15, 0,\n            'utc offset should be a multiple of 15 (was ' + moment().utcOffset() + ')');\n\n    assert.equal(moment().utcOffset(), -(new Date()).getTimezoneOffset(),\n        'utcOffset should return the opposite of getTimezoneOffset');\n});\n\ntest('default format', function (assert) {\n    var isoRegex = /\\d{4}.\\d\\d.\\d\\dT\\d\\d.\\d\\d.\\d\\d[\\+\\-]\\d\\d:\\d\\d/;\n    assert.ok(isoRegex.exec(moment().format()), 'default format (' + moment().format() + ') should match ISO');\n});\n\ntest('default UTC format', function (assert) {\n    var isoRegex = /\\d{4}.\\d\\d.\\d\\dT\\d\\d.\\d\\d.\\d\\dZ/;\n    assert.ok(isoRegex.exec(moment.utc().format()), 'default UTC format (' + moment.utc().format() + ') should match ISO');\n});\n\ntest('toJSON', function (assert) {\n    var supportsJson = typeof JSON !== 'undefined' && JSON.stringify && JSON.stringify.call,\n        date = moment('2012-10-09T21:30:40.678+0100');\n\n    assert.equal(date.toJSON(), '2012-10-09T20:30:40.678Z', 'should output ISO8601 on moment.fn.toJSON');\n\n    if (supportsJson) {\n        assert.equal(JSON.stringify({\n            date : date\n        }), '{\"date\":\"2012-10-09T20:30:40.678Z\"}', 'should output ISO8601 on JSON.stringify');\n    }\n});\n\ntest('toISOString', function (assert) {\n    var date = moment.utc('2012-10-09T20:30:40.678');\n\n    assert.equal(date.toISOString(), '2012-10-09T20:30:40.678Z', 'should output ISO8601 on moment.fn.toISOString');\n\n    // big years\n    date = moment.utc('+020123-10-09T20:30:40.678');\n    assert.equal(date.toISOString(), '+020123-10-09T20:30:40.678Z', 'ISO8601 format on big positive year');\n    // negative years\n    date = moment.utc('-000001-10-09T20:30:40.678');\n    assert.equal(date.toISOString(), '-000001-10-09T20:30:40.678Z', 'ISO8601 format on negative year');\n    // big negative years\n    date = moment.utc('-020123-10-09T20:30:40.678');\n    assert.equal(date.toISOString(), '-020123-10-09T20:30:40.678Z', 'ISO8601 format on big negative year');\n\n    //invalid dates\n    date = moment.utc('2017-12-32');\n    assert.equal(date.toISOString(), null, 'An invalid date to iso string is null');\n});\n\n// See https://nodejs.org/dist/latest/docs/api/util.html#util_custom_inspect_function_on_objects\ntest('inspect', function (assert) {\n    function roundtrip(m) {\n        /*jshint evil:true */\n        return (new Function('moment', 'return ' + m.inspect()))(moment);\n    }\n    function testInspect(date, string) {\n        var inspected = date.inspect();\n        assert.equal(inspected, string);\n        assert.ok(date.isSame(roundtrip(date)), 'Tried to parse ' + inspected);\n    }\n\n    testInspect(\n        moment('2012-10-09T20:30:40.678'),\n        'moment(\"2012-10-09T20:30:40.678\")'\n    );\n    testInspect(\n        moment('+020123-10-09T20:30:40.678'),\n        'moment(\"+020123-10-09T20:30:40.678\")'\n    );\n    testInspect(\n        moment.utc('2012-10-09T20:30:40.678'),\n        'moment.utc(\"2012-10-09T20:30:40.678+00:00\")'\n    );\n    testInspect(\n        moment.utc('+020123-10-09T20:30:40.678'),\n        'moment.utc(\"+020123-10-09T20:30:40.678+00:00\")'\n    );\n    testInspect(\n        moment.utc('+020123-10-09T20:30:40.678+01:00'),\n        'moment.utc(\"+020123-10-09T19:30:40.678+00:00\")'\n    );\n    testInspect(\n        moment.parseZone('2016-06-11T17:30:40.678+0430'),\n        'moment.parseZone(\"2016-06-11T17:30:40.678+04:30\")'\n    );\n    testInspect(\n        moment.parseZone('+112016-06-11T17:30:40.678+0430'),\n        'moment.parseZone(\"+112016-06-11T17:30:40.678+04:30\")'\n    );\n\n    assert.equal(\n        moment(new Date('nope')).inspect(),\n        'moment.invalid(/* Invalid Date */)'\n    );\n    assert.equal(\n        moment('blah', 'YYYY').inspect(),\n        'moment.invalid(/* blah */)'\n    );\n});\n\ntest('long years', function (assert) {\n    assert.equal(moment.utc().year(2).format('YYYYYY'), '+000002', 'small year with YYYYYY');\n    assert.equal(moment.utc().year(2012).format('YYYYYY'), '+002012', 'regular year with YYYYYY');\n    assert.equal(moment.utc().year(20123).format('YYYYYY'), '+020123', 'big year with YYYYYY');\n\n    assert.equal(moment.utc().year(-1).format('YYYYYY'), '-000001', 'small negative year with YYYYYY');\n    assert.equal(moment.utc().year(-2012).format('YYYYYY'), '-002012', 'negative year with YYYYYY');\n    assert.equal(moment.utc().year(-20123).format('YYYYYY'), '-020123', 'big negative year with YYYYYY');\n});\n\ntest('toISOString() when 0 year', function (assert) {\n    // https://github.com/moment/moment/issues/3765\n    var date = moment('0000-01-01T21:00:00.000Z');\n    assert.equal(date.toISOString(), '0000-01-01T21:00:00.000Z');\n    assert.equal(date.toDate().toISOString(), '0000-01-01T21:00:00.000Z');\n});\n\ntest('iso week formats', function (assert) {\n    // https://en.wikipedia.org/wiki/ISO_week_date\n    var cases = {\n        '2005-01-02': '2004-53',\n        '2005-12-31': '2005-52',\n        '2007-01-01': '2007-01',\n        '2007-12-30': '2007-52',\n        '2007-12-31': '2008-01',\n        '2008-01-01': '2008-01',\n        '2008-12-28': '2008-52',\n        '2008-12-29': '2009-01',\n        '2008-12-30': '2009-01',\n        '2008-12-31': '2009-01',\n        '2009-01-01': '2009-01',\n        '2009-12-31': '2009-53',\n        '2010-01-01': '2009-53',\n        '2010-01-02': '2009-53',\n        '2010-01-03': '2009-53',\n        '404-12-31': '0404-53',\n        '405-12-31': '0405-52'\n    }, i, isoWeek, formatted2, formatted1;\n\n    for (i in cases) {\n        isoWeek = cases[i].split('-').pop();\n        formatted2 = moment(i, 'YYYY-MM-DD').format('WW');\n        assert.equal(isoWeek, formatted2, i + ': WW should be ' + isoWeek + ', but ' + formatted2);\n        isoWeek = isoWeek.replace(/^0+/, '');\n        formatted1 = moment(i, 'YYYY-MM-DD').format('W');\n        assert.equal(isoWeek, formatted1, i + ': W should be ' + isoWeek + ', but ' + formatted1);\n    }\n});\n\ntest('iso week year formats', function (assert) {\n    // https://en.wikipedia.org/wiki/ISO_week_date\n    var cases = {\n        '2005-01-02': '2004-53',\n        '2005-12-31': '2005-52',\n        '2007-01-01': '2007-01',\n        '2007-12-30': '2007-52',\n        '2007-12-31': '2008-01',\n        '2008-01-01': '2008-01',\n        '2008-12-28': '2008-52',\n        '2008-12-29': '2009-01',\n        '2008-12-30': '2009-01',\n        '2008-12-31': '2009-01',\n        '2009-01-01': '2009-01',\n        '2009-12-31': '2009-53',\n        '2010-01-01': '2009-53',\n        '2010-01-02': '2009-53',\n        '2010-01-03': '2009-53',\n        '404-12-31': '0404-53',\n        '405-12-31': '0405-52'\n    }, i, isoWeekYear, formatted5, formatted4, formatted2;\n\n    for (i in cases) {\n        isoWeekYear = cases[i].split('-')[0];\n        formatted5 = moment(i, 'YYYY-MM-DD').format('GGGGG');\n        assert.equal('0' + isoWeekYear, formatted5, i + ': GGGGG should be ' + isoWeekYear + ', but ' + formatted5);\n        formatted4 = moment(i, 'YYYY-MM-DD').format('GGGG');\n        assert.equal(isoWeekYear, formatted4, i + ': GGGG should be ' + isoWeekYear + ', but ' + formatted4);\n        formatted2 = moment(i, 'YYYY-MM-DD').format('GG');\n        assert.equal(isoWeekYear.slice(2, 4), formatted2, i + ': GG should be ' + isoWeekYear + ', but ' + formatted2);\n    }\n});\n\ntest('week year formats', function (assert) {\n    // https://en.wikipedia.org/wiki/ISO_week_date\n    var cases = {\n        '2005-01-02': '2004-53',\n        '2005-12-31': '2005-52',\n        '2007-01-01': '2007-01',\n        '2007-12-30': '2007-52',\n        '2007-12-31': '2008-01',\n        '2008-01-01': '2008-01',\n        '2008-12-28': '2008-52',\n        '2008-12-29': '2009-01',\n        '2008-12-30': '2009-01',\n        '2008-12-31': '2009-01',\n        '2009-01-01': '2009-01',\n        '2009-12-31': '2009-53',\n        '2010-01-01': '2009-53',\n        '2010-01-02': '2009-53',\n        '2010-01-03': '2009-53',\n        '404-12-31': '0404-53',\n        '405-12-31': '0405-52'\n    }, i, isoWeekYear, formatted5, formatted4, formatted2;\n\n    moment.defineLocale('dow:1,doy:4', {week: {dow: 1, doy: 4}});\n\n    for (i in cases) {\n        isoWeekYear = cases[i].split('-')[0];\n        formatted5 = moment(i, 'YYYY-MM-DD').format('ggggg');\n        assert.equal('0' + isoWeekYear, formatted5, i + ': ggggg should be ' + isoWeekYear + ', but ' + formatted5);\n        formatted4 = moment(i, 'YYYY-MM-DD').format('gggg');\n        assert.equal(isoWeekYear, formatted4, i + ': gggg should be ' + isoWeekYear + ', but ' + formatted4);\n        formatted2 = moment(i, 'YYYY-MM-DD').format('gg');\n        assert.equal(isoWeekYear.slice(2, 4), formatted2, i + ': gg should be ' + isoWeekYear + ', but ' + formatted2);\n    }\n    moment.defineLocale('dow:1,doy:4', null);\n});\n\ntest('iso weekday formats', function (assert) {\n    assert.equal(moment([1985, 1,  4]).format('E'), '1', 'Feb  4 1985 is Monday    -- 1st day');\n    assert.equal(moment([2029, 8, 18]).format('E'), '2', 'Sep 18 2029 is Tuesday   -- 2nd day');\n    assert.equal(moment([2013, 3, 24]).format('E'), '3', 'Apr 24 2013 is Wednesday -- 3rd day');\n    assert.equal(moment([2015, 2,  5]).format('E'), '4', 'Mar  5 2015 is Thursday  -- 4th day');\n    assert.equal(moment([1970, 0,  2]).format('E'), '5', 'Jan  2 1970 is Friday    -- 5th day');\n    assert.equal(moment([2001, 4, 12]).format('E'), '6', 'May 12 2001 is Saturday  -- 6th day');\n    assert.equal(moment([2000, 0,  2]).format('E'), '7', 'Jan  2 2000 is Sunday    -- 7th day');\n});\n\ntest('weekday formats', function (assert) {\n    moment.defineLocale('dow: 3,doy: 5', {week: {dow: 3, doy: 5}});\n    assert.equal(moment([1985, 1,  6]).format('e'), '0', 'Feb  6 1985 is Wednesday -- 0th day');\n    assert.equal(moment([2029, 8, 20]).format('e'), '1', 'Sep 20 2029 is Thursday  -- 1st day');\n    assert.equal(moment([2013, 3, 26]).format('e'), '2', 'Apr 26 2013 is Friday    -- 2nd day');\n    assert.equal(moment([2015, 2,  7]).format('e'), '3', 'Mar  7 2015 is Saturday  -- 3nd day');\n    assert.equal(moment([1970, 0,  4]).format('e'), '4', 'Jan  4 1970 is Sunday    -- 4th day');\n    assert.equal(moment([2001, 4, 14]).format('e'), '5', 'May 14 2001 is Monday    -- 5th day');\n    assert.equal(moment([2000, 0,  4]).format('e'), '6', 'Jan  4 2000 is Tuesday   -- 6th day');\n    moment.defineLocale('dow: 3,doy: 5', null);\n});\n\ntest('toString is just human readable format', function (assert) {\n    var b = moment(new Date(2009, 1, 5, 15, 25, 50, 125));\n    assert.equal(b.toString(), b.format('ddd MMM DD YYYY HH:mm:ss [GMT]ZZ'));\n});\n\ntest('toJSON skips postformat', function (assert) {\n    moment.defineLocale('postformat', {\n        postformat: function (s) {\n            s.replace(/./g, 'X');\n        }\n    });\n    assert.equal(moment.utc([2000, 0, 1]).toJSON(), '2000-01-01T00:00:00.000Z', 'toJSON doesn\\'t postformat');\n    moment.defineLocale('postformat', null);\n});\n\ntest('calendar day timezone', function (assert) {\n    moment.locale('en');\n    var zones = [60, -60, 90, -90, 360, -360, 720, -720],\n        b = moment().utc().startOf('day').subtract({m : 1}),\n        c = moment().local().startOf('day').subtract({m : 1}),\n        d = moment().local().startOf('day').subtract({d : 2}),\n        i, z, a;\n\n    for (i = 0; i < zones.length; ++i) {\n        z = zones[i];\n        a = moment().utcOffset(z).startOf('day').subtract({m: 1});\n        assert.equal(moment(a).utcOffset(z).calendar(), 'Yesterday at 11:59 PM',\n                     'Yesterday at 11:59 PM, not Today, or the wrong time, tz = ' + z);\n    }\n\n    assert.equal(moment(b).utc().calendar(), 'Yesterday at 11:59 PM', 'Yesterday at 11:59 PM, not Today, or the wrong time');\n    assert.equal(moment(c).local().calendar(), 'Yesterday at 11:59 PM', 'Yesterday at 11:59 PM, not Today, or the wrong time');\n    assert.equal(moment(c).local().calendar(d), 'Tomorrow at 11:59 PM', 'Tomorrow at 11:59 PM, not Yesterday, or the wrong time');\n});\n\ntest('calendar with custom formats', function (assert) {\n    assert.equal(moment().calendar(null, {sameDay: '[Today]'}), 'Today', 'Today');\n    assert.equal(moment().add(1, 'days').calendar(null, {nextDay: '[Tomorrow]'}), 'Tomorrow', 'Tomorrow');\n    assert.equal(moment([1985, 1, 4]).calendar(null, {sameElse: 'YYYY-MM-DD'}), '1985-02-04', 'Else');\n});\n\ntest('invalid', function (assert) {\n    assert.equal(moment.invalid().format(), 'Invalid date');\n    assert.equal(moment.invalid().format('YYYY-MM-DD'), 'Invalid date');\n});\n\ntest('quarter formats', function (assert) {\n    assert.equal(moment([1985, 1,  4]).format('Q'), '1', 'Feb  4 1985 is Q1');\n    assert.equal(moment([2029, 8, 18]).format('Q'), '3', 'Sep 18 2029 is Q3');\n    assert.equal(moment([2013, 3, 24]).format('Q'), '2', 'Apr 24 2013 is Q2');\n    assert.equal(moment([2015, 2,  5]).format('Q'), '1', 'Mar  5 2015 is Q1');\n    assert.equal(moment([1970, 0,  2]).format('Q'), '1', 'Jan  2 1970 is Q1');\n    assert.equal(moment([2001, 11, 12]).format('Q'), '4', 'Dec 12 2001 is Q4');\n    assert.equal(moment([2000, 0,  2]).format('[Q]Q-YYYY'), 'Q1-2000', 'Jan  2 2000 is Q1');\n});\n\ntest('quarter ordinal formats', function (assert) {\n    assert.equal(moment([1985, 1, 4]).format('Qo'), '1st', 'Feb 4 1985 is 1st quarter');\n    assert.equal(moment([2029, 8, 18]).format('Qo'), '3rd', 'Sep 18 2029 is 3rd quarter');\n    assert.equal(moment([2013, 3, 24]).format('Qo'), '2nd', 'Apr 24 2013 is 2nd quarter');\n    assert.equal(moment([2015, 2,  5]).format('Qo'), '1st', 'Mar  5 2015 is 1st quarter');\n    assert.equal(moment([1970, 0,  2]).format('Qo'), '1st', 'Jan  2 1970 is 1st quarter');\n    assert.equal(moment([2001, 11, 12]).format('Qo'), '4th', 'Dec 12 2001 is 4th quarter');\n    assert.equal(moment([2000, 0,  2]).format('Qo [quarter] YYYY'), '1st quarter 2000', 'Jan  2 2000 is 1st quarter');\n});\n\n// test('full expanded format is returned from abbreviated formats', function (assert) {\n//     function objectKeys(obj) {\n//         if (Object.keys) {\n//             return Object.keys(obj);\n//         } else {\n//             // IE8\n//             var res = [], i;\n//             for (i in obj) {\n//                 if (obj.hasOwnProperty(i)) {\n//                     res.push(i);\n//                 }\n//             }\n//             return res;\n//         }\n//     }\n\n//     var locales =\n//         'ar-sa ar-tn ar az be bg bn bo br bs ca cs cv cy da de-at de dv el ' +\n//         'en-au en-ca en-gb en-ie en-nz eo es et eu fa fi fo fr-ca fr-ch fr fy ' +\n//         'gd gl he hi hr hu hy-am id is it ja jv ka kk km ko lb lo lt lv me mk ml ' +\n//         'mr ms-my ms my nb ne nl nn pl pt-br pt ro ru se si sk sl sq sr-cyrl ' +\n//         'sr sv sw ta te th tl-ph tlh tr tzl tzm-latn tzm uk uz vi zh-cn zh-tw';\n\n//     each(locales.split(' '), function (locale) {\n//         var data, tokens;\n//         data = moment().locale(locale).localeData()._longDateFormat;\n//         tokens = objectKeys(data);\n//         each(tokens, function (token) {\n//             // Check each format string to make sure it does not contain any\n//             // tokens that need to be expanded.\n//             each(tokens, function (i) {\n//                 // strip escaped sequences\n//                 var format = data[i].replace(/(\\[[^\\]]*\\])/g, '');\n//                 assert.equal(false, !!~format.indexOf(token), 'locale ' + locale + ' contains ' + token + ' in ' + i);\n//             });\n//         });\n//     });\n// });\n\ntest('milliseconds', function (assert) {\n    var m = moment('123', 'SSS');\n\n    assert.equal(m.format('S'), '1');\n    assert.equal(m.format('SS'), '12');\n    assert.equal(m.format('SSS'), '123');\n    assert.equal(m.format('SSSS'), '1230');\n    assert.equal(m.format('SSSSS'), '12300');\n    assert.equal(m.format('SSSSSS'), '123000');\n    assert.equal(m.format('SSSSSSS'), '1230000');\n    assert.equal(m.format('SSSSSSSS'), '12300000');\n    assert.equal(m.format('SSSSSSSSS'), '123000000');\n});\n\ntest('hmm and hmmss', function (assert) {\n    assert.equal(moment('12:34:56', 'HH:mm:ss').format('hmm'), '1234');\n    assert.equal(moment('01:34:56', 'HH:mm:ss').format('hmm'), '134');\n    assert.equal(moment('13:34:56', 'HH:mm:ss').format('hmm'), '134');\n\n    assert.equal(moment('12:34:56', 'HH:mm:ss').format('hmmss'), '123456');\n    assert.equal(moment('01:34:56', 'HH:mm:ss').format('hmmss'), '13456');\n    assert.equal(moment('13:34:56', 'HH:mm:ss').format('hmmss'), '13456');\n});\n\ntest('Hmm and Hmmss', function (assert) {\n    assert.equal(moment('12:34:56', 'HH:mm:ss').format('Hmm'), '1234');\n    assert.equal(moment('01:34:56', 'HH:mm:ss').format('Hmm'), '134');\n    assert.equal(moment('13:34:56', 'HH:mm:ss').format('Hmm'), '1334');\n\n    assert.equal(moment('12:34:56', 'HH:mm:ss').format('Hmmss'), '123456');\n    assert.equal(moment('01:34:56', 'HH:mm:ss').format('Hmmss'), '13456');\n    assert.equal(moment('08:34:56', 'HH:mm:ss').format('Hmmss'), '83456');\n    assert.equal(moment('18:34:56', 'HH:mm:ss').format('Hmmss'), '183456');\n});\n\ntest('k and kk', function (assert) {\n    assert.equal(moment('01:23:45', 'HH:mm:ss').format('k'), '1');\n    assert.equal(moment('12:34:56', 'HH:mm:ss').format('k'), '12');\n    assert.equal(moment('01:23:45', 'HH:mm:ss').format('kk'), '01');\n    assert.equal(moment('12:34:56', 'HH:mm:ss').format('kk'), '12');\n    assert.equal(moment('00:34:56', 'HH:mm:ss').format('kk'), '24');\n    assert.equal(moment('00:00:00', 'HH:mm:ss').format('kk'), '24');\n});\n\ntest('Y token', function (assert) {\n    assert.equal(moment('2010-01-01', 'YYYY-MM-DD', true).format('Y'), '2010', 'format 2010 with Y');\n    assert.equal(moment('-123-01-01', 'Y-MM-DD', true).format('Y'), '-123', 'format -123 with Y');\n    assert.equal(moment('12345-01-01', 'Y-MM-DD', true).format('Y'), '+12345', 'format 12345 with Y');\n    assert.equal(moment('0-01-01', 'Y-MM-DD', true).format('Y'), '0', 'format 0 with Y');\n    assert.equal(moment('1-01-01', 'Y-MM-DD', true).format('Y'), '1', 'format 1 with Y');\n    assert.equal(moment('9999-01-01', 'Y-MM-DD', true).format('Y'), '9999', 'format 9999 with Y');\n    assert.equal(moment('10000-01-01', 'Y-MM-DD', true).format('Y'), '+10000', 'format 10000 with Y');\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\nfunction module$1 (name, lifecycle) {\n    QUnit.module(name, {\n        setup : function () {\n            moment.locale('en');\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'core');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            teardownDeprecationHandler(test, moment, 'core');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n}\n\nmodule$1('from_to');\n\ntest('from', function (assert) {\n    var start = moment();\n    moment.locale('en');\n    assert.equal(start.from(start.clone().add(5, 'seconds')),  'a few seconds ago', '5 seconds = a few seconds ago');\n    assert.equal(start.from(start.clone().add(1, 'minute')),  'a minute ago', '1 minute = a minute ago');\n    assert.equal(start.from(start.clone().add(5, 'minutes')),  '5 minutes ago', '5 minutes = 5 minutes ago');\n\n    assert.equal(start.from(start.clone().subtract(5, 'seconds')),  'in a few seconds', '5 seconds = in a few seconds');\n    assert.equal(start.from(start.clone().subtract(1, 'minute')),  'in a minute', '1 minute = in a minute');\n    assert.equal(start.from(start.clone().subtract(5, 'minutes')),  'in 5 minutes', '5 minutes = in 5 minutes');\n});\n\ntest('from with absolute duration', function (assert) {\n    var start = moment();\n    moment.locale('en');\n    assert.equal(start.from(start.clone().add(5, 'seconds'), true),  'a few seconds', '5 seconds = a few seconds');\n    assert.equal(start.from(start.clone().add(1, 'minute'), true),  'a minute', '1 minute = a minute');\n    assert.equal(start.from(start.clone().add(5, 'minutes'), true),  '5 minutes', '5 minutes = 5 minutes');\n\n    assert.equal(start.from(start.clone().subtract(5, 'seconds'), true),  'a few seconds', '5 seconds = a few seconds');\n    assert.equal(start.from(start.clone().subtract(1, 'minute'), true),  'a minute', '1 minute = a minute');\n    assert.equal(start.from(start.clone().subtract(5, 'minutes'), true),  '5 minutes', '5 minutes = 5 minutes');\n});\n\ntest('to', function (assert) {\n    var start = moment();\n    moment.locale('en');\n    assert.equal(start.to(start.clone().subtract(5, 'seconds')),  'a few seconds ago', '5 seconds = a few seconds ago');\n    assert.equal(start.to(start.clone().subtract(1, 'minute')),  'a minute ago', '1 minute = a minute ago');\n    assert.equal(start.to(start.clone().subtract(5, 'minutes')),  '5 minutes ago', '5 minutes = 5 minutes ago');\n\n    assert.equal(start.to(start.clone().add(5, 'seconds')),  'in a few seconds', '5 seconds = in a few seconds');\n    assert.equal(start.to(start.clone().add(1, 'minute')),  'in a minute', '1 minute = in a minute');\n    assert.equal(start.to(start.clone().add(5, 'minutes')),  'in 5 minutes', '5 minutes = in 5 minutes');\n});\n\ntest('to with absolute duration', function (assert) {\n    var start = moment();\n    moment.locale('en');\n    assert.equal(start.to(start.clone().add(5, 'seconds'), true),  'a few seconds', '5 seconds = a few seconds');\n    assert.equal(start.to(start.clone().add(1, 'minute'), true),  'a minute', '1 minute = a minute');\n    assert.equal(start.to(start.clone().add(5, 'minutes'), true),  '5 minutes', '5 minutes = 5 minutes');\n\n    assert.equal(start.to(start.clone().subtract(5, 'seconds'), true),  'a few seconds', '5 seconds = a few seconds');\n    assert.equal(start.to(start.clone().subtract(1, 'minute'), true),  'a minute', '1 minute = a minute');\n    assert.equal(start.to(start.clone().subtract(5, 'minutes'), true),  '5 minutes', '5 minutes = 5 minutes');\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\nfunction module$1 (name, lifecycle) {\n    QUnit.module(name, {\n        setup : function () {\n            moment.locale('en');\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'core');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            teardownDeprecationHandler(test, moment, 'core');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n}\n\nmodule$1('getters and setters');\n\ntest('getters', function (assert) {\n    var a = moment([2011, 9, 12, 6, 7, 8, 9]);\n    assert.equal(a.year(), 2011, 'year');\n    assert.equal(a.month(), 9, 'month');\n    assert.equal(a.date(), 12, 'date');\n    assert.equal(a.day(), 3, 'day');\n    assert.equal(a.hours(), 6, 'hour');\n    assert.equal(a.minutes(), 7, 'minute');\n    assert.equal(a.seconds(), 8, 'second');\n    assert.equal(a.milliseconds(), 9, 'milliseconds');\n});\n\ntest('getters programmatic', function (assert) {\n    var a = moment([2011, 9, 12, 6, 7, 8, 9]);\n    assert.equal(a.get('year'), 2011, 'year');\n    assert.equal(a.get('month'), 9, 'month');\n    assert.equal(a.get('date'), 12, 'date');\n    assert.equal(a.get('day'), 3, 'day');\n    assert.equal(a.get('hour'), 6, 'hour');\n    assert.equal(a.get('minute'), 7, 'minute');\n    assert.equal(a.get('second'), 8, 'second');\n    assert.equal(a.get('milliseconds'), 9, 'milliseconds');\n\n    //actual getters tested elsewhere\n    assert.equal(a.get('weekday'), a.weekday(), 'weekday');\n    assert.equal(a.get('isoWeekday'), a.isoWeekday(), 'isoWeekday');\n    assert.equal(a.get('week'), a.week(), 'week');\n    assert.equal(a.get('isoWeek'), a.isoWeek(), 'isoWeek');\n    assert.equal(a.get('dayOfYear'), a.dayOfYear(), 'dayOfYear');\n\n    //getter no longer sets values when passed an object\n    assert.equal(moment([2016,0,1]).get({year:2015}).year(), 2016, 'getter no longer sets values when passed an object');\n});\n\ntest('setters plural', function (assert) {\n    var a = moment();\n    test.expectedDeprecations('years accessor', 'months accessor', 'dates accessor');\n\n    a.years(2011);\n    a.months(9);\n    a.dates(12);\n    a.hours(6);\n    a.minutes(7);\n    a.seconds(8);\n    a.milliseconds(9);\n    assert.equal(a.years(), 2011, 'years');\n    assert.equal(a.months(), 9, 'months');\n    assert.equal(a.dates(), 12, 'dates');\n    assert.equal(a.days(), 3, 'days');\n    assert.equal(a.hours(), 6, 'hours');\n    assert.equal(a.minutes(), 7, 'minutes');\n    assert.equal(a.seconds(), 8, 'seconds');\n    assert.equal(a.milliseconds(), 9, 'milliseconds');\n});\n\ntest('setters singular', function (assert) {\n    var a = moment();\n    a.year(2011);\n    a.month(9);\n    a.date(12);\n    a.hour(6);\n    a.minute(7);\n    a.second(8);\n    a.millisecond(9);\n    assert.equal(a.year(), 2011, 'year');\n    assert.equal(a.month(), 9, 'month');\n    assert.equal(a.date(), 12, 'date');\n    assert.equal(a.day(), 3, 'day');\n    assert.equal(a.hour(), 6, 'hour');\n    assert.equal(a.minute(), 7, 'minute');\n    assert.equal(a.second(), 8, 'second');\n    assert.equal(a.millisecond(), 9, 'milliseconds');\n});\n\ntest('setters', function (assert) {\n    var a = moment();\n    a.year(2011);\n    a.month(9);\n    a.date(12);\n    a.hours(6);\n    a.minutes(7);\n    a.seconds(8);\n    a.milliseconds(9);\n    assert.equal(a.year(), 2011, 'year');\n    assert.equal(a.month(), 9, 'month');\n    assert.equal(a.date(), 12, 'date');\n    assert.equal(a.day(), 3, 'day');\n    assert.equal(a.hours(), 6, 'hour');\n    assert.equal(a.minutes(), 7, 'minute');\n    assert.equal(a.seconds(), 8, 'second');\n    assert.equal(a.milliseconds(), 9, 'milliseconds');\n\n    // Test month() behavior. See https://github.com/timrwood/moment/pull/822\n    a = moment('20130531', 'YYYYMMDD');\n    a.month(3);\n    assert.equal(a.month(), 3, 'month edge case');\n});\n\ntest('setter programmatic', function (assert) {\n    var a = moment();\n    a.set('year', 2011);\n    a.set('month', 9);\n    a.set('date', 12);\n    a.set('hours', 6);\n    a.set('minutes', 7);\n    a.set('seconds', 8);\n    a.set('milliseconds', 9);\n    assert.equal(a.year(), 2011, 'year');\n    assert.equal(a.month(), 9, 'month');\n    assert.equal(a.date(), 12, 'date');\n    assert.equal(a.day(), 3, 'day');\n    assert.equal(a.hours(), 6, 'hour');\n    assert.equal(a.minutes(), 7, 'minute');\n    assert.equal(a.seconds(), 8, 'second');\n    assert.equal(a.milliseconds(), 9, 'milliseconds');\n\n    // Test month() behavior. See https://github.com/timrwood/moment/pull/822\n    a = moment('20130531', 'YYYYMMDD');\n    a.month(3);\n    assert.equal(a.month(), 3, 'month edge case');\n});\n\ntest('setters programatic with weeks', function (assert) {\n    var a = moment();\n    a.set('weekYear', 2001);\n    a.set('week', 49);\n    a.set('day', 4);\n\n    assert.equal(a.weekYear(), 2001, 'weekYear');\n    assert.equal(a.week(), 49, 'week');\n    assert.equal(a.day(), 4, 'day');\n\n    a.set('weekday', 1);\n    assert.equal(a.weekday(), 1, 'weekday');\n});\n\ntest('setters programatic with weeks ISO', function (assert) {\n    var a = moment();\n    a.set('isoWeekYear', 2001);\n    a.set('isoWeek', 49);\n    a.set('isoWeekday', 4);\n\n    assert.equal(a.isoWeekYear(), 2001, 'isoWeekYear');\n    assert.equal(a.isoWeek(), 49, 'isoWeek');\n    assert.equal(a.isoWeekday(), 4, 'isoWeekday');\n});\n\ntest('setters strings', function (assert) {\n    var a = moment([2012]).locale('en');\n    assert.equal(a.clone().day(0).day('Wednesday').day(), 3, 'day full name');\n    assert.equal(a.clone().day(0).day('Wed').day(), 3, 'day short name');\n    assert.equal(a.clone().day(0).day('We').day(), 3, 'day minimal name');\n    assert.equal(a.clone().day(0).day('invalid').day(), 0, 'invalid day name');\n    assert.equal(a.clone().month(0).month('April').month(), 3, 'month full name');\n    assert.equal(a.clone().month(0).month('Apr').month(), 3, 'month short name');\n    assert.equal(a.clone().month(0).month('invalid').month(), 0, 'invalid month name');\n});\n\ntest('setters - falsey values', function (assert) {\n    var a = moment();\n    // ensure minutes wasn't coincidentally 0 already\n    a.minutes(1);\n    a.minutes(0);\n    assert.equal(a.minutes(), 0, 'falsey value');\n});\n\ntest('chaining setters', function (assert) {\n    var a = moment();\n    a.year(2011)\n     .month(9)\n     .date(12)\n     .hours(6)\n     .minutes(7)\n     .seconds(8);\n    assert.equal(a.year(), 2011, 'year');\n    assert.equal(a.month(), 9, 'month');\n    assert.equal(a.date(), 12, 'date');\n    assert.equal(a.day(), 3, 'day');\n    assert.equal(a.hours(), 6, 'hour');\n    assert.equal(a.minutes(), 7, 'minute');\n    assert.equal(a.seconds(), 8, 'second');\n});\n\ntest('setter with multiple unit values', function (assert) {\n    var a = moment();\n    a.set({\n        year: 2011,\n        month: 9,\n        date: 12,\n        hours: 6,\n        minutes: 7,\n        seconds: 8,\n        milliseconds: 9\n    });\n    assert.equal(a.year(), 2011, 'year');\n    assert.equal(a.month(), 9, 'month');\n    assert.equal(a.date(), 12, 'date');\n    assert.equal(a.day(), 3, 'day');\n    assert.equal(a.hours(), 6, 'hour');\n    assert.equal(a.minutes(), 7, 'minute');\n    assert.equal(a.seconds(), 8, 'second');\n    assert.equal(a.milliseconds(), 9, 'milliseconds');\n\n    var c = moment([2016,0,1]);\n    assert.equal(c.set({weekYear: 2016}).weekYear(), 2016, 'week year correctly sets with object syntax');\n    assert.equal(c.set({quarter: 3}).quarter(), 3, 'quarter sets correctly with object syntax');\n});\n\ntest('day setter', function (assert) {\n    var a = moment([2011, 0, 15]);\n    assert.equal(moment(a).day(0).date(), 9, 'set from saturday to sunday');\n    assert.equal(moment(a).day(6).date(), 15, 'set from saturday to saturday');\n    assert.equal(moment(a).day(3).date(), 12, 'set from saturday to wednesday');\n\n    a = moment([2011, 0, 9]);\n    assert.equal(moment(a).day(0).date(), 9, 'set from sunday to sunday');\n    assert.equal(moment(a).day(6).date(), 15, 'set from sunday to saturday');\n    assert.equal(moment(a).day(3).date(), 12, 'set from sunday to wednesday');\n\n    a = moment([2011, 0, 12]);\n    assert.equal(moment(a).day(0).date(), 9, 'set from wednesday to sunday');\n    assert.equal(moment(a).day(6).date(), 15, 'set from wednesday to saturday');\n    assert.equal(moment(a).day(3).date(), 12, 'set from wednesday to wednesday');\n\n    assert.equal(moment(a).day(-7).date(), 2, 'set from wednesday to last sunday');\n    assert.equal(moment(a).day(-1).date(), 8, 'set from wednesday to last saturday');\n    assert.equal(moment(a).day(-4).date(), 5, 'set from wednesday to last wednesday');\n\n    assert.equal(moment(a).day(7).date(), 16, 'set from wednesday to next sunday');\n    assert.equal(moment(a).day(13).date(), 22, 'set from wednesday to next saturday');\n    assert.equal(moment(a).day(10).date(), 19, 'set from wednesday to next wednesday');\n\n    assert.equal(moment(a).day(14).date(), 23, 'set from wednesday to second next sunday');\n    assert.equal(moment(a).day(20).date(), 29, 'set from wednesday to second next saturday');\n    assert.equal(moment(a).day(17).date(), 26, 'set from wednesday to second next wednesday');\n});\n\ntest('object set ordering', function (assert) {\n    var a = moment([2016,3,30]);\n    assert.equal(a.set({date:31, month:4}).date(), 31, 'setter order automatically arranged by size');\n    var b = moment([2015,1,28]);\n    assert.equal(b.set({date:29, year: 2016}).format('YYYY-MM-DD'), '2016-02-29', 'year is prioritized over date');\n    //check a nonexistent time in US isn't set\n    var c = moment([2016,2,13]);\n    c.set({\n        hour:2,\n        minutes:30,\n        date: 14\n    });\n    assert.equal(c.format('YYYY-MM-DDTHH:mm'), '2016-03-14T02:30', 'setting hours, minutes date puts date first allowing time set to work');\n});\n\ntest('string setters', function (assert) {\n    var a = moment();\n    a.year('2011');\n    a.month('9');\n    a.date('12');\n    a.hours('6');\n    a.minutes('7');\n    a.seconds('8');\n    a.milliseconds('9');\n    assert.equal(a.year(), 2011, 'year');\n    assert.equal(a.month(), 9, 'month');\n    assert.equal(a.date(), 12, 'date');\n    assert.equal(a.day(), 3, 'day');\n    assert.equal(a.hours(), 6, 'hour');\n    assert.equal(a.minutes(), 7, 'minute');\n    assert.equal(a.seconds(), 8, 'second');\n    assert.equal(a.milliseconds(), 9, 'milliseconds');\n});\n\ntest('setters across DST +1', function (assert) {\n    var oldUpdateOffset = moment.updateOffset,\n        // Based on a real story somewhere in America/Los_Angeles\n        dstAt = moment('2014-03-09T02:00:00-08:00').parseZone(),\n        m;\n\n    moment.updateOffset = function (mom, keepTime) {\n        if (mom.isBefore(dstAt)) {\n            mom.utcOffset(-8, keepTime);\n        } else {\n            mom.utcOffset(-7, keepTime);\n        }\n    };\n\n    m = moment('2014-03-15T00:00:00-07:00').parseZone();\n    m.year(2013);\n    assert.equal(m.format(), '2013-03-15T00:00:00-08:00', 'year across +1');\n\n    m = moment('2014-03-15T00:00:00-07:00').parseZone();\n    m.month(0);\n    assert.equal(m.format(), '2014-01-15T00:00:00-08:00', 'month across +1');\n\n    m = moment('2014-03-15T00:00:00-07:00').parseZone();\n    m.date(1);\n    assert.equal(m.format(), '2014-03-01T00:00:00-08:00', 'date across +1');\n\n    m = moment('2014-03-09T03:05:00-07:00').parseZone();\n    m.hour(0);\n    assert.equal(m.format(), '2014-03-09T00:05:00-08:00', 'hour across +1');\n\n    moment.updateOffset = oldUpdateOffset;\n});\n\ntest('setters across DST -1', function (assert) {\n    var oldUpdateOffset = moment.updateOffset,\n        // Based on a real story somewhere in America/Los_Angeles\n        dstAt = moment('2014-11-02T02:00:00-07:00').parseZone(),\n        m;\n\n    moment.updateOffset = function (mom, keepTime) {\n        if (mom.isBefore(dstAt)) {\n            mom.utcOffset(-7, keepTime);\n        } else {\n            mom.utcOffset(-8, keepTime);\n        }\n    };\n\n    m = moment('2014-11-15T00:00:00-08:00').parseZone();\n    m.year(2013);\n    assert.equal(m.format(), '2013-11-15T00:00:00-07:00', 'year across -1');\n\n    m = moment('2014-11-15T00:00:00-08:00').parseZone();\n    m.month(0);\n    assert.equal(m.format(), '2014-01-15T00:00:00-07:00', 'month across -1');\n\n    m = moment('2014-11-15T00:00:00-08:00').parseZone();\n    m.date(1);\n    assert.equal(m.format(), '2014-11-01T00:00:00-07:00', 'date across -1');\n\n    m = moment('2014-11-02T03:30:00-08:00').parseZone();\n    m.hour(0);\n    assert.equal(m.format(), '2014-11-02T00:30:00-07:00', 'hour across -1');\n\n    moment.updateOffset = oldUpdateOffset;\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\nfunction module$1 (name, lifecycle) {\n    QUnit.module(name, {\n        setup : function () {\n            moment.locale('en');\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'core');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            teardownDeprecationHandler(test, moment, 'core');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n}\n\nmodule$1('instanceof');\n\ntest('instanceof', function (assert) {\n    var mm = moment([2010, 0, 1]);\n\n    var extend = function (a, b) {\n        var i;\n        for (i in b) {\n            a[i] = b[i];\n        }\n        return a;\n    };\n\n    assert.equal(moment() instanceof moment, true, 'simple moment object');\n    assert.equal(extend({}, moment()) instanceof moment, false, 'extended moment object');\n    assert.equal(moment(null) instanceof moment, true, 'invalid moment object');\n\n    assert.equal(new Date() instanceof moment, false, 'date object is not moment object');\n    assert.equal(Object instanceof moment, false, 'Object is not moment object');\n    assert.equal('foo' instanceof moment, false, 'string is not moment object');\n    assert.equal(1 instanceof moment, false, 'number is not moment object');\n    assert.equal(NaN instanceof moment, false, 'NaN is not moment object');\n    assert.equal(null instanceof moment, false, 'null is not moment object');\n    assert.equal(undefined instanceof moment, false, 'undefined is not moment object');\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\nfunction module$1 (name, lifecycle) {\n    QUnit.module(name, {\n        setup : function () {\n            moment.locale('en');\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'core');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            teardownDeprecationHandler(test, moment, 'core');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n}\n\nmodule$1('invalid');\n\ntest('invalid', function (assert) {\n    var m = moment.invalid();\n    assert.equal(m.isValid(), false);\n    assert.equal(m.parsingFlags().userInvalidated, true);\n    assert.ok(isNaN(m.valueOf()));\n});\n\ntest('invalid with existing flag', function (assert) {\n    var m = moment.invalid({invalidMonth : 'whatchamacallit'});\n    assert.equal(m.isValid(), false);\n    assert.equal(m.parsingFlags().userInvalidated, false);\n    assert.equal(m.parsingFlags().invalidMonth, 'whatchamacallit');\n    assert.ok(isNaN(m.valueOf()));\n});\n\ntest('invalid with custom flag', function (assert) {\n    var m = moment.invalid({tooBusyWith : 'reiculating splines'});\n    assert.equal(m.isValid(), false);\n    assert.equal(m.parsingFlags().userInvalidated, false);\n    assert.equal(m.parsingFlags().tooBusyWith, 'reiculating splines');\n    assert.ok(isNaN(m.valueOf()));\n});\n\ntest('invalid operations', function (assert) {\n    var invalids = [\n            moment.invalid(),\n            moment('xyz', 'l'),\n            moment('2015-01-35', 'YYYY-MM-DD'),\n            moment('2015-01-25 a', 'YYYY-MM-DD', true)\n        ],\n        i,\n        invalid,\n        valid = moment();\n\n    test.expectedDeprecations('moment().min', 'moment().max', 'isDSTShifted');\n\n    for (i = 0; i < invalids.length; ++i) {\n        invalid = invalids[i];\n\n        assert.ok(!invalid.clone().add(5, 'hours').isValid(), 'invalid.add is invalid');\n        assert.equal(invalid.calendar(), 'Invalid date', 'invalid.calendar is \\'Invalid date\\'');\n        assert.ok(!invalid.clone().isValid(), 'invalid.clone is invalid');\n        assert.ok(isNaN(invalid.diff(valid)), 'invalid.diff(valid) is NaN');\n        assert.ok(isNaN(valid.diff(invalid)), 'valid.diff(invalid) is NaN');\n        assert.ok(isNaN(invalid.diff(invalid)), 'invalid.diff(invalid) is NaN');\n        assert.ok(!invalid.clone().endOf('month').isValid(), 'invalid.endOf is invalid');\n        assert.equal(invalid.format(), 'Invalid date', 'invalid.format is \\'Invalid date\\'');\n        assert.equal(invalid.from(), 'Invalid date');\n        assert.equal(invalid.from(valid), 'Invalid date');\n        assert.equal(valid.from(invalid), 'Invalid date');\n        assert.equal(invalid.fromNow(), 'Invalid date');\n        assert.equal(invalid.to(), 'Invalid date');\n        assert.equal(invalid.to(valid), 'Invalid date');\n        assert.equal(valid.to(invalid), 'Invalid date');\n        assert.equal(invalid.toNow(), 'Invalid date');\n        assert.ok(isNaN(invalid.get('year')), 'invalid.get is NaN');\n        // TODO invalidAt\n        assert.ok(!invalid.isAfter(valid));\n        assert.ok(!valid.isAfter(invalid));\n        assert.ok(!invalid.isAfter(invalid));\n        assert.ok(!invalid.isBefore(valid));\n        assert.ok(!valid.isBefore(invalid));\n        assert.ok(!invalid.isBefore(invalid));\n        assert.ok(!invalid.isBetween(valid, valid));\n        assert.ok(!valid.isBetween(invalid, valid));\n        assert.ok(!valid.isBetween(valid, invalid));\n        assert.ok(!invalid.isSame(invalid));\n        assert.ok(!invalid.isSame(valid));\n        assert.ok(!valid.isSame(invalid));\n        assert.ok(!invalid.isValid());\n        assert.equal(invalid.locale(), 'en');\n        assert.equal(invalid.localeData()._abbr, 'en');\n        assert.ok(!invalid.clone().max(valid).isValid());\n        assert.ok(!valid.clone().max(invalid).isValid());\n        assert.ok(!invalid.clone().max(invalid).isValid());\n        assert.ok(!invalid.clone().min(valid).isValid());\n        assert.ok(!valid.clone().min(invalid).isValid());\n        assert.ok(!invalid.clone().min(invalid).isValid());\n        assert.ok(!moment.min(invalid, valid).isValid());\n        assert.ok(!moment.min(valid, invalid).isValid());\n        assert.ok(!moment.max(invalid, valid).isValid());\n        assert.ok(!moment.max(valid, invalid).isValid());\n        assert.ok(!invalid.clone().set('year', 2005).isValid());\n        assert.ok(!invalid.clone().startOf('month').isValid());\n\n        assert.ok(!invalid.clone().subtract(5, 'days').isValid());\n        assert.deepEqual(invalid.toArray(), [NaN, NaN, NaN, NaN, NaN, NaN, NaN]);\n        assert.deepEqual(invalid.toObject(), {\n            years: NaN,\n            months: NaN,\n            date: NaN,\n            hours: NaN,\n            minutes: NaN,\n            seconds: NaN,\n            milliseconds: NaN\n        });\n        assert.ok(moment.isDate(invalid.toDate()));\n        assert.ok(isNaN(invalid.toDate().valueOf()));\n        assert.equal(invalid.toJSON(), null);\n        assert.equal(invalid.toString(), 'Invalid date');\n        assert.ok(isNaN(invalid.unix()));\n        assert.ok(isNaN(invalid.valueOf()));\n\n        assert.ok(isNaN(invalid.year()));\n        assert.ok(isNaN(invalid.weekYear()));\n        assert.ok(isNaN(invalid.isoWeekYear()));\n        assert.ok(isNaN(invalid.quarter()));\n        assert.ok(isNaN(invalid.quarters()));\n        assert.ok(isNaN(invalid.month()));\n        assert.ok(isNaN(invalid.daysInMonth()));\n        assert.ok(isNaN(invalid.week()));\n        assert.ok(isNaN(invalid.weeks()));\n        assert.ok(isNaN(invalid.isoWeek()));\n        assert.ok(isNaN(invalid.isoWeeks()));\n        assert.ok(isNaN(invalid.weeksInYear()));\n        assert.ok(isNaN(invalid.isoWeeksInYear()));\n        assert.ok(isNaN(invalid.date()));\n        assert.ok(isNaN(invalid.day()));\n        assert.ok(isNaN(invalid.days()));\n        assert.ok(isNaN(invalid.weekday()));\n        assert.ok(isNaN(invalid.isoWeekday()));\n        assert.ok(isNaN(invalid.dayOfYear()));\n        assert.ok(isNaN(invalid.hour()));\n        assert.ok(isNaN(invalid.hours()));\n        assert.ok(isNaN(invalid.minute()));\n        assert.ok(isNaN(invalid.minutes()));\n        assert.ok(isNaN(invalid.second()));\n        assert.ok(isNaN(invalid.seconds()));\n        assert.ok(isNaN(invalid.millisecond()));\n        assert.ok(isNaN(invalid.milliseconds()));\n        assert.ok(isNaN(invalid.utcOffset()));\n\n        assert.ok(!invalid.clone().year(2001).isValid());\n        assert.ok(!invalid.clone().weekYear(2001).isValid());\n        assert.ok(!invalid.clone().isoWeekYear(2001).isValid());\n        assert.ok(!invalid.clone().quarter(1).isValid());\n        assert.ok(!invalid.clone().quarters(1).isValid());\n        assert.ok(!invalid.clone().month(1).isValid());\n        assert.ok(!invalid.clone().week(1).isValid());\n        assert.ok(!invalid.clone().weeks(1).isValid());\n        assert.ok(!invalid.clone().isoWeek(1).isValid());\n        assert.ok(!invalid.clone().isoWeeks(1).isValid());\n        assert.ok(!invalid.clone().date(1).isValid());\n        assert.ok(!invalid.clone().day(1).isValid());\n        assert.ok(!invalid.clone().days(1).isValid());\n        assert.ok(!invalid.clone().weekday(1).isValid());\n        assert.ok(!invalid.clone().isoWeekday(1).isValid());\n        assert.ok(!invalid.clone().dayOfYear(1).isValid());\n        assert.ok(!invalid.clone().hour(1).isValid());\n        assert.ok(!invalid.clone().hours(1).isValid());\n        assert.ok(!invalid.clone().minute(1).isValid());\n        assert.ok(!invalid.clone().minutes(1).isValid());\n        assert.ok(!invalid.clone().second(1).isValid());\n        assert.ok(!invalid.clone().seconds(1).isValid());\n        assert.ok(!invalid.clone().millisecond(1).isValid());\n        assert.ok(!invalid.clone().milliseconds(1).isValid());\n        assert.ok(!invalid.clone().utcOffset(1).isValid());\n\n        assert.ok(!invalid.clone().utc().isValid());\n        assert.ok(!invalid.clone().local().isValid());\n        assert.ok(!invalid.clone().parseZone('05:30').isValid());\n        assert.ok(!invalid.hasAlignedHourOffset());\n        assert.ok(!invalid.isDST());\n        assert.ok(!invalid.isDSTShifted());\n        assert.ok(!invalid.isLocal());\n        assert.ok(!invalid.isUtcOffset());\n        assert.ok(!invalid.isUtc());\n        assert.ok(!invalid.isUTC());\n\n        assert.ok(!invalid.isLeapYear());\n\n        assert.equal(moment.duration({from: invalid, to: valid}).asMilliseconds(), 0);\n        assert.equal(moment.duration({from: valid, to: invalid}).asMilliseconds(), 0);\n        assert.equal(moment.duration({from: invalid, to: invalid}).asMilliseconds(), 0);\n    }\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\nfunction module$1 (name, lifecycle) {\n    QUnit.module(name, {\n        setup : function () {\n            moment.locale('en');\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'core');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            teardownDeprecationHandler(test, moment, 'core');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n}\n\nmodule$1('is after');\n\ntest('is after without units', function (assert) {\n    var m = moment(new Date(2011, 3, 2, 3, 4, 5, 10)), mCopy = moment(m);\n    assert.equal(m.isAfter(moment(new Date(2012, 3, 2, 3, 5, 5, 10))), false, 'year is later');\n    assert.equal(m.isAfter(moment(new Date(2010, 3, 2, 3, 3, 5, 10))), true, 'year is earlier');\n    assert.equal(m.isAfter(moment(new Date(2011, 4, 2, 3, 4, 5, 10))), false, 'month is later');\n    assert.equal(m.isAfter(moment(new Date(2011, 2, 2, 3, 4, 5, 10))), true, 'month is earlier');\n    assert.equal(m.isAfter(moment(new Date(2011, 3, 3, 3, 4, 5, 10))), false, 'day is later');\n    assert.equal(m.isAfter(moment(new Date(2011, 3, 1, 3, 4, 5, 10))), true, 'day is earlier');\n    assert.equal(m.isAfter(moment(new Date(2011, 3, 2, 4, 4, 5, 10))), false, 'hour is later');\n    assert.equal(m.isAfter(moment(new Date(2011, 3, 2, 2, 4, 5, 10))), true, 'hour is earlier');\n    assert.equal(m.isAfter(moment(new Date(2011, 3, 2, 3, 5, 5, 10))), false, 'minute is later');\n    assert.equal(m.isAfter(moment(new Date(2011, 3, 2, 3, 3, 5, 10))), true, 'minute is earlier');\n    assert.equal(m.isAfter(moment(new Date(2011, 3, 2, 3, 4, 6, 10))), false, 'second is later');\n    assert.equal(m.isAfter(moment(new Date(2011, 3, 2, 3, 4, 4, 11))), true, 'second is earlier');\n    assert.equal(m.isAfter(moment(new Date(2011, 3, 2, 3, 4, 5, 10))), false, 'millisecond match');\n    assert.equal(m.isAfter(moment(new Date(2011, 3, 2, 3, 4, 5, 11))), false, 'millisecond is later');\n    assert.equal(m.isAfter(moment(new Date(2011, 3, 2, 3, 4, 5, 9))), true, 'millisecond is earlier');\n    assert.equal(m.isAfter(m), false, 'moments are not after themselves');\n    assert.equal(+m, +mCopy, 'isAfter second should not change moment');\n});\n\ntest('is after year', function (assert) {\n    var m = moment(new Date(2011, 1, 2, 3, 4, 5, 6)), mCopy = moment(m);\n    assert.equal(m.isAfter(moment(new Date(2011, 5, 6, 7, 8, 9, 10)), 'year'), false, 'year match');\n    assert.equal(m.isAfter(moment(new Date(2010, 5, 6, 7, 8, 9, 10)), 'years'), true, 'plural should work');\n    assert.equal(m.isAfter(moment(new Date(2013, 5, 6, 7, 8, 9, 10)), 'year'), false, 'year is later');\n    assert.equal(m.isAfter(moment(new Date(2010, 5, 6, 7, 8, 9, 10)), 'year'), true, 'year is earlier');\n    assert.equal(m.isAfter(moment(new Date(2011, 0, 1, 0, 0, 0, 0)), 'year'), false, 'exact start of year');\n    assert.equal(m.isAfter(moment(new Date(2011, 11, 31, 23, 59, 59, 999)), 'year'), false, 'exact end of year');\n    assert.equal(m.isAfter(moment(new Date(2012, 0, 1, 0, 0, 0, 0)), 'year'), false, 'start of next year');\n    assert.equal(m.isAfter(moment(new Date(2010, 11, 31, 23, 59, 59, 999)), 'year'), true, 'end of previous year');\n    assert.equal(m.isAfter(moment(new Date(1980, 11, 31, 23, 59, 59, 999)), 'year'), true, 'end of year far before');\n    assert.equal(m.isAfter(m, 'year'), false, 'same moments are not after the same year');\n    assert.equal(+m, +mCopy, 'isAfter year should not change moment');\n});\n\ntest('is after month', function (assert) {\n    var m = moment(new Date(2011, 2, 3, 4, 5, 6, 7)), mCopy = moment(m);\n    assert.equal(m.isAfter(moment(new Date(2011, 2, 6, 7, 8, 9, 10)), 'month'), false, 'month match');\n    assert.equal(m.isAfter(moment(new Date(2010, 2, 6, 7, 8, 9, 10)), 'months'), true, 'plural should work');\n    assert.equal(m.isAfter(moment(new Date(2012, 2, 6, 7, 8, 9, 10)), 'month'), false, 'year is later');\n    assert.equal(m.isAfter(moment(new Date(2010, 2, 6, 7, 8, 9, 10)), 'month'), true, 'year is earlier');\n    assert.equal(m.isAfter(moment(new Date(2011, 5, 6, 7, 8, 9, 10)), 'month'), false, 'month is later');\n    assert.equal(m.isAfter(moment(new Date(2011, 1, 6, 7, 8, 9, 10)), 'month'), true, 'month is earlier');\n    assert.equal(m.isAfter(moment(new Date(2011, 2, 1, 0, 0, 0, 0)), 'month'), false, 'exact start of month');\n    assert.equal(m.isAfter(moment(new Date(2011, 2, 31, 23, 59, 59, 999)), 'month'), false, 'exact end of month');\n    assert.equal(m.isAfter(moment(new Date(2011, 3, 1, 0, 0, 0, 0)), 'month'), false, 'start of next month');\n    assert.equal(m.isAfter(moment(new Date(2011, 1, 27, 23, 59, 59, 999)), 'month'), true, 'end of previous month');\n    assert.equal(m.isAfter(moment(new Date(2010, 12, 31, 23, 59, 59, 999)), 'month'), true, 'later month but earlier year');\n    assert.equal(m.isAfter(m, 'month'), false, 'same moments are not after the same month');\n    assert.equal(+m, +mCopy, 'isAfter month should not change moment');\n});\n\ntest('is after day', function (assert) {\n    var m = moment(new Date(2011, 3, 2, 3, 4, 5, 6)), mCopy = moment(m);\n    assert.equal(m.isAfter(moment(new Date(2011, 3, 2, 7, 8, 9, 10)), 'day'), false, 'day match');\n    assert.equal(m.isAfter(moment(new Date(2010, 3, 2, 7, 8, 9, 10)), 'days'), true, 'plural should work');\n    assert.equal(m.isAfter(moment(new Date(2012, 3, 2, 7, 8, 9, 10)), 'day'), false, 'year is later');\n    assert.equal(m.isAfter(moment(new Date(2010, 3, 2, 7, 8, 9, 10)), 'day'), true, 'year is earlier');\n    assert.equal(m.isAfter(moment(new Date(2011, 4, 2, 7, 8, 9, 10)), 'day'), false, 'month is later');\n    assert.equal(m.isAfter(moment(new Date(2011, 2, 2, 7, 8, 9, 10)), 'day'), true, 'month is earlier');\n    assert.equal(m.isAfter(moment(new Date(2011, 3, 3, 7, 8, 9, 10)), 'day'), false, 'day is later');\n    assert.equal(m.isAfter(moment(new Date(2011, 3, 1, 7, 8, 9, 10)), 'day'), true, 'day is earlier');\n    assert.equal(m.isAfter(moment(new Date(2011, 3, 2, 0, 0, 0, 0)), 'day'), false, 'exact start of day');\n    assert.equal(m.isAfter(moment(new Date(2011, 3, 2, 23, 59, 59, 999)), 'day'), false, 'exact end of day');\n    assert.equal(m.isAfter(moment(new Date(2011, 3, 3, 0, 0, 0, 0)), 'day'), false, 'start of next day');\n    assert.equal(m.isAfter(moment(new Date(2011, 3, 1, 23, 59, 59, 999)), 'day'), true, 'end of previous day');\n    assert.equal(m.isAfter(moment(new Date(2010, 3, 10, 0, 0, 0, 0)), 'day'), true, 'later day but earlier year');\n    assert.equal(m.isAfter(m, 'day'), false, 'same moments are not after the same day');\n    assert.equal(+m, +mCopy, 'isAfter day should not change moment');\n});\n\ntest('is after hour', function (assert) {\n    var m = moment(new Date(2011, 3, 2, 3, 4, 5, 6)), mCopy = moment(m);\n    assert.equal(m.isAfter(moment(new Date(2011, 3, 2, 3, 8, 9, 10)), 'hour'), false, 'hour match');\n    assert.equal(m.isAfter(moment(new Date(2010, 3, 2, 3, 8, 9, 10)), 'hours'), true, 'plural should work');\n    assert.equal(m.isAfter(moment(new Date(2012, 3, 2, 3, 8, 9, 10)), 'hour'), false, 'year is later');\n    assert.equal(m.isAfter(moment(new Date(2010, 3, 2, 3, 8, 9, 10)), 'hour'), true, 'year is earlier');\n    assert.equal(m.isAfter(moment(new Date(2011, 4, 2, 3, 8, 9, 10)), 'hour'), false, 'month is later');\n    assert.equal(m.isAfter(moment(new Date(2011, 1, 2, 3, 8, 9, 10)), 'hour'), true, 'month is earlier');\n    assert.equal(m.isAfter(moment(new Date(2011, 3, 3, 3, 8, 9, 10)), 'hour'), false, 'day is later');\n    assert.equal(m.isAfter(moment(new Date(2011, 3, 1, 3, 8, 9, 10)), 'hour'), true, 'day is earlier');\n    assert.equal(m.isAfter(moment(new Date(2011, 3, 2, 4, 8, 9, 10)), 'hour'), false, 'hour is later');\n    assert.equal(m.isAfter(moment(new Date(2011, 3, 2, 3, 8, 9, 10)), 'hour'), false, 'hour is earlier');\n    assert.equal(m.isAfter(moment(new Date(2011, 3, 2, 3, 0, 0, 0)), 'hour'), false, 'exact start of hour');\n    assert.equal(m.isAfter(moment(new Date(2011, 3, 2, 3, 59, 59, 999)), 'hour'), false, 'exact end of hour');\n    assert.equal(m.isAfter(moment(new Date(2011, 3, 2, 4, 0, 0, 0)), 'hour'), false, 'start of next hour');\n    assert.equal(m.isAfter(moment(new Date(2011, 3, 2, 2, 59, 59, 999)), 'hour'), true, 'end of previous hour');\n    assert.equal(m.isAfter(m, 'hour'), false, 'same moments are not after the same hour');\n    assert.equal(+m, +mCopy, 'isAfter hour should not change moment');\n});\n\ntest('is after minute', function (assert) {\n    var m = moment(new Date(2011, 3, 2, 3, 4, 5, 6)), mCopy = moment(m);\n    assert.equal(m.isAfter(moment(new Date(2011, 3, 2, 3, 4, 9, 10)), 'minute'), false, 'minute match');\n    assert.equal(m.isAfter(moment(new Date(2010, 3, 2, 3, 4, 9, 10)), 'minutes'), true, 'plural should work');\n    assert.equal(m.isAfter(moment(new Date(2012, 3, 2, 3, 4, 9, 10)), 'minute'), false, 'year is later');\n    assert.equal(m.isAfter(moment(new Date(2010, 3, 2, 3, 4, 9, 10)), 'minute'), true, 'year is earlier');\n    assert.equal(m.isAfter(moment(new Date(2011, 4, 2, 3, 4, 9, 10)), 'minute'), false, 'month is later');\n    assert.equal(m.isAfter(moment(new Date(2011, 2, 2, 3, 4, 9, 10)), 'minute'), true, 'month is earlier');\n    assert.equal(m.isAfter(moment(new Date(2011, 3, 3, 3, 4, 9, 10)), 'minute'), false, 'day is later');\n    assert.equal(m.isAfter(moment(new Date(2011, 3, 1, 3, 4, 9, 10)), 'minute'), true, 'day is earlier');\n    assert.equal(m.isAfter(moment(new Date(2011, 3, 2, 4, 4, 9, 10)), 'minute'), false, 'hour is later');\n    assert.equal(m.isAfter(moment(new Date(2011, 3, 2, 2, 4, 9, 10)), 'minute'), true, 'hour is earler');\n    assert.equal(m.isAfter(moment(new Date(2011, 3, 2, 3, 5, 9, 10)), 'minute'), false, 'minute is later');\n    assert.equal(m.isAfter(moment(new Date(2011, 3, 2, 3, 3, 9, 10)), 'minute'), true, 'minute is earlier');\n    assert.equal(m.isAfter(moment(new Date(2011, 3, 2, 3, 4, 0, 0)), 'minute'), false, 'exact start of minute');\n    assert.equal(m.isAfter(moment(new Date(2011, 3, 2, 3, 4, 59, 999)), 'minute'), false, 'exact end of minute');\n    assert.equal(m.isAfter(moment(new Date(2011, 3, 2, 3, 5, 0, 0)), 'minute'), false, 'start of next minute');\n    assert.equal(m.isAfter(moment(new Date(2011, 3, 2, 3, 3, 59, 999)), 'minute'), true, 'end of previous minute');\n    assert.equal(m.isAfter(m, 'minute'), false, 'same moments are not after the same minute');\n    assert.equal(+m, +mCopy, 'isAfter minute should not change moment');\n});\n\ntest('is after second', function (assert) {\n    var m = moment(new Date(2011, 3, 2, 3, 4, 5, 10)), mCopy = moment(m);\n    assert.equal(m.isAfter(moment(new Date(2011, 3, 2, 3, 4, 5, 10)), 'second'), false, 'second match');\n    assert.equal(m.isAfter(moment(new Date(2010, 3, 2, 3, 4, 5, 10)), 'seconds'), true, 'plural should work');\n    assert.equal(m.isAfter(moment(new Date(2012, 3, 2, 3, 4, 5, 10)), 'second'), false, 'year is later');\n    assert.equal(m.isAfter(moment(new Date(2010, 3, 2, 3, 4, 5, 10)), 'second'), true, 'year is earlier');\n    assert.equal(m.isAfter(moment(new Date(2011, 4, 2, 3, 4, 5, 10)), 'second'), false, 'month is later');\n    assert.equal(m.isAfter(moment(new Date(2011, 2, 2, 3, 4, 5, 10)), 'second'), true, 'month is earlier');\n    assert.equal(m.isAfter(moment(new Date(2011, 3, 3, 3, 4, 5, 10)), 'second'), false, 'day is later');\n    assert.equal(m.isAfter(moment(new Date(2011, 3, 1, 1, 4, 5, 10)), 'second'), true, 'day is earlier');\n    assert.equal(m.isAfter(moment(new Date(2011, 3, 2, 4, 4, 5, 10)), 'second'), false, 'hour is later');\n    assert.equal(m.isAfter(moment(new Date(2011, 3, 1, 4, 1, 5, 10)), 'second'), true, 'hour is earlier');\n    assert.equal(m.isAfter(moment(new Date(2011, 3, 2, 3, 5, 5, 10)), 'second'), false, 'minute is later');\n    assert.equal(m.isAfter(moment(new Date(2011, 3, 2, 3, 3, 5, 10)), 'second'), true, 'minute is earlier');\n    assert.equal(m.isAfter(moment(new Date(2011, 3, 2, 3, 4, 6, 10)), 'second'), false, 'second is later');\n    assert.equal(m.isAfter(moment(new Date(2011, 3, 2, 3, 4, 4, 5)), 'second'), true, 'second is earlier');\n    assert.equal(m.isAfter(moment(new Date(2011, 3, 2, 3, 4, 5, 0)), 'second'), false, 'exact start of second');\n    assert.equal(m.isAfter(moment(new Date(2011, 3, 2, 3, 4, 5, 999)), 'second'), false, 'exact end of second');\n    assert.equal(m.isAfter(moment(new Date(2011, 3, 2, 3, 4, 6, 0)), 'second'), false, 'start of next second');\n    assert.equal(m.isAfter(moment(new Date(2011, 3, 2, 3, 4, 4, 999)), 'second'), true, 'end of previous second');\n    assert.equal(m.isAfter(m, 'second'), false, 'same moments are not after the same second');\n    assert.equal(+m, +mCopy, 'isAfter second should not change moment');\n});\n\ntest('is after millisecond', function (assert) {\n    var m = moment(new Date(2011, 3, 2, 3, 4, 5, 10)), mCopy = moment(m);\n    assert.equal(m.isAfter(moment(new Date(2011, 3, 2, 3, 4, 5, 10)), 'millisecond'), false, 'millisecond match');\n    assert.equal(m.isAfter(moment(new Date(2010, 3, 2, 3, 4, 5, 10)), 'milliseconds'), true, 'plural should work');\n    assert.equal(m.isAfter(moment(new Date(2012, 3, 2, 3, 4, 5, 10)), 'millisecond'), false, 'year is later');\n    assert.equal(m.isAfter(moment(new Date(2010, 3, 2, 3, 4, 5, 10)), 'millisecond'), true, 'year is earlier');\n    assert.equal(m.isAfter(moment(new Date(2011, 4, 2, 3, 4, 5, 10)), 'millisecond'), false, 'month is later');\n    assert.equal(m.isAfter(moment(new Date(2011, 2, 2, 3, 4, 5, 10)), 'millisecond'), true, 'month is earlier');\n    assert.equal(m.isAfter(moment(new Date(2011, 3, 3, 3, 4, 5, 10)), 'millisecond'), false, 'day is later');\n    assert.equal(m.isAfter(moment(new Date(2011, 3, 1, 1, 4, 5, 10)), 'millisecond'), true, 'day is earlier');\n    assert.equal(m.isAfter(moment(new Date(2011, 3, 2, 4, 4, 5, 10)), 'millisecond'), false, 'hour is later');\n    assert.equal(m.isAfter(moment(new Date(2011, 3, 1, 4, 1, 5, 10)), 'millisecond'), true, 'hour is earlier');\n    assert.equal(m.isAfter(moment(new Date(2011, 3, 2, 3, 5, 5, 10)), 'millisecond'), false, 'minute is later');\n    assert.equal(m.isAfter(moment(new Date(2011, 3, 2, 3, 3, 5, 10)), 'millisecond'), true, 'minute is earlier');\n    assert.equal(m.isAfter(moment(new Date(2011, 3, 2, 3, 4, 6, 10)), 'millisecond'), false, 'second is later');\n    assert.equal(m.isAfter(moment(new Date(2011, 3, 2, 3, 4, 4, 5)), 'millisecond'), true, 'second is earlier');\n    assert.equal(m.isAfter(moment(new Date(2011, 3, 2, 3, 4, 6, 11)), 'millisecond'), false, 'millisecond is later');\n    assert.equal(m.isAfter(moment(new Date(2011, 3, 2, 3, 4, 4, 9)), 'millisecond'), true, 'millisecond is earlier');\n    assert.equal(m.isAfter(m, 'millisecond'), false, 'same moments are not after the same millisecond');\n    assert.equal(+m, +mCopy, 'isAfter millisecond should not change moment');\n});\n\ntest('is after invalid', function (assert) {\n    var m = moment(), invalid = moment.invalid();\n    assert.equal(m.isAfter(invalid), false, 'valid moment is not after invalid moment');\n    assert.equal(invalid.isAfter(m), false, 'invalid moment is not after valid moment');\n    assert.equal(m.isAfter(invalid, 'year'), false, 'invalid moment year');\n    assert.equal(m.isAfter(invalid, 'month'), false, 'invalid moment month');\n    assert.equal(m.isAfter(invalid, 'day'), false, 'invalid moment day');\n    assert.equal(m.isAfter(invalid, 'hour'), false, 'invalid moment hour');\n    assert.equal(m.isAfter(invalid, 'minute'), false, 'invalid moment minute');\n    assert.equal(m.isAfter(invalid, 'second'), false, 'invalid moment second');\n    assert.equal(m.isAfter(invalid, 'milliseconds'), false, 'invalid moment milliseconds');\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\nfunction isArray(input) {\n    return input instanceof Array || Object.prototype.toString.call(input) === '[object Array]';\n}\n\ntest('isArray recognizes Array objects', function (assert) {\n    assert.ok(isArray([1,2,3]), 'array args');\n    assert.ok(isArray([]), 'empty array');\n    assert.ok(isArray(new Array(1,2,3)), 'array constructor');\n});\n\ntest('isArray rejects non-Array objects', function (assert) {\n    assert.ok(!isArray(), 'nothing');\n    assert.ok(!isArray(undefined), 'undefined');\n    assert.ok(!isArray(null), 'null');\n    assert.ok(!isArray(123), 'number');\n    assert.ok(!isArray('[1,2,3]'), 'string');\n    assert.ok(!isArray(new Date()), 'date');\n    assert.ok(!isArray({a:1,b:2}), 'object');\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\nfunction module$1 (name, lifecycle) {\n    QUnit.module(name, {\n        setup : function () {\n            moment.locale('en');\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'core');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            teardownDeprecationHandler(test, moment, 'core');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n}\n\nmodule$1('is before');\n\ntest('is after without units', function (assert) {\n    var m = moment(new Date(2011, 3, 2, 3, 4, 5, 10)), mCopy = moment(m);\n    assert.equal(m.isBefore(moment(new Date(2012, 3, 2, 3, 5, 5, 10))), true, 'year is later');\n    assert.equal(m.isBefore(moment(new Date(2010, 3, 2, 3, 3, 5, 10))), false, 'year is earlier');\n    assert.equal(m.isBefore(moment(new Date(2011, 4, 2, 3, 4, 5, 10))), true, 'month is later');\n    assert.equal(m.isBefore(moment(new Date(2011, 2, 2, 3, 4, 5, 10))), false, 'month is earlier');\n    assert.equal(m.isBefore(moment(new Date(2011, 3, 3, 3, 4, 5, 10))), true, 'day is later');\n    assert.equal(m.isBefore(moment(new Date(2011, 3, 1, 3, 4, 5, 10))), false, 'day is earlier');\n    assert.equal(m.isBefore(moment(new Date(2011, 3, 2, 4, 4, 5, 10))), true, 'hour is later');\n    assert.equal(m.isBefore(moment(new Date(2011, 3, 2, 2, 4, 5, 10))), false, 'hour is earlier');\n    assert.equal(m.isBefore(moment(new Date(2011, 3, 2, 3, 5, 5, 10))), true, 'minute is later');\n    assert.equal(m.isBefore(moment(new Date(2011, 3, 2, 3, 3, 5, 10))), false, 'minute is earlier');\n    assert.equal(m.isBefore(moment(new Date(2011, 3, 2, 3, 4, 6, 10))), true, 'second is later');\n    assert.equal(m.isBefore(moment(new Date(2011, 3, 2, 3, 4, 4, 11))), false, 'second is earlier');\n    assert.equal(m.isBefore(moment(new Date(2011, 3, 2, 3, 4, 5, 10))), false, 'millisecond match');\n    assert.equal(m.isBefore(moment(new Date(2011, 3, 2, 3, 4, 5, 11))), true, 'millisecond is later');\n    assert.equal(m.isBefore(moment(new Date(2011, 3, 2, 3, 4, 5, 9))), false, 'millisecond is earlier');\n    assert.equal(m.isBefore(m), false, 'moments are not before themselves');\n    assert.equal(+m, +mCopy, 'isBefore second should not change moment');\n});\n\ntest('is before year', function (assert) {\n    var m = moment(new Date(2011, 1, 2, 3, 4, 5, 6)), mCopy = moment(m);\n    assert.equal(m.isBefore(moment(new Date(2011, 5, 6, 7, 8, 9, 10)), 'year'), false, 'year match');\n    assert.equal(m.isBefore(moment(new Date(2012, 5, 6, 7, 8, 9, 10)), 'years'), true, 'plural should work');\n    assert.equal(m.isBefore(moment(new Date(2013, 5, 6, 7, 8, 9, 10)), 'year'), true, 'year is later');\n    assert.equal(m.isBefore(moment(new Date(2010, 5, 6, 7, 8, 9, 10)), 'year'), false, 'year is earlier');\n    assert.equal(m.isBefore(moment(new Date(2011, 0, 1, 0, 0, 0, 0)), 'year'), false, 'exact start of year');\n    assert.equal(m.isBefore(moment(new Date(2011, 11, 31, 23, 59, 59, 999)), 'year'), false, 'exact end of year');\n    assert.equal(m.isBefore(moment(new Date(2012, 0, 1, 0, 0, 0, 0)), 'year'), true, 'start of next year');\n    assert.equal(m.isBefore(moment(new Date(2010, 11, 31, 23, 59, 59, 999)), 'year'), false, 'end of previous year');\n    assert.equal(m.isBefore(moment(new Date(1980, 11, 31, 23, 59, 59, 999)), 'year'), false, 'end of year far before');\n    assert.equal(m.isBefore(m, 'year'), false, 'same moments are not before the same year');\n    assert.equal(+m, +mCopy, 'isBefore year should not change moment');\n});\n\ntest('is before month', function (assert) {\n    var m = moment(new Date(2011, 2, 3, 4, 5, 6, 7)), mCopy = moment(m);\n    assert.equal(m.isBefore(moment(new Date(2011, 2, 6, 7, 8, 9, 10)), 'month'), false, 'month match');\n    assert.equal(m.isBefore(moment(new Date(2012, 2, 6, 7, 8, 9, 10)), 'months'), true, 'plural should work');\n    assert.equal(m.isBefore(moment(new Date(2012, 2, 6, 7, 8, 9, 10)), 'month'), true, 'year is later');\n    assert.equal(m.isBefore(moment(new Date(2010, 2, 6, 7, 8, 9, 10)), 'month'), false, 'year is earlier');\n    assert.equal(m.isBefore(moment(new Date(2011, 5, 6, 7, 8, 9, 10)), 'month'), true, 'month is later');\n    assert.equal(m.isBefore(moment(new Date(2011, 1, 6, 7, 8, 9, 10)), 'month'), false, 'month is earlier');\n    assert.equal(m.isBefore(moment(new Date(2011, 2, 1, 0, 0, 0, 0)), 'month'), false, 'exact start of month');\n    assert.equal(m.isBefore(moment(new Date(2011, 2, 31, 23, 59, 59, 999)), 'month'), false, 'exact end of month');\n    assert.equal(m.isBefore(moment(new Date(2011, 3, 1, 0, 0, 0, 0)), 'month'), true, 'start of next month');\n    assert.equal(m.isBefore(moment(new Date(2011, 1, 27, 23, 59, 59, 999)), 'month'), false, 'end of previous month');\n    assert.equal(m.isBefore(moment(new Date(2010, 12, 31, 23, 59, 59, 999)), 'month'), false, 'later month but earlier year');\n    assert.equal(m.isBefore(m, 'month'), false, 'same moments are not before the same month');\n    assert.equal(+m, +mCopy, 'isBefore month should not change moment');\n});\n\ntest('is before day', function (assert) {\n    var m = moment(new Date(2011, 3, 2, 3, 4, 5, 6)), mCopy = moment(m);\n    assert.equal(m.isBefore(moment(new Date(2011, 3, 2, 7, 8, 9, 10)), 'day'), false, 'day match');\n    assert.equal(m.isBefore(moment(new Date(2012, 3, 2, 7, 8, 9, 10)), 'days'), true, 'plural should work');\n    assert.equal(m.isBefore(moment(new Date(2012, 3, 2, 7, 8, 9, 10)), 'day'), true, 'year is later');\n    assert.equal(m.isBefore(moment(new Date(2010, 3, 2, 7, 8, 9, 10)), 'day'), false, 'year is earlier');\n    assert.equal(m.isBefore(moment(new Date(2011, 4, 2, 7, 8, 9, 10)), 'day'), true, 'month is later');\n    assert.equal(m.isBefore(moment(new Date(2011, 2, 2, 7, 8, 9, 10)), 'day'), false, 'month is earlier');\n    assert.equal(m.isBefore(moment(new Date(2011, 3, 3, 7, 8, 9, 10)), 'day'), true, 'day is later');\n    assert.equal(m.isBefore(moment(new Date(2011, 3, 1, 7, 8, 9, 10)), 'day'), false, 'day is earlier');\n    assert.equal(m.isBefore(moment(new Date(2011, 3, 2, 0, 0, 0, 0)), 'day'), false, 'exact start of day');\n    assert.equal(m.isBefore(moment(new Date(2011, 3, 2, 23, 59, 59, 999)), 'day'), false, 'exact end of day');\n    assert.equal(m.isBefore(moment(new Date(2011, 3, 3, 0, 0, 0, 0)), 'day'), true, 'start of next day');\n    assert.equal(m.isBefore(moment(new Date(2011, 3, 1, 23, 59, 59, 999)), 'day'), false, 'end of previous day');\n    assert.equal(m.isBefore(moment(new Date(2010, 3, 10, 0, 0, 0, 0)), 'day'), false, 'later day but earlier year');\n    assert.equal(m.isBefore(m, 'day'), false, 'same moments are not before the same day');\n    assert.equal(+m, +mCopy, 'isBefore day should not change moment');\n});\n\ntest('is before hour', function (assert) {\n    var m = moment(new Date(2011, 3, 2, 3, 4, 5, 6)), mCopy = moment(m);\n    assert.equal(m.isBefore(moment(new Date(2011, 3, 2, 3, 8, 9, 10)), 'hour'), false, 'hour match');\n    assert.equal(m.isBefore(moment(new Date(2012, 3, 2, 3, 8, 9, 10)), 'hours'), true, 'plural should work');\n    assert.equal(m.isBefore(moment(new Date(2012, 3, 2, 3, 8, 9, 10)), 'hour'), true, 'year is later');\n    assert.equal(m.isBefore(moment(new Date(2010, 3, 2, 3, 8, 9, 10)), 'hour'), false, 'year is earlier');\n    assert.equal(m.isBefore(moment(new Date(2011, 4, 2, 3, 8, 9, 10)), 'hour'), true, 'month is later');\n    assert.equal(m.isBefore(moment(new Date(2011, 1, 2, 3, 8, 9, 10)), 'hour'), false, 'month is earlier');\n    assert.equal(m.isBefore(moment(new Date(2011, 3, 3, 3, 8, 9, 10)), 'hour'), true, 'day is later');\n    assert.equal(m.isBefore(moment(new Date(2011, 3, 1, 3, 8, 9, 10)), 'hour'), false, 'day is earlier');\n    assert.equal(m.isBefore(moment(new Date(2011, 3, 2, 4, 8, 9, 10)), 'hour'), true, 'hour is later');\n    assert.equal(m.isBefore(moment(new Date(2011, 3, 2, 3, 8, 9, 10)), 'hour'), false, 'hour is earlier');\n    assert.equal(m.isBefore(moment(new Date(2011, 3, 2, 3, 0, 0, 0)), 'hour'), false, 'exact start of hour');\n    assert.equal(m.isBefore(moment(new Date(2011, 3, 2, 3, 59, 59, 999)), 'hour'), false, 'exact end of hour');\n    assert.equal(m.isBefore(moment(new Date(2011, 3, 2, 4, 0, 0, 0)), 'hour'), true, 'start of next hour');\n    assert.equal(m.isBefore(moment(new Date(2011, 3, 2, 2, 59, 59, 999)), 'hour'), false, 'end of previous hour');\n    assert.equal(m.isBefore(m, 'hour'), false, 'same moments are not before the same hour');\n    assert.equal(+m, +mCopy, 'isBefore hour should not change moment');\n});\n\ntest('is before minute', function (assert) {\n    var m = moment(new Date(2011, 3, 2, 3, 4, 5, 6)), mCopy = moment(m);\n    assert.equal(m.isBefore(moment(new Date(2011, 3, 2, 3, 4, 9, 10)), 'minute'), false, 'minute match');\n    assert.equal(m.isBefore(moment(new Date(2012, 3, 2, 3, 4, 9, 10)), 'minutes'), true, 'plural should work');\n    assert.equal(m.isBefore(moment(new Date(2012, 3, 2, 3, 4, 9, 10)), 'minute'), true, 'year is later');\n    assert.equal(m.isBefore(moment(new Date(2010, 3, 2, 3, 4, 9, 10)), 'minute'), false, 'year is earlier');\n    assert.equal(m.isBefore(moment(new Date(2011, 4, 2, 3, 4, 9, 10)), 'minute'), true, 'month is later');\n    assert.equal(m.isBefore(moment(new Date(2011, 2, 2, 3, 4, 9, 10)), 'minute'), false, 'month is earlier');\n    assert.equal(m.isBefore(moment(new Date(2011, 3, 3, 3, 4, 9, 10)), 'minute'), true, 'day is later');\n    assert.equal(m.isBefore(moment(new Date(2011, 3, 1, 3, 4, 9, 10)), 'minute'), false, 'day is earlier');\n    assert.equal(m.isBefore(moment(new Date(2011, 3, 2, 4, 4, 9, 10)), 'minute'), true, 'hour is later');\n    assert.equal(m.isBefore(moment(new Date(2011, 3, 2, 2, 4, 9, 10)), 'minute'), false, 'hour is earler');\n    assert.equal(m.isBefore(moment(new Date(2011, 3, 2, 3, 5, 9, 10)), 'minute'), true, 'minute is later');\n    assert.equal(m.isBefore(moment(new Date(2011, 3, 2, 3, 3, 9, 10)), 'minute'), false, 'minute is earlier');\n    assert.equal(m.isBefore(moment(new Date(2011, 3, 2, 3, 4, 0, 0)), 'minute'), false, 'exact start of minute');\n    assert.equal(m.isBefore(moment(new Date(2011, 3, 2, 3, 4, 59, 999)), 'minute'), false, 'exact end of minute');\n    assert.equal(m.isBefore(moment(new Date(2011, 3, 2, 3, 5, 0, 0)), 'minute'), true, 'start of next minute');\n    assert.equal(m.isBefore(moment(new Date(2011, 3, 2, 3, 3, 59, 999)), 'minute'), false, 'end of previous minute');\n    assert.equal(m.isBefore(m, 'minute'), false, 'same moments are not before the same minute');\n    assert.equal(+m, +mCopy, 'isBefore minute should not change moment');\n});\n\ntest('is before second', function (assert) {\n    var m = moment(new Date(2011, 3, 2, 3, 4, 5, 10)), mCopy = moment(m);\n    assert.equal(m.isBefore(moment(new Date(2011, 3, 2, 3, 4, 5, 10)), 'second'), false, 'second match');\n    assert.equal(m.isBefore(moment(new Date(2012, 3, 2, 3, 4, 5, 10)), 'seconds'), true, 'plural should work');\n    assert.equal(m.isBefore(moment(new Date(2012, 3, 2, 3, 4, 5, 10)), 'second'), true, 'year is later');\n    assert.equal(m.isBefore(moment(new Date(2010, 3, 2, 3, 4, 5, 10)), 'second'), false, 'year is earlier');\n    assert.equal(m.isBefore(moment(new Date(2011, 4, 2, 3, 4, 5, 10)), 'second'), true, 'month is later');\n    assert.equal(m.isBefore(moment(new Date(2011, 2, 2, 3, 4, 5, 10)), 'second'), false, 'month is earlier');\n    assert.equal(m.isBefore(moment(new Date(2011, 3, 3, 3, 4, 5, 10)), 'second'), true, 'day is later');\n    assert.equal(m.isBefore(moment(new Date(2011, 3, 1, 1, 4, 5, 10)), 'second'), false, 'day is earlier');\n    assert.equal(m.isBefore(moment(new Date(2011, 3, 2, 4, 4, 5, 10)), 'second'), true, 'hour is later');\n    assert.equal(m.isBefore(moment(new Date(2011, 3, 1, 4, 1, 5, 10)), 'second'), false, 'hour is earlier');\n    assert.equal(m.isBefore(moment(new Date(2011, 3, 2, 3, 5, 5, 10)), 'second'), true, 'minute is later');\n    assert.equal(m.isBefore(moment(new Date(2011, 3, 2, 3, 3, 5, 10)), 'second'), false, 'minute is earlier');\n    assert.equal(m.isBefore(moment(new Date(2011, 3, 2, 3, 4, 6, 10)), 'second'), true, 'second is later');\n    assert.equal(m.isBefore(moment(new Date(2011, 3, 2, 3, 4, 4, 5)), 'second'), false, 'second is earlier');\n    assert.equal(m.isBefore(moment(new Date(2011, 3, 2, 3, 4, 5, 0)), 'second'), false, 'exact start of second');\n    assert.equal(m.isBefore(moment(new Date(2011, 3, 2, 3, 4, 5, 999)), 'second'), false, 'exact end of second');\n    assert.equal(m.isBefore(moment(new Date(2011, 3, 2, 3, 4, 6, 0)), 'second'), true, 'start of next second');\n    assert.equal(m.isBefore(moment(new Date(2011, 3, 2, 3, 4, 4, 999)), 'second'), false, 'end of previous second');\n    assert.equal(m.isBefore(m, 'second'), false, 'same moments are not before the same second');\n    assert.equal(+m, +mCopy, 'isBefore second should not change moment');\n});\n\ntest('is before millisecond', function (assert) {\n    var m = moment(new Date(2011, 3, 2, 3, 4, 5, 10)), mCopy = moment(m);\n    assert.equal(m.isBefore(moment(new Date(2011, 3, 2, 3, 4, 5, 10)), 'millisecond'), false, 'millisecond match');\n    assert.equal(m.isBefore(moment(new Date(2010, 3, 2, 3, 4, 5, 10)), 'milliseconds'), false, 'plural should work');\n    assert.equal(m.isBefore(moment(new Date(2012, 3, 2, 3, 4, 5, 10)), 'millisecond'), true, 'year is later');\n    assert.equal(m.isBefore(moment(new Date(2010, 3, 2, 3, 4, 5, 10)), 'millisecond'), false, 'year is earlier');\n    assert.equal(m.isBefore(moment(new Date(2011, 4, 2, 3, 4, 5, 10)), 'millisecond'), true, 'month is later');\n    assert.equal(m.isBefore(moment(new Date(2011, 2, 2, 3, 4, 5, 10)), 'millisecond'), false, 'month is earlier');\n    assert.equal(m.isBefore(moment(new Date(2011, 3, 3, 3, 4, 5, 10)), 'millisecond'), true, 'day is later');\n    assert.equal(m.isBefore(moment(new Date(2011, 3, 1, 1, 4, 5, 10)), 'millisecond'), false, 'day is earlier');\n    assert.equal(m.isBefore(moment(new Date(2011, 3, 2, 4, 4, 5, 10)), 'millisecond'), true, 'hour is later');\n    assert.equal(m.isBefore(moment(new Date(2011, 3, 1, 4, 1, 5, 10)), 'millisecond'), false, 'hour is earlier');\n    assert.equal(m.isBefore(moment(new Date(2011, 3, 2, 3, 5, 5, 10)), 'millisecond'), true, 'minute is later');\n    assert.equal(m.isBefore(moment(new Date(2011, 3, 2, 3, 3, 5, 10)), 'millisecond'), false, 'minute is earlier');\n    assert.equal(m.isBefore(moment(new Date(2011, 3, 2, 3, 4, 6, 10)), 'millisecond'), true, 'second is later');\n    assert.equal(m.isBefore(moment(new Date(2011, 3, 2, 3, 4, 4, 5)), 'millisecond'), false, 'second is earlier');\n    assert.equal(m.isBefore(moment(new Date(2011, 3, 2, 3, 4, 6, 11)), 'millisecond'), true, 'millisecond is later');\n    assert.equal(m.isBefore(moment(new Date(2011, 3, 2, 3, 4, 4, 9)), 'millisecond'), false, 'millisecond is earlier');\n    assert.equal(m.isBefore(m, 'millisecond'), false, 'same moments are not before the same millisecond');\n    assert.equal(+m, +mCopy, 'isBefore millisecond should not change moment');\n});\n\ntest('is before invalid', function (assert) {\n    var m = moment(), invalid = moment.invalid();\n    assert.equal(m.isBefore(invalid), false, 'valid moment is not before invalid moment');\n    assert.equal(invalid.isBefore(m), false, 'invalid moment is not before valid moment');\n    assert.equal(m.isBefore(invalid, 'year'), false, 'invalid moment year');\n    assert.equal(m.isBefore(invalid, 'month'), false, 'invalid moment month');\n    assert.equal(m.isBefore(invalid, 'day'), false, 'invalid moment day');\n    assert.equal(m.isBefore(invalid, 'hour'), false, 'invalid moment hour');\n    assert.equal(m.isBefore(invalid, 'minute'), false, 'invalid moment minute');\n    assert.equal(m.isBefore(invalid, 'second'), false, 'invalid moment second');\n    assert.equal(m.isBefore(invalid, 'milliseconds'), false, 'invalid moment milliseconds');\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\nfunction module$1 (name, lifecycle) {\n    QUnit.module(name, {\n        setup : function () {\n            moment.locale('en');\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'core');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            teardownDeprecationHandler(test, moment, 'core');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n}\n\nmodule$1('is between');\n\ntest('is between without units', function (assert) {\n    var m = moment(new Date(2011, 3, 2, 3, 4, 5, 10)), mCopy = moment(m);\n    assert.equal(m.isBetween(\n                moment(new Date(2009, 3, 2, 3, 4, 5, 10)),\n                moment(new Date(2011, 3, 2, 3, 4, 5, 10))), false, 'year is later');\n    assert.equal(m.isBetween(\n                moment(new Date(2011, 3, 2, 3, 4, 5, 10)),\n                moment(new Date(2013, 3, 2, 3, 4, 5, 10))), false, 'year is earlier');\n    assert.equal(m.isBetween(\n                moment(new Date(2010, 3, 2, 3, 4, 5, 10)),\n                moment(new Date(2012, 3, 2, 3, 4, 5, 10))), true, 'year is between');\n    assert.equal(m.isBetween(\n                moment(new Date(2011, 1, 2, 3, 4, 5, 10)),\n                moment(new Date(2011, 3, 2, 3, 4, 5, 10))), false, 'month is later');\n    assert.equal(m.isBetween(\n                moment(new Date(2011, 3, 2, 3, 4, 5, 10)),\n                moment(new Date(2011, 5, 2, 3, 4, 5, 10))), false, 'month is earlier');\n    assert.equal(m.isBetween(\n                moment(new Date(2011, 2, 2, 3, 4, 5, 10)),\n                moment(new Date(2011, 4, 2, 3, 4, 5, 10))), true, 'month is between');\n    assert.equal(m.isBetween(\n                moment(new Date(2011, 3, 1, 3, 4, 5, 10)),\n                moment(new Date(2011, 3, 2, 3, 4, 5, 10))), false, 'day is later');\n    assert.equal(m.isBetween(\n                moment(new Date(2011, 3, 2, 3, 4, 5, 10)),\n                moment(new Date(2011, 3, 4, 3, 4, 5, 10))), false, 'day is earlier');\n    assert.equal(m.isBetween(\n                moment(new Date(2011, 3, 1, 3, 4, 5, 10)),\n                moment(new Date(2011, 3, 3, 3, 4, 5, 10))), true, 'day is between');\n    assert.equal(m.isBetween(\n                moment(new Date(2011, 3, 2, 1, 4, 5, 10)),\n                moment(new Date(2011, 3, 2, 3, 4, 5, 10))), false, 'hour is later');\n    assert.equal(m.isBetween(\n                moment(new Date(2011, 3, 2, 3, 4, 5, 10)),\n                moment(new Date(2011, 3, 2, 5, 4, 5, 10))), false, 'hour is earlier');\n    assert.equal(m.isBetween(\n                moment(new Date(2011, 3, 2, 2, 4, 5, 10)),\n                moment(new Date(2011, 3, 2, 4, 4, 5, 10))), true, 'hour is between');\n    assert.equal(m.isBetween(\n                moment(new Date(2011, 3, 2, 3, 4, 5, 10)),\n                moment(new Date(2011, 3, 2, 3, 6, 5, 10))), false, 'minute is later');\n    assert.equal(m.isBetween(\n                moment(new Date(2011, 3, 2, 3, 2, 5, 10)),\n                moment(new Date(2011, 3, 2, 3, 4, 5, 10))), false, 'minute is earlier');\n    assert.equal(m.isBetween(\n                moment(new Date(2011, 3, 2, 3, 3, 5, 10)),\n                moment(new Date(2011, 3, 2, 3, 5, 5, 10))), true, 'minute is between');\n    assert.equal(m.isBetween(\n                moment(new Date(2011, 3, 2, 3, 4, 5, 10)),\n                moment(new Date(2011, 3, 2, 3, 4, 7, 10))), false, 'second is later');\n    assert.equal(m.isBetween(\n                moment(new Date(2011, 3, 2, 3, 4, 3, 10)),\n                moment(new Date(2011, 3, 2, 3, 4, 5, 10))), false, 'second is earlier');\n    assert.equal(m.isBetween(\n                moment(new Date(2011, 3, 2, 3, 4, 4, 10)),\n                moment(new Date(2011, 3, 2, 3, 4, 6, 10))), true, 'second is between');\n    assert.equal(m.isBetween(\n                moment(new Date(2011, 3, 2, 3, 4, 5, 10)),\n                moment(new Date(2011, 3, 2, 3, 4, 5, 12))), false, 'millisecond is later');\n    assert.equal(m.isBetween(\n                moment(new Date(2011, 3, 2, 3, 4, 5, 8)),\n                moment(new Date(2011, 3, 2, 3, 4, 5, 10))), false, 'millisecond is earlier');\n    assert.equal(m.isBetween(\n                moment(new Date(2011, 3, 2, 3, 4, 5, 9)),\n                moment(new Date(2011, 3, 2, 3, 4, 5, 11))), true, 'millisecond is between');\n    assert.equal(m.isBetween(m, m), false, 'moments are not between themselves');\n    assert.equal(+m, +mCopy, 'isBetween second should not change moment');\n});\n\ntest('is between without units inclusivity', function (assert) {\n    var m = moment(new Date(2011, 3, 2, 3, 4, 5, 10)), mCopy = moment(m);\n    assert.equal(m.isBetween(\n        moment(new Date(2011, 3, 2, 3, 4, 5, 10)),\n        moment(new Date(2012, 3, 2, 3, 4, 5, 10)), null, '()'), false, 'start and end are excluded, start is equal to moment');\n    assert.equal(m.isBetween(\n        moment(new Date(2010, 3, 2, 3, 4, 5, 10)),\n        moment(new Date(2011, 3, 2, 3, 4, 5, 10)), null, '()'), false, 'start and end are excluded, end is equal to moment');\n    assert.equal(m.isBetween(\n        moment(new Date(2010, 3, 2, 3, 4, 5, 10)),\n        moment(new Date(2012, 3, 2, 3, 4, 5, 10)), null, '()'), true, 'start and end are excluded, is between');\n    assert.equal(m.isBetween(\n        moment(new Date(2009, 3, 2, 3, 4, 5, 10)),\n        moment(new Date(2010, 3, 2, 3, 4, 5, 10)), null, '()'), false, 'start and end are excluded, is not between');\n    assert.equal(m.isBetween(\n        moment(new Date(2011, 3, 2, 3, 4, 5, 10)),\n        moment(new Date(2011, 3, 2, 3, 4, 5, 10)), null, '()'), false, 'start and end are excluded, should fail on same start/end date.');\n\n    assert.equal(m.isBetween(\n        moment(new Date(2011, 3, 2, 3, 4, 5, 10)),\n        moment(new Date(2012, 3, 2, 3, 4, 5, 10)), null, '(]'), false, 'start is excluded and end is included should fail on same start date');\n    assert.equal(m.isBetween(\n        moment(new Date(2010, 3, 2, 3, 4, 5, 10)),\n        moment(new Date(2011, 3, 2, 3, 4, 5, 10)), null, '(]'), true, 'start is excluded and end is included should succeed on end date');\n    assert.equal(m.isBetween(\n        moment(new Date(2010, 3, 2, 3, 4, 5, 10)),\n        moment(new Date(2012, 3, 2, 3, 4, 5, 10)), null, '(]'), true, 'start is excluded and end is included, is between');\n    assert.equal(m.isBetween(\n        moment(new Date(2009, 3, 2, 3, 4, 5, 10)),\n        moment(new Date(2010, 3, 2, 3, 4, 5, 10)), null, '(]'), false, 'start is excluded and end is included, is not between');\n    assert.equal(m.isBetween(\n        moment(new Date(2011, 3, 2, 3, 4, 5, 10)),\n        moment(new Date(2011, 3, 2, 3, 4, 5, 10)), null, '(]'), false, 'start is excluded and end is included, should fail on same start/end date.');\n\n    assert.equal(m.isBetween(\n        moment(new Date(2011, 3, 2, 3, 4, 5, 10)),\n        moment(new Date(2012, 3, 2, 3, 4, 5, 10)), null, '[)'), true, 'start is included and end is excluded should succeed on same start date');\n    assert.equal(m.isBetween(\n        moment(new Date(2010, 3, 2, 3, 4, 5, 10)),\n        moment(new Date(2011, 3, 2, 3, 4, 5, 10)), null, '[)'), false, 'start is included and end is excluded should fail on same end date');\n    assert.equal(m.isBetween(\n        moment(new Date(2010, 3, 2, 3, 4, 5, 10)),\n        moment(new Date(2012, 3, 2, 3, 4, 5, 10)), null, '[)'), true, 'start is included and end is excluded, is between');\n    assert.equal(m.isBetween(\n        moment(new Date(2009, 3, 2, 3, 4, 5, 10)),\n        moment(new Date(2010, 3, 2, 3, 4, 5, 10)), null, '[)'), false, 'start is included and end is excluded, is not between');\n    assert.equal(m.isBetween(\n        moment(new Date(2011, 3, 2, 3, 4, 5, 10)),\n        moment(new Date(2011, 3, 2, 3, 4, 5, 10)), null, '[)'), false, 'start is included and end is excluded, should fail on same end and start date');\n\n    assert.equal(m.isBetween(\n        moment(new Date(2011, 3, 2, 3, 4, 5, 10)),\n        moment(new Date(2012, 3, 2, 3, 4, 5, 10)), null, '[]'), true, 'start and end inclusive should succeed on same start date');\n    assert.equal(m.isBetween(\n        moment(new Date(2010, 3, 2, 3, 4, 5, 10)),\n        moment(new Date(2011, 3, 2, 3, 4, 5, 10)), null, '[]'), true, 'start and end inclusive should succeed on same end date');\n    assert.equal(m.isBetween(\n        moment(new Date(2010, 3, 2, 3, 4, 5, 10)),\n        moment(new Date(2012, 3, 2, 3, 4, 5, 10)), null, '[]'), true, 'start and end inclusive, is between');\n    assert.equal(m.isBetween(\n        moment(new Date(2009, 3, 2, 3, 4, 5, 10)),\n        moment(new Date(2010, 3, 2, 3, 4, 5, 10)), null, '[]'), false, 'start and end inclusive, is not between');\n    assert.equal(m.isBetween(\n        moment(new Date(2011, 3, 2, 3, 4, 5, 10)),\n        moment(new Date(2011, 3, 2, 3, 4, 5, 10)), null, '[]'), true, 'start and end inclusive, should handle same end and start date');\n});\n\ntest('is between milliseconds inclusivity', function (assert) {\n    var m = moment(new Date(2011, 3, 2, 3, 4, 5, 10)), mCopy = moment(m);\n    assert.equal(m.isBetween(\n        moment(new Date(2010, 3, 2, 3, 4, 5, 10)),\n        moment(new Date(2012, 3, 2, 3, 4, 5, 10)), 'milliseconds'), true, 'options, no inclusive');\n    assert.equal(m.isBetween(\n        moment(new Date(2011, 3, 2, 3, 4, 5, 10)),\n        moment(new Date(2012, 3, 2, 3, 4, 5, 10)), 'milliseconds', '()'), false, 'start and end are excluded, start is equal to moment');\n    assert.equal(m.isBetween(\n        moment(new Date(2010, 3, 2, 3, 4, 5, 10)),\n        moment(new Date(2011, 3, 2, 3, 4, 5, 10)), 'milliseconds', '()'), false, 'start and end are excluded, end is equal to moment');\n    assert.equal(m.isBetween(\n        moment(new Date(2010, 3, 2, 3, 4, 5, 10)),\n        moment(new Date(2012, 3, 2, 3, 4, 5, 10)), 'milliseconds', '()'), true, 'start and end are excluded, is between');\n    assert.equal(m.isBetween(\n        moment(new Date(2009, 3, 2, 3, 4, 5, 10)),\n        moment(new Date(2010, 3, 2, 3, 4, 5, 10)), 'milliseconds', '()'), false, 'start and end are excluded, is not between');\n    assert.equal(m.isBetween(\n        moment(new Date(2011, 3, 2, 3, 4, 5, 10)),\n        moment(new Date(2011, 3, 2, 3, 4, 5, 10)), 'milliseconds', '()'), false, 'start and end are excluded, should fail on same start/end date.');\n\n    assert.equal(m.isBetween(\n        moment(new Date(2011, 3, 2, 3, 4, 5, 10)),\n        moment(new Date(2012, 3, 2, 3, 4, 5, 10)), 'milliseconds', '(]'), false, 'start is excluded and end is included should fail on same start date');\n    assert.equal(m.isBetween(\n        moment(new Date(2010, 3, 2, 3, 4, 5, 10)),\n        moment(new Date(2011, 3, 2, 3, 4, 5, 10)), 'milliseconds', '(]'), true, 'start is excluded and end is included should succeed on end date');\n    assert.equal(m.isBetween(\n        moment(new Date(2010, 3, 2, 3, 4, 5, 10)),\n        moment(new Date(2012, 3, 2, 3, 4, 5, 10)), 'milliseconds', '(]'), true, 'start is excluded and end is included, is between');\n    assert.equal(m.isBetween(\n        moment(new Date(2009, 3, 2, 3, 4, 5, 10)),\n        moment(new Date(2010, 3, 2, 3, 4, 5, 10)), 'milliseconds', '(]'), false, 'start is excluded and end is included, is not between');\n    assert.equal(m.isBetween(\n        moment(new Date(2011, 3, 2, 3, 4, 5, 10)),\n        moment(new Date(2011, 3, 2, 3, 4, 5, 10)), 'milliseconds', '(]'), false, 'start is excluded and end is included, should fail on same start/end date.');\n\n    assert.equal(m.isBetween(\n        moment(new Date(2011, 3, 2, 3, 4, 5, 10)),\n        moment(new Date(2012, 3, 2, 3, 4, 5, 10)), 'milliseconds', '[)'), true, 'start is included and end is excluded should succeed on same start date');\n    assert.equal(m.isBetween(\n        moment(new Date(2010, 3, 2, 3, 4, 5, 10)),\n        moment(new Date(2011, 3, 2, 3, 4, 5, 10)), 'milliseconds', '[)'), false, 'start is included and end is excluded should fail on same end date');\n    assert.equal(m.isBetween(\n        moment(new Date(2010, 3, 2, 3, 4, 5, 10)),\n        moment(new Date(2012, 3, 2, 3, 4, 5, 10)), 'milliseconds', '[)'), true, 'start is included and end is excluded, is between');\n    assert.equal(m.isBetween(\n        moment(new Date(2009, 3, 2, 3, 4, 5, 10)),\n        moment(new Date(2010, 3, 2, 3, 4, 5, 10)), 'milliseconds', '[)'), false, 'start is included and end is excluded, is not between');\n    assert.equal(m.isBetween(\n        moment(new Date(2011, 3, 2, 3, 4, 5, 10)),\n        moment(new Date(2011, 3, 2, 3, 4, 5, 10)), 'milliseconds', '[)'), false, 'start is included and end is excluded, should fail on same end and start date');\n\n    assert.equal(m.isBetween(\n        moment(new Date(2011, 3, 2, 3, 4, 5, 10)),\n        moment(new Date(2012, 3, 2, 3, 4, 5, 10)), 'milliseconds', '[]'), true, 'start and end inclusive should succeed on same start date');\n    assert.equal(m.isBetween(\n        moment(new Date(2010, 3, 2, 3, 4, 5, 10)),\n        moment(new Date(2011, 3, 2, 3, 4, 5, 10)), 'milliseconds', '[]'), true, 'start and end inclusive should succeed on same end date');\n    assert.equal(m.isBetween(\n        moment(new Date(2010, 3, 2, 3, 4, 5, 10)),\n        moment(new Date(2012, 3, 2, 3, 4, 5, 10)), 'milliseconds', '[]'), true, 'start and end inclusive, is between');\n    assert.equal(m.isBetween(\n        moment(new Date(2009, 3, 2, 3, 4, 5, 10)),\n        moment(new Date(2010, 3, 2, 3, 4, 5, 10)), 'milliseconds', '[]'), false, 'start and end inclusive, is not between');\n    assert.equal(m.isBetween(\n        moment(new Date(2011, 3, 2, 3, 4, 5, 10)),\n        moment(new Date(2011, 3, 2, 3, 4, 5, 10)), 'milliseconds', '[]'), true, 'start and end inclusive, should handle same end and start date');\n});\n\ntest('is between year', function (assert) {\n    var m = moment(new Date(2011, 1, 2, 3, 4, 5, 6)), mCopy = moment(m);\n    assert.equal(m.isBetween(\n                moment(new Date(2011, 5, 6, 7, 8, 9, 10)),\n                moment(new Date(2011, 5, 6, 7, 8, 9, 10)), 'year'), false, 'year match');\n    assert.equal(m.isBetween(\n                moment(new Date(2010, 5, 6, 7, 8, 9, 10)),\n                moment(new Date(2012, 5, 6, 7, 8, 9, 10)), 'years'), true, 'plural should work');\n    assert.equal(m.isBetween(\n                moment(new Date(2010, 5, 6, 7, 8, 9, 10)),\n                moment(new Date(2012, 5, 6, 7, 8, 9, 10)), 'year'), true, 'year is between');\n    assert.equal(m.isBetween(\n                moment(new Date(2011, 5, 6, 7, 8, 9, 10)),\n                moment(new Date(2013, 5, 6, 7, 8, 9, 10)), 'year'), false, 'year is earlier');\n    assert.equal(m.isBetween(\n                moment(new Date(2010, 5, 6, 7, 8, 9, 10)),\n                moment(new Date(2011, 5, 6, 7, 8, 9, 10)), 'year'), false, 'year is later');\n    assert.equal(m.isBetween(m, 'year'), false, 'same moments are not between the same year');\n    assert.equal(+m, +mCopy, 'isBetween year should not change moment');\n});\n\ntest('is between month', function (assert) {\n    var m = moment(new Date(2011, 1, 2, 3, 4, 5, 6)), mCopy = moment(m);\n    assert.equal(m.isBetween(\n                moment(new Date(2011, 1, 6, 7, 8, 9, 10)),\n                moment(new Date(2011, 1, 6, 7, 8, 9, 10)), 'month'), false, 'month match');\n    assert.equal(m.isBetween(\n                moment(new Date(2011, 0, 6, 7, 8, 9, 10)),\n                moment(new Date(2011, 2, 6, 7, 8, 9, 10)), 'months'), true, 'plural should work');\n    assert.equal(m.isBetween(\n                moment(new Date(2011, 0, 31, 23, 59, 59, 999)),\n                moment(new Date(2011, 2, 1, 0, 0, 0, 0)), 'month'), true, 'month is between');\n    assert.equal(m.isBetween(\n                moment(new Date(2011, 1, 6, 7, 8, 9, 10)),\n                moment(new Date(2011, 2, 6, 7, 8, 9, 10)), 'month'), false, 'month is earlier');\n    assert.equal(m.isBetween(\n                moment(new Date(2011, 11, 6, 7, 8, 9, 10)),\n                moment(new Date(2011, 1, 6, 7, 8, 9, 10)), 'month'), false, 'month is later');\n    assert.equal(m.isBetween(m, 'month'), false, 'same moments are not between the same month');\n    assert.equal(+m, +mCopy, 'isBetween month should not change moment');\n});\n\ntest('is between day', function (assert) {\n    var m = moment(new Date(2011, 1, 2, 3, 4, 5, 6)), mCopy = moment(m);\n    assert.equal(m.isBetween(\n                moment(new Date(2011, 1, 2, 7, 8, 9, 10)),\n                moment(new Date(2011, 1, 2, 7, 8, 9, 10)), 'day'), false, 'day match');\n    assert.equal(m.isBetween(\n                moment(new Date(2011, 1, 1, 7, 8, 9, 10)),\n                moment(new Date(2011, 1, 3, 7, 8, 9, 10)), 'days'), true, 'plural should work');\n    assert.equal(m.isBetween(\n                moment(new Date(2011, 1, 1, 7, 8, 9, 10)),\n                moment(new Date(2011, 1, 3, 7, 8, 9, 10)), 'day'), true, 'day is between');\n    assert.equal(m.isBetween(\n                moment(new Date(2011, 1, 2, 7, 8, 9, 10)),\n                moment(new Date(2011, 1, 4, 7, 8, 9, 10)), 'day'), false, 'day is earlier');\n    assert.equal(m.isBetween(\n                moment(new Date(2011, 1, 1, 7, 8, 9, 10)),\n                moment(new Date(2011, 1, 2, 7, 8, 9, 10)), 'day'), false, 'day is later');\n    assert.equal(m.isBetween(m, 'day'), false, 'same moments are not between the same day');\n    assert.equal(+m, +mCopy, 'isBetween day should not change moment');\n});\n\ntest('is between hour', function (assert) {\n    var m = moment(new Date(2011, 1, 2, 3, 4, 5, 6)), mCopy = moment(m);\n    assert.equal(m.isBetween(\n                moment(new Date(2011, 1, 2, 3, 5, 9, 10)),\n                moment(new Date(2011, 1, 2, 3, 9, 9, 10)), 'hour'), false, 'hour match');\n    assert.equal(m.isBetween(\n                moment(new Date(2011, 1, 2, 1, 59, 59, 999)),\n                moment(new Date(2011, 1, 2, 4, 0, 0, 0)), 'hours'), true, 'plural should work');\n    assert.equal(m.isBetween(\n                moment(new Date(2011, 1, 2, 2, 59, 59, 999)),\n                moment(new Date(2011, 1, 2, 4, 0, 0, 0)), 'hour'), true, 'hour is between');\n    assert.equal(m.isBetween(\n                moment(new Date(2011, 1, 2, 7, 8, 9, 10)),\n                moment(new Date(2011, 1, 2, 7, 8, 9, 10)), 'hour'), false, 'hour is earlier');\n    assert.equal(m.isBetween(\n                moment(new Date(2011, 1, 2, 7, 8, 9, 10)),\n                moment(new Date(2011, 1, 2, 7, 8, 9, 10)), 'hour'), false, 'hour is later');\n    assert.equal(m.isBetween(m, 'hour'), false, 'same moments are not between the same hour');\n    assert.equal(+m, +mCopy, 'isBetween hour should not change moment');\n});\n\ntest('is between minute', function (assert) {\n    var m = moment(new Date(2011, 1, 2, 3, 4, 5, 6)), mCopy = moment(m);\n    assert.equal(m.isBetween(\n                moment(new Date(2011, 1, 2, 3, 4, 9, 10)),\n                moment(new Date(2011, 1, 2, 3, 4, 9, 10)), 'minute'), false, 'minute match');\n    assert.equal(m.isBetween(\n                moment(new Date(2011, 1, 2, 3, 3, 9, 10)),\n                moment(new Date(2011, 1, 2, 3, 5, 9, 10)), 'minutes'), true, 'plural should work');\n    assert.equal(m.isBetween(\n                moment(new Date(2011, 1, 2, 3, 3, 59, 999)),\n                moment(new Date(2011, 1, 2, 3, 5, 0, 0)), 'minute'), true, 'minute is between');\n    assert.equal(m.isBetween(\n                moment(new Date(2011, 1, 2, 3, 5, 0, 0)),\n                moment(new Date(2011, 1, 2, 3, 8, 9, 10)), 'minute'), false, 'minute is earlier');\n    assert.equal(m.isBetween(\n                moment(new Date(2011, 1, 2, 3, 2, 9, 10)),\n                moment(new Date(2011, 1, 2, 3, 3, 59, 999)), 'minute'), false, 'minute is later');\n    assert.equal(m.isBetween(m, 'minute'), false, 'same moments are not between the same minute');\n    assert.equal(+m, +mCopy, 'isBetween minute should not change moment');\n});\n\ntest('is between second', function (assert) {\n    var m = moment(new Date(2011, 1, 2, 3, 4, 5, 6)), mCopy = moment(m);\n    assert.equal(m.isBetween(\n                moment(new Date(2011, 1, 2, 3, 4, 5, 10)),\n                moment(new Date(2011, 1, 2, 3, 4, 5, 10)), 'second'), false, 'second match');\n    assert.equal(m.isBetween(\n                moment(new Date(2011, 1, 2, 3, 4, 4, 10)),\n                moment(new Date(2011, 1, 2, 3, 4, 6, 10)), 'seconds'), true, 'plural should work');\n    assert.equal(m.isBetween(\n                moment(new Date(2011, 1, 2, 3, 4, 4, 999)),\n                moment(new Date(2011, 1, 2, 3, 4, 6, 0)), 'second'), true, 'second is between');\n    assert.equal(m.isBetween(\n                moment(new Date(2011, 1, 2, 3, 4, 6, 0)),\n                moment(new Date(2011, 1, 2, 3, 4, 7, 10)), 'second'), false, 'second is earlier');\n    assert.equal(m.isBetween(\n                moment(new Date(2011, 1, 2, 3, 4, 3, 10)),\n                moment(new Date(2011, 1, 2, 3, 4, 4, 999)), 'second'), false, 'second is later');\n    assert.equal(m.isBetween(m, 'second'), false, 'same moments are not between the same second');\n    assert.equal(+m, +mCopy, 'isBetween second should not change moment');\n});\n\ntest('is between millisecond', function (assert) {\n    var m = moment(new Date(2011, 1, 2, 3, 4, 5, 6)), mCopy = moment(m);\n    assert.equal(m.isBetween(\n                moment(new Date(2011, 1, 2, 3, 4, 5, 6)),\n                moment(new Date(2011, 1, 2, 3, 4, 5, 6)), 'millisecond'), false, 'millisecond match');\n    assert.equal(m.isBetween(\n                moment(new Date(2011, 1, 2, 3, 4, 5, 5)),\n                moment(new Date(2011, 1, 2, 3, 4, 5, 7)), 'milliseconds'), true, 'plural should work');\n    assert.equal(m.isBetween(\n                moment(new Date(2011, 1, 2, 3, 4, 5, 5)),\n                moment(new Date(2011, 1, 2, 3, 4, 5, 7)), 'millisecond'), true, 'millisecond is between');\n    assert.equal(m.isBetween(\n                moment(new Date(2011, 1, 2, 3, 4, 5, 7)),\n                moment(new Date(2011, 1, 2, 3, 4, 5, 10)), 'millisecond'), false, 'millisecond is earlier');\n    assert.equal(m.isBetween(\n                moment(new Date(2011, 1, 2, 3, 4, 5, 4)),\n                moment(new Date(2011, 1, 2, 3, 4, 5, 6)), 'millisecond'), false, 'millisecond is later');\n    assert.equal(m.isBetween(m, 'millisecond'), false, 'same moments are not between the same millisecond');\n    assert.equal(+m, +mCopy, 'isBetween millisecond should not change moment');\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\nfunction module$1 (name, lifecycle) {\n    QUnit.module(name, {\n        setup : function () {\n            moment.locale('en');\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'core');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            teardownDeprecationHandler(test, moment, 'core');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n}\n\nmodule$1('is date');\n\ntest('isDate recognizes Date objects', function (assert) {\n    assert.ok(moment.isDate(new Date()), 'no args (now)');\n    assert.ok(moment.isDate(new Date([2014, 2, 15])), 'array args');\n    assert.ok(moment.isDate(new Date('2014-03-15')), 'string args');\n    assert.ok(moment.isDate(new Date('does NOT look like a date')), 'invalid date');\n});\n\ntest('isDate rejects non-Date objects', function (assert) {\n    assert.ok(!moment.isDate(), 'nothing');\n    assert.ok(!moment.isDate(undefined), 'undefined');\n    assert.ok(!moment.isDate(null), 'string args');\n    assert.ok(!moment.isDate(42), 'number');\n    assert.ok(!moment.isDate('2014-03-15'), 'string');\n    assert.ok(!moment.isDate([2014, 2, 15]), 'array');\n    assert.ok(!moment.isDate({year: 2014, month: 2, day: 15}), 'object');\n    assert.ok(!moment.isDate({\n        toString: function () {\n            return '[object Date]';\n        }\n    }), 'lying object');\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\nfunction module$1 (name, lifecycle) {\n    QUnit.module(name, {\n        setup : function () {\n            moment.locale('en');\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'core');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            teardownDeprecationHandler(test, moment, 'core');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n}\n\nmodule$1('is moment');\n\ntest('is moment object', function (assert) {\n    var MyObj = function () {},\n        extend = function (a, b) {\n            var i;\n            for (i in b) {\n                a[i] = b[i];\n            }\n            return a;\n        };\n    MyObj.prototype.toDate = function () {\n        return new Date();\n    };\n\n    assert.ok(moment.isMoment(moment()), 'simple moment object');\n    assert.ok(moment.isMoment(moment(null)), 'invalid moment object');\n    assert.ok(moment.isMoment(extend({}, moment())), 'externally cloned moments are moments');\n    assert.ok(moment.isMoment(extend({}, moment.utc())), 'externally cloned utc moments are moments');\n\n    assert.ok(!moment.isMoment(new MyObj()), 'myObj is not moment object');\n    assert.ok(!moment.isMoment(moment), 'moment function is not moment object');\n    assert.ok(!moment.isMoment(new Date()), 'date object is not moment object');\n    assert.ok(!moment.isMoment(Object), 'Object is not moment object');\n    assert.ok(!moment.isMoment('foo'), 'string is not moment object');\n    assert.ok(!moment.isMoment(1), 'number is not moment object');\n    assert.ok(!moment.isMoment(NaN), 'NaN is not moment object');\n    assert.ok(!moment.isMoment(null), 'null is not moment object');\n    assert.ok(!moment.isMoment(undefined), 'undefined is not moment object');\n});\n\ntest('is moment with hacked hasOwnProperty', function (assert) {\n    var obj = {};\n    // HACK to suppress jshint warning about bad property name\n    obj['hasOwnMoney'.replace('Money', 'Property')] = function () {\n        return true;\n    };\n\n    assert.ok(!moment.isMoment(obj), 'isMoment works even if passed object has a wrong hasOwnProperty implementation (ie8)');\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\nfunction isNumber(input) {\n    return typeof input === 'number' || Object.prototype.toString.call(input) === '[object Number]';\n}\n\ntest('isNumber recognizes numbers', function (assert) {\n    assert.ok(isNumber(1), 'simple integer');\n    assert.ok(isNumber(0), 'simple number');\n    assert.ok(isNumber(-0), 'silly number');\n    assert.ok(isNumber(1010010293029), 'large number');\n    assert.ok(isNumber(Infinity), 'largest number');\n    assert.ok(isNumber(-Infinity), 'smallest number');\n    assert.ok(isNumber(NaN), 'not number');\n    assert.ok(isNumber(1.100393830000), 'decimal numbers');\n    assert.ok(isNumber(Math.LN2), 'natural log of two');\n    assert.ok(isNumber(Math.PI), 'delicious number');\n    assert.ok(isNumber(5e10), 'scientifically notated number');\n    assert.ok(isNumber(new Number(1)), 'number primitive wrapped in an object'); // jshint ignore:line\n});\n\ntest('isNumber rejects non-numbers', function (assert) {\n    assert.ok(!isNumber(), 'nothing');\n    assert.ok(!isNumber(undefined), 'undefined');\n    assert.ok(!isNumber(null), 'null');\n    assert.ok(!isNumber([1]), 'array');\n    assert.ok(!isNumber('[1,2,3]'), 'string');\n    assert.ok(!isNumber(new Date()), 'date');\n    assert.ok(!isNumber({a:1,b:2}), 'object');\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\nfunction module$1 (name, lifecycle) {\n    QUnit.module(name, {\n        setup : function () {\n            moment.locale('en');\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'core');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            teardownDeprecationHandler(test, moment, 'core');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n}\n\nmodule$1('is same');\n\ntest('is same without units', function (assert) {\n    var m = moment(new Date(2011, 3, 2, 3, 4, 5, 10)), mCopy = moment(m);\n    assert.equal(m.isSame(moment(new Date(2012, 3, 2, 3, 5, 5, 10))), false, 'year is later');\n    assert.equal(m.isSame(moment(new Date(2010, 3, 2, 3, 3, 5, 10))), false, 'year is earlier');\n    assert.equal(m.isSame(moment(new Date(2011, 4, 2, 3, 4, 5, 10))), false, 'month is later');\n    assert.equal(m.isSame(moment(new Date(2011, 2, 2, 3, 4, 5, 10))), false, 'month is earlier');\n    assert.equal(m.isSame(moment(new Date(2011, 3, 3, 3, 4, 5, 10))), false, 'day is later');\n    assert.equal(m.isSame(moment(new Date(2011, 3, 1, 3, 4, 5, 10))), false, 'day is earlier');\n    assert.equal(m.isSame(moment(new Date(2011, 3, 2, 4, 4, 5, 10))), false, 'hour is later');\n    assert.equal(m.isSame(moment(new Date(2011, 3, 2, 2, 4, 5, 10))), false, 'hour is earlier');\n    assert.equal(m.isSame(moment(new Date(2011, 3, 2, 3, 5, 5, 10))), false, 'minute is later');\n    assert.equal(m.isSame(moment(new Date(2011, 3, 2, 3, 3, 5, 10))), false, 'minute is earlier');\n    assert.equal(m.isSame(moment(new Date(2011, 3, 2, 3, 4, 6, 10))), false, 'second is later');\n    assert.equal(m.isSame(moment(new Date(2011, 3, 2, 3, 4, 4, 11))), false, 'second is earlier');\n    assert.equal(m.isSame(moment(new Date(2011, 3, 2, 3, 4, 5, 10))), true, 'millisecond match');\n    assert.equal(m.isSame(moment(new Date(2011, 3, 2, 3, 4, 5, 11))), false, 'millisecond is later');\n    assert.equal(m.isSame(moment(new Date(2011, 3, 2, 3, 4, 5, 9))), false, 'millisecond is earlier');\n    assert.equal(m.isSame(m), true, 'moments are the same as themselves');\n    assert.equal(+m, +mCopy, 'isSame second should not change moment');\n});\n\ntest('is same year', function (assert) {\n    var m = moment(new Date(2011, 1, 2, 3, 4, 5, 6)), mCopy = moment(m);\n    assert.equal(m.isSame(moment(new Date(2011, 5, 6, 7, 8, 9, 10)), 'year'), true, 'year match');\n    assert.equal(m.isSame(moment(new Date(2011, 5, 6, 7, 8, 9, 10)), 'years'), true, 'plural should work');\n    assert.equal(m.isSame(moment(new Date(2012, 5, 6, 7, 8, 9, 10)), 'year'), false, 'year mismatch');\n    assert.equal(m.isSame(moment(new Date(2011, 0, 1, 0, 0, 0, 0)), 'year'), true, 'exact start of year');\n    assert.equal(m.isSame(moment(new Date(2011, 11, 31, 23, 59, 59, 999)), 'year'), true, 'exact end of year');\n    assert.equal(m.isSame(moment(new Date(2012, 0, 1, 0, 0, 0, 0)), 'year'), false, 'start of next year');\n    assert.equal(m.isSame(moment(new Date(2010, 11, 31, 23, 59, 59, 999)), 'year'), false, 'end of previous year');\n    assert.equal(m.isSame(m, 'year'), true, 'same moments are in the same year');\n    assert.equal(+m, +mCopy, 'isSame year should not change moment');\n});\n\ntest('is same month', function (assert) {\n    var m = moment(new Date(2011, 2, 3, 4, 5, 6, 7)), mCopy = moment(m);\n    assert.equal(m.isSame(moment(new Date(2011, 2, 6, 7, 8, 9, 10)), 'month'), true, 'month match');\n    assert.equal(m.isSame(moment(new Date(2011, 2, 6, 7, 8, 9, 10)), 'months'), true, 'plural should work');\n    assert.equal(m.isSame(moment(new Date(2012, 2, 6, 7, 8, 9, 10)), 'month'), false, 'year mismatch');\n    assert.equal(m.isSame(moment(new Date(2011, 5, 6, 7, 8, 9, 10)), 'month'), false, 'month mismatch');\n    assert.equal(m.isSame(moment(new Date(2011, 2, 1, 0, 0, 0, 0)), 'month'), true, 'exact start of month');\n    assert.equal(m.isSame(moment(new Date(2011, 2, 31, 23, 59, 59, 999)), 'month'), true, 'exact end of month');\n    assert.equal(m.isSame(moment(new Date(2011, 3, 1, 0, 0, 0, 0)), 'month'), false, 'start of next month');\n    assert.equal(m.isSame(moment(new Date(2011, 1, 27, 23, 59, 59, 999)), 'month'), false, 'end of previous month');\n    assert.equal(m.isSame(m, 'month'), true, 'same moments are in the same month');\n    assert.equal(+m, +mCopy, 'isSame month should not change moment');\n});\n\ntest('is same day', function (assert) {\n    var m = moment(new Date(2011, 1, 2, 3, 4, 5, 6)), mCopy = moment(m);\n    assert.equal(m.isSame(moment(new Date(2011, 1, 2, 7, 8, 9, 10)), 'day'), true, 'day match');\n    assert.equal(m.isSame(moment(new Date(2011, 1, 2, 7, 8, 9, 10)), 'days'), true, 'plural should work');\n    assert.equal(m.isSame(moment(new Date(2012, 1, 2, 7, 8, 9, 10)), 'day'), false, 'year mismatch');\n    assert.equal(m.isSame(moment(new Date(2011, 2, 2, 7, 8, 9, 10)), 'day'), false, 'month mismatch');\n    assert.equal(m.isSame(moment(new Date(2011, 1, 3, 7, 8, 9, 10)), 'day'), false, 'day mismatch');\n    assert.equal(m.isSame(moment(new Date(2011, 1, 2, 0, 0, 0, 0)), 'day'), true, 'exact start of day');\n    assert.equal(m.isSame(moment(new Date(2011, 1, 2, 23, 59, 59, 999)), 'day'), true, 'exact end of day');\n    assert.equal(m.isSame(moment(new Date(2011, 1, 3, 0, 0, 0, 0)), 'day'), false, 'start of next day');\n    assert.equal(m.isSame(moment(new Date(2011, 1, 1, 23, 59, 59, 999)), 'day'), false, 'end of previous day');\n    assert.equal(m.isSame(m, 'day'), true, 'same moments are in the same day');\n    assert.equal(+m, +mCopy, 'isSame day should not change moment');\n});\n\ntest('is same hour', function (assert) {\n    var m = moment(new Date(2011, 1, 2, 3, 4, 5, 6)), mCopy = moment(m);\n    assert.equal(m.isSame(moment(new Date(2011, 1, 2, 3, 8, 9, 10)), 'hour'), true, 'hour match');\n    assert.equal(m.isSame(moment(new Date(2011, 1, 2, 3, 8, 9, 10)), 'hours'), true, 'plural should work');\n    assert.equal(m.isSame(moment(new Date(2012, 1, 2, 3, 8, 9, 10)), 'hour'), false, 'year mismatch');\n    assert.equal(m.isSame(moment(new Date(2011, 2, 2, 3, 8, 9, 10)), 'hour'), false, 'month mismatch');\n    assert.equal(m.isSame(moment(new Date(2011, 1, 3, 3, 8, 9, 10)), 'hour'), false, 'day mismatch');\n    assert.equal(m.isSame(moment(new Date(2011, 1, 2, 4, 8, 9, 10)), 'hour'), false, 'hour mismatch');\n    assert.equal(m.isSame(moment(new Date(2011, 1, 2, 3, 0, 0, 0)), 'hour'), true, 'exact start of hour');\n    assert.equal(m.isSame(moment(new Date(2011, 1, 2, 3, 59, 59, 999)), 'hour'), true, 'exact end of hour');\n    assert.equal(m.isSame(moment(new Date(2011, 1, 2, 4, 0, 0, 0)), 'hour'), false, 'start of next hour');\n    assert.equal(m.isSame(moment(new Date(2011, 1, 2, 2, 59, 59, 999)), 'hour'), false, 'end of previous hour');\n    assert.equal(m.isSame(m, 'hour'), true, 'same moments are in the same hour');\n    assert.equal(+m, +mCopy, 'isSame hour should not change moment');\n});\n\ntest('is same minute', function (assert) {\n    var m = moment(new Date(2011, 1, 2, 3, 4, 5, 6)), mCopy = moment(m);\n    assert.equal(m.isSame(moment(new Date(2011, 1, 2, 3, 4, 9, 10)), 'minute'), true, 'minute match');\n    assert.equal(m.isSame(moment(new Date(2011, 1, 2, 3, 4, 9, 10)), 'minutes'), true, 'plural should work');\n    assert.equal(m.isSame(moment(new Date(2012, 1, 2, 3, 4, 9, 10)), 'minute'), false, 'year mismatch');\n    assert.equal(m.isSame(moment(new Date(2011, 2, 2, 3, 4, 9, 10)), 'minute'), false, 'month mismatch');\n    assert.equal(m.isSame(moment(new Date(2011, 1, 3, 3, 4, 9, 10)), 'minute'), false, 'day mismatch');\n    assert.equal(m.isSame(moment(new Date(2011, 1, 2, 4, 4, 9, 10)), 'minute'), false, 'hour mismatch');\n    assert.equal(m.isSame(moment(new Date(2011, 1, 2, 3, 5, 9, 10)), 'minute'), false, 'minute mismatch');\n    assert.equal(m.isSame(moment(new Date(2011, 1, 2, 3, 4, 0, 0)), 'minute'), true, 'exact start of minute');\n    assert.equal(m.isSame(moment(new Date(2011, 1, 2, 3, 4, 59, 999)), 'minute'), true, 'exact end of minute');\n    assert.equal(m.isSame(moment(new Date(2011, 1, 2, 3, 5, 0, 0)), 'minute'), false, 'start of next minute');\n    assert.equal(m.isSame(moment(new Date(2011, 1, 2, 3, 3, 59, 999)), 'minute'), false, 'end of previous minute');\n    assert.equal(m.isSame(m, 'minute'), true, 'same moments are in the same minute');\n    assert.equal(+m, +mCopy, 'isSame minute should not change moment');\n});\n\ntest('is same second', function (assert) {\n    var m = moment(new Date(2011, 1, 2, 3, 4, 5, 6)), mCopy = moment(m);\n    assert.equal(m.isSame(moment(new Date(2011, 1, 2, 3, 4, 5, 10)), 'second'), true, 'second match');\n    assert.equal(m.isSame(moment(new Date(2011, 1, 2, 3, 4, 5, 10)), 'seconds'), true, 'plural should work');\n    assert.equal(m.isSame(moment(new Date(2012, 1, 2, 3, 4, 5, 10)), 'second'), false, 'year mismatch');\n    assert.equal(m.isSame(moment(new Date(2011, 2, 2, 3, 4, 5, 10)), 'second'), false, 'month mismatch');\n    assert.equal(m.isSame(moment(new Date(2011, 1, 3, 3, 4, 5, 10)), 'second'), false, 'day mismatch');\n    assert.equal(m.isSame(moment(new Date(2011, 1, 2, 4, 4, 5, 10)), 'second'), false, 'hour mismatch');\n    assert.equal(m.isSame(moment(new Date(2011, 1, 2, 3, 5, 5, 10)), 'second'), false, 'minute mismatch');\n    assert.equal(m.isSame(moment(new Date(2011, 1, 2, 3, 4, 6, 10)), 'second'), false, 'second mismatch');\n    assert.equal(m.isSame(moment(new Date(2011, 1, 2, 3, 4, 5, 0)), 'second'), true, 'exact start of second');\n    assert.equal(m.isSame(moment(new Date(2011, 1, 2, 3, 4, 5, 999)), 'second'), true, 'exact end of second');\n    assert.equal(m.isSame(moment(new Date(2011, 1, 2, 3, 4, 6, 0)), 'second'), false, 'start of next second');\n    assert.equal(m.isSame(moment(new Date(2011, 1, 2, 3, 4, 4, 999)), 'second'), false, 'end of previous second');\n    assert.equal(m.isSame(m, 'second'), true, 'same moments are in the same second');\n    assert.equal(+m, +mCopy, 'isSame second should not change moment');\n});\n\ntest('is same millisecond', function (assert) {\n    var m = moment(new Date(2011, 3, 2, 3, 4, 5, 10)), mCopy = moment(m);\n    assert.equal(m.isSame(moment(new Date(2011, 3, 2, 3, 4, 5, 10)), 'millisecond'), true, 'millisecond match');\n    assert.equal(m.isSame(moment(new Date(2011, 3, 2, 3, 4, 5, 10)), 'milliseconds'), true, 'plural should work');\n    assert.equal(m.isSame(moment(new Date(2012, 3, 2, 3, 4, 5, 10)), 'millisecond'), false, 'year is later');\n    assert.equal(m.isSame(moment(new Date(2010, 3, 2, 3, 4, 5, 10)), 'millisecond'), false, 'year is earlier');\n    assert.equal(m.isSame(moment(new Date(2011, 4, 2, 3, 4, 5, 10)), 'millisecond'), false, 'month is later');\n    assert.equal(m.isSame(moment(new Date(2011, 2, 2, 3, 4, 5, 10)), 'millisecond'), false, 'month is earlier');\n    assert.equal(m.isSame(moment(new Date(2011, 3, 3, 3, 4, 5, 10)), 'millisecond'), false, 'day is later');\n    assert.equal(m.isSame(moment(new Date(2011, 3, 1, 1, 4, 5, 10)), 'millisecond'), false, 'day is earlier');\n    assert.equal(m.isSame(moment(new Date(2011, 3, 2, 4, 4, 5, 10)), 'millisecond'), false, 'hour is later');\n    assert.equal(m.isSame(moment(new Date(2011, 3, 1, 4, 1, 5, 10)), 'millisecond'), false, 'hour is earlier');\n    assert.equal(m.isSame(moment(new Date(2011, 3, 2, 3, 5, 5, 10)), 'millisecond'), false, 'minute is later');\n    assert.equal(m.isSame(moment(new Date(2011, 3, 2, 3, 3, 5, 10)), 'millisecond'), false, 'minute is earlier');\n    assert.equal(m.isSame(moment(new Date(2011, 3, 2, 3, 4, 6, 10)), 'millisecond'), false, 'second is later');\n    assert.equal(m.isSame(moment(new Date(2011, 3, 2, 3, 4, 4, 5)), 'millisecond'), false, 'second is earlier');\n    assert.equal(m.isSame(moment(new Date(2011, 3, 2, 3, 4, 6, 11)), 'millisecond'), false, 'millisecond is later');\n    assert.equal(m.isSame(moment(new Date(2011, 3, 2, 3, 4, 4, 9)), 'millisecond'), false, 'millisecond is earlier');\n    assert.equal(m.isSame(m, 'millisecond'), true, 'same moments are in the same millisecond');\n    assert.equal(+m, +mCopy, 'isSame millisecond should not change moment');\n});\n\ntest('is same with utc offset moments', function (assert) {\n    assert.ok(moment.parseZone('2013-02-01T00:00:00-05:00').isSame(moment('2013-02-01'), 'year'), 'zoned vs local moment');\n    assert.ok(moment('2013-02-01').isSame(moment('2013-02-01').utcOffset('-05:00'), 'year'), 'local vs zoned moment');\n    assert.ok(moment.parseZone('2013-02-01T00:00:00-05:00').isSame(moment.parseZone('2013-02-01T00:00:00-06:30'), 'year'),\n            'zoned vs (differently) zoned moment');\n});\n\ntest('is same with invalid moments', function (assert) {\n    assert.equal(moment.invalid().isSame(moment.invalid()), false, 'invalid moments are not considered equal');\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\nfunction module$1 (name, lifecycle) {\n    QUnit.module(name, {\n        setup : function () {\n            moment.locale('en');\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'core');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            teardownDeprecationHandler(test, moment, 'core');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n}\n\nmodule$1('is same or after');\n\ntest('is same or after without units', function (assert) {\n    var m = moment(new Date(2011, 3, 2, 3, 4, 5, 10)), mCopy = moment(m);\n    assert.equal(m.isSameOrAfter(moment(new Date(2012, 3, 2, 3, 5, 5, 10))), false, 'year is later');\n    assert.equal(m.isSameOrAfter(moment(new Date(2010, 3, 2, 3, 3, 5, 10))), true, 'year is earlier');\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 4, 2, 3, 4, 5, 10))), false, 'month is later');\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 2, 2, 3, 4, 5, 10))), true, 'month is earlier');\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 3, 3, 3, 4, 5, 10))), false, 'day is later');\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 3, 1, 3, 4, 5, 10))), true, 'day is earlier');\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 3, 2, 4, 4, 5, 10))), false, 'hour is later');\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 3, 2, 2, 4, 5, 10))), true, 'hour is earlier');\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 3, 2, 3, 5, 5, 10))), false, 'minute is later');\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 3, 2, 3, 3, 5, 10))), true, 'minute is earlier');\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 3, 2, 3, 4, 6, 10))), false, 'second is later');\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 3, 2, 3, 4, 4, 11))), true, 'second is earlier');\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 3, 2, 3, 4, 5, 10))), true, 'millisecond match');\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 3, 2, 3, 4, 5, 11))), false, 'millisecond is later');\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 3, 2, 3, 4, 5, 9))), true, 'millisecond is earlier');\n    assert.equal(m.isSameOrAfter(m), true, 'moments are the same as themselves');\n    assert.equal(+m, +mCopy, 'isSameOrAfter second should not change moment');\n});\n\ntest('is same or after year', function (assert) {\n    var m = moment(new Date(2011, 1, 2, 3, 4, 5, 6)), mCopy = moment(m);\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 5, 6, 7, 8, 9, 10)), 'year'), true, 'year match');\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 5, 6, 7, 8, 9, 10)), 'years'), true, 'plural should work');\n    assert.equal(m.isSameOrAfter(moment(new Date(2012, 5, 6, 7, 8, 9, 10)), 'year'), false, 'year is later');\n    assert.equal(m.isSameOrAfter(moment(new Date(2010, 5, 6, 7, 8, 9, 10)), 'year'), true, 'year is earlier');\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 0, 1, 0, 0, 0, 0)), 'year'), true, 'exact start of year');\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 11, 31, 23, 59, 59, 999)), 'year'), true, 'exact end of year');\n    assert.equal(m.isSameOrAfter(moment(new Date(2012, 0, 1, 0, 0, 0, 0)), 'year'), false, 'start of next year');\n    assert.equal(m.isSameOrAfter(moment(new Date(2010, 11, 31, 23, 59, 59, 999)), 'year'), true, 'end of previous year');\n    assert.equal(m.isSameOrAfter(m, 'year'), true, 'same moments are in the same year');\n    assert.equal(+m, +mCopy, 'isSameOrAfter year should not change moment');\n});\n\ntest('is same or after month', function (assert) {\n    var m = moment(new Date(2011, 2, 3, 4, 5, 6, 7)), mCopy = moment(m);\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 2, 6, 7, 8, 9, 10)), 'month'), true, 'month match');\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 2, 6, 7, 8, 9, 10)), 'months'), true, 'plural should work');\n    assert.equal(m.isSameOrAfter(moment(new Date(2012, 2, 6, 7, 8, 9, 10)), 'month'), false, 'year is later');\n    assert.equal(m.isSameOrAfter(moment(new Date(2010, 2, 6, 7, 8, 9, 10)), 'month'), true, 'year is earlier');\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 5, 6, 7, 8, 9, 10)), 'month'), false, 'month is later');\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 1, 6, 7, 8, 9, 10)), 'month'), true, 'month is earlier');\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 2, 1, 0, 0, 0, 0)), 'month'), true, 'exact start of month');\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 2, 31, 23, 59, 59, 999)), 'month'), true, 'exact end of month');\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 3, 1, 0, 0, 0, 0)), 'month'), false, 'start of next month');\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 1, 27, 23, 59, 59, 999)), 'month'), true, 'end of previous month');\n    assert.equal(m.isSameOrAfter(m, 'month'), true, 'same moments are in the same month');\n    assert.equal(+m, +mCopy, 'isSameOrAfter month should not change moment');\n});\n\ntest('is same or after day', function (assert) {\n    var m = moment(new Date(2011, 1, 2, 3, 4, 5, 6)), mCopy = moment(m);\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 1, 2, 7, 8, 9, 10)), 'day'), true, 'day match');\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 1, 2, 7, 8, 9, 10)), 'days'), true, 'plural should work');\n    assert.equal(m.isSameOrAfter(moment(new Date(2012, 1, 2, 7, 8, 9, 10)), 'day'), false, 'year is later');\n    assert.equal(m.isSameOrAfter(moment(new Date(2010, 1, 2, 7, 8, 9, 10)), 'day'), true, 'year is earlier');\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 2, 2, 7, 8, 9, 10)), 'day'), false, 'month is later');\n    assert.equal(m.isSameOrAfter(moment(new Date(2010, 12, 2, 7, 8, 9, 10)), 'day'), true, 'month is earlier');\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 1, 3, 7, 8, 9, 10)), 'day'), false, 'day is later');\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 1, 1, 7, 8, 9, 10)), 'day'), true, 'day is earlier');\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 1, 2, 0, 0, 0, 0)), 'day'), true, 'exact start of day');\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 1, 2, 23, 59, 59, 999)), 'day'), true, 'exact end of day');\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 1, 3, 0, 0, 0, 0)), 'day'), false, 'start of next day');\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 1, 1, 23, 59, 59, 999)), 'day'), true, 'end of previous day');\n    assert.equal(m.isSameOrAfter(m, 'day'), true, 'same moments are in the same day');\n    assert.equal(+m, +mCopy, 'isSameOrAfter day should not change moment');\n});\n\ntest('is same or after hour', function (assert) {\n    var m = moment(new Date(2011, 1, 2, 3, 4, 5, 6)), mCopy = moment(m);\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 1, 2, 3, 8, 9, 10)), 'hour'), true, 'hour match');\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 1, 2, 3, 8, 9, 10)), 'hours'), true, 'plural should work');\n    assert.equal(m.isSameOrAfter(moment(new Date(2012, 1, 2, 3, 8, 9, 10)), 'hour'), false, 'year is later');\n    assert.equal(m.isSameOrAfter(moment(new Date(2010, 1, 2, 3, 8, 9, 10)), 'hour'), true, 'year is earlier');\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 2, 2, 3, 8, 9, 10)), 'hour'), false, 'month is later');\n    assert.equal(m.isSameOrAfter(moment(new Date(2010, 12, 2, 3, 8, 9, 10)), 'hour'), true, 'month is earlier');\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 1, 3, 3, 8, 9, 10)), 'hour'), false, 'day is later');\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 1, 1, 3, 8, 9, 10)), 'hour'), true, 'day is earlier');\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 1, 2, 4, 8, 9, 10)), 'hour'), false, 'hour is later');\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 1, 2, 2, 8, 9, 10)), 'hour'), true, 'hour is earlier');\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 1, 2, 3, 0, 0, 0)), 'hour'), true, 'exact start of hour');\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 1, 2, 3, 59, 59, 999)), 'hour'), true, 'exact end of hour');\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 1, 2, 4, 0, 0, 0)), 'hour'), false, 'start of next hour');\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 1, 2, 2, 59, 59, 999)), 'hour'), true, 'end of previous hour');\n    assert.equal(m.isSameOrAfter(m, 'hour'), true, 'same moments are in the same hour');\n    assert.equal(+m, +mCopy, 'isSameOrAfter hour should not change moment');\n});\n\ntest('is same or after minute', function (assert) {\n    var m = moment(new Date(2011, 1, 2, 3, 4, 5, 6)), mCopy = moment(m);\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 1, 2, 3, 4, 9, 10)), 'minute'), true, 'minute match');\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 1, 2, 3, 4, 9, 10)), 'minutes'), true, 'plural should work');\n    assert.equal(m.isSameOrAfter(moment(new Date(2012, 1, 2, 3, 4, 9, 10)), 'minute'), false, 'year is later');\n    assert.equal(m.isSameOrAfter(moment(new Date(2010, 1, 2, 3, 4, 9, 10)), 'minute'), true, 'year is earlier');\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 2, 2, 3, 4, 9, 10)), 'minute'), false, 'month is later');\n    assert.equal(m.isSameOrAfter(moment(new Date(2010, 12, 2, 3, 4, 9, 10)), 'minute'), true, 'month is earlier');\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 1, 3, 3, 4, 9, 10)), 'minute'), false, 'day is later');\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 1, 1, 3, 4, 9, 10)), 'minute'), true, 'day is earlier');\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 1, 2, 4, 4, 9, 10)), 'minute'), false, 'hour is later');\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 1, 2, 2, 4, 9, 10)), 'minute'), true, 'hour is earlier');\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 1, 2, 3, 5, 9, 10)), 'minute'), false, 'minute is later');\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 1, 2, 3, 3, 9, 10)), 'minute'), true, 'minute is earlier');\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 1, 2, 3, 4, 0, 0)), 'minute'), true, 'exact start of minute');\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 1, 2, 3, 4, 59, 999)), 'minute'), true, 'exact end of minute');\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 1, 2, 3, 5, 0, 0)), 'minute'), false, 'start of next minute');\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 1, 2, 3, 3, 59, 999)), 'minute'), true, 'end of previous minute');\n    assert.equal(m.isSameOrAfter(m, 'minute'), true, 'same moments are in the same minute');\n    assert.equal(+m, +mCopy, 'isSameOrAfter minute should not change moment');\n});\n\ntest('is same or after second', function (assert) {\n    var m = moment(new Date(2011, 1, 2, 3, 4, 5, 6)), mCopy = moment(m);\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 1, 2, 3, 4, 5, 10)), 'second'), true, 'second match');\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 1, 2, 3, 4, 5, 10)), 'seconds'), true, 'plural should work');\n    assert.equal(m.isSameOrAfter(moment(new Date(2012, 1, 2, 3, 4, 5, 10)), 'second'), false, 'year is later');\n    assert.equal(m.isSameOrAfter(moment(new Date(2010, 1, 2, 3, 4, 5, 10)), 'second'), true, 'year is earlier');\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 2, 2, 3, 4, 5, 10)), 'second'), false, 'month is later');\n    assert.equal(m.isSameOrAfter(moment(new Date(2010, 12, 2, 3, 4, 5, 10)), 'second'), true, 'month is earlier');\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 1, 3, 3, 4, 5, 10)), 'second'), false, 'day is later');\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 1, 1, 3, 4, 5, 10)), 'second'), true, 'day is earlier');\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 1, 2, 4, 4, 5, 10)), 'second'), false, 'hour is later');\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 1, 2, 2, 4, 5, 10)), 'second'), true, 'hour is earlier');\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 1, 2, 3, 5, 5, 10)), 'second'), false, 'minute is later');\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 1, 2, 3, 3, 5, 10)), 'second'), true, 'minute is earlier');\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 1, 2, 3, 4, 6, 10)), 'second'), false, 'second is later');\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 1, 2, 3, 4, 4, 10)), 'second'), true, 'second is earlier');\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 1, 2, 3, 4, 5, 0)), 'second'), true, 'exact start of second');\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 1, 2, 3, 4, 5, 999)), 'second'), true, 'exact end of second');\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 1, 2, 3, 4, 6, 0)), 'second'), false, 'start of next second');\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 1, 2, 3, 4, 4, 999)), 'second'), true, 'end of previous second');\n    assert.equal(m.isSameOrAfter(m, 'second'), true, 'same moments are in the same second');\n    assert.equal(+m, +mCopy, 'isSameOrAfter second should not change moment');\n});\n\ntest('is same or after millisecond', function (assert) {\n    var m = moment(new Date(2011, 3, 2, 3, 4, 5, 10)), mCopy = moment(m);\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 3, 2, 3, 4, 5, 10)), 'millisecond'), true, 'millisecond match');\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 3, 2, 3, 4, 5, 10)), 'milliseconds'), true, 'plural should work');\n    assert.equal(m.isSameOrAfter(moment(new Date(2012, 3, 2, 3, 4, 5, 10)), 'millisecond'), false, 'year is later');\n    assert.equal(m.isSameOrAfter(moment(new Date(2010, 3, 2, 3, 4, 5, 10)), 'millisecond'), true, 'year is earlier');\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 4, 2, 3, 4, 5, 10)), 'millisecond'), false, 'month is later');\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 2, 2, 3, 4, 5, 10)), 'millisecond'), true, 'month is earlier');\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 3, 3, 3, 4, 5, 10)), 'millisecond'), false, 'day is later');\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 3, 1, 1, 4, 5, 10)), 'millisecond'), true, 'day is earlier');\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 3, 2, 4, 4, 5, 10)), 'millisecond'), false, 'hour is later');\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 3, 1, 4, 1, 5, 10)), 'millisecond'), true, 'hour is earlier');\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 3, 2, 3, 5, 5, 10)), 'millisecond'), false, 'minute is later');\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 3, 2, 3, 3, 5, 10)), 'millisecond'), true, 'minute is earlier');\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 3, 2, 3, 4, 6, 10)), 'millisecond'), false, 'second is later');\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 3, 2, 3, 4, 4, 5)), 'millisecond'), true, 'second is earlier');\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 3, 2, 3, 4, 6, 11)), 'millisecond'), false, 'millisecond is later');\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 3, 2, 3, 4, 4, 9)), 'millisecond'), true, 'millisecond is earlier');\n    assert.equal(m.isSameOrAfter(m, 'millisecond'), true, 'same moments are in the same millisecond');\n    assert.equal(+m, +mCopy, 'isSameOrAfter millisecond should not change moment');\n});\n\ntest('is same or after with utc offset moments', function (assert) {\n    assert.ok(moment.parseZone('2013-02-01T00:00:00-05:00').isSameOrAfter(moment('2013-02-01'), 'year'), 'zoned vs local moment');\n    assert.ok(moment('2013-02-01').isSameOrAfter(moment('2013-02-01').utcOffset('-05:00'), 'year'), 'local vs zoned moment');\n    assert.ok(moment.parseZone('2013-02-01T00:00:00-05:00').isSameOrAfter(moment.parseZone('2013-02-01T00:00:00-06:30'), 'year'),\n            'zoned vs (differently) zoned moment');\n});\n\ntest('is same or after with invalid moments', function (assert) {\n    var m = moment(), invalid = moment.invalid();\n    assert.equal(invalid.isSameOrAfter(invalid), false, 'invalid moments are not considered equal');\n    assert.equal(m.isSameOrAfter(invalid), false, 'valid moment is not after invalid moment');\n    assert.equal(invalid.isSameOrAfter(m), false, 'invalid moment is not after valid moment');\n    assert.equal(m.isSameOrAfter(invalid, 'year'), false, 'invalid moment year');\n    assert.equal(m.isSameOrAfter(invalid, 'month'), false, 'invalid moment month');\n    assert.equal(m.isSameOrAfter(invalid, 'day'), false, 'invalid moment day');\n    assert.equal(m.isSameOrAfter(invalid, 'hour'), false, 'invalid moment hour');\n    assert.equal(m.isSameOrAfter(invalid, 'minute'), false, 'invalid moment minute');\n    assert.equal(m.isSameOrAfter(invalid, 'second'), false, 'invalid moment second');\n    assert.equal(m.isSameOrAfter(invalid, 'milliseconds'), false, 'invalid moment milliseconds');\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\nfunction module$1 (name, lifecycle) {\n    QUnit.module(name, {\n        setup : function () {\n            moment.locale('en');\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'core');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            teardownDeprecationHandler(test, moment, 'core');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n}\n\nmodule$1('is same or before');\n\ntest('is same or before without units', function (assert) {\n    var m = moment(new Date(2011, 3, 2, 3, 4, 5, 10)), mCopy = moment(m);\n    assert.equal(m.isSameOrBefore(moment(new Date(2012, 3, 2, 3, 5, 5, 10))), true, 'year is later');\n    assert.equal(m.isSameOrBefore(moment(new Date(2010, 3, 2, 3, 3, 5, 10))), false, 'year is earlier');\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 4, 2, 3, 4, 5, 10))), true, 'month is later');\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 2, 2, 3, 4, 5, 10))), false, 'month is earlier');\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 3, 3, 3, 4, 5, 10))), true, 'day is later');\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 3, 1, 3, 4, 5, 10))), false, 'day is earlier');\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 3, 2, 4, 4, 5, 10))), true, 'hour is later');\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 3, 2, 2, 4, 5, 10))), false, 'hour is earlier');\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 3, 2, 3, 5, 5, 10))), true, 'minute is later');\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 3, 2, 3, 3, 5, 10))), false, 'minute is earlier');\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 3, 2, 3, 4, 6, 10))), true, 'second is later');\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 3, 2, 3, 4, 4, 11))), false, 'second is earlier');\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 3, 2, 3, 4, 5, 10))), true, 'millisecond match');\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 3, 2, 3, 4, 5, 11))), true, 'millisecond is later');\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 3, 2, 3, 4, 5, 9))), false, 'millisecond is earlier');\n    assert.equal(m.isSameOrBefore(m), true, 'moments are the same as themselves');\n    assert.equal(+m, +mCopy, 'isSameOrBefore second should not change moment');\n});\n\ntest('is same or before year', function (assert) {\n    var m = moment(new Date(2011, 1, 2, 3, 4, 5, 6)), mCopy = moment(m);\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 5, 6, 7, 8, 9, 10)), 'year'), true, 'year match');\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 5, 6, 7, 8, 9, 10)), 'years'), true, 'plural should work');\n    assert.equal(m.isSameOrBefore(moment(new Date(2012, 5, 6, 7, 8, 9, 10)), 'year'), true, 'year is later');\n    assert.equal(m.isSameOrBefore(moment(new Date(2010, 5, 6, 7, 8, 9, 10)), 'year'), false, 'year is earlier');\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 0, 1, 0, 0, 0, 0)), 'year'), true, 'exact start of year');\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 11, 31, 23, 59, 59, 999)), 'year'), true, 'exact end of year');\n    assert.equal(m.isSameOrBefore(moment(new Date(2012, 0, 1, 0, 0, 0, 0)), 'year'), true, 'start of next year');\n    assert.equal(m.isSameOrBefore(moment(new Date(2010, 11, 31, 23, 59, 59, 999)), 'year'), false, 'end of previous year');\n    assert.equal(m.isSameOrBefore(m, 'year'), true, 'same moments are in the same year');\n    assert.equal(+m, +mCopy, 'isSameOrBefore year should not change moment');\n});\n\ntest('is same or before month', function (assert) {\n    var m = moment(new Date(2011, 2, 3, 4, 5, 6, 7)), mCopy = moment(m);\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 2, 6, 7, 8, 9, 10)), 'month'), true, 'month match');\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 2, 6, 7, 8, 9, 10)), 'months'), true, 'plural should work');\n    assert.equal(m.isSameOrBefore(moment(new Date(2012, 2, 6, 7, 8, 9, 10)), 'month'), true, 'year is later');\n    assert.equal(m.isSameOrBefore(moment(new Date(2010, 2, 6, 7, 8, 9, 10)), 'month'), false, 'year is earlier');\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 5, 6, 7, 8, 9, 10)), 'month'), true, 'month is later');\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 1, 6, 7, 8, 9, 10)), 'month'), false, 'month is earlier');\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 2, 1, 0, 0, 0, 0)), 'month'), true, 'exact start of month');\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 2, 31, 23, 59, 59, 999)), 'month'), true, 'exact end of month');\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 3, 1, 0, 0, 0, 0)), 'month'), true, 'start of next month');\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 1, 27, 23, 59, 59, 999)), 'month'), false, 'end of previous month');\n    assert.equal(m.isSameOrBefore(m, 'month'), true, 'same moments are in the same month');\n    assert.equal(+m, +mCopy, 'isSameOrBefore month should not change moment');\n});\n\ntest('is same or before day', function (assert) {\n    var m = moment(new Date(2011, 1, 2, 3, 4, 5, 6)), mCopy = moment(m);\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 1, 2, 7, 8, 9, 10)), 'day'), true, 'day match');\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 1, 2, 7, 8, 9, 10)), 'days'), true, 'plural should work');\n    assert.equal(m.isSameOrBefore(moment(new Date(2012, 1, 2, 7, 8, 9, 10)), 'day'), true, 'year is later');\n    assert.equal(m.isSameOrBefore(moment(new Date(2010, 1, 2, 7, 8, 9, 10)), 'day'), false, 'year is earlier');\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 2, 2, 7, 8, 9, 10)), 'day'), true, 'month is later');\n    assert.equal(m.isSameOrBefore(moment(new Date(2010, 12, 2, 7, 8, 9, 10)), 'day'), false, 'month is earlier');\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 1, 3, 7, 8, 9, 10)), 'day'), true, 'day is later');\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 1, 1, 7, 8, 9, 10)), 'day'), false, 'day is earlier');\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 1, 2, 0, 0, 0, 0)), 'day'), true, 'exact start of day');\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 1, 2, 23, 59, 59, 999)), 'day'), true, 'exact end of day');\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 1, 3, 0, 0, 0, 0)), 'day'), true, 'start of next day');\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 1, 1, 23, 59, 59, 999)), 'day'), false, 'end of previous day');\n    assert.equal(m.isSameOrBefore(m, 'day'), true, 'same moments are in the same day');\n    assert.equal(+m, +mCopy, 'isSameOrBefore day should not change moment');\n});\n\ntest('is same or before hour', function (assert) {\n    var m = moment(new Date(2011, 1, 2, 3, 4, 5, 6)), mCopy = moment(m);\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 1, 2, 3, 8, 9, 10)), 'hour'), true, 'hour match');\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 1, 2, 3, 8, 9, 10)), 'hours'), true, 'plural should work');\n    assert.equal(m.isSameOrBefore(moment(new Date(2012, 1, 2, 3, 8, 9, 10)), 'hour'), true, 'year is later');\n    assert.equal(m.isSameOrBefore(moment(new Date(2010, 1, 2, 3, 8, 9, 10)), 'hour'), false, 'year is earlier');\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 2, 2, 3, 8, 9, 10)), 'hour'), true, 'month is later');\n    assert.equal(m.isSameOrBefore(moment(new Date(2010, 12, 2, 3, 8, 9, 10)), 'hour'), false, 'month is earlier');\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 1, 3, 3, 8, 9, 10)), 'hour'), true, 'day is later');\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 1, 1, 3, 8, 9, 10)), 'hour'), false, 'day is earlier');\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 1, 2, 4, 8, 9, 10)), 'hour'), true, 'hour is later');\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 1, 2, 2, 8, 9, 10)), 'hour'), false, 'hour is earlier');\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 1, 2, 3, 0, 0, 0)), 'hour'), true, 'exact start of hour');\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 1, 2, 3, 59, 59, 999)), 'hour'), true, 'exact end of hour');\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 1, 2, 4, 0, 0, 0)), 'hour'), true, 'start of next hour');\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 1, 2, 2, 59, 59, 999)), 'hour'), false, 'end of previous hour');\n    assert.equal(m.isSameOrBefore(m, 'hour'), true, 'same moments are in the same hour');\n    assert.equal(+m, +mCopy, 'isSameOrBefore hour should not change moment');\n});\n\ntest('is same or before minute', function (assert) {\n    var m = moment(new Date(2011, 1, 2, 3, 4, 5, 6)), mCopy = moment(m);\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 1, 2, 3, 4, 9, 10)), 'minute'), true, 'minute match');\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 1, 2, 3, 4, 9, 10)), 'minutes'), true, 'plural should work');\n    assert.equal(m.isSameOrBefore(moment(new Date(2012, 1, 2, 3, 4, 9, 10)), 'minute'), true, 'year is later');\n    assert.equal(m.isSameOrBefore(moment(new Date(2010, 1, 2, 3, 4, 9, 10)), 'minute'), false, 'year is earlier');\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 2, 2, 3, 4, 9, 10)), 'minute'), true, 'month is later');\n    assert.equal(m.isSameOrBefore(moment(new Date(2010, 12, 2, 3, 4, 9, 10)), 'minute'), false, 'month is earlier');\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 1, 3, 3, 4, 9, 10)), 'minute'), true, 'day is later');\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 1, 1, 3, 4, 9, 10)), 'minute'), false, 'day is earlier');\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 1, 2, 4, 4, 9, 10)), 'minute'), true, 'hour is later');\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 1, 2, 2, 4, 9, 10)), 'minute'), false, 'hour is earlier');\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 1, 2, 3, 5, 9, 10)), 'minute'), true, 'minute is later');\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 1, 2, 3, 3, 9, 10)), 'minute'), false, 'minute is earlier');\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 1, 2, 3, 4, 0, 0)), 'minute'), true, 'exact start of minute');\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 1, 2, 3, 4, 59, 999)), 'minute'), true, 'exact end of minute');\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 1, 2, 3, 5, 0, 0)), 'minute'), true, 'start of next minute');\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 1, 2, 3, 3, 59, 999)), 'minute'), false, 'end of previous minute');\n    assert.equal(m.isSameOrBefore(m, 'minute'), true, 'same moments are in the same minute');\n    assert.equal(+m, +mCopy, 'isSameOrBefore minute should not change moment');\n});\n\ntest('is same or before second', function (assert) {\n    var m = moment(new Date(2011, 1, 2, 3, 4, 5, 6)), mCopy = moment(m);\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 1, 2, 3, 4, 5, 10)), 'second'), true, 'second match');\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 1, 2, 3, 4, 5, 10)), 'seconds'), true, 'plural should work');\n    assert.equal(m.isSameOrBefore(moment(new Date(2012, 1, 2, 3, 4, 5, 10)), 'second'), true, 'year is later');\n    assert.equal(m.isSameOrBefore(moment(new Date(2010, 1, 2, 3, 4, 5, 10)), 'second'), false, 'year is earlier');\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 2, 2, 3, 4, 5, 10)), 'second'), true, 'month is later');\n    assert.equal(m.isSameOrBefore(moment(new Date(2010, 12, 2, 3, 4, 5, 10)), 'second'), false, 'month is earlier');\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 1, 3, 3, 4, 5, 10)), 'second'), true, 'day is later');\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 1, 1, 3, 4, 5, 10)), 'second'), false, 'day is earlier');\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 1, 2, 4, 4, 5, 10)), 'second'), true, 'hour is later');\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 1, 2, 2, 4, 5, 10)), 'second'), false, 'hour is earlier');\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 1, 2, 3, 5, 5, 10)), 'second'), true, 'minute is later');\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 1, 2, 3, 3, 5, 10)), 'second'), false, 'minute is earlier');\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 1, 2, 3, 4, 6, 10)), 'second'), true, 'second is later');\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 1, 2, 3, 4, 4, 10)), 'second'), false, 'second is earlier');\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 1, 2, 3, 4, 5, 0)), 'second'), true, 'exact start of second');\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 1, 2, 3, 4, 5, 999)), 'second'), true, 'exact end of second');\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 1, 2, 3, 4, 6, 0)), 'second'), true, 'start of next second');\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 1, 2, 3, 4, 4, 999)), 'second'), false, 'end of previous second');\n    assert.equal(m.isSameOrBefore(m, 'second'), true, 'same moments are in the same second');\n    assert.equal(+m, +mCopy, 'isSameOrBefore second should not change moment');\n});\n\ntest('is same or before millisecond', function (assert) {\n    var m = moment(new Date(2011, 3, 2, 3, 4, 5, 10)), mCopy = moment(m);\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 3, 2, 3, 4, 5, 10)), 'millisecond'), true, 'millisecond match');\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 3, 2, 3, 4, 5, 10)), 'milliseconds'), true, 'plural should work');\n    assert.equal(m.isSameOrBefore(moment(new Date(2012, 3, 2, 3, 4, 5, 10)), 'millisecond'), true, 'year is later');\n    assert.equal(m.isSameOrBefore(moment(new Date(2010, 3, 2, 3, 4, 5, 10)), 'millisecond'), false, 'year is earlier');\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 4, 2, 3, 4, 5, 10)), 'millisecond'), true, 'month is later');\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 2, 2, 3, 4, 5, 10)), 'millisecond'), false, 'month is earlier');\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 3, 3, 3, 4, 5, 10)), 'millisecond'), true, 'day is later');\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 3, 1, 1, 4, 5, 10)), 'millisecond'), false, 'day is earlier');\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 3, 2, 4, 4, 5, 10)), 'millisecond'), true, 'hour is later');\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 3, 1, 4, 1, 5, 10)), 'millisecond'), false, 'hour is earlier');\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 3, 2, 3, 5, 5, 10)), 'millisecond'), true, 'minute is later');\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 3, 2, 3, 3, 5, 10)), 'millisecond'), false, 'minute is earlier');\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 3, 2, 3, 4, 6, 10)), 'millisecond'), true, 'second is later');\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 3, 2, 3, 4, 4, 5)), 'millisecond'), false, 'second is earlier');\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 3, 2, 3, 4, 6, 11)), 'millisecond'), true, 'millisecond is later');\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 3, 2, 3, 4, 4, 9)), 'millisecond'), false, 'millisecond is earlier');\n    assert.equal(m.isSameOrBefore(m, 'millisecond'), true, 'same moments are in the same millisecond');\n    assert.equal(+m, +mCopy, 'isSameOrBefore millisecond should not change moment');\n});\n\ntest('is same with utc offset moments', function (assert) {\n    assert.ok(moment.parseZone('2013-02-01T00:00:00-05:00').isSameOrBefore(moment('2013-02-01'), 'year'), 'zoned vs local moment');\n    assert.ok(moment('2013-02-01').isSameOrBefore(moment('2013-02-01').utcOffset('-05:00'), 'year'), 'local vs zoned moment');\n    assert.ok(\n      moment.parseZone('2013-02-01T00:00:00-05:00').isSameOrBefore(moment.parseZone('2013-02-01T00:00:00-06:30'), 'year'),\n      'zoned vs (differently) zoned moment'\n    );\n});\n\ntest('is same with invalid moments', function (assert) {\n    var m = moment(), invalid = moment.invalid();\n    assert.equal(invalid.isSameOrBefore(invalid), false, 'invalid moments are not considered equal');\n    assert.equal(m.isSameOrBefore(invalid), false, 'valid moment is not before invalid moment');\n    assert.equal(invalid.isSameOrBefore(m), false, 'invalid moment is not before valid moment');\n    assert.equal(m.isSameOrBefore(invalid, 'year'), false, 'invalid moment year');\n    assert.equal(m.isSameOrBefore(invalid, 'month'), false, 'invalid moment month');\n    assert.equal(m.isSameOrBefore(invalid, 'day'), false, 'invalid moment day');\n    assert.equal(m.isSameOrBefore(invalid, 'hour'), false, 'invalid moment hour');\n    assert.equal(m.isSameOrBefore(invalid, 'minute'), false, 'invalid moment minute');\n    assert.equal(m.isSameOrBefore(invalid, 'second'), false, 'invalid moment second');\n    assert.equal(m.isSameOrBefore(invalid, 'milliseconds'), false, 'invalid moment milliseconds');\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\nfunction module$1 (name, lifecycle) {\n    QUnit.module(name, {\n        setup : function () {\n            moment.locale('en');\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'core');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            teardownDeprecationHandler(test, moment, 'core');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n}\n\nmodule$1('is valid');\n\ntest('array bad month', function (assert) {\n    assert.equal(moment([2010, -1]).isValid(), false, 'month -1 invalid');\n    assert.equal(moment([2100, 12]).isValid(), false, 'month 12 invalid');\n});\n\ntest('array good month', function (assert) {\n    for (var i = 0; i < 12; i++) {\n        assert.equal(moment([2010, i]).isValid(), true, 'month ' + i);\n        assert.equal(moment.utc([2010, i]).isValid(), true, 'month ' + i);\n    }\n});\n\ntest('array bad date', function (assert) {\n    var tests = [\n        moment([2010, 0, 0]),\n        moment([2100, 0, 32]),\n        moment.utc([2010, 0, 0]),\n        moment.utc([2100, 0, 32])\n    ],\n    i, m;\n\n    for (i in tests) {\n        m = tests[i];\n        assert.equal(m.isValid(), false);\n    }\n});\n\ntest('h/hh with hour > 12', function (assert) {\n    assert.ok(moment('06/20/2014 11:51 PM', 'MM/DD/YYYY hh:mm A', true).isValid(), '11 for hh');\n    assert.ok(moment('06/20/2014 11:51 AM', 'MM/DD/YYYY hh:mm A', true).isValid(), '11 for hh');\n    assert.ok(moment('06/20/2014 23:51 PM', 'MM/DD/YYYY hh:mm A').isValid(), 'non-strict validity 23 for hh');\n    assert.ok(moment('06/20/2014 23:51 PM', 'MM/DD/YYYY hh:mm A').parsingFlags().bigHour, 'non-strict bigHour 23 for hh');\n    assert.ok(!moment('06/20/2014 23:51 PM', 'MM/DD/YYYY hh:mm A', true).isValid(), 'validity 23 for hh');\n    assert.ok(moment('06/20/2014 23:51 PM', 'MM/DD/YYYY hh:mm A', true).parsingFlags().bigHour, 'bigHour 23 for hh');\n});\n\ntest('array bad date leap year', function (assert) {\n    assert.equal(moment([2010, 1, 29]).isValid(), false, '2010 feb 29');\n    assert.equal(moment([2100, 1, 29]).isValid(), false, '2100 feb 29');\n    assert.equal(moment([2008, 1, 30]).isValid(), false, '2008 feb 30');\n    assert.equal(moment([2000, 1, 30]).isValid(), false, '2000 feb 30');\n\n    assert.equal(moment.utc([2010, 1, 29]).isValid(), false, 'utc 2010 feb 29');\n    assert.equal(moment.utc([2100, 1, 29]).isValid(), false, 'utc 2100 feb 29');\n    assert.equal(moment.utc([2008, 1, 30]).isValid(), false, 'utc 2008 feb 30');\n    assert.equal(moment.utc([2000, 1, 30]).isValid(), false, 'utc 2000 feb 30');\n});\n\ntest('string + formats bad date', function (assert) {\n    assert.equal(moment('2020-00-00', []).isValid(), false, 'invalid on empty array');\n    assert.equal(moment('2020-00-00', ['YYYY-MM-DD', 'DD-MM-YYYY']).isValid(), false, 'invalid on all in array');\n    assert.equal(moment('2020-00-00', ['DD-MM-YYYY', 'YYYY-MM-DD']).isValid(), false, 'invalid on all in array');\n    assert.equal(moment('2020-01-01', ['YYYY-MM-DD', 'DD-MM-YYYY']).isValid(), true, 'valid on first');\n    assert.equal(moment('2020-01-01', ['DD-MM-YYYY', 'YYYY-MM-DD']).isValid(), true, 'valid on last');\n    assert.equal(moment('2020-01-01', ['YYYY-MM-DD', 'YYYY-DD-MM']).isValid(), true, 'valid on both');\n    assert.equal(moment('2020-13-01', ['YYYY-MM-DD', 'YYYY-DD-MM']).isValid(), true, 'valid on last');\n\n    assert.equal(moment('12-13-2012', ['DD-MM-YYYY', 'YYYY-MM-DD']).isValid(), false, 'month rollover');\n    assert.equal(moment('12-13-2012', ['DD-MM-YYYY', 'DD-MM-YYYY']).isValid(), false, 'month rollover');\n    assert.equal(moment('38-12-2012', ['DD-MM-YYYY']).isValid(), false, 'day rollover');\n});\n\ntest('string nonsensical with format', function (assert) {\n    assert.equal(moment('fail', 'MM-DD-YYYY').isValid(), false, 'string \\'fail\\' with format \\'MM-DD-YYYY\\'');\n    assert.equal(moment('xx-xx-2001', 'DD-MM-YYY').isValid(), true, 'string \\'xx-xx-2001\\' with format \\'MM-DD-YYYY\\'');\n});\n\ntest('string with bad month name', function (assert) {\n    assert.equal(moment('01-Nam-2012', 'DD-MMM-YYYY').isValid(), false, '\\'Nam\\' is an invalid month');\n    assert.equal(moment('01-Aug-2012', 'DD-MMM-YYYY').isValid(), true, '\\'Aug\\' is a valid month');\n});\n\ntest('string with spaceless format', function (assert) {\n    assert.equal(moment('10Sep2001', 'DDMMMYYYY').isValid(), true, 'Parsing 10Sep2001 should result in a valid date');\n});\n\ntest('invalid string iso 8601', function (assert) {\n    var tests = [\n        '2010-00-00',\n        '2010-01-00',\n        '2010-01-40',\n        '2010-01-01T24:01',  // 24:00:00 is actually valid\n        '2010-01-01T23:60',\n        '2010-01-01T23:59:60'\n    ], i;\n\n    for (i = 0; i < tests.length; i++) {\n        assert.equal(moment(tests[i], moment.ISO_8601).isValid(), false, tests[i] + ' should be invalid');\n        assert.equal(moment.utc(tests[i], moment.ISO_8601).isValid(), false, tests[i] + ' should be invalid');\n    }\n});\n\ntest('invalid string iso 8601 + timezone', function (assert) {\n    var tests = [\n        '2010-00-00T+00:00',\n        '2010-01-00T+00:00',\n        '2010-01-40T+00:00',\n        '2010-01-40T24:01+00:00',\n        '2010-01-40T23:60+00:00',\n        '2010-01-40T23:59:60+00:00',\n        '2010-01-40T23:59:59.9999+00:00',\n        '2010-01-40T23:59:59,9999+00:00'\n    ], i;\n\n    for (i = 0; i < tests.length; i++) {\n        assert.equal(moment(tests[i], moment.ISO_8601).isValid(), false, tests[i] + ' should be invalid');\n        assert.equal(moment.utc(tests[i], moment.ISO_8601).isValid(), false, tests[i] + ' should be invalid');\n    }\n});\n\ntest('valid string iso 8601 - not strict', function (assert) {\n    var tests = [\n        '2010-01-30 00:00:00,000Z',\n        '20100101',\n        '20100130',\n        '20100130T23+00:00',\n        '20100130T2359+0000',\n        '20100130T235959+0000',\n        '20100130T235959,999+0000',\n        '20100130T235959,999-0700',\n        '20100130T000000,000+0700',\n        '20100130 000000,000Z'\n    ];\n\n    for (var i = 0; i < tests.length; i++) {\n        assert.equal(moment(tests[i]).isValid(), true, tests[i] + ' should be valid in normal');\n        assert.equal(moment.utc(tests[i]).isValid(), true, tests[i] + ' should be valid in normal');\n    }\n});\n\ntest('valid string iso 8601 + timezone', function (assert) {\n    var tests = [\n        '2010-01-01',\n        '2010-01-30',\n        '2010-01-30T23+00:00',\n        '2010-01-30T23:59+00:00',\n        '2010-01-30T23:59:59+00:00',\n        '2010-01-30T23:59:59.999+00:00',\n        '2010-01-30T23:59:59.999-07:00',\n        '2010-01-30T00:00:00.000+07:00',\n        '2010-01-30T23:59:59.999-07',\n        '2010-01-30T00:00:00.000+07',\n        '2010-01-30 00:00:00.000Z'\n    ], i;\n\n    for (i = 0; i < tests.length; i++) {\n        assert.equal(moment(tests[i]).isValid(), true, tests[i] + ' should be valid in normal');\n        assert.equal(moment.utc(tests[i]).isValid(), true, tests[i] + ' should be valid in normal');\n        assert.equal(moment(tests[i], moment.ISO_8601, true).isValid(), true, tests[i] + ' should be valid in strict');\n        assert.equal(moment.utc(tests[i], moment.ISO_8601, true).isValid(), true, tests[i] + ' should be valid in strict');\n    }\n});\n\ntest('invalidAt', function (assert) {\n    assert.equal(moment([2000, 12]).invalidAt(), 1, 'month 12 is invalid: 0-11');\n    assert.equal(moment([2000, 1, 30]).invalidAt(), 2, '30 is not a valid february day');\n    assert.equal(moment([2000, 1, 29, 25]).invalidAt(), 3, '25 is invalid hour');\n    assert.equal(moment([2000, 1, 29, 24,  1]).invalidAt(), 3, '24:01 is invalid hour');\n    assert.equal(moment([2000, 1, 29, 23, 60]).invalidAt(), 4, '60 is invalid minute');\n    assert.equal(moment([2000, 1, 29, 23, 59, 60]).invalidAt(), 5, '60 is invalid second');\n    assert.equal(moment([2000, 1, 29, 23, 59, 59, 1000]).invalidAt(), 6, '1000 is invalid millisecond');\n    assert.equal(moment([2000, 1, 29, 23, 59, 59, 999]).invalidAt(), -1, '-1 if everything is fine');\n});\n\ntest('valid Unix timestamp', function (assert) {\n    assert.equal(moment(1371065286, 'X').isValid(), true, 'number integer');\n    assert.equal(moment(1379066897.0, 'X').isValid(), true, 'number whole 1dp');\n    assert.equal(moment(1379066897.7, 'X').isValid(), true, 'number 1dp');\n    assert.equal(moment(1379066897.00, 'X').isValid(), true, 'number whole 2dp');\n    assert.equal(moment(1379066897.07, 'X').isValid(), true, 'number 2dp');\n    assert.equal(moment(1379066897.17, 'X').isValid(), true, 'number 2dp');\n    assert.equal(moment(1379066897.000, 'X').isValid(), true, 'number whole 3dp');\n    assert.equal(moment(1379066897.007, 'X').isValid(), true, 'number 3dp');\n    assert.equal(moment(1379066897.017, 'X').isValid(), true, 'number 3dp');\n    assert.equal(moment(1379066897.157, 'X').isValid(), true, 'number 3dp');\n    assert.equal(moment('1371065286', 'X').isValid(), true, 'string integer');\n    assert.equal(moment('1379066897.', 'X').isValid(), true, 'string trailing .');\n    assert.equal(moment('1379066897.0', 'X').isValid(), true, 'string whole 1dp');\n    assert.equal(moment('1379066897.7', 'X').isValid(), true, 'string 1dp');\n    assert.equal(moment('1379066897.00', 'X').isValid(), true, 'string whole 2dp');\n    assert.equal(moment('1379066897.07', 'X').isValid(), true, 'string 2dp');\n    assert.equal(moment('1379066897.17', 'X').isValid(), true, 'string 2dp');\n    assert.equal(moment('1379066897.000', 'X').isValid(), true, 'string whole 3dp');\n    assert.equal(moment('1379066897.007', 'X').isValid(), true, 'string 3dp');\n    assert.equal(moment('1379066897.017', 'X').isValid(), true, 'string 3dp');\n    assert.equal(moment('1379066897.157', 'X').isValid(), true, 'string 3dp');\n});\n\ntest('invalid Unix timestamp', function (assert) {\n    assert.equal(moment(undefined, 'X').isValid(), false, 'undefined');\n    assert.equal(moment('undefined', 'X').isValid(), false, 'string undefined');\n    try {\n        assert.equal(moment(null, 'X').isValid(), false, 'null');\n    } catch (e) {\n        assert.ok(true, 'null');\n    }\n\n    assert.equal(moment('null', 'X').isValid(), false, 'string null');\n    assert.equal(moment([], 'X').isValid(), false, 'array');\n    assert.equal(moment('{}', 'X').isValid(), false, 'object');\n    try {\n        assert.equal(moment('', 'X').isValid(), false, 'string empty');\n    } catch (e) {\n        assert.ok(true, 'string empty');\n    }\n\n    assert.equal(moment(' ', 'X').isValid(), false, 'string space');\n});\n\ntest('valid Unix offset milliseconds', function (assert) {\n    assert.equal(moment(1234567890123, 'x').isValid(), true, 'number integer');\n    assert.equal(moment('1234567890123', 'x').isValid(), true, 'string integer');\n});\n\ntest('invalid Unix offset milliseconds', function (assert) {\n    assert.equal(moment(undefined, 'x').isValid(), false, 'undefined');\n    assert.equal(moment('undefined', 'x').isValid(), false, 'string undefined');\n    try {\n        assert.equal(moment(null, 'x').isValid(), false, 'null');\n    } catch (e) {\n        assert.ok(true, 'null');\n    }\n\n    assert.equal(moment('null', 'x').isValid(), false, 'string null');\n    assert.equal(moment([], 'x').isValid(), false, 'array');\n    assert.equal(moment('{}', 'x').isValid(), false, 'object');\n    try {\n        assert.equal(moment('', 'x').isValid(), false, 'string empty');\n    } catch (e) {\n        assert.ok(true, 'string empty');\n    }\n\n    assert.equal(moment(' ', 'x').isValid(), false, 'string space');\n});\n\ntest('empty', function (assert) {\n    assert.equal(moment(null).isValid(), false, 'null');\n    assert.equal(moment('').isValid(), false, 'empty string');\n    assert.equal(moment(null, 'YYYY').isValid(), false, 'format + null');\n    assert.equal(moment('', 'YYYY').isValid(), false, 'format + empty string');\n    assert.equal(moment(' ', 'YYYY').isValid(), false, 'format + empty when trimmed');\n});\n\ntest('days of the year', function (assert) {\n    assert.equal(moment('2010 300', 'YYYY DDDD').isValid(), true, 'day 300 of year valid');\n    assert.equal(moment('2010 365', 'YYYY DDDD').isValid(), true, 'day 365 of year valid');\n    assert.equal(moment('2010 366', 'YYYY DDDD').isValid(), false, 'day 366 of year invalid');\n    assert.equal(moment('2012 365', 'YYYY DDDD').isValid(), true, 'day 365 of leap year valid');\n    assert.equal(moment('2012 366', 'YYYY DDDD').isValid(), true, 'day 366 of leap year valid');\n    assert.equal(moment('2012 367', 'YYYY DDDD').isValid(), false, 'day 367 of leap year invalid');\n});\n\ntest('24:00:00.000 is valid', function (assert) {\n    assert.equal(moment('2014-01-01 24', 'YYYY-MM-DD HH').isValid(), true, '24 is valid');\n    assert.equal(moment('2014-01-01 24:00', 'YYYY-MM-DD HH:mm').isValid(), true, '24:00 is valid');\n    assert.equal(moment('2014-01-01 24:01', 'YYYY-MM-DD HH:mm').isValid(), false, '24:01 is not valid');\n});\n\ntest('oddball permissiveness', function (assert) {\n    // https://github.com/moment/moment/issues/1128\n    assert.ok(moment('2010-10-3199', ['MM/DD/YYYY', 'MM-DD-YYYY', 'YYYY-MM-DD']).isValid());\n\n    // https://github.com/moment/moment/issues/1122\n    assert.ok(moment('3:25', ['h:mma', 'hh:mma', 'H:mm', 'HH:mm']).isValid());\n});\n\ntest('0 hour is invalid in strict', function (assert) {\n    assert.equal(moment('00:01', 'hh:mm', true).isValid(), false, '00 hour is invalid in strict');\n    assert.equal(moment('00:01', 'hh:mm').isValid(), true, '00 hour is valid in normal');\n    assert.equal(moment('0:01', 'h:mm', true).isValid(), false, '0 hour is invalid in strict');\n    assert.equal(moment('0:01', 'h:mm').isValid(), true, '0 hour is valid in normal');\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\nfunction module$1 (name, lifecycle) {\n    QUnit.module(name, {\n        setup : function () {\n            moment.locale('en');\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'core');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            teardownDeprecationHandler(test, moment, 'core');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n}\n\nmodule$1('leap year');\n\ntest('leap year', function (assert) {\n    assert.equal(moment([2010, 0, 1]).isLeapYear(), false, '2010');\n    assert.equal(moment([2100, 0, 1]).isLeapYear(), false, '2100');\n    assert.equal(moment([2008, 0, 1]).isLeapYear(), true, '2008');\n    assert.equal(moment([2000, 0, 1]).isLeapYear(), true, '2000');\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\nfunction module$1 (name, lifecycle) {\n    QUnit.module(name, {\n        setup : function () {\n            moment.locale('en');\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'core');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            teardownDeprecationHandler(test, moment, 'core');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n}\n\nmodule$1('listers');\n\ntest('default', function (assert) {\n    assert.deepEqual(moment.months(), ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December']);\n    assert.deepEqual(moment.monthsShort(), ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']);\n    assert.deepEqual(moment.weekdays(), ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday']);\n    assert.deepEqual(moment.weekdaysShort(), ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat']);\n    assert.deepEqual(moment.weekdaysMin(), ['Su', 'Mo', 'Tu', 'We', 'Th', 'Fr', 'Sa']);\n});\n\ntest('index', function (assert) {\n    assert.equal(moment.months(0), 'January');\n    assert.equal(moment.months(2), 'March');\n    assert.equal(moment.monthsShort(0), 'Jan');\n    assert.equal(moment.monthsShort(2), 'Mar');\n    assert.equal(moment.weekdays(0), 'Sunday');\n    assert.equal(moment.weekdays(2), 'Tuesday');\n    assert.equal(moment.weekdaysShort(0), 'Sun');\n    assert.equal(moment.weekdaysShort(2), 'Tue');\n    assert.equal(moment.weekdaysMin(0), 'Su');\n    assert.equal(moment.weekdaysMin(2), 'Tu');\n});\n\ntest('localized', function (assert) {\n    var months = 'one_two_three_four_five_six_seven_eight_nine_ten_eleven_twelve'.split('_'),\n        monthsShort = 'on_tw_th_fo_fi_si_se_ei_ni_te_el_tw'.split('_'),\n        weekdays = 'one_two_three_four_five_six_seven'.split('_'),\n        weekdaysShort = 'on_tw_th_fo_fi_si_se'.split('_'),\n        weekdaysMin = '1_2_3_4_5_6_7'.split('_'),\n        weekdaysLocale = 'four_five_six_seven_one_two_three'.split('_'),\n        weekdaysShortLocale = 'fo_fi_si_se_on_tw_th'.split('_'),\n        weekdaysMinLocale = '4_5_6_7_1_2_3'.split('_'),\n        week = {\n            dow : 3,\n            doy : 6\n        };\n\n    moment.locale('numerologists', {\n        months : months,\n        monthsShort : monthsShort,\n        weekdays : weekdays,\n        weekdaysShort: weekdaysShort,\n        weekdaysMin: weekdaysMin,\n        week : week\n    });\n\n    assert.deepEqual(moment.months(), months);\n    assert.deepEqual(moment.monthsShort(), monthsShort);\n    assert.deepEqual(moment.weekdays(), weekdays);\n    assert.deepEqual(moment.weekdaysShort(), weekdaysShort);\n    assert.deepEqual(moment.weekdaysMin(), weekdaysMin);\n\n    assert.equal(moment.months(0), 'one');\n    assert.equal(moment.monthsShort(0), 'on');\n    assert.equal(moment.weekdays(0), 'one');\n    assert.equal(moment.weekdaysShort(0), 'on');\n    assert.equal(moment.weekdaysMin(0), '1');\n\n    assert.equal(moment.months(2), 'three');\n    assert.equal(moment.monthsShort(2), 'th');\n    assert.equal(moment.weekdays(2), 'three');\n    assert.equal(moment.weekdaysShort(2), 'th');\n    assert.equal(moment.weekdaysMin(2), '3');\n\n    assert.deepEqual(moment.weekdays(true), weekdaysLocale);\n    assert.deepEqual(moment.weekdaysShort(true), weekdaysShortLocale);\n    assert.deepEqual(moment.weekdaysMin(true), weekdaysMinLocale);\n\n    assert.equal(moment.weekdays(true, 0), 'four');\n    assert.equal(moment.weekdaysShort(true, 0), 'fo');\n    assert.equal(moment.weekdaysMin(true, 0), '4');\n\n    assert.equal(moment.weekdays(false, 2), 'three');\n    assert.equal(moment.weekdaysShort(false, 2), 'th');\n    assert.equal(moment.weekdaysMin(false, 2), '3');\n});\n\ntest('with functions', function (assert) {\n    var monthsShort = 'one_two_three_four_five_six_seven_eight_nine_ten_eleven_twelve'.split('_'),\n        monthsShortWeird = 'onesy_twosy_threesy_foursy_fivesy_sixsy_sevensy_eightsy_ninesy_tensy_elevensy_twelvesy'.split('_');\n\n    moment.locale('difficult', {\n\n        monthsShort: function (m, format) {\n            var arr = format.match(/-MMM-/) ? monthsShortWeird : monthsShort;\n            return arr[m.month()];\n        }\n    });\n\n    assert.deepEqual(moment.monthsShort(), monthsShort);\n    assert.deepEqual(moment.monthsShort('MMM'), monthsShort);\n    assert.deepEqual(moment.monthsShort('-MMM-'), monthsShortWeird);\n\n    assert.deepEqual(moment.monthsShort('MMM', 2), 'three');\n    assert.deepEqual(moment.monthsShort('-MMM-', 2), 'threesy');\n    assert.deepEqual(moment.monthsShort(2), 'three');\n});\n\ntest('with locale data', function (assert) {\n    var months = 'one_two_three_four_five_six_seven_eight_nine_ten_eleven_twelve'.split('_'),\n        monthsShort = 'on_tw_th_fo_fi_si_se_ei_ni_te_el_tw'.split('_'),\n        weekdays = 'one_two_three_four_five_six_seven'.split('_'),\n        weekdaysShort = 'on_tw_th_fo_fi_si_se'.split('_'),\n        weekdaysMin = '1_2_3_4_5_6_7'.split('_'),\n        weekdaysLocale = 'four_five_six_seven_one_two_three'.split('_'),\n        weekdaysShortLocale = 'fo_fi_si_se_on_tw_th'.split('_'),\n        weekdaysMinLocale = '4_5_6_7_1_2_3'.split('_'),\n        week = {\n            dow : 3,\n            doy : 6\n        };\n\n    var customLocale = moment.localeData('numerologists');\n\n    assert.deepEqual(customLocale.months(), months);\n    assert.deepEqual(customLocale.monthsShort(), monthsShort);\n    assert.deepEqual(customLocale.weekdays(), weekdays);\n    assert.deepEqual(customLocale.weekdaysShort(), weekdaysShort);\n    assert.deepEqual(customLocale.weekdaysMin(), weekdaysMin);\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\nfunction module$1 (name, lifecycle) {\n    QUnit.module(name, {\n        setup : function () {\n            moment.locale('en');\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'core');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            teardownDeprecationHandler(test, moment, 'core');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n}\n\nvar indexOf;\n\nif (Array.prototype.indexOf) {\n    indexOf = Array.prototype.indexOf;\n} else {\n    indexOf = function (o) {\n        // I know\n        var i;\n        for (i = 0; i < this.length; ++i) {\n            if (this[i] === o) {\n                return i;\n            }\n        }\n        return -1;\n    };\n}\n\nvar indexOf$1 = indexOf;\n\nmodule$1('locale', {\n    setup : function () {\n        // TODO: Remove once locales are switched to ES6\n        each([{\n            name: 'en-gb',\n            data: {}\n        }, {\n            name: 'en-ca',\n            data: {}\n        }, {\n            name: 'es',\n            data: {\n                relativeTime: {past: 'hace %s', s: 'unos segundos', d: 'un día'},\n                months: 'enero_febrero_marzo_abril_mayo_junio_julio_agosto_septiembre_octubre_noviembre_diciembre'.split('_')\n            }\n        }, {\n            name: 'fr',\n            data: {}\n        }, {\n            name: 'fr-ca',\n            data: {}\n        }, {\n            name: 'it',\n            data: {}\n        }, {\n            name: 'zh-cn',\n            data: {\n                months: '一月_二月_三月_四月_五月_六月_七月_八月_九月_十月_十一月_十二月'.split('_')\n            }\n        }], function (locale) {\n            if (moment.locale(locale.name) !== locale.name) {\n                moment.defineLocale(locale.name, locale.data);\n            }\n        });\n        moment.locale('en');\n    }\n});\n\ntest('library getters and setters', function (assert) {\n    var r = moment.locale('en');\n\n    assert.equal(r, 'en', 'locale should return en by default');\n    assert.equal(moment.locale(), 'en', 'locale should return en by default');\n\n    moment.locale('fr');\n    assert.equal(moment.locale(), 'fr', 'locale should return the changed locale');\n\n    moment.locale('en-gb');\n    assert.equal(moment.locale(), 'en-gb', 'locale should return the changed locale');\n\n    moment.locale('en');\n    assert.equal(moment.locale(), 'en', 'locale should reset');\n\n    moment.locale('does-not-exist');\n    assert.equal(moment.locale(), 'en', 'locale should reset');\n\n    moment.locale('EN');\n    assert.equal(moment.locale(), 'en', 'Normalize locale key case');\n\n    moment.locale('EN_gb');\n    assert.equal(moment.locale(), 'en-gb', 'Normalize locale key underscore');\n});\n\ntest('library setter array of locales', function (assert) {\n    assert.equal(moment.locale(['non-existent', 'fr', 'also-non-existent']), 'fr', 'passing an array uses the first valid locale');\n    assert.equal(moment.locale(['es', 'fr', 'also-non-existent']), 'es', 'passing an array uses the first valid locale');\n});\n\ntest('library setter locale substrings', function (assert) {\n    assert.equal(moment.locale('fr-crap'), 'fr', 'use substrings');\n    assert.equal(moment.locale('fr-does-not-exist'), 'fr', 'uses deep substrings');\n    assert.equal(moment.locale('fr-CA-does-not-exist'), 'fr-ca', 'uses deepest substring');\n});\n\ntest('library getter locale array and substrings', function (assert) {\n    assert.equal(moment.locale(['en-CH', 'fr']), 'en', 'prefer root locale to shallower ones');\n    assert.equal(moment.locale(['en-gb-leeds', 'en-CA']), 'en-gb', 'prefer root locale to shallower ones');\n    assert.equal(moment.locale(['en-fake', 'en-CA']), 'en-ca', 'prefer alternatives with shared roots');\n    assert.equal(moment.locale(['en-fake', 'en-fake2', 'en-ca']), 'en-ca', 'prefer alternatives with shared roots');\n    assert.equal(moment.locale(['fake-CA', 'fake-MX', 'fr']), 'fr', 'always find something if possible');\n    assert.equal(moment.locale(['fake-CA', 'fake-MX', 'fr']), 'fr', 'always find something if possible');\n    assert.equal(moment.locale(['fake-CA', 'fake-MX', 'fr-fake-fake-fake']), 'fr', 'always find something if possible');\n    assert.equal(moment.locale(['en', 'en-CA']), 'en', 'prefer earlier if it works');\n});\n\ntest('library ensure inheritance', function (assert) {\n    moment.locale('made-up', {\n        // I put them out of order\n        months : 'February_March_April_May_June_July_August_September_October_November_December_January'.split('_')\n        // the rest of the properties should be inherited.\n    });\n\n    assert.equal(moment([2012, 5, 6]).format('MMMM'), 'July', 'Override some of the configs');\n    assert.equal(moment([2012, 5, 6]).format('MMM'), 'Jun', 'But not all of them');\n});\n\ntest('library ensure inheritance LT L LL LLL LLLL', function (assert) {\n    var locale = 'test-inherit-lt';\n\n    moment.defineLocale(locale, {\n        longDateFormat : {\n            LT : '-[LT]-',\n            L : '-[L]-',\n            LL : '-[LL]-',\n            LLL : '-[LLL]-',\n            LLLL : '-[LLLL]-'\n        },\n        calendar : {\n            sameDay : '[sameDay] LT',\n            nextDay : '[nextDay] L',\n            nextWeek : '[nextWeek] LL',\n            lastDay : '[lastDay] LLL',\n            lastWeek : '[lastWeek] LLLL',\n            sameElse : 'L'\n        }\n    });\n\n    moment.locale('es');\n\n    assert.equal(moment().locale(locale).calendar(), 'sameDay -LT-', 'Should use instance locale in LT formatting');\n    assert.equal(moment().add(1, 'days').locale(locale).calendar(), 'nextDay -L-', 'Should use instance locale in L formatting');\n    assert.equal(moment().add(-1, 'days').locale(locale).calendar(), 'lastDay -LLL-', 'Should use instance locale in LL formatting');\n    assert.equal(moment().add(4, 'days').locale(locale).calendar(), 'nextWeek -LL-', 'Should use instance locale in LLL formatting');\n    assert.equal(moment().add(-4, 'days').locale(locale).calendar(), 'lastWeek -LLLL-', 'Should use instance locale in LLLL formatting');\n});\n\ntest('library localeData', function (assert) {\n    moment.locale('en');\n\n    var jan = moment([2000, 0]);\n\n    assert.equal(moment.localeData().months(jan), 'January', 'no arguments returns global');\n    assert.equal(moment.localeData('zh-cn').months(jan), '一月', 'a string returns the locale based on key');\n    assert.equal(moment.localeData(moment().locale('es')).months(jan), 'enero', 'if you pass in a moment it uses the moment\\'s locale');\n});\n\ntest('library deprecations', function (assert) {\n    test.expectedDeprecations('moment.lang');\n    moment.lang('dude', {months: ['Movember']});\n    assert.equal(moment.locale(), 'dude', 'setting the lang sets the locale');\n    assert.equal(moment.lang(), moment.locale());\n    assert.equal(moment.langData(), moment.localeData(), 'langData is localeData');\n    moment.defineLocale('dude', null);\n});\n\ntest('defineLocale', function (assert) {\n    moment.locale('en');\n    moment.defineLocale('dude', {months: ['Movember']});\n    assert.equal(moment().locale(), 'dude', 'defineLocale also sets it');\n    assert.equal(moment().locale('dude').locale(), 'dude', 'defineLocale defines a locale');\n    moment.defineLocale('dude', null);\n});\n\ntest('locales', function (assert) {\n    moment.defineLocale('dude', {months: ['Movember']});\n    assert.equal(true, !!~indexOf$1.call(moment.locales(), 'dude'), 'locales returns an array of defined locales');\n    assert.equal(true, !!~indexOf$1.call(moment.locales(), 'en'), 'locales should always include english');\n    moment.defineLocale('dude', null);\n});\n\ntest('library convenience', function (assert) {\n    moment.locale('something', {week: {dow: 3}});\n    moment.locale('something');\n    assert.equal(moment.locale(), 'something', 'locale can be used to create the locale too');\n    moment.defineLocale('something', null);\n});\n\ntest('firstDayOfWeek firstDayOfYear locale getters', function (assert) {\n    moment.locale('something', {week: {dow: 3, doy: 4}});\n    moment.locale('something');\n    assert.equal(moment.localeData().firstDayOfWeek(), 3, 'firstDayOfWeek');\n    assert.equal(moment.localeData().firstDayOfYear(), 4, 'firstDayOfYear');\n    moment.defineLocale('something', null);\n});\n\ntest('instance locale method', function (assert) {\n    moment.locale('en');\n\n    assert.equal(moment([2012, 5, 6]).format('MMMM'), 'June', 'Normally default to global');\n    assert.equal(moment([2012, 5, 6]).locale('es').format('MMMM'), 'junio', 'Use the instance specific locale');\n    assert.equal(moment([2012, 5, 6]).format('MMMM'), 'June', 'Using an instance specific locale does not affect other moments');\n});\n\ntest('instance locale method with array', function (assert) {\n    var m = moment().locale(['non-existent', 'fr', 'also-non-existent']);\n    assert.equal(m.locale(), 'fr', 'passing an array uses the first valid locale');\n    m = moment().locale(['es', 'fr', 'also-non-existent']);\n    assert.equal(m.locale(), 'es', 'passing an array uses the first valid locale');\n});\n\ntest('instance getter locale substrings', function (assert) {\n    var m = moment();\n\n    m.locale('fr-crap');\n    assert.equal(m.locale(), 'fr', 'use substrings');\n\n    m.locale('fr-does-not-exist');\n    assert.equal(m.locale(), 'fr', 'uses deep substrings');\n});\n\ntest('instance locale persists with manipulation', function (assert) {\n    moment.locale('en');\n\n    assert.equal(moment([2012, 5, 6]).locale('es').add({days: 1}).format('MMMM'), 'junio', 'With addition');\n    assert.equal(moment([2012, 5, 6]).locale('es').day(0).format('MMMM'), 'junio', 'With day getter');\n    assert.equal(moment([2012, 5, 6]).locale('es').endOf('day').format('MMMM'), 'junio', 'With endOf');\n});\n\ntest('instance locale persists with cloning', function (assert) {\n    moment.locale('en');\n\n    var a = moment([2012, 5, 6]).locale('es'),\n        b = a.clone(),\n        c = moment(a);\n\n    assert.equal(b.format('MMMM'), 'junio', 'using moment.fn.clone()');\n    assert.equal(b.format('MMMM'), 'junio', 'using moment()');\n});\n\ntest('duration locale method', function (assert) {\n    moment.locale('en');\n\n    assert.equal(moment.duration({seconds:  44}).humanize(), 'a few seconds', 'Normally default to global');\n    assert.equal(moment.duration({seconds:  44}).locale('es').humanize(), 'unos segundos', 'Use the instance specific locale');\n    assert.equal(moment.duration({seconds:  44}).humanize(), 'a few seconds', 'Using an instance specific locale does not affect other durations');\n});\n\ntest('duration locale persists with cloning', function (assert) {\n    moment.locale('en');\n\n    var a = moment.duration({seconds:  44}).locale('es'),\n        b = moment.duration(a);\n\n    assert.equal(b.humanize(), 'unos segundos', 'using moment.duration()');\n});\n\ntest('changing the global locale doesn\\'t affect existing duration instances', function (assert) {\n    var mom = moment.duration();\n    moment.locale('fr');\n    assert.equal('en', mom.locale());\n});\n\ntest('duration deprecations', function (assert) {\n    test.expectedDeprecations('moment().lang()');\n    assert.equal(moment.duration().lang(), moment.duration().localeData(), 'duration.lang is the same as duration.localeData');\n});\n\ntest('from and fromNow with invalid date', function (assert) {\n    assert.equal(moment(NaN).from(), 'Invalid date', 'moment.from with invalid moment');\n    assert.equal(moment(NaN).fromNow(), 'Invalid date', 'moment.fromNow with invalid moment');\n});\n\ntest('from relative time future', function (assert) {\n    var start = moment([2007, 1, 28]);\n\n    assert.equal(start.from(moment([2007, 1, 28]).subtract({s: 44})),  'in a few seconds', '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).subtract({s: 45})),  'in a minute',      '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).subtract({s: 89})),  'in a minute',      '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).subtract({s: 90})),  'in 2 minutes',     '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).subtract({m: 44})),  'in 44 minutes',    '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).subtract({m: 45})),  'in an hour',       '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).subtract({m: 89})),  'in an hour',       '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).subtract({m: 90})),  'in 2 hours',       '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).subtract({h: 5})),   'in 5 hours',       '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).subtract({h: 21})),  'in 21 hours',      '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).subtract({h: 22})),  'in a day',         '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).subtract({h: 35})),  'in a day',         '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).subtract({h: 36})),  'in 2 days',        '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).subtract({d: 1})),   'in a day',         '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).subtract({d: 5})),   'in 5 days',        '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).subtract({d: 25})),  'in 25 days',       '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).subtract({d: 26})),  'in a month',       '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).subtract({d: 30})),  'in a month',       '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).subtract({d: 45})),  'in a month',       '45 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).subtract({d: 47})),  'in 2 months',      '47 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).subtract({d: 74})),  'in 2 months',      '74 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).subtract({d: 78})),  'in 3 months',      '78 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).subtract({M: 1})),   'in a month',       '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).subtract({M: 5})),   'in 5 months',      '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).subtract({d: 315})), 'in 10 months',     '315 days = 10 months');\n    assert.equal(start.from(moment([2007, 1, 28]).subtract({d: 344})), 'in a year',        '344 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).subtract({d: 345})), 'in a year',        '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).subtract({d: 548})), 'in 2 years',       '548 days = in 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).subtract({y: 1})),   'in a year',        '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).subtract({y: 5})),   'in 5 years',       '5 years = 5 years');\n});\n\ntest('from relative time past', function (assert) {\n    var start = moment([2007, 1, 28]);\n\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44})),  'a few seconds ago', '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45})),  'a minute ago',      '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89})),  'a minute ago',      '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90})),  '2 minutes ago',     '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44})),  '44 minutes ago',    '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45})),  'an hour ago',       '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89})),  'an hour ago',       '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90})),  '2 hours ago',       '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5})),   '5 hours ago',       '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21})),  '21 hours ago',      '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22})),  'a day ago',         '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35})),  'a day ago',         '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36})),  '2 days ago',        '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1})),   'a day ago',         '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5})),   '5 days ago',        '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25})),  '25 days ago',       '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26})),  'a month ago',       '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30})),  'a month ago',       '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43})),  'a month ago',       '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46})),  '2 months ago',      '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74})),  '2 months ago',      '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76})),  '3 months ago',      '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1})),   'a month ago',       '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5})),   '5 months ago',      '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 315})), '10 months ago',     '315 days = 10 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 344})), 'a year ago',        '344 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345})), 'a year ago',        '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548})), '2 years ago',       '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1})),   'a year ago',        '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5})),   '5 years ago',       '5 years = 5 years');\n});\n\ntest('instance locale used with from', function (assert) {\n    moment.locale('en');\n\n    var a = moment([2012, 5, 6]).locale('es'),\n        b = moment([2012, 5, 7]);\n\n    assert.equal(a.from(b), 'hace un día', 'preserve locale of first moment');\n    assert.equal(b.from(a), 'in a day', 'do not preserve locale of second moment');\n});\n\ntest('instance localeData', function (assert) {\n    moment.defineLocale('dude', {week: {dow: 3}});\n    assert.equal(moment().locale('dude').localeData()._week.dow, 3);\n    moment.defineLocale('dude', null);\n});\n\ntest('month name callback function', function (assert) {\n    function fakeReplace(m, format) {\n        if (/test/.test(format)) {\n            return 'test';\n        }\n        if (m.date() === 1) {\n            return 'date';\n        }\n        return 'default';\n    }\n\n    moment.locale('made-up-2', {\n        months : fakeReplace,\n        monthsShort : fakeReplace,\n        weekdays : fakeReplace,\n        weekdaysShort : fakeReplace,\n        weekdaysMin : fakeReplace\n    });\n\n    assert.equal(moment().format('[test] dd ddd dddd MMM MMMM'), 'test test test test test test', 'format month name function should be able to access the format string');\n    assert.equal(moment([2011, 0, 1]).format('dd ddd dddd MMM MMMM'), 'date date date date date', 'format month name function should be able to access the moment object');\n    assert.equal(moment([2011, 0, 2]).format('dd ddd dddd MMM MMMM'), 'default default default default default', 'format month name function should be able to access the moment object');\n});\n\ntest('changing parts of a locale config', function (assert) {\n    test.expectedDeprecations('defineLocaleOverride');\n\n    moment.locale('partial-lang', {\n        months : 'a b c d e f g h i j k l'.split(' ')\n    });\n\n    assert.equal(moment([2011, 0, 1]).format('MMMM'), 'a', 'should be able to set locale values when creating the localeuage');\n\n    moment.locale('partial-lang', {\n        monthsShort : 'A B C D E F G H I J K L'.split(' ')\n    });\n\n    assert.equal(moment([2011, 0, 1]).format('MMMM MMM'), 'a A', 'should be able to set locale values after creating the localeuage');\n\n    moment.defineLocale('partial-lang', null);\n});\n\ntest('start/endOf week feature for first-day-is-monday locales', function (assert) {\n    moment.locale('monday-lang', {\n        week : {\n            dow : 1 // Monday is the first day of the week\n        }\n    });\n\n    moment.locale('monday-lang');\n    assert.equal(moment([2013, 0, 1]).startOf('week').day(), 1, 'for locale monday-lang first day of the week should be monday');\n    assert.equal(moment([2013, 0, 1]).endOf('week').day(), 0, 'for locale monday-lang last day of the week should be sunday');\n    moment.defineLocale('monday-lang', null);\n});\n\ntest('meridiem parsing', function (assert) {\n    moment.locale('meridiem-parsing', {\n        meridiemParse : /[bd]/i,\n        isPM : function (input) {\n            return input === 'b';\n        }\n    });\n\n    moment.locale('meridiem-parsing');\n    assert.equal(moment('2012-01-01 3b', 'YYYY-MM-DD ha').hour(), 15, 'Custom parsing of meridiem should work');\n    assert.equal(moment('2012-01-01 3d', 'YYYY-MM-DD ha').hour(), 3, 'Custom parsing of meridiem should work');\n    moment.defineLocale('meridiem-parsing', null);\n});\n\ntest('invalid date formatting', function (assert) {\n    moment.locale('has-invalid', {\n        invalidDate: 'KHAAAAAAAAAAAN!'\n    });\n\n    assert.equal(moment.invalid().format(), 'KHAAAAAAAAAAAN!');\n    assert.equal(moment.invalid().format('YYYY-MM-DD'), 'KHAAAAAAAAAAAN!');\n    moment.defineLocale('has-invalid', null);\n});\n\ntest('return locale name', function (assert) {\n    var registered = moment.locale('return-this', {});\n\n    assert.equal(registered, 'return-this', 'returns the locale configured');\n    moment.locale('return-this', null);\n});\n\ntest('changing the global locale doesn\\'t affect existing instances', function (assert) {\n    var mom = moment();\n    moment.locale('fr');\n    assert.equal('en', mom.locale());\n});\n\ntest('setting a language on instance returns the original moment for chaining', function (assert) {\n    test.expectedDeprecations('moment().lang()');\n    var mom = moment();\n\n    assert.equal(mom.lang('fr'), mom, 'setting the language (lang) returns the original moment for chaining');\n    assert.equal(mom.locale('it'), mom, 'setting the language (locale) returns the original moment for chaining');\n});\n\ntest('lang(key) changes the language of the instance', function (assert) {\n    test.expectedDeprecations('moment().lang()');\n    var m = moment().month(0);\n    m.lang('fr');\n    assert.equal(m.locale(), 'fr', 'm.lang(key) changes instance locale');\n});\n\ntest('moment#locale(false) resets to global locale', function (assert) {\n    var m = moment();\n\n    moment.locale('fr');\n    m.locale('it');\n\n    assert.equal(moment.locale(), 'fr', 'global locale is it');\n    assert.equal(m.locale(), 'it', 'instance locale is it');\n    m.locale(false);\n    assert.equal(m.locale(), 'fr', 'instance locale reset to global locale');\n});\n\ntest('moment().locale with missing key doesn\\'t change locale', function (assert) {\n    assert.equal(moment().locale('boo').localeData(), moment.localeData(),\n            'preserve global locale in case of bad locale id');\n});\n\ntest('moment().lang with missing key doesn\\'t change locale', function (assert) {\n    test.expectedDeprecations('moment().lang()');\n    assert.equal(moment().lang('boo').localeData(), moment.localeData(),\n            'preserve global locale in case of bad locale id');\n});\n\n\n// TODO: Enable this after fixing pl months parse hack hack\n// test('monthsParseExact', function (assert) {\n//     var locale = 'test-months-parse-exact';\n\n//     moment.defineLocale(locale, {\n//         monthsParseExact: true,\n//         months: 'A_AA_AAA_B_B B_BB  B_C_C-C_C,C2C_D_D+D_D`D*D'.split('_'),\n//         monthsShort: 'E_EE_EEE_F_FF_FFF_G_GG_GGG_H_HH_HHH'.split('_')\n//     });\n\n//     assert.equal(moment('A', 'MMMM', true).month(), 0, 'parse long month 0 with MMMM');\n//     assert.equal(moment('AA', 'MMMM', true).month(), 1, 'parse long month 1 with MMMM');\n//     assert.equal(moment('AAA', 'MMMM', true).month(), 2, 'parse long month 2 with MMMM');\n//     assert.equal(moment('B B', 'MMMM', true).month(), 4, 'parse long month 4 with MMMM');\n//     assert.equal(moment('BB  B', 'MMMM', true).month(), 5, 'parse long month 5 with MMMM');\n//     assert.equal(moment('C-C', 'MMMM', true).month(), 7, 'parse long month 7 with MMMM');\n//     assert.equal(moment('C,C2C', 'MMMM', true).month(), 8, 'parse long month 8 with MMMM');\n//     assert.equal(moment('D+D', 'MMMM', true).month(), 10, 'parse long month 10 with MMMM');\n//     assert.equal(moment('D`D*D', 'MMMM', true).month(), 11, 'parse long month 11 with MMMM');\n\n//     assert.equal(moment('E', 'MMM', true).month(), 0, 'parse long month 0 with MMM');\n//     assert.equal(moment('EE', 'MMM', true).month(), 1, 'parse long month 1 with MMM');\n//     assert.equal(moment('EEE', 'MMM', true).month(), 2, 'parse long month 2 with MMM');\n\n//     assert.equal(moment('A', 'MMM').month(), 0, 'non-strict parse long month 0 with MMM');\n//     assert.equal(moment('AA', 'MMM').month(), 1, 'non-strict parse long month 1 with MMM');\n//     assert.equal(moment('AAA', 'MMM').month(), 2, 'non-strict parse long month 2 with MMM');\n//     assert.equal(moment('E', 'MMMM').month(), 0, 'non-strict parse short month 0 with MMMM');\n//     assert.equal(moment('EE', 'MMMM').month(), 1, 'non-strict parse short month 1 with MMMM');\n//     assert.equal(moment('EEE', 'MMMM').month(), 2, 'non-strict parse short month 2 with MMMM');\n// });\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\nfunction module$1 (name, lifecycle) {\n    QUnit.module(name, {\n        setup : function () {\n            moment.locale('en');\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'core');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            teardownDeprecationHandler(test, moment, 'core');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n}\n\nmodule$1('locale inheritance');\n\ntest('calendar', function (assert) {\n    moment.defineLocale('base-cal', {\n        calendar : {\n            sameDay: '[Today at] HH:mm',\n            nextDay: '[Tomorrow at] HH:mm',\n            nextWeek: '[Next week at] HH:mm',\n            lastDay: '[Yesterday at] HH:mm',\n            lastWeek: '[Last week at] HH:mm',\n            sameElse: '[whatever]'\n        }\n    });\n    moment.defineLocale('child-cal', {\n        parentLocale: 'base-cal',\n        calendar: {\n            sameDay: '[Today] HH:mm',\n            nextDay: '[Tomorrow] HH:mm',\n            nextWeek: '[Next week] HH:mm'\n        }\n    });\n\n    moment.locale('child-cal');\n    var anchor = moment.utc('2015-05-05T12:00:00', moment.ISO_8601);\n    assert.equal(anchor.clone().add(3, 'hours').calendar(anchor), 'Today 15:00', 'today uses child version');\n    assert.equal(anchor.clone().add(1, 'day').calendar(anchor), 'Tomorrow 12:00', 'tomorrow uses child version');\n    assert.equal(anchor.clone().add(3, 'days').calendar(anchor), 'Next week 12:00', 'next week uses child version');\n\n    assert.equal(anchor.clone().subtract(1, 'day').calendar(anchor), 'Yesterday at 12:00', 'yesterday uses parent version');\n    assert.equal(anchor.clone().subtract(3, 'days').calendar(anchor), 'Last week at 12:00', 'last week uses parent version');\n    assert.equal(anchor.clone().subtract(7, 'days').calendar(anchor), 'whatever', 'sameElse uses parent version -');\n    assert.equal(anchor.clone().add(7, 'days').calendar(anchor), 'whatever', 'sameElse uses parent version +');\n});\n\ntest('missing', function (assert) {\n    moment.defineLocale('base-cal-2', {\n        calendar: {\n            sameDay: '[Today at] HH:mm',\n            nextDay: '[Tomorrow at] HH:mm',\n            nextWeek: '[Next week at] HH:mm',\n            lastDay: '[Yesterday at] HH:mm',\n            lastWeek: '[Last week at] HH:mm',\n            sameElse: '[whatever]'\n        }\n    });\n    moment.defineLocale('child-cal-2', {\n        parentLocale: 'base-cal-2'\n    });\n    moment.locale('child-cal-2');\n    var anchor = moment.utc('2015-05-05T12:00:00', moment.ISO_8601);\n    assert.equal(anchor.clone().add(3, 'hours').calendar(anchor), 'Today at 15:00', 'today uses parent version');\n    assert.equal(anchor.clone().add(1, 'day').calendar(anchor), 'Tomorrow at 12:00', 'tomorrow uses parent version');\n    assert.equal(anchor.clone().add(3, 'days').calendar(anchor), 'Next week at 12:00', 'next week uses parent version');\n    assert.equal(anchor.clone().subtract(1, 'day').calendar(anchor), 'Yesterday at 12:00', 'yesterday uses parent version');\n    assert.equal(anchor.clone().subtract(3, 'days').calendar(anchor), 'Last week at 12:00', 'last week uses parent version');\n    assert.equal(anchor.clone().subtract(7, 'days').calendar(anchor), 'whatever', 'sameElse uses parent version -');\n    assert.equal(anchor.clone().add(7, 'days').calendar(anchor), 'whatever', 'sameElse uses parent version +');\n});\n\n// Test function vs obj both directions\n\ntest('long date format', function (assert) {\n    moment.defineLocale('base-ldf', {\n        longDateFormat : {\n            LTS  : 'h:mm:ss A',\n            LT   : 'h:mm A',\n            L    : 'MM/DD/YYYY',\n            LL   : 'MMMM D, YYYY',\n            LLL  : 'MMMM D, YYYY h:mm A',\n            LLLL : 'dddd, MMMM D, YYYY h:mm A'\n        }\n    });\n    moment.defineLocale('child-ldf', {\n        parentLocale: 'base-ldf',\n        longDateFormat: {\n            LLL  : '[child] MMMM D, YYYY h:mm A',\n            LLLL : '[child] dddd, MMMM D, YYYY h:mm A'\n        }\n    });\n\n    moment.locale('child-ldf');\n    var anchor = moment.utc('2015-09-06T12:34:56', moment.ISO_8601);\n    assert.equal(anchor.format('LTS'), '12:34:56 PM', 'LTS uses base');\n    assert.equal(anchor.format('LT'), '12:34 PM', 'LT uses base');\n    assert.equal(anchor.format('L'), '09/06/2015', 'L uses base');\n    assert.equal(anchor.format('l'), '9/6/2015', 'l uses base');\n    assert.equal(anchor.format('LL'), 'September 6, 2015', 'LL uses base');\n    assert.equal(anchor.format('ll'), 'Sep 6, 2015', 'll uses base');\n    assert.equal(anchor.format('LLL'), 'child September 6, 2015 12:34 PM', 'LLL uses child');\n    assert.equal(anchor.format('lll'), 'child Sep 6, 2015 12:34 PM', 'lll uses child');\n    assert.equal(anchor.format('LLLL'), 'child Sunday, September 6, 2015 12:34 PM', 'LLLL uses child');\n    assert.equal(anchor.format('llll'), 'child Sun, Sep 6, 2015 12:34 PM', 'llll uses child');\n});\n\ntest('ordinal', function (assert) {\n    moment.defineLocale('base-ordinal-1', {\n        ordinal : '%dx'\n    });\n    moment.defineLocale('child-ordinal-1', {\n        parentLocale: 'base-ordinal-1',\n        ordinal : '%dy'\n    });\n\n    assert.equal(moment.utc('2015-02-03', moment.ISO_8601).format('Do'), '3y', 'ordinal uses child string');\n\n    moment.defineLocale('base-ordinal-2', {\n        ordinal : '%dx'\n    });\n    moment.defineLocale('child-ordinal-2', {\n        parentLocale: 'base-ordinal-2',\n        ordinal : function (num) {\n            return num + 'y';\n        }\n    });\n\n    assert.equal(moment.utc('2015-02-03', moment.ISO_8601).format('Do'), '3y', 'ordinal uses child function');\n\n    moment.defineLocale('base-ordinal-3', {\n        ordinal : function (num) {\n            return num + 'x';\n        }\n    });\n    moment.defineLocale('child-ordinal-3', {\n        parentLocale: 'base-ordinal-3',\n        ordinal : '%dy'\n    });\n\n    assert.equal(moment.utc('2015-02-03', moment.ISO_8601).format('Do'), '3y', 'ordinal uses child string (overwrite parent function)');\n});\n\ntest('ordinal parse', function (assert) {\n    moment.defineLocale('base-ordinal-parse-1', {\n        dayOfMonthOrdinalParse : /\\d{1,2}x/\n    });\n    moment.defineLocale('child-ordinal-parse-1', {\n        parentLocale: 'base-ordinal-parse-1',\n        dayOfMonthOrdinalParse : /\\d{1,2}y/\n    });\n\n    assert.ok(moment.utc('2015-01-1y', 'YYYY-MM-Do', true).isValid(), 'ordinal parse uses child');\n\n    moment.defineLocale('base-ordinal-parse-2', {\n        dayOfMonthOrdinalParse : /\\d{1,2}x/\n    });\n    moment.defineLocale('child-ordinal-parse-2', {\n        parentLocale: 'base-ordinal-parse-2',\n        dayOfMonthOrdinalParse : /\\d{1,2}/\n    });\n\n    assert.ok(moment.utc('2015-01-1', 'YYYY-MM-Do', true).isValid(), 'ordinal parse uses child (default)');\n});\n\ntest('months', function (assert) {\n    moment.defineLocale('base-months', {\n        months : 'One_Two_Three_Four_Five_Six_Seven_Eight_Nine_Ten_Eleven_Twelve'.split('_')\n    });\n    moment.defineLocale('child-months', {\n        parentLocale: 'base-months',\n        months : 'First_Second_Third_Fourth_Fifth_Sixth_Seventh_Eighth_Ninth_Tenth_Eleventh_Twelveth '.split('_')\n    });\n    assert.ok(moment.utc('2015-01-01', 'YYYY-MM-DD').format('MMMM'), 'First', 'months uses child');\n});\n\ntest('define child locale before parent', function (assert) {\n    moment.defineLocale('months-x', null);\n    moment.defineLocale('base-months-x', null);\n\n    moment.defineLocale('months-x', {\n        parentLocale: 'base-months-x',\n        months : 'First_Second_Third_Fourth_Fifth_Sixth_Seventh_Eighth_Ninth_Tenth_Eleventh_Twelveth '.split('_')\n    });\n    assert.equal(moment.locale(), 'en', 'failed to set a locale requiring missing parent');\n    moment.defineLocale('base-months-x', {\n        months : 'One_Two_Three_Four_Five_Six_Seven_Eight_Nine_Ten_Eleven_Twelve'.split('_')\n    });\n    assert.equal(moment.locale(), 'base-months-x', 'defineLocale should also set the locale (regardless of child locales)');\n\n    assert.equal(moment().locale('months-x').month(0).format('MMMM'), 'First', 'loading child before parent locale works');\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\nfunction module$1 (name, lifecycle) {\n    QUnit.module(name, {\n        setup : function () {\n            moment.locale('en');\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'core');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            teardownDeprecationHandler(test, moment, 'core');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n}\n\nmodule$1('locale update');\n\ntest('calendar', function (assert) {\n    moment.defineLocale('cal', null);\n    moment.defineLocale('cal', {\n        calendar : {\n            sameDay: '[Today at] HH:mm',\n            nextDay: '[Tomorrow at] HH:mm',\n            nextWeek: '[Next week at] HH:mm',\n            lastDay: '[Yesterday at] HH:mm',\n            lastWeek: '[Last week at] HH:mm',\n            sameElse: '[whatever]'\n        }\n    });\n    moment.updateLocale('cal', {\n        calendar: {\n            sameDay: '[Today] HH:mm',\n            nextDay: '[Tomorrow] HH:mm',\n            nextWeek: '[Next week] HH:mm'\n        }\n    });\n\n    moment.locale('cal');\n    var anchor = moment.utc('2015-05-05T12:00:00', moment.ISO_8601);\n    assert.equal(anchor.clone().add(3, 'hours').calendar(anchor), 'Today 15:00', 'today uses child version');\n    assert.equal(anchor.clone().add(1, 'day').calendar(anchor), 'Tomorrow 12:00', 'tomorrow uses child version');\n    assert.equal(anchor.clone().add(3, 'days').calendar(anchor), 'Next week 12:00', 'next week uses child version');\n\n    assert.equal(anchor.clone().subtract(1, 'day').calendar(anchor), 'Yesterday at 12:00', 'yesterday uses parent version');\n    assert.equal(anchor.clone().subtract(3, 'days').calendar(anchor), 'Last week at 12:00', 'last week uses parent version');\n    assert.equal(anchor.clone().subtract(7, 'days').calendar(anchor), 'whatever', 'sameElse uses parent version -');\n    assert.equal(anchor.clone().add(7, 'days').calendar(anchor), 'whatever', 'sameElse uses parent version +');\n});\n\ntest('missing', function (assert) {\n    moment.defineLocale('cal-2', null);\n    moment.defineLocale('cal-2', {\n        calendar: {\n            sameDay: '[Today at] HH:mm',\n            nextDay: '[Tomorrow at] HH:mm',\n            nextWeek: '[Next week at] HH:mm',\n            lastDay: '[Yesterday at] HH:mm',\n            lastWeek: '[Last week at] HH:mm',\n            sameElse: '[whatever]'\n        }\n    });\n    moment.updateLocale('cal-2', {\n    });\n    moment.locale('cal-2');\n    var anchor = moment.utc('2015-05-05T12:00:00', moment.ISO_8601);\n    assert.equal(anchor.clone().add(3, 'hours').calendar(anchor), 'Today at 15:00', 'today uses parent version');\n    assert.equal(anchor.clone().add(1, 'day').calendar(anchor), 'Tomorrow at 12:00', 'tomorrow uses parent version');\n    assert.equal(anchor.clone().add(3, 'days').calendar(anchor), 'Next week at 12:00', 'next week uses parent version');\n    assert.equal(anchor.clone().subtract(1, 'day').calendar(anchor), 'Yesterday at 12:00', 'yesterday uses parent version');\n    assert.equal(anchor.clone().subtract(3, 'days').calendar(anchor), 'Last week at 12:00', 'last week uses parent version');\n    assert.equal(anchor.clone().subtract(7, 'days').calendar(anchor), 'whatever', 'sameElse uses parent version -');\n    assert.equal(anchor.clone().add(7, 'days').calendar(anchor), 'whatever', 'sameElse uses parent version +');\n});\n\n// Test function vs obj both directions\n\ntest('long date format', function (assert) {\n    moment.defineLocale('ldf', null);\n    moment.defineLocale('ldf', {\n        longDateFormat : {\n            LTS  : 'h:mm:ss A',\n            LT   : 'h:mm A',\n            L    : 'MM/DD/YYYY',\n            LL   : 'MMMM D, YYYY',\n            LLL  : 'MMMM D, YYYY h:mm A',\n            LLLL : 'dddd, MMMM D, YYYY h:mm A'\n        }\n    });\n    moment.updateLocale('ldf', {\n        longDateFormat: {\n            LLL  : '[child] MMMM D, YYYY h:mm A',\n            LLLL : '[child] dddd, MMMM D, YYYY h:mm A'\n        }\n    });\n\n    moment.locale('ldf');\n    var anchor = moment.utc('2015-09-06T12:34:56', moment.ISO_8601);\n    assert.equal(anchor.format('LTS'), '12:34:56 PM', 'LTS uses base');\n    assert.equal(anchor.format('LT'), '12:34 PM', 'LT uses base');\n    assert.equal(anchor.format('L'), '09/06/2015', 'L uses base');\n    assert.equal(anchor.format('l'), '9/6/2015', 'l uses base');\n    assert.equal(anchor.format('LL'), 'September 6, 2015', 'LL uses base');\n    assert.equal(anchor.format('ll'), 'Sep 6, 2015', 'll uses base');\n    assert.equal(anchor.format('LLL'), 'child September 6, 2015 12:34 PM', 'LLL uses child');\n    assert.equal(anchor.format('lll'), 'child Sep 6, 2015 12:34 PM', 'lll uses child');\n    assert.equal(anchor.format('LLLL'), 'child Sunday, September 6, 2015 12:34 PM', 'LLLL uses child');\n    assert.equal(anchor.format('llll'), 'child Sun, Sep 6, 2015 12:34 PM', 'llll uses child');\n});\n\ntest('ordinal', function (assert) {\n    moment.defineLocale('ordinal-1', null);\n    moment.defineLocale('ordinal-1', {\n        ordinal : '%dx'\n    });\n    moment.updateLocale('ordinal-1', {\n        ordinal : '%dy'\n    });\n\n    assert.equal(moment.utc('2015-02-03', moment.ISO_8601).format('Do'), '3y', 'ordinal uses child string');\n\n    moment.defineLocale('ordinal-2', null);\n    moment.defineLocale('ordinal-2', {\n        ordinal : '%dx'\n    });\n    moment.updateLocale('ordinal-2', {\n        ordinal : function (num) {\n            return num + 'y';\n        }\n    });\n\n    assert.equal(moment.utc('2015-02-03', moment.ISO_8601).format('Do'), '3y', 'ordinal uses child function');\n\n    moment.defineLocale('ordinal-3', null);\n    moment.defineLocale('ordinal-3', {\n        ordinal : function (num) {\n            return num + 'x';\n        }\n    });\n    moment.updateLocale('ordinal-3', {\n        ordinal : '%dy'\n    });\n\n    assert.equal(moment.utc('2015-02-03', moment.ISO_8601).format('Do'), '3y', 'ordinal uses child string (overwrite parent function)');\n});\n\ntest('ordinal parse', function (assert) {\n    moment.defineLocale('ordinal-parse-1', null);\n    moment.defineLocale('ordinal-parse-1', {\n        dayOfMonthOrdinalParse : /\\d{1,2}x/\n    });\n    moment.updateLocale('ordinal-parse-1', {\n        dayOfMonthOrdinalParse : /\\d{1,2}y/\n    });\n\n    assert.ok(moment.utc('2015-01-1y', 'YYYY-MM-Do', true).isValid(), 'ordinal parse uses child');\n\n    moment.defineLocale('ordinal-parse-2', null);\n    moment.defineLocale('ordinal-parse-2', {\n        dayOfMonthOrdinalParse : /\\d{1,2}x/\n    });\n    moment.updateLocale('ordinal-parse-2', {\n        dayOfMonthOrdinalParse : /\\d{1,2}/\n    });\n\n    assert.ok(moment.utc('2015-01-1', 'YYYY-MM-Do', true).isValid(), 'ordinal parse uses child (default)');\n});\n\ntest('months', function (assert) {\n    moment.defineLocale('months', null);\n    moment.defineLocale('months', {\n        months : 'One_Two_Three_Four_Five_Six_Seven_Eight_Nine_Ten_Eleven_Twelve'.split('_')\n    });\n    moment.updateLocale('months', {\n        parentLocale: 'base-months',\n        months : 'First_Second_Third_Fourth_Fifth_Sixth_Seventh_Eighth_Ninth_Tenth_Eleventh_Twelveth '.split('_')\n    });\n    assert.ok(moment.utc('2015-01-01', 'YYYY-MM-DD').format('MMMM'), 'First', 'months uses child');\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\nfunction module$1 (name, lifecycle) {\n    QUnit.module(name, {\n        setup : function () {\n            moment.locale('en');\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'core');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            teardownDeprecationHandler(test, moment, 'core');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n}\n\nmodule$1('min max');\n\ntest('min', function (assert) {\n    var now = moment(),\n        future = now.clone().add(1, 'month'),\n        past = now.clone().subtract(1, 'month'),\n        invalid = moment.invalid();\n\n    assert.equal(moment.min(now, future, past), past, 'min(now, future, past)');\n    assert.equal(moment.min(future, now, past), past, 'min(future, now, past)');\n    assert.equal(moment.min(future, past, now), past, 'min(future, past, now)');\n    assert.equal(moment.min(past, future, now), past, 'min(past, future, now)');\n    assert.equal(moment.min(now, past), past, 'min(now, past)');\n    assert.equal(moment.min(past, now), past, 'min(past, now)');\n    assert.equal(moment.min(now), now, 'min(now, past)');\n\n    assert.equal(moment.min([now, future, past]), past, 'min([now, future, past])');\n    assert.equal(moment.min([now, past]), past, 'min(now, past)');\n    assert.equal(moment.min([now]), now, 'min(now)');\n\n    assert.equal(moment.min([now, invalid]), invalid, 'min(now, invalid)');\n    assert.equal(moment.min([invalid, now]), invalid, 'min(invalid, now)');\n});\n\ntest('max', function (assert) {\n    var now = moment(),\n        future = now.clone().add(1, 'month'),\n        past = now.clone().subtract(1, 'month'),\n        invalid = moment.invalid();\n\n    assert.equal(moment.max(now, future, past), future, 'max(now, future, past)');\n    assert.equal(moment.max(future, now, past), future, 'max(future, now, past)');\n    assert.equal(moment.max(future, past, now), future, 'max(future, past, now)');\n    assert.equal(moment.max(past, future, now), future, 'max(past, future, now)');\n    assert.equal(moment.max(now, past), now, 'max(now, past)');\n    assert.equal(moment.max(past, now), now, 'max(past, now)');\n    assert.equal(moment.max(now), now, 'max(now, past)');\n\n    assert.equal(moment.max([now, future, past]), future, 'max([now, future, past])');\n    assert.equal(moment.max([now, past]), now, 'max(now, past)');\n    assert.equal(moment.max([now]), now, 'max(now)');\n\n    assert.equal(moment.max([now, invalid]), invalid, 'max(now, invalid)');\n    assert.equal(moment.max([invalid, now]), invalid, 'max(invalid, now)');\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\nfunction module$1 (name, lifecycle) {\n    QUnit.module(name, {\n        setup : function () {\n            moment.locale('en');\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'core');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            teardownDeprecationHandler(test, moment, 'core');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n}\n\nmodule$1('mutable');\n\ntest('manipulation methods', function (assert) {\n    var m = moment();\n\n    assert.equal(m, m.year(2011), 'year() should be mutable');\n    assert.equal(m, m.month(1), 'month() should be mutable');\n    assert.equal(m, m.hours(7), 'hours() should be mutable');\n    assert.equal(m, m.minutes(33), 'minutes() should be mutable');\n    assert.equal(m, m.seconds(44), 'seconds() should be mutable');\n    assert.equal(m, m.milliseconds(55), 'milliseconds() should be mutable');\n    assert.equal(m, m.day(2), 'day() should be mutable');\n    assert.equal(m, m.startOf('week'), 'startOf() should be mutable');\n    assert.equal(m, m.add(1, 'days'), 'add() should be mutable');\n    assert.equal(m, m.subtract(2, 'years'), 'subtract() should be mutable');\n    assert.equal(m, m.local(), 'local() should be mutable');\n    assert.equal(m, m.utc(), 'utc() should be mutable');\n});\n\ntest('non mutable methods', function (assert) {\n    var m = moment();\n    assert.notEqual(m, m.clone(), 'clone() should not be mutable');\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\nfunction module$1 (name, lifecycle) {\n    QUnit.module(name, {\n        setup : function () {\n            moment.locale('en');\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'core');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            teardownDeprecationHandler(test, moment, 'core');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n}\n\nmodule$1('normalize units');\n\ntest('normalize units', function (assert) {\n    var fullKeys = ['year', 'quarter', 'month', 'isoWeek', 'week', 'day', 'hour', 'minute', 'second', 'millisecond', 'date', 'dayOfYear', 'weekday', 'isoWeekday', 'weekYear', 'isoWeekYear'],\n        aliases = ['y', 'Q', 'M', 'W', 'w', 'd', 'h', 'm', 's', 'ms', 'D', 'DDD', 'e', 'E', 'gg', 'GG'],\n        length = fullKeys.length,\n        fullKey,\n        fullKeyCaps,\n        fullKeyPlural,\n        fullKeyCapsPlural,\n        fullKeyLower,\n        alias,\n        index;\n\n    for (index = 0; index < length; index += 1) {\n        fullKey = fullKeys[index];\n        fullKeyCaps = fullKey.toUpperCase();\n        fullKeyLower = fullKey.toLowerCase();\n        fullKeyPlural = fullKey + 's';\n        fullKeyCapsPlural = fullKeyCaps + 's';\n        alias = aliases[index];\n        assert.equal(moment.normalizeUnits(fullKey), fullKey, 'Testing full key ' + fullKey);\n        assert.equal(moment.normalizeUnits(fullKeyCaps), fullKey, 'Testing full key capitalised ' + fullKey);\n        assert.equal(moment.normalizeUnits(fullKeyPlural), fullKey, 'Testing full key plural ' + fullKey);\n        assert.equal(moment.normalizeUnits(fullKeyCapsPlural), fullKey, 'Testing full key capitalised and plural ' + fullKey);\n        assert.equal(moment.normalizeUnits(alias), fullKey, 'Testing alias ' + fullKey);\n    }\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\nfunction module$1 (name, lifecycle) {\n    QUnit.module(name, {\n        setup : function () {\n            moment.locale('en');\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'core');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            teardownDeprecationHandler(test, moment, 'core');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n}\n\nmodule$1('now');\n\ntest('now', function (assert) {\n    var startOfTest = new Date().valueOf(),\n        momentNowTime = moment.now(),\n        afterMomentCreationTime = new Date().valueOf();\n\n    assert.ok(startOfTest <= momentNowTime, 'moment now() time should be now, not in the past');\n    assert.ok(momentNowTime <= afterMomentCreationTime, 'moment now() time should be now, not in the future');\n});\n\ntest('now - Date mocked', function (assert) {\n    // We need to test mocking the global Date object, so disable 'Read Only' jshint check\n    /* jshint -W020 */\n    var RealDate = Date,\n        customTimeMs = moment('2015-01-01T01:30:00.000Z').valueOf();\n\n    function MockDate() {\n        return new RealDate(customTimeMs);\n    }\n\n    MockDate.now = function () {\n        return new MockDate().valueOf();\n    };\n\n    MockDate.prototype = RealDate.prototype;\n\n    Date = MockDate;\n\n    try {\n        assert.equal(moment().valueOf(), customTimeMs, 'moment now() time should use the global Date object');\n    } finally {\n        Date = RealDate;\n    }\n});\n\ntest('now - custom value', function (assert) {\n    var customTimeStr = '2015-01-01T01:30:00.000Z',\n        customTime = moment(customTimeStr, moment.ISO_8601).valueOf(),\n        oldFn = moment.now;\n\n    moment.now = function () {\n        return customTime;\n    };\n\n    try {\n        assert.equal(moment().toISOString(), customTimeStr, 'moment() constructor should use the function defined by moment.now, but it did not');\n        assert.equal(moment.utc().toISOString(), customTimeStr, 'moment() constructor should use the function defined by moment.now, but it did not');\n    } finally {\n        moment.now = oldFn;\n    }\n});\n\ntest('empty object, empty array', function (assert) {\n    function assertIsNow(gen, msg) {\n        var before = +(new Date()),\n            mid = gen(),\n            after = +(new Date());\n        assert.ok(before <= +mid && +mid <= after, 'should be now : ' + msg);\n    }\n    assertIsNow(function () {\n        return moment();\n    }, 'moment()');\n    assertIsNow(function () {\n        return moment([]);\n    }, 'moment([])');\n    assertIsNow(function () {\n        return moment({});\n    }, 'moment({})');\n    assertIsNow(function () {\n        return moment.utc();\n    }, 'moment.utc()');\n    assertIsNow(function () {\n        return moment.utc([]);\n    }, 'moment.utc([])');\n    assertIsNow(function () {\n        return moment.utc({});\n    }, 'moment.utc({})');\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\nfunction module$1 (name, lifecycle) {\n    QUnit.module(name, {\n        setup : function () {\n            moment.locale('en');\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'core');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            teardownDeprecationHandler(test, moment, 'core');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n}\n\nmodule$1('parsing flags');\n\nfunction flags () {\n    return moment.apply(null, arguments).parsingFlags();\n}\n\ntest('overflow with array', function (assert) {\n    //months\n    assert.equal(flags([2010, 0]).overflow, -1, 'month 0 valid');\n    assert.equal(flags([2010, 1]).overflow, -1, 'month 1 valid');\n    assert.equal(flags([2010, -1]).overflow, 1, 'month -1 invalid');\n    assert.equal(flags([2100, 12]).overflow, 1, 'month 12 invalid');\n\n    //days\n    assert.equal(flags([2010, 1, 16]).overflow, -1, 'date valid');\n    assert.equal(flags([2010, 1, -1]).overflow, 2, 'date -1 invalid');\n    assert.equal(flags([2010, 1, 0]).overflow, 2, 'date 0 invalid');\n    assert.equal(flags([2010, 1, 32]).overflow, 2, 'date 32 invalid');\n    assert.equal(flags([2012, 1, 29]).overflow, -1, 'date leap year valid');\n    assert.equal(flags([2010, 1, 29]).overflow, 2, 'date leap year invalid');\n\n    //hours\n    assert.equal(flags([2010, 1, 1, 8]).overflow, -1, 'hour valid');\n    assert.equal(flags([2010, 1, 1, 0]).overflow, -1, 'hour 0 valid');\n    assert.equal(flags([2010, 1, 1, -1]).overflow, 3, 'hour -1 invalid');\n    assert.equal(flags([2010, 1, 1, 25]).overflow, 3, 'hour 25 invalid');\n    assert.equal(flags([2010, 1, 1, 24, 1]).overflow, 3, 'hour 24:01 invalid');\n\n    //minutes\n    assert.equal(flags([2010, 1, 1, 8, 15]).overflow, -1, 'minute valid');\n    assert.equal(flags([2010, 1, 1, 8, 0]).overflow, -1, 'minute 0 valid');\n    assert.equal(flags([2010, 1, 1, 8, -1]).overflow, 4, 'minute -1 invalid');\n    assert.equal(flags([2010, 1, 1, 8, 60]).overflow, 4, 'minute 60 invalid');\n\n    //seconds\n    assert.equal(flags([2010, 1, 1, 8, 15, 12]).overflow, -1, 'second valid');\n    assert.equal(flags([2010, 1, 1, 8, 15, 0]).overflow, -1, 'second 0 valid');\n    assert.equal(flags([2010, 1, 1, 8, 15, -1]).overflow, 5, 'second -1 invalid');\n    assert.equal(flags([2010, 1, 1, 8, 15, 60]).overflow, 5, 'second 60 invalid');\n\n    //milliseconds\n    assert.equal(flags([2010, 1, 1, 8, 15, 12, 345]).overflow, -1, 'millisecond valid');\n    assert.equal(flags([2010, 1, 1, 8, 15, 12, 0]).overflow, -1, 'millisecond 0 valid');\n    assert.equal(flags([2010, 1, 1, 8, 15, 12, -1]).overflow, 6, 'millisecond -1 invalid');\n    assert.equal(flags([2010, 1, 1, 8, 15, 12, 1000]).overflow, 6, 'millisecond 1000 invalid');\n\n    // 24 hrs\n    assert.equal(flags([2010, 1, 1, 24, 0, 0, 0]).overflow, -1, '24:00:00.000 is fine');\n    assert.equal(flags([2010, 1, 1, 24, 1, 0, 0]).overflow, 3, '24:01:00.000 is wrong hour');\n    assert.equal(flags([2010, 1, 1, 24, 0, 1, 0]).overflow, 3, '24:00:01.000 is wrong hour');\n    assert.equal(flags([2010, 1, 1, 24, 0, 0, 1]).overflow, 3, '24:00:00.001 is wrong hour');\n});\n\ntest('overflow without format', function (assert) {\n    //months\n    assert.equal(flags('2001-01', 'YYYY-MM').overflow, -1, 'month 1 valid');\n    assert.equal(flags('2001-12', 'YYYY-MM').overflow, -1, 'month 12 valid');\n    assert.equal(flags('2001-13', 'YYYY-MM').overflow, 1, 'month 13 invalid');\n\n    //days\n    assert.equal(flags('2010-01-16', 'YYYY-MM-DD').overflow, -1, 'date 16 valid');\n    assert.equal(flags('2010-01-0',  'YYYY-MM-DD').overflow, 2, 'date 0 invalid');\n    assert.equal(flags('2010-01-32', 'YYYY-MM-DD').overflow, 2, 'date 32 invalid');\n    assert.equal(flags('2012-02-29', 'YYYY-MM-DD').overflow, -1, 'date leap year valid');\n    assert.equal(flags('2010-02-29', 'YYYY-MM-DD').overflow, 2, 'date leap year invalid');\n\n    //days of the year\n    assert.equal(flags('2010 300', 'YYYY DDDD').overflow, -1, 'day 300 of year valid');\n    assert.equal(flags('2010 365', 'YYYY DDDD').overflow, -1, 'day 365 of year valid');\n    assert.equal(flags('2010 366', 'YYYY DDDD').overflow, 2, 'day 366 of year invalid');\n    assert.equal(flags('2012 366', 'YYYY DDDD').overflow, -1, 'day 366 of leap year valid');\n    assert.equal(flags('2012 367', 'YYYY DDDD').overflow, 2, 'day 367 of leap year invalid');\n\n    //hours\n    assert.equal(flags('08', 'HH').overflow, -1, 'hour valid');\n    assert.equal(flags('00', 'HH').overflow, -1, 'hour 0 valid');\n    assert.equal(flags('25', 'HH').overflow, 3, 'hour 25 invalid');\n    assert.equal(flags('24:01', 'HH:mm').overflow, 3, 'hour 24:01 invalid');\n\n    //minutes\n    assert.equal(flags('08:15', 'HH:mm').overflow, -1, 'minute valid');\n    assert.equal(flags('08:00', 'HH:mm').overflow, -1, 'minute 0 valid');\n    assert.equal(flags('08:60', 'HH:mm').overflow, 4, 'minute 60 invalid');\n\n    //seconds\n    assert.equal(flags('08:15:12', 'HH:mm:ss').overflow, -1, 'second valid');\n    assert.equal(flags('08:15:00', 'HH:mm:ss').overflow, -1, 'second 0 valid');\n    assert.equal(flags('08:15:60', 'HH:mm:ss').overflow, 5, 'second 60 invalid');\n\n    //milliseconds\n    assert.equal(flags('08:15:12:345', 'HH:mm:ss:SSSS').overflow, -1, 'millisecond valid');\n    assert.equal(flags('08:15:12:000', 'HH:mm:ss:SSSS').overflow, -1, 'millisecond 0 valid');\n\n    //this is OK because we don't match the last digit, so it's 100 ms\n    assert.equal(flags('08:15:12:1000', 'HH:mm:ss:SSSS').overflow, -1, 'millisecond 1000 actually valid');\n});\n\ntest('extra tokens', function (assert) {\n    assert.deepEqual(flags('1982-05-25', 'YYYY-MM-DD').unusedTokens, [], 'nothing extra');\n    assert.deepEqual(flags('1982-05', 'YYYY-MM-DD').unusedTokens, ['DD'], 'extra formatting token');\n    assert.deepEqual(flags('1982', 'YYYY-MM-DD').unusedTokens, ['MM', 'DD'], 'multiple extra formatting tokens');\n    assert.deepEqual(flags('1982-05', 'YYYY-MM-').unusedTokens, [], 'extra non-formatting token');\n    assert.deepEqual(flags('1982-05-', 'YYYY-MM-DD').unusedTokens, ['DD'], 'non-extra non-formatting token');\n    assert.deepEqual(flags('1982 05 1982', 'YYYY-MM-DD').unusedTokens, [], 'different non-formatting token');\n});\n\ntest('extra tokens strict', function (assert) {\n    assert.deepEqual(flags('1982-05-25', 'YYYY-MM-DD', true).unusedTokens, [], 'nothing extra');\n    assert.deepEqual(flags('1982-05', 'YYYY-MM-DD', true).unusedTokens, ['-', 'DD'], 'extra formatting token');\n    assert.deepEqual(flags('1982', 'YYYY-MM-DD', true).unusedTokens, ['-', 'MM', '-', 'DD'], 'multiple extra formatting tokens');\n    assert.deepEqual(flags('1982-05', 'YYYY-MM-', true).unusedTokens, ['-'], 'extra non-formatting token');\n    assert.deepEqual(flags('1982-05-', 'YYYY-MM-DD', true).unusedTokens, ['DD'], 'non-extra non-formatting token');\n    assert.deepEqual(flags('1982 05 1982', 'YYYY-MM-DD', true).unusedTokens, ['-', '-'], 'different non-formatting token');\n});\n\ntest('unused input', function (assert) {\n    assert.deepEqual(flags('1982-05-25', 'YYYY-MM-DD').unusedInput, [], 'normal input');\n    assert.deepEqual(flags('1982-05-25 this is more stuff', 'YYYY-MM-DD').unusedInput, [' this is more stuff'], 'trailing nonsense');\n    assert.deepEqual(flags('1982-05-25 09:30', 'YYYY-MM-DD').unusedInput, [' 09:30'], ['trailing legit-looking input']);\n    assert.deepEqual(flags('1982-05-25 some junk', 'YYYY-MM-DD [some junk]').unusedInput, [], 'junk that actually gets matched');\n    assert.deepEqual(flags('stuff at beginning 1982-05-25', 'YYYY-MM-DD').unusedInput, ['stuff at beginning '], 'leading junk');\n    assert.deepEqual(flags('junk 1982 more junk 05 yet more junk25', 'YYYY-MM-DD').unusedInput, ['junk ', ' more junk ', ' yet more junk'], 'interstitial junk');\n});\n\ntest('unused input strict', function (assert) {\n    assert.deepEqual(flags('1982-05-25', 'YYYY-MM-DD', true).unusedInput, [], 'normal input');\n    assert.deepEqual(flags('1982-05-25 this is more stuff', 'YYYY-MM-DD', true).unusedInput, [' this is more stuff'], 'trailing nonsense');\n    assert.deepEqual(flags('1982-05-25 09:30', 'YYYY-MM-DD', true).unusedInput, [' 09:30'], ['trailing legit-looking input']);\n    assert.deepEqual(flags('1982-05-25 some junk', 'YYYY-MM-DD [some junk]', true).unusedInput, [], 'junk that actually gets matched');\n    assert.deepEqual(flags('stuff at beginning 1982-05-25', 'YYYY-MM-DD', true).unusedInput, ['stuff at beginning '], 'leading junk');\n    assert.deepEqual(flags('junk 1982 more junk 05 yet more junk25', 'YYYY-MM-DD', true).unusedInput, ['junk ', ' more junk ', ' yet more junk'], 'interstitial junk');\n});\n\ntest('chars left over', function (assert) {\n    assert.equal(flags('1982-05-25', 'YYYY-MM-DD').charsLeftOver, 0, 'normal input');\n    assert.equal(flags('1982-05-25 this is more stuff', 'YYYY-MM-DD').charsLeftOver, ' this is more stuff'.length, 'trailing nonsense');\n    assert.equal(flags('1982-05-25 09:30', 'YYYY-MM-DD').charsLeftOver, ' 09:30'.length, 'trailing legit-looking input');\n    assert.equal(flags('stuff at beginning 1982-05-25', 'YYYY-MM-DD').charsLeftOver, 'stuff at beginning '.length, 'leading junk');\n    assert.equal(flags('1982 junk 05 more junk25', 'YYYY-MM-DD').charsLeftOver, [' junk ', ' more junk'].join('').length, 'interstitial junk');\n    assert.equal(flags('stuff at beginning 1982 junk 05 more junk25', 'YYYY-MM-DD').charsLeftOver, ['stuff at beginning ', ' junk ', ' more junk'].join('').length, 'leading and interstitial junk');\n});\n\ntest('empty', function (assert) {\n    assert.equal(flags('1982-05-25', 'YYYY-MM-DD').empty, false, 'normal input');\n    assert.equal(flags('nothing here', 'YYYY-MM-DD').empty, true, 'pure garbage');\n    assert.equal(flags('junk but has the number 2000 in it', 'YYYY-MM-DD').empty, false, 'only mostly garbage');\n    assert.equal(flags('', 'YYYY-MM-DD').empty, true, 'empty string');\n    assert.equal(flags('', 'YYYY-MM-DD').empty, true, 'blank string');\n});\n\ntest('null', function (assert) {\n    assert.equal(flags('1982-05-25', 'YYYY-MM-DD').nullInput, false, 'normal input');\n    assert.equal(flags(null).nullInput, true, 'just null');\n    assert.equal(flags(null, 'YYYY-MM-DD').nullInput, true, 'null with format');\n});\n\ntest('invalid month', function (assert) {\n    assert.equal(flags('1982 May', 'YYYY MMMM').invalidMonth, null, 'normal input');\n    assert.equal(flags('1982 Laser', 'YYYY MMMM').invalidMonth, 'Laser', 'bad month name');\n});\n\ntest('empty format array', function (assert) {\n    assert.equal(flags('1982 May', ['YYYY MMM']).invalidFormat, false, 'empty format array');\n    assert.equal(flags('1982 May', []).invalidFormat, true, 'empty format array');\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\nfunction module$1 (name, lifecycle) {\n    QUnit.module(name, {\n        setup : function () {\n            moment.locale('en');\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'core');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            teardownDeprecationHandler(test, moment, 'core');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n}\n\nvar symbolMap = {\n        '1': '!',\n        '2': '@',\n        '3': '#',\n        '4': '$',\n        '5': '%',\n        '6': '^',\n        '7': '&',\n        '8': '*',\n        '9': '(',\n        '0': ')'\n    };\nvar numberMap = {\n        '!': '1',\n        '@': '2',\n        '#': '3',\n        '$': '4',\n        '%': '5',\n        '^': '6',\n        '&': '7',\n        '*': '8',\n        '(': '9',\n        ')': '0'\n    };\n\nmodule$1('preparse and postformat', {\n    setup: function () {\n        moment.locale('symbol', {\n            preparse: function (string) {\n                return string.replace(/[!@#$%\\^&*()]/g, function (match) {\n                    return numberMap[match];\n                });\n            },\n\n            postformat: function (string) {\n                return string.replace(/\\d/g, function (match) {\n                    return symbolMap[match];\n                });\n            }\n        });\n    },\n    teardown: function () {\n        moment.defineLocale('symbol', null);\n    }\n});\n\ntest('transform', function (assert) {\n    assert.equal(moment.utc('@)!@-)*-@&', 'YYYY-MM-DD').unix(), 1346025600, 'preparse string + format');\n    assert.equal(moment.utc('@)!@-)*-@&').unix(), 1346025600, 'preparse ISO8601 string');\n    assert.equal(moment.unix(1346025600).utc().format('YYYY-MM-DD'), '@)!@-)*-@&', 'postformat');\n});\n\ntest('transform from', function (assert) {\n    var start = moment([2007, 1, 28]);\n\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true), '@ minutes', 'postformat should work on moment.fn.from');\n    assert.equal(moment().add(6, 'd').fromNow(true), '^ days', 'postformat should work on moment.fn.fromNow');\n    assert.equal(moment.duration(10, 'h').humanize(), '!) hours', 'postformat should work on moment.duration.fn.humanize');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'Today at !@:)) PM',     'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'Today at !@:@% PM',     'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'Today at !:)) PM',      'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'Tomorrow at !@:)) PM',  'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'Today at !!:)) AM',     'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'Yesterday at !@:)) PM', 'yesterday at the same time');\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\nfunction module$1 (name, lifecycle) {\n    QUnit.module(name, {\n        setup : function () {\n            moment.locale('en');\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'core');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            teardownDeprecationHandler(test, moment, 'core');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n}\n\nmodule$1('quarter');\n\ntest('library quarter getter', function (assert) {\n    assert.equal(moment([1985,  1,  4]).quarter(), 1, 'Feb  4 1985 is Q1');\n    assert.equal(moment([2029,  8, 18]).quarter(), 3, 'Sep 18 2029 is Q3');\n    assert.equal(moment([2013,  3, 24]).quarter(), 2, 'Apr 24 2013 is Q2');\n    assert.equal(moment([2015,  2,  5]).quarter(), 1, 'Mar  5 2015 is Q1');\n    assert.equal(moment([1970,  0,  2]).quarter(), 1, 'Jan  2 1970 is Q1');\n    assert.equal(moment([2001, 11, 12]).quarter(), 4, 'Dec 12 2001 is Q4');\n    assert.equal(moment([2000,  0,  2]).quarter(), 1, 'Jan  2 2000 is Q1');\n});\n\ntest('quarter setter singular', function (assert) {\n    var m = moment([2014, 4, 11]);\n    assert.equal(m.quarter(2).month(), 4, 'set same quarter');\n    assert.equal(m.quarter(3).month(), 7, 'set 3rd quarter');\n    assert.equal(m.quarter(1).month(), 1, 'set 1st quarter');\n    assert.equal(m.quarter(4).month(), 10, 'set 4th quarter');\n});\n\ntest('quarter setter plural', function (assert) {\n    var m = moment([2014, 4, 11]);\n    assert.equal(m.quarters(2).month(), 4, 'set same quarter');\n    assert.equal(m.quarters(3).month(), 7, 'set 3rd quarter');\n    assert.equal(m.quarters(1).month(), 1, 'set 1st quarter');\n    assert.equal(m.quarters(4).month(), 10, 'set 4th quarter');\n});\n\ntest('quarter setter programmatic', function (assert) {\n    var m = moment([2014, 4, 11]);\n    assert.equal(m.set('quarter', 2).month(), 4, 'set same quarter');\n    assert.equal(m.set('quarter', 3).month(), 7, 'set 3rd quarter');\n    assert.equal(m.set('quarter', 1).month(), 1, 'set 1st quarter');\n    assert.equal(m.set('quarter', 4).month(), 10, 'set 4th quarter');\n});\n\ntest('quarter setter programmatic plural', function (assert) {\n    var m = moment([2014, 4, 11]);\n    assert.equal(m.set('quarters', 2).month(), 4, 'set same quarter');\n    assert.equal(m.set('quarters', 3).month(), 7, 'set 3rd quarter');\n    assert.equal(m.set('quarters', 1).month(), 1, 'set 1st quarter');\n    assert.equal(m.set('quarters', 4).month(), 10, 'set 4th quarter');\n});\n\ntest('quarter setter programmatic abbr', function (assert) {\n    var m = moment([2014, 4, 11]);\n    assert.equal(m.set('Q', 2).month(), 4, 'set same quarter');\n    assert.equal(m.set('Q', 3).month(), 7, 'set 3rd quarter');\n    assert.equal(m.set('Q', 1).month(), 1, 'set 1st quarter');\n    assert.equal(m.set('Q', 4).month(), 10, 'set 4th quarter');\n});\n\ntest('quarter setter only month changes', function (assert) {\n    var m = moment([2014, 4, 11, 1, 2, 3, 4]).quarter(4);\n    assert.equal(m.year(), 2014, 'keep year');\n    assert.equal(m.month(), 10, 'set month');\n    assert.equal(m.date(), 11, 'keep date');\n    assert.equal(m.hour(), 1, 'keep hour');\n    assert.equal(m.minute(), 2, 'keep minutes');\n    assert.equal(m.second(), 3, 'keep seconds');\n    assert.equal(m.millisecond(), 4, 'keep milliseconds');\n});\n\ntest('quarter setter bubble to next year', function (assert) {\n    var m = moment([2014, 4, 11, 1, 2, 3, 4]).quarter(7);\n    assert.equal(m.year(), 2015, 'year bubbled');\n    assert.equal(m.month(), 7, 'set month');\n    assert.equal(m.date(), 11, 'keep date');\n    assert.equal(m.hour(), 1, 'keep hour');\n    assert.equal(m.minute(), 2, 'keep minutes');\n    assert.equal(m.second(), 3, 'keep seconds');\n    assert.equal(m.millisecond(), 4, 'keep milliseconds');\n});\n\ntest('quarter diff', function (assert) {\n    assert.equal(moment('2014-01-01').diff(moment('2014-04-01'), 'quarter'),\n            -1, 'diff -1 quarter');\n    assert.equal(moment('2014-04-01').diff(moment('2014-01-01'), 'quarter'),\n            1, 'diff 1 quarter');\n    assert.equal(moment('2014-05-01').diff(moment('2014-01-01'), 'quarter'),\n            1, 'diff 1 quarter');\n    assert.ok(Math.abs((4 / 3) - moment('2014-05-01').diff(\n                    moment('2014-01-01'), 'quarter', true)) < 0.00001,\n            'diff 1 1/3 quarter');\n    assert.equal(moment('2015-01-01').diff(moment('2014-01-01'), 'quarter'),\n            4, 'diff 4 quarters');\n});\n\ntest('quarter setter bubble to previous year', function (assert) {\n    var m = moment([2014, 4, 11, 1, 2, 3, 4]).quarter(-3);\n    assert.equal(m.year(), 2013, 'year bubbled');\n    assert.equal(m.month(), 1, 'set month');\n    assert.equal(m.date(), 11, 'keep date');\n    assert.equal(m.hour(), 1, 'keep hour');\n    assert.equal(m.minute(), 2, 'keep minutes');\n    assert.equal(m.second(), 3, 'keep seconds');\n    assert.equal(m.millisecond(), 4, 'keep milliseconds');\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\nfunction module$1 (name, lifecycle) {\n    QUnit.module(name, {\n        setup : function () {\n            moment.locale('en');\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'core');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            teardownDeprecationHandler(test, moment, 'core');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n}\n\nmodule$1('relative time');\n\ntest('default thresholds fromNow', function (assert) {\n    var a = moment();\n\n    // Seconds to minutes threshold\n    a.subtract(44, 'seconds');\n    assert.equal(a.fromNow(), 'a few seconds ago', 'Below default seconds to minutes threshold');\n    a.subtract(1, 'seconds');\n    assert.equal(a.fromNow(), 'a minute ago', 'Above default seconds to minutes threshold');\n\n    // Minutes to hours threshold\n    a = moment();\n    a.subtract(44, 'minutes');\n    assert.equal(a.fromNow(), '44 minutes ago', 'Below default minute to hour threshold');\n    a.subtract(1, 'minutes');\n    assert.equal(a.fromNow(), 'an hour ago', 'Above default minute to hour threshold');\n\n    // Hours to days threshold\n    a = moment();\n    a.subtract(21, 'hours');\n    assert.equal(a.fromNow(), '21 hours ago', 'Below default hours to day threshold');\n    a.subtract(1, 'hours');\n    assert.equal(a.fromNow(), 'a day ago', 'Above default hours to day threshold');\n\n    // Days to month threshold\n    a = moment();\n    a.subtract(25, 'days');\n    assert.equal(a.fromNow(), '25 days ago', 'Below default days to month (singular) threshold');\n    a.subtract(1, 'days');\n    assert.equal(a.fromNow(), 'a month ago', 'Above default days to month (singular) threshold');\n\n    // months to year threshold\n    a = moment();\n    a.subtract(10, 'months');\n    assert.equal(a.fromNow(), '10 months ago', 'Below default days to years threshold');\n    a.subtract(1, 'month');\n    assert.equal(a.fromNow(), 'a year ago', 'Above default days to years threshold');\n});\n\ntest('default thresholds toNow', function (assert) {\n    var a = moment();\n\n    // Seconds to minutes threshold\n    a.subtract(44, 'seconds');\n    assert.equal(a.toNow(), 'in a few seconds', 'Below default seconds to minutes threshold');\n    a.subtract(1, 'seconds');\n    assert.equal(a.toNow(), 'in a minute', 'Above default seconds to minutes threshold');\n\n    // Minutes to hours threshold\n    a = moment();\n    a.subtract(44, 'minutes');\n    assert.equal(a.toNow(), 'in 44 minutes', 'Below default minute to hour threshold');\n    a.subtract(1, 'minutes');\n    assert.equal(a.toNow(), 'in an hour', 'Above default minute to hour threshold');\n\n    // Hours to days threshold\n    a = moment();\n    a.subtract(21, 'hours');\n    assert.equal(a.toNow(), 'in 21 hours', 'Below default hours to day threshold');\n    a.subtract(1, 'hours');\n    assert.equal(a.toNow(), 'in a day', 'Above default hours to day threshold');\n\n    // Days to month threshold\n    a = moment();\n    a.subtract(25, 'days');\n    assert.equal(a.toNow(), 'in 25 days', 'Below default days to month (singular) threshold');\n    a.subtract(1, 'days');\n    assert.equal(a.toNow(), 'in a month', 'Above default days to month (singular) threshold');\n\n    // months to year threshold\n    a = moment();\n    a.subtract(10, 'months');\n    assert.equal(a.toNow(), 'in 10 months', 'Below default days to years threshold');\n    a.subtract(1, 'month');\n    assert.equal(a.toNow(), 'in a year', 'Above default days to years threshold');\n});\n\ntest('custom thresholds', function (assert) {\n    var a;\n\n    // Seconds to minute threshold, under 30\n    moment.relativeTimeThreshold('s', 25);\n\n    a = moment();\n    a.subtract(24, 'seconds');\n    assert.equal(a.fromNow(), 'a few seconds ago', 'Below custom seconds to minute threshold, s < 30');\n    a.subtract(1, 'seconds');\n    assert.equal(a.fromNow(), 'a minute ago', 'Above custom seconds to minute threshold, s < 30');\n\n    // Seconds to minutes threshold\n    moment.relativeTimeThreshold('s', 55);\n\n    a = moment();\n    a.subtract(54, 'seconds');\n    assert.equal(a.fromNow(), 'a few seconds ago', 'Below custom seconds to minutes threshold');\n    a.subtract(1, 'seconds');\n    assert.equal(a.fromNow(), 'a minute ago', 'Above custom seconds to minutes threshold');\n\n    moment.relativeTimeThreshold('s', 45);\n\n    // A few seconds to seconds threshold\n    moment.relativeTimeThreshold('ss', 3);\n\n    a = moment();\n    a.subtract(3, 'seconds');\n    assert.equal(a.fromNow(), 'a few seconds ago', 'Below custom a few seconds to seconds threshold');\n    a.subtract(1, 'seconds');\n    assert.equal(a.fromNow(), '4 seconds ago', 'Above custom a few seconds to seconds threshold');\n\n    moment.relativeTimeThreshold('ss', 44);\n\n    // Minutes to hours threshold\n    moment.relativeTimeThreshold('m', 55);\n    a = moment();\n    a.subtract(54, 'minutes');\n    assert.equal(a.fromNow(), '54 minutes ago', 'Below custom minutes to hours threshold');\n    a.subtract(1, 'minutes');\n    assert.equal(a.fromNow(), 'an hour ago', 'Above custom minutes to hours threshold');\n    moment.relativeTimeThreshold('m', 45);\n\n    // Hours to days threshold\n    moment.relativeTimeThreshold('h', 24);\n    a = moment();\n    a.subtract(23, 'hours');\n    assert.equal(a.fromNow(), '23 hours ago', 'Below custom hours to days threshold');\n    a.subtract(1, 'hours');\n    assert.equal(a.fromNow(), 'a day ago', 'Above custom hours to days threshold');\n    moment.relativeTimeThreshold('h', 22);\n\n    // Days to month threshold\n    moment.relativeTimeThreshold('d', 28);\n    a = moment();\n    a.subtract(27, 'days');\n    assert.equal(a.fromNow(), '27 days ago', 'Below custom days to month (singular) threshold');\n    a.subtract(1, 'days');\n    assert.equal(a.fromNow(), 'a month ago', 'Above custom days to month (singular) threshold');\n    moment.relativeTimeThreshold('d', 26);\n\n    // months to years threshold\n    moment.relativeTimeThreshold('M', 9);\n    a = moment();\n    a.subtract(8, 'months');\n    assert.equal(a.fromNow(), '8 months ago', 'Below custom days to years threshold');\n    a.subtract(1, 'months');\n    assert.equal(a.fromNow(), 'a year ago', 'Above custom days to years threshold');\n    moment.relativeTimeThreshold('M', 11);\n});\n\ntest('custom rounding', function (assert) {\n    var roundingDefault = moment.relativeTimeRounding();\n\n    // Round relative time evaluation down\n    moment.relativeTimeRounding(Math.floor);\n\n    moment.relativeTimeThreshold('s', 60);\n    moment.relativeTimeThreshold('m', 60);\n    moment.relativeTimeThreshold('h', 24);\n    moment.relativeTimeThreshold('d', 27);\n    moment.relativeTimeThreshold('M', 12);\n\n    var a = moment.utc();\n    a.subtract({minutes: 59, seconds: 59});\n    assert.equal(a.toNow(), 'in 59 minutes', 'Round down towards the nearest minute');\n\n    a = moment.utc();\n    a.subtract({hours: 23, minutes: 59, seconds: 59});\n    assert.equal(a.toNow(), 'in 23 hours', 'Round down towards the nearest hour');\n\n    a = moment.utc();\n    a.subtract({days: 26, hours: 23, minutes: 59});\n    assert.equal(a.toNow(), 'in 26 days', 'Round down towards the nearest day (just under)');\n\n    a = moment.utc();\n    a.subtract({days: 27});\n    assert.equal(a.toNow(), 'in a month', 'Round down towards the nearest day (just over)');\n\n    a = moment.utc();\n    a.subtract({days: 364});\n    assert.equal(a.toNow(), 'in 11 months', 'Round down towards the nearest month');\n\n    a = moment.utc();\n    a.subtract({years: 1, days: 364});\n    assert.equal(a.toNow(), 'in a year', 'Round down towards the nearest year');\n\n    // Do not round relative time evaluation\n    var retainValue = function (value) {\n        return value.toFixed(3);\n    };\n    moment.relativeTimeRounding(retainValue);\n\n    a = moment.utc();\n    a.subtract({hours: 39});\n    assert.equal(a.toNow(), 'in 1.625 days', 'Round down towards the nearest year');\n\n    // Restore defaults\n    moment.relativeTimeThreshold('s', 45);\n    moment.relativeTimeThreshold('m', 45);\n    moment.relativeTimeThreshold('h', 22);\n    moment.relativeTimeThreshold('d', 26);\n    moment.relativeTimeThreshold('M', 11);\n    moment.relativeTimeRounding(roundingDefault);\n});\n\ntest('retrieve rounding settings', function (assert) {\n    moment.relativeTimeRounding(Math.round);\n    var roundingFunction = moment.relativeTimeRounding();\n\n    assert.equal(roundingFunction, Math.round, 'Can retrieve rounding setting');\n});\n\ntest('retrieve threshold settings', function (assert) {\n    moment.relativeTimeThreshold('m', 45);\n    var minuteThreshold = moment.relativeTimeThreshold('m');\n\n    assert.equal(minuteThreshold, 45, 'Can retrieve minute setting');\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\nfunction module$1 (name, lifecycle) {\n    QUnit.module(name, {\n        setup : function () {\n            moment.locale('en');\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'core');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            teardownDeprecationHandler(test, moment, 'core');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n}\n\nmodule$1('start and end of units');\n\ntest('start of year', function (assert) {\n    var m = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).startOf('year'),\n        ms = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).startOf('years'),\n        ma = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).startOf('y');\n    assert.equal(+m, +ms, 'Plural or singular should work');\n    assert.equal(+m, +ma, 'Full or abbreviated should work');\n    assert.equal(m.year(), 2011, 'keep the year');\n    assert.equal(m.month(), 0, 'strip out the month');\n    assert.equal(m.date(), 1, 'strip out the day');\n    assert.equal(m.hours(), 0, 'strip out the hours');\n    assert.equal(m.minutes(), 0, 'strip out the minutes');\n    assert.equal(m.seconds(), 0, 'strip out the seconds');\n    assert.equal(m.milliseconds(), 0, 'strip out the milliseconds');\n});\n\ntest('end of year', function (assert) {\n    var m = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).endOf('year'),\n        ms = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).endOf('years'),\n        ma = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).endOf('y');\n    assert.equal(+m, +ms, 'Plural or singular should work');\n    assert.equal(+m, +ma, 'Full or abbreviated should work');\n    assert.equal(m.year(), 2011, 'keep the year');\n    assert.equal(m.month(), 11, 'set the month');\n    assert.equal(m.date(), 31, 'set the day');\n    assert.equal(m.hours(), 23, 'set the hours');\n    assert.equal(m.minutes(), 59, 'set the minutes');\n    assert.equal(m.seconds(), 59, 'set the seconds');\n    assert.equal(m.milliseconds(), 999, 'set the seconds');\n});\n\ntest('start of quarter', function (assert) {\n    var m = moment(new Date(2011, 4, 2, 3, 4, 5, 6)).startOf('quarter'),\n        ms = moment(new Date(2011, 4, 2, 3, 4, 5, 6)).startOf('quarters'),\n        ma = moment(new Date(2011, 4, 2, 3, 4, 5, 6)).startOf('Q');\n    assert.equal(+m, +ms, 'Plural or singular should work');\n    assert.equal(+m, +ma, 'Full or abbreviated should work');\n    assert.equal(m.year(), 2011, 'keep the year');\n    assert.equal(m.quarter(), 2, 'keep the quarter');\n    assert.equal(m.month(), 3, 'strip out the month');\n    assert.equal(m.date(), 1, 'strip out the day');\n    assert.equal(m.hours(), 0, 'strip out the hours');\n    assert.equal(m.minutes(), 0, 'strip out the minutes');\n    assert.equal(m.seconds(), 0, 'strip out the seconds');\n    assert.equal(m.milliseconds(), 0, 'strip out the milliseconds');\n});\n\ntest('end of quarter', function (assert) {\n    var m = moment(new Date(2011, 4, 2, 3, 4, 5, 6)).endOf('quarter'),\n        ms = moment(new Date(2011, 4, 2, 3, 4, 5, 6)).endOf('quarters'),\n        ma = moment(new Date(2011, 4, 2, 3, 4, 5, 6)).endOf('Q');\n    assert.equal(+m, +ms, 'Plural or singular should work');\n    assert.equal(+m, +ma, 'Full or abbreviated should work');\n    assert.equal(m.year(), 2011, 'keep the year');\n    assert.equal(m.quarter(), 2, 'keep the quarter');\n    assert.equal(m.month(), 5, 'set the month');\n    assert.equal(m.date(), 30, 'set the day');\n    assert.equal(m.hours(), 23, 'set the hours');\n    assert.equal(m.minutes(), 59, 'set the minutes');\n    assert.equal(m.seconds(), 59, 'set the seconds');\n    assert.equal(m.milliseconds(), 999, 'set the seconds');\n});\n\ntest('start of month', function (assert) {\n    var m = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).startOf('month'),\n        ms = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).startOf('months'),\n        ma = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).startOf('M');\n    assert.equal(+m, +ms, 'Plural or singular should work');\n    assert.equal(+m, +ma, 'Full or abbreviated should work');\n    assert.equal(m.year(), 2011, 'keep the year');\n    assert.equal(m.month(), 1, 'keep the month');\n    assert.equal(m.date(), 1, 'strip out the day');\n    assert.equal(m.hours(), 0, 'strip out the hours');\n    assert.equal(m.minutes(), 0, 'strip out the minutes');\n    assert.equal(m.seconds(), 0, 'strip out the seconds');\n    assert.equal(m.milliseconds(), 0, 'strip out the milliseconds');\n});\n\ntest('end of month', function (assert) {\n    var m = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).endOf('month'),\n        ms = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).endOf('months'),\n        ma = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).endOf('M');\n    assert.equal(+m, +ms, 'Plural or singular should work');\n    assert.equal(+m, +ma, 'Full or abbreviated should work');\n    assert.equal(m.year(), 2011, 'keep the year');\n    assert.equal(m.month(), 1, 'keep the month');\n    assert.equal(m.date(), 28, 'set the day');\n    assert.equal(m.hours(), 23, 'set the hours');\n    assert.equal(m.minutes(), 59, 'set the minutes');\n    assert.equal(m.seconds(), 59, 'set the seconds');\n    assert.equal(m.milliseconds(), 999, 'set the seconds');\n});\n\ntest('start of week', function (assert) {\n    var m = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).startOf('week'),\n        ms = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).startOf('weeks'),\n        ma = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).startOf('w');\n    assert.equal(+m, +ms, 'Plural or singular should work');\n    assert.equal(+m, +ma, 'Full or abbreviated should work');\n    assert.equal(m.year(), 2011, 'keep the year');\n    assert.equal(m.month(), 0, 'rolls back to January');\n    assert.equal(m.day(), 0, 'set day of week');\n    assert.equal(m.date(), 30, 'set correct date');\n    assert.equal(m.hours(), 0, 'strip out the hours');\n    assert.equal(m.minutes(), 0, 'strip out the minutes');\n    assert.equal(m.seconds(), 0, 'strip out the seconds');\n    assert.equal(m.milliseconds(), 0, 'strip out the milliseconds');\n});\n\ntest('end of week', function (assert) {\n    var m = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).endOf('week'),\n        ms = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).endOf('weeks'),\n        ma = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).endOf('weeks');\n    assert.equal(+m, +ms, 'Plural or singular should work');\n    assert.equal(+m, +ma, 'Full or abbreviated should work');\n    assert.equal(m.year(), 2011, 'keep the year');\n    assert.equal(m.month(), 1, 'keep the month');\n    assert.equal(m.day(), 6, 'set the day of the week');\n    assert.equal(m.date(), 5, 'set the day');\n    assert.equal(m.hours(), 23, 'set the hours');\n    assert.equal(m.minutes(), 59, 'set the minutes');\n    assert.equal(m.seconds(), 59, 'set the seconds');\n    assert.equal(m.milliseconds(), 999, 'set the seconds');\n});\n\ntest('start of iso-week', function (assert) {\n    var m = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).startOf('isoWeek'),\n        ms = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).startOf('isoWeeks'),\n        ma = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).startOf('W');\n    assert.equal(+m, +ms, 'Plural or singular should work');\n    assert.equal(+m, +ma, 'Full or abbreviated should work');\n    assert.equal(m.year(), 2011, 'keep the year');\n    assert.equal(m.month(), 0, 'rollback to January');\n    assert.equal(m.isoWeekday(), 1, 'set day of iso-week');\n    assert.equal(m.date(), 31, 'set correct date');\n    assert.equal(m.hours(), 0, 'strip out the hours');\n    assert.equal(m.minutes(), 0, 'strip out the minutes');\n    assert.equal(m.seconds(), 0, 'strip out the seconds');\n    assert.equal(m.milliseconds(), 0, 'strip out the milliseconds');\n});\n\ntest('end of iso-week', function (assert) {\n    var m = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).endOf('isoWeek'),\n        ms = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).endOf('isoWeeks'),\n        ma = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).endOf('W');\n    assert.equal(+m, +ms, 'Plural or singular should work');\n    assert.equal(+m, +ma, 'Full or abbreviated should work');\n    assert.equal(m.year(), 2011, 'keep the year');\n    assert.equal(m.month(), 1, 'keep the month');\n    assert.equal(m.isoWeekday(), 7, 'set the day of the week');\n    assert.equal(m.date(), 6, 'set the day');\n    assert.equal(m.hours(), 23, 'set the hours');\n    assert.equal(m.minutes(), 59, 'set the minutes');\n    assert.equal(m.seconds(), 59, 'set the seconds');\n    assert.equal(m.milliseconds(), 999, 'set the seconds');\n});\n\ntest('start of day', function (assert) {\n    var m = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).startOf('day'),\n        ms = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).startOf('days'),\n        ma = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).startOf('d');\n    assert.equal(+m, +ms, 'Plural or singular should work');\n    assert.equal(+m, +ma, 'Full or abbreviated should work');\n    assert.equal(m.year(), 2011, 'keep the year');\n    assert.equal(m.month(), 1, 'keep the month');\n    assert.equal(m.date(), 2, 'keep the day');\n    assert.equal(m.hours(), 0, 'strip out the hours');\n    assert.equal(m.minutes(), 0, 'strip out the minutes');\n    assert.equal(m.seconds(), 0, 'strip out the seconds');\n    assert.equal(m.milliseconds(), 0, 'strip out the milliseconds');\n});\n\ntest('end of day', function (assert) {\n    var m = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).endOf('day'),\n        ms = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).endOf('days'),\n        ma = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).endOf('d');\n    assert.equal(+m, +ms, 'Plural or singular should work');\n    assert.equal(+m, +ma, 'Full or abbreviated should work');\n    assert.equal(m.year(), 2011, 'keep the year');\n    assert.equal(m.month(), 1, 'keep the month');\n    assert.equal(m.date(), 2, 'keep the day');\n    assert.equal(m.hours(), 23, 'set the hours');\n    assert.equal(m.minutes(), 59, 'set the minutes');\n    assert.equal(m.seconds(), 59, 'set the seconds');\n    assert.equal(m.milliseconds(), 999, 'set the seconds');\n});\n\ntest('start of date', function (assert) {\n    var m = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).startOf('date'),\n        ms = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).startOf('dates');\n\n    assert.equal(+m, +ms, 'Plural or singular should work');\n    assert.equal(m.year(), 2011, 'keep the year');\n    assert.equal(m.month(), 1, 'keep the month');\n    assert.equal(m.date(), 2, 'keep the day');\n    assert.equal(m.hours(), 0, 'strip out the hours');\n    assert.equal(m.minutes(), 0, 'strip out the minutes');\n    assert.equal(m.seconds(), 0, 'strip out the seconds');\n    assert.equal(m.milliseconds(), 0, 'strip out the milliseconds');\n});\n\ntest('end of date', function (assert) {\n    var m = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).endOf('date'),\n        ms = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).endOf('dates');\n\n    assert.equal(+m, +ms, 'Plural or singular should work');\n    assert.equal(m.year(), 2011, 'keep the year');\n    assert.equal(m.month(), 1, 'keep the month');\n    assert.equal(m.date(), 2, 'keep the day');\n    assert.equal(m.hours(), 23, 'set the hours');\n    assert.equal(m.minutes(), 59, 'set the minutes');\n    assert.equal(m.seconds(), 59, 'set the seconds');\n    assert.equal(m.milliseconds(), 999, 'set the seconds');\n});\n\n\ntest('start of hour', function (assert) {\n    var m = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).startOf('hour'),\n        ms = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).startOf('hours'),\n        ma = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).startOf('h');\n    assert.equal(+m, +ms, 'Plural or singular should work');\n    assert.equal(+m, +ma, 'Full or abbreviated should work');\n    assert.equal(m.year(), 2011, 'keep the year');\n    assert.equal(m.month(), 1, 'keep the month');\n    assert.equal(m.date(), 2, 'keep the day');\n    assert.equal(m.hours(), 3, 'keep the hours');\n    assert.equal(m.minutes(), 0, 'strip out the minutes');\n    assert.equal(m.seconds(), 0, 'strip out the seconds');\n    assert.equal(m.milliseconds(), 0, 'strip out the milliseconds');\n});\n\ntest('end of hour', function (assert) {\n    var m = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).endOf('hour'),\n        ms = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).endOf('hours'),\n        ma = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).endOf('h');\n    assert.equal(+m, +ms, 'Plural or singular should work');\n    assert.equal(+m, +ma, 'Full or abbreviated should work');\n    assert.equal(m.year(), 2011, 'keep the year');\n    assert.equal(m.month(), 1, 'keep the month');\n    assert.equal(m.date(), 2, 'keep the day');\n    assert.equal(m.hours(), 3, 'keep the hours');\n    assert.equal(m.minutes(), 59, 'set the minutes');\n    assert.equal(m.seconds(), 59, 'set the seconds');\n    assert.equal(m.milliseconds(), 999, 'set the seconds');\n});\n\ntest('start of minute', function (assert) {\n    var m = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).startOf('minute'),\n        ms = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).startOf('minutes'),\n        ma = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).startOf('m');\n    assert.equal(+m, +ms, 'Plural or singular should work');\n    assert.equal(+m, +ma, 'Full or abbreviated should work');\n    assert.equal(m.year(), 2011, 'keep the year');\n    assert.equal(m.month(), 1, 'keep the month');\n    assert.equal(m.date(), 2, 'keep the day');\n    assert.equal(m.hours(), 3, 'keep the hours');\n    assert.equal(m.minutes(), 4, 'keep the minutes');\n    assert.equal(m.seconds(), 0, 'strip out the seconds');\n    assert.equal(m.milliseconds(), 0, 'strip out the milliseconds');\n});\n\ntest('end of minute', function (assert) {\n    var m = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).endOf('minute'),\n        ms = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).endOf('minutes'),\n        ma = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).endOf('m');\n    assert.equal(+m, +ms, 'Plural or singular should work');\n    assert.equal(+m, +ma, 'Full or abbreviated should work');\n    assert.equal(m.year(), 2011, 'keep the year');\n    assert.equal(m.month(), 1, 'keep the month');\n    assert.equal(m.date(), 2, 'keep the day');\n    assert.equal(m.hours(), 3, 'keep the hours');\n    assert.equal(m.minutes(), 4, 'keep the minutes');\n    assert.equal(m.seconds(), 59, 'set the seconds');\n    assert.equal(m.milliseconds(), 999, 'set the seconds');\n});\n\ntest('start of second', function (assert) {\n    var m = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).startOf('second'),\n        ms = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).startOf('seconds'),\n        ma = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).startOf('s');\n    assert.equal(+m, +ms, 'Plural or singular should work');\n    assert.equal(+m, +ma, 'Full or abbreviated should work');\n    assert.equal(m.year(), 2011, 'keep the year');\n    assert.equal(m.month(), 1, 'keep the month');\n    assert.equal(m.date(), 2, 'keep the day');\n    assert.equal(m.hours(), 3, 'keep the hours');\n    assert.equal(m.minutes(), 4, 'keep the minutes');\n    assert.equal(m.seconds(), 5, 'keep the the seconds');\n    assert.equal(m.milliseconds(), 0, 'strip out the milliseconds');\n});\n\ntest('end of second', function (assert) {\n    var m = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).endOf('second'),\n        ms = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).endOf('seconds'),\n        ma = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).endOf('s');\n    assert.equal(+m, +ms, 'Plural or singular should work');\n    assert.equal(+m, +ma, 'Full or abbreviated should work');\n    assert.equal(m.year(), 2011, 'keep the year');\n    assert.equal(m.month(), 1, 'keep the month');\n    assert.equal(m.date(), 2, 'keep the day');\n    assert.equal(m.hours(), 3, 'keep the hours');\n    assert.equal(m.minutes(), 4, 'keep the minutes');\n    assert.equal(m.seconds(), 5, 'keep the seconds');\n    assert.equal(m.milliseconds(), 999, 'set the seconds');\n});\n\ntest('startOf across DST +1', function (assert) {\n    var oldUpdateOffset = moment.updateOffset,\n        // Based on a real story somewhere in America/Los_Angeles\n        dstAt = moment('2014-03-09T02:00:00-08:00').parseZone(),\n        m;\n\n    moment.updateOffset = function (mom, keepTime) {\n        if (mom.isBefore(dstAt)) {\n            mom.utcOffset(-8, keepTime);\n        } else {\n            mom.utcOffset(-7, keepTime);\n        }\n    };\n\n    m = moment('2014-03-15T00:00:00-07:00').parseZone();\n    m.startOf('y');\n    assert.equal(m.format(), '2014-01-01T00:00:00-08:00', 'startOf(\\'year\\') across +1');\n\n    m = moment('2014-03-15T00:00:00-07:00').parseZone();\n    m.startOf('M');\n    assert.equal(m.format(), '2014-03-01T00:00:00-08:00', 'startOf(\\'month\\') across +1');\n\n    m = moment('2014-03-09T09:00:00-07:00').parseZone();\n    m.startOf('d');\n    assert.equal(m.format(), '2014-03-09T00:00:00-08:00', 'startOf(\\'day\\') across +1');\n\n    m = moment('2014-03-09T03:05:00-07:00').parseZone();\n    m.startOf('h');\n    assert.equal(m.format(), '2014-03-09T03:00:00-07:00', 'startOf(\\'hour\\') after +1');\n\n    m = moment('2014-03-09T01:35:00-08:00').parseZone();\n    m.startOf('h');\n    assert.equal(m.format(), '2014-03-09T01:00:00-08:00', 'startOf(\\'hour\\') before +1');\n\n    // There is no such time as 2:30-7 to try startOf('hour') across that\n\n    moment.updateOffset = oldUpdateOffset;\n});\n\ntest('startOf across DST -1', function (assert) {\n    var oldUpdateOffset = moment.updateOffset,\n        // Based on a real story somewhere in America/Los_Angeles\n        dstAt = moment('2014-11-02T02:00:00-07:00').parseZone(),\n        m;\n\n    moment.updateOffset = function (mom, keepTime) {\n        if (mom.isBefore(dstAt)) {\n            mom.utcOffset(-7, keepTime);\n        } else {\n            mom.utcOffset(-8, keepTime);\n        }\n    };\n\n    m = moment('2014-11-15T00:00:00-08:00').parseZone();\n    m.startOf('y');\n    assert.equal(m.format(), '2014-01-01T00:00:00-07:00', 'startOf(\\'year\\') across -1');\n\n    m = moment('2014-11-15T00:00:00-08:00').parseZone();\n    m.startOf('M');\n    assert.equal(m.format(), '2014-11-01T00:00:00-07:00', 'startOf(\\'month\\') across -1');\n\n    m = moment('2014-11-02T09:00:00-08:00').parseZone();\n    m.startOf('d');\n    assert.equal(m.format(), '2014-11-02T00:00:00-07:00', 'startOf(\\'day\\') across -1');\n\n    // note that utc offset is -8\n    m = moment('2014-11-02T01:30:00-08:00').parseZone();\n    m.startOf('h');\n    assert.equal(m.format(), '2014-11-02T01:00:00-08:00', 'startOf(\\'hour\\') after +1');\n\n    // note that utc offset is -7\n    m = moment('2014-11-02T01:30:00-07:00').parseZone();\n    m.startOf('h');\n    assert.equal(m.format(), '2014-11-02T01:00:00-07:00', 'startOf(\\'hour\\') before +1');\n\n    moment.updateOffset = oldUpdateOffset;\n});\n\ntest('endOf millisecond and no-arg', function (assert) {\n    var m = moment();\n    assert.equal(+m, +m.clone().endOf(), 'endOf without argument should change time');\n    assert.equal(+m, +m.clone().endOf('ms'), 'endOf with ms argument should change time');\n    assert.equal(+m, +m.clone().endOf('millisecond'), 'endOf with millisecond argument should change time');\n    assert.equal(+m, +m.clone().endOf('milliseconds'), 'endOf with milliseconds argument should change time');\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\nfunction module$1 (name, lifecycle) {\n    QUnit.module(name, {\n        setup : function () {\n            moment.locale('en');\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'core');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            teardownDeprecationHandler(test, moment, 'core');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n}\n\nmodule$1('string prototype');\n\ntest('string prototype overrides call', function (assert) {\n    var prior = String.prototype.call, b;\n    String.prototype.call = function () {\n        return null;\n    };\n\n    b = moment(new Date(2011, 7, 28, 15, 25, 50, 125));\n    assert.equal(b.format('MMMM Do YYYY, h:mm a'), 'August 28th 2011, 3:25 pm');\n\n    String.prototype.call = prior;\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\nfunction module$1 (name, lifecycle) {\n    QUnit.module(name, {\n        setup : function () {\n            moment.locale('en');\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'core');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            teardownDeprecationHandler(test, moment, 'core');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n}\n\nmodule$1('to type');\n\ntest('toObject', function (assert) {\n    var expected = {\n        years:2010,\n        months:3,\n        date:5,\n        hours:15,\n        minutes:10,\n        seconds:3,\n        milliseconds:123\n    };\n    assert.deepEqual(moment(expected).toObject(), expected, 'toObject invalid');\n});\n\ntest('toArray', function (assert) {\n    var expected = [2014, 11, 26, 11, 46, 58, 17];\n    assert.deepEqual(moment(expected).toArray(), expected, 'toArray invalid');\n});\n\ntest('toDate returns a copy of the internal date', function (assert) {\n    var m = moment();\n    var d = m.toDate();\n    m.year(0);\n    assert.notEqual(d, m.toDate());\n});\n\ntest('toJSON', function (assert) {\n    if (Date.prototype.toISOString) {\n        var expected = new Date().toISOString();\n        assert.deepEqual(moment(expected).toJSON(), expected, 'toJSON invalid');\n    } else {\n        // IE8\n        expect(0);\n    }\n});\n\ntest('toJSON works when moment is frozen', function (assert) {\n    if (Date.prototype.toISOString) {\n        var expected = new Date().toISOString();\n        var m = moment(expected);\n        if (Object.freeze != null) {\n            Object.freeze(m);\n        }\n        assert.deepEqual(m.toJSON(), expected, 'toJSON when frozen invalid');\n    } else {\n        // IE8\n        expect(0);\n    }\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\nfunction module$1 (name, lifecycle) {\n    QUnit.module(name, {\n        setup : function () {\n            moment.locale('en');\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'core');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            teardownDeprecationHandler(test, moment, 'core');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n}\n\nmodule$1('utc');\n\ntest('utc and local', function (assert) {\n    var m = moment(Date.UTC(2011, 1, 2, 3, 4, 5, 6)), offset, expected;\n    m.utc();\n    // utc\n    assert.equal(m.date(), 2, 'the day should be correct for utc');\n    assert.equal(m.day(), 3, 'the date should be correct for utc');\n    assert.equal(m.hours(), 3, 'the hours should be correct for utc');\n\n    // local\n    m.local();\n    if (m.utcOffset() < -180) {\n        assert.equal(m.date(), 1, 'the date should be correct for local');\n        assert.equal(m.day(), 2, 'the day should be correct for local');\n    } else {\n        assert.equal(m.date(), 2, 'the date should be correct for local');\n        assert.equal(m.day(), 3, 'the day should be correct for local');\n    }\n    offset = Math.floor(m.utcOffset() / 60);\n    expected = (24 + 3 + offset) % 24;\n    assert.equal(m.hours(), expected, 'the hours (' + m.hours() + ') should be correct for local');\n    assert.equal(moment().utc().utcOffset(), 0, 'timezone in utc should always be zero');\n});\n\ntest('creating with utc and no arguments', function (assert) {\n    var startOfTest = new Date().valueOf(),\n        momentDefaultUtcTime = moment.utc().valueOf(),\n        afterMomentCreationTime = new Date().valueOf();\n\n    assert.ok(startOfTest <= momentDefaultUtcTime, 'moment UTC default time should be now, not in the past');\n    assert.ok(momentDefaultUtcTime <= afterMomentCreationTime, 'moment UTC default time should be now, not in the future');\n});\n\ntest('creating with utc and a date parameter array', function (assert) {\n    var m = moment.utc([2011, 1, 2, 3, 4, 5, 6]);\n    assert.equal(m.date(), 2, 'the day should be correct for utc array');\n    assert.equal(m.hours(), 3, 'the hours should be correct for utc array');\n\n    m = moment.utc('2011-02-02 3:04:05', 'YYYY-MM-DD HH:mm:ss');\n    assert.equal(m.date(), 2, 'the day should be correct for utc parsing format');\n    assert.equal(m.hours(), 3, 'the hours should be correct for utc parsing format');\n\n    m = moment.utc('2011-02-02T03:04:05+00:00');\n    assert.equal(m.date(), 2, 'the day should be correct for utc parsing iso');\n    assert.equal(m.hours(), 3, 'the hours should be correct for utc parsing iso');\n});\n\ntest('creating with utc without timezone', function (assert) {\n    var m = moment.utc('2012-01-02T08:20:00');\n    assert.equal(m.date(), 2, 'the day should be correct for utc parse without timezone');\n    assert.equal(m.hours(), 8, 'the hours should be correct for utc parse without timezone');\n\n    m = moment.utc('2012-01-02T08:20:00+09:00');\n    assert.equal(m.date(), 1, 'the day should be correct for utc parse with timezone');\n    assert.equal(m.hours(), 23, 'the hours should be correct for utc parse with timezone');\n});\n\ntest('cloning with utc offset', function (assert) {\n    var m = moment.utc('2012-01-02T08:20:00');\n    assert.equal(moment.utc(m)._isUTC, true, 'the local offset should be converted to UTC');\n    assert.equal(moment.utc(m.clone().utc())._isUTC, true, 'the local offset should stay in UTC');\n\n    m.utcOffset(120);\n    assert.equal(moment.utc(m)._isUTC, true, 'the explicit utc offset should stay in UTC');\n    assert.equal(moment.utc(m).utcOffset(), 0, 'the explicit utc offset should have an offset of 0');\n});\n\ntest('weekday with utc', function (assert) {\n    assert.equal(\n        moment('2013-09-15T00:00:00Z').utc().weekday(), // first minute of the day\n        moment('2013-09-15T23:59:00Z').utc().weekday(), // last minute of the day\n        'a UTC-moment\\'s .weekday() should not be affected by the local timezone'\n    );\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\nfunction module$1 (name, lifecycle) {\n    QUnit.module(name, {\n        setup : function () {\n            moment.locale('en');\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'core');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            teardownDeprecationHandler(test, moment, 'core');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n}\n\nmodule$1('utc offset');\n\ntest('setter / getter blackbox', function (assert) {\n    var m = moment([2010]);\n\n    assert.equal(m.clone().utcOffset(0).utcOffset(), 0, 'utcOffset 0');\n\n    assert.equal(m.clone().utcOffset(1).utcOffset(), 60, 'utcOffset 1 is 60');\n    assert.equal(m.clone().utcOffset(60).utcOffset(), 60, 'utcOffset 60');\n    assert.equal(m.clone().utcOffset('+01:00').utcOffset(), 60, 'utcOffset +01:00 is 60');\n    assert.equal(m.clone().utcOffset('+0100').utcOffset(), 60, 'utcOffset +0100 is 60');\n\n    assert.equal(m.clone().utcOffset(-1).utcOffset(), -60, 'utcOffset -1 is -60');\n    assert.equal(m.clone().utcOffset(-60).utcOffset(), -60, 'utcOffset -60');\n    assert.equal(m.clone().utcOffset('-01:00').utcOffset(), -60, 'utcOffset -01:00 is -60');\n    assert.equal(m.clone().utcOffset('-0100').utcOffset(), -60, 'utcOffset -0100 is -60');\n\n    assert.equal(m.clone().utcOffset(1.5).utcOffset(), 90, 'utcOffset 1.5 is 90');\n    assert.equal(m.clone().utcOffset(90).utcOffset(), 90, 'utcOffset 1.5 is 90');\n    assert.equal(m.clone().utcOffset('+01:30').utcOffset(), 90, 'utcOffset +01:30 is 90');\n    assert.equal(m.clone().utcOffset('+0130').utcOffset(), 90, 'utcOffset +0130 is 90');\n\n    assert.equal(m.clone().utcOffset(-1.5).utcOffset(), -90, 'utcOffset -1.5');\n    assert.equal(m.clone().utcOffset(-90).utcOffset(), -90, 'utcOffset -90');\n    assert.equal(m.clone().utcOffset('-01:30').utcOffset(), -90, 'utcOffset +01:30 is 90');\n    assert.equal(m.clone().utcOffset('-0130').utcOffset(), -90, 'utcOffset +0130 is 90');\n    assert.equal(m.clone().utcOffset('+00:10').utcOffset(), 10, 'utcOffset +00:10 is 10');\n    assert.equal(m.clone().utcOffset('-00:10').utcOffset(), -10, 'utcOffset +00:10 is 10');\n    assert.equal(m.clone().utcOffset('+0010').utcOffset(), 10, 'utcOffset +0010 is 10');\n    assert.equal(m.clone().utcOffset('-0010').utcOffset(), -10, 'utcOffset +0010 is 10');\n});\n\ntest('utcOffset shorthand hours -> minutes', function (assert) {\n    var i;\n    for (i = -15; i <= 15; ++i) {\n        assert.equal(moment().utcOffset(i).utcOffset(), i * 60,\n                '' + i + ' -> ' + i * 60);\n    }\n    assert.equal(moment().utcOffset(-16).utcOffset(), -16, '-16 -> -16');\n    assert.equal(moment().utcOffset(16).utcOffset(), 16, '16 -> 16');\n});\n\ntest('isLocal, isUtc, isUtcOffset', function (assert) {\n    assert.ok(moment().isLocal(), 'moment() creates objects in local time');\n    assert.ok(!moment.utc().isLocal(), 'moment.utc creates objects NOT in local time');\n    assert.ok(moment.utc().local().isLocal(), 'moment.fn.local() converts to local time');\n    assert.ok(!moment().utcOffset(5).isLocal(), 'moment.fn.utcOffset(N) puts objects NOT in local time');\n    assert.ok(moment().utcOffset(5).local().isLocal(), 'moment.fn.local() converts to local time');\n\n    assert.ok(moment.utc().isUtc(), 'moment.utc() creates objects in utc time');\n    assert.ok(moment().utcOffset(0).isUtc(), 'utcOffset(0) is equivalent to utc mode');\n    assert.ok(!moment().utcOffset(1).isUtc(), 'utcOffset(1) is NOT equivalent to utc mode');\n\n    assert.ok(!moment().isUtcOffset(), 'moment() creates objects NOT in utc-offset mode');\n    assert.ok(moment.utc().isUtcOffset(), 'moment.utc() creates objects in utc-offset mode');\n    assert.ok(moment().utcOffset(3).isUtcOffset(), 'utcOffset(N != 0) creates objects in utc-offset mode');\n    assert.ok(moment().utcOffset(0).isUtcOffset(), 'utcOffset(0) creates objects in utc-offset mode');\n});\n\ntest('isUTC', function (assert) {\n    assert.ok(moment.utc().isUTC(), 'moment.utc() creates objects in utc time');\n    assert.ok(moment().utcOffset(0).isUTC(), 'utcOffset(0) is equivalent to utc mode');\n    assert.ok(!moment().utcOffset(1).isUTC(), 'utcOffset(1) is NOT equivalent to utc mode');\n});\n\ntest('change hours when changing the utc offset', function (assert) {\n    var m = moment.utc([2000, 0, 1, 6]);\n    assert.equal(m.hour(), 6, 'UTC 6AM should be 6AM at +0000');\n\n    // sanity check\n    m.utcOffset(0);\n    assert.equal(m.hour(), 6, 'UTC 6AM should be 6AM at +0000');\n\n    m.utcOffset(-60);\n    assert.equal(m.hour(), 5, 'UTC 6AM should be 5AM at -0100');\n\n    m.utcOffset(60);\n    assert.equal(m.hour(), 7, 'UTC 6AM should be 7AM at +0100');\n});\n\ntest('change minutes when changing the utc offset', function (assert) {\n    var m = moment.utc([2000, 0, 1, 6, 31]);\n\n    m.utcOffset(0);\n    assert.equal(m.format('HH:mm'), '06:31', 'UTC 6:31AM should be 6:31AM at +0000');\n\n    m.utcOffset(-30);\n    assert.equal(m.format('HH:mm'), '06:01', 'UTC 6:31AM should be 6:01AM at -0030');\n\n    m.utcOffset(30);\n    assert.equal(m.format('HH:mm'), '07:01', 'UTC 6:31AM should be 7:01AM at +0030');\n\n    m.utcOffset(-1380);\n    assert.equal(m.format('HH:mm'), '07:31', 'UTC 6:31AM should be 7:31AM at +1380');\n});\n\ntest('distance from the unix epoch', function (assert) {\n    var zoneA = moment(),\n        zoneB = moment(zoneA),\n        zoneC = moment(zoneA),\n        zoneD = moment(zoneA),\n        zoneE = moment(zoneA);\n\n    zoneB.utc();\n    assert.equal(+zoneA, +zoneB, 'moment should equal moment.utc');\n\n    zoneC.utcOffset(60);\n    assert.equal(+zoneA, +zoneC, 'moment should equal moment.utcOffset(60)');\n\n    zoneD.utcOffset(-480);\n    assert.equal(+zoneA, +zoneD,\n            'moment should equal moment.utcOffset(-480)');\n\n    zoneE.utcOffset(-1000);\n    assert.equal(+zoneA, +zoneE,\n            'moment should equal moment.utcOffset(-1000)');\n});\n\ntest('update offset after changing any values', function (assert) {\n    var oldOffset = moment.updateOffset,\n        m = moment.utc([2000, 6, 1]);\n\n    moment.updateOffset = function (mom, keepTime) {\n        if (mom.__doChange) {\n            if (+mom > 962409600000) {\n                mom.utcOffset(-120, keepTime);\n            } else {\n                mom.utcOffset(-60, keepTime);\n            }\n        }\n    };\n\n    assert.equal(m.format('ZZ'), '+0000', 'should be at +0000');\n    assert.equal(m.format('HH:mm'), '00:00', 'should start 12AM at +0000 timezone');\n\n    m.__doChange = true;\n    m.add(1, 'h');\n\n    assert.equal(m.format('ZZ'), '-0200', 'should be at -0200');\n    assert.equal(m.format('HH:mm'), '23:00', '1AM at +0000 should be 11PM at -0200 timezone');\n\n    m.subtract(1, 'h');\n\n    assert.equal(m.format('ZZ'), '-0100', 'should be at -0100');\n    assert.equal(m.format('HH:mm'), '23:00', '12AM at +0000 should be 11PM at -0100 timezone');\n\n    moment.updateOffset = oldOffset;\n});\n\n//////////////////\ntest('getters and setters', function (assert) {\n    var a = moment([2011, 5, 20]);\n\n    assert.equal(a.clone().utcOffset(-120).year(2012).year(), 2012, 'should get and set year correctly');\n    assert.equal(a.clone().utcOffset(-120).month(1).month(), 1, 'should get and set month correctly');\n    assert.equal(a.clone().utcOffset(-120).date(2).date(), 2, 'should get and set date correctly');\n    assert.equal(a.clone().utcOffset(-120).day(1).day(), 1, 'should get and set day correctly');\n    assert.equal(a.clone().utcOffset(-120).hour(1).hour(), 1, 'should get and set hour correctly');\n    assert.equal(a.clone().utcOffset(-120).minute(1).minute(), 1, 'should get and set minute correctly');\n});\n\ntest('getters', function (assert) {\n    var a = moment.utc([2012, 0, 1, 0, 0, 0]);\n\n    assert.equal(a.clone().utcOffset(-120).year(),  2011, 'should get year correctly');\n    assert.equal(a.clone().utcOffset(-120).month(),   11, 'should get month correctly');\n    assert.equal(a.clone().utcOffset(-120).date(),    31, 'should get date correctly');\n    assert.equal(a.clone().utcOffset(-120).hour(),    22, 'should get hour correctly');\n    assert.equal(a.clone().utcOffset(-120).minute(),   0, 'should get minute correctly');\n\n    assert.equal(a.clone().utcOffset(120).year(),  2012, 'should get year correctly');\n    assert.equal(a.clone().utcOffset(120).month(),    0, 'should get month correctly');\n    assert.equal(a.clone().utcOffset(120).date(),     1, 'should get date correctly');\n    assert.equal(a.clone().utcOffset(120).hour(),     2, 'should get hour correctly');\n    assert.equal(a.clone().utcOffset(120).minute(),   0, 'should get minute correctly');\n\n    assert.equal(a.clone().utcOffset(90).year(),  2012, 'should get year correctly');\n    assert.equal(a.clone().utcOffset(90).month(),    0, 'should get month correctly');\n    assert.equal(a.clone().utcOffset(90).date(),     1, 'should get date correctly');\n    assert.equal(a.clone().utcOffset(90).hour(),     1, 'should get hour correctly');\n    assert.equal(a.clone().utcOffset(90).minute(),  30, 'should get minute correctly');\n});\n\ntest('from', function (assert) {\n    var zoneA = moment(),\n        zoneB = moment(zoneA).utcOffset(-720),\n        zoneC = moment(zoneA).utcOffset(-360),\n        zoneD = moment(zoneA).utcOffset(690),\n        other = moment(zoneA).add(35, 'm');\n\n    assert.equal(zoneA.from(other), zoneB.from(other), 'moment#from should be the same in all zones');\n    assert.equal(zoneA.from(other), zoneC.from(other), 'moment#from should be the same in all zones');\n    assert.equal(zoneA.from(other), zoneD.from(other), 'moment#from should be the same in all zones');\n});\n\ntest('diff', function (assert) {\n    var zoneA = moment(),\n        zoneB = moment(zoneA).utcOffset(-720),\n        zoneC = moment(zoneA).utcOffset(-360),\n        zoneD = moment(zoneA).utcOffset(690),\n        other = moment(zoneA).add(35, 'm');\n\n    assert.equal(zoneA.diff(other), zoneB.diff(other), 'moment#diff should be the same in all zones');\n    assert.equal(zoneA.diff(other), zoneC.diff(other), 'moment#diff should be the same in all zones');\n    assert.equal(zoneA.diff(other), zoneD.diff(other), 'moment#diff should be the same in all zones');\n\n    assert.equal(zoneA.diff(other, 'minute', true), zoneB.diff(other, 'minute', true), 'moment#diff should be the same in all zones');\n    assert.equal(zoneA.diff(other, 'minute', true), zoneC.diff(other, 'minute', true), 'moment#diff should be the same in all zones');\n    assert.equal(zoneA.diff(other, 'minute', true), zoneD.diff(other, 'minute', true), 'moment#diff should be the same in all zones');\n\n    assert.equal(zoneA.diff(other, 'hour', true), zoneB.diff(other, 'hour', true), 'moment#diff should be the same in all zones');\n    assert.equal(zoneA.diff(other, 'hour', true), zoneC.diff(other, 'hour', true), 'moment#diff should be the same in all zones');\n    assert.equal(zoneA.diff(other, 'hour', true), zoneD.diff(other, 'hour', true), 'moment#diff should be the same in all zones');\n});\n\ntest('unix offset and timestamp', function (assert) {\n    var zoneA = moment(),\n        zoneB = moment(zoneA).utcOffset(-720),\n        zoneC = moment(zoneA).utcOffset(-360),\n        zoneD = moment(zoneA).utcOffset(690);\n\n    assert.equal(zoneA.unix(), zoneB.unix(), 'moment#unix should be the same in all zones');\n    assert.equal(zoneA.unix(), zoneC.unix(), 'moment#unix should be the same in all zones');\n    assert.equal(zoneA.unix(), zoneD.unix(), 'moment#unix should be the same in all zones');\n\n    assert.equal(+zoneA, +zoneB, 'moment#valueOf should be the same in all zones');\n    assert.equal(+zoneA, +zoneC, 'moment#valueOf should be the same in all zones');\n    assert.equal(+zoneA, +zoneD, 'moment#valueOf should be the same in all zones');\n});\n\ntest('cloning', function (assert) {\n    assert.equal(moment().utcOffset(-120).clone().utcOffset(), -120,\n            'explicit cloning should retain the offset');\n    assert.equal(moment().utcOffset(120).clone().utcOffset(), 120,\n            'explicit cloning should retain the offset');\n    assert.equal(moment(moment().utcOffset(-120)).utcOffset(), -120,\n            'implicit cloning should retain the offset');\n    assert.equal(moment(moment().utcOffset(120)).utcOffset(), 120,\n            'implicit cloning should retain the offset');\n});\n\ntest('start of / end of', function (assert) {\n    var a = moment.utc([2010, 1, 2, 0, 0, 0]).utcOffset(-450);\n\n    assert.equal(a.clone().startOf('day').hour(), 0,\n            'start of day should work on moments with utc offset');\n    assert.equal(a.clone().startOf('day').minute(), 0,\n            'start of day should work on moments with utc offset');\n    assert.equal(a.clone().startOf('hour').minute(), 0,\n            'start of hour should work on moments with utc offset');\n\n    assert.equal(a.clone().endOf('day').hour(), 23,\n            'end of day should work on moments with utc offset');\n    assert.equal(a.clone().endOf('day').minute(), 59,\n            'end of day should work on moments with utc offset');\n    assert.equal(a.clone().endOf('hour').minute(), 59,\n            'end of hour should work on moments with utc offset');\n});\n\ntest('reset offset with moment#utc', function (assert) {\n    var a = moment.utc([2012]).utcOffset(-480);\n\n    assert.equal(a.clone().hour(),      16, 'different utc offset should have different hour');\n    assert.equal(a.clone().utc().hour(), 0, 'calling moment#utc should reset the offset');\n});\n\ntest('reset offset with moment#local', function (assert) {\n    var a = moment([2012]).utcOffset(-480);\n\n    assert.equal(a.clone().local().hour(), 0, 'calling moment#local should reset the offset');\n});\n\ntest('toDate', function (assert) {\n    var zoneA = new Date(),\n        zoneB = moment(zoneA).utcOffset(-720).toDate(),\n        zoneC = moment(zoneA).utcOffset(-360).toDate(),\n        zoneD = moment(zoneA).utcOffset(690).toDate();\n\n    assert.equal(+zoneA, +zoneB, 'moment#toDate should output a date with the right unix timestamp');\n    assert.equal(+zoneA, +zoneC, 'moment#toDate should output a date with the right unix timestamp');\n    assert.equal(+zoneA, +zoneD, 'moment#toDate should output a date with the right unix timestamp');\n});\n\ntest('same / before / after', function (assert) {\n    var zoneA = moment().utc(),\n        zoneB = moment(zoneA).utcOffset(-120),\n        zoneC = moment(zoneA).utcOffset(120);\n\n    assert.ok(zoneA.isSame(zoneB), 'two moments with different offsets should be the same');\n    assert.ok(zoneA.isSame(zoneC), 'two moments with different offsets should be the same');\n\n    assert.ok(zoneA.isSame(zoneB, 'hour'), 'two moments with different offsets should be the same hour');\n    assert.ok(zoneA.isSame(zoneC, 'hour'), 'two moments with different offsets should be the same hour');\n\n    zoneA.add(1, 'hour');\n\n    assert.ok(zoneA.isAfter(zoneB), 'isAfter should work with two moments with different offsets');\n    assert.ok(zoneA.isAfter(zoneC), 'isAfter should work with two moments with different offsets');\n\n    assert.ok(zoneA.isAfter(zoneB, 'hour'), 'isAfter:hour should work with two moments with different offsets');\n    assert.ok(zoneA.isAfter(zoneC, 'hour'), 'isAfter:hour should work with two moments with different offsets');\n\n    zoneA.subtract(2, 'hour');\n\n    assert.ok(zoneA.isBefore(zoneB), 'isBefore should work with two moments with different offsets');\n    assert.ok(zoneA.isBefore(zoneC), 'isBefore should work with two moments with different offsets');\n\n    assert.ok(zoneA.isBefore(zoneB, 'hour'), 'isBefore:hour should work with two moments with different offsets');\n    assert.ok(zoneA.isBefore(zoneC, 'hour'), 'isBefore:hour should work with two moments with different offsets');\n});\n\ntest('add / subtract over dst', function (assert) {\n    var oldOffset = moment.updateOffset,\n        m = moment.utc([2000, 2, 31, 3]);\n\n    moment.updateOffset = function (mom, keepTime) {\n        if (mom.clone().utc().month() > 2) {\n            mom.utcOffset(60, keepTime);\n        } else {\n            mom.utcOffset(0, keepTime);\n        }\n    };\n\n    assert.equal(m.hour(), 3, 'should start at 00:00');\n\n    m.add(24, 'hour');\n\n    assert.equal(m.hour(), 4, 'adding 24 hours should disregard dst');\n\n    m.subtract(24, 'hour');\n\n    assert.equal(m.hour(), 3, 'subtracting 24 hours should disregard dst');\n\n    m.add(1, 'day');\n\n    assert.equal(m.hour(), 3, 'adding 1 day should have the same hour');\n\n    m.subtract(1, 'day');\n\n    assert.equal(m.hour(), 3, 'subtracting 1 day should have the same hour');\n\n    m.add(1, 'month');\n\n    assert.equal(m.hour(), 3, 'adding 1 month should have the same hour');\n\n    m.subtract(1, 'month');\n\n    assert.equal(m.hour(), 3, 'subtracting 1 month should have the same hour');\n\n    moment.updateOffset = oldOffset;\n});\n\ntest('isDST', function (assert) {\n    var oldOffset = moment.updateOffset;\n\n    moment.updateOffset = function (mom, keepTime) {\n        if (mom.month() > 2 && mom.month() < 9) {\n            mom.utcOffset(60, keepTime);\n        } else {\n            mom.utcOffset(0, keepTime);\n        }\n    };\n\n    assert.ok(!moment().month(0).isDST(),  'Jan should not be summer dst');\n    assert.ok(moment().month(6).isDST(),   'Jul should be summer dst');\n    assert.ok(!moment().month(11).isDST(), 'Dec should not be summer dst');\n\n    moment.updateOffset = function (mom) {\n        if (mom.month() > 2 && mom.month() < 9) {\n            mom.utcOffset(0);\n        } else {\n            mom.utcOffset(60);\n        }\n    };\n\n    assert.ok(moment().month(0).isDST(),  'Jan should be winter dst');\n    assert.ok(!moment().month(6).isDST(), 'Jul should not be winter dst');\n    assert.ok(moment().month(11).isDST(), 'Dec should be winter dst');\n\n    moment.updateOffset = oldOffset;\n});\n\ntest('zone names', function (assert) {\n    assert.equal(moment().zoneAbbr(),   '', 'Local zone abbr should be empty');\n    assert.equal(moment().format('z'),  '', 'Local zone formatted abbr should be empty');\n    assert.equal(moment().zoneName(),   '', 'Local zone name should be empty');\n    assert.equal(moment().format('zz'), '', 'Local zone formatted name should be empty');\n\n    assert.equal(moment.utc().zoneAbbr(),   'UTC', 'UTC zone abbr should be UTC');\n    assert.equal(moment.utc().format('z'),  'UTC', 'UTC zone formatted abbr should be UTC');\n    assert.equal(moment.utc().zoneName(),   'Coordinated Universal Time', 'UTC zone abbr should be Coordinated Universal Time');\n    assert.equal(moment.utc().format('zz'), 'Coordinated Universal Time', 'UTC zone formatted abbr should be Coordinated Universal Time');\n});\n\ntest('hours alignment with UTC', function (assert) {\n    assert.equal(moment().utcOffset(-120).hasAlignedHourOffset(), true);\n    assert.equal(moment().utcOffset(180).hasAlignedHourOffset(), true);\n    assert.equal(moment().utcOffset(-90).hasAlignedHourOffset(), false);\n    assert.equal(moment().utcOffset(90).hasAlignedHourOffset(), false);\n});\n\ntest('hours alignment with other zone', function (assert) {\n    var m = moment().utcOffset(-120);\n\n    assert.equal(m.hasAlignedHourOffset(moment().utcOffset(-180)), true);\n    assert.equal(m.hasAlignedHourOffset(moment().utcOffset(180)), true);\n    assert.equal(m.hasAlignedHourOffset(moment().utcOffset(-90)), false);\n    assert.equal(m.hasAlignedHourOffset(moment().utcOffset(90)), false);\n\n    m = moment().utcOffset(-90);\n\n    assert.equal(m.hasAlignedHourOffset(moment().utcOffset(-180)), false);\n    assert.equal(m.hasAlignedHourOffset(moment().utcOffset(180)), false);\n    assert.equal(m.hasAlignedHourOffset(moment().utcOffset(-30)), true);\n    assert.equal(m.hasAlignedHourOffset(moment().utcOffset(30)), true);\n\n    m = moment().utcOffset(60);\n\n    assert.equal(m.hasAlignedHourOffset(moment().utcOffset(-180)), true);\n    assert.equal(m.hasAlignedHourOffset(moment().utcOffset(180)), true);\n    assert.equal(m.hasAlignedHourOffset(moment().utcOffset(-90)), false);\n    assert.equal(m.hasAlignedHourOffset(moment().utcOffset(90)), false);\n\n    m = moment().utcOffset(-25);\n\n    assert.equal(m.hasAlignedHourOffset(moment().utcOffset(35)), true);\n    assert.equal(m.hasAlignedHourOffset(moment().utcOffset(-85)), true);\n\n    assert.equal(m.hasAlignedHourOffset(moment().utcOffset(-35)), false);\n    assert.equal(m.hasAlignedHourOffset(moment().utcOffset(85)), false);\n});\n\ntest('parse zone', function (assert) {\n    var m = moment('2013-01-01T00:00:00-13:00').parseZone();\n    assert.equal(m.utcOffset(), -13 * 60);\n    assert.equal(m.hours(), 0);\n});\n\ntest('parse UTC zone', function (assert) {\n    var m = moment('2013-01-01T05:00:00+00:00').parseZone();\n    assert.equal(m.utcOffset(), 0);\n    assert.equal(m.hours(), 5);\n});\n\ntest('parse zone static', function (assert) {\n    var m = moment.parseZone('2013-01-01T00:00:00-13:00');\n    assert.equal(m.utcOffset(), -13 * 60);\n    assert.equal(m.hours(), 0);\n});\n\ntest('parse zone with more arguments', function (assert) {\n    var m;\n    m = moment.parseZone('2013 01 01 05 -13:00', 'YYYY MM DD HH ZZ');\n    assert.equal(m.format(), '2013-01-01T05:00:00-13:00', 'accept input and format');\n    m = moment.parseZone('2013-01-01-13:00', 'YYYY MM DD ZZ', true);\n    assert.equal(m.isValid(), false, 'accept input, format and strict flag');\n    m = moment.parseZone('2013-01-01-13:00', ['DD MM YYYY ZZ', 'YYYY MM DD ZZ']);\n    assert.equal(m.format(), '2013-01-01T00:00:00-13:00', 'accept input and array of formats');\n});\n\ntest('parse zone with a timezone from the format string', function (assert) {\n    var m = moment('11-12-2013 -0400 +1100', 'DD-MM-YYYY ZZ #####').parseZone();\n\n    assert.equal(m.utcOffset(), -4 * 60);\n});\n\ntest('parse zone without a timezone included in the format string', function (assert) {\n    var m = moment('11-12-2013 -0400 +1100', 'DD-MM-YYYY').parseZone();\n\n    assert.equal(m.utcOffset(), 11 * 60);\n});\n\ntest('timezone format', function (assert) {\n    assert.equal(moment().utcOffset(60).format('ZZ'), '+0100', '-60 -> +0100');\n    assert.equal(moment().utcOffset(90).format('ZZ'), '+0130', '-90 -> +0130');\n    assert.equal(moment().utcOffset(120).format('ZZ'), '+0200', '-120 -> +0200');\n\n    assert.equal(moment().utcOffset(-60).format('ZZ'), '-0100', '+60 -> -0100');\n    assert.equal(moment().utcOffset(-90).format('ZZ'), '-0130', '+90 -> -0130');\n    assert.equal(moment().utcOffset(-120).format('ZZ'), '-0200', '+120 -> -0200');\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\nfunction module$1 (name, lifecycle) {\n    QUnit.module(name, {\n        setup : function () {\n            moment.locale('en');\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'core');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            teardownDeprecationHandler(test, moment, 'core');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n}\n\nmodule$1('week year');\n\ntest('iso week year', function (assert) {\n    // Some examples taken from https://en.wikipedia.org/wiki/ISO_week\n    assert.equal(moment([2005, 0, 1]).isoWeekYear(), 2004);\n    assert.equal(moment([2005, 0, 2]).isoWeekYear(), 2004);\n    assert.equal(moment([2005, 0, 3]).isoWeekYear(), 2005);\n    assert.equal(moment([2005, 11, 31]).isoWeekYear(), 2005);\n    assert.equal(moment([2006, 0, 1]).isoWeekYear(), 2005);\n    assert.equal(moment([2006, 0, 2]).isoWeekYear(), 2006);\n    assert.equal(moment([2007, 0, 1]).isoWeekYear(), 2007);\n    assert.equal(moment([2007, 11, 30]).isoWeekYear(), 2007);\n    assert.equal(moment([2007, 11, 31]).isoWeekYear(), 2008);\n    assert.equal(moment([2008, 0, 1]).isoWeekYear(), 2008);\n    assert.equal(moment([2008, 11, 28]).isoWeekYear(), 2008);\n    assert.equal(moment([2008, 11, 29]).isoWeekYear(), 2009);\n    assert.equal(moment([2008, 11, 30]).isoWeekYear(), 2009);\n    assert.equal(moment([2008, 11, 31]).isoWeekYear(), 2009);\n    assert.equal(moment([2009, 0, 1]).isoWeekYear(), 2009);\n    assert.equal(moment([2010, 0, 1]).isoWeekYear(), 2009);\n    assert.equal(moment([2010, 0, 2]).isoWeekYear(), 2009);\n    assert.equal(moment([2010, 0, 3]).isoWeekYear(), 2009);\n    assert.equal(moment([2010, 0, 4]).isoWeekYear(), 2010);\n});\n\ntest('week year', function (assert) {\n    // Some examples taken from https://en.wikipedia.org/wiki/ISO_week\n    moment.locale('dow: 1,doy: 4', {week: {dow: 1, doy: 4}}); // like iso\n    assert.equal(moment([2005, 0, 1]).weekYear(), 2004);\n    assert.equal(moment([2005, 0, 2]).weekYear(), 2004);\n    assert.equal(moment([2005, 0, 3]).weekYear(), 2005);\n    assert.equal(moment([2005, 11, 31]).weekYear(), 2005);\n    assert.equal(moment([2006, 0, 1]).weekYear(), 2005);\n    assert.equal(moment([2006, 0, 2]).weekYear(), 2006);\n    assert.equal(moment([2007, 0, 1]).weekYear(), 2007);\n    assert.equal(moment([2007, 11, 30]).weekYear(), 2007);\n    assert.equal(moment([2007, 11, 31]).weekYear(), 2008);\n    assert.equal(moment([2008, 0, 1]).weekYear(), 2008);\n    assert.equal(moment([2008, 11, 28]).weekYear(), 2008);\n    assert.equal(moment([2008, 11, 29]).weekYear(), 2009);\n    assert.equal(moment([2008, 11, 30]).weekYear(), 2009);\n    assert.equal(moment([2008, 11, 31]).weekYear(), 2009);\n    assert.equal(moment([2009, 0, 1]).weekYear(), 2009);\n    assert.equal(moment([2010, 0, 1]).weekYear(), 2009);\n    assert.equal(moment([2010, 0, 2]).weekYear(), 2009);\n    assert.equal(moment([2010, 0, 3]).weekYear(), 2009);\n    assert.equal(moment([2010, 0, 4]).weekYear(), 2010);\n\n    moment.locale('dow: 1,doy: 7', {week: {dow: 1, doy: 7}});\n    assert.equal(moment([2004, 11, 26]).weekYear(), 2004);\n    assert.equal(moment([2004, 11, 27]).weekYear(), 2005);\n    assert.equal(moment([2005, 11, 25]).weekYear(), 2005);\n    assert.equal(moment([2005, 11, 26]).weekYear(), 2006);\n    assert.equal(moment([2006, 11, 31]).weekYear(), 2006);\n    assert.equal(moment([2007,  0,  1]).weekYear(), 2007);\n    assert.equal(moment([2007, 11, 30]).weekYear(), 2007);\n    assert.equal(moment([2007, 11, 31]).weekYear(), 2008);\n    assert.equal(moment([2008, 11, 28]).weekYear(), 2008);\n    assert.equal(moment([2008, 11, 29]).weekYear(), 2009);\n    assert.equal(moment([2009, 11, 27]).weekYear(), 2009);\n    assert.equal(moment([2009, 11, 28]).weekYear(), 2010);\n});\n\n// Verifies that the week number, week day computation is correct for all dow, doy combinations\ntest('week year roundtrip', function (assert) {\n    var dow, doy, wd, m, localeName;\n    for (dow = 0; dow < 7; ++dow) {\n        for (doy = dow; doy < dow + 7; ++doy) {\n            for (wd = 0; wd < 7; ++wd) {\n                localeName = 'dow: ' + dow + ', doy: ' + doy;\n                moment.locale(localeName, {week: {dow: dow, doy: doy}});\n                // We use the 10th week as the 1st one can spill to the previous year\n                m = moment('2015 10 ' + wd, 'gggg w d', true);\n                assert.equal(m.format('gggg w d'), '2015 10 ' + wd, 'dow: ' + dow + ' doy: ' + doy + ' wd: ' + wd);\n                m = moment('2015 10 ' + wd, 'gggg w e', true);\n                assert.equal(m.format('gggg w e'), '2015 10 ' + wd, 'dow: ' + dow + ' doy: ' + doy + ' wd: ' + wd);\n                moment.defineLocale(localeName, null);\n            }\n        }\n    }\n});\n\ntest('week numbers 2012/2013', function (assert) {\n    moment.locale('dow: 6, doy: 12', {week: {dow: 6, doy: 12}});\n    assert.equal(52, moment('2012-12-28', 'YYYY-MM-DD').week(), '2012-12-28 is week 52'); // 51 -- should be 52?\n    assert.equal(1, moment('2012-12-29', 'YYYY-MM-DD').week(), '2012-12-29 is week 1'); // 52 -- should be 1\n    assert.equal(1, moment('2013-01-01', 'YYYY-MM-DD').week(), '2013-01-01 is week 1'); // 52 -- should be 1\n    assert.equal(2, moment('2013-01-08', 'YYYY-MM-DD').week(), '2013-01-08 is week 2'); // 53 -- should be 2\n    assert.equal(2, moment('2013-01-11', 'YYYY-MM-DD').week(), '2013-01-11 is week 2'); // 53 -- should be 2\n    assert.equal(3, moment('2013-01-12', 'YYYY-MM-DD').week(), '2013-01-12 is week 3'); // 1 -- should be 3\n    assert.equal(52, moment('2012-01-01', 'YYYY-MM-DD').weeksInYear(), 'weeks in 2012 are 52'); // 52\n    moment.defineLocale('dow: 6, doy: 12', null);\n});\n\ntest('weeks numbers dow:1 doy:4', function (assert) {\n    moment.locale('dow: 1, doy: 4', {week: {dow: 1, doy: 4}});\n    assert.equal(moment([2012, 0, 1]).week(), 52, 'Jan  1 2012 should be week 52');\n    assert.equal(moment([2012, 0, 2]).week(),  1, 'Jan  2 2012 should be week 1');\n    assert.equal(moment([2012, 0, 8]).week(),  1, 'Jan  8 2012 should be week 1');\n    assert.equal(moment([2012, 0, 9]).week(),  2, 'Jan  9 2012 should be week 2');\n    assert.equal(moment([2012, 0, 15]).week(), 2, 'Jan 15 2012 should be week 2');\n    assert.equal(moment([2007, 0, 1]).week(),  1, 'Jan  1 2007 should be week 1');\n    assert.equal(moment([2007, 0, 7]).week(),  1, 'Jan  7 2007 should be week 1');\n    assert.equal(moment([2007, 0, 8]).week(),  2, 'Jan  8 2007 should be week 2');\n    assert.equal(moment([2007, 0, 14]).week(), 2, 'Jan 14 2007 should be week 2');\n    assert.equal(moment([2007, 0, 15]).week(), 3, 'Jan 15 2007 should be week 3');\n    assert.equal(moment([2007, 11, 31]).week(), 1, 'Dec 31 2007 should be week 1');\n    assert.equal(moment([2008,  0,  1]).week(), 1, 'Jan  1 2008 should be week 1');\n    assert.equal(moment([2008,  0,  6]).week(), 1, 'Jan  6 2008 should be week 1');\n    assert.equal(moment([2008,  0,  7]).week(), 2, 'Jan  7 2008 should be week 2');\n    assert.equal(moment([2008,  0, 13]).week(), 2, 'Jan 13 2008 should be week 2');\n    assert.equal(moment([2008,  0, 14]).week(), 3, 'Jan 14 2008 should be week 3');\n    assert.equal(moment([2002, 11, 30]).week(), 1, 'Dec 30 2002 should be week 1');\n    assert.equal(moment([2003,  0,  1]).week(), 1, 'Jan  1 2003 should be week 1');\n    assert.equal(moment([2003,  0,  5]).week(), 1, 'Jan  5 2003 should be week 1');\n    assert.equal(moment([2003,  0,  6]).week(), 2, 'Jan  6 2003 should be week 2');\n    assert.equal(moment([2003,  0, 12]).week(), 2, 'Jan 12 2003 should be week 2');\n    assert.equal(moment([2003,  0, 13]).week(), 3, 'Jan 13 2003 should be week 3');\n    assert.equal(moment([2008, 11, 29]).week(), 1, 'Dec 29 2008 should be week 1');\n    assert.equal(moment([2009,  0,  1]).week(), 1, 'Jan  1 2009 should be week 1');\n    assert.equal(moment([2009,  0,  4]).week(), 1, 'Jan  4 2009 should be week 1');\n    assert.equal(moment([2009,  0,  5]).week(), 2, 'Jan  5 2009 should be week 2');\n    assert.equal(moment([2009,  0, 11]).week(), 2, 'Jan 11 2009 should be week 2');\n    assert.equal(moment([2009,  0, 13]).week(), 3, 'Jan 12 2009 should be week 3');\n    assert.equal(moment([2009, 11, 28]).week(), 53, 'Dec 28 2009 should be week 53');\n    assert.equal(moment([2010,  0,  1]).week(), 53, 'Jan  1 2010 should be week 53');\n    assert.equal(moment([2010,  0,  3]).week(), 53, 'Jan  3 2010 should be week 53');\n    assert.equal(moment([2010,  0,  4]).week(),  1, 'Jan  4 2010 should be week 1');\n    assert.equal(moment([2010,  0, 10]).week(),  1, 'Jan 10 2010 should be week 1');\n    assert.equal(moment([2010,  0, 11]).week(),  2, 'Jan 11 2010 should be week 2');\n    assert.equal(moment([2010, 11, 27]).week(), 52, 'Dec 27 2010 should be week 52');\n    assert.equal(moment([2011,  0,  1]).week(), 52, 'Jan  1 2011 should be week 52');\n    assert.equal(moment([2011,  0,  2]).week(), 52, 'Jan  2 2011 should be week 52');\n    assert.equal(moment([2011,  0,  3]).week(),  1, 'Jan  3 2011 should be week 1');\n    assert.equal(moment([2011,  0,  9]).week(),  1, 'Jan  9 2011 should be week 1');\n    assert.equal(moment([2011,  0, 10]).week(),  2, 'Jan 10 2011 should be week 2');\n    moment.defineLocale('dow: 1, doy: 4', null);\n});\n\ntest('weeks numbers dow:6 doy:12', function (assert) {\n    moment.locale('dow: 6, doy: 12', {week: {dow: 6, doy: 12}});\n    assert.equal(moment([2011, 11, 31]).week(), 1, 'Dec 31 2011 should be week 1');\n    assert.equal(moment([2012,  0,  6]).week(), 1, 'Jan  6 2012 should be week 1');\n    assert.equal(moment([2012,  0,  7]).week(), 2, 'Jan  7 2012 should be week 2');\n    assert.equal(moment([2012,  0, 13]).week(), 2, 'Jan 13 2012 should be week 2');\n    assert.equal(moment([2012,  0, 14]).week(), 3, 'Jan 14 2012 should be week 3');\n    assert.equal(moment([2006, 11, 30]).week(), 1, 'Dec 30 2006 should be week 1');\n    assert.equal(moment([2007,  0,  5]).week(), 1, 'Jan  5 2007 should be week 1');\n    assert.equal(moment([2007,  0,  6]).week(), 2, 'Jan  6 2007 should be week 2');\n    assert.equal(moment([2007,  0, 12]).week(), 2, 'Jan 12 2007 should be week 2');\n    assert.equal(moment([2007,  0, 13]).week(), 3, 'Jan 13 2007 should be week 3');\n    assert.equal(moment([2007, 11, 29]).week(), 1, 'Dec 29 2007 should be week 1');\n    assert.equal(moment([2008,  0,  1]).week(), 1, 'Jan  1 2008 should be week 1');\n    assert.equal(moment([2008,  0,  4]).week(), 1, 'Jan  4 2008 should be week 1');\n    assert.equal(moment([2008,  0,  5]).week(), 2, 'Jan  5 2008 should be week 2');\n    assert.equal(moment([2008,  0, 11]).week(), 2, 'Jan 11 2008 should be week 2');\n    assert.equal(moment([2008,  0, 12]).week(), 3, 'Jan 12 2008 should be week 3');\n    assert.equal(moment([2002, 11, 28]).week(), 1, 'Dec 28 2002 should be week 1');\n    assert.equal(moment([2003,  0,  1]).week(), 1, 'Jan  1 2003 should be week 1');\n    assert.equal(moment([2003,  0,  3]).week(), 1, 'Jan  3 2003 should be week 1');\n    assert.equal(moment([2003,  0,  4]).week(), 2, 'Jan  4 2003 should be week 2');\n    assert.equal(moment([2003,  0, 10]).week(), 2, 'Jan 10 2003 should be week 2');\n    assert.equal(moment([2003,  0, 11]).week(), 3, 'Jan 11 2003 should be week 3');\n    assert.equal(moment([2008, 11, 27]).week(), 1, 'Dec 27 2008 should be week 1');\n    assert.equal(moment([2009,  0,  1]).week(), 1, 'Jan  1 2009 should be week 1');\n    assert.equal(moment([2009,  0,  2]).week(), 1, 'Jan  2 2009 should be week 1');\n    assert.equal(moment([2009,  0,  3]).week(), 2, 'Jan  3 2009 should be week 2');\n    assert.equal(moment([2009,  0,  9]).week(), 2, 'Jan  9 2009 should be week 2');\n    assert.equal(moment([2009,  0, 10]).week(), 3, 'Jan 10 2009 should be week 3');\n    assert.equal(moment([2009, 11, 26]).week(), 1, 'Dec 26 2009 should be week 1');\n    assert.equal(moment([2010,  0,  1]).week(), 1, 'Jan  1 2010 should be week 1');\n    assert.equal(moment([2010,  0,  2]).week(), 2, 'Jan  2 2010 should be week 2');\n    assert.equal(moment([2010,  0,  8]).week(), 2, 'Jan  8 2010 should be week 2');\n    assert.equal(moment([2010,  0,  9]).week(), 3, 'Jan  9 2010 should be week 3');\n    assert.equal(moment([2011, 0,  1]).week(), 1, 'Jan  1 2011 should be week 1');\n    assert.equal(moment([2011, 0,  7]).week(), 1, 'Jan  7 2011 should be week 1');\n    assert.equal(moment([2011, 0,  8]).week(), 2, 'Jan  8 2011 should be week 2');\n    assert.equal(moment([2011, 0, 14]).week(), 2, 'Jan 14 2011 should be week 2');\n    assert.equal(moment([2011, 0, 15]).week(), 3, 'Jan 15 2011 should be week 3');\n    moment.defineLocale('dow: 6, doy: 12', null);\n});\n\ntest('weeks numbers dow:1 doy:7', function (assert) {\n    moment.locale('dow: 1, doy: 7', {week: {dow: 1, doy: 7}});\n    assert.equal(moment([2011, 11, 26]).week(), 1, 'Dec 26 2011 should be week 1');\n    assert.equal(moment([2012,  0,  1]).week(), 1, 'Jan  1 2012 should be week 1');\n    assert.equal(moment([2012,  0,  2]).week(), 2, 'Jan  2 2012 should be week 2');\n    assert.equal(moment([2012,  0,  8]).week(), 2, 'Jan  8 2012 should be week 2');\n    assert.equal(moment([2012,  0,  9]).week(), 3, 'Jan  9 2012 should be week 3');\n    assert.equal(moment([2007, 0, 1]).week(),  1, 'Jan  1 2007 should be week 1');\n    assert.equal(moment([2007, 0, 7]).week(),  1, 'Jan  7 2007 should be week 1');\n    assert.equal(moment([2007, 0, 8]).week(),  2, 'Jan  8 2007 should be week 2');\n    assert.equal(moment([2007, 0, 14]).week(), 2, 'Jan 14 2007 should be week 2');\n    assert.equal(moment([2007, 0, 15]).week(), 3, 'Jan 15 2007 should be week 3');\n    assert.equal(moment([2007, 11, 31]).week(), 1, 'Dec 31 2007 should be week 1');\n    assert.equal(moment([2008,  0,  1]).week(), 1, 'Jan  1 2008 should be week 1');\n    assert.equal(moment([2008,  0,  6]).week(), 1, 'Jan  6 2008 should be week 1');\n    assert.equal(moment([2008,  0,  7]).week(), 2, 'Jan  7 2008 should be week 2');\n    assert.equal(moment([2008,  0, 13]).week(), 2, 'Jan 13 2008 should be week 2');\n    assert.equal(moment([2008,  0, 14]).week(), 3, 'Jan 14 2008 should be week 3');\n    assert.equal(moment([2002, 11, 30]).week(), 1, 'Dec 30 2002 should be week 1');\n    assert.equal(moment([2003,  0,  1]).week(), 1, 'Jan  1 2003 should be week 1');\n    assert.equal(moment([2003,  0,  5]).week(), 1, 'Jan  5 2003 should be week 1');\n    assert.equal(moment([2003,  0,  6]).week(), 2, 'Jan  6 2003 should be week 2');\n    assert.equal(moment([2003,  0, 12]).week(), 2, 'Jan 12 2003 should be week 2');\n    assert.equal(moment([2003,  0, 13]).week(), 3, 'Jan 13 2003 should be week 3');\n    assert.equal(moment([2008, 11, 29]).week(), 1, 'Dec 29 2008 should be week 1');\n    assert.equal(moment([2009,  0,  1]).week(), 1, 'Jan  1 2009 should be week 1');\n    assert.equal(moment([2009,  0,  4]).week(), 1, 'Jan  4 2009 should be week 1');\n    assert.equal(moment([2009,  0,  5]).week(), 2, 'Jan  5 2009 should be week 2');\n    assert.equal(moment([2009,  0, 11]).week(), 2, 'Jan 11 2009 should be week 2');\n    assert.equal(moment([2009,  0, 12]).week(), 3, 'Jan 12 2009 should be week 3');\n    assert.equal(moment([2009, 11, 28]).week(), 1, 'Dec 28 2009 should be week 1');\n    assert.equal(moment([2010,  0,  1]).week(), 1, 'Jan  1 2010 should be week 1');\n    assert.equal(moment([2010,  0,  3]).week(), 1, 'Jan  3 2010 should be week 1');\n    assert.equal(moment([2010,  0,  4]).week(), 2, 'Jan  4 2010 should be week 2');\n    assert.equal(moment([2010,  0, 10]).week(), 2, 'Jan 10 2010 should be week 2');\n    assert.equal(moment([2010,  0, 11]).week(), 3, 'Jan 11 2010 should be week 3');\n    assert.equal(moment([2010, 11, 27]).week(), 1, 'Dec 27 2010 should be week 1');\n    assert.equal(moment([2011,  0,  1]).week(), 1, 'Jan  1 2011 should be week 1');\n    assert.equal(moment([2011,  0,  2]).week(), 1, 'Jan  2 2011 should be week 1');\n    assert.equal(moment([2011,  0,  3]).week(), 2, 'Jan  3 2011 should be week 2');\n    assert.equal(moment([2011,  0,  9]).week(), 2, 'Jan  9 2011 should be week 2');\n    assert.equal(moment([2011,  0, 10]).week(), 3, 'Jan 10 2011 should be week 3');\n    moment.defineLocale('dow: 1, doy: 7', null);\n});\n\ntest('weeks numbers dow:0 doy:6', function (assert) {\n    moment.locale('dow: 0, doy: 6', {week: {dow: 0, doy: 6}});\n    assert.equal(moment([2012, 0,  1]).week(), 1, 'Jan  1 2012 should be week 1');\n    assert.equal(moment([2012, 0,  7]).week(), 1, 'Jan  7 2012 should be week 1');\n    assert.equal(moment([2012, 0,  8]).week(), 2, 'Jan  8 2012 should be week 2');\n    assert.equal(moment([2012, 0, 14]).week(), 2, 'Jan 14 2012 should be week 2');\n    assert.equal(moment([2012, 0, 15]).week(), 3, 'Jan 15 2012 should be week 3');\n    assert.equal(moment([2006, 11, 31]).week(), 1, 'Dec 31 2006 should be week 1');\n    assert.equal(moment([2007,  0,  1]).week(), 1, 'Jan  1 2007 should be week 1');\n    assert.equal(moment([2007,  0,  6]).week(), 1, 'Jan  6 2007 should be week 1');\n    assert.equal(moment([2007,  0,  7]).week(), 2, 'Jan  7 2007 should be week 2');\n    assert.equal(moment([2007,  0, 13]).week(), 2, 'Jan 13 2007 should be week 2');\n    assert.equal(moment([2007,  0, 14]).week(), 3, 'Jan 14 2007 should be week 3');\n    assert.equal(moment([2007, 11, 29]).week(), 52, 'Dec 29 2007 should be week 52');\n    assert.equal(moment([2008,  0,  1]).week(), 1, 'Jan  1 2008 should be week 1');\n    assert.equal(moment([2008,  0,  5]).week(), 1, 'Jan  5 2008 should be week 1');\n    assert.equal(moment([2008,  0,  6]).week(), 2, 'Jan  6 2008 should be week 2');\n    assert.equal(moment([2008,  0, 12]).week(), 2, 'Jan 12 2008 should be week 2');\n    assert.equal(moment([2008,  0, 13]).week(), 3, 'Jan 13 2008 should be week 3');\n    assert.equal(moment([2002, 11, 29]).week(), 1, 'Dec 29 2002 should be week 1');\n    assert.equal(moment([2003,  0,  1]).week(), 1, 'Jan  1 2003 should be week 1');\n    assert.equal(moment([2003,  0,  4]).week(), 1, 'Jan  4 2003 should be week 1');\n    assert.equal(moment([2003,  0,  5]).week(), 2, 'Jan  5 2003 should be week 2');\n    assert.equal(moment([2003,  0, 11]).week(), 2, 'Jan 11 2003 should be week 2');\n    assert.equal(moment([2003,  0, 12]).week(), 3, 'Jan 12 2003 should be week 3');\n    assert.equal(moment([2008, 11, 28]).week(), 1, 'Dec 28 2008 should be week 1');\n    assert.equal(moment([2009,  0,  1]).week(), 1, 'Jan  1 2009 should be week 1');\n    assert.equal(moment([2009,  0,  3]).week(), 1, 'Jan  3 2009 should be week 1');\n    assert.equal(moment([2009,  0,  4]).week(), 2, 'Jan  4 2009 should be week 2');\n    assert.equal(moment([2009,  0, 10]).week(), 2, 'Jan 10 2009 should be week 2');\n    assert.equal(moment([2009,  0, 11]).week(), 3, 'Jan 11 2009 should be week 3');\n    assert.equal(moment([2009, 11, 27]).week(), 1, 'Dec 27 2009 should be week 1');\n    assert.equal(moment([2010,  0,  1]).week(), 1, 'Jan  1 2010 should be week 1');\n    assert.equal(moment([2010,  0,  2]).week(), 1, 'Jan  2 2010 should be week 1');\n    assert.equal(moment([2010,  0,  3]).week(), 2, 'Jan  3 2010 should be week 2');\n    assert.equal(moment([2010,  0,  9]).week(), 2, 'Jan  9 2010 should be week 2');\n    assert.equal(moment([2010,  0, 10]).week(), 3, 'Jan 10 2010 should be week 3');\n    assert.equal(moment([2010, 11, 26]).week(), 1, 'Dec 26 2010 should be week 1');\n    assert.equal(moment([2011,  0,  1]).week(), 1, 'Jan  1 2011 should be week 1');\n    assert.equal(moment([2011,  0,  2]).week(), 2, 'Jan  2 2011 should be week 2');\n    assert.equal(moment([2011,  0,  8]).week(), 2, 'Jan  8 2011 should be week 2');\n    assert.equal(moment([2011,  0,  9]).week(), 3, 'Jan  9 2011 should be week 3');\n    moment.defineLocale('dow: 0, doy: 6', null);\n});\n\ntest('week year overflows', function (assert) {\n    assert.equal('2005-01-01', moment.utc('2004-W53-6', moment.ISO_8601, true).format('YYYY-MM-DD'), '2004-W53-6 is 1st Jan 2005');\n    assert.equal('2007-12-31', moment.utc('2008-W01-1', moment.ISO_8601, true).format('YYYY-MM-DD'), '2008-W01-1 is 31st Dec 2007');\n});\n\ntest('weeks overflow', function (assert) {\n    assert.equal(7, moment.utc('2004-W54-1', moment.ISO_8601, true).parsingFlags().overflow, '2004 has only 53 weeks');\n    assert.equal(7, moment.utc('2004-W00-1', moment.ISO_8601, true).parsingFlags().overflow, 'there is no 0th week');\n});\n\ntest('weekday overflow', function (assert) {\n    assert.equal(8, moment.utc('2004-W30-0', moment.ISO_8601, true).parsingFlags().overflow, 'there is no 0 iso weekday');\n    assert.equal(8, moment.utc('2004-W30-8', moment.ISO_8601, true).parsingFlags().overflow, 'there is no 8 iso weekday');\n    assert.equal(8, moment.utc('2004-w30-7', 'gggg-[w]ww-e', true).parsingFlags().overflow, 'there is no 7 \\'e\\' weekday');\n    assert.equal(8, moment.utc('2004-w30-7', 'gggg-[w]ww-d', true).parsingFlags().overflow, 'there is no 7 \\'d\\' weekday');\n});\n\ntest('week year setter works', function (assert) {\n    for (var year = 2000; year <= 2020; year += 1) {\n        assert.equal(moment.utc('2012-12-31T00:00:00.000Z').isoWeekYear(year).isoWeekYear(), year, 'setting iso-week-year to ' + year);\n        assert.equal(moment.utc('2012-12-31T00:00:00.000Z').weekYear(year).weekYear(), year, 'setting week-year to ' + year);\n    }\n\n    assert.equal(moment.utc('2004-W53-1', moment.ISO_8601, true).isoWeekYear(2013).format('GGGG-[W]WW-E'), '2013-W52-1', '2004-W53-1 to 2013');\n    assert.equal(moment.utc('2004-W53-1', moment.ISO_8601, true).isoWeekYear(2020).format('GGGG-[W]WW-E'), '2020-W53-1', '2004-W53-1 to 2020');\n    assert.equal(moment.utc('2005-W52-1', moment.ISO_8601, true).isoWeekYear(2004).format('GGGG-[W]WW-E'), '2004-W52-1', '2005-W52-1 to 2004');\n    assert.equal(moment.utc('2013-W30-4', moment.ISO_8601, true).isoWeekYear(2015).format('GGGG-[W]WW-E'), '2015-W30-4', '2013-W30-4 to 2015');\n\n    assert.equal(moment.utc('2005-w53-0', 'gggg-[w]ww-e', true).weekYear(2013).format('gggg-[w]ww-e'), '2013-w52-0', '2005-w53-0 to 2013');\n    assert.equal(moment.utc('2005-w53-0', 'gggg-[w]ww-e', true).weekYear(2016).format('gggg-[w]ww-e'), '2016-w53-0', '2005-w53-0 to 2016');\n    assert.equal(moment.utc('2004-w52-0', 'gggg-[w]ww-e', true).weekYear(2005).format('gggg-[w]ww-e'), '2005-w52-0', '2004-w52-0 to 2005');\n    assert.equal(moment.utc('2013-w30-4', 'gggg-[w]ww-e', true).weekYear(2015).format('gggg-[w]ww-e'), '2015-w30-4', '2013-w30-4 to 2015');\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\nfunction module$1 (name, lifecycle) {\n    QUnit.module(name, {\n        setup : function () {\n            moment.locale('en');\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'core');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            teardownDeprecationHandler(test, moment, 'core');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n}\n\nmodule$1('week day');\n\ntest('iso weekday', function (assert) {\n    var i;\n\n    for (i = 0; i < 7; ++i) {\n        moment.locale('dow:' + i + ',doy: 6', {week: {dow: i, doy: 6}});\n        assert.equal(moment([1985, 1,  4]).isoWeekday(), 1, 'Feb  4 1985 is Monday    -- 1st day');\n        assert.equal(moment([2029, 8, 18]).isoWeekday(), 2, 'Sep 18 2029 is Tuesday   -- 2nd day');\n        assert.equal(moment([2013, 3, 24]).isoWeekday(), 3, 'Apr 24 2013 is Wednesday -- 3rd day');\n        assert.equal(moment([2015, 2,  5]).isoWeekday(), 4, 'Mar  5 2015 is Thursday  -- 4th day');\n        assert.equal(moment([1970, 0,  2]).isoWeekday(), 5, 'Jan  2 1970 is Friday    -- 5th day');\n        assert.equal(moment([2001, 4, 12]).isoWeekday(), 6, 'May 12 2001 is Saturday  -- 6th day');\n        assert.equal(moment([2000, 0,  2]).isoWeekday(), 7, 'Jan  2 2000 is Sunday    -- 7th day');\n    }\n});\n\ntest('iso weekday setter', function (assert) {\n    var a = moment([2011, 0, 10]);\n    assert.equal(moment(a).isoWeekday(1).date(),  10, 'set from mon to mon');\n    assert.equal(moment(a).isoWeekday(4).date(),  13, 'set from mon to thu');\n    assert.equal(moment(a).isoWeekday(7).date(),  16, 'set from mon to sun');\n    assert.equal(moment(a).isoWeekday(-6).date(),  3, 'set from mon to last mon');\n    assert.equal(moment(a).isoWeekday(-3).date(),  6, 'set from mon to last thu');\n    assert.equal(moment(a).isoWeekday(0).date(),   9, 'set from mon to last sun');\n    assert.equal(moment(a).isoWeekday(8).date(),  17, 'set from mon to next mon');\n    assert.equal(moment(a).isoWeekday(11).date(), 20, 'set from mon to next thu');\n    assert.equal(moment(a).isoWeekday(14).date(), 23, 'set from mon to next sun');\n\n    a = moment([2011, 0, 13]);\n    assert.equal(moment(a).isoWeekday(1).date(), 10, 'set from thu to mon');\n    assert.equal(moment(a).isoWeekday(4).date(), 13, 'set from thu to thu');\n    assert.equal(moment(a).isoWeekday(7).date(), 16, 'set from thu to sun');\n    assert.equal(moment(a).isoWeekday(-6).date(),  3, 'set from thu to last mon');\n    assert.equal(moment(a).isoWeekday(-3).date(),  6, 'set from thu to last thu');\n    assert.equal(moment(a).isoWeekday(0).date(),   9, 'set from thu to last sun');\n    assert.equal(moment(a).isoWeekday(8).date(),  17, 'set from thu to next mon');\n    assert.equal(moment(a).isoWeekday(11).date(), 20, 'set from thu to next thu');\n    assert.equal(moment(a).isoWeekday(14).date(), 23, 'set from thu to next sun');\n\n    a = moment([2011, 0, 16]);\n    assert.equal(moment(a).isoWeekday(1).date(), 10, 'set from sun to mon');\n    assert.equal(moment(a).isoWeekday(4).date(), 13, 'set from sun to thu');\n    assert.equal(moment(a).isoWeekday(7).date(), 16, 'set from sun to sun');\n    assert.equal(moment(a).isoWeekday(-6).date(),  3, 'set from sun to last mon');\n    assert.equal(moment(a).isoWeekday(-3).date(),  6, 'set from sun to last thu');\n    assert.equal(moment(a).isoWeekday(0).date(),   9, 'set from sun to last sun');\n    assert.equal(moment(a).isoWeekday(8).date(),  17, 'set from sun to next mon');\n    assert.equal(moment(a).isoWeekday(11).date(), 20, 'set from sun to next thu');\n    assert.equal(moment(a).isoWeekday(14).date(), 23, 'set from sun to next sun');\n});\n\ntest('iso weekday setter with day name', function (assert) {\n    moment.locale('en');\n\n    var a = moment([2011, 0, 10]);\n    assert.equal(moment(a).isoWeekday('Monday').date(),   10, 'set from mon to mon');\n    assert.equal(moment(a).isoWeekday('Thursday').date(), 13, 'set from mon to thu');\n    assert.equal(moment(a).isoWeekday('Sunday').date(),   16, 'set from mon to sun');\n\n    a = moment([2011, 0, 13]);\n    assert.equal(moment(a).isoWeekday('Monday').date(),   10, 'set from thu to mon');\n    assert.equal(moment(a).isoWeekday('Thursday').date(), 13, 'set from thu to thu');\n    assert.equal(moment(a).isoWeekday('Sunday').date(),   16, 'set from thu to sun');\n\n    a = moment([2011, 0, 16]);\n    assert.equal(moment(a).isoWeekday('Monday').date(),   10, 'set from sun to mon');\n    assert.equal(moment(a).isoWeekday('Thursday').date(), 13, 'set from sun to thu');\n    assert.equal(moment(a).isoWeekday('Sunday').date(),   16, 'set from sun to sun');\n});\n\ntest('weekday first day of week Sunday (dow 0)', function (assert) {\n    moment.locale('dow: 0,doy: 6', {week: {dow: 0, doy: 6}});\n    assert.equal(moment([1985, 1,  3]).weekday(), 0, 'Feb  3 1985 is Sunday    -- 0th day');\n    assert.equal(moment([2029, 8, 17]).weekday(), 1, 'Sep 17 2029 is Monday    -- 1st day');\n    assert.equal(moment([2013, 3, 23]).weekday(), 2, 'Apr 23 2013 is Tuesday   -- 2nd day');\n    assert.equal(moment([2015, 2,  4]).weekday(), 3, 'Mar  4 2015 is Wednesday -- 3nd day');\n    assert.equal(moment([1970, 0,  1]).weekday(), 4, 'Jan  1 1970 is Thursday  -- 4th day');\n    assert.equal(moment([2001, 4, 11]).weekday(), 5, 'May 11 2001 is Friday    -- 5th day');\n    assert.equal(moment([2000, 0,  1]).weekday(), 6, 'Jan  1 2000 is Saturday  -- 6th day');\n});\n\ntest('weekday first day of week Monday (dow 1)', function (assert) {\n    moment.locale('dow: 1,doy: 6', {week: {dow: 1, doy: 6}});\n    assert.equal(moment([1985, 1,  4]).weekday(), 0, 'Feb  4 1985 is Monday    -- 0th day');\n    assert.equal(moment([2029, 8, 18]).weekday(), 1, 'Sep 18 2029 is Tuesday   -- 1st day');\n    assert.equal(moment([2013, 3, 24]).weekday(), 2, 'Apr 24 2013 is Wednesday -- 2nd day');\n    assert.equal(moment([2015, 2,  5]).weekday(), 3, 'Mar  5 2015 is Thursday  -- 3nd day');\n    assert.equal(moment([1970, 0,  2]).weekday(), 4, 'Jan  2 1970 is Friday    -- 4th day');\n    assert.equal(moment([2001, 4, 12]).weekday(), 5, 'May 12 2001 is Saturday  -- 5th day');\n    assert.equal(moment([2000, 0,  2]).weekday(), 6, 'Jan  2 2000 is Sunday    -- 6th day');\n});\n\ntest('weekday first day of week Tuesday (dow 2)', function (assert) {\n    moment.locale('dow: 2,doy: 6', {week: {dow: 2, doy: 6}});\n    assert.equal(moment([1985, 1,  5]).weekday(), 0, 'Feb  5 1985 is Tuesday   -- 0th day');\n    assert.equal(moment([2029, 8, 19]).weekday(), 1, 'Sep 19 2029 is Wednesday -- 1st day');\n    assert.equal(moment([2013, 3, 25]).weekday(), 2, 'Apr 25 2013 is Thursday  -- 2nd day');\n    assert.equal(moment([2015, 2,  6]).weekday(), 3, 'Mar  6 2015 is Friday    -- 3nd day');\n    assert.equal(moment([1970, 0,  3]).weekday(), 4, 'Jan  3 1970 is Staturday -- 4th day');\n    assert.equal(moment([2001, 4, 13]).weekday(), 5, 'May 13 2001 is Sunday    -- 5th day');\n    assert.equal(moment([2000, 0,  3]).weekday(), 6, 'Jan  3 2000 is Monday    -- 6th day');\n});\n\ntest('weekday first day of week Wednesday (dow 3)', function (assert) {\n    moment.locale('dow: 3,doy: 6', {week: {dow: 3, doy: 6}});\n    assert.equal(moment([1985, 1,  6]).weekday(), 0, 'Feb  6 1985 is Wednesday -- 0th day');\n    assert.equal(moment([2029, 8, 20]).weekday(), 1, 'Sep 20 2029 is Thursday  -- 1st day');\n    assert.equal(moment([2013, 3, 26]).weekday(), 2, 'Apr 26 2013 is Friday    -- 2nd day');\n    assert.equal(moment([2015, 2,  7]).weekday(), 3, 'Mar  7 2015 is Saturday  -- 3nd day');\n    assert.equal(moment([1970, 0,  4]).weekday(), 4, 'Jan  4 1970 is Sunday    -- 4th day');\n    assert.equal(moment([2001, 4, 14]).weekday(), 5, 'May 14 2001 is Monday    -- 5th day');\n    assert.equal(moment([2000, 0,  4]).weekday(), 6, 'Jan  4 2000 is Tuesday   -- 6th day');\n    moment.locale('dow:3,doy:6', null);\n});\n\ntest('weekday first day of week Thursday (dow 4)', function (assert) {\n    moment.locale('dow: 4,doy: 6', {week: {dow: 4, doy: 6}});\n    assert.equal(moment([1985, 1,  7]).weekday(), 0, 'Feb  7 1985 is Thursday  -- 0th day');\n    assert.equal(moment([2029, 8, 21]).weekday(), 1, 'Sep 21 2029 is Friday    -- 1st day');\n    assert.equal(moment([2013, 3, 27]).weekday(), 2, 'Apr 27 2013 is Saturday  -- 2nd day');\n    assert.equal(moment([2015, 2,  8]).weekday(), 3, 'Mar  8 2015 is Sunday    -- 3nd day');\n    assert.equal(moment([1970, 0,  5]).weekday(), 4, 'Jan  5 1970 is Monday    -- 4th day');\n    assert.equal(moment([2001, 4, 15]).weekday(), 5, 'May 15 2001 is Tuesday   -- 5th day');\n    assert.equal(moment([2000, 0,  5]).weekday(), 6, 'Jan  5 2000 is Wednesday -- 6th day');\n});\n\ntest('weekday first day of week Friday (dow 5)', function (assert) {\n    moment.locale('dow: 5,doy: 6', {week: {dow: 5, doy: 6}});\n    assert.equal(moment([1985, 1,  8]).weekday(), 0, 'Feb  8 1985 is Friday    -- 0th day');\n    assert.equal(moment([2029, 8, 22]).weekday(), 1, 'Sep 22 2029 is Staturday -- 1st day');\n    assert.equal(moment([2013, 3, 28]).weekday(), 2, 'Apr 28 2013 is Sunday    -- 2nd day');\n    assert.equal(moment([2015, 2,  9]).weekday(), 3, 'Mar  9 2015 is Monday    -- 3nd day');\n    assert.equal(moment([1970, 0,  6]).weekday(), 4, 'Jan  6 1970 is Tuesday   -- 4th day');\n    assert.equal(moment([2001, 4, 16]).weekday(), 5, 'May 16 2001 is Wednesday -- 5th day');\n    assert.equal(moment([2000, 0,  6]).weekday(), 6, 'Jan  6 2000 is Thursday  -- 6th day');\n});\n\ntest('weekday first day of week Saturday (dow 6)', function (assert) {\n    moment.locale('dow: 6,doy: 6', {week: {dow: 6, doy: 6}});\n    assert.equal(moment([1985, 1,  9]).weekday(), 0, 'Feb  9 1985 is Staturday -- 0th day');\n    assert.equal(moment([2029, 8, 23]).weekday(), 1, 'Sep 23 2029 is Sunday    -- 1st day');\n    assert.equal(moment([2013, 3, 29]).weekday(), 2, 'Apr 29 2013 is Monday    -- 2nd day');\n    assert.equal(moment([2015, 2, 10]).weekday(), 3, 'Mar 10 2015 is Tuesday   -- 3nd day');\n    assert.equal(moment([1970, 0,  7]).weekday(), 4, 'Jan  7 1970 is Wednesday -- 4th day');\n    assert.equal(moment([2001, 4, 17]).weekday(), 5, 'May 17 2001 is Thursday  -- 5th day');\n    assert.equal(moment([2000, 0,  7]).weekday(), 6, 'Jan  7 2000 is Friday    -- 6th day');\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\nfunction module$1 (name, lifecycle) {\n    QUnit.module(name, {\n        setup : function () {\n            moment.locale('en');\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'core');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            teardownDeprecationHandler(test, moment, 'core');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n}\n\nmodule$1('weeks');\n\ntest('day of year', function (assert) {\n    assert.equal(moment([2000,  0,  1]).dayOfYear(),   1, 'Jan  1 2000 should be day 1 of the year');\n    assert.equal(moment([2000,  1, 28]).dayOfYear(),  59, 'Feb 28 2000 should be day 59 of the year');\n    assert.equal(moment([2000,  1, 29]).dayOfYear(),  60, 'Feb 28 2000 should be day 60 of the year');\n    assert.equal(moment([2000, 11, 31]).dayOfYear(), 366, 'Dec 31 2000 should be day 366 of the year');\n    assert.equal(moment([2001,  0,  1]).dayOfYear(),   1, 'Jan  1 2001 should be day 1 of the year');\n    assert.equal(moment([2001,  1, 28]).dayOfYear(),  59, 'Feb 28 2001 should be day 59 of the year');\n    assert.equal(moment([2001,  2,  1]).dayOfYear(),  60, 'Mar  1 2001 should be day 60 of the year');\n    assert.equal(moment([2001, 11, 31]).dayOfYear(), 365, 'Dec 31 2001 should be day 365 of the year');\n});\n\ntest('day of year setters', function (assert) {\n    assert.equal(moment([2000,  0,  1]).dayOfYear(200).dayOfYear(), 200, 'Setting Jan  1 2000 day of the year to 200 should work');\n    assert.equal(moment([2000,  1, 28]).dayOfYear(200).dayOfYear(), 200, 'Setting Feb 28 2000 day of the year to 200 should work');\n    assert.equal(moment([2000,  1, 29]).dayOfYear(200).dayOfYear(), 200, 'Setting Feb 28 2000 day of the year to 200 should work');\n    assert.equal(moment([2000, 11, 31]).dayOfYear(200).dayOfYear(), 200, 'Setting Dec 31 2000 day of the year to 200 should work');\n    assert.equal(moment().dayOfYear(1).dayOfYear(),   1, 'Setting day of the year to 1 should work');\n    assert.equal(moment().dayOfYear(59).dayOfYear(),  59, 'Setting day of the year to 59 should work');\n    assert.equal(moment().dayOfYear(60).dayOfYear(),  60, 'Setting day of the year to 60 should work');\n    assert.equal(moment().dayOfYear(365).dayOfYear(), 365, 'Setting day of the year to 365 should work');\n});\n\ntest('iso weeks year starting sunday', function (assert) {\n    assert.equal(moment([2012, 0, 1]).isoWeek(), 52, 'Jan  1 2012 should be iso week 52');\n    assert.equal(moment([2012, 0, 2]).isoWeek(),  1, 'Jan  2 2012 should be iso week 1');\n    assert.equal(moment([2012, 0, 8]).isoWeek(),  1, 'Jan  8 2012 should be iso week 1');\n    assert.equal(moment([2012, 0, 9]).isoWeek(),  2, 'Jan  9 2012 should be iso week 2');\n    assert.equal(moment([2012, 0, 15]).isoWeek(), 2, 'Jan 15 2012 should be iso week 2');\n});\n\ntest('iso weeks year starting monday', function (assert) {\n    assert.equal(moment([2007, 0, 1]).isoWeek(),  1, 'Jan  1 2007 should be iso week 1');\n    assert.equal(moment([2007, 0, 7]).isoWeek(),  1, 'Jan  7 2007 should be iso week 1');\n    assert.equal(moment([2007, 0, 8]).isoWeek(),  2, 'Jan  8 2007 should be iso week 2');\n    assert.equal(moment([2007, 0, 14]).isoWeek(), 2, 'Jan 14 2007 should be iso week 2');\n    assert.equal(moment([2007, 0, 15]).isoWeek(), 3, 'Jan 15 2007 should be iso week 3');\n});\n\ntest('iso weeks year starting tuesday', function (assert) {\n    assert.equal(moment([2007, 11, 31]).isoWeek(), 1, 'Dec 31 2007 should be iso week 1');\n    assert.equal(moment([2008,  0,  1]).isoWeek(), 1, 'Jan  1 2008 should be iso week 1');\n    assert.equal(moment([2008,  0,  6]).isoWeek(), 1, 'Jan  6 2008 should be iso week 1');\n    assert.equal(moment([2008,  0,  7]).isoWeek(), 2, 'Jan  7 2008 should be iso week 2');\n    assert.equal(moment([2008,  0, 13]).isoWeek(), 2, 'Jan 13 2008 should be iso week 2');\n    assert.equal(moment([2008,  0, 14]).isoWeek(), 3, 'Jan 14 2008 should be iso week 3');\n});\n\ntest('iso weeks year starting wednesday', function (assert) {\n    assert.equal(moment([2002, 11, 30]).isoWeek(), 1, 'Dec 30 2002 should be iso week 1');\n    assert.equal(moment([2003,  0,  1]).isoWeek(), 1, 'Jan  1 2003 should be iso week 1');\n    assert.equal(moment([2003,  0,  5]).isoWeek(), 1, 'Jan  5 2003 should be iso week 1');\n    assert.equal(moment([2003,  0,  6]).isoWeek(), 2, 'Jan  6 2003 should be iso week 2');\n    assert.equal(moment([2003,  0, 12]).isoWeek(), 2, 'Jan 12 2003 should be iso week 2');\n    assert.equal(moment([2003,  0, 13]).isoWeek(), 3, 'Jan 13 2003 should be iso week 3');\n});\n\ntest('iso weeks year starting thursday', function (assert) {\n    assert.equal(moment([2008, 11, 29]).isoWeek(), 1, 'Dec 29 2008 should be iso week 1');\n    assert.equal(moment([2009,  0,  1]).isoWeek(), 1, 'Jan  1 2009 should be iso week 1');\n    assert.equal(moment([2009,  0,  4]).isoWeek(), 1, 'Jan  4 2009 should be iso week 1');\n    assert.equal(moment([2009,  0,  5]).isoWeek(), 2, 'Jan  5 2009 should be iso week 2');\n    assert.equal(moment([2009,  0, 11]).isoWeek(), 2, 'Jan 11 2009 should be iso week 2');\n    assert.equal(moment([2009,  0, 13]).isoWeek(), 3, 'Jan 12 2009 should be iso week 3');\n});\n\ntest('iso weeks year starting friday', function (assert) {\n    assert.equal(moment([2009, 11, 28]).isoWeek(), 53, 'Dec 28 2009 should be iso week 53');\n    assert.equal(moment([2010,  0,  1]).isoWeek(), 53, 'Jan  1 2010 should be iso week 53');\n    assert.equal(moment([2010,  0,  3]).isoWeek(), 53, 'Jan  3 2010 should be iso week 53');\n    assert.equal(moment([2010,  0,  4]).isoWeek(),  1, 'Jan  4 2010 should be iso week 1');\n    assert.equal(moment([2010,  0, 10]).isoWeek(),  1, 'Jan 10 2010 should be iso week 1');\n    assert.equal(moment([2010,  0, 11]).isoWeek(),  2, 'Jan 11 2010 should be iso week 2');\n});\n\ntest('iso weeks year starting saturday', function (assert) {\n    assert.equal(moment([2010, 11, 27]).isoWeek(), 52, 'Dec 27 2010 should be iso week 52');\n    assert.equal(moment([2011,  0,  1]).isoWeek(), 52, 'Jan  1 2011 should be iso week 52');\n    assert.equal(moment([2011,  0,  2]).isoWeek(), 52, 'Jan  2 2011 should be iso week 52');\n    assert.equal(moment([2011,  0,  3]).isoWeek(),  1, 'Jan  3 2011 should be iso week 1');\n    assert.equal(moment([2011,  0,  9]).isoWeek(),  1, 'Jan  9 2011 should be iso week 1');\n    assert.equal(moment([2011,  0, 10]).isoWeek(),  2, 'Jan 10 2011 should be iso week 2');\n});\n\ntest('iso weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2012, 0,  1]).format('W WW Wo'), '52 52 52nd', 'Jan  1 2012 should be iso week 52');\n    assert.equal(moment([2012, 0,  2]).format('W WW Wo'),   '1 01 1st', 'Jan  2 2012 should be iso week 1');\n    assert.equal(moment([2012, 0,  8]).format('W WW Wo'),   '1 01 1st', 'Jan  8 2012 should be iso week 1');\n    assert.equal(moment([2012, 0,  9]).format('W WW Wo'),   '2 02 2nd', 'Jan  9 2012 should be iso week 2');\n    assert.equal(moment([2012, 0, 15]).format('W WW Wo'),   '2 02 2nd', 'Jan 15 2012 should be iso week 2');\n});\n\ntest('weeks plural year starting sunday', function (assert) {\n    assert.equal(moment([2012, 0,  1]).weeks(), 1, 'Jan  1 2012 should be week 1');\n    assert.equal(moment([2012, 0,  7]).weeks(), 1, 'Jan  7 2012 should be week 1');\n    assert.equal(moment([2012, 0,  8]).weeks(), 2, 'Jan  8 2012 should be week 2');\n    assert.equal(moment([2012, 0, 14]).weeks(), 2, 'Jan 14 2012 should be week 2');\n    assert.equal(moment([2012, 0, 15]).weeks(), 3, 'Jan 15 2012 should be week 3');\n});\n\ntest('iso weeks plural year starting sunday', function (assert) {\n    assert.equal(moment([2012, 0, 1]).isoWeeks(), 52, 'Jan  1 2012 should be iso week 52');\n    assert.equal(moment([2012, 0, 2]).isoWeeks(),  1, 'Jan  2 2012 should be iso week 1');\n    assert.equal(moment([2012, 0, 8]).isoWeeks(),  1, 'Jan  8 2012 should be iso week 1');\n    assert.equal(moment([2012, 0, 9]).isoWeeks(),  2, 'Jan  9 2012 should be iso week 2');\n    assert.equal(moment([2012, 0, 15]).isoWeeks(), 2, 'Jan 15 2012 should be iso week 2');\n});\n\ntest('weeks setter', function (assert) {\n    assert.equal(moment([2012, 0,  1]).week(30).week(), 30, 'Setting Jan 1 2012 to week 30 should work');\n    assert.equal(moment([2012, 0,  7]).week(30).week(), 30, 'Setting Jan 7 2012 to week 30 should work');\n    assert.equal(moment([2012, 0,  8]).week(30).week(), 30, 'Setting Jan 8 2012 to week 30 should work');\n    assert.equal(moment([2012, 0, 14]).week(30).week(), 30, 'Setting Jan 14 2012 to week 30 should work');\n    assert.equal(moment([2012, 0, 15]).week(30).week(), 30, 'Setting Jan 15 2012 to week 30 should work');\n});\n\ntest('iso weeks setter', function (assert) {\n    assert.equal(moment([2012, 0,  1]).isoWeeks(25).isoWeeks(), 25, 'Setting Jan  1 2012 to week 25 should work');\n    assert.equal(moment([2012, 0,  2]).isoWeeks(24).isoWeeks(), 24, 'Setting Jan  2 2012 to week 24 should work');\n    assert.equal(moment([2012, 0,  8]).isoWeeks(23).isoWeeks(), 23, 'Setting Jan  8 2012 to week 23 should work');\n    assert.equal(moment([2012, 0,  9]).isoWeeks(22).isoWeeks(), 22, 'Setting Jan  9 2012 to week 22 should work');\n    assert.equal(moment([2012, 0, 15]).isoWeeks(21).isoWeeks(), 21, 'Setting Jan 15 2012 to week 21 should work');\n});\n\ntest('iso weeks setter day of year', function (assert) {\n    assert.equal(moment([2012, 0,  1]).isoWeek(1).dayOfYear(), 9, 'Setting Jan  1 2012 to week 1 should be day of year 8');\n    assert.equal(moment([2012, 0,  1]).isoWeek(1).year(),   2011, 'Setting Jan  1 2012 to week 1 should be year 2011');\n    assert.equal(moment([2012, 0,  2]).isoWeek(1).dayOfYear(), 2, 'Setting Jan  2 2012 to week 1 should be day of year 2');\n    assert.equal(moment([2012, 0,  8]).isoWeek(1).dayOfYear(), 8, 'Setting Jan  8 2012 to week 1 should be day of year 8');\n    assert.equal(moment([2012, 0,  9]).isoWeek(1).dayOfYear(), 2, 'Setting Jan  9 2012 to week 1 should be day of year 2');\n    assert.equal(moment([2012, 0, 15]).isoWeek(1).dayOfYear(), 8, 'Setting Jan 15 2012 to week 1 should be day of year 8');\n});\n\ntest('years with iso week 53', function (assert) {\n    // Based on a table taken from https://en.wikipedia.org/wiki/ISO_week_date\n    // (as downloaded on 2014-01-06) listing the 71 years in a 400-year cycle\n    // that have 53 weeks; in this case reflecting the 2000 based cycle\n    assert.equal(moment([2004, 11, 31]).isoWeek(), 53, 'Dec 31 2004 should be iso week 53');\n    assert.equal(moment([2009, 11, 31]).isoWeek(), 53, 'Dec 31 2009 should be iso week 53');\n    assert.equal(moment([2015, 11, 31]).isoWeek(), 53, 'Dec 31 2015 should be iso week 53');\n    assert.equal(moment([2020, 11, 31]).isoWeek(), 53, 'Dec 31 2020 should be iso week 53');\n    assert.equal(moment([2026, 11, 31]).isoWeek(), 53, 'Dec 31 2026 should be iso week 53');\n    assert.equal(moment([2032, 11, 31]).isoWeek(), 53, 'Dec 31 2032 should be iso week 53');\n    assert.equal(moment([2037, 11, 31]).isoWeek(), 53, 'Dec 31 2037 should be iso week 53');\n    assert.equal(moment([2043, 11, 31]).isoWeek(), 53, 'Dec 31 2043 should be iso week 53');\n    assert.equal(moment([2048, 11, 31]).isoWeek(), 53, 'Dec 31 2048 should be iso week 53');\n    assert.equal(moment([2054, 11, 31]).isoWeek(), 53, 'Dec 31 2054 should be iso week 53');\n    assert.equal(moment([2060, 11, 31]).isoWeek(), 53, 'Dec 31 2060 should be iso week 53');\n    assert.equal(moment([2065, 11, 31]).isoWeek(), 53, 'Dec 31 2065 should be iso week 53');\n    assert.equal(moment([2071, 11, 31]).isoWeek(), 53, 'Dec 31 2071 should be iso week 53');\n    assert.equal(moment([2076, 11, 31]).isoWeek(), 53, 'Dec 31 2076 should be iso week 53');\n    assert.equal(moment([2082, 11, 31]).isoWeek(), 53, 'Dec 31 2082 should be iso week 53');\n    assert.equal(moment([2088, 11, 31]).isoWeek(), 53, 'Dec 31 2088 should be iso week 53');\n    assert.equal(moment([2093, 11, 31]).isoWeek(), 53, 'Dec 31 2093 should be iso week 53');\n    assert.equal(moment([2099, 11, 31]).isoWeek(), 53, 'Dec 31 2099 should be iso week 53');\n    assert.equal(moment([2105, 11, 31]).isoWeek(), 53, 'Dec 31 2105 should be iso week 53');\n    assert.equal(moment([2111, 11, 31]).isoWeek(), 53, 'Dec 31 2111 should be iso week 53');\n    assert.equal(moment([2116, 11, 31]).isoWeek(), 53, 'Dec 31 2116 should be iso week 53');\n    assert.equal(moment([2122, 11, 31]).isoWeek(), 53, 'Dec 31 2122 should be iso week 53');\n    assert.equal(moment([2128, 11, 31]).isoWeek(), 53, 'Dec 31 2128 should be iso week 53');\n    assert.equal(moment([2133, 11, 31]).isoWeek(), 53, 'Dec 31 2133 should be iso week 53');\n    assert.equal(moment([2139, 11, 31]).isoWeek(), 53, 'Dec 31 2139 should be iso week 53');\n    assert.equal(moment([2144, 11, 31]).isoWeek(), 53, 'Dec 31 2144 should be iso week 53');\n    assert.equal(moment([2150, 11, 31]).isoWeek(), 53, 'Dec 31 2150 should be iso week 53');\n    assert.equal(moment([2156, 11, 31]).isoWeek(), 53, 'Dec 31 2156 should be iso week 53');\n    assert.equal(moment([2161, 11, 31]).isoWeek(), 53, 'Dec 31 2161 should be iso week 53');\n    assert.equal(moment([2167, 11, 31]).isoWeek(), 53, 'Dec 31 2167 should be iso week 53');\n    assert.equal(moment([2172, 11, 31]).isoWeek(), 53, 'Dec 31 2172 should be iso week 53');\n    assert.equal(moment([2178, 11, 31]).isoWeek(), 53, 'Dec 31 2178 should be iso week 53');\n    assert.equal(moment([2184, 11, 31]).isoWeek(), 53, 'Dec 31 2184 should be iso week 53');\n    assert.equal(moment([2189, 11, 31]).isoWeek(), 53, 'Dec 31 2189 should be iso week 53');\n    assert.equal(moment([2195, 11, 31]).isoWeek(), 53, 'Dec 31 2195 should be iso week 53');\n    assert.equal(moment([2201, 11, 31]).isoWeek(), 53, 'Dec 31 2201 should be iso week 53');\n    assert.equal(moment([2207, 11, 31]).isoWeek(), 53, 'Dec 31 2207 should be iso week 53');\n    assert.equal(moment([2212, 11, 31]).isoWeek(), 53, 'Dec 31 2212 should be iso week 53');\n    assert.equal(moment([2218, 11, 31]).isoWeek(), 53, 'Dec 31 2218 should be iso week 53');\n    assert.equal(moment([2224, 11, 31]).isoWeek(), 53, 'Dec 31 2224 should be iso week 53');\n    assert.equal(moment([2229, 11, 31]).isoWeek(), 53, 'Dec 31 2229 should be iso week 53');\n    assert.equal(moment([2235, 11, 31]).isoWeek(), 53, 'Dec 31 2235 should be iso week 53');\n    assert.equal(moment([2240, 11, 31]).isoWeek(), 53, 'Dec 31 2240 should be iso week 53');\n    assert.equal(moment([2246, 11, 31]).isoWeek(), 53, 'Dec 31 2246 should be iso week 53');\n    assert.equal(moment([2252, 11, 31]).isoWeek(), 53, 'Dec 31 2252 should be iso week 53');\n    assert.equal(moment([2257, 11, 31]).isoWeek(), 53, 'Dec 31 2257 should be iso week 53');\n    assert.equal(moment([2263, 11, 31]).isoWeek(), 53, 'Dec 31 2263 should be iso week 53');\n    assert.equal(moment([2268, 11, 31]).isoWeek(), 53, 'Dec 31 2268 should be iso week 53');\n    assert.equal(moment([2274, 11, 31]).isoWeek(), 53, 'Dec 31 2274 should be iso week 53');\n    assert.equal(moment([2280, 11, 31]).isoWeek(), 53, 'Dec 31 2280 should be iso week 53');\n    assert.equal(moment([2285, 11, 31]).isoWeek(), 53, 'Dec 31 2285 should be iso week 53');\n    assert.equal(moment([2291, 11, 31]).isoWeek(), 53, 'Dec 31 2291 should be iso week 53');\n    assert.equal(moment([2296, 11, 31]).isoWeek(), 53, 'Dec 31 2296 should be iso week 53');\n    assert.equal(moment([2303, 11, 31]).isoWeek(), 53, 'Dec 31 2303 should be iso week 53');\n    assert.equal(moment([2308, 11, 31]).isoWeek(), 53, 'Dec 31 2308 should be iso week 53');\n    assert.equal(moment([2314, 11, 31]).isoWeek(), 53, 'Dec 31 2314 should be iso week 53');\n    assert.equal(moment([2320, 11, 31]).isoWeek(), 53, 'Dec 31 2320 should be iso week 53');\n    assert.equal(moment([2325, 11, 31]).isoWeek(), 53, 'Dec 31 2325 should be iso week 53');\n    assert.equal(moment([2331, 11, 31]).isoWeek(), 53, 'Dec 31 2331 should be iso week 53');\n    assert.equal(moment([2336, 11, 31]).isoWeek(), 53, 'Dec 31 2336 should be iso week 53');\n    assert.equal(moment([2342, 11, 31]).isoWeek(), 53, 'Dec 31 2342 should be iso week 53');\n    assert.equal(moment([2348, 11, 31]).isoWeek(), 53, 'Dec 31 2348 should be iso week 53');\n    assert.equal(moment([2353, 11, 31]).isoWeek(), 53, 'Dec 31 2353 should be iso week 53');\n    assert.equal(moment([2359, 11, 31]).isoWeek(), 53, 'Dec 31 2359 should be iso week 53');\n    assert.equal(moment([2364, 11, 31]).isoWeek(), 53, 'Dec 31 2364 should be iso week 53');\n    assert.equal(moment([2370, 11, 31]).isoWeek(), 53, 'Dec 31 2370 should be iso week 53');\n    assert.equal(moment([2376, 11, 31]).isoWeek(), 53, 'Dec 31 2376 should be iso week 53');\n    assert.equal(moment([2381, 11, 31]).isoWeek(), 53, 'Dec 31 2381 should be iso week 53');\n    assert.equal(moment([2387, 11, 31]).isoWeek(), 53, 'Dec 31 2387 should be iso week 53');\n    assert.equal(moment([2392, 11, 31]).isoWeek(), 53, 'Dec 31 2392 should be iso week 53');\n    assert.equal(moment([2398, 11, 31]).isoWeek(), 53, 'Dec 31 2398 should be iso week 53');\n});\n\ntest('count years with iso week 53', function (assert) {\n    // Based on https://en.wikipedia.org/wiki/ISO_week_date (as seen on 2014-01-06)\n    // stating that there are 71 years in a 400-year cycle that have 53 weeks;\n    // in this case reflecting the 2000 based cycle\n    var count = 0, i;\n    for (i = 0; i < 400; i++) {\n        count += (moment([2000 + i, 11, 31]).isoWeek() === 53) ? 1 : 0;\n    }\n    assert.equal(count, 71, 'Should have 71 years in 400-year cycle with iso week 53');\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\nfunction module$1 (name, lifecycle) {\n    QUnit.module(name, {\n        setup : function () {\n            moment.locale('en');\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'core');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            teardownDeprecationHandler(test, moment, 'core');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n}\n\nmodule$1('weeks in year');\n\ntest('isoWeeksInYear', function (assert) {\n    assert.equal(moment([2004]).isoWeeksInYear(), 53, '2004 has 53 iso weeks');\n    assert.equal(moment([2005]).isoWeeksInYear(), 52, '2005 has 53 iso weeks');\n    assert.equal(moment([2006]).isoWeeksInYear(), 52, '2006 has 53 iso weeks');\n    assert.equal(moment([2007]).isoWeeksInYear(), 52, '2007 has 52 iso weeks');\n    assert.equal(moment([2008]).isoWeeksInYear(), 52, '2008 has 53 iso weeks');\n    assert.equal(moment([2009]).isoWeeksInYear(), 53, '2009 has 53 iso weeks');\n    assert.equal(moment([2010]).isoWeeksInYear(), 52, '2010 has 52 iso weeks');\n    assert.equal(moment([2011]).isoWeeksInYear(), 52, '2011 has 52 iso weeks');\n    assert.equal(moment([2012]).isoWeeksInYear(), 52, '2012 has 52 iso weeks');\n    assert.equal(moment([2013]).isoWeeksInYear(), 52, '2013 has 52 iso weeks');\n    assert.equal(moment([2014]).isoWeeksInYear(), 52, '2014 has 52 iso weeks');\n    assert.equal(moment([2015]).isoWeeksInYear(), 53, '2015 has 53 iso weeks');\n});\n\ntest('weeksInYear doy/dow = 1/4', function (assert) {\n    moment.locale('1/4', {week: {dow: 1, doy: 4}});\n\n    assert.equal(moment([2004]).weeksInYear(), 53, '2004 has 53 weeks');\n    assert.equal(moment([2005]).weeksInYear(), 52, '2005 has 53 weeks');\n    assert.equal(moment([2006]).weeksInYear(), 52, '2006 has 53 weeks');\n    assert.equal(moment([2007]).weeksInYear(), 52, '2007 has 52 weeks');\n    assert.equal(moment([2008]).weeksInYear(), 52, '2008 has 53 weeks');\n    assert.equal(moment([2009]).weeksInYear(), 53, '2009 has 53 weeks');\n    assert.equal(moment([2010]).weeksInYear(), 52, '2010 has 52 weeks');\n    assert.equal(moment([2011]).weeksInYear(), 52, '2011 has 52 weeks');\n    assert.equal(moment([2012]).weeksInYear(), 52, '2012 has 52 weeks');\n    assert.equal(moment([2013]).weeksInYear(), 52, '2013 has 52 weeks');\n    assert.equal(moment([2014]).weeksInYear(), 52, '2014 has 52 weeks');\n    assert.equal(moment([2015]).weeksInYear(), 53, '2015 has 53 weeks');\n});\n\ntest('weeksInYear doy/dow = 6/12', function (assert) {\n    moment.locale('6/12', {week: {dow: 6, doy: 12}});\n\n    assert.equal(moment([2004]).weeksInYear(), 53, '2004 has 53 weeks');\n    assert.equal(moment([2005]).weeksInYear(), 52, '2005 has 53 weeks');\n    assert.equal(moment([2006]).weeksInYear(), 52, '2006 has 53 weeks');\n    assert.equal(moment([2007]).weeksInYear(), 52, '2007 has 52 weeks');\n    assert.equal(moment([2008]).weeksInYear(), 52, '2008 has 53 weeks');\n    assert.equal(moment([2009]).weeksInYear(), 52, '2009 has 53 weeks');\n    assert.equal(moment([2010]).weeksInYear(), 53, '2010 has 52 weeks');\n    assert.equal(moment([2011]).weeksInYear(), 52, '2011 has 52 weeks');\n    assert.equal(moment([2012]).weeksInYear(), 52, '2012 has 52 weeks');\n    assert.equal(moment([2013]).weeksInYear(), 52, '2013 has 52 weeks');\n    assert.equal(moment([2014]).weeksInYear(), 52, '2014 has 52 weeks');\n    assert.equal(moment([2015]).weeksInYear(), 52, '2015 has 53 weeks');\n});\n\ntest('weeksInYear doy/dow = 1/7', function (assert) {\n    moment.locale('1/7', {week: {dow: 1, doy: 7}});\n\n    assert.equal(moment([2004]).weeksInYear(), 52, '2004 has 53 weeks');\n    assert.equal(moment([2005]).weeksInYear(), 52, '2005 has 53 weeks');\n    assert.equal(moment([2006]).weeksInYear(), 53, '2006 has 53 weeks');\n    assert.equal(moment([2007]).weeksInYear(), 52, '2007 has 52 weeks');\n    assert.equal(moment([2008]).weeksInYear(), 52, '2008 has 53 weeks');\n    assert.equal(moment([2009]).weeksInYear(), 52, '2009 has 53 weeks');\n    assert.equal(moment([2010]).weeksInYear(), 52, '2010 has 52 weeks');\n    assert.equal(moment([2011]).weeksInYear(), 52, '2011 has 52 weeks');\n    assert.equal(moment([2012]).weeksInYear(), 53, '2012 has 52 weeks');\n    assert.equal(moment([2013]).weeksInYear(), 52, '2013 has 52 weeks');\n    assert.equal(moment([2014]).weeksInYear(), 52, '2014 has 52 weeks');\n    assert.equal(moment([2015]).weeksInYear(), 52, '2015 has 53 weeks');\n});\n\ntest('weeksInYear doy/dow = 0/6', function (assert) {\n    moment.locale('0/6', {week: {dow: 0, doy: 6}});\n\n    assert.equal(moment([2004]).weeksInYear(), 52, '2004 has 53 weeks');\n    assert.equal(moment([2005]).weeksInYear(), 53, '2005 has 53 weeks');\n    assert.equal(moment([2006]).weeksInYear(), 52, '2006 has 53 weeks');\n    assert.equal(moment([2007]).weeksInYear(), 52, '2007 has 52 weeks');\n    assert.equal(moment([2008]).weeksInYear(), 52, '2008 has 53 weeks');\n    assert.equal(moment([2009]).weeksInYear(), 52, '2009 has 53 weeks');\n    assert.equal(moment([2010]).weeksInYear(), 52, '2010 has 52 weeks');\n    assert.equal(moment([2011]).weeksInYear(), 53, '2011 has 52 weeks');\n    assert.equal(moment([2012]).weeksInYear(), 52, '2012 has 52 weeks');\n    assert.equal(moment([2013]).weeksInYear(), 52, '2013 has 52 weeks');\n    assert.equal(moment([2014]).weeksInYear(), 52, '2014 has 52 weeks');\n    assert.equal(moment([2015]).weeksInYear(), 52, '2015 has 53 weeks');\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\nfunction module$1 (name, lifecycle) {\n    QUnit.module(name, {\n        setup : function () {\n            moment.locale('en');\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'core');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            teardownDeprecationHandler(test, moment, 'core');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n}\n\nfunction isNearSpringDST() {\n    return moment().subtract(1, 'day').utcOffset() !== moment().add(1, 'day').utcOffset();\n}\n\nmodule$1('zone switching');\n\ntest('local to utc, keepLocalTime = true', function (assert) {\n    var m = moment(),\n        fmt = 'YYYY-DD-MM HH:mm:ss';\n    assert.equal(m.clone().utc(true).format(fmt), m.format(fmt), 'local to utc failed to keep local time');\n});\n\ntest('local to utc, keepLocalTime = false', function (assert) {\n    var m = moment();\n    assert.equal(m.clone().utc().valueOf(), m.valueOf(), 'local to utc failed to keep utc time (implicit)');\n    assert.equal(m.clone().utc(false).valueOf(), m.valueOf(), 'local to utc failed to keep utc time (explicit)');\n});\n\ntest('local to zone, keepLocalTime = true', function (assert) {\n    test.expectedDeprecations('moment().zone');\n    var m = moment(),\n        fmt = 'YYYY-DD-MM HH:mm:ss',\n        z;\n\n    // Apparently there is -12:00 and +14:00\n    // https://en.wikipedia.org/wiki/UTC+14:00\n    // https://en.wikipedia.org/wiki/UTC-12:00\n    for (z = -12; z <= 14; ++z) {\n        assert.equal(m.clone().zone(z * 60, true).format(fmt), m.format(fmt),\n                'local to zone(' + z + ':00) failed to keep local time');\n    }\n});\n\ntest('local to zone, keepLocalTime = false', function (assert) {\n    test.expectedDeprecations('moment().zone');\n    var m = moment(),\n        z;\n\n    // Apparently there is -12:00 and +14:00\n    // https://en.wikipedia.org/wiki/UTC+14:00\n    // https://en.wikipedia.org/wiki/UTC-12:00\n    for (z = -12; z <= 14; ++z) {\n        assert.equal(m.clone().zone(z * 60).valueOf(), m.valueOf(),\n                'local to zone(' + z + ':00) failed to keep utc time (implicit)');\n        assert.equal(m.clone().zone(z * 60, false).valueOf(), m.valueOf(),\n                'local to zone(' + z + ':00) failed to keep utc time (explicit)');\n    }\n});\n\ntest('utc to local, keepLocalTime = true', function (assert) {\n    // Don't test near the spring DST transition\n    if (isNearSpringDST()) {\n        expect(0);\n        return;\n    }\n\n    var um = moment.utc(),\n        fmt = 'YYYY-DD-MM HH:mm:ss';\n\n    assert.equal(um.clone().local(true).format(fmt), um.format(fmt), 'utc to local failed to keep local time');\n});\n\ntest('utc to local, keepLocalTime = false', function (assert) {\n    var um = moment.utc();\n    assert.equal(um.clone().local().valueOf(), um.valueOf(), 'utc to local failed to keep utc time (implicit)');\n    assert.equal(um.clone().local(false).valueOf(), um.valueOf(), 'utc to local failed to keep utc time (explicit)');\n});\n\ntest('zone to local, keepLocalTime = true', function (assert) {\n    // Don't test near the spring DST transition\n    if (isNearSpringDST()) {\n        expect(0);\n        return;\n    }\n\n    test.expectedDeprecations('moment().zone');\n\n    var m = moment(),\n        fmt = 'YYYY-DD-MM HH:mm:ss',\n        z;\n\n    // Apparently there is -12:00 and +14:00\n    // https://en.wikipedia.org/wiki/UTC+14:00\n    // https://en.wikipedia.org/wiki/UTC-12:00\n    for (z = -12; z <= 14; ++z) {\n        m.zone(z * 60);\n\n        assert.equal(m.clone().local(true).format(fmt), m.format(fmt),\n                'zone(' + z + ':00) to local failed to keep local time');\n    }\n});\n\ntest('zone to local, keepLocalTime = false', function (assert) {\n    test.expectedDeprecations('moment().zone');\n    var m = moment(),\n        z;\n\n    // Apparently there is -12:00 and +14:00\n    // https://en.wikipedia.org/wiki/UTC+14:00\n    // https://en.wikipedia.org/wiki/UTC-12:00\n    for (z = -12; z <= 14; ++z) {\n        m.zone(z * 60);\n\n        assert.equal(m.clone().local(false).valueOf(), m.valueOf(),\n                'zone(' + z + ':00) to local failed to keep utc time (explicit)');\n        assert.equal(m.clone().local().valueOf(), m.valueOf(),\n                'zone(' + z + ':00) to local failed to keep utc time (implicit)');\n    }\n});\n\n})));\n\n\n;(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n\nfunction each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nfunction objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n\n// Pick the first defined of two or three arguments.\n\nfunction defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\nfunction setupDeprecationHandler(test, moment$$1, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment$$1.suppressDeprecationWarnings;\n    moment$$1.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment$$1.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nfunction teardownDeprecationHandler(test, moment$$1, scope) {\n    moment$$1.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/*global QUnit:false*/\n\nvar test = QUnit.test;\n\nvar expect = QUnit.expect;\n\nfunction module$1 (name, lifecycle) {\n    QUnit.module(name, {\n        setup : function () {\n            moment.locale('en');\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'core');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            teardownDeprecationHandler(test, moment, 'core');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n}\n\nmodule$1('zones', {\n    'setup': function () {\n        test.expectedDeprecations('moment().zone');\n    }\n});\n\ntest('set zone', function (assert) {\n    var zone = moment();\n\n    zone.zone(0);\n    assert.equal(zone.zone(), 0, 'should be able to set the zone to 0');\n\n    zone.zone(60);\n    assert.equal(zone.zone(), 60, 'should be able to set the zone to 60');\n\n    zone.zone(-60);\n    assert.equal(zone.zone(), -60, 'should be able to set the zone to -60');\n});\n\ntest('set zone shorthand', function (assert) {\n    var zone = moment();\n\n    zone.zone(1);\n    assert.equal(zone.zone(), 60, 'setting the zone to 1 should imply hours and convert to 60');\n\n    zone.zone(-1);\n    assert.equal(zone.zone(), -60, 'setting the zone to -1 should imply hours and convert to -60');\n\n    zone.zone(15);\n    assert.equal(zone.zone(), 900, 'setting the zone to 15 should imply hours and convert to 900');\n\n    zone.zone(-15);\n    assert.equal(zone.zone(), -900, 'setting the zone to -15 should imply hours and convert to -900');\n\n    zone.zone(16);\n    assert.equal(zone.zone(), 16, 'setting the zone to 16 should imply minutes');\n\n    zone.zone(-16);\n    assert.equal(zone.zone(), -16, 'setting the zone to -16 should imply minutes');\n});\n\ntest('set zone with string', function (assert) {\n    var zone = moment();\n\n    zone.zone('+00:00');\n    assert.equal(zone.zone(), 0, 'set the zone with a timezone string');\n\n    zone.zone('2013-03-07T07:00:00-08:00');\n    assert.equal(zone.zone(), 480, 'set the zone with a string that does not begin with the timezone');\n\n    zone.zone('2013-03-07T07:00:00+0100');\n    assert.equal(zone.zone(), -60, 'set the zone with a string that uses the +0000 syntax');\n\n    zone.zone('2013-03-07T07:00:00+02');\n    assert.equal(zone.zone(), -120, 'set the zone with a string that uses the +00 syntax');\n\n    zone.zone('03-07-2013T07:00:00-08:00');\n    assert.equal(zone.zone(), 480, 'set the zone with a string with a non-ISO 8601 date');\n});\n\ntest('change hours when changing the zone', function (assert) {\n    var zone = moment.utc([2000, 0, 1, 6]);\n\n    zone.zone(0);\n    assert.equal(zone.hour(), 6, 'UTC 6AM should be 6AM at +0000');\n\n    zone.zone(60);\n    assert.equal(zone.hour(), 5, 'UTC 6AM should be 5AM at -0100');\n\n    zone.zone(-60);\n    assert.equal(zone.hour(), 7, 'UTC 6AM should be 7AM at +0100');\n});\n\ntest('change minutes when changing the zone', function (assert) {\n    var zone = moment.utc([2000, 0, 1, 6, 31]);\n\n    zone.zone(0);\n    assert.equal(zone.format('HH:mm'), '06:31', 'UTC 6:31AM should be 6:31AM at +0000');\n\n    zone.zone(30);\n    assert.equal(zone.format('HH:mm'), '06:01', 'UTC 6:31AM should be 6:01AM at -0030');\n\n    zone.zone(-30);\n    assert.equal(zone.format('HH:mm'), '07:01', 'UTC 6:31AM should be 7:01AM at +0030');\n\n    zone.zone(1380);\n    assert.equal(zone.format('HH:mm'), '07:31', 'UTC 6:31AM should be 7:31AM at +1380');\n});\n\ntest('distance from the unix epoch', function (assert) {\n    var zoneA = moment(),\n        zoneB = moment(zoneA),\n        zoneC = moment(zoneA),\n        zoneD = moment(zoneA),\n        zoneE = moment(zoneA);\n\n    zoneB.utc();\n    assert.equal(+zoneA, +zoneB, 'moment should equal moment.utc');\n\n    zoneC.zone(-60);\n    assert.equal(+zoneA, +zoneC, 'moment should equal moment.zone(-60)');\n\n    zoneD.zone(480);\n    assert.equal(+zoneA, +zoneD, 'moment should equal moment.zone(480)');\n\n    zoneE.zone(1000);\n    assert.equal(+zoneA, +zoneE, 'moment should equal moment.zone(1000)');\n});\n\ntest('update offset after changing any values', function (assert) {\n    var oldOffset = moment.updateOffset,\n        m = moment.utc([2000, 6, 1]);\n\n    moment.updateOffset = function (mom, keepTime) {\n        if (mom.__doChange) {\n            if (+mom > 962409600000) {\n                mom.zone(120, keepTime);\n            } else {\n                mom.zone(60, keepTime);\n            }\n        }\n    };\n\n    assert.equal(m.format('ZZ'), '+0000', 'should be at +0000');\n    assert.equal(m.format('HH:mm'), '00:00', 'should start 12AM at +0000 timezone');\n\n    m.__doChange = true;\n    m.add(1, 'h');\n\n    assert.equal(m.format('ZZ'), '-0200', 'should be at -0200');\n    assert.equal(m.format('HH:mm'), '23:00', '1AM at +0000 should be 11PM at -0200 timezone');\n\n    m.subtract(1, 'h');\n\n    assert.equal(m.format('ZZ'), '-0100', 'should be at -0100');\n    assert.equal(m.format('HH:mm'), '23:00', '12AM at +0000 should be 11PM at -0100 timezone');\n\n    moment.updateOffset = oldOffset;\n});\n\ntest('getters and setters', function (assert) {\n    var a = moment([2011, 5, 20]);\n\n    assert.equal(a.clone().zone(120).year(2012).year(), 2012, 'should get and set year correctly');\n    assert.equal(a.clone().zone(120).month(1).month(), 1, 'should get and set month correctly');\n    assert.equal(a.clone().zone(120).date(2).date(), 2, 'should get and set date correctly');\n    assert.equal(a.clone().zone(120).day(1).day(), 1, 'should get and set day correctly');\n    assert.equal(a.clone().zone(120).hour(1).hour(), 1, 'should get and set hour correctly');\n    assert.equal(a.clone().zone(120).minute(1).minute(), 1, 'should get and set minute correctly');\n});\n\ntest('getters', function (assert) {\n    var a = moment.utc([2012, 0, 1, 0, 0, 0]);\n\n    assert.equal(a.clone().zone(120).year(),  2011, 'should get year correctly');\n    assert.equal(a.clone().zone(120).month(),   11, 'should get month correctly');\n    assert.equal(a.clone().zone(120).date(),    31, 'should get date correctly');\n    assert.equal(a.clone().zone(120).hour(),    22, 'should get hour correctly');\n    assert.equal(a.clone().zone(120).minute(),   0, 'should get minute correctly');\n\n    assert.equal(a.clone().zone(-120).year(),  2012, 'should get year correctly');\n    assert.equal(a.clone().zone(-120).month(),    0, 'should get month correctly');\n    assert.equal(a.clone().zone(-120).date(),     1, 'should get date correctly');\n    assert.equal(a.clone().zone(-120).hour(),     2, 'should get hour correctly');\n    assert.equal(a.clone().zone(-120).minute(),   0, 'should get minute correctly');\n\n    assert.equal(a.clone().zone(-90).year(),  2012, 'should get year correctly');\n    assert.equal(a.clone().zone(-90).month(),    0, 'should get month correctly');\n    assert.equal(a.clone().zone(-90).date(),     1, 'should get date correctly');\n    assert.equal(a.clone().zone(-90).hour(),     1, 'should get hour correctly');\n    assert.equal(a.clone().zone(-90).minute(),  30, 'should get minute correctly');\n});\n\ntest('from', function (assert) {\n    var zoneA = moment(),\n        zoneB = moment(zoneA).zone(720),\n        zoneC = moment(zoneA).zone(360),\n        zoneD = moment(zoneA).zone(-690),\n        other = moment(zoneA).add(35, 'm');\n\n    assert.equal(zoneA.from(other), zoneB.from(other), 'moment#from should be the same in all zones');\n    assert.equal(zoneA.from(other), zoneC.from(other), 'moment#from should be the same in all zones');\n    assert.equal(zoneA.from(other), zoneD.from(other), 'moment#from should be the same in all zones');\n});\n\ntest('diff', function (assert) {\n    var zoneA = moment(),\n        zoneB = moment(zoneA).zone(720),\n        zoneC = moment(zoneA).zone(360),\n        zoneD = moment(zoneA).zone(-690),\n        other = moment(zoneA).add(35, 'm');\n\n    assert.equal(zoneA.diff(other), zoneB.diff(other), 'moment#diff should be the same in all zones');\n    assert.equal(zoneA.diff(other), zoneC.diff(other), 'moment#diff should be the same in all zones');\n    assert.equal(zoneA.diff(other), zoneD.diff(other), 'moment#diff should be the same in all zones');\n\n    assert.equal(zoneA.diff(other, 'minute', true), zoneB.diff(other, 'minute', true), 'moment#diff should be the same in all zones');\n    assert.equal(zoneA.diff(other, 'minute', true), zoneC.diff(other, 'minute', true), 'moment#diff should be the same in all zones');\n    assert.equal(zoneA.diff(other, 'minute', true), zoneD.diff(other, 'minute', true), 'moment#diff should be the same in all zones');\n\n    assert.equal(zoneA.diff(other, 'hour', true), zoneB.diff(other, 'hour', true), 'moment#diff should be the same in all zones');\n    assert.equal(zoneA.diff(other, 'hour', true), zoneC.diff(other, 'hour', true), 'moment#diff should be the same in all zones');\n    assert.equal(zoneA.diff(other, 'hour', true), zoneD.diff(other, 'hour', true), 'moment#diff should be the same in all zones');\n});\n\ntest('unix offset and timestamp', function (assert) {\n    var zoneA = moment(),\n        zoneB = moment(zoneA).zone(720),\n        zoneC = moment(zoneA).zone(360),\n        zoneD = moment(zoneA).zone(-690);\n\n    assert.equal(zoneA.unix(), zoneB.unix(), 'moment#unix should be the same in all zones');\n    assert.equal(zoneA.unix(), zoneC.unix(), 'moment#unix should be the same in all zones');\n    assert.equal(zoneA.unix(), zoneD.unix(), 'moment#unix should be the same in all zones');\n\n    assert.equal(+zoneA, +zoneB, 'moment#valueOf should be the same in all zones');\n    assert.equal(+zoneA, +zoneC, 'moment#valueOf should be the same in all zones');\n    assert.equal(+zoneA, +zoneD, 'moment#valueOf should be the same in all zones');\n});\n\ntest('cloning', function (assert) {\n    assert.equal(moment().zone(120).clone().zone(),   120, 'explicit cloning should retain the zone');\n    assert.equal(moment().zone(-120).clone().zone(), -120, 'explicit cloning should retain the zone');\n    assert.equal(moment(moment().zone(120)).zone(),   120, 'implicit cloning should retain the zone');\n    assert.equal(moment(moment().zone(-120)).zone(), -120, 'implicit cloning should retain the zone');\n});\n\ntest('start of / end of', function (assert) {\n    var a = moment.utc([2010, 1, 2, 0, 0, 0]).zone(450);\n\n    assert.equal(a.clone().startOf('day').hour(), 0, 'start of day should work on moments with a zone');\n    assert.equal(a.clone().startOf('day').minute(), 0, 'start of day should work on moments with a zone');\n    assert.equal(a.clone().startOf('hour').minute(), 0, 'start of hour should work on moments with a zone');\n\n    assert.equal(a.clone().endOf('day').hour(), 23, 'end of day should work on moments with a zone');\n    assert.equal(a.clone().endOf('day').minute(), 59, 'end of day should work on moments with a zone');\n    assert.equal(a.clone().endOf('hour').minute(), 59, 'end of hour should work on moments with a zone');\n});\n\ntest('reset zone with moment#utc', function (assert) {\n    var a = moment.utc([2012]).zone(480);\n\n    assert.equal(a.clone().hour(),      16, 'different zone should have different hour');\n    assert.equal(a.clone().utc().hour(), 0, 'calling moment#utc should reset the offset');\n});\n\ntest('reset zone with moment#local', function (assert) {\n    var a = moment([2012]).zone(480);\n\n    assert.equal(a.clone().local().hour(), 0, 'calling moment#local should reset the offset');\n});\n\ntest('toDate', function (assert) {\n    var zoneA = new Date(),\n        zoneB = moment(zoneA).zone(720).toDate(),\n        zoneC = moment(zoneA).zone(360).toDate(),\n        zoneD = moment(zoneA).zone(-690).toDate();\n\n    assert.equal(+zoneA, +zoneB, 'moment#toDate should output a date with the right unix timestamp');\n    assert.equal(+zoneA, +zoneC, 'moment#toDate should output a date with the right unix timestamp');\n    assert.equal(+zoneA, +zoneD, 'moment#toDate should output a date with the right unix timestamp');\n});\n\ntest('same / before / after', function (assert) {\n    var zoneA = moment().utc(),\n        zoneB = moment(zoneA).zone(120),\n        zoneC = moment(zoneA).zone(-120);\n\n    assert.ok(zoneA.isSame(zoneB), 'two moments with different offsets should be the same');\n    assert.ok(zoneA.isSame(zoneC), 'two moments with different offsets should be the same');\n\n    assert.ok(zoneA.isSame(zoneB, 'hour'), 'two moments with different offsets should be the same hour');\n    assert.ok(zoneA.isSame(zoneC, 'hour'), 'two moments with different offsets should be the same hour');\n\n    zoneA.add(1, 'hour');\n\n    assert.ok(zoneA.isAfter(zoneB), 'isAfter should work with two moments with different offsets');\n    assert.ok(zoneA.isAfter(zoneC), 'isAfter should work with two moments with different offsets');\n\n    assert.ok(zoneA.isAfter(zoneB, 'hour'), 'isAfter:hour should work with two moments with different offsets');\n    assert.ok(zoneA.isAfter(zoneC, 'hour'), 'isAfter:hour should work with two moments with different offsets');\n\n    zoneA.subtract(2, 'hour');\n\n    assert.ok(zoneA.isBefore(zoneB), 'isBefore should work with two moments with different offsets');\n    assert.ok(zoneA.isBefore(zoneC), 'isBefore should work with two moments with different offsets');\n\n    assert.ok(zoneA.isBefore(zoneB, 'hour'), 'isBefore:hour should work with two moments with different offsets');\n    assert.ok(zoneA.isBefore(zoneC, 'hour'), 'isBefore:hour should work with two moments with different offsets');\n});\n\ntest('add / subtract over dst', function (assert) {\n    var oldOffset = moment.updateOffset,\n        m = moment.utc([2000, 2, 31, 3]);\n\n    moment.updateOffset = function (mom, keepTime) {\n        if (mom.clone().utc().month() > 2) {\n            mom.zone(-60, keepTime);\n        } else {\n            mom.zone(0, keepTime);\n        }\n    };\n\n    assert.equal(m.hour(), 3, 'should start at 00:00');\n\n    m.add(24, 'hour');\n\n    assert.equal(m.hour(), 4, 'adding 24 hours should disregard dst');\n\n    m.subtract(24, 'hour');\n\n    assert.equal(m.hour(), 3, 'subtracting 24 hours should disregard dst');\n\n    m.add(1, 'day');\n\n    assert.equal(m.hour(), 3, 'adding 1 day should have the same hour');\n\n    m.subtract(1, 'day');\n\n    assert.equal(m.hour(), 3, 'subtracting 1 day should have the same hour');\n\n    m.add(1, 'month');\n\n    assert.equal(m.hour(), 3, 'adding 1 month should have the same hour');\n\n    m.subtract(1, 'month');\n\n    assert.equal(m.hour(), 3, 'subtracting 1 month should have the same hour');\n\n    moment.updateOffset = oldOffset;\n});\n\ntest('isDST', function (assert) {\n    var oldOffset = moment.updateOffset;\n\n    moment.updateOffset = function (mom, keepTime) {\n        if (mom.month() > 2 && mom.month() < 9) {\n            mom.zone(-60, keepTime);\n        } else {\n            mom.zone(0, keepTime);\n        }\n    };\n\n    assert.ok(!moment().month(0).isDST(),  'Jan should not be summer dst');\n    assert.ok(moment().month(6).isDST(),   'Jul should be summer dst');\n    assert.ok(!moment().month(11).isDST(), 'Dec should not be summer dst');\n\n    moment.updateOffset = function (mom) {\n        if (mom.month() > 2 && mom.month() < 9) {\n            mom.zone(0);\n        } else {\n            mom.zone(-60);\n        }\n    };\n\n    assert.ok(moment().month(0).isDST(),  'Jan should be winter dst');\n    assert.ok(!moment().month(6).isDST(), 'Jul should not be winter dst');\n    assert.ok(moment().month(11).isDST(), 'Dec should be winter dst');\n\n    moment.updateOffset = oldOffset;\n});\n\ntest('zone names', function (assert) {\n    test.expectedDeprecations();\n    assert.equal(moment().zoneAbbr(),   '', 'Local zone abbr should be empty');\n    assert.equal(moment().format('z'),  '', 'Local zone formatted abbr should be empty');\n    assert.equal(moment().zoneName(),   '', 'Local zone name should be empty');\n    assert.equal(moment().format('zz'), '', 'Local zone formatted name should be empty');\n\n    assert.equal(moment.utc().zoneAbbr(),   'UTC', 'UTC zone abbr should be UTC');\n    assert.equal(moment.utc().format('z'),  'UTC', 'UTC zone formatted abbr should be UTC');\n    assert.equal(moment.utc().zoneName(),   'Coordinated Universal Time', 'UTC zone abbr should be Coordinated Universal Time');\n    assert.equal(moment.utc().format('zz'), 'Coordinated Universal Time', 'UTC zone formatted abbr should be Coordinated Universal Time');\n});\n\ntest('hours alignment with UTC', function (assert) {\n    assert.equal(moment().zone(120).hasAlignedHourOffset(), true);\n    assert.equal(moment().zone(-180).hasAlignedHourOffset(), true);\n    assert.equal(moment().zone(90).hasAlignedHourOffset(), false);\n    assert.equal(moment().zone(-90).hasAlignedHourOffset(), false);\n});\n\ntest('hours alignment with other zone', function (assert) {\n    var m = moment().zone(120);\n\n    assert.equal(m.hasAlignedHourOffset(moment().zone(180)), true);\n    assert.equal(m.hasAlignedHourOffset(moment().zone(-180)), true);\n    assert.equal(m.hasAlignedHourOffset(moment().zone(90)), false);\n    assert.equal(m.hasAlignedHourOffset(moment().zone(-90)), false);\n\n    m = moment().zone(90);\n\n    assert.equal(m.hasAlignedHourOffset(moment().zone(180)), false);\n    assert.equal(m.hasAlignedHourOffset(moment().zone(-180)), false);\n    assert.equal(m.hasAlignedHourOffset(moment().zone(30)), true);\n    assert.equal(m.hasAlignedHourOffset(moment().zone(-30)), true);\n\n    m = moment().zone(-60);\n\n    assert.equal(m.hasAlignedHourOffset(moment().zone(180)), true);\n    assert.equal(m.hasAlignedHourOffset(moment().zone(-180)), true);\n    assert.equal(m.hasAlignedHourOffset(moment().zone(90)), false);\n    assert.equal(m.hasAlignedHourOffset(moment().zone(-90)), false);\n\n    m = moment().zone(25);\n\n    assert.equal(m.hasAlignedHourOffset(moment().zone(-35)), true);\n    assert.equal(m.hasAlignedHourOffset(moment().zone(85)), true);\n\n    assert.equal(m.hasAlignedHourOffset(moment().zone(35)), false);\n    assert.equal(m.hasAlignedHourOffset(moment().zone(-85)), false);\n});\n\ntest('parse zone', function (assert) {\n    var m = moment('2013-01-01T00:00:00-13:00').parseZone();\n    assert.equal(m.zone(), 13 * 60);\n    assert.equal(m.hours(), 0);\n});\n\ntest('parse zone static', function (assert) {\n    var m = moment.parseZone('2013-01-01T00:00:00-13:00');\n    assert.equal(m.zone(), 13 * 60);\n    assert.equal(m.hours(), 0);\n});\n\ntest('parse zone with more arguments', function (assert) {\n    test.expectedDeprecations();\n    var m;\n    m = moment.parseZone('2013 01 01 05 -13:00', 'YYYY MM DD HH ZZ');\n    assert.equal(m.format(), '2013-01-01T05:00:00-13:00', 'accept input and format');\n    m = moment.parseZone('2013-01-01-13:00', 'YYYY MM DD ZZ', true);\n    assert.equal(m.isValid(), false, 'accept input, format and strict flag');\n    m = moment.parseZone('2013-01-01-13:00', ['DD MM YYYY ZZ', 'YYYY MM DD ZZ']);\n    assert.equal(m.format(), '2013-01-01T00:00:00-13:00', 'accept input and array of formats');\n});\n\ntest('parse zone with a timezone from the format string', function (assert) {\n    var m = moment('11-12-2013 -0400 +1100', 'DD-MM-YYYY ZZ #####').parseZone();\n\n    assert.equal(m.zone(), 4 * 60);\n});\n\ntest('parse zone without a timezone included in the format string', function (assert) {\n    var m = moment('11-12-2013 -0400 +1100', 'DD-MM-YYYY').parseZone();\n\n    assert.equal(m.zone(), -11 * 60);\n});\n\ntest('timezone format', function (assert) {\n    assert.equal(moment().zone(-60).format('ZZ'), '+0100', '-60 -> +0100');\n    assert.equal(moment().zone(-90).format('ZZ'), '+0130', '-90 -> +0130');\n    assert.equal(moment().zone(-120).format('ZZ'), '+0200', '-120 -> +0200');\n\n    assert.equal(moment().zone(+60).format('ZZ'), '-0100', '+60 -> -0100');\n    assert.equal(moment().zone(+90).format('ZZ'), '-0130', '+90 -> -0130');\n    assert.equal(moment().zone(+120).format('ZZ'), '-0200', '+120 -> -0200');\n});\n\ntest('parse zone without a timezone', function (assert) {\n    test.expectedDeprecations();\n    var m1 = moment.parseZone('2016-02-01T00:00:00');\n    var m2 = moment.parseZone('2016-02-01T00:00:00Z');\n    var m3 = moment.parseZone('2016-02-01T00:00:00+00:00'); //Someone might argue this is not necessary, you could even argue that is wrong being here.\n    var m4 = moment.parseZone('2016-02-01T00:00:00+0000'); //Someone might argue this is not necessary, you could even argue that is wrong being here.\n    assert.equal(\n        m1.format('M D YYYY HH:mm:ss ZZ'),\n        '2 1 2016 00:00:00 +0000',\n        'Not providing a timezone should keep the time and change the zone to 0'\n    );\n    assert.equal(\n        m2.format('M D YYYY HH:mm:ss ZZ'),\n        '2 1 2016 00:00:00 +0000',\n        'Not providing a timezone should keep the time and change the zone to 0'\n    );\n    assert.equal(\n        m3.format('M D YYYY HH:mm:ss ZZ'),\n        '2 1 2016 00:00:00 +0000',\n        'Not providing a timezone should keep the time and change the zone to 0'\n    );\n    assert.equal(\n        m4.format('M D YYYY HH:mm:ss ZZ'),\n        '2 1 2016 00:00:00 +0000',\n        'Not providing a timezone should keep the time and change the zone to 0'\n    );\n});\n\ntest('parse zone with a minutes unit abs less than 16 should retain minutes', function (assert) {\n    //ensure when minutes are explicitly parsed, they are retained\n    //instead of converted to hours, even if less than 16\n    var n = moment.parseZone('2013-01-01T00:00:00-00:15');\n    assert.equal(n.utcOffset(), -15);\n    assert.equal(n.zone(), 15);\n    assert.equal(n.hour(), 0);\n    var o = moment.parseZone('2013-01-01T00:00:00+00:15');\n    assert.equal(o.utcOffset(), 15);\n    assert.equal(o.zone(), -15);\n    assert.equal(o.hour(), 0);\n});\n\n})));\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/moment.d.ts",
    "content": "declare function moment(inp?: moment.MomentInput, format?: moment.MomentFormatSpecification, strict?: boolean): moment.Moment;\ndeclare function moment(inp?: moment.MomentInput, format?: moment.MomentFormatSpecification, language?: string, strict?: boolean): moment.Moment;\n\ndeclare namespace moment {\n  type RelativeTimeKey = 's' | 'm' | 'mm' | 'h' | 'hh' | 'd' | 'dd' | 'M' | 'MM' | 'y' | 'yy';\n  type CalendarKey = 'sameDay' | 'nextDay' | 'lastDay' | 'nextWeek' | 'lastWeek' | 'sameElse' | string;\n  type LongDateFormatKey = 'LTS' | 'LT' | 'L' | 'LL' | 'LLL' | 'LLLL' | 'lts' | 'lt' | 'l' | 'll' | 'lll' | 'llll';\n\n  interface Locale {\n    calendar(key?: CalendarKey, m?: Moment, now?: Moment): string;\n\n    longDateFormat(key: LongDateFormatKey): string;\n    invalidDate(): string;\n    ordinal(n: number): string;\n\n    preparse(inp: string): string;\n    postformat(inp: string): string;\n    relativeTime(n: number, withoutSuffix: boolean,\n                 key: RelativeTimeKey, isFuture: boolean): string;\n    pastFuture(diff: number, absRelTime: string): string;\n    set(config: Object): void;\n\n    months(): string[];\n    months(m: Moment, format?: string): string;\n    monthsShort(): string[];\n    monthsShort(m: Moment, format?: string): string;\n    monthsParse(monthName: string, format: string, strict: boolean): number;\n    monthsRegex(strict: boolean): RegExp;\n    monthsShortRegex(strict: boolean): RegExp;\n\n    week(m: Moment): number;\n    firstDayOfYear(): number;\n    firstDayOfWeek(): number;\n\n    weekdays(): string[];\n    weekdays(m: Moment, format?: string): string;\n    weekdaysMin(): string[];\n    weekdaysMin(m: Moment): string;\n    weekdaysShort(): string[];\n    weekdaysShort(m: Moment): string;\n    weekdaysParse(weekdayName: string, format: string, strict: boolean): number;\n    weekdaysRegex(strict: boolean): RegExp;\n    weekdaysShortRegex(strict: boolean): RegExp;\n    weekdaysMinRegex(strict: boolean): RegExp;\n\n    isPM(input: string): boolean;\n    meridiem(hour: number, minute: number, isLower: boolean): string;\n  }\n\n  interface StandaloneFormatSpec {\n    format: string[];\n    standalone: string[];\n    isFormat?: RegExp;\n  }\n\n  interface WeekSpec {\n    dow: number;\n    doy: number;\n  }\n\n  type CalendarSpecVal = string | ((m?: MomentInput, now?: Moment) => string);\n  interface CalendarSpec {\n    sameDay?: CalendarSpecVal;\n    nextDay?: CalendarSpecVal;\n    lastDay?: CalendarSpecVal;\n    nextWeek?: CalendarSpecVal;\n    lastWeek?: CalendarSpecVal;\n    sameElse?: CalendarSpecVal;\n\n    // any additional properties might be used with moment.calendarFormat\n    [x: string]: CalendarSpecVal | void; // undefined\n  }\n\n  type RelativeTimeSpecVal = (\n    string |\n    ((n: number, withoutSuffix: boolean,\n      key: RelativeTimeKey, isFuture: boolean) => string)\n  );\n  type RelativeTimeFuturePastVal = string | ((relTime: string) => string);\n\n  interface RelativeTimeSpec {\n    future: RelativeTimeFuturePastVal;\n    past: RelativeTimeFuturePastVal;\n    s: RelativeTimeSpecVal;\n    m: RelativeTimeSpecVal;\n    mm: RelativeTimeSpecVal;\n    h: RelativeTimeSpecVal;\n    hh: RelativeTimeSpecVal;\n    d: RelativeTimeSpecVal;\n    dd: RelativeTimeSpecVal;\n    M: RelativeTimeSpecVal;\n    MM: RelativeTimeSpecVal;\n    y: RelativeTimeSpecVal;\n    yy: RelativeTimeSpecVal;\n  }\n\n  interface LongDateFormatSpec {\n    LTS: string;\n    LT: string;\n    L: string;\n    LL: string;\n    LLL: string;\n    LLLL: string;\n\n    // lets forget for a sec that any upper/lower permutation will also work\n    lts?: string;\n    lt?: string;\n    l?: string;\n    ll?: string;\n    lll?: string;\n    llll?: string;\n  }\n\n  type MonthWeekdayFn = (momentToFormat: Moment, format?: string) => string;\n  type WeekdaySimpleFn = (momentToFormat: Moment) => string;\n\n  interface LocaleSpecification {\n    months?: string[] | StandaloneFormatSpec | MonthWeekdayFn;\n    monthsShort?: string[] | StandaloneFormatSpec | MonthWeekdayFn;\n\n    weekdays?: string[] | StandaloneFormatSpec | MonthWeekdayFn;\n    weekdaysShort?: string[] | StandaloneFormatSpec | WeekdaySimpleFn;\n    weekdaysMin?: string[] | StandaloneFormatSpec | WeekdaySimpleFn;\n\n    meridiemParse?: RegExp;\n    meridiem?: (hour: number, minute:number, isLower: boolean) => string;\n\n    isPM?: (input: string) => boolean;\n\n    longDateFormat?: LongDateFormatSpec;\n    calendar?: CalendarSpec;\n    relativeTime?: RelativeTimeSpec;\n    invalidDate?: string;\n    ordinal?: (n: number) => string;\n    ordinalParse?: RegExp;\n\n    week?: WeekSpec;\n\n    // Allow anything: in general any property that is passed as locale spec is\n    // put in the locale object so it can be used by locale functions\n    [x: string]: any;\n  }\n\n  interface MomentObjectOutput {\n    years: number;\n    /* One digit */\n    months: number;\n    /* Day of the month */\n    date: number;\n    hours: number;\n    minutes: number;\n    seconds: number;\n    milliseconds: number;\n  }\n\n  interface Duration {\n    humanize(withSuffix?: boolean): string;\n\n    abs(): Duration;\n\n    as(units: unitOfTime.Base): number;\n    get(units: unitOfTime.Base): number;\n\n    milliseconds(): number;\n    asMilliseconds(): number;\n\n    seconds(): number;\n    asSeconds(): number;\n\n    minutes(): number;\n    asMinutes(): number;\n\n    hours(): number;\n    asHours(): number;\n\n    days(): number;\n    asDays(): number;\n\n    weeks(): number;\n    asWeeks(): number;\n\n    months(): number;\n    asMonths(): number;\n\n    years(): number;\n    asYears(): number;\n\n    add(inp?: DurationInputArg1, unit?: DurationInputArg2): Duration;\n    subtract(inp?: DurationInputArg1, unit?: DurationInputArg2): Duration;\n\n    locale(): string;\n    locale(locale: LocaleSpecifier): Duration;\n    localeData(): Locale;\n\n    toISOString(): string;\n    toJSON(): string;\n\n    /**\n     * @deprecated since version 2.8.0\n     */\n    lang(locale: LocaleSpecifier): Moment;\n    /**\n     * @deprecated since version 2.8.0\n     */\n    lang(): Locale;\n    /**\n     * @deprecated\n     */\n    toIsoString(): string;\n  }\n\n  interface MomentRelativeTime {\n    future: any;\n    past: any;\n    s: any;\n    m: any;\n    mm: any;\n    h: any;\n    hh: any;\n    d: any;\n    dd: any;\n    M: any;\n    MM: any;\n    y: any;\n    yy: any;\n  }\n\n  interface MomentLongDateFormat {\n    L: string;\n    LL: string;\n    LLL: string;\n    LLLL: string;\n    LT: string;\n    LTS: string;\n\n    l?: string;\n    ll?: string;\n    lll?: string;\n    llll?: string;\n    lt?: string;\n    lts?: string;\n  }\n\n  interface MomentParsingFlags {\n    empty: boolean;\n    unusedTokens: string[];\n    unusedInput: string[];\n    overflow: number;\n    charsLeftOver: number;\n    nullInput: boolean;\n    invalidMonth: string | void; // null\n    invalidFormat: boolean;\n    userInvalidated: boolean;\n    iso: boolean;\n    parsedDateParts: any[];\n    meridiem: string | void; // null\n  }\n\n  interface MomentParsingFlagsOpt {\n    empty?: boolean;\n    unusedTokens?: string[];\n    unusedInput?: string[];\n    overflow?: number;\n    charsLeftOver?: number;\n    nullInput?: boolean;\n    invalidMonth?: string;\n    invalidFormat?: boolean;\n    userInvalidated?: boolean;\n    iso?: boolean;\n    parsedDateParts?: any[];\n    meridiem?: string;\n  }\n\n  interface MomentBuiltinFormat {\n    __momentBuiltinFormatBrand: any;\n  }\n\n  type MomentFormatSpecification = string | MomentBuiltinFormat | (string | MomentBuiltinFormat)[];\n\n  namespace unitOfTime {\n    type Base = (\n      \"year\" | \"years\" | \"y\" |\n      \"month\" | \"months\" | \"M\" |\n      \"week\" | \"weeks\" | \"w\" |\n      \"day\" | \"days\" | \"d\" |\n      \"hour\" | \"hours\" | \"h\" |\n      \"minute\" | \"minutes\" | \"m\" |\n      \"second\" | \"seconds\" | \"s\" |\n      \"millisecond\" | \"milliseconds\" | \"ms\"\n    );\n\n    type _quarter = \"quarter\" | \"quarters\" | \"Q\";\n    type _isoWeek = \"isoWeek\" | \"isoWeeks\" | \"W\";\n    type _date = \"date\" | \"dates\" | \"D\";\n    type DurationConstructor = Base | _quarter;\n\n    type DurationAs = Base;\n\n    type StartOf = Base | _quarter | _isoWeek | _date;\n\n    type Diff = Base | _quarter;\n\n    type MomentConstructor = Base | _date;\n\n    type All = Base | _quarter | _isoWeek | _date |\n      \"weekYear\" | \"weekYears\" | \"gg\" |\n      \"isoWeekYear\" | \"isoWeekYears\" | \"GG\" |\n      \"dayOfYear\" | \"dayOfYears\" | \"DDD\" |\n      \"weekday\" | \"weekdays\" | \"e\" |\n      \"isoWeekday\" | \"isoWeekdays\" | \"E\";\n  }\n\n  interface MomentInputObject {\n    years?: number;\n    year?: number;\n    y?: number;\n\n    months?: number;\n    month?: number;\n    M?: number;\n\n    days?: number;\n    day?: number;\n    d?: number;\n\n    dates?: number;\n    date?: number;\n    D?: number;\n\n    hours?: number;\n    hour?: number;\n    h?: number;\n\n    minutes?: number;\n    minute?: number;\n    m?: number;\n\n    seconds?: number;\n    second?: number;\n    s?: number;\n\n    milliseconds?: number;\n    millisecond?: number;\n    ms?: number;\n  }\n\n  interface DurationInputObject extends MomentInputObject {\n    quarters?: number;\n    quarter?: number;\n    Q?: number;\n\n    weeks?: number;\n    week?: number;\n    w?: number;\n  }\n\n  interface MomentSetObject extends MomentInputObject {\n    weekYears?: number;\n    weekYear?: number;\n    gg?: number;\n\n    isoWeekYears?: number;\n    isoWeekYear?: number;\n    GG?: number;\n\n    quarters?: number;\n    quarter?: number;\n    Q?: number;\n\n    weeks?: number;\n    week?: number;\n    w?: number;\n\n    isoWeeks?: number;\n    isoWeek?: number;\n    W?: number;\n\n    dayOfYears?: number;\n    dayOfYear?: number;\n    DDD?: number;\n\n    weekdays?: number;\n    weekday?: number;\n    e?: number;\n\n    isoWeekdays?: number;\n    isoWeekday?: number;\n    E?: number;\n  }\n\n  interface FromTo {\n    from: MomentInput;\n    to: MomentInput;\n  }\n\n  type MomentInput = Moment | Date | string | number | (number | string)[] | MomentInputObject | void; // null | undefined\n  type DurationInputArg1 = Duration | number | string | FromTo | DurationInputObject | void; // null | undefined\n  type DurationInputArg2 = unitOfTime.DurationConstructor;\n  type LocaleSpecifier = string | Moment | Duration | string[] | boolean;\n\n  interface MomentCreationData {\n    input: MomentInput;\n    format?: MomentFormatSpecification;\n    locale: Locale;\n    isUTC: boolean;\n    strict?: boolean;\n  }\n\n  interface Moment extends Object{\n    format(format?: string): string;\n\n    startOf(unitOfTime: unitOfTime.StartOf): Moment;\n    endOf(unitOfTime: unitOfTime.StartOf): Moment;\n\n    add(amount?: DurationInputArg1, unit?: DurationInputArg2): Moment;\n    /**\n     * @deprecated reverse syntax\n     */\n    add(unit: unitOfTime.DurationConstructor, amount: number|string): Moment;\n\n    subtract(amount?: DurationInputArg1, unit?: DurationInputArg2): Moment;\n    /**\n     * @deprecated reverse syntax\n     */\n    subtract(unit: unitOfTime.DurationConstructor, amount: number|string): Moment;\n\n    calendar(time?: MomentInput, formats?: CalendarSpec): string;\n\n    clone(): Moment;\n\n    /**\n     * @return Unix timestamp in milliseconds\n     */\n    valueOf(): number;\n\n    // current date/time in local mode\n    local(keepLocalTime?: boolean): Moment;\n    isLocal(): boolean;\n\n    // current date/time in UTC mode\n    utc(keepLocalTime?: boolean): Moment;\n    isUTC(): boolean;\n    /**\n     * @deprecated use isUTC\n     */\n    isUtc(): boolean;\n\n    parseZone(): Moment;\n    isValid(): boolean;\n    invalidAt(): number;\n\n    hasAlignedHourOffset(other?: MomentInput): boolean;\n\n    creationData(): MomentCreationData;\n    parsingFlags(): MomentParsingFlags;\n\n    year(y: number): Moment;\n    year(): number;\n    /**\n     * @deprecated use year(y)\n     */\n    years(y: number): Moment;\n    /**\n     * @deprecated use year()\n     */\n    years(): number;\n    quarter(): number;\n    quarter(q: number): Moment;\n    quarters(): number;\n    quarters(q: number): Moment;\n    month(M: number|string): Moment;\n    month(): number;\n    /**\n     * @deprecated use month(M)\n     */\n    months(M: number|string): Moment;\n    /**\n     * @deprecated use month()\n     */\n    months(): number;\n    day(d: number|string): Moment;\n    day(): number;\n    days(d: number|string): Moment;\n    days(): number;\n    date(d: number): Moment;\n    date(): number;\n    /**\n     * @deprecated use date(d)\n     */\n    dates(d: number): Moment;\n    /**\n     * @deprecated use date()\n     */\n    dates(): number;\n    hour(h: number): Moment;\n    hour(): number;\n    hours(h: number): Moment;\n    hours(): number;\n    minute(m: number): Moment;\n    minute(): number;\n    minutes(m: number): Moment;\n    minutes(): number;\n    second(s: number): Moment;\n    second(): number;\n    seconds(s: number): Moment;\n    seconds(): number;\n    millisecond(ms: number): Moment;\n    millisecond(): number;\n    milliseconds(ms: number): Moment;\n    milliseconds(): number;\n    weekday(): number;\n    weekday(d: number): Moment;\n    isoWeekday(): number;\n    isoWeekday(d: number|string): Moment;\n    weekYear(): number;\n    weekYear(d: number): Moment;\n    isoWeekYear(): number;\n    isoWeekYear(d: number): Moment;\n    week(): number;\n    week(d: number): Moment;\n    weeks(): number;\n    weeks(d: number): Moment;\n    isoWeek(): number;\n    isoWeek(d: number): Moment;\n    isoWeeks(): number;\n    isoWeeks(d: number): Moment;\n    weeksInYear(): number;\n    isoWeeksInYear(): number;\n    dayOfYear(): number;\n    dayOfYear(d: number): Moment;\n\n    from(inp: MomentInput, suffix?: boolean): string;\n    to(inp: MomentInput, suffix?: boolean): string;\n    fromNow(withoutSuffix?: boolean): string;\n    toNow(withoutPrefix?: boolean): string;\n\n    diff(b: MomentInput, unitOfTime?: unitOfTime.Diff, precise?: boolean): number;\n\n    toArray(): number[];\n    toDate(): Date;\n    toISOString(): string;\n    inspect(): string;\n    toJSON(): string;\n    unix(): number;\n\n    isLeapYear(): boolean;\n    /**\n     * @deprecated in favor of utcOffset\n     */\n    zone(): number;\n    zone(b: number|string): Moment;\n    utcOffset(): number;\n    utcOffset(b: number|string, keepLocalTime?: boolean): Moment;\n    isUtcOffset(): boolean;\n    daysInMonth(): number;\n    isDST(): boolean;\n\n    zoneAbbr(): string;\n    zoneName(): string;\n\n    isBefore(inp?: MomentInput, granularity?: unitOfTime.StartOf): boolean;\n    isAfter(inp?: MomentInput, granularity?: unitOfTime.StartOf): boolean;\n    isSame(inp?: MomentInput, granularity?: unitOfTime.StartOf): boolean;\n    isSameOrAfter(inp?: MomentInput, granularity?: unitOfTime.StartOf): boolean;\n    isSameOrBefore(inp?: MomentInput, granularity?: unitOfTime.StartOf): boolean;\n    isBetween(a: MomentInput, b: MomentInput, granularity?: unitOfTime.StartOf, inclusivity?: \"()\" | \"[)\" | \"(]\" | \"[]\"): boolean;\n\n    /**\n     * @deprecated as of 2.8.0, use locale\n     */\n    lang(language: LocaleSpecifier): Moment;\n    /**\n     * @deprecated as of 2.8.0, use locale\n     */\n    lang(): Locale;\n\n    locale(): string;\n    locale(locale: LocaleSpecifier): Moment;\n\n    localeData(): Locale;\n\n    /**\n     * @deprecated no reliable implementation\n     */\n    isDSTShifted(): boolean;\n\n    // NOTE(constructor): Same as moment constructor\n    /**\n     * @deprecated as of 2.7.0, use moment.min/max\n     */\n    max(inp?: MomentInput, format?: MomentFormatSpecification, strict?: boolean): Moment;\n    /**\n     * @deprecated as of 2.7.0, use moment.min/max\n     */\n    max(inp?: MomentInput, format?: MomentFormatSpecification, language?: string, strict?: boolean): Moment;\n\n    // NOTE(constructor): Same as moment constructor\n    /**\n     * @deprecated as of 2.7.0, use moment.min/max\n     */\n    min(inp?: MomentInput, format?: MomentFormatSpecification, strict?: boolean): Moment;\n    /**\n     * @deprecated as of 2.7.0, use moment.min/max\n     */\n    min(inp?: MomentInput, format?: MomentFormatSpecification, language?: string, strict?: boolean): Moment;\n\n    get(unit: unitOfTime.All): number;\n    set(unit: unitOfTime.All, value: number): Moment;\n    set(objectLiteral: MomentSetObject): Moment;\n\n    toObject(): MomentObjectOutput;\n  }\n\n  export var version: string;\n  export var fn: Moment;\n\n  // NOTE(constructor): Same as moment constructor\n  export function utc(inp?: MomentInput, format?: MomentFormatSpecification, strict?: boolean): Moment;\n  export function utc(inp?: MomentInput, format?: MomentFormatSpecification, language?: string, strict?: boolean): Moment;\n\n  export function unix(timestamp: number): Moment;\n\n  export function invalid(flags?: MomentParsingFlagsOpt): Moment;\n  export function isMoment(m: any): m is Moment;\n  export function isDate(m: any): m is Date;\n  export function isDuration(d: any): d is Duration;\n\n  /**\n   * @deprecated in 2.8.0\n   */\n  export function lang(language?: string): string;\n  /**\n   * @deprecated in 2.8.0\n   */\n  export function lang(language?: string, definition?: Locale): string;\n\n  export function locale(language?: string): string;\n  export function locale(language?: string[]): string;\n  export function locale(language?: string, definition?: LocaleSpecification | void): string; // null | undefined\n\n  export function localeData(key?: string | string[]): Locale;\n\n  export function duration(inp?: DurationInputArg1, unit?: DurationInputArg2): Duration;\n\n  // NOTE(constructor): Same as moment constructor\n  export function parseZone(inp?: MomentInput, format?: MomentFormatSpecification, strict?: boolean): Moment;\n  export function parseZone(inp?: MomentInput, format?: MomentFormatSpecification, language?: string, strict?: boolean): Moment;\n\n  export function months(): string[];\n  export function months(index: number): string;\n  export function months(format: string): string[];\n  export function months(format: string, index: number): string;\n  export function monthsShort(): string[];\n  export function monthsShort(index: number): string;\n  export function monthsShort(format: string): string[];\n  export function monthsShort(format: string, index: number): string;\n\n  export function weekdays(): string[];\n  export function weekdays(index: number): string;\n  export function weekdays(format: string): string[];\n  export function weekdays(format: string, index: number): string;\n  export function weekdays(localeSorted: boolean): string[];\n  export function weekdays(localeSorted: boolean, index: number): string;\n  export function weekdays(localeSorted: boolean, format: string): string[];\n  export function weekdays(localeSorted: boolean, format: string, index: number): string;\n  export function weekdaysShort(): string[];\n  export function weekdaysShort(index: number): string;\n  export function weekdaysShort(format: string): string[];\n  export function weekdaysShort(format: string, index: number): string;\n  export function weekdaysShort(localeSorted: boolean): string[];\n  export function weekdaysShort(localeSorted: boolean, index: number): string;\n  export function weekdaysShort(localeSorted: boolean, format: string): string[];\n  export function weekdaysShort(localeSorted: boolean, format: string, index: number): string;\n  export function weekdaysMin(): string[];\n  export function weekdaysMin(index: number): string;\n  export function weekdaysMin(format: string): string[];\n  export function weekdaysMin(format: string, index: number): string;\n  export function weekdaysMin(localeSorted: boolean): string[];\n  export function weekdaysMin(localeSorted: boolean, index: number): string;\n  export function weekdaysMin(localeSorted: boolean, format: string): string[];\n  export function weekdaysMin(localeSorted: boolean, format: string, index: number): string;\n\n  export function min(...moments: MomentInput[]): Moment;\n  export function max(...moments: MomentInput[]): Moment;\n\n  /**\n   * Returns unix time in milliseconds. Overwrite for profit.\n   */\n  export function now(): number;\n\n  export function defineLocale(language: string, localeSpec: LocaleSpecification | void): Locale; // null\n  export function updateLocale(language: string, localeSpec: LocaleSpecification | void): Locale; // null\n\n  export function locales(): string[];\n\n  export function normalizeUnits(unit: unitOfTime.All): string;\n  export function relativeTimeThreshold(threshold: string): number | boolean;\n  export function relativeTimeThreshold(threshold: string, limit: number): boolean;\n  export function relativeTimeRounding(fn: (num: number) => number): boolean;\n  export function relativeTimeRounding(): (num: number) => number;\n  export function calendarFormat(m: Moment, now: Moment): string;\n\n  /**\n   * Constant used to enable explicit ISO_8601 format parsing.\n   */\n  export var ISO_8601: MomentBuiltinFormat;\n\n  export var defaultFormat: string;\n  export var defaultFormatUtc: string;\n}\n\nexport = moment;\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/moment.js",
    "content": "//! moment.js\n//! version : 2.18.1\n//! authors : Tim Wood, Iskren Chernev, Moment.js contributors\n//! license : MIT\n//! momentjs.com\n\n;(function (global, factory) {\n    typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :\n    typeof define === 'function' && define.amd ? define(factory) :\n    global.moment = factory()\n}(this, (function () { 'use strict';\n\nvar hookCallback;\n\nfunction hooks () {\n    return hookCallback.apply(null, arguments);\n}\n\n// This is done to register the method called with moment()\n// without creating circular dependencies.\nfunction setHookCallback (callback) {\n    hookCallback = callback;\n}\n\nfunction isArray(input) {\n    return input instanceof Array || Object.prototype.toString.call(input) === '[object Array]';\n}\n\nfunction isObject(input) {\n    // IE8 will treat undefined and null as object if it wasn't for\n    // input != null\n    return input != null && Object.prototype.toString.call(input) === '[object Object]';\n}\n\nfunction isObjectEmpty(obj) {\n    var k;\n    for (k in obj) {\n        // even if its not own property I'd still call it non-empty\n        return false;\n    }\n    return true;\n}\n\nfunction isUndefined(input) {\n    return input === void 0;\n}\n\nfunction isNumber(input) {\n    return typeof input === 'number' || Object.prototype.toString.call(input) === '[object Number]';\n}\n\nfunction isDate(input) {\n    return input instanceof Date || Object.prototype.toString.call(input) === '[object Date]';\n}\n\nfunction map(arr, fn) {\n    var res = [], i;\n    for (i = 0; i < arr.length; ++i) {\n        res.push(fn(arr[i], i));\n    }\n    return res;\n}\n\nfunction hasOwnProp(a, b) {\n    return Object.prototype.hasOwnProperty.call(a, b);\n}\n\nfunction extend(a, b) {\n    for (var i in b) {\n        if (hasOwnProp(b, i)) {\n            a[i] = b[i];\n        }\n    }\n\n    if (hasOwnProp(b, 'toString')) {\n        a.toString = b.toString;\n    }\n\n    if (hasOwnProp(b, 'valueOf')) {\n        a.valueOf = b.valueOf;\n    }\n\n    return a;\n}\n\nfunction createUTC (input, format, locale, strict) {\n    return createLocalOrUTC(input, format, locale, strict, true).utc();\n}\n\nfunction defaultParsingFlags() {\n    // We need to deep clone this object.\n    return {\n        empty           : false,\n        unusedTokens    : [],\n        unusedInput     : [],\n        overflow        : -2,\n        charsLeftOver   : 0,\n        nullInput       : false,\n        invalidMonth    : null,\n        invalidFormat   : false,\n        userInvalidated : false,\n        iso             : false,\n        parsedDateParts : [],\n        meridiem        : null,\n        rfc2822         : false,\n        weekdayMismatch : false\n    };\n}\n\nfunction getParsingFlags(m) {\n    if (m._pf == null) {\n        m._pf = defaultParsingFlags();\n    }\n    return m._pf;\n}\n\nvar some;\nif (Array.prototype.some) {\n    some = Array.prototype.some;\n} else {\n    some = function (fun) {\n        var t = Object(this);\n        var len = t.length >>> 0;\n\n        for (var i = 0; i < len; i++) {\n            if (i in t && fun.call(this, t[i], i, t)) {\n                return true;\n            }\n        }\n\n        return false;\n    };\n}\n\nvar some$1 = some;\n\nfunction isValid(m) {\n    if (m._isValid == null) {\n        var flags = getParsingFlags(m);\n        var parsedParts = some$1.call(flags.parsedDateParts, function (i) {\n            return i != null;\n        });\n        var isNowValid = !isNaN(m._d.getTime()) &&\n            flags.overflow < 0 &&\n            !flags.empty &&\n            !flags.invalidMonth &&\n            !flags.invalidWeekday &&\n            !flags.nullInput &&\n            !flags.invalidFormat &&\n            !flags.userInvalidated &&\n            (!flags.meridiem || (flags.meridiem && parsedParts));\n\n        if (m._strict) {\n            isNowValid = isNowValid &&\n                flags.charsLeftOver === 0 &&\n                flags.unusedTokens.length === 0 &&\n                flags.bigHour === undefined;\n        }\n\n        if (Object.isFrozen == null || !Object.isFrozen(m)) {\n            m._isValid = isNowValid;\n        }\n        else {\n            return isNowValid;\n        }\n    }\n    return m._isValid;\n}\n\nfunction createInvalid (flags) {\n    var m = createUTC(NaN);\n    if (flags != null) {\n        extend(getParsingFlags(m), flags);\n    }\n    else {\n        getParsingFlags(m).userInvalidated = true;\n    }\n\n    return m;\n}\n\n// Plugins that add properties should also add the key here (null value),\n// so we can properly clone ourselves.\nvar momentProperties = hooks.momentProperties = [];\n\nfunction copyConfig(to, from) {\n    var i, prop, val;\n\n    if (!isUndefined(from._isAMomentObject)) {\n        to._isAMomentObject = from._isAMomentObject;\n    }\n    if (!isUndefined(from._i)) {\n        to._i = from._i;\n    }\n    if (!isUndefined(from._f)) {\n        to._f = from._f;\n    }\n    if (!isUndefined(from._l)) {\n        to._l = from._l;\n    }\n    if (!isUndefined(from._strict)) {\n        to._strict = from._strict;\n    }\n    if (!isUndefined(from._tzm)) {\n        to._tzm = from._tzm;\n    }\n    if (!isUndefined(from._isUTC)) {\n        to._isUTC = from._isUTC;\n    }\n    if (!isUndefined(from._offset)) {\n        to._offset = from._offset;\n    }\n    if (!isUndefined(from._pf)) {\n        to._pf = getParsingFlags(from);\n    }\n    if (!isUndefined(from._locale)) {\n        to._locale = from._locale;\n    }\n\n    if (momentProperties.length > 0) {\n        for (i = 0; i < momentProperties.length; i++) {\n            prop = momentProperties[i];\n            val = from[prop];\n            if (!isUndefined(val)) {\n                to[prop] = val;\n            }\n        }\n    }\n\n    return to;\n}\n\nvar updateInProgress = false;\n\n// Moment prototype object\nfunction Moment(config) {\n    copyConfig(this, config);\n    this._d = new Date(config._d != null ? config._d.getTime() : NaN);\n    if (!this.isValid()) {\n        this._d = new Date(NaN);\n    }\n    // Prevent infinite loop in case updateOffset creates new moment\n    // objects.\n    if (updateInProgress === false) {\n        updateInProgress = true;\n        hooks.updateOffset(this);\n        updateInProgress = false;\n    }\n}\n\nfunction isMoment (obj) {\n    return obj instanceof Moment || (obj != null && obj._isAMomentObject != null);\n}\n\nfunction absFloor (number) {\n    if (number < 0) {\n        // -0 -> 0\n        return Math.ceil(number) || 0;\n    } else {\n        return Math.floor(number);\n    }\n}\n\nfunction toInt(argumentForCoercion) {\n    var coercedNumber = +argumentForCoercion,\n        value = 0;\n\n    if (coercedNumber !== 0 && isFinite(coercedNumber)) {\n        value = absFloor(coercedNumber);\n    }\n\n    return value;\n}\n\n// compare two arrays, return the number of differences\nfunction compareArrays(array1, array2, dontConvert) {\n    var len = Math.min(array1.length, array2.length),\n        lengthDiff = Math.abs(array1.length - array2.length),\n        diffs = 0,\n        i;\n    for (i = 0; i < len; i++) {\n        if ((dontConvert && array1[i] !== array2[i]) ||\n            (!dontConvert && toInt(array1[i]) !== toInt(array2[i]))) {\n            diffs++;\n        }\n    }\n    return diffs + lengthDiff;\n}\n\nfunction warn(msg) {\n    if (hooks.suppressDeprecationWarnings === false &&\n            (typeof console !==  'undefined') && console.warn) {\n        console.warn('Deprecation warning: ' + msg);\n    }\n}\n\nfunction deprecate(msg, fn) {\n    var firstTime = true;\n\n    return extend(function () {\n        if (hooks.deprecationHandler != null) {\n            hooks.deprecationHandler(null, msg);\n        }\n        if (firstTime) {\n            var args = [];\n            var arg;\n            for (var i = 0; i < arguments.length; i++) {\n                arg = '';\n                if (typeof arguments[i] === 'object') {\n                    arg += '\\n[' + i + '] ';\n                    for (var key in arguments[0]) {\n                        arg += key + ': ' + arguments[0][key] + ', ';\n                    }\n                    arg = arg.slice(0, -2); // Remove trailing comma and space\n                } else {\n                    arg = arguments[i];\n                }\n                args.push(arg);\n            }\n            warn(msg + '\\nArguments: ' + Array.prototype.slice.call(args).join('') + '\\n' + (new Error()).stack);\n            firstTime = false;\n        }\n        return fn.apply(this, arguments);\n    }, fn);\n}\n\nvar deprecations = {};\n\nfunction deprecateSimple(name, msg) {\n    if (hooks.deprecationHandler != null) {\n        hooks.deprecationHandler(name, msg);\n    }\n    if (!deprecations[name]) {\n        warn(msg);\n        deprecations[name] = true;\n    }\n}\n\nhooks.suppressDeprecationWarnings = false;\nhooks.deprecationHandler = null;\n\nfunction isFunction(input) {\n    return input instanceof Function || Object.prototype.toString.call(input) === '[object Function]';\n}\n\nfunction set (config) {\n    var prop, i;\n    for (i in config) {\n        prop = config[i];\n        if (isFunction(prop)) {\n            this[i] = prop;\n        } else {\n            this['_' + i] = prop;\n        }\n    }\n    this._config = config;\n    // Lenient ordinal parsing accepts just a number in addition to\n    // number + (possibly) stuff coming from _dayOfMonthOrdinalParse.\n    // TODO: Remove \"ordinalParse\" fallback in next major release.\n    this._dayOfMonthOrdinalParseLenient = new RegExp(\n        (this._dayOfMonthOrdinalParse.source || this._ordinalParse.source) +\n            '|' + (/\\d{1,2}/).source);\n}\n\nfunction mergeConfigs(parentConfig, childConfig) {\n    var res = extend({}, parentConfig), prop;\n    for (prop in childConfig) {\n        if (hasOwnProp(childConfig, prop)) {\n            if (isObject(parentConfig[prop]) && isObject(childConfig[prop])) {\n                res[prop] = {};\n                extend(res[prop], parentConfig[prop]);\n                extend(res[prop], childConfig[prop]);\n            } else if (childConfig[prop] != null) {\n                res[prop] = childConfig[prop];\n            } else {\n                delete res[prop];\n            }\n        }\n    }\n    for (prop in parentConfig) {\n        if (hasOwnProp(parentConfig, prop) &&\n                !hasOwnProp(childConfig, prop) &&\n                isObject(parentConfig[prop])) {\n            // make sure changes to properties don't modify parent config\n            res[prop] = extend({}, res[prop]);\n        }\n    }\n    return res;\n}\n\nfunction Locale(config) {\n    if (config != null) {\n        this.set(config);\n    }\n}\n\nvar keys;\n\nif (Object.keys) {\n    keys = Object.keys;\n} else {\n    keys = function (obj) {\n        var i, res = [];\n        for (i in obj) {\n            if (hasOwnProp(obj, i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    };\n}\n\nvar keys$1 = keys;\n\nvar defaultCalendar = {\n    sameDay : '[Today at] LT',\n    nextDay : '[Tomorrow at] LT',\n    nextWeek : 'dddd [at] LT',\n    lastDay : '[Yesterday at] LT',\n    lastWeek : '[Last] dddd [at] LT',\n    sameElse : 'L'\n};\n\nfunction calendar (key, mom, now) {\n    var output = this._calendar[key] || this._calendar['sameElse'];\n    return isFunction(output) ? output.call(mom, now) : output;\n}\n\nvar defaultLongDateFormat = {\n    LTS  : 'h:mm:ss A',\n    LT   : 'h:mm A',\n    L    : 'MM/DD/YYYY',\n    LL   : 'MMMM D, YYYY',\n    LLL  : 'MMMM D, YYYY h:mm A',\n    LLLL : 'dddd, MMMM D, YYYY h:mm A'\n};\n\nfunction longDateFormat (key) {\n    var format = this._longDateFormat[key],\n        formatUpper = this._longDateFormat[key.toUpperCase()];\n\n    if (format || !formatUpper) {\n        return format;\n    }\n\n    this._longDateFormat[key] = formatUpper.replace(/MMMM|MM|DD|dddd/g, function (val) {\n        return val.slice(1);\n    });\n\n    return this._longDateFormat[key];\n}\n\nvar defaultInvalidDate = 'Invalid date';\n\nfunction invalidDate () {\n    return this._invalidDate;\n}\n\nvar defaultOrdinal = '%d';\nvar defaultDayOfMonthOrdinalParse = /\\d{1,2}/;\n\nfunction ordinal (number) {\n    return this._ordinal.replace('%d', number);\n}\n\nvar defaultRelativeTime = {\n    future : 'in %s',\n    past   : '%s ago',\n    s  : 'a few seconds',\n    ss : '%d seconds',\n    m  : 'a minute',\n    mm : '%d minutes',\n    h  : 'an hour',\n    hh : '%d hours',\n    d  : 'a day',\n    dd : '%d days',\n    M  : 'a month',\n    MM : '%d months',\n    y  : 'a year',\n    yy : '%d years'\n};\n\nfunction relativeTime (number, withoutSuffix, string, isFuture) {\n    var output = this._relativeTime[string];\n    return (isFunction(output)) ?\n        output(number, withoutSuffix, string, isFuture) :\n        output.replace(/%d/i, number);\n}\n\nfunction pastFuture (diff, output) {\n    var format = this._relativeTime[diff > 0 ? 'future' : 'past'];\n    return isFunction(format) ? format(output) : format.replace(/%s/i, output);\n}\n\nvar aliases = {};\n\nfunction addUnitAlias (unit, shorthand) {\n    var lowerCase = unit.toLowerCase();\n    aliases[lowerCase] = aliases[lowerCase + 's'] = aliases[shorthand] = unit;\n}\n\nfunction normalizeUnits(units) {\n    return typeof units === 'string' ? aliases[units] || aliases[units.toLowerCase()] : undefined;\n}\n\nfunction normalizeObjectUnits(inputObject) {\n    var normalizedInput = {},\n        normalizedProp,\n        prop;\n\n    for (prop in inputObject) {\n        if (hasOwnProp(inputObject, prop)) {\n            normalizedProp = normalizeUnits(prop);\n            if (normalizedProp) {\n                normalizedInput[normalizedProp] = inputObject[prop];\n            }\n        }\n    }\n\n    return normalizedInput;\n}\n\nvar priorities = {};\n\nfunction addUnitPriority(unit, priority) {\n    priorities[unit] = priority;\n}\n\nfunction getPrioritizedUnits(unitsObj) {\n    var units = [];\n    for (var u in unitsObj) {\n        units.push({unit: u, priority: priorities[u]});\n    }\n    units.sort(function (a, b) {\n        return a.priority - b.priority;\n    });\n    return units;\n}\n\nfunction makeGetSet (unit, keepTime) {\n    return function (value) {\n        if (value != null) {\n            set$1(this, unit, value);\n            hooks.updateOffset(this, keepTime);\n            return this;\n        } else {\n            return get(this, unit);\n        }\n    };\n}\n\nfunction get (mom, unit) {\n    return mom.isValid() ?\n        mom._d['get' + (mom._isUTC ? 'UTC' : '') + unit]() : NaN;\n}\n\nfunction set$1 (mom, unit, value) {\n    if (mom.isValid()) {\n        mom._d['set' + (mom._isUTC ? 'UTC' : '') + unit](value);\n    }\n}\n\n// MOMENTS\n\nfunction stringGet (units) {\n    units = normalizeUnits(units);\n    if (isFunction(this[units])) {\n        return this[units]();\n    }\n    return this;\n}\n\n\nfunction stringSet (units, value) {\n    if (typeof units === 'object') {\n        units = normalizeObjectUnits(units);\n        var prioritized = getPrioritizedUnits(units);\n        for (var i = 0; i < prioritized.length; i++) {\n            this[prioritized[i].unit](units[prioritized[i].unit]);\n        }\n    } else {\n        units = normalizeUnits(units);\n        if (isFunction(this[units])) {\n            return this[units](value);\n        }\n    }\n    return this;\n}\n\nfunction zeroFill(number, targetLength, forceSign) {\n    var absNumber = '' + Math.abs(number),\n        zerosToFill = targetLength - absNumber.length,\n        sign = number >= 0;\n    return (sign ? (forceSign ? '+' : '') : '-') +\n        Math.pow(10, Math.max(0, zerosToFill)).toString().substr(1) + absNumber;\n}\n\nvar formattingTokens = /(\\[[^\\[]*\\])|(\\\\)?([Hh]mm(ss)?|Mo|MM?M?M?|Do|DDDo|DD?D?D?|ddd?d?|do?|w[o|w]?|W[o|W]?|Qo?|YYYYYY|YYYYY|YYYY|YY|gg(ggg?)?|GG(GGG?)?|e|E|a|A|hh?|HH?|kk?|mm?|ss?|S{1,9}|x|X|zz?|ZZ?|.)/g;\n\nvar localFormattingTokens = /(\\[[^\\[]*\\])|(\\\\)?(LTS|LT|LL?L?L?|l{1,4})/g;\n\nvar formatFunctions = {};\n\nvar formatTokenFunctions = {};\n\n// token:    'M'\n// padded:   ['MM', 2]\n// ordinal:  'Mo'\n// callback: function () { this.month() + 1 }\nfunction addFormatToken (token, padded, ordinal, callback) {\n    var func = callback;\n    if (typeof callback === 'string') {\n        func = function () {\n            return this[callback]();\n        };\n    }\n    if (token) {\n        formatTokenFunctions[token] = func;\n    }\n    if (padded) {\n        formatTokenFunctions[padded[0]] = function () {\n            return zeroFill(func.apply(this, arguments), padded[1], padded[2]);\n        };\n    }\n    if (ordinal) {\n        formatTokenFunctions[ordinal] = function () {\n            return this.localeData().ordinal(func.apply(this, arguments), token);\n        };\n    }\n}\n\nfunction removeFormattingTokens(input) {\n    if (input.match(/\\[[\\s\\S]/)) {\n        return input.replace(/^\\[|\\]$/g, '');\n    }\n    return input.replace(/\\\\/g, '');\n}\n\nfunction makeFormatFunction(format) {\n    var array = format.match(formattingTokens), i, length;\n\n    for (i = 0, length = array.length; i < length; i++) {\n        if (formatTokenFunctions[array[i]]) {\n            array[i] = formatTokenFunctions[array[i]];\n        } else {\n            array[i] = removeFormattingTokens(array[i]);\n        }\n    }\n\n    return function (mom) {\n        var output = '', i;\n        for (i = 0; i < length; i++) {\n            output += isFunction(array[i]) ? array[i].call(mom, format) : array[i];\n        }\n        return output;\n    };\n}\n\n// format date using native date object\nfunction formatMoment(m, format) {\n    if (!m.isValid()) {\n        return m.localeData().invalidDate();\n    }\n\n    format = expandFormat(format, m.localeData());\n    formatFunctions[format] = formatFunctions[format] || makeFormatFunction(format);\n\n    return formatFunctions[format](m);\n}\n\nfunction expandFormat(format, locale) {\n    var i = 5;\n\n    function replaceLongDateFormatTokens(input) {\n        return locale.longDateFormat(input) || input;\n    }\n\n    localFormattingTokens.lastIndex = 0;\n    while (i >= 0 && localFormattingTokens.test(format)) {\n        format = format.replace(localFormattingTokens, replaceLongDateFormatTokens);\n        localFormattingTokens.lastIndex = 0;\n        i -= 1;\n    }\n\n    return format;\n}\n\nvar match1         = /\\d/;            //       0 - 9\nvar match2         = /\\d\\d/;          //      00 - 99\nvar match3         = /\\d{3}/;         //     000 - 999\nvar match4         = /\\d{4}/;         //    0000 - 9999\nvar match6         = /[+-]?\\d{6}/;    // -999999 - 999999\nvar match1to2      = /\\d\\d?/;         //       0 - 99\nvar match3to4      = /\\d\\d\\d\\d?/;     //     999 - 9999\nvar match5to6      = /\\d\\d\\d\\d\\d\\d?/; //   99999 - 999999\nvar match1to3      = /\\d{1,3}/;       //       0 - 999\nvar match1to4      = /\\d{1,4}/;       //       0 - 9999\nvar match1to6      = /[+-]?\\d{1,6}/;  // -999999 - 999999\n\nvar matchUnsigned  = /\\d+/;           //       0 - inf\nvar matchSigned    = /[+-]?\\d+/;      //    -inf - inf\n\nvar matchOffset    = /Z|[+-]\\d\\d:?\\d\\d/gi; // +00:00 -00:00 +0000 -0000 or Z\nvar matchShortOffset = /Z|[+-]\\d\\d(?::?\\d\\d)?/gi; // +00 -00 +00:00 -00:00 +0000 -0000 or Z\n\nvar matchTimestamp = /[+-]?\\d+(\\.\\d{1,3})?/; // 123456789 123456789.123\n\n// any word (or two) characters or numbers including two/three word month in arabic.\n// includes scottish gaelic two word and hyphenated months\nvar matchWord = /[0-9]*['a-z\\u00A0-\\u05FF\\u0700-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF]+|[\\u0600-\\u06FF\\/]+(\\s*?[\\u0600-\\u06FF]+){1,2}/i;\n\n\nvar regexes = {};\n\nfunction addRegexToken (token, regex, strictRegex) {\n    regexes[token] = isFunction(regex) ? regex : function (isStrict, localeData) {\n        return (isStrict && strictRegex) ? strictRegex : regex;\n    };\n}\n\nfunction getParseRegexForToken (token, config) {\n    if (!hasOwnProp(regexes, token)) {\n        return new RegExp(unescapeFormat(token));\n    }\n\n    return regexes[token](config._strict, config._locale);\n}\n\n// Code from http://stackoverflow.com/questions/3561493/is-there-a-regexp-escape-function-in-javascript\nfunction unescapeFormat(s) {\n    return regexEscape(s.replace('\\\\', '').replace(/\\\\(\\[)|\\\\(\\])|\\[([^\\]\\[]*)\\]|\\\\(.)/g, function (matched, p1, p2, p3, p4) {\n        return p1 || p2 || p3 || p4;\n    }));\n}\n\nfunction regexEscape(s) {\n    return s.replace(/[-\\/\\\\^$*+?.()|[\\]{}]/g, '\\\\$&');\n}\n\nvar tokens = {};\n\nfunction addParseToken (token, callback) {\n    var i, func = callback;\n    if (typeof token === 'string') {\n        token = [token];\n    }\n    if (isNumber(callback)) {\n        func = function (input, array) {\n            array[callback] = toInt(input);\n        };\n    }\n    for (i = 0; i < token.length; i++) {\n        tokens[token[i]] = func;\n    }\n}\n\nfunction addWeekParseToken (token, callback) {\n    addParseToken(token, function (input, array, config, token) {\n        config._w = config._w || {};\n        callback(input, config._w, config, token);\n    });\n}\n\nfunction addTimeToArrayFromToken(token, input, config) {\n    if (input != null && hasOwnProp(tokens, token)) {\n        tokens[token](input, config._a, config, token);\n    }\n}\n\nvar YEAR = 0;\nvar MONTH = 1;\nvar DATE = 2;\nvar HOUR = 3;\nvar MINUTE = 4;\nvar SECOND = 5;\nvar MILLISECOND = 6;\nvar WEEK = 7;\nvar WEEKDAY = 8;\n\nvar indexOf;\n\nif (Array.prototype.indexOf) {\n    indexOf = Array.prototype.indexOf;\n} else {\n    indexOf = function (o) {\n        // I know\n        var i;\n        for (i = 0; i < this.length; ++i) {\n            if (this[i] === o) {\n                return i;\n            }\n        }\n        return -1;\n    };\n}\n\nvar indexOf$1 = indexOf;\n\nfunction daysInMonth(year, month) {\n    return new Date(Date.UTC(year, month + 1, 0)).getUTCDate();\n}\n\n// FORMATTING\n\naddFormatToken('M', ['MM', 2], 'Mo', function () {\n    return this.month() + 1;\n});\n\naddFormatToken('MMM', 0, 0, function (format) {\n    return this.localeData().monthsShort(this, format);\n});\n\naddFormatToken('MMMM', 0, 0, function (format) {\n    return this.localeData().months(this, format);\n});\n\n// ALIASES\n\naddUnitAlias('month', 'M');\n\n// PRIORITY\n\naddUnitPriority('month', 8);\n\n// PARSING\n\naddRegexToken('M',    match1to2);\naddRegexToken('MM',   match1to2, match2);\naddRegexToken('MMM',  function (isStrict, locale) {\n    return locale.monthsShortRegex(isStrict);\n});\naddRegexToken('MMMM', function (isStrict, locale) {\n    return locale.monthsRegex(isStrict);\n});\n\naddParseToken(['M', 'MM'], function (input, array) {\n    array[MONTH] = toInt(input) - 1;\n});\n\naddParseToken(['MMM', 'MMMM'], function (input, array, config, token) {\n    var month = config._locale.monthsParse(input, token, config._strict);\n    // if we didn't find a month name, mark the date as invalid.\n    if (month != null) {\n        array[MONTH] = month;\n    } else {\n        getParsingFlags(config).invalidMonth = input;\n    }\n});\n\n// LOCALES\n\nvar MONTHS_IN_FORMAT = /D[oD]?(\\[[^\\[\\]]*\\]|\\s)+MMMM?/;\nvar defaultLocaleMonths = 'January_February_March_April_May_June_July_August_September_October_November_December'.split('_');\nfunction localeMonths (m, format) {\n    if (!m) {\n        return isArray(this._months) ? this._months :\n            this._months['standalone'];\n    }\n    return isArray(this._months) ? this._months[m.month()] :\n        this._months[(this._months.isFormat || MONTHS_IN_FORMAT).test(format) ? 'format' : 'standalone'][m.month()];\n}\n\nvar defaultLocaleMonthsShort = 'Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec'.split('_');\nfunction localeMonthsShort (m, format) {\n    if (!m) {\n        return isArray(this._monthsShort) ? this._monthsShort :\n            this._monthsShort['standalone'];\n    }\n    return isArray(this._monthsShort) ? this._monthsShort[m.month()] :\n        this._monthsShort[MONTHS_IN_FORMAT.test(format) ? 'format' : 'standalone'][m.month()];\n}\n\nfunction handleStrictParse(monthName, format, strict) {\n    var i, ii, mom, llc = monthName.toLocaleLowerCase();\n    if (!this._monthsParse) {\n        // this is not used\n        this._monthsParse = [];\n        this._longMonthsParse = [];\n        this._shortMonthsParse = [];\n        for (i = 0; i < 12; ++i) {\n            mom = createUTC([2000, i]);\n            this._shortMonthsParse[i] = this.monthsShort(mom, '').toLocaleLowerCase();\n            this._longMonthsParse[i] = this.months(mom, '').toLocaleLowerCase();\n        }\n    }\n\n    if (strict) {\n        if (format === 'MMM') {\n            ii = indexOf$1.call(this._shortMonthsParse, llc);\n            return ii !== -1 ? ii : null;\n        } else {\n            ii = indexOf$1.call(this._longMonthsParse, llc);\n            return ii !== -1 ? ii : null;\n        }\n    } else {\n        if (format === 'MMM') {\n            ii = indexOf$1.call(this._shortMonthsParse, llc);\n            if (ii !== -1) {\n                return ii;\n            }\n            ii = indexOf$1.call(this._longMonthsParse, llc);\n            return ii !== -1 ? ii : null;\n        } else {\n            ii = indexOf$1.call(this._longMonthsParse, llc);\n            if (ii !== -1) {\n                return ii;\n            }\n            ii = indexOf$1.call(this._shortMonthsParse, llc);\n            return ii !== -1 ? ii : null;\n        }\n    }\n}\n\nfunction localeMonthsParse (monthName, format, strict) {\n    var i, mom, regex;\n\n    if (this._monthsParseExact) {\n        return handleStrictParse.call(this, monthName, format, strict);\n    }\n\n    if (!this._monthsParse) {\n        this._monthsParse = [];\n        this._longMonthsParse = [];\n        this._shortMonthsParse = [];\n    }\n\n    // TODO: add sorting\n    // Sorting makes sure if one month (or abbr) is a prefix of another\n    // see sorting in computeMonthsParse\n    for (i = 0; i < 12; i++) {\n        // make the regex if we don't have it already\n        mom = createUTC([2000, i]);\n        if (strict && !this._longMonthsParse[i]) {\n            this._longMonthsParse[i] = new RegExp('^' + this.months(mom, '').replace('.', '') + '$', 'i');\n            this._shortMonthsParse[i] = new RegExp('^' + this.monthsShort(mom, '').replace('.', '') + '$', 'i');\n        }\n        if (!strict && !this._monthsParse[i]) {\n            regex = '^' + this.months(mom, '') + '|^' + this.monthsShort(mom, '');\n            this._monthsParse[i] = new RegExp(regex.replace('.', ''), 'i');\n        }\n        // test the regex\n        if (strict && format === 'MMMM' && this._longMonthsParse[i].test(monthName)) {\n            return i;\n        } else if (strict && format === 'MMM' && this._shortMonthsParse[i].test(monthName)) {\n            return i;\n        } else if (!strict && this._monthsParse[i].test(monthName)) {\n            return i;\n        }\n    }\n}\n\n// MOMENTS\n\nfunction setMonth (mom, value) {\n    var dayOfMonth;\n\n    if (!mom.isValid()) {\n        // No op\n        return mom;\n    }\n\n    if (typeof value === 'string') {\n        if (/^\\d+$/.test(value)) {\n            value = toInt(value);\n        } else {\n            value = mom.localeData().monthsParse(value);\n            // TODO: Another silent failure?\n            if (!isNumber(value)) {\n                return mom;\n            }\n        }\n    }\n\n    dayOfMonth = Math.min(mom.date(), daysInMonth(mom.year(), value));\n    mom._d['set' + (mom._isUTC ? 'UTC' : '') + 'Month'](value, dayOfMonth);\n    return mom;\n}\n\nfunction getSetMonth (value) {\n    if (value != null) {\n        setMonth(this, value);\n        hooks.updateOffset(this, true);\n        return this;\n    } else {\n        return get(this, 'Month');\n    }\n}\n\nfunction getDaysInMonth () {\n    return daysInMonth(this.year(), this.month());\n}\n\nvar defaultMonthsShortRegex = matchWord;\nfunction monthsShortRegex (isStrict) {\n    if (this._monthsParseExact) {\n        if (!hasOwnProp(this, '_monthsRegex')) {\n            computeMonthsParse.call(this);\n        }\n        if (isStrict) {\n            return this._monthsShortStrictRegex;\n        } else {\n            return this._monthsShortRegex;\n        }\n    } else {\n        if (!hasOwnProp(this, '_monthsShortRegex')) {\n            this._monthsShortRegex = defaultMonthsShortRegex;\n        }\n        return this._monthsShortStrictRegex && isStrict ?\n            this._monthsShortStrictRegex : this._monthsShortRegex;\n    }\n}\n\nvar defaultMonthsRegex = matchWord;\nfunction monthsRegex (isStrict) {\n    if (this._monthsParseExact) {\n        if (!hasOwnProp(this, '_monthsRegex')) {\n            computeMonthsParse.call(this);\n        }\n        if (isStrict) {\n            return this._monthsStrictRegex;\n        } else {\n            return this._monthsRegex;\n        }\n    } else {\n        if (!hasOwnProp(this, '_monthsRegex')) {\n            this._monthsRegex = defaultMonthsRegex;\n        }\n        return this._monthsStrictRegex && isStrict ?\n            this._monthsStrictRegex : this._monthsRegex;\n    }\n}\n\nfunction computeMonthsParse () {\n    function cmpLenRev(a, b) {\n        return b.length - a.length;\n    }\n\n    var shortPieces = [], longPieces = [], mixedPieces = [],\n        i, mom;\n    for (i = 0; i < 12; i++) {\n        // make the regex if we don't have it already\n        mom = createUTC([2000, i]);\n        shortPieces.push(this.monthsShort(mom, ''));\n        longPieces.push(this.months(mom, ''));\n        mixedPieces.push(this.months(mom, ''));\n        mixedPieces.push(this.monthsShort(mom, ''));\n    }\n    // Sorting makes sure if one month (or abbr) is a prefix of another it\n    // will match the longer piece.\n    shortPieces.sort(cmpLenRev);\n    longPieces.sort(cmpLenRev);\n    mixedPieces.sort(cmpLenRev);\n    for (i = 0; i < 12; i++) {\n        shortPieces[i] = regexEscape(shortPieces[i]);\n        longPieces[i] = regexEscape(longPieces[i]);\n    }\n    for (i = 0; i < 24; i++) {\n        mixedPieces[i] = regexEscape(mixedPieces[i]);\n    }\n\n    this._monthsRegex = new RegExp('^(' + mixedPieces.join('|') + ')', 'i');\n    this._monthsShortRegex = this._monthsRegex;\n    this._monthsStrictRegex = new RegExp('^(' + longPieces.join('|') + ')', 'i');\n    this._monthsShortStrictRegex = new RegExp('^(' + shortPieces.join('|') + ')', 'i');\n}\n\n// FORMATTING\n\naddFormatToken('Y', 0, 0, function () {\n    var y = this.year();\n    return y <= 9999 ? '' + y : '+' + y;\n});\n\naddFormatToken(0, ['YY', 2], 0, function () {\n    return this.year() % 100;\n});\n\naddFormatToken(0, ['YYYY',   4],       0, 'year');\naddFormatToken(0, ['YYYYY',  5],       0, 'year');\naddFormatToken(0, ['YYYYYY', 6, true], 0, 'year');\n\n// ALIASES\n\naddUnitAlias('year', 'y');\n\n// PRIORITIES\n\naddUnitPriority('year', 1);\n\n// PARSING\n\naddRegexToken('Y',      matchSigned);\naddRegexToken('YY',     match1to2, match2);\naddRegexToken('YYYY',   match1to4, match4);\naddRegexToken('YYYYY',  match1to6, match6);\naddRegexToken('YYYYYY', match1to6, match6);\n\naddParseToken(['YYYYY', 'YYYYYY'], YEAR);\naddParseToken('YYYY', function (input, array) {\n    array[YEAR] = input.length === 2 ? hooks.parseTwoDigitYear(input) : toInt(input);\n});\naddParseToken('YY', function (input, array) {\n    array[YEAR] = hooks.parseTwoDigitYear(input);\n});\naddParseToken('Y', function (input, array) {\n    array[YEAR] = parseInt(input, 10);\n});\n\n// HELPERS\n\nfunction daysInYear(year) {\n    return isLeapYear(year) ? 366 : 365;\n}\n\nfunction isLeapYear(year) {\n    return (year % 4 === 0 && year % 100 !== 0) || year % 400 === 0;\n}\n\n// HOOKS\n\nhooks.parseTwoDigitYear = function (input) {\n    return toInt(input) + (toInt(input) > 68 ? 1900 : 2000);\n};\n\n// MOMENTS\n\nvar getSetYear = makeGetSet('FullYear', true);\n\nfunction getIsLeapYear () {\n    return isLeapYear(this.year());\n}\n\nfunction createDate (y, m, d, h, M, s, ms) {\n    // can't just apply() to create a date:\n    // https://stackoverflow.com/q/181348\n    var date = new Date(y, m, d, h, M, s, ms);\n\n    // the date constructor remaps years 0-99 to 1900-1999\n    if (y < 100 && y >= 0 && isFinite(date.getFullYear())) {\n        date.setFullYear(y);\n    }\n    return date;\n}\n\nfunction createUTCDate (y) {\n    var date = new Date(Date.UTC.apply(null, arguments));\n\n    // the Date.UTC function remaps years 0-99 to 1900-1999\n    if (y < 100 && y >= 0 && isFinite(date.getUTCFullYear())) {\n        date.setUTCFullYear(y);\n    }\n    return date;\n}\n\n// start-of-first-week - start-of-year\nfunction firstWeekOffset(year, dow, doy) {\n    var // first-week day -- which january is always in the first week (4 for iso, 1 for other)\n        fwd = 7 + dow - doy,\n        // first-week day local weekday -- which local weekday is fwd\n        fwdlw = (7 + createUTCDate(year, 0, fwd).getUTCDay() - dow) % 7;\n\n    return -fwdlw + fwd - 1;\n}\n\n// https://en.wikipedia.org/wiki/ISO_week_date#Calculating_a_date_given_the_year.2C_week_number_and_weekday\nfunction dayOfYearFromWeeks(year, week, weekday, dow, doy) {\n    var localWeekday = (7 + weekday - dow) % 7,\n        weekOffset = firstWeekOffset(year, dow, doy),\n        dayOfYear = 1 + 7 * (week - 1) + localWeekday + weekOffset,\n        resYear, resDayOfYear;\n\n    if (dayOfYear <= 0) {\n        resYear = year - 1;\n        resDayOfYear = daysInYear(resYear) + dayOfYear;\n    } else if (dayOfYear > daysInYear(year)) {\n        resYear = year + 1;\n        resDayOfYear = dayOfYear - daysInYear(year);\n    } else {\n        resYear = year;\n        resDayOfYear = dayOfYear;\n    }\n\n    return {\n        year: resYear,\n        dayOfYear: resDayOfYear\n    };\n}\n\nfunction weekOfYear(mom, dow, doy) {\n    var weekOffset = firstWeekOffset(mom.year(), dow, doy),\n        week = Math.floor((mom.dayOfYear() - weekOffset - 1) / 7) + 1,\n        resWeek, resYear;\n\n    if (week < 1) {\n        resYear = mom.year() - 1;\n        resWeek = week + weeksInYear(resYear, dow, doy);\n    } else if (week > weeksInYear(mom.year(), dow, doy)) {\n        resWeek = week - weeksInYear(mom.year(), dow, doy);\n        resYear = mom.year() + 1;\n    } else {\n        resYear = mom.year();\n        resWeek = week;\n    }\n\n    return {\n        week: resWeek,\n        year: resYear\n    };\n}\n\nfunction weeksInYear(year, dow, doy) {\n    var weekOffset = firstWeekOffset(year, dow, doy),\n        weekOffsetNext = firstWeekOffset(year + 1, dow, doy);\n    return (daysInYear(year) - weekOffset + weekOffsetNext) / 7;\n}\n\n// FORMATTING\n\naddFormatToken('w', ['ww', 2], 'wo', 'week');\naddFormatToken('W', ['WW', 2], 'Wo', 'isoWeek');\n\n// ALIASES\n\naddUnitAlias('week', 'w');\naddUnitAlias('isoWeek', 'W');\n\n// PRIORITIES\n\naddUnitPriority('week', 5);\naddUnitPriority('isoWeek', 5);\n\n// PARSING\n\naddRegexToken('w',  match1to2);\naddRegexToken('ww', match1to2, match2);\naddRegexToken('W',  match1to2);\naddRegexToken('WW', match1to2, match2);\n\naddWeekParseToken(['w', 'ww', 'W', 'WW'], function (input, week, config, token) {\n    week[token.substr(0, 1)] = toInt(input);\n});\n\n// HELPERS\n\n// LOCALES\n\nfunction localeWeek (mom) {\n    return weekOfYear(mom, this._week.dow, this._week.doy).week;\n}\n\nvar defaultLocaleWeek = {\n    dow : 0, // Sunday is the first day of the week.\n    doy : 6  // The week that contains Jan 1st is the first week of the year.\n};\n\nfunction localeFirstDayOfWeek () {\n    return this._week.dow;\n}\n\nfunction localeFirstDayOfYear () {\n    return this._week.doy;\n}\n\n// MOMENTS\n\nfunction getSetWeek (input) {\n    var week = this.localeData().week(this);\n    return input == null ? week : this.add((input - week) * 7, 'd');\n}\n\nfunction getSetISOWeek (input) {\n    var week = weekOfYear(this, 1, 4).week;\n    return input == null ? week : this.add((input - week) * 7, 'd');\n}\n\n// FORMATTING\n\naddFormatToken('d', 0, 'do', 'day');\n\naddFormatToken('dd', 0, 0, function (format) {\n    return this.localeData().weekdaysMin(this, format);\n});\n\naddFormatToken('ddd', 0, 0, function (format) {\n    return this.localeData().weekdaysShort(this, format);\n});\n\naddFormatToken('dddd', 0, 0, function (format) {\n    return this.localeData().weekdays(this, format);\n});\n\naddFormatToken('e', 0, 0, 'weekday');\naddFormatToken('E', 0, 0, 'isoWeekday');\n\n// ALIASES\n\naddUnitAlias('day', 'd');\naddUnitAlias('weekday', 'e');\naddUnitAlias('isoWeekday', 'E');\n\n// PRIORITY\naddUnitPriority('day', 11);\naddUnitPriority('weekday', 11);\naddUnitPriority('isoWeekday', 11);\n\n// PARSING\n\naddRegexToken('d',    match1to2);\naddRegexToken('e',    match1to2);\naddRegexToken('E',    match1to2);\naddRegexToken('dd',   function (isStrict, locale) {\n    return locale.weekdaysMinRegex(isStrict);\n});\naddRegexToken('ddd',   function (isStrict, locale) {\n    return locale.weekdaysShortRegex(isStrict);\n});\naddRegexToken('dddd',   function (isStrict, locale) {\n    return locale.weekdaysRegex(isStrict);\n});\n\naddWeekParseToken(['dd', 'ddd', 'dddd'], function (input, week, config, token) {\n    var weekday = config._locale.weekdaysParse(input, token, config._strict);\n    // if we didn't get a weekday name, mark the date as invalid\n    if (weekday != null) {\n        week.d = weekday;\n    } else {\n        getParsingFlags(config).invalidWeekday = input;\n    }\n});\n\naddWeekParseToken(['d', 'e', 'E'], function (input, week, config, token) {\n    week[token] = toInt(input);\n});\n\n// HELPERS\n\nfunction parseWeekday(input, locale) {\n    if (typeof input !== 'string') {\n        return input;\n    }\n\n    if (!isNaN(input)) {\n        return parseInt(input, 10);\n    }\n\n    input = locale.weekdaysParse(input);\n    if (typeof input === 'number') {\n        return input;\n    }\n\n    return null;\n}\n\nfunction parseIsoWeekday(input, locale) {\n    if (typeof input === 'string') {\n        return locale.weekdaysParse(input) % 7 || 7;\n    }\n    return isNaN(input) ? null : input;\n}\n\n// LOCALES\n\nvar defaultLocaleWeekdays = 'Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday'.split('_');\nfunction localeWeekdays (m, format) {\n    if (!m) {\n        return isArray(this._weekdays) ? this._weekdays :\n            this._weekdays['standalone'];\n    }\n    return isArray(this._weekdays) ? this._weekdays[m.day()] :\n        this._weekdays[this._weekdays.isFormat.test(format) ? 'format' : 'standalone'][m.day()];\n}\n\nvar defaultLocaleWeekdaysShort = 'Sun_Mon_Tue_Wed_Thu_Fri_Sat'.split('_');\nfunction localeWeekdaysShort (m) {\n    return (m) ? this._weekdaysShort[m.day()] : this._weekdaysShort;\n}\n\nvar defaultLocaleWeekdaysMin = 'Su_Mo_Tu_We_Th_Fr_Sa'.split('_');\nfunction localeWeekdaysMin (m) {\n    return (m) ? this._weekdaysMin[m.day()] : this._weekdaysMin;\n}\n\nfunction handleStrictParse$1(weekdayName, format, strict) {\n    var i, ii, mom, llc = weekdayName.toLocaleLowerCase();\n    if (!this._weekdaysParse) {\n        this._weekdaysParse = [];\n        this._shortWeekdaysParse = [];\n        this._minWeekdaysParse = [];\n\n        for (i = 0; i < 7; ++i) {\n            mom = createUTC([2000, 1]).day(i);\n            this._minWeekdaysParse[i] = this.weekdaysMin(mom, '').toLocaleLowerCase();\n            this._shortWeekdaysParse[i] = this.weekdaysShort(mom, '').toLocaleLowerCase();\n            this._weekdaysParse[i] = this.weekdays(mom, '').toLocaleLowerCase();\n        }\n    }\n\n    if (strict) {\n        if (format === 'dddd') {\n            ii = indexOf$1.call(this._weekdaysParse, llc);\n            return ii !== -1 ? ii : null;\n        } else if (format === 'ddd') {\n            ii = indexOf$1.call(this._shortWeekdaysParse, llc);\n            return ii !== -1 ? ii : null;\n        } else {\n            ii = indexOf$1.call(this._minWeekdaysParse, llc);\n            return ii !== -1 ? ii : null;\n        }\n    } else {\n        if (format === 'dddd') {\n            ii = indexOf$1.call(this._weekdaysParse, llc);\n            if (ii !== -1) {\n                return ii;\n            }\n            ii = indexOf$1.call(this._shortWeekdaysParse, llc);\n            if (ii !== -1) {\n                return ii;\n            }\n            ii = indexOf$1.call(this._minWeekdaysParse, llc);\n            return ii !== -1 ? ii : null;\n        } else if (format === 'ddd') {\n            ii = indexOf$1.call(this._shortWeekdaysParse, llc);\n            if (ii !== -1) {\n                return ii;\n            }\n            ii = indexOf$1.call(this._weekdaysParse, llc);\n            if (ii !== -1) {\n                return ii;\n            }\n            ii = indexOf$1.call(this._minWeekdaysParse, llc);\n            return ii !== -1 ? ii : null;\n        } else {\n            ii = indexOf$1.call(this._minWeekdaysParse, llc);\n            if (ii !== -1) {\n                return ii;\n            }\n            ii = indexOf$1.call(this._weekdaysParse, llc);\n            if (ii !== -1) {\n                return ii;\n            }\n            ii = indexOf$1.call(this._shortWeekdaysParse, llc);\n            return ii !== -1 ? ii : null;\n        }\n    }\n}\n\nfunction localeWeekdaysParse (weekdayName, format, strict) {\n    var i, mom, regex;\n\n    if (this._weekdaysParseExact) {\n        return handleStrictParse$1.call(this, weekdayName, format, strict);\n    }\n\n    if (!this._weekdaysParse) {\n        this._weekdaysParse = [];\n        this._minWeekdaysParse = [];\n        this._shortWeekdaysParse = [];\n        this._fullWeekdaysParse = [];\n    }\n\n    for (i = 0; i < 7; i++) {\n        // make the regex if we don't have it already\n\n        mom = createUTC([2000, 1]).day(i);\n        if (strict && !this._fullWeekdaysParse[i]) {\n            this._fullWeekdaysParse[i] = new RegExp('^' + this.weekdays(mom, '').replace('.', '\\.?') + '$', 'i');\n            this._shortWeekdaysParse[i] = new RegExp('^' + this.weekdaysShort(mom, '').replace('.', '\\.?') + '$', 'i');\n            this._minWeekdaysParse[i] = new RegExp('^' + this.weekdaysMin(mom, '').replace('.', '\\.?') + '$', 'i');\n        }\n        if (!this._weekdaysParse[i]) {\n            regex = '^' + this.weekdays(mom, '') + '|^' + this.weekdaysShort(mom, '') + '|^' + this.weekdaysMin(mom, '');\n            this._weekdaysParse[i] = new RegExp(regex.replace('.', ''), 'i');\n        }\n        // test the regex\n        if (strict && format === 'dddd' && this._fullWeekdaysParse[i].test(weekdayName)) {\n            return i;\n        } else if (strict && format === 'ddd' && this._shortWeekdaysParse[i].test(weekdayName)) {\n            return i;\n        } else if (strict && format === 'dd' && this._minWeekdaysParse[i].test(weekdayName)) {\n            return i;\n        } else if (!strict && this._weekdaysParse[i].test(weekdayName)) {\n            return i;\n        }\n    }\n}\n\n// MOMENTS\n\nfunction getSetDayOfWeek (input) {\n    if (!this.isValid()) {\n        return input != null ? this : NaN;\n    }\n    var day = this._isUTC ? this._d.getUTCDay() : this._d.getDay();\n    if (input != null) {\n        input = parseWeekday(input, this.localeData());\n        return this.add(input - day, 'd');\n    } else {\n        return day;\n    }\n}\n\nfunction getSetLocaleDayOfWeek (input) {\n    if (!this.isValid()) {\n        return input != null ? this : NaN;\n    }\n    var weekday = (this.day() + 7 - this.localeData()._week.dow) % 7;\n    return input == null ? weekday : this.add(input - weekday, 'd');\n}\n\nfunction getSetISODayOfWeek (input) {\n    if (!this.isValid()) {\n        return input != null ? this : NaN;\n    }\n\n    // behaves the same as moment#day except\n    // as a getter, returns 7 instead of 0 (1-7 range instead of 0-6)\n    // as a setter, sunday should belong to the previous week.\n\n    if (input != null) {\n        var weekday = parseIsoWeekday(input, this.localeData());\n        return this.day(this.day() % 7 ? weekday : weekday - 7);\n    } else {\n        return this.day() || 7;\n    }\n}\n\nvar defaultWeekdaysRegex = matchWord;\nfunction weekdaysRegex (isStrict) {\n    if (this._weekdaysParseExact) {\n        if (!hasOwnProp(this, '_weekdaysRegex')) {\n            computeWeekdaysParse.call(this);\n        }\n        if (isStrict) {\n            return this._weekdaysStrictRegex;\n        } else {\n            return this._weekdaysRegex;\n        }\n    } else {\n        if (!hasOwnProp(this, '_weekdaysRegex')) {\n            this._weekdaysRegex = defaultWeekdaysRegex;\n        }\n        return this._weekdaysStrictRegex && isStrict ?\n            this._weekdaysStrictRegex : this._weekdaysRegex;\n    }\n}\n\nvar defaultWeekdaysShortRegex = matchWord;\nfunction weekdaysShortRegex (isStrict) {\n    if (this._weekdaysParseExact) {\n        if (!hasOwnProp(this, '_weekdaysRegex')) {\n            computeWeekdaysParse.call(this);\n        }\n        if (isStrict) {\n            return this._weekdaysShortStrictRegex;\n        } else {\n            return this._weekdaysShortRegex;\n        }\n    } else {\n        if (!hasOwnProp(this, '_weekdaysShortRegex')) {\n            this._weekdaysShortRegex = defaultWeekdaysShortRegex;\n        }\n        return this._weekdaysShortStrictRegex && isStrict ?\n            this._weekdaysShortStrictRegex : this._weekdaysShortRegex;\n    }\n}\n\nvar defaultWeekdaysMinRegex = matchWord;\nfunction weekdaysMinRegex (isStrict) {\n    if (this._weekdaysParseExact) {\n        if (!hasOwnProp(this, '_weekdaysRegex')) {\n            computeWeekdaysParse.call(this);\n        }\n        if (isStrict) {\n            return this._weekdaysMinStrictRegex;\n        } else {\n            return this._weekdaysMinRegex;\n        }\n    } else {\n        if (!hasOwnProp(this, '_weekdaysMinRegex')) {\n            this._weekdaysMinRegex = defaultWeekdaysMinRegex;\n        }\n        return this._weekdaysMinStrictRegex && isStrict ?\n            this._weekdaysMinStrictRegex : this._weekdaysMinRegex;\n    }\n}\n\n\nfunction computeWeekdaysParse () {\n    function cmpLenRev(a, b) {\n        return b.length - a.length;\n    }\n\n    var minPieces = [], shortPieces = [], longPieces = [], mixedPieces = [],\n        i, mom, minp, shortp, longp;\n    for (i = 0; i < 7; i++) {\n        // make the regex if we don't have it already\n        mom = createUTC([2000, 1]).day(i);\n        minp = this.weekdaysMin(mom, '');\n        shortp = this.weekdaysShort(mom, '');\n        longp = this.weekdays(mom, '');\n        minPieces.push(minp);\n        shortPieces.push(shortp);\n        longPieces.push(longp);\n        mixedPieces.push(minp);\n        mixedPieces.push(shortp);\n        mixedPieces.push(longp);\n    }\n    // Sorting makes sure if one weekday (or abbr) is a prefix of another it\n    // will match the longer piece.\n    minPieces.sort(cmpLenRev);\n    shortPieces.sort(cmpLenRev);\n    longPieces.sort(cmpLenRev);\n    mixedPieces.sort(cmpLenRev);\n    for (i = 0; i < 7; i++) {\n        shortPieces[i] = regexEscape(shortPieces[i]);\n        longPieces[i] = regexEscape(longPieces[i]);\n        mixedPieces[i] = regexEscape(mixedPieces[i]);\n    }\n\n    this._weekdaysRegex = new RegExp('^(' + mixedPieces.join('|') + ')', 'i');\n    this._weekdaysShortRegex = this._weekdaysRegex;\n    this._weekdaysMinRegex = this._weekdaysRegex;\n\n    this._weekdaysStrictRegex = new RegExp('^(' + longPieces.join('|') + ')', 'i');\n    this._weekdaysShortStrictRegex = new RegExp('^(' + shortPieces.join('|') + ')', 'i');\n    this._weekdaysMinStrictRegex = new RegExp('^(' + minPieces.join('|') + ')', 'i');\n}\n\n// FORMATTING\n\nfunction hFormat() {\n    return this.hours() % 12 || 12;\n}\n\nfunction kFormat() {\n    return this.hours() || 24;\n}\n\naddFormatToken('H', ['HH', 2], 0, 'hour');\naddFormatToken('h', ['hh', 2], 0, hFormat);\naddFormatToken('k', ['kk', 2], 0, kFormat);\n\naddFormatToken('hmm', 0, 0, function () {\n    return '' + hFormat.apply(this) + zeroFill(this.minutes(), 2);\n});\n\naddFormatToken('hmmss', 0, 0, function () {\n    return '' + hFormat.apply(this) + zeroFill(this.minutes(), 2) +\n        zeroFill(this.seconds(), 2);\n});\n\naddFormatToken('Hmm', 0, 0, function () {\n    return '' + this.hours() + zeroFill(this.minutes(), 2);\n});\n\naddFormatToken('Hmmss', 0, 0, function () {\n    return '' + this.hours() + zeroFill(this.minutes(), 2) +\n        zeroFill(this.seconds(), 2);\n});\n\nfunction meridiem (token, lowercase) {\n    addFormatToken(token, 0, 0, function () {\n        return this.localeData().meridiem(this.hours(), this.minutes(), lowercase);\n    });\n}\n\nmeridiem('a', true);\nmeridiem('A', false);\n\n// ALIASES\n\naddUnitAlias('hour', 'h');\n\n// PRIORITY\naddUnitPriority('hour', 13);\n\n// PARSING\n\nfunction matchMeridiem (isStrict, locale) {\n    return locale._meridiemParse;\n}\n\naddRegexToken('a',  matchMeridiem);\naddRegexToken('A',  matchMeridiem);\naddRegexToken('H',  match1to2);\naddRegexToken('h',  match1to2);\naddRegexToken('k',  match1to2);\naddRegexToken('HH', match1to2, match2);\naddRegexToken('hh', match1to2, match2);\naddRegexToken('kk', match1to2, match2);\n\naddRegexToken('hmm', match3to4);\naddRegexToken('hmmss', match5to6);\naddRegexToken('Hmm', match3to4);\naddRegexToken('Hmmss', match5to6);\n\naddParseToken(['H', 'HH'], HOUR);\naddParseToken(['k', 'kk'], function (input, array, config) {\n    var kInput = toInt(input);\n    array[HOUR] = kInput === 24 ? 0 : kInput;\n});\naddParseToken(['a', 'A'], function (input, array, config) {\n    config._isPm = config._locale.isPM(input);\n    config._meridiem = input;\n});\naddParseToken(['h', 'hh'], function (input, array, config) {\n    array[HOUR] = toInt(input);\n    getParsingFlags(config).bigHour = true;\n});\naddParseToken('hmm', function (input, array, config) {\n    var pos = input.length - 2;\n    array[HOUR] = toInt(input.substr(0, pos));\n    array[MINUTE] = toInt(input.substr(pos));\n    getParsingFlags(config).bigHour = true;\n});\naddParseToken('hmmss', function (input, array, config) {\n    var pos1 = input.length - 4;\n    var pos2 = input.length - 2;\n    array[HOUR] = toInt(input.substr(0, pos1));\n    array[MINUTE] = toInt(input.substr(pos1, 2));\n    array[SECOND] = toInt(input.substr(pos2));\n    getParsingFlags(config).bigHour = true;\n});\naddParseToken('Hmm', function (input, array, config) {\n    var pos = input.length - 2;\n    array[HOUR] = toInt(input.substr(0, pos));\n    array[MINUTE] = toInt(input.substr(pos));\n});\naddParseToken('Hmmss', function (input, array, config) {\n    var pos1 = input.length - 4;\n    var pos2 = input.length - 2;\n    array[HOUR] = toInt(input.substr(0, pos1));\n    array[MINUTE] = toInt(input.substr(pos1, 2));\n    array[SECOND] = toInt(input.substr(pos2));\n});\n\n// LOCALES\n\nfunction localeIsPM (input) {\n    // IE8 Quirks Mode & IE7 Standards Mode do not allow accessing strings like arrays\n    // Using charAt should be more compatible.\n    return ((input + '').toLowerCase().charAt(0) === 'p');\n}\n\nvar defaultLocaleMeridiemParse = /[ap]\\.?m?\\.?/i;\nfunction localeMeridiem (hours, minutes, isLower) {\n    if (hours > 11) {\n        return isLower ? 'pm' : 'PM';\n    } else {\n        return isLower ? 'am' : 'AM';\n    }\n}\n\n\n// MOMENTS\n\n// Setting the hour should keep the time, because the user explicitly\n// specified which hour he wants. So trying to maintain the same hour (in\n// a new timezone) makes sense. Adding/subtracting hours does not follow\n// this rule.\nvar getSetHour = makeGetSet('Hours', true);\n\n// months\n// week\n// weekdays\n// meridiem\nvar baseConfig = {\n    calendar: defaultCalendar,\n    longDateFormat: defaultLongDateFormat,\n    invalidDate: defaultInvalidDate,\n    ordinal: defaultOrdinal,\n    dayOfMonthOrdinalParse: defaultDayOfMonthOrdinalParse,\n    relativeTime: defaultRelativeTime,\n\n    months: defaultLocaleMonths,\n    monthsShort: defaultLocaleMonthsShort,\n\n    week: defaultLocaleWeek,\n\n    weekdays: defaultLocaleWeekdays,\n    weekdaysMin: defaultLocaleWeekdaysMin,\n    weekdaysShort: defaultLocaleWeekdaysShort,\n\n    meridiemParse: defaultLocaleMeridiemParse\n};\n\n// internal storage for locale config files\nvar locales = {};\nvar localeFamilies = {};\nvar globalLocale;\n\nfunction normalizeLocale(key) {\n    return key ? key.toLowerCase().replace('_', '-') : key;\n}\n\n// pick the locale from the array\n// try ['en-au', 'en-gb'] as 'en-au', 'en-gb', 'en', as in move through the list trying each\n// substring from most specific to least, but move to the next array item if it's a more specific variant than the current root\nfunction chooseLocale(names) {\n    var i = 0, j, next, locale, split;\n\n    while (i < names.length) {\n        split = normalizeLocale(names[i]).split('-');\n        j = split.length;\n        next = normalizeLocale(names[i + 1]);\n        next = next ? next.split('-') : null;\n        while (j > 0) {\n            locale = loadLocale(split.slice(0, j).join('-'));\n            if (locale) {\n                return locale;\n            }\n            if (next && next.length >= j && compareArrays(split, next, true) >= j - 1) {\n                //the next array item is better than a shallower substring of this one\n                break;\n            }\n            j--;\n        }\n        i++;\n    }\n    return null;\n}\n\nfunction loadLocale(name) {\n    var oldLocale = null;\n    // TODO: Find a better way to register and load all the locales in Node\n    if (!locales[name] && (typeof module !== 'undefined') &&\n            module && module.exports) {\n        try {\n            oldLocale = globalLocale._abbr;\n            require('./locale/' + name);\n            // because defineLocale currently also sets the global locale, we\n            // want to undo that for lazy loaded locales\n            getSetGlobalLocale(oldLocale);\n        } catch (e) { }\n    }\n    return locales[name];\n}\n\n// This function will load locale and then set the global locale.  If\n// no arguments are passed in, it will simply return the current global\n// locale key.\nfunction getSetGlobalLocale (key, values) {\n    var data;\n    if (key) {\n        if (isUndefined(values)) {\n            data = getLocale(key);\n        }\n        else {\n            data = defineLocale(key, values);\n        }\n\n        if (data) {\n            // moment.duration._locale = moment._locale = data;\n            globalLocale = data;\n        }\n    }\n\n    return globalLocale._abbr;\n}\n\nfunction defineLocale (name, config) {\n    if (config !== null) {\n        var parentConfig = baseConfig;\n        config.abbr = name;\n        if (locales[name] != null) {\n            deprecateSimple('defineLocaleOverride',\n                    'use moment.updateLocale(localeName, config) to change ' +\n                    'an existing locale. moment.defineLocale(localeName, ' +\n                    'config) should only be used for creating a new locale ' +\n                    'See http://momentjs.com/guides/#/warnings/define-locale/ for more info.');\n            parentConfig = locales[name]._config;\n        } else if (config.parentLocale != null) {\n            if (locales[config.parentLocale] != null) {\n                parentConfig = locales[config.parentLocale]._config;\n            } else {\n                if (!localeFamilies[config.parentLocale]) {\n                    localeFamilies[config.parentLocale] = [];\n                }\n                localeFamilies[config.parentLocale].push({\n                    name: name,\n                    config: config\n                });\n                return null;\n            }\n        }\n        locales[name] = new Locale(mergeConfigs(parentConfig, config));\n\n        if (localeFamilies[name]) {\n            localeFamilies[name].forEach(function (x) {\n                defineLocale(x.name, x.config);\n            });\n        }\n\n        // backwards compat for now: also set the locale\n        // make sure we set the locale AFTER all child locales have been\n        // created, so we won't end up with the child locale set.\n        getSetGlobalLocale(name);\n\n\n        return locales[name];\n    } else {\n        // useful for testing\n        delete locales[name];\n        return null;\n    }\n}\n\nfunction updateLocale(name, config) {\n    if (config != null) {\n        var locale, parentConfig = baseConfig;\n        // MERGE\n        if (locales[name] != null) {\n            parentConfig = locales[name]._config;\n        }\n        config = mergeConfigs(parentConfig, config);\n        locale = new Locale(config);\n        locale.parentLocale = locales[name];\n        locales[name] = locale;\n\n        // backwards compat for now: also set the locale\n        getSetGlobalLocale(name);\n    } else {\n        // pass null for config to unupdate, useful for tests\n        if (locales[name] != null) {\n            if (locales[name].parentLocale != null) {\n                locales[name] = locales[name].parentLocale;\n            } else if (locales[name] != null) {\n                delete locales[name];\n            }\n        }\n    }\n    return locales[name];\n}\n\n// returns locale data\nfunction getLocale (key) {\n    var locale;\n\n    if (key && key._locale && key._locale._abbr) {\n        key = key._locale._abbr;\n    }\n\n    if (!key) {\n        return globalLocale;\n    }\n\n    if (!isArray(key)) {\n        //short-circuit everything else\n        locale = loadLocale(key);\n        if (locale) {\n            return locale;\n        }\n        key = [key];\n    }\n\n    return chooseLocale(key);\n}\n\nfunction listLocales() {\n    return keys$1(locales);\n}\n\nfunction checkOverflow (m) {\n    var overflow;\n    var a = m._a;\n\n    if (a && getParsingFlags(m).overflow === -2) {\n        overflow =\n            a[MONTH]       < 0 || a[MONTH]       > 11  ? MONTH :\n            a[DATE]        < 1 || a[DATE]        > daysInMonth(a[YEAR], a[MONTH]) ? DATE :\n            a[HOUR]        < 0 || a[HOUR]        > 24 || (a[HOUR] === 24 && (a[MINUTE] !== 0 || a[SECOND] !== 0 || a[MILLISECOND] !== 0)) ? HOUR :\n            a[MINUTE]      < 0 || a[MINUTE]      > 59  ? MINUTE :\n            a[SECOND]      < 0 || a[SECOND]      > 59  ? SECOND :\n            a[MILLISECOND] < 0 || a[MILLISECOND] > 999 ? MILLISECOND :\n            -1;\n\n        if (getParsingFlags(m)._overflowDayOfYear && (overflow < YEAR || overflow > DATE)) {\n            overflow = DATE;\n        }\n        if (getParsingFlags(m)._overflowWeeks && overflow === -1) {\n            overflow = WEEK;\n        }\n        if (getParsingFlags(m)._overflowWeekday && overflow === -1) {\n            overflow = WEEKDAY;\n        }\n\n        getParsingFlags(m).overflow = overflow;\n    }\n\n    return m;\n}\n\n// iso 8601 regex\n// 0000-00-00 0000-W00 or 0000-W00-0 + T + 00 or 00:00 or 00:00:00 or 00:00:00.000 + +00:00 or +0000 or +00)\nvar extendedIsoRegex = /^\\s*((?:[+-]\\d{6}|\\d{4})-(?:\\d\\d-\\d\\d|W\\d\\d-\\d|W\\d\\d|\\d\\d\\d|\\d\\d))(?:(T| )(\\d\\d(?::\\d\\d(?::\\d\\d(?:[.,]\\d+)?)?)?)([\\+\\-]\\d\\d(?::?\\d\\d)?|\\s*Z)?)?$/;\nvar basicIsoRegex = /^\\s*((?:[+-]\\d{6}|\\d{4})(?:\\d\\d\\d\\d|W\\d\\d\\d|W\\d\\d|\\d\\d\\d|\\d\\d))(?:(T| )(\\d\\d(?:\\d\\d(?:\\d\\d(?:[.,]\\d+)?)?)?)([\\+\\-]\\d\\d(?::?\\d\\d)?|\\s*Z)?)?$/;\n\nvar tzRegex = /Z|[+-]\\d\\d(?::?\\d\\d)?/;\n\nvar isoDates = [\n    ['YYYYYY-MM-DD', /[+-]\\d{6}-\\d\\d-\\d\\d/],\n    ['YYYY-MM-DD', /\\d{4}-\\d\\d-\\d\\d/],\n    ['GGGG-[W]WW-E', /\\d{4}-W\\d\\d-\\d/],\n    ['GGGG-[W]WW', /\\d{4}-W\\d\\d/, false],\n    ['YYYY-DDD', /\\d{4}-\\d{3}/],\n    ['YYYY-MM', /\\d{4}-\\d\\d/, false],\n    ['YYYYYYMMDD', /[+-]\\d{10}/],\n    ['YYYYMMDD', /\\d{8}/],\n    // YYYYMM is NOT allowed by the standard\n    ['GGGG[W]WWE', /\\d{4}W\\d{3}/],\n    ['GGGG[W]WW', /\\d{4}W\\d{2}/, false],\n    ['YYYYDDD', /\\d{7}/]\n];\n\n// iso time formats and regexes\nvar isoTimes = [\n    ['HH:mm:ss.SSSS', /\\d\\d:\\d\\d:\\d\\d\\.\\d+/],\n    ['HH:mm:ss,SSSS', /\\d\\d:\\d\\d:\\d\\d,\\d+/],\n    ['HH:mm:ss', /\\d\\d:\\d\\d:\\d\\d/],\n    ['HH:mm', /\\d\\d:\\d\\d/],\n    ['HHmmss.SSSS', /\\d\\d\\d\\d\\d\\d\\.\\d+/],\n    ['HHmmss,SSSS', /\\d\\d\\d\\d\\d\\d,\\d+/],\n    ['HHmmss', /\\d\\d\\d\\d\\d\\d/],\n    ['HHmm', /\\d\\d\\d\\d/],\n    ['HH', /\\d\\d/]\n];\n\nvar aspNetJsonRegex = /^\\/?Date\\((\\-?\\d+)/i;\n\n// date from iso format\nfunction configFromISO(config) {\n    var i, l,\n        string = config._i,\n        match = extendedIsoRegex.exec(string) || basicIsoRegex.exec(string),\n        allowTime, dateFormat, timeFormat, tzFormat;\n\n    if (match) {\n        getParsingFlags(config).iso = true;\n\n        for (i = 0, l = isoDates.length; i < l; i++) {\n            if (isoDates[i][1].exec(match[1])) {\n                dateFormat = isoDates[i][0];\n                allowTime = isoDates[i][2] !== false;\n                break;\n            }\n        }\n        if (dateFormat == null) {\n            config._isValid = false;\n            return;\n        }\n        if (match[3]) {\n            for (i = 0, l = isoTimes.length; i < l; i++) {\n                if (isoTimes[i][1].exec(match[3])) {\n                    // match[2] should be 'T' or space\n                    timeFormat = (match[2] || ' ') + isoTimes[i][0];\n                    break;\n                }\n            }\n            if (timeFormat == null) {\n                config._isValid = false;\n                return;\n            }\n        }\n        if (!allowTime && timeFormat != null) {\n            config._isValid = false;\n            return;\n        }\n        if (match[4]) {\n            if (tzRegex.exec(match[4])) {\n                tzFormat = 'Z';\n            } else {\n                config._isValid = false;\n                return;\n            }\n        }\n        config._f = dateFormat + (timeFormat || '') + (tzFormat || '');\n        configFromStringAndFormat(config);\n    } else {\n        config._isValid = false;\n    }\n}\n\n// RFC 2822 regex: For details see https://tools.ietf.org/html/rfc2822#section-3.3\nvar basicRfcRegex = /^((?:Mon|Tue|Wed|Thu|Fri|Sat|Sun),?\\s)?(\\d?\\d\\s(?:Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)\\s(?:\\d\\d)?\\d\\d\\s)(\\d\\d:\\d\\d)(\\:\\d\\d)?(\\s(?:UT|GMT|[ECMP][SD]T|[A-IK-Za-ik-z]|[+-]\\d{4}))$/;\n\n// date and time from ref 2822 format\nfunction configFromRFC2822(config) {\n    var string, match, dayFormat,\n        dateFormat, timeFormat, tzFormat;\n    var timezones = {\n        ' GMT': ' +0000',\n        ' EDT': ' -0400',\n        ' EST': ' -0500',\n        ' CDT': ' -0500',\n        ' CST': ' -0600',\n        ' MDT': ' -0600',\n        ' MST': ' -0700',\n        ' PDT': ' -0700',\n        ' PST': ' -0800'\n    };\n    var military = 'YXWVUTSRQPONZABCDEFGHIKLM';\n    var timezone, timezoneIndex;\n\n    string = config._i\n        .replace(/\\([^\\)]*\\)|[\\n\\t]/g, ' ') // Remove comments and folding whitespace\n        .replace(/(\\s\\s+)/g, ' ') // Replace multiple-spaces with a single space\n        .replace(/^\\s|\\s$/g, ''); // Remove leading and trailing spaces\n    match = basicRfcRegex.exec(string);\n\n    if (match) {\n        dayFormat = match[1] ? 'ddd' + ((match[1].length === 5) ? ', ' : ' ') : '';\n        dateFormat = 'D MMM ' + ((match[2].length > 10) ? 'YYYY ' : 'YY ');\n        timeFormat = 'HH:mm' + (match[4] ? ':ss' : '');\n\n        // TODO: Replace the vanilla JS Date object with an indepentent day-of-week check.\n        if (match[1]) { // day of week given\n            var momentDate = new Date(match[2]);\n            var momentDay = ['Sun','Mon','Tue','Wed','Thu','Fri','Sat'][momentDate.getDay()];\n\n            if (match[1].substr(0,3) !== momentDay) {\n                getParsingFlags(config).weekdayMismatch = true;\n                config._isValid = false;\n                return;\n            }\n        }\n\n        switch (match[5].length) {\n            case 2: // military\n                if (timezoneIndex === 0) {\n                    timezone = ' +0000';\n                } else {\n                    timezoneIndex = military.indexOf(match[5][1].toUpperCase()) - 12;\n                    timezone = ((timezoneIndex < 0) ? ' -' : ' +') +\n                        (('' + timezoneIndex).replace(/^-?/, '0')).match(/..$/)[0] + '00';\n                }\n                break;\n            case 4: // Zone\n                timezone = timezones[match[5]];\n                break;\n            default: // UT or +/-9999\n                timezone = timezones[' GMT'];\n        }\n        match[5] = timezone;\n        config._i = match.splice(1).join('');\n        tzFormat = ' ZZ';\n        config._f = dayFormat + dateFormat + timeFormat + tzFormat;\n        configFromStringAndFormat(config);\n        getParsingFlags(config).rfc2822 = true;\n    } else {\n        config._isValid = false;\n    }\n}\n\n// date from iso format or fallback\nfunction configFromString(config) {\n    var matched = aspNetJsonRegex.exec(config._i);\n\n    if (matched !== null) {\n        config._d = new Date(+matched[1]);\n        return;\n    }\n\n    configFromISO(config);\n    if (config._isValid === false) {\n        delete config._isValid;\n    } else {\n        return;\n    }\n\n    configFromRFC2822(config);\n    if (config._isValid === false) {\n        delete config._isValid;\n    } else {\n        return;\n    }\n\n    // Final attempt, use Input Fallback\n    hooks.createFromInputFallback(config);\n}\n\nhooks.createFromInputFallback = deprecate(\n    'value provided is not in a recognized RFC2822 or ISO format. moment construction falls back to js Date(), ' +\n    'which is not reliable across all browsers and versions. Non RFC2822/ISO date formats are ' +\n    'discouraged and will be removed in an upcoming major release. Please refer to ' +\n    'http://momentjs.com/guides/#/warnings/js-date/ for more info.',\n    function (config) {\n        config._d = new Date(config._i + (config._useUTC ? ' UTC' : ''));\n    }\n);\n\n// Pick the first defined of two or three arguments.\nfunction defaults(a, b, c) {\n    if (a != null) {\n        return a;\n    }\n    if (b != null) {\n        return b;\n    }\n    return c;\n}\n\nfunction currentDateArray(config) {\n    // hooks is actually the exported moment object\n    var nowValue = new Date(hooks.now());\n    if (config._useUTC) {\n        return [nowValue.getUTCFullYear(), nowValue.getUTCMonth(), nowValue.getUTCDate()];\n    }\n    return [nowValue.getFullYear(), nowValue.getMonth(), nowValue.getDate()];\n}\n\n// convert an array to a date.\n// the array should mirror the parameters below\n// note: all values past the year are optional and will default to the lowest possible value.\n// [year, month, day , hour, minute, second, millisecond]\nfunction configFromArray (config) {\n    var i, date, input = [], currentDate, yearToUse;\n\n    if (config._d) {\n        return;\n    }\n\n    currentDate = currentDateArray(config);\n\n    //compute day of the year from weeks and weekdays\n    if (config._w && config._a[DATE] == null && config._a[MONTH] == null) {\n        dayOfYearFromWeekInfo(config);\n    }\n\n    //if the day of the year is set, figure out what it is\n    if (config._dayOfYear != null) {\n        yearToUse = defaults(config._a[YEAR], currentDate[YEAR]);\n\n        if (config._dayOfYear > daysInYear(yearToUse) || config._dayOfYear === 0) {\n            getParsingFlags(config)._overflowDayOfYear = true;\n        }\n\n        date = createUTCDate(yearToUse, 0, config._dayOfYear);\n        config._a[MONTH] = date.getUTCMonth();\n        config._a[DATE] = date.getUTCDate();\n    }\n\n    // Default to current date.\n    // * if no year, month, day of month are given, default to today\n    // * if day of month is given, default month and year\n    // * if month is given, default only year\n    // * if year is given, don't default anything\n    for (i = 0; i < 3 && config._a[i] == null; ++i) {\n        config._a[i] = input[i] = currentDate[i];\n    }\n\n    // Zero out whatever was not defaulted, including time\n    for (; i < 7; i++) {\n        config._a[i] = input[i] = (config._a[i] == null) ? (i === 2 ? 1 : 0) : config._a[i];\n    }\n\n    // Check for 24:00:00.000\n    if (config._a[HOUR] === 24 &&\n            config._a[MINUTE] === 0 &&\n            config._a[SECOND] === 0 &&\n            config._a[MILLISECOND] === 0) {\n        config._nextDay = true;\n        config._a[HOUR] = 0;\n    }\n\n    config._d = (config._useUTC ? createUTCDate : createDate).apply(null, input);\n    // Apply timezone offset from input. The actual utcOffset can be changed\n    // with parseZone.\n    if (config._tzm != null) {\n        config._d.setUTCMinutes(config._d.getUTCMinutes() - config._tzm);\n    }\n\n    if (config._nextDay) {\n        config._a[HOUR] = 24;\n    }\n}\n\nfunction dayOfYearFromWeekInfo(config) {\n    var w, weekYear, week, weekday, dow, doy, temp, weekdayOverflow;\n\n    w = config._w;\n    if (w.GG != null || w.W != null || w.E != null) {\n        dow = 1;\n        doy = 4;\n\n        // TODO: We need to take the current isoWeekYear, but that depends on\n        // how we interpret now (local, utc, fixed offset). So create\n        // a now version of current config (take local/utc/offset flags, and\n        // create now).\n        weekYear = defaults(w.GG, config._a[YEAR], weekOfYear(createLocal(), 1, 4).year);\n        week = defaults(w.W, 1);\n        weekday = defaults(w.E, 1);\n        if (weekday < 1 || weekday > 7) {\n            weekdayOverflow = true;\n        }\n    } else {\n        dow = config._locale._week.dow;\n        doy = config._locale._week.doy;\n\n        var curWeek = weekOfYear(createLocal(), dow, doy);\n\n        weekYear = defaults(w.gg, config._a[YEAR], curWeek.year);\n\n        // Default to current week.\n        week = defaults(w.w, curWeek.week);\n\n        if (w.d != null) {\n            // weekday -- low day numbers are considered next week\n            weekday = w.d;\n            if (weekday < 0 || weekday > 6) {\n                weekdayOverflow = true;\n            }\n        } else if (w.e != null) {\n            // local weekday -- counting starts from begining of week\n            weekday = w.e + dow;\n            if (w.e < 0 || w.e > 6) {\n                weekdayOverflow = true;\n            }\n        } else {\n            // default to begining of week\n            weekday = dow;\n        }\n    }\n    if (week < 1 || week > weeksInYear(weekYear, dow, doy)) {\n        getParsingFlags(config)._overflowWeeks = true;\n    } else if (weekdayOverflow != null) {\n        getParsingFlags(config)._overflowWeekday = true;\n    } else {\n        temp = dayOfYearFromWeeks(weekYear, week, weekday, dow, doy);\n        config._a[YEAR] = temp.year;\n        config._dayOfYear = temp.dayOfYear;\n    }\n}\n\n// constant that refers to the ISO standard\nhooks.ISO_8601 = function () {};\n\n// constant that refers to the RFC 2822 form\nhooks.RFC_2822 = function () {};\n\n// date from string and format string\nfunction configFromStringAndFormat(config) {\n    // TODO: Move this to another part of the creation flow to prevent circular deps\n    if (config._f === hooks.ISO_8601) {\n        configFromISO(config);\n        return;\n    }\n    if (config._f === hooks.RFC_2822) {\n        configFromRFC2822(config);\n        return;\n    }\n    config._a = [];\n    getParsingFlags(config).empty = true;\n\n    // This array is used to make a Date, either with `new Date` or `Date.UTC`\n    var string = '' + config._i,\n        i, parsedInput, tokens, token, skipped,\n        stringLength = string.length,\n        totalParsedInputLength = 0;\n\n    tokens = expandFormat(config._f, config._locale).match(formattingTokens) || [];\n\n    for (i = 0; i < tokens.length; i++) {\n        token = tokens[i];\n        parsedInput = (string.match(getParseRegexForToken(token, config)) || [])[0];\n        // console.log('token', token, 'parsedInput', parsedInput,\n        //         'regex', getParseRegexForToken(token, config));\n        if (parsedInput) {\n            skipped = string.substr(0, string.indexOf(parsedInput));\n            if (skipped.length > 0) {\n                getParsingFlags(config).unusedInput.push(skipped);\n            }\n            string = string.slice(string.indexOf(parsedInput) + parsedInput.length);\n            totalParsedInputLength += parsedInput.length;\n        }\n        // don't parse if it's not a known token\n        if (formatTokenFunctions[token]) {\n            if (parsedInput) {\n                getParsingFlags(config).empty = false;\n            }\n            else {\n                getParsingFlags(config).unusedTokens.push(token);\n            }\n            addTimeToArrayFromToken(token, parsedInput, config);\n        }\n        else if (config._strict && !parsedInput) {\n            getParsingFlags(config).unusedTokens.push(token);\n        }\n    }\n\n    // add remaining unparsed input length to the string\n    getParsingFlags(config).charsLeftOver = stringLength - totalParsedInputLength;\n    if (string.length > 0) {\n        getParsingFlags(config).unusedInput.push(string);\n    }\n\n    // clear _12h flag if hour is <= 12\n    if (config._a[HOUR] <= 12 &&\n        getParsingFlags(config).bigHour === true &&\n        config._a[HOUR] > 0) {\n        getParsingFlags(config).bigHour = undefined;\n    }\n\n    getParsingFlags(config).parsedDateParts = config._a.slice(0);\n    getParsingFlags(config).meridiem = config._meridiem;\n    // handle meridiem\n    config._a[HOUR] = meridiemFixWrap(config._locale, config._a[HOUR], config._meridiem);\n\n    configFromArray(config);\n    checkOverflow(config);\n}\n\n\nfunction meridiemFixWrap (locale, hour, meridiem) {\n    var isPm;\n\n    if (meridiem == null) {\n        // nothing to do\n        return hour;\n    }\n    if (locale.meridiemHour != null) {\n        return locale.meridiemHour(hour, meridiem);\n    } else if (locale.isPM != null) {\n        // Fallback\n        isPm = locale.isPM(meridiem);\n        if (isPm && hour < 12) {\n            hour += 12;\n        }\n        if (!isPm && hour === 12) {\n            hour = 0;\n        }\n        return hour;\n    } else {\n        // this is not supposed to happen\n        return hour;\n    }\n}\n\n// date from string and array of format strings\nfunction configFromStringAndArray(config) {\n    var tempConfig,\n        bestMoment,\n\n        scoreToBeat,\n        i,\n        currentScore;\n\n    if (config._f.length === 0) {\n        getParsingFlags(config).invalidFormat = true;\n        config._d = new Date(NaN);\n        return;\n    }\n\n    for (i = 0; i < config._f.length; i++) {\n        currentScore = 0;\n        tempConfig = copyConfig({}, config);\n        if (config._useUTC != null) {\n            tempConfig._useUTC = config._useUTC;\n        }\n        tempConfig._f = config._f[i];\n        configFromStringAndFormat(tempConfig);\n\n        if (!isValid(tempConfig)) {\n            continue;\n        }\n\n        // if there is any input that was not parsed add a penalty for that format\n        currentScore += getParsingFlags(tempConfig).charsLeftOver;\n\n        //or tokens\n        currentScore += getParsingFlags(tempConfig).unusedTokens.length * 10;\n\n        getParsingFlags(tempConfig).score = currentScore;\n\n        if (scoreToBeat == null || currentScore < scoreToBeat) {\n            scoreToBeat = currentScore;\n            bestMoment = tempConfig;\n        }\n    }\n\n    extend(config, bestMoment || tempConfig);\n}\n\nfunction configFromObject(config) {\n    if (config._d) {\n        return;\n    }\n\n    var i = normalizeObjectUnits(config._i);\n    config._a = map([i.year, i.month, i.day || i.date, i.hour, i.minute, i.second, i.millisecond], function (obj) {\n        return obj && parseInt(obj, 10);\n    });\n\n    configFromArray(config);\n}\n\nfunction createFromConfig (config) {\n    var res = new Moment(checkOverflow(prepareConfig(config)));\n    if (res._nextDay) {\n        // Adding is smart enough around DST\n        res.add(1, 'd');\n        res._nextDay = undefined;\n    }\n\n    return res;\n}\n\nfunction prepareConfig (config) {\n    var input = config._i,\n        format = config._f;\n\n    config._locale = config._locale || getLocale(config._l);\n\n    if (input === null || (format === undefined && input === '')) {\n        return createInvalid({nullInput: true});\n    }\n\n    if (typeof input === 'string') {\n        config._i = input = config._locale.preparse(input);\n    }\n\n    if (isMoment(input)) {\n        return new Moment(checkOverflow(input));\n    } else if (isDate(input)) {\n        config._d = input;\n    } else if (isArray(format)) {\n        configFromStringAndArray(config);\n    } else if (format) {\n        configFromStringAndFormat(config);\n    }  else {\n        configFromInput(config);\n    }\n\n    if (!isValid(config)) {\n        config._d = null;\n    }\n\n    return config;\n}\n\nfunction configFromInput(config) {\n    var input = config._i;\n    if (isUndefined(input)) {\n        config._d = new Date(hooks.now());\n    } else if (isDate(input)) {\n        config._d = new Date(input.valueOf());\n    } else if (typeof input === 'string') {\n        configFromString(config);\n    } else if (isArray(input)) {\n        config._a = map(input.slice(0), function (obj) {\n            return parseInt(obj, 10);\n        });\n        configFromArray(config);\n    } else if (isObject(input)) {\n        configFromObject(config);\n    } else if (isNumber(input)) {\n        // from milliseconds\n        config._d = new Date(input);\n    } else {\n        hooks.createFromInputFallback(config);\n    }\n}\n\nfunction createLocalOrUTC (input, format, locale, strict, isUTC) {\n    var c = {};\n\n    if (locale === true || locale === false) {\n        strict = locale;\n        locale = undefined;\n    }\n\n    if ((isObject(input) && isObjectEmpty(input)) ||\n            (isArray(input) && input.length === 0)) {\n        input = undefined;\n    }\n    // object construction must be done this way.\n    // https://github.com/moment/moment/issues/1423\n    c._isAMomentObject = true;\n    c._useUTC = c._isUTC = isUTC;\n    c._l = locale;\n    c._i = input;\n    c._f = format;\n    c._strict = strict;\n\n    return createFromConfig(c);\n}\n\nfunction createLocal (input, format, locale, strict) {\n    return createLocalOrUTC(input, format, locale, strict, false);\n}\n\nvar prototypeMin = deprecate(\n    'moment().min is deprecated, use moment.max instead. http://momentjs.com/guides/#/warnings/min-max/',\n    function () {\n        var other = createLocal.apply(null, arguments);\n        if (this.isValid() && other.isValid()) {\n            return other < this ? this : other;\n        } else {\n            return createInvalid();\n        }\n    }\n);\n\nvar prototypeMax = deprecate(\n    'moment().max is deprecated, use moment.min instead. http://momentjs.com/guides/#/warnings/min-max/',\n    function () {\n        var other = createLocal.apply(null, arguments);\n        if (this.isValid() && other.isValid()) {\n            return other > this ? this : other;\n        } else {\n            return createInvalid();\n        }\n    }\n);\n\n// Pick a moment m from moments so that m[fn](other) is true for all\n// other. This relies on the function fn to be transitive.\n//\n// moments should either be an array of moment objects or an array, whose\n// first element is an array of moment objects.\nfunction pickBy(fn, moments) {\n    var res, i;\n    if (moments.length === 1 && isArray(moments[0])) {\n        moments = moments[0];\n    }\n    if (!moments.length) {\n        return createLocal();\n    }\n    res = moments[0];\n    for (i = 1; i < moments.length; ++i) {\n        if (!moments[i].isValid() || moments[i][fn](res)) {\n            res = moments[i];\n        }\n    }\n    return res;\n}\n\n// TODO: Use [].sort instead?\nfunction min () {\n    var args = [].slice.call(arguments, 0);\n\n    return pickBy('isBefore', args);\n}\n\nfunction max () {\n    var args = [].slice.call(arguments, 0);\n\n    return pickBy('isAfter', args);\n}\n\nvar now = function () {\n    return Date.now ? Date.now() : +(new Date());\n};\n\nvar ordering = ['year', 'quarter', 'month', 'week', 'day', 'hour', 'minute', 'second', 'millisecond'];\n\nfunction isDurationValid(m) {\n    for (var key in m) {\n        if (!(ordering.indexOf(key) !== -1 && (m[key] == null || !isNaN(m[key])))) {\n            return false;\n        }\n    }\n\n    var unitHasDecimal = false;\n    for (var i = 0; i < ordering.length; ++i) {\n        if (m[ordering[i]]) {\n            if (unitHasDecimal) {\n                return false; // only allow non-integers for smallest unit\n            }\n            if (parseFloat(m[ordering[i]]) !== toInt(m[ordering[i]])) {\n                unitHasDecimal = true;\n            }\n        }\n    }\n\n    return true;\n}\n\nfunction isValid$1() {\n    return this._isValid;\n}\n\nfunction createInvalid$1() {\n    return createDuration(NaN);\n}\n\nfunction Duration (duration) {\n    var normalizedInput = normalizeObjectUnits(duration),\n        years = normalizedInput.year || 0,\n        quarters = normalizedInput.quarter || 0,\n        months = normalizedInput.month || 0,\n        weeks = normalizedInput.week || 0,\n        days = normalizedInput.day || 0,\n        hours = normalizedInput.hour || 0,\n        minutes = normalizedInput.minute || 0,\n        seconds = normalizedInput.second || 0,\n        milliseconds = normalizedInput.millisecond || 0;\n\n    this._isValid = isDurationValid(normalizedInput);\n\n    // representation for dateAddRemove\n    this._milliseconds = +milliseconds +\n        seconds * 1e3 + // 1000\n        minutes * 6e4 + // 1000 * 60\n        hours * 1000 * 60 * 60; //using 1000 * 60 * 60 instead of 36e5 to avoid floating point rounding errors https://github.com/moment/moment/issues/2978\n    // Because of dateAddRemove treats 24 hours as different from a\n    // day when working around DST, we need to store them separately\n    this._days = +days +\n        weeks * 7;\n    // It is impossible translate months into days without knowing\n    // which months you are are talking about, so we have to store\n    // it separately.\n    this._months = +months +\n        quarters * 3 +\n        years * 12;\n\n    this._data = {};\n\n    this._locale = getLocale();\n\n    this._bubble();\n}\n\nfunction isDuration (obj) {\n    return obj instanceof Duration;\n}\n\nfunction absRound (number) {\n    if (number < 0) {\n        return Math.round(-1 * number) * -1;\n    } else {\n        return Math.round(number);\n    }\n}\n\n// FORMATTING\n\nfunction offset (token, separator) {\n    addFormatToken(token, 0, 0, function () {\n        var offset = this.utcOffset();\n        var sign = '+';\n        if (offset < 0) {\n            offset = -offset;\n            sign = '-';\n        }\n        return sign + zeroFill(~~(offset / 60), 2) + separator + zeroFill(~~(offset) % 60, 2);\n    });\n}\n\noffset('Z', ':');\noffset('ZZ', '');\n\n// PARSING\n\naddRegexToken('Z',  matchShortOffset);\naddRegexToken('ZZ', matchShortOffset);\naddParseToken(['Z', 'ZZ'], function (input, array, config) {\n    config._useUTC = true;\n    config._tzm = offsetFromString(matchShortOffset, input);\n});\n\n// HELPERS\n\n// timezone chunker\n// '+10:00' > ['10',  '00']\n// '-1530'  > ['-15', '30']\nvar chunkOffset = /([\\+\\-]|\\d\\d)/gi;\n\nfunction offsetFromString(matcher, string) {\n    var matches = (string || '').match(matcher);\n\n    if (matches === null) {\n        return null;\n    }\n\n    var chunk   = matches[matches.length - 1] || [];\n    var parts   = (chunk + '').match(chunkOffset) || ['-', 0, 0];\n    var minutes = +(parts[1] * 60) + toInt(parts[2]);\n\n    return minutes === 0 ?\n      0 :\n      parts[0] === '+' ? minutes : -minutes;\n}\n\n// Return a moment from input, that is local/utc/zone equivalent to model.\nfunction cloneWithOffset(input, model) {\n    var res, diff;\n    if (model._isUTC) {\n        res = model.clone();\n        diff = (isMoment(input) || isDate(input) ? input.valueOf() : createLocal(input).valueOf()) - res.valueOf();\n        // Use low-level api, because this fn is low-level api.\n        res._d.setTime(res._d.valueOf() + diff);\n        hooks.updateOffset(res, false);\n        return res;\n    } else {\n        return createLocal(input).local();\n    }\n}\n\nfunction getDateOffset (m) {\n    // On Firefox.24 Date#getTimezoneOffset returns a floating point.\n    // https://github.com/moment/moment/pull/1871\n    return -Math.round(m._d.getTimezoneOffset() / 15) * 15;\n}\n\n// HOOKS\n\n// This function will be called whenever a moment is mutated.\n// It is intended to keep the offset in sync with the timezone.\nhooks.updateOffset = function () {};\n\n// MOMENTS\n\n// keepLocalTime = true means only change the timezone, without\n// affecting the local hour. So 5:31:26 +0300 --[utcOffset(2, true)]-->\n// 5:31:26 +0200 It is possible that 5:31:26 doesn't exist with offset\n// +0200, so we adjust the time as needed, to be valid.\n//\n// Keeping the time actually adds/subtracts (one hour)\n// from the actual represented time. That is why we call updateOffset\n// a second time. In case it wants us to change the offset again\n// _changeInProgress == true case, then we have to adjust, because\n// there is no such time in the given timezone.\nfunction getSetOffset (input, keepLocalTime, keepMinutes) {\n    var offset = this._offset || 0,\n        localAdjust;\n    if (!this.isValid()) {\n        return input != null ? this : NaN;\n    }\n    if (input != null) {\n        if (typeof input === 'string') {\n            input = offsetFromString(matchShortOffset, input);\n            if (input === null) {\n                return this;\n            }\n        } else if (Math.abs(input) < 16 && !keepMinutes) {\n            input = input * 60;\n        }\n        if (!this._isUTC && keepLocalTime) {\n            localAdjust = getDateOffset(this);\n        }\n        this._offset = input;\n        this._isUTC = true;\n        if (localAdjust != null) {\n            this.add(localAdjust, 'm');\n        }\n        if (offset !== input) {\n            if (!keepLocalTime || this._changeInProgress) {\n                addSubtract(this, createDuration(input - offset, 'm'), 1, false);\n            } else if (!this._changeInProgress) {\n                this._changeInProgress = true;\n                hooks.updateOffset(this, true);\n                this._changeInProgress = null;\n            }\n        }\n        return this;\n    } else {\n        return this._isUTC ? offset : getDateOffset(this);\n    }\n}\n\nfunction getSetZone (input, keepLocalTime) {\n    if (input != null) {\n        if (typeof input !== 'string') {\n            input = -input;\n        }\n\n        this.utcOffset(input, keepLocalTime);\n\n        return this;\n    } else {\n        return -this.utcOffset();\n    }\n}\n\nfunction setOffsetToUTC (keepLocalTime) {\n    return this.utcOffset(0, keepLocalTime);\n}\n\nfunction setOffsetToLocal (keepLocalTime) {\n    if (this._isUTC) {\n        this.utcOffset(0, keepLocalTime);\n        this._isUTC = false;\n\n        if (keepLocalTime) {\n            this.subtract(getDateOffset(this), 'm');\n        }\n    }\n    return this;\n}\n\nfunction setOffsetToParsedOffset () {\n    if (this._tzm != null) {\n        this.utcOffset(this._tzm, false, true);\n    } else if (typeof this._i === 'string') {\n        var tZone = offsetFromString(matchOffset, this._i);\n        if (tZone != null) {\n            this.utcOffset(tZone);\n        }\n        else {\n            this.utcOffset(0, true);\n        }\n    }\n    return this;\n}\n\nfunction hasAlignedHourOffset (input) {\n    if (!this.isValid()) {\n        return false;\n    }\n    input = input ? createLocal(input).utcOffset() : 0;\n\n    return (this.utcOffset() - input) % 60 === 0;\n}\n\nfunction isDaylightSavingTime () {\n    return (\n        this.utcOffset() > this.clone().month(0).utcOffset() ||\n        this.utcOffset() > this.clone().month(5).utcOffset()\n    );\n}\n\nfunction isDaylightSavingTimeShifted () {\n    if (!isUndefined(this._isDSTShifted)) {\n        return this._isDSTShifted;\n    }\n\n    var c = {};\n\n    copyConfig(c, this);\n    c = prepareConfig(c);\n\n    if (c._a) {\n        var other = c._isUTC ? createUTC(c._a) : createLocal(c._a);\n        this._isDSTShifted = this.isValid() &&\n            compareArrays(c._a, other.toArray()) > 0;\n    } else {\n        this._isDSTShifted = false;\n    }\n\n    return this._isDSTShifted;\n}\n\nfunction isLocal () {\n    return this.isValid() ? !this._isUTC : false;\n}\n\nfunction isUtcOffset () {\n    return this.isValid() ? this._isUTC : false;\n}\n\nfunction isUtc () {\n    return this.isValid() ? this._isUTC && this._offset === 0 : false;\n}\n\n// ASP.NET json date format regex\nvar aspNetRegex = /^(\\-)?(?:(\\d*)[. ])?(\\d+)\\:(\\d+)(?:\\:(\\d+)(\\.\\d*)?)?$/;\n\n// from http://docs.closure-library.googlecode.com/git/closure_goog_date_date.js.source.html\n// somewhat more in line with 4.4.3.2 2004 spec, but allows decimal anywhere\n// and further modified to allow for strings containing both week and day\nvar isoRegex = /^(-)?P(?:(-?[0-9,.]*)Y)?(?:(-?[0-9,.]*)M)?(?:(-?[0-9,.]*)W)?(?:(-?[0-9,.]*)D)?(?:T(?:(-?[0-9,.]*)H)?(?:(-?[0-9,.]*)M)?(?:(-?[0-9,.]*)S)?)?$/;\n\nfunction createDuration (input, key) {\n    var duration = input,\n        // matching against regexp is expensive, do it on demand\n        match = null,\n        sign,\n        ret,\n        diffRes;\n\n    if (isDuration(input)) {\n        duration = {\n            ms : input._milliseconds,\n            d  : input._days,\n            M  : input._months\n        };\n    } else if (isNumber(input)) {\n        duration = {};\n        if (key) {\n            duration[key] = input;\n        } else {\n            duration.milliseconds = input;\n        }\n    } else if (!!(match = aspNetRegex.exec(input))) {\n        sign = (match[1] === '-') ? -1 : 1;\n        duration = {\n            y  : 0,\n            d  : toInt(match[DATE])                         * sign,\n            h  : toInt(match[HOUR])                         * sign,\n            m  : toInt(match[MINUTE])                       * sign,\n            s  : toInt(match[SECOND])                       * sign,\n            ms : toInt(absRound(match[MILLISECOND] * 1000)) * sign // the millisecond decimal point is included in the match\n        };\n    } else if (!!(match = isoRegex.exec(input))) {\n        sign = (match[1] === '-') ? -1 : 1;\n        duration = {\n            y : parseIso(match[2], sign),\n            M : parseIso(match[3], sign),\n            w : parseIso(match[4], sign),\n            d : parseIso(match[5], sign),\n            h : parseIso(match[6], sign),\n            m : parseIso(match[7], sign),\n            s : parseIso(match[8], sign)\n        };\n    } else if (duration == null) {// checks for null or undefined\n        duration = {};\n    } else if (typeof duration === 'object' && ('from' in duration || 'to' in duration)) {\n        diffRes = momentsDifference(createLocal(duration.from), createLocal(duration.to));\n\n        duration = {};\n        duration.ms = diffRes.milliseconds;\n        duration.M = diffRes.months;\n    }\n\n    ret = new Duration(duration);\n\n    if (isDuration(input) && hasOwnProp(input, '_locale')) {\n        ret._locale = input._locale;\n    }\n\n    return ret;\n}\n\ncreateDuration.fn = Duration.prototype;\ncreateDuration.invalid = createInvalid$1;\n\nfunction parseIso (inp, sign) {\n    // We'd normally use ~~inp for this, but unfortunately it also\n    // converts floats to ints.\n    // inp may be undefined, so careful calling replace on it.\n    var res = inp && parseFloat(inp.replace(',', '.'));\n    // apply sign while we're at it\n    return (isNaN(res) ? 0 : res) * sign;\n}\n\nfunction positiveMomentsDifference(base, other) {\n    var res = {milliseconds: 0, months: 0};\n\n    res.months = other.month() - base.month() +\n        (other.year() - base.year()) * 12;\n    if (base.clone().add(res.months, 'M').isAfter(other)) {\n        --res.months;\n    }\n\n    res.milliseconds = +other - +(base.clone().add(res.months, 'M'));\n\n    return res;\n}\n\nfunction momentsDifference(base, other) {\n    var res;\n    if (!(base.isValid() && other.isValid())) {\n        return {milliseconds: 0, months: 0};\n    }\n\n    other = cloneWithOffset(other, base);\n    if (base.isBefore(other)) {\n        res = positiveMomentsDifference(base, other);\n    } else {\n        res = positiveMomentsDifference(other, base);\n        res.milliseconds = -res.milliseconds;\n        res.months = -res.months;\n    }\n\n    return res;\n}\n\n// TODO: remove 'name' arg after deprecation is removed\nfunction createAdder(direction, name) {\n    return function (val, period) {\n        var dur, tmp;\n        //invert the arguments, but complain about it\n        if (period !== null && !isNaN(+period)) {\n            deprecateSimple(name, 'moment().' + name  + '(period, number) is deprecated. Please use moment().' + name + '(number, period). ' +\n            'See http://momentjs.com/guides/#/warnings/add-inverted-param/ for more info.');\n            tmp = val; val = period; period = tmp;\n        }\n\n        val = typeof val === 'string' ? +val : val;\n        dur = createDuration(val, period);\n        addSubtract(this, dur, direction);\n        return this;\n    };\n}\n\nfunction addSubtract (mom, duration, isAdding, updateOffset) {\n    var milliseconds = duration._milliseconds,\n        days = absRound(duration._days),\n        months = absRound(duration._months);\n\n    if (!mom.isValid()) {\n        // No op\n        return;\n    }\n\n    updateOffset = updateOffset == null ? true : updateOffset;\n\n    if (milliseconds) {\n        mom._d.setTime(mom._d.valueOf() + milliseconds * isAdding);\n    }\n    if (days) {\n        set$1(mom, 'Date', get(mom, 'Date') + days * isAdding);\n    }\n    if (months) {\n        setMonth(mom, get(mom, 'Month') + months * isAdding);\n    }\n    if (updateOffset) {\n        hooks.updateOffset(mom, days || months);\n    }\n}\n\nvar add      = createAdder(1, 'add');\nvar subtract = createAdder(-1, 'subtract');\n\nfunction getCalendarFormat(myMoment, now) {\n    var diff = myMoment.diff(now, 'days', true);\n    return diff < -6 ? 'sameElse' :\n            diff < -1 ? 'lastWeek' :\n            diff < 0 ? 'lastDay' :\n            diff < 1 ? 'sameDay' :\n            diff < 2 ? 'nextDay' :\n            diff < 7 ? 'nextWeek' : 'sameElse';\n}\n\nfunction calendar$1 (time, formats) {\n    // We want to compare the start of today, vs this.\n    // Getting start-of-today depends on whether we're local/utc/offset or not.\n    var now = time || createLocal(),\n        sod = cloneWithOffset(now, this).startOf('day'),\n        format = hooks.calendarFormat(this, sod) || 'sameElse';\n\n    var output = formats && (isFunction(formats[format]) ? formats[format].call(this, now) : formats[format]);\n\n    return this.format(output || this.localeData().calendar(format, this, createLocal(now)));\n}\n\nfunction clone () {\n    return new Moment(this);\n}\n\nfunction isAfter (input, units) {\n    var localInput = isMoment(input) ? input : createLocal(input);\n    if (!(this.isValid() && localInput.isValid())) {\n        return false;\n    }\n    units = normalizeUnits(!isUndefined(units) ? units : 'millisecond');\n    if (units === 'millisecond') {\n        return this.valueOf() > localInput.valueOf();\n    } else {\n        return localInput.valueOf() < this.clone().startOf(units).valueOf();\n    }\n}\n\nfunction isBefore (input, units) {\n    var localInput = isMoment(input) ? input : createLocal(input);\n    if (!(this.isValid() && localInput.isValid())) {\n        return false;\n    }\n    units = normalizeUnits(!isUndefined(units) ? units : 'millisecond');\n    if (units === 'millisecond') {\n        return this.valueOf() < localInput.valueOf();\n    } else {\n        return this.clone().endOf(units).valueOf() < localInput.valueOf();\n    }\n}\n\nfunction isBetween (from, to, units, inclusivity) {\n    inclusivity = inclusivity || '()';\n    return (inclusivity[0] === '(' ? this.isAfter(from, units) : !this.isBefore(from, units)) &&\n        (inclusivity[1] === ')' ? this.isBefore(to, units) : !this.isAfter(to, units));\n}\n\nfunction isSame (input, units) {\n    var localInput = isMoment(input) ? input : createLocal(input),\n        inputMs;\n    if (!(this.isValid() && localInput.isValid())) {\n        return false;\n    }\n    units = normalizeUnits(units || 'millisecond');\n    if (units === 'millisecond') {\n        return this.valueOf() === localInput.valueOf();\n    } else {\n        inputMs = localInput.valueOf();\n        return this.clone().startOf(units).valueOf() <= inputMs && inputMs <= this.clone().endOf(units).valueOf();\n    }\n}\n\nfunction isSameOrAfter (input, units) {\n    return this.isSame(input, units) || this.isAfter(input,units);\n}\n\nfunction isSameOrBefore (input, units) {\n    return this.isSame(input, units) || this.isBefore(input,units);\n}\n\nfunction diff (input, units, asFloat) {\n    var that,\n        zoneDelta,\n        delta, output;\n\n    if (!this.isValid()) {\n        return NaN;\n    }\n\n    that = cloneWithOffset(input, this);\n\n    if (!that.isValid()) {\n        return NaN;\n    }\n\n    zoneDelta = (that.utcOffset() - this.utcOffset()) * 6e4;\n\n    units = normalizeUnits(units);\n\n    if (units === 'year' || units === 'month' || units === 'quarter') {\n        output = monthDiff(this, that);\n        if (units === 'quarter') {\n            output = output / 3;\n        } else if (units === 'year') {\n            output = output / 12;\n        }\n    } else {\n        delta = this - that;\n        output = units === 'second' ? delta / 1e3 : // 1000\n            units === 'minute' ? delta / 6e4 : // 1000 * 60\n            units === 'hour' ? delta / 36e5 : // 1000 * 60 * 60\n            units === 'day' ? (delta - zoneDelta) / 864e5 : // 1000 * 60 * 60 * 24, negate dst\n            units === 'week' ? (delta - zoneDelta) / 6048e5 : // 1000 * 60 * 60 * 24 * 7, negate dst\n            delta;\n    }\n    return asFloat ? output : absFloor(output);\n}\n\nfunction monthDiff (a, b) {\n    // difference in months\n    var wholeMonthDiff = ((b.year() - a.year()) * 12) + (b.month() - a.month()),\n        // b is in (anchor - 1 month, anchor + 1 month)\n        anchor = a.clone().add(wholeMonthDiff, 'months'),\n        anchor2, adjust;\n\n    if (b - anchor < 0) {\n        anchor2 = a.clone().add(wholeMonthDiff - 1, 'months');\n        // linear across the month\n        adjust = (b - anchor) / (anchor - anchor2);\n    } else {\n        anchor2 = a.clone().add(wholeMonthDiff + 1, 'months');\n        // linear across the month\n        adjust = (b - anchor) / (anchor2 - anchor);\n    }\n\n    //check for negative zero, return zero if negative zero\n    return -(wholeMonthDiff + adjust) || 0;\n}\n\nhooks.defaultFormat = 'YYYY-MM-DDTHH:mm:ssZ';\nhooks.defaultFormatUtc = 'YYYY-MM-DDTHH:mm:ss[Z]';\n\nfunction toString () {\n    return this.clone().locale('en').format('ddd MMM DD YYYY HH:mm:ss [GMT]ZZ');\n}\n\nfunction toISOString() {\n    if (!this.isValid()) {\n        return null;\n    }\n    var m = this.clone().utc();\n    if (m.year() < 0 || m.year() > 9999) {\n        return formatMoment(m, 'YYYYYY-MM-DD[T]HH:mm:ss.SSS[Z]');\n    }\n    if (isFunction(Date.prototype.toISOString)) {\n        // native implementation is ~50x faster, use it when we can\n        return this.toDate().toISOString();\n    }\n    return formatMoment(m, 'YYYY-MM-DD[T]HH:mm:ss.SSS[Z]');\n}\n\n/**\n * Return a human readable representation of a moment that can\n * also be evaluated to get a new moment which is the same\n *\n * @link https://nodejs.org/dist/latest/docs/api/util.html#util_custom_inspect_function_on_objects\n */\nfunction inspect () {\n    if (!this.isValid()) {\n        return 'moment.invalid(/* ' + this._i + ' */)';\n    }\n    var func = 'moment';\n    var zone = '';\n    if (!this.isLocal()) {\n        func = this.utcOffset() === 0 ? 'moment.utc' : 'moment.parseZone';\n        zone = 'Z';\n    }\n    var prefix = '[' + func + '(\"]';\n    var year = (0 <= this.year() && this.year() <= 9999) ? 'YYYY' : 'YYYYYY';\n    var datetime = '-MM-DD[T]HH:mm:ss.SSS';\n    var suffix = zone + '[\")]';\n\n    return this.format(prefix + year + datetime + suffix);\n}\n\nfunction format (inputString) {\n    if (!inputString) {\n        inputString = this.isUtc() ? hooks.defaultFormatUtc : hooks.defaultFormat;\n    }\n    var output = formatMoment(this, inputString);\n    return this.localeData().postformat(output);\n}\n\nfunction from (time, withoutSuffix) {\n    if (this.isValid() &&\n            ((isMoment(time) && time.isValid()) ||\n             createLocal(time).isValid())) {\n        return createDuration({to: this, from: time}).locale(this.locale()).humanize(!withoutSuffix);\n    } else {\n        return this.localeData().invalidDate();\n    }\n}\n\nfunction fromNow (withoutSuffix) {\n    return this.from(createLocal(), withoutSuffix);\n}\n\nfunction to (time, withoutSuffix) {\n    if (this.isValid() &&\n            ((isMoment(time) && time.isValid()) ||\n             createLocal(time).isValid())) {\n        return createDuration({from: this, to: time}).locale(this.locale()).humanize(!withoutSuffix);\n    } else {\n        return this.localeData().invalidDate();\n    }\n}\n\nfunction toNow (withoutSuffix) {\n    return this.to(createLocal(), withoutSuffix);\n}\n\n// If passed a locale key, it will set the locale for this\n// instance.  Otherwise, it will return the locale configuration\n// variables for this instance.\nfunction locale (key) {\n    var newLocaleData;\n\n    if (key === undefined) {\n        return this._locale._abbr;\n    } else {\n        newLocaleData = getLocale(key);\n        if (newLocaleData != null) {\n            this._locale = newLocaleData;\n        }\n        return this;\n    }\n}\n\nvar lang = deprecate(\n    'moment().lang() is deprecated. Instead, use moment().localeData() to get the language configuration. Use moment().locale() to change languages.',\n    function (key) {\n        if (key === undefined) {\n            return this.localeData();\n        } else {\n            return this.locale(key);\n        }\n    }\n);\n\nfunction localeData () {\n    return this._locale;\n}\n\nfunction startOf (units) {\n    units = normalizeUnits(units);\n    // the following switch intentionally omits break keywords\n    // to utilize falling through the cases.\n    switch (units) {\n        case 'year':\n            this.month(0);\n            /* falls through */\n        case 'quarter':\n        case 'month':\n            this.date(1);\n            /* falls through */\n        case 'week':\n        case 'isoWeek':\n        case 'day':\n        case 'date':\n            this.hours(0);\n            /* falls through */\n        case 'hour':\n            this.minutes(0);\n            /* falls through */\n        case 'minute':\n            this.seconds(0);\n            /* falls through */\n        case 'second':\n            this.milliseconds(0);\n    }\n\n    // weeks are a special case\n    if (units === 'week') {\n        this.weekday(0);\n    }\n    if (units === 'isoWeek') {\n        this.isoWeekday(1);\n    }\n\n    // quarters are also special\n    if (units === 'quarter') {\n        this.month(Math.floor(this.month() / 3) * 3);\n    }\n\n    return this;\n}\n\nfunction endOf (units) {\n    units = normalizeUnits(units);\n    if (units === undefined || units === 'millisecond') {\n        return this;\n    }\n\n    // 'date' is an alias for 'day', so it should be considered as such.\n    if (units === 'date') {\n        units = 'day';\n    }\n\n    return this.startOf(units).add(1, (units === 'isoWeek' ? 'week' : units)).subtract(1, 'ms');\n}\n\nfunction valueOf () {\n    return this._d.valueOf() - ((this._offset || 0) * 60000);\n}\n\nfunction unix () {\n    return Math.floor(this.valueOf() / 1000);\n}\n\nfunction toDate () {\n    return new Date(this.valueOf());\n}\n\nfunction toArray () {\n    var m = this;\n    return [m.year(), m.month(), m.date(), m.hour(), m.minute(), m.second(), m.millisecond()];\n}\n\nfunction toObject () {\n    var m = this;\n    return {\n        years: m.year(),\n        months: m.month(),\n        date: m.date(),\n        hours: m.hours(),\n        minutes: m.minutes(),\n        seconds: m.seconds(),\n        milliseconds: m.milliseconds()\n    };\n}\n\nfunction toJSON () {\n    // new Date(NaN).toJSON() === null\n    return this.isValid() ? this.toISOString() : null;\n}\n\nfunction isValid$2 () {\n    return isValid(this);\n}\n\nfunction parsingFlags () {\n    return extend({}, getParsingFlags(this));\n}\n\nfunction invalidAt () {\n    return getParsingFlags(this).overflow;\n}\n\nfunction creationData() {\n    return {\n        input: this._i,\n        format: this._f,\n        locale: this._locale,\n        isUTC: this._isUTC,\n        strict: this._strict\n    };\n}\n\n// FORMATTING\n\naddFormatToken(0, ['gg', 2], 0, function () {\n    return this.weekYear() % 100;\n});\n\naddFormatToken(0, ['GG', 2], 0, function () {\n    return this.isoWeekYear() % 100;\n});\n\nfunction addWeekYearFormatToken (token, getter) {\n    addFormatToken(0, [token, token.length], 0, getter);\n}\n\naddWeekYearFormatToken('gggg',     'weekYear');\naddWeekYearFormatToken('ggggg',    'weekYear');\naddWeekYearFormatToken('GGGG',  'isoWeekYear');\naddWeekYearFormatToken('GGGGG', 'isoWeekYear');\n\n// ALIASES\n\naddUnitAlias('weekYear', 'gg');\naddUnitAlias('isoWeekYear', 'GG');\n\n// PRIORITY\n\naddUnitPriority('weekYear', 1);\naddUnitPriority('isoWeekYear', 1);\n\n\n// PARSING\n\naddRegexToken('G',      matchSigned);\naddRegexToken('g',      matchSigned);\naddRegexToken('GG',     match1to2, match2);\naddRegexToken('gg',     match1to2, match2);\naddRegexToken('GGGG',   match1to4, match4);\naddRegexToken('gggg',   match1to4, match4);\naddRegexToken('GGGGG',  match1to6, match6);\naddRegexToken('ggggg',  match1to6, match6);\n\naddWeekParseToken(['gggg', 'ggggg', 'GGGG', 'GGGGG'], function (input, week, config, token) {\n    week[token.substr(0, 2)] = toInt(input);\n});\n\naddWeekParseToken(['gg', 'GG'], function (input, week, config, token) {\n    week[token] = hooks.parseTwoDigitYear(input);\n});\n\n// MOMENTS\n\nfunction getSetWeekYear (input) {\n    return getSetWeekYearHelper.call(this,\n            input,\n            this.week(),\n            this.weekday(),\n            this.localeData()._week.dow,\n            this.localeData()._week.doy);\n}\n\nfunction getSetISOWeekYear (input) {\n    return getSetWeekYearHelper.call(this,\n            input, this.isoWeek(), this.isoWeekday(), 1, 4);\n}\n\nfunction getISOWeeksInYear () {\n    return weeksInYear(this.year(), 1, 4);\n}\n\nfunction getWeeksInYear () {\n    var weekInfo = this.localeData()._week;\n    return weeksInYear(this.year(), weekInfo.dow, weekInfo.doy);\n}\n\nfunction getSetWeekYearHelper(input, week, weekday, dow, doy) {\n    var weeksTarget;\n    if (input == null) {\n        return weekOfYear(this, dow, doy).year;\n    } else {\n        weeksTarget = weeksInYear(input, dow, doy);\n        if (week > weeksTarget) {\n            week = weeksTarget;\n        }\n        return setWeekAll.call(this, input, week, weekday, dow, doy);\n    }\n}\n\nfunction setWeekAll(weekYear, week, weekday, dow, doy) {\n    var dayOfYearData = dayOfYearFromWeeks(weekYear, week, weekday, dow, doy),\n        date = createUTCDate(dayOfYearData.year, 0, dayOfYearData.dayOfYear);\n\n    this.year(date.getUTCFullYear());\n    this.month(date.getUTCMonth());\n    this.date(date.getUTCDate());\n    return this;\n}\n\n// FORMATTING\n\naddFormatToken('Q', 0, 'Qo', 'quarter');\n\n// ALIASES\n\naddUnitAlias('quarter', 'Q');\n\n// PRIORITY\n\naddUnitPriority('quarter', 7);\n\n// PARSING\n\naddRegexToken('Q', match1);\naddParseToken('Q', function (input, array) {\n    array[MONTH] = (toInt(input) - 1) * 3;\n});\n\n// MOMENTS\n\nfunction getSetQuarter (input) {\n    return input == null ? Math.ceil((this.month() + 1) / 3) : this.month((input - 1) * 3 + this.month() % 3);\n}\n\n// FORMATTING\n\naddFormatToken('D', ['DD', 2], 'Do', 'date');\n\n// ALIASES\n\naddUnitAlias('date', 'D');\n\n// PRIOROITY\naddUnitPriority('date', 9);\n\n// PARSING\n\naddRegexToken('D',  match1to2);\naddRegexToken('DD', match1to2, match2);\naddRegexToken('Do', function (isStrict, locale) {\n    // TODO: Remove \"ordinalParse\" fallback in next major release.\n    return isStrict ?\n      (locale._dayOfMonthOrdinalParse || locale._ordinalParse) :\n      locale._dayOfMonthOrdinalParseLenient;\n});\n\naddParseToken(['D', 'DD'], DATE);\naddParseToken('Do', function (input, array) {\n    array[DATE] = toInt(input.match(match1to2)[0], 10);\n});\n\n// MOMENTS\n\nvar getSetDayOfMonth = makeGetSet('Date', true);\n\n// FORMATTING\n\naddFormatToken('DDD', ['DDDD', 3], 'DDDo', 'dayOfYear');\n\n// ALIASES\n\naddUnitAlias('dayOfYear', 'DDD');\n\n// PRIORITY\naddUnitPriority('dayOfYear', 4);\n\n// PARSING\n\naddRegexToken('DDD',  match1to3);\naddRegexToken('DDDD', match3);\naddParseToken(['DDD', 'DDDD'], function (input, array, config) {\n    config._dayOfYear = toInt(input);\n});\n\n// HELPERS\n\n// MOMENTS\n\nfunction getSetDayOfYear (input) {\n    var dayOfYear = Math.round((this.clone().startOf('day') - this.clone().startOf('year')) / 864e5) + 1;\n    return input == null ? dayOfYear : this.add((input - dayOfYear), 'd');\n}\n\n// FORMATTING\n\naddFormatToken('m', ['mm', 2], 0, 'minute');\n\n// ALIASES\n\naddUnitAlias('minute', 'm');\n\n// PRIORITY\n\naddUnitPriority('minute', 14);\n\n// PARSING\n\naddRegexToken('m',  match1to2);\naddRegexToken('mm', match1to2, match2);\naddParseToken(['m', 'mm'], MINUTE);\n\n// MOMENTS\n\nvar getSetMinute = makeGetSet('Minutes', false);\n\n// FORMATTING\n\naddFormatToken('s', ['ss', 2], 0, 'second');\n\n// ALIASES\n\naddUnitAlias('second', 's');\n\n// PRIORITY\n\naddUnitPriority('second', 15);\n\n// PARSING\n\naddRegexToken('s',  match1to2);\naddRegexToken('ss', match1to2, match2);\naddParseToken(['s', 'ss'], SECOND);\n\n// MOMENTS\n\nvar getSetSecond = makeGetSet('Seconds', false);\n\n// FORMATTING\n\naddFormatToken('S', 0, 0, function () {\n    return ~~(this.millisecond() / 100);\n});\n\naddFormatToken(0, ['SS', 2], 0, function () {\n    return ~~(this.millisecond() / 10);\n});\n\naddFormatToken(0, ['SSS', 3], 0, 'millisecond');\naddFormatToken(0, ['SSSS', 4], 0, function () {\n    return this.millisecond() * 10;\n});\naddFormatToken(0, ['SSSSS', 5], 0, function () {\n    return this.millisecond() * 100;\n});\naddFormatToken(0, ['SSSSSS', 6], 0, function () {\n    return this.millisecond() * 1000;\n});\naddFormatToken(0, ['SSSSSSS', 7], 0, function () {\n    return this.millisecond() * 10000;\n});\naddFormatToken(0, ['SSSSSSSS', 8], 0, function () {\n    return this.millisecond() * 100000;\n});\naddFormatToken(0, ['SSSSSSSSS', 9], 0, function () {\n    return this.millisecond() * 1000000;\n});\n\n\n// ALIASES\n\naddUnitAlias('millisecond', 'ms');\n\n// PRIORITY\n\naddUnitPriority('millisecond', 16);\n\n// PARSING\n\naddRegexToken('S',    match1to3, match1);\naddRegexToken('SS',   match1to3, match2);\naddRegexToken('SSS',  match1to3, match3);\n\nvar token;\nfor (token = 'SSSS'; token.length <= 9; token += 'S') {\n    addRegexToken(token, matchUnsigned);\n}\n\nfunction parseMs(input, array) {\n    array[MILLISECOND] = toInt(('0.' + input) * 1000);\n}\n\nfor (token = 'S'; token.length <= 9; token += 'S') {\n    addParseToken(token, parseMs);\n}\n// MOMENTS\n\nvar getSetMillisecond = makeGetSet('Milliseconds', false);\n\n// FORMATTING\n\naddFormatToken('z',  0, 0, 'zoneAbbr');\naddFormatToken('zz', 0, 0, 'zoneName');\n\n// MOMENTS\n\nfunction getZoneAbbr () {\n    return this._isUTC ? 'UTC' : '';\n}\n\nfunction getZoneName () {\n    return this._isUTC ? 'Coordinated Universal Time' : '';\n}\n\nvar proto = Moment.prototype;\n\nproto.add               = add;\nproto.calendar          = calendar$1;\nproto.clone             = clone;\nproto.diff              = diff;\nproto.endOf             = endOf;\nproto.format            = format;\nproto.from              = from;\nproto.fromNow           = fromNow;\nproto.to                = to;\nproto.toNow             = toNow;\nproto.get               = stringGet;\nproto.invalidAt         = invalidAt;\nproto.isAfter           = isAfter;\nproto.isBefore          = isBefore;\nproto.isBetween         = isBetween;\nproto.isSame            = isSame;\nproto.isSameOrAfter     = isSameOrAfter;\nproto.isSameOrBefore    = isSameOrBefore;\nproto.isValid           = isValid$2;\nproto.lang              = lang;\nproto.locale            = locale;\nproto.localeData        = localeData;\nproto.max               = prototypeMax;\nproto.min               = prototypeMin;\nproto.parsingFlags      = parsingFlags;\nproto.set               = stringSet;\nproto.startOf           = startOf;\nproto.subtract          = subtract;\nproto.toArray           = toArray;\nproto.toObject          = toObject;\nproto.toDate            = toDate;\nproto.toISOString       = toISOString;\nproto.inspect           = inspect;\nproto.toJSON            = toJSON;\nproto.toString          = toString;\nproto.unix              = unix;\nproto.valueOf           = valueOf;\nproto.creationData      = creationData;\n\n// Year\nproto.year       = getSetYear;\nproto.isLeapYear = getIsLeapYear;\n\n// Week Year\nproto.weekYear    = getSetWeekYear;\nproto.isoWeekYear = getSetISOWeekYear;\n\n// Quarter\nproto.quarter = proto.quarters = getSetQuarter;\n\n// Month\nproto.month       = getSetMonth;\nproto.daysInMonth = getDaysInMonth;\n\n// Week\nproto.week           = proto.weeks        = getSetWeek;\nproto.isoWeek        = proto.isoWeeks     = getSetISOWeek;\nproto.weeksInYear    = getWeeksInYear;\nproto.isoWeeksInYear = getISOWeeksInYear;\n\n// Day\nproto.date       = getSetDayOfMonth;\nproto.day        = proto.days             = getSetDayOfWeek;\nproto.weekday    = getSetLocaleDayOfWeek;\nproto.isoWeekday = getSetISODayOfWeek;\nproto.dayOfYear  = getSetDayOfYear;\n\n// Hour\nproto.hour = proto.hours = getSetHour;\n\n// Minute\nproto.minute = proto.minutes = getSetMinute;\n\n// Second\nproto.second = proto.seconds = getSetSecond;\n\n// Millisecond\nproto.millisecond = proto.milliseconds = getSetMillisecond;\n\n// Offset\nproto.utcOffset            = getSetOffset;\nproto.utc                  = setOffsetToUTC;\nproto.local                = setOffsetToLocal;\nproto.parseZone            = setOffsetToParsedOffset;\nproto.hasAlignedHourOffset = hasAlignedHourOffset;\nproto.isDST                = isDaylightSavingTime;\nproto.isLocal              = isLocal;\nproto.isUtcOffset          = isUtcOffset;\nproto.isUtc                = isUtc;\nproto.isUTC                = isUtc;\n\n// Timezone\nproto.zoneAbbr = getZoneAbbr;\nproto.zoneName = getZoneName;\n\n// Deprecations\nproto.dates  = deprecate('dates accessor is deprecated. Use date instead.', getSetDayOfMonth);\nproto.months = deprecate('months accessor is deprecated. Use month instead', getSetMonth);\nproto.years  = deprecate('years accessor is deprecated. Use year instead', getSetYear);\nproto.zone   = deprecate('moment().zone is deprecated, use moment().utcOffset instead. http://momentjs.com/guides/#/warnings/zone/', getSetZone);\nproto.isDSTShifted = deprecate('isDSTShifted is deprecated. See http://momentjs.com/guides/#/warnings/dst-shifted/ for more information', isDaylightSavingTimeShifted);\n\nfunction createUnix (input) {\n    return createLocal(input * 1000);\n}\n\nfunction createInZone () {\n    return createLocal.apply(null, arguments).parseZone();\n}\n\nfunction preParsePostFormat (string) {\n    return string;\n}\n\nvar proto$1 = Locale.prototype;\n\nproto$1.calendar        = calendar;\nproto$1.longDateFormat  = longDateFormat;\nproto$1.invalidDate     = invalidDate;\nproto$1.ordinal         = ordinal;\nproto$1.preparse        = preParsePostFormat;\nproto$1.postformat      = preParsePostFormat;\nproto$1.relativeTime    = relativeTime;\nproto$1.pastFuture      = pastFuture;\nproto$1.set             = set;\n\n// Month\nproto$1.months            =        localeMonths;\nproto$1.monthsShort       =        localeMonthsShort;\nproto$1.monthsParse       =        localeMonthsParse;\nproto$1.monthsRegex       = monthsRegex;\nproto$1.monthsShortRegex  = monthsShortRegex;\n\n// Week\nproto$1.week = localeWeek;\nproto$1.firstDayOfYear = localeFirstDayOfYear;\nproto$1.firstDayOfWeek = localeFirstDayOfWeek;\n\n// Day of Week\nproto$1.weekdays       =        localeWeekdays;\nproto$1.weekdaysMin    =        localeWeekdaysMin;\nproto$1.weekdaysShort  =        localeWeekdaysShort;\nproto$1.weekdaysParse  =        localeWeekdaysParse;\n\nproto$1.weekdaysRegex       =        weekdaysRegex;\nproto$1.weekdaysShortRegex  =        weekdaysShortRegex;\nproto$1.weekdaysMinRegex    =        weekdaysMinRegex;\n\n// Hours\nproto$1.isPM = localeIsPM;\nproto$1.meridiem = localeMeridiem;\n\nfunction get$1 (format, index, field, setter) {\n    var locale = getLocale();\n    var utc = createUTC().set(setter, index);\n    return locale[field](utc, format);\n}\n\nfunction listMonthsImpl (format, index, field) {\n    if (isNumber(format)) {\n        index = format;\n        format = undefined;\n    }\n\n    format = format || '';\n\n    if (index != null) {\n        return get$1(format, index, field, 'month');\n    }\n\n    var i;\n    var out = [];\n    for (i = 0; i < 12; i++) {\n        out[i] = get$1(format, i, field, 'month');\n    }\n    return out;\n}\n\n// ()\n// (5)\n// (fmt, 5)\n// (fmt)\n// (true)\n// (true, 5)\n// (true, fmt, 5)\n// (true, fmt)\nfunction listWeekdaysImpl (localeSorted, format, index, field) {\n    if (typeof localeSorted === 'boolean') {\n        if (isNumber(format)) {\n            index = format;\n            format = undefined;\n        }\n\n        format = format || '';\n    } else {\n        format = localeSorted;\n        index = format;\n        localeSorted = false;\n\n        if (isNumber(format)) {\n            index = format;\n            format = undefined;\n        }\n\n        format = format || '';\n    }\n\n    var locale = getLocale(),\n        shift = localeSorted ? locale._week.dow : 0;\n\n    if (index != null) {\n        return get$1(format, (index + shift) % 7, field, 'day');\n    }\n\n    var i;\n    var out = [];\n    for (i = 0; i < 7; i++) {\n        out[i] = get$1(format, (i + shift) % 7, field, 'day');\n    }\n    return out;\n}\n\nfunction listMonths (format, index) {\n    return listMonthsImpl(format, index, 'months');\n}\n\nfunction listMonthsShort (format, index) {\n    return listMonthsImpl(format, index, 'monthsShort');\n}\n\nfunction listWeekdays (localeSorted, format, index) {\n    return listWeekdaysImpl(localeSorted, format, index, 'weekdays');\n}\n\nfunction listWeekdaysShort (localeSorted, format, index) {\n    return listWeekdaysImpl(localeSorted, format, index, 'weekdaysShort');\n}\n\nfunction listWeekdaysMin (localeSorted, format, index) {\n    return listWeekdaysImpl(localeSorted, format, index, 'weekdaysMin');\n}\n\ngetSetGlobalLocale('en', {\n    dayOfMonthOrdinalParse: /\\d{1,2}(th|st|nd|rd)/,\n    ordinal : function (number) {\n        var b = number % 10,\n            output = (toInt(number % 100 / 10) === 1) ? 'th' :\n            (b === 1) ? 'st' :\n            (b === 2) ? 'nd' :\n            (b === 3) ? 'rd' : 'th';\n        return number + output;\n    }\n});\n\n// Side effect imports\nhooks.lang = deprecate('moment.lang is deprecated. Use moment.locale instead.', getSetGlobalLocale);\nhooks.langData = deprecate('moment.langData is deprecated. Use moment.localeData instead.', getLocale);\n\nvar mathAbs = Math.abs;\n\nfunction abs () {\n    var data           = this._data;\n\n    this._milliseconds = mathAbs(this._milliseconds);\n    this._days         = mathAbs(this._days);\n    this._months       = mathAbs(this._months);\n\n    data.milliseconds  = mathAbs(data.milliseconds);\n    data.seconds       = mathAbs(data.seconds);\n    data.minutes       = mathAbs(data.minutes);\n    data.hours         = mathAbs(data.hours);\n    data.months        = mathAbs(data.months);\n    data.years         = mathAbs(data.years);\n\n    return this;\n}\n\nfunction addSubtract$1 (duration, input, value, direction) {\n    var other = createDuration(input, value);\n\n    duration._milliseconds += direction * other._milliseconds;\n    duration._days         += direction * other._days;\n    duration._months       += direction * other._months;\n\n    return duration._bubble();\n}\n\n// supports only 2.0-style add(1, 's') or add(duration)\nfunction add$1 (input, value) {\n    return addSubtract$1(this, input, value, 1);\n}\n\n// supports only 2.0-style subtract(1, 's') or subtract(duration)\nfunction subtract$1 (input, value) {\n    return addSubtract$1(this, input, value, -1);\n}\n\nfunction absCeil (number) {\n    if (number < 0) {\n        return Math.floor(number);\n    } else {\n        return Math.ceil(number);\n    }\n}\n\nfunction bubble () {\n    var milliseconds = this._milliseconds;\n    var days         = this._days;\n    var months       = this._months;\n    var data         = this._data;\n    var seconds, minutes, hours, years, monthsFromDays;\n\n    // if we have a mix of positive and negative values, bubble down first\n    // check: https://github.com/moment/moment/issues/2166\n    if (!((milliseconds >= 0 && days >= 0 && months >= 0) ||\n            (milliseconds <= 0 && days <= 0 && months <= 0))) {\n        milliseconds += absCeil(monthsToDays(months) + days) * 864e5;\n        days = 0;\n        months = 0;\n    }\n\n    // The following code bubbles up values, see the tests for\n    // examples of what that means.\n    data.milliseconds = milliseconds % 1000;\n\n    seconds           = absFloor(milliseconds / 1000);\n    data.seconds      = seconds % 60;\n\n    minutes           = absFloor(seconds / 60);\n    data.minutes      = minutes % 60;\n\n    hours             = absFloor(minutes / 60);\n    data.hours        = hours % 24;\n\n    days += absFloor(hours / 24);\n\n    // convert days to months\n    monthsFromDays = absFloor(daysToMonths(days));\n    months += monthsFromDays;\n    days -= absCeil(monthsToDays(monthsFromDays));\n\n    // 12 months -> 1 year\n    years = absFloor(months / 12);\n    months %= 12;\n\n    data.days   = days;\n    data.months = months;\n    data.years  = years;\n\n    return this;\n}\n\nfunction daysToMonths (days) {\n    // 400 years have 146097 days (taking into account leap year rules)\n    // 400 years have 12 months === 4800\n    return days * 4800 / 146097;\n}\n\nfunction monthsToDays (months) {\n    // the reverse of daysToMonths\n    return months * 146097 / 4800;\n}\n\nfunction as (units) {\n    if (!this.isValid()) {\n        return NaN;\n    }\n    var days;\n    var months;\n    var milliseconds = this._milliseconds;\n\n    units = normalizeUnits(units);\n\n    if (units === 'month' || units === 'year') {\n        days   = this._days   + milliseconds / 864e5;\n        months = this._months + daysToMonths(days);\n        return units === 'month' ? months : months / 12;\n    } else {\n        // handle milliseconds separately because of floating point math errors (issue #1867)\n        days = this._days + Math.round(monthsToDays(this._months));\n        switch (units) {\n            case 'week'   : return days / 7     + milliseconds / 6048e5;\n            case 'day'    : return days         + milliseconds / 864e5;\n            case 'hour'   : return days * 24    + milliseconds / 36e5;\n            case 'minute' : return days * 1440  + milliseconds / 6e4;\n            case 'second' : return days * 86400 + milliseconds / 1000;\n            // Math.floor prevents floating point math errors here\n            case 'millisecond': return Math.floor(days * 864e5) + milliseconds;\n            default: throw new Error('Unknown unit ' + units);\n        }\n    }\n}\n\n// TODO: Use this.as('ms')?\nfunction valueOf$1 () {\n    if (!this.isValid()) {\n        return NaN;\n    }\n    return (\n        this._milliseconds +\n        this._days * 864e5 +\n        (this._months % 12) * 2592e6 +\n        toInt(this._months / 12) * 31536e6\n    );\n}\n\nfunction makeAs (alias) {\n    return function () {\n        return this.as(alias);\n    };\n}\n\nvar asMilliseconds = makeAs('ms');\nvar asSeconds      = makeAs('s');\nvar asMinutes      = makeAs('m');\nvar asHours        = makeAs('h');\nvar asDays         = makeAs('d');\nvar asWeeks        = makeAs('w');\nvar asMonths       = makeAs('M');\nvar asYears        = makeAs('y');\n\nfunction get$2 (units) {\n    units = normalizeUnits(units);\n    return this.isValid() ? this[units + 's']() : NaN;\n}\n\nfunction makeGetter(name) {\n    return function () {\n        return this.isValid() ? this._data[name] : NaN;\n    };\n}\n\nvar milliseconds = makeGetter('milliseconds');\nvar seconds      = makeGetter('seconds');\nvar minutes      = makeGetter('minutes');\nvar hours        = makeGetter('hours');\nvar days         = makeGetter('days');\nvar months       = makeGetter('months');\nvar years        = makeGetter('years');\n\nfunction weeks () {\n    return absFloor(this.days() / 7);\n}\n\nvar round = Math.round;\nvar thresholds = {\n    ss: 44,         // a few seconds to seconds\n    s : 45,         // seconds to minute\n    m : 45,         // minutes to hour\n    h : 22,         // hours to day\n    d : 26,         // days to month\n    M : 11          // months to year\n};\n\n// helper function for moment.fn.from, moment.fn.fromNow, and moment.duration.fn.humanize\nfunction substituteTimeAgo(string, number, withoutSuffix, isFuture, locale) {\n    return locale.relativeTime(number || 1, !!withoutSuffix, string, isFuture);\n}\n\nfunction relativeTime$1 (posNegDuration, withoutSuffix, locale) {\n    var duration = createDuration(posNegDuration).abs();\n    var seconds  = round(duration.as('s'));\n    var minutes  = round(duration.as('m'));\n    var hours    = round(duration.as('h'));\n    var days     = round(duration.as('d'));\n    var months   = round(duration.as('M'));\n    var years    = round(duration.as('y'));\n\n    var a = seconds <= thresholds.ss && ['s', seconds]  ||\n            seconds < thresholds.s   && ['ss', seconds] ||\n            minutes <= 1             && ['m']           ||\n            minutes < thresholds.m   && ['mm', minutes] ||\n            hours   <= 1             && ['h']           ||\n            hours   < thresholds.h   && ['hh', hours]   ||\n            days    <= 1             && ['d']           ||\n            days    < thresholds.d   && ['dd', days]    ||\n            months  <= 1             && ['M']           ||\n            months  < thresholds.M   && ['MM', months]  ||\n            years   <= 1             && ['y']           || ['yy', years];\n\n    a[2] = withoutSuffix;\n    a[3] = +posNegDuration > 0;\n    a[4] = locale;\n    return substituteTimeAgo.apply(null, a);\n}\n\n// This function allows you to set the rounding function for relative time strings\nfunction getSetRelativeTimeRounding (roundingFunction) {\n    if (roundingFunction === undefined) {\n        return round;\n    }\n    if (typeof(roundingFunction) === 'function') {\n        round = roundingFunction;\n        return true;\n    }\n    return false;\n}\n\n// This function allows you to set a threshold for relative time strings\nfunction getSetRelativeTimeThreshold (threshold, limit) {\n    if (thresholds[threshold] === undefined) {\n        return false;\n    }\n    if (limit === undefined) {\n        return thresholds[threshold];\n    }\n    thresholds[threshold] = limit;\n    if (threshold === 's') {\n        thresholds.ss = limit - 1;\n    }\n    return true;\n}\n\nfunction humanize (withSuffix) {\n    if (!this.isValid()) {\n        return this.localeData().invalidDate();\n    }\n\n    var locale = this.localeData();\n    var output = relativeTime$1(this, !withSuffix, locale);\n\n    if (withSuffix) {\n        output = locale.pastFuture(+this, output);\n    }\n\n    return locale.postformat(output);\n}\n\nvar abs$1 = Math.abs;\n\nfunction toISOString$1() {\n    // for ISO strings we do not use the normal bubbling rules:\n    //  * milliseconds bubble up until they become hours\n    //  * days do not bubble at all\n    //  * months bubble up until they become years\n    // This is because there is no context-free conversion between hours and days\n    // (think of clock changes)\n    // and also not between days and months (28-31 days per month)\n    if (!this.isValid()) {\n        return this.localeData().invalidDate();\n    }\n\n    var seconds = abs$1(this._milliseconds) / 1000;\n    var days         = abs$1(this._days);\n    var months       = abs$1(this._months);\n    var minutes, hours, years;\n\n    // 3600 seconds -> 60 minutes -> 1 hour\n    minutes           = absFloor(seconds / 60);\n    hours             = absFloor(minutes / 60);\n    seconds %= 60;\n    minutes %= 60;\n\n    // 12 months -> 1 year\n    years  = absFloor(months / 12);\n    months %= 12;\n\n\n    // inspired by https://github.com/dordille/moment-isoduration/blob/master/moment.isoduration.js\n    var Y = years;\n    var M = months;\n    var D = days;\n    var h = hours;\n    var m = minutes;\n    var s = seconds;\n    var total = this.asSeconds();\n\n    if (!total) {\n        // this is the same as C#'s (Noda) and python (isodate)...\n        // but not other JS (goog.date)\n        return 'P0D';\n    }\n\n    return (total < 0 ? '-' : '') +\n        'P' +\n        (Y ? Y + 'Y' : '') +\n        (M ? M + 'M' : '') +\n        (D ? D + 'D' : '') +\n        ((h || m || s) ? 'T' : '') +\n        (h ? h + 'H' : '') +\n        (m ? m + 'M' : '') +\n        (s ? s + 'S' : '');\n}\n\nvar proto$2 = Duration.prototype;\n\nproto$2.isValid        = isValid$1;\nproto$2.abs            = abs;\nproto$2.add            = add$1;\nproto$2.subtract       = subtract$1;\nproto$2.as             = as;\nproto$2.asMilliseconds = asMilliseconds;\nproto$2.asSeconds      = asSeconds;\nproto$2.asMinutes      = asMinutes;\nproto$2.asHours        = asHours;\nproto$2.asDays         = asDays;\nproto$2.asWeeks        = asWeeks;\nproto$2.asMonths       = asMonths;\nproto$2.asYears        = asYears;\nproto$2.valueOf        = valueOf$1;\nproto$2._bubble        = bubble;\nproto$2.get            = get$2;\nproto$2.milliseconds   = milliseconds;\nproto$2.seconds        = seconds;\nproto$2.minutes        = minutes;\nproto$2.hours          = hours;\nproto$2.days           = days;\nproto$2.weeks          = weeks;\nproto$2.months         = months;\nproto$2.years          = years;\nproto$2.humanize       = humanize;\nproto$2.toISOString    = toISOString$1;\nproto$2.toString       = toISOString$1;\nproto$2.toJSON         = toISOString$1;\nproto$2.locale         = locale;\nproto$2.localeData     = localeData;\n\n// Deprecations\nproto$2.toIsoString = deprecate('toIsoString() is deprecated. Please use toISOString() instead (notice the capitals)', toISOString$1);\nproto$2.lang = lang;\n\n// Side effect imports\n\n// FORMATTING\n\naddFormatToken('X', 0, 0, 'unix');\naddFormatToken('x', 0, 0, 'valueOf');\n\n// PARSING\n\naddRegexToken('x', matchSigned);\naddRegexToken('X', matchTimestamp);\naddParseToken('X', function (input, array, config) {\n    config._d = new Date(parseFloat(input, 10) * 1000);\n});\naddParseToken('x', function (input, array, config) {\n    config._d = new Date(toInt(input));\n});\n\n// Side effect imports\n\n\nhooks.version = '2.18.1';\n\nsetHookCallback(createLocal);\n\nhooks.fn                    = proto;\nhooks.min                   = min;\nhooks.max                   = max;\nhooks.now                   = now;\nhooks.utc                   = createUTC;\nhooks.unix                  = createUnix;\nhooks.months                = listMonths;\nhooks.isDate                = isDate;\nhooks.locale                = getSetGlobalLocale;\nhooks.invalid               = createInvalid;\nhooks.duration              = createDuration;\nhooks.isMoment              = isMoment;\nhooks.weekdays              = listWeekdays;\nhooks.parseZone             = createInZone;\nhooks.localeData            = getLocale;\nhooks.isDuration            = isDuration;\nhooks.monthsShort           = listMonthsShort;\nhooks.weekdaysMin           = listWeekdaysMin;\nhooks.defineLocale          = defineLocale;\nhooks.updateLocale          = updateLocale;\nhooks.locales               = listLocales;\nhooks.weekdaysShort         = listWeekdaysShort;\nhooks.normalizeUnits        = normalizeUnits;\nhooks.relativeTimeRounding = getSetRelativeTimeRounding;\nhooks.relativeTimeThreshold = getSetRelativeTimeThreshold;\nhooks.calendarFormat        = getCalendarFormat;\nhooks.prototype             = proto;\n\nreturn hooks;\n\n})));\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/package.js",
    "content": "var profile = {\n    resourceTags: {\n        ignore: function(filename, mid){\n            // only include moment/moment\n            return mid != \"moment/moment\";\n        },\n        amd: function(filename, mid){\n            return /\\.js$/.test(filename);\n        }\n    }\n};\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/package.json",
    "content": "{\n    \"name\": \"moment\",\n    \"version\": \"2.18.1\",\n    \"description\": \"Parse, validate, manipulate, and display dates\",\n    \"homepage\": \"http://momentjs.com\",\n    \"author\": \"Iskren Ivov Chernev <iskren.chernev@gmail.com> (https://github.com/ichernev)\",\n    \"contributors\": [\n        \"Tim Wood <washwithcare@gmail.com> (http://timwoodcreates.com/)\",\n        \"Rocky Meza (http://rockymeza.com)\",\n        \"Matt Johnson <mj1856@hotmail.com> (http://codeofmatt.com)\",\n        \"Isaac Cambron <isaac@isaaccambron.com> (http://isaaccambron.com)\",\n        \"Andre Polykanine <andre@oire.org> (https://github.com/oire)\"\n    ],\n    \"keywords\": [\n        \"moment\",\n        \"date\",\n        \"time\",\n        \"parse\",\n        \"format\",\n        \"validate\",\n        \"i18n\",\n        \"l10n\",\n        \"ender\"\n    ],\n    \"main\": \"./moment.js\",\n    \"jsnext:main\": \"./src/moment.js\",\n    \"typings\": \"./moment.d.ts\",\n    \"engines\": {\n        \"node\": \"*\"\n    },\n    \"repository\": {\n        \"type\": \"git\",\n        \"url\": \"https://github.com/moment/moment.git\"\n    },\n    \"bugs\": {\n        \"url\": \"https://github.com/moment/moment/issues\"\n    },\n    \"license\": \"MIT\",\n    \"devDependencies\": {\n        \"uglify-js\": \"latest\",\n        \"es6-promise\": \"latest\",\n        \"grunt\": \"~0.4\",\n        \"grunt-cli\": \"latest\",\n        \"benchmark\": \"latest\",\n        \"grunt-contrib-clean\": \"latest\",\n        \"grunt-contrib-concat\": \"latest\",\n        \"grunt-contrib-copy\": \"latest\",\n        \"grunt-contrib-jshint\": \"latest\",\n        \"grunt-contrib-uglify\": \"latest\",\n        \"grunt-contrib-watch\": \"latest\",\n        \"grunt-env\": \"latest\",\n        \"grunt-jscs\": \"latest\",\n        \"grunt-karma\": \"latest\",\n        \"grunt-nuget\": \"latest\",\n        \"grunt-benchmark\": \"latest\",\n        \"grunt-string-replace\": \"latest\",\n        \"grunt-exec\": \"latest\",\n        \"load-grunt-tasks\": \"latest\",\n        \"karma\": \"latest\",\n        \"karma-chrome-launcher\": \"latest\",\n        \"karma-firefox-launcher\": \"latest\",\n        \"karma-qunit\": \"latest\",\n        \"karma-sauce-launcher\": \"latest\",\n        \"qunit\": \"^0.7.5\",\n        \"qunit-cli\": \"^0.1.4\",\n        \"rollup\": \"latest\",\n        \"spacejam\": \"latest\",\n        \"typescript\": \"^1.8.10\",\n        \"coveralls\": \"^2.11.2\",\n        \"nyc\": \"^2.1.4\"\n    },\n    \"ender\": \"./ender.js\",\n    \"dojoBuild\": \"package.js\",\n    \"jspm\": {\n        \"files\": [\n            \"moment.js\",\n            \"moment.d.ts\",\n            \"locale\"\n        ],\n        \"map\": {\n            \"moment\": \"./moment\"\n        },\n        \"buildConfig\": {\n            \"uglify\": true\n        }\n    },\n    \"scripts\": {\n        \"typescript-test\": \"tsc --project typing-tests\",\n        \"test\": \"grunt test\",\n        \"coverage\": \"nyc npm test && nyc report\",\n        \"coveralls\": \"nyc npm test && nyc report --reporter=text-lcov | coveralls\"\n    },\n    \"spm\": {\n        \"main\": \"moment.js\",\n        \"output\": [\n            \"locale/*.js\"\n        ]\n    }\n}\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/scripts/locales.js",
    "content": "var fs = require('fs'),\n    path = require('path'),\n    https = require('https');\n\nvar localeDir = path.join('src', 'locale');\n\nvar args = process.argv.slice(2);\n\nfunction help() {\n    console.log(process.argv[1], '[list|mention|find-commenters] ARGS');\n    console.log();\n    console.log('    list      show all authors in all locales');\n    console.log('    mention   show all authors in all locales, ready to copy-paste in github issue');\n    console.log('    find-commenters #ID  finds all people that participated in a github conversation');\n}\n\nfunction extract() {\n    var authors = {};\n    fs.readdirSync(localeDir).forEach(function (locale) {\n        var content = fs.readFileSync(path.join(localeDir, locale), {encoding: 'utf-8'}),\n            localeCode = locale.split('.')[0],\n            localeAuthors = [];\n        content.split('\\n').forEach(function (line) {\n            var match = line.match(/^\\/\\/! author.*github[.]com\\/(.*)$/);\n            if (match !== null) {\n                // console.log(\"  \", line);\n                localeAuthors.push(match[1]);\n            }\n        });\n        if (localeAuthors.length === 0) {\n            // use to debug\n            content.split('\\n').forEach(function (line) {\n                var match = line.match(/^\\/\\/! author(.*)$/);\n                if (match !== null) {\n                    localeAuthors.push('---' + match[1]);\n                }\n            });\n            console.log(localeCode, localeAuthors);\n        } else {\n            authors[localeCode] = localeAuthors;\n        }\n    });\n    return authors;\n}\n\nfunction list() {\n    var authors = extract();\n    Object.keys(authors).forEach(function (localeCode) {\n        console.log(localeCode, authors[localeCode]);\n    });\n}\n\nfunction mention() {\n    var authors = extract();\n    Object.keys(authors).forEach(function (localeCode) {\n        console.log('- [ ]', localeCode, authors[localeCode].map(function (author) { return '@' + author; }).join(' '));\n    });\n}\n\nfunction findCommenters(postId) {\n\n    function fetchComments(page, callback) {\n        var options = {\n                hostname: 'api.github.com',\n                port: 443,\n                path: '/repos/moment/moment/issues/' + postId + '/comments?page=' + page,\n                method: 'GET',\n                headers: {\n                    'User-Agent': 'node script'\n                }\n            },\n            links = {};\n        console.log('fetching', options.path);\n        https.get(options, function (res) {\n            if ('link' in res.headers) {\n                res.headers.link.split(', ').forEach(function(linkStr) {\n                    var pieces = linkStr.split('; ');\n                    var key = pieces[1].split('=')[1];\n                    var link = pieces[0];\n                    key = key.substr(1, key.length - 2);\n                    link = link.substr(1, link.length - 2);\n                    links[key] = link;\n                });\n            }\n            var bodyChunks = [], body;\n            res.on('data', function (chunk) {\n                bodyChunks.push(chunk);\n            });\n            res.on('end', function () {\n                body = bodyChunks.join('');\n                callback(page, JSON.parse(body), links);\n            });\n        });\n    }\n\n    var commenters = {};\n    var maxPage = 1;\n    fetchComments(1, function (page, body, links) {\n        handleBody(body, page);\n        if ('last' in links) {\n            maxPage = parseInt(links.last.split('=')[1], 10);\n        }\n        var pagesLeft = maxPage - 1;\n        for (var p = 2; p <= maxPage; p += 1) {\n            fetchComments(p, function (page, body, links) {\n                handleBody(body, page);\n                pagesLeft -= 1;\n                if (pagesLeft === 0) {\n                    handleCommenters(Object.keys(commenters));\n                }\n            });\n        }\n    });\n\n    function handleBody(body, page) {\n        body.forEach(function (comment) {\n            console.log(page, comment.user.login);\n            commenters[comment.user.login] = 1;\n        });\n    }\n\n    function handleCommenters(commenters) {\n        console.log('len of commenters', commenters.length);\n        console.log(commenters);\n    }\n}\n\nif (args.length === 0) {\n    help();\n    process.exit(0);\n}\n\nswitch (args[0]) {\n    case 'list':\n        list();\n        break;\n    case 'mention':\n        mention();\n        break;\n    case 'find-commenters':\n        findCommenters(args[1]);\n        break;\n    default:\n        console.log('unknown argument', args[0]);\n        break;\n}\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/scripts/npm_prepublish.sh",
    "content": "#!/bin/bash\n\nset -e\n\nif [ \"$#\" != 1 ]; then\n    echo \"Please provide tag to checkout\" >&2\n    exit 1\nfi\ntag=\"$1\"\n\nwhile [ \"$PWD\" != '/' -a ! -f moment.js ]; do\n    cd ..\ndone\n\nif [ ! -f moment.js ]; then\n    echo \"Run me from the moment repo\" >&2\n    exit 1\nfi\n\nbasename=$(basename $PWD)\nsrc=moment-npm-git\ndest=moment-npm\n\ncd ..\n\nrm -rf $src $dest\n\ngit clone $basename $src\nmkdir $dest\n\n\ncp $src/moment.js $dest\ncp $src/moment.d.ts $dest\ncp $src/package.json $dest\ncp $src/README.md $dest\ncp $src/CHANGELOG.md $dest\ncp $src/LICENSE $dest\ncp -r $src/locale $dest\ncp -r $src/min $dest\ncp -r $src/src $dest && rm -r $dest/src/test\ncp $src/ender.js $dest\ncp $src/package.js $dest\ncp $src/.npmignore $dest\n\nrm -rf $src\n\necho \"Check out $dest\"\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/lib/create/check-overflow.js",
    "content": "import { daysInMonth } from '../units/month';\nimport { YEAR, MONTH, DATE, HOUR, MINUTE, SECOND, MILLISECOND, WEEK, WEEKDAY } from '../units/constants';\nimport getParsingFlags from '../create/parsing-flags';\n\nexport default function checkOverflow (m) {\n    var overflow;\n    var a = m._a;\n\n    if (a && getParsingFlags(m).overflow === -2) {\n        overflow =\n            a[MONTH]       < 0 || a[MONTH]       > 11  ? MONTH :\n            a[DATE]        < 1 || a[DATE]        > daysInMonth(a[YEAR], a[MONTH]) ? DATE :\n            a[HOUR]        < 0 || a[HOUR]        > 24 || (a[HOUR] === 24 && (a[MINUTE] !== 0 || a[SECOND] !== 0 || a[MILLISECOND] !== 0)) ? HOUR :\n            a[MINUTE]      < 0 || a[MINUTE]      > 59  ? MINUTE :\n            a[SECOND]      < 0 || a[SECOND]      > 59  ? SECOND :\n            a[MILLISECOND] < 0 || a[MILLISECOND] > 999 ? MILLISECOND :\n            -1;\n\n        if (getParsingFlags(m)._overflowDayOfYear && (overflow < YEAR || overflow > DATE)) {\n            overflow = DATE;\n        }\n        if (getParsingFlags(m)._overflowWeeks && overflow === -1) {\n            overflow = WEEK;\n        }\n        if (getParsingFlags(m)._overflowWeekday && overflow === -1) {\n            overflow = WEEKDAY;\n        }\n\n        getParsingFlags(m).overflow = overflow;\n    }\n\n    return m;\n}\n\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/lib/create/date-from-array.js",
    "content": "export function createDate (y, m, d, h, M, s, ms) {\n    // can't just apply() to create a date:\n    // https://stackoverflow.com/q/181348\n    var date = new Date(y, m, d, h, M, s, ms);\n\n    // the date constructor remaps years 0-99 to 1900-1999\n    if (y < 100 && y >= 0 && isFinite(date.getFullYear())) {\n        date.setFullYear(y);\n    }\n    return date;\n}\n\nexport function createUTCDate (y) {\n    var date = new Date(Date.UTC.apply(null, arguments));\n\n    // the Date.UTC function remaps years 0-99 to 1900-1999\n    if (y < 100 && y >= 0 && isFinite(date.getUTCFullYear())) {\n        date.setUTCFullYear(y);\n    }\n    return date;\n}\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/lib/create/from-anything.js",
    "content": "import isArray from '../utils/is-array';\nimport isObject from '../utils/is-object';\nimport isObjectEmpty from '../utils/is-object-empty';\nimport isUndefined from '../utils/is-undefined';\nimport isNumber from '../utils/is-number';\nimport isDate from '../utils/is-date';\nimport map from '../utils/map';\nimport { createInvalid } from './valid';\nimport { Moment, isMoment } from '../moment/constructor';\nimport { getLocale } from '../locale/locales';\nimport { hooks } from '../utils/hooks';\nimport checkOverflow from './check-overflow';\nimport { isValid } from './valid';\n\nimport { configFromStringAndArray }  from './from-string-and-array';\nimport { configFromStringAndFormat } from './from-string-and-format';\nimport { configFromString }          from './from-string';\nimport { configFromArray }           from './from-array';\nimport { configFromObject }          from './from-object';\n\nfunction createFromConfig (config) {\n    var res = new Moment(checkOverflow(prepareConfig(config)));\n    if (res._nextDay) {\n        // Adding is smart enough around DST\n        res.add(1, 'd');\n        res._nextDay = undefined;\n    }\n\n    return res;\n}\n\nexport function prepareConfig (config) {\n    var input = config._i,\n        format = config._f;\n\n    config._locale = config._locale || getLocale(config._l);\n\n    if (input === null || (format === undefined && input === '')) {\n        return createInvalid({nullInput: true});\n    }\n\n    if (typeof input === 'string') {\n        config._i = input = config._locale.preparse(input);\n    }\n\n    if (isMoment(input)) {\n        return new Moment(checkOverflow(input));\n    } else if (isDate(input)) {\n        config._d = input;\n    } else if (isArray(format)) {\n        configFromStringAndArray(config);\n    } else if (format) {\n        configFromStringAndFormat(config);\n    }  else {\n        configFromInput(config);\n    }\n\n    if (!isValid(config)) {\n        config._d = null;\n    }\n\n    return config;\n}\n\nfunction configFromInput(config) {\n    var input = config._i;\n    if (isUndefined(input)) {\n        config._d = new Date(hooks.now());\n    } else if (isDate(input)) {\n        config._d = new Date(input.valueOf());\n    } else if (typeof input === 'string') {\n        configFromString(config);\n    } else if (isArray(input)) {\n        config._a = map(input.slice(0), function (obj) {\n            return parseInt(obj, 10);\n        });\n        configFromArray(config);\n    } else if (isObject(input)) {\n        configFromObject(config);\n    } else if (isNumber(input)) {\n        // from milliseconds\n        config._d = new Date(input);\n    } else {\n        hooks.createFromInputFallback(config);\n    }\n}\n\nexport function createLocalOrUTC (input, format, locale, strict, isUTC) {\n    var c = {};\n\n    if (locale === true || locale === false) {\n        strict = locale;\n        locale = undefined;\n    }\n\n    if ((isObject(input) && isObjectEmpty(input)) ||\n            (isArray(input) && input.length === 0)) {\n        input = undefined;\n    }\n    // object construction must be done this way.\n    // https://github.com/moment/moment/issues/1423\n    c._isAMomentObject = true;\n    c._useUTC = c._isUTC = isUTC;\n    c._l = locale;\n    c._i = input;\n    c._f = format;\n    c._strict = strict;\n\n    return createFromConfig(c);\n}\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/lib/create/from-array.js",
    "content": "import { hooks } from '../utils/hooks';\nimport { createDate, createUTCDate } from './date-from-array';\nimport { daysInYear } from '../units/year';\nimport { weekOfYear, weeksInYear, dayOfYearFromWeeks } from '../units/week-calendar-utils';\nimport { YEAR, MONTH, DATE, HOUR, MINUTE, SECOND, MILLISECOND } from '../units/constants';\nimport { createLocal } from './local';\nimport defaults from '../utils/defaults';\nimport getParsingFlags from './parsing-flags';\n\nfunction currentDateArray(config) {\n    // hooks is actually the exported moment object\n    var nowValue = new Date(hooks.now());\n    if (config._useUTC) {\n        return [nowValue.getUTCFullYear(), nowValue.getUTCMonth(), nowValue.getUTCDate()];\n    }\n    return [nowValue.getFullYear(), nowValue.getMonth(), nowValue.getDate()];\n}\n\n// convert an array to a date.\n// the array should mirror the parameters below\n// note: all values past the year are optional and will default to the lowest possible value.\n// [year, month, day , hour, minute, second, millisecond]\nexport function configFromArray (config) {\n    var i, date, input = [], currentDate, yearToUse;\n\n    if (config._d) {\n        return;\n    }\n\n    currentDate = currentDateArray(config);\n\n    //compute day of the year from weeks and weekdays\n    if (config._w && config._a[DATE] == null && config._a[MONTH] == null) {\n        dayOfYearFromWeekInfo(config);\n    }\n\n    //if the day of the year is set, figure out what it is\n    if (config._dayOfYear != null) {\n        yearToUse = defaults(config._a[YEAR], currentDate[YEAR]);\n\n        if (config._dayOfYear > daysInYear(yearToUse) || config._dayOfYear === 0) {\n            getParsingFlags(config)._overflowDayOfYear = true;\n        }\n\n        date = createUTCDate(yearToUse, 0, config._dayOfYear);\n        config._a[MONTH] = date.getUTCMonth();\n        config._a[DATE] = date.getUTCDate();\n    }\n\n    // Default to current date.\n    // * if no year, month, day of month are given, default to today\n    // * if day of month is given, default month and year\n    // * if month is given, default only year\n    // * if year is given, don't default anything\n    for (i = 0; i < 3 && config._a[i] == null; ++i) {\n        config._a[i] = input[i] = currentDate[i];\n    }\n\n    // Zero out whatever was not defaulted, including time\n    for (; i < 7; i++) {\n        config._a[i] = input[i] = (config._a[i] == null) ? (i === 2 ? 1 : 0) : config._a[i];\n    }\n\n    // Check for 24:00:00.000\n    if (config._a[HOUR] === 24 &&\n            config._a[MINUTE] === 0 &&\n            config._a[SECOND] === 0 &&\n            config._a[MILLISECOND] === 0) {\n        config._nextDay = true;\n        config._a[HOUR] = 0;\n    }\n\n    config._d = (config._useUTC ? createUTCDate : createDate).apply(null, input);\n    // Apply timezone offset from input. The actual utcOffset can be changed\n    // with parseZone.\n    if (config._tzm != null) {\n        config._d.setUTCMinutes(config._d.getUTCMinutes() - config._tzm);\n    }\n\n    if (config._nextDay) {\n        config._a[HOUR] = 24;\n    }\n}\n\nfunction dayOfYearFromWeekInfo(config) {\n    var w, weekYear, week, weekday, dow, doy, temp, weekdayOverflow;\n\n    w = config._w;\n    if (w.GG != null || w.W != null || w.E != null) {\n        dow = 1;\n        doy = 4;\n\n        // TODO: We need to take the current isoWeekYear, but that depends on\n        // how we interpret now (local, utc, fixed offset). So create\n        // a now version of current config (take local/utc/offset flags, and\n        // create now).\n        weekYear = defaults(w.GG, config._a[YEAR], weekOfYear(createLocal(), 1, 4).year);\n        week = defaults(w.W, 1);\n        weekday = defaults(w.E, 1);\n        if (weekday < 1 || weekday > 7) {\n            weekdayOverflow = true;\n        }\n    } else {\n        dow = config._locale._week.dow;\n        doy = config._locale._week.doy;\n\n        var curWeek = weekOfYear(createLocal(), dow, doy);\n\n        weekYear = defaults(w.gg, config._a[YEAR], curWeek.year);\n\n        // Default to current week.\n        week = defaults(w.w, curWeek.week);\n\n        if (w.d != null) {\n            // weekday -- low day numbers are considered next week\n            weekday = w.d;\n            if (weekday < 0 || weekday > 6) {\n                weekdayOverflow = true;\n            }\n        } else if (w.e != null) {\n            // local weekday -- counting starts from begining of week\n            weekday = w.e + dow;\n            if (w.e < 0 || w.e > 6) {\n                weekdayOverflow = true;\n            }\n        } else {\n            // default to begining of week\n            weekday = dow;\n        }\n    }\n    if (week < 1 || week > weeksInYear(weekYear, dow, doy)) {\n        getParsingFlags(config)._overflowWeeks = true;\n    } else if (weekdayOverflow != null) {\n        getParsingFlags(config)._overflowWeekday = true;\n    } else {\n        temp = dayOfYearFromWeeks(weekYear, week, weekday, dow, doy);\n        config._a[YEAR] = temp.year;\n        config._dayOfYear = temp.dayOfYear;\n    }\n}\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/lib/create/from-object.js",
    "content": "import { normalizeObjectUnits } from '../units/aliases';\nimport { configFromArray } from './from-array';\nimport map from '../utils/map';\n\nexport function configFromObject(config) {\n    if (config._d) {\n        return;\n    }\n\n    var i = normalizeObjectUnits(config._i);\n    config._a = map([i.year, i.month, i.day || i.date, i.hour, i.minute, i.second, i.millisecond], function (obj) {\n        return obj && parseInt(obj, 10);\n    });\n\n    configFromArray(config);\n}\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/lib/create/from-string-and-array.js",
    "content": "import { copyConfig } from '../moment/constructor';\nimport { configFromStringAndFormat } from './from-string-and-format';\nimport getParsingFlags from './parsing-flags';\nimport { isValid } from './valid';\nimport extend from '../utils/extend';\n\n// date from string and array of format strings\nexport function configFromStringAndArray(config) {\n    var tempConfig,\n        bestMoment,\n\n        scoreToBeat,\n        i,\n        currentScore;\n\n    if (config._f.length === 0) {\n        getParsingFlags(config).invalidFormat = true;\n        config._d = new Date(NaN);\n        return;\n    }\n\n    for (i = 0; i < config._f.length; i++) {\n        currentScore = 0;\n        tempConfig = copyConfig({}, config);\n        if (config._useUTC != null) {\n            tempConfig._useUTC = config._useUTC;\n        }\n        tempConfig._f = config._f[i];\n        configFromStringAndFormat(tempConfig);\n\n        if (!isValid(tempConfig)) {\n            continue;\n        }\n\n        // if there is any input that was not parsed add a penalty for that format\n        currentScore += getParsingFlags(tempConfig).charsLeftOver;\n\n        //or tokens\n        currentScore += getParsingFlags(tempConfig).unusedTokens.length * 10;\n\n        getParsingFlags(tempConfig).score = currentScore;\n\n        if (scoreToBeat == null || currentScore < scoreToBeat) {\n            scoreToBeat = currentScore;\n            bestMoment = tempConfig;\n        }\n    }\n\n    extend(config, bestMoment || tempConfig);\n}\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/lib/create/from-string-and-format.js",
    "content": "import { configFromISO, configFromRFC2822 } from './from-string';\nimport { configFromArray } from './from-array';\nimport { getParseRegexForToken }   from '../parse/regex';\nimport { addTimeToArrayFromToken } from '../parse/token';\nimport { expandFormat, formatTokenFunctions, formattingTokens } from '../format/format';\nimport checkOverflow from './check-overflow';\nimport { HOUR } from '../units/constants';\nimport { hooks } from '../utils/hooks';\nimport getParsingFlags from './parsing-flags';\n\n// constant that refers to the ISO standard\nhooks.ISO_8601 = function () {};\n\n// constant that refers to the RFC 2822 form\nhooks.RFC_2822 = function () {};\n\n// date from string and format string\nexport function configFromStringAndFormat(config) {\n    // TODO: Move this to another part of the creation flow to prevent circular deps\n    if (config._f === hooks.ISO_8601) {\n        configFromISO(config);\n        return;\n    }\n    if (config._f === hooks.RFC_2822) {\n        configFromRFC2822(config);\n        return;\n    }\n    config._a = [];\n    getParsingFlags(config).empty = true;\n\n    // This array is used to make a Date, either with `new Date` or `Date.UTC`\n    var string = '' + config._i,\n        i, parsedInput, tokens, token, skipped,\n        stringLength = string.length,\n        totalParsedInputLength = 0;\n\n    tokens = expandFormat(config._f, config._locale).match(formattingTokens) || [];\n\n    for (i = 0; i < tokens.length; i++) {\n        token = tokens[i];\n        parsedInput = (string.match(getParseRegexForToken(token, config)) || [])[0];\n        // console.log('token', token, 'parsedInput', parsedInput,\n        //         'regex', getParseRegexForToken(token, config));\n        if (parsedInput) {\n            skipped = string.substr(0, string.indexOf(parsedInput));\n            if (skipped.length > 0) {\n                getParsingFlags(config).unusedInput.push(skipped);\n            }\n            string = string.slice(string.indexOf(parsedInput) + parsedInput.length);\n            totalParsedInputLength += parsedInput.length;\n        }\n        // don't parse if it's not a known token\n        if (formatTokenFunctions[token]) {\n            if (parsedInput) {\n                getParsingFlags(config).empty = false;\n            }\n            else {\n                getParsingFlags(config).unusedTokens.push(token);\n            }\n            addTimeToArrayFromToken(token, parsedInput, config);\n        }\n        else if (config._strict && !parsedInput) {\n            getParsingFlags(config).unusedTokens.push(token);\n        }\n    }\n\n    // add remaining unparsed input length to the string\n    getParsingFlags(config).charsLeftOver = stringLength - totalParsedInputLength;\n    if (string.length > 0) {\n        getParsingFlags(config).unusedInput.push(string);\n    }\n\n    // clear _12h flag if hour is <= 12\n    if (config._a[HOUR] <= 12 &&\n        getParsingFlags(config).bigHour === true &&\n        config._a[HOUR] > 0) {\n        getParsingFlags(config).bigHour = undefined;\n    }\n\n    getParsingFlags(config).parsedDateParts = config._a.slice(0);\n    getParsingFlags(config).meridiem = config._meridiem;\n    // handle meridiem\n    config._a[HOUR] = meridiemFixWrap(config._locale, config._a[HOUR], config._meridiem);\n\n    configFromArray(config);\n    checkOverflow(config);\n}\n\n\nfunction meridiemFixWrap (locale, hour, meridiem) {\n    var isPm;\n\n    if (meridiem == null) {\n        // nothing to do\n        return hour;\n    }\n    if (locale.meridiemHour != null) {\n        return locale.meridiemHour(hour, meridiem);\n    } else if (locale.isPM != null) {\n        // Fallback\n        isPm = locale.isPM(meridiem);\n        if (isPm && hour < 12) {\n            hour += 12;\n        }\n        if (!isPm && hour === 12) {\n            hour = 0;\n        }\n        return hour;\n    } else {\n        // this is not supposed to happen\n        return hour;\n    }\n}\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/lib/create/from-string.js",
    "content": "import { configFromStringAndFormat } from './from-string-and-format';\nimport { hooks } from '../utils/hooks';\nimport { deprecate } from '../utils/deprecate';\nimport getParsingFlags from './parsing-flags';\n\n// iso 8601 regex\n// 0000-00-00 0000-W00 or 0000-W00-0 + T + 00 or 00:00 or 00:00:00 or 00:00:00.000 + +00:00 or +0000 or +00)\nvar extendedIsoRegex = /^\\s*((?:[+-]\\d{6}|\\d{4})-(?:\\d\\d-\\d\\d|W\\d\\d-\\d|W\\d\\d|\\d\\d\\d|\\d\\d))(?:(T| )(\\d\\d(?::\\d\\d(?::\\d\\d(?:[.,]\\d+)?)?)?)([\\+\\-]\\d\\d(?::?\\d\\d)?|\\s*Z)?)?$/;\nvar basicIsoRegex = /^\\s*((?:[+-]\\d{6}|\\d{4})(?:\\d\\d\\d\\d|W\\d\\d\\d|W\\d\\d|\\d\\d\\d|\\d\\d))(?:(T| )(\\d\\d(?:\\d\\d(?:\\d\\d(?:[.,]\\d+)?)?)?)([\\+\\-]\\d\\d(?::?\\d\\d)?|\\s*Z)?)?$/;\n\nvar tzRegex = /Z|[+-]\\d\\d(?::?\\d\\d)?/;\n\nvar isoDates = [\n    ['YYYYYY-MM-DD', /[+-]\\d{6}-\\d\\d-\\d\\d/],\n    ['YYYY-MM-DD', /\\d{4}-\\d\\d-\\d\\d/],\n    ['GGGG-[W]WW-E', /\\d{4}-W\\d\\d-\\d/],\n    ['GGGG-[W]WW', /\\d{4}-W\\d\\d/, false],\n    ['YYYY-DDD', /\\d{4}-\\d{3}/],\n    ['YYYY-MM', /\\d{4}-\\d\\d/, false],\n    ['YYYYYYMMDD', /[+-]\\d{10}/],\n    ['YYYYMMDD', /\\d{8}/],\n    // YYYYMM is NOT allowed by the standard\n    ['GGGG[W]WWE', /\\d{4}W\\d{3}/],\n    ['GGGG[W]WW', /\\d{4}W\\d{2}/, false],\n    ['YYYYDDD', /\\d{7}/]\n];\n\n// iso time formats and regexes\nvar isoTimes = [\n    ['HH:mm:ss.SSSS', /\\d\\d:\\d\\d:\\d\\d\\.\\d+/],\n    ['HH:mm:ss,SSSS', /\\d\\d:\\d\\d:\\d\\d,\\d+/],\n    ['HH:mm:ss', /\\d\\d:\\d\\d:\\d\\d/],\n    ['HH:mm', /\\d\\d:\\d\\d/],\n    ['HHmmss.SSSS', /\\d\\d\\d\\d\\d\\d\\.\\d+/],\n    ['HHmmss,SSSS', /\\d\\d\\d\\d\\d\\d,\\d+/],\n    ['HHmmss', /\\d\\d\\d\\d\\d\\d/],\n    ['HHmm', /\\d\\d\\d\\d/],\n    ['HH', /\\d\\d/]\n];\n\nvar aspNetJsonRegex = /^\\/?Date\\((\\-?\\d+)/i;\n\n// date from iso format\nexport function configFromISO(config) {\n    var i, l,\n        string = config._i,\n        match = extendedIsoRegex.exec(string) || basicIsoRegex.exec(string),\n        allowTime, dateFormat, timeFormat, tzFormat;\n\n    if (match) {\n        getParsingFlags(config).iso = true;\n\n        for (i = 0, l = isoDates.length; i < l; i++) {\n            if (isoDates[i][1].exec(match[1])) {\n                dateFormat = isoDates[i][0];\n                allowTime = isoDates[i][2] !== false;\n                break;\n            }\n        }\n        if (dateFormat == null) {\n            config._isValid = false;\n            return;\n        }\n        if (match[3]) {\n            for (i = 0, l = isoTimes.length; i < l; i++) {\n                if (isoTimes[i][1].exec(match[3])) {\n                    // match[2] should be 'T' or space\n                    timeFormat = (match[2] || ' ') + isoTimes[i][0];\n                    break;\n                }\n            }\n            if (timeFormat == null) {\n                config._isValid = false;\n                return;\n            }\n        }\n        if (!allowTime && timeFormat != null) {\n            config._isValid = false;\n            return;\n        }\n        if (match[4]) {\n            if (tzRegex.exec(match[4])) {\n                tzFormat = 'Z';\n            } else {\n                config._isValid = false;\n                return;\n            }\n        }\n        config._f = dateFormat + (timeFormat || '') + (tzFormat || '');\n        configFromStringAndFormat(config);\n    } else {\n        config._isValid = false;\n    }\n}\n\n// RFC 2822 regex: For details see https://tools.ietf.org/html/rfc2822#section-3.3\nvar basicRfcRegex = /^((?:Mon|Tue|Wed|Thu|Fri|Sat|Sun),?\\s)?(\\d?\\d\\s(?:Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)\\s(?:\\d\\d)?\\d\\d\\s)(\\d\\d:\\d\\d)(\\:\\d\\d)?(\\s(?:UT|GMT|[ECMP][SD]T|[A-IK-Za-ik-z]|[+-]\\d{4}))$/;\n\n// date and time from ref 2822 format\nexport function configFromRFC2822(config) {\n    var string, match, dayFormat,\n        dateFormat, timeFormat, tzFormat;\n    var timezones = {\n        ' GMT': ' +0000',\n        ' EDT': ' -0400',\n        ' EST': ' -0500',\n        ' CDT': ' -0500',\n        ' CST': ' -0600',\n        ' MDT': ' -0600',\n        ' MST': ' -0700',\n        ' PDT': ' -0700',\n        ' PST': ' -0800'\n    };\n    var military = 'YXWVUTSRQPONZABCDEFGHIKLM';\n    var timezone, timezoneIndex;\n\n    string = config._i\n        .replace(/\\([^\\)]*\\)|[\\n\\t]/g, ' ') // Remove comments and folding whitespace\n        .replace(/(\\s\\s+)/g, ' ') // Replace multiple-spaces with a single space\n        .replace(/^\\s|\\s$/g, ''); // Remove leading and trailing spaces\n    match = basicRfcRegex.exec(string);\n\n    if (match) {\n        dayFormat = match[1] ? 'ddd' + ((match[1].length === 5) ? ', ' : ' ') : '';\n        dateFormat = 'D MMM ' + ((match[2].length > 10) ? 'YYYY ' : 'YY ');\n        timeFormat = 'HH:mm' + (match[4] ? ':ss' : '');\n\n        // TODO: Replace the vanilla JS Date object with an indepentent day-of-week check.\n        if (match[1]) { // day of week given\n            var momentDate = new Date(match[2]);\n            var momentDay = ['Sun','Mon','Tue','Wed','Thu','Fri','Sat'][momentDate.getDay()];\n\n            if (match[1].substr(0,3) !== momentDay) {\n                getParsingFlags(config).weekdayMismatch = true;\n                config._isValid = false;\n                return;\n            }\n        }\n\n        switch (match[5].length) {\n            case 2: // military\n                if (timezoneIndex === 0) {\n                    timezone = ' +0000';\n                } else {\n                    timezoneIndex = military.indexOf(match[5][1].toUpperCase()) - 12;\n                    timezone = ((timezoneIndex < 0) ? ' -' : ' +') +\n                        (('' + timezoneIndex).replace(/^-?/, '0')).match(/..$/)[0] + '00';\n                }\n                break;\n            case 4: // Zone\n                timezone = timezones[match[5]];\n                break;\n            default: // UT or +/-9999\n                timezone = timezones[' GMT'];\n        }\n        match[5] = timezone;\n        config._i = match.splice(1).join('');\n        tzFormat = ' ZZ';\n        config._f = dayFormat + dateFormat + timeFormat + tzFormat;\n        configFromStringAndFormat(config);\n        getParsingFlags(config).rfc2822 = true;\n    } else {\n        config._isValid = false;\n    }\n}\n\n// date from iso format or fallback\nexport function configFromString(config) {\n    var matched = aspNetJsonRegex.exec(config._i);\n\n    if (matched !== null) {\n        config._d = new Date(+matched[1]);\n        return;\n    }\n\n    configFromISO(config);\n    if (config._isValid === false) {\n        delete config._isValid;\n    } else {\n        return;\n    }\n\n    configFromRFC2822(config);\n    if (config._isValid === false) {\n        delete config._isValid;\n    } else {\n        return;\n    }\n\n    // Final attempt, use Input Fallback\n    hooks.createFromInputFallback(config);\n}\n\nhooks.createFromInputFallback = deprecate(\n    'value provided is not in a recognized RFC2822 or ISO format. moment construction falls back to js Date(), ' +\n    'which is not reliable across all browsers and versions. Non RFC2822/ISO date formats are ' +\n    'discouraged and will be removed in an upcoming major release. Please refer to ' +\n    'http://momentjs.com/guides/#/warnings/js-date/ for more info.',\n    function (config) {\n        config._d = new Date(config._i + (config._useUTC ? ' UTC' : ''));\n    }\n);\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/lib/create/local.js",
    "content": "import { createLocalOrUTC } from './from-anything';\n\nexport function createLocal (input, format, locale, strict) {\n    return createLocalOrUTC(input, format, locale, strict, false);\n}\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/lib/create/parsing-flags.js",
    "content": "function defaultParsingFlags() {\n    // We need to deep clone this object.\n    return {\n        empty           : false,\n        unusedTokens    : [],\n        unusedInput     : [],\n        overflow        : -2,\n        charsLeftOver   : 0,\n        nullInput       : false,\n        invalidMonth    : null,\n        invalidFormat   : false,\n        userInvalidated : false,\n        iso             : false,\n        parsedDateParts : [],\n        meridiem        : null,\n        rfc2822         : false,\n        weekdayMismatch : false\n    };\n}\n\nexport default function getParsingFlags(m) {\n    if (m._pf == null) {\n        m._pf = defaultParsingFlags();\n    }\n    return m._pf;\n}\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/lib/create/utc.js",
    "content": "import { createLocalOrUTC } from './from-anything';\n\nexport function createUTC (input, format, locale, strict) {\n    return createLocalOrUTC(input, format, locale, strict, true).utc();\n}\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/lib/create/valid.js",
    "content": "import extend from '../utils/extend';\nimport { createUTC } from './utc';\nimport getParsingFlags from '../create/parsing-flags';\nimport some from '../utils/some';\n\nexport function isValid(m) {\n    if (m._isValid == null) {\n        var flags = getParsingFlags(m);\n        var parsedParts = some.call(flags.parsedDateParts, function (i) {\n            return i != null;\n        });\n        var isNowValid = !isNaN(m._d.getTime()) &&\n            flags.overflow < 0 &&\n            !flags.empty &&\n            !flags.invalidMonth &&\n            !flags.invalidWeekday &&\n            !flags.nullInput &&\n            !flags.invalidFormat &&\n            !flags.userInvalidated &&\n            (!flags.meridiem || (flags.meridiem && parsedParts));\n\n        if (m._strict) {\n            isNowValid = isNowValid &&\n                flags.charsLeftOver === 0 &&\n                flags.unusedTokens.length === 0 &&\n                flags.bigHour === undefined;\n        }\n\n        if (Object.isFrozen == null || !Object.isFrozen(m)) {\n            m._isValid = isNowValid;\n        }\n        else {\n            return isNowValid;\n        }\n    }\n    return m._isValid;\n}\n\nexport function createInvalid (flags) {\n    var m = createUTC(NaN);\n    if (flags != null) {\n        extend(getParsingFlags(m), flags);\n    }\n    else {\n        getParsingFlags(m).userInvalidated = true;\n    }\n\n    return m;\n}\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/lib/duration/abs.js",
    "content": "var mathAbs = Math.abs;\n\nexport function abs () {\n    var data           = this._data;\n\n    this._milliseconds = mathAbs(this._milliseconds);\n    this._days         = mathAbs(this._days);\n    this._months       = mathAbs(this._months);\n\n    data.milliseconds  = mathAbs(data.milliseconds);\n    data.seconds       = mathAbs(data.seconds);\n    data.minutes       = mathAbs(data.minutes);\n    data.hours         = mathAbs(data.hours);\n    data.months        = mathAbs(data.months);\n    data.years         = mathAbs(data.years);\n\n    return this;\n}\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/lib/duration/add-subtract.js",
    "content": "import { createDuration } from './create';\n\nfunction addSubtract (duration, input, value, direction) {\n    var other = createDuration(input, value);\n\n    duration._milliseconds += direction * other._milliseconds;\n    duration._days         += direction * other._days;\n    duration._months       += direction * other._months;\n\n    return duration._bubble();\n}\n\n// supports only 2.0-style add(1, 's') or add(duration)\nexport function add (input, value) {\n    return addSubtract(this, input, value, 1);\n}\n\n// supports only 2.0-style subtract(1, 's') or subtract(duration)\nexport function subtract (input, value) {\n    return addSubtract(this, input, value, -1);\n}\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/lib/duration/as.js",
    "content": "import { daysToMonths, monthsToDays } from './bubble';\nimport { normalizeUnits } from '../units/aliases';\nimport toInt from '../utils/to-int';\n\nexport function as (units) {\n    if (!this.isValid()) {\n        return NaN;\n    }\n    var days;\n    var months;\n    var milliseconds = this._milliseconds;\n\n    units = normalizeUnits(units);\n\n    if (units === 'month' || units === 'year') {\n        days   = this._days   + milliseconds / 864e5;\n        months = this._months + daysToMonths(days);\n        return units === 'month' ? months : months / 12;\n    } else {\n        // handle milliseconds separately because of floating point math errors (issue #1867)\n        days = this._days + Math.round(monthsToDays(this._months));\n        switch (units) {\n            case 'week'   : return days / 7     + milliseconds / 6048e5;\n            case 'day'    : return days         + milliseconds / 864e5;\n            case 'hour'   : return days * 24    + milliseconds / 36e5;\n            case 'minute' : return days * 1440  + milliseconds / 6e4;\n            case 'second' : return days * 86400 + milliseconds / 1000;\n            // Math.floor prevents floating point math errors here\n            case 'millisecond': return Math.floor(days * 864e5) + milliseconds;\n            default: throw new Error('Unknown unit ' + units);\n        }\n    }\n}\n\n// TODO: Use this.as('ms')?\nexport function valueOf () {\n    if (!this.isValid()) {\n        return NaN;\n    }\n    return (\n        this._milliseconds +\n        this._days * 864e5 +\n        (this._months % 12) * 2592e6 +\n        toInt(this._months / 12) * 31536e6\n    );\n}\n\nfunction makeAs (alias) {\n    return function () {\n        return this.as(alias);\n    };\n}\n\nexport var asMilliseconds = makeAs('ms');\nexport var asSeconds      = makeAs('s');\nexport var asMinutes      = makeAs('m');\nexport var asHours        = makeAs('h');\nexport var asDays         = makeAs('d');\nexport var asWeeks        = makeAs('w');\nexport var asMonths       = makeAs('M');\nexport var asYears        = makeAs('y');\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/lib/duration/bubble.js",
    "content": "import absFloor from '../utils/abs-floor';\nimport absCeil from '../utils/abs-ceil';\nimport { createUTCDate } from '../create/date-from-array';\n\nexport function bubble () {\n    var milliseconds = this._milliseconds;\n    var days         = this._days;\n    var months       = this._months;\n    var data         = this._data;\n    var seconds, minutes, hours, years, monthsFromDays;\n\n    // if we have a mix of positive and negative values, bubble down first\n    // check: https://github.com/moment/moment/issues/2166\n    if (!((milliseconds >= 0 && days >= 0 && months >= 0) ||\n            (milliseconds <= 0 && days <= 0 && months <= 0))) {\n        milliseconds += absCeil(monthsToDays(months) + days) * 864e5;\n        days = 0;\n        months = 0;\n    }\n\n    // The following code bubbles up values, see the tests for\n    // examples of what that means.\n    data.milliseconds = milliseconds % 1000;\n\n    seconds           = absFloor(milliseconds / 1000);\n    data.seconds      = seconds % 60;\n\n    minutes           = absFloor(seconds / 60);\n    data.minutes      = minutes % 60;\n\n    hours             = absFloor(minutes / 60);\n    data.hours        = hours % 24;\n\n    days += absFloor(hours / 24);\n\n    // convert days to months\n    monthsFromDays = absFloor(daysToMonths(days));\n    months += monthsFromDays;\n    days -= absCeil(monthsToDays(monthsFromDays));\n\n    // 12 months -> 1 year\n    years = absFloor(months / 12);\n    months %= 12;\n\n    data.days   = days;\n    data.months = months;\n    data.years  = years;\n\n    return this;\n}\n\nexport function daysToMonths (days) {\n    // 400 years have 146097 days (taking into account leap year rules)\n    // 400 years have 12 months === 4800\n    return days * 4800 / 146097;\n}\n\nexport function monthsToDays (months) {\n    // the reverse of daysToMonths\n    return months * 146097 / 4800;\n}\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/lib/duration/constructor.js",
    "content": "import { normalizeObjectUnits } from '../units/aliases';\nimport { getLocale } from '../locale/locales';\nimport isDurationValid from './valid.js';\n\nexport function Duration (duration) {\n    var normalizedInput = normalizeObjectUnits(duration),\n        years = normalizedInput.year || 0,\n        quarters = normalizedInput.quarter || 0,\n        months = normalizedInput.month || 0,\n        weeks = normalizedInput.week || 0,\n        days = normalizedInput.day || 0,\n        hours = normalizedInput.hour || 0,\n        minutes = normalizedInput.minute || 0,\n        seconds = normalizedInput.second || 0,\n        milliseconds = normalizedInput.millisecond || 0;\n\n    this._isValid = isDurationValid(normalizedInput);\n\n    // representation for dateAddRemove\n    this._milliseconds = +milliseconds +\n        seconds * 1e3 + // 1000\n        minutes * 6e4 + // 1000 * 60\n        hours * 1000 * 60 * 60; //using 1000 * 60 * 60 instead of 36e5 to avoid floating point rounding errors https://github.com/moment/moment/issues/2978\n    // Because of dateAddRemove treats 24 hours as different from a\n    // day when working around DST, we need to store them separately\n    this._days = +days +\n        weeks * 7;\n    // It is impossible translate months into days without knowing\n    // which months you are are talking about, so we have to store\n    // it separately.\n    this._months = +months +\n        quarters * 3 +\n        years * 12;\n\n    this._data = {};\n\n    this._locale = getLocale();\n\n    this._bubble();\n}\n\nexport function isDuration (obj) {\n    return obj instanceof Duration;\n}\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/lib/duration/create.js",
    "content": "import { Duration, isDuration } from './constructor';\nimport isNumber from '../utils/is-number';\nimport toInt from '../utils/to-int';\nimport absRound from '../utils/abs-round';\nimport hasOwnProp from '../utils/has-own-prop';\nimport { DATE, HOUR, MINUTE, SECOND, MILLISECOND } from '../units/constants';\nimport { cloneWithOffset } from '../units/offset';\nimport { createLocal } from '../create/local';\nimport { createInvalid as invalid } from './valid';\n\n// ASP.NET json date format regex\nvar aspNetRegex = /^(\\-)?(?:(\\d*)[. ])?(\\d+)\\:(\\d+)(?:\\:(\\d+)(\\.\\d*)?)?$/;\n\n// from http://docs.closure-library.googlecode.com/git/closure_goog_date_date.js.source.html\n// somewhat more in line with 4.4.3.2 2004 spec, but allows decimal anywhere\n// and further modified to allow for strings containing both week and day\nvar isoRegex = /^(-)?P(?:(-?[0-9,.]*)Y)?(?:(-?[0-9,.]*)M)?(?:(-?[0-9,.]*)W)?(?:(-?[0-9,.]*)D)?(?:T(?:(-?[0-9,.]*)H)?(?:(-?[0-9,.]*)M)?(?:(-?[0-9,.]*)S)?)?$/;\n\nexport function createDuration (input, key) {\n    var duration = input,\n        // matching against regexp is expensive, do it on demand\n        match = null,\n        sign,\n        ret,\n        diffRes;\n\n    if (isDuration(input)) {\n        duration = {\n            ms : input._milliseconds,\n            d  : input._days,\n            M  : input._months\n        };\n    } else if (isNumber(input)) {\n        duration = {};\n        if (key) {\n            duration[key] = input;\n        } else {\n            duration.milliseconds = input;\n        }\n    } else if (!!(match = aspNetRegex.exec(input))) {\n        sign = (match[1] === '-') ? -1 : 1;\n        duration = {\n            y  : 0,\n            d  : toInt(match[DATE])                         * sign,\n            h  : toInt(match[HOUR])                         * sign,\n            m  : toInt(match[MINUTE])                       * sign,\n            s  : toInt(match[SECOND])                       * sign,\n            ms : toInt(absRound(match[MILLISECOND] * 1000)) * sign // the millisecond decimal point is included in the match\n        };\n    } else if (!!(match = isoRegex.exec(input))) {\n        sign = (match[1] === '-') ? -1 : 1;\n        duration = {\n            y : parseIso(match[2], sign),\n            M : parseIso(match[3], sign),\n            w : parseIso(match[4], sign),\n            d : parseIso(match[5], sign),\n            h : parseIso(match[6], sign),\n            m : parseIso(match[7], sign),\n            s : parseIso(match[8], sign)\n        };\n    } else if (duration == null) {// checks for null or undefined\n        duration = {};\n    } else if (typeof duration === 'object' && ('from' in duration || 'to' in duration)) {\n        diffRes = momentsDifference(createLocal(duration.from), createLocal(duration.to));\n\n        duration = {};\n        duration.ms = diffRes.milliseconds;\n        duration.M = diffRes.months;\n    }\n\n    ret = new Duration(duration);\n\n    if (isDuration(input) && hasOwnProp(input, '_locale')) {\n        ret._locale = input._locale;\n    }\n\n    return ret;\n}\n\ncreateDuration.fn = Duration.prototype;\ncreateDuration.invalid = invalid;\n\nfunction parseIso (inp, sign) {\n    // We'd normally use ~~inp for this, but unfortunately it also\n    // converts floats to ints.\n    // inp may be undefined, so careful calling replace on it.\n    var res = inp && parseFloat(inp.replace(',', '.'));\n    // apply sign while we're at it\n    return (isNaN(res) ? 0 : res) * sign;\n}\n\nfunction positiveMomentsDifference(base, other) {\n    var res = {milliseconds: 0, months: 0};\n\n    res.months = other.month() - base.month() +\n        (other.year() - base.year()) * 12;\n    if (base.clone().add(res.months, 'M').isAfter(other)) {\n        --res.months;\n    }\n\n    res.milliseconds = +other - +(base.clone().add(res.months, 'M'));\n\n    return res;\n}\n\nfunction momentsDifference(base, other) {\n    var res;\n    if (!(base.isValid() && other.isValid())) {\n        return {milliseconds: 0, months: 0};\n    }\n\n    other = cloneWithOffset(other, base);\n    if (base.isBefore(other)) {\n        res = positiveMomentsDifference(base, other);\n    } else {\n        res = positiveMomentsDifference(other, base);\n        res.milliseconds = -res.milliseconds;\n        res.months = -res.months;\n    }\n\n    return res;\n}\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/lib/duration/duration.js",
    "content": "// Side effect imports\nimport './prototype';\n\nimport { createDuration } from './create';\nimport { isDuration } from './constructor';\nimport {\n    getSetRelativeTimeRounding,\n    getSetRelativeTimeThreshold\n} from './humanize';\n\nexport {\n    createDuration,\n    isDuration,\n    getSetRelativeTimeRounding,\n    getSetRelativeTimeThreshold\n};\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/lib/duration/get.js",
    "content": "import { normalizeUnits } from '../units/aliases';\nimport absFloor from '../utils/abs-floor';\n\nexport function get (units) {\n    units = normalizeUnits(units);\n    return this.isValid() ? this[units + 's']() : NaN;\n}\n\nfunction makeGetter(name) {\n    return function () {\n        return this.isValid() ? this._data[name] : NaN;\n    };\n}\n\nexport var milliseconds = makeGetter('milliseconds');\nexport var seconds      = makeGetter('seconds');\nexport var minutes      = makeGetter('minutes');\nexport var hours        = makeGetter('hours');\nexport var days         = makeGetter('days');\nexport var months       = makeGetter('months');\nexport var years        = makeGetter('years');\n\nexport function weeks () {\n    return absFloor(this.days() / 7);\n}\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/lib/duration/humanize.js",
    "content": "import { createDuration } from './create';\n\nvar round = Math.round;\nvar thresholds = {\n    ss: 44,         // a few seconds to seconds\n    s : 45,         // seconds to minute\n    m : 45,         // minutes to hour\n    h : 22,         // hours to day\n    d : 26,         // days to month\n    M : 11          // months to year\n};\n\n// helper function for moment.fn.from, moment.fn.fromNow, and moment.duration.fn.humanize\nfunction substituteTimeAgo(string, number, withoutSuffix, isFuture, locale) {\n    return locale.relativeTime(number || 1, !!withoutSuffix, string, isFuture);\n}\n\nfunction relativeTime (posNegDuration, withoutSuffix, locale) {\n    var duration = createDuration(posNegDuration).abs();\n    var seconds  = round(duration.as('s'));\n    var minutes  = round(duration.as('m'));\n    var hours    = round(duration.as('h'));\n    var days     = round(duration.as('d'));\n    var months   = round(duration.as('M'));\n    var years    = round(duration.as('y'));\n\n    var a = seconds <= thresholds.ss && ['s', seconds]  ||\n            seconds < thresholds.s   && ['ss', seconds] ||\n            minutes <= 1             && ['m']           ||\n            minutes < thresholds.m   && ['mm', minutes] ||\n            hours   <= 1             && ['h']           ||\n            hours   < thresholds.h   && ['hh', hours]   ||\n            days    <= 1             && ['d']           ||\n            days    < thresholds.d   && ['dd', days]    ||\n            months  <= 1             && ['M']           ||\n            months  < thresholds.M   && ['MM', months]  ||\n            years   <= 1             && ['y']           || ['yy', years];\n\n    a[2] = withoutSuffix;\n    a[3] = +posNegDuration > 0;\n    a[4] = locale;\n    return substituteTimeAgo.apply(null, a);\n}\n\n// This function allows you to set the rounding function for relative time strings\nexport function getSetRelativeTimeRounding (roundingFunction) {\n    if (roundingFunction === undefined) {\n        return round;\n    }\n    if (typeof(roundingFunction) === 'function') {\n        round = roundingFunction;\n        return true;\n    }\n    return false;\n}\n\n// This function allows you to set a threshold for relative time strings\nexport function getSetRelativeTimeThreshold (threshold, limit) {\n    if (thresholds[threshold] === undefined) {\n        return false;\n    }\n    if (limit === undefined) {\n        return thresholds[threshold];\n    }\n    thresholds[threshold] = limit;\n    if (threshold === 's') {\n        thresholds.ss = limit - 1;\n    }\n    return true;\n}\n\nexport function humanize (withSuffix) {\n    if (!this.isValid()) {\n        return this.localeData().invalidDate();\n    }\n\n    var locale = this.localeData();\n    var output = relativeTime(this, !withSuffix, locale);\n\n    if (withSuffix) {\n        output = locale.pastFuture(+this, output);\n    }\n\n    return locale.postformat(output);\n}\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/lib/duration/iso-string.js",
    "content": "import absFloor from '../utils/abs-floor';\nvar abs = Math.abs;\n\nexport function toISOString() {\n    // for ISO strings we do not use the normal bubbling rules:\n    //  * milliseconds bubble up until they become hours\n    //  * days do not bubble at all\n    //  * months bubble up until they become years\n    // This is because there is no context-free conversion between hours and days\n    // (think of clock changes)\n    // and also not between days and months (28-31 days per month)\n    if (!this.isValid()) {\n        return this.localeData().invalidDate();\n    }\n\n    var seconds = abs(this._milliseconds) / 1000;\n    var days         = abs(this._days);\n    var months       = abs(this._months);\n    var minutes, hours, years;\n\n    // 3600 seconds -> 60 minutes -> 1 hour\n    minutes           = absFloor(seconds / 60);\n    hours             = absFloor(minutes / 60);\n    seconds %= 60;\n    minutes %= 60;\n\n    // 12 months -> 1 year\n    years  = absFloor(months / 12);\n    months %= 12;\n\n\n    // inspired by https://github.com/dordille/moment-isoduration/blob/master/moment.isoduration.js\n    var Y = years;\n    var M = months;\n    var D = days;\n    var h = hours;\n    var m = minutes;\n    var s = seconds;\n    var total = this.asSeconds();\n\n    if (!total) {\n        // this is the same as C#'s (Noda) and python (isodate)...\n        // but not other JS (goog.date)\n        return 'P0D';\n    }\n\n    return (total < 0 ? '-' : '') +\n        'P' +\n        (Y ? Y + 'Y' : '') +\n        (M ? M + 'M' : '') +\n        (D ? D + 'D' : '') +\n        ((h || m || s) ? 'T' : '') +\n        (h ? h + 'H' : '') +\n        (m ? m + 'M' : '') +\n        (s ? s + 'S' : '');\n}\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/lib/duration/prototype.js",
    "content": "import { Duration } from './constructor';\n\nvar proto = Duration.prototype;\n\nimport { abs } from './abs';\nimport { add, subtract } from './add-subtract';\nimport { as, asMilliseconds, asSeconds, asMinutes, asHours, asDays, asWeeks, asMonths, asYears, valueOf } from './as';\nimport { bubble } from './bubble';\nimport { get, milliseconds, seconds, minutes, hours, days, months, years, weeks } from './get';\nimport { humanize } from './humanize';\nimport { toISOString } from './iso-string';\nimport { lang, locale, localeData } from '../moment/locale';\nimport { isValid } from './valid';\n\nproto.isValid        = isValid;\nproto.abs            = abs;\nproto.add            = add;\nproto.subtract       = subtract;\nproto.as             = as;\nproto.asMilliseconds = asMilliseconds;\nproto.asSeconds      = asSeconds;\nproto.asMinutes      = asMinutes;\nproto.asHours        = asHours;\nproto.asDays         = asDays;\nproto.asWeeks        = asWeeks;\nproto.asMonths       = asMonths;\nproto.asYears        = asYears;\nproto.valueOf        = valueOf;\nproto._bubble        = bubble;\nproto.get            = get;\nproto.milliseconds   = milliseconds;\nproto.seconds        = seconds;\nproto.minutes        = minutes;\nproto.hours          = hours;\nproto.days           = days;\nproto.weeks          = weeks;\nproto.months         = months;\nproto.years          = years;\nproto.humanize       = humanize;\nproto.toISOString    = toISOString;\nproto.toString       = toISOString;\nproto.toJSON         = toISOString;\nproto.locale         = locale;\nproto.localeData     = localeData;\n\n// Deprecations\nimport { deprecate } from '../utils/deprecate';\n\nproto.toIsoString = deprecate('toIsoString() is deprecated. Please use toISOString() instead (notice the capitals)', toISOString);\nproto.lang = lang;\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/lib/duration/valid.js",
    "content": "import toInt from '../utils/to-int';\nimport {Duration} from './constructor';\nimport {createDuration} from './create';\n\nvar ordering = ['year', 'quarter', 'month', 'week', 'day', 'hour', 'minute', 'second', 'millisecond'];\n\nexport default function isDurationValid(m) {\n    for (var key in m) {\n        if (!(ordering.indexOf(key) !== -1 && (m[key] == null || !isNaN(m[key])))) {\n            return false;\n        }\n    }\n\n    var unitHasDecimal = false;\n    for (var i = 0; i < ordering.length; ++i) {\n        if (m[ordering[i]]) {\n            if (unitHasDecimal) {\n                return false; // only allow non-integers for smallest unit\n            }\n            if (parseFloat(m[ordering[i]]) !== toInt(m[ordering[i]])) {\n                unitHasDecimal = true;\n            }\n        }\n    }\n\n    return true;\n}\n\nexport function isValid() {\n    return this._isValid;\n}\n\nexport function createInvalid() {\n    return createDuration(NaN);\n}\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/lib/format/format.js",
    "content": "import zeroFill from '../utils/zero-fill';\nimport isFunction from '../utils/is-function';\n\nexport var formattingTokens = /(\\[[^\\[]*\\])|(\\\\)?([Hh]mm(ss)?|Mo|MM?M?M?|Do|DDDo|DD?D?D?|ddd?d?|do?|w[o|w]?|W[o|W]?|Qo?|YYYYYY|YYYYY|YYYY|YY|gg(ggg?)?|GG(GGG?)?|e|E|a|A|hh?|HH?|kk?|mm?|ss?|S{1,9}|x|X|zz?|ZZ?|.)/g;\n\nvar localFormattingTokens = /(\\[[^\\[]*\\])|(\\\\)?(LTS|LT|LL?L?L?|l{1,4})/g;\n\nvar formatFunctions = {};\n\nexport var formatTokenFunctions = {};\n\n// token:    'M'\n// padded:   ['MM', 2]\n// ordinal:  'Mo'\n// callback: function () { this.month() + 1 }\nexport function addFormatToken (token, padded, ordinal, callback) {\n    var func = callback;\n    if (typeof callback === 'string') {\n        func = function () {\n            return this[callback]();\n        };\n    }\n    if (token) {\n        formatTokenFunctions[token] = func;\n    }\n    if (padded) {\n        formatTokenFunctions[padded[0]] = function () {\n            return zeroFill(func.apply(this, arguments), padded[1], padded[2]);\n        };\n    }\n    if (ordinal) {\n        formatTokenFunctions[ordinal] = function () {\n            return this.localeData().ordinal(func.apply(this, arguments), token);\n        };\n    }\n}\n\nfunction removeFormattingTokens(input) {\n    if (input.match(/\\[[\\s\\S]/)) {\n        return input.replace(/^\\[|\\]$/g, '');\n    }\n    return input.replace(/\\\\/g, '');\n}\n\nfunction makeFormatFunction(format) {\n    var array = format.match(formattingTokens), i, length;\n\n    for (i = 0, length = array.length; i < length; i++) {\n        if (formatTokenFunctions[array[i]]) {\n            array[i] = formatTokenFunctions[array[i]];\n        } else {\n            array[i] = removeFormattingTokens(array[i]);\n        }\n    }\n\n    return function (mom) {\n        var output = '', i;\n        for (i = 0; i < length; i++) {\n            output += isFunction(array[i]) ? array[i].call(mom, format) : array[i];\n        }\n        return output;\n    };\n}\n\n// format date using native date object\nexport function formatMoment(m, format) {\n    if (!m.isValid()) {\n        return m.localeData().invalidDate();\n    }\n\n    format = expandFormat(format, m.localeData());\n    formatFunctions[format] = formatFunctions[format] || makeFormatFunction(format);\n\n    return formatFunctions[format](m);\n}\n\nexport function expandFormat(format, locale) {\n    var i = 5;\n\n    function replaceLongDateFormatTokens(input) {\n        return locale.longDateFormat(input) || input;\n    }\n\n    localFormattingTokens.lastIndex = 0;\n    while (i >= 0 && localFormattingTokens.test(format)) {\n        format = format.replace(localFormattingTokens, replaceLongDateFormatTokens);\n        localFormattingTokens.lastIndex = 0;\n        i -= 1;\n    }\n\n    return format;\n}\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/lib/locale/base-config.js",
    "content": "import { defaultCalendar } from './calendar';\nimport { defaultLongDateFormat } from './formats';\nimport { defaultInvalidDate } from './invalid';\nimport { defaultOrdinal, defaultDayOfMonthOrdinalParse } from './ordinal';\nimport { defaultRelativeTime } from './relative';\n\n// months\nimport {\n    defaultLocaleMonths,\n    defaultLocaleMonthsShort,\n} from '../units/month';\n\n// week\nimport { defaultLocaleWeek } from '../units/week';\n\n// weekdays\nimport {\n    defaultLocaleWeekdays,\n    defaultLocaleWeekdaysMin,\n    defaultLocaleWeekdaysShort,\n} from '../units/day-of-week';\n\n// meridiem\nimport { defaultLocaleMeridiemParse } from '../units/hour';\n\nexport var baseConfig = {\n    calendar: defaultCalendar,\n    longDateFormat: defaultLongDateFormat,\n    invalidDate: defaultInvalidDate,\n    ordinal: defaultOrdinal,\n    dayOfMonthOrdinalParse: defaultDayOfMonthOrdinalParse,\n    relativeTime: defaultRelativeTime,\n\n    months: defaultLocaleMonths,\n    monthsShort: defaultLocaleMonthsShort,\n\n    week: defaultLocaleWeek,\n\n    weekdays: defaultLocaleWeekdays,\n    weekdaysMin: defaultLocaleWeekdaysMin,\n    weekdaysShort: defaultLocaleWeekdaysShort,\n\n    meridiemParse: defaultLocaleMeridiemParse\n};\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/lib/locale/calendar.js",
    "content": "export var defaultCalendar = {\n    sameDay : '[Today at] LT',\n    nextDay : '[Tomorrow at] LT',\n    nextWeek : 'dddd [at] LT',\n    lastDay : '[Yesterday at] LT',\n    lastWeek : '[Last] dddd [at] LT',\n    sameElse : 'L'\n};\n\nimport isFunction from '../utils/is-function';\n\nexport function calendar (key, mom, now) {\n    var output = this._calendar[key] || this._calendar['sameElse'];\n    return isFunction(output) ? output.call(mom, now) : output;\n}\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/lib/locale/constructor.js",
    "content": "export function Locale(config) {\n    if (config != null) {\n        this.set(config);\n    }\n}\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/lib/locale/en.js",
    "content": "import './prototype';\nimport { getSetGlobalLocale } from './locales';\nimport toInt from '../utils/to-int';\n\ngetSetGlobalLocale('en', {\n    dayOfMonthOrdinalParse: /\\d{1,2}(th|st|nd|rd)/,\n    ordinal : function (number) {\n        var b = number % 10,\n            output = (toInt(number % 100 / 10) === 1) ? 'th' :\n            (b === 1) ? 'st' :\n            (b === 2) ? 'nd' :\n            (b === 3) ? 'rd' : 'th';\n        return number + output;\n    }\n});\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/lib/locale/formats.js",
    "content": "export var defaultLongDateFormat = {\n    LTS  : 'h:mm:ss A',\n    LT   : 'h:mm A',\n    L    : 'MM/DD/YYYY',\n    LL   : 'MMMM D, YYYY',\n    LLL  : 'MMMM D, YYYY h:mm A',\n    LLLL : 'dddd, MMMM D, YYYY h:mm A'\n};\n\nexport function longDateFormat (key) {\n    var format = this._longDateFormat[key],\n        formatUpper = this._longDateFormat[key.toUpperCase()];\n\n    if (format || !formatUpper) {\n        return format;\n    }\n\n    this._longDateFormat[key] = formatUpper.replace(/MMMM|MM|DD|dddd/g, function (val) {\n        return val.slice(1);\n    });\n\n    return this._longDateFormat[key];\n}\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/lib/locale/invalid.js",
    "content": "export var defaultInvalidDate = 'Invalid date';\n\nexport function invalidDate () {\n    return this._invalidDate;\n}\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/lib/locale/lists.js",
    "content": "import isNumber from '../utils/is-number';\nimport { getLocale } from './locales';\nimport { createUTC } from '../create/utc';\n\nfunction get (format, index, field, setter) {\n    var locale = getLocale();\n    var utc = createUTC().set(setter, index);\n    return locale[field](utc, format);\n}\n\nfunction listMonthsImpl (format, index, field) {\n    if (isNumber(format)) {\n        index = format;\n        format = undefined;\n    }\n\n    format = format || '';\n\n    if (index != null) {\n        return get(format, index, field, 'month');\n    }\n\n    var i;\n    var out = [];\n    for (i = 0; i < 12; i++) {\n        out[i] = get(format, i, field, 'month');\n    }\n    return out;\n}\n\n// ()\n// (5)\n// (fmt, 5)\n// (fmt)\n// (true)\n// (true, 5)\n// (true, fmt, 5)\n// (true, fmt)\nfunction listWeekdaysImpl (localeSorted, format, index, field) {\n    if (typeof localeSorted === 'boolean') {\n        if (isNumber(format)) {\n            index = format;\n            format = undefined;\n        }\n\n        format = format || '';\n    } else {\n        format = localeSorted;\n        index = format;\n        localeSorted = false;\n\n        if (isNumber(format)) {\n            index = format;\n            format = undefined;\n        }\n\n        format = format || '';\n    }\n\n    var locale = getLocale(),\n        shift = localeSorted ? locale._week.dow : 0;\n\n    if (index != null) {\n        return get(format, (index + shift) % 7, field, 'day');\n    }\n\n    var i;\n    var out = [];\n    for (i = 0; i < 7; i++) {\n        out[i] = get(format, (i + shift) % 7, field, 'day');\n    }\n    return out;\n}\n\nexport function listMonths (format, index) {\n    return listMonthsImpl(format, index, 'months');\n}\n\nexport function listMonthsShort (format, index) {\n    return listMonthsImpl(format, index, 'monthsShort');\n}\n\nexport function listWeekdays (localeSorted, format, index) {\n    return listWeekdaysImpl(localeSorted, format, index, 'weekdays');\n}\n\nexport function listWeekdaysShort (localeSorted, format, index) {\n    return listWeekdaysImpl(localeSorted, format, index, 'weekdaysShort');\n}\n\nexport function listWeekdaysMin (localeSorted, format, index) {\n    return listWeekdaysImpl(localeSorted, format, index, 'weekdaysMin');\n}\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/lib/locale/locale.js",
    "content": "// Side effect imports\nimport './prototype';\n\nimport {\n    getSetGlobalLocale,\n    defineLocale,\n    updateLocale,\n    getLocale,\n    listLocales\n} from './locales';\n\nimport {\n    listMonths,\n    listMonthsShort,\n    listWeekdays,\n    listWeekdaysShort,\n    listWeekdaysMin\n} from './lists';\n\nexport {\n    getSetGlobalLocale,\n    defineLocale,\n    updateLocale,\n    getLocale,\n    listLocales,\n    listMonths,\n    listMonthsShort,\n    listWeekdays,\n    listWeekdaysShort,\n    listWeekdaysMin\n};\n\nimport { deprecate } from '../utils/deprecate';\nimport { hooks } from '../utils/hooks';\n\nhooks.lang = deprecate('moment.lang is deprecated. Use moment.locale instead.', getSetGlobalLocale);\nhooks.langData = deprecate('moment.langData is deprecated. Use moment.localeData instead.', getLocale);\n\nimport './en';\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/lib/locale/locales.js",
    "content": "import isArray from '../utils/is-array';\nimport hasOwnProp from '../utils/has-own-prop';\nimport isUndefined from '../utils/is-undefined';\nimport compareArrays from '../utils/compare-arrays';\nimport { deprecateSimple } from '../utils/deprecate';\nimport { mergeConfigs } from './set';\nimport { Locale } from './constructor';\nimport keys from '../utils/keys';\n\nimport { baseConfig } from './base-config';\n\n// internal storage for locale config files\nvar locales = {};\nvar localeFamilies = {};\nvar globalLocale;\n\nfunction normalizeLocale(key) {\n    return key ? key.toLowerCase().replace('_', '-') : key;\n}\n\n// pick the locale from the array\n// try ['en-au', 'en-gb'] as 'en-au', 'en-gb', 'en', as in move through the list trying each\n// substring from most specific to least, but move to the next array item if it's a more specific variant than the current root\nfunction chooseLocale(names) {\n    var i = 0, j, next, locale, split;\n\n    while (i < names.length) {\n        split = normalizeLocale(names[i]).split('-');\n        j = split.length;\n        next = normalizeLocale(names[i + 1]);\n        next = next ? next.split('-') : null;\n        while (j > 0) {\n            locale = loadLocale(split.slice(0, j).join('-'));\n            if (locale) {\n                return locale;\n            }\n            if (next && next.length >= j && compareArrays(split, next, true) >= j - 1) {\n                //the next array item is better than a shallower substring of this one\n                break;\n            }\n            j--;\n        }\n        i++;\n    }\n    return null;\n}\n\nfunction loadLocale(name) {\n    var oldLocale = null;\n    // TODO: Find a better way to register and load all the locales in Node\n    if (!locales[name] && (typeof module !== 'undefined') &&\n            module && module.exports) {\n        try {\n            oldLocale = globalLocale._abbr;\n            require('./locale/' + name);\n            // because defineLocale currently also sets the global locale, we\n            // want to undo that for lazy loaded locales\n            getSetGlobalLocale(oldLocale);\n        } catch (e) { }\n    }\n    return locales[name];\n}\n\n// This function will load locale and then set the global locale.  If\n// no arguments are passed in, it will simply return the current global\n// locale key.\nexport function getSetGlobalLocale (key, values) {\n    var data;\n    if (key) {\n        if (isUndefined(values)) {\n            data = getLocale(key);\n        }\n        else {\n            data = defineLocale(key, values);\n        }\n\n        if (data) {\n            // moment.duration._locale = moment._locale = data;\n            globalLocale = data;\n        }\n    }\n\n    return globalLocale._abbr;\n}\n\nexport function defineLocale (name, config) {\n    if (config !== null) {\n        var parentConfig = baseConfig;\n        config.abbr = name;\n        if (locales[name] != null) {\n            deprecateSimple('defineLocaleOverride',\n                    'use moment.updateLocale(localeName, config) to change ' +\n                    'an existing locale. moment.defineLocale(localeName, ' +\n                    'config) should only be used for creating a new locale ' +\n                    'See http://momentjs.com/guides/#/warnings/define-locale/ for more info.');\n            parentConfig = locales[name]._config;\n        } else if (config.parentLocale != null) {\n            if (locales[config.parentLocale] != null) {\n                parentConfig = locales[config.parentLocale]._config;\n            } else {\n                if (!localeFamilies[config.parentLocale]) {\n                    localeFamilies[config.parentLocale] = [];\n                }\n                localeFamilies[config.parentLocale].push({\n                    name: name,\n                    config: config\n                });\n                return null;\n            }\n        }\n        locales[name] = new Locale(mergeConfigs(parentConfig, config));\n\n        if (localeFamilies[name]) {\n            localeFamilies[name].forEach(function (x) {\n                defineLocale(x.name, x.config);\n            });\n        }\n\n        // backwards compat for now: also set the locale\n        // make sure we set the locale AFTER all child locales have been\n        // created, so we won't end up with the child locale set.\n        getSetGlobalLocale(name);\n\n\n        return locales[name];\n    } else {\n        // useful for testing\n        delete locales[name];\n        return null;\n    }\n}\n\nexport function updateLocale(name, config) {\n    if (config != null) {\n        var locale, parentConfig = baseConfig;\n        // MERGE\n        if (locales[name] != null) {\n            parentConfig = locales[name]._config;\n        }\n        config = mergeConfigs(parentConfig, config);\n        locale = new Locale(config);\n        locale.parentLocale = locales[name];\n        locales[name] = locale;\n\n        // backwards compat for now: also set the locale\n        getSetGlobalLocale(name);\n    } else {\n        // pass null for config to unupdate, useful for tests\n        if (locales[name] != null) {\n            if (locales[name].parentLocale != null) {\n                locales[name] = locales[name].parentLocale;\n            } else if (locales[name] != null) {\n                delete locales[name];\n            }\n        }\n    }\n    return locales[name];\n}\n\n// returns locale data\nexport function getLocale (key) {\n    var locale;\n\n    if (key && key._locale && key._locale._abbr) {\n        key = key._locale._abbr;\n    }\n\n    if (!key) {\n        return globalLocale;\n    }\n\n    if (!isArray(key)) {\n        //short-circuit everything else\n        locale = loadLocale(key);\n        if (locale) {\n            return locale;\n        }\n        key = [key];\n    }\n\n    return chooseLocale(key);\n}\n\nexport function listLocales() {\n    return keys(locales);\n}\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/lib/locale/ordinal.js",
    "content": "export var defaultOrdinal = '%d';\nexport var defaultDayOfMonthOrdinalParse = /\\d{1,2}/;\n\nexport function ordinal (number) {\n    return this._ordinal.replace('%d', number);\n}\n\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/lib/locale/pre-post-format.js",
    "content": "export function preParsePostFormat (string) {\n    return string;\n}\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/lib/locale/prototype.js",
    "content": "import { Locale } from './constructor';\n\nvar proto = Locale.prototype;\n\nimport { calendar } from './calendar';\nimport { longDateFormat } from './formats';\nimport { invalidDate } from './invalid';\nimport { ordinal } from './ordinal';\nimport { preParsePostFormat } from './pre-post-format';\nimport { relativeTime, pastFuture } from './relative';\nimport { set } from './set';\n\nproto.calendar        = calendar;\nproto.longDateFormat  = longDateFormat;\nproto.invalidDate     = invalidDate;\nproto.ordinal         = ordinal;\nproto.preparse        = preParsePostFormat;\nproto.postformat      = preParsePostFormat;\nproto.relativeTime    = relativeTime;\nproto.pastFuture      = pastFuture;\nproto.set             = set;\n\n// Month\nimport {\n    localeMonthsParse,\n    localeMonths,\n    localeMonthsShort,\n    monthsRegex,\n    monthsShortRegex\n} from '../units/month';\n\nproto.months            =        localeMonths;\nproto.monthsShort       =        localeMonthsShort;\nproto.monthsParse       =        localeMonthsParse;\nproto.monthsRegex       = monthsRegex;\nproto.monthsShortRegex  = monthsShortRegex;\n\n// Week\nimport { localeWeek, localeFirstDayOfYear, localeFirstDayOfWeek } from '../units/week';\nproto.week = localeWeek;\nproto.firstDayOfYear = localeFirstDayOfYear;\nproto.firstDayOfWeek = localeFirstDayOfWeek;\n\n// Day of Week\nimport {\n    localeWeekdaysParse,\n    localeWeekdays,\n    localeWeekdaysMin,\n    localeWeekdaysShort,\n\n    weekdaysRegex,\n    weekdaysShortRegex,\n    weekdaysMinRegex\n} from '../units/day-of-week';\n\nproto.weekdays       =        localeWeekdays;\nproto.weekdaysMin    =        localeWeekdaysMin;\nproto.weekdaysShort  =        localeWeekdaysShort;\nproto.weekdaysParse  =        localeWeekdaysParse;\n\nproto.weekdaysRegex       =        weekdaysRegex;\nproto.weekdaysShortRegex  =        weekdaysShortRegex;\nproto.weekdaysMinRegex    =        weekdaysMinRegex;\n\n// Hours\nimport { localeIsPM, localeMeridiem } from '../units/hour';\n\nproto.isPM = localeIsPM;\nproto.meridiem = localeMeridiem;\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/lib/locale/relative.js",
    "content": "export var defaultRelativeTime = {\n    future : 'in %s',\n    past   : '%s ago',\n    s  : 'a few seconds',\n    ss : '%d seconds',\n    m  : 'a minute',\n    mm : '%d minutes',\n    h  : 'an hour',\n    hh : '%d hours',\n    d  : 'a day',\n    dd : '%d days',\n    M  : 'a month',\n    MM : '%d months',\n    y  : 'a year',\n    yy : '%d years'\n};\n\nimport isFunction from '../utils/is-function';\n\nexport function relativeTime (number, withoutSuffix, string, isFuture) {\n    var output = this._relativeTime[string];\n    return (isFunction(output)) ?\n        output(number, withoutSuffix, string, isFuture) :\n        output.replace(/%d/i, number);\n}\n\nexport function pastFuture (diff, output) {\n    var format = this._relativeTime[diff > 0 ? 'future' : 'past'];\n    return isFunction(format) ? format(output) : format.replace(/%s/i, output);\n}\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/lib/locale/set.js",
    "content": "import isFunction from '../utils/is-function';\nimport extend from '../utils/extend';\nimport isObject from '../utils/is-object';\nimport hasOwnProp from '../utils/has-own-prop';\n\nexport function set (config) {\n    var prop, i;\n    for (i in config) {\n        prop = config[i];\n        if (isFunction(prop)) {\n            this[i] = prop;\n        } else {\n            this['_' + i] = prop;\n        }\n    }\n    this._config = config;\n    // Lenient ordinal parsing accepts just a number in addition to\n    // number + (possibly) stuff coming from _dayOfMonthOrdinalParse.\n    // TODO: Remove \"ordinalParse\" fallback in next major release.\n    this._dayOfMonthOrdinalParseLenient = new RegExp(\n        (this._dayOfMonthOrdinalParse.source || this._ordinalParse.source) +\n            '|' + (/\\d{1,2}/).source);\n}\n\nexport function mergeConfigs(parentConfig, childConfig) {\n    var res = extend({}, parentConfig), prop;\n    for (prop in childConfig) {\n        if (hasOwnProp(childConfig, prop)) {\n            if (isObject(parentConfig[prop]) && isObject(childConfig[prop])) {\n                res[prop] = {};\n                extend(res[prop], parentConfig[prop]);\n                extend(res[prop], childConfig[prop]);\n            } else if (childConfig[prop] != null) {\n                res[prop] = childConfig[prop];\n            } else {\n                delete res[prop];\n            }\n        }\n    }\n    for (prop in parentConfig) {\n        if (hasOwnProp(parentConfig, prop) &&\n                !hasOwnProp(childConfig, prop) &&\n                isObject(parentConfig[prop])) {\n            // make sure changes to properties don't modify parent config\n            res[prop] = extend({}, res[prop]);\n        }\n    }\n    return res;\n}\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/lib/moment/add-subtract.js",
    "content": "import { get, set } from './get-set';\nimport { setMonth } from '../units/month';\nimport { createDuration } from '../duration/create';\nimport { deprecateSimple } from '../utils/deprecate';\nimport { hooks } from '../utils/hooks';\nimport absRound from '../utils/abs-round';\n\n\n// TODO: remove 'name' arg after deprecation is removed\nfunction createAdder(direction, name) {\n    return function (val, period) {\n        var dur, tmp;\n        //invert the arguments, but complain about it\n        if (period !== null && !isNaN(+period)) {\n            deprecateSimple(name, 'moment().' + name  + '(period, number) is deprecated. Please use moment().' + name + '(number, period). ' +\n            'See http://momentjs.com/guides/#/warnings/add-inverted-param/ for more info.');\n            tmp = val; val = period; period = tmp;\n        }\n\n        val = typeof val === 'string' ? +val : val;\n        dur = createDuration(val, period);\n        addSubtract(this, dur, direction);\n        return this;\n    };\n}\n\nexport function addSubtract (mom, duration, isAdding, updateOffset) {\n    var milliseconds = duration._milliseconds,\n        days = absRound(duration._days),\n        months = absRound(duration._months);\n\n    if (!mom.isValid()) {\n        // No op\n        return;\n    }\n\n    updateOffset = updateOffset == null ? true : updateOffset;\n\n    if (milliseconds) {\n        mom._d.setTime(mom._d.valueOf() + milliseconds * isAdding);\n    }\n    if (days) {\n        set(mom, 'Date', get(mom, 'Date') + days * isAdding);\n    }\n    if (months) {\n        setMonth(mom, get(mom, 'Month') + months * isAdding);\n    }\n    if (updateOffset) {\n        hooks.updateOffset(mom, days || months);\n    }\n}\n\nexport var add      = createAdder(1, 'add');\nexport var subtract = createAdder(-1, 'subtract');\n\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/lib/moment/calendar.js",
    "content": "import { createLocal } from '../create/local';\nimport { cloneWithOffset } from '../units/offset';\nimport isFunction from '../utils/is-function';\nimport { hooks } from '../utils/hooks';\n\nexport function getCalendarFormat(myMoment, now) {\n    var diff = myMoment.diff(now, 'days', true);\n    return diff < -6 ? 'sameElse' :\n            diff < -1 ? 'lastWeek' :\n            diff < 0 ? 'lastDay' :\n            diff < 1 ? 'sameDay' :\n            diff < 2 ? 'nextDay' :\n            diff < 7 ? 'nextWeek' : 'sameElse';\n}\n\nexport function calendar (time, formats) {\n    // We want to compare the start of today, vs this.\n    // Getting start-of-today depends on whether we're local/utc/offset or not.\n    var now = time || createLocal(),\n        sod = cloneWithOffset(now, this).startOf('day'),\n        format = hooks.calendarFormat(this, sod) || 'sameElse';\n\n    var output = formats && (isFunction(formats[format]) ? formats[format].call(this, now) : formats[format]);\n\n    return this.format(output || this.localeData().calendar(format, this, createLocal(now)));\n}\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/lib/moment/clone.js",
    "content": "import { Moment } from './constructor';\n\nexport function clone () {\n    return new Moment(this);\n}\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/lib/moment/compare.js",
    "content": "import { isMoment } from './constructor';\nimport { normalizeUnits } from '../units/aliases';\nimport { createLocal } from '../create/local';\nimport isUndefined from '../utils/is-undefined';\n\nexport function isAfter (input, units) {\n    var localInput = isMoment(input) ? input : createLocal(input);\n    if (!(this.isValid() && localInput.isValid())) {\n        return false;\n    }\n    units = normalizeUnits(!isUndefined(units) ? units : 'millisecond');\n    if (units === 'millisecond') {\n        return this.valueOf() > localInput.valueOf();\n    } else {\n        return localInput.valueOf() < this.clone().startOf(units).valueOf();\n    }\n}\n\nexport function isBefore (input, units) {\n    var localInput = isMoment(input) ? input : createLocal(input);\n    if (!(this.isValid() && localInput.isValid())) {\n        return false;\n    }\n    units = normalizeUnits(!isUndefined(units) ? units : 'millisecond');\n    if (units === 'millisecond') {\n        return this.valueOf() < localInput.valueOf();\n    } else {\n        return this.clone().endOf(units).valueOf() < localInput.valueOf();\n    }\n}\n\nexport function isBetween (from, to, units, inclusivity) {\n    inclusivity = inclusivity || '()';\n    return (inclusivity[0] === '(' ? this.isAfter(from, units) : !this.isBefore(from, units)) &&\n        (inclusivity[1] === ')' ? this.isBefore(to, units) : !this.isAfter(to, units));\n}\n\nexport function isSame (input, units) {\n    var localInput = isMoment(input) ? input : createLocal(input),\n        inputMs;\n    if (!(this.isValid() && localInput.isValid())) {\n        return false;\n    }\n    units = normalizeUnits(units || 'millisecond');\n    if (units === 'millisecond') {\n        return this.valueOf() === localInput.valueOf();\n    } else {\n        inputMs = localInput.valueOf();\n        return this.clone().startOf(units).valueOf() <= inputMs && inputMs <= this.clone().endOf(units).valueOf();\n    }\n}\n\nexport function isSameOrAfter (input, units) {\n    return this.isSame(input, units) || this.isAfter(input,units);\n}\n\nexport function isSameOrBefore (input, units) {\n    return this.isSame(input, units) || this.isBefore(input,units);\n}\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/lib/moment/constructor.js",
    "content": "import { hooks } from '../utils/hooks';\nimport hasOwnProp from '../utils/has-own-prop';\nimport isUndefined from '../utils/is-undefined';\nimport getParsingFlags from '../create/parsing-flags';\n\n// Plugins that add properties should also add the key here (null value),\n// so we can properly clone ourselves.\nvar momentProperties = hooks.momentProperties = [];\n\nexport function copyConfig(to, from) {\n    var i, prop, val;\n\n    if (!isUndefined(from._isAMomentObject)) {\n        to._isAMomentObject = from._isAMomentObject;\n    }\n    if (!isUndefined(from._i)) {\n        to._i = from._i;\n    }\n    if (!isUndefined(from._f)) {\n        to._f = from._f;\n    }\n    if (!isUndefined(from._l)) {\n        to._l = from._l;\n    }\n    if (!isUndefined(from._strict)) {\n        to._strict = from._strict;\n    }\n    if (!isUndefined(from._tzm)) {\n        to._tzm = from._tzm;\n    }\n    if (!isUndefined(from._isUTC)) {\n        to._isUTC = from._isUTC;\n    }\n    if (!isUndefined(from._offset)) {\n        to._offset = from._offset;\n    }\n    if (!isUndefined(from._pf)) {\n        to._pf = getParsingFlags(from);\n    }\n    if (!isUndefined(from._locale)) {\n        to._locale = from._locale;\n    }\n\n    if (momentProperties.length > 0) {\n        for (i = 0; i < momentProperties.length; i++) {\n            prop = momentProperties[i];\n            val = from[prop];\n            if (!isUndefined(val)) {\n                to[prop] = val;\n            }\n        }\n    }\n\n    return to;\n}\n\nvar updateInProgress = false;\n\n// Moment prototype object\nexport function Moment(config) {\n    copyConfig(this, config);\n    this._d = new Date(config._d != null ? config._d.getTime() : NaN);\n    if (!this.isValid()) {\n        this._d = new Date(NaN);\n    }\n    // Prevent infinite loop in case updateOffset creates new moment\n    // objects.\n    if (updateInProgress === false) {\n        updateInProgress = true;\n        hooks.updateOffset(this);\n        updateInProgress = false;\n    }\n}\n\nexport function isMoment (obj) {\n    return obj instanceof Moment || (obj != null && obj._isAMomentObject != null);\n}\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/lib/moment/creation-data.js",
    "content": "export function creationData() {\n    return {\n        input: this._i,\n        format: this._f,\n        locale: this._locale,\n        isUTC: this._isUTC,\n        strict: this._strict\n    };\n}\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/lib/moment/diff.js",
    "content": "import absFloor from '../utils/abs-floor';\nimport { cloneWithOffset } from '../units/offset';\nimport { normalizeUnits } from '../units/aliases';\n\nexport function diff (input, units, asFloat) {\n    var that,\n        zoneDelta,\n        delta, output;\n\n    if (!this.isValid()) {\n        return NaN;\n    }\n\n    that = cloneWithOffset(input, this);\n\n    if (!that.isValid()) {\n        return NaN;\n    }\n\n    zoneDelta = (that.utcOffset() - this.utcOffset()) * 6e4;\n\n    units = normalizeUnits(units);\n\n    if (units === 'year' || units === 'month' || units === 'quarter') {\n        output = monthDiff(this, that);\n        if (units === 'quarter') {\n            output = output / 3;\n        } else if (units === 'year') {\n            output = output / 12;\n        }\n    } else {\n        delta = this - that;\n        output = units === 'second' ? delta / 1e3 : // 1000\n            units === 'minute' ? delta / 6e4 : // 1000 * 60\n            units === 'hour' ? delta / 36e5 : // 1000 * 60 * 60\n            units === 'day' ? (delta - zoneDelta) / 864e5 : // 1000 * 60 * 60 * 24, negate dst\n            units === 'week' ? (delta - zoneDelta) / 6048e5 : // 1000 * 60 * 60 * 24 * 7, negate dst\n            delta;\n    }\n    return asFloat ? output : absFloor(output);\n}\n\nfunction monthDiff (a, b) {\n    // difference in months\n    var wholeMonthDiff = ((b.year() - a.year()) * 12) + (b.month() - a.month()),\n        // b is in (anchor - 1 month, anchor + 1 month)\n        anchor = a.clone().add(wholeMonthDiff, 'months'),\n        anchor2, adjust;\n\n    if (b - anchor < 0) {\n        anchor2 = a.clone().add(wholeMonthDiff - 1, 'months');\n        // linear across the month\n        adjust = (b - anchor) / (anchor - anchor2);\n    } else {\n        anchor2 = a.clone().add(wholeMonthDiff + 1, 'months');\n        // linear across the month\n        adjust = (b - anchor) / (anchor2 - anchor);\n    }\n\n    //check for negative zero, return zero if negative zero\n    return -(wholeMonthDiff + adjust) || 0;\n}\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/lib/moment/format.js",
    "content": "import { formatMoment } from '../format/format';\nimport { hooks } from '../utils/hooks';\nimport isFunction from '../utils/is-function';\n\nhooks.defaultFormat = 'YYYY-MM-DDTHH:mm:ssZ';\nhooks.defaultFormatUtc = 'YYYY-MM-DDTHH:mm:ss[Z]';\n\nexport function toString () {\n    return this.clone().locale('en').format('ddd MMM DD YYYY HH:mm:ss [GMT]ZZ');\n}\n\nexport function toISOString() {\n    if (!this.isValid()) {\n        return null;\n    }\n    var m = this.clone().utc();\n    if (m.year() < 0 || m.year() > 9999) {\n        return formatMoment(m, 'YYYYYY-MM-DD[T]HH:mm:ss.SSS[Z]');\n    }\n    if (isFunction(Date.prototype.toISOString)) {\n        // native implementation is ~50x faster, use it when we can\n        return this.toDate().toISOString();\n    }\n    return formatMoment(m, 'YYYY-MM-DD[T]HH:mm:ss.SSS[Z]');\n}\n\n/**\n * Return a human readable representation of a moment that can\n * also be evaluated to get a new moment which is the same\n *\n * @link https://nodejs.org/dist/latest/docs/api/util.html#util_custom_inspect_function_on_objects\n */\nexport function inspect () {\n    if (!this.isValid()) {\n        return 'moment.invalid(/* ' + this._i + ' */)';\n    }\n    var func = 'moment';\n    var zone = '';\n    if (!this.isLocal()) {\n        func = this.utcOffset() === 0 ? 'moment.utc' : 'moment.parseZone';\n        zone = 'Z';\n    }\n    var prefix = '[' + func + '(\"]';\n    var year = (0 <= this.year() && this.year() <= 9999) ? 'YYYY' : 'YYYYYY';\n    var datetime = '-MM-DD[T]HH:mm:ss.SSS';\n    var suffix = zone + '[\")]';\n\n    return this.format(prefix + year + datetime + suffix);\n}\n\nexport function format (inputString) {\n    if (!inputString) {\n        inputString = this.isUtc() ? hooks.defaultFormatUtc : hooks.defaultFormat;\n    }\n    var output = formatMoment(this, inputString);\n    return this.localeData().postformat(output);\n}\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/lib/moment/from.js",
    "content": "import { createDuration } from '../duration/create';\nimport { createLocal } from '../create/local';\nimport { isMoment } from '../moment/constructor';\n\nexport function from (time, withoutSuffix) {\n    if (this.isValid() &&\n            ((isMoment(time) && time.isValid()) ||\n             createLocal(time).isValid())) {\n        return createDuration({to: this, from: time}).locale(this.locale()).humanize(!withoutSuffix);\n    } else {\n        return this.localeData().invalidDate();\n    }\n}\n\nexport function fromNow (withoutSuffix) {\n    return this.from(createLocal(), withoutSuffix);\n}\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/lib/moment/get-set.js",
    "content": "import { normalizeUnits, normalizeObjectUnits } from '../units/aliases';\nimport { getPrioritizedUnits } from '../units/priorities';\nimport { hooks } from '../utils/hooks';\nimport isFunction from '../utils/is-function';\n\n\nexport function makeGetSet (unit, keepTime) {\n    return function (value) {\n        if (value != null) {\n            set(this, unit, value);\n            hooks.updateOffset(this, keepTime);\n            return this;\n        } else {\n            return get(this, unit);\n        }\n    };\n}\n\nexport function get (mom, unit) {\n    return mom.isValid() ?\n        mom._d['get' + (mom._isUTC ? 'UTC' : '') + unit]() : NaN;\n}\n\nexport function set (mom, unit, value) {\n    if (mom.isValid()) {\n        mom._d['set' + (mom._isUTC ? 'UTC' : '') + unit](value);\n    }\n}\n\n// MOMENTS\n\nexport function stringGet (units) {\n    units = normalizeUnits(units);\n    if (isFunction(this[units])) {\n        return this[units]();\n    }\n    return this;\n}\n\n\nexport function stringSet (units, value) {\n    if (typeof units === 'object') {\n        units = normalizeObjectUnits(units);\n        var prioritized = getPrioritizedUnits(units);\n        for (var i = 0; i < prioritized.length; i++) {\n            this[prioritized[i].unit](units[prioritized[i].unit]);\n        }\n    } else {\n        units = normalizeUnits(units);\n        if (isFunction(this[units])) {\n            return this[units](value);\n        }\n    }\n    return this;\n}\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/lib/moment/locale.js",
    "content": "import { getLocale } from '../locale/locales';\nimport { deprecate } from '../utils/deprecate';\n\n// If passed a locale key, it will set the locale for this\n// instance.  Otherwise, it will return the locale configuration\n// variables for this instance.\nexport function locale (key) {\n    var newLocaleData;\n\n    if (key === undefined) {\n        return this._locale._abbr;\n    } else {\n        newLocaleData = getLocale(key);\n        if (newLocaleData != null) {\n            this._locale = newLocaleData;\n        }\n        return this;\n    }\n}\n\nexport var lang = deprecate(\n    'moment().lang() is deprecated. Instead, use moment().localeData() to get the language configuration. Use moment().locale() to change languages.',\n    function (key) {\n        if (key === undefined) {\n            return this.localeData();\n        } else {\n            return this.locale(key);\n        }\n    }\n);\n\nexport function localeData () {\n    return this._locale;\n}\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/lib/moment/min-max.js",
    "content": "import { deprecate } from '../utils/deprecate';\nimport isArray from '../utils/is-array';\nimport { createLocal } from '../create/local';\nimport { createInvalid } from '../create/valid';\n\nexport var prototypeMin = deprecate(\n    'moment().min is deprecated, use moment.max instead. http://momentjs.com/guides/#/warnings/min-max/',\n    function () {\n        var other = createLocal.apply(null, arguments);\n        if (this.isValid() && other.isValid()) {\n            return other < this ? this : other;\n        } else {\n            return createInvalid();\n        }\n    }\n);\n\nexport var prototypeMax = deprecate(\n    'moment().max is deprecated, use moment.min instead. http://momentjs.com/guides/#/warnings/min-max/',\n    function () {\n        var other = createLocal.apply(null, arguments);\n        if (this.isValid() && other.isValid()) {\n            return other > this ? this : other;\n        } else {\n            return createInvalid();\n        }\n    }\n);\n\n// Pick a moment m from moments so that m[fn](other) is true for all\n// other. This relies on the function fn to be transitive.\n//\n// moments should either be an array of moment objects or an array, whose\n// first element is an array of moment objects.\nfunction pickBy(fn, moments) {\n    var res, i;\n    if (moments.length === 1 && isArray(moments[0])) {\n        moments = moments[0];\n    }\n    if (!moments.length) {\n        return createLocal();\n    }\n    res = moments[0];\n    for (i = 1; i < moments.length; ++i) {\n        if (!moments[i].isValid() || moments[i][fn](res)) {\n            res = moments[i];\n        }\n    }\n    return res;\n}\n\n// TODO: Use [].sort instead?\nexport function min () {\n    var args = [].slice.call(arguments, 0);\n\n    return pickBy('isBefore', args);\n}\n\nexport function max () {\n    var args = [].slice.call(arguments, 0);\n\n    return pickBy('isAfter', args);\n}\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/lib/moment/moment.js",
    "content": "import { createLocal } from '../create/local';\nimport { createUTC } from '../create/utc';\nimport { createInvalid } from '../create/valid';\nimport { isMoment } from './constructor';\nimport { min, max } from './min-max';\nimport { now } from './now';\nimport momentPrototype from './prototype';\n\nfunction createUnix (input) {\n    return createLocal(input * 1000);\n}\n\nfunction createInZone () {\n    return createLocal.apply(null, arguments).parseZone();\n}\n\nexport {\n    now,\n    min,\n    max,\n    isMoment,\n    createUTC,\n    createUnix,\n    createLocal,\n    createInZone,\n    createInvalid,\n    momentPrototype\n};\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/lib/moment/now.js",
    "content": "export var now = function () {\n    return Date.now ? Date.now() : +(new Date());\n};\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/lib/moment/prototype.js",
    "content": "import { Moment } from './constructor';\n\nvar proto = Moment.prototype;\n\nimport { add, subtract } from './add-subtract';\nimport { calendar, getCalendarFormat } from './calendar';\nimport { clone } from './clone';\nimport { isBefore, isBetween, isSame, isAfter, isSameOrAfter, isSameOrBefore } from './compare';\nimport { diff } from './diff';\nimport { format, toString, toISOString, inspect } from './format';\nimport { from, fromNow } from './from';\nimport { to, toNow } from './to';\nimport { stringGet, stringSet } from './get-set';\nimport { locale, localeData, lang } from './locale';\nimport { prototypeMin, prototypeMax } from './min-max';\nimport { startOf, endOf } from './start-end-of';\nimport { valueOf, toDate, toArray, toObject, toJSON, unix } from './to-type';\nimport { isValid, parsingFlags, invalidAt } from './valid';\nimport { creationData } from './creation-data';\n\nproto.add               = add;\nproto.calendar          = calendar;\nproto.clone             = clone;\nproto.diff              = diff;\nproto.endOf             = endOf;\nproto.format            = format;\nproto.from              = from;\nproto.fromNow           = fromNow;\nproto.to                = to;\nproto.toNow             = toNow;\nproto.get               = stringGet;\nproto.invalidAt         = invalidAt;\nproto.isAfter           = isAfter;\nproto.isBefore          = isBefore;\nproto.isBetween         = isBetween;\nproto.isSame            = isSame;\nproto.isSameOrAfter     = isSameOrAfter;\nproto.isSameOrBefore    = isSameOrBefore;\nproto.isValid           = isValid;\nproto.lang              = lang;\nproto.locale            = locale;\nproto.localeData        = localeData;\nproto.max               = prototypeMax;\nproto.min               = prototypeMin;\nproto.parsingFlags      = parsingFlags;\nproto.set               = stringSet;\nproto.startOf           = startOf;\nproto.subtract          = subtract;\nproto.toArray           = toArray;\nproto.toObject          = toObject;\nproto.toDate            = toDate;\nproto.toISOString       = toISOString;\nproto.inspect           = inspect;\nproto.toJSON            = toJSON;\nproto.toString          = toString;\nproto.unix              = unix;\nproto.valueOf           = valueOf;\nproto.creationData      = creationData;\n\n// Year\nimport { getSetYear, getIsLeapYear } from '../units/year';\nproto.year       = getSetYear;\nproto.isLeapYear = getIsLeapYear;\n\n// Week Year\nimport { getSetWeekYear, getSetISOWeekYear, getWeeksInYear, getISOWeeksInYear } from '../units/week-year';\nproto.weekYear    = getSetWeekYear;\nproto.isoWeekYear = getSetISOWeekYear;\n\n// Quarter\nimport { getSetQuarter } from '../units/quarter';\nproto.quarter = proto.quarters = getSetQuarter;\n\n// Month\nimport { getSetMonth, getDaysInMonth } from '../units/month';\nproto.month       = getSetMonth;\nproto.daysInMonth = getDaysInMonth;\n\n// Week\nimport { getSetWeek, getSetISOWeek } from '../units/week';\nproto.week           = proto.weeks        = getSetWeek;\nproto.isoWeek        = proto.isoWeeks     = getSetISOWeek;\nproto.weeksInYear    = getWeeksInYear;\nproto.isoWeeksInYear = getISOWeeksInYear;\n\n// Day\nimport { getSetDayOfMonth } from '../units/day-of-month';\nimport { getSetDayOfWeek, getSetISODayOfWeek, getSetLocaleDayOfWeek } from '../units/day-of-week';\nimport { getSetDayOfYear } from '../units/day-of-year';\nproto.date       = getSetDayOfMonth;\nproto.day        = proto.days             = getSetDayOfWeek;\nproto.weekday    = getSetLocaleDayOfWeek;\nproto.isoWeekday = getSetISODayOfWeek;\nproto.dayOfYear  = getSetDayOfYear;\n\n// Hour\nimport { getSetHour } from '../units/hour';\nproto.hour = proto.hours = getSetHour;\n\n// Minute\nimport { getSetMinute } from '../units/minute';\nproto.minute = proto.minutes = getSetMinute;\n\n// Second\nimport { getSetSecond } from '../units/second';\nproto.second = proto.seconds = getSetSecond;\n\n// Millisecond\nimport { getSetMillisecond } from '../units/millisecond';\nproto.millisecond = proto.milliseconds = getSetMillisecond;\n\n// Offset\nimport {\n    getSetOffset,\n    setOffsetToUTC,\n    setOffsetToLocal,\n    setOffsetToParsedOffset,\n    hasAlignedHourOffset,\n    isDaylightSavingTime,\n    isDaylightSavingTimeShifted,\n    getSetZone,\n    isLocal,\n    isUtcOffset,\n    isUtc\n} from '../units/offset';\nproto.utcOffset            = getSetOffset;\nproto.utc                  = setOffsetToUTC;\nproto.local                = setOffsetToLocal;\nproto.parseZone            = setOffsetToParsedOffset;\nproto.hasAlignedHourOffset = hasAlignedHourOffset;\nproto.isDST                = isDaylightSavingTime;\nproto.isLocal              = isLocal;\nproto.isUtcOffset          = isUtcOffset;\nproto.isUtc                = isUtc;\nproto.isUTC                = isUtc;\n\n// Timezone\nimport { getZoneAbbr, getZoneName } from '../units/timezone';\nproto.zoneAbbr = getZoneAbbr;\nproto.zoneName = getZoneName;\n\n// Deprecations\nimport { deprecate } from '../utils/deprecate';\nproto.dates  = deprecate('dates accessor is deprecated. Use date instead.', getSetDayOfMonth);\nproto.months = deprecate('months accessor is deprecated. Use month instead', getSetMonth);\nproto.years  = deprecate('years accessor is deprecated. Use year instead', getSetYear);\nproto.zone   = deprecate('moment().zone is deprecated, use moment().utcOffset instead. http://momentjs.com/guides/#/warnings/zone/', getSetZone);\nproto.isDSTShifted = deprecate('isDSTShifted is deprecated. See http://momentjs.com/guides/#/warnings/dst-shifted/ for more information', isDaylightSavingTimeShifted);\n\nexport default proto;\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/lib/moment/start-end-of.js",
    "content": "import { normalizeUnits } from '../units/aliases';\n\nexport function startOf (units) {\n    units = normalizeUnits(units);\n    // the following switch intentionally omits break keywords\n    // to utilize falling through the cases.\n    switch (units) {\n        case 'year':\n            this.month(0);\n            /* falls through */\n        case 'quarter':\n        case 'month':\n            this.date(1);\n            /* falls through */\n        case 'week':\n        case 'isoWeek':\n        case 'day':\n        case 'date':\n            this.hours(0);\n            /* falls through */\n        case 'hour':\n            this.minutes(0);\n            /* falls through */\n        case 'minute':\n            this.seconds(0);\n            /* falls through */\n        case 'second':\n            this.milliseconds(0);\n    }\n\n    // weeks are a special case\n    if (units === 'week') {\n        this.weekday(0);\n    }\n    if (units === 'isoWeek') {\n        this.isoWeekday(1);\n    }\n\n    // quarters are also special\n    if (units === 'quarter') {\n        this.month(Math.floor(this.month() / 3) * 3);\n    }\n\n    return this;\n}\n\nexport function endOf (units) {\n    units = normalizeUnits(units);\n    if (units === undefined || units === 'millisecond') {\n        return this;\n    }\n\n    // 'date' is an alias for 'day', so it should be considered as such.\n    if (units === 'date') {\n        units = 'day';\n    }\n\n    return this.startOf(units).add(1, (units === 'isoWeek' ? 'week' : units)).subtract(1, 'ms');\n}\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/lib/moment/to-type.js",
    "content": "export function valueOf () {\n    return this._d.valueOf() - ((this._offset || 0) * 60000);\n}\n\nexport function unix () {\n    return Math.floor(this.valueOf() / 1000);\n}\n\nexport function toDate () {\n    return new Date(this.valueOf());\n}\n\nexport function toArray () {\n    var m = this;\n    return [m.year(), m.month(), m.date(), m.hour(), m.minute(), m.second(), m.millisecond()];\n}\n\nexport function toObject () {\n    var m = this;\n    return {\n        years: m.year(),\n        months: m.month(),\n        date: m.date(),\n        hours: m.hours(),\n        minutes: m.minutes(),\n        seconds: m.seconds(),\n        milliseconds: m.milliseconds()\n    };\n}\n\nexport function toJSON () {\n    // new Date(NaN).toJSON() === null\n    return this.isValid() ? this.toISOString() : null;\n}\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/lib/moment/to.js",
    "content": "import { createDuration } from '../duration/create';\nimport { createLocal } from '../create/local';\nimport { isMoment } from '../moment/constructor';\n\nexport function to (time, withoutSuffix) {\n    if (this.isValid() &&\n            ((isMoment(time) && time.isValid()) ||\n             createLocal(time).isValid())) {\n        return createDuration({from: this, to: time}).locale(this.locale()).humanize(!withoutSuffix);\n    } else {\n        return this.localeData().invalidDate();\n    }\n}\n\nexport function toNow (withoutSuffix) {\n    return this.to(createLocal(), withoutSuffix);\n}\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/lib/moment/valid.js",
    "content": "import { isValid as _isValid } from '../create/valid';\nimport extend from '../utils/extend';\nimport getParsingFlags from '../create/parsing-flags';\n\nexport function isValid () {\n    return _isValid(this);\n}\n\nexport function parsingFlags () {\n    return extend({}, getParsingFlags(this));\n}\n\nexport function invalidAt () {\n    return getParsingFlags(this).overflow;\n}\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/lib/parse/regex.js",
    "content": "export var match1         = /\\d/;            //       0 - 9\nexport var match2         = /\\d\\d/;          //      00 - 99\nexport var match3         = /\\d{3}/;         //     000 - 999\nexport var match4         = /\\d{4}/;         //    0000 - 9999\nexport var match6         = /[+-]?\\d{6}/;    // -999999 - 999999\nexport var match1to2      = /\\d\\d?/;         //       0 - 99\nexport var match3to4      = /\\d\\d\\d\\d?/;     //     999 - 9999\nexport var match5to6      = /\\d\\d\\d\\d\\d\\d?/; //   99999 - 999999\nexport var match1to3      = /\\d{1,3}/;       //       0 - 999\nexport var match1to4      = /\\d{1,4}/;       //       0 - 9999\nexport var match1to6      = /[+-]?\\d{1,6}/;  // -999999 - 999999\n\nexport var matchUnsigned  = /\\d+/;           //       0 - inf\nexport var matchSigned    = /[+-]?\\d+/;      //    -inf - inf\n\nexport var matchOffset    = /Z|[+-]\\d\\d:?\\d\\d/gi; // +00:00 -00:00 +0000 -0000 or Z\nexport var matchShortOffset = /Z|[+-]\\d\\d(?::?\\d\\d)?/gi; // +00 -00 +00:00 -00:00 +0000 -0000 or Z\n\nexport var matchTimestamp = /[+-]?\\d+(\\.\\d{1,3})?/; // 123456789 123456789.123\n\n// any word (or two) characters or numbers including two/three word month in arabic.\n// includes scottish gaelic two word and hyphenated months\nexport var matchWord = /[0-9]*['a-z\\u00A0-\\u05FF\\u0700-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF]+|[\\u0600-\\u06FF\\/]+(\\s*?[\\u0600-\\u06FF]+){1,2}/i;\n\n\nimport hasOwnProp from '../utils/has-own-prop';\nimport isFunction from '../utils/is-function';\n\nvar regexes = {};\n\nexport function addRegexToken (token, regex, strictRegex) {\n    regexes[token] = isFunction(regex) ? regex : function (isStrict, localeData) {\n        return (isStrict && strictRegex) ? strictRegex : regex;\n    };\n}\n\nexport function getParseRegexForToken (token, config) {\n    if (!hasOwnProp(regexes, token)) {\n        return new RegExp(unescapeFormat(token));\n    }\n\n    return regexes[token](config._strict, config._locale);\n}\n\n// Code from http://stackoverflow.com/questions/3561493/is-there-a-regexp-escape-function-in-javascript\nfunction unescapeFormat(s) {\n    return regexEscape(s.replace('\\\\', '').replace(/\\\\(\\[)|\\\\(\\])|\\[([^\\]\\[]*)\\]|\\\\(.)/g, function (matched, p1, p2, p3, p4) {\n        return p1 || p2 || p3 || p4;\n    }));\n}\n\nexport function regexEscape(s) {\n    return s.replace(/[-\\/\\\\^$*+?.()|[\\]{}]/g, '\\\\$&');\n}\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/lib/parse/token.js",
    "content": "import hasOwnProp from '../utils/has-own-prop';\nimport isNumber from '../utils/is-number';\nimport toInt from '../utils/to-int';\n\nvar tokens = {};\n\nexport function addParseToken (token, callback) {\n    var i, func = callback;\n    if (typeof token === 'string') {\n        token = [token];\n    }\n    if (isNumber(callback)) {\n        func = function (input, array) {\n            array[callback] = toInt(input);\n        };\n    }\n    for (i = 0; i < token.length; i++) {\n        tokens[token[i]] = func;\n    }\n}\n\nexport function addWeekParseToken (token, callback) {\n    addParseToken(token, function (input, array, config, token) {\n        config._w = config._w || {};\n        callback(input, config._w, config, token);\n    });\n}\n\nexport function addTimeToArrayFromToken(token, input, config) {\n    if (input != null && hasOwnProp(tokens, token)) {\n        tokens[token](input, config._a, config, token);\n    }\n}\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/lib/units/aliases.js",
    "content": "import hasOwnProp from '../utils/has-own-prop';\n\nvar aliases = {};\n\nexport function addUnitAlias (unit, shorthand) {\n    var lowerCase = unit.toLowerCase();\n    aliases[lowerCase] = aliases[lowerCase + 's'] = aliases[shorthand] = unit;\n}\n\nexport function normalizeUnits(units) {\n    return typeof units === 'string' ? aliases[units] || aliases[units.toLowerCase()] : undefined;\n}\n\nexport function normalizeObjectUnits(inputObject) {\n    var normalizedInput = {},\n        normalizedProp,\n        prop;\n\n    for (prop in inputObject) {\n        if (hasOwnProp(inputObject, prop)) {\n            normalizedProp = normalizeUnits(prop);\n            if (normalizedProp) {\n                normalizedInput[normalizedProp] = inputObject[prop];\n            }\n        }\n    }\n\n    return normalizedInput;\n}\n\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/lib/units/constants.js",
    "content": "export var YEAR = 0;\nexport var MONTH = 1;\nexport var DATE = 2;\nexport var HOUR = 3;\nexport var MINUTE = 4;\nexport var SECOND = 5;\nexport var MILLISECOND = 6;\nexport var WEEK = 7;\nexport var WEEKDAY = 8;\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/lib/units/day-of-month.js",
    "content": "import { makeGetSet } from '../moment/get-set';\nimport { addFormatToken } from '../format/format';\nimport { addUnitAlias } from './aliases';\nimport { addUnitPriority } from './priorities';\nimport { addRegexToken, match1to2, match2 } from '../parse/regex';\nimport { addParseToken } from '../parse/token';\nimport { DATE } from './constants';\nimport toInt from '../utils/to-int';\n\n// FORMATTING\n\naddFormatToken('D', ['DD', 2], 'Do', 'date');\n\n// ALIASES\n\naddUnitAlias('date', 'D');\n\n// PRIOROITY\naddUnitPriority('date', 9);\n\n// PARSING\n\naddRegexToken('D',  match1to2);\naddRegexToken('DD', match1to2, match2);\naddRegexToken('Do', function (isStrict, locale) {\n    // TODO: Remove \"ordinalParse\" fallback in next major release.\n    return isStrict ?\n      (locale._dayOfMonthOrdinalParse || locale._ordinalParse) :\n      locale._dayOfMonthOrdinalParseLenient;\n});\n\naddParseToken(['D', 'DD'], DATE);\naddParseToken('Do', function (input, array) {\n    array[DATE] = toInt(input.match(match1to2)[0], 10);\n});\n\n// MOMENTS\n\nexport var getSetDayOfMonth = makeGetSet('Date', true);\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/lib/units/day-of-week.js",
    "content": "import { addFormatToken } from '../format/format';\nimport { addUnitAlias } from './aliases';\nimport { addUnitPriority } from './priorities';\nimport { addRegexToken, match1to2, matchWord, regexEscape } from '../parse/regex';\nimport { addWeekParseToken } from '../parse/token';\nimport toInt from '../utils/to-int';\nimport isArray from '../utils/is-array';\nimport indexOf from '../utils/index-of';\nimport hasOwnProp from '../utils/has-own-prop';\nimport { createUTC } from '../create/utc';\nimport getParsingFlags from '../create/parsing-flags';\n\n// FORMATTING\n\naddFormatToken('d', 0, 'do', 'day');\n\naddFormatToken('dd', 0, 0, function (format) {\n    return this.localeData().weekdaysMin(this, format);\n});\n\naddFormatToken('ddd', 0, 0, function (format) {\n    return this.localeData().weekdaysShort(this, format);\n});\n\naddFormatToken('dddd', 0, 0, function (format) {\n    return this.localeData().weekdays(this, format);\n});\n\naddFormatToken('e', 0, 0, 'weekday');\naddFormatToken('E', 0, 0, 'isoWeekday');\n\n// ALIASES\n\naddUnitAlias('day', 'd');\naddUnitAlias('weekday', 'e');\naddUnitAlias('isoWeekday', 'E');\n\n// PRIORITY\naddUnitPriority('day', 11);\naddUnitPriority('weekday', 11);\naddUnitPriority('isoWeekday', 11);\n\n// PARSING\n\naddRegexToken('d',    match1to2);\naddRegexToken('e',    match1to2);\naddRegexToken('E',    match1to2);\naddRegexToken('dd',   function (isStrict, locale) {\n    return locale.weekdaysMinRegex(isStrict);\n});\naddRegexToken('ddd',   function (isStrict, locale) {\n    return locale.weekdaysShortRegex(isStrict);\n});\naddRegexToken('dddd',   function (isStrict, locale) {\n    return locale.weekdaysRegex(isStrict);\n});\n\naddWeekParseToken(['dd', 'ddd', 'dddd'], function (input, week, config, token) {\n    var weekday = config._locale.weekdaysParse(input, token, config._strict);\n    // if we didn't get a weekday name, mark the date as invalid\n    if (weekday != null) {\n        week.d = weekday;\n    } else {\n        getParsingFlags(config).invalidWeekday = input;\n    }\n});\n\naddWeekParseToken(['d', 'e', 'E'], function (input, week, config, token) {\n    week[token] = toInt(input);\n});\n\n// HELPERS\n\nfunction parseWeekday(input, locale) {\n    if (typeof input !== 'string') {\n        return input;\n    }\n\n    if (!isNaN(input)) {\n        return parseInt(input, 10);\n    }\n\n    input = locale.weekdaysParse(input);\n    if (typeof input === 'number') {\n        return input;\n    }\n\n    return null;\n}\n\nfunction parseIsoWeekday(input, locale) {\n    if (typeof input === 'string') {\n        return locale.weekdaysParse(input) % 7 || 7;\n    }\n    return isNaN(input) ? null : input;\n}\n\n// LOCALES\n\nexport var defaultLocaleWeekdays = 'Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday'.split('_');\nexport function localeWeekdays (m, format) {\n    if (!m) {\n        return isArray(this._weekdays) ? this._weekdays :\n            this._weekdays['standalone'];\n    }\n    return isArray(this._weekdays) ? this._weekdays[m.day()] :\n        this._weekdays[this._weekdays.isFormat.test(format) ? 'format' : 'standalone'][m.day()];\n}\n\nexport var defaultLocaleWeekdaysShort = 'Sun_Mon_Tue_Wed_Thu_Fri_Sat'.split('_');\nexport function localeWeekdaysShort (m) {\n    return (m) ? this._weekdaysShort[m.day()] : this._weekdaysShort;\n}\n\nexport var defaultLocaleWeekdaysMin = 'Su_Mo_Tu_We_Th_Fr_Sa'.split('_');\nexport function localeWeekdaysMin (m) {\n    return (m) ? this._weekdaysMin[m.day()] : this._weekdaysMin;\n}\n\nfunction handleStrictParse(weekdayName, format, strict) {\n    var i, ii, mom, llc = weekdayName.toLocaleLowerCase();\n    if (!this._weekdaysParse) {\n        this._weekdaysParse = [];\n        this._shortWeekdaysParse = [];\n        this._minWeekdaysParse = [];\n\n        for (i = 0; i < 7; ++i) {\n            mom = createUTC([2000, 1]).day(i);\n            this._minWeekdaysParse[i] = this.weekdaysMin(mom, '').toLocaleLowerCase();\n            this._shortWeekdaysParse[i] = this.weekdaysShort(mom, '').toLocaleLowerCase();\n            this._weekdaysParse[i] = this.weekdays(mom, '').toLocaleLowerCase();\n        }\n    }\n\n    if (strict) {\n        if (format === 'dddd') {\n            ii = indexOf.call(this._weekdaysParse, llc);\n            return ii !== -1 ? ii : null;\n        } else if (format === 'ddd') {\n            ii = indexOf.call(this._shortWeekdaysParse, llc);\n            return ii !== -1 ? ii : null;\n        } else {\n            ii = indexOf.call(this._minWeekdaysParse, llc);\n            return ii !== -1 ? ii : null;\n        }\n    } else {\n        if (format === 'dddd') {\n            ii = indexOf.call(this._weekdaysParse, llc);\n            if (ii !== -1) {\n                return ii;\n            }\n            ii = indexOf.call(this._shortWeekdaysParse, llc);\n            if (ii !== -1) {\n                return ii;\n            }\n            ii = indexOf.call(this._minWeekdaysParse, llc);\n            return ii !== -1 ? ii : null;\n        } else if (format === 'ddd') {\n            ii = indexOf.call(this._shortWeekdaysParse, llc);\n            if (ii !== -1) {\n                return ii;\n            }\n            ii = indexOf.call(this._weekdaysParse, llc);\n            if (ii !== -1) {\n                return ii;\n            }\n            ii = indexOf.call(this._minWeekdaysParse, llc);\n            return ii !== -1 ? ii : null;\n        } else {\n            ii = indexOf.call(this._minWeekdaysParse, llc);\n            if (ii !== -1) {\n                return ii;\n            }\n            ii = indexOf.call(this._weekdaysParse, llc);\n            if (ii !== -1) {\n                return ii;\n            }\n            ii = indexOf.call(this._shortWeekdaysParse, llc);\n            return ii !== -1 ? ii : null;\n        }\n    }\n}\n\nexport function localeWeekdaysParse (weekdayName, format, strict) {\n    var i, mom, regex;\n\n    if (this._weekdaysParseExact) {\n        return handleStrictParse.call(this, weekdayName, format, strict);\n    }\n\n    if (!this._weekdaysParse) {\n        this._weekdaysParse = [];\n        this._minWeekdaysParse = [];\n        this._shortWeekdaysParse = [];\n        this._fullWeekdaysParse = [];\n    }\n\n    for (i = 0; i < 7; i++) {\n        // make the regex if we don't have it already\n\n        mom = createUTC([2000, 1]).day(i);\n        if (strict && !this._fullWeekdaysParse[i]) {\n            this._fullWeekdaysParse[i] = new RegExp('^' + this.weekdays(mom, '').replace('.', '\\.?') + '$', 'i');\n            this._shortWeekdaysParse[i] = new RegExp('^' + this.weekdaysShort(mom, '').replace('.', '\\.?') + '$', 'i');\n            this._minWeekdaysParse[i] = new RegExp('^' + this.weekdaysMin(mom, '').replace('.', '\\.?') + '$', 'i');\n        }\n        if (!this._weekdaysParse[i]) {\n            regex = '^' + this.weekdays(mom, '') + '|^' + this.weekdaysShort(mom, '') + '|^' + this.weekdaysMin(mom, '');\n            this._weekdaysParse[i] = new RegExp(regex.replace('.', ''), 'i');\n        }\n        // test the regex\n        if (strict && format === 'dddd' && this._fullWeekdaysParse[i].test(weekdayName)) {\n            return i;\n        } else if (strict && format === 'ddd' && this._shortWeekdaysParse[i].test(weekdayName)) {\n            return i;\n        } else if (strict && format === 'dd' && this._minWeekdaysParse[i].test(weekdayName)) {\n            return i;\n        } else if (!strict && this._weekdaysParse[i].test(weekdayName)) {\n            return i;\n        }\n    }\n}\n\n// MOMENTS\n\nexport function getSetDayOfWeek (input) {\n    if (!this.isValid()) {\n        return input != null ? this : NaN;\n    }\n    var day = this._isUTC ? this._d.getUTCDay() : this._d.getDay();\n    if (input != null) {\n        input = parseWeekday(input, this.localeData());\n        return this.add(input - day, 'd');\n    } else {\n        return day;\n    }\n}\n\nexport function getSetLocaleDayOfWeek (input) {\n    if (!this.isValid()) {\n        return input != null ? this : NaN;\n    }\n    var weekday = (this.day() + 7 - this.localeData()._week.dow) % 7;\n    return input == null ? weekday : this.add(input - weekday, 'd');\n}\n\nexport function getSetISODayOfWeek (input) {\n    if (!this.isValid()) {\n        return input != null ? this : NaN;\n    }\n\n    // behaves the same as moment#day except\n    // as a getter, returns 7 instead of 0 (1-7 range instead of 0-6)\n    // as a setter, sunday should belong to the previous week.\n\n    if (input != null) {\n        var weekday = parseIsoWeekday(input, this.localeData());\n        return this.day(this.day() % 7 ? weekday : weekday - 7);\n    } else {\n        return this.day() || 7;\n    }\n}\n\nvar defaultWeekdaysRegex = matchWord;\nexport function weekdaysRegex (isStrict) {\n    if (this._weekdaysParseExact) {\n        if (!hasOwnProp(this, '_weekdaysRegex')) {\n            computeWeekdaysParse.call(this);\n        }\n        if (isStrict) {\n            return this._weekdaysStrictRegex;\n        } else {\n            return this._weekdaysRegex;\n        }\n    } else {\n        if (!hasOwnProp(this, '_weekdaysRegex')) {\n            this._weekdaysRegex = defaultWeekdaysRegex;\n        }\n        return this._weekdaysStrictRegex && isStrict ?\n            this._weekdaysStrictRegex : this._weekdaysRegex;\n    }\n}\n\nvar defaultWeekdaysShortRegex = matchWord;\nexport function weekdaysShortRegex (isStrict) {\n    if (this._weekdaysParseExact) {\n        if (!hasOwnProp(this, '_weekdaysRegex')) {\n            computeWeekdaysParse.call(this);\n        }\n        if (isStrict) {\n            return this._weekdaysShortStrictRegex;\n        } else {\n            return this._weekdaysShortRegex;\n        }\n    } else {\n        if (!hasOwnProp(this, '_weekdaysShortRegex')) {\n            this._weekdaysShortRegex = defaultWeekdaysShortRegex;\n        }\n        return this._weekdaysShortStrictRegex && isStrict ?\n            this._weekdaysShortStrictRegex : this._weekdaysShortRegex;\n    }\n}\n\nvar defaultWeekdaysMinRegex = matchWord;\nexport function weekdaysMinRegex (isStrict) {\n    if (this._weekdaysParseExact) {\n        if (!hasOwnProp(this, '_weekdaysRegex')) {\n            computeWeekdaysParse.call(this);\n        }\n        if (isStrict) {\n            return this._weekdaysMinStrictRegex;\n        } else {\n            return this._weekdaysMinRegex;\n        }\n    } else {\n        if (!hasOwnProp(this, '_weekdaysMinRegex')) {\n            this._weekdaysMinRegex = defaultWeekdaysMinRegex;\n        }\n        return this._weekdaysMinStrictRegex && isStrict ?\n            this._weekdaysMinStrictRegex : this._weekdaysMinRegex;\n    }\n}\n\n\nfunction computeWeekdaysParse () {\n    function cmpLenRev(a, b) {\n        return b.length - a.length;\n    }\n\n    var minPieces = [], shortPieces = [], longPieces = [], mixedPieces = [],\n        i, mom, minp, shortp, longp;\n    for (i = 0; i < 7; i++) {\n        // make the regex if we don't have it already\n        mom = createUTC([2000, 1]).day(i);\n        minp = this.weekdaysMin(mom, '');\n        shortp = this.weekdaysShort(mom, '');\n        longp = this.weekdays(mom, '');\n        minPieces.push(minp);\n        shortPieces.push(shortp);\n        longPieces.push(longp);\n        mixedPieces.push(minp);\n        mixedPieces.push(shortp);\n        mixedPieces.push(longp);\n    }\n    // Sorting makes sure if one weekday (or abbr) is a prefix of another it\n    // will match the longer piece.\n    minPieces.sort(cmpLenRev);\n    shortPieces.sort(cmpLenRev);\n    longPieces.sort(cmpLenRev);\n    mixedPieces.sort(cmpLenRev);\n    for (i = 0; i < 7; i++) {\n        shortPieces[i] = regexEscape(shortPieces[i]);\n        longPieces[i] = regexEscape(longPieces[i]);\n        mixedPieces[i] = regexEscape(mixedPieces[i]);\n    }\n\n    this._weekdaysRegex = new RegExp('^(' + mixedPieces.join('|') + ')', 'i');\n    this._weekdaysShortRegex = this._weekdaysRegex;\n    this._weekdaysMinRegex = this._weekdaysRegex;\n\n    this._weekdaysStrictRegex = new RegExp('^(' + longPieces.join('|') + ')', 'i');\n    this._weekdaysShortStrictRegex = new RegExp('^(' + shortPieces.join('|') + ')', 'i');\n    this._weekdaysMinStrictRegex = new RegExp('^(' + minPieces.join('|') + ')', 'i');\n}\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/lib/units/day-of-year.js",
    "content": "import { addFormatToken } from '../format/format';\nimport { addUnitAlias } from './aliases';\nimport { addUnitPriority } from './priorities';\nimport { addRegexToken, match3, match1to3 } from '../parse/regex';\nimport { daysInYear } from './year';\nimport { createUTCDate } from '../create/date-from-array';\nimport { addParseToken } from '../parse/token';\nimport toInt from '../utils/to-int';\n\n// FORMATTING\n\naddFormatToken('DDD', ['DDDD', 3], 'DDDo', 'dayOfYear');\n\n// ALIASES\n\naddUnitAlias('dayOfYear', 'DDD');\n\n// PRIORITY\naddUnitPriority('dayOfYear', 4);\n\n// PARSING\n\naddRegexToken('DDD',  match1to3);\naddRegexToken('DDDD', match3);\naddParseToken(['DDD', 'DDDD'], function (input, array, config) {\n    config._dayOfYear = toInt(input);\n});\n\n// HELPERS\n\n// MOMENTS\n\nexport function getSetDayOfYear (input) {\n    var dayOfYear = Math.round((this.clone().startOf('day') - this.clone().startOf('year')) / 864e5) + 1;\n    return input == null ? dayOfYear : this.add((input - dayOfYear), 'd');\n}\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/lib/units/hour.js",
    "content": "import { makeGetSet } from '../moment/get-set';\nimport { addFormatToken } from '../format/format';\nimport { addUnitAlias } from './aliases';\nimport { addUnitPriority } from './priorities';\nimport { addRegexToken, match1to2, match2, match3to4, match5to6 } from '../parse/regex';\nimport { addParseToken } from '../parse/token';\nimport { HOUR, MINUTE, SECOND } from './constants';\nimport toInt from '../utils/to-int';\nimport zeroFill from '../utils/zero-fill';\nimport getParsingFlags from '../create/parsing-flags';\n\n// FORMATTING\n\nfunction hFormat() {\n    return this.hours() % 12 || 12;\n}\n\nfunction kFormat() {\n    return this.hours() || 24;\n}\n\naddFormatToken('H', ['HH', 2], 0, 'hour');\naddFormatToken('h', ['hh', 2], 0, hFormat);\naddFormatToken('k', ['kk', 2], 0, kFormat);\n\naddFormatToken('hmm', 0, 0, function () {\n    return '' + hFormat.apply(this) + zeroFill(this.minutes(), 2);\n});\n\naddFormatToken('hmmss', 0, 0, function () {\n    return '' + hFormat.apply(this) + zeroFill(this.minutes(), 2) +\n        zeroFill(this.seconds(), 2);\n});\n\naddFormatToken('Hmm', 0, 0, function () {\n    return '' + this.hours() + zeroFill(this.minutes(), 2);\n});\n\naddFormatToken('Hmmss', 0, 0, function () {\n    return '' + this.hours() + zeroFill(this.minutes(), 2) +\n        zeroFill(this.seconds(), 2);\n});\n\nfunction meridiem (token, lowercase) {\n    addFormatToken(token, 0, 0, function () {\n        return this.localeData().meridiem(this.hours(), this.minutes(), lowercase);\n    });\n}\n\nmeridiem('a', true);\nmeridiem('A', false);\n\n// ALIASES\n\naddUnitAlias('hour', 'h');\n\n// PRIORITY\naddUnitPriority('hour', 13);\n\n// PARSING\n\nfunction matchMeridiem (isStrict, locale) {\n    return locale._meridiemParse;\n}\n\naddRegexToken('a',  matchMeridiem);\naddRegexToken('A',  matchMeridiem);\naddRegexToken('H',  match1to2);\naddRegexToken('h',  match1to2);\naddRegexToken('k',  match1to2);\naddRegexToken('HH', match1to2, match2);\naddRegexToken('hh', match1to2, match2);\naddRegexToken('kk', match1to2, match2);\n\naddRegexToken('hmm', match3to4);\naddRegexToken('hmmss', match5to6);\naddRegexToken('Hmm', match3to4);\naddRegexToken('Hmmss', match5to6);\n\naddParseToken(['H', 'HH'], HOUR);\naddParseToken(['k', 'kk'], function (input, array, config) {\n    var kInput = toInt(input);\n    array[HOUR] = kInput === 24 ? 0 : kInput;\n});\naddParseToken(['a', 'A'], function (input, array, config) {\n    config._isPm = config._locale.isPM(input);\n    config._meridiem = input;\n});\naddParseToken(['h', 'hh'], function (input, array, config) {\n    array[HOUR] = toInt(input);\n    getParsingFlags(config).bigHour = true;\n});\naddParseToken('hmm', function (input, array, config) {\n    var pos = input.length - 2;\n    array[HOUR] = toInt(input.substr(0, pos));\n    array[MINUTE] = toInt(input.substr(pos));\n    getParsingFlags(config).bigHour = true;\n});\naddParseToken('hmmss', function (input, array, config) {\n    var pos1 = input.length - 4;\n    var pos2 = input.length - 2;\n    array[HOUR] = toInt(input.substr(0, pos1));\n    array[MINUTE] = toInt(input.substr(pos1, 2));\n    array[SECOND] = toInt(input.substr(pos2));\n    getParsingFlags(config).bigHour = true;\n});\naddParseToken('Hmm', function (input, array, config) {\n    var pos = input.length - 2;\n    array[HOUR] = toInt(input.substr(0, pos));\n    array[MINUTE] = toInt(input.substr(pos));\n});\naddParseToken('Hmmss', function (input, array, config) {\n    var pos1 = input.length - 4;\n    var pos2 = input.length - 2;\n    array[HOUR] = toInt(input.substr(0, pos1));\n    array[MINUTE] = toInt(input.substr(pos1, 2));\n    array[SECOND] = toInt(input.substr(pos2));\n});\n\n// LOCALES\n\nexport function localeIsPM (input) {\n    // IE8 Quirks Mode & IE7 Standards Mode do not allow accessing strings like arrays\n    // Using charAt should be more compatible.\n    return ((input + '').toLowerCase().charAt(0) === 'p');\n}\n\nexport var defaultLocaleMeridiemParse = /[ap]\\.?m?\\.?/i;\nexport function localeMeridiem (hours, minutes, isLower) {\n    if (hours > 11) {\n        return isLower ? 'pm' : 'PM';\n    } else {\n        return isLower ? 'am' : 'AM';\n    }\n}\n\n\n// MOMENTS\n\n// Setting the hour should keep the time, because the user explicitly\n// specified which hour he wants. So trying to maintain the same hour (in\n// a new timezone) makes sense. Adding/subtracting hours does not follow\n// this rule.\nexport var getSetHour = makeGetSet('Hours', true);\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/lib/units/millisecond.js",
    "content": "import { makeGetSet } from '../moment/get-set';\nimport { addFormatToken } from '../format/format';\nimport { addUnitAlias } from './aliases';\nimport { addUnitPriority } from './priorities';\nimport { addRegexToken, match1, match2, match3, match1to3, matchUnsigned } from '../parse/regex';\nimport { addParseToken } from '../parse/token';\nimport { MILLISECOND } from './constants';\nimport toInt from '../utils/to-int';\n\n// FORMATTING\n\naddFormatToken('S', 0, 0, function () {\n    return ~~(this.millisecond() / 100);\n});\n\naddFormatToken(0, ['SS', 2], 0, function () {\n    return ~~(this.millisecond() / 10);\n});\n\naddFormatToken(0, ['SSS', 3], 0, 'millisecond');\naddFormatToken(0, ['SSSS', 4], 0, function () {\n    return this.millisecond() * 10;\n});\naddFormatToken(0, ['SSSSS', 5], 0, function () {\n    return this.millisecond() * 100;\n});\naddFormatToken(0, ['SSSSSS', 6], 0, function () {\n    return this.millisecond() * 1000;\n});\naddFormatToken(0, ['SSSSSSS', 7], 0, function () {\n    return this.millisecond() * 10000;\n});\naddFormatToken(0, ['SSSSSSSS', 8], 0, function () {\n    return this.millisecond() * 100000;\n});\naddFormatToken(0, ['SSSSSSSSS', 9], 0, function () {\n    return this.millisecond() * 1000000;\n});\n\n\n// ALIASES\n\naddUnitAlias('millisecond', 'ms');\n\n// PRIORITY\n\naddUnitPriority('millisecond', 16);\n\n// PARSING\n\naddRegexToken('S',    match1to3, match1);\naddRegexToken('SS',   match1to3, match2);\naddRegexToken('SSS',  match1to3, match3);\n\nvar token;\nfor (token = 'SSSS'; token.length <= 9; token += 'S') {\n    addRegexToken(token, matchUnsigned);\n}\n\nfunction parseMs(input, array) {\n    array[MILLISECOND] = toInt(('0.' + input) * 1000);\n}\n\nfor (token = 'S'; token.length <= 9; token += 'S') {\n    addParseToken(token, parseMs);\n}\n// MOMENTS\n\nexport var getSetMillisecond = makeGetSet('Milliseconds', false);\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/lib/units/minute.js",
    "content": "import { makeGetSet } from '../moment/get-set';\nimport { addFormatToken } from '../format/format';\nimport { addUnitAlias } from './aliases';\nimport { addUnitPriority } from './priorities';\nimport { addRegexToken, match1to2, match2 } from '../parse/regex';\nimport { addParseToken } from '../parse/token';\nimport { MINUTE } from './constants';\n\n// FORMATTING\n\naddFormatToken('m', ['mm', 2], 0, 'minute');\n\n// ALIASES\n\naddUnitAlias('minute', 'm');\n\n// PRIORITY\n\naddUnitPriority('minute', 14);\n\n// PARSING\n\naddRegexToken('m',  match1to2);\naddRegexToken('mm', match1to2, match2);\naddParseToken(['m', 'mm'], MINUTE);\n\n// MOMENTS\n\nexport var getSetMinute = makeGetSet('Minutes', false);\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/lib/units/month.js",
    "content": "import { get } from '../moment/get-set';\nimport hasOwnProp from '../utils/has-own-prop';\nimport { addFormatToken } from '../format/format';\nimport { addUnitAlias } from './aliases';\nimport { addUnitPriority } from './priorities';\nimport { addRegexToken, match1to2, match2, matchWord, regexEscape } from '../parse/regex';\nimport { addParseToken } from '../parse/token';\nimport { hooks } from '../utils/hooks';\nimport { MONTH } from './constants';\nimport toInt from '../utils/to-int';\nimport isArray from '../utils/is-array';\nimport isNumber from '../utils/is-number';\nimport indexOf from '../utils/index-of';\nimport { createUTC } from '../create/utc';\nimport getParsingFlags from '../create/parsing-flags';\n\nexport function daysInMonth(year, month) {\n    return new Date(Date.UTC(year, month + 1, 0)).getUTCDate();\n}\n\n// FORMATTING\n\naddFormatToken('M', ['MM', 2], 'Mo', function () {\n    return this.month() + 1;\n});\n\naddFormatToken('MMM', 0, 0, function (format) {\n    return this.localeData().monthsShort(this, format);\n});\n\naddFormatToken('MMMM', 0, 0, function (format) {\n    return this.localeData().months(this, format);\n});\n\n// ALIASES\n\naddUnitAlias('month', 'M');\n\n// PRIORITY\n\naddUnitPriority('month', 8);\n\n// PARSING\n\naddRegexToken('M',    match1to2);\naddRegexToken('MM',   match1to2, match2);\naddRegexToken('MMM',  function (isStrict, locale) {\n    return locale.monthsShortRegex(isStrict);\n});\naddRegexToken('MMMM', function (isStrict, locale) {\n    return locale.monthsRegex(isStrict);\n});\n\naddParseToken(['M', 'MM'], function (input, array) {\n    array[MONTH] = toInt(input) - 1;\n});\n\naddParseToken(['MMM', 'MMMM'], function (input, array, config, token) {\n    var month = config._locale.monthsParse(input, token, config._strict);\n    // if we didn't find a month name, mark the date as invalid.\n    if (month != null) {\n        array[MONTH] = month;\n    } else {\n        getParsingFlags(config).invalidMonth = input;\n    }\n});\n\n// LOCALES\n\nvar MONTHS_IN_FORMAT = /D[oD]?(\\[[^\\[\\]]*\\]|\\s)+MMMM?/;\nexport var defaultLocaleMonths = 'January_February_March_April_May_June_July_August_September_October_November_December'.split('_');\nexport function localeMonths (m, format) {\n    if (!m) {\n        return isArray(this._months) ? this._months :\n            this._months['standalone'];\n    }\n    return isArray(this._months) ? this._months[m.month()] :\n        this._months[(this._months.isFormat || MONTHS_IN_FORMAT).test(format) ? 'format' : 'standalone'][m.month()];\n}\n\nexport var defaultLocaleMonthsShort = 'Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec'.split('_');\nexport function localeMonthsShort (m, format) {\n    if (!m) {\n        return isArray(this._monthsShort) ? this._monthsShort :\n            this._monthsShort['standalone'];\n    }\n    return isArray(this._monthsShort) ? this._monthsShort[m.month()] :\n        this._monthsShort[MONTHS_IN_FORMAT.test(format) ? 'format' : 'standalone'][m.month()];\n}\n\nfunction handleStrictParse(monthName, format, strict) {\n    var i, ii, mom, llc = monthName.toLocaleLowerCase();\n    if (!this._monthsParse) {\n        // this is not used\n        this._monthsParse = [];\n        this._longMonthsParse = [];\n        this._shortMonthsParse = [];\n        for (i = 0; i < 12; ++i) {\n            mom = createUTC([2000, i]);\n            this._shortMonthsParse[i] = this.monthsShort(mom, '').toLocaleLowerCase();\n            this._longMonthsParse[i] = this.months(mom, '').toLocaleLowerCase();\n        }\n    }\n\n    if (strict) {\n        if (format === 'MMM') {\n            ii = indexOf.call(this._shortMonthsParse, llc);\n            return ii !== -1 ? ii : null;\n        } else {\n            ii = indexOf.call(this._longMonthsParse, llc);\n            return ii !== -1 ? ii : null;\n        }\n    } else {\n        if (format === 'MMM') {\n            ii = indexOf.call(this._shortMonthsParse, llc);\n            if (ii !== -1) {\n                return ii;\n            }\n            ii = indexOf.call(this._longMonthsParse, llc);\n            return ii !== -1 ? ii : null;\n        } else {\n            ii = indexOf.call(this._longMonthsParse, llc);\n            if (ii !== -1) {\n                return ii;\n            }\n            ii = indexOf.call(this._shortMonthsParse, llc);\n            return ii !== -1 ? ii : null;\n        }\n    }\n}\n\nexport function localeMonthsParse (monthName, format, strict) {\n    var i, mom, regex;\n\n    if (this._monthsParseExact) {\n        return handleStrictParse.call(this, monthName, format, strict);\n    }\n\n    if (!this._monthsParse) {\n        this._monthsParse = [];\n        this._longMonthsParse = [];\n        this._shortMonthsParse = [];\n    }\n\n    // TODO: add sorting\n    // Sorting makes sure if one month (or abbr) is a prefix of another\n    // see sorting in computeMonthsParse\n    for (i = 0; i < 12; i++) {\n        // make the regex if we don't have it already\n        mom = createUTC([2000, i]);\n        if (strict && !this._longMonthsParse[i]) {\n            this._longMonthsParse[i] = new RegExp('^' + this.months(mom, '').replace('.', '') + '$', 'i');\n            this._shortMonthsParse[i] = new RegExp('^' + this.monthsShort(mom, '').replace('.', '') + '$', 'i');\n        }\n        if (!strict && !this._monthsParse[i]) {\n            regex = '^' + this.months(mom, '') + '|^' + this.monthsShort(mom, '');\n            this._monthsParse[i] = new RegExp(regex.replace('.', ''), 'i');\n        }\n        // test the regex\n        if (strict && format === 'MMMM' && this._longMonthsParse[i].test(monthName)) {\n            return i;\n        } else if (strict && format === 'MMM' && this._shortMonthsParse[i].test(monthName)) {\n            return i;\n        } else if (!strict && this._monthsParse[i].test(monthName)) {\n            return i;\n        }\n    }\n}\n\n// MOMENTS\n\nexport function setMonth (mom, value) {\n    var dayOfMonth;\n\n    if (!mom.isValid()) {\n        // No op\n        return mom;\n    }\n\n    if (typeof value === 'string') {\n        if (/^\\d+$/.test(value)) {\n            value = toInt(value);\n        } else {\n            value = mom.localeData().monthsParse(value);\n            // TODO: Another silent failure?\n            if (!isNumber(value)) {\n                return mom;\n            }\n        }\n    }\n\n    dayOfMonth = Math.min(mom.date(), daysInMonth(mom.year(), value));\n    mom._d['set' + (mom._isUTC ? 'UTC' : '') + 'Month'](value, dayOfMonth);\n    return mom;\n}\n\nexport function getSetMonth (value) {\n    if (value != null) {\n        setMonth(this, value);\n        hooks.updateOffset(this, true);\n        return this;\n    } else {\n        return get(this, 'Month');\n    }\n}\n\nexport function getDaysInMonth () {\n    return daysInMonth(this.year(), this.month());\n}\n\nvar defaultMonthsShortRegex = matchWord;\nexport function monthsShortRegex (isStrict) {\n    if (this._monthsParseExact) {\n        if (!hasOwnProp(this, '_monthsRegex')) {\n            computeMonthsParse.call(this);\n        }\n        if (isStrict) {\n            return this._monthsShortStrictRegex;\n        } else {\n            return this._monthsShortRegex;\n        }\n    } else {\n        if (!hasOwnProp(this, '_monthsShortRegex')) {\n            this._monthsShortRegex = defaultMonthsShortRegex;\n        }\n        return this._monthsShortStrictRegex && isStrict ?\n            this._monthsShortStrictRegex : this._monthsShortRegex;\n    }\n}\n\nvar defaultMonthsRegex = matchWord;\nexport function monthsRegex (isStrict) {\n    if (this._monthsParseExact) {\n        if (!hasOwnProp(this, '_monthsRegex')) {\n            computeMonthsParse.call(this);\n        }\n        if (isStrict) {\n            return this._monthsStrictRegex;\n        } else {\n            return this._monthsRegex;\n        }\n    } else {\n        if (!hasOwnProp(this, '_monthsRegex')) {\n            this._monthsRegex = defaultMonthsRegex;\n        }\n        return this._monthsStrictRegex && isStrict ?\n            this._monthsStrictRegex : this._monthsRegex;\n    }\n}\n\nfunction computeMonthsParse () {\n    function cmpLenRev(a, b) {\n        return b.length - a.length;\n    }\n\n    var shortPieces = [], longPieces = [], mixedPieces = [],\n        i, mom;\n    for (i = 0; i < 12; i++) {\n        // make the regex if we don't have it already\n        mom = createUTC([2000, i]);\n        shortPieces.push(this.monthsShort(mom, ''));\n        longPieces.push(this.months(mom, ''));\n        mixedPieces.push(this.months(mom, ''));\n        mixedPieces.push(this.monthsShort(mom, ''));\n    }\n    // Sorting makes sure if one month (or abbr) is a prefix of another it\n    // will match the longer piece.\n    shortPieces.sort(cmpLenRev);\n    longPieces.sort(cmpLenRev);\n    mixedPieces.sort(cmpLenRev);\n    for (i = 0; i < 12; i++) {\n        shortPieces[i] = regexEscape(shortPieces[i]);\n        longPieces[i] = regexEscape(longPieces[i]);\n    }\n    for (i = 0; i < 24; i++) {\n        mixedPieces[i] = regexEscape(mixedPieces[i]);\n    }\n\n    this._monthsRegex = new RegExp('^(' + mixedPieces.join('|') + ')', 'i');\n    this._monthsShortRegex = this._monthsRegex;\n    this._monthsStrictRegex = new RegExp('^(' + longPieces.join('|') + ')', 'i');\n    this._monthsShortStrictRegex = new RegExp('^(' + shortPieces.join('|') + ')', 'i');\n}\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/lib/units/offset.js",
    "content": "import zeroFill from '../utils/zero-fill';\nimport { createDuration } from '../duration/create';\nimport { addSubtract } from '../moment/add-subtract';\nimport { isMoment, copyConfig } from '../moment/constructor';\nimport { addFormatToken } from '../format/format';\nimport { addRegexToken, matchOffset, matchShortOffset } from '../parse/regex';\nimport { addParseToken } from '../parse/token';\nimport { createLocal } from '../create/local';\nimport { prepareConfig } from '../create/from-anything';\nimport { createUTC } from '../create/utc';\nimport isDate from '../utils/is-date';\nimport toInt from '../utils/to-int';\nimport isUndefined from '../utils/is-undefined';\nimport compareArrays from '../utils/compare-arrays';\nimport { hooks } from '../utils/hooks';\n\n// FORMATTING\n\nfunction offset (token, separator) {\n    addFormatToken(token, 0, 0, function () {\n        var offset = this.utcOffset();\n        var sign = '+';\n        if (offset < 0) {\n            offset = -offset;\n            sign = '-';\n        }\n        return sign + zeroFill(~~(offset / 60), 2) + separator + zeroFill(~~(offset) % 60, 2);\n    });\n}\n\noffset('Z', ':');\noffset('ZZ', '');\n\n// PARSING\n\naddRegexToken('Z',  matchShortOffset);\naddRegexToken('ZZ', matchShortOffset);\naddParseToken(['Z', 'ZZ'], function (input, array, config) {\n    config._useUTC = true;\n    config._tzm = offsetFromString(matchShortOffset, input);\n});\n\n// HELPERS\n\n// timezone chunker\n// '+10:00' > ['10',  '00']\n// '-1530'  > ['-15', '30']\nvar chunkOffset = /([\\+\\-]|\\d\\d)/gi;\n\nfunction offsetFromString(matcher, string) {\n    var matches = (string || '').match(matcher);\n\n    if (matches === null) {\n        return null;\n    }\n\n    var chunk   = matches[matches.length - 1] || [];\n    var parts   = (chunk + '').match(chunkOffset) || ['-', 0, 0];\n    var minutes = +(parts[1] * 60) + toInt(parts[2]);\n\n    return minutes === 0 ?\n      0 :\n      parts[0] === '+' ? minutes : -minutes;\n}\n\n// Return a moment from input, that is local/utc/zone equivalent to model.\nexport function cloneWithOffset(input, model) {\n    var res, diff;\n    if (model._isUTC) {\n        res = model.clone();\n        diff = (isMoment(input) || isDate(input) ? input.valueOf() : createLocal(input).valueOf()) - res.valueOf();\n        // Use low-level api, because this fn is low-level api.\n        res._d.setTime(res._d.valueOf() + diff);\n        hooks.updateOffset(res, false);\n        return res;\n    } else {\n        return createLocal(input).local();\n    }\n}\n\nfunction getDateOffset (m) {\n    // On Firefox.24 Date#getTimezoneOffset returns a floating point.\n    // https://github.com/moment/moment/pull/1871\n    return -Math.round(m._d.getTimezoneOffset() / 15) * 15;\n}\n\n// HOOKS\n\n// This function will be called whenever a moment is mutated.\n// It is intended to keep the offset in sync with the timezone.\nhooks.updateOffset = function () {};\n\n// MOMENTS\n\n// keepLocalTime = true means only change the timezone, without\n// affecting the local hour. So 5:31:26 +0300 --[utcOffset(2, true)]-->\n// 5:31:26 +0200 It is possible that 5:31:26 doesn't exist with offset\n// +0200, so we adjust the time as needed, to be valid.\n//\n// Keeping the time actually adds/subtracts (one hour)\n// from the actual represented time. That is why we call updateOffset\n// a second time. In case it wants us to change the offset again\n// _changeInProgress == true case, then we have to adjust, because\n// there is no such time in the given timezone.\nexport function getSetOffset (input, keepLocalTime, keepMinutes) {\n    var offset = this._offset || 0,\n        localAdjust;\n    if (!this.isValid()) {\n        return input != null ? this : NaN;\n    }\n    if (input != null) {\n        if (typeof input === 'string') {\n            input = offsetFromString(matchShortOffset, input);\n            if (input === null) {\n                return this;\n            }\n        } else if (Math.abs(input) < 16 && !keepMinutes) {\n            input = input * 60;\n        }\n        if (!this._isUTC && keepLocalTime) {\n            localAdjust = getDateOffset(this);\n        }\n        this._offset = input;\n        this._isUTC = true;\n        if (localAdjust != null) {\n            this.add(localAdjust, 'm');\n        }\n        if (offset !== input) {\n            if (!keepLocalTime || this._changeInProgress) {\n                addSubtract(this, createDuration(input - offset, 'm'), 1, false);\n            } else if (!this._changeInProgress) {\n                this._changeInProgress = true;\n                hooks.updateOffset(this, true);\n                this._changeInProgress = null;\n            }\n        }\n        return this;\n    } else {\n        return this._isUTC ? offset : getDateOffset(this);\n    }\n}\n\nexport function getSetZone (input, keepLocalTime) {\n    if (input != null) {\n        if (typeof input !== 'string') {\n            input = -input;\n        }\n\n        this.utcOffset(input, keepLocalTime);\n\n        return this;\n    } else {\n        return -this.utcOffset();\n    }\n}\n\nexport function setOffsetToUTC (keepLocalTime) {\n    return this.utcOffset(0, keepLocalTime);\n}\n\nexport function setOffsetToLocal (keepLocalTime) {\n    if (this._isUTC) {\n        this.utcOffset(0, keepLocalTime);\n        this._isUTC = false;\n\n        if (keepLocalTime) {\n            this.subtract(getDateOffset(this), 'm');\n        }\n    }\n    return this;\n}\n\nexport function setOffsetToParsedOffset () {\n    if (this._tzm != null) {\n        this.utcOffset(this._tzm, false, true);\n    } else if (typeof this._i === 'string') {\n        var tZone = offsetFromString(matchOffset, this._i);\n        if (tZone != null) {\n            this.utcOffset(tZone);\n        }\n        else {\n            this.utcOffset(0, true);\n        }\n    }\n    return this;\n}\n\nexport function hasAlignedHourOffset (input) {\n    if (!this.isValid()) {\n        return false;\n    }\n    input = input ? createLocal(input).utcOffset() : 0;\n\n    return (this.utcOffset() - input) % 60 === 0;\n}\n\nexport function isDaylightSavingTime () {\n    return (\n        this.utcOffset() > this.clone().month(0).utcOffset() ||\n        this.utcOffset() > this.clone().month(5).utcOffset()\n    );\n}\n\nexport function isDaylightSavingTimeShifted () {\n    if (!isUndefined(this._isDSTShifted)) {\n        return this._isDSTShifted;\n    }\n\n    var c = {};\n\n    copyConfig(c, this);\n    c = prepareConfig(c);\n\n    if (c._a) {\n        var other = c._isUTC ? createUTC(c._a) : createLocal(c._a);\n        this._isDSTShifted = this.isValid() &&\n            compareArrays(c._a, other.toArray()) > 0;\n    } else {\n        this._isDSTShifted = false;\n    }\n\n    return this._isDSTShifted;\n}\n\nexport function isLocal () {\n    return this.isValid() ? !this._isUTC : false;\n}\n\nexport function isUtcOffset () {\n    return this.isValid() ? this._isUTC : false;\n}\n\nexport function isUtc () {\n    return this.isValid() ? this._isUTC && this._offset === 0 : false;\n}\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/lib/units/priorities.js",
    "content": "var priorities = {};\n\nexport function addUnitPriority(unit, priority) {\n    priorities[unit] = priority;\n}\n\nexport function getPrioritizedUnits(unitsObj) {\n    var units = [];\n    for (var u in unitsObj) {\n        units.push({unit: u, priority: priorities[u]});\n    }\n    units.sort(function (a, b) {\n        return a.priority - b.priority;\n    });\n    return units;\n}\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/lib/units/quarter.js",
    "content": "import { addFormatToken } from '../format/format';\nimport { addUnitAlias } from './aliases';\nimport { addUnitPriority } from './priorities';\nimport { addRegexToken, match1 } from '../parse/regex';\nimport { addParseToken } from '../parse/token';\nimport { MONTH } from './constants';\nimport toInt from '../utils/to-int';\n\n// FORMATTING\n\naddFormatToken('Q', 0, 'Qo', 'quarter');\n\n// ALIASES\n\naddUnitAlias('quarter', 'Q');\n\n// PRIORITY\n\naddUnitPriority('quarter', 7);\n\n// PARSING\n\naddRegexToken('Q', match1);\naddParseToken('Q', function (input, array) {\n    array[MONTH] = (toInt(input) - 1) * 3;\n});\n\n// MOMENTS\n\nexport function getSetQuarter (input) {\n    return input == null ? Math.ceil((this.month() + 1) / 3) : this.month((input - 1) * 3 + this.month() % 3);\n}\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/lib/units/second.js",
    "content": "import { makeGetSet } from '../moment/get-set';\nimport { addFormatToken } from '../format/format';\nimport { addUnitAlias } from './aliases';\nimport { addUnitPriority } from './priorities';\nimport { addRegexToken, match1to2, match2 } from '../parse/regex';\nimport { addParseToken } from '../parse/token';\nimport { SECOND } from './constants';\n\n// FORMATTING\n\naddFormatToken('s', ['ss', 2], 0, 'second');\n\n// ALIASES\n\naddUnitAlias('second', 's');\n\n// PRIORITY\n\naddUnitPriority('second', 15);\n\n// PARSING\n\naddRegexToken('s',  match1to2);\naddRegexToken('ss', match1to2, match2);\naddParseToken(['s', 'ss'], SECOND);\n\n// MOMENTS\n\nexport var getSetSecond = makeGetSet('Seconds', false);\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/lib/units/timestamp.js",
    "content": "import { addFormatToken } from '../format/format';\nimport { addRegexToken, matchTimestamp, matchSigned } from '../parse/regex';\nimport { addParseToken } from '../parse/token';\nimport toInt from '../utils/to-int';\n\n// FORMATTING\n\naddFormatToken('X', 0, 0, 'unix');\naddFormatToken('x', 0, 0, 'valueOf');\n\n// PARSING\n\naddRegexToken('x', matchSigned);\naddRegexToken('X', matchTimestamp);\naddParseToken('X', function (input, array, config) {\n    config._d = new Date(parseFloat(input, 10) * 1000);\n});\naddParseToken('x', function (input, array, config) {\n    config._d = new Date(toInt(input));\n});\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/lib/units/timezone.js",
    "content": "import { addFormatToken } from '../format/format';\n\n// FORMATTING\n\naddFormatToken('z',  0, 0, 'zoneAbbr');\naddFormatToken('zz', 0, 0, 'zoneName');\n\n// MOMENTS\n\nexport function getZoneAbbr () {\n    return this._isUTC ? 'UTC' : '';\n}\n\nexport function getZoneName () {\n    return this._isUTC ? 'Coordinated Universal Time' : '';\n}\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/lib/units/units.js",
    "content": "// Side effect imports\nimport './day-of-month';\nimport './day-of-week';\nimport './day-of-year';\nimport './hour';\nimport './millisecond';\nimport './minute';\nimport './month';\nimport './offset';\nimport './quarter';\nimport './second';\nimport './timestamp';\nimport './timezone';\nimport './week-year';\nimport './week';\nimport './year';\n\nimport { normalizeUnits } from './aliases';\n\nexport { normalizeUnits };\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/lib/units/week-calendar-utils.js",
    "content": "import { daysInYear } from './year';\nimport { createLocal } from '../create/local';\nimport { createUTCDate } from '../create/date-from-array';\n\n// start-of-first-week - start-of-year\nfunction firstWeekOffset(year, dow, doy) {\n    var // first-week day -- which january is always in the first week (4 for iso, 1 for other)\n        fwd = 7 + dow - doy,\n        // first-week day local weekday -- which local weekday is fwd\n        fwdlw = (7 + createUTCDate(year, 0, fwd).getUTCDay() - dow) % 7;\n\n    return -fwdlw + fwd - 1;\n}\n\n// https://en.wikipedia.org/wiki/ISO_week_date#Calculating_a_date_given_the_year.2C_week_number_and_weekday\nexport function dayOfYearFromWeeks(year, week, weekday, dow, doy) {\n    var localWeekday = (7 + weekday - dow) % 7,\n        weekOffset = firstWeekOffset(year, dow, doy),\n        dayOfYear = 1 + 7 * (week - 1) + localWeekday + weekOffset,\n        resYear, resDayOfYear;\n\n    if (dayOfYear <= 0) {\n        resYear = year - 1;\n        resDayOfYear = daysInYear(resYear) + dayOfYear;\n    } else if (dayOfYear > daysInYear(year)) {\n        resYear = year + 1;\n        resDayOfYear = dayOfYear - daysInYear(year);\n    } else {\n        resYear = year;\n        resDayOfYear = dayOfYear;\n    }\n\n    return {\n        year: resYear,\n        dayOfYear: resDayOfYear\n    };\n}\n\nexport function weekOfYear(mom, dow, doy) {\n    var weekOffset = firstWeekOffset(mom.year(), dow, doy),\n        week = Math.floor((mom.dayOfYear() - weekOffset - 1) / 7) + 1,\n        resWeek, resYear;\n\n    if (week < 1) {\n        resYear = mom.year() - 1;\n        resWeek = week + weeksInYear(resYear, dow, doy);\n    } else if (week > weeksInYear(mom.year(), dow, doy)) {\n        resWeek = week - weeksInYear(mom.year(), dow, doy);\n        resYear = mom.year() + 1;\n    } else {\n        resYear = mom.year();\n        resWeek = week;\n    }\n\n    return {\n        week: resWeek,\n        year: resYear\n    };\n}\n\nexport function weeksInYear(year, dow, doy) {\n    var weekOffset = firstWeekOffset(year, dow, doy),\n        weekOffsetNext = firstWeekOffset(year + 1, dow, doy);\n    return (daysInYear(year) - weekOffset + weekOffsetNext) / 7;\n}\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/lib/units/week-year.js",
    "content": "import { addFormatToken } from '../format/format';\nimport { addUnitAlias } from './aliases';\nimport { addUnitPriority } from './priorities';\nimport { addRegexToken, match1to2, match1to4, match1to6, match2, match4, match6, matchSigned } from '../parse/regex';\nimport { addWeekParseToken } from '../parse/token';\nimport { weekOfYear, weeksInYear, dayOfYearFromWeeks } from './week-calendar-utils';\nimport toInt from '../utils/to-int';\nimport { hooks } from '../utils/hooks';\nimport { createLocal } from '../create/local';\nimport { createUTCDate } from '../create/date-from-array';\n\n// FORMATTING\n\naddFormatToken(0, ['gg', 2], 0, function () {\n    return this.weekYear() % 100;\n});\n\naddFormatToken(0, ['GG', 2], 0, function () {\n    return this.isoWeekYear() % 100;\n});\n\nfunction addWeekYearFormatToken (token, getter) {\n    addFormatToken(0, [token, token.length], 0, getter);\n}\n\naddWeekYearFormatToken('gggg',     'weekYear');\naddWeekYearFormatToken('ggggg',    'weekYear');\naddWeekYearFormatToken('GGGG',  'isoWeekYear');\naddWeekYearFormatToken('GGGGG', 'isoWeekYear');\n\n// ALIASES\n\naddUnitAlias('weekYear', 'gg');\naddUnitAlias('isoWeekYear', 'GG');\n\n// PRIORITY\n\naddUnitPriority('weekYear', 1);\naddUnitPriority('isoWeekYear', 1);\n\n\n// PARSING\n\naddRegexToken('G',      matchSigned);\naddRegexToken('g',      matchSigned);\naddRegexToken('GG',     match1to2, match2);\naddRegexToken('gg',     match1to2, match2);\naddRegexToken('GGGG',   match1to4, match4);\naddRegexToken('gggg',   match1to4, match4);\naddRegexToken('GGGGG',  match1to6, match6);\naddRegexToken('ggggg',  match1to6, match6);\n\naddWeekParseToken(['gggg', 'ggggg', 'GGGG', 'GGGGG'], function (input, week, config, token) {\n    week[token.substr(0, 2)] = toInt(input);\n});\n\naddWeekParseToken(['gg', 'GG'], function (input, week, config, token) {\n    week[token] = hooks.parseTwoDigitYear(input);\n});\n\n// MOMENTS\n\nexport function getSetWeekYear (input) {\n    return getSetWeekYearHelper.call(this,\n            input,\n            this.week(),\n            this.weekday(),\n            this.localeData()._week.dow,\n            this.localeData()._week.doy);\n}\n\nexport function getSetISOWeekYear (input) {\n    return getSetWeekYearHelper.call(this,\n            input, this.isoWeek(), this.isoWeekday(), 1, 4);\n}\n\nexport function getISOWeeksInYear () {\n    return weeksInYear(this.year(), 1, 4);\n}\n\nexport function getWeeksInYear () {\n    var weekInfo = this.localeData()._week;\n    return weeksInYear(this.year(), weekInfo.dow, weekInfo.doy);\n}\n\nfunction getSetWeekYearHelper(input, week, weekday, dow, doy) {\n    var weeksTarget;\n    if (input == null) {\n        return weekOfYear(this, dow, doy).year;\n    } else {\n        weeksTarget = weeksInYear(input, dow, doy);\n        if (week > weeksTarget) {\n            week = weeksTarget;\n        }\n        return setWeekAll.call(this, input, week, weekday, dow, doy);\n    }\n}\n\nfunction setWeekAll(weekYear, week, weekday, dow, doy) {\n    var dayOfYearData = dayOfYearFromWeeks(weekYear, week, weekday, dow, doy),\n        date = createUTCDate(dayOfYearData.year, 0, dayOfYearData.dayOfYear);\n\n    this.year(date.getUTCFullYear());\n    this.month(date.getUTCMonth());\n    this.date(date.getUTCDate());\n    return this;\n}\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/lib/units/week.js",
    "content": "import { addFormatToken } from '../format/format';\nimport { addUnitAlias } from './aliases';\nimport { addUnitPriority } from './priorities';\nimport { addRegexToken, match1to2, match2 } from '../parse/regex';\nimport { addWeekParseToken } from '../parse/token';\nimport toInt from '../utils/to-int';\nimport { createLocal } from '../create/local';\nimport { weekOfYear } from './week-calendar-utils';\n\n// FORMATTING\n\naddFormatToken('w', ['ww', 2], 'wo', 'week');\naddFormatToken('W', ['WW', 2], 'Wo', 'isoWeek');\n\n// ALIASES\n\naddUnitAlias('week', 'w');\naddUnitAlias('isoWeek', 'W');\n\n// PRIORITIES\n\naddUnitPriority('week', 5);\naddUnitPriority('isoWeek', 5);\n\n// PARSING\n\naddRegexToken('w',  match1to2);\naddRegexToken('ww', match1to2, match2);\naddRegexToken('W',  match1to2);\naddRegexToken('WW', match1to2, match2);\n\naddWeekParseToken(['w', 'ww', 'W', 'WW'], function (input, week, config, token) {\n    week[token.substr(0, 1)] = toInt(input);\n});\n\n// HELPERS\n\n// LOCALES\n\nexport function localeWeek (mom) {\n    return weekOfYear(mom, this._week.dow, this._week.doy).week;\n}\n\nexport var defaultLocaleWeek = {\n    dow : 0, // Sunday is the first day of the week.\n    doy : 6  // The week that contains Jan 1st is the first week of the year.\n};\n\nexport function localeFirstDayOfWeek () {\n    return this._week.dow;\n}\n\nexport function localeFirstDayOfYear () {\n    return this._week.doy;\n}\n\n// MOMENTS\n\nexport function getSetWeek (input) {\n    var week = this.localeData().week(this);\n    return input == null ? week : this.add((input - week) * 7, 'd');\n}\n\nexport function getSetISOWeek (input) {\n    var week = weekOfYear(this, 1, 4).week;\n    return input == null ? week : this.add((input - week) * 7, 'd');\n}\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/lib/units/year.js",
    "content": "import { makeGetSet } from '../moment/get-set';\nimport { addFormatToken } from '../format/format';\nimport { addUnitAlias } from './aliases';\nimport { addUnitPriority } from './priorities';\nimport { addRegexToken, match1to2, match1to4, match1to6, match2, match4, match6, matchSigned } from '../parse/regex';\nimport { addParseToken } from '../parse/token';\nimport { hooks } from '../utils/hooks';\nimport { YEAR } from './constants';\nimport toInt from '../utils/to-int';\n\n// FORMATTING\n\naddFormatToken('Y', 0, 0, function () {\n    var y = this.year();\n    return y <= 9999 ? '' + y : '+' + y;\n});\n\naddFormatToken(0, ['YY', 2], 0, function () {\n    return this.year() % 100;\n});\n\naddFormatToken(0, ['YYYY',   4],       0, 'year');\naddFormatToken(0, ['YYYYY',  5],       0, 'year');\naddFormatToken(0, ['YYYYYY', 6, true], 0, 'year');\n\n// ALIASES\n\naddUnitAlias('year', 'y');\n\n// PRIORITIES\n\naddUnitPriority('year', 1);\n\n// PARSING\n\naddRegexToken('Y',      matchSigned);\naddRegexToken('YY',     match1to2, match2);\naddRegexToken('YYYY',   match1to4, match4);\naddRegexToken('YYYYY',  match1to6, match6);\naddRegexToken('YYYYYY', match1to6, match6);\n\naddParseToken(['YYYYY', 'YYYYYY'], YEAR);\naddParseToken('YYYY', function (input, array) {\n    array[YEAR] = input.length === 2 ? hooks.parseTwoDigitYear(input) : toInt(input);\n});\naddParseToken('YY', function (input, array) {\n    array[YEAR] = hooks.parseTwoDigitYear(input);\n});\naddParseToken('Y', function (input, array) {\n    array[YEAR] = parseInt(input, 10);\n});\n\n// HELPERS\n\nexport function daysInYear(year) {\n    return isLeapYear(year) ? 366 : 365;\n}\n\nfunction isLeapYear(year) {\n    return (year % 4 === 0 && year % 100 !== 0) || year % 400 === 0;\n}\n\n// HOOKS\n\nhooks.parseTwoDigitYear = function (input) {\n    return toInt(input) + (toInt(input) > 68 ? 1900 : 2000);\n};\n\n// MOMENTS\n\nexport var getSetYear = makeGetSet('FullYear', true);\n\nexport function getIsLeapYear () {\n    return isLeapYear(this.year());\n}\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/lib/utils/abs-ceil.js",
    "content": "export default function absCeil (number) {\n    if (number < 0) {\n        return Math.floor(number);\n    } else {\n        return Math.ceil(number);\n    }\n}\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/lib/utils/abs-floor.js",
    "content": "export default function absFloor (number) {\n    if (number < 0) {\n        // -0 -> 0\n        return Math.ceil(number) || 0;\n    } else {\n        return Math.floor(number);\n    }\n}\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/lib/utils/abs-round.js",
    "content": "export default function absRound (number) {\n    if (number < 0) {\n        return Math.round(-1 * number) * -1;\n    } else {\n        return Math.round(number);\n    }\n}\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/lib/utils/compare-arrays.js",
    "content": "import toInt from './to-int';\n\n// compare two arrays, return the number of differences\nexport default function compareArrays(array1, array2, dontConvert) {\n    var len = Math.min(array1.length, array2.length),\n        lengthDiff = Math.abs(array1.length - array2.length),\n        diffs = 0,\n        i;\n    for (i = 0; i < len; i++) {\n        if ((dontConvert && array1[i] !== array2[i]) ||\n            (!dontConvert && toInt(array1[i]) !== toInt(array2[i]))) {\n            diffs++;\n        }\n    }\n    return diffs + lengthDiff;\n}\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/lib/utils/defaults.js",
    "content": "// Pick the first defined of two or three arguments.\nexport default function defaults(a, b, c) {\n    if (a != null) {\n        return a;\n    }\n    if (b != null) {\n        return b;\n    }\n    return c;\n}\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/lib/utils/deprecate.js",
    "content": "import extend from './extend';\nimport { hooks } from './hooks';\nimport isUndefined from './is-undefined';\n\nfunction warn(msg) {\n    if (hooks.suppressDeprecationWarnings === false &&\n            (typeof console !==  'undefined') && console.warn) {\n        console.warn('Deprecation warning: ' + msg);\n    }\n}\n\nexport function deprecate(msg, fn) {\n    var firstTime = true;\n\n    return extend(function () {\n        if (hooks.deprecationHandler != null) {\n            hooks.deprecationHandler(null, msg);\n        }\n        if (firstTime) {\n            var args = [];\n            var arg;\n            for (var i = 0; i < arguments.length; i++) {\n                arg = '';\n                if (typeof arguments[i] === 'object') {\n                    arg += '\\n[' + i + '] ';\n                    for (var key in arguments[0]) {\n                        arg += key + ': ' + arguments[0][key] + ', ';\n                    }\n                    arg = arg.slice(0, -2); // Remove trailing comma and space\n                } else {\n                    arg = arguments[i];\n                }\n                args.push(arg);\n            }\n            warn(msg + '\\nArguments: ' + Array.prototype.slice.call(args).join('') + '\\n' + (new Error()).stack);\n            firstTime = false;\n        }\n        return fn.apply(this, arguments);\n    }, fn);\n}\n\nvar deprecations = {};\n\nexport function deprecateSimple(name, msg) {\n    if (hooks.deprecationHandler != null) {\n        hooks.deprecationHandler(name, msg);\n    }\n    if (!deprecations[name]) {\n        warn(msg);\n        deprecations[name] = true;\n    }\n}\n\nhooks.suppressDeprecationWarnings = false;\nhooks.deprecationHandler = null;\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/lib/utils/extend.js",
    "content": "import hasOwnProp from './has-own-prop';\n\nexport default function extend(a, b) {\n    for (var i in b) {\n        if (hasOwnProp(b, i)) {\n            a[i] = b[i];\n        }\n    }\n\n    if (hasOwnProp(b, 'toString')) {\n        a.toString = b.toString;\n    }\n\n    if (hasOwnProp(b, 'valueOf')) {\n        a.valueOf = b.valueOf;\n    }\n\n    return a;\n}\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/lib/utils/has-own-prop.js",
    "content": "export default function hasOwnProp(a, b) {\n    return Object.prototype.hasOwnProperty.call(a, b);\n}\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/lib/utils/hooks.js",
    "content": "export { hooks, setHookCallback };\n\nvar hookCallback;\n\nfunction hooks () {\n    return hookCallback.apply(null, arguments);\n}\n\n// This is done to register the method called with moment()\n// without creating circular dependencies.\nfunction setHookCallback (callback) {\n    hookCallback = callback;\n}\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/lib/utils/index-of.js",
    "content": "var indexOf;\n\nif (Array.prototype.indexOf) {\n    indexOf = Array.prototype.indexOf;\n} else {\n    indexOf = function (o) {\n        // I know\n        var i;\n        for (i = 0; i < this.length; ++i) {\n            if (this[i] === o) {\n                return i;\n            }\n        }\n        return -1;\n    };\n}\n\nexport { indexOf as default };\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/lib/utils/is-array.js",
    "content": "export default function isArray(input) {\n    return input instanceof Array || Object.prototype.toString.call(input) === '[object Array]';\n}\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/lib/utils/is-date.js",
    "content": "export default function isDate(input) {\n    return input instanceof Date || Object.prototype.toString.call(input) === '[object Date]';\n}\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/lib/utils/is-function.js",
    "content": "export default function isFunction(input) {\n    return input instanceof Function || Object.prototype.toString.call(input) === '[object Function]';\n}\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/lib/utils/is-number.js",
    "content": "export default function isNumber(input) {\n    return typeof input === 'number' || Object.prototype.toString.call(input) === '[object Number]';\n}\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/lib/utils/is-object-empty.js",
    "content": "export default function isObjectEmpty(obj) {\n    var k;\n    for (k in obj) {\n        // even if its not own property I'd still call it non-empty\n        return false;\n    }\n    return true;\n}\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/lib/utils/is-object.js",
    "content": "export default function isObject(input) {\n    // IE8 will treat undefined and null as object if it wasn't for\n    // input != null\n    return input != null && Object.prototype.toString.call(input) === '[object Object]';\n}\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/lib/utils/is-undefined.js",
    "content": "export default function isUndefined(input) {\n    return input === void 0;\n}\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/lib/utils/keys.js",
    "content": "import hasOwnProp from './has-own-prop';\n\nvar keys;\n\nif (Object.keys) {\n    keys = Object.keys;\n} else {\n    keys = function (obj) {\n        var i, res = [];\n        for (i in obj) {\n            if (hasOwnProp(obj, i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    };\n}\n\nexport { keys as default };\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/lib/utils/map.js",
    "content": "export default function map(arr, fn) {\n    var res = [], i;\n    for (i = 0; i < arr.length; ++i) {\n        res.push(fn(arr[i], i));\n    }\n    return res;\n}\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/lib/utils/some.js",
    "content": "var some;\nif (Array.prototype.some) {\n    some = Array.prototype.some;\n} else {\n    some = function (fun) {\n        var t = Object(this);\n        var len = t.length >>> 0;\n\n        for (var i = 0; i < len; i++) {\n            if (i in t && fun.call(this, t[i], i, t)) {\n                return true;\n            }\n        }\n\n        return false;\n    };\n}\n\nexport { some as default };\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/lib/utils/to-int.js",
    "content": "import absFloor from './abs-floor';\n\nexport default function toInt(argumentForCoercion) {\n    var coercedNumber = +argumentForCoercion,\n        value = 0;\n\n    if (coercedNumber !== 0 && isFinite(coercedNumber)) {\n        value = absFloor(coercedNumber);\n    }\n\n    return value;\n}\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/lib/utils/zero-fill.js",
    "content": "export default function zeroFill(number, targetLength, forceSign) {\n    var absNumber = '' + Math.abs(number),\n        zerosToFill = targetLength - absNumber.length,\n        sign = number >= 0;\n    return (sign ? (forceSign ? '+' : '') : '-') +\n        Math.pow(10, Math.max(0, zerosToFill)).toString().substr(1) + absNumber;\n}\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/locale/af.js",
    "content": "//! moment.js locale configuration\n//! locale : Afrikaans [af]\n//! author : Werner Mollentze : https://github.com/wernerm\n\nimport moment from '../moment';\n\nexport default moment.defineLocale('af', {\n    months : 'Januarie_Februarie_Maart_April_Mei_Junie_Julie_Augustus_September_Oktober_November_Desember'.split('_'),\n    monthsShort : 'Jan_Feb_Mrt_Apr_Mei_Jun_Jul_Aug_Sep_Okt_Nov_Des'.split('_'),\n    weekdays : 'Sondag_Maandag_Dinsdag_Woensdag_Donderdag_Vrydag_Saterdag'.split('_'),\n    weekdaysShort : 'Son_Maa_Din_Woe_Don_Vry_Sat'.split('_'),\n    weekdaysMin : 'So_Ma_Di_Wo_Do_Vr_Sa'.split('_'),\n    meridiemParse: /vm|nm/i,\n    isPM : function (input) {\n        return /^nm$/i.test(input);\n    },\n    meridiem : function (hours, minutes, isLower) {\n        if (hours < 12) {\n            return isLower ? 'vm' : 'VM';\n        } else {\n            return isLower ? 'nm' : 'NM';\n        }\n    },\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY HH:mm',\n        LLLL : 'dddd, D MMMM YYYY HH:mm'\n    },\n    calendar : {\n        sameDay : '[Vandag om] LT',\n        nextDay : '[Môre om] LT',\n        nextWeek : 'dddd [om] LT',\n        lastDay : '[Gister om] LT',\n        lastWeek : '[Laas] dddd [om] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'oor %s',\n        past : '%s gelede',\n        s : '\\'n paar sekondes',\n        m : '\\'n minuut',\n        mm : '%d minute',\n        h : '\\'n uur',\n        hh : '%d ure',\n        d : '\\'n dag',\n        dd : '%d dae',\n        M : '\\'n maand',\n        MM : '%d maande',\n        y : '\\'n jaar',\n        yy : '%d jaar'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}(ste|de)/,\n    ordinal : function (number) {\n        return number + ((number === 1 || number === 8 || number >= 20) ? 'ste' : 'de'); // Thanks to Joris Röling : https://github.com/jjupiter\n    },\n    week : {\n        dow : 1, // Maandag is die eerste dag van die week.\n        doy : 4  // Die week wat die 4de Januarie bevat is die eerste week van die jaar.\n    }\n});\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/locale/ar-dz.js",
    "content": "//! moment.js locale configuration\n//! locale : Arabic (Algeria) [ar-dz]\n//! author : Noureddine LOUAHEDJ : https://github.com/noureddineme\n\nimport moment from '../moment';\n\nexport default moment.defineLocale('ar-dz', {\n    months : 'جانفي_فيفري_مارس_أفريل_ماي_جوان_جويلية_أوت_سبتمبر_أكتوبر_نوفمبر_ديسمبر'.split('_'),\n    monthsShort : 'جانفي_فيفري_مارس_أفريل_ماي_جوان_جويلية_أوت_سبتمبر_أكتوبر_نوفمبر_ديسمبر'.split('_'),\n    weekdays : 'الأحد_الإثنين_الثلاثاء_الأربعاء_الخميس_الجمعة_السبت'.split('_'),\n    weekdaysShort : 'احد_اثنين_ثلاثاء_اربعاء_خميس_جمعة_سبت'.split('_'),\n    weekdaysMin : 'أح_إث_ثلا_أر_خم_جم_سب'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY HH:mm',\n        LLLL : 'dddd D MMMM YYYY HH:mm'\n    },\n    calendar : {\n        sameDay: '[اليوم على الساعة] LT',\n        nextDay: '[غدا على الساعة] LT',\n        nextWeek: 'dddd [على الساعة] LT',\n        lastDay: '[أمس على الساعة] LT',\n        lastWeek: 'dddd [على الساعة] LT',\n        sameElse: 'L'\n    },\n    relativeTime : {\n        future : 'في %s',\n        past : 'منذ %s',\n        s : 'ثوان',\n        m : 'دقيقة',\n        mm : '%d دقائق',\n        h : 'ساعة',\n        hh : '%d ساعات',\n        d : 'يوم',\n        dd : '%d أيام',\n        M : 'شهر',\n        MM : '%d أشهر',\n        y : 'سنة',\n        yy : '%d سنوات'\n    },\n    week : {\n        dow : 0, // Sunday is the first day of the week.\n        doy : 4  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/locale/ar-kw.js",
    "content": "//! moment.js locale configuration\n//! locale : Arabic (Kuwait) [ar-kw]\n//! author : Nusret Parlak: https://github.com/nusretparlak\n\nimport moment from '../moment';\n\nexport default moment.defineLocale('ar-kw', {\n    months : 'يناير_فبراير_مارس_أبريل_ماي_يونيو_يوليوز_غشت_شتنبر_أكتوبر_نونبر_دجنبر'.split('_'),\n    monthsShort : 'يناير_فبراير_مارس_أبريل_ماي_يونيو_يوليوز_غشت_شتنبر_أكتوبر_نونبر_دجنبر'.split('_'),\n    weekdays : 'الأحد_الإتنين_الثلاثاء_الأربعاء_الخميس_الجمعة_السبت'.split('_'),\n    weekdaysShort : 'احد_اتنين_ثلاثاء_اربعاء_خميس_جمعة_سبت'.split('_'),\n    weekdaysMin : 'ح_ن_ث_ر_خ_ج_س'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY HH:mm',\n        LLLL : 'dddd D MMMM YYYY HH:mm'\n    },\n    calendar : {\n        sameDay: '[اليوم على الساعة] LT',\n        nextDay: '[غدا على الساعة] LT',\n        nextWeek: 'dddd [على الساعة] LT',\n        lastDay: '[أمس على الساعة] LT',\n        lastWeek: 'dddd [على الساعة] LT',\n        sameElse: 'L'\n    },\n    relativeTime : {\n        future : 'في %s',\n        past : 'منذ %s',\n        s : 'ثوان',\n        m : 'دقيقة',\n        mm : '%d دقائق',\n        h : 'ساعة',\n        hh : '%d ساعات',\n        d : 'يوم',\n        dd : '%d أيام',\n        M : 'شهر',\n        MM : '%d أشهر',\n        y : 'سنة',\n        yy : '%d سنوات'\n    },\n    week : {\n        dow : 0, // Sunday is the first day of the week.\n        doy : 12  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/locale/ar-ly.js",
    "content": "//! moment.js locale configuration\n//! locale : Arabic (Lybia) [ar-ly]\n//! author : Ali Hmer: https://github.com/kikoanis\n\nimport moment from '../moment';\n\nvar symbolMap = {\n    '1': '1',\n    '2': '2',\n    '3': '3',\n    '4': '4',\n    '5': '5',\n    '6': '6',\n    '7': '7',\n    '8': '8',\n    '9': '9',\n    '0': '0'\n}, pluralForm = function (n) {\n    return n === 0 ? 0 : n === 1 ? 1 : n === 2 ? 2 : n % 100 >= 3 && n % 100 <= 10 ? 3 : n % 100 >= 11 ? 4 : 5;\n}, plurals = {\n    s : ['أقل من ثانية', 'ثانية واحدة', ['ثانيتان', 'ثانيتين'], '%d ثوان', '%d ثانية', '%d ثانية'],\n    m : ['أقل من دقيقة', 'دقيقة واحدة', ['دقيقتان', 'دقيقتين'], '%d دقائق', '%d دقيقة', '%d دقيقة'],\n    h : ['أقل من ساعة', 'ساعة واحدة', ['ساعتان', 'ساعتين'], '%d ساعات', '%d ساعة', '%d ساعة'],\n    d : ['أقل من يوم', 'يوم واحد', ['يومان', 'يومين'], '%d أيام', '%d يومًا', '%d يوم'],\n    M : ['أقل من شهر', 'شهر واحد', ['شهران', 'شهرين'], '%d أشهر', '%d شهرا', '%d شهر'],\n    y : ['أقل من عام', 'عام واحد', ['عامان', 'عامين'], '%d أعوام', '%d عامًا', '%d عام']\n}, pluralize = function (u) {\n    return function (number, withoutSuffix, string, isFuture) {\n        var f = pluralForm(number),\n            str = plurals[u][pluralForm(number)];\n        if (f === 2) {\n            str = str[withoutSuffix ? 0 : 1];\n        }\n        return str.replace(/%d/i, number);\n    };\n}, months = [\n    'يناير',\n    'فبراير',\n    'مارس',\n    'أبريل',\n    'مايو',\n    'يونيو',\n    'يوليو',\n    'أغسطس',\n    'سبتمبر',\n    'أكتوبر',\n    'نوفمبر',\n    'ديسمبر'\n];\n\nexport default moment.defineLocale('ar-ly', {\n    months : months,\n    monthsShort : months,\n    weekdays : 'الأحد_الإثنين_الثلاثاء_الأربعاء_الخميس_الجمعة_السبت'.split('_'),\n    weekdaysShort : 'أحد_إثنين_ثلاثاء_أربعاء_خميس_جمعة_سبت'.split('_'),\n    weekdaysMin : 'ح_ن_ث_ر_خ_ج_س'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'D/\\u200FM/\\u200FYYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY HH:mm',\n        LLLL : 'dddd D MMMM YYYY HH:mm'\n    },\n    meridiemParse: /ص|م/,\n    isPM : function (input) {\n        return 'م' === input;\n    },\n    meridiem : function (hour, minute, isLower) {\n        if (hour < 12) {\n            return 'ص';\n        } else {\n            return 'م';\n        }\n    },\n    calendar : {\n        sameDay: '[اليوم عند الساعة] LT',\n        nextDay: '[غدًا عند الساعة] LT',\n        nextWeek: 'dddd [عند الساعة] LT',\n        lastDay: '[أمس عند الساعة] LT',\n        lastWeek: 'dddd [عند الساعة] LT',\n        sameElse: 'L'\n    },\n    relativeTime : {\n        future : 'بعد %s',\n        past : 'منذ %s',\n        s : pluralize('s'),\n        m : pluralize('m'),\n        mm : pluralize('m'),\n        h : pluralize('h'),\n        hh : pluralize('h'),\n        d : pluralize('d'),\n        dd : pluralize('d'),\n        M : pluralize('M'),\n        MM : pluralize('M'),\n        y : pluralize('y'),\n        yy : pluralize('y')\n    },\n    preparse: function (string) {\n        return string.replace(/\\u200f/g, '').replace(/،/g, ',');\n    },\n    postformat: function (string) {\n        return string.replace(/\\d/g, function (match) {\n            return symbolMap[match];\n        }).replace(/,/g, '،');\n    },\n    week : {\n        dow : 6, // Saturday is the first day of the week.\n        doy : 12  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/locale/ar-ma.js",
    "content": "//! moment.js locale configuration\n//! locale : Arabic (Morocco) [ar-ma]\n//! author : ElFadili Yassine : https://github.com/ElFadiliY\n//! author : Abdel Said : https://github.com/abdelsaid\n\nimport moment from '../moment';\n\nexport default moment.defineLocale('ar-ma', {\n    months : 'يناير_فبراير_مارس_أبريل_ماي_يونيو_يوليوز_غشت_شتنبر_أكتوبر_نونبر_دجنبر'.split('_'),\n    monthsShort : 'يناير_فبراير_مارس_أبريل_ماي_يونيو_يوليوز_غشت_شتنبر_أكتوبر_نونبر_دجنبر'.split('_'),\n    weekdays : 'الأحد_الإتنين_الثلاثاء_الأربعاء_الخميس_الجمعة_السبت'.split('_'),\n    weekdaysShort : 'احد_اتنين_ثلاثاء_اربعاء_خميس_جمعة_سبت'.split('_'),\n    weekdaysMin : 'ح_ن_ث_ر_خ_ج_س'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY HH:mm',\n        LLLL : 'dddd D MMMM YYYY HH:mm'\n    },\n    calendar : {\n        sameDay: '[اليوم على الساعة] LT',\n        nextDay: '[غدا على الساعة] LT',\n        nextWeek: 'dddd [على الساعة] LT',\n        lastDay: '[أمس على الساعة] LT',\n        lastWeek: 'dddd [على الساعة] LT',\n        sameElse: 'L'\n    },\n    relativeTime : {\n        future : 'في %s',\n        past : 'منذ %s',\n        s : 'ثوان',\n        m : 'دقيقة',\n        mm : '%d دقائق',\n        h : 'ساعة',\n        hh : '%d ساعات',\n        d : 'يوم',\n        dd : '%d أيام',\n        M : 'شهر',\n        MM : '%d أشهر',\n        y : 'سنة',\n        yy : '%d سنوات'\n    },\n    week : {\n        dow : 6, // Saturday is the first day of the week.\n        doy : 12  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/locale/ar-sa.js",
    "content": "//! moment.js locale configuration\n//! locale : Arabic (Saudi Arabia) [ar-sa]\n//! author : Suhail Alkowaileet : https://github.com/xsoh\n\nimport moment from '../moment';\n\nvar symbolMap = {\n    '1': '١',\n    '2': '٢',\n    '3': '٣',\n    '4': '٤',\n    '5': '٥',\n    '6': '٦',\n    '7': '٧',\n    '8': '٨',\n    '9': '٩',\n    '0': '٠'\n}, numberMap = {\n    '١': '1',\n    '٢': '2',\n    '٣': '3',\n    '٤': '4',\n    '٥': '5',\n    '٦': '6',\n    '٧': '7',\n    '٨': '8',\n    '٩': '9',\n    '٠': '0'\n};\n\nexport default moment.defineLocale('ar-sa', {\n    months : 'يناير_فبراير_مارس_أبريل_مايو_يونيو_يوليو_أغسطس_سبتمبر_أكتوبر_نوفمبر_ديسمبر'.split('_'),\n    monthsShort : 'يناير_فبراير_مارس_أبريل_مايو_يونيو_يوليو_أغسطس_سبتمبر_أكتوبر_نوفمبر_ديسمبر'.split('_'),\n    weekdays : 'الأحد_الإثنين_الثلاثاء_الأربعاء_الخميس_الجمعة_السبت'.split('_'),\n    weekdaysShort : 'أحد_إثنين_ثلاثاء_أربعاء_خميس_جمعة_سبت'.split('_'),\n    weekdaysMin : 'ح_ن_ث_ر_خ_ج_س'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY HH:mm',\n        LLLL : 'dddd D MMMM YYYY HH:mm'\n    },\n    meridiemParse: /ص|م/,\n    isPM : function (input) {\n        return 'م' === input;\n    },\n    meridiem : function (hour, minute, isLower) {\n        if (hour < 12) {\n            return 'ص';\n        } else {\n            return 'م';\n        }\n    },\n    calendar : {\n        sameDay: '[اليوم على الساعة] LT',\n        nextDay: '[غدا على الساعة] LT',\n        nextWeek: 'dddd [على الساعة] LT',\n        lastDay: '[أمس على الساعة] LT',\n        lastWeek: 'dddd [على الساعة] LT',\n        sameElse: 'L'\n    },\n    relativeTime : {\n        future : 'في %s',\n        past : 'منذ %s',\n        s : 'ثوان',\n        m : 'دقيقة',\n        mm : '%d دقائق',\n        h : 'ساعة',\n        hh : '%d ساعات',\n        d : 'يوم',\n        dd : '%d أيام',\n        M : 'شهر',\n        MM : '%d أشهر',\n        y : 'سنة',\n        yy : '%d سنوات'\n    },\n    preparse: function (string) {\n        return string.replace(/[١٢٣٤٥٦٧٨٩٠]/g, function (match) {\n            return numberMap[match];\n        }).replace(/،/g, ',');\n    },\n    postformat: function (string) {\n        return string.replace(/\\d/g, function (match) {\n            return symbolMap[match];\n        }).replace(/,/g, '،');\n    },\n    week : {\n        dow : 0, // Sunday is the first day of the week.\n        doy : 6  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/locale/ar-tn.js",
    "content": "//! moment.js locale configuration\n//! locale  :  Arabic (Tunisia) [ar-tn]\n//! author : Nader Toukabri : https://github.com/naderio\n\nimport moment from '../moment';\n\nexport default moment.defineLocale('ar-tn', {\n    months: 'جانفي_فيفري_مارس_أفريل_ماي_جوان_جويلية_أوت_سبتمبر_أكتوبر_نوفمبر_ديسمبر'.split('_'),\n    monthsShort: 'جانفي_فيفري_مارس_أفريل_ماي_جوان_جويلية_أوت_سبتمبر_أكتوبر_نوفمبر_ديسمبر'.split('_'),\n    weekdays: 'الأحد_الإثنين_الثلاثاء_الأربعاء_الخميس_الجمعة_السبت'.split('_'),\n    weekdaysShort: 'أحد_إثنين_ثلاثاء_أربعاء_خميس_جمعة_سبت'.split('_'),\n    weekdaysMin: 'ح_ن_ث_ر_خ_ج_س'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat: {\n        LT: 'HH:mm',\n        LTS: 'HH:mm:ss',\n        L: 'DD/MM/YYYY',\n        LL: 'D MMMM YYYY',\n        LLL: 'D MMMM YYYY HH:mm',\n        LLLL: 'dddd D MMMM YYYY HH:mm'\n    },\n    calendar: {\n        sameDay: '[اليوم على الساعة] LT',\n        nextDay: '[غدا على الساعة] LT',\n        nextWeek: 'dddd [على الساعة] LT',\n        lastDay: '[أمس على الساعة] LT',\n        lastWeek: 'dddd [على الساعة] LT',\n        sameElse: 'L'\n    },\n    relativeTime: {\n        future: 'في %s',\n        past: 'منذ %s',\n        s: 'ثوان',\n        m: 'دقيقة',\n        mm: '%d دقائق',\n        h: 'ساعة',\n        hh: '%d ساعات',\n        d: 'يوم',\n        dd: '%d أيام',\n        M: 'شهر',\n        MM: '%d أشهر',\n        y: 'سنة',\n        yy: '%d سنوات'\n    },\n    week: {\n        dow: 1, // Monday is the first day of the week.\n        doy: 4 // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/locale/ar.js",
    "content": "//! moment.js locale configuration\n//! locale : Arabic [ar]\n//! author : Abdel Said: https://github.com/abdelsaid\n//! author : Ahmed Elkhatib\n//! author : forabi https://github.com/forabi\n\nimport moment from '../moment';\n\nvar symbolMap = {\n    '1': '١',\n    '2': '٢',\n    '3': '٣',\n    '4': '٤',\n    '5': '٥',\n    '6': '٦',\n    '7': '٧',\n    '8': '٨',\n    '9': '٩',\n    '0': '٠'\n}, numberMap = {\n    '١': '1',\n    '٢': '2',\n    '٣': '3',\n    '٤': '4',\n    '٥': '5',\n    '٦': '6',\n    '٧': '7',\n    '٨': '8',\n    '٩': '9',\n    '٠': '0'\n}, pluralForm = function (n) {\n    return n === 0 ? 0 : n === 1 ? 1 : n === 2 ? 2 : n % 100 >= 3 && n % 100 <= 10 ? 3 : n % 100 >= 11 ? 4 : 5;\n}, plurals = {\n    s : ['أقل من ثانية', 'ثانية واحدة', ['ثانيتان', 'ثانيتين'], '%d ثوان', '%d ثانية', '%d ثانية'],\n    m : ['أقل من دقيقة', 'دقيقة واحدة', ['دقيقتان', 'دقيقتين'], '%d دقائق', '%d دقيقة', '%d دقيقة'],\n    h : ['أقل من ساعة', 'ساعة واحدة', ['ساعتان', 'ساعتين'], '%d ساعات', '%d ساعة', '%d ساعة'],\n    d : ['أقل من يوم', 'يوم واحد', ['يومان', 'يومين'], '%d أيام', '%d يومًا', '%d يوم'],\n    M : ['أقل من شهر', 'شهر واحد', ['شهران', 'شهرين'], '%d أشهر', '%d شهرا', '%d شهر'],\n    y : ['أقل من عام', 'عام واحد', ['عامان', 'عامين'], '%d أعوام', '%d عامًا', '%d عام']\n}, pluralize = function (u) {\n    return function (number, withoutSuffix, string, isFuture) {\n        var f = pluralForm(number),\n            str = plurals[u][pluralForm(number)];\n        if (f === 2) {\n            str = str[withoutSuffix ? 0 : 1];\n        }\n        return str.replace(/%d/i, number);\n    };\n}, months = [\n    'كانون الثاني يناير',\n    'شباط فبراير',\n    'آذار مارس',\n    'نيسان أبريل',\n    'أيار مايو',\n    'حزيران يونيو',\n    'تموز يوليو',\n    'آب أغسطس',\n    'أيلول سبتمبر',\n    'تشرين الأول أكتوبر',\n    'تشرين الثاني نوفمبر',\n    'كانون الأول ديسمبر'\n];\n\nexport default moment.defineLocale('ar', {\n    months : months,\n    monthsShort : months,\n    weekdays : 'الأحد_الإثنين_الثلاثاء_الأربعاء_الخميس_الجمعة_السبت'.split('_'),\n    weekdaysShort : 'أحد_إثنين_ثلاثاء_أربعاء_خميس_جمعة_سبت'.split('_'),\n    weekdaysMin : 'ح_ن_ث_ر_خ_ج_س'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'D/\\u200FM/\\u200FYYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY HH:mm',\n        LLLL : 'dddd D MMMM YYYY HH:mm'\n    },\n    meridiemParse: /ص|م/,\n    isPM : function (input) {\n        return 'م' === input;\n    },\n    meridiem : function (hour, minute, isLower) {\n        if (hour < 12) {\n            return 'ص';\n        } else {\n            return 'م';\n        }\n    },\n    calendar : {\n        sameDay: '[اليوم عند الساعة] LT',\n        nextDay: '[غدًا عند الساعة] LT',\n        nextWeek: 'dddd [عند الساعة] LT',\n        lastDay: '[أمس عند الساعة] LT',\n        lastWeek: 'dddd [عند الساعة] LT',\n        sameElse: 'L'\n    },\n    relativeTime : {\n        future : 'بعد %s',\n        past : 'منذ %s',\n        s : pluralize('s'),\n        m : pluralize('m'),\n        mm : pluralize('m'),\n        h : pluralize('h'),\n        hh : pluralize('h'),\n        d : pluralize('d'),\n        dd : pluralize('d'),\n        M : pluralize('M'),\n        MM : pluralize('M'),\n        y : pluralize('y'),\n        yy : pluralize('y')\n    },\n    preparse: function (string) {\n        return string.replace(/\\u200f/g, '').replace(/[١٢٣٤٥٦٧٨٩٠]/g, function (match) {\n            return numberMap[match];\n        }).replace(/،/g, ',');\n    },\n    postformat: function (string) {\n        return string.replace(/\\d/g, function (match) {\n            return symbolMap[match];\n        }).replace(/,/g, '،');\n    },\n    week : {\n        dow : 6, // Saturday is the first day of the week.\n        doy : 12  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/locale/az.js",
    "content": "//! moment.js locale configuration\n//! locale : Azerbaijani [az]\n//! author : topchiyev : https://github.com/topchiyev\n\nimport moment from '../moment';\n\nvar suffixes = {\n    1: '-inci',\n    5: '-inci',\n    8: '-inci',\n    70: '-inci',\n    80: '-inci',\n    2: '-nci',\n    7: '-nci',\n    20: '-nci',\n    50: '-nci',\n    3: '-üncü',\n    4: '-üncü',\n    100: '-üncü',\n    6: '-ncı',\n    9: '-uncu',\n    10: '-uncu',\n    30: '-uncu',\n    60: '-ıncı',\n    90: '-ıncı'\n};\n\nexport default moment.defineLocale('az', {\n    months : 'yanvar_fevral_mart_aprel_may_iyun_iyul_avqust_sentyabr_oktyabr_noyabr_dekabr'.split('_'),\n    monthsShort : 'yan_fev_mar_apr_may_iyn_iyl_avq_sen_okt_noy_dek'.split('_'),\n    weekdays : 'Bazar_Bazar ertəsi_Çərşənbə axşamı_Çərşənbə_Cümə axşamı_Cümə_Şənbə'.split('_'),\n    weekdaysShort : 'Baz_BzE_ÇAx_Çər_CAx_Cüm_Şən'.split('_'),\n    weekdaysMin : 'Bz_BE_ÇA_Çə_CA_Cü_Şə'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD.MM.YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY HH:mm',\n        LLLL : 'dddd, D MMMM YYYY HH:mm'\n    },\n    calendar : {\n        sameDay : '[bugün saat] LT',\n        nextDay : '[sabah saat] LT',\n        nextWeek : '[gələn həftə] dddd [saat] LT',\n        lastDay : '[dünən] LT',\n        lastWeek : '[keçən həftə] dddd [saat] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : '%s sonra',\n        past : '%s əvvəl',\n        s : 'birneçə saniyyə',\n        m : 'bir dəqiqə',\n        mm : '%d dəqiqə',\n        h : 'bir saat',\n        hh : '%d saat',\n        d : 'bir gün',\n        dd : '%d gün',\n        M : 'bir ay',\n        MM : '%d ay',\n        y : 'bir il',\n        yy : '%d il'\n    },\n    meridiemParse: /gecə|səhər|gündüz|axşam/,\n    isPM : function (input) {\n        return /^(gündüz|axşam)$/.test(input);\n    },\n    meridiem : function (hour, minute, isLower) {\n        if (hour < 4) {\n            return 'gecə';\n        } else if (hour < 12) {\n            return 'səhər';\n        } else if (hour < 17) {\n            return 'gündüz';\n        } else {\n            return 'axşam';\n        }\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}-(ıncı|inci|nci|üncü|ncı|uncu)/,\n    ordinal : function (number) {\n        if (number === 0) {  // special case for zero\n            return number + '-ıncı';\n        }\n        var a = number % 10,\n            b = number % 100 - a,\n            c = number >= 100 ? 100 : null;\n        return number + (suffixes[a] || suffixes[b] || suffixes[c]);\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 7  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/locale/be.js",
    "content": "//! moment.js locale configuration\n//! locale : Belarusian [be]\n//! author : Dmitry Demidov : https://github.com/demidov91\n//! author: Praleska: http://praleska.pro/\n//! Author : Menelion Elensúle : https://github.com/Oire\n\nimport moment from '../moment';\n\nfunction plural(word, num) {\n    var forms = word.split('_');\n    return num % 10 === 1 && num % 100 !== 11 ? forms[0] : (num % 10 >= 2 && num % 10 <= 4 && (num % 100 < 10 || num % 100 >= 20) ? forms[1] : forms[2]);\n}\nfunction relativeTimeWithPlural(number, withoutSuffix, key) {\n    var format = {\n        'mm': withoutSuffix ? 'хвіліна_хвіліны_хвілін' : 'хвіліну_хвіліны_хвілін',\n        'hh': withoutSuffix ? 'гадзіна_гадзіны_гадзін' : 'гадзіну_гадзіны_гадзін',\n        'dd': 'дзень_дні_дзён',\n        'MM': 'месяц_месяцы_месяцаў',\n        'yy': 'год_гады_гадоў'\n    };\n    if (key === 'm') {\n        return withoutSuffix ? 'хвіліна' : 'хвіліну';\n    }\n    else if (key === 'h') {\n        return withoutSuffix ? 'гадзіна' : 'гадзіну';\n    }\n    else {\n        return number + ' ' + plural(format[key], +number);\n    }\n}\n\nexport default moment.defineLocale('be', {\n    months : {\n        format: 'студзеня_лютага_сакавіка_красавіка_траўня_чэрвеня_ліпеня_жніўня_верасня_кастрычніка_лістапада_снежня'.split('_'),\n        standalone: 'студзень_люты_сакавік_красавік_травень_чэрвень_ліпень_жнівень_верасень_кастрычнік_лістапад_снежань'.split('_')\n    },\n    monthsShort : 'студ_лют_сак_крас_трав_чэрв_ліп_жнів_вер_каст_ліст_снеж'.split('_'),\n    weekdays : {\n        format: 'нядзелю_панядзелак_аўторак_сераду_чацвер_пятніцу_суботу'.split('_'),\n        standalone: 'нядзеля_панядзелак_аўторак_серада_чацвер_пятніца_субота'.split('_'),\n        isFormat: /\\[ ?[Вв] ?(?:мінулую|наступную)? ?\\] ?dddd/\n    },\n    weekdaysShort : 'нд_пн_ат_ср_чц_пт_сб'.split('_'),\n    weekdaysMin : 'нд_пн_ат_ср_чц_пт_сб'.split('_'),\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD.MM.YYYY',\n        LL : 'D MMMM YYYY г.',\n        LLL : 'D MMMM YYYY г., HH:mm',\n        LLLL : 'dddd, D MMMM YYYY г., HH:mm'\n    },\n    calendar : {\n        sameDay: '[Сёння ў] LT',\n        nextDay: '[Заўтра ў] LT',\n        lastDay: '[Учора ў] LT',\n        nextWeek: function () {\n            return '[У] dddd [ў] LT';\n        },\n        lastWeek: function () {\n            switch (this.day()) {\n                case 0:\n                case 3:\n                case 5:\n                case 6:\n                    return '[У мінулую] dddd [ў] LT';\n                case 1:\n                case 2:\n                case 4:\n                    return '[У мінулы] dddd [ў] LT';\n            }\n        },\n        sameElse: 'L'\n    },\n    relativeTime : {\n        future : 'праз %s',\n        past : '%s таму',\n        s : 'некалькі секунд',\n        m : relativeTimeWithPlural,\n        mm : relativeTimeWithPlural,\n        h : relativeTimeWithPlural,\n        hh : relativeTimeWithPlural,\n        d : 'дзень',\n        dd : relativeTimeWithPlural,\n        M : 'месяц',\n        MM : relativeTimeWithPlural,\n        y : 'год',\n        yy : relativeTimeWithPlural\n    },\n    meridiemParse: /ночы|раніцы|дня|вечара/,\n    isPM : function (input) {\n        return /^(дня|вечара)$/.test(input);\n    },\n    meridiem : function (hour, minute, isLower) {\n        if (hour < 4) {\n            return 'ночы';\n        } else if (hour < 12) {\n            return 'раніцы';\n        } else if (hour < 17) {\n            return 'дня';\n        } else {\n            return 'вечара';\n        }\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}-(і|ы|га)/,\n    ordinal: function (number, period) {\n        switch (period) {\n            case 'M':\n            case 'd':\n            case 'DDD':\n            case 'w':\n            case 'W':\n                return (number % 10 === 2 || number % 10 === 3) && (number % 100 !== 12 && number % 100 !== 13) ? number + '-і' : number + '-ы';\n            case 'D':\n                return number + '-га';\n            default:\n                return number;\n        }\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 7  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/locale/bg.js",
    "content": "//! moment.js locale configuration\n//! locale : Bulgarian [bg]\n//! author : Krasen Borisov : https://github.com/kraz\n\nimport moment from '../moment';\n\nexport default moment.defineLocale('bg', {\n    months : 'януари_февруари_март_април_май_юни_юли_август_септември_октомври_ноември_декември'.split('_'),\n    monthsShort : 'янр_фев_мар_апр_май_юни_юли_авг_сеп_окт_ное_дек'.split('_'),\n    weekdays : 'неделя_понеделник_вторник_сряда_четвъртък_петък_събота'.split('_'),\n    weekdaysShort : 'нед_пон_вто_сря_чет_пет_съб'.split('_'),\n    weekdaysMin : 'нд_пн_вт_ср_чт_пт_сб'.split('_'),\n    longDateFormat : {\n        LT : 'H:mm',\n        LTS : 'H:mm:ss',\n        L : 'D.MM.YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY H:mm',\n        LLLL : 'dddd, D MMMM YYYY H:mm'\n    },\n    calendar : {\n        sameDay : '[Днес в] LT',\n        nextDay : '[Утре в] LT',\n        nextWeek : 'dddd [в] LT',\n        lastDay : '[Вчера в] LT',\n        lastWeek : function () {\n            switch (this.day()) {\n                case 0:\n                case 3:\n                case 6:\n                    return '[В изминалата] dddd [в] LT';\n                case 1:\n                case 2:\n                case 4:\n                case 5:\n                    return '[В изминалия] dddd [в] LT';\n            }\n        },\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'след %s',\n        past : 'преди %s',\n        s : 'няколко секунди',\n        m : 'минута',\n        mm : '%d минути',\n        h : 'час',\n        hh : '%d часа',\n        d : 'ден',\n        dd : '%d дни',\n        M : 'месец',\n        MM : '%d месеца',\n        y : 'година',\n        yy : '%d години'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}-(ев|ен|ти|ви|ри|ми)/,\n    ordinal : function (number) {\n        var lastDigit = number % 10,\n            last2Digits = number % 100;\n        if (number === 0) {\n            return number + '-ев';\n        } else if (last2Digits === 0) {\n            return number + '-ен';\n        } else if (last2Digits > 10 && last2Digits < 20) {\n            return number + '-ти';\n        } else if (lastDigit === 1) {\n            return number + '-ви';\n        } else if (lastDigit === 2) {\n            return number + '-ри';\n        } else if (lastDigit === 7 || lastDigit === 8) {\n            return number + '-ми';\n        } else {\n            return number + '-ти';\n        }\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 7  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/locale/bn.js",
    "content": "//! moment.js locale configuration\n//! locale : Bengali [bn]\n//! author : Kaushik Gandhi : https://github.com/kaushikgandhi\n\nimport moment from '../moment';\n\nvar symbolMap = {\n    '1': '১',\n    '2': '২',\n    '3': '৩',\n    '4': '৪',\n    '5': '৫',\n    '6': '৬',\n    '7': '৭',\n    '8': '৮',\n    '9': '৯',\n    '0': '০'\n},\nnumberMap = {\n    '১': '1',\n    '২': '2',\n    '৩': '3',\n    '৪': '4',\n    '৫': '5',\n    '৬': '6',\n    '৭': '7',\n    '৮': '8',\n    '৯': '9',\n    '০': '0'\n};\n\nexport default moment.defineLocale('bn', {\n    months : 'জানুয়ারী_ফেব্রুয়ারি_মার্চ_এপ্রিল_মে_জুন_জুলাই_আগস্ট_সেপ্টেম্বর_অক্টোবর_নভেম্বর_ডিসেম্বর'.split('_'),\n    monthsShort : 'জানু_ফেব_মার্চ_এপ্র_মে_জুন_জুল_আগ_সেপ্ট_অক্টো_নভে_ডিসে'.split('_'),\n    weekdays : 'রবিবার_সোমবার_মঙ্গলবার_বুধবার_বৃহস্পতিবার_শুক্রবার_শনিবার'.split('_'),\n    weekdaysShort : 'রবি_সোম_মঙ্গল_বুধ_বৃহস্পতি_শুক্র_শনি'.split('_'),\n    weekdaysMin : 'রবি_সোম_মঙ্গ_বুধ_বৃহঃ_শুক্র_শনি'.split('_'),\n    longDateFormat : {\n        LT : 'A h:mm সময়',\n        LTS : 'A h:mm:ss সময়',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY, A h:mm সময়',\n        LLLL : 'dddd, D MMMM YYYY, A h:mm সময়'\n    },\n    calendar : {\n        sameDay : '[আজ] LT',\n        nextDay : '[আগামীকাল] LT',\n        nextWeek : 'dddd, LT',\n        lastDay : '[গতকাল] LT',\n        lastWeek : '[গত] dddd, LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : '%s পরে',\n        past : '%s আগে',\n        s : 'কয়েক সেকেন্ড',\n        m : 'এক মিনিট',\n        mm : '%d মিনিট',\n        h : 'এক ঘন্টা',\n        hh : '%d ঘন্টা',\n        d : 'এক দিন',\n        dd : '%d দিন',\n        M : 'এক মাস',\n        MM : '%d মাস',\n        y : 'এক বছর',\n        yy : '%d বছর'\n    },\n    preparse: function (string) {\n        return string.replace(/[১২৩৪৫৬৭৮৯০]/g, function (match) {\n            return numberMap[match];\n        });\n    },\n    postformat: function (string) {\n        return string.replace(/\\d/g, function (match) {\n            return symbolMap[match];\n        });\n    },\n    meridiemParse: /রাত|সকাল|দুপুর|বিকাল|রাত/,\n    meridiemHour : function (hour, meridiem) {\n        if (hour === 12) {\n            hour = 0;\n        }\n        if ((meridiem === 'রাত' && hour >= 4) ||\n                (meridiem === 'দুপুর' && hour < 5) ||\n                meridiem === 'বিকাল') {\n            return hour + 12;\n        } else {\n            return hour;\n        }\n    },\n    meridiem : function (hour, minute, isLower) {\n        if (hour < 4) {\n            return 'রাত';\n        } else if (hour < 10) {\n            return 'সকাল';\n        } else if (hour < 17) {\n            return 'দুপুর';\n        } else if (hour < 20) {\n            return 'বিকাল';\n        } else {\n            return 'রাত';\n        }\n    },\n    week : {\n        dow : 0, // Sunday is the first day of the week.\n        doy : 6  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/locale/bo.js",
    "content": "//! moment.js locale configuration\n//! locale : Tibetan [bo]\n//! author : Thupten N. Chakrishar : https://github.com/vajradog\n\nimport moment from '../moment';\n\nvar symbolMap = {\n    '1': '༡',\n    '2': '༢',\n    '3': '༣',\n    '4': '༤',\n    '5': '༥',\n    '6': '༦',\n    '7': '༧',\n    '8': '༨',\n    '9': '༩',\n    '0': '༠'\n},\nnumberMap = {\n    '༡': '1',\n    '༢': '2',\n    '༣': '3',\n    '༤': '4',\n    '༥': '5',\n    '༦': '6',\n    '༧': '7',\n    '༨': '8',\n    '༩': '9',\n    '༠': '0'\n};\n\nexport default moment.defineLocale('bo', {\n    months : 'ཟླ་བ་དང་པོ_ཟླ་བ་གཉིས་པ_ཟླ་བ་གསུམ་པ_ཟླ་བ་བཞི་པ_ཟླ་བ་ལྔ་པ_ཟླ་བ་དྲུག་པ_ཟླ་བ་བདུན་པ_ཟླ་བ་བརྒྱད་པ_ཟླ་བ་དགུ་པ_ཟླ་བ་བཅུ་པ_ཟླ་བ་བཅུ་གཅིག་པ_ཟླ་བ་བཅུ་གཉིས་པ'.split('_'),\n    monthsShort : 'ཟླ་བ་དང་པོ_ཟླ་བ་གཉིས་པ_ཟླ་བ་གསུམ་པ_ཟླ་བ་བཞི་པ_ཟླ་བ་ལྔ་པ_ཟླ་བ་དྲུག་པ_ཟླ་བ་བདུན་པ_ཟླ་བ་བརྒྱད་པ_ཟླ་བ་དགུ་པ_ཟླ་བ་བཅུ་པ_ཟླ་བ་བཅུ་གཅིག་པ_ཟླ་བ་བཅུ་གཉིས་པ'.split('_'),\n    weekdays : 'གཟའ་ཉི་མ་_གཟའ་ཟླ་བ་_གཟའ་མིག་དམར་_གཟའ་ལྷག་པ་_གཟའ་ཕུར་བུ_གཟའ་པ་སངས་_གཟའ་སྤེན་པ་'.split('_'),\n    weekdaysShort : 'ཉི་མ་_ཟླ་བ་_མིག་དམར་_ལྷག་པ་_ཕུར་བུ_པ་སངས་_སྤེན་པ་'.split('_'),\n    weekdaysMin : 'ཉི་མ་_ཟླ་བ་_མིག་དམར་_ལྷག་པ་_ཕུར་བུ_པ་སངས་_སྤེན་པ་'.split('_'),\n    longDateFormat : {\n        LT : 'A h:mm',\n        LTS : 'A h:mm:ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY, A h:mm',\n        LLLL : 'dddd, D MMMM YYYY, A h:mm'\n    },\n    calendar : {\n        sameDay : '[དི་རིང] LT',\n        nextDay : '[སང་ཉིན] LT',\n        nextWeek : '[བདུན་ཕྲག་རྗེས་མ], LT',\n        lastDay : '[ཁ་སང] LT',\n        lastWeek : '[བདུན་ཕྲག་མཐའ་མ] dddd, LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : '%s ལ་',\n        past : '%s སྔན་ལ',\n        s : 'ལམ་སང',\n        m : 'སྐར་མ་གཅིག',\n        mm : '%d སྐར་མ',\n        h : 'ཆུ་ཚོད་གཅིག',\n        hh : '%d ཆུ་ཚོད',\n        d : 'ཉིན་གཅིག',\n        dd : '%d ཉིན་',\n        M : 'ཟླ་བ་གཅིག',\n        MM : '%d ཟླ་བ',\n        y : 'ལོ་གཅིག',\n        yy : '%d ལོ'\n    },\n    preparse: function (string) {\n        return string.replace(/[༡༢༣༤༥༦༧༨༩༠]/g, function (match) {\n            return numberMap[match];\n        });\n    },\n    postformat: function (string) {\n        return string.replace(/\\d/g, function (match) {\n            return symbolMap[match];\n        });\n    },\n    meridiemParse: /མཚན་མོ|ཞོགས་ཀས|ཉིན་གུང|དགོང་དག|མཚན་མོ/,\n    meridiemHour : function (hour, meridiem) {\n        if (hour === 12) {\n            hour = 0;\n        }\n        if ((meridiem === 'མཚན་མོ' && hour >= 4) ||\n                (meridiem === 'ཉིན་གུང' && hour < 5) ||\n                meridiem === 'དགོང་དག') {\n            return hour + 12;\n        } else {\n            return hour;\n        }\n    },\n    meridiem : function (hour, minute, isLower) {\n        if (hour < 4) {\n            return 'མཚན་མོ';\n        } else if (hour < 10) {\n            return 'ཞོགས་ཀས';\n        } else if (hour < 17) {\n            return 'ཉིན་གུང';\n        } else if (hour < 20) {\n            return 'དགོང་དག';\n        } else {\n            return 'མཚན་མོ';\n        }\n    },\n    week : {\n        dow : 0, // Sunday is the first day of the week.\n        doy : 6  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/locale/br.js",
    "content": "//! moment.js locale configuration\n//! locale : Breton [br]\n//! author : Jean-Baptiste Le Duigou : https://github.com/jbleduigou\n\nimport moment from '../moment';\n\nfunction relativeTimeWithMutation(number, withoutSuffix, key) {\n    var format = {\n        'mm': 'munutenn',\n        'MM': 'miz',\n        'dd': 'devezh'\n    };\n    return number + ' ' + mutation(format[key], number);\n}\nfunction specialMutationForYears(number) {\n    switch (lastNumber(number)) {\n        case 1:\n        case 3:\n        case 4:\n        case 5:\n        case 9:\n            return number + ' bloaz';\n        default:\n            return number + ' vloaz';\n    }\n}\nfunction lastNumber(number) {\n    if (number > 9) {\n        return lastNumber(number % 10);\n    }\n    return number;\n}\nfunction mutation(text, number) {\n    if (number === 2) {\n        return softMutation(text);\n    }\n    return text;\n}\nfunction softMutation(text) {\n    var mutationTable = {\n        'm': 'v',\n        'b': 'v',\n        'd': 'z'\n    };\n    if (mutationTable[text.charAt(0)] === undefined) {\n        return text;\n    }\n    return mutationTable[text.charAt(0)] + text.substring(1);\n}\n\nexport default moment.defineLocale('br', {\n    months : 'Genver_C\\'hwevrer_Meurzh_Ebrel_Mae_Mezheven_Gouere_Eost_Gwengolo_Here_Du_Kerzu'.split('_'),\n    monthsShort : 'Gen_C\\'hwe_Meu_Ebr_Mae_Eve_Gou_Eos_Gwe_Her_Du_Ker'.split('_'),\n    weekdays : 'Sul_Lun_Meurzh_Merc\\'her_Yaou_Gwener_Sadorn'.split('_'),\n    weekdaysShort : 'Sul_Lun_Meu_Mer_Yao_Gwe_Sad'.split('_'),\n    weekdaysMin : 'Su_Lu_Me_Mer_Ya_Gw_Sa'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat : {\n        LT : 'h[e]mm A',\n        LTS : 'h[e]mm:ss A',\n        L : 'DD/MM/YYYY',\n        LL : 'D [a viz] MMMM YYYY',\n        LLL : 'D [a viz] MMMM YYYY h[e]mm A',\n        LLLL : 'dddd, D [a viz] MMMM YYYY h[e]mm A'\n    },\n    calendar : {\n        sameDay : '[Hiziv da] LT',\n        nextDay : '[Warc\\'hoazh da] LT',\n        nextWeek : 'dddd [da] LT',\n        lastDay : '[Dec\\'h da] LT',\n        lastWeek : 'dddd [paset da] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'a-benn %s',\n        past : '%s \\'zo',\n        s : 'un nebeud segondennoù',\n        m : 'ur vunutenn',\n        mm : relativeTimeWithMutation,\n        h : 'un eur',\n        hh : '%d eur',\n        d : 'un devezh',\n        dd : relativeTimeWithMutation,\n        M : 'ur miz',\n        MM : relativeTimeWithMutation,\n        y : 'ur bloaz',\n        yy : specialMutationForYears\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}(añ|vet)/,\n    ordinal : function (number) {\n        var output = (number === 1) ? 'añ' : 'vet';\n        return number + output;\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/locale/bs.js",
    "content": "//! moment.js locale configuration\n//! locale : Bosnian [bs]\n//! author : Nedim Cholich : https://github.com/frontyard\n//! based on (hr) translation by Bojan Marković\n\nimport moment from '../moment';\n\nfunction translate(number, withoutSuffix, key) {\n    var result = number + ' ';\n    switch (key) {\n        case 'm':\n            return withoutSuffix ? 'jedna minuta' : 'jedne minute';\n        case 'mm':\n            if (number === 1) {\n                result += 'minuta';\n            } else if (number === 2 || number === 3 || number === 4) {\n                result += 'minute';\n            } else {\n                result += 'minuta';\n            }\n            return result;\n        case 'h':\n            return withoutSuffix ? 'jedan sat' : 'jednog sata';\n        case 'hh':\n            if (number === 1) {\n                result += 'sat';\n            } else if (number === 2 || number === 3 || number === 4) {\n                result += 'sata';\n            } else {\n                result += 'sati';\n            }\n            return result;\n        case 'dd':\n            if (number === 1) {\n                result += 'dan';\n            } else {\n                result += 'dana';\n            }\n            return result;\n        case 'MM':\n            if (number === 1) {\n                result += 'mjesec';\n            } else if (number === 2 || number === 3 || number === 4) {\n                result += 'mjeseca';\n            } else {\n                result += 'mjeseci';\n            }\n            return result;\n        case 'yy':\n            if (number === 1) {\n                result += 'godina';\n            } else if (number === 2 || number === 3 || number === 4) {\n                result += 'godine';\n            } else {\n                result += 'godina';\n            }\n            return result;\n    }\n}\n\nexport default moment.defineLocale('bs', {\n    months : 'januar_februar_mart_april_maj_juni_juli_august_septembar_oktobar_novembar_decembar'.split('_'),\n    monthsShort : 'jan._feb._mar._apr._maj._jun._jul._aug._sep._okt._nov._dec.'.split('_'),\n    monthsParseExact: true,\n    weekdays : 'nedjelja_ponedjeljak_utorak_srijeda_četvrtak_petak_subota'.split('_'),\n    weekdaysShort : 'ned._pon._uto._sri._čet._pet._sub.'.split('_'),\n    weekdaysMin : 'ne_po_ut_sr_če_pe_su'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat : {\n        LT : 'H:mm',\n        LTS : 'H:mm:ss',\n        L : 'DD.MM.YYYY',\n        LL : 'D. MMMM YYYY',\n        LLL : 'D. MMMM YYYY H:mm',\n        LLLL : 'dddd, D. MMMM YYYY H:mm'\n    },\n    calendar : {\n        sameDay  : '[danas u] LT',\n        nextDay  : '[sutra u] LT',\n        nextWeek : function () {\n            switch (this.day()) {\n                case 0:\n                    return '[u] [nedjelju] [u] LT';\n                case 3:\n                    return '[u] [srijedu] [u] LT';\n                case 6:\n                    return '[u] [subotu] [u] LT';\n                case 1:\n                case 2:\n                case 4:\n                case 5:\n                    return '[u] dddd [u] LT';\n            }\n        },\n        lastDay  : '[jučer u] LT',\n        lastWeek : function () {\n            switch (this.day()) {\n                case 0:\n                case 3:\n                    return '[prošlu] dddd [u] LT';\n                case 6:\n                    return '[prošle] [subote] [u] LT';\n                case 1:\n                case 2:\n                case 4:\n                case 5:\n                    return '[prošli] dddd [u] LT';\n            }\n        },\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'za %s',\n        past   : 'prije %s',\n        s      : 'par sekundi',\n        m      : translate,\n        mm     : translate,\n        h      : translate,\n        hh     : translate,\n        d      : 'dan',\n        dd     : translate,\n        M      : 'mjesec',\n        MM     : translate,\n        y      : 'godinu',\n        yy     : translate\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}\\./,\n    ordinal : '%d.',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 7  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/locale/ca.js",
    "content": "//! moment.js locale configuration\n//! locale : Catalan [ca]\n//! author : Juan G. Hurtado : https://github.com/juanghurtado\n\nimport moment from '../moment';\n\nexport default moment.defineLocale('ca', {\n    months : {\n        standalone: 'gener_febrer_març_abril_maig_juny_juliol_agost_setembre_octubre_novembre_desembre'.split('_'),\n        format: 'de gener_de febrer_de març_d\\'abril_de maig_de juny_de juliol_d\\'agost_de setembre_d\\'octubre_de novembre_de desembre'.split('_'),\n        isFormat: /D[oD]?(\\s)+MMMM/\n    },\n    monthsShort : 'gen._febr._març_abr._maig_juny_jul._ag._set._oct._nov._des.'.split('_'),\n    monthsParseExact : true,\n    weekdays : 'diumenge_dilluns_dimarts_dimecres_dijous_divendres_dissabte'.split('_'),\n    weekdaysShort : 'dg._dl._dt._dc._dj._dv._ds.'.split('_'),\n    weekdaysMin : 'Dg_Dl_Dt_Dc_Dj_Dv_Ds'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat : {\n        LT : 'H:mm',\n        LTS : 'H:mm:ss',\n        L : 'DD/MM/YYYY',\n        LL : '[el] D MMMM [de] YYYY',\n        ll : 'D MMM YYYY',\n        LLL : '[el] D MMMM [de] YYYY [a les] H:mm',\n        lll : 'D MMM YYYY, H:mm',\n        LLLL : '[el] dddd D MMMM [de] YYYY [a les] H:mm',\n        llll : 'ddd D MMM YYYY, H:mm'\n    },\n    calendar : {\n        sameDay : function () {\n            return '[avui a ' + ((this.hours() !== 1) ? 'les' : 'la') + '] LT';\n        },\n        nextDay : function () {\n            return '[demà a ' + ((this.hours() !== 1) ? 'les' : 'la') + '] LT';\n        },\n        nextWeek : function () {\n            return 'dddd [a ' + ((this.hours() !== 1) ? 'les' : 'la') + '] LT';\n        },\n        lastDay : function () {\n            return '[ahir a ' + ((this.hours() !== 1) ? 'les' : 'la') + '] LT';\n        },\n        lastWeek : function () {\n            return '[el] dddd [passat a ' + ((this.hours() !== 1) ? 'les' : 'la') + '] LT';\n        },\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'd\\'aquí %s',\n        past : 'fa %s',\n        s : 'uns segons',\n        m : 'un minut',\n        mm : '%d minuts',\n        h : 'una hora',\n        hh : '%d hores',\n        d : 'un dia',\n        dd : '%d dies',\n        M : 'un mes',\n        MM : '%d mesos',\n        y : 'un any',\n        yy : '%d anys'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}(r|n|t|è|a)/,\n    ordinal : function (number, period) {\n        var output = (number === 1) ? 'r' :\n            (number === 2) ? 'n' :\n            (number === 3) ? 'r' :\n            (number === 4) ? 't' : 'è';\n        if (period === 'w' || period === 'W') {\n            output = 'a';\n        }\n        return number + output;\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/locale/cs.js",
    "content": "//! moment.js locale configuration\n//! locale : Czech [cs]\n//! author : petrbela : https://github.com/petrbela\n\nimport moment from '../moment';\n\nvar months = 'leden_únor_březen_duben_květen_červen_červenec_srpen_září_říjen_listopad_prosinec'.split('_'),\n    monthsShort = 'led_úno_bře_dub_kvě_čvn_čvc_srp_zář_říj_lis_pro'.split('_');\nfunction plural(n) {\n    return (n > 1) && (n < 5) && (~~(n / 10) !== 1);\n}\nfunction translate(number, withoutSuffix, key, isFuture) {\n    var result = number + ' ';\n    switch (key) {\n        case 's':  // a few seconds / in a few seconds / a few seconds ago\n            return (withoutSuffix || isFuture) ? 'pár sekund' : 'pár sekundami';\n        case 'm':  // a minute / in a minute / a minute ago\n            return withoutSuffix ? 'minuta' : (isFuture ? 'minutu' : 'minutou');\n        case 'mm': // 9 minutes / in 9 minutes / 9 minutes ago\n            if (withoutSuffix || isFuture) {\n                return result + (plural(number) ? 'minuty' : 'minut');\n            } else {\n                return result + 'minutami';\n            }\n            break;\n        case 'h':  // an hour / in an hour / an hour ago\n            return withoutSuffix ? 'hodina' : (isFuture ? 'hodinu' : 'hodinou');\n        case 'hh': // 9 hours / in 9 hours / 9 hours ago\n            if (withoutSuffix || isFuture) {\n                return result + (plural(number) ? 'hodiny' : 'hodin');\n            } else {\n                return result + 'hodinami';\n            }\n            break;\n        case 'd':  // a day / in a day / a day ago\n            return (withoutSuffix || isFuture) ? 'den' : 'dnem';\n        case 'dd': // 9 days / in 9 days / 9 days ago\n            if (withoutSuffix || isFuture) {\n                return result + (plural(number) ? 'dny' : 'dní');\n            } else {\n                return result + 'dny';\n            }\n            break;\n        case 'M':  // a month / in a month / a month ago\n            return (withoutSuffix || isFuture) ? 'měsíc' : 'měsícem';\n        case 'MM': // 9 months / in 9 months / 9 months ago\n            if (withoutSuffix || isFuture) {\n                return result + (plural(number) ? 'měsíce' : 'měsíců');\n            } else {\n                return result + 'měsíci';\n            }\n            break;\n        case 'y':  // a year / in a year / a year ago\n            return (withoutSuffix || isFuture) ? 'rok' : 'rokem';\n        case 'yy': // 9 years / in 9 years / 9 years ago\n            if (withoutSuffix || isFuture) {\n                return result + (plural(number) ? 'roky' : 'let');\n            } else {\n                return result + 'lety';\n            }\n            break;\n    }\n}\n\nexport default moment.defineLocale('cs', {\n    months : months,\n    monthsShort : monthsShort,\n    monthsParse : (function (months, monthsShort) {\n        var i, _monthsParse = [];\n        for (i = 0; i < 12; i++) {\n            // use custom parser to solve problem with July (červenec)\n            _monthsParse[i] = new RegExp('^' + months[i] + '$|^' + monthsShort[i] + '$', 'i');\n        }\n        return _monthsParse;\n    }(months, monthsShort)),\n    shortMonthsParse : (function (monthsShort) {\n        var i, _shortMonthsParse = [];\n        for (i = 0; i < 12; i++) {\n            _shortMonthsParse[i] = new RegExp('^' + monthsShort[i] + '$', 'i');\n        }\n        return _shortMonthsParse;\n    }(monthsShort)),\n    longMonthsParse : (function (months) {\n        var i, _longMonthsParse = [];\n        for (i = 0; i < 12; i++) {\n            _longMonthsParse[i] = new RegExp('^' + months[i] + '$', 'i');\n        }\n        return _longMonthsParse;\n    }(months)),\n    weekdays : 'neděle_pondělí_úterý_středa_čtvrtek_pátek_sobota'.split('_'),\n    weekdaysShort : 'ne_po_út_st_čt_pá_so'.split('_'),\n    weekdaysMin : 'ne_po_út_st_čt_pá_so'.split('_'),\n    longDateFormat : {\n        LT: 'H:mm',\n        LTS : 'H:mm:ss',\n        L : 'DD.MM.YYYY',\n        LL : 'D. MMMM YYYY',\n        LLL : 'D. MMMM YYYY H:mm',\n        LLLL : 'dddd D. MMMM YYYY H:mm',\n        l : 'D. M. YYYY'\n    },\n    calendar : {\n        sameDay: '[dnes v] LT',\n        nextDay: '[zítra v] LT',\n        nextWeek: function () {\n            switch (this.day()) {\n                case 0:\n                    return '[v neděli v] LT';\n                case 1:\n                case 2:\n                    return '[v] dddd [v] LT';\n                case 3:\n                    return '[ve středu v] LT';\n                case 4:\n                    return '[ve čtvrtek v] LT';\n                case 5:\n                    return '[v pátek v] LT';\n                case 6:\n                    return '[v sobotu v] LT';\n            }\n        },\n        lastDay: '[včera v] LT',\n        lastWeek: function () {\n            switch (this.day()) {\n                case 0:\n                    return '[minulou neděli v] LT';\n                case 1:\n                case 2:\n                    return '[minulé] dddd [v] LT';\n                case 3:\n                    return '[minulou středu v] LT';\n                case 4:\n                case 5:\n                    return '[minulý] dddd [v] LT';\n                case 6:\n                    return '[minulou sobotu v] LT';\n            }\n        },\n        sameElse: 'L'\n    },\n    relativeTime : {\n        future : 'za %s',\n        past : 'před %s',\n        s : translate,\n        m : translate,\n        mm : translate,\n        h : translate,\n        hh : translate,\n        d : translate,\n        dd : translate,\n        M : translate,\n        MM : translate,\n        y : translate,\n        yy : translate\n    },\n    dayOfMonthOrdinalParse : /\\d{1,2}\\./,\n    ordinal : '%d.',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/locale/cv.js",
    "content": "//! moment.js locale configuration\n//! locale : Chuvash [cv]\n//! author : Anatoly Mironov : https://github.com/mirontoli\n\nimport moment from '../moment';\n\nexport default moment.defineLocale('cv', {\n    months : 'кӑрлач_нарӑс_пуш_ака_май_ҫӗртме_утӑ_ҫурла_авӑн_юпа_чӳк_раштав'.split('_'),\n    monthsShort : 'кӑр_нар_пуш_ака_май_ҫӗр_утӑ_ҫур_авн_юпа_чӳк_раш'.split('_'),\n    weekdays : 'вырсарникун_тунтикун_ытларикун_юнкун_кӗҫнерникун_эрнекун_шӑматкун'.split('_'),\n    weekdaysShort : 'выр_тун_ытл_юн_кӗҫ_эрн_шӑм'.split('_'),\n    weekdaysMin : 'вр_тн_ыт_юн_кҫ_эр_шм'.split('_'),\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD-MM-YYYY',\n        LL : 'YYYY [ҫулхи] MMMM [уйӑхӗн] D[-мӗшӗ]',\n        LLL : 'YYYY [ҫулхи] MMMM [уйӑхӗн] D[-мӗшӗ], HH:mm',\n        LLLL : 'dddd, YYYY [ҫулхи] MMMM [уйӑхӗн] D[-мӗшӗ], HH:mm'\n    },\n    calendar : {\n        sameDay: '[Паян] LT [сехетре]',\n        nextDay: '[Ыран] LT [сехетре]',\n        lastDay: '[Ӗнер] LT [сехетре]',\n        nextWeek: '[Ҫитес] dddd LT [сехетре]',\n        lastWeek: '[Иртнӗ] dddd LT [сехетре]',\n        sameElse: 'L'\n    },\n    relativeTime : {\n        future : function (output) {\n            var affix = /сехет$/i.exec(output) ? 'рен' : /ҫул$/i.exec(output) ? 'тан' : 'ран';\n            return output + affix;\n        },\n        past : '%s каялла',\n        s : 'пӗр-ик ҫеккунт',\n        m : 'пӗр минут',\n        mm : '%d минут',\n        h : 'пӗр сехет',\n        hh : '%d сехет',\n        d : 'пӗр кун',\n        dd : '%d кун',\n        M : 'пӗр уйӑх',\n        MM : '%d уйӑх',\n        y : 'пӗр ҫул',\n        yy : '%d ҫул'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}-мӗш/,\n    ordinal : '%d-мӗш',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 7  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/locale/cy.js",
    "content": "//! moment.js locale configuration\n//! locale : Welsh [cy]\n//! author : Robert Allen : https://github.com/robgallen\n//! author : https://github.com/ryangreaves\n\nimport moment from '../moment';\n\nexport default moment.defineLocale('cy', {\n    months: 'Ionawr_Chwefror_Mawrth_Ebrill_Mai_Mehefin_Gorffennaf_Awst_Medi_Hydref_Tachwedd_Rhagfyr'.split('_'),\n    monthsShort: 'Ion_Chwe_Maw_Ebr_Mai_Meh_Gor_Aws_Med_Hyd_Tach_Rhag'.split('_'),\n    weekdays: 'Dydd Sul_Dydd Llun_Dydd Mawrth_Dydd Mercher_Dydd Iau_Dydd Gwener_Dydd Sadwrn'.split('_'),\n    weekdaysShort: 'Sul_Llun_Maw_Mer_Iau_Gwe_Sad'.split('_'),\n    weekdaysMin: 'Su_Ll_Ma_Me_Ia_Gw_Sa'.split('_'),\n    weekdaysParseExact : true,\n    // time formats are the same as en-gb\n    longDateFormat: {\n        LT: 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L: 'DD/MM/YYYY',\n        LL: 'D MMMM YYYY',\n        LLL: 'D MMMM YYYY HH:mm',\n        LLLL: 'dddd, D MMMM YYYY HH:mm'\n    },\n    calendar: {\n        sameDay: '[Heddiw am] LT',\n        nextDay: '[Yfory am] LT',\n        nextWeek: 'dddd [am] LT',\n        lastDay: '[Ddoe am] LT',\n        lastWeek: 'dddd [diwethaf am] LT',\n        sameElse: 'L'\n    },\n    relativeTime: {\n        future: 'mewn %s',\n        past: '%s yn ôl',\n        s: 'ychydig eiliadau',\n        m: 'munud',\n        mm: '%d munud',\n        h: 'awr',\n        hh: '%d awr',\n        d: 'diwrnod',\n        dd: '%d diwrnod',\n        M: 'mis',\n        MM: '%d mis',\n        y: 'blwyddyn',\n        yy: '%d flynedd'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}(fed|ain|af|il|ydd|ed|eg)/,\n    // traditional ordinal numbers above 31 are not commonly used in colloquial Welsh\n    ordinal: function (number) {\n        var b = number,\n            output = '',\n            lookup = [\n                '', 'af', 'il', 'ydd', 'ydd', 'ed', 'ed', 'ed', 'fed', 'fed', 'fed', // 1af to 10fed\n                'eg', 'fed', 'eg', 'eg', 'fed', 'eg', 'eg', 'fed', 'eg', 'fed' // 11eg to 20fed\n            ];\n        if (b > 20) {\n            if (b === 40 || b === 50 || b === 60 || b === 80 || b === 100) {\n                output = 'fed'; // not 30ain, 70ain or 90ain\n            } else {\n                output = 'ain';\n            }\n        } else if (b > 0) {\n            output = lookup[b];\n        }\n        return number + output;\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/locale/da.js",
    "content": "//! moment.js locale configuration\n//! locale : Danish [da]\n//! author : Ulrik Nielsen : https://github.com/mrbase\n\nimport moment from '../moment';\n\nexport default moment.defineLocale('da', {\n    months : 'januar_februar_marts_april_maj_juni_juli_august_september_oktober_november_december'.split('_'),\n    monthsShort : 'jan_feb_mar_apr_maj_jun_jul_aug_sep_okt_nov_dec'.split('_'),\n    weekdays : 'søndag_mandag_tirsdag_onsdag_torsdag_fredag_lørdag'.split('_'),\n    weekdaysShort : 'søn_man_tir_ons_tor_fre_lør'.split('_'),\n    weekdaysMin : 'sø_ma_ti_on_to_fr_lø'.split('_'),\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D. MMMM YYYY',\n        LLL : 'D. MMMM YYYY HH:mm',\n        LLLL : 'dddd [d.] D. MMMM YYYY [kl.] HH:mm'\n    },\n    calendar : {\n        sameDay : '[i dag kl.] LT',\n        nextDay : '[i morgen kl.] LT',\n        nextWeek : 'på dddd [kl.] LT',\n        lastDay : '[i går kl.] LT',\n        lastWeek : '[i] dddd[s kl.] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'om %s',\n        past : '%s siden',\n        s : 'få sekunder',\n        m : 'et minut',\n        mm : '%d minutter',\n        h : 'en time',\n        hh : '%d timer',\n        d : 'en dag',\n        dd : '%d dage',\n        M : 'en måned',\n        MM : '%d måneder',\n        y : 'et år',\n        yy : '%d år'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}\\./,\n    ordinal : '%d.',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/locale/de-at.js",
    "content": "//! moment.js locale configuration\n//! locale : German (Austria) [de-at]\n//! author : lluchs : https://github.com/lluchs\n//! author: Menelion Elensúle: https://github.com/Oire\n//! author : Martin Groller : https://github.com/MadMG\n//! author : Mikolaj Dadela : https://github.com/mik01aj\n\nimport moment from '../moment';\n\nfunction processRelativeTime(number, withoutSuffix, key, isFuture) {\n    var format = {\n        'm': ['eine Minute', 'einer Minute'],\n        'h': ['eine Stunde', 'einer Stunde'],\n        'd': ['ein Tag', 'einem Tag'],\n        'dd': [number + ' Tage', number + ' Tagen'],\n        'M': ['ein Monat', 'einem Monat'],\n        'MM': [number + ' Monate', number + ' Monaten'],\n        'y': ['ein Jahr', 'einem Jahr'],\n        'yy': [number + ' Jahre', number + ' Jahren']\n    };\n    return withoutSuffix ? format[key][0] : format[key][1];\n}\n\nexport default moment.defineLocale('de-at', {\n    months : 'Jänner_Februar_März_April_Mai_Juni_Juli_August_September_Oktober_November_Dezember'.split('_'),\n    monthsShort : 'Jän._Febr._Mrz._Apr._Mai_Jun._Jul._Aug._Sept._Okt._Nov._Dez.'.split('_'),\n    monthsParseExact : true,\n    weekdays : 'Sonntag_Montag_Dienstag_Mittwoch_Donnerstag_Freitag_Samstag'.split('_'),\n    weekdaysShort : 'So._Mo._Di._Mi._Do._Fr._Sa.'.split('_'),\n    weekdaysMin : 'So_Mo_Di_Mi_Do_Fr_Sa'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat : {\n        LT: 'HH:mm',\n        LTS: 'HH:mm:ss',\n        L : 'DD.MM.YYYY',\n        LL : 'D. MMMM YYYY',\n        LLL : 'D. MMMM YYYY HH:mm',\n        LLLL : 'dddd, D. MMMM YYYY HH:mm'\n    },\n    calendar : {\n        sameDay: '[heute um] LT [Uhr]',\n        sameElse: 'L',\n        nextDay: '[morgen um] LT [Uhr]',\n        nextWeek: 'dddd [um] LT [Uhr]',\n        lastDay: '[gestern um] LT [Uhr]',\n        lastWeek: '[letzten] dddd [um] LT [Uhr]'\n    },\n    relativeTime : {\n        future : 'in %s',\n        past : 'vor %s',\n        s : 'ein paar Sekunden',\n        m : processRelativeTime,\n        mm : '%d Minuten',\n        h : processRelativeTime,\n        hh : '%d Stunden',\n        d : processRelativeTime,\n        dd : processRelativeTime,\n        M : processRelativeTime,\n        MM : processRelativeTime,\n        y : processRelativeTime,\n        yy : processRelativeTime\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}\\./,\n    ordinal : '%d.',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/locale/de-ch.js",
    "content": "//! moment.js locale configuration\n//! locale : German (Switzerland) [de-ch]\n//! author : sschueller : https://github.com/sschueller\n\n// based on: https://www.bk.admin.ch/dokumentation/sprachen/04915/05016/index.html?lang=de#\n\nimport moment from '../moment';\n\nfunction processRelativeTime(number, withoutSuffix, key, isFuture) {\n    var format = {\n        'm': ['eine Minute', 'einer Minute'],\n        'h': ['eine Stunde', 'einer Stunde'],\n        'd': ['ein Tag', 'einem Tag'],\n        'dd': [number + ' Tage', number + ' Tagen'],\n        'M': ['ein Monat', 'einem Monat'],\n        'MM': [number + ' Monate', number + ' Monaten'],\n        'y': ['ein Jahr', 'einem Jahr'],\n        'yy': [number + ' Jahre', number + ' Jahren']\n    };\n    return withoutSuffix ? format[key][0] : format[key][1];\n}\n\nexport default moment.defineLocale('de-ch', {\n    months : 'Januar_Februar_März_April_Mai_Juni_Juli_August_September_Oktober_November_Dezember'.split('_'),\n    monthsShort : 'Jan._Febr._März_April_Mai_Juni_Juli_Aug._Sept._Okt._Nov._Dez.'.split('_'),\n    monthsParseExact : true,\n    weekdays : 'Sonntag_Montag_Dienstag_Mittwoch_Donnerstag_Freitag_Samstag'.split('_'),\n    weekdaysShort : 'So_Mo_Di_Mi_Do_Fr_Sa'.split('_'),\n    weekdaysMin : 'So_Mo_Di_Mi_Do_Fr_Sa'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat : {\n        LT: 'HH.mm',\n        LTS: 'HH.mm.ss',\n        L : 'DD.MM.YYYY',\n        LL : 'D. MMMM YYYY',\n        LLL : 'D. MMMM YYYY HH.mm',\n        LLLL : 'dddd, D. MMMM YYYY HH.mm'\n    },\n    calendar : {\n        sameDay: '[heute um] LT [Uhr]',\n        sameElse: 'L',\n        nextDay: '[morgen um] LT [Uhr]',\n        nextWeek: 'dddd [um] LT [Uhr]',\n        lastDay: '[gestern um] LT [Uhr]',\n        lastWeek: '[letzten] dddd [um] LT [Uhr]'\n    },\n    relativeTime : {\n        future : 'in %s',\n        past : 'vor %s',\n        s : 'ein paar Sekunden',\n        m : processRelativeTime,\n        mm : '%d Minuten',\n        h : processRelativeTime,\n        hh : '%d Stunden',\n        d : processRelativeTime,\n        dd : processRelativeTime,\n        M : processRelativeTime,\n        MM : processRelativeTime,\n        y : processRelativeTime,\n        yy : processRelativeTime\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}\\./,\n    ordinal : '%d.',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/locale/de.js",
    "content": "//! moment.js locale configuration\n//! locale : German [de]\n//! author : lluchs : https://github.com/lluchs\n//! author: Menelion Elensúle: https://github.com/Oire\n//! author : Mikolaj Dadela : https://github.com/mik01aj\n\nimport moment from '../moment';\n\nfunction processRelativeTime(number, withoutSuffix, key, isFuture) {\n    var format = {\n        'm': ['eine Minute', 'einer Minute'],\n        'h': ['eine Stunde', 'einer Stunde'],\n        'd': ['ein Tag', 'einem Tag'],\n        'dd': [number + ' Tage', number + ' Tagen'],\n        'M': ['ein Monat', 'einem Monat'],\n        'MM': [number + ' Monate', number + ' Monaten'],\n        'y': ['ein Jahr', 'einem Jahr'],\n        'yy': [number + ' Jahre', number + ' Jahren']\n    };\n    return withoutSuffix ? format[key][0] : format[key][1];\n}\n\nexport default moment.defineLocale('de', {\n    months : 'Januar_Februar_März_April_Mai_Juni_Juli_August_September_Oktober_November_Dezember'.split('_'),\n    monthsShort : 'Jan._Febr._Mrz._Apr._Mai_Jun._Jul._Aug._Sept._Okt._Nov._Dez.'.split('_'),\n    monthsParseExact : true,\n    weekdays : 'Sonntag_Montag_Dienstag_Mittwoch_Donnerstag_Freitag_Samstag'.split('_'),\n    weekdaysShort : 'So._Mo._Di._Mi._Do._Fr._Sa.'.split('_'),\n    weekdaysMin : 'So_Mo_Di_Mi_Do_Fr_Sa'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat : {\n        LT: 'HH:mm',\n        LTS: 'HH:mm:ss',\n        L : 'DD.MM.YYYY',\n        LL : 'D. MMMM YYYY',\n        LLL : 'D. MMMM YYYY HH:mm',\n        LLLL : 'dddd, D. MMMM YYYY HH:mm'\n    },\n    calendar : {\n        sameDay: '[heute um] LT [Uhr]',\n        sameElse: 'L',\n        nextDay: '[morgen um] LT [Uhr]',\n        nextWeek: 'dddd [um] LT [Uhr]',\n        lastDay: '[gestern um] LT [Uhr]',\n        lastWeek: '[letzten] dddd [um] LT [Uhr]'\n    },\n    relativeTime : {\n        future : 'in %s',\n        past : 'vor %s',\n        s : 'ein paar Sekunden',\n        m : processRelativeTime,\n        mm : '%d Minuten',\n        h : processRelativeTime,\n        hh : '%d Stunden',\n        d : processRelativeTime,\n        dd : processRelativeTime,\n        M : processRelativeTime,\n        MM : processRelativeTime,\n        y : processRelativeTime,\n        yy : processRelativeTime\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}\\./,\n    ordinal : '%d.',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/locale/dv.js",
    "content": "//! moment.js locale configuration\n//! locale : Maldivian [dv]\n//! author : Jawish Hameed : https://github.com/jawish\n\nimport moment from '../moment';\n\nvar months = [\n    'ޖެނުއަރީ',\n    'ފެބްރުއަރީ',\n    'މާރިޗު',\n    'އޭޕްރީލު',\n    'މޭ',\n    'ޖޫން',\n    'ޖުލައި',\n    'އޯގަސްޓު',\n    'ސެޕްޓެމްބަރު',\n    'އޮކްޓޯބަރު',\n    'ނޮވެމްބަރު',\n    'ޑިސެމްބަރު'\n], weekdays = [\n    'އާދިއްތަ',\n    'ހޯމަ',\n    'އަންގާރަ',\n    'ބުދަ',\n    'ބުރާސްފަތި',\n    'ހުކުރު',\n    'ހޮނިހިރު'\n];\n\nexport default moment.defineLocale('dv', {\n    months : months,\n    monthsShort : months,\n    weekdays : weekdays,\n    weekdaysShort : weekdays,\n    weekdaysMin : 'އާދި_ހޯމަ_އަން_ބުދަ_ބުރާ_ހުކު_ހޮނި'.split('_'),\n    longDateFormat : {\n\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'D/M/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY HH:mm',\n        LLLL : 'dddd D MMMM YYYY HH:mm'\n    },\n    meridiemParse: /މކ|މފ/,\n    isPM : function (input) {\n        return 'މފ' === input;\n    },\n    meridiem : function (hour, minute, isLower) {\n        if (hour < 12) {\n            return 'މކ';\n        } else {\n            return 'މފ';\n        }\n    },\n    calendar : {\n        sameDay : '[މިއަދު] LT',\n        nextDay : '[މާދަމާ] LT',\n        nextWeek : 'dddd LT',\n        lastDay : '[އިއްޔެ] LT',\n        lastWeek : '[ފާއިތުވި] dddd LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'ތެރޭގައި %s',\n        past : 'ކުރިން %s',\n        s : 'ސިކުންތުކޮޅެއް',\n        m : 'މިނިޓެއް',\n        mm : 'މިނިޓު %d',\n        h : 'ގަޑިއިރެއް',\n        hh : 'ގަޑިއިރު %d',\n        d : 'ދުވަހެއް',\n        dd : 'ދުވަސް %d',\n        M : 'މަހެއް',\n        MM : 'މަސް %d',\n        y : 'އަހަރެއް',\n        yy : 'އަހަރު %d'\n    },\n    preparse: function (string) {\n        return string.replace(/،/g, ',');\n    },\n    postformat: function (string) {\n        return string.replace(/,/g, '،');\n    },\n    week : {\n        dow : 7,  // Sunday is the first day of the week.\n        doy : 12  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/locale/el.js",
    "content": "//! moment.js locale configuration\n//! locale : Greek [el]\n//! author : Aggelos Karalias : https://github.com/mehiel\n\nimport moment from '../moment';\nimport isFunction from '../lib/utils/is-function';\n\nexport default moment.defineLocale('el', {\n    monthsNominativeEl : 'Ιανουάριος_Φεβρουάριος_Μάρτιος_Απρίλιος_Μάιος_Ιούνιος_Ιούλιος_Αύγουστος_Σεπτέμβριος_Οκτώβριος_Νοέμβριος_Δεκέμβριος'.split('_'),\n    monthsGenitiveEl : 'Ιανουαρίου_Φεβρουαρίου_Μαρτίου_Απριλίου_Μαΐου_Ιουνίου_Ιουλίου_Αυγούστου_Σεπτεμβρίου_Οκτωβρίου_Νοεμβρίου_Δεκεμβρίου'.split('_'),\n    months : function (momentToFormat, format) {\n        if (!momentToFormat) {\n            return this._monthsNominativeEl;\n        } else if (/D/.test(format.substring(0, format.indexOf('MMMM')))) { // if there is a day number before 'MMMM'\n            return this._monthsGenitiveEl[momentToFormat.month()];\n        } else {\n            return this._monthsNominativeEl[momentToFormat.month()];\n        }\n    },\n    monthsShort : 'Ιαν_Φεβ_Μαρ_Απρ_Μαϊ_Ιουν_Ιουλ_Αυγ_Σεπ_Οκτ_Νοε_Δεκ'.split('_'),\n    weekdays : 'Κυριακή_Δευτέρα_Τρίτη_Τετάρτη_Πέμπτη_Παρασκευή_Σάββατο'.split('_'),\n    weekdaysShort : 'Κυρ_Δευ_Τρι_Τετ_Πεμ_Παρ_Σαβ'.split('_'),\n    weekdaysMin : 'Κυ_Δε_Τρ_Τε_Πε_Πα_Σα'.split('_'),\n    meridiem : function (hours, minutes, isLower) {\n        if (hours > 11) {\n            return isLower ? 'μμ' : 'ΜΜ';\n        } else {\n            return isLower ? 'πμ' : 'ΠΜ';\n        }\n    },\n    isPM : function (input) {\n        return ((input + '').toLowerCase()[0] === 'μ');\n    },\n    meridiemParse : /[ΠΜ]\\.?Μ?\\.?/i,\n    longDateFormat : {\n        LT : 'h:mm A',\n        LTS : 'h:mm:ss A',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY h:mm A',\n        LLLL : 'dddd, D MMMM YYYY h:mm A'\n    },\n    calendarEl : {\n        sameDay : '[Σήμερα {}] LT',\n        nextDay : '[Αύριο {}] LT',\n        nextWeek : 'dddd [{}] LT',\n        lastDay : '[Χθες {}] LT',\n        lastWeek : function () {\n            switch (this.day()) {\n                case 6:\n                    return '[το προηγούμενο] dddd [{}] LT';\n                default:\n                    return '[την προηγούμενη] dddd [{}] LT';\n            }\n        },\n        sameElse : 'L'\n    },\n    calendar : function (key, mom) {\n        var output = this._calendarEl[key],\n            hours = mom && mom.hours();\n        if (isFunction(output)) {\n            output = output.apply(mom);\n        }\n        return output.replace('{}', (hours % 12 === 1 ? 'στη' : 'στις'));\n    },\n    relativeTime : {\n        future : 'σε %s',\n        past : '%s πριν',\n        s : 'λίγα δευτερόλεπτα',\n        m : 'ένα λεπτό',\n        mm : '%d λεπτά',\n        h : 'μία ώρα',\n        hh : '%d ώρες',\n        d : 'μία μέρα',\n        dd : '%d μέρες',\n        M : 'ένας μήνας',\n        MM : '%d μήνες',\n        y : 'ένας χρόνος',\n        yy : '%d χρόνια'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}η/,\n    ordinal: '%dη',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4st is the first week of the year.\n    }\n});\n\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/locale/en-au.js",
    "content": "//! moment.js locale configuration\n//! locale : English (Australia) [en-au]\n//! author : Jared Morse : https://github.com/jarcoal\n\nimport moment from '../moment';\n\nexport default moment.defineLocale('en-au', {\n    months : 'January_February_March_April_May_June_July_August_September_October_November_December'.split('_'),\n    monthsShort : 'Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec'.split('_'),\n    weekdays : 'Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday'.split('_'),\n    weekdaysShort : 'Sun_Mon_Tue_Wed_Thu_Fri_Sat'.split('_'),\n    weekdaysMin : 'Su_Mo_Tu_We_Th_Fr_Sa'.split('_'),\n    longDateFormat : {\n        LT : 'h:mm A',\n        LTS : 'h:mm:ss A',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY h:mm A',\n        LLLL : 'dddd, D MMMM YYYY h:mm A'\n    },\n    calendar : {\n        sameDay : '[Today at] LT',\n        nextDay : '[Tomorrow at] LT',\n        nextWeek : 'dddd [at] LT',\n        lastDay : '[Yesterday at] LT',\n        lastWeek : '[Last] dddd [at] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'in %s',\n        past : '%s ago',\n        s : 'a few seconds',\n        m : 'a minute',\n        mm : '%d minutes',\n        h : 'an hour',\n        hh : '%d hours',\n        d : 'a day',\n        dd : '%d days',\n        M : 'a month',\n        MM : '%d months',\n        y : 'a year',\n        yy : '%d years'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}(st|nd|rd|th)/,\n    ordinal : function (number) {\n        var b = number % 10,\n            output = (~~(number % 100 / 10) === 1) ? 'th' :\n            (b === 1) ? 'st' :\n            (b === 2) ? 'nd' :\n            (b === 3) ? 'rd' : 'th';\n        return number + output;\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/locale/en-ca.js",
    "content": "//! moment.js locale configuration\n//! locale : English (Canada) [en-ca]\n//! author : Jonathan Abourbih : https://github.com/jonbca\n\nimport moment from '../moment';\n\nexport default moment.defineLocale('en-ca', {\n    months : 'January_February_March_April_May_June_July_August_September_October_November_December'.split('_'),\n    monthsShort : 'Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec'.split('_'),\n    weekdays : 'Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday'.split('_'),\n    weekdaysShort : 'Sun_Mon_Tue_Wed_Thu_Fri_Sat'.split('_'),\n    weekdaysMin : 'Su_Mo_Tu_We_Th_Fr_Sa'.split('_'),\n    longDateFormat : {\n        LT : 'h:mm A',\n        LTS : 'h:mm:ss A',\n        L : 'YYYY-MM-DD',\n        LL : 'MMMM D, YYYY',\n        LLL : 'MMMM D, YYYY h:mm A',\n        LLLL : 'dddd, MMMM D, YYYY h:mm A'\n    },\n    calendar : {\n        sameDay : '[Today at] LT',\n        nextDay : '[Tomorrow at] LT',\n        nextWeek : 'dddd [at] LT',\n        lastDay : '[Yesterday at] LT',\n        lastWeek : '[Last] dddd [at] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'in %s',\n        past : '%s ago',\n        s : 'a few seconds',\n        m : 'a minute',\n        mm : '%d minutes',\n        h : 'an hour',\n        hh : '%d hours',\n        d : 'a day',\n        dd : '%d days',\n        M : 'a month',\n        MM : '%d months',\n        y : 'a year',\n        yy : '%d years'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}(st|nd|rd|th)/,\n    ordinal : function (number) {\n        var b = number % 10,\n            output = (~~(number % 100 / 10) === 1) ? 'th' :\n            (b === 1) ? 'st' :\n            (b === 2) ? 'nd' :\n            (b === 3) ? 'rd' : 'th';\n        return number + output;\n    }\n});\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/locale/en-gb.js",
    "content": "//! moment.js locale configuration\n//! locale : English (United Kingdom) [en-gb]\n//! author : Chris Gedrim : https://github.com/chrisgedrim\n\nimport moment from '../moment';\n\nexport default moment.defineLocale('en-gb', {\n    months : 'January_February_March_April_May_June_July_August_September_October_November_December'.split('_'),\n    monthsShort : 'Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec'.split('_'),\n    weekdays : 'Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday'.split('_'),\n    weekdaysShort : 'Sun_Mon_Tue_Wed_Thu_Fri_Sat'.split('_'),\n    weekdaysMin : 'Su_Mo_Tu_We_Th_Fr_Sa'.split('_'),\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY HH:mm',\n        LLLL : 'dddd, D MMMM YYYY HH:mm'\n    },\n    calendar : {\n        sameDay : '[Today at] LT',\n        nextDay : '[Tomorrow at] LT',\n        nextWeek : 'dddd [at] LT',\n        lastDay : '[Yesterday at] LT',\n        lastWeek : '[Last] dddd [at] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'in %s',\n        past : '%s ago',\n        s : 'a few seconds',\n        m : 'a minute',\n        mm : '%d minutes',\n        h : 'an hour',\n        hh : '%d hours',\n        d : 'a day',\n        dd : '%d days',\n        M : 'a month',\n        MM : '%d months',\n        y : 'a year',\n        yy : '%d years'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}(st|nd|rd|th)/,\n    ordinal : function (number) {\n        var b = number % 10,\n            output = (~~(number % 100 / 10) === 1) ? 'th' :\n            (b === 1) ? 'st' :\n            (b === 2) ? 'nd' :\n            (b === 3) ? 'rd' : 'th';\n        return number + output;\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/locale/en-ie.js",
    "content": "//! moment.js locale configuration\n//! locale : English (Ireland) [en-ie]\n//! author : Chris Cartlidge : https://github.com/chriscartlidge\n\nimport moment from '../moment';\n\nexport default moment.defineLocale('en-ie', {\n    months : 'January_February_March_April_May_June_July_August_September_October_November_December'.split('_'),\n    monthsShort : 'Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec'.split('_'),\n    weekdays : 'Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday'.split('_'),\n    weekdaysShort : 'Sun_Mon_Tue_Wed_Thu_Fri_Sat'.split('_'),\n    weekdaysMin : 'Su_Mo_Tu_We_Th_Fr_Sa'.split('_'),\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD-MM-YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY HH:mm',\n        LLLL : 'dddd D MMMM YYYY HH:mm'\n    },\n    calendar : {\n        sameDay : '[Today at] LT',\n        nextDay : '[Tomorrow at] LT',\n        nextWeek : 'dddd [at] LT',\n        lastDay : '[Yesterday at] LT',\n        lastWeek : '[Last] dddd [at] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'in %s',\n        past : '%s ago',\n        s : 'a few seconds',\n        m : 'a minute',\n        mm : '%d minutes',\n        h : 'an hour',\n        hh : '%d hours',\n        d : 'a day',\n        dd : '%d days',\n        M : 'a month',\n        MM : '%d months',\n        y : 'a year',\n        yy : '%d years'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}(st|nd|rd|th)/,\n    ordinal : function (number) {\n        var b = number % 10,\n            output = (~~(number % 100 / 10) === 1) ? 'th' :\n            (b === 1) ? 'st' :\n            (b === 2) ? 'nd' :\n            (b === 3) ? 'rd' : 'th';\n        return number + output;\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/locale/en-nz.js",
    "content": "//! moment.js locale configuration\n//! locale : English (New Zealand) [en-nz]\n//! author : Luke McGregor : https://github.com/lukemcgregor\n\nimport moment from '../moment';\n\nexport default moment.defineLocale('en-nz', {\n    months : 'January_February_March_April_May_June_July_August_September_October_November_December'.split('_'),\n    monthsShort : 'Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec'.split('_'),\n    weekdays : 'Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday'.split('_'),\n    weekdaysShort : 'Sun_Mon_Tue_Wed_Thu_Fri_Sat'.split('_'),\n    weekdaysMin : 'Su_Mo_Tu_We_Th_Fr_Sa'.split('_'),\n    longDateFormat : {\n        LT : 'h:mm A',\n        LTS : 'h:mm:ss A',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY h:mm A',\n        LLLL : 'dddd, D MMMM YYYY h:mm A'\n    },\n    calendar : {\n        sameDay : '[Today at] LT',\n        nextDay : '[Tomorrow at] LT',\n        nextWeek : 'dddd [at] LT',\n        lastDay : '[Yesterday at] LT',\n        lastWeek : '[Last] dddd [at] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'in %s',\n        past : '%s ago',\n        s : 'a few seconds',\n        m : 'a minute',\n        mm : '%d minutes',\n        h : 'an hour',\n        hh : '%d hours',\n        d : 'a day',\n        dd : '%d days',\n        M : 'a month',\n        MM : '%d months',\n        y : 'a year',\n        yy : '%d years'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}(st|nd|rd|th)/,\n    ordinal : function (number) {\n        var b = number % 10,\n            output = (~~(number % 100 / 10) === 1) ? 'th' :\n            (b === 1) ? 'st' :\n            (b === 2) ? 'nd' :\n            (b === 3) ? 'rd' : 'th';\n        return number + output;\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/locale/eo.js",
    "content": "//! moment.js locale configuration\n//! locale : Esperanto [eo]\n//! author : Colin Dean : https://github.com/colindean\n//! author : Mia Nordentoft Imperatori : https://github.com/miestasmia\n//! comment : miestasmia corrected the translation by colindean\n\nimport moment from '../moment';\n\nexport default moment.defineLocale('eo', {\n    months : 'januaro_februaro_marto_aprilo_majo_junio_julio_aŭgusto_septembro_oktobro_novembro_decembro'.split('_'),\n    monthsShort : 'jan_feb_mar_apr_maj_jun_jul_aŭg_sep_okt_nov_dec'.split('_'),\n    weekdays : 'dimanĉo_lundo_mardo_merkredo_ĵaŭdo_vendredo_sabato'.split('_'),\n    weekdaysShort : 'dim_lun_mard_merk_ĵaŭ_ven_sab'.split('_'),\n    weekdaysMin : 'di_lu_ma_me_ĵa_ve_sa'.split('_'),\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'YYYY-MM-DD',\n        LL : 'D[-a de] MMMM, YYYY',\n        LLL : 'D[-a de] MMMM, YYYY HH:mm',\n        LLLL : 'dddd, [la] D[-a de] MMMM, YYYY HH:mm'\n    },\n    meridiemParse: /[ap]\\.t\\.m/i,\n    isPM: function (input) {\n        return input.charAt(0).toLowerCase() === 'p';\n    },\n    meridiem : function (hours, minutes, isLower) {\n        if (hours > 11) {\n            return isLower ? 'p.t.m.' : 'P.T.M.';\n        } else {\n            return isLower ? 'a.t.m.' : 'A.T.M.';\n        }\n    },\n    calendar : {\n        sameDay : '[Hodiaŭ je] LT',\n        nextDay : '[Morgaŭ je] LT',\n        nextWeek : 'dddd [je] LT',\n        lastDay : '[Hieraŭ je] LT',\n        lastWeek : '[pasinta] dddd [je] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'post %s',\n        past : 'antaŭ %s',\n        s : 'sekundoj',\n        m : 'minuto',\n        mm : '%d minutoj',\n        h : 'horo',\n        hh : '%d horoj',\n        d : 'tago',//ne 'diurno', ĉar estas uzita por proksimumo\n        dd : '%d tagoj',\n        M : 'monato',\n        MM : '%d monatoj',\n        y : 'jaro',\n        yy : '%d jaroj'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}a/,\n    ordinal : '%da',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 7  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/locale/es-do.js",
    "content": "//! moment.js locale configuration\n//! locale : Spanish (Dominican Republic) [es-do]\n\nimport moment from '../moment';\n\nvar monthsShortDot = 'ene._feb._mar._abr._may._jun._jul._ago._sep._oct._nov._dic.'.split('_'),\n    monthsShort = 'ene_feb_mar_abr_may_jun_jul_ago_sep_oct_nov_dic'.split('_');\n\nexport default moment.defineLocale('es-do', {\n    months : 'enero_febrero_marzo_abril_mayo_junio_julio_agosto_septiembre_octubre_noviembre_diciembre'.split('_'),\n    monthsShort : function (m, format) {\n        if (!m) {\n            return monthsShortDot;\n        } else if (/-MMM-/.test(format)) {\n            return monthsShort[m.month()];\n        } else {\n            return monthsShortDot[m.month()];\n        }\n    },\n    monthsParseExact : true,\n    weekdays : 'domingo_lunes_martes_miércoles_jueves_viernes_sábado'.split('_'),\n    weekdaysShort : 'dom._lun._mar._mié._jue._vie._sáb.'.split('_'),\n    weekdaysMin : 'do_lu_ma_mi_ju_vi_sá'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat : {\n        LT : 'h:mm A',\n        LTS : 'h:mm:ss A',\n        L : 'DD/MM/YYYY',\n        LL : 'D [de] MMMM [de] YYYY',\n        LLL : 'D [de] MMMM [de] YYYY h:mm A',\n        LLLL : 'dddd, D [de] MMMM [de] YYYY h:mm A'\n    },\n    calendar : {\n        sameDay : function () {\n            return '[hoy a la' + ((this.hours() !== 1) ? 's' : '') + '] LT';\n        },\n        nextDay : function () {\n            return '[mañana a la' + ((this.hours() !== 1) ? 's' : '') + '] LT';\n        },\n        nextWeek : function () {\n            return 'dddd [a la' + ((this.hours() !== 1) ? 's' : '') + '] LT';\n        },\n        lastDay : function () {\n            return '[ayer a la' + ((this.hours() !== 1) ? 's' : '') + '] LT';\n        },\n        lastWeek : function () {\n            return '[el] dddd [pasado a la' + ((this.hours() !== 1) ? 's' : '') + '] LT';\n        },\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'en %s',\n        past : 'hace %s',\n        s : 'unos segundos',\n        m : 'un minuto',\n        mm : '%d minutos',\n        h : 'una hora',\n        hh : '%d horas',\n        d : 'un día',\n        dd : '%d días',\n        M : 'un mes',\n        MM : '%d meses',\n        y : 'un año',\n        yy : '%d años'\n    },\n    dayOfMonthOrdinalParse : /\\d{1,2}º/,\n    ordinal : '%dº',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/locale/es.js",
    "content": "//! moment.js locale configuration\n//! locale : Spanish [es]\n//! author : Julio Napurí : https://github.com/julionc\n\nimport moment from '../moment';\n\nvar monthsShortDot = 'ene._feb._mar._abr._may._jun._jul._ago._sep._oct._nov._dic.'.split('_'),\n    monthsShort = 'ene_feb_mar_abr_may_jun_jul_ago_sep_oct_nov_dic'.split('_');\n\nexport default moment.defineLocale('es', {\n    months : 'enero_febrero_marzo_abril_mayo_junio_julio_agosto_septiembre_octubre_noviembre_diciembre'.split('_'),\n    monthsShort : function (m, format) {\n        if (!m) {\n            return monthsShortDot;\n        } else if (/-MMM-/.test(format)) {\n            return monthsShort[m.month()];\n        } else {\n            return monthsShortDot[m.month()];\n        }\n    },\n    monthsParseExact : true,\n    weekdays : 'domingo_lunes_martes_miércoles_jueves_viernes_sábado'.split('_'),\n    weekdaysShort : 'dom._lun._mar._mié._jue._vie._sáb.'.split('_'),\n    weekdaysMin : 'do_lu_ma_mi_ju_vi_sá'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat : {\n        LT : 'H:mm',\n        LTS : 'H:mm:ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D [de] MMMM [de] YYYY',\n        LLL : 'D [de] MMMM [de] YYYY H:mm',\n        LLLL : 'dddd, D [de] MMMM [de] YYYY H:mm'\n    },\n    calendar : {\n        sameDay : function () {\n            return '[hoy a la' + ((this.hours() !== 1) ? 's' : '') + '] LT';\n        },\n        nextDay : function () {\n            return '[mañana a la' + ((this.hours() !== 1) ? 's' : '') + '] LT';\n        },\n        nextWeek : function () {\n            return 'dddd [a la' + ((this.hours() !== 1) ? 's' : '') + '] LT';\n        },\n        lastDay : function () {\n            return '[ayer a la' + ((this.hours() !== 1) ? 's' : '') + '] LT';\n        },\n        lastWeek : function () {\n            return '[el] dddd [pasado a la' + ((this.hours() !== 1) ? 's' : '') + '] LT';\n        },\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'en %s',\n        past : 'hace %s',\n        s : 'unos segundos',\n        m : 'un minuto',\n        mm : '%d minutos',\n        h : 'una hora',\n        hh : '%d horas',\n        d : 'un día',\n        dd : '%d días',\n        M : 'un mes',\n        MM : '%d meses',\n        y : 'un año',\n        yy : '%d años'\n    },\n    dayOfMonthOrdinalParse : /\\d{1,2}º/,\n    ordinal : '%dº',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/locale/et.js",
    "content": "//! moment.js locale configuration\n//! locale : Estonian [et]\n//! author : Henry Kehlmann : https://github.com/madhenry\n//! improvements : Illimar Tambek : https://github.com/ragulka\n\nimport moment from '../moment';\n\nfunction processRelativeTime(number, withoutSuffix, key, isFuture) {\n    var format = {\n        's' : ['mõne sekundi', 'mõni sekund', 'paar sekundit'],\n        'm' : ['ühe minuti', 'üks minut'],\n        'mm': [number + ' minuti', number + ' minutit'],\n        'h' : ['ühe tunni', 'tund aega', 'üks tund'],\n        'hh': [number + ' tunni', number + ' tundi'],\n        'd' : ['ühe päeva', 'üks päev'],\n        'M' : ['kuu aja', 'kuu aega', 'üks kuu'],\n        'MM': [number + ' kuu', number + ' kuud'],\n        'y' : ['ühe aasta', 'aasta', 'üks aasta'],\n        'yy': [number + ' aasta', number + ' aastat']\n    };\n    if (withoutSuffix) {\n        return format[key][2] ? format[key][2] : format[key][1];\n    }\n    return isFuture ? format[key][0] : format[key][1];\n}\n\nexport default moment.defineLocale('et', {\n    months        : 'jaanuar_veebruar_märts_aprill_mai_juuni_juuli_august_september_oktoober_november_detsember'.split('_'),\n    monthsShort   : 'jaan_veebr_märts_apr_mai_juuni_juuli_aug_sept_okt_nov_dets'.split('_'),\n    weekdays      : 'pühapäev_esmaspäev_teisipäev_kolmapäev_neljapäev_reede_laupäev'.split('_'),\n    weekdaysShort : 'P_E_T_K_N_R_L'.split('_'),\n    weekdaysMin   : 'P_E_T_K_N_R_L'.split('_'),\n    longDateFormat : {\n        LT   : 'H:mm',\n        LTS : 'H:mm:ss',\n        L    : 'DD.MM.YYYY',\n        LL   : 'D. MMMM YYYY',\n        LLL  : 'D. MMMM YYYY H:mm',\n        LLLL : 'dddd, D. MMMM YYYY H:mm'\n    },\n    calendar : {\n        sameDay  : '[Täna,] LT',\n        nextDay  : '[Homme,] LT',\n        nextWeek : '[Järgmine] dddd LT',\n        lastDay  : '[Eile,] LT',\n        lastWeek : '[Eelmine] dddd LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : '%s pärast',\n        past   : '%s tagasi',\n        s      : processRelativeTime,\n        m      : processRelativeTime,\n        mm     : processRelativeTime,\n        h      : processRelativeTime,\n        hh     : processRelativeTime,\n        d      : processRelativeTime,\n        dd     : '%d päeva',\n        M      : processRelativeTime,\n        MM     : processRelativeTime,\n        y      : processRelativeTime,\n        yy     : processRelativeTime\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}\\./,\n    ordinal : '%d.',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/locale/eu.js",
    "content": "//! moment.js locale configuration\n//! locale : Basque [eu]\n//! author : Eneko Illarramendi : https://github.com/eillarra\n\nimport moment from '../moment';\n\nexport default moment.defineLocale('eu', {\n    months : 'urtarrila_otsaila_martxoa_apirila_maiatza_ekaina_uztaila_abuztua_iraila_urria_azaroa_abendua'.split('_'),\n    monthsShort : 'urt._ots._mar._api._mai._eka._uzt._abu._ira._urr._aza._abe.'.split('_'),\n    monthsParseExact : true,\n    weekdays : 'igandea_astelehena_asteartea_asteazkena_osteguna_ostirala_larunbata'.split('_'),\n    weekdaysShort : 'ig._al._ar._az._og._ol._lr.'.split('_'),\n    weekdaysMin : 'ig_al_ar_az_og_ol_lr'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'YYYY-MM-DD',\n        LL : 'YYYY[ko] MMMM[ren] D[a]',\n        LLL : 'YYYY[ko] MMMM[ren] D[a] HH:mm',\n        LLLL : 'dddd, YYYY[ko] MMMM[ren] D[a] HH:mm',\n        l : 'YYYY-M-D',\n        ll : 'YYYY[ko] MMM D[a]',\n        lll : 'YYYY[ko] MMM D[a] HH:mm',\n        llll : 'ddd, YYYY[ko] MMM D[a] HH:mm'\n    },\n    calendar : {\n        sameDay : '[gaur] LT[etan]',\n        nextDay : '[bihar] LT[etan]',\n        nextWeek : 'dddd LT[etan]',\n        lastDay : '[atzo] LT[etan]',\n        lastWeek : '[aurreko] dddd LT[etan]',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : '%s barru',\n        past : 'duela %s',\n        s : 'segundo batzuk',\n        m : 'minutu bat',\n        mm : '%d minutu',\n        h : 'ordu bat',\n        hh : '%d ordu',\n        d : 'egun bat',\n        dd : '%d egun',\n        M : 'hilabete bat',\n        MM : '%d hilabete',\n        y : 'urte bat',\n        yy : '%d urte'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}\\./,\n    ordinal : '%d.',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 7  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/locale/fa.js",
    "content": "//! moment.js locale configuration\n//! locale : Persian [fa]\n//! author : Ebrahim Byagowi : https://github.com/ebraminio\n\nimport moment from '../moment';\n\nvar symbolMap = {\n    '1': '۱',\n    '2': '۲',\n    '3': '۳',\n    '4': '۴',\n    '5': '۵',\n    '6': '۶',\n    '7': '۷',\n    '8': '۸',\n    '9': '۹',\n    '0': '۰'\n}, numberMap = {\n    '۱': '1',\n    '۲': '2',\n    '۳': '3',\n    '۴': '4',\n    '۵': '5',\n    '۶': '6',\n    '۷': '7',\n    '۸': '8',\n    '۹': '9',\n    '۰': '0'\n};\n\nexport default moment.defineLocale('fa', {\n    months : 'ژانویه_فوریه_مارس_آوریل_مه_ژوئن_ژوئیه_اوت_سپتامبر_اکتبر_نوامبر_دسامبر'.split('_'),\n    monthsShort : 'ژانویه_فوریه_مارس_آوریل_مه_ژوئن_ژوئیه_اوت_سپتامبر_اکتبر_نوامبر_دسامبر'.split('_'),\n    weekdays : 'یک\\u200cشنبه_دوشنبه_سه\\u200cشنبه_چهارشنبه_پنج\\u200cشنبه_جمعه_شنبه'.split('_'),\n    weekdaysShort : 'یک\\u200cشنبه_دوشنبه_سه\\u200cشنبه_چهارشنبه_پنج\\u200cشنبه_جمعه_شنبه'.split('_'),\n    weekdaysMin : 'ی_د_س_چ_پ_ج_ش'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY HH:mm',\n        LLLL : 'dddd, D MMMM YYYY HH:mm'\n    },\n    meridiemParse: /قبل از ظهر|بعد از ظهر/,\n    isPM: function (input) {\n        return /بعد از ظهر/.test(input);\n    },\n    meridiem : function (hour, minute, isLower) {\n        if (hour < 12) {\n            return 'قبل از ظهر';\n        } else {\n            return 'بعد از ظهر';\n        }\n    },\n    calendar : {\n        sameDay : '[امروز ساعت] LT',\n        nextDay : '[فردا ساعت] LT',\n        nextWeek : 'dddd [ساعت] LT',\n        lastDay : '[دیروز ساعت] LT',\n        lastWeek : 'dddd [پیش] [ساعت] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'در %s',\n        past : '%s پیش',\n        s : 'چند ثانیه',\n        m : 'یک دقیقه',\n        mm : '%d دقیقه',\n        h : 'یک ساعت',\n        hh : '%d ساعت',\n        d : 'یک روز',\n        dd : '%d روز',\n        M : 'یک ماه',\n        MM : '%d ماه',\n        y : 'یک سال',\n        yy : '%d سال'\n    },\n    preparse: function (string) {\n        return string.replace(/[۰-۹]/g, function (match) {\n            return numberMap[match];\n        }).replace(/،/g, ',');\n    },\n    postformat: function (string) {\n        return string.replace(/\\d/g, function (match) {\n            return symbolMap[match];\n        }).replace(/,/g, '،');\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}م/,\n    ordinal : '%dم',\n    week : {\n        dow : 6, // Saturday is the first day of the week.\n        doy : 12 // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/locale/fi.js",
    "content": "//! moment.js locale configuration\n//! locale : Finnish [fi]\n//! author : Tarmo Aidantausta : https://github.com/bleadof\n\nimport moment from '../moment';\n\nvar numbersPast = 'nolla yksi kaksi kolme neljä viisi kuusi seitsemän kahdeksan yhdeksän'.split(' '),\n    numbersFuture = [\n        'nolla', 'yhden', 'kahden', 'kolmen', 'neljän', 'viiden', 'kuuden',\n        numbersPast[7], numbersPast[8], numbersPast[9]\n    ];\nfunction translate(number, withoutSuffix, key, isFuture) {\n    var result = '';\n    switch (key) {\n        case 's':\n            return isFuture ? 'muutaman sekunnin' : 'muutama sekunti';\n        case 'm':\n            return isFuture ? 'minuutin' : 'minuutti';\n        case 'mm':\n            result = isFuture ? 'minuutin' : 'minuuttia';\n            break;\n        case 'h':\n            return isFuture ? 'tunnin' : 'tunti';\n        case 'hh':\n            result = isFuture ? 'tunnin' : 'tuntia';\n            break;\n        case 'd':\n            return isFuture ? 'päivän' : 'päivä';\n        case 'dd':\n            result = isFuture ? 'päivän' : 'päivää';\n            break;\n        case 'M':\n            return isFuture ? 'kuukauden' : 'kuukausi';\n        case 'MM':\n            result = isFuture ? 'kuukauden' : 'kuukautta';\n            break;\n        case 'y':\n            return isFuture ? 'vuoden' : 'vuosi';\n        case 'yy':\n            result = isFuture ? 'vuoden' : 'vuotta';\n            break;\n    }\n    result = verbalNumber(number, isFuture) + ' ' + result;\n    return result;\n}\nfunction verbalNumber(number, isFuture) {\n    return number < 10 ? (isFuture ? numbersFuture[number] : numbersPast[number]) : number;\n}\n\nexport default moment.defineLocale('fi', {\n    months : 'tammikuu_helmikuu_maaliskuu_huhtikuu_toukokuu_kesäkuu_heinäkuu_elokuu_syyskuu_lokakuu_marraskuu_joulukuu'.split('_'),\n    monthsShort : 'tammi_helmi_maalis_huhti_touko_kesä_heinä_elo_syys_loka_marras_joulu'.split('_'),\n    weekdays : 'sunnuntai_maanantai_tiistai_keskiviikko_torstai_perjantai_lauantai'.split('_'),\n    weekdaysShort : 'su_ma_ti_ke_to_pe_la'.split('_'),\n    weekdaysMin : 'su_ma_ti_ke_to_pe_la'.split('_'),\n    longDateFormat : {\n        LT : 'HH.mm',\n        LTS : 'HH.mm.ss',\n        L : 'DD.MM.YYYY',\n        LL : 'Do MMMM[ta] YYYY',\n        LLL : 'Do MMMM[ta] YYYY, [klo] HH.mm',\n        LLLL : 'dddd, Do MMMM[ta] YYYY, [klo] HH.mm',\n        l : 'D.M.YYYY',\n        ll : 'Do MMM YYYY',\n        lll : 'Do MMM YYYY, [klo] HH.mm',\n        llll : 'ddd, Do MMM YYYY, [klo] HH.mm'\n    },\n    calendar : {\n        sameDay : '[tänään] [klo] LT',\n        nextDay : '[huomenna] [klo] LT',\n        nextWeek : 'dddd [klo] LT',\n        lastDay : '[eilen] [klo] LT',\n        lastWeek : '[viime] dddd[na] [klo] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : '%s päästä',\n        past : '%s sitten',\n        s : translate,\n        m : translate,\n        mm : translate,\n        h : translate,\n        hh : translate,\n        d : translate,\n        dd : translate,\n        M : translate,\n        MM : translate,\n        y : translate,\n        yy : translate\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}\\./,\n    ordinal : '%d.',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/locale/fo.js",
    "content": "//! moment.js locale configuration\n//! locale : Faroese [fo]\n//! author : Ragnar Johannesen : https://github.com/ragnar123\n\nimport moment from '../moment';\n\nexport default moment.defineLocale('fo', {\n    months : 'januar_februar_mars_apríl_mai_juni_juli_august_september_oktober_november_desember'.split('_'),\n    monthsShort : 'jan_feb_mar_apr_mai_jun_jul_aug_sep_okt_nov_des'.split('_'),\n    weekdays : 'sunnudagur_mánadagur_týsdagur_mikudagur_hósdagur_fríggjadagur_leygardagur'.split('_'),\n    weekdaysShort : 'sun_mán_týs_mik_hós_frí_ley'.split('_'),\n    weekdaysMin : 'su_má_tý_mi_hó_fr_le'.split('_'),\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY HH:mm',\n        LLLL : 'dddd D. MMMM, YYYY HH:mm'\n    },\n    calendar : {\n        sameDay : '[Í dag kl.] LT',\n        nextDay : '[Í morgin kl.] LT',\n        nextWeek : 'dddd [kl.] LT',\n        lastDay : '[Í gjár kl.] LT',\n        lastWeek : '[síðstu] dddd [kl] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'um %s',\n        past : '%s síðani',\n        s : 'fá sekund',\n        m : 'ein minutt',\n        mm : '%d minuttir',\n        h : 'ein tími',\n        hh : '%d tímar',\n        d : 'ein dagur',\n        dd : '%d dagar',\n        M : 'ein mánaði',\n        MM : '%d mánaðir',\n        y : 'eitt ár',\n        yy : '%d ár'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}\\./,\n    ordinal : '%d.',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/locale/fr-ca.js",
    "content": "//! moment.js locale configuration\n//! locale : French (Canada) [fr-ca]\n//! author : Jonathan Abourbih : https://github.com/jonbca\n\nimport moment from '../moment';\n\nexport default moment.defineLocale('fr-ca', {\n    months : 'janvier_février_mars_avril_mai_juin_juillet_août_septembre_octobre_novembre_décembre'.split('_'),\n    monthsShort : 'janv._févr._mars_avr._mai_juin_juil._août_sept._oct._nov._déc.'.split('_'),\n    monthsParseExact : true,\n    weekdays : 'dimanche_lundi_mardi_mercredi_jeudi_vendredi_samedi'.split('_'),\n    weekdaysShort : 'dim._lun._mar._mer._jeu._ven._sam.'.split('_'),\n    weekdaysMin : 'Di_Lu_Ma_Me_Je_Ve_Sa'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'YYYY-MM-DD',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY HH:mm',\n        LLLL : 'dddd D MMMM YYYY HH:mm'\n    },\n    calendar : {\n        sameDay : '[Aujourd’hui à] LT',\n        nextDay : '[Demain à] LT',\n        nextWeek : 'dddd [à] LT',\n        lastDay : '[Hier à] LT',\n        lastWeek : 'dddd [dernier à] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'dans %s',\n        past : 'il y a %s',\n        s : 'quelques secondes',\n        m : 'une minute',\n        mm : '%d minutes',\n        h : 'une heure',\n        hh : '%d heures',\n        d : 'un jour',\n        dd : '%d jours',\n        M : 'un mois',\n        MM : '%d mois',\n        y : 'un an',\n        yy : '%d ans'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}(er|e)/,\n    ordinal : function (number, period) {\n        switch (period) {\n            // Words with masculine grammatical gender: mois, trimestre, jour\n            default:\n            case 'M':\n            case 'Q':\n            case 'D':\n            case 'DDD':\n            case 'd':\n                return number + (number === 1 ? 'er' : 'e');\n\n            // Words with feminine grammatical gender: semaine\n            case 'w':\n            case 'W':\n                return number + (number === 1 ? 're' : 'e');\n        }\n    }\n});\n\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/locale/fr-ch.js",
    "content": "//! moment.js locale configuration\n//! locale : French (Switzerland) [fr-ch]\n//! author : Gaspard Bucher : https://github.com/gaspard\n\nimport moment from '../moment';\n\nexport default moment.defineLocale('fr-ch', {\n    months : 'janvier_février_mars_avril_mai_juin_juillet_août_septembre_octobre_novembre_décembre'.split('_'),\n    monthsShort : 'janv._févr._mars_avr._mai_juin_juil._août_sept._oct._nov._déc.'.split('_'),\n    monthsParseExact : true,\n    weekdays : 'dimanche_lundi_mardi_mercredi_jeudi_vendredi_samedi'.split('_'),\n    weekdaysShort : 'dim._lun._mar._mer._jeu._ven._sam.'.split('_'),\n    weekdaysMin : 'Di_Lu_Ma_Me_Je_Ve_Sa'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD.MM.YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY HH:mm',\n        LLLL : 'dddd D MMMM YYYY HH:mm'\n    },\n    calendar : {\n        sameDay : '[Aujourd’hui à] LT',\n        nextDay : '[Demain à] LT',\n        nextWeek : 'dddd [à] LT',\n        lastDay : '[Hier à] LT',\n        lastWeek : 'dddd [dernier à] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'dans %s',\n        past : 'il y a %s',\n        s : 'quelques secondes',\n        m : 'une minute',\n        mm : '%d minutes',\n        h : 'une heure',\n        hh : '%d heures',\n        d : 'un jour',\n        dd : '%d jours',\n        M : 'un mois',\n        MM : '%d mois',\n        y : 'un an',\n        yy : '%d ans'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}(er|e)/,\n    ordinal : function (number, period) {\n        switch (period) {\n            // Words with masculine grammatical gender: mois, trimestre, jour\n            default:\n            case 'M':\n            case 'Q':\n            case 'D':\n            case 'DDD':\n            case 'd':\n                return number + (number === 1 ? 'er' : 'e');\n\n            // Words with feminine grammatical gender: semaine\n            case 'w':\n            case 'W':\n                return number + (number === 1 ? 're' : 'e');\n        }\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/locale/fr.js",
    "content": "//! moment.js locale configuration\n//! locale : French [fr]\n//! author : John Fischer : https://github.com/jfroffice\n\nimport moment from '../moment';\n\nexport default moment.defineLocale('fr', {\n    months : 'janvier_février_mars_avril_mai_juin_juillet_août_septembre_octobre_novembre_décembre'.split('_'),\n    monthsShort : 'janv._févr._mars_avr._mai_juin_juil._août_sept._oct._nov._déc.'.split('_'),\n    monthsParseExact : true,\n    weekdays : 'dimanche_lundi_mardi_mercredi_jeudi_vendredi_samedi'.split('_'),\n    weekdaysShort : 'dim._lun._mar._mer._jeu._ven._sam.'.split('_'),\n    weekdaysMin : 'Di_Lu_Ma_Me_Je_Ve_Sa'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY HH:mm',\n        LLLL : 'dddd D MMMM YYYY HH:mm'\n    },\n    calendar : {\n        sameDay : '[Aujourd’hui à] LT',\n        nextDay : '[Demain à] LT',\n        nextWeek : 'dddd [à] LT',\n        lastDay : '[Hier à] LT',\n        lastWeek : 'dddd [dernier à] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'dans %s',\n        past : 'il y a %s',\n        s : 'quelques secondes',\n        m : 'une minute',\n        mm : '%d minutes',\n        h : 'une heure',\n        hh : '%d heures',\n        d : 'un jour',\n        dd : '%d jours',\n        M : 'un mois',\n        MM : '%d mois',\n        y : 'un an',\n        yy : '%d ans'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}(er|)/,\n    ordinal : function (number, period) {\n        switch (period) {\n            // TODO: Return 'e' when day of month > 1. Move this case inside\n            // block for masculine words below.\n            // See https://github.com/moment/moment/issues/3375\n            case 'D':\n                return number + (number === 1 ? 'er' : '');\n\n            // Words with masculine grammatical gender: mois, trimestre, jour\n            default:\n            case 'M':\n            case 'Q':\n            case 'DDD':\n            case 'd':\n                return number + (number === 1 ? 'er' : 'e');\n\n            // Words with feminine grammatical gender: semaine\n            case 'w':\n            case 'W':\n                return number + (number === 1 ? 're' : 'e');\n        }\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/locale/fy.js",
    "content": "//! moment.js locale configuration\n//! locale : Frisian [fy]\n//! author : Robin van der Vliet : https://github.com/robin0van0der0v\n\nimport moment from '../moment';\n\nvar monthsShortWithDots = 'jan._feb._mrt._apr._mai_jun._jul._aug._sep._okt._nov._des.'.split('_'),\n    monthsShortWithoutDots = 'jan_feb_mrt_apr_mai_jun_jul_aug_sep_okt_nov_des'.split('_');\n\nexport default moment.defineLocale('fy', {\n    months : 'jannewaris_febrewaris_maart_april_maaie_juny_july_augustus_septimber_oktober_novimber_desimber'.split('_'),\n    monthsShort : function (m, format) {\n        if (!m) {\n            return monthsShortWithDots;\n        } else if (/-MMM-/.test(format)) {\n            return monthsShortWithoutDots[m.month()];\n        } else {\n            return monthsShortWithDots[m.month()];\n        }\n    },\n    monthsParseExact : true,\n    weekdays : 'snein_moandei_tiisdei_woansdei_tongersdei_freed_sneon'.split('_'),\n    weekdaysShort : 'si._mo._ti._wo._to._fr._so.'.split('_'),\n    weekdaysMin : 'Si_Mo_Ti_Wo_To_Fr_So'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD-MM-YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY HH:mm',\n        LLLL : 'dddd D MMMM YYYY HH:mm'\n    },\n    calendar : {\n        sameDay: '[hjoed om] LT',\n        nextDay: '[moarn om] LT',\n        nextWeek: 'dddd [om] LT',\n        lastDay: '[juster om] LT',\n        lastWeek: '[ôfrûne] dddd [om] LT',\n        sameElse: 'L'\n    },\n    relativeTime : {\n        future : 'oer %s',\n        past : '%s lyn',\n        s : 'in pear sekonden',\n        m : 'ien minút',\n        mm : '%d minuten',\n        h : 'ien oere',\n        hh : '%d oeren',\n        d : 'ien dei',\n        dd : '%d dagen',\n        M : 'ien moanne',\n        MM : '%d moannen',\n        y : 'ien jier',\n        yy : '%d jierren'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}(ste|de)/,\n    ordinal : function (number) {\n        return number + ((number === 1 || number === 8 || number >= 20) ? 'ste' : 'de');\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/locale/gd.js",
    "content": "//! moment.js locale configuration\n//! locale : Scottish Gaelic [gd]\n//! author : Jon Ashdown : https://github.com/jonashdown\n\nimport moment from '../moment';\n\nvar months = [\n    'Am Faoilleach', 'An Gearran', 'Am Màrt', 'An Giblean', 'An Cèitean', 'An t-Ògmhios', 'An t-Iuchar', 'An Lùnastal', 'An t-Sultain', 'An Dàmhair', 'An t-Samhain', 'An Dùbhlachd'\n];\n\nvar monthsShort = ['Faoi', 'Gear', 'Màrt', 'Gibl', 'Cèit', 'Ògmh', 'Iuch', 'Lùn', 'Sult', 'Dàmh', 'Samh', 'Dùbh'];\n\nvar weekdays = ['Didòmhnaich', 'Diluain', 'Dimàirt', 'Diciadain', 'Diardaoin', 'Dihaoine', 'Disathairne'];\n\nvar weekdaysShort = ['Did', 'Dil', 'Dim', 'Dic', 'Dia', 'Dih', 'Dis'];\n\nvar weekdaysMin = ['Dò', 'Lu', 'Mà', 'Ci', 'Ar', 'Ha', 'Sa'];\n\nexport default moment.defineLocale('gd', {\n    months : months,\n    monthsShort : monthsShort,\n    monthsParseExact : true,\n    weekdays : weekdays,\n    weekdaysShort : weekdaysShort,\n    weekdaysMin : weekdaysMin,\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY HH:mm',\n        LLLL : 'dddd, D MMMM YYYY HH:mm'\n    },\n    calendar : {\n        sameDay : '[An-diugh aig] LT',\n        nextDay : '[A-màireach aig] LT',\n        nextWeek : 'dddd [aig] LT',\n        lastDay : '[An-dè aig] LT',\n        lastWeek : 'dddd [seo chaidh] [aig] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'ann an %s',\n        past : 'bho chionn %s',\n        s : 'beagan diogan',\n        m : 'mionaid',\n        mm : '%d mionaidean',\n        h : 'uair',\n        hh : '%d uairean',\n        d : 'latha',\n        dd : '%d latha',\n        M : 'mìos',\n        MM : '%d mìosan',\n        y : 'bliadhna',\n        yy : '%d bliadhna'\n    },\n    dayOfMonthOrdinalParse : /\\d{1,2}(d|na|mh)/,\n    ordinal : function (number) {\n        var output = number === 1 ? 'd' : number % 10 === 2 ? 'na' : 'mh';\n        return number + output;\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/locale/gl.js",
    "content": "//! moment.js locale configuration\n//! locale : Galician [gl]\n//! author : Juan G. Hurtado : https://github.com/juanghurtado\n\nimport moment from '../moment';\n\nexport default moment.defineLocale('gl', {\n    months : 'xaneiro_febreiro_marzo_abril_maio_xuño_xullo_agosto_setembro_outubro_novembro_decembro'.split('_'),\n    monthsShort : 'xan._feb._mar._abr._mai._xuñ._xul._ago._set._out._nov._dec.'.split('_'),\n    monthsParseExact: true,\n    weekdays : 'domingo_luns_martes_mércores_xoves_venres_sábado'.split('_'),\n    weekdaysShort : 'dom._lun._mar._mér._xov._ven._sáb.'.split('_'),\n    weekdaysMin : 'do_lu_ma_mé_xo_ve_sá'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat : {\n        LT : 'H:mm',\n        LTS : 'H:mm:ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D [de] MMMM [de] YYYY',\n        LLL : 'D [de] MMMM [de] YYYY H:mm',\n        LLLL : 'dddd, D [de] MMMM [de] YYYY H:mm'\n    },\n    calendar : {\n        sameDay : function () {\n            return '[hoxe ' + ((this.hours() !== 1) ? 'ás' : 'á') + '] LT';\n        },\n        nextDay : function () {\n            return '[mañá ' + ((this.hours() !== 1) ? 'ás' : 'á') + '] LT';\n        },\n        nextWeek : function () {\n            return 'dddd [' + ((this.hours() !== 1) ? 'ás' : 'a') + '] LT';\n        },\n        lastDay : function () {\n            return '[onte ' + ((this.hours() !== 1) ? 'á' : 'a') + '] LT';\n        },\n        lastWeek : function () {\n            return '[o] dddd [pasado ' + ((this.hours() !== 1) ? 'ás' : 'a') + '] LT';\n        },\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : function (str) {\n            if (str.indexOf('un') === 0) {\n                return 'n' + str;\n            }\n            return 'en ' + str;\n        },\n        past : 'hai %s',\n        s : 'uns segundos',\n        m : 'un minuto',\n        mm : '%d minutos',\n        h : 'unha hora',\n        hh : '%d horas',\n        d : 'un día',\n        dd : '%d días',\n        M : 'un mes',\n        MM : '%d meses',\n        y : 'un ano',\n        yy : '%d anos'\n    },\n    dayOfMonthOrdinalParse : /\\d{1,2}º/,\n    ordinal : '%dº',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/locale/gom-latn.js",
    "content": "//! moment.js locale configuration\n//! locale : Konkani Latin script [gom-latn]\n//! author : The Discoverer : https://github.com/WikiDiscoverer\n\nimport moment from '../moment';\n\nfunction processRelativeTime(number, withoutSuffix, key, isFuture) {\n    var format = {\n        's': ['thodde secondanim', 'thodde second'],\n        'm': ['eka mintan', 'ek minute'],\n        'mm': [number + ' mintanim', number + ' mintam'],\n        'h': ['eka horan', 'ek hor'],\n        'hh': [number + ' horanim', number + ' hor'],\n        'd': ['eka disan', 'ek dis'],\n        'dd': [number + ' disanim', number + ' dis'],\n        'M': ['eka mhoinean', 'ek mhoino'],\n        'MM': [number + ' mhoineanim', number + ' mhoine'],\n        'y': ['eka vorsan', 'ek voros'],\n        'yy': [number + ' vorsanim', number + ' vorsam']\n    };\n    return withoutSuffix ? format[key][0] : format[key][1];\n}\n\nexport default moment.defineLocale('gom-latn', {\n    months : 'Janer_Febrer_Mars_Abril_Mai_Jun_Julai_Agost_Setembr_Otubr_Novembr_Dezembr'.split('_'),\n    monthsShort : 'Jan._Feb._Mars_Abr._Mai_Jun_Jul._Ago._Set._Otu._Nov._Dez.'.split('_'),\n    monthsParseExact : true,\n    weekdays : 'Aitar_Somar_Mongllar_Budvar_Brestar_Sukrar_Son\\'var'.split('_'),\n    weekdaysShort : 'Ait._Som._Mon._Bud._Bre._Suk._Son.'.split('_'),\n    weekdaysMin : 'Ai_Sm_Mo_Bu_Br_Su_Sn'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat : {\n        LT : 'A h:mm [vazta]',\n        LTS : 'A h:mm:ss [vazta]',\n        L : 'DD-MM-YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY A h:mm [vazta]',\n        LLLL : 'dddd, MMMM[achea] Do, YYYY, A h:mm [vazta]',\n        llll: 'ddd, D MMM YYYY, A h:mm [vazta]'\n    },\n    calendar : {\n        sameDay: '[Aiz] LT',\n        nextDay: '[Faleam] LT',\n        nextWeek: '[Ieta to] dddd[,] LT',\n        lastDay: '[Kal] LT',\n        lastWeek: '[Fatlo] dddd[,] LT',\n        sameElse: 'L'\n    },\n    relativeTime : {\n        future : '%s',\n        past : '%s adim',\n        s : processRelativeTime,\n        m : processRelativeTime,\n        mm : processRelativeTime,\n        h : processRelativeTime,\n        hh : processRelativeTime,\n        d : processRelativeTime,\n        dd : processRelativeTime,\n        M : processRelativeTime,\n        MM : processRelativeTime,\n        y : processRelativeTime,\n        yy : processRelativeTime\n    },\n    dayOfMonthOrdinalParse : /\\d{1,2}(er)/,\n    ordinal : function (number, period) {\n        switch (period) {\n            // the ordinal 'er' only applies to day of the month\n            case 'D':\n                return number + 'er';\n            default:\n            case 'M':\n            case 'Q':\n            case 'DDD':\n            case 'd':\n            case 'w':\n            case 'W':\n                return number;\n        }\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    },\n    meridiemParse: /rati|sokalli|donparam|sanje/,\n    meridiemHour : function (hour, meridiem) {\n        if (hour === 12) {\n            hour = 0;\n        }\n        if (meridiem === 'rati') {\n            return hour < 4 ? hour : hour + 12;\n        } else if (meridiem === 'sokalli') {\n            return hour;\n        } else if (meridiem === 'donparam') {\n            return hour > 12 ? hour : hour + 12;\n        } else if (meridiem === 'sanje') {\n            return hour + 12;\n        }\n    },\n    meridiem : function (hour, minute, isLower) {\n        if (hour < 4) {\n            return 'rati';\n        } else if (hour < 12) {\n            return 'sokalli';\n        } else if (hour < 16) {\n            return 'donparam';\n        } else if (hour < 20) {\n            return 'sanje';\n        } else {\n            return 'rati';\n        }\n    }\n});\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/locale/he.js",
    "content": "//! moment.js locale configuration\n//! locale : Hebrew [he]\n//! author : Tomer Cohen : https://github.com/tomer\n//! author : Moshe Simantov : https://github.com/DevelopmentIL\n//! author : Tal Ater : https://github.com/TalAter\n\nimport moment from '../moment';\n\nexport default moment.defineLocale('he', {\n    months : 'ינואר_פברואר_מרץ_אפריל_מאי_יוני_יולי_אוגוסט_ספטמבר_אוקטובר_נובמבר_דצמבר'.split('_'),\n    monthsShort : 'ינו׳_פבר׳_מרץ_אפר׳_מאי_יוני_יולי_אוג׳_ספט׳_אוק׳_נוב׳_דצמ׳'.split('_'),\n    weekdays : 'ראשון_שני_שלישי_רביעי_חמישי_שישי_שבת'.split('_'),\n    weekdaysShort : 'א׳_ב׳_ג׳_ד׳_ה׳_ו׳_ש׳'.split('_'),\n    weekdaysMin : 'א_ב_ג_ד_ה_ו_ש'.split('_'),\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D [ב]MMMM YYYY',\n        LLL : 'D [ב]MMMM YYYY HH:mm',\n        LLLL : 'dddd, D [ב]MMMM YYYY HH:mm',\n        l : 'D/M/YYYY',\n        ll : 'D MMM YYYY',\n        lll : 'D MMM YYYY HH:mm',\n        llll : 'ddd, D MMM YYYY HH:mm'\n    },\n    calendar : {\n        sameDay : '[היום ב־]LT',\n        nextDay : '[מחר ב־]LT',\n        nextWeek : 'dddd [בשעה] LT',\n        lastDay : '[אתמול ב־]LT',\n        lastWeek : '[ביום] dddd [האחרון בשעה] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'בעוד %s',\n        past : 'לפני %s',\n        s : 'מספר שניות',\n        m : 'דקה',\n        mm : '%d דקות',\n        h : 'שעה',\n        hh : function (number) {\n            if (number === 2) {\n                return 'שעתיים';\n            }\n            return number + ' שעות';\n        },\n        d : 'יום',\n        dd : function (number) {\n            if (number === 2) {\n                return 'יומיים';\n            }\n            return number + ' ימים';\n        },\n        M : 'חודש',\n        MM : function (number) {\n            if (number === 2) {\n                return 'חודשיים';\n            }\n            return number + ' חודשים';\n        },\n        y : 'שנה',\n        yy : function (number) {\n            if (number === 2) {\n                return 'שנתיים';\n            } else if (number % 10 === 0 && number !== 10) {\n                return number + ' שנה';\n            }\n            return number + ' שנים';\n        }\n    },\n    meridiemParse: /אחה\"צ|לפנה\"צ|אחרי הצהריים|לפני הצהריים|לפנות בוקר|בבוקר|בערב/i,\n    isPM : function (input) {\n        return /^(אחה\"צ|אחרי הצהריים|בערב)$/.test(input);\n    },\n    meridiem : function (hour, minute, isLower) {\n        if (hour < 5) {\n            return 'לפנות בוקר';\n        } else if (hour < 10) {\n            return 'בבוקר';\n        } else if (hour < 12) {\n            return isLower ? 'לפנה\"צ' : 'לפני הצהריים';\n        } else if (hour < 18) {\n            return isLower ? 'אחה\"צ' : 'אחרי הצהריים';\n        } else {\n            return 'בערב';\n        }\n    }\n});\n\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/locale/hi.js",
    "content": "//! moment.js locale configuration\n//! locale : Hindi [hi]\n//! author : Mayank Singhal : https://github.com/mayanksinghal\n\nimport moment from '../moment';\n\nvar symbolMap = {\n    '1': '१',\n    '2': '२',\n    '3': '३',\n    '4': '४',\n    '5': '५',\n    '6': '६',\n    '7': '७',\n    '8': '८',\n    '9': '९',\n    '0': '०'\n},\nnumberMap = {\n    '१': '1',\n    '२': '2',\n    '३': '3',\n    '४': '4',\n    '५': '5',\n    '६': '6',\n    '७': '7',\n    '८': '8',\n    '९': '9',\n    '०': '0'\n};\n\nexport default moment.defineLocale('hi', {\n    months : 'जनवरी_फ़रवरी_मार्च_अप्रैल_मई_जून_जुलाई_अगस्त_सितम्बर_अक्टूबर_नवम्बर_दिसम्बर'.split('_'),\n    monthsShort : 'जन._फ़र._मार्च_अप्रै._मई_जून_जुल._अग._सित._अक्टू._नव._दिस.'.split('_'),\n    monthsParseExact: true,\n    weekdays : 'रविवार_सोमवार_मंगलवार_बुधवार_गुरूवार_शुक्रवार_शनिवार'.split('_'),\n    weekdaysShort : 'रवि_सोम_मंगल_बुध_गुरू_शुक्र_शनि'.split('_'),\n    weekdaysMin : 'र_सो_मं_बु_गु_शु_श'.split('_'),\n    longDateFormat : {\n        LT : 'A h:mm बजे',\n        LTS : 'A h:mm:ss बजे',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY, A h:mm बजे',\n        LLLL : 'dddd, D MMMM YYYY, A h:mm बजे'\n    },\n    calendar : {\n        sameDay : '[आज] LT',\n        nextDay : '[कल] LT',\n        nextWeek : 'dddd, LT',\n        lastDay : '[कल] LT',\n        lastWeek : '[पिछले] dddd, LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : '%s में',\n        past : '%s पहले',\n        s : 'कुछ ही क्षण',\n        m : 'एक मिनट',\n        mm : '%d मिनट',\n        h : 'एक घंटा',\n        hh : '%d घंटे',\n        d : 'एक दिन',\n        dd : '%d दिन',\n        M : 'एक महीने',\n        MM : '%d महीने',\n        y : 'एक वर्ष',\n        yy : '%d वर्ष'\n    },\n    preparse: function (string) {\n        return string.replace(/[१२३४५६७८९०]/g, function (match) {\n            return numberMap[match];\n        });\n    },\n    postformat: function (string) {\n        return string.replace(/\\d/g, function (match) {\n            return symbolMap[match];\n        });\n    },\n    // Hindi notation for meridiems are quite fuzzy in practice. While there exists\n    // a rigid notion of a 'Pahar' it is not used as rigidly in modern Hindi.\n    meridiemParse: /रात|सुबह|दोपहर|शाम/,\n    meridiemHour : function (hour, meridiem) {\n        if (hour === 12) {\n            hour = 0;\n        }\n        if (meridiem === 'रात') {\n            return hour < 4 ? hour : hour + 12;\n        } else if (meridiem === 'सुबह') {\n            return hour;\n        } else if (meridiem === 'दोपहर') {\n            return hour >= 10 ? hour : hour + 12;\n        } else if (meridiem === 'शाम') {\n            return hour + 12;\n        }\n    },\n    meridiem : function (hour, minute, isLower) {\n        if (hour < 4) {\n            return 'रात';\n        } else if (hour < 10) {\n            return 'सुबह';\n        } else if (hour < 17) {\n            return 'दोपहर';\n        } else if (hour < 20) {\n            return 'शाम';\n        } else {\n            return 'रात';\n        }\n    },\n    week : {\n        dow : 0, // Sunday is the first day of the week.\n        doy : 6  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/locale/hr.js",
    "content": "//! moment.js locale configuration\n//! locale : Croatian [hr]\n//! author : Bojan Marković : https://github.com/bmarkovic\n\nimport moment from '../moment';\n\nfunction translate(number, withoutSuffix, key) {\n    var result = number + ' ';\n    switch (key) {\n        case 'm':\n            return withoutSuffix ? 'jedna minuta' : 'jedne minute';\n        case 'mm':\n            if (number === 1) {\n                result += 'minuta';\n            } else if (number === 2 || number === 3 || number === 4) {\n                result += 'minute';\n            } else {\n                result += 'minuta';\n            }\n            return result;\n        case 'h':\n            return withoutSuffix ? 'jedan sat' : 'jednog sata';\n        case 'hh':\n            if (number === 1) {\n                result += 'sat';\n            } else if (number === 2 || number === 3 || number === 4) {\n                result += 'sata';\n            } else {\n                result += 'sati';\n            }\n            return result;\n        case 'dd':\n            if (number === 1) {\n                result += 'dan';\n            } else {\n                result += 'dana';\n            }\n            return result;\n        case 'MM':\n            if (number === 1) {\n                result += 'mjesec';\n            } else if (number === 2 || number === 3 || number === 4) {\n                result += 'mjeseca';\n            } else {\n                result += 'mjeseci';\n            }\n            return result;\n        case 'yy':\n            if (number === 1) {\n                result += 'godina';\n            } else if (number === 2 || number === 3 || number === 4) {\n                result += 'godine';\n            } else {\n                result += 'godina';\n            }\n            return result;\n    }\n}\n\nexport default moment.defineLocale('hr', {\n    months : {\n        format: 'siječnja_veljače_ožujka_travnja_svibnja_lipnja_srpnja_kolovoza_rujna_listopada_studenoga_prosinca'.split('_'),\n        standalone: 'siječanj_veljača_ožujak_travanj_svibanj_lipanj_srpanj_kolovoz_rujan_listopad_studeni_prosinac'.split('_')\n    },\n    monthsShort : 'sij._velj._ožu._tra._svi._lip._srp._kol._ruj._lis._stu._pro.'.split('_'),\n    monthsParseExact: true,\n    weekdays : 'nedjelja_ponedjeljak_utorak_srijeda_četvrtak_petak_subota'.split('_'),\n    weekdaysShort : 'ned._pon._uto._sri._čet._pet._sub.'.split('_'),\n    weekdaysMin : 'ne_po_ut_sr_če_pe_su'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat : {\n        LT : 'H:mm',\n        LTS : 'H:mm:ss',\n        L : 'DD.MM.YYYY',\n        LL : 'D. MMMM YYYY',\n        LLL : 'D. MMMM YYYY H:mm',\n        LLLL : 'dddd, D. MMMM YYYY H:mm'\n    },\n    calendar : {\n        sameDay  : '[danas u] LT',\n        nextDay  : '[sutra u] LT',\n        nextWeek : function () {\n            switch (this.day()) {\n                case 0:\n                    return '[u] [nedjelju] [u] LT';\n                case 3:\n                    return '[u] [srijedu] [u] LT';\n                case 6:\n                    return '[u] [subotu] [u] LT';\n                case 1:\n                case 2:\n                case 4:\n                case 5:\n                    return '[u] dddd [u] LT';\n            }\n        },\n        lastDay  : '[jučer u] LT',\n        lastWeek : function () {\n            switch (this.day()) {\n                case 0:\n                case 3:\n                    return '[prošlu] dddd [u] LT';\n                case 6:\n                    return '[prošle] [subote] [u] LT';\n                case 1:\n                case 2:\n                case 4:\n                case 5:\n                    return '[prošli] dddd [u] LT';\n            }\n        },\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'za %s',\n        past   : 'prije %s',\n        s      : 'par sekundi',\n        m      : translate,\n        mm     : translate,\n        h      : translate,\n        hh     : translate,\n        d      : 'dan',\n        dd     : translate,\n        M      : 'mjesec',\n        MM     : translate,\n        y      : 'godinu',\n        yy     : translate\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}\\./,\n    ordinal : '%d.',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 7  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/locale/hu.js",
    "content": "//! moment.js locale configuration\n//! locale : Hungarian [hu]\n//! author : Adam Brunner : https://github.com/adambrunner\n\nimport moment from '../moment';\n\nvar weekEndings = 'vasárnap hétfőn kedden szerdán csütörtökön pénteken szombaton'.split(' ');\nfunction translate(number, withoutSuffix, key, isFuture) {\n    var num = number,\n        suffix;\n    switch (key) {\n        case 's':\n            return (isFuture || withoutSuffix) ? 'néhány másodperc' : 'néhány másodperce';\n        case 'm':\n            return 'egy' + (isFuture || withoutSuffix ? ' perc' : ' perce');\n        case 'mm':\n            return num + (isFuture || withoutSuffix ? ' perc' : ' perce');\n        case 'h':\n            return 'egy' + (isFuture || withoutSuffix ? ' óra' : ' órája');\n        case 'hh':\n            return num + (isFuture || withoutSuffix ? ' óra' : ' órája');\n        case 'd':\n            return 'egy' + (isFuture || withoutSuffix ? ' nap' : ' napja');\n        case 'dd':\n            return num + (isFuture || withoutSuffix ? ' nap' : ' napja');\n        case 'M':\n            return 'egy' + (isFuture || withoutSuffix ? ' hónap' : ' hónapja');\n        case 'MM':\n            return num + (isFuture || withoutSuffix ? ' hónap' : ' hónapja');\n        case 'y':\n            return 'egy' + (isFuture || withoutSuffix ? ' év' : ' éve');\n        case 'yy':\n            return num + (isFuture || withoutSuffix ? ' év' : ' éve');\n    }\n    return '';\n}\nfunction week(isFuture) {\n    return (isFuture ? '' : '[múlt] ') + '[' + weekEndings[this.day()] + '] LT[-kor]';\n}\n\nexport default moment.defineLocale('hu', {\n    months : 'január_február_március_április_május_június_július_augusztus_szeptember_október_november_december'.split('_'),\n    monthsShort : 'jan_feb_márc_ápr_máj_jún_júl_aug_szept_okt_nov_dec'.split('_'),\n    weekdays : 'vasárnap_hétfő_kedd_szerda_csütörtök_péntek_szombat'.split('_'),\n    weekdaysShort : 'vas_hét_kedd_sze_csüt_pén_szo'.split('_'),\n    weekdaysMin : 'v_h_k_sze_cs_p_szo'.split('_'),\n    longDateFormat : {\n        LT : 'H:mm',\n        LTS : 'H:mm:ss',\n        L : 'YYYY.MM.DD.',\n        LL : 'YYYY. MMMM D.',\n        LLL : 'YYYY. MMMM D. H:mm',\n        LLLL : 'YYYY. MMMM D., dddd H:mm'\n    },\n    meridiemParse: /de|du/i,\n    isPM: function (input) {\n        return input.charAt(1).toLowerCase() === 'u';\n    },\n    meridiem : function (hours, minutes, isLower) {\n        if (hours < 12) {\n            return isLower === true ? 'de' : 'DE';\n        } else {\n            return isLower === true ? 'du' : 'DU';\n        }\n    },\n    calendar : {\n        sameDay : '[ma] LT[-kor]',\n        nextDay : '[holnap] LT[-kor]',\n        nextWeek : function () {\n            return week.call(this, true);\n        },\n        lastDay : '[tegnap] LT[-kor]',\n        lastWeek : function () {\n            return week.call(this, false);\n        },\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : '%s múlva',\n        past : '%s',\n        s : translate,\n        m : translate,\n        mm : translate,\n        h : translate,\n        hh : translate,\n        d : translate,\n        dd : translate,\n        M : translate,\n        MM : translate,\n        y : translate,\n        yy : translate\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}\\./,\n    ordinal : '%d.',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/locale/hy-am.js",
    "content": "//! moment.js locale configuration\n//! locale : Armenian [hy-am]\n//! author : Armendarabyan : https://github.com/armendarabyan\n\nimport moment from '../moment';\n\nexport default moment.defineLocale('hy-am', {\n    months : {\n        format: 'հունվարի_փետրվարի_մարտի_ապրիլի_մայիսի_հունիսի_հուլիսի_օգոստոսի_սեպտեմբերի_հոկտեմբերի_նոյեմբերի_դեկտեմբերի'.split('_'),\n        standalone: 'հունվար_փետրվար_մարտ_ապրիլ_մայիս_հունիս_հուլիս_օգոստոս_սեպտեմբեր_հոկտեմբեր_նոյեմբեր_դեկտեմբեր'.split('_')\n    },\n    monthsShort : 'հնվ_փտր_մրտ_ապր_մյս_հնս_հլս_օգս_սպտ_հկտ_նմբ_դկտ'.split('_'),\n    weekdays : 'կիրակի_երկուշաբթի_երեքշաբթի_չորեքշաբթի_հինգշաբթի_ուրբաթ_շաբաթ'.split('_'),\n    weekdaysShort : 'կրկ_երկ_երք_չրք_հնգ_ուրբ_շբթ'.split('_'),\n    weekdaysMin : 'կրկ_երկ_երք_չրք_հնգ_ուրբ_շբթ'.split('_'),\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD.MM.YYYY',\n        LL : 'D MMMM YYYY թ.',\n        LLL : 'D MMMM YYYY թ., HH:mm',\n        LLLL : 'dddd, D MMMM YYYY թ., HH:mm'\n    },\n    calendar : {\n        sameDay: '[այսօր] LT',\n        nextDay: '[վաղը] LT',\n        lastDay: '[երեկ] LT',\n        nextWeek: function () {\n            return 'dddd [օրը ժամը] LT';\n        },\n        lastWeek: function () {\n            return '[անցած] dddd [օրը ժամը] LT';\n        },\n        sameElse: 'L'\n    },\n    relativeTime : {\n        future : '%s հետո',\n        past : '%s առաջ',\n        s : 'մի քանի վայրկյան',\n        m : 'րոպե',\n        mm : '%d րոպե',\n        h : 'ժամ',\n        hh : '%d ժամ',\n        d : 'օր',\n        dd : '%d օր',\n        M : 'ամիս',\n        MM : '%d ամիս',\n        y : 'տարի',\n        yy : '%d տարի'\n    },\n    meridiemParse: /գիշերվա|առավոտվա|ցերեկվա|երեկոյան/,\n    isPM: function (input) {\n        return /^(ցերեկվա|երեկոյան)$/.test(input);\n    },\n    meridiem : function (hour) {\n        if (hour < 4) {\n            return 'գիշերվա';\n        } else if (hour < 12) {\n            return 'առավոտվա';\n        } else if (hour < 17) {\n            return 'ցերեկվա';\n        } else {\n            return 'երեկոյան';\n        }\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}|\\d{1,2}-(ին|րդ)/,\n    ordinal: function (number, period) {\n        switch (period) {\n            case 'DDD':\n            case 'w':\n            case 'W':\n            case 'DDDo':\n                if (number === 1) {\n                    return number + '-ին';\n                }\n                return number + '-րդ';\n            default:\n                return number;\n        }\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 7  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/locale/id.js",
    "content": "//! moment.js locale configuration\n//! locale : Indonesian [id]\n//! author : Mohammad Satrio Utomo : https://github.com/tyok\n//! reference: http://id.wikisource.org/wiki/Pedoman_Umum_Ejaan_Bahasa_Indonesia_yang_Disempurnakan\n\nimport moment from '../moment';\n\nexport default moment.defineLocale('id', {\n    months : 'Januari_Februari_Maret_April_Mei_Juni_Juli_Agustus_September_Oktober_November_Desember'.split('_'),\n    monthsShort : 'Jan_Feb_Mar_Apr_Mei_Jun_Jul_Ags_Sep_Okt_Nov_Des'.split('_'),\n    weekdays : 'Minggu_Senin_Selasa_Rabu_Kamis_Jumat_Sabtu'.split('_'),\n    weekdaysShort : 'Min_Sen_Sel_Rab_Kam_Jum_Sab'.split('_'),\n    weekdaysMin : 'Mg_Sn_Sl_Rb_Km_Jm_Sb'.split('_'),\n    longDateFormat : {\n        LT : 'HH.mm',\n        LTS : 'HH.mm.ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY [pukul] HH.mm',\n        LLLL : 'dddd, D MMMM YYYY [pukul] HH.mm'\n    },\n    meridiemParse: /pagi|siang|sore|malam/,\n    meridiemHour : function (hour, meridiem) {\n        if (hour === 12) {\n            hour = 0;\n        }\n        if (meridiem === 'pagi') {\n            return hour;\n        } else if (meridiem === 'siang') {\n            return hour >= 11 ? hour : hour + 12;\n        } else if (meridiem === 'sore' || meridiem === 'malam') {\n            return hour + 12;\n        }\n    },\n    meridiem : function (hours, minutes, isLower) {\n        if (hours < 11) {\n            return 'pagi';\n        } else if (hours < 15) {\n            return 'siang';\n        } else if (hours < 19) {\n            return 'sore';\n        } else {\n            return 'malam';\n        }\n    },\n    calendar : {\n        sameDay : '[Hari ini pukul] LT',\n        nextDay : '[Besok pukul] LT',\n        nextWeek : 'dddd [pukul] LT',\n        lastDay : '[Kemarin pukul] LT',\n        lastWeek : 'dddd [lalu pukul] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'dalam %s',\n        past : '%s yang lalu',\n        s : 'beberapa detik',\n        m : 'semenit',\n        mm : '%d menit',\n        h : 'sejam',\n        hh : '%d jam',\n        d : 'sehari',\n        dd : '%d hari',\n        M : 'sebulan',\n        MM : '%d bulan',\n        y : 'setahun',\n        yy : '%d tahun'\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 7  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/locale/is.js",
    "content": "//! moment.js locale configuration\n//! locale : Icelandic [is]\n//! author : Hinrik Örn Sigurðsson : https://github.com/hinrik\n\nimport moment from '../moment';\n\nfunction plural(n) {\n    if (n % 100 === 11) {\n        return true;\n    } else if (n % 10 === 1) {\n        return false;\n    }\n    return true;\n}\nfunction translate(number, withoutSuffix, key, isFuture) {\n    var result = number + ' ';\n    switch (key) {\n        case 's':\n            return withoutSuffix || isFuture ? 'nokkrar sekúndur' : 'nokkrum sekúndum';\n        case 'm':\n            return withoutSuffix ? 'mínúta' : 'mínútu';\n        case 'mm':\n            if (plural(number)) {\n                return result + (withoutSuffix || isFuture ? 'mínútur' : 'mínútum');\n            } else if (withoutSuffix) {\n                return result + 'mínúta';\n            }\n            return result + 'mínútu';\n        case 'hh':\n            if (plural(number)) {\n                return result + (withoutSuffix || isFuture ? 'klukkustundir' : 'klukkustundum');\n            }\n            return result + 'klukkustund';\n        case 'd':\n            if (withoutSuffix) {\n                return 'dagur';\n            }\n            return isFuture ? 'dag' : 'degi';\n        case 'dd':\n            if (plural(number)) {\n                if (withoutSuffix) {\n                    return result + 'dagar';\n                }\n                return result + (isFuture ? 'daga' : 'dögum');\n            } else if (withoutSuffix) {\n                return result + 'dagur';\n            }\n            return result + (isFuture ? 'dag' : 'degi');\n        case 'M':\n            if (withoutSuffix) {\n                return 'mánuður';\n            }\n            return isFuture ? 'mánuð' : 'mánuði';\n        case 'MM':\n            if (plural(number)) {\n                if (withoutSuffix) {\n                    return result + 'mánuðir';\n                }\n                return result + (isFuture ? 'mánuði' : 'mánuðum');\n            } else if (withoutSuffix) {\n                return result + 'mánuður';\n            }\n            return result + (isFuture ? 'mánuð' : 'mánuði');\n        case 'y':\n            return withoutSuffix || isFuture ? 'ár' : 'ári';\n        case 'yy':\n            if (plural(number)) {\n                return result + (withoutSuffix || isFuture ? 'ár' : 'árum');\n            }\n            return result + (withoutSuffix || isFuture ? 'ár' : 'ári');\n    }\n}\n\nexport default moment.defineLocale('is', {\n    months : 'janúar_febrúar_mars_apríl_maí_júní_júlí_ágúst_september_október_nóvember_desember'.split('_'),\n    monthsShort : 'jan_feb_mar_apr_maí_jún_júl_ágú_sep_okt_nóv_des'.split('_'),\n    weekdays : 'sunnudagur_mánudagur_þriðjudagur_miðvikudagur_fimmtudagur_föstudagur_laugardagur'.split('_'),\n    weekdaysShort : 'sun_mán_þri_mið_fim_fös_lau'.split('_'),\n    weekdaysMin : 'Su_Má_Þr_Mi_Fi_Fö_La'.split('_'),\n    longDateFormat : {\n        LT : 'H:mm',\n        LTS : 'H:mm:ss',\n        L : 'DD.MM.YYYY',\n        LL : 'D. MMMM YYYY',\n        LLL : 'D. MMMM YYYY [kl.] H:mm',\n        LLLL : 'dddd, D. MMMM YYYY [kl.] H:mm'\n    },\n    calendar : {\n        sameDay : '[í dag kl.] LT',\n        nextDay : '[á morgun kl.] LT',\n        nextWeek : 'dddd [kl.] LT',\n        lastDay : '[í gær kl.] LT',\n        lastWeek : '[síðasta] dddd [kl.] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'eftir %s',\n        past : 'fyrir %s síðan',\n        s : translate,\n        m : translate,\n        mm : translate,\n        h : 'klukkustund',\n        hh : translate,\n        d : translate,\n        dd : translate,\n        M : translate,\n        MM : translate,\n        y : translate,\n        yy : translate\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}\\./,\n    ordinal : '%d.',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/locale/it.js",
    "content": "//! moment.js locale configuration\n//! locale : Italian [it]\n//! author : Lorenzo : https://github.com/aliem\n//! author: Mattia Larentis: https://github.com/nostalgiaz\n\nimport moment from '../moment';\n\nexport default moment.defineLocale('it', {\n    months : 'gennaio_febbraio_marzo_aprile_maggio_giugno_luglio_agosto_settembre_ottobre_novembre_dicembre'.split('_'),\n    monthsShort : 'gen_feb_mar_apr_mag_giu_lug_ago_set_ott_nov_dic'.split('_'),\n    weekdays : 'domenica_lunedì_martedì_mercoledì_giovedì_venerdì_sabato'.split('_'),\n    weekdaysShort : 'dom_lun_mar_mer_gio_ven_sab'.split('_'),\n    weekdaysMin : 'do_lu_ma_me_gi_ve_sa'.split('_'),\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY HH:mm',\n        LLLL : 'dddd, D MMMM YYYY HH:mm'\n    },\n    calendar : {\n        sameDay: '[Oggi alle] LT',\n        nextDay: '[Domani alle] LT',\n        nextWeek: 'dddd [alle] LT',\n        lastDay: '[Ieri alle] LT',\n        lastWeek: function () {\n            switch (this.day()) {\n                case 0:\n                    return '[la scorsa] dddd [alle] LT';\n                default:\n                    return '[lo scorso] dddd [alle] LT';\n            }\n        },\n        sameElse: 'L'\n    },\n    relativeTime : {\n        future : function (s) {\n            return ((/^[0-9].+$/).test(s) ? 'tra' : 'in') + ' ' + s;\n        },\n        past : '%s fa',\n        s : 'alcuni secondi',\n        m : 'un minuto',\n        mm : '%d minuti',\n        h : 'un\\'ora',\n        hh : '%d ore',\n        d : 'un giorno',\n        dd : '%d giorni',\n        M : 'un mese',\n        MM : '%d mesi',\n        y : 'un anno',\n        yy : '%d anni'\n    },\n    dayOfMonthOrdinalParse : /\\d{1,2}º/,\n    ordinal: '%dº',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/locale/ja.js",
    "content": "//! moment.js locale configuration\n//! locale : Japanese [ja]\n//! author : LI Long : https://github.com/baryon\n\nimport moment from '../moment';\n\nexport default moment.defineLocale('ja', {\n    months : '1月_2月_3月_4月_5月_6月_7月_8月_9月_10月_11月_12月'.split('_'),\n    monthsShort : '1月_2月_3月_4月_5月_6月_7月_8月_9月_10月_11月_12月'.split('_'),\n    weekdays : '日曜日_月曜日_火曜日_水曜日_木曜日_金曜日_土曜日'.split('_'),\n    weekdaysShort : '日_月_火_水_木_金_土'.split('_'),\n    weekdaysMin : '日_月_火_水_木_金_土'.split('_'),\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'YYYY/MM/DD',\n        LL : 'YYYY年M月D日',\n        LLL : 'YYYY年M月D日 HH:mm',\n        LLLL : 'YYYY年M月D日 HH:mm dddd',\n        l : 'YYYY/MM/DD',\n        ll : 'YYYY年M月D日',\n        lll : 'YYYY年M月D日 HH:mm',\n        llll : 'YYYY年M月D日 HH:mm dddd'\n    },\n    meridiemParse: /午前|午後/i,\n    isPM : function (input) {\n        return input === '午後';\n    },\n    meridiem : function (hour, minute, isLower) {\n        if (hour < 12) {\n            return '午前';\n        } else {\n            return '午後';\n        }\n    },\n    calendar : {\n        sameDay : '[今日] LT',\n        nextDay : '[明日] LT',\n        nextWeek : '[来週]dddd LT',\n        lastDay : '[昨日] LT',\n        lastWeek : '[前週]dddd LT',\n        sameElse : 'L'\n    },\n    dayOfMonthOrdinalParse : /\\d{1,2}日/,\n    ordinal : function (number, period) {\n        switch (period) {\n            case 'd':\n            case 'D':\n            case 'DDD':\n                return number + '日';\n            default:\n                return number;\n        }\n    },\n    relativeTime : {\n        future : '%s後',\n        past : '%s前',\n        s : '数秒',\n        m : '1分',\n        mm : '%d分',\n        h : '1時間',\n        hh : '%d時間',\n        d : '1日',\n        dd : '%d日',\n        M : '1ヶ月',\n        MM : '%dヶ月',\n        y : '1年',\n        yy : '%d年'\n    }\n});\n\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/locale/jv.js",
    "content": "//! moment.js locale configuration\n//! locale : Javanese [jv]\n//! author : Rony Lantip : https://github.com/lantip\n//! reference: http://jv.wikipedia.org/wiki/Basa_Jawa\n\nimport moment from '../moment';\n\nexport default moment.defineLocale('jv', {\n    months : 'Januari_Februari_Maret_April_Mei_Juni_Juli_Agustus_September_Oktober_Nopember_Desember'.split('_'),\n    monthsShort : 'Jan_Feb_Mar_Apr_Mei_Jun_Jul_Ags_Sep_Okt_Nop_Des'.split('_'),\n    weekdays : 'Minggu_Senen_Seloso_Rebu_Kemis_Jemuwah_Septu'.split('_'),\n    weekdaysShort : 'Min_Sen_Sel_Reb_Kem_Jem_Sep'.split('_'),\n    weekdaysMin : 'Mg_Sn_Sl_Rb_Km_Jm_Sp'.split('_'),\n    longDateFormat : {\n        LT : 'HH.mm',\n        LTS : 'HH.mm.ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY [pukul] HH.mm',\n        LLLL : 'dddd, D MMMM YYYY [pukul] HH.mm'\n    },\n    meridiemParse: /enjing|siyang|sonten|ndalu/,\n    meridiemHour : function (hour, meridiem) {\n        if (hour === 12) {\n            hour = 0;\n        }\n        if (meridiem === 'enjing') {\n            return hour;\n        } else if (meridiem === 'siyang') {\n            return hour >= 11 ? hour : hour + 12;\n        } else if (meridiem === 'sonten' || meridiem === 'ndalu') {\n            return hour + 12;\n        }\n    },\n    meridiem : function (hours, minutes, isLower) {\n        if (hours < 11) {\n            return 'enjing';\n        } else if (hours < 15) {\n            return 'siyang';\n        } else if (hours < 19) {\n            return 'sonten';\n        } else {\n            return 'ndalu';\n        }\n    },\n    calendar : {\n        sameDay : '[Dinten puniko pukul] LT',\n        nextDay : '[Mbenjang pukul] LT',\n        nextWeek : 'dddd [pukul] LT',\n        lastDay : '[Kala wingi pukul] LT',\n        lastWeek : 'dddd [kepengker pukul] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'wonten ing %s',\n        past : '%s ingkang kepengker',\n        s : 'sawetawis detik',\n        m : 'setunggal menit',\n        mm : '%d menit',\n        h : 'setunggal jam',\n        hh : '%d jam',\n        d : 'sedinten',\n        dd : '%d dinten',\n        M : 'sewulan',\n        MM : '%d wulan',\n        y : 'setaun',\n        yy : '%d taun'\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 7  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/locale/ka.js",
    "content": "//! moment.js locale configuration\n//! locale : Georgian [ka]\n//! author : Irakli Janiashvili : https://github.com/irakli-janiashvili\n\nimport moment from '../moment';\n\nexport default moment.defineLocale('ka', {\n    months : {\n        standalone: 'იანვარი_თებერვალი_მარტი_აპრილი_მაისი_ივნისი_ივლისი_აგვისტო_სექტემბერი_ოქტომბერი_ნოემბერი_დეკემბერი'.split('_'),\n        format: 'იანვარს_თებერვალს_მარტს_აპრილის_მაისს_ივნისს_ივლისს_აგვისტს_სექტემბერს_ოქტომბერს_ნოემბერს_დეკემბერს'.split('_')\n    },\n    monthsShort : 'იან_თებ_მარ_აპრ_მაი_ივნ_ივლ_აგვ_სექ_ოქტ_ნოე_დეკ'.split('_'),\n    weekdays : {\n        standalone: 'კვირა_ორშაბათი_სამშაბათი_ოთხშაბათი_ხუთშაბათი_პარასკევი_შაბათი'.split('_'),\n        format: 'კვირას_ორშაბათს_სამშაბათს_ოთხშაბათს_ხუთშაბათს_პარასკევს_შაბათს'.split('_'),\n        isFormat: /(წინა|შემდეგ)/\n    },\n    weekdaysShort : 'კვი_ორშ_სამ_ოთხ_ხუთ_პარ_შაბ'.split('_'),\n    weekdaysMin : 'კვ_ორ_სა_ოთ_ხუ_პა_შა'.split('_'),\n    longDateFormat : {\n        LT : 'h:mm A',\n        LTS : 'h:mm:ss A',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY h:mm A',\n        LLLL : 'dddd, D MMMM YYYY h:mm A'\n    },\n    calendar : {\n        sameDay : '[დღეს] LT[-ზე]',\n        nextDay : '[ხვალ] LT[-ზე]',\n        lastDay : '[გუშინ] LT[-ზე]',\n        nextWeek : '[შემდეგ] dddd LT[-ზე]',\n        lastWeek : '[წინა] dddd LT-ზე',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : function (s) {\n            return (/(წამი|წუთი|საათი|წელი)/).test(s) ?\n                s.replace(/ი$/, 'ში') :\n                s + 'ში';\n        },\n        past : function (s) {\n            if ((/(წამი|წუთი|საათი|დღე|თვე)/).test(s)) {\n                return s.replace(/(ი|ე)$/, 'ის უკან');\n            }\n            if ((/წელი/).test(s)) {\n                return s.replace(/წელი$/, 'წლის უკან');\n            }\n        },\n        s : 'რამდენიმე წამი',\n        m : 'წუთი',\n        mm : '%d წუთი',\n        h : 'საათი',\n        hh : '%d საათი',\n        d : 'დღე',\n        dd : '%d დღე',\n        M : 'თვე',\n        MM : '%d თვე',\n        y : 'წელი',\n        yy : '%d წელი'\n    },\n    dayOfMonthOrdinalParse: /0|1-ლი|მე-\\d{1,2}|\\d{1,2}-ე/,\n    ordinal : function (number) {\n        if (number === 0) {\n            return number;\n        }\n        if (number === 1) {\n            return number + '-ლი';\n        }\n        if ((number < 20) || (number <= 100 && (number % 20 === 0)) || (number % 100 === 0)) {\n            return 'მე-' + number;\n        }\n        return number + '-ე';\n    },\n    week : {\n        dow : 1,\n        doy : 7\n    }\n});\n\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/locale/kk.js",
    "content": "//! moment.js locale configuration\n//! locale : Kazakh [kk]\n//! authors : Nurlan Rakhimzhanov : https://github.com/nurlan\n\nimport moment from '../moment';\n\nvar suffixes = {\n    0: '-ші',\n    1: '-ші',\n    2: '-ші',\n    3: '-ші',\n    4: '-ші',\n    5: '-ші',\n    6: '-шы',\n    7: '-ші',\n    8: '-ші',\n    9: '-шы',\n    10: '-шы',\n    20: '-шы',\n    30: '-шы',\n    40: '-шы',\n    50: '-ші',\n    60: '-шы',\n    70: '-ші',\n    80: '-ші',\n    90: '-шы',\n    100: '-ші'\n};\n\nexport default moment.defineLocale('kk', {\n    months : 'қаңтар_ақпан_наурыз_сәуір_мамыр_маусым_шілде_тамыз_қыркүйек_қазан_қараша_желтоқсан'.split('_'),\n    monthsShort : 'қаң_ақп_нау_сәу_мам_мау_шіл_там_қыр_қаз_қар_жел'.split('_'),\n    weekdays : 'жексенбі_дүйсенбі_сейсенбі_сәрсенбі_бейсенбі_жұма_сенбі'.split('_'),\n    weekdaysShort : 'жек_дүй_сей_сәр_бей_жұм_сен'.split('_'),\n    weekdaysMin : 'жк_дй_сй_ср_бй_жм_сн'.split('_'),\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD.MM.YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY HH:mm',\n        LLLL : 'dddd, D MMMM YYYY HH:mm'\n    },\n    calendar : {\n        sameDay : '[Бүгін сағат] LT',\n        nextDay : '[Ертең сағат] LT',\n        nextWeek : 'dddd [сағат] LT',\n        lastDay : '[Кеше сағат] LT',\n        lastWeek : '[Өткен аптаның] dddd [сағат] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : '%s ішінде',\n        past : '%s бұрын',\n        s : 'бірнеше секунд',\n        m : 'бір минут',\n        mm : '%d минут',\n        h : 'бір сағат',\n        hh : '%d сағат',\n        d : 'бір күн',\n        dd : '%d күн',\n        M : 'бір ай',\n        MM : '%d ай',\n        y : 'бір жыл',\n        yy : '%d жыл'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}-(ші|шы)/,\n    ordinal : function (number) {\n        var a = number % 10,\n            b = number >= 100 ? 100 : null;\n        return number + (suffixes[number] || suffixes[a] || suffixes[b]);\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 7  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/locale/km.js",
    "content": "//! moment.js locale configuration\n//! locale : Cambodian [km]\n//! author : Kruy Vanna : https://github.com/kruyvanna\n\nimport moment from '../moment';\n\nexport default moment.defineLocale('km', {\n    months: 'មករា_កុម្ភៈ_មីនា_មេសា_ឧសភា_មិថុនា_កក្កដា_សីហា_កញ្ញា_តុលា_វិច្ឆិកា_ធ្នូ'.split('_'),\n    monthsShort: 'មករា_កុម្ភៈ_មីនា_មេសា_ឧសភា_មិថុនា_កក្កដា_សីហា_កញ្ញា_តុលា_វិច្ឆិកា_ធ្នូ'.split('_'),\n    weekdays: 'អាទិត្យ_ច័ន្ទ_អង្គារ_ពុធ_ព្រហស្បតិ៍_សុក្រ_សៅរ៍'.split('_'),\n    weekdaysShort: 'អាទិត្យ_ច័ន្ទ_អង្គារ_ពុធ_ព្រហស្បតិ៍_សុក្រ_សៅរ៍'.split('_'),\n    weekdaysMin: 'អាទិត្យ_ច័ន្ទ_អង្គារ_ពុធ_ព្រហស្បតិ៍_សុក្រ_សៅរ៍'.split('_'),\n    longDateFormat: {\n        LT: 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L: 'DD/MM/YYYY',\n        LL: 'D MMMM YYYY',\n        LLL: 'D MMMM YYYY HH:mm',\n        LLLL: 'dddd, D MMMM YYYY HH:mm'\n    },\n    calendar: {\n        sameDay: '[ថ្ងៃនេះ ម៉ោង] LT',\n        nextDay: '[ស្អែក ម៉ោង] LT',\n        nextWeek: 'dddd [ម៉ោង] LT',\n        lastDay: '[ម្សិលមិញ ម៉ោង] LT',\n        lastWeek: 'dddd [សប្តាហ៍មុន] [ម៉ោង] LT',\n        sameElse: 'L'\n    },\n    relativeTime: {\n        future: '%sទៀត',\n        past: '%sមុន',\n        s: 'ប៉ុន្មានវិនាទី',\n        m: 'មួយនាទី',\n        mm: '%d នាទី',\n        h: 'មួយម៉ោង',\n        hh: '%d ម៉ោង',\n        d: 'មួយថ្ងៃ',\n        dd: '%d ថ្ងៃ',\n        M: 'មួយខែ',\n        MM: '%d ខែ',\n        y: 'មួយឆ្នាំ',\n        yy: '%d ឆ្នាំ'\n    },\n    week: {\n        dow: 1, // Monday is the first day of the week.\n        doy: 4 // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/locale/kn.js",
    "content": "//! moment.js locale configuration\n//! locale : Kannada [kn]\n//! author : Rajeev Naik : https://github.com/rajeevnaikte\n\nimport moment from '../moment';\n\nvar symbolMap = {\n    '1': '೧',\n    '2': '೨',\n    '3': '೩',\n    '4': '೪',\n    '5': '೫',\n    '6': '೬',\n    '7': '೭',\n    '8': '೮',\n    '9': '೯',\n    '0': '೦'\n},\nnumberMap = {\n    '೧': '1',\n    '೨': '2',\n    '೩': '3',\n    '೪': '4',\n    '೫': '5',\n    '೬': '6',\n    '೭': '7',\n    '೮': '8',\n    '೯': '9',\n    '೦': '0'\n};\n\nexport default moment.defineLocale('kn', {\n    months : 'ಜನವರಿ_ಫೆಬ್ರವರಿ_ಮಾರ್ಚ್_ಏಪ್ರಿಲ್_ಮೇ_ಜೂನ್_ಜುಲೈ_ಆಗಸ್ಟ್_ಸೆಪ್ಟೆಂಬರ್_ಅಕ್ಟೋಬರ್_ನವೆಂಬರ್_ಡಿಸೆಂಬರ್'.split('_'),\n    monthsShort : 'ಜನ_ಫೆಬ್ರ_ಮಾರ್ಚ್_ಏಪ್ರಿಲ್_ಮೇ_ಜೂನ್_ಜುಲೈ_ಆಗಸ್ಟ್_ಸೆಪ್ಟೆಂಬ_ಅಕ್ಟೋಬ_ನವೆಂಬ_ಡಿಸೆಂಬ'.split('_'),\n    monthsParseExact: true,\n    weekdays : 'ಭಾನುವಾರ_ಸೋಮವಾರ_ಮಂಗಳವಾರ_ಬುಧವಾರ_ಗುರುವಾರ_ಶುಕ್ರವಾರ_ಶನಿವಾರ'.split('_'),\n    weekdaysShort : 'ಭಾನು_ಸೋಮ_ಮಂಗಳ_ಬುಧ_ಗುರು_ಶುಕ್ರ_ಶನಿ'.split('_'),\n    weekdaysMin : 'ಭಾ_ಸೋ_ಮಂ_ಬು_ಗು_ಶು_ಶ'.split('_'),\n    longDateFormat : {\n        LT : 'A h:mm',\n        LTS : 'A h:mm:ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY, A h:mm',\n        LLLL : 'dddd, D MMMM YYYY, A h:mm'\n    },\n    calendar : {\n        sameDay : '[ಇಂದು] LT',\n        nextDay : '[ನಾಳೆ] LT',\n        nextWeek : 'dddd, LT',\n        lastDay : '[ನಿನ್ನೆ] LT',\n        lastWeek : '[ಕೊನೆಯ] dddd, LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : '%s ನಂತರ',\n        past : '%s ಹಿಂದೆ',\n        s : 'ಕೆಲವು ಕ್ಷಣಗಳು',\n        m : 'ಒಂದು ನಿಮಿಷ',\n        mm : '%d ನಿಮಿಷ',\n        h : 'ಒಂದು ಗಂಟೆ',\n        hh : '%d ಗಂಟೆ',\n        d : 'ಒಂದು ದಿನ',\n        dd : '%d ದಿನ',\n        M : 'ಒಂದು ತಿಂಗಳು',\n        MM : '%d ತಿಂಗಳು',\n        y : 'ಒಂದು ವರ್ಷ',\n        yy : '%d ವರ್ಷ'\n    },\n    preparse: function (string) {\n        return string.replace(/[೧೨೩೪೫೬೭೮೯೦]/g, function (match) {\n            return numberMap[match];\n        });\n    },\n    postformat: function (string) {\n        return string.replace(/\\d/g, function (match) {\n            return symbolMap[match];\n        });\n    },\n    meridiemParse: /ರಾತ್ರಿ|ಬೆಳಿಗ್ಗೆ|ಮಧ್ಯಾಹ್ನ|ಸಂಜೆ/,\n    meridiemHour : function (hour, meridiem) {\n        if (hour === 12) {\n            hour = 0;\n        }\n        if (meridiem === 'ರಾತ್ರಿ') {\n            return hour < 4 ? hour : hour + 12;\n        } else if (meridiem === 'ಬೆಳಿಗ್ಗೆ') {\n            return hour;\n        } else if (meridiem === 'ಮಧ್ಯಾಹ್ನ') {\n            return hour >= 10 ? hour : hour + 12;\n        } else if (meridiem === 'ಸಂಜೆ') {\n            return hour + 12;\n        }\n    },\n    meridiem : function (hour, minute, isLower) {\n        if (hour < 4) {\n            return 'ರಾತ್ರಿ';\n        } else if (hour < 10) {\n            return 'ಬೆಳಿಗ್ಗೆ';\n        } else if (hour < 17) {\n            return 'ಮಧ್ಯಾಹ್ನ';\n        } else if (hour < 20) {\n            return 'ಸಂಜೆ';\n        } else {\n            return 'ರಾತ್ರಿ';\n        }\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}(ನೇ)/,\n    ordinal : function (number) {\n        return number + 'ನೇ';\n    },\n    week : {\n        dow : 0, // Sunday is the first day of the week.\n        doy : 6  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/locale/ko.js",
    "content": "//! moment.js locale configuration\n//! locale : Korean [ko]\n//! author : Kyungwook, Park : https://github.com/kyungw00k\n//! author : Jeeeyul Lee <jeeeyul@gmail.com>\n\nimport moment from '../moment';\n\nexport default moment.defineLocale('ko', {\n    months : '1월_2월_3월_4월_5월_6월_7월_8월_9월_10월_11월_12월'.split('_'),\n    monthsShort : '1월_2월_3월_4월_5월_6월_7월_8월_9월_10월_11월_12월'.split('_'),\n    weekdays : '일요일_월요일_화요일_수요일_목요일_금요일_토요일'.split('_'),\n    weekdaysShort : '일_월_화_수_목_금_토'.split('_'),\n    weekdaysMin : '일_월_화_수_목_금_토'.split('_'),\n    longDateFormat : {\n        LT : 'A h:mm',\n        LTS : 'A h:mm:ss',\n        L : 'YYYY.MM.DD',\n        LL : 'YYYY년 MMMM D일',\n        LLL : 'YYYY년 MMMM D일 A h:mm',\n        LLLL : 'YYYY년 MMMM D일 dddd A h:mm',\n        l : 'YYYY.MM.DD',\n        ll : 'YYYY년 MMMM D일',\n        lll : 'YYYY년 MMMM D일 A h:mm',\n        llll : 'YYYY년 MMMM D일 dddd A h:mm'\n    },\n    calendar : {\n        sameDay : '오늘 LT',\n        nextDay : '내일 LT',\n        nextWeek : 'dddd LT',\n        lastDay : '어제 LT',\n        lastWeek : '지난주 dddd LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : '%s 후',\n        past : '%s 전',\n        s : '몇 초',\n        ss : '%d초',\n        m : '1분',\n        mm : '%d분',\n        h : '한 시간',\n        hh : '%d시간',\n        d : '하루',\n        dd : '%d일',\n        M : '한 달',\n        MM : '%d달',\n        y : '일 년',\n        yy : '%d년'\n    },\n    dayOfMonthOrdinalParse : /\\d{1,2}일/,\n    ordinal : '%d일',\n    meridiemParse : /오전|오후/,\n    isPM : function (token) {\n        return token === '오후';\n    },\n    meridiem : function (hour, minute, isUpper) {\n        return hour < 12 ? '오전' : '오후';\n    }\n});\n\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/locale/ky.js",
    "content": "//! moment.js locale configuration\n//! locale : Kyrgyz [ky]\n//! author : Chyngyz Arystan uulu : https://github.com/chyngyz\n\n\nimport moment from '../moment';\n\nvar suffixes = {\n    0: '-чү',\n    1: '-чи',\n    2: '-чи',\n    3: '-чү',\n    4: '-чү',\n    5: '-чи',\n    6: '-чы',\n    7: '-чи',\n    8: '-чи',\n    9: '-чу',\n    10: '-чу',\n    20: '-чы',\n    30: '-чу',\n    40: '-чы',\n    50: '-чү',\n    60: '-чы',\n    70: '-чи',\n    80: '-чи',\n    90: '-чу',\n    100: '-чү'\n};\n\nexport default moment.defineLocale('ky', {\n    months : 'январь_февраль_март_апрель_май_июнь_июль_август_сентябрь_октябрь_ноябрь_декабрь'.split('_'),\n    monthsShort : 'янв_фев_март_апр_май_июнь_июль_авг_сен_окт_ноя_дек'.split('_'),\n    weekdays : 'Жекшемби_Дүйшөмбү_Шейшемби_Шаршемби_Бейшемби_Жума_Ишемби'.split('_'),\n    weekdaysShort : 'Жек_Дүй_Шей_Шар_Бей_Жум_Ише'.split('_'),\n    weekdaysMin : 'Жк_Дй_Шй_Шр_Бй_Жм_Иш'.split('_'),\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD.MM.YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY HH:mm',\n        LLLL : 'dddd, D MMMM YYYY HH:mm'\n    },\n    calendar : {\n        sameDay : '[Бүгүн саат] LT',\n        nextDay : '[Эртең саат] LT',\n        nextWeek : 'dddd [саат] LT',\n        lastDay : '[Кече саат] LT',\n        lastWeek : '[Өткен аптанын] dddd [күнү] [саат] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : '%s ичинде',\n        past : '%s мурун',\n        s : 'бирнече секунд',\n        m : 'бир мүнөт',\n        mm : '%d мүнөт',\n        h : 'бир саат',\n        hh : '%d саат',\n        d : 'бир күн',\n        dd : '%d күн',\n        M : 'бир ай',\n        MM : '%d ай',\n        y : 'бир жыл',\n        yy : '%d жыл'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}-(чи|чы|чү|чу)/,\n    ordinal : function (number) {\n        var a = number % 10,\n            b = number >= 100 ? 100 : null;\n        return number + (suffixes[number] || suffixes[a] || suffixes[b]);\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 7  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/locale/lb.js",
    "content": "//! moment.js locale configuration\n//! locale : Luxembourgish [lb]\n//! author : mweimerskirch : https://github.com/mweimerskirch\n//! author : David Raison : https://github.com/kwisatz\n\nimport moment from '../moment';\n\nfunction processRelativeTime(number, withoutSuffix, key, isFuture) {\n    var format = {\n        'm': ['eng Minutt', 'enger Minutt'],\n        'h': ['eng Stonn', 'enger Stonn'],\n        'd': ['een Dag', 'engem Dag'],\n        'M': ['ee Mount', 'engem Mount'],\n        'y': ['ee Joer', 'engem Joer']\n    };\n    return withoutSuffix ? format[key][0] : format[key][1];\n}\nfunction processFutureTime(string) {\n    var number = string.substr(0, string.indexOf(' '));\n    if (eifelerRegelAppliesToNumber(number)) {\n        return 'a ' + string;\n    }\n    return 'an ' + string;\n}\nfunction processPastTime(string) {\n    var number = string.substr(0, string.indexOf(' '));\n    if (eifelerRegelAppliesToNumber(number)) {\n        return 'viru ' + string;\n    }\n    return 'virun ' + string;\n}\n/**\n * Returns true if the word before the given number loses the '-n' ending.\n * e.g. 'an 10 Deeg' but 'a 5 Deeg'\n *\n * @param number {integer}\n * @returns {boolean}\n */\nfunction eifelerRegelAppliesToNumber(number) {\n    number = parseInt(number, 10);\n    if (isNaN(number)) {\n        return false;\n    }\n    if (number < 0) {\n        // Negative Number --> always true\n        return true;\n    } else if (number < 10) {\n        // Only 1 digit\n        if (4 <= number && number <= 7) {\n            return true;\n        }\n        return false;\n    } else if (number < 100) {\n        // 2 digits\n        var lastDigit = number % 10, firstDigit = number / 10;\n        if (lastDigit === 0) {\n            return eifelerRegelAppliesToNumber(firstDigit);\n        }\n        return eifelerRegelAppliesToNumber(lastDigit);\n    } else if (number < 10000) {\n        // 3 or 4 digits --> recursively check first digit\n        while (number >= 10) {\n            number = number / 10;\n        }\n        return eifelerRegelAppliesToNumber(number);\n    } else {\n        // Anything larger than 4 digits: recursively check first n-3 digits\n        number = number / 1000;\n        return eifelerRegelAppliesToNumber(number);\n    }\n}\n\nexport default moment.defineLocale('lb', {\n    months: 'Januar_Februar_Mäerz_Abrëll_Mee_Juni_Juli_August_September_Oktober_November_Dezember'.split('_'),\n    monthsShort: 'Jan._Febr._Mrz._Abr._Mee_Jun._Jul._Aug._Sept._Okt._Nov._Dez.'.split('_'),\n    monthsParseExact : true,\n    weekdays: 'Sonndeg_Méindeg_Dënschdeg_Mëttwoch_Donneschdeg_Freideg_Samschdeg'.split('_'),\n    weekdaysShort: 'So._Mé._Dë._Më._Do._Fr._Sa.'.split('_'),\n    weekdaysMin: 'So_Mé_Dë_Më_Do_Fr_Sa'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat: {\n        LT: 'H:mm [Auer]',\n        LTS: 'H:mm:ss [Auer]',\n        L: 'DD.MM.YYYY',\n        LL: 'D. MMMM YYYY',\n        LLL: 'D. MMMM YYYY H:mm [Auer]',\n        LLLL: 'dddd, D. MMMM YYYY H:mm [Auer]'\n    },\n    calendar: {\n        sameDay: '[Haut um] LT',\n        sameElse: 'L',\n        nextDay: '[Muer um] LT',\n        nextWeek: 'dddd [um] LT',\n        lastDay: '[Gëschter um] LT',\n        lastWeek: function () {\n            // Different date string for 'Dënschdeg' (Tuesday) and 'Donneschdeg' (Thursday) due to phonological rule\n            switch (this.day()) {\n                case 2:\n                case 4:\n                    return '[Leschten] dddd [um] LT';\n                default:\n                    return '[Leschte] dddd [um] LT';\n            }\n        }\n    },\n    relativeTime : {\n        future : processFutureTime,\n        past : processPastTime,\n        s : 'e puer Sekonnen',\n        m : processRelativeTime,\n        mm : '%d Minutten',\n        h : processRelativeTime,\n        hh : '%d Stonnen',\n        d : processRelativeTime,\n        dd : '%d Deeg',\n        M : processRelativeTime,\n        MM : '%d Méint',\n        y : processRelativeTime,\n        yy : '%d Joer'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}\\./,\n    ordinal: '%d.',\n    week: {\n        dow: 1, // Monday is the first day of the week.\n        doy: 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/locale/lo.js",
    "content": "//! moment.js locale configuration\n//! locale : Lao [lo]\n//! author : Ryan Hart : https://github.com/ryanhart2\n\nimport moment from '../moment';\n\nexport default moment.defineLocale('lo', {\n    months : 'ມັງກອນ_ກຸມພາ_ມີນາ_ເມສາ_ພຶດສະພາ_ມິຖຸນາ_ກໍລະກົດ_ສິງຫາ_ກັນຍາ_ຕຸລາ_ພະຈິກ_ທັນວາ'.split('_'),\n    monthsShort : 'ມັງກອນ_ກຸມພາ_ມີນາ_ເມສາ_ພຶດສະພາ_ມິຖຸນາ_ກໍລະກົດ_ສິງຫາ_ກັນຍາ_ຕຸລາ_ພະຈິກ_ທັນວາ'.split('_'),\n    weekdays : 'ອາທິດ_ຈັນ_ອັງຄານ_ພຸດ_ພະຫັດ_ສຸກ_ເສົາ'.split('_'),\n    weekdaysShort : 'ທິດ_ຈັນ_ອັງຄານ_ພຸດ_ພະຫັດ_ສຸກ_ເສົາ'.split('_'),\n    weekdaysMin : 'ທ_ຈ_ອຄ_ພ_ພຫ_ສກ_ສ'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY HH:mm',\n        LLLL : 'ວັນdddd D MMMM YYYY HH:mm'\n    },\n    meridiemParse: /ຕອນເຊົ້າ|ຕອນແລງ/,\n    isPM: function (input) {\n        return input === 'ຕອນແລງ';\n    },\n    meridiem : function (hour, minute, isLower) {\n        if (hour < 12) {\n            return 'ຕອນເຊົ້າ';\n        } else {\n            return 'ຕອນແລງ';\n        }\n    },\n    calendar : {\n        sameDay : '[ມື້ນີ້ເວລາ] LT',\n        nextDay : '[ມື້ອື່ນເວລາ] LT',\n        nextWeek : '[ວັນ]dddd[ໜ້າເວລາ] LT',\n        lastDay : '[ມື້ວານນີ້ເວລາ] LT',\n        lastWeek : '[ວັນ]dddd[ແລ້ວນີ້ເວລາ] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'ອີກ %s',\n        past : '%sຜ່ານມາ',\n        s : 'ບໍ່ເທົ່າໃດວິນາທີ',\n        m : '1 ນາທີ',\n        mm : '%d ນາທີ',\n        h : '1 ຊົ່ວໂມງ',\n        hh : '%d ຊົ່ວໂມງ',\n        d : '1 ມື້',\n        dd : '%d ມື້',\n        M : '1 ເດືອນ',\n        MM : '%d ເດືອນ',\n        y : '1 ປີ',\n        yy : '%d ປີ'\n    },\n    dayOfMonthOrdinalParse: /(ທີ່)\\d{1,2}/,\n    ordinal : function (number) {\n        return 'ທີ່' + number;\n    }\n});\n\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/locale/lt.js",
    "content": "//! moment.js locale configuration\n//! locale : Lithuanian [lt]\n//! author : Mindaugas Mozūras : https://github.com/mmozuras\n\nimport moment from '../moment';\n\nvar units = {\n    'm' : 'minutė_minutės_minutę',\n    'mm': 'minutės_minučių_minutes',\n    'h' : 'valanda_valandos_valandą',\n    'hh': 'valandos_valandų_valandas',\n    'd' : 'diena_dienos_dieną',\n    'dd': 'dienos_dienų_dienas',\n    'M' : 'mėnuo_mėnesio_mėnesį',\n    'MM': 'mėnesiai_mėnesių_mėnesius',\n    'y' : 'metai_metų_metus',\n    'yy': 'metai_metų_metus'\n};\nfunction translateSeconds(number, withoutSuffix, key, isFuture) {\n    if (withoutSuffix) {\n        return 'kelios sekundės';\n    } else {\n        return isFuture ? 'kelių sekundžių' : 'kelias sekundes';\n    }\n}\nfunction translateSingular(number, withoutSuffix, key, isFuture) {\n    return withoutSuffix ? forms(key)[0] : (isFuture ? forms(key)[1] : forms(key)[2]);\n}\nfunction special(number) {\n    return number % 10 === 0 || (number > 10 && number < 20);\n}\nfunction forms(key) {\n    return units[key].split('_');\n}\nfunction translate(number, withoutSuffix, key, isFuture) {\n    var result = number + ' ';\n    if (number === 1) {\n        return result + translateSingular(number, withoutSuffix, key[0], isFuture);\n    } else if (withoutSuffix) {\n        return result + (special(number) ? forms(key)[1] : forms(key)[0]);\n    } else {\n        if (isFuture) {\n            return result + forms(key)[1];\n        } else {\n            return result + (special(number) ? forms(key)[1] : forms(key)[2]);\n        }\n    }\n}\nexport default moment.defineLocale('lt', {\n    months : {\n        format: 'sausio_vasario_kovo_balandžio_gegužės_birželio_liepos_rugpjūčio_rugsėjo_spalio_lapkričio_gruodžio'.split('_'),\n        standalone: 'sausis_vasaris_kovas_balandis_gegužė_birželis_liepa_rugpjūtis_rugsėjis_spalis_lapkritis_gruodis'.split('_'),\n        isFormat: /D[oD]?(\\[[^\\[\\]]*\\]|\\s)+MMMM?|MMMM?(\\[[^\\[\\]]*\\]|\\s)+D[oD]?/\n    },\n    monthsShort : 'sau_vas_kov_bal_geg_bir_lie_rgp_rgs_spa_lap_grd'.split('_'),\n    weekdays : {\n        format: 'sekmadienį_pirmadienį_antradienį_trečiadienį_ketvirtadienį_penktadienį_šeštadienį'.split('_'),\n        standalone: 'sekmadienis_pirmadienis_antradienis_trečiadienis_ketvirtadienis_penktadienis_šeštadienis'.split('_'),\n        isFormat: /dddd HH:mm/\n    },\n    weekdaysShort : 'Sek_Pir_Ant_Tre_Ket_Pen_Šeš'.split('_'),\n    weekdaysMin : 'S_P_A_T_K_Pn_Š'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'YYYY-MM-DD',\n        LL : 'YYYY [m.] MMMM D [d.]',\n        LLL : 'YYYY [m.] MMMM D [d.], HH:mm [val.]',\n        LLLL : 'YYYY [m.] MMMM D [d.], dddd, HH:mm [val.]',\n        l : 'YYYY-MM-DD',\n        ll : 'YYYY [m.] MMMM D [d.]',\n        lll : 'YYYY [m.] MMMM D [d.], HH:mm [val.]',\n        llll : 'YYYY [m.] MMMM D [d.], ddd, HH:mm [val.]'\n    },\n    calendar : {\n        sameDay : '[Šiandien] LT',\n        nextDay : '[Rytoj] LT',\n        nextWeek : 'dddd LT',\n        lastDay : '[Vakar] LT',\n        lastWeek : '[Praėjusį] dddd LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'po %s',\n        past : 'prieš %s',\n        s : translateSeconds,\n        m : translateSingular,\n        mm : translate,\n        h : translateSingular,\n        hh : translate,\n        d : translateSingular,\n        dd : translate,\n        M : translateSingular,\n        MM : translate,\n        y : translateSingular,\n        yy : translate\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}-oji/,\n    ordinal : function (number) {\n        return number + '-oji';\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/locale/lv.js",
    "content": "//! moment.js locale configuration\n//! locale : Latvian [lv]\n//! author : Kristaps Karlsons : https://github.com/skakri\n//! author : Jānis Elmeris : https://github.com/JanisE\n\nimport moment from '../moment';\n\nvar units = {\n    'm': 'minūtes_minūtēm_minūte_minūtes'.split('_'),\n    'mm': 'minūtes_minūtēm_minūte_minūtes'.split('_'),\n    'h': 'stundas_stundām_stunda_stundas'.split('_'),\n    'hh': 'stundas_stundām_stunda_stundas'.split('_'),\n    'd': 'dienas_dienām_diena_dienas'.split('_'),\n    'dd': 'dienas_dienām_diena_dienas'.split('_'),\n    'M': 'mēneša_mēnešiem_mēnesis_mēneši'.split('_'),\n    'MM': 'mēneša_mēnešiem_mēnesis_mēneši'.split('_'),\n    'y': 'gada_gadiem_gads_gadi'.split('_'),\n    'yy': 'gada_gadiem_gads_gadi'.split('_')\n};\n/**\n * @param withoutSuffix boolean true = a length of time; false = before/after a period of time.\n */\nfunction format(forms, number, withoutSuffix) {\n    if (withoutSuffix) {\n        // E.g. \"21 minūte\", \"3 minūtes\".\n        return number % 10 === 1 && number % 100 !== 11 ? forms[2] : forms[3];\n    } else {\n        // E.g. \"21 minūtes\" as in \"pēc 21 minūtes\".\n        // E.g. \"3 minūtēm\" as in \"pēc 3 minūtēm\".\n        return number % 10 === 1 && number % 100 !== 11 ? forms[0] : forms[1];\n    }\n}\nfunction relativeTimeWithPlural(number, withoutSuffix, key) {\n    return number + ' ' + format(units[key], number, withoutSuffix);\n}\nfunction relativeTimeWithSingular(number, withoutSuffix, key) {\n    return format(units[key], number, withoutSuffix);\n}\nfunction relativeSeconds(number, withoutSuffix) {\n    return withoutSuffix ? 'dažas sekundes' : 'dažām sekundēm';\n}\n\nexport default moment.defineLocale('lv', {\n    months : 'janvāris_februāris_marts_aprīlis_maijs_jūnijs_jūlijs_augusts_septembris_oktobris_novembris_decembris'.split('_'),\n    monthsShort : 'jan_feb_mar_apr_mai_jūn_jūl_aug_sep_okt_nov_dec'.split('_'),\n    weekdays : 'svētdiena_pirmdiena_otrdiena_trešdiena_ceturtdiena_piektdiena_sestdiena'.split('_'),\n    weekdaysShort : 'Sv_P_O_T_C_Pk_S'.split('_'),\n    weekdaysMin : 'Sv_P_O_T_C_Pk_S'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD.MM.YYYY.',\n        LL : 'YYYY. [gada] D. MMMM',\n        LLL : 'YYYY. [gada] D. MMMM, HH:mm',\n        LLLL : 'YYYY. [gada] D. MMMM, dddd, HH:mm'\n    },\n    calendar : {\n        sameDay : '[Šodien pulksten] LT',\n        nextDay : '[Rīt pulksten] LT',\n        nextWeek : 'dddd [pulksten] LT',\n        lastDay : '[Vakar pulksten] LT',\n        lastWeek : '[Pagājušā] dddd [pulksten] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'pēc %s',\n        past : 'pirms %s',\n        s : relativeSeconds,\n        m : relativeTimeWithSingular,\n        mm : relativeTimeWithPlural,\n        h : relativeTimeWithSingular,\n        hh : relativeTimeWithPlural,\n        d : relativeTimeWithSingular,\n        dd : relativeTimeWithPlural,\n        M : relativeTimeWithSingular,\n        MM : relativeTimeWithPlural,\n        y : relativeTimeWithSingular,\n        yy : relativeTimeWithPlural\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}\\./,\n    ordinal : '%d.',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/locale/me.js",
    "content": "//! moment.js locale configuration\n//! locale : Montenegrin [me]\n//! author : Miodrag Nikač <miodrag@restartit.me> : https://github.com/miodragnikac\n\nimport moment from '../moment';\n\nvar translator = {\n    words: { //Different grammatical cases\n        m: ['jedan minut', 'jednog minuta'],\n        mm: ['minut', 'minuta', 'minuta'],\n        h: ['jedan sat', 'jednog sata'],\n        hh: ['sat', 'sata', 'sati'],\n        dd: ['dan', 'dana', 'dana'],\n        MM: ['mjesec', 'mjeseca', 'mjeseci'],\n        yy: ['godina', 'godine', 'godina']\n    },\n    correctGrammaticalCase: function (number, wordKey) {\n        return number === 1 ? wordKey[0] : (number >= 2 && number <= 4 ? wordKey[1] : wordKey[2]);\n    },\n    translate: function (number, withoutSuffix, key) {\n        var wordKey = translator.words[key];\n        if (key.length === 1) {\n            return withoutSuffix ? wordKey[0] : wordKey[1];\n        } else {\n            return number + ' ' + translator.correctGrammaticalCase(number, wordKey);\n        }\n    }\n};\n\nexport default moment.defineLocale('me', {\n    months: 'januar_februar_mart_april_maj_jun_jul_avgust_septembar_oktobar_novembar_decembar'.split('_'),\n    monthsShort: 'jan._feb._mar._apr._maj_jun_jul_avg._sep._okt._nov._dec.'.split('_'),\n    monthsParseExact : true,\n    weekdays: 'nedjelja_ponedjeljak_utorak_srijeda_četvrtak_petak_subota'.split('_'),\n    weekdaysShort: 'ned._pon._uto._sri._čet._pet._sub.'.split('_'),\n    weekdaysMin: 'ne_po_ut_sr_če_pe_su'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat: {\n        LT: 'H:mm',\n        LTS : 'H:mm:ss',\n        L: 'DD.MM.YYYY',\n        LL: 'D. MMMM YYYY',\n        LLL: 'D. MMMM YYYY H:mm',\n        LLLL: 'dddd, D. MMMM YYYY H:mm'\n    },\n    calendar: {\n        sameDay: '[danas u] LT',\n        nextDay: '[sjutra u] LT',\n\n        nextWeek: function () {\n            switch (this.day()) {\n                case 0:\n                    return '[u] [nedjelju] [u] LT';\n                case 3:\n                    return '[u] [srijedu] [u] LT';\n                case 6:\n                    return '[u] [subotu] [u] LT';\n                case 1:\n                case 2:\n                case 4:\n                case 5:\n                    return '[u] dddd [u] LT';\n            }\n        },\n        lastDay  : '[juče u] LT',\n        lastWeek : function () {\n            var lastWeekDays = [\n                '[prošle] [nedjelje] [u] LT',\n                '[prošlog] [ponedjeljka] [u] LT',\n                '[prošlog] [utorka] [u] LT',\n                '[prošle] [srijede] [u] LT',\n                '[prošlog] [četvrtka] [u] LT',\n                '[prošlog] [petka] [u] LT',\n                '[prošle] [subote] [u] LT'\n            ];\n            return lastWeekDays[this.day()];\n        },\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'za %s',\n        past   : 'prije %s',\n        s      : 'nekoliko sekundi',\n        m      : translator.translate,\n        mm     : translator.translate,\n        h      : translator.translate,\n        hh     : translator.translate,\n        d      : 'dan',\n        dd     : translator.translate,\n        M      : 'mjesec',\n        MM     : translator.translate,\n        y      : 'godinu',\n        yy     : translator.translate\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}\\./,\n    ordinal : '%d.',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 7  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/locale/mi.js",
    "content": "//! moment.js locale configuration\n//! locale : Maori [mi]\n//! author : John Corrigan <robbiecloset@gmail.com> : https://github.com/johnideal\n\nimport moment from '../moment';\n\nexport default moment.defineLocale('mi', {\n    months: 'Kohi-tāte_Hui-tanguru_Poutū-te-rangi_Paenga-whāwhā_Haratua_Pipiri_Hōngoingoi_Here-turi-kōkā_Mahuru_Whiringa-ā-nuku_Whiringa-ā-rangi_Hakihea'.split('_'),\n    monthsShort: 'Kohi_Hui_Pou_Pae_Hara_Pipi_Hōngoi_Here_Mahu_Whi-nu_Whi-ra_Haki'.split('_'),\n    monthsRegex: /(?:['a-z\\u0101\\u014D\\u016B]+\\-?){1,3}/i,\n    monthsStrictRegex: /(?:['a-z\\u0101\\u014D\\u016B]+\\-?){1,3}/i,\n    monthsShortRegex: /(?:['a-z\\u0101\\u014D\\u016B]+\\-?){1,3}/i,\n    monthsShortStrictRegex: /(?:['a-z\\u0101\\u014D\\u016B]+\\-?){1,2}/i,\n    weekdays: 'Rātapu_Mane_Tūrei_Wenerei_Tāite_Paraire_Hātarei'.split('_'),\n    weekdaysShort: 'Ta_Ma_Tū_We_Tāi_Pa_Hā'.split('_'),\n    weekdaysMin: 'Ta_Ma_Tū_We_Tāi_Pa_Hā'.split('_'),\n    longDateFormat: {\n        LT: 'HH:mm',\n        LTS: 'HH:mm:ss',\n        L: 'DD/MM/YYYY',\n        LL: 'D MMMM YYYY',\n        LLL: 'D MMMM YYYY [i] HH:mm',\n        LLLL: 'dddd, D MMMM YYYY [i] HH:mm'\n    },\n    calendar: {\n        sameDay: '[i teie mahana, i] LT',\n        nextDay: '[apopo i] LT',\n        nextWeek: 'dddd [i] LT',\n        lastDay: '[inanahi i] LT',\n        lastWeek: 'dddd [whakamutunga i] LT',\n        sameElse: 'L'\n    },\n    relativeTime: {\n        future: 'i roto i %s',\n        past: '%s i mua',\n        s: 'te hēkona ruarua',\n        m: 'he meneti',\n        mm: '%d meneti',\n        h: 'te haora',\n        hh: '%d haora',\n        d: 'he ra',\n        dd: '%d ra',\n        M: 'he marama',\n        MM: '%d marama',\n        y: 'he tau',\n        yy: '%d tau'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}º/,\n    ordinal: '%dº',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/locale/mk.js",
    "content": "//! moment.js locale configuration\n//! locale : Macedonian [mk]\n//! author : Borislav Mickov : https://github.com/B0k0\n\nimport moment from '../moment';\n\nexport default moment.defineLocale('mk', {\n    months : 'јануари_февруари_март_април_мај_јуни_јули_август_септември_октомври_ноември_декември'.split('_'),\n    monthsShort : 'јан_фев_мар_апр_мај_јун_јул_авг_сеп_окт_ное_дек'.split('_'),\n    weekdays : 'недела_понеделник_вторник_среда_четврток_петок_сабота'.split('_'),\n    weekdaysShort : 'нед_пон_вто_сре_чет_пет_саб'.split('_'),\n    weekdaysMin : 'нe_пo_вт_ср_че_пе_сa'.split('_'),\n    longDateFormat : {\n        LT : 'H:mm',\n        LTS : 'H:mm:ss',\n        L : 'D.MM.YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY H:mm',\n        LLLL : 'dddd, D MMMM YYYY H:mm'\n    },\n    calendar : {\n        sameDay : '[Денес во] LT',\n        nextDay : '[Утре во] LT',\n        nextWeek : '[Во] dddd [во] LT',\n        lastDay : '[Вчера во] LT',\n        lastWeek : function () {\n            switch (this.day()) {\n                case 0:\n                case 3:\n                case 6:\n                    return '[Изминатата] dddd [во] LT';\n                case 1:\n                case 2:\n                case 4:\n                case 5:\n                    return '[Изминатиот] dddd [во] LT';\n            }\n        },\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'после %s',\n        past : 'пред %s',\n        s : 'неколку секунди',\n        m : 'минута',\n        mm : '%d минути',\n        h : 'час',\n        hh : '%d часа',\n        d : 'ден',\n        dd : '%d дена',\n        M : 'месец',\n        MM : '%d месеци',\n        y : 'година',\n        yy : '%d години'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}-(ев|ен|ти|ви|ри|ми)/,\n    ordinal : function (number) {\n        var lastDigit = number % 10,\n            last2Digits = number % 100;\n        if (number === 0) {\n            return number + '-ев';\n        } else if (last2Digits === 0) {\n            return number + '-ен';\n        } else if (last2Digits > 10 && last2Digits < 20) {\n            return number + '-ти';\n        } else if (lastDigit === 1) {\n            return number + '-ви';\n        } else if (lastDigit === 2) {\n            return number + '-ри';\n        } else if (lastDigit === 7 || lastDigit === 8) {\n            return number + '-ми';\n        } else {\n            return number + '-ти';\n        }\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 7  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/locale/ml.js",
    "content": "//! moment.js locale configuration\n//! locale : Malayalam [ml]\n//! author : Floyd Pink : https://github.com/floydpink\n\nimport moment from '../moment';\n\nexport default moment.defineLocale('ml', {\n    months : 'ജനുവരി_ഫെബ്രുവരി_മാർച്ച്_ഏപ്രിൽ_മേയ്_ജൂൺ_ജൂലൈ_ഓഗസ്റ്റ്_സെപ്റ്റംബർ_ഒക്ടോബർ_നവംബർ_ഡിസംബർ'.split('_'),\n    monthsShort : 'ജനു._ഫെബ്രു._മാർ._ഏപ്രി._മേയ്_ജൂൺ_ജൂലൈ._ഓഗ._സെപ്റ്റ._ഒക്ടോ._നവം._ഡിസം.'.split('_'),\n    monthsParseExact : true,\n    weekdays : 'ഞായറാഴ്ച_തിങ്കളാഴ്ച_ചൊവ്വാഴ്ച_ബുധനാഴ്ച_വ്യാഴാഴ്ച_വെള്ളിയാഴ്ച_ശനിയാഴ്ച'.split('_'),\n    weekdaysShort : 'ഞായർ_തിങ്കൾ_ചൊവ്വ_ബുധൻ_വ്യാഴം_വെള്ളി_ശനി'.split('_'),\n    weekdaysMin : 'ഞാ_തി_ചൊ_ബു_വ്യാ_വെ_ശ'.split('_'),\n    longDateFormat : {\n        LT : 'A h:mm -നു',\n        LTS : 'A h:mm:ss -നു',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY, A h:mm -നു',\n        LLLL : 'dddd, D MMMM YYYY, A h:mm -നു'\n    },\n    calendar : {\n        sameDay : '[ഇന്ന്] LT',\n        nextDay : '[നാളെ] LT',\n        nextWeek : 'dddd, LT',\n        lastDay : '[ഇന്നലെ] LT',\n        lastWeek : '[കഴിഞ്ഞ] dddd, LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : '%s കഴിഞ്ഞ്',\n        past : '%s മുൻപ്',\n        s : 'അൽപ നിമിഷങ്ങൾ',\n        m : 'ഒരു മിനിറ്റ്',\n        mm : '%d മിനിറ്റ്',\n        h : 'ഒരു മണിക്കൂർ',\n        hh : '%d മണിക്കൂർ',\n        d : 'ഒരു ദിവസം',\n        dd : '%d ദിവസം',\n        M : 'ഒരു മാസം',\n        MM : '%d മാസം',\n        y : 'ഒരു വർഷം',\n        yy : '%d വർഷം'\n    },\n    meridiemParse: /രാത്രി|രാവിലെ|ഉച്ച കഴിഞ്ഞ്|വൈകുന്നേരം|രാത്രി/i,\n    meridiemHour : function (hour, meridiem) {\n        if (hour === 12) {\n            hour = 0;\n        }\n        if ((meridiem === 'രാത്രി' && hour >= 4) ||\n                meridiem === 'ഉച്ച കഴിഞ്ഞ്' ||\n                meridiem === 'വൈകുന്നേരം') {\n            return hour + 12;\n        } else {\n            return hour;\n        }\n    },\n    meridiem : function (hour, minute, isLower) {\n        if (hour < 4) {\n            return 'രാത്രി';\n        } else if (hour < 12) {\n            return 'രാവിലെ';\n        } else if (hour < 17) {\n            return 'ഉച്ച കഴിഞ്ഞ്';\n        } else if (hour < 20) {\n            return 'വൈകുന്നേരം';\n        } else {\n            return 'രാത്രി';\n        }\n    }\n});\n\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/locale/mr.js",
    "content": "//! moment.js locale configuration\n//! locale : Marathi [mr]\n//! author : Harshad Kale : https://github.com/kalehv\n//! author : Vivek Athalye : https://github.com/vnathalye\n\nimport moment from '../moment';\n\nvar symbolMap = {\n    '1': '१',\n    '2': '२',\n    '3': '३',\n    '4': '४',\n    '5': '५',\n    '6': '६',\n    '7': '७',\n    '8': '८',\n    '9': '९',\n    '0': '०'\n},\nnumberMap = {\n    '१': '1',\n    '२': '2',\n    '३': '3',\n    '४': '4',\n    '५': '5',\n    '६': '6',\n    '७': '7',\n    '८': '8',\n    '९': '9',\n    '०': '0'\n};\n\nfunction relativeTimeMr(number, withoutSuffix, string, isFuture)\n{\n    var output = '';\n    if (withoutSuffix) {\n        switch (string) {\n            case 's': output = 'काही सेकंद'; break;\n            case 'm': output = 'एक मिनिट'; break;\n            case 'mm': output = '%d मिनिटे'; break;\n            case 'h': output = 'एक तास'; break;\n            case 'hh': output = '%d तास'; break;\n            case 'd': output = 'एक दिवस'; break;\n            case 'dd': output = '%d दिवस'; break;\n            case 'M': output = 'एक महिना'; break;\n            case 'MM': output = '%d महिने'; break;\n            case 'y': output = 'एक वर्ष'; break;\n            case 'yy': output = '%d वर्षे'; break;\n        }\n    }\n    else {\n        switch (string) {\n            case 's': output = 'काही सेकंदां'; break;\n            case 'm': output = 'एका मिनिटा'; break;\n            case 'mm': output = '%d मिनिटां'; break;\n            case 'h': output = 'एका तासा'; break;\n            case 'hh': output = '%d तासां'; break;\n            case 'd': output = 'एका दिवसा'; break;\n            case 'dd': output = '%d दिवसां'; break;\n            case 'M': output = 'एका महिन्या'; break;\n            case 'MM': output = '%d महिन्यां'; break;\n            case 'y': output = 'एका वर्षा'; break;\n            case 'yy': output = '%d वर्षां'; break;\n        }\n    }\n    return output.replace(/%d/i, number);\n}\n\nexport default moment.defineLocale('mr', {\n    months : 'जानेवारी_फेब्रुवारी_मार्च_एप्रिल_मे_जून_जुलै_ऑगस्ट_सप्टेंबर_ऑक्टोबर_नोव्हेंबर_डिसेंबर'.split('_'),\n    monthsShort: 'जाने._फेब्रु._मार्च._एप्रि._मे._जून._जुलै._ऑग._सप्टें._ऑक्टो._नोव्हें._डिसें.'.split('_'),\n    monthsParseExact : true,\n    weekdays : 'रविवार_सोमवार_मंगळवार_बुधवार_गुरूवार_शुक्रवार_शनिवार'.split('_'),\n    weekdaysShort : 'रवि_सोम_मंगळ_बुध_गुरू_शुक्र_शनि'.split('_'),\n    weekdaysMin : 'र_सो_मं_बु_गु_शु_श'.split('_'),\n    longDateFormat : {\n        LT : 'A h:mm वाजता',\n        LTS : 'A h:mm:ss वाजता',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY, A h:mm वाजता',\n        LLLL : 'dddd, D MMMM YYYY, A h:mm वाजता'\n    },\n    calendar : {\n        sameDay : '[आज] LT',\n        nextDay : '[उद्या] LT',\n        nextWeek : 'dddd, LT',\n        lastDay : '[काल] LT',\n        lastWeek: '[मागील] dddd, LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future: '%sमध्ये',\n        past: '%sपूर्वी',\n        s: relativeTimeMr,\n        m: relativeTimeMr,\n        mm: relativeTimeMr,\n        h: relativeTimeMr,\n        hh: relativeTimeMr,\n        d: relativeTimeMr,\n        dd: relativeTimeMr,\n        M: relativeTimeMr,\n        MM: relativeTimeMr,\n        y: relativeTimeMr,\n        yy: relativeTimeMr\n    },\n    preparse: function (string) {\n        return string.replace(/[१२३४५६७८९०]/g, function (match) {\n            return numberMap[match];\n        });\n    },\n    postformat: function (string) {\n        return string.replace(/\\d/g, function (match) {\n            return symbolMap[match];\n        });\n    },\n    meridiemParse: /रात्री|सकाळी|दुपारी|सायंकाळी/,\n    meridiemHour : function (hour, meridiem) {\n        if (hour === 12) {\n            hour = 0;\n        }\n        if (meridiem === 'रात्री') {\n            return hour < 4 ? hour : hour + 12;\n        } else if (meridiem === 'सकाळी') {\n            return hour;\n        } else if (meridiem === 'दुपारी') {\n            return hour >= 10 ? hour : hour + 12;\n        } else if (meridiem === 'सायंकाळी') {\n            return hour + 12;\n        }\n    },\n    meridiem: function (hour, minute, isLower) {\n        if (hour < 4) {\n            return 'रात्री';\n        } else if (hour < 10) {\n            return 'सकाळी';\n        } else if (hour < 17) {\n            return 'दुपारी';\n        } else if (hour < 20) {\n            return 'सायंकाळी';\n        } else {\n            return 'रात्री';\n        }\n    },\n    week : {\n        dow : 0, // Sunday is the first day of the week.\n        doy : 6  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/locale/ms-my.js",
    "content": "//! moment.js locale configuration\n//! locale : Malay [ms-my]\n//! note : DEPRECATED, the correct one is [ms]\n//! author : Weldan Jamili : https://github.com/weldan\n\nimport moment from '../moment';\n\nexport default moment.defineLocale('ms-my', {\n    months : 'Januari_Februari_Mac_April_Mei_Jun_Julai_Ogos_September_Oktober_November_Disember'.split('_'),\n    monthsShort : 'Jan_Feb_Mac_Apr_Mei_Jun_Jul_Ogs_Sep_Okt_Nov_Dis'.split('_'),\n    weekdays : 'Ahad_Isnin_Selasa_Rabu_Khamis_Jumaat_Sabtu'.split('_'),\n    weekdaysShort : 'Ahd_Isn_Sel_Rab_Kha_Jum_Sab'.split('_'),\n    weekdaysMin : 'Ah_Is_Sl_Rb_Km_Jm_Sb'.split('_'),\n    longDateFormat : {\n        LT : 'HH.mm',\n        LTS : 'HH.mm.ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY [pukul] HH.mm',\n        LLLL : 'dddd, D MMMM YYYY [pukul] HH.mm'\n    },\n    meridiemParse: /pagi|tengahari|petang|malam/,\n    meridiemHour: function (hour, meridiem) {\n        if (hour === 12) {\n            hour = 0;\n        }\n        if (meridiem === 'pagi') {\n            return hour;\n        } else if (meridiem === 'tengahari') {\n            return hour >= 11 ? hour : hour + 12;\n        } else if (meridiem === 'petang' || meridiem === 'malam') {\n            return hour + 12;\n        }\n    },\n    meridiem : function (hours, minutes, isLower) {\n        if (hours < 11) {\n            return 'pagi';\n        } else if (hours < 15) {\n            return 'tengahari';\n        } else if (hours < 19) {\n            return 'petang';\n        } else {\n            return 'malam';\n        }\n    },\n    calendar : {\n        sameDay : '[Hari ini pukul] LT',\n        nextDay : '[Esok pukul] LT',\n        nextWeek : 'dddd [pukul] LT',\n        lastDay : '[Kelmarin pukul] LT',\n        lastWeek : 'dddd [lepas pukul] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'dalam %s',\n        past : '%s yang lepas',\n        s : 'beberapa saat',\n        m : 'seminit',\n        mm : '%d minit',\n        h : 'sejam',\n        hh : '%d jam',\n        d : 'sehari',\n        dd : '%d hari',\n        M : 'sebulan',\n        MM : '%d bulan',\n        y : 'setahun',\n        yy : '%d tahun'\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 7  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/locale/ms.js",
    "content": "//! moment.js locale configuration\n//! locale : Malay [ms]\n//! author : Weldan Jamili : https://github.com/weldan\n\nimport moment from '../moment';\n\nexport default moment.defineLocale('ms', {\n    months : 'Januari_Februari_Mac_April_Mei_Jun_Julai_Ogos_September_Oktober_November_Disember'.split('_'),\n    monthsShort : 'Jan_Feb_Mac_Apr_Mei_Jun_Jul_Ogs_Sep_Okt_Nov_Dis'.split('_'),\n    weekdays : 'Ahad_Isnin_Selasa_Rabu_Khamis_Jumaat_Sabtu'.split('_'),\n    weekdaysShort : 'Ahd_Isn_Sel_Rab_Kha_Jum_Sab'.split('_'),\n    weekdaysMin : 'Ah_Is_Sl_Rb_Km_Jm_Sb'.split('_'),\n    longDateFormat : {\n        LT : 'HH.mm',\n        LTS : 'HH.mm.ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY [pukul] HH.mm',\n        LLLL : 'dddd, D MMMM YYYY [pukul] HH.mm'\n    },\n    meridiemParse: /pagi|tengahari|petang|malam/,\n    meridiemHour: function (hour, meridiem) {\n        if (hour === 12) {\n            hour = 0;\n        }\n        if (meridiem === 'pagi') {\n            return hour;\n        } else if (meridiem === 'tengahari') {\n            return hour >= 11 ? hour : hour + 12;\n        } else if (meridiem === 'petang' || meridiem === 'malam') {\n            return hour + 12;\n        }\n    },\n    meridiem : function (hours, minutes, isLower) {\n        if (hours < 11) {\n            return 'pagi';\n        } else if (hours < 15) {\n            return 'tengahari';\n        } else if (hours < 19) {\n            return 'petang';\n        } else {\n            return 'malam';\n        }\n    },\n    calendar : {\n        sameDay : '[Hari ini pukul] LT',\n        nextDay : '[Esok pukul] LT',\n        nextWeek : 'dddd [pukul] LT',\n        lastDay : '[Kelmarin pukul] LT',\n        lastWeek : 'dddd [lepas pukul] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'dalam %s',\n        past : '%s yang lepas',\n        s : 'beberapa saat',\n        m : 'seminit',\n        mm : '%d minit',\n        h : 'sejam',\n        hh : '%d jam',\n        d : 'sehari',\n        dd : '%d hari',\n        M : 'sebulan',\n        MM : '%d bulan',\n        y : 'setahun',\n        yy : '%d tahun'\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 7  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/locale/my.js",
    "content": "//! moment.js locale configuration\n//! locale : Burmese [my]\n//! author : Squar team, mysquar.com\n//! author : David Rossellat : https://github.com/gholadr\n//! author : Tin Aung Lin : https://github.com/thanyawzinmin\n\nimport moment from '../moment';\n\nvar symbolMap = {\n    '1': '၁',\n    '2': '၂',\n    '3': '၃',\n    '4': '၄',\n    '5': '၅',\n    '6': '၆',\n    '7': '၇',\n    '8': '၈',\n    '9': '၉',\n    '0': '၀'\n}, numberMap = {\n    '၁': '1',\n    '၂': '2',\n    '၃': '3',\n    '၄': '4',\n    '၅': '5',\n    '၆': '6',\n    '၇': '7',\n    '၈': '8',\n    '၉': '9',\n    '၀': '0'\n};\n\nexport default moment.defineLocale('my', {\n    months: 'ဇန်နဝါရီ_ဖေဖော်ဝါရီ_မတ်_ဧပြီ_မေ_ဇွန်_ဇူလိုင်_သြဂုတ်_စက်တင်ဘာ_အောက်တိုဘာ_နိုဝင်ဘာ_ဒီဇင်ဘာ'.split('_'),\n    monthsShort: 'ဇန်_ဖေ_မတ်_ပြီ_မေ_ဇွန်_လိုင်_သြ_စက်_အောက်_နို_ဒီ'.split('_'),\n    weekdays: 'တနင်္ဂနွေ_တနင်္လာ_အင်္ဂါ_ဗုဒ္ဓဟူး_ကြာသပတေး_သောကြာ_စနေ'.split('_'),\n    weekdaysShort: 'နွေ_လာ_ဂါ_ဟူး_ကြာ_သော_နေ'.split('_'),\n    weekdaysMin: 'နွေ_လာ_ဂါ_ဟူး_ကြာ_သော_နေ'.split('_'),\n\n    longDateFormat: {\n        LT: 'HH:mm',\n        LTS: 'HH:mm:ss',\n        L: 'DD/MM/YYYY',\n        LL: 'D MMMM YYYY',\n        LLL: 'D MMMM YYYY HH:mm',\n        LLLL: 'dddd D MMMM YYYY HH:mm'\n    },\n    calendar: {\n        sameDay: '[ယနေ.] LT [မှာ]',\n        nextDay: '[မနက်ဖြန်] LT [မှာ]',\n        nextWeek: 'dddd LT [မှာ]',\n        lastDay: '[မနေ.က] LT [မှာ]',\n        lastWeek: '[ပြီးခဲ့သော] dddd LT [မှာ]',\n        sameElse: 'L'\n    },\n    relativeTime: {\n        future: 'လာမည့် %s မှာ',\n        past: 'လွန်ခဲ့သော %s က',\n        s: 'စက္ကန်.အနည်းငယ်',\n        m: 'တစ်မိနစ်',\n        mm: '%d မိနစ်',\n        h: 'တစ်နာရီ',\n        hh: '%d နာရီ',\n        d: 'တစ်ရက်',\n        dd: '%d ရက်',\n        M: 'တစ်လ',\n        MM: '%d လ',\n        y: 'တစ်နှစ်',\n        yy: '%d နှစ်'\n    },\n    preparse: function (string) {\n        return string.replace(/[၁၂၃၄၅၆၇၈၉၀]/g, function (match) {\n            return numberMap[match];\n        });\n    },\n    postformat: function (string) {\n        return string.replace(/\\d/g, function (match) {\n            return symbolMap[match];\n        });\n    },\n    week: {\n        dow: 1, // Monday is the first day of the week.\n        doy: 4 // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/locale/nb.js",
    "content": "//! moment.js locale configuration\n//! locale : Norwegian Bokmål [nb]\n//! authors : Espen Hovlandsdal : https://github.com/rexxars\n//!           Sigurd Gartmann : https://github.com/sigurdga\n\nimport moment from '../moment';\n\nexport default moment.defineLocale('nb', {\n    months : 'januar_februar_mars_april_mai_juni_juli_august_september_oktober_november_desember'.split('_'),\n    monthsShort : 'jan._feb._mars_april_mai_juni_juli_aug._sep._okt._nov._des.'.split('_'),\n    monthsParseExact : true,\n    weekdays : 'søndag_mandag_tirsdag_onsdag_torsdag_fredag_lørdag'.split('_'),\n    weekdaysShort : 'sø._ma._ti._on._to._fr._lø.'.split('_'),\n    weekdaysMin : 'sø_ma_ti_on_to_fr_lø'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD.MM.YYYY',\n        LL : 'D. MMMM YYYY',\n        LLL : 'D. MMMM YYYY [kl.] HH:mm',\n        LLLL : 'dddd D. MMMM YYYY [kl.] HH:mm'\n    },\n    calendar : {\n        sameDay: '[i dag kl.] LT',\n        nextDay: '[i morgen kl.] LT',\n        nextWeek: 'dddd [kl.] LT',\n        lastDay: '[i går kl.] LT',\n        lastWeek: '[forrige] dddd [kl.] LT',\n        sameElse: 'L'\n    },\n    relativeTime : {\n        future : 'om %s',\n        past : '%s siden',\n        s : 'noen sekunder',\n        m : 'ett minutt',\n        mm : '%d minutter',\n        h : 'en time',\n        hh : '%d timer',\n        d : 'en dag',\n        dd : '%d dager',\n        M : 'en måned',\n        MM : '%d måneder',\n        y : 'ett år',\n        yy : '%d år'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}\\./,\n    ordinal : '%d.',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/locale/ne.js",
    "content": "//! moment.js locale configuration\n//! locale : Nepalese [ne]\n//! author : suvash : https://github.com/suvash\n\nimport moment from '../moment';\n\nvar symbolMap = {\n    '1': '१',\n    '2': '२',\n    '3': '३',\n    '4': '४',\n    '5': '५',\n    '6': '६',\n    '7': '७',\n    '8': '८',\n    '9': '९',\n    '0': '०'\n},\nnumberMap = {\n    '१': '1',\n    '२': '2',\n    '३': '3',\n    '४': '4',\n    '५': '5',\n    '६': '6',\n    '७': '7',\n    '८': '8',\n    '९': '9',\n    '०': '0'\n};\n\nexport default moment.defineLocale('ne', {\n    months : 'जनवरी_फेब्रुवरी_मार्च_अप्रिल_मई_जुन_जुलाई_अगष्ट_सेप्टेम्बर_अक्टोबर_नोभेम्बर_डिसेम्बर'.split('_'),\n    monthsShort : 'जन._फेब्रु._मार्च_अप्रि._मई_जुन_जुलाई._अग._सेप्ट._अक्टो._नोभे._डिसे.'.split('_'),\n    monthsParseExact : true,\n    weekdays : 'आइतबार_सोमबार_मङ्गलबार_बुधबार_बिहिबार_शुक्रबार_शनिबार'.split('_'),\n    weekdaysShort : 'आइत._सोम._मङ्गल._बुध._बिहि._शुक्र._शनि.'.split('_'),\n    weekdaysMin : 'आ._सो._मं._बु._बि._शु._श.'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat : {\n        LT : 'Aको h:mm बजे',\n        LTS : 'Aको h:mm:ss बजे',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY, Aको h:mm बजे',\n        LLLL : 'dddd, D MMMM YYYY, Aको h:mm बजे'\n    },\n    preparse: function (string) {\n        return string.replace(/[१२३४५६७८९०]/g, function (match) {\n            return numberMap[match];\n        });\n    },\n    postformat: function (string) {\n        return string.replace(/\\d/g, function (match) {\n            return symbolMap[match];\n        });\n    },\n    meridiemParse: /राति|बिहान|दिउँसो|साँझ/,\n    meridiemHour : function (hour, meridiem) {\n        if (hour === 12) {\n            hour = 0;\n        }\n        if (meridiem === 'राति') {\n            return hour < 4 ? hour : hour + 12;\n        } else if (meridiem === 'बिहान') {\n            return hour;\n        } else if (meridiem === 'दिउँसो') {\n            return hour >= 10 ? hour : hour + 12;\n        } else if (meridiem === 'साँझ') {\n            return hour + 12;\n        }\n    },\n    meridiem : function (hour, minute, isLower) {\n        if (hour < 3) {\n            return 'राति';\n        } else if (hour < 12) {\n            return 'बिहान';\n        } else if (hour < 16) {\n            return 'दिउँसो';\n        } else if (hour < 20) {\n            return 'साँझ';\n        } else {\n            return 'राति';\n        }\n    },\n    calendar : {\n        sameDay : '[आज] LT',\n        nextDay : '[भोलि] LT',\n        nextWeek : '[आउँदो] dddd[,] LT',\n        lastDay : '[हिजो] LT',\n        lastWeek : '[गएको] dddd[,] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : '%sमा',\n        past : '%s अगाडि',\n        s : 'केही क्षण',\n        m : 'एक मिनेट',\n        mm : '%d मिनेट',\n        h : 'एक घण्टा',\n        hh : '%d घण्टा',\n        d : 'एक दिन',\n        dd : '%d दिन',\n        M : 'एक महिना',\n        MM : '%d महिना',\n        y : 'एक बर्ष',\n        yy : '%d बर्ष'\n    },\n    week : {\n        dow : 0, // Sunday is the first day of the week.\n        doy : 6  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/locale/nl-be.js",
    "content": "//! moment.js locale configuration\n//! locale : Dutch (Belgium) [nl-be]\n//! author : Joris Röling : https://github.com/jorisroling\n//! author : Jacob Middag : https://github.com/middagj\n\nimport moment from '../moment';\n\nvar monthsShortWithDots = 'jan._feb._mrt._apr._mei_jun._jul._aug._sep._okt._nov._dec.'.split('_'),\n    monthsShortWithoutDots = 'jan_feb_mrt_apr_mei_jun_jul_aug_sep_okt_nov_dec'.split('_');\n\nvar monthsParse = [/^jan/i, /^feb/i, /^maart|mrt.?$/i, /^apr/i, /^mei$/i, /^jun[i.]?$/i, /^jul[i.]?$/i, /^aug/i, /^sep/i, /^okt/i, /^nov/i, /^dec/i];\nvar monthsRegex = /^(januari|februari|maart|april|mei|april|ju[nl]i|augustus|september|oktober|november|december|jan\\.?|feb\\.?|mrt\\.?|apr\\.?|ju[nl]\\.?|aug\\.?|sep\\.?|okt\\.?|nov\\.?|dec\\.?)/i;\n\nexport default moment.defineLocale('nl-be', {\n    months : 'januari_februari_maart_april_mei_juni_juli_augustus_september_oktober_november_december'.split('_'),\n    monthsShort : function (m, format) {\n        if (!m) {\n            return monthsShortWithDots;\n        } else if (/-MMM-/.test(format)) {\n            return monthsShortWithoutDots[m.month()];\n        } else {\n            return monthsShortWithDots[m.month()];\n        }\n    },\n\n    monthsRegex: monthsRegex,\n    monthsShortRegex: monthsRegex,\n    monthsStrictRegex: /^(januari|februari|maart|mei|ju[nl]i|april|augustus|september|oktober|november|december)/i,\n    monthsShortStrictRegex: /^(jan\\.?|feb\\.?|mrt\\.?|apr\\.?|mei|ju[nl]\\.?|aug\\.?|sep\\.?|okt\\.?|nov\\.?|dec\\.?)/i,\n\n    monthsParse : monthsParse,\n    longMonthsParse : monthsParse,\n    shortMonthsParse : monthsParse,\n\n    weekdays : 'zondag_maandag_dinsdag_woensdag_donderdag_vrijdag_zaterdag'.split('_'),\n    weekdaysShort : 'zo._ma._di._wo._do._vr._za.'.split('_'),\n    weekdaysMin : 'Zo_Ma_Di_Wo_Do_Vr_Za'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY HH:mm',\n        LLLL : 'dddd D MMMM YYYY HH:mm'\n    },\n    calendar : {\n        sameDay: '[vandaag om] LT',\n        nextDay: '[morgen om] LT',\n        nextWeek: 'dddd [om] LT',\n        lastDay: '[gisteren om] LT',\n        lastWeek: '[afgelopen] dddd [om] LT',\n        sameElse: 'L'\n    },\n    relativeTime : {\n        future : 'over %s',\n        past : '%s geleden',\n        s : 'een paar seconden',\n        m : 'één minuut',\n        mm : '%d minuten',\n        h : 'één uur',\n        hh : '%d uur',\n        d : 'één dag',\n        dd : '%d dagen',\n        M : 'één maand',\n        MM : '%d maanden',\n        y : 'één jaar',\n        yy : '%d jaar'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}(ste|de)/,\n    ordinal : function (number) {\n        return number + ((number === 1 || number === 8 || number >= 20) ? 'ste' : 'de');\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/locale/nl.js",
    "content": "//! moment.js locale configuration\n//! locale : Dutch [nl]\n//! author : Joris Röling : https://github.com/jorisroling\n//! author : Jacob Middag : https://github.com/middagj\n\nimport moment from '../moment';\n\nvar monthsShortWithDots = 'jan._feb._mrt._apr._mei_jun._jul._aug._sep._okt._nov._dec.'.split('_'),\n    monthsShortWithoutDots = 'jan_feb_mrt_apr_mei_jun_jul_aug_sep_okt_nov_dec'.split('_');\n\nvar monthsParse = [/^jan/i, /^feb/i, /^maart|mrt.?$/i, /^apr/i, /^mei$/i, /^jun[i.]?$/i, /^jul[i.]?$/i, /^aug/i, /^sep/i, /^okt/i, /^nov/i, /^dec/i];\nvar monthsRegex = /^(januari|februari|maart|april|mei|april|ju[nl]i|augustus|september|oktober|november|december|jan\\.?|feb\\.?|mrt\\.?|apr\\.?|ju[nl]\\.?|aug\\.?|sep\\.?|okt\\.?|nov\\.?|dec\\.?)/i;\n\nexport default moment.defineLocale('nl', {\n    months : 'januari_februari_maart_april_mei_juni_juli_augustus_september_oktober_november_december'.split('_'),\n    monthsShort : function (m, format) {\n        if (!m) {\n            return monthsShortWithDots;\n        } else if (/-MMM-/.test(format)) {\n            return monthsShortWithoutDots[m.month()];\n        } else {\n            return monthsShortWithDots[m.month()];\n        }\n    },\n\n    monthsRegex: monthsRegex,\n    monthsShortRegex: monthsRegex,\n    monthsStrictRegex: /^(januari|februari|maart|mei|ju[nl]i|april|augustus|september|oktober|november|december)/i,\n    monthsShortStrictRegex: /^(jan\\.?|feb\\.?|mrt\\.?|apr\\.?|mei|ju[nl]\\.?|aug\\.?|sep\\.?|okt\\.?|nov\\.?|dec\\.?)/i,\n\n    monthsParse : monthsParse,\n    longMonthsParse : monthsParse,\n    shortMonthsParse : monthsParse,\n\n    weekdays : 'zondag_maandag_dinsdag_woensdag_donderdag_vrijdag_zaterdag'.split('_'),\n    weekdaysShort : 'zo._ma._di._wo._do._vr._za.'.split('_'),\n    weekdaysMin : 'Zo_Ma_Di_Wo_Do_Vr_Za'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD-MM-YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY HH:mm',\n        LLLL : 'dddd D MMMM YYYY HH:mm'\n    },\n    calendar : {\n        sameDay: '[vandaag om] LT',\n        nextDay: '[morgen om] LT',\n        nextWeek: 'dddd [om] LT',\n        lastDay: '[gisteren om] LT',\n        lastWeek: '[afgelopen] dddd [om] LT',\n        sameElse: 'L'\n    },\n    relativeTime : {\n        future : 'over %s',\n        past : '%s geleden',\n        s : 'een paar seconden',\n        m : 'één minuut',\n        mm : '%d minuten',\n        h : 'één uur',\n        hh : '%d uur',\n        d : 'één dag',\n        dd : '%d dagen',\n        M : 'één maand',\n        MM : '%d maanden',\n        y : 'één jaar',\n        yy : '%d jaar'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}(ste|de)/,\n    ordinal : function (number) {\n        return number + ((number === 1 || number === 8 || number >= 20) ? 'ste' : 'de');\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/locale/nn.js",
    "content": "//! moment.js locale configuration\n//! locale : Nynorsk [nn]\n//! author : https://github.com/mechuwind\n\nimport moment from '../moment';\n\nexport default moment.defineLocale('nn', {\n    months : 'januar_februar_mars_april_mai_juni_juli_august_september_oktober_november_desember'.split('_'),\n    monthsShort : 'jan_feb_mar_apr_mai_jun_jul_aug_sep_okt_nov_des'.split('_'),\n    weekdays : 'sundag_måndag_tysdag_onsdag_torsdag_fredag_laurdag'.split('_'),\n    weekdaysShort : 'sun_mån_tys_ons_tor_fre_lau'.split('_'),\n    weekdaysMin : 'su_må_ty_on_to_fr_lø'.split('_'),\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD.MM.YYYY',\n        LL : 'D. MMMM YYYY',\n        LLL : 'D. MMMM YYYY [kl.] H:mm',\n        LLLL : 'dddd D. MMMM YYYY [kl.] HH:mm'\n    },\n    calendar : {\n        sameDay: '[I dag klokka] LT',\n        nextDay: '[I morgon klokka] LT',\n        nextWeek: 'dddd [klokka] LT',\n        lastDay: '[I går klokka] LT',\n        lastWeek: '[Føregåande] dddd [klokka] LT',\n        sameElse: 'L'\n    },\n    relativeTime : {\n        future : 'om %s',\n        past : '%s sidan',\n        s : 'nokre sekund',\n        m : 'eit minutt',\n        mm : '%d minutt',\n        h : 'ein time',\n        hh : '%d timar',\n        d : 'ein dag',\n        dd : '%d dagar',\n        M : 'ein månad',\n        MM : '%d månader',\n        y : 'eit år',\n        yy : '%d år'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}\\./,\n    ordinal : '%d.',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/locale/pa-in.js",
    "content": "//! moment.js locale configuration\n//! locale : Punjabi (India) [pa-in]\n//! author : Harpreet Singh : https://github.com/harpreetkhalsagtbit\n\nimport moment from '../moment';\n\nvar symbolMap = {\n    '1': '੧',\n    '2': '੨',\n    '3': '੩',\n    '4': '੪',\n    '5': '੫',\n    '6': '੬',\n    '7': '੭',\n    '8': '੮',\n    '9': '੯',\n    '0': '੦'\n},\nnumberMap = {\n    '੧': '1',\n    '੨': '2',\n    '੩': '3',\n    '੪': '4',\n    '੫': '5',\n    '੬': '6',\n    '੭': '7',\n    '੮': '8',\n    '੯': '9',\n    '੦': '0'\n};\n\nexport default moment.defineLocale('pa-in', {\n    // There are months name as per Nanakshahi Calender but they are not used as rigidly in modern Punjabi.\n    months : 'ਜਨਵਰੀ_ਫ਼ਰਵਰੀ_ਮਾਰਚ_ਅਪ੍ਰੈਲ_ਮਈ_ਜੂਨ_ਜੁਲਾਈ_ਅਗਸਤ_ਸਤੰਬਰ_ਅਕਤੂਬਰ_ਨਵੰਬਰ_ਦਸੰਬਰ'.split('_'),\n    monthsShort : 'ਜਨਵਰੀ_ਫ਼ਰਵਰੀ_ਮਾਰਚ_ਅਪ੍ਰੈਲ_ਮਈ_ਜੂਨ_ਜੁਲਾਈ_ਅਗਸਤ_ਸਤੰਬਰ_ਅਕਤੂਬਰ_ਨਵੰਬਰ_ਦਸੰਬਰ'.split('_'),\n    weekdays : 'ਐਤਵਾਰ_ਸੋਮਵਾਰ_ਮੰਗਲਵਾਰ_ਬੁਧਵਾਰ_ਵੀਰਵਾਰ_ਸ਼ੁੱਕਰਵਾਰ_ਸ਼ਨੀਚਰਵਾਰ'.split('_'),\n    weekdaysShort : 'ਐਤ_ਸੋਮ_ਮੰਗਲ_ਬੁਧ_ਵੀਰ_ਸ਼ੁਕਰ_ਸ਼ਨੀ'.split('_'),\n    weekdaysMin : 'ਐਤ_ਸੋਮ_ਮੰਗਲ_ਬੁਧ_ਵੀਰ_ਸ਼ੁਕਰ_ਸ਼ਨੀ'.split('_'),\n    longDateFormat : {\n        LT : 'A h:mm ਵਜੇ',\n        LTS : 'A h:mm:ss ਵਜੇ',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY, A h:mm ਵਜੇ',\n        LLLL : 'dddd, D MMMM YYYY, A h:mm ਵਜੇ'\n    },\n    calendar : {\n        sameDay : '[ਅਜ] LT',\n        nextDay : '[ਕਲ] LT',\n        nextWeek : 'dddd, LT',\n        lastDay : '[ਕਲ] LT',\n        lastWeek : '[ਪਿਛਲੇ] dddd, LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : '%s ਵਿੱਚ',\n        past : '%s ਪਿਛਲੇ',\n        s : 'ਕੁਝ ਸਕਿੰਟ',\n        m : 'ਇਕ ਮਿੰਟ',\n        mm : '%d ਮਿੰਟ',\n        h : 'ਇੱਕ ਘੰਟਾ',\n        hh : '%d ਘੰਟੇ',\n        d : 'ਇੱਕ ਦਿਨ',\n        dd : '%d ਦਿਨ',\n        M : 'ਇੱਕ ਮਹੀਨਾ',\n        MM : '%d ਮਹੀਨੇ',\n        y : 'ਇੱਕ ਸਾਲ',\n        yy : '%d ਸਾਲ'\n    },\n    preparse: function (string) {\n        return string.replace(/[੧੨੩੪੫੬੭੮੯੦]/g, function (match) {\n            return numberMap[match];\n        });\n    },\n    postformat: function (string) {\n        return string.replace(/\\d/g, function (match) {\n            return symbolMap[match];\n        });\n    },\n    // Punjabi notation for meridiems are quite fuzzy in practice. While there exists\n    // a rigid notion of a 'Pahar' it is not used as rigidly in modern Punjabi.\n    meridiemParse: /ਰਾਤ|ਸਵੇਰ|ਦੁਪਹਿਰ|ਸ਼ਾਮ/,\n    meridiemHour : function (hour, meridiem) {\n        if (hour === 12) {\n            hour = 0;\n        }\n        if (meridiem === 'ਰਾਤ') {\n            return hour < 4 ? hour : hour + 12;\n        } else if (meridiem === 'ਸਵੇਰ') {\n            return hour;\n        } else if (meridiem === 'ਦੁਪਹਿਰ') {\n            return hour >= 10 ? hour : hour + 12;\n        } else if (meridiem === 'ਸ਼ਾਮ') {\n            return hour + 12;\n        }\n    },\n    meridiem : function (hour, minute, isLower) {\n        if (hour < 4) {\n            return 'ਰਾਤ';\n        } else if (hour < 10) {\n            return 'ਸਵੇਰ';\n        } else if (hour < 17) {\n            return 'ਦੁਪਹਿਰ';\n        } else if (hour < 20) {\n            return 'ਸ਼ਾਮ';\n        } else {\n            return 'ਰਾਤ';\n        }\n    },\n    week : {\n        dow : 0, // Sunday is the first day of the week.\n        doy : 6  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/locale/pl.js",
    "content": "//! moment.js locale configuration\n//! locale : Polish [pl]\n//! author : Rafal Hirsz : https://github.com/evoL\n\nimport moment from '../moment';\n\nvar monthsNominative = 'styczeń_luty_marzec_kwiecień_maj_czerwiec_lipiec_sierpień_wrzesień_październik_listopad_grudzień'.split('_'),\n    monthsSubjective = 'stycznia_lutego_marca_kwietnia_maja_czerwca_lipca_sierpnia_września_października_listopada_grudnia'.split('_');\nfunction plural(n) {\n    return (n % 10 < 5) && (n % 10 > 1) && ((~~(n / 10) % 10) !== 1);\n}\nfunction translate(number, withoutSuffix, key) {\n    var result = number + ' ';\n    switch (key) {\n        case 'm':\n            return withoutSuffix ? 'minuta' : 'minutę';\n        case 'mm':\n            return result + (plural(number) ? 'minuty' : 'minut');\n        case 'h':\n            return withoutSuffix  ? 'godzina'  : 'godzinę';\n        case 'hh':\n            return result + (plural(number) ? 'godziny' : 'godzin');\n        case 'MM':\n            return result + (plural(number) ? 'miesiące' : 'miesięcy');\n        case 'yy':\n            return result + (plural(number) ? 'lata' : 'lat');\n    }\n}\n\nexport default moment.defineLocale('pl', {\n    months : function (momentToFormat, format) {\n        if (!momentToFormat) {\n            return monthsNominative;\n        } else if (format === '') {\n            // Hack: if format empty we know this is used to generate\n            // RegExp by moment. Give then back both valid forms of months\n            // in RegExp ready format.\n            return '(' + monthsSubjective[momentToFormat.month()] + '|' + monthsNominative[momentToFormat.month()] + ')';\n        } else if (/D MMMM/.test(format)) {\n            return monthsSubjective[momentToFormat.month()];\n        } else {\n            return monthsNominative[momentToFormat.month()];\n        }\n    },\n    monthsShort : 'sty_lut_mar_kwi_maj_cze_lip_sie_wrz_paź_lis_gru'.split('_'),\n    weekdays : 'niedziela_poniedziałek_wtorek_środa_czwartek_piątek_sobota'.split('_'),\n    weekdaysShort : 'ndz_pon_wt_śr_czw_pt_sob'.split('_'),\n    weekdaysMin : 'Nd_Pn_Wt_Śr_Cz_Pt_So'.split('_'),\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD.MM.YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY HH:mm',\n        LLLL : 'dddd, D MMMM YYYY HH:mm'\n    },\n    calendar : {\n        sameDay: '[Dziś o] LT',\n        nextDay: '[Jutro o] LT',\n        nextWeek: '[W] dddd [o] LT',\n        lastDay: '[Wczoraj o] LT',\n        lastWeek: function () {\n            switch (this.day()) {\n                case 0:\n                    return '[W zeszłą niedzielę o] LT';\n                case 3:\n                    return '[W zeszłą środę o] LT';\n                case 6:\n                    return '[W zeszłą sobotę o] LT';\n                default:\n                    return '[W zeszły] dddd [o] LT';\n            }\n        },\n        sameElse: 'L'\n    },\n    relativeTime : {\n        future : 'za %s',\n        past : '%s temu',\n        s : 'kilka sekund',\n        m : translate,\n        mm : translate,\n        h : translate,\n        hh : translate,\n        d : '1 dzień',\n        dd : '%d dni',\n        M : 'miesiąc',\n        MM : translate,\n        y : 'rok',\n        yy : translate\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}\\./,\n    ordinal : '%d.',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/locale/pt-br.js",
    "content": "//! moment.js locale configuration\n//! locale : Portuguese (Brazil) [pt-br]\n//! author : Caio Ribeiro Pereira : https://github.com/caio-ribeiro-pereira\n\nimport moment from '../moment';\n\nexport default moment.defineLocale('pt-br', {\n    months : 'Janeiro_Fevereiro_Março_Abril_Maio_Junho_Julho_Agosto_Setembro_Outubro_Novembro_Dezembro'.split('_'),\n    monthsShort : 'Jan_Fev_Mar_Abr_Mai_Jun_Jul_Ago_Set_Out_Nov_Dez'.split('_'),\n    weekdays : 'Domingo_Segunda-feira_Terça-feira_Quarta-feira_Quinta-feira_Sexta-feira_Sábado'.split('_'),\n    weekdaysShort : 'Dom_Seg_Ter_Qua_Qui_Sex_Sáb'.split('_'),\n    weekdaysMin : 'Do_2ª_3ª_4ª_5ª_6ª_Sá'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D [de] MMMM [de] YYYY',\n        LLL : 'D [de] MMMM [de] YYYY [às] HH:mm',\n        LLLL : 'dddd, D [de] MMMM [de] YYYY [às] HH:mm'\n    },\n    calendar : {\n        sameDay: '[Hoje às] LT',\n        nextDay: '[Amanhã às] LT',\n        nextWeek: 'dddd [às] LT',\n        lastDay: '[Ontem às] LT',\n        lastWeek: function () {\n            return (this.day() === 0 || this.day() === 6) ?\n                '[Último] dddd [às] LT' : // Saturday + Sunday\n                '[Última] dddd [às] LT'; // Monday - Friday\n        },\n        sameElse: 'L'\n    },\n    relativeTime : {\n        future : 'em %s',\n        past : '%s atrás',\n        s : 'poucos segundos',\n        m : 'um minuto',\n        mm : '%d minutos',\n        h : 'uma hora',\n        hh : '%d horas',\n        d : 'um dia',\n        dd : '%d dias',\n        M : 'um mês',\n        MM : '%d meses',\n        y : 'um ano',\n        yy : '%d anos'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}º/,\n    ordinal : '%dº'\n});\n\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/locale/pt.js",
    "content": "//! moment.js locale configuration\n//! locale : Portuguese [pt]\n//! author : Jefferson : https://github.com/jalex79\n\nimport moment from '../moment';\n\nexport default moment.defineLocale('pt', {\n    months : 'Janeiro_Fevereiro_Março_Abril_Maio_Junho_Julho_Agosto_Setembro_Outubro_Novembro_Dezembro'.split('_'),\n    monthsShort : 'Jan_Fev_Mar_Abr_Mai_Jun_Jul_Ago_Set_Out_Nov_Dez'.split('_'),\n    weekdays : 'Domingo_Segunda-Feira_Terça-Feira_Quarta-Feira_Quinta-Feira_Sexta-Feira_Sábado'.split('_'),\n    weekdaysShort : 'Dom_Seg_Ter_Qua_Qui_Sex_Sáb'.split('_'),\n    weekdaysMin : 'Do_2ª_3ª_4ª_5ª_6ª_Sá'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D [de] MMMM [de] YYYY',\n        LLL : 'D [de] MMMM [de] YYYY HH:mm',\n        LLLL : 'dddd, D [de] MMMM [de] YYYY HH:mm'\n    },\n    calendar : {\n        sameDay: '[Hoje às] LT',\n        nextDay: '[Amanhã às] LT',\n        nextWeek: 'dddd [às] LT',\n        lastDay: '[Ontem às] LT',\n        lastWeek: function () {\n            return (this.day() === 0 || this.day() === 6) ?\n                '[Último] dddd [às] LT' : // Saturday + Sunday\n                '[Última] dddd [às] LT'; // Monday - Friday\n        },\n        sameElse: 'L'\n    },\n    relativeTime : {\n        future : 'em %s',\n        past : 'há %s',\n        s : 'segundos',\n        m : 'um minuto',\n        mm : '%d minutos',\n        h : 'uma hora',\n        hh : '%d horas',\n        d : 'um dia',\n        dd : '%d dias',\n        M : 'um mês',\n        MM : '%d meses',\n        y : 'um ano',\n        yy : '%d anos'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}º/,\n    ordinal : '%dº',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/locale/ro.js",
    "content": "//! moment.js locale configuration\n//! locale : Romanian [ro]\n//! author : Vlad Gurdiga : https://github.com/gurdiga\n//! author : Valentin Agachi : https://github.com/avaly\n\nimport moment from '../moment';\n\nfunction relativeTimeWithPlural(number, withoutSuffix, key) {\n    var format = {\n            'mm': 'minute',\n            'hh': 'ore',\n            'dd': 'zile',\n            'MM': 'luni',\n            'yy': 'ani'\n        },\n        separator = ' ';\n    if (number % 100 >= 20 || (number >= 100 && number % 100 === 0)) {\n        separator = ' de ';\n    }\n    return number + separator + format[key];\n}\n\nexport default moment.defineLocale('ro', {\n    months : 'ianuarie_februarie_martie_aprilie_mai_iunie_iulie_august_septembrie_octombrie_noiembrie_decembrie'.split('_'),\n    monthsShort : 'ian._febr._mart._apr._mai_iun._iul._aug._sept._oct._nov._dec.'.split('_'),\n    monthsParseExact: true,\n    weekdays : 'duminică_luni_marți_miercuri_joi_vineri_sâmbătă'.split('_'),\n    weekdaysShort : 'Dum_Lun_Mar_Mie_Joi_Vin_Sâm'.split('_'),\n    weekdaysMin : 'Du_Lu_Ma_Mi_Jo_Vi_Sâ'.split('_'),\n    longDateFormat : {\n        LT : 'H:mm',\n        LTS : 'H:mm:ss',\n        L : 'DD.MM.YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY H:mm',\n        LLLL : 'dddd, D MMMM YYYY H:mm'\n    },\n    calendar : {\n        sameDay: '[azi la] LT',\n        nextDay: '[mâine la] LT',\n        nextWeek: 'dddd [la] LT',\n        lastDay: '[ieri la] LT',\n        lastWeek: '[fosta] dddd [la] LT',\n        sameElse: 'L'\n    },\n    relativeTime : {\n        future : 'peste %s',\n        past : '%s în urmă',\n        s : 'câteva secunde',\n        m : 'un minut',\n        mm : relativeTimeWithPlural,\n        h : 'o oră',\n        hh : relativeTimeWithPlural,\n        d : 'o zi',\n        dd : relativeTimeWithPlural,\n        M : 'o lună',\n        MM : relativeTimeWithPlural,\n        y : 'un an',\n        yy : relativeTimeWithPlural\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 7  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/locale/ru.js",
    "content": "//! moment.js locale configuration\n//! locale : Russian [ru]\n//! author : Viktorminator : https://github.com/Viktorminator\n//! Author : Menelion Elensúle : https://github.com/Oire\n//! author : Коренберг Марк : https://github.com/socketpair\n\nimport moment from '../moment';\n\nfunction plural(word, num) {\n    var forms = word.split('_');\n    return num % 10 === 1 && num % 100 !== 11 ? forms[0] : (num % 10 >= 2 && num % 10 <= 4 && (num % 100 < 10 || num % 100 >= 20) ? forms[1] : forms[2]);\n}\nfunction relativeTimeWithPlural(number, withoutSuffix, key) {\n    var format = {\n        'mm': withoutSuffix ? 'минута_минуты_минут' : 'минуту_минуты_минут',\n        'hh': 'час_часа_часов',\n        'dd': 'день_дня_дней',\n        'MM': 'месяц_месяца_месяцев',\n        'yy': 'год_года_лет'\n    };\n    if (key === 'm') {\n        return withoutSuffix ? 'минута' : 'минуту';\n    }\n    else {\n        return number + ' ' + plural(format[key], +number);\n    }\n}\nvar monthsParse = [/^янв/i, /^фев/i, /^мар/i, /^апр/i, /^ма[йя]/i, /^июн/i, /^июл/i, /^авг/i, /^сен/i, /^окт/i, /^ноя/i, /^дек/i];\n\n// http://new.gramota.ru/spravka/rules/139-prop : § 103\n// Сокращения месяцев: http://new.gramota.ru/spravka/buro/search-answer?s=242637\n// CLDR data:          http://www.unicode.org/cldr/charts/28/summary/ru.html#1753\nexport default moment.defineLocale('ru', {\n    months : {\n        format: 'января_февраля_марта_апреля_мая_июня_июля_августа_сентября_октября_ноября_декабря'.split('_'),\n        standalone: 'январь_февраль_март_апрель_май_июнь_июль_август_сентябрь_октябрь_ноябрь_декабрь'.split('_')\n    },\n    monthsShort : {\n        // по CLDR именно \"июл.\" и \"июн.\", но какой смысл менять букву на точку ?\n        format: 'янв._февр._мар._апр._мая_июня_июля_авг._сент._окт._нояб._дек.'.split('_'),\n        standalone: 'янв._февр._март_апр._май_июнь_июль_авг._сент._окт._нояб._дек.'.split('_')\n    },\n    weekdays : {\n        standalone: 'воскресенье_понедельник_вторник_среда_четверг_пятница_суббота'.split('_'),\n        format: 'воскресенье_понедельник_вторник_среду_четверг_пятницу_субботу'.split('_'),\n        isFormat: /\\[ ?[Вв] ?(?:прошлую|следующую|эту)? ?\\] ?dddd/\n    },\n    weekdaysShort : 'вс_пн_вт_ср_чт_пт_сб'.split('_'),\n    weekdaysMin : 'вс_пн_вт_ср_чт_пт_сб'.split('_'),\n    monthsParse : monthsParse,\n    longMonthsParse : monthsParse,\n    shortMonthsParse : monthsParse,\n\n    // полные названия с падежами, по три буквы, для некоторых, по 4 буквы, сокращения с точкой и без точки\n    monthsRegex: /^(январ[ья]|янв\\.?|феврал[ья]|февр?\\.?|марта?|мар\\.?|апрел[ья]|апр\\.?|ма[йя]|июн[ья]|июн\\.?|июл[ья]|июл\\.?|августа?|авг\\.?|сентябр[ья]|сент?\\.?|октябр[ья]|окт\\.?|ноябр[ья]|нояб?\\.?|декабр[ья]|дек\\.?)/i,\n\n    // копия предыдущего\n    monthsShortRegex: /^(январ[ья]|янв\\.?|феврал[ья]|февр?\\.?|марта?|мар\\.?|апрел[ья]|апр\\.?|ма[йя]|июн[ья]|июн\\.?|июл[ья]|июл\\.?|августа?|авг\\.?|сентябр[ья]|сент?\\.?|октябр[ья]|окт\\.?|ноябр[ья]|нояб?\\.?|декабр[ья]|дек\\.?)/i,\n\n    // полные названия с падежами\n    monthsStrictRegex: /^(январ[яь]|феврал[яь]|марта?|апрел[яь]|ма[яй]|июн[яь]|июл[яь]|августа?|сентябр[яь]|октябр[яь]|ноябр[яь]|декабр[яь])/i,\n\n    // Выражение, которое соотвествует только сокращённым формам\n    monthsShortStrictRegex: /^(янв\\.|февр?\\.|мар[т.]|апр\\.|ма[яй]|июн[ья.]|июл[ья.]|авг\\.|сент?\\.|окт\\.|нояб?\\.|дек\\.)/i,\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD.MM.YYYY',\n        LL : 'D MMMM YYYY г.',\n        LLL : 'D MMMM YYYY г., HH:mm',\n        LLLL : 'dddd, D MMMM YYYY г., HH:mm'\n    },\n    calendar : {\n        sameDay: '[Сегодня в] LT',\n        nextDay: '[Завтра в] LT',\n        lastDay: '[Вчера в] LT',\n        nextWeek: function (now) {\n            if (now.week() !== this.week()) {\n                switch (this.day()) {\n                    case 0:\n                        return '[В следующее] dddd [в] LT';\n                    case 1:\n                    case 2:\n                    case 4:\n                        return '[В следующий] dddd [в] LT';\n                    case 3:\n                    case 5:\n                    case 6:\n                        return '[В следующую] dddd [в] LT';\n                }\n            } else {\n                if (this.day() === 2) {\n                    return '[Во] dddd [в] LT';\n                } else {\n                    return '[В] dddd [в] LT';\n                }\n            }\n        },\n        lastWeek: function (now) {\n            if (now.week() !== this.week()) {\n                switch (this.day()) {\n                    case 0:\n                        return '[В прошлое] dddd [в] LT';\n                    case 1:\n                    case 2:\n                    case 4:\n                        return '[В прошлый] dddd [в] LT';\n                    case 3:\n                    case 5:\n                    case 6:\n                        return '[В прошлую] dddd [в] LT';\n                }\n            } else {\n                if (this.day() === 2) {\n                    return '[Во] dddd [в] LT';\n                } else {\n                    return '[В] dddd [в] LT';\n                }\n            }\n        },\n        sameElse: 'L'\n    },\n    relativeTime : {\n        future : 'через %s',\n        past : '%s назад',\n        s : 'несколько секунд',\n        m : relativeTimeWithPlural,\n        mm : relativeTimeWithPlural,\n        h : 'час',\n        hh : relativeTimeWithPlural,\n        d : 'день',\n        dd : relativeTimeWithPlural,\n        M : 'месяц',\n        MM : relativeTimeWithPlural,\n        y : 'год',\n        yy : relativeTimeWithPlural\n    },\n    meridiemParse: /ночи|утра|дня|вечера/i,\n    isPM : function (input) {\n        return /^(дня|вечера)$/.test(input);\n    },\n    meridiem : function (hour, minute, isLower) {\n        if (hour < 4) {\n            return 'ночи';\n        } else if (hour < 12) {\n            return 'утра';\n        } else if (hour < 17) {\n            return 'дня';\n        } else {\n            return 'вечера';\n        }\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}-(й|го|я)/,\n    ordinal: function (number, period) {\n        switch (period) {\n            case 'M':\n            case 'd':\n            case 'DDD':\n                return number + '-й';\n            case 'D':\n                return number + '-го';\n            case 'w':\n            case 'W':\n                return number + '-я';\n            default:\n                return number;\n        }\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 7  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/locale/sd.js",
    "content": "//! moment.js locale configuration\n//! locale : Sindhi [sd]\n//! author : Narain Sagar : https://github.com/narainsagar\n\nimport moment from '../moment';\n\nvar months = [\n    'جنوري',\n    'فيبروري',\n    'مارچ',\n    'اپريل',\n    'مئي',\n    'جون',\n    'جولاءِ',\n    'آگسٽ',\n    'سيپٽمبر',\n    'آڪٽوبر',\n    'نومبر',\n    'ڊسمبر'\n];\nvar days = [\n    'آچر',\n    'سومر',\n    'اڱارو',\n    'اربع',\n    'خميس',\n    'جمع',\n    'ڇنڇر'\n];\n\nexport default moment.defineLocale('sd', {\n    months : months,\n    monthsShort : months,\n    weekdays : days,\n    weekdaysShort : days,\n    weekdaysMin : days,\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY HH:mm',\n        LLLL : 'dddd، D MMMM YYYY HH:mm'\n    },\n    meridiemParse: /صبح|شام/,\n    isPM : function (input) {\n        return 'شام' === input;\n    },\n    meridiem : function (hour, minute, isLower) {\n        if (hour < 12) {\n            return 'صبح';\n        }\n        return 'شام';\n    },\n    calendar : {\n        sameDay : '[اڄ] LT',\n        nextDay : '[سڀاڻي] LT',\n        nextWeek : 'dddd [اڳين هفتي تي] LT',\n        lastDay : '[ڪالهه] LT',\n        lastWeek : '[گزريل هفتي] dddd [تي] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : '%s پوء',\n        past : '%s اڳ',\n        s : 'چند سيڪنڊ',\n        m : 'هڪ منٽ',\n        mm : '%d منٽ',\n        h : 'هڪ ڪلاڪ',\n        hh : '%d ڪلاڪ',\n        d : 'هڪ ڏينهن',\n        dd : '%d ڏينهن',\n        M : 'هڪ مهينو',\n        MM : '%d مهينا',\n        y : 'هڪ سال',\n        yy : '%d سال'\n    },\n    preparse: function (string) {\n        return string.replace(/،/g, ',');\n    },\n    postformat: function (string) {\n        return string.replace(/,/g, '،');\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/locale/se.js",
    "content": "//! moment.js locale configuration\n//! locale : Northern Sami [se]\n//! authors : Bård Rolstad Henriksen : https://github.com/karamell\n\n\nimport moment from '../moment';\n\nexport default moment.defineLocale('se', {\n    months : 'ođđajagemánnu_guovvamánnu_njukčamánnu_cuoŋománnu_miessemánnu_geassemánnu_suoidnemánnu_borgemánnu_čakčamánnu_golggotmánnu_skábmamánnu_juovlamánnu'.split('_'),\n    monthsShort : 'ođđj_guov_njuk_cuo_mies_geas_suoi_borg_čakč_golg_skáb_juov'.split('_'),\n    weekdays : 'sotnabeaivi_vuossárga_maŋŋebárga_gaskavahkku_duorastat_bearjadat_lávvardat'.split('_'),\n    weekdaysShort : 'sotn_vuos_maŋ_gask_duor_bear_láv'.split('_'),\n    weekdaysMin : 's_v_m_g_d_b_L'.split('_'),\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD.MM.YYYY',\n        LL : 'MMMM D. [b.] YYYY',\n        LLL : 'MMMM D. [b.] YYYY [ti.] HH:mm',\n        LLLL : 'dddd, MMMM D. [b.] YYYY [ti.] HH:mm'\n    },\n    calendar : {\n        sameDay: '[otne ti] LT',\n        nextDay: '[ihttin ti] LT',\n        nextWeek: 'dddd [ti] LT',\n        lastDay: '[ikte ti] LT',\n        lastWeek: '[ovddit] dddd [ti] LT',\n        sameElse: 'L'\n    },\n    relativeTime : {\n        future : '%s geažes',\n        past : 'maŋit %s',\n        s : 'moadde sekunddat',\n        m : 'okta minuhta',\n        mm : '%d minuhtat',\n        h : 'okta diimmu',\n        hh : '%d diimmut',\n        d : 'okta beaivi',\n        dd : '%d beaivvit',\n        M : 'okta mánnu',\n        MM : '%d mánut',\n        y : 'okta jahki',\n        yy : '%d jagit'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}\\./,\n    ordinal : '%d.',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/locale/si.js",
    "content": "//! moment.js locale configuration\n//! locale : Sinhalese [si]\n//! author : Sampath Sitinamaluwa : https://github.com/sampathsris\n\nimport moment from '../moment';\n\n/*jshint -W100*/\nexport default moment.defineLocale('si', {\n    months : 'ජනවාරි_පෙබරවාරි_මාර්තු_අප්‍රේල්_මැයි_ජූනි_ජූලි_අගෝස්තු_සැප්තැම්බර්_ඔක්තෝබර්_නොවැම්බර්_දෙසැම්බර්'.split('_'),\n    monthsShort : 'ජන_පෙබ_මාර්_අප්_මැයි_ජූනි_ජූලි_අගෝ_සැප්_ඔක්_නොවැ_දෙසැ'.split('_'),\n    weekdays : 'ඉරිදා_සඳුදා_අඟහරුවාදා_බදාදා_බ්‍රහස්පතින්දා_සිකුරාදා_සෙනසුරාදා'.split('_'),\n    weekdaysShort : 'ඉරි_සඳු_අඟ_බදා_බ්‍රහ_සිකු_සෙන'.split('_'),\n    weekdaysMin : 'ඉ_ස_අ_බ_බ්‍ර_සි_සෙ'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat : {\n        LT : 'a h:mm',\n        LTS : 'a h:mm:ss',\n        L : 'YYYY/MM/DD',\n        LL : 'YYYY MMMM D',\n        LLL : 'YYYY MMMM D, a h:mm',\n        LLLL : 'YYYY MMMM D [වැනි] dddd, a h:mm:ss'\n    },\n    calendar : {\n        sameDay : '[අද] LT[ට]',\n        nextDay : '[හෙට] LT[ට]',\n        nextWeek : 'dddd LT[ට]',\n        lastDay : '[ඊයේ] LT[ට]',\n        lastWeek : '[පසුගිය] dddd LT[ට]',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : '%sකින්',\n        past : '%sකට පෙර',\n        s : 'තත්පර කිහිපය',\n        m : 'මිනිත්තුව',\n        mm : 'මිනිත්තු %d',\n        h : 'පැය',\n        hh : 'පැය %d',\n        d : 'දිනය',\n        dd : 'දින %d',\n        M : 'මාසය',\n        MM : 'මාස %d',\n        y : 'වසර',\n        yy : 'වසර %d'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2} වැනි/,\n    ordinal : function (number) {\n        return number + ' වැනි';\n    },\n    meridiemParse : /පෙර වරු|පස් වරු|පෙ.ව|ප.ව./,\n    isPM : function (input) {\n        return input === 'ප.ව.' || input === 'පස් වරු';\n    },\n    meridiem : function (hours, minutes, isLower) {\n        if (hours > 11) {\n            return isLower ? 'ප.ව.' : 'පස් වරු';\n        } else {\n            return isLower ? 'පෙ.ව.' : 'පෙර වරු';\n        }\n    }\n});\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/locale/sk.js",
    "content": "//! moment.js locale configuration\n//! locale : Slovak [sk]\n//! author : Martin Minka : https://github.com/k2s\n//! based on work of petrbela : https://github.com/petrbela\n\nimport moment from '../moment';\n\nvar months = 'január_február_marec_apríl_máj_jún_júl_august_september_október_november_december'.split('_'),\n    monthsShort = 'jan_feb_mar_apr_máj_jún_júl_aug_sep_okt_nov_dec'.split('_');\nfunction plural(n) {\n    return (n > 1) && (n < 5);\n}\nfunction translate(number, withoutSuffix, key, isFuture) {\n    var result = number + ' ';\n    switch (key) {\n        case 's':  // a few seconds / in a few seconds / a few seconds ago\n            return (withoutSuffix || isFuture) ? 'pár sekúnd' : 'pár sekundami';\n        case 'm':  // a minute / in a minute / a minute ago\n            return withoutSuffix ? 'minúta' : (isFuture ? 'minútu' : 'minútou');\n        case 'mm': // 9 minutes / in 9 minutes / 9 minutes ago\n            if (withoutSuffix || isFuture) {\n                return result + (plural(number) ? 'minúty' : 'minút');\n            } else {\n                return result + 'minútami';\n            }\n            break;\n        case 'h':  // an hour / in an hour / an hour ago\n            return withoutSuffix ? 'hodina' : (isFuture ? 'hodinu' : 'hodinou');\n        case 'hh': // 9 hours / in 9 hours / 9 hours ago\n            if (withoutSuffix || isFuture) {\n                return result + (plural(number) ? 'hodiny' : 'hodín');\n            } else {\n                return result + 'hodinami';\n            }\n            break;\n        case 'd':  // a day / in a day / a day ago\n            return (withoutSuffix || isFuture) ? 'deň' : 'dňom';\n        case 'dd': // 9 days / in 9 days / 9 days ago\n            if (withoutSuffix || isFuture) {\n                return result + (plural(number) ? 'dni' : 'dní');\n            } else {\n                return result + 'dňami';\n            }\n            break;\n        case 'M':  // a month / in a month / a month ago\n            return (withoutSuffix || isFuture) ? 'mesiac' : 'mesiacom';\n        case 'MM': // 9 months / in 9 months / 9 months ago\n            if (withoutSuffix || isFuture) {\n                return result + (plural(number) ? 'mesiace' : 'mesiacov');\n            } else {\n                return result + 'mesiacmi';\n            }\n            break;\n        case 'y':  // a year / in a year / a year ago\n            return (withoutSuffix || isFuture) ? 'rok' : 'rokom';\n        case 'yy': // 9 years / in 9 years / 9 years ago\n            if (withoutSuffix || isFuture) {\n                return result + (plural(number) ? 'roky' : 'rokov');\n            } else {\n                return result + 'rokmi';\n            }\n            break;\n    }\n}\n\nexport default moment.defineLocale('sk', {\n    months : months,\n    monthsShort : monthsShort,\n    weekdays : 'nedeľa_pondelok_utorok_streda_štvrtok_piatok_sobota'.split('_'),\n    weekdaysShort : 'ne_po_ut_st_št_pi_so'.split('_'),\n    weekdaysMin : 'ne_po_ut_st_št_pi_so'.split('_'),\n    longDateFormat : {\n        LT: 'H:mm',\n        LTS : 'H:mm:ss',\n        L : 'DD.MM.YYYY',\n        LL : 'D. MMMM YYYY',\n        LLL : 'D. MMMM YYYY H:mm',\n        LLLL : 'dddd D. MMMM YYYY H:mm'\n    },\n    calendar : {\n        sameDay: '[dnes o] LT',\n        nextDay: '[zajtra o] LT',\n        nextWeek: function () {\n            switch (this.day()) {\n                case 0:\n                    return '[v nedeľu o] LT';\n                case 1:\n                case 2:\n                    return '[v] dddd [o] LT';\n                case 3:\n                    return '[v stredu o] LT';\n                case 4:\n                    return '[vo štvrtok o] LT';\n                case 5:\n                    return '[v piatok o] LT';\n                case 6:\n                    return '[v sobotu o] LT';\n            }\n        },\n        lastDay: '[včera o] LT',\n        lastWeek: function () {\n            switch (this.day()) {\n                case 0:\n                    return '[minulú nedeľu o] LT';\n                case 1:\n                case 2:\n                    return '[minulý] dddd [o] LT';\n                case 3:\n                    return '[minulú stredu o] LT';\n                case 4:\n                case 5:\n                    return '[minulý] dddd [o] LT';\n                case 6:\n                    return '[minulú sobotu o] LT';\n            }\n        },\n        sameElse: 'L'\n    },\n    relativeTime : {\n        future : 'za %s',\n        past : 'pred %s',\n        s : translate,\n        m : translate,\n        mm : translate,\n        h : translate,\n        hh : translate,\n        d : translate,\n        dd : translate,\n        M : translate,\n        MM : translate,\n        y : translate,\n        yy : translate\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}\\./,\n    ordinal : '%d.',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/locale/sl.js",
    "content": "//! moment.js locale configuration\n//! locale : Slovenian [sl]\n//! author : Robert Sedovšek : https://github.com/sedovsek\n\nimport moment from '../moment';\n\nfunction processRelativeTime(number, withoutSuffix, key, isFuture) {\n    var result = number + ' ';\n    switch (key) {\n        case 's':\n            return withoutSuffix || isFuture ? 'nekaj sekund' : 'nekaj sekundami';\n        case 'm':\n            return withoutSuffix ? 'ena minuta' : 'eno minuto';\n        case 'mm':\n            if (number === 1) {\n                result += withoutSuffix ? 'minuta' : 'minuto';\n            } else if (number === 2) {\n                result += withoutSuffix || isFuture ? 'minuti' : 'minutama';\n            } else if (number < 5) {\n                result += withoutSuffix || isFuture ? 'minute' : 'minutami';\n            } else {\n                result += withoutSuffix || isFuture ? 'minut' : 'minutami';\n            }\n            return result;\n        case 'h':\n            return withoutSuffix ? 'ena ura' : 'eno uro';\n        case 'hh':\n            if (number === 1) {\n                result += withoutSuffix ? 'ura' : 'uro';\n            } else if (number === 2) {\n                result += withoutSuffix || isFuture ? 'uri' : 'urama';\n            } else if (number < 5) {\n                result += withoutSuffix || isFuture ? 'ure' : 'urami';\n            } else {\n                result += withoutSuffix || isFuture ? 'ur' : 'urami';\n            }\n            return result;\n        case 'd':\n            return withoutSuffix || isFuture ? 'en dan' : 'enim dnem';\n        case 'dd':\n            if (number === 1) {\n                result += withoutSuffix || isFuture ? 'dan' : 'dnem';\n            } else if (number === 2) {\n                result += withoutSuffix || isFuture ? 'dni' : 'dnevoma';\n            } else {\n                result += withoutSuffix || isFuture ? 'dni' : 'dnevi';\n            }\n            return result;\n        case 'M':\n            return withoutSuffix || isFuture ? 'en mesec' : 'enim mesecem';\n        case 'MM':\n            if (number === 1) {\n                result += withoutSuffix || isFuture ? 'mesec' : 'mesecem';\n            } else if (number === 2) {\n                result += withoutSuffix || isFuture ? 'meseca' : 'mesecema';\n            } else if (number < 5) {\n                result += withoutSuffix || isFuture ? 'mesece' : 'meseci';\n            } else {\n                result += withoutSuffix || isFuture ? 'mesecev' : 'meseci';\n            }\n            return result;\n        case 'y':\n            return withoutSuffix || isFuture ? 'eno leto' : 'enim letom';\n        case 'yy':\n            if (number === 1) {\n                result += withoutSuffix || isFuture ? 'leto' : 'letom';\n            } else if (number === 2) {\n                result += withoutSuffix || isFuture ? 'leti' : 'letoma';\n            } else if (number < 5) {\n                result += withoutSuffix || isFuture ? 'leta' : 'leti';\n            } else {\n                result += withoutSuffix || isFuture ? 'let' : 'leti';\n            }\n            return result;\n    }\n}\n\nexport default moment.defineLocale('sl', {\n    months : 'januar_februar_marec_april_maj_junij_julij_avgust_september_oktober_november_december'.split('_'),\n    monthsShort : 'jan._feb._mar._apr._maj._jun._jul._avg._sep._okt._nov._dec.'.split('_'),\n    monthsParseExact: true,\n    weekdays : 'nedelja_ponedeljek_torek_sreda_četrtek_petek_sobota'.split('_'),\n    weekdaysShort : 'ned._pon._tor._sre._čet._pet._sob.'.split('_'),\n    weekdaysMin : 'ne_po_to_sr_če_pe_so'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat : {\n        LT : 'H:mm',\n        LTS : 'H:mm:ss',\n        L : 'DD.MM.YYYY',\n        LL : 'D. MMMM YYYY',\n        LLL : 'D. MMMM YYYY H:mm',\n        LLLL : 'dddd, D. MMMM YYYY H:mm'\n    },\n    calendar : {\n        sameDay  : '[danes ob] LT',\n        nextDay  : '[jutri ob] LT',\n\n        nextWeek : function () {\n            switch (this.day()) {\n                case 0:\n                    return '[v] [nedeljo] [ob] LT';\n                case 3:\n                    return '[v] [sredo] [ob] LT';\n                case 6:\n                    return '[v] [soboto] [ob] LT';\n                case 1:\n                case 2:\n                case 4:\n                case 5:\n                    return '[v] dddd [ob] LT';\n            }\n        },\n        lastDay  : '[včeraj ob] LT',\n        lastWeek : function () {\n            switch (this.day()) {\n                case 0:\n                    return '[prejšnjo] [nedeljo] [ob] LT';\n                case 3:\n                    return '[prejšnjo] [sredo] [ob] LT';\n                case 6:\n                    return '[prejšnjo] [soboto] [ob] LT';\n                case 1:\n                case 2:\n                case 4:\n                case 5:\n                    return '[prejšnji] dddd [ob] LT';\n            }\n        },\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'čez %s',\n        past   : 'pred %s',\n        s      : processRelativeTime,\n        m      : processRelativeTime,\n        mm     : processRelativeTime,\n        h      : processRelativeTime,\n        hh     : processRelativeTime,\n        d      : processRelativeTime,\n        dd     : processRelativeTime,\n        M      : processRelativeTime,\n        MM     : processRelativeTime,\n        y      : processRelativeTime,\n        yy     : processRelativeTime\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}\\./,\n    ordinal : '%d.',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 7  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/locale/sq.js",
    "content": "//! moment.js locale configuration\n//! locale : Albanian [sq]\n//! author : Flakërim Ismani : https://github.com/flakerimi\n//! author : Menelion Elensúle : https://github.com/Oire\n//! author : Oerd Cukalla : https://github.com/oerd\n\nimport moment from '../moment';\n\nexport default moment.defineLocale('sq', {\n    months : 'Janar_Shkurt_Mars_Prill_Maj_Qershor_Korrik_Gusht_Shtator_Tetor_Nëntor_Dhjetor'.split('_'),\n    monthsShort : 'Jan_Shk_Mar_Pri_Maj_Qer_Kor_Gus_Sht_Tet_Nën_Dhj'.split('_'),\n    weekdays : 'E Diel_E Hënë_E Martë_E Mërkurë_E Enjte_E Premte_E Shtunë'.split('_'),\n    weekdaysShort : 'Die_Hën_Mar_Mër_Enj_Pre_Sht'.split('_'),\n    weekdaysMin : 'D_H_Ma_Më_E_P_Sh'.split('_'),\n    weekdaysParseExact : true,\n    meridiemParse: /PD|MD/,\n    isPM: function (input) {\n        return input.charAt(0) === 'M';\n    },\n    meridiem : function (hours, minutes, isLower) {\n        return hours < 12 ? 'PD' : 'MD';\n    },\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY HH:mm',\n        LLLL : 'dddd, D MMMM YYYY HH:mm'\n    },\n    calendar : {\n        sameDay : '[Sot në] LT',\n        nextDay : '[Nesër në] LT',\n        nextWeek : 'dddd [në] LT',\n        lastDay : '[Dje në] LT',\n        lastWeek : 'dddd [e kaluar në] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'në %s',\n        past : '%s më parë',\n        s : 'disa sekonda',\n        m : 'një minutë',\n        mm : '%d minuta',\n        h : 'një orë',\n        hh : '%d orë',\n        d : 'një ditë',\n        dd : '%d ditë',\n        M : 'një muaj',\n        MM : '%d muaj',\n        y : 'një vit',\n        yy : '%d vite'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}\\./,\n    ordinal : '%d.',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/locale/sr-cyrl.js",
    "content": "//! moment.js locale configuration\n//! locale : Serbian Cyrillic [sr-cyrl]\n//! author : Milan Janačković<milanjanackovic@gmail.com> : https://github.com/milan-j\n\nimport moment from '../moment';\n\nvar translator = {\n    words: { //Different grammatical cases\n        m: ['један минут', 'једне минуте'],\n        mm: ['минут', 'минуте', 'минута'],\n        h: ['један сат', 'једног сата'],\n        hh: ['сат', 'сата', 'сати'],\n        dd: ['дан', 'дана', 'дана'],\n        MM: ['месец', 'месеца', 'месеци'],\n        yy: ['година', 'године', 'година']\n    },\n    correctGrammaticalCase: function (number, wordKey) {\n        return number === 1 ? wordKey[0] : (number >= 2 && number <= 4 ? wordKey[1] : wordKey[2]);\n    },\n    translate: function (number, withoutSuffix, key) {\n        var wordKey = translator.words[key];\n        if (key.length === 1) {\n            return withoutSuffix ? wordKey[0] : wordKey[1];\n        } else {\n            return number + ' ' + translator.correctGrammaticalCase(number, wordKey);\n        }\n    }\n};\n\nexport default moment.defineLocale('sr-cyrl', {\n    months: 'јануар_фебруар_март_април_мај_јун_јул_август_септембар_октобар_новембар_децембар'.split('_'),\n    monthsShort: 'јан._феб._мар._апр._мај_јун_јул_авг._сеп._окт._нов._дец.'.split('_'),\n    monthsParseExact: true,\n    weekdays: 'недеља_понедељак_уторак_среда_четвртак_петак_субота'.split('_'),\n    weekdaysShort: 'нед._пон._уто._сре._чет._пет._суб.'.split('_'),\n    weekdaysMin: 'не_по_ут_ср_че_пе_су'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat: {\n        LT: 'H:mm',\n        LTS : 'H:mm:ss',\n        L: 'DD.MM.YYYY',\n        LL: 'D. MMMM YYYY',\n        LLL: 'D. MMMM YYYY H:mm',\n        LLLL: 'dddd, D. MMMM YYYY H:mm'\n    },\n    calendar: {\n        sameDay: '[данас у] LT',\n        nextDay: '[сутра у] LT',\n        nextWeek: function () {\n            switch (this.day()) {\n                case 0:\n                    return '[у] [недељу] [у] LT';\n                case 3:\n                    return '[у] [среду] [у] LT';\n                case 6:\n                    return '[у] [суботу] [у] LT';\n                case 1:\n                case 2:\n                case 4:\n                case 5:\n                    return '[у] dddd [у] LT';\n            }\n        },\n        lastDay  : '[јуче у] LT',\n        lastWeek : function () {\n            var lastWeekDays = [\n                '[прошле] [недеље] [у] LT',\n                '[прошлог] [понедељка] [у] LT',\n                '[прошлог] [уторка] [у] LT',\n                '[прошле] [среде] [у] LT',\n                '[прошлог] [четвртка] [у] LT',\n                '[прошлог] [петка] [у] LT',\n                '[прошле] [суботе] [у] LT'\n            ];\n            return lastWeekDays[this.day()];\n        },\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'за %s',\n        past   : 'пре %s',\n        s      : 'неколико секунди',\n        m      : translator.translate,\n        mm     : translator.translate,\n        h      : translator.translate,\n        hh     : translator.translate,\n        d      : 'дан',\n        dd     : translator.translate,\n        M      : 'месец',\n        MM     : translator.translate,\n        y      : 'годину',\n        yy     : translator.translate\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}\\./,\n    ordinal : '%d.',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 7  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/locale/sr.js",
    "content": "//! moment.js locale configuration\n//! locale : Serbian [sr]\n//! author : Milan Janačković<milanjanackovic@gmail.com> : https://github.com/milan-j\n\nimport moment from '../moment';\n\nvar translator = {\n    words: { //Different grammatical cases\n        m: ['jedan minut', 'jedne minute'],\n        mm: ['minut', 'minute', 'minuta'],\n        h: ['jedan sat', 'jednog sata'],\n        hh: ['sat', 'sata', 'sati'],\n        dd: ['dan', 'dana', 'dana'],\n        MM: ['mesec', 'meseca', 'meseci'],\n        yy: ['godina', 'godine', 'godina']\n    },\n    correctGrammaticalCase: function (number, wordKey) {\n        return number === 1 ? wordKey[0] : (number >= 2 && number <= 4 ? wordKey[1] : wordKey[2]);\n    },\n    translate: function (number, withoutSuffix, key) {\n        var wordKey = translator.words[key];\n        if (key.length === 1) {\n            return withoutSuffix ? wordKey[0] : wordKey[1];\n        } else {\n            return number + ' ' + translator.correctGrammaticalCase(number, wordKey);\n        }\n    }\n};\n\nexport default moment.defineLocale('sr', {\n    months: 'januar_februar_mart_april_maj_jun_jul_avgust_septembar_oktobar_novembar_decembar'.split('_'),\n    monthsShort: 'jan._feb._mar._apr._maj_jun_jul_avg._sep._okt._nov._dec.'.split('_'),\n    monthsParseExact: true,\n    weekdays: 'nedelja_ponedeljak_utorak_sreda_četvrtak_petak_subota'.split('_'),\n    weekdaysShort: 'ned._pon._uto._sre._čet._pet._sub.'.split('_'),\n    weekdaysMin: 'ne_po_ut_sr_če_pe_su'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat: {\n        LT: 'H:mm',\n        LTS : 'H:mm:ss',\n        L: 'DD.MM.YYYY',\n        LL: 'D. MMMM YYYY',\n        LLL: 'D. MMMM YYYY H:mm',\n        LLLL: 'dddd, D. MMMM YYYY H:mm'\n    },\n    calendar: {\n        sameDay: '[danas u] LT',\n        nextDay: '[sutra u] LT',\n        nextWeek: function () {\n            switch (this.day()) {\n                case 0:\n                    return '[u] [nedelju] [u] LT';\n                case 3:\n                    return '[u] [sredu] [u] LT';\n                case 6:\n                    return '[u] [subotu] [u] LT';\n                case 1:\n                case 2:\n                case 4:\n                case 5:\n                    return '[u] dddd [u] LT';\n            }\n        },\n        lastDay  : '[juče u] LT',\n        lastWeek : function () {\n            var lastWeekDays = [\n                '[prošle] [nedelje] [u] LT',\n                '[prošlog] [ponedeljka] [u] LT',\n                '[prošlog] [utorka] [u] LT',\n                '[prošle] [srede] [u] LT',\n                '[prošlog] [četvrtka] [u] LT',\n                '[prošlog] [petka] [u] LT',\n                '[prošle] [subote] [u] LT'\n            ];\n            return lastWeekDays[this.day()];\n        },\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'za %s',\n        past   : 'pre %s',\n        s      : 'nekoliko sekundi',\n        m      : translator.translate,\n        mm     : translator.translate,\n        h      : translator.translate,\n        hh     : translator.translate,\n        d      : 'dan',\n        dd     : translator.translate,\n        M      : 'mesec',\n        MM     : translator.translate,\n        y      : 'godinu',\n        yy     : translator.translate\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}\\./,\n    ordinal : '%d.',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 7  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/locale/ss.js",
    "content": "//! moment.js locale configuration\n//! locale : siSwati [ss]\n//! author : Nicolai Davies<mail@nicolai.io> : https://github.com/nicolaidavies\n\n\nimport moment from '../moment';\n\nexport default moment.defineLocale('ss', {\n    months : \"Bhimbidvwane_Indlovana_Indlov'lenkhulu_Mabasa_Inkhwekhweti_Inhlaba_Kholwane_Ingci_Inyoni_Imphala_Lweti_Ingongoni\".split('_'),\n    monthsShort : 'Bhi_Ina_Inu_Mab_Ink_Inh_Kho_Igc_Iny_Imp_Lwe_Igo'.split('_'),\n    weekdays : 'Lisontfo_Umsombuluko_Lesibili_Lesitsatfu_Lesine_Lesihlanu_Umgcibelo'.split('_'),\n    weekdaysShort : 'Lis_Umb_Lsb_Les_Lsi_Lsh_Umg'.split('_'),\n    weekdaysMin : 'Li_Us_Lb_Lt_Ls_Lh_Ug'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat : {\n        LT : 'h:mm A',\n        LTS : 'h:mm:ss A',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY h:mm A',\n        LLLL : 'dddd, D MMMM YYYY h:mm A'\n    },\n    calendar : {\n        sameDay : '[Namuhla nga] LT',\n        nextDay : '[Kusasa nga] LT',\n        nextWeek : 'dddd [nga] LT',\n        lastDay : '[Itolo nga] LT',\n        lastWeek : 'dddd [leliphelile] [nga] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'nga %s',\n        past : 'wenteka nga %s',\n        s : 'emizuzwana lomcane',\n        m : 'umzuzu',\n        mm : '%d emizuzu',\n        h : 'lihora',\n        hh : '%d emahora',\n        d : 'lilanga',\n        dd : '%d emalanga',\n        M : 'inyanga',\n        MM : '%d tinyanga',\n        y : 'umnyaka',\n        yy : '%d iminyaka'\n    },\n    meridiemParse: /ekuseni|emini|entsambama|ebusuku/,\n    meridiem : function (hours, minutes, isLower) {\n        if (hours < 11) {\n            return 'ekuseni';\n        } else if (hours < 15) {\n            return 'emini';\n        } else if (hours < 19) {\n            return 'entsambama';\n        } else {\n            return 'ebusuku';\n        }\n    },\n    meridiemHour : function (hour, meridiem) {\n        if (hour === 12) {\n            hour = 0;\n        }\n        if (meridiem === 'ekuseni') {\n            return hour;\n        } else if (meridiem === 'emini') {\n            return hour >= 11 ? hour : hour + 12;\n        } else if (meridiem === 'entsambama' || meridiem === 'ebusuku') {\n            if (hour === 0) {\n                return 0;\n            }\n            return hour + 12;\n        }\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}/,\n    ordinal : '%d',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/locale/sv.js",
    "content": "//! moment.js locale configuration\n//! locale : Swedish [sv]\n//! author : Jens Alm : https://github.com/ulmus\n\nimport moment from '../moment';\n\nexport default moment.defineLocale('sv', {\n    months : 'januari_februari_mars_april_maj_juni_juli_augusti_september_oktober_november_december'.split('_'),\n    monthsShort : 'jan_feb_mar_apr_maj_jun_jul_aug_sep_okt_nov_dec'.split('_'),\n    weekdays : 'söndag_måndag_tisdag_onsdag_torsdag_fredag_lördag'.split('_'),\n    weekdaysShort : 'sön_mån_tis_ons_tor_fre_lör'.split('_'),\n    weekdaysMin : 'sö_må_ti_on_to_fr_lö'.split('_'),\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'YYYY-MM-DD',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY [kl.] HH:mm',\n        LLLL : 'dddd D MMMM YYYY [kl.] HH:mm',\n        lll : 'D MMM YYYY HH:mm',\n        llll : 'ddd D MMM YYYY HH:mm'\n    },\n    calendar : {\n        sameDay: '[Idag] LT',\n        nextDay: '[Imorgon] LT',\n        lastDay: '[Igår] LT',\n        nextWeek: '[På] dddd LT',\n        lastWeek: '[I] dddd[s] LT',\n        sameElse: 'L'\n    },\n    relativeTime : {\n        future : 'om %s',\n        past : 'för %s sedan',\n        s : 'några sekunder',\n        m : 'en minut',\n        mm : '%d minuter',\n        h : 'en timme',\n        hh : '%d timmar',\n        d : 'en dag',\n        dd : '%d dagar',\n        M : 'en månad',\n        MM : '%d månader',\n        y : 'ett år',\n        yy : '%d år'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}(e|a)/,\n    ordinal : function (number) {\n        var b = number % 10,\n            output = (~~(number % 100 / 10) === 1) ? 'e' :\n            (b === 1) ? 'a' :\n            (b === 2) ? 'a' :\n            (b === 3) ? 'e' : 'e';\n        return number + output;\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/locale/sw.js",
    "content": "//! moment.js locale configuration\n//! locale : Swahili [sw]\n//! author : Fahad Kassim : https://github.com/fadsel\n\nimport moment from '../moment';\n\nexport default moment.defineLocale('sw', {\n    months : 'Januari_Februari_Machi_Aprili_Mei_Juni_Julai_Agosti_Septemba_Oktoba_Novemba_Desemba'.split('_'),\n    monthsShort : 'Jan_Feb_Mac_Apr_Mei_Jun_Jul_Ago_Sep_Okt_Nov_Des'.split('_'),\n    weekdays : 'Jumapili_Jumatatu_Jumanne_Jumatano_Alhamisi_Ijumaa_Jumamosi'.split('_'),\n    weekdaysShort : 'Jpl_Jtat_Jnne_Jtan_Alh_Ijm_Jmos'.split('_'),\n    weekdaysMin : 'J2_J3_J4_J5_Al_Ij_J1'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD.MM.YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY HH:mm',\n        LLLL : 'dddd, D MMMM YYYY HH:mm'\n    },\n    calendar : {\n        sameDay : '[leo saa] LT',\n        nextDay : '[kesho saa] LT',\n        nextWeek : '[wiki ijayo] dddd [saat] LT',\n        lastDay : '[jana] LT',\n        lastWeek : '[wiki iliyopita] dddd [saat] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : '%s baadaye',\n        past : 'tokea %s',\n        s : 'hivi punde',\n        m : 'dakika moja',\n        mm : 'dakika %d',\n        h : 'saa limoja',\n        hh : 'masaa %d',\n        d : 'siku moja',\n        dd : 'masiku %d',\n        M : 'mwezi mmoja',\n        MM : 'miezi %d',\n        y : 'mwaka mmoja',\n        yy : 'miaka %d'\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 7  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/locale/ta.js",
    "content": "//! moment.js locale configuration\n//! locale : Tamil [ta]\n//! author : Arjunkumar Krishnamoorthy : https://github.com/tk120404\n\nimport moment from '../moment';\n\nvar symbolMap = {\n    '1': '௧',\n    '2': '௨',\n    '3': '௩',\n    '4': '௪',\n    '5': '௫',\n    '6': '௬',\n    '7': '௭',\n    '8': '௮',\n    '9': '௯',\n    '0': '௦'\n}, numberMap = {\n    '௧': '1',\n    '௨': '2',\n    '௩': '3',\n    '௪': '4',\n    '௫': '5',\n    '௬': '6',\n    '௭': '7',\n    '௮': '8',\n    '௯': '9',\n    '௦': '0'\n};\n\nexport default moment.defineLocale('ta', {\n    months : 'ஜனவரி_பிப்ரவரி_மார்ச்_ஏப்ரல்_மே_ஜூன்_ஜூலை_ஆகஸ்ட்_செப்டெம்பர்_அக்டோபர்_நவம்பர்_டிசம்பர்'.split('_'),\n    monthsShort : 'ஜனவரி_பிப்ரவரி_மார்ச்_ஏப்ரல்_மே_ஜூன்_ஜூலை_ஆகஸ்ட்_செப்டெம்பர்_அக்டோபர்_நவம்பர்_டிசம்பர்'.split('_'),\n    weekdays : 'ஞாயிற்றுக்கிழமை_திங்கட்கிழமை_செவ்வாய்கிழமை_புதன்கிழமை_வியாழக்கிழமை_வெள்ளிக்கிழமை_சனிக்கிழமை'.split('_'),\n    weekdaysShort : 'ஞாயிறு_திங்கள்_செவ்வாய்_புதன்_வியாழன்_வெள்ளி_சனி'.split('_'),\n    weekdaysMin : 'ஞா_தி_செ_பு_வி_வெ_ச'.split('_'),\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY, HH:mm',\n        LLLL : 'dddd, D MMMM YYYY, HH:mm'\n    },\n    calendar : {\n        sameDay : '[இன்று] LT',\n        nextDay : '[நாளை] LT',\n        nextWeek : 'dddd, LT',\n        lastDay : '[நேற்று] LT',\n        lastWeek : '[கடந்த வாரம்] dddd, LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : '%s இல்',\n        past : '%s முன்',\n        s : 'ஒரு சில விநாடிகள்',\n        m : 'ஒரு நிமிடம்',\n        mm : '%d நிமிடங்கள்',\n        h : 'ஒரு மணி நேரம்',\n        hh : '%d மணி நேரம்',\n        d : 'ஒரு நாள்',\n        dd : '%d நாட்கள்',\n        M : 'ஒரு மாதம்',\n        MM : '%d மாதங்கள்',\n        y : 'ஒரு வருடம்',\n        yy : '%d ஆண்டுகள்'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}வது/,\n    ordinal : function (number) {\n        return number + 'வது';\n    },\n    preparse: function (string) {\n        return string.replace(/[௧௨௩௪௫௬௭௮௯௦]/g, function (match) {\n            return numberMap[match];\n        });\n    },\n    postformat: function (string) {\n        return string.replace(/\\d/g, function (match) {\n            return symbolMap[match];\n        });\n    },\n    // refer http://ta.wikipedia.org/s/1er1\n    meridiemParse: /யாமம்|வைகறை|காலை|நண்பகல்|எற்பாடு|மாலை/,\n    meridiem : function (hour, minute, isLower) {\n        if (hour < 2) {\n            return ' யாமம்';\n        } else if (hour < 6) {\n            return ' வைகறை';  // வைகறை\n        } else if (hour < 10) {\n            return ' காலை'; // காலை\n        } else if (hour < 14) {\n            return ' நண்பகல்'; // நண்பகல்\n        } else if (hour < 18) {\n            return ' எற்பாடு'; // எற்பாடு\n        } else if (hour < 22) {\n            return ' மாலை'; // மாலை\n        } else {\n            return ' யாமம்';\n        }\n    },\n    meridiemHour : function (hour, meridiem) {\n        if (hour === 12) {\n            hour = 0;\n        }\n        if (meridiem === 'யாமம்') {\n            return hour < 2 ? hour : hour + 12;\n        } else if (meridiem === 'வைகறை' || meridiem === 'காலை') {\n            return hour;\n        } else if (meridiem === 'நண்பகல்') {\n            return hour >= 10 ? hour : hour + 12;\n        } else {\n            return hour + 12;\n        }\n    },\n    week : {\n        dow : 0, // Sunday is the first day of the week.\n        doy : 6  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/locale/te.js",
    "content": "//! moment.js locale configuration\n//! locale : Telugu [te]\n//! author : Krishna Chaitanya Thota : https://github.com/kcthota\n\nimport moment from '../moment';\n\nexport default moment.defineLocale('te', {\n    months : 'జనవరి_ఫిబ్రవరి_మార్చి_ఏప్రిల్_మే_జూన్_జూలై_ఆగస్టు_సెప్టెంబర్_అక్టోబర్_నవంబర్_డిసెంబర్'.split('_'),\n    monthsShort : 'జన._ఫిబ్ర._మార్చి_ఏప్రి._మే_జూన్_జూలై_ఆగ._సెప్._అక్టో._నవ._డిసె.'.split('_'),\n    monthsParseExact : true,\n    weekdays : 'ఆదివారం_సోమవారం_మంగళవారం_బుధవారం_గురువారం_శుక్రవారం_శనివారం'.split('_'),\n    weekdaysShort : 'ఆది_సోమ_మంగళ_బుధ_గురు_శుక్ర_శని'.split('_'),\n    weekdaysMin : 'ఆ_సో_మం_బు_గు_శు_శ'.split('_'),\n    longDateFormat : {\n        LT : 'A h:mm',\n        LTS : 'A h:mm:ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY, A h:mm',\n        LLLL : 'dddd, D MMMM YYYY, A h:mm'\n    },\n    calendar : {\n        sameDay : '[నేడు] LT',\n        nextDay : '[రేపు] LT',\n        nextWeek : 'dddd, LT',\n        lastDay : '[నిన్న] LT',\n        lastWeek : '[గత] dddd, LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : '%s లో',\n        past : '%s క్రితం',\n        s : 'కొన్ని క్షణాలు',\n        m : 'ఒక నిమిషం',\n        mm : '%d నిమిషాలు',\n        h : 'ఒక గంట',\n        hh : '%d గంటలు',\n        d : 'ఒక రోజు',\n        dd : '%d రోజులు',\n        M : 'ఒక నెల',\n        MM : '%d నెలలు',\n        y : 'ఒక సంవత్సరం',\n        yy : '%d సంవత్సరాలు'\n    },\n    dayOfMonthOrdinalParse : /\\d{1,2}వ/,\n    ordinal : '%dవ',\n    meridiemParse: /రాత్రి|ఉదయం|మధ్యాహ్నం|సాయంత్రం/,\n    meridiemHour : function (hour, meridiem) {\n        if (hour === 12) {\n            hour = 0;\n        }\n        if (meridiem === 'రాత్రి') {\n            return hour < 4 ? hour : hour + 12;\n        } else if (meridiem === 'ఉదయం') {\n            return hour;\n        } else if (meridiem === 'మధ్యాహ్నం') {\n            return hour >= 10 ? hour : hour + 12;\n        } else if (meridiem === 'సాయంత్రం') {\n            return hour + 12;\n        }\n    },\n    meridiem : function (hour, minute, isLower) {\n        if (hour < 4) {\n            return 'రాత్రి';\n        } else if (hour < 10) {\n            return 'ఉదయం';\n        } else if (hour < 17) {\n            return 'మధ్యాహ్నం';\n        } else if (hour < 20) {\n            return 'సాయంత్రం';\n        } else {\n            return 'రాత్రి';\n        }\n    },\n    week : {\n        dow : 0, // Sunday is the first day of the week.\n        doy : 6  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/locale/tet.js",
    "content": "//! moment.js locale configuration\n//! locale : Tetun Dili (East Timor) [tet]\n//! author : Joshua Brooks : https://github.com/joshbrooks\n//! author : Onorio De J. Afonso : https://github.com/marobo\n\nimport moment from '../moment';\n\nexport default moment.defineLocale('tet', {\n    months : 'Janeiru_Fevereiru_Marsu_Abril_Maiu_Juniu_Juliu_Augustu_Setembru_Outubru_Novembru_Dezembru'.split('_'),\n    monthsShort : 'Jan_Fev_Mar_Abr_Mai_Jun_Jul_Aug_Set_Out_Nov_Dez'.split('_'),\n    weekdays : 'Domingu_Segunda_Tersa_Kuarta_Kinta_Sexta_Sabadu'.split('_'),\n    weekdaysShort : 'Dom_Seg_Ters_Kua_Kint_Sext_Sab'.split('_'),\n    weekdaysMin : 'Do_Seg_Te_Ku_Ki_Sex_Sa'.split('_'),\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY HH:mm',\n        LLLL : 'dddd, D MMMM YYYY HH:mm'\n    },\n    calendar : {\n        sameDay: '[Ohin iha] LT',\n        nextDay: '[Aban iha] LT',\n        nextWeek: 'dddd [iha] LT',\n        lastDay: '[Horiseik iha] LT',\n        lastWeek: 'dddd [semana kotuk] [iha] LT',\n        sameElse: 'L'\n    },\n    relativeTime : {\n        future : 'iha %s',\n        past : '%s liuba',\n        s : 'minutu balun',\n        m : 'minutu ida',\n        mm : 'minutus %d',\n        h : 'horas ida',\n        hh : 'horas %d',\n        d : 'loron ida',\n        dd : 'loron %d',\n        M : 'fulan ida',\n        MM : 'fulan %d',\n        y : 'tinan ida',\n        yy : 'tinan %d'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}(st|nd|rd|th)/,\n    ordinal : function (number) {\n        var b = number % 10,\n            output = (~~(number % 100 / 10) === 1) ? 'th' :\n            (b === 1) ? 'st' :\n            (b === 2) ? 'nd' :\n            (b === 3) ? 'rd' : 'th';\n        return number + output;\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/locale/th.js",
    "content": "//! moment.js locale configuration\n//! locale : Thai [th]\n//! author : Kridsada Thanabulpong : https://github.com/sirn\n\nimport moment from '../moment';\n\nexport default moment.defineLocale('th', {\n    months : 'มกราคม_กุมภาพันธ์_มีนาคม_เมษายน_พฤษภาคม_มิถุนายน_กรกฎาคม_สิงหาคม_กันยายน_ตุลาคม_พฤศจิกายน_ธันวาคม'.split('_'),\n    monthsShort : 'ม.ค._ก.พ._มี.ค._เม.ย._พ.ค._มิ.ย._ก.ค._ส.ค._ก.ย._ต.ค._พ.ย._ธ.ค.'.split('_'),\n    monthsParseExact: true,\n    weekdays : 'อาทิตย์_จันทร์_อังคาร_พุธ_พฤหัสบดี_ศุกร์_เสาร์'.split('_'),\n    weekdaysShort : 'อาทิตย์_จันทร์_อังคาร_พุธ_พฤหัส_ศุกร์_เสาร์'.split('_'), // yes, three characters difference\n    weekdaysMin : 'อา._จ._อ._พ._พฤ._ศ._ส.'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat : {\n        LT : 'H:mm',\n        LTS : 'H:mm:ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY เวลา H:mm',\n        LLLL : 'วันddddที่ D MMMM YYYY เวลา H:mm'\n    },\n    meridiemParse: /ก่อนเที่ยง|หลังเที่ยง/,\n    isPM: function (input) {\n        return input === 'หลังเที่ยง';\n    },\n    meridiem : function (hour, minute, isLower) {\n        if (hour < 12) {\n            return 'ก่อนเที่ยง';\n        } else {\n            return 'หลังเที่ยง';\n        }\n    },\n    calendar : {\n        sameDay : '[วันนี้ เวลา] LT',\n        nextDay : '[พรุ่งนี้ เวลา] LT',\n        nextWeek : 'dddd[หน้า เวลา] LT',\n        lastDay : '[เมื่อวานนี้ เวลา] LT',\n        lastWeek : '[วัน]dddd[ที่แล้ว เวลา] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'อีก %s',\n        past : '%sที่แล้ว',\n        s : 'ไม่กี่วินาที',\n        m : '1 นาที',\n        mm : '%d นาที',\n        h : '1 ชั่วโมง',\n        hh : '%d ชั่วโมง',\n        d : '1 วัน',\n        dd : '%d วัน',\n        M : '1 เดือน',\n        MM : '%d เดือน',\n        y : '1 ปี',\n        yy : '%d ปี'\n    }\n});\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/locale/tl-ph.js",
    "content": "//! moment.js locale configuration\n//! locale : Tagalog (Philippines) [tl-ph]\n//! author : Dan Hagman : https://github.com/hagmandan\n\nimport moment from '../moment';\n\nexport default moment.defineLocale('tl-ph', {\n    months : 'Enero_Pebrero_Marso_Abril_Mayo_Hunyo_Hulyo_Agosto_Setyembre_Oktubre_Nobyembre_Disyembre'.split('_'),\n    monthsShort : 'Ene_Peb_Mar_Abr_May_Hun_Hul_Ago_Set_Okt_Nob_Dis'.split('_'),\n    weekdays : 'Linggo_Lunes_Martes_Miyerkules_Huwebes_Biyernes_Sabado'.split('_'),\n    weekdaysShort : 'Lin_Lun_Mar_Miy_Huw_Biy_Sab'.split('_'),\n    weekdaysMin : 'Li_Lu_Ma_Mi_Hu_Bi_Sab'.split('_'),\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'MM/D/YYYY',\n        LL : 'MMMM D, YYYY',\n        LLL : 'MMMM D, YYYY HH:mm',\n        LLLL : 'dddd, MMMM DD, YYYY HH:mm'\n    },\n    calendar : {\n        sameDay: 'LT [ngayong araw]',\n        nextDay: '[Bukas ng] LT',\n        nextWeek: 'LT [sa susunod na] dddd',\n        lastDay: 'LT [kahapon]',\n        lastWeek: 'LT [noong nakaraang] dddd',\n        sameElse: 'L'\n    },\n    relativeTime : {\n        future : 'sa loob ng %s',\n        past : '%s ang nakalipas',\n        s : 'ilang segundo',\n        m : 'isang minuto',\n        mm : '%d minuto',\n        h : 'isang oras',\n        hh : '%d oras',\n        d : 'isang araw',\n        dd : '%d araw',\n        M : 'isang buwan',\n        MM : '%d buwan',\n        y : 'isang taon',\n        yy : '%d taon'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}/,\n    ordinal : function (number) {\n        return number;\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/locale/tlh.js",
    "content": "//! moment.js locale configuration\n//! locale : Klingon [tlh]\n//! author : Dominika Kruk : https://github.com/amaranthrose\n\nimport moment from '../moment';\n\nvar numbersNouns = 'pagh_wa’_cha’_wej_loS_vagh_jav_Soch_chorgh_Hut'.split('_');\n\nfunction translateFuture(output) {\n    var time = output;\n    time = (output.indexOf('jaj') !== -1) ?\n    time.slice(0, -3) + 'leS' :\n    (output.indexOf('jar') !== -1) ?\n    time.slice(0, -3) + 'waQ' :\n    (output.indexOf('DIS') !== -1) ?\n    time.slice(0, -3) + 'nem' :\n    time + ' pIq';\n    return time;\n}\n\nfunction translatePast(output) {\n    var time = output;\n    time = (output.indexOf('jaj') !== -1) ?\n    time.slice(0, -3) + 'Hu’' :\n    (output.indexOf('jar') !== -1) ?\n    time.slice(0, -3) + 'wen' :\n    (output.indexOf('DIS') !== -1) ?\n    time.slice(0, -3) + 'ben' :\n    time + ' ret';\n    return time;\n}\n\nfunction translate(number, withoutSuffix, string, isFuture) {\n    var numberNoun = numberAsNoun(number);\n    switch (string) {\n        case 'mm':\n            return numberNoun + ' tup';\n        case 'hh':\n            return numberNoun + ' rep';\n        case 'dd':\n            return numberNoun + ' jaj';\n        case 'MM':\n            return numberNoun + ' jar';\n        case 'yy':\n            return numberNoun + ' DIS';\n    }\n}\n\nfunction numberAsNoun(number) {\n    var hundred = Math.floor((number % 1000) / 100),\n    ten = Math.floor((number % 100) / 10),\n    one = number % 10,\n    word = '';\n    if (hundred > 0) {\n        word += numbersNouns[hundred] + 'vatlh';\n    }\n    if (ten > 0) {\n        word += ((word !== '') ? ' ' : '') + numbersNouns[ten] + 'maH';\n    }\n    if (one > 0) {\n        word += ((word !== '') ? ' ' : '') + numbersNouns[one];\n    }\n    return (word === '') ? 'pagh' : word;\n}\n\nexport default moment.defineLocale('tlh', {\n    months : 'tera’ jar wa’_tera’ jar cha’_tera’ jar wej_tera’ jar loS_tera’ jar vagh_tera’ jar jav_tera’ jar Soch_tera’ jar chorgh_tera’ jar Hut_tera’ jar wa’maH_tera’ jar wa’maH wa’_tera’ jar wa’maH cha’'.split('_'),\n    monthsShort : 'jar wa’_jar cha’_jar wej_jar loS_jar vagh_jar jav_jar Soch_jar chorgh_jar Hut_jar wa’maH_jar wa’maH wa’_jar wa’maH cha’'.split('_'),\n    monthsParseExact : true,\n    weekdays : 'lojmItjaj_DaSjaj_povjaj_ghItlhjaj_loghjaj_buqjaj_ghInjaj'.split('_'),\n    weekdaysShort : 'lojmItjaj_DaSjaj_povjaj_ghItlhjaj_loghjaj_buqjaj_ghInjaj'.split('_'),\n    weekdaysMin : 'lojmItjaj_DaSjaj_povjaj_ghItlhjaj_loghjaj_buqjaj_ghInjaj'.split('_'),\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD.MM.YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY HH:mm',\n        LLLL : 'dddd, D MMMM YYYY HH:mm'\n    },\n    calendar : {\n        sameDay: '[DaHjaj] LT',\n        nextDay: '[wa’leS] LT',\n        nextWeek: 'LLL',\n        lastDay: '[wa’Hu’] LT',\n        lastWeek: 'LLL',\n        sameElse: 'L'\n    },\n    relativeTime : {\n        future : translateFuture,\n        past : translatePast,\n        s : 'puS lup',\n        m : 'wa’ tup',\n        mm : translate,\n        h : 'wa’ rep',\n        hh : translate,\n        d : 'wa’ jaj',\n        dd : translate,\n        M : 'wa’ jar',\n        MM : translate,\n        y : 'wa’ DIS',\n        yy : translate\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}\\./,\n    ordinal : '%d.',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/locale/tr.js",
    "content": "//! moment.js locale configuration\n//! locale : Turkish [tr]\n//! authors : Erhan Gundogan : https://github.com/erhangundogan,\n//!           Burak Yiğit Kaya: https://github.com/BYK\n\nimport moment from '../moment';\n\nvar suffixes = {\n    1: '\\'inci',\n    5: '\\'inci',\n    8: '\\'inci',\n    70: '\\'inci',\n    80: '\\'inci',\n    2: '\\'nci',\n    7: '\\'nci',\n    20: '\\'nci',\n    50: '\\'nci',\n    3: '\\'üncü',\n    4: '\\'üncü',\n    100: '\\'üncü',\n    6: '\\'ncı',\n    9: '\\'uncu',\n    10: '\\'uncu',\n    30: '\\'uncu',\n    60: '\\'ıncı',\n    90: '\\'ıncı'\n};\n\nexport default moment.defineLocale('tr', {\n    months : 'Ocak_Şubat_Mart_Nisan_Mayıs_Haziran_Temmuz_Ağustos_Eylül_Ekim_Kasım_Aralık'.split('_'),\n    monthsShort : 'Oca_Şub_Mar_Nis_May_Haz_Tem_Ağu_Eyl_Eki_Kas_Ara'.split('_'),\n    weekdays : 'Pazar_Pazartesi_Salı_Çarşamba_Perşembe_Cuma_Cumartesi'.split('_'),\n    weekdaysShort : 'Paz_Pts_Sal_Çar_Per_Cum_Cts'.split('_'),\n    weekdaysMin : 'Pz_Pt_Sa_Ça_Pe_Cu_Ct'.split('_'),\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD.MM.YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY HH:mm',\n        LLLL : 'dddd, D MMMM YYYY HH:mm'\n    },\n    calendar : {\n        sameDay : '[bugün saat] LT',\n        nextDay : '[yarın saat] LT',\n        nextWeek : '[haftaya] dddd [saat] LT',\n        lastDay : '[dün] LT',\n        lastWeek : '[geçen hafta] dddd [saat] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : '%s sonra',\n        past : '%s önce',\n        s : 'birkaç saniye',\n        m : 'bir dakika',\n        mm : '%d dakika',\n        h : 'bir saat',\n        hh : '%d saat',\n        d : 'bir gün',\n        dd : '%d gün',\n        M : 'bir ay',\n        MM : '%d ay',\n        y : 'bir yıl',\n        yy : '%d yıl'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}'(inci|nci|üncü|ncı|uncu|ıncı)/,\n    ordinal : function (number) {\n        if (number === 0) {  // special case for zero\n            return number + '\\'ıncı';\n        }\n        var a = number % 10,\n            b = number % 100 - a,\n            c = number >= 100 ? 100 : null;\n        return number + (suffixes[a] || suffixes[b] || suffixes[c]);\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 7  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/locale/tzl.js",
    "content": "//! moment.js locale configuration\n//! locale : Talossan [tzl]\n//! author : Robin van der Vliet : https://github.com/robin0van0der0v\n//! author : Iustì Canun\n\nimport moment from '../moment';\n\n// After the year there should be a slash and the amount of years since December 26, 1979 in Roman numerals.\n// This is currently too difficult (maybe even impossible) to add.\nexport default moment.defineLocale('tzl', {\n    months : 'Januar_Fevraglh_Març_Avrïu_Mai_Gün_Julia_Guscht_Setemvar_Listopäts_Noemvar_Zecemvar'.split('_'),\n    monthsShort : 'Jan_Fev_Mar_Avr_Mai_Gün_Jul_Gus_Set_Lis_Noe_Zec'.split('_'),\n    weekdays : 'Súladi_Lúneçi_Maitzi_Márcuri_Xhúadi_Viénerçi_Sáturi'.split('_'),\n    weekdaysShort : 'Súl_Lún_Mai_Már_Xhú_Vié_Sát'.split('_'),\n    weekdaysMin : 'Sú_Lú_Ma_Má_Xh_Vi_Sá'.split('_'),\n    longDateFormat : {\n        LT : 'HH.mm',\n        LTS : 'HH.mm.ss',\n        L : 'DD.MM.YYYY',\n        LL : 'D. MMMM [dallas] YYYY',\n        LLL : 'D. MMMM [dallas] YYYY HH.mm',\n        LLLL : 'dddd, [li] D. MMMM [dallas] YYYY HH.mm'\n    },\n    meridiemParse: /d\\'o|d\\'a/i,\n    isPM : function (input) {\n        return 'd\\'o' === input.toLowerCase();\n    },\n    meridiem : function (hours, minutes, isLower) {\n        if (hours > 11) {\n            return isLower ? 'd\\'o' : 'D\\'O';\n        } else {\n            return isLower ? 'd\\'a' : 'D\\'A';\n        }\n    },\n    calendar : {\n        sameDay : '[oxhi à] LT',\n        nextDay : '[demà à] LT',\n        nextWeek : 'dddd [à] LT',\n        lastDay : '[ieiri à] LT',\n        lastWeek : '[sür el] dddd [lasteu à] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'osprei %s',\n        past : 'ja%s',\n        s : processRelativeTime,\n        m : processRelativeTime,\n        mm : processRelativeTime,\n        h : processRelativeTime,\n        hh : processRelativeTime,\n        d : processRelativeTime,\n        dd : processRelativeTime,\n        M : processRelativeTime,\n        MM : processRelativeTime,\n        y : processRelativeTime,\n        yy : processRelativeTime\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}\\./,\n    ordinal : '%d.',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\nfunction processRelativeTime(number, withoutSuffix, key, isFuture) {\n    var format = {\n        's': ['viensas secunds', '\\'iensas secunds'],\n        'm': ['\\'n míut', '\\'iens míut'],\n        'mm': [number + ' míuts', '' + number + ' míuts'],\n        'h': ['\\'n þora', '\\'iensa þora'],\n        'hh': [number + ' þoras', '' + number + ' þoras'],\n        'd': ['\\'n ziua', '\\'iensa ziua'],\n        'dd': [number + ' ziuas', '' + number + ' ziuas'],\n        'M': ['\\'n mes', '\\'iens mes'],\n        'MM': [number + ' mesen', '' + number + ' mesen'],\n        'y': ['\\'n ar', '\\'iens ar'],\n        'yy': [number + ' ars', '' + number + ' ars']\n    };\n    return isFuture ? format[key][0] : (withoutSuffix ? format[key][0] : format[key][1]);\n}\n\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/locale/tzm-latn.js",
    "content": "//! moment.js locale configuration\n//! locale : Central Atlas Tamazight Latin [tzm-latn]\n//! author : Abdel Said : https://github.com/abdelsaid\n\nimport moment from '../moment';\n\nexport default moment.defineLocale('tzm-latn', {\n    months : 'innayr_brˤayrˤ_marˤsˤ_ibrir_mayyw_ywnyw_ywlywz_ɣwšt_šwtanbir_ktˤwbrˤ_nwwanbir_dwjnbir'.split('_'),\n    monthsShort : 'innayr_brˤayrˤ_marˤsˤ_ibrir_mayyw_ywnyw_ywlywz_ɣwšt_šwtanbir_ktˤwbrˤ_nwwanbir_dwjnbir'.split('_'),\n    weekdays : 'asamas_aynas_asinas_akras_akwas_asimwas_asiḍyas'.split('_'),\n    weekdaysShort : 'asamas_aynas_asinas_akras_akwas_asimwas_asiḍyas'.split('_'),\n    weekdaysMin : 'asamas_aynas_asinas_akras_akwas_asimwas_asiḍyas'.split('_'),\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY HH:mm',\n        LLLL : 'dddd D MMMM YYYY HH:mm'\n    },\n    calendar : {\n        sameDay: '[asdkh g] LT',\n        nextDay: '[aska g] LT',\n        nextWeek: 'dddd [g] LT',\n        lastDay: '[assant g] LT',\n        lastWeek: 'dddd [g] LT',\n        sameElse: 'L'\n    },\n    relativeTime : {\n        future : 'dadkh s yan %s',\n        past : 'yan %s',\n        s : 'imik',\n        m : 'minuḍ',\n        mm : '%d minuḍ',\n        h : 'saɛa',\n        hh : '%d tassaɛin',\n        d : 'ass',\n        dd : '%d ossan',\n        M : 'ayowr',\n        MM : '%d iyyirn',\n        y : 'asgas',\n        yy : '%d isgasn'\n    },\n    week : {\n        dow : 6, // Saturday is the first day of the week.\n        doy : 12  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/locale/tzm.js",
    "content": "//! moment.js locale configuration\n//! locale : Central Atlas Tamazight [tzm]\n//! author : Abdel Said : https://github.com/abdelsaid\n\nimport moment from '../moment';\n\nexport default moment.defineLocale('tzm', {\n    months : 'ⵉⵏⵏⴰⵢⵔ_ⴱⵕⴰⵢⵕ_ⵎⴰⵕⵚ_ⵉⴱⵔⵉⵔ_ⵎⴰⵢⵢⵓ_ⵢⵓⵏⵢⵓ_ⵢⵓⵍⵢⵓⵣ_ⵖⵓⵛⵜ_ⵛⵓⵜⴰⵏⴱⵉⵔ_ⴽⵟⵓⴱⵕ_ⵏⵓⵡⴰⵏⴱⵉⵔ_ⴷⵓⵊⵏⴱⵉⵔ'.split('_'),\n    monthsShort : 'ⵉⵏⵏⴰⵢⵔ_ⴱⵕⴰⵢⵕ_ⵎⴰⵕⵚ_ⵉⴱⵔⵉⵔ_ⵎⴰⵢⵢⵓ_ⵢⵓⵏⵢⵓ_ⵢⵓⵍⵢⵓⵣ_ⵖⵓⵛⵜ_ⵛⵓⵜⴰⵏⴱⵉⵔ_ⴽⵟⵓⴱⵕ_ⵏⵓⵡⴰⵏⴱⵉⵔ_ⴷⵓⵊⵏⴱⵉⵔ'.split('_'),\n    weekdays : 'ⴰⵙⴰⵎⴰⵙ_ⴰⵢⵏⴰⵙ_ⴰⵙⵉⵏⴰⵙ_ⴰⴽⵔⴰⵙ_ⴰⴽⵡⴰⵙ_ⴰⵙⵉⵎⵡⴰⵙ_ⴰⵙⵉⴹⵢⴰⵙ'.split('_'),\n    weekdaysShort : 'ⴰⵙⴰⵎⴰⵙ_ⴰⵢⵏⴰⵙ_ⴰⵙⵉⵏⴰⵙ_ⴰⴽⵔⴰⵙ_ⴰⴽⵡⴰⵙ_ⴰⵙⵉⵎⵡⴰⵙ_ⴰⵙⵉⴹⵢⴰⵙ'.split('_'),\n    weekdaysMin : 'ⴰⵙⴰⵎⴰⵙ_ⴰⵢⵏⴰⵙ_ⴰⵙⵉⵏⴰⵙ_ⴰⴽⵔⴰⵙ_ⴰⴽⵡⴰⵙ_ⴰⵙⵉⵎⵡⴰⵙ_ⴰⵙⵉⴹⵢⴰⵙ'.split('_'),\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS: 'HH:mm:ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY HH:mm',\n        LLLL : 'dddd D MMMM YYYY HH:mm'\n    },\n    calendar : {\n        sameDay: '[ⴰⵙⴷⵅ ⴴ] LT',\n        nextDay: '[ⴰⵙⴽⴰ ⴴ] LT',\n        nextWeek: 'dddd [ⴴ] LT',\n        lastDay: '[ⴰⵚⴰⵏⵜ ⴴ] LT',\n        lastWeek: 'dddd [ⴴ] LT',\n        sameElse: 'L'\n    },\n    relativeTime : {\n        future : 'ⴷⴰⴷⵅ ⵙ ⵢⴰⵏ %s',\n        past : 'ⵢⴰⵏ %s',\n        s : 'ⵉⵎⵉⴽ',\n        m : 'ⵎⵉⵏⵓⴺ',\n        mm : '%d ⵎⵉⵏⵓⴺ',\n        h : 'ⵙⴰⵄⴰ',\n        hh : '%d ⵜⴰⵙⵙⴰⵄⵉⵏ',\n        d : 'ⴰⵙⵙ',\n        dd : '%d oⵙⵙⴰⵏ',\n        M : 'ⴰⵢoⵓⵔ',\n        MM : '%d ⵉⵢⵢⵉⵔⵏ',\n        y : 'ⴰⵙⴳⴰⵙ',\n        yy : '%d ⵉⵙⴳⴰⵙⵏ'\n    },\n    week : {\n        dow : 6, // Saturday is the first day of the week.\n        doy : 12  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/locale/uk.js",
    "content": "//! moment.js locale configuration\n//! locale : Ukrainian [uk]\n//! author : zemlanin : https://github.com/zemlanin\n//! Author : Menelion Elensúle : https://github.com/Oire\n\nimport moment from '../moment';\n\nfunction plural(word, num) {\n    var forms = word.split('_');\n    return num % 10 === 1 && num % 100 !== 11 ? forms[0] : (num % 10 >= 2 && num % 10 <= 4 && (num % 100 < 10 || num % 100 >= 20) ? forms[1] : forms[2]);\n}\nfunction relativeTimeWithPlural(number, withoutSuffix, key) {\n    var format = {\n        'mm': withoutSuffix ? 'хвилина_хвилини_хвилин' : 'хвилину_хвилини_хвилин',\n        'hh': withoutSuffix ? 'година_години_годин' : 'годину_години_годин',\n        'dd': 'день_дні_днів',\n        'MM': 'місяць_місяці_місяців',\n        'yy': 'рік_роки_років'\n    };\n    if (key === 'm') {\n        return withoutSuffix ? 'хвилина' : 'хвилину';\n    }\n    else if (key === 'h') {\n        return withoutSuffix ? 'година' : 'годину';\n    }\n    else {\n        return number + ' ' + plural(format[key], +number);\n    }\n}\nfunction weekdaysCaseReplace(m, format) {\n    var weekdays = {\n        'nominative': 'неділя_понеділок_вівторок_середа_четвер_п’ятниця_субота'.split('_'),\n        'accusative': 'неділю_понеділок_вівторок_середу_четвер_п’ятницю_суботу'.split('_'),\n        'genitive': 'неділі_понеділка_вівторка_середи_четверга_п’ятниці_суботи'.split('_')\n    };\n\n    if (!m) {\n        return weekdays['nominative'];\n    }\n\n    var nounCase = (/(\\[[ВвУу]\\]) ?dddd/).test(format) ?\n        'accusative' :\n        ((/\\[?(?:минулої|наступної)? ?\\] ?dddd/).test(format) ?\n            'genitive' :\n            'nominative');\n    return weekdays[nounCase][m.day()];\n}\nfunction processHoursFunction(str) {\n    return function () {\n        return str + 'о' + (this.hours() === 11 ? 'б' : '') + '] LT';\n    };\n}\n\nexport default moment.defineLocale('uk', {\n    months : {\n        'format': 'січня_лютого_березня_квітня_травня_червня_липня_серпня_вересня_жовтня_листопада_грудня'.split('_'),\n        'standalone': 'січень_лютий_березень_квітень_травень_червень_липень_серпень_вересень_жовтень_листопад_грудень'.split('_')\n    },\n    monthsShort : 'січ_лют_бер_квіт_трав_черв_лип_серп_вер_жовт_лист_груд'.split('_'),\n    weekdays : weekdaysCaseReplace,\n    weekdaysShort : 'нд_пн_вт_ср_чт_пт_сб'.split('_'),\n    weekdaysMin : 'нд_пн_вт_ср_чт_пт_сб'.split('_'),\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD.MM.YYYY',\n        LL : 'D MMMM YYYY р.',\n        LLL : 'D MMMM YYYY р., HH:mm',\n        LLLL : 'dddd, D MMMM YYYY р., HH:mm'\n    },\n    calendar : {\n        sameDay: processHoursFunction('[Сьогодні '),\n        nextDay: processHoursFunction('[Завтра '),\n        lastDay: processHoursFunction('[Вчора '),\n        nextWeek: processHoursFunction('[У] dddd ['),\n        lastWeek: function () {\n            switch (this.day()) {\n                case 0:\n                case 3:\n                case 5:\n                case 6:\n                    return processHoursFunction('[Минулої] dddd [').call(this);\n                case 1:\n                case 2:\n                case 4:\n                    return processHoursFunction('[Минулого] dddd [').call(this);\n            }\n        },\n        sameElse: 'L'\n    },\n    relativeTime : {\n        future : 'за %s',\n        past : '%s тому',\n        s : 'декілька секунд',\n        m : relativeTimeWithPlural,\n        mm : relativeTimeWithPlural,\n        h : 'годину',\n        hh : relativeTimeWithPlural,\n        d : 'день',\n        dd : relativeTimeWithPlural,\n        M : 'місяць',\n        MM : relativeTimeWithPlural,\n        y : 'рік',\n        yy : relativeTimeWithPlural\n    },\n    // M. E.: those two are virtually unused but a user might want to implement them for his/her website for some reason\n    meridiemParse: /ночі|ранку|дня|вечора/,\n    isPM: function (input) {\n        return /^(дня|вечора)$/.test(input);\n    },\n    meridiem : function (hour, minute, isLower) {\n        if (hour < 4) {\n            return 'ночі';\n        } else if (hour < 12) {\n            return 'ранку';\n        } else if (hour < 17) {\n            return 'дня';\n        } else {\n            return 'вечора';\n        }\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}-(й|го)/,\n    ordinal: function (number, period) {\n        switch (period) {\n            case 'M':\n            case 'd':\n            case 'DDD':\n            case 'w':\n            case 'W':\n                return number + '-й';\n            case 'D':\n                return number + '-го';\n            default:\n                return number;\n        }\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 7  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/locale/ur.js",
    "content": "//! moment.js locale configuration\n//! locale : Urdu [ur]\n//! author : Sawood Alam : https://github.com/ibnesayeed\n//! author : Zack : https://github.com/ZackVision\n\nimport moment from '../moment';\n\nvar months = [\n    'جنوری',\n    'فروری',\n    'مارچ',\n    'اپریل',\n    'مئی',\n    'جون',\n    'جولائی',\n    'اگست',\n    'ستمبر',\n    'اکتوبر',\n    'نومبر',\n    'دسمبر'\n];\nvar days = [\n    'اتوار',\n    'پیر',\n    'منگل',\n    'بدھ',\n    'جمعرات',\n    'جمعہ',\n    'ہفتہ'\n];\n\nexport default moment.defineLocale('ur', {\n    months : months,\n    monthsShort : months,\n    weekdays : days,\n    weekdaysShort : days,\n    weekdaysMin : days,\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY HH:mm',\n        LLLL : 'dddd، D MMMM YYYY HH:mm'\n    },\n    meridiemParse: /صبح|شام/,\n    isPM : function (input) {\n        return 'شام' === input;\n    },\n    meridiem : function (hour, minute, isLower) {\n        if (hour < 12) {\n            return 'صبح';\n        }\n        return 'شام';\n    },\n    calendar : {\n        sameDay : '[آج بوقت] LT',\n        nextDay : '[کل بوقت] LT',\n        nextWeek : 'dddd [بوقت] LT',\n        lastDay : '[گذشتہ روز بوقت] LT',\n        lastWeek : '[گذشتہ] dddd [بوقت] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : '%s بعد',\n        past : '%s قبل',\n        s : 'چند سیکنڈ',\n        m : 'ایک منٹ',\n        mm : '%d منٹ',\n        h : 'ایک گھنٹہ',\n        hh : '%d گھنٹے',\n        d : 'ایک دن',\n        dd : '%d دن',\n        M : 'ایک ماہ',\n        MM : '%d ماہ',\n        y : 'ایک سال',\n        yy : '%d سال'\n    },\n    preparse: function (string) {\n        return string.replace(/،/g, ',');\n    },\n    postformat: function (string) {\n        return string.replace(/,/g, '،');\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/locale/uz-latn.js",
    "content": "//! moment.js locale configuration\n//! locale : Uzbek Latin [uz-latn]\n//! author : Rasulbek Mirzayev : github.com/Rasulbeeek\n\nimport moment from '../moment';\n\nexport default moment.defineLocale('uz-latn', {\n    months : 'Yanvar_Fevral_Mart_Aprel_May_Iyun_Iyul_Avgust_Sentabr_Oktabr_Noyabr_Dekabr'.split('_'),\n    monthsShort : 'Yan_Fev_Mar_Apr_May_Iyun_Iyul_Avg_Sen_Okt_Noy_Dek'.split('_'),\n    weekdays : 'Yakshanba_Dushanba_Seshanba_Chorshanba_Payshanba_Juma_Shanba'.split('_'),\n    weekdaysShort : 'Yak_Dush_Sesh_Chor_Pay_Jum_Shan'.split('_'),\n    weekdaysMin : 'Ya_Du_Se_Cho_Pa_Ju_Sha'.split('_'),\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY HH:mm',\n        LLLL : 'D MMMM YYYY, dddd HH:mm'\n    },\n    calendar : {\n        sameDay : '[Bugun soat] LT [da]',\n        nextDay : '[Ertaga] LT [da]',\n        nextWeek : 'dddd [kuni soat] LT [da]',\n        lastDay : '[Kecha soat] LT [da]',\n        lastWeek : '[O\\'tgan] dddd [kuni soat] LT [da]',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'Yaqin %s ichida',\n        past : 'Bir necha %s oldin',\n        s : 'soniya',\n        m : 'bir daqiqa',\n        mm : '%d daqiqa',\n        h : 'bir soat',\n        hh : '%d soat',\n        d : 'bir kun',\n        dd : '%d kun',\n        M : 'bir oy',\n        MM : '%d oy',\n        y : 'bir yil',\n        yy : '%d yil'\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 7  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/locale/uz.js",
    "content": "//! moment.js locale configuration\n//! locale : Uzbek [uz]\n//! author : Sardor Muminov : https://github.com/muminoff\n\nimport moment from '../moment';\n\nexport default moment.defineLocale('uz', {\n    months : 'январ_феврал_март_апрел_май_июн_июл_август_сентябр_октябр_ноябр_декабр'.split('_'),\n    monthsShort : 'янв_фев_мар_апр_май_июн_июл_авг_сен_окт_ноя_дек'.split('_'),\n    weekdays : 'Якшанба_Душанба_Сешанба_Чоршанба_Пайшанба_Жума_Шанба'.split('_'),\n    weekdaysShort : 'Якш_Душ_Сеш_Чор_Пай_Жум_Шан'.split('_'),\n    weekdaysMin : 'Як_Ду_Се_Чо_Па_Жу_Ша'.split('_'),\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY HH:mm',\n        LLLL : 'D MMMM YYYY, dddd HH:mm'\n    },\n    calendar : {\n        sameDay : '[Бугун соат] LT [да]',\n        nextDay : '[Эртага] LT [да]',\n        nextWeek : 'dddd [куни соат] LT [да]',\n        lastDay : '[Кеча соат] LT [да]',\n        lastWeek : '[Утган] dddd [куни соат] LT [да]',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'Якин %s ичида',\n        past : 'Бир неча %s олдин',\n        s : 'фурсат',\n        m : 'бир дакика',\n        mm : '%d дакика',\n        h : 'бир соат',\n        hh : '%d соат',\n        d : 'бир кун',\n        dd : '%d кун',\n        M : 'бир ой',\n        MM : '%d ой',\n        y : 'бир йил',\n        yy : '%d йил'\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 7  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/locale/vi.js",
    "content": "//! moment.js locale configuration\n//! locale : Vietnamese [vi]\n//! author : Bang Nguyen : https://github.com/bangnk\n\nimport moment from '../moment';\n\nexport default moment.defineLocale('vi', {\n    months : 'tháng 1_tháng 2_tháng 3_tháng 4_tháng 5_tháng 6_tháng 7_tháng 8_tháng 9_tháng 10_tháng 11_tháng 12'.split('_'),\n    monthsShort : 'Th01_Th02_Th03_Th04_Th05_Th06_Th07_Th08_Th09_Th10_Th11_Th12'.split('_'),\n    monthsParseExact : true,\n    weekdays : 'chủ nhật_thứ hai_thứ ba_thứ tư_thứ năm_thứ sáu_thứ bảy'.split('_'),\n    weekdaysShort : 'CN_T2_T3_T4_T5_T6_T7'.split('_'),\n    weekdaysMin : 'CN_T2_T3_T4_T5_T6_T7'.split('_'),\n    weekdaysParseExact : true,\n    meridiemParse: /sa|ch/i,\n    isPM : function (input) {\n        return /^ch$/i.test(input);\n    },\n    meridiem : function (hours, minutes, isLower) {\n        if (hours < 12) {\n            return isLower ? 'sa' : 'SA';\n        } else {\n            return isLower ? 'ch' : 'CH';\n        }\n    },\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM [năm] YYYY',\n        LLL : 'D MMMM [năm] YYYY HH:mm',\n        LLLL : 'dddd, D MMMM [năm] YYYY HH:mm',\n        l : 'DD/M/YYYY',\n        ll : 'D MMM YYYY',\n        lll : 'D MMM YYYY HH:mm',\n        llll : 'ddd, D MMM YYYY HH:mm'\n    },\n    calendar : {\n        sameDay: '[Hôm nay lúc] LT',\n        nextDay: '[Ngày mai lúc] LT',\n        nextWeek: 'dddd [tuần tới lúc] LT',\n        lastDay: '[Hôm qua lúc] LT',\n        lastWeek: 'dddd [tuần rồi lúc] LT',\n        sameElse: 'L'\n    },\n    relativeTime : {\n        future : '%s tới',\n        past : '%s trước',\n        s : 'vài giây',\n        m : 'một phút',\n        mm : '%d phút',\n        h : 'một giờ',\n        hh : '%d giờ',\n        d : 'một ngày',\n        dd : '%d ngày',\n        M : 'một tháng',\n        MM : '%d tháng',\n        y : 'một năm',\n        yy : '%d năm'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}/,\n    ordinal : function (number) {\n        return number;\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/locale/x-pseudo.js",
    "content": "//! moment.js locale configuration\n//! locale : Pseudo [x-pseudo]\n//! author : Andrew Hood : https://github.com/andrewhood125\n\nimport moment from '../moment';\n\nexport default moment.defineLocale('x-pseudo', {\n    months : 'J~áñúá~rý_F~ébrú~árý_~Márc~h_Áp~ríl_~Máý_~Júñé~_Júl~ý_Áú~gúst~_Sép~témb~ér_Ó~ctób~ér_Ñ~óvém~bér_~Décé~mbér'.split('_'),\n    monthsShort : 'J~áñ_~Féb_~Már_~Ápr_~Máý_~Júñ_~Júl_~Áúg_~Sép_~Óct_~Ñóv_~Déc'.split('_'),\n    monthsParseExact : true,\n    weekdays : 'S~úñdá~ý_Mó~ñdáý~_Túé~sdáý~_Wéd~ñésd~áý_T~húrs~dáý_~Fríd~áý_S~átúr~dáý'.split('_'),\n    weekdaysShort : 'S~úñ_~Móñ_~Túé_~Wéd_~Thú_~Frí_~Sát'.split('_'),\n    weekdaysMin : 'S~ú_Mó~_Tú_~Wé_T~h_Fr~_Sá'.split('_'),\n    weekdaysParseExact : true,\n    longDateFormat : {\n        LT : 'HH:mm',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY HH:mm',\n        LLLL : 'dddd, D MMMM YYYY HH:mm'\n    },\n    calendar : {\n        sameDay : '[T~ódá~ý át] LT',\n        nextDay : '[T~ómó~rró~w át] LT',\n        nextWeek : 'dddd [át] LT',\n        lastDay : '[Ý~ést~érdá~ý át] LT',\n        lastWeek : '[L~ást] dddd [át] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'í~ñ %s',\n        past : '%s á~gó',\n        s : 'á ~féw ~sécó~ñds',\n        m : 'á ~míñ~úté',\n        mm : '%d m~íñú~tés',\n        h : 'á~ñ hó~úr',\n        hh : '%d h~óúrs',\n        d : 'á ~dáý',\n        dd : '%d d~áýs',\n        M : 'á ~móñ~th',\n        MM : '%d m~óñt~hs',\n        y : 'á ~ýéár',\n        yy : '%d ý~éárs'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}(th|st|nd|rd)/,\n    ordinal : function (number) {\n        var b = number % 10,\n            output = (~~(number % 100 / 10) === 1) ? 'th' :\n            (b === 1) ? 'st' :\n            (b === 2) ? 'nd' :\n            (b === 3) ? 'rd' : 'th';\n        return number + output;\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/locale/yo.js",
    "content": "//! moment.js locale configuration\n//! locale : Yoruba Nigeria [yo]\n//! author : Atolagbe Abisoye : https://github.com/andela-batolagbe\n\nimport moment from '../moment';\n\nexport default moment.defineLocale('yo', {\n    months : 'Sẹ́rẹ́_Èrèlè_Ẹrẹ̀nà_Ìgbé_Èbibi_Òkùdu_Agẹmo_Ògún_Owewe_Ọ̀wàrà_Bélú_Ọ̀pẹ̀̀'.split('_'),\n    monthsShort : 'Sẹ́r_Èrl_Ẹrn_Ìgb_Èbi_Òkù_Agẹ_Ògú_Owe_Ọ̀wà_Bél_Ọ̀pẹ̀̀'.split('_'),\n    weekdays : 'Àìkú_Ajé_Ìsẹ́gun_Ọjọ́rú_Ọjọ́bọ_Ẹtì_Àbámẹ́ta'.split('_'),\n    weekdaysShort : 'Àìk_Ajé_Ìsẹ́_Ọjr_Ọjb_Ẹtì_Àbá'.split('_'),\n    weekdaysMin : 'Àì_Aj_Ìs_Ọr_Ọb_Ẹt_Àb'.split('_'),\n    longDateFormat : {\n        LT : 'h:mm A',\n        LTS : 'h:mm:ss A',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY h:mm A',\n        LLLL : 'dddd, D MMMM YYYY h:mm A'\n    },\n    calendar : {\n        sameDay : '[Ònì ni] LT',\n        nextDay : '[Ọ̀la ni] LT',\n        nextWeek : 'dddd [Ọsẹ̀ tón\\'bọ] [ni] LT',\n        lastDay : '[Àna ni] LT',\n        lastWeek : 'dddd [Ọsẹ̀ tólọ́] [ni] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'ní %s',\n        past : '%s kọjá',\n        s : 'ìsẹjú aayá die',\n        m : 'ìsẹjú kan',\n        mm : 'ìsẹjú %d',\n        h : 'wákati kan',\n        hh : 'wákati %d',\n        d : 'ọjọ́ kan',\n        dd : 'ọjọ́ %d',\n        M : 'osù kan',\n        MM : 'osù %d',\n        y : 'ọdún kan',\n        yy : 'ọdún %d'\n    },\n    dayOfMonthOrdinalParse : /ọjọ́\\s\\d{1,2}/,\n    ordinal : 'ọjọ́ %d',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4 // The week that contains Jan 4th is the first week of the year.\n    }\n});\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/locale/zh-cn.js",
    "content": "//! moment.js locale configuration\n//! locale : Chinese (China) [zh-cn]\n//! author : suupic : https://github.com/suupic\n//! author : Zeno Zeng : https://github.com/zenozeng\n\nimport moment from '../moment';\n\nexport default moment.defineLocale('zh-cn', {\n    months : '一月_二月_三月_四月_五月_六月_七月_八月_九月_十月_十一月_十二月'.split('_'),\n    monthsShort : '1月_2月_3月_4月_5月_6月_7月_8月_9月_10月_11月_12月'.split('_'),\n    weekdays : '星期日_星期一_星期二_星期三_星期四_星期五_星期六'.split('_'),\n    weekdaysShort : '周日_周一_周二_周三_周四_周五_周六'.split('_'),\n    weekdaysMin : '日_一_二_三_四_五_六'.split('_'),\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'YYYY年MMMD日',\n        LL : 'YYYY年MMMD日',\n        LLL : 'YYYY年MMMD日Ah点mm分',\n        LLLL : 'YYYY年MMMD日ddddAh点mm分',\n        l : 'YYYY年MMMD日',\n        ll : 'YYYY年MMMD日',\n        lll : 'YYYY年MMMD日 HH:mm',\n        llll : 'YYYY年MMMD日dddd HH:mm'\n    },\n    meridiemParse: /凌晨|早上|上午|中午|下午|晚上/,\n    meridiemHour: function (hour, meridiem) {\n        if (hour === 12) {\n            hour = 0;\n        }\n        if (meridiem === '凌晨' || meridiem === '早上' ||\n                meridiem === '上午') {\n            return hour;\n        } else if (meridiem === '下午' || meridiem === '晚上') {\n            return hour + 12;\n        } else {\n            // '中午'\n            return hour >= 11 ? hour : hour + 12;\n        }\n    },\n    meridiem : function (hour, minute, isLower) {\n        var hm = hour * 100 + minute;\n        if (hm < 600) {\n            return '凌晨';\n        } else if (hm < 900) {\n            return '早上';\n        } else if (hm < 1130) {\n            return '上午';\n        } else if (hm < 1230) {\n            return '中午';\n        } else if (hm < 1800) {\n            return '下午';\n        } else {\n            return '晚上';\n        }\n    },\n    calendar : {\n        sameDay : '[今天]LT',\n        nextDay : '[明天]LT',\n        nextWeek : '[下]ddddLT',\n        lastDay : '[昨天]LT',\n        lastWeek : '[上]ddddLT',\n        sameElse : 'L'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}(日|月|周)/,\n    ordinal : function (number, period) {\n        switch (period) {\n            case 'd':\n            case 'D':\n            case 'DDD':\n                return number + '日';\n            case 'M':\n                return number + '月';\n            case 'w':\n            case 'W':\n                return number + '周';\n            default:\n                return number;\n        }\n    },\n    relativeTime : {\n        future : '%s内',\n        past : '%s前',\n        s : '几秒',\n        m : '1 分钟',\n        mm : '%d 分钟',\n        h : '1 小时',\n        hh : '%d 小时',\n        d : '1 天',\n        dd : '%d 天',\n        M : '1 个月',\n        MM : '%d 个月',\n        y : '1 年',\n        yy : '%d 年'\n    },\n    week : {\n        // GB/T 7408-1994《数据元和交换格式·信息交换·日期和时间表示法》与ISO 8601:1988等效\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/locale/zh-hk.js",
    "content": "//! moment.js locale configuration\n//! locale : Chinese (Hong Kong) [zh-hk]\n//! author : Ben : https://github.com/ben-lin\n//! author : Chris Lam : https://github.com/hehachris\n//! author : Konstantin : https://github.com/skfd\n\nimport moment from '../moment';\n\nexport default moment.defineLocale('zh-hk', {\n    months : '一月_二月_三月_四月_五月_六月_七月_八月_九月_十月_十一月_十二月'.split('_'),\n    monthsShort : '1月_2月_3月_4月_5月_6月_7月_8月_9月_10月_11月_12月'.split('_'),\n    weekdays : '星期日_星期一_星期二_星期三_星期四_星期五_星期六'.split('_'),\n    weekdaysShort : '週日_週一_週二_週三_週四_週五_週六'.split('_'),\n    weekdaysMin : '日_一_二_三_四_五_六'.split('_'),\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'YYYY年MMMD日',\n        LL : 'YYYY年MMMD日',\n        LLL : 'YYYY年MMMD日 HH:mm',\n        LLLL : 'YYYY年MMMD日dddd HH:mm',\n        l : 'YYYY年MMMD日',\n        ll : 'YYYY年MMMD日',\n        lll : 'YYYY年MMMD日 HH:mm',\n        llll : 'YYYY年MMMD日dddd HH:mm'\n    },\n    meridiemParse: /凌晨|早上|上午|中午|下午|晚上/,\n    meridiemHour : function (hour, meridiem) {\n        if (hour === 12) {\n            hour = 0;\n        }\n        if (meridiem === '凌晨' || meridiem === '早上' || meridiem === '上午') {\n            return hour;\n        } else if (meridiem === '中午') {\n            return hour >= 11 ? hour : hour + 12;\n        } else if (meridiem === '下午' || meridiem === '晚上') {\n            return hour + 12;\n        }\n    },\n    meridiem : function (hour, minute, isLower) {\n        var hm = hour * 100 + minute;\n        if (hm < 600) {\n            return '凌晨';\n        } else if (hm < 900) {\n            return '早上';\n        } else if (hm < 1130) {\n            return '上午';\n        } else if (hm < 1230) {\n            return '中午';\n        } else if (hm < 1800) {\n            return '下午';\n        } else {\n            return '晚上';\n        }\n    },\n    calendar : {\n        sameDay : '[今天]LT',\n        nextDay : '[明天]LT',\n        nextWeek : '[下]ddddLT',\n        lastDay : '[昨天]LT',\n        lastWeek : '[上]ddddLT',\n        sameElse : 'L'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}(日|月|週)/,\n    ordinal : function (number, period) {\n        switch (period) {\n            case 'd' :\n            case 'D' :\n            case 'DDD' :\n                return number + '日';\n            case 'M' :\n                return number + '月';\n            case 'w' :\n            case 'W' :\n                return number + '週';\n            default :\n                return number;\n        }\n    },\n    relativeTime : {\n        future : '%s內',\n        past : '%s前',\n        s : '幾秒',\n        m : '1 分鐘',\n        mm : '%d 分鐘',\n        h : '1 小時',\n        hh : '%d 小時',\n        d : '1 天',\n        dd : '%d 天',\n        M : '1 個月',\n        MM : '%d 個月',\n        y : '1 年',\n        yy : '%d 年'\n    }\n});\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/locale/zh-tw.js",
    "content": "//! moment.js locale configuration\n//! locale : Chinese (Taiwan) [zh-tw]\n//! author : Ben : https://github.com/ben-lin\n//! author : Chris Lam : https://github.com/hehachris\n\nimport moment from '../moment';\n\nexport default moment.defineLocale('zh-tw', {\n    months : '一月_二月_三月_四月_五月_六月_七月_八月_九月_十月_十一月_十二月'.split('_'),\n    monthsShort : '1月_2月_3月_4月_5月_6月_7月_8月_9月_10月_11月_12月'.split('_'),\n    weekdays : '星期日_星期一_星期二_星期三_星期四_星期五_星期六'.split('_'),\n    weekdaysShort : '週日_週一_週二_週三_週四_週五_週六'.split('_'),\n    weekdaysMin : '日_一_二_三_四_五_六'.split('_'),\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'YYYY年MMMD日',\n        LL : 'YYYY年MMMD日',\n        LLL : 'YYYY年MMMD日 HH:mm',\n        LLLL : 'YYYY年MMMD日dddd HH:mm',\n        l : 'YYYY年MMMD日',\n        ll : 'YYYY年MMMD日',\n        lll : 'YYYY年MMMD日 HH:mm',\n        llll : 'YYYY年MMMD日dddd HH:mm'\n    },\n    meridiemParse: /凌晨|早上|上午|中午|下午|晚上/,\n    meridiemHour : function (hour, meridiem) {\n        if (hour === 12) {\n            hour = 0;\n        }\n        if (meridiem === '凌晨' || meridiem === '早上' || meridiem === '上午') {\n            return hour;\n        } else if (meridiem === '中午') {\n            return hour >= 11 ? hour : hour + 12;\n        } else if (meridiem === '下午' || meridiem === '晚上') {\n            return hour + 12;\n        }\n    },\n    meridiem : function (hour, minute, isLower) {\n        var hm = hour * 100 + minute;\n        if (hm < 600) {\n            return '凌晨';\n        } else if (hm < 900) {\n            return '早上';\n        } else if (hm < 1130) {\n            return '上午';\n        } else if (hm < 1230) {\n            return '中午';\n        } else if (hm < 1800) {\n            return '下午';\n        } else {\n            return '晚上';\n        }\n    },\n    calendar : {\n        sameDay : '[今天]LT',\n        nextDay : '[明天]LT',\n        nextWeek : '[下]ddddLT',\n        lastDay : '[昨天]LT',\n        lastWeek : '[上]ddddLT',\n        sameElse : 'L'\n    },\n    dayOfMonthOrdinalParse: /\\d{1,2}(日|月|週)/,\n    ordinal : function (number, period) {\n        switch (period) {\n            case 'd' :\n            case 'D' :\n            case 'DDD' :\n                return number + '日';\n            case 'M' :\n                return number + '月';\n            case 'w' :\n            case 'W' :\n                return number + '週';\n            default :\n                return number;\n        }\n    },\n    relativeTime : {\n        future : '%s內',\n        past : '%s前',\n        s : '幾秒',\n        m : '1 分鐘',\n        mm : '%d 分鐘',\n        h : '1 小時',\n        hh : '%d 小時',\n        d : '1 天',\n        dd : '%d 天',\n        M : '1 個月',\n        MM : '%d 個月',\n        y : '1 年',\n        yy : '%d 年'\n    }\n});\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/moment.js",
    "content": "//! moment.js\n//! version : 2.18.1\n//! authors : Tim Wood, Iskren Chernev, Moment.js contributors\n//! license : MIT\n//! momentjs.com\n\nimport { hooks as moment, setHookCallback } from './lib/utils/hooks';\n\nmoment.version = '2.18.1';\n\nimport {\n    min,\n    max,\n    now,\n    isMoment,\n    momentPrototype as fn,\n    createUTC       as utc,\n    createUnix      as unix,\n    createLocal     as local,\n    createInvalid   as invalid,\n    createInZone    as parseZone\n} from './lib/moment/moment';\n\nimport {\n    getCalendarFormat\n} from './lib/moment/calendar';\n\nimport {\n    defineLocale,\n    updateLocale,\n    getSetGlobalLocale as locale,\n    getLocale          as localeData,\n    listLocales        as locales,\n    listMonths         as months,\n    listMonthsShort    as monthsShort,\n    listWeekdays       as weekdays,\n    listWeekdaysMin    as weekdaysMin,\n    listWeekdaysShort  as weekdaysShort\n} from './lib/locale/locale';\n\nimport {\n    isDuration,\n    createDuration as duration,\n    getSetRelativeTimeRounding as relativeTimeRounding,\n    getSetRelativeTimeThreshold as relativeTimeThreshold\n} from './lib/duration/duration';\n\nimport { normalizeUnits } from './lib/units/units';\n\nimport isDate from './lib/utils/is-date';\n\nsetHookCallback(local);\n\nmoment.fn                    = fn;\nmoment.min                   = min;\nmoment.max                   = max;\nmoment.now                   = now;\nmoment.utc                   = utc;\nmoment.unix                  = unix;\nmoment.months                = months;\nmoment.isDate                = isDate;\nmoment.locale                = locale;\nmoment.invalid               = invalid;\nmoment.duration              = duration;\nmoment.isMoment              = isMoment;\nmoment.weekdays              = weekdays;\nmoment.parseZone             = parseZone;\nmoment.localeData            = localeData;\nmoment.isDuration            = isDuration;\nmoment.monthsShort           = monthsShort;\nmoment.weekdaysMin           = weekdaysMin;\nmoment.defineLocale          = defineLocale;\nmoment.updateLocale          = updateLocale;\nmoment.locales               = locales;\nmoment.weekdaysShort         = weekdaysShort;\nmoment.normalizeUnits        = normalizeUnits;\nmoment.relativeTimeRounding = relativeTimeRounding;\nmoment.relativeTimeThreshold = relativeTimeThreshold;\nmoment.calendarFormat        = getCalendarFormat;\nmoment.prototype             = fn;\n\nexport default moment;\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/test/helpers/common-locale.js",
    "content": "import { test, expect } from '../qunit';\nimport each from './each';\nimport objectKeys from './object-keys';\nimport moment from '../../moment';\nimport defaults from '../../lib/utils/defaults';\n\nexport function defineCommonLocaleTests(locale, options) {\n    test('lenient day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient day of month ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient day of month ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient day of month ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient day of month ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict day of month ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment.utc(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('date format correctness', function (assert) {\n        var data, tokens;\n        data = moment.localeData()._longDateFormat;\n        tokens = objectKeys(data);\n        each(tokens, function (srchToken) {\n            // Check each format string to make sure it does not contain any\n            // tokens that need to be expanded.\n            each(tokens, function (baseToken) {\n                // strip escaped sequences\n                var format = data[baseToken].replace(/(\\[[^\\]]*\\])/g, '');\n                assert.equal(false, !!~format.indexOf(srchToken),\n                        'contains ' + srchToken + ' in ' + baseToken);\n            });\n        });\n    });\n\n    test('month parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr') {\n            // I can't fix it :(\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r;\n            r = moment(m.format(format), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.month(), m.month(), 'month ' + i + ' fmt ' + format + ' lower strict');\n        }\n\n        for (i = 0; i < 12; ++i) {\n            m = moment([2015, i, 15, 18]);\n            tester('MMM');\n            tester('MMM.');\n            tester('MMMM');\n            tester('MMMM.');\n        }\n    });\n\n    test('weekday parsing correctness', function (assert) {\n        var i, m;\n\n        if (locale === 'tr' || locale === 'az' || locale === 'ro') {\n            // tr, az: There is a lower-case letter (ı), that converted to\n            // upper then lower changes to i\n            // ro: there is the letter ț which behaves weird under IE8\n            expect(0);\n            return;\n        }\n        function tester(format) {\n            var r, baseMsg = 'weekday ' + m.weekday() + ' fmt ' + format + ' ' + m.toISOString();\n            r = moment(m.format(format), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg);\n            r = moment(m.format(format).toLocaleUpperCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper');\n            r = moment(m.format(format).toLocaleLowerCase(), format);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower');\n\n            r = moment(m.format(format), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' strict');\n            r = moment(m.format(format).toLocaleUpperCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' upper strict');\n            r = moment(m.format(format).toLocaleLowerCase(), format, true);\n            assert.equal(r.weekday(), m.weekday(), baseMsg + ' lower strict');\n        }\n\n        for (i = 0; i < 7; ++i) {\n            m = moment.utc([2015, 0, i + 1, 18]);\n            tester('dd');\n            tester('ddd');\n            tester('dddd');\n        }\n    });\n\n    test('valid localeData', function (assert) {\n        assert.equal(moment().localeData().months().length, 12, 'months should return 12 months');\n        assert.equal(moment().localeData().monthsShort().length, 12, 'monthsShort should return 12 months');\n        assert.equal(moment().localeData().weekdays().length, 7, 'weekdays should return 7 days');\n        assert.equal(moment().localeData().weekdaysShort().length, 7, 'weekdaysShort should return 7 days');\n        assert.equal(moment().localeData().weekdaysMin().length, 7, 'monthsShort should return 7 days');\n    });\n}\n\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/test/helpers/deprecation-handler.js",
    "content": "import each from './each';\n\nexport function setupDeprecationHandler(test, moment, scope) {\n    test._expectedDeprecations = null;\n    test._observedDeprecations = null;\n    test._oldSupress = moment.suppressDeprecationWarnings;\n    moment.suppressDeprecationWarnings = true;\n    test.expectedDeprecations = function () {\n        test._expectedDeprecations = arguments;\n        test._observedDeprecations = [];\n    };\n    moment.deprecationHandler = function (name, msg) {\n        var deprecationId = matchedDeprecation(name, msg, test._expectedDeprecations);\n        if (deprecationId === -1) {\n            throw new Error('Unexpected deprecation thrown name=' +\n                    name + ' msg=' + msg);\n        }\n        test._observedDeprecations[deprecationId] = 1;\n    };\n}\n\nexport function teardownDeprecationHandler(test, moment, scope) {\n    moment.suppressDeprecationWarnings = test._oldSupress;\n\n    if (test._expectedDeprecations != null) {\n        var missedDeprecations = [];\n        each(test._expectedDeprecations, function (deprecationPattern, id) {\n            if (test._observedDeprecations[id] !== 1) {\n                missedDeprecations.push(deprecationPattern);\n            }\n        });\n        if (missedDeprecations.length !== 0) {\n            throw new Error('Expected deprecation warnings did not happen: ' +\n                    missedDeprecations.join(' '));\n        }\n    }\n}\n\nfunction matchedDeprecation(name, msg, deprecations) {\n    if (deprecations == null) {\n        return -1;\n    }\n    for (var i = 0; i < deprecations.length; ++i) {\n        if (name != null && name === deprecations[i]) {\n            return i;\n        }\n        if (msg != null && msg.substring(0, deprecations[i].length) === deprecations[i]) {\n            return i;\n        }\n    }\n    return -1;\n}\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/test/helpers/dst.js",
    "content": "import moment from '../../moment';\n\nexport function isNearSpringDST() {\n    return moment().subtract(1, 'day').utcOffset() !== moment().add(1, 'day').utcOffset();\n}\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/test/helpers/each.js",
    "content": "function each(array, callback) {\n    var i;\n    for (i = 0; i < array.length; i++) {\n        callback(array[i], i, array);\n    }\n}\n\nexport default each;\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/test/helpers/object-keys.js",
    "content": "export default function objectKeys(obj) {\n    if (Object.keys) {\n        return Object.keys(obj);\n    } else {\n        // IE8\n        var res = [], i;\n        for (i in obj) {\n            if (obj.hasOwnProperty(i)) {\n                res.push(i);\n            }\n        }\n        return res;\n    }\n}\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/test/locale/af.js",
    "content": "import {localeModule, test} from '../qunit';\nimport moment from '../../moment';\nlocaleModule('af');\n\ntest('parse', function (assert) {\n    var tests = 'Januarie Jan_Februarie Feb_Maart Mrt_April Apr_Mei Mei_Junie Jun_Julie Jul_Augustus Aug_September Sep_Oktober Okt_November Nov_Desember Des'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, MMMM Do YYYY, h:mm:ss a',      'Sondag, Februarie 14de 2010, 3:25:50 nm'],\n            ['ddd, hA',                            'Son, 3NM'],\n            ['M Mo MM MMMM MMM',                   '2 2de 02 Februarie Feb'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14de 14'],\n            ['d do dddd ddd dd',                   '0 0de Sondag Son So'],\n            ['DDD DDDo DDDD',                      '45 45ste 045'],\n            ['w wo ww',                            '6 6de 06'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'nm NM'],\n            ['[the] DDDo [day of the year]',       'the 45ste day of the year'],\n            ['LT',                                 '15:25'],\n            ['LTS',                                '15:25:50'],\n            ['L',                                  '14/02/2010'],\n            ['LL',                                 '14 Februarie 2010'],\n            ['LLL',                                '14 Februarie 2010 15:25'],\n            ['LLLL',                               'Sondag, 14 Februarie 2010 15:25'],\n            ['l',                                  '14/2/2010'],\n            ['ll',                                 '14 Feb 2010'],\n            ['lll',                                '14 Feb 2010 15:25'],\n            ['llll',                               'Son, 14 Feb 2010 15:25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1ste', '1ste');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2de', '2de');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3de', '3de');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4de', '4de');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5de', '5de');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6de', '6de');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7de', '7de');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8ste', '8ste');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9de', '9de');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10de', '10de');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11de', '11de');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12de', '12de');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13de', '13de');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14de', '14de');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15de', '15de');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16de', '16de');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17de', '17de');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18de', '18de');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19de', '19de');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20ste', '20ste');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21ste', '21ste');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22ste', '22ste');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23ste', '23ste');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24ste', '24ste');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25ste', '25ste');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26ste', '26ste');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27ste', '27ste');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28ste', '28ste');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29ste', '29ste');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30ste', '30ste');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31ste', '31ste');\n});\n\ntest('format month', function (assert) {\n    var expected = 'Januarie Jan_Februarie Feb_Maart Mrt_April Apr_Mei Mei_Junie Jun_Julie Jul_Augustus Aug_September Sep_Oktober Okt_November Nov_Desember Des'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'Sondag Son So_Maandag Maa Ma_Dinsdag Din Di_Woensdag Woe Wo_Donderdag Don Do_Vrydag Vry Vr_Saterdag Sat Sa'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  '\\'n paar sekondes', '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  '\\'n minuut',      '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  '\\'n minuut',      '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 minute',     '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 minute',    '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  '\\'n uur',       '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  '\\'n uur',       '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 ure',       '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 ure',       '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 ure',      '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  '\\'n dag',         '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  '\\'n dag',         '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 dae',        '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   '\\'n dag',         '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 dae',        '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 dae',       '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  '\\'n maand',       '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  '\\'n maand',       '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  '\\'n maand',       '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 maande',      '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 maande',      '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 maande',      '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   '\\'n maand',       '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 maande',      '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), '\\'n jaar',        '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 jaar',       '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   '\\'n jaar',        '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 jaar',       '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'oor \\'n paar sekondes',  'prefix');\n    assert.equal(moment(0).from(30000), '\\'n paar sekondes gelede', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), '\\'n paar sekondes gelede',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'oor \\'n paar sekondes', 'in a few seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), 'oor 5 dae', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'Vandag om 12:00',     'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'Vandag om 12:25',     'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'Vandag om 13:00',     'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'Môre om 12:00',       'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'Vandag om 11:00',     'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'Gister om 12:00',     'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('dddd [om] LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd [om] LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd [om] LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('[Laas] dddd [om] LT'),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[Laas] dddd [om] LT'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[Laas] dddd [om] LT'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2012, 0,  1]).format('w ww wo'), '52 52 52ste', 'Jan  1 2012 should be week 52');\n    assert.equal(moment([2012, 0,  2]).format('w ww wo'),   '1 01 1ste', 'Jan  2 2012 should be week 1');\n    assert.equal(moment([2012, 0,  8]).format('w ww wo'),   '1 01 1ste', 'Jan  8 2012 should be week 1');\n    assert.equal(moment([2012, 0,  9]).format('w ww wo'),    '2 02 2de', 'Jan  9 2012 should be week 2');\n    assert.equal(moment([2012, 0, 15]).format('w ww wo'),    '2 02 2de', 'Jan 15 2012 should be week 2');\n});\n\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/test/locale/ar-dz.js",
    "content": "import {localeModule, test} from '../qunit';\nimport moment from '../../moment';\nlocaleModule('ar-dz');\n\ntest('parse', function (assert) {\n    var tests = 'جانفي:جانفي_فيفري:فيفري_مارس:مارس_أفريل:أفريل_ماي:ماي_جوان:جوان_جويلية:جويلية_أوت:أوت_سبتمبر:سبتمبر_أكتوبر:أكتوبر_نوفمبر:نوفمبر_ديسمبر:ديسمبر'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(':');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, MMMM Do YYYY, h:mm:ss a',      'الأحد, فيفري 14 2010, 3:25:50 pm'],\n            ['ddd, hA',                            'احد, 3PM'],\n            ['M Mo MM MMMM MMM',                   '2 2 02 فيفري فيفري'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14 14'],\n            ['d do dddd ddd dd',                   '0 0 الأحد احد أح'],\n            ['DDD DDDo DDDD',                      '45 45 045'],\n            ['w wo ww',                            '7 7 07'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'pm PM'],\n            ['[the] DDDo [day of the year]',       'the 45 day of the year'],\n            ['LT',                                 '15:25'],\n            ['LTS',                                '15:25:50'],\n            ['L',                                  '14/02/2010'],\n            ['LL',                                 '14 فيفري 2010'],\n            ['LLL',                                '14 فيفري 2010 15:25'],\n            ['LLLL',                               'الأحد 14 فيفري 2010 15:25'],\n            ['l',                                  '14/2/2010'],\n            ['ll',                                 '14 فيفري 2010'],\n            ['lll',                                '14 فيفري 2010 15:25'],\n            ['llll',                               'احد 14 فيفري 2010 15:25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1', '1');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2', '2');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3', '3');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4', '4');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5', '5');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6', '6');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7', '7');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8', '8');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9', '9');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10', '10');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11', '11');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12', '12');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13', '13');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14', '14');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15', '15');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16', '16');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17', '17');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18', '18');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19', '19');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20', '20');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21', '21');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22', '22');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23', '23');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24', '24');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25', '25');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26', '26');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27', '27');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28', '28');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29', '29');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30', '30');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31', '31');\n});\n\ntest('format month', function (assert) {\n    var expected = 'جانفي جانفي_فيفري فيفري_مارس مارس_أفريل أفريل_ماي ماي_جوان جوان_جويلية جويلية_أوت أوت_سبتمبر سبتمبر_أكتوبر أكتوبر_نوفمبر نوفمبر_ديسمبر ديسمبر'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'الأحد احد أح_الإثنين اثنين إث_الثلاثاء ثلاثاء ثلا_الأربعاء اربعاء أر_الخميس خميس خم_الجمعة جمعة جم_السبت سبت سب'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'ثوان', '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'دقيقة',      '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'دقيقة',      '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 دقائق',     '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 دقائق',    '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'ساعة',       '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'ساعة',       '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 ساعات',       '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 ساعات',       '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 ساعات',      '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'يوم',         '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'يوم',         '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 أيام',        '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'يوم',         '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 أيام',        '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 أيام',       '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'شهر',       '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'شهر',       '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'شهر',       '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 أشهر',      '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 أشهر',      '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 أشهر',      '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'شهر',       '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 أشهر',      '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'سنة',        '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 سنوات',       '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'سنة',        '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 سنوات',       '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'في ثوان',  'prefix');\n    assert.equal(moment(0).from(30000), 'منذ ثوان', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'منذ ثوان',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'في ثوان', 'in a few seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), 'في 5 أيام', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'اليوم على الساعة 12:00',     'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'اليوم على الساعة 12:25',     'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'اليوم على الساعة 13:00',     'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'غدا على الساعة 12:00',      'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'اليوم على الساعة 11:00',     'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'أمس على الساعة 12:00',     'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('dddd [على الساعة] LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd [على الساعة] LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd [على الساعة] LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('dddd [على الساعة] LT'),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd [على الساعة] LT'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd [على الساعة] LT'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2016, 1, 4]).format('w ww wo'), '5 05 5', 'Feb 4 2016 should be week 5');\n    assert.equal(moment([2016,  0,  6]).format('w ww wo'), '1 01 1', 'Jan  6 2016 should be week 1');\n    assert.equal(moment([2016,  0,  7]).format('w ww wo'), '1 01 1', 'Jan  7 2016 should be week 1');\n    assert.equal(moment([2016,  0, 13]).format('w ww wo'), '2 02 2', 'Jan 13 2016 should be week 2');\n    assert.equal(moment([2016,  0, 14]).format('w ww wo'), '2 02 2', 'Jan 14 2016 should be week 2');\n});\n\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/test/locale/ar-kw.js",
    "content": "import {localeModule, test} from '../qunit';\nimport moment from '../../moment';\nlocaleModule('ar-kw');\n\ntest('parse', function (assert) {\n    var tests = 'يناير:يناير_فبراير:فبراير_مارس:مارس_أبريل:أبريل_ماي:ماي_يونيو:يونيو_يوليوز:يوليوز_غشت:غشت_شتنبر:شتنبر_أكتوبر:أكتوبر_نونبر:نونبر_دجنبر:دجنبر'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(':');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, MMMM Do YYYY, h:mm:ss a',      'الأحد, فبراير 14 2010, 3:25:50 pm'],\n            ['ddd, hA',                            'احد, 3PM'],\n            ['M Mo MM MMMM MMM',                   '2 2 02 فبراير فبراير'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14 14'],\n            ['d do dddd ddd dd',                   '0 0 الأحد احد ح'],\n            ['DDD DDDo DDDD',                      '45 45 045'],\n            ['w wo ww',                            '9 9 09'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'pm PM'],\n            ['[the] DDDo [day of the year]',       'the 45 day of the year'],\n            ['LT',                                 '15:25'],\n            ['LTS',                                '15:25:50'],\n            ['L',                                  '14/02/2010'],\n            ['LL',                                 '14 فبراير 2010'],\n            ['LLL',                                '14 فبراير 2010 15:25'],\n            ['LLLL',                               'الأحد 14 فبراير 2010 15:25'],\n            ['l',                                  '14/2/2010'],\n            ['ll',                                 '14 فبراير 2010'],\n            ['lll',                                '14 فبراير 2010 15:25'],\n            ['llll',                               'احد 14 فبراير 2010 15:25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1', '1');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2', '2');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3', '3');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4', '4');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5', '5');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6', '6');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7', '7');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8', '8');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9', '9');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10', '10');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11', '11');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12', '12');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13', '13');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14', '14');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15', '15');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16', '16');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17', '17');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18', '18');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19', '19');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20', '20');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21', '21');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22', '22');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23', '23');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24', '24');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25', '25');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26', '26');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27', '27');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28', '28');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29', '29');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30', '30');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31', '31');\n});\n\ntest('format month', function (assert) {\n    var expected = 'يناير يناير_فبراير فبراير_مارس مارس_أبريل أبريل_ماي ماي_يونيو يونيو_يوليوز يوليوز_غشت غشت_شتنبر شتنبر_أكتوبر أكتوبر_نونبر نونبر_دجنبر دجنبر'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'الأحد احد ح_الإتنين اتنين ن_الثلاثاء ثلاثاء ث_الأربعاء اربعاء ر_الخميس خميس خ_الجمعة جمعة ج_السبت سبت س'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'ثوان', '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'دقيقة',      '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'دقيقة',      '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 دقائق',     '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 دقائق',    '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'ساعة',       '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'ساعة',       '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 ساعات',       '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 ساعات',       '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 ساعات',      '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'يوم',         '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'يوم',         '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 أيام',        '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'يوم',         '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 أيام',        '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 أيام',       '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'شهر',       '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'شهر',       '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'شهر',       '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 أشهر',      '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 أشهر',      '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 أشهر',      '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'شهر',       '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 أشهر',      '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'سنة',        '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 سنوات',       '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'سنة',        '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 سنوات',       '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'في ثوان',  'prefix');\n    assert.equal(moment(0).from(30000), 'منذ ثوان', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'منذ ثوان',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'في ثوان', 'in a few seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), 'في 5 أيام', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'اليوم على الساعة 12:00',     'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'اليوم على الساعة 12:25',     'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'اليوم على الساعة 13:00',     'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'غدا على الساعة 12:00',      'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'اليوم على الساعة 11:00',     'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'أمس على الساعة 12:00',     'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('dddd [على الساعة] LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd [على الساعة] LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd [على الساعة] LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('dddd [على الساعة] LT'),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd [على الساعة] LT'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd [على الساعة] LT'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2011, 11, 31]).format('w ww wo'), '1 01 1', 'Dec 31 2011 should be week 1');\n    assert.equal(moment([2012,  0,  1]).format('w ww wo'), '2 02 2', 'Jan  1 2012 should be week 2');\n    assert.equal(moment([2012,  0,  8]).format('w ww wo'), '3 03 3', 'Jan  8 2012 should be week 3');\n    assert.equal(moment([2012,  0, 14]).format('w ww wo'), '3 03 3', 'Jan 14 2012 should be week 3');\n    assert.equal(moment([2012,  0, 15]).format('w ww wo'), '4 04 4', 'Jan 15 2012 should be week 4');\n});\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/test/locale/ar-ly.js",
    "content": "import {localeModule, test} from '../qunit';\nimport moment from '../../moment';\nlocaleModule('ar-ly');\n\nvar months = [\n    'يناير',\n    'فبراير',\n    'مارس',\n    'أبريل',\n    'مايو',\n    'يونيو',\n    'يوليو',\n    'أغسطس',\n    'سبتمبر',\n    'أكتوبر',\n    'نوفمبر',\n    'ديسمبر'\n];\n\ntest('parse', function (assert) {\n    var tests = months, i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1) + ' instead is month ' + moment(input, mmm).month());\n    }\n    for (i = 0; i < 12; i++) {\n        equalTest(tests[i], 'MMM', i);\n        equalTest(tests[i], 'MMM', i);\n        equalTest(tests[i], 'MMMM', i);\n        equalTest(tests[i], 'MMMM', i);\n        equalTest(tests[i].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, MMMM Do YYYY, h:mm:ss a',      'الأحد، فبراير 14 2010، 3:25:50 م'],\n            ['ddd, hA',                            'أحد، 3م'],\n            ['M Mo MM MMMM MMM',                   '2 2 02 فبراير فبراير'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14 14'],\n            ['d do dddd ddd dd',                   '0 0 الأحد أحد ح'],\n            ['DDD DDDo DDDD',                      '45 45 045'],\n            ['w wo ww',                            '8 8 08'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'م م'],\n            ['[the] DDDo [day of the year]',       'the 45 day of the year'],\n            ['LT',                                 '15:25'],\n            ['LTS',                                '15:25:50'],\n            ['L',                                  '14/\\u200f2/\\u200f2010'],\n            ['LL',                                 '14 فبراير 2010'],\n            ['LLL',                                '14 فبراير 2010 15:25'],\n            ['LLLL',                               'الأحد 14 فبراير 2010 15:25'],\n            ['l',                                  '14/\\u200f2/\\u200f2010'],\n            ['ll',                                 '14 فبراير 2010'],\n            ['lll',                                '14 فبراير 2010 15:25'],\n            ['llll',                               'أحد 14 فبراير 2010 15:25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1', '1');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2', '2');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3', '3');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4', '4');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5', '5');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6', '6');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7', '7');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8', '8');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9', '9');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10', '10');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11', '11');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12', '12');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13', '13');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14', '14');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15', '15');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16', '16');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17', '17');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18', '18');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19', '19');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20', '20');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21', '21');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22', '22');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23', '23');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24', '24');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25', '25');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26', '26');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27', '27');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28', '28');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29', '29');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30', '30');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31', '31');\n});\n\ntest('format month', function (assert) {\n    var expected = months, i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM'), expected[i], expected[i]);\n        assert.equal(moment([2011, i, 1]).format('MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'الأحد أحد ح_الإثنين إثنين ن_الثلاثاء ثلاثاء ث_الأربعاء أربعاء ر_الخميس خميس خ_الجمعة جمعة ج_السبت سبت س'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  '44 ثانية', '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'دقيقة واحدة',      '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'دقيقة واحدة',      '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  'دقيقتان',     '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 دقيقة',    '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'ساعة واحدة',       '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'ساعة واحدة',       '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  'ساعتان',       '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 ساعات',       '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 ساعة',      '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'يوم واحد',         '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'يوم واحد',         '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  'يومان',        '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'يوم واحد',         '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 أيام',        '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 يومًا',       '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'شهر واحد',       '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'شهر واحد',       '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'شهر واحد',       '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  'شهران',      '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  'شهران',      '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 أشهر',      '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'شهر واحد',       '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 أشهر',      '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'عام واحد',        '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), 'عامان',       '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'عام واحد',        '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 أعوام',       '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'بعد 30 ثانية',  'prefix');\n    assert.equal(moment(0).from(30000), 'منذ 30 ثانية', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'منذ ثانية واحدة',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'بعد 30 ثانية', 'in a few seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), 'بعد 5 أيام', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'اليوم عند الساعة 12:00',     'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'اليوم عند الساعة 12:25',     'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'اليوم عند الساعة 13:00',     'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'غدًا عند الساعة 12:00',      'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'اليوم عند الساعة 11:00',     'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'أمس عند الساعة 12:00',       'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('dddd [عند الساعة] LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd [عند الساعة] LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd [عند الساعة] LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('dddd [عند الساعة] LT'),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd [عند الساعة] LT'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd [عند الساعة] LT'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('weeks year starting wednesday custom', function (assert) {\n    assert.equal(moment('2003 1 6', 'gggg w d').format('YYYY-MM-DD'), '2002-12-28', 'Week 1 of 2003 should be Dec 28 2002');\n    assert.equal(moment('2003 1 0', 'gggg w e').format('YYYY-MM-DD'), '2002-12-28', 'Week 1 of 2003 should be Dec 28 2002');\n    assert.equal(moment('2003 1 6', 'gggg w d').format('gggg w d'), '2003 1 6', 'Saturday of week 1 of 2003 parsed should be formatted as 2003 1 6');\n    assert.equal(moment('2003 1 0', 'gggg w e').format('gggg w e'), '2003 1 0', '1st day of week 1 of 2003 parsed should be formatted as 2003 1 0');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2011, 11, 31]).format('w ww wo'), '1 01 1', 'Dec 31 2011 should be week 1');\n    assert.equal(moment([2012,  0,  6]).format('w ww wo'), '1 01 1', 'Jan  6 2012 should be week 1');\n    assert.equal(moment([2012,  0,  7]).format('w ww wo'), '2 02 2', 'Jan  7 2012 should be week 2');\n    assert.equal(moment([2012,  0, 13]).format('w ww wo'), '2 02 2', 'Jan 13 2012 should be week 2');\n    assert.equal(moment([2012,  0, 14]).format('w ww wo'), '3 03 3', 'Jan 14 2012 should be week 3');\n});\n\ntest('no leading zeros in long date formats', function (assert) {\n    var i, j, longDateStr, shortDateStr;\n    for (i = 1; i <= 9; ++i) {\n        for (j = 1; j <= 9; ++j) {\n            longDateStr = moment([2014, i, j]).format('L');\n            shortDateStr = moment([2014, i, j]).format('l');\n            assert.equal(longDateStr, shortDateStr, 'should not have leading zeros in month or day');\n        }\n    }\n});\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/test/locale/ar-ma.js",
    "content": "import {localeModule, test} from '../qunit';\nimport moment from '../../moment';\nlocaleModule('ar-ma');\n\ntest('parse', function (assert) {\n    var tests = 'يناير:يناير_فبراير:فبراير_مارس:مارس_أبريل:أبريل_ماي:ماي_يونيو:يونيو_يوليوز:يوليوز_غشت:غشت_شتنبر:شتنبر_أكتوبر:أكتوبر_نونبر:نونبر_دجنبر:دجنبر'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(':');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, MMMM Do YYYY, h:mm:ss a',      'الأحد, فبراير 14 2010, 3:25:50 pm'],\n            ['ddd, hA',                            'احد, 3PM'],\n            ['M Mo MM MMMM MMM',                   '2 2 02 فبراير فبراير'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14 14'],\n            ['d do dddd ddd dd',                   '0 0 الأحد احد ح'],\n            ['DDD DDDo DDDD',                      '45 45 045'],\n            ['w wo ww',                            '8 8 08'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'pm PM'],\n            ['[the] DDDo [day of the year]',       'the 45 day of the year'],\n            ['LT',                                 '15:25'],\n            ['LTS',                                '15:25:50'],\n            ['L',                                  '14/02/2010'],\n            ['LL',                                 '14 فبراير 2010'],\n            ['LLL',                                '14 فبراير 2010 15:25'],\n            ['LLLL',                               'الأحد 14 فبراير 2010 15:25'],\n            ['l',                                  '14/2/2010'],\n            ['ll',                                 '14 فبراير 2010'],\n            ['lll',                                '14 فبراير 2010 15:25'],\n            ['llll',                               'احد 14 فبراير 2010 15:25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1', '1');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2', '2');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3', '3');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4', '4');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5', '5');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6', '6');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7', '7');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8', '8');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9', '9');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10', '10');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11', '11');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12', '12');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13', '13');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14', '14');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15', '15');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16', '16');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17', '17');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18', '18');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19', '19');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20', '20');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21', '21');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22', '22');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23', '23');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24', '24');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25', '25');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26', '26');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27', '27');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28', '28');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29', '29');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30', '30');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31', '31');\n});\n\ntest('format month', function (assert) {\n    var expected = 'يناير يناير_فبراير فبراير_مارس مارس_أبريل أبريل_ماي ماي_يونيو يونيو_يوليوز يوليوز_غشت غشت_شتنبر شتنبر_أكتوبر أكتوبر_نونبر نونبر_دجنبر دجنبر'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'الأحد احد ح_الإتنين اتنين ن_الثلاثاء ثلاثاء ث_الأربعاء اربعاء ر_الخميس خميس خ_الجمعة جمعة ج_السبت سبت س'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'ثوان', '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'دقيقة',      '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'دقيقة',      '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 دقائق',     '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 دقائق',    '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'ساعة',       '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'ساعة',       '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 ساعات',       '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 ساعات',       '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 ساعات',      '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'يوم',         '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'يوم',         '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 أيام',        '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'يوم',         '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 أيام',        '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 أيام',       '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'شهر',       '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'شهر',       '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'شهر',       '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 أشهر',      '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 أشهر',      '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 أشهر',      '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'شهر',       '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 أشهر',      '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'سنة',        '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 سنوات',       '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'سنة',        '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 سنوات',       '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'في ثوان',  'prefix');\n    assert.equal(moment(0).from(30000), 'منذ ثوان', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'منذ ثوان',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'في ثوان', 'in a few seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), 'في 5 أيام', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'اليوم على الساعة 12:00',     'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'اليوم على الساعة 12:25',     'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'اليوم على الساعة 13:00',     'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'غدا على الساعة 12:00',      'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'اليوم على الساعة 11:00',     'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'أمس على الساعة 12:00',     'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('dddd [على الساعة] LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd [على الساعة] LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd [على الساعة] LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('dddd [على الساعة] LT'),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd [على الساعة] LT'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd [على الساعة] LT'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2011, 11, 31]).format('w ww wo'), '1 01 1', 'Dec 31 2011 should be week 1');\n    assert.equal(moment([2012,  0,  6]).format('w ww wo'), '1 01 1', 'Jan  6 2012 should be week 1');\n    assert.equal(moment([2012,  0,  7]).format('w ww wo'), '2 02 2', 'Jan  7 2012 should be week 2');\n    assert.equal(moment([2012,  0, 13]).format('w ww wo'), '2 02 2', 'Jan 13 2012 should be week 2');\n    assert.equal(moment([2012,  0, 14]).format('w ww wo'), '3 03 3', 'Jan 14 2012 should be week 3');\n});\n\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/test/locale/ar-sa.js",
    "content": "import {localeModule, test} from '../qunit';\nimport moment from '../../moment';\nlocaleModule('ar-sa');\n\ntest('parse', function (assert) {\n    var tests = 'يناير:يناير_فبراير:فبراير_مارس:مارس_أبريل:أبريل_مايو:مايو_يونيو:يونيو_يوليو:يوليو_أغسطس:أغسطس_سبتمبر:سبتمبر_أكتوبر:أكتوبر_نوفمبر:نوفمبر_ديسمبر:ديسمبر'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1) + ' instead is month ' + moment(input, mmm).month());\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(':');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, MMMM Do YYYY, h:mm:ss a',      'الأحد، فبراير ١٤ ٢٠١٠، ٣:٢٥:٥٠ م'],\n            ['ddd, hA',                            'أحد، ٣م'],\n            ['M Mo MM MMMM MMM',                   '٢ ٢ ٠٢ فبراير فبراير'],\n            ['YYYY YY',                            '٢٠١٠ ١٠'],\n            ['D Do DD',                            '١٤ ١٤ ١٤'],\n            ['d do dddd ddd dd',                   '٠ ٠ الأحد أحد ح'],\n            ['DDD DDDo DDDD',                      '٤٥ ٤٥ ٠٤٥'],\n            ['w wo ww',                            '٨ ٨ ٠٨'],\n            ['h hh',                               '٣ ٠٣'],\n            ['H HH',                               '١٥ ١٥'],\n            ['m mm',                               '٢٥ ٢٥'],\n            ['s ss',                               '٥٠ ٥٠'],\n            ['a A',                                'م م'],\n            ['[the] DDDo [day of the year]',       'the ٤٥ day of the year'],\n            ['LT',                                 '١٥:٢٥'],\n            ['LTS',                                '١٥:٢٥:٥٠'],\n            ['L',                                  '١٤/٠٢/٢٠١٠'],\n            ['LL',                                 '١٤ فبراير ٢٠١٠'],\n            ['LLL',                                '١٤ فبراير ٢٠١٠ ١٥:٢٥'],\n            ['LLLL',                               'الأحد ١٤ فبراير ٢٠١٠ ١٥:٢٥'],\n            ['l',                                  '١٤/٢/٢٠١٠'],\n            ['ll',                                 '١٤ فبراير ٢٠١٠'],\n            ['lll',                                '١٤ فبراير ٢٠١٠ ١٥:٢٥'],\n            ['llll',                               'أحد ١٤ فبراير ٢٠١٠ ١٥:٢٥']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '١', '1');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '٢', '2');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '٣', '3');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '٤', '4');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '٥', '5');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '٦', '6');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '٧', '7');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '٨', '8');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '٩', '9');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '١٠', '10');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '١١', '11');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '١٢', '12');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '١٣', '13');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '١٤', '14');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '١٥', '15');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '١٦', '16');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '١٧', '17');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '١٨', '18');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '١٩', '19');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '٢٠', '20');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '٢١', '21');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '٢٢', '22');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '٢٣', '23');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '٢٤', '24');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '٢٥', '25');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '٢٦', '26');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '٢٧', '27');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '٢٨', '28');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '٢٩', '29');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '٣٠', '30');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '٣١', '31');\n});\n\ntest('format month', function (assert) {\n    var expected = 'يناير يناير_فبراير فبراير_مارس مارس_أبريل أبريل_مايو مايو_يونيو يونيو_يوليو يوليو_أغسطس أغسطس_سبتمبر سبتمبر_أكتوبر أكتوبر_نوفمبر نوفمبر_ديسمبر ديسمبر'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'الأحد أحد ح_الإثنين إثنين ن_الثلاثاء ثلاثاء ث_الأربعاء أربعاء ر_الخميس خميس خ_الجمعة جمعة ج_السبت سبت س'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'ثوان', '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'دقيقة',      '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'دقيقة',      '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '٢ دقائق',     '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '٤٤ دقائق',    '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'ساعة',       '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'ساعة',       '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '٢ ساعات',       '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '٥ ساعات',       '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '٢١ ساعات',      '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'يوم',         '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'يوم',         '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '٢ أيام',        '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'يوم',         '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '٥ أيام',        '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '٢٥ أيام',       '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'شهر',       '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'شهر',       '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'شهر',       '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '٢ أشهر',      '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '٢ أشهر',      '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '٣ أشهر',      '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'شهر',       '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '٥ أشهر',      '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'سنة',        '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '٢ سنوات',       '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'سنة',        '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '٥ سنوات',       '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'في ثوان',  'prefix');\n    assert.equal(moment(0).from(30000), 'منذ ثوان', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'منذ ثوان',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'في ثوان', 'in a few seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), 'في ٥ أيام', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'اليوم على الساعة ١٢:٠٠',     'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'اليوم على الساعة ١٢:٢٥',     'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'اليوم على الساعة ١٣:٠٠',     'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'غدا على الساعة ١٢:٠٠',       'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'اليوم على الساعة ١١:٠٠',     'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'أمس على الساعة ١٢:٠٠',      'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('dddd [على الساعة] LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd [على الساعة] LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd [على الساعة] LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('dddd [على الساعة] LT'),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd [على الساعة] LT'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd [على الساعة] LT'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('weeks year starting wednesday custom', function (assert) {\n    assert.equal(moment('2003 1 6', 'gggg w d').format('YYYY-MM-DD'), '٢٠٠٣-٠١-٠٤', '2003 1 6 : gggg w d');\n    assert.equal(moment('2003 1 0', 'gggg w e').format('YYYY-MM-DD'), '٢٠٠٢-١٢-٢٩', '2003 1 0 : gggg w e');\n    assert.equal(moment('2003 1 6', 'gggg w d').format('gggg w d'), '٢٠٠٣ ١ ٦', '2003 1 6 : gggg w d');\n    assert.equal(moment('2003 1 0', 'gggg w e').format('gggg w e'), '٢٠٠٣ ١ ٠', '2003 1 0 : gggg w e');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2011, 11, 31]).format('w ww wo'), '٥٣ ٥٣ ٥٣', '2011 11 31');\n    assert.equal(moment([2012,  0,  6]).format('w ww wo'), '١ ٠١ ١', '2012 0 6');\n    assert.equal(moment([2012,  0,  7]).format('w ww wo'), '١ ٠١ ١', '2012 0 7');\n    assert.equal(moment([2012,  0, 13]).format('w ww wo'), '٢ ٠٢ ٢', '2012 0 13');\n    assert.equal(moment([2012,  0, 14]).format('w ww wo'), '٢ ٠٢ ٢', '2012 0 14');\n});\n\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/test/locale/ar-tn.js",
    "content": "import {localeModule, test} from '../qunit';\nimport moment from '../../moment';\nlocaleModule('ar-tn');\n\ntest('parse', function (assert) {\n    var tests = 'جانفي:جانفي_فيفري:فيفري_مارس:مارس_أفريل:أفريل_ماي:ماي_جوان:جوان_جويلية:جويلية_أوت:أوت_سبتمبر:سبتمبر_أكتوبر:أكتوبر_نوفمبر:نوفمبر_ديسمبر:ديسمبر'.split('_'),\n        i;\n\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(':');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, MMMM Do YYYY, h:mm:ss a', 'الأحد, فيفري 14 2010, 3:25:50 pm'],\n            ['ddd, hA', 'أحد, 3PM'],\n            ['M Mo MM MMMM MMM', '2 2 02 فيفري فيفري'],\n            ['YYYY YY', '2010 10'],\n            ['D Do DD', '14 14 14'],\n            ['d do dddd ddd dd', '0 0 الأحد أحد ح'],\n            ['DDD DDDo DDDD', '45 45 045'],\n            ['w wo ww', '6 6 06'],\n            ['h hh', '3 03'],\n            ['H HH', '15 15'],\n            ['m mm', '25 25'],\n            ['s ss', '50 50'],\n            ['a A', 'pm PM'],\n            ['[the] DDDo [day of the year]', 'the 45 day of the year'],\n            ['LT', '15:25'],\n            ['LTS', '15:25:50'],\n            ['L', '14/02/2010'],\n            ['LL', '14 فيفري 2010'],\n            ['LLL', '14 فيفري 2010 15:25'],\n            ['LLLL', 'الأحد 14 فيفري 2010 15:25'],\n            ['l', '14/2/2010'],\n            ['ll', '14 فيفري 2010'],\n            ['lll', '14 فيفري 2010 15:25'],\n            ['llll', 'أحد 14 فيفري 2010 15:25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1', '1');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2', '2');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3', '3');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4', '4');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5', '5');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6', '6');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7', '7');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8', '8');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9', '9');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10', '10');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11', '11');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12', '12');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13', '13');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14', '14');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15', '15');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16', '16');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17', '17');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18', '18');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19', '19');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20', '20');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21', '21');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22', '22');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23', '23');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24', '24');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25', '25');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26', '26');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27', '27');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28', '28');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29', '29');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30', '30');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31', '31');\n});\n\ntest('format month', function (assert) {\n    var expected = 'جانفي جانفي_فيفري فيفري_مارس مارس_أفريل أفريل_ماي ماي_جوان جوان_جويلية جويلية_أوت أوت_سبتمبر سبتمبر_أكتوبر أكتوبر_نوفمبر نوفمبر_ديسمبر ديسمبر'.split('_'),\n        i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'الأحد أحد ح_الإثنين إثنين ن_الثلاثاء ثلاثاء ث_الأربعاء أربعاء ر_الخميس خميس خ_الجمعة جمعة ج_السبت سبت س'.split('_'),\n        i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({\n        s: 44\n    }), true), 'ثوان', '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({\n        s: 45\n    }), true), 'دقيقة', '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({\n        s: 89\n    }), true), 'دقيقة', '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({\n        s: 90\n    }), true), '2 دقائق', '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({\n        m: 44\n    }), true), '44 دقائق', '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({\n        m: 45\n    }), true), 'ساعة', '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({\n        m: 89\n    }), true), 'ساعة', '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({\n        m: 90\n    }), true), '2 ساعات', '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({\n        h: 5\n    }), true), '5 ساعات', '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({\n        h: 21\n    }), true), '21 ساعات', '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({\n        h: 22\n    }), true), 'يوم', '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({\n        h: 35\n    }), true), 'يوم', '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({\n        h: 36\n    }), true), '2 أيام', '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({\n        d: 1\n    }), true), 'يوم', '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({\n        d: 5\n    }), true), '5 أيام', '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({\n        d: 25\n    }), true), '25 أيام', '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({\n        d: 26\n    }), true), 'شهر', '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({\n        d: 30\n    }), true), 'شهر', '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({\n        d: 43\n    }), true), 'شهر', '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({\n        d: 46\n    }), true), '2 أشهر', '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({\n        d: 74\n    }), true), '2 أشهر', '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({\n        d: 76\n    }), true), '3 أشهر', '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({\n        M: 1\n    }), true), 'شهر', '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({\n        M: 5\n    }), true), '5 أشهر', '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({\n        d: 345\n    }), true), 'سنة', '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({\n        d: 548\n    }), true), '2 سنوات', '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({\n        y: 1\n    }), true), 'سنة', '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({\n        y: 5\n    }), true), '5 سنوات', '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'في ثوان', 'prefix');\n    assert.equal(moment(0).from(30000), 'منذ ثوان', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'منذ ثوان', 'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({\n        s: 30\n    }).fromNow(), 'في ثوان', 'in a few seconds');\n    assert.equal(moment().add({\n        d: 5\n    }).fromNow(), 'في 5 أيام', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                  'اليوم على الساعة 12:00', 'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),     'اليوم على الساعة 12:25', 'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),      'اليوم على الساعة 13:00', 'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),      'غدا على الساعة 12:00',  'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(), 'اليوم على الساعة 11:00', 'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(), 'أمس على الساعة 12:00',  'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({\n            d: i\n        });\n        assert.equal(m.calendar(), m.format('dddd [على الساعة] LT'), 'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(), m.format('dddd [على الساعة] LT'), 'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(), m.format('dddd [على الساعة] LT'), 'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({\n            d: i\n        });\n        assert.equal(m.calendar(), m.format('dddd [على الساعة] LT'), 'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(), m.format('dddd [على الساعة] LT'), 'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(), m.format('dddd [على الساعة] LT'), 'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({\n            w: 1\n        }),\n        weeksFromNow = moment().add({\n            w: 1\n        });\n\n    assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '1 week ago');\n    assert.equal(weeksFromNow.calendar(), weeksFromNow.format('L'), 'in 1 week');\n\n    weeksAgo = moment().subtract({\n        w: 2\n    });\n    weeksFromNow = moment().add({\n        w: 2\n    });\n\n    assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(), weeksFromNow.format('L'), 'in 2 weeks');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2012, 0,  1]).format('w ww wo'), '52 52 52', 'Jan  1 2012 should be week 52');\n    assert.equal(moment([2012, 0,  2]).format('w ww wo'), '1 01 1', 'Jan  2 2012 should be week 1');\n    assert.equal(moment([2012, 0,  8]).format('w ww wo'), '1 01 1', 'Jan  8 2012 should be week 1');\n    assert.equal(moment([2012, 0,  9]).format('w ww wo'),   '2 02 2', 'Jan  9 2012 should be week 2');\n    assert.equal(moment([2012, 0, 15]).format('w ww wo'),   '2 02 2', 'Jan 15 2012 should be week 2');\n});\n\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/test/locale/ar.js",
    "content": "import {localeModule, test} from '../qunit';\nimport moment from '../../moment';\nlocaleModule('ar');\n\nvar months = [\n    'كانون الثاني يناير',\n    'شباط فبراير',\n    'آذار مارس',\n    'نيسان أبريل',\n    'أيار مايو',\n    'حزيران يونيو',\n    'تموز يوليو',\n    'آب أغسطس',\n    'أيلول سبتمبر',\n    'تشرين الأول أكتوبر',\n    'تشرين الثاني نوفمبر',\n    'كانون الأول ديسمبر'\n];\n\ntest('parse', function (assert) {\n    var tests = months, i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1) + ' instead is month ' + moment(input, mmm).month());\n    }\n    for (i = 0; i < 12; i++) {\n        equalTest(tests[i], 'MMM', i);\n        equalTest(tests[i], 'MMM', i);\n        equalTest(tests[i], 'MMMM', i);\n        equalTest(tests[i], 'MMMM', i);\n        equalTest(tests[i].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, MMMM Do YYYY, h:mm:ss a',      'الأحد، شباط فبراير ١٤ ٢٠١٠، ٣:٢٥:٥٠ م'],\n            ['ddd, hA',                            'أحد، ٣م'],\n            ['M Mo MM MMMM MMM',                   '٢ ٢ ٠٢ شباط فبراير شباط فبراير'],\n            ['YYYY YY',                            '٢٠١٠ ١٠'],\n            ['D Do DD',                            '١٤ ١٤ ١٤'],\n            ['d do dddd ddd dd',                   '٠ ٠ الأحد أحد ح'],\n            ['DDD DDDo DDDD',                      '٤٥ ٤٥ ٠٤٥'],\n            ['w wo ww',                            '٨ ٨ ٠٨'],\n            ['h hh',                               '٣ ٠٣'],\n            ['H HH',                               '١٥ ١٥'],\n            ['m mm',                               '٢٥ ٢٥'],\n            ['s ss',                               '٥٠ ٥٠'],\n            ['a A',                                'م م'],\n            ['[the] DDDo [day of the year]',       'the ٤٥ day of the year'],\n            ['LT',                                 '١٥:٢٥'],\n            ['LTS',                                '١٥:٢٥:٥٠'],\n            ['L',                                  '١٤/\\u200f٢/\\u200f٢٠١٠'],\n            ['LL',                                 '١٤ شباط فبراير ٢٠١٠'],\n            ['LLL',                                '١٤ شباط فبراير ٢٠١٠ ١٥:٢٥'],\n            ['LLLL',                               'الأحد ١٤ شباط فبراير ٢٠١٠ ١٥:٢٥'],\n            ['l',                                  '١٤/\\u200f٢/\\u200f٢٠١٠'],\n            ['ll',                                 '١٤ شباط فبراير ٢٠١٠'],\n            ['lll',                                '١٤ شباط فبراير ٢٠١٠ ١٥:٢٥'],\n            ['llll',                               'أحد ١٤ شباط فبراير ٢٠١٠ ١٥:٢٥']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '١', '1');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '٢', '2');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '٣', '3');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '٤', '4');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '٥', '5');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '٦', '6');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '٧', '7');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '٨', '8');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '٩', '9');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '١٠', '10');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '١١', '11');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '١٢', '12');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '١٣', '13');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '١٤', '14');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '١٥', '15');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '١٦', '16');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '١٧', '17');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '١٨', '18');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '١٩', '19');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '٢٠', '20');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '٢١', '21');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '٢٢', '22');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '٢٣', '23');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '٢٤', '24');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '٢٥', '25');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '٢٦', '26');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '٢٧', '27');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '٢٨', '28');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '٢٩', '29');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '٣٠', '30');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '٣١', '31');\n});\n\ntest('format month', function (assert) {\n    var expected = months, i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM'), expected[i], expected[i]);\n        assert.equal(moment([2011, i, 1]).format('MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'الأحد أحد ح_الإثنين إثنين ن_الثلاثاء ثلاثاء ث_الأربعاء أربعاء ر_الخميس خميس خ_الجمعة جمعة ج_السبت سبت س'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  '٤٤ ثانية', '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'دقيقة واحدة',      '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'دقيقة واحدة',      '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  'دقيقتان',     '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '٤٤ دقيقة',    '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'ساعة واحدة',       '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'ساعة واحدة',       '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  'ساعتان',       '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '٥ ساعات',       '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '٢١ ساعة',      '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'يوم واحد',         '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'يوم واحد',         '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  'يومان',        '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'يوم واحد',         '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '٥ أيام',        '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '٢٥ يومًا',       '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'شهر واحد',       '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'شهر واحد',       '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'شهر واحد',       '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  'شهران',      '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  'شهران',      '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '٣ أشهر',      '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'شهر واحد',       '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '٥ أشهر',      '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'عام واحد',        '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), 'عامان',       '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'عام واحد',        '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '٥ أعوام',       '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'بعد ٣٠ ثانية',  'prefix');\n    assert.equal(moment(0).from(30000), 'منذ ٣٠ ثانية', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'منذ ثانية واحدة',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'بعد ٣٠ ثانية', 'in a few seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), 'بعد ٥ أيام', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'اليوم عند الساعة ١٢:٠٠',     'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'اليوم عند الساعة ١٢:٢٥',     'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'اليوم عند الساعة ١٣:٠٠',     'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'غدًا عند الساعة ١٢:٠٠',      'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'اليوم عند الساعة ١١:٠٠',     'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'أمس عند الساعة ١٢:٠٠',       'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('dddd [عند الساعة] LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd [عند الساعة] LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd [عند الساعة] LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('dddd [عند الساعة] LT'),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd [عند الساعة] LT'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd [عند الساعة] LT'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('weeks year starting wednesday custom', function (assert) {\n    assert.equal(moment('2003 1 6', 'gggg w d').format('YYYY-MM-DD'), '٢٠٠٢-١٢-٢٨', 'Week 1 of 2003 should be Dec 28 2002');\n    assert.equal(moment('2003 1 0', 'gggg w e').format('YYYY-MM-DD'), '٢٠٠٢-١٢-٢٨', 'Week 1 of 2003 should be Dec 28 2002');\n    assert.equal(moment('2003 1 6', 'gggg w d').format('gggg w d'), '٢٠٠٣ ١ ٦', 'Saturday of week 1 of 2003 parsed should be formatted as 2003 1 6');\n    assert.equal(moment('2003 1 0', 'gggg w e').format('gggg w e'), '٢٠٠٣ ١ ٠', '1st day of week 1 of 2003 parsed should be formatted as 2003 1 0');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2011, 11, 31]).format('w ww wo'), '١ ٠١ ١', 'Dec 31 2011 should be week 1');\n    assert.equal(moment([2012,  0,  6]).format('w ww wo'), '١ ٠١ ١', 'Jan  6 2012 should be week 1');\n    assert.equal(moment([2012,  0,  7]).format('w ww wo'), '٢ ٠٢ ٢', 'Jan  7 2012 should be week 2');\n    assert.equal(moment([2012,  0, 13]).format('w ww wo'), '٢ ٠٢ ٢', 'Jan 13 2012 should be week 2');\n    assert.equal(moment([2012,  0, 14]).format('w ww wo'), '٣ ٠٣ ٣', 'Jan 14 2012 should be week 3');\n});\n\ntest('no leading zeros in long date formats', function (assert) {\n    var i, j, longDateStr, shortDateStr;\n    for (i = 1; i <= 9; ++i) {\n        for (j = 1; j <= 9; ++j) {\n            longDateStr = moment([2014, i, j]).format('L');\n            shortDateStr = moment([2014, i, j]).format('l');\n            assert.equal(longDateStr, shortDateStr, 'should not have leading zeros in month or day');\n        }\n    }\n});\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/test/locale/az.js",
    "content": "import {localeModule, test} from '../qunit';\nimport moment from '../../moment';\nlocaleModule('az');\n\ntest('parse', function (assert) {\n    var tests = 'yanvar yan_fevral fev_mart mar_Aprel apr_may may_iyun iyn_iyul iyl_Avqust avq_sentyabr sen_oktyabr okt_noyabr noy_dekabr dek'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, D MMMM YYYY, HH:mm:ss',        'Bazar, 14 fevral 2010, 15:25:50'],\n            ['ddd, A h',                           'Baz, gündüz 3'],\n            ['M Mo MM MMMM MMM',                   '2 2-nci 02 fevral fev'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14-üncü 14'],\n            ['d do dddd ddd dd',                   '0 0-ıncı Bazar Baz Bz'],\n            ['DDD DDDo DDDD',                      '45 45-inci 045'],\n            ['w wo ww',                            '7 7-nci 07'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'gündüz gündüz'],\n            ['[ilin] DDDo [günü]',                 'ilin 45-inci günü'],\n            ['LT',                                 '15:25'],\n            ['LTS',                                '15:25:50'],\n            ['L',                                  '14.02.2010'],\n            ['LL',                                 '14 fevral 2010'],\n            ['LLL',                                '14 fevral 2010 15:25'],\n            ['LLLL',                               'Bazar, 14 fevral 2010 15:25'],\n            ['l',                                  '14.2.2010'],\n            ['ll',                                 '14 fev 2010'],\n            ['lll',                                '14 fev 2010 15:25'],\n            ['llll',                               'Baz, 14 fev 2010 15:25']\n        ],\n        DDDo = [\n            [359, '360-ıncı'],\n            [199, '200-üncü'],\n            [149, '150-nci']\n        ],\n        dt = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        DDDoDt,\n        i;\n\n    for (i = 0; i < a.length; i++) {\n        assert.equal(dt.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n    for (i = 0; i < DDDo.length; i++) {\n        DDDoDt = moment([2010]);\n        assert.equal(DDDoDt.add(DDDo[i][0], 'days').format('DDDo'), DDDo[i][1], DDDo[i][0] + ' ---> ' + DDDo[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1-inci', '1st');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2-nci', '2nd');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3-üncü', '3rd');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4-üncü', '4th');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5-inci', '5th');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6-ncı', '6th');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7-nci', '7th');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8-inci', '8th');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9-uncu', '9th');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10-uncu', '10th');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11-inci', '11th');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12-nci', '12th');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13-üncü', '13th');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14-üncü', '14th');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15-inci', '15th');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16-ncı', '16th');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17-nci', '17th');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18-inci', '18th');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19-uncu', '19th');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20-nci', '20th');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21-inci', '21th');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22-nci', '22th');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23-üncü', '23th');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24-üncü', '24th');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25-inci', '25th');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26-ncı', '26th');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27-nci', '27th');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28-inci', '28th');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29-uncu', '29th');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30-uncu', '30th');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31-inci', '31st');\n});\n\ntest('format month', function (assert) {\n    var expected = 'yanvar yan_fevral fev_mart mar_aprel apr_may may_iyun iyn_iyul iyl_avqust avq_sentyabr sen_oktyabr okt_noyabr noy_dekabr dek'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'Bazar Baz Bz_Bazar ertəsi BzE BE_Çərşənbə axşamı ÇAx ÇA_Çərşənbə Çər Çə_Cümə axşamı CAx CA_Cümə Cüm Cü_Şənbə Şən Şə'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'birneçə saniyyə', '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'bir dəqiqə',      '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'bir dəqiqə',      '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 dəqiqə',     '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 dəqiqə',    '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'bir saat',       '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'bir saat',       '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 saat',       '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 saat',       '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 saat',      '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'bir gün',         '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'bir gün',         '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 gün',        '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'bir gün',         '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 gün',        '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 gün',       '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'bir ay',       '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'bir ay',       '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 ay',      '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 ay',      '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 ay',      '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'bir ay',       '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 ay',      '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'bir il',        '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 il',       '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'bir il',        '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 il',       '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'birneçə saniyyə sonra',  'prefix');\n    assert.equal(moment(0).from(30000), 'birneçə saniyyə əvvəl', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'birneçə saniyyə əvvəl',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'birneçə saniyyə sonra', 'in a few seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), '5 gün sonra', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'bugün saat 12:00',     'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'bugün saat 12:25',     'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'bugün saat 13:00',     'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'sabah saat 12:00',     'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'bugün saat 11:00',     'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'dünən 12:00',          'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('[gələn həftə] dddd [saat] LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[gələn həftə] dddd [saat] LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[gələn həftə] dddd [saat] LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('[keçən həftə] dddd [saat] LT'),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[keçən həftə] dddd [saat] LT'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[keçən həftə] dddd [saat] LT'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2011, 11, 26]).format('w ww wo'), '1 01 1-inci', 'Dec 26 2011 should be week 1');\n    assert.equal(moment([2012,  0,  1]).format('w ww wo'), '1 01 1-inci', 'Jan  1 2012 should be week 1');\n    assert.equal(moment([2012,  0,  2]).format('w ww wo'), '2 02 2-nci', 'Jan  2 2012 should be week 2');\n    assert.equal(moment([2012,  0,  8]).format('w ww wo'), '2 02 2-nci', 'Jan  8 2012 should be week 2');\n    assert.equal(moment([2012,  0,  9]).format('w ww wo'), '3 03 3-üncü', 'Jan  9 2012 should be week 3');\n});\n\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/test/locale/be.js",
    "content": "import {localeModule, test} from '../qunit';\nimport moment from '../../moment';\nlocaleModule('be');\n\ntest('parse', function (assert) {\n    var tests = 'студзень студ_люты лют_сакавік сак_красавік крас_травень трав_чэрвень чэрв_ліпень ліп_жнівень жнів_верасень вер_кастрычнік каст_лістапад ліст_снежань снеж'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, Do MMMM YYYY, HH:mm:ss',       'нядзеля, 14-га лютага 2010, 15:25:50'],\n            ['ddd, h A',                           'нд, 3 дня'],\n            ['M Mo MM MMMM MMM',                   '2 2-і 02 люты лют'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14-га 14'],\n            ['d do dddd ddd dd',                   '0 0-ы нядзеля нд нд'],\n            ['DDD DDDo DDDD',                      '45 45-ы 045'],\n            ['w wo ww',                            '7 7-ы 07'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'дня дня'],\n            ['DDDo [дзень года]',                   '45-ы дзень года'],\n            ['LT',                                 '15:25'],\n            ['LTS',                                '15:25:50'],\n            ['L',                                  '14.02.2010'],\n            ['LL',                                 '14 лютага 2010 г.'],\n            ['LLL',                                '14 лютага 2010 г., 15:25'],\n            ['LLLL',                               'нядзеля, 14 лютага 2010 г., 15:25'],\n            ['l',                                  '14.2.2010'],\n            ['ll',                                 '14 лют 2010 г.'],\n            ['lll',                                '14 лют 2010 г., 15:25'],\n            ['llll',                               'нд, 14 лют 2010 г., 15:25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format meridiem', function (assert) {\n    assert.equal(moment([2012, 11, 28, 0, 0]).format('A'), 'ночы', 'night');\n    assert.equal(moment([2012, 11, 28, 3, 59]).format('A'), 'ночы', 'night');\n    assert.equal(moment([2012, 11, 28, 4, 0]).format('A'), 'раніцы', 'morning');\n    assert.equal(moment([2012, 11, 28, 11, 59]).format('A'), 'раніцы', 'morning');\n    assert.equal(moment([2012, 11, 28, 12, 0]).format('A'), 'дня', 'afternoon');\n    assert.equal(moment([2012, 11, 28, 16, 59]).format('A'), 'дня', 'afternoon');\n    assert.equal(moment([2012, 11, 28, 17, 0]).format('A'), 'вечара', 'evening');\n    assert.equal(moment([2012, 11, 28, 23, 59]).format('A'), 'вечара', 'evening');\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1-ы', '1-ы');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2-і', '2-і');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3-і', '3-і');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4-ы', '4-ы');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5-ы', '5-ы');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6-ы', '6-ы');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7-ы', '7-ы');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8-ы', '8-ы');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9-ы', '9-ы');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10-ы', '10-ы');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11-ы', '11-ы');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12-ы', '12-ы');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13-ы', '13-ы');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14-ы', '14-ы');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15-ы', '15-ы');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16-ы', '16-ы');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17-ы', '17-ы');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18-ы', '18-ы');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19-ы', '19-ы');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20-ы', '20-ы');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21-ы', '21-ы');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22-і', '22-і');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23-і', '23-і');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24-ы', '24-ы');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25-ы', '25-ы');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26-ы', '26-ы');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27-ы', '27-ы');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28-ы', '28-ы');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29-ы', '29-ы');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30-ы', '30-ы');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31-ы', '31-ы');\n});\n\ntest('format month', function (assert) {\n    var expected = 'студзень студ_люты лют_сакавік сак_красавік крас_травень трав_чэрвень чэрв_ліпень ліп_жнівень жнів_верасень вер_кастрычнік каст_лістапад ліст_снежань снеж'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format month case', function (assert) {\n    var months = {\n        'nominative': 'студзень_люты_сакавік_красавік_травень_чэрвень_ліпень_жнівень_верасень_кастрычнік_лістапад_снежань'.split('_'),\n        'accusative': 'студзеня_лютага_сакавіка_красавіка_траўня_чэрвеня_ліпеня_жніўня_верасня_кастрычніка_лістапада_снежня'.split('_')\n    }, i;\n    for (i = 0; i < 12; i++) {\n        assert.equal(moment([2011, i, 1]).format('D MMMM'), '1 ' + months.accusative[i], '1 ' + months.accusative[i]);\n        assert.equal(moment([2011, i, 1]).format('MMMM'), months.nominative[i], '1 ' + months.nominative[i]);\n    }\n});\n\ntest('format month case with escaped symbols', function (assert) {\n    var months = {\n        'nominative': 'студзень_люты_сакавік_красавік_травень_чэрвень_ліпень_жнівень_верасень_кастрычнік_лістапад_снежань'.split('_'),\n        'accusative': 'студзеня_лютага_сакавіка_красавіка_траўня_чэрвеня_ліпеня_жніўня_верасня_кастрычніка_лістапада_снежня'.split('_')\n    }, i;\n    for (i = 0; i < 12; i++) {\n        assert.equal(moment([2013, i, 1]).format('D[] MMMM'), '1 ' + months.accusative[i], '1 ' + months.accusative[i]);\n        assert.equal(moment([2013, i, 1]).format('[<i>]D[</i>] [<b>]MMMM[</b>]'), '<i>1</i> <b>' + months.accusative[i] + '</b>', '1 <b>' + months.accusative[i] + '</b>');\n        assert.equal(moment([2013, i, 1]).format('D[-ы дзень] MMMM'), '1-ы дзень ' + months.accusative[i], '1-ы дзень ' + months.accusative[i]);\n        assert.equal(moment([2013, i, 1]).format('D, MMMM'), '1, ' + months.nominative[i], '1, ' + months.nominative[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'нядзеля нд нд_панядзелак пн пн_аўторак ат ат_серада ср ср_чацвер чц чц_пятніца пт пт_субота сб сб'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'некалькі секунд',    '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'хвіліна',   '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'хвіліна',   '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 хвіліны',  '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 31}), true),  '31 хвіліна',  '31 minutes = 31 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 хвіліны', '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'гадзіна',    '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'гадзіна',    '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 гадзіны',    '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 гадзін',    '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 гадзіна',   '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'дзень',      '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'дзень',      '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 дні',     '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'дзень',      '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 дзён',     '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 11}), true),  '11 дзён',     '11 days = 11 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 21}), true),  '21 дзень',     '21 days = 21 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 дзён',    '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'месяц',    '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'месяц',    '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'месяц',    '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 месяцы',   '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 месяцы',   '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 месяцы',   '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'месяц',    '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 месяцаў',   '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'год',     '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 гады',    '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'год',     '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 гадоў',    '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'праз некалькі секунд', 'prefix');\n    assert.equal(moment(0).from(30000), 'некалькі секунд таму', 'suffix');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'праз некалькі секунд', 'in a few seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), 'праз 5 дзён', 'in 5 days');\n    assert.equal(moment().add({m: 31}).fromNow(), 'праз 31 хвіліну', 'in 31 minutes = in 31 minutes');\n    assert.equal(moment().subtract({m: 31}).fromNow(), '31 хвіліну таму', '31 minutes ago = 31 minutes ago');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'Сёння ў 12:00',     'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'Сёння ў 12:25',     'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'Сёння ў 13:00',     'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'Заўтра ў 12:00',    'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'Сёння ў 11:00',     'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'Учора ў 12:00',     'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    function makeFormat(d) {\n        return '[У] dddd [ў] LT';\n    }\n\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format(makeFormat(m)),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format(makeFormat(m)),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format(makeFormat(m)),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n\n    function makeFormat(d) {\n        switch (d.day()) {\n            case 0:\n            case 3:\n            case 5:\n            case 6:\n                return '[У мінулую] dddd [ў] LT';\n            case 1:\n            case 2:\n            case 4:\n                return '[У мінулы] dddd [ў] LT';\n        }\n    }\n\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format(makeFormat(m)),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format(makeFormat(m)),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format(makeFormat(m)),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2011, 11, 26]).format('w ww wo'), '1 01 1-ы', 'Dec 26 2011 should be week 1');\n    assert.equal(moment([2012,  0,  1]).format('w ww wo'), '1 01 1-ы', 'Jan  1 2012 should be week 1');\n    assert.equal(moment([2012,  0,  2]).format('w ww wo'), '2 02 2-і', 'Jan  2 2012 should be week 2');\n    assert.equal(moment([2012,  0,  8]).format('w ww wo'), '2 02 2-і', 'Jan  8 2012 should be week 2');\n    assert.equal(moment([2012,  0,  9]).format('w ww wo'), '3 03 3-і', 'Jan  9 2012 should be week 3');\n});\n\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/test/locale/bg.js",
    "content": "import {localeModule, test} from '../qunit';\nimport moment from '../../moment';\nlocaleModule('bg');\n\ntest('parse', function (assert) {\n    var tests = 'януари янр_февруари фев_март мар_април апр_май май_юни юни_юли юли_август авг_септември сеп_октомври окт_ноември ное_декември дек'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, MMMM Do YYYY, H:mm:ss',        'неделя, февруари 14-ти 2010, 15:25:50'],\n            ['ddd, hA',                            'нед, 3PM'],\n            ['M Mo MM MMMM MMM',                   '2 2-ри 02 февруари фев'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14-ти 14'],\n            ['d do dddd ddd dd',                   '0 0-ев неделя нед нд'],\n            ['DDD DDDo DDDD',                      '45 45-ти 045'],\n            ['w wo ww',                            '7 7-ми 07'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'pm PM'],\n            ['[the] DDDo [day of the year]',       'the 45-ти day of the year'],\n            ['LT',                                 '15:25'],\n            ['LTS',                                '15:25:50'],\n            ['L',                                  '14.02.2010'],\n            ['LL',                                 '14 февруари 2010'],\n            ['LLL',                                '14 февруари 2010 15:25'],\n            ['LLLL',                               'неделя, 14 февруари 2010 15:25'],\n            ['l',                                  '14.2.2010'],\n            ['ll',                                 '14 фев 2010'],\n            ['lll',                                '14 фев 2010 15:25'],\n            ['llll',                               'нед, 14 фев 2010 15:25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1-ви', '1-ви');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2-ри', '2-ри');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3-ти', '3-ти');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4-ти', '4-ти');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5-ти', '5-ти');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6-ти', '6-ти');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7-ми', '7-ми');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8-ми', '8-ми');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9-ти', '9-ти');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10-ти', '10-ти');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11-ти', '11-ти');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12-ти', '12-ти');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13-ти', '13-ти');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14-ти', '14-ти');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15-ти', '15-ти');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16-ти', '16-ти');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17-ти', '17-ти');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18-ти', '18-ти');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19-ти', '19-ти');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20-ти', '20-ти');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21-ви', '21-ви');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22-ри', '22-ри');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23-ти', '23-ти');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24-ти', '24-ти');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25-ти', '25-ти');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26-ти', '26-ти');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27-ми', '27-ми');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28-ми', '28-ми');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29-ти', '29-ти');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30-ти', '30-ти');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31-ви', '31-ви');\n});\n\ntest('format month', function (assert) {\n    var expected = 'януари янр_февруари фев_март мар_април апр_май май_юни юни_юли юли_август авг_септември сеп_октомври окт_ноември ное_декември дек'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'неделя нед нд_понеделник пон пн_вторник вто вт_сряда сря ср_четвъртък чет чт_петък пет пт_събота съб сб'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'няколко секунди', '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'минута',          '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'минута',          '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 минути',        '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 минути',       '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'час',             '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'час',             '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 часа',          '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 часа',          '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 часа',         '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'ден',             '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'ден',             '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 дни',           '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'ден',             '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 дни',           '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 дни',          '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'месец',           '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'месец',           '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'месец',           '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 месеца',        '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 месеца',        '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 месеца',        '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'месец',           '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 месеца',        '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'година',          '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 години',        '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'година',          '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 години',        '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'след няколко секунди',  'prefix');\n    assert.equal(moment(0).from(30000), 'преди няколко секунди', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'преди няколко секунди',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'след няколко секунди', 'in a few seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), 'след 5 дни', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'Днес в 12:00',  'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'Днес в 12:25',  'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'Днес в 13:00',  'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'Утре в 12:00',  'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'Днес в 11:00',  'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'Вчера в 12:00', 'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('dddd [в] LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd [в] LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd [в] LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n\n    function makeFormat(d) {\n        switch (d.day()) {\n            case 0:\n            case 3:\n            case 6:\n                return '[В изминалата] dddd [в] LT';\n            case 1:\n            case 2:\n            case 4:\n            case 5:\n                return '[В изминалия] dddd [в] LT';\n        }\n    }\n\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format(makeFormat(m)),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format(makeFormat(m)),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format(makeFormat(m)),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2011, 11, 26]).format('w ww wo'), '1 01 1-ви', 'Dec 26 2011 should be week 1');\n    assert.equal(moment([2012,  0,  1]).format('w ww wo'), '1 01 1-ви', 'Jan  1 2012 should be week 1');\n    assert.equal(moment([2012,  0,  2]).format('w ww wo'), '2 02 2-ри', 'Jan  2 2012 should be week 2');\n    assert.equal(moment([2012,  0,  8]).format('w ww wo'), '2 02 2-ри', 'Jan  8 2012 should be week 2');\n    assert.equal(moment([2012,  0,  9]).format('w ww wo'), '3 03 3-ти', 'Jan  9 2012 should be week 3');\n});\n\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/test/locale/bn.js",
    "content": "import {localeModule, test} from '../qunit';\nimport moment from '../../moment';\nlocaleModule('bn');\n\ntest('parse', function (assert) {\n    var tests = 'জানুয়ারী জানু_ফেব্রুয়ারি ফেব_মার্চ মার্চ_এপ্রিল এপ্র_মে মে_জুন জুন_জুলাই জুল_আগস্ট আগ_সেপ্টেম্বর সেপ্ট_অক্টোবর অক্টো_নভেম্বর নভে_ডিসেম্বর ডিসে'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, Do MMMM YYYY, a h:mm:ss সময়',  'রবিবার, ১৪ ফেব্রুয়ারি ২০১০, দুপুর ৩:২৫:৫০ সময়'],\n            ['ddd, a h সময়',                       'রবি, দুপুর ৩ সময়'],\n            ['M Mo MM MMMM MMM',                   '২ ২ ০২ ফেব্রুয়ারি ফেব'],\n            ['YYYY YY',                            '২০১০ ১০'],\n            ['D Do DD',                            '১৪ ১৪ ১৪'],\n            ['d do dddd ddd dd',                   '০ ০ রবিবার রবি রবি'],\n            ['DDD DDDo DDDD',                      '৪৫ ৪৫ ০৪৫'],\n            ['w wo ww',                            '৮ ৮ ০৮'],\n            ['h hh',                               '৩ ০৩'],\n            ['H HH',                               '১৫ ১৫'],\n            ['m mm',                               '২৫ ২৫'],\n            ['s ss',                               '৫০ ৫০'],\n            ['a A',                                'দুপুর দুপুর'],\n            ['LT',                                 'দুপুর ৩:২৫ সময়'],\n            ['LTS',                                'দুপুর ৩:২৫:৫০ সময়'],\n            ['L',                                  '১৪/০২/২০১০'],\n            ['LL',                                 '১৪ ফেব্রুয়ারি ২০১০'],\n            ['LLL',                                '১৪ ফেব্রুয়ারি ২০১০, দুপুর ৩:২৫ সময়'],\n            ['LLLL',                               'রবিবার, ১৪ ফেব্রুয়ারি ২০১০, দুপুর ৩:২৫ সময়'],\n            ['l',                                  '১৪/২/২০১০'],\n            ['ll',                                 '১৪ ফেব ২০১০'],\n            ['lll',                                '১৪ ফেব ২০১০, দুপুর ৩:২৫ সময়'],\n            ['llll',                               'রবি, ১৪ ফেব ২০১০, দুপুর ৩:২৫ সময়']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '১', '১');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '২', '২');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '৩', '৩');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '৪', '৪');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '৫', '৫');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '৬', '৬');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '৭', '৭');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '৮', '৮');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '৯', '৯');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '১০', '১০');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '১১', '১১');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '১২', '১২');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '১৩', '১৩');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '১৪', '১৪');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '১৫', '১৫');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '১৬', '১৬');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '১৭', '১৭');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '১৮', '১৮');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '১৯', '১৯');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '২০', '২০');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '২১', '২১');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '২২', '২২');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '২৩', '২৩');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '২৪', '২৪');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '২৫', '২৫');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '২৬', '২৬');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '২৭', '২৭');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '২৮', '२৮');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '২৯', '২৯');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '৩০', '৩০');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '৩১', '৩১');\n});\n\ntest('format month', function (assert) {\n    var expected = 'জানুয়ারী জানু_ফেব্রুয়ারি ফেব_মার্চ মার্চ_এপ্রিল এপ্র_মে মে_জুন জুন_জুলাই জুল_আগস্ট আগ_সেপ্টেম্বর সেপ্ট_অক্টোবর অক্টো_নভেম্বর নভে_ডিসেম্বর ডিসে'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'রবিবার রবি রবি_সোমবার সোম সোম_মঙ্গলবার মঙ্গল মঙ্গ_বুধবার বুধ বুধ_বৃহস্পতিবার বৃহস্পতি বৃহঃ_শুক্রবার শুক্র শুক্র_শনিবার শনি শনি'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'কয়েক সেকেন্ড', '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'এক মিনিট',      '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'এক মিনিট',      '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '২ মিনিট',     '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '৪৪ মিনিট',    '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'এক ঘন্টা',       '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'এক ঘন্টা',       '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '২ ঘন্টা',       '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '৫ ঘন্টা',       '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '২১ ঘন্টা',      '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'এক দিন',         '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'এক দিন',         '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '২ দিন',        '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'এক দিন',         '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '৫ দিন',        '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '২৫ দিন',       '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'এক মাস',       '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'এক মাস',       '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '২ মাস',      '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '২ মাস',      '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '৩ মাস',      '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'এক মাস',       '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '৫ মাস',      '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'এক বছর',        '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '২ বছর',       '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'এক বছর',        '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '৫ বছর',       '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'কয়েক সেকেন্ড পরে',  'prefix');\n    assert.equal(moment(0).from(30000), 'কয়েক সেকেন্ড আগে', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'কয়েক সেকেন্ড আগে',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'কয়েক সেকেন্ড পরে', 'কয়েক সেকেন্ড পরে');\n    assert.equal(moment().add({d: 5}).fromNow(), '৫ দিন পরে', '৫ দিন পরে');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'আজ দুপুর ১২:০০ সময়',       'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'আজ দুপুর ১২:২৫ সময়',       'Now plus 25 min');\n    assert.equal(moment(a).add({h: 3}).calendar(),       'আজ দুপুর ৩:০০ সময়',        'Now plus 3 hours');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'আগামীকাল দুপুর ১২:০০ সময়', 'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'আজ দুপুর ১১:০০ সময়',       'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'গতকাল দুপুর ১২:০০ সময়',    'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('dddd[,] LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd[,] LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd[,] LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('[গত] dddd[,] LT'),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[গত] dddd[,] LT'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[গত] dddd[,] LT'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('meridiem', function (assert) {\n    assert.equal(moment([2011, 2, 23,  2, 30]).format('a'), 'রাত', 'before dawn');\n    assert.equal(moment([2011, 2, 23,  9, 30]).format('a'), 'সকাল', 'morning');\n    assert.equal(moment([2011, 2, 23, 14, 30]).format('a'), 'দুপুর', 'during day');\n    assert.equal(moment([2011, 2, 23, 17, 30]).format('a'), 'বিকাল', 'evening');\n    assert.equal(moment([2011, 2, 23, 19, 30]).format('a'), 'বিকাল', 'late evening');\n    assert.equal(moment([2011, 2, 23, 21, 20]).format('a'), 'রাত', 'night');\n\n    assert.equal(moment([2011, 2, 23,  2, 30]).format('A'), 'রাত', 'before dawn');\n    assert.equal(moment([2011, 2, 23,  9, 30]).format('A'), 'সকাল', 'morning');\n    assert.equal(moment([2011, 2, 23, 14, 30]).format('A'), 'দুপুর', ' during day');\n    assert.equal(moment([2011, 2, 23, 17, 30]).format('A'), 'বিকাল', 'evening');\n    assert.equal(moment([2011, 2, 23, 19, 30]).format('A'), 'বিকাল', 'late evening');\n    assert.equal(moment([2011, 2, 23, 21, 20]).format('A'), 'রাত', 'night');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2012, 0,  1]).format('w ww wo'), '১ ০১ ১', 'Jan  1 2012 should be week 1');\n    assert.equal(moment([2012, 0,  7]).format('w ww wo'), '১ ০১ ১', 'Jan  7 2012 should be week 1');\n    assert.equal(moment([2012, 0,  8]).format('w ww wo'), '২ ০২ ২', 'Jan  8 2012 should be week 2');\n    assert.equal(moment([2012, 0, 14]).format('w ww wo'), '২ ০২ ২', 'Jan 14 2012 should be week 2');\n    assert.equal(moment([2012, 0, 15]).format('w ww wo'), '৩ ০৩ ৩', 'Jan 15 2012 should be week 3');\n});\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/test/locale/bo.js",
    "content": "import {localeModule, test} from '../qunit';\nimport moment from '../../moment';\nlocaleModule('bo');\n\ntest('parse', function (assert) {\n    var tests = 'ཟླ་བ་དང་པོ ཟླ་བ་དང་པོ._ཟླ་བ་གཉིས་པ ཟླ་བ་གཉིས་པ_ཟླ་བ་གསུམ་པ ཟླ་བ་གསུམ་པ_ཟླ་བ་བཞི་པ ཟླ་བ་བཞི་པ_ཟླ་བ་ལྔ་པ ཟླ་བ་ལྔ་པ_ཟླ་བ་དྲུག་པ ཟླ་བ་དྲུག་པ_ཟླ་བ་བདུན་པ ཟླ་བ་བདུན་པ_ཟླ་བ་བརྒྱད་པ ཟླ་བ་བརྒྱད་པ_ཟླ་བ་དགུ་པ ཟླ་བ་དགུ་པ_ཟླ་བ་བཅུ་པ ཟླ་བ་བཅུ་པ_ཟླ་བ་བཅུ་གཅིག་པ ཟླ་བ་བཅུ་གཅིག་པ_ཟླ་བ་བཅུ་གཉིས་པ ཟླ་བ་བཅུ་གཉིས་པ'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, Do MMMM YYYY, a h:mm:ss ལ་',  'གཟའ་ཉི་མ་, ༡༤ ཟླ་བ་གཉིས་པ ༢༠༡༠, ཉིན་གུང ༣:༢༥:༥༠ ལ་'],\n            ['ddd, a h ལ་',                       'ཉི་མ་, ཉིན་གུང ༣ ལ་'],\n            ['M Mo MM MMMM MMM',                   '༢ ༢ ༠༢ ཟླ་བ་གཉིས་པ ཟླ་བ་གཉིས་པ'],\n            ['YYYY YY',                            '༢༠༡༠ ༡༠'],\n            ['D Do DD',                            '༡༤ ༡༤ ༡༤'],\n            ['d do dddd ddd dd',                   '༠ ༠ གཟའ་ཉི་མ་ ཉི་མ་ ཉི་མ་'],\n            ['DDD DDDo DDDD',                      '༤༥ ༤༥ ༠༤༥'],\n            ['w wo ww',                            '༨ ༨ ༠༨'],\n            ['h hh',                               '༣ ༠༣'],\n            ['H HH',                               '༡༥ ༡༥'],\n            ['m mm',                               '༢༥ ༢༥'],\n            ['s ss',                               '༥༠ ༥༠'],\n            ['a A',                                'ཉིན་གུང ཉིན་གུང'],\n            ['LT',                                 'ཉིན་གུང ༣:༢༥'],\n            ['LTS',                                'ཉིན་གུང ༣:༢༥:༥༠'],\n            ['L',                                  '༡༤/༠༢/༢༠༡༠'],\n            ['LL',                                 '༡༤ ཟླ་བ་གཉིས་པ ༢༠༡༠'],\n            ['LLL',                                '༡༤ ཟླ་བ་གཉིས་པ ༢༠༡༠, ཉིན་གུང ༣:༢༥'],\n            ['LLLL',                               'གཟའ་ཉི་མ་, ༡༤ ཟླ་བ་གཉིས་པ ༢༠༡༠, ཉིན་གུང ༣:༢༥'],\n            ['l',                                  '༡༤/༢/༢༠༡༠'],\n            ['ll',                                 '༡༤ ཟླ་བ་གཉིས་པ ༢༠༡༠'],\n            ['lll',                                '༡༤ ཟླ་བ་གཉིས་པ ༢༠༡༠, ཉིན་གུང ༣:༢༥'],\n            ['llll',                               'ཉི་མ་, ༡༤ ཟླ་བ་གཉིས་པ ༢༠༡༠, ཉིན་གུང ༣:༢༥']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '༡', '༡');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '༢', '༢');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '༣', '༣');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '༤', '༤');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '༥', '༥');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '༦', '༦');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '༧', '༧');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '༨', '༨');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '༩', '༩');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '༡༠', '༡༠');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '༡༡', '༡༡');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '༡༢', '༡༢');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '༡༣', '༡༣');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '༡༤', '༡༤');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '༡༥', '༡༥');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '༡༦', '༡༦');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '༡༧', '༡༧');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '༡༨', '༡༨');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '༡༩', '༡༩');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '༢༠', '༢༠');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '༢༡', '༢༡');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '༢༢', '༢༢');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '༢༣', '༢༣');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '༢༤', '༢༤');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '༢༥', '༢༥');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '༢༦', '༢༦');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '༢༧', '༢༧');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '༢༨', '༢༨');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '༢༩', '༢༩');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '༣༠', '༣༠');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '༣༡', '༣༡');\n});\n\ntest('format month', function (assert) {\n    var expected = 'ཟླ་བ་དང་པོ ཟླ་བ་དང་པོ_ཟླ་བ་གཉིས་པ ཟླ་བ་གཉིས་པ_ཟླ་བ་གསུམ་པ ཟླ་བ་གསུམ་པ_ཟླ་བ་བཞི་པ ཟླ་བ་བཞི་པ_ཟླ་བ་ལྔ་པ ཟླ་བ་ལྔ་པ_ཟླ་བ་དྲུག་པ ཟླ་བ་དྲུག་པ_ཟླ་བ་བདུན་པ ཟླ་བ་བདུན་པ_ཟླ་བ་བརྒྱད་པ ཟླ་བ་བརྒྱད་པ_ཟླ་བ་དགུ་པ ཟླ་བ་དགུ་པ_ཟླ་བ་བཅུ་པ ཟླ་བ་བཅུ་པ_ཟླ་བ་བཅུ་གཅིག་པ ཟླ་བ་བཅུ་གཅིག་པ_ཟླ་བ་བཅུ་གཉིས་པ ཟླ་བ་བཅུ་གཉིས་པ'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'གཟའ་ཉི་མ་ ཉི་མ་ ཉི་མ་_གཟའ་ཟླ་བ་ ཟླ་བ་ ཟླ་བ་_གཟའ་མིག་དམར་ མིག་དམར་ མིག་དམར་_གཟའ་ལྷག་པ་ ལྷག་པ་ ལྷག་པ་_གཟའ་ཕུར་བུ ཕུར་བུ ཕུར་བུ_གཟའ་པ་སངས་ པ་སངས་ པ་སངས་_གཟའ་སྤེན་པ་ སྤེན་པ་ སྤེན་པ་'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'ལམ་སང', '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'སྐར་མ་གཅིག',      '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'སྐར་མ་གཅིག',      '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '༢ སྐར་མ',     '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '༤༤ སྐར་མ',    '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'ཆུ་ཚོད་གཅིག',       '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'ཆུ་ཚོད་གཅིག',       '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '༢ ཆུ་ཚོད',       '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '༥ ཆུ་ཚོད',       '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '༢༡ ཆུ་ཚོད',      '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'ཉིན་གཅིག',         '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'ཉིན་གཅིག',         '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '༢ ཉིན་',        '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'ཉིན་གཅིག',         '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '༥ ཉིན་',        '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '༢༥ ཉིན་',       '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'ཟླ་བ་གཅིག',       '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'ཟླ་བ་གཅིག',       '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'ཟླ་བ་གཅིག',       '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '༢ ཟླ་བ',      '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '༢ ཟླ་བ',      '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '༣ ཟླ་བ',      '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'ཟླ་བ་གཅིག',       '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '༥ ཟླ་བ',      '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'ལོ་གཅིག',        '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '༢ ལོ',       '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'ལོ་གཅིག',        '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '༥ ལོ',       '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'ལམ་སང ལ་',  'prefix');\n    assert.equal(moment(0).from(30000), 'ལམ་སང སྔན་ལ', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'ལམ་སང སྔན་ལ',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'ལམ་སང ལ་', 'ལམ་སང ལ་');\n    assert.equal(moment().add({d: 5}).fromNow(), '༥ ཉིན་ ལ་', '༥ ཉིན་ ལ་');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'དི་རིང ཉིན་གུང ༡༢:༠༠',  'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'དི་རིང ཉིན་གུང ༡༢:༢༥',  'Now plus 25 min');\n    assert.equal(moment(a).add({h: 3}).calendar(),       'དི་རིང ཉིན་གུང ༣:༠༠',   'Now plus 3 hours');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'སང་ཉིན ཉིན་གུང ༡༢:༠༠',  'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'དི་རིང ཉིན་གུང ༡༡:༠༠',  'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'ཁ་སང ཉིན་གུང ༡༢:༠༠',    'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('[བདུན་ཕྲག་རྗེས་མ][,] LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[བདུན་ཕྲག་རྗེས་མ][,] LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[བདུན་ཕྲག་རྗེས་མ][,] LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('[བདུན་ཕྲག་མཐའ་མ] dddd[,] LT'),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[བདུན་ཕྲག་མཐའ་མ] dddd[,] LT'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[བདུན་ཕྲག་མཐའ་མ] dddd[,] LT'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('meridiem', function (assert) {\n    assert.equal(moment([2011, 2, 23,  2, 30]).format('a'), 'མཚན་མོ', 'before dawn');\n    assert.equal(moment([2011, 2, 23,  9, 30]).format('a'), 'ཞོགས་ཀས', 'morning');\n    assert.equal(moment([2011, 2, 23, 14, 30]).format('a'), 'ཉིན་གུང', 'during day');\n    assert.equal(moment([2011, 2, 23, 17, 30]).format('a'), 'དགོང་དག', 'evening');\n    assert.equal(moment([2011, 2, 23, 19, 30]).format('a'), 'དགོང་དག', 'late evening');\n    assert.equal(moment([2011, 2, 23, 21, 20]).format('a'), 'མཚན་མོ', 'night');\n\n    assert.equal(moment([2011, 2, 23,  2, 30]).format('A'), 'མཚན་མོ', 'before dawn');\n    assert.equal(moment([2011, 2, 23,  9, 30]).format('A'), 'ཞོགས་ཀས', 'morning');\n    assert.equal(moment([2011, 2, 23, 14, 30]).format('A'), 'ཉིན་གུང', ' during day');\n    assert.equal(moment([2011, 2, 23, 17, 30]).format('A'), 'དགོང་དག', 'evening');\n    assert.equal(moment([2011, 2, 23, 19, 30]).format('A'), 'དགོང་དག', 'late evening');\n    assert.equal(moment([2011, 2, 23, 21, 20]).format('A'), 'མཚན་མོ', 'night');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2012, 0,  1]).format('w ww wo'), '༡ ༠༡ ༡', 'Jan  1 2012 should be week 1');\n    assert.equal(moment([2012, 0,  7]).format('w ww wo'), '༡ ༠༡ ༡', 'Jan  7 2012 should be week 1');\n    assert.equal(moment([2012, 0,  8]).format('w ww wo'), '༢ ༠༢ ༢', 'Jan  8 2012 should be week 2');\n    assert.equal(moment([2012, 0, 14]).format('w ww wo'), '༢ ༠༢ ༢', 'Jan 14 2012 should be week 2');\n    assert.equal(moment([2012, 0, 15]).format('w ww wo'), '༣ ༠༣ ༣', 'Jan 15 2012 should be week 3');\n});\n\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/test/locale/br.js",
    "content": "import {localeModule, test} from '../qunit';\nimport moment from '../../moment';\nlocaleModule('br');\n\ntest('parse', function (assert) {\n    var tests = 'Genver Gen_C\\'hwevrer C\\'hwe_Meurzh Meu_Ebrel Ebr_Mae Mae_Mezheven Eve_Gouere Gou_Eost Eos_Gwengolo Gwe_Here Her_Du Du_Kerzu Ker'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    moment.locale('br');\n    var a = [\n            ['dddd, MMMM Do YYYY, h:mm:ss a',      'Sul, C\\'hwevrer 14vet 2010, 3:25:50 pm'],\n            ['ddd, h A',                            'Sul, 3 PM'],\n            ['M Mo MM MMMM MMM',                   '2 2vet 02 C\\'hwevrer C\\'hwe'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14vet 14'],\n            ['d do dddd ddd dd',                   '0 0vet Sul Sul Su'],\n            ['DDD DDDo DDDD',                      '45 45vet 045'],\n            ['w wo ww',                            '6 6vet 06'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['DDDo [devezh] [ar] [vloaz]',       '45vet devezh ar vloaz'],\n            ['L',                                  '14/02/2010'],\n            ['LL',                                 '14 a viz C\\'hwevrer 2010'],\n            ['LLL',                                '14 a viz C\\'hwevrer 2010 3e25 PM'],\n            ['LLLL',                               'Sul, 14 a viz C\\'hwevrer 2010 3e25 PM']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    moment.locale('br');\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1añ', '1añ');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2vet', '2vet');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3vet', '3vet');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4vet', '4vet');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5vet', '5vet');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6vet', '6vet');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7vet', '7vet');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8vet', '8vet');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9vet', '9vet');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10vet', '10vet');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11vet', '11vet');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12vet', '12vet');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13vet', '13vet');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14vet', '14vet');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15vet', '15vet');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16vet', '16vet');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17vet', '17vet');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18vet', '18vet');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19vet', '19vet');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20vet', '20vet');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21vet', '21vet');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22vet', '22vet');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23vet', '23vet');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24vet', '24vet');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25vet', '25vet');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26vet', '26vet');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27vet', '27vet');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28vet', '28vet');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29vet', '29vet');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30vet', '30vet');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31vet', '31vet');\n});\n\ntest('format month', function (assert) {\n    moment.locale('br');\n    var expected = 'Genver Gen_C\\'hwevrer C\\'hwe_Meurzh Meu_Ebrel Ebr_Mae Mae_Mezheven Eve_Gouere Gou_Eost Eos_Gwengolo Gwe_Here Her_Du Du_Kerzu Ker'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    moment.locale('br');\n    var expected = 'Sul Sul Su_Lun Lun Lu_Meurzh Meu Me_Merc\\'her Mer Mer_Yaou Yao Ya_Gwener Gwe Gw_Sadorn Sad Sa'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    moment.locale('br');\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'un nebeud segondennoù', '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'ur vunutenn',      '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'ur vunutenn',      '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 vunutenn',     '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 munutenn',    '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'un eur',       '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'un eur',       '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 eur',       '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 eur',       '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 eur',      '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'un devezh',         '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'un devezh',         '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 zevezh',        '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'un devezh',         '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 devezh',        '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 devezh',       '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'ur miz',       '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'ur miz',       '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'ur miz',       '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 viz',      '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 viz',      '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 miz',      '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'ur miz',       '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 miz',      '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'ur bloaz',        '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 vloaz',       '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'ur bloaz',        '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 bloaz',       '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    moment.locale('br');\n    assert.equal(moment(30000).from(0), 'a-benn un nebeud segondennoù',  'prefix');\n    assert.equal(moment(0).from(30000), 'un nebeud segondennoù \\'zo', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    moment.locale('br');\n    assert.equal(moment().fromNow(), 'un nebeud segondennoù \\'zo',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    moment.locale('br');\n    assert.equal(moment().add({s: 30}).fromNow(), 'a-benn un nebeud segondennoù', 'in a few seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), 'a-benn 5 devezh', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    moment.locale('br');\n\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'Hiziv da 12e00 PM',        'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'Hiziv da 12e25 PM',        'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'Hiziv da 1e00 PM',         'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'Warc\\'hoazh da 12e00 PM',  'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'Hiziv da 11e00 AM',        'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'Dec\\'h da 12e00 PM',       'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    moment.locale('br');\n\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('dddd [da] LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd [da] LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd [da] LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    moment.locale('br');\n\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('dddd [paset da] LT'),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd [paset da] LT'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd [paset da] LT'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    moment.locale('br');\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('special mutations for years', function (assert) {\n    moment.locale('br');\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true), 'ur bloaz', 'mutation 1 year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 2}), true), '2 vloaz', 'mutation 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 3}), true), '3 bloaz', 'mutation 3 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 4}), true), '4 bloaz', 'mutation 4 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true), '5 bloaz', 'mutation 5 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 9}), true), '9 bloaz', 'mutation 9 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 10}), true), '10 vloaz', 'mutation 10 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 21}), true), '21 bloaz', 'mutation 21 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 22}), true), '22 vloaz', 'mutation 22 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 133}), true), '133 bloaz', 'mutation 133 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 148}), true), '148 vloaz', 'mutation 148 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 261}), true), '261 bloaz', 'mutation 261 years');\n});\n\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/test/locale/bs.js",
    "content": "import {localeModule, test} from '../qunit';\nimport moment from '../../moment';\nlocaleModule('bs');\n\ntest('parse', function (assert) {\n    var tests = 'januar jan._februar feb._mart mar._april apr._maj maj._juni jun._juli jul._august aug._septembar sep._oktobar okt._novembar nov._decembar dec.'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1) + ' inp ' + mmm);\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, Do MMMM YYYY, h:mm:ss a',      'nedjelja, 14. februar 2010, 3:25:50 pm'],\n            ['ddd, hA',                            'ned., 3PM'],\n            ['M Mo MM MMMM MMM',                   '2 2. 02 februar feb.'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14. 14'],\n            ['d do dddd ddd dd',                   '0 0. nedjelja ned. ne'],\n            ['DDD DDDo DDDD',                      '45 45. 045'],\n            ['w wo ww',                            '7 7. 07'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'pm PM'],\n            ['[the] DDDo [day of the year]',       'the 45. day of the year'],\n            ['LTS',                                '15:25:50'],\n            ['L',                                  '14.02.2010'],\n            ['LL',                                 '14. februar 2010'],\n            ['LLL',                                '14. februar 2010 15:25'],\n            ['LLLL',                               'nedjelja, 14. februar 2010 15:25'],\n            ['l',                                  '14.2.2010'],\n            ['ll',                                 '14. feb. 2010'],\n            ['lll',                                '14. feb. 2010 15:25'],\n            ['llll',                               'ned., 14. feb. 2010 15:25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1.', '1.');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2.', '2.');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3.', '3.');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4.', '4.');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5.', '5.');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6.', '6.');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7.', '7.');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8.', '8.');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9.', '9.');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10.', '10.');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11.', '11.');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12.', '12.');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13.', '13.');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14.', '14.');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15.', '15.');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16.', '16.');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17.', '17.');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18.', '18.');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19.', '19.');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20.', '20.');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21.', '21.');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22.', '22.');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23.', '23.');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24.', '24.');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25.', '25.');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26.', '26.');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27.', '27.');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28.', '28.');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29.', '29.');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30.', '30.');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31.', '31.');\n});\n\ntest('format month', function (assert) {\n    var expected = 'januar jan._februar feb._mart mar._april apr._maj maj._juni jun._juli jul._august aug._septembar sep._oktobar okt._novembar nov._decembar dec.'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'nedjelja ned. ne_ponedjeljak pon. po_utorak uto. ut_srijeda sri. sr_četvrtak čet. če_petak pet. pe_subota sub. su'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'par sekundi', '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'jedna minuta',   '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'jedna minuta',   '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 minute',     '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 minuta',     '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'jedan sat',      '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'jedan sat',      '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 sata',        '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 sati',         '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 sati',        '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'dan',       '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'dan',       '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 dana',        '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'dan',       '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 dana',        '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 dana',       '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'mjesec',     '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'mjesec',     '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'mjesec',     '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 mjeseca',     '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 mjeseca',     '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 mjeseca',     '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'mjesec',     '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 mjeseci',    '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'godinu',     '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 godine',       '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'godinu',     '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 godina',        '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'za par sekundi',  'prefix');\n    assert.equal(moment(0).from(30000), 'prije par sekundi', 'prefix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'prije par sekundi',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'za par sekundi', 'in a few seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), 'za 5 dana', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'danas u 12:00',  'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'danas u 12:25',  'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'danas u 13:00',  'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'sutra u 12:00',  'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'danas u 11:00',  'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'jučer u 12:00',  'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n\n    function makeFormat(d) {\n        switch (d.day()) {\n            case 0:\n                return '[u] [nedjelju] [u] LT';\n            case 3:\n                return '[u] [srijedu] [u] LT';\n            case 6:\n                return '[u] [subotu] [u] LT';\n            case 1:\n            case 2:\n            case 4:\n            case 5:\n                return '[u] dddd [u] LT';\n        }\n    }\n\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format(makeFormat(m)),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format(makeFormat(m)),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format(makeFormat(m)),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n\n    function makeFormat(d) {\n        switch (d.day()) {\n            case 0:\n            case 3:\n                return '[prošlu] dddd [u] LT';\n            case 6:\n                return '[prošle] [subote] [u] LT';\n            case 1:\n            case 2:\n            case 4:\n            case 5:\n                return '[prošli] dddd [u] LT';\n        }\n    }\n\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format(makeFormat(m)),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format(makeFormat(m)),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format(makeFormat(m)),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2011, 11, 26]).format('w ww wo'), '1 01 1.', 'Dec 26 2011 should be week 1');\n    assert.equal(moment([2012,  0,  1]).format('w ww wo'), '1 01 1.', 'Jan  1 2012 should be week 1');\n    assert.equal(moment([2012,  0,  2]).format('w ww wo'), '2 02 2.', 'Jan  2 2012 should be week 2');\n    assert.equal(moment([2012,  0,  8]).format('w ww wo'), '2 02 2.', 'Jan  8 2012 should be week 2');\n    assert.equal(moment([2012,  0,  9]).format('w ww wo'), '3 03 3.', 'Jan  9 2012 should be week 3');\n});\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/test/locale/ca.js",
    "content": "import {localeModule, test} from '../qunit';\nimport moment from '../../moment';\nlocaleModule('ca');\n\ntest('parse', function (assert) {\n    var tests = 'gener gen._febrer febr._març març_abril abr._maig maig_juny juny_juliol jul._agost ag._setembre set._octubre oct._novembre nov._desembre des.'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, Do MMMM YYYY, h:mm:ss a',      'diumenge, 14è de febrer 2010, 3:25:50 pm'],\n            ['ddd, hA',                            'dg., 3PM'],\n            ['M Mo MM MMMM MMM',                   '2 2n 02 febrer febr.'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14è 14'],\n            ['d do dddd ddd dd',                   '0 0è diumenge dg. Dg'],\n            ['DDD DDDo DDDD',                      '45 45è 045'],\n            ['w wo ww',                            '6 6a 06'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'pm PM'],\n            ['[the] DDDo [day of the year]',       'the 45è day of the year'],\n            ['LTS',                                '15:25:50'],\n            ['L',                                  '14/02/2010'],\n            ['LL',                                 'el 14 de febrer de 2010'],\n            ['LLL',                                'el 14 de febrer de 2010 a les 15:25'],\n            ['LLLL',                               'el diumenge 14 de febrer de 2010 a les 15:25'],\n            ['l',                                  '14/2/2010'],\n            ['ll',                                 '14 febr. 2010'],\n            ['lll',                                '14 febr. 2010, 15:25'],\n            ['llll',                               'dg. 14 febr. 2010, 15:25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1r', '1r');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2n', '2n');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3r', '3r');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4t', '4t');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5è', '5è');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6è', '6è');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7è', '7è');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8è', '8è');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9è', '9è');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10è', '10è');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11è', '11è');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12è', '12è');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13è', '13è');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14è', '14è');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15è', '15è');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16è', '16è');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17è', '17è');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18è', '18è');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19è', '19è');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20è', '20è');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21è', '21è');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22è', '22è');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23è', '23è');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24è', '24è');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25è', '25è');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26è', '26è');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27è', '27è');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28è', '28è');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29è', '29è');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30è', '30è');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31è', '31è');\n});\n\ntest('format month', function (assert) {\n    var expected = 'gener gen._febrer febr._març març_abril abr._maig maig_juny juny_juliol jul._agost ag._setembre set._octubre oct._novembre nov._desembre des.'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'diumenge dg. Dg_dilluns dl. Dl_dimarts dt. Dt_dimecres dc. Dc_dijous dj. Dj_divendres dv. Dv_dissabte ds. Ds'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'uns segons', '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'un minut',      '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'un minut',      '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 minuts',     '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 minuts',    '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'una hora',       '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'una hora',       '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 hores',       '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 hores',       '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 hores',      '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'un dia',         '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'un dia',         '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 dies',        '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'un dia',         '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 dies',        '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 dies',       '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'un mes',       '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'un mes',       '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'un mes',       '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 mesos',      '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 mesos',      '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 mesos',      '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'un mes',       '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 mesos',      '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'un any',        '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 anys',       '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'un any',        '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 anys',       '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'd\\'aquí uns segons',  'prefix');\n    assert.equal(moment(0).from(30000), 'fa uns segons', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'fa uns segons',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'd\\'aquí uns segons', 'd\\'aquí uns segons');\n    assert.equal(moment().add({d: 5}).fromNow(), 'd\\'aquí 5 dies', 'd\\'aquí 5 dies');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                       'avui a les 12:00',     'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),          'avui a les 12:25',     'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),           'avui a les 13:00',     'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),           'demà a les 12:00',     'tomorrow at the same time');\n    assert.equal(moment(a).add({d: 1, h : -1}).calendar(),   'demà a les 11:00',     'tomorrow minus 1 hour');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),      'avui a les 11:00',     'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),      'ahir a les 12:00',     'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('dddd [a ' + ((m.hours() !== 1) ? 'les' : 'la') + '] LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd [a ' + ((m.hours() !== 1) ? 'les' : 'la') + '] LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd [a ' + ((m.hours() !== 1) ? 'les' : 'la') + '] LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('[el] dddd [passat a ' + ((m.hours() !== 1) ? 'les' : 'la') + '] LT'),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[el] dddd [passat a ' + ((m.hours() !== 1) ? 'les' : 'la') + '] LT'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[el] dddd [passat a ' + ((m.hours() !== 1) ? 'les' : 'la') + '] LT'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2012, 0,  1]).format('w ww wo'), '52 52 52a', 'Jan  1 2012 should be week 52');\n    assert.equal(moment([2012, 0,  2]).format('w ww wo'),   '1 01 1a', 'Jan  2 2012 should be week 1');\n    assert.equal(moment([2012, 0,  8]).format('w ww wo'),   '1 01 1a', 'Jan  8 2012 should be week 1');\n    assert.equal(moment([2012, 0,  9]).format('w ww wo'),   '2 02 2a', 'Jan  9 2012 should be week 2');\n    assert.equal(moment([2012, 0, 15]).format('w ww wo'),   '2 02 2a', 'Jan 15 2012 should be week 2');\n});\n\ntest('day and month', function (assert) {\n    assert.equal(moment([2012, 1, 15]).format('D MMMM'), '15 de febrer');\n    assert.equal(moment([2012, 9, 15]).format('D MMMM'), '15 d\\'octubre');\n    assert.equal(moment([2012, 9, 15]).format('MMMM, D'), 'octubre, 15');\n});\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/test/locale/cs.js",
    "content": "import {localeModule, test} from '../qunit';\nimport moment from '../../moment';\nlocaleModule('cs');\n\ntest('parse', function (assert) {\n    var tests = 'leden led_únor úno_březen bře_duben dub_květen kvě_červen čvn_červenec čvc_srpen srp_září zář_říjen říj_listopad lis_prosinec pro'.split('_'), i;\n    function equalTest(input, mmm, monthIndex) {\n        assert.equal(moment(input, mmm).month(), monthIndex, input + ' ' + mmm + ' should be month ' + (monthIndex + 1));\n    }\n    function equalTestStrict(input, mmm, monthIndex) {\n        assert.equal(moment(input, mmm, true).month(), monthIndex, input + ' ' + mmm + ' should be strict month ' + (monthIndex + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n\n        equalTestStrict(tests[i][1], 'MMM', i);\n        equalTestStrict(tests[i][0], 'MMMM', i);\n        equalTestStrict(tests[i][1].toLocaleLowerCase(), 'MMM', i);\n        equalTestStrict(tests[i][1].toLocaleUpperCase(), 'MMM', i);\n        equalTestStrict(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTestStrict(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, MMMM Do YYYY, h:mm:ss',  'neděle, únor 14. 2010, 3:25:50'],\n            ['ddd, h',                       'ne, 3'],\n            ['M Mo MM MMMM MMM',             '2 2. 02 únor úno'],\n            ['YYYY YY',                      '2010 10'],\n            ['D Do DD',                      '14 14. 14'],\n            ['d do dddd ddd dd',             '0 0. neděle ne ne'],\n            ['DDD DDDo DDDD',                '45 45. 045'],\n            ['w wo ww',                      '6 6. 06'],\n            ['h hh',                         '3 03'],\n            ['H HH',                         '15 15'],\n            ['m mm',                         '25 25'],\n            ['s ss',                         '50 50'],\n            ['a A',                          'pm PM'],\n            ['DDDo [den v roce]',            '45. den v roce'],\n            ['LTS',                          '15:25:50'],\n            ['L',                            '14.02.2010'],\n            ['LL',                           '14. únor 2010'],\n            ['LLL',                          '14. únor 2010 15:25'],\n            ['LLLL',                         'neděle 14. únor 2010 15:25'],\n            ['l',                            '14. 2. 2010'],\n            ['ll',                           '14. úno 2010'],\n            ['lll',                          '14. úno 2010 15:25'],\n            ['llll',                         'ne 14. úno 2010 15:25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1.', '1.');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2.', '2.');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3.', '3.');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4.', '4.');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5.', '5.');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6.', '6.');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7.', '7.');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8.', '8.');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9.', '9.');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10.', '10.');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11.', '11.');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12.', '12.');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13.', '13.');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14.', '14.');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15.', '15.');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16.', '16.');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17.', '17.');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18.', '18.');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19.', '19.');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20.', '20.');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21.', '21.');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22.', '22.');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23.', '23.');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24.', '24.');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25.', '25.');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26.', '26.');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27.', '27.');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28.', '28.');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29.', '29.');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30.', '30.');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31.', '31.');\n});\n\ntest('format month', function (assert) {\n    var expected = 'leden led_únor úno_březen bře_duben dub_květen kvě_červen čvn_červenec čvc_srpen srp_září zář_říjen říj_listopad lis_prosinec pro'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'neděle ne ne_pondělí po po_úterý út út_středa st st_čtvrtek čt čt_pátek pá pá_sobota so so'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'pár sekund',  '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'minuta',        '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'minuta',        '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 minuty',      '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 minut',     '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'hodina',       '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'hodina',       '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 hodiny',     '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 hodin',      '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 hodin',     '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'den',       '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'den',       '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 dny',         '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'den',       '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 dní',         '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 dní',        '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'měsíc',       '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'měsíc',       '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'měsíc',       '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 měsíce',    '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 měsíce',    '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 měsíce',    '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'měsíc',       '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 měsíců',    '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'rok',           '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 roky',        '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'rok',           '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 let',         '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'za pár sekund',  'prefix');\n    assert.equal(moment(0).from(30000), 'před pár sekundami', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'před pár sekundami',  'now from now should display as in the past');\n});\n\ntest('fromNow (future)', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'za pár sekund', 'in a few seconds');\n    assert.equal(moment().add({m: 1}).fromNow(), 'za minutu', 'in a minute');\n    assert.equal(moment().add({m: 3}).fromNow(), 'za 3 minuty', 'in 3 minutes');\n    assert.equal(moment().add({m: 10}).fromNow(), 'za 10 minut', 'in 10 minutes');\n    assert.equal(moment().add({h: 1}).fromNow(), 'za hodinu', 'in an hour');\n    assert.equal(moment().add({h: 3}).fromNow(), 'za 3 hodiny', 'in 3 hours');\n    assert.equal(moment().add({h: 10}).fromNow(), 'za 10 hodin', 'in 10 hours');\n    assert.equal(moment().add({d: 1}).fromNow(), 'za den', 'in a day');\n    assert.equal(moment().add({d: 3}).fromNow(), 'za 3 dny', 'in 3 days');\n    assert.equal(moment().add({d: 10}).fromNow(), 'za 10 dní', 'in 10 days');\n    assert.equal(moment().add({M: 1}).fromNow(), 'za měsíc', 'in a month');\n    assert.equal(moment().add({M: 3}).fromNow(), 'za 3 měsíce', 'in 3 months');\n    assert.equal(moment().add({M: 10}).fromNow(), 'za 10 měsíců', 'in 10 months');\n    assert.equal(moment().add({y: 1}).fromNow(), 'za rok', 'in a year');\n    assert.equal(moment().add({y: 3}).fromNow(), 'za 3 roky', 'in 3 years');\n    assert.equal(moment().add({y: 10}).fromNow(), 'za 10 let', 'in 10 years');\n});\n\ntest('fromNow (past)', function (assert) {\n    assert.equal(moment().subtract({s: 30}).fromNow(), 'před pár sekundami', 'a few seconds ago');\n    assert.equal(moment().subtract({m: 1}).fromNow(), 'před minutou', 'a minute ago');\n    assert.equal(moment().subtract({m: 3}).fromNow(), 'před 3 minutami', '3 minutes ago');\n    assert.equal(moment().subtract({m: 10}).fromNow(), 'před 10 minutami', '10 minutes ago');\n    assert.equal(moment().subtract({h: 1}).fromNow(), 'před hodinou', 'an hour ago');\n    assert.equal(moment().subtract({h: 3}).fromNow(), 'před 3 hodinami', '3 hours ago');\n    assert.equal(moment().subtract({h: 10}).fromNow(), 'před 10 hodinami', '10 hours ago');\n    assert.equal(moment().subtract({d: 1}).fromNow(), 'před dnem', 'a day ago');\n    assert.equal(moment().subtract({d: 3}).fromNow(), 'před 3 dny', '3 days ago');\n    assert.equal(moment().subtract({d: 10}).fromNow(), 'před 10 dny', '10 days ago');\n    assert.equal(moment().subtract({M: 1}).fromNow(), 'před měsícem', 'a month ago');\n    assert.equal(moment().subtract({M: 3}).fromNow(), 'před 3 měsíci', '3 months ago');\n    assert.equal(moment().subtract({M: 10}).fromNow(), 'před 10 měsíci', '10 months ago');\n    assert.equal(moment().subtract({y: 1}).fromNow(), 'před rokem', 'a year ago');\n    assert.equal(moment().subtract({y: 3}).fromNow(), 'před 3 lety', '3 years ago');\n    assert.equal(moment().subtract({y: 10}).fromNow(), 'před 10 lety', '10 years ago');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'dnes v 12:00',     'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'dnes v 12:25',     'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'dnes v 13:00',     'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'zítra v 12:00',    'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'dnes v 11:00',     'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'včera v 12:00',    'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m, nextDay;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        nextDay = '';\n        switch (m.day()) {\n            case 0:\n                nextDay = 'v neděli';\n                break;\n            case 1:\n                nextDay = 'v pondělí';\n                break;\n            case 2:\n                nextDay = 'v úterý';\n                break;\n            case 3:\n                nextDay = 've středu';\n                break;\n            case 4:\n                nextDay = 've čtvrtek';\n                break;\n            case 5:\n                nextDay = 'v pátek';\n                break;\n            case 6:\n                nextDay = 'v sobotu';\n                break;\n        }\n        assert.equal(m.calendar(),       m.format('[' + nextDay + '] [v] LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[' + nextDay + '] [v] LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[' + nextDay + '] [v] LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m, lastDay;\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        lastDay = '';\n        switch (m.day()) {\n            case 0:\n                lastDay = 'minulou neděli';\n                break;\n            case 1:\n                lastDay = 'minulé pondělí';\n                break;\n            case 2:\n                lastDay = 'minulé úterý';\n                break;\n            case 3:\n                lastDay = 'minulou středu';\n                break;\n            case 4:\n                lastDay = 'minulý čtvrtek';\n                break;\n            case 5:\n                lastDay = 'minulý pátek';\n                break;\n            case 6:\n                lastDay = 'minulou sobotu';\n                break;\n        }\n        assert.equal(m.calendar(),       m.format('[' + lastDay + '] [v] LT'),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[' + lastDay + '] [v] LT'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[' + lastDay + '] [v] LT'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('humanize duration', function (assert) {\n    assert.equal(moment.duration(1, 'minutes').humanize(), 'minuta', 'a minute (future)');\n    assert.equal(moment.duration(1, 'minutes').humanize(true), 'za minutu', 'in a minute');\n    assert.equal(moment.duration(-1, 'minutes').humanize(), 'minuta', 'a minute (past)');\n    assert.equal(moment.duration(-1, 'minutes').humanize(true), 'před minutou', 'a minute ago');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2012, 0,  1]).format('w ww wo'), '52 52 52.', 'Jan  1 2012 should be week 52');\n    assert.equal(moment([2012, 0,  2]).format('w ww wo'),   '1 01 1.', 'Jan  2 2012 should be week 1');\n    assert.equal(moment([2012, 0,  8]).format('w ww wo'),   '1 01 1.', 'Jan  8 2012 should be week 1');\n    assert.equal(moment([2012, 0,  9]).format('w ww wo'),   '2 02 2.', 'Jan  9 2012 should be week 2');\n    assert.equal(moment([2012, 0, 15]).format('w ww wo'),   '2 02 2.', 'Jan 15 2012 should be week 2');\n});\n\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/test/locale/cv.js",
    "content": "import {localeModule, test} from '../qunit';\nimport moment from '../../moment';\nlocaleModule('cv');\n\ntest('parse', function (assert) {\n    var tests = 'кӑрлач кӑр_нарӑс нар_пуш пуш_ака ака_май май_ҫӗртме ҫӗр_утӑ утӑ_ҫурла ҫур_авӑн авн_юпа юпа_чӳк чӳк_раштав раш'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, MMMM Do YYYY, h:mm:ss a',      'вырсарникун, нарӑс 14-мӗш 2010, 3:25:50 pm'],\n            ['ddd, hA',                            'выр, 3PM'],\n            ['M Mo MM MMMM MMM',                   '2 2-мӗш 02 нарӑс нар'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14-мӗш 14'],\n            ['d do dddd ddd dd',                   '0 0-мӗш вырсарникун выр вр'],\n            ['DDD DDDo DDDD',                      '45 45-мӗш 045'],\n            ['w wo ww',                            '7 7-мӗш 07'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'pm PM'],\n            ['Ҫулӑн DDDo кунӗ',                    'Ҫулӑн 45-мӗш кунӗ'],\n            ['LTS',                                '15:25:50'],\n            ['L',                                  '14-02-2010'],\n            ['LL',                                 '2010 ҫулхи нарӑс уйӑхӗн 14-мӗшӗ'],\n            ['LLL',                                '2010 ҫулхи нарӑс уйӑхӗн 14-мӗшӗ, 15:25'],\n            ['LLLL',                               'вырсарникун, 2010 ҫулхи нарӑс уйӑхӗн 14-мӗшӗ, 15:25'],\n            ['l',                                  '14-2-2010'],\n            ['ll',                                 '2010 ҫулхи нар уйӑхӗн 14-мӗшӗ'],\n            ['lll',                                '2010 ҫулхи нар уйӑхӗн 14-мӗшӗ, 15:25'],\n            ['llll',                               'выр, 2010 ҫулхи нар уйӑхӗн 14-мӗшӗ, 15:25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1-мӗш', '1-мӗш');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2-мӗш', '2-мӗш');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3-мӗш', '3-мӗш');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4-мӗш', '4-мӗш');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5-мӗш', '5-мӗш');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6-мӗш', '6-мӗш');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7-мӗш', '7-мӗш');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8-мӗш', '8-мӗш');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9-мӗш', '9-мӗш');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10-мӗш', '10-мӗш');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11-мӗш', '11-мӗш');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12-мӗш', '12-мӗш');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13-мӗш', '13-мӗш');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14-мӗш', '14-мӗш');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15-мӗш', '15-мӗш');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16-мӗш', '16-мӗш');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17-мӗш', '17-мӗш');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18-мӗш', '18-мӗш');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19-мӗш', '19-мӗш');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20-мӗш', '20-мӗш');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21-мӗш', '21-мӗш');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22-мӗш', '22-мӗш');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23-мӗш', '23-мӗш');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24-мӗш', '24-мӗш');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25-мӗш', '25-мӗш');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26-мӗш', '26-мӗш');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27-мӗш', '27-мӗш');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28-мӗш', '28-мӗш');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29-мӗш', '29-мӗш');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30-мӗш', '30-мӗш');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31-мӗш', '31-мӗш');\n});\n\ntest('format month', function (assert) {\n    var expected = 'кӑрлач кӑр_нарӑс нар_пуш пуш_ака ака_май май_ҫӗртме ҫӗр_утӑ утӑ_ҫурла ҫур_авӑн авн_юпа юпа_чӳк чӳк_раштав раш'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'вырсарникун выр вр_тунтикун тун тн_ытларикун ытл ыт_юнкун юн юн_кӗҫнерникун кӗҫ кҫ_эрнекун эрн эр_шӑматкун шӑм шм'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'пӗр-ик ҫеккунт', '44 sekunder = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'пӗр минут',      '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'пӗр минут',      '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 минут',     '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 минут',    '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'пӗр сехет',       '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'пӗр сехет',       '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 сехет',       '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 сехет',       '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 сехет',      '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'пӗр кун',         '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'пӗр кун',         '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 кун',        '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'пӗр кун',         '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 кун',        '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 кун',       '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'пӗр уйӑх',       '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'пӗр уйӑх',       '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'пӗр уйӑх',       '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 уйӑх',      '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 уйӑх',      '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 уйӑх',      '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'пӗр уйӑх',       '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 уйӑх',      '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'пӗр ҫул',        '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 ҫул',       '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'пӗр ҫул',        '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 ҫул',       '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'пӗр-ик ҫеккунтран',  'prefix');\n    assert.equal(moment(0).from(30000), 'пӗр-ик ҫеккунт каялла', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'пӗр-ик ҫеккунт каялла',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'пӗр-ик ҫеккунтран', 'in a few seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), '5 кунран', 'in 5 days');\n    assert.equal(moment().add({h: 2}).fromNow(), '2 сехетрен', 'in 2 hours, the right suffix!');\n    assert.equal(moment().add({y: 3}).fromNow(), '3 ҫултан', 'in 3 years, the right suffix!');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n    assert.equal(moment(a).calendar(),                   'Паян 12:00 сехетре',     'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'Паян 12:25 сехетре',     'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'Паян 13:00 сехетре',     'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'Ыран 12:00 сехетре',     'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'Паян 11:00 сехетре',     'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'Ӗнер 12:00 сехетре',     'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('[Ҫитес] dddd LT [сехетре]'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[Ҫитес] dddd LT [сехетре]'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[Ҫитес] dddd LT [сехетре]'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('[Иртнӗ] dddd LT [сехетре]'),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[Иртнӗ] dddd LT [сехетре]'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[Иртнӗ] dddd LT [сехетре]'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\n// Monday is the first day of the week.\n// The week that contains Jan 1st is the first week of the year.\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2011, 11, 26]).format('w ww wo'), '1 01 1-мӗш', 'Dec 26 2011 should be week 1');\n    assert.equal(moment([2012,  0,  1]).format('w ww wo'), '1 01 1-мӗш', 'Jan  1 2012 should be week 1');\n    assert.equal(moment([2012,  0,  2]).format('w ww wo'), '2 02 2-мӗш', 'Jan  2 2012 should be week 2');\n    assert.equal(moment([2012,  0,  8]).format('w ww wo'), '2 02 2-мӗш', 'Jan  8 2012 should be week 2');\n    assert.equal(moment([2012,  0,  9]).format('w ww wo'), '3 03 3-мӗш', 'Jan  9 2012 should be week 3');\n});\n\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/test/locale/cy.js",
    "content": "import {localeModule, test} from '../qunit';\nimport moment from '../../moment';\nlocaleModule('cy');\n\ntest('parse', function (assert) {\n    var tests = 'Ionawr Ion_Chwefror Chwe_Mawrth Maw_Ebrill Ebr_Mai Mai_Mehefin Meh_Gorffennaf Gor_Awst Aws_Medi Med_Hydref Hyd_Tachwedd Tach_Rhagfyr Rhag'.split('_'),\n        i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, MMMM Do YYYY, h:mm:ss a',      'Dydd Sul, Chwefror 14eg 2010, 3:25:50 pm'],\n            ['ddd, hA',                            'Sul, 3PM'],\n            ['M Mo MM MMMM MMM',                   '2 2il 02 Chwefror Chwe'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14eg 14'],\n            ['d do dddd ddd dd',                   '0 0 Dydd Sul Sul Su'],\n            ['DDD DDDo DDDD',                      '45 45ain 045'],\n            ['w wo ww',                            '6 6ed 06'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'pm PM'],\n            ['[the] DDDo [day of the year]',       'the 45ain day of the year'],\n            ['LTS',                                '15:25:50'],\n            ['L',                                  '14/02/2010'],\n            ['LL',                                 '14 Chwefror 2010'],\n            ['LLL',                                '14 Chwefror 2010 15:25'],\n            ['LLLL',                               'Dydd Sul, 14 Chwefror 2010 15:25'],\n            ['l',                                  '14/2/2010'],\n            ['ll',                                 '14 Chwe 2010'],\n            ['lll',                                '14 Chwe 2010 15:25'],\n            ['llll',                               'Sul, 14 Chwe 2010 15:25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1af', '1af');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2il', '2il');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3ydd', '3ydd');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4ydd', '4ydd');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5ed', '5ed');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6ed', '6ed');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7ed', '7ed');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8fed', '8fed');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9fed', '9fed');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10fed', '10fed');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11eg', '11eg');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12fed', '12fed');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13eg', '13eg');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14eg', '14eg');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15fed', '15fed');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16eg', '16eg');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17eg', '17eg');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18fed', '18fed');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19eg', '19eg');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20fed', '20fed');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21ain', '21ain');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22ain', '22ain');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23ain', '23ain');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24ain', '24ain');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25ain', '25ain');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26ain', '26ain');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27ain', '27ain');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28ain', '28ain');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29ain', '29ain');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30ain', '30ain');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31ain', '31ain');\n});\n\ntest('format month', function (assert) {\n    var expected = 'Ionawr Ion_Chwefror Chwe_Mawrth Maw_Ebrill Ebr_Mai Mai_Mehefin Meh_Gorffennaf Gor_Awst Aws_Medi Med_Hydref Hyd_Tachwedd Tach_Rhagfyr Rhag'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'Dydd Sul Sul Su_Dydd Llun Llun Ll_Dydd Mawrth Maw Ma_Dydd Mercher Mer Me_Dydd Iau Iau Ia_Dydd Gwener Gwe Gw_Dydd Sadwrn Sad Sa'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'ychydig eiliadau', '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'munud',   '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'munud',   '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 munud',  '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 munud', '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'awr',    '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'awr',    '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 awr',    '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 awr',    '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 awr',   '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'diwrnod',      '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'diwrnod',      '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 diwrnod',     '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'diwrnod',      '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 diwrnod',     '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 diwrnod',    '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'mis',    '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'mis',    '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'mis',    '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 mis',   '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 mis',   '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 mis',   '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'mis',    '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 mis',   '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'blwyddyn',     '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 flynedd',    '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'blwyddyn',     '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 flynedd',    '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'mewn ychydig eiliadau', 'prefix');\n    assert.equal(moment(0).from(30000), 'ychydig eiliadau yn ôl', 'suffix');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'mewn ychydig eiliadau', 'in a few seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), 'mewn 5 diwrnod', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'Heddiw am 12:00',    'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'Heddiw am 12:25',    'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'Heddiw am 13:00',    'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'Yfory am 12:00',     'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'Heddiw am 11:00',    'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'Ddoe am 12:00',      'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('dddd [am] LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd [am] LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd [am] LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('dddd [diwethaf am] LT'),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd [diwethaf am] LT'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd [diwethaf am] LT'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2012, 0,  1]).format('w ww wo'), '52 52 52ain', 'Jan  1 2012 should be week 52');\n    assert.equal(moment([2012, 0,  2]).format('w ww wo'), '1 01 1af', 'Jan  2 2012 should be week 1');\n    assert.equal(moment([2012, 0,  8]).format('w ww wo'), '1 01 1af', 'Jan  8 2012 should be week 1');\n    assert.equal(moment([2012, 0,  9]).format('w ww wo'),   '2 02 2il', 'Jan  9 2012 should be week 2');\n    assert.equal(moment([2012, 0, 15]).format('w ww wo'),   '2 02 2il', 'Jan 15 2012 should be week 2');\n});\n\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/test/locale/da.js",
    "content": "import {localeModule, test} from '../qunit';\nimport moment from '../../moment';\nlocaleModule('da');\n\ntest('parse', function (assert) {\n    var tests = 'januar jan_februar feb_marts mar_april apr_maj maj_juni jun_juli jul_august aug_september sep_oktober okt_november nov_december dec'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd [den] Do MMMM YYYY, h:mm:ss a', 'søndag den 14. februar 2010, 3:25:50 pm'],\n            ['ddd hA',                             'søn 3PM'],\n            ['M Mo MM MMMM MMM',                   '2 2. 02 februar feb'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14. 14'],\n            ['d do dddd ddd dd',                   '0 0. søndag søn sø'],\n            ['DDD DDDo DDDD',                      '45 45. 045'],\n            ['w wo ww',                            '6 6. 06'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'pm PM'],\n            ['[den] DDDo [dag på året]',           'den 45. dag på året'],\n            ['LTS',                                '15:25:50'],\n            ['L',                                  '14/02/2010'],\n            ['LL',                                 '14. februar 2010'],\n            ['LLL',                                '14. februar 2010 15:25'],\n            ['LLLL',                               'søndag d. 14. februar 2010 kl. 15:25'],\n            ['l',                                  '14/2/2010'],\n            ['ll',                                 '14. feb 2010'],\n            ['lll',                                '14. feb 2010 15:25'],\n            ['llll',                               'søn d. 14. feb 2010 kl. 15:25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1.', '1.');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2.', '2.');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3.', '3.');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4.', '4.');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5.', '5.');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6.', '6.');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7.', '7.');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8.', '8.');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9.', '9.');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10.', '10.');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11.', '11.');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12.', '12.');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13.', '13.');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14.', '14.');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15.', '15.');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16.', '16.');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17.', '17.');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18.', '18.');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19.', '19.');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20.', '20.');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21.', '21.');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22.', '22.');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23.', '23.');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24.', '24.');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25.', '25.');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26.', '26.');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27.', '27.');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28.', '28.');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29.', '29.');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30.', '30.');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31.', '31.');\n});\n\ntest('format month', function (assert) {\n    var expected = 'januar jan_februar feb_marts mar_april apr_maj maj_juni jun_juli jul_august aug_september sep_oktober okt_november nov_december dec'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'søndag søn sø_mandag man ma_tirsdag tir ti_onsdag ons on_torsdag tor to_fredag fre fr_lørdag lør lø'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'få sekunder', '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'et minut',    '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'et minut',    '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 minutter',  '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 minutter', '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'en time',     '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'en time',     '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 timer',     '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 timer',     '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 timer',    '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'en dag',      '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'en dag',      '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 dage',      '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'en dag',      '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 dage',      '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 dage',     '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'en måned',    '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'en måned',    '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'en måned',    '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 måneder',   '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 måneder',   '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 måneder',   '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'en måned',    '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 måneder',   '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'et år',       '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 år',        '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'et år',       '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 år',        '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'om få sekunder',  'prefix');\n    assert.equal(moment(0).from(30000), 'få sekunder siden', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'få sekunder siden',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'om få sekunder', 'in a few seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), 'om 5 dage', 'in 5 days');\n});\n\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'i dag kl. 12:00',    'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'i dag kl. 12:25',    'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'i dag kl. 13:00',    'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'i morgen kl. 12:00', 'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'i dag kl. 11:00',    'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'i går kl. 12:00',    'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('på dddd [kl.] LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('på dddd [kl.] LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('på dddd [kl.] LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('[i] dddd[s kl.] LT'),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[i] dddd[s kl.] LT'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[i] dddd[s kl.] LT'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2012, 0,  1]).format('w ww wo'), '52 52 52.', 'Jan  1 2012 should be week 52');\n    assert.equal(moment([2012, 0,  2]).format('w ww wo'),   '1 01 1.', 'Jan  2 2012 should be week 1');\n    assert.equal(moment([2012, 0,  8]).format('w ww wo'),   '1 01 1.', 'Jan  8 2012 should be week 1');\n    assert.equal(moment([2012, 0,  9]).format('w ww wo'),   '2 02 2.', 'Jan  9 2012 should be week 2');\n    assert.equal(moment([2012, 0, 15]).format('w ww wo'),   '2 02 2.', 'Jan 15 2012 should be week 2');\n});\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/test/locale/de-at.js",
    "content": "import {localeModule, test} from '../qunit';\nimport moment from '../../moment';\nlocaleModule('de-at');\n\ntest('parse', function (assert) {\n    var tests = 'Jänner Jän._Februar Febr._März Mrz._April Apr._Mai Mai_Juni Jun._Juli Jul._August Aug._September Sept._Oktober Okt._November Nov._Dezember Dez.'.split('_'), i;\n\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, Do MMMM YYYY, h:mm:ss a', 'Sonntag, 14. Februar 2010, 3:25:50 pm'],\n            ['ddd, hA', 'So., 3PM'],\n            ['M Mo MM MMMM MMM', '2 2. 02 Februar Febr.'],\n            ['YYYY YY', '2010 10'],\n            ['D Do DD', '14 14. 14'],\n            ['d do dddd ddd dd', '0 0. Sonntag So. So'],\n            ['DDD DDDo DDDD', '45 45. 045'],\n            ['w wo ww', '6 6. 06'],\n            ['h hh', '3 03'],\n            ['H HH', '15 15'],\n            ['m mm', '25 25'],\n            ['s ss', '50 50'],\n            ['a A', 'pm PM'],\n            ['[the] DDDo [day of the year]', 'the 45. day of the year'],\n            ['LTS', '15:25:50'],\n            ['L', '14.02.2010'],\n            ['LL', '14. Februar 2010'],\n            ['LLL', '14. Februar 2010 15:25'],\n            ['LLLL', 'Sonntag, 14. Februar 2010 15:25'],\n            ['l', '14.2.2010'],\n            ['ll', '14. Febr. 2010'],\n            ['lll', '14. Febr. 2010 15:25'],\n            ['llll', 'So., 14. Febr. 2010 15:25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1.', '1.');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2.', '2.');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3.', '3.');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4.', '4.');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5.', '5.');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6.', '6.');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7.', '7.');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8.', '8.');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9.', '9.');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10.', '10.');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11.', '11.');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12.', '12.');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13.', '13.');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14.', '14.');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15.', '15.');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16.', '16.');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17.', '17.');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18.', '18.');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19.', '19.');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20.', '20.');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21.', '21.');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22.', '22.');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23.', '23.');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24.', '24.');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25.', '25.');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26.', '26.');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27.', '27.');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28.', '28.');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29.', '29.');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30.', '30.');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31.', '31.');\n});\n\ntest('format month', function (assert) {\n    var expected = 'Jänner Jän._Februar Febr._März Mrz._April Apr._Mai Mai_Juni Jun._Juli Jul._August Aug._September Sept._Oktober Okt._November Nov._Dezember Dez.'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'Sonntag So. So_Montag Mo. Mo_Dienstag Di. Di_Mittwoch Mi. Mi_Donnerstag Do. Do_Freitag Fr. Fr_Samstag Sa. Sa'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true), 'ein paar Sekunden', '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true), 'eine Minute', '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true), 'eine Minute', '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true), '2 Minuten', '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true), '44 Minuten', '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true), 'eine Stunde', '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true), 'eine Stunde', '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true), '2 Stunden', '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true), '5 Stunden', '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true), '21 Stunden', '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true), 'ein Tag', '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true), 'ein Tag', '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true), '2 Tage', '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true), 'ein Tag', '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true), '5 Tage', '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true), '25 Tage', '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true), 'ein Monat', '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true), 'ein Monat', '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true), '2 Monate', '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true), '2 Monate', '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true), '3 Monate', '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true), 'ein Monat', '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true), '5 Monate', '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'ein Jahr', '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 Jahre', '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true), 'ein Jahr', '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true), '5 Jahre', '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'in ein paar Sekunden', 'prefix');\n    assert.equal(moment(0).from(30000), 'vor ein paar Sekunden', 'suffix');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'in ein paar Sekunden', 'in a few seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), 'in 5 Tagen', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                  'heute um 12:00 Uhr',   'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),     'heute um 12:25 Uhr',   'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),      'heute um 13:00 Uhr',   'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),      'morgen um 12:00 Uhr',  'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(), 'heute um 11:00 Uhr',   'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(), 'gestern um 12:00 Uhr', 'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(), m.format('dddd [um] LT [Uhr]'), 'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(), m.format('dddd [um] LT [Uhr]'), 'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(), m.format('dddd [um] LT [Uhr]'), 'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(), m.format('[letzten] dddd [um] LT [Uhr]'), 'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(), m.format('[letzten] dddd [um] LT [Uhr]'), 'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(), m.format('[letzten] dddd [um] LT [Uhr]'), 'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '1 week ago');\n    assert.equal(weeksFromNow.calendar(), weeksFromNow.format('L'), 'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(), weeksFromNow.format('L'), 'in 2 weeks');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2012, 0, 1]).format('w ww wo'), '52 52 52.', 'Jan  1 2012 should be week 52');\n    assert.equal(moment([2012, 0, 2]).format('w ww wo'), '1 01 1.', 'Jan  2 2012 should be week 1');\n    assert.equal(moment([2012, 0, 8]).format('w ww wo'), '1 01 1.', 'Jan  8 2012 should be week 1');\n    assert.equal(moment([2012, 0, 9]).format('w ww wo'), '2 02 2.', 'Jan  9 2012 should be week 2');\n    assert.equal(moment([2012, 0, 15]).format('w ww wo'), '2 02 2.', 'Jan 15 2012 should be week 2');\n});\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/test/locale/de-ch.js",
    "content": "import {localeModule, test} from '../qunit';\nimport moment from '../../moment';\nlocaleModule('de-ch');\n\ntest('parse', function (assert) {\n    var tests = 'Januar Jan._Februar Febr._März März_April April_Mai Mai_Juni Juni_Juli Juli_August Aug._September Sept._Oktober Okt._November Nov._Dezember Dez.'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, Do MMMM YYYY, h.mm.ss a',      'Sonntag, 14. Februar 2010, 3.25.50 pm'],\n            ['ddd, hA',                            'So, 3PM'],\n            ['M Mo MM MMMM MMM',                   '2 2. 02 Februar Febr.'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14. 14'],\n            ['d do dddd ddd dd',                   '0 0. Sonntag So So'],\n            ['DDD DDDo DDDD',                      '45 45. 045'],\n            ['w wo ww',                            '6 6. 06'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'pm PM'],\n            ['[the] DDDo [day of the year]',       'the 45. day of the year'],\n            ['LTS',                                '15.25.50'],\n            ['L',                                  '14.02.2010'],\n            ['LL',                                 '14. Februar 2010'],\n            ['LLL',                                '14. Februar 2010 15.25'],\n            ['LLLL',                               'Sonntag, 14. Februar 2010 15.25'],\n            ['l',                                  '14.2.2010'],\n            ['ll',                                 '14. Febr. 2010'],\n            ['lll',                                '14. Febr. 2010 15.25'],\n            ['llll',                               'So, 14. Febr. 2010 15.25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1.', '1.');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2.', '2.');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3.', '3.');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4.', '4.');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5.', '5.');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6.', '6.');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7.', '7.');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8.', '8.');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9.', '9.');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10.', '10.');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11.', '11.');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12.', '12.');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13.', '13.');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14.', '14.');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15.', '15.');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16.', '16.');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17.', '17.');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18.', '18.');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19.', '19.');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20.', '20.');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21.', '21.');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22.', '22.');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23.', '23.');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24.', '24.');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25.', '25.');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26.', '26.');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27.', '27.');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28.', '28.');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29.', '29.');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30.', '30.');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31.', '31.');\n});\n\ntest('format month', function (assert) {\n    var expected = 'Januar Jan._Februar Febr._März März_April April_Mai Mai_Juni Juni_Juli Juli_August Aug._September Sept._Oktober Okt._November Nov._Dezember Dez.'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'Sonntag So So_Montag Mo Mo_Dienstag Di Di_Mittwoch Mi Mi_Donnerstag Do Do_Freitag Fr Fr_Samstag Sa Sa'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'ein paar Sekunden',  '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'eine Minute',       '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'eine Minute',       '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 Minuten',          '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 Minuten',         '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'eine Stunde',       '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'eine Stunde',       '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 Stunden',          '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 Stunden',          '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 Stunden',         '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'ein Tag',          '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'ein Tag',          '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 Tage',            '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'ein Tag',          '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 Tage',            '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 Tage',           '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'ein Monat',        '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'ein Monat',        '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'ein Monat',        '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 Monate',          '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 Monate',          '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 Monate',          '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'ein Monat',        '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 Monate',          '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'ein Jahr',         '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 Jahre',           '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'ein Jahr',         '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 Jahre',           '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'in ein paar Sekunden', 'prefix');\n    assert.equal(moment(0).from(30000), 'vor ein paar Sekunden', 'suffix');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'in ein paar Sekunden', 'in a few seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), 'in 5 Tagen', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'heute um 12.00 Uhr',   'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'heute um 12.25 Uhr',   'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'heute um 13.00 Uhr',   'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'morgen um 12.00 Uhr',  'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'heute um 11.00 Uhr',   'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'gestern um 12.00 Uhr', 'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('dddd [um] LT [Uhr]'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd [um] LT [Uhr]'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd [um] LT [Uhr]'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('[letzten] dddd [um] LT [Uhr]'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[letzten] dddd [um] LT [Uhr]'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[letzten] dddd [um] LT [Uhr]'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2012, 0,  1]).format('w ww wo'), '52 52 52.', 'Jan  1 2012 should be week 52');\n    assert.equal(moment([2012, 0,  2]).format('w ww wo'),   '1 01 1.', 'Jan  2 2012 should be week 1');\n    assert.equal(moment([2012, 0,  8]).format('w ww wo'),   '1 01 1.', 'Jan  8 2012 should be week 1');\n    assert.equal(moment([2012, 0,  9]).format('w ww wo'),   '2 02 2.', 'Jan  9 2012 should be week 2');\n    assert.equal(moment([2012, 0, 15]).format('w ww wo'),   '2 02 2.', 'Jan 15 2012 should be week 2');\n});\n\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/test/locale/de.js",
    "content": "import {localeModule, test} from '../qunit';\nimport moment from '../../moment';\nlocaleModule('de');\n\ntest('parse', function (assert) {\n    var tests = 'Januar Jan._Februar Febr._März Mrz._April Apr._Mai Mai_Juni Jun._Juli Jul._August Aug._September Sept._Oktober Okt._November Nov._Dezember Dez.'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, Do MMMM YYYY, h:mm:ss a',      'Sonntag, 14. Februar 2010, 3:25:50 pm'],\n            ['ddd, hA',                            'So., 3PM'],\n            ['M Mo MM MMMM MMM',                   '2 2. 02 Februar Febr.'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14. 14'],\n            ['d do dddd ddd dd',                   '0 0. Sonntag So. So'],\n            ['DDD DDDo DDDD',                      '45 45. 045'],\n            ['w wo ww',                            '6 6. 06'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'pm PM'],\n            ['[the] DDDo [day of the year]',       'the 45. day of the year'],\n            ['LTS',                                '15:25:50'],\n            ['L',                                  '14.02.2010'],\n            ['LL',                                 '14. Februar 2010'],\n            ['LLL',                                '14. Februar 2010 15:25'],\n            ['LLLL',                               'Sonntag, 14. Februar 2010 15:25'],\n            ['l',                                  '14.2.2010'],\n            ['ll',                                 '14. Febr. 2010'],\n            ['lll',                                '14. Febr. 2010 15:25'],\n            ['llll',                               'So., 14. Febr. 2010 15:25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1.', '1.');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2.', '2.');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3.', '3.');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4.', '4.');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5.', '5.');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6.', '6.');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7.', '7.');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8.', '8.');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9.', '9.');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10.', '10.');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11.', '11.');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12.', '12.');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13.', '13.');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14.', '14.');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15.', '15.');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16.', '16.');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17.', '17.');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18.', '18.');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19.', '19.');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20.', '20.');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21.', '21.');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22.', '22.');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23.', '23.');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24.', '24.');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25.', '25.');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26.', '26.');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27.', '27.');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28.', '28.');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29.', '29.');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30.', '30.');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31.', '31.');\n});\n\ntest('format month', function (assert) {\n    var expected = 'Januar Jan._Februar Febr._März Mrz._April Apr._Mai Mai_Juni Jun._Juli Jul._August Aug._September Sept._Oktober Okt._November Nov._Dezember Dez.'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'Sonntag So. So_Montag Mo. Mo_Dienstag Di. Di_Mittwoch Mi. Mi_Donnerstag Do. Do_Freitag Fr. Fr_Samstag Sa. Sa'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'ein paar Sekunden',  '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'eine Minute',       '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'eine Minute',       '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 Minuten',          '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 Minuten',         '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'eine Stunde',       '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'eine Stunde',       '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 Stunden',          '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 Stunden',          '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 Stunden',         '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'ein Tag',          '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'ein Tag',          '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 Tage',            '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'ein Tag',          '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 Tage',            '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 Tage',           '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'ein Monat',        '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'ein Monat',        '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'ein Monat',        '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 Monate',          '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 Monate',          '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 Monate',          '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'ein Monat',        '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 Monate',          '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'ein Jahr',         '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 Jahre',           '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'ein Jahr',         '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 Jahre',           '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'in ein paar Sekunden', 'prefix');\n    assert.equal(moment(0).from(30000), 'vor ein paar Sekunden', 'suffix');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'in ein paar Sekunden', 'in a few seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), 'in 5 Tagen', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'heute um 12:00 Uhr',   'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'heute um 12:25 Uhr',   'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'heute um 13:00 Uhr',   'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'morgen um 12:00 Uhr',  'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'heute um 11:00 Uhr',   'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'gestern um 12:00 Uhr', 'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('dddd [um] LT [Uhr]'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd [um] LT [Uhr]'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd [um] LT [Uhr]'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('[letzten] dddd [um] LT [Uhr]'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[letzten] dddd [um] LT [Uhr]'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[letzten] dddd [um] LT [Uhr]'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2012, 0,  1]).format('w ww wo'), '52 52 52.', 'Jan  1 2012 should be week 52');\n    assert.equal(moment([2012, 0,  2]).format('w ww wo'),   '1 01 1.', 'Jan  2 2012 should be week 1');\n    assert.equal(moment([2012, 0,  8]).format('w ww wo'),   '1 01 1.', 'Jan  8 2012 should be week 1');\n    assert.equal(moment([2012, 0,  9]).format('w ww wo'),   '2 02 2.', 'Jan  9 2012 should be week 2');\n    assert.equal(moment([2012, 0, 15]).format('w ww wo'),   '2 02 2.', 'Jan 15 2012 should be week 2');\n});\n\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/test/locale/dv.js",
    "content": "import {localeModule, test} from '../qunit';\nimport moment from '../../moment';\nlocaleModule('dv');\n\ntest('parse', function (assert) {\n    var i,\n        tests = [\n            'ޖެނުއަރީ',\n            'ފެބްރުއަރީ',\n            'މާރިޗު',\n            'އޭޕްރީލު',\n            'މޭ',\n            'ޖޫން',\n            'ޖުލައި',\n            'އޯގަސްޓު',\n            'ސެޕްޓެމްބަރު',\n            'އޮކްޓޯބަރު',\n            'ނޮވެމްބަރު',\n            'ޑިސެމްބަރު'\n        ];\n\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n\n    for (i = 0; i < 12; i++) {\n        equalTest(tests[i], 'MMM', i);\n        equalTest(tests[i], 'MMMM', i);\n        equalTest(tests[i].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, MMMM Do YYYY, h:mm:ss a',      'އާދިއްތަ، ފެބްރުއަރީ 14 2010، 3:25:50 މފ'],\n            ['ddd, hA',                            'އާދިއްތަ، 3މފ'],\n            ['M Mo MM MMMM MMM',                   '2 2 02 ފެބްރުއަރީ ފެބްރުއަރީ'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14 14'],\n            ['d do dddd ddd dd',                   '0 0 އާދިއްތަ އާދިއްތަ އާދި'],\n            ['DDD DDDo DDDD',                      '45 45 045'],\n            ['w wo ww',                            '8 8 08'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'މފ މފ'],\n            ['LTS',                                '15:25:50'],\n            ['L',                                  '14/2/2010'],\n            ['LL',                                 '14 ފެބްރުއަރީ 2010'],\n            ['LLL',                                '14 ފެބްރުއަރީ 2010 15:25'],\n            ['LLLL',                               'އާދިއްތަ 14 ފެބްރުއަރީ 2010 15:25'],\n            ['l',                                  '14/2/2010'],\n            ['ll',                                 '14 ފެބްރުއަރީ 2010'],\n            ['lll',                                '14 ފެބްރުއަރީ 2010 15:25'],\n            ['llll',                               'އާދިއްތަ 14 ފެބްރުއަރީ 2010 15:25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format month', function (assert) {\n    var i,\n        expected = [\n            'ޖެނުއަރީ',\n            'ފެބްރުއަރީ',\n            'މާރިޗު',\n            'އޭޕްރީލު',\n            'މޭ',\n            'ޖޫން',\n            'ޖުލައި',\n            'އޯގަސްޓު',\n            'ސެޕްޓެމްބަރު',\n            'އޮކްޓޯބަރު',\n            'ނޮވެމްބަރު',\n            'ޑިސެމްބަރު'\n        ];\n\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM'), expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var i,\n        expected = [\n            'އާދިއްތަ',\n            'ހޯމަ',\n            'އަންގާރަ',\n            'ބުދަ',\n            'ބުރާސްފަތި',\n            'ހުކުރު',\n            'ހޮނިހިރު'\n        ];\n\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd'), expected[i]);\n    }\n});\n\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'ސިކުންތުކޮޅެއް',  '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'މިނިޓެއް',        '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'މިނިޓެއް',        '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  'މިނިޓު 2',        '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  'މިނިޓު 44',       '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'ގަޑިއިރެއް',      '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'ގަޑިއިރެއް',      '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  'ގަޑިއިރު 2',      '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   'ގަޑިއިރު 5',      '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  'ގަޑިއިރު 21',     '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'ދުވަހެއް',        '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'ދުވަހެއް',        '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  'ދުވަސް 2',        '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'ދުވަހެއް',        '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   'ދުވަސް 5',        '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  'ދުވަސް 25',       '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'މަހެއް',          '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'މަހެއް',          '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'މަހެއް',          '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  'މަސް 2',          '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  'މަސް 2',          '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  'މަސް 3',          '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'މަހެއް',          '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   'މަސް 5',          '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'އަހަރެއް',        '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), 'އަހަރު 2',        '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'އަހަރެއް',        '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   'އަހަރު 5',        '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'ތެރޭގައި ސިކުންތުކޮޅެއް', 'prefix');\n    assert.equal(moment(0).from(30000), 'ކުރިން ސިކުންތުކޮޅެއް', 'suffix');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'ތެރޭގައި ސިކުންތުކޮޅެއް', 'in a few seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), 'ތެރޭގައި ދުވަސް 5', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'މިއަދު 12:00',  'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'މިއަދު 12:25',  'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'މިއަދު 13:00',  'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'މާދަމާ 12:00',  'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'މިއަދު 11:00',  'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'އިއްޔެ 12:00',  'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('dddd LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('[ފާއިތުވި] dddd LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[ފާއިތުވި] dddd LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[ފާއިތުވި] dddd LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2012, 0,  1]).format('w ww wo'),   '1 01 1', 'Jan  1 2012 should be week 1');\n    assert.equal(moment([2012, 0,  2]).format('w ww wo'),   '1 01 1', 'Jan  2 2012 should be week 1');\n    assert.equal(moment([2012, 0,  8]).format('w ww wo'),   '2 02 2', 'Jan  8 2012 should be week 2');\n    assert.equal(moment([2012, 0,  9]).format('w ww wo'),   '2 02 2', 'Jan  9 2012 should be week 2');\n    assert.equal(moment([2012, 0, 15]).format('w ww wo'),   '3 03 3', 'Jan 15 2012 should be week 3');\n});\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/test/locale/el.js",
    "content": "import {localeModule, test} from '../qunit';\nimport moment from '../../moment';\nlocaleModule('el');\n\ntest('parse', function (assert) {\n    var i,\n        tests = 'Ιανουάριος Ιαν_Φεβρουάριος Φεβ_Μάρτιος Μαρ_Απρίλιος Απρ_Μάιος Μαϊ_Ιούνιος Ιουν_Ιούλιος Ιουλ_Αύγουστος Αυγ_Σεπτέμβριος Σεπ_Οκτώβριος Οκτ_Νοέμβριος Νοε_Δεκέμβριος Δεκ'.split('_');\n\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('parse meridiem', function (assert) {\n    var i,\n        b = moment(),\n        meridiemTests = [\n            // h a patterns, expected hours, isValid\n            ['10 πμ',   10, true],\n            ['10 μμ',   22, true],\n            ['10 π.μ.', 10, true],\n            ['10 μ.μ.', 22, true],\n            ['10 π',    10, true],\n            ['10 μ',    22, true],\n            ['10 ΠΜ',   10, true],\n            ['10 ΜΜ',   22, true],\n            ['10 Π.Μ.', 10, true],\n            ['10 Μ.Μ.', 22, true],\n            ['10 Π',    10, true],\n            ['10 Μ',    22, true],\n            ['10 am',   10, false],\n            ['10 pm',   10, false]\n        ],\n        parsed;\n\n    // test that a formatted moment including meridiem string can be parsed back to the same moment\n    assert.ok(b.isSame(moment(b.format('h:mm:ss a'), 'h:mm:ss a', 'el', true), 'seconds'), b.format('h:mm:ss a') + ' should be equal to ' + moment(b.format('h:mm:ss a'), 'h:mm:ss a', 'el', true).format('h:mm:ss a'));\n\n    // test that a formatted moment having a meridiem string can be parsed with strict flag\n    assert.ok(moment(b.format('h:mm:ss a'), 'h:mm:ss a', 'el', true).isValid(), b.format('h:mm:ss a') + ' should be parsed as valid');\n\n    for (i = 0; i < meridiemTests.length; i++) {\n        parsed = moment(meridiemTests[i][0], 'h a', 'el', true);\n        assert.equal(parsed.isValid(), meridiemTests[i][2], 'validity for ' + meridiemTests[i][0]);\n        if (parsed.isValid()) {\n            assert.equal(parsed.hours(), meridiemTests[i][1], 'hours for ' + meridiemTests[i][0]);\n        }\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, MMMM Do YYYY, h:mm:ss a',      'Κυριακή, Φεβρουάριος 14η 2010, 3:25:50 μμ'],\n            ['dddd, D MMMM YYYY, h:mm:ss a',       'Κυριακή, 14 Φεβρουαρίου 2010, 3:25:50 μμ'],\n            ['ddd, hA',                            'Κυρ, 3ΜΜ'],\n            ['dddd, MMMM YYYY',                    'Κυριακή, Φεβρουάριος 2010'],\n            ['M Mo MM MMMM MMM',                   '2 2η 02 Φεβρουάριος Φεβ'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14η 14'],\n            ['d do dddd ddd dd',                   '0 0η Κυριακή Κυρ Κυ'],\n            ['DDD DDDo DDDD',                      '45 45η 045'],\n            ['w wo ww',                            '6 6η 06'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'μμ ΜΜ'],\n            ['[the] DDDo [day of the year]',       'the 45η day of the year'],\n            ['LTS',                                '3:25:50 ΜΜ'],\n            ['L',                                  '14/02/2010'],\n            ['LL',                                 '14 Φεβρουαρίου 2010'],\n            ['LLL',                                '14 Φεβρουαρίου 2010 3:25 ΜΜ'],\n            ['LLLL',                               'Κυριακή, 14 Φεβρουαρίου 2010 3:25 ΜΜ'],\n            ['l',                                  '14/2/2010'],\n            ['ll',                                 '14 Φεβ 2010'],\n            ['lll',                                '14 Φεβ 2010 3:25 ΜΜ'],\n            ['llll',                               'Κυρ, 14 Φεβ 2010 3:25 ΜΜ']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1η', '1η');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2η', '2η');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3η', '3η');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4η', '4η');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5η', '5η');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6η', '6η');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7η', '7η');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8η', '8η');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9η', '9η');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10η', '10η');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11η', '11η');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12η', '12η');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13η', '13η');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14η', '14η');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15η', '15η');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16η', '16η');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17η', '17η');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18η', '18η');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19η', '19η');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20η', '20η');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21η', '21η');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22η', '22η');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23η', '23η');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24η', '24η');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25η', '25η');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26η', '26η');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27η', '27η');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28η', '28η');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29η', '29η');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30η', '30η');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31η', '31η');\n});\n\ntest('format month', function (assert) {\n    var i,\n        expected = 'Ιανουάριος Ιαν_Φεβρουάριος Φεβ_Μάρτιος Μαρ_Απρίλιος Απρ_Μάιος Μαϊ_Ιούνιος Ιουν_Ιούλιος Ιουλ_Αύγουστος Αυγ_Σεπτέμβριος Σεπ_Οκτώβριος Οκτ_Νοέμβριος Νοε_Δεκέμβριος Δεκ'.split('_');\n\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var i,\n        expected = 'Κυριακή Κυρ Κυ_Δευτέρα Δευ Δε_Τρίτη Τρι Τρ_Τετάρτη Τετ Τε_Πέμπτη Πεμ Πε_Παρασκευή Παρ Πα_Σάββατο Σαβ Σα'.split('_');\n\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'λίγα δευτερόλεπτα',   '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'ένα λεπτό',           '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'ένα λεπτό',           '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 λεπτά',             '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 λεπτά',            '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'μία ώρα',             '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'μία ώρα',             '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 ώρες',              '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 ώρες',              '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 ώρες',             '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'μία μέρα',            '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'μία μέρα',            '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 μέρες',             '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'μία μέρα',            '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 μέρες',             '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 μέρες',            '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'ένας μήνας',          '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'ένας μήνας',          '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'ένας μήνας',          '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 μήνες',             '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 μήνες',             '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 μήνες',             '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'ένας μήνας',          '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 μήνες',             '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'ένας χρόνος',         '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 χρόνια',            '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'ένας χρόνος',         '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 χρόνια',            '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'σε λίγα δευτερόλεπτα',  'prefix');\n    assert.equal(moment(0).from(30000), 'λίγα δευτερόλεπτα πριν', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'λίγα δευτερόλεπτα πριν',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'σε λίγα δευτερόλεπτα', 'in a few seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), 'σε 5 μέρες', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'Σήμερα στις 12:00 ΜΜ',     'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'Σήμερα στις 12:25 ΜΜ',     'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'Σήμερα στη 1:00 ΜΜ',      'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'Αύριο στις 12:00 ΜΜ',      'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'Σήμερα στις 11:00 ΠΜ',      'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'Χθες στις 12:00 ΜΜ',       'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('dddd [' + (m.hours() % 12 === 1 ? 'στη' : 'στις') + '] LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd [στις] LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd [στις] LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m, dayString;\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        dayString = m.day() === 6 ? '[το προηγούμενο Σάββατο]' : '[την προηγούμενη] dddd';\n        assert.equal(m.calendar(),       m.format(dayString + ' [' + (m.hours() % 12 === 1 ? 'στη' : 'στις') + '] LT'),  'Today - ' + i + ' days current time');\n        m.hours(1).minutes(30).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format(dayString + ' [στη] LT'),  'Today - ' + i + ' days one o clock');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format(dayString + ' [στις] LT'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format(dayString + ' [στις] LT'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('weeks year starting sunday format', function (assert) {\n    assert.equal(moment([2012, 0,  1]).format('w ww wo'), '52 52 52η', 'Jan  1 2012 should be week 52');\n    assert.equal(moment([2012, 0,  7]).format('w ww wo'),   '1 01 1η', 'Jan  7 2012 should be week 1');\n    assert.equal(moment([2012, 0,  8]).format('w ww wo'),   '1 01 1η', 'Jan  8 2012 should be week 1');\n    assert.equal(moment([2012, 0, 14]).format('w ww wo'),   '2 02 2η', 'Jan 14 2012 should be week 2');\n    assert.equal(moment([2012, 0, 15]).format('w ww wo'),   '2 02 2η', 'Jan 15 2012 should be week 2');\n});\n\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/test/locale/en-au.js",
    "content": "import {localeModule, test} from '../qunit';\nimport moment from '../../moment';\nlocaleModule('en-au');\n\ntest('parse', function (assert) {\n    var tests = 'January Jan_February Feb_March Mar_April Apr_May May_June Jun_July Jul_August Aug_September Sep_October Oct_November Nov_December Dec'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, MMMM Do YYYY, h:mm:ss a',      'Sunday, February 14th 2010, 3:25:50 pm'],\n            ['ddd, hA',                            'Sun, 3PM'],\n            ['M Mo MM MMMM MMM',                   '2 2nd 02 February Feb'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14th 14'],\n            ['d do dddd ddd dd',                   '0 0th Sunday Sun Su'],\n            ['DDD DDDo DDDD',                      '45 45th 045'],\n            ['w wo ww',                            '6 6th 06'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'pm PM'],\n            ['[the] DDDo [day of the year]',       'the 45th day of the year'],\n            ['LTS',                                '3:25:50 PM'],\n            ['L',                                  '14/02/2010'],\n            ['LL',                                 '14 February 2010'],\n            ['LLL',                                '14 February 2010 3:25 PM'],\n            ['LLLL',                               'Sunday, 14 February 2010 3:25 PM'],\n            ['l',                                  '14/2/2010'],\n            ['ll',                                 '14 Feb 2010'],\n            ['lll',                                '14 Feb 2010 3:25 PM'],\n            ['llll',                               'Sun, 14 Feb 2010 3:25 PM']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1st', '1st');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2nd', '2nd');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3rd', '3rd');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4th', '4th');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5th', '5th');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6th', '6th');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7th', '7th');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8th', '8th');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9th', '9th');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10th', '10th');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11th', '11th');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12th', '12th');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13th', '13th');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14th', '14th');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15th', '15th');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16th', '16th');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17th', '17th');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18th', '18th');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19th', '19th');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20th', '20th');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21st', '21st');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22nd', '22nd');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23rd', '23rd');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24th', '24th');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25th', '25th');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26th', '26th');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27th', '27th');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28th', '28th');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29th', '29th');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30th', '30th');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31st', '31st');\n});\n\ntest('format month', function (assert) {\n    var expected = 'January Jan_February Feb_March Mar_April Apr_May May_June Jun_July Jul_August Aug_September Sep_October Oct_November Nov_December Dec'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'Sunday Sun Su_Monday Mon Mo_Tuesday Tue Tu_Wednesday Wed We_Thursday Thu Th_Friday Fri Fr_Saturday Sat Sa'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'a few seconds', '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'a minute',      '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'a minute',      '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 minutes',     '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 minutes',    '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'an hour',       '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'an hour',       '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 hours',       '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 hours',       '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 hours',      '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'a day',         '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'a day',         '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 days',        '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'a day',         '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 days',        '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 days',       '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'a month',       '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'a month',       '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'a month',       '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 months',      '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 months',      '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 months',      '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'a month',       '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 months',      '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'a year',        '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 years',       '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'a year',        '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 years',       '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'in a few seconds',  'prefix');\n    assert.equal(moment(0).from(30000), 'a few seconds ago', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'a few seconds ago',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'in a few seconds', 'in a few seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), 'in 5 days', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'Today at 12:00 PM',     'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'Today at 12:25 PM',     'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'Today at 1:00 PM',      'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'Tomorrow at 12:00 PM',  'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'Today at 11:00 AM',     'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'Yesterday at 12:00 PM', 'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('dddd [at] LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd [at] LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd [at] LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('[Last] dddd [at] LT'),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[Last] dddd [at] LT'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[Last] dddd [at] LT'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2012, 0,  1]).format('w ww wo'), '52 52 52nd', 'Jan  1 2012 should be week 52');\n    assert.equal(moment([2012, 0,  2]).format('w ww wo'),   '1 01 1st', 'Jan  2 2012 should be week 1');\n    assert.equal(moment([2012, 0,  8]).format('w ww wo'),   '1 01 1st', 'Jan  8 2012 should be week 1');\n    assert.equal(moment([2012, 0,  9]).format('w ww wo'),   '2 02 2nd', 'Jan  9 2012 should be week 2');\n    assert.equal(moment([2012, 0, 15]).format('w ww wo'),   '2 02 2nd', 'Jan 15 2012 should be week 2');\n});\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/test/locale/en-ca.js",
    "content": "import {localeModule, test} from '../qunit';\nimport moment from '../../moment';\nlocaleModule('en-ca');\n\ntest('parse', function (assert) {\n    var i,\n        tests = 'January Jan_February Feb_March Mar_April Apr_May May_June Jun_July Jul_August Aug_September Sep_October Oct_November Nov_December Dec'.split('_');\n\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, MMMM Do YYYY, h:mm:ss a',      'Sunday, February 14th 2010, 3:25:50 pm'],\n            ['ddd, hA',                            'Sun, 3PM'],\n            ['M Mo MM MMMM MMM',                   '2 2nd 02 February Feb'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14th 14'],\n            ['d do dddd ddd dd',                   '0 0th Sunday Sun Su'],\n            ['DDD DDDo DDDD',                      '45 45th 045'],\n            ['w wo ww',                            '8 8th 08'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'pm PM'],\n            ['[the] DDDo [day of the year]',       'the 45th day of the year'],\n            ['L',                                  '2010-02-14'],\n            ['LTS',                                '3:25:50 PM'],\n            ['LL',                                 'February 14, 2010'],\n            ['LLL',                                'February 14, 2010 3:25 PM'],\n            ['LLLL',                               'Sunday, February 14, 2010 3:25 PM'],\n            ['l',                                  '2010-2-14'],\n            ['ll',                                 'Feb 14, 2010'],\n            ['lll',                                'Feb 14, 2010 3:25 PM'],\n            ['llll',                               'Sun, Feb 14, 2010 3:25 PM']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1st', '1st');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2nd', '2nd');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3rd', '3rd');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4th', '4th');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5th', '5th');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6th', '6th');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7th', '7th');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8th', '8th');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9th', '9th');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10th', '10th');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11th', '11th');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12th', '12th');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13th', '13th');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14th', '14th');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15th', '15th');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16th', '16th');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17th', '17th');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18th', '18th');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19th', '19th');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20th', '20th');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21st', '21st');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22nd', '22nd');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23rd', '23rd');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24th', '24th');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25th', '25th');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26th', '26th');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27th', '27th');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28th', '28th');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29th', '29th');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30th', '30th');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31st', '31st');\n});\n\ntest('format month', function (assert) {\n    var i,\n        expected = 'January Jan_February Feb_March Mar_April Apr_May May_June Jun_July Jul_August Aug_September Sep_October Oct_November Nov_December Dec'.split('_');\n\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var i,\n        expected = 'Sunday Sun Su_Monday Mon Mo_Tuesday Tue Tu_Wednesday Wed We_Thursday Thu Th_Friday Fri Fr_Saturday Sat Sa'.split('_');\n\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'a few seconds', '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'a minute',      '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'a minute',      '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 minutes',     '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 minutes',    '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'an hour',       '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'an hour',       '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 hours',       '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 hours',       '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 hours',      '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'a day',         '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'a day',         '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 days',        '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'a day',         '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 days',        '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 days',       '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'a month',       '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'a month',       '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'a month',       '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 months',      '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 months',      '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 months',      '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'a month',       '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 months',      '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'a year',        '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 years',       '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'a year',        '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 years',       '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'in a few seconds',  'prefix');\n    assert.equal(moment(0).from(30000), 'a few seconds ago', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'a few seconds ago',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'in a few seconds', 'in a few seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), 'in 5 days', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'Today at 12:00 PM',     'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'Today at 12:25 PM',     'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'Today at 1:00 PM',      'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'Tomorrow at 12:00 PM',  'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'Today at 11:00 AM',     'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'Yesterday at 12:00 PM', 'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('dddd [at] LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd [at] LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd [at] LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('[Last] dddd [at] LT'),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[Last] dddd [at] LT'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[Last] dddd [at] LT'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('weeks year starting sunday format', function (assert) {\n    assert.equal(moment([2012, 0,  1]).format('w ww wo'), '1 01 1st', 'Jan  1 2012 should be week 1');\n    assert.equal(moment([2012, 0,  7]).format('w ww wo'), '1 01 1st', 'Jan  7 2012 should be week 1');\n    assert.equal(moment([2012, 0,  8]).format('w ww wo'), '2 02 2nd', 'Jan  8 2012 should be week 2');\n    assert.equal(moment([2012, 0, 14]).format('w ww wo'), '2 02 2nd', 'Jan 14 2012 should be week 2');\n    assert.equal(moment([2012, 0, 15]).format('w ww wo'), '3 03 3rd', 'Jan 15 2012 should be week 3');\n});\n\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/test/locale/en-gb.js",
    "content": "import {localeModule, test} from '../qunit';\nimport moment from '../../moment';\nlocaleModule('en-gb');\n\ntest('parse', function (assert) {\n    var tests = 'January Jan_February Feb_March Mar_April Apr_May May_June Jun_July Jul_August Aug_September Sep_October Oct_November Nov_December Dec'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, MMMM Do YYYY, h:mm:ss a',      'Sunday, February 14th 2010, 3:25:50 pm'],\n            ['ddd, hA',                            'Sun, 3PM'],\n            ['M Mo MM MMMM MMM',                   '2 2nd 02 February Feb'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14th 14'],\n            ['d do dddd ddd dd',                   '0 0th Sunday Sun Su'],\n            ['DDD DDDo DDDD',                      '45 45th 045'],\n            ['w wo ww',                            '6 6th 06'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'pm PM'],\n            ['[the] DDDo [day of the year]',       'the 45th day of the year'],\n            ['LTS',                                '15:25:50'],\n            ['L',                                  '14/02/2010'],\n            ['LL',                                 '14 February 2010'],\n            ['LLL',                                '14 February 2010 15:25'],\n            ['LLLL',                               'Sunday, 14 February 2010 15:25'],\n            ['l',                                  '14/2/2010'],\n            ['ll',                                 '14 Feb 2010'],\n            ['lll',                                '14 Feb 2010 15:25'],\n            ['llll',                               'Sun, 14 Feb 2010 15:25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1st', '1st');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2nd', '2nd');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3rd', '3rd');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4th', '4th');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5th', '5th');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6th', '6th');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7th', '7th');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8th', '8th');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9th', '9th');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10th', '10th');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11th', '11th');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12th', '12th');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13th', '13th');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14th', '14th');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15th', '15th');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16th', '16th');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17th', '17th');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18th', '18th');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19th', '19th');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20th', '20th');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21st', '21st');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22nd', '22nd');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23rd', '23rd');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24th', '24th');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25th', '25th');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26th', '26th');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27th', '27th');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28th', '28th');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29th', '29th');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30th', '30th');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31st', '31st');\n});\n\ntest('format month', function (assert) {\n    var expected = 'January Jan_February Feb_March Mar_April Apr_May May_June Jun_July Jul_August Aug_September Sep_October Oct_November Nov_December Dec'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'Sunday Sun Su_Monday Mon Mo_Tuesday Tue Tu_Wednesday Wed We_Thursday Thu Th_Friday Fri Fr_Saturday Sat Sa'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'a few seconds', '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'a minute',      '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'a minute',      '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 minutes',     '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 minutes',    '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'an hour',       '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'an hour',       '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 hours',       '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 hours',       '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 hours',      '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'a day',         '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'a day',         '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 days',        '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'a day',         '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 days',        '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 days',       '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'a month',       '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'a month',       '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'a month',       '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 months',      '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 months',      '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 months',      '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'a month',       '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 months',      '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'a year',        '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 years',       '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'a year',        '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 years',       '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'in a few seconds',  'prefix');\n    assert.equal(moment(0).from(30000), 'a few seconds ago', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'a few seconds ago',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'in a few seconds', 'in a few seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), 'in 5 days', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'Today at 12:00',      'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'Today at 12:25',      'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'Today at 13:00',      'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'Tomorrow at 12:00',   'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'Today at 11:00',      'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'Yesterday at 12:00',  'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('dddd [at] LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd [at] LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd [at] LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('[Last] dddd [at] LT'),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[Last] dddd [at] LT'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[Last] dddd [at] LT'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2012, 0,  1]).format('w ww wo'), '52 52 52nd', 'Jan  1 2012 should be week 52');\n    assert.equal(moment([2012, 0,  2]).format('w ww wo'),   '1 01 1st', 'Jan  2 2012 should be week 1');\n    assert.equal(moment([2012, 0,  8]).format('w ww wo'),   '1 01 1st', 'Jan  8 2012 should be week 1');\n    assert.equal(moment([2012, 0,  9]).format('w ww wo'),   '2 02 2nd', 'Jan  9 2012 should be week 2');\n    assert.equal(moment([2012, 0, 15]).format('w ww wo'),   '2 02 2nd', 'Jan 15 2012 should be week 2');\n});\n\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/test/locale/en-ie.js",
    "content": "import {localeModule, test} from '../qunit';\nimport moment from '../../moment';\nlocaleModule('en-ie');\n\ntest('parse', function (assert) {\n    var tests = 'January Jan_February Feb_March Mar_April Apr_May May_June Jun_July Jul_August Aug_September Sep_October Oct_November Nov_December Dec'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, MMMM Do YYYY, h:mm:ss a',      'Sunday, February 14th 2010, 3:25:50 pm'],\n            ['ddd, hA',                            'Sun, 3PM'],\n            ['M Mo MM MMMM MMM',                   '2 2nd 02 February Feb'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14th 14'],\n            ['d do dddd ddd dd',                   '0 0th Sunday Sun Su'],\n            ['DDD DDDo DDDD',                      '45 45th 045'],\n            ['w wo ww',                            '6 6th 06'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'pm PM'],\n            ['[the] DDDo [day of the year]',       'the 45th day of the year'],\n            ['LTS',                                '15:25:50'],\n            ['L',                                  '14-02-2010'],\n            ['LL',                                 '14 February 2010'],\n            ['LLL',                                '14 February 2010 15:25'],\n            ['LLLL',                               'Sunday 14 February 2010 15:25'],\n            ['l',                                  '14-2-2010'],\n            ['ll',                                 '14 Feb 2010'],\n            ['lll',                                '14 Feb 2010 15:25'],\n            ['llll',                               'Sun 14 Feb 2010 15:25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1st', '1st');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2nd', '2nd');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3rd', '3rd');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4th', '4th');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5th', '5th');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6th', '6th');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7th', '7th');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8th', '8th');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9th', '9th');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10th', '10th');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11th', '11th');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12th', '12th');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13th', '13th');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14th', '14th');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15th', '15th');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16th', '16th');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17th', '17th');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18th', '18th');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19th', '19th');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20th', '20th');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21st', '21st');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22nd', '22nd');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23rd', '23rd');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24th', '24th');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25th', '25th');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26th', '26th');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27th', '27th');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28th', '28th');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29th', '29th');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30th', '30th');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31st', '31st');\n});\n\ntest('format month', function (assert) {\n    var expected = 'January Jan_February Feb_March Mar_April Apr_May May_June Jun_July Jul_August Aug_September Sep_October Oct_November Nov_December Dec'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'Sunday Sun Su_Monday Mon Mo_Tuesday Tue Tu_Wednesday Wed We_Thursday Thu Th_Friday Fri Fr_Saturday Sat Sa'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'a few seconds', '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'a minute',      '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'a minute',      '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 minutes',     '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 minutes',    '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'an hour',       '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'an hour',       '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 hours',       '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 hours',       '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 hours',      '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'a day',         '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'a day',         '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 days',        '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'a day',         '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 days',        '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 days',       '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'a month',       '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'a month',       '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'a month',       '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 months',      '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 months',      '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 months',      '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'a month',       '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 months',      '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'a year',        '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 years',       '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'a year',        '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 years',       '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'in a few seconds',  'prefix');\n    assert.equal(moment(0).from(30000), 'a few seconds ago', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'a few seconds ago',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'in a few seconds', 'in a few seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), 'in 5 days', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'Today at 12:00',      'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'Today at 12:25',      'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'Today at 13:00',      'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'Tomorrow at 12:00',   'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'Today at 11:00',      'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'Yesterday at 12:00',  'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('dddd [at] LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd [at] LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd [at] LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('[Last] dddd [at] LT'),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[Last] dddd [at] LT'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[Last] dddd [at] LT'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2012, 0,  1]).format('w ww wo'), '52 52 52nd', 'Jan  1 2012 should be week 52');\n    assert.equal(moment([2012, 0,  2]).format('w ww wo'),   '1 01 1st', 'Jan  2 2012 should be week 1');\n    assert.equal(moment([2012, 0,  8]).format('w ww wo'),   '1 01 1st', 'Jan  8 2012 should be week 1');\n    assert.equal(moment([2012, 0,  9]).format('w ww wo'),   '2 02 2nd', 'Jan  9 2012 should be week 2');\n    assert.equal(moment([2012, 0, 15]).format('w ww wo'),   '2 02 2nd', 'Jan 15 2012 should be week 2');\n});\n\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/test/locale/en-nz.js",
    "content": "import {localeModule, test} from '../qunit';\nimport moment from '../../moment';\nlocaleModule('en-nz');\n\ntest('parse', function (assert) {\n    var tests = 'January Jan_February Feb_March Mar_April Apr_May May_June Jun_July Jul_August Aug_September Sep_October Oct_November Nov_December Dec'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, MMMM Do YYYY, h:mm:ss a',      'Sunday, February 14th 2010, 3:25:50 pm'],\n            ['ddd, hA',                            'Sun, 3PM'],\n            ['M Mo MM MMMM MMM',                   '2 2nd 02 February Feb'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14th 14'],\n            ['d do dddd ddd dd',                   '0 0th Sunday Sun Su'],\n            ['DDD DDDo DDDD',                      '45 45th 045'],\n            ['w wo ww',                            '6 6th 06'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'pm PM'],\n            ['[the] DDDo [day of the year]',       'the 45th day of the year'],\n            ['LTS',                                '3:25:50 PM'],\n            ['L',                                  '14/02/2010'],\n            ['LL',                                 '14 February 2010'],\n            ['LLL',                                '14 February 2010 3:25 PM'],\n            ['LLLL',                               'Sunday, 14 February 2010 3:25 PM'],\n            ['l',                                  '14/2/2010'],\n            ['ll',                                 '14 Feb 2010'],\n            ['lll',                                '14 Feb 2010 3:25 PM'],\n            ['llll',                               'Sun, 14 Feb 2010 3:25 PM']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1st', '1st');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2nd', '2nd');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3rd', '3rd');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4th', '4th');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5th', '5th');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6th', '6th');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7th', '7th');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8th', '8th');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9th', '9th');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10th', '10th');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11th', '11th');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12th', '12th');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13th', '13th');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14th', '14th');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15th', '15th');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16th', '16th');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17th', '17th');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18th', '18th');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19th', '19th');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20th', '20th');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21st', '21st');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22nd', '22nd');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23rd', '23rd');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24th', '24th');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25th', '25th');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26th', '26th');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27th', '27th');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28th', '28th');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29th', '29th');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30th', '30th');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31st', '31st');\n});\n\ntest('format month', function (assert) {\n    var expected = 'January Jan_February Feb_March Mar_April Apr_May May_June Jun_July Jul_August Aug_September Sep_October Oct_November Nov_December Dec'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'Sunday Sun Su_Monday Mon Mo_Tuesday Tue Tu_Wednesday Wed We_Thursday Thu Th_Friday Fri Fr_Saturday Sat Sa'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'a few seconds', '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'a minute',      '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'a minute',      '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 minutes',     '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 minutes',    '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'an hour',       '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'an hour',       '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 hours',       '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 hours',       '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 hours',      '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'a day',         '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'a day',         '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 days',        '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'a day',         '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 days',        '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 days',       '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'a month',       '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'a month',       '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'a month',       '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 months',      '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 months',      '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 months',      '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'a month',       '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 months',      '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'a year',        '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 years',       '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'a year',        '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 years',       '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'in a few seconds',  'prefix');\n    assert.equal(moment(0).from(30000), 'a few seconds ago', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'a few seconds ago',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'in a few seconds', 'in a few seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), 'in 5 days', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'Today at 12:00 PM',     'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'Today at 12:25 PM',     'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'Today at 1:00 PM',      'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'Tomorrow at 12:00 PM',  'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'Today at 11:00 AM',     'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'Yesterday at 12:00 PM', 'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('dddd [at] LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd [at] LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd [at] LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('[Last] dddd [at] LT'),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[Last] dddd [at] LT'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[Last] dddd [at] LT'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2012, 0,  1]).format('w ww wo'), '52 52 52nd', 'Jan  1 2012 should be week 52');\n    assert.equal(moment([2012, 0,  2]).format('w ww wo'),   '1 01 1st', 'Jan  2 2012 should be week 1');\n    assert.equal(moment([2012, 0,  8]).format('w ww wo'),   '1 01 1st', 'Jan  8 2012 should be week 1');\n    assert.equal(moment([2012, 0,  9]).format('w ww wo'),   '2 02 2nd', 'Jan  9 2012 should be week 2');\n    assert.equal(moment([2012, 0, 15]).format('w ww wo'),   '2 02 2nd', 'Jan 15 2012 should be week 2');\n});\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/test/locale/en.js",
    "content": "import {localeModule, test} from '../qunit';\nimport moment from '../../moment';\nlocaleModule('en');\n\ntest('parse', function (assert) {\n    var i,\n        tests = 'January Jan_February Feb_March Mar_April Apr_May May_June Jun_July Jul_August Aug_September Sep_October Oct_November Nov_December Dec'.split('_');\n\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, MMMM Do YYYY, h:mm:ss a',      'Sunday, February 14th 2010, 3:25:50 pm'],\n            ['ddd, hA',                            'Sun, 3PM'],\n            ['M Mo MM MMMM MMM',                   '2 2nd 02 February Feb'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14th 14'],\n            ['d do dddd ddd dd',                   '0 0th Sunday Sun Su'],\n            ['DDD DDDo DDDD',                      '45 45th 045'],\n            ['w wo ww',                            '8 8th 08'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'pm PM'],\n            ['[the] DDDo [day of the year]',       'the 45th day of the year'],\n            ['LTS',                                '3:25:50 PM'],\n            ['L',                                  '02/14/2010'],\n            ['LL',                                 'February 14, 2010'],\n            ['LLL',                                'February 14, 2010 3:25 PM'],\n            ['LLLL',                               'Sunday, February 14, 2010 3:25 PM'],\n            ['l',                                  '2/14/2010'],\n            ['ll',                                 'Feb 14, 2010'],\n            ['lll',                                'Feb 14, 2010 3:25 PM'],\n            ['llll',                               'Sun, Feb 14, 2010 3:25 PM']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1st', '1st');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2nd', '2nd');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3rd', '3rd');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4th', '4th');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5th', '5th');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6th', '6th');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7th', '7th');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8th', '8th');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9th', '9th');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10th', '10th');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11th', '11th');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12th', '12th');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13th', '13th');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14th', '14th');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15th', '15th');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16th', '16th');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17th', '17th');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18th', '18th');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19th', '19th');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20th', '20th');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21st', '21st');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22nd', '22nd');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23rd', '23rd');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24th', '24th');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25th', '25th');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26th', '26th');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27th', '27th');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28th', '28th');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29th', '29th');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30th', '30th');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31st', '31st');\n});\n\ntest('format month', function (assert) {\n    var i,\n        expected = 'January Jan_February Feb_March Mar_April Apr_May May_June Jun_July Jul_August Aug_September Sep_October Oct_November Nov_December Dec'.split('_');\n\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var i,\n        expected = 'Sunday Sun Su_Monday Mon Mo_Tuesday Tue Tu_Wednesday Wed We_Thursday Thu Th_Friday Fri Fr_Saturday Sat Sa'.split('_');\n\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'a few seconds', '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'a minute',      '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'a minute',      '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 minutes',     '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 minutes',    '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'an hour',       '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'an hour',       '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 hours',       '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 hours',       '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 hours',      '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'a day',         '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'a day',         '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 days',        '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'a day',         '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 days',        '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 days',       '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'a month',       '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'a month',       '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'a month',       '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 months',      '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 months',      '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 months',      '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'a month',       '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 months',      '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'a year',        '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 years',       '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'a year',        '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 years',       '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'in a few seconds',  'prefix');\n    assert.equal(moment(0).from(30000), 'a few seconds ago', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'a few seconds ago',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'in a few seconds', 'in a few seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), 'in 5 days', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'Today at 12:00 PM',     'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'Today at 12:25 PM',     'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'Today at 1:00 PM',      'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'Tomorrow at 12:00 PM',  'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'Today at 11:00 AM',     'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'Yesterday at 12:00 PM', 'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('dddd [at] LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd [at] LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd [at] LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('[Last] dddd [at] LT'),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[Last] dddd [at] LT'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[Last] dddd [at] LT'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('weeks year starting sunday format', function (assert) {\n    assert.equal(moment([2012, 0,  1]).format('w ww wo'), '1 01 1st', 'Jan  1 2012 should be week 1');\n    assert.equal(moment([2012, 0,  7]).format('w ww wo'), '1 01 1st', 'Jan  7 2012 should be week 1');\n    assert.equal(moment([2012, 0,  8]).format('w ww wo'), '2 02 2nd', 'Jan  8 2012 should be week 2');\n    assert.equal(moment([2012, 0, 14]).format('w ww wo'), '2 02 2nd', 'Jan 14 2012 should be week 2');\n    assert.equal(moment([2012, 0, 15]).format('w ww wo'), '3 03 3rd', 'Jan 15 2012 should be week 3');\n});\n\ntest('weekdays strict parsing', function (assert) {\n    var m = moment('2015-01-01T12', moment.ISO_8601, true),\n        enLocale = moment.localeData('en');\n\n    for (var i = 0; i < 7; ++i) {\n        assert.equal(moment(enLocale.weekdays(m.day(i), ''), 'dddd', true).isValid(), true, 'parse weekday ' + i);\n        assert.equal(moment(enLocale.weekdaysShort(m.day(i), ''), 'ddd', true).isValid(), true, 'parse short weekday ' + i);\n        assert.equal(moment(enLocale.weekdaysMin(m.day(i), ''), 'dd', true).isValid(), true, 'parse min weekday ' + i);\n\n        // negative tests\n        assert.equal(moment(enLocale.weekdaysMin(m.day(i), ''), 'ddd', true).isValid(), false, 'parse short weekday ' + i);\n        assert.equal(moment(enLocale.weekdaysShort(m.day(i), ''), 'dd', true).isValid(), false, 'parse min weekday ' + i);\n    }\n});\n\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/test/locale/eo.js",
    "content": "import {localeModule, test} from '../qunit';\nimport moment from '../../moment';\nlocaleModule('eo');\n\ntest('parse', function (assert) {\n    var tests = 'januaro jan_februaro feb_marto mar_aprilo apr_majo maj_junio jun_julio jul_aŭgusto aŭg_septembro sep_oktobro okt_novembro nov_decembro dec'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, MMMM Do YYYY, h:mm:ss a',      'dimanĉo, februaro 14a 2010, 3:25:50 p.t.m.'],\n            ['ddd, hA',                            'dim, 3P.T.M.'],\n            ['M Mo MM MMMM MMM',                   '2 2a 02 februaro feb'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14a 14'],\n            ['d do dddd ddd dd',                   '0 0a dimanĉo dim di'],\n            ['DDD DDDo DDDD',                      '45 45a 045'],\n            ['w wo ww',                            '7 7a 07'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'p.t.m. P.T.M.'],\n            ['[la] DDDo [tago] [de] [la] [jaro]',  'la 45a tago de la jaro'],\n            ['LTS',                                '15:25:50'],\n            ['L',                                  '2010-02-14'],\n            ['LL',                                 '14-a de februaro, 2010'],\n            ['LLL',                                '14-a de februaro, 2010 15:25'],\n            ['LLLL',                               'dimanĉo, la 14-a de februaro, 2010 15:25'],\n            ['l',                                  '2010-2-14'],\n            ['ll',                                 '14-a de feb, 2010'],\n            ['lll',                                '14-a de feb, 2010 15:25'],\n            ['llll',                               'dim, la 14-a de feb, 2010 15:25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1a', '1a');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2a', '2a');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3a', '3a');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4a', '4a');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5a', '5a');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6a', '6a');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7a', '7a');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8a', '8a');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9a', '9a');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10a', '10a');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11a', '11a');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12a', '12a');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13a', '13a');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14a', '14a');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15a', '15a');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16a', '16a');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17a', '17a');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18a', '18a');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19a', '19a');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20a', '20a');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21a', '21a');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22a', '22a');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23a', '23a');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24a', '24a');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25a', '25a');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26a', '26a');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27a', '27a');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28a', '28a');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29a', '29a');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30a', '30a');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31a', '31a');\n});\n\ntest('format month', function (assert) {\n    var expected = 'januaro jan_februaro feb_marto mar_aprilo apr_majo maj_junio jun_julio jul_aŭgusto aŭg_septembro sep_oktobro okt_novembro nov_decembro dec'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'dimanĉo dim di_lundo lun lu_mardo mard ma_merkredo merk me_ĵaŭdo ĵaŭ ĵa_vendredo ven ve_sabato sab sa'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'sekundoj', '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'minuto',      '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'minuto',      '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 minutoj',     '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 minutoj',    '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'horo',       '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'horo',       '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 horoj',       '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 horoj',       '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 horoj',      '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'tago',         '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'tago',         '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 tagoj',        '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'tago',         '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 tagoj',        '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 tagoj',       '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'monato',       '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'monato',       '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'monato',       '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 monatoj',      '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 monatoj',      '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 monatoj',      '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'monato',       '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 monatoj',      '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'jaro',        '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 jaroj',       '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'jaro',        '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 jaroj',       '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'post sekundoj',  'post prefix');\n    assert.equal(moment(0).from(30000), 'antaŭ sekundoj', 'antaŭ prefix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'antaŭ sekundoj',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'post sekundoj', 'post sekundoj');\n    assert.equal(moment().add({d: 5}).fromNow(), 'post 5 tagoj', 'post 5 tagoj');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'Hodiaŭ je 12:00',     'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'Hodiaŭ je 12:25',     'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'Hodiaŭ je 13:00',     'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'Morgaŭ je 12:00',     'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'Hodiaŭ je 11:00',     'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'Hieraŭ je 12:00',     'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('dddd [je] LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd [je] LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd [je] LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('[pasinta] dddd [je] LT'),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[pasinta] dddd [je] LT'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[pasinta] dddd [je] LT'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2011, 11, 26]).format('w ww wo'), '1 01 1a', 'Dec 26 2011 should be week 1');\n    assert.equal(moment([2012,  0,  1]).format('w ww wo'), '1 01 1a', 'Jan  1 2012 should be week 1');\n    assert.equal(moment([2012,  0,  2]).format('w ww wo'), '2 02 2a', 'Jan  2 2012 should be week 2');\n    assert.equal(moment([2012,  0,  8]).format('w ww wo'), '2 02 2a', 'Jan  8 2012 should be week 2');\n    assert.equal(moment([2012,  0,  9]).format('w ww wo'), '3 03 3a', 'Jan  9 2012 should be week 3');\n});\n\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/test/locale/es-do.js",
    "content": "import {localeModule, test} from '../qunit';\nimport moment from '../../moment';\nlocaleModule('es-do');\n\ntest('parse', function (assert) {\n    var tests = 'enero ene._febrero feb._marzo mar._abril abr._mayo may._junio jun._julio jul._agosto ago._septiembre sep._octubre oct._noviembre nov._diciembre dic.'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, MMMM Do YYYY, h:mm:ss a',      'domingo, febrero 14º 2010, 3:25:50 pm'],\n            ['ddd, hA',                            'dom., 3PM'],\n            ['M Mo MM MMMM MMM',                   '2 2º 02 febrero feb.'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14º 14'],\n            ['d do dddd ddd dd',                   '0 0º domingo dom. do'],\n            ['DDD DDDo DDDD',                      '45 45º 045'],\n            ['w wo ww',                            '6 6º 06'],\n            ['YYYY-MMM-DD',                        '2010-feb-14'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'pm PM'],\n            ['[the] DDDo [day of the year]',       'the 45º day of the year'],\n            ['LTS',                                '3:25:50 PM'],\n            ['L',                                  '14/02/2010'],\n            ['LL',                                 '14 de febrero de 2010'],\n            ['LLL',                                '14 de febrero de 2010 3:25 PM'],\n            ['LLLL',                               'domingo, 14 de febrero de 2010 3:25 PM'],\n            ['l',                                  '14/2/2010'],\n            ['ll',                                 '14 de feb. de 2010'],\n            ['lll',                                '14 de feb. de 2010 3:25 PM'],\n            ['llll',                               'dom., 14 de feb. de 2010 3:25 PM']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1º', '1º');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2º', '2º');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3º', '3º');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4º', '4º');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5º', '5º');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6º', '6º');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7º', '7º');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8º', '8º');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9º', '9º');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10º', '10º');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11º', '11º');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12º', '12º');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13º', '13º');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14º', '14º');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15º', '15º');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16º', '16º');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17º', '17º');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18º', '18º');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19º', '19º');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20º', '20º');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21º', '21º');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22º', '22º');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23º', '23º');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24º', '24º');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25º', '25º');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26º', '26º');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27º', '27º');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28º', '28º');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29º', '29º');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30º', '30º');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31º', '31º');\n});\n\ntest('format month', function (assert) {\n    var expected = 'enero ene._febrero feb._marzo mar._abril abr._mayo may._junio jun._julio jul._agosto ago._septiembre sep._octubre oct._noviembre nov._diciembre dic.'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'domingo dom. do_lunes lun. lu_martes mar. ma_miércoles mié. mi_jueves jue. ju_viernes vie. vi_sábado sáb. sá'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'unos segundos', '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'un minuto',      '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'un minuto',      '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 minutos',     '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 minutos',    '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'una hora',       '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'una hora',       '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 horas',       '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 horas',       '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 horas',      '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'un día',         '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'un día',         '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 días',        '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'un día',         '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 días',        '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 días',       '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'un mes',       '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'un mes',       '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'un mes',       '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 meses',      '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 meses',      '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 meses',      '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'un mes',       '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 meses',      '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'un año',        '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 años',       '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'un año',        '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 años',       '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'en unos segundos',  'prefix');\n    assert.equal(moment(0).from(30000), 'hace unos segundos', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'hace unos segundos',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'en unos segundos', 'en unos segundos');\n    assert.equal(moment().add({d: 5}).fromNow(), 'en 5 días', 'en 5 días');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                       'hoy a las 12:00 PM',     'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),          'hoy a las 12:25 PM',     'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),           'hoy a las 1:00 PM',     'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),           'mañana a las 12:00 PM',  'tomorrow at the same time');\n    assert.equal(moment(a).add({d: 1, h : -1}).calendar(),   'mañana a las 11:00 AM',   'tomorrow minus 1 hour');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),      'hoy a las 11:00 AM',     'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),      'ayer a las 12:00 PM',    'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('dddd [a la' + ((m.hours() !== 1) ? 's' : '') + '] LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd [a la' + ((m.hours() !== 1) ? 's' : '') + '] LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd [a la' + ((m.hours() !== 1) ? 's' : '') + '] LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('[el] dddd [pasado a la' + ((m.hours() !== 1) ? 's' : '') + '] LT'),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[el] dddd [pasado a la' + ((m.hours() !== 1) ? 's' : '') + '] LT'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[el] dddd [pasado a la' + ((m.hours() !== 1) ? 's' : '') + '] LT'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2012, 0,  1]).format('w ww wo'), '52 52 52º', 'Jan  1 2012 should be week 52');\n    assert.equal(moment([2012, 0,  2]).format('w ww wo'),   '1 01 1º', 'Jan  2 2012 should be week 1');\n    assert.equal(moment([2012, 0,  8]).format('w ww wo'),   '1 01 1º', 'Jan  8 2012 should be week 1');\n    assert.equal(moment([2012, 0,  9]).format('w ww wo'),   '2 02 2º', 'Jan  9 2012 should be week 2');\n    assert.equal(moment([2012, 0, 15]).format('w ww wo'),   '2 02 2º', 'Jan 15 2012 should be week 2');\n});\n\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/test/locale/es.js",
    "content": "import {localeModule, test} from '../qunit';\nimport moment from '../../moment';\nlocaleModule('es');\n\ntest('parse', function (assert) {\n    var tests = 'enero ene._febrero feb._marzo mar._abril abr._mayo may._junio jun._julio jul._agosto ago._septiembre sep._octubre oct._noviembre nov._diciembre dic.'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, MMMM Do YYYY, h:mm:ss a',      'domingo, febrero 14º 2010, 3:25:50 pm'],\n            ['ddd, hA',                            'dom., 3PM'],\n            ['M Mo MM MMMM MMM',                   '2 2º 02 febrero feb.'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14º 14'],\n            ['d do dddd ddd dd',                   '0 0º domingo dom. do'],\n            ['DDD DDDo DDDD',                      '45 45º 045'],\n            ['w wo ww',                            '6 6º 06'],\n            ['YYYY-MMM-DD',                        '2010-feb-14'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'pm PM'],\n            ['[the] DDDo [day of the year]',       'the 45º day of the year'],\n            ['LTS',                                '15:25:50'],\n            ['L',                                  '14/02/2010'],\n            ['LL',                                 '14 de febrero de 2010'],\n            ['LLL',                                '14 de febrero de 2010 15:25'],\n            ['LLLL',                               'domingo, 14 de febrero de 2010 15:25'],\n            ['l',                                  '14/2/2010'],\n            ['ll',                                 '14 de feb. de 2010'],\n            ['lll',                                '14 de feb. de 2010 15:25'],\n            ['llll',                               'dom., 14 de feb. de 2010 15:25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1º', '1º');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2º', '2º');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3º', '3º');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4º', '4º');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5º', '5º');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6º', '6º');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7º', '7º');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8º', '8º');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9º', '9º');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10º', '10º');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11º', '11º');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12º', '12º');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13º', '13º');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14º', '14º');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15º', '15º');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16º', '16º');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17º', '17º');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18º', '18º');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19º', '19º');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20º', '20º');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21º', '21º');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22º', '22º');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23º', '23º');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24º', '24º');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25º', '25º');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26º', '26º');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27º', '27º');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28º', '28º');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29º', '29º');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30º', '30º');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31º', '31º');\n});\n\ntest('format month', function (assert) {\n    var expected = 'enero ene._febrero feb._marzo mar._abril abr._mayo may._junio jun._julio jul._agosto ago._septiembre sep._octubre oct._noviembre nov._diciembre dic.'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'domingo dom. do_lunes lun. lu_martes mar. ma_miércoles mié. mi_jueves jue. ju_viernes vie. vi_sábado sáb. sá'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'unos segundos', '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'un minuto',      '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'un minuto',      '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 minutos',     '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 minutos',    '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'una hora',       '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'una hora',       '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 horas',       '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 horas',       '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 horas',      '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'un día',         '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'un día',         '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 días',        '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'un día',         '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 días',        '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 días',       '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'un mes',       '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'un mes',       '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'un mes',       '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 meses',      '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 meses',      '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 meses',      '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'un mes',       '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 meses',      '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'un año',        '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 años',       '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'un año',        '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 años',       '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'en unos segundos',  'prefix');\n    assert.equal(moment(0).from(30000), 'hace unos segundos', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'hace unos segundos',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'en unos segundos', 'en unos segundos');\n    assert.equal(moment().add({d: 5}).fromNow(), 'en 5 días', 'en 5 días');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                       'hoy a las 12:00',     'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),          'hoy a las 12:25',     'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),           'hoy a las 13:00',     'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),           'mañana a las 12:00',  'tomorrow at the same time');\n    assert.equal(moment(a).add({d: 1, h : -1}).calendar(),   'mañana a las 11:00',   'tomorrow minus 1 hour');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),      'hoy a las 11:00',     'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),      'ayer a las 12:00',    'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('dddd [a la' + ((m.hours() !== 1) ? 's' : '') + '] LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd [a la' + ((m.hours() !== 1) ? 's' : '') + '] LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd [a la' + ((m.hours() !== 1) ? 's' : '') + '] LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('[el] dddd [pasado a la' + ((m.hours() !== 1) ? 's' : '') + '] LT'),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[el] dddd [pasado a la' + ((m.hours() !== 1) ? 's' : '') + '] LT'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[el] dddd [pasado a la' + ((m.hours() !== 1) ? 's' : '') + '] LT'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2012, 0,  1]).format('w ww wo'), '52 52 52º', 'Jan  1 2012 should be week 52');\n    assert.equal(moment([2012, 0,  2]).format('w ww wo'),   '1 01 1º', 'Jan  2 2012 should be week 1');\n    assert.equal(moment([2012, 0,  8]).format('w ww wo'),   '1 01 1º', 'Jan  8 2012 should be week 1');\n    assert.equal(moment([2012, 0,  9]).format('w ww wo'),   '2 02 2º', 'Jan  9 2012 should be week 2');\n    assert.equal(moment([2012, 0, 15]).format('w ww wo'),   '2 02 2º', 'Jan 15 2012 should be week 2');\n});\n\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/test/locale/et.js",
    "content": "import {localeModule, test} from '../qunit';\nimport moment from '../../moment';\nlocaleModule('et');\n\ntest('parse', function (assert) {\n    var tests = 'jaanuar jaan_veebruar veebr_märts märts_aprill apr_mai mai_juuni juuni_juuli juuli_august aug_september sept_oktoober okt_november nov_detsember dets'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' peaks olema kuu ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, Do MMMM YYYY, H:mm:ss',      'pühapäev, 14. veebruar 2010, 15:25:50'],\n            ['ddd, h',                           'P, 3'],\n            ['M Mo MM MMMM MMM',                 '2 2. 02 veebruar veebr'],\n            ['YYYY YY',                          '2010 10'],\n            ['D Do DD',                          '14 14. 14'],\n            ['d do dddd ddd dd',                 '0 0. pühapäev P P'],\n            ['DDD DDDo DDDD',                    '45 45. 045'],\n            ['w wo ww',                          '6 6. 06'],\n            ['h hh',                             '3 03'],\n            ['H HH',                             '15 15'],\n            ['m mm',                             '25 25'],\n            ['s ss',                             '50 50'],\n            ['a A',                              'pm PM'],\n            ['[aasta] DDDo [päev]',              'aasta 45. päev'],\n            ['LTS',                              '15:25:50'],\n            ['L',                                '14.02.2010'],\n            ['LL',                               '14. veebruar 2010'],\n            ['LLL',                              '14. veebruar 2010 15:25'],\n            ['LLLL',                             'pühapäev, 14. veebruar 2010 15:25'],\n            ['l',                                '14.2.2010'],\n            ['ll',                               '14. veebr 2010'],\n            ['lll',                              '14. veebr 2010 15:25'],\n            ['llll',                             'P, 14. veebr 2010 15:25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1.', '1.');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2.', '2.');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3.', '3.');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4.', '4.');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5.', '5.');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6.', '6.');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7.', '7.');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8.', '8.');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9.', '9.');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10.', '10.');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11.', '11.');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12.', '12.');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13.', '13.');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14.', '14.');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15.', '15.');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16.', '16.');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17.', '17.');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18.', '18.');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19.', '19.');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20.', '20.');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21.', '21.');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22.', '22.');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23.', '23.');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24.', '24.');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25.', '25.');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26.', '26.');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27.', '27.');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28.', '28.');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29.', '29.');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30.', '30.');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31.', '31.');\n});\n\ntest('format month', function (assert) {\n    var expected = 'jaanuar jaan_veebruar veebr_märts märts_aprill apr_mai mai_juuni juuni_juuli juuli_august aug_september sept_oktoober okt_november nov_detsember dets'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'pühapäev P P_esmaspäev E E_teisipäev T T_kolmapäev K K_neljapäev N N_reede R R_laupäev L L'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'paar sekundit',  '44 seconds = paar sekundit');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'üks minut',      '45 seconds = üks minut');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'üks minut',      '89 seconds = üks minut');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 minutit',      '90 seconds = 2 minutit');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 minutit',     '44 minutes = 44 minutit');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'üks tund',       '45 minutes = tund aega');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'üks tund',       '89 minutes = üks tund');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 tundi',        '90 minutes = 2 tundi');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 tundi',        '5 hours = 5 tundi');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 tundi',       '21 hours = 21 tundi');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'üks päev',       '22 hours = üks päev');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'üks päev',       '35 hours = üks päev');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 päeva',        '36 hours = 2 päeva');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'üks päev',       '1 day = üks päev');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 päeva',        '5 days = 5 päeva');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 päeva',       '25 days = 25 päeva');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'üks kuu',        '26 days = üks kuu');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'üks kuu',        '30 days = üks kuu');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'üks kuu',        '43 days = üks kuu');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 kuud',         '46 days = 2 kuud');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 kuud',         '75 days = 2 kuud');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 kuud',         '76 days = 3 kuud');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'üks kuu',        '1 month = üks kuu');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 kuud',         '5 months = 5 kuud');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'üks aasta',      '345 days = üks aasta');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 aastat',       '548 days = 2 aastat');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'üks aasta',      '1 year = üks aasta');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 aastat',       '5 years = 5 aastat');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'mõne sekundi pärast',  'prefix');\n    assert.equal(moment(0).from(30000), 'mõni sekund tagasi', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'mõni sekund tagasi',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'mõne sekundi pärast', 'in a few seconds');\n    assert.equal(moment().subtract({s: 30}).fromNow(), 'mõni sekund tagasi', 'a few seconds ago');\n\n    assert.equal(moment().add({m: 1}).fromNow(), 'ühe minuti pärast', 'in a minute');\n    assert.equal(moment().subtract({m: 1}).fromNow(), 'üks minut tagasi', 'a minute ago');\n\n    assert.equal(moment().add({m: 5}).fromNow(), '5 minuti pärast', 'in 5 minutes');\n    assert.equal(moment().subtract({m: 5}).fromNow(), '5 minutit tagasi', '5 minutes ago');\n\n    assert.equal(moment().add({d: 1}).fromNow(), 'ühe päeva pärast', 'in one day');\n    assert.equal(moment().subtract({d: 1}).fromNow(), 'üks päev tagasi', 'one day ago');\n\n    assert.equal(moment().add({d: 5}).fromNow(), '5 päeva pärast', 'in 5 days');\n    assert.equal(moment().subtract({d: 5}).fromNow(), '5 päeva tagasi', '5 days ago');\n\n    assert.equal(moment().add({M: 1}).fromNow(), 'kuu aja pärast', 'in a month');\n    assert.equal(moment().subtract({M: 1}).fromNow(), 'kuu aega tagasi', 'a month ago');\n\n    assert.equal(moment().add({M: 5}).fromNow(), '5 kuu pärast', 'in 5 months');\n    assert.equal(moment().subtract({M: 5}).fromNow(), '5 kuud tagasi', '5 months ago');\n\n    assert.equal(moment().add({y: 1}).fromNow(), 'ühe aasta pärast', 'in a year');\n    assert.equal(moment().subtract({y: 1}).fromNow(), 'aasta tagasi', 'a year ago');\n\n    assert.equal(moment().add({y: 5}).fromNow(), '5 aasta pärast', 'in 5 years');\n    assert.equal(moment().subtract({y: 5}).fromNow(), '5 aastat tagasi', '5 years ago');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'Täna, 12:00',     'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'Täna, 12:25',     'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'Täna, 13:00',     'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'Homme, 12:00',    'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'Täna, 11:00',     'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'Eile, 12:00',     'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('[Järgmine] dddd LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[Järgmine] dddd LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[Järgmine] dddd LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('[Eelmine] dddd LT'),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[Eelmine] dddd LT'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[Eelmine] dddd LT'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 nädal tagasi');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  '1 nädala pärast');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 nädalat tagasi');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  '2 nädala pärast');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2012, 0,  1]).format('w ww wo'), '52 52 52.', 'Jan  1 2012 should be week 52');\n    assert.equal(moment([2012, 0,  2]).format('w ww wo'),   '1 01 1.', 'Jan  2 2012 should be week 1');\n    assert.equal(moment([2012, 0,  8]).format('w ww wo'),   '1 01 1.', 'Jan  8 2012 should be week 1');\n    assert.equal(moment([2012, 0,  9]).format('w ww wo'),   '2 02 2.', 'Jan  9 2012 should be week 2');\n    assert.equal(moment([2012, 0, 15]).format('w ww wo'),   '2 02 2.', 'Jan 15 2012 should be week 2');\n});\n\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/test/locale/eu.js",
    "content": "import {localeModule, test} from '../qunit';\nimport moment from '../../moment';\nlocaleModule('eu');\n\ntest('parse', function (assert) {\n    var tests = 'urtarrila urt._otsaila ots._martxoa mar._apirila api._maiatza mai._ekaina eka._uztaila uzt._abuztua abu._iraila ira._urria urr._azaroa aza._abendua abe.'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, MMMM Do YYYY, h:mm:ss a',      'igandea, otsaila 14. 2010, 3:25:50 pm'],\n            ['ddd, hA',                            'ig., 3PM'],\n            ['M Mo MM MMMM MMM',                   '2 2. 02 otsaila ots.'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14. 14'],\n            ['d do dddd ddd dd',                   '0 0. igandea ig. ig'],\n            ['DDD DDDo DDDD',                      '45 45. 045'],\n            ['w wo ww',                            '7 7. 07'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'pm PM'],\n            ['[the] DDDo [day of the year]',       'the 45. day of the year'],\n            ['LTS',                                '15:25:50'],\n            ['L',                                  '2010-02-14'],\n            ['LL',                                 '2010ko otsailaren 14a'],\n            ['LLL',                                '2010ko otsailaren 14a 15:25'],\n            ['LLLL',                               'igandea, 2010ko otsailaren 14a 15:25'],\n            ['l',                                  '2010-2-14'],\n            ['ll',                                 '2010ko ots. 14a'],\n            ['lll',                                '2010ko ots. 14a 15:25'],\n            ['llll',                               'ig., 2010ko ots. 14a 15:25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1.', '1.');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2.', '2.');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3.', '3.');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4.', '4.');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5.', '5.');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6.', '6.');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7.', '7.');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8.', '8.');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9.', '9.');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10.', '10.');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11.', '11.');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12.', '12.');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13.', '13.');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14.', '14.');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15.', '15.');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16.', '16.');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17.', '17.');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18.', '18.');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19.', '19.');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20.', '20.');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21.', '21.');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22.', '22.');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23.', '23.');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24.', '24.');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25.', '25.');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26.', '26.');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27.', '27.');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28.', '28.');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29.', '29.');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30.', '30.');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31.', '31.');\n});\n\ntest('format month', function (assert) {\n    var expected = 'urtarrila urt._otsaila ots._martxoa mar._apirila api._maiatza mai._ekaina eka._uztaila uzt._abuztua abu._iraila ira._urria urr._azaroa aza._abendua abe.'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'igandea ig. ig_astelehena al. al_asteartea ar. ar_asteazkena az. az_osteguna og. og_ostirala ol. ol_larunbata lr. lr'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'segundo batzuk', '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'minutu bat',     '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'minutu bat',     '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 minutu',       '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 minutu',      '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'ordu bat',       '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'ordu bat',       '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 ordu',         '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 ordu',         '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 ordu',        '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'egun bat',       '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'egun bat',       '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 egun',         '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'egun bat',       '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 egun',         '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 egun',        '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'hilabete bat',   '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'hilabete bat',   '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'hilabete bat',   '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 hilabete',     '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 hilabete',     '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 hilabete',     '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'hilabete bat',   '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 hilabete',     '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'urte bat',       '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 urte',         '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'urte bat',       '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 urte',         '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'segundo batzuk barru',  'prefix');\n    assert.equal(moment(0).from(30000), 'duela segundo batzuk', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'duela segundo batzuk',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'segundo batzuk barru', 'in seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), '5 egun barru', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'gaur 12:00etan',  'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'gaur 12:25etan',  'now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'gaur 13:00etan',  'now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'bihar 12:00etan', 'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'gaur 11:00etan',  'now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'atzo 12:00etan',  'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('dddd LT[etan]'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd LT[etan]'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd LT[etan]'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('[aurreko] dddd LT[etan]'),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[aurreko] dddd LT[etan]'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[aurreko] dddd LT[etan]'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2011, 11, 26]).format('w ww wo'), '1 01 1.', 'Dec 26 2011 should be week 1');\n    assert.equal(moment([2012,  0,  1]).format('w ww wo'), '1 01 1.', 'Jan  1 2012 should be week 1');\n    assert.equal(moment([2012,  0,  2]).format('w ww wo'), '2 02 2.', 'Jan  2 2012 should be week 2');\n    assert.equal(moment([2012,  0,  8]).format('w ww wo'), '2 02 2.', 'Jan  8 2012 should be week 2');\n    assert.equal(moment([2012,  0,  9]).format('w ww wo'), '3 03 3.', 'Jan  9 2012 should be week 3');\n});\n\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/test/locale/fa.js",
    "content": "import {localeModule, test} from '../qunit';\nimport moment from '../../moment';\nlocaleModule('fa');\n\ntest('parse', function (assert) {\n    var tests = 'ژانویه_فوریه_مارس_آوریل_مه_ژوئن_ژوئیه_اوت_سپتامبر_اکتبر_نوامبر_دسامبر'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1) + ' instead is month ' + moment(input, mmm).month());\n    }\n    for (i = 0; i < 12; i++) {\n        equalTest(tests[i], 'MMM', i);\n        equalTest(tests[i], 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, MMMM Do YYYY, h:mm:ss a',      'یک\\u200cشنبه، فوریه ۱۴م ۲۰۱۰، ۳:۲۵:۵۰ بعد از ظهر'],\n            ['ddd, hA',                            'یک\\u200cشنبه، ۳بعد از ظهر'],\n            ['M Mo MM MMMM MMM',                   '۲ ۲م ۰۲ فوریه فوریه'],\n            ['YYYY YY',                            '۲۰۱۰ ۱۰'],\n            ['D Do DD',                            '۱۴ ۱۴م ۱۴'],\n            ['d do dddd ddd dd',                   '۰ ۰م یک\\u200cشنبه یک\\u200cشنبه ی'],\n            ['DDD DDDo DDDD',                      '۴۵ ۴۵م ۰۴۵'],\n            ['w wo ww',                            '۸ ۸م ۰۸'],\n            ['h hh',                               '۳ ۰۳'],\n            ['H HH',                               '۱۵ ۱۵'],\n            ['m mm',                               '۲۵ ۲۵'],\n            ['s ss',                               '۵۰ ۵۰'],\n            ['a A',                                'بعد از ظهر بعد از ظهر'],\n            ['DDDo [روز سال]',             '۴۵م روز سال'],\n            ['LTS',                                '۱۵:۲۵:۵۰'],\n            ['L',                                  '۱۴/۰۲/۲۰۱۰'],\n            ['LL',                                 '۱۴ فوریه ۲۰۱۰'],\n            ['LLL',                                '۱۴ فوریه ۲۰۱۰ ۱۵:۲۵'],\n            ['LLLL',                               'یک\\u200cشنبه، ۱۴ فوریه ۲۰۱۰ ۱۵:۲۵'],\n            ['l',                                  '۱۴/۲/۲۰۱۰'],\n            ['ll',                                 '۱۴ فوریه ۲۰۱۰'],\n            ['lll',                                '۱۴ فوریه ۲۰۱۰ ۱۵:۲۵'],\n            ['llll',                               'یک\\u200cشنبه، ۱۴ فوریه ۲۰۱۰ ۱۵:۲۵']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '۱م', '1');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '۲م', '2');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '۳م', '3');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '۴م', '4');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '۵م', '5');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '۶م', '6');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '۷م', '7');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '۸م', '8');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '۹م', '9');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '۱۰م', '10');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '۱۱م', '11');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '۱۲م', '12');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '۱۳م', '13');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '۱۴م', '14');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '۱۵م', '15');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '۱۶م', '16');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '۱۷م', '17');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '۱۸م', '18');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '۱۹م', '19');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '۲۰م', '20');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '۲۱م', '21');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '۲۲م', '22');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '۲۳م', '23');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '۲۴م', '24');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '۲۵م', '25');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '۲۶م', '26');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '۲۷م', '27');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '۲۸م', '28');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '۲۹م', '29');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '۳۰م', '30');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '۳۱م', '31');\n});\n\ntest('format month', function (assert) {\n    var expected = 'ژانویه ژانویه_فوریه فوریه_مارس مارس_آوریل آوریل_مه مه_ژوئن ژوئن_ژوئیه ژوئیه_اوت اوت_سپتامبر سپتامبر_اکتبر اکتبر_نوامبر نوامبر_دسامبر دسامبر'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'یک\\u200cشنبه یک\\u200cشنبه ی_دوشنبه دوشنبه د_سه\\u200cشنبه سه\\u200cشنبه س_چهارشنبه چهارشنبه چ_پنج\\u200cشنبه پنج\\u200cشنبه پ_جمعه جمعه ج_شنبه شنبه ش'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'چند ثانیه', '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'یک دقیقه',       '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'یک دقیقه',       '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '۲ دقیقه',     '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '۴۴ دقیقه',    '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'یک ساعت',     '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'یک ساعت',     '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '۲ ساعت',      '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '۵ ساعت',      '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '۲۱ ساعت',     '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'یک روز',      '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'یک روز',      '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '۲ روز',       '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'یک روز',      '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '۵ روز',       '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '۲۵ روز',      '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'یک ماه',      '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'یک ماه',      '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'یک ماه',      '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '۲ ماه',       '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '۲ ماه',       '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '۳ ماه',       '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'یک ماه',      '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '۵ ماه',       '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'یک سال',      '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '۲ سال',       '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'یک سال',      '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '۵ سال',       '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'در چند ثانیه', 'prefix');\n    assert.equal(moment(0).from(30000), 'چند ثانیه پیش', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'چند ثانیه پیش',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'در چند ثانیه', 'in a few seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), 'در ۵ روز', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'امروز ساعت ۱۲:۰۰', 'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'امروز ساعت ۱۲:۲۵', 'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'امروز ساعت ۱۳:۰۰', 'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'فردا ساعت ۱۲:۰۰', 'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'امروز ساعت ۱۱:۰۰', 'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'دیروز ساعت ۱۲:۰۰', 'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('dddd [ساعت] LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd [ساعت] LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd [ساعت] LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('dddd [پیش ساعت] LT'),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd [پیش ساعت] LT'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd [پیش ساعت] LT'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2011, 11, 31]).format('w ww wo'), '۱ ۰۱ ۱م', 'Dec 31 2011 should be week 1');\n    assert.equal(moment([2012,  0,  6]).format('w ww wo'), '۱ ۰۱ ۱م', 'Jan  6 2012 should be week 1');\n    assert.equal(moment([2012,  0,  7]).format('w ww wo'), '۲ ۰۲ ۲م', 'Jan  7 2012 should be week 2');\n    assert.equal(moment([2012,  0, 13]).format('w ww wo'), '۲ ۰۲ ۲م', 'Jan 13 2012 should be week 2');\n    assert.equal(moment([2012,  0, 14]).format('w ww wo'), '۳ ۰۳ ۳م', 'Jan 14 2012 should be week 3');\n});\n\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/test/locale/fi.js",
    "content": "import {localeModule, test} from '../qunit';\nimport moment from '../../moment';\nlocaleModule('fi');\n\ntest('parse', function (assert) {\n    var tests = 'tammikuu tammi_helmikuu helmi_maaliskuu maalis_huhtikuu huhti_toukokuu touko_kesäkuu kesä_heinäkuu heinä_elokuu elo_syyskuu syys_lokakuu loka_marraskuu marras_joulukuu joulu'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, MMMM Do YYYY, h:mm:ss a',      'sunnuntai, helmikuu 14. 2010, 3:25:50 pm'],\n            ['ddd, hA',                            'su, 3PM'],\n            ['M Mo MM MMMM MMM',                   '2 2. 02 helmikuu helmi'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14. 14'],\n            ['d do dddd ddd dd',                   '0 0. sunnuntai su su'],\n            ['DDD DDDo DDDD',                      '45 45. 045'],\n            ['w wo ww',                            '6 6. 06'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'pm PM'],\n            ['[vuoden] DDDo [päivä]',              'vuoden 45. päivä'],\n            ['LTS',                                '15.25.50'],\n            ['L',                                  '14.02.2010'],\n            ['LL',                                 '14. helmikuuta 2010'],\n            ['LLL',                                '14. helmikuuta 2010, klo 15.25'],\n            ['LLLL',                               'sunnuntai, 14. helmikuuta 2010, klo 15.25'],\n            ['l',                                  '14.2.2010'],\n            ['ll',                                 '14. helmi 2010'],\n            ['lll',                                '14. helmi 2010, klo 15.25'],\n            ['llll',                               'su, 14. helmi 2010, klo 15.25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1.', '1st');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2.', '2nd');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3.', '3rd');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4.', '4th');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5.', '5th');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6.', '6th');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7.', '7th');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8.', '8th');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9.', '9th');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10.', '10th');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11.', '11th');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12.', '12th');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13.', '13th');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14.', '14th');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15.', '15th');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16.', '16th');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17.', '17th');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18.', '18th');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19.', '19th');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20.', '20th');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21.', '21st');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22.', '22nd');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23.', '23rd');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24.', '24th');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25.', '25th');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26.', '26th');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27.', '27th');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28.', '28th');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29.', '29th');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30.', '30th');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31.', '31st');\n});\n\ntest('format month', function (assert) {\n    var expected = 'tammikuu tammi_helmikuu helmi_maaliskuu maalis_huhtikuu huhti_toukokuu touko_kesäkuu kesä_heinäkuu heinä_elokuu elo_syyskuu syys_lokakuu loka_marraskuu marras_joulukuu joulu'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'sunnuntai su su_maanantai ma ma_tiistai ti ti_keskiviikko ke ke_torstai to to_perjantai pe pe_lauantai la la'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'muutama sekunti', '44 seconds = few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'minuutti',      '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'minuutti',      '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  'kaksi minuuttia',     '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 minuuttia',    '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'tunti',       '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'tunti',       '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  'kaksi tuntia',       '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   'viisi tuntia',       '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 tuntia',      '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'päivä',         '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'päivä',         '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  'kaksi päivää',        '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'päivä',         '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   'viisi päivää',        '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 päivää',       '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'kuukausi',       '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'kuukausi',       '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'kuukausi',       '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  'kaksi kuukautta',      '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  'kaksi kuukautta',      '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  'kolme kuukautta',      '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'kuukausi',       '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   'viisi kuukautta',      '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'vuosi',        '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), 'kaksi vuotta',       '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'vuosi',        '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   'viisi vuotta',       '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'muutaman sekunnin päästä',  'prefix');\n    assert.equal(moment(0).from(30000), 'muutama sekunti sitten', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'muutama sekunti sitten',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'muutaman sekunnin päästä', 'in a few seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), 'viiden päivän päästä', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'tänään klo 12.00',    'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'tänään klo 12.25',    'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'tänään klo 13.00',    'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'huomenna klo 12.00',  'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'tänään klo 11.00',    'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'eilen klo 12.00',     'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('dddd [klo] LT'),  'today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd [klo] LT'),  'today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd [klo] LT'),  'today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('[viime] dddd[na] [klo] LT'),  'today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[viime] dddd[na] [klo] LT'),  'today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[viime] dddd[na] [klo] LT'),  'today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  'yksi viikko sitten');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'yhden viikon päästä');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  'kaksi viikkoa sitten');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'kaden viikon päästä');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2012, 0,  1]).format('w ww wo'), '52 52 52.', 'Jan  1 2012 should be week 52');\n    assert.equal(moment([2012, 0,  2]).format('w ww wo'),   '1 01 1.', 'Jan  2 2012 should be week 1');\n    assert.equal(moment([2012, 0,  8]).format('w ww wo'),   '1 01 1.', 'Jan  8 2012 should be week 1');\n    assert.equal(moment([2012, 0,  9]).format('w ww wo'),   '2 02 2.', 'Jan  9 2012 should be week 2');\n    assert.equal(moment([2012, 0, 15]).format('w ww wo'),   '2 02 2.', 'Jan 15 2012 should be week 2');\n});\n\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/test/locale/fo.js",
    "content": "import {localeModule, test} from '../qunit';\nimport moment from '../../moment';\nlocaleModule('fo');\n\ntest('parse', function (assert) {\n    var tests = 'januar jan_februar feb_mars mar_apríl apr_mai mai_juni jun_juli jul_august aug_september sep_oktober okt_november nov_desember des'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd [tann] Do MMMM YYYY, h:mm:ss a', 'sunnudagur tann 14. februar 2010, 3:25:50 pm'],\n            ['ddd hA',                             'sun 3PM'],\n            ['M Mo MM MMMM MMM',                   '2 2. 02 februar feb'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14. 14'],\n            ['d do dddd ddd dd',                   '0 0. sunnudagur sun su'],\n            ['DDD DDDo DDDD',                      '45 45. 045'],\n            ['w wo ww',                            '6 6. 06'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'pm PM'],\n            ['[tann] DDDo [dagin á árinum]',       'tann 45. dagin á árinum'],\n            ['LTS',                                '15:25:50'],\n            ['L',                                  '14/02/2010'],\n            ['LL',                                 '14 februar 2010'],\n            ['LLL',                                '14 februar 2010 15:25'],\n            ['LLLL',                               'sunnudagur 14. februar, 2010 15:25'],\n            ['l',                                  '14/2/2010'],\n            ['ll',                                 '14 feb 2010'],\n            ['lll',                                '14 feb 2010 15:25'],\n            ['llll',                               'sun 14. feb, 2010 15:25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1.', '1.');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2.', '2.');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3.', '3.');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4.', '4.');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5.', '5.');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6.', '6.');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7.', '7.');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8.', '8.');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9.', '9.');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10.', '10.');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11.', '11.');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12.', '12.');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13.', '13.');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14.', '14.');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15.', '15.');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16.', '16.');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17.', '17.');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18.', '18.');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19.', '19.');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20.', '20.');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21.', '21.');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22.', '22.');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23.', '23.');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24.', '24.');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25.', '25.');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26.', '26.');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27.', '27.');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28.', '28.');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29.', '29.');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30.', '30.');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31.', '31.');\n});\n\ntest('format month', function (assert) {\n    var expected = 'januar jan_februar feb_mars mar_apríl apr_mai mai_juni jun_juli jul_august aug_september sep_oktober okt_november nov_desember des'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'sunnudagur sun su_mánadagur mán má_týsdagur týs tý_mikudagur mik mi_hósdagur hós hó_fríggjadagur frí fr_leygardagur ley le'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'fá sekund', '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'ein minutt',    '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'ein minutt',    '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 minuttir',  '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 minuttir', '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'ein tími',     '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'ein tími',     '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 tímar',     '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 tímar',     '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 tímar',    '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'ein dagur',      '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'ein dagur',      '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 dagar',      '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'ein dagur',      '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 dagar',      '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 dagar',     '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'ein mánaði',    '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'ein mánaði',    '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'ein mánaði',    '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 mánaðir',   '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 mánaðir',   '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 mánaðir',   '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'ein mánaði',    '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 mánaðir',   '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'eitt ár',       '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 ár',        '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'eitt ár',       '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 ár',        '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'um fá sekund',  'prefix');\n    assert.equal(moment(0).from(30000), 'fá sekund síðani', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'fá sekund síðani',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'um fá sekund', 'in a few seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), 'um 5 dagar', 'in 5 days');\n});\n\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'Í dag kl. 12:00',    'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'Í dag kl. 12:25',    'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'Í dag kl. 13:00',    'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'Í morgin kl. 12:00', 'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'Í dag kl. 11:00',    'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'Í gjár kl. 12:00',   'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('dddd [kl.] LT'),  'today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd [kl.] LT'),  'today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd [kl.] LT'),  'today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('[síðstu] dddd [kl] LT'),  'today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[síðstu] dddd [kl] LT'),  'today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[síðstu] dddd [kl] LT'),  'today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  'yksi viikko sitten');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'yhden viikon päästä');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  'kaksi viikkoa sitten');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'kaden viikon päästä');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2012, 0,  1]).format('w ww wo'), '52 52 52.', 'Jan  1 2012 should be week 52');\n    assert.equal(moment([2012, 0,  2]).format('w ww wo'),   '1 01 1.', 'Jan  2 2012 should be week 1');\n    assert.equal(moment([2012, 0,  8]).format('w ww wo'),   '1 01 1.', 'Jan  8 2012 should be week 1');\n    assert.equal(moment([2012, 0,  9]).format('w ww wo'),   '2 02 2.', 'Jan  9 2012 should be week 2');\n    assert.equal(moment([2012, 0, 15]).format('w ww wo'),   '2 02 2.', 'Jan 15 2012 should be week 2');\n});\n\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/test/locale/fr-ca.js",
    "content": "import {localeModule, test} from '../qunit';\nimport moment from '../../moment';\nlocaleModule('fr-ca');\n\ntest('parse', function (assert) {\n    var i,\n        tests = 'janvier janv._février févr._mars mars_avril avr._mai mai_juin juin_juillet juil._août août_septembre sept._octobre oct._novembre nov._décembre déc.'.split('_');\n\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, MMMM Do YYYY, h:mm:ss a', 'dimanche, février 14e 2010, 3:25:50 pm'],\n            ['ddd, hA',                       'dim., 3PM'],\n            ['M Mo MM MMMM MMM',              '2 2e 02 février févr.'],\n            ['YYYY YY',                       '2010 10'],\n            ['D Do DD',                       '14 14e 14'],\n            ['d do dddd ddd dd',              '0 0e dimanche dim. Di'],\n            ['DDD DDDo DDDD',                 '45 45e 045'],\n            ['w wo ww',                       '8 8e 08'],\n            ['h hh',                          '3 03'],\n            ['H HH',                          '15 15'],\n            ['m mm',                          '25 25'],\n            ['s ss',                          '50 50'],\n            ['a A',                           'pm PM'],\n            ['[le] Do [jour du mois]',        'le 14e jour du mois'],\n            ['[le] DDDo [jour de l’année]',   'le 45e jour de l’année'],\n            ['LTS',                           '15:25:50'],\n            ['L',                             '2010-02-14'],\n            ['LL',                            '14 février 2010'],\n            ['LLL',                           '14 février 2010 15:25'],\n            ['LLLL',                          'dimanche 14 février 2010 15:25'],\n            ['l',                             '2010-2-14'],\n            ['ll',                            '14 févr. 2010'],\n            ['lll',                           '14 févr. 2010 15:25'],\n            ['llll',                          'dim. 14 févr. 2010 15:25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2017, 0, 1]).format('Mo'),     '1er',     '1er');\n    assert.equal(moment([2017, 1, 1]).format('Mo'),     '2e',      '2e');\n\n    assert.equal(moment([2017, 0, 1]).format('Qo'),     '1er',     '1er');\n    assert.equal(moment([2017, 3, 1]).format('Qo'),     '2e',      '2e');\n\n    assert.equal(moment([2017, 0, 1]).format('Do'),     '1er',     '1er');\n    assert.equal(moment([2017, 0, 2]).format('Do'),     '2e',      '2e');\n\n    assert.equal(moment([2011, 0, 1]).format('DDDo'),   '1er',     '1er');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'),   '2e',      '2e');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'),   '3e',      '3e');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'),   '4e',      '4e');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'),   '5e',      '5e');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'),   '6e',      '6e');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'),   '7e',      '7e');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'),   '8e',      '8e');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'),   '9e',      '9e');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'),  '10e',     '10e');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'),  '11e',     '11e');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'),  '12e',     '12e');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'),  '13e',     '13e');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'),  '14e',     '14e');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'),  '15e',     '15e');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'),  '16e',     '16e');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'),  '17e',     '17e');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'),  '18e',     '18e');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'),  '19e',     '19e');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'),  '20e',     '20e');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'),  '21e',     '21e');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'),  '22e',     '22e');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'),  '23e',     '23e');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'),  '24e',     '24e');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'),  '25e',     '25e');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'),  '26e',     '26e');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'),  '27e',     '27e');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'),  '28e',     '28e');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'),  '29e',     '29e');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'),  '30e',     '30e');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'),  '31e',     '31e');\n\n    assert.equal(moment([2017, 0, 1]).format('do'),     '0e',      '0e');\n    assert.equal(moment([2017, 0, 2]).format('do'),     '1er',     '1er');\n\n    assert.equal(moment([2017, 0, 4]).format('wo Wo'),  '1re 1re', '1re 1re');\n    assert.equal(moment([2017, 0, 11]).format('wo Wo'), '2e 2e',   '2e 2e');\n});\n\ntest('format month', function (assert) {\n    var i,\n        expected = 'janvier janv._février févr._mars mars_avril avr._mai mai_juin juin_juillet juil._août août_septembre sept._octobre oct._novembre nov._décembre déc.'.split('_');\n\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var i,\n        expected = 'dimanche dim. Di_lundi lun. Lu_mardi mar. Ma_mercredi mer. Me_jeudi jeu. Je_vendredi ven. Ve_samedi sam. Sa'.split('_');\n\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'quelques secondes', '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'une minute',        '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'une minute',        '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 minutes',         '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 minutes',        '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'une heure',         '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'une heure',         '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 heures',          '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 heures',          '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 heures',         '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'un jour',           '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'un jour',           '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 jours',           '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'un jour',           '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 jours',           '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 jours',          '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'un mois',           '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'un mois',           '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'un mois',           '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 mois',            '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 mois',            '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 mois',            '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'un mois',           '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 mois',            '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'un an',             '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 ans',             '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'un an',             '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 ans',             '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'dans quelques secondes',   'prefix');\n    assert.equal(moment(0).from(30000), 'il y a quelques secondes', 'suffix');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'dans quelques secondes', 'in a few seconds');\n    assert.equal(moment().add({d: 5}).fromNow(),  'dans 5 jours',           'in 5 days');\n});\n\ntest('same day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                  'Aujourd’hui à 12:00', 'Today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),     'Aujourd’hui à 12:25', 'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),      'Aujourd’hui à 13:00', 'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),      'Demain à 12:00',      'Tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(), 'Aujourd’hui à 11:00', 'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(), 'Hier à 12:00',        'Yesterday at the same time');\n});\n\ntest('same next week', function (assert) {\n    var i, m;\n\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(), m.format('dddd [à] LT'), 'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(), m.format('dddd [à] LT'), 'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(), m.format('dddd [à] LT'), 'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('same last week', function (assert) {\n    var i, m;\n\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(), m.format('dddd [dernier à] LT'), 'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(), m.format('dddd [dernier à] LT'), 'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(), m.format('dddd [dernier à] LT'), 'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('same all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),     weeksAgo.format('L'),     '1 week ago');\n    assert.equal(weeksFromNow.calendar(), weeksFromNow.format('L'), 'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),     weeksAgo.format('L'),     '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(), weeksFromNow.format('L'), 'in 2 weeks');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2012, 0,  1]).format('w ww wo'), '1 01 1re', 'Jan  1 2012 should be week 1');\n    assert.equal(moment([2012, 0,  7]).format('w ww wo'), '1 01 1re', 'Jan  7 2012 should be week 1');\n    assert.equal(moment([2012, 0,  8]).format('w ww wo'), '2 02 2e',  'Jan  8 2012 should be week 2');\n    assert.equal(moment([2012, 0, 14]).format('w ww wo'), '2 02 2e',  'Jan 14 2012 should be week 2');\n    assert.equal(moment([2012, 0, 15]).format('w ww wo'), '3 03 3e',  'Jan 15 2012 should be week 3');\n});\n\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/test/locale/fr-ch.js",
    "content": "import {localeModule, test} from '../qunit';\nimport moment from '../../moment';\nlocaleModule('fr-ch');\n\ntest('parse', function (assert) {\n    var i,\n        tests = 'janvier janv._février févr._mars mars_avril avr._mai mai_juin juin_juillet juil._août août_septembre sept._octobre oct._novembre nov._décembre déc.'.split('_');\n\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, MMMM Do YYYY, h:mm:ss a', 'dimanche, février 14e 2010, 3:25:50 pm'],\n            ['ddd, hA',                       'dim., 3PM'],\n            ['M Mo MM MMMM MMM',              '2 2e 02 février févr.'],\n            ['YYYY YY',                       '2010 10'],\n            ['D Do DD',                       '14 14e 14'],\n            ['d do dddd ddd dd',              '0 0e dimanche dim. Di'],\n            ['DDD DDDo DDDD',                 '45 45e 045'],\n            ['w wo ww',                       '6 6e 06'],\n            ['h hh',                          '3 03'],\n            ['H HH',                          '15 15'],\n            ['m mm',                          '25 25'],\n            ['s ss',                          '50 50'],\n            ['a A',                           'pm PM'],\n            ['[le] Do [jour du mois]',        'le 14e jour du mois'],\n            ['[le] DDDo [jour de l’année]',   'le 45e jour de l’année'],\n            ['LTS',                           '15:25:50'],\n            ['L',                             '14.02.2010'],\n            ['LL',                            '14 février 2010'],\n            ['LLL',                           '14 février 2010 15:25'],\n            ['LLLL',                          'dimanche 14 février 2010 15:25'],\n            ['l',                             '14.2.2010'],\n            ['ll',                            '14 févr. 2010'],\n            ['lll',                           '14 févr. 2010 15:25'],\n            ['llll',                          'dim. 14 févr. 2010 15:25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2017, 0, 1]).format('Mo'),     '1er',     '1er');\n    assert.equal(moment([2017, 1, 1]).format('Mo'),     '2e',      '2e');\n\n    assert.equal(moment([2017, 0, 1]).format('Qo'),     '1er',     '1er');\n    assert.equal(moment([2017, 3, 1]).format('Qo'),     '2e',      '2e');\n\n    assert.equal(moment([2017, 0, 1]).format('Do'),     '1er',     '1er');\n    assert.equal(moment([2017, 0, 2]).format('Do'),     '2e',      '2e');\n\n    assert.equal(moment([2011, 0, 1]).format('DDDo'),   '1er',     '1er');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'),   '2e',      '2e');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'),   '3e',      '3e');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'),   '4e',      '4e');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'),   '5e',      '5e');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'),   '6e',      '6e');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'),   '7e',      '7e');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'),   '8e',      '8e');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'),   '9e',      '9e');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'),  '10e',     '10e');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'),  '11e',     '11e');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'),  '12e',     '12e');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'),  '13e',     '13e');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'),  '14e',     '14e');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'),  '15e',     '15e');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'),  '16e',     '16e');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'),  '17e',     '17e');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'),  '18e',     '18e');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'),  '19e',     '19e');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'),  '20e',     '20e');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'),  '21e',     '21e');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'),  '22e',     '22e');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'),  '23e',     '23e');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'),  '24e',     '24e');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'),  '25e',     '25e');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'),  '26e',     '26e');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'),  '27e',     '27e');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'),  '28e',     '28e');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'),  '29e',     '29e');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'),  '30e',     '30e');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'),  '31e',     '31e');\n\n    assert.equal(moment([2017, 0, 1]).format('do'),     '0e',      '0e');\n    assert.equal(moment([2017, 0, 2]).format('do'),     '1er',     '1er');\n\n    assert.equal(moment([2017, 0, 4]).format('wo Wo'),  '1re 1re', '1re 1re');\n    assert.equal(moment([2017, 0, 11]).format('wo Wo'), '2e 2e',   '2e 2e');\n});\n\ntest('format month', function (assert) {\n    var i,\n        expected = 'janvier janv._février févr._mars mars_avril avr._mai mai_juin juin_juillet juil._août août_septembre sept._octobre oct._novembre nov._décembre déc.'.split('_');\n\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var i,\n        expected = 'dimanche dim. Di_lundi lun. Lu_mardi mar. Ma_mercredi mer. Me_jeudi jeu. Je_vendredi ven. Ve_samedi sam. Sa'.split('_');\n\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'quelques secondes', '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'une minute',        '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'une minute',        '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 minutes',         '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 minutes',        '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'une heure',         '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'une heure',         '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 heures',          '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 heures',          '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 heures',         '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'un jour',           '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'un jour',           '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 jours',           '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'un jour',           '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 jours',           '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 jours',          '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'un mois',           '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'un mois',           '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'un mois',           '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 mois',            '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 mois',            '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 mois',            '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'un mois',           '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 mois',            '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'un an',             '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 ans',             '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'un an',             '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 ans',             '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'dans quelques secondes',   'prefix');\n    assert.equal(moment(0).from(30000), 'il y a quelques secondes', 'suffix');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'dans quelques secondes', 'in a few seconds');\n    assert.equal(moment().add({d: 5}).fromNow(),  'dans 5 jours',           'in 5 days');\n});\n\ntest('same day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                  'Aujourd’hui à 12:00', 'Today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),     'Aujourd’hui à 12:25', 'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),      'Aujourd’hui à 13:00', 'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),      'Demain à 12:00',      'Tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(), 'Aujourd’hui à 11:00', 'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(), 'Hier à 12:00',        'Yesterday at the same time');\n});\n\ntest('same next week', function (assert) {\n    var i, m;\n\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(), m.format('dddd [à] LT'), 'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(), m.format('dddd [à] LT'), 'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(), m.format('dddd [à] LT'), 'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('same last week', function (assert) {\n    var i, m;\n\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(), m.format('dddd [dernier à] LT'), 'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(), m.format('dddd [dernier à] LT'), 'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(), m.format('dddd [dernier à] LT'), 'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('same all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),     weeksAgo.format('L'),     '1 week ago');\n    assert.equal(weeksFromNow.calendar(), weeksFromNow.format('L'), 'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),     weeksAgo.format('L'),     '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(), weeksFromNow.format('L'), 'in 2 weeks');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2012, 0,  1]).format('w ww wo'), '52 52 52e', 'Jan  1 2012 should be week 52');\n    assert.equal(moment([2012, 0,  2]).format('w ww wo'), '1 01 1re',  'Jan  2 2012 should be week 1');\n    assert.equal(moment([2012, 0,  8]).format('w ww wo'), '1 01 1re',  'Jan  8 2012 should be week 1');\n    assert.equal(moment([2012, 0,  9]).format('w ww wo'), '2 02 2e',   'Jan  9 2012 should be week 2');\n    assert.equal(moment([2012, 0, 15]).format('w ww wo'), '2 02 2e',   'Jan 15 2012 should be week 2');\n});\n\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/test/locale/fr.js",
    "content": "import {localeModule, test} from '../qunit';\nimport moment from '../../moment';\nlocaleModule('fr');\n\ntest('parse', function (assert) {\n    var i,\n        tests = 'janvier janv._février févr._mars mars_avril avr._mai mai_juin juin_juillet juil._août août_septembre sept._octobre oct._novembre nov._décembre déc.'.split('_');\n\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, MMMM Do YYYY, h:mm:ss a', 'dimanche, février 14 2010, 3:25:50 pm'],\n            ['ddd, hA',                       'dim., 3PM'],\n            ['M Mo MM MMMM MMM',              '2 2e 02 février févr.'],\n            ['YYYY YY',                       '2010 10'],\n            ['D Do DD',                       '14 14 14'],\n            ['d do dddd ddd dd',              '0 0e dimanche dim. Di'],\n            ['DDD DDDo DDDD',                 '45 45e 045'],\n            ['w wo ww',                       '6 6e 06'],\n            ['h hh',                          '3 03'],\n            ['H HH',                          '15 15'],\n            ['m mm',                          '25 25'],\n            ['s ss',                          '50 50'],\n            ['a A',                           'pm PM'],\n            ['[le] Do [jour du mois]',        'le 14 jour du mois'],\n            ['[le] DDDo [jour de l’année]',   'le 45e jour de l’année'],\n            ['LTS',                           '15:25:50'],\n            ['L',                             '14/02/2010'],\n            ['LL',                            '14 février 2010'],\n            ['LLL',                           '14 février 2010 15:25'],\n            ['LLLL',                          'dimanche 14 février 2010 15:25'],\n            ['l',                             '14/2/2010'],\n            ['ll',                            '14 févr. 2010'],\n            ['lll',                           '14 févr. 2010 15:25'],\n            ['llll',                          'dim. 14 févr. 2010 15:25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2017, 0, 1]).format('Mo'),     '1er',     '1er');\n    assert.equal(moment([2017, 1, 1]).format('Mo'),     '2e',      '2e');\n\n    assert.equal(moment([2017, 0, 1]).format('Qo'),     '1er',     '1er');\n    assert.equal(moment([2017, 3, 1]).format('Qo'),     '2e',      '2e');\n\n    assert.equal(moment([2017, 0, 1]).format('Do'),     '1er',     '1er');\n    assert.equal(moment([2017, 0, 2]).format('Do'),     '2',       '2');\n\n    assert.equal(moment([2011, 0, 1]).format('DDDo'),   '1er',     '1er');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'),   '2e',      '2e');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'),   '3e',      '3e');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'),   '4e',      '4e');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'),   '5e',      '5e');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'),   '6e',      '6e');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'),   '7e',      '7e');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'),   '8e',      '8e');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'),   '9e',      '9e');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'),  '10e',     '10e');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'),  '11e',     '11e');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'),  '12e',     '12e');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'),  '13e',     '13e');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'),  '14e',     '14e');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'),  '15e',     '15e');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'),  '16e',     '16e');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'),  '17e',     '17e');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'),  '18e',     '18e');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'),  '19e',     '19e');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'),  '20e',     '20e');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'),  '21e',     '21e');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'),  '22e',     '22e');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'),  '23e',     '23e');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'),  '24e',     '24e');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'),  '25e',     '25e');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'),  '26e',     '26e');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'),  '27e',     '27e');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'),  '28e',     '28e');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'),  '29e',     '29e');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'),  '30e',     '30e');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'),  '31e',     '31e');\n\n    assert.equal(moment([2017, 0, 1]).format('do'),     '0e',      '0e');\n    assert.equal(moment([2017, 0, 2]).format('do'),     '1er',     '1er');\n\n    assert.equal(moment([2017, 0, 4]).format('wo Wo'),  '1re 1re', '1re 1re');\n    assert.equal(moment([2017, 0, 11]).format('wo Wo'), '2e 2e',   '2e 2e');\n});\n\ntest('format month', function (assert) {\n    var i,\n        expected = 'janvier janv._février févr._mars mars_avril avr._mai mai_juin juin_juillet juil._août août_septembre sept._octobre oct._novembre nov._décembre déc.'.split('_');\n\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var i,\n        expected = 'dimanche dim. Di_lundi lun. Lu_mardi mar. Ma_mercredi mer. Me_jeudi jeu. Je_vendredi ven. Ve_samedi sam. Sa'.split('_');\n\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'quelques secondes', '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'une minute',        '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'une minute',        '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 minutes',         '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 minutes',        '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'une heure',         '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'une heure',         '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 heures',          '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 heures',          '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 heures',         '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'un jour',           '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'un jour',           '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 jours',           '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'un jour',           '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 jours',           '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 jours',          '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'un mois',           '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'un mois',           '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'un mois',           '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 mois',            '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 mois',            '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 mois',            '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'un mois',           '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 mois',            '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'un an',             '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 ans',             '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'un an',             '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 ans',             '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'dans quelques secondes',   'prefix');\n    assert.equal(moment(0).from(30000), 'il y a quelques secondes', 'suffix');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'dans quelques secondes', 'in a few seconds');\n    assert.equal(moment().add({d: 5}).fromNow(),  'dans 5 jours',           'in 5 days');\n});\n\ntest('same day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                  'Aujourd’hui à 12:00', 'Today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),     'Aujourd’hui à 12:25', 'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),      'Aujourd’hui à 13:00', 'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),      'Demain à 12:00',      'Tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(), 'Aujourd’hui à 11:00', 'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(), 'Hier à 12:00',        'Yesterday at the same time');\n});\n\ntest('same next week', function (assert) {\n    var i, m;\n\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(), m.format('dddd [à] LT'), 'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(), m.format('dddd [à] LT'), 'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(), m.format('dddd [à] LT'), 'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('same last week', function (assert) {\n    var i, m;\n\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(), m.format('dddd [dernier à] LT'), 'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(), m.format('dddd [dernier à] LT'), 'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(), m.format('dddd [dernier à] LT'), 'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('same all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),     weeksAgo.format('L'),     '1 week ago');\n    assert.equal(weeksFromNow.calendar(), weeksFromNow.format('L'), 'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),     weeksAgo.format('L'),     '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(), weeksFromNow.format('L'), 'in 2 weeks');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2012, 0,  1]).format('w ww wo'), '52 52 52e', 'Jan  1 2012 should be week 52');\n    assert.equal(moment([2012, 0,  2]).format('w ww wo'), '1 01 1re',  'Jan  2 2012 should be week 1');\n    assert.equal(moment([2012, 0,  8]).format('w ww wo'), '1 01 1re',  'Jan  8 2012 should be week 1');\n    assert.equal(moment([2012, 0,  9]).format('w ww wo'), '2 02 2e',   'Jan  9 2012 should be week 2');\n    assert.equal(moment([2012, 0, 15]).format('w ww wo'), '2 02 2e',   'Jan 15 2012 should be week 2');\n});\n\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/test/locale/fy.js",
    "content": "import {localeModule, test} from '../qunit';\nimport moment from '../../moment';\nlocaleModule('fy');\n\ntest('parse', function (assert) {\n    var tests = 'jannewaris jan._febrewaris feb._maart mrt._april apr._maaie mai._juny jun._july jul._augustus aug._septimber sep._oktober okt._novimber nov._desimber des.'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, MMMM Do YYYY, HH:mm:ss',       'snein, febrewaris 14de 2010, 15:25:50'],\n            ['ddd, HH',                            'si., 15'],\n            ['M Mo MM MMMM MMM',                   '2 2de 02 febrewaris feb.'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14de 14'],\n            ['d do dddd ddd dd',                   '0 0de snein si. Si'],\n            ['DDD DDDo DDDD',                      '45 45ste 045'],\n            ['w wo ww',                            '6 6de 06'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'pm PM'],\n            ['[the] DDDo [day of the year]',       'the 45ste day of the year'],\n            ['LTS',                                '15:25:50'],\n            ['L',                                  '14-02-2010'],\n            ['LL',                                 '14 febrewaris 2010'],\n            ['LLL',                                '14 febrewaris 2010 15:25'],\n            ['LLLL',                               'snein 14 febrewaris 2010 15:25'],\n            ['l',                                  '14-2-2010'],\n            ['ll',                                 '14 feb. 2010'],\n            ['lll',                                '14 feb. 2010 15:25'],\n            ['llll',                               'si. 14 feb. 2010 15:25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1ste', '1ste');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2de', '2de');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3de', '3de');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4de', '4de');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5de', '5de');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6de', '6de');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7de', '7de');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8ste', '8ste');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9de', '9de');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10de', '10de');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11de', '11de');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12de', '12de');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13de', '13de');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14de', '14de');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15de', '15de');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16de', '16de');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17de', '17de');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18de', '18de');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19de', '19de');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20ste', '20ste');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21ste', '21ste');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22ste', '22ste');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23ste', '23ste');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24ste', '24ste');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25ste', '25ste');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26ste', '26ste');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27ste', '27ste');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28ste', '28ste');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29ste', '29ste');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30ste', '30ste');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31ste', '31ste');\n});\n\ntest('format month', function (assert) {\n    var expected = 'jannewaris jan._febrewaris feb._maart mrt._april apr._maaie mai_juny jun._july jul._augustus aug._septimber sep._oktober okt._novimber nov._desimber des.'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'snein si. Si_moandei mo. Mo_tiisdei ti. Ti_woansdei wo. Wo_tongersdei to. To_freed fr. Fr_sneon so. So'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'in pear sekonden', '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'ien minút',      '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'ien minút',      '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 minuten',     '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 minuten',    '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'ien oere',       '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'ien oere',       '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 oeren',       '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 oeren',       '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 oeren',      '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'ien dei',         '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'ien dei',         '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 dagen',        '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'ien dei',         '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 dagen',        '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 dagen',       '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'ien moanne',       '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'ien moanne',       '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'ien moanne',       '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 moannen',      '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 moannen',      '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 moannen',      '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'ien moanne',       '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 moannen',      '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'ien jier',        '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 jierren',       '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'ien jier',        '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 jierren',       '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'oer in pear sekonden',  'prefix');\n    assert.equal(moment(0).from(30000), 'in pear sekonden lyn', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'in pear sekonden lyn',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'oer in pear sekonden', 'in a few seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), 'oer 5 dagen', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'hjoed om 12:00',     'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'hjoed om 12:25',     'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'hjoed om 13:00',     'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'moarn om 12:00',     'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'hjoed om 11:00',     'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'juster om 12:00',    'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('dddd [om] LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd [om] LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd [om] LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('[ôfrûne] dddd [om] LT'),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[ôfrûne] dddd [om] LT'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[ôfrûne] dddd [om] LT'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('month abbreviation', function (assert) {\n    assert.equal(moment([2012, 5, 23]).format('D-MMM-YYYY'), '23-jun-2012', 'format month abbreviation surrounded by dashes should not include a dot');\n    assert.equal(moment([2012, 5, 23]).format('D MMM YYYY'), '23 jun. 2012', 'format month abbreviation not surrounded by dashes should include a dot');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2012, 0,  1]).format('w ww wo'), '52 52 52ste', 'Jan  1 2012 should be week 52');\n    assert.equal(moment([2012, 0,  2]).format('w ww wo'),   '1 01 1ste', 'Jan  2 2012 should be week 1');\n    assert.equal(moment([2012, 0,  8]).format('w ww wo'),   '1 01 1ste', 'Jan  8 2012 should be week 1');\n    assert.equal(moment([2012, 0,  9]).format('w ww wo'),    '2 02 2de', 'Jan  9 2012 should be week 2');\n    assert.equal(moment([2012, 0, 15]).format('w ww wo'),    '2 02 2de', 'Jan 15 2012 should be week 2');\n});\n\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/test/locale/gd.js",
    "content": "import {localeModule, test} from '../qunit';\nimport moment from '../../moment';\nlocaleModule('gd');\n\nvar months = [\n    'Am Faoilleach,Faoi',\n    'An Gearran,Gear',\n    'Am Màrt,Màrt',\n    'An Giblean,Gibl',\n    'An Cèitean,Cèit',\n    'An t-Ògmhios,Ògmh',\n    'An t-Iuchar,Iuch',\n    'An Lùnastal,Lùn',\n    'An t-Sultain,Sult',\n    'An Dàmhair,Dàmh',\n    'An t-Samhain,Samh',\n    'An Dùbhlachd,Dùbh'\n];\n\ntest('parse', function (assert) {\n    function equalTest(monthName, monthFormat, monthNum) {\n        assert.equal(moment(monthName, monthFormat).month(), monthNum, monthName + ' should be month ' + (monthNum + 1));\n    }\n\n    for (var i = 0; i < 12; i++) {\n        var testMonth = months[i].split(',');\n        equalTest(testMonth[0], 'MMM', i);\n        equalTest(testMonth[1], 'MMM', i);\n        equalTest(testMonth[0], 'MMMM', i);\n        equalTest(testMonth[1], 'MMMM', i);\n        equalTest(testMonth[0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(testMonth[1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(testMonth[0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(testMonth[1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n        ['dddd, MMMM Do YYYY, h:mm:ss a', 'Didòmhnaich, An Gearran 14mh 2010, 3:25:50 pm'],\n        ['ddd, hA', 'Did, 3PM'],\n        ['M Mo MM MMMM MMM', '2 2na 02 An Gearran Gear'],\n        ['YYYY YY', '2010 10'],\n        ['D Do DD', '14 14mh 14'],\n        ['d do dddd ddd dd', '0 0mh Didòmhnaich Did Dò'],\n        ['DDD DDDo DDDD', '45 45mh 045'],\n        ['w wo ww', '6 6mh 06'],\n        ['h hh', '3 03'],\n        ['H HH', '15 15'],\n        ['m mm', '25 25'],\n        ['s ss', '50 50'],\n        ['a A', 'pm PM'],\n        ['[an] DDDo [latha den bhliadhna]', 'an 45mh latha den bhliadhna'],\n        ['LTS', '15:25:50'],\n        ['L', '14/02/2010'],\n        ['LL', '14 An Gearran 2010'],\n        ['LLL', '14 An Gearran 2010 15:25'],\n        ['LLLL', 'Didòmhnaich, 14 An Gearran 2010 15:25'],\n        ['l', '14/2/2010'],\n        ['ll', '14 Gear 2010'],\n        ['lll', '14 Gear 2010 15:25'],\n        ['llll', 'Did, 14 Gear 2010 15:25']\n    ],\n    b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n    i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1d', '1d');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2na', '2na');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3mh', '3mh');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4mh', '4mh');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5mh', '5mh');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6mh', '6mh');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7mh', '7mh');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8mh', '8mh');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9mh', '9mh');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10mh', '10mh');\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11mh', '11mh');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12na', '12na');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13mh', '13mh');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14mh', '14mh');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15mh', '15mh');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16mh', '16mh');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17mh', '17mh');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18mh', '18mh');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19mh', '19mh');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20mh', '20mh');\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21mh', '21mh');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22na', '22na');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23mh', '23mh');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24mh', '24mh');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25mh', '25mh');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26mh', '26mh');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27mh', '27mh');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28mh', '28mh');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29mh', '29mh');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30mh', '30mh');\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31mh', '31mh');\n});\n\ntest('format month', function (assert) {\n    var expected = months;\n    for (var i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM,MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = ['Didòmhnaich Did Dò', 'Diluain Dil Lu', 'Dimàirt Dim Mà', 'Diciadain Dic Ci', 'Diardaoin Dia Ar', 'Dihaoine Dih Ha', 'Disathairne Dis Sa'];\n    for (var i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true), 'beagan diogan', '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true), 'mionaid', '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true), 'mionaid', '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true), '2 mionaidean', '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true), '44 mionaidean', '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true), 'uair', '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true), 'uair', '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true), '2 uairean', '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true), '5 uairean', '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true), '21 uairean', '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true), 'latha', '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true), 'latha', '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true), '2 latha', '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true), 'latha', '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true), '5 latha', '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true), '25 latha', '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true), 'mìos', '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true), 'mìos', '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true), 'mìos', '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true), '2 mìosan', '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true), '2 mìosan', '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true), '3 mìosan', '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true), 'mìos', '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true), '5 mìosan', '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'bliadhna', '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 bliadhna', '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true), 'bliadhna', '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true), '5 bliadhna', '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'ann an beagan diogan', 'prefix');\n    assert.equal(moment(0).from(30000), 'bho chionn beagan diogan', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'bho chionn beagan diogan', 'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'ann an beagan diogan', 'in a few seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), 'ann an 5 latha', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                  'An-diugh aig 12:00',   'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),     'An-diugh aig 12:25',   'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),      'An-diugh aig 13:00',   'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),      'A-màireach aig 12:00', 'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(), 'An-diugh aig 11:00',   'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(), 'An-dè aig 12:00',      'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(), m.format('dddd [aig] LT'), 'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(), m.format('dddd [aig] LT'), 'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(), m.format('dddd [aig] LT'), 'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(), m.format('dddd [seo chaidh] [aig] LT'), 'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(), m.format('dddd [seo chaidh] [aig] LT'), 'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(), m.format('dddd [seo chaidh] [aig] LT'), 'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n       weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '1 week ago');\n    assert.equal(weeksFromNow.calendar(), weeksFromNow.format('L'), 'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(), weeksFromNow.format('L'), 'in 2 weeks');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2012, 0, 1]).format('w ww wo'), '52 52 52na', 'Faoi  1 2012 should be week 52');\n    assert.equal(moment([2012, 0, 2]).format('w ww wo'), '1 01 1d', 'Faoi  2 2012 should be week 1');\n    assert.equal(moment([2012, 0, 8]).format('w ww wo'), '1 01 1d', 'Faoi  8 2012 should be week 1');\n    assert.equal(moment([2012, 0, 9]).format('w ww wo'), '2 02 2na', 'Faoi  9 2012 should be week 2');\n    assert.equal(moment([2012, 0, 15]).format('w ww wo'), '2 02 2na', 'Faoi 15 2012 should be week 2');\n});\n\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/test/locale/gl.js",
    "content": "import {localeModule, test} from '../qunit';\nimport moment from '../../moment';\nlocaleModule('gl');\n\ntest('parse', function (assert) {\n    var tests = 'xaneiro xan._febreiro feb._marzo mar._abril abr._maio mai._xuño xuñ._xullo xul._agosto ago._setembro set._outubro out._novembro nov._decembro dec.'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, MMMM Do YYYY, h:mm:ss a',      'domingo, febreiro 14º 2010, 3:25:50 pm'],\n            ['ddd, hA',                            'dom., 3PM'],\n            ['M Mo MM MMMM MMM',                   '2 2º 02 febreiro feb.'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14º 14'],\n            ['d do dddd ddd dd',                   '0 0º domingo dom. do'],\n            ['DDD DDDo DDDD',                      '45 45º 045'],\n            ['w wo ww',                            '6 6º 06'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'pm PM'],\n            ['[the] DDDo [day of the year]',       'the 45º day of the year'],\n            ['LTS',                                '15:25:50'],\n            ['L',                                  '14/02/2010'],\n            ['LL',                                 '14 de febreiro de 2010'],\n            ['LLL',                                '14 de febreiro de 2010 15:25'],\n            ['LLLL',                               'domingo, 14 de febreiro de 2010 15:25'],\n            ['l',                                  '14/2/2010'],\n            ['ll',                                 '14 de feb. de 2010'],\n            ['lll',                                '14 de feb. de 2010 15:25'],\n            ['llll',                               'dom., 14 de feb. de 2010 15:25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1º', '1º');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2º', '2º');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3º', '3º');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4º', '4º');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5º', '5º');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6º', '6º');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7º', '7º');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8º', '8º');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9º', '9º');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10º', '10º');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11º', '11º');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12º', '12º');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13º', '13º');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14º', '14º');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15º', '15º');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16º', '16º');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17º', '17º');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18º', '18º');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19º', '19º');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20º', '20º');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21º', '21º');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22º', '22º');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23º', '23º');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24º', '24º');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25º', '25º');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26º', '26º');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27º', '27º');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28º', '28º');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29º', '29º');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30º', '30º');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31º', '31º');\n});\n\ntest('format month', function (assert) {\n    var expected = 'xaneiro xan._febreiro feb._marzo mar._abril abr._maio mai._xuño xuñ._xullo xul._agosto ago._setembro set._outubro out._novembro nov._decembro dec.'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'domingo dom. do_luns lun. lu_martes mar. ma_mércores mér. mé_xoves xov. xo_venres ven. ve_sábado sáb. sá'.split('_'),\n    i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'uns segundos', '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'un minuto',      '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'un minuto',      '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 minutos',     '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 minutos',    '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'unha hora',       '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'unha hora',       '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 horas',       '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 horas',       '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 horas',      '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'un día',         '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'un día',         '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 días',        '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'un día',         '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 días',        '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 días',       '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'un mes',       '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'un mes',       '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'un mes',       '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 meses',      '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 meses',      '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 meses',      '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'un mes',       '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 meses',      '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'un ano',        '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 anos',       '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'un ano',        '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 anos',       '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'nuns segundos',  'prefix');\n    assert.equal(moment(0).from(30000), 'hai uns segundos', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'hai uns segundos',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'nuns segundos', 'nuns segundos');\n    assert.equal(moment().add({d: 5}).fromNow(), 'en 5 días', 'en 5 días');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                       'hoxe ás 12:00',  'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),          'hoxe ás 12:25',  'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),           'hoxe ás 13:00',  'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),           'mañá ás 12:00',  'tomorrow at the same time');\n    assert.equal(moment(a).add({d: 1, h : -1}).calendar(),   'mañá ás 11:00',   'tomorrow minus 1 hour');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),      'hoxe ás 11:00',   'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),      'onte á 12:00',   'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('dddd [' + ((m.hours() !== 1) ? 'ás' : 'a') + '] LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd [' + ((m.hours() !== 1) ? 'ás' : 'a') + '] LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd [' + ((m.hours() !== 1) ? 'ás' : 'a') + '] LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('[o] dddd [pasado ' + ((m.hours() !== 1) ? 'ás' : 'a') + '] LT'),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[o] dddd [pasado ' + ((m.hours() !== 1) ? 'ás' : 'a') + '] LT'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[o] dddd [pasado ' + ((m.hours() !== 1) ? 'ás' : 'a') + '] LT'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('regression tests', function (assert) {\n    var lastWeek = moment().subtract({d: 4}).hours(1);\n    assert.equal(lastWeek.calendar(), lastWeek.format('[o] dddd [pasado a] LT'), '1 o\\'clock bug');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2012, 0,  1]).format('w ww wo'), '52 52 52º', 'Jan  1 2012 should be week 52');\n    assert.equal(moment([2012, 0,  2]).format('w ww wo'),   '1 01 1º', 'Jan  2 2012 should be week 1');\n    assert.equal(moment([2012, 0,  8]).format('w ww wo'),   '1 01 1º', 'Jan  8 2012 should be week 1');\n    assert.equal(moment([2012, 0,  9]).format('w ww wo'),   '2 02 2º', 'Jan  9 2012 should be week 2');\n    assert.equal(moment([2012, 0, 15]).format('w ww wo'),   '2 02 2º', 'Jan 15 2012 should be week 2');\n});\n\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/test/locale/gom-latn.js",
    "content": "import {localeModule, test} from '../qunit';\nimport moment from '../../moment';\nlocaleModule('gom-latn');\n\ntest('parse', function (assert) {\n    var i,\n        tests = 'Janer Jan._Febrer Feb._Mars Mars_Abril Abr._Mai Mai_Jun Jun_Julai Jul._Agost Ago._Setembr Set._Otubr Otu._Novembr Nov._Dezembr Dez.'.split('_');\n\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, MMMM Do YYYY, h:mm:ss a',      'Aitar, Febrer 14er 2010, 3:25:50 donparam'],\n            ['ddd, hA',                            'Ait., 3donparam'],\n            ['M Mo MM MMMM MMM',                   '2 2 02 Febrer Feb.'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14er 14'],\n            ['d do dddd ddd dd',                   '0 0 Aitar Ait. Ai'],\n            ['DDD DDDo DDDD',                      '45 45 045'],\n            ['w wo ww',                            '6 6 06'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'donparam donparam'],\n            ['[the] DDDo [day of the year]',       'the 45 day of the year'],\n            ['LTS',                                'donparam 3:25:50 vazta'],\n            ['L',                                  '14-02-2010'],\n            ['LL',                                 '14 Febrer 2010'],\n            ['LLL',                                '14 Febrer 2010 donparam 3:25 vazta'],\n            ['LLLL',                               'Aitar, Febrerachea 14er, 2010, donparam 3:25 vazta'],\n            ['l',                                  '14-2-2010'],\n            ['ll',                                 '14 Feb. 2010'],\n            ['lll',                                '14 Feb. 2010 donparam 3:25 vazta'],\n            ['llll',                               'Ait., 14 Feb. 2010, donparam 3:25 vazta']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1', '1');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2', '2');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3', '3');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4', '4');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5', '5');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6', '6');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7', '7');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8', '8');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9', '9');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10', '10');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11', '11');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12', '12');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13', '13');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14', '14');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15', '15');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16', '16');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17', '17');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18', '18');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19', '19');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20', '20');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21', '21');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22', '22');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23', '23');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24', '24');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25', '25');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26', '26');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27', '27');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28', '28');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29', '29');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30', '30');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31', '31');\n});\n\ntest('format month', function (assert) {\n    var i,\n        expected = 'Janer Jan._Febrer Feb._Mars Mars_Abril Abr._Mai Mai_Jun Jun_Julai Jul._Agost Ago._Setembr Set._Otubr Otu._Novembr Nov._Dezembr Dez.'.split('_');\n\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var i,\n        expected = 'Aitar Ait. Ai_Somar Som. Sm_Mongllar Mon. Mo_Budvar Bud. Bu_Brestar Bre. Br_Sukrar Suk. Su_Son\\'var Son. Sn'.split('_');\n\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'thodde secondanim', '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'eka mintan',      '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'eka mintan',      '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 mintanim',     '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 mintanim',    '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'eka horan',       '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'eka horan',       '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 horanim',       '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 horanim',       '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 horanim',      '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'eka disan',         '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'eka disan',         '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 disanim',        '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'eka disan',         '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 disanim',        '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 disanim',       '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'eka mhoinean',       '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'eka mhoinean',       '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'eka mhoinean',       '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 mhoineanim',      '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 mhoineanim',      '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 mhoineanim',      '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'eka mhoinean',       '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 mhoineanim',      '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'eka vorsan',        '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 vorsanim',       '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'eka vorsan',        '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 vorsanim',       '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'thodde second',  'prefix');\n    assert.equal(moment(0).from(30000), 'thodde second adim', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'thodde second adim',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'thodde second', 'in a few seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), '5 dis', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'Aiz donparam 12:00 vazta',     'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'Aiz donparam 12:25 vazta',     'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'Aiz donparam 1:00 vazta',      'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'Faleam donparam 12:00 vazta',  'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'Aiz sokalli 11:00 vazta',     'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'Kal donparam 12:00 vazta', 'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('[Ieta to] dddd[,] LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[Ieta to] dddd[,] LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[Ieta to] dddd[,] LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('[Fatlo] dddd[,] LT'),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[Fatlo] dddd[,] LT'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[Fatlo] dddd[,] LT'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('weeks year starting sunday format', function (assert) {\n    assert.equal(moment([2012, 0,  1]).format('w ww wo'), '52 52 52', 'Jan  1 2012 should be week 52');\n    assert.equal(moment([2012, 0,  2]).format('w ww wo'), '1 01 1', 'Jan  2 2012 should be week 1');\n    assert.equal(moment([2012, 0,  8]).format('w ww wo'), '1 01 1', 'Jan  8 2012 should be week 1');\n    assert.equal(moment([2012, 0, 14]).format('w ww wo'), '2 02 2', 'Jan 14 2012 should be week 2');\n    assert.equal(moment([2012, 0, 15]).format('w ww wo'), '2 02 2', 'Jan 15 2012 should be week 2');\n});\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/test/locale/he.js",
    "content": "import {localeModule, test} from '../qunit';\nimport moment from '../../moment';\nlocaleModule('he');\n\ntest('parse', function (assert) {\n    var tests = 'ינואר ינו׳_פברואר פבר׳_מרץ מרץ_אפריל אפר׳_מאי מאי_יוני יוני_יולי יולי_אוגוסט אוג׳_ספטמבר ספט׳_אוקטובר אוק׳_נובמבר נוב׳_דצמבר דצמ׳'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, MMMM Do YYYY, h:mm:ss a',      'ראשון, פברואר 14 2010, 3:25:50 אחה\"צ'],\n            ['ddd, h A',                           'א׳, 3 אחרי הצהריים'],\n            ['M Mo MM MMMM MMM',                   '2 2 02 פברואר פבר׳'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14 14'],\n            ['d do dddd ddd dd',                   '0 0 ראשון א׳ א'],\n            ['DDD DDDo DDDD',                      '45 45 045'],\n            ['w wo ww',                            '8 8 08'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'אחה\"צ אחרי הצהריים'],\n            ['[the] DDDo [day of the year]',       'the 45 day of the year'],\n            ['LTS',                                '15:25:50'],\n            ['L',                                  '14/02/2010'],\n            ['LL',                                 '14 בפברואר 2010'],\n            ['LLL',                                '14 בפברואר 2010 15:25'],\n            ['LLLL',                               'ראשון, 14 בפברואר 2010 15:25'],\n            ['l',                                  '14/2/2010'],\n            ['ll',                                 '14 פבר׳ 2010'],\n            ['lll',                                '14 פבר׳ 2010 15:25'],\n            ['llll',                               'א׳, 14 פבר׳ 2010 15:25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format month', function (assert) {\n    var expected = 'ינואר ינו׳_פברואר פבר׳_מרץ מרץ_אפריל אפר׳_מאי מאי_יוני יוני_יולי יולי_אוגוסט אוג׳_ספטמבר ספט׳_אוקטובר אוק׳_נובמבר נוב׳_דצמבר דצמ׳'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'ראשון א׳ א|שני ב׳ ב|שלישי ג׳ ג|רביעי ד׳ ד|חמישי ה׳ ה|שישי ו׳ ו|שבת ש׳ ש'.split('|'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'מספר שניות', '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'דקה',      '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'דקה',      '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 דקות',     '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 דקות',    '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'שעה',       '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'שעה',       '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  'שעתיים',       '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 שעות',       '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 שעות',      '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'יום',         '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'יום',         '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  'יומיים',        '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'יום',         '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 ימים',        '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 ימים',       '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'חודש',       '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'חודש',       '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'חודש',       '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  'חודשיים',      '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  'חודשיים',      '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 חודשים',      '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'חודש',       '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 חודשים',      '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'שנה',        '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), 'שנתיים',       '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 3699}), true), '10 שנים',        '345 days = 10 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 7340}), true), '20 שנה',       '548 days = 20 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'שנה',        '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 שנים',       '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'בעוד מספר שניות',  'prefix');\n    assert.equal(moment(0).from(30000), 'לפני מספר שניות', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'לפני מספר שניות',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'בעוד מספר שניות', 'in a few seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), 'בעוד 5 ימים', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'היום ב־12:00',   'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'היום ב־12:25',   'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'היום ב־13:00',   'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'מחר ב־12:00',   'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'היום ב־11:00',   'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'אתמול ב־12:00',  'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('dddd [בשעה] LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd [בשעה] LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd [בשעה] LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('[ביום] dddd [האחרון בשעה] LT'),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[ביום] dddd [האחרון בשעה] LT'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[ביום] dddd [האחרון בשעה] LT'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('weeks year starting sunday format', function (assert) {\n    assert.equal(moment([2012, 0,  1]).format('w ww wo'), '1 01 1', 'Jan  1 2012 should be week 1');\n    assert.equal(moment([2012, 0,  7]).format('w ww wo'), '1 01 1', 'Jan  7 2012 should be week 1');\n    assert.equal(moment([2012, 0,  8]).format('w ww wo'), '2 02 2', 'Jan  8 2012 should be week 2');\n    assert.equal(moment([2012, 0, 14]).format('w ww wo'), '2 02 2', 'Jan 14 2012 should be week 2');\n    assert.equal(moment([2012, 0, 15]).format('w ww wo'), '3 03 3', 'Jan 15 2012 should be week 3');\n});\n\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/test/locale/hi.js",
    "content": "import {localeModule, test} from '../qunit';\nimport moment from '../../moment';\nlocaleModule('hi');\n\ntest('parse', function (assert) {\n    var tests = 'जनवरी जन._फ़रवरी फ़र._मार्च मार्च_अप्रैल अप्रै._मई मई_जून जून_जुलाई जुल._अगस्त अग._सितम्बर सित._अक्टूबर अक्टू._नवम्बर नव._दिसम्बर दिस.'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, Do MMMM YYYY, a h:mm:ss बजे',  'रविवार, १४ फ़रवरी २०१०, दोपहर ३:२५:५० बजे'],\n            ['ddd, a h बजे',                       'रवि, दोपहर ३ बजे'],\n            ['M Mo MM MMMM MMM',                   '२ २ ०२ फ़रवरी फ़र.'],\n            ['YYYY YY',                            '२०१० १०'],\n            ['D Do DD',                            '१४ १४ १४'],\n            ['d do dddd ddd dd',                   '० ० रविवार रवि र'],\n            ['DDD DDDo DDDD',                      '४५ ४५ ०४५'],\n            ['w wo ww',                            '८ ८ ०८'],\n            ['h hh',                               '३ ०३'],\n            ['H HH',                               '१५ १५'],\n            ['m mm',                               '२५ २५'],\n            ['s ss',                               '५० ५०'],\n            ['a A',                                'दोपहर दोपहर'],\n            ['LTS',                                'दोपहर ३:२५:५० बजे'],\n            ['L',                                  '१४/०२/२०१०'],\n            ['LL',                                 '१४ फ़रवरी २०१०'],\n            ['LLL',                                '१४ फ़रवरी २०१०, दोपहर ३:२५ बजे'],\n            ['LLLL',                               'रविवार, १४ फ़रवरी २०१०, दोपहर ३:२५ बजे'],\n            ['l',                                  '१४/२/२०१०'],\n            ['ll',                                 '१४ फ़र. २०१०'],\n            ['lll',                                '१४ फ़र. २०१०, दोपहर ३:२५ बजे'],\n            ['llll',                               'रवि, १४ फ़र. २०१०, दोपहर ३:२५ बजे']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '१', '१');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '२', '२');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '३', '३');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '४', '४');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '५', '५');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '६', '६');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '७', '७');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '८', '८');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '९', '९');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '१०', '१०');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '११', '११');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '१२', '१२');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '१३', '१३');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '१४', '१४');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '१५', '१५');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '१६', '१६');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '१७', '१७');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '१८', '१८');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '१९', '१९');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '२०', '२०');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '२१', '२१');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '२२', '२२');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '२३', '२३');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '२४', '२४');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '२५', '२५');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '२६', '२६');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '२७', '२७');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '२८', '२८');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '२९', '२९');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '३०', '३०');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '३१', '३१');\n});\n\ntest('format month', function (assert) {\n    var expected = 'जनवरी जन._फ़रवरी फ़र._मार्च मार्च_अप्रैल अप्रै._मई मई_जून जून_जुलाई जुल._अगस्त अग._सितम्बर सित._अक्टूबर अक्टू._नवम्बर नव._दिसम्बर दिस.'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'रविवार रवि र_सोमवार सोम सो_मंगलवार मंगल मं_बुधवार बुध बु_गुरूवार गुरू गु_शुक्रवार शुक्र शु_शनिवार शनि श'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'कुछ ही क्षण', '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'एक मिनट',      '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'एक मिनट',      '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '२ मिनट',     '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '४४ मिनट',    '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'एक घंटा',       '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'एक घंटा',       '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '२ घंटे',       '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '५ घंटे',       '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '२१ घंटे',      '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'एक दिन',         '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'एक दिन',         '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '२ दिन',        '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'एक दिन',         '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '५ दिन',        '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '२५ दिन',       '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'एक महीने',       '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'एक महीने',       '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'एक महीने',       '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '२ महीने',      '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '२ महीने',      '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '३ महीने',      '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'एक महीने',       '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '५ महीने',      '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'एक वर्ष',        '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '२ वर्ष',       '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'एक वर्ष',        '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '५ वर्ष',       '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'कुछ ही क्षण में',  'prefix');\n    assert.equal(moment(0).from(30000), 'कुछ ही क्षण पहले', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'कुछ ही क्षण पहले',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'कुछ ही क्षण में', 'कुछ ही क्षण में');\n    assert.equal(moment().add({d: 5}).fromNow(), '५ दिन में', '५ दिन में');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'आज दोपहर १२:०० बजे',    'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'आज दोपहर १२:२५ बजे',    'Now plus 25 min');\n    assert.equal(moment(a).add({h: 3}).calendar(),       'आज दोपहर ३:०० बजे',     'Now plus 3 hours');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'कल दोपहर १२:०० बजे',    'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'आज दोपहर ११:०० बजे',    'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'कल दोपहर १२:०० बजे',    'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('dddd[,] LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd[,] LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd[,] LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('[पिछले] dddd[,] LT'),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[पिछले] dddd[,] LT'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[पिछले] dddd[,] LT'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('meridiem', function (assert) {\n    assert.equal(moment([2011, 2, 23,  2, 30]).format('a'), 'रात', 'before dawn');\n    assert.equal(moment([2011, 2, 23,  9, 30]).format('a'), 'सुबह', 'morning');\n    assert.equal(moment([2011, 2, 23, 14, 30]).format('a'), 'दोपहर', 'during day');\n    assert.equal(moment([2011, 2, 23, 17, 30]).format('a'), 'शाम', 'evening');\n    assert.equal(moment([2011, 2, 23, 19, 30]).format('a'), 'शाम', 'late evening');\n    assert.equal(moment([2011, 2, 23, 21, 20]).format('a'), 'रात', 'night');\n\n    assert.equal(moment([2011, 2, 23,  2, 30]).format('A'), 'रात', 'before dawn');\n    assert.equal(moment([2011, 2, 23,  9, 30]).format('A'), 'सुबह', 'morning');\n    assert.equal(moment([2011, 2, 23, 14, 30]).format('A'), 'दोपहर', ' during day');\n    assert.equal(moment([2011, 2, 23, 17, 30]).format('A'), 'शाम', 'evening');\n    assert.equal(moment([2011, 2, 23, 19, 30]).format('A'), 'शाम', 'late evening');\n    assert.equal(moment([2011, 2, 23, 21, 20]).format('A'), 'रात', 'night');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2012, 0,  1]).format('w ww wo'), '१ ०१ १', 'Jan  1 2012 should be week 1');\n    assert.equal(moment([2012, 0,  7]).format('w ww wo'), '१ ०१ १', 'Jan  7 2012 should be week 1');\n    assert.equal(moment([2012, 0,  8]).format('w ww wo'), '२ ०२ २', 'Jan  8 2012 should be week 2');\n    assert.equal(moment([2012, 0, 14]).format('w ww wo'), '२ ०२ २', 'Jan 14 2012 should be week 2');\n    assert.equal(moment([2012, 0, 15]).format('w ww wo'), '३ ०३ ३', 'Jan 15 2012 should be week 3');\n});\n\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/test/locale/hr.js",
    "content": "import {localeModule, test} from '../qunit';\nimport moment from '../../moment';\nlocaleModule('hr');\n\ntest('parse', function (assert) {\n    var tests = 'siječanj sij._veljača velj._ožujak ožu._travanj tra._svibanj svi._lipanj lip._srpanj srp._kolovoz kol._rujan ruj._listopad lis._studeni stu._prosinac pro.'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, Do MMMM YYYY, h:mm:ss a',      'nedjelja, 14. veljače 2010, 3:25:50 pm'],\n            ['ddd, hA',                            'ned., 3PM'],\n            ['M Mo MM MMMM MMM',                   '2 2. 02 veljača velj.'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14. 14'],\n            ['d do dddd ddd dd',                   '0 0. nedjelja ned. ne'],\n            ['DDD DDDo DDDD',                      '45 45. 045'],\n            ['w wo ww',                            '7 7. 07'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'pm PM'],\n            ['[the] DDDo [day of the year]',       'the 45. day of the year'],\n            ['LTS',                                '15:25:50'],\n            ['L',                                  '14.02.2010'],\n            ['LL',                                 '14. veljača 2010'],\n            ['LLL',                                '14. veljača 2010 15:25'],\n            ['LLLL',                               'nedjelja, 14. veljača 2010 15:25'],\n            ['l',                                  '14.2.2010'],\n            ['ll',                                 '14. velj. 2010'],\n            ['lll',                                '14. velj. 2010 15:25'],\n            ['llll',                               'ned., 14. velj. 2010 15:25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1.', '1.');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2.', '2.');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3.', '3.');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4.', '4.');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5.', '5.');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6.', '6.');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7.', '7.');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8.', '8.');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9.', '9.');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10.', '10.');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11.', '11.');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12.', '12.');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13.', '13.');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14.', '14.');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15.', '15.');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16.', '16.');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17.', '17.');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18.', '18.');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19.', '19.');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20.', '20.');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21.', '21.');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22.', '22.');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23.', '23.');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24.', '24.');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25.', '25.');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26.', '26.');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27.', '27.');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28.', '28.');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29.', '29.');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30.', '30.');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31.', '31.');\n});\n\ntest('format month', function (assert) {\n    var expected = 'siječanj sij._veljača velj._ožujak ožu._travanj tra._svibanj svi._lipanj lip._srpanj srp._kolovoz kol._rujan ruj._listopad lis._studeni stu._prosinac pro.'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'nedjelja ned. ne_ponedjeljak pon. po_utorak uto. ut_srijeda sri. sr_četvrtak čet. če_petak pet. pe_subota sub. su'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'par sekundi', '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'jedna minuta',   '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'jedna minuta',   '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 minute',     '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 minuta',     '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'jedan sat',      '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'jedan sat',      '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 sata',        '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 sati',         '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 sati',        '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'dan',       '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'dan',       '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 dana',        '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'dan',       '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 dana',        '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 dana',       '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'mjesec',     '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'mjesec',     '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'mjesec',     '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 mjeseca',     '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 mjeseca',     '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 mjeseca',     '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'mjesec',     '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 mjeseci',    '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'godinu',     '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 godine',       '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'godinu',     '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 godina',        '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'za par sekundi',  'prefix');\n    assert.equal(moment(0).from(30000), 'prije par sekundi', 'prefix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'prije par sekundi',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'za par sekundi', 'in a few seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), 'za 5 dana', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'danas u 12:00',  'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'danas u 12:25',  'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'danas u 13:00',  'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'sutra u 12:00',  'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'danas u 11:00',  'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'jučer u 12:00',  'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n\n    function makeFormat(d) {\n        switch (d.day()) {\n            case 0:\n                return '[u] [nedjelju] [u] LT';\n            case 3:\n                return '[u] [srijedu] [u] LT';\n            case 6:\n                return '[u] [subotu] [u] LT';\n            case 1:\n            case 2:\n            case 4:\n            case 5:\n                return '[u] dddd [u] LT';\n        }\n    }\n\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format(makeFormat(m)),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format(makeFormat(m)),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format(makeFormat(m)),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n\n    function makeFormat(d) {\n        switch (d.day()) {\n            case 0:\n            case 3:\n                return '[prošlu] dddd [u] LT';\n            case 6:\n                return '[prošle] [subote] [u] LT';\n            case 1:\n            case 2:\n            case 4:\n            case 5:\n                return '[prošli] dddd [u] LT';\n        }\n    }\n\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format(makeFormat(m)),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format(makeFormat(m)),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format(makeFormat(m)),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2011, 11, 26]).format('w ww wo'), '1 01 1.', 'Dec 26 2011 should be week 1');\n    assert.equal(moment([2012,  0,  1]).format('w ww wo'), '1 01 1.', 'Jan  1 2012 should be week 1');\n    assert.equal(moment([2012,  0,  2]).format('w ww wo'), '2 02 2.', 'Jan  2 2012 should be week 2');\n    assert.equal(moment([2012,  0,  8]).format('w ww wo'), '2 02 2.', 'Jan  8 2012 should be week 2');\n    assert.equal(moment([2012,  0,  9]).format('w ww wo'), '3 03 3.', 'Jan  9 2012 should be week 3');\n});\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/test/locale/hu.js",
    "content": "import {localeModule, test} from '../qunit';\nimport moment from '../../moment';\nlocaleModule('hu');\n\ntest('parse', function (assert) {\n    var tests = 'január jan_február feb_március márc_április ápr_május máj_június jún_július júl_augusztus aug_szeptember szept_október okt_november nov_december dec'.split('_'),\n        i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, MMMM Do YYYY, HH:mm:ss',      'vasárnap, február 14. 2010, 15:25:50'],\n            ['ddd, HH',                            'vas, 15'],\n            ['M Mo MM MMMM MMM',                   '2 2. 02 február feb'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14. 14'],\n            ['d do dddd ddd dd',                   '0 0. vasárnap vas v'],\n            ['DDD DDDo DDDD',                      '45 45. 045'],\n            ['w wo ww',                            '6 6. 06'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['[az év] DDDo [napja]',               'az év 45. napja'],\n            ['LTS',                                '15:25:50'],\n            ['L',                                  '2010.02.14.'],\n            ['LL',                                 '2010. február 14.'],\n            ['LLL',                                '2010. február 14. 15:25'],\n            ['LLLL',                               '2010. február 14., vasárnap 15:25'],\n            ['l',                                  '2010.2.14.'],\n            ['ll',                                 '2010. feb 14.'],\n            ['lll',                                '2010. feb 14. 15:25'],\n            ['llll',                               '2010. feb 14., vas 15:25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('meridiem', function (assert) {\n    assert.equal(moment([2011, 2, 23,  0,  0]).format('a'), 'de', 'am');\n    assert.equal(moment([2011, 2, 23, 11, 59]).format('a'), 'de', 'am');\n    assert.equal(moment([2011, 2, 23, 12,  0]).format('a'), 'du', 'pm');\n    assert.equal(moment([2011, 2, 23, 23, 59]).format('a'), 'du', 'pm');\n\n    assert.equal(moment([2011, 2, 23,  0,  0]).format('A'), 'DE', 'AM');\n    assert.equal(moment([2011, 2, 23, 11, 59]).format('A'), 'DE', 'AM');\n    assert.equal(moment([2011, 2, 23, 12,  0]).format('A'), 'DU', 'PM');\n    assert.equal(moment([2011, 2, 23, 23, 59]).format('A'), 'DU', 'PM');\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1.', '1.');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2.', '2.');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3.', '3.');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4.', '4.');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5.', '5.');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6.', '6.');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7.', '7.');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8.', '8.');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9.', '9.');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10.', '10.');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11.', '11.');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12.', '12.');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13.', '13.');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14.', '14.');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15.', '15.');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16.', '16.');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17.', '17.');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18.', '18.');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19.', '19.');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20.', '20.');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21.', '21.');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22.', '22.');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23.', '23.');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24.', '24.');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25.', '25.');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26.', '26.');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27.', '27.');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28.', '28.');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29.', '29.');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30.', '30.');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31.', '31.');\n});\n\ntest('format month', function (assert) {\n    var expected = 'január jan_február feb_március márc_április ápr_május máj_június jún_július júl_augusztus aug_szeptember szept_október okt_november nov_december dec'.split('_'),\n        i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'vasárnap vas_hétfő hét_kedd kedd_szerda sze_csütörtök csüt_péntek pén_szombat szo'.split('_'),\n        i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'néhány másodperc', '44 másodperc = néhány másodperc');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'egy perc',         '45 másodperc = egy perc');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'egy perc',         '89 másodperc = egy perc');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 perc',           '90 másodperc = 2 perc');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 perc',          '44 perc = 44 perc');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'egy óra',          '45 perc = egy óra');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'egy óra',          '89 perc = egy óra');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 óra',            '90 perc = 2 óra');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 óra',            '5 óra = 5 óra');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 óra',           '21 óra = 21 óra');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'egy nap',          '22 óra = egy nap');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'egy nap',          '35 óra = egy nap');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 nap',            '36 óra = 2 nap');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'egy nap',          '1 nap = egy nap');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 nap',            '5 nap = 5 nap');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 nap',           '25 nap = 25 nap');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'egy hónap',        '26 nap = egy hónap');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'egy hónap',        '30 nap = egy hónap');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'egy hónap',        '45 nap = egy hónap');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 hónap',          '46 nap = 2 hónap');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 hónap',          '75 nap = 2 hónap');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 hónap',          '76 nap = 3 hónap');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'egy hónap',        '1 hónap = egy hónap');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 hónap',          '5 hónap = 5 hónap');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'egy év',           '345 nap = egy év');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 év',             '548 nap = 2 év');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'egy év',           '1 év = egy év');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 év',             '5 év = 5 év');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'néhány másodperc múlva',  'prefix');\n    assert.equal(moment(0).from(30000), 'néhány másodperce', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'néhány másodperce',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'néhány másodperc múlva', 'néhány másodperc múlva');\n    assert.equal(moment().add({d: 5}).fromNow(), '5 nap múlva', '5 nap múlva');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'ma 12:00-kor',     'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'ma 12:25-kor',     'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'ma 13:00-kor',     'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'holnap 12:00-kor', 'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'ma 11:00-kor',     'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'tegnap 12:00-kor', 'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m, days = 'vasárnap_hétfőn_kedden_szerdán_csütörtökön_pénteken_szombaton'.split('_');\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('[' + days[m.day()] + '] LT[-kor]'),  'today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[' + days[m.day()] + '] LT[-kor]'),  'today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[' + days[m.day()] + '] LT[-kor]'),  'today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m, days = 'vasárnap_hétfőn_kedden_szerdán_csütörtökön_pénteken_szombaton'.split('_');\n\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('[múlt ' + days[m.day()] + '] LT[-kor]'),  'today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[múlt ' + days[m.day()] + '] LT[-kor]'),  'today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[múlt ' + days[m.day()] + '] LT[-kor]'),  'today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  'egy héte');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'egy hét múlva');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 hete');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  '2 hét múlva');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2011, 11, 26]).format('w ww wo'), '52 52 52.', 'Dec 26 2011 should be week 52');\n    assert.equal(moment([2012,  0,  1]).format('w ww wo'), '52 52 52.', 'Jan  1 2012 should be week 52');\n    assert.equal(moment([2012,  0,  2]).format('w ww wo'), '1 01 1.', 'Jan  2 2012 should be week 1');\n    assert.equal(moment([2012,  0,  8]).format('w ww wo'), '1 01 1.', 'Jan  8 2012 should be week 1');\n    assert.equal(moment([2012,  0,  9]).format('w ww wo'), '2 02 2.', 'Jan  9 2012 should be week 2');\n});\n\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/test/locale/hy-am.js",
    "content": "import {localeModule, test} from '../qunit';\nimport moment from '../../moment';\nlocaleModule('hy-am');\n\ntest('parse', function (assert) {\n    var tests = 'հունվար հնվ_փետրվար փտր_մարտ մրտ_ապրիլ ապր_մայիս մյս_հունիս հնս_հուլիս հլս_օգոստոս օգս_սեպտեմբեր սպտ_հոկտեմբեր հկտ_նոյեմբեր նմբ_դեկտեմբեր դկտ'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('parse exceptional case', function (assert) {\n    assert.equal(moment('11 մայիսի 1989', ['DD MMMM YYYY']).format('DD-MM-YYYY'), '11-05-1989');\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, Do MMMM YYYY, HH:mm:ss',       'կիրակի, 14 փետրվարի 2010, 15:25:50'],\n            ['ddd, h A',                           'կրկ, 3 ցերեկվա'],\n            ['M Mo MM MMMM MMM',                   '2 2 02 փետրվար փտր'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14 14'],\n            ['d do dddd ddd dd',                   '0 0 կիրակի կրկ կրկ'],\n            ['DDD DDDo DDDD',                      '45 45-րդ 045'],\n            ['w wo ww',                            '7 7-րդ 07'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'ցերեկվա ցերեկվա'],\n            ['[տարվա] DDDo [օրը]',                 'տարվա 45-րդ օրը'],\n            ['LTS',                                '15:25:50'],\n            ['L',                                  '14.02.2010'],\n            ['LL',                                 '14 փետրվարի 2010 թ.'],\n            ['LLL',                                '14 փետրվարի 2010 թ., 15:25'],\n            ['LLLL',                               'կիրակի, 14 փետրվարի 2010 թ., 15:25'],\n            ['l',                                  '14.2.2010'],\n            ['ll',                                 '14 փտր 2010 թ.'],\n            ['lll',                                '14 փտր 2010 թ., 15:25'],\n            ['llll',                               'կրկ, 14 փտր 2010 թ., 15:25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format meridiem', function (assert) {\n    assert.equal(moment([2012, 11, 28, 0, 0]).format('A'), 'գիշերվա', 'night');\n    assert.equal(moment([2012, 11, 28, 3, 59]).format('A'), 'գիշերվա', 'night');\n    assert.equal(moment([2012, 11, 28, 4, 0]).format('A'), 'առավոտվա', 'morning');\n    assert.equal(moment([2012, 11, 28, 11, 59]).format('A'), 'առավոտվա', 'morning');\n    assert.equal(moment([2012, 11, 28, 12, 0]).format('A'), 'ցերեկվա', 'afternoon');\n    assert.equal(moment([2012, 11, 28, 16, 59]).format('A'), 'ցերեկվա', 'afternoon');\n    assert.equal(moment([2012, 11, 28, 17, 0]).format('A'), 'երեկոյան', 'evening');\n    assert.equal(moment([2012, 11, 28, 23, 59]).format('A'), 'երեկոյան', 'evening');\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1-ին', '1-ին');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2-րդ', '2-րդ');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3-րդ', '3-րդ');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4-րդ', '4-րդ');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5-րդ', '5-րդ');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6-րդ', '6-րդ');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7-րդ', '7-րդ');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8-րդ', '8-րդ');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9-րդ', '9-րդ');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10-րդ', '10-րդ');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11-րդ', '11-րդ');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12-րդ', '12-րդ');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13-րդ', '13-րդ');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14-րդ', '14-րդ');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15-րդ', '15-րդ');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16-րդ', '16-րդ');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17-րդ', '17-րդ');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18-րդ', '18-րդ');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19-րդ', '19-րդ');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20-րդ', '20-րդ');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21-րդ', '21-րդ');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22-րդ', '22-րդ');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23-րդ', '23-րդ');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24-րդ', '24-րդ');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25-րդ', '25-րդ');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26-րդ', '26-րդ');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27-րդ', '27-րդ');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28-րդ', '28-րդ');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29-րդ', '29-րդ');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30-րդ', '30-րդ');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31-րդ', '31-րդ');\n});\n\ntest('format month', function (assert) {\n    var expected = 'հունվար հնվ_փետրվար փտր_մարտ մրտ_ապրիլ ապր_մայիս մյս_հունիս հնս_հուլիս հլս_օգոստոս օգս_սեպտեմբեր սպտ_հոկտեմբեր հկտ_նոյեմբեր նմբ_դեկտեմբեր դկտ'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format month case', function (assert) {\n    var months = {\n        'nominative': 'հունվար_փետրվար_մարտ_ապրիլ_մայիս_հունիս_հուլիս_օգոստոս_սեպտեմբեր_հոկտեմբեր_նոյեմբեր_դեկտեմբեր'.split('_'),\n        'accusative': 'հունվարի_փետրվարի_մարտի_ապրիլի_մայիսի_հունիսի_հուլիսի_օգոստոսի_սեպտեմբերի_հոկտեմբերի_նոյեմբերի_դեկտեմբերի'.split('_')\n    }, i;\n    for (i = 0; i < 12; i++) {\n        assert.equal(moment([2011, i, 1]).format('D MMMM'), '1 ' + months.accusative[i], '1 ' + months.accusative[i]);\n        assert.equal(moment([2011, i, 1]).format('MMMM'), months.nominative[i], '1 ' + months.nominative[i]);\n    }\n});\n\ntest('format month short case', function (assert) {\n    var monthsShort = {\n        'nominative': 'հնվ_փտր_մրտ_ապր_մյս_հնս_հլս_օգս_սպտ_հկտ_նմբ_դկտ'.split('_'),\n        'accusative': 'հնվ_փտր_մրտ_ապր_մյս_հնս_հլս_օգս_սպտ_հկտ_նմբ_դկտ'.split('_')\n    }, i;\n    for (i = 0; i < 12; i++) {\n        assert.equal(moment([2011, i, 1]).format('D MMM'), '1 ' + monthsShort.accusative[i], '1 ' + monthsShort.accusative[i]);\n        assert.equal(moment([2011, i, 1]).format('MMM'), monthsShort.nominative[i], '1 ' + monthsShort.nominative[i]);\n    }\n});\n\ntest('format month case with escaped symbols', function (assert) {\n    var months = {\n        'nominative': 'հունվար_փետրվար_մարտ_ապրիլ_մայիս_հունիս_հուլիս_օգոստոս_սեպտեմբեր_հոկտեմբեր_նոյեմբեր_դեկտեմբեր'.split('_'),\n        'accusative': 'հունվարի_փետրվարի_մարտի_ապրիլի_մայիսի_հունիսի_հուլիսի_օգոստոսի_սեպտեմբերի_հոկտեմբերի_նոյեմբերի_դեկտեմբերի'.split('_')\n    }, i;\n    for (i = 0; i < 12; i++) {\n        assert.equal(moment([2013, i, 1]).format('D[] MMMM'), '1 ' + months.accusative[i], '1 ' + months.accusative[i]);\n        assert.equal(moment([2013, i, 1]).format('[<i>]D[</i>] [<b>]MMMM[</b>]'), '<i>1</i> <b>' + months.accusative[i] + '</b>', '1 <b>' + months.accusative[i] + '</b>');\n        assert.equal(moment([2013, i, 1]).format('D[-ին օրը] MMMM'), '1-ին օրը ' + months.accusative[i], '1-ին օրը ' + months.accusative[i]);\n        assert.equal(moment([2013, i, 1]).format('D, MMMM'), '1, ' + months.nominative[i], '1, ' + months.nominative[i]);\n    }\n});\n\ntest('format month short case with escaped symbols', function (assert) {\n    var monthsShort = {\n        'nominative': 'հնվ_փտր_մրտ_ապր_մյս_հնս_հլս_օգս_սպտ_հկտ_նմբ_դկտ'.split('_'),\n        'accusative': 'հնվ_փտր_մրտ_ապր_մյս_հնս_հլս_օգս_սպտ_հկտ_նմբ_դկտ'.split('_')\n    }, i;\n    for (i = 0; i < 12; i++) {\n        assert.equal(moment([2013, i, 1]).format('D[] MMM'), '1 ' + monthsShort.accusative[i], '1 ' + monthsShort.accusative[i]);\n        assert.equal(moment([2013, i, 1]).format('[<i>]D[</i>] [<b>]MMM[</b>]'), '<i>1</i> <b>' + monthsShort.accusative[i] + '</b>', '1 <b>' + monthsShort.accusative[i] + '</b>');\n        assert.equal(moment([2013, i, 1]).format('D[-ին օրը] MMM'), '1-ին օրը ' + monthsShort.accusative[i], '1-ին օրը ' + monthsShort.accusative[i]);\n        assert.equal(moment([2013, i, 1]).format('D, MMM'), '1, ' + monthsShort.nominative[i], '1, ' + monthsShort.nominative[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'կիրակի կրկ կրկ_երկուշաբթի երկ երկ_երեքշաբթի երք երք_չորեքշաբթի չրք չրք_հինգշաբթի հնգ հնգ_ուրբաթ ուրբ ուրբ_շաբաթ շբթ շբթ'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'մի քանի վայրկյան',    '44 seconds = seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'րոպե',   '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'րոպե',   '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 րոպե',  '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 րոպե', '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'ժամ',    '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'ժամ',    '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 ժամ',    '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 ժամ',    '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 ժամ',   '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'օր',      '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'օր',      '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 օր',     '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'օր',      '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 օր',     '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 11}), true),  '11 օր',     '11 days = 11 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 21}), true),  '21 օր',     '21 days = 21 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 օր',    '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'ամիս',    '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'ամիս',    '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'ամիս',    '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 ամիս',   '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 ամիս',   '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 ամիս',   '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'ամիս',    '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 ամիս',   '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'տարի',     '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 տարի',    '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'տարի',     '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 տարի',    '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'մի քանի վայրկյան հետո', 'prefix');\n    assert.equal(moment(0).from(30000), 'մի քանի վայրկյան առաջ', 'suffix');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'մի քանի վայրկյան հետո', 'in seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), '5 օր հետո', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'այսօր 12:00',   'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'այսօր 12:25',   'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'այսօր 13:00',   'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'վաղը 12:00',    'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'այսօր 11:00',   'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'երեկ 12:00',    'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    function makeFormat(d) {\n        return 'dddd [օրը ժամը] LT';\n    }\n\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format(makeFormat(m)),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format(makeFormat(m)),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format(makeFormat(m)),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n\n    function makeFormat(d) {\n        return '[անցած] dddd [օրը ժամը] LT';\n    }\n\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format(makeFormat(m)),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format(makeFormat(m)),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format(makeFormat(m)),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2011, 11, 26]).format('w ww wo'), '1 01 1-ին', 'Dec 26 2011 should be week 1');\n    assert.equal(moment([2012,  0,  1]).format('w ww wo'), '1 01 1-ին', 'Jan  1 2012 should be week 1');\n    assert.equal(moment([2012,  0,  2]).format('w ww wo'), '2 02 2-րդ', 'Jan  2 2012 should be week 2');\n    assert.equal(moment([2012,  0,  8]).format('w ww wo'), '2 02 2-րդ', 'Jan  8 2012 should be week 2');\n    assert.equal(moment([2012,  0,  9]).format('w ww wo'), '3 03 3-րդ', 'Jan  9 2012 should be week 3');\n});\n\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/test/locale/id.js",
    "content": "import {localeModule, test} from '../qunit';\nimport moment from '../../moment';\nlocaleModule('id');\n\ntest('parse', function (assert) {\n    var tests = 'Januari Jan_Februari Feb_Maret Mar_April Apr_Mei Mei_Juni Jun_Juli Jul_Agustus Ags_September Sep_Oktober Okt_November Nov_Desember Des'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, MMMM Do YYYY, h:mm:ss a',      'Minggu, Februari 14 2010, 3:25:50 sore'],\n            ['ddd, hA',                            'Min, 3sore'],\n            ['M Mo MM MMMM MMM',                   '2 2 02 Februari Feb'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14 14'],\n            ['d do dddd ddd dd',                   '0 0 Minggu Min Mg'],\n            ['DDD DDDo DDDD',                      '45 45 045'],\n            ['w wo ww',                            '7 7 07'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'sore sore'],\n            ['[the] DDDo [day of the year]',       'the 45 day of the year'],\n            ['LTS',                                '15.25.50'],\n            ['L',                                  '14/02/2010'],\n            ['LL',                                 '14 Februari 2010'],\n            ['LLL',                                '14 Februari 2010 pukul 15.25'],\n            ['LLLL',                               'Minggu, 14 Februari 2010 pukul 15.25'],\n            ['l',                                  '14/2/2010'],\n            ['ll',                                 '14 Feb 2010'],\n            ['lll',                                '14 Feb 2010 pukul 15.25'],\n            ['llll',                               'Min, 14 Feb 2010 pukul 15.25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format month', function (assert) {\n    var expected = 'Januari Jan_Februari Feb_Maret Mar_April Apr_Mei Mei_Juni Jun_Juli Jul_Agustus Ags_September Sep_Oktober Okt_November Nov_Desember Des'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'Minggu Min Mg_Senin Sen Sn_Selasa Sel Sl_Rabu Rab Rb_Kamis Kam Km_Jumat Jum Jm_Sabtu Sab Sb'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'beberapa detik', '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'semenit',      '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'semenit',      '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 menit',     '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 menit',    '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'sejam',       '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'sejam',       '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 jam',       '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 jam',       '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 jam',      '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'sehari',         '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'sehari',         '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 hari',        '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'sehari',         '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 hari',        '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 hari',       '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'sebulan',       '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'sebulan',       '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'sebulan',       '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 bulan',      '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 bulan',      '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 bulan',      '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'sebulan',       '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 bulan',      '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'setahun',        '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 tahun',       '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'setahun',        '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 tahun',       '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'dalam beberapa detik',  'prefix');\n    assert.equal(moment(0).from(30000), 'beberapa detik yang lalu', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'beberapa detik yang lalu',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'dalam beberapa detik', 'in a few seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), 'dalam 5 hari', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'Hari ini pukul 12.00', 'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'Hari ini pukul 12.25', 'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'Hari ini pukul 13.00', 'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'Besok pukul 12.00',    'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'Hari ini pukul 11.00', 'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'Kemarin pukul 12.00',  'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('dddd [pukul] LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd [pukul] LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd [pukul] LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('dddd [lalu pukul] LT'),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd [lalu pukul] LT'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd [lalu pukul] LT'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2011, 11, 26]).format('w ww wo'), '1 01 1', 'Dec 26 2011 should be week 1');\n    assert.equal(moment([2012,  0,  1]).format('w ww wo'), '1 01 1', 'Jan  1 2012 should be week 1');\n    assert.equal(moment([2012,  0,  2]).format('w ww wo'), '2 02 2', 'Jan  2 2012 should be week 2');\n    assert.equal(moment([2012,  0,  8]).format('w ww wo'), '2 02 2', 'Jan  8 2012 should be week 2');\n    assert.equal(moment([2012,  0,  9]).format('w ww wo'), '3 03 3', 'Jan  9 2012 should be week 3');\n});\n\n\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/test/locale/is.js",
    "content": "import {localeModule, test} from '../qunit';\nimport moment from '../../moment';\nlocaleModule('is');\n\ntest('parse', function (assert) {\n    var tests = 'janúar jan_febrúar feb_mars mar_apríl apr_maí maí_júní jún_júlí júl_ágúst ágú_september sep_október okt_nóvember nóv_desember des'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, Do MMMM YYYY, h:mm:ss a',      'sunnudagur, 14. febrúar 2010, 3:25:50 pm'],\n            ['ddd, hA',                            'sun, 3PM'],\n            ['M Mo MM MMMM MMM',                   '2 2. 02 febrúar feb'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14. 14'],\n            ['d do dddd ddd dd',                   '0 0. sunnudagur sun Su'],\n            ['DDD DDDo DDDD',                      '45 45. 045'],\n            ['w wo ww',                            '6 6. 06'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'pm PM'],\n            ['[the] DDDo [day of the year]',       'the 45. day of the year'],\n            ['LTS',                                '15:25:50'],\n            ['L',                                  '14.02.2010'],\n            ['LL',                                 '14. febrúar 2010'],\n            ['LLL',                                '14. febrúar 2010 kl. 15:25'],\n            ['LLLL',                               'sunnudagur, 14. febrúar 2010 kl. 15:25'],\n            ['l',                                  '14.2.2010'],\n            ['ll',                                 '14. feb 2010'],\n            ['lll',                                '14. feb 2010 kl. 15:25'],\n            ['llll',                               'sun, 14. feb 2010 kl. 15:25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1.', '1.');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2.', '2.');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3.', '3.');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4.', '4.');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5.', '5.');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6.', '6.');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7.', '7.');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8.', '8.');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9.', '9.');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10.', '10.');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11.', '11.');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12.', '12.');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13.', '13.');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14.', '14.');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15.', '15.');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16.', '16.');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17.', '17.');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18.', '18.');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19.', '19.');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20.', '20.');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21.', '21.');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22.', '22.');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23.', '23.');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24.', '24.');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25.', '25.');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26.', '26.');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27.', '27.');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28.', '28.');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29.', '29.');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30.', '30.');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31.', '31.');\n});\n\ntest('format month', function (assert) {\n    var expected = 'janúar jan_febrúar feb_mars mar_apríl apr_maí maí_júní jún_júlí júl_ágúst ágú_september sep_október okt_nóvember nóv_desember des'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'sunnudagur sun Su_mánudagur mán Má_þriðjudagur þri Þr_miðvikudagur mið Mi_fimmtudagur fim Fi_föstudagur fös Fö_laugardagur lau La'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'nokkrar sekúndur', '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'mínúta',      '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'mínúta',      '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 mínútur',     '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 mínútur',    '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 21}), true),  '21 mínúta',    '21 minutes = 21 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'klukkustund',       '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'klukkustund',       '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 klukkustundir',       '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 klukkustundir',       '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 klukkustund',      '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'dagur',         '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'dagur',         '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 dagar',        '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'dagur',         '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 dagar',        '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 dagar',       '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 11}), true),  '11 dagar',       '11 days = 11 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 21}), true),  '21 dagur',       '21 days = 21 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'mánuður',       '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'mánuður',       '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'mánuður',       '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 mánuðir',      '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 mánuðir',      '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 mánuðir',      '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'mánuður',       '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 mánuðir',      '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'ár',        '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 ár',       '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'ár',        '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 ár',       '5 years = 5 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 21}), true),  '21 ár',       '21 years = 21 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'eftir nokkrar sekúndur',  'prefix');\n    assert.equal(moment(0).from(30000), 'fyrir nokkrum sekúndum síðan', 'suffix');\n    assert.equal(moment().subtract({m: 1}).fromNow(), 'fyrir mínútu síðan', 'a minute ago');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'fyrir nokkrum sekúndum síðan',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'eftir nokkrar sekúndur', 'in a few seconds');\n    assert.equal(moment().add({m: 1}).fromNow(), 'eftir mínútu', 'in a minute');\n    assert.equal(moment().add({d: 5}).fromNow(), 'eftir 5 daga', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'í dag kl. 12:00',     'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'í dag kl. 12:25',     'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'í dag kl. 13:00',     'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'á morgun kl. 12:00',  'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'í dag kl. 11:00',     'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'í gær kl. 12:00',     'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('dddd [kl.] LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd [kl.] LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd [kl.] LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('[síðasta] dddd [kl.] LT'),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[síðasta] dddd [kl.] LT'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[síðasta] dddd [kl.] LT'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2012, 0,  1]).format('w ww wo'), '52 52 52.', 'Jan  1 2012 should be week 52');\n    assert.equal(moment([2012, 0,  2]).format('w ww wo'),  '1 01 1.', 'Jan  2 2012 should be week 1');\n    assert.equal(moment([2012, 0,  8]).format('w ww wo'),  '1 01 1.', 'Jan  8 2012 should be week 1');\n    assert.equal(moment([2012, 0,  9]).format('w ww wo'),  '2 02 2.', 'Jan  9 2012 should be week 2');\n    assert.equal(moment([2012, 0, 15]).format('w ww wo'),  '2 02 2.', 'Jan 15 2012 should be week 2');\n});\n\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/test/locale/it.js",
    "content": "import {localeModule, test} from '../qunit';\nimport moment from '../../moment';\nlocaleModule('it');\n\ntest('parse', function (assert) {\n    var tests = 'gennaio gen_febbraio feb_marzo mar_aprile apr_maggio mag_giugno giu_luglio lug_agosto ago_settembre set_ottobre ott_novembre nov_dicembre dic'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, MMMM Do YYYY, h:mm:ss a',      'domenica, febbraio 14º 2010, 3:25:50 pm'],\n            ['ddd, hA',                            'dom, 3PM'],\n            ['M Mo MM MMMM MMM',                   '2 2º 02 febbraio feb'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14º 14'],\n            ['d do dddd ddd dd',                   '0 0º domenica dom do'],\n            ['DDD DDDo DDDD',                      '45 45º 045'],\n            ['w wo ww',                            '6 6º 06'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'pm PM'],\n            ['[the] DDDo [day of the year]',       'the 45º day of the year'],\n            ['LTS',                                '15:25:50'],\n            ['L',                                  '14/02/2010'],\n            ['LL',                                 '14 febbraio 2010'],\n            ['LLL',                                '14 febbraio 2010 15:25'],\n            ['LLLL',                               'domenica, 14 febbraio 2010 15:25'],\n            ['l',                                  '14/2/2010'],\n            ['ll',                                 '14 feb 2010'],\n            ['lll',                                '14 feb 2010 15:25'],\n            ['llll',                               'dom, 14 feb 2010 15:25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1º', '1º');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2º', '2º');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3º', '3º');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4º', '4º');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5º', '5º');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6º', '6º');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7º', '7º');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8º', '8º');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9º', '9º');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10º', '10º');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11º', '11º');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12º', '12º');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13º', '13º');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14º', '14º');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15º', '15º');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16º', '16º');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17º', '17º');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18º', '18º');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19º', '19º');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20º', '20º');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21º', '21º');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22º', '22º');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23º', '23º');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24º', '24º');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25º', '25º');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26º', '26º');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27º', '27º');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28º', '28º');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29º', '29º');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30º', '30º');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31º', '31º');\n});\n\ntest('format month', function (assert) {\n    var expected = 'gennaio gen_febbraio feb_marzo mar_aprile apr_maggio mag_giugno giu_luglio lug_agosto ago_settembre set_ottobre ott_novembre nov_dicembre dic'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'domenica dom do_lunedì lun lu_martedì mar ma_mercoledì mer me_giovedì gio gi_venerdì ven ve_sabato sab sa'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'alcuni secondi', '44 seconds = seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'un minuto',      '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'un minuto',      '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 minuti',       '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 minuti',      '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'un\\'ora',        '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'un\\'ora',        '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 ore',          '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 ore',          '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 ore',         '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'un giorno',      '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'un giorno',      '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 giorni',       '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'un giorno',      '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 giorni',       '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 giorni',      '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'un mese',        '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'un mese',        '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'un mese',        '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 mesi',         '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 mesi',         '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 mesi',         '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'un mese',        '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 mesi',         '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'un anno',        '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 anni',         '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'un anno',        '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 anni',         '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'in alcuni secondi', 'prefix');\n    assert.equal(moment(0).from(30000), 'alcuni secondi fa', 'suffix');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'in alcuni secondi', 'in seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), 'tra 5 giorni', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'Oggi alle 12:00',     'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'Oggi alle 12:25',     'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'Oggi alle 13:00',     'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'Domani alle 12:00',   'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'Oggi alle 11:00',     'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'Ieri alle 12:00',     'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('dddd [alle] LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd [alle] LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd [alle] LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m, weekday, datestring;\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        // Different date string\n        weekday = parseInt(m.format('d'), 10);\n        datestring = (weekday === 0) ? '[la scorsa] dddd [alle] LT' : '[lo scorso] dddd [alle] LT';\n        assert.equal(m.calendar(), m.format(datestring), 'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(), m.format(datestring), 'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(), m.format(datestring), 'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2012, 0,  1]).format('w ww wo'), '52 52 52º', 'Jan  1 2012 should be week 52');\n    assert.equal(moment([2012, 0,  2]).format('w ww wo'),  '1 01 1º', 'Jan  2 2012 should be week 1');\n    assert.equal(moment([2012, 0,  8]).format('w ww wo'),  '1 01 1º', 'Jan  8 2012 should be week 1');\n    assert.equal(moment([2012, 0,  9]).format('w ww wo'),  '2 02 2º', 'Jan  9 2012 should be week 2');\n    assert.equal(moment([2012, 0, 15]).format('w ww wo'),  '2 02 2º', 'Jan 15 2012 should be week 2');\n});\n\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/test/locale/ja.js",
    "content": "import {localeModule, test} from '../qunit';\nimport moment from '../../moment';\nlocaleModule('ja');\n\ntest('parse', function (assert) {\n    var tests = '1月 1月_2月 2月_3月 3月_4月 4月_5月 5月_6月 6月_7月 7月_8月 8月_9月 9月_10月 10月_11月 11月_12月 12月'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, MMMM Do YYYY, a h:mm:ss',      '日曜日, 2月 14日 2010, 午後 3:25:50'],\n            ['ddd, Ah',                            '日, 午後3'],\n            ['M Mo MM MMMM MMM',                   '2 2 02 2月 2月'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14日 14'],\n            ['d do dddd ddd dd',                   '0 0日 日曜日 日 日'],\n            ['DDD DDDo DDDD',                      '45 45日 045'],\n            ['w wo ww',                            '8 8 08'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                '午後 午後'],\n            ['[the] DDDo [day of the year]',       'the 45日 day of the year'],\n            ['LTS',                                '15:25:50'],\n            ['L',                                  '2010/02/14'],\n            ['LL',                                 '2010年2月14日'],\n            ['LLL',                                '2010年2月14日 15:25'],\n            ['LLLL',                               '2010年2月14日 15:25 日曜日'],\n            ['l',                                  '2010/02/14'],\n            ['ll',                                 '2010年2月14日'],\n            ['lll',                                '2010年2月14日 15:25'],\n            ['llll',                               '2010年2月14日 15:25 日曜日']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format month', function (assert) {\n    var expected = '1月 1月_2月 2月_3月 3月_4月 4月_5月 5月_6月 6月_7月 7月_8月 8月_9月 9月_10月 10月_11月 11月_12月 12月'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = '日曜日 日 日_月曜日 月 月_火曜日 火 火_水曜日 水 水_木曜日 木 木_金曜日 金 金_土曜日 土 土'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  '数秒',   '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  '1分', '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  '1分', '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2分',  '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44分', '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  '1時間', '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  '1時間', '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2時間',  '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5時間',  '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21時間', '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  '1日',   '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  '1日',   '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2日',   '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   '1日',   '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5日',   '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25日',  '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  '1ヶ月', '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  '1ヶ月', '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  '1ヶ月', '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2ヶ月',  '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2ヶ月',  '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3ヶ月',  '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   '1ヶ月', '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5ヶ月',  '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), '1年',   '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2年',   '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   '1年',   '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5年',   '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), '数秒後',  'prefix');\n    assert.equal(moment(0).from(30000), '数秒前', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), '数秒前',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), '数秒後', 'in a few seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), '5日後', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   '今日 12:00', 'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      '今日 12:25', 'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       '今日 13:00', 'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       '明日 12:00', 'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  '今日 11:00', 'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  '昨日 12:00', 'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('[来週]dddd LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[来週]dddd LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[来週]dddd LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('[前週]dddd LT'),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[前週]dddd LT'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[前週]dddd LT'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),      '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),      '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('weeks year starting sunday format', function (assert) {\n    assert.equal(moment([2012, 0,  1]).format('w ww wo'), '1 01 1', 'Jan  1 2012 should be week 1');\n    assert.equal(moment([2012, 0,  7]).format('w ww wo'), '1 01 1', 'Jan  7 2012 should be week 1');\n    assert.equal(moment([2012, 0,  8]).format('w ww wo'), '2 02 2', 'Jan  8 2012 should be week 2');\n    assert.equal(moment([2012, 0, 14]).format('w ww wo'), '2 02 2', 'Jan 14 2012 should be week 2');\n    assert.equal(moment([2012, 0, 15]).format('w ww wo'), '3 03 3', 'Jan 15 2012 should be week 3');\n});\n\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/test/locale/jv.js",
    "content": "import {localeModule, test} from '../qunit';\nimport moment from '../../moment';\nlocaleModule('jv');\n\ntest('parse', function (assert) {\n    var tests = 'Januari Jan_Februari Feb_Maret Mar_April Apr_Mei Mei_Juni Jun_Juli Jul_Agustus Ags_September Sep_Oktober Okt_Nopember Nop_Desember Des'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, MMMM Do YYYY, h:mm:ss a',      'Minggu, Februari 14 2010, 3:25:50 sonten'],\n            ['ddd, hA',                            'Min, 3sonten'],\n            ['M Mo MM MMMM MMM',                   '2 2 02 Februari Feb'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14 14'],\n            ['d do dddd ddd dd',                   '0 0 Minggu Min Mg'],\n            ['DDD DDDo DDDD',                      '45 45 045'],\n            ['w wo ww',                            '7 7 07'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'sonten sonten'],\n            ['[the] DDDo [day of the year]',       'the 45 day of the year'],\n            ['LTS',                                '15.25.50'],\n            ['L',                                  '14/02/2010'],\n            ['LL',                                 '14 Februari 2010'],\n            ['LLL',                                '14 Februari 2010 pukul 15.25'],\n            ['LLLL',                               'Minggu, 14 Februari 2010 pukul 15.25'],\n            ['l',                                  '14/2/2010'],\n            ['ll',                                 '14 Feb 2010'],\n            ['lll',                                '14 Feb 2010 pukul 15.25'],\n            ['llll',                               'Min, 14 Feb 2010 pukul 15.25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format month', function (assert) {\n    var expected = 'Januari Jan_Februari Feb_Maret Mar_April Apr_Mei Mei_Juni Jun_Juli Jul_Agustus Ags_September Sep_Oktober Okt_Nopember Nop_Desember Des'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'Minggu Min Mg_Senen Sen Sn_Seloso Sel Sl_Rebu Reb Rb_Kemis Kem Km_Jemuwah Jem Jm_Septu Sep Sp'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'sawetawis detik', '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'setunggal menit',      '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'setunggal menit',      '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 menit',     '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 menit',    '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'setunggal jam',       '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'setunggal jam',       '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 jam',       '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 jam',       '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 jam',      '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'sedinten',         '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'sedinten',         '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 dinten',        '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'sedinten',         '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 dinten',        '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 dinten',       '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'sewulan',       '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'sewulan',       '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'sewulan',       '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 wulan',      '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 wulan',      '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 wulan',      '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'sewulan',       '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 wulan',      '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'setaun',        '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 taun',       '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'setaun',        '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 taun',       '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'wonten ing sawetawis detik',  'prefix');\n    assert.equal(moment(0).from(30000), 'sawetawis detik ingkang kepengker', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'sawetawis detik ingkang kepengker',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'wonten ing sawetawis detik', 'in a few seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), 'wonten ing 5 dinten', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'Dinten puniko pukul 12.00', 'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'Dinten puniko pukul 12.25', 'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'Dinten puniko pukul 13.00', 'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'Mbenjang pukul 12.00',      'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'Dinten puniko pukul 11.00', 'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'Kala wingi pukul 12.00',    'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('dddd [pukul] LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd [pukul] LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd [pukul] LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('dddd [kepengker pukul] LT'),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd [kepengker pukul] LT'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd [kepengker pukul] LT'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\n// Monday is the first day of the week.\n// The week that contains Jan 1st is the first week of the year.\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2011, 11, 26]).format('w ww wo'), '1 01 1', 'Dec 26 2011 should be week 1');\n    assert.equal(moment([2012,  0,  1]).format('w ww wo'), '1 01 1', 'Jan  1 2012 should be week 1');\n    assert.equal(moment([2012,  0,  2]).format('w ww wo'), '2 02 2', 'Jan  2 2012 should be week 2');\n    assert.equal(moment([2012,  0,  8]).format('w ww wo'), '2 02 2', 'Jan  8 2012 should be week 2');\n    assert.equal(moment([2012,  0,  9]).format('w ww wo'), '3 03 3', 'Jan  9 2012 should be week 3');\n});\n\n\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/test/locale/ka.js",
    "content": "import {localeModule, test} from '../qunit';\nimport moment from '../../moment';\nlocaleModule('ka');\n\ntest('parse', function (assert) {\n    var i,\n        tests = 'იანვარი იან_თებერვალი თებ_მარტი მარ_აპრილი აპრ_მაისი მაი_ივნისი ივნ_ივლისი ივლ_აგვისტო აგვ_სექტემბერი სექ_ოქტომბერი ოქტ_ნოემბერი ნოე_დეკემბერი დეკ'.split('_');\n\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' უნდა იყოს თვე ' + (i + 1));\n    }\n\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, MMMM Do YYYY, h:mm:ss a', 'კვირა, თებერვალი მე-14 2010, 3:25:50 pm'],\n            ['ddd, hA',                       'კვი, 3PM'],\n            ['M Mo MM MMMM MMM',              '2 მე-2 02 თებერვალი თებ'],\n            ['YYYY YY',                       '2010 10'],\n            ['D Do DD',                       '14 მე-14 14'],\n            ['d do dddd ddd dd',              '0 0 კვირა კვი კვ'],\n            ['DDD DDDo DDDD',                 '45 45-ე 045'],\n            ['w wo ww',                       '7 მე-7 07'],\n            ['h hh',                          '3 03'],\n            ['H HH',                          '15 15'],\n            ['m mm',                          '25 25'],\n            ['s ss',                          '50 50'],\n            ['a A',                           'pm PM'],\n            ['წლის DDDo დღე',                 'წლის 45-ე დღე'],\n            ['LTS',                           '3:25:50 PM'],\n            ['L',                             '14/02/2010'],\n            ['LL',                            '14 თებერვალს 2010'],\n            ['LLL',                           '14 თებერვალს 2010 3:25 PM'],\n            ['LLLL',                          'კვირა, 14 თებერვალს 2010 3:25 PM'],\n            ['l',                             '14/2/2010'],\n            ['ll',                            '14 თებ 2010'],\n            ['lll',                           '14 თებ 2010 3:25 PM'],\n            ['llll',                          'კვი, 14 თებ 2010 3:25 PM']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'),  '1-ლი',  '1-ლი');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'),  'მე-2',  'მე-2');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'),  'მე-3',  'მე-3');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'),  'მე-4',  'მე-4');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'),  'მე-5',  'მე-5');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'),  'მე-6',  'მე-6');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'),  'მე-7',  'მე-7');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'),  'მე-8',  'მე-8');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'),  'მე-9',  'მე-9');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), 'მე-10', 'მე-10');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), 'მე-11', 'მე-11');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), 'მე-12', 'მე-12');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), 'მე-13', 'მე-13');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), 'მე-14', 'მე-14');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), 'მე-15', 'მე-15');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), 'მე-16', 'მე-16');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), 'მე-17', 'მე-17');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), 'მე-18', 'მე-18');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), 'მე-19', 'მე-19');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), 'მე-20', 'მე-20');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21-ე', '21-ე');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22-ე', '22-ე');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23-ე', '23-ე');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24-ე', '24-ე');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25-ე', '25-ე');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26-ე', '26-ე');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27-ე', '27-ე');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28-ე', '28-ე');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29-ე', '29-ე');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30-ე', '30-ე');\n\n    assert.equal(moment('2011 40', 'YYYY DDD').format('DDDo'),  'მე-40',  'მე-40');\n    assert.equal(moment('2011 50', 'YYYY DDD').format('DDDo'),  '50-ე',   '50-ე');\n    assert.equal(moment('2011 60', 'YYYY DDD').format('DDDo'),  'მე-60',  'მე-60');\n    assert.equal(moment('2011 100', 'YYYY DDD').format('DDDo'), 'მე-100', 'მე-100');\n    assert.equal(moment('2011 101', 'YYYY DDD').format('DDDo'), '101-ე',  '101-ე');\n});\n\ntest('format month', function (assert) {\n    var i,\n        expected = 'იანვარი იან_თებერვალი თებ_მარტი მარ_აპრილი აპრ_მაისი მაი_ივნისი ივნ_ივლისი ივლ_აგვისტო აგვ_სექტემბერი სექ_ოქტომბერი ოქტ_ნოემბერი ნოე_დეკემბერი დეკ'.split('_');\n\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var i,\n        expected = 'კვირა კვი კვ_ორშაბათი ორშ ორ_სამშაბათი სამ სა_ოთხშაბათი ოთხ ოთ_ხუთშაბათი ხუთ ხუ_პარასკევი პარ პა_შაბათი შაბ შა'.split('_');\n\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}),  true), 'რამდენიმე წამი', '44 წამი  = რამდენიმე წამი');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}),  true), 'წუთი',           '45 წამი  = წუთი');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}),  true), 'წუთი',           '89 წამი  = წუთი');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}),  true), '2 წუთი',         '90 წამი  = 2 წუთი');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}),  true), '44 წუთი',        '44 წამი  = 44 წუთი');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}),  true), 'საათი',          '45 წამი  = საათი');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}),  true), 'საათი',          '89 წამი  = საათი');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}),  true), '2 საათი',        '90 წამი  = 2 საათი');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}),   true), '5 საათი',        '5 საათი  = 5 საათი');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}),  true), '21 საათი',       '21 საათი = 21 საათი');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}),  true), 'დღე',            '22 საათი = დღე');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}),  true), 'დღე',            '35 საათი = დღე');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}),  true), '2 დღე',          '36 საათი = 2 დღე');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}),   true), 'დღე',            '1 დღე    = დღე');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}),   true), '5 დღე',          '5 დღე    = 5 დღე');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}),  true), '25 დღე',         '25 დღე   = 25 დღე');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}),  true), 'თვე',            '26 დღე   = თვე');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}),  true), 'თვე',            '30 დღე   = თვე');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}),  true), 'თვე',            '45 დღე   = თვე');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}),  true), '2 თვე',          '46 დღე   = 2 თვე');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}),  true), '2 თვე',          '75 დღე   = 2 თვე');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}),  true), '3 თვე',          '76 დღე   = 3 თვე');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}),   true), 'თვე',            '1 თვე    = თვე');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}),   true), '5 თვე',          '5 თვე    = 5 თვე');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'წელი',           '345 დღე  = წელი');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 წელი',         '548 დღე  = 2 წელი');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}),   true), 'წელი',           '1 წელი   = წელი');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}),   true), '5 წელი',         '5 წელი   = 5 წელი');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'რამდენიმე წამში',     'ში სუფიქსი');\n    assert.equal(moment(0).from(30000), 'რამდენიმე წამის უკან', 'უკან სუფიქსი');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'რამდენიმე წამის უკან', 'უნდა აჩვენოს როგორც წარსული');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'რამდენიმე წამში', 'რამდენიმე წამში');\n    assert.equal(moment().add({d: 5}).fromNow(), '5 დღეში', '5 დღეში');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'დღეს 12:00 PM-ზე',  'დღეს ამავე დროს');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'დღეს 12:25 PM-ზე',  'ახლანდელ დროს დამატებული 25 წუთი');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'დღეს 1:00 PM-ზე',   'ახლანდელ დროს დამატებული 1 საათი');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'ხვალ 12:00 PM-ზე',  'ხვალ ამავე დროს');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'დღეს 11:00 AM-ზე',  'ახლანდელ დროს გამოკლებული 1 საათი');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'გუშინ 12:00 PM-ზე', 'გუშინ ამავე დროს');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('[შემდეგ] dddd LT[-ზე]'),  'დღეს + ' + i + ' დღე ახლანდელ დროს');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[შემდეგ] dddd LT[-ზე]'),  'დღეს + ' + i + ' დღე დღის დასაწყისში');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[შემდეგ] dddd LT[-ზე]'),  'დღეს + ' + i + ' დღე დღის დასასრულს');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('[წინა] dddd LT[-ზე]'),  'დღეს - ' + i + ' დღე ახლანდელ დროს');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[წინა] dddd LT[-ზე]'),  'დღეს - ' + i + ' დღე დღის დასაწყისში');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[წინა] dddd LT[-ზე]'),  'დღეს - ' + i + ' დღე დღის დასასრულს');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 კვირის უკან');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  '1 კვირაში');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 კვირის წინ');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  '2 კვირაში');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2011, 11, 26]).format('w ww wo'), '1 01 1-ლი', 'დეკ 26 2011 უნდა იყოს კვირა 1');\n    assert.equal(moment([2012,  0,  1]).format('w ww wo'), '1 01 1-ლი', 'იან  1 2012 უნდა იყოს კვირა 1');\n    assert.equal(moment([2012,  0,  2]).format('w ww wo'), '2 02 მე-2', 'იან  2 2012 უნდა იყოს კვირა 2');\n    assert.equal(moment([2012,  0,  8]).format('w ww wo'), '2 02 მე-2', 'იან  8 2012 უნდა იყოს კვირა 2');\n    assert.equal(moment([2012,  0,  9]).format('w ww wo'), '3 03 მე-3', 'იან  9 2012 უნდა იყოს კვირა 3');\n});\n\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/test/locale/kk.js",
    "content": "import {localeModule, test} from '../qunit';\nimport moment from '../../moment';\nlocaleModule('kk');\n\ntest('parse', function (assert) {\n    var tests = 'қаңтар қаң_ақпан ақп_наурыз нау_сәуір сәу_мамыр мам_маусым мау_шілде шіл_тамыз там_қыркүйек қыр_қазан қаз_қараша қар_желтоқсан жел'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, Do MMMM YYYY, HH:mm:ss',       'жексенбі, 14-ші ақпан 2010, 15:25:50'],\n            ['ddd, hA',                            'жек, 3PM'],\n            ['M Mo MM MMMM MMM',                   '2 2-ші 02 ақпан ақп'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14-ші 14'],\n            ['d do dddd ddd dd',                   '0 0-ші жексенбі жек жк'],\n            ['DDD DDDo DDDD',                      '45 45-ші 045'],\n            ['w wo ww',                            '7 7-ші 07'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'pm PM'],\n            ['[жылдың] DDDo [күні]',               'жылдың 45-ші күні'],\n            ['LTS',                                '15:25:50'],\n            ['L',                                  '14.02.2010'],\n            ['LL',                                 '14 ақпан 2010'],\n            ['LLL',                                '14 ақпан 2010 15:25'],\n            ['LLLL',                               'жексенбі, 14 ақпан 2010 15:25'],\n            ['l',                                  '14.2.2010'],\n            ['ll',                                 '14 ақп 2010'],\n            ['lll',                                '14 ақп 2010 15:25'],\n            ['llll',                               'жек, 14 ақп 2010 15:25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1-ші', '1st');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2-ші', '2nd');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3-ші', '3rd');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4-ші', '4th');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5-ші', '5th');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6-шы', '6th');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7-ші', '7th');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8-ші', '8th');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9-шы', '9th');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10-шы', '10th');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11-ші', '11th');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12-ші', '12th');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13-ші', '13th');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14-ші', '14th');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15-ші', '15th');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16-шы', '16th');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17-ші', '17th');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18-ші', '18th');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19-шы', '19th');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20-шы', '20th');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21-ші', '21st');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22-ші', '22nd');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23-ші', '23rd');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24-ші', '24th');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25-ші', '25th');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26-шы', '26th');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27-ші', '27th');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28-ші', '28th');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29-шы', '29th');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30-шы', '30th');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31-ші', '31st');\n});\n\ntest('format month', function (assert) {\n    var expected = 'қаңтар қаң_ақпан ақп_наурыз нау_сәуір сәу_мамыр мам_маусым мау_шілде шіл_тамыз там_қыркүйек қыр_қазан қаз_қараша қар_желтоқсан жел'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'жексенбі жек жк_дүйсенбі дүй дй_сейсенбі сей сй_сәрсенбі сәр ср_бейсенбі бей бй_жұма жұм жм_сенбі сен сн'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'бірнеше секунд', '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'бір минут',      '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'бір минут',      '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 минут',     '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 минут',    '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'бір сағат',       '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'бір сағат',       '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 сағат',       '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 сағат',       '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 сағат',      '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'бір күн',         '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'бір күн',         '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 күн',        '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'бір күн',         '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 күн',        '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 күн',       '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'бір ай',       '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'бір ай',       '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'бір ай',       '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 ай',      '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 ай',      '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 ай',      '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'бір ай',       '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 ай',      '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'бір жыл',        '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 жыл',       '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'бір жыл',        '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 жыл',       '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'бірнеше секунд ішінде',  'prefix');\n    assert.equal(moment(0).from(30000), 'бірнеше секунд бұрын', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'бірнеше секунд бұрын',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'бірнеше секунд ішінде', 'in a few seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), '5 күн ішінде', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'Бүгін сағат 12:00',  'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'Бүгін сағат 12:25',  'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'Бүгін сағат 13:00',  'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'Ертең сағат 12:00',  'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'Бүгін сағат 11:00',  'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'Кеше сағат 12:00',   'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('dddd [сағат] LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd [сағат] LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd [сағат] LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('[Өткен аптаның] dddd [сағат] LT'),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[Өткен аптаның] dddd [сағат] LT'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[Өткен аптаның] dddd [сағат] LT'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2012, 0,  1]).format('w ww wo'),   '1 01 1-ші', 'Jan  1 2012 should be week 1');\n    assert.equal(moment([2012, 0,  2]).format('w ww wo'),   '2 02 2-ші', 'Jan  2 2012 should be week 2');\n    assert.equal(moment([2012, 0,  8]).format('w ww wo'),   '2 02 2-ші', 'Jan  8 2012 should be week 2');\n    assert.equal(moment([2012, 0,  9]).format('w ww wo'),   '3 03 3-ші', 'Jan  9 2012 should be week 3');\n    assert.equal(moment([2012, 0, 15]).format('w ww wo'),   '3 03 3-ші', 'Jan 15 2012 should be week 3');\n});\n\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/test/locale/km.js",
    "content": "import {localeModule, test} from '../qunit';\nimport moment from '../../moment';\nlocaleModule('km');\n\ntest('parse', function (assert) {\n    var tests = 'មករា មករា_កុម្ភៈ កុម្ភៈ_មីនា មីនា_មេសា មេសា_ឧសភា ឧសភា_មិថុនា មិថុនា_កក្កដា កក្កដា_សីហា សីហា_កញ្ញា កញ្ញា_តុលា តុលា_វិច្ឆិកា វិច្ឆិកា_ធ្នូ ធ្នូ'.split('_'),\n        i;\n\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, MMMM Do YYYY, h:mm:ss a', 'អាទិត្យ, កុម្ភៈ 14 2010, 3:25:50 pm'],\n            ['ddd, hA', 'អាទិត្យ, 3PM'],\n            ['M Mo MM MMMM MMM', '2 2 02 កុម្ភៈ កុម្ភៈ'],\n            ['YYYY YY', '2010 10'],\n            ['D Do DD', '14 14 14'],\n            ['d do dddd ddd dd', '0 0 អាទិត្យ អាទិត្យ អាទិត្យ'],\n            ['DDD DDDo DDDD', '45 45 045'],\n            ['w wo ww', '6 6 06'],\n            ['h hh', '3 03'],\n            ['H HH', '15 15'],\n            ['m mm', '25 25'],\n            ['s ss', '50 50'],\n            ['a A', 'pm PM'],\n            ['[the] DDDo [day of the year]', 'the 45 day of the year'],\n            ['LTS', '15:25:50'],\n            ['L', '14/02/2010'],\n            ['LL', '14 កុម្ភៈ 2010'],\n            ['LLL', '14 កុម្ភៈ 2010 15:25'],\n            ['LLLL', 'អាទិត្យ, 14 កុម្ភៈ 2010 15:25'],\n            ['l', '14/2/2010'],\n            ['ll', '14 កុម្ភៈ 2010'],\n            ['lll', '14 កុម្ភៈ 2010 15:25'],\n            ['llll', 'អាទិត្យ, 14 កុម្ភៈ 2010 15:25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1', '1st');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2', '2nd');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3', '3rd');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4', '4th');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5', '5th');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6', '6th');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7', '7th');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8', '8th');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9', '9th');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10', '10th');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11', '11th');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12', '12th');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13', '13th');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14', '14th');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15', '15th');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16', '16th');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17', '17th');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18', '18th');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19', '19th');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20', '20th');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21', '21st');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22', '22nd');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23', '23rd');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24', '24th');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25', '25th');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26', '26th');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27', '27th');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28', '28th');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29', '29th');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30', '30th');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31', '31st');\n});\n\ntest('format month', function (assert) {\n    var expected = 'មករា មករា_កុម្ភៈ កុម្ភៈ_មីនា មីនា_មេសា មេសា_ឧសភា ឧសភា_មិថុនា មិថុនា_កក្កដា កក្កដា_សីហា សីហា_កញ្ញា កញ្ញា_តុលា តុលា_វិច្ឆិកា វិច្ឆិកា_ធ្នូ ធ្នូ'.split('_'),\n        i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'អាទិត្យ អាទិត្យ អាទិត្យ_ច័ន្ទ ច័ន្ទ ច័ន្ទ_អង្គារ អង្គារ អង្គារ_ពុធ ពុធ ពុធ_ព្រហស្បតិ៍ ព្រហស្បតិ៍ ព្រហស្បតិ៍_សុក្រ សុក្រ សុក្រ_សៅរ៍ សៅរ៍ សៅរ៍'.split('_'),\n        i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true), 'ប៉ុន្មានវិនាទី', '44 seconds = ប៉ុន្មានវិនាទី');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true), 'មួយនាទី', '45 seconds = មួយនាទី');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true), 'មួយនាទី', '89 seconds = មួយនាទី');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true), '2 នាទី', '90 seconds = 2 នាទី');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true), '44 នាទី', '44 minutes = 44 នាទី');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true), 'មួយម៉ោង', '45 minutes = មួយម៉ោង');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true), 'មួយម៉ោង', '89 minutes = មួយម៉ោង');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true), '2 ម៉ោង', '90 minutes = 2 ម៉ោង');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true), '5 ម៉ោង', '5 hours = 5 ម៉ោង');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true), '21 ម៉ោង', '21 hours = 21 ម៉ោង');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true), 'មួយថ្ងៃ', '22 hours = មួយថ្ងៃ');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true), 'មួយថ្ងៃ', '35 hours = មួយថ្ងៃ');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true), '2 ថ្ងៃ', '36 hours = 2 ថ្ងៃ');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true), 'មួយថ្ងៃ', '1 day = មួយថ្ងៃ');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true), '5 ថ្ងៃ', '5 days = 5 ថ្ងៃ');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true), '25 ថ្ងៃ', '25 days = 25 ថ្ងៃ');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true), 'មួយខែ', '26 days = មួយខែ');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true), 'មួយខែ', '30 days = មួយខែ');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true), 'មួយខែ', '43 days = មួយខែ');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true), '2 ខែ', '46 days = 2 ខែ');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true), '2 ខែ', '75 days = 2 ខែ');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true), '3 ខែ', '76 days = 3 ខែ');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true), 'មួយខែ', '1 month = មួយខែ');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true), '5 ខែ', '5 months = 5 ខែ');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'មួយឆ្នាំ', '345 days = មួយឆ្នាំ');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 ឆ្នាំ', '548 days = 2 ឆ្នាំ');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true), 'មួយឆ្នាំ', '1 year = មួយឆ្នាំ');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true), '5 ឆ្នាំ', '5 years = 5 ឆ្នាំ');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'ប៉ុន្មានវិនាទីទៀត', 'prefix');\n    assert.equal(moment(0).from(30000), 'ប៉ុន្មានវិនាទីមុន', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'ប៉ុន្មានវិនាទីមុន', 'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({\n        s: 30\n    }).fromNow(), 'ប៉ុន្មានវិនាទីទៀត', 'in a few seconds');\n    assert.equal(moment().add({\n        d: 5\n    }).fromNow(), '5 ថ្ងៃទៀត', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                  'ថ្ងៃនេះ ម៉ោង 12:00',  'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),     'ថ្ងៃនេះ ម៉ោង 12:25',  'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),      'ថ្ងៃនេះ ម៉ោង 13:00',  'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),      'ស្អែក ម៉ោង 12:00',    'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(), 'ថ្ងៃនេះ ម៉ោង 11:00',  'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(), 'ម្សិលមិញ ម៉ោង 12:00', 'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({\n            d: i\n        });\n        assert.equal(m.calendar(), m.format('dddd [ម៉ោង] LT'), 'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(), m.format('dddd [ម៉ោង] LT'), 'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(), m.format('dddd [ម៉ោង] LT'), 'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({\n            d: i\n        });\n        assert.equal(m.calendar(), m.format('dddd [សប្តាហ៍មុន] [ម៉ោង] LT'), 'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(), m.format('dddd [សប្តាហ៍មុន] [ម៉ោង] LT'), 'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(), m.format('dddd [សប្តាហ៍មុន] [ម៉ោង] LT'), 'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({\n            w: 1\n        }),\n        weeksFromNow = moment().add({\n            w: 1\n        });\n\n    assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '1 week ago');\n    assert.equal(weeksFromNow.calendar(), weeksFromNow.format('L'), 'in 1 week');\n\n    weeksAgo = moment().subtract({\n        w: 2\n    });\n    weeksFromNow = moment().add({\n        w: 2\n    });\n\n    assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(), weeksFromNow.format('L'), 'in 2 weeks');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2012, 0, 1]).format('w ww wo'), '52 52 52', 'Jan  1 2012 should be week 52');\n    assert.equal(moment([2012, 0, 2]).format('w ww wo'), '1 01 1', 'Jan  2 2012 should be week 1');\n    assert.equal(moment([2012, 0, 8]).format('w ww wo'), '1 01 1', 'Jan  8 2012 should be week 1');\n    assert.equal(moment([2012, 0, 9]).format('w ww wo'), '2 02 2', 'Jan  9 2012 should be week 2');\n    assert.equal(moment([2012, 0, 15]).format('w ww wo'), '2 02 2', 'Jan 15 2012 should be week 2');\n});\n\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/test/locale/kn.js",
    "content": "import {localeModule, test} from '../qunit';\nimport moment from '../../moment';\nlocaleModule('kn');\n\ntest('parse', function (assert) {\n    var tests = 'ಜನವರಿ ಜನ_ಫೆಬ್ರವರಿ ಫೆಬ್ರ_ಮಾರ್ಚ್ ಮಾರ್ಚ್_ಏಪ್ರಿಲ್ ಏಪ್ರಿಲ್_ಮೇ ಮೇ_ಜೂನ್ ಜೂನ್_ಜುಲೈ ಜುಲೈ_ಆಗಸ್ಟ್ ಆಗಸ್ಟ್_ಸೆಪ್ಟೆಂಬರ್ ಸೆಪ್ಟೆಂಬ_ಅಕ್ಟೋಬರ್ ಅಕ್ಟೋಬ_ನವೆಂಬರ್ ನವೆಂಬ_ಡಿಸೆಂಬರ್ ಡಿಸೆಂಬ'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, Do MMMM YYYY, a h:mm:ss',      'ಭಾನುವಾರ, ೧೪ನೇ ಫೆಬ್ರವರಿ ೨೦೧೦, ಮಧ್ಯಾಹ್ನ ೩:೨೫:೫೦'],\n            ['ddd, a h ಗಂಟೆ',                      'ಭಾನು, ಮಧ್ಯಾಹ್ನ ೩ ಗಂಟೆ'],\n            ['M Mo MM MMMM MMM',                   '೨ ೨ನೇ ೦೨ ಫೆಬ್ರವರಿ ಫೆಬ್ರ'],\n            ['YYYY YY',                            '೨೦೧೦ ೧೦'],\n            ['D Do DD',                            '೧೪ ೧೪ನೇ ೧೪'],\n            ['d do dddd ddd dd',                   '೦ ೦ನೇ ಭಾನುವಾರ ಭಾನು ಭಾ'],\n            ['DDD DDDo DDDD',                      '೪೫ ೪೫ನೇ ೦೪೫'],\n            ['w wo ww',                            '೮ ೮ನೇ ೦೮'],\n            ['h hh',                               '೩ ೦೩'],\n            ['H HH',                               '೧೫ ೧೫'],\n            ['m mm',                               '೨೫ ೨೫'],\n            ['s ss',                               '೫೦ ೫೦'],\n            ['a A',                                'ಮಧ್ಯಾಹ್ನ ಮಧ್ಯಾಹ್ನ'],\n            ['LTS',                                'ಮಧ್ಯಾಹ್ನ ೩:೨೫:೫೦'],\n            ['L',                                  '೧೪/೦೨/೨೦೧೦'],\n            ['LL',                                 '೧೪ ಫೆಬ್ರವರಿ ೨೦೧೦'],\n            ['LLL',                                '೧೪ ಫೆಬ್ರವರಿ ೨೦೧೦, ಮಧ್ಯಾಹ್ನ ೩:೨೫'],\n            ['LLLL',                               'ಭಾನುವಾರ, ೧೪ ಫೆಬ್ರವರಿ ೨೦೧೦, ಮಧ್ಯಾಹ್ನ ೩:೨೫'],\n            ['l',                                  '೧೪/೨/೨೦೧೦'],\n            ['ll',                                 '೧೪ ಫೆಬ್ರ ೨೦೧೦'],\n            ['lll',                                '೧೪ ಫೆಬ್ರ ೨೦೧೦, ಮಧ್ಯಾಹ್ನ ೩:೨೫'],\n            ['llll',                               'ಭಾನು, ೧೪ ಫೆಬ್ರ ೨೦೧೦, ಮಧ್ಯಾಹ್ನ ೩:೨೫']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '೧ನೇ', '೧ನೇ');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '೨ನೇ', '೨ನೇ');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '೩ನೇ', '೩ನೇ');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '೪ನೇ', '೪ನೇ');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '೫ನೇ', '೫ನೇ');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '೬ನೇ', '೬ನೇ');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '೭ನೇ', '೭ನೇ');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '೮ನೇ', '೮ನೇ');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '೯ನೇ', '೯ನೇ');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '೧೦ನೇ', '೧೦ನೇ');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '೧೧ನೇ', '೧೧ನೇ');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '೧೨ನೇ', '೧೨ನೇ');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '೧೩ನೇ', '೧೩ನೇ');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '೧೪ನೇ', '೧೪ನೇ');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '೧೫ನೇ', '೧೫ನೇ');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '೧೬ನೇ', '೧೬ನೇ');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '೧೭ನೇ', '೧೭ನೇ');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '೧೮ನೇ', '೧೮ನೇ');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '೧೯ನೇ', '೧೯ನೇ');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '೨೦ನೇ', '೨೦ನೇ');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '೨೧ನೇ', '೨೧ನೇ');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '೨೨ನೇ', '೨೨ನೇ');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '೨೩ನೇ', '೨೩ನೇ');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '೨೪ನೇ', '೨೪ನೇ');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '೨೫ನೇ', '೨೫ನೇ');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '೨೬ನೇ', '೨೬ನೇ');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '೨೭ನೇ', '೨೭ನೇ');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '೨೮ನೇ', '೨೮ನೇ');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '೨೯ನೇ', '೨೯ನೇ');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '೩೦ನೇ', '೩೦ನೇ');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '೩೧ನೇ', '೩೧ನೇ');\n});\n\ntest('format month', function (assert) {\n    var expected = 'ಜನವರಿ ಜನ_ಫೆಬ್ರವರಿ ಫೆಬ್ರ_ಮಾರ್ಚ್ ಮಾರ್ಚ್_ಏಪ್ರಿಲ್ ಏಪ್ರಿಲ್_ಮೇ ಮೇ_ಜೂನ್ ಜೂನ್_ಜುಲೈ ಜುಲೈ_ಆಗಸ್ಟ್ ಆಗಸ್ಟ್_ಸೆಪ್ಟೆಂಬರ್ ಸೆಪ್ಟೆಂಬ_ಅಕ್ಟೋಬರ್ ಅಕ್ಟೋಬ_ನವೆಂಬರ್ ನವೆಂಬ_ಡಿಸೆಂಬರ್ ಡಿಸೆಂಬ'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'ಭಾನುವಾರ ಭಾನು ಭಾ_ಸೋಮವಾರ ಸೋಮ ಸೋ_ಮಂಗಳವಾರ ಮಂಗಳ ಮಂ_ಬುಧವಾರ ಬುಧ ಬು_ಗುರುವಾರ ಗುರು ಗು_ಶುಕ್ರವಾರ ಶುಕ್ರ ಶು_ಶನಿವಾರ ಶನಿ ಶ'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'ಕೆಲವು ಕ್ಷಣಗಳು', '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'ಒಂದು ನಿಮಿಷ',      '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'ಒಂದು ನಿಮಿಷ',      '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '೨ ನಿಮಿಷ',     '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '೪೪ ನಿಮಿಷ',    '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'ಒಂದು ಗಂಟೆ',       '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'ಒಂದು ಗಂಟೆ',       '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '೨ ಗಂಟೆ',       '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '೫ ಗಂಟೆ',       '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '೨೧ ಗಂಟೆ',      '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'ಒಂದು ದಿನ',         '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'ಒಂದು ದಿನ',         '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '೨ ದಿನ',        '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'ಒಂದು ದಿನ',         '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '೫ ದಿನ',        '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '೨೫ ದಿನ',       '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'ಒಂದು ತಿಂಗಳು',       '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'ಒಂದು ತಿಂಗಳು',       '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'ಒಂದು ತಿಂಗಳು',       '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '೨ ತಿಂಗಳು',      '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '೨ ತಿಂಗಳು',      '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '೩ ತಿಂಗಳು',      '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'ಒಂದು ತಿಂಗಳು',       '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '೫ ತಿಂಗಳು',      '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'ಒಂದು ವರ್ಷ',        '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '೨ ವರ್ಷ',       '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'ಒಂದು ವರ್ಷ',        '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '೫ ವರ್ಷ',       '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'ಕೆಲವು ಕ್ಷಣಗಳು ನಂತರ',  'prefix');\n    assert.equal(moment(0).from(30000), 'ಕೆಲವು ಕ್ಷಣಗಳು ಹಿಂದೆ', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'ಕೆಲವು ಕ್ಷಣಗಳು ಹಿಂದೆ',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'ಕೆಲವು ಕ್ಷಣಗಳು ನಂತರ', 'ಕೆಲವು ಕ್ಷಣಗಳು ನಂತರ');\n    assert.equal(moment().add({d: 5}).fromNow(), '೫ ದಿನ ನಂತರ', '೫ ದಿನ ನಂತರ');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'ಇಂದು ಮಧ್ಯಾಹ್ನ ೧೨:೦೦',    'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'ಇಂದು ಮಧ್ಯಾಹ್ನ ೧೨:೨೫',    'Now plus 25 min');\n    assert.equal(moment(a).add({h: 3}).calendar(),       'ಇಂದು ಮಧ್ಯಾಹ್ನ ೩:೦೦',     'Now plus 3 hours');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'ನಾಳೆ ಮಧ್ಯಾಹ್ನ ೧೨:೦೦',    'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'ಇಂದು ಮಧ್ಯಾಹ್ನ ೧೧:೦೦',    'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'ನಿನ್ನೆ ಮಧ್ಯಾಹ್ನ ೧೨:೦೦',    'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('dddd[,] LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd[,] LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd[,] LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('[ಕೊನೆಯ] dddd[,] LT'),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[ಕೊನೆಯ] dddd[,] LT'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[ಕೊನೆಯ] dddd[,] LT'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('meridiem', function (assert) {\n    assert.equal(moment([2011, 2, 23,  2, 30]).format('a'), 'ರಾತ್ರಿ', 'before dawn');\n    assert.equal(moment([2011, 2, 23,  9, 30]).format('a'), 'ಬೆಳಿಗ್ಗೆ', 'morning');\n    assert.equal(moment([2011, 2, 23, 14, 30]).format('a'), 'ಮಧ್ಯಾಹ್ನ', 'during day');\n    assert.equal(moment([2011, 2, 23, 17, 30]).format('a'), 'ಸಂಜೆ', 'evening');\n    assert.equal(moment([2011, 2, 23, 19, 30]).format('a'), 'ಸಂಜೆ', 'late evening');\n    assert.equal(moment([2011, 2, 23, 21, 20]).format('a'), 'ರಾತ್ರಿ', 'night');\n\n    assert.equal(moment([2011, 2, 23,  2, 30]).format('A'), 'ರಾತ್ರಿ', 'before dawn');\n    assert.equal(moment([2011, 2, 23,  9, 30]).format('A'), 'ಬೆಳಿಗ್ಗೆ', 'morning');\n    assert.equal(moment([2011, 2, 23, 14, 30]).format('A'), 'ಮಧ್ಯಾಹ್ನ', ' during day');\n    assert.equal(moment([2011, 2, 23, 17, 30]).format('A'), 'ಸಂಜೆ', 'evening');\n    assert.equal(moment([2011, 2, 23, 19, 30]).format('A'), 'ಸಂಜೆ', 'late evening');\n    assert.equal(moment([2011, 2, 23, 21, 20]).format('A'), 'ರಾತ್ರಿ', 'night');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2012, 0,  1]).format('w ww wo'), '೧ ೦೧ ೧ನೇ', 'Jan  1 2012 should be week 1');\n    assert.equal(moment([2012, 0,  7]).format('w ww wo'), '೧ ೦೧ ೧ನೇ', 'Jan  7 2012 should be week 1');\n    assert.equal(moment([2012, 0,  8]).format('w ww wo'), '೨ ೦೨ ೨ನೇ', 'Jan  8 2012 should be week 2');\n    assert.equal(moment([2012, 0, 14]).format('w ww wo'), '೨ ೦೨ ೨ನೇ', 'Jan 14 2012 should be week 2');\n    assert.equal(moment([2012, 0, 15]).format('w ww wo'), '೩ ೦೩ ೩ನೇ', 'Jan 15 2012 should be week 3');\n});\n\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/test/locale/ko.js",
    "content": "import {localeModule, test} from '../qunit';\nimport moment from '../../moment';\nlocaleModule('ko');\n\ntest('parse', function (assert) {\n    var tests = '1월 1월_2월 2월_3월 3월_4월 4월_5월 5월_6월 6월_7월 7월_8월 8월_9월 9월_10월 10월_11월 11월_12월 12월'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('parse meridiem', function (assert) {\n    var elements = [{\n        expression : '1981년 9월 8일 오후 2시 30분',\n        inputFormat : 'YYYY[년] M[월] D[일] A h[시] m[분]',\n        outputFormat : 'A',\n        expected : '오후'\n    }, {\n        expression : '1981년 9월 8일 오전 2시 30분',\n        inputFormat : 'YYYY[년] M[월] D[일] A h[시] m[분]',\n        outputFormat : 'A h시',\n        expected : '오전 2시'\n    }, {\n        expression : '14시 30분',\n        inputFormat : 'H[시] m[분]',\n        outputFormat : 'A',\n        expected : '오후'\n    }, {\n        expression : '오후 4시',\n        inputFormat : 'A h[시]',\n        outputFormat : 'H',\n        expected : '16'\n    }], i, l, it, actual;\n\n    for (i = 0, l = elements.length; i < l; ++i) {\n        it = elements[i];\n        actual = moment(it.expression, it.inputFormat).format(it.outputFormat);\n\n        assert.equal(\n            actual,\n            it.expected,\n            '\\'' + it.outputFormat + '\\' of \\'' + it.expression + '\\' must be \\'' + it.expected + '\\' but was \\'' + actual + '\\'.'\n        );\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['YYYY년 MMMM Do dddd a h:mm:ss',      '2010년 2월 14일 일요일 오후 3:25:50'],\n            ['ddd A h',                            '일 오후 3'],\n            ['M Mo MM MMMM MMM',                   '2 2일 02 2월 2월'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14일 14'],\n            ['d do dddd ddd dd',                   '0 0일 일요일 일 일'],\n            ['DDD DDDo DDDD',                      '45 45일 045'],\n            ['w wo ww',                            '8 8일 08'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                '오후 오후'],\n            ['일년 중 DDDo째 되는 날',                 '일년 중 45일째 되는 날'],\n            ['LTS',                                '오후 3:25:50'],\n            ['L',                                  '2010.02.14'],\n            ['LL',                                 '2010년 2월 14일'],\n            ['LLL',                                '2010년 2월 14일 오후 3:25'],\n            ['LLLL',                               '2010년 2월 14일 일요일 오후 3:25'],\n            ['l',                                  '2010.02.14'],\n            ['ll',                                 '2010년 2월 14일'],\n            ['lll',                                '2010년 2월 14일 오후 3:25'],\n            ['llll',                               '2010년 2월 14일 일요일 오후 3:25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1일', '1일');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2일', '2일');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3일', '3일');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4일', '4일');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5일', '5일');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6일', '6일');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7일', '7일');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8일', '8일');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9일', '9일');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10일', '10일');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11일', '11일');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12일', '12일');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13일', '13일');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14일', '14일');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15일', '15일');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16일', '16일');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17일', '17일');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18일', '18일');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19일', '19일');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20일', '20일');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21일', '21일');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22일', '22일');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23일', '23일');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24일', '24일');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25일', '25일');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26일', '26일');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27일', '27일');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28일', '28일');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29일', '29일');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30일', '30일');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31일', '31일');\n});\n\ntest('format month', function (assert) {\n    var expected = '1월 1월_2월 2월_3월 3월_4월 4월_5월 5월_6월 6월_7월 7월_8월 8월_9월 9월_10월 10월_11월 11월_12월 12월'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = '일요일 일 일_월요일 월 월_화요일 화 화_수요일 수 수_목요일 목 목_금요일 금 금_토요일 토 토'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  '몇 초', '44초 = 몇 초');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  '1분',      '45초 = 1분');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  '1분',      '89초 = 1분');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2분',     '90초 = 2분');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44분',    '44분 = 44분');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  '한 시간',       '45분 = 한 시간');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  '한 시간',       '89분 = 한 시간');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2시간',       '90분 = 2시간');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5시간',       '5시간 = 5시간');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21시간',      '21시간 = 21시간');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  '하루',         '22시간 = 하루');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  '하루',         '35시간 = 하루');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2일',        '36시간 = 2일');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   '하루',         '하루 = 하루');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5일',        '5일 = 5일');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25일',       '25일 = 25일');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  '한 달',       '26일 = 한 달');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  '한 달',       '30일 = 한 달');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  '한 달',       '45일 = 한 달');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2달',      '46일 = 2달');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2달',      '75일 = 2달');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3달',      '76일 = 3달');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   '한 달',       '1달 = 한 달');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5달',      '5달 = 5달');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), '일 년',        '345일 = 일 년');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2년',       '548일 = 2년');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   '일 년',        '일 년 = 일 년');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5년',       '5년 = 5년');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), '몇 초 후',  'prefix');\n    assert.equal(moment(0).from(30000), '몇 초 전', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), '몇 초 전',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), '몇 초 후', 'in a few seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), '5일 후', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   '오늘 오후 12:00', 'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      '오늘 오후 12:25', 'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       '오늘 오후 1:00',  'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       '내일 오후 12:00', 'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  '오늘 오전 11:00', 'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  '어제 오후 12:00', 'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('dddd LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('지난주 dddd LT'),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('지난주 dddd LT'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('지난주 dddd LT'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('weeks year starting sunday format', function (assert) {\n    assert.equal(moment([2012, 0,  1]).format('w ww wo'), '1 01 1일', 'Jan  1 2012 should be week 1');\n    assert.equal(moment([2012, 0,  7]).format('w ww wo'), '1 01 1일', 'Jan  7 2012 should be week 1');\n    assert.equal(moment([2012, 0,  8]).format('w ww wo'), '2 02 2일', 'Jan  8 2012 should be week 2');\n    assert.equal(moment([2012, 0, 14]).format('w ww wo'), '2 02 2일', 'Jan 14 2012 should be week 2');\n    assert.equal(moment([2012, 0, 15]).format('w ww wo'), '3 03 3일', 'Jan 15 2012 should be week 3');\n});\n\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/test/locale/ky.js",
    "content": "import {localeModule, test} from '../qunit';\nimport moment from '../../moment';\nlocaleModule('ky');\n\ntest('parse', function (assert) {\n    var tests = 'январь янв_февраль фев_март март_апрель апр_май май_июнь июнь_июль июль_август авг_сентябрь сен_октябрь окт_ноябрь ноя_декабрь дек'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, Do MMMM YYYY, HH:mm:ss',       'Жекшемби, 14-чү февраль 2010, 15:25:50'],\n            ['ddd, hA',                            'Жек, 3PM'],\n            ['M Mo MM MMMM MMM',                   '2 2-чи 02 февраль фев'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14-чү 14'],\n            ['d do dddd ddd dd',                   '0 0-чү Жекшемби Жек Жк'],\n            ['DDD DDDo DDDD',                      '45 45-чи 045'],\n            ['w wo ww',                            '7 7-чи 07'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'pm PM'],\n            ['[жылдын] DDDo [күнү]',               'жылдын 45-чи күнү'],\n            ['LTS',                                '15:25:50'],\n            ['L',                                  '14.02.2010'],\n            ['LL',                                 '14 февраль 2010'],\n            ['LLL',                                '14 февраль 2010 15:25'],\n            ['LLLL',                               'Жекшемби, 14 февраль 2010 15:25'],\n            ['l',                                  '14.2.2010'],\n            ['ll',                                 '14 фев 2010'],\n            ['lll',                                '14 фев 2010 15:25'],\n            ['llll',                               'Жек, 14 фев 2010 15:25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1-чи', '1st');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2-чи', '2nd');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3-чү', '3rd');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4-чү', '4th');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5-чи', '5th');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6-чы', '6th');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7-чи', '7th');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8-чи', '8th');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9-чу', '9th');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10-чу', '10th');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11-чи', '11th');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12-чи', '12th');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13-чү', '13th');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14-чү', '14th');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15-чи', '15th');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16-чы', '16th');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17-чи', '17th');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18-чи', '18th');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19-чу', '19th');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20-чы', '20th');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21-чи', '21st');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22-чи', '22nd');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23-чү', '23rd');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24-чү', '24th');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25-чи', '25th');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26-чы', '26th');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27-чи', '27th');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28-чи', '28th');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29-чу', '29th');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30-чу', '30th');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31-чи', '31st');\n});\n\ntest('format month', function (assert) {\n    var expected = 'январь янв_февраль фев_март март_апрель апр_май май_июнь июнь_июль июль_август авг_сентябрь сен_октябрь окт_ноябрь ноя_декабрь дек'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'Жекшемби Жек Жк_Дүйшөмбү Дүй Дй_Шейшемби Шей Шй_Шаршемби Шар Шр_Бейшемби Бей Бй_Жума Жум Жм_Ишемби Ише Иш'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'бирнече секунд', '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'бир мүнөт',      '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'бир мүнөт',      '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 мүнөт',     '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 мүнөт',    '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'бир саат',       '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'бир саат',       '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 саат',       '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 саат',       '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 саат',      '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'бир күн',         '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'бир күн',         '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 күн',        '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'бир күн',         '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 күн',        '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 күн',       '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'бир ай',       '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'бир ай',       '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'бир ай',       '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 ай',      '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 ай',      '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 ай',      '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'бир ай',       '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 ай',      '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'бир жыл',        '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 жыл',       '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'бир жыл',        '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 жыл',       '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'бирнече секунд ичинде',  'prefix');\n    assert.equal(moment(0).from(30000), 'бирнече секунд мурун', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'бирнече секунд мурун',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'бирнече секунд ичинде', 'in a few seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), '5 күн ичинде', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'Бүгүн саат 12:00',  'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'Бүгүн саат 12:25',  'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'Бүгүн саат 13:00',  'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'Эртең саат 12:00',  'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'Бүгүн саат 11:00',  'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'Кече саат 12:00',   'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('dddd [саат] LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd [саат] LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd [саат] LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('[Өткен аптанын] dddd [күнү] [саат] LT'),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[Өткен аптанын] dddd [күнү] [саат] LT'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[Өткен аптанын] dddd [күнү] [саат] LT'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2012, 0,  1]).format('w ww wo'),   '1 01 1-чи', 'Jan  1 2012 should be week 1');\n    assert.equal(moment([2012, 0,  2]).format('w ww wo'),   '2 02 2-чи', 'Jan  2 2012 should be week 2');\n    assert.equal(moment([2012, 0,  8]).format('w ww wo'),   '2 02 2-чи', 'Jan  8 2012 should be week 2');\n    assert.equal(moment([2012, 0,  9]).format('w ww wo'),   '3 03 3-чү', 'Jan  9 2012 should be week 3');\n    assert.equal(moment([2012, 0, 15]).format('w ww wo'),   '3 03 3-чү', 'Jan 15 2012 should be week 3');\n});\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/test/locale/lb.js",
    "content": "import {localeModule, test} from '../qunit';\nimport moment from '../../moment';\nlocaleModule('lb');\n\ntest('parse', function (assert) {\n    var tests = 'Januar Jan._Februar Febr._Mäerz Mrz._Abrëll Abr._Mee Mee_Juni Jun._Juli Jul._August Aug._September Sept._Oktober Okt._November Nov._Dezember Dez.'.split('_'), i;\n\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, Do MMMM YYYY, HH:mm:ss', 'Sonndeg, 14. Februar 2010, 15:25:50'],\n            ['ddd, HH:mm', 'So., 15:25'],\n            ['M Mo MM MMMM MMM', '2 2. 02 Februar Febr.'],\n            ['YYYY YY', '2010 10'],\n            ['D Do DD', '14 14. 14'],\n            ['d do dddd ddd dd', '0 0. Sonndeg So. So'],\n            ['DDD DDDo DDDD', '45 45. 045'],\n            ['w wo ww', '6 6. 06'],\n            ['h hh', '3 03'],\n            ['H HH', '15 15'],\n            ['m mm', '25 25'],\n            ['s ss', '50 50'],\n            ['a A', 'pm PM'],\n            ['[the] DDDo [day of the year]', 'the 45. day of the year'],\n            ['LTS', '15:25:50 Auer'],\n            ['L', '14.02.2010'],\n            ['LL', '14. Februar 2010'],\n            ['LLL', '14. Februar 2010 15:25 Auer'],\n            ['LLLL', 'Sonndeg, 14. Februar 2010 15:25 Auer'],\n            ['l', '14.2.2010'],\n            ['ll', '14. Febr. 2010'],\n            ['lll', '14. Febr. 2010 15:25 Auer'],\n            ['llll', 'So., 14. Febr. 2010 15:25 Auer']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format month', function (assert) {\n    var expected = 'Januar Jan._Februar Febr._Mäerz Mrz._Abrëll Abr._Mee Mee_Juni Jun._Juli Jul._August Aug._September Sept._Oktober Okt._November Nov._Dezember Dez.'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'Sonndeg So. So_Méindeg Mé. Mé_Dënschdeg Dë. Dë_Mëttwoch Më. Më_Donneschdeg Do. Do_Freideg Fr. Fr_Samschdeg Sa. Sa'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true), 'e puer Sekonnen', '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true), 'eng Minutt', '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true), 'eng Minutt', '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true), '2 Minutten', '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true), '44 Minutten', '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true), 'eng Stonn', '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true), 'eng Stonn', '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true), '2 Stonnen', '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true), '5 Stonnen', '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true), '21 Stonnen', '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true), 'een Dag', '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true), 'een Dag', '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true), '2 Deeg', '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true), 'een Dag', '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true), '5 Deeg', '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true), '25 Deeg', '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true), 'ee Mount', '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true), 'ee Mount', '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true), 'ee Mount', '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true), '2 Méint', '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true), '2 Méint', '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true), '3 Méint', '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true), 'ee Mount', '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true), '5 Méint', '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'ee Joer', '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 Joer', '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true), 'ee Joer', '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true), '5 Joer', '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'an e puer Sekonnen', 'prefix');\n    assert.equal(moment(0).from(30000), 'virun e puer Sekonnen', 'suffix');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'an e puer Sekonnen', 'in a few seconds');\n    assert.equal(moment().add({d: 1}).fromNow(), 'an engem Dag', 'in one day');\n    assert.equal(moment().add({d: 2}).fromNow(), 'an 2 Deeg', 'in 2 days');\n    assert.equal(moment().add({d: 3}).fromNow(), 'an 3 Deeg', 'in 3 days');\n    assert.equal(moment().add({d: 4}).fromNow(), 'a 4 Deeg', 'in 4 days');\n    assert.equal(moment().add({d: 5}).fromNow(), 'a 5 Deeg', 'in 5 days');\n    assert.equal(moment().add({d: 6}).fromNow(), 'a 6 Deeg', 'in 6 days');\n    assert.equal(moment().add({d: 7}).fromNow(), 'a 7 Deeg', 'in 7 days');\n    assert.equal(moment().add({d: 8}).fromNow(), 'an 8 Deeg', 'in 8 days');\n    assert.equal(moment().add({d: 9}).fromNow(), 'an 9 Deeg', 'in 9 days');\n    assert.equal(moment().add({d: 10}).fromNow(), 'an 10 Deeg', 'in 10 days');\n    assert.equal(moment().add({y: 100}).fromNow(), 'an 100 Joer', 'in 100 years');\n    assert.equal(moment().add({y: 400}).fromNow(), 'a 400 Joer', 'in 400 years');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'Haut um 12:00 Auer',     'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'Haut um 12:25 Auer',     'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'Haut um 13:00 Auer',     'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'Muer um 12:00 Auer',     'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'Haut um 11:00 Auer',     'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'Gëschter um 12:00 Auer', 'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('dddd [um] LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd [um] LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd [um] LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m, weekday, datestring;\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n\n        // Different date string for 'Dënschdeg' (Tuesday) and 'Donneschdeg' (Thursday)\n        weekday = parseInt(m.format('d'), 10);\n        datestring = (weekday === 2 || weekday === 4 ? '[Leschten] dddd [um] LT' : '[Leschte] dddd [um] LT');\n\n        assert.equal(m.calendar(), m.format(datestring), 'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(), m.format(datestring), 'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(), m.format(datestring), 'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('weeks year starting sunday format', function (assert) {\n    assert.equal(moment([2012, 0,  1]).format('w ww wo'), '52 52 52.', 'Jan  1 2012 should be week 52');\n    assert.equal(moment([2012, 0,  7]).format('w ww wo'), '1 01 1.',   'Jan  7 2012 should be week 1');\n    assert.equal(moment([2012, 0,  8]).format('w ww wo'), '1 01 1.',   'Jan  8 2012 should be week 1');\n    assert.equal(moment([2012, 0, 14]).format('w ww wo'), '2 02 2.',   'Jan 14 2012 should be week 2');\n    assert.equal(moment([2012, 0, 15]).format('w ww wo'), '2 02 2.',   'Jan 15 2012 should be week 2');\n});\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/test/locale/lo.js",
    "content": "import {localeModule, test} from '../qunit';\nimport moment from '../../moment';\nlocaleModule('lo');\n\ntest('parse', function (assert) {\n    var tests = 'ມັງກອນ ມັງກອນ_ກຸມພາ ກຸມພາ_ມີນາ ມີນາ_ເມສາ ເມສາ_ພຶດສະພາ ພຶດສະພາ_ມິຖຸນາ ມິຖຸນາ_ກໍລະກົດ ກໍລະກົດ_ສິງຫາ ສິງຫາ_ກັນຍາ ກັນຍາ_ຕຸລາ ຕຸລາ_ພະຈິກ ພະຈິກ_ທັນວາ ທັນວາ'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, MMMM Do YYYY, h:mm:ss a',      'ອາທິດ, ກຸມພາ ທີ່14 2010, 3:25:50 ຕອນແລງ'],\n            ['ddd, hA',                            'ທິດ, 3ຕອນແລງ'],\n            ['M Mo MM MMMM MMM',                   '2 ທີ່2 02 ກຸມພາ ກຸມພາ'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 ທີ່14 14'],\n            ['d do dddd ddd dd',                   '0 ທີ່0 ອາທິດ ທິດ ທ'],\n            ['DDD DDDo DDDD',                      '45 ທີ່45 045'],\n            ['w wo ww',                            '8 ທີ່8 08'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'ຕອນແລງ ຕອນແລງ'],\n            ['[ວັນ]DDDo [ຂອງປີ]',                   'ວັນທີ່45 ຂອງປີ'],\n            ['LTS',                                '15:25:50'],\n            ['L',                                  '14/02/2010'],\n            ['LL',                                 '14 ກຸມພາ 2010'],\n            ['LLL',                                '14 ກຸມພາ 2010 15:25'],\n            ['LLLL',                               'ວັນອາທິດ 14 ກຸມພາ 2010 15:25'],\n            ['l',                                  '14/2/2010'],\n            ['ll',                                 '14 ກຸມພາ 2010'],\n            ['lll',                                '14 ກຸມພາ 2010 15:25'],\n            ['llll',                               'ວັນທິດ 14 ກຸມພາ 2010 15:25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), 'ທີ່1', 'ທີ່1');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), 'ທີ່2', 'ທີ່2');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), 'ທີ່3', 'ທີ່3');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), 'ທີ່4', 'ທີ່4');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), 'ທີ່5', 'ທີ່5');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), 'ທີ່6', 'ທີ່6');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), 'ທີ່7', 'ທີ່7');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), 'ທີ່8', 'ທີ່8');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), 'ທີ່9', 'ທີ່9');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), 'ທີ່10', 'ທີ່10');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), 'ທີ່11', 'ທີ່11');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), 'ທີ່12', 'ທີ່12');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), 'ທີ່13', 'ທີ່13');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), 'ທີ່14', 'ທີ່14');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), 'ທີ່15', 'ທີ່15');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), 'ທີ່16', 'ທີ່16');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), 'ທີ່17', 'ທີ່17');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), 'ທີ່18', 'ທີ່18');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), 'ທີ່19', 'ທີ່19');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), 'ທີ່20', 'ທີ່20');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), 'ທີ່21', 'ທີ່21');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), 'ທີ່22', 'ທີ່22');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), 'ທີ່23', 'ທີ່23');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), 'ທີ່24', 'ທີ່24');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), 'ທີ່25', 'ທີ່25');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), 'ທີ່26', 'ທີ່26');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), 'ທີ່27', 'ທີ່27');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), 'ທີ່28', 'ທີ່28');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), 'ທີ່29', 'ທີ່29');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), 'ທີ່30', 'ທີ່30');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), 'ທີ່31', 'ທີ່31');\n});\n\ntest('format month', function (assert) {\n    var expected = 'ມັງກອນ ມັງກອນ_ກຸມພາ ກຸມພາ_ມີນາ ມີນາ_ເມສາ ເມສາ_ພຶດສະພາ ພຶດສະພາ_ມິຖຸນາ ມິຖຸນາ_ກໍລະກົດ ກໍລະກົດ_ສິງຫາ ສິງຫາ_ກັນຍາ ກັນຍາ_ຕຸລາ ຕຸລາ_ພະຈິກ ພະຈິກ_ທັນວາ ທັນວາ'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'ອາທິດ ທິດ ທ_ຈັນ ຈັນ ຈ_ອັງຄານ ອັງຄານ ອຄ_ພຸດ ພຸດ ພ_ພະຫັດ ພະຫັດ ພຫ_ສຸກ ສຸກ ສກ_ເສົາ ເສົາ ສ'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'ບໍ່ເທົ່າໃດວິນາທີ', '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  '1 ນາທີ',      '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  '1 ນາທີ',      '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 ນາທີ',     '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 ນາທີ',    '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  '1 ຊົ່ວໂມງ',       '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  '1 ຊົ່ວໂມງ',       '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 ຊົ່ວໂມງ',       '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 ຊົ່ວໂມງ',       '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 ຊົ່ວໂມງ',      '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  '1 ມື້',         '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  '1 ມື້',         '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 ມື້',        '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   '1 ມື້',         '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 ມື້',        '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 ມື້',       '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  '1 ເດືອນ',       '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  '1 ເດືອນ',       '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  '1 ເດືອນ',       '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 ເດືອນ',      '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 ເດືອນ',      '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 ເດືອນ',      '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   '1 ເດືອນ',       '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 ເດືອນ',      '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), '1 ປີ',        '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 ປີ',       '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   '1 ປີ',        '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 ປີ',       '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'ອີກ ບໍ່ເທົ່າໃດວິນາທີ',  'prefix');\n    assert.equal(moment(0).from(30000), 'ບໍ່ເທົ່າໃດວິນາທີຜ່ານມາ', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'ບໍ່ເທົ່າໃດວິນາທີຜ່ານມາ',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'ອີກ ບໍ່ເທົ່າໃດວິນາທີ', 'in a few seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), 'ອີກ 5 ມື້', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'ມື້ນີ້ເວລາ 12:00',    'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'ມື້ນີ້ເວລາ 12:25',    'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'ມື້ນີ້ເວລາ 13:00',    'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'ມື້ອື່ນເວລາ 12:00',   'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'ມື້ນີ້ເວລາ 11:00',    'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'ມື້ວານນີ້ເວລາ 12:00',  'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('[ວັນ]dddd[ໜ້າເວລາ] LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[ວັນ]dddd[ໜ້າເວລາ] LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[ວັນ]dddd[ໜ້າເວລາ] LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('[ວັນ]dddd[ແລ້ວນີ້ເວລາ] LT'),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[ວັນ]dddd[ແລ້ວນີ້ເວລາ] LT'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[ວັນ]dddd[ແລ້ວນີ້ເວລາ] LT'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('weeks year starting sunday format', function (assert) {\n    assert.equal(moment([2012, 0,  1]).format('w ww wo'), '1 01 ທີ່1', 'Jan  1 2012 should be week 1');\n    assert.equal(moment([2012, 0,  7]).format('w ww wo'), '1 01 ທີ່1', 'Jan  7 2012 should be week 1');\n    assert.equal(moment([2012, 0,  8]).format('w ww wo'), '2 02 ທີ່2', 'Jan  8 2012 should be week 2');\n    assert.equal(moment([2012, 0, 14]).format('w ww wo'), '2 02 ທີ່2', 'Jan 14 2012 should be week 2');\n    assert.equal(moment([2012, 0, 15]).format('w ww wo'), '3 03 ທີ່3', 'Jan 15 2012 should be week 3');\n});\n\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/test/locale/lt.js",
    "content": "import {localeModule, test} from '../qunit';\nimport moment from '../../moment';\nlocaleModule('lt');\n\ntest('parse', function (assert) {\n    var tests = 'sausis sau_vasaris vas_kovas kov_balandis bal_gegužė geg_birželis bir_liepa lie_rugpjūtis rgp_rugsėjis rgs_spalis spa_lapkritis lap_gruodis grd'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, Do MMMM YYYY, h:mm:ss a',      'sekmadienis, 14-oji vasario 2010, 3:25:50 pm'],\n            ['ddd, hA',                            'Sek, 3PM'],\n            ['M Mo MM MMMM MMM',                   '2 2-oji 02 vasaris vas'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14-oji 14'],\n            ['d do dddd ddd dd',                   '0 0-oji sekmadienis Sek S'],\n            ['DDD DDDo DDDD',                      '45 45-oji 045'],\n            ['w wo ww',                            '6 6-oji 06'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'pm PM'],\n            ['DDDo [metų diena]',                  '45-oji metų diena'],\n            ['LTS',                                '15:25:50'],\n            ['L',                                  '2010-02-14'],\n            ['LL',                                 '2010 m. vasario 14 d.'],\n            ['LLL',                                '2010 m. vasario 14 d., 15:25 val.'],\n            ['LLLL',                               '2010 m. vasario 14 d., sekmadienis, 15:25 val.'],\n            ['l',                                  '2010-02-14'],\n            ['ll',                                 '2010 m. vasario 14 d.'],\n            ['lll',                                '2010 m. vasario 14 d., 15:25 val.'],\n            ['llll',                               '2010 m. vasario 14 d., Sek, 15:25 val.']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1-oji', '1-oji');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2-oji', '2-oji');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3-oji', '3-oji');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4-oji', '4-oji');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5-oji', '5-oji');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6-oji', '6-oji');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7-oji', '7-oji');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8-oji', '8-oji');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9-oji', '9-oji');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10-oji', '10-oji');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11-oji', '11-oji');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12-oji', '12-oji');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13-oji', '13-oji');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14-oji', '14-oji');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15-oji', '15-oji');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16-oji', '16-oji');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17-oji', '17-oji');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18-oji', '18-oji');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19-oji', '19-oji');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20-oji', '20-oji');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21-oji', '21-oji');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22-oji', '22-oji');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23-oji', '23-oji');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24-oji', '24-oji');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25-oji', '25-oji');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26-oji', '26-oji');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27-oji', '27-oji');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28-oji', '28-oji');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29-oji', '29-oji');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30-oji', '30-oji');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31-oji', '31-oji');\n});\n\ntest('format month', function (assert) {\n    var expected = 'sausis sau_vasaris vas_kovas kov_balandis bal_gegužė geg_birželis bir_liepa lie_rugpjūtis rgp_rugsėjis rgs_spalis spa_lapkritis lap_gruodis grd'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'sekmadienis Sek S_pirmadienis Pir P_antradienis Ant A_trečiadienis Tre T_ketvirtadienis Ket K_penktadienis Pen Pn_šeštadienis Šeš Š'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('format week on US calendar', function (assert) {\n    // Tests, whether the weekday names are correct, even if the week does not start on Monday\n    moment.updateLocale('lt', {week: {dow: 0, doy: 6}});\n    var expected = 'sekmadienis Sek S_pirmadienis Pir P_antradienis Ant A_trečiadienis Tre T_ketvirtadienis Ket K_penktadienis Pen Pn_šeštadienis Šeš Š'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n    moment.updateLocale('lt', null);\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'kelios sekundės', '44 seconds = seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'minutė',          '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'minutė',          '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 minutės',       '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 10}), true),  '10 minučių',       '10 minutes = 10 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 11}), true),  '11 minučių',       '11 minutes = 11 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 19}), true),  '19 minučių',       '19 minutes = 19 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 20}), true),  '20 minučių',       '20 minutes = 20 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 minutės',      '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'valanda',         '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'valanda',         '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 valandos',      '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 valandos',      '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 10}), true),  '10 valandų',      '10 hours = 10 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 valandos',     '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'diena',           '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'diena',           '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 dienos',        '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'diena',           '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 dienos',        '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 10}), true),  '10 dienų',        '10 days = 10 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 dienos',       '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'mėnuo',           '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'mėnuo',           '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'mėnuo',           '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 mėnesiai',      '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 mėnesiai',      '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 mėnesiai',      '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'mėnuo',           '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 mėnesiai',      '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 10}), true),  '10 mėnesių',      '10 months = 10 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'metai',           '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 metai',         '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'metai',           '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 metai',         '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'po kelių sekundžių',  'prefix');\n    assert.equal(moment(0).from(30000), 'prieš kelias sekundes', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'prieš kelias sekundes',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'po kelių sekundžių', 'in seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), 'po 5 dienų', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'Šiandien 12:00',  'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'Šiandien 12:25',  'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'Šiandien 13:00',  'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'Rytoj 12:00',     'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'Šiandien 11:00',  'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'Vakar 12:00',     'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('dddd LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('[Praėjusį] dddd LT'),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[Praėjusį] dddd LT'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[Praėjusį] dddd LT'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2012, 0,  1]).format('w ww wo'), '52 52 52-oji', 'Jan  1 2012 should be week 52');\n    assert.equal(moment([2012, 0,  2]).format('w ww wo'),  '1 01 1-oji', 'Jan  2 2012 should be week 1');\n    assert.equal(moment([2012, 0,  8]).format('w ww wo'),  '1 01 1-oji', 'Jan  8 2012 should be week 1');\n    assert.equal(moment([2012, 0,  9]).format('w ww wo'),  '2 02 2-oji', 'Jan  9 2012 should be week 2');\n    assert.equal(moment([2012, 0, 15]).format('w ww wo'),  '2 02 2-oji', 'Jan 15 2012 should be week 2');\n});\n\ntest('month cases', function (assert) {\n    assert.equal(moment([2015, 4, 1]).format('LL'), '2015 m. gegužės 1 d.', 'uses format instead of standalone form');\n});\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/test/locale/lv.js",
    "content": "import {localeModule, test} from '../qunit';\nimport moment from '../../moment';\nlocaleModule('lv');\n\ntest('parse', function (assert) {\n    var tests = 'janvāris jan_februāris feb_marts mar_aprīlis apr_maijs mai_jūnijs jūn_jūlijs jūl_augusts aug_septembris sep_oktobris okt_novembris nov_decembris dec'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, Do MMMM YYYY, h:mm:ss a',      'svētdiena, 14. februāris 2010, 3:25:50 pm'],\n            ['ddd, hA',                            'Sv, 3PM'],\n            ['M Mo MM MMMM MMM',                   '2 2. 02 februāris feb'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14. 14'],\n            ['d do dddd ddd dd',                   '0 0. svētdiena Sv Sv'],\n            ['DDD DDDo DDDD',                      '45 45. 045'],\n            ['w wo ww',                            '6 6. 06'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'pm PM'],\n            ['[the] DDDo [day of the year]',       'the 45. day of the year'],\n            ['LTS',                                '15:25:50'],\n            ['L',                                  '14.02.2010.'],\n            ['LL',                                 '2010. gada 14. februāris'],\n            ['LLL',                                '2010. gada 14. februāris, 15:25'],\n            ['LLLL',                               '2010. gada 14. februāris, svētdiena, 15:25'],\n            ['l',                                  '14.2.2010.'],\n            ['ll',                                 '2010. gada 14. feb'],\n            ['lll',                                '2010. gada 14. feb, 15:25'],\n            ['llll',                               '2010. gada 14. feb, Sv, 15:25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1.', '1.');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2.', '2.');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3.', '3.');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4.', '4.');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5.', '5.');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6.', '6.');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7.', '7.');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8.', '8.');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9.', '9.');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10.', '10.');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11.', '11.');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12.', '12.');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13.', '13.');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14.', '14.');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15.', '15.');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16.', '16.');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17.', '17.');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18.', '18.');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19.', '19.');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20.', '20.');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21.', '21.');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22.', '22.');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23.', '23.');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24.', '24.');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25.', '25.');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26.', '26.');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27.', '27.');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28.', '28.');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29.', '29.');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30.', '30.');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31.', '31.');\n});\n\ntest('format month', function (assert) {\n    var expected = 'janvāris jan_februāris feb_marts mar_aprīlis apr_maijs mai_jūnijs jūn_jūlijs jūl_augusts aug_septembris sep_oktobris okt_novembris nov_decembris dec'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'svētdiena Sv Sv_pirmdiena P P_otrdiena O O_trešdiena T T_ceturtdiena C C_piektdiena Pk Pk_sestdiena S S'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\n// Includes testing the cases of withoutSuffix = true and false.\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),   'dažas sekundes',       '44 seconds = seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), false),  'pirms dažām sekundēm', '44 seconds with suffix = seconds ago');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),   'minūte',               '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), false),  'pirms minūtes',        '45 seconds with suffix = a minute ago');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),   'minūte',               '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: -89}), false), 'pēc minūtes',          '89 seconds with suffix/prefix = in a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),   '2 minūtes',            '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), false),  'pirms 2 minūtēm',      '90 seconds with suffix = 2 minutes ago');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),   '44 minūtes',           '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), false),  'pirms 44 minūtēm',     '44 minutes with suffix = 44 minutes ago');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),   'stunda',               '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), false),  'pirms stundas',        '45 minutes with suffix = an hour ago');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),   'stunda',               '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),   '2 stundas',            '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: -90}), false), 'pēc 2 stundām',        '90 minutes with suffix = in 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),    '5 stundas',            '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), false),   'pirms 5 stundām',      '5 hours with suffix = 5 hours ago');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),   '21 stunda',            '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), false),  'pirms 21 stundas',     '21 hours with suffix = 21 hours ago');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),   'diena',                '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), false),  'pirms dienas',         '22 hours with suffix = a day ago');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),   'diena',                '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),   '2 dienas',             '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), false),  'pirms 2 dienām',       '36 hours with suffix = 2 days ago');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),    'diena',                '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),    '5 dienas',             '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), false),   'pirms 5 dienām',       '5 days with suffix = 5 days ago');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),   '25 dienas',            '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), false),  'pirms 25 dienām',      '25 days with suffix = 25 days ago');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),   'mēnesis',              '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), false),  'pirms mēneša',         '26 days with suffix = a month ago');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),   'mēnesis',              '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),   'mēnesis',              '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),   '2 mēneši',             '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), false),  'pirms 2 mēnešiem',     '46 days with suffix = 2 months ago');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),   '2 mēneši',             '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),   '3 mēneši',             '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), false),  'pirms 3 mēnešiem',     '76 days with suffix = 3 months ago');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),    'mēnesis',              '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),    '5 mēneši',             '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), false),   'pirms 5 mēnešiem',     '5 months with suffix = 5 months ago');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true),  'gads',                 '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), false), 'pirms gada',           '345 days with suffix = a year ago');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true),  '2 gadi',               '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), false), 'pirms 2 gadiem',       '548 days with suffix = 2 years ago');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),    'gads',                 '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),    '5 gadi',               '5 years = 5 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), false),   'pirms 5 gadiem',       '5 years with suffix = 5 years ago');\n\n    // test that numbers ending with 1 are singular except for when they end with 11 in which case they are plural\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 11}), true),   '11 gadi',              '11 years = 11 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 21}), true),   '21 gads',              '21 year = 21 year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 211}), true),  '211 gadi',             '211 years = 211 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 221}), false), 'pirms 221 gada',       '221 year with suffix = 221 years ago');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'pēc dažām sekundēm',  'prefix');\n    assert.equal(moment(0).from(30000), 'pirms dažām sekundēm', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'pirms dažām sekundēm',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'pēc dažām sekundēm', 'in seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), 'pēc 5 dienām', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'Šodien pulksten 12:00',  'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'Šodien pulksten 12:25',  'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'Šodien pulksten 13:00',  'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'Rīt pulksten 12:00',     'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'Šodien pulksten 11:00',  'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'Vakar pulksten 12:00',   'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('dddd [pulksten] LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd [pulksten] LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd [pulksten] LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('[Pagājušā] dddd [pulksten] LT'),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[Pagājušā] dddd [pulksten] LT'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[Pagājušā] dddd [pulksten] LT'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2012, 0,  1]).format('w ww wo'), '52 52 52.', 'Jan  1 2012 should be week 52');\n    assert.equal(moment([2012, 0,  2]).format('w ww wo'),  '1 01 1.', 'Jan  2 2012 should be week 1');\n    assert.equal(moment([2012, 0,  8]).format('w ww wo'),  '1 01 1.', 'Jan  8 2012 should be week 1');\n    assert.equal(moment([2012, 0,  9]).format('w ww wo'),  '2 02 2.', 'Jan  9 2012 should be week 2');\n    assert.equal(moment([2012, 0, 15]).format('w ww wo'),  '2 02 2.', 'Jan 15 2012 should be week 2');\n});\n\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/test/locale/me.js",
    "content": "import {localeModule, test} from '../qunit';\nimport moment from '../../moment';\nlocaleModule('me');\n\ntest('parse', function (assert) {\n    var tests = 'januar jan._februar feb._mart mar._april apr._maj maj_jun jun_jul jul_avgust avg._septembar sep._oktobar okt._novembar nov._decembar dec.'.split('_'),\n        i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, Do MMMM YYYY, h:mm:ss a',      'nedjelja, 14. februar 2010, 3:25:50 pm'],\n            ['ddd, hA',                            'ned., 3PM'],\n            ['M Mo MM MMMM MMM',                   '2 2. 02 februar feb.'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14. 14'],\n            ['d do dddd ddd dd',                   '0 0. nedjelja ned. ne'],\n            ['DDD DDDo DDDD',                      '45 45. 045'],\n            ['w wo ww',                            '7 7. 07'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'pm PM'],\n            ['[the] DDDo [day of the year]',       'the 45. day of the year'],\n            ['LTS',                                '15:25:50'],\n            ['L',                                  '14.02.2010'],\n            ['LL',                                 '14. februar 2010'],\n            ['LLL',                                '14. februar 2010 15:25'],\n            ['LLLL',                               'nedjelja, 14. februar 2010 15:25'],\n            ['l',                                  '14.2.2010'],\n            ['ll',                                 '14. feb. 2010'],\n            ['lll',                                '14. feb. 2010 15:25'],\n            ['llll',                               'ned., 14. feb. 2010 15:25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1.', '1.');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2.', '2.');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3.', '3.');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4.', '4.');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5.', '5.');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6.', '6.');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7.', '7.');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8.', '8.');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9.', '9.');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10.', '10.');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11.', '11.');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12.', '12.');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13.', '13.');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14.', '14.');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15.', '15.');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16.', '16.');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17.', '17.');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18.', '18.');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19.', '19.');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20.', '20.');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21.', '21.');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22.', '22.');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23.', '23.');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24.', '24.');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25.', '25.');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26.', '26.');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27.', '27.');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28.', '28.');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29.', '29.');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30.', '30.');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31.', '31.');\n});\n\ntest('format month', function (assert) {\n    var expected = 'januar jan._februar feb._mart mar._april apr._maj maj_jun jun_jul jul_avgust avg._septembar sep._oktobar okt._novembar nov._decembar dec.'.split('_'),\n        i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'nedjelja ned. ne_ponedjeljak pon. po_utorak uto. ut_srijeda sri. sr_četvrtak čet. če_petak pet. pe_subota sub. su'.split('_'),\n        i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'nekoliko sekundi', '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'jedan minut',   '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'jedan minut',   '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 minuta',     '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 minuta',     '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'jedan sat',      '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'jedan sat',      '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 sata',        '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 sati',         '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 sati',        '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'dan',       '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'dan',       '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 dana',        '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'dan',       '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 dana',        '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 dana',       '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'mjesec',     '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'mjesec',     '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'mjesec',     '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 mjeseca',     '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 mjeseca',     '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 mjeseca',     '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'mjesec',     '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 mjeseci',    '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'godinu',     '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 godine',       '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'godinu',     '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 godina',        '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'za nekoliko sekundi',  'prefix');\n    assert.equal(moment(0).from(30000), 'prije nekoliko sekundi', 'prefix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'prije nekoliko sekundi',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'za nekoliko sekundi', 'in a few seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), 'za 5 dana', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'danas u 12:00',  'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'danas u 12:25',  'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'danas u 13:00',  'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'sjutra u 12:00', 'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'danas u 11:00',  'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'juče u 12:00',   'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n\n    function makeFormat(d) {\n        switch (d.day()) {\n            case 0:\n                return '[u] [nedjelju] [u] LT';\n            case 3:\n                return '[u] [srijedu] [u] LT';\n            case 6:\n                return '[u] [subotu] [u] LT';\n            case 1:\n            case 2:\n            case 4:\n            case 5:\n                return '[u] dddd [u] LT';\n        }\n    }\n\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format(makeFormat(m)),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format(makeFormat(m)),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format(makeFormat(m)),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n\n    function makeFormat(d) {\n        var lastWeekDay = [\n                '[prošle] [nedjelje] [u] LT',\n                '[prošlog] [ponedjeljka] [u] LT',\n                '[prošlog] [utorka] [u] LT',\n                '[prošle] [srijede] [u] LT',\n                '[prošlog] [četvrtka] [u] LT',\n                '[prošlog] [petka] [u] LT',\n                '[prošle] [subote] [u] LT'\n            ];\n\n        return lastWeekDay[d.day()];\n    }\n\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format(makeFormat(m)),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format(makeFormat(m)),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format(makeFormat(m)),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\n// Monday is the first day of the week.\n// The week that contains Jan 1st is the first week of the year.\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2011, 11, 26]).format('w ww wo'), '1 01 1.', 'Dec 26 2011 should be week 1');\n    assert.equal(moment([2012,  0,  1]).format('w ww wo'), '1 01 1.', 'Jan  1 2012 should be week 1');\n    assert.equal(moment([2012,  0,  2]).format('w ww wo'), '2 02 2.', 'Jan  2 2012 should be week 2');\n    assert.equal(moment([2012,  0,  8]).format('w ww wo'), '2 02 2.', 'Jan  8 2012 should be week 2');\n    assert.equal(moment([2012,  0,  9]).format('w ww wo'), '3 03 3.', 'Jan  9 2012 should be week 3');\n});\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/test/locale/mi.js",
    "content": "import {localeModule, test} from '../qunit';\nimport moment from '../../moment';\nlocaleModule('mi');\n\ntest('parse', function (assert) {\n    var tests = 'Kohi-tāte Kohi_Hui-tanguru Hui_Poutū-te-rangi Pou_Paenga-whāwhā Pae_Haratua Hara_Pipiri Pipi_Hōngoingoi Hōngoi_Here-turi-kōkā Here_Mahuru Mahu_Whiringa-ā-nuku Whi-nu_Whiringa-ā-rangi Whi-ra_Hakihea Haki'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, MMMM Do YYYY, h:mm:ss a',      'Rātapu, Hui-tanguru 14º 2010, 3:25:50 pm'],\n            ['ddd, hA',                            'Ta, 3PM'],\n            ['M Mo MM MMMM MMM',                   '2 2º 02 Hui-tanguru Hui'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14º 14'],\n            ['d do dddd ddd dd',                   '0 0º Rātapu Ta Ta'],\n            ['DDD DDDo DDDD',                      '45 45º 045'],\n            ['w wo ww',                            '6 6º 06'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'pm PM'],\n            ['[the] DDDo [day of the year]',       'the 45º day of the year'],\n            ['LTS',                                '15:25:50'],\n            ['L',                                  '14/02/2010'],\n            ['LL',                                 '14 Hui-tanguru 2010'],\n            ['LLL',                                '14 Hui-tanguru 2010 i 15:25'],\n            ['LLLL',                               'Rātapu, 14 Hui-tanguru 2010 i 15:25'],\n            ['l',                                  '14/2/2010'],\n            ['ll',                                 '14 Hui 2010'],\n            ['lll',                                '14 Hui 2010 i 15:25'],\n            ['llll',                               'Ta, 14 Hui 2010 i 15:25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1º', '1º');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2º', '2º');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3º', '3º');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4º', '4º');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5º', '5º');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6º', '6º');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7º', '7º');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8º', '8º');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9º', '9º');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10º', '10º');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11º', '11º');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12º', '12º');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13º', '13º');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14º', '14º');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15º', '15º');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16º', '16º');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17º', '17º');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18º', '18º');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19º', '19º');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20º', '20º');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21º', '21º');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22º', '22º');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23º', '23º');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24º', '24º');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25º', '25º');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26º', '26º');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27º', '27º');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28º', '28º');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29º', '29º');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30º', '30º');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31º', '31º');\n});\n\ntest('format month', function (assert) {\n    var expected = 'Kohi-tāte Kohi_Hui-tanguru Hui_Poutū-te-rangi Pou_Paenga-whāwhā Pae_Haratua Hara_Pipiri Pipi_Hōngoingoi Hōngoi_Here-turi-kōkā Here_Mahuru Mahu_Whiringa-ā-nuku Whi-nu_Whiringa-ā-rangi Whi-ra_Hakihea Haki'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'Rātapu Ta Ta_Mane Ma Ma_Tūrei Tū Tū_Wenerei We We_Tāite Tāi Tāi_Paraire Pa Pa_Hātarei Hā Hā'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'te hēkona ruarua', '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'he meneti',        '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'he meneti',        '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 meneti',         '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 meneti',        '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'te haora',         '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'te haora',         '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 haora',          '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 haora',          '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 haora',         '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'he ra',            '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'he ra',            '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 ra',             '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'he ra',            '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 ra',             '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 ra',            '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'he marama',        '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'he marama',        '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'he marama',        '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 marama',         '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 marama',         '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 marama',         '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'he marama',         '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 marama',         '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'he tau',           '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 tau',            '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'he tau',           '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 tau',            '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'i roto i te hēkona ruarua',  'prefix');\n    assert.equal(moment(0).from(30000), 'te hēkona ruarua i mua', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'te hēkona ruarua i mua',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'i roto i te hēkona ruarua', 'in a few seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), 'i roto i 5 ra', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'i teie mahana, i 12:00', 'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'i teie mahana, i 12:25', 'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'i teie mahana, i 13:00', 'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'apopo i 12:00',       'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'i teie mahana, i 11:00', 'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'inanahi i 12:00',     'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('dddd [i] LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd [i] LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd [i] LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('dddd [whakamutunga i] LT'), 'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd [whakamutunga i] LT'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd [whakamutunga i] LT'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2012, 0,  1]).format('w ww wo'), '52 52 52º', 'Jan  1 2012 should be week 52');\n    assert.equal(moment([2012, 0,  2]).format('w ww wo'),   '1 01 1º', 'Jan  2 2012 should be week 1');\n    assert.equal(moment([2012, 0,  8]).format('w ww wo'),   '1 01 1º', 'Jan  8 2012 should be week 1');\n    assert.equal(moment([2012, 0,  9]).format('w ww wo'),   '2 02 2º', 'Jan  9 2012 should be week 2');\n    assert.equal(moment([2012, 0, 15]).format('w ww wo'),   '2 02 2º', 'Jan 15 2012 should be week 2');\n});\n\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/test/locale/mk.js",
    "content": "import {localeModule, test} from '../qunit';\nimport moment from '../../moment';\nlocaleModule('mk');\n\ntest('parse', function (assert) {\n    var tests = 'јануари јан_февруари фев_март мар_април апр_мај мај_јуни јун_јули јул_август авг_септември сеп_октомври окт_ноември ное_декември дек'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, MMMM Do YYYY, H:mm:ss',        'недела, февруари 14-ти 2010, 15:25:50'],\n            ['ddd, hA',                            'нед, 3PM'],\n            ['M Mo MM MMMM MMM',                   '2 2-ри 02 февруари фев'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14-ти 14'],\n            ['d do dddd ddd dd',                   '0 0-ев недела нед нe'],\n            ['DDD DDDo DDDD',                      '45 45-ти 045'],\n            ['w wo ww',                            '7 7-ми 07'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'pm PM'],\n            ['[the] DDDo [day of the year]',       'the 45-ти day of the year'],\n            ['LTS',                                '15:25:50'],\n            ['L',                                  '14.02.2010'],\n            ['LL',                                 '14 февруари 2010'],\n            ['LLL',                                '14 февруари 2010 15:25'],\n            ['LLLL',                               'недела, 14 февруари 2010 15:25'],\n            ['l',                                  '14.2.2010'],\n            ['ll',                                 '14 фев 2010'],\n            ['lll',                                '14 фев 2010 15:25'],\n            ['llll',                               'нед, 14 фев 2010 15:25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1-ви', '1-ви');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2-ри', '2-ри');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3-ти', '3-ти');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4-ти', '4-ти');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5-ти', '5-ти');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6-ти', '6-ти');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7-ми', '7-ми');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8-ми', '8-ми');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9-ти', '9-ти');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10-ти', '10-ти');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11-ти', '11-ти');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12-ти', '12-ти');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13-ти', '13-ти');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14-ти', '14-ти');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15-ти', '15-ти');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16-ти', '16-ти');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17-ти', '17-ти');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18-ти', '18-ти');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19-ти', '19-ти');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20-ти', '20-ти');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21-ви', '21-ви');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22-ри', '22-ри');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23-ти', '23-ти');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24-ти', '24-ти');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25-ти', '25-ти');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26-ти', '26-ти');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27-ми', '27-ми');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28-ми', '28-ми');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29-ти', '29-ти');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30-ти', '30-ти');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31-ви', '31-ви');\n});\n\ntest('format month', function (assert) {\n    var expected = 'јануари јан_февруари фев_март мар_април апр_мај мај_јуни јун_јули јул_август авг_септември сеп_октомври окт_ноември ное_декември дек'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'недела нед нe_понеделник пон пo_вторник вто вт_среда сре ср_четврток чет че_петок пет пе_сабота саб сa'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'неколку секунди', '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'минута',          '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'минута',          '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 минути',        '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 минути',       '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'час',             '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'час',             '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 часа',          '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 часа',          '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 часа',         '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'ден',             '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'ден',             '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 дена',          '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'ден',             '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 дена',          '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 дена',         '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'месец',           '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'месец',           '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'месец',           '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 месеци',        '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 месеци',        '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 месеци',        '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'месец',           '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 месеци',        '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'година',          '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 години',        '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'година',          '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 години',        '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'после неколку секунди', 'prefix');\n    assert.equal(moment(0).from(30000), 'пред неколку секунди',  'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'пред неколку секунди',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'после неколку секунди', 'in a few seconds');\n    assert.equal(moment().add({d: 5}).fromNow(),  'после 5 дена', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'Денес во 12:00',  'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'Денес во 12:25',  'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'Денес во 13:00',  'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'Утре во 12:00',   'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'Денес во 11:00',  'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'Вчера во 12:00',  'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('[Во] dddd [во] LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[Во] dddd [во] LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[Во] dddd [во] LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n\n    function makeFormat(d) {\n        switch (d.day()) {\n            case 0:\n            case 3:\n            case 6:\n                return '[Изминатата] dddd [во] LT';\n            case 1:\n            case 2:\n            case 4:\n            case 5:\n                return '[Изминатиот] dddd [во] LT';\n        }\n    }\n\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format(makeFormat(m)),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format(makeFormat(m)),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format(makeFormat(m)),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2011, 11, 26]).format('w ww wo'), '1 01 1-ви', 'Dec 26 2011 should be week 1');\n    assert.equal(moment([2012,  0,  1]).format('w ww wo'), '1 01 1-ви', 'Jan  1 2012 should be week 1');\n    assert.equal(moment([2012,  0,  2]).format('w ww wo'), '2 02 2-ри', 'Jan  2 2012 should be week 2');\n    assert.equal(moment([2012,  0,  8]).format('w ww wo'), '2 02 2-ри', 'Jan  8 2012 should be week 2');\n    assert.equal(moment([2012,  0,  9]).format('w ww wo'), '3 03 3-ти', 'Jan  9 2012 should be week 3');\n});\n\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/test/locale/ml.js",
    "content": "import {localeModule, test} from '../qunit';\nimport moment from '../../moment';\nlocaleModule('ml');\n\ntest('parse', function (assert) {\n    var tests = 'ജനുവരി ജനു._ഫെബ്രുവരി ഫെബ്രു._മാർച്ച് മാർ._ഏപ്രിൽ ഏപ്രി._മേയ് മേയ്_ജൂൺ ജൂൺ_ജൂലൈ ജൂലൈ._ഓഗസ്റ്റ് ഓഗ._സെപ്റ്റംബർ സെപ്റ്റ._ഒക്ടോബർ ഒക്ടോ._നവംബർ നവം._ഡിസംബർ ഡിസം.'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, Do MMMM YYYY, a h:mm:ss -നു',  'ഞായറാഴ്ച, 14 ഫെബ്രുവരി 2010, ഉച്ച കഴിഞ്ഞ് 3:25:50 -നു'],\n            ['ddd, a h -നു',                       'ഞായർ, ഉച്ച കഴിഞ്ഞ് 3 -നു'],\n            ['M Mo MM MMMM MMM',                   '2 2 02 ഫെബ്രുവരി ഫെബ്രു.'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14 14'],\n            ['d do dddd ddd dd',                   '0 0 ഞായറാഴ്ച ഞായർ ഞാ'],\n            ['DDD DDDo DDDD',                      '45 45 045'],\n            ['w wo ww',                            '8 8 08'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'ഉച്ച കഴിഞ്ഞ് ഉച്ച കഴിഞ്ഞ്'],\n            ['LTS',                                'ഉച്ച കഴിഞ്ഞ് 3:25:50 -നു'],\n            ['L',                                  '14/02/2010'],\n            ['LL',                                 '14 ഫെബ്രുവരി 2010'],\n            ['LLL',                                '14 ഫെബ്രുവരി 2010, ഉച്ച കഴിഞ്ഞ് 3:25 -നു'],\n            ['LLLL',                               'ഞായറാഴ്ച, 14 ഫെബ്രുവരി 2010, ഉച്ച കഴിഞ്ഞ് 3:25 -നു'],\n            ['l',                                  '14/2/2010'],\n            ['ll',                                 '14 ഫെബ്രു. 2010'],\n            ['lll',                                '14 ഫെബ്രു. 2010, ഉച്ച കഴിഞ്ഞ് 3:25 -നു'],\n            ['llll',                               'ഞായർ, 14 ഫെബ്രു. 2010, ഉച്ച കഴിഞ്ഞ് 3:25 -നു']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1', '1');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2', '2');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3', '3');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4', '4');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5', '5');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6', '6');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7', '7');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8', '8');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9', '9');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10', '10');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11', '11');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12', '12');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13', '13');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14', '14');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15', '15');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16', '16');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17', '17');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18', '18');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19', '19');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20', '20');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21', '21');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22', '22');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23', '23');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24', '24');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25', '25');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26', '26');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27', '27');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28', '28');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29', '29');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30', '30');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31', '31');\n});\n\ntest('format month', function (assert) {\n    var expected = 'ജനുവരി ജനു._ഫെബ്രുവരി ഫെബ്രു._മാർച്ച് മാർ._ഏപ്രിൽ ഏപ്രി._മേയ് മേയ്_ജൂൺ ജൂൺ_ജൂലൈ ജൂലൈ._ഓഗസ്റ്റ് ഓഗ._സെപ്റ്റംബർ സെപ്റ്റ._ഒക്ടോബർ ഒക്ടോ._നവംബർ നവം._ഡിസംബർ ഡിസം.'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'ഞായറാഴ്ച ഞായർ ഞാ_തിങ്കളാഴ്ച തിങ്കൾ തി_ചൊവ്വാഴ്ച ചൊവ്വ ചൊ_ബുധനാഴ്ച ബുധൻ ബു_വ്യാഴാഴ്ച വ്യാഴം വ്യാ_വെള്ളിയാഴ്ച വെള്ളി വെ_ശനിയാഴ്ച ശനി ശ'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'അൽപ നിമിഷങ്ങൾ', '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'ഒരു മിനിറ്റ്',      '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'ഒരു മിനിറ്റ്',      '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 മിനിറ്റ്',     '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 മിനിറ്റ്',    '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'ഒരു മണിക്കൂർ',       '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'ഒരു മണിക്കൂർ',       '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 മണിക്കൂർ',       '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 മണിക്കൂർ',       '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 മണിക്കൂർ',      '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'ഒരു ദിവസം',         '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'ഒരു ദിവസം',         '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 ദിവസം',        '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'ഒരു ദിവസം',         '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 ദിവസം',        '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 ദിവസം',       '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'ഒരു മാസം',       '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'ഒരു മാസം',       '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'ഒരു മാസം',       '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 മാസം',      '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 മാസം',      '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 മാസം',      '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'ഒരു മാസം',       '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 മാസം',      '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'ഒരു വർഷം',        '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 വർഷം',       '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'ഒരു വർഷം',        '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 വർഷം',       '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'അൽപ നിമിഷങ്ങൾ കഴിഞ്ഞ്',  'prefix');\n    assert.equal(moment(0).from(30000), 'അൽപ നിമിഷങ്ങൾ മുൻപ്', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'അൽപ നിമിഷങ്ങൾ മുൻപ്',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'അൽപ നിമിഷങ്ങൾ കഴിഞ്ഞ്', 'അൽപ നിമിഷങ്ങൾ കഴിഞ്ഞ്');\n    assert.equal(moment().add({d: 5}).fromNow(), '5 ദിവസം കഴിഞ്ഞ്', '5 ദിവസം കഴിഞ്ഞ്');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'ഇന്ന് ഉച്ച കഴിഞ്ഞ് 12:00 -നു',   'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'ഇന്ന് ഉച്ച കഴിഞ്ഞ് 12:25 -നു',   'Now plus 25 min');\n    assert.equal(moment(a).add({h: 3}).calendar(),       'ഇന്ന് ഉച്ച കഴിഞ്ഞ് 3:00 -നു',    'Now plus 3 hours');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'നാളെ ഉച്ച കഴിഞ്ഞ് 12:00 -നു',    'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'ഇന്ന് രാവിലെ 11:00 -നു',         'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'ഇന്നലെ ഉച്ച കഴിഞ്ഞ് 12:00 -നു',  'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('dddd[,] LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd[,] LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd[,] LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('[കഴിഞ്ഞ] dddd[,] LT'),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[കഴിഞ്ഞ] dddd[,] LT'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[കഴിഞ്ഞ] dddd[,] LT'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('meridiem', function (assert) {\n    assert.equal(moment([2011, 2, 23,  2, 30]).format('a'), 'രാത്രി', 'before dawn');\n    assert.equal(moment([2011, 2, 23,  9, 30]).format('a'), 'രാവിലെ', 'morning');\n    assert.equal(moment([2011, 2, 23, 14, 30]).format('a'), 'ഉച്ച കഴിഞ്ഞ്', 'during day');\n    assert.equal(moment([2011, 2, 23, 17, 30]).format('a'), 'വൈകുന്നേരം', 'evening');\n    assert.equal(moment([2011, 2, 23, 19, 30]).format('a'), 'വൈകുന്നേരം', 'late evening');\n    assert.equal(moment([2011, 2, 23, 21, 20]).format('a'), 'രാത്രി', 'night');\n\n    assert.equal(moment([2011, 2, 23,  2, 30]).format('A'), 'രാത്രി', 'before dawn');\n    assert.equal(moment([2011, 2, 23,  9, 30]).format('A'), 'രാവിലെ', 'morning');\n    assert.equal(moment([2011, 2, 23, 14, 30]).format('A'), 'ഉച്ച കഴിഞ്ഞ്', ' during day');\n    assert.equal(moment([2011, 2, 23, 17, 30]).format('A'), 'വൈകുന്നേരം', 'evening');\n    assert.equal(moment([2011, 2, 23, 19, 30]).format('A'), 'വൈകുന്നേരം', 'late evening');\n    assert.equal(moment([2011, 2, 23, 21, 20]).format('A'), 'രാത്രി', 'night');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2012, 0,  1]).format('w ww wo'), '1 01 1', 'Jan  1 2012 should be week 1');\n    assert.equal(moment([2012, 0,  7]).format('w ww wo'), '1 01 1', 'Jan  7 2012 should be week 1');\n    assert.equal(moment([2012, 0,  8]).format('w ww wo'), '2 02 2', 'Jan  8 2012 should be week 2');\n    assert.equal(moment([2012, 0, 14]).format('w ww wo'), '2 02 2', 'Jan 14 2012 should be week 2');\n    assert.equal(moment([2012, 0, 15]).format('w ww wo'), '3 03 3', 'Jan 15 2012 should be week 3');\n});\n\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/test/locale/mr.js",
    "content": "import {localeModule, test} from '../qunit';\nimport moment from '../../moment';\nlocaleModule('mr');\n\ntest('parse', function (assert) {\n    var tests = 'जानेवारी जाने._फेब्रुवारी फेब्रु._मार्च मार्च._एप्रिल एप्रि._मे मे._जून जून._जुलै जुलै._ऑगस्ट ऑग._सप्टेंबर सप्टें._ऑक्टोबर ऑक्टो._नोव्हेंबर नोव्हें._डिसेंबर डिसें.'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, Do MMMM YYYY, a h:mm:ss वाजता', 'रविवार, १४ फेब्रुवारी २०१०, दुपारी ३:२५:५० वाजता'],\n            ['ddd, a h वाजता',                       'रवि, दुपारी ३ वाजता'],\n            ['M Mo MM MMMM MMM',                   '२ २ ०२ फेब्रुवारी फेब्रु.'],\n            ['YYYY YY',                            '२०१० १०'],\n            ['D Do DD',                            '१४ १४ १४'],\n            ['d do dddd ddd dd',                   '० ० रविवार रवि र'],\n            ['DDD DDDo DDDD',                      '४५ ४५ ०४५'],\n            ['w wo ww',                            '८ ८ ०८'],\n            ['h hh',                               '३ ०३'],\n            ['H HH',                               '१५ १५'],\n            ['m mm',                               '२५ २५'],\n            ['s ss',                               '५० ५०'],\n            ['a A',                                'दुपारी दुपारी'],\n            ['LTS',                                'दुपारी ३:२५:५० वाजता'],\n            ['L',                                  '१४/०२/२०१०'],\n            ['LL',                                 '१४ फेब्रुवारी २०१०'],\n            ['LLL',                                '१४ फेब्रुवारी २०१०, दुपारी ३:२५ वाजता'],\n            ['LLLL',                               'रविवार, १४ फेब्रुवारी २०१०, दुपारी ३:२५ वाजता'],\n            ['l',                                  '१४/२/२०१०'],\n            ['ll',                                 '१४ फेब्रु. २०१०'],\n            ['lll',                                '१४ फेब्रु. २०१०, दुपारी ३:२५ वाजता'],\n            ['llll',                               'रवि, १४ फेब्रु. २०१०, दुपारी ३:२५ वाजता']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '१', '१');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '२', '२');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '३', '३');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '४', '४');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '५', '५');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '६', '६');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '७', '७');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '८', '८');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '९', '९');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '१०', '१०');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '११', '११');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '१२', '१२');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '१३', '१३');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '१४', '१४');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '१५', '१५');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '१६', '१६');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '१७', '१७');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '१८', '१८');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '१९', '१९');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '२०', '२०');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '२१', '२१');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '२२', '२२');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '२३', '२३');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '२४', '२४');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '२५', '२५');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '२६', '२६');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '२७', '२७');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '२८', '२८');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '२९', '२९');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '३०', '३०');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '३१', '३१');\n});\n\ntest('format month', function (assert) {\n    var expected = 'जानेवारी जाने._फेब्रुवारी फेब्रु._मार्च मार्च._एप्रिल एप्रि._मे मे._जून जून._जुलै जुलै._ऑगस्ट ऑग._सप्टेंबर सप्टें._ऑक्टोबर ऑक्टो._नोव्हेंबर नोव्हें._डिसेंबर डिसें.'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'रविवार रवि र_सोमवार सोम सो_मंगळवार मंगळ मं_बुधवार बुध बु_गुरूवार गुरू गु_शुक्रवार शुक्र शु_शनिवार शनि श'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'काही सेकंद', '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'एक मिनिट',      '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'एक मिनिट',      '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '२ मिनिटे',     '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true), '४४ मिनिटे', '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'एक तास',       '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'एक तास',       '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '२ तास',       '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '५ तास',       '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '२१ तास',      '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'एक दिवस',         '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'एक दिवस',         '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '२ दिवस',        '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'एक दिवस',         '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '५ दिवस',        '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '२५ दिवस',       '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true), 'एक महिना', '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true), 'एक महिना', '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true), 'एक महिना', '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true), '२ महिने', '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true), '२ महिने', '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true), '३ महिने', '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true), 'एक महिना', '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true), '५ महिने', '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'एक वर्ष',        '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '२ वर्षे',       '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'एक वर्ष',        '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true), '५ वर्षे', '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'काही सेकंदांमध्ये', 'prefix');\n    assert.equal(moment(0).from(30000), 'काही सेकंदांपूर्वी', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'काही सेकंदांपूर्वी',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'काही सेकंदांमध्ये', 'in a few seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), '५ दिवसांमध्ये', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'आज दुपारी १२:०० वाजता',    'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'आज दुपारी १२:२५ वाजता',    'Now plus 25 min');\n    assert.equal(moment(a).add({h: 3}).calendar(),       'आज दुपारी ३:०० वाजता',     'Now plus 3 hours');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'उद्या दुपारी १२:०० वाजता', 'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'आज दुपारी ११:०० वाजता',    'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'काल दुपारी १२:०० वाजता',   'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('dddd[,] LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd[,] LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd[,] LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(), m.format('[मागील] dddd[,] LT'), 'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(), m.format('[मागील] dddd[,] LT'), 'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(), m.format('[मागील] dddd[,] LT'), 'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('meridiem', function (assert) {\n    assert.equal(moment([2011, 2, 23,  2, 30]).format('a'), 'रात्री', 'before dawn');\n    assert.equal(moment([2011, 2, 23,  9, 30]).format('a'), 'सकाळी', 'morning');\n    assert.equal(moment([2011, 2, 23, 14, 30]).format('a'), 'दुपारी', 'during day');\n    assert.equal(moment([2011, 2, 23, 17, 30]).format('a'), 'सायंकाळी', 'evening');\n    assert.equal(moment([2011, 2, 23, 19, 30]).format('a'), 'सायंकाळी', 'late evening');\n    assert.equal(moment([2011, 2, 23, 21, 20]).format('a'), 'रात्री', 'night');\n\n    assert.equal(moment([2011, 2, 23,  2, 30]).format('A'), 'रात्री', 'before dawn');\n    assert.equal(moment([2011, 2, 23,  9, 30]).format('A'), 'सकाळी', 'morning');\n    assert.equal(moment([2011, 2, 23, 14, 30]).format('A'), 'दुपारी', ' during day');\n    assert.equal(moment([2011, 2, 23, 17, 30]).format('A'), 'सायंकाळी', 'evening');\n    assert.equal(moment([2011, 2, 23, 19, 30]).format('A'), 'सायंकाळी', 'late evening');\n    assert.equal(moment([2011, 2, 23, 21, 20]).format('A'), 'रात्री', 'night');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2012, 0,  1]).format('w ww wo'), '१ ०१ १', 'Jan  1 2012 should be week 1');\n    assert.equal(moment([2012, 0,  7]).format('w ww wo'), '१ ०१ १', 'Jan  7 2012 should be week 1');\n    assert.equal(moment([2012, 0,  8]).format('w ww wo'), '२ ०२ २', 'Jan  8 2012 should be week 2');\n    assert.equal(moment([2012, 0, 14]).format('w ww wo'), '२ ०२ २', 'Jan 14 2012 should be week 2');\n    assert.equal(moment([2012, 0, 15]).format('w ww wo'), '३ ०३ ३', 'Jan 15 2012 should be week 3');\n});\n\n\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/test/locale/ms-my.js",
    "content": "import {localeModule, test} from '../qunit';\nimport moment from '../../moment';\nlocaleModule('ms-my');\n\ntest('parse', function (assert) {\n    var i,\n        tests = 'Januari Jan_Februari Feb_Mac Mac_April Apr_Mei Mei_Jun Jun_Julai Jul_Ogos Ogs_September Sep_Oktober Okt_November Nov_Disember Dis'.split('_');\n\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' sepatutnya bulan ' + (i + 1));\n    }\n\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, MMMM Do YYYY, h:mm:ss a',      'Ahad, Februari 14 2010, 3:25:50 petang'],\n            ['ddd, hA',                            'Ahd, 3petang'],\n            ['M Mo MM MMMM MMM',                   '2 2 02 Februari Feb'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14 14'],\n            ['d do dddd ddd dd',                   '0 0 Ahad Ahd Ah'],\n            ['DDD DDDo DDDD',                      '45 45 045'],\n            ['w wo ww',                            '7 7 07'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'petang petang'],\n            ['[hari] [ke] DDDo [tahun] ini', 'hari ke 45 tahun ini'],\n            ['LTS',                                '15.25.50'],\n            ['L',                                  '14/02/2010'],\n            ['LL',                                 '14 Februari 2010'],\n            ['LLL',                                '14 Februari 2010 pukul 15.25'],\n            ['LLLL',                               'Ahad, 14 Februari 2010 pukul 15.25'],\n            ['l',                                  '14/2/2010'],\n            ['ll',                                 '14 Feb 2010'],\n            ['lll',                                '14 Feb 2010 pukul 15.25'],\n            ['llll',                               'Ahd, 14 Feb 2010 pukul 15.25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1', '1');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2', '2');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3', '3');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4', '4');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5', '5');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6', '6');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7', '7');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8', '8');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9', '9');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10', '10');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11', '11');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12', '12');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13', '13');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14', '14');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15', '15');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16', '16');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17', '17');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18', '18');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19', '19');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20', '20');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21', '21');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22', '22');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23', '23');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24', '24');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25', '25');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26', '26');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27', '27');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28', '28');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29', '29');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30', '30');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31', '31');\n});\n\ntest('format month', function (assert) {\n    var i,\n        expected = 'Januari Jan_Februari Feb_Mac Mac_April Apr_Mei Mei_Jun Jun_Julai Jul_Ogos Ogs_September Sep_Oktober Okt_November Nov_Disember Dis'.split('_');\n\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var i,\n        expected = 'Ahad Ahd Ah_Isnin Isn Is_Selasa Sel Sl_Rabu Rab Rb_Khamis Kha Km_Jumaat Jum Jm_Sabtu Sab Sb'.split('_');\n\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'beberapa saat', '44 saat = beberapa saat');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'seminit',      '45 saat = seminit');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'seminit',      '89 saat = seminit');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 minit',     '90 saat = 2 minit');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 minit',    '44 minit = 44 minit');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'sejam',       '45 minit = sejam');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'sejam',       '89 minit = sejam');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 jam',       '90 minit = 2 jam');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 jam',       '5 jam = 5 jam');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 jam',      '21 jam = 21 jam');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'sehari',         '22 jam = sehari');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'sehari',         '35 jam = sehari');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 hari',        '36 jam = 2 hari');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'sehari',         '1 hari = sehari');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 hari',        '5 hari = 5 hari');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 hari',       '25 hari = 25 hari');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'sebulan',       '26 hari = sebulan');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'sebulan',       '30 hari = sebulan');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'sebulan',       '45 hari = sebulan');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 bulan',      '46 hari = 2 bulan');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 bulan',      '75 hari = 2 bulan');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 bulan',      '76 hari = 3 bulan');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'sebulan',       '1 bulan = sebulan');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 bulan',      '5 bulan = 5 bulan');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'setahun',        '345 hari = setahun');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 tahun',       '548 hari = 2 tahun');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'setahun',        '1 tahun = setahun');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 tahun',       '5 tahun = 5 tahun');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'dalam beberapa saat',  'prefix');\n    assert.equal(moment(0).from(30000), 'beberapa saat yang lepas', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'beberapa saat yang lepas',  'waktu sekarang dari sekarang sepatutnya menunjukkan sebagai telah lepas');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'dalam beberapa saat', 'dalam beberapa saat');\n    assert.equal(moment().add({d: 5}).fromNow(), 'dalam 5 hari', 'dalam 5 hari');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'Hari ini pukul 12.00',  'hari ini pada waktu yang sama');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'Hari ini pukul 12.25',  'Sekarang tambah 25 minit');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'Hari ini pukul 13.00',  'Sekarang tambah 1 jam');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'Esok pukul 12.00',      'esok pada waktu yang sama');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'Hari ini pukul 11.00',  'Sekarang tolak 1 jam');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'Kelmarin pukul 12.00',  'kelmarin pada waktu yang sama');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('dddd [pukul] LT'),  'Hari ini + ' + i + ' hari waktu sekarang');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd [pukul] LT'),  'Hari ini + ' + i + ' hari permulaan hari');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd [pukul] LT'),  'Hari ini + ' + i + ' hari tamat hari');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('dddd [lepas] [pukul] LT'),  'Hari ini - ' + i + ' hari waktu sekarang');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd [lepas] [pukul] LT'),  'Hari ini - ' + i + ' hari permulaan hari');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd [lepas] [pukul] LT'),  'Hari ini - ' + i + ' hari tamat hari');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 minggu lepas');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'dalam 1 minggu');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 minggu lepas');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'dalam 2 minggu');\n});\n\ntest('weeks year starting sunday format', function (assert) {\n    assert.equal(moment([2012, 0,  1]).format('w ww wo'), '1 01 1', 'Jan  1 2012 sepatutnya minggu 1');\n    assert.equal(moment([2012, 0,  7]).format('w ww wo'), '2 02 2', 'Jan  7 2012 sepatutnya minggu 2');\n    assert.equal(moment([2012, 0,  8]).format('w ww wo'), '2 02 2', 'Jan  8 2012 sepatutnya minggu 2');\n    assert.equal(moment([2012, 0, 14]).format('w ww wo'), '3 03 3', 'Jan 14 2012 sepatutnya minggu 3');\n    assert.equal(moment([2012, 0, 15]).format('w ww wo'), '3 03 3', 'Jan 15 2012 sepatutnya minggu 3');\n});\n\n\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/test/locale/ms.js",
    "content": "import {localeModule, test} from '../qunit';\nimport moment from '../../moment';\nlocaleModule('ms');\n\ntest('parse', function (assert) {\n    var i,\n        tests = 'Januari Jan_Februari Feb_Mac Mac_April Apr_Mei Mei_Jun Jun_Julai Jul_Ogos Ogs_September Sep_Oktober Okt_November Nov_Disember Dis'.split('_');\n\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' sepatutnya bulan ' + (i + 1));\n    }\n\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, MMMM Do YYYY, h:mm:ss a',      'Ahad, Februari 14 2010, 3:25:50 petang'],\n            ['ddd, hA',                            'Ahd, 3petang'],\n            ['M Mo MM MMMM MMM',                   '2 2 02 Februari Feb'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14 14'],\n            ['d do dddd ddd dd',                   '0 0 Ahad Ahd Ah'],\n            ['DDD DDDo DDDD',                      '45 45 045'],\n            ['w wo ww',                            '7 7 07'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'petang petang'],\n            ['[hari] [ke] DDDo [tahun] ini', 'hari ke 45 tahun ini'],\n            ['LTS',                                '15.25.50'],\n            ['L',                                  '14/02/2010'],\n            ['LL',                                 '14 Februari 2010'],\n            ['LLL',                                '14 Februari 2010 pukul 15.25'],\n            ['LLLL',                               'Ahad, 14 Februari 2010 pukul 15.25'],\n            ['l',                                  '14/2/2010'],\n            ['ll',                                 '14 Feb 2010'],\n            ['lll',                                '14 Feb 2010 pukul 15.25'],\n            ['llll',                               'Ahd, 14 Feb 2010 pukul 15.25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1', '1');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2', '2');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3', '3');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4', '4');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5', '5');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6', '6');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7', '7');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8', '8');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9', '9');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10', '10');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11', '11');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12', '12');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13', '13');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14', '14');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15', '15');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16', '16');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17', '17');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18', '18');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19', '19');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20', '20');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21', '21');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22', '22');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23', '23');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24', '24');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25', '25');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26', '26');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27', '27');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28', '28');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29', '29');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30', '30');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31', '31');\n});\n\ntest('format month', function (assert) {\n    var i,\n        expected = 'Januari Jan_Februari Feb_Mac Mac_April Apr_Mei Mei_Jun Jun_Julai Jul_Ogos Ogs_September Sep_Oktober Okt_November Nov_Disember Dis'.split('_');\n\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var i,\n        expected = 'Ahad Ahd Ah_Isnin Isn Is_Selasa Sel Sl_Rabu Rab Rb_Khamis Kha Km_Jumaat Jum Jm_Sabtu Sab Sb'.split('_');\n\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'beberapa saat', '44 saat = beberapa saat');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'seminit',      '45 saat = seminit');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'seminit',      '89 saat = seminit');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 minit',     '90 saat = 2 minit');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 minit',    '44 minit = 44 minit');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'sejam',       '45 minit = sejam');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'sejam',       '89 minit = sejam');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 jam',       '90 minit = 2 jam');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 jam',       '5 jam = 5 jam');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 jam',      '21 jam = 21 jam');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'sehari',         '22 jam = sehari');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'sehari',         '35 jam = sehari');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 hari',        '36 jam = 2 hari');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'sehari',         '1 hari = sehari');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 hari',        '5 hari = 5 hari');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 hari',       '25 hari = 25 hari');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'sebulan',       '26 hari = sebulan');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'sebulan',       '30 hari = sebulan');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'sebulan',       '45 hari = sebulan');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 bulan',      '46 hari = 2 bulan');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 bulan',      '75 hari = 2 bulan');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 bulan',      '76 hari = 3 bulan');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'sebulan',       '1 bulan = sebulan');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 bulan',      '5 bulan = 5 bulan');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'setahun',        '345 hari = setahun');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 tahun',       '548 hari = 2 tahun');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'setahun',        '1 tahun = setahun');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 tahun',       '5 tahun = 5 tahun');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'dalam beberapa saat',  'prefix');\n    assert.equal(moment(0).from(30000), 'beberapa saat yang lepas', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'beberapa saat yang lepas',  'waktu sekarang dari sekarang sepatutnya menunjukkan sebagai telah lepas');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'dalam beberapa saat', 'dalam beberapa saat');\n    assert.equal(moment().add({d: 5}).fromNow(), 'dalam 5 hari', 'dalam 5 hari');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'Hari ini pukul 12.00',  'hari ini pada waktu yang sama');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'Hari ini pukul 12.25',  'Sekarang tambah 25 minit');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'Hari ini pukul 13.00',  'Sekarang tambah 1 jam');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'Esok pukul 12.00',      'esok pada waktu yang sama');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'Hari ini pukul 11.00',  'Sekarang tolak 1 jam');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'Kelmarin pukul 12.00',  'kelmarin pada waktu yang sama');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('dddd [pukul] LT'),  'Hari ini + ' + i + ' hari waktu sekarang');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd [pukul] LT'),  'Hari ini + ' + i + ' hari permulaan hari');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd [pukul] LT'),  'Hari ini + ' + i + ' hari tamat hari');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('dddd [lepas] [pukul] LT'),  'Hari ini - ' + i + ' hari waktu sekarang');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd [lepas] [pukul] LT'),  'Hari ini - ' + i + ' hari permulaan hari');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd [lepas] [pukul] LT'),  'Hari ini - ' + i + ' hari tamat hari');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 minggu lepas');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'dalam 1 minggu');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 minggu lepas');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'dalam 2 minggu');\n});\n\ntest('weeks year starting sunday format', function (assert) {\n    assert.equal(moment([2012, 0,  1]).format('w ww wo'), '1 01 1', 'Jan  1 2012 sepatutnya minggu 1');\n    assert.equal(moment([2012, 0,  7]).format('w ww wo'), '2 02 2', 'Jan  7 2012 sepatutnya minggu 2');\n    assert.equal(moment([2012, 0,  8]).format('w ww wo'), '2 02 2', 'Jan  8 2012 sepatutnya minggu 2');\n    assert.equal(moment([2012, 0, 14]).format('w ww wo'), '3 03 3', 'Jan 14 2012 sepatutnya minggu 3');\n    assert.equal(moment([2012, 0, 15]).format('w ww wo'), '3 03 3', 'Jan 15 2012 sepatutnya minggu 3');\n});\n\n\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/test/locale/my.js",
    "content": "import {localeModule, test} from '../qunit';\nimport moment from '../../moment';\nlocaleModule('my');\n\ntest('parse', function (assert) {\n    var tests = 'ဇန်နဝါရီ ဇန်_ဖေဖော်ဝါရီ ဖေ_မတ် မတ်_ဧပြီ ပြီ_မေ မေ_ဇွန် ဇွန်_ဇူလိုင် လိုင်_သြဂုတ် သြ_စက်တင်ဘာ စက်_အောက်တိုဘာ အောက်_နိုဝင်ဘာ နို_ဒီဇင်ဘာ ဒီ'.split('_'),\n        i;\n\n    function equalTest (input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, MMMM Do YYYY, h:mm:ss a', 'တနင်္ဂနွေ, ဖေဖော်ဝါရီ ၁၄ ၂၀၁၀, ၃:၂၅:၅၀ pm'],\n            ['ddd, hA', 'နွေ, ၃PM'],\n            ['M Mo MM MMMM MMM', '၂ ၂ ၀၂ ဖေဖော်ဝါရီ ဖေ'],\n            ['YYYY YY', '၂၀၁၀ ၁၀'],\n            ['D Do DD', '၁၄ ၁၄ ၁၄'],\n            ['d do dddd ddd dd', '၀ ၀ တနင်္ဂနွေ နွေ နွေ'],\n            ['DDD DDDo DDDD', '၄၅ ၄၅ ၀၄၅'],\n            ['w wo ww', '၆ ၆ ၀၆'],\n            ['h hh', '၃ ၀၃'],\n            ['H HH', '၁၅ ၁၅'],\n            ['m mm', '၂၅ ၂၅'],\n            ['s ss', '၅၀ ၅၀'],\n            ['a A', 'pm PM'],\n            ['[နှစ်၏] DDDo [ရက်မြောက်]', 'နှစ်၏ ၄၅ ရက်မြောက်'],\n            ['LTS', '၁၅:၂၅:၅၀'],\n            ['L', '၁၄/၀၂/၂၀၁၀'],\n            ['LL', '၁၄ ဖေဖော်ဝါရီ ၂၀၁၀'],\n            ['LLL', '၁၄ ဖေဖော်ဝါရီ ၂၀၁၀ ၁၅:၂၅'],\n            ['LLLL', 'တနင်္ဂနွေ ၁၄ ဖေဖော်ဝါရီ ၂၀၁၀ ၁၅:၂၅'],\n            ['l', '၁၄/၂/၂၀၁၀'],\n            ['ll', '၁၄ ဖေ ၂၀၁၀'],\n            ['lll', '၁၄ ဖေ ၂၀၁၀ ၁၅:၂၅'],\n            ['llll', 'နွေ ၁၄ ဖေ ၂၀၁၀ ၁၅:၂၅']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '၁', '၁');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '၂', '၂');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '၃', '၃');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '၄', '၄');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '၅', '၅');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '၆', '၆');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '၇', '၇');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '၈', '၈');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '၉', '၉');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '၁၀', '၁၀');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '၁၁', '၁၁');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '၁၂', '၁၂');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '၁၃', '၁၃');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '၁၄', '၁၄');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '၁၅', '၁၅');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '၁၆', '၁၆');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '၁၇', '၁၇');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '၁၈', '၁၈');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '၁၉', '၁၉');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '၂၀', '၂၀');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '၂၁', '၂၁');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '၂၂', '၂၂');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '၂၃', '၂၃');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '၂၄', '၂၄');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '၂၅', '၂၅');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '၂၆', '၂၆');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '၂၇', '၂၇');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '၂၈', '၂၈');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '၂၉', '၂၉');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '၃၀', '၃၀');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '၃၁', '၃၁');\n});\n\ntest('format month', function (assert) {\n    var expected = 'ဇန်နဝါရီ ဇန်_ဖေဖော်ဝါရီ ဖေ_မတ် မတ်_ဧပြီ ပြီ_မေ မေ_ဇွန် ဇွန်_ဇူလိုင် လိုင်_သြဂုတ် သြ_စက်တင်ဘာ စက်_အောက်တိုဘာ အောက်_နိုဝင်ဘာ နို_ဒီဇင်ဘာ ဒီ'.split('_'),\n        i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'တနင်္ဂနွေ နွေ နွေ_တနင်္လာ လာ လာ_အင်္ဂါ ဂါ ဂါ_ဗုဒ္ဓဟူး ဟူး ဟူး_ကြာသပတေး ကြာ ကြာ_သောကြာ သော သော_စနေ နေ နေ'.split('_'),\n        i;\n\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({\n        s: 44\n    }), true), 'စက္ကန်.အနည်းငယ်', '၄၄ စက္ကန်. = စက္ကန်.အနည်းငယ်');\n    assert.equal(start.from(moment([2007, 1, 28]).add({\n        s: 45\n    }), true), 'တစ်မိနစ်', '၄၅ စက္ကန်. = တစ်မိနစ်');\n    assert.equal(start.from(moment([2007, 1, 28]).add({\n        s: 89\n    }), true), 'တစ်မိနစ်', '၈၉ စက္ကန်. = တစ်မိနစ်');\n    assert.equal(start.from(moment([2007, 1, 28]).add({\n        s: 90\n    }), true), '၂ မိနစ်', '၉၀ စက္ကန်. =  ၂ မိနစ်');\n    assert.equal(start.from(moment([2007, 1, 28]).add({\n        m: 44\n    }), true), '၄၄ မိနစ်', '၄၄ မိနစ် = ၄၄ မိနစ်');\n    assert.equal(start.from(moment([2007, 1, 28]).add({\n        m: 45\n    }), true), 'တစ်နာရီ', '၄၅ မိနစ် = ၁ နာရီ');\n    assert.equal(start.from(moment([2007, 1, 28]).add({\n        m: 89\n    }), true), 'တစ်နာရီ', '၈၉ မိနစ် = တစ်နာရီ');\n    assert.equal(start.from(moment([2007, 1, 28]).add({\n        m: 90\n    }), true), '၂ နာရီ', 'မိနစ် ၉၀= ၂ နာရီ');\n    assert.equal(start.from(moment([2007, 1, 28]).add({\n        h: 5\n    }), true), '၅ နာရီ', '၅ နာရီ= ၅ နာရီ');\n    assert.equal(start.from(moment([2007, 1, 28]).add({\n        h: 21\n    }), true), '၂၁ နာရီ', '၂၁ နာရီ =၂၁ နာရီ');\n    assert.equal(start.from(moment([2007, 1, 28]).add({\n        h: 22\n    }), true), 'တစ်ရက်', '၂၂ နာရီ =တစ်ရက်');\n    assert.equal(start.from(moment([2007, 1, 28]).add({\n        h: 35\n    }), true), 'တစ်ရက်', '၃၅ နာရီ =တစ်ရက်');\n    assert.equal(start.from(moment([2007, 1, 28]).add({\n        h: 36\n    }), true), '၂ ရက်', '၃၆ နာရီ = ၂ ရက်');\n    assert.equal(start.from(moment([2007, 1, 28]).add({\n        d: 1\n    }), true), 'တစ်ရက်', '၁ ရက်= တစ်ရက်');\n    assert.equal(start.from(moment([2007, 1, 28]).add({\n        d: 5\n    }), true), '၅ ရက်', '၅ ရက် = ၅ ရက်');\n    assert.equal(start.from(moment([2007, 1, 28]).add({\n        d: 25\n    }), true), '၂၅ ရက်', '၂၅ ရက်= ၂၅ ရက်');\n    assert.equal(start.from(moment([2007, 1, 28]).add({\n        d: 26\n    }), true), 'တစ်လ', '၂၆ ရက် = တစ်လ');\n    assert.equal(start.from(moment([2007, 1, 28]).add({\n        d: 30\n    }), true), 'တစ်လ', 'ရက် ၃၀ = တစ်လ');\n    assert.equal(start.from(moment([2007, 1, 28]).add({\n        d: 43\n    }), true), 'တစ်လ', '၄၃ ရက် = တစ်လ');\n    assert.equal(start.from(moment([2007, 1, 28]).add({\n        d: 46\n    }), true), '၂ လ', '၄၆ ရက် = ၂ လ');\n    assert.equal(start.from(moment([2007, 1, 28]).add({\n        d: 74\n    }), true), '၂ လ', '၇၅ ရက်= ၂ လ');\n    assert.equal(start.from(moment([2007, 1, 28]).add({\n        d: 76\n    }), true), '၃ လ', '၇၆ ရက် = ၃ လ');\n    assert.equal(start.from(moment([2007, 1, 28]).add({\n        M: 1\n    }), true), 'တစ်လ', '၁ လ = တစ်လ');\n    assert.equal(start.from(moment([2007, 1, 28]).add({\n        M: 5\n    }), true), '၅ လ', '၅ လ = ၅ လ');\n    assert.equal(start.from(moment([2007, 1, 28]).add({\n        d: 345\n    }), true), 'တစ်နှစ်', '၃၄၅ ရက် = တစ်နှစ်');\n    assert.equal(start.from(moment([2007, 1, 28]).add({\n        d: 548\n    }), true), '၂ နှစ်', '၅၄၈ ရက် = ၂ နှစ်');\n    assert.equal(start.from(moment([2007, 1, 28]).add({\n        y: 1\n    }), true), 'တစ်နှစ်', '၁ နှစ် = တစ်နှစ်');\n    assert.equal(start.from(moment([2007, 1, 28]).add({\n        y: 5\n    }), true), '၅ နှစ်', '၅ နှစ် = ၅ နှစ်');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'လာမည့် စက္ကန်.အနည်းငယ် မှာ', 'prefix');\n    assert.equal(moment(0).from(30000), 'လွန်ခဲ့သော စက္ကန်.အနည်းငယ် က', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'လွန်ခဲ့သော စက္ကန်.အနည်းငယ် က', 'ယခုမှစပြီး အတိတ်တွင်ဖော်ပြသလိုဖော်ပြမည်');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({\n        s: 30\n    }).fromNow(), 'လာမည့် စက္ကန်.အနည်းငယ် မှာ', 'လာမည့် စက္ကန်.အနည်းငယ် မှာ');\n    assert.equal(moment().add({\n        d: 5\n    }).fromNow(), 'လာမည့် ၅ ရက် မှာ', 'လာမည့် ၅ ရက် မှာ');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                  'ယနေ. ၁၂:၀၀ မှာ',      'ယနေ. ဒီအချိန်');\n    assert.equal(moment(a).add({m: 25}).calendar(),     'ယနေ. ၁၂:၂၅ မှာ',      'ယခုမှ ၂၅ မိနစ်ပေါင်းထည့်');\n    assert.equal(moment(a).add({h: 1}).calendar(),      'ယနေ. ၁၃:၀၀ မှာ',      'ယခုမှ ၁ နာရီပေါင်းထည့်');\n    assert.equal(moment(a).add({d: 1}).calendar(),      'မနက်ဖြန် ၁၂:၀၀ မှာ',  'မနက်ဖြန် ဒီအချိန်');\n    assert.equal(moment(a).subtract({h: 1}).calendar(), 'ယနေ. ၁၁:၀၀ မှာ',      'ယခုမှ ၁ နာရီနှုတ်');\n    assert.equal(moment(a).subtract({d: 1}).calendar(), 'မနေ.က ၁၂:၀၀ မှာ',     'မနေ.က ဒီအချိန်');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({\n            d: i\n        });\n        assert.equal(m.calendar(), m.format('dddd LT [မှာ]'), 'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(), m.format('dddd LT [မှာ]'), 'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(), m.format('dddd LT [မှာ]'), 'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({\n            d: i\n        });\n        assert.equal(m.calendar(), m.format('[ပြီးခဲ့သော] dddd LT [မှာ]'), 'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(), m.format('[ပြီးခဲ့သော] dddd LT [မှာ]'), 'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(), m.format('[ပြီးခဲ့သော] dddd LT [မှာ]'), 'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({\n            w: 1\n        }),\n        weeksFromNow = moment().add({\n            w: 1\n        });\n\n    assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), 'လွန်ခဲ့သော ၁ ပတ်က');\n    assert.equal(weeksFromNow.calendar(), weeksFromNow.format('L'), '၁ ပတ်အတွင်း');\n\n    weeksAgo = moment().subtract({\n        w: 2\n    });\n    weeksFromNow = moment().add({\n        w: 2\n    });\n\n    assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '၂ ပတ် အရင်က');\n    assert.equal(weeksFromNow.calendar(), weeksFromNow.format('L'), '၂ ပတ် အတွင်း');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2012, 0, 1]).format('w ww wo'), '၅၂ ၅၂ ၅၂', 'Jan  1 2012 should be week 52');\n    assert.equal(moment([2012, 0, 2]).format('w ww wo'), '၁ ၀၁ ၁', 'Jan  2 2012 should be week 1');\n    assert.equal(moment([2012, 0, 8]).format('w ww wo'), '၁ ၀၁ ၁', 'Jan  8 2012 should be week 1');\n    assert.equal(moment([2012, 0, 9]).format('w ww wo'), '၂ ၀၂ ၂', 'Jan  9 2012 should be week 2');\n    assert.equal(moment([2012, 0, 15]).format('w ww wo'), '၂ ၀၂ ၂', 'Jan 15 2012 should be week 2');\n});\n\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/test/locale/nb.js",
    "content": "import {localeModule, test} from '../qunit';\nimport moment from '../../moment';\nlocaleModule('nb');\n\ntest('parse', function (assert) {\n    var tests = 'januar jan._februar feb._mars mars_april april_mai mai_juni juni_juli juli_august aug._september sep._oktober okt._november nov._desember des.'.split('_'),\n        i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, MMMM Do YYYY, h:mm:ss a',      'søndag, februar 14. 2010, 3:25:50 pm'],\n            ['ddd, hA',                            'sø., 3PM'],\n            ['M Mo MM MMMM MMM',                   '2 2. 02 februar feb.'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14. 14'],\n            ['d do dddd ddd dd',                   '0 0. søndag sø. sø'],\n            ['DDD DDDo DDDD',                      '45 45. 045'],\n            ['w wo ww',                            '6 6. 06'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'pm PM'],\n            ['[den] DDDo [dagen i året]',          'den 45. dagen i året'],\n            ['LTS',                                '15:25:50'],\n            ['L',                                  '14.02.2010'],\n            ['LL',                                 '14. februar 2010'],\n            ['LLL',                                '14. februar 2010 kl. 15:25'],\n            ['LLLL',                               'søndag 14. februar 2010 kl. 15:25'],\n            ['l',                                  '14.2.2010'],\n            ['ll',                                 '14. feb. 2010'],\n            ['lll',                                '14. feb. 2010 kl. 15:25'],\n            ['llll',                               'sø. 14. feb. 2010 kl. 15:25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1.', '1.');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2.', '2.');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3.', '3.');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4.', '4.');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5.', '5.');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6.', '6.');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7.', '7.');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8.', '8.');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9.', '9.');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10.', '10.');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11.', '11.');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12.', '12.');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13.', '13.');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14.', '14.');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15.', '15.');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16.', '16.');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17.', '17.');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18.', '18.');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19.', '19.');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20.', '20.');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21.', '21.');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22.', '22.');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23.', '23.');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24.', '24.');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25.', '25.');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26.', '26.');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27.', '27.');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28.', '28.');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29.', '29.');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30.', '30.');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31.', '31.');\n});\n\ntest('format month', function (assert) {\n    var expected = 'januar jan._februar feb._mars mars_april april_mai mai_juni juni_juli juli_august aug._september sep._oktober okt._november nov._desember des.'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'søndag sø. sø_mandag ma. ma_tirsdag ti. ti_onsdag on. on_torsdag to. to_fredag fr. fr_lørdag lø. lø'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'noen sekunder', '44 sekunder = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'ett minutt',      '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'ett minutt',      '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 minutter',     '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 minutter',    '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'en time',       '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'en time',       '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 timer',       '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 timer',       '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 timer',      '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'en dag',         '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'en dag',         '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 dager',        '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'en dag',         '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 dager',        '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 dager',       '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'en måned',       '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'en måned',       '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'en måned',       '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 måneder',      '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 måneder',      '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 måneder',      '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'en måned',       '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 måneder',      '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'ett år',        '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 år',       '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'ett år',        '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 år',       '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'om noen sekunder',  'prefix');\n    assert.equal(moment(0).from(30000), 'noen sekunder siden', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'noen sekunder siden',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'om noen sekunder', 'in a few seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), 'om 5 dager', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'i dag kl. 12:00',     'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'i dag kl. 12:25',     'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'i dag kl. 13:00',     'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'i morgen kl. 12:00',  'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'i dag kl. 11:00',     'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'i går kl. 12:00',     'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('dddd [kl.] LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd [kl.] LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd [kl.] LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('[forrige] dddd [kl.] LT'),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[forrige] dddd [kl.] LT'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[forrige] dddd [kl.] LT'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2012, 0,  1]).format('w ww wo'), '52 52 52.', 'Jan  1 2012 should be week 52');\n    assert.equal(moment([2012, 0,  2]).format('w ww wo'),  '1 01 1.', 'Jan  2 2012 should be week 1');\n    assert.equal(moment([2012, 0,  8]).format('w ww wo'),  '1 01 1.', 'Jan  8 2012 should be week 1');\n    assert.equal(moment([2012, 0,  9]).format('w ww wo'),  '2 02 2.', 'Jan  9 2012 should be week 2');\n    assert.equal(moment([2012, 0, 15]).format('w ww wo'),  '2 02 2.', 'Jan 15 2012 should be week 2');\n});\n\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/test/locale/ne.js",
    "content": "import {localeModule, test} from '../qunit';\nimport moment from '../../moment';\nlocaleModule('ne');\n\ntest('parse', function (assert) {\n    var tests = 'जनवरी जन._फेब्रुवरी फेब्रु._मार्च मार्च_अप्रिल अप्रि._मई मई_जुन जुन_जुलाई जुलाई._अगष्ट अग._सेप्टेम्बर सेप्ट._अक्टोबर अक्टो._नोभेम्बर नोभे._डिसेम्बर डिसे.'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, Do MMMM YYYY, aको h:mm:ss बजे',      'आइतबार, १४ फेब्रुवरी २०१०, दिउँसोको ३:२५:५० बजे'],\n            ['ddd, aको h बजे',                                                'आइत., दिउँसोको ३ बजे'],\n            ['M Mo MM MMMM MMM',                   '२ २ ०२ फेब्रुवरी फेब्रु.'],\n            ['YYYY YY',                            '२०१० १०'],\n            ['D Do DD',                            '१४ १४ १४'],\n            ['d do dddd ddd dd',                   '० ० आइतबार आइत. आ.'],\n            ['DDD DDDo DDDD',                      '४५ ४५ ०४५'],\n            ['w wo ww',                            '८ ८ ०८'],\n            ['h hh',                               '३ ०३'],\n            ['H HH',                               '१५ १५'],\n            ['m mm',                               '२५ २५'],\n            ['s ss',                               '५० ५०'],\n            ['a A',                                'दिउँसो दिउँसो'],\n            ['LTS',                                'दिउँसोको ३:२५:५० बजे'],\n            ['L',                                  '१४/०२/२०१०'],\n            ['LL',                                 '१४ फेब्रुवरी २०१०'],\n            ['LLL',                                '१४ फेब्रुवरी २०१०, दिउँसोको ३:२५ बजे'],\n            ['LLLL',                               'आइतबार, १४ फेब्रुवरी २०१०, दिउँसोको ३:२५ बजे'],\n            ['l',                                  '१४/२/२०१०'],\n            ['ll',                                 '१४ फेब्रु. २०१०'],\n            ['lll',                                '१४ फेब्रु. २०१०, दिउँसोको ३:२५ बजे'],\n            ['llll',                               'आइत., १४ फेब्रु. २०१०, दिउँसोको ३:२५ बजे']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '१', '१');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '२', '२');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '३', '३');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '४', '४');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '५', '५');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '६', '६');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '७', '७');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '८', '८');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '९', '९');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '१०', '१०');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '११', '११');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '१२', '१२');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '१३', '१३');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '१४', '१४');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '१५', '१५');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '१६', '१६');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '१७', '१७');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '१८', '१८');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '१९', '१९');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '२०', '२०');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '२१', '२१');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '२२', '२२');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '२३', '२३');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '२४', '२४');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '२५', '२५');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '२६', '२६');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '२७', '२७');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '२८', '२८');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '२९', '२९');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '३०', '३०');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '३१', '३१');\n});\n\ntest('format month', function (assert) {\n    var expected = 'जनवरी जन._फेब्रुवरी फेब्रु._मार्च मार्च_अप्रिल अप्रि._मई मई_जुन जुन_जुलाई जुलाई._अगष्ट अग._सेप्टेम्बर सेप्ट._अक्टोबर अक्टो._नोभेम्बर नोभे._डिसेम्बर डिसे.'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'आइतबार आइत. आ._सोमबार सोम. सो._मङ्गलबार मङ्गल. मं._बुधबार बुध. बु._बिहिबार बिहि. बि._शुक्रबार शुक्र. शु._शनिबार शनि. श.'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'केही क्षण', '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'एक मिनेट',      '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'एक मिनेट',      '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '२ मिनेट',     '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '४४ मिनेट',    '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'एक घण्टा',       '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'एक घण्टा',       '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '२ घण्टा',       '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '५ घण्टा',       '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '२१ घण्टा',      '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'एक दिन',         '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'एक दिन',         '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '२ दिन',        '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'एक दिन',         '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '५ दिन',        '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '२५ दिन',       '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'एक महिना',       '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'एक महिना',       '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'एक महिना',       '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '२ महिना',      '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '२ महिना',      '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '३ महिना',      '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'एक महिना',       '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '५ महिना',      '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'एक बर्ष',        '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '२ बर्ष',       '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'एक बर्ष',        '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '५ बर्ष',       '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'केही क्षणमा',  'prefix');\n    assert.equal(moment(0).from(30000), 'केही क्षण अगाडि', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'केही क्षण अगाडि',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'केही क्षणमा', 'केही क्षणमा');\n    assert.equal(moment().add({d: 5}).fromNow(), '५ दिनमा', '५ दिनमा');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'आज दिउँसोको १२:०० बजे',    'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'आज दिउँसोको १२:२५ बजे',    'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'आज दिउँसोको १:०० बजे',     'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'भोलि दिउँसोको १२:०० बजे',  'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'आज बिहानको ११:०० बजे',     'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'हिजो दिउँसोको १२:०० बजे',  'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('[आउँदो] dddd[,] LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[आउँदो] dddd[,] LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[आउँदो] dddd[,] LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('[गएको] dddd[,] LT'),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[गएको] dddd[,] LT'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[गएको] dddd[,] LT'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('meridiem', function (assert) {\n    assert.equal(moment([2011, 2, 23,  2, 30]).format('a'), 'राति', 'before dawn');\n    assert.equal(moment([2011, 2, 23,  9, 30]).format('a'), 'बिहान', 'morning');\n    assert.equal(moment([2011, 2, 23, 14, 30]).format('a'), 'दिउँसो', 'during day');\n    assert.equal(moment([2011, 2, 23, 17, 30]).format('a'), 'साँझ', 'evening');\n    assert.equal(moment([2011, 2, 23, 19, 30]).format('a'), 'साँझ', 'late evening');\n    assert.equal(moment([2011, 2, 23, 21, 20]).format('a'), 'राति', 'night');\n\n    assert.equal(moment([2011, 2, 23,  2, 30]).format('A'), 'राति', 'before dawn');\n    assert.equal(moment([2011, 2, 23,  9, 30]).format('A'), 'बिहान', 'morning');\n    assert.equal(moment([2011, 2, 23, 14, 30]).format('A'), 'दिउँसो', 'during day');\n    assert.equal(moment([2011, 2, 23, 17, 30]).format('A'), 'साँझ', 'evening');\n    assert.equal(moment([2011, 2, 23, 19, 30]).format('A'), 'साँझ', 'late evening');\n    assert.equal(moment([2011, 2, 23, 21, 20]).format('A'), 'राति', 'night');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2011, 11, 26]).format('w ww wo'), '५३ ५३ ५३', 'Dec 26 2011 should be week 53');\n    assert.equal(moment([2012,  0,  1]).format('w ww wo'), '१ ०१ १', 'Jan  1 2012 should be week 1');\n    assert.equal(moment([2012,  0,  2]).format('w ww wo'), '१ ०१ १', 'Jan  2 2012 should be week 1');\n    assert.equal(moment([2012,  0,  8]).format('w ww wo'), '२ ०२ २', 'Jan  8 2012 should be week 2');\n    assert.equal(moment([2012,  0,  9]).format('w ww wo'), '२ ०२ २', 'Jan  9 2012 should be week 2');\n});\n\n\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/test/locale/nl-be.js",
    "content": "import {localeModule, test} from '../qunit';\nimport moment from '../../moment';\nlocaleModule('nl-be');\n\ntest('parse', function (assert) {\n    var tests = 'januari jan._februari feb._maart mrt._april apr._mei mei._juni jun._juli jul._augustus aug._september sep._oktober okt._november nov._december dec.'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, MMMM Do YYYY, HH:mm:ss',       'zondag, februari 14de 2010, 15:25:50'],\n            ['ddd, HH',                            'zo., 15'],\n            ['M Mo MM MMMM MMM',                   '2 2de 02 februari feb.'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14de 14'],\n            ['d do dddd ddd dd',                   '0 0de zondag zo. Zo'],\n            ['DDD DDDo DDDD',                      '45 45ste 045'],\n            ['w wo ww',                            '6 6de 06'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'pm PM'],\n            ['[the] DDDo [day of the year]',       'the 45ste day of the year'],\n            ['LTS',                                '15:25:50'],\n            ['L',                                  '14/02/2010'],\n            ['LL',                                 '14 februari 2010'],\n            ['LLL',                                '14 februari 2010 15:25'],\n            ['LLLL',                               'zondag 14 februari 2010 15:25'],\n            ['l',                                  '14/2/2010'],\n            ['ll',                                 '14 feb. 2010'],\n            ['lll',                                '14 feb. 2010 15:25'],\n            ['llll',                               'zo. 14 feb. 2010 15:25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1ste', '1ste');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2de', '2de');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3de', '3de');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4de', '4de');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5de', '5de');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6de', '6de');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7de', '7de');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8ste', '8ste');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9de', '9de');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10de', '10de');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11de', '11de');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12de', '12de');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13de', '13de');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14de', '14de');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15de', '15de');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16de', '16de');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17de', '17de');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18de', '18de');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19de', '19de');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20ste', '20ste');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21ste', '21ste');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22ste', '22ste');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23ste', '23ste');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24ste', '24ste');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25ste', '25ste');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26ste', '26ste');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27ste', '27ste');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28ste', '28ste');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29ste', '29ste');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30ste', '30ste');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31ste', '31ste');\n});\n\ntest('format month', function (assert) {\n    var expected = 'januari jan._februari feb._maart mrt._april apr._mei mei_juni jun._juli jul._augustus aug._september sep._oktober okt._november nov._december dec.'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'zondag zo. Zo_maandag ma. Ma_dinsdag di. Di_woensdag wo. Wo_donderdag do. Do_vrijdag vr. Vr_zaterdag za. Za'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'een paar seconden', '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'één minuut',      '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'één minuut',      '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 minuten',     '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 minuten',    '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'één uur',       '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'één uur',       '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 uur',       '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 uur',       '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 uur',      '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'één dag',         '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'één dag',         '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 dagen',        '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'één dag',         '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 dagen',        '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 dagen',       '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'één maand',       '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'één maand',       '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'één maand',       '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 maanden',      '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 maanden',      '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 maanden',      '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'één maand',       '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 maanden',      '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'één jaar',        '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 jaar',       '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'één jaar',        '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 jaar',       '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'over een paar seconden',  'prefix');\n    assert.equal(moment(0).from(30000), 'een paar seconden geleden', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'een paar seconden geleden',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'over een paar seconden', 'in a few seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), 'over 5 dagen', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'vandaag om 12:00',   'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'vandaag om 12:25',   'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'vandaag om 13:00',   'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'morgen om 12:00',    'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'vandaag om 11:00',   'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'gisteren om 12:00',  'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('dddd [om] LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd [om] LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd [om] LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('[afgelopen] dddd [om] LT'),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[afgelopen] dddd [om] LT'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[afgelopen] dddd [om] LT'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('month abbreviation', function (assert) {\n    assert.equal(moment([2012, 5, 23]).format('D-MMM-YYYY'), '23-jun-2012', 'format month abbreviation surrounded by dashes should not include a dot');\n    assert.equal(moment([2012, 5, 23]).unix(), moment('23-jun-2012', 'D-MMM-YYYY').unix(), 'parse month abbreviation surrounded by dashes without dot');\n    assert.equal(moment([2012, 5, 23]).format('D MMM YYYY'), '23 jun. 2012', 'format month abbreviation not surrounded by dashes should include a dot');\n    assert.equal(moment([2012, 5, 23]).unix(), moment('23 jun. 2012', 'D MMM YYYY').unix(), 'parse month abbreviation not surrounded by dashes with dot');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2012, 0,  1]).format('w ww wo'), '52 52 52ste', 'Jan  1 2012 should be week 52');\n    assert.equal(moment([2012, 0,  2]).format('w ww wo'),   '1 01 1ste', 'Jan  2 2012 should be week 1');\n    assert.equal(moment([2012, 0,  8]).format('w ww wo'),   '1 01 1ste', 'Jan  8 2012 should be week 1');\n    assert.equal(moment([2012, 0,  9]).format('w ww wo'),    '2 02 2de', 'Jan  9 2012 should be week 2');\n    assert.equal(moment([2012, 0, 15]).format('w ww wo'),    '2 02 2de', 'Jan 15 2012 should be week 2');\n});\n\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/test/locale/nl.js",
    "content": "import {localeModule, test} from '../qunit';\nimport moment from '../../moment';\nlocaleModule('nl');\n\ntest('parse', function (assert) {\n    var tests = 'januari jan._februari feb._maart mrt._april apr._mei mei._juni jun._juli jul._augustus aug._september sep._oktober okt._november nov._december dec.'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, MMMM Do YYYY, HH:mm:ss',       'zondag, februari 14de 2010, 15:25:50'],\n            ['ddd, HH',                            'zo., 15'],\n            ['M Mo MM MMMM MMM',                   '2 2de 02 februari feb.'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14de 14'],\n            ['d do dddd ddd dd',                   '0 0de zondag zo. Zo'],\n            ['DDD DDDo DDDD',                      '45 45ste 045'],\n            ['w wo ww',                            '6 6de 06'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'pm PM'],\n            ['[the] DDDo [day of the year]',       'the 45ste day of the year'],\n            ['LTS',                                '15:25:50'],\n            ['L',                                  '14-02-2010'],\n            ['LL',                                 '14 februari 2010'],\n            ['LLL',                                '14 februari 2010 15:25'],\n            ['LLLL',                               'zondag 14 februari 2010 15:25'],\n            ['l',                                  '14-2-2010'],\n            ['ll',                                 '14 feb. 2010'],\n            ['lll',                                '14 feb. 2010 15:25'],\n            ['llll',                               'zo. 14 feb. 2010 15:25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1ste', '1ste');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2de', '2de');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3de', '3de');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4de', '4de');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5de', '5de');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6de', '6de');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7de', '7de');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8ste', '8ste');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9de', '9de');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10de', '10de');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11de', '11de');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12de', '12de');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13de', '13de');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14de', '14de');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15de', '15de');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16de', '16de');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17de', '17de');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18de', '18de');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19de', '19de');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20ste', '20ste');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21ste', '21ste');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22ste', '22ste');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23ste', '23ste');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24ste', '24ste');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25ste', '25ste');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26ste', '26ste');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27ste', '27ste');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28ste', '28ste');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29ste', '29ste');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30ste', '30ste');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31ste', '31ste');\n});\n\ntest('format month', function (assert) {\n    var expected = 'januari jan._februari feb._maart mrt._april apr._mei mei_juni jun._juli jul._augustus aug._september sep._oktober okt._november nov._december dec.'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'zondag zo. Zo_maandag ma. Ma_dinsdag di. Di_woensdag wo. Wo_donderdag do. Do_vrijdag vr. Vr_zaterdag za. Za'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'een paar seconden', '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'één minuut',      '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'één minuut',      '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 minuten',     '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 minuten',    '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'één uur',       '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'één uur',       '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 uur',       '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 uur',       '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 uur',      '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'één dag',         '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'één dag',         '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 dagen',        '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'één dag',         '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 dagen',        '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 dagen',       '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'één maand',       '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'één maand',       '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'één maand',       '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 maanden',      '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 maanden',      '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 maanden',      '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'één maand',       '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 maanden',      '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'één jaar',        '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 jaar',       '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'één jaar',        '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 jaar',       '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'over een paar seconden',  'prefix');\n    assert.equal(moment(0).from(30000), 'een paar seconden geleden', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'een paar seconden geleden',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'over een paar seconden', 'in a few seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), 'over 5 dagen', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'vandaag om 12:00',   'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'vandaag om 12:25',   'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'vandaag om 13:00',   'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'morgen om 12:00',    'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'vandaag om 11:00',   'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'gisteren om 12:00',  'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('dddd [om] LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd [om] LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd [om] LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('[afgelopen] dddd [om] LT'),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[afgelopen] dddd [om] LT'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[afgelopen] dddd [om] LT'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('month abbreviation', function (assert) {\n    assert.equal(moment([2012, 5, 23]).format('D-MMM-YYYY'), '23-jun-2012', 'format month abbreviation surrounded by dashes should not include a dot');\n    assert.equal(moment([2012, 5, 23]).unix(), moment('23-jun-2012', 'D-MMM-YYYY').unix(), 'parse month abbreviation surrounded by dashes without dot');\n    assert.equal(moment([2012, 5, 23]).format('D MMM YYYY'), '23 jun. 2012', 'format month abbreviation not surrounded by dashes should include a dot');\n    assert.equal(moment([2012, 5, 23]).unix(), moment('23 jun. 2012', 'D MMM YYYY').unix(), 'parse month abbreviation not surrounded by dashes with dot');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2012, 0,  1]).format('w ww wo'), '52 52 52ste', 'Jan  1 2012 should be week 52');\n    assert.equal(moment([2012, 0,  2]).format('w ww wo'),   '1 01 1ste', 'Jan  2 2012 should be week 1');\n    assert.equal(moment([2012, 0,  8]).format('w ww wo'),   '1 01 1ste', 'Jan  8 2012 should be week 1');\n    assert.equal(moment([2012, 0,  9]).format('w ww wo'),    '2 02 2de', 'Jan  9 2012 should be week 2');\n    assert.equal(moment([2012, 0, 15]).format('w ww wo'),    '2 02 2de', 'Jan 15 2012 should be week 2');\n});\n\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/test/locale/nn.js",
    "content": "import {localeModule, test} from '../qunit';\nimport moment from '../../moment';\nlocaleModule('nn');\n\ntest('parse', function (assert) {\n    var tests = 'januar jan_februar feb_mars mar_april apr_mai mai_juni jun_juli jul_august aug_september sep_oktober okt_november nov_desember des'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, MMMM Do YYYY, h:mm:ss a',      'sundag, februar 14. 2010, 3:25:50 pm'],\n            ['ddd, hA',                            'sun, 3PM'],\n            ['M Mo MM MMMM MMM',                   '2 2. 02 februar feb'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14. 14'],\n            ['d do dddd ddd dd',                   '0 0. sundag sun su'],\n            ['DDD DDDo DDDD',                      '45 45. 045'],\n            ['w wo ww',                            '6 6. 06'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'pm PM'],\n            ['[the] DDDo [day of the year]',       'the 45. day of the year'],\n            ['LTS',                                '15:25:50'],\n            ['L',                                  '14.02.2010'],\n            ['LL',                                 '14. februar 2010'],\n            ['LLL',                                '14. februar 2010 kl. 15:25'],\n            ['LLLL',                               'sundag 14. februar 2010 kl. 15:25'],\n            ['l',                                  '14.2.2010'],\n            ['ll',                                 '14. feb 2010'],\n            ['lll',                                '14. feb 2010 kl. 15:25'],\n            ['llll',                               'sun 14. feb 2010 kl. 15:25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1.', '1.');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2.', '2.');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3.', '3.');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4.', '4.');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5.', '5.');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6.', '6.');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7.', '7.');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8.', '8.');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9.', '9.');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10.', '10.');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11.', '11.');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12.', '12.');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13.', '13.');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14.', '14.');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15.', '15.');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16.', '16.');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17.', '17.');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18.', '18.');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19.', '19.');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20.', '20.');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21.', '21.');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22.', '22.');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23.', '23.');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24.', '24.');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25.', '25.');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26.', '26.');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27.', '27.');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28.', '28.');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29.', '29.');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30.', '30.');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31.', '31.');\n});\n\ntest('format month', function (assert) {\n    var expected = 'januar jan_februar feb_mars mar_april apr_mai mai_juni jun_juli jul_august aug_september sep_oktober okt_november nov_desember des'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'sundag sun su_måndag mån må_tysdag tys ty_onsdag ons on_torsdag tor to_fredag fre fr_laurdag lau lø'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'nokre sekund', '44 sekunder = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'eit minutt',   '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'eit minutt',   '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 minutt',     '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 minutt',    '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'ein time',     '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'ein time',     '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 timar',      '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 timar',      '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 timar',     '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'ein dag',      '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'ein dag',      '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 dagar',      '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'ein dag',      '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 dagar',      '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 dagar',     '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'ein månad',    '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'ein månad',    '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'ein månad',    '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 månader',    '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 månader',    '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 månader',    '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'ein månad',    '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 månader',    '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'eit år',       '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 år',         '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'eit år',       '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 år',         '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'om nokre sekund',  'prefix');\n    assert.equal(moment(0).from(30000), 'nokre sekund sidan', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'nokre sekund sidan',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'om nokre sekund', 'in a few seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), 'om 5 dagar', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'I dag klokka 12:00',     'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'I dag klokka 12:25',     'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'I dag klokka 13:00',     'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'I morgon klokka 12:00',  'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'I dag klokka 11:00',     'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'I går klokka 12:00',     'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('dddd [klokka] LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd [klokka] LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd [klokka] LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('[Føregåande] dddd [klokka] LT'),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[Føregåande] dddd [klokka] LT'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[Føregåande] dddd [klokka] LT'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2012, 0,  1]).format('w ww wo'), '52 52 52.', 'Jan  1 2012 should be week 52');\n    assert.equal(moment([2012, 0,  2]).format('w ww wo'),   '1 01 1.', 'Jan  2 2012 should be week 1');\n    assert.equal(moment([2012, 0,  8]).format('w ww wo'),   '1 01 1.', 'Jan  8 2012 should be week 1');\n    assert.equal(moment([2012, 0,  9]).format('w ww wo'),   '2 02 2.', 'Jan  9 2012 should be week 2');\n    assert.equal(moment([2012, 0, 15]).format('w ww wo'),   '2 02 2.', 'Jan 15 2012 should be week 2');\n});\n\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/test/locale/pa-in.js",
    "content": "import {localeModule, test} from '../qunit';\nimport moment from '../../moment';\nlocaleModule('pa-in');\n\ntest('parse', function (assert) {\n    var tests = 'ਜਨਵਰੀ ਜਨਵਰੀ_ਫ਼ਰਵਰੀ ਫ਼ਰਵਰੀ_ਮਾਰਚ ਮਾਰਚ_ਅਪ੍ਰੈਲ ਅਪ੍ਰੈਲ_ਮਈ ਮਈ_ਜੂਨ ਜੂਨ_ਜੁਲਾਈ ਜੁਲਾਈ_ਅਗਸਤ ਅਗਸਤ_ਸਤੰਬਰ ਸਤੰਬਰ_ਅਕਤੂਬਰ ਅਕਤੂਬਰ_ਨਵੰਬਰ ਨਵੰਬਰ_ਦਸੰਬਰ ਦਸੰਬਰ'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, Do MMMM YYYY, a h:mm:ss ਵਜੇ',  'ਐਤਵਾਰ, ੧੪ ਫ਼ਰਵਰੀ ੨੦੧੦, ਦੁਪਹਿਰ ੩:੨੫:੫੦ ਵਜੇ'],\n            ['ddd, a h ਵਜੇ',                       'ਐਤ, ਦੁਪਹਿਰ ੩ ਵਜੇ'],\n            ['M Mo MM MMMM MMM',                   '੨ ੨ ੦੨ ਫ਼ਰਵਰੀ ਫ਼ਰਵਰੀ'],\n            ['YYYY YY',                            '੨੦੧੦ ੧੦'],\n            ['D Do DD',                            '੧੪ ੧੪ ੧੪'],\n            ['d do dddd ddd dd',                   '੦ ੦ ਐਤਵਾਰ ਐਤ ਐਤ'],\n            ['DDD DDDo DDDD',                      '੪੫ ੪੫ ੦੪੫'],\n            ['w wo ww',                            '੮ ੮ ੦੮'],\n            ['h hh',                               '੩ ੦੩'],\n            ['H HH',                               '੧੫ ੧੫'],\n            ['m mm',                               '੨੫ ੨੫'],\n            ['s ss',                               '੫੦ ੫੦'],\n            ['a A',                                'ਦੁਪਹਿਰ ਦੁਪਹਿਰ'],\n            ['LTS',                                'ਦੁਪਹਿਰ ੩:੨੫:੫੦ ਵਜੇ'],\n            ['L',                                  '੧੪/੦੨/੨੦੧੦'],\n            ['LL',                                 '੧੪ ਫ਼ਰਵਰੀ ੨੦੧੦'],\n            ['LLL',                                '੧੪ ਫ਼ਰਵਰੀ ੨੦੧੦, ਦੁਪਹਿਰ ੩:੨੫ ਵਜੇ'],\n            ['LLLL',                               'ਐਤਵਾਰ, ੧੪ ਫ਼ਰਵਰੀ ੨੦੧੦, ਦੁਪਹਿਰ ੩:੨੫ ਵਜੇ'],\n            ['l',                                  '੧੪/੨/੨੦੧੦'],\n            ['ll',                                 '੧੪ ਫ਼ਰਵਰੀ ੨੦੧੦'],\n            ['lll',                                '੧੪ ਫ਼ਰਵਰੀ ੨੦੧੦, ਦੁਪਹਿਰ ੩:੨੫ ਵਜੇ'],\n            ['llll',                               'ਐਤ, ੧੪ ਫ਼ਰਵਰੀ ੨੦੧੦, ਦੁਪਹਿਰ ੩:੨੫ ਵਜੇ']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '੧', '੧');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '੨', '੨');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '੩', '੩');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '੪', '੪');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '੫', '੫');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '੬', '੬');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '੭', '੭');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '੮', '੮');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '੯', '੯');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '੧੦', '੧੦');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '੧੧', '੧੧');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '੧੨', '੧੨');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '੧੩', '੧੩');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '੧੪', '੧੪');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '੧੫', '੧੫');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '੧੬', '੧੬');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '੧੭', '੧੭');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '੧੮', '੧੮');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '੧੯', '੧੯');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '੨੦', '੨੦');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '੨੧', '੨੧');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '੨੨', '੨੨');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '੨੩', '੨੩');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '੨੪', '੨੪');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '੨੫', '੨੫');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '੨੬', '੨੬');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '੨੭', '੨੭');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '੨੮', '੨੮');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '੨੯', '੨੯');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '੩੦', '੩੦');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '੩੧', '੩੧');\n});\n\ntest('format month', function (assert) {\n    var expected = 'ਜਨਵਰੀ ਜਨਵਰੀ_ਫ਼ਰਵਰੀ ਫ਼ਰਵਰੀ_ਮਾਰਚ ਮਾਰਚ_ਅਪ੍ਰੈਲ ਅਪ੍ਰੈਲ_ਮਈ ਮਈ_ਜੂਨ ਜੂਨ_ਜੁਲਾਈ ਜੁਲਾਈ_ਅਗਸਤ ਅਗਸਤ_ਸਤੰਬਰ ਸਤੰਬਰ_ਅਕਤੂਬਰ ਅਕਤੂਬਰ_ਨਵੰਬਰ ਨਵੰਬਰ_ਦਸੰਬਰ ਦਸੰਬਰ'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'ਐਤਵਾਰ ਐਤ ਐਤ_ਸੋਮਵਾਰ ਸੋਮ ਸੋਮ_ਮੰਗਲਵਾਰ ਮੰਗਲ ਮੰਗਲ_ਬੁਧਵਾਰ ਬੁਧ ਬੁਧ_ਵੀਰਵਾਰ ਵੀਰ ਵੀਰ_ਸ਼ੁੱਕਰਵਾਰ ਸ਼ੁਕਰ ਸ਼ੁਕਰ_ਸ਼ਨੀਚਰਵਾਰ ਸ਼ਨੀ ਸ਼ਨੀ'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'ਕੁਝ ਸਕਿੰਟ', '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'ਇਕ ਮਿੰਟ',      '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'ਇਕ ਮਿੰਟ',      '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '੨ ਮਿੰਟ',     '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '੪੪ ਮਿੰਟ',    '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'ਇੱਕ ਘੰਟਾ',       '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'ਇੱਕ ਘੰਟਾ',       '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '੨ ਘੰਟੇ',       '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '੫ ਘੰਟੇ',       '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '੨੧ ਘੰਟੇ',      '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'ਇੱਕ ਦਿਨ',         '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'ਇੱਕ ਦਿਨ',         '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '੨ ਦਿਨ',        '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'ਇੱਕ ਦਿਨ',         '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '੫ ਦਿਨ',        '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '੨੫ ਦਿਨ',       '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'ਇੱਕ ਮਹੀਨਾ',       '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'ਇੱਕ ਮਹੀਨਾ',       '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'ਇੱਕ ਮਹੀਨਾ',       '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '੨ ਮਹੀਨੇ',      '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '੨ ਮਹੀਨੇ',      '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '੩ ਮਹੀਨੇ',      '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'ਇੱਕ ਮਹੀਨਾ',       '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '੫ ਮਹੀਨੇ',      '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'ਇੱਕ ਸਾਲ',        '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '੨ ਸਾਲ',       '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'ਇੱਕ ਸਾਲ',        '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '੫ ਸਾਲ',       '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'ਕੁਝ ਸਕਿੰਟ ਵਿੱਚ',  'prefix');\n    assert.equal(moment(0).from(30000), 'ਕੁਝ ਸਕਿੰਟ ਪਿਛਲੇ', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'ਕੁਝ ਸਕਿੰਟ ਪਿਛਲੇ',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'ਕੁਝ ਸਕਿੰਟ ਵਿੱਚ', 'ਕੁਝ ਸਕਿੰਟ ਵਿੱਚ');\n    assert.equal(moment().add({d: 5}).fromNow(), '੫ ਦਿਨ ਵਿੱਚ', '੫ ਦਿਨ ਵਿੱਚ');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'ਅਜ ਦੁਪਹਿਰ ੧੨:੦੦ ਵਜੇ',  'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'ਅਜ ਦੁਪਹਿਰ ੧੨:੨੫ ਵਜੇ',  'Now plus 25 min');\n    assert.equal(moment(a).add({h: 3}).calendar(),       'ਅਜ ਦੁਪਹਿਰ ੩:੦੦ ਵਜੇ',   'Now plus 3 hours');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'ਕਲ ਦੁਪਹਿਰ ੧੨:੦੦ ਵਜੇ',  'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'ਅਜ ਦੁਪਹਿਰ ੧੧:੦੦ ਵਜੇ',  'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'ਕਲ ਦੁਪਹਿਰ ੧੨:੦੦ ਵਜੇ',  'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('dddd[,] LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd[,] LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd[,] LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('[ਪਿਛਲੇ] dddd[,] LT'),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[ਪਿਛਲੇ] dddd[,] LT'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[ਪਿਛਲੇ] dddd[,] LT'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('meridiem invariant', function (assert) {\n    assert.equal(moment([2011, 2, 23,  2, 30]).format('a'), 'ਰਾਤ', 'before dawn');\n    assert.equal(moment([2011, 2, 23,  9, 30]).format('a'), 'ਸਵੇਰ', 'morning');\n    assert.equal(moment([2011, 2, 23, 14, 30]).format('a'), 'ਦੁਪਹਿਰ', 'during day');\n    assert.equal(moment([2011, 2, 23, 17, 30]).format('a'), 'ਸ਼ਾਮ', 'evening');\n    assert.equal(moment([2011, 2, 23, 19, 30]).format('a'), 'ਸ਼ਾਮ', 'late evening');\n    assert.equal(moment([2011, 2, 23, 21, 20]).format('a'), 'ਰਾਤ', 'night');\n\n    assert.equal(moment([2011, 2, 23,  2, 30]).format('A'), 'ਰਾਤ', 'before dawn');\n    assert.equal(moment([2011, 2, 23,  9, 30]).format('A'), 'ਸਵੇਰ', 'morning');\n    assert.equal(moment([2011, 2, 23, 14, 30]).format('A'), 'ਦੁਪਹਿਰ', ' during day');\n    assert.equal(moment([2011, 2, 23, 17, 30]).format('A'), 'ਸ਼ਾਮ', 'evening');\n    assert.equal(moment([2011, 2, 23, 19, 30]).format('A'), 'ਸ਼ਾਮ', 'late evening');\n    assert.equal(moment([2011, 2, 23, 21, 20]).format('A'), 'ਰਾਤ', 'night');\n});\n\ntest('weeks year starting sunday', function (assert) {\n    assert.equal(moment([2012, 0,  1]).week(), 1, 'Jan  1 2012 should be week 1');\n    assert.equal(moment([2012, 0,  7]).week(), 1, 'Jan  7 2012 should be week 1');\n    assert.equal(moment([2012, 0,  8]).week(), 2, 'Jan  8 2012 should be week 2');\n    assert.equal(moment([2012, 0, 14]).week(), 2, 'Jan 14 2012 should be week 2');\n    assert.equal(moment([2012, 0, 15]).week(), 3, 'Jan 15 2012 should be week 3');\n});\n\ntest('weeks year starting monday', function (assert) {\n    assert.equal(moment([2006, 11, 31]).week(), 1, 'Dec 31 2006 should be week 1');\n    assert.equal(moment([2007,  0,  1]).week(), 1, 'Jan  1 2007 should be week 1');\n    assert.equal(moment([2007,  0,  6]).week(), 1, 'Jan  6 2007 should be week 1');\n    assert.equal(moment([2007,  0,  7]).week(), 2, 'Jan  7 2007 should be week 2');\n    assert.equal(moment([2007,  0, 13]).week(), 2, 'Jan 13 2007 should be week 2');\n    assert.equal(moment([2007,  0, 14]).week(), 3, 'Jan 14 2007 should be week 3');\n});\n\ntest('weeks year starting tuesday', function (assert) {\n    assert.equal(moment([2007, 11, 29]).week(), 52, 'Dec 29 2007 should be week 52');\n    assert.equal(moment([2008,  0,  1]).week(), 1, 'Jan  1 2008 should be week 1');\n    assert.equal(moment([2008,  0,  5]).week(), 1, 'Jan  5 2008 should be week 1');\n    assert.equal(moment([2008,  0,  6]).week(), 2, 'Jan  6 2008 should be week 2');\n    assert.equal(moment([2008,  0, 12]).week(), 2, 'Jan 12 2008 should be week 2');\n    assert.equal(moment([2008,  0, 13]).week(), 3, 'Jan 13 2008 should be week 3');\n});\n\ntest('weeks year starting wednesday', function (assert) {\n    assert.equal(moment([2002, 11, 29]).week(), 1, 'Dec 29 2002 should be week 1');\n    assert.equal(moment([2003,  0,  1]).week(), 1, 'Jan  1 2003 should be week 1');\n    assert.equal(moment([2003,  0,  4]).week(), 1, 'Jan  4 2003 should be week 1');\n    assert.equal(moment([2003,  0,  5]).week(), 2, 'Jan  5 2003 should be week 2');\n    assert.equal(moment([2003,  0, 11]).week(), 2, 'Jan 11 2003 should be week 2');\n    assert.equal(moment([2003,  0, 12]).week(), 3, 'Jan 12 2003 should be week 3');\n});\n\ntest('weeks year starting thursday', function (assert) {\n    assert.equal(moment([2008, 11, 28]).week(), 1, 'Dec 28 2008 should be week 1');\n    assert.equal(moment([2009,  0,  1]).week(), 1, 'Jan  1 2009 should be week 1');\n    assert.equal(moment([2009,  0,  3]).week(), 1, 'Jan  3 2009 should be week 1');\n    assert.equal(moment([2009,  0,  4]).week(), 2, 'Jan  4 2009 should be week 2');\n    assert.equal(moment([2009,  0, 10]).week(), 2, 'Jan 10 2009 should be week 2');\n    assert.equal(moment([2009,  0, 11]).week(), 3, 'Jan 11 2009 should be week 3');\n});\n\ntest('weeks year starting friday', function (assert) {\n    assert.equal(moment([2009, 11, 27]).week(), 1, 'Dec 27 2009 should be week 1');\n    assert.equal(moment([2010,  0,  1]).week(), 1, 'Jan  1 2010 should be week 1');\n    assert.equal(moment([2010,  0,  2]).week(), 1, 'Jan  2 2010 should be week 1');\n    assert.equal(moment([2010,  0,  3]).week(), 2, 'Jan  3 2010 should be week 2');\n    assert.equal(moment([2010,  0,  9]).week(), 2, 'Jan  9 2010 should be week 2');\n    assert.equal(moment([2010,  0, 10]).week(), 3, 'Jan 10 2010 should be week 3');\n});\n\ntest('weeks year starting saturday', function (assert) {\n    assert.equal(moment([2010, 11, 26]).week(), 1, 'Dec 26 2010 should be week 1');\n    assert.equal(moment([2011,  0,  1]).week(), 1, 'Jan  1 2011 should be week 1');\n    assert.equal(moment([2011,  0,  2]).week(), 2, 'Jan  2 2011 should be week 2');\n    assert.equal(moment([2011,  0,  8]).week(), 2, 'Jan  8 2011 should be week 2');\n    assert.equal(moment([2011,  0,  9]).week(), 3, 'Jan  9 2011 should be week 3');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2012, 0,  1]).format('w ww wo'), '੧ ੦੧ ੧', 'Jan  1 2012 should be week 1');\n    assert.equal(moment([2012, 0,  7]).format('w ww wo'), '੧ ੦੧ ੧', 'Jan  7 2012 should be week 1');\n    assert.equal(moment([2012, 0,  8]).format('w ww wo'), '੨ ੦੨ ੨', 'Jan  8 2012 should be week 2');\n    assert.equal(moment([2012, 0, 14]).format('w ww wo'), '੨ ੦੨ ੨', 'Jan 14 2012 should be week 2');\n    assert.equal(moment([2012, 0, 15]).format('w ww wo'), '੩ ੦੩ ੩', 'Jan 15 2012 should be week 3');\n});\n\ntest('lenient day of month ordinal parsing', function (assert) {\n    var i, ordinalStr, testMoment;\n    for (i = 1; i <= 31; ++i) {\n        ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n        testMoment = moment(ordinalStr, 'YYYY MM Do');\n        assert.equal(testMoment.year(), 2014,\n                'lenient day of month ordinal parsing ' + i + ' year check');\n        assert.equal(testMoment.month(), 0,\n                'lenient day of month ordinal parsing ' + i + ' month check');\n        assert.equal(testMoment.date(), i,\n                'lenient day of month ordinal parsing ' + i + ' date check');\n    }\n});\n\ntest('lenient day of month ordinal parsing of number', function (assert) {\n    var i, testMoment;\n    for (i = 1; i <= 31; ++i) {\n        testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n        assert.equal(testMoment.year(), 2014,\n                'lenient day of month ordinal parsing of number ' + i + ' year check');\n        assert.equal(testMoment.month(), 0,\n                'lenient day of month ordinal parsing of number ' + i + ' month check');\n        assert.equal(testMoment.date(), i,\n                'lenient day of month ordinal parsing of number ' + i + ' date check');\n    }\n});\n\ntest('strict day of month ordinal parsing', function (assert) {\n    var i, ordinalStr, testMoment;\n    for (i = 1; i <= 31; ++i) {\n        ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n        testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n        assert.ok(testMoment.isValid(), 'strict day of month ordinal parsing ' + i);\n    }\n});\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/test/locale/pl.js",
    "content": "import {localeModule, test} from '../qunit';\nimport moment from '../../moment';\nlocaleModule('pl');\n\ntest('parse', function (assert) {\n    var tests = 'styczeń stycznia sty_luty lutego lut_marzec marca mar_kwiecień kwietnia kwi_maj maja maj_czerwiec czerwca cze_lipiec lipca lip_sierpień sierpnia sie_wrzesień września wrz_październik października paź_listopad listopada lis_grudzień grudnia gru'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][2], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][2], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][2].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][2].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('parse strict', function (assert) {\n    var tests = 'styczeń stycznia sty_luty lutego lut_marzec marca mar_kwiecień kwietnia kwi_maj maja maj_czerwiec czerwca cze_lipiec lipca lip_sierpień sierpnia sie_wrzesień września wrz_październik października paź_listopad listopada lis_grudzień grudnia gru'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm, true).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][2], 'MMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][2].toLocaleLowerCase(), 'MMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][2].toLocaleUpperCase(), 'MMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, MMMM Do YYYY, h:mm:ss a',      'niedziela, luty 14. 2010, 3:25:50 pm'],\n            ['ddd, hA',                            'ndz, 3PM'],\n            ['M Mo MM MMMM MMM',                   '2 2. 02 luty lut'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14. 14'],\n            ['d do dddd ddd dd',                   '0 0. niedziela ndz Nd'],\n            ['DDD DDDo DDDD',                      '45 45. 045'],\n            ['w wo ww',                            '6 6. 06'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'pm PM'],\n            ['[the] DDDo [day of the year]',       'the 45. day of the year'],\n            ['LTS',                                '15:25:50'],\n            ['L',                                  '14.02.2010'],\n            ['LL',                                 '14 lutego 2010'],\n            ['LLL',                                '14 lutego 2010 15:25'],\n            ['LLLL',                               'niedziela, 14 lutego 2010 15:25'],\n            ['l',                                  '14.2.2010'],\n            ['ll',                                 '14 lut 2010'],\n            ['lll',                                '14 lut 2010 15:25'],\n            ['llll',                               'ndz, 14 lut 2010 15:25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1.', '1.');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2.', '2.');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3.', '3.');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4.', '4.');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5.', '5.');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6.', '6.');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7.', '7.');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8.', '8.');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9.', '9.');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10.', '10.');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11.', '11.');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12.', '12.');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13.', '13.');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14.', '14.');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15.', '15.');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16.', '16.');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17.', '17.');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18.', '18.');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19.', '19.');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20.', '20.');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21.', '21.');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22.', '22.');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23.', '23.');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24.', '24.');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25.', '25.');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26.', '26.');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27.', '27.');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28.', '28.');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29.', '29.');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30.', '30.');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31.', '31.');\n});\n\ntest('format month', function (assert) {\n    var expected = 'styczeń sty_luty lut_marzec mar_kwiecień kwi_maj maj_czerwiec cze_lipiec lip_sierpień sie_wrzesień wrz_październik paź_listopad lis_grudzień gru'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'niedziela ndz Nd_poniedziałek pon Pn_wtorek wt Wt_środa śr Śr_czwartek czw Cz_piątek pt Pt_sobota sob So'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'kilka sekund',  '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'minuta',        '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'minuta',        '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 minuty',      '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 minuty',     '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'godzina',       '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'godzina',       '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 godziny',     '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 godzin',      '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 godzin',     '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  '1 dzień',       '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  '1 dzień',       '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 dni',         '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   '1 dzień',       '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 dni',         '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 dni',        '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'miesiąc',       '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'miesiąc',       '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'miesiąc',       '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 miesiące',    '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 miesiące',    '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 miesiące',    '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'miesiąc',       '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 miesięcy',    '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'rok',           '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 lata',        '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'rok',           '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 lat',         '5 years = 5 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 112}), true), '112 lat',       '112 years = 112 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 122}), true), '122 lata',      '122 years = 122 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 213}), true), '213 lat',       '213 years = 213 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 223}), true), '223 lata',      '223 years = 223 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'za kilka sekund',  'prefix');\n    assert.equal(moment(0).from(30000), 'kilka sekund temu', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'kilka sekund temu',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'za kilka sekund', 'in a few seconds');\n    assert.equal(moment().add({h: 1}).fromNow(), 'za godzinę', 'in an hour');\n    assert.equal(moment().add({d: 5}).fromNow(), 'za 5 dni', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'Dziś o 12:00',    'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'Dziś o 12:25',    'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'Dziś o 13:00',    'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'Jutro o 12:00',   'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'Dziś o 11:00',    'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'Wczoraj o 12:00', 'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('[W] dddd [o] LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[W] dddd [o] LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[W] dddd [o] LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n\n    function makeFormat(d) {\n        switch (d.day()) {\n            case 0:\n                return '[W zeszłą niedzielę o] LT';\n            case 3:\n                return '[W zeszłą środę o] LT';\n            case 6:\n                return '[W zeszłą sobotę o] LT';\n            default:\n                return '[W zeszły] dddd [o] LT';\n        }\n    }\n\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(), m.format(makeFormat(m)), 'Today - ' + i + ' days current time');\n\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(), m.format(makeFormat(m)), 'Today - ' + i + ' days beginning of day');\n\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(), m.format(makeFormat(m)), 'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2012, 0,  1]).format('w ww wo'), '52 52 52.', 'Jan  1 2012 should be week 52');\n    assert.equal(moment([2012, 0,  2]).format('w ww wo'),   '1 01 1.', 'Jan  2 2012 should be week 1');\n    assert.equal(moment([2012, 0,  8]).format('w ww wo'),   '1 01 1.', 'Jan  8 2012 should be week 1');\n    assert.equal(moment([2012, 0,  9]).format('w ww wo'),   '2 02 2.', 'Jan  9 2012 should be week 2');\n    assert.equal(moment([2012, 0, 15]).format('w ww wo'),   '2 02 2.', 'Jan 15 2012 should be week 2');\n});\n\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/test/locale/pt-br.js",
    "content": "import {localeModule, test} from '../qunit';\nimport moment from '../../moment';\nlocaleModule('pt-br');\n\ntest('parse', function (assert) {\n    var tests = 'janeiro jan_fevereiro fev_março mar_abril abr_maio mai_junho jun_julho jul_agosto ago_setembro set_outubro out_novembro nov_dezembro dez'.split('_'), i;\n\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, MMMM Do YYYY, h:mm:ss a',      'Domingo, Fevereiro 14º 2010, 3:25:50 pm'],\n            ['ddd, hA',                            'Dom, 3PM'],\n            ['M Mo MM MMMM MMM',                   '2 2º 02 Fevereiro Fev'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14º 14'],\n            ['d do dddd ddd',                      '0 0º Domingo Dom'],\n            ['DDD DDDo DDDD',                      '45 45º 045'],\n            ['w wo ww',                            '8 8º 08'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'pm PM'],\n            ['[the] DDDo [day of the year]',       'the 45º day of the year'],\n            ['LTS',                                '15:25:50'],\n            ['L',                                  '14/02/2010'],\n            ['LL',                                 '14 de Fevereiro de 2010'],\n            ['LLL',                                '14 de Fevereiro de 2010 às 15:25'],\n            ['LLLL',                               'Domingo, 14 de Fevereiro de 2010 às 15:25'],\n            ['l',                                  '14/2/2010'],\n            ['ll',                                 '14 de Fev de 2010'],\n            ['lll',                                '14 de Fev de 2010 às 15:25'],\n            ['llll',                               'Dom, 14 de Fev de 2010 às 15:25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1º', '1º');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2º', '2º');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3º', '3º');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4º', '4º');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5º', '5º');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6º', '6º');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7º', '7º');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8º', '8º');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9º', '9º');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10º', '10º');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11º', '11º');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12º', '12º');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13º', '13º');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14º', '14º');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15º', '15º');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16º', '16º');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17º', '17º');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18º', '18º');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19º', '19º');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20º', '20º');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21º', '21º');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22º', '22º');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23º', '23º');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24º', '24º');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25º', '25º');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26º', '26º');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27º', '27º');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28º', '28º');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29º', '29º');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30º', '30º');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31º', '31º');\n});\n\ntest('format month', function (assert) {\n    var expected = 'Janeiro Jan_Fevereiro Fev_Março Mar_Abril Abr_Maio Mai_Junho Jun_Julho Jul_Agosto Ago_Setembro Set_Outubro Out_Novembro Nov_Dezembro Dez'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'Domingo Dom Do_Segunda-feira Seg 2ª_Terça-feira Ter 3ª_Quarta-feira Qua 4ª_Quinta-feira Qui 5ª_Sexta-feira Sex 6ª_Sábado Sáb Sá'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'poucos segundos', '44 seconds = seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'um minuto',   '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'um minuto',   '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 minutos',  '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 minutos', '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'uma hora',    '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'uma hora',    '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 horas',    '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 horas',    '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 horas',   '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'um dia',      '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'um dia',      '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 dias',     '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'um dia',      '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 dias',     '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 dias',    '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'um mês',    '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'um mês',    '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'um mês',    '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 meses',   '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 meses',   '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 meses',   '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'um mês',    '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 meses',   '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'um ano',     '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 anos',    '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'um ano',     '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 anos',    '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'em poucos segundos', 'prefix');\n    assert.equal(moment(0).from(30000), 'poucos segundos atrás', 'suffix');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'em poucos segundos', 'in seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), 'em 5 dias', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'Hoje às 12:00',    'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'Hoje às 12:25',    'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'Hoje às 13:00',    'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'Amanhã às 12:00',  'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'Hoje às 11:00',    'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'Ontem às 12:00',   'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('dddd [às] LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd [às] LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd [às] LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format((m.day() === 0 || m.day() === 6) ? '[Último] dddd [às] LT' : '[Última] dddd [às] LT'),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format((m.day() === 0 || m.day() === 6) ? '[Último] dddd [às] LT' : '[Última] dddd [às] LT'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format((m.day() === 0 || m.day() === 6) ? '[Último] dddd [às] LT' : '[Última] dddd [às] LT'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('weeks year starting sunday format', function (assert) {\n    assert.equal(moment([2012, 0,  1]).format('w ww wo'), '1 01 1º', 'Jan  1 2012 should be week 1');\n    assert.equal(moment([2012, 0,  7]).format('w ww wo'), '1 01 1º', 'Jan  7 2012 should be week 1');\n    assert.equal(moment([2012, 0,  8]).format('w ww wo'), '2 02 2º', 'Jan  8 2012 should be week 2');\n    assert.equal(moment([2012, 0, 14]).format('w ww wo'), '2 02 2º', 'Jan 14 2012 should be week 2');\n    assert.equal(moment([2012, 0, 15]).format('w ww wo'), '3 03 3º', 'Jan 15 2012 should be week 3');\n});\n\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/test/locale/pt.js",
    "content": "import {localeModule, test} from '../qunit';\nimport moment from '../../moment';\nlocaleModule('pt');\n\ntest('parse', function (assert) {\n    var tests = 'Janeiro Jan_Fevereiro Fev_Março Mar_Abril Abr_Maio Mai_Junho Jun_Julho Jul_Agosto Ago_Setembro Set_Outubro Out_Novembro Nov_Dezembro Dez'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, MMMM Do YYYY, h:mm:ss a',      'Domingo, Fevereiro 14º 2010, 3:25:50 pm'],\n            ['ddd, hA',                            'Dom, 3PM'],\n            ['M Mo MM MMMM MMM',                   '2 2º 02 Fevereiro Fev'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14º 14'],\n            ['d do dddd ddd',                      '0 0º Domingo Dom'],\n            ['DDD DDDo DDDD',                      '45 45º 045'],\n            ['w wo ww',                            '6 6º 06'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'pm PM'],\n            ['[the] DDDo [day of the year]',       'the 45º day of the year'],\n            ['LTS',                                '15:25:50'],\n            ['L',                                  '14/02/2010'],\n            ['LL',                                 '14 de Fevereiro de 2010'],\n            ['LLL',                                '14 de Fevereiro de 2010 15:25'],\n            ['LLLL',                               'Domingo, 14 de Fevereiro de 2010 15:25'],\n            ['l',                                  '14/2/2010'],\n            ['ll',                                 '14 de Fev de 2010'],\n            ['lll',                                '14 de Fev de 2010 15:25'],\n            ['llll',                               'Dom, 14 de Fev de 2010 15:25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1º', '1º');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2º', '2º');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3º', '3º');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4º', '4º');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5º', '5º');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6º', '6º');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7º', '7º');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8º', '8º');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9º', '9º');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10º', '10º');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11º', '11º');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12º', '12º');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13º', '13º');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14º', '14º');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15º', '15º');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16º', '16º');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17º', '17º');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18º', '18º');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19º', '19º');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20º', '20º');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21º', '21º');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22º', '22º');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23º', '23º');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24º', '24º');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25º', '25º');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26º', '26º');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27º', '27º');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28º', '28º');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29º', '29º');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30º', '30º');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31º', '31º');\n});\n\ntest('format month', function (assert) {\n    var expected = 'Janeiro Jan_Fevereiro Fev_Março Mar_Abril Abr_Maio Mai_Junho Jun_Julho Jul_Agosto Ago_Setembro Set_Outubro Out_Novembro Nov_Dezembro Dez'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'Domingo Dom Do_Segunda-Feira Seg 2ª_Terça-Feira Ter 3ª_Quarta-Feira Qua 4ª_Quinta-Feira Qui 5ª_Sexta-Feira Sex 6ª_Sábado Sáb Sá'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'segundos',    '44 seconds = seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'um minuto',   '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'um minuto',   '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 minutos',  '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 minutos', '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'uma hora',    '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'uma hora',    '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 horas',    '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 horas',    '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 horas',   '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'um dia',      '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'um dia',      '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 dias',     '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'um dia',      '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 dias',     '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 dias',    '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'um mês',    '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'um mês',    '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'um mês',    '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 meses',   '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 meses',   '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 meses',   '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'um mês',    '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 meses',   '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'um ano',     '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 anos',    '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'um ano',     '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 anos',    '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'em segundos', 'prefix');\n    assert.equal(moment(0).from(30000), 'há segundos', 'suffix');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'em segundos', 'in seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), 'em 5 dias', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'Hoje às 12:00',    'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'Hoje às 12:25',    'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'Hoje às 13:00',    'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'Amanhã às 12:00',  'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'Hoje às 11:00',    'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'Ontem às 12:00',   'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('dddd [às] LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd [às] LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd [às] LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format((m.day() === 0 || m.day() === 6) ? '[Último] dddd [às] LT' : '[Última] dddd [às] LT'),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format((m.day() === 0 || m.day() === 6) ? '[Último] dddd [às] LT' : '[Última] dddd [às] LT'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format((m.day() === 0 || m.day() === 6) ? '[Último] dddd [às] LT' : '[Última] dddd [às] LT'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2012, 0,  1]).format('w ww wo'), '52 52 52º', 'Jan  1 2012 should be week 52');\n    assert.equal(moment([2012, 0,  2]).format('w ww wo'),  '1 01 1º', 'Jan  2 2012 should be week 1');\n    assert.equal(moment([2012, 0,  8]).format('w ww wo'),  '1 01 1º', 'Jan  8 2012 should be week 1');\n    assert.equal(moment([2012, 0,  9]).format('w ww wo'),  '2 02 2º', 'Jan  9 2012 should be week 2');\n    assert.equal(moment([2012, 0, 15]).format('w ww wo'),  '2 02 2º', 'Jan 15 2012 should be week 2');\n});\n\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/test/locale/ro.js",
    "content": "import {localeModule, test} from '../qunit';\nimport moment from '../../moment';\nlocaleModule('ro');\n\ntest('parse', function (assert) {\n    var tests = 'ianuarie ian._februarie febr._martie mart._aprilie apr._mai mai_iunie iun._iulie iul._august aug._septembrie sept._octombrie oct._noiembrie nov._decembrie dec.'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, MMMM Do YYYY, h:mm:ss A',  'duminică, februarie 14 2010, 3:25:50 PM'],\n            ['ddd, hA',                        'Dum, 3PM'],\n            ['M Mo MM MMMM MMM',               '2 2 02 februarie febr.'],\n            ['YYYY YY',                        '2010 10'],\n            ['D Do DD',                        '14 14 14'],\n            ['d do dddd ddd dd',               '0 0 duminică Dum Du'],\n            ['DDD DDDo DDDD',                  '45 45 045'],\n            ['w wo ww',                        '7 7 07'],\n            ['h hh',                           '3 03'],\n            ['H HH',                           '15 15'],\n            ['m mm',                           '25 25'],\n            ['s ss',                           '50 50'],\n            ['a A',                            'pm PM'],\n            ['[a] DDDo[a zi a anului]',        'a 45a zi a anului'],\n            ['LTS',                            '15:25:50'],\n            ['L',                              '14.02.2010'],\n            ['LL',                             '14 februarie 2010'],\n            ['LLL',                            '14 februarie 2010 15:25'],\n            ['LLLL',                           'duminică, 14 februarie 2010 15:25'],\n            ['l',                              '14.2.2010'],\n            ['ll',                             '14 febr. 2010'],\n            ['lll',                            '14 febr. 2010 15:25'],\n            ['llll',                           'Dum, 14 febr. 2010 15:25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1', '1');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2', '2');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3', '3');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4', '4');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5', '5');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6', '6');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7', '7');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8', '8');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9', '9');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10', '10');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11', '11');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12', '12');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13', '13');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14', '14');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15', '15');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16', '16');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17', '17');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18', '18');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19', '19');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20', '20');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21', '21');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22', '22');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23', '23');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24', '24');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25', '25');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26', '26');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27', '27');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28', '28');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29', '29');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30', '30');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31', '31');\n});\n\ntest('format month', function (assert) {\n    var expected = 'ianuarie ian._februarie febr._martie mart._aprilie apr._mai mai_iunie iun._iulie iul._august aug._septembrie sept._octombrie oct._noiembrie nov._decembrie dec.'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'duminică Dum Du_luni Lun Lu_marți Mar Ma_miercuri Mie Mi_joi Joi Jo_vineri Vin Vi_sâmbătă Sâm Sâ'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'câteva secunde', '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'un minut',       '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'un minut',       '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 minute',       '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 de minute',   '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'o oră',          '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'o oră',          '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 ore',          '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 ore',          '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 de ore',      '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'o zi',           '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'o zi',           '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 zile',         '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'o zi',           '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 zile',         '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 de zile',     '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'o lună',         '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'o lună',         '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'o lună',         '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 luni',         '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 luni',         '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 luni',         '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'o lună',         '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 luni',         '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'un an',          '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 ani',          '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'un an',          '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 ani',          '5 years = 5 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 19}), true),   '19 ani',        '19 years = 19 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 20}), true),   '20 de ani',     '20 years = 20 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 100}), true),   '100 de ani',   '100 years = 100 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 101}), true),   '101 ani',      '101 years = 101 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 119}), true),   '119 ani',      '119 years = 119 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 120}), true),   '120 de ani',   '120 years = 120 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 219}), true),   '219 ani',      '219 years = 219 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 220}), true),   '220 de ani',   '220 years = 220 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'peste câteva secunde',   'prefix');\n    assert.equal(moment(0).from(30000), 'câteva secunde în urmă', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'câteva secunde în urmă',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'peste câteva secunde', 'in a few seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), 'peste 5 zile', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'azi la 12:00',     'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'azi la 12:25',     'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'azi la 13:00',     'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'mâine la 12:00',   'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'azi la 11:00',     'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'ieri la 12:00',    'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('dddd [la] LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd [la] LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd [la] LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('[fosta] dddd [la] LT'),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[fosta] dddd [la] LT'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[fosta] dddd [la] LT'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2011, 11, 26]).format('w ww wo'), '1 01 1', 'Dec 26 2011 should be week 1');\n    assert.equal(moment([2012,  0,  1]).format('w ww wo'), '1 01 1', 'Jan  1 2012 should be week 1');\n    assert.equal(moment([2012,  0,  2]).format('w ww wo'), '2 02 2', 'Jan  2 2012 should be week 2');\n    assert.equal(moment([2012,  0,  8]).format('w ww wo'), '2 02 2', 'Jan  8 2012 should be week 2');\n    assert.equal(moment([2012,  0,  9]).format('w ww wo'), '3 03 3', 'Jan  9 2012 should be week 3');\n});\n\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/test/locale/ru.js",
    "content": "import {localeModule, test} from '../qunit';\nimport moment from '../../moment';\nlocaleModule('ru');\n\ntest('parse', function (assert) {\n    var tests = 'январь янв._февраль февр._март март_апрель апр._май май_июнь июнь_июль июль_август авг._сентябрь сент._октябрь окт._ноябрь нояб._декабрь дек.'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    function equalTestStrict(input, mmm, monthIndex) {\n        assert.equal(moment(input, mmm, true).month(), monthIndex, input + ' ' + mmm + ' should be strict month ' + (monthIndex + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n\n        equalTestStrict(tests[i][1], 'MMM', i);\n        equalTestStrict(tests[i][0], 'MMMM', i);\n        equalTestStrict(tests[i][1].toLocaleLowerCase(), 'MMM', i);\n        equalTestStrict(tests[i][1].toLocaleUpperCase(), 'MMM', i);\n        equalTestStrict(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTestStrict(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('parse exceptional case', function (assert) {\n    assert.equal(moment('11 Мая 1989', ['DD MMMM YYYY']).format('DD-MM-YYYY'), '11-05-1989');\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, Do MMMM YYYY, HH:mm:ss',       'воскресенье, 14-го февраля 2010, 15:25:50'],\n            ['ddd, h A',                           'вс, 3 дня'],\n            ['M Mo MM MMMM MMM',                   '2 2-й 02 февраль февр.'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14-го 14'],\n            ['d do dddd ddd dd',                   '0 0-й воскресенье вс вс'],\n            ['DDD DDDo DDDD',                      '45 45-й 045'],\n            ['w wo ww',                            '7 7-я 07'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'дня дня'],\n            ['DDDo [день года]',                   '45-й день года'],\n            ['LTS',                                '15:25:50'],\n            ['L',                                  '14.02.2010'],\n            ['LL',                                 '14 февраля 2010 г.'],\n            ['LLL',                                '14 февраля 2010 г., 15:25'],\n            ['LLLL',                               'воскресенье, 14 февраля 2010 г., 15:25'],\n            ['l',                                  '14.2.2010'],\n            ['ll',                                 '14 февр. 2010 г.'],\n            ['lll',                                '14 февр. 2010 г., 15:25'],\n            ['llll',                               'вс, 14 февр. 2010 г., 15:25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format meridiem', function (assert) {\n    assert.equal(moment([2012, 11, 28, 0, 0]).format('A'), 'ночи', 'night');\n    assert.equal(moment([2012, 11, 28, 3, 59]).format('A'), 'ночи', 'night');\n    assert.equal(moment([2012, 11, 28, 4, 0]).format('A'), 'утра', 'morning');\n    assert.equal(moment([2012, 11, 28, 11, 59]).format('A'), 'утра', 'morning');\n    assert.equal(moment([2012, 11, 28, 12, 0]).format('A'), 'дня', 'afternoon');\n    assert.equal(moment([2012, 11, 28, 16, 59]).format('A'), 'дня', 'afternoon');\n    assert.equal(moment([2012, 11, 28, 17, 0]).format('A'), 'вечера', 'evening');\n    assert.equal(moment([2012, 11, 28, 23, 59]).format('A'), 'вечера', 'evening');\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1-й', '1-й');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2-й', '2-й');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3-й', '3-й');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4-й', '4-й');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5-й', '5-й');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6-й', '6-й');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7-й', '7-й');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8-й', '8-й');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9-й', '9-й');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10-й', '10-й');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11-й', '11-й');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12-й', '12-й');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13-й', '13-й');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14-й', '14-й');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15-й', '15-й');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16-й', '16-й');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17-й', '17-й');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18-й', '18-й');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19-й', '19-й');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20-й', '20-й');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21-й', '21-й');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22-й', '22-й');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23-й', '23-й');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24-й', '24-й');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25-й', '25-й');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26-й', '26-й');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27-й', '27-й');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28-й', '28-й');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29-й', '29-й');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30-й', '30-й');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31-й', '31-й');\n});\n\ntest('format month', function (assert) {\n    var expected = 'январь янв._февраль февр._март март_апрель апр._май май_июнь июнь_июль июль_август авг._сентябрь сент._октябрь окт._ноябрь нояб._декабрь дек.'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format month case', function (assert) {\n    var months = {\n        'nominative': 'январь_февраль_март_апрель_май_июнь_июль_август_сентябрь_октябрь_ноябрь_декабрь'.split('_'),\n        'accusative': 'января_февраля_марта_апреля_мая_июня_июля_августа_сентября_октября_ноября_декабря'.split('_')\n    }, i;\n    for (i = 0; i < 12; i++) {\n        assert.equal(moment([2011, i, 1]).format('D MMMM'), '1 ' + months.accusative[i], '1 ' + months.accusative[i]);\n        assert.equal(moment([2011, i, 1]).format('MMMM'), months.nominative[i], '1 ' + months.nominative[i]);\n    }\n});\n\ntest('format month short case', function (assert) {\n    var monthsShort = {\n        'nominative': 'янв._февр._март_апр._май_июнь_июль_авг._сент._окт._нояб._дек.'.split('_'),\n        'accusative': 'янв._февр._мар._апр._мая_июня_июля_авг._сент._окт._нояб._дек.'.split('_')\n    }, i;\n    for (i = 0; i < 12; i++) {\n        assert.equal(moment([2011, i, 1]).format('D MMM'), '1 ' + monthsShort.accusative[i], '1 ' + monthsShort.accusative[i]);\n        assert.equal(moment([2011, i, 1]).format('MMM'), monthsShort.nominative[i], '1 ' + monthsShort.nominative[i]);\n    }\n});\n\ntest('format month case with escaped symbols', function (assert) {\n    var months = {\n        'nominative': 'январь_февраль_март_апрель_май_июнь_июль_август_сентябрь_октябрь_ноябрь_декабрь'.split('_'),\n        'accusative': 'января_февраля_марта_апреля_мая_июня_июля_августа_сентября_октября_ноября_декабря'.split('_')\n    }, i;\n    for (i = 0; i < 12; i++) {\n        assert.equal(moment([2013, i, 1]).format('D[] MMMM'), '1 ' + months.accusative[i], '1 ' + months.accusative[i]);\n        assert.equal(moment([2013, i, 1]).format('[<i>]D[</i>] [<b>]MMMM[</b>]'), '<i>1</i> <b>' + months.accusative[i] + '</b>', '1 <b>' + months.accusative[i] + '</b>');\n        assert.equal(moment([2013, i, 1]).format('D[-й день] MMMM'), '1-й день ' + months.accusative[i], '1-й день ' + months.accusative[i]);\n        assert.equal(moment([2013, i, 1]).format('D, MMMM'), '1, ' + months.nominative[i], '1, ' + months.nominative[i]);\n    }\n});\n\ntest('format month short case with escaped symbols', function (assert) {\n    var monthsShort = {\n        'nominative': 'янв._февр._март_апр._май_июнь_июль_авг._сент._окт._нояб._дек.'.split('_'),\n        'accusative': 'янв._февр._мар._апр._мая_июня_июля_авг._сент._окт._нояб._дек.'.split('_')\n    }, i;\n    for (i = 0; i < 12; i++) {\n        assert.equal(moment([2013, i, 1]).format('D[] MMM'), '1 ' + monthsShort.accusative[i], '1 ' + monthsShort.accusative[i]);\n        assert.equal(moment([2013, i, 1]).format('[<i>]D[</i>] [<b>]MMM[</b>]'), '<i>1</i> <b>' + monthsShort.accusative[i] + '</b>', '1 <b>' + monthsShort.accusative[i] + '</b>');\n        assert.equal(moment([2013, i, 1]).format('D[-й день] MMM'), '1-й день ' + monthsShort.accusative[i], '1-й день ' + monthsShort.accusative[i]);\n        assert.equal(moment([2013, i, 1]).format('D, MMM'), '1, ' + monthsShort.nominative[i], '1, ' + monthsShort.nominative[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'воскресенье вс вс_понедельник пн пн_вторник вт вт_среда ср ср_четверг чт чт_пятница пт пт_суббота сб сб'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'несколько секунд',    '44 seconds = seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'минута',   '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'минута',   '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 минуты',  '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 31}), true),  '31 минута',  '31 minutes = 31 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 минуты', '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'час',    '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'час',    '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 часа',    '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 часов',    '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 час',   '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'день',      '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'день',      '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 дня',     '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'день',      '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 дней',     '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 11}), true),  '11 дней',     '11 days = 11 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 21}), true),  '21 день',     '21 days = 21 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 дней',    '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'месяц',    '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'месяц',    '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'месяц',    '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 месяца',   '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 месяца',   '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 месяца',   '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'месяц',    '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 месяцев',   '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'год',     '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 года',    '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'год',     '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 лет',    '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'через несколько секунд', 'prefix');\n    assert.equal(moment(0).from(30000), 'несколько секунд назад', 'suffix');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'через несколько секунд', 'in seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), 'через 5 дней', 'in 5 days');\n    assert.equal(moment().add({m: 31}).fromNow(), 'через 31 минуту', 'in 31 minutes = in 31 minutes');\n    assert.equal(moment().subtract({m: 31}).fromNow(), '31 минуту назад', '31 minutes ago = 31 minutes ago');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'Сегодня в 12:00',     'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'Сегодня в 12:25',     'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'Сегодня в 13:00',     'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'Завтра в 12:00',      'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'Сегодня в 11:00',     'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'Вчера в 12:00',       'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m, now;\n\n    function makeFormatNext(d) {\n        switch (d.day()) {\n            case 0:\n                return '[В следующее] dddd [в] LT';\n            case 1:\n            case 2:\n            case 4:\n                return '[В следующий] dddd [в] LT';\n            case 3:\n            case 5:\n            case 6:\n                return '[В следующую] dddd [в] LT';\n        }\n    }\n\n    function makeFormatThis(d) {\n        if (d.day() === 2) {\n            return '[Во] dddd [в] LT';\n        }\n        else {\n            return '[В] dddd [в] LT';\n        }\n    }\n\n    now = moment().startOf('week');\n    for (i = 2; i < 7; i++) {\n        m = moment(now).add({d: i});\n        assert.equal(m.calendar(now),       m.format(makeFormatThis(m)),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(now),       m.format(makeFormatThis(m)),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(now),       m.format(makeFormatThis(m)),  'Today + ' + i + ' days end of day');\n    }\n\n    now = moment().endOf('week');\n    for (i = 2; i < 7; i++) {\n        m = moment(now).add({d: i});\n        assert.equal(m.calendar(now),       m.format(makeFormatNext(m)),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(now),       m.format(makeFormatNext(m)),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(now),       m.format(makeFormatNext(m)),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m, now;\n\n    function makeFormatLast(d) {\n        switch (d.day()) {\n            case 0:\n                return '[В прошлое] dddd [в] LT';\n            case 1:\n            case 2:\n            case 4:\n                return '[В прошлый] dddd [в] LT';\n            case 3:\n            case 5:\n            case 6:\n                return '[В прошлую] dddd [в] LT';\n        }\n    }\n\n    function makeFormatThis(d) {\n        if (d.day() === 2) {\n            return '[Во] dddd [в] LT';\n        }\n        else {\n            return '[В] dddd [в] LT';\n        }\n    }\n\n    now = moment().startOf('week');\n    for (i = 2; i < 7; i++) {\n        m = moment(now).subtract({d: i});\n        assert.equal(m.calendar(now),       m.format(makeFormatLast(m)),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(now),       m.format(makeFormatLast(m)),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(now),       m.format(makeFormatLast(m)),  'Today - ' + i + ' days end of day');\n    }\n\n    now = moment().endOf('week');\n    for (i = 2; i < 7; i++) {\n        m = moment(now).subtract({d: i});\n        assert.equal(m.calendar(now),       m.format(makeFormatThis(m)),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(now),       m.format(makeFormatThis(m)),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(now),       m.format(makeFormatThis(m)),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2011, 11, 26]).format('w ww wo'), '1 01 1-я', 'Dec 26 2011 should be week 1');\n    assert.equal(moment([2012,  0,  1]).format('w ww wo'), '1 01 1-я', 'Jan  1 2012 should be week 1');\n    assert.equal(moment([2012,  0,  2]).format('w ww wo'), '2 02 2-я', 'Jan  2 2012 should be week 2');\n    assert.equal(moment([2012,  0,  8]).format('w ww wo'), '2 02 2-я', 'Jan  8 2012 should be week 2');\n    assert.equal(moment([2012,  0,  9]).format('w ww wo'), '3 03 3-я', 'Jan  9 2012 should be week 3');\n});\n\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/test/locale/sd.js",
    "content": "import {localeModule, test} from '../qunit';\nimport moment from '../../moment';\nlocaleModule('sd');\n\nvar months = [\n    'جنوري',\n    'فيبروري',\n    'مارچ',\n    'اپريل',\n    'مئي',\n    'جون',\n    'جولاءِ',\n    'آگسٽ',\n    'سيپٽمبر',\n    'آڪٽوبر',\n    'نومبر',\n    'ڊسمبر'\n];\nvar days = [\n    'آچر',\n    'سومر',\n    'اڱارو',\n    'اربع',\n    'خميس',\n    'جمع',\n    'ڇنڇر'\n];\n\ntest('parse', function (assert) {\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (var i = 0; i < 12; i++) {\n        equalTest(months[i], 'MMM', i);\n        equalTest(months[i], 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, MMMM Do YYYY, h:mm:ss a',      'آچر، فيبروري 14 2010، 3:25:50 شام'],\n            ['ddd, hA',                            'آچر، 3شام'],\n            ['M Mo MM MMMM MMM',                   '2 2 02 فيبروري فيبروري'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14 14'],\n            ['d do dddd ddd dd',                   '0 0 آچر آچر آچر'],\n            ['DDD DDDo DDDD',                      '45 45 045'],\n            ['w wo ww',                            '6 6 06'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'شام شام'],\n            ['[سال جو] DDDo[ڏينهن]',       'سال جو 45ڏينهن'],\n            ['LTS',                                '15:25:50'],\n            ['L',                                  '14/02/2010'],\n            ['LL',                                 '14 فيبروري 2010'],\n            ['LLL',                                '14 فيبروري 2010 15:25'],\n            ['LLLL',                               'آچر، 14 فيبروري 2010 15:25'],\n            ['l',                                  '14/2/2010'],\n            ['ll',                                 '14 فيبروري 2010'],\n            ['lll',                                '14 فيبروري 2010 15:25'],\n            ['llll',                               'آچر، 14 فيبروري 2010 15:25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1', '1');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2', '2');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3', '3');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4', '4');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5', '5');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6', '6');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7', '7');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8', '8');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9', '9');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10', '10');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11', '11');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12', '12');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13', '13');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14', '14');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15', '15');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16', '16');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17', '17');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18', '18');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19', '19');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20', '20');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21', '21');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22', '22');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23', '23');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24', '24');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25', '25');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26', '26');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27', '27');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28', '28');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29', '29');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30', '30');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31', '31');\n});\n\ntest('format month', function (assert) {\n    for (var i = 0; i < months.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), months[i] + ' ' + months[i], months[i] + ' ' + months[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    for (var i = 0; i < days.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), days[i] + ' ' + days[i] + ' ' + days[i], days[i] + ' ' + days[i] + ' ' + days[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'چند سيڪنڊ', '44 seconds = چند سيڪنڊ');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'هڪ منٽ',      '45 seconds = هڪ منٽ');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'هڪ منٽ',      '89 seconds = هڪ منٽ');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 منٽ',     '90 seconds = 2 منٽ');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 منٽ',    '44 minutes = 44 منٽ');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'هڪ ڪلاڪ',       '45 minutes = هڪ ڪلاڪ');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'هڪ ڪلاڪ',       '89 minutes = هڪ ڪلاڪ');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 ڪلاڪ',       '90 minutes = 2 ڪلاڪ');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 ڪلاڪ',       '5 hours = 5 ڪلاڪ');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 ڪلاڪ',      '21 hours = 21 ڪلاڪ');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'هڪ ڏينهن',         '22 hours = هڪ ڏينهن');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'هڪ ڏينهن',         '35 hours = هڪ ڏينهن');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 ڏينهن',        '36 hours = 2 ڏينهن');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'هڪ ڏينهن',         '1 day = هڪ ڏينهن');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 ڏينهن',        '5 days = 5 ڏينهن');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 ڏينهن',       '25 days = 25 ڏينهن');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'هڪ مهينو',       '26 days = هڪ مهينو');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'هڪ مهينو',       '30 days = هڪ مهينو');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'هڪ مهينو',       '43 days = هڪ مهينو');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 مهينا',      '46 days = 2 مهينا');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 مهينا',      '75 days = 2 مهينا');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 مهينا',      '76 days = 3 مهينا');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'هڪ مهينو',       '1 month = هڪ مهينو');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 مهينا',      '5 months = 5 مهينا');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'هڪ سال',        '345 days = هڪ سال');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 سال',       '548 days = 2 سال');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'هڪ سال',        '1 year = هڪ سال');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 سال',       '5 years = 5 سال');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'چند سيڪنڊ پوء',  'prefix');\n    assert.equal(moment(0).from(30000), 'چند سيڪنڊ اڳ', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'چند سيڪنڊ اڳ',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'چند سيڪنڊ پوء', 'in a few seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), '5 ڏينهن پوء', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'اڄ 12:00',      'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'اڄ 12:25',      'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'اڄ 13:00',      'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'سڀاڻي 12:00',   'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'اڄ 11:00',      'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'ڪالهه 12:00',  'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('dddd [اڳين هفتي تي] LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd [اڳين هفتي تي] LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd [اڳين هفتي تي] LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('[گزريل هفتي] dddd [تي] LT'),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[گزريل هفتي] dddd [تي] LT'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[گزريل هفتي] dddd [تي] LT'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2012, 0,  1]).format('w ww wo'), '52 52 52', 'Jan  1 2012 should be week 52');\n    assert.equal(moment([2012, 0,  2]).format('w ww wo'),   '1 01 1', 'Jan  2 2012 should be week 1');\n    assert.equal(moment([2012, 0,  8]).format('w ww wo'),   '1 01 1', 'Jan  8 2012 should be week 1');\n    assert.equal(moment([2012, 0,  9]).format('w ww wo'),   '2 02 2', 'Jan  9 2012 should be week 2');\n    assert.equal(moment([2012, 0, 15]).format('w ww wo'),   '2 02 2', 'Jan 15 2012 should be week 2');\n});\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/test/locale/se.js",
    "content": "import {localeModule, test} from '../qunit';\nimport moment from '../../moment';\nlocaleModule('se');\n\ntest('parse', function (assert) {\n    var i,\n        tests = 'ođđajagemánnu ođđj_guovvamánnu guov_njukčamánnu njuk_cuoŋománnu cuo_miessemánnu mies_geassemánnu geas_suoidnemánnu suoi_borgemánnu borg_čakčamánnu čakč_golggotmánnu golg_skábmamánnu skáb_juovlamánnu juov'.split('_');\n\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, MMMM Do YYYY, h:mm:ss a',      'sotnabeaivi, guovvamánnu 14. 2010, 3:25:50 pm'],\n            ['ddd, hA',                            'sotn, 3PM'],\n            ['M Mo MM MMMM MMM',                   '2 2. 02 guovvamánnu guov'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14. 14'],\n            ['d do dddd ddd dd',                   '0 0. sotnabeaivi sotn s'],\n            ['DDD DDDo DDDD',                      '45 45. 045'],\n            ['w wo ww',                            '6 6. 06'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'pm PM'],\n            ['[jagi] DDDo [beaivi]',               'jagi 45. beaivi'],\n            ['LTS',                                '15:25:50'],\n            ['L',                                  '14.02.2010'],\n            ['LL',                                 'guovvamánnu 14. b. 2010'],\n            ['LLL',                                'guovvamánnu 14. b. 2010 ti. 15:25'],\n            ['LLLL',                               'sotnabeaivi, guovvamánnu 14. b. 2010 ti. 15:25'],\n            ['l',                                  '14.2.2010'],\n            ['ll',                                 'guov 14. b. 2010'],\n            ['lll',                                'guov 14. b. 2010 ti. 15:25'],\n            ['llll',                               'sotn, guov 14. b. 2010 ti. 15:25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1.', '1.');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2.', '2.');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3.', '3.');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4.', '4.');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5.', '5.');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6.', '6.');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7.', '7.');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8.', '8.');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9.', '9.');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10.', '10.');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11.', '11.');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12.', '12.');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13.', '13.');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14.', '14.');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15.', '15.');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16.', '16.');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17.', '17.');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18.', '18.');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19.', '19.');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20.', '20.');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21.', '21.');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22.', '22.');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23.', '23.');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24.', '24.');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25.', '25.');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26.', '26.');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27.', '27.');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28.', '28.');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29.', '29.');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30.', '30.');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31.', '31.');\n});\n\ntest('format month', function (assert) {\n    var i,\n        expected = 'ođđajagemánnu ođđj_guovvamánnu guov_njukčamánnu njuk_cuoŋománnu cuo_miessemánnu mies_geassemánnu geas_suoidnemánnu suoi_borgemánnu borg_čakčamánnu čakč_golggotmánnu golg_skábmamánnu skáb_juovlamánnu juov'.split('_');\n\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var i,\n        expected = 'sotnabeaivi sotn s_vuossárga vuos v_maŋŋebárga maŋ m_gaskavahkku gask g_duorastat duor d_bearjadat bear b_lávvardat láv L'.split('_');\n\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'moadde sekunddat', '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'okta minuhta',  '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'okta minuhta',  '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 minuhtat',    '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 minuhtat',   '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'okta diimmu',   '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'okta diimmu',   '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 diimmut',     '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 diimmut',     '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 diimmut',    '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'okta beaivi',   '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'okta beaivi',   '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 beaivvit',    '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'okta beaivi',   '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 beaivvit',    '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 beaivvit',   '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'okta mánnu',    '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'okta mánnu',    '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'okta mánnu',    '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 mánut',       '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 mánut',       '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 mánut',       '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'okta mánnu',    '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 mánut',       '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'okta jahki',    '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 jagit',       '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'okta jahki',    '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 jagit',       '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'moadde sekunddat geažes',  'prefix');\n    assert.equal(moment(0).from(30000), 'maŋit moadde sekunddat', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'maŋit moadde sekunddat',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'moadde sekunddat geažes', 'in a few seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), '5 beaivvit geažes', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'otne ti 12:00',     'Today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'otne ti 12:25',     'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'otne ti 13:00',     'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'ihttin ti 12:00',   'Tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'otne ti 11:00',     'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'ikte ti 12:00',     'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('dddd [ti] LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd [ti] LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd [ti] LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('[ovddit] dddd [ti] LT'),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[ovddit] dddd [ti] LT'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[ovddit] dddd [ti] LT'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2012, 0,  1]).format('w ww wo'), '52 52 52.', 'Jan  1 2012 should be week 52');\n    assert.equal(moment([2012, 0,  2]).format('w ww wo'),  '1 01 1.', 'Jan  2 2012 should be week 1');\n    assert.equal(moment([2012, 0,  8]).format('w ww wo'),  '1 01 1.', 'Jan  8 2012 should be week 1');\n    assert.equal(moment([2012, 0,  9]).format('w ww wo'),  '2 02 2.', 'Jan  9 2012 should be week 2');\n    assert.equal(moment([2012, 0, 15]).format('w ww wo'),  '2 02 2.', 'Jan 15 2012 should be week 2');\n});\n\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/test/locale/si.js",
    "content": "import {localeModule, test} from '../qunit';\nimport moment from '../../moment';\nlocaleModule('si');\n\n/*jshint -W100*/\ntest('parse', function (assert) {\n    var tests = 'ජනවාරි ජන_පෙබරවාරි පෙබ_මාර්තු මාර්_අප්‍රේල් අප්_මැයි මැයි_ජූනි ජූනි_ජූලි ජූලි_අගෝස්තු අගෝ_සැප්තැම්බර් සැප්_ඔක්තෝබර් ඔක්_නොවැම්බර් නොවැ_දෙසැම්බර් දෙසැ'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['YYYY MMMM Do dddd, a h:mm:ss',       '2010 පෙබරවාරි 14 වැනි ඉරිදා, ප.ව. 3:25:50'],\n            ['YYYY MMMM Do dddd, a h:mm:ss',       '2010 පෙබරවාරි 14 වැනි ඉරිදා, ප.ව. 3:25:50'],\n            ['ddd, A h',                            'ඉරි, පස් වරු 3'],\n            ['M Mo MM MMMM MMM',                   '2 2 වැනි 02 පෙබරවාරි පෙබ'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14 වැනි 14'],\n            ['d do dddd ddd dd',                   '0 0 වැනි ඉරිදා ඉරි ඉ'],\n            ['DDD DDDo DDDD',                      '45 45 වැනි 045'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'ප.ව. පස් වරු'],\n            ['[වසරේ] DDDo [දිනය]',                      'වසරේ 45 වැනි දිනය'],\n            ['LTS',                                'ප.ව. 3:25:50'],\n            ['LT',                                 'ප.ව. 3:25'],\n            ['L',                                  '2010/02/14'],\n            ['LL',                                 '2010 පෙබරවාරි 14'],\n            ['LLL',                                '2010 පෙබරවාරි 14, ප.ව. 3:25'],\n            ['LLLL',                               '2010 පෙබරවාරි 14 වැනි ඉරිදා, ප.ව. 3:25:50'],\n            ['l',                                  '2010/2/14'],\n            ['ll',                                 '2010 පෙබ 14'],\n            ['lll',                                '2010 පෙබ 14, ප.ව. 3:25'],\n            ['llll',                               '2010 පෙබ 14 වැනි ඉරි, ප.ව. 3:25:50']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1 වැනි', '1 වැනි');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2 වැනි', '2 වැනි');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3 වැනි', '3 වැනි');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4 වැනි', '4 වැනි');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5 වැනි', '5 වැනි');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6 වැනි', '6 වැනි');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7 වැනි', '7 වැනි');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8 වැනි', '8 වැනි');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9 වැනි', '9 වැනි');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10 වැනි', '10 වැනි');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11 වැනි', '11 වැනි');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12 වැනි', '12 වැනි');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13 වැනි', '13 වැනි');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14 වැනි', '14 වැනි');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15 වැනි', '15 වැනි');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16 වැනි', '16 වැනි');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17 වැනි', '17 වැනි');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18 වැනි', '18 වැනි');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19 වැනි', '19 වැනි');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20 වැනි', '20 වැනි');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21 වැනි', '21 වැනි');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22 වැනි', '22 වැනි');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23 වැනි', '23 වැනි');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24 වැනි', '24 වැනි');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25 වැනි', '25 වැනි');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26 වැනි', '26 වැනි');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27 වැනි', '27 වැනි');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28 වැනි', '28 වැනි');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29 වැනි', '29 වැනි');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30 වැනි', '30 වැනි');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31 වැනි', '31 වැනි');\n});\n\ntest('format month', function (assert) {\n    var expected = 'ජනවාරි ජන_පෙබරවාරි පෙබ_මාර්තු මාර්_අප්‍රේල් අප්_මැයි මැයි_ජූනි ජූනි_ජූලි ජූලි_අගෝස්තු අගෝ_සැප්තැම්බර් සැප්_ඔක්තෝබර් ඔක්_නොවැම්බර් නොවැ_දෙසැම්බර් දෙසැ'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'ඉරිදා ඉරි ඉ_සඳුදා සඳු ස_අඟහරුවාදා අඟ අ_බදාදා බදා බ_බ්‍රහස්පතින්දා බ්‍රහ බ්‍ර_සිකුරාදා සිකු සි_සෙනසුරාදා සෙන සෙ'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'තත්පර කිහිපය', '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'මිනිත්තුව',      '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'මිනිත්තුව',      '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  'මිනිත්තු 2',     '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  'මිනිත්තු 44',    '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'පැය',       '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'පැය',       '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  'පැය 2',       '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   'පැය 5',       '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  'පැය 21',      '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'දිනය',         '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'දිනය',         '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  'දින 2',        '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'දිනය',         '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   'දින 5',        '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  'දින 25',       '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'මාසය',       '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'මාසය',       '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'මාසය',       '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  'මාස 2',      '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  'මාස 2',      '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  'මාස 3',      '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'මාසය',       '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   'මාස 5',      '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'වසර',        '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), 'වසර 2',       '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'වසර',        '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   'වසර 5',       '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'තත්පර කිහිපයකින්',  'prefix');\n    assert.equal(moment(0).from(30000), 'තත්පර කිහිපයකට පෙර', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'තත්පර කිහිපයකට පෙර',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'තත්පර කිහිපයකින්', 'in a few seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), 'දින 5කින්', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'අද ප.ව. 12:00ට',     'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'අද ප.ව. 12:25ට',     'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'අද ප.ව. 1:00ට',      'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'හෙට ප.ව. 12:00ට',   'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'අද පෙ.ව. 11:00ට',    'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'ඊයේ ප.ව. 12:00ට',   'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('dddd LT[ට]'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd LT[ට]'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd LT[ට]'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('[පසුගිය] dddd LT[ට]'),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[පසුගිය] dddd LT[ට]'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[පසුගිය] dddd LT[ට]'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/test/locale/sk.js",
    "content": "import {localeModule, test} from '../qunit';\nimport moment from '../../moment';\nlocaleModule('sk');\n\ntest('parse', function (assert) {\n    var tests = 'január jan._február feb._marec mar._apríl apr._máj máj_jún jún._júl júl._august aug._september sep._október okt._november nov._december dec.'.split('_'), i;\n    function equalTest(input, mmm, monthIndex) {\n        assert.equal(moment(input, mmm).month(), monthIndex, input + ' should be month ' + (monthIndex + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, MMMM Do YYYY, h:mm:ss',  'nedeľa, február 14. 2010, 3:25:50'],\n            ['ddd, h',                       'ne, 3'],\n            ['M Mo MM MMMM MMM',             '2 2. 02 február feb'],\n            ['YYYY YY',                      '2010 10'],\n            ['D Do DD',                      '14 14. 14'],\n            ['d do dddd ddd dd',             '0 0. nedeľa ne ne'],\n            ['DDD DDDo DDDD',                '45 45. 045'],\n            ['w wo ww',                      '6 6. 06'],\n            ['h hh',                         '3 03'],\n            ['H HH',                         '15 15'],\n            ['m mm',                         '25 25'],\n            ['s ss',                         '50 50'],\n            ['a A',                          'pm PM'],\n            ['DDDo [deň v roku]',            '45. deň v roku'],\n            ['LTS',                          '15:25:50'],\n            ['L',                            '14.02.2010'],\n            ['LL',                           '14. február 2010'],\n            ['LLL',                          '14. február 2010 15:25'],\n            ['LLLL',                         'nedeľa 14. február 2010 15:25'],\n            ['l',                            '14.2.2010'],\n            ['ll',                           '14. feb 2010'],\n            ['lll',                          '14. feb 2010 15:25'],\n            ['llll',                         'ne 14. feb 2010 15:25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1.', '1.');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2.', '2.');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3.', '3.');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4.', '4.');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5.', '5.');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6.', '6.');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7.', '7.');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8.', '8.');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9.', '9.');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10.', '10.');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11.', '11.');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12.', '12.');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13.', '13.');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14.', '14.');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15.', '15.');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16.', '16.');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17.', '17.');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18.', '18.');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19.', '19.');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20.', '20.');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21.', '21.');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22.', '22.');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23.', '23.');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24.', '24.');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25.', '25.');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26.', '26.');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27.', '27.');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28.', '28.');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29.', '29.');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30.', '30.');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31.', '31.');\n});\n\ntest('format month', function (assert) {\n    var expected = 'január jan_február feb_marec mar_apríl apr_máj máj_jún jún_júl júl_august aug_september sep_október okt_november nov_december dec'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'nedeľa ne ne_pondelok po po_utorok ut ut_streda st st_štvrtok št št_piatok pi pi_sobota so so'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'pár sekúnd',  '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'minúta',        '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'minúta',        '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 minúty',      '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 minút',     '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'hodina',       '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'hodina',       '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 hodiny',     '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 hodín',      '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 hodín',     '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'deň',       '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'deň',       '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 dni',         '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'deň',       '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 dní',         '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 dní',        '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'mesiac',       '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'mesiac',       '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'mesiac',       '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 mesiace',    '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 mesiace',    '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 mesiace',    '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'mesiac',       '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 mesiacov',    '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'rok',           '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 roky',        '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'rok',           '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 rokov',         '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'za pár sekúnd',  'prefix');\n    assert.equal(moment(0).from(30000), 'pred pár sekundami', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'pred pár sekundami',  'now from now should display as in the past');\n});\n\ntest('fromNow (future)', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'za pár sekúnd', 'in a few seconds');\n    assert.equal(moment().add({m: 1}).fromNow(), 'za minútu', 'in a minute');\n    assert.equal(moment().add({m: 3}).fromNow(), 'za 3 minúty', 'in 3 minutes');\n    assert.equal(moment().add({m: 10}).fromNow(), 'za 10 minút', 'in 10 minutes');\n    assert.equal(moment().add({h: 1}).fromNow(), 'za hodinu', 'in an hour');\n    assert.equal(moment().add({h: 3}).fromNow(), 'za 3 hodiny', 'in 3 hours');\n    assert.equal(moment().add({h: 10}).fromNow(), 'za 10 hodín', 'in 10 hours');\n    assert.equal(moment().add({d: 1}).fromNow(), 'za deň', 'in a day');\n    assert.equal(moment().add({d: 3}).fromNow(), 'za 3 dni', 'in 3 days');\n    assert.equal(moment().add({d: 10}).fromNow(), 'za 10 dní', 'in 10 days');\n    assert.equal(moment().add({M: 1}).fromNow(), 'za mesiac', 'in a month');\n    assert.equal(moment().add({M: 3}).fromNow(), 'za 3 mesiace', 'in 3 months');\n    assert.equal(moment().add({M: 10}).fromNow(), 'za 10 mesiacov', 'in 10 months');\n    assert.equal(moment().add({y: 1}).fromNow(), 'za rok', 'in a year');\n    assert.equal(moment().add({y: 3}).fromNow(), 'za 3 roky', 'in 3 years');\n    assert.equal(moment().add({y: 10}).fromNow(), 'za 10 rokov', 'in 10 years');\n});\n\ntest('fromNow (past)', function (assert) {\n    assert.equal(moment().subtract({s: 30}).fromNow(), 'pred pár sekundami', 'a few seconds ago');\n    assert.equal(moment().subtract({m: 1}).fromNow(), 'pred minútou', 'a minute ago');\n    assert.equal(moment().subtract({m: 3}).fromNow(), 'pred 3 minútami', '3 minutes ago');\n    assert.equal(moment().subtract({m: 10}).fromNow(), 'pred 10 minútami', '10 minutes ago');\n    assert.equal(moment().subtract({h: 1}).fromNow(), 'pred hodinou', 'an hour ago');\n    assert.equal(moment().subtract({h: 3}).fromNow(), 'pred 3 hodinami', '3 hours ago');\n    assert.equal(moment().subtract({h: 10}).fromNow(), 'pred 10 hodinami', '10 hours ago');\n    assert.equal(moment().subtract({d: 1}).fromNow(), 'pred dňom', 'a day ago');\n    assert.equal(moment().subtract({d: 3}).fromNow(), 'pred 3 dňami', '3 days ago');\n    assert.equal(moment().subtract({d: 10}).fromNow(), 'pred 10 dňami', '10 days ago');\n    assert.equal(moment().subtract({M: 1}).fromNow(), 'pred mesiacom', 'a month ago');\n    assert.equal(moment().subtract({M: 3}).fromNow(), 'pred 3 mesiacmi', '3 months ago');\n    assert.equal(moment().subtract({M: 10}).fromNow(), 'pred 10 mesiacmi', '10 months ago');\n    assert.equal(moment().subtract({y: 1}).fromNow(), 'pred rokom', 'a year ago');\n    assert.equal(moment().subtract({y: 3}).fromNow(), 'pred 3 rokmi', '3 years ago');\n    assert.equal(moment().subtract({y: 10}).fromNow(), 'pred 10 rokmi', '10 years ago');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'dnes o 12:00',     'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'dnes o 12:25',     'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'dnes o 13:00',     'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'zajtra o 12:00',   'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'dnes o 11:00',     'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'včera o 12:00',    'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m, nextDay;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        nextDay = '';\n        switch (m.day()) {\n            case 0:\n                nextDay = 'v nedeľu';\n                break;\n            case 1:\n                nextDay = 'v pondelok';\n                break;\n            case 2:\n                nextDay = 'v utorok';\n                break;\n            case 3:\n                nextDay = 'v stredu';\n                break;\n            case 4:\n                nextDay = 'vo štvrtok';\n                break;\n            case 5:\n                nextDay = 'v piatok';\n                break;\n            case 6:\n                nextDay = 'v sobotu';\n                break;\n        }\n        assert.equal(m.calendar(),       m.format('[' + nextDay + '] [o] LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[' + nextDay + '] [o] LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[' + nextDay + '] [o] LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m, lastDay;\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        lastDay = '';\n        switch (m.day()) {\n            case 0:\n                lastDay = 'minulú nedeľu';\n                break;\n            case 1:\n                lastDay = 'minulý pondelok';\n                break;\n            case 2:\n                lastDay = 'minulý utorok';\n                break;\n            case 3:\n                lastDay = 'minulú stredu';\n                break;\n            case 4:\n                lastDay = 'minulý štvrtok';\n                break;\n            case 5:\n                lastDay = 'minulý piatok';\n                break;\n            case 6:\n                lastDay = 'minulú sobotu';\n                break;\n        }\n        assert.equal(m.calendar(),       m.format('[' + lastDay + '] [o] LT'),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[' + lastDay + '] [o] LT'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[' + lastDay + '] [o] LT'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('humanize duration', function (assert) {\n    assert.equal(moment.duration(1, 'minutes').humanize(), 'minúta', 'a minute (future)');\n    assert.equal(moment.duration(1, 'minutes').humanize(true), 'za minútu', 'in a minute');\n    assert.equal(moment.duration(-1, 'minutes').humanize(), 'minúta', 'a minute (past)');\n    assert.equal(moment.duration(-1, 'minutes').humanize(true), 'pred minútou', 'a minute ago');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2012, 0,  1]).format('w ww wo'), '52 52 52.', 'Jan  1 2012 should be week 52');\n    assert.equal(moment([2012, 0,  2]).format('w ww wo'),   '1 01 1.', 'Jan  2 2012 should be week 1');\n    assert.equal(moment([2012, 0,  8]).format('w ww wo'),   '1 01 1.', 'Jan  8 2012 should be week 1');\n    assert.equal(moment([2012, 0,  9]).format('w ww wo'),   '2 02 2.', 'Jan  9 2012 should be week 2');\n    assert.equal(moment([2012, 0, 15]).format('w ww wo'),   '2 02 2.', 'Jan 15 2012 should be week 2');\n});\n\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/test/locale/sl.js",
    "content": "import {localeModule, test} from '../qunit';\nimport moment from '../../moment';\nlocaleModule('sl');\n\ntest('parse', function (assert) {\n    var tests = 'januar jan._februar feb._marec mar._april apr._maj maj_junij jun._julij jul._avgust avg._september sep._oktober okt._november nov._december dec.'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, Do MMMM YYYY, h:mm:ss a',      'nedelja, 14. februar 2010, 3:25:50 pm'],\n            ['ddd, hA',                            'ned., 3PM'],\n            ['M Mo MM MMMM MMM',                   '2 2. 02 februar feb.'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14. 14'],\n            ['d do dddd ddd dd',                   '0 0. nedelja ned. ne'],\n            ['DDD DDDo DDDD',                      '45 45. 045'],\n            ['w wo ww',                            '7 7. 07'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'pm PM'],\n            ['[the] DDDo [day of the year]',       'the 45. day of the year'],\n            ['LTS',                                '15:25:50'],\n            ['L',                                  '14.02.2010'],\n            ['LL',                                 '14. februar 2010'],\n            ['LLL',                                '14. februar 2010 15:25'],\n            ['LLLL',                               'nedelja, 14. februar 2010 15:25'],\n            ['l',                                  '14.2.2010'],\n            ['ll',                                 '14. feb. 2010'],\n            ['lll',                                '14. feb. 2010 15:25'],\n            ['llll',                               'ned., 14. feb. 2010 15:25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1.', '1.');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2.', '2.');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3.', '3.');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4.', '4.');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5.', '5.');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6.', '6.');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7.', '7.');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8.', '8.');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9.', '9.');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10.', '10.');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11.', '11.');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12.', '12.');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13.', '13.');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14.', '14.');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15.', '15.');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16.', '16.');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17.', '17.');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18.', '18.');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19.', '19.');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20.', '20.');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21.', '21.');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22.', '22.');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23.', '23.');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24.', '24.');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25.', '25.');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26.', '26.');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27.', '27.');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28.', '28.');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29.', '29.');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30.', '30.');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31.', '31.');\n});\n\ntest('format month', function (assert) {\n    var expected = 'januar jan._februar feb._marec mar._april apr._maj maj._junij jun._julij jul._avgust avg._september sep._oktober okt._november nov._december dec.'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'nedelja ned. ne_ponedeljek pon. po_torek tor. to_sreda sre. sr_četrtek čet. če_petek pet. pe_sobota sob. so'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'nekaj sekund', '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'ena minuta',   '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'ena minuta',   '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 minuti',     '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 minut',     '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'ena ura',      '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'ena ura',      '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 uri',        '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 ur',         '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 ur',        '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'en dan',       '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'en dan',       '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 dni',        '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'en dan',       '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 dni',        '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 dni',       '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'en mesec',     '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'en mesec',     '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'en mesec',     '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 meseca',     '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 meseca',     '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 mesece',     '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'en mesec',     '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 mesecev',    '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'eno leto',     '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 leti',       '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'eno leto',     '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 let',        '5 years = 5 years');\n\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 1}), true),  'ena minuta', 'a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 2}), true),  '2 minuti',   '2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 3}), true),  '3 minute',   '3 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 4}), true),  '4 minute',   '4 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 5}), true),  '5 minut',    '5 minutes');\n\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 1}), true),  'ena ura', 'an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 2}), true),  '2 uri',   '2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 3}), true),  '3 ure',   '3 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 4}), true),  '4 ure',   '4 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),  '5 ur',    '5 hours');\n\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),  'en dan', 'a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 2}), true),  '2 dni',  '2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 3}), true),  '3 dni',  '3 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 4}), true),  '4 dni',  '4 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),  '5 dni',  '5 days');\n\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),  'en mesec',  'a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 2}), true),  '2 meseca',  '2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 3}), true),  '3 mesece',  '3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 4}), true),  '4 mesece',  '4 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),  '5 mesecev', '5 months');\n\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),  'eno leto', 'a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 2}), true),  '2 leti',   '2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 3}), true),  '3 leta',   '3 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 4}), true),  '4 leta',   '4 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),  '5 let',    '5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'čez nekaj sekund',  'prefix');\n    assert.equal(moment(0).from(30000), 'pred nekaj sekundami', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'pred nekaj sekundami',  'now from now should display as in the past');\n});\n\ntest('fromNow (future)', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'čez nekaj sekund', 'in a few seconds');\n    assert.equal(moment().add({m: 1}).fromNow(),  'čez eno minuto', 'in a minute');\n    assert.equal(moment().add({m: 2}).fromNow(),  'čez 2 minuti',   'in 2 minutes');\n    assert.equal(moment().add({m: 3}).fromNow(),  'čez 3 minute',   'in 3 minutes');\n    assert.equal(moment().add({m: 4}).fromNow(),  'čez 4 minute',   'in 4 minutes');\n    assert.equal(moment().add({m: 5}).fromNow(),  'čez 5 minut',    'in 5 minutes');\n\n    assert.equal(moment().add({h: 1}).fromNow(),  'čez eno uro', 'in an hour');\n    assert.equal(moment().add({h: 2}).fromNow(),  'čez 2 uri',   'in 2 hours');\n    assert.equal(moment().add({h: 3}).fromNow(),  'čez 3 ure',   'in 3 hours');\n    assert.equal(moment().add({h: 4}).fromNow(),  'čez 4 ure',   'in 4 hours');\n    assert.equal(moment().add({h: 5}).fromNow(),  'čez 5 ur',    'in 5 hours');\n\n    assert.equal(moment().add({d: 1}).fromNow(),  'čez en dan', 'in a day');\n    assert.equal(moment().add({d: 2}).fromNow(),  'čez 2 dni',  'in 2 days');\n    assert.equal(moment().add({d: 3}).fromNow(),  'čez 3 dni',  'in 3 days');\n    assert.equal(moment().add({d: 4}).fromNow(),  'čez 4 dni',  'in 4 days');\n    assert.equal(moment().add({d: 5}).fromNow(),  'čez 5 dni',  'in 5 days');\n\n    assert.equal(moment().add({M: 1}).fromNow(),  'čez en mesec',  'in a month');\n    assert.equal(moment().add({M: 2}).fromNow(),  'čez 2 meseca',  'in 2 months');\n    assert.equal(moment().add({M: 3}).fromNow(),  'čez 3 mesece',  'in 3 months');\n    assert.equal(moment().add({M: 4}).fromNow(),  'čez 4 mesece',  'in 4 months');\n    assert.equal(moment().add({M: 5}).fromNow(),  'čez 5 mesecev', 'in 5 months');\n\n    assert.equal(moment().add({y: 1}).fromNow(),  'čez eno leto', 'in a year');\n    assert.equal(moment().add({y: 2}).fromNow(),  'čez 2 leti',   'in 2 years');\n    assert.equal(moment().add({y: 3}).fromNow(),  'čez 3 leta',   'in 3 years');\n    assert.equal(moment().add({y: 4}).fromNow(),  'čez 4 leta',   'in 4 years');\n    assert.equal(moment().add({y: 5}).fromNow(),  'čez 5 let',    'in 5 years');\n\n    assert.equal(moment().subtract({s: 30}).fromNow(), 'pred nekaj sekundami', 'a few seconds ago');\n\n    assert.equal(moment().subtract({m: 1}).fromNow(),  'pred eno minuto', 'a minute ago');\n    assert.equal(moment().subtract({m: 2}).fromNow(),  'pred 2 minutama', '2 minutes ago');\n    assert.equal(moment().subtract({m: 3}).fromNow(),  'pred 3 minutami', '3 minutes ago');\n    assert.equal(moment().subtract({m: 4}).fromNow(),  'pred 4 minutami', '4 minutes ago');\n    assert.equal(moment().subtract({m: 5}).fromNow(),  'pred 5 minutami', '5 minutes ago');\n\n    assert.equal(moment().subtract({h: 1}).fromNow(),  'pred eno uro', 'an hour ago');\n    assert.equal(moment().subtract({h: 2}).fromNow(),  'pred 2 urama', '2 hours ago');\n    assert.equal(moment().subtract({h: 3}).fromNow(),  'pred 3 urami', '3 hours ago');\n    assert.equal(moment().subtract({h: 4}).fromNow(),  'pred 4 urami', '4 hours ago');\n    assert.equal(moment().subtract({h: 5}).fromNow(),  'pred 5 urami', '5 hours ago');\n\n    assert.equal(moment().subtract({d: 1}).fromNow(),  'pred enim dnem', 'a day ago');\n    assert.equal(moment().subtract({d: 2}).fromNow(),  'pred 2 dnevoma', '2 days ago');\n    assert.equal(moment().subtract({d: 3}).fromNow(),  'pred 3 dnevi',   '3 days ago');\n    assert.equal(moment().subtract({d: 4}).fromNow(),  'pred 4 dnevi',   '4 days ago');\n    assert.equal(moment().subtract({d: 5}).fromNow(),  'pred 5 dnevi',   '5 days ago');\n\n    assert.equal(moment().subtract({M: 1}).fromNow(),  'pred enim mesecem', 'a month ago');\n    assert.equal(moment().subtract({M: 2}).fromNow(),  'pred 2 mesecema',   '2 months ago');\n    assert.equal(moment().subtract({M: 3}).fromNow(),  'pred 3 meseci',     '3 months ago');\n    assert.equal(moment().subtract({M: 4}).fromNow(),  'pred 4 meseci',     '4 months ago');\n    assert.equal(moment().subtract({M: 5}).fromNow(),  'pred 5 meseci',     '5 months ago');\n\n    assert.equal(moment().subtract({y: 1}).fromNow(),  'pred enim letom', 'a year ago');\n    assert.equal(moment().subtract({y: 2}).fromNow(),  'pred 2 letoma',   '2 years ago');\n    assert.equal(moment().subtract({y: 3}).fromNow(),  'pred 3 leti',     '3 years ago');\n    assert.equal(moment().subtract({y: 4}).fromNow(),  'pred 4 leti',     '4 years ago');\n    assert.equal(moment().subtract({y: 5}).fromNow(),  'pred 5 leti',     '5 years ago');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'danes ob 12:00',  'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'danes ob 12:25',  'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'danes ob 13:00',  'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'jutri ob 12:00',  'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'danes ob 11:00',  'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'včeraj ob 12:00', 'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n\n    function makeFormat(d) {\n        switch (d.day()) {\n            case 0:\n                return '[v] [nedeljo] [ob] LT';\n            case 3:\n                return '[v] [sredo] [ob] LT';\n            case 6:\n                return '[v] [soboto] [ob] LT';\n            case 1:\n            case 2:\n            case 4:\n            case 5:\n                return '[v] dddd [ob] LT';\n        }\n    }\n\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format(makeFormat(m)),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format(makeFormat(m)),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format(makeFormat(m)),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n\n    function makeFormat(d) {\n        switch (d.day()) {\n            case 0:\n                return '[prejšnjo] [nedeljo] [ob] LT';\n            case 3:\n                return '[prejšnjo] [sredo] [ob] LT';\n            case 6:\n                return '[prejšnjo] [soboto] [ob] LT';\n            case 1:\n            case 2:\n            case 4:\n            case 5:\n                return '[prejšnji] dddd [ob] LT';\n        }\n    }\n\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format(makeFormat(m)),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format(makeFormat(m)),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format(makeFormat(m)),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2011, 11, 26]).format('w ww wo'), '1 01 1.', 'Dec 26 2011 should be week 1');\n    assert.equal(moment([2012,  0,  1]).format('w ww wo'), '1 01 1.', 'Jan  1 2012 should be week 1');\n    assert.equal(moment([2012,  0,  2]).format('w ww wo'), '2 02 2.', 'Jan  2 2012 should be week 2');\n    assert.equal(moment([2012,  0,  8]).format('w ww wo'), '2 02 2.', 'Jan  8 2012 should be week 2');\n    assert.equal(moment([2012,  0,  9]).format('w ww wo'), '3 03 3.', 'Jan  9 2012 should be week 3');\n});\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/test/locale/sq.js",
    "content": "import {localeModule, test} from '../qunit';\nimport moment from '../../moment';\nlocaleModule('sq');\n\ntest('parse', function (assert) {\n    var i,\n        tests = 'Janar Jan_Shkurt Shk_Mars Mar_Prill Pri_Maj Maj_Qershor Qer_Korrik Kor_Gusht Gus_Shtator Sht_Tetor Tet_Nëntor Nën_Dhjetor Dhj'.split('_');\n\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, MMMM Do YYYY, HH:mm:ss',       'E Diel, Shkurt 14. 2010, 15:25:50'],\n            ['ddd, HH',                            'Die, 15'],\n            ['M Mo MM MMMM MMM',                   '2 2. 02 Shkurt Shk'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14. 14'],\n            ['d do dddd ddd dd',                   '0 0. E Diel Die D'],\n            ['DDD DDDo DDDD',                      '45 45. 045'],\n            ['w wo ww',                            '6 6. 06'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'MD MD'],\n            ['[the] DDDo [day of the year]',       'the 45. day of the year'],\n            ['LTS',                                '15:25:50'],\n            ['L',                                  '14/02/2010'],\n            ['LL',                                 '14 Shkurt 2010'],\n            ['LLL',                                '14 Shkurt 2010 15:25'],\n            ['LLLL',                               'E Diel, 14 Shkurt 2010 15:25'],\n            ['l',                                  '14/2/2010'],\n            ['ll',                                 '14 Shk 2010'],\n            ['lll',                                '14 Shk 2010 15:25'],\n            ['llll',                               'Die, 14 Shk 2010 15:25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('meridiem', function (assert) {\n    assert.equal(moment([2011, 2, 23,  0, 0]).format('A'), 'PD', 'before dawn');\n    assert.equal(moment([2011, 2, 23, 12, 0]).format('A'), 'MD', 'noon');\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1.', '1.');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2.', '2.');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3.', '3.');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4.', '4.');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5.', '5.');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6.', '6.');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7.', '7.');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8.', '8.');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9.', '9.');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10.', '10.');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11.', '11.');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12.', '12.');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13.', '13.');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14.', '14.');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15.', '15.');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16.', '16.');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17.', '17.');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18.', '18.');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19.', '19.');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20.', '20.');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21.', '21.');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22.', '22.');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23.', '23.');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24.', '24.');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25.', '25.');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26.', '26.');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27.', '27.');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28.', '28.');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29.', '29.');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30.', '30.');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31.', '31.');\n});\n\ntest('format month', function (assert) {\n    var i,\n        expected = 'Janar Jan_Shkurt Shk_Mars Mar_Prill Pri_Maj Maj_Qershor Qer_Korrik Kor_Gusht Gus_Shtator Sht_Tetor Tet_Nëntor Nën_Dhjetor Dhj'.split('_');\n\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var i,\n        expected = 'E Diel Die D_E Hënë Hën H_E Martë Mar Ma_E Mërkurë Mër Më_E Enjte Enj E_E Premte Pre P_E Shtunë Sht Sh'.split('_');\n\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'disa sekonda', '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'një minutë',      '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'një minutë',      '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 minuta',     '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 minuta',    '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'një orë',       '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'një orë',       '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 orë',       '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 orë',       '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 orë',      '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'një ditë',         '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'një ditë',         '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 ditë',        '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'një ditë',         '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 ditë',        '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 ditë',       '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'një muaj',       '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'një muaj',       '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'një muaj',       '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 muaj',      '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 muaj',      '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 muaj',      '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'një muaj',       '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 muaj',      '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'një vit',        '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 vite',       '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'një vit',        '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 vite',       '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'në disa sekonda',  'prefix');\n    assert.equal(moment(0).from(30000), 'disa sekonda më parë', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'disa sekonda më parë',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'në disa sekonda', 'in a few seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), 'në 5 ditë', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'Sot në 12:00',   'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'Sot në 12:25',   'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'Sot në 13:00',   'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'Nesër në 12:00', 'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'Sot në 11:00',   'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'Dje në 12:00',   'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('dddd [në] LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd [në] LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd [në] LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('dddd [e kaluar në] LT'),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd [e kaluar në] LT'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd [e kaluar në] LT'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2012, 0,  1]).format('w ww wo'), '52 52 52.', 'Jan  1 2012 should be week 52');\n    assert.equal(moment([2012, 0,  2]).format('w ww wo'),   '1 01 1.', 'Jan  2 2012 should be week 1');\n    assert.equal(moment([2012, 0,  8]).format('w ww wo'),   '1 01 1.', 'Jan  8 2012 should be week 1');\n    assert.equal(moment([2012, 0,  9]).format('w ww wo'),   '2 02 2.', 'Jan  9 2012 should be week 2');\n    assert.equal(moment([2012, 0, 15]).format('w ww wo'),   '2 02 2.', 'Jan 15 2012 should be week 2');\n});\n\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/test/locale/sr-cyrl.js",
    "content": "import {localeModule, test} from '../qunit';\nimport moment from '../../moment';\nlocaleModule('sr-cyrl');\n\ntest('parse', function (assert) {\n    var tests = 'јануар јан._фебруар феб._март мар._април апр._мај мај_јун јун_јул јул_август авг._септембар сеп._октобар окт._новембар нов._децембар дец.'.split('_'),\n        i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, Do MMMM YYYY, h:mm:ss a',      'недеља, 14. фебруар 2010, 3:25:50 pm'],\n            ['ddd, hA',                            'нед., 3PM'],\n            ['M Mo MM MMMM MMM',                   '2 2. 02 фебруар феб.'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14. 14'],\n            ['d do dddd ddd dd',                   '0 0. недеља нед. не'],\n            ['DDD DDDo DDDD',                      '45 45. 045'],\n            ['w wo ww',                            '7 7. 07'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'pm PM'],\n            ['[the] DDDo [day of the year]',       'the 45. day of the year'],\n            ['LTS',                                '15:25:50'],\n            ['L',                                  '14.02.2010'],\n            ['LL',                                 '14. фебруар 2010'],\n            ['LLL',                                '14. фебруар 2010 15:25'],\n            ['LLLL',                               'недеља, 14. фебруар 2010 15:25'],\n            ['l',                                  '14.2.2010'],\n            ['ll',                                 '14. феб. 2010'],\n            ['lll',                                '14. феб. 2010 15:25'],\n            ['llll',                               'нед., 14. феб. 2010 15:25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1.', '1.');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2.', '2.');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3.', '3.');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4.', '4.');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5.', '5.');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6.', '6.');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7.', '7.');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8.', '8.');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9.', '9.');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10.', '10.');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11.', '11.');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12.', '12.');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13.', '13.');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14.', '14.');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15.', '15.');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16.', '16.');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17.', '17.');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18.', '18.');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19.', '19.');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20.', '20.');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21.', '21.');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22.', '22.');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23.', '23.');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24.', '24.');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25.', '25.');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26.', '26.');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27.', '27.');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28.', '28.');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29.', '29.');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30.', '30.');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31.', '31.');\n});\n\ntest('format month', function (assert) {\n    var expected = 'јануар јан._фебруар феб._март мар._април апр._мај мај_јун јун_јул јул_август авг._септембар сеп._октобар окт._новембар нов._децембар дец.'.split('_'),\n        i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'недеља нед. не_понедељак пон. по_уторак уто. ут_среда сре. ср_четвртак чет. че_петак пет. пе_субота суб. су'.split('_'),\n        i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'неколико секунди', '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'један минут',   '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'један минут',   '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 минуте',     '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 минута',     '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'један сат',      '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'један сат',      '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 сата',        '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 сати',         '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 сати',        '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'дан',       '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'дан',       '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 дана',        '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'дан',       '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 дана',        '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 дана',       '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'месец',     '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'месец',     '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'месец',     '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 месеца',     '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 месеца',     '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 месеца',     '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'месец',     '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 месеци',    '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'годину',     '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 године',       '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'годину',     '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 година',        '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'за неколико секунди',  'prefix');\n    assert.equal(moment(0).from(30000), 'пре неколико секунди', 'prefix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'пре неколико секунди',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'за неколико секунди', 'in a few seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), 'за 5 дана', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'данас у 12:00',  'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'данас у 12:25',  'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'данас у 13:00',  'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'сутра у 12:00',  'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'данас у 11:00',  'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'јуче у 12:00',   'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n\n    function makeFormat(d) {\n        switch (d.day()) {\n            case 0:\n                return '[у] [недељу] [у] LT';\n            case 3:\n                return '[у] [среду] [у] LT';\n            case 6:\n                return '[у] [суботу] [у] LT';\n            case 1:\n            case 2:\n            case 4:\n            case 5:\n                return '[у] dddd [у] LT';\n        }\n    }\n\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format(makeFormat(m)),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format(makeFormat(m)),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format(makeFormat(m)),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n\n    function makeFormat(d) {\n        var lastWeekDay = [\n                '[прошле] [недеље] [у] LT',\n                '[прошлог] [понедељка] [у] LT',\n                '[прошлог] [уторка] [у] LT',\n                '[прошле] [среде] [у] LT',\n                '[прошлог] [четвртка] [у] LT',\n                '[прошлог] [петка] [у] LT',\n                '[прошле] [суботе] [у] LT'\n            ];\n\n        return lastWeekDay[d.day()];\n    }\n\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format(makeFormat(m)),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format(makeFormat(m)),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format(makeFormat(m)),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2011, 11, 26]).format('w ww wo'), '1 01 1.', 'Dec 26 2011 should be week 1');\n    assert.equal(moment([2012,  0,  1]).format('w ww wo'), '1 01 1.', 'Jan  1 2012 should be week 1');\n    assert.equal(moment([2012,  0,  2]).format('w ww wo'), '2 02 2.', 'Jan  2 2012 should be week 2');\n    assert.equal(moment([2012,  0,  8]).format('w ww wo'), '2 02 2.', 'Jan  8 2012 should be week 2');\n    assert.equal(moment([2012,  0,  9]).format('w ww wo'), '3 03 3.', 'Jan  9 2012 should be week 3');\n});\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/test/locale/sr.js",
    "content": "import {localeModule, test} from '../qunit';\nimport moment from '../../moment';\nlocaleModule('sr');\n\ntest('parse', function (assert) {\n    var tests = 'januar jan._februar feb._mart mar._april apr._maj maj_jun jun_jul jul_avgust avg._septembar sep._oktobar okt._novembar nov._decembar dec.'.split('_'),\n        i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, Do MMMM YYYY, h:mm:ss a',      'nedelja, 14. februar 2010, 3:25:50 pm'],\n            ['ddd, hA',                            'ned., 3PM'],\n            ['M Mo MM MMMM MMM',                   '2 2. 02 februar feb.'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14. 14'],\n            ['d do dddd ddd dd',                   '0 0. nedelja ned. ne'],\n            ['DDD DDDo DDDD',                      '45 45. 045'],\n            ['w wo ww',                            '7 7. 07'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'pm PM'],\n            ['[the] DDDo [day of the year]',       'the 45. day of the year'],\n            ['LTS',                                '15:25:50'],\n            ['L',                                  '14.02.2010'],\n            ['LL',                                 '14. februar 2010'],\n            ['LLL',                                '14. februar 2010 15:25'],\n            ['LLLL',                               'nedelja, 14. februar 2010 15:25'],\n            ['l',                                  '14.2.2010'],\n            ['ll',                                 '14. feb. 2010'],\n            ['lll',                                '14. feb. 2010 15:25'],\n            ['llll',                               'ned., 14. feb. 2010 15:25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1.', '1.');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2.', '2.');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3.', '3.');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4.', '4.');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5.', '5.');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6.', '6.');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7.', '7.');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8.', '8.');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9.', '9.');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10.', '10.');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11.', '11.');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12.', '12.');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13.', '13.');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14.', '14.');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15.', '15.');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16.', '16.');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17.', '17.');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18.', '18.');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19.', '19.');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20.', '20.');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21.', '21.');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22.', '22.');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23.', '23.');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24.', '24.');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25.', '25.');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26.', '26.');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27.', '27.');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28.', '28.');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29.', '29.');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30.', '30.');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31.', '31.');\n});\n\ntest('format month', function (assert) {\n    var expected = 'januar jan._februar feb._mart mar._april apr._maj maj_jun jun_jul jul_avgust avg._septembar sep._oktobar okt._novembar nov._decembar dec.'.split('_'),\n        i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'nedelja ned. ne_ponedeljak pon. po_utorak uto. ut_sreda sre. sr_četvrtak čet. če_petak pet. pe_subota sub. su'.split('_'),\n        i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'nekoliko sekundi', '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'jedan minut',   '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'jedan minut',   '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 minute',     '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 minuta',     '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'jedan sat',      '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'jedan sat',      '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 sata',        '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 sati',         '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 sati',        '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'dan',       '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'dan',       '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 dana',        '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'dan',       '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 dana',        '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 dana',       '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'mesec',     '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'mesec',     '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'mesec',     '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 meseca',     '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 meseca',     '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 meseca',     '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'mesec',     '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 meseci',    '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'godinu',     '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 godine',       '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'godinu',     '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 godina',        '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'za nekoliko sekundi',  'prefix');\n    assert.equal(moment(0).from(30000), 'pre nekoliko sekundi', 'prefix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'pre nekoliko sekundi',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'za nekoliko sekundi', 'in a few seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), 'za 5 dana', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'danas u 12:00',  'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'danas u 12:25',  'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'danas u 13:00',  'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'sutra u 12:00',  'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'danas u 11:00',  'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'juče u 12:00',   'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n\n    function makeFormat(d) {\n        switch (d.day()) {\n            case 0:\n                return '[u] [nedelju] [u] LT';\n            case 3:\n                return '[u] [sredu] [u] LT';\n            case 6:\n                return '[u] [subotu] [u] LT';\n            case 1:\n            case 2:\n            case 4:\n            case 5:\n                return '[u] dddd [u] LT';\n        }\n    }\n\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format(makeFormat(m)),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format(makeFormat(m)),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format(makeFormat(m)),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n\n    function makeFormat(d) {\n        var lastWeekDay = [\n                '[prošle] [nedelje] [u] LT',\n                '[prošlog] [ponedeljka] [u] LT',\n                '[prošlog] [utorka] [u] LT',\n                '[prošle] [srede] [u] LT',\n                '[prošlog] [četvrtka] [u] LT',\n                '[prošlog] [petka] [u] LT',\n                '[prošle] [subote] [u] LT'\n            ];\n\n        return lastWeekDay[d.day()];\n    }\n\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format(makeFormat(m)),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format(makeFormat(m)),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format(makeFormat(m)),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2011, 11, 26]).format('w ww wo'), '1 01 1.', 'Dec 26 2011 should be week 1');\n    assert.equal(moment([2012,  0,  1]).format('w ww wo'), '1 01 1.', 'Jan  1 2012 should be week 1');\n    assert.equal(moment([2012,  0,  2]).format('w ww wo'), '2 02 2.', 'Jan  2 2012 should be week 2');\n    assert.equal(moment([2012,  0,  8]).format('w ww wo'), '2 02 2.', 'Jan  8 2012 should be week 2');\n    assert.equal(moment([2012,  0,  9]).format('w ww wo'), '3 03 3.', 'Jan  9 2012 should be week 3');\n});\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/test/locale/ss.js",
    "content": "import {localeModule, test} from '../qunit';\nimport moment from '../../moment';\nlocaleModule('ss');\n\ntest('parse', function (assert) {\n    var tests = \"Bhimbidvwane Bhi_Indlovana Ina_Indlov'lenkhulu Inu_Mabasa Mab_Inkhwekhweti Ink_Inhlaba Inh_Kholwane Kho_Ingci Igc_Inyoni Iny_Imphala Imp_Lweti lwe_Ingongoni Igo\".split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('parse meridiem', function (assert) {\n    var i,\n        b = moment(),\n        meridiemTests = [\n            // h a patterns, expected hours, isValid\n            ['10 ekuseni',   10, true],\n            ['11 emini',   11, true],\n            ['3 entsambama',   15, true],\n            ['4 entsambama',   16, true],\n            ['6 entsambama',   18, true],\n            ['7 ebusuku',   19, true],\n            ['12 ebusuku',   0, true],\n            ['10 am',   10, false],\n            ['10 pm',   10, false]\n        ],\n        parsed;\n\n    // test that a formatted moment including meridiem string can be parsed back to the same moment\n    assert.ok(b.isSame(moment(b.format('h:mm:ss a'), 'h:mm:ss a', 'ss', true), 'seconds'), b.format('h:mm:ss a') + ' should be equal to ' + moment(b.format('h:mm:ss a'), 'h:mm:ss a', 'ss', true).format('h:mm:ss a'));\n\n    // test that a formatted moment having a meridiem string can be parsed with strict flag\n    assert.ok(moment(b.format('h:mm:ss a'), 'h:mm:ss a', 'ss', true).isValid(), b.format('h:mm:ss a') + ' should be parsed as valid');\n\n    for (i = 0; i < meridiemTests.length; i++) {\n        parsed = moment(meridiemTests[i][0], 'h a', 'ss', true);\n        assert.equal(parsed.isValid(), meridiemTests[i][2], 'validity for ' + meridiemTests[i][0]);\n        if (parsed.isValid()) {\n            assert.equal(parsed.hours(), meridiemTests[i][1], 'hours for ' + meridiemTests[i][0]);\n        }\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, MMMM Do YYYY, h:mm:ss a',      'Lisontfo, Indlovana 14 2010, 3:25:50 entsambama'],\n            ['ddd, h A',                            'Lis, 3 entsambama'],\n            ['M Mo MM MMMM MMM',                   '2 2 02 Indlovana Ina'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14 14'],\n            ['d do dddd ddd dd',                   '0 0 Lisontfo Lis Li'],\n            ['DDD DDDo DDDD',                      '45 45 045'],\n            ['w wo ww',                            '6 6 06'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'entsambama entsambama'],\n            ['[Lilanga] DDDo [lilanga lelinyaka]', 'Lilanga 45 lilanga lelinyaka'],\n            ['LTS',                                '3:25:50 entsambama'],\n            ['L',                                  '14/02/2010'],\n            ['LL',                                 '14 Indlovana 2010'],\n            ['LLL',                                '14 Indlovana 2010 3:25 entsambama'],\n            ['LLLL',                               'Lisontfo, 14 Indlovana 2010 3:25 entsambama'],\n            ['l',                                  '14/2/2010'],\n            ['ll',                                 '14 Ina 2010'],\n            ['lll',                                '14 Ina 2010 3:25 entsambama'],\n            ['llll',                               'Lis, 14 Ina 2010 3:25 entsambama']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1', '1');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2', '2');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3', '3');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4', '4');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5', '5');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6', '6');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7', '7');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8', '8');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9', '9');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10', '10');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11', '11');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12', '12');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13', '13');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14', '14');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15', '15');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16', '16');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17', '17');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18', '18');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19', '19');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20', '20');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21', '21');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22', '22');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23', '23');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24', '24');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25', '25');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26', '26');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27', '27');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28', '28');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29', '29');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30', '30');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31', '31');\n});\n\ntest('format month', function (assert) {\n    var expected = \"Bhimbidvwane Bhi_Indlovana Ina_Indlov'lenkhulu Inu_Mabasa Mab_Inkhwekhweti Ink_Inhlaba Inh_Kholwane Kho_Ingci Igc_Inyoni Iny_Imphala Imp_Lweti Lwe_Ingongoni Igo\".split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'Lisontfo Lis Li_Umsombuluko Umb Us_Lesibili Lsb Lb_Lesitsatfu Les Lt_Lesine Lsi Ls_Lesihlanu Lsh Lh_Umgcibelo Umg Ug'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'emizuzwana lomcane', '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'umzuzu',      '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'umzuzu',      '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 emizuzu',     '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 emizuzu',    '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'lihora',       '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'lihora',       '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 emahora',       '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 emahora',       '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 emahora',      '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'lilanga',         '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'lilanga',         '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 emalanga',        '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'lilanga',         '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 emalanga',        '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 emalanga',       '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'inyanga',       '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'inyanga',       '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'inyanga',       '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 tinyanga',      '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 tinyanga',      '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 tinyanga',      '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'inyanga',       '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 tinyanga',      '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'umnyaka',        '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 iminyaka',       '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'umnyaka',        '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 iminyaka',       '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'nga emizuzwana lomcane',  'prefix');\n    assert.equal(moment(0).from(30000), 'wenteka nga emizuzwana lomcane', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'wenteka nga emizuzwana lomcane',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'nga emizuzwana lomcane', 'in a few seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), 'nga 5 emalanga', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'Namuhla nga 12:00 emini',      'Today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'Namuhla nga 12:25 emini',      'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'Namuhla nga 1:00 emini',      'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'Kusasa nga 12:00 emini',   'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'Namuhla nga 11:00 emini',      'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'Itolo nga 12:00 emini',  'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('dddd [nga] LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd [nga] LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd [nga] LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('dddd [leliphelile] [nga] LT'),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd [leliphelile] [nga] LT'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd [leliphelile] [nga] LT'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2012, 0,  1]).format('w ww wo'), '52 52 52', 'Jan  1 2012 should be week 52');\n    assert.equal(moment([2012, 0,  2]).format('w ww wo'),   '1 01 1', 'Jan  4 2012 should be week 1');\n    assert.equal(moment([2012, 0,  8]).format('w ww wo'),   '1 01 1', 'Jan  8 2012 should be week 1');\n    assert.equal(moment([2012, 0,  9]).format('w ww wo'),   '2 02 2', 'Jan  9 2012 should be week 2');\n    assert.equal(moment([2012, 0, 15]).format('w ww wo'),   '2 02 2', 'Jan 15 2012 should be week 2');\n});\n\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/test/locale/sv.js",
    "content": "import {localeModule, test} from '../qunit';\nimport moment from '../../moment';\nlocaleModule('sv');\n\ntest('parse', function (assert) {\n    var tests = 'januari jan_februari feb_mars mar_april apr_maj maj_juni jun_juli jul_augusti aug_september sep_oktober okt_november nov_december dec'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, MMMM Do YYYY, h:mm:ss a',      'söndag, februari 14e 2010, 3:25:50 pm'],\n            ['ddd, hA',                            'sön, 3PM'],\n            ['M Mo MM MMMM MMM',                   '2 2a 02 februari feb'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14e 14'],\n            ['d do dddd ddd dd',                   '0 0e söndag sön sö'],\n            ['DDD DDDo DDDD',                      '45 45e 045'],\n            ['w wo ww',                            '6 6e 06'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'pm PM'],\n            ['[the] DDDo [day of the year]',       'the 45e day of the year'],\n            ['LTS',                                '15:25:50'],\n            ['L',                                  '2010-02-14'],\n            ['LL',                                 '14 februari 2010'],\n            ['LLL',                                '14 februari 2010 kl. 15:25'],\n            ['LLLL',                               'söndag 14 februari 2010 kl. 15:25'],\n            ['l',                                  '2010-2-14'],\n            ['ll',                                 '14 feb 2010'],\n            ['lll',                                '14 feb 2010 15:25'],\n            ['llll',                               'sön 14 feb 2010 15:25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1a', '1a');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2a', '2a');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3e', '3e');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4e', '4e');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5e', '5e');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6e', '6e');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7e', '7e');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8e', '8e');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9e', '9e');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10e', '10e');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11e', '11e');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12e', '12e');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13e', '13e');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14e', '14e');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15e', '15e');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16e', '16e');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17e', '17e');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18e', '18e');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19e', '19e');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20e', '20e');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21a', '21a');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22a', '22a');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23e', '23e');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24e', '24e');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25e', '25e');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26e', '26e');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27e', '27e');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28e', '28e');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29e', '29e');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30e', '30e');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31a', '31a');\n});\n\ntest('format month', function (assert) {\n    var expected = 'januari jan_februari feb_mars mar_april apr_maj maj_juni jun_juli jul_augusti aug_september sep_oktober okt_november nov_december dec'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'söndag sön sö_måndag mån må_tisdag tis ti_onsdag ons on_torsdag tor to_fredag fre fr_lördag lör lö'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'några sekunder', '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'en minut',      '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'en minut',      '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 minuter',     '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 minuter',    '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'en timme',       '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'en timme',       '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 timmar',       '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 timmar',       '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 timmar',      '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'en dag',         '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'en dag',         '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 dagar',        '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'en dag',         '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 dagar',        '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 dagar',       '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'en månad',       '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'en månad',       '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'en månad',       '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 månader',      '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 månader',      '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 månader',      '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'en månad',       '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 månader',      '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'ett år',        '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 år',       '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'ett år',        '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 år',       '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'om några sekunder',  'prefix');\n    assert.equal(moment(0).from(30000), 'för några sekunder sedan', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'för några sekunder sedan',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'om några sekunder', 'in a few seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), 'om 5 dagar', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'Idag 12:00',     'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'Idag 12:25',     'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'Idag 13:00',     'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'Imorgon 12:00',  'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'Idag 11:00',     'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'Igår 12:00',     'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('[På] dddd LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[På] dddd LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[På] dddd LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('[I] dddd[s] LT'),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[I] dddd[s] LT'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[I] dddd[s] LT'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2012, 0,  1]).format('w ww wo'), '52 52 52a', 'Jan  1 2012 should be week 52');\n    assert.equal(moment([2012, 0,  2]).format('w ww wo'),   '1 01 1a', 'Jan  2 2012 should be week 1');\n    assert.equal(moment([2012, 0,  8]).format('w ww wo'),   '1 01 1a', 'Jan  8 2012 should be week 1');\n    assert.equal(moment([2012, 0,  9]).format('w ww wo'),   '2 02 2a', 'Jan  9 2012 should be week 2');\n    assert.equal(moment([2012, 0, 15]).format('w ww wo'),   '2 02 2a', 'Jan 15 2012 should be week 2');\n});\n\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/test/locale/sw.js",
    "content": "import {localeModule, test} from '../qunit';\nimport moment from '../../moment';\nlocaleModule('sw');\n\ntest('parse', function (assert) {\n    var tests = 'Januari Jan_Februari Feb_Machi Mac_Aprili Apr_Mei Mei_Juni Jun_Julai Jul_Agosti Ago_Septemba Sep_Oktoba Okt_Novemba Nov_Desemba Des'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, MMMM Do YYYY, h:mm:ss a',      'Jumapili, Februari 14 2010, 3:25:50 pm'],\n            ['ddd, hA',                            'Jpl, 3PM'],\n            ['M Mo MM MMMM MMM',                   '2 2 02 Februari Feb'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14 14'],\n            ['d do dddd ddd dd',                   '0 0 Jumapili Jpl J2'],\n            ['DDD DDDo DDDD',                      '45 45 045'],\n            ['w wo ww',                            '7 7 07'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'pm PM'],\n            ['[siku] DDDo [ya mwaka]',             'siku 45 ya mwaka'],\n            ['LTS',                                '15:25:50'],\n            ['L',                                  '14.02.2010'],\n            ['LL',                                 '14 Februari 2010'],\n            ['LLL',                                '14 Februari 2010 15:25'],\n            ['LLLL',                               'Jumapili, 14 Februari 2010 15:25'],\n            ['l',                                  '14.2.2010'],\n            ['ll',                                 '14 Feb 2010'],\n            ['lll',                                '14 Feb 2010 15:25'],\n            ['llll',                               'Jpl, 14 Feb 2010 15:25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1', '1');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2', '2');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3', '3');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4', '4');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5', '5');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6', '6');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7', '7');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8', '8');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9', '9');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10', '10');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11', '11');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12', '12');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13', '13');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14', '14');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15', '15');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16', '16');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17', '17');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18', '18');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19', '19');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20', '20');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21', '21');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22', '22');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23', '23');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24', '24');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25', '25');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26', '26');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27', '27');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28', '28');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29', '29');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30', '30');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31', '31');\n});\n\ntest('format month', function (assert) {\n    var expected = 'Januari Jan_Februari Feb_Machi Mac_Aprili Apr_Mei Mei_Juni Jun_Julai Jul_Agosti Ago_Septemba Sep_Oktoba Okt_Novemba Nov_Desemba Des'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'Jumapili Jpl J2_Jumatatu Jtat J3_Jumanne Jnne J4_Jumatano Jtan J5_Alhamisi Alh Al_Ijumaa Ijm Ij_Jumamosi Jmos J1'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'hivi punde',   '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'dakika moja',  '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'dakika moja',  '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  'dakika 2',     '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  'dakika 44',    '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'saa limoja',   '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'saa limoja',   '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  'masaa 2',      '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   'masaa 5',      '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  'masaa 21',     '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'siku moja',    '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'siku moja',    '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  'masiku 2',     '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'siku moja',    '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   'masiku 5',     '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  'masiku 25',    '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'mwezi mmoja',  '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'mwezi mmoja',  '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'mwezi mmoja',  '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  'miezi 2',      '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  'miezi 2',      '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  'miezi 3',      '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'mwezi mmoja',  '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   'miezi 5',      '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'mwaka mmoja',  '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), 'miaka 2',      '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'mwaka mmoja',  '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   'miaka 5',      '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'hivi punde baadaye',  'prefix');\n    assert.equal(moment(0).from(30000), 'tokea hivi punde', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'tokea hivi punde',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'hivi punde baadaye', 'in a few seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), 'masiku 5 baadaye', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n    assert.equal(moment(a).calendar(),                   'leo saa 12:00',      'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'leo saa 12:25',      'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'leo saa 13:00',      'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'kesho saa 12:00',    'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'leo saa 11:00',      'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'jana 12:00',         'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('[wiki ijayo] dddd [saat] LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[wiki ijayo] dddd [saat] LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[wiki ijayo] dddd [saat] LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('[wiki iliyopita] dddd [saat] LT'),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[wiki iliyopita] dddd [saat] LT'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[wiki iliyopita] dddd [saat] LT'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),      '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('weeks year starting sunday format', function (assert) {\n    assert.equal(moment([2011, 11, 26]).format('w ww wo'), '1 01 1', 'Dec 26 2011 should be week 1');\n    assert.equal(moment([2012,  0,  1]).format('w ww wo'), '1 01 1', 'Jan  1 2012 should be week 1');\n    assert.equal(moment([2012,  0,  2]).format('w ww wo'), '2 02 2', 'Jan  2 2012 should be week 2');\n    assert.equal(moment([2012,  0,  8]).format('w ww wo'), '2 02 2', 'Jan  8 2012 should be week 2');\n    assert.equal(moment([2012,  0,  9]).format('w ww wo'), '3 03 3', 'Jan  9 2012 should be week 3');\n});\n\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/test/locale/ta.js",
    "content": "import {localeModule, test} from '../qunit';\nimport moment from '../../moment';\nlocaleModule('ta');\n\ntest('parse', function (assert) {\n    var tests = 'ஜனவரி ஜனவரி_பிப்ரவரி பிப்ரவரி_மார்ச் மார்ச்_ஏப்ரல் ஏப்ரல்_மே மே_ஜூன் ஜூன்_ஜூலை ஜூலை_ஆகஸ்ட் ஆகஸ்ட்_செப்டெம்பர் செப்டெம்பர்_அக்டோபர் அக்டோபர்_நவம்பர் நவம்பர்_டிசம்பர் டிசம்பர்'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, MMMM Do YYYY, h:mm:ss a', 'ஞாயிற்றுக்கிழமை, பிப்ரவரி ௧௪வது ௨௦௧௦, ௩:௨௫:௫௦  எற்பாடு'],\n            ['ddd, hA',                       'ஞாயிறு, ௩ எற்பாடு'],\n            ['M Mo MM MMMM MMM',              '௨ ௨வது ௦௨ பிப்ரவரி பிப்ரவரி'],\n            ['YYYY YY',                       '௨௦௧௦ ௧௦'],\n            ['D Do DD',                       '௧௪ ௧௪வது ௧௪'],\n            ['d do dddd ddd dd',              '௦ ௦வது ஞாயிற்றுக்கிழமை ஞாயிறு ஞா'],\n            ['DDD DDDo DDDD',                 '௪௫ ௪௫வது ௦௪௫'],\n            ['w wo ww',                       '௮ ௮வது ௦௮'],\n            ['h hh',                          '௩ ௦௩'],\n            ['H HH',                          '௧௫ ௧௫'],\n            ['m mm',                          '௨௫ ௨௫'],\n            ['s ss',                          '௫௦ ௫௦'],\n            ['a A',                           ' எற்பாடு  எற்பாடு'],\n            ['[ஆண்டின்] DDDo  [நாள்]', 'ஆண்டின் ௪௫வது  நாள்'],\n            ['LTS',                           '௧௫:௨௫:௫௦'],\n            ['L',                             '௧௪/௦௨/௨௦௧௦'],\n            ['LL',                            '௧௪ பிப்ரவரி ௨௦௧௦'],\n            ['LLL',                           '௧௪ பிப்ரவரி ௨௦௧௦, ௧௫:௨௫'],\n            ['LLLL',                          'ஞாயிற்றுக்கிழமை, ௧௪ பிப்ரவரி ௨௦௧௦, ௧௫:௨௫'],\n            ['l',                             '௧௪/௨/௨௦௧௦'],\n            ['ll',                            '௧௪ பிப்ரவரி ௨௦௧௦'],\n            ['lll',                           '௧௪ பிப்ரவரி ௨௦௧௦, ௧௫:௨௫'],\n            ['llll',                          'ஞாயிறு, ௧௪ பிப்ரவரி ௨௦௧௦, ௧௫:௨௫']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '௧வது', '௧வது');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '௨வது', '௨வது');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '௩வது', '௩வது');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '௪வது', '௪வது');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '௫வது', '௫வது');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '௬வது', '௬வது');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '௭வது', '௭வது');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '௮வது', '௮வது');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '௯வது', '௯வது');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '௧௦வது', '௧௦வது');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '௧௧வது', '௧௧வது');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '௧௨வது', '௧௨வது');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '௧௩வது', '௧௩வது');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '௧௪வது', '௧௪வது');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '௧௫வது', '௧௫வது');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '௧௬வது', '௧௬வது');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '௧௭வது', '௧௭வது');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '௧௮வது', '௧௮வது');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '௧௯வது', '௧௯வது');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '௨௦வது', '௨௦வது');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '௨௧வது', '௨௧வது');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '௨௨வது', '௨௨வது');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '௨௩வது', '௨௩வது');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '௨௪வது', '௨௪வது');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '௨௫வது', '௨௫வது');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '௨௬வது', '௨௬வது');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '௨௭வது', '௨௭வது');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '௨௮வது', '௨௮வது');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '௨௯வது', '௨௯வது');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '௩௦வது', '௩௦வது');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '௩௧வது', '௩௧வது');\n});\n\ntest('format month', function (assert) {\n    var expected = 'ஜனவரி ஜனவரி_பிப்ரவரி பிப்ரவரி_மார்ச் மார்ச்_ஏப்ரல் ஏப்ரல்_மே மே_ஜூன் ஜூன்_ஜூலை ஜூலை_ஆகஸ்ட் ஆகஸ்ட்_செப்டெம்பர் செப்டெம்பர்_அக்டோபர் அக்டோபர்_நவம்பர் நவம்பர்_டிசம்பர் டிசம்பர்'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'ஞாயிற்றுக்கிழமை ஞாயிறு ஞா_திங்கட்கிழமை திங்கள் தி_செவ்வாய்கிழமை செவ்வாய் செ_புதன்கிழமை புதன் பு_வியாழக்கிழமை வியாழன் வி_வெள்ளிக்கிழமை வெள்ளி வெ_சனிக்கிழமை சனி ச'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'ஒரு சில விநாடிகள்', '44 விநாடிகள் = ஒரு சில விநாடிகள்');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'ஒரு நிமிடம்',      '45 விநாடிகள் = ஒரு நிமிடம்');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'ஒரு நிமிடம்',      '89 விநாடிகள் = ஒரு நிமிடம்');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '௨ நிமிடங்கள்',     '90 விநாடிகள் = ௨ நிமிடங்கள்');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '௪௪ நிமிடங்கள்',    '44 நிமிடங்கள் = 44 நிமிடங்கள்');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'ஒரு மணி நேரம்',       '45 நிமிடங்கள் = ஒரு மணி நேரம்');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'ஒரு மணி நேரம்',       '89 நிமிடங்கள் = ஒரு மணி நேரம்');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '௨ மணி நேரம்',       '90 நிமிடங்கள் = ௨ மணி நேரம்');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '௫ மணி நேரம்',       '5 மணி நேரம் = 5 மணி நேரம்');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '௨௧ மணி நேரம்',      '௨௧ மணி நேரம் = ௨௧ மணி நேரம்');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'ஒரு நாள்',         '௨௨ மணி நேரம் = ஒரு நாள்');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'ஒரு நாள்',         '௩5 மணி நேரம் = ஒரு நாள்');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '௨ நாட்கள்',        '௩6 மணி நேரம் = ௨ days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'ஒரு நாள்',         '௧ நாள் = ஒரு நாள்');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '௫ நாட்கள்',        '5 நாட்கள் = 5 நாட்கள்');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '௨௫ நாட்கள்',       '௨5 நாட்கள் = ௨5 நாட்கள்');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'ஒரு மாதம்',       '௨6 நாட்கள் = ஒரு மாதம்');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'ஒரு மாதம்',       '௩0 நாட்கள் = ஒரு மாதம்');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'ஒரு மாதம்',       '45 நாட்கள் = ஒரு மாதம்');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '௨ மாதங்கள்',      '46 நாட்கள் = ௨ மாதங்கள்');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '௨ மாதங்கள்',      '75 நாட்கள் = ௨ மாதங்கள்');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '௩ மாதங்கள்',      '76 நாட்கள் = ௩ மாதங்கள்');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'ஒரு மாதம்',       '௧ மாதம் = ஒரு மாதம்');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '௫ மாதங்கள்',      '5 மாதங்கள் = 5 மாதங்கள்');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'ஒரு வருடம்',        '௩45 நாட்கள் = ஒரு வருடம்');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '௨ ஆண்டுகள்',       '548 நாட்கள் = ௨ ஆண்டுகள்');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'ஒரு வருடம்',        '௧ வருடம் = ஒரு வருடம்');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '௫ ஆண்டுகள்',       '5 ஆண்டுகள் = 5 ஆண்டுகள்');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'ஒரு சில விநாடிகள் இல்',  'prefix');\n    assert.equal(moment(0).from(30000), 'ஒரு சில விநாடிகள் முன்', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'ஒரு சில விநாடிகள் முன்',  'இப்போது இருந்து கடந்த காலத்தில் காட்ட வேண்டும்');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'ஒரு சில விநாடிகள் இல்', 'ஒரு சில விநாடிகள் இல்');\n    assert.equal(moment().add({d: 5}).fromNow(), '௫ நாட்கள் இல்', '5 நாட்கள் இல்');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'இன்று ௧௨:௦௦',   'இன்று  12:00');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'இன்று ௧௨:௨௫',   'இன்று  12:25');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'இன்று ௧௩:௦௦',   'இன்று  13:00');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'நாளை ௧௨:௦௦',    'நாளை  12:00');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'இன்று ௧௧:௦௦',   'இன்று  11:00');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'நேற்று ௧௨:௦௦',  'நேற்று  12:00');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('dddd, LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd, LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd, LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('[கடந்த வாரம்] dddd, LT'),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[கடந்த வாரம்] dddd, LT'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[கடந்த வாரம்] dddd, LT'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('meridiem', function (assert) {\n    assert.equal(moment([2011, 2, 23,  0, 30]).format('a'), ' யாமம்', '(after) midnight');\n    assert.equal(moment([2011, 2, 23,  2, 30]).format('a'), ' வைகறை', 'before dawn');\n    assert.equal(moment([2011, 2, 23,  9, 30]).format('a'), ' காலை', 'morning');\n    assert.equal(moment([2011, 2, 23, 14, 30]).format('a'), ' எற்பாடு', 'during day');\n    assert.equal(moment([2011, 2, 23, 17, 30]).format('a'), ' எற்பாடு', 'evening');\n    assert.equal(moment([2011, 2, 23, 19, 30]).format('a'), ' மாலை', 'late evening');\n    assert.equal(moment([2011, 2, 23, 23, 30]).format('a'), ' யாமம்', '(before) midnight');\n});\n\n\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/test/locale/te.js",
    "content": "import {localeModule, test} from '../qunit';\nimport moment from '../../moment';\nlocaleModule('te');\n\ntest('parse', function (assert) {\n    var tests = 'జనవరి జన._ఫిబ్రవరి ఫిబ్ర._మార్చి మార్చి_ఏప్రిల్ ఏప్రి._మే మే_జూన్ జూన్_జూలై జూలై_ఆగస్టు ఆగ._సెప్టెంబర్ సెప్._అక్టోబర్ అక్టో._నవంబర్ నవ._డిసెంబర్ డిసె.'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, Do తేదీ MMMM YYYY, a h:mm:ss',  'ఆదివారం, 14వ తేదీ ఫిబ్రవరి 2010, మధ్యాహ్నం 3:25:50'],\n            ['ddd, a h గంటలు',                 'ఆది, మధ్యాహ్నం 3 గంటలు'],\n            ['M Mo నెల MM MMMM MMM',                   '2 2వ నెల 02 ఫిబ్రవరి ఫిబ్ర.'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14వ 14'],\n            ['d do dddd ddd dd',                   '0 0వ ఆదివారం ఆది ఆ'],\n            ['DDD DDDo DDDD',                      '45 45వ 045'],\n            ['w wo ww',                            '8 8వ 08'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'మధ్యాహ్నం మధ్యాహ్నం'],\n            ['LTS',                                'మధ్యాహ్నం 3:25:50'],\n            ['L',                                  '14/02/2010'],\n            ['LL',                                 '14 ఫిబ్రవరి 2010'],\n            ['LLL',                                '14 ఫిబ్రవరి 2010, మధ్యాహ్నం 3:25'],\n            ['LLLL',                               'ఆదివారం, 14 ఫిబ్రవరి 2010, మధ్యాహ్నం 3:25'],\n            ['l',                                  '14/2/2010'],\n            ['ll',                                 '14 ఫిబ్ర. 2010'],\n            ['lll',                                '14 ఫిబ్ర. 2010, మధ్యాహ్నం 3:25'],\n            ['llll',                               'ఆది, 14 ఫిబ్ర. 2010, మధ్యాహ్నం 3:25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1వ', '1వ');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2వ', '2వ');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3వ', '3వ');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4వ', '4వ');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5వ', '5వ');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6వ', '6వ');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7వ', '7వ');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8వ', '8వ');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9వ', '9వ');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10వ', '10వ');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11వ', '11వ');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12వ', '12వ');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13వ', '13వ');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14వ', '14వ');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15వ', '15వ');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16వ', '16వ');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17వ', '17వ');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18వ', '18వ');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19వ', '19వ');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20వ', '20వ');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21వ', '21వ');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22వ', '22వ');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23వ', '23వ');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24వ', '24వ');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25వ', '25వ');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26వ', '26వ');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27వ', '27వ');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28వ', '28వ');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29వ', '29వ');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30వ', '30వ');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31వ', '31వ');\n});\n\ntest('format month', function (assert) {\n    var expected = 'జనవరి జన._ఫిబ్రవరి ఫిబ్ర._మార్చి మార్చి_ఏప్రిల్ ఏప్రి._మే మే_జూన్ జూన్_జూలై జూలై_ఆగస్టు ఆగ._సెప్టెంబర్ సెప్._అక్టోబర్ అక్టో._నవంబర్ నవ._డిసెంబర్ డిసె.'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'ఆదివారం ఆది ఆ_సోమవారం సోమ సో_మంగళవారం మంగళ మం_బుధవారం బుధ బు_గురువారం గురు గు_శుక్రవారం శుక్ర శు_శనివారం శని శ'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'కొన్ని క్షణాలు', '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'ఒక నిమిషం',      '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'ఒక నిమిషం',      '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 నిమిషాలు',     '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 నిమిషాలు',    '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'ఒక గంట',       '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'ఒక గంట',       '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 గంటలు',       '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 గంటలు',       '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 గంటలు',      '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'ఒక రోజు',         '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'ఒక రోజు',         '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 రోజులు',        '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'ఒక రోజు',         '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 రోజులు',        '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 రోజులు',       '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'ఒక నెల',       '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'ఒక నెల',       '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'ఒక నెల',       '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 నెలలు',      '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 నెలలు',      '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 నెలలు',      '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'ఒక నెల',       '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 నెలలు',      '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'ఒక సంవత్సరం',        '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 సంవత్సరాలు',       '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'ఒక సంవత్సరం',        '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 సంవత్సరాలు',       '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'కొన్ని క్షణాలు లో',  'prefix');\n    assert.equal(moment(0).from(30000), 'కొన్ని క్షణాలు క్రితం', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'కొన్ని క్షణాలు క్రితం',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'కొన్ని క్షణాలు లో', 'కొన్ని క్షణాలు లో');\n    assert.equal(moment().add({d: 5}).fromNow(), '5 రోజులు లో', '5 రోజులు లో');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'నేడు మధ్యాహ్నం 12:00',   'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'నేడు మధ్యాహ్నం 12:25',   'Now plus 25 min');\n    assert.equal(moment(a).add({h: 3}).calendar(),       'నేడు మధ్యాహ్నం 3:00',    'Now plus 3 hours');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'రేపు మధ్యాహ్నం 12:00',   'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'నేడు మధ్యాహ్నం 11:00',   'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'నిన్న మధ్యాహ్నం 12:00',  'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('dddd[,] LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd[,] LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd[,] LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('[గత] dddd[,] LT'),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[గత] dddd[,] LT'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[గత] dddd[,] LT'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('meridiem', function (assert) {\n    assert.equal(moment([2011, 2, 23,  2, 30]).format('a'), 'రాత్రి', 'before dawn');\n    assert.equal(moment([2011, 2, 23,  9, 30]).format('a'), 'ఉదయం', 'morning');\n    assert.equal(moment([2011, 2, 23, 14, 30]).format('a'), 'మధ్యాహ్నం', 'during day');\n    assert.equal(moment([2011, 2, 23, 17, 30]).format('a'), 'సాయంత్రం', 'evening');\n    assert.equal(moment([2011, 2, 23, 19, 30]).format('a'), 'సాయంత్రం', 'late evening');\n    assert.equal(moment([2011, 2, 23, 21, 20]).format('a'), 'రాత్రి', 'night');\n\n    assert.equal(moment([2011, 2, 23,  2, 30]).format('A'), 'రాత్రి', 'before dawn');\n    assert.equal(moment([2011, 2, 23,  9, 30]).format('A'), 'ఉదయం', 'morning');\n    assert.equal(moment([2011, 2, 23, 14, 30]).format('A'), 'మధ్యాహ్నం', ' during day');\n    assert.equal(moment([2011, 2, 23, 17, 30]).format('A'), 'సాయంత్రం', 'evening');\n    assert.equal(moment([2011, 2, 23, 19, 30]).format('A'), 'సాయంత్రం', 'late evening');\n    assert.equal(moment([2011, 2, 23, 21, 20]).format('A'), 'రాత్రి', 'night');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2012, 0,  1]).format('w ww wo'), '1 01 1వ', 'Jan  1 2012 should be week 1');\n    assert.equal(moment([2012, 0,  7]).format('w ww wo'), '1 01 1వ', 'Jan  7 2012 should be week 1');\n    assert.equal(moment([2012, 0,  8]).format('w ww wo'), '2 02 2వ', 'Jan  8 2012 should be week 2');\n    assert.equal(moment([2012, 0, 14]).format('w ww wo'), '2 02 2వ', 'Jan 14 2012 should be week 2');\n    assert.equal(moment([2012, 0, 15]).format('w ww wo'), '3 03 3వ', 'Jan 15 2012 should be week 3');\n});\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/test/locale/tet.js",
    "content": "import {localeModule, test} from '../qunit';\nimport moment from '../../moment';\nlocaleModule('tet');\n\ntest('parse', function (assert) {\n    var tests = 'Janeiru Jan_Fevereiru Fev_Marsu Mar_Abril Abr_Maiu Mai_Juniu Jun_Juliu Jul_Augustu Aug_Setembru Set_Outubru Out_Novembru Nov_Dezembru Dez'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, MMMM Do YYYY, h:mm:ss a',      'Domingu, Fevereiru 14th 2010, 3:25:50 pm'],\n            ['ddd, hA',                            'Dom, 3PM'],\n            ['M Mo MM MMMM MMM',                   '2 2nd 02 Fevereiru Fev'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14th 14'],\n            ['d do dddd ddd dd',                   '0 0th Domingu Dom Do'],\n            ['DDD DDDo DDDD',                      '45 45th 045'],\n            ['w wo ww',                            '6 6th 06'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'pm PM'],\n            ['[the] DDDo [day of the year]',       'the 45th day of the year'],\n            ['LTS',                                '15:25:50'],\n            ['L',                                  '14/02/2010'],\n            ['LL',                                 '14 Fevereiru 2010'],\n            ['LLL',                                '14 Fevereiru 2010 15:25'],\n            ['LLLL',                               'Domingu, 14 Fevereiru 2010 15:25'],\n            ['l',                                  '14/2/2010'],\n            ['ll',                                 '14 Fev 2010'],\n            ['lll',                                '14 Fev 2010 15:25'],\n            ['llll',                               'Dom, 14 Fev 2010 15:25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1st', '1st');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2nd', '2nd');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3rd', '3rd');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4th', '4th');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5th', '5th');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6th', '6th');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7th', '7th');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8th', '8th');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9th', '9th');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10th', '10th');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11th', '11th');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12th', '12th');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13th', '13th');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14th', '14th');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15th', '15th');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16th', '16th');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17th', '17th');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18th', '18th');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19th', '19th');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20th', '20th');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21st', '21st');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22nd', '22nd');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23rd', '23rd');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24th', '24th');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25th', '25th');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26th', '26th');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27th', '27th');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28th', '28th');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29th', '29th');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30th', '30th');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31st', '31st');\n});\n\ntest('format month', function (assert) {\n    var expected = 'Janeiru Jan_Fevereiru Fev_Marsu Mar_Abril Abr_Maiu Mai_Juniu Jun_Juliu Jul_Augustu Aug_Setembru Set_Outubru Out_Novembru Nov_Dezembru Dez'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'Domingu Dom Do_Segunda Seg Seg_Tersa Ters Te_Kuarta Kua Ku_Kinta Kint Ki_Sexta Sext Sex_Sabadu Sab Sa'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'minutu balun', '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'minutu ida',      '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'minutu ida',      '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  'minutus 2',     '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  'minutus 44',    '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'horas ida',       '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'horas ida',       '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  'horas 2',       '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   'horas 5',       '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  'horas 21',      '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'loron ida',         '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'loron ida',         '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  'loron 2',        '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'loron ida',         '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   'loron 5',        '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  'loron 25',       '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'fulan ida',       '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'fulan ida',       '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'fulan ida',       '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  'fulan 2',      '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  'fulan 2',      '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  'fulan 3',      '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'fulan ida',       '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   'fulan 5',      '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'tinan ida',        '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), 'tinan 2',       '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'tinan ida',        '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   'tinan 5',       '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'iha minutu balun',  'prefix');\n    assert.equal(moment(0).from(30000), 'minutu balun liuba', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'minutu balun liuba',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'iha minutu balun', 'in a few seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), 'iha loron 5', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'Ohin iha 12:00',      'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'Ohin iha 12:25',      'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'Ohin iha 13:00',      'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'Aban iha 12:00',   'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'Ohin iha 11:00',      'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'Horiseik iha 12:00',  'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('dddd [iha] LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd [iha] LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd [iha] LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('dddd [semana kotuk] [iha] LT'),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd [semana kotuk] [iha] LT'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd [semana kotuk] [iha] LT'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2012, 0,  1]).format('w ww wo'), '52 52 52nd', 'Jan  1 2012 should be week 52');\n    assert.equal(moment([2012, 0,  2]).format('w ww wo'),   '1 01 1st', 'Jan  2 2012 should be week 1');\n    assert.equal(moment([2012, 0,  8]).format('w ww wo'),   '1 01 1st', 'Jan  8 2012 should be week 1');\n    assert.equal(moment([2012, 0,  9]).format('w ww wo'),   '2 02 2nd', 'Jan  9 2012 should be week 2');\n    assert.equal(moment([2012, 0, 15]).format('w ww wo'),   '2 02 2nd', 'Jan 15 2012 should be week 2');\n});\n\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/test/locale/th.js",
    "content": "import {localeModule, test} from '../qunit';\nimport moment from '../../moment';\nlocaleModule('th');\n\ntest('parse', function (assert) {\n    var tests = 'มกราคม ม.ค._กุมภาพันธ์ ก.พ._มีนาคม มี.ค._เมษายน เม.ย._พฤษภาคม พ.ค._มิถุนายน มิ.ย._กรกฎาคม ก.ค._สิงหาคม ส.ค._กันยายน ก.ย._ตุลาคม ต.ค._พฤศจิกายน พ.ย._ธันวาคม ธ.ค.'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, Do MMMM YYYY, h:mm:ss a',      'อาทิตย์, 14 กุมภาพันธ์ 2010, 3:25:50 หลังเที่ยง'],\n            ['ddd, h A',                           'อาทิตย์, 3 หลังเที่ยง'],\n            ['M Mo MM MMMM MMM',                   '2 2 02 กุมภาพันธ์ ก.พ.'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14 14'],\n            ['d do dddd ddd dd',                   '0 0 อาทิตย์ อาทิตย์ อา.'],\n            ['DDD DDDo DDDD',                      '45 45 045'],\n            ['w wo ww',                            '8 8 08'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'หลังเที่ยง หลังเที่ยง'],\n            ['[the] DDDo [day of the year]',       'the 45 day of the year'],\n            ['LTS',                                '15:25:50'],\n            ['L',                                  '14/02/2010'],\n            ['LL',                                 '14 กุมภาพันธ์ 2010'],\n            ['LLL',                                '14 กุมภาพันธ์ 2010 เวลา 15:25'],\n            ['LLLL',                               'วันอาทิตย์ที่ 14 กุมภาพันธ์ 2010 เวลา 15:25'],\n            ['l',                                  '14/2/2010'],\n            ['ll',                                 '14 ก.พ. 2010'],\n            ['lll',                                '14 ก.พ. 2010 เวลา 15:25'],\n            ['llll',                               'วันอาทิตย์ที่ 14 ก.พ. 2010 เวลา 15:25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format month', function (assert) {\n    var expected = 'มกราคม ม.ค._กุมภาพันธ์ ก.พ._มีนาคม มี.ค._เมษายน เม.ย._พฤษภาคม พ.ค._มิถุนายน มิ.ย._กรกฎาคม ก.ค._สิงหาคม ส.ค._กันยายน ก.ย._ตุลาคม ต.ค._พฤศจิกายน พ.ย._ธันวาคม ธ.ค.'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'อาทิตย์ อาทิตย์ อา._จันทร์ จันทร์ จ._อังคาร อังคาร อ._พุธ พุธ พ._พฤหัสบดี พฤหัส พฤ._ศุกร์ ศุกร์ ศ._เสาร์ เสาร์ ส.'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'ไม่กี่วินาที',   '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  '1 นาที', '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  '1 นาที', '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 นาที',  '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 นาที', '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  '1 ชั่วโมง', '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  '1 ชั่วโมง', '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 ชั่วโมง',  '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 ชั่วโมง',  '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 ชั่วโมง', '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  '1 วัน',   '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  '1 วัน',   '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 วัน',   '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   '1 วัน',   '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 วัน',   '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 วัน',  '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  '1 เดือน', '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  '1 เดือน', '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  '1 เดือน', '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 เดือน',  '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 เดือน',  '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 เดือน',  '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   '1 เดือน', '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 เดือน',  '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), '1 ปี',   '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 ปี',   '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   '1 ปี',   '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 ปี',   '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'อีก ไม่กี่วินาที',  'prefix');\n    assert.equal(moment(0).from(30000), 'ไม่กี่วินาทีที่แล้ว', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'ไม่กี่วินาทีที่แล้ว',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'อีก ไม่กี่วินาที', 'in a few seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), 'อีก 5 วัน', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'วันนี้ เวลา 12:00',      'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'วันนี้ เวลา 12:25',     'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'วันนี้ เวลา 13:00',      'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'พรุ่งนี้ เวลา 12:00',    'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'วันนี้ เวลา 11:00',      'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'เมื่อวานนี้ เวลา 12:00', 'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('dddd[หน้า เวลา] LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd[หน้า เวลา] LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd[หน้า เวลา] LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('[วัน]dddd[ที่แล้ว เวลา] LT'),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[วัน]dddd[ที่แล้ว เวลา] LT'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[วัน]dddd[ที่แล้ว เวลา] LT'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),      '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),      '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('weeks year starting sunday format', function (assert) {\n    assert.equal(moment([2012, 0,  1]).format('w ww wo'), '1 01 1', 'Jan  1 2012 should be week 1');\n    assert.equal(moment([2012, 0,  7]).format('w ww wo'), '1 01 1', 'Jan  7 2012 should be week 1');\n    assert.equal(moment([2012, 0,  8]).format('w ww wo'), '2 02 2', 'Jan  8 2012 should be week 2');\n    assert.equal(moment([2012, 0, 14]).format('w ww wo'), '2 02 2', 'Jan 14 2012 should be week 2');\n    assert.equal(moment([2012, 0, 15]).format('w ww wo'), '3 03 3', 'Jan 15 2012 should be week 3');\n});\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/test/locale/tl-ph.js",
    "content": "import {localeModule, test} from '../qunit';\nimport moment from '../../moment';\nlocaleModule('tl-ph');\n\ntest('parse', function (assert) {\n    var tests = 'Enero Ene_Pebrero Peb_Marso Mar_Abril Abr_Mayo May_Hunyo Hun_Hulyo Hul_Agosto Ago_Setyembre Set_Oktubre Okt_Nobyembre Nob_Disyembre Dis'.split('_'),\n        i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, MMMM Do YYYY, h:mm:ss a',      'Linggo, Pebrero 14 2010, 3:25:50 pm'],\n            ['ddd, hA',                            'Lin, 3PM'],\n            ['M Mo MM MMMM MMM',                   '2 2 02 Pebrero Peb'],\n            ['YYYY YY',                             '2010 10'],\n            ['D Do DD',                            '14 14 14'],\n            ['d do dddd ddd dd',                   '0 0 Linggo Lin Li'],\n            ['DDD DDDo DDDD',                      '45 45 045'],\n            ['w wo ww',                            '6 6 06'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'pm PM'],\n            ['[the] DDDo [day of the year]',       'the 45 day of the year'],\n            ['LTS',                                '15:25:50'],\n            ['L',                                  '02/14/2010'],\n            ['LL',                                 'Pebrero 14, 2010'],\n            ['LLL',                                'Pebrero 14, 2010 15:25'],\n            ['LLLL',                               'Linggo, Pebrero 14, 2010 15:25'],\n            ['l',                                  '2/14/2010'],\n            ['ll',                                 'Peb 14, 2010'],\n            ['lll',                                'Peb 14, 2010 15:25'],\n            ['llll',                               'Lin, Peb 14, 2010 15:25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1', '1');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2', '2');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3', '3');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4', '4');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5', '5');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6', '6');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7', '7');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8', '8');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9', '9');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10', '10');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11', '11');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12', '12');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13', '13');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14', '14');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15', '15');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16', '16');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17', '17');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18', '18');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19', '19');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20', '20');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21', '21');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22', '22');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23', '23');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24', '24');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25', '25');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26', '26');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27', '27');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28', '28');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29', '29');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30', '30');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31', '31');\n});\n\ntest('format month', function (assert) {\n    var expected = 'Enero Ene_Pebrero Peb_Marso Mar_Abril Abr_Mayo May_Hunyo Hun_Hulyo Hul_Agosto Ago_Setyembre Set_Oktubre Okt_Nobyembre Nob_Disyembre Dis'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'Linggo Lin Li_Lunes Lun Lu_Martes Mar Ma_Miyerkules Miy Mi_Huwebes Huw Hu_Biyernes Biy Bi_Sabado Sab Sab'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'ilang segundo', '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'isang minuto',   '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'isang minuto',   '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 minuto',  '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 minuto', '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'isang oras',    '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'isang oras',    '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 oras',    '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 oras',    '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 oras',   '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'isang araw',      '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'isang araw',      '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 araw',     '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'isang araw',      '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 araw',     '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 araw',    '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'isang buwan',    '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'isang buwan',    '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'isang buwan',    '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 buwan',   '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 buwan',   '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 buwan',   '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'isang buwan',    '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 buwan',   '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'isang taon',     '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 taon',    '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'isang taon',     '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 taon',    '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'sa loob ng ilang segundo', 'prefix');\n    assert.equal(moment(0).from(30000), 'ilang segundo ang nakalipas', 'suffix');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'sa loob ng ilang segundo', 'in a few seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), 'sa loob ng 5 araw', 'in 5 days');\n});\n\ntest('same day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   '12:00 ngayong araw',    'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      '12:25 ngayong araw',    'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       '13:00 ngayong araw',    'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'Bukas ng 12:00',     'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  '11:00 ngayong araw',    'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  '12:00 kahapon',   'yesterday at the same time');\n});\n\ntest('same next week', function (assert) {\n    var i, m;\n\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('LT [sa susunod na] dddd'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('LT [sa susunod na] dddd'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('LT [sa susunod na] dddd'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('same last week', function (assert) {\n    var i, m;\n\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('LT [noong nakaraang] dddd'),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('LT [noong nakaraang] dddd'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('LT [noong nakaraang] dddd'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('same all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2012, 0,  1]).format('w ww wo'), '52 52 52', 'Jan  1 2012 should be week 52');\n    assert.equal(moment([2012, 0,  2]).format('w ww wo'), '1 01 1', 'Jan  2 2012 should be week 1');\n    assert.equal(moment([2012, 0,  8]).format('w ww wo'), '1 01 1', 'Jan  8 2012 should be week 1');\n    assert.equal(moment([2012, 0,  9]).format('w ww wo'),   '2 02 2', 'Jan  9 2012 should be week 2');\n    assert.equal(moment([2012, 0, 15]).format('w ww wo'),   '2 02 2', 'Jan 15 2012 should be week 2');\n});\n\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/test/locale/tlh.js",
    "content": "import {localeModule, test} from '../qunit';\nimport moment from '../../moment';\nlocaleModule('tlh');\n\n//Current parsing method doesn't allow parsing correctly months 10, 11 and 12.\n/*\n * test('parse', function (assert) {\n    var tests = 'tera’ jar wa’.jar wa’_tera’ jar cha’.jar cha’_tera’ jar wej.jar wej_tera’ jar loS.jar loS_tera’ jar vagh.jar vagh_tera’ jar jav.jar jav_tera’ jar Soch.jar Soch_tera’ jar chorgh.jar chorgh_tera’ jar Hut.jar Hut_tera’ jar wa’maH.jar wa’maH_tera’ jar wa’maH wa’.jar wa’maH wa’_tera’ jar wa’maH cha’.jar wa’maH cha’'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split('.');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n*/\ntest('format', function (assert) {\n    var a = [\n            ['dddd, MMMM Do YYYY, h:mm:ss a',      'lojmItjaj, tera’ jar cha’ 14. 2010, 3:25:50 pm'],\n            ['ddd, hA',                            'lojmItjaj, 3PM'],\n            ['M Mo MM MMMM MMM',                   '2 2. 02 tera’ jar cha’ jar cha’'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14. 14'],\n            ['d do dddd ddd dd',                   '0 0. lojmItjaj lojmItjaj lojmItjaj'],\n            ['DDD DDDo DDDD',                      '45 45. 045'],\n            ['w wo ww',                            '6 6. 06'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'pm PM'],\n            ['[DIS jaj] DDDo',                     'DIS jaj 45.'],\n            ['LTS',                                '15:25:50'],\n            ['L',                                  '14.02.2010'],\n            ['LL',                                 '14 tera’ jar cha’ 2010'],\n            ['LLL',                                '14 tera’ jar cha’ 2010 15:25'],\n            ['LLLL',                               'lojmItjaj, 14 tera’ jar cha’ 2010 15:25'],\n            ['l',                                  '14.2.2010'],\n            ['ll',                                 '14 jar cha’ 2010'],\n            ['lll',                                '14 jar cha’ 2010 15:25'],\n            ['llll',                               'lojmItjaj, 14 jar cha’ 2010 15:25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1.', '1.');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2.', '2.');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3.', '3.');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4.', '4.');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5.', '5.');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6.', '6.');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7.', '7.');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8.', '8.');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9.', '9.');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10.', '10.');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11.', '11.');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12.', '12.');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13.', '13.');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14.', '14.');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15.', '15.');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16.', '16.');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17.', '17.');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18.', '18.');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19.', '19.');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20.', '20.');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21.', '21.');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22.', '22.');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23.', '23.');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24.', '24.');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25.', '25.');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26.', '26.');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27.', '27.');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28.', '28.');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29.', '29.');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30.', '30.');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31.', '31.');\n});\n\ntest('format month', function (assert) {\n    var expected = 'tera’ jar wa’ jar wa’_tera’ jar cha’ jar cha’_tera’ jar wej jar wej_tera’ jar loS jar loS_tera’ jar vagh jar vagh_tera’ jar jav jar jav_tera’ jar Soch jar Soch_tera’ jar chorgh jar chorgh_tera’ jar Hut jar Hut_tera’ jar wa’maH jar wa’maH_tera’ jar wa’maH wa’ jar wa’maH wa’_tera’ jar wa’maH cha’ jar wa’maH cha’'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'lojmItjaj lojmItjaj lojmItjaj_DaSjaj DaSjaj DaSjaj_povjaj povjaj povjaj_ghItlhjaj ghItlhjaj ghItlhjaj_loghjaj loghjaj loghjaj_buqjaj buqjaj buqjaj_ghInjaj ghInjaj ghInjaj'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'puS lup',  '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'wa’ tup',        '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'wa’ tup',        '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  'cha’ tup',      '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  'loSmaH loS tup',     '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'wa’ rep',       '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'wa’ rep',       '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  'cha’ rep',     '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   'vagh rep',      '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  'cha’maH wa’ rep',     '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'wa’ jaj',       '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'wa’ jaj',       '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  'cha’ jaj',         '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'wa’ jaj',       '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   'vagh jaj',         '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  'cha’maH vagh jaj',        '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'wa’ jar',       '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'wa’ jar',       '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'wa’ jar',       '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  'cha’ jar',    '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  'cha’ jar',    '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  'wej jar',    '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'wa’ jar',       '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   'vagh jar',    '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'wa’ DIS',           '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), 'cha’ DIS',        '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'wa’ DIS',           '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   'vagh DIS',         '5 years = 5 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 112}), true), 'wa’vatlh wa’maH cha’ DIS',       '112 years = 112 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 122}), true), 'wa’vatlh cha’maH cha’ DIS',      '122 years = 122 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 213}), true), 'cha’vatlh wa’maH wej DIS',       '213 years = 213 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 223}), true), 'cha’vatlh cha’maH wej DIS',      '223 years = 223 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'puS lup pIq',  'suffix');\n    assert.equal(moment(0).from(30000), 'puS lup ret', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'puS lup ret',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'puS lup pIq', 'in a few seconds');\n    assert.equal(moment().add({h: 1}).fromNow(), 'wa’ rep pIq', 'in an hour');\n    assert.equal(moment().add({d: 5}).fromNow(), 'vagh leS', 'in 5 days');\n    assert.equal(moment().add({M: 2}).fromNow(), 'cha’ waQ', 'in 2 months');\n    assert.equal(moment().add({y: 1}).fromNow(), 'wa’ nem', 'in a year');\n    assert.equal(moment().add({s: -30}).fromNow(), 'puS lup ret', 'a few seconds ago');\n    assert.equal(moment().add({h: -1}).fromNow(), 'wa’ rep ret', 'an hour ago');\n    assert.equal(moment().add({d: -5}).fromNow(), 'vagh Hu’', '5 days ago');\n    assert.equal(moment().add({M: -2}).fromNow(), 'cha’ wen', '2 months ago');\n    assert.equal(moment().add({y: -1}).fromNow(), 'wa’ ben', 'a year ago');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'DaHjaj 12:00',     'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'DaHjaj 12:25',     'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'DaHjaj 13:00',     'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'wa’leS 12:00',     'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'DaHjaj 11:00',     'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'wa’Hu’ 12:00',     'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('LLL'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('LLL'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('LLL'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(), m.format('LLL'), 'Today - ' + i + ' days current time');\n\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(), m.format('LLL'), 'Today - ' + i + ' days beginning of day');\n\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(), m.format('LLL'), 'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2012, 0,  1]).format('w ww wo'), '52 52 52.', 'Jan  1 2012 should be week 52');\n    assert.equal(moment([2012, 0,  2]).format('w ww wo'),   '1 01 1.', 'Jan  2 2012 should be week 1');\n    assert.equal(moment([2012, 0,  8]).format('w ww wo'),   '1 01 1.', 'Jan  8 2012 should be week 1');\n    assert.equal(moment([2012, 0,  9]).format('w ww wo'),   '2 02 2.', 'Jan  9 2012 should be week 2');\n    assert.equal(moment([2012, 0, 15]).format('w ww wo'),   '2 02 2.', 'Jan 15 2012 should be week 2');\n});\n\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/test/locale/tr.js",
    "content": "import {localeModule, test} from '../qunit';\nimport moment from '../../moment';\nlocaleModule('tr');\n\ntest('parse', function (assert) {\n    var tests = 'Ocak Oca_Şubat Şub_Mart Mar_Nisan Nis_Mayıs May_Haziran Haz_Temmuz Tem_Ağustos Ağu_Eylül Eyl_Ekim Eki_Kasım Kas_Aralık Ara'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, MMMM Do YYYY, h:mm:ss a',      'Pazar, Şubat 14\\'üncü 2010, 3:25:50 pm'],\n            ['ddd, hA',                            'Paz, 3PM'],\n            ['M Mo MM MMMM MMM',                   '2 2\\'nci 02 Şubat Şub'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14\\'üncü 14'],\n            ['d do dddd ddd dd',                   '0 0\\'ıncı Pazar Paz Pz'],\n            ['DDD DDDo DDDD',                      '45 45\\'inci 045'],\n            ['w wo ww',                            '7 7\\'nci 07'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'pm PM'],\n            ['[yılın] DDDo [günü]',                'yılın 45\\'inci günü'],\n            ['LTS',                                '15:25:50'],\n            ['L',                                  '14.02.2010'],\n            ['LL',                                 '14 Şubat 2010'],\n            ['LLL',                                '14 Şubat 2010 15:25'],\n            ['LLLL',                               'Pazar, 14 Şubat 2010 15:25'],\n            ['l',                                  '14.2.2010'],\n            ['ll',                                 '14 Şub 2010'],\n            ['lll',                                '14 Şub 2010 15:25'],\n            ['llll',                               'Paz, 14 Şub 2010 15:25']\n        ],\n        DDDo = [\n            [359, '360\\'ıncı'],\n            [199, '200\\'üncü'],\n            [149, '150\\'nci']\n        ],\n        dt = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        DDDoDt,\n        i;\n\n    for (i = 0; i < a.length; i++) {\n        assert.equal(dt.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n    for (i = 0; i < DDDo.length; i++) {\n        DDDoDt = moment([2010]);\n        assert.equal(DDDoDt.add(DDDo[i][0], 'days').format('DDDo'), DDDo[i][1], DDDo[i][0] + ' ---> ' + DDDo[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1\\'inci', '1st');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2\\'nci', '2nd');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3\\'üncü', '3rd');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4\\'üncü', '4th');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5\\'inci', '5th');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6\\'ncı', '6th');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7\\'nci', '7th');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8\\'inci', '8th');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9\\'uncu', '9th');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10\\'uncu', '10th');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11\\'inci', '11th');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12\\'nci', '12th');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13\\'üncü', '13th');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14\\'üncü', '14th');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15\\'inci', '15th');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16\\'ncı', '16th');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17\\'nci', '17th');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18\\'inci', '18th');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19\\'uncu', '19th');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20\\'nci', '20th');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21\\'inci', '21th');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22\\'nci', '22th');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23\\'üncü', '23th');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24\\'üncü', '24th');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25\\'inci', '25th');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26\\'ncı', '26th');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27\\'nci', '27th');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28\\'inci', '28th');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29\\'uncu', '29th');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30\\'uncu', '30th');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31\\'inci', '31st');\n});\n\ntest('format month', function (assert) {\n    var expected = 'Ocak Oca_Şubat Şub_Mart Mar_Nisan Nis_Mayıs May_Haziran Haz_Temmuz Tem_Ağustos Ağu_Eylül Eyl_Ekim Eki_Kasım Kas_Aralık Ara'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'Pazar Paz Pz_Pazartesi Pts Pt_Salı Sal Sa_Çarşamba Çar Ça_Perşembe Per Pe_Cuma Cum Cu_Cumartesi Cts Ct'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'birkaç saniye', '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'bir dakika',      '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'bir dakika',      '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 dakika',     '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 dakika',    '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'bir saat',       '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'bir saat',       '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 saat',       '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 saat',       '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 saat',      '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'bir gün',         '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'bir gün',         '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 gün',        '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'bir gün',         '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 gün',        '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 gün',       '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'bir ay',       '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'bir ay',       '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'bir ay',       '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 ay',      '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 ay',      '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 ay',      '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'bir ay',       '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 ay',      '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'bir yıl',        '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 yıl',       '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'bir yıl',        '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 yıl',       '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'birkaç saniye sonra',  'prefix');\n    assert.equal(moment(0).from(30000), 'birkaç saniye önce', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'birkaç saniye önce',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'birkaç saniye sonra', 'in a few seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), '5 gün sonra', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'bugün saat 12:00',     'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'bugün saat 12:25',     'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'bugün saat 13:00',     'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'yarın saat 12:00',     'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'bugün saat 11:00',     'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'dün 12:00',            'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('[haftaya] dddd [saat] LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[haftaya] dddd [saat] LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[haftaya] dddd [saat] LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('[geçen hafta] dddd [saat] LT'),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[geçen hafta] dddd [saat] LT'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[geçen hafta] dddd [saat] LT'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2011, 11, 26]).format('w ww wo'), '1 01 1\\'inci', 'Dec 26 2011 should be week 1');\n    assert.equal(moment([2012,  0,  1]).format('w ww wo'), '1 01 1\\'inci', 'Jan  1 2012 should be week 1');\n    assert.equal(moment([2012,  0,  2]).format('w ww wo'), '2 02 2\\'nci', 'Jan  2 2012 should be week 2');\n    assert.equal(moment([2012,  0,  8]).format('w ww wo'), '2 02 2\\'nci', 'Jan  8 2012 should be week 2');\n    assert.equal(moment([2012,  0,  9]).format('w ww wo'), '3 03 3\\'üncü', 'Jan  9 2012 should be week 3');\n});\n\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/test/locale/tzl.js",
    "content": "import {localeModule, test} from '../qunit';\nimport moment from '../../moment';\nlocaleModule('tzl');\n\ntest('parse', function (assert) {\n    var tests = 'Januar Jan_Fevraglh Fev_Març Mar_Avrïu Avr_Mai Mai_Gün Gün_Julia Jul_Guscht Gus_Setemvar Set_Listopäts Lis_Noemvar Noe_Zecemvar Zec'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, MMMM Do YYYY, h.mm.ss a',      'Súladi, Fevraglh 14. 2010, 3.25.50 d\\'o'],\n            ['ddd, hA',                            'Súl, 3D\\'O'],\n            ['M Mo MM MMMM MMM',                   '2 2. 02 Fevraglh Fev'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14. 14'],\n            ['d do dddd ddd dd',                   '0 0. Súladi Súl Sú'],\n            ['DDD DDDo DDDD',                      '45 45. 045'],\n            ['w wo ww',                            '6 6. 06'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'd\\'o D\\'O'],\n            ['[the] DDDo [day of the year]',       'the 45. day of the year'],\n            ['LTS',                                '15.25.50'],\n            ['L',                                  '14.02.2010'],\n            ['LL',                                 '14. Fevraglh dallas 2010'],\n            ['LLL',                                '14. Fevraglh dallas 2010 15.25'],\n            ['LLLL',                               'Súladi, li 14. Fevraglh dallas 2010 15.25'],\n            ['l',                                  '14.2.2010'],\n            ['ll',                                 '14. Fev dallas 2010'],\n            ['lll',                                '14. Fev dallas 2010 15.25'],\n            ['llll',                               'Súl, li 14. Fev dallas 2010 15.25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1.', '1.');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2.', '2.');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3.', '3.');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4.', '4.');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5.', '5.');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6.', '6.');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7.', '7.');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8.', '8.');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9.', '9.');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10.', '10.');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11.', '11.');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12.', '12.');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13.', '13.');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14.', '14.');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15.', '15.');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16.', '16.');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17.', '17.');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18.', '18.');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19.', '19.');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20.', '20.');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21.', '21.');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22.', '22.');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23.', '23.');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24.', '24.');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25.', '25.');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26.', '26.');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27.', '27.');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28.', '28.');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29.', '29.');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30.', '30.');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31.', '31.');\n});\n\ntest('format month', function (assert) {\n    var expected = 'Januar Jan_Fevraglh Fev_Març Mar_Avrïu Avr_Mai Mai_Gün Gün_Julia Jul_Guscht Gus_Setemvar Set_Listopäts Lis_Noemvar Noe_Zecemvar Zec'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'Súladi Súl Sú_Lúneçi Lún Lú_Maitzi Mai Ma_Márcuri Már Má_Xhúadi Xhú Xh_Viénerçi Vié Vi_Sáturi Sát Sá'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'viensas secunds', '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  '\\'n míut',      '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  '\\'n míut',      '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 míuts',     '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 míuts',    '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  '\\'n þora',       '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  '\\'n þora',       '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 þoras',       '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 þoras',       '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 þoras',      '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  '\\'n ziua',         '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  '\\'n ziua',         '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 ziuas',        '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   '\\'n ziua',         '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 ziuas',        '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 ziuas',       '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  '\\'n mes',       '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  '\\'n mes',       '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  '\\'n mes',       '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 mesen',      '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 mesen',      '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 mesen',      '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   '\\'n mes',       '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 mesen',      '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), '\\'n ar',        '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 ars',       '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   '\\'n ar',        '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 ars',       '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'osprei viensas secunds',  'prefix');\n    assert.equal(moment(0).from(30000), 'ja\\'iensas secunds', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'ja\\'iensas secunds',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'osprei viensas secunds', 'in a few seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), 'osprei 5 ziuas', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'oxhi à 12.00',      'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'oxhi à 12.25',      'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'oxhi à 13.00',      'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'demà à 12.00',      'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'oxhi à 11.00',      'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'ieiri à 12.00',     'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('dddd [à] LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd [à] LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd [à] LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('[sür el] dddd [lasteu à] LT'),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[sür el] dddd [lasteu à] LT'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[sür el] dddd [lasteu à] LT'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\n// Monday is the first day of the week.\n// The week that contains Jan 4th is the first week of the year.\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2012, 0,  1]).format('w ww wo'), '52 52 52.', 'Jan  1 2012 should be week 52');\n    assert.equal(moment([2012, 0,  2]).format('w ww wo'),   '1 01 1.', 'Jan  2 2012 should be week 1');\n    assert.equal(moment([2012, 0,  8]).format('w ww wo'),   '1 01 1.', 'Jan  8 2012 should be week 1');\n    assert.equal(moment([2012, 0,  9]).format('w ww wo'),   '2 02 2.', 'Jan  9 2012 should be week 2');\n    assert.equal(moment([2012, 0, 15]).format('w ww wo'),   '2 02 2.', 'Jan 15 2012 should be week 2');\n});\n\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/test/locale/tzm-latn.js",
    "content": "import {localeModule, test} from '../qunit';\nimport moment from '../../moment';\nlocaleModule('tzm-latn');\n\ntest('parse', function (assert) {\n    var tests = 'innayr innayr_brˤayrˤ brˤayrˤ_marˤsˤ marˤsˤ_ibrir ibrir_mayyw mayyw_ywnyw ywnyw_ywlywz ywlywz_ɣwšt ɣwšt_šwtanbir šwtanbir_ktˤwbrˤ ktˤwbrˤ_nwwanbir nwwanbir_dwjnbir dwjnbir'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, MMMM Do YYYY, h:mm:ss a',      'asamas, brˤayrˤ 14 2010, 3:25:50 pm'],\n            ['ddd, hA',                            'asamas, 3PM'],\n            ['M Mo MM MMMM MMM',                   '2 2 02 brˤayrˤ brˤayrˤ'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14 14'],\n            ['d do dddd ddd dd',                   '0 0 asamas asamas asamas'],\n            ['DDD DDDo DDDD',                      '45 45 045'],\n            ['w wo ww',                            '8 8 08'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'pm PM'],\n            ['[the] DDDo [day of the year]',       'the 45 day of the year'],\n            ['LTS',                                '15:25:50'],\n            ['L',                                  '14/02/2010'],\n            ['LL',                                 '14 brˤayrˤ 2010'],\n            ['LLL',                                '14 brˤayrˤ 2010 15:25'],\n            ['LLLL',                               'asamas 14 brˤayrˤ 2010 15:25'],\n            ['l',                                  '14/2/2010'],\n            ['ll',                                 '14 brˤayrˤ 2010'],\n            ['lll',                                '14 brˤayrˤ 2010 15:25'],\n            ['llll',                               'asamas 14 brˤayrˤ 2010 15:25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1', '1');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2', '2');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3', '3');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4', '4');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5', '5');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6', '6');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7', '7');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8', '8');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9', '9');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10', '10');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11', '11');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12', '12');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13', '13');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14', '14');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15', '15');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16', '16');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17', '17');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18', '18');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19', '19');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20', '20');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21', '21');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22', '22');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23', '23');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24', '24');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25', '25');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26', '26');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27', '27');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28', '28');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29', '29');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30', '30');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31', '31');\n});\n\ntest('format month', function (assert) {\n    var expected = 'innayr innayr_brˤayrˤ brˤayrˤ_marˤsˤ marˤsˤ_ibrir ibrir_mayyw mayyw_ywnyw ywnyw_ywlywz ywlywz_ɣwšt ɣwšt_šwtanbir šwtanbir_ktˤwbrˤ ktˤwbrˤ_nwwanbir nwwanbir_dwjnbir dwjnbir'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'asamas asamas asamas_aynas aynas aynas_asinas asinas asinas_akras akras akras_akwas akwas akwas_asimwas asimwas asimwas_asiḍyas asiḍyas asiḍyas'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'imik', '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'minuḍ',      '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'minuḍ',      '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 minuḍ',     '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 minuḍ',    '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'saɛa',       '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'saɛa',       '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 tassaɛin',       '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 tassaɛin',       '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 tassaɛin',      '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'ass',         '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'ass',         '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 ossan',        '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'ass',         '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 ossan',        '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 ossan',       '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'ayowr',       '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'ayowr',       '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'ayowr',       '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 iyyirn',      '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 iyyirn',      '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 iyyirn',      '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'ayowr',       '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 iyyirn',      '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'asgas',        '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 isgasn',       '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'asgas',        '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 isgasn',       '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'dadkh s yan imik',  'prefix');\n    assert.equal(moment(0).from(30000), 'yan imik', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'yan imik',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'dadkh s yan imik', 'in a few seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), 'dadkh s yan 5 ossan', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'asdkh g 12:00',   'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'asdkh g 12:25',   'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'asdkh g 13:00',   'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'aska g 12:00',    'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'asdkh g 11:00',   'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'assant g 12:00',  'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('dddd [g] LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd [g] LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd [g] LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('dddd [g] LT'),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd [g] LT'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd [g] LT'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2011, 11, 31]).format('w ww wo'), '1 01 1', 'Dec 31 2011 should be week 1');\n    assert.equal(moment([2012,  0,  6]).format('w ww wo'), '1 01 1', 'Jan  6 2012 should be week 1');\n    assert.equal(moment([2012,  0,  7]).format('w ww wo'), '2 02 2', 'Jan  7 2012 should be week 2');\n    assert.equal(moment([2012,  0, 13]).format('w ww wo'), '2 02 2', 'Jan 13 2012 should be week 2');\n    assert.equal(moment([2012,  0, 14]).format('w ww wo'), '3 03 3', 'Jan 14 2012 should be week 3');\n});\n\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/test/locale/tzm.js",
    "content": "import {localeModule, test} from '../qunit';\nimport moment from '../../moment';\nlocaleModule('tzm');\n\ntest('parse', function (assert) {\n    var tests = 'ⵉⵏⵏⴰⵢⵔ ⵉⵏⵏⴰⵢⵔ_ⴱⵕⴰⵢⵕ ⴱⵕⴰⵢⵕ_ⵎⴰⵕⵚ ⵎⴰⵕⵚ_ⵉⴱⵔⵉⵔ ⵉⴱⵔⵉⵔ_ⵎⴰⵢⵢⵓ ⵎⴰⵢⵢⵓ_ⵢⵓⵏⵢⵓ ⵢⵓⵏⵢⵓ_ⵢⵓⵍⵢⵓⵣ ⵢⵓⵍⵢⵓⵣ_ⵖⵓⵛⵜ ⵖⵓⵛⵜ_ⵛⵓⵜⴰⵏⴱⵉⵔ ⵛⵓⵜⴰⵏⴱⵉⵔ_ⴽⵟⵓⴱⵕ ⴽⵟⵓⴱⵕ_ⵏⵓⵡⴰⵏⴱⵉⵔ ⵏⵓⵡⴰⵏⴱⵉⵔ_ⴷⵓⵊⵏⴱⵉⵔ ⴷⵓⵊⵏⴱⵉⵔ'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, MMMM Do YYYY, h:mm:ss a',      'ⴰⵙⴰⵎⴰⵙ, ⴱⵕⴰⵢⵕ 14 2010, 3:25:50 pm'],\n            ['ddd, hA',                            'ⴰⵙⴰⵎⴰⵙ, 3PM'],\n            ['M Mo MM MMMM MMM',                   '2 2 02 ⴱⵕⴰⵢⵕ ⴱⵕⴰⵢⵕ'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14 14'],\n            ['d do dddd ddd dd',                   '0 0 ⴰⵙⴰⵎⴰⵙ ⴰⵙⴰⵎⴰⵙ ⴰⵙⴰⵎⴰⵙ'],\n            ['DDD DDDo DDDD',                      '45 45 045'],\n            ['w wo ww',                            '8 8 08'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'pm PM'],\n            ['[the] DDDo [day of the year]',       'the 45 day of the year'],\n            ['LTS',                                '15:25:50'],\n            ['L',                                  '14/02/2010'],\n            ['LL',                                 '14 ⴱⵕⴰⵢⵕ 2010'],\n            ['LLL',                                '14 ⴱⵕⴰⵢⵕ 2010 15:25'],\n            ['LLLL',                               'ⴰⵙⴰⵎⴰⵙ 14 ⴱⵕⴰⵢⵕ 2010 15:25'],\n            ['l',                                  '14/2/2010'],\n            ['ll',                                 '14 ⴱⵕⴰⵢⵕ 2010'],\n            ['lll',                                '14 ⴱⵕⴰⵢⵕ 2010 15:25'],\n            ['llll',                               'ⴰⵙⴰⵎⴰⵙ 14 ⴱⵕⴰⵢⵕ 2010 15:25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1', '1');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2', '2');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3', '3');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4', '4');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5', '5');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6', '6');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7', '7');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8', '8');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9', '9');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10', '10');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11', '11');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12', '12');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13', '13');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14', '14');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15', '15');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16', '16');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17', '17');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18', '18');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19', '19');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20', '20');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21', '21');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22', '22');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23', '23');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24', '24');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25', '25');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26', '26');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27', '27');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28', '28');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29', '29');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30', '30');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31', '31');\n});\n\ntest('format month', function (assert) {\n    var expected = 'ⵉⵏⵏⴰⵢⵔ ⵉⵏⵏⴰⵢⵔ_ⴱⵕⴰⵢⵕ ⴱⵕⴰⵢⵕ_ⵎⴰⵕⵚ ⵎⴰⵕⵚ_ⵉⴱⵔⵉⵔ ⵉⴱⵔⵉⵔ_ⵎⴰⵢⵢⵓ ⵎⴰⵢⵢⵓ_ⵢⵓⵏⵢⵓ ⵢⵓⵏⵢⵓ_ⵢⵓⵍⵢⵓⵣ ⵢⵓⵍⵢⵓⵣ_ⵖⵓⵛⵜ ⵖⵓⵛⵜ_ⵛⵓⵜⴰⵏⴱⵉⵔ ⵛⵓⵜⴰⵏⴱⵉⵔ_ⴽⵟⵓⴱⵕ ⴽⵟⵓⴱⵕ_ⵏⵓⵡⴰⵏⴱⵉⵔ ⵏⵓⵡⴰⵏⴱⵉⵔ_ⴷⵓⵊⵏⴱⵉⵔ ⴷⵓⵊⵏⴱⵉⵔ'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'ⴰⵙⴰⵎⴰⵙ ⴰⵙⴰⵎⴰⵙ ⴰⵙⴰⵎⴰⵙ_ⴰⵢⵏⴰⵙ ⴰⵢⵏⴰⵙ ⴰⵢⵏⴰⵙ_ⴰⵙⵉⵏⴰⵙ ⴰⵙⵉⵏⴰⵙ ⴰⵙⵉⵏⴰⵙ_ⴰⴽⵔⴰⵙ ⴰⴽⵔⴰⵙ ⴰⴽⵔⴰⵙ_ⴰⴽⵡⴰⵙ ⴰⴽⵡⴰⵙ ⴰⴽⵡⴰⵙ_ⴰⵙⵉⵎⵡⴰⵙ ⴰⵙⵉⵎⵡⴰⵙ ⴰⵙⵉⵎⵡⴰⵙ_ⴰⵙⵉⴹⵢⴰⵙ ⴰⵙⵉⴹⵢⴰⵙ ⴰⵙⵉⴹⵢⴰⵙ'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'ⵉⵎⵉⴽ', '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'ⵎⵉⵏⵓⴺ',      '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'ⵎⵉⵏⵓⴺ',      '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 ⵎⵉⵏⵓⴺ',     '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 ⵎⵉⵏⵓⴺ',    '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'ⵙⴰⵄⴰ',       '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'ⵙⴰⵄⴰ',       '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 ⵜⴰⵙⵙⴰⵄⵉⵏ',       '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 ⵜⴰⵙⵙⴰⵄⵉⵏ',       '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 ⵜⴰⵙⵙⴰⵄⵉⵏ',      '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'ⴰⵙⵙ',         '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'ⴰⵙⵙ',         '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 oⵙⵙⴰⵏ',        '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'ⴰⵙⵙ',         '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 oⵙⵙⴰⵏ',        '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 oⵙⵙⴰⵏ',       '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'ⴰⵢoⵓⵔ',       '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'ⴰⵢoⵓⵔ',       '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'ⴰⵢoⵓⵔ',       '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 ⵉⵢⵢⵉⵔⵏ',      '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 ⵉⵢⵢⵉⵔⵏ',      '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 ⵉⵢⵢⵉⵔⵏ',      '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'ⴰⵢoⵓⵔ',       '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 ⵉⵢⵢⵉⵔⵏ',      '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'ⴰⵙⴳⴰⵙ',        '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 ⵉⵙⴳⴰⵙⵏ',       '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'ⴰⵙⴳⴰⵙ',        '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 ⵉⵙⴳⴰⵙⵏ',       '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'ⴷⴰⴷⵅ ⵙ ⵢⴰⵏ ⵉⵎⵉⴽ',  'prefix');\n    assert.equal(moment(0).from(30000), 'ⵢⴰⵏ ⵉⵎⵉⴽ', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'ⵢⴰⵏ ⵉⵎⵉⴽ',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'ⴷⴰⴷⵅ ⵙ ⵢⴰⵏ ⵉⵎⵉⴽ', 'in a few seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), 'ⴷⴰⴷⵅ ⵙ ⵢⴰⵏ 5 oⵙⵙⴰⵏ', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'ⴰⵙⴷⵅ ⴴ 12:00',  'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'ⴰⵙⴷⵅ ⴴ 12:25',  'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'ⴰⵙⴷⵅ ⴴ 13:00',  'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'ⴰⵙⴽⴰ ⴴ 12:00',  'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'ⴰⵙⴷⵅ ⴴ 11:00',  'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'ⴰⵚⴰⵏⵜ ⴴ 12:00',  'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('dddd [ⴴ] LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd [ⴴ] LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd [ⴴ] LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('dddd [ⴴ] LT'),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd [ⴴ] LT'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd [ⴴ] LT'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2011, 11, 31]).format('w ww wo'), '1 01 1', 'Dec 31 2011 should be week 1');\n    assert.equal(moment([2012,  0,  6]).format('w ww wo'), '1 01 1', 'Jan  6 2012 should be week 1');\n    assert.equal(moment([2012,  0,  7]).format('w ww wo'), '2 02 2', 'Jan  7 2012 should be week 2');\n    assert.equal(moment([2012,  0, 13]).format('w ww wo'), '2 02 2', 'Jan 13 2012 should be week 2');\n    assert.equal(moment([2012,  0, 14]).format('w ww wo'), '3 03 3', 'Jan 14 2012 should be week 3');\n});\n\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/test/locale/uk.js",
    "content": "import {localeModule, test} from '../qunit';\nimport moment from '../../moment';\nlocaleModule('uk');\n\ntest('parse', function (assert) {\n    var tests = 'січень січ_лютий лют_березень бер_квітень квіт_травень трав_червень черв_липень лип_серпень серп_вересень вер_жовтень жовт_листопад лист_грудень груд'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, Do MMMM YYYY, HH:mm:ss',       'неділя, 14-го лютого 2010, 15:25:50'],\n            ['ddd, h A',                           'нд, 3 дня'],\n            ['M Mo MM MMMM MMM',                   '2 2-й 02 лютий лют'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14-го 14'],\n            ['d do dddd ddd dd',                   '0 0-й неділя нд нд'],\n            ['DDD DDDo DDDD',                      '45 45-й 045'],\n            ['w wo ww',                            '7 7-й 07'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'дня дня'],\n            ['DDDo [день року]',                  '45-й день року'],\n            ['LTS',                                '15:25:50'],\n            ['L',                                  '14.02.2010'],\n            ['LL',                                 '14 лютого 2010 р.'],\n            ['LLL',                                '14 лютого 2010 р., 15:25'],\n            ['LLLL',                               'неділя, 14 лютого 2010 р., 15:25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format meridiem', function (assert) {\n    assert.equal(moment([2012, 11, 28, 0, 0]).format('A'), 'ночі', 'night');\n    assert.equal(moment([2012, 11, 28, 3, 59]).format('A'), 'ночі', 'night');\n    assert.equal(moment([2012, 11, 28, 4, 0]).format('A'), 'ранку', 'morning');\n    assert.equal(moment([2012, 11, 28, 11, 59]).format('A'), 'ранку', 'morning');\n    assert.equal(moment([2012, 11, 28, 12, 0]).format('A'), 'дня', 'afternoon');\n    assert.equal(moment([2012, 11, 28, 16, 59]).format('A'), 'дня', 'afternoon');\n    assert.equal(moment([2012, 11, 28, 17, 0]).format('A'), 'вечора', 'evening');\n    assert.equal(moment([2012, 11, 28, 23, 59]).format('A'), 'вечора', 'evening');\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1-й', '1-й');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2-й', '2-й');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3-й', '3-й');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4-й', '4-й');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5-й', '5-й');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6-й', '6-й');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7-й', '7-й');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8-й', '8-й');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9-й', '9-й');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10-й', '10-й');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11-й', '11-й');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12-й', '12-й');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13-й', '13-й');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14-й', '14-й');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15-й', '15-й');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16-й', '16-й');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17-й', '17-й');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18-й', '18-й');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19-й', '19-й');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20-й', '20-й');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21-й', '21-й');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22-й', '22-й');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23-й', '23-й');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24-й', '24-й');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25-й', '25-й');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26-й', '26-й');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27-й', '27-й');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28-й', '28-й');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29-й', '29-й');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30-й', '30-й');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31-й', '31-й');\n});\n\ntest('format month', function (assert) {\n    var expected = 'січень січ_лютий лют_березень бер_квітень квіт_травень трав_червень черв_липень лип_серпень серп_вересень вер_жовтень жовт_листопад лист_грудень груд'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format month case', function (assert) {\n    var months = {\n        'nominative': 'січень_лютий_березень_квітень_травень_червень_липень_серпень_вересень_жовтень_листопад_грудень'.split('_'),\n        'accusative': 'січня_лютого_березня_квітня_травня_червня_липня_серпня_вересня_жовтня_листопада_грудня'.split('_')\n    }, i;\n    for (i = 0; i < 12; i++) {\n        assert.equal(moment([2011, i, 1]).format('D MMMM'), '1 ' + months.accusative[i], '1 ' + months.accusative[i]);\n        assert.equal(moment([2011, i, 1]).format('MMMM'), months.nominative[i], '1 ' + months.nominative[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'неділя нд нд_понеділок пн пн_вівторок вт вт_середа ср ср_четвер чт чт_п’ятниця пт пт_субота сб сб'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'декілька секунд',    '44 seconds = seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'хвилина',   '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'хвилина',   '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 хвилини',  '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 хвилини', '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'годину',    '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'годину',    '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 години',    '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 годин',    '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 година',   '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'день',      '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'день',      '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 дні',     '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'день',      '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 днів',     '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 11}), true),  '11 днів',     '11 days = 11 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 21}), true),  '21 день',     '21 days = 21 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 днів',    '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'місяць',    '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'місяць',    '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'місяць',    '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 місяці',   '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 місяці',   '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 місяці',   '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'місяць',    '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 місяців',   '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'рік',     '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 роки',    '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'рік',     '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 років',    '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'за декілька секунд', 'prefix');\n    assert.equal(moment(0).from(30000), 'декілька секунд тому', 'suffix');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'за декілька секунд', 'in seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), 'за 5 днів', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'Сьогодні о 12:00',   'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'Сьогодні о 12:25',   'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'Сьогодні о 13:00',   'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'Завтра о 12:00',     'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 2}).calendar(),  'Сьогодні о 10:00',   'Now minus 2 hours');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'Вчора о 12:00',      'yesterday at the same time');\n    // A special case for Ukrainian since 11 hours have different preposition\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'Сьогодні об 11:00',  'same day at 11 o\\'clock');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('[У] dddd [о' + (m.hours() === 11 ? 'б' : '') + '] LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[У] dddd [о] LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[У] dddd [о] LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n\n    function makeFormat(d) {\n        switch (d.day()) {\n            case 0:\n            case 3:\n            case 5:\n            case 6:\n                return '[Минулої] dddd [о' + (d.hours() === 11 ? 'б' : '') + '] LT';\n            case 1:\n            case 2:\n            case 4:\n                return '[Минулого] dddd [о' + (d.hours() === 11 ? 'б' : '') + '] LT';\n        }\n    }\n\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format(makeFormat(m)),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format(makeFormat(m)),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format(makeFormat(m)),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2011, 11, 26]).format('w ww wo'), '1 01 1-й', 'Dec 26 2011 should be week 1');\n    assert.equal(moment([2012,  0,  1]).format('w ww wo'), '1 01 1-й', 'Jan  1 2012 should be week 1');\n    assert.equal(moment([2012,  0,  2]).format('w ww wo'), '2 02 2-й', 'Jan  2 2012 should be week 2');\n    assert.equal(moment([2012,  0,  8]).format('w ww wo'), '2 02 2-й', 'Jan  8 2012 should be week 2');\n    assert.equal(moment([2012,  0,  9]).format('w ww wo'), '3 03 3-й', 'Jan  9 2012 should be week 3');\n});\n\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/test/locale/ur.js",
    "content": "import {localeModule, test} from '../qunit';\nimport moment from '../../moment';\nlocaleModule('ur');\n\nvar months = [\n    'جنوری',\n    'فروری',\n    'مارچ',\n    'اپریل',\n    'مئی',\n    'جون',\n    'جولائی',\n    'اگست',\n    'ستمبر',\n    'اکتوبر',\n    'نومبر',\n    'دسمبر'\n];\nvar days = [\n    'اتوار',\n    'پیر',\n    'منگل',\n    'بدھ',\n    'جمعرات',\n    'جمعہ',\n    'ہفتہ'\n];\n\ntest('parse', function (assert) {\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (var i = 0; i < 12; i++) {\n        equalTest(months[i], 'MMM', i);\n        equalTest(months[i], 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, MMMM Do YYYY, h:mm:ss a',      'اتوار، فروری 14 2010، 3:25:50 شام'],\n            ['ddd, hA',                            'اتوار، 3شام'],\n            ['M Mo MM MMMM MMM',                   '2 2 02 فروری فروری'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14 14'],\n            ['d do dddd ddd dd',                   '0 0 اتوار اتوار اتوار'],\n            ['DDD DDDo DDDD',                      '45 45 045'],\n            ['w wo ww',                            '6 6 06'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'شام شام'],\n            ['[سال کا] DDDo[واں دن]',       'سال کا 45واں دن'],\n            ['LTS',                                '15:25:50'],\n            ['L',                                  '14/02/2010'],\n            ['LL',                                 '14 فروری 2010'],\n            ['LLL',                                '14 فروری 2010 15:25'],\n            ['LLLL',                               'اتوار، 14 فروری 2010 15:25'],\n            ['l',                                  '14/2/2010'],\n            ['ll',                                 '14 فروری 2010'],\n            ['lll',                                '14 فروری 2010 15:25'],\n            ['llll',                               'اتوار، 14 فروری 2010 15:25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1', '1');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2', '2');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3', '3');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4', '4');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5', '5');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6', '6');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7', '7');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8', '8');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9', '9');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10', '10');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11', '11');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12', '12');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13', '13');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14', '14');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15', '15');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16', '16');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17', '17');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18', '18');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19', '19');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20', '20');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21', '21');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22', '22');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23', '23');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24', '24');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25', '25');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26', '26');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27', '27');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28', '28');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29', '29');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30', '30');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31', '31');\n});\n\ntest('format month', function (assert) {\n    for (var i = 0; i < months.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), months[i] + ' ' + months[i], months[i] + ' ' + months[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    for (var i = 0; i < days.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), days[i] + ' ' + days[i] + ' ' + days[i], days[i] + ' ' + days[i] + ' ' + days[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'چند سیکنڈ', '44 seconds = چند سیکنڈ');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'ایک منٹ',      '45 seconds = ایک منٹ');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'ایک منٹ',      '89 seconds = ایک منٹ');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 منٹ',     '90 seconds = 2 منٹ');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 منٹ',    '44 minutes = 44 منٹ');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'ایک گھنٹہ',       '45 minutes = ایک گھنٹہ');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'ایک گھنٹہ',       '89 minutes = ایک گھنٹہ');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 گھنٹے',       '90 minutes = 2 گھنٹے');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 گھنٹے',       '5 hours = 5 گھنٹے');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 گھنٹے',      '21 hours = 21 گھنٹے');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'ایک دن',         '22 hours = ایک دن');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'ایک دن',         '35 hours = ایک دن');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 دن',        '36 hours = 2 دن');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'ایک دن',         '1 day = ایک دن');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 دن',        '5 days = 5 دن');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 دن',       '25 days = 25 دن');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'ایک ماہ',       '26 days = ایک ماہ');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'ایک ماہ',       '30 days = ایک ماہ');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'ایک ماہ',       '43 days = ایک ماہ');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 ماہ',      '46 days = 2 ماہ');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 ماہ',      '75 days = 2 ماہ');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 ماہ',      '76 days = 3 ماہ');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'ایک ماہ',       '1 month = ایک ماہ');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 ماہ',      '5 months = 5 ماہ');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'ایک سال',        '345 days = ایک سال');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 سال',       '548 days = 2 سال');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'ایک سال',        '1 year = ایک سال');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 سال',       '5 years = 5 سال');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'چند سیکنڈ بعد',  'prefix');\n    assert.equal(moment(0).from(30000), 'چند سیکنڈ قبل', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'چند سیکنڈ قبل',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'چند سیکنڈ بعد', 'in a few seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), '5 دن بعد', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'آج بوقت 12:00',      'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'آج بوقت 12:25',      'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'آج بوقت 13:00',      'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'کل بوقت 12:00',   'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'آج بوقت 11:00',      'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'گذشتہ روز بوقت 12:00',  'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('dddd [بوقت] LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd [بوقت] LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd [بوقت] LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('[گذشتہ] dddd [بوقت] LT'),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[گذشتہ] dddd [بوقت] LT'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[گذشتہ] dddd [بوقت] LT'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2012, 0,  1]).format('w ww wo'), '52 52 52', 'Jan  1 2012 should be week 52');\n    assert.equal(moment([2012, 0,  2]).format('w ww wo'),   '1 01 1', 'Jan  2 2012 should be week 1');\n    assert.equal(moment([2012, 0,  8]).format('w ww wo'),   '1 01 1', 'Jan  8 2012 should be week 1');\n    assert.equal(moment([2012, 0,  9]).format('w ww wo'),   '2 02 2', 'Jan  9 2012 should be week 2');\n    assert.equal(moment([2012, 0, 15]).format('w ww wo'),   '2 02 2', 'Jan 15 2012 should be week 2');\n});\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/test/locale/uz-latn.js",
    "content": "import {localeModule, test} from '../qunit';\nimport moment from '../../moment';\nlocaleModule('uz-latn');\n\ntest('parse', function (assert) {\n    var tests = 'Yanvar Yan_Fevral Fev_Mart Mar_Aprel Apr_May May_Iyun Iyun_Iyul Iyul_Avgust Avg_Sentabr Sen_Oktabr Okt_Noyabr Noy_Dekabr Dek'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, Do-MMMM YYYY, h:mm:ss',        'Yakshanba, 14-Fevral 2010, 3:25:50'],\n            ['ddd, h:mm',                          'Yak, 3:25'],\n            ['M Mo MM MMMM MMM',                   '2 2 02 Fevral Fev'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14 14'],\n            ['d do dddd ddd dd',                   '0 0 Yakshanba Yak Ya'],\n            ['DDD DDDo DDDD',                      '45 45 045'],\n            ['w wo ww',                            '7 7 07'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'pm PM'],\n            ['[yilning] DDDo-[kuni]',             'yilning 45-kuni'],\n            ['LTS',                                '15:25:50'],\n            ['L',                                  '14/02/2010'],\n            ['LL',                                 '14 Fevral 2010'],\n            ['LLL',                                '14 Fevral 2010 15:25'],\n            ['LLLL',                               '14 Fevral 2010, Yakshanba 15:25'],\n            ['l',                                  '14/2/2010'],\n            ['ll',                                 '14 Fev 2010'],\n            ['lll',                                '14 Fev 2010 15:25'],\n            ['llll',                               '14 Fev 2010, Yak 15:25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2016, 0, 1]).format('DDDo'), '1', '1');\n    assert.equal(moment([2016, 0, 2]).format('DDDo'), '2', '2');\n    assert.equal(moment([2016, 0, 3]).format('DDDo'), '3', '3');\n    assert.equal(moment([2016, 0, 4]).format('DDDo'), '4', '4');\n    assert.equal(moment([2016, 0, 5]).format('DDDo'), '5', '5');\n    assert.equal(moment([2016, 0, 6]).format('DDDo'), '6', '6');\n    assert.equal(moment([2016, 0, 7]).format('DDDo'), '7', '7');\n    assert.equal(moment([2016, 0, 8]).format('DDDo'), '8', '8');\n    assert.equal(moment([2016, 0, 9]).format('DDDo'), '9', '9');\n    assert.equal(moment([2016, 0, 10]).format('DDDo'), '10', '10');\n\n    assert.equal(moment([2016, 0, 11]).format('DDDo'), '11', '11');\n    assert.equal(moment([2016, 0, 12]).format('DDDo'), '12', '12');\n    assert.equal(moment([2016, 0, 13]).format('DDDo'), '13', '13');\n    assert.equal(moment([2016, 0, 14]).format('DDDo'), '14', '14');\n    assert.equal(moment([2016, 0, 15]).format('DDDo'), '15', '15');\n    assert.equal(moment([2016, 0, 16]).format('DDDo'), '16', '16');\n    assert.equal(moment([2016, 0, 17]).format('DDDo'), '17', '17');\n    assert.equal(moment([2016, 0, 18]).format('DDDo'), '18', '18');\n    assert.equal(moment([2016, 0, 19]).format('DDDo'), '19', '19');\n    assert.equal(moment([2016, 0, 20]).format('DDDo'), '20', '20');\n\n    assert.equal(moment([2016, 0, 21]).format('DDDo'), '21', '21');\n    assert.equal(moment([2016, 0, 22]).format('DDDo'), '22', '22');\n    assert.equal(moment([2016, 0, 23]).format('DDDo'), '23', '23');\n    assert.equal(moment([2016, 0, 24]).format('DDDo'), '24', '24');\n    assert.equal(moment([2016, 0, 25]).format('DDDo'), '25', '25');\n    assert.equal(moment([2016, 0, 26]).format('DDDo'), '26', '26');\n    assert.equal(moment([2016, 0, 27]).format('DDDo'), '27', '27');\n    assert.equal(moment([2016, 0, 28]).format('DDDo'), '28', '28');\n    assert.equal(moment([2016, 0, 29]).format('DDDo'), '29', '29');\n    assert.equal(moment([2016, 0, 30]).format('DDDo'), '30', '30');\n\n    assert.equal(moment([2016, 0, 31]).format('DDDo'), '31', '31');\n});\n\ntest('format month', function (assert) {\n    var expected = 'Yanvar Yan_Fevral Fev_Mart Mar_Aprel Apr_May May_Iyun Iyun_Iyul Iyul_Avgust Avg_Sentabr Sen_Oktabr Okt_Noyabr Noy_Dekabr Dek'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2016, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'Yakshanba Yak Ya_Dushanba Dush Du_Seshanba Sesh Se_Chorshanba Chor Cho_Payshanba Pay Pa_Juma Jum Ju_Shanba Shan Sha'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2016, 0, 3 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2017, 1, 28]);\n    assert.equal(start.from(moment([2017, 1, 28]).add({s: 44}), true),  'soniya', '44 soniya = soniya');\n    assert.equal(start.from(moment([2017, 1, 28]).add({s: 45}), true),  'bir daqiqa',      '45 soniya = bir daqiqa');\n    assert.equal(start.from(moment([2017, 1, 28]).add({s: 89}), true),  'bir daqiqa',      '89 soniya = bir daqiqa');\n    assert.equal(start.from(moment([2017, 1, 28]).add({s: 90}), true),  '2 daqiqa',     '90 soniya = 2 daqiqa');\n    assert.equal(start.from(moment([2017, 1, 28]).add({m: 44}), true),  '44 daqiqa',    '44 daqiqa = 44 daqiqa');\n    assert.equal(start.from(moment([2017, 1, 28]).add({m: 45}), true),  'bir soat',       '45 minut = bir soat');\n    assert.equal(start.from(moment([2017, 1, 28]).add({m: 89}), true),  'bir soat',       '89 minut = bir soat');\n    assert.equal(start.from(moment([2017, 1, 28]).add({m: 90}), true),  '2 soat',       '90 minut = 2 soat');\n    assert.equal(start.from(moment([2017, 1, 28]).add({h: 5}), true),   '5 soat',       '5 soat = 5 soat');\n    assert.equal(start.from(moment([2017, 1, 28]).add({h: 21}), true),  '21 soat',      '21 soat = 21 soat');\n    assert.equal(start.from(moment([2017, 1, 28]).add({h: 22}), true),  'bir kun',         '22 soat = bir kun');\n    assert.equal(start.from(moment([2017, 1, 28]).add({h: 35}), true),  'bir kun',         '35 soat = bir kun');\n    assert.equal(start.from(moment([2017, 1, 28]).add({h: 36}), true),  '2 kun',        '36 soat = 2 kun');\n    assert.equal(start.from(moment([2017, 1, 28]).add({d: 1}), true),   'bir kun',         '1 kun = 1 kun');\n    assert.equal(start.from(moment([2017, 1, 28]).add({d: 5}), true),   '5 kun',        '5 kun = 5 kun');\n    assert.equal(start.from(moment([2017, 1, 28]).add({d: 25}), true),  '25 kun',       '25 kun = 25 kun');\n    assert.equal(start.from(moment([2017, 1, 28]).add({d: 26}), true),  'bir oy',       '26 kun = bir oy');\n    assert.equal(start.from(moment([2017, 1, 28]).add({d: 30}), true),  'bir oy',       '30 kun = bir oy');\n    assert.equal(start.from(moment([2017, 1, 28]).add({d: 43}), true),  'bir oy',       '45 kun = bir oy');\n    assert.equal(start.from(moment([2017, 1, 28]).add({d: 46}), true),  '2 oy',      '46 kun = 2 oy');\n    assert.equal(start.from(moment([2017, 1, 28]).add({d: 74}), true),  '2 oy',      '75 kun = 2 oy');\n    assert.equal(start.from(moment([2017, 1, 28]).add({d: 76}), true),  '3 oy',      '76 kun = 3 oy');\n    assert.equal(start.from(moment([2017, 1, 28]).add({M: 1}), true),   'bir oy',       'bir oy = bir oy');\n    assert.equal(start.from(moment([2017, 1, 28]).add({M: 5}), true),   '5 oy',      '5 oy = 5 oy');\n    assert.equal(start.from(moment([2017, 1, 28]).add({d: 345}), true), 'bir yil',        '345 kun = bir yil');\n    assert.equal(start.from(moment([2017, 1, 28]).add({d: 548}), true), '2 yil',       '548 kun = 2 yil');\n    assert.equal(start.from(moment([2017, 1, 28]).add({y: 1}), true),   'bir yil',        '1 yil = bir yil');\n    assert.equal(start.from(moment([2017, 1, 28]).add({y: 5}), true),   '5 yil',       '5 yil = 5 yil');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'Yaqin soniya ichida',  'prefix');\n    assert.equal(moment(0).from(30000), 'Bir necha soniya oldin', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'Bir necha soniya oldin',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'Yaqin soniya ichida', 'in a few seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), 'Yaqin 5 kun ichida', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'Bugun soat 12:00 da',  'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'Bugun soat 12:25 da',  'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'Bugun soat 13:00 da',  'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'Ertaga 12:00 da',      'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'Bugun soat 11:00 da',  'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'Kecha soat 12:00 da',   'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('dddd [kuni soat] LT [da]'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd [kuni soat] LT [da]'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd [kuni soat] LT [da]'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('[O\\'tgan] dddd [kuni soat] LT [da]'),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[O\\'tgan] dddd [kuni soat] LT [da]'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[O\\'tgan] dddd [kuni soat] LT [da]'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2012, 0,  1]).format('w ww wo'), '1 01 1', 'Jan  1 2012 should be week 52');\n    assert.equal(moment([2012, 0,  2]).format('w ww wo'),   '2 02 2', 'Jan  2 2012 should be week 1');\n    assert.equal(moment([2012, 0,  8]).format('w ww wo'),   '2 02 2', 'Jan  8 2012 should be week 1');\n    assert.equal(moment([2012, 0,  9]).format('w ww wo'),   '3 03 3', 'Jan  9 2012 should be week 2');\n    assert.equal(moment([2012, 0, 15]).format('w ww wo'),   '3 03 3', 'Jan 15 2012 should be week 2');\n});\n\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/test/locale/uz.js",
    "content": "import {localeModule, test} from '../qunit';\nimport moment from '../../moment';\nlocaleModule('uz');\n\ntest('parse', function (assert) {\n    var tests = 'январ янв_феврал фев_март мар_апрел апр_май май_июн июн_июл июл_август авг_сентябр сен_октябр окт_ноябр ноя_декабр дек'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, Do-MMMM YYYY, h:mm:ss',        'Якшанба, 14-феврал 2010, 3:25:50'],\n            ['ddd, h:mm',                          'Якш, 3:25'],\n            ['M Mo MM MMMM MMM',                   '2 2 02 феврал фев'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14 14'],\n            ['d do dddd ddd dd',                   '0 0 Якшанба Якш Як'],\n            ['DDD DDDo DDDD',                      '45 45 045'],\n            ['w wo ww',                            '7 7 07'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'pm PM'],\n            ['[йилнинг] DDDo-[куни]',             'йилнинг 45-куни'],\n            ['LTS',                                '15:25:50'],\n            ['L',                                  '14/02/2010'],\n            ['LL',                                 '14 феврал 2010'],\n            ['LLL',                                '14 феврал 2010 15:25'],\n            ['LLLL',                               '14 феврал 2010, Якшанба 15:25'],\n            ['l',                                  '14/2/2010'],\n            ['ll',                                 '14 фев 2010'],\n            ['lll',                                '14 фев 2010 15:25'],\n            ['llll',                               '14 фев 2010, Якш 15:25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1', '1');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2', '2');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3', '3');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4', '4');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5', '5');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6', '6');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7', '7');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8', '8');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9', '9');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10', '10');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11', '11');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12', '12');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13', '13');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14', '14');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15', '15');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16', '16');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17', '17');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18', '18');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19', '19');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20', '20');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21', '21');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22', '22');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23', '23');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24', '24');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25', '25');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26', '26');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27', '27');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28', '28');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29', '29');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30', '30');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31', '31');\n});\n\ntest('format month', function (assert) {\n    var expected = 'январ янв_феврал фев_март мар_апрел апр_май май_июн июн_июл июл_август авг_сентябр сен_октябр окт_ноябр ноя_декабр дек'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'Якшанба Якш Як_Душанба Душ Ду_Сешанба Сеш Се_Чоршанба Чор Чо_Пайшанба Пай Па_Жума Жум Жу_Шанба Шан Ша'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'фурсат', '44 секунд = фурсат');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'бир дакика',      '45 секунд = бир дакика');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'бир дакика',      '89 секунд = бир дакика');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 дакика',     '90 секунд = 2 дакика');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 дакика',    '44 дакика = 44 дакика');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'бир соат',       '45 минут = бир соат');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'бир соат',       '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 соат',       '90 минут = 2 соат');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 соат',       '5 соат = 5 соат');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 соат',      '21 соат = 21 соат');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'бир кун',         '22 соат = бир кун');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'бир кун',         '35 соат = бир кун');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 кун',        '36 соат = 2 кун');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'бир кун',         '1 кун = 1 кун');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 кун',        '5 кун = 5 кун');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 кун',       '25 кун = 25 кун');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'бир ой',       '26 кун = бир ой');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'бир ой',       '30 кун = бир ой');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'бир ой',       '45 кун = бир ой');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 ой',      '46 кун = 2 ой');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 ой',      '75 кун = 2 ой');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 ой',      '76 кун = 3 ой');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'бир ой',       'бир ой = бир ой');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 ой',      '5 ой = 5 ой');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'бир йил',        '345 кун = бир йил');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 йил',       '548 кун = 2 йил');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'бир йил',        '1 йил = бир йил');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 йил',       '5 йил = 5 йил');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'Якин фурсат ичида',  'prefix');\n    assert.equal(moment(0).from(30000), 'Бир неча фурсат олдин', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'Бир неча фурсат олдин',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'Якин фурсат ичида', 'in a few seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), 'Якин 5 кун ичида', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'Бугун соат 12:00 да',  'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'Бугун соат 12:25 да',  'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'Бугун соат 13:00 да',  'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'Эртага 12:00 да',      'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'Бугун соат 11:00 да',  'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'Кеча соат 12:00 да',   'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('dddd [куни соат] LT [да]'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd [куни соат] LT [да]'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd [куни соат] LT [да]'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('[Утган] dddd [куни соат] LT [да]'),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[Утган] dddd [куни соат] LT [да]'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[Утган] dddd [куни соат] LT [да]'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2012, 0,  1]).format('w ww wo'), '1 01 1', 'Jan  1 2012 should be week 52');\n    assert.equal(moment([2012, 0,  2]).format('w ww wo'),   '2 02 2', 'Jan  2 2012 should be week 1');\n    assert.equal(moment([2012, 0,  8]).format('w ww wo'),   '2 02 2', 'Jan  8 2012 should be week 1');\n    assert.equal(moment([2012, 0,  9]).format('w ww wo'),   '3 03 3', 'Jan  9 2012 should be week 2');\n    assert.equal(moment([2012, 0, 15]).format('w ww wo'),   '3 03 3', 'Jan 15 2012 should be week 2');\n});\n\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/test/locale/vi.js",
    "content": "import {localeModule, test} from '../qunit';\nimport moment from '../../moment';\nlocaleModule('vi');\n\ntest('parse', function (assert) {\n    var i,\n        tests = 'tháng 1,Th01_tháng 2,Th02_tháng 3,Th03_tháng 4,Th04_tháng 5,Th05_tháng 6,Th06_tháng 7,Th07_tháng 8,Th08_tháng 9,Th09_tháng 10,Th10_tháng 11,Th11_tháng 12,Th12'.split('_');\n\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + i);\n    }\n\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(',');\n        equalTest(tests[i][0], '[tháng] M', i);\n        equalTest(tests[i][1], '[Th]M', i);\n        equalTest(tests[i][0], '[tháng] MM', i);\n        equalTest(tests[i][1], '[Th]MM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), '[THÁNG] M', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), '[TH]M', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), '[THÁNG] MM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), '[TH]MM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, MMMM Do YYYY, h:mm:ss a',      'chủ nhật, tháng 2 14 2010, 3:25:50 ch'],\n            ['ddd, hA',                            'CN, 3CH'],\n            ['M Mo MM MMMM MMM',                   '2 2 02 tháng 2 Th02'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14 14'],\n            ['d do dddd ddd dd',                   '0 0 chủ nhật CN CN'],\n            ['DDD DDDo DDDD',                      '45 45 045'],\n            ['w wo ww',                            '6 6 06'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'ch CH'],\n            ['[ngày thứ] DDDo [của năm]',          'ngày thứ 45 của năm'],\n            ['LTS',                                '15:25:50'],\n            ['L',                                  '14/02/2010'],\n            ['LL',                                 '14 tháng 2 năm 2010'],\n            ['LLL',                                '14 tháng 2 năm 2010 15:25'],\n            ['LLLL',                               'chủ nhật, 14 tháng 2 năm 2010 15:25'],\n            ['l',                                  '14/2/2010'],\n            ['ll',                                 '14 Th02 2010'],\n            ['lll',                                '14 Th02 2010 15:25'],\n            ['llll',                               'CN, 14 Th02 2010 15:25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1', '1');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2', '2');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3', '3');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4', '4');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5', '5');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6', '6');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7', '7');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8', '8');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9', '9');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10', '10');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11', '11');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12', '12');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13', '13');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14', '14');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15', '15');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16', '16');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17', '17');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18', '18');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19', '19');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20', '20');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21', '21');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22', '22');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23', '23');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24', '24');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25', '25');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26', '26');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27', '27');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28', '28');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29', '29');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30', '30');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31', '31');\n});\n\ntest('format month', function (assert) {\n    var i,\n        expected = 'tháng 1,Th01_tháng 2,Th02_tháng 3,Th03_tháng 4,Th04_tháng 5,Th05_tháng 6,Th06_tháng 7,Th07_tháng 8,Th08_tháng 9,Th09_tháng 10,Th10_tháng 11,Th11_tháng 12,Th12'.split('_');\n\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM,MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var i,\n        expected = 'chủ nhật CN CN_thứ hai T2 T2_thứ ba T3 T3_thứ tư T4 T4_thứ năm T5 T5_thứ sáu T6 T6_thứ bảy T7 T7'.split('_');\n\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'vài giây', '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'một phút',      '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'một phút',      '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 phút',     '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 phút',    '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'một giờ',       '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'một giờ',       '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 giờ',       '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 giờ',       '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 giờ',      '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'một ngày',         '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'một ngày',         '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 ngày',        '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'một ngày',         '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 ngày',        '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 ngày',       '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'một tháng',       '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'một tháng',       '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'một tháng',       '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 tháng',      '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 tháng',      '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 tháng',      '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'một tháng',       '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 tháng',      '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'một năm',        '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 năm',       '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'một năm',        '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 năm',       '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'vài giây tới',  'prefix');\n    assert.equal(moment(0).from(30000), 'vài giây trước', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'vài giây trước',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'vài giây tới', 'in a few seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), '5 ngày tới', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'Hôm nay lúc 12:00',   'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'Hôm nay lúc 12:25',   'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'Hôm nay lúc 13:00',   'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'Ngày mai lúc 12:00',  'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'Hôm nay lúc 11:00',   'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'Hôm qua lúc 12:00',   'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('dddd [tuần tới lúc] LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd [tuần tới lúc] LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd [tuần tới lúc] LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('dddd [tuần rồi lúc] LT'),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd [tuần rồi lúc] LT'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd [tuần rồi lúc] LT'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2012, 0,  1]).format('w ww wo'), '52 52 52', 'Jan  1 2012 should be week 52');\n    assert.equal(moment([2012, 0,  2]).format('w ww wo'),   '1 01 1', 'Jan  2 2012 should be week 1');\n    assert.equal(moment([2012, 0,  8]).format('w ww wo'),   '1 01 1', 'Jan  8 2012 should be week 1');\n    assert.equal(moment([2012, 0,  9]).format('w ww wo'),   '2 02 2', 'Jan  9 2012 should be week 2');\n    assert.equal(moment([2012, 0, 15]).format('w ww wo'),   '2 02 2', 'Jan 15 2012 should be week 2');\n});\n\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/test/locale/x-pseudo.js",
    "content": "import {localeModule, test} from '../qunit';\nimport moment from '../../moment';\nlocaleModule('x-pseudo');\n\ntest('parse', function (assert) {\n    var tests = 'J~áñúá~rý J~áñ_F~ébrú~árý ~Féb_~Márc~h ~Már_Áp~ríl ~Ápr_~Máý ~Máý_~Júñé~ ~Júñ_Júl~ý ~Júl_Áú~gúst~ ~Áúg_Sép~témb~ér ~Sép_Ó~ctób~ér ~Óct_Ñ~óvém~bér ~Ñóv_~Décé~mbér ~Déc'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, MMMM Do YYYY, h:mm:ss a',      'S~úñdá~ý, F~ébrú~árý 14th 2010, 3:25:50 pm'],\n            ['ddd, hA',                            'S~úñ, 3PM'],\n            ['M Mo MM MMMM MMM',                   '2 2nd 02 F~ébrú~árý ~Féb'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14th 14'],\n            ['d do dddd ddd dd',                   '0 0th S~úñdá~ý S~úñ S~ú'],\n            ['DDD DDDo DDDD',                      '45 45th 045'],\n            ['w wo ww',                            '6 6th 06'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                'pm PM'],\n            ['[the] DDDo [day of the year]',       'the 45th day of the year'],\n            ['LT',                                 '15:25'],\n            ['L',                                  '14/02/2010'],\n            ['LL',                                 '14 F~ébrú~árý 2010'],\n            ['LLL',                                '14 F~ébrú~árý 2010 15:25'],\n            ['LLLL',                               'S~úñdá~ý, 14 F~ébrú~árý 2010 15:25'],\n            ['l',                                  '14/2/2010'],\n            ['ll',                                 '14 ~Féb 2010'],\n            ['lll',                                '14 ~Féb 2010 15:25'],\n            ['llll',                               'S~úñ, 14 ~Féb 2010 15:25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), '1st', '1st');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), '2nd', '2nd');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), '3rd', '3rd');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), '4th', '4th');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), '5th', '5th');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), '6th', '6th');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), '7th', '7th');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), '8th', '8th');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), '9th', '9th');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), '10th', '10th');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), '11th', '11th');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), '12th', '12th');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), '13th', '13th');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), '14th', '14th');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), '15th', '15th');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), '16th', '16th');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), '17th', '17th');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), '18th', '18th');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), '19th', '19th');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), '20th', '20th');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), '21st', '21st');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), '22nd', '22nd');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), '23rd', '23rd');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), '24th', '24th');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), '25th', '25th');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), '26th', '26th');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), '27th', '27th');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), '28th', '28th');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), '29th', '29th');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), '30th', '30th');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), '31st', '31st');\n});\n\ntest('format month', function (assert) {\n    var expected = 'J~áñúá~rý J~áñ_F~ébrú~árý ~Féb_~Márc~h ~Már_Áp~ríl ~Ápr_~Máý ~Máý_~Júñé~ ~Júñ_Júl~ý ~Júl_Áú~gúst~ ~Áúg_Sép~témb~ér ~Sép_Ó~ctób~ér ~Óct_Ñ~óvém~bér ~Ñóv_~Décé~mbér ~Déc'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'S~úñdá~ý S~úñ S~ú_Mó~ñdáý~ ~Móñ Mó~_Túé~sdáý~ ~Túé Tú_Wéd~ñésd~áý ~Wéd ~Wé_T~húrs~dáý ~Thú T~h_~Fríd~áý ~Frí Fr~_S~átúr~dáý ~Sát Sá'.split('_'), i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'á ~féw ~sécó~ñds', '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'á ~míñ~úté',      '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'á ~míñ~úté',      '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 m~íñú~tés',     '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 m~íñú~tés',    '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'á~ñ hó~úr',       '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'á~ñ hó~úr',       '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 h~óúrs',       '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 h~óúrs',       '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 h~óúrs',      '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'á ~dáý',         '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'á ~dáý',         '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 d~áýs',        '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'á ~dáý',         '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 d~áýs',        '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 d~áýs',       '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'á ~móñ~th',       '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'á ~móñ~th',       '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'á ~móñ~th',       '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 m~óñt~hs',      '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 m~óñt~hs',      '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 m~óñt~hs',      '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'á ~móñ~th',       '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 m~óñt~hs',      '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'á ~ýéár',        '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 ý~éárs',       '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'á ~ýéár',        '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 ý~éárs',       '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'í~ñ á ~féw ~sécó~ñds',  'prefix');\n    assert.equal(moment(0).from(30000), 'á ~féw ~sécó~ñds á~gó', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'á ~féw ~sécó~ñds á~gó',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'í~ñ á ~féw ~sécó~ñds', 'in a few seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), 'í~ñ 5 d~áýs', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(2).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                     'T~ódá~ý át 02:00',      'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'T~ódá~ý át 02:25',      'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'T~ódá~ý át 03:00',      'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'T~ómó~rró~w át 02:00',   'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'T~ódá~ý át 01:00',      'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'Ý~ést~érdá~ý át 02:00',  'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('dddd [át] LT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('dddd [át] LT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('dddd [át] LT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('[L~ást] dddd [át] LT'),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[L~ást] dddd [át] LT'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[L~ást] dddd [át] LT'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2012, 0,  1]).format('w ww wo'), '52 52 52nd', 'Jan  1 2012 should be week 52');\n    assert.equal(moment([2012, 0,  2]).format('w ww wo'),   '1 01 1st', 'Jan  2 2012 should be week 1');\n    assert.equal(moment([2012, 0,  8]).format('w ww wo'),   '1 01 1st', 'Jan  8 2012 should be week 1');\n    assert.equal(moment([2012, 0,  9]).format('w ww wo'),   '2 02 2nd', 'Jan  9 2012 should be week 2');\n    assert.equal(moment([2012, 0, 15]).format('w ww wo'),   '2 02 2nd', 'Jan 15 2012 should be week 2');\n});\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/test/locale/yo.js",
    "content": "import { localeModule, test } from '../qunit';\nimport moment from '../../moment';\nlocaleModule('yo');\n\ntest('parse', function (assert) {\n    var tests = 'Sẹ́rẹ́ Sẹ́r_Èrèlè Èrl_Ẹrẹ̀nà Ẹrn_Ìgbé Ìgb_Èbibi Èbi_Òkùdu Òkù_Agẹmo Agẹ_Ògún Ògú_Owewe Owe_Ọ̀wàrà Ọ̀wà_Bélú Bél_Ọ̀pẹ̀̀ Ọ̀pẹ̀̀'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, MMMM Do YYYY, h:mm:ss a', 'Àìkú, Èrèlè ọjọ́ 14 2010, 3:25:50 pm'],\n            ['ddd, hA', 'Àìk, 3PM'],\n            ['M Mo MM MMMM MMM', '2 ọjọ́ 2 02 Èrèlè Èrl'],\n            ['YYYY YY', '2010 10'],\n            ['D Do DD', '14 ọjọ́ 14 14'],\n            ['d do dddd ddd dd', '0 ọjọ́ 0 Àìkú Àìk Àì'],\n            ['DDD DDDo DDDD', '45 ọjọ́ 45 045'],\n            ['w wo ww', '6 ọjọ́ 6 06'],\n            ['h hh', '3 03'],\n            ['H HH', '15 15'],\n            ['m mm', '25 25'],\n            ['s ss', '50 50'],\n            ['a A', 'pm PM'],\n            ['[the] DDDo [day of the year]', 'the ọjọ́ 45 day of the year'],\n            ['LTS', '3:25:50 PM'],\n            ['L', '14/02/2010'],\n            ['LL', '14 Èrèlè 2010'],\n            ['LLL', '14 Èrèlè 2010 3:25 PM'],\n            ['LLLL', 'Àìkú, 14 Èrèlè 2010 3:25 PM'],\n            ['l', '14/2/2010'],\n            ['ll', '14 Èrl 2010'],\n            ['lll', '14 Èrl 2010 3:25 PM'],\n            ['llll', 'Àìk, 14 Èrl 2010 3:25 PM']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format ordinal', function (assert) {\n    assert.equal(moment([2011, 0, 1]).format('DDDo'), 'ọjọ́ 1', 'ọjọ́ 1');\n    assert.equal(moment([2011, 0, 2]).format('DDDo'), 'ọjọ́ 2', 'ọjọ́ 2');\n    assert.equal(moment([2011, 0, 3]).format('DDDo'), 'ọjọ́ 3', 'ọjọ́ 3');\n    assert.equal(moment([2011, 0, 4]).format('DDDo'), 'ọjọ́ 4', 'ọjọ́ 4');\n    assert.equal(moment([2011, 0, 5]).format('DDDo'), 'ọjọ́ 5', 'ọjọ́ 5');\n    assert.equal(moment([2011, 0, 6]).format('DDDo'), 'ọjọ́ 6', 'ọjọ́ 6');\n    assert.equal(moment([2011, 0, 7]).format('DDDo'), 'ọjọ́ 7', 'ọjọ́ 7');\n    assert.equal(moment([2011, 0, 8]).format('DDDo'), 'ọjọ́ 8', 'ọjọ́ 8');\n    assert.equal(moment([2011, 0, 9]).format('DDDo'), 'ọjọ́ 9', 'ọjọ́ 9');\n    assert.equal(moment([2011, 0, 10]).format('DDDo'), 'ọjọ́ 10', 'ọjọ́ 10');\n\n    assert.equal(moment([2011, 0, 11]).format('DDDo'), 'ọjọ́ 11', 'ọjọ́ 11');\n    assert.equal(moment([2011, 0, 12]).format('DDDo'), 'ọjọ́ 12', 'ọjọ́ 12');\n    assert.equal(moment([2011, 0, 13]).format('DDDo'), 'ọjọ́ 13', 'ọjọ́ 13');\n    assert.equal(moment([2011, 0, 14]).format('DDDo'), 'ọjọ́ 14', 'ọjọ́ 14');\n    assert.equal(moment([2011, 0, 15]).format('DDDo'), 'ọjọ́ 15', 'ọjọ́ 15');\n    assert.equal(moment([2011, 0, 16]).format('DDDo'), 'ọjọ́ 16', 'ọjọ́ 16');\n    assert.equal(moment([2011, 0, 17]).format('DDDo'), 'ọjọ́ 17', 'ọjọ́ 17');\n    assert.equal(moment([2011, 0, 18]).format('DDDo'), 'ọjọ́ 18', 'ọjọ́ 18');\n    assert.equal(moment([2011, 0, 19]).format('DDDo'), 'ọjọ́ 19', 'ọjọ́ 19');\n    assert.equal(moment([2011, 0, 20]).format('DDDo'), 'ọjọ́ 20', 'ọjọ́ 20');\n\n    assert.equal(moment([2011, 0, 21]).format('DDDo'), 'ọjọ́ 21', 'ọjọ́ 21');\n    assert.equal(moment([2011, 0, 22]).format('DDDo'), 'ọjọ́ 22', 'ọjọ́ 22');\n    assert.equal(moment([2011, 0, 23]).format('DDDo'), 'ọjọ́ 23', 'ọjọ́ 23');\n    assert.equal(moment([2011, 0, 24]).format('DDDo'), 'ọjọ́ 24', 'ọjọ́ 24');\n    assert.equal(moment([2011, 0, 25]).format('DDDo'), 'ọjọ́ 25', 'ọjọ́ 25');\n    assert.equal(moment([2011, 0, 26]).format('DDDo'), 'ọjọ́ 26', 'ọjọ́ 26');\n    assert.equal(moment([2011, 0, 27]).format('DDDo'), 'ọjọ́ 27', 'ọjọ́ 27');\n    assert.equal(moment([2011, 0, 28]).format('DDDo'), 'ọjọ́ 28', 'ọjọ́ 28');\n    assert.equal(moment([2011, 0, 29]).format('DDDo'), 'ọjọ́ 29', 'ọjọ́ 29');\n    assert.equal(moment([2011, 0, 30]).format('DDDo'), 'ọjọ́ 30', 'ọjọ́ 30');\n\n    assert.equal(moment([2011, 0, 31]).format('DDDo'), 'ọjọ́ 31', 'ọjọ́ 31');\n});\n\ntest('format month', function (assert) {\n    var expected = 'Sẹ́rẹ́ Sẹ́r_Èrèlè Èrl_Ẹrẹ̀nà Ẹrn_Ìgbé Ìgb_Èbibi Èbi_Òkùdu Òkù_Agẹmo Agẹ_Ògún Ògú_Owewe Owe_Ọ̀wàrà Ọ̀wà_Bélú Bél_Ọ̀pẹ̀̀ Ọ̀pẹ̀̀'.split('_'),\n        i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = 'Àìkú Àìk Àì_Ajé Ajé Aj_Ìsẹ́gun Ìsẹ́ Ìs_Ọjọ́rú Ọjr Ọr_Ọjọ́bọ Ọjb Ọb_Ẹtì Ẹtì Ẹt_Àbámẹ́ta Àbá Àb'.split('_'),\n        i;\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'ìsẹjú aayá die', '44 seconds = ìsẹjú aayá die');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'ìsẹjú kan',      '45 seconds = ìsẹjú kan');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'ìsẹjú kan',      '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  'ìsẹjú 2',        '90 seconds = ìsẹjú 2');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  'ìsẹjú 44',       'ìsẹjú 44 = ìsẹjú 44');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'wákati kan',     'ìsẹjú 45 = wákati kan');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'wákati kan',     'ìsẹjú 89 = wákati kan');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  'wákati 2',       'ìsẹjú 90 = wákati 2');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   'wákati 5',       'wákati 5 = wákati 5');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  'wákati 21',      'wákati 21 = wákati 21');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'ọjọ́ kan',        '22 wákati = ọjọ́ kan');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'ọjọ́ kan',        '35 wákati = ọjọ́ kan');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  'ọjọ́ 2',          'wákati 36 = ọjọ́ 2');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'ọjọ́ kan',        '1  = ọjọ́ kan');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   'ọjọ́ 5',          'ọjọ́ 5 = ọjọ́  5');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  'ọjọ́ 25',         'ọjọ́ 25 = ọjọ́ 25');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'osù kan',        'ọjọ́ 26 = osù kan');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'osù kan',        'ọjọ́ 30 = osù kan');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'osù kan',        'ọjọ́ 43 = osù kan');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  'osù 2',          'ọjọ́ 46 = osù 2');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  'osù 2',          'ọjọ́ 75 = osù 2');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  'osù 3',          'ọjọ́ 76 = osù 3');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'osù kan',        'osù 1 = osù kan');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   'osù 5',          'osù 5 = osù 5');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'ọdún kan',       'ọjọ 345 = ọdún kan');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), 'ọdún 2',         'ọjọ 548 = ọdún 2');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'ọdún kan',       'ọdún 1 = ọdún kan');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   'ọdún 5',         'ọdún 5 = ọdún 5');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), 'ní ìsẹjú aayá die', 'prefix');\n    assert.equal(moment(0).from(30000), 'ìsẹjú aayá die kọjá', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), 'ìsẹjú aayá die kọjá', 'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), 'ní ìsẹjú aayá die', 'ní ìsẹjú aayá die');\n    assert.equal(moment().add({d: 5}).fromNow(), 'ní ọjọ́ 5', 'ní ọjọ́ 5');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                     'Ònì ni 12:00 PM',   'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'Ònì ni 12:25 PM',   'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'Ònì ni 1:00 PM',    'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'Ọ̀la ni 12:00 PM',   'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'Ònì ni 11:00 AM',   'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'Àna ni 12:00 PM',   'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(), m.format('dddd [Ọsẹ̀ tón\\'bọ] [ni] LT'), 'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(), m.format('dddd [Ọsẹ̀ tón\\'bọ] [ni] LT'), 'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(), m.format('dddd [Ọsẹ̀ tón\\'bọ] [ni] LT'), 'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(), m.format('dddd [Ọsẹ̀ tólọ́] [ni] LT'), 'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(), m.format('dddd [Ọsẹ̀ tólọ́] [ni] LT'), 'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(), m.format('dddd [Ọsẹ̀ tólọ́] [ni] LT'), 'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '1 week ago');\n    assert.equal(weeksFromNow.calendar(), weeksFromNow.format('L'), 'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(), weeksFromNow.format('L'), 'in 2 weeks');\n});\n\ntest('weeks year starting sunday format', function (assert) {\n    assert.equal(moment([2012, 0,  1]).format('w ww wo'), '52 52 ọjọ́ 52', 'Jan  1 2012 should be week 52');\n    assert.equal(moment([2012, 0,  2]).format('w ww wo'),   '1 01 ọjọ́ 1', 'Jan  2 2012 should be week 1');\n    assert.equal(moment([2012, 0,  8]).format('w ww wo'),   '1 01 ọjọ́ 1', 'Jan  8 2012 should be week 1');\n    assert.equal(moment([2012, 0,  9]).format('w ww wo'),   '2 02 ọjọ́ 2', 'Jan  9 2012 should be week 2');\n    assert.equal(moment([2012, 0, 15]).format('w ww wo'),   '2 02 ọjọ́ 2', 'Jan 15 2012 should be week 2');\n});\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/test/locale/zh-cn.js",
    "content": "import {localeModule, test} from '../qunit';\nimport moment from '../../moment';\nlocaleModule('zh-cn');\n\ntest('parse', function (assert) {\n    var tests = '一月 1月_二月 2月_三月 3月_四月 4月_五月 5月_六月 6月_七月 7月_八月 8月_九月 9月_十月 10月_十一月 11月_十二月 12月'.split('_'), i;\n\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, MMMM Do YYYY, a h:mm:ss',      '星期日, 二月 14日 2010, 下午 3:25:50'],\n            ['ddd, Ah',                            '周日, 下午3'],\n            ['M Mo MM MMMM MMM',                   '2 2月 02 二月 2月'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14日 14'],\n            ['d do dddd ddd dd',                   '0 0日 星期日 周日 日'],\n            ['DDD DDDo DDDD',                      '45 45日 045'],\n            ['w wo ww',                            '6 6周 06'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                '下午 下午'],\n            ['[这年的第] DDDo',                    '这年的第 45日'],\n            ['LTS',                                '15:25:50'],\n            ['L',                                  '2010年2月14日'],\n            ['LL',                                 '2010年2月14日'],\n            ['LLL',                                '2010年2月14日下午3点25分'],\n            ['LLLL',                               '2010年2月14日星期日下午3点25分'],\n            ['l',                                  '2010年2月14日'],\n            ['ll',                                 '2010年2月14日'],\n            ['lll',                                '2010年2月14日 15:25'],\n            ['llll',                               '2010年2月14日星期日 15:25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format month', function (assert) {\n    var expected = '一月 1月_二月 2月_三月 3月_四月 4月_五月 5月_六月 6月_七月 7月_八月 8月_九月 9月_十月 10月_十一月 11月_十二月 12月'.split('_'), i;\n\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = '星期日 周日 日_星期一 周一 一_星期二 周二 二_星期三 周三 三_星期四 周四 四_星期五 周五 五_星期六 周六 六'.split('_'), i;\n\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  '几秒',   '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  '1 分钟', '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  '1 分钟', '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 分钟',  '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 分钟', '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  '1 小时', '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  '1 小时', '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 小时',  '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 小时',  '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 小时', '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  '1 天',   '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  '1 天',   '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 天',   '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   '1 天',   '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 天',   '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 天',  '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  '1 个月', '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  '1 个月', '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  '1 个月', '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 个月',  '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 个月',  '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 个月',  '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   '1 个月', '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 个月',  '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), '1 年',   '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 年',   '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   '1 年',   '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 年',   '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), '几秒内',  'prefix');\n    assert.equal(moment(0).from(30000), '几秒前', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), '几秒前',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), '几秒内', 'in a few seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), '5 天内', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   '今天12:00', 'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      '今天12:25', 'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       '今天13:00', 'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       '明天12:00', 'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  '今天11:00', 'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  '昨天12:00', 'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('[下]ddddLT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[下]ddddLT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[下]ddddLT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('[上]ddddLT'),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[上]ddddLT'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[上]ddddLT'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),      '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),      '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('meridiem', function (assert) {\n    assert.equal(moment([2011, 2, 23,  0, 0]).format('A'), '凌晨', 'before dawn');\n    assert.equal(moment([2011, 2, 23,  6, 0]).format('A'), '早上', 'morning');\n    assert.equal(moment([2011, 2, 23,  9, 0]).format('A'), '上午', 'before noon');\n    assert.equal(moment([2011, 2, 23, 12, 0]).format('A'), '中午', 'noon');\n    assert.equal(moment([2011, 2, 23, 13, 0]).format('A'), '下午', 'afternoon');\n    assert.equal(moment([2011, 2, 23, 18, 0]).format('A'), '晚上', 'night');\n});\n\ntest('weeks year starting sunday format', function (assert) {\n    assert.equal(moment([2012, 0,  1]).format('w ww wo'), '52 52 52周', 'Jan  1 2012 应该是第52周');\n    assert.equal(moment([2012, 0,  7]).format('w ww wo'), '1 01 1周', 'Jan  7 2012 应该是第 1周');\n    assert.equal(moment([2012, 0, 14]).format('w ww wo'), '2 02 2周', 'Jan 14 2012 应该是第 2周');\n});\n\n\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/test/locale/zh-hk.js",
    "content": "import {localeModule, test} from '../qunit';\nimport moment from '../../moment';\nlocaleModule('zh-hk');\n\ntest('parse', function (assert) {\n    var tests = '一月 1月_二月 2月_三月 3月_四月 4月_五月 5月_六月 6月_七月 7月_八月 8月_九月 9月_十月 10月_十一月 11月_十二月 12月'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, MMMM Do YYYY, a h:mm:ss',      '星期日, 二月 14日 2010, 下午 3:25:50'],\n            ['ddd, Ah',                            '週日, 下午3'],\n            ['M Mo MM MMMM MMM',                   '2 2月 02 二月 2月'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14日 14'],\n            ['d do dddd ddd dd',                   '0 0日 星期日 週日 日'],\n            ['DDD DDDo DDDD',                      '45 45日 045'],\n            ['w wo ww',                            '8 8週 08'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                '下午 下午'],\n            ['[這年的第] DDDo',                    '這年的第 45日'],\n            ['LTS',                                '15:25:50'],\n            ['L',                                  '2010年2月14日'],\n            ['LL',                                 '2010年2月14日'],\n            ['LLL',                                '2010年2月14日 15:25'],\n            ['LLLL',                               '2010年2月14日星期日 15:25'],\n            ['l',                                  '2010年2月14日'],\n            ['ll',                                 '2010年2月14日'],\n            ['lll',                                '2010年2月14日 15:25'],\n            ['llll',                               '2010年2月14日星期日 15:25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format month', function (assert) {\n    var expected = '一月 1月_二月 2月_三月 3月_四月 4月_五月 5月_六月 6月_七月 7月_八月 8月_九月 9月_十月 10月_十一月 11月_十二月 12月'.split('_'), i;\n\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = '星期日 週日 日_星期一 週一 一_星期二 週二 二_星期三 週三 三_星期四 週四 四_星期五 週五 五_星期六 週六 六'.split('_'), i;\n\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  '幾秒',   '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  '1 分鐘', '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  '1 分鐘', '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 分鐘',  '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 分鐘', '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  '1 小時', '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  '1 小時', '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 小時',  '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 小時',  '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 小時', '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  '1 天',   '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  '1 天',   '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 天',   '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   '1 天',   '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 天',   '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 天',  '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  '1 個月', '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  '1 個月', '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  '1 個月', '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 個月',  '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 個月',  '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 個月',  '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   '1 個月', '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 個月',  '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), '1 年',   '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 年',   '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   '1 年',   '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 年',   '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), '幾秒內',  'prefix');\n    assert.equal(moment(0).from(30000), '幾秒前', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), '幾秒前',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), '幾秒內', 'in a few seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), '5 天內', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   '今天12:00', 'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      '今天12:25', 'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       '今天13:00', 'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       '明天12:00', 'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  '今天11:00', 'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  '昨天12:00', 'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('[下]ddddLT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[下]ddddLT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[下]ddddLT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('[上]ddddLT'),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[上]ddddLT'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[上]ddddLT'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),      '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),      '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('meridiem', function (assert) {\n    assert.equal(moment([2011, 2, 23,  0, 0]).format('a'), '凌晨', 'before dawn');\n    assert.equal(moment([2011, 2, 23,  6, 0]).format('a'), '早上', 'morning');\n    assert.equal(moment([2011, 2, 23,  9, 0]).format('a'), '上午', 'before noon');\n    assert.equal(moment([2011, 2, 23, 12, 0]).format('a'), '中午', 'noon');\n    assert.equal(moment([2011, 2, 23, 13, 0]).format('a'), '下午', 'after noon');\n    assert.equal(moment([2011, 2, 23, 18, 0]).format('a'), '晚上', 'night');\n\n    assert.equal(moment([2011, 2, 23,  0, 0]).format('A'), '凌晨', 'before dawn');\n    assert.equal(moment([2011, 2, 23,  6, 0]).format('A'), '早上', 'morning');\n    assert.equal(moment([2011, 2, 23,  9, 0]).format('A'), '上午', 'before noon');\n    assert.equal(moment([2011, 2, 23, 12, 0]).format('A'), '中午', 'noon');\n    assert.equal(moment([2011, 2, 23, 13, 0]).format('A'), '下午', 'afternoon');\n    assert.equal(moment([2011, 2, 23, 18, 0]).format('A'), '晚上', 'night');\n});\n\ntest('weeks year starting sunday format', function (assert) {\n    assert.equal(moment([2012, 0,  1]).format('w ww wo'), '1 01 1週', 'Jan  1 2012 應該是第 1週');\n    assert.equal(moment([2012, 0,  7]).format('w ww wo'), '1 01 1週', 'Jan  7 2012 應該是第 1週');\n    assert.equal(moment([2012, 0,  8]).format('w ww wo'), '2 02 2週', 'Jan  8 2012 應該是第 2週');\n    assert.equal(moment([2012, 0, 14]).format('w ww wo'), '2 02 2週', 'Jan 14 2012 應該是第 2週');\n    assert.equal(moment([2012, 0, 15]).format('w ww wo'), '3 03 3週', 'Jan 15 2012 應該是第 3週');\n});\n\n\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/test/locale/zh-tw.js",
    "content": "import {localeModule, test} from '../qunit';\nimport moment from '../../moment';\nlocaleModule('zh-tw');\n\ntest('parse', function (assert) {\n    var tests = '一月 1月_二月 2月_三月 3月_四月 4月_五月 5月_六月 6月_七月 7月_八月 8月_九月 9月_十月 10月_十一月 11月_十二月 12月'.split('_'), i;\n    function equalTest(input, mmm, i) {\n        assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n    }\n    for (i = 0; i < 12; i++) {\n        tests[i] = tests[i].split(' ');\n        equalTest(tests[i][0], 'MMM', i);\n        equalTest(tests[i][1], 'MMM', i);\n        equalTest(tests[i][0], 'MMMM', i);\n        equalTest(tests[i][1], 'MMMM', i);\n        equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n        equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n        equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n    }\n});\n\ntest('format', function (assert) {\n    var a = [\n            ['dddd, MMMM Do YYYY, a h:mm:ss',      '星期日, 二月 14日 2010, 下午 3:25:50'],\n            ['ddd, Ah',                            '週日, 下午3'],\n            ['M Mo MM MMMM MMM',                   '2 2月 02 二月 2月'],\n            ['YYYY YY',                            '2010 10'],\n            ['D Do DD',                            '14 14日 14'],\n            ['d do dddd ddd dd',                   '0 0日 星期日 週日 日'],\n            ['DDD DDDo DDDD',                      '45 45日 045'],\n            ['w wo ww',                            '8 8週 08'],\n            ['h hh',                               '3 03'],\n            ['H HH',                               '15 15'],\n            ['m mm',                               '25 25'],\n            ['s ss',                               '50 50'],\n            ['a A',                                '下午 下午'],\n            ['[這年的第] DDDo',                    '這年的第 45日'],\n            ['LTS',                                '15:25:50'],\n            ['L',                                  '2010年2月14日'],\n            ['LL',                                 '2010年2月14日'],\n            ['LLL',                                '2010年2月14日 15:25'],\n            ['LLLL',                               '2010年2月14日星期日 15:25'],\n            ['l',                                  '2010年2月14日'],\n            ['ll',                                 '2010年2月14日'],\n            ['lll',                                '2010年2月14日 15:25'],\n            ['llll',                               '2010年2月14日星期日 15:25']\n        ],\n        b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n        i;\n\n    for (i = 0; i < a.length; i++) {\n        assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('format month', function (assert) {\n    var expected = '一月 1月_二月 2月_三月 3月_四月 4月_五月 5月_六月 6月_七月 7月_八月 8月_九月 9月_十月 10月_十一月 11月_十二月 12月'.split('_'), i;\n\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n    }\n});\n\ntest('format week', function (assert) {\n    var expected = '星期日 週日 日_星期一 週一 一_星期二 週二 二_星期三 週三 三_星期四 週四 四_星期五 週五 五_星期六 週六 六'.split('_'), i;\n\n    for (i = 0; i < expected.length; i++) {\n        assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n    }\n});\n\ntest('from', function (assert) {\n    var start = moment([2007, 1, 28]);\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  '幾秒',   '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  '1 分鐘', '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  '1 分鐘', '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 分鐘',  '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 分鐘', '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  '1 小時', '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  '1 小時', '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 小時',  '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 小時',  '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 小時', '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  '1 天',   '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  '1 天',   '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 天',   '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   '1 天',   '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 天',   '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 天',  '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  '1 個月', '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  '1 個月', '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  '1 個月', '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 個月',  '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 個月',  '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 個月',  '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   '1 個月', '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 個月',  '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), '1 年',   '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 年',   '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   '1 年',   '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 年',   '5 years = 5 years');\n});\n\ntest('suffix', function (assert) {\n    assert.equal(moment(30000).from(0), '幾秒內',  'prefix');\n    assert.equal(moment(0).from(30000), '幾秒前', 'suffix');\n});\n\ntest('now from now', function (assert) {\n    assert.equal(moment().fromNow(), '幾秒前',  'now from now should display as in the past');\n});\n\ntest('fromNow', function (assert) {\n    assert.equal(moment().add({s: 30}).fromNow(), '幾秒內', 'in a few seconds');\n    assert.equal(moment().add({d: 5}).fromNow(), '5 天內', 'in 5 days');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   '今天12:00', 'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      '今天12:25', 'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       '今天13:00', 'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       '明天12:00', 'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  '今天11:00', 'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  '昨天12:00', 'yesterday at the same time');\n});\n\ntest('calendar next week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().add({d: i});\n        assert.equal(m.calendar(),       m.format('[下]ddddLT'),  'Today + ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[下]ddddLT'),  'Today + ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[下]ddddLT'),  'Today + ' + i + ' days end of day');\n    }\n});\n\ntest('calendar last week', function (assert) {\n    var i, m;\n    for (i = 2; i < 7; i++) {\n        m = moment().subtract({d: i});\n        assert.equal(m.calendar(),       m.format('[上]ddddLT'),  'Today - ' + i + ' days current time');\n        m.hours(0).minutes(0).seconds(0).milliseconds(0);\n        assert.equal(m.calendar(),       m.format('[上]ddddLT'),  'Today - ' + i + ' days beginning of day');\n        m.hours(23).minutes(59).seconds(59).milliseconds(999);\n        assert.equal(m.calendar(),       m.format('[上]ddddLT'),  'Today - ' + i + ' days end of day');\n    }\n});\n\ntest('calendar all else', function (assert) {\n    var weeksAgo = moment().subtract({w: 1}),\n        weeksFromNow = moment().add({w: 1});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),      '1 week ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n    weeksAgo = moment().subtract({w: 2});\n    weeksFromNow = moment().add({w: 2});\n\n    assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),      '2 weeks ago');\n    assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n});\n\ntest('meridiem', function (assert) {\n    assert.equal(moment([2011, 2, 23,  0, 0]).format('a'), '凌晨', 'before dawn');\n    assert.equal(moment([2011, 2, 23,  6, 0]).format('a'), '早上', 'morning');\n    assert.equal(moment([2011, 2, 23,  9, 0]).format('a'), '上午', 'before noon');\n    assert.equal(moment([2011, 2, 23, 12, 0]).format('a'), '中午', 'noon');\n    assert.equal(moment([2011, 2, 23, 13, 0]).format('a'), '下午', 'after noon');\n    assert.equal(moment([2011, 2, 23, 18, 0]).format('a'), '晚上', 'night');\n\n    assert.equal(moment([2011, 2, 23,  0, 0]).format('A'), '凌晨', 'before dawn');\n    assert.equal(moment([2011, 2, 23,  6, 0]).format('A'), '早上', 'morning');\n    assert.equal(moment([2011, 2, 23,  9, 0]).format('A'), '上午', 'before noon');\n    assert.equal(moment([2011, 2, 23, 12, 0]).format('A'), '中午', 'noon');\n    assert.equal(moment([2011, 2, 23, 13, 0]).format('A'), '下午', 'afternoon');\n    assert.equal(moment([2011, 2, 23, 18, 0]).format('A'), '晚上', 'night');\n});\n\ntest('weeks year starting sunday format', function (assert) {\n    assert.equal(moment([2012, 0,  1]).format('w ww wo'), '1 01 1週', 'Jan  1 2012 應該是第 1週');\n    assert.equal(moment([2012, 0,  7]).format('w ww wo'), '1 01 1週', 'Jan  7 2012 應該是第 1週');\n    assert.equal(moment([2012, 0,  8]).format('w ww wo'), '2 02 2週', 'Jan  8 2012 應該是第 2週');\n    assert.equal(moment([2012, 0, 14]).format('w ww wo'), '2 02 2週', 'Jan 14 2012 應該是第 2週');\n    assert.equal(moment([2012, 0, 15]).format('w ww wo'), '3 03 3週', 'Jan 15 2012 應該是第 3週');\n});\n\n\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/test/moment/add_subtract.js",
    "content": "import { module, test, expect } from '../qunit';\nimport moment from '../../moment';\n\nmodule('add and subtract');\n\ntest('add short reverse args', function (assert) {\n    var a = moment(), b, c, d;\n    a.year(2011);\n    a.month(9);\n    a.date(12);\n    a.hours(6);\n    a.minutes(7);\n    a.seconds(8);\n    a.milliseconds(500);\n\n    assert.equal(a.add({ms: 50}).milliseconds(), 550, 'Add milliseconds');\n    assert.equal(a.add({s: 1}).seconds(), 9, 'Add seconds');\n    assert.equal(a.add({m: 1}).minutes(), 8, 'Add minutes');\n    assert.equal(a.add({h: 1}).hours(), 7, 'Add hours');\n    assert.equal(a.add({d: 1}).date(), 13, 'Add date');\n    assert.equal(a.add({w: 1}).date(), 20, 'Add week');\n    assert.equal(a.add({M: 1}).month(), 10, 'Add month');\n    assert.equal(a.add({y: 1}).year(), 2012, 'Add year');\n    assert.equal(a.add({Q: 1}).month(), 1, 'Add quarter');\n\n    b = moment([2010, 0, 31]).add({M: 1});\n    c = moment([2010, 1, 28]).subtract({M: 1});\n    d = moment([2010, 1, 28]).subtract({Q: 1});\n\n    assert.equal(b.month(), 1, 'add month, jan 31st to feb 28th');\n    assert.equal(b.date(), 28, 'add month, jan 31st to feb 28th');\n    assert.equal(c.month(), 0, 'subtract month, feb 28th to jan 28th');\n    assert.equal(c.date(), 28, 'subtract month, feb 28th to jan 28th');\n    assert.equal(d.month(), 10, 'subtract quarter, feb 28th 2010 to nov 28th 2009');\n    assert.equal(d.date(), 28, 'subtract quarter, feb 28th 2010 to nov 28th 2009');\n    assert.equal(d.year(), 2009, 'subtract quarter, feb 28th 2010 to nov 28th 2009');\n});\n\ntest('add long reverse args', function (assert) {\n    var a = moment();\n    a.year(2011);\n    a.month(9);\n    a.date(12);\n    a.hours(6);\n    a.minutes(7);\n    a.seconds(8);\n    a.milliseconds(500);\n\n    assert.equal(a.add({milliseconds: 50}).milliseconds(), 550, 'Add milliseconds');\n    assert.equal(a.add({seconds: 1}).seconds(), 9, 'Add seconds');\n    assert.equal(a.add({minutes: 1}).minutes(), 8, 'Add minutes');\n    assert.equal(a.add({hours: 1}).hours(), 7, 'Add hours');\n    assert.equal(a.add({days: 1}).date(), 13, 'Add date');\n    assert.equal(a.add({weeks: 1}).date(), 20, 'Add week');\n    assert.equal(a.add({months: 1}).month(), 10, 'Add month');\n    assert.equal(a.add({years: 1}).year(), 2012, 'Add year');\n    assert.equal(a.add({quarters: 1}).month(), 1, 'Add quarter');\n});\n\ntest('add long singular reverse args', function (assert) {\n    var a = moment();\n    a.year(2011);\n    a.month(9);\n    a.date(12);\n    a.hours(6);\n    a.minutes(7);\n    a.seconds(8);\n    a.milliseconds(500);\n\n    assert.equal(a.add({millisecond: 50}).milliseconds(), 550, 'Add milliseconds');\n    assert.equal(a.add({second: 1}).seconds(), 9, 'Add seconds');\n    assert.equal(a.add({minute: 1}).minutes(), 8, 'Add minutes');\n    assert.equal(a.add({hour: 1}).hours(), 7, 'Add hours');\n    assert.equal(a.add({day: 1}).date(), 13, 'Add date');\n    assert.equal(a.add({week: 1}).date(), 20, 'Add week');\n    assert.equal(a.add({month: 1}).month(), 10, 'Add month');\n    assert.equal(a.add({year: 1}).year(), 2012, 'Add year');\n    assert.equal(a.add({quarter: 1}).month(), 1, 'Add quarter');\n});\n\ntest('add string long reverse args', function (assert) {\n    var a = moment(), b;\n\n    test.expectedDeprecations('moment().add(period, number)');\n\n    a.year(2011);\n    a.month(9);\n    a.date(12);\n    a.hours(6);\n    a.minutes(7);\n    a.seconds(8);\n    a.milliseconds(500);\n\n    b = a.clone();\n\n    assert.equal(a.add('millisecond', 50).milliseconds(), 550, 'Add milliseconds');\n    assert.equal(a.add('second', 1).seconds(), 9, 'Add seconds');\n    assert.equal(a.add('minute', 1).minutes(), 8, 'Add minutes');\n    assert.equal(a.add('hour', 1).hours(), 7, 'Add hours');\n    assert.equal(a.add('day', 1).date(), 13, 'Add date');\n    assert.equal(a.add('week', 1).date(), 20, 'Add week');\n    assert.equal(a.add('month', 1).month(), 10, 'Add month');\n    assert.equal(a.add('year', 1).year(), 2012, 'Add year');\n    assert.equal(b.add('day', '01').date(), 13, 'Add date');\n    assert.equal(a.add('quarter', 1).month(), 1, 'Add quarter');\n});\n\ntest('add string long singular reverse args', function (assert) {\n    var a = moment(), b;\n\n    test.expectedDeprecations('moment().add(period, number)');\n\n    a.year(2011);\n    a.month(9);\n    a.date(12);\n    a.hours(6);\n    a.minutes(7);\n    a.seconds(8);\n    a.milliseconds(500);\n\n    b = a.clone();\n\n    assert.equal(a.add('milliseconds', 50).milliseconds(), 550, 'Add milliseconds');\n    assert.equal(a.add('seconds', 1).seconds(), 9, 'Add seconds');\n    assert.equal(a.add('minutes', 1).minutes(), 8, 'Add minutes');\n    assert.equal(a.add('hours', 1).hours(), 7, 'Add hours');\n    assert.equal(a.add('days', 1).date(), 13, 'Add date');\n    assert.equal(a.add('weeks', 1).date(), 20, 'Add week');\n    assert.equal(a.add('months', 1).month(), 10, 'Add month');\n    assert.equal(a.add('years', 1).year(), 2012, 'Add year');\n    assert.equal(b.add('days', '01').date(), 13, 'Add date');\n    assert.equal(a.add('quarters', 1).month(), 1, 'Add quarter');\n});\n\ntest('add string short reverse args', function (assert) {\n    var a = moment();\n    test.expectedDeprecations('moment().add(period, number)');\n\n    a.year(2011);\n    a.month(9);\n    a.date(12);\n    a.hours(6);\n    a.minutes(7);\n    a.seconds(8);\n    a.milliseconds(500);\n\n    assert.equal(a.add('ms', 50).milliseconds(), 550, 'Add milliseconds');\n    assert.equal(a.add('s', 1).seconds(), 9, 'Add seconds');\n    assert.equal(a.add('m', 1).minutes(), 8, 'Add minutes');\n    assert.equal(a.add('h', 1).hours(), 7, 'Add hours');\n    assert.equal(a.add('d', 1).date(), 13, 'Add date');\n    assert.equal(a.add('w', 1).date(), 20, 'Add week');\n    assert.equal(a.add('M', 1).month(), 10, 'Add month');\n    assert.equal(a.add('y', 1).year(), 2012, 'Add year');\n    assert.equal(a.add('Q', 1).month(), 1, 'Add quarter');\n});\n\ntest('add string long', function (assert) {\n    var a = moment();\n    a.year(2011);\n    a.month(9);\n    a.date(12);\n    a.hours(6);\n    a.minutes(7);\n    a.seconds(8);\n    a.milliseconds(500);\n\n    assert.equal(a.add(50, 'millisecond').milliseconds(), 550, 'Add milliseconds');\n    assert.equal(a.add(1, 'second').seconds(), 9, 'Add seconds');\n    assert.equal(a.add(1, 'minute').minutes(), 8, 'Add minutes');\n    assert.equal(a.add(1, 'hour').hours(), 7, 'Add hours');\n    assert.equal(a.add(1, 'day').date(), 13, 'Add date');\n    assert.equal(a.add(1, 'week').date(), 20, 'Add week');\n    assert.equal(a.add(1, 'month').month(), 10, 'Add month');\n    assert.equal(a.add(1, 'year').year(), 2012, 'Add year');\n    assert.equal(a.add(1, 'quarter').month(), 1, 'Add quarter');\n});\n\ntest('add string long singular', function (assert) {\n    var a = moment();\n    a.year(2011);\n    a.month(9);\n    a.date(12);\n    a.hours(6);\n    a.minutes(7);\n    a.seconds(8);\n    a.milliseconds(500);\n\n    assert.equal(a.add(50, 'milliseconds').milliseconds(), 550, 'Add milliseconds');\n    assert.equal(a.add(1, 'seconds').seconds(), 9, 'Add seconds');\n    assert.equal(a.add(1, 'minutes').minutes(), 8, 'Add minutes');\n    assert.equal(a.add(1, 'hours').hours(), 7, 'Add hours');\n    assert.equal(a.add(1, 'days').date(), 13, 'Add date');\n    assert.equal(a.add(1, 'weeks').date(), 20, 'Add week');\n    assert.equal(a.add(1, 'months').month(), 10, 'Add month');\n    assert.equal(a.add(1, 'years').year(), 2012, 'Add year');\n    assert.equal(a.add(1, 'quarters').month(), 1, 'Add quarter');\n});\n\ntest('add string short', function (assert) {\n    var a = moment();\n    a.year(2011);\n    a.month(9);\n    a.date(12);\n    a.hours(6);\n    a.minutes(7);\n    a.seconds(8);\n    a.milliseconds(500);\n\n    assert.equal(a.add(50, 'ms').milliseconds(), 550, 'Add milliseconds');\n    assert.equal(a.add(1, 's').seconds(), 9, 'Add seconds');\n    assert.equal(a.add(1, 'm').minutes(), 8, 'Add minutes');\n    assert.equal(a.add(1, 'h').hours(), 7, 'Add hours');\n    assert.equal(a.add(1, 'd').date(), 13, 'Add date');\n    assert.equal(a.add(1, 'w').date(), 20, 'Add week');\n    assert.equal(a.add(1, 'M').month(), 10, 'Add month');\n    assert.equal(a.add(1, 'y').year(), 2012, 'Add year');\n    assert.equal(a.add(1, 'Q').month(), 1, 'Add quarter');\n});\n\ntest('add strings string short reversed', function (assert) {\n    var a = moment();\n    test.expectedDeprecations('moment().add(period, number)');\n\n    a.year(2011);\n    a.month(9);\n    a.date(12);\n    a.hours(6);\n    a.minutes(7);\n    a.seconds(8);\n    a.milliseconds(500);\n\n    assert.equal(a.add('ms', '50').milliseconds(), 550, 'Add milliseconds');\n    assert.equal(a.add('s', '1').seconds(), 9, 'Add seconds');\n    assert.equal(a.add('m', '1').minutes(), 8, 'Add minutes');\n    assert.equal(a.add('h', '1').hours(), 7, 'Add hours');\n    assert.equal(a.add('d', '1').date(), 13, 'Add date');\n    assert.equal(a.add('w', '1').date(), 20, 'Add week');\n    assert.equal(a.add('M', '1').month(), 10, 'Add month');\n    assert.equal(a.add('y', '1').year(), 2012, 'Add year');\n    assert.equal(a.add('Q', '1').month(), 1, 'Add quarter');\n});\n\ntest('subtract strings string short reversed', function (assert) {\n    var a = moment();\n    test.expectedDeprecations('moment().subtract(period, number)');\n\n    a.year(2011);\n    a.month(9);\n    a.date(12);\n    a.hours(6);\n    a.minutes(7);\n    a.seconds(8);\n    a.milliseconds(500);\n\n    assert.equal(a.subtract('ms', '50').milliseconds(), 450, 'Subtract milliseconds');\n    assert.equal(a.subtract('s', '1').seconds(), 7, 'Subtract seconds');\n    assert.equal(a.subtract('m', '1').minutes(), 6, 'Subtract minutes');\n    assert.equal(a.subtract('h', '1').hours(), 5, 'Subtract hours');\n    assert.equal(a.subtract('d', '1').date(), 11, 'Subtract date');\n    assert.equal(a.subtract('w', '1').date(), 4, 'Subtract week');\n    assert.equal(a.subtract('M', '1').month(), 8, 'Subtract month');\n    assert.equal(a.subtract('y', '1').year(), 2010, 'Subtract year');\n    assert.equal(a.subtract('Q', '1').month(), 5, 'Subtract quarter');\n});\n\ntest('add strings string short', function (assert) {\n    var a = moment();\n    a.year(2011);\n    a.month(9);\n    a.date(12);\n    a.hours(6);\n    a.minutes(7);\n    a.seconds(8);\n    a.milliseconds(500);\n\n    assert.equal(a.add('50', 'ms').milliseconds(), 550, 'Add milliseconds');\n    assert.equal(a.add('1', 's').seconds(), 9, 'Add seconds');\n    assert.equal(a.add('1', 'm').minutes(), 8, 'Add minutes');\n    assert.equal(a.add('1', 'h').hours(), 7, 'Add hours');\n    assert.equal(a.add('1', 'd').date(), 13, 'Add date');\n    assert.equal(a.add('1', 'w').date(), 20, 'Add week');\n    assert.equal(a.add('1', 'M').month(), 10, 'Add month');\n    assert.equal(a.add('1', 'y').year(), 2012, 'Add year');\n    assert.equal(a.add('1', 'Q').month(), 1, 'Add quarter');\n});\n\ntest('add no string with milliseconds default', function (assert) {\n    var a = moment();\n    a.year(2011);\n    a.month(9);\n    a.date(12);\n    a.hours(6);\n    a.minutes(7);\n    a.seconds(8);\n    a.milliseconds(500);\n\n    assert.equal(a.add(50).milliseconds(), 550, 'Add milliseconds');\n});\n\ntest('subtract strings string short', function (assert) {\n    var a = moment();\n    a.year(2011);\n    a.month(9);\n    a.date(12);\n    a.hours(6);\n    a.minutes(7);\n    a.seconds(8);\n    a.milliseconds(500);\n\n    assert.equal(a.subtract('50', 'ms').milliseconds(), 450, 'Subtract milliseconds');\n    assert.equal(a.subtract('1', 's').seconds(), 7, 'Subtract seconds');\n    assert.equal(a.subtract('1', 'm').minutes(), 6, 'Subtract minutes');\n    assert.equal(a.subtract('1', 'h').hours(), 5, 'Subtract hours');\n    assert.equal(a.subtract('1', 'd').date(), 11, 'Subtract date');\n    assert.equal(a.subtract('1', 'w').date(), 4, 'Subtract week');\n    assert.equal(a.subtract('1', 'M').month(), 8, 'Subtract month');\n    assert.equal(a.subtract('1', 'y').year(), 2010, 'Subtract year');\n    assert.equal(a.subtract('1', 'Q').month(), 5, 'Subtract quarter');\n});\n\ntest('add across DST', function (assert) {\n    // Detect Safari bug and bail. Hours on 13th March 2011 are shifted\n    // with 1 ahead.\n    if (new Date(2011, 2, 13, 5, 0, 0).getHours() !== 5) {\n        expect(0);\n        return;\n    }\n\n    var a = moment(new Date(2011, 2, 12, 5, 0, 0)),\n        b = moment(new Date(2011, 2, 12, 5, 0, 0)),\n        c = moment(new Date(2011, 2, 12, 5, 0, 0)),\n        d = moment(new Date(2011, 2, 12, 5, 0, 0)),\n        e = moment(new Date(2011, 2, 12, 5, 0, 0));\n    a.add(1, 'days');\n    b.add(24, 'hours');\n    c.add(1, 'months');\n    e.add(1, 'quarter');\n\n    assert.equal(a.hours(), 5, 'adding days over DST difference should result in the same hour');\n    if (b.isDST() && !d.isDST()) {\n        assert.equal(b.hours(), 6, 'adding hours over DST difference should result in a different hour');\n    } else if (!b.isDST() && d.isDST()) {\n        assert.equal(b.hours(), 4, 'adding hours over DST difference should result in a different hour');\n    } else {\n        assert.equal(b.hours(), 5, 'adding hours over DST difference should result in a same hour if the timezone does not have daylight savings time');\n    }\n    assert.equal(c.hours(), 5, 'adding months over DST difference should result in the same hour');\n    assert.equal(e.hours(), 5, 'adding quarters over DST difference should result in the same hour');\n});\n\ntest('add decimal values of days and months', function (assert) {\n    assert.equal(moment([2016,3,3]).add(1.5, 'days').date(), 5, 'adding 1.5 days is rounded to adding 2 day');\n    assert.equal(moment([2016,3,3]).add(-1.5, 'days').date(), 1, 'adding -1.5 days is rounded to adding -2 day');\n    assert.equal(moment([2016,3,1]).add(-1.5, 'days').date(), 30, 'adding -1.5 days on first of month wraps around');\n    assert.equal(moment([2016,3,3]).add(1.5, 'months').month(), 5, 'adding 1.5 months adds 2 months');\n    assert.equal(moment([2016,3,3]).add(-1.5, 'months').month(), 1, 'adding -1.5 months adds -2 months');\n    assert.equal(moment([2016,0,3]).add(-1.5, 'months').month(), 10, 'adding -1.5 months at start of year wraps back');\n    assert.equal(moment([2016,3,3]).subtract(1.5, 'days').date(),1, 'subtract 1.5 days is rounded to subtract 2 day');\n    assert.equal(moment([2016,3,2]).subtract(1.5, 'days').date(), 31, 'subtract 1.5 days subtracts 2 days');\n    assert.equal(moment([2016,1,1]).subtract(1.1, 'days').date(), 31, 'subtract 1.1 days wraps to previous month');\n    assert.equal(moment([2016,3,3]).subtract(-1.5, 'days').date(), 5, 'subtract -1.5 days is rounded to subtract -2 day');\n    assert.equal(moment([2016,3,30]).subtract(-1.5, 'days').date(), 2, 'subtract -1.5 days on last of month wraps around');\n    assert.equal(moment([2016,3,3]).subtract(1.5, 'months').month(), 1, 'subtract 1.5 months subtract 2 months');\n    assert.equal(moment([2016,3,3]).subtract(-1.5, 'months').month(), 5, 'subtract -1.5 months subtract -2 month');\n    assert.equal(moment([2016,11,31]).subtract(-1.5, 'months').month(),1, 'subtract -1.5 months at end of year wraps back');\n    assert.equal(moment([2016, 0,1]).add(1.5, 'years').format('YYYY-MM-DD'), '2017-07-01', 'add 1.5 years adds 1 year six months');\n    assert.equal(moment([2016, 0,1]).add(1.6, 'years').format('YYYY-MM-DD'), '2017-08-01', 'add 1.6 years becomes 1.6*12 = 19.2, round, 19 months');\n    assert.equal(moment([2016,0,1]).add(1.1, 'quarters').format('YYYY-MM-DD'), '2016-04-01', 'add 1.1 quarters 1.1*3=3.3, round, 3 months');\n});\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/test/moment/calendar.js",
    "content": "// These tests are for locale independent features\n// locale dependent tests would be in locale test folder\nimport { module, test } from '../qunit';\nimport moment from '../../moment';\n\nmodule('calendar');\n\ntest('passing a function', function (assert) {\n    var a  = moment().hours(13).minutes(0).seconds(0);\n    assert.equal(moment(a).calendar(null, {\n        'sameDay': function () {\n            return 'h:mmA';\n        }\n    }), '1:00PM', 'should equate');\n});\n\ntest('extending calendar options', function (assert) {\n    var calendarFormat = moment.calendarFormat;\n\n    moment.calendarFormat = function (myMoment, now) {\n        var diff = myMoment.diff(now, 'days', true);\n        var nextMonth = now.clone().add(1, 'month');\n\n        var retVal =  diff < -6 ? 'sameElse' :\n            diff < -1 ? 'lastWeek' :\n            diff < 0 ? 'lastDay' :\n            diff < 1 ? 'sameDay' :\n            diff < 2 ? 'nextDay' :\n            diff < 7 ? 'nextWeek' :\n            (myMoment.month() === now.month() && myMoment.year() === now.year()) ? 'thisMonth' :\n            (nextMonth.month() === myMoment.month() && nextMonth.year() === myMoment.year()) ? 'nextMonth' : 'sameElse';\n        return retVal;\n    };\n\n    moment.updateLocale('en', {\n        calendar : {\n                sameDay : '[Today at] LT',\n                nextDay : '[Tomorrow at] LT',\n                nextWeek : 'dddd [at] LT',\n                lastDay : '[Yesterday at] LT',\n                lastWeek : '[Last] dddd [at] LT',\n                thisMonth : '[This month on the] Do',\n                nextMonth : '[Next month on the] Do',\n                sameElse : 'L'\n            }\n    });\n    var a = moment('2016-01-01').add(28, 'days');\n    var b = moment('2016-01-01').add(1, 'month');\n    try {\n        assert.equal(a.calendar('2016-01-01'), 'This month on the 29th', 'Ad hoc calendar format for this month');\n        assert.equal(b.calendar('2016-01-01'), 'Next month on the 1st', 'Ad hoc calendar format for next month');\n        assert.equal(a.locale('fr').calendar('2016-01-01'), a.locale('fr').format('L'), 'French falls back to default because thisMonth is not defined in that locale');\n    } finally {\n        moment.calendarFormat = calendarFormat;\n        moment.updateLocale('en', null);\n    }\n});\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/test/moment/create.js",
    "content": "import { module, test } from '../qunit';\nimport moment from '../../moment';\n\nmodule('create');\n\ntest('array', function (assert) {\n    assert.ok(moment([2010]).toDate() instanceof Date, '[2010]');\n    assert.ok(moment([2010, 1]).toDate() instanceof Date, '[2010, 1]');\n    assert.ok(moment([2010, 1, 12]).toDate() instanceof Date, '[2010, 1, 12]');\n    assert.ok(moment([2010, 1, 12, 1]).toDate() instanceof Date, '[2010, 1, 12, 1]');\n    assert.ok(moment([2010, 1, 12, 1, 1]).toDate() instanceof Date, '[2010, 1, 12, 1, 1]');\n    assert.ok(moment([2010, 1, 12, 1, 1, 1]).toDate() instanceof Date, '[2010, 1, 12, 1, 1, 1]');\n    assert.ok(moment([2010, 1, 12, 1, 1, 1, 1]).toDate() instanceof Date, '[2010, 1, 12, 1, 1, 1, 1]');\n    assert.equal(+moment(new Date(2010, 1, 14, 15, 25, 50, 125)), +moment([2010, 1, 14, 15, 25, 50, 125]), 'constructing with array === constructing with new Date()');\n});\n\ntest('array with invalid arguments', function (assert) {\n    assert.ok(!moment([2010, null, null]).isValid(), '[2010, null, null]');\n    assert.ok(!moment([1945, null, null]).isValid(), '[1945, null, null] (pre-1970)');\n});\n\ntest('array copying', function (assert) {\n    var importantArray = [2009, 11];\n    moment(importantArray);\n    assert.deepEqual(importantArray, [2009, 11], 'initializer should not mutate the original array');\n});\n\ntest('object', function (assert) {\n    var fmt = 'YYYY-MM-DD HH:mm:ss.SSS',\n        tests = [\n            [{year: 2010}, '2010-01-01 00:00:00.000'],\n            [{year: 2010, month: 1}, '2010-02-01 00:00:00.000'],\n            [{year: 2010, month: 1, day: 12}, '2010-02-12 00:00:00.000'],\n            [{year: 2010, month: 1, date: 12}, '2010-02-12 00:00:00.000'],\n            [{year: 2010, month: 1, day: 12, hours: 1}, '2010-02-12 01:00:00.000'],\n            [{year: 2010, month: 1, date: 12, hours: 1}, '2010-02-12 01:00:00.000'],\n            [{year: 2010, month: 1, day: 12, hours: 1, minutes: 1}, '2010-02-12 01:01:00.000'],\n            [{year: 2010, month: 1, date: 12, hours: 1, minutes: 1}, '2010-02-12 01:01:00.000'],\n            [{year: 2010, month: 1, day: 12, hours: 1, minutes: 1, seconds: 1}, '2010-02-12 01:01:01.000'],\n            [{year: 2010, month: 1, day: 12, hours: 1, minutes: 1, seconds: 1, milliseconds: 1}, '2010-02-12 01:01:01.001'],\n            [{years: 2010, months: 1, days: 14, hours: 15, minutes: 25, seconds: 50, milliseconds: 125}, '2010-02-14 15:25:50.125'],\n            [{year: 2010, month: 1, day: 14, hour: 15, minute: 25, second: 50, millisecond: 125}, '2010-02-14 15:25:50.125'],\n            [{y: 2010, M: 1, d: 14, h: 15, m: 25, s: 50, ms: 125}, '2010-02-14 15:25:50.125']\n        ], i;\n    for (i = 0; i < tests.length; ++i) {\n        assert.equal(moment(tests[i][0]).format(fmt), tests[i][1]);\n    }\n});\n\ntest('multi format array copying', function (assert) {\n    var importantArray = ['MM/DD/YYYY', 'YYYY-MM-DD', 'MM-DD-YYYY'];\n    moment('1999-02-13', importantArray);\n    assert.deepEqual(importantArray, ['MM/DD/YYYY', 'YYYY-MM-DD', 'MM-DD-YYYY'], 'initializer should not mutate the original array');\n});\n\ntest('number', function (assert) {\n    assert.ok(moment(1000).toDate() instanceof Date, '1000');\n    assert.equal(moment(1000).valueOf(), 1000, 'asserting valueOf');\n    assert.equal(moment.utc(1000).valueOf(), 1000, 'asserting valueOf');\n});\n\ntest('unix', function (assert) {\n    assert.equal(moment.unix(1).valueOf(), 1000, '1 unix timestamp == 1000 Date.valueOf');\n    assert.equal(moment(1000).unix(), 1, '1000 Date.valueOf == 1 unix timestamp');\n    assert.equal(moment.unix(1000).valueOf(), 1000000, '1000 unix timestamp == 1000000 Date.valueOf');\n    assert.equal(moment(1500).unix(), 1, '1500 Date.valueOf == 1 unix timestamp');\n    assert.equal(moment(1900).unix(), 1, '1900 Date.valueOf == 1 unix timestamp');\n    assert.equal(moment(2100).unix(), 2, '2100 Date.valueOf == 2 unix timestamp');\n    assert.equal(moment(1333129333524).unix(), 1333129333, '1333129333524 Date.valueOf == 1333129333 unix timestamp');\n    assert.equal(moment(1333129333524000).unix(), 1333129333524, '1333129333524000 Date.valueOf == 1333129333524 unix timestamp');\n});\n\ntest('date', function (assert) {\n    assert.ok(moment(new Date()).toDate() instanceof Date, 'new Date()');\n    assert.equal(moment(new Date(2016,0,1), 'YYYY-MM-DD').format('YYYY-MM-DD'), '2016-01-01', 'If date is provided, format string is ignored');\n});\n\ntest('date with a format as an array', function (assert) {\n    var tests = [\n        new Date(2016, 9, 27),\n        new Date(2016, 9, 28),\n        new Date(2016, 9, 29),\n        new Date(2016, 9, 30),\n        new Date(2016, 9, 31)\n    ], i;\n\n    for (i = 0; i < tests.length; i++) {\n        assert.equal(moment(tests[i]).format(), moment(tests[i], ['MM/DD/YYYY'], false).format(), 'Passing date with a format array should still return the correct date');\n    }\n});\n\ntest('date mutation', function (assert) {\n    var a = new Date();\n    assert.ok(moment(a).toDate() !== a, 'the date moment uses should not be the date passed in');\n});\n\ntest('moment', function (assert) {\n    assert.ok(moment(moment()).toDate() instanceof Date, 'moment(moment())');\n    assert.ok(moment(moment(moment())).toDate() instanceof Date, 'moment(moment(moment()))');\n});\n\ntest('cloning moment should only copy own properties', function (assert) {\n    assert.ok(!moment().clone().hasOwnProperty('month'), 'Should not clone prototype methods');\n});\n\ntest('cloning moment works with weird clones', function (assert) {\n    var extend = function (a, b) {\n        var i;\n        for (i in b) {\n            a[i] = b[i];\n        }\n        return a;\n    },\n    now = moment(),\n    nowu = moment.utc();\n\n    assert.equal(+extend({}, now).clone(), +now, 'cloning extend-ed now is now');\n    assert.equal(+extend({}, nowu).clone(), +nowu, 'cloning extend-ed utc now is utc now');\n});\n\ntest('cloning respects moment.momentProperties', function (assert) {\n    var m = moment();\n\n    assert.equal(m.clone()._special, undefined, 'cloning ignores extra properties');\n    m._special = 'bacon';\n    moment.momentProperties.push('_special');\n    assert.equal(m.clone()._special, 'bacon', 'cloning respects momentProperties');\n    moment.momentProperties.pop();\n});\n\ntest('undefined', function (assert) {\n    assert.ok(moment().toDate() instanceof Date, 'undefined');\n});\n\ntest('iso with bad input', function (assert) {\n    assert.ok(!moment('a', moment.ISO_8601).isValid(), 'iso parsing with invalid string');\n    assert.ok(!moment('a', moment.ISO_8601, true).isValid(), 'iso parsing with invalid string, strict');\n});\n\ntest('iso format 24hrs', function (assert) {\n    assert.equal(moment('2014-01-01T24:00:00.000').format('YYYY-MM-DD[T]HH:mm:ss.SSS'),\n            '2014-01-02T00:00:00.000', 'iso format with 24:00 localtime');\n    assert.equal(moment.utc('2014-01-01T24:00:00.000').format('YYYY-MM-DD[T]HH:mm:ss.SSS'),\n            '2014-01-02T00:00:00.000', 'iso format with 24:00 utc');\n});\n\ntest('string without format - json', function (assert) {\n    assert.equal(moment('Date(1325132654000)').valueOf(), 1325132654000, 'Date(1325132654000)');\n    assert.equal(moment('Date(-1325132654000)').valueOf(), -1325132654000, 'Date(-1325132654000)');\n    assert.equal(moment('/Date(1325132654000)/').valueOf(), 1325132654000, '/Date(1325132654000)/');\n    assert.equal(moment('/Date(1325132654000+0700)/').valueOf(), 1325132654000, '/Date(1325132654000+0700)/');\n    assert.equal(moment('/Date(1325132654000-0700)/').valueOf(), 1325132654000, '/Date(1325132654000-0700)/');\n});\n\ntest('string with format dropped am/pm bug', function (assert) {\n    moment.locale('en');\n\n    assert.equal(moment('05/1/2012 12:25:00', 'MM/DD/YYYY h:m:s a').format('MM/DD/YYYY'), '05/01/2012', 'should not break if am/pm is left off from the parsing tokens');\n    assert.equal(moment('05/1/2012 12:25:00 am', 'MM/DD/YYYY h:m:s a').format('MM/DD/YYYY'), '05/01/2012', 'should not break if am/pm is left off from the parsing tokens');\n    assert.equal(moment('05/1/2012 12:25:00 pm', 'MM/DD/YYYY h:m:s a').format('MM/DD/YYYY'), '05/01/2012', 'should not break if am/pm is left off from the parsing tokens');\n\n    assert.ok(moment('05/1/2012 12:25:00', 'MM/DD/YYYY h:m:s a').isValid());\n    assert.ok(moment('05/1/2012 12:25:00 am', 'MM/DD/YYYY h:m:s a').isValid());\n    assert.ok(moment('05/1/2012 12:25:00 pm', 'MM/DD/YYYY h:m:s a').isValid());\n});\n\ntest('empty string with formats', function (assert) {\n    assert.equal(moment('', 'MM').format('YYYY-MM-DD HH:mm:ss'), 'Invalid date');\n    assert.equal(moment(' ', 'MM').format('YYYY-MM-DD HH:mm:ss'), 'Invalid date');\n    assert.equal(moment(' ', 'DD').format('YYYY-MM-DD HH:mm:ss'), 'Invalid date');\n    assert.equal(moment(' ', ['MM', 'DD']).format('YYYY-MM-DD HH:mm:ss'), 'Invalid date');\n\n    assert.ok(!moment('', 'MM').isValid());\n    assert.ok(!moment(' ', 'MM').isValid());\n    assert.ok(!moment(' ', 'DD').isValid());\n    assert.ok(!moment(' ', ['MM', 'DD']).isValid());\n});\n\ntest('undefined argument with formats', function (assert) {\n    assert.equal(moment(undefined, 'MM').format('YYYY-MM-DD HH:mm:ss'), 'Invalid date');\n    assert.equal(moment(undefined, 'DD').format('YYYY-MM-DD HH:mm:ss'), 'Invalid date');\n    assert.equal(moment(undefined, ['MM', 'DD']).format('YYYY-MM-DD HH:mm:ss'), 'Invalid date');\n\n    assert.ok(!moment(undefined, 'MM').isValid());\n    assert.ok(!moment(undefined, 'MM').isValid());\n    assert.ok(!moment(undefined, 'DD').isValid());\n    assert.ok(!moment(undefined, ['MM', 'DD']).isValid());\n});\n\ntest('defaulting to current date', function (assert) {\n    var now = moment();\n    assert.equal(moment('12:13:14', 'hh:mm:ss').format('YYYY-MM-DD hh:mm:ss'),\n                 now.clone().hour(12).minute(13).second(14).format('YYYY-MM-DD hh:mm:ss'),\n                 'given only time default to current date');\n    assert.equal(moment('05', 'DD').format('YYYY-MM-DD'),\n                 now.clone().date(5).format('YYYY-MM-DD'),\n                 'given day of month default to current month, year');\n    assert.equal(moment('05', 'MM').format('YYYY-MM-DD'),\n                 now.clone().month(4).date(1).format('YYYY-MM-DD'),\n                 'given month default to current year');\n    assert.equal(moment('1996', 'YYYY').format('YYYY-MM-DD'),\n                 now.clone().year(1996).month(0).date(1).format('YYYY-MM-DD'),\n                 'given year do not default');\n});\n\ntest('matching am/pm', function (assert) {\n    assert.equal(moment('2012-09-03T03:00PM',   'YYYY-MM-DDThh:mmA').format('YYYY-MM-DDThh:mmA'), '2012-09-03T03:00PM', 'am/pm should parse correctly for PM');\n    assert.equal(moment('2012-09-03T03:00P.M.', 'YYYY-MM-DDThh:mmA').format('YYYY-MM-DDThh:mmA'), '2012-09-03T03:00PM', 'am/pm should parse correctly for P.M.');\n    assert.equal(moment('2012-09-03T03:00P',    'YYYY-MM-DDThh:mmA').format('YYYY-MM-DDThh:mmA'), '2012-09-03T03:00PM', 'am/pm should parse correctly for P');\n    assert.equal(moment('2012-09-03T03:00pm',   'YYYY-MM-DDThh:mmA').format('YYYY-MM-DDThh:mmA'), '2012-09-03T03:00PM', 'am/pm should parse correctly for pm');\n    assert.equal(moment('2012-09-03T03:00p.m.', 'YYYY-MM-DDThh:mmA').format('YYYY-MM-DDThh:mmA'), '2012-09-03T03:00PM', 'am/pm should parse correctly for p.m.');\n    assert.equal(moment('2012-09-03T03:00p',    'YYYY-MM-DDThh:mmA').format('YYYY-MM-DDThh:mmA'), '2012-09-03T03:00PM', 'am/pm should parse correctly for p');\n\n    assert.equal(moment('2012-09-03T03:00AM',   'YYYY-MM-DDThh:mmA').format('YYYY-MM-DDThh:mmA'), '2012-09-03T03:00AM', 'am/pm should parse correctly for AM');\n    assert.equal(moment('2012-09-03T03:00A.M.', 'YYYY-MM-DDThh:mmA').format('YYYY-MM-DDThh:mmA'), '2012-09-03T03:00AM', 'am/pm should parse correctly for A.M.');\n    assert.equal(moment('2012-09-03T03:00A',    'YYYY-MM-DDThh:mmA').format('YYYY-MM-DDThh:mmA'), '2012-09-03T03:00AM', 'am/pm should parse correctly for A');\n    assert.equal(moment('2012-09-03T03:00am',   'YYYY-MM-DDThh:mmA').format('YYYY-MM-DDThh:mmA'), '2012-09-03T03:00AM', 'am/pm should parse correctly for am');\n    assert.equal(moment('2012-09-03T03:00a.m.', 'YYYY-MM-DDThh:mmA').format('YYYY-MM-DDThh:mmA'), '2012-09-03T03:00AM', 'am/pm should parse correctly for a.m.');\n    assert.equal(moment('2012-09-03T03:00a',    'YYYY-MM-DDThh:mmA').format('YYYY-MM-DDThh:mmA'), '2012-09-03T03:00AM', 'am/pm should parse correctly for a');\n\n    assert.equal(moment('5:00p.m.March 4 2012', 'h:mmAMMMM D YYYY').format('YYYY-MM-DDThh:mmA'), '2012-03-04T05:00PM', 'am/pm should parse correctly before month names');\n});\n\ntest('string with format', function (assert) {\n    moment.locale('en');\n    var a = [\n        ['YYYY-Q',              '2014-4'],\n        ['MM-DD-YYYY',          '12-02-1999'],\n        ['DD-MM-YYYY',          '12-02-1999'],\n        ['DD/MM/YYYY',          '12/02/1999'],\n        ['DD_MM_YYYY',          '12_02_1999'],\n        ['DD:MM:YYYY',          '12:02:1999'],\n        ['D-M-YY',              '2-2-99'],\n        ['YY',                  '99'],\n        ['DDD-YYYY',            '300-1999'],\n        ['DD-MM-YYYY h:m:s',    '12-02-1999 2:45:10'],\n        ['DD-MM-YYYY h:m:s a',  '12-02-1999 2:45:10 am'],\n        ['DD-MM-YYYY h:m:s a',  '12-02-1999 2:45:10 pm'],\n        ['h:mm a',              '12:00 pm'],\n        ['h:mm a',              '12:30 pm'],\n        ['h:mm a',              '12:00 am'],\n        ['h:mm a',              '12:30 am'],\n        ['HH:mm',               '12:00'],\n        ['kk:mm',               '12:00'],\n        ['YYYY-MM-DDTHH:mm:ss', '2011-11-11T11:11:11'],\n        ['MM-DD-YYYY [M]',      '12-02-1999 M'],\n        ['ddd MMM DD HH:mm:ss YYYY', 'Tue Apr 07 22:52:51 2009'],\n        ['HH:mm:ss',            '12:00:00'],\n        ['HH:mm:ss',            '12:30:00'],\n        ['HH:mm:ss',            '00:00:00'],\n        ['HH:mm:ss S',          '00:30:00 1'],\n        ['HH:mm:ss SS',         '00:30:00 12'],\n        ['HH:mm:ss SSS',        '00:30:00 123'],\n        ['HH:mm:ss S',          '00:30:00 7'],\n        ['HH:mm:ss SS',         '00:30:00 78'],\n        ['HH:mm:ss SSS',        '00:30:00 789'],\n        ['kk:mm:ss',            '12:00:00'],\n        ['kk:mm:ss',            '12:30:00'],\n        ['kk:mm:ss',            '24:00:00'],\n        ['kk:mm:ss S',          '24:30:00 1'],\n        ['kk:mm:ss SS',         '24:30:00 12'],\n        ['kk:mm:ss SSS',        '24:30:00 123'],\n        ['kk:mm:ss S',          '24:30:00 7'],\n        ['kk:mm:ss SS',         '24:30:00 78'],\n        ['kk:mm:ss SSS',        '24:30:00 789'],\n        ['X',                   '1234567890'],\n        ['x',                   '1234567890123'],\n        ['LT',                  '12:30 AM'],\n        ['LTS',                 '12:30:29 AM'],\n        ['L',                   '09/02/1999'],\n        ['l',                   '9/2/1999'],\n        ['LL',                  'September 2, 1999'],\n        ['ll',                  'Sep 2, 1999'],\n        ['LLL',                 'September 2, 1999 12:30 AM'],\n        ['lll',                 'Sep 2, 1999 12:30 AM'],\n        ['LLLL',                'Thursday, September 2, 1999 12:30 AM'],\n        ['llll',                'Thu, Sep 2, 1999 12:30 AM']\n    ],\n    m,\n    i;\n\n    for (i = 0; i < a.length; i++) {\n        m = moment(a[i][1], a[i][0]);\n        assert.ok(m.isValid());\n        assert.equal(m.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('2 digit year with YYYY format', function (assert) {\n    assert.equal(moment('9/2/99', 'D/M/YYYY').format('DD/MM/YYYY'), '09/02/1999', 'D/M/YYYY ---> 9/2/99');\n    assert.equal(moment('9/2/1999', 'D/M/YYYY').format('DD/MM/YYYY'), '09/02/1999', 'D/M/YYYY ---> 9/2/1999');\n    assert.equal(moment('9/2/68', 'D/M/YYYY').format('DD/MM/YYYY'), '09/02/2068', 'D/M/YYYY ---> 9/2/68');\n    assert.equal(moment('9/2/69', 'D/M/YYYY').format('DD/MM/YYYY'), '09/02/1969', 'D/M/YYYY ---> 9/2/69');\n});\n\ntest('unix timestamp format', function (assert) {\n    var formats = ['X', 'X.S', 'X.SS', 'X.SSS'], i, format;\n\n    for (i = 0; i < formats.length; i++) {\n        format = formats[i];\n        assert.equal(moment('1234567890',     format).valueOf(), 1234567890 * 1000,       format + ' matches timestamp without milliseconds');\n        assert.equal(moment('1234567890.1',   format).valueOf(), 1234567890 * 1000 + 100, format + ' matches timestamp with deciseconds');\n        assert.equal(moment('1234567890.12',  format).valueOf(), 1234567890 * 1000 + 120, format + ' matches timestamp with centiseconds');\n        assert.equal(moment('1234567890.123', format).valueOf(), 1234567890 * 1000 + 123, format + ' matches timestamp with milliseconds');\n    }\n});\n\ntest('unix offset milliseconds', function (assert) {\n    assert.equal(moment('1234567890123', 'x').valueOf(), 1234567890123, 'x matches unix offset in milliseconds');\n});\n\ntest('milliseconds format', function (assert) {\n    assert.equal(moment('1', 'S').get('ms'), 100, 'deciseconds');\n    // assert.equal(moment('10', 'S', true).isValid(), false, 'deciseconds with two digits');\n    // assert.equal(moment('1', 'SS', true).isValid(), false, 'centiseconds with one digits');\n    assert.equal(moment('12', 'SS').get('ms'), 120, 'centiseconds');\n    // assert.equal(moment('123', 'SS', true).isValid(), false, 'centiseconds with three digits');\n    assert.equal(moment('123', 'SSS').get('ms'), 123, 'milliseconds');\n    assert.equal(moment('1234', 'SSSS').get('ms'), 123, 'milliseconds with SSSS');\n    assert.equal(moment('123456789101112', 'SSSS').get('ms'), 123, 'milliseconds with SSSS');\n});\n\ntest('string with format no separators', function (assert) {\n    moment.locale('en');\n    var a = [\n        ['MMDDYYYY',          '12021999'],\n        ['DDMMYYYY',          '12021999'],\n        ['YYYYMMDD',          '19991202'],\n        ['DDMMMYYYY',         '10Sep2001']\n    ], i;\n\n    for (i = 0; i < a.length; i++) {\n        assert.equal(moment(a[i][1], a[i][0]).format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n    }\n});\n\ntest('string with format (timezone)', function (assert) {\n    assert.equal(moment('5 -0700', 'H ZZ').toDate().getUTCHours(), 12, 'parse hours \\'5 -0700\\' ---> \\'H ZZ\\'');\n    assert.equal(moment('5 -07:00', 'H Z').toDate().getUTCHours(), 12, 'parse hours \\'5 -07:00\\' ---> \\'H Z\\'');\n    assert.equal(moment('5 -0730', 'H ZZ').toDate().getUTCMinutes(), 30, 'parse hours \\'5 -0730\\' ---> \\'H ZZ\\'');\n    assert.equal(moment('5 -07:30', 'H Z').toDate().getUTCMinutes(), 30, 'parse hours \\'5 -07:0\\' ---> \\'H Z\\'');\n    assert.equal(moment('5 +0100', 'H ZZ').toDate().getUTCHours(), 4, 'parse hours \\'5 +0100\\' ---> \\'H ZZ\\'');\n    assert.equal(moment('5 +01:00', 'H Z').toDate().getUTCHours(), 4, 'parse hours \\'5 +01:00\\' ---> \\'H Z\\'');\n    assert.equal(moment('5 +0130', 'H ZZ').toDate().getUTCMinutes(), 30, 'parse hours \\'5 +0130\\' ---> \\'H ZZ\\'');\n    assert.equal(moment('5 +01:30', 'H Z').toDate().getUTCMinutes(), 30, 'parse hours \\'5 +01:30\\' ---> \\'H Z\\'');\n});\n\ntest('string with format (timezone offset)', function (assert) {\n    var a, b, c, d, e, f;\n    a = new Date(Date.UTC(2011, 0, 1, 1));\n    b = moment('2011 1 1 0 -01:00', 'YYYY MM DD HH Z');\n    assert.equal(a.getHours(), b.hours(), 'date created with utc == parsed string with timezone offset');\n    assert.equal(+a, +b, 'date created with utc == parsed string with timezone offset');\n    c = moment('2011 2 1 10 -05:00', 'YYYY MM DD HH Z');\n    d = moment('2011 2 1 8 -07:00', 'YYYY MM DD HH Z');\n    assert.equal(c.hours(), d.hours(), '10 am central time == 8 am pacific time');\n    e = moment.utc('Fri, 20 Jul 2012 17:15:00', 'ddd, DD MMM YYYY HH:mm:ss');\n    f = moment.utc('Fri, 20 Jul 2012 10:15:00 -0700', 'ddd, DD MMM YYYY HH:mm:ss ZZ');\n    assert.equal(e.hours(), f.hours(), 'parse timezone offset in utc');\n});\n\ntest('string with timezone around start of year', function (assert) {\n    assert.equal(moment('2000-01-01T00:00:00.000+01:00').toISOString(), '1999-12-31T23:00:00.000Z', '+1:00 around 2000');\n    assert.equal(moment('2000-01-01T00:00:00.000-01:00').toISOString(), '2000-01-01T01:00:00.000Z', '-1:00 around 2000');\n    assert.equal(moment('1970-01-01T00:00:00.000+01:00').toISOString(), '1969-12-31T23:00:00.000Z', '+1:00 around 1970');\n    assert.equal(moment('1970-01-01T00:00:00.000-01:00').toISOString(), '1970-01-01T01:00:00.000Z', '-1:00 around 1970');\n    assert.equal(moment('1200-01-01T00:00:00.000+01:00').toISOString(), '1199-12-31T23:00:00.000Z', '+1:00 around 1200');\n    assert.equal(moment('1200-01-01T00:00:00.000-01:00').toISOString(), '1200-01-01T01:00:00.000Z', '-1:00 around 1200');\n});\n\ntest('string with array of formats', function (assert) {\n    var thursdayForCurrentWeek = moment()\n      .day(4)\n      .format('YYYY MM DD');\n\n    assert.equal(moment('11-02-1999', ['MM-DD-YYYY', 'DD-MM-YYYY']).format('MM DD YYYY'), '11 02 1999', 'switching month and day');\n    assert.equal(moment('02-11-1999', ['MM/DD/YYYY', 'YYYY MM DD', 'MM-DD-YYYY']).format('MM DD YYYY'), '02 11 1999', 'year last');\n    assert.equal(moment('1999-02-11', ['MM/DD/YYYY', 'YYYY MM DD', 'MM-DD-YYYY']).format('MM DD YYYY'), '02 11 1999', 'year first');\n\n    assert.equal(moment('02-11-1999', ['MM/DD/YYYY', 'YYYY MM DD']).format('MM DD YYYY'), '02 11 1999', 'year last');\n    assert.equal(moment('1999-02-11', ['MM/DD/YYYY', 'YYYY MM DD']).format('MM DD YYYY'), '02 11 1999', 'year first');\n    assert.equal(moment('02-11-1999', ['YYYY MM DD', 'MM/DD/YYYY']).format('MM DD YYYY'), '02 11 1999', 'year last');\n    assert.equal(moment('1999-02-11', ['YYYY MM DD', 'MM/DD/YYYY']).format('MM DD YYYY'), '02 11 1999', 'year first');\n\n    assert.equal(moment('13-11-1999', ['MM/DD/YYYY', 'DD/MM/YYYY']).format('MM DD YYYY'), '11 13 1999', 'second must be month');\n    assert.equal(moment('11-13-1999', ['MM/DD/YYYY', 'DD/MM/YYYY']).format('MM DD YYYY'), '11 13 1999', 'first must be month');\n    assert.equal(moment('01-02-2000', ['MM/DD/YYYY', 'DD/MM/YYYY']).format('MM DD YYYY'), '01 02 2000', 'either can be a month, month first format');\n    assert.equal(moment('02-01-2000', ['DD/MM/YYYY', 'MM/DD/YYYY']).format('MM DD YYYY'), '01 02 2000', 'either can be a month, day first format');\n\n    assert.equal(moment('11-02-10', ['MM/DD/YY', 'YY MM DD', 'DD-MM-YY']).format('MM DD YYYY'), '02 11 2010', 'all unparsed substrings have influence on format penalty');\n    assert.equal(moment('11-02-10', ['MM-DD-YY HH:mm', 'YY MM DD']).format('MM DD YYYY'), '02 10 2011', 'prefer formats without extra tokens');\n    assert.equal(moment('11-02-10 junk', ['MM-DD-YY', 'YY.MM.DD [junk]']).format('MM DD YYYY'), '02 10 2011', 'prefer formats that dont result in extra characters');\n    assert.equal(moment('11-22-10', ['YY-MM-DD', 'YY-DD-MM']).format('MM DD YYYY'), '10 22 2011', 'prefer valid results');\n\n    assert.equal(moment('gibberish', ['YY-MM-DD', 'YY-DD-MM']).format('MM DD YYYY'), 'Invalid date', 'doest throw for invalid strings');\n    assert.equal(moment('gibberish', []).format('MM DD YYYY'), 'Invalid date', 'doest throw for an empty array');\n\n    // https://github.com/moment/moment/issues/1143\n    assert.equal(moment(\n        'System Administrator and Database Assistant (7/1/2011), System Administrator and Database Assistant (7/1/2011), Database Coordinator (7/1/2011), Vice President (7/1/2011), System Administrator and Database Assistant (5/31/2012), Database Coordinator (7/1/2012), System Administrator and Database Assistant (7/1/2013)',\n        ['MM/DD/YYYY', 'MM-DD-YYYY', 'YYYY-MM-DD', 'YYYY-MM-DDTHH:mm:ssZ'])\n        .format('YYYY-MM-DD'), '2011-07-01', 'Works for long strings');\n\n    assert.equal(moment('11-02-10', ['MM.DD.YY', 'DD-MM-YY']).format('MM DD YYYY'), '02 11 2010', 'escape RegExp special characters on comparing');\n\n    assert.equal(moment('13-10-98', ['DD MM YY', 'DD MM YYYY'])._f, 'DD MM YY', 'use two digit year');\n    assert.equal(moment('13-10-1998', ['DD MM YY', 'DD MM YYYY'])._f, 'DD MM YYYY', 'use four digit year');\n\n    assert.equal(moment('01', ['MM', 'DD'])._f, 'MM', 'Should use first valid format');\n\n    assert.equal(moment('Thursday 8:30pm', ['dddd h:mma']).format('YYYY MM DD dddd h:mma'), thursdayForCurrentWeek + ' Thursday 8:30pm', 'Default to current week');\n});\n\ntest('string with array of formats + ISO', function (assert) {\n    assert.equal(moment('1994', [moment.ISO_8601, 'MM', 'HH:mm', 'YYYY']).year(), 1994, 'iso: assert parse YYYY');\n    assert.equal(moment('17:15', [moment.ISO_8601, 'MM', 'HH:mm', 'YYYY']).hour(), 17, 'iso: assert parse HH:mm (1)');\n    assert.equal(moment('24:15', [moment.ISO_8601, 'MM', 'kk:mm', 'YYYY']).hour(), 0, 'iso: assert parse kk:mm');\n    assert.equal(moment('17:15', [moment.ISO_8601, 'MM', 'HH:mm', 'YYYY']).minutes(), 15, 'iso: assert parse HH:mm (2)');\n    assert.equal(moment('06', [moment.ISO_8601, 'MM', 'HH:mm', 'YYYY']).month(), 6 - 1, 'iso: assert parse MM');\n    assert.equal(moment('2012-06-01', [moment.ISO_8601, 'MM', 'HH:mm', 'YYYY']).parsingFlags().iso, true, 'iso: assert parse iso');\n    assert.equal(moment('2014-05-05', [moment.ISO_8601, 'YYYY-MM-DD']).parsingFlags().iso, true, 'iso: edge case array precedence iso');\n    assert.equal(moment('2014-05-05', ['YYYY-MM-DD', moment.ISO_8601]).parsingFlags().iso, false, 'iso: edge case array precedence not iso');\n});\n\ntest('string with format - years', function (assert) {\n    assert.equal(moment('67', 'YY').format('YYYY'), '2067', '67 > 2067');\n    assert.equal(moment('68', 'YY').format('YYYY'), '2068', '68 > 2068');\n    assert.equal(moment('69', 'YY').format('YYYY'), '1969', '69 > 1969');\n    assert.equal(moment('70', 'YY').format('YYYY'), '1970', '70 > 1970');\n});\n\ntest('implicit cloning', function (assert) {\n    var momentA = moment([2011, 10, 10]),\n    momentB = moment(momentA);\n    momentA.month(5);\n    assert.equal(momentB.month(), 10, 'Calling moment() on a moment will create a clone');\n    assert.equal(momentA.month(), 5, 'Calling moment() on a moment will create a clone');\n});\n\ntest('explicit cloning', function (assert) {\n    var momentA = moment([2011, 10, 10]),\n    momentB = momentA.clone();\n    momentA.month(5);\n    assert.equal(momentB.month(), 10, 'Calling moment() on a moment will create a clone');\n    assert.equal(momentA.month(), 5, 'Calling moment() on a moment will create a clone');\n});\n\ntest('cloning carrying over utc mode', function (assert) {\n    assert.equal(moment().local().clone()._isUTC, false, 'An explicit cloned local moment should have _isUTC == false');\n    assert.equal(moment().utc().clone()._isUTC, true, 'An cloned utc moment should have _isUTC == true');\n    assert.equal(moment().clone()._isUTC, false, 'An explicit cloned local moment should have _isUTC == false');\n    assert.equal(moment.utc().clone()._isUTC, true, 'An explicit cloned utc moment should have _isUTC == true');\n    assert.equal(moment(moment().local())._isUTC, false, 'An implicit cloned local moment should have _isUTC == false');\n    assert.equal(moment(moment().utc())._isUTC, true, 'An implicit cloned utc moment should have _isUTC == true');\n    assert.equal(moment(moment())._isUTC, false, 'An implicit cloned local moment should have _isUTC == false');\n    assert.equal(moment(moment.utc())._isUTC, true, 'An implicit cloned utc moment should have _isUTC == true');\n});\n\ntest('parsing RFC 2822', function (assert) {\n    var testCases = {\n        'clean RFC2822 datetime with all options': 'Tue, 01 Nov 2016 01:23:45 UT',\n        'clean RFC2822 datetime without comma': 'Tue 01 Nov 2016 02:23:45 GMT',\n        'clean RFC2822 datetime without seconds': 'Tue, 01 Nov 2016 03:23 +0000',\n        'clean RFC2822 datetime without century': 'Tue, 01 Nov 16 04:23:45 Z',\n        'clean RFC2822 datetime without day': '01 Nov 2016 05:23:45 z',\n        'clean RFC2822 datetime with single-digit day-of-month': 'Tue, 1 Nov 2016 06:23:45 GMT',\n        'RFC2822 datetime with CFWSs': '(Init Comment) Tue,\\n 1 Nov              2016 (Split\\n Comment)  07:23:45 +0000 (GMT)'\n    };\n    var testCase;\n\n    for (testCase in testCases) {\n        var testResult = moment(testCases[testCase], moment.RFC_2822, true);\n        assert.ok(testResult.isValid(), testResult);\n        assert.ok(testResult.parsingFlags().rfc2822, testResult + ' - rfc2822 parsingFlag');\n    }\n});\n\ntest('non RFC 2822 strings', function (assert) {\n    var testCases = {\n        'RFC2822 datetime with all options but invalid day delimiter': 'Tue. 01 Nov 2016 01:23:45 GMT',\n        'RFC2822 datetime with mismatching Day (week v date)': 'Mon, 01 Nov 2016 01:23:45 GMT'\n    };\n    var testCase;\n\n    for (testCase in testCases) {\n        var testResult = moment(testCases[testCase], moment.RFC_2822, true);\n        assert.ok(!testResult.isValid(), testResult);\n        assert.ok(!testResult.parsingFlags().rfc2822, testResult + ' - rfc2822 parsingFlag');\n    }\n});\n\ntest('parsing iso', function (assert) {\n    var offset = moment([2011, 9, 8]).utcOffset(),\n    pad = function (input) {\n        if (input < 10) {\n            return '0' + input;\n        }\n        return '' + input;\n    },\n    hourOffset = (offset > 0 ? Math.floor(offset / 60) : Math.ceil(offset / 60)),\n    minOffset = offset - (hourOffset * 60),\n    tz = (offset >= 0) ?\n        '+' + pad(hourOffset) + ':' + pad(minOffset) :\n        '-' + pad(-hourOffset) + ':' + pad(-minOffset),\n    tz2 = tz.replace(':', ''),\n    tz3 = tz2.slice(0, 3),\n    //Tz3 removes minutes digit so will break the tests when parsed if they all use the same minutes digit\n    minutesForTz3 = pad((4 + minOffset) % 60),\n    minute = pad(4 + minOffset),\n\n    formats = [\n        ['2011-10-08',                    '2011-10-08T00:00:00.000' + tz],\n        ['2011-10-08T18',                 '2011-10-08T18:00:00.000' + tz],\n        ['2011-10-08T18:04',              '2011-10-08T18:04:00.000' + tz],\n        ['2011-10-08T18:04:20',           '2011-10-08T18:04:20.000' + tz],\n        ['2011-10-08T18:04' + tz,         '2011-10-08T18:04:00.000' + tz],\n        ['2011-10-08T18:04:20' + tz,      '2011-10-08T18:04:20.000' + tz],\n        ['2011-10-08T18:04' + tz2,        '2011-10-08T18:04:00.000' + tz],\n        ['2011-10-08T18:04:20' + tz2,     '2011-10-08T18:04:20.000' + tz],\n        ['2011-10-08T18:04' + tz3,        '2011-10-08T18:' + minutesForTz3 + ':00.000' + tz],\n        ['2011-10-08T18:04:20' + tz3,     '2011-10-08T18:' + minutesForTz3 + ':20.000' + tz],\n        ['2011-10-08T18:04:20.1' + tz2,   '2011-10-08T18:04:20.100' + tz],\n        ['2011-10-08T18:04:20.11' + tz2,  '2011-10-08T18:04:20.110' + tz],\n        ['2011-10-08T18:04:20.111' + tz2, '2011-10-08T18:04:20.111' + tz],\n        ['2011-10-08 18',                 '2011-10-08T18:00:00.000' + tz],\n        ['2011-10-08 18:04',              '2011-10-08T18:04:00.000' + tz],\n        ['2011-10-08 18:04:20',           '2011-10-08T18:04:20.000' + tz],\n        ['2011-10-08 18:04' + tz,         '2011-10-08T18:04:00.000' + tz],\n        ['2011-10-08 18:04:20' + tz,      '2011-10-08T18:04:20.000' + tz],\n        ['2011-10-08 18:04' + tz2,        '2011-10-08T18:04:00.000' + tz],\n        ['2011-10-08 18:04:20' + tz2,     '2011-10-08T18:04:20.000' + tz],\n        ['2011-10-08 18:04' + tz3,        '2011-10-08T18:' + minutesForTz3 + ':00.000' + tz],\n        ['2011-10-08 18:04:20' + tz3,     '2011-10-08T18:' + minutesForTz3 + ':20.000' + tz],\n        ['2011-10-08 18:04:20.1' + tz2,   '2011-10-08T18:04:20.100' + tz],\n        ['2011-10-08 18:04:20.11' + tz2,  '2011-10-08T18:04:20.110' + tz],\n        ['2011-10-08 18:04:20.111' + tz2, '2011-10-08T18:04:20.111' + tz],\n        ['2011-W40',                      '2011-10-03T00:00:00.000' + tz],\n        ['2011-W40-6',                    '2011-10-08T00:00:00.000' + tz],\n        ['2011-W40-6T18',                 '2011-10-08T18:00:00.000' + tz],\n        ['2011-W40-6T18:04',              '2011-10-08T18:04:00.000' + tz],\n        ['2011-W40-6T18:04:20',           '2011-10-08T18:04:20.000' + tz],\n        ['2011-W40-6T18:04' + tz,         '2011-10-08T18:04:00.000' + tz],\n        ['2011-W40-6T18:04:20' + tz,      '2011-10-08T18:04:20.000' + tz],\n        ['2011-W40-6T18:04' + tz2,        '2011-10-08T18:04:00.000' + tz],\n        ['2011-W40-6T18:04:20' + tz2,     '2011-10-08T18:04:20.000' + tz],\n        ['2011-W40-6T18:04' + tz3,        '2011-10-08T18:' + minutesForTz3 + ':00.000' + tz],\n        ['2011-W40-6T18:04:20' + tz3,     '2011-10-08T18:' + minutesForTz3 + ':20.000' + tz],\n        ['2011-W40-6T18:04:20.1' + tz2,   '2011-10-08T18:04:20.100' + tz],\n        ['2011-W40-6T18:04:20.11' + tz2,  '2011-10-08T18:04:20.110' + tz],\n        ['2011-W40-6T18:04:20.111' + tz2, '2011-10-08T18:04:20.111' + tz],\n        ['2011-W40-6 18',                 '2011-10-08T18:00:00.000' + tz],\n        ['2011-W40-6 18:04',              '2011-10-08T18:04:00.000' + tz],\n        ['2011-W40-6 18:04:20',           '2011-10-08T18:04:20.000' + tz],\n        ['2011-W40-6 18:04' + tz,         '2011-10-08T18:04:00.000' + tz],\n        ['2011-W40-6 18:04:20' + tz,      '2011-10-08T18:04:20.000' + tz],\n        ['2011-W40-6 18:04' + tz2,        '2011-10-08T18:04:00.000' + tz],\n        ['2011-W40-6 18:04:20' + tz2,     '2011-10-08T18:04:20.000' + tz],\n        ['2011-W40-6 18:04' + tz3,        '2011-10-08T18:' + minutesForTz3 + ':00.000' + tz],\n        ['2011-W40-6 18:04:20' + tz3,     '2011-10-08T18:' + minutesForTz3 + ':20.000' + tz],\n        ['2011-W40-6 18:04:20.1' + tz2,   '2011-10-08T18:04:20.100' + tz],\n        ['2011-W40-6 18:04:20.11' + tz2,  '2011-10-08T18:04:20.110' + tz],\n        ['2011-W40-6 18:04:20.111' + tz2, '2011-10-08T18:04:20.111' + tz],\n        ['2011-281',                      '2011-10-08T00:00:00.000' + tz],\n        ['2011-281T18',                   '2011-10-08T18:00:00.000' + tz],\n        ['2011-281T18:04',                '2011-10-08T18:04:00.000' + tz],\n        ['2011-281T18:04:20',             '2011-10-08T18:04:20.000' + tz],\n        ['2011-281T18:04' + tz,           '2011-10-08T18:04:00.000' + tz],\n        ['2011-281T18:04:20' + tz,        '2011-10-08T18:04:20.000' + tz],\n        ['2011-281T18:04' + tz2,          '2011-10-08T18:04:00.000' + tz],\n        ['2011-281T18:04:20' + tz2,       '2011-10-08T18:04:20.000' + tz],\n        ['2011-281T18:04' + tz3,          '2011-10-08T18:' + minutesForTz3 + ':00.000' + tz],\n        ['2011-281T18:04:20' + tz3,       '2011-10-08T18:' + minutesForTz3 + ':20.000' + tz],\n        ['2011-281T18:04:20.1' + tz2,     '2011-10-08T18:04:20.100' + tz],\n        ['2011-281T18:04:20.11' + tz2,    '2011-10-08T18:04:20.110' + tz],\n        ['2011-281T18:04:20.111' + tz2,   '2011-10-08T18:04:20.111' + tz],\n        ['2011-281 18',                   '2011-10-08T18:00:00.000' + tz],\n        ['2011-281 18:04',                '2011-10-08T18:04:00.000' + tz],\n        ['2011-281 18:04:20',             '2011-10-08T18:04:20.000' + tz],\n        ['2011-281 18:04' + tz,           '2011-10-08T18:04:00.000' + tz],\n        ['2011-281 18:04:20' + tz,        '2011-10-08T18:04:20.000' + tz],\n        ['2011-281 18:04' + tz2,          '2011-10-08T18:04:00.000' + tz],\n        ['2011-281 18:04:20' + tz2,       '2011-10-08T18:04:20.000' + tz],\n        ['2011-281 18:04' + tz3,          '2011-10-08T18:' + minutesForTz3 + ':00.000' + tz],\n        ['2011-281 18:04:20' + tz3,       '2011-10-08T18:' + minutesForTz3 + ':20.000' + tz],\n        ['2011-281 18:04:20.1' + tz2,     '2011-10-08T18:04:20.100' + tz],\n        ['2011-281 18:04:20.11' + tz2,    '2011-10-08T18:04:20.110' + tz],\n        ['2011-281 18:04:20.111' + tz2,   '2011-10-08T18:04:20.111' + tz],\n        ['20111008T18',                   '2011-10-08T18:00:00.000' + tz],\n        ['20111008T1804',                 '2011-10-08T18:04:00.000' + tz],\n        ['20111008T180420',               '2011-10-08T18:04:20.000' + tz],\n        ['20111008T1804' + tz,            '2011-10-08T18:04:00.000' + tz],\n        ['20111008T180420' + tz,          '2011-10-08T18:04:20.000' + tz],\n        ['20111008T1804' + tz2,           '2011-10-08T18:04:00.000' + tz],\n        ['20111008T180420' + tz2,         '2011-10-08T18:04:20.000' + tz],\n        ['20111008T1804' + tz3,           '2011-10-08T18:' + minutesForTz3 + ':00.000' + tz],\n        ['20111008T180420' + tz3,         '2011-10-08T18:' + minutesForTz3 + ':20.000' + tz],\n        ['20111008T180420,1' + tz2,       '2011-10-08T18:04:20.100' + tz],\n        ['20111008T180420,11' + tz2,      '2011-10-08T18:04:20.110' + tz],\n        ['20111008T180420,111' + tz2,     '2011-10-08T18:04:20.111' + tz],\n        ['20111008 18',                   '2011-10-08T18:00:00.000' + tz],\n        ['20111008 1804',                 '2011-10-08T18:04:00.000' + tz],\n        ['20111008 180420',               '2011-10-08T18:04:20.000' + tz],\n        ['20111008 1804' + tz,            '2011-10-08T18:04:00.000' + tz],\n        ['20111008 180420' + tz,          '2011-10-08T18:04:20.000' + tz],\n        ['20111008 1804' + tz2,           '2011-10-08T18:04:00.000' + tz],\n        ['20111008 180420' + tz2,         '2011-10-08T18:04:20.000' + tz],\n        ['20111008 1804' + tz3,           '2011-10-08T18:' + minutesForTz3 + ':00.000' + tz],\n        ['20111008 180420' + tz3,         '2011-10-08T18:' + minutesForTz3 + ':20.000' + tz],\n        ['20111008 180420,1' + tz2,       '2011-10-08T18:04:20.100' + tz],\n        ['20111008 180420,11' + tz2,      '2011-10-08T18:04:20.110' + tz],\n        ['20111008 180420,111' + tz2,     '2011-10-08T18:04:20.111' + tz],\n        ['2011W40',                       '2011-10-03T00:00:00.000' + tz],\n        ['2011W406',                      '2011-10-08T00:00:00.000' + tz],\n        ['2011W406T18',                   '2011-10-08T18:00:00.000' + tz],\n        ['2011W406T1804',                 '2011-10-08T18:04:00.000' + tz],\n        ['2011W406T180420',               '2011-10-08T18:04:20.000' + tz],\n        ['2011W406 1804' + tz2,           '2011-10-08T18:04:00.000' + tz],\n        ['2011W406T1804' + tz,            '2011-10-08T18:04:00.000' + tz],\n        ['2011W406T180420' + tz,          '2011-10-08T18:04:20.000' + tz],\n        ['2011W406T1804' + tz2,           '2011-10-08T18:04:00.000' + tz],\n        ['2011W406T180420' + tz2,         '2011-10-08T18:04:20.000' + tz],\n        ['2011W406T1804' + tz3,           '2011-10-08T18:' + minutesForTz3 + ':00.000' + tz],\n        ['2011W406T180420' + tz3,         '2011-10-08T18:' + minutesForTz3 + ':20.000' + tz],\n        ['2011W406T180420,1' + tz2,       '2011-10-08T18:04:20.100' + tz],\n        ['2011W406T180420,11' + tz2,      '2011-10-08T18:04:20.110' + tz],\n        ['2011W406T180420,111' + tz2,     '2011-10-08T18:04:20.111' + tz],\n        ['2011W406 18',                   '2011-10-08T18:00:00.000' + tz],\n        ['2011W406 1804',                 '2011-10-08T18:04:00.000' + tz],\n        ['2011W406 180420',               '2011-10-08T18:04:20.000' + tz],\n        ['2011W406 1804' + tz,            '2011-10-08T18:04:00.000' + tz],\n        ['2011W406 180420' + tz,          '2011-10-08T18:04:20.000' + tz],\n        ['2011W406 180420' + tz2,         '2011-10-08T18:04:20.000' + tz],\n        ['2011W406 1804' + tz3,           '2011-10-08T18:' + minutesForTz3 + ':00.000' + tz],\n        ['2011W406 180420' + tz3,         '2011-10-08T18:' + minutesForTz3 + ':20.000' + tz],\n        ['2011W406 180420,1' + tz2,       '2011-10-08T18:04:20.100' + tz],\n        ['2011W406 180420,11' + tz2,      '2011-10-08T18:04:20.110' + tz],\n        ['2011W406 180420,111' + tz2,     '2011-10-08T18:04:20.111' + tz],\n        ['2011281',                       '2011-10-08T00:00:00.000' + tz],\n        ['2011281T18',                    '2011-10-08T18:00:00.000' + tz],\n        ['2011281T1804',                  '2011-10-08T18:04:00.000' + tz],\n        ['2011281T180420',                '2011-10-08T18:04:20.000' + tz],\n        ['2011281T1804' + tz,             '2011-10-08T18:04:00.000' + tz],\n        ['2011281T180420' + tz,           '2011-10-08T18:04:20.000' + tz],\n        ['2011281T1804' + tz2,            '2011-10-08T18:04:00.000' + tz],\n        ['2011281T180420' + tz2,          '2011-10-08T18:04:20.000' + tz],\n        ['2011281T1804' + tz3,            '2011-10-08T18:' + minutesForTz3 + ':00.000' + tz],\n        ['2011281T180420' + tz3,          '2011-10-08T18:' + minutesForTz3 + ':20.000' + tz],\n        ['2011281T180420,1' + tz2,        '2011-10-08T18:04:20.100' + tz],\n        ['2011281T180420,11' + tz2,       '2011-10-08T18:04:20.110' + tz],\n        ['2011281T180420,111' + tz2,      '2011-10-08T18:04:20.111' + tz],\n        ['2011281 18',                    '2011-10-08T18:00:00.000' + tz],\n        ['2011281 1804',                  '2011-10-08T18:04:00.000' + tz],\n        ['2011281 180420',                '2011-10-08T18:04:20.000' + tz],\n        ['2011281 1804' + tz,             '2011-10-08T18:04:00.000' + tz],\n        ['2011281 180420' + tz,           '2011-10-08T18:04:20.000' + tz],\n        ['2011281 1804' + tz2,            '2011-10-08T18:04:00.000' + tz],\n        ['2011281 180420' + tz2,          '2011-10-08T18:04:20.000' + tz],\n        ['2011281 1804' + tz3,            '2011-10-08T18:' + minutesForTz3 + ':00.000' + tz],\n        ['2011281 180420' + tz3,          '2011-10-08T18:' + minutesForTz3 + ':20.000' + tz],\n        ['2011281 180420,1' + tz2,        '2011-10-08T18:04:20.100' + tz],\n        ['2011281 180420,11' + tz2,       '2011-10-08T18:04:20.110' + tz],\n        ['2011281 180420,111' + tz2,      '2011-10-08T18:04:20.111' + tz]\n    ], i;\n    for (i = 0; i < formats.length; i++) {\n        assert.equal(moment(formats[i][0]).format('YYYY-MM-DDTHH:mm:ss.SSSZ'),\n                formats[i][1], 'moment should be able to parse ISO ' + formats[i][0]);\n        assert.equal(moment(formats[i][0], moment.ISO_8601).format('YYYY-MM-DDTHH:mm:ss.SSSZ'),\n                formats[i][1], 'moment should be able to parse specified ISO ' + formats[i][0]);\n        assert.equal(moment(formats[i][0], moment.ISO_8601, true).format('YYYY-MM-DDTHH:mm:ss.SSSZ'),\n                formats[i][1], 'moment should be able to parse specified strict ISO ' + formats[i][0]);\n    }\n});\n\ntest('non iso 8601 strings', function (assert) {\n    assert.ok(!moment('2015-10T10:15', moment.ISO_8601, true).isValid(), 'incomplete date with time');\n    assert.ok(!moment('2015-W10T10:15', moment.ISO_8601, true).isValid(), 'incomplete week date with time');\n    assert.ok(!moment('201510', moment.ISO_8601, true).isValid(), 'basic YYYYMM is not allowed');\n    assert.ok(!moment('2015W10T1015', moment.ISO_8601, true).isValid(), 'incomplete week date with time (basic)');\n    assert.ok(!moment('2015-10-08T1015', moment.ISO_8601, true).isValid(), 'mixing extended and basic format');\n    assert.ok(!moment('20151008T10:15', moment.ISO_8601, true).isValid(), 'mixing basic and extended format');\n    assert.ok(!moment('2015-10-1', moment.ISO_8601, true).isValid(), 'missing zero padding for day');\n});\n\ntest('parsing iso week year/week/weekday', function (assert) {\n    assert.equal(moment.utc('2007-W01').format(), '2007-01-01T00:00:00Z', '2008 week 1 (1st Jan Mon)');\n    assert.equal(moment.utc('2008-W01').format(), '2007-12-31T00:00:00Z', '2008 week 1 (1st Jan Tue)');\n    assert.equal(moment.utc('2003-W01').format(), '2002-12-30T00:00:00Z', '2008 week 1 (1st Jan Wed)');\n    assert.equal(moment.utc('2009-W01').format(), '2008-12-29T00:00:00Z', '2009 week 1 (1st Jan Thu)');\n    assert.equal(moment.utc('2010-W01').format(), '2010-01-04T00:00:00Z', '2010 week 1 (1st Jan Fri)');\n    assert.equal(moment.utc('2011-W01').format(), '2011-01-03T00:00:00Z', '2011 week 1 (1st Jan Sat)');\n    assert.equal(moment.utc('2012-W01').format(), '2012-01-02T00:00:00Z', '2012 week 1 (1st Jan Sun)');\n});\n\ntest('parsing week year/week/weekday (dow 1, doy 4)', function (assert) {\n    moment.locale('dow:1,doy:4', {week: {dow: 1, doy: 4}});\n\n    assert.equal(moment.utc('2007-01', 'gggg-ww').format(), '2007-01-01T00:00:00Z', '2007 week 1 (1st Jan Mon)');\n    assert.equal(moment.utc('2008-01', 'gggg-ww').format(), '2007-12-31T00:00:00Z', '2008 week 1 (1st Jan Tue)');\n    assert.equal(moment.utc('2003-01', 'gggg-ww').format(), '2002-12-30T00:00:00Z', '2003 week 1 (1st Jan Wed)');\n    assert.equal(moment.utc('2009-01', 'gggg-ww').format(), '2008-12-29T00:00:00Z', '2009 week 1 (1st Jan Thu)');\n    assert.equal(moment.utc('2010-01', 'gggg-ww').format(), '2010-01-04T00:00:00Z', '2010 week 1 (1st Jan Fri)');\n    assert.equal(moment.utc('2011-01', 'gggg-ww').format(), '2011-01-03T00:00:00Z', '2011 week 1 (1st Jan Sat)');\n    assert.equal(moment.utc('2012-01', 'gggg-ww').format(), '2012-01-02T00:00:00Z', '2012 week 1 (1st Jan Sun)');\n\n    moment.defineLocale('dow:1,doy:4', null);\n});\n\ntest('parsing week year/week/weekday (dow 1, doy 7)', function (assert) {\n    moment.locale('dow:1,doy:7', {week: {dow: 1, doy: 7}});\n\n    assert.equal(moment.utc('2007-01', 'gggg-ww').format(), '2007-01-01T00:00:00Z', '2007 week 1 (1st Jan Mon)');\n    assert.equal(moment.utc('2008-01', 'gggg-ww').format(), '2007-12-31T00:00:00Z', '2008 week 1 (1st Jan Tue)');\n    assert.equal(moment.utc('2003-01', 'gggg-ww').format(), '2002-12-30T00:00:00Z', '2003 week 1 (1st Jan Wed)');\n    assert.equal(moment.utc('2009-01', 'gggg-ww').format(), '2008-12-29T00:00:00Z', '2009 week 1 (1st Jan Thu)');\n    assert.equal(moment.utc('2010-01', 'gggg-ww').format(), '2009-12-28T00:00:00Z', '2010 week 1 (1st Jan Fri)');\n    assert.equal(moment.utc('2011-01', 'gggg-ww').format(), '2010-12-27T00:00:00Z', '2011 week 1 (1st Jan Sat)');\n    assert.equal(moment.utc('2012-01', 'gggg-ww').format(), '2011-12-26T00:00:00Z', '2012 week 1 (1st Jan Sun)');\n    moment.defineLocale('dow:1,doy:7', null);\n});\n\ntest('parsing week year/week/weekday (dow 0, doy 6)', function (assert) {\n    moment.locale('dow:0,doy:6', {week: {dow: 0, doy: 6}});\n\n    assert.equal(moment.utc('2007-01', 'gggg-ww').format(), '2006-12-31T00:00:00Z', '2007 week 1 (1st Jan Mon)');\n    assert.equal(moment.utc('2008-01', 'gggg-ww').format(), '2007-12-30T00:00:00Z', '2008 week 1 (1st Jan Tue)');\n    assert.equal(moment.utc('2003-01', 'gggg-ww').format(), '2002-12-29T00:00:00Z', '2003 week 1 (1st Jan Wed)');\n    assert.equal(moment.utc('2009-01', 'gggg-ww').format(), '2008-12-28T00:00:00Z', '2009 week 1 (1st Jan Thu)');\n    assert.equal(moment.utc('2010-01', 'gggg-ww').format(), '2009-12-27T00:00:00Z', '2010 week 1 (1st Jan Fri)');\n    assert.equal(moment.utc('2011-01', 'gggg-ww').format(), '2010-12-26T00:00:00Z', '2011 week 1 (1st Jan Sat)');\n    assert.equal(moment.utc('2012-01', 'gggg-ww').format(), '2012-01-01T00:00:00Z', '2012 week 1 (1st Jan Sun)');\n    moment.defineLocale('dow:0,doy:6', null);\n});\n\ntest('parsing week year/week/weekday (dow 6, doy 12)', function (assert) {\n    moment.locale('dow:6,doy:12', {week: {dow: 6, doy: 12}});\n\n    assert.equal(moment.utc('2007-01', 'gggg-ww').format(), '2006-12-30T00:00:00Z', '2007 week 1 (1st Jan Mon)');\n    assert.equal(moment.utc('2008-01', 'gggg-ww').format(), '2007-12-29T00:00:00Z', '2008 week 1 (1st Jan Tue)');\n    assert.equal(moment.utc('2003-01', 'gggg-ww').format(), '2002-12-28T00:00:00Z', '2003 week 1 (1st Jan Wed)');\n    assert.equal(moment.utc('2009-01', 'gggg-ww').format(), '2008-12-27T00:00:00Z', '2009 week 1 (1st Jan Thu)');\n    assert.equal(moment.utc('2010-01', 'gggg-ww').format(), '2009-12-26T00:00:00Z', '2010 week 1 (1st Jan Fri)');\n    assert.equal(moment.utc('2011-01', 'gggg-ww').format(), '2011-01-01T00:00:00Z', '2011 week 1 (1st Jan Sat)');\n    assert.equal(moment.utc('2012-01', 'gggg-ww').format(), '2011-12-31T00:00:00Z', '2012 week 1 (1st Jan Sun)');\n    moment.defineLocale('dow:6,doy:12', null);\n});\n\ntest('parsing ISO with Z', function (assert) {\n    var i, mom, formats = [\n        ['2011-10-08T18:04',             '2011-10-08T18:04:00.000'],\n        ['2011-10-08T18:04:20',          '2011-10-08T18:04:20.000'],\n        ['2011-10-08T18:04:20.1',        '2011-10-08T18:04:20.100'],\n        ['2011-10-08T18:04:20.11',       '2011-10-08T18:04:20.110'],\n        ['2011-10-08T18:04:20.111',      '2011-10-08T18:04:20.111'],\n        ['2011-W40-6T18',                '2011-10-08T18:00:00.000'],\n        ['2011-W40-6T18:04',             '2011-10-08T18:04:00.000'],\n        ['2011-W40-6T18:04:20',          '2011-10-08T18:04:20.000'],\n        ['2011-W40-6T18:04:20.1',        '2011-10-08T18:04:20.100'],\n        ['2011-W40-6T18:04:20.11',       '2011-10-08T18:04:20.110'],\n        ['2011-W40-6T18:04:20.111',      '2011-10-08T18:04:20.111'],\n        ['2011-281T18',                  '2011-10-08T18:00:00.000'],\n        ['2011-281T18:04',               '2011-10-08T18:04:00.000'],\n        ['2011-281T18:04:20',            '2011-10-08T18:04:20.000'],\n        ['2011-281T18:04:20',            '2011-10-08T18:04:20.000'],\n        ['2011-281T18:04:20.1',          '2011-10-08T18:04:20.100'],\n        ['2011-281T18:04:20.11',         '2011-10-08T18:04:20.110'],\n        ['2011-281T18:04:20.111',        '2011-10-08T18:04:20.111']\n    ];\n\n    for (i = 0; i < formats.length; i++) {\n        mom = moment(formats[i][0] + 'Z').utc();\n        assert.equal(mom.format('YYYY-MM-DDTHH:mm:ss.SSS'), formats[i][1], 'moment should be able to parse ISO in UTC ' + formats[i][0] + 'Z');\n\n        mom = moment(formats[i][0] + ' Z').utc();\n        assert.equal(mom.format('YYYY-MM-DDTHH:mm:ss.SSS'), formats[i][1], 'moment should be able to parse ISO in UTC ' + formats[i][0] + ' Z');\n    }\n});\n\ntest('parsing iso with T', function (assert) {\n    assert.equal(moment('2011-10-08T18')._f, 'YYYY-MM-DDTHH', 'should include \\'T\\' in the format');\n    assert.equal(moment('2011-10-08T18:20')._f, 'YYYY-MM-DDTHH:mm', 'should include \\'T\\' in the format');\n    assert.equal(moment('2011-10-08T18:20:13')._f, 'YYYY-MM-DDTHH:mm:ss', 'should include \\'T\\' in the format');\n    assert.equal(moment('2011-10-08T18:20:13.321')._f, 'YYYY-MM-DDTHH:mm:ss.SSSS', 'should include \\'T\\' in the format');\n\n    assert.equal(moment('2011-10-08 18')._f, 'YYYY-MM-DD HH', 'should not include \\'T\\' in the format');\n    assert.equal(moment('2011-10-08 18:20')._f, 'YYYY-MM-DD HH:mm', 'should not include \\'T\\' in the format');\n    assert.equal(moment('2011-10-08 18:20:13')._f, 'YYYY-MM-DD HH:mm:ss', 'should not include \\'T\\' in the format');\n    assert.equal(moment('2011-10-08 18:20:13.321')._f, 'YYYY-MM-DD HH:mm:ss.SSSS', 'should not include \\'T\\' in the format');\n});\n\ntest('parsing iso Z timezone', function (assert) {\n    var i,\n    formats = [\n        ['2011-10-08T18:04Z',             '2011-10-08T18:04:00.000+00:00'],\n        ['2011-10-08T18:04:20Z',          '2011-10-08T18:04:20.000+00:00'],\n        ['2011-10-08T18:04:20.111Z',      '2011-10-08T18:04:20.111+00:00']\n    ];\n    for (i = 0; i < formats.length; i++) {\n        assert.equal(moment.utc(formats[i][0]).format('YYYY-MM-DDTHH:mm:ss.SSSZ'), formats[i][1], 'moment should be able to parse ISO ' + formats[i][0]);\n    }\n});\n\ntest('parsing iso Z timezone into local', function (assert) {\n    var m = moment('2011-10-08T18:04:20.111Z');\n\n    assert.equal(m.utc().format('YYYY-MM-DDTHH:mm:ss.SSS'), '2011-10-08T18:04:20.111', 'moment should be able to parse ISO 2011-10-08T18:04:20.111Z');\n});\n\ntest('parsing iso with more subsecond precision digits', function (assert) {\n    assert.equal(moment.utc('2013-07-31T22:00:00.0000000Z').format(), '2013-07-31T22:00:00Z', 'more than 3 subsecond digits');\n});\n\ntest('null or empty', function (assert) {\n    assert.equal(moment('').isValid(), false, 'moment(\\'\\') is not valid');\n    assert.equal(moment(null).isValid(), false, 'moment(null) is not valid');\n    assert.equal(moment(null, 'YYYY-MM-DD').isValid(), false, 'moment(\\'\\', \\'format\\') is not valid');\n    assert.equal(moment('', 'YYYY-MM-DD').isValid(), false, 'moment(\\'\\', \\'format\\') is not valid');\n    assert.equal(moment.utc('').isValid(), false, 'moment.utc(\\'\\') is not valid');\n    assert.equal(moment.utc(null).isValid(), false, 'moment.utc(null) is not valid');\n    assert.equal(moment.utc(null, 'YYYY-MM-DD').isValid(), false, 'moment.utc(null) is not valid');\n    assert.equal(moment.utc('', 'YYYY-MM-DD').isValid(), false, 'moment.utc(\\'\\', \\'YYYY-MM-DD\\') is not valid');\n});\n\ntest('first century', function (assert) {\n    assert.equal(moment([0, 0, 1]).format('YYYY-MM-DD'), '0000-01-01', 'Year AD 0');\n    assert.equal(moment([99, 0, 1]).format('YYYY-MM-DD'), '0099-01-01', 'Year AD 99');\n    assert.equal(moment([999, 0, 1]).format('YYYY-MM-DD'), '0999-01-01', 'Year AD 999');\n    assert.equal(moment('0 1 1', 'YYYY MM DD').format('YYYY-MM-DD'), '0000-01-01', 'Year AD 0');\n    assert.equal(moment('999 1 1', 'YYYY MM DD').format('YYYY-MM-DD'), '0999-01-01', 'Year AD 999');\n    assert.equal(moment('0 1 1', 'YYYYY MM DD').format('YYYYY-MM-DD'), '00000-01-01', 'Year AD 0');\n    assert.equal(moment('99 1 1', 'YYYYY MM DD').format('YYYYY-MM-DD'), '00099-01-01', 'Year AD 99');\n    assert.equal(moment('999 1 1', 'YYYYY MM DD').format('YYYYY-MM-DD'), '00999-01-01', 'Year AD 999');\n});\n\ntest('six digit years', function (assert) {\n    assert.equal(moment([-270000, 0, 1]).format('YYYYY-MM-DD'), '-270000-01-01', 'format BC 270,001');\n    assert.equal(moment([270000, 0, 1]).format('YYYYY-MM-DD'), '270000-01-01', 'format AD 270,000');\n    assert.equal(moment('-270000-01-01', 'YYYYY-MM-DD').toDate().getFullYear(), -270000, 'parse BC 270,001');\n    assert.equal(moment('270000-01-01',  'YYYYY-MM-DD').toDate().getFullYear(), 270000, 'parse AD 270,000');\n    assert.equal(moment('+270000-01-01', 'YYYYY-MM-DD').toDate().getFullYear(), 270000, 'parse AD +270,000');\n    assert.equal(moment.utc('-270000-01-01', 'YYYYY-MM-DD').toDate().getUTCFullYear(), -270000, 'parse utc BC 270,001');\n    assert.equal(moment.utc('270000-01-01',  'YYYYY-MM-DD').toDate().getUTCFullYear(), 270000, 'parse utc AD 270,000');\n    assert.equal(moment.utc('+270000-01-01', 'YYYYY-MM-DD').toDate().getUTCFullYear(), 270000, 'parse utc AD +270,000');\n});\n\ntest('negative four digit years', function (assert) {\n    assert.equal(moment('-1000-01-01', 'YYYYY-MM-DD').toDate().getFullYear(), -1000, 'parse BC 1,001');\n    assert.equal(moment.utc('-1000-01-01', 'YYYYY-MM-DD').toDate().getUTCFullYear(), -1000, 'parse utc BC 1,001');\n});\n\ntest('strict parsing', function (assert) {\n    assert.equal(moment('2014-', 'YYYY-Q', true).isValid(), false, 'fail missing quarter');\n\n    assert.equal(moment('2012-05', 'YYYY-MM', true).format('YYYY-MM'), '2012-05', 'parse correct string');\n    assert.equal(moment(' 2012-05', 'YYYY-MM', true).isValid(), false, 'fail on extra whitespace');\n    assert.equal(moment('foo 2012-05', '[foo] YYYY-MM', true).format('YYYY-MM'), '2012-05', 'handle fixed text');\n    assert.equal(moment('2012 05', 'YYYY-MM', true).isValid(), false, 'fail on different separator');\n    assert.equal(moment('2012 05', 'YYYY MM DD', true).isValid(), false, 'fail on too many tokens');\n\n    assert.equal(moment('05 30 2010', ['DD MM YYYY', 'MM DD YYYY'], true).format('MM DD YYYY'), '05 30 2010', 'array with bad date');\n    assert.equal(moment('05 30 2010', ['', 'MM DD YYYY'], true).format('MM DD YYYY'), '05 30 2010', 'array with invalid format');\n    assert.equal(moment('05 30 2010', [' DD MM YYYY', 'MM DD YYYY'], true).format('MM DD YYYY'), '05 30 2010', 'array with non-matching format');\n\n    assert.equal(moment('2010.*...', 'YYYY.*', true).isValid(), false, 'invalid format with regex chars');\n    assert.equal(moment('2010.*', 'YYYY.*', true).year(), 2010, 'valid format with regex chars');\n    assert.equal(moment('.*2010.*', '.*YYYY.*', true).year(), 2010, 'valid format with regex chars on both sides');\n\n    //strict tokens\n    assert.equal(moment('-5-05-25', 'YYYY-MM-DD', true).isValid(), false, 'invalid negative year');\n    assert.equal(moment('2-05-25', 'YYYY-MM-DD', true).isValid(), false, 'invalid one-digit year');\n    assert.equal(moment('20-05-25', 'YYYY-MM-DD', true).isValid(), false, 'invalid two-digit year');\n    assert.equal(moment('201-05-25', 'YYYY-MM-DD', true).isValid(), false, 'invalid three-digit year');\n    assert.equal(moment('2010-05-25', 'YYYY-MM-DD', true).isValid(), true, 'valid four-digit year');\n    assert.equal(moment('22010-05-25', 'YYYY-MM-DD', true).isValid(), false, 'invalid five-digit year');\n\n    assert.equal(moment('12-05-25', 'YY-MM-DD', true).isValid(), true, 'valid two-digit year');\n    assert.equal(moment('2012-05-25', 'YY-MM-DD', true).isValid(), false, 'invalid four-digit year');\n\n    assert.equal(moment('-5-05-25', 'Y-MM-DD', true).isValid(), true, 'valid negative year');\n    assert.equal(moment('2-05-25', 'Y-MM-DD', true).isValid(), true, 'valid one-digit year');\n    assert.equal(moment('20-05-25', 'Y-MM-DD', true).isValid(), true, 'valid two-digit year');\n    assert.equal(moment('201-05-25', 'Y-MM-DD', true).isValid(), true, 'valid three-digit year');\n\n    assert.equal(moment('2012-5-25', 'YYYY-M-DD', true).isValid(), true, 'valid one-digit month');\n    assert.equal(moment('2012-5-25', 'YYYY-MM-DD', true).isValid(), false, 'invalid one-digit month');\n    assert.equal(moment('2012-05-25', 'YYYY-M-DD', true).isValid(), true, 'valid one-digit month');\n    assert.equal(moment('2012-05-25', 'YYYY-MM-DD', true).isValid(), true, 'valid one-digit month');\n\n    assert.equal(moment('2012-05-2', 'YYYY-MM-D', true).isValid(), true, 'valid one-digit day');\n    assert.equal(moment('2012-05-2', 'YYYY-MM-DD', true).isValid(), false, 'invalid one-digit day');\n    assert.equal(moment('2012-05-02', 'YYYY-MM-D', true).isValid(), true, 'valid two-digit day');\n    assert.equal(moment('2012-05-02', 'YYYY-MM-DD', true).isValid(), true, 'valid two-digit day');\n\n    assert.equal(moment('+002012-05-25', 'YYYYY-MM-DD', true).isValid(), true, 'valid six-digit year');\n    assert.equal(moment('+2012-05-25', 'YYYYY-MM-DD', true).isValid(), false, 'invalid four-digit year');\n\n    //thse are kinda pointless, but they should work as expected\n    assert.equal(moment('1', 'S', true).isValid(), true, 'valid one-digit milisecond');\n    assert.equal(moment('12', 'S', true).isValid(), false, 'invalid two-digit milisecond');\n    assert.equal(moment('123', 'S', true).isValid(), false, 'invalid three-digit milisecond');\n\n    assert.equal(moment('1', 'SS', true).isValid(), false, 'invalid one-digit milisecond');\n    assert.equal(moment('12', 'SS', true).isValid(), true, 'valid two-digit milisecond');\n    assert.equal(moment('123', 'SS', true).isValid(), false, 'invalid three-digit milisecond');\n\n    assert.equal(moment('1', 'SSS', true).isValid(), false, 'invalid one-digit milisecond');\n    assert.equal(moment('12', 'SSS', true).isValid(), false, 'invalid two-digit milisecond');\n    assert.equal(moment('123', 'SSS', true).isValid(), true, 'valid three-digit milisecond');\n\n    // strict parsing respects month length\n    assert.ok(moment('1 January 2000', 'D MMMM YYYY', true).isValid(), 'capital long-month + MMMM');\n    assert.ok(!moment('1 January 2000', 'D MMM YYYY', true).isValid(), 'capital long-month + MMM');\n    assert.ok(!moment('1 Jan 2000', 'D MMMM YYYY', true).isValid(), 'capital short-month + MMMM');\n    assert.ok(moment('1 Jan 2000', 'D MMM YYYY', true).isValid(), 'capital short-month + MMM');\n    assert.ok(moment('1 january 2000', 'D MMMM YYYY', true).isValid(), 'lower long-month + MMMM');\n    assert.ok(!moment('1 january 2000', 'D MMM YYYY', true).isValid(), 'lower long-month + MMM');\n    assert.ok(!moment('1 jan 2000', 'D MMMM YYYY', true).isValid(), 'lower short-month + MMMM');\n    assert.ok(moment('1 jan 2000', 'D MMM YYYY', true).isValid(), 'lower short-month + MMM');\n});\n\ntest('parsing into a locale', function (assert) {\n    moment.defineLocale('parselocale', {\n        months : 'one_two_three_four_five_six_seven_eight_nine_ten_eleven_twelve'.split('_'),\n        monthsShort : 'one_two_three_four_five_six_seven_eight_nine_ten_eleven_twelve'.split('_')\n    });\n\n    moment.locale('en');\n\n    assert.equal(moment('2012 seven', 'YYYY MMM', 'parselocale').month(), 6, 'should be able to parse in a specific locale');\n\n    moment.locale('parselocale');\n\n    assert.equal(moment('2012 july', 'YYYY MMM', 'en').month(), 6, 'should be able to parse in a specific locale');\n\n    moment.defineLocale('parselocale', null);\n});\n\nfunction getVerifier(test) {\n    return function (input, format, expected, description, asymetrical) {\n        var m = moment(input, format);\n        test.equal(m.format('YYYY MM DD'), expected, 'compare: ' + description);\n\n        //test round trip\n        if (!asymetrical) {\n            test.equal(m.format(format), input, 'round trip: ' + description);\n        }\n    };\n}\n\ntest('parsing week and weekday information', function (assert) {\n    var ver = getVerifier(assert);\n    var currentWeekOfYear = moment().weeks();\n    var expectedDate2012 = moment([2012, 0, 1])\n      .day(0)\n      .add((currentWeekOfYear - 1), 'weeks')\n      .format('YYYY MM DD');\n    var expectedDate1999 = moment([1999, 0, 1])\n      .day(0)\n      .add((currentWeekOfYear - 1), 'weeks')\n      .format('YYYY MM DD');\n\n    // year\n    ver('12', 'gg', expectedDate2012, 'week-year two digits');\n    ver('2012', 'gggg', expectedDate2012, 'week-year four digits');\n    ver('99', 'gg', expectedDate1999, 'week-year two digits previous year');\n    ver('1999', 'gggg', expectedDate1999, 'week-year four digits previous year');\n\n    ver('99', 'GG', '1999 01 04', 'iso week-year two digits');\n    ver('1999', 'GGGG', '1999 01 04', 'iso week-year four digits');\n\n    ver('13', 'GG', '2012 12 31', 'iso week-year two digits previous year');\n    ver('2013', 'GGGG', '2012 12 31', 'iso week-year four digits previous year');\n\n    // year + week\n    ver('1999 37', 'gggg w', '1999 09 05', 'week');\n    ver('1999 37', 'gggg ww', '1999 09 05', 'week double');\n    ver('1999 37', 'GGGG W', '1999 09 13', 'iso week');\n    ver('1999 37', 'GGGG WW', '1999 09 13', 'iso week double');\n\n    ver('1999 37 4', 'GGGG WW E', '1999 09 16', 'iso day');\n    ver('1999 37 04', 'GGGG WW E', '1999 09 16', 'iso day wide', true);\n\n    ver('1999 37 4', 'gggg ww e', '1999 09 09', 'day');\n    ver('1999 37 04', 'gggg ww e', '1999 09 09', 'day wide', true);\n\n    // year + week + day\n    ver('1999 37 4', 'gggg ww d', '1999 09 09', 'd');\n    ver('1999 37 Th', 'gggg ww dd', '1999 09 09', 'dd');\n    ver('1999 37 Thu', 'gggg ww ddd', '1999 09 09', 'ddd');\n    ver('1999 37 Thursday', 'gggg ww dddd', '1999 09 09', 'dddd');\n\n    // lower-order only\n    assert.equal(moment('22', 'ww').week(), 22, 'week sets the week by itself');\n    assert.equal(moment('22', 'ww').weekYear(), moment().weekYear(), 'week keeps this year');\n    assert.equal(moment('2012 22', 'YYYY ww').weekYear(), 2012, 'week keeps parsed year');\n\n    assert.equal(moment('22', 'WW').isoWeek(), 22, 'iso week sets the week by itself');\n    assert.equal(moment('2012 22', 'YYYY WW').weekYear(), 2012, 'iso week keeps parsed year');\n    assert.equal(moment('22', 'WW').isoWeekYear(), moment().isoWeekYear(), 'iso week keeps this year');\n\n    // order\n    ver('6 2013 2', 'e gggg w', '2013 01 12', 'order doesn\\'t matter');\n    ver('6 2013 2', 'E GGGG W', '2013 01 12', 'iso order doesn\\'t matter');\n\n    //can parse other stuff too\n    assert.equal(moment('1999-W37-4 3:30', 'GGGG-[W]WW-E HH:mm').format('YYYY MM DD HH:mm'), '1999 09 16 03:30', 'parsing weeks and hours');\n\n    // In safari, all years before 1300 are shifted back with one day.\n    // http://stackoverflow.com/questions/20768975/safari-subtracts-1-day-from-dates-before-1300\n    if (new Date('1300-01-01').getUTCFullYear() === 1300) {\n        // Years less than 100\n        ver('0098-06', 'GGGG-WW', '0098 02 03', 'small years work', true);\n    }\n});\n\ntest('parsing localized weekdays', function (assert) {\n    var ver = getVerifier(assert);\n    try {\n        moment.locale('dow:1,doy:4', {\n            weekdays : 'dimanche_lundi_mardi_mercredi_jeudi_vendredi_samedi'.split('_'),\n            weekdaysShort : 'dim._lun._mar._mer._jeu._ven._sam.'.split('_'),\n            weekdaysMin : 'Di_Lu_Ma_Me_Je_Ve_Sa'.split('_'),\n            week: {dow: 1, doy: 4}\n        });\n        ver('1999 37 4', 'GGGG WW E', '1999 09 16', 'iso ignores locale');\n        ver('1999 37 7', 'GGGG WW E', '1999 09 19', 'iso ignores locale');\n\n        ver('1999 37 0', 'gggg ww e', '1999 09 13', 'localized e uses local doy and dow: 0 = monday');\n        ver('1999 37 4', 'gggg ww e', '1999 09 17', 'localized e uses local doy and dow: 4 = friday');\n\n        ver('1999 37 1', 'gggg ww d', '1999 09 13', 'localized d uses 0-indexed days: 1 = monday');\n        ver('1999 37 Lu', 'gggg ww dd', '1999 09 13', 'localized d uses 0-indexed days: Mo');\n        ver('1999 37 lun.', 'gggg ww ddd', '1999 09 13', 'localized d uses 0-indexed days: Mon');\n        ver('1999 37 lundi', 'gggg ww dddd', '1999 09 13', 'localized d uses 0-indexed days: Monday');\n        ver('1999 37 4', 'gggg ww d', '1999 09 16', 'localized d uses 0-indexed days: 4');\n\n        //sunday goes at the end of the week\n        ver('1999 37 0', 'gggg ww d', '1999 09 19', 'localized d uses 0-indexed days: 0 = sund');\n        ver('1999 37 Di', 'gggg ww dd', '1999 09 19', 'localized d uses 0-indexed days: 0 = sund');\n    }\n    finally {\n        moment.defineLocale('dow:1,doy:4', null);\n        moment.locale('en');\n    }\n});\n\ntest('parsing with customized two-digit year', function (assert) {\n    var original = moment.parseTwoDigitYear;\n    try {\n        assert.equal(moment('68', 'YY').year(), 2068);\n        assert.equal(moment('69', 'YY').year(), 1969);\n        moment.parseTwoDigitYear = function (input) {\n            return +input + (+input > 30 ? 1900 : 2000);\n        };\n        assert.equal(moment('68', 'YY').year(), 1968);\n        assert.equal(moment('67', 'YY').year(), 1967);\n        assert.equal(moment('31', 'YY').year(), 1931);\n        assert.equal(moment('30', 'YY').year(), 2030);\n    }\n    finally {\n        moment.parseTwoDigitYear = original;\n    }\n});\n\ntest('array with strings', function (assert) {\n    assert.equal(moment(['2014', '7', '31']).isValid(), true, 'string array + isValid');\n});\n\ntest('object with strings', function (assert) {\n    assert.equal(moment({year: '2014', month: '7', day: '31'}).isValid(), true, 'string object + isValid');\n});\n\ntest('utc with array of formats', function (assert) {\n    assert.equal(moment.utc('2014-01-01', ['YYYY-MM-DD', 'YYYY-MM']).format(), '2014-01-01T00:00:00Z', 'moment.utc works with array of formats');\n});\n\ntest('parsing invalid string weekdays', function (assert) {\n    assert.equal(false, moment('a', 'dd').isValid(),\n            'dd with invalid weekday, non-strict');\n    assert.equal(false, moment('a', 'dd', true).isValid(),\n            'dd with invalid weekday, strict');\n    assert.equal(false, moment('a', 'ddd').isValid(),\n            'ddd with invalid weekday, non-strict');\n    assert.equal(false, moment('a', 'ddd', true).isValid(),\n            'ddd with invalid weekday, strict');\n    assert.equal(false, moment('a', 'dddd').isValid(),\n            'dddd with invalid weekday, non-strict');\n    assert.equal(false, moment('a', 'dddd', true).isValid(),\n            'dddd with invalid weekday, strict');\n});\n\ntest('milliseconds', function (assert) {\n    assert.equal(moment('1', 'S').millisecond(), 100);\n    assert.equal(moment('12', 'SS').millisecond(), 120);\n    assert.equal(moment('123', 'SSS').millisecond(), 123);\n    assert.equal(moment('1234', 'SSSS').millisecond(), 123);\n    assert.equal(moment('12345', 'SSSSS').millisecond(), 123);\n    assert.equal(moment('123456', 'SSSSSS').millisecond(), 123);\n    assert.equal(moment('1234567', 'SSSSSSS').millisecond(), 123);\n    assert.equal(moment('12345678', 'SSSSSSSS').millisecond(), 123);\n    assert.equal(moment('123456789', 'SSSSSSSSS').millisecond(), 123);\n});\n\ntest('hmm', function (assert) {\n    assert.equal(moment('123', 'hmm', true).format('HH:mm:ss'), '01:23:00', '123 with hmm');\n    assert.equal(moment('123a', 'hmmA', true).format('HH:mm:ss'), '01:23:00', '123a with hmmA');\n    assert.equal(moment('123p', 'hmmA', true).format('HH:mm:ss'), '13:23:00', '123p with hmmA');\n\n    assert.equal(moment('1234', 'hmm', true).format('HH:mm:ss'), '12:34:00', '1234 with hmm');\n    assert.equal(moment('1234a', 'hmmA', true).format('HH:mm:ss'), '00:34:00', '1234a with hmmA');\n    assert.equal(moment('1234p', 'hmmA', true).format('HH:mm:ss'), '12:34:00', '1234p with hmmA');\n\n    assert.equal(moment('12345', 'hmmss', true).format('HH:mm:ss'), '01:23:45', '12345 with hmmss');\n    assert.equal(moment('12345a', 'hmmssA', true).format('HH:mm:ss'), '01:23:45', '12345a with hmmssA');\n    assert.equal(moment('12345p', 'hmmssA', true).format('HH:mm:ss'), '13:23:45', '12345p with hmmssA');\n    assert.equal(moment('112345', 'hmmss', true).format('HH:mm:ss'), '11:23:45', '112345 with hmmss');\n    assert.equal(moment('112345a', 'hmmssA', true).format('HH:mm:ss'), '11:23:45', '112345a with hmmssA');\n    assert.equal(moment('112345p', 'hmmssA', true).format('HH:mm:ss'), '23:23:45', '112345p with hmmssA');\n\n    assert.equal(moment('023', 'Hmm', true).format('HH:mm:ss'), '00:23:00', '023 with Hmm');\n    assert.equal(moment('123', 'Hmm', true).format('HH:mm:ss'), '01:23:00', '123 with Hmm');\n    assert.equal(moment('1234', 'Hmm', true).format('HH:mm:ss'), '12:34:00', '1234 with Hmm');\n    assert.equal(moment('1534', 'Hmm', true).format('HH:mm:ss'), '15:34:00', '1234 with Hmm');\n    assert.equal(moment('12345', 'Hmmss', true).format('HH:mm:ss'), '01:23:45', '12345 with Hmmss');\n    assert.equal(moment('112345', 'Hmmss', true).format('HH:mm:ss'), '11:23:45', '112345 with Hmmss');\n    assert.equal(moment('172345', 'Hmmss', true).format('HH:mm:ss'), '17:23:45', '112345 with Hmmss');\n});\n\ntest('Y token', function (assert) {\n    assert.equal(moment('1-1-2010', 'M-D-Y', true).year(), 2010, 'parsing Y');\n});\n\ntest('parsing flags retain parsed date parts', function (assert) {\n    var a = moment('10 p', 'hh:mm a');\n    assert.equal(a.parsingFlags().parsedDateParts[3], 10, 'parsed 10 as the hour');\n    assert.equal(a.parsingFlags().parsedDateParts[0], undefined, 'year was not parsed');\n    assert.equal(a.parsingFlags().meridiem, 'p', 'meridiem flag was added');\n    var b = moment('10:30', ['MMDDYY', 'HH:mm']);\n    assert.equal(b.parsingFlags().parsedDateParts[3], 10, 'multiple format parshing matched hour');\n    assert.equal(b.parsingFlags().parsedDateParts[0], undefined, 'array is properly copied, no residual data from first token parse');\n});\n\ntest('parsing only meridiem results in invalid date', function (assert) {\n    assert.ok(!moment('alkj', 'hh:mm a').isValid(), 'because an a token is used, a meridiem will be parsed but nothing else was so invalid');\n    assert.ok(moment('02:30 p more extra stuff', 'hh:mm a').isValid(), 'because other tokens were parsed, date is valid');\n    assert.ok(moment('1/1/2016 extra data', ['a', 'M/D/YYYY']).isValid(), 'took second format, does not pick up on meridiem parsed from first format (good copy)');\n});\n\ntest('invalid dates return invalid for methods that access the _d prop', function (assert) {\n    var momentAsDate = moment(['2015', '12', '1']).toDate();\n    assert.ok(momentAsDate instanceof Date, 'toDate returns a Date object');\n    assert.ok(isNaN(momentAsDate.getTime()), 'toDate returns an invalid Date invalid');\n});\n\ntest('k, kk', function (assert) {\n    for (var i = -1; i <= 24; i++) {\n        var kVal = i + ':15:59';\n        var kkVal = (i < 10 ? '0' : '') + i + ':15:59';\n        if (i !== 24) {\n            assert.ok(moment(kVal, 'k:mm:ss').isSame(moment(kVal, 'H:mm:ss')), kVal + ' k parsing');\n            assert.ok(moment(kkVal, 'kk:mm:ss').isSame(moment(kkVal, 'HH:mm:ss')), kkVal + ' kk parsing');\n        } else {\n            assert.equal(moment(kVal, 'k:mm:ss').format('k:mm:ss'), kVal, kVal + ' k parsing');\n            assert.equal(moment(kkVal, 'kk:mm:ss').format('kk:mm:ss'), kkVal, kkVal + ' skk parsing');\n        }\n    }\n});\n\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/test/moment/creation-data.js",
    "content": "import { module, test } from '../qunit';\nimport moment from '../../moment';\n\nmodule('creation data');\n\ntest('valid date', function (assert) {\n    var dat = moment('1992-10-22');\n    var orig = dat.creationData();\n\n    assert.equal(dat.isValid(), true, '1992-10-22 is valid');\n    assert.equal(orig.input, '1992-10-22', 'original input is not correct.');\n    assert.equal(orig.format, 'YYYY-MM-DD', 'original format is defined.');\n    assert.equal(orig.locale._abbr, 'en', 'default locale is en');\n    assert.equal(orig.isUTC, false, 'not a UTC date');\n});\n\ntest('valid date at fr locale', function (assert) {\n    var dat = moment('1992-10-22', 'YYYY-MM-DD', 'fr');\n    var orig = dat.creationData();\n\n    assert.equal(orig.locale._abbr, 'fr', 'locale is fr');\n});\n\ntest('valid date with formats', function (assert) {\n    var dat = moment('29-06-1995', ['MM-DD-YYYY', 'DD-MM', 'DD-MM-YYYY']);\n    var orig = dat.creationData();\n\n    assert.equal(orig.format, 'DD-MM-YYYY', 'DD-MM-YYYY format is defined.');\n});\n\ntest('strict', function (assert) {\n    assert.ok(moment('2015-01-02', 'YYYY-MM-DD', true).creationData().strict, 'strict is true');\n    assert.ok(!moment('2015-01-02', 'YYYY-MM-DD').creationData().strict, 'strict is true');\n});\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/test/moment/days_in_month.js",
    "content": "import { module, test } from '../qunit';\nimport moment from '../../moment';\nimport each from '../helpers/each';\n\nmodule('days in month');\n\ntest('days in month', function (assert) {\n    each([31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31], function (days, i) {\n        var firstDay = moment([2012, i]),\n            lastDay  = moment([2012, i, days]);\n        assert.equal(firstDay.daysInMonth(), days, firstDay.format('L') + ' should have ' + days + ' days.');\n        assert.equal(lastDay.daysInMonth(), days, lastDay.format('L') + ' should have ' + days + ' days.');\n    });\n});\n\ntest('days in month leap years', function (assert) {\n    assert.equal(moment([2010, 1]).daysInMonth(), 28, 'Feb 2010 should have 28 days');\n    assert.equal(moment([2100, 1]).daysInMonth(), 28, 'Feb 2100 should have 28 days');\n    assert.equal(moment([2008, 1]).daysInMonth(), 29, 'Feb 2008 should have 29 days');\n    assert.equal(moment([2000, 1]).daysInMonth(), 29, 'Feb 2000 should have 29 days');\n});\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/test/moment/days_in_year.js",
    "content": "import { module, test } from '../qunit';\nimport moment from '../../moment';\n\nmodule('days in year');\n\n// https://github.com/moment/moment/issues/3717\ntest('YYYYDDD should not parse DDD=000', function (assert) {\n    assert.equal(moment(7000000, moment.ISO_8601, true).isValid(), false);\n    assert.equal(moment('7000000', moment.ISO_8601, true).isValid(), false);\n    assert.equal(moment(7000000, moment.ISO_8601, false).isValid(), false);\n});\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/test/moment/deprecate.js",
    "content": "import { module, test, expect } from '../qunit';\nimport { deprecate } from '../../lib/utils/deprecate';\nimport moment from '../../moment';\n\nmodule('deprecate');\n\ntest('deprecate', function (assert) {\n    // NOTE: hooks inside deprecate.js and moment are different, so this is can\n    // not be test.expectedDeprecations(...)\n    var fn = function () {};\n    var deprecatedFn = deprecate('testing deprecation', fn);\n    deprecatedFn();\n\n    expect(0);\n});\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/test/moment/diff.js",
    "content": "import { module, test } from '../qunit';\nimport moment from '../../moment';\n\nfunction equal(assert, a, b, message) {\n    assert.ok(Math.abs(a - b) < 0.00000001, '(' + a + ' === ' + b + ') ' + message);\n}\n\nfunction dstForYear(year) {\n    var start = moment([year]),\n        end = moment([year + 1]),\n        current = start.clone(),\n        last;\n\n    while (current < end) {\n        last = current.clone();\n        current.add(24, 'hour');\n        if (last.utcOffset() !== current.utcOffset()) {\n            end = current.clone();\n            current = last.clone();\n            break;\n        }\n    }\n\n    while (current < end) {\n        last = current.clone();\n        current.add(1, 'hour');\n        if (last.utcOffset() !== current.utcOffset()) {\n            return {\n                moment : last,\n                diff : -(current.utcOffset() - last.utcOffset()) / 60\n            };\n        }\n    }\n}\n\nmodule('diff');\n\ntest('diff', function (assert) {\n    assert.equal(moment(1000).diff(0), 1000, '1 second - 0 = 1000');\n    assert.equal(moment(1000).diff(500), 500, '1 second - 0.5 seconds = 500');\n    assert.equal(moment(0).diff(1000), -1000, '0 - 1 second = -1000');\n    assert.equal(moment(new Date(1000)).diff(1000), 0, '1 second - 1 second = 0');\n    var oneHourDate = new Date(2015, 5, 21),\n    nowDate = new Date(+oneHourDate);\n    oneHourDate.setHours(oneHourDate.getHours() + 1);\n    assert.equal(moment(oneHourDate).diff(nowDate), 60 * 60 * 1000, '1 hour from now = 3600000');\n});\n\ntest('diff key after', function (assert) {\n    assert.equal(moment([2010]).diff([2011], 'years'), -1, 'year diff');\n    assert.equal(moment([2010]).diff([2010, 2], 'months'), -2, 'month diff');\n    assert.equal(moment([2010]).diff([2010, 0, 7], 'weeks'), 0, 'week diff');\n    assert.equal(moment([2010]).diff([2010, 0, 8], 'weeks'), -1, 'week diff');\n    assert.equal(moment([2010]).diff([2010, 0, 21], 'weeks'), -2, 'week diff');\n    assert.equal(moment([2010]).diff([2010, 0, 22], 'weeks'), -3, 'week diff');\n    assert.equal(moment([2010]).diff([2010, 0, 4], 'days'), -3, 'day diff');\n    assert.equal(moment([2010]).diff([2010, 0, 1, 4], 'hours'), -4, 'hour diff');\n    assert.equal(moment([2010]).diff([2010, 0, 1, 0, 5], 'minutes'), -5, 'minute diff');\n    assert.equal(moment([2010]).diff([2010, 0, 1, 0, 0, 6], 'seconds'), -6, 'second diff');\n});\n\ntest('diff key before', function (assert) {\n    assert.equal(moment([2011]).diff([2010], 'years'), 1, 'year diff');\n    assert.equal(moment([2010, 2]).diff([2010], 'months'), 2, 'month diff');\n    assert.equal(moment([2010, 0, 4]).diff([2010], 'days'), 3, 'day diff');\n    assert.equal(moment([2010, 0, 7]).diff([2010], 'weeks'), 0, 'week diff');\n    assert.equal(moment([2010, 0, 8]).diff([2010], 'weeks'), 1, 'week diff');\n    assert.equal(moment([2010, 0, 21]).diff([2010], 'weeks'), 2, 'week diff');\n    assert.equal(moment([2010, 0, 22]).diff([2010], 'weeks'), 3, 'week diff');\n    assert.equal(moment([2010, 0, 1, 4]).diff([2010], 'hours'), 4, 'hour diff');\n    assert.equal(moment([2010, 0, 1, 0, 5]).diff([2010], 'minutes'), 5, 'minute diff');\n    assert.equal(moment([2010, 0, 1, 0, 0, 6]).diff([2010], 'seconds'), 6, 'second diff');\n});\n\ntest('diff key before singular', function (assert) {\n    assert.equal(moment([2011]).diff([2010], 'year'), 1, 'year diff singular');\n    assert.equal(moment([2010, 2]).diff([2010], 'month'), 2, 'month diff singular');\n    assert.equal(moment([2010, 0, 4]).diff([2010], 'day'), 3, 'day diff singular');\n    assert.equal(moment([2010, 0, 7]).diff([2010], 'week'), 0, 'week diff singular');\n    assert.equal(moment([2010, 0, 8]).diff([2010], 'week'), 1, 'week diff singular');\n    assert.equal(moment([2010, 0, 21]).diff([2010], 'week'), 2, 'week diff singular');\n    assert.equal(moment([2010, 0, 22]).diff([2010], 'week'), 3, 'week diff singular');\n    assert.equal(moment([2010, 0, 1, 4]).diff([2010], 'hour'), 4, 'hour diff singular');\n    assert.equal(moment([2010, 0, 1, 0, 5]).diff([2010], 'minute'), 5, 'minute diff singular');\n    assert.equal(moment([2010, 0, 1, 0, 0, 6]).diff([2010], 'second'), 6, 'second diff singular');\n});\n\ntest('diff key before abbreviated', function (assert) {\n    assert.equal(moment([2011]).diff([2010], 'y'), 1, 'year diff abbreviated');\n    assert.equal(moment([2010, 2]).diff([2010], 'M'), 2, 'month diff abbreviated');\n    assert.equal(moment([2010, 0, 4]).diff([2010], 'd'), 3, 'day diff abbreviated');\n    assert.equal(moment([2010, 0, 7]).diff([2010], 'w'), 0, 'week diff abbreviated');\n    assert.equal(moment([2010, 0, 8]).diff([2010], 'w'), 1, 'week diff abbreviated');\n    assert.equal(moment([2010, 0, 21]).diff([2010], 'w'), 2, 'week diff abbreviated');\n    assert.equal(moment([2010, 0, 22]).diff([2010], 'w'), 3, 'week diff abbreviated');\n    assert.equal(moment([2010, 0, 1, 4]).diff([2010], 'h'), 4, 'hour diff abbreviated');\n    assert.equal(moment([2010, 0, 1, 0, 5]).diff([2010], 'm'), 5, 'minute diff abbreviated');\n    assert.equal(moment([2010, 0, 1, 0, 0, 6]).diff([2010], 's'), 6, 'second diff abbreviated');\n});\n\ntest('diff month', function (assert) {\n    assert.equal(moment([2011, 0, 31]).diff([2011, 2, 1], 'months'), -1, 'month diff');\n});\n\ntest('diff across DST', function (assert) {\n    var dst = dstForYear(2012), a, b, daysInMonth;\n    if (!dst) {\n        assert.equal(42, 42, 'at least one assertion');\n        return;\n    }\n\n    a = dst.moment;\n    b = a.clone().utc().add(12, 'hours').local();\n    daysInMonth = (a.daysInMonth() + b.daysInMonth()) / 2;\n    assert.equal(b.diff(a, 'milliseconds', true), 12 * 60 * 60 * 1000,\n            'ms diff across DST');\n    assert.equal(b.diff(a, 'seconds', true), 12 * 60 * 60,\n            'second diff across DST');\n    assert.equal(b.diff(a, 'minutes', true), 12 * 60,\n            'minute diff across DST');\n    assert.equal(b.diff(a, 'hours', true), 12,\n            'hour diff across DST');\n    assert.equal(b.diff(a, 'days', true), (12 - dst.diff) / 24,\n            'day diff across DST');\n    equal(assert, b.diff(a, 'weeks', true),  (12 - dst.diff) / 24 / 7,\n            'week diff across DST');\n    assert.ok(0.95 / (2 * 31) < b.diff(a, 'months', true),\n            'month diff across DST, lower bound');\n    assert.ok(b.diff(a, 'month', true) < 1.05 / (2 * 28),\n            'month diff across DST, upper bound');\n    assert.ok(0.95 / (2 * 31 * 12) < b.diff(a, 'years', true),\n            'year diff across DST, lower bound');\n    assert.ok(b.diff(a, 'year', true) < 1.05 / (2 * 28 * 12),\n            'year diff across DST, upper bound');\n\n    a = dst.moment;\n    b = a.clone().utc().add(12 + dst.diff, 'hours').local();\n    daysInMonth = (a.daysInMonth() + b.daysInMonth()) / 2;\n\n    assert.equal(b.diff(a, 'milliseconds', true),\n            (12 + dst.diff) * 60 * 60 * 1000,\n            'ms diff across DST');\n    assert.equal(b.diff(a, 'seconds', true),  (12 + dst.diff) * 60 * 60,\n            'second diff across DST');\n    assert.equal(b.diff(a, 'minutes', true),  (12 + dst.diff) * 60,\n            'minute diff across DST');\n    assert.equal(b.diff(a, 'hours', true),  (12 + dst.diff),\n            'hour diff across DST');\n    assert.equal(b.diff(a, 'days', true),  12 / 24, 'day diff across DST');\n    equal(assert, b.diff(a, 'weeks', true),  12 / 24 / 7,\n            'week diff across DST');\n    assert.ok(0.95 / (2 * 31) < b.diff(a, 'months', true),\n            'month diff across DST, lower bound');\n    assert.ok(b.diff(a, 'month', true) < 1.05 / (2 * 28),\n            'month diff across DST, upper bound');\n    assert.ok(0.95 / (2 * 31 * 12) < b.diff(a, 'years', true),\n            'year diff across DST, lower bound');\n    assert.ok(b.diff(a, 'year', true) < 1.05 / (2 * 28 * 12),\n            'year diff across DST, upper bound');\n});\n\ntest('diff overflow', function (assert) {\n    assert.equal(moment([2011]).diff([2010], 'months'), 12, 'month diff');\n    assert.equal(moment([2010, 0, 2]).diff([2010], 'hours'), 24, 'hour diff');\n    assert.equal(moment([2010, 0, 1, 2]).diff([2010], 'minutes'), 120, 'minute diff');\n    assert.equal(moment([2010, 0, 1, 0, 4]).diff([2010], 'seconds'), 240, 'second diff');\n});\n\ntest('diff between utc and local', function (assert) {\n    if (moment([2012]).utcOffset() === moment([2011]).utcOffset()) {\n        // Russia's utc offset on 1st of Jan 2012 vs 2011 is different\n        assert.equal(moment([2012]).utc().diff([2011], 'years'), 1, 'year diff');\n    }\n    assert.equal(moment([2010, 2, 2]).utc().diff([2010, 0, 2], 'months'), 2, 'month diff');\n    assert.equal(moment([2010, 0, 4]).utc().diff([2010], 'days'), 3, 'day diff');\n    assert.equal(moment([2010, 0, 22]).utc().diff([2010], 'weeks'), 3, 'week diff');\n    assert.equal(moment([2010, 0, 1, 4]).utc().diff([2010], 'hours'), 4, 'hour diff');\n    assert.equal(moment([2010, 0, 1, 0, 5]).utc().diff([2010], 'minutes'), 5, 'minute diff');\n    assert.equal(moment([2010, 0, 1, 0, 0, 6]).utc().diff([2010], 'seconds'), 6, 'second diff');\n});\n\ntest('diff floored', function (assert) {\n    assert.equal(moment([2010, 0, 1, 23]).diff([2010], 'day'), 0, '23 hours = 0 days');\n    assert.equal(moment([2010, 0, 1, 23, 59]).diff([2010], 'day'), 0, '23:59 hours = 0 days');\n    assert.equal(moment([2010, 0, 1, 24]).diff([2010], 'day'), 1, '24 hours = 1 day');\n    assert.equal(moment([2010, 0, 2]).diff([2011, 0, 1], 'year'), 0, 'year rounded down');\n    assert.equal(moment([2011, 0, 1]).diff([2010, 0, 2], 'year'), 0, 'year rounded down');\n    assert.equal(moment([2010, 0, 2]).diff([2011, 0, 2], 'year'), -1, 'year rounded down');\n    assert.equal(moment([2011, 0, 2]).diff([2010, 0, 2], 'year'), 1, 'year rounded down');\n});\n\ntest('year diffs include dates', function (assert) {\n    assert.ok(moment([2012, 1, 19]).diff(moment([2002, 1, 20]), 'years', true) < 10, 'year diff should include date of month');\n});\n\ntest('month diffs', function (assert) {\n    // due to floating point math errors, these tests just need to be accurate within 0.00000001\n    assert.equal(moment([2012, 0, 1]).diff([2012, 1, 1], 'months', true), -1, 'Jan 1 to Feb 1 should be 1 month');\n    equal(assert, moment([2012, 0, 1]).diff([2012, 0, 1, 12], 'months', true), -0.5 / 31, 'Jan 1 to Jan 1 noon should be 0.5 / 31 months');\n    assert.equal(moment([2012, 0, 15]).diff([2012, 1, 15], 'months', true), -1, 'Jan 15 to Feb 15 should be 1 month');\n    assert.equal(moment([2012, 0, 28]).diff([2012, 1, 28], 'months', true), -1, 'Jan 28 to Feb 28 should be 1 month');\n    assert.ok(moment([2012, 0, 31]).diff([2012, 1, 29], 'months', true), -1, 'Jan 31 to Feb 29 should be 1 month');\n    assert.ok(-1 > moment([2012, 0, 31]).diff([2012, 2, 1], 'months', true), 'Jan 31 to Mar 1 should be more than 1 month');\n    assert.ok(-30 / 28 < moment([2012, 0, 31]).diff([2012, 2, 1], 'months', true), 'Jan 31 to Mar 1 should be less than 1 month and 1 day');\n    equal(assert, moment([2012, 0, 1]).diff([2012, 0, 31], 'months', true), -(30 / 31), 'Jan 1 to Jan 31 should be 30 / 31 months');\n    assert.ok(0 < moment('2014-02-01').diff(moment('2014-01-31'), 'months', true), 'jan-31 to feb-1 diff is positive');\n});\n\ntest('exact month diffs', function (assert) {\n    // generate all pairs of months and compute month diff, with fixed day\n    // of month = 15.\n\n    var m1, m2;\n    for (m1 = 0; m1 < 12; ++m1) {\n        for (m2 = m1; m2 < 12; ++m2) {\n            assert.equal(moment([2013, m2, 15]).diff(moment([2013, m1, 15]), 'months', true), m2 - m1,\n                         'month diff from 2013-' + m1 + '-15 to 2013-' + m2 + '-15');\n        }\n    }\n});\n\ntest('year diffs', function (assert) {\n    // due to floating point math errors, these tests just need to be accurate within 0.00000001\n    equal(assert, moment([2012, 0, 1]).diff([2013, 0, 1], 'years', true), -1, 'Jan 1 2012 to Jan 1 2013 should be 1 year');\n    equal(assert, moment([2012, 1, 28]).diff([2013, 1, 28], 'years', true), -1, 'Feb 28 2012 to Feb 28 2013 should be 1 year');\n    equal(assert, moment([2012, 2, 1]).diff([2013, 2, 1], 'years', true), -1, 'Mar 1 2012 to Mar 1 2013 should be 1 year');\n    equal(assert, moment([2012, 11, 1]).diff([2013, 11, 1], 'years', true), -1, 'Dec 1 2012 to Dec 1 2013 should be 1 year');\n    equal(assert, moment([2012, 11, 31]).diff([2013, 11, 31], 'years', true), -1, 'Dec 31 2012 to Dec 31 2013 should be 1 year');\n    equal(assert, moment([2012, 0, 1]).diff([2013, 6, 1], 'years', true), -1.5, 'Jan 1 2012 to Jul 1 2013 should be 1.5 years');\n    equal(assert, moment([2012, 0, 31]).diff([2013, 6, 31], 'years', true), -1.5, 'Jan 31 2012 to Jul 31 2013 should be 1.5 years');\n    equal(assert, moment([2012, 0, 1]).diff([2013, 0, 1, 12], 'years', true), -1 - (0.5 / 31) / 12, 'Jan 1 2012 to Jan 1 2013 noon should be 1+(0.5 / 31) / 12 years');\n    equal(assert, moment([2012, 0, 1]).diff([2013, 6, 1, 12], 'years', true), -1.5 - (0.5 / 31) / 12, 'Jan 1 2012 to Jul 1 2013 noon should be 1.5+(0.5 / 31) / 12 years');\n    equal(assert, moment([2012, 1, 29]).diff([2013, 1, 28], 'years', true), -1, 'Feb 29 2012 to Feb 28 2013 should be 1-(1 / 28.5) / 12 years');\n});\n\ntest('negative zero', function (assert) {\n    function isNegative (n) {\n        return (1 / n) < 0;\n    }\n    assert.ok(!isNegative(moment([2012, 0, 1]).diff(moment([2012, 0, 1]), 'months')), 'month diff on same date is zero, not -0');\n    assert.ok(!isNegative(moment([2012, 0, 1]).diff(moment([2012, 0, 1]), 'years')), 'year diff on same date is zero, not -0');\n    assert.ok(!isNegative(moment([2012, 0, 1]).diff(moment([2012, 0, 1]), 'quarters')), 'quarter diff on same date is zero, not -0');\n    assert.ok(!isNegative(moment([2012, 0, 1]).diff(moment([2012, 0, 1, 1]), 'days')), 'days diff on same date is zero, not -0');\n    assert.ok(!isNegative(moment([2012, 0, 1]).diff(moment([2012, 0, 1, 0, 1]), 'hours')), 'hour diff on same hour is zero, not -0');\n    assert.ok(!isNegative(moment([2012, 0, 1]).diff(moment([2012, 0, 1, 0, 0, 1]), 'minutes')), 'minute diff on same minute is zero, not -0');\n    assert.ok(!isNegative(moment([2012, 0, 1]).diff(moment([2012, 0, 1, 0, 0, 0, 1]), 'seconds')), 'second diff on same second is zero, not -0');\n});\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/test/moment/duration.js",
    "content": "import { module, test } from '../qunit';\nimport moment from '../../moment';\n\nmodule('duration');\n\ntest('object instantiation', function (assert) {\n    var d = moment.duration({\n        years: 2,\n        months: 3,\n        weeks: 2,\n        days: 1,\n        hours: 8,\n        minutes: 9,\n        seconds: 20,\n        milliseconds: 12\n    });\n\n    assert.equal(d.years(),        2,  'years');\n    assert.equal(d.months(),       3,  'months');\n    assert.equal(d.weeks(),        2,  'weeks');\n    assert.equal(d.days(),         15, 'days'); // two weeks + 1 day\n    assert.equal(d.hours(),        8,  'hours');\n    assert.equal(d.minutes(),      9,  'minutes');\n    assert.equal(d.seconds(),      20, 'seconds');\n    assert.equal(d.milliseconds(), 12, 'milliseconds');\n});\n\ntest('object instantiation with strings', function (assert) {\n    var d = moment.duration({\n        years: '2',\n        months: '3',\n        weeks: '2',\n        days: '1',\n        hours: '8',\n        minutes: '9',\n        seconds: '20',\n        milliseconds: '12'\n    });\n\n    assert.equal(d.years(),        2,  'years');\n    assert.equal(d.months(),       3,  'months');\n    assert.equal(d.weeks(),        2,  'weeks');\n    assert.equal(d.days(),         15, 'days'); // two weeks + 1 day\n    assert.equal(d.hours(),        8,  'hours');\n    assert.equal(d.minutes(),      9,  'minutes');\n    assert.equal(d.seconds(),      20, 'seconds');\n    assert.equal(d.milliseconds(), 12, 'milliseconds');\n});\n\ntest('milliseconds instantiation', function (assert) {\n    assert.equal(moment.duration(72).milliseconds(), 72, 'milliseconds');\n    assert.equal(moment.duration(72).humanize(), 'a few seconds', 'Duration should be valid');\n});\n\ntest('undefined instantiation', function (assert) {\n    assert.equal(moment.duration(undefined).milliseconds(), 0, 'milliseconds');\n    assert.equal(moment.duration(undefined).isValid(), true, '_isValid');\n    assert.equal(moment.duration(undefined).humanize(), 'a few seconds', 'Duration should be valid');\n});\n\ntest('null instantiation', function (assert) {\n    assert.equal(moment.duration(null).milliseconds(), 0, 'milliseconds');\n    assert.equal(moment.duration(null).isValid(), true, '_isValid');\n    assert.equal(moment.duration(null).humanize(), 'a few seconds', 'Duration should be valid');\n});\n\ntest('NaN instantiation', function (assert) {\n    assert.ok(isNaN(moment.duration(NaN).milliseconds()), 'milliseconds should be NaN');\n    assert.equal(moment.duration(NaN).isValid(), false, '_isValid');\n    assert.equal(moment.duration(NaN).humanize(), 'Invalid date', 'Duration should be invalid');\n});\n\ntest('instantiation by type', function (assert) {\n    assert.equal(moment.duration(1, 'years').years(),                 1, 'years');\n    assert.equal(moment.duration(1, 'y').years(),                     1, 'y');\n    assert.equal(moment.duration(2, 'months').months(),               2, 'months');\n    assert.equal(moment.duration(2, 'M').months(),                    2, 'M');\n    assert.equal(moment.duration(3, 'weeks').weeks(),                 3, 'weeks');\n    assert.equal(moment.duration(3, 'w').weeks(),                     3, 'weeks');\n    assert.equal(moment.duration(4, 'days').days(),                   4, 'days');\n    assert.equal(moment.duration(4, 'd').days(),                      4, 'd');\n    assert.equal(moment.duration(5, 'hours').hours(),                 5, 'hours');\n    assert.equal(moment.duration(5, 'h').hours(),                     5, 'h');\n    assert.equal(moment.duration(6, 'minutes').minutes(),             6, 'minutes');\n    assert.equal(moment.duration(6, 'm').minutes(),                   6, 'm');\n    assert.equal(moment.duration(7, 'seconds').seconds(),             7, 'seconds');\n    assert.equal(moment.duration(7, 's').seconds(),                   7, 's');\n    assert.equal(moment.duration(8, 'milliseconds').milliseconds(),   8, 'milliseconds');\n    assert.equal(moment.duration(8, 'ms').milliseconds(),             8, 'ms');\n});\n\ntest('shortcuts', function (assert) {\n    assert.equal(moment.duration({y: 1}).years(),         1, 'years = y');\n    assert.equal(moment.duration({M: 2}).months(),        2, 'months = M');\n    assert.equal(moment.duration({w: 3}).weeks(),         3, 'weeks = w');\n    assert.equal(moment.duration({d: 4}).days(),          4, 'days = d');\n    assert.equal(moment.duration({h: 5}).hours(),         5, 'hours = h');\n    assert.equal(moment.duration({m: 6}).minutes(),       6, 'minutes = m');\n    assert.equal(moment.duration({s: 7}).seconds(),       7, 'seconds = s');\n    assert.equal(moment.duration({ms: 8}).milliseconds(), 8, 'milliseconds = ms');\n});\n\ntest('generic getter', function (assert) {\n    assert.equal(moment.duration(1, 'years').get('years'),                1, 'years');\n    assert.equal(moment.duration(1, 'years').get('year'),                 1, 'years = year');\n    assert.equal(moment.duration(1, 'years').get('y'),                    1, 'years = y');\n    assert.equal(moment.duration(2, 'months').get('months'),              2, 'months');\n    assert.equal(moment.duration(2, 'months').get('month'),               2, 'months = month');\n    assert.equal(moment.duration(2, 'months').get('M'),                   2, 'months = M');\n    assert.equal(moment.duration(3, 'weeks').get('weeks'),                3, 'weeks');\n    assert.equal(moment.duration(3, 'weeks').get('week'),                 3, 'weeks = week');\n    assert.equal(moment.duration(3, 'weeks').get('w'),                    3, 'weeks = w');\n    assert.equal(moment.duration(4, 'days').get('days'),                  4, 'days');\n    assert.equal(moment.duration(4, 'days').get('day'),                   4, 'days = day');\n    assert.equal(moment.duration(4, 'days').get('d'),                     4, 'days = d');\n    assert.equal(moment.duration(5, 'hours').get('hours'),                5, 'hours');\n    assert.equal(moment.duration(5, 'hours').get('hour'),                 5, 'hours = hour');\n    assert.equal(moment.duration(5, 'hours').get('h'),                    5, 'hours = h');\n    assert.equal(moment.duration(6, 'minutes').get('minutes'),            6, 'minutes');\n    assert.equal(moment.duration(6, 'minutes').get('minute'),             6, 'minutes = minute');\n    assert.equal(moment.duration(6, 'minutes').get('m'),                  6, 'minutes = m');\n    assert.equal(moment.duration(7, 'seconds').get('seconds'),            7, 'seconds');\n    assert.equal(moment.duration(7, 'seconds').get('second'),             7, 'seconds = second');\n    assert.equal(moment.duration(7, 'seconds').get('s'),                  7, 'seconds = s');\n    assert.equal(moment.duration(8, 'milliseconds').get('milliseconds'),  8, 'milliseconds');\n    assert.equal(moment.duration(8, 'milliseconds').get('millisecond'),   8, 'milliseconds = millisecond');\n    assert.equal(moment.duration(8, 'milliseconds').get('ms'),            8, 'milliseconds = ms');\n});\n\ntest('instantiation from another duration', function (assert) {\n    var simple = moment.duration(1234),\n        lengthy = moment.duration(60 * 60 * 24 * 360 * 1e3),\n        complicated = moment.duration({\n            years: 2,\n            months: 3,\n            weeks: 4,\n            days: 1,\n            hours: 8,\n            minutes: 9,\n            seconds: 20,\n            milliseconds: 12\n        }),\n        modified = moment.duration(1, 'day').add(moment.duration(1, 'day'));\n\n    assert.deepEqual(moment.duration(simple), simple, 'simple clones are equal');\n    assert.deepEqual(moment.duration(lengthy), lengthy, 'lengthy clones are equal');\n    assert.deepEqual(moment.duration(complicated), complicated, 'complicated clones are equal');\n    assert.deepEqual(moment.duration(modified), modified, 'cloning modified duration works');\n});\n\ntest('instantiation from 24-hour time zero', function (assert) {\n    assert.equal(moment.duration('00:00').years(), 0, '0 years');\n    assert.equal(moment.duration('00:00').days(), 0, '0 days');\n    assert.equal(moment.duration('00:00').hours(), 0, '0 hours');\n    assert.equal(moment.duration('00:00').minutes(), 0, '0 minutes');\n    assert.equal(moment.duration('00:00').seconds(), 0, '0 seconds');\n    assert.equal(moment.duration('00:00').milliseconds(), 0, '0 milliseconds');\n});\n\ntest('instantiation from 24-hour time <24 hours', function (assert) {\n    assert.equal(moment.duration('06:45').years(), 0, '0 years');\n    assert.equal(moment.duration('06:45').days(), 0, '0 days');\n    assert.equal(moment.duration('06:45').hours(), 6, '6 hours');\n    assert.equal(moment.duration('06:45').minutes(), 45, '45 minutes');\n    assert.equal(moment.duration('06:45').seconds(), 0, '0 seconds');\n    assert.equal(moment.duration('06:45').milliseconds(), 0, '0 milliseconds');\n});\n\ntest('instantiation from 24-hour time >24 hours', function (assert) {\n    assert.equal(moment.duration('26:45').years(), 0, '0 years');\n    assert.equal(moment.duration('26:45').days(), 1, '0 days');\n    assert.equal(moment.duration('26:45').hours(), 2, '2 hours');\n    assert.equal(moment.duration('26:45').minutes(), 45, '45 minutes');\n    assert.equal(moment.duration('26:45').seconds(), 0, '0 seconds');\n    assert.equal(moment.duration('26:45').milliseconds(), 0, '0 milliseconds');\n});\n\ntest('instatiation from serialized C# TimeSpan zero', function (assert) {\n    assert.equal(moment.duration('00:00:00').years(), 0, '0 years');\n    assert.equal(moment.duration('00:00:00').days(), 0, '0 days');\n    assert.equal(moment.duration('00:00:00').hours(), 0, '0 hours');\n    assert.equal(moment.duration('00:00:00').minutes(), 0, '0 minutes');\n    assert.equal(moment.duration('00:00:00').seconds(), 0, '0 seconds');\n    assert.equal(moment.duration('00:00:00').milliseconds(), 0, '0 milliseconds');\n});\n\ntest('instatiation from serialized C# TimeSpan with days', function (assert) {\n    assert.equal(moment.duration('1.02:03:04.9999999').years(), 0, '0 years');\n    assert.equal(moment.duration('1.02:03:04.9999999').days(), 1, '1 day');\n    assert.equal(moment.duration('1.02:03:04.9999999').hours(), 2, '2 hours');\n    assert.equal(moment.duration('1.02:03:04.9999999').minutes(), 3, '3 minutes');\n    assert.equal(moment.duration('1.02:03:04.9999999').seconds(), 5, '5 seconds');\n    assert.equal(moment.duration('1.02:03:04.9999999').milliseconds(), 0, '0 milliseconds');\n\n    assert.equal(moment.duration('1 02:03:04.9999999').years(), 0, '0 years');\n    assert.equal(moment.duration('1 02:03:04.9999999').days(), 1, '1 day');\n    assert.equal(moment.duration('1 02:03:04.9999999').hours(), 2, '2 hours');\n    assert.equal(moment.duration('1 02:03:04.9999999').minutes(), 3, '3 minutes');\n    assert.equal(moment.duration('1 02:03:04.9999999').seconds(), 5, '5 seconds');\n    assert.equal(moment.duration('1 02:03:04.9999999').milliseconds(), 0, '0 milliseconds');\n});\n\ntest('instatiation from serialized C# TimeSpan without days', function (assert) {\n    assert.equal(moment.duration('01:02:03.9999999').years(), 0, '0 years');\n    assert.equal(moment.duration('01:02:03.9999999').days(), 0, '0 days');\n    assert.equal(moment.duration('01:02:03.9999999').hours(), 1, '1 hour');\n    assert.equal(moment.duration('01:02:03.9999999').minutes(), 2, '2 minutes');\n    assert.equal(moment.duration('01:02:03.9999999').seconds(), 4, '4 seconds');\n    assert.equal(moment.duration('01:02:03.9999999').milliseconds(), 0, '0 milliseconds');\n\n    assert.equal(moment.duration('23:59:59.9999999').days(), 1, '1 days');\n    assert.equal(moment.duration('23:59:59.9999999').hours(), 0, '0 hours');\n    assert.equal(moment.duration('23:59:59.9999999').minutes(), 0, '0 minutes');\n    assert.equal(moment.duration('23:59:59.9999999').seconds(), 0, '0 seconds');\n    assert.equal(moment.duration('23:59:59.9999999').milliseconds(), 0, '0 milliseconds');\n\n    assert.equal(moment.duration('500:59:59.8888888').days(), 20, '500 hours overflows to 20 days');\n    assert.equal(moment.duration('500:59:59.8888888').hours(), 20, '500 hours overflows to 20 hours');\n});\n\ntest('instatiation from serialized C# TimeSpan without days or milliseconds', function (assert) {\n    assert.equal(moment.duration('01:02:03').years(), 0, '0 years');\n    assert.equal(moment.duration('01:02:03').days(), 0, '0 days');\n    assert.equal(moment.duration('01:02:03').hours(), 1, '1 hour');\n    assert.equal(moment.duration('01:02:03').minutes(), 2, '2 minutes');\n    assert.equal(moment.duration('01:02:03').seconds(), 3, '3 seconds');\n    assert.equal(moment.duration('01:02:03').milliseconds(), 0, '0 milliseconds');\n});\n\ntest('instatiation from serialized C# TimeSpan without milliseconds', function (assert) {\n    assert.equal(moment.duration('1.02:03:04').years(), 0, '0 years');\n    assert.equal(moment.duration('1.02:03:04').days(), 1, '1 day');\n    assert.equal(moment.duration('1.02:03:04').hours(), 2, '2 hours');\n    assert.equal(moment.duration('1.02:03:04').minutes(), 3, '3 minutes');\n    assert.equal(moment.duration('1.02:03:04').seconds(), 4, '4 seconds');\n    assert.equal(moment.duration('1.02:03:04').milliseconds(), 0, '0 milliseconds');\n});\n\ntest('instantiation from serialized C# TimeSpan with low millisecond precision', function (assert) {\n    assert.equal(moment.duration('00:00:15.72').years(), 0, '0 years');\n    assert.equal(moment.duration('00:00:15.72').days(), 0, '0 days');\n    assert.equal(moment.duration('00:00:15.72').hours(), 0, '0 hours');\n    assert.equal(moment.duration('00:00:15.72').minutes(), 0, '0 minutes');\n    assert.equal(moment.duration('00:00:15.72').seconds(), 15, '15 seconds');\n    assert.equal(moment.duration('00:00:15.72').milliseconds(), 720, '720 milliseconds');\n\n    assert.equal(moment.duration('00:00:15.7').milliseconds(), 700, '700 milliseconds');\n\n    assert.equal(moment.duration('00:00:15.').milliseconds(), 0, '0 milliseconds');\n});\n\ntest('instantiation from serialized C# TimeSpan with high millisecond precision', function (assert) {\n    assert.equal(moment.duration('00:00:15.7200000').seconds(), 15, '15 seconds');\n    assert.equal(moment.duration('00:00:15.7200000').milliseconds(), 720, '720 milliseconds');\n\n    assert.equal(moment.duration('00:00:15.7209999').seconds(), 15, '15 seconds');\n    assert.equal(moment.duration('00:00:15.7209999').milliseconds(), 721, '721 milliseconds');\n\n    assert.equal(moment.duration('00:00:15.7205000').seconds(), 15, '15 seconds');\n    assert.equal(moment.duration('00:00:15.7205000').milliseconds(), 721, '721 milliseconds');\n\n    assert.equal(moment.duration('-00:00:15.7205000').seconds(), -15, '15 seconds');\n    assert.equal(moment.duration('-00:00:15.7205000').milliseconds(), -721, '721 milliseconds');\n});\n\ntest('instatiation from serialized C# TimeSpan maxValue', function (assert) {\n    var d = moment.duration('10675199.02:48:05.4775807');\n\n    assert.equal(d.years(), 29227, '29227 years');\n    assert.equal(d.months(), 8, '8 months');\n    assert.equal(d.days(), 12, '12 day');  // if you have to change this value -- just do it\n\n    assert.equal(d.hours(), 2, '2 hours');\n    assert.equal(d.minutes(), 48, '48 minutes');\n    assert.equal(d.seconds(), 5, '5 seconds');\n    assert.equal(d.milliseconds(), 478, '478 milliseconds');\n});\n\ntest('instatiation from serialized C# TimeSpan minValue', function (assert) {\n    var d = moment.duration('-10675199.02:48:05.4775808');\n\n    assert.equal(d.years(), -29227, '29653 years');\n    assert.equal(d.months(), -8, '8 day');\n    assert.equal(d.days(), -12, '12 day');  // if you have to change this value -- just do it\n\n    assert.equal(d.hours(), -2, '2 hours');\n    assert.equal(d.minutes(), -48, '48 minutes');\n    assert.equal(d.seconds(), -5, '5 seconds');\n    assert.equal(d.milliseconds(), -478, '478 milliseconds');\n});\n\ntest('instantiation from ISO 8601 duration', function (assert) {\n    assert.equal(moment.duration('P1Y2M3DT4H5M6S').asSeconds(), moment.duration({y: 1, M: 2, d: 3, h: 4, m: 5, s: 6}).asSeconds(), 'all fields');\n    assert.equal(moment.duration('P3W3D').asSeconds(), moment.duration({w: 3, d: 3}).asSeconds(), 'week and day fields');\n    assert.equal(moment.duration('P1M').asSeconds(), moment.duration({M: 1}).asSeconds(), 'single month field');\n    assert.equal(moment.duration('PT1M').asSeconds(), moment.duration({m: 1}).asSeconds(), 'single minute field');\n    assert.equal(moment.duration('P1MT2H').asSeconds(), moment.duration({M: 1, h: 2}).asSeconds(), 'random fields missing');\n    assert.equal(moment.duration('-P60D').asSeconds(), moment.duration({d: -60}).asSeconds(), 'negative days');\n    assert.equal(moment.duration('PT0.5S').asSeconds(), moment.duration({s: 0.5}).asSeconds(), 'fractional seconds');\n    assert.equal(moment.duration('PT0,5S').asSeconds(), moment.duration({s: 0.5}).asSeconds(), 'fractional seconds (comma)');\n});\n\ntest('serialization to ISO 8601 duration strings', function (assert) {\n    assert.equal(moment.duration({y: 1, M: 2, d: 3, h: 4, m: 5, s: 6}).toISOString(), 'P1Y2M3DT4H5M6S', 'all fields');\n    assert.equal(moment.duration({M: -1}).toISOString(), '-P1M', 'one month ago');\n    assert.equal(moment.duration({m: -1}).toISOString(), '-PT1M', 'one minute ago');\n    assert.equal(moment.duration({s: -0.5}).toISOString(), '-PT0.5S', 'one half second ago');\n    assert.equal(moment.duration({y: -1, M: 1}).toISOString(), '-P11M', 'a month after a year ago');\n    assert.equal(moment.duration({}).toISOString(), 'P0D', 'zero duration');\n    assert.equal(moment.duration({M: 16, d:40, s: 86465}).toISOString(), 'P1Y4M40DT24H1M5S', 'all fields');\n});\n\ntest('toString acts as toISOString', function (assert) {\n    assert.equal(moment.duration({y: 1, M: 2, d: 3, h: 4, m: 5, s: 6}).toString(), 'P1Y2M3DT4H5M6S', 'all fields');\n    assert.equal(moment.duration({M: -1}).toString(), '-P1M', 'one month ago');\n    assert.equal(moment.duration({m: -1}).toString(), '-PT1M', 'one minute ago');\n    assert.equal(moment.duration({s: -0.5}).toString(), '-PT0.5S', 'one half second ago');\n    assert.equal(moment.duration({y: -1, M: 1}).toString(), '-P11M', 'a month after a year ago');\n    assert.equal(moment.duration({}).toString(), 'P0D', 'zero duration');\n    assert.equal(moment.duration({M: 16, d:40, s: 86465}).toString(), 'P1Y4M40DT24H1M5S', 'all fields');\n});\n\ntest('toIsoString deprecation', function (assert) {\n    test.expectedDeprecations('toIsoString()');\n\n    assert.equal(moment.duration({}).toIsoString(), moment.duration({}).toISOString(), 'toIsoString delegates to toISOString');\n});\n\ntest('`isodate` (python) test cases', function (assert) {\n    assert.equal(moment.duration('P18Y9M4DT11H9M8S').asSeconds(), moment.duration({y: 18, M: 9, d: 4, h: 11, m: 9, s: 8}).asSeconds(), 'python isodate 1');\n    assert.equal(moment.duration('P2W').asSeconds(), moment.duration({w: 2}).asSeconds(), 'python isodate 2');\n    assert.equal(moment.duration('P3Y6M4DT12H30M5S').asSeconds(), moment.duration({y: 3, M: 6, d: 4, h: 12, m: 30, s: 5}).asSeconds(), 'python isodate 3');\n    assert.equal(moment.duration('P23DT23H').asSeconds(), moment.duration({d: 23, h: 23}).asSeconds(), 'python isodate 4');\n    assert.equal(moment.duration('P4Y').asSeconds(), moment.duration({y: 4}).asSeconds(), 'python isodate 5');\n    assert.equal(moment.duration('P1M').asSeconds(), moment.duration({M: 1}).asSeconds(), 'python isodate 6');\n    assert.equal(moment.duration('PT1M').asSeconds(), moment.duration({m: 1}).asSeconds(), 'python isodate 7');\n    assert.equal(moment.duration('P0.5Y').asSeconds(), moment.duration({y: 0.5}).asSeconds(), 'python isodate 8');\n    assert.equal(moment.duration('PT36H').asSeconds(), moment.duration({h: 36}).asSeconds(), 'python isodate 9');\n    assert.equal(moment.duration('P1DT12H').asSeconds(), moment.duration({d: 1, h: 12}).asSeconds(), 'python isodate 10');\n    assert.equal(moment.duration('-P2W').asSeconds(), moment.duration({w: -2}).asSeconds(), 'python isodate 11');\n    assert.equal(moment.duration('-P2.2W').asSeconds(), moment.duration({w: -2.2}).asSeconds(), 'python isodate 12');\n    assert.equal(moment.duration('P1DT2H3M4S').asSeconds(), moment.duration({d: 1, h: 2, m: 3, s: 4}).asSeconds(), 'python isodate 13');\n    assert.equal(moment.duration('P1DT2H3M').asSeconds(), moment.duration({d: 1, h: 2, m: 3}).asSeconds(), 'python isodate 14');\n    assert.equal(moment.duration('P1DT2H').asSeconds(), moment.duration({d: 1, h: 2}).asSeconds(), 'python isodate 15');\n    assert.equal(moment.duration('PT2H').asSeconds(), moment.duration({h: 2}).asSeconds(), 'python isodate 16');\n    assert.equal(moment.duration('PT2.3H').asSeconds(), moment.duration({h: 2.3}).asSeconds(), 'python isodate 17');\n    assert.equal(moment.duration('PT2H3M4S').asSeconds(), moment.duration({h: 2, m: 3, s: 4}).asSeconds(), 'python isodate 18');\n    assert.equal(moment.duration('PT3M4S').asSeconds(), moment.duration({m: 3, s: 4}).asSeconds(), 'python isodate 19');\n    assert.equal(moment.duration('PT22S').asSeconds(), moment.duration({s: 22}).asSeconds(), 'python isodate 20');\n    assert.equal(moment.duration('PT22.22S').asSeconds(), moment.duration({s: 22.22}).asSeconds(), 'python isodate 21');\n    assert.equal(moment.duration('-P2Y').asSeconds(), moment.duration({y: -2}).asSeconds(), 'python isodate 22');\n    assert.equal(moment.duration('-P3Y6M4DT12H30M5S').asSeconds(), moment.duration({y: -3, M: -6, d: -4, h: -12, m: -30, s: -5}).asSeconds(), 'python isodate 23');\n    assert.equal(moment.duration('-P1DT2H3M4S').asSeconds(), moment.duration({d: -1, h: -2, m: -3, s: -4}).asSeconds(), 'python isodate 24');\n    assert.equal(moment.duration('PT-6H3M').asSeconds(), moment.duration({h: -6, m: 3}).asSeconds(), 'python isodate 25');\n    assert.equal(moment.duration('-PT-6H3M').asSeconds(), moment.duration({h: 6, m: -3}).asSeconds(), 'python isodate 26');\n    assert.equal(moment.duration('-P-3Y-6M-4DT-12H-30M-5S').asSeconds(), moment.duration({y: 3, M: 6, d: 4, h: 12, m: 30, s: 5}).asSeconds(), 'python isodate 27');\n    assert.equal(moment.duration('P-3Y-6M-4DT-12H-30M-5S').asSeconds(), moment.duration({y: -3, M: -6, d: -4, h: -12, m: -30, s: -5}).asSeconds(), 'python isodate 28');\n    assert.equal(moment.duration('-P-2W').asSeconds(), moment.duration({w: 2}).asSeconds(), 'python isodate 29');\n    assert.equal(moment.duration('P-2W').asSeconds(), moment.duration({w: -2}).asSeconds(), 'python isodate 30');\n});\n\ntest('ISO 8601 misuse cases', function (assert) {\n    assert.equal(moment.duration('P').asSeconds(), 0, 'lonely P');\n    assert.equal(moment.duration('PT').asSeconds(), 0, 'just P and T');\n    assert.equal(moment.duration('P1H').asSeconds(), 0, 'missing T');\n    assert.equal(moment.duration('P1D1Y').asSeconds(), 0, 'out of order');\n    assert.equal(moment.duration('PT.5S').asSeconds(), 0.5, 'accept no leading zero for decimal');\n    assert.equal(moment.duration('PT1,S').asSeconds(), 1, 'accept trailing decimal separator');\n    assert.equal(moment.duration('PT1M0,,5S').asSeconds(), 60, 'extra decimal separators are ignored as 0');\n});\n\ntest('humanize', function (assert) {\n    moment.locale('en');\n    assert.equal(moment.duration({seconds: 44}).humanize(),  'a few seconds', '44 seconds = a few seconds');\n    assert.equal(moment.duration({seconds: 45}).humanize(),  'a minute',      '45 seconds = a minute');\n    assert.equal(moment.duration({seconds: 89}).humanize(),  'a minute',      '89 seconds = a minute');\n    assert.equal(moment.duration({seconds: 90}).humanize(),  '2 minutes',     '90 seconds = 2 minutes');\n    assert.equal(moment.duration({minutes: 44}).humanize(),  '44 minutes',    '44 minutes = 44 minutes');\n    assert.equal(moment.duration({minutes: 45}).humanize(),  'an hour',       '45 minutes = an hour');\n    assert.equal(moment.duration({minutes: 89}).humanize(),  'an hour',       '89 minutes = an hour');\n    assert.equal(moment.duration({minutes: 90}).humanize(),  '2 hours',       '90 minutes = 2 hours');\n    assert.equal(moment.duration({hours: 5}).humanize(),     '5 hours',       '5 hours = 5 hours');\n    assert.equal(moment.duration({hours: 21}).humanize(),    '21 hours',      '21 hours = 21 hours');\n    assert.equal(moment.duration({hours: 22}).humanize(),    'a day',         '22 hours = a day');\n    assert.equal(moment.duration({hours: 35}).humanize(),    'a day',         '35 hours = a day');\n    assert.equal(moment.duration({hours: 36}).humanize(),    '2 days',        '36 hours = 2 days');\n    assert.equal(moment.duration({days: 1}).humanize(),      'a day',         '1 day = a day');\n    assert.equal(moment.duration({days: 5}).humanize(),      '5 days',        '5 days = 5 days');\n    assert.equal(moment.duration({weeks: 1}).humanize(),     '7 days',        '1 week = 7 days');\n    assert.equal(moment.duration({days: 25}).humanize(),     '25 days',       '25 days = 25 days');\n    assert.equal(moment.duration({days: 26}).humanize(),     'a month',       '26 days = a month');\n    assert.equal(moment.duration({days: 30}).humanize(),     'a month',       '30 days = a month');\n    assert.equal(moment.duration({days: 45}).humanize(),     'a month',       '45 days = a month');\n    assert.equal(moment.duration({days: 46}).humanize(),     '2 months',      '46 days = 2 months');\n    assert.equal(moment.duration({days: 74}).humanize(),     '2 months',      '74 days = 2 months');\n    assert.equal(moment.duration({days: 77}).humanize(),     '3 months',      '77 days = 3 months');\n    assert.equal(moment.duration({months: 1}).humanize(),    'a month',       '1 month = a month');\n    assert.equal(moment.duration({months: 5}).humanize(),    '5 months',      '5 months = 5 months');\n    assert.equal(moment.duration({days: 344}).humanize(),    'a year',        '344 days = a year');\n    assert.equal(moment.duration({days: 345}).humanize(),    'a year',        '345 days = a year');\n    assert.equal(moment.duration({days: 547}).humanize(),    'a year',        '547 days = a year');\n    assert.equal(moment.duration({days: 548}).humanize(),    '2 years',       '548 days = 2 years');\n    assert.equal(moment.duration({years: 1}).humanize(),     'a year',        '1 year = a year');\n    assert.equal(moment.duration({years: 5}).humanize(),     '5 years',       '5 years = 5 years');\n    assert.equal(moment.duration(7200000).humanize(),        '2 hours',       '7200000 = 2 minutes');\n});\n\ntest('humanize duration with suffix', function (assert) {\n    moment.locale('en');\n    assert.equal(moment.duration({seconds:  44}).humanize(true),  'in a few seconds', '44 seconds = a few seconds');\n    assert.equal(moment.duration({seconds: -44}).humanize(true),  'a few seconds ago', '44 seconds = a few seconds');\n});\n\ntest('bubble value up', function (assert) {\n    assert.equal(moment.duration({milliseconds: 61001}).milliseconds(), 1, '61001 milliseconds has 1 millisecond left over');\n    assert.equal(moment.duration({milliseconds: 61001}).seconds(),      1, '61001 milliseconds has 1 second left over');\n    assert.equal(moment.duration({milliseconds: 61001}).minutes(),      1, '61001 milliseconds has 1 minute left over');\n\n    assert.equal(moment.duration({minutes: 350}).minutes(), 50, '350 minutes has 50 minutes left over');\n    assert.equal(moment.duration({minutes: 350}).hours(),   5,  '350 minutes has 5 hours left over');\n});\n\ntest('clipping', function (assert) {\n    assert.equal(moment.duration({months: 11}).months(), 11, '11 months is 11 months');\n    assert.equal(moment.duration({months: 11}).years(),  0,  '11 months makes no year');\n    assert.equal(moment.duration({months: 12}).months(), 0,  '12 months is 0 months left over');\n    assert.equal(moment.duration({months: 12}).years(),  1,  '12 months makes 1 year');\n    assert.equal(moment.duration({months: 13}).months(), 1,  '13 months is 1 month left over');\n    assert.equal(moment.duration({months: 13}).years(),  1,  '13 months makes 1 year');\n\n    assert.equal(moment.duration({days: 30}).days(),   30, '30 days is 30 days');\n    assert.equal(moment.duration({days: 30}).months(), 0,  '30 days makes no month');\n    assert.equal(moment.duration({days: 31}).days(),   0,  '31 days is 0 days left over');\n    assert.equal(moment.duration({days: 31}).months(), 1,  '31 days is a month');\n    assert.equal(moment.duration({days: 32}).days(),   1,  '32 days is 1 day left over');\n    assert.equal(moment.duration({days: 32}).months(), 1,  '32 days is a month');\n\n    assert.equal(moment.duration({hours: 23}).hours(), 23, '23 hours is 23 hours');\n    assert.equal(moment.duration({hours: 23}).days(),  0,  '23 hours makes no day');\n    assert.equal(moment.duration({hours: 24}).hours(), 0,  '24 hours is 0 hours left over');\n    assert.equal(moment.duration({hours: 24}).days(),  1,  '24 hours makes 1 day');\n    assert.equal(moment.duration({hours: 25}).hours(), 1,  '25 hours is 1 hour left over');\n    assert.equal(moment.duration({hours: 25}).days(),  1,  '25 hours makes 1 day');\n});\n\ntest('bubbling consistency', function (assert) {\n    var days = 0, months = 0, newDays, newMonths, totalDays, d;\n    for (totalDays = 1; totalDays <= 500; ++totalDays) {\n        d = moment.duration(totalDays, 'days');\n        newDays = d.days();\n        newMonths = d.months() + d.years() * 12;\n        assert.ok(\n                (months === newMonths && days + 1 === newDays) ||\n                (months + 1 === newMonths && newDays === 0),\n                'consistent total days ' + totalDays +\n                ' was ' + months + ' ' + days +\n                ' now ' + newMonths + ' ' + newDays);\n        days = newDays;\n        months = newMonths;\n    }\n});\n\ntest('effective equivalency', function (assert) {\n    assert.deepEqual(moment.duration({seconds: 1})._data,  moment.duration({milliseconds: 1000})._data, '1 second is the same as 1000 milliseconds');\n    assert.deepEqual(moment.duration({seconds: 60})._data, moment.duration({minutes: 1})._data,         '1 minute is the same as 60 seconds');\n    assert.deepEqual(moment.duration({minutes: 60})._data, moment.duration({hours: 1})._data,           '1 hour is the same as 60 minutes');\n    assert.deepEqual(moment.duration({hours: 24})._data,   moment.duration({days: 1})._data,            '1 day is the same as 24 hours');\n    assert.deepEqual(moment.duration({days: 7})._data,     moment.duration({weeks: 1})._data,           '1 week is the same as 7 days');\n    assert.deepEqual(moment.duration({days: 31})._data,    moment.duration({months: 1})._data,          '1 month is the same as 30 days');\n    assert.deepEqual(moment.duration({months: 12})._data,  moment.duration({years: 1})._data,           '1 years is the same as 12 months');\n});\n\ntest('asGetters', function (assert) {\n    // 400 years have exactly 146097 days\n\n    // years\n    assert.equal(moment.duration(1, 'year').asYears(),            1,           '1 year as years');\n    assert.equal(moment.duration(1, 'year').asMonths(),           12,          '1 year as months');\n    assert.equal(moment.duration(400, 'year').asMonths(),         4800,        '400 years as months');\n    assert.equal(moment.duration(1, 'year').asWeeks().toFixed(3), 52.143,      '1 year as weeks');\n    assert.equal(moment.duration(1, 'year').asDays(),             365,         '1 year as days');\n    assert.equal(moment.duration(2, 'year').asDays(),             730,         '2 years as days');\n    assert.equal(moment.duration(3, 'year').asDays(),             1096,        '3 years as days');\n    assert.equal(moment.duration(4, 'year').asDays(),             1461,        '4 years as days');\n    assert.equal(moment.duration(400, 'year').asDays(),           146097,      '400 years as days');\n    assert.equal(moment.duration(1, 'year').asHours(),            8760,        '1 year as hours');\n    assert.equal(moment.duration(1, 'year').asMinutes(),          525600,      '1 year as minutes');\n    assert.equal(moment.duration(1, 'year').asSeconds(),          31536000,    '1 year as seconds');\n    assert.equal(moment.duration(1, 'year').asMilliseconds(),     31536000000, '1 year as milliseconds');\n\n    // months\n    assert.equal(moment.duration(1, 'month').asYears().toFixed(4), 0.0833,     '1 month as years');\n    assert.equal(moment.duration(1, 'month').asMonths(),           1,          '1 month as months');\n    assert.equal(moment.duration(1, 'month').asWeeks().toFixed(3), 4.286,      '1 month as weeks');\n    assert.equal(moment.duration(1, 'month').asDays(),             30,         '1 month as days');\n    assert.equal(moment.duration(2, 'month').asDays(),             61,         '2 months as days');\n    assert.equal(moment.duration(3, 'month').asDays(),             91,         '3 months as days');\n    assert.equal(moment.duration(4, 'month').asDays(),             122,        '4 months as days');\n    assert.equal(moment.duration(5, 'month').asDays(),             152,        '5 months as days');\n    assert.equal(moment.duration(6, 'month').asDays(),             183,        '6 months as days');\n    assert.equal(moment.duration(7, 'month').asDays(),             213,        '7 months as days');\n    assert.equal(moment.duration(8, 'month').asDays(),             243,        '8 months as days');\n    assert.equal(moment.duration(9, 'month').asDays(),             274,        '9 months as days');\n    assert.equal(moment.duration(10, 'month').asDays(),            304,        '10 months as days');\n    assert.equal(moment.duration(11, 'month').asDays(),            335,        '11 months as days');\n    assert.equal(moment.duration(12, 'month').asDays(),            365,        '12 months as days');\n    assert.equal(moment.duration(24, 'month').asDays(),            730,        '24 months as days');\n    assert.equal(moment.duration(36, 'month').asDays(),            1096,       '36 months as days');\n    assert.equal(moment.duration(48, 'month').asDays(),            1461,       '48 months as days');\n    assert.equal(moment.duration(4800, 'month').asDays(),          146097,     '4800 months as days');\n    assert.equal(moment.duration(1, 'month').asHours(),            720,        '1 month as hours');\n    assert.equal(moment.duration(1, 'month').asMinutes(),          43200,      '1 month as minutes');\n    assert.equal(moment.duration(1, 'month').asSeconds(),          2592000,    '1 month as seconds');\n    assert.equal(moment.duration(1, 'month').asMilliseconds(),     2592000000, '1 month as milliseconds');\n\n    // weeks\n    assert.equal(moment.duration(1, 'week').asYears().toFixed(4),  0.0192,    '1 week as years');\n    assert.equal(moment.duration(1, 'week').asMonths().toFixed(3), 0.230,     '1 week as months');\n    assert.equal(moment.duration(1, 'week').asWeeks(),             1,         '1 week as weeks');\n    assert.equal(moment.duration(1, 'week').asDays(),              7,         '1 week as days');\n    assert.equal(moment.duration(1, 'week').asHours(),             168,       '1 week as hours');\n    assert.equal(moment.duration(1, 'week').asMinutes(),           10080,     '1 week as minutes');\n    assert.equal(moment.duration(1, 'week').asSeconds(),           604800,    '1 week as seconds');\n    assert.equal(moment.duration(1, 'week').asMilliseconds(),      604800000, '1 week as milliseconds');\n\n    // days\n    assert.equal(moment.duration(1, 'day').asYears().toFixed(4),  0.0027,   '1 day as years');\n    assert.equal(moment.duration(1, 'day').asMonths().toFixed(3), 0.033,    '1 day as months');\n    assert.equal(moment.duration(1, 'day').asWeeks().toFixed(3),  0.143,    '1 day as weeks');\n    assert.equal(moment.duration(1, 'day').asDays(),              1,        '1 day as days');\n    assert.equal(moment.duration(1, 'day').asHours(),             24,       '1 day as hours');\n    assert.equal(moment.duration(1, 'day').asMinutes(),           1440,     '1 day as minutes');\n    assert.equal(moment.duration(1, 'day').asSeconds(),           86400,    '1 day as seconds');\n    assert.equal(moment.duration(1, 'day').asMilliseconds(),      86400000, '1 day as milliseconds');\n\n    // hours\n    assert.equal(moment.duration(1, 'hour').asYears().toFixed(6),  0.000114, '1 hour as years');\n    assert.equal(moment.duration(1, 'hour').asMonths().toFixed(5), 0.00137,  '1 hour as months');\n    assert.equal(moment.duration(1, 'hour').asWeeks().toFixed(5),  0.00595,  '1 hour as weeks');\n    assert.equal(moment.duration(1, 'hour').asDays().toFixed(4),   0.0417,   '1 hour as days');\n    assert.equal(moment.duration(1, 'hour').asHours(),             1,        '1 hour as hours');\n    assert.equal(moment.duration(1, 'hour').asMinutes(),           60,       '1 hour as minutes');\n    assert.equal(moment.duration(1, 'hour').asSeconds(),           3600,     '1 hour as seconds');\n    assert.equal(moment.duration(1, 'hour').asMilliseconds(),      3600000,  '1 hour as milliseconds');\n\n    // minutes\n    assert.equal(moment.duration(1, 'minute').asYears().toFixed(8),  0.00000190, '1 minute as years');\n    assert.equal(moment.duration(1, 'minute').asMonths().toFixed(7), 0.0000228,  '1 minute as months');\n    assert.equal(moment.duration(1, 'minute').asWeeks().toFixed(7),  0.0000992,  '1 minute as weeks');\n    assert.equal(moment.duration(1, 'minute').asDays().toFixed(6),   0.000694,   '1 minute as days');\n    assert.equal(moment.duration(1, 'minute').asHours().toFixed(4),  0.0167,     '1 minute as hours');\n    assert.equal(moment.duration(1, 'minute').asMinutes(),           1,          '1 minute as minutes');\n    assert.equal(moment.duration(1, 'minute').asSeconds(),           60,         '1 minute as seconds');\n    assert.equal(moment.duration(1, 'minute').asMilliseconds(),      60000,      '1 minute as milliseconds');\n\n    // seconds\n    assert.equal(moment.duration(1, 'second').asYears().toFixed(10),  0.0000000317, '1 second as years');\n    assert.equal(moment.duration(1, 'second').asMonths().toFixed(9),  0.000000380,  '1 second as months');\n    assert.equal(moment.duration(1, 'second').asWeeks().toFixed(8),   0.00000165,   '1 second as weeks');\n    assert.equal(moment.duration(1, 'second').asDays().toFixed(7),    0.0000116,    '1 second as days');\n    assert.equal(moment.duration(1, 'second').asHours().toFixed(6),   0.000278,     '1 second as hours');\n    assert.equal(moment.duration(1, 'second').asMinutes().toFixed(4), 0.0167,       '1 second as minutes');\n    assert.equal(moment.duration(1, 'second').asSeconds(),            1,            '1 second as seconds');\n    assert.equal(moment.duration(1, 'second').asMilliseconds(),       1000,         '1 second as milliseconds');\n\n    // milliseconds\n    assert.equal(moment.duration(1, 'millisecond').asYears().toFixed(13),  0.0000000000317, '1 millisecond as years');\n    assert.equal(moment.duration(1, 'millisecond').asMonths().toFixed(12), 0.000000000380,  '1 millisecond as months');\n    assert.equal(moment.duration(1, 'millisecond').asWeeks().toFixed(11),  0.00000000165,   '1 millisecond as weeks');\n    assert.equal(moment.duration(1, 'millisecond').asDays().toFixed(10),   0.0000000116,    '1 millisecond as days');\n    assert.equal(moment.duration(1, 'millisecond').asHours().toFixed(9),   0.000000278,     '1 millisecond as hours');\n    assert.equal(moment.duration(1, 'millisecond').asMinutes().toFixed(7), 0.0000167,       '1 millisecond as minutes');\n    assert.equal(moment.duration(1, 'millisecond').asSeconds(),            0.001,           '1 millisecond as seconds');\n    assert.equal(moment.duration(1, 'millisecond').asMilliseconds(),       1,               '1 millisecond as milliseconds');\n});\n\ntest('as getters for small units', function (assert) {\n    var dS = moment.duration(1, 'milliseconds'),\n        ds = moment.duration(3, 'seconds'),\n        dm = moment.duration(13, 'minutes');\n\n    // Tests for issue #1867.\n    // Floating point errors for small duration units were introduced in version 2.8.0.\n    assert.equal(dS.as('milliseconds'), 1, 'as(\"milliseconds\")');\n    assert.equal(dS.asMilliseconds(),   1, 'asMilliseconds()');\n    assert.equal(ds.as('seconds'),      3, 'as(\"seconds\")');\n    assert.equal(ds.asSeconds(),        3, 'asSeconds()');\n    assert.equal(dm.as('minutes'),      13, 'as(\"minutes\")');\n    assert.equal(dm.asMinutes(),        13, 'asMinutes()');\n});\n\ntest('minutes getter for floating point hours', function (assert) {\n    // Tests for issue #2978.\n    // For certain floating point hours, .minutes() getter produced incorrect values due to the rounding errors\n    assert.equal(moment.duration(2.3, 'h').minutes(), 18, 'minutes()');\n    assert.equal(moment.duration(4.1, 'h').minutes(), 6, 'minutes()');\n});\n\ntest('isDuration', function (assert) {\n    assert.ok(moment.isDuration(moment.duration(12345678)), 'correctly says true');\n    assert.ok(!moment.isDuration(moment()), 'moment object is not a duration');\n    assert.ok(!moment.isDuration({milliseconds: 1}), 'plain object is not a duration');\n});\n\ntest('add', function (assert) {\n    var d = moment.duration({months: 4, weeks: 3, days: 2});\n    // for some reason, d._data._months does not get updated; use d._months instead.\n    assert.equal(d.add(1, 'month')._months, 5, 'Add months');\n    assert.equal(d.add(5, 'days')._days, 28, 'Add days');\n    assert.equal(d.add(10000)._milliseconds, 10000, 'Add milliseconds');\n    assert.equal(d.add({h: 23, m: 59})._milliseconds, 23 * 60 * 60 * 1000 + 59 * 60 * 1000 + 10000, 'Add hour:minute');\n});\n\ntest('add and bubble', function (assert) {\n    var d;\n\n    assert.equal(moment.duration(1, 'second').add(1000, 'milliseconds').seconds(), 2, 'Adding milliseconds should bubble up to seconds');\n    assert.equal(moment.duration(1, 'minute').add(60, 'second').minutes(), 2, 'Adding seconds should bubble up to minutes');\n    assert.equal(moment.duration(1, 'hour').add(60, 'minutes').hours(), 2, 'Adding minutes should bubble up to hours');\n    assert.equal(moment.duration(1, 'day').add(24, 'hours').days(), 2, 'Adding hours should bubble up to days');\n\n    d = moment.duration(-1, 'day').add(1, 'hour');\n    assert.equal(d.hours(), -23, '-1 day + 1 hour == -23 hour (component)');\n    assert.equal(d.asHours(), -23, '-1 day + 1 hour == -23 hours');\n\n    d = moment.duration(-1, 'year').add(1, 'day');\n    assert.equal(d.days(), -30, '- 1 year + 1 day == -30 days (component)');\n    assert.equal(d.months(), -11, '- 1 year + 1 day == -11 months (component)');\n    assert.equal(d.years(), 0, '- 1 year + 1 day == 0 years (component)');\n    assert.equal(d.asDays(), -364, '- 1 year + 1 day == -364 days');\n\n    d = moment.duration(-1, 'year').add(1, 'hour');\n    assert.equal(d.hours(), -23, '- 1 year + 1 hour == -23 hours (component)');\n    assert.equal(d.days(), -30, '- 1 year + 1 hour == -30 days (component)');\n    assert.equal(d.months(), -11, '- 1 year + 1 hour == -11 months (component)');\n    assert.equal(d.years(), 0, '- 1 year + 1 hour == 0 years (component)');\n});\n\ntest('subtract and bubble', function (assert) {\n    var d;\n\n    assert.equal(moment.duration(2, 'second').subtract(1000, 'milliseconds').seconds(), 1, 'Subtracting milliseconds should bubble up to seconds');\n    assert.equal(moment.duration(2, 'minute').subtract(60, 'second').minutes(), 1, 'Subtracting seconds should bubble up to minutes');\n    assert.equal(moment.duration(2, 'hour').subtract(60, 'minutes').hours(), 1, 'Subtracting minutes should bubble up to hours');\n    assert.equal(moment.duration(2, 'day').subtract(24, 'hours').days(), 1, 'Subtracting hours should bubble up to days');\n\n    d = moment.duration(1, 'day').subtract(1, 'hour');\n    assert.equal(d.hours(), 23, '1 day - 1 hour == 23 hour (component)');\n    assert.equal(d.asHours(), 23, '1 day - 1 hour == 23 hours');\n\n    d = moment.duration(1, 'year').subtract(1, 'day');\n    assert.equal(d.days(), 30, '1 year - 1 day == 30 days (component)');\n    assert.equal(d.months(), 11, '1 year - 1 day == 11 months (component)');\n    assert.equal(d.years(), 0, '1 year - 1 day == 0 years (component)');\n    assert.equal(d.asDays(), 364, '1 year - 1 day == 364 days');\n\n    d = moment.duration(1, 'year').subtract(1, 'hour');\n    assert.equal(d.hours(), 23, '1 year - 1 hour == 23 hours (component)');\n    assert.equal(d.days(), 30, '1 year - 1 hour == 30 days (component)');\n    assert.equal(d.months(), 11, '1 year - 1 hour == 11 months (component)');\n    assert.equal(d.years(), 0, '1 year - 1 hour == 0 years (component)');\n});\n\ntest('subtract', function (assert) {\n    var d = moment.duration({months: 2, weeks: 2, days: 0, hours: 5});\n    // for some reason, d._data._months does not get updated; use d._months instead.\n    assert.equal(d.subtract(1, 'months')._months, 1, 'Subtract months');\n    assert.equal(d.subtract(14, 'days')._days, 0, 'Subtract days');\n    assert.equal(d.subtract(10000)._milliseconds, 5 * 60 * 60 * 1000 - 10000, 'Subtract milliseconds');\n    assert.equal(d.subtract({h: 1, m: 59})._milliseconds, 3 * 60 * 60 * 1000 + 1 * 60 * 1000 - 10000, 'Subtract hour:minute');\n});\n\ntest('JSON.stringify duration', function (assert) {\n    var d = moment.duration(1024, 'h');\n\n    assert.equal(JSON.stringify(d), '\"' + d.toISOString() + '\"', 'JSON.stringify on duration should return ISO string');\n});\n\ntest('duration plugins', function (assert) {\n    var durationObject = moment.duration();\n    moment.duration.fn.foo = function (arg) {\n        assert.equal(this, durationObject);\n        assert.equal(arg, 5);\n    };\n    durationObject.foo(5);\n});\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/test/moment/duration_from_moments.js",
    "content": "import { module, test } from '../qunit';\nimport moment from '../../moment';\n\nmodule('duration from moments');\n\ntest('pure year diff', function (assert) {\n    var m1 = moment('2012-01-01T00:00:00.000Z'),\n        m2 = moment('2013-01-01T00:00:00.000Z');\n\n    assert.equal(moment.duration({from: m1, to: m2}).as('years'), 1, 'year moment difference');\n    assert.equal(moment.duration({from: m2, to: m1}).as('years'), -1, 'negative year moment difference');\n});\n\ntest('month and day diff', function (assert) {\n    var m1 = moment('2012-01-15T00:00:00.000Z'),\n        m2 = moment('2012-02-17T00:00:00.000Z'),\n        d = moment.duration({from: m1, to: m2});\n\n    assert.equal(d.get('days'), 2);\n    assert.equal(d.get('months'), 1);\n});\n\ntest('day diff, separate months', function (assert) {\n    var m1 = moment('2012-01-15T00:00:00.000Z'),\n        m2 = moment('2012-02-13T00:00:00.000Z'),\n        d = moment.duration({from: m1, to: m2});\n\n    assert.equal(d.as('days'), 29);\n});\n\ntest('hour diff', function (assert) {\n    var m1 = moment('2012-01-15T17:00:00.000Z'),\n        m2 = moment('2012-01-16T03:00:00.000Z'),\n        d = moment.duration({from: m1, to: m2});\n\n    assert.equal(d.as('hours'), 10);\n});\n\ntest('minute diff', function (assert) {\n    var m1 = moment('2012-01-15T17:45:00.000Z'),\n        m2 = moment('2012-01-16T03:15:00.000Z'),\n        d = moment.duration({from: m1, to: m2});\n\n    assert.equal(d.as('hours'), 9.5);\n});\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/test/moment/duration_invalid.js",
    "content": "import { module, test } from '../qunit';\nimport moment from '../../moment';\n\nmodule('invalid');\n\ntest('invalid duration', function (assert) {\n    var m = moment.duration.invalid(); // should be invalid\n    assert.equal(m.isValid(), false);\n    assert.ok(isNaN(m.valueOf()));\n});\n\ntest('valid duration', function (assert) {\n    var m = moment.duration({d: null}); // should be valid, for now\n    assert.equal(m.isValid(), true);\n    assert.equal(m.valueOf(), 0);\n});\n\ntest('invalid duration - only smallest unit can have decimal', function (assert) {\n    var m = moment.duration({'days': 3.5, 'hours': 1.1}); // should be invalid\n    assert.equal(m.isValid(), false);\n    assert.ok(isNaN(m.valueOf())); // .valueOf() returns NaN for invalid durations\n});\n\ntest('valid duration - smallest unit can have decimal', function (assert) {\n    var m = moment.duration({'days': 3, 'hours': 1.1}); // should be valid\n    assert.equal(m.isValid(), true);\n    assert.equal(m.asHours(), 73.1);\n});\n\ntest('invalid duration with two arguments', function (assert) {\n    var m = moment.duration(NaN, 'days');\n    assert.equal(m.isValid(), false);\n    assert.ok(isNaN(m.valueOf()));\n});\n\ntest('invalid duration operations', function (assert) {\n    var invalids = [\n            moment.duration(NaN),\n            moment.duration(NaN, 'days'),\n            moment.duration.invalid()\n        ],\n        i,\n        invalid,\n        valid = moment.duration();\n\n    for (i = 0; i < invalids.length; ++i) {\n        invalid = invalids[i];\n\n        assert.ok(!invalid.add(5, 'hours').isValid(), 'invalid.add is invalid; i=' + i);\n        assert.ok(!invalid.subtract(30, 'days').isValid(), 'invalid.subtract is invalid; i=' + i);\n        assert.ok(!invalid.abs().isValid(), 'invalid.abs is invalid; i=' + i);\n        assert.ok(isNaN(invalid.as('years')), 'invalid.as is NaN; i=' + i);\n        assert.ok(isNaN(invalid.asMilliseconds()), 'invalid.asMilliseconds is NaN; i=' + i);\n        assert.ok(isNaN(invalid.asSeconds()), 'invalid.asSeconds is NaN; i=' + i);\n        assert.ok(isNaN(invalid.asMinutes()), 'invalid.asMinutes is NaN; i=' + i);\n        assert.ok(isNaN(invalid.asHours()), 'invalid.asHours is NaN; i=' + i);\n        assert.ok(isNaN(invalid.asDays()), 'invalid.asDays is NaN; i=' + i);\n        assert.ok(isNaN(invalid.asWeeks()), 'invalid.asWeeks is NaN; i=' + i);\n        assert.ok(isNaN(invalid.asMonths()), 'invalid.asMonths is NaN; i=' + i);\n        assert.ok(isNaN(invalid.asYears()), 'invalid.asYears is NaN; i=' + i);\n        assert.ok(isNaN(invalid.valueOf()), 'invalid.valueOf is NaN; i=' + i);\n        assert.ok(isNaN(invalid.get('hours')), 'invalid.get is NaN; i=' + i);\n\n        assert.ok(isNaN(invalid.milliseconds()), 'invalid.milliseconds is NaN; i=' + i);\n        assert.ok(isNaN(invalid.seconds()), 'invalid.seconds is NaN; i=' + i);\n        assert.ok(isNaN(invalid.minutes()), 'invalid.minutes is NaN; i=' + i);\n        assert.ok(isNaN(invalid.hours()), 'invalid.hours is NaN; i=' + i);\n        assert.ok(isNaN(invalid.days()), 'invalid.days is NaN; i=' + i);\n        assert.ok(isNaN(invalid.weeks()), 'invalid.weeks is NaN; i=' + i);\n        assert.ok(isNaN(invalid.months()), 'invalid.months is NaN; i=' + i);\n        assert.ok(isNaN(invalid.years()), 'invalid.years is NaN; i=' + i);\n\n        assert.equal(invalid.humanize(),\n                     invalid.localeData().invalidDate(),\n                     'invalid.humanize is localized invalid duration string; i=' + i);\n        assert.equal(invalid.toISOString(),\n                     invalid.localeData().invalidDate(),\n                     'invalid.toISOString is localized invalid duration string; i=' + i);\n        assert.equal(invalid.toString(),\n                     invalid.localeData().invalidDate(),\n                     'invalid.toString is localized invalid duration string; i=' + i);\n        assert.equal(invalid.toJSON(), invalid.localeData().invalidDate(), 'invalid.toJSON is null; i=' + i);\n        assert.equal(invalid.locale(), 'en', 'invalid.locale; i=' + i);\n        assert.equal(invalid.localeData()._abbr, 'en', 'invalid.localeData()._abbr; i=' + i);\n    }\n});\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/test/moment/format.js",
    "content": "import { module, test } from '../qunit';\nimport each from '../helpers/each';\nimport moment from '../../moment';\n\nmodule('format');\n\ntest('format YY', function (assert) {\n    var b = moment(new Date(2009, 1, 14, 15, 25, 50, 125));\n    assert.equal(b.format('YY'), '09', 'YY ---> 09');\n});\n\ntest('format escape brackets', function (assert) {\n    moment.locale('en');\n\n    var b = moment(new Date(2009, 1, 14, 15, 25, 50, 125));\n    assert.equal(b.format('[day]'), 'day', 'Single bracket');\n    assert.equal(b.format('[day] YY [YY]'), 'day 09 YY', 'Double bracket');\n    assert.equal(b.format('[YY'), '[09', 'Un-ended bracket');\n    assert.equal(b.format('[[YY]]'), '[YY]', 'Double nested brackets');\n    assert.equal(b.format('[[]'), '[', 'Escape open bracket');\n    assert.equal(b.format('[Last]'), 'Last', 'localized tokens');\n    assert.equal(b.format('[L] L'), 'L 02/14/2009', 'localized tokens with escaped localized tokens');\n    assert.equal(b.format('[L LL LLL LLLL aLa]'), 'L LL LLL LLLL aLa', 'localized tokens with escaped localized tokens');\n    assert.equal(b.format('[LLL] LLL'), 'LLL February 14, 2009 3:25 PM', 'localized tokens with escaped localized tokens (recursion)');\n    assert.equal(b.format('YYYY[\\n]DD[\\n]'), '2009\\n14\\n', 'Newlines');\n});\n\ntest('handle negative years', function (assert) {\n    moment.locale('en');\n    assert.equal(moment.utc().year(-1).format('YY'), '-01', 'YY with negative year');\n    assert.equal(moment.utc().year(-1).format('YYYY'), '-0001', 'YYYY with negative year');\n    assert.equal(moment.utc().year(-12).format('YY'), '-12', 'YY with negative year');\n    assert.equal(moment.utc().year(-12).format('YYYY'), '-0012', 'YYYY with negative year');\n    assert.equal(moment.utc().year(-123).format('YY'), '-23', 'YY with negative year');\n    assert.equal(moment.utc().year(-123).format('YYYY'), '-0123', 'YYYY with negative year');\n    assert.equal(moment.utc().year(-1234).format('YY'), '-34', 'YY with negative year');\n    assert.equal(moment.utc().year(-1234).format('YYYY'), '-1234', 'YYYY with negative year');\n    assert.equal(moment.utc().year(-12345).format('YY'), '-45', 'YY with negative year');\n    assert.equal(moment.utc().year(-12345).format('YYYY'), '-12345', 'YYYY with negative year');\n});\n\ntest('format milliseconds', function (assert) {\n    var b = moment(new Date(2009, 1, 14, 15, 25, 50, 123));\n    assert.equal(b.format('S'), '1', 'Deciseconds');\n    assert.equal(b.format('SS'), '12', 'Centiseconds');\n    assert.equal(b.format('SSS'), '123', 'Milliseconds');\n    b.milliseconds(789);\n    assert.equal(b.format('S'), '7', 'Deciseconds');\n    assert.equal(b.format('SS'), '78', 'Centiseconds');\n    assert.equal(b.format('SSS'), '789', 'Milliseconds');\n});\n\ntest('format timezone', function (assert) {\n    var b = moment(new Date(2010, 1, 14, 15, 25, 50, 125));\n    assert.ok(b.format('Z').match(/^[\\+\\-]\\d\\d:\\d\\d$/), b.format('Z') + ' should be something like \\'+07:30\\'');\n    assert.ok(b.format('ZZ').match(/^[\\+\\-]\\d{4}$/), b.format('ZZ') + ' should be something like \\'+0700\\'');\n});\n\ntest('format multiple with utc offset', function (assert) {\n    var b = moment('2012-10-08 -1200', ['YYYY-MM-DD HH:mm ZZ', 'YYYY-MM-DD ZZ', 'YYYY-MM-DD']);\n    assert.equal(b.format('YYYY-MM'), '2012-10', 'Parsing multiple formats should not crash with different sized formats');\n});\n\ntest('isDST', function (assert) {\n    var janOffset = new Date(2011, 0, 1).getTimezoneOffset(),\n        julOffset = new Date(2011, 6, 1).getTimezoneOffset(),\n        janIsDst = janOffset < julOffset,\n        julIsDst = julOffset < janOffset,\n        jan1 = moment([2011]),\n        jul1 = moment([2011, 6]);\n\n    if (janIsDst && julIsDst) {\n        assert.ok(0, 'January and July cannot both be in DST');\n        assert.ok(0, 'January and July cannot both be in DST');\n    } else if (janIsDst) {\n        assert.ok(jan1.isDST(), 'January 1 is DST');\n        assert.ok(!jul1.isDST(), 'July 1 is not DST');\n    } else if (julIsDst) {\n        assert.ok(!jan1.isDST(), 'January 1 is not DST');\n        assert.ok(jul1.isDST(), 'July 1 is DST');\n    } else {\n        assert.ok(!jan1.isDST(), 'January 1 is not DST');\n        assert.ok(!jul1.isDST(), 'July 1 is not DST');\n    }\n});\n\ntest('unix timestamp', function (assert) {\n    var m = moment('1234567890.123', 'X');\n    assert.equal(m.format('X'), '1234567890', 'unix timestamp without milliseconds');\n    assert.equal(m.format('X.S'), '1234567890.1', 'unix timestamp with deciseconds');\n    assert.equal(m.format('X.SS'), '1234567890.12', 'unix timestamp with centiseconds');\n    assert.equal(m.format('X.SSS'), '1234567890.123', 'unix timestamp with milliseconds');\n\n    m = moment(1234567890.123, 'X');\n    assert.equal(m.format('X'), '1234567890', 'unix timestamp as integer');\n});\n\ntest('unix offset milliseconds', function (assert) {\n    var m = moment('1234567890123', 'x');\n    assert.equal(m.format('x'), '1234567890123', 'unix offset in milliseconds');\n\n    m = moment(1234567890123, 'x');\n    assert.equal(m.format('x'), '1234567890123', 'unix offset in milliseconds as integer');\n});\n\ntest('utcOffset sanity checks', function (assert) {\n    assert.equal(moment().utcOffset() % 15, 0,\n            'utc offset should be a multiple of 15 (was ' + moment().utcOffset() + ')');\n\n    assert.equal(moment().utcOffset(), -(new Date()).getTimezoneOffset(),\n        'utcOffset should return the opposite of getTimezoneOffset');\n});\n\ntest('default format', function (assert) {\n    var isoRegex = /\\d{4}.\\d\\d.\\d\\dT\\d\\d.\\d\\d.\\d\\d[\\+\\-]\\d\\d:\\d\\d/;\n    assert.ok(isoRegex.exec(moment().format()), 'default format (' + moment().format() + ') should match ISO');\n});\n\ntest('default UTC format', function (assert) {\n    var isoRegex = /\\d{4}.\\d\\d.\\d\\dT\\d\\d.\\d\\d.\\d\\dZ/;\n    assert.ok(isoRegex.exec(moment.utc().format()), 'default UTC format (' + moment.utc().format() + ') should match ISO');\n});\n\ntest('toJSON', function (assert) {\n    var supportsJson = typeof JSON !== 'undefined' && JSON.stringify && JSON.stringify.call,\n        date = moment('2012-10-09T21:30:40.678+0100');\n\n    assert.equal(date.toJSON(), '2012-10-09T20:30:40.678Z', 'should output ISO8601 on moment.fn.toJSON');\n\n    if (supportsJson) {\n        assert.equal(JSON.stringify({\n            date : date\n        }), '{\"date\":\"2012-10-09T20:30:40.678Z\"}', 'should output ISO8601 on JSON.stringify');\n    }\n});\n\ntest('toISOString', function (assert) {\n    var date = moment.utc('2012-10-09T20:30:40.678');\n\n    assert.equal(date.toISOString(), '2012-10-09T20:30:40.678Z', 'should output ISO8601 on moment.fn.toISOString');\n\n    // big years\n    date = moment.utc('+020123-10-09T20:30:40.678');\n    assert.equal(date.toISOString(), '+020123-10-09T20:30:40.678Z', 'ISO8601 format on big positive year');\n    // negative years\n    date = moment.utc('-000001-10-09T20:30:40.678');\n    assert.equal(date.toISOString(), '-000001-10-09T20:30:40.678Z', 'ISO8601 format on negative year');\n    // big negative years\n    date = moment.utc('-020123-10-09T20:30:40.678');\n    assert.equal(date.toISOString(), '-020123-10-09T20:30:40.678Z', 'ISO8601 format on big negative year');\n\n    //invalid dates\n    date = moment.utc('2017-12-32');\n    assert.equal(date.toISOString(), null, 'An invalid date to iso string is null');\n});\n\n// See https://nodejs.org/dist/latest/docs/api/util.html#util_custom_inspect_function_on_objects\ntest('inspect', function (assert) {\n    function roundtrip(m) {\n        /*jshint evil:true */\n        return (new Function('moment', 'return ' + m.inspect()))(moment);\n    }\n    function testInspect(date, string) {\n        var inspected = date.inspect();\n        assert.equal(inspected, string);\n        assert.ok(date.isSame(roundtrip(date)), 'Tried to parse ' + inspected);\n    }\n\n    testInspect(\n        moment('2012-10-09T20:30:40.678'),\n        'moment(\"2012-10-09T20:30:40.678\")'\n    );\n    testInspect(\n        moment('+020123-10-09T20:30:40.678'),\n        'moment(\"+020123-10-09T20:30:40.678\")'\n    );\n    testInspect(\n        moment.utc('2012-10-09T20:30:40.678'),\n        'moment.utc(\"2012-10-09T20:30:40.678+00:00\")'\n    );\n    testInspect(\n        moment.utc('+020123-10-09T20:30:40.678'),\n        'moment.utc(\"+020123-10-09T20:30:40.678+00:00\")'\n    );\n    testInspect(\n        moment.utc('+020123-10-09T20:30:40.678+01:00'),\n        'moment.utc(\"+020123-10-09T19:30:40.678+00:00\")'\n    );\n    testInspect(\n        moment.parseZone('2016-06-11T17:30:40.678+0430'),\n        'moment.parseZone(\"2016-06-11T17:30:40.678+04:30\")'\n    );\n    testInspect(\n        moment.parseZone('+112016-06-11T17:30:40.678+0430'),\n        'moment.parseZone(\"+112016-06-11T17:30:40.678+04:30\")'\n    );\n\n    assert.equal(\n        moment(new Date('nope')).inspect(),\n        'moment.invalid(/* Invalid Date */)'\n    );\n    assert.equal(\n        moment('blah', 'YYYY').inspect(),\n        'moment.invalid(/* blah */)'\n    );\n});\n\ntest('long years', function (assert) {\n    assert.equal(moment.utc().year(2).format('YYYYYY'), '+000002', 'small year with YYYYYY');\n    assert.equal(moment.utc().year(2012).format('YYYYYY'), '+002012', 'regular year with YYYYYY');\n    assert.equal(moment.utc().year(20123).format('YYYYYY'), '+020123', 'big year with YYYYYY');\n\n    assert.equal(moment.utc().year(-1).format('YYYYYY'), '-000001', 'small negative year with YYYYYY');\n    assert.equal(moment.utc().year(-2012).format('YYYYYY'), '-002012', 'negative year with YYYYYY');\n    assert.equal(moment.utc().year(-20123).format('YYYYYY'), '-020123', 'big negative year with YYYYYY');\n});\n\ntest('toISOString() when 0 year', function (assert) {\n    // https://github.com/moment/moment/issues/3765\n    var date = moment('0000-01-01T21:00:00.000Z');\n    assert.equal(date.toISOString(), '0000-01-01T21:00:00.000Z');\n    assert.equal(date.toDate().toISOString(), '0000-01-01T21:00:00.000Z');\n});\n\ntest('iso week formats', function (assert) {\n    // https://en.wikipedia.org/wiki/ISO_week_date\n    var cases = {\n        '2005-01-02': '2004-53',\n        '2005-12-31': '2005-52',\n        '2007-01-01': '2007-01',\n        '2007-12-30': '2007-52',\n        '2007-12-31': '2008-01',\n        '2008-01-01': '2008-01',\n        '2008-12-28': '2008-52',\n        '2008-12-29': '2009-01',\n        '2008-12-30': '2009-01',\n        '2008-12-31': '2009-01',\n        '2009-01-01': '2009-01',\n        '2009-12-31': '2009-53',\n        '2010-01-01': '2009-53',\n        '2010-01-02': '2009-53',\n        '2010-01-03': '2009-53',\n        '404-12-31': '0404-53',\n        '405-12-31': '0405-52'\n    }, i, isoWeek, formatted2, formatted1;\n\n    for (i in cases) {\n        isoWeek = cases[i].split('-').pop();\n        formatted2 = moment(i, 'YYYY-MM-DD').format('WW');\n        assert.equal(isoWeek, formatted2, i + ': WW should be ' + isoWeek + ', but ' + formatted2);\n        isoWeek = isoWeek.replace(/^0+/, '');\n        formatted1 = moment(i, 'YYYY-MM-DD').format('W');\n        assert.equal(isoWeek, formatted1, i + ': W should be ' + isoWeek + ', but ' + formatted1);\n    }\n});\n\ntest('iso week year formats', function (assert) {\n    // https://en.wikipedia.org/wiki/ISO_week_date\n    var cases = {\n        '2005-01-02': '2004-53',\n        '2005-12-31': '2005-52',\n        '2007-01-01': '2007-01',\n        '2007-12-30': '2007-52',\n        '2007-12-31': '2008-01',\n        '2008-01-01': '2008-01',\n        '2008-12-28': '2008-52',\n        '2008-12-29': '2009-01',\n        '2008-12-30': '2009-01',\n        '2008-12-31': '2009-01',\n        '2009-01-01': '2009-01',\n        '2009-12-31': '2009-53',\n        '2010-01-01': '2009-53',\n        '2010-01-02': '2009-53',\n        '2010-01-03': '2009-53',\n        '404-12-31': '0404-53',\n        '405-12-31': '0405-52'\n    }, i, isoWeekYear, formatted5, formatted4, formatted2;\n\n    for (i in cases) {\n        isoWeekYear = cases[i].split('-')[0];\n        formatted5 = moment(i, 'YYYY-MM-DD').format('GGGGG');\n        assert.equal('0' + isoWeekYear, formatted5, i + ': GGGGG should be ' + isoWeekYear + ', but ' + formatted5);\n        formatted4 = moment(i, 'YYYY-MM-DD').format('GGGG');\n        assert.equal(isoWeekYear, formatted4, i + ': GGGG should be ' + isoWeekYear + ', but ' + formatted4);\n        formatted2 = moment(i, 'YYYY-MM-DD').format('GG');\n        assert.equal(isoWeekYear.slice(2, 4), formatted2, i + ': GG should be ' + isoWeekYear + ', but ' + formatted2);\n    }\n});\n\ntest('week year formats', function (assert) {\n    // https://en.wikipedia.org/wiki/ISO_week_date\n    var cases = {\n        '2005-01-02': '2004-53',\n        '2005-12-31': '2005-52',\n        '2007-01-01': '2007-01',\n        '2007-12-30': '2007-52',\n        '2007-12-31': '2008-01',\n        '2008-01-01': '2008-01',\n        '2008-12-28': '2008-52',\n        '2008-12-29': '2009-01',\n        '2008-12-30': '2009-01',\n        '2008-12-31': '2009-01',\n        '2009-01-01': '2009-01',\n        '2009-12-31': '2009-53',\n        '2010-01-01': '2009-53',\n        '2010-01-02': '2009-53',\n        '2010-01-03': '2009-53',\n        '404-12-31': '0404-53',\n        '405-12-31': '0405-52'\n    }, i, isoWeekYear, formatted5, formatted4, formatted2;\n\n    moment.defineLocale('dow:1,doy:4', {week: {dow: 1, doy: 4}});\n\n    for (i in cases) {\n        isoWeekYear = cases[i].split('-')[0];\n        formatted5 = moment(i, 'YYYY-MM-DD').format('ggggg');\n        assert.equal('0' + isoWeekYear, formatted5, i + ': ggggg should be ' + isoWeekYear + ', but ' + formatted5);\n        formatted4 = moment(i, 'YYYY-MM-DD').format('gggg');\n        assert.equal(isoWeekYear, formatted4, i + ': gggg should be ' + isoWeekYear + ', but ' + formatted4);\n        formatted2 = moment(i, 'YYYY-MM-DD').format('gg');\n        assert.equal(isoWeekYear.slice(2, 4), formatted2, i + ': gg should be ' + isoWeekYear + ', but ' + formatted2);\n    }\n    moment.defineLocale('dow:1,doy:4', null);\n});\n\ntest('iso weekday formats', function (assert) {\n    assert.equal(moment([1985, 1,  4]).format('E'), '1', 'Feb  4 1985 is Monday    -- 1st day');\n    assert.equal(moment([2029, 8, 18]).format('E'), '2', 'Sep 18 2029 is Tuesday   -- 2nd day');\n    assert.equal(moment([2013, 3, 24]).format('E'), '3', 'Apr 24 2013 is Wednesday -- 3rd day');\n    assert.equal(moment([2015, 2,  5]).format('E'), '4', 'Mar  5 2015 is Thursday  -- 4th day');\n    assert.equal(moment([1970, 0,  2]).format('E'), '5', 'Jan  2 1970 is Friday    -- 5th day');\n    assert.equal(moment([2001, 4, 12]).format('E'), '6', 'May 12 2001 is Saturday  -- 6th day');\n    assert.equal(moment([2000, 0,  2]).format('E'), '7', 'Jan  2 2000 is Sunday    -- 7th day');\n});\n\ntest('weekday formats', function (assert) {\n    moment.defineLocale('dow: 3,doy: 5', {week: {dow: 3, doy: 5}});\n    assert.equal(moment([1985, 1,  6]).format('e'), '0', 'Feb  6 1985 is Wednesday -- 0th day');\n    assert.equal(moment([2029, 8, 20]).format('e'), '1', 'Sep 20 2029 is Thursday  -- 1st day');\n    assert.equal(moment([2013, 3, 26]).format('e'), '2', 'Apr 26 2013 is Friday    -- 2nd day');\n    assert.equal(moment([2015, 2,  7]).format('e'), '3', 'Mar  7 2015 is Saturday  -- 3nd day');\n    assert.equal(moment([1970, 0,  4]).format('e'), '4', 'Jan  4 1970 is Sunday    -- 4th day');\n    assert.equal(moment([2001, 4, 14]).format('e'), '5', 'May 14 2001 is Monday    -- 5th day');\n    assert.equal(moment([2000, 0,  4]).format('e'), '6', 'Jan  4 2000 is Tuesday   -- 6th day');\n    moment.defineLocale('dow: 3,doy: 5', null);\n});\n\ntest('toString is just human readable format', function (assert) {\n    var b = moment(new Date(2009, 1, 5, 15, 25, 50, 125));\n    assert.equal(b.toString(), b.format('ddd MMM DD YYYY HH:mm:ss [GMT]ZZ'));\n});\n\ntest('toJSON skips postformat', function (assert) {\n    moment.defineLocale('postformat', {\n        postformat: function (s) {\n            s.replace(/./g, 'X');\n        }\n    });\n    assert.equal(moment.utc([2000, 0, 1]).toJSON(), '2000-01-01T00:00:00.000Z', 'toJSON doesn\\'t postformat');\n    moment.defineLocale('postformat', null);\n});\n\ntest('calendar day timezone', function (assert) {\n    moment.locale('en');\n    var zones = [60, -60, 90, -90, 360, -360, 720, -720],\n        b = moment().utc().startOf('day').subtract({m : 1}),\n        c = moment().local().startOf('day').subtract({m : 1}),\n        d = moment().local().startOf('day').subtract({d : 2}),\n        i, z, a;\n\n    for (i = 0; i < zones.length; ++i) {\n        z = zones[i];\n        a = moment().utcOffset(z).startOf('day').subtract({m: 1});\n        assert.equal(moment(a).utcOffset(z).calendar(), 'Yesterday at 11:59 PM',\n                     'Yesterday at 11:59 PM, not Today, or the wrong time, tz = ' + z);\n    }\n\n    assert.equal(moment(b).utc().calendar(), 'Yesterday at 11:59 PM', 'Yesterday at 11:59 PM, not Today, or the wrong time');\n    assert.equal(moment(c).local().calendar(), 'Yesterday at 11:59 PM', 'Yesterday at 11:59 PM, not Today, or the wrong time');\n    assert.equal(moment(c).local().calendar(d), 'Tomorrow at 11:59 PM', 'Tomorrow at 11:59 PM, not Yesterday, or the wrong time');\n});\n\ntest('calendar with custom formats', function (assert) {\n    assert.equal(moment().calendar(null, {sameDay: '[Today]'}), 'Today', 'Today');\n    assert.equal(moment().add(1, 'days').calendar(null, {nextDay: '[Tomorrow]'}), 'Tomorrow', 'Tomorrow');\n    assert.equal(moment([1985, 1, 4]).calendar(null, {sameElse: 'YYYY-MM-DD'}), '1985-02-04', 'Else');\n});\n\ntest('invalid', function (assert) {\n    assert.equal(moment.invalid().format(), 'Invalid date');\n    assert.equal(moment.invalid().format('YYYY-MM-DD'), 'Invalid date');\n});\n\ntest('quarter formats', function (assert) {\n    assert.equal(moment([1985, 1,  4]).format('Q'), '1', 'Feb  4 1985 is Q1');\n    assert.equal(moment([2029, 8, 18]).format('Q'), '3', 'Sep 18 2029 is Q3');\n    assert.equal(moment([2013, 3, 24]).format('Q'), '2', 'Apr 24 2013 is Q2');\n    assert.equal(moment([2015, 2,  5]).format('Q'), '1', 'Mar  5 2015 is Q1');\n    assert.equal(moment([1970, 0,  2]).format('Q'), '1', 'Jan  2 1970 is Q1');\n    assert.equal(moment([2001, 11, 12]).format('Q'), '4', 'Dec 12 2001 is Q4');\n    assert.equal(moment([2000, 0,  2]).format('[Q]Q-YYYY'), 'Q1-2000', 'Jan  2 2000 is Q1');\n});\n\ntest('quarter ordinal formats', function (assert) {\n    assert.equal(moment([1985, 1, 4]).format('Qo'), '1st', 'Feb 4 1985 is 1st quarter');\n    assert.equal(moment([2029, 8, 18]).format('Qo'), '3rd', 'Sep 18 2029 is 3rd quarter');\n    assert.equal(moment([2013, 3, 24]).format('Qo'), '2nd', 'Apr 24 2013 is 2nd quarter');\n    assert.equal(moment([2015, 2,  5]).format('Qo'), '1st', 'Mar  5 2015 is 1st quarter');\n    assert.equal(moment([1970, 0,  2]).format('Qo'), '1st', 'Jan  2 1970 is 1st quarter');\n    assert.equal(moment([2001, 11, 12]).format('Qo'), '4th', 'Dec 12 2001 is 4th quarter');\n    assert.equal(moment([2000, 0,  2]).format('Qo [quarter] YYYY'), '1st quarter 2000', 'Jan  2 2000 is 1st quarter');\n});\n\n// test('full expanded format is returned from abbreviated formats', function (assert) {\n//     function objectKeys(obj) {\n//         if (Object.keys) {\n//             return Object.keys(obj);\n//         } else {\n//             // IE8\n//             var res = [], i;\n//             for (i in obj) {\n//                 if (obj.hasOwnProperty(i)) {\n//                     res.push(i);\n//                 }\n//             }\n//             return res;\n//         }\n//     }\n\n//     var locales =\n//         'ar-sa ar-tn ar az be bg bn bo br bs ca cs cv cy da de-at de dv el ' +\n//         'en-au en-ca en-gb en-ie en-nz eo es et eu fa fi fo fr-ca fr-ch fr fy ' +\n//         'gd gl he hi hr hu hy-am id is it ja jv ka kk km ko lb lo lt lv me mk ml ' +\n//         'mr ms-my ms my nb ne nl nn pl pt-br pt ro ru se si sk sl sq sr-cyrl ' +\n//         'sr sv sw ta te th tl-ph tlh tr tzl tzm-latn tzm uk uz vi zh-cn zh-tw';\n\n//     each(locales.split(' '), function (locale) {\n//         var data, tokens;\n//         data = moment().locale(locale).localeData()._longDateFormat;\n//         tokens = objectKeys(data);\n//         each(tokens, function (token) {\n//             // Check each format string to make sure it does not contain any\n//             // tokens that need to be expanded.\n//             each(tokens, function (i) {\n//                 // strip escaped sequences\n//                 var format = data[i].replace(/(\\[[^\\]]*\\])/g, '');\n//                 assert.equal(false, !!~format.indexOf(token), 'locale ' + locale + ' contains ' + token + ' in ' + i);\n//             });\n//         });\n//     });\n// });\n\ntest('milliseconds', function (assert) {\n    var m = moment('123', 'SSS');\n\n    assert.equal(m.format('S'), '1');\n    assert.equal(m.format('SS'), '12');\n    assert.equal(m.format('SSS'), '123');\n    assert.equal(m.format('SSSS'), '1230');\n    assert.equal(m.format('SSSSS'), '12300');\n    assert.equal(m.format('SSSSSS'), '123000');\n    assert.equal(m.format('SSSSSSS'), '1230000');\n    assert.equal(m.format('SSSSSSSS'), '12300000');\n    assert.equal(m.format('SSSSSSSSS'), '123000000');\n});\n\ntest('hmm and hmmss', function (assert) {\n    assert.equal(moment('12:34:56', 'HH:mm:ss').format('hmm'), '1234');\n    assert.equal(moment('01:34:56', 'HH:mm:ss').format('hmm'), '134');\n    assert.equal(moment('13:34:56', 'HH:mm:ss').format('hmm'), '134');\n\n    assert.equal(moment('12:34:56', 'HH:mm:ss').format('hmmss'), '123456');\n    assert.equal(moment('01:34:56', 'HH:mm:ss').format('hmmss'), '13456');\n    assert.equal(moment('13:34:56', 'HH:mm:ss').format('hmmss'), '13456');\n});\n\ntest('Hmm and Hmmss', function (assert) {\n    assert.equal(moment('12:34:56', 'HH:mm:ss').format('Hmm'), '1234');\n    assert.equal(moment('01:34:56', 'HH:mm:ss').format('Hmm'), '134');\n    assert.equal(moment('13:34:56', 'HH:mm:ss').format('Hmm'), '1334');\n\n    assert.equal(moment('12:34:56', 'HH:mm:ss').format('Hmmss'), '123456');\n    assert.equal(moment('01:34:56', 'HH:mm:ss').format('Hmmss'), '13456');\n    assert.equal(moment('08:34:56', 'HH:mm:ss').format('Hmmss'), '83456');\n    assert.equal(moment('18:34:56', 'HH:mm:ss').format('Hmmss'), '183456');\n});\n\ntest('k and kk', function (assert) {\n    assert.equal(moment('01:23:45', 'HH:mm:ss').format('k'), '1');\n    assert.equal(moment('12:34:56', 'HH:mm:ss').format('k'), '12');\n    assert.equal(moment('01:23:45', 'HH:mm:ss').format('kk'), '01');\n    assert.equal(moment('12:34:56', 'HH:mm:ss').format('kk'), '12');\n    assert.equal(moment('00:34:56', 'HH:mm:ss').format('kk'), '24');\n    assert.equal(moment('00:00:00', 'HH:mm:ss').format('kk'), '24');\n});\n\ntest('Y token', function (assert) {\n    assert.equal(moment('2010-01-01', 'YYYY-MM-DD', true).format('Y'), '2010', 'format 2010 with Y');\n    assert.equal(moment('-123-01-01', 'Y-MM-DD', true).format('Y'), '-123', 'format -123 with Y');\n    assert.equal(moment('12345-01-01', 'Y-MM-DD', true).format('Y'), '+12345', 'format 12345 with Y');\n    assert.equal(moment('0-01-01', 'Y-MM-DD', true).format('Y'), '0', 'format 0 with Y');\n    assert.equal(moment('1-01-01', 'Y-MM-DD', true).format('Y'), '1', 'format 1 with Y');\n    assert.equal(moment('9999-01-01', 'Y-MM-DD', true).format('Y'), '9999', 'format 9999 with Y');\n    assert.equal(moment('10000-01-01', 'Y-MM-DD', true).format('Y'), '+10000', 'format 10000 with Y');\n});\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/test/moment/from_to.js",
    "content": "import { module, test } from '../qunit';\nimport moment from '../../moment';\n\nmodule('from_to');\n\ntest('from', function (assert) {\n    var start = moment();\n    moment.locale('en');\n    assert.equal(start.from(start.clone().add(5, 'seconds')),  'a few seconds ago', '5 seconds = a few seconds ago');\n    assert.equal(start.from(start.clone().add(1, 'minute')),  'a minute ago', '1 minute = a minute ago');\n    assert.equal(start.from(start.clone().add(5, 'minutes')),  '5 minutes ago', '5 minutes = 5 minutes ago');\n\n    assert.equal(start.from(start.clone().subtract(5, 'seconds')),  'in a few seconds', '5 seconds = in a few seconds');\n    assert.equal(start.from(start.clone().subtract(1, 'minute')),  'in a minute', '1 minute = in a minute');\n    assert.equal(start.from(start.clone().subtract(5, 'minutes')),  'in 5 minutes', '5 minutes = in 5 minutes');\n});\n\ntest('from with absolute duration', function (assert) {\n    var start = moment();\n    moment.locale('en');\n    assert.equal(start.from(start.clone().add(5, 'seconds'), true),  'a few seconds', '5 seconds = a few seconds');\n    assert.equal(start.from(start.clone().add(1, 'minute'), true),  'a minute', '1 minute = a minute');\n    assert.equal(start.from(start.clone().add(5, 'minutes'), true),  '5 minutes', '5 minutes = 5 minutes');\n\n    assert.equal(start.from(start.clone().subtract(5, 'seconds'), true),  'a few seconds', '5 seconds = a few seconds');\n    assert.equal(start.from(start.clone().subtract(1, 'minute'), true),  'a minute', '1 minute = a minute');\n    assert.equal(start.from(start.clone().subtract(5, 'minutes'), true),  '5 minutes', '5 minutes = 5 minutes');\n});\n\ntest('to', function (assert) {\n    var start = moment();\n    moment.locale('en');\n    assert.equal(start.to(start.clone().subtract(5, 'seconds')),  'a few seconds ago', '5 seconds = a few seconds ago');\n    assert.equal(start.to(start.clone().subtract(1, 'minute')),  'a minute ago', '1 minute = a minute ago');\n    assert.equal(start.to(start.clone().subtract(5, 'minutes')),  '5 minutes ago', '5 minutes = 5 minutes ago');\n\n    assert.equal(start.to(start.clone().add(5, 'seconds')),  'in a few seconds', '5 seconds = in a few seconds');\n    assert.equal(start.to(start.clone().add(1, 'minute')),  'in a minute', '1 minute = in a minute');\n    assert.equal(start.to(start.clone().add(5, 'minutes')),  'in 5 minutes', '5 minutes = in 5 minutes');\n});\n\ntest('to with absolute duration', function (assert) {\n    var start = moment();\n    moment.locale('en');\n    assert.equal(start.to(start.clone().add(5, 'seconds'), true),  'a few seconds', '5 seconds = a few seconds');\n    assert.equal(start.to(start.clone().add(1, 'minute'), true),  'a minute', '1 minute = a minute');\n    assert.equal(start.to(start.clone().add(5, 'minutes'), true),  '5 minutes', '5 minutes = 5 minutes');\n\n    assert.equal(start.to(start.clone().subtract(5, 'seconds'), true),  'a few seconds', '5 seconds = a few seconds');\n    assert.equal(start.to(start.clone().subtract(1, 'minute'), true),  'a minute', '1 minute = a minute');\n    assert.equal(start.to(start.clone().subtract(5, 'minutes'), true),  '5 minutes', '5 minutes = 5 minutes');\n});\n\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/test/moment/getters_setters.js",
    "content": "import { module, test } from '../qunit';\nimport moment from '../../moment';\n\nmodule('getters and setters');\n\ntest('getters', function (assert) {\n    var a = moment([2011, 9, 12, 6, 7, 8, 9]);\n    assert.equal(a.year(), 2011, 'year');\n    assert.equal(a.month(), 9, 'month');\n    assert.equal(a.date(), 12, 'date');\n    assert.equal(a.day(), 3, 'day');\n    assert.equal(a.hours(), 6, 'hour');\n    assert.equal(a.minutes(), 7, 'minute');\n    assert.equal(a.seconds(), 8, 'second');\n    assert.equal(a.milliseconds(), 9, 'milliseconds');\n});\n\ntest('getters programmatic', function (assert) {\n    var a = moment([2011, 9, 12, 6, 7, 8, 9]);\n    assert.equal(a.get('year'), 2011, 'year');\n    assert.equal(a.get('month'), 9, 'month');\n    assert.equal(a.get('date'), 12, 'date');\n    assert.equal(a.get('day'), 3, 'day');\n    assert.equal(a.get('hour'), 6, 'hour');\n    assert.equal(a.get('minute'), 7, 'minute');\n    assert.equal(a.get('second'), 8, 'second');\n    assert.equal(a.get('milliseconds'), 9, 'milliseconds');\n\n    //actual getters tested elsewhere\n    assert.equal(a.get('weekday'), a.weekday(), 'weekday');\n    assert.equal(a.get('isoWeekday'), a.isoWeekday(), 'isoWeekday');\n    assert.equal(a.get('week'), a.week(), 'week');\n    assert.equal(a.get('isoWeek'), a.isoWeek(), 'isoWeek');\n    assert.equal(a.get('dayOfYear'), a.dayOfYear(), 'dayOfYear');\n\n    //getter no longer sets values when passed an object\n    assert.equal(moment([2016,0,1]).get({year:2015}).year(), 2016, 'getter no longer sets values when passed an object');\n});\n\ntest('setters plural', function (assert) {\n    var a = moment();\n    test.expectedDeprecations('years accessor', 'months accessor', 'dates accessor');\n\n    a.years(2011);\n    a.months(9);\n    a.dates(12);\n    a.hours(6);\n    a.minutes(7);\n    a.seconds(8);\n    a.milliseconds(9);\n    assert.equal(a.years(), 2011, 'years');\n    assert.equal(a.months(), 9, 'months');\n    assert.equal(a.dates(), 12, 'dates');\n    assert.equal(a.days(), 3, 'days');\n    assert.equal(a.hours(), 6, 'hours');\n    assert.equal(a.minutes(), 7, 'minutes');\n    assert.equal(a.seconds(), 8, 'seconds');\n    assert.equal(a.milliseconds(), 9, 'milliseconds');\n});\n\ntest('setters singular', function (assert) {\n    var a = moment();\n    a.year(2011);\n    a.month(9);\n    a.date(12);\n    a.hour(6);\n    a.minute(7);\n    a.second(8);\n    a.millisecond(9);\n    assert.equal(a.year(), 2011, 'year');\n    assert.equal(a.month(), 9, 'month');\n    assert.equal(a.date(), 12, 'date');\n    assert.equal(a.day(), 3, 'day');\n    assert.equal(a.hour(), 6, 'hour');\n    assert.equal(a.minute(), 7, 'minute');\n    assert.equal(a.second(), 8, 'second');\n    assert.equal(a.millisecond(), 9, 'milliseconds');\n});\n\ntest('setters', function (assert) {\n    var a = moment();\n    a.year(2011);\n    a.month(9);\n    a.date(12);\n    a.hours(6);\n    a.minutes(7);\n    a.seconds(8);\n    a.milliseconds(9);\n    assert.equal(a.year(), 2011, 'year');\n    assert.equal(a.month(), 9, 'month');\n    assert.equal(a.date(), 12, 'date');\n    assert.equal(a.day(), 3, 'day');\n    assert.equal(a.hours(), 6, 'hour');\n    assert.equal(a.minutes(), 7, 'minute');\n    assert.equal(a.seconds(), 8, 'second');\n    assert.equal(a.milliseconds(), 9, 'milliseconds');\n\n    // Test month() behavior. See https://github.com/timrwood/moment/pull/822\n    a = moment('20130531', 'YYYYMMDD');\n    a.month(3);\n    assert.equal(a.month(), 3, 'month edge case');\n});\n\ntest('setter programmatic', function (assert) {\n    var a = moment();\n    a.set('year', 2011);\n    a.set('month', 9);\n    a.set('date', 12);\n    a.set('hours', 6);\n    a.set('minutes', 7);\n    a.set('seconds', 8);\n    a.set('milliseconds', 9);\n    assert.equal(a.year(), 2011, 'year');\n    assert.equal(a.month(), 9, 'month');\n    assert.equal(a.date(), 12, 'date');\n    assert.equal(a.day(), 3, 'day');\n    assert.equal(a.hours(), 6, 'hour');\n    assert.equal(a.minutes(), 7, 'minute');\n    assert.equal(a.seconds(), 8, 'second');\n    assert.equal(a.milliseconds(), 9, 'milliseconds');\n\n    // Test month() behavior. See https://github.com/timrwood/moment/pull/822\n    a = moment('20130531', 'YYYYMMDD');\n    a.month(3);\n    assert.equal(a.month(), 3, 'month edge case');\n});\n\ntest('setters programatic with weeks', function (assert) {\n    var a = moment();\n    a.set('weekYear', 2001);\n    a.set('week', 49);\n    a.set('day', 4);\n\n    assert.equal(a.weekYear(), 2001, 'weekYear');\n    assert.equal(a.week(), 49, 'week');\n    assert.equal(a.day(), 4, 'day');\n\n    a.set('weekday', 1);\n    assert.equal(a.weekday(), 1, 'weekday');\n});\n\ntest('setters programatic with weeks ISO', function (assert) {\n    var a = moment();\n    a.set('isoWeekYear', 2001);\n    a.set('isoWeek', 49);\n    a.set('isoWeekday', 4);\n\n    assert.equal(a.isoWeekYear(), 2001, 'isoWeekYear');\n    assert.equal(a.isoWeek(), 49, 'isoWeek');\n    assert.equal(a.isoWeekday(), 4, 'isoWeekday');\n});\n\ntest('setters strings', function (assert) {\n    var a = moment([2012]).locale('en');\n    assert.equal(a.clone().day(0).day('Wednesday').day(), 3, 'day full name');\n    assert.equal(a.clone().day(0).day('Wed').day(), 3, 'day short name');\n    assert.equal(a.clone().day(0).day('We').day(), 3, 'day minimal name');\n    assert.equal(a.clone().day(0).day('invalid').day(), 0, 'invalid day name');\n    assert.equal(a.clone().month(0).month('April').month(), 3, 'month full name');\n    assert.equal(a.clone().month(0).month('Apr').month(), 3, 'month short name');\n    assert.equal(a.clone().month(0).month('invalid').month(), 0, 'invalid month name');\n});\n\ntest('setters - falsey values', function (assert) {\n    var a = moment();\n    // ensure minutes wasn't coincidentally 0 already\n    a.minutes(1);\n    a.minutes(0);\n    assert.equal(a.minutes(), 0, 'falsey value');\n});\n\ntest('chaining setters', function (assert) {\n    var a = moment();\n    a.year(2011)\n     .month(9)\n     .date(12)\n     .hours(6)\n     .minutes(7)\n     .seconds(8);\n    assert.equal(a.year(), 2011, 'year');\n    assert.equal(a.month(), 9, 'month');\n    assert.equal(a.date(), 12, 'date');\n    assert.equal(a.day(), 3, 'day');\n    assert.equal(a.hours(), 6, 'hour');\n    assert.equal(a.minutes(), 7, 'minute');\n    assert.equal(a.seconds(), 8, 'second');\n});\n\ntest('setter with multiple unit values', function (assert) {\n    var a = moment();\n    a.set({\n        year: 2011,\n        month: 9,\n        date: 12,\n        hours: 6,\n        minutes: 7,\n        seconds: 8,\n        milliseconds: 9\n    });\n    assert.equal(a.year(), 2011, 'year');\n    assert.equal(a.month(), 9, 'month');\n    assert.equal(a.date(), 12, 'date');\n    assert.equal(a.day(), 3, 'day');\n    assert.equal(a.hours(), 6, 'hour');\n    assert.equal(a.minutes(), 7, 'minute');\n    assert.equal(a.seconds(), 8, 'second');\n    assert.equal(a.milliseconds(), 9, 'milliseconds');\n\n    var c = moment([2016,0,1]);\n    assert.equal(c.set({weekYear: 2016}).weekYear(), 2016, 'week year correctly sets with object syntax');\n    assert.equal(c.set({quarter: 3}).quarter(), 3, 'quarter sets correctly with object syntax');\n});\n\ntest('day setter', function (assert) {\n    var a = moment([2011, 0, 15]);\n    assert.equal(moment(a).day(0).date(), 9, 'set from saturday to sunday');\n    assert.equal(moment(a).day(6).date(), 15, 'set from saturday to saturday');\n    assert.equal(moment(a).day(3).date(), 12, 'set from saturday to wednesday');\n\n    a = moment([2011, 0, 9]);\n    assert.equal(moment(a).day(0).date(), 9, 'set from sunday to sunday');\n    assert.equal(moment(a).day(6).date(), 15, 'set from sunday to saturday');\n    assert.equal(moment(a).day(3).date(), 12, 'set from sunday to wednesday');\n\n    a = moment([2011, 0, 12]);\n    assert.equal(moment(a).day(0).date(), 9, 'set from wednesday to sunday');\n    assert.equal(moment(a).day(6).date(), 15, 'set from wednesday to saturday');\n    assert.equal(moment(a).day(3).date(), 12, 'set from wednesday to wednesday');\n\n    assert.equal(moment(a).day(-7).date(), 2, 'set from wednesday to last sunday');\n    assert.equal(moment(a).day(-1).date(), 8, 'set from wednesday to last saturday');\n    assert.equal(moment(a).day(-4).date(), 5, 'set from wednesday to last wednesday');\n\n    assert.equal(moment(a).day(7).date(), 16, 'set from wednesday to next sunday');\n    assert.equal(moment(a).day(13).date(), 22, 'set from wednesday to next saturday');\n    assert.equal(moment(a).day(10).date(), 19, 'set from wednesday to next wednesday');\n\n    assert.equal(moment(a).day(14).date(), 23, 'set from wednesday to second next sunday');\n    assert.equal(moment(a).day(20).date(), 29, 'set from wednesday to second next saturday');\n    assert.equal(moment(a).day(17).date(), 26, 'set from wednesday to second next wednesday');\n});\n\ntest('object set ordering', function (assert) {\n    var a = moment([2016,3,30]);\n    assert.equal(a.set({date:31, month:4}).date(), 31, 'setter order automatically arranged by size');\n    var b = moment([2015,1,28]);\n    assert.equal(b.set({date:29, year: 2016}).format('YYYY-MM-DD'), '2016-02-29', 'year is prioritized over date');\n    //check a nonexistent time in US isn't set\n    var c = moment([2016,2,13]);\n    c.set({\n        hour:2,\n        minutes:30,\n        date: 14\n    });\n    assert.equal(c.format('YYYY-MM-DDTHH:mm'), '2016-03-14T02:30', 'setting hours, minutes date puts date first allowing time set to work');\n});\n\ntest('string setters', function (assert) {\n    var a = moment();\n    a.year('2011');\n    a.month('9');\n    a.date('12');\n    a.hours('6');\n    a.minutes('7');\n    a.seconds('8');\n    a.milliseconds('9');\n    assert.equal(a.year(), 2011, 'year');\n    assert.equal(a.month(), 9, 'month');\n    assert.equal(a.date(), 12, 'date');\n    assert.equal(a.day(), 3, 'day');\n    assert.equal(a.hours(), 6, 'hour');\n    assert.equal(a.minutes(), 7, 'minute');\n    assert.equal(a.seconds(), 8, 'second');\n    assert.equal(a.milliseconds(), 9, 'milliseconds');\n});\n\ntest('setters across DST +1', function (assert) {\n    var oldUpdateOffset = moment.updateOffset,\n        // Based on a real story somewhere in America/Los_Angeles\n        dstAt = moment('2014-03-09T02:00:00-08:00').parseZone(),\n        m;\n\n    moment.updateOffset = function (mom, keepTime) {\n        if (mom.isBefore(dstAt)) {\n            mom.utcOffset(-8, keepTime);\n        } else {\n            mom.utcOffset(-7, keepTime);\n        }\n    };\n\n    m = moment('2014-03-15T00:00:00-07:00').parseZone();\n    m.year(2013);\n    assert.equal(m.format(), '2013-03-15T00:00:00-08:00', 'year across +1');\n\n    m = moment('2014-03-15T00:00:00-07:00').parseZone();\n    m.month(0);\n    assert.equal(m.format(), '2014-01-15T00:00:00-08:00', 'month across +1');\n\n    m = moment('2014-03-15T00:00:00-07:00').parseZone();\n    m.date(1);\n    assert.equal(m.format(), '2014-03-01T00:00:00-08:00', 'date across +1');\n\n    m = moment('2014-03-09T03:05:00-07:00').parseZone();\n    m.hour(0);\n    assert.equal(m.format(), '2014-03-09T00:05:00-08:00', 'hour across +1');\n\n    moment.updateOffset = oldUpdateOffset;\n});\n\ntest('setters across DST -1', function (assert) {\n    var oldUpdateOffset = moment.updateOffset,\n        // Based on a real story somewhere in America/Los_Angeles\n        dstAt = moment('2014-11-02T02:00:00-07:00').parseZone(),\n        m;\n\n    moment.updateOffset = function (mom, keepTime) {\n        if (mom.isBefore(dstAt)) {\n            mom.utcOffset(-7, keepTime);\n        } else {\n            mom.utcOffset(-8, keepTime);\n        }\n    };\n\n    m = moment('2014-11-15T00:00:00-08:00').parseZone();\n    m.year(2013);\n    assert.equal(m.format(), '2013-11-15T00:00:00-07:00', 'year across -1');\n\n    m = moment('2014-11-15T00:00:00-08:00').parseZone();\n    m.month(0);\n    assert.equal(m.format(), '2014-01-15T00:00:00-07:00', 'month across -1');\n\n    m = moment('2014-11-15T00:00:00-08:00').parseZone();\n    m.date(1);\n    assert.equal(m.format(), '2014-11-01T00:00:00-07:00', 'date across -1');\n\n    m = moment('2014-11-02T03:30:00-08:00').parseZone();\n    m.hour(0);\n    assert.equal(m.format(), '2014-11-02T00:30:00-07:00', 'hour across -1');\n\n    moment.updateOffset = oldUpdateOffset;\n});\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/test/moment/instanceof.js",
    "content": "import { module, test } from '../qunit';\nimport moment from '../../moment';\n\nmodule('instanceof');\n\ntest('instanceof', function (assert) {\n    var mm = moment([2010, 0, 1]);\n\n    var extend = function (a, b) {\n        var i;\n        for (i in b) {\n            a[i] = b[i];\n        }\n        return a;\n    };\n\n    assert.equal(moment() instanceof moment, true, 'simple moment object');\n    assert.equal(extend({}, moment()) instanceof moment, false, 'extended moment object');\n    assert.equal(moment(null) instanceof moment, true, 'invalid moment object');\n\n    assert.equal(new Date() instanceof moment, false, 'date object is not moment object');\n    assert.equal(Object instanceof moment, false, 'Object is not moment object');\n    assert.equal('foo' instanceof moment, false, 'string is not moment object');\n    assert.equal(1 instanceof moment, false, 'number is not moment object');\n    assert.equal(NaN instanceof moment, false, 'NaN is not moment object');\n    assert.equal(null instanceof moment, false, 'null is not moment object');\n    assert.equal(undefined instanceof moment, false, 'undefined is not moment object');\n});\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/test/moment/invalid.js",
    "content": "import { module, test } from '../qunit';\nimport moment from '../../moment';\n\nmodule('invalid');\n\ntest('invalid', function (assert) {\n    var m = moment.invalid();\n    assert.equal(m.isValid(), false);\n    assert.equal(m.parsingFlags().userInvalidated, true);\n    assert.ok(isNaN(m.valueOf()));\n});\n\ntest('invalid with existing flag', function (assert) {\n    var m = moment.invalid({invalidMonth : 'whatchamacallit'});\n    assert.equal(m.isValid(), false);\n    assert.equal(m.parsingFlags().userInvalidated, false);\n    assert.equal(m.parsingFlags().invalidMonth, 'whatchamacallit');\n    assert.ok(isNaN(m.valueOf()));\n});\n\ntest('invalid with custom flag', function (assert) {\n    var m = moment.invalid({tooBusyWith : 'reiculating splines'});\n    assert.equal(m.isValid(), false);\n    assert.equal(m.parsingFlags().userInvalidated, false);\n    assert.equal(m.parsingFlags().tooBusyWith, 'reiculating splines');\n    assert.ok(isNaN(m.valueOf()));\n});\n\ntest('invalid operations', function (assert) {\n    var invalids = [\n            moment.invalid(),\n            moment('xyz', 'l'),\n            moment('2015-01-35', 'YYYY-MM-DD'),\n            moment('2015-01-25 a', 'YYYY-MM-DD', true)\n        ],\n        i,\n        invalid,\n        valid = moment();\n\n    test.expectedDeprecations('moment().min', 'moment().max', 'isDSTShifted');\n\n    for (i = 0; i < invalids.length; ++i) {\n        invalid = invalids[i];\n\n        assert.ok(!invalid.clone().add(5, 'hours').isValid(), 'invalid.add is invalid');\n        assert.equal(invalid.calendar(), 'Invalid date', 'invalid.calendar is \\'Invalid date\\'');\n        assert.ok(!invalid.clone().isValid(), 'invalid.clone is invalid');\n        assert.ok(isNaN(invalid.diff(valid)), 'invalid.diff(valid) is NaN');\n        assert.ok(isNaN(valid.diff(invalid)), 'valid.diff(invalid) is NaN');\n        assert.ok(isNaN(invalid.diff(invalid)), 'invalid.diff(invalid) is NaN');\n        assert.ok(!invalid.clone().endOf('month').isValid(), 'invalid.endOf is invalid');\n        assert.equal(invalid.format(), 'Invalid date', 'invalid.format is \\'Invalid date\\'');\n        assert.equal(invalid.from(), 'Invalid date');\n        assert.equal(invalid.from(valid), 'Invalid date');\n        assert.equal(valid.from(invalid), 'Invalid date');\n        assert.equal(invalid.fromNow(), 'Invalid date');\n        assert.equal(invalid.to(), 'Invalid date');\n        assert.equal(invalid.to(valid), 'Invalid date');\n        assert.equal(valid.to(invalid), 'Invalid date');\n        assert.equal(invalid.toNow(), 'Invalid date');\n        assert.ok(isNaN(invalid.get('year')), 'invalid.get is NaN');\n        // TODO invalidAt\n        assert.ok(!invalid.isAfter(valid));\n        assert.ok(!valid.isAfter(invalid));\n        assert.ok(!invalid.isAfter(invalid));\n        assert.ok(!invalid.isBefore(valid));\n        assert.ok(!valid.isBefore(invalid));\n        assert.ok(!invalid.isBefore(invalid));\n        assert.ok(!invalid.isBetween(valid, valid));\n        assert.ok(!valid.isBetween(invalid, valid));\n        assert.ok(!valid.isBetween(valid, invalid));\n        assert.ok(!invalid.isSame(invalid));\n        assert.ok(!invalid.isSame(valid));\n        assert.ok(!valid.isSame(invalid));\n        assert.ok(!invalid.isValid());\n        assert.equal(invalid.locale(), 'en');\n        assert.equal(invalid.localeData()._abbr, 'en');\n        assert.ok(!invalid.clone().max(valid).isValid());\n        assert.ok(!valid.clone().max(invalid).isValid());\n        assert.ok(!invalid.clone().max(invalid).isValid());\n        assert.ok(!invalid.clone().min(valid).isValid());\n        assert.ok(!valid.clone().min(invalid).isValid());\n        assert.ok(!invalid.clone().min(invalid).isValid());\n        assert.ok(!moment.min(invalid, valid).isValid());\n        assert.ok(!moment.min(valid, invalid).isValid());\n        assert.ok(!moment.max(invalid, valid).isValid());\n        assert.ok(!moment.max(valid, invalid).isValid());\n        assert.ok(!invalid.clone().set('year', 2005).isValid());\n        assert.ok(!invalid.clone().startOf('month').isValid());\n\n        assert.ok(!invalid.clone().subtract(5, 'days').isValid());\n        assert.deepEqual(invalid.toArray(), [NaN, NaN, NaN, NaN, NaN, NaN, NaN]);\n        assert.deepEqual(invalid.toObject(), {\n            years: NaN,\n            months: NaN,\n            date: NaN,\n            hours: NaN,\n            minutes: NaN,\n            seconds: NaN,\n            milliseconds: NaN\n        });\n        assert.ok(moment.isDate(invalid.toDate()));\n        assert.ok(isNaN(invalid.toDate().valueOf()));\n        assert.equal(invalid.toJSON(), null);\n        assert.equal(invalid.toString(), 'Invalid date');\n        assert.ok(isNaN(invalid.unix()));\n        assert.ok(isNaN(invalid.valueOf()));\n\n        assert.ok(isNaN(invalid.year()));\n        assert.ok(isNaN(invalid.weekYear()));\n        assert.ok(isNaN(invalid.isoWeekYear()));\n        assert.ok(isNaN(invalid.quarter()));\n        assert.ok(isNaN(invalid.quarters()));\n        assert.ok(isNaN(invalid.month()));\n        assert.ok(isNaN(invalid.daysInMonth()));\n        assert.ok(isNaN(invalid.week()));\n        assert.ok(isNaN(invalid.weeks()));\n        assert.ok(isNaN(invalid.isoWeek()));\n        assert.ok(isNaN(invalid.isoWeeks()));\n        assert.ok(isNaN(invalid.weeksInYear()));\n        assert.ok(isNaN(invalid.isoWeeksInYear()));\n        assert.ok(isNaN(invalid.date()));\n        assert.ok(isNaN(invalid.day()));\n        assert.ok(isNaN(invalid.days()));\n        assert.ok(isNaN(invalid.weekday()));\n        assert.ok(isNaN(invalid.isoWeekday()));\n        assert.ok(isNaN(invalid.dayOfYear()));\n        assert.ok(isNaN(invalid.hour()));\n        assert.ok(isNaN(invalid.hours()));\n        assert.ok(isNaN(invalid.minute()));\n        assert.ok(isNaN(invalid.minutes()));\n        assert.ok(isNaN(invalid.second()));\n        assert.ok(isNaN(invalid.seconds()));\n        assert.ok(isNaN(invalid.millisecond()));\n        assert.ok(isNaN(invalid.milliseconds()));\n        assert.ok(isNaN(invalid.utcOffset()));\n\n        assert.ok(!invalid.clone().year(2001).isValid());\n        assert.ok(!invalid.clone().weekYear(2001).isValid());\n        assert.ok(!invalid.clone().isoWeekYear(2001).isValid());\n        assert.ok(!invalid.clone().quarter(1).isValid());\n        assert.ok(!invalid.clone().quarters(1).isValid());\n        assert.ok(!invalid.clone().month(1).isValid());\n        assert.ok(!invalid.clone().week(1).isValid());\n        assert.ok(!invalid.clone().weeks(1).isValid());\n        assert.ok(!invalid.clone().isoWeek(1).isValid());\n        assert.ok(!invalid.clone().isoWeeks(1).isValid());\n        assert.ok(!invalid.clone().date(1).isValid());\n        assert.ok(!invalid.clone().day(1).isValid());\n        assert.ok(!invalid.clone().days(1).isValid());\n        assert.ok(!invalid.clone().weekday(1).isValid());\n        assert.ok(!invalid.clone().isoWeekday(1).isValid());\n        assert.ok(!invalid.clone().dayOfYear(1).isValid());\n        assert.ok(!invalid.clone().hour(1).isValid());\n        assert.ok(!invalid.clone().hours(1).isValid());\n        assert.ok(!invalid.clone().minute(1).isValid());\n        assert.ok(!invalid.clone().minutes(1).isValid());\n        assert.ok(!invalid.clone().second(1).isValid());\n        assert.ok(!invalid.clone().seconds(1).isValid());\n        assert.ok(!invalid.clone().millisecond(1).isValid());\n        assert.ok(!invalid.clone().milliseconds(1).isValid());\n        assert.ok(!invalid.clone().utcOffset(1).isValid());\n\n        assert.ok(!invalid.clone().utc().isValid());\n        assert.ok(!invalid.clone().local().isValid());\n        assert.ok(!invalid.clone().parseZone('05:30').isValid());\n        assert.ok(!invalid.hasAlignedHourOffset());\n        assert.ok(!invalid.isDST());\n        assert.ok(!invalid.isDSTShifted());\n        assert.ok(!invalid.isLocal());\n        assert.ok(!invalid.isUtcOffset());\n        assert.ok(!invalid.isUtc());\n        assert.ok(!invalid.isUTC());\n\n        assert.ok(!invalid.isLeapYear());\n\n        assert.equal(moment.duration({from: invalid, to: valid}).asMilliseconds(), 0);\n        assert.equal(moment.duration({from: valid, to: invalid}).asMilliseconds(), 0);\n        assert.equal(moment.duration({from: invalid, to: invalid}).asMilliseconds(), 0);\n    }\n});\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/test/moment/is_after.js",
    "content": "import { module, test } from '../qunit';\nimport moment from '../../moment';\n\nmodule('is after');\n\ntest('is after without units', function (assert) {\n    var m = moment(new Date(2011, 3, 2, 3, 4, 5, 10)), mCopy = moment(m);\n    assert.equal(m.isAfter(moment(new Date(2012, 3, 2, 3, 5, 5, 10))), false, 'year is later');\n    assert.equal(m.isAfter(moment(new Date(2010, 3, 2, 3, 3, 5, 10))), true, 'year is earlier');\n    assert.equal(m.isAfter(moment(new Date(2011, 4, 2, 3, 4, 5, 10))), false, 'month is later');\n    assert.equal(m.isAfter(moment(new Date(2011, 2, 2, 3, 4, 5, 10))), true, 'month is earlier');\n    assert.equal(m.isAfter(moment(new Date(2011, 3, 3, 3, 4, 5, 10))), false, 'day is later');\n    assert.equal(m.isAfter(moment(new Date(2011, 3, 1, 3, 4, 5, 10))), true, 'day is earlier');\n    assert.equal(m.isAfter(moment(new Date(2011, 3, 2, 4, 4, 5, 10))), false, 'hour is later');\n    assert.equal(m.isAfter(moment(new Date(2011, 3, 2, 2, 4, 5, 10))), true, 'hour is earlier');\n    assert.equal(m.isAfter(moment(new Date(2011, 3, 2, 3, 5, 5, 10))), false, 'minute is later');\n    assert.equal(m.isAfter(moment(new Date(2011, 3, 2, 3, 3, 5, 10))), true, 'minute is earlier');\n    assert.equal(m.isAfter(moment(new Date(2011, 3, 2, 3, 4, 6, 10))), false, 'second is later');\n    assert.equal(m.isAfter(moment(new Date(2011, 3, 2, 3, 4, 4, 11))), true, 'second is earlier');\n    assert.equal(m.isAfter(moment(new Date(2011, 3, 2, 3, 4, 5, 10))), false, 'millisecond match');\n    assert.equal(m.isAfter(moment(new Date(2011, 3, 2, 3, 4, 5, 11))), false, 'millisecond is later');\n    assert.equal(m.isAfter(moment(new Date(2011, 3, 2, 3, 4, 5, 9))), true, 'millisecond is earlier');\n    assert.equal(m.isAfter(m), false, 'moments are not after themselves');\n    assert.equal(+m, +mCopy, 'isAfter second should not change moment');\n});\n\ntest('is after year', function (assert) {\n    var m = moment(new Date(2011, 1, 2, 3, 4, 5, 6)), mCopy = moment(m);\n    assert.equal(m.isAfter(moment(new Date(2011, 5, 6, 7, 8, 9, 10)), 'year'), false, 'year match');\n    assert.equal(m.isAfter(moment(new Date(2010, 5, 6, 7, 8, 9, 10)), 'years'), true, 'plural should work');\n    assert.equal(m.isAfter(moment(new Date(2013, 5, 6, 7, 8, 9, 10)), 'year'), false, 'year is later');\n    assert.equal(m.isAfter(moment(new Date(2010, 5, 6, 7, 8, 9, 10)), 'year'), true, 'year is earlier');\n    assert.equal(m.isAfter(moment(new Date(2011, 0, 1, 0, 0, 0, 0)), 'year'), false, 'exact start of year');\n    assert.equal(m.isAfter(moment(new Date(2011, 11, 31, 23, 59, 59, 999)), 'year'), false, 'exact end of year');\n    assert.equal(m.isAfter(moment(new Date(2012, 0, 1, 0, 0, 0, 0)), 'year'), false, 'start of next year');\n    assert.equal(m.isAfter(moment(new Date(2010, 11, 31, 23, 59, 59, 999)), 'year'), true, 'end of previous year');\n    assert.equal(m.isAfter(moment(new Date(1980, 11, 31, 23, 59, 59, 999)), 'year'), true, 'end of year far before');\n    assert.equal(m.isAfter(m, 'year'), false, 'same moments are not after the same year');\n    assert.equal(+m, +mCopy, 'isAfter year should not change moment');\n});\n\ntest('is after month', function (assert) {\n    var m = moment(new Date(2011, 2, 3, 4, 5, 6, 7)), mCopy = moment(m);\n    assert.equal(m.isAfter(moment(new Date(2011, 2, 6, 7, 8, 9, 10)), 'month'), false, 'month match');\n    assert.equal(m.isAfter(moment(new Date(2010, 2, 6, 7, 8, 9, 10)), 'months'), true, 'plural should work');\n    assert.equal(m.isAfter(moment(new Date(2012, 2, 6, 7, 8, 9, 10)), 'month'), false, 'year is later');\n    assert.equal(m.isAfter(moment(new Date(2010, 2, 6, 7, 8, 9, 10)), 'month'), true, 'year is earlier');\n    assert.equal(m.isAfter(moment(new Date(2011, 5, 6, 7, 8, 9, 10)), 'month'), false, 'month is later');\n    assert.equal(m.isAfter(moment(new Date(2011, 1, 6, 7, 8, 9, 10)), 'month'), true, 'month is earlier');\n    assert.equal(m.isAfter(moment(new Date(2011, 2, 1, 0, 0, 0, 0)), 'month'), false, 'exact start of month');\n    assert.equal(m.isAfter(moment(new Date(2011, 2, 31, 23, 59, 59, 999)), 'month'), false, 'exact end of month');\n    assert.equal(m.isAfter(moment(new Date(2011, 3, 1, 0, 0, 0, 0)), 'month'), false, 'start of next month');\n    assert.equal(m.isAfter(moment(new Date(2011, 1, 27, 23, 59, 59, 999)), 'month'), true, 'end of previous month');\n    assert.equal(m.isAfter(moment(new Date(2010, 12, 31, 23, 59, 59, 999)), 'month'), true, 'later month but earlier year');\n    assert.equal(m.isAfter(m, 'month'), false, 'same moments are not after the same month');\n    assert.equal(+m, +mCopy, 'isAfter month should not change moment');\n});\n\ntest('is after day', function (assert) {\n    var m = moment(new Date(2011, 3, 2, 3, 4, 5, 6)), mCopy = moment(m);\n    assert.equal(m.isAfter(moment(new Date(2011, 3, 2, 7, 8, 9, 10)), 'day'), false, 'day match');\n    assert.equal(m.isAfter(moment(new Date(2010, 3, 2, 7, 8, 9, 10)), 'days'), true, 'plural should work');\n    assert.equal(m.isAfter(moment(new Date(2012, 3, 2, 7, 8, 9, 10)), 'day'), false, 'year is later');\n    assert.equal(m.isAfter(moment(new Date(2010, 3, 2, 7, 8, 9, 10)), 'day'), true, 'year is earlier');\n    assert.equal(m.isAfter(moment(new Date(2011, 4, 2, 7, 8, 9, 10)), 'day'), false, 'month is later');\n    assert.equal(m.isAfter(moment(new Date(2011, 2, 2, 7, 8, 9, 10)), 'day'), true, 'month is earlier');\n    assert.equal(m.isAfter(moment(new Date(2011, 3, 3, 7, 8, 9, 10)), 'day'), false, 'day is later');\n    assert.equal(m.isAfter(moment(new Date(2011, 3, 1, 7, 8, 9, 10)), 'day'), true, 'day is earlier');\n    assert.equal(m.isAfter(moment(new Date(2011, 3, 2, 0, 0, 0, 0)), 'day'), false, 'exact start of day');\n    assert.equal(m.isAfter(moment(new Date(2011, 3, 2, 23, 59, 59, 999)), 'day'), false, 'exact end of day');\n    assert.equal(m.isAfter(moment(new Date(2011, 3, 3, 0, 0, 0, 0)), 'day'), false, 'start of next day');\n    assert.equal(m.isAfter(moment(new Date(2011, 3, 1, 23, 59, 59, 999)), 'day'), true, 'end of previous day');\n    assert.equal(m.isAfter(moment(new Date(2010, 3, 10, 0, 0, 0, 0)), 'day'), true, 'later day but earlier year');\n    assert.equal(m.isAfter(m, 'day'), false, 'same moments are not after the same day');\n    assert.equal(+m, +mCopy, 'isAfter day should not change moment');\n});\n\ntest('is after hour', function (assert) {\n    var m = moment(new Date(2011, 3, 2, 3, 4, 5, 6)), mCopy = moment(m);\n    assert.equal(m.isAfter(moment(new Date(2011, 3, 2, 3, 8, 9, 10)), 'hour'), false, 'hour match');\n    assert.equal(m.isAfter(moment(new Date(2010, 3, 2, 3, 8, 9, 10)), 'hours'), true, 'plural should work');\n    assert.equal(m.isAfter(moment(new Date(2012, 3, 2, 3, 8, 9, 10)), 'hour'), false, 'year is later');\n    assert.equal(m.isAfter(moment(new Date(2010, 3, 2, 3, 8, 9, 10)), 'hour'), true, 'year is earlier');\n    assert.equal(m.isAfter(moment(new Date(2011, 4, 2, 3, 8, 9, 10)), 'hour'), false, 'month is later');\n    assert.equal(m.isAfter(moment(new Date(2011, 1, 2, 3, 8, 9, 10)), 'hour'), true, 'month is earlier');\n    assert.equal(m.isAfter(moment(new Date(2011, 3, 3, 3, 8, 9, 10)), 'hour'), false, 'day is later');\n    assert.equal(m.isAfter(moment(new Date(2011, 3, 1, 3, 8, 9, 10)), 'hour'), true, 'day is earlier');\n    assert.equal(m.isAfter(moment(new Date(2011, 3, 2, 4, 8, 9, 10)), 'hour'), false, 'hour is later');\n    assert.equal(m.isAfter(moment(new Date(2011, 3, 2, 3, 8, 9, 10)), 'hour'), false, 'hour is earlier');\n    assert.equal(m.isAfter(moment(new Date(2011, 3, 2, 3, 0, 0, 0)), 'hour'), false, 'exact start of hour');\n    assert.equal(m.isAfter(moment(new Date(2011, 3, 2, 3, 59, 59, 999)), 'hour'), false, 'exact end of hour');\n    assert.equal(m.isAfter(moment(new Date(2011, 3, 2, 4, 0, 0, 0)), 'hour'), false, 'start of next hour');\n    assert.equal(m.isAfter(moment(new Date(2011, 3, 2, 2, 59, 59, 999)), 'hour'), true, 'end of previous hour');\n    assert.equal(m.isAfter(m, 'hour'), false, 'same moments are not after the same hour');\n    assert.equal(+m, +mCopy, 'isAfter hour should not change moment');\n});\n\ntest('is after minute', function (assert) {\n    var m = moment(new Date(2011, 3, 2, 3, 4, 5, 6)), mCopy = moment(m);\n    assert.equal(m.isAfter(moment(new Date(2011, 3, 2, 3, 4, 9, 10)), 'minute'), false, 'minute match');\n    assert.equal(m.isAfter(moment(new Date(2010, 3, 2, 3, 4, 9, 10)), 'minutes'), true, 'plural should work');\n    assert.equal(m.isAfter(moment(new Date(2012, 3, 2, 3, 4, 9, 10)), 'minute'), false, 'year is later');\n    assert.equal(m.isAfter(moment(new Date(2010, 3, 2, 3, 4, 9, 10)), 'minute'), true, 'year is earlier');\n    assert.equal(m.isAfter(moment(new Date(2011, 4, 2, 3, 4, 9, 10)), 'minute'), false, 'month is later');\n    assert.equal(m.isAfter(moment(new Date(2011, 2, 2, 3, 4, 9, 10)), 'minute'), true, 'month is earlier');\n    assert.equal(m.isAfter(moment(new Date(2011, 3, 3, 3, 4, 9, 10)), 'minute'), false, 'day is later');\n    assert.equal(m.isAfter(moment(new Date(2011, 3, 1, 3, 4, 9, 10)), 'minute'), true, 'day is earlier');\n    assert.equal(m.isAfter(moment(new Date(2011, 3, 2, 4, 4, 9, 10)), 'minute'), false, 'hour is later');\n    assert.equal(m.isAfter(moment(new Date(2011, 3, 2, 2, 4, 9, 10)), 'minute'), true, 'hour is earler');\n    assert.equal(m.isAfter(moment(new Date(2011, 3, 2, 3, 5, 9, 10)), 'minute'), false, 'minute is later');\n    assert.equal(m.isAfter(moment(new Date(2011, 3, 2, 3, 3, 9, 10)), 'minute'), true, 'minute is earlier');\n    assert.equal(m.isAfter(moment(new Date(2011, 3, 2, 3, 4, 0, 0)), 'minute'), false, 'exact start of minute');\n    assert.equal(m.isAfter(moment(new Date(2011, 3, 2, 3, 4, 59, 999)), 'minute'), false, 'exact end of minute');\n    assert.equal(m.isAfter(moment(new Date(2011, 3, 2, 3, 5, 0, 0)), 'minute'), false, 'start of next minute');\n    assert.equal(m.isAfter(moment(new Date(2011, 3, 2, 3, 3, 59, 999)), 'minute'), true, 'end of previous minute');\n    assert.equal(m.isAfter(m, 'minute'), false, 'same moments are not after the same minute');\n    assert.equal(+m, +mCopy, 'isAfter minute should not change moment');\n});\n\ntest('is after second', function (assert) {\n    var m = moment(new Date(2011, 3, 2, 3, 4, 5, 10)), mCopy = moment(m);\n    assert.equal(m.isAfter(moment(new Date(2011, 3, 2, 3, 4, 5, 10)), 'second'), false, 'second match');\n    assert.equal(m.isAfter(moment(new Date(2010, 3, 2, 3, 4, 5, 10)), 'seconds'), true, 'plural should work');\n    assert.equal(m.isAfter(moment(new Date(2012, 3, 2, 3, 4, 5, 10)), 'second'), false, 'year is later');\n    assert.equal(m.isAfter(moment(new Date(2010, 3, 2, 3, 4, 5, 10)), 'second'), true, 'year is earlier');\n    assert.equal(m.isAfter(moment(new Date(2011, 4, 2, 3, 4, 5, 10)), 'second'), false, 'month is later');\n    assert.equal(m.isAfter(moment(new Date(2011, 2, 2, 3, 4, 5, 10)), 'second'), true, 'month is earlier');\n    assert.equal(m.isAfter(moment(new Date(2011, 3, 3, 3, 4, 5, 10)), 'second'), false, 'day is later');\n    assert.equal(m.isAfter(moment(new Date(2011, 3, 1, 1, 4, 5, 10)), 'second'), true, 'day is earlier');\n    assert.equal(m.isAfter(moment(new Date(2011, 3, 2, 4, 4, 5, 10)), 'second'), false, 'hour is later');\n    assert.equal(m.isAfter(moment(new Date(2011, 3, 1, 4, 1, 5, 10)), 'second'), true, 'hour is earlier');\n    assert.equal(m.isAfter(moment(new Date(2011, 3, 2, 3, 5, 5, 10)), 'second'), false, 'minute is later');\n    assert.equal(m.isAfter(moment(new Date(2011, 3, 2, 3, 3, 5, 10)), 'second'), true, 'minute is earlier');\n    assert.equal(m.isAfter(moment(new Date(2011, 3, 2, 3, 4, 6, 10)), 'second'), false, 'second is later');\n    assert.equal(m.isAfter(moment(new Date(2011, 3, 2, 3, 4, 4, 5)), 'second'), true, 'second is earlier');\n    assert.equal(m.isAfter(moment(new Date(2011, 3, 2, 3, 4, 5, 0)), 'second'), false, 'exact start of second');\n    assert.equal(m.isAfter(moment(new Date(2011, 3, 2, 3, 4, 5, 999)), 'second'), false, 'exact end of second');\n    assert.equal(m.isAfter(moment(new Date(2011, 3, 2, 3, 4, 6, 0)), 'second'), false, 'start of next second');\n    assert.equal(m.isAfter(moment(new Date(2011, 3, 2, 3, 4, 4, 999)), 'second'), true, 'end of previous second');\n    assert.equal(m.isAfter(m, 'second'), false, 'same moments are not after the same second');\n    assert.equal(+m, +mCopy, 'isAfter second should not change moment');\n});\n\ntest('is after millisecond', function (assert) {\n    var m = moment(new Date(2011, 3, 2, 3, 4, 5, 10)), mCopy = moment(m);\n    assert.equal(m.isAfter(moment(new Date(2011, 3, 2, 3, 4, 5, 10)), 'millisecond'), false, 'millisecond match');\n    assert.equal(m.isAfter(moment(new Date(2010, 3, 2, 3, 4, 5, 10)), 'milliseconds'), true, 'plural should work');\n    assert.equal(m.isAfter(moment(new Date(2012, 3, 2, 3, 4, 5, 10)), 'millisecond'), false, 'year is later');\n    assert.equal(m.isAfter(moment(new Date(2010, 3, 2, 3, 4, 5, 10)), 'millisecond'), true, 'year is earlier');\n    assert.equal(m.isAfter(moment(new Date(2011, 4, 2, 3, 4, 5, 10)), 'millisecond'), false, 'month is later');\n    assert.equal(m.isAfter(moment(new Date(2011, 2, 2, 3, 4, 5, 10)), 'millisecond'), true, 'month is earlier');\n    assert.equal(m.isAfter(moment(new Date(2011, 3, 3, 3, 4, 5, 10)), 'millisecond'), false, 'day is later');\n    assert.equal(m.isAfter(moment(new Date(2011, 3, 1, 1, 4, 5, 10)), 'millisecond'), true, 'day is earlier');\n    assert.equal(m.isAfter(moment(new Date(2011, 3, 2, 4, 4, 5, 10)), 'millisecond'), false, 'hour is later');\n    assert.equal(m.isAfter(moment(new Date(2011, 3, 1, 4, 1, 5, 10)), 'millisecond'), true, 'hour is earlier');\n    assert.equal(m.isAfter(moment(new Date(2011, 3, 2, 3, 5, 5, 10)), 'millisecond'), false, 'minute is later');\n    assert.equal(m.isAfter(moment(new Date(2011, 3, 2, 3, 3, 5, 10)), 'millisecond'), true, 'minute is earlier');\n    assert.equal(m.isAfter(moment(new Date(2011, 3, 2, 3, 4, 6, 10)), 'millisecond'), false, 'second is later');\n    assert.equal(m.isAfter(moment(new Date(2011, 3, 2, 3, 4, 4, 5)), 'millisecond'), true, 'second is earlier');\n    assert.equal(m.isAfter(moment(new Date(2011, 3, 2, 3, 4, 6, 11)), 'millisecond'), false, 'millisecond is later');\n    assert.equal(m.isAfter(moment(new Date(2011, 3, 2, 3, 4, 4, 9)), 'millisecond'), true, 'millisecond is earlier');\n    assert.equal(m.isAfter(m, 'millisecond'), false, 'same moments are not after the same millisecond');\n    assert.equal(+m, +mCopy, 'isAfter millisecond should not change moment');\n});\n\ntest('is after invalid', function (assert) {\n    var m = moment(), invalid = moment.invalid();\n    assert.equal(m.isAfter(invalid), false, 'valid moment is not after invalid moment');\n    assert.equal(invalid.isAfter(m), false, 'invalid moment is not after valid moment');\n    assert.equal(m.isAfter(invalid, 'year'), false, 'invalid moment year');\n    assert.equal(m.isAfter(invalid, 'month'), false, 'invalid moment month');\n    assert.equal(m.isAfter(invalid, 'day'), false, 'invalid moment day');\n    assert.equal(m.isAfter(invalid, 'hour'), false, 'invalid moment hour');\n    assert.equal(m.isAfter(invalid, 'minute'), false, 'invalid moment minute');\n    assert.equal(m.isAfter(invalid, 'second'), false, 'invalid moment second');\n    assert.equal(m.isAfter(invalid, 'milliseconds'), false, 'invalid moment milliseconds');\n});\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/test/moment/is_array.js",
    "content": "import { module, test } from '../qunit';\nimport isArray from '../../lib/utils/is-array.js';\n\n\ntest('isArray recognizes Array objects', function (assert) {\n    assert.ok(isArray([1,2,3]), 'array args');\n    assert.ok(isArray([]), 'empty array');\n    assert.ok(isArray(new Array(1,2,3)), 'array constructor');\n});\n\ntest('isArray rejects non-Array objects', function (assert) {\n    assert.ok(!isArray(), 'nothing');\n    assert.ok(!isArray(undefined), 'undefined');\n    assert.ok(!isArray(null), 'null');\n    assert.ok(!isArray(123), 'number');\n    assert.ok(!isArray('[1,2,3]'), 'string');\n    assert.ok(!isArray(new Date()), 'date');\n    assert.ok(!isArray({a:1,b:2}), 'object');\n});\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/test/moment/is_before.js",
    "content": "import { module, test } from '../qunit';\nimport moment from '../../moment';\n\nmodule('is before');\n\ntest('is after without units', function (assert) {\n    var m = moment(new Date(2011, 3, 2, 3, 4, 5, 10)), mCopy = moment(m);\n    assert.equal(m.isBefore(moment(new Date(2012, 3, 2, 3, 5, 5, 10))), true, 'year is later');\n    assert.equal(m.isBefore(moment(new Date(2010, 3, 2, 3, 3, 5, 10))), false, 'year is earlier');\n    assert.equal(m.isBefore(moment(new Date(2011, 4, 2, 3, 4, 5, 10))), true, 'month is later');\n    assert.equal(m.isBefore(moment(new Date(2011, 2, 2, 3, 4, 5, 10))), false, 'month is earlier');\n    assert.equal(m.isBefore(moment(new Date(2011, 3, 3, 3, 4, 5, 10))), true, 'day is later');\n    assert.equal(m.isBefore(moment(new Date(2011, 3, 1, 3, 4, 5, 10))), false, 'day is earlier');\n    assert.equal(m.isBefore(moment(new Date(2011, 3, 2, 4, 4, 5, 10))), true, 'hour is later');\n    assert.equal(m.isBefore(moment(new Date(2011, 3, 2, 2, 4, 5, 10))), false, 'hour is earlier');\n    assert.equal(m.isBefore(moment(new Date(2011, 3, 2, 3, 5, 5, 10))), true, 'minute is later');\n    assert.equal(m.isBefore(moment(new Date(2011, 3, 2, 3, 3, 5, 10))), false, 'minute is earlier');\n    assert.equal(m.isBefore(moment(new Date(2011, 3, 2, 3, 4, 6, 10))), true, 'second is later');\n    assert.equal(m.isBefore(moment(new Date(2011, 3, 2, 3, 4, 4, 11))), false, 'second is earlier');\n    assert.equal(m.isBefore(moment(new Date(2011, 3, 2, 3, 4, 5, 10))), false, 'millisecond match');\n    assert.equal(m.isBefore(moment(new Date(2011, 3, 2, 3, 4, 5, 11))), true, 'millisecond is later');\n    assert.equal(m.isBefore(moment(new Date(2011, 3, 2, 3, 4, 5, 9))), false, 'millisecond is earlier');\n    assert.equal(m.isBefore(m), false, 'moments are not before themselves');\n    assert.equal(+m, +mCopy, 'isBefore second should not change moment');\n});\n\ntest('is before year', function (assert) {\n    var m = moment(new Date(2011, 1, 2, 3, 4, 5, 6)), mCopy = moment(m);\n    assert.equal(m.isBefore(moment(new Date(2011, 5, 6, 7, 8, 9, 10)), 'year'), false, 'year match');\n    assert.equal(m.isBefore(moment(new Date(2012, 5, 6, 7, 8, 9, 10)), 'years'), true, 'plural should work');\n    assert.equal(m.isBefore(moment(new Date(2013, 5, 6, 7, 8, 9, 10)), 'year'), true, 'year is later');\n    assert.equal(m.isBefore(moment(new Date(2010, 5, 6, 7, 8, 9, 10)), 'year'), false, 'year is earlier');\n    assert.equal(m.isBefore(moment(new Date(2011, 0, 1, 0, 0, 0, 0)), 'year'), false, 'exact start of year');\n    assert.equal(m.isBefore(moment(new Date(2011, 11, 31, 23, 59, 59, 999)), 'year'), false, 'exact end of year');\n    assert.equal(m.isBefore(moment(new Date(2012, 0, 1, 0, 0, 0, 0)), 'year'), true, 'start of next year');\n    assert.equal(m.isBefore(moment(new Date(2010, 11, 31, 23, 59, 59, 999)), 'year'), false, 'end of previous year');\n    assert.equal(m.isBefore(moment(new Date(1980, 11, 31, 23, 59, 59, 999)), 'year'), false, 'end of year far before');\n    assert.equal(m.isBefore(m, 'year'), false, 'same moments are not before the same year');\n    assert.equal(+m, +mCopy, 'isBefore year should not change moment');\n});\n\ntest('is before month', function (assert) {\n    var m = moment(new Date(2011, 2, 3, 4, 5, 6, 7)), mCopy = moment(m);\n    assert.equal(m.isBefore(moment(new Date(2011, 2, 6, 7, 8, 9, 10)), 'month'), false, 'month match');\n    assert.equal(m.isBefore(moment(new Date(2012, 2, 6, 7, 8, 9, 10)), 'months'), true, 'plural should work');\n    assert.equal(m.isBefore(moment(new Date(2012, 2, 6, 7, 8, 9, 10)), 'month'), true, 'year is later');\n    assert.equal(m.isBefore(moment(new Date(2010, 2, 6, 7, 8, 9, 10)), 'month'), false, 'year is earlier');\n    assert.equal(m.isBefore(moment(new Date(2011, 5, 6, 7, 8, 9, 10)), 'month'), true, 'month is later');\n    assert.equal(m.isBefore(moment(new Date(2011, 1, 6, 7, 8, 9, 10)), 'month'), false, 'month is earlier');\n    assert.equal(m.isBefore(moment(new Date(2011, 2, 1, 0, 0, 0, 0)), 'month'), false, 'exact start of month');\n    assert.equal(m.isBefore(moment(new Date(2011, 2, 31, 23, 59, 59, 999)), 'month'), false, 'exact end of month');\n    assert.equal(m.isBefore(moment(new Date(2011, 3, 1, 0, 0, 0, 0)), 'month'), true, 'start of next month');\n    assert.equal(m.isBefore(moment(new Date(2011, 1, 27, 23, 59, 59, 999)), 'month'), false, 'end of previous month');\n    assert.equal(m.isBefore(moment(new Date(2010, 12, 31, 23, 59, 59, 999)), 'month'), false, 'later month but earlier year');\n    assert.equal(m.isBefore(m, 'month'), false, 'same moments are not before the same month');\n    assert.equal(+m, +mCopy, 'isBefore month should not change moment');\n});\n\ntest('is before day', function (assert) {\n    var m = moment(new Date(2011, 3, 2, 3, 4, 5, 6)), mCopy = moment(m);\n    assert.equal(m.isBefore(moment(new Date(2011, 3, 2, 7, 8, 9, 10)), 'day'), false, 'day match');\n    assert.equal(m.isBefore(moment(new Date(2012, 3, 2, 7, 8, 9, 10)), 'days'), true, 'plural should work');\n    assert.equal(m.isBefore(moment(new Date(2012, 3, 2, 7, 8, 9, 10)), 'day'), true, 'year is later');\n    assert.equal(m.isBefore(moment(new Date(2010, 3, 2, 7, 8, 9, 10)), 'day'), false, 'year is earlier');\n    assert.equal(m.isBefore(moment(new Date(2011, 4, 2, 7, 8, 9, 10)), 'day'), true, 'month is later');\n    assert.equal(m.isBefore(moment(new Date(2011, 2, 2, 7, 8, 9, 10)), 'day'), false, 'month is earlier');\n    assert.equal(m.isBefore(moment(new Date(2011, 3, 3, 7, 8, 9, 10)), 'day'), true, 'day is later');\n    assert.equal(m.isBefore(moment(new Date(2011, 3, 1, 7, 8, 9, 10)), 'day'), false, 'day is earlier');\n    assert.equal(m.isBefore(moment(new Date(2011, 3, 2, 0, 0, 0, 0)), 'day'), false, 'exact start of day');\n    assert.equal(m.isBefore(moment(new Date(2011, 3, 2, 23, 59, 59, 999)), 'day'), false, 'exact end of day');\n    assert.equal(m.isBefore(moment(new Date(2011, 3, 3, 0, 0, 0, 0)), 'day'), true, 'start of next day');\n    assert.equal(m.isBefore(moment(new Date(2011, 3, 1, 23, 59, 59, 999)), 'day'), false, 'end of previous day');\n    assert.equal(m.isBefore(moment(new Date(2010, 3, 10, 0, 0, 0, 0)), 'day'), false, 'later day but earlier year');\n    assert.equal(m.isBefore(m, 'day'), false, 'same moments are not before the same day');\n    assert.equal(+m, +mCopy, 'isBefore day should not change moment');\n});\n\ntest('is before hour', function (assert) {\n    var m = moment(new Date(2011, 3, 2, 3, 4, 5, 6)), mCopy = moment(m);\n    assert.equal(m.isBefore(moment(new Date(2011, 3, 2, 3, 8, 9, 10)), 'hour'), false, 'hour match');\n    assert.equal(m.isBefore(moment(new Date(2012, 3, 2, 3, 8, 9, 10)), 'hours'), true, 'plural should work');\n    assert.equal(m.isBefore(moment(new Date(2012, 3, 2, 3, 8, 9, 10)), 'hour'), true, 'year is later');\n    assert.equal(m.isBefore(moment(new Date(2010, 3, 2, 3, 8, 9, 10)), 'hour'), false, 'year is earlier');\n    assert.equal(m.isBefore(moment(new Date(2011, 4, 2, 3, 8, 9, 10)), 'hour'), true, 'month is later');\n    assert.equal(m.isBefore(moment(new Date(2011, 1, 2, 3, 8, 9, 10)), 'hour'), false, 'month is earlier');\n    assert.equal(m.isBefore(moment(new Date(2011, 3, 3, 3, 8, 9, 10)), 'hour'), true, 'day is later');\n    assert.equal(m.isBefore(moment(new Date(2011, 3, 1, 3, 8, 9, 10)), 'hour'), false, 'day is earlier');\n    assert.equal(m.isBefore(moment(new Date(2011, 3, 2, 4, 8, 9, 10)), 'hour'), true, 'hour is later');\n    assert.equal(m.isBefore(moment(new Date(2011, 3, 2, 3, 8, 9, 10)), 'hour'), false, 'hour is earlier');\n    assert.equal(m.isBefore(moment(new Date(2011, 3, 2, 3, 0, 0, 0)), 'hour'), false, 'exact start of hour');\n    assert.equal(m.isBefore(moment(new Date(2011, 3, 2, 3, 59, 59, 999)), 'hour'), false, 'exact end of hour');\n    assert.equal(m.isBefore(moment(new Date(2011, 3, 2, 4, 0, 0, 0)), 'hour'), true, 'start of next hour');\n    assert.equal(m.isBefore(moment(new Date(2011, 3, 2, 2, 59, 59, 999)), 'hour'), false, 'end of previous hour');\n    assert.equal(m.isBefore(m, 'hour'), false, 'same moments are not before the same hour');\n    assert.equal(+m, +mCopy, 'isBefore hour should not change moment');\n});\n\ntest('is before minute', function (assert) {\n    var m = moment(new Date(2011, 3, 2, 3, 4, 5, 6)), mCopy = moment(m);\n    assert.equal(m.isBefore(moment(new Date(2011, 3, 2, 3, 4, 9, 10)), 'minute'), false, 'minute match');\n    assert.equal(m.isBefore(moment(new Date(2012, 3, 2, 3, 4, 9, 10)), 'minutes'), true, 'plural should work');\n    assert.equal(m.isBefore(moment(new Date(2012, 3, 2, 3, 4, 9, 10)), 'minute'), true, 'year is later');\n    assert.equal(m.isBefore(moment(new Date(2010, 3, 2, 3, 4, 9, 10)), 'minute'), false, 'year is earlier');\n    assert.equal(m.isBefore(moment(new Date(2011, 4, 2, 3, 4, 9, 10)), 'minute'), true, 'month is later');\n    assert.equal(m.isBefore(moment(new Date(2011, 2, 2, 3, 4, 9, 10)), 'minute'), false, 'month is earlier');\n    assert.equal(m.isBefore(moment(new Date(2011, 3, 3, 3, 4, 9, 10)), 'minute'), true, 'day is later');\n    assert.equal(m.isBefore(moment(new Date(2011, 3, 1, 3, 4, 9, 10)), 'minute'), false, 'day is earlier');\n    assert.equal(m.isBefore(moment(new Date(2011, 3, 2, 4, 4, 9, 10)), 'minute'), true, 'hour is later');\n    assert.equal(m.isBefore(moment(new Date(2011, 3, 2, 2, 4, 9, 10)), 'minute'), false, 'hour is earler');\n    assert.equal(m.isBefore(moment(new Date(2011, 3, 2, 3, 5, 9, 10)), 'minute'), true, 'minute is later');\n    assert.equal(m.isBefore(moment(new Date(2011, 3, 2, 3, 3, 9, 10)), 'minute'), false, 'minute is earlier');\n    assert.equal(m.isBefore(moment(new Date(2011, 3, 2, 3, 4, 0, 0)), 'minute'), false, 'exact start of minute');\n    assert.equal(m.isBefore(moment(new Date(2011, 3, 2, 3, 4, 59, 999)), 'minute'), false, 'exact end of minute');\n    assert.equal(m.isBefore(moment(new Date(2011, 3, 2, 3, 5, 0, 0)), 'minute'), true, 'start of next minute');\n    assert.equal(m.isBefore(moment(new Date(2011, 3, 2, 3, 3, 59, 999)), 'minute'), false, 'end of previous minute');\n    assert.equal(m.isBefore(m, 'minute'), false, 'same moments are not before the same minute');\n    assert.equal(+m, +mCopy, 'isBefore minute should not change moment');\n});\n\ntest('is before second', function (assert) {\n    var m = moment(new Date(2011, 3, 2, 3, 4, 5, 10)), mCopy = moment(m);\n    assert.equal(m.isBefore(moment(new Date(2011, 3, 2, 3, 4, 5, 10)), 'second'), false, 'second match');\n    assert.equal(m.isBefore(moment(new Date(2012, 3, 2, 3, 4, 5, 10)), 'seconds'), true, 'plural should work');\n    assert.equal(m.isBefore(moment(new Date(2012, 3, 2, 3, 4, 5, 10)), 'second'), true, 'year is later');\n    assert.equal(m.isBefore(moment(new Date(2010, 3, 2, 3, 4, 5, 10)), 'second'), false, 'year is earlier');\n    assert.equal(m.isBefore(moment(new Date(2011, 4, 2, 3, 4, 5, 10)), 'second'), true, 'month is later');\n    assert.equal(m.isBefore(moment(new Date(2011, 2, 2, 3, 4, 5, 10)), 'second'), false, 'month is earlier');\n    assert.equal(m.isBefore(moment(new Date(2011, 3, 3, 3, 4, 5, 10)), 'second'), true, 'day is later');\n    assert.equal(m.isBefore(moment(new Date(2011, 3, 1, 1, 4, 5, 10)), 'second'), false, 'day is earlier');\n    assert.equal(m.isBefore(moment(new Date(2011, 3, 2, 4, 4, 5, 10)), 'second'), true, 'hour is later');\n    assert.equal(m.isBefore(moment(new Date(2011, 3, 1, 4, 1, 5, 10)), 'second'), false, 'hour is earlier');\n    assert.equal(m.isBefore(moment(new Date(2011, 3, 2, 3, 5, 5, 10)), 'second'), true, 'minute is later');\n    assert.equal(m.isBefore(moment(new Date(2011, 3, 2, 3, 3, 5, 10)), 'second'), false, 'minute is earlier');\n    assert.equal(m.isBefore(moment(new Date(2011, 3, 2, 3, 4, 6, 10)), 'second'), true, 'second is later');\n    assert.equal(m.isBefore(moment(new Date(2011, 3, 2, 3, 4, 4, 5)), 'second'), false, 'second is earlier');\n    assert.equal(m.isBefore(moment(new Date(2011, 3, 2, 3, 4, 5, 0)), 'second'), false, 'exact start of second');\n    assert.equal(m.isBefore(moment(new Date(2011, 3, 2, 3, 4, 5, 999)), 'second'), false, 'exact end of second');\n    assert.equal(m.isBefore(moment(new Date(2011, 3, 2, 3, 4, 6, 0)), 'second'), true, 'start of next second');\n    assert.equal(m.isBefore(moment(new Date(2011, 3, 2, 3, 4, 4, 999)), 'second'), false, 'end of previous second');\n    assert.equal(m.isBefore(m, 'second'), false, 'same moments are not before the same second');\n    assert.equal(+m, +mCopy, 'isBefore second should not change moment');\n});\n\ntest('is before millisecond', function (assert) {\n    var m = moment(new Date(2011, 3, 2, 3, 4, 5, 10)), mCopy = moment(m);\n    assert.equal(m.isBefore(moment(new Date(2011, 3, 2, 3, 4, 5, 10)), 'millisecond'), false, 'millisecond match');\n    assert.equal(m.isBefore(moment(new Date(2010, 3, 2, 3, 4, 5, 10)), 'milliseconds'), false, 'plural should work');\n    assert.equal(m.isBefore(moment(new Date(2012, 3, 2, 3, 4, 5, 10)), 'millisecond'), true, 'year is later');\n    assert.equal(m.isBefore(moment(new Date(2010, 3, 2, 3, 4, 5, 10)), 'millisecond'), false, 'year is earlier');\n    assert.equal(m.isBefore(moment(new Date(2011, 4, 2, 3, 4, 5, 10)), 'millisecond'), true, 'month is later');\n    assert.equal(m.isBefore(moment(new Date(2011, 2, 2, 3, 4, 5, 10)), 'millisecond'), false, 'month is earlier');\n    assert.equal(m.isBefore(moment(new Date(2011, 3, 3, 3, 4, 5, 10)), 'millisecond'), true, 'day is later');\n    assert.equal(m.isBefore(moment(new Date(2011, 3, 1, 1, 4, 5, 10)), 'millisecond'), false, 'day is earlier');\n    assert.equal(m.isBefore(moment(new Date(2011, 3, 2, 4, 4, 5, 10)), 'millisecond'), true, 'hour is later');\n    assert.equal(m.isBefore(moment(new Date(2011, 3, 1, 4, 1, 5, 10)), 'millisecond'), false, 'hour is earlier');\n    assert.equal(m.isBefore(moment(new Date(2011, 3, 2, 3, 5, 5, 10)), 'millisecond'), true, 'minute is later');\n    assert.equal(m.isBefore(moment(new Date(2011, 3, 2, 3, 3, 5, 10)), 'millisecond'), false, 'minute is earlier');\n    assert.equal(m.isBefore(moment(new Date(2011, 3, 2, 3, 4, 6, 10)), 'millisecond'), true, 'second is later');\n    assert.equal(m.isBefore(moment(new Date(2011, 3, 2, 3, 4, 4, 5)), 'millisecond'), false, 'second is earlier');\n    assert.equal(m.isBefore(moment(new Date(2011, 3, 2, 3, 4, 6, 11)), 'millisecond'), true, 'millisecond is later');\n    assert.equal(m.isBefore(moment(new Date(2011, 3, 2, 3, 4, 4, 9)), 'millisecond'), false, 'millisecond is earlier');\n    assert.equal(m.isBefore(m, 'millisecond'), false, 'same moments are not before the same millisecond');\n    assert.equal(+m, +mCopy, 'isBefore millisecond should not change moment');\n});\n\ntest('is before invalid', function (assert) {\n    var m = moment(), invalid = moment.invalid();\n    assert.equal(m.isBefore(invalid), false, 'valid moment is not before invalid moment');\n    assert.equal(invalid.isBefore(m), false, 'invalid moment is not before valid moment');\n    assert.equal(m.isBefore(invalid, 'year'), false, 'invalid moment year');\n    assert.equal(m.isBefore(invalid, 'month'), false, 'invalid moment month');\n    assert.equal(m.isBefore(invalid, 'day'), false, 'invalid moment day');\n    assert.equal(m.isBefore(invalid, 'hour'), false, 'invalid moment hour');\n    assert.equal(m.isBefore(invalid, 'minute'), false, 'invalid moment minute');\n    assert.equal(m.isBefore(invalid, 'second'), false, 'invalid moment second');\n    assert.equal(m.isBefore(invalid, 'milliseconds'), false, 'invalid moment milliseconds');\n});\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/test/moment/is_between.js",
    "content": "import { module, test } from '../qunit';\nimport moment from '../../moment';\n\nmodule('is between');\n\ntest('is between without units', function (assert) {\n    var m = moment(new Date(2011, 3, 2, 3, 4, 5, 10)), mCopy = moment(m);\n    assert.equal(m.isBetween(\n                moment(new Date(2009, 3, 2, 3, 4, 5, 10)),\n                moment(new Date(2011, 3, 2, 3, 4, 5, 10))), false, 'year is later');\n    assert.equal(m.isBetween(\n                moment(new Date(2011, 3, 2, 3, 4, 5, 10)),\n                moment(new Date(2013, 3, 2, 3, 4, 5, 10))), false, 'year is earlier');\n    assert.equal(m.isBetween(\n                moment(new Date(2010, 3, 2, 3, 4, 5, 10)),\n                moment(new Date(2012, 3, 2, 3, 4, 5, 10))), true, 'year is between');\n    assert.equal(m.isBetween(\n                moment(new Date(2011, 1, 2, 3, 4, 5, 10)),\n                moment(new Date(2011, 3, 2, 3, 4, 5, 10))), false, 'month is later');\n    assert.equal(m.isBetween(\n                moment(new Date(2011, 3, 2, 3, 4, 5, 10)),\n                moment(new Date(2011, 5, 2, 3, 4, 5, 10))), false, 'month is earlier');\n    assert.equal(m.isBetween(\n                moment(new Date(2011, 2, 2, 3, 4, 5, 10)),\n                moment(new Date(2011, 4, 2, 3, 4, 5, 10))), true, 'month is between');\n    assert.equal(m.isBetween(\n                moment(new Date(2011, 3, 1, 3, 4, 5, 10)),\n                moment(new Date(2011, 3, 2, 3, 4, 5, 10))), false, 'day is later');\n    assert.equal(m.isBetween(\n                moment(new Date(2011, 3, 2, 3, 4, 5, 10)),\n                moment(new Date(2011, 3, 4, 3, 4, 5, 10))), false, 'day is earlier');\n    assert.equal(m.isBetween(\n                moment(new Date(2011, 3, 1, 3, 4, 5, 10)),\n                moment(new Date(2011, 3, 3, 3, 4, 5, 10))), true, 'day is between');\n    assert.equal(m.isBetween(\n                moment(new Date(2011, 3, 2, 1, 4, 5, 10)),\n                moment(new Date(2011, 3, 2, 3, 4, 5, 10))), false, 'hour is later');\n    assert.equal(m.isBetween(\n                moment(new Date(2011, 3, 2, 3, 4, 5, 10)),\n                moment(new Date(2011, 3, 2, 5, 4, 5, 10))), false, 'hour is earlier');\n    assert.equal(m.isBetween(\n                moment(new Date(2011, 3, 2, 2, 4, 5, 10)),\n                moment(new Date(2011, 3, 2, 4, 4, 5, 10))), true, 'hour is between');\n    assert.equal(m.isBetween(\n                moment(new Date(2011, 3, 2, 3, 4, 5, 10)),\n                moment(new Date(2011, 3, 2, 3, 6, 5, 10))), false, 'minute is later');\n    assert.equal(m.isBetween(\n                moment(new Date(2011, 3, 2, 3, 2, 5, 10)),\n                moment(new Date(2011, 3, 2, 3, 4, 5, 10))), false, 'minute is earlier');\n    assert.equal(m.isBetween(\n                moment(new Date(2011, 3, 2, 3, 3, 5, 10)),\n                moment(new Date(2011, 3, 2, 3, 5, 5, 10))), true, 'minute is between');\n    assert.equal(m.isBetween(\n                moment(new Date(2011, 3, 2, 3, 4, 5, 10)),\n                moment(new Date(2011, 3, 2, 3, 4, 7, 10))), false, 'second is later');\n    assert.equal(m.isBetween(\n                moment(new Date(2011, 3, 2, 3, 4, 3, 10)),\n                moment(new Date(2011, 3, 2, 3, 4, 5, 10))), false, 'second is earlier');\n    assert.equal(m.isBetween(\n                moment(new Date(2011, 3, 2, 3, 4, 4, 10)),\n                moment(new Date(2011, 3, 2, 3, 4, 6, 10))), true, 'second is between');\n    assert.equal(m.isBetween(\n                moment(new Date(2011, 3, 2, 3, 4, 5, 10)),\n                moment(new Date(2011, 3, 2, 3, 4, 5, 12))), false, 'millisecond is later');\n    assert.equal(m.isBetween(\n                moment(new Date(2011, 3, 2, 3, 4, 5, 8)),\n                moment(new Date(2011, 3, 2, 3, 4, 5, 10))), false, 'millisecond is earlier');\n    assert.equal(m.isBetween(\n                moment(new Date(2011, 3, 2, 3, 4, 5, 9)),\n                moment(new Date(2011, 3, 2, 3, 4, 5, 11))), true, 'millisecond is between');\n    assert.equal(m.isBetween(m, m), false, 'moments are not between themselves');\n    assert.equal(+m, +mCopy, 'isBetween second should not change moment');\n});\n\ntest('is between without units inclusivity', function (assert) {\n    var m = moment(new Date(2011, 3, 2, 3, 4, 5, 10)), mCopy = moment(m);\n    assert.equal(m.isBetween(\n        moment(new Date(2011, 3, 2, 3, 4, 5, 10)),\n        moment(new Date(2012, 3, 2, 3, 4, 5, 10)), null, '()'), false, 'start and end are excluded, start is equal to moment');\n    assert.equal(m.isBetween(\n        moment(new Date(2010, 3, 2, 3, 4, 5, 10)),\n        moment(new Date(2011, 3, 2, 3, 4, 5, 10)), null, '()'), false, 'start and end are excluded, end is equal to moment');\n    assert.equal(m.isBetween(\n        moment(new Date(2010, 3, 2, 3, 4, 5, 10)),\n        moment(new Date(2012, 3, 2, 3, 4, 5, 10)), null, '()'), true, 'start and end are excluded, is between');\n    assert.equal(m.isBetween(\n        moment(new Date(2009, 3, 2, 3, 4, 5, 10)),\n        moment(new Date(2010, 3, 2, 3, 4, 5, 10)), null, '()'), false, 'start and end are excluded, is not between');\n    assert.equal(m.isBetween(\n        moment(new Date(2011, 3, 2, 3, 4, 5, 10)),\n        moment(new Date(2011, 3, 2, 3, 4, 5, 10)), null, '()'), false, 'start and end are excluded, should fail on same start/end date.');\n\n    assert.equal(m.isBetween(\n        moment(new Date(2011, 3, 2, 3, 4, 5, 10)),\n        moment(new Date(2012, 3, 2, 3, 4, 5, 10)), null, '(]'), false, 'start is excluded and end is included should fail on same start date');\n    assert.equal(m.isBetween(\n        moment(new Date(2010, 3, 2, 3, 4, 5, 10)),\n        moment(new Date(2011, 3, 2, 3, 4, 5, 10)), null, '(]'), true, 'start is excluded and end is included should succeed on end date');\n    assert.equal(m.isBetween(\n        moment(new Date(2010, 3, 2, 3, 4, 5, 10)),\n        moment(new Date(2012, 3, 2, 3, 4, 5, 10)), null, '(]'), true, 'start is excluded and end is included, is between');\n    assert.equal(m.isBetween(\n        moment(new Date(2009, 3, 2, 3, 4, 5, 10)),\n        moment(new Date(2010, 3, 2, 3, 4, 5, 10)), null, '(]'), false, 'start is excluded and end is included, is not between');\n    assert.equal(m.isBetween(\n        moment(new Date(2011, 3, 2, 3, 4, 5, 10)),\n        moment(new Date(2011, 3, 2, 3, 4, 5, 10)), null, '(]'), false, 'start is excluded and end is included, should fail on same start/end date.');\n\n    assert.equal(m.isBetween(\n        moment(new Date(2011, 3, 2, 3, 4, 5, 10)),\n        moment(new Date(2012, 3, 2, 3, 4, 5, 10)), null, '[)'), true, 'start is included and end is excluded should succeed on same start date');\n    assert.equal(m.isBetween(\n        moment(new Date(2010, 3, 2, 3, 4, 5, 10)),\n        moment(new Date(2011, 3, 2, 3, 4, 5, 10)), null, '[)'), false, 'start is included and end is excluded should fail on same end date');\n    assert.equal(m.isBetween(\n        moment(new Date(2010, 3, 2, 3, 4, 5, 10)),\n        moment(new Date(2012, 3, 2, 3, 4, 5, 10)), null, '[)'), true, 'start is included and end is excluded, is between');\n    assert.equal(m.isBetween(\n        moment(new Date(2009, 3, 2, 3, 4, 5, 10)),\n        moment(new Date(2010, 3, 2, 3, 4, 5, 10)), null, '[)'), false, 'start is included and end is excluded, is not between');\n    assert.equal(m.isBetween(\n        moment(new Date(2011, 3, 2, 3, 4, 5, 10)),\n        moment(new Date(2011, 3, 2, 3, 4, 5, 10)), null, '[)'), false, 'start is included and end is excluded, should fail on same end and start date');\n\n    assert.equal(m.isBetween(\n        moment(new Date(2011, 3, 2, 3, 4, 5, 10)),\n        moment(new Date(2012, 3, 2, 3, 4, 5, 10)), null, '[]'), true, 'start and end inclusive should succeed on same start date');\n    assert.equal(m.isBetween(\n        moment(new Date(2010, 3, 2, 3, 4, 5, 10)),\n        moment(new Date(2011, 3, 2, 3, 4, 5, 10)), null, '[]'), true, 'start and end inclusive should succeed on same end date');\n    assert.equal(m.isBetween(\n        moment(new Date(2010, 3, 2, 3, 4, 5, 10)),\n        moment(new Date(2012, 3, 2, 3, 4, 5, 10)), null, '[]'), true, 'start and end inclusive, is between');\n    assert.equal(m.isBetween(\n        moment(new Date(2009, 3, 2, 3, 4, 5, 10)),\n        moment(new Date(2010, 3, 2, 3, 4, 5, 10)), null, '[]'), false, 'start and end inclusive, is not between');\n    assert.equal(m.isBetween(\n        moment(new Date(2011, 3, 2, 3, 4, 5, 10)),\n        moment(new Date(2011, 3, 2, 3, 4, 5, 10)), null, '[]'), true, 'start and end inclusive, should handle same end and start date');\n});\n\ntest('is between milliseconds inclusivity', function (assert) {\n    var m = moment(new Date(2011, 3, 2, 3, 4, 5, 10)), mCopy = moment(m);\n    assert.equal(m.isBetween(\n        moment(new Date(2010, 3, 2, 3, 4, 5, 10)),\n        moment(new Date(2012, 3, 2, 3, 4, 5, 10)), 'milliseconds'), true, 'options, no inclusive');\n    assert.equal(m.isBetween(\n        moment(new Date(2011, 3, 2, 3, 4, 5, 10)),\n        moment(new Date(2012, 3, 2, 3, 4, 5, 10)), 'milliseconds', '()'), false, 'start and end are excluded, start is equal to moment');\n    assert.equal(m.isBetween(\n        moment(new Date(2010, 3, 2, 3, 4, 5, 10)),\n        moment(new Date(2011, 3, 2, 3, 4, 5, 10)), 'milliseconds', '()'), false, 'start and end are excluded, end is equal to moment');\n    assert.equal(m.isBetween(\n        moment(new Date(2010, 3, 2, 3, 4, 5, 10)),\n        moment(new Date(2012, 3, 2, 3, 4, 5, 10)), 'milliseconds', '()'), true, 'start and end are excluded, is between');\n    assert.equal(m.isBetween(\n        moment(new Date(2009, 3, 2, 3, 4, 5, 10)),\n        moment(new Date(2010, 3, 2, 3, 4, 5, 10)), 'milliseconds', '()'), false, 'start and end are excluded, is not between');\n    assert.equal(m.isBetween(\n        moment(new Date(2011, 3, 2, 3, 4, 5, 10)),\n        moment(new Date(2011, 3, 2, 3, 4, 5, 10)), 'milliseconds', '()'), false, 'start and end are excluded, should fail on same start/end date.');\n\n    assert.equal(m.isBetween(\n        moment(new Date(2011, 3, 2, 3, 4, 5, 10)),\n        moment(new Date(2012, 3, 2, 3, 4, 5, 10)), 'milliseconds', '(]'), false, 'start is excluded and end is included should fail on same start date');\n    assert.equal(m.isBetween(\n        moment(new Date(2010, 3, 2, 3, 4, 5, 10)),\n        moment(new Date(2011, 3, 2, 3, 4, 5, 10)), 'milliseconds', '(]'), true, 'start is excluded and end is included should succeed on end date');\n    assert.equal(m.isBetween(\n        moment(new Date(2010, 3, 2, 3, 4, 5, 10)),\n        moment(new Date(2012, 3, 2, 3, 4, 5, 10)), 'milliseconds', '(]'), true, 'start is excluded and end is included, is between');\n    assert.equal(m.isBetween(\n        moment(new Date(2009, 3, 2, 3, 4, 5, 10)),\n        moment(new Date(2010, 3, 2, 3, 4, 5, 10)), 'milliseconds', '(]'), false, 'start is excluded and end is included, is not between');\n    assert.equal(m.isBetween(\n        moment(new Date(2011, 3, 2, 3, 4, 5, 10)),\n        moment(new Date(2011, 3, 2, 3, 4, 5, 10)), 'milliseconds', '(]'), false, 'start is excluded and end is included, should fail on same start/end date.');\n\n    assert.equal(m.isBetween(\n        moment(new Date(2011, 3, 2, 3, 4, 5, 10)),\n        moment(new Date(2012, 3, 2, 3, 4, 5, 10)), 'milliseconds', '[)'), true, 'start is included and end is excluded should succeed on same start date');\n    assert.equal(m.isBetween(\n        moment(new Date(2010, 3, 2, 3, 4, 5, 10)),\n        moment(new Date(2011, 3, 2, 3, 4, 5, 10)), 'milliseconds', '[)'), false, 'start is included and end is excluded should fail on same end date');\n    assert.equal(m.isBetween(\n        moment(new Date(2010, 3, 2, 3, 4, 5, 10)),\n        moment(new Date(2012, 3, 2, 3, 4, 5, 10)), 'milliseconds', '[)'), true, 'start is included and end is excluded, is between');\n    assert.equal(m.isBetween(\n        moment(new Date(2009, 3, 2, 3, 4, 5, 10)),\n        moment(new Date(2010, 3, 2, 3, 4, 5, 10)), 'milliseconds', '[)'), false, 'start is included and end is excluded, is not between');\n    assert.equal(m.isBetween(\n        moment(new Date(2011, 3, 2, 3, 4, 5, 10)),\n        moment(new Date(2011, 3, 2, 3, 4, 5, 10)), 'milliseconds', '[)'), false, 'start is included and end is excluded, should fail on same end and start date');\n\n    assert.equal(m.isBetween(\n        moment(new Date(2011, 3, 2, 3, 4, 5, 10)),\n        moment(new Date(2012, 3, 2, 3, 4, 5, 10)), 'milliseconds', '[]'), true, 'start and end inclusive should succeed on same start date');\n    assert.equal(m.isBetween(\n        moment(new Date(2010, 3, 2, 3, 4, 5, 10)),\n        moment(new Date(2011, 3, 2, 3, 4, 5, 10)), 'milliseconds', '[]'), true, 'start and end inclusive should succeed on same end date');\n    assert.equal(m.isBetween(\n        moment(new Date(2010, 3, 2, 3, 4, 5, 10)),\n        moment(new Date(2012, 3, 2, 3, 4, 5, 10)), 'milliseconds', '[]'), true, 'start and end inclusive, is between');\n    assert.equal(m.isBetween(\n        moment(new Date(2009, 3, 2, 3, 4, 5, 10)),\n        moment(new Date(2010, 3, 2, 3, 4, 5, 10)), 'milliseconds', '[]'), false, 'start and end inclusive, is not between');\n    assert.equal(m.isBetween(\n        moment(new Date(2011, 3, 2, 3, 4, 5, 10)),\n        moment(new Date(2011, 3, 2, 3, 4, 5, 10)), 'milliseconds', '[]'), true, 'start and end inclusive, should handle same end and start date');\n});\n\ntest('is between year', function (assert) {\n    var m = moment(new Date(2011, 1, 2, 3, 4, 5, 6)), mCopy = moment(m);\n    assert.equal(m.isBetween(\n                moment(new Date(2011, 5, 6, 7, 8, 9, 10)),\n                moment(new Date(2011, 5, 6, 7, 8, 9, 10)), 'year'), false, 'year match');\n    assert.equal(m.isBetween(\n                moment(new Date(2010, 5, 6, 7, 8, 9, 10)),\n                moment(new Date(2012, 5, 6, 7, 8, 9, 10)), 'years'), true, 'plural should work');\n    assert.equal(m.isBetween(\n                moment(new Date(2010, 5, 6, 7, 8, 9, 10)),\n                moment(new Date(2012, 5, 6, 7, 8, 9, 10)), 'year'), true, 'year is between');\n    assert.equal(m.isBetween(\n                moment(new Date(2011, 5, 6, 7, 8, 9, 10)),\n                moment(new Date(2013, 5, 6, 7, 8, 9, 10)), 'year'), false, 'year is earlier');\n    assert.equal(m.isBetween(\n                moment(new Date(2010, 5, 6, 7, 8, 9, 10)),\n                moment(new Date(2011, 5, 6, 7, 8, 9, 10)), 'year'), false, 'year is later');\n    assert.equal(m.isBetween(m, 'year'), false, 'same moments are not between the same year');\n    assert.equal(+m, +mCopy, 'isBetween year should not change moment');\n});\n\ntest('is between month', function (assert) {\n    var m = moment(new Date(2011, 1, 2, 3, 4, 5, 6)), mCopy = moment(m);\n    assert.equal(m.isBetween(\n                moment(new Date(2011, 1, 6, 7, 8, 9, 10)),\n                moment(new Date(2011, 1, 6, 7, 8, 9, 10)), 'month'), false, 'month match');\n    assert.equal(m.isBetween(\n                moment(new Date(2011, 0, 6, 7, 8, 9, 10)),\n                moment(new Date(2011, 2, 6, 7, 8, 9, 10)), 'months'), true, 'plural should work');\n    assert.equal(m.isBetween(\n                moment(new Date(2011, 0, 31, 23, 59, 59, 999)),\n                moment(new Date(2011, 2, 1, 0, 0, 0, 0)), 'month'), true, 'month is between');\n    assert.equal(m.isBetween(\n                moment(new Date(2011, 1, 6, 7, 8, 9, 10)),\n                moment(new Date(2011, 2, 6, 7, 8, 9, 10)), 'month'), false, 'month is earlier');\n    assert.equal(m.isBetween(\n                moment(new Date(2011, 11, 6, 7, 8, 9, 10)),\n                moment(new Date(2011, 1, 6, 7, 8, 9, 10)), 'month'), false, 'month is later');\n    assert.equal(m.isBetween(m, 'month'), false, 'same moments are not between the same month');\n    assert.equal(+m, +mCopy, 'isBetween month should not change moment');\n});\n\ntest('is between day', function (assert) {\n    var m = moment(new Date(2011, 1, 2, 3, 4, 5, 6)), mCopy = moment(m);\n    assert.equal(m.isBetween(\n                moment(new Date(2011, 1, 2, 7, 8, 9, 10)),\n                moment(new Date(2011, 1, 2, 7, 8, 9, 10)), 'day'), false, 'day match');\n    assert.equal(m.isBetween(\n                moment(new Date(2011, 1, 1, 7, 8, 9, 10)),\n                moment(new Date(2011, 1, 3, 7, 8, 9, 10)), 'days'), true, 'plural should work');\n    assert.equal(m.isBetween(\n                moment(new Date(2011, 1, 1, 7, 8, 9, 10)),\n                moment(new Date(2011, 1, 3, 7, 8, 9, 10)), 'day'), true, 'day is between');\n    assert.equal(m.isBetween(\n                moment(new Date(2011, 1, 2, 7, 8, 9, 10)),\n                moment(new Date(2011, 1, 4, 7, 8, 9, 10)), 'day'), false, 'day is earlier');\n    assert.equal(m.isBetween(\n                moment(new Date(2011, 1, 1, 7, 8, 9, 10)),\n                moment(new Date(2011, 1, 2, 7, 8, 9, 10)), 'day'), false, 'day is later');\n    assert.equal(m.isBetween(m, 'day'), false, 'same moments are not between the same day');\n    assert.equal(+m, +mCopy, 'isBetween day should not change moment');\n});\n\ntest('is between hour', function (assert) {\n    var m = moment(new Date(2011, 1, 2, 3, 4, 5, 6)), mCopy = moment(m);\n    assert.equal(m.isBetween(\n                moment(new Date(2011, 1, 2, 3, 5, 9, 10)),\n                moment(new Date(2011, 1, 2, 3, 9, 9, 10)), 'hour'), false, 'hour match');\n    assert.equal(m.isBetween(\n                moment(new Date(2011, 1, 2, 1, 59, 59, 999)),\n                moment(new Date(2011, 1, 2, 4, 0, 0, 0)), 'hours'), true, 'plural should work');\n    assert.equal(m.isBetween(\n                moment(new Date(2011, 1, 2, 2, 59, 59, 999)),\n                moment(new Date(2011, 1, 2, 4, 0, 0, 0)), 'hour'), true, 'hour is between');\n    assert.equal(m.isBetween(\n                moment(new Date(2011, 1, 2, 7, 8, 9, 10)),\n                moment(new Date(2011, 1, 2, 7, 8, 9, 10)), 'hour'), false, 'hour is earlier');\n    assert.equal(m.isBetween(\n                moment(new Date(2011, 1, 2, 7, 8, 9, 10)),\n                moment(new Date(2011, 1, 2, 7, 8, 9, 10)), 'hour'), false, 'hour is later');\n    assert.equal(m.isBetween(m, 'hour'), false, 'same moments are not between the same hour');\n    assert.equal(+m, +mCopy, 'isBetween hour should not change moment');\n});\n\ntest('is between minute', function (assert) {\n    var m = moment(new Date(2011, 1, 2, 3, 4, 5, 6)), mCopy = moment(m);\n    assert.equal(m.isBetween(\n                moment(new Date(2011, 1, 2, 3, 4, 9, 10)),\n                moment(new Date(2011, 1, 2, 3, 4, 9, 10)), 'minute'), false, 'minute match');\n    assert.equal(m.isBetween(\n                moment(new Date(2011, 1, 2, 3, 3, 9, 10)),\n                moment(new Date(2011, 1, 2, 3, 5, 9, 10)), 'minutes'), true, 'plural should work');\n    assert.equal(m.isBetween(\n                moment(new Date(2011, 1, 2, 3, 3, 59, 999)),\n                moment(new Date(2011, 1, 2, 3, 5, 0, 0)), 'minute'), true, 'minute is between');\n    assert.equal(m.isBetween(\n                moment(new Date(2011, 1, 2, 3, 5, 0, 0)),\n                moment(new Date(2011, 1, 2, 3, 8, 9, 10)), 'minute'), false, 'minute is earlier');\n    assert.equal(m.isBetween(\n                moment(new Date(2011, 1, 2, 3, 2, 9, 10)),\n                moment(new Date(2011, 1, 2, 3, 3, 59, 999)), 'minute'), false, 'minute is later');\n    assert.equal(m.isBetween(m, 'minute'), false, 'same moments are not between the same minute');\n    assert.equal(+m, +mCopy, 'isBetween minute should not change moment');\n});\n\ntest('is between second', function (assert) {\n    var m = moment(new Date(2011, 1, 2, 3, 4, 5, 6)), mCopy = moment(m);\n    assert.equal(m.isBetween(\n                moment(new Date(2011, 1, 2, 3, 4, 5, 10)),\n                moment(new Date(2011, 1, 2, 3, 4, 5, 10)), 'second'), false, 'second match');\n    assert.equal(m.isBetween(\n                moment(new Date(2011, 1, 2, 3, 4, 4, 10)),\n                moment(new Date(2011, 1, 2, 3, 4, 6, 10)), 'seconds'), true, 'plural should work');\n    assert.equal(m.isBetween(\n                moment(new Date(2011, 1, 2, 3, 4, 4, 999)),\n                moment(new Date(2011, 1, 2, 3, 4, 6, 0)), 'second'), true, 'second is between');\n    assert.equal(m.isBetween(\n                moment(new Date(2011, 1, 2, 3, 4, 6, 0)),\n                moment(new Date(2011, 1, 2, 3, 4, 7, 10)), 'second'), false, 'second is earlier');\n    assert.equal(m.isBetween(\n                moment(new Date(2011, 1, 2, 3, 4, 3, 10)),\n                moment(new Date(2011, 1, 2, 3, 4, 4, 999)), 'second'), false, 'second is later');\n    assert.equal(m.isBetween(m, 'second'), false, 'same moments are not between the same second');\n    assert.equal(+m, +mCopy, 'isBetween second should not change moment');\n});\n\ntest('is between millisecond', function (assert) {\n    var m = moment(new Date(2011, 1, 2, 3, 4, 5, 6)), mCopy = moment(m);\n    assert.equal(m.isBetween(\n                moment(new Date(2011, 1, 2, 3, 4, 5, 6)),\n                moment(new Date(2011, 1, 2, 3, 4, 5, 6)), 'millisecond'), false, 'millisecond match');\n    assert.equal(m.isBetween(\n                moment(new Date(2011, 1, 2, 3, 4, 5, 5)),\n                moment(new Date(2011, 1, 2, 3, 4, 5, 7)), 'milliseconds'), true, 'plural should work');\n    assert.equal(m.isBetween(\n                moment(new Date(2011, 1, 2, 3, 4, 5, 5)),\n                moment(new Date(2011, 1, 2, 3, 4, 5, 7)), 'millisecond'), true, 'millisecond is between');\n    assert.equal(m.isBetween(\n                moment(new Date(2011, 1, 2, 3, 4, 5, 7)),\n                moment(new Date(2011, 1, 2, 3, 4, 5, 10)), 'millisecond'), false, 'millisecond is earlier');\n    assert.equal(m.isBetween(\n                moment(new Date(2011, 1, 2, 3, 4, 5, 4)),\n                moment(new Date(2011, 1, 2, 3, 4, 5, 6)), 'millisecond'), false, 'millisecond is later');\n    assert.equal(m.isBetween(m, 'millisecond'), false, 'same moments are not between the same millisecond');\n    assert.equal(+m, +mCopy, 'isBetween millisecond should not change moment');\n});\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/test/moment/is_date.js",
    "content": "import { module, test } from '../qunit';\nimport moment from '../../moment';\n\nmodule('is date');\n\ntest('isDate recognizes Date objects', function (assert) {\n    assert.ok(moment.isDate(new Date()), 'no args (now)');\n    assert.ok(moment.isDate(new Date([2014, 2, 15])), 'array args');\n    assert.ok(moment.isDate(new Date('2014-03-15')), 'string args');\n    assert.ok(moment.isDate(new Date('does NOT look like a date')), 'invalid date');\n});\n\ntest('isDate rejects non-Date objects', function (assert) {\n    assert.ok(!moment.isDate(), 'nothing');\n    assert.ok(!moment.isDate(undefined), 'undefined');\n    assert.ok(!moment.isDate(null), 'string args');\n    assert.ok(!moment.isDate(42), 'number');\n    assert.ok(!moment.isDate('2014-03-15'), 'string');\n    assert.ok(!moment.isDate([2014, 2, 15]), 'array');\n    assert.ok(!moment.isDate({year: 2014, month: 2, day: 15}), 'object');\n    assert.ok(!moment.isDate({\n        toString: function () {\n            return '[object Date]';\n        }\n    }), 'lying object');\n});\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/test/moment/is_moment.js",
    "content": "import { module, test } from '../qunit';\nimport moment from '../../moment';\n\nmodule('is moment');\n\ntest('is moment object', function (assert) {\n    var MyObj = function () {},\n        extend = function (a, b) {\n            var i;\n            for (i in b) {\n                a[i] = b[i];\n            }\n            return a;\n        };\n    MyObj.prototype.toDate = function () {\n        return new Date();\n    };\n\n    assert.ok(moment.isMoment(moment()), 'simple moment object');\n    assert.ok(moment.isMoment(moment(null)), 'invalid moment object');\n    assert.ok(moment.isMoment(extend({}, moment())), 'externally cloned moments are moments');\n    assert.ok(moment.isMoment(extend({}, moment.utc())), 'externally cloned utc moments are moments');\n\n    assert.ok(!moment.isMoment(new MyObj()), 'myObj is not moment object');\n    assert.ok(!moment.isMoment(moment), 'moment function is not moment object');\n    assert.ok(!moment.isMoment(new Date()), 'date object is not moment object');\n    assert.ok(!moment.isMoment(Object), 'Object is not moment object');\n    assert.ok(!moment.isMoment('foo'), 'string is not moment object');\n    assert.ok(!moment.isMoment(1), 'number is not moment object');\n    assert.ok(!moment.isMoment(NaN), 'NaN is not moment object');\n    assert.ok(!moment.isMoment(null), 'null is not moment object');\n    assert.ok(!moment.isMoment(undefined), 'undefined is not moment object');\n});\n\ntest('is moment with hacked hasOwnProperty', function (assert) {\n    var obj = {};\n    // HACK to suppress jshint warning about bad property name\n    obj['hasOwnMoney'.replace('Money', 'Property')] = function () {\n        return true;\n    };\n\n    assert.ok(!moment.isMoment(obj), 'isMoment works even if passed object has a wrong hasOwnProperty implementation (ie8)');\n});\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/test/moment/is_number.js",
    "content": "import { module, test } from '../qunit';\nimport isNumber from '../../lib/utils/is-number.js';\n\n\ntest('isNumber recognizes numbers', function (assert) {\n    assert.ok(isNumber(1), 'simple integer');\n    assert.ok(isNumber(0), 'simple number');\n    assert.ok(isNumber(-0), 'silly number');\n    assert.ok(isNumber(1010010293029), 'large number');\n    assert.ok(isNumber(Infinity), 'largest number');\n    assert.ok(isNumber(-Infinity), 'smallest number');\n    assert.ok(isNumber(NaN), 'not number');\n    assert.ok(isNumber(1.100393830000), 'decimal numbers');\n    assert.ok(isNumber(Math.LN2), 'natural log of two');\n    assert.ok(isNumber(Math.PI), 'delicious number');\n    assert.ok(isNumber(5e10), 'scientifically notated number');\n    assert.ok(isNumber(new Number(1)), 'number primitive wrapped in an object'); // jshint ignore:line\n});\n\ntest('isNumber rejects non-numbers', function (assert) {\n    assert.ok(!isNumber(), 'nothing');\n    assert.ok(!isNumber(undefined), 'undefined');\n    assert.ok(!isNumber(null), 'null');\n    assert.ok(!isNumber([1]), 'array');\n    assert.ok(!isNumber('[1,2,3]'), 'string');\n    assert.ok(!isNumber(new Date()), 'date');\n    assert.ok(!isNumber({a:1,b:2}), 'object');\n});\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/test/moment/is_same.js",
    "content": "import { module, test } from '../qunit';\nimport moment from '../../moment';\n\nmodule('is same');\n\ntest('is same without units', function (assert) {\n    var m = moment(new Date(2011, 3, 2, 3, 4, 5, 10)), mCopy = moment(m);\n    assert.equal(m.isSame(moment(new Date(2012, 3, 2, 3, 5, 5, 10))), false, 'year is later');\n    assert.equal(m.isSame(moment(new Date(2010, 3, 2, 3, 3, 5, 10))), false, 'year is earlier');\n    assert.equal(m.isSame(moment(new Date(2011, 4, 2, 3, 4, 5, 10))), false, 'month is later');\n    assert.equal(m.isSame(moment(new Date(2011, 2, 2, 3, 4, 5, 10))), false, 'month is earlier');\n    assert.equal(m.isSame(moment(new Date(2011, 3, 3, 3, 4, 5, 10))), false, 'day is later');\n    assert.equal(m.isSame(moment(new Date(2011, 3, 1, 3, 4, 5, 10))), false, 'day is earlier');\n    assert.equal(m.isSame(moment(new Date(2011, 3, 2, 4, 4, 5, 10))), false, 'hour is later');\n    assert.equal(m.isSame(moment(new Date(2011, 3, 2, 2, 4, 5, 10))), false, 'hour is earlier');\n    assert.equal(m.isSame(moment(new Date(2011, 3, 2, 3, 5, 5, 10))), false, 'minute is later');\n    assert.equal(m.isSame(moment(new Date(2011, 3, 2, 3, 3, 5, 10))), false, 'minute is earlier');\n    assert.equal(m.isSame(moment(new Date(2011, 3, 2, 3, 4, 6, 10))), false, 'second is later');\n    assert.equal(m.isSame(moment(new Date(2011, 3, 2, 3, 4, 4, 11))), false, 'second is earlier');\n    assert.equal(m.isSame(moment(new Date(2011, 3, 2, 3, 4, 5, 10))), true, 'millisecond match');\n    assert.equal(m.isSame(moment(new Date(2011, 3, 2, 3, 4, 5, 11))), false, 'millisecond is later');\n    assert.equal(m.isSame(moment(new Date(2011, 3, 2, 3, 4, 5, 9))), false, 'millisecond is earlier');\n    assert.equal(m.isSame(m), true, 'moments are the same as themselves');\n    assert.equal(+m, +mCopy, 'isSame second should not change moment');\n});\n\ntest('is same year', function (assert) {\n    var m = moment(new Date(2011, 1, 2, 3, 4, 5, 6)), mCopy = moment(m);\n    assert.equal(m.isSame(moment(new Date(2011, 5, 6, 7, 8, 9, 10)), 'year'), true, 'year match');\n    assert.equal(m.isSame(moment(new Date(2011, 5, 6, 7, 8, 9, 10)), 'years'), true, 'plural should work');\n    assert.equal(m.isSame(moment(new Date(2012, 5, 6, 7, 8, 9, 10)), 'year'), false, 'year mismatch');\n    assert.equal(m.isSame(moment(new Date(2011, 0, 1, 0, 0, 0, 0)), 'year'), true, 'exact start of year');\n    assert.equal(m.isSame(moment(new Date(2011, 11, 31, 23, 59, 59, 999)), 'year'), true, 'exact end of year');\n    assert.equal(m.isSame(moment(new Date(2012, 0, 1, 0, 0, 0, 0)), 'year'), false, 'start of next year');\n    assert.equal(m.isSame(moment(new Date(2010, 11, 31, 23, 59, 59, 999)), 'year'), false, 'end of previous year');\n    assert.equal(m.isSame(m, 'year'), true, 'same moments are in the same year');\n    assert.equal(+m, +mCopy, 'isSame year should not change moment');\n});\n\ntest('is same month', function (assert) {\n    var m = moment(new Date(2011, 2, 3, 4, 5, 6, 7)), mCopy = moment(m);\n    assert.equal(m.isSame(moment(new Date(2011, 2, 6, 7, 8, 9, 10)), 'month'), true, 'month match');\n    assert.equal(m.isSame(moment(new Date(2011, 2, 6, 7, 8, 9, 10)), 'months'), true, 'plural should work');\n    assert.equal(m.isSame(moment(new Date(2012, 2, 6, 7, 8, 9, 10)), 'month'), false, 'year mismatch');\n    assert.equal(m.isSame(moment(new Date(2011, 5, 6, 7, 8, 9, 10)), 'month'), false, 'month mismatch');\n    assert.equal(m.isSame(moment(new Date(2011, 2, 1, 0, 0, 0, 0)), 'month'), true, 'exact start of month');\n    assert.equal(m.isSame(moment(new Date(2011, 2, 31, 23, 59, 59, 999)), 'month'), true, 'exact end of month');\n    assert.equal(m.isSame(moment(new Date(2011, 3, 1, 0, 0, 0, 0)), 'month'), false, 'start of next month');\n    assert.equal(m.isSame(moment(new Date(2011, 1, 27, 23, 59, 59, 999)), 'month'), false, 'end of previous month');\n    assert.equal(m.isSame(m, 'month'), true, 'same moments are in the same month');\n    assert.equal(+m, +mCopy, 'isSame month should not change moment');\n});\n\ntest('is same day', function (assert) {\n    var m = moment(new Date(2011, 1, 2, 3, 4, 5, 6)), mCopy = moment(m);\n    assert.equal(m.isSame(moment(new Date(2011, 1, 2, 7, 8, 9, 10)), 'day'), true, 'day match');\n    assert.equal(m.isSame(moment(new Date(2011, 1, 2, 7, 8, 9, 10)), 'days'), true, 'plural should work');\n    assert.equal(m.isSame(moment(new Date(2012, 1, 2, 7, 8, 9, 10)), 'day'), false, 'year mismatch');\n    assert.equal(m.isSame(moment(new Date(2011, 2, 2, 7, 8, 9, 10)), 'day'), false, 'month mismatch');\n    assert.equal(m.isSame(moment(new Date(2011, 1, 3, 7, 8, 9, 10)), 'day'), false, 'day mismatch');\n    assert.equal(m.isSame(moment(new Date(2011, 1, 2, 0, 0, 0, 0)), 'day'), true, 'exact start of day');\n    assert.equal(m.isSame(moment(new Date(2011, 1, 2, 23, 59, 59, 999)), 'day'), true, 'exact end of day');\n    assert.equal(m.isSame(moment(new Date(2011, 1, 3, 0, 0, 0, 0)), 'day'), false, 'start of next day');\n    assert.equal(m.isSame(moment(new Date(2011, 1, 1, 23, 59, 59, 999)), 'day'), false, 'end of previous day');\n    assert.equal(m.isSame(m, 'day'), true, 'same moments are in the same day');\n    assert.equal(+m, +mCopy, 'isSame day should not change moment');\n});\n\ntest('is same hour', function (assert) {\n    var m = moment(new Date(2011, 1, 2, 3, 4, 5, 6)), mCopy = moment(m);\n    assert.equal(m.isSame(moment(new Date(2011, 1, 2, 3, 8, 9, 10)), 'hour'), true, 'hour match');\n    assert.equal(m.isSame(moment(new Date(2011, 1, 2, 3, 8, 9, 10)), 'hours'), true, 'plural should work');\n    assert.equal(m.isSame(moment(new Date(2012, 1, 2, 3, 8, 9, 10)), 'hour'), false, 'year mismatch');\n    assert.equal(m.isSame(moment(new Date(2011, 2, 2, 3, 8, 9, 10)), 'hour'), false, 'month mismatch');\n    assert.equal(m.isSame(moment(new Date(2011, 1, 3, 3, 8, 9, 10)), 'hour'), false, 'day mismatch');\n    assert.equal(m.isSame(moment(new Date(2011, 1, 2, 4, 8, 9, 10)), 'hour'), false, 'hour mismatch');\n    assert.equal(m.isSame(moment(new Date(2011, 1, 2, 3, 0, 0, 0)), 'hour'), true, 'exact start of hour');\n    assert.equal(m.isSame(moment(new Date(2011, 1, 2, 3, 59, 59, 999)), 'hour'), true, 'exact end of hour');\n    assert.equal(m.isSame(moment(new Date(2011, 1, 2, 4, 0, 0, 0)), 'hour'), false, 'start of next hour');\n    assert.equal(m.isSame(moment(new Date(2011, 1, 2, 2, 59, 59, 999)), 'hour'), false, 'end of previous hour');\n    assert.equal(m.isSame(m, 'hour'), true, 'same moments are in the same hour');\n    assert.equal(+m, +mCopy, 'isSame hour should not change moment');\n});\n\ntest('is same minute', function (assert) {\n    var m = moment(new Date(2011, 1, 2, 3, 4, 5, 6)), mCopy = moment(m);\n    assert.equal(m.isSame(moment(new Date(2011, 1, 2, 3, 4, 9, 10)), 'minute'), true, 'minute match');\n    assert.equal(m.isSame(moment(new Date(2011, 1, 2, 3, 4, 9, 10)), 'minutes'), true, 'plural should work');\n    assert.equal(m.isSame(moment(new Date(2012, 1, 2, 3, 4, 9, 10)), 'minute'), false, 'year mismatch');\n    assert.equal(m.isSame(moment(new Date(2011, 2, 2, 3, 4, 9, 10)), 'minute'), false, 'month mismatch');\n    assert.equal(m.isSame(moment(new Date(2011, 1, 3, 3, 4, 9, 10)), 'minute'), false, 'day mismatch');\n    assert.equal(m.isSame(moment(new Date(2011, 1, 2, 4, 4, 9, 10)), 'minute'), false, 'hour mismatch');\n    assert.equal(m.isSame(moment(new Date(2011, 1, 2, 3, 5, 9, 10)), 'minute'), false, 'minute mismatch');\n    assert.equal(m.isSame(moment(new Date(2011, 1, 2, 3, 4, 0, 0)), 'minute'), true, 'exact start of minute');\n    assert.equal(m.isSame(moment(new Date(2011, 1, 2, 3, 4, 59, 999)), 'minute'), true, 'exact end of minute');\n    assert.equal(m.isSame(moment(new Date(2011, 1, 2, 3, 5, 0, 0)), 'minute'), false, 'start of next minute');\n    assert.equal(m.isSame(moment(new Date(2011, 1, 2, 3, 3, 59, 999)), 'minute'), false, 'end of previous minute');\n    assert.equal(m.isSame(m, 'minute'), true, 'same moments are in the same minute');\n    assert.equal(+m, +mCopy, 'isSame minute should not change moment');\n});\n\ntest('is same second', function (assert) {\n    var m = moment(new Date(2011, 1, 2, 3, 4, 5, 6)), mCopy = moment(m);\n    assert.equal(m.isSame(moment(new Date(2011, 1, 2, 3, 4, 5, 10)), 'second'), true, 'second match');\n    assert.equal(m.isSame(moment(new Date(2011, 1, 2, 3, 4, 5, 10)), 'seconds'), true, 'plural should work');\n    assert.equal(m.isSame(moment(new Date(2012, 1, 2, 3, 4, 5, 10)), 'second'), false, 'year mismatch');\n    assert.equal(m.isSame(moment(new Date(2011, 2, 2, 3, 4, 5, 10)), 'second'), false, 'month mismatch');\n    assert.equal(m.isSame(moment(new Date(2011, 1, 3, 3, 4, 5, 10)), 'second'), false, 'day mismatch');\n    assert.equal(m.isSame(moment(new Date(2011, 1, 2, 4, 4, 5, 10)), 'second'), false, 'hour mismatch');\n    assert.equal(m.isSame(moment(new Date(2011, 1, 2, 3, 5, 5, 10)), 'second'), false, 'minute mismatch');\n    assert.equal(m.isSame(moment(new Date(2011, 1, 2, 3, 4, 6, 10)), 'second'), false, 'second mismatch');\n    assert.equal(m.isSame(moment(new Date(2011, 1, 2, 3, 4, 5, 0)), 'second'), true, 'exact start of second');\n    assert.equal(m.isSame(moment(new Date(2011, 1, 2, 3, 4, 5, 999)), 'second'), true, 'exact end of second');\n    assert.equal(m.isSame(moment(new Date(2011, 1, 2, 3, 4, 6, 0)), 'second'), false, 'start of next second');\n    assert.equal(m.isSame(moment(new Date(2011, 1, 2, 3, 4, 4, 999)), 'second'), false, 'end of previous second');\n    assert.equal(m.isSame(m, 'second'), true, 'same moments are in the same second');\n    assert.equal(+m, +mCopy, 'isSame second should not change moment');\n});\n\ntest('is same millisecond', function (assert) {\n    var m = moment(new Date(2011, 3, 2, 3, 4, 5, 10)), mCopy = moment(m);\n    assert.equal(m.isSame(moment(new Date(2011, 3, 2, 3, 4, 5, 10)), 'millisecond'), true, 'millisecond match');\n    assert.equal(m.isSame(moment(new Date(2011, 3, 2, 3, 4, 5, 10)), 'milliseconds'), true, 'plural should work');\n    assert.equal(m.isSame(moment(new Date(2012, 3, 2, 3, 4, 5, 10)), 'millisecond'), false, 'year is later');\n    assert.equal(m.isSame(moment(new Date(2010, 3, 2, 3, 4, 5, 10)), 'millisecond'), false, 'year is earlier');\n    assert.equal(m.isSame(moment(new Date(2011, 4, 2, 3, 4, 5, 10)), 'millisecond'), false, 'month is later');\n    assert.equal(m.isSame(moment(new Date(2011, 2, 2, 3, 4, 5, 10)), 'millisecond'), false, 'month is earlier');\n    assert.equal(m.isSame(moment(new Date(2011, 3, 3, 3, 4, 5, 10)), 'millisecond'), false, 'day is later');\n    assert.equal(m.isSame(moment(new Date(2011, 3, 1, 1, 4, 5, 10)), 'millisecond'), false, 'day is earlier');\n    assert.equal(m.isSame(moment(new Date(2011, 3, 2, 4, 4, 5, 10)), 'millisecond'), false, 'hour is later');\n    assert.equal(m.isSame(moment(new Date(2011, 3, 1, 4, 1, 5, 10)), 'millisecond'), false, 'hour is earlier');\n    assert.equal(m.isSame(moment(new Date(2011, 3, 2, 3, 5, 5, 10)), 'millisecond'), false, 'minute is later');\n    assert.equal(m.isSame(moment(new Date(2011, 3, 2, 3, 3, 5, 10)), 'millisecond'), false, 'minute is earlier');\n    assert.equal(m.isSame(moment(new Date(2011, 3, 2, 3, 4, 6, 10)), 'millisecond'), false, 'second is later');\n    assert.equal(m.isSame(moment(new Date(2011, 3, 2, 3, 4, 4, 5)), 'millisecond'), false, 'second is earlier');\n    assert.equal(m.isSame(moment(new Date(2011, 3, 2, 3, 4, 6, 11)), 'millisecond'), false, 'millisecond is later');\n    assert.equal(m.isSame(moment(new Date(2011, 3, 2, 3, 4, 4, 9)), 'millisecond'), false, 'millisecond is earlier');\n    assert.equal(m.isSame(m, 'millisecond'), true, 'same moments are in the same millisecond');\n    assert.equal(+m, +mCopy, 'isSame millisecond should not change moment');\n});\n\ntest('is same with utc offset moments', function (assert) {\n    assert.ok(moment.parseZone('2013-02-01T00:00:00-05:00').isSame(moment('2013-02-01'), 'year'), 'zoned vs local moment');\n    assert.ok(moment('2013-02-01').isSame(moment('2013-02-01').utcOffset('-05:00'), 'year'), 'local vs zoned moment');\n    assert.ok(moment.parseZone('2013-02-01T00:00:00-05:00').isSame(moment.parseZone('2013-02-01T00:00:00-06:30'), 'year'),\n            'zoned vs (differently) zoned moment');\n});\n\ntest('is same with invalid moments', function (assert) {\n    assert.equal(moment.invalid().isSame(moment.invalid()), false, 'invalid moments are not considered equal');\n});\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/test/moment/is_same_or_after.js",
    "content": "import { module, test } from '../qunit';\nimport moment from '../../moment';\n\nmodule('is same or after');\n\ntest('is same or after without units', function (assert) {\n    var m = moment(new Date(2011, 3, 2, 3, 4, 5, 10)), mCopy = moment(m);\n    assert.equal(m.isSameOrAfter(moment(new Date(2012, 3, 2, 3, 5, 5, 10))), false, 'year is later');\n    assert.equal(m.isSameOrAfter(moment(new Date(2010, 3, 2, 3, 3, 5, 10))), true, 'year is earlier');\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 4, 2, 3, 4, 5, 10))), false, 'month is later');\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 2, 2, 3, 4, 5, 10))), true, 'month is earlier');\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 3, 3, 3, 4, 5, 10))), false, 'day is later');\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 3, 1, 3, 4, 5, 10))), true, 'day is earlier');\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 3, 2, 4, 4, 5, 10))), false, 'hour is later');\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 3, 2, 2, 4, 5, 10))), true, 'hour is earlier');\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 3, 2, 3, 5, 5, 10))), false, 'minute is later');\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 3, 2, 3, 3, 5, 10))), true, 'minute is earlier');\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 3, 2, 3, 4, 6, 10))), false, 'second is later');\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 3, 2, 3, 4, 4, 11))), true, 'second is earlier');\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 3, 2, 3, 4, 5, 10))), true, 'millisecond match');\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 3, 2, 3, 4, 5, 11))), false, 'millisecond is later');\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 3, 2, 3, 4, 5, 9))), true, 'millisecond is earlier');\n    assert.equal(m.isSameOrAfter(m), true, 'moments are the same as themselves');\n    assert.equal(+m, +mCopy, 'isSameOrAfter second should not change moment');\n});\n\ntest('is same or after year', function (assert) {\n    var m = moment(new Date(2011, 1, 2, 3, 4, 5, 6)), mCopy = moment(m);\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 5, 6, 7, 8, 9, 10)), 'year'), true, 'year match');\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 5, 6, 7, 8, 9, 10)), 'years'), true, 'plural should work');\n    assert.equal(m.isSameOrAfter(moment(new Date(2012, 5, 6, 7, 8, 9, 10)), 'year'), false, 'year is later');\n    assert.equal(m.isSameOrAfter(moment(new Date(2010, 5, 6, 7, 8, 9, 10)), 'year'), true, 'year is earlier');\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 0, 1, 0, 0, 0, 0)), 'year'), true, 'exact start of year');\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 11, 31, 23, 59, 59, 999)), 'year'), true, 'exact end of year');\n    assert.equal(m.isSameOrAfter(moment(new Date(2012, 0, 1, 0, 0, 0, 0)), 'year'), false, 'start of next year');\n    assert.equal(m.isSameOrAfter(moment(new Date(2010, 11, 31, 23, 59, 59, 999)), 'year'), true, 'end of previous year');\n    assert.equal(m.isSameOrAfter(m, 'year'), true, 'same moments are in the same year');\n    assert.equal(+m, +mCopy, 'isSameOrAfter year should not change moment');\n});\n\ntest('is same or after month', function (assert) {\n    var m = moment(new Date(2011, 2, 3, 4, 5, 6, 7)), mCopy = moment(m);\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 2, 6, 7, 8, 9, 10)), 'month'), true, 'month match');\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 2, 6, 7, 8, 9, 10)), 'months'), true, 'plural should work');\n    assert.equal(m.isSameOrAfter(moment(new Date(2012, 2, 6, 7, 8, 9, 10)), 'month'), false, 'year is later');\n    assert.equal(m.isSameOrAfter(moment(new Date(2010, 2, 6, 7, 8, 9, 10)), 'month'), true, 'year is earlier');\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 5, 6, 7, 8, 9, 10)), 'month'), false, 'month is later');\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 1, 6, 7, 8, 9, 10)), 'month'), true, 'month is earlier');\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 2, 1, 0, 0, 0, 0)), 'month'), true, 'exact start of month');\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 2, 31, 23, 59, 59, 999)), 'month'), true, 'exact end of month');\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 3, 1, 0, 0, 0, 0)), 'month'), false, 'start of next month');\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 1, 27, 23, 59, 59, 999)), 'month'), true, 'end of previous month');\n    assert.equal(m.isSameOrAfter(m, 'month'), true, 'same moments are in the same month');\n    assert.equal(+m, +mCopy, 'isSameOrAfter month should not change moment');\n});\n\ntest('is same or after day', function (assert) {\n    var m = moment(new Date(2011, 1, 2, 3, 4, 5, 6)), mCopy = moment(m);\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 1, 2, 7, 8, 9, 10)), 'day'), true, 'day match');\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 1, 2, 7, 8, 9, 10)), 'days'), true, 'plural should work');\n    assert.equal(m.isSameOrAfter(moment(new Date(2012, 1, 2, 7, 8, 9, 10)), 'day'), false, 'year is later');\n    assert.equal(m.isSameOrAfter(moment(new Date(2010, 1, 2, 7, 8, 9, 10)), 'day'), true, 'year is earlier');\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 2, 2, 7, 8, 9, 10)), 'day'), false, 'month is later');\n    assert.equal(m.isSameOrAfter(moment(new Date(2010, 12, 2, 7, 8, 9, 10)), 'day'), true, 'month is earlier');\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 1, 3, 7, 8, 9, 10)), 'day'), false, 'day is later');\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 1, 1, 7, 8, 9, 10)), 'day'), true, 'day is earlier');\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 1, 2, 0, 0, 0, 0)), 'day'), true, 'exact start of day');\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 1, 2, 23, 59, 59, 999)), 'day'), true, 'exact end of day');\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 1, 3, 0, 0, 0, 0)), 'day'), false, 'start of next day');\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 1, 1, 23, 59, 59, 999)), 'day'), true, 'end of previous day');\n    assert.equal(m.isSameOrAfter(m, 'day'), true, 'same moments are in the same day');\n    assert.equal(+m, +mCopy, 'isSameOrAfter day should not change moment');\n});\n\ntest('is same or after hour', function (assert) {\n    var m = moment(new Date(2011, 1, 2, 3, 4, 5, 6)), mCopy = moment(m);\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 1, 2, 3, 8, 9, 10)), 'hour'), true, 'hour match');\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 1, 2, 3, 8, 9, 10)), 'hours'), true, 'plural should work');\n    assert.equal(m.isSameOrAfter(moment(new Date(2012, 1, 2, 3, 8, 9, 10)), 'hour'), false, 'year is later');\n    assert.equal(m.isSameOrAfter(moment(new Date(2010, 1, 2, 3, 8, 9, 10)), 'hour'), true, 'year is earlier');\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 2, 2, 3, 8, 9, 10)), 'hour'), false, 'month is later');\n    assert.equal(m.isSameOrAfter(moment(new Date(2010, 12, 2, 3, 8, 9, 10)), 'hour'), true, 'month is earlier');\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 1, 3, 3, 8, 9, 10)), 'hour'), false, 'day is later');\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 1, 1, 3, 8, 9, 10)), 'hour'), true, 'day is earlier');\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 1, 2, 4, 8, 9, 10)), 'hour'), false, 'hour is later');\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 1, 2, 2, 8, 9, 10)), 'hour'), true, 'hour is earlier');\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 1, 2, 3, 0, 0, 0)), 'hour'), true, 'exact start of hour');\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 1, 2, 3, 59, 59, 999)), 'hour'), true, 'exact end of hour');\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 1, 2, 4, 0, 0, 0)), 'hour'), false, 'start of next hour');\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 1, 2, 2, 59, 59, 999)), 'hour'), true, 'end of previous hour');\n    assert.equal(m.isSameOrAfter(m, 'hour'), true, 'same moments are in the same hour');\n    assert.equal(+m, +mCopy, 'isSameOrAfter hour should not change moment');\n});\n\ntest('is same or after minute', function (assert) {\n    var m = moment(new Date(2011, 1, 2, 3, 4, 5, 6)), mCopy = moment(m);\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 1, 2, 3, 4, 9, 10)), 'minute'), true, 'minute match');\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 1, 2, 3, 4, 9, 10)), 'minutes'), true, 'plural should work');\n    assert.equal(m.isSameOrAfter(moment(new Date(2012, 1, 2, 3, 4, 9, 10)), 'minute'), false, 'year is later');\n    assert.equal(m.isSameOrAfter(moment(new Date(2010, 1, 2, 3, 4, 9, 10)), 'minute'), true, 'year is earlier');\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 2, 2, 3, 4, 9, 10)), 'minute'), false, 'month is later');\n    assert.equal(m.isSameOrAfter(moment(new Date(2010, 12, 2, 3, 4, 9, 10)), 'minute'), true, 'month is earlier');\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 1, 3, 3, 4, 9, 10)), 'minute'), false, 'day is later');\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 1, 1, 3, 4, 9, 10)), 'minute'), true, 'day is earlier');\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 1, 2, 4, 4, 9, 10)), 'minute'), false, 'hour is later');\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 1, 2, 2, 4, 9, 10)), 'minute'), true, 'hour is earlier');\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 1, 2, 3, 5, 9, 10)), 'minute'), false, 'minute is later');\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 1, 2, 3, 3, 9, 10)), 'minute'), true, 'minute is earlier');\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 1, 2, 3, 4, 0, 0)), 'minute'), true, 'exact start of minute');\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 1, 2, 3, 4, 59, 999)), 'minute'), true, 'exact end of minute');\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 1, 2, 3, 5, 0, 0)), 'minute'), false, 'start of next minute');\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 1, 2, 3, 3, 59, 999)), 'minute'), true, 'end of previous minute');\n    assert.equal(m.isSameOrAfter(m, 'minute'), true, 'same moments are in the same minute');\n    assert.equal(+m, +mCopy, 'isSameOrAfter minute should not change moment');\n});\n\ntest('is same or after second', function (assert) {\n    var m = moment(new Date(2011, 1, 2, 3, 4, 5, 6)), mCopy = moment(m);\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 1, 2, 3, 4, 5, 10)), 'second'), true, 'second match');\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 1, 2, 3, 4, 5, 10)), 'seconds'), true, 'plural should work');\n    assert.equal(m.isSameOrAfter(moment(new Date(2012, 1, 2, 3, 4, 5, 10)), 'second'), false, 'year is later');\n    assert.equal(m.isSameOrAfter(moment(new Date(2010, 1, 2, 3, 4, 5, 10)), 'second'), true, 'year is earlier');\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 2, 2, 3, 4, 5, 10)), 'second'), false, 'month is later');\n    assert.equal(m.isSameOrAfter(moment(new Date(2010, 12, 2, 3, 4, 5, 10)), 'second'), true, 'month is earlier');\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 1, 3, 3, 4, 5, 10)), 'second'), false, 'day is later');\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 1, 1, 3, 4, 5, 10)), 'second'), true, 'day is earlier');\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 1, 2, 4, 4, 5, 10)), 'second'), false, 'hour is later');\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 1, 2, 2, 4, 5, 10)), 'second'), true, 'hour is earlier');\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 1, 2, 3, 5, 5, 10)), 'second'), false, 'minute is later');\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 1, 2, 3, 3, 5, 10)), 'second'), true, 'minute is earlier');\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 1, 2, 3, 4, 6, 10)), 'second'), false, 'second is later');\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 1, 2, 3, 4, 4, 10)), 'second'), true, 'second is earlier');\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 1, 2, 3, 4, 5, 0)), 'second'), true, 'exact start of second');\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 1, 2, 3, 4, 5, 999)), 'second'), true, 'exact end of second');\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 1, 2, 3, 4, 6, 0)), 'second'), false, 'start of next second');\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 1, 2, 3, 4, 4, 999)), 'second'), true, 'end of previous second');\n    assert.equal(m.isSameOrAfter(m, 'second'), true, 'same moments are in the same second');\n    assert.equal(+m, +mCopy, 'isSameOrAfter second should not change moment');\n});\n\ntest('is same or after millisecond', function (assert) {\n    var m = moment(new Date(2011, 3, 2, 3, 4, 5, 10)), mCopy = moment(m);\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 3, 2, 3, 4, 5, 10)), 'millisecond'), true, 'millisecond match');\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 3, 2, 3, 4, 5, 10)), 'milliseconds'), true, 'plural should work');\n    assert.equal(m.isSameOrAfter(moment(new Date(2012, 3, 2, 3, 4, 5, 10)), 'millisecond'), false, 'year is later');\n    assert.equal(m.isSameOrAfter(moment(new Date(2010, 3, 2, 3, 4, 5, 10)), 'millisecond'), true, 'year is earlier');\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 4, 2, 3, 4, 5, 10)), 'millisecond'), false, 'month is later');\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 2, 2, 3, 4, 5, 10)), 'millisecond'), true, 'month is earlier');\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 3, 3, 3, 4, 5, 10)), 'millisecond'), false, 'day is later');\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 3, 1, 1, 4, 5, 10)), 'millisecond'), true, 'day is earlier');\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 3, 2, 4, 4, 5, 10)), 'millisecond'), false, 'hour is later');\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 3, 1, 4, 1, 5, 10)), 'millisecond'), true, 'hour is earlier');\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 3, 2, 3, 5, 5, 10)), 'millisecond'), false, 'minute is later');\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 3, 2, 3, 3, 5, 10)), 'millisecond'), true, 'minute is earlier');\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 3, 2, 3, 4, 6, 10)), 'millisecond'), false, 'second is later');\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 3, 2, 3, 4, 4, 5)), 'millisecond'), true, 'second is earlier');\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 3, 2, 3, 4, 6, 11)), 'millisecond'), false, 'millisecond is later');\n    assert.equal(m.isSameOrAfter(moment(new Date(2011, 3, 2, 3, 4, 4, 9)), 'millisecond'), true, 'millisecond is earlier');\n    assert.equal(m.isSameOrAfter(m, 'millisecond'), true, 'same moments are in the same millisecond');\n    assert.equal(+m, +mCopy, 'isSameOrAfter millisecond should not change moment');\n});\n\ntest('is same or after with utc offset moments', function (assert) {\n    assert.ok(moment.parseZone('2013-02-01T00:00:00-05:00').isSameOrAfter(moment('2013-02-01'), 'year'), 'zoned vs local moment');\n    assert.ok(moment('2013-02-01').isSameOrAfter(moment('2013-02-01').utcOffset('-05:00'), 'year'), 'local vs zoned moment');\n    assert.ok(moment.parseZone('2013-02-01T00:00:00-05:00').isSameOrAfter(moment.parseZone('2013-02-01T00:00:00-06:30'), 'year'),\n            'zoned vs (differently) zoned moment');\n});\n\ntest('is same or after with invalid moments', function (assert) {\n    var m = moment(), invalid = moment.invalid();\n    assert.equal(invalid.isSameOrAfter(invalid), false, 'invalid moments are not considered equal');\n    assert.equal(m.isSameOrAfter(invalid), false, 'valid moment is not after invalid moment');\n    assert.equal(invalid.isSameOrAfter(m), false, 'invalid moment is not after valid moment');\n    assert.equal(m.isSameOrAfter(invalid, 'year'), false, 'invalid moment year');\n    assert.equal(m.isSameOrAfter(invalid, 'month'), false, 'invalid moment month');\n    assert.equal(m.isSameOrAfter(invalid, 'day'), false, 'invalid moment day');\n    assert.equal(m.isSameOrAfter(invalid, 'hour'), false, 'invalid moment hour');\n    assert.equal(m.isSameOrAfter(invalid, 'minute'), false, 'invalid moment minute');\n    assert.equal(m.isSameOrAfter(invalid, 'second'), false, 'invalid moment second');\n    assert.equal(m.isSameOrAfter(invalid, 'milliseconds'), false, 'invalid moment milliseconds');\n});\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/test/moment/is_same_or_before.js",
    "content": "import { module, test } from '../qunit';\nimport moment from '../../moment';\n\nmodule('is same or before');\n\ntest('is same or before without units', function (assert) {\n    var m = moment(new Date(2011, 3, 2, 3, 4, 5, 10)), mCopy = moment(m);\n    assert.equal(m.isSameOrBefore(moment(new Date(2012, 3, 2, 3, 5, 5, 10))), true, 'year is later');\n    assert.equal(m.isSameOrBefore(moment(new Date(2010, 3, 2, 3, 3, 5, 10))), false, 'year is earlier');\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 4, 2, 3, 4, 5, 10))), true, 'month is later');\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 2, 2, 3, 4, 5, 10))), false, 'month is earlier');\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 3, 3, 3, 4, 5, 10))), true, 'day is later');\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 3, 1, 3, 4, 5, 10))), false, 'day is earlier');\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 3, 2, 4, 4, 5, 10))), true, 'hour is later');\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 3, 2, 2, 4, 5, 10))), false, 'hour is earlier');\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 3, 2, 3, 5, 5, 10))), true, 'minute is later');\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 3, 2, 3, 3, 5, 10))), false, 'minute is earlier');\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 3, 2, 3, 4, 6, 10))), true, 'second is later');\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 3, 2, 3, 4, 4, 11))), false, 'second is earlier');\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 3, 2, 3, 4, 5, 10))), true, 'millisecond match');\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 3, 2, 3, 4, 5, 11))), true, 'millisecond is later');\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 3, 2, 3, 4, 5, 9))), false, 'millisecond is earlier');\n    assert.equal(m.isSameOrBefore(m), true, 'moments are the same as themselves');\n    assert.equal(+m, +mCopy, 'isSameOrBefore second should not change moment');\n});\n\ntest('is same or before year', function (assert) {\n    var m = moment(new Date(2011, 1, 2, 3, 4, 5, 6)), mCopy = moment(m);\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 5, 6, 7, 8, 9, 10)), 'year'), true, 'year match');\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 5, 6, 7, 8, 9, 10)), 'years'), true, 'plural should work');\n    assert.equal(m.isSameOrBefore(moment(new Date(2012, 5, 6, 7, 8, 9, 10)), 'year'), true, 'year is later');\n    assert.equal(m.isSameOrBefore(moment(new Date(2010, 5, 6, 7, 8, 9, 10)), 'year'), false, 'year is earlier');\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 0, 1, 0, 0, 0, 0)), 'year'), true, 'exact start of year');\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 11, 31, 23, 59, 59, 999)), 'year'), true, 'exact end of year');\n    assert.equal(m.isSameOrBefore(moment(new Date(2012, 0, 1, 0, 0, 0, 0)), 'year'), true, 'start of next year');\n    assert.equal(m.isSameOrBefore(moment(new Date(2010, 11, 31, 23, 59, 59, 999)), 'year'), false, 'end of previous year');\n    assert.equal(m.isSameOrBefore(m, 'year'), true, 'same moments are in the same year');\n    assert.equal(+m, +mCopy, 'isSameOrBefore year should not change moment');\n});\n\ntest('is same or before month', function (assert) {\n    var m = moment(new Date(2011, 2, 3, 4, 5, 6, 7)), mCopy = moment(m);\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 2, 6, 7, 8, 9, 10)), 'month'), true, 'month match');\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 2, 6, 7, 8, 9, 10)), 'months'), true, 'plural should work');\n    assert.equal(m.isSameOrBefore(moment(new Date(2012, 2, 6, 7, 8, 9, 10)), 'month'), true, 'year is later');\n    assert.equal(m.isSameOrBefore(moment(new Date(2010, 2, 6, 7, 8, 9, 10)), 'month'), false, 'year is earlier');\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 5, 6, 7, 8, 9, 10)), 'month'), true, 'month is later');\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 1, 6, 7, 8, 9, 10)), 'month'), false, 'month is earlier');\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 2, 1, 0, 0, 0, 0)), 'month'), true, 'exact start of month');\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 2, 31, 23, 59, 59, 999)), 'month'), true, 'exact end of month');\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 3, 1, 0, 0, 0, 0)), 'month'), true, 'start of next month');\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 1, 27, 23, 59, 59, 999)), 'month'), false, 'end of previous month');\n    assert.equal(m.isSameOrBefore(m, 'month'), true, 'same moments are in the same month');\n    assert.equal(+m, +mCopy, 'isSameOrBefore month should not change moment');\n});\n\ntest('is same or before day', function (assert) {\n    var m = moment(new Date(2011, 1, 2, 3, 4, 5, 6)), mCopy = moment(m);\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 1, 2, 7, 8, 9, 10)), 'day'), true, 'day match');\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 1, 2, 7, 8, 9, 10)), 'days'), true, 'plural should work');\n    assert.equal(m.isSameOrBefore(moment(new Date(2012, 1, 2, 7, 8, 9, 10)), 'day'), true, 'year is later');\n    assert.equal(m.isSameOrBefore(moment(new Date(2010, 1, 2, 7, 8, 9, 10)), 'day'), false, 'year is earlier');\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 2, 2, 7, 8, 9, 10)), 'day'), true, 'month is later');\n    assert.equal(m.isSameOrBefore(moment(new Date(2010, 12, 2, 7, 8, 9, 10)), 'day'), false, 'month is earlier');\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 1, 3, 7, 8, 9, 10)), 'day'), true, 'day is later');\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 1, 1, 7, 8, 9, 10)), 'day'), false, 'day is earlier');\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 1, 2, 0, 0, 0, 0)), 'day'), true, 'exact start of day');\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 1, 2, 23, 59, 59, 999)), 'day'), true, 'exact end of day');\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 1, 3, 0, 0, 0, 0)), 'day'), true, 'start of next day');\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 1, 1, 23, 59, 59, 999)), 'day'), false, 'end of previous day');\n    assert.equal(m.isSameOrBefore(m, 'day'), true, 'same moments are in the same day');\n    assert.equal(+m, +mCopy, 'isSameOrBefore day should not change moment');\n});\n\ntest('is same or before hour', function (assert) {\n    var m = moment(new Date(2011, 1, 2, 3, 4, 5, 6)), mCopy = moment(m);\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 1, 2, 3, 8, 9, 10)), 'hour'), true, 'hour match');\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 1, 2, 3, 8, 9, 10)), 'hours'), true, 'plural should work');\n    assert.equal(m.isSameOrBefore(moment(new Date(2012, 1, 2, 3, 8, 9, 10)), 'hour'), true, 'year is later');\n    assert.equal(m.isSameOrBefore(moment(new Date(2010, 1, 2, 3, 8, 9, 10)), 'hour'), false, 'year is earlier');\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 2, 2, 3, 8, 9, 10)), 'hour'), true, 'month is later');\n    assert.equal(m.isSameOrBefore(moment(new Date(2010, 12, 2, 3, 8, 9, 10)), 'hour'), false, 'month is earlier');\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 1, 3, 3, 8, 9, 10)), 'hour'), true, 'day is later');\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 1, 1, 3, 8, 9, 10)), 'hour'), false, 'day is earlier');\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 1, 2, 4, 8, 9, 10)), 'hour'), true, 'hour is later');\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 1, 2, 2, 8, 9, 10)), 'hour'), false, 'hour is earlier');\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 1, 2, 3, 0, 0, 0)), 'hour'), true, 'exact start of hour');\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 1, 2, 3, 59, 59, 999)), 'hour'), true, 'exact end of hour');\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 1, 2, 4, 0, 0, 0)), 'hour'), true, 'start of next hour');\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 1, 2, 2, 59, 59, 999)), 'hour'), false, 'end of previous hour');\n    assert.equal(m.isSameOrBefore(m, 'hour'), true, 'same moments are in the same hour');\n    assert.equal(+m, +mCopy, 'isSameOrBefore hour should not change moment');\n});\n\ntest('is same or before minute', function (assert) {\n    var m = moment(new Date(2011, 1, 2, 3, 4, 5, 6)), mCopy = moment(m);\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 1, 2, 3, 4, 9, 10)), 'minute'), true, 'minute match');\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 1, 2, 3, 4, 9, 10)), 'minutes'), true, 'plural should work');\n    assert.equal(m.isSameOrBefore(moment(new Date(2012, 1, 2, 3, 4, 9, 10)), 'minute'), true, 'year is later');\n    assert.equal(m.isSameOrBefore(moment(new Date(2010, 1, 2, 3, 4, 9, 10)), 'minute'), false, 'year is earlier');\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 2, 2, 3, 4, 9, 10)), 'minute'), true, 'month is later');\n    assert.equal(m.isSameOrBefore(moment(new Date(2010, 12, 2, 3, 4, 9, 10)), 'minute'), false, 'month is earlier');\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 1, 3, 3, 4, 9, 10)), 'minute'), true, 'day is later');\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 1, 1, 3, 4, 9, 10)), 'minute'), false, 'day is earlier');\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 1, 2, 4, 4, 9, 10)), 'minute'), true, 'hour is later');\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 1, 2, 2, 4, 9, 10)), 'minute'), false, 'hour is earlier');\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 1, 2, 3, 5, 9, 10)), 'minute'), true, 'minute is later');\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 1, 2, 3, 3, 9, 10)), 'minute'), false, 'minute is earlier');\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 1, 2, 3, 4, 0, 0)), 'minute'), true, 'exact start of minute');\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 1, 2, 3, 4, 59, 999)), 'minute'), true, 'exact end of minute');\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 1, 2, 3, 5, 0, 0)), 'minute'), true, 'start of next minute');\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 1, 2, 3, 3, 59, 999)), 'minute'), false, 'end of previous minute');\n    assert.equal(m.isSameOrBefore(m, 'minute'), true, 'same moments are in the same minute');\n    assert.equal(+m, +mCopy, 'isSameOrBefore minute should not change moment');\n});\n\ntest('is same or before second', function (assert) {\n    var m = moment(new Date(2011, 1, 2, 3, 4, 5, 6)), mCopy = moment(m);\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 1, 2, 3, 4, 5, 10)), 'second'), true, 'second match');\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 1, 2, 3, 4, 5, 10)), 'seconds'), true, 'plural should work');\n    assert.equal(m.isSameOrBefore(moment(new Date(2012, 1, 2, 3, 4, 5, 10)), 'second'), true, 'year is later');\n    assert.equal(m.isSameOrBefore(moment(new Date(2010, 1, 2, 3, 4, 5, 10)), 'second'), false, 'year is earlier');\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 2, 2, 3, 4, 5, 10)), 'second'), true, 'month is later');\n    assert.equal(m.isSameOrBefore(moment(new Date(2010, 12, 2, 3, 4, 5, 10)), 'second'), false, 'month is earlier');\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 1, 3, 3, 4, 5, 10)), 'second'), true, 'day is later');\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 1, 1, 3, 4, 5, 10)), 'second'), false, 'day is earlier');\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 1, 2, 4, 4, 5, 10)), 'second'), true, 'hour is later');\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 1, 2, 2, 4, 5, 10)), 'second'), false, 'hour is earlier');\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 1, 2, 3, 5, 5, 10)), 'second'), true, 'minute is later');\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 1, 2, 3, 3, 5, 10)), 'second'), false, 'minute is earlier');\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 1, 2, 3, 4, 6, 10)), 'second'), true, 'second is later');\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 1, 2, 3, 4, 4, 10)), 'second'), false, 'second is earlier');\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 1, 2, 3, 4, 5, 0)), 'second'), true, 'exact start of second');\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 1, 2, 3, 4, 5, 999)), 'second'), true, 'exact end of second');\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 1, 2, 3, 4, 6, 0)), 'second'), true, 'start of next second');\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 1, 2, 3, 4, 4, 999)), 'second'), false, 'end of previous second');\n    assert.equal(m.isSameOrBefore(m, 'second'), true, 'same moments are in the same second');\n    assert.equal(+m, +mCopy, 'isSameOrBefore second should not change moment');\n});\n\ntest('is same or before millisecond', function (assert) {\n    var m = moment(new Date(2011, 3, 2, 3, 4, 5, 10)), mCopy = moment(m);\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 3, 2, 3, 4, 5, 10)), 'millisecond'), true, 'millisecond match');\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 3, 2, 3, 4, 5, 10)), 'milliseconds'), true, 'plural should work');\n    assert.equal(m.isSameOrBefore(moment(new Date(2012, 3, 2, 3, 4, 5, 10)), 'millisecond'), true, 'year is later');\n    assert.equal(m.isSameOrBefore(moment(new Date(2010, 3, 2, 3, 4, 5, 10)), 'millisecond'), false, 'year is earlier');\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 4, 2, 3, 4, 5, 10)), 'millisecond'), true, 'month is later');\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 2, 2, 3, 4, 5, 10)), 'millisecond'), false, 'month is earlier');\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 3, 3, 3, 4, 5, 10)), 'millisecond'), true, 'day is later');\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 3, 1, 1, 4, 5, 10)), 'millisecond'), false, 'day is earlier');\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 3, 2, 4, 4, 5, 10)), 'millisecond'), true, 'hour is later');\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 3, 1, 4, 1, 5, 10)), 'millisecond'), false, 'hour is earlier');\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 3, 2, 3, 5, 5, 10)), 'millisecond'), true, 'minute is later');\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 3, 2, 3, 3, 5, 10)), 'millisecond'), false, 'minute is earlier');\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 3, 2, 3, 4, 6, 10)), 'millisecond'), true, 'second is later');\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 3, 2, 3, 4, 4, 5)), 'millisecond'), false, 'second is earlier');\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 3, 2, 3, 4, 6, 11)), 'millisecond'), true, 'millisecond is later');\n    assert.equal(m.isSameOrBefore(moment(new Date(2011, 3, 2, 3, 4, 4, 9)), 'millisecond'), false, 'millisecond is earlier');\n    assert.equal(m.isSameOrBefore(m, 'millisecond'), true, 'same moments are in the same millisecond');\n    assert.equal(+m, +mCopy, 'isSameOrBefore millisecond should not change moment');\n});\n\ntest('is same with utc offset moments', function (assert) {\n    assert.ok(moment.parseZone('2013-02-01T00:00:00-05:00').isSameOrBefore(moment('2013-02-01'), 'year'), 'zoned vs local moment');\n    assert.ok(moment('2013-02-01').isSameOrBefore(moment('2013-02-01').utcOffset('-05:00'), 'year'), 'local vs zoned moment');\n    assert.ok(\n      moment.parseZone('2013-02-01T00:00:00-05:00').isSameOrBefore(moment.parseZone('2013-02-01T00:00:00-06:30'), 'year'),\n      'zoned vs (differently) zoned moment'\n    );\n});\n\ntest('is same with invalid moments', function (assert) {\n    var m = moment(), invalid = moment.invalid();\n    assert.equal(invalid.isSameOrBefore(invalid), false, 'invalid moments are not considered equal');\n    assert.equal(m.isSameOrBefore(invalid), false, 'valid moment is not before invalid moment');\n    assert.equal(invalid.isSameOrBefore(m), false, 'invalid moment is not before valid moment');\n    assert.equal(m.isSameOrBefore(invalid, 'year'), false, 'invalid moment year');\n    assert.equal(m.isSameOrBefore(invalid, 'month'), false, 'invalid moment month');\n    assert.equal(m.isSameOrBefore(invalid, 'day'), false, 'invalid moment day');\n    assert.equal(m.isSameOrBefore(invalid, 'hour'), false, 'invalid moment hour');\n    assert.equal(m.isSameOrBefore(invalid, 'minute'), false, 'invalid moment minute');\n    assert.equal(m.isSameOrBefore(invalid, 'second'), false, 'invalid moment second');\n    assert.equal(m.isSameOrBefore(invalid, 'milliseconds'), false, 'invalid moment milliseconds');\n});\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/test/moment/is_valid.js",
    "content": "import { module, test } from '../qunit';\nimport moment from '../../moment';\n\nmodule('is valid');\n\ntest('array bad month', function (assert) {\n    assert.equal(moment([2010, -1]).isValid(), false, 'month -1 invalid');\n    assert.equal(moment([2100, 12]).isValid(), false, 'month 12 invalid');\n});\n\ntest('array good month', function (assert) {\n    for (var i = 0; i < 12; i++) {\n        assert.equal(moment([2010, i]).isValid(), true, 'month ' + i);\n        assert.equal(moment.utc([2010, i]).isValid(), true, 'month ' + i);\n    }\n});\n\ntest('array bad date', function (assert) {\n    var tests = [\n        moment([2010, 0, 0]),\n        moment([2100, 0, 32]),\n        moment.utc([2010, 0, 0]),\n        moment.utc([2100, 0, 32])\n    ],\n    i, m;\n\n    for (i in tests) {\n        m = tests[i];\n        assert.equal(m.isValid(), false);\n    }\n});\n\ntest('h/hh with hour > 12', function (assert) {\n    assert.ok(moment('06/20/2014 11:51 PM', 'MM/DD/YYYY hh:mm A', true).isValid(), '11 for hh');\n    assert.ok(moment('06/20/2014 11:51 AM', 'MM/DD/YYYY hh:mm A', true).isValid(), '11 for hh');\n    assert.ok(moment('06/20/2014 23:51 PM', 'MM/DD/YYYY hh:mm A').isValid(), 'non-strict validity 23 for hh');\n    assert.ok(moment('06/20/2014 23:51 PM', 'MM/DD/YYYY hh:mm A').parsingFlags().bigHour, 'non-strict bigHour 23 for hh');\n    assert.ok(!moment('06/20/2014 23:51 PM', 'MM/DD/YYYY hh:mm A', true).isValid(), 'validity 23 for hh');\n    assert.ok(moment('06/20/2014 23:51 PM', 'MM/DD/YYYY hh:mm A', true).parsingFlags().bigHour, 'bigHour 23 for hh');\n});\n\ntest('array bad date leap year', function (assert) {\n    assert.equal(moment([2010, 1, 29]).isValid(), false, '2010 feb 29');\n    assert.equal(moment([2100, 1, 29]).isValid(), false, '2100 feb 29');\n    assert.equal(moment([2008, 1, 30]).isValid(), false, '2008 feb 30');\n    assert.equal(moment([2000, 1, 30]).isValid(), false, '2000 feb 30');\n\n    assert.equal(moment.utc([2010, 1, 29]).isValid(), false, 'utc 2010 feb 29');\n    assert.equal(moment.utc([2100, 1, 29]).isValid(), false, 'utc 2100 feb 29');\n    assert.equal(moment.utc([2008, 1, 30]).isValid(), false, 'utc 2008 feb 30');\n    assert.equal(moment.utc([2000, 1, 30]).isValid(), false, 'utc 2000 feb 30');\n});\n\ntest('string + formats bad date', function (assert) {\n    assert.equal(moment('2020-00-00', []).isValid(), false, 'invalid on empty array');\n    assert.equal(moment('2020-00-00', ['YYYY-MM-DD', 'DD-MM-YYYY']).isValid(), false, 'invalid on all in array');\n    assert.equal(moment('2020-00-00', ['DD-MM-YYYY', 'YYYY-MM-DD']).isValid(), false, 'invalid on all in array');\n    assert.equal(moment('2020-01-01', ['YYYY-MM-DD', 'DD-MM-YYYY']).isValid(), true, 'valid on first');\n    assert.equal(moment('2020-01-01', ['DD-MM-YYYY', 'YYYY-MM-DD']).isValid(), true, 'valid on last');\n    assert.equal(moment('2020-01-01', ['YYYY-MM-DD', 'YYYY-DD-MM']).isValid(), true, 'valid on both');\n    assert.equal(moment('2020-13-01', ['YYYY-MM-DD', 'YYYY-DD-MM']).isValid(), true, 'valid on last');\n\n    assert.equal(moment('12-13-2012', ['DD-MM-YYYY', 'YYYY-MM-DD']).isValid(), false, 'month rollover');\n    assert.equal(moment('12-13-2012', ['DD-MM-YYYY', 'DD-MM-YYYY']).isValid(), false, 'month rollover');\n    assert.equal(moment('38-12-2012', ['DD-MM-YYYY']).isValid(), false, 'day rollover');\n});\n\ntest('string nonsensical with format', function (assert) {\n    assert.equal(moment('fail', 'MM-DD-YYYY').isValid(), false, 'string \\'fail\\' with format \\'MM-DD-YYYY\\'');\n    assert.equal(moment('xx-xx-2001', 'DD-MM-YYY').isValid(), true, 'string \\'xx-xx-2001\\' with format \\'MM-DD-YYYY\\'');\n});\n\ntest('string with bad month name', function (assert) {\n    assert.equal(moment('01-Nam-2012', 'DD-MMM-YYYY').isValid(), false, '\\'Nam\\' is an invalid month');\n    assert.equal(moment('01-Aug-2012', 'DD-MMM-YYYY').isValid(), true, '\\'Aug\\' is a valid month');\n});\n\ntest('string with spaceless format', function (assert) {\n    assert.equal(moment('10Sep2001', 'DDMMMYYYY').isValid(), true, 'Parsing 10Sep2001 should result in a valid date');\n});\n\ntest('invalid string iso 8601', function (assert) {\n    var tests = [\n        '2010-00-00',\n        '2010-01-00',\n        '2010-01-40',\n        '2010-01-01T24:01',  // 24:00:00 is actually valid\n        '2010-01-01T23:60',\n        '2010-01-01T23:59:60'\n    ], i;\n\n    for (i = 0; i < tests.length; i++) {\n        assert.equal(moment(tests[i], moment.ISO_8601).isValid(), false, tests[i] + ' should be invalid');\n        assert.equal(moment.utc(tests[i], moment.ISO_8601).isValid(), false, tests[i] + ' should be invalid');\n    }\n});\n\ntest('invalid string iso 8601 + timezone', function (assert) {\n    var tests = [\n        '2010-00-00T+00:00',\n        '2010-01-00T+00:00',\n        '2010-01-40T+00:00',\n        '2010-01-40T24:01+00:00',\n        '2010-01-40T23:60+00:00',\n        '2010-01-40T23:59:60+00:00',\n        '2010-01-40T23:59:59.9999+00:00',\n        '2010-01-40T23:59:59,9999+00:00'\n    ], i;\n\n    for (i = 0; i < tests.length; i++) {\n        assert.equal(moment(tests[i], moment.ISO_8601).isValid(), false, tests[i] + ' should be invalid');\n        assert.equal(moment.utc(tests[i], moment.ISO_8601).isValid(), false, tests[i] + ' should be invalid');\n    }\n});\n\ntest('valid string iso 8601 - not strict', function (assert) {\n    var tests = [\n        '2010-01-30 00:00:00,000Z',\n        '20100101',\n        '20100130',\n        '20100130T23+00:00',\n        '20100130T2359+0000',\n        '20100130T235959+0000',\n        '20100130T235959,999+0000',\n        '20100130T235959,999-0700',\n        '20100130T000000,000+0700',\n        '20100130 000000,000Z'\n    ];\n\n    for (var i = 0; i < tests.length; i++) {\n        assert.equal(moment(tests[i]).isValid(), true, tests[i] + ' should be valid in normal');\n        assert.equal(moment.utc(tests[i]).isValid(), true, tests[i] + ' should be valid in normal');\n    }\n});\n\ntest('valid string iso 8601 + timezone', function (assert) {\n    var tests = [\n        '2010-01-01',\n        '2010-01-30',\n        '2010-01-30T23+00:00',\n        '2010-01-30T23:59+00:00',\n        '2010-01-30T23:59:59+00:00',\n        '2010-01-30T23:59:59.999+00:00',\n        '2010-01-30T23:59:59.999-07:00',\n        '2010-01-30T00:00:00.000+07:00',\n        '2010-01-30T23:59:59.999-07',\n        '2010-01-30T00:00:00.000+07',\n        '2010-01-30 00:00:00.000Z'\n    ], i;\n\n    for (i = 0; i < tests.length; i++) {\n        assert.equal(moment(tests[i]).isValid(), true, tests[i] + ' should be valid in normal');\n        assert.equal(moment.utc(tests[i]).isValid(), true, tests[i] + ' should be valid in normal');\n        assert.equal(moment(tests[i], moment.ISO_8601, true).isValid(), true, tests[i] + ' should be valid in strict');\n        assert.equal(moment.utc(tests[i], moment.ISO_8601, true).isValid(), true, tests[i] + ' should be valid in strict');\n    }\n});\n\ntest('invalidAt', function (assert) {\n    assert.equal(moment([2000, 12]).invalidAt(), 1, 'month 12 is invalid: 0-11');\n    assert.equal(moment([2000, 1, 30]).invalidAt(), 2, '30 is not a valid february day');\n    assert.equal(moment([2000, 1, 29, 25]).invalidAt(), 3, '25 is invalid hour');\n    assert.equal(moment([2000, 1, 29, 24,  1]).invalidAt(), 3, '24:01 is invalid hour');\n    assert.equal(moment([2000, 1, 29, 23, 60]).invalidAt(), 4, '60 is invalid minute');\n    assert.equal(moment([2000, 1, 29, 23, 59, 60]).invalidAt(), 5, '60 is invalid second');\n    assert.equal(moment([2000, 1, 29, 23, 59, 59, 1000]).invalidAt(), 6, '1000 is invalid millisecond');\n    assert.equal(moment([2000, 1, 29, 23, 59, 59, 999]).invalidAt(), -1, '-1 if everything is fine');\n});\n\ntest('valid Unix timestamp', function (assert) {\n    assert.equal(moment(1371065286, 'X').isValid(), true, 'number integer');\n    assert.equal(moment(1379066897.0, 'X').isValid(), true, 'number whole 1dp');\n    assert.equal(moment(1379066897.7, 'X').isValid(), true, 'number 1dp');\n    assert.equal(moment(1379066897.00, 'X').isValid(), true, 'number whole 2dp');\n    assert.equal(moment(1379066897.07, 'X').isValid(), true, 'number 2dp');\n    assert.equal(moment(1379066897.17, 'X').isValid(), true, 'number 2dp');\n    assert.equal(moment(1379066897.000, 'X').isValid(), true, 'number whole 3dp');\n    assert.equal(moment(1379066897.007, 'X').isValid(), true, 'number 3dp');\n    assert.equal(moment(1379066897.017, 'X').isValid(), true, 'number 3dp');\n    assert.equal(moment(1379066897.157, 'X').isValid(), true, 'number 3dp');\n    assert.equal(moment('1371065286', 'X').isValid(), true, 'string integer');\n    assert.equal(moment('1379066897.', 'X').isValid(), true, 'string trailing .');\n    assert.equal(moment('1379066897.0', 'X').isValid(), true, 'string whole 1dp');\n    assert.equal(moment('1379066897.7', 'X').isValid(), true, 'string 1dp');\n    assert.equal(moment('1379066897.00', 'X').isValid(), true, 'string whole 2dp');\n    assert.equal(moment('1379066897.07', 'X').isValid(), true, 'string 2dp');\n    assert.equal(moment('1379066897.17', 'X').isValid(), true, 'string 2dp');\n    assert.equal(moment('1379066897.000', 'X').isValid(), true, 'string whole 3dp');\n    assert.equal(moment('1379066897.007', 'X').isValid(), true, 'string 3dp');\n    assert.equal(moment('1379066897.017', 'X').isValid(), true, 'string 3dp');\n    assert.equal(moment('1379066897.157', 'X').isValid(), true, 'string 3dp');\n});\n\ntest('invalid Unix timestamp', function (assert) {\n    assert.equal(moment(undefined, 'X').isValid(), false, 'undefined');\n    assert.equal(moment('undefined', 'X').isValid(), false, 'string undefined');\n    try {\n        assert.equal(moment(null, 'X').isValid(), false, 'null');\n    } catch (e) {\n        assert.ok(true, 'null');\n    }\n\n    assert.equal(moment('null', 'X').isValid(), false, 'string null');\n    assert.equal(moment([], 'X').isValid(), false, 'array');\n    assert.equal(moment('{}', 'X').isValid(), false, 'object');\n    try {\n        assert.equal(moment('', 'X').isValid(), false, 'string empty');\n    } catch (e) {\n        assert.ok(true, 'string empty');\n    }\n\n    assert.equal(moment(' ', 'X').isValid(), false, 'string space');\n});\n\ntest('valid Unix offset milliseconds', function (assert) {\n    assert.equal(moment(1234567890123, 'x').isValid(), true, 'number integer');\n    assert.equal(moment('1234567890123', 'x').isValid(), true, 'string integer');\n});\n\ntest('invalid Unix offset milliseconds', function (assert) {\n    assert.equal(moment(undefined, 'x').isValid(), false, 'undefined');\n    assert.equal(moment('undefined', 'x').isValid(), false, 'string undefined');\n    try {\n        assert.equal(moment(null, 'x').isValid(), false, 'null');\n    } catch (e) {\n        assert.ok(true, 'null');\n    }\n\n    assert.equal(moment('null', 'x').isValid(), false, 'string null');\n    assert.equal(moment([], 'x').isValid(), false, 'array');\n    assert.equal(moment('{}', 'x').isValid(), false, 'object');\n    try {\n        assert.equal(moment('', 'x').isValid(), false, 'string empty');\n    } catch (e) {\n        assert.ok(true, 'string empty');\n    }\n\n    assert.equal(moment(' ', 'x').isValid(), false, 'string space');\n});\n\ntest('empty', function (assert) {\n    assert.equal(moment(null).isValid(), false, 'null');\n    assert.equal(moment('').isValid(), false, 'empty string');\n    assert.equal(moment(null, 'YYYY').isValid(), false, 'format + null');\n    assert.equal(moment('', 'YYYY').isValid(), false, 'format + empty string');\n    assert.equal(moment(' ', 'YYYY').isValid(), false, 'format + empty when trimmed');\n});\n\ntest('days of the year', function (assert) {\n    assert.equal(moment('2010 300', 'YYYY DDDD').isValid(), true, 'day 300 of year valid');\n    assert.equal(moment('2010 365', 'YYYY DDDD').isValid(), true, 'day 365 of year valid');\n    assert.equal(moment('2010 366', 'YYYY DDDD').isValid(), false, 'day 366 of year invalid');\n    assert.equal(moment('2012 365', 'YYYY DDDD').isValid(), true, 'day 365 of leap year valid');\n    assert.equal(moment('2012 366', 'YYYY DDDD').isValid(), true, 'day 366 of leap year valid');\n    assert.equal(moment('2012 367', 'YYYY DDDD').isValid(), false, 'day 367 of leap year invalid');\n});\n\ntest('24:00:00.000 is valid', function (assert) {\n    assert.equal(moment('2014-01-01 24', 'YYYY-MM-DD HH').isValid(), true, '24 is valid');\n    assert.equal(moment('2014-01-01 24:00', 'YYYY-MM-DD HH:mm').isValid(), true, '24:00 is valid');\n    assert.equal(moment('2014-01-01 24:01', 'YYYY-MM-DD HH:mm').isValid(), false, '24:01 is not valid');\n});\n\ntest('oddball permissiveness', function (assert) {\n    // https://github.com/moment/moment/issues/1128\n    assert.ok(moment('2010-10-3199', ['MM/DD/YYYY', 'MM-DD-YYYY', 'YYYY-MM-DD']).isValid());\n\n    // https://github.com/moment/moment/issues/1122\n    assert.ok(moment('3:25', ['h:mma', 'hh:mma', 'H:mm', 'HH:mm']).isValid());\n});\n\ntest('0 hour is invalid in strict', function (assert) {\n    assert.equal(moment('00:01', 'hh:mm', true).isValid(), false, '00 hour is invalid in strict');\n    assert.equal(moment('00:01', 'hh:mm').isValid(), true, '00 hour is valid in normal');\n    assert.equal(moment('0:01', 'h:mm', true).isValid(), false, '0 hour is invalid in strict');\n    assert.equal(moment('0:01', 'h:mm').isValid(), true, '0 hour is valid in normal');\n});\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/test/moment/leapyear.js",
    "content": "import { module, test } from '../qunit';\nimport moment from '../../moment';\n\nmodule('leap year');\n\ntest('leap year', function (assert) {\n    assert.equal(moment([2010, 0, 1]).isLeapYear(), false, '2010');\n    assert.equal(moment([2100, 0, 1]).isLeapYear(), false, '2100');\n    assert.equal(moment([2008, 0, 1]).isLeapYear(), true, '2008');\n    assert.equal(moment([2000, 0, 1]).isLeapYear(), true, '2000');\n});\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/test/moment/listers.js",
    "content": "import { module, test } from '../qunit';\nimport moment from '../../moment';\n\nmodule('listers');\n\ntest('default', function (assert) {\n    assert.deepEqual(moment.months(), ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December']);\n    assert.deepEqual(moment.monthsShort(), ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']);\n    assert.deepEqual(moment.weekdays(), ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday']);\n    assert.deepEqual(moment.weekdaysShort(), ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat']);\n    assert.deepEqual(moment.weekdaysMin(), ['Su', 'Mo', 'Tu', 'We', 'Th', 'Fr', 'Sa']);\n});\n\ntest('index', function (assert) {\n    assert.equal(moment.months(0), 'January');\n    assert.equal(moment.months(2), 'March');\n    assert.equal(moment.monthsShort(0), 'Jan');\n    assert.equal(moment.monthsShort(2), 'Mar');\n    assert.equal(moment.weekdays(0), 'Sunday');\n    assert.equal(moment.weekdays(2), 'Tuesday');\n    assert.equal(moment.weekdaysShort(0), 'Sun');\n    assert.equal(moment.weekdaysShort(2), 'Tue');\n    assert.equal(moment.weekdaysMin(0), 'Su');\n    assert.equal(moment.weekdaysMin(2), 'Tu');\n});\n\ntest('localized', function (assert) {\n    var months = 'one_two_three_four_five_six_seven_eight_nine_ten_eleven_twelve'.split('_'),\n        monthsShort = 'on_tw_th_fo_fi_si_se_ei_ni_te_el_tw'.split('_'),\n        weekdays = 'one_two_three_four_five_six_seven'.split('_'),\n        weekdaysShort = 'on_tw_th_fo_fi_si_se'.split('_'),\n        weekdaysMin = '1_2_3_4_5_6_7'.split('_'),\n        weekdaysLocale = 'four_five_six_seven_one_two_three'.split('_'),\n        weekdaysShortLocale = 'fo_fi_si_se_on_tw_th'.split('_'),\n        weekdaysMinLocale = '4_5_6_7_1_2_3'.split('_'),\n        week = {\n            dow : 3,\n            doy : 6\n        };\n\n    moment.locale('numerologists', {\n        months : months,\n        monthsShort : monthsShort,\n        weekdays : weekdays,\n        weekdaysShort: weekdaysShort,\n        weekdaysMin: weekdaysMin,\n        week : week\n    });\n\n    assert.deepEqual(moment.months(), months);\n    assert.deepEqual(moment.monthsShort(), monthsShort);\n    assert.deepEqual(moment.weekdays(), weekdays);\n    assert.deepEqual(moment.weekdaysShort(), weekdaysShort);\n    assert.deepEqual(moment.weekdaysMin(), weekdaysMin);\n\n    assert.equal(moment.months(0), 'one');\n    assert.equal(moment.monthsShort(0), 'on');\n    assert.equal(moment.weekdays(0), 'one');\n    assert.equal(moment.weekdaysShort(0), 'on');\n    assert.equal(moment.weekdaysMin(0), '1');\n\n    assert.equal(moment.months(2), 'three');\n    assert.equal(moment.monthsShort(2), 'th');\n    assert.equal(moment.weekdays(2), 'three');\n    assert.equal(moment.weekdaysShort(2), 'th');\n    assert.equal(moment.weekdaysMin(2), '3');\n\n    assert.deepEqual(moment.weekdays(true), weekdaysLocale);\n    assert.deepEqual(moment.weekdaysShort(true), weekdaysShortLocale);\n    assert.deepEqual(moment.weekdaysMin(true), weekdaysMinLocale);\n\n    assert.equal(moment.weekdays(true, 0), 'four');\n    assert.equal(moment.weekdaysShort(true, 0), 'fo');\n    assert.equal(moment.weekdaysMin(true, 0), '4');\n\n    assert.equal(moment.weekdays(false, 2), 'three');\n    assert.equal(moment.weekdaysShort(false, 2), 'th');\n    assert.equal(moment.weekdaysMin(false, 2), '3');\n});\n\ntest('with functions', function (assert) {\n    var monthsShort = 'one_two_three_four_five_six_seven_eight_nine_ten_eleven_twelve'.split('_'),\n        monthsShortWeird = 'onesy_twosy_threesy_foursy_fivesy_sixsy_sevensy_eightsy_ninesy_tensy_elevensy_twelvesy'.split('_');\n\n    moment.locale('difficult', {\n\n        monthsShort: function (m, format) {\n            var arr = format.match(/-MMM-/) ? monthsShortWeird : monthsShort;\n            return arr[m.month()];\n        }\n    });\n\n    assert.deepEqual(moment.monthsShort(), monthsShort);\n    assert.deepEqual(moment.monthsShort('MMM'), monthsShort);\n    assert.deepEqual(moment.monthsShort('-MMM-'), monthsShortWeird);\n\n    assert.deepEqual(moment.monthsShort('MMM', 2), 'three');\n    assert.deepEqual(moment.monthsShort('-MMM-', 2), 'threesy');\n    assert.deepEqual(moment.monthsShort(2), 'three');\n});\n\ntest('with locale data', function (assert) {\n    var months = 'one_two_three_four_five_six_seven_eight_nine_ten_eleven_twelve'.split('_'),\n        monthsShort = 'on_tw_th_fo_fi_si_se_ei_ni_te_el_tw'.split('_'),\n        weekdays = 'one_two_three_four_five_six_seven'.split('_'),\n        weekdaysShort = 'on_tw_th_fo_fi_si_se'.split('_'),\n        weekdaysMin = '1_2_3_4_5_6_7'.split('_'),\n        weekdaysLocale = 'four_five_six_seven_one_two_three'.split('_'),\n        weekdaysShortLocale = 'fo_fi_si_se_on_tw_th'.split('_'),\n        weekdaysMinLocale = '4_5_6_7_1_2_3'.split('_'),\n        week = {\n            dow : 3,\n            doy : 6\n        };\n\n    var customLocale = moment.localeData('numerologists');\n\n    assert.deepEqual(customLocale.months(), months);\n    assert.deepEqual(customLocale.monthsShort(), monthsShort);\n    assert.deepEqual(customLocale.weekdays(), weekdays);\n    assert.deepEqual(customLocale.weekdaysShort(), weekdaysShort);\n    assert.deepEqual(customLocale.weekdaysMin(), weekdaysMin);\n});\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/test/moment/locale.js",
    "content": "import { module, test } from '../qunit';\nimport moment from '../../moment';\nimport each from '../helpers/each';\nimport indexOf from '../../lib/utils/index-of';\n\nmodule('locale', {\n    setup : function () {\n        // TODO: Remove once locales are switched to ES6\n        each([{\n            name: 'en-gb',\n            data: {}\n        }, {\n            name: 'en-ca',\n            data: {}\n        }, {\n            name: 'es',\n            data: {\n                relativeTime: {past: 'hace %s', s: 'unos segundos', d: 'un día'},\n                months: 'enero_febrero_marzo_abril_mayo_junio_julio_agosto_septiembre_octubre_noviembre_diciembre'.split('_')\n            }\n        }, {\n            name: 'fr',\n            data: {}\n        }, {\n            name: 'fr-ca',\n            data: {}\n        }, {\n            name: 'it',\n            data: {}\n        }, {\n            name: 'zh-cn',\n            data: {\n                months: '一月_二月_三月_四月_五月_六月_七月_八月_九月_十月_十一月_十二月'.split('_')\n            }\n        }], function (locale) {\n            if (moment.locale(locale.name) !== locale.name) {\n                moment.defineLocale(locale.name, locale.data);\n            }\n        });\n        moment.locale('en');\n    }\n});\n\ntest('library getters and setters', function (assert) {\n    var r = moment.locale('en');\n\n    assert.equal(r, 'en', 'locale should return en by default');\n    assert.equal(moment.locale(), 'en', 'locale should return en by default');\n\n    moment.locale('fr');\n    assert.equal(moment.locale(), 'fr', 'locale should return the changed locale');\n\n    moment.locale('en-gb');\n    assert.equal(moment.locale(), 'en-gb', 'locale should return the changed locale');\n\n    moment.locale('en');\n    assert.equal(moment.locale(), 'en', 'locale should reset');\n\n    moment.locale('does-not-exist');\n    assert.equal(moment.locale(), 'en', 'locale should reset');\n\n    moment.locale('EN');\n    assert.equal(moment.locale(), 'en', 'Normalize locale key case');\n\n    moment.locale('EN_gb');\n    assert.equal(moment.locale(), 'en-gb', 'Normalize locale key underscore');\n});\n\ntest('library setter array of locales', function (assert) {\n    assert.equal(moment.locale(['non-existent', 'fr', 'also-non-existent']), 'fr', 'passing an array uses the first valid locale');\n    assert.equal(moment.locale(['es', 'fr', 'also-non-existent']), 'es', 'passing an array uses the first valid locale');\n});\n\ntest('library setter locale substrings', function (assert) {\n    assert.equal(moment.locale('fr-crap'), 'fr', 'use substrings');\n    assert.equal(moment.locale('fr-does-not-exist'), 'fr', 'uses deep substrings');\n    assert.equal(moment.locale('fr-CA-does-not-exist'), 'fr-ca', 'uses deepest substring');\n});\n\ntest('library getter locale array and substrings', function (assert) {\n    assert.equal(moment.locale(['en-CH', 'fr']), 'en', 'prefer root locale to shallower ones');\n    assert.equal(moment.locale(['en-gb-leeds', 'en-CA']), 'en-gb', 'prefer root locale to shallower ones');\n    assert.equal(moment.locale(['en-fake', 'en-CA']), 'en-ca', 'prefer alternatives with shared roots');\n    assert.equal(moment.locale(['en-fake', 'en-fake2', 'en-ca']), 'en-ca', 'prefer alternatives with shared roots');\n    assert.equal(moment.locale(['fake-CA', 'fake-MX', 'fr']), 'fr', 'always find something if possible');\n    assert.equal(moment.locale(['fake-CA', 'fake-MX', 'fr']), 'fr', 'always find something if possible');\n    assert.equal(moment.locale(['fake-CA', 'fake-MX', 'fr-fake-fake-fake']), 'fr', 'always find something if possible');\n    assert.equal(moment.locale(['en', 'en-CA']), 'en', 'prefer earlier if it works');\n});\n\ntest('library ensure inheritance', function (assert) {\n    moment.locale('made-up', {\n        // I put them out of order\n        months : 'February_March_April_May_June_July_August_September_October_November_December_January'.split('_')\n        // the rest of the properties should be inherited.\n    });\n\n    assert.equal(moment([2012, 5, 6]).format('MMMM'), 'July', 'Override some of the configs');\n    assert.equal(moment([2012, 5, 6]).format('MMM'), 'Jun', 'But not all of them');\n});\n\ntest('library ensure inheritance LT L LL LLL LLLL', function (assert) {\n    var locale = 'test-inherit-lt';\n\n    moment.defineLocale(locale, {\n        longDateFormat : {\n            LT : '-[LT]-',\n            L : '-[L]-',\n            LL : '-[LL]-',\n            LLL : '-[LLL]-',\n            LLLL : '-[LLLL]-'\n        },\n        calendar : {\n            sameDay : '[sameDay] LT',\n            nextDay : '[nextDay] L',\n            nextWeek : '[nextWeek] LL',\n            lastDay : '[lastDay] LLL',\n            lastWeek : '[lastWeek] LLLL',\n            sameElse : 'L'\n        }\n    });\n\n    moment.locale('es');\n\n    assert.equal(moment().locale(locale).calendar(), 'sameDay -LT-', 'Should use instance locale in LT formatting');\n    assert.equal(moment().add(1, 'days').locale(locale).calendar(), 'nextDay -L-', 'Should use instance locale in L formatting');\n    assert.equal(moment().add(-1, 'days').locale(locale).calendar(), 'lastDay -LLL-', 'Should use instance locale in LL formatting');\n    assert.equal(moment().add(4, 'days').locale(locale).calendar(), 'nextWeek -LL-', 'Should use instance locale in LLL formatting');\n    assert.equal(moment().add(-4, 'days').locale(locale).calendar(), 'lastWeek -LLLL-', 'Should use instance locale in LLLL formatting');\n});\n\ntest('library localeData', function (assert) {\n    moment.locale('en');\n\n    var jan = moment([2000, 0]);\n\n    assert.equal(moment.localeData().months(jan), 'January', 'no arguments returns global');\n    assert.equal(moment.localeData('zh-cn').months(jan), '一月', 'a string returns the locale based on key');\n    assert.equal(moment.localeData(moment().locale('es')).months(jan), 'enero', 'if you pass in a moment it uses the moment\\'s locale');\n});\n\ntest('library deprecations', function (assert) {\n    test.expectedDeprecations('moment.lang');\n    moment.lang('dude', {months: ['Movember']});\n    assert.equal(moment.locale(), 'dude', 'setting the lang sets the locale');\n    assert.equal(moment.lang(), moment.locale());\n    assert.equal(moment.langData(), moment.localeData(), 'langData is localeData');\n    moment.defineLocale('dude', null);\n});\n\ntest('defineLocale', function (assert) {\n    moment.locale('en');\n    moment.defineLocale('dude', {months: ['Movember']});\n    assert.equal(moment().locale(), 'dude', 'defineLocale also sets it');\n    assert.equal(moment().locale('dude').locale(), 'dude', 'defineLocale defines a locale');\n    moment.defineLocale('dude', null);\n});\n\ntest('locales', function (assert) {\n    moment.defineLocale('dude', {months: ['Movember']});\n    assert.equal(true, !!~indexOf.call(moment.locales(), 'dude'), 'locales returns an array of defined locales');\n    assert.equal(true, !!~indexOf.call(moment.locales(), 'en'), 'locales should always include english');\n    moment.defineLocale('dude', null);\n});\n\ntest('library convenience', function (assert) {\n    moment.locale('something', {week: {dow: 3}});\n    moment.locale('something');\n    assert.equal(moment.locale(), 'something', 'locale can be used to create the locale too');\n    moment.defineLocale('something', null);\n});\n\ntest('firstDayOfWeek firstDayOfYear locale getters', function (assert) {\n    moment.locale('something', {week: {dow: 3, doy: 4}});\n    moment.locale('something');\n    assert.equal(moment.localeData().firstDayOfWeek(), 3, 'firstDayOfWeek');\n    assert.equal(moment.localeData().firstDayOfYear(), 4, 'firstDayOfYear');\n    moment.defineLocale('something', null);\n});\n\ntest('instance locale method', function (assert) {\n    moment.locale('en');\n\n    assert.equal(moment([2012, 5, 6]).format('MMMM'), 'June', 'Normally default to global');\n    assert.equal(moment([2012, 5, 6]).locale('es').format('MMMM'), 'junio', 'Use the instance specific locale');\n    assert.equal(moment([2012, 5, 6]).format('MMMM'), 'June', 'Using an instance specific locale does not affect other moments');\n});\n\ntest('instance locale method with array', function (assert) {\n    var m = moment().locale(['non-existent', 'fr', 'also-non-existent']);\n    assert.equal(m.locale(), 'fr', 'passing an array uses the first valid locale');\n    m = moment().locale(['es', 'fr', 'also-non-existent']);\n    assert.equal(m.locale(), 'es', 'passing an array uses the first valid locale');\n});\n\ntest('instance getter locale substrings', function (assert) {\n    var m = moment();\n\n    m.locale('fr-crap');\n    assert.equal(m.locale(), 'fr', 'use substrings');\n\n    m.locale('fr-does-not-exist');\n    assert.equal(m.locale(), 'fr', 'uses deep substrings');\n});\n\ntest('instance locale persists with manipulation', function (assert) {\n    moment.locale('en');\n\n    assert.equal(moment([2012, 5, 6]).locale('es').add({days: 1}).format('MMMM'), 'junio', 'With addition');\n    assert.equal(moment([2012, 5, 6]).locale('es').day(0).format('MMMM'), 'junio', 'With day getter');\n    assert.equal(moment([2012, 5, 6]).locale('es').endOf('day').format('MMMM'), 'junio', 'With endOf');\n});\n\ntest('instance locale persists with cloning', function (assert) {\n    moment.locale('en');\n\n    var a = moment([2012, 5, 6]).locale('es'),\n        b = a.clone(),\n        c = moment(a);\n\n    assert.equal(b.format('MMMM'), 'junio', 'using moment.fn.clone()');\n    assert.equal(b.format('MMMM'), 'junio', 'using moment()');\n});\n\ntest('duration locale method', function (assert) {\n    moment.locale('en');\n\n    assert.equal(moment.duration({seconds:  44}).humanize(), 'a few seconds', 'Normally default to global');\n    assert.equal(moment.duration({seconds:  44}).locale('es').humanize(), 'unos segundos', 'Use the instance specific locale');\n    assert.equal(moment.duration({seconds:  44}).humanize(), 'a few seconds', 'Using an instance specific locale does not affect other durations');\n});\n\ntest('duration locale persists with cloning', function (assert) {\n    moment.locale('en');\n\n    var a = moment.duration({seconds:  44}).locale('es'),\n        b = moment.duration(a);\n\n    assert.equal(b.humanize(), 'unos segundos', 'using moment.duration()');\n});\n\ntest('changing the global locale doesn\\'t affect existing duration instances', function (assert) {\n    var mom = moment.duration();\n    moment.locale('fr');\n    assert.equal('en', mom.locale());\n});\n\ntest('duration deprecations', function (assert) {\n    test.expectedDeprecations('moment().lang()');\n    assert.equal(moment.duration().lang(), moment.duration().localeData(), 'duration.lang is the same as duration.localeData');\n});\n\ntest('from and fromNow with invalid date', function (assert) {\n    assert.equal(moment(NaN).from(), 'Invalid date', 'moment.from with invalid moment');\n    assert.equal(moment(NaN).fromNow(), 'Invalid date', 'moment.fromNow with invalid moment');\n});\n\ntest('from relative time future', function (assert) {\n    var start = moment([2007, 1, 28]);\n\n    assert.equal(start.from(moment([2007, 1, 28]).subtract({s: 44})),  'in a few seconds', '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).subtract({s: 45})),  'in a minute',      '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).subtract({s: 89})),  'in a minute',      '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).subtract({s: 90})),  'in 2 minutes',     '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).subtract({m: 44})),  'in 44 minutes',    '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).subtract({m: 45})),  'in an hour',       '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).subtract({m: 89})),  'in an hour',       '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).subtract({m: 90})),  'in 2 hours',       '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).subtract({h: 5})),   'in 5 hours',       '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).subtract({h: 21})),  'in 21 hours',      '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).subtract({h: 22})),  'in a day',         '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).subtract({h: 35})),  'in a day',         '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).subtract({h: 36})),  'in 2 days',        '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).subtract({d: 1})),   'in a day',         '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).subtract({d: 5})),   'in 5 days',        '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).subtract({d: 25})),  'in 25 days',       '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).subtract({d: 26})),  'in a month',       '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).subtract({d: 30})),  'in a month',       '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).subtract({d: 45})),  'in a month',       '45 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).subtract({d: 47})),  'in 2 months',      '47 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).subtract({d: 74})),  'in 2 months',      '74 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).subtract({d: 78})),  'in 3 months',      '78 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).subtract({M: 1})),   'in a month',       '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).subtract({M: 5})),   'in 5 months',      '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).subtract({d: 315})), 'in 10 months',     '315 days = 10 months');\n    assert.equal(start.from(moment([2007, 1, 28]).subtract({d: 344})), 'in a year',        '344 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).subtract({d: 345})), 'in a year',        '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).subtract({d: 548})), 'in 2 years',       '548 days = in 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).subtract({y: 1})),   'in a year',        '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).subtract({y: 5})),   'in 5 years',       '5 years = 5 years');\n});\n\ntest('from relative time past', function (assert) {\n    var start = moment([2007, 1, 28]);\n\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 44})),  'a few seconds ago', '44 seconds = a few seconds');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 45})),  'a minute ago',      '45 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 89})),  'a minute ago',      '89 seconds = a minute');\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90})),  '2 minutes ago',     '90 seconds = 2 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 44})),  '44 minutes ago',    '44 minutes = 44 minutes');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 45})),  'an hour ago',       '45 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 89})),  'an hour ago',       '89 minutes = an hour');\n    assert.equal(start.from(moment([2007, 1, 28]).add({m: 90})),  '2 hours ago',       '90 minutes = 2 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 5})),   '5 hours ago',       '5 hours = 5 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 21})),  '21 hours ago',      '21 hours = 21 hours');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 22})),  'a day ago',         '22 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 35})),  'a day ago',         '35 hours = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({h: 36})),  '2 days ago',        '36 hours = 2 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 1})),   'a day ago',         '1 day = a day');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 5})),   '5 days ago',        '5 days = 5 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 25})),  '25 days ago',       '25 days = 25 days');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 26})),  'a month ago',       '26 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 30})),  'a month ago',       '30 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 43})),  'a month ago',       '43 days = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 46})),  '2 months ago',      '46 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 74})),  '2 months ago',      '75 days = 2 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 76})),  '3 months ago',      '76 days = 3 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 1})),   'a month ago',       '1 month = a month');\n    assert.equal(start.from(moment([2007, 1, 28]).add({M: 5})),   '5 months ago',      '5 months = 5 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 315})), '10 months ago',     '315 days = 10 months');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 344})), 'a year ago',        '344 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 345})), 'a year ago',        '345 days = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({d: 548})), '2 years ago',       '548 days = 2 years');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 1})),   'a year ago',        '1 year = a year');\n    assert.equal(start.from(moment([2007, 1, 28]).add({y: 5})),   '5 years ago',       '5 years = 5 years');\n});\n\ntest('instance locale used with from', function (assert) {\n    moment.locale('en');\n\n    var a = moment([2012, 5, 6]).locale('es'),\n        b = moment([2012, 5, 7]);\n\n    assert.equal(a.from(b), 'hace un día', 'preserve locale of first moment');\n    assert.equal(b.from(a), 'in a day', 'do not preserve locale of second moment');\n});\n\ntest('instance localeData', function (assert) {\n    moment.defineLocale('dude', {week: {dow: 3}});\n    assert.equal(moment().locale('dude').localeData()._week.dow, 3);\n    moment.defineLocale('dude', null);\n});\n\ntest('month name callback function', function (assert) {\n    function fakeReplace(m, format) {\n        if (/test/.test(format)) {\n            return 'test';\n        }\n        if (m.date() === 1) {\n            return 'date';\n        }\n        return 'default';\n    }\n\n    moment.locale('made-up-2', {\n        months : fakeReplace,\n        monthsShort : fakeReplace,\n        weekdays : fakeReplace,\n        weekdaysShort : fakeReplace,\n        weekdaysMin : fakeReplace\n    });\n\n    assert.equal(moment().format('[test] dd ddd dddd MMM MMMM'), 'test test test test test test', 'format month name function should be able to access the format string');\n    assert.equal(moment([2011, 0, 1]).format('dd ddd dddd MMM MMMM'), 'date date date date date', 'format month name function should be able to access the moment object');\n    assert.equal(moment([2011, 0, 2]).format('dd ddd dddd MMM MMMM'), 'default default default default default', 'format month name function should be able to access the moment object');\n});\n\ntest('changing parts of a locale config', function (assert) {\n    test.expectedDeprecations('defineLocaleOverride');\n\n    moment.locale('partial-lang', {\n        months : 'a b c d e f g h i j k l'.split(' ')\n    });\n\n    assert.equal(moment([2011, 0, 1]).format('MMMM'), 'a', 'should be able to set locale values when creating the localeuage');\n\n    moment.locale('partial-lang', {\n        monthsShort : 'A B C D E F G H I J K L'.split(' ')\n    });\n\n    assert.equal(moment([2011, 0, 1]).format('MMMM MMM'), 'a A', 'should be able to set locale values after creating the localeuage');\n\n    moment.defineLocale('partial-lang', null);\n});\n\ntest('start/endOf week feature for first-day-is-monday locales', function (assert) {\n    moment.locale('monday-lang', {\n        week : {\n            dow : 1 // Monday is the first day of the week\n        }\n    });\n\n    moment.locale('monday-lang');\n    assert.equal(moment([2013, 0, 1]).startOf('week').day(), 1, 'for locale monday-lang first day of the week should be monday');\n    assert.equal(moment([2013, 0, 1]).endOf('week').day(), 0, 'for locale monday-lang last day of the week should be sunday');\n    moment.defineLocale('monday-lang', null);\n});\n\ntest('meridiem parsing', function (assert) {\n    moment.locale('meridiem-parsing', {\n        meridiemParse : /[bd]/i,\n        isPM : function (input) {\n            return input === 'b';\n        }\n    });\n\n    moment.locale('meridiem-parsing');\n    assert.equal(moment('2012-01-01 3b', 'YYYY-MM-DD ha').hour(), 15, 'Custom parsing of meridiem should work');\n    assert.equal(moment('2012-01-01 3d', 'YYYY-MM-DD ha').hour(), 3, 'Custom parsing of meridiem should work');\n    moment.defineLocale('meridiem-parsing', null);\n});\n\ntest('invalid date formatting', function (assert) {\n    moment.locale('has-invalid', {\n        invalidDate: 'KHAAAAAAAAAAAN!'\n    });\n\n    assert.equal(moment.invalid().format(), 'KHAAAAAAAAAAAN!');\n    assert.equal(moment.invalid().format('YYYY-MM-DD'), 'KHAAAAAAAAAAAN!');\n    moment.defineLocale('has-invalid', null);\n});\n\ntest('return locale name', function (assert) {\n    var registered = moment.locale('return-this', {});\n\n    assert.equal(registered, 'return-this', 'returns the locale configured');\n    moment.locale('return-this', null);\n});\n\ntest('changing the global locale doesn\\'t affect existing instances', function (assert) {\n    var mom = moment();\n    moment.locale('fr');\n    assert.equal('en', mom.locale());\n});\n\ntest('setting a language on instance returns the original moment for chaining', function (assert) {\n    test.expectedDeprecations('moment().lang()');\n    var mom = moment();\n\n    assert.equal(mom.lang('fr'), mom, 'setting the language (lang) returns the original moment for chaining');\n    assert.equal(mom.locale('it'), mom, 'setting the language (locale) returns the original moment for chaining');\n});\n\ntest('lang(key) changes the language of the instance', function (assert) {\n    test.expectedDeprecations('moment().lang()');\n    var m = moment().month(0);\n    m.lang('fr');\n    assert.equal(m.locale(), 'fr', 'm.lang(key) changes instance locale');\n});\n\ntest('moment#locale(false) resets to global locale', function (assert) {\n    var m = moment();\n\n    moment.locale('fr');\n    m.locale('it');\n\n    assert.equal(moment.locale(), 'fr', 'global locale is it');\n    assert.equal(m.locale(), 'it', 'instance locale is it');\n    m.locale(false);\n    assert.equal(m.locale(), 'fr', 'instance locale reset to global locale');\n});\n\ntest('moment().locale with missing key doesn\\'t change locale', function (assert) {\n    assert.equal(moment().locale('boo').localeData(), moment.localeData(),\n            'preserve global locale in case of bad locale id');\n});\n\ntest('moment().lang with missing key doesn\\'t change locale', function (assert) {\n    test.expectedDeprecations('moment().lang()');\n    assert.equal(moment().lang('boo').localeData(), moment.localeData(),\n            'preserve global locale in case of bad locale id');\n});\n\n\n// TODO: Enable this after fixing pl months parse hack hack\n// test('monthsParseExact', function (assert) {\n//     var locale = 'test-months-parse-exact';\n\n//     moment.defineLocale(locale, {\n//         monthsParseExact: true,\n//         months: 'A_AA_AAA_B_B B_BB  B_C_C-C_C,C2C_D_D+D_D`D*D'.split('_'),\n//         monthsShort: 'E_EE_EEE_F_FF_FFF_G_GG_GGG_H_HH_HHH'.split('_')\n//     });\n\n//     assert.equal(moment('A', 'MMMM', true).month(), 0, 'parse long month 0 with MMMM');\n//     assert.equal(moment('AA', 'MMMM', true).month(), 1, 'parse long month 1 with MMMM');\n//     assert.equal(moment('AAA', 'MMMM', true).month(), 2, 'parse long month 2 with MMMM');\n//     assert.equal(moment('B B', 'MMMM', true).month(), 4, 'parse long month 4 with MMMM');\n//     assert.equal(moment('BB  B', 'MMMM', true).month(), 5, 'parse long month 5 with MMMM');\n//     assert.equal(moment('C-C', 'MMMM', true).month(), 7, 'parse long month 7 with MMMM');\n//     assert.equal(moment('C,C2C', 'MMMM', true).month(), 8, 'parse long month 8 with MMMM');\n//     assert.equal(moment('D+D', 'MMMM', true).month(), 10, 'parse long month 10 with MMMM');\n//     assert.equal(moment('D`D*D', 'MMMM', true).month(), 11, 'parse long month 11 with MMMM');\n\n//     assert.equal(moment('E', 'MMM', true).month(), 0, 'parse long month 0 with MMM');\n//     assert.equal(moment('EE', 'MMM', true).month(), 1, 'parse long month 1 with MMM');\n//     assert.equal(moment('EEE', 'MMM', true).month(), 2, 'parse long month 2 with MMM');\n\n//     assert.equal(moment('A', 'MMM').month(), 0, 'non-strict parse long month 0 with MMM');\n//     assert.equal(moment('AA', 'MMM').month(), 1, 'non-strict parse long month 1 with MMM');\n//     assert.equal(moment('AAA', 'MMM').month(), 2, 'non-strict parse long month 2 with MMM');\n//     assert.equal(moment('E', 'MMMM').month(), 0, 'non-strict parse short month 0 with MMMM');\n//     assert.equal(moment('EE', 'MMMM').month(), 1, 'non-strict parse short month 1 with MMMM');\n//     assert.equal(moment('EEE', 'MMMM').month(), 2, 'non-strict parse short month 2 with MMMM');\n// });\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/test/moment/locale_inheritance.js",
    "content": "import { module, test } from '../qunit';\nimport moment from '../../moment';\n\nmodule('locale inheritance');\n\ntest('calendar', function (assert) {\n    moment.defineLocale('base-cal', {\n        calendar : {\n            sameDay: '[Today at] HH:mm',\n            nextDay: '[Tomorrow at] HH:mm',\n            nextWeek: '[Next week at] HH:mm',\n            lastDay: '[Yesterday at] HH:mm',\n            lastWeek: '[Last week at] HH:mm',\n            sameElse: '[whatever]'\n        }\n    });\n    moment.defineLocale('child-cal', {\n        parentLocale: 'base-cal',\n        calendar: {\n            sameDay: '[Today] HH:mm',\n            nextDay: '[Tomorrow] HH:mm',\n            nextWeek: '[Next week] HH:mm'\n        }\n    });\n\n    moment.locale('child-cal');\n    var anchor = moment.utc('2015-05-05T12:00:00', moment.ISO_8601);\n    assert.equal(anchor.clone().add(3, 'hours').calendar(anchor), 'Today 15:00', 'today uses child version');\n    assert.equal(anchor.clone().add(1, 'day').calendar(anchor), 'Tomorrow 12:00', 'tomorrow uses child version');\n    assert.equal(anchor.clone().add(3, 'days').calendar(anchor), 'Next week 12:00', 'next week uses child version');\n\n    assert.equal(anchor.clone().subtract(1, 'day').calendar(anchor), 'Yesterday at 12:00', 'yesterday uses parent version');\n    assert.equal(anchor.clone().subtract(3, 'days').calendar(anchor), 'Last week at 12:00', 'last week uses parent version');\n    assert.equal(anchor.clone().subtract(7, 'days').calendar(anchor), 'whatever', 'sameElse uses parent version -');\n    assert.equal(anchor.clone().add(7, 'days').calendar(anchor), 'whatever', 'sameElse uses parent version +');\n});\n\ntest('missing', function (assert) {\n    moment.defineLocale('base-cal-2', {\n        calendar: {\n            sameDay: '[Today at] HH:mm',\n            nextDay: '[Tomorrow at] HH:mm',\n            nextWeek: '[Next week at] HH:mm',\n            lastDay: '[Yesterday at] HH:mm',\n            lastWeek: '[Last week at] HH:mm',\n            sameElse: '[whatever]'\n        }\n    });\n    moment.defineLocale('child-cal-2', {\n        parentLocale: 'base-cal-2'\n    });\n    moment.locale('child-cal-2');\n    var anchor = moment.utc('2015-05-05T12:00:00', moment.ISO_8601);\n    assert.equal(anchor.clone().add(3, 'hours').calendar(anchor), 'Today at 15:00', 'today uses parent version');\n    assert.equal(anchor.clone().add(1, 'day').calendar(anchor), 'Tomorrow at 12:00', 'tomorrow uses parent version');\n    assert.equal(anchor.clone().add(3, 'days').calendar(anchor), 'Next week at 12:00', 'next week uses parent version');\n    assert.equal(anchor.clone().subtract(1, 'day').calendar(anchor), 'Yesterday at 12:00', 'yesterday uses parent version');\n    assert.equal(anchor.clone().subtract(3, 'days').calendar(anchor), 'Last week at 12:00', 'last week uses parent version');\n    assert.equal(anchor.clone().subtract(7, 'days').calendar(anchor), 'whatever', 'sameElse uses parent version -');\n    assert.equal(anchor.clone().add(7, 'days').calendar(anchor), 'whatever', 'sameElse uses parent version +');\n});\n\n// Test function vs obj both directions\n\ntest('long date format', function (assert) {\n    moment.defineLocale('base-ldf', {\n        longDateFormat : {\n            LTS  : 'h:mm:ss A',\n            LT   : 'h:mm A',\n            L    : 'MM/DD/YYYY',\n            LL   : 'MMMM D, YYYY',\n            LLL  : 'MMMM D, YYYY h:mm A',\n            LLLL : 'dddd, MMMM D, YYYY h:mm A'\n        }\n    });\n    moment.defineLocale('child-ldf', {\n        parentLocale: 'base-ldf',\n        longDateFormat: {\n            LLL  : '[child] MMMM D, YYYY h:mm A',\n            LLLL : '[child] dddd, MMMM D, YYYY h:mm A'\n        }\n    });\n\n    moment.locale('child-ldf');\n    var anchor = moment.utc('2015-09-06T12:34:56', moment.ISO_8601);\n    assert.equal(anchor.format('LTS'), '12:34:56 PM', 'LTS uses base');\n    assert.equal(anchor.format('LT'), '12:34 PM', 'LT uses base');\n    assert.equal(anchor.format('L'), '09/06/2015', 'L uses base');\n    assert.equal(anchor.format('l'), '9/6/2015', 'l uses base');\n    assert.equal(anchor.format('LL'), 'September 6, 2015', 'LL uses base');\n    assert.equal(anchor.format('ll'), 'Sep 6, 2015', 'll uses base');\n    assert.equal(anchor.format('LLL'), 'child September 6, 2015 12:34 PM', 'LLL uses child');\n    assert.equal(anchor.format('lll'), 'child Sep 6, 2015 12:34 PM', 'lll uses child');\n    assert.equal(anchor.format('LLLL'), 'child Sunday, September 6, 2015 12:34 PM', 'LLLL uses child');\n    assert.equal(anchor.format('llll'), 'child Sun, Sep 6, 2015 12:34 PM', 'llll uses child');\n});\n\ntest('ordinal', function (assert) {\n    moment.defineLocale('base-ordinal-1', {\n        ordinal : '%dx'\n    });\n    moment.defineLocale('child-ordinal-1', {\n        parentLocale: 'base-ordinal-1',\n        ordinal : '%dy'\n    });\n\n    assert.equal(moment.utc('2015-02-03', moment.ISO_8601).format('Do'), '3y', 'ordinal uses child string');\n\n    moment.defineLocale('base-ordinal-2', {\n        ordinal : '%dx'\n    });\n    moment.defineLocale('child-ordinal-2', {\n        parentLocale: 'base-ordinal-2',\n        ordinal : function (num) {\n            return num + 'y';\n        }\n    });\n\n    assert.equal(moment.utc('2015-02-03', moment.ISO_8601).format('Do'), '3y', 'ordinal uses child function');\n\n    moment.defineLocale('base-ordinal-3', {\n        ordinal : function (num) {\n            return num + 'x';\n        }\n    });\n    moment.defineLocale('child-ordinal-3', {\n        parentLocale: 'base-ordinal-3',\n        ordinal : '%dy'\n    });\n\n    assert.equal(moment.utc('2015-02-03', moment.ISO_8601).format('Do'), '3y', 'ordinal uses child string (overwrite parent function)');\n});\n\ntest('ordinal parse', function (assert) {\n    moment.defineLocale('base-ordinal-parse-1', {\n        dayOfMonthOrdinalParse : /\\d{1,2}x/\n    });\n    moment.defineLocale('child-ordinal-parse-1', {\n        parentLocale: 'base-ordinal-parse-1',\n        dayOfMonthOrdinalParse : /\\d{1,2}y/\n    });\n\n    assert.ok(moment.utc('2015-01-1y', 'YYYY-MM-Do', true).isValid(), 'ordinal parse uses child');\n\n    moment.defineLocale('base-ordinal-parse-2', {\n        dayOfMonthOrdinalParse : /\\d{1,2}x/\n    });\n    moment.defineLocale('child-ordinal-parse-2', {\n        parentLocale: 'base-ordinal-parse-2',\n        dayOfMonthOrdinalParse : /\\d{1,2}/\n    });\n\n    assert.ok(moment.utc('2015-01-1', 'YYYY-MM-Do', true).isValid(), 'ordinal parse uses child (default)');\n});\n\ntest('months', function (assert) {\n    moment.defineLocale('base-months', {\n        months : 'One_Two_Three_Four_Five_Six_Seven_Eight_Nine_Ten_Eleven_Twelve'.split('_')\n    });\n    moment.defineLocale('child-months', {\n        parentLocale: 'base-months',\n        months : 'First_Second_Third_Fourth_Fifth_Sixth_Seventh_Eighth_Ninth_Tenth_Eleventh_Twelveth '.split('_')\n    });\n    assert.ok(moment.utc('2015-01-01', 'YYYY-MM-DD').format('MMMM'), 'First', 'months uses child');\n});\n\ntest('define child locale before parent', function (assert) {\n    moment.defineLocale('months-x', null);\n    moment.defineLocale('base-months-x', null);\n\n    moment.defineLocale('months-x', {\n        parentLocale: 'base-months-x',\n        months : 'First_Second_Third_Fourth_Fifth_Sixth_Seventh_Eighth_Ninth_Tenth_Eleventh_Twelveth '.split('_')\n    });\n    assert.equal(moment.locale(), 'en', 'failed to set a locale requiring missing parent');\n    moment.defineLocale('base-months-x', {\n        months : 'One_Two_Three_Four_Five_Six_Seven_Eight_Nine_Ten_Eleven_Twelve'.split('_')\n    });\n    assert.equal(moment.locale(), 'base-months-x', 'defineLocale should also set the locale (regardless of child locales)');\n\n    assert.equal(moment().locale('months-x').month(0).format('MMMM'), 'First', 'loading child before parent locale works');\n});\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/test/moment/locale_update.js",
    "content": "import { module, test } from '../qunit';\nimport moment from '../../moment';\n\nmodule('locale update');\n\ntest('calendar', function (assert) {\n    moment.defineLocale('cal', null);\n    moment.defineLocale('cal', {\n        calendar : {\n            sameDay: '[Today at] HH:mm',\n            nextDay: '[Tomorrow at] HH:mm',\n            nextWeek: '[Next week at] HH:mm',\n            lastDay: '[Yesterday at] HH:mm',\n            lastWeek: '[Last week at] HH:mm',\n            sameElse: '[whatever]'\n        }\n    });\n    moment.updateLocale('cal', {\n        calendar: {\n            sameDay: '[Today] HH:mm',\n            nextDay: '[Tomorrow] HH:mm',\n            nextWeek: '[Next week] HH:mm'\n        }\n    });\n\n    moment.locale('cal');\n    var anchor = moment.utc('2015-05-05T12:00:00', moment.ISO_8601);\n    assert.equal(anchor.clone().add(3, 'hours').calendar(anchor), 'Today 15:00', 'today uses child version');\n    assert.equal(anchor.clone().add(1, 'day').calendar(anchor), 'Tomorrow 12:00', 'tomorrow uses child version');\n    assert.equal(anchor.clone().add(3, 'days').calendar(anchor), 'Next week 12:00', 'next week uses child version');\n\n    assert.equal(anchor.clone().subtract(1, 'day').calendar(anchor), 'Yesterday at 12:00', 'yesterday uses parent version');\n    assert.equal(anchor.clone().subtract(3, 'days').calendar(anchor), 'Last week at 12:00', 'last week uses parent version');\n    assert.equal(anchor.clone().subtract(7, 'days').calendar(anchor), 'whatever', 'sameElse uses parent version -');\n    assert.equal(anchor.clone().add(7, 'days').calendar(anchor), 'whatever', 'sameElse uses parent version +');\n});\n\ntest('missing', function (assert) {\n    moment.defineLocale('cal-2', null);\n    moment.defineLocale('cal-2', {\n        calendar: {\n            sameDay: '[Today at] HH:mm',\n            nextDay: '[Tomorrow at] HH:mm',\n            nextWeek: '[Next week at] HH:mm',\n            lastDay: '[Yesterday at] HH:mm',\n            lastWeek: '[Last week at] HH:mm',\n            sameElse: '[whatever]'\n        }\n    });\n    moment.updateLocale('cal-2', {\n    });\n    moment.locale('cal-2');\n    var anchor = moment.utc('2015-05-05T12:00:00', moment.ISO_8601);\n    assert.equal(anchor.clone().add(3, 'hours').calendar(anchor), 'Today at 15:00', 'today uses parent version');\n    assert.equal(anchor.clone().add(1, 'day').calendar(anchor), 'Tomorrow at 12:00', 'tomorrow uses parent version');\n    assert.equal(anchor.clone().add(3, 'days').calendar(anchor), 'Next week at 12:00', 'next week uses parent version');\n    assert.equal(anchor.clone().subtract(1, 'day').calendar(anchor), 'Yesterday at 12:00', 'yesterday uses parent version');\n    assert.equal(anchor.clone().subtract(3, 'days').calendar(anchor), 'Last week at 12:00', 'last week uses parent version');\n    assert.equal(anchor.clone().subtract(7, 'days').calendar(anchor), 'whatever', 'sameElse uses parent version -');\n    assert.equal(anchor.clone().add(7, 'days').calendar(anchor), 'whatever', 'sameElse uses parent version +');\n});\n\n// Test function vs obj both directions\n\ntest('long date format', function (assert) {\n    moment.defineLocale('ldf', null);\n    moment.defineLocale('ldf', {\n        longDateFormat : {\n            LTS  : 'h:mm:ss A',\n            LT   : 'h:mm A',\n            L    : 'MM/DD/YYYY',\n            LL   : 'MMMM D, YYYY',\n            LLL  : 'MMMM D, YYYY h:mm A',\n            LLLL : 'dddd, MMMM D, YYYY h:mm A'\n        }\n    });\n    moment.updateLocale('ldf', {\n        longDateFormat: {\n            LLL  : '[child] MMMM D, YYYY h:mm A',\n            LLLL : '[child] dddd, MMMM D, YYYY h:mm A'\n        }\n    });\n\n    moment.locale('ldf');\n    var anchor = moment.utc('2015-09-06T12:34:56', moment.ISO_8601);\n    assert.equal(anchor.format('LTS'), '12:34:56 PM', 'LTS uses base');\n    assert.equal(anchor.format('LT'), '12:34 PM', 'LT uses base');\n    assert.equal(anchor.format('L'), '09/06/2015', 'L uses base');\n    assert.equal(anchor.format('l'), '9/6/2015', 'l uses base');\n    assert.equal(anchor.format('LL'), 'September 6, 2015', 'LL uses base');\n    assert.equal(anchor.format('ll'), 'Sep 6, 2015', 'll uses base');\n    assert.equal(anchor.format('LLL'), 'child September 6, 2015 12:34 PM', 'LLL uses child');\n    assert.equal(anchor.format('lll'), 'child Sep 6, 2015 12:34 PM', 'lll uses child');\n    assert.equal(anchor.format('LLLL'), 'child Sunday, September 6, 2015 12:34 PM', 'LLLL uses child');\n    assert.equal(anchor.format('llll'), 'child Sun, Sep 6, 2015 12:34 PM', 'llll uses child');\n});\n\ntest('ordinal', function (assert) {\n    moment.defineLocale('ordinal-1', null);\n    moment.defineLocale('ordinal-1', {\n        ordinal : '%dx'\n    });\n    moment.updateLocale('ordinal-1', {\n        ordinal : '%dy'\n    });\n\n    assert.equal(moment.utc('2015-02-03', moment.ISO_8601).format('Do'), '3y', 'ordinal uses child string');\n\n    moment.defineLocale('ordinal-2', null);\n    moment.defineLocale('ordinal-2', {\n        ordinal : '%dx'\n    });\n    moment.updateLocale('ordinal-2', {\n        ordinal : function (num) {\n            return num + 'y';\n        }\n    });\n\n    assert.equal(moment.utc('2015-02-03', moment.ISO_8601).format('Do'), '3y', 'ordinal uses child function');\n\n    moment.defineLocale('ordinal-3', null);\n    moment.defineLocale('ordinal-3', {\n        ordinal : function (num) {\n            return num + 'x';\n        }\n    });\n    moment.updateLocale('ordinal-3', {\n        ordinal : '%dy'\n    });\n\n    assert.equal(moment.utc('2015-02-03', moment.ISO_8601).format('Do'), '3y', 'ordinal uses child string (overwrite parent function)');\n});\n\ntest('ordinal parse', function (assert) {\n    moment.defineLocale('ordinal-parse-1', null);\n    moment.defineLocale('ordinal-parse-1', {\n        dayOfMonthOrdinalParse : /\\d{1,2}x/\n    });\n    moment.updateLocale('ordinal-parse-1', {\n        dayOfMonthOrdinalParse : /\\d{1,2}y/\n    });\n\n    assert.ok(moment.utc('2015-01-1y', 'YYYY-MM-Do', true).isValid(), 'ordinal parse uses child');\n\n    moment.defineLocale('ordinal-parse-2', null);\n    moment.defineLocale('ordinal-parse-2', {\n        dayOfMonthOrdinalParse : /\\d{1,2}x/\n    });\n    moment.updateLocale('ordinal-parse-2', {\n        dayOfMonthOrdinalParse : /\\d{1,2}/\n    });\n\n    assert.ok(moment.utc('2015-01-1', 'YYYY-MM-Do', true).isValid(), 'ordinal parse uses child (default)');\n});\n\ntest('months', function (assert) {\n    moment.defineLocale('months', null);\n    moment.defineLocale('months', {\n        months : 'One_Two_Three_Four_Five_Six_Seven_Eight_Nine_Ten_Eleven_Twelve'.split('_')\n    });\n    moment.updateLocale('months', {\n        parentLocale: 'base-months',\n        months : 'First_Second_Third_Fourth_Fifth_Sixth_Seventh_Eighth_Ninth_Tenth_Eleventh_Twelveth '.split('_')\n    });\n    assert.ok(moment.utc('2015-01-01', 'YYYY-MM-DD').format('MMMM'), 'First', 'months uses child');\n});\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/test/moment/min_max.js",
    "content": "import { module, test } from '../qunit';\nimport moment from '../../moment';\n\nmodule('min max');\n\ntest('min', function (assert) {\n    var now = moment(),\n        future = now.clone().add(1, 'month'),\n        past = now.clone().subtract(1, 'month'),\n        invalid = moment.invalid();\n\n    assert.equal(moment.min(now, future, past), past, 'min(now, future, past)');\n    assert.equal(moment.min(future, now, past), past, 'min(future, now, past)');\n    assert.equal(moment.min(future, past, now), past, 'min(future, past, now)');\n    assert.equal(moment.min(past, future, now), past, 'min(past, future, now)');\n    assert.equal(moment.min(now, past), past, 'min(now, past)');\n    assert.equal(moment.min(past, now), past, 'min(past, now)');\n    assert.equal(moment.min(now), now, 'min(now, past)');\n\n    assert.equal(moment.min([now, future, past]), past, 'min([now, future, past])');\n    assert.equal(moment.min([now, past]), past, 'min(now, past)');\n    assert.equal(moment.min([now]), now, 'min(now)');\n\n    assert.equal(moment.min([now, invalid]), invalid, 'min(now, invalid)');\n    assert.equal(moment.min([invalid, now]), invalid, 'min(invalid, now)');\n});\n\ntest('max', function (assert) {\n    var now = moment(),\n        future = now.clone().add(1, 'month'),\n        past = now.clone().subtract(1, 'month'),\n        invalid = moment.invalid();\n\n    assert.equal(moment.max(now, future, past), future, 'max(now, future, past)');\n    assert.equal(moment.max(future, now, past), future, 'max(future, now, past)');\n    assert.equal(moment.max(future, past, now), future, 'max(future, past, now)');\n    assert.equal(moment.max(past, future, now), future, 'max(past, future, now)');\n    assert.equal(moment.max(now, past), now, 'max(now, past)');\n    assert.equal(moment.max(past, now), now, 'max(past, now)');\n    assert.equal(moment.max(now), now, 'max(now, past)');\n\n    assert.equal(moment.max([now, future, past]), future, 'max([now, future, past])');\n    assert.equal(moment.max([now, past]), now, 'max(now, past)');\n    assert.equal(moment.max([now]), now, 'max(now)');\n\n    assert.equal(moment.max([now, invalid]), invalid, 'max(now, invalid)');\n    assert.equal(moment.max([invalid, now]), invalid, 'max(invalid, now)');\n});\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/test/moment/mutable.js",
    "content": "import { module, test } from '../qunit';\nimport moment from '../../moment';\n\nmodule('mutable');\n\ntest('manipulation methods', function (assert) {\n    var m = moment();\n\n    assert.equal(m, m.year(2011), 'year() should be mutable');\n    assert.equal(m, m.month(1), 'month() should be mutable');\n    assert.equal(m, m.hours(7), 'hours() should be mutable');\n    assert.equal(m, m.minutes(33), 'minutes() should be mutable');\n    assert.equal(m, m.seconds(44), 'seconds() should be mutable');\n    assert.equal(m, m.milliseconds(55), 'milliseconds() should be mutable');\n    assert.equal(m, m.day(2), 'day() should be mutable');\n    assert.equal(m, m.startOf('week'), 'startOf() should be mutable');\n    assert.equal(m, m.add(1, 'days'), 'add() should be mutable');\n    assert.equal(m, m.subtract(2, 'years'), 'subtract() should be mutable');\n    assert.equal(m, m.local(), 'local() should be mutable');\n    assert.equal(m, m.utc(), 'utc() should be mutable');\n});\n\ntest('non mutable methods', function (assert) {\n    var m = moment();\n    assert.notEqual(m, m.clone(), 'clone() should not be mutable');\n});\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/test/moment/normalize_units.js",
    "content": "import { module, test } from '../qunit';\nimport moment from '../../moment';\n\nmodule('normalize units');\n\ntest('normalize units', function (assert) {\n    var fullKeys = ['year', 'quarter', 'month', 'isoWeek', 'week', 'day', 'hour', 'minute', 'second', 'millisecond', 'date', 'dayOfYear', 'weekday', 'isoWeekday', 'weekYear', 'isoWeekYear'],\n        aliases = ['y', 'Q', 'M', 'W', 'w', 'd', 'h', 'm', 's', 'ms', 'D', 'DDD', 'e', 'E', 'gg', 'GG'],\n        length = fullKeys.length,\n        fullKey,\n        fullKeyCaps,\n        fullKeyPlural,\n        fullKeyCapsPlural,\n        fullKeyLower,\n        alias,\n        index;\n\n    for (index = 0; index < length; index += 1) {\n        fullKey = fullKeys[index];\n        fullKeyCaps = fullKey.toUpperCase();\n        fullKeyLower = fullKey.toLowerCase();\n        fullKeyPlural = fullKey + 's';\n        fullKeyCapsPlural = fullKeyCaps + 's';\n        alias = aliases[index];\n        assert.equal(moment.normalizeUnits(fullKey), fullKey, 'Testing full key ' + fullKey);\n        assert.equal(moment.normalizeUnits(fullKeyCaps), fullKey, 'Testing full key capitalised ' + fullKey);\n        assert.equal(moment.normalizeUnits(fullKeyPlural), fullKey, 'Testing full key plural ' + fullKey);\n        assert.equal(moment.normalizeUnits(fullKeyCapsPlural), fullKey, 'Testing full key capitalised and plural ' + fullKey);\n        assert.equal(moment.normalizeUnits(alias), fullKey, 'Testing alias ' + fullKey);\n    }\n});\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/test/moment/now.js",
    "content": "import { module, test, expect } from '../qunit';\nimport moment from '../../moment';\n\nmodule('now');\n\ntest('now', function (assert) {\n    var startOfTest = new Date().valueOf(),\n        momentNowTime = moment.now(),\n        afterMomentCreationTime = new Date().valueOf();\n\n    assert.ok(startOfTest <= momentNowTime, 'moment now() time should be now, not in the past');\n    assert.ok(momentNowTime <= afterMomentCreationTime, 'moment now() time should be now, not in the future');\n});\n\ntest('now - Date mocked', function (assert) {\n    // We need to test mocking the global Date object, so disable 'Read Only' jshint check\n    /* jshint -W020 */\n    var RealDate = Date,\n        customTimeMs = moment('2015-01-01T01:30:00.000Z').valueOf();\n\n    function MockDate() {\n        return new RealDate(customTimeMs);\n    }\n\n    MockDate.now = function () {\n        return new MockDate().valueOf();\n    };\n\n    MockDate.prototype = RealDate.prototype;\n\n    Date = MockDate;\n\n    try {\n        assert.equal(moment().valueOf(), customTimeMs, 'moment now() time should use the global Date object');\n    } finally {\n        Date = RealDate;\n    }\n});\n\ntest('now - custom value', function (assert) {\n    var customTimeStr = '2015-01-01T01:30:00.000Z',\n        customTime = moment(customTimeStr, moment.ISO_8601).valueOf(),\n        oldFn = moment.now;\n\n    moment.now = function () {\n        return customTime;\n    };\n\n    try {\n        assert.equal(moment().toISOString(), customTimeStr, 'moment() constructor should use the function defined by moment.now, but it did not');\n        assert.equal(moment.utc().toISOString(), customTimeStr, 'moment() constructor should use the function defined by moment.now, but it did not');\n    } finally {\n        moment.now = oldFn;\n    }\n});\n\ntest('empty object, empty array', function (assert) {\n    function assertIsNow(gen, msg) {\n        var before = +(new Date()),\n            mid = gen(),\n            after = +(new Date());\n        assert.ok(before <= +mid && +mid <= after, 'should be now : ' + msg);\n    }\n    assertIsNow(function () {\n        return moment();\n    }, 'moment()');\n    assertIsNow(function () {\n        return moment([]);\n    }, 'moment([])');\n    assertIsNow(function () {\n        return moment({});\n    }, 'moment({})');\n    assertIsNow(function () {\n        return moment.utc();\n    }, 'moment.utc()');\n    assertIsNow(function () {\n        return moment.utc([]);\n    }, 'moment.utc([])');\n    assertIsNow(function () {\n        return moment.utc({});\n    }, 'moment.utc({})');\n});\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/test/moment/parsing_flags.js",
    "content": "import { module, test } from '../qunit';\nimport moment from '../../moment';\n\nmodule('parsing flags');\n\nfunction flags () {\n    return moment.apply(null, arguments).parsingFlags();\n}\n\ntest('overflow with array', function (assert) {\n    //months\n    assert.equal(flags([2010, 0]).overflow, -1, 'month 0 valid');\n    assert.equal(flags([2010, 1]).overflow, -1, 'month 1 valid');\n    assert.equal(flags([2010, -1]).overflow, 1, 'month -1 invalid');\n    assert.equal(flags([2100, 12]).overflow, 1, 'month 12 invalid');\n\n    //days\n    assert.equal(flags([2010, 1, 16]).overflow, -1, 'date valid');\n    assert.equal(flags([2010, 1, -1]).overflow, 2, 'date -1 invalid');\n    assert.equal(flags([2010, 1, 0]).overflow, 2, 'date 0 invalid');\n    assert.equal(flags([2010, 1, 32]).overflow, 2, 'date 32 invalid');\n    assert.equal(flags([2012, 1, 29]).overflow, -1, 'date leap year valid');\n    assert.equal(flags([2010, 1, 29]).overflow, 2, 'date leap year invalid');\n\n    //hours\n    assert.equal(flags([2010, 1, 1, 8]).overflow, -1, 'hour valid');\n    assert.equal(flags([2010, 1, 1, 0]).overflow, -1, 'hour 0 valid');\n    assert.equal(flags([2010, 1, 1, -1]).overflow, 3, 'hour -1 invalid');\n    assert.equal(flags([2010, 1, 1, 25]).overflow, 3, 'hour 25 invalid');\n    assert.equal(flags([2010, 1, 1, 24, 1]).overflow, 3, 'hour 24:01 invalid');\n\n    //minutes\n    assert.equal(flags([2010, 1, 1, 8, 15]).overflow, -1, 'minute valid');\n    assert.equal(flags([2010, 1, 1, 8, 0]).overflow, -1, 'minute 0 valid');\n    assert.equal(flags([2010, 1, 1, 8, -1]).overflow, 4, 'minute -1 invalid');\n    assert.equal(flags([2010, 1, 1, 8, 60]).overflow, 4, 'minute 60 invalid');\n\n    //seconds\n    assert.equal(flags([2010, 1, 1, 8, 15, 12]).overflow, -1, 'second valid');\n    assert.equal(flags([2010, 1, 1, 8, 15, 0]).overflow, -1, 'second 0 valid');\n    assert.equal(flags([2010, 1, 1, 8, 15, -1]).overflow, 5, 'second -1 invalid');\n    assert.equal(flags([2010, 1, 1, 8, 15, 60]).overflow, 5, 'second 60 invalid');\n\n    //milliseconds\n    assert.equal(flags([2010, 1, 1, 8, 15, 12, 345]).overflow, -1, 'millisecond valid');\n    assert.equal(flags([2010, 1, 1, 8, 15, 12, 0]).overflow, -1, 'millisecond 0 valid');\n    assert.equal(flags([2010, 1, 1, 8, 15, 12, -1]).overflow, 6, 'millisecond -1 invalid');\n    assert.equal(flags([2010, 1, 1, 8, 15, 12, 1000]).overflow, 6, 'millisecond 1000 invalid');\n\n    // 24 hrs\n    assert.equal(flags([2010, 1, 1, 24, 0, 0, 0]).overflow, -1, '24:00:00.000 is fine');\n    assert.equal(flags([2010, 1, 1, 24, 1, 0, 0]).overflow, 3, '24:01:00.000 is wrong hour');\n    assert.equal(flags([2010, 1, 1, 24, 0, 1, 0]).overflow, 3, '24:00:01.000 is wrong hour');\n    assert.equal(flags([2010, 1, 1, 24, 0, 0, 1]).overflow, 3, '24:00:00.001 is wrong hour');\n});\n\ntest('overflow without format', function (assert) {\n    //months\n    assert.equal(flags('2001-01', 'YYYY-MM').overflow, -1, 'month 1 valid');\n    assert.equal(flags('2001-12', 'YYYY-MM').overflow, -1, 'month 12 valid');\n    assert.equal(flags('2001-13', 'YYYY-MM').overflow, 1, 'month 13 invalid');\n\n    //days\n    assert.equal(flags('2010-01-16', 'YYYY-MM-DD').overflow, -1, 'date 16 valid');\n    assert.equal(flags('2010-01-0',  'YYYY-MM-DD').overflow, 2, 'date 0 invalid');\n    assert.equal(flags('2010-01-32', 'YYYY-MM-DD').overflow, 2, 'date 32 invalid');\n    assert.equal(flags('2012-02-29', 'YYYY-MM-DD').overflow, -1, 'date leap year valid');\n    assert.equal(flags('2010-02-29', 'YYYY-MM-DD').overflow, 2, 'date leap year invalid');\n\n    //days of the year\n    assert.equal(flags('2010 300', 'YYYY DDDD').overflow, -1, 'day 300 of year valid');\n    assert.equal(flags('2010 365', 'YYYY DDDD').overflow, -1, 'day 365 of year valid');\n    assert.equal(flags('2010 366', 'YYYY DDDD').overflow, 2, 'day 366 of year invalid');\n    assert.equal(flags('2012 366', 'YYYY DDDD').overflow, -1, 'day 366 of leap year valid');\n    assert.equal(flags('2012 367', 'YYYY DDDD').overflow, 2, 'day 367 of leap year invalid');\n\n    //hours\n    assert.equal(flags('08', 'HH').overflow, -1, 'hour valid');\n    assert.equal(flags('00', 'HH').overflow, -1, 'hour 0 valid');\n    assert.equal(flags('25', 'HH').overflow, 3, 'hour 25 invalid');\n    assert.equal(flags('24:01', 'HH:mm').overflow, 3, 'hour 24:01 invalid');\n\n    //minutes\n    assert.equal(flags('08:15', 'HH:mm').overflow, -1, 'minute valid');\n    assert.equal(flags('08:00', 'HH:mm').overflow, -1, 'minute 0 valid');\n    assert.equal(flags('08:60', 'HH:mm').overflow, 4, 'minute 60 invalid');\n\n    //seconds\n    assert.equal(flags('08:15:12', 'HH:mm:ss').overflow, -1, 'second valid');\n    assert.equal(flags('08:15:00', 'HH:mm:ss').overflow, -1, 'second 0 valid');\n    assert.equal(flags('08:15:60', 'HH:mm:ss').overflow, 5, 'second 60 invalid');\n\n    //milliseconds\n    assert.equal(flags('08:15:12:345', 'HH:mm:ss:SSSS').overflow, -1, 'millisecond valid');\n    assert.equal(flags('08:15:12:000', 'HH:mm:ss:SSSS').overflow, -1, 'millisecond 0 valid');\n\n    //this is OK because we don't match the last digit, so it's 100 ms\n    assert.equal(flags('08:15:12:1000', 'HH:mm:ss:SSSS').overflow, -1, 'millisecond 1000 actually valid');\n});\n\ntest('extra tokens', function (assert) {\n    assert.deepEqual(flags('1982-05-25', 'YYYY-MM-DD').unusedTokens, [], 'nothing extra');\n    assert.deepEqual(flags('1982-05', 'YYYY-MM-DD').unusedTokens, ['DD'], 'extra formatting token');\n    assert.deepEqual(flags('1982', 'YYYY-MM-DD').unusedTokens, ['MM', 'DD'], 'multiple extra formatting tokens');\n    assert.deepEqual(flags('1982-05', 'YYYY-MM-').unusedTokens, [], 'extra non-formatting token');\n    assert.deepEqual(flags('1982-05-', 'YYYY-MM-DD').unusedTokens, ['DD'], 'non-extra non-formatting token');\n    assert.deepEqual(flags('1982 05 1982', 'YYYY-MM-DD').unusedTokens, [], 'different non-formatting token');\n});\n\ntest('extra tokens strict', function (assert) {\n    assert.deepEqual(flags('1982-05-25', 'YYYY-MM-DD', true).unusedTokens, [], 'nothing extra');\n    assert.deepEqual(flags('1982-05', 'YYYY-MM-DD', true).unusedTokens, ['-', 'DD'], 'extra formatting token');\n    assert.deepEqual(flags('1982', 'YYYY-MM-DD', true).unusedTokens, ['-', 'MM', '-', 'DD'], 'multiple extra formatting tokens');\n    assert.deepEqual(flags('1982-05', 'YYYY-MM-', true).unusedTokens, ['-'], 'extra non-formatting token');\n    assert.deepEqual(flags('1982-05-', 'YYYY-MM-DD', true).unusedTokens, ['DD'], 'non-extra non-formatting token');\n    assert.deepEqual(flags('1982 05 1982', 'YYYY-MM-DD', true).unusedTokens, ['-', '-'], 'different non-formatting token');\n});\n\ntest('unused input', function (assert) {\n    assert.deepEqual(flags('1982-05-25', 'YYYY-MM-DD').unusedInput, [], 'normal input');\n    assert.deepEqual(flags('1982-05-25 this is more stuff', 'YYYY-MM-DD').unusedInput, [' this is more stuff'], 'trailing nonsense');\n    assert.deepEqual(flags('1982-05-25 09:30', 'YYYY-MM-DD').unusedInput, [' 09:30'], ['trailing legit-looking input']);\n    assert.deepEqual(flags('1982-05-25 some junk', 'YYYY-MM-DD [some junk]').unusedInput, [], 'junk that actually gets matched');\n    assert.deepEqual(flags('stuff at beginning 1982-05-25', 'YYYY-MM-DD').unusedInput, ['stuff at beginning '], 'leading junk');\n    assert.deepEqual(flags('junk 1982 more junk 05 yet more junk25', 'YYYY-MM-DD').unusedInput, ['junk ', ' more junk ', ' yet more junk'], 'interstitial junk');\n});\n\ntest('unused input strict', function (assert) {\n    assert.deepEqual(flags('1982-05-25', 'YYYY-MM-DD', true).unusedInput, [], 'normal input');\n    assert.deepEqual(flags('1982-05-25 this is more stuff', 'YYYY-MM-DD', true).unusedInput, [' this is more stuff'], 'trailing nonsense');\n    assert.deepEqual(flags('1982-05-25 09:30', 'YYYY-MM-DD', true).unusedInput, [' 09:30'], ['trailing legit-looking input']);\n    assert.deepEqual(flags('1982-05-25 some junk', 'YYYY-MM-DD [some junk]', true).unusedInput, [], 'junk that actually gets matched');\n    assert.deepEqual(flags('stuff at beginning 1982-05-25', 'YYYY-MM-DD', true).unusedInput, ['stuff at beginning '], 'leading junk');\n    assert.deepEqual(flags('junk 1982 more junk 05 yet more junk25', 'YYYY-MM-DD', true).unusedInput, ['junk ', ' more junk ', ' yet more junk'], 'interstitial junk');\n});\n\ntest('chars left over', function (assert) {\n    assert.equal(flags('1982-05-25', 'YYYY-MM-DD').charsLeftOver, 0, 'normal input');\n    assert.equal(flags('1982-05-25 this is more stuff', 'YYYY-MM-DD').charsLeftOver, ' this is more stuff'.length, 'trailing nonsense');\n    assert.equal(flags('1982-05-25 09:30', 'YYYY-MM-DD').charsLeftOver, ' 09:30'.length, 'trailing legit-looking input');\n    assert.equal(flags('stuff at beginning 1982-05-25', 'YYYY-MM-DD').charsLeftOver, 'stuff at beginning '.length, 'leading junk');\n    assert.equal(flags('1982 junk 05 more junk25', 'YYYY-MM-DD').charsLeftOver, [' junk ', ' more junk'].join('').length, 'interstitial junk');\n    assert.equal(flags('stuff at beginning 1982 junk 05 more junk25', 'YYYY-MM-DD').charsLeftOver, ['stuff at beginning ', ' junk ', ' more junk'].join('').length, 'leading and interstitial junk');\n});\n\ntest('empty', function (assert) {\n    assert.equal(flags('1982-05-25', 'YYYY-MM-DD').empty, false, 'normal input');\n    assert.equal(flags('nothing here', 'YYYY-MM-DD').empty, true, 'pure garbage');\n    assert.equal(flags('junk but has the number 2000 in it', 'YYYY-MM-DD').empty, false, 'only mostly garbage');\n    assert.equal(flags('', 'YYYY-MM-DD').empty, true, 'empty string');\n    assert.equal(flags('', 'YYYY-MM-DD').empty, true, 'blank string');\n});\n\ntest('null', function (assert) {\n    assert.equal(flags('1982-05-25', 'YYYY-MM-DD').nullInput, false, 'normal input');\n    assert.equal(flags(null).nullInput, true, 'just null');\n    assert.equal(flags(null, 'YYYY-MM-DD').nullInput, true, 'null with format');\n});\n\ntest('invalid month', function (assert) {\n    assert.equal(flags('1982 May', 'YYYY MMMM').invalidMonth, null, 'normal input');\n    assert.equal(flags('1982 Laser', 'YYYY MMMM').invalidMonth, 'Laser', 'bad month name');\n});\n\ntest('empty format array', function (assert) {\n    assert.equal(flags('1982 May', ['YYYY MMM']).invalidFormat, false, 'empty format array');\n    assert.equal(flags('1982 May', []).invalidFormat, true, 'empty format array');\n});\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/test/moment/preparse_postformat.js",
    "content": "import { module, test } from '../qunit';\nimport moment from '../../moment';\n\nvar symbolMap = {\n        '1': '!',\n        '2': '@',\n        '3': '#',\n        '4': '$',\n        '5': '%',\n        '6': '^',\n        '7': '&',\n        '8': '*',\n        '9': '(',\n        '0': ')'\n    },\n    numberMap = {\n        '!': '1',\n        '@': '2',\n        '#': '3',\n        '$': '4',\n        '%': '5',\n        '^': '6',\n        '&': '7',\n        '*': '8',\n        '(': '9',\n        ')': '0'\n    };\n\nmodule('preparse and postformat', {\n    setup: function () {\n        moment.locale('symbol', {\n            preparse: function (string) {\n                return string.replace(/[!@#$%\\^&*()]/g, function (match) {\n                    return numberMap[match];\n                });\n            },\n\n            postformat: function (string) {\n                return string.replace(/\\d/g, function (match) {\n                    return symbolMap[match];\n                });\n            }\n        });\n    },\n    teardown: function () {\n        moment.defineLocale('symbol', null);\n    }\n});\n\ntest('transform', function (assert) {\n    assert.equal(moment.utc('@)!@-)*-@&', 'YYYY-MM-DD').unix(), 1346025600, 'preparse string + format');\n    assert.equal(moment.utc('@)!@-)*-@&').unix(), 1346025600, 'preparse ISO8601 string');\n    assert.equal(moment.unix(1346025600).utc().format('YYYY-MM-DD'), '@)!@-)*-@&', 'postformat');\n});\n\ntest('transform from', function (assert) {\n    var start = moment([2007, 1, 28]);\n\n    assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true), '@ minutes', 'postformat should work on moment.fn.from');\n    assert.equal(moment().add(6, 'd').fromNow(true), '^ days', 'postformat should work on moment.fn.fromNow');\n    assert.equal(moment.duration(10, 'h').humanize(), '!) hours', 'postformat should work on moment.duration.fn.humanize');\n});\n\ntest('calendar day', function (assert) {\n    var a = moment().hours(12).minutes(0).seconds(0);\n\n    assert.equal(moment(a).calendar(),                   'Today at !@:)) PM',     'today at the same time');\n    assert.equal(moment(a).add({m: 25}).calendar(),      'Today at !@:@% PM',     'Now plus 25 min');\n    assert.equal(moment(a).add({h: 1}).calendar(),       'Today at !:)) PM',      'Now plus 1 hour');\n    assert.equal(moment(a).add({d: 1}).calendar(),       'Tomorrow at !@:)) PM',  'tomorrow at the same time');\n    assert.equal(moment(a).subtract({h: 1}).calendar(),  'Today at !!:)) AM',     'Now minus 1 hour');\n    assert.equal(moment(a).subtract({d: 1}).calendar(),  'Yesterday at !@:)) PM', 'yesterday at the same time');\n});\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/test/moment/quarter.js",
    "content": "import { module, test } from '../qunit';\nimport moment from '../../moment';\n\nmodule('quarter');\n\ntest('library quarter getter', function (assert) {\n    assert.equal(moment([1985,  1,  4]).quarter(), 1, 'Feb  4 1985 is Q1');\n    assert.equal(moment([2029,  8, 18]).quarter(), 3, 'Sep 18 2029 is Q3');\n    assert.equal(moment([2013,  3, 24]).quarter(), 2, 'Apr 24 2013 is Q2');\n    assert.equal(moment([2015,  2,  5]).quarter(), 1, 'Mar  5 2015 is Q1');\n    assert.equal(moment([1970,  0,  2]).quarter(), 1, 'Jan  2 1970 is Q1');\n    assert.equal(moment([2001, 11, 12]).quarter(), 4, 'Dec 12 2001 is Q4');\n    assert.equal(moment([2000,  0,  2]).quarter(), 1, 'Jan  2 2000 is Q1');\n});\n\ntest('quarter setter singular', function (assert) {\n    var m = moment([2014, 4, 11]);\n    assert.equal(m.quarter(2).month(), 4, 'set same quarter');\n    assert.equal(m.quarter(3).month(), 7, 'set 3rd quarter');\n    assert.equal(m.quarter(1).month(), 1, 'set 1st quarter');\n    assert.equal(m.quarter(4).month(), 10, 'set 4th quarter');\n});\n\ntest('quarter setter plural', function (assert) {\n    var m = moment([2014, 4, 11]);\n    assert.equal(m.quarters(2).month(), 4, 'set same quarter');\n    assert.equal(m.quarters(3).month(), 7, 'set 3rd quarter');\n    assert.equal(m.quarters(1).month(), 1, 'set 1st quarter');\n    assert.equal(m.quarters(4).month(), 10, 'set 4th quarter');\n});\n\ntest('quarter setter programmatic', function (assert) {\n    var m = moment([2014, 4, 11]);\n    assert.equal(m.set('quarter', 2).month(), 4, 'set same quarter');\n    assert.equal(m.set('quarter', 3).month(), 7, 'set 3rd quarter');\n    assert.equal(m.set('quarter', 1).month(), 1, 'set 1st quarter');\n    assert.equal(m.set('quarter', 4).month(), 10, 'set 4th quarter');\n});\n\ntest('quarter setter programmatic plural', function (assert) {\n    var m = moment([2014, 4, 11]);\n    assert.equal(m.set('quarters', 2).month(), 4, 'set same quarter');\n    assert.equal(m.set('quarters', 3).month(), 7, 'set 3rd quarter');\n    assert.equal(m.set('quarters', 1).month(), 1, 'set 1st quarter');\n    assert.equal(m.set('quarters', 4).month(), 10, 'set 4th quarter');\n});\n\ntest('quarter setter programmatic abbr', function (assert) {\n    var m = moment([2014, 4, 11]);\n    assert.equal(m.set('Q', 2).month(), 4, 'set same quarter');\n    assert.equal(m.set('Q', 3).month(), 7, 'set 3rd quarter');\n    assert.equal(m.set('Q', 1).month(), 1, 'set 1st quarter');\n    assert.equal(m.set('Q', 4).month(), 10, 'set 4th quarter');\n});\n\ntest('quarter setter only month changes', function (assert) {\n    var m = moment([2014, 4, 11, 1, 2, 3, 4]).quarter(4);\n    assert.equal(m.year(), 2014, 'keep year');\n    assert.equal(m.month(), 10, 'set month');\n    assert.equal(m.date(), 11, 'keep date');\n    assert.equal(m.hour(), 1, 'keep hour');\n    assert.equal(m.minute(), 2, 'keep minutes');\n    assert.equal(m.second(), 3, 'keep seconds');\n    assert.equal(m.millisecond(), 4, 'keep milliseconds');\n});\n\ntest('quarter setter bubble to next year', function (assert) {\n    var m = moment([2014, 4, 11, 1, 2, 3, 4]).quarter(7);\n    assert.equal(m.year(), 2015, 'year bubbled');\n    assert.equal(m.month(), 7, 'set month');\n    assert.equal(m.date(), 11, 'keep date');\n    assert.equal(m.hour(), 1, 'keep hour');\n    assert.equal(m.minute(), 2, 'keep minutes');\n    assert.equal(m.second(), 3, 'keep seconds');\n    assert.equal(m.millisecond(), 4, 'keep milliseconds');\n});\n\ntest('quarter diff', function (assert) {\n    assert.equal(moment('2014-01-01').diff(moment('2014-04-01'), 'quarter'),\n            -1, 'diff -1 quarter');\n    assert.equal(moment('2014-04-01').diff(moment('2014-01-01'), 'quarter'),\n            1, 'diff 1 quarter');\n    assert.equal(moment('2014-05-01').diff(moment('2014-01-01'), 'quarter'),\n            1, 'diff 1 quarter');\n    assert.ok(Math.abs((4 / 3) - moment('2014-05-01').diff(\n                    moment('2014-01-01'), 'quarter', true)) < 0.00001,\n            'diff 1 1/3 quarter');\n    assert.equal(moment('2015-01-01').diff(moment('2014-01-01'), 'quarter'),\n            4, 'diff 4 quarters');\n});\n\ntest('quarter setter bubble to previous year', function (assert) {\n    var m = moment([2014, 4, 11, 1, 2, 3, 4]).quarter(-3);\n    assert.equal(m.year(), 2013, 'year bubbled');\n    assert.equal(m.month(), 1, 'set month');\n    assert.equal(m.date(), 11, 'keep date');\n    assert.equal(m.hour(), 1, 'keep hour');\n    assert.equal(m.minute(), 2, 'keep minutes');\n    assert.equal(m.second(), 3, 'keep seconds');\n    assert.equal(m.millisecond(), 4, 'keep milliseconds');\n});\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/test/moment/relative_time.js",
    "content": "import { module, test } from '../qunit';\nimport moment from '../../moment';\n\nmodule('relative time');\n\ntest('default thresholds fromNow', function (assert) {\n    var a = moment();\n\n    // Seconds to minutes threshold\n    a.subtract(44, 'seconds');\n    assert.equal(a.fromNow(), 'a few seconds ago', 'Below default seconds to minutes threshold');\n    a.subtract(1, 'seconds');\n    assert.equal(a.fromNow(), 'a minute ago', 'Above default seconds to minutes threshold');\n\n    // Minutes to hours threshold\n    a = moment();\n    a.subtract(44, 'minutes');\n    assert.equal(a.fromNow(), '44 minutes ago', 'Below default minute to hour threshold');\n    a.subtract(1, 'minutes');\n    assert.equal(a.fromNow(), 'an hour ago', 'Above default minute to hour threshold');\n\n    // Hours to days threshold\n    a = moment();\n    a.subtract(21, 'hours');\n    assert.equal(a.fromNow(), '21 hours ago', 'Below default hours to day threshold');\n    a.subtract(1, 'hours');\n    assert.equal(a.fromNow(), 'a day ago', 'Above default hours to day threshold');\n\n    // Days to month threshold\n    a = moment();\n    a.subtract(25, 'days');\n    assert.equal(a.fromNow(), '25 days ago', 'Below default days to month (singular) threshold');\n    a.subtract(1, 'days');\n    assert.equal(a.fromNow(), 'a month ago', 'Above default days to month (singular) threshold');\n\n    // months to year threshold\n    a = moment();\n    a.subtract(10, 'months');\n    assert.equal(a.fromNow(), '10 months ago', 'Below default days to years threshold');\n    a.subtract(1, 'month');\n    assert.equal(a.fromNow(), 'a year ago', 'Above default days to years threshold');\n});\n\ntest('default thresholds toNow', function (assert) {\n    var a = moment();\n\n    // Seconds to minutes threshold\n    a.subtract(44, 'seconds');\n    assert.equal(a.toNow(), 'in a few seconds', 'Below default seconds to minutes threshold');\n    a.subtract(1, 'seconds');\n    assert.equal(a.toNow(), 'in a minute', 'Above default seconds to minutes threshold');\n\n    // Minutes to hours threshold\n    a = moment();\n    a.subtract(44, 'minutes');\n    assert.equal(a.toNow(), 'in 44 minutes', 'Below default minute to hour threshold');\n    a.subtract(1, 'minutes');\n    assert.equal(a.toNow(), 'in an hour', 'Above default minute to hour threshold');\n\n    // Hours to days threshold\n    a = moment();\n    a.subtract(21, 'hours');\n    assert.equal(a.toNow(), 'in 21 hours', 'Below default hours to day threshold');\n    a.subtract(1, 'hours');\n    assert.equal(a.toNow(), 'in a day', 'Above default hours to day threshold');\n\n    // Days to month threshold\n    a = moment();\n    a.subtract(25, 'days');\n    assert.equal(a.toNow(), 'in 25 days', 'Below default days to month (singular) threshold');\n    a.subtract(1, 'days');\n    assert.equal(a.toNow(), 'in a month', 'Above default days to month (singular) threshold');\n\n    // months to year threshold\n    a = moment();\n    a.subtract(10, 'months');\n    assert.equal(a.toNow(), 'in 10 months', 'Below default days to years threshold');\n    a.subtract(1, 'month');\n    assert.equal(a.toNow(), 'in a year', 'Above default days to years threshold');\n});\n\ntest('custom thresholds', function (assert) {\n    var a;\n\n    // Seconds to minute threshold, under 30\n    moment.relativeTimeThreshold('s', 25);\n\n    a = moment();\n    a.subtract(24, 'seconds');\n    assert.equal(a.fromNow(), 'a few seconds ago', 'Below custom seconds to minute threshold, s < 30');\n    a.subtract(1, 'seconds');\n    assert.equal(a.fromNow(), 'a minute ago', 'Above custom seconds to minute threshold, s < 30');\n\n    // Seconds to minutes threshold\n    moment.relativeTimeThreshold('s', 55);\n\n    a = moment();\n    a.subtract(54, 'seconds');\n    assert.equal(a.fromNow(), 'a few seconds ago', 'Below custom seconds to minutes threshold');\n    a.subtract(1, 'seconds');\n    assert.equal(a.fromNow(), 'a minute ago', 'Above custom seconds to minutes threshold');\n\n    moment.relativeTimeThreshold('s', 45);\n\n    // A few seconds to seconds threshold\n    moment.relativeTimeThreshold('ss', 3);\n\n    a = moment();\n    a.subtract(3, 'seconds');\n    assert.equal(a.fromNow(), 'a few seconds ago', 'Below custom a few seconds to seconds threshold');\n    a.subtract(1, 'seconds');\n    assert.equal(a.fromNow(), '4 seconds ago', 'Above custom a few seconds to seconds threshold');\n\n    moment.relativeTimeThreshold('ss', 44);\n\n    // Minutes to hours threshold\n    moment.relativeTimeThreshold('m', 55);\n    a = moment();\n    a.subtract(54, 'minutes');\n    assert.equal(a.fromNow(), '54 minutes ago', 'Below custom minutes to hours threshold');\n    a.subtract(1, 'minutes');\n    assert.equal(a.fromNow(), 'an hour ago', 'Above custom minutes to hours threshold');\n    moment.relativeTimeThreshold('m', 45);\n\n    // Hours to days threshold\n    moment.relativeTimeThreshold('h', 24);\n    a = moment();\n    a.subtract(23, 'hours');\n    assert.equal(a.fromNow(), '23 hours ago', 'Below custom hours to days threshold');\n    a.subtract(1, 'hours');\n    assert.equal(a.fromNow(), 'a day ago', 'Above custom hours to days threshold');\n    moment.relativeTimeThreshold('h', 22);\n\n    // Days to month threshold\n    moment.relativeTimeThreshold('d', 28);\n    a = moment();\n    a.subtract(27, 'days');\n    assert.equal(a.fromNow(), '27 days ago', 'Below custom days to month (singular) threshold');\n    a.subtract(1, 'days');\n    assert.equal(a.fromNow(), 'a month ago', 'Above custom days to month (singular) threshold');\n    moment.relativeTimeThreshold('d', 26);\n\n    // months to years threshold\n    moment.relativeTimeThreshold('M', 9);\n    a = moment();\n    a.subtract(8, 'months');\n    assert.equal(a.fromNow(), '8 months ago', 'Below custom days to years threshold');\n    a.subtract(1, 'months');\n    assert.equal(a.fromNow(), 'a year ago', 'Above custom days to years threshold');\n    moment.relativeTimeThreshold('M', 11);\n});\n\ntest('custom rounding', function (assert) {\n    var roundingDefault = moment.relativeTimeRounding();\n\n    // Round relative time evaluation down\n    moment.relativeTimeRounding(Math.floor);\n\n    moment.relativeTimeThreshold('s', 60);\n    moment.relativeTimeThreshold('m', 60);\n    moment.relativeTimeThreshold('h', 24);\n    moment.relativeTimeThreshold('d', 27);\n    moment.relativeTimeThreshold('M', 12);\n\n    var a = moment.utc();\n    a.subtract({minutes: 59, seconds: 59});\n    assert.equal(a.toNow(), 'in 59 minutes', 'Round down towards the nearest minute');\n\n    a = moment.utc();\n    a.subtract({hours: 23, minutes: 59, seconds: 59});\n    assert.equal(a.toNow(), 'in 23 hours', 'Round down towards the nearest hour');\n\n    a = moment.utc();\n    a.subtract({days: 26, hours: 23, minutes: 59});\n    assert.equal(a.toNow(), 'in 26 days', 'Round down towards the nearest day (just under)');\n\n    a = moment.utc();\n    a.subtract({days: 27});\n    assert.equal(a.toNow(), 'in a month', 'Round down towards the nearest day (just over)');\n\n    a = moment.utc();\n    a.subtract({days: 364});\n    assert.equal(a.toNow(), 'in 11 months', 'Round down towards the nearest month');\n\n    a = moment.utc();\n    a.subtract({years: 1, days: 364});\n    assert.equal(a.toNow(), 'in a year', 'Round down towards the nearest year');\n\n    // Do not round relative time evaluation\n    var retainValue = function (value) {\n        return value.toFixed(3);\n    };\n    moment.relativeTimeRounding(retainValue);\n\n    a = moment.utc();\n    a.subtract({hours: 39});\n    assert.equal(a.toNow(), 'in 1.625 days', 'Round down towards the nearest year');\n\n    // Restore defaults\n    moment.relativeTimeThreshold('s', 45);\n    moment.relativeTimeThreshold('m', 45);\n    moment.relativeTimeThreshold('h', 22);\n    moment.relativeTimeThreshold('d', 26);\n    moment.relativeTimeThreshold('M', 11);\n    moment.relativeTimeRounding(roundingDefault);\n});\n\ntest('retrieve rounding settings', function (assert) {\n    moment.relativeTimeRounding(Math.round);\n    var roundingFunction = moment.relativeTimeRounding();\n\n    assert.equal(roundingFunction, Math.round, 'Can retrieve rounding setting');\n});\n\ntest('retrieve threshold settings', function (assert) {\n    moment.relativeTimeThreshold('m', 45);\n    var minuteThreshold = moment.relativeTimeThreshold('m');\n\n    assert.equal(minuteThreshold, 45, 'Can retrieve minute setting');\n});\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/test/moment/start_end_of.js",
    "content": "import { module, test } from '../qunit';\nimport moment from '../../moment';\n\nmodule('start and end of units');\n\ntest('start of year', function (assert) {\n    var m = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).startOf('year'),\n        ms = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).startOf('years'),\n        ma = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).startOf('y');\n    assert.equal(+m, +ms, 'Plural or singular should work');\n    assert.equal(+m, +ma, 'Full or abbreviated should work');\n    assert.equal(m.year(), 2011, 'keep the year');\n    assert.equal(m.month(), 0, 'strip out the month');\n    assert.equal(m.date(), 1, 'strip out the day');\n    assert.equal(m.hours(), 0, 'strip out the hours');\n    assert.equal(m.minutes(), 0, 'strip out the minutes');\n    assert.equal(m.seconds(), 0, 'strip out the seconds');\n    assert.equal(m.milliseconds(), 0, 'strip out the milliseconds');\n});\n\ntest('end of year', function (assert) {\n    var m = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).endOf('year'),\n        ms = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).endOf('years'),\n        ma = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).endOf('y');\n    assert.equal(+m, +ms, 'Plural or singular should work');\n    assert.equal(+m, +ma, 'Full or abbreviated should work');\n    assert.equal(m.year(), 2011, 'keep the year');\n    assert.equal(m.month(), 11, 'set the month');\n    assert.equal(m.date(), 31, 'set the day');\n    assert.equal(m.hours(), 23, 'set the hours');\n    assert.equal(m.minutes(), 59, 'set the minutes');\n    assert.equal(m.seconds(), 59, 'set the seconds');\n    assert.equal(m.milliseconds(), 999, 'set the seconds');\n});\n\ntest('start of quarter', function (assert) {\n    var m = moment(new Date(2011, 4, 2, 3, 4, 5, 6)).startOf('quarter'),\n        ms = moment(new Date(2011, 4, 2, 3, 4, 5, 6)).startOf('quarters'),\n        ma = moment(new Date(2011, 4, 2, 3, 4, 5, 6)).startOf('Q');\n    assert.equal(+m, +ms, 'Plural or singular should work');\n    assert.equal(+m, +ma, 'Full or abbreviated should work');\n    assert.equal(m.year(), 2011, 'keep the year');\n    assert.equal(m.quarter(), 2, 'keep the quarter');\n    assert.equal(m.month(), 3, 'strip out the month');\n    assert.equal(m.date(), 1, 'strip out the day');\n    assert.equal(m.hours(), 0, 'strip out the hours');\n    assert.equal(m.minutes(), 0, 'strip out the minutes');\n    assert.equal(m.seconds(), 0, 'strip out the seconds');\n    assert.equal(m.milliseconds(), 0, 'strip out the milliseconds');\n});\n\ntest('end of quarter', function (assert) {\n    var m = moment(new Date(2011, 4, 2, 3, 4, 5, 6)).endOf('quarter'),\n        ms = moment(new Date(2011, 4, 2, 3, 4, 5, 6)).endOf('quarters'),\n        ma = moment(new Date(2011, 4, 2, 3, 4, 5, 6)).endOf('Q');\n    assert.equal(+m, +ms, 'Plural or singular should work');\n    assert.equal(+m, +ma, 'Full or abbreviated should work');\n    assert.equal(m.year(), 2011, 'keep the year');\n    assert.equal(m.quarter(), 2, 'keep the quarter');\n    assert.equal(m.month(), 5, 'set the month');\n    assert.equal(m.date(), 30, 'set the day');\n    assert.equal(m.hours(), 23, 'set the hours');\n    assert.equal(m.minutes(), 59, 'set the minutes');\n    assert.equal(m.seconds(), 59, 'set the seconds');\n    assert.equal(m.milliseconds(), 999, 'set the seconds');\n});\n\ntest('start of month', function (assert) {\n    var m = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).startOf('month'),\n        ms = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).startOf('months'),\n        ma = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).startOf('M');\n    assert.equal(+m, +ms, 'Plural or singular should work');\n    assert.equal(+m, +ma, 'Full or abbreviated should work');\n    assert.equal(m.year(), 2011, 'keep the year');\n    assert.equal(m.month(), 1, 'keep the month');\n    assert.equal(m.date(), 1, 'strip out the day');\n    assert.equal(m.hours(), 0, 'strip out the hours');\n    assert.equal(m.minutes(), 0, 'strip out the minutes');\n    assert.equal(m.seconds(), 0, 'strip out the seconds');\n    assert.equal(m.milliseconds(), 0, 'strip out the milliseconds');\n});\n\ntest('end of month', function (assert) {\n    var m = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).endOf('month'),\n        ms = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).endOf('months'),\n        ma = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).endOf('M');\n    assert.equal(+m, +ms, 'Plural or singular should work');\n    assert.equal(+m, +ma, 'Full or abbreviated should work');\n    assert.equal(m.year(), 2011, 'keep the year');\n    assert.equal(m.month(), 1, 'keep the month');\n    assert.equal(m.date(), 28, 'set the day');\n    assert.equal(m.hours(), 23, 'set the hours');\n    assert.equal(m.minutes(), 59, 'set the minutes');\n    assert.equal(m.seconds(), 59, 'set the seconds');\n    assert.equal(m.milliseconds(), 999, 'set the seconds');\n});\n\ntest('start of week', function (assert) {\n    var m = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).startOf('week'),\n        ms = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).startOf('weeks'),\n        ma = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).startOf('w');\n    assert.equal(+m, +ms, 'Plural or singular should work');\n    assert.equal(+m, +ma, 'Full or abbreviated should work');\n    assert.equal(m.year(), 2011, 'keep the year');\n    assert.equal(m.month(), 0, 'rolls back to January');\n    assert.equal(m.day(), 0, 'set day of week');\n    assert.equal(m.date(), 30, 'set correct date');\n    assert.equal(m.hours(), 0, 'strip out the hours');\n    assert.equal(m.minutes(), 0, 'strip out the minutes');\n    assert.equal(m.seconds(), 0, 'strip out the seconds');\n    assert.equal(m.milliseconds(), 0, 'strip out the milliseconds');\n});\n\ntest('end of week', function (assert) {\n    var m = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).endOf('week'),\n        ms = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).endOf('weeks'),\n        ma = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).endOf('weeks');\n    assert.equal(+m, +ms, 'Plural or singular should work');\n    assert.equal(+m, +ma, 'Full or abbreviated should work');\n    assert.equal(m.year(), 2011, 'keep the year');\n    assert.equal(m.month(), 1, 'keep the month');\n    assert.equal(m.day(), 6, 'set the day of the week');\n    assert.equal(m.date(), 5, 'set the day');\n    assert.equal(m.hours(), 23, 'set the hours');\n    assert.equal(m.minutes(), 59, 'set the minutes');\n    assert.equal(m.seconds(), 59, 'set the seconds');\n    assert.equal(m.milliseconds(), 999, 'set the seconds');\n});\n\ntest('start of iso-week', function (assert) {\n    var m = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).startOf('isoWeek'),\n        ms = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).startOf('isoWeeks'),\n        ma = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).startOf('W');\n    assert.equal(+m, +ms, 'Plural or singular should work');\n    assert.equal(+m, +ma, 'Full or abbreviated should work');\n    assert.equal(m.year(), 2011, 'keep the year');\n    assert.equal(m.month(), 0, 'rollback to January');\n    assert.equal(m.isoWeekday(), 1, 'set day of iso-week');\n    assert.equal(m.date(), 31, 'set correct date');\n    assert.equal(m.hours(), 0, 'strip out the hours');\n    assert.equal(m.minutes(), 0, 'strip out the minutes');\n    assert.equal(m.seconds(), 0, 'strip out the seconds');\n    assert.equal(m.milliseconds(), 0, 'strip out the milliseconds');\n});\n\ntest('end of iso-week', function (assert) {\n    var m = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).endOf('isoWeek'),\n        ms = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).endOf('isoWeeks'),\n        ma = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).endOf('W');\n    assert.equal(+m, +ms, 'Plural or singular should work');\n    assert.equal(+m, +ma, 'Full or abbreviated should work');\n    assert.equal(m.year(), 2011, 'keep the year');\n    assert.equal(m.month(), 1, 'keep the month');\n    assert.equal(m.isoWeekday(), 7, 'set the day of the week');\n    assert.equal(m.date(), 6, 'set the day');\n    assert.equal(m.hours(), 23, 'set the hours');\n    assert.equal(m.minutes(), 59, 'set the minutes');\n    assert.equal(m.seconds(), 59, 'set the seconds');\n    assert.equal(m.milliseconds(), 999, 'set the seconds');\n});\n\ntest('start of day', function (assert) {\n    var m = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).startOf('day'),\n        ms = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).startOf('days'),\n        ma = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).startOf('d');\n    assert.equal(+m, +ms, 'Plural or singular should work');\n    assert.equal(+m, +ma, 'Full or abbreviated should work');\n    assert.equal(m.year(), 2011, 'keep the year');\n    assert.equal(m.month(), 1, 'keep the month');\n    assert.equal(m.date(), 2, 'keep the day');\n    assert.equal(m.hours(), 0, 'strip out the hours');\n    assert.equal(m.minutes(), 0, 'strip out the minutes');\n    assert.equal(m.seconds(), 0, 'strip out the seconds');\n    assert.equal(m.milliseconds(), 0, 'strip out the milliseconds');\n});\n\ntest('end of day', function (assert) {\n    var m = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).endOf('day'),\n        ms = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).endOf('days'),\n        ma = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).endOf('d');\n    assert.equal(+m, +ms, 'Plural or singular should work');\n    assert.equal(+m, +ma, 'Full or abbreviated should work');\n    assert.equal(m.year(), 2011, 'keep the year');\n    assert.equal(m.month(), 1, 'keep the month');\n    assert.equal(m.date(), 2, 'keep the day');\n    assert.equal(m.hours(), 23, 'set the hours');\n    assert.equal(m.minutes(), 59, 'set the minutes');\n    assert.equal(m.seconds(), 59, 'set the seconds');\n    assert.equal(m.milliseconds(), 999, 'set the seconds');\n});\n\ntest('start of date', function (assert) {\n    var m = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).startOf('date'),\n        ms = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).startOf('dates');\n\n    assert.equal(+m, +ms, 'Plural or singular should work');\n    assert.equal(m.year(), 2011, 'keep the year');\n    assert.equal(m.month(), 1, 'keep the month');\n    assert.equal(m.date(), 2, 'keep the day');\n    assert.equal(m.hours(), 0, 'strip out the hours');\n    assert.equal(m.minutes(), 0, 'strip out the minutes');\n    assert.equal(m.seconds(), 0, 'strip out the seconds');\n    assert.equal(m.milliseconds(), 0, 'strip out the milliseconds');\n});\n\ntest('end of date', function (assert) {\n    var m = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).endOf('date'),\n        ms = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).endOf('dates');\n\n    assert.equal(+m, +ms, 'Plural or singular should work');\n    assert.equal(m.year(), 2011, 'keep the year');\n    assert.equal(m.month(), 1, 'keep the month');\n    assert.equal(m.date(), 2, 'keep the day');\n    assert.equal(m.hours(), 23, 'set the hours');\n    assert.equal(m.minutes(), 59, 'set the minutes');\n    assert.equal(m.seconds(), 59, 'set the seconds');\n    assert.equal(m.milliseconds(), 999, 'set the seconds');\n});\n\n\ntest('start of hour', function (assert) {\n    var m = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).startOf('hour'),\n        ms = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).startOf('hours'),\n        ma = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).startOf('h');\n    assert.equal(+m, +ms, 'Plural or singular should work');\n    assert.equal(+m, +ma, 'Full or abbreviated should work');\n    assert.equal(m.year(), 2011, 'keep the year');\n    assert.equal(m.month(), 1, 'keep the month');\n    assert.equal(m.date(), 2, 'keep the day');\n    assert.equal(m.hours(), 3, 'keep the hours');\n    assert.equal(m.minutes(), 0, 'strip out the minutes');\n    assert.equal(m.seconds(), 0, 'strip out the seconds');\n    assert.equal(m.milliseconds(), 0, 'strip out the milliseconds');\n});\n\ntest('end of hour', function (assert) {\n    var m = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).endOf('hour'),\n        ms = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).endOf('hours'),\n        ma = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).endOf('h');\n    assert.equal(+m, +ms, 'Plural or singular should work');\n    assert.equal(+m, +ma, 'Full or abbreviated should work');\n    assert.equal(m.year(), 2011, 'keep the year');\n    assert.equal(m.month(), 1, 'keep the month');\n    assert.equal(m.date(), 2, 'keep the day');\n    assert.equal(m.hours(), 3, 'keep the hours');\n    assert.equal(m.minutes(), 59, 'set the minutes');\n    assert.equal(m.seconds(), 59, 'set the seconds');\n    assert.equal(m.milliseconds(), 999, 'set the seconds');\n});\n\ntest('start of minute', function (assert) {\n    var m = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).startOf('minute'),\n        ms = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).startOf('minutes'),\n        ma = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).startOf('m');\n    assert.equal(+m, +ms, 'Plural or singular should work');\n    assert.equal(+m, +ma, 'Full or abbreviated should work');\n    assert.equal(m.year(), 2011, 'keep the year');\n    assert.equal(m.month(), 1, 'keep the month');\n    assert.equal(m.date(), 2, 'keep the day');\n    assert.equal(m.hours(), 3, 'keep the hours');\n    assert.equal(m.minutes(), 4, 'keep the minutes');\n    assert.equal(m.seconds(), 0, 'strip out the seconds');\n    assert.equal(m.milliseconds(), 0, 'strip out the milliseconds');\n});\n\ntest('end of minute', function (assert) {\n    var m = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).endOf('minute'),\n        ms = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).endOf('minutes'),\n        ma = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).endOf('m');\n    assert.equal(+m, +ms, 'Plural or singular should work');\n    assert.equal(+m, +ma, 'Full or abbreviated should work');\n    assert.equal(m.year(), 2011, 'keep the year');\n    assert.equal(m.month(), 1, 'keep the month');\n    assert.equal(m.date(), 2, 'keep the day');\n    assert.equal(m.hours(), 3, 'keep the hours');\n    assert.equal(m.minutes(), 4, 'keep the minutes');\n    assert.equal(m.seconds(), 59, 'set the seconds');\n    assert.equal(m.milliseconds(), 999, 'set the seconds');\n});\n\ntest('start of second', function (assert) {\n    var m = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).startOf('second'),\n        ms = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).startOf('seconds'),\n        ma = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).startOf('s');\n    assert.equal(+m, +ms, 'Plural or singular should work');\n    assert.equal(+m, +ma, 'Full or abbreviated should work');\n    assert.equal(m.year(), 2011, 'keep the year');\n    assert.equal(m.month(), 1, 'keep the month');\n    assert.equal(m.date(), 2, 'keep the day');\n    assert.equal(m.hours(), 3, 'keep the hours');\n    assert.equal(m.minutes(), 4, 'keep the minutes');\n    assert.equal(m.seconds(), 5, 'keep the the seconds');\n    assert.equal(m.milliseconds(), 0, 'strip out the milliseconds');\n});\n\ntest('end of second', function (assert) {\n    var m = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).endOf('second'),\n        ms = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).endOf('seconds'),\n        ma = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).endOf('s');\n    assert.equal(+m, +ms, 'Plural or singular should work');\n    assert.equal(+m, +ma, 'Full or abbreviated should work');\n    assert.equal(m.year(), 2011, 'keep the year');\n    assert.equal(m.month(), 1, 'keep the month');\n    assert.equal(m.date(), 2, 'keep the day');\n    assert.equal(m.hours(), 3, 'keep the hours');\n    assert.equal(m.minutes(), 4, 'keep the minutes');\n    assert.equal(m.seconds(), 5, 'keep the seconds');\n    assert.equal(m.milliseconds(), 999, 'set the seconds');\n});\n\ntest('startOf across DST +1', function (assert) {\n    var oldUpdateOffset = moment.updateOffset,\n        // Based on a real story somewhere in America/Los_Angeles\n        dstAt = moment('2014-03-09T02:00:00-08:00').parseZone(),\n        m;\n\n    moment.updateOffset = function (mom, keepTime) {\n        if (mom.isBefore(dstAt)) {\n            mom.utcOffset(-8, keepTime);\n        } else {\n            mom.utcOffset(-7, keepTime);\n        }\n    };\n\n    m = moment('2014-03-15T00:00:00-07:00').parseZone();\n    m.startOf('y');\n    assert.equal(m.format(), '2014-01-01T00:00:00-08:00', 'startOf(\\'year\\') across +1');\n\n    m = moment('2014-03-15T00:00:00-07:00').parseZone();\n    m.startOf('M');\n    assert.equal(m.format(), '2014-03-01T00:00:00-08:00', 'startOf(\\'month\\') across +1');\n\n    m = moment('2014-03-09T09:00:00-07:00').parseZone();\n    m.startOf('d');\n    assert.equal(m.format(), '2014-03-09T00:00:00-08:00', 'startOf(\\'day\\') across +1');\n\n    m = moment('2014-03-09T03:05:00-07:00').parseZone();\n    m.startOf('h');\n    assert.equal(m.format(), '2014-03-09T03:00:00-07:00', 'startOf(\\'hour\\') after +1');\n\n    m = moment('2014-03-09T01:35:00-08:00').parseZone();\n    m.startOf('h');\n    assert.equal(m.format(), '2014-03-09T01:00:00-08:00', 'startOf(\\'hour\\') before +1');\n\n    // There is no such time as 2:30-7 to try startOf('hour') across that\n\n    moment.updateOffset = oldUpdateOffset;\n});\n\ntest('startOf across DST -1', function (assert) {\n    var oldUpdateOffset = moment.updateOffset,\n        // Based on a real story somewhere in America/Los_Angeles\n        dstAt = moment('2014-11-02T02:00:00-07:00').parseZone(),\n        m;\n\n    moment.updateOffset = function (mom, keepTime) {\n        if (mom.isBefore(dstAt)) {\n            mom.utcOffset(-7, keepTime);\n        } else {\n            mom.utcOffset(-8, keepTime);\n        }\n    };\n\n    m = moment('2014-11-15T00:00:00-08:00').parseZone();\n    m.startOf('y');\n    assert.equal(m.format(), '2014-01-01T00:00:00-07:00', 'startOf(\\'year\\') across -1');\n\n    m = moment('2014-11-15T00:00:00-08:00').parseZone();\n    m.startOf('M');\n    assert.equal(m.format(), '2014-11-01T00:00:00-07:00', 'startOf(\\'month\\') across -1');\n\n    m = moment('2014-11-02T09:00:00-08:00').parseZone();\n    m.startOf('d');\n    assert.equal(m.format(), '2014-11-02T00:00:00-07:00', 'startOf(\\'day\\') across -1');\n\n    // note that utc offset is -8\n    m = moment('2014-11-02T01:30:00-08:00').parseZone();\n    m.startOf('h');\n    assert.equal(m.format(), '2014-11-02T01:00:00-08:00', 'startOf(\\'hour\\') after +1');\n\n    // note that utc offset is -7\n    m = moment('2014-11-02T01:30:00-07:00').parseZone();\n    m.startOf('h');\n    assert.equal(m.format(), '2014-11-02T01:00:00-07:00', 'startOf(\\'hour\\') before +1');\n\n    moment.updateOffset = oldUpdateOffset;\n});\n\ntest('endOf millisecond and no-arg', function (assert) {\n    var m = moment();\n    assert.equal(+m, +m.clone().endOf(), 'endOf without argument should change time');\n    assert.equal(+m, +m.clone().endOf('ms'), 'endOf with ms argument should change time');\n    assert.equal(+m, +m.clone().endOf('millisecond'), 'endOf with millisecond argument should change time');\n    assert.equal(+m, +m.clone().endOf('milliseconds'), 'endOf with milliseconds argument should change time');\n});\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/test/moment/string_prototype.js",
    "content": "import { module, test } from '../qunit';\nimport moment from '../../moment';\n\nmodule('string prototype');\n\ntest('string prototype overrides call', function (assert) {\n    var prior = String.prototype.call, b;\n    String.prototype.call = function () {\n        return null;\n    };\n\n    b = moment(new Date(2011, 7, 28, 15, 25, 50, 125));\n    assert.equal(b.format('MMMM Do YYYY, h:mm a'), 'August 28th 2011, 3:25 pm');\n\n    String.prototype.call = prior;\n});\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/test/moment/to_type.js",
    "content": "import { module, test, expect } from '../qunit';\nimport moment from '../../moment';\n\nmodule('to type');\n\ntest('toObject', function (assert) {\n    var expected = {\n        years:2010,\n        months:3,\n        date:5,\n        hours:15,\n        minutes:10,\n        seconds:3,\n        milliseconds:123\n    };\n    assert.deepEqual(moment(expected).toObject(), expected, 'toObject invalid');\n});\n\ntest('toArray', function (assert) {\n    var expected = [2014, 11, 26, 11, 46, 58, 17];\n    assert.deepEqual(moment(expected).toArray(), expected, 'toArray invalid');\n});\n\ntest('toDate returns a copy of the internal date', function (assert) {\n    var m = moment();\n    var d = m.toDate();\n    m.year(0);\n    assert.notEqual(d, m.toDate());\n});\n\ntest('toJSON', function (assert) {\n    if (Date.prototype.toISOString) {\n        var expected = new Date().toISOString();\n        assert.deepEqual(moment(expected).toJSON(), expected, 'toJSON invalid');\n    } else {\n        // IE8\n        expect(0);\n    }\n});\n\ntest('toJSON works when moment is frozen', function (assert) {\n    if (Date.prototype.toISOString) {\n        var expected = new Date().toISOString();\n        var m = moment(expected);\n        if (Object.freeze != null) {\n            Object.freeze(m);\n        }\n        assert.deepEqual(m.toJSON(), expected, 'toJSON when frozen invalid');\n    } else {\n        // IE8\n        expect(0);\n    }\n});\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/test/moment/utc.js",
    "content": "import { module, test } from '../qunit';\nimport moment from '../../moment';\n\nmodule('utc');\n\ntest('utc and local', function (assert) {\n    var m = moment(Date.UTC(2011, 1, 2, 3, 4, 5, 6)), offset, expected;\n    m.utc();\n    // utc\n    assert.equal(m.date(), 2, 'the day should be correct for utc');\n    assert.equal(m.day(), 3, 'the date should be correct for utc');\n    assert.equal(m.hours(), 3, 'the hours should be correct for utc');\n\n    // local\n    m.local();\n    if (m.utcOffset() < -180) {\n        assert.equal(m.date(), 1, 'the date should be correct for local');\n        assert.equal(m.day(), 2, 'the day should be correct for local');\n    } else {\n        assert.equal(m.date(), 2, 'the date should be correct for local');\n        assert.equal(m.day(), 3, 'the day should be correct for local');\n    }\n    offset = Math.floor(m.utcOffset() / 60);\n    expected = (24 + 3 + offset) % 24;\n    assert.equal(m.hours(), expected, 'the hours (' + m.hours() + ') should be correct for local');\n    assert.equal(moment().utc().utcOffset(), 0, 'timezone in utc should always be zero');\n});\n\ntest('creating with utc and no arguments', function (assert) {\n    var startOfTest = new Date().valueOf(),\n        momentDefaultUtcTime = moment.utc().valueOf(),\n        afterMomentCreationTime = new Date().valueOf();\n\n    assert.ok(startOfTest <= momentDefaultUtcTime, 'moment UTC default time should be now, not in the past');\n    assert.ok(momentDefaultUtcTime <= afterMomentCreationTime, 'moment UTC default time should be now, not in the future');\n});\n\ntest('creating with utc and a date parameter array', function (assert) {\n    var m = moment.utc([2011, 1, 2, 3, 4, 5, 6]);\n    assert.equal(m.date(), 2, 'the day should be correct for utc array');\n    assert.equal(m.hours(), 3, 'the hours should be correct for utc array');\n\n    m = moment.utc('2011-02-02 3:04:05', 'YYYY-MM-DD HH:mm:ss');\n    assert.equal(m.date(), 2, 'the day should be correct for utc parsing format');\n    assert.equal(m.hours(), 3, 'the hours should be correct for utc parsing format');\n\n    m = moment.utc('2011-02-02T03:04:05+00:00');\n    assert.equal(m.date(), 2, 'the day should be correct for utc parsing iso');\n    assert.equal(m.hours(), 3, 'the hours should be correct for utc parsing iso');\n});\n\ntest('creating with utc without timezone', function (assert) {\n    var m = moment.utc('2012-01-02T08:20:00');\n    assert.equal(m.date(), 2, 'the day should be correct for utc parse without timezone');\n    assert.equal(m.hours(), 8, 'the hours should be correct for utc parse without timezone');\n\n    m = moment.utc('2012-01-02T08:20:00+09:00');\n    assert.equal(m.date(), 1, 'the day should be correct for utc parse with timezone');\n    assert.equal(m.hours(), 23, 'the hours should be correct for utc parse with timezone');\n});\n\ntest('cloning with utc offset', function (assert) {\n    var m = moment.utc('2012-01-02T08:20:00');\n    assert.equal(moment.utc(m)._isUTC, true, 'the local offset should be converted to UTC');\n    assert.equal(moment.utc(m.clone().utc())._isUTC, true, 'the local offset should stay in UTC');\n\n    m.utcOffset(120);\n    assert.equal(moment.utc(m)._isUTC, true, 'the explicit utc offset should stay in UTC');\n    assert.equal(moment.utc(m).utcOffset(), 0, 'the explicit utc offset should have an offset of 0');\n});\n\ntest('weekday with utc', function (assert) {\n    assert.equal(\n        moment('2013-09-15T00:00:00Z').utc().weekday(), // first minute of the day\n        moment('2013-09-15T23:59:00Z').utc().weekday(), // last minute of the day\n        'a UTC-moment\\'s .weekday() should not be affected by the local timezone'\n    );\n});\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/test/moment/utc_offset.js",
    "content": "import { module, test } from '../qunit';\nimport moment from '../../moment';\n\nmodule('utc offset');\n\ntest('setter / getter blackbox', function (assert) {\n    var m = moment([2010]);\n\n    assert.equal(m.clone().utcOffset(0).utcOffset(), 0, 'utcOffset 0');\n\n    assert.equal(m.clone().utcOffset(1).utcOffset(), 60, 'utcOffset 1 is 60');\n    assert.equal(m.clone().utcOffset(60).utcOffset(), 60, 'utcOffset 60');\n    assert.equal(m.clone().utcOffset('+01:00').utcOffset(), 60, 'utcOffset +01:00 is 60');\n    assert.equal(m.clone().utcOffset('+0100').utcOffset(), 60, 'utcOffset +0100 is 60');\n\n    assert.equal(m.clone().utcOffset(-1).utcOffset(), -60, 'utcOffset -1 is -60');\n    assert.equal(m.clone().utcOffset(-60).utcOffset(), -60, 'utcOffset -60');\n    assert.equal(m.clone().utcOffset('-01:00').utcOffset(), -60, 'utcOffset -01:00 is -60');\n    assert.equal(m.clone().utcOffset('-0100').utcOffset(), -60, 'utcOffset -0100 is -60');\n\n    assert.equal(m.clone().utcOffset(1.5).utcOffset(), 90, 'utcOffset 1.5 is 90');\n    assert.equal(m.clone().utcOffset(90).utcOffset(), 90, 'utcOffset 1.5 is 90');\n    assert.equal(m.clone().utcOffset('+01:30').utcOffset(), 90, 'utcOffset +01:30 is 90');\n    assert.equal(m.clone().utcOffset('+0130').utcOffset(), 90, 'utcOffset +0130 is 90');\n\n    assert.equal(m.clone().utcOffset(-1.5).utcOffset(), -90, 'utcOffset -1.5');\n    assert.equal(m.clone().utcOffset(-90).utcOffset(), -90, 'utcOffset -90');\n    assert.equal(m.clone().utcOffset('-01:30').utcOffset(), -90, 'utcOffset +01:30 is 90');\n    assert.equal(m.clone().utcOffset('-0130').utcOffset(), -90, 'utcOffset +0130 is 90');\n    assert.equal(m.clone().utcOffset('+00:10').utcOffset(), 10, 'utcOffset +00:10 is 10');\n    assert.equal(m.clone().utcOffset('-00:10').utcOffset(), -10, 'utcOffset +00:10 is 10');\n    assert.equal(m.clone().utcOffset('+0010').utcOffset(), 10, 'utcOffset +0010 is 10');\n    assert.equal(m.clone().utcOffset('-0010').utcOffset(), -10, 'utcOffset +0010 is 10');\n});\n\ntest('utcOffset shorthand hours -> minutes', function (assert) {\n    var i;\n    for (i = -15; i <= 15; ++i) {\n        assert.equal(moment().utcOffset(i).utcOffset(), i * 60,\n                '' + i + ' -> ' + i * 60);\n    }\n    assert.equal(moment().utcOffset(-16).utcOffset(), -16, '-16 -> -16');\n    assert.equal(moment().utcOffset(16).utcOffset(), 16, '16 -> 16');\n});\n\ntest('isLocal, isUtc, isUtcOffset', function (assert) {\n    assert.ok(moment().isLocal(), 'moment() creates objects in local time');\n    assert.ok(!moment.utc().isLocal(), 'moment.utc creates objects NOT in local time');\n    assert.ok(moment.utc().local().isLocal(), 'moment.fn.local() converts to local time');\n    assert.ok(!moment().utcOffset(5).isLocal(), 'moment.fn.utcOffset(N) puts objects NOT in local time');\n    assert.ok(moment().utcOffset(5).local().isLocal(), 'moment.fn.local() converts to local time');\n\n    assert.ok(moment.utc().isUtc(), 'moment.utc() creates objects in utc time');\n    assert.ok(moment().utcOffset(0).isUtc(), 'utcOffset(0) is equivalent to utc mode');\n    assert.ok(!moment().utcOffset(1).isUtc(), 'utcOffset(1) is NOT equivalent to utc mode');\n\n    assert.ok(!moment().isUtcOffset(), 'moment() creates objects NOT in utc-offset mode');\n    assert.ok(moment.utc().isUtcOffset(), 'moment.utc() creates objects in utc-offset mode');\n    assert.ok(moment().utcOffset(3).isUtcOffset(), 'utcOffset(N != 0) creates objects in utc-offset mode');\n    assert.ok(moment().utcOffset(0).isUtcOffset(), 'utcOffset(0) creates objects in utc-offset mode');\n});\n\ntest('isUTC', function (assert) {\n    assert.ok(moment.utc().isUTC(), 'moment.utc() creates objects in utc time');\n    assert.ok(moment().utcOffset(0).isUTC(), 'utcOffset(0) is equivalent to utc mode');\n    assert.ok(!moment().utcOffset(1).isUTC(), 'utcOffset(1) is NOT equivalent to utc mode');\n});\n\ntest('change hours when changing the utc offset', function (assert) {\n    var m = moment.utc([2000, 0, 1, 6]);\n    assert.equal(m.hour(), 6, 'UTC 6AM should be 6AM at +0000');\n\n    // sanity check\n    m.utcOffset(0);\n    assert.equal(m.hour(), 6, 'UTC 6AM should be 6AM at +0000');\n\n    m.utcOffset(-60);\n    assert.equal(m.hour(), 5, 'UTC 6AM should be 5AM at -0100');\n\n    m.utcOffset(60);\n    assert.equal(m.hour(), 7, 'UTC 6AM should be 7AM at +0100');\n});\n\ntest('change minutes when changing the utc offset', function (assert) {\n    var m = moment.utc([2000, 0, 1, 6, 31]);\n\n    m.utcOffset(0);\n    assert.equal(m.format('HH:mm'), '06:31', 'UTC 6:31AM should be 6:31AM at +0000');\n\n    m.utcOffset(-30);\n    assert.equal(m.format('HH:mm'), '06:01', 'UTC 6:31AM should be 6:01AM at -0030');\n\n    m.utcOffset(30);\n    assert.equal(m.format('HH:mm'), '07:01', 'UTC 6:31AM should be 7:01AM at +0030');\n\n    m.utcOffset(-1380);\n    assert.equal(m.format('HH:mm'), '07:31', 'UTC 6:31AM should be 7:31AM at +1380');\n});\n\ntest('distance from the unix epoch', function (assert) {\n    var zoneA = moment(),\n        zoneB = moment(zoneA),\n        zoneC = moment(zoneA),\n        zoneD = moment(zoneA),\n        zoneE = moment(zoneA);\n\n    zoneB.utc();\n    assert.equal(+zoneA, +zoneB, 'moment should equal moment.utc');\n\n    zoneC.utcOffset(60);\n    assert.equal(+zoneA, +zoneC, 'moment should equal moment.utcOffset(60)');\n\n    zoneD.utcOffset(-480);\n    assert.equal(+zoneA, +zoneD,\n            'moment should equal moment.utcOffset(-480)');\n\n    zoneE.utcOffset(-1000);\n    assert.equal(+zoneA, +zoneE,\n            'moment should equal moment.utcOffset(-1000)');\n});\n\ntest('update offset after changing any values', function (assert) {\n    var oldOffset = moment.updateOffset,\n        m = moment.utc([2000, 6, 1]);\n\n    moment.updateOffset = function (mom, keepTime) {\n        if (mom.__doChange) {\n            if (+mom > 962409600000) {\n                mom.utcOffset(-120, keepTime);\n            } else {\n                mom.utcOffset(-60, keepTime);\n            }\n        }\n    };\n\n    assert.equal(m.format('ZZ'), '+0000', 'should be at +0000');\n    assert.equal(m.format('HH:mm'), '00:00', 'should start 12AM at +0000 timezone');\n\n    m.__doChange = true;\n    m.add(1, 'h');\n\n    assert.equal(m.format('ZZ'), '-0200', 'should be at -0200');\n    assert.equal(m.format('HH:mm'), '23:00', '1AM at +0000 should be 11PM at -0200 timezone');\n\n    m.subtract(1, 'h');\n\n    assert.equal(m.format('ZZ'), '-0100', 'should be at -0100');\n    assert.equal(m.format('HH:mm'), '23:00', '12AM at +0000 should be 11PM at -0100 timezone');\n\n    moment.updateOffset = oldOffset;\n});\n\n//////////////////\ntest('getters and setters', function (assert) {\n    var a = moment([2011, 5, 20]);\n\n    assert.equal(a.clone().utcOffset(-120).year(2012).year(), 2012, 'should get and set year correctly');\n    assert.equal(a.clone().utcOffset(-120).month(1).month(), 1, 'should get and set month correctly');\n    assert.equal(a.clone().utcOffset(-120).date(2).date(), 2, 'should get and set date correctly');\n    assert.equal(a.clone().utcOffset(-120).day(1).day(), 1, 'should get and set day correctly');\n    assert.equal(a.clone().utcOffset(-120).hour(1).hour(), 1, 'should get and set hour correctly');\n    assert.equal(a.clone().utcOffset(-120).minute(1).minute(), 1, 'should get and set minute correctly');\n});\n\ntest('getters', function (assert) {\n    var a = moment.utc([2012, 0, 1, 0, 0, 0]);\n\n    assert.equal(a.clone().utcOffset(-120).year(),  2011, 'should get year correctly');\n    assert.equal(a.clone().utcOffset(-120).month(),   11, 'should get month correctly');\n    assert.equal(a.clone().utcOffset(-120).date(),    31, 'should get date correctly');\n    assert.equal(a.clone().utcOffset(-120).hour(),    22, 'should get hour correctly');\n    assert.equal(a.clone().utcOffset(-120).minute(),   0, 'should get minute correctly');\n\n    assert.equal(a.clone().utcOffset(120).year(),  2012, 'should get year correctly');\n    assert.equal(a.clone().utcOffset(120).month(),    0, 'should get month correctly');\n    assert.equal(a.clone().utcOffset(120).date(),     1, 'should get date correctly');\n    assert.equal(a.clone().utcOffset(120).hour(),     2, 'should get hour correctly');\n    assert.equal(a.clone().utcOffset(120).minute(),   0, 'should get minute correctly');\n\n    assert.equal(a.clone().utcOffset(90).year(),  2012, 'should get year correctly');\n    assert.equal(a.clone().utcOffset(90).month(),    0, 'should get month correctly');\n    assert.equal(a.clone().utcOffset(90).date(),     1, 'should get date correctly');\n    assert.equal(a.clone().utcOffset(90).hour(),     1, 'should get hour correctly');\n    assert.equal(a.clone().utcOffset(90).minute(),  30, 'should get minute correctly');\n});\n\ntest('from', function (assert) {\n    var zoneA = moment(),\n        zoneB = moment(zoneA).utcOffset(-720),\n        zoneC = moment(zoneA).utcOffset(-360),\n        zoneD = moment(zoneA).utcOffset(690),\n        other = moment(zoneA).add(35, 'm');\n\n    assert.equal(zoneA.from(other), zoneB.from(other), 'moment#from should be the same in all zones');\n    assert.equal(zoneA.from(other), zoneC.from(other), 'moment#from should be the same in all zones');\n    assert.equal(zoneA.from(other), zoneD.from(other), 'moment#from should be the same in all zones');\n});\n\ntest('diff', function (assert) {\n    var zoneA = moment(),\n        zoneB = moment(zoneA).utcOffset(-720),\n        zoneC = moment(zoneA).utcOffset(-360),\n        zoneD = moment(zoneA).utcOffset(690),\n        other = moment(zoneA).add(35, 'm');\n\n    assert.equal(zoneA.diff(other), zoneB.diff(other), 'moment#diff should be the same in all zones');\n    assert.equal(zoneA.diff(other), zoneC.diff(other), 'moment#diff should be the same in all zones');\n    assert.equal(zoneA.diff(other), zoneD.diff(other), 'moment#diff should be the same in all zones');\n\n    assert.equal(zoneA.diff(other, 'minute', true), zoneB.diff(other, 'minute', true), 'moment#diff should be the same in all zones');\n    assert.equal(zoneA.diff(other, 'minute', true), zoneC.diff(other, 'minute', true), 'moment#diff should be the same in all zones');\n    assert.equal(zoneA.diff(other, 'minute', true), zoneD.diff(other, 'minute', true), 'moment#diff should be the same in all zones');\n\n    assert.equal(zoneA.diff(other, 'hour', true), zoneB.diff(other, 'hour', true), 'moment#diff should be the same in all zones');\n    assert.equal(zoneA.diff(other, 'hour', true), zoneC.diff(other, 'hour', true), 'moment#diff should be the same in all zones');\n    assert.equal(zoneA.diff(other, 'hour', true), zoneD.diff(other, 'hour', true), 'moment#diff should be the same in all zones');\n});\n\ntest('unix offset and timestamp', function (assert) {\n    var zoneA = moment(),\n        zoneB = moment(zoneA).utcOffset(-720),\n        zoneC = moment(zoneA).utcOffset(-360),\n        zoneD = moment(zoneA).utcOffset(690);\n\n    assert.equal(zoneA.unix(), zoneB.unix(), 'moment#unix should be the same in all zones');\n    assert.equal(zoneA.unix(), zoneC.unix(), 'moment#unix should be the same in all zones');\n    assert.equal(zoneA.unix(), zoneD.unix(), 'moment#unix should be the same in all zones');\n\n    assert.equal(+zoneA, +zoneB, 'moment#valueOf should be the same in all zones');\n    assert.equal(+zoneA, +zoneC, 'moment#valueOf should be the same in all zones');\n    assert.equal(+zoneA, +zoneD, 'moment#valueOf should be the same in all zones');\n});\n\ntest('cloning', function (assert) {\n    assert.equal(moment().utcOffset(-120).clone().utcOffset(), -120,\n            'explicit cloning should retain the offset');\n    assert.equal(moment().utcOffset(120).clone().utcOffset(), 120,\n            'explicit cloning should retain the offset');\n    assert.equal(moment(moment().utcOffset(-120)).utcOffset(), -120,\n            'implicit cloning should retain the offset');\n    assert.equal(moment(moment().utcOffset(120)).utcOffset(), 120,\n            'implicit cloning should retain the offset');\n});\n\ntest('start of / end of', function (assert) {\n    var a = moment.utc([2010, 1, 2, 0, 0, 0]).utcOffset(-450);\n\n    assert.equal(a.clone().startOf('day').hour(), 0,\n            'start of day should work on moments with utc offset');\n    assert.equal(a.clone().startOf('day').minute(), 0,\n            'start of day should work on moments with utc offset');\n    assert.equal(a.clone().startOf('hour').minute(), 0,\n            'start of hour should work on moments with utc offset');\n\n    assert.equal(a.clone().endOf('day').hour(), 23,\n            'end of day should work on moments with utc offset');\n    assert.equal(a.clone().endOf('day').minute(), 59,\n            'end of day should work on moments with utc offset');\n    assert.equal(a.clone().endOf('hour').minute(), 59,\n            'end of hour should work on moments with utc offset');\n});\n\ntest('reset offset with moment#utc', function (assert) {\n    var a = moment.utc([2012]).utcOffset(-480);\n\n    assert.equal(a.clone().hour(),      16, 'different utc offset should have different hour');\n    assert.equal(a.clone().utc().hour(), 0, 'calling moment#utc should reset the offset');\n});\n\ntest('reset offset with moment#local', function (assert) {\n    var a = moment([2012]).utcOffset(-480);\n\n    assert.equal(a.clone().local().hour(), 0, 'calling moment#local should reset the offset');\n});\n\ntest('toDate', function (assert) {\n    var zoneA = new Date(),\n        zoneB = moment(zoneA).utcOffset(-720).toDate(),\n        zoneC = moment(zoneA).utcOffset(-360).toDate(),\n        zoneD = moment(zoneA).utcOffset(690).toDate();\n\n    assert.equal(+zoneA, +zoneB, 'moment#toDate should output a date with the right unix timestamp');\n    assert.equal(+zoneA, +zoneC, 'moment#toDate should output a date with the right unix timestamp');\n    assert.equal(+zoneA, +zoneD, 'moment#toDate should output a date with the right unix timestamp');\n});\n\ntest('same / before / after', function (assert) {\n    var zoneA = moment().utc(),\n        zoneB = moment(zoneA).utcOffset(-120),\n        zoneC = moment(zoneA).utcOffset(120);\n\n    assert.ok(zoneA.isSame(zoneB), 'two moments with different offsets should be the same');\n    assert.ok(zoneA.isSame(zoneC), 'two moments with different offsets should be the same');\n\n    assert.ok(zoneA.isSame(zoneB, 'hour'), 'two moments with different offsets should be the same hour');\n    assert.ok(zoneA.isSame(zoneC, 'hour'), 'two moments with different offsets should be the same hour');\n\n    zoneA.add(1, 'hour');\n\n    assert.ok(zoneA.isAfter(zoneB), 'isAfter should work with two moments with different offsets');\n    assert.ok(zoneA.isAfter(zoneC), 'isAfter should work with two moments with different offsets');\n\n    assert.ok(zoneA.isAfter(zoneB, 'hour'), 'isAfter:hour should work with two moments with different offsets');\n    assert.ok(zoneA.isAfter(zoneC, 'hour'), 'isAfter:hour should work with two moments with different offsets');\n\n    zoneA.subtract(2, 'hour');\n\n    assert.ok(zoneA.isBefore(zoneB), 'isBefore should work with two moments with different offsets');\n    assert.ok(zoneA.isBefore(zoneC), 'isBefore should work with two moments with different offsets');\n\n    assert.ok(zoneA.isBefore(zoneB, 'hour'), 'isBefore:hour should work with two moments with different offsets');\n    assert.ok(zoneA.isBefore(zoneC, 'hour'), 'isBefore:hour should work with two moments with different offsets');\n});\n\ntest('add / subtract over dst', function (assert) {\n    var oldOffset = moment.updateOffset,\n        m = moment.utc([2000, 2, 31, 3]);\n\n    moment.updateOffset = function (mom, keepTime) {\n        if (mom.clone().utc().month() > 2) {\n            mom.utcOffset(60, keepTime);\n        } else {\n            mom.utcOffset(0, keepTime);\n        }\n    };\n\n    assert.equal(m.hour(), 3, 'should start at 00:00');\n\n    m.add(24, 'hour');\n\n    assert.equal(m.hour(), 4, 'adding 24 hours should disregard dst');\n\n    m.subtract(24, 'hour');\n\n    assert.equal(m.hour(), 3, 'subtracting 24 hours should disregard dst');\n\n    m.add(1, 'day');\n\n    assert.equal(m.hour(), 3, 'adding 1 day should have the same hour');\n\n    m.subtract(1, 'day');\n\n    assert.equal(m.hour(), 3, 'subtracting 1 day should have the same hour');\n\n    m.add(1, 'month');\n\n    assert.equal(m.hour(), 3, 'adding 1 month should have the same hour');\n\n    m.subtract(1, 'month');\n\n    assert.equal(m.hour(), 3, 'subtracting 1 month should have the same hour');\n\n    moment.updateOffset = oldOffset;\n});\n\ntest('isDST', function (assert) {\n    var oldOffset = moment.updateOffset;\n\n    moment.updateOffset = function (mom, keepTime) {\n        if (mom.month() > 2 && mom.month() < 9) {\n            mom.utcOffset(60, keepTime);\n        } else {\n            mom.utcOffset(0, keepTime);\n        }\n    };\n\n    assert.ok(!moment().month(0).isDST(),  'Jan should not be summer dst');\n    assert.ok(moment().month(6).isDST(),   'Jul should be summer dst');\n    assert.ok(!moment().month(11).isDST(), 'Dec should not be summer dst');\n\n    moment.updateOffset = function (mom) {\n        if (mom.month() > 2 && mom.month() < 9) {\n            mom.utcOffset(0);\n        } else {\n            mom.utcOffset(60);\n        }\n    };\n\n    assert.ok(moment().month(0).isDST(),  'Jan should be winter dst');\n    assert.ok(!moment().month(6).isDST(), 'Jul should not be winter dst');\n    assert.ok(moment().month(11).isDST(), 'Dec should be winter dst');\n\n    moment.updateOffset = oldOffset;\n});\n\ntest('zone names', function (assert) {\n    assert.equal(moment().zoneAbbr(),   '', 'Local zone abbr should be empty');\n    assert.equal(moment().format('z'),  '', 'Local zone formatted abbr should be empty');\n    assert.equal(moment().zoneName(),   '', 'Local zone name should be empty');\n    assert.equal(moment().format('zz'), '', 'Local zone formatted name should be empty');\n\n    assert.equal(moment.utc().zoneAbbr(),   'UTC', 'UTC zone abbr should be UTC');\n    assert.equal(moment.utc().format('z'),  'UTC', 'UTC zone formatted abbr should be UTC');\n    assert.equal(moment.utc().zoneName(),   'Coordinated Universal Time', 'UTC zone abbr should be Coordinated Universal Time');\n    assert.equal(moment.utc().format('zz'), 'Coordinated Universal Time', 'UTC zone formatted abbr should be Coordinated Universal Time');\n});\n\ntest('hours alignment with UTC', function (assert) {\n    assert.equal(moment().utcOffset(-120).hasAlignedHourOffset(), true);\n    assert.equal(moment().utcOffset(180).hasAlignedHourOffset(), true);\n    assert.equal(moment().utcOffset(-90).hasAlignedHourOffset(), false);\n    assert.equal(moment().utcOffset(90).hasAlignedHourOffset(), false);\n});\n\ntest('hours alignment with other zone', function (assert) {\n    var m = moment().utcOffset(-120);\n\n    assert.equal(m.hasAlignedHourOffset(moment().utcOffset(-180)), true);\n    assert.equal(m.hasAlignedHourOffset(moment().utcOffset(180)), true);\n    assert.equal(m.hasAlignedHourOffset(moment().utcOffset(-90)), false);\n    assert.equal(m.hasAlignedHourOffset(moment().utcOffset(90)), false);\n\n    m = moment().utcOffset(-90);\n\n    assert.equal(m.hasAlignedHourOffset(moment().utcOffset(-180)), false);\n    assert.equal(m.hasAlignedHourOffset(moment().utcOffset(180)), false);\n    assert.equal(m.hasAlignedHourOffset(moment().utcOffset(-30)), true);\n    assert.equal(m.hasAlignedHourOffset(moment().utcOffset(30)), true);\n\n    m = moment().utcOffset(60);\n\n    assert.equal(m.hasAlignedHourOffset(moment().utcOffset(-180)), true);\n    assert.equal(m.hasAlignedHourOffset(moment().utcOffset(180)), true);\n    assert.equal(m.hasAlignedHourOffset(moment().utcOffset(-90)), false);\n    assert.equal(m.hasAlignedHourOffset(moment().utcOffset(90)), false);\n\n    m = moment().utcOffset(-25);\n\n    assert.equal(m.hasAlignedHourOffset(moment().utcOffset(35)), true);\n    assert.equal(m.hasAlignedHourOffset(moment().utcOffset(-85)), true);\n\n    assert.equal(m.hasAlignedHourOffset(moment().utcOffset(-35)), false);\n    assert.equal(m.hasAlignedHourOffset(moment().utcOffset(85)), false);\n});\n\ntest('parse zone', function (assert) {\n    var m = moment('2013-01-01T00:00:00-13:00').parseZone();\n    assert.equal(m.utcOffset(), -13 * 60);\n    assert.equal(m.hours(), 0);\n});\n\ntest('parse UTC zone', function (assert) {\n    var m = moment('2013-01-01T05:00:00+00:00').parseZone();\n    assert.equal(m.utcOffset(), 0);\n    assert.equal(m.hours(), 5);\n});\n\ntest('parse zone static', function (assert) {\n    var m = moment.parseZone('2013-01-01T00:00:00-13:00');\n    assert.equal(m.utcOffset(), -13 * 60);\n    assert.equal(m.hours(), 0);\n});\n\ntest('parse zone with more arguments', function (assert) {\n    var m;\n    m = moment.parseZone('2013 01 01 05 -13:00', 'YYYY MM DD HH ZZ');\n    assert.equal(m.format(), '2013-01-01T05:00:00-13:00', 'accept input and format');\n    m = moment.parseZone('2013-01-01-13:00', 'YYYY MM DD ZZ', true);\n    assert.equal(m.isValid(), false, 'accept input, format and strict flag');\n    m = moment.parseZone('2013-01-01-13:00', ['DD MM YYYY ZZ', 'YYYY MM DD ZZ']);\n    assert.equal(m.format(), '2013-01-01T00:00:00-13:00', 'accept input and array of formats');\n});\n\ntest('parse zone with a timezone from the format string', function (assert) {\n    var m = moment('11-12-2013 -0400 +1100', 'DD-MM-YYYY ZZ #####').parseZone();\n\n    assert.equal(m.utcOffset(), -4 * 60);\n});\n\ntest('parse zone without a timezone included in the format string', function (assert) {\n    var m = moment('11-12-2013 -0400 +1100', 'DD-MM-YYYY').parseZone();\n\n    assert.equal(m.utcOffset(), 11 * 60);\n});\n\ntest('timezone format', function (assert) {\n    assert.equal(moment().utcOffset(60).format('ZZ'), '+0100', '-60 -> +0100');\n    assert.equal(moment().utcOffset(90).format('ZZ'), '+0130', '-90 -> +0130');\n    assert.equal(moment().utcOffset(120).format('ZZ'), '+0200', '-120 -> +0200');\n\n    assert.equal(moment().utcOffset(-60).format('ZZ'), '-0100', '+60 -> -0100');\n    assert.equal(moment().utcOffset(-90).format('ZZ'), '-0130', '+90 -> -0130');\n    assert.equal(moment().utcOffset(-120).format('ZZ'), '-0200', '+120 -> -0200');\n});\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/test/moment/week_year.js",
    "content": "import { module, test } from '../qunit';\nimport moment from '../../moment';\n\nmodule('week year');\n\ntest('iso week year', function (assert) {\n    // Some examples taken from https://en.wikipedia.org/wiki/ISO_week\n    assert.equal(moment([2005, 0, 1]).isoWeekYear(), 2004);\n    assert.equal(moment([2005, 0, 2]).isoWeekYear(), 2004);\n    assert.equal(moment([2005, 0, 3]).isoWeekYear(), 2005);\n    assert.equal(moment([2005, 11, 31]).isoWeekYear(), 2005);\n    assert.equal(moment([2006, 0, 1]).isoWeekYear(), 2005);\n    assert.equal(moment([2006, 0, 2]).isoWeekYear(), 2006);\n    assert.equal(moment([2007, 0, 1]).isoWeekYear(), 2007);\n    assert.equal(moment([2007, 11, 30]).isoWeekYear(), 2007);\n    assert.equal(moment([2007, 11, 31]).isoWeekYear(), 2008);\n    assert.equal(moment([2008, 0, 1]).isoWeekYear(), 2008);\n    assert.equal(moment([2008, 11, 28]).isoWeekYear(), 2008);\n    assert.equal(moment([2008, 11, 29]).isoWeekYear(), 2009);\n    assert.equal(moment([2008, 11, 30]).isoWeekYear(), 2009);\n    assert.equal(moment([2008, 11, 31]).isoWeekYear(), 2009);\n    assert.equal(moment([2009, 0, 1]).isoWeekYear(), 2009);\n    assert.equal(moment([2010, 0, 1]).isoWeekYear(), 2009);\n    assert.equal(moment([2010, 0, 2]).isoWeekYear(), 2009);\n    assert.equal(moment([2010, 0, 3]).isoWeekYear(), 2009);\n    assert.equal(moment([2010, 0, 4]).isoWeekYear(), 2010);\n});\n\ntest('week year', function (assert) {\n    // Some examples taken from https://en.wikipedia.org/wiki/ISO_week\n    moment.locale('dow: 1,doy: 4', {week: {dow: 1, doy: 4}}); // like iso\n    assert.equal(moment([2005, 0, 1]).weekYear(), 2004);\n    assert.equal(moment([2005, 0, 2]).weekYear(), 2004);\n    assert.equal(moment([2005, 0, 3]).weekYear(), 2005);\n    assert.equal(moment([2005, 11, 31]).weekYear(), 2005);\n    assert.equal(moment([2006, 0, 1]).weekYear(), 2005);\n    assert.equal(moment([2006, 0, 2]).weekYear(), 2006);\n    assert.equal(moment([2007, 0, 1]).weekYear(), 2007);\n    assert.equal(moment([2007, 11, 30]).weekYear(), 2007);\n    assert.equal(moment([2007, 11, 31]).weekYear(), 2008);\n    assert.equal(moment([2008, 0, 1]).weekYear(), 2008);\n    assert.equal(moment([2008, 11, 28]).weekYear(), 2008);\n    assert.equal(moment([2008, 11, 29]).weekYear(), 2009);\n    assert.equal(moment([2008, 11, 30]).weekYear(), 2009);\n    assert.equal(moment([2008, 11, 31]).weekYear(), 2009);\n    assert.equal(moment([2009, 0, 1]).weekYear(), 2009);\n    assert.equal(moment([2010, 0, 1]).weekYear(), 2009);\n    assert.equal(moment([2010, 0, 2]).weekYear(), 2009);\n    assert.equal(moment([2010, 0, 3]).weekYear(), 2009);\n    assert.equal(moment([2010, 0, 4]).weekYear(), 2010);\n\n    moment.locale('dow: 1,doy: 7', {week: {dow: 1, doy: 7}});\n    assert.equal(moment([2004, 11, 26]).weekYear(), 2004);\n    assert.equal(moment([2004, 11, 27]).weekYear(), 2005);\n    assert.equal(moment([2005, 11, 25]).weekYear(), 2005);\n    assert.equal(moment([2005, 11, 26]).weekYear(), 2006);\n    assert.equal(moment([2006, 11, 31]).weekYear(), 2006);\n    assert.equal(moment([2007,  0,  1]).weekYear(), 2007);\n    assert.equal(moment([2007, 11, 30]).weekYear(), 2007);\n    assert.equal(moment([2007, 11, 31]).weekYear(), 2008);\n    assert.equal(moment([2008, 11, 28]).weekYear(), 2008);\n    assert.equal(moment([2008, 11, 29]).weekYear(), 2009);\n    assert.equal(moment([2009, 11, 27]).weekYear(), 2009);\n    assert.equal(moment([2009, 11, 28]).weekYear(), 2010);\n});\n\n// Verifies that the week number, week day computation is correct for all dow, doy combinations\ntest('week year roundtrip', function (assert) {\n    var dow, doy, wd, m, localeName;\n    for (dow = 0; dow < 7; ++dow) {\n        for (doy = dow; doy < dow + 7; ++doy) {\n            for (wd = 0; wd < 7; ++wd) {\n                localeName = 'dow: ' + dow + ', doy: ' + doy;\n                moment.locale(localeName, {week: {dow: dow, doy: doy}});\n                // We use the 10th week as the 1st one can spill to the previous year\n                m = moment('2015 10 ' + wd, 'gggg w d', true);\n                assert.equal(m.format('gggg w d'), '2015 10 ' + wd, 'dow: ' + dow + ' doy: ' + doy + ' wd: ' + wd);\n                m = moment('2015 10 ' + wd, 'gggg w e', true);\n                assert.equal(m.format('gggg w e'), '2015 10 ' + wd, 'dow: ' + dow + ' doy: ' + doy + ' wd: ' + wd);\n                moment.defineLocale(localeName, null);\n            }\n        }\n    }\n});\n\ntest('week numbers 2012/2013', function (assert) {\n    moment.locale('dow: 6, doy: 12', {week: {dow: 6, doy: 12}});\n    assert.equal(52, moment('2012-12-28', 'YYYY-MM-DD').week(), '2012-12-28 is week 52'); // 51 -- should be 52?\n    assert.equal(1, moment('2012-12-29', 'YYYY-MM-DD').week(), '2012-12-29 is week 1'); // 52 -- should be 1\n    assert.equal(1, moment('2013-01-01', 'YYYY-MM-DD').week(), '2013-01-01 is week 1'); // 52 -- should be 1\n    assert.equal(2, moment('2013-01-08', 'YYYY-MM-DD').week(), '2013-01-08 is week 2'); // 53 -- should be 2\n    assert.equal(2, moment('2013-01-11', 'YYYY-MM-DD').week(), '2013-01-11 is week 2'); // 53 -- should be 2\n    assert.equal(3, moment('2013-01-12', 'YYYY-MM-DD').week(), '2013-01-12 is week 3'); // 1 -- should be 3\n    assert.equal(52, moment('2012-01-01', 'YYYY-MM-DD').weeksInYear(), 'weeks in 2012 are 52'); // 52\n    moment.defineLocale('dow: 6, doy: 12', null);\n});\n\ntest('weeks numbers dow:1 doy:4', function (assert) {\n    moment.locale('dow: 1, doy: 4', {week: {dow: 1, doy: 4}});\n    assert.equal(moment([2012, 0, 1]).week(), 52, 'Jan  1 2012 should be week 52');\n    assert.equal(moment([2012, 0, 2]).week(),  1, 'Jan  2 2012 should be week 1');\n    assert.equal(moment([2012, 0, 8]).week(),  1, 'Jan  8 2012 should be week 1');\n    assert.equal(moment([2012, 0, 9]).week(),  2, 'Jan  9 2012 should be week 2');\n    assert.equal(moment([2012, 0, 15]).week(), 2, 'Jan 15 2012 should be week 2');\n    assert.equal(moment([2007, 0, 1]).week(),  1, 'Jan  1 2007 should be week 1');\n    assert.equal(moment([2007, 0, 7]).week(),  1, 'Jan  7 2007 should be week 1');\n    assert.equal(moment([2007, 0, 8]).week(),  2, 'Jan  8 2007 should be week 2');\n    assert.equal(moment([2007, 0, 14]).week(), 2, 'Jan 14 2007 should be week 2');\n    assert.equal(moment([2007, 0, 15]).week(), 3, 'Jan 15 2007 should be week 3');\n    assert.equal(moment([2007, 11, 31]).week(), 1, 'Dec 31 2007 should be week 1');\n    assert.equal(moment([2008,  0,  1]).week(), 1, 'Jan  1 2008 should be week 1');\n    assert.equal(moment([2008,  0,  6]).week(), 1, 'Jan  6 2008 should be week 1');\n    assert.equal(moment([2008,  0,  7]).week(), 2, 'Jan  7 2008 should be week 2');\n    assert.equal(moment([2008,  0, 13]).week(), 2, 'Jan 13 2008 should be week 2');\n    assert.equal(moment([2008,  0, 14]).week(), 3, 'Jan 14 2008 should be week 3');\n    assert.equal(moment([2002, 11, 30]).week(), 1, 'Dec 30 2002 should be week 1');\n    assert.equal(moment([2003,  0,  1]).week(), 1, 'Jan  1 2003 should be week 1');\n    assert.equal(moment([2003,  0,  5]).week(), 1, 'Jan  5 2003 should be week 1');\n    assert.equal(moment([2003,  0,  6]).week(), 2, 'Jan  6 2003 should be week 2');\n    assert.equal(moment([2003,  0, 12]).week(), 2, 'Jan 12 2003 should be week 2');\n    assert.equal(moment([2003,  0, 13]).week(), 3, 'Jan 13 2003 should be week 3');\n    assert.equal(moment([2008, 11, 29]).week(), 1, 'Dec 29 2008 should be week 1');\n    assert.equal(moment([2009,  0,  1]).week(), 1, 'Jan  1 2009 should be week 1');\n    assert.equal(moment([2009,  0,  4]).week(), 1, 'Jan  4 2009 should be week 1');\n    assert.equal(moment([2009,  0,  5]).week(), 2, 'Jan  5 2009 should be week 2');\n    assert.equal(moment([2009,  0, 11]).week(), 2, 'Jan 11 2009 should be week 2');\n    assert.equal(moment([2009,  0, 13]).week(), 3, 'Jan 12 2009 should be week 3');\n    assert.equal(moment([2009, 11, 28]).week(), 53, 'Dec 28 2009 should be week 53');\n    assert.equal(moment([2010,  0,  1]).week(), 53, 'Jan  1 2010 should be week 53');\n    assert.equal(moment([2010,  0,  3]).week(), 53, 'Jan  3 2010 should be week 53');\n    assert.equal(moment([2010,  0,  4]).week(),  1, 'Jan  4 2010 should be week 1');\n    assert.equal(moment([2010,  0, 10]).week(),  1, 'Jan 10 2010 should be week 1');\n    assert.equal(moment([2010,  0, 11]).week(),  2, 'Jan 11 2010 should be week 2');\n    assert.equal(moment([2010, 11, 27]).week(), 52, 'Dec 27 2010 should be week 52');\n    assert.equal(moment([2011,  0,  1]).week(), 52, 'Jan  1 2011 should be week 52');\n    assert.equal(moment([2011,  0,  2]).week(), 52, 'Jan  2 2011 should be week 52');\n    assert.equal(moment([2011,  0,  3]).week(),  1, 'Jan  3 2011 should be week 1');\n    assert.equal(moment([2011,  0,  9]).week(),  1, 'Jan  9 2011 should be week 1');\n    assert.equal(moment([2011,  0, 10]).week(),  2, 'Jan 10 2011 should be week 2');\n    moment.defineLocale('dow: 1, doy: 4', null);\n});\n\ntest('weeks numbers dow:6 doy:12', function (assert) {\n    moment.locale('dow: 6, doy: 12', {week: {dow: 6, doy: 12}});\n    assert.equal(moment([2011, 11, 31]).week(), 1, 'Dec 31 2011 should be week 1');\n    assert.equal(moment([2012,  0,  6]).week(), 1, 'Jan  6 2012 should be week 1');\n    assert.equal(moment([2012,  0,  7]).week(), 2, 'Jan  7 2012 should be week 2');\n    assert.equal(moment([2012,  0, 13]).week(), 2, 'Jan 13 2012 should be week 2');\n    assert.equal(moment([2012,  0, 14]).week(), 3, 'Jan 14 2012 should be week 3');\n    assert.equal(moment([2006, 11, 30]).week(), 1, 'Dec 30 2006 should be week 1');\n    assert.equal(moment([2007,  0,  5]).week(), 1, 'Jan  5 2007 should be week 1');\n    assert.equal(moment([2007,  0,  6]).week(), 2, 'Jan  6 2007 should be week 2');\n    assert.equal(moment([2007,  0, 12]).week(), 2, 'Jan 12 2007 should be week 2');\n    assert.equal(moment([2007,  0, 13]).week(), 3, 'Jan 13 2007 should be week 3');\n    assert.equal(moment([2007, 11, 29]).week(), 1, 'Dec 29 2007 should be week 1');\n    assert.equal(moment([2008,  0,  1]).week(), 1, 'Jan  1 2008 should be week 1');\n    assert.equal(moment([2008,  0,  4]).week(), 1, 'Jan  4 2008 should be week 1');\n    assert.equal(moment([2008,  0,  5]).week(), 2, 'Jan  5 2008 should be week 2');\n    assert.equal(moment([2008,  0, 11]).week(), 2, 'Jan 11 2008 should be week 2');\n    assert.equal(moment([2008,  0, 12]).week(), 3, 'Jan 12 2008 should be week 3');\n    assert.equal(moment([2002, 11, 28]).week(), 1, 'Dec 28 2002 should be week 1');\n    assert.equal(moment([2003,  0,  1]).week(), 1, 'Jan  1 2003 should be week 1');\n    assert.equal(moment([2003,  0,  3]).week(), 1, 'Jan  3 2003 should be week 1');\n    assert.equal(moment([2003,  0,  4]).week(), 2, 'Jan  4 2003 should be week 2');\n    assert.equal(moment([2003,  0, 10]).week(), 2, 'Jan 10 2003 should be week 2');\n    assert.equal(moment([2003,  0, 11]).week(), 3, 'Jan 11 2003 should be week 3');\n    assert.equal(moment([2008, 11, 27]).week(), 1, 'Dec 27 2008 should be week 1');\n    assert.equal(moment([2009,  0,  1]).week(), 1, 'Jan  1 2009 should be week 1');\n    assert.equal(moment([2009,  0,  2]).week(), 1, 'Jan  2 2009 should be week 1');\n    assert.equal(moment([2009,  0,  3]).week(), 2, 'Jan  3 2009 should be week 2');\n    assert.equal(moment([2009,  0,  9]).week(), 2, 'Jan  9 2009 should be week 2');\n    assert.equal(moment([2009,  0, 10]).week(), 3, 'Jan 10 2009 should be week 3');\n    assert.equal(moment([2009, 11, 26]).week(), 1, 'Dec 26 2009 should be week 1');\n    assert.equal(moment([2010,  0,  1]).week(), 1, 'Jan  1 2010 should be week 1');\n    assert.equal(moment([2010,  0,  2]).week(), 2, 'Jan  2 2010 should be week 2');\n    assert.equal(moment([2010,  0,  8]).week(), 2, 'Jan  8 2010 should be week 2');\n    assert.equal(moment([2010,  0,  9]).week(), 3, 'Jan  9 2010 should be week 3');\n    assert.equal(moment([2011, 0,  1]).week(), 1, 'Jan  1 2011 should be week 1');\n    assert.equal(moment([2011, 0,  7]).week(), 1, 'Jan  7 2011 should be week 1');\n    assert.equal(moment([2011, 0,  8]).week(), 2, 'Jan  8 2011 should be week 2');\n    assert.equal(moment([2011, 0, 14]).week(), 2, 'Jan 14 2011 should be week 2');\n    assert.equal(moment([2011, 0, 15]).week(), 3, 'Jan 15 2011 should be week 3');\n    moment.defineLocale('dow: 6, doy: 12', null);\n});\n\ntest('weeks numbers dow:1 doy:7', function (assert) {\n    moment.locale('dow: 1, doy: 7', {week: {dow: 1, doy: 7}});\n    assert.equal(moment([2011, 11, 26]).week(), 1, 'Dec 26 2011 should be week 1');\n    assert.equal(moment([2012,  0,  1]).week(), 1, 'Jan  1 2012 should be week 1');\n    assert.equal(moment([2012,  0,  2]).week(), 2, 'Jan  2 2012 should be week 2');\n    assert.equal(moment([2012,  0,  8]).week(), 2, 'Jan  8 2012 should be week 2');\n    assert.equal(moment([2012,  0,  9]).week(), 3, 'Jan  9 2012 should be week 3');\n    assert.equal(moment([2007, 0, 1]).week(),  1, 'Jan  1 2007 should be week 1');\n    assert.equal(moment([2007, 0, 7]).week(),  1, 'Jan  7 2007 should be week 1');\n    assert.equal(moment([2007, 0, 8]).week(),  2, 'Jan  8 2007 should be week 2');\n    assert.equal(moment([2007, 0, 14]).week(), 2, 'Jan 14 2007 should be week 2');\n    assert.equal(moment([2007, 0, 15]).week(), 3, 'Jan 15 2007 should be week 3');\n    assert.equal(moment([2007, 11, 31]).week(), 1, 'Dec 31 2007 should be week 1');\n    assert.equal(moment([2008,  0,  1]).week(), 1, 'Jan  1 2008 should be week 1');\n    assert.equal(moment([2008,  0,  6]).week(), 1, 'Jan  6 2008 should be week 1');\n    assert.equal(moment([2008,  0,  7]).week(), 2, 'Jan  7 2008 should be week 2');\n    assert.equal(moment([2008,  0, 13]).week(), 2, 'Jan 13 2008 should be week 2');\n    assert.equal(moment([2008,  0, 14]).week(), 3, 'Jan 14 2008 should be week 3');\n    assert.equal(moment([2002, 11, 30]).week(), 1, 'Dec 30 2002 should be week 1');\n    assert.equal(moment([2003,  0,  1]).week(), 1, 'Jan  1 2003 should be week 1');\n    assert.equal(moment([2003,  0,  5]).week(), 1, 'Jan  5 2003 should be week 1');\n    assert.equal(moment([2003,  0,  6]).week(), 2, 'Jan  6 2003 should be week 2');\n    assert.equal(moment([2003,  0, 12]).week(), 2, 'Jan 12 2003 should be week 2');\n    assert.equal(moment([2003,  0, 13]).week(), 3, 'Jan 13 2003 should be week 3');\n    assert.equal(moment([2008, 11, 29]).week(), 1, 'Dec 29 2008 should be week 1');\n    assert.equal(moment([2009,  0,  1]).week(), 1, 'Jan  1 2009 should be week 1');\n    assert.equal(moment([2009,  0,  4]).week(), 1, 'Jan  4 2009 should be week 1');\n    assert.equal(moment([2009,  0,  5]).week(), 2, 'Jan  5 2009 should be week 2');\n    assert.equal(moment([2009,  0, 11]).week(), 2, 'Jan 11 2009 should be week 2');\n    assert.equal(moment([2009,  0, 12]).week(), 3, 'Jan 12 2009 should be week 3');\n    assert.equal(moment([2009, 11, 28]).week(), 1, 'Dec 28 2009 should be week 1');\n    assert.equal(moment([2010,  0,  1]).week(), 1, 'Jan  1 2010 should be week 1');\n    assert.equal(moment([2010,  0,  3]).week(), 1, 'Jan  3 2010 should be week 1');\n    assert.equal(moment([2010,  0,  4]).week(), 2, 'Jan  4 2010 should be week 2');\n    assert.equal(moment([2010,  0, 10]).week(), 2, 'Jan 10 2010 should be week 2');\n    assert.equal(moment([2010,  0, 11]).week(), 3, 'Jan 11 2010 should be week 3');\n    assert.equal(moment([2010, 11, 27]).week(), 1, 'Dec 27 2010 should be week 1');\n    assert.equal(moment([2011,  0,  1]).week(), 1, 'Jan  1 2011 should be week 1');\n    assert.equal(moment([2011,  0,  2]).week(), 1, 'Jan  2 2011 should be week 1');\n    assert.equal(moment([2011,  0,  3]).week(), 2, 'Jan  3 2011 should be week 2');\n    assert.equal(moment([2011,  0,  9]).week(), 2, 'Jan  9 2011 should be week 2');\n    assert.equal(moment([2011,  0, 10]).week(), 3, 'Jan 10 2011 should be week 3');\n    moment.defineLocale('dow: 1, doy: 7', null);\n});\n\ntest('weeks numbers dow:0 doy:6', function (assert) {\n    moment.locale('dow: 0, doy: 6', {week: {dow: 0, doy: 6}});\n    assert.equal(moment([2012, 0,  1]).week(), 1, 'Jan  1 2012 should be week 1');\n    assert.equal(moment([2012, 0,  7]).week(), 1, 'Jan  7 2012 should be week 1');\n    assert.equal(moment([2012, 0,  8]).week(), 2, 'Jan  8 2012 should be week 2');\n    assert.equal(moment([2012, 0, 14]).week(), 2, 'Jan 14 2012 should be week 2');\n    assert.equal(moment([2012, 0, 15]).week(), 3, 'Jan 15 2012 should be week 3');\n    assert.equal(moment([2006, 11, 31]).week(), 1, 'Dec 31 2006 should be week 1');\n    assert.equal(moment([2007,  0,  1]).week(), 1, 'Jan  1 2007 should be week 1');\n    assert.equal(moment([2007,  0,  6]).week(), 1, 'Jan  6 2007 should be week 1');\n    assert.equal(moment([2007,  0,  7]).week(), 2, 'Jan  7 2007 should be week 2');\n    assert.equal(moment([2007,  0, 13]).week(), 2, 'Jan 13 2007 should be week 2');\n    assert.equal(moment([2007,  0, 14]).week(), 3, 'Jan 14 2007 should be week 3');\n    assert.equal(moment([2007, 11, 29]).week(), 52, 'Dec 29 2007 should be week 52');\n    assert.equal(moment([2008,  0,  1]).week(), 1, 'Jan  1 2008 should be week 1');\n    assert.equal(moment([2008,  0,  5]).week(), 1, 'Jan  5 2008 should be week 1');\n    assert.equal(moment([2008,  0,  6]).week(), 2, 'Jan  6 2008 should be week 2');\n    assert.equal(moment([2008,  0, 12]).week(), 2, 'Jan 12 2008 should be week 2');\n    assert.equal(moment([2008,  0, 13]).week(), 3, 'Jan 13 2008 should be week 3');\n    assert.equal(moment([2002, 11, 29]).week(), 1, 'Dec 29 2002 should be week 1');\n    assert.equal(moment([2003,  0,  1]).week(), 1, 'Jan  1 2003 should be week 1');\n    assert.equal(moment([2003,  0,  4]).week(), 1, 'Jan  4 2003 should be week 1');\n    assert.equal(moment([2003,  0,  5]).week(), 2, 'Jan  5 2003 should be week 2');\n    assert.equal(moment([2003,  0, 11]).week(), 2, 'Jan 11 2003 should be week 2');\n    assert.equal(moment([2003,  0, 12]).week(), 3, 'Jan 12 2003 should be week 3');\n    assert.equal(moment([2008, 11, 28]).week(), 1, 'Dec 28 2008 should be week 1');\n    assert.equal(moment([2009,  0,  1]).week(), 1, 'Jan  1 2009 should be week 1');\n    assert.equal(moment([2009,  0,  3]).week(), 1, 'Jan  3 2009 should be week 1');\n    assert.equal(moment([2009,  0,  4]).week(), 2, 'Jan  4 2009 should be week 2');\n    assert.equal(moment([2009,  0, 10]).week(), 2, 'Jan 10 2009 should be week 2');\n    assert.equal(moment([2009,  0, 11]).week(), 3, 'Jan 11 2009 should be week 3');\n    assert.equal(moment([2009, 11, 27]).week(), 1, 'Dec 27 2009 should be week 1');\n    assert.equal(moment([2010,  0,  1]).week(), 1, 'Jan  1 2010 should be week 1');\n    assert.equal(moment([2010,  0,  2]).week(), 1, 'Jan  2 2010 should be week 1');\n    assert.equal(moment([2010,  0,  3]).week(), 2, 'Jan  3 2010 should be week 2');\n    assert.equal(moment([2010,  0,  9]).week(), 2, 'Jan  9 2010 should be week 2');\n    assert.equal(moment([2010,  0, 10]).week(), 3, 'Jan 10 2010 should be week 3');\n    assert.equal(moment([2010, 11, 26]).week(), 1, 'Dec 26 2010 should be week 1');\n    assert.equal(moment([2011,  0,  1]).week(), 1, 'Jan  1 2011 should be week 1');\n    assert.equal(moment([2011,  0,  2]).week(), 2, 'Jan  2 2011 should be week 2');\n    assert.equal(moment([2011,  0,  8]).week(), 2, 'Jan  8 2011 should be week 2');\n    assert.equal(moment([2011,  0,  9]).week(), 3, 'Jan  9 2011 should be week 3');\n    moment.defineLocale('dow: 0, doy: 6', null);\n});\n\ntest('week year overflows', function (assert) {\n    assert.equal('2005-01-01', moment.utc('2004-W53-6', moment.ISO_8601, true).format('YYYY-MM-DD'), '2004-W53-6 is 1st Jan 2005');\n    assert.equal('2007-12-31', moment.utc('2008-W01-1', moment.ISO_8601, true).format('YYYY-MM-DD'), '2008-W01-1 is 31st Dec 2007');\n});\n\ntest('weeks overflow', function (assert) {\n    assert.equal(7, moment.utc('2004-W54-1', moment.ISO_8601, true).parsingFlags().overflow, '2004 has only 53 weeks');\n    assert.equal(7, moment.utc('2004-W00-1', moment.ISO_8601, true).parsingFlags().overflow, 'there is no 0th week');\n});\n\ntest('weekday overflow', function (assert) {\n    assert.equal(8, moment.utc('2004-W30-0', moment.ISO_8601, true).parsingFlags().overflow, 'there is no 0 iso weekday');\n    assert.equal(8, moment.utc('2004-W30-8', moment.ISO_8601, true).parsingFlags().overflow, 'there is no 8 iso weekday');\n    assert.equal(8, moment.utc('2004-w30-7', 'gggg-[w]ww-e', true).parsingFlags().overflow, 'there is no 7 \\'e\\' weekday');\n    assert.equal(8, moment.utc('2004-w30-7', 'gggg-[w]ww-d', true).parsingFlags().overflow, 'there is no 7 \\'d\\' weekday');\n});\n\ntest('week year setter works', function (assert) {\n    for (var year = 2000; year <= 2020; year += 1) {\n        assert.equal(moment.utc('2012-12-31T00:00:00.000Z').isoWeekYear(year).isoWeekYear(), year, 'setting iso-week-year to ' + year);\n        assert.equal(moment.utc('2012-12-31T00:00:00.000Z').weekYear(year).weekYear(), year, 'setting week-year to ' + year);\n    }\n\n    assert.equal(moment.utc('2004-W53-1', moment.ISO_8601, true).isoWeekYear(2013).format('GGGG-[W]WW-E'), '2013-W52-1', '2004-W53-1 to 2013');\n    assert.equal(moment.utc('2004-W53-1', moment.ISO_8601, true).isoWeekYear(2020).format('GGGG-[W]WW-E'), '2020-W53-1', '2004-W53-1 to 2020');\n    assert.equal(moment.utc('2005-W52-1', moment.ISO_8601, true).isoWeekYear(2004).format('GGGG-[W]WW-E'), '2004-W52-1', '2005-W52-1 to 2004');\n    assert.equal(moment.utc('2013-W30-4', moment.ISO_8601, true).isoWeekYear(2015).format('GGGG-[W]WW-E'), '2015-W30-4', '2013-W30-4 to 2015');\n\n    assert.equal(moment.utc('2005-w53-0', 'gggg-[w]ww-e', true).weekYear(2013).format('gggg-[w]ww-e'), '2013-w52-0', '2005-w53-0 to 2013');\n    assert.equal(moment.utc('2005-w53-0', 'gggg-[w]ww-e', true).weekYear(2016).format('gggg-[w]ww-e'), '2016-w53-0', '2005-w53-0 to 2016');\n    assert.equal(moment.utc('2004-w52-0', 'gggg-[w]ww-e', true).weekYear(2005).format('gggg-[w]ww-e'), '2005-w52-0', '2004-w52-0 to 2005');\n    assert.equal(moment.utc('2013-w30-4', 'gggg-[w]ww-e', true).weekYear(2015).format('gggg-[w]ww-e'), '2015-w30-4', '2013-w30-4 to 2015');\n});\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/test/moment/weekday.js",
    "content": "import { module, test } from '../qunit';\nimport moment from '../../moment';\n\nmodule('week day');\n\ntest('iso weekday', function (assert) {\n    var i;\n\n    for (i = 0; i < 7; ++i) {\n        moment.locale('dow:' + i + ',doy: 6', {week: {dow: i, doy: 6}});\n        assert.equal(moment([1985, 1,  4]).isoWeekday(), 1, 'Feb  4 1985 is Monday    -- 1st day');\n        assert.equal(moment([2029, 8, 18]).isoWeekday(), 2, 'Sep 18 2029 is Tuesday   -- 2nd day');\n        assert.equal(moment([2013, 3, 24]).isoWeekday(), 3, 'Apr 24 2013 is Wednesday -- 3rd day');\n        assert.equal(moment([2015, 2,  5]).isoWeekday(), 4, 'Mar  5 2015 is Thursday  -- 4th day');\n        assert.equal(moment([1970, 0,  2]).isoWeekday(), 5, 'Jan  2 1970 is Friday    -- 5th day');\n        assert.equal(moment([2001, 4, 12]).isoWeekday(), 6, 'May 12 2001 is Saturday  -- 6th day');\n        assert.equal(moment([2000, 0,  2]).isoWeekday(), 7, 'Jan  2 2000 is Sunday    -- 7th day');\n    }\n});\n\ntest('iso weekday setter', function (assert) {\n    var a = moment([2011, 0, 10]);\n    assert.equal(moment(a).isoWeekday(1).date(),  10, 'set from mon to mon');\n    assert.equal(moment(a).isoWeekday(4).date(),  13, 'set from mon to thu');\n    assert.equal(moment(a).isoWeekday(7).date(),  16, 'set from mon to sun');\n    assert.equal(moment(a).isoWeekday(-6).date(),  3, 'set from mon to last mon');\n    assert.equal(moment(a).isoWeekday(-3).date(),  6, 'set from mon to last thu');\n    assert.equal(moment(a).isoWeekday(0).date(),   9, 'set from mon to last sun');\n    assert.equal(moment(a).isoWeekday(8).date(),  17, 'set from mon to next mon');\n    assert.equal(moment(a).isoWeekday(11).date(), 20, 'set from mon to next thu');\n    assert.equal(moment(a).isoWeekday(14).date(), 23, 'set from mon to next sun');\n\n    a = moment([2011, 0, 13]);\n    assert.equal(moment(a).isoWeekday(1).date(), 10, 'set from thu to mon');\n    assert.equal(moment(a).isoWeekday(4).date(), 13, 'set from thu to thu');\n    assert.equal(moment(a).isoWeekday(7).date(), 16, 'set from thu to sun');\n    assert.equal(moment(a).isoWeekday(-6).date(),  3, 'set from thu to last mon');\n    assert.equal(moment(a).isoWeekday(-3).date(),  6, 'set from thu to last thu');\n    assert.equal(moment(a).isoWeekday(0).date(),   9, 'set from thu to last sun');\n    assert.equal(moment(a).isoWeekday(8).date(),  17, 'set from thu to next mon');\n    assert.equal(moment(a).isoWeekday(11).date(), 20, 'set from thu to next thu');\n    assert.equal(moment(a).isoWeekday(14).date(), 23, 'set from thu to next sun');\n\n    a = moment([2011, 0, 16]);\n    assert.equal(moment(a).isoWeekday(1).date(), 10, 'set from sun to mon');\n    assert.equal(moment(a).isoWeekday(4).date(), 13, 'set from sun to thu');\n    assert.equal(moment(a).isoWeekday(7).date(), 16, 'set from sun to sun');\n    assert.equal(moment(a).isoWeekday(-6).date(),  3, 'set from sun to last mon');\n    assert.equal(moment(a).isoWeekday(-3).date(),  6, 'set from sun to last thu');\n    assert.equal(moment(a).isoWeekday(0).date(),   9, 'set from sun to last sun');\n    assert.equal(moment(a).isoWeekday(8).date(),  17, 'set from sun to next mon');\n    assert.equal(moment(a).isoWeekday(11).date(), 20, 'set from sun to next thu');\n    assert.equal(moment(a).isoWeekday(14).date(), 23, 'set from sun to next sun');\n});\n\ntest('iso weekday setter with day name', function (assert) {\n    moment.locale('en');\n\n    var a = moment([2011, 0, 10]);\n    assert.equal(moment(a).isoWeekday('Monday').date(),   10, 'set from mon to mon');\n    assert.equal(moment(a).isoWeekday('Thursday').date(), 13, 'set from mon to thu');\n    assert.equal(moment(a).isoWeekday('Sunday').date(),   16, 'set from mon to sun');\n\n    a = moment([2011, 0, 13]);\n    assert.equal(moment(a).isoWeekday('Monday').date(),   10, 'set from thu to mon');\n    assert.equal(moment(a).isoWeekday('Thursday').date(), 13, 'set from thu to thu');\n    assert.equal(moment(a).isoWeekday('Sunday').date(),   16, 'set from thu to sun');\n\n    a = moment([2011, 0, 16]);\n    assert.equal(moment(a).isoWeekday('Monday').date(),   10, 'set from sun to mon');\n    assert.equal(moment(a).isoWeekday('Thursday').date(), 13, 'set from sun to thu');\n    assert.equal(moment(a).isoWeekday('Sunday').date(),   16, 'set from sun to sun');\n});\n\ntest('weekday first day of week Sunday (dow 0)', function (assert) {\n    moment.locale('dow: 0,doy: 6', {week: {dow: 0, doy: 6}});\n    assert.equal(moment([1985, 1,  3]).weekday(), 0, 'Feb  3 1985 is Sunday    -- 0th day');\n    assert.equal(moment([2029, 8, 17]).weekday(), 1, 'Sep 17 2029 is Monday    -- 1st day');\n    assert.equal(moment([2013, 3, 23]).weekday(), 2, 'Apr 23 2013 is Tuesday   -- 2nd day');\n    assert.equal(moment([2015, 2,  4]).weekday(), 3, 'Mar  4 2015 is Wednesday -- 3nd day');\n    assert.equal(moment([1970, 0,  1]).weekday(), 4, 'Jan  1 1970 is Thursday  -- 4th day');\n    assert.equal(moment([2001, 4, 11]).weekday(), 5, 'May 11 2001 is Friday    -- 5th day');\n    assert.equal(moment([2000, 0,  1]).weekday(), 6, 'Jan  1 2000 is Saturday  -- 6th day');\n});\n\ntest('weekday first day of week Monday (dow 1)', function (assert) {\n    moment.locale('dow: 1,doy: 6', {week: {dow: 1, doy: 6}});\n    assert.equal(moment([1985, 1,  4]).weekday(), 0, 'Feb  4 1985 is Monday    -- 0th day');\n    assert.equal(moment([2029, 8, 18]).weekday(), 1, 'Sep 18 2029 is Tuesday   -- 1st day');\n    assert.equal(moment([2013, 3, 24]).weekday(), 2, 'Apr 24 2013 is Wednesday -- 2nd day');\n    assert.equal(moment([2015, 2,  5]).weekday(), 3, 'Mar  5 2015 is Thursday  -- 3nd day');\n    assert.equal(moment([1970, 0,  2]).weekday(), 4, 'Jan  2 1970 is Friday    -- 4th day');\n    assert.equal(moment([2001, 4, 12]).weekday(), 5, 'May 12 2001 is Saturday  -- 5th day');\n    assert.equal(moment([2000, 0,  2]).weekday(), 6, 'Jan  2 2000 is Sunday    -- 6th day');\n});\n\ntest('weekday first day of week Tuesday (dow 2)', function (assert) {\n    moment.locale('dow: 2,doy: 6', {week: {dow: 2, doy: 6}});\n    assert.equal(moment([1985, 1,  5]).weekday(), 0, 'Feb  5 1985 is Tuesday   -- 0th day');\n    assert.equal(moment([2029, 8, 19]).weekday(), 1, 'Sep 19 2029 is Wednesday -- 1st day');\n    assert.equal(moment([2013, 3, 25]).weekday(), 2, 'Apr 25 2013 is Thursday  -- 2nd day');\n    assert.equal(moment([2015, 2,  6]).weekday(), 3, 'Mar  6 2015 is Friday    -- 3nd day');\n    assert.equal(moment([1970, 0,  3]).weekday(), 4, 'Jan  3 1970 is Staturday -- 4th day');\n    assert.equal(moment([2001, 4, 13]).weekday(), 5, 'May 13 2001 is Sunday    -- 5th day');\n    assert.equal(moment([2000, 0,  3]).weekday(), 6, 'Jan  3 2000 is Monday    -- 6th day');\n});\n\ntest('weekday first day of week Wednesday (dow 3)', function (assert) {\n    moment.locale('dow: 3,doy: 6', {week: {dow: 3, doy: 6}});\n    assert.equal(moment([1985, 1,  6]).weekday(), 0, 'Feb  6 1985 is Wednesday -- 0th day');\n    assert.equal(moment([2029, 8, 20]).weekday(), 1, 'Sep 20 2029 is Thursday  -- 1st day');\n    assert.equal(moment([2013, 3, 26]).weekday(), 2, 'Apr 26 2013 is Friday    -- 2nd day');\n    assert.equal(moment([2015, 2,  7]).weekday(), 3, 'Mar  7 2015 is Saturday  -- 3nd day');\n    assert.equal(moment([1970, 0,  4]).weekday(), 4, 'Jan  4 1970 is Sunday    -- 4th day');\n    assert.equal(moment([2001, 4, 14]).weekday(), 5, 'May 14 2001 is Monday    -- 5th day');\n    assert.equal(moment([2000, 0,  4]).weekday(), 6, 'Jan  4 2000 is Tuesday   -- 6th day');\n    moment.locale('dow:3,doy:6', null);\n});\n\ntest('weekday first day of week Thursday (dow 4)', function (assert) {\n    moment.locale('dow: 4,doy: 6', {week: {dow: 4, doy: 6}});\n    assert.equal(moment([1985, 1,  7]).weekday(), 0, 'Feb  7 1985 is Thursday  -- 0th day');\n    assert.equal(moment([2029, 8, 21]).weekday(), 1, 'Sep 21 2029 is Friday    -- 1st day');\n    assert.equal(moment([2013, 3, 27]).weekday(), 2, 'Apr 27 2013 is Saturday  -- 2nd day');\n    assert.equal(moment([2015, 2,  8]).weekday(), 3, 'Mar  8 2015 is Sunday    -- 3nd day');\n    assert.equal(moment([1970, 0,  5]).weekday(), 4, 'Jan  5 1970 is Monday    -- 4th day');\n    assert.equal(moment([2001, 4, 15]).weekday(), 5, 'May 15 2001 is Tuesday   -- 5th day');\n    assert.equal(moment([2000, 0,  5]).weekday(), 6, 'Jan  5 2000 is Wednesday -- 6th day');\n});\n\ntest('weekday first day of week Friday (dow 5)', function (assert) {\n    moment.locale('dow: 5,doy: 6', {week: {dow: 5, doy: 6}});\n    assert.equal(moment([1985, 1,  8]).weekday(), 0, 'Feb  8 1985 is Friday    -- 0th day');\n    assert.equal(moment([2029, 8, 22]).weekday(), 1, 'Sep 22 2029 is Staturday -- 1st day');\n    assert.equal(moment([2013, 3, 28]).weekday(), 2, 'Apr 28 2013 is Sunday    -- 2nd day');\n    assert.equal(moment([2015, 2,  9]).weekday(), 3, 'Mar  9 2015 is Monday    -- 3nd day');\n    assert.equal(moment([1970, 0,  6]).weekday(), 4, 'Jan  6 1970 is Tuesday   -- 4th day');\n    assert.equal(moment([2001, 4, 16]).weekday(), 5, 'May 16 2001 is Wednesday -- 5th day');\n    assert.equal(moment([2000, 0,  6]).weekday(), 6, 'Jan  6 2000 is Thursday  -- 6th day');\n});\n\ntest('weekday first day of week Saturday (dow 6)', function (assert) {\n    moment.locale('dow: 6,doy: 6', {week: {dow: 6, doy: 6}});\n    assert.equal(moment([1985, 1,  9]).weekday(), 0, 'Feb  9 1985 is Staturday -- 0th day');\n    assert.equal(moment([2029, 8, 23]).weekday(), 1, 'Sep 23 2029 is Sunday    -- 1st day');\n    assert.equal(moment([2013, 3, 29]).weekday(), 2, 'Apr 29 2013 is Monday    -- 2nd day');\n    assert.equal(moment([2015, 2, 10]).weekday(), 3, 'Mar 10 2015 is Tuesday   -- 3nd day');\n    assert.equal(moment([1970, 0,  7]).weekday(), 4, 'Jan  7 1970 is Wednesday -- 4th day');\n    assert.equal(moment([2001, 4, 17]).weekday(), 5, 'May 17 2001 is Thursday  -- 5th day');\n    assert.equal(moment([2000, 0,  7]).weekday(), 6, 'Jan  7 2000 is Friday    -- 6th day');\n});\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/test/moment/weeks.js",
    "content": "import { module, test } from '../qunit';\nimport moment from '../../moment';\n\nmodule('weeks');\n\ntest('day of year', function (assert) {\n    assert.equal(moment([2000,  0,  1]).dayOfYear(),   1, 'Jan  1 2000 should be day 1 of the year');\n    assert.equal(moment([2000,  1, 28]).dayOfYear(),  59, 'Feb 28 2000 should be day 59 of the year');\n    assert.equal(moment([2000,  1, 29]).dayOfYear(),  60, 'Feb 28 2000 should be day 60 of the year');\n    assert.equal(moment([2000, 11, 31]).dayOfYear(), 366, 'Dec 31 2000 should be day 366 of the year');\n    assert.equal(moment([2001,  0,  1]).dayOfYear(),   1, 'Jan  1 2001 should be day 1 of the year');\n    assert.equal(moment([2001,  1, 28]).dayOfYear(),  59, 'Feb 28 2001 should be day 59 of the year');\n    assert.equal(moment([2001,  2,  1]).dayOfYear(),  60, 'Mar  1 2001 should be day 60 of the year');\n    assert.equal(moment([2001, 11, 31]).dayOfYear(), 365, 'Dec 31 2001 should be day 365 of the year');\n});\n\ntest('day of year setters', function (assert) {\n    assert.equal(moment([2000,  0,  1]).dayOfYear(200).dayOfYear(), 200, 'Setting Jan  1 2000 day of the year to 200 should work');\n    assert.equal(moment([2000,  1, 28]).dayOfYear(200).dayOfYear(), 200, 'Setting Feb 28 2000 day of the year to 200 should work');\n    assert.equal(moment([2000,  1, 29]).dayOfYear(200).dayOfYear(), 200, 'Setting Feb 28 2000 day of the year to 200 should work');\n    assert.equal(moment([2000, 11, 31]).dayOfYear(200).dayOfYear(), 200, 'Setting Dec 31 2000 day of the year to 200 should work');\n    assert.equal(moment().dayOfYear(1).dayOfYear(),   1, 'Setting day of the year to 1 should work');\n    assert.equal(moment().dayOfYear(59).dayOfYear(),  59, 'Setting day of the year to 59 should work');\n    assert.equal(moment().dayOfYear(60).dayOfYear(),  60, 'Setting day of the year to 60 should work');\n    assert.equal(moment().dayOfYear(365).dayOfYear(), 365, 'Setting day of the year to 365 should work');\n});\n\ntest('iso weeks year starting sunday', function (assert) {\n    assert.equal(moment([2012, 0, 1]).isoWeek(), 52, 'Jan  1 2012 should be iso week 52');\n    assert.equal(moment([2012, 0, 2]).isoWeek(),  1, 'Jan  2 2012 should be iso week 1');\n    assert.equal(moment([2012, 0, 8]).isoWeek(),  1, 'Jan  8 2012 should be iso week 1');\n    assert.equal(moment([2012, 0, 9]).isoWeek(),  2, 'Jan  9 2012 should be iso week 2');\n    assert.equal(moment([2012, 0, 15]).isoWeek(), 2, 'Jan 15 2012 should be iso week 2');\n});\n\ntest('iso weeks year starting monday', function (assert) {\n    assert.equal(moment([2007, 0, 1]).isoWeek(),  1, 'Jan  1 2007 should be iso week 1');\n    assert.equal(moment([2007, 0, 7]).isoWeek(),  1, 'Jan  7 2007 should be iso week 1');\n    assert.equal(moment([2007, 0, 8]).isoWeek(),  2, 'Jan  8 2007 should be iso week 2');\n    assert.equal(moment([2007, 0, 14]).isoWeek(), 2, 'Jan 14 2007 should be iso week 2');\n    assert.equal(moment([2007, 0, 15]).isoWeek(), 3, 'Jan 15 2007 should be iso week 3');\n});\n\ntest('iso weeks year starting tuesday', function (assert) {\n    assert.equal(moment([2007, 11, 31]).isoWeek(), 1, 'Dec 31 2007 should be iso week 1');\n    assert.equal(moment([2008,  0,  1]).isoWeek(), 1, 'Jan  1 2008 should be iso week 1');\n    assert.equal(moment([2008,  0,  6]).isoWeek(), 1, 'Jan  6 2008 should be iso week 1');\n    assert.equal(moment([2008,  0,  7]).isoWeek(), 2, 'Jan  7 2008 should be iso week 2');\n    assert.equal(moment([2008,  0, 13]).isoWeek(), 2, 'Jan 13 2008 should be iso week 2');\n    assert.equal(moment([2008,  0, 14]).isoWeek(), 3, 'Jan 14 2008 should be iso week 3');\n});\n\ntest('iso weeks year starting wednesday', function (assert) {\n    assert.equal(moment([2002, 11, 30]).isoWeek(), 1, 'Dec 30 2002 should be iso week 1');\n    assert.equal(moment([2003,  0,  1]).isoWeek(), 1, 'Jan  1 2003 should be iso week 1');\n    assert.equal(moment([2003,  0,  5]).isoWeek(), 1, 'Jan  5 2003 should be iso week 1');\n    assert.equal(moment([2003,  0,  6]).isoWeek(), 2, 'Jan  6 2003 should be iso week 2');\n    assert.equal(moment([2003,  0, 12]).isoWeek(), 2, 'Jan 12 2003 should be iso week 2');\n    assert.equal(moment([2003,  0, 13]).isoWeek(), 3, 'Jan 13 2003 should be iso week 3');\n});\n\ntest('iso weeks year starting thursday', function (assert) {\n    assert.equal(moment([2008, 11, 29]).isoWeek(), 1, 'Dec 29 2008 should be iso week 1');\n    assert.equal(moment([2009,  0,  1]).isoWeek(), 1, 'Jan  1 2009 should be iso week 1');\n    assert.equal(moment([2009,  0,  4]).isoWeek(), 1, 'Jan  4 2009 should be iso week 1');\n    assert.equal(moment([2009,  0,  5]).isoWeek(), 2, 'Jan  5 2009 should be iso week 2');\n    assert.equal(moment([2009,  0, 11]).isoWeek(), 2, 'Jan 11 2009 should be iso week 2');\n    assert.equal(moment([2009,  0, 13]).isoWeek(), 3, 'Jan 12 2009 should be iso week 3');\n});\n\ntest('iso weeks year starting friday', function (assert) {\n    assert.equal(moment([2009, 11, 28]).isoWeek(), 53, 'Dec 28 2009 should be iso week 53');\n    assert.equal(moment([2010,  0,  1]).isoWeek(), 53, 'Jan  1 2010 should be iso week 53');\n    assert.equal(moment([2010,  0,  3]).isoWeek(), 53, 'Jan  3 2010 should be iso week 53');\n    assert.equal(moment([2010,  0,  4]).isoWeek(),  1, 'Jan  4 2010 should be iso week 1');\n    assert.equal(moment([2010,  0, 10]).isoWeek(),  1, 'Jan 10 2010 should be iso week 1');\n    assert.equal(moment([2010,  0, 11]).isoWeek(),  2, 'Jan 11 2010 should be iso week 2');\n});\n\ntest('iso weeks year starting saturday', function (assert) {\n    assert.equal(moment([2010, 11, 27]).isoWeek(), 52, 'Dec 27 2010 should be iso week 52');\n    assert.equal(moment([2011,  0,  1]).isoWeek(), 52, 'Jan  1 2011 should be iso week 52');\n    assert.equal(moment([2011,  0,  2]).isoWeek(), 52, 'Jan  2 2011 should be iso week 52');\n    assert.equal(moment([2011,  0,  3]).isoWeek(),  1, 'Jan  3 2011 should be iso week 1');\n    assert.equal(moment([2011,  0,  9]).isoWeek(),  1, 'Jan  9 2011 should be iso week 1');\n    assert.equal(moment([2011,  0, 10]).isoWeek(),  2, 'Jan 10 2011 should be iso week 2');\n});\n\ntest('iso weeks year starting sunday formatted', function (assert) {\n    assert.equal(moment([2012, 0,  1]).format('W WW Wo'), '52 52 52nd', 'Jan  1 2012 should be iso week 52');\n    assert.equal(moment([2012, 0,  2]).format('W WW Wo'),   '1 01 1st', 'Jan  2 2012 should be iso week 1');\n    assert.equal(moment([2012, 0,  8]).format('W WW Wo'),   '1 01 1st', 'Jan  8 2012 should be iso week 1');\n    assert.equal(moment([2012, 0,  9]).format('W WW Wo'),   '2 02 2nd', 'Jan  9 2012 should be iso week 2');\n    assert.equal(moment([2012, 0, 15]).format('W WW Wo'),   '2 02 2nd', 'Jan 15 2012 should be iso week 2');\n});\n\ntest('weeks plural year starting sunday', function (assert) {\n    assert.equal(moment([2012, 0,  1]).weeks(), 1, 'Jan  1 2012 should be week 1');\n    assert.equal(moment([2012, 0,  7]).weeks(), 1, 'Jan  7 2012 should be week 1');\n    assert.equal(moment([2012, 0,  8]).weeks(), 2, 'Jan  8 2012 should be week 2');\n    assert.equal(moment([2012, 0, 14]).weeks(), 2, 'Jan 14 2012 should be week 2');\n    assert.equal(moment([2012, 0, 15]).weeks(), 3, 'Jan 15 2012 should be week 3');\n});\n\ntest('iso weeks plural year starting sunday', function (assert) {\n    assert.equal(moment([2012, 0, 1]).isoWeeks(), 52, 'Jan  1 2012 should be iso week 52');\n    assert.equal(moment([2012, 0, 2]).isoWeeks(),  1, 'Jan  2 2012 should be iso week 1');\n    assert.equal(moment([2012, 0, 8]).isoWeeks(),  1, 'Jan  8 2012 should be iso week 1');\n    assert.equal(moment([2012, 0, 9]).isoWeeks(),  2, 'Jan  9 2012 should be iso week 2');\n    assert.equal(moment([2012, 0, 15]).isoWeeks(), 2, 'Jan 15 2012 should be iso week 2');\n});\n\ntest('weeks setter', function (assert) {\n    assert.equal(moment([2012, 0,  1]).week(30).week(), 30, 'Setting Jan 1 2012 to week 30 should work');\n    assert.equal(moment([2012, 0,  7]).week(30).week(), 30, 'Setting Jan 7 2012 to week 30 should work');\n    assert.equal(moment([2012, 0,  8]).week(30).week(), 30, 'Setting Jan 8 2012 to week 30 should work');\n    assert.equal(moment([2012, 0, 14]).week(30).week(), 30, 'Setting Jan 14 2012 to week 30 should work');\n    assert.equal(moment([2012, 0, 15]).week(30).week(), 30, 'Setting Jan 15 2012 to week 30 should work');\n});\n\ntest('iso weeks setter', function (assert) {\n    assert.equal(moment([2012, 0,  1]).isoWeeks(25).isoWeeks(), 25, 'Setting Jan  1 2012 to week 25 should work');\n    assert.equal(moment([2012, 0,  2]).isoWeeks(24).isoWeeks(), 24, 'Setting Jan  2 2012 to week 24 should work');\n    assert.equal(moment([2012, 0,  8]).isoWeeks(23).isoWeeks(), 23, 'Setting Jan  8 2012 to week 23 should work');\n    assert.equal(moment([2012, 0,  9]).isoWeeks(22).isoWeeks(), 22, 'Setting Jan  9 2012 to week 22 should work');\n    assert.equal(moment([2012, 0, 15]).isoWeeks(21).isoWeeks(), 21, 'Setting Jan 15 2012 to week 21 should work');\n});\n\ntest('iso weeks setter day of year', function (assert) {\n    assert.equal(moment([2012, 0,  1]).isoWeek(1).dayOfYear(), 9, 'Setting Jan  1 2012 to week 1 should be day of year 8');\n    assert.equal(moment([2012, 0,  1]).isoWeek(1).year(),   2011, 'Setting Jan  1 2012 to week 1 should be year 2011');\n    assert.equal(moment([2012, 0,  2]).isoWeek(1).dayOfYear(), 2, 'Setting Jan  2 2012 to week 1 should be day of year 2');\n    assert.equal(moment([2012, 0,  8]).isoWeek(1).dayOfYear(), 8, 'Setting Jan  8 2012 to week 1 should be day of year 8');\n    assert.equal(moment([2012, 0,  9]).isoWeek(1).dayOfYear(), 2, 'Setting Jan  9 2012 to week 1 should be day of year 2');\n    assert.equal(moment([2012, 0, 15]).isoWeek(1).dayOfYear(), 8, 'Setting Jan 15 2012 to week 1 should be day of year 8');\n});\n\ntest('years with iso week 53', function (assert) {\n    // Based on a table taken from https://en.wikipedia.org/wiki/ISO_week_date\n    // (as downloaded on 2014-01-06) listing the 71 years in a 400-year cycle\n    // that have 53 weeks; in this case reflecting the 2000 based cycle\n    assert.equal(moment([2004, 11, 31]).isoWeek(), 53, 'Dec 31 2004 should be iso week 53');\n    assert.equal(moment([2009, 11, 31]).isoWeek(), 53, 'Dec 31 2009 should be iso week 53');\n    assert.equal(moment([2015, 11, 31]).isoWeek(), 53, 'Dec 31 2015 should be iso week 53');\n    assert.equal(moment([2020, 11, 31]).isoWeek(), 53, 'Dec 31 2020 should be iso week 53');\n    assert.equal(moment([2026, 11, 31]).isoWeek(), 53, 'Dec 31 2026 should be iso week 53');\n    assert.equal(moment([2032, 11, 31]).isoWeek(), 53, 'Dec 31 2032 should be iso week 53');\n    assert.equal(moment([2037, 11, 31]).isoWeek(), 53, 'Dec 31 2037 should be iso week 53');\n    assert.equal(moment([2043, 11, 31]).isoWeek(), 53, 'Dec 31 2043 should be iso week 53');\n    assert.equal(moment([2048, 11, 31]).isoWeek(), 53, 'Dec 31 2048 should be iso week 53');\n    assert.equal(moment([2054, 11, 31]).isoWeek(), 53, 'Dec 31 2054 should be iso week 53');\n    assert.equal(moment([2060, 11, 31]).isoWeek(), 53, 'Dec 31 2060 should be iso week 53');\n    assert.equal(moment([2065, 11, 31]).isoWeek(), 53, 'Dec 31 2065 should be iso week 53');\n    assert.equal(moment([2071, 11, 31]).isoWeek(), 53, 'Dec 31 2071 should be iso week 53');\n    assert.equal(moment([2076, 11, 31]).isoWeek(), 53, 'Dec 31 2076 should be iso week 53');\n    assert.equal(moment([2082, 11, 31]).isoWeek(), 53, 'Dec 31 2082 should be iso week 53');\n    assert.equal(moment([2088, 11, 31]).isoWeek(), 53, 'Dec 31 2088 should be iso week 53');\n    assert.equal(moment([2093, 11, 31]).isoWeek(), 53, 'Dec 31 2093 should be iso week 53');\n    assert.equal(moment([2099, 11, 31]).isoWeek(), 53, 'Dec 31 2099 should be iso week 53');\n    assert.equal(moment([2105, 11, 31]).isoWeek(), 53, 'Dec 31 2105 should be iso week 53');\n    assert.equal(moment([2111, 11, 31]).isoWeek(), 53, 'Dec 31 2111 should be iso week 53');\n    assert.equal(moment([2116, 11, 31]).isoWeek(), 53, 'Dec 31 2116 should be iso week 53');\n    assert.equal(moment([2122, 11, 31]).isoWeek(), 53, 'Dec 31 2122 should be iso week 53');\n    assert.equal(moment([2128, 11, 31]).isoWeek(), 53, 'Dec 31 2128 should be iso week 53');\n    assert.equal(moment([2133, 11, 31]).isoWeek(), 53, 'Dec 31 2133 should be iso week 53');\n    assert.equal(moment([2139, 11, 31]).isoWeek(), 53, 'Dec 31 2139 should be iso week 53');\n    assert.equal(moment([2144, 11, 31]).isoWeek(), 53, 'Dec 31 2144 should be iso week 53');\n    assert.equal(moment([2150, 11, 31]).isoWeek(), 53, 'Dec 31 2150 should be iso week 53');\n    assert.equal(moment([2156, 11, 31]).isoWeek(), 53, 'Dec 31 2156 should be iso week 53');\n    assert.equal(moment([2161, 11, 31]).isoWeek(), 53, 'Dec 31 2161 should be iso week 53');\n    assert.equal(moment([2167, 11, 31]).isoWeek(), 53, 'Dec 31 2167 should be iso week 53');\n    assert.equal(moment([2172, 11, 31]).isoWeek(), 53, 'Dec 31 2172 should be iso week 53');\n    assert.equal(moment([2178, 11, 31]).isoWeek(), 53, 'Dec 31 2178 should be iso week 53');\n    assert.equal(moment([2184, 11, 31]).isoWeek(), 53, 'Dec 31 2184 should be iso week 53');\n    assert.equal(moment([2189, 11, 31]).isoWeek(), 53, 'Dec 31 2189 should be iso week 53');\n    assert.equal(moment([2195, 11, 31]).isoWeek(), 53, 'Dec 31 2195 should be iso week 53');\n    assert.equal(moment([2201, 11, 31]).isoWeek(), 53, 'Dec 31 2201 should be iso week 53');\n    assert.equal(moment([2207, 11, 31]).isoWeek(), 53, 'Dec 31 2207 should be iso week 53');\n    assert.equal(moment([2212, 11, 31]).isoWeek(), 53, 'Dec 31 2212 should be iso week 53');\n    assert.equal(moment([2218, 11, 31]).isoWeek(), 53, 'Dec 31 2218 should be iso week 53');\n    assert.equal(moment([2224, 11, 31]).isoWeek(), 53, 'Dec 31 2224 should be iso week 53');\n    assert.equal(moment([2229, 11, 31]).isoWeek(), 53, 'Dec 31 2229 should be iso week 53');\n    assert.equal(moment([2235, 11, 31]).isoWeek(), 53, 'Dec 31 2235 should be iso week 53');\n    assert.equal(moment([2240, 11, 31]).isoWeek(), 53, 'Dec 31 2240 should be iso week 53');\n    assert.equal(moment([2246, 11, 31]).isoWeek(), 53, 'Dec 31 2246 should be iso week 53');\n    assert.equal(moment([2252, 11, 31]).isoWeek(), 53, 'Dec 31 2252 should be iso week 53');\n    assert.equal(moment([2257, 11, 31]).isoWeek(), 53, 'Dec 31 2257 should be iso week 53');\n    assert.equal(moment([2263, 11, 31]).isoWeek(), 53, 'Dec 31 2263 should be iso week 53');\n    assert.equal(moment([2268, 11, 31]).isoWeek(), 53, 'Dec 31 2268 should be iso week 53');\n    assert.equal(moment([2274, 11, 31]).isoWeek(), 53, 'Dec 31 2274 should be iso week 53');\n    assert.equal(moment([2280, 11, 31]).isoWeek(), 53, 'Dec 31 2280 should be iso week 53');\n    assert.equal(moment([2285, 11, 31]).isoWeek(), 53, 'Dec 31 2285 should be iso week 53');\n    assert.equal(moment([2291, 11, 31]).isoWeek(), 53, 'Dec 31 2291 should be iso week 53');\n    assert.equal(moment([2296, 11, 31]).isoWeek(), 53, 'Dec 31 2296 should be iso week 53');\n    assert.equal(moment([2303, 11, 31]).isoWeek(), 53, 'Dec 31 2303 should be iso week 53');\n    assert.equal(moment([2308, 11, 31]).isoWeek(), 53, 'Dec 31 2308 should be iso week 53');\n    assert.equal(moment([2314, 11, 31]).isoWeek(), 53, 'Dec 31 2314 should be iso week 53');\n    assert.equal(moment([2320, 11, 31]).isoWeek(), 53, 'Dec 31 2320 should be iso week 53');\n    assert.equal(moment([2325, 11, 31]).isoWeek(), 53, 'Dec 31 2325 should be iso week 53');\n    assert.equal(moment([2331, 11, 31]).isoWeek(), 53, 'Dec 31 2331 should be iso week 53');\n    assert.equal(moment([2336, 11, 31]).isoWeek(), 53, 'Dec 31 2336 should be iso week 53');\n    assert.equal(moment([2342, 11, 31]).isoWeek(), 53, 'Dec 31 2342 should be iso week 53');\n    assert.equal(moment([2348, 11, 31]).isoWeek(), 53, 'Dec 31 2348 should be iso week 53');\n    assert.equal(moment([2353, 11, 31]).isoWeek(), 53, 'Dec 31 2353 should be iso week 53');\n    assert.equal(moment([2359, 11, 31]).isoWeek(), 53, 'Dec 31 2359 should be iso week 53');\n    assert.equal(moment([2364, 11, 31]).isoWeek(), 53, 'Dec 31 2364 should be iso week 53');\n    assert.equal(moment([2370, 11, 31]).isoWeek(), 53, 'Dec 31 2370 should be iso week 53');\n    assert.equal(moment([2376, 11, 31]).isoWeek(), 53, 'Dec 31 2376 should be iso week 53');\n    assert.equal(moment([2381, 11, 31]).isoWeek(), 53, 'Dec 31 2381 should be iso week 53');\n    assert.equal(moment([2387, 11, 31]).isoWeek(), 53, 'Dec 31 2387 should be iso week 53');\n    assert.equal(moment([2392, 11, 31]).isoWeek(), 53, 'Dec 31 2392 should be iso week 53');\n    assert.equal(moment([2398, 11, 31]).isoWeek(), 53, 'Dec 31 2398 should be iso week 53');\n});\n\ntest('count years with iso week 53', function (assert) {\n    // Based on https://en.wikipedia.org/wiki/ISO_week_date (as seen on 2014-01-06)\n    // stating that there are 71 years in a 400-year cycle that have 53 weeks;\n    // in this case reflecting the 2000 based cycle\n    var count = 0, i;\n    for (i = 0; i < 400; i++) {\n        count += (moment([2000 + i, 11, 31]).isoWeek() === 53) ? 1 : 0;\n    }\n    assert.equal(count, 71, 'Should have 71 years in 400-year cycle with iso week 53');\n});\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/test/moment/weeks_in_year.js",
    "content": "import { module, test } from '../qunit';\nimport moment from '../../moment';\n\nmodule('weeks in year');\n\ntest('isoWeeksInYear', function (assert) {\n    assert.equal(moment([2004]).isoWeeksInYear(), 53, '2004 has 53 iso weeks');\n    assert.equal(moment([2005]).isoWeeksInYear(), 52, '2005 has 53 iso weeks');\n    assert.equal(moment([2006]).isoWeeksInYear(), 52, '2006 has 53 iso weeks');\n    assert.equal(moment([2007]).isoWeeksInYear(), 52, '2007 has 52 iso weeks');\n    assert.equal(moment([2008]).isoWeeksInYear(), 52, '2008 has 53 iso weeks');\n    assert.equal(moment([2009]).isoWeeksInYear(), 53, '2009 has 53 iso weeks');\n    assert.equal(moment([2010]).isoWeeksInYear(), 52, '2010 has 52 iso weeks');\n    assert.equal(moment([2011]).isoWeeksInYear(), 52, '2011 has 52 iso weeks');\n    assert.equal(moment([2012]).isoWeeksInYear(), 52, '2012 has 52 iso weeks');\n    assert.equal(moment([2013]).isoWeeksInYear(), 52, '2013 has 52 iso weeks');\n    assert.equal(moment([2014]).isoWeeksInYear(), 52, '2014 has 52 iso weeks');\n    assert.equal(moment([2015]).isoWeeksInYear(), 53, '2015 has 53 iso weeks');\n});\n\ntest('weeksInYear doy/dow = 1/4', function (assert) {\n    moment.locale('1/4', {week: {dow: 1, doy: 4}});\n\n    assert.equal(moment([2004]).weeksInYear(), 53, '2004 has 53 weeks');\n    assert.equal(moment([2005]).weeksInYear(), 52, '2005 has 53 weeks');\n    assert.equal(moment([2006]).weeksInYear(), 52, '2006 has 53 weeks');\n    assert.equal(moment([2007]).weeksInYear(), 52, '2007 has 52 weeks');\n    assert.equal(moment([2008]).weeksInYear(), 52, '2008 has 53 weeks');\n    assert.equal(moment([2009]).weeksInYear(), 53, '2009 has 53 weeks');\n    assert.equal(moment([2010]).weeksInYear(), 52, '2010 has 52 weeks');\n    assert.equal(moment([2011]).weeksInYear(), 52, '2011 has 52 weeks');\n    assert.equal(moment([2012]).weeksInYear(), 52, '2012 has 52 weeks');\n    assert.equal(moment([2013]).weeksInYear(), 52, '2013 has 52 weeks');\n    assert.equal(moment([2014]).weeksInYear(), 52, '2014 has 52 weeks');\n    assert.equal(moment([2015]).weeksInYear(), 53, '2015 has 53 weeks');\n});\n\ntest('weeksInYear doy/dow = 6/12', function (assert) {\n    moment.locale('6/12', {week: {dow: 6, doy: 12}});\n\n    assert.equal(moment([2004]).weeksInYear(), 53, '2004 has 53 weeks');\n    assert.equal(moment([2005]).weeksInYear(), 52, '2005 has 53 weeks');\n    assert.equal(moment([2006]).weeksInYear(), 52, '2006 has 53 weeks');\n    assert.equal(moment([2007]).weeksInYear(), 52, '2007 has 52 weeks');\n    assert.equal(moment([2008]).weeksInYear(), 52, '2008 has 53 weeks');\n    assert.equal(moment([2009]).weeksInYear(), 52, '2009 has 53 weeks');\n    assert.equal(moment([2010]).weeksInYear(), 53, '2010 has 52 weeks');\n    assert.equal(moment([2011]).weeksInYear(), 52, '2011 has 52 weeks');\n    assert.equal(moment([2012]).weeksInYear(), 52, '2012 has 52 weeks');\n    assert.equal(moment([2013]).weeksInYear(), 52, '2013 has 52 weeks');\n    assert.equal(moment([2014]).weeksInYear(), 52, '2014 has 52 weeks');\n    assert.equal(moment([2015]).weeksInYear(), 52, '2015 has 53 weeks');\n});\n\ntest('weeksInYear doy/dow = 1/7', function (assert) {\n    moment.locale('1/7', {week: {dow: 1, doy: 7}});\n\n    assert.equal(moment([2004]).weeksInYear(), 52, '2004 has 53 weeks');\n    assert.equal(moment([2005]).weeksInYear(), 52, '2005 has 53 weeks');\n    assert.equal(moment([2006]).weeksInYear(), 53, '2006 has 53 weeks');\n    assert.equal(moment([2007]).weeksInYear(), 52, '2007 has 52 weeks');\n    assert.equal(moment([2008]).weeksInYear(), 52, '2008 has 53 weeks');\n    assert.equal(moment([2009]).weeksInYear(), 52, '2009 has 53 weeks');\n    assert.equal(moment([2010]).weeksInYear(), 52, '2010 has 52 weeks');\n    assert.equal(moment([2011]).weeksInYear(), 52, '2011 has 52 weeks');\n    assert.equal(moment([2012]).weeksInYear(), 53, '2012 has 52 weeks');\n    assert.equal(moment([2013]).weeksInYear(), 52, '2013 has 52 weeks');\n    assert.equal(moment([2014]).weeksInYear(), 52, '2014 has 52 weeks');\n    assert.equal(moment([2015]).weeksInYear(), 52, '2015 has 53 weeks');\n});\n\ntest('weeksInYear doy/dow = 0/6', function (assert) {\n    moment.locale('0/6', {week: {dow: 0, doy: 6}});\n\n    assert.equal(moment([2004]).weeksInYear(), 52, '2004 has 53 weeks');\n    assert.equal(moment([2005]).weeksInYear(), 53, '2005 has 53 weeks');\n    assert.equal(moment([2006]).weeksInYear(), 52, '2006 has 53 weeks');\n    assert.equal(moment([2007]).weeksInYear(), 52, '2007 has 52 weeks');\n    assert.equal(moment([2008]).weeksInYear(), 52, '2008 has 53 weeks');\n    assert.equal(moment([2009]).weeksInYear(), 52, '2009 has 53 weeks');\n    assert.equal(moment([2010]).weeksInYear(), 52, '2010 has 52 weeks');\n    assert.equal(moment([2011]).weeksInYear(), 53, '2011 has 52 weeks');\n    assert.equal(moment([2012]).weeksInYear(), 52, '2012 has 52 weeks');\n    assert.equal(moment([2013]).weeksInYear(), 52, '2013 has 52 weeks');\n    assert.equal(moment([2014]).weeksInYear(), 52, '2014 has 52 weeks');\n    assert.equal(moment([2015]).weeksInYear(), 52, '2015 has 53 weeks');\n});\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/test/moment/zone_switching.js",
    "content": "import { module, test, expect } from '../qunit';\nimport moment from '../../moment';\nimport { isNearSpringDST } from '../helpers/dst';\n\nmodule('zone switching');\n\ntest('local to utc, keepLocalTime = true', function (assert) {\n    var m = moment(),\n        fmt = 'YYYY-DD-MM HH:mm:ss';\n    assert.equal(m.clone().utc(true).format(fmt), m.format(fmt), 'local to utc failed to keep local time');\n});\n\ntest('local to utc, keepLocalTime = false', function (assert) {\n    var m = moment();\n    assert.equal(m.clone().utc().valueOf(), m.valueOf(), 'local to utc failed to keep utc time (implicit)');\n    assert.equal(m.clone().utc(false).valueOf(), m.valueOf(), 'local to utc failed to keep utc time (explicit)');\n});\n\ntest('local to zone, keepLocalTime = true', function (assert) {\n    test.expectedDeprecations('moment().zone');\n    var m = moment(),\n        fmt = 'YYYY-DD-MM HH:mm:ss',\n        z;\n\n    // Apparently there is -12:00 and +14:00\n    // https://en.wikipedia.org/wiki/UTC+14:00\n    // https://en.wikipedia.org/wiki/UTC-12:00\n    for (z = -12; z <= 14; ++z) {\n        assert.equal(m.clone().zone(z * 60, true).format(fmt), m.format(fmt),\n                'local to zone(' + z + ':00) failed to keep local time');\n    }\n});\n\ntest('local to zone, keepLocalTime = false', function (assert) {\n    test.expectedDeprecations('moment().zone');\n    var m = moment(),\n        z;\n\n    // Apparently there is -12:00 and +14:00\n    // https://en.wikipedia.org/wiki/UTC+14:00\n    // https://en.wikipedia.org/wiki/UTC-12:00\n    for (z = -12; z <= 14; ++z) {\n        assert.equal(m.clone().zone(z * 60).valueOf(), m.valueOf(),\n                'local to zone(' + z + ':00) failed to keep utc time (implicit)');\n        assert.equal(m.clone().zone(z * 60, false).valueOf(), m.valueOf(),\n                'local to zone(' + z + ':00) failed to keep utc time (explicit)');\n    }\n});\n\ntest('utc to local, keepLocalTime = true', function (assert) {\n    // Don't test near the spring DST transition\n    if (isNearSpringDST()) {\n        expect(0);\n        return;\n    }\n\n    var um = moment.utc(),\n        fmt = 'YYYY-DD-MM HH:mm:ss';\n\n    assert.equal(um.clone().local(true).format(fmt), um.format(fmt), 'utc to local failed to keep local time');\n});\n\ntest('utc to local, keepLocalTime = false', function (assert) {\n    var um = moment.utc();\n    assert.equal(um.clone().local().valueOf(), um.valueOf(), 'utc to local failed to keep utc time (implicit)');\n    assert.equal(um.clone().local(false).valueOf(), um.valueOf(), 'utc to local failed to keep utc time (explicit)');\n});\n\ntest('zone to local, keepLocalTime = true', function (assert) {\n    // Don't test near the spring DST transition\n    if (isNearSpringDST()) {\n        expect(0);\n        return;\n    }\n\n    test.expectedDeprecations('moment().zone');\n\n    var m = moment(),\n        fmt = 'YYYY-DD-MM HH:mm:ss',\n        z;\n\n    // Apparently there is -12:00 and +14:00\n    // https://en.wikipedia.org/wiki/UTC+14:00\n    // https://en.wikipedia.org/wiki/UTC-12:00\n    for (z = -12; z <= 14; ++z) {\n        m.zone(z * 60);\n\n        assert.equal(m.clone().local(true).format(fmt), m.format(fmt),\n                'zone(' + z + ':00) to local failed to keep local time');\n    }\n});\n\ntest('zone to local, keepLocalTime = false', function (assert) {\n    test.expectedDeprecations('moment().zone');\n    var m = moment(),\n        z;\n\n    // Apparently there is -12:00 and +14:00\n    // https://en.wikipedia.org/wiki/UTC+14:00\n    // https://en.wikipedia.org/wiki/UTC-12:00\n    for (z = -12; z <= 14; ++z) {\n        m.zone(z * 60);\n\n        assert.equal(m.clone().local(false).valueOf(), m.valueOf(),\n                'zone(' + z + ':00) to local failed to keep utc time (explicit)');\n        assert.equal(m.clone().local().valueOf(), m.valueOf(),\n                'zone(' + z + ':00) to local failed to keep utc time (implicit)');\n    }\n});\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/test/moment/zones.js",
    "content": "import { module, test } from '../qunit';\nimport moment from '../../moment';\n\nmodule('zones', {\n    'setup': function () {\n        test.expectedDeprecations('moment().zone');\n    }\n});\n\ntest('set zone', function (assert) {\n    var zone = moment();\n\n    zone.zone(0);\n    assert.equal(zone.zone(), 0, 'should be able to set the zone to 0');\n\n    zone.zone(60);\n    assert.equal(zone.zone(), 60, 'should be able to set the zone to 60');\n\n    zone.zone(-60);\n    assert.equal(zone.zone(), -60, 'should be able to set the zone to -60');\n});\n\ntest('set zone shorthand', function (assert) {\n    var zone = moment();\n\n    zone.zone(1);\n    assert.equal(zone.zone(), 60, 'setting the zone to 1 should imply hours and convert to 60');\n\n    zone.zone(-1);\n    assert.equal(zone.zone(), -60, 'setting the zone to -1 should imply hours and convert to -60');\n\n    zone.zone(15);\n    assert.equal(zone.zone(), 900, 'setting the zone to 15 should imply hours and convert to 900');\n\n    zone.zone(-15);\n    assert.equal(zone.zone(), -900, 'setting the zone to -15 should imply hours and convert to -900');\n\n    zone.zone(16);\n    assert.equal(zone.zone(), 16, 'setting the zone to 16 should imply minutes');\n\n    zone.zone(-16);\n    assert.equal(zone.zone(), -16, 'setting the zone to -16 should imply minutes');\n});\n\ntest('set zone with string', function (assert) {\n    var zone = moment();\n\n    zone.zone('+00:00');\n    assert.equal(zone.zone(), 0, 'set the zone with a timezone string');\n\n    zone.zone('2013-03-07T07:00:00-08:00');\n    assert.equal(zone.zone(), 480, 'set the zone with a string that does not begin with the timezone');\n\n    zone.zone('2013-03-07T07:00:00+0100');\n    assert.equal(zone.zone(), -60, 'set the zone with a string that uses the +0000 syntax');\n\n    zone.zone('2013-03-07T07:00:00+02');\n    assert.equal(zone.zone(), -120, 'set the zone with a string that uses the +00 syntax');\n\n    zone.zone('03-07-2013T07:00:00-08:00');\n    assert.equal(zone.zone(), 480, 'set the zone with a string with a non-ISO 8601 date');\n});\n\ntest('change hours when changing the zone', function (assert) {\n    var zone = moment.utc([2000, 0, 1, 6]);\n\n    zone.zone(0);\n    assert.equal(zone.hour(), 6, 'UTC 6AM should be 6AM at +0000');\n\n    zone.zone(60);\n    assert.equal(zone.hour(), 5, 'UTC 6AM should be 5AM at -0100');\n\n    zone.zone(-60);\n    assert.equal(zone.hour(), 7, 'UTC 6AM should be 7AM at +0100');\n});\n\ntest('change minutes when changing the zone', function (assert) {\n    var zone = moment.utc([2000, 0, 1, 6, 31]);\n\n    zone.zone(0);\n    assert.equal(zone.format('HH:mm'), '06:31', 'UTC 6:31AM should be 6:31AM at +0000');\n\n    zone.zone(30);\n    assert.equal(zone.format('HH:mm'), '06:01', 'UTC 6:31AM should be 6:01AM at -0030');\n\n    zone.zone(-30);\n    assert.equal(zone.format('HH:mm'), '07:01', 'UTC 6:31AM should be 7:01AM at +0030');\n\n    zone.zone(1380);\n    assert.equal(zone.format('HH:mm'), '07:31', 'UTC 6:31AM should be 7:31AM at +1380');\n});\n\ntest('distance from the unix epoch', function (assert) {\n    var zoneA = moment(),\n        zoneB = moment(zoneA),\n        zoneC = moment(zoneA),\n        zoneD = moment(zoneA),\n        zoneE = moment(zoneA);\n\n    zoneB.utc();\n    assert.equal(+zoneA, +zoneB, 'moment should equal moment.utc');\n\n    zoneC.zone(-60);\n    assert.equal(+zoneA, +zoneC, 'moment should equal moment.zone(-60)');\n\n    zoneD.zone(480);\n    assert.equal(+zoneA, +zoneD, 'moment should equal moment.zone(480)');\n\n    zoneE.zone(1000);\n    assert.equal(+zoneA, +zoneE, 'moment should equal moment.zone(1000)');\n});\n\ntest('update offset after changing any values', function (assert) {\n    var oldOffset = moment.updateOffset,\n        m = moment.utc([2000, 6, 1]);\n\n    moment.updateOffset = function (mom, keepTime) {\n        if (mom.__doChange) {\n            if (+mom > 962409600000) {\n                mom.zone(120, keepTime);\n            } else {\n                mom.zone(60, keepTime);\n            }\n        }\n    };\n\n    assert.equal(m.format('ZZ'), '+0000', 'should be at +0000');\n    assert.equal(m.format('HH:mm'), '00:00', 'should start 12AM at +0000 timezone');\n\n    m.__doChange = true;\n    m.add(1, 'h');\n\n    assert.equal(m.format('ZZ'), '-0200', 'should be at -0200');\n    assert.equal(m.format('HH:mm'), '23:00', '1AM at +0000 should be 11PM at -0200 timezone');\n\n    m.subtract(1, 'h');\n\n    assert.equal(m.format('ZZ'), '-0100', 'should be at -0100');\n    assert.equal(m.format('HH:mm'), '23:00', '12AM at +0000 should be 11PM at -0100 timezone');\n\n    moment.updateOffset = oldOffset;\n});\n\ntest('getters and setters', function (assert) {\n    var a = moment([2011, 5, 20]);\n\n    assert.equal(a.clone().zone(120).year(2012).year(), 2012, 'should get and set year correctly');\n    assert.equal(a.clone().zone(120).month(1).month(), 1, 'should get and set month correctly');\n    assert.equal(a.clone().zone(120).date(2).date(), 2, 'should get and set date correctly');\n    assert.equal(a.clone().zone(120).day(1).day(), 1, 'should get and set day correctly');\n    assert.equal(a.clone().zone(120).hour(1).hour(), 1, 'should get and set hour correctly');\n    assert.equal(a.clone().zone(120).minute(1).minute(), 1, 'should get and set minute correctly');\n});\n\ntest('getters', function (assert) {\n    var a = moment.utc([2012, 0, 1, 0, 0, 0]);\n\n    assert.equal(a.clone().zone(120).year(),  2011, 'should get year correctly');\n    assert.equal(a.clone().zone(120).month(),   11, 'should get month correctly');\n    assert.equal(a.clone().zone(120).date(),    31, 'should get date correctly');\n    assert.equal(a.clone().zone(120).hour(),    22, 'should get hour correctly');\n    assert.equal(a.clone().zone(120).minute(),   0, 'should get minute correctly');\n\n    assert.equal(a.clone().zone(-120).year(),  2012, 'should get year correctly');\n    assert.equal(a.clone().zone(-120).month(),    0, 'should get month correctly');\n    assert.equal(a.clone().zone(-120).date(),     1, 'should get date correctly');\n    assert.equal(a.clone().zone(-120).hour(),     2, 'should get hour correctly');\n    assert.equal(a.clone().zone(-120).minute(),   0, 'should get minute correctly');\n\n    assert.equal(a.clone().zone(-90).year(),  2012, 'should get year correctly');\n    assert.equal(a.clone().zone(-90).month(),    0, 'should get month correctly');\n    assert.equal(a.clone().zone(-90).date(),     1, 'should get date correctly');\n    assert.equal(a.clone().zone(-90).hour(),     1, 'should get hour correctly');\n    assert.equal(a.clone().zone(-90).minute(),  30, 'should get minute correctly');\n});\n\ntest('from', function (assert) {\n    var zoneA = moment(),\n        zoneB = moment(zoneA).zone(720),\n        zoneC = moment(zoneA).zone(360),\n        zoneD = moment(zoneA).zone(-690),\n        other = moment(zoneA).add(35, 'm');\n\n    assert.equal(zoneA.from(other), zoneB.from(other), 'moment#from should be the same in all zones');\n    assert.equal(zoneA.from(other), zoneC.from(other), 'moment#from should be the same in all zones');\n    assert.equal(zoneA.from(other), zoneD.from(other), 'moment#from should be the same in all zones');\n});\n\ntest('diff', function (assert) {\n    var zoneA = moment(),\n        zoneB = moment(zoneA).zone(720),\n        zoneC = moment(zoneA).zone(360),\n        zoneD = moment(zoneA).zone(-690),\n        other = moment(zoneA).add(35, 'm');\n\n    assert.equal(zoneA.diff(other), zoneB.diff(other), 'moment#diff should be the same in all zones');\n    assert.equal(zoneA.diff(other), zoneC.diff(other), 'moment#diff should be the same in all zones');\n    assert.equal(zoneA.diff(other), zoneD.diff(other), 'moment#diff should be the same in all zones');\n\n    assert.equal(zoneA.diff(other, 'minute', true), zoneB.diff(other, 'minute', true), 'moment#diff should be the same in all zones');\n    assert.equal(zoneA.diff(other, 'minute', true), zoneC.diff(other, 'minute', true), 'moment#diff should be the same in all zones');\n    assert.equal(zoneA.diff(other, 'minute', true), zoneD.diff(other, 'minute', true), 'moment#diff should be the same in all zones');\n\n    assert.equal(zoneA.diff(other, 'hour', true), zoneB.diff(other, 'hour', true), 'moment#diff should be the same in all zones');\n    assert.equal(zoneA.diff(other, 'hour', true), zoneC.diff(other, 'hour', true), 'moment#diff should be the same in all zones');\n    assert.equal(zoneA.diff(other, 'hour', true), zoneD.diff(other, 'hour', true), 'moment#diff should be the same in all zones');\n});\n\ntest('unix offset and timestamp', function (assert) {\n    var zoneA = moment(),\n        zoneB = moment(zoneA).zone(720),\n        zoneC = moment(zoneA).zone(360),\n        zoneD = moment(zoneA).zone(-690);\n\n    assert.equal(zoneA.unix(), zoneB.unix(), 'moment#unix should be the same in all zones');\n    assert.equal(zoneA.unix(), zoneC.unix(), 'moment#unix should be the same in all zones');\n    assert.equal(zoneA.unix(), zoneD.unix(), 'moment#unix should be the same in all zones');\n\n    assert.equal(+zoneA, +zoneB, 'moment#valueOf should be the same in all zones');\n    assert.equal(+zoneA, +zoneC, 'moment#valueOf should be the same in all zones');\n    assert.equal(+zoneA, +zoneD, 'moment#valueOf should be the same in all zones');\n});\n\ntest('cloning', function (assert) {\n    assert.equal(moment().zone(120).clone().zone(),   120, 'explicit cloning should retain the zone');\n    assert.equal(moment().zone(-120).clone().zone(), -120, 'explicit cloning should retain the zone');\n    assert.equal(moment(moment().zone(120)).zone(),   120, 'implicit cloning should retain the zone');\n    assert.equal(moment(moment().zone(-120)).zone(), -120, 'implicit cloning should retain the zone');\n});\n\ntest('start of / end of', function (assert) {\n    var a = moment.utc([2010, 1, 2, 0, 0, 0]).zone(450);\n\n    assert.equal(a.clone().startOf('day').hour(), 0, 'start of day should work on moments with a zone');\n    assert.equal(a.clone().startOf('day').minute(), 0, 'start of day should work on moments with a zone');\n    assert.equal(a.clone().startOf('hour').minute(), 0, 'start of hour should work on moments with a zone');\n\n    assert.equal(a.clone().endOf('day').hour(), 23, 'end of day should work on moments with a zone');\n    assert.equal(a.clone().endOf('day').minute(), 59, 'end of day should work on moments with a zone');\n    assert.equal(a.clone().endOf('hour').minute(), 59, 'end of hour should work on moments with a zone');\n});\n\ntest('reset zone with moment#utc', function (assert) {\n    var a = moment.utc([2012]).zone(480);\n\n    assert.equal(a.clone().hour(),      16, 'different zone should have different hour');\n    assert.equal(a.clone().utc().hour(), 0, 'calling moment#utc should reset the offset');\n});\n\ntest('reset zone with moment#local', function (assert) {\n    var a = moment([2012]).zone(480);\n\n    assert.equal(a.clone().local().hour(), 0, 'calling moment#local should reset the offset');\n});\n\ntest('toDate', function (assert) {\n    var zoneA = new Date(),\n        zoneB = moment(zoneA).zone(720).toDate(),\n        zoneC = moment(zoneA).zone(360).toDate(),\n        zoneD = moment(zoneA).zone(-690).toDate();\n\n    assert.equal(+zoneA, +zoneB, 'moment#toDate should output a date with the right unix timestamp');\n    assert.equal(+zoneA, +zoneC, 'moment#toDate should output a date with the right unix timestamp');\n    assert.equal(+zoneA, +zoneD, 'moment#toDate should output a date with the right unix timestamp');\n});\n\ntest('same / before / after', function (assert) {\n    var zoneA = moment().utc(),\n        zoneB = moment(zoneA).zone(120),\n        zoneC = moment(zoneA).zone(-120);\n\n    assert.ok(zoneA.isSame(zoneB), 'two moments with different offsets should be the same');\n    assert.ok(zoneA.isSame(zoneC), 'two moments with different offsets should be the same');\n\n    assert.ok(zoneA.isSame(zoneB, 'hour'), 'two moments with different offsets should be the same hour');\n    assert.ok(zoneA.isSame(zoneC, 'hour'), 'two moments with different offsets should be the same hour');\n\n    zoneA.add(1, 'hour');\n\n    assert.ok(zoneA.isAfter(zoneB), 'isAfter should work with two moments with different offsets');\n    assert.ok(zoneA.isAfter(zoneC), 'isAfter should work with two moments with different offsets');\n\n    assert.ok(zoneA.isAfter(zoneB, 'hour'), 'isAfter:hour should work with two moments with different offsets');\n    assert.ok(zoneA.isAfter(zoneC, 'hour'), 'isAfter:hour should work with two moments with different offsets');\n\n    zoneA.subtract(2, 'hour');\n\n    assert.ok(zoneA.isBefore(zoneB), 'isBefore should work with two moments with different offsets');\n    assert.ok(zoneA.isBefore(zoneC), 'isBefore should work with two moments with different offsets');\n\n    assert.ok(zoneA.isBefore(zoneB, 'hour'), 'isBefore:hour should work with two moments with different offsets');\n    assert.ok(zoneA.isBefore(zoneC, 'hour'), 'isBefore:hour should work with two moments with different offsets');\n});\n\ntest('add / subtract over dst', function (assert) {\n    var oldOffset = moment.updateOffset,\n        m = moment.utc([2000, 2, 31, 3]);\n\n    moment.updateOffset = function (mom, keepTime) {\n        if (mom.clone().utc().month() > 2) {\n            mom.zone(-60, keepTime);\n        } else {\n            mom.zone(0, keepTime);\n        }\n    };\n\n    assert.equal(m.hour(), 3, 'should start at 00:00');\n\n    m.add(24, 'hour');\n\n    assert.equal(m.hour(), 4, 'adding 24 hours should disregard dst');\n\n    m.subtract(24, 'hour');\n\n    assert.equal(m.hour(), 3, 'subtracting 24 hours should disregard dst');\n\n    m.add(1, 'day');\n\n    assert.equal(m.hour(), 3, 'adding 1 day should have the same hour');\n\n    m.subtract(1, 'day');\n\n    assert.equal(m.hour(), 3, 'subtracting 1 day should have the same hour');\n\n    m.add(1, 'month');\n\n    assert.equal(m.hour(), 3, 'adding 1 month should have the same hour');\n\n    m.subtract(1, 'month');\n\n    assert.equal(m.hour(), 3, 'subtracting 1 month should have the same hour');\n\n    moment.updateOffset = oldOffset;\n});\n\ntest('isDST', function (assert) {\n    var oldOffset = moment.updateOffset;\n\n    moment.updateOffset = function (mom, keepTime) {\n        if (mom.month() > 2 && mom.month() < 9) {\n            mom.zone(-60, keepTime);\n        } else {\n            mom.zone(0, keepTime);\n        }\n    };\n\n    assert.ok(!moment().month(0).isDST(),  'Jan should not be summer dst');\n    assert.ok(moment().month(6).isDST(),   'Jul should be summer dst');\n    assert.ok(!moment().month(11).isDST(), 'Dec should not be summer dst');\n\n    moment.updateOffset = function (mom) {\n        if (mom.month() > 2 && mom.month() < 9) {\n            mom.zone(0);\n        } else {\n            mom.zone(-60);\n        }\n    };\n\n    assert.ok(moment().month(0).isDST(),  'Jan should be winter dst');\n    assert.ok(!moment().month(6).isDST(), 'Jul should not be winter dst');\n    assert.ok(moment().month(11).isDST(), 'Dec should be winter dst');\n\n    moment.updateOffset = oldOffset;\n});\n\ntest('zone names', function (assert) {\n    test.expectedDeprecations();\n    assert.equal(moment().zoneAbbr(),   '', 'Local zone abbr should be empty');\n    assert.equal(moment().format('z'),  '', 'Local zone formatted abbr should be empty');\n    assert.equal(moment().zoneName(),   '', 'Local zone name should be empty');\n    assert.equal(moment().format('zz'), '', 'Local zone formatted name should be empty');\n\n    assert.equal(moment.utc().zoneAbbr(),   'UTC', 'UTC zone abbr should be UTC');\n    assert.equal(moment.utc().format('z'),  'UTC', 'UTC zone formatted abbr should be UTC');\n    assert.equal(moment.utc().zoneName(),   'Coordinated Universal Time', 'UTC zone abbr should be Coordinated Universal Time');\n    assert.equal(moment.utc().format('zz'), 'Coordinated Universal Time', 'UTC zone formatted abbr should be Coordinated Universal Time');\n});\n\ntest('hours alignment with UTC', function (assert) {\n    assert.equal(moment().zone(120).hasAlignedHourOffset(), true);\n    assert.equal(moment().zone(-180).hasAlignedHourOffset(), true);\n    assert.equal(moment().zone(90).hasAlignedHourOffset(), false);\n    assert.equal(moment().zone(-90).hasAlignedHourOffset(), false);\n});\n\ntest('hours alignment with other zone', function (assert) {\n    var m = moment().zone(120);\n\n    assert.equal(m.hasAlignedHourOffset(moment().zone(180)), true);\n    assert.equal(m.hasAlignedHourOffset(moment().zone(-180)), true);\n    assert.equal(m.hasAlignedHourOffset(moment().zone(90)), false);\n    assert.equal(m.hasAlignedHourOffset(moment().zone(-90)), false);\n\n    m = moment().zone(90);\n\n    assert.equal(m.hasAlignedHourOffset(moment().zone(180)), false);\n    assert.equal(m.hasAlignedHourOffset(moment().zone(-180)), false);\n    assert.equal(m.hasAlignedHourOffset(moment().zone(30)), true);\n    assert.equal(m.hasAlignedHourOffset(moment().zone(-30)), true);\n\n    m = moment().zone(-60);\n\n    assert.equal(m.hasAlignedHourOffset(moment().zone(180)), true);\n    assert.equal(m.hasAlignedHourOffset(moment().zone(-180)), true);\n    assert.equal(m.hasAlignedHourOffset(moment().zone(90)), false);\n    assert.equal(m.hasAlignedHourOffset(moment().zone(-90)), false);\n\n    m = moment().zone(25);\n\n    assert.equal(m.hasAlignedHourOffset(moment().zone(-35)), true);\n    assert.equal(m.hasAlignedHourOffset(moment().zone(85)), true);\n\n    assert.equal(m.hasAlignedHourOffset(moment().zone(35)), false);\n    assert.equal(m.hasAlignedHourOffset(moment().zone(-85)), false);\n});\n\ntest('parse zone', function (assert) {\n    var m = moment('2013-01-01T00:00:00-13:00').parseZone();\n    assert.equal(m.zone(), 13 * 60);\n    assert.equal(m.hours(), 0);\n});\n\ntest('parse zone static', function (assert) {\n    var m = moment.parseZone('2013-01-01T00:00:00-13:00');\n    assert.equal(m.zone(), 13 * 60);\n    assert.equal(m.hours(), 0);\n});\n\ntest('parse zone with more arguments', function (assert) {\n    test.expectedDeprecations();\n    var m;\n    m = moment.parseZone('2013 01 01 05 -13:00', 'YYYY MM DD HH ZZ');\n    assert.equal(m.format(), '2013-01-01T05:00:00-13:00', 'accept input and format');\n    m = moment.parseZone('2013-01-01-13:00', 'YYYY MM DD ZZ', true);\n    assert.equal(m.isValid(), false, 'accept input, format and strict flag');\n    m = moment.parseZone('2013-01-01-13:00', ['DD MM YYYY ZZ', 'YYYY MM DD ZZ']);\n    assert.equal(m.format(), '2013-01-01T00:00:00-13:00', 'accept input and array of formats');\n});\n\ntest('parse zone with a timezone from the format string', function (assert) {\n    var m = moment('11-12-2013 -0400 +1100', 'DD-MM-YYYY ZZ #####').parseZone();\n\n    assert.equal(m.zone(), 4 * 60);\n});\n\ntest('parse zone without a timezone included in the format string', function (assert) {\n    var m = moment('11-12-2013 -0400 +1100', 'DD-MM-YYYY').parseZone();\n\n    assert.equal(m.zone(), -11 * 60);\n});\n\ntest('timezone format', function (assert) {\n    assert.equal(moment().zone(-60).format('ZZ'), '+0100', '-60 -> +0100');\n    assert.equal(moment().zone(-90).format('ZZ'), '+0130', '-90 -> +0130');\n    assert.equal(moment().zone(-120).format('ZZ'), '+0200', '-120 -> +0200');\n\n    assert.equal(moment().zone(+60).format('ZZ'), '-0100', '+60 -> -0100');\n    assert.equal(moment().zone(+90).format('ZZ'), '-0130', '+90 -> -0130');\n    assert.equal(moment().zone(+120).format('ZZ'), '-0200', '+120 -> -0200');\n});\n\ntest('parse zone without a timezone', function (assert) {\n    test.expectedDeprecations();\n    var m1 = moment.parseZone('2016-02-01T00:00:00');\n    var m2 = moment.parseZone('2016-02-01T00:00:00Z');\n    var m3 = moment.parseZone('2016-02-01T00:00:00+00:00'); //Someone might argue this is not necessary, you could even argue that is wrong being here.\n    var m4 = moment.parseZone('2016-02-01T00:00:00+0000'); //Someone might argue this is not necessary, you could even argue that is wrong being here.\n    assert.equal(\n        m1.format('M D YYYY HH:mm:ss ZZ'),\n        '2 1 2016 00:00:00 +0000',\n        'Not providing a timezone should keep the time and change the zone to 0'\n    );\n    assert.equal(\n        m2.format('M D YYYY HH:mm:ss ZZ'),\n        '2 1 2016 00:00:00 +0000',\n        'Not providing a timezone should keep the time and change the zone to 0'\n    );\n    assert.equal(\n        m3.format('M D YYYY HH:mm:ss ZZ'),\n        '2 1 2016 00:00:00 +0000',\n        'Not providing a timezone should keep the time and change the zone to 0'\n    );\n    assert.equal(\n        m4.format('M D YYYY HH:mm:ss ZZ'),\n        '2 1 2016 00:00:00 +0000',\n        'Not providing a timezone should keep the time and change the zone to 0'\n    );\n});\n\ntest('parse zone with a minutes unit abs less than 16 should retain minutes', function (assert) {\n    //ensure when minutes are explicitly parsed, they are retained\n    //instead of converted to hours, even if less than 16\n    var n = moment.parseZone('2013-01-01T00:00:00-00:15');\n    assert.equal(n.utcOffset(), -15);\n    assert.equal(n.zone(), 15);\n    assert.equal(n.hour(), 0);\n    var o = moment.parseZone('2013-01-01T00:00:00+00:15');\n    assert.equal(o.utcOffset(), 15);\n    assert.equal(o.zone(), -15);\n    assert.equal(o.hour(), 0);\n});\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/src/test/qunit.js",
    "content": "/*global QUnit:false*/\n\nimport moment from '../moment';\nimport { defineCommonLocaleTests } from './helpers/common-locale';\nimport { setupDeprecationHandler, teardownDeprecationHandler } from './helpers/deprecation-handler';\n\nexport var test = QUnit.test;\n\nexport var expect = QUnit.expect;\n\nexport function module (name, lifecycle) {\n    QUnit.module(name, {\n        setup : function () {\n            moment.locale('en');\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'core');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            teardownDeprecationHandler(test, moment, 'core');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n}\n\nexport function localeModule (name, lifecycle) {\n    QUnit.module('locale:' + name, {\n        setup : function () {\n            moment.locale(name);\n            moment.createFromInputFallback = function (config) {\n                throw new Error('input not handled by moment: ' + config._i);\n            };\n            setupDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.setup) {\n                lifecycle.setup();\n            }\n        },\n        teardown : function () {\n            moment.locale('en');\n            teardownDeprecationHandler(test, moment, 'locale');\n            if (lifecycle && lifecycle.teardown) {\n                lifecycle.teardown();\n            }\n        }\n    });\n    defineCommonLocaleTests(name, -1, -1);\n}\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/tasks/bump_version.js",
    "content": "module.exports = function (grunt) {\n    grunt.registerTask('bump_version', function (version) {\n        if (!version || version.split('.').length !== 3) {\n            grunt.fail.fatal('malformed version. Use\\n\\n    grunt bump_version:1.2.3');\n        }\n\n        grunt.config('string-replace.moment-js', {\n            files: {'src/moment.js': 'src/moment.js'},\n            options: {\n                replacements: [\n                    {\n                        pattern:     /\\/\\/! version : .*/,\n                        replacement: '//! version : ' + version\n                    }, {\n                        pattern:     /moment\\.version = '.*'/,\n                        replacement: \"moment.version = '\" + version + \"'\"\n                    }\n                ]\n            }\n        });\n\n        grunt.config('string-replace.package-json', {\n            files: {'package.json': 'package.json'},\n            options: {\n                replacements: [\n                    {\n                        pattern:     /\"version\": .*/,\n                        replacement: '\"version\": \"' + version + '\",'\n                    }\n                ]\n            }\n        });\n\n        grunt.config('string-replace.component-json', {\n            files: {'component.json': 'component.json'},\n            options: {\n                replacements: [\n                    {\n                        pattern:     /\"version\": .*/,\n                        replacement: '\"version\": \"' + version + '\",'\n                    }\n                ]\n            }\n        });\n\n        grunt.config('string-replace.moment-js-nuspec', {\n            files: {'Moment.js.nuspec': 'Moment.js.nuspec'},\n            options: {\n                replacements: [\n                    {\n                        pattern:     /<version>.*<\\/version>/,\n                        replacement: '<version>' + version + '</version>'\n                    }\n                ]\n            }\n        });\n\n        grunt.config('string-replace.meteor-package-js', {\n            files: {'meteor/package.js': 'meteor/package.js'},\n            options: {\n                replacements: [\n                    {\n                        pattern:     /version: .*/,\n                        replacement: 'version: \\'' + version + '\\','\n                    }\n                ]\n            }\n        });\n\n        grunt.task.run([\n            'string-replace:moment-js',\n            'string-replace:package-json',\n            'string-replace:component-json',\n            'string-replace:moment-js-nuspec',\n            'string-replace:meteor-package-js'\n        ]);\n    });\n};\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/tasks/check_sauce_creds.js",
    "content": "module.exports = function (grunt) {\n    // Pull requests do not have secure variables enabled for security reasons.\n    // Use this task before launching travis-sauce-browser task, so it would\n    // exit early and won't try connecting to SauceLabs without credentials.\n    grunt.registerTask('check-sauce-creds', function () {\n        if (process.env.SAUCE_USERNAME === undefined) {\n            grunt.log.writeln('No sauce credentials found');\n            grunt.task.clearQueue();\n        } else {\n            grunt.log.writeln('Sauce credentials found');\n        }\n    });\n};\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/tasks/component.js",
    "content": "module.exports = function (grunt) {\n    grunt.registerTask('component', function () {\n        var config = JSON.parse(grunt.file.read('component.json'));\n\n        config.files = grunt.file.expand('locale/*.js');\n        config.files.unshift('moment.js');\n\n        grunt.file.write('component.json', JSON.stringify(config, true, 2) + '\\n');\n    });\n};\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/tasks/nuget.js",
    "content": "module.exports = function (grunt) {\n    // To set up on mac:\n    // * brew install nuget # this fetches mono\n    // * go to nuget.org, login, click on username (top right), copy api-key\n    //   from the bottom\n    // * grunt nugetkey --key=XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX\n    // * grunt nuget-publish\n    //\n    //\n    // If this fails you might need to follow:\n    //\n    // http://stackoverflow.com/questions/15181888/nuget-on-linux-error-getting-response-stream\n    //\n    // $ sudo mozroots --import --machine --sync\n    // $ sudo certmgr -ssl -m https://go.microsoft.com\n    // $ sudo certmgr -ssl -m https://nugetgallery.blob.core.windows.net\n    // $ sudo certmgr -ssl -m https://nuget.org\n\n    grunt.config('nugetpack', {\n        dist: {\n            src: 'Moment.js.nuspec',\n            dest: './'\n        }\n    });\n    grunt.registerTask('nugetkey_pre', function () {\n        grunt.option('key', process.env.NUGET_KEY);\n        grunt.option('source', 'https://www.nuget.org/api/v2/package');\n    });\n    grunt.registerTask('nugetkey_post', function () {\n        grunt.option('key', null);\n        grunt.option('source', null);\n    });\n    grunt.config('nugetpush', {\n        dist: {\n            src: 'Moment.js.*.nupkg'\n        }\n    });\n    grunt.config('clean.nuget', {\n        src: 'Moment.js.*.nupkg'\n    });\n\n    grunt.registerTask('nuget-publish', [\n        'nugetpack', 'nugetkey_pre', 'nugetkey', 'nugetkey_post', 'nugetpush', 'clean:nuget'\n    ]);\n};\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/tasks/qtest.js",
    "content": "module.exports = function (grunt) {\n    grunt.task.registerTask('qtest', 'run tests locally', function () {\n        var done = this.async();\n\n        var testrunner = require('qunit');\n\n        testrunner.options.log.assertions = false;\n        testrunner.options.log.tests = false;\n        testrunner.options.log.summary = false;\n        testrunner.options.log.testing = false;\n        testrunner.options.maxBlockDuration = 120000;\n\n        var tests;\n\n        if (grunt.option('only') != null) {\n            tests = grunt.file.expand.apply(null, grunt.option('only').split(',').map(function (file) {\n                if (file === 'moment') {\n                    return 'build/umd/test/moment/*.js';\n                } else if (file === 'locale') {\n                    return 'build/umd/test/locale/*.js';\n                } else {\n                    return 'build/umd/test/' + file + '.js';\n                }\n            }));\n        } else {\n            tests = grunt.file.expand('build/umd/test/moment/*.js',\n                'build/umd/test/locale/*.js');\n        }\n\n        testrunner.run({\n            code: 'build/umd/moment.js',\n            tests: tests\n        }, function (err, report) {\n            if (err) {\n                console.log('woot', err, report);\n                done(err);\n                return;\n            }\n            err = null;\n            if (report.failed !== 0) {\n                err = new Error(report.failed + ' tests failed');\n            }\n            done(err);\n        });\n    });\n};\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/tasks/transpile.js",
    "content": "module.exports = function (grunt) {\n    // var esperanto = require('esperanto');\n    var rollup = require('rollup').rollup;\n    // var babel = require('rollup-plugin-babel');\n    var path = require('path');\n    var Promise = require('es6-promise').Promise;\n    var TMP_DIR = 'build/tmp';\n\n    function moveComments(code, moveType) {\n        var comments = [], rest = [], skipId = -1;\n        code.split('\\n').forEach(function (line, i) {\n            var isComment = false;\n            if (line.trim().slice(0, 3) === '//!') {\n                isComment = true;\n            }\n            if (isComment && moveType === 'main-only') {\n                if (i === skipId + 1 ||\n                        line.trim() === '//! moment.js locale configuration') {\n                    skipId = i;\n                    // continue to next line\n                    return;\n                }\n            }\n\n            if (isComment) {\n                comments.push(line.trim());\n            } else {\n                rest.push(line);\n            }\n        });\n\n        return comments.concat([''], rest).join('\\n');\n    }\n\n    var headerCache = {};\n    function getHeaderByFile(headerFile) {\n        if (headerFile === 'none') {\n            return '';\n        }\n        if (!(headerFile in headerCache)) {\n            headerCache[headerFile] = grunt.file.read(headerFile);\n        }\n        return headerCache[headerFile];\n    }\n\n    function rollupBundle(opts) {\n        // entry, umdName, skipMoment\n\n        var rollupOpts = {\n            entry: opts.entry,\n            plugins: [\n                // babel({})\n            ]\n        }, bundleOpts = {\n            format: 'umd',\n            moduleName: opts.umdName != null ? opts.umdName : 'not_used'\n        };\n\n        if (opts.skipMoment) {\n            // And this is what people call progress?\n            rollupOpts.external = [\n                './moment',\n                '../moment',\n                '../../moment',\n                path.resolve('src/moment'),\n                path.resolve('build/tmp/moment')\n            ];\n            bundleOpts.globals = {};\n            bundleOpts.globals[path.resolve('src/moment')] = 'moment';\n            bundleOpts.globals[path.resolve('build/tmp/moment')] = 'moment';\n        }\n\n        return rollup(rollupOpts).then(function (bundle) {\n            var result = bundle.generate(bundleOpts);\n            return result.code;\n        });\n    }\n\n    function transpile(opts) {\n        // base, entry, skipMoment, headerFile, skipLines, target\n        var umdName = opts.headerFile != null && opts.headerFile !== 'none' ? 'not_used' : opts.umdName,\n            headerFile = opts.headerFile ? opts.headerFile : 'templates/default.js',\n            header = getHeaderByFile(headerFile),\n            skipLines = opts.skipLines != null ? opts.skipLines : 5;\n\n        return rollupBundle({\n            entry: path.join(opts.base, opts.entry),\n            skipMoment: opts.skipMoment != null ? opts.skipMoment : false,\n            umdName: umdName\n        }).then(function (code) {\n            var fixed = header + code.split('\\n').slice(skipLines).join('\\n');\n            if (opts.moveComments) {\n                fixed = moveComments(fixed, opts.moveComments);\n            }\n            grunt.file.write(opts.target, fixed);\n        });\n    }\n\n    function transpileMany(opts) {\n        var batchSize = 50,\n            promise = Promise.resolve(null),\n            files = grunt.file.expand({cwd: opts.base}, opts.pattern),\n            i,\n            transpileOne = function (i) {\n                promise = promise.then(function () {\n                    return Promise.all(files.slice(i, i + batchSize).map(function (file) {\n                        return transpile({\n                            base: opts.base,\n                            entry: file,\n                            headerFile: opts.headerFile,\n                            skipMoment: opts.skipMoment,\n                            skipLines: opts.skipLines,\n                            moveComments: opts.moveComments,\n                            target: path.join(opts.targetDir, file)\n                        });\n                    }));\n                });\n            };\n\n        for (i = 0; i < files.length; i += batchSize) {\n            transpileOne(i);\n        }\n\n        return promise;\n    }\n\n    function prepareTemp(base) {\n        var files = grunt.file.expand({cwd: base}, '**/*.js'),\n            tmpDir = TMP_DIR;\n        if (grunt.file.exists(tmpDir)) {\n            return;\n        }\n        files.forEach(function (file) {\n            grunt.file.copy(path.join(base, file), path.join(tmpDir, file));\n        });\n    }\n\n    function transpileCode(opts) {\n        var entry = opts.entry || path.basename(opts.target);\n        prepareTemp(opts.base);\n        grunt.file.write(path.join(TMP_DIR, entry), opts.code);\n        return transpile({\n            base: TMP_DIR,\n            entry: entry,\n            umdName: opts.umdName || 'not_used',\n            headerFile: opts.headerFile,\n            skipLines: opts.skipLines,\n            moveComments: opts.moveComments,\n            target: opts.target,\n            skipMoment: opts.skipMoment\n        });\n    }\n\n    function generateLocales(target, localeFiles, opts) {\n        var files = localeFiles,\n            code = [\n                'import moment from \"./moment\";',\n                'export default moment;'\n            ].concat(files.map(function (file) {\n                var identifier = path.basename(file, '.js').replace('-', '_');\n                return 'import ' + identifier + ' from \"./' + file + '\";';\n            })).concat([\n                // Reset the language back to 'en', because every defineLocale\n                // also sets it.\n                'moment.locale(\\'en\\');'\n            ]).join('\\n');\n        return transpileCode({\n            base: 'src',\n            code: code,\n            target: target,\n            skipMoment: opts.skipMoment,\n            headerFile: opts.skipMoment === true ? 'templates/locale-header.js' : 'templates/default.js',\n            skipLines: opts.skipMoment === true ? 7 : 5\n        });\n    }\n\n    grunt.task.registerTask('transpile-raw', 'convert es6 to umd', function () {\n        var done = this.async();\n\n        transpile({\n            base: 'src',\n            entry: 'moment.js',\n            umdName: 'moment',\n            target: 'build/umd/moment.js',\n            skipLines: 5,\n            moveComments: true\n        }).then(function () {\n            grunt.log.ok('build/umd/moment.js');\n        }).then(function () {\n            return transpileMany({\n                base: 'src',\n                pattern: 'locale/*.js',\n                headerFile: 'templates/locale-header.js',\n                skipLines: 7,\n                moveComments: true,\n                targetDir: 'build/umd',\n                skipMoment: true\n            });\n        }).then(function () {\n            grunt.log.ok('build/umd/locale/*.js');\n        }).then(function () {\n            return transpileMany({\n                base: 'src',\n                pattern: 'test/moment/*.js',\n                headerFile: 'templates/test-header.js',\n                skipLines: 7,\n                moveComments: true,\n                targetDir: 'build/umd',\n                skipMoment: true\n            });\n        }).then(function () {\n            grunt.log.ok('build/umd/test/moment/*.js');\n        }).then(function () {\n            return transpileMany({\n                base: 'src',\n                pattern: 'test/locale/*.js',\n                headerFile: 'templates/test-header.js',\n                skipLines: 7,\n                moveComments: true,\n                targetDir: 'build/umd',\n                skipMoment: true\n            });\n        }).then(function () {\n            grunt.log.ok('build/umd/test/locale/*.js');\n        }).then(function () {\n            return generateLocales(\n                'build/umd/min/locales.js',\n                grunt.file.expand({cwd: 'src'}, 'locale/*.js'),\n                {skipMoment: true}\n            );\n        }).then(function () {\n            grunt.log.ok('build/umd/min/locales.js');\n        }).then(function () {\n            return generateLocales(\n                'build/umd/min/moment-with-locales.js',\n                grunt.file.expand({cwd: 'src'}, 'locale/*.js'),\n                {skipMoment: false}\n            );\n        }).then(function () {\n            grunt.log.ok('build/umd/min/moment-with-locales.js');\n        }).then(done, function (e) {\n            grunt.log.error('error transpiling', e);\n            done(e);\n        });\n    });\n\n    grunt.task.registerTask('transpile-custom-raw',\n            'build just custom language bundles',\n            function (locales) {\n        var done = this.async();\n\n        var localeFiles = locales.split(',').map(function (locale) {\n            var file = grunt.file.expand({cwd: 'src'}, 'locale/' + locale + '.js');\n            if (file.length !== 1) {\n                // we failed to find a locale\n                done(new Error('could not find locale: ' + locale));\n                done = null;\n            } else {\n                return file[0];\n            }\n        });\n\n        // There was an issue with a locale\n        if (done == null) {\n            return;\n        }\n\n        return generateLocales(\n            'build/umd/min/locales.custom.js',\n            localeFiles,\n            {skipMoment: true}\n        ).then(function () {\n            grunt.log.ok('build/umd/min/locales.custom.js');\n        }).then(function () {\n            return generateLocales(\n                'build/umd/min/moment-with-locales.custom.js',\n                localeFiles,\n                {skipMoment: false});\n        }).then(function () {\n            grunt.log.ok('build/umd/min/moment-with-locales.custom.js');\n        }).then(function () {\n            var moment = require('../build/umd/min/moment-with-locales.custom.js');\n            if (moment.locales().filter(function (locale) {\n                return locale !== 'en';\n            }).length !== localeFiles.length) {\n                throw new Error(\n                    'You probably specified locales requiring ' +\n                    'parent locale, but didn\\'t specify parent');\n            }\n        }).then(done, function (e) {\n            grunt.log.error('error transpiling-custom', e);\n            done(e);\n        });\n    });\n\n    grunt.config('clean.build', [\n        'build'\n    ]);\n\n    grunt.config('concat.tests', {\n        src: 'build/umd/test/**/*.js',\n        dest: 'build/umd/min/tests.js'\n    });\n\n    grunt.task.registerTask('transpile',\n            'builds all es5 files, optinally creating custom locales',\n            function (locales) {\n        var tasks = [\n            'clean:build',\n            'transpile-raw',\n            'concat:tests'\n        ];\n\n        if (locales) {\n            tasks.push('transpile-custom-raw:' + locales);\n        }\n\n        grunt.task.run(tasks);\n    });\n};\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/tasks/update_index.js",
    "content": "module.exports = function (grunt) {\n    grunt.config('copy.index-files', {\n        expand: true,\n        cwd: 'build/umd/',\n        src: [\n            'moment.js',\n            'locale/*.js',\n            'min/locales.js',\n            'min/moment-with-locales.js',\n            'min/tests.js'\n        ],\n        dest: '.'\n    });\n\n    grunt.registerTask('update-index', ['copy:index-files']);\n};\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/templates/default.js",
    "content": ";(function (global, factory) {\n    typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :\n    typeof define === 'function' && define.amd ? define(factory) :\n    global.moment = factory()\n}(this, (function () { 'use strict';\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/templates/locale-header.js",
    "content": ";(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/templates/test-header.js",
    "content": ";(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined'\n       && typeof require === 'function' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, (function (moment) { 'use strict';\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/typing-tests/moment-tests.ts",
    "content": "/// <reference path=\"../moment.d.ts\" />\nimport moment = require('../moment');\n\nmoment().add('hours', 1).fromNow();\n\nvar day = new Date(2011, 9, 16);\nvar dayWrapper = moment(day);\nvar otherDay = moment(new Date(2020, 3, 7));\n\nvar day1 = moment(1318781876406);\nvar day2 = moment.unix(1318781876);\nvar day3 = moment(\"Dec 25, 1995\");\nvar day4 = moment(\"12-25-1995\", \"MM-DD-YYYY\");\nvar day5 = moment(\"12-25-1995\", [\"MM-DD-YYYY\", \"YYYY-MM-DD\"]);\nvar day6 = moment(\"05-06-1995\", [\"MM-DD-YYYY\", \"DD-MM-YYYY\"]);\nvar now = moment();\nvar day7 = moment([2010, 1, 14, 15, 25, 50, 125]);\nvar day8 = moment([2010]);\nvar day9 = moment([2010, 6]);\nvar day10 = moment([2010, 6, 10]);\nvar array = [2010, 1, 14, 15, 25, 50, 125];\nvar day11 = moment(Date.UTC.apply({}, array));\nvar day12 = moment.unix(1318781876);\n\n// TODO: reenable in 2.0\n// moment(null);\nmoment(undefined);\nmoment({ years: 2010, months: 3, days: 5, hours: 15, minutes: 10, seconds: 3, milliseconds: 123 });\nmoment(\"20140101\", \"YYYYMMDD\", true);\nmoment(\"20140101\", \"YYYYMMDD\", \"en\");\nmoment(\"20140101\", \"YYYYMMDD\", \"en\", true);\nmoment(\"20140101\", [\"YYYYMMDD\"], true);\nmoment(\"20140101\", [\"YYYYMMDD\"], \"en\");\nmoment(\"20140101\", [\"YYYYMMDD\"], \"en\", true);\n\nmoment(day.toISOString(), moment.ISO_8601);\nmoment(day.toISOString(), moment.ISO_8601, true);\nmoment(day.toISOString(), moment.ISO_8601, \"en\", true);\nmoment(day.toISOString(), [moment.ISO_8601]);\nmoment(day.toISOString(), [moment.ISO_8601], true);\nmoment(day.toISOString(), [moment.ISO_8601], \"en\", true);\n\nvar a = moment([2012]);\nvar b = moment(a);\na.year(2000);\nb.year(); // 2012\n\nmoment.utc();\nmoment.utc(12345);\nmoment.utc([12, 34, 56]);\nmoment.utc({ years: 2010, months: 3, days: 5, hours: 15, minutes: 10, seconds: 3, milliseconds: 123 });\nmoment.utc(\"1-2-3\");\nmoment.utc(\"1-2-3\", \"3-2-1\");\nmoment.utc(\"1-2-3\", \"3-2-1\", true);\nmoment.utc(\"1-2-3\", \"3-2-1\", \"en\");\nmoment.utc(\"1-2-3\", \"3-2-1\", \"en\", true);\nmoment.utc(\"01-01-2014\", [\"DD-MM-YYYY\", \"MM-DD-YYYY\"]);\nmoment.utc(\"01-01-2014\", [\"DD-MM-YYYY\", \"MM-DD-YYYY\"], true);\nmoment.utc(\"01-01-2014\", [\"DD-MM-YYYY\", \"MM-DD-YYYY\"], \"en\");\nmoment.utc(\"01-01-2014\", [\"DD-MM-YYYY\", \"MM-DD-YYYY\"], \"en\", true);\n\nvar a2 = moment.utc([2011, 0, 1, 8]);\na.hours();\na.local();\na.hours();\n\nmoment(\"2011-10-10\", \"YYYY-MM-DD\").isValid();\nmoment(\"2011-10-50\", \"YYYY-MM-DD\").isValid();\nmoment(\"2011-10-10T10:20:90\").isValid();\nmoment([2011, 0, 1]).isValid();\nmoment([2011, 0, 50]).isValid();\nmoment(\"not a date\").isValid();\n\nmoment().add('days', 7).subtract('months', 1).year(2009).hours(0).minutes(0).seconds(0);\n\nmoment().add('days', 7);\nmoment().add('days', 7).add('months', 1);\nmoment().add({days:7,months:1});\nmoment().add('milliseconds', 1000000);\nmoment().add('days', 360);\nmoment([2010, 0, 31]);\nmoment([2010, 0, 31]).add('months', 1);\nvar m = moment(new Date(2011, 2, 12, 5, 0, 0));\nm.hours();\nm.add('days', 1).hours();\nvar m2 = moment(new Date(2011, 2, 12, 5, 0, 0));\nm2.hours();\nm2.add('hours', 24).hours();\nvar duration = moment.duration({'days': 1});\nmoment([2012, 0, 31]).add(duration);\n\nmoment().add('seconds', 1);\nmoment().add(1, 'seconds');\n\nmoment().add('1', 'seconds');\n\nmoment().subtract('days', 7);\n\nmoment().seconds(30);\nmoment().minutes(30);\n\nmoment().hours(12);\nmoment().date(5);\nmoment().day(5);\nmoment().day(\"Sunday\");\nmoment().month(5);\nmoment().month(\"January\");\nmoment().year(1984);\nmoment().startOf('year');\nmoment().month(0).date(1).hours(0).minutes(0).seconds(0).milliseconds(0);\nmoment().startOf('hour');\nmoment().minutes(0).seconds(0).milliseconds(0);\nmoment().weekday();\nmoment().weekday(0);\nmoment().isoWeekday(1);\nmoment().isoWeekday();\nmoment().weekYear(2);\nmoment().weekYear();\nmoment().isoWeekYear(3);\nmoment().isoWeekYear();\nmoment().week();\nmoment().week(45);\nmoment().weeks();\nmoment().weeks(45);\nmoment().isoWeek();\nmoment().isoWeek(45);\nmoment().isoWeeks();\nmoment().isoWeeks(45);\nmoment().dayOfYear();\nmoment().dayOfYear(45);\n\nmoment().set('year', 2013);\nmoment().set('month', 3);  // April\nmoment().set('date', 1);\nmoment().set('hour', 13);\nmoment().set('minute', 20);\nmoment().set('second', 30);\nmoment().set('millisecond', 123);\nmoment().set({'year': 2013, 'month': 3});\n\nvar getMilliseconds: number = moment().milliseconds();\nvar getSeconds: number = moment().seconds();\nvar getMinutes: number = moment().minutes();\nvar getHours: number = moment().hours();\nvar getDate: number = moment().date();\nvar getDay: number = moment().day();\nvar getMonth: number = moment().month();\nvar getQuater: number = moment().quarter();\nvar getYear: number = moment().year();\n\nmoment().hours(0).minutes(0).seconds(0).milliseconds(0);\n\nvar a3 = moment([2011, 0, 1, 8]);\na3.hours();\na3.utc();\na3.hours();\n\nvar a4 = moment([2010, 1, 14, 15, 25, 50, 125]);\na4.format(\"dddd, MMMM Do YYYY, h:mm:ss a\");\na4.format(\"ddd, hA\");\n\nmoment().format('\\\\L');\nmoment().format('[today] DDDD');\n\nvar a5 = moment([2007, 0, 29]);\nvar b5 = moment([2007, 0, 28]);\na5.from(b5);\n\nvar a6 = moment([2007, 0, 29]);\nvar b6 = moment([2007, 0, 28]);\na6.from(b6);\na6.from([2007, 0, 28]);\na6.from(new Date(2007, 0, 28));\na6.from(\"1-28-2007\");\n\nvar a7 = moment();\nvar b7 = moment(\"10-10-1900\", \"MM-DD-YYYY\");\na7.from(b7);\n\nvar start = moment([2007, 0, 5]);\nvar end = moment([2007, 0, 10]);\nstart.from(end);\nstart.from(end, true);\n\nmoment([2007, 0, 29]).fromNow();\nmoment([2007, 0, 29]).fromNow();\nmoment([2007, 0, 29]).fromNow(true);\n\nvar a8 = moment([2007, 0, 29]);\nvar b8 = moment([2007, 0, 28]);\na8.diff(b8) ;\na8.diff(b8, 'days');\na8.diff(b8, 'years')\na8.diff(b8, 'years', true);\n\nmoment([2007, 0, 29]).toDate();\nmoment([2007, 1, 23]).toISOString();\nmoment(1318874398806).valueOf();\nmoment(1318874398806).unix();\nmoment([2000]).isLeapYear();\nmoment().zone();\nmoment().utcOffset();\nmoment(\"2012-2\", \"YYYY-MM\").daysInMonth();\nmoment([2011, 2, 12]).isDST();\n\nmoment.isMoment(new Date());\nmoment.isMoment(moment());\n\nmoment.isDate(new Date());\nmoment.isDate(/regexp/);\n\nmoment.isDuration(new Date());\nmoment.isDuration(moment.duration());\n\nmoment().isBetween(moment(), moment());\nmoment().isBetween(new Date(), new Date());\nmoment().isBetween([1,1,2000], [1,1,2001], \"year\");\n\nmoment.localeData('fr');\nmoment(1316116057189).fromNow();\n\nmoment.localeData('en');\nvar globalLang = moment();\nvar localLang = moment();\nlocalLang.localeData();\nlocalLang.format('LLLL');\nglobalLang.format('LLLL');\n\n// TODO: reenable in 2.0\n// moment.duration(null);\nmoment.duration(undefined);\nmoment.duration(100);\nmoment.duration(2, 'seconds');\nmoment.duration({\n    seconds: 2,\n    minutes: 2,\n    hours: 2,\n    days: 2,\n    weeks: 2,\n    months: 2,\n    years: 2\n});\nmoment.duration({\n    s: 2,\n    m: 2,\n    h: 2,\n    d: 2,\n    w: 2,\n    M: 2,\n    y: 2,\n});\nmoment.duration(1, \"minutes\").humanize();\nmoment.duration(500).milliseconds();\nmoment.duration(500).asMilliseconds();\nmoment.duration(500).seconds();\nmoment.duration(500).asSeconds();\nmoment.duration().minutes();\nmoment.duration().asMinutes();\nmoment.duration().toISOString();\nmoment.duration().toJSON();\n\nvar adur = moment.duration(3, 'd');\nvar bdur = moment.duration(2, 'd');\nadur.subtract(bdur).days();\nadur.subtract(1).days();\nadur.subtract(1, 'd').days();\n\n// Selecting a language\nmoment.locale();\nmoment.locale('en');\nmoment.locale(['en', 'fr']);\n\n// TODO: Reenable in 2.0\n// moment.defineLocale('en', null);\n// moment.updateLocale('en', null);\n// moment.locale('en', null);\n\n// Defining a custom language:\nmoment.locale('en', {\n    months: [\"January\", \"February\", \"March\", \"April\", \"May\", \"June\", \"July\", \"August\", \"September\", \"October\", \"November\", \"December\"],\n    monthsShort: [\"Jan\", \"Feb\", \"Mar\", \"Apr\", \"May\", \"Jun\", \"Jul\", \"Aug\", \"Sep\", \"Oct\", \"Nov\", \"Dec\"],\n    weekdays: [\"Sunday\", \"Monday\", \"Tuesday\", \"Wednesday\", \"Thursday\", \"Friday\", \"Saturday\"],\n    weekdaysShort: [\"Sun\", \"Mon\", \"Tue\", \"Wed\", \"Thu\", \"Fri\", \"Sat\"],\n    weekdaysMin: [\"Su\", \"Mo\", \"Tu\", \"We\", \"Th\", \"Fr\", \"Sa\"],\n    longDateFormat: {\n        LTS: \"h:mm:ss A\",\n        LT: \"h:mm A\",\n        L: \"MM/DD/YYYY\",\n        LL: \"MMMM D YYYY\",\n        LLL: \"MMMM D YYYY LT\",\n        LLLL: \"dddd, MMMM D YYYY LT\"\n    },\n    relativeTime: {\n        future: \"in %s\",\n        past: \"%s ago\",\n        s: \"seconds\",\n        m: \"a minute\",\n        mm: \"%d minutes\",\n        h: \"an hour\",\n        hh: \"%d hours\",\n        d: \"a day\",\n        dd: \"%d days\",\n        M: \"a month\",\n        MM: \"%d months\",\n        y: \"a year\",\n        yy: \"%d years\"\n    },\n    meridiem: function (hour, minute, isLower) {\n        if (hour < 9) {\n            return \"??\";\n        } else if (hour < 11 && minute < 30) {\n            return \"??\";\n        } else if (hour < 13 && minute < 30) {\n            return \"??\";\n        } else if (hour < 18) {\n            return \"??\";\n        } else {\n            return \"??\";\n        }\n    },\n    calendar: {\n        lastDay: '[Yesterday at] LT',\n        sameDay: '[Today at] LT',\n        nextDay: '[Tomorrow at] LT',\n        lastWeek: '[last] dddd [at] LT',\n        nextWeek: 'dddd [at] LT',\n        sameElse: 'L'\n    },\n    ordinal: function (number) {\n        var b = number % 10;\n        return (~~(number % 100 / 10) === 1) ? 'th' :\n            (b === 1) ? 'st' :\n            (b === 2) ? 'nd' :\n            (b === 3) ? 'rd' : 'th';\n    },\n    week: {\n        dow: 1,\n        doy: 4\n    }\n});\n\nmoment.locale('en', {\n    months : [\n        \"January\", \"February\", \"March\", \"April\", \"May\", \"June\", \"July\",\n        \"August\", \"September\", \"October\", \"November\", \"December\"\n    ]\n});\n\nmoment.locale('en', {\n    months : function (momentToFormat: moment.Moment, format: string) {\n        // momentToFormat is the moment currently being formatted\n        // format is the formatting string\n        if (/^MMMM/.test(format)) { // if the format starts with 'MMMM'\n            return this.nominative[momentToFormat.month()];\n        } else {\n            return this.subjective[momentToFormat.month()];\n        }\n    }\n});\n\nmoment.locale('en', {\n    monthsShort : [\n        \"Jan\", \"Feb\", \"Mar\", \"Apr\", \"May\", \"Jun\",\n        \"Jul\", \"Aug\", \"Sep\", \"Oct\", \"Nov\", \"Dec\"\n    ]\n});\n\nmoment.locale('en', {\n    monthsShort : function (momentToFormat: moment.Moment, format: string) {\n        if (/^MMMM/.test(format)) {\n            return this.nominative[momentToFormat.month()];\n        } else {\n            return this.subjective[momentToFormat.month()];\n        }\n    }\n});\n\nmoment.locale('en', {\n    weekdays : [\n        \"Sunday\", \"Monday\", \"Tuesday\", \"Wednesday\", \"Thursday\", \"Friday\", \"Saturday\"\n    ]\n});\n\nmoment.locale('en', {\n    weekdays : function (momentToFormat: moment.Moment) {\n        return this.weekdays[momentToFormat.day()];\n    }\n});\n\nmoment.locale('en', {\n    weekdaysShort : [\"Sun\", \"Mon\", \"Tue\", \"Wed\", \"Thu\", \"Fri\", \"Sat\"]\n});\n\nmoment.locale('en', {\n    weekdaysShort : function (momentToFormat: moment.Moment) {\n        return this.weekdaysShort[momentToFormat.day()];\n    }\n});\n\nmoment.locale('en', {\n    weekdaysMin : [\"Su\", \"Mo\", \"Tu\", \"We\", \"Th\", \"Fr\", \"Sa\"]\n});\n\nmoment.locale('en', {\n    weekdaysMin : function (momentToFormat: moment.Moment) {\n        return this.weekdaysMin[momentToFormat.day()];\n    }\n});\n\nmoment.locale('en', {\n    longDateFormat : {\n        LTS: \"h:mm:ss A\",\n        LT: \"h:mm A\",\n        L: \"MM/DD/YYYY\",\n        l: \"M/D/YYYY\",\n        LL: \"MMMM Do YYYY\",\n        ll: \"MMM D YYYY\",\n        LLL: \"MMMM Do YYYY LT\",\n        lll: \"MMM D YYYY LT\",\n        LLLL: \"dddd, MMMM Do YYYY LT\",\n        llll: \"ddd, MMM D YYYY LT\"\n    }\n});\n\nmoment.locale('en', {\n    longDateFormat : {\n        LTS: \"h:mm A\",\n        LT: \"h:mm A\",\n        L: \"MM/DD/YYYY\",\n        LL: \"MMMM Do YYYY\",\n        LLL: \"MMMM Do YYYY LT\",\n        LLLL: \"dddd, MMMM Do YYYY LT\"\n    }\n});\n\nmoment.locale('en', {\n    relativeTime : {\n        future: \"in %s\",\n        past:   \"%s ago\",\n        s:  \"seconds\",\n        m:  \"a minute\",\n        mm: \"%d minutes\",\n        h:  \"an hour\",\n        hh: \"%d hours\",\n        d:  \"a day\",\n        dd: \"%d days\",\n        M:  \"a month\",\n        MM: \"%d months\",\n        y:  \"a year\",\n        yy: \"%d years\"\n    }\n});\n\nmoment.locale('en', {\n    meridiem : function (hour, minute, isLowercase) {\n        if (hour < 9) {\n            return \"早上\";\n        } else if (hour < 11 && minute < 30) {\n            return \"上午\";\n        } else if (hour < 13 && minute < 30) {\n            return \"中午\";\n        } else if (hour < 18) {\n            return \"下午\";\n        } else {\n            return \"晚上\";\n        }\n    }\n});\n\nmoment.locale('en', {\n    calendar : {\n        lastDay : '[Yesterday at] LT',\n        sameDay : '[Today at] LT',\n        nextDay : function () {\n          return '[hoy a la' + ((this.hours() !== 1) ? 's' : '') + '] LT';\n        },\n        lastWeek : '[last] dddd [at] LT',\n        nextWeek : 'dddd [at] LT',\n        sameElse : 'L'\n    }\n});\n\nmoment.locale('en', {\n    ordinal : function (number) {\n        var b = number % 10;\n        var output = (~~ (number % 100 / 10) === 1) ? 'th' :\n            (b === 1) ? 'st' :\n            (b === 2) ? 'nd' :\n            (b === 3) ? 'rd' : 'th';\n        return number + output;\n    }\n});\n\nconsole.log(moment.version);\n\nmoment.defaultFormat = 'YYYY-MM-DD HH:mm';\n"
  },
  {
    "path": "app_frontend/static/plugin/moment-2.18.1/typing-tests/tsconfig.json",
    "content": "{\n  \"compileOnSave\": false,\n  \"compilerOptions\": {\n    \"module\": \"commonjs\",\n    \"noEmit\": true,\n    \"noImplicitAny\": true\n  },\n  \"files\": [\n    \"../moment.d.ts\",\n    \"./moment-tests.ts\"\n  ]\n}\n"
  },
  {
    "path": "app_frontend/static/robots.txt",
    "content": "User-agent: *\nDisallow:\nSitemap: sitemap.xml\n# 购物车\n"
  },
  {
    "path": "app_frontend/static/theme/default/css/animate.css",
    "content": "@charset \"UTF-8\";\r\n\r\n/*!\r\n * animate.css -http://daneden.me/animate\r\n * Version - 3.5.0\r\n * Licensed under the MIT license - http://opensource.org/licenses/MIT\r\n *\r\n * Copyright (c) 2015 Daniel Eden\r\n */\r\n\r\n.animated {\r\n  -webkit-animation-duration: 1s;\r\n  animation-duration: 1s;\r\n  -webkit-animation-fill-mode: both;\r\n  animation-fill-mode: both;\r\n}\r\n\r\n.animated.infinite {\r\n  -webkit-animation-iteration-count: infinite;\r\n  animation-iteration-count: infinite;\r\n}\r\n\r\n.animated.hinge {\r\n  -webkit-animation-duration: 2s;\r\n  animation-duration: 2s;\r\n}\r\n\r\n.animated.flipOutX,\r\n.animated.flipOutY,\r\n.animated.bounceIn,\r\n.animated.bounceOut {\r\n  -webkit-animation-duration: .75s;\r\n  animation-duration: .75s;\r\n}\r\n\r\n@-webkit-keyframes bounce {\r\n  from, 20%, 53%, 80%, to {\r\n    -webkit-animation-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000);\r\n    animation-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000);\r\n    -webkit-transform: translate3d(0,0,0);\r\n    transform: translate3d(0,0,0);\r\n  }\r\n\r\n  40%, 43% {\r\n    -webkit-animation-timing-function: cubic-bezier(0.755, 0.050, 0.855, 0.060);\r\n    animation-timing-function: cubic-bezier(0.755, 0.050, 0.855, 0.060);\r\n    -webkit-transform: translate3d(0, -30px, 0);\r\n    transform: translate3d(0, -30px, 0);\r\n  }\r\n\r\n  70% {\r\n    -webkit-animation-timing-function: cubic-bezier(0.755, 0.050, 0.855, 0.060);\r\n    animation-timing-function: cubic-bezier(0.755, 0.050, 0.855, 0.060);\r\n    -webkit-transform: translate3d(0, -15px, 0);\r\n    transform: translate3d(0, -15px, 0);\r\n  }\r\n\r\n  90% {\r\n    -webkit-transform: translate3d(0,-4px,0);\r\n    transform: translate3d(0,-4px,0);\r\n  }\r\n}\r\n\r\n@keyframes bounce {\r\n  from, 20%, 53%, 80%, to {\r\n    -webkit-animation-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000);\r\n    animation-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000);\r\n    -webkit-transform: translate3d(0,0,0);\r\n    transform: translate3d(0,0,0);\r\n  }\r\n\r\n  40%, 43% {\r\n    -webkit-animation-timing-function: cubic-bezier(0.755, 0.050, 0.855, 0.060);\r\n    animation-timing-function: cubic-bezier(0.755, 0.050, 0.855, 0.060);\r\n    -webkit-transform: translate3d(0, -30px, 0);\r\n    transform: translate3d(0, -30px, 0);\r\n  }\r\n\r\n  70% {\r\n    -webkit-animation-timing-function: cubic-bezier(0.755, 0.050, 0.855, 0.060);\r\n    animation-timing-function: cubic-bezier(0.755, 0.050, 0.855, 0.060);\r\n    -webkit-transform: translate3d(0, -15px, 0);\r\n    transform: translate3d(0, -15px, 0);\r\n  }\r\n\r\n  90% {\r\n    -webkit-transform: translate3d(0,-4px,0);\r\n    transform: translate3d(0,-4px,0);\r\n  }\r\n}\r\n\r\n.bounce {\r\n  -webkit-animation-name: bounce;\r\n  animation-name: bounce;\r\n  -webkit-transform-origin: center bottom;\r\n  transform-origin: center bottom;\r\n}\r\n\r\n@-webkit-keyframes flash {\r\n  from, 50%, to {\r\n    opacity: 1;\r\n  }\r\n\r\n  25%, 75% {\r\n    opacity: 0;\r\n  }\r\n}\r\n\r\n@keyframes flash {\r\n  from, 50%, to {\r\n    opacity: 1;\r\n  }\r\n\r\n  25%, 75% {\r\n    opacity: 0;\r\n  }\r\n}\r\n\r\n.flash {\r\n  -webkit-animation-name: flash;\r\n  animation-name: flash;\r\n}\r\n\r\n/* originally authored by Nick Pettit - https://github.com/nickpettit/glide */\r\n\r\n@-webkit-keyframes pulse {\r\n  from {\r\n    -webkit-transform: scale3d(1, 1, 1);\r\n    transform: scale3d(1, 1, 1);\r\n  }\r\n\r\n  50% {\r\n    -webkit-transform: scale3d(1.05, 1.05, 1.05);\r\n    transform: scale3d(1.05, 1.05, 1.05);\r\n  }\r\n\r\n  to {\r\n    -webkit-transform: scale3d(1, 1, 1);\r\n    transform: scale3d(1, 1, 1);\r\n  }\r\n}\r\n\r\n@keyframes pulse {\r\n  from {\r\n    -webkit-transform: scale3d(1, 1, 1);\r\n    transform: scale3d(1, 1, 1);\r\n  }\r\n\r\n  50% {\r\n    -webkit-transform: scale3d(1.05, 1.05, 1.05);\r\n    transform: scale3d(1.05, 1.05, 1.05);\r\n  }\r\n\r\n  to {\r\n    -webkit-transform: scale3d(1, 1, 1);\r\n    transform: scale3d(1, 1, 1);\r\n  }\r\n}\r\n\r\n.pulse {\r\n  -webkit-animation-name: pulse;\r\n  animation-name: pulse;\r\n}\r\n\r\n@-webkit-keyframes rubberBand {\r\n  from {\r\n    -webkit-transform: scale3d(1, 1, 1);\r\n    transform: scale3d(1, 1, 1);\r\n  }\r\n\r\n  30% {\r\n    -webkit-transform: scale3d(1.25, 0.75, 1);\r\n    transform: scale3d(1.25, 0.75, 1);\r\n  }\r\n\r\n  40% {\r\n    -webkit-transform: scale3d(0.75, 1.25, 1);\r\n    transform: scale3d(0.75, 1.25, 1);\r\n  }\r\n\r\n  50% {\r\n    -webkit-transform: scale3d(1.15, 0.85, 1);\r\n    transform: scale3d(1.15, 0.85, 1);\r\n  }\r\n\r\n  65% {\r\n    -webkit-transform: scale3d(.95, 1.05, 1);\r\n    transform: scale3d(.95, 1.05, 1);\r\n  }\r\n\r\n  75% {\r\n    -webkit-transform: scale3d(1.05, .95, 1);\r\n    transform: scale3d(1.05, .95, 1);\r\n  }\r\n\r\n  to {\r\n    -webkit-transform: scale3d(1, 1, 1);\r\n    transform: scale3d(1, 1, 1);\r\n  }\r\n}\r\n\r\n@keyframes rubberBand {\r\n  from {\r\n    -webkit-transform: scale3d(1, 1, 1);\r\n    transform: scale3d(1, 1, 1);\r\n  }\r\n\r\n  30% {\r\n    -webkit-transform: scale3d(1.25, 0.75, 1);\r\n    transform: scale3d(1.25, 0.75, 1);\r\n  }\r\n\r\n  40% {\r\n    -webkit-transform: scale3d(0.75, 1.25, 1);\r\n    transform: scale3d(0.75, 1.25, 1);\r\n  }\r\n\r\n  50% {\r\n    -webkit-transform: scale3d(1.15, 0.85, 1);\r\n    transform: scale3d(1.15, 0.85, 1);\r\n  }\r\n\r\n  65% {\r\n    -webkit-transform: scale3d(.95, 1.05, 1);\r\n    transform: scale3d(.95, 1.05, 1);\r\n  }\r\n\r\n  75% {\r\n    -webkit-transform: scale3d(1.05, .95, 1);\r\n    transform: scale3d(1.05, .95, 1);\r\n  }\r\n\r\n  to {\r\n    -webkit-transform: scale3d(1, 1, 1);\r\n    transform: scale3d(1, 1, 1);\r\n  }\r\n}\r\n\r\n.rubberBand {\r\n  -webkit-animation-name: rubberBand;\r\n  animation-name: rubberBand;\r\n}\r\n\r\n@-webkit-keyframes shake {\r\n  from, to {\r\n    -webkit-transform: translate3d(0, 0, 0);\r\n    transform: translate3d(0, 0, 0);\r\n  }\r\n\r\n  10%, 30%, 50%, 70%, 90% {\r\n    -webkit-transform: translate3d(-10px, 0, 0);\r\n    transform: translate3d(-10px, 0, 0);\r\n  }\r\n\r\n  20%, 40%, 60%, 80% {\r\n    -webkit-transform: translate3d(10px, 0, 0);\r\n    transform: translate3d(10px, 0, 0);\r\n  }\r\n}\r\n\r\n@keyframes shake {\r\n  from, to {\r\n    -webkit-transform: translate3d(0, 0, 0);\r\n    transform: translate3d(0, 0, 0);\r\n  }\r\n\r\n  10%, 30%, 50%, 70%, 90% {\r\n    -webkit-transform: translate3d(-10px, 0, 0);\r\n    transform: translate3d(-10px, 0, 0);\r\n  }\r\n\r\n  20%, 40%, 60%, 80% {\r\n    -webkit-transform: translate3d(10px, 0, 0);\r\n    transform: translate3d(10px, 0, 0);\r\n  }\r\n}\r\n\r\n.shake {\r\n  -webkit-animation-name: shake;\r\n  animation-name: shake;\r\n}\r\n\r\n@-webkit-keyframes headShake {\r\n  0% {\r\n    -webkit-transform: translateX(0);\r\n    transform: translateX(0);\r\n  }\r\n\r\n  6.5% {\r\n    -webkit-transform: translateX(-6px) rotateY(-9deg);\r\n    transform: translateX(-6px) rotateY(-9deg);\r\n  }\r\n\r\n  18.5% {\r\n    -webkit-transform: translateX(5px) rotateY(7deg);\r\n    transform: translateX(5px) rotateY(7deg);\r\n  }\r\n\r\n  31.5% {\r\n    -webkit-transform: translateX(-3px) rotateY(-5deg);\r\n    transform: translateX(-3px) rotateY(-5deg);\r\n  }\r\n\r\n  43.5% {\r\n    -webkit-transform: translateX(2px) rotateY(3deg);\r\n    transform: translateX(2px) rotateY(3deg);\r\n  }\r\n\r\n  50% {\r\n    -webkit-transform: translateX(0);\r\n    transform: translateX(0);\r\n  }\r\n}\r\n\r\n@keyframes headShake {\r\n  0% {\r\n    -webkit-transform: translateX(0);\r\n    transform: translateX(0);\r\n  }\r\n\r\n  6.5% {\r\n    -webkit-transform: translateX(-6px) rotateY(-9deg);\r\n    transform: translateX(-6px) rotateY(-9deg);\r\n  }\r\n\r\n  18.5% {\r\n    -webkit-transform: translateX(5px) rotateY(7deg);\r\n    transform: translateX(5px) rotateY(7deg);\r\n  }\r\n\r\n  31.5% {\r\n    -webkit-transform: translateX(-3px) rotateY(-5deg);\r\n    transform: translateX(-3px) rotateY(-5deg);\r\n  }\r\n\r\n  43.5% {\r\n    -webkit-transform: translateX(2px) rotateY(3deg);\r\n    transform: translateX(2px) rotateY(3deg);\r\n  }\r\n\r\n  50% {\r\n    -webkit-transform: translateX(0);\r\n    transform: translateX(0);\r\n  }\r\n}\r\n\r\n.headShake {\r\n  -webkit-animation-timing-function: ease-in-out;\r\n  animation-timing-function: ease-in-out;\r\n  -webkit-animation-name: headShake;\r\n  animation-name: headShake;\r\n}\r\n\r\n@-webkit-keyframes swing {\r\n  20% {\r\n    -webkit-transform: rotate3d(0, 0, 1, 15deg);\r\n    transform: rotate3d(0, 0, 1, 15deg);\r\n  }\r\n\r\n  40% {\r\n    -webkit-transform: rotate3d(0, 0, 1, -10deg);\r\n    transform: rotate3d(0, 0, 1, -10deg);\r\n  }\r\n\r\n  60% {\r\n    -webkit-transform: rotate3d(0, 0, 1, 5deg);\r\n    transform: rotate3d(0, 0, 1, 5deg);\r\n  }\r\n\r\n  80% {\r\n    -webkit-transform: rotate3d(0, 0, 1, -5deg);\r\n    transform: rotate3d(0, 0, 1, -5deg);\r\n  }\r\n\r\n  to {\r\n    -webkit-transform: rotate3d(0, 0, 1, 0deg);\r\n    transform: rotate3d(0, 0, 1, 0deg);\r\n  }\r\n}\r\n\r\n@keyframes swing {\r\n  20% {\r\n    -webkit-transform: rotate3d(0, 0, 1, 15deg);\r\n    transform: rotate3d(0, 0, 1, 15deg);\r\n  }\r\n\r\n  40% {\r\n    -webkit-transform: rotate3d(0, 0, 1, -10deg);\r\n    transform: rotate3d(0, 0, 1, -10deg);\r\n  }\r\n\r\n  60% {\r\n    -webkit-transform: rotate3d(0, 0, 1, 5deg);\r\n    transform: rotate3d(0, 0, 1, 5deg);\r\n  }\r\n\r\n  80% {\r\n    -webkit-transform: rotate3d(0, 0, 1, -5deg);\r\n    transform: rotate3d(0, 0, 1, -5deg);\r\n  }\r\n\r\n  to {\r\n    -webkit-transform: rotate3d(0, 0, 1, 0deg);\r\n    transform: rotate3d(0, 0, 1, 0deg);\r\n  }\r\n}\r\n\r\n.swing {\r\n  -webkit-transform-origin: top center;\r\n  transform-origin: top center;\r\n  -webkit-animation-name: swing;\r\n  animation-name: swing;\r\n}\r\n\r\n@-webkit-keyframes tada {\r\n  from {\r\n    -webkit-transform: scale3d(1, 1, 1);\r\n    transform: scale3d(1, 1, 1);\r\n  }\r\n\r\n  10%, 20% {\r\n    -webkit-transform: scale3d(.9, .9, .9) rotate3d(0, 0, 1, -3deg);\r\n    transform: scale3d(.9, .9, .9) rotate3d(0, 0, 1, -3deg);\r\n  }\r\n\r\n  30%, 50%, 70%, 90% {\r\n    -webkit-transform: scale3d(1.1, 1.1, 1.1) rotate3d(0, 0, 1, 3deg);\r\n    transform: scale3d(1.1, 1.1, 1.1) rotate3d(0, 0, 1, 3deg);\r\n  }\r\n\r\n  40%, 60%, 80% {\r\n    -webkit-transform: scale3d(1.1, 1.1, 1.1) rotate3d(0, 0, 1, -3deg);\r\n    transform: scale3d(1.1, 1.1, 1.1) rotate3d(0, 0, 1, -3deg);\r\n  }\r\n\r\n  to {\r\n    -webkit-transform: scale3d(1, 1, 1);\r\n    transform: scale3d(1, 1, 1);\r\n  }\r\n}\r\n\r\n@keyframes tada {\r\n  from {\r\n    -webkit-transform: scale3d(1, 1, 1);\r\n    transform: scale3d(1, 1, 1);\r\n  }\r\n\r\n  10%, 20% {\r\n    -webkit-transform: scale3d(.9, .9, .9) rotate3d(0, 0, 1, -3deg);\r\n    transform: scale3d(.9, .9, .9) rotate3d(0, 0, 1, -3deg);\r\n  }\r\n\r\n  30%, 50%, 70%, 90% {\r\n    -webkit-transform: scale3d(1.1, 1.1, 1.1) rotate3d(0, 0, 1, 3deg);\r\n    transform: scale3d(1.1, 1.1, 1.1) rotate3d(0, 0, 1, 3deg);\r\n  }\r\n\r\n  40%, 60%, 80% {\r\n    -webkit-transform: scale3d(1.1, 1.1, 1.1) rotate3d(0, 0, 1, -3deg);\r\n    transform: scale3d(1.1, 1.1, 1.1) rotate3d(0, 0, 1, -3deg);\r\n  }\r\n\r\n  to {\r\n    -webkit-transform: scale3d(1, 1, 1);\r\n    transform: scale3d(1, 1, 1);\r\n  }\r\n}\r\n\r\n.tada {\r\n  -webkit-animation-name: tada;\r\n  animation-name: tada;\r\n}\r\n\r\n/* originally authored by Nick Pettit - https://github.com/nickpettit/glide */\r\n\r\n@-webkit-keyframes wobble {\r\n  from {\r\n    -webkit-transform: none;\r\n    transform: none;\r\n  }\r\n\r\n  15% {\r\n    -webkit-transform: translate3d(-25%, 0, 0) rotate3d(0, 0, 1, -5deg);\r\n    transform: translate3d(-25%, 0, 0) rotate3d(0, 0, 1, -5deg);\r\n  }\r\n\r\n  30% {\r\n    -webkit-transform: translate3d(20%, 0, 0) rotate3d(0, 0, 1, 3deg);\r\n    transform: translate3d(20%, 0, 0) rotate3d(0, 0, 1, 3deg);\r\n  }\r\n\r\n  45% {\r\n    -webkit-transform: translate3d(-15%, 0, 0) rotate3d(0, 0, 1, -3deg);\r\n    transform: translate3d(-15%, 0, 0) rotate3d(0, 0, 1, -3deg);\r\n  }\r\n\r\n  60% {\r\n    -webkit-transform: translate3d(10%, 0, 0) rotate3d(0, 0, 1, 2deg);\r\n    transform: translate3d(10%, 0, 0) rotate3d(0, 0, 1, 2deg);\r\n  }\r\n\r\n  75% {\r\n    -webkit-transform: translate3d(-5%, 0, 0) rotate3d(0, 0, 1, -1deg);\r\n    transform: translate3d(-5%, 0, 0) rotate3d(0, 0, 1, -1deg);\r\n  }\r\n\r\n  to {\r\n    -webkit-transform: none;\r\n    transform: none;\r\n  }\r\n}\r\n\r\n@keyframes wobble {\r\n  from {\r\n    -webkit-transform: none;\r\n    transform: none;\r\n  }\r\n\r\n  15% {\r\n    -webkit-transform: translate3d(-25%, 0, 0) rotate3d(0, 0, 1, -5deg);\r\n    transform: translate3d(-25%, 0, 0) rotate3d(0, 0, 1, -5deg);\r\n  }\r\n\r\n  30% {\r\n    -webkit-transform: translate3d(20%, 0, 0) rotate3d(0, 0, 1, 3deg);\r\n    transform: translate3d(20%, 0, 0) rotate3d(0, 0, 1, 3deg);\r\n  }\r\n\r\n  45% {\r\n    -webkit-transform: translate3d(-15%, 0, 0) rotate3d(0, 0, 1, -3deg);\r\n    transform: translate3d(-15%, 0, 0) rotate3d(0, 0, 1, -3deg);\r\n  }\r\n\r\n  60% {\r\n    -webkit-transform: translate3d(10%, 0, 0) rotate3d(0, 0, 1, 2deg);\r\n    transform: translate3d(10%, 0, 0) rotate3d(0, 0, 1, 2deg);\r\n  }\r\n\r\n  75% {\r\n    -webkit-transform: translate3d(-5%, 0, 0) rotate3d(0, 0, 1, -1deg);\r\n    transform: translate3d(-5%, 0, 0) rotate3d(0, 0, 1, -1deg);\r\n  }\r\n\r\n  to {\r\n    -webkit-transform: none;\r\n    transform: none;\r\n  }\r\n}\r\n\r\n.wobble {\r\n  -webkit-animation-name: wobble;\r\n  animation-name: wobble;\r\n}\r\n\r\n@-webkit-keyframes jello {\r\n  from, 11.1%, to {\r\n    -webkit-transform: none;\r\n    transform: none;\r\n  }\r\n\r\n  22.2% {\r\n    -webkit-transform: skewX(-12.5deg) skewY(-12.5deg);\r\n    transform: skewX(-12.5deg) skewY(-12.5deg);\r\n  }\r\n\r\n  33.3% {\r\n    -webkit-transform: skewX(6.25deg) skewY(6.25deg);\r\n    transform: skewX(6.25deg) skewY(6.25deg);\r\n  }\r\n\r\n  44.4% {\r\n    -webkit-transform: skewX(-3.125deg) skewY(-3.125deg);\r\n    transform: skewX(-3.125deg) skewY(-3.125deg);\r\n  }\r\n\r\n  55.5% {\r\n    -webkit-transform: skewX(1.5625deg) skewY(1.5625deg);\r\n    transform: skewX(1.5625deg) skewY(1.5625deg);\r\n  }\r\n\r\n  66.6% {\r\n    -webkit-transform: skewX(-0.78125deg) skewY(-0.78125deg);\r\n    transform: skewX(-0.78125deg) skewY(-0.78125deg);\r\n  }\r\n\r\n  77.7% {\r\n    -webkit-transform: skewX(0.390625deg) skewY(0.390625deg);\r\n    transform: skewX(0.390625deg) skewY(0.390625deg);\r\n  }\r\n\r\n  88.8% {\r\n    -webkit-transform: skewX(-0.1953125deg) skewY(-0.1953125deg);\r\n    transform: skewX(-0.1953125deg) skewY(-0.1953125deg);\r\n  }\r\n}\r\n\r\n@keyframes jello {\r\n  from, 11.1%, to {\r\n    -webkit-transform: none;\r\n    transform: none;\r\n  }\r\n\r\n  22.2% {\r\n    -webkit-transform: skewX(-12.5deg) skewY(-12.5deg);\r\n    transform: skewX(-12.5deg) skewY(-12.5deg);\r\n  }\r\n\r\n  33.3% {\r\n    -webkit-transform: skewX(6.25deg) skewY(6.25deg);\r\n    transform: skewX(6.25deg) skewY(6.25deg);\r\n  }\r\n\r\n  44.4% {\r\n    -webkit-transform: skewX(-3.125deg) skewY(-3.125deg);\r\n    transform: skewX(-3.125deg) skewY(-3.125deg);\r\n  }\r\n\r\n  55.5% {\r\n    -webkit-transform: skewX(1.5625deg) skewY(1.5625deg);\r\n    transform: skewX(1.5625deg) skewY(1.5625deg);\r\n  }\r\n\r\n  66.6% {\r\n    -webkit-transform: skewX(-0.78125deg) skewY(-0.78125deg);\r\n    transform: skewX(-0.78125deg) skewY(-0.78125deg);\r\n  }\r\n\r\n  77.7% {\r\n    -webkit-transform: skewX(0.390625deg) skewY(0.390625deg);\r\n    transform: skewX(0.390625deg) skewY(0.390625deg);\r\n  }\r\n\r\n  88.8% {\r\n    -webkit-transform: skewX(-0.1953125deg) skewY(-0.1953125deg);\r\n    transform: skewX(-0.1953125deg) skewY(-0.1953125deg);\r\n  }\r\n}\r\n\r\n.jello {\r\n  -webkit-animation-name: jello;\r\n  animation-name: jello;\r\n  -webkit-transform-origin: center;\r\n  transform-origin: center;\r\n}\r\n\r\n@-webkit-keyframes bounceIn {\r\n  from, 20%, 40%, 60%, 80%, to {\r\n    -webkit-animation-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000);\r\n    animation-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000);\r\n  }\r\n\r\n  0% {\r\n    opacity: 0;\r\n    -webkit-transform: scale3d(.3, .3, .3);\r\n    transform: scale3d(.3, .3, .3);\r\n  }\r\n\r\n  20% {\r\n    -webkit-transform: scale3d(1.1, 1.1, 1.1);\r\n    transform: scale3d(1.1, 1.1, 1.1);\r\n  }\r\n\r\n  40% {\r\n    -webkit-transform: scale3d(.9, .9, .9);\r\n    transform: scale3d(.9, .9, .9);\r\n  }\r\n\r\n  60% {\r\n    opacity: 1;\r\n    -webkit-transform: scale3d(1.03, 1.03, 1.03);\r\n    transform: scale3d(1.03, 1.03, 1.03);\r\n  }\r\n\r\n  80% {\r\n    -webkit-transform: scale3d(.97, .97, .97);\r\n    transform: scale3d(.97, .97, .97);\r\n  }\r\n\r\n  to {\r\n    opacity: 1;\r\n    -webkit-transform: scale3d(1, 1, 1);\r\n    transform: scale3d(1, 1, 1);\r\n  }\r\n}\r\n\r\n@keyframes bounceIn {\r\n  from, 20%, 40%, 60%, 80%, to {\r\n    -webkit-animation-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000);\r\n    animation-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000);\r\n  }\r\n\r\n  0% {\r\n    opacity: 0;\r\n    -webkit-transform: scale3d(.3, .3, .3);\r\n    transform: scale3d(.3, .3, .3);\r\n  }\r\n\r\n  20% {\r\n    -webkit-transform: scale3d(1.1, 1.1, 1.1);\r\n    transform: scale3d(1.1, 1.1, 1.1);\r\n  }\r\n\r\n  40% {\r\n    -webkit-transform: scale3d(.9, .9, .9);\r\n    transform: scale3d(.9, .9, .9);\r\n  }\r\n\r\n  60% {\r\n    opacity: 1;\r\n    -webkit-transform: scale3d(1.03, 1.03, 1.03);\r\n    transform: scale3d(1.03, 1.03, 1.03);\r\n  }\r\n\r\n  80% {\r\n    -webkit-transform: scale3d(.97, .97, .97);\r\n    transform: scale3d(.97, .97, .97);\r\n  }\r\n\r\n  to {\r\n    opacity: 1;\r\n    -webkit-transform: scale3d(1, 1, 1);\r\n    transform: scale3d(1, 1, 1);\r\n  }\r\n}\r\n\r\n.bounceIn {\r\n  -webkit-animation-name: bounceIn;\r\n  animation-name: bounceIn;\r\n}\r\n\r\n@-webkit-keyframes bounceInDown {\r\n  from, 60%, 75%, 90%, to {\r\n    -webkit-animation-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000);\r\n    animation-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000);\r\n  }\r\n\r\n  0% {\r\n    opacity: 0;\r\n    -webkit-transform: translate3d(0, -3000px, 0);\r\n    transform: translate3d(0, -3000px, 0);\r\n  }\r\n\r\n  60% {\r\n    opacity: 1;\r\n    -webkit-transform: translate3d(0, 25px, 0);\r\n    transform: translate3d(0, 25px, 0);\r\n  }\r\n\r\n  75% {\r\n    -webkit-transform: translate3d(0, -10px, 0);\r\n    transform: translate3d(0, -10px, 0);\r\n  }\r\n\r\n  90% {\r\n    -webkit-transform: translate3d(0, 5px, 0);\r\n    transform: translate3d(0, 5px, 0);\r\n  }\r\n\r\n  to {\r\n    -webkit-transform: none;\r\n    transform: none;\r\n  }\r\n}\r\n\r\n@keyframes bounceInDown {\r\n  from, 60%, 75%, 90%, to {\r\n    -webkit-animation-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000);\r\n    animation-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000);\r\n  }\r\n\r\n  0% {\r\n    opacity: 0;\r\n    -webkit-transform: translate3d(0, -3000px, 0);\r\n    transform: translate3d(0, -3000px, 0);\r\n  }\r\n\r\n  60% {\r\n    opacity: 1;\r\n    -webkit-transform: translate3d(0, 25px, 0);\r\n    transform: translate3d(0, 25px, 0);\r\n  }\r\n\r\n  75% {\r\n    -webkit-transform: translate3d(0, -10px, 0);\r\n    transform: translate3d(0, -10px, 0);\r\n  }\r\n\r\n  90% {\r\n    -webkit-transform: translate3d(0, 5px, 0);\r\n    transform: translate3d(0, 5px, 0);\r\n  }\r\n\r\n  to {\r\n    -webkit-transform: none;\r\n    transform: none;\r\n  }\r\n}\r\n\r\n.bounceInDown {\r\n  -webkit-animation-name: bounceInDown;\r\n  animation-name: bounceInDown;\r\n}\r\n\r\n@-webkit-keyframes bounceInLeft {\r\n  from, 60%, 75%, 90%, to {\r\n    -webkit-animation-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000);\r\n    animation-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000);\r\n  }\r\n\r\n  0% {\r\n    opacity: 0;\r\n    -webkit-transform: translate3d(-3000px, 0, 0);\r\n    transform: translate3d(-3000px, 0, 0);\r\n  }\r\n\r\n  60% {\r\n    opacity: 1;\r\n    -webkit-transform: translate3d(25px, 0, 0);\r\n    transform: translate3d(25px, 0, 0);\r\n  }\r\n\r\n  75% {\r\n    -webkit-transform: translate3d(-10px, 0, 0);\r\n    transform: translate3d(-10px, 0, 0);\r\n  }\r\n\r\n  90% {\r\n    -webkit-transform: translate3d(5px, 0, 0);\r\n    transform: translate3d(5px, 0, 0);\r\n  }\r\n\r\n  to {\r\n    -webkit-transform: none;\r\n    transform: none;\r\n  }\r\n}\r\n\r\n@keyframes bounceInLeft {\r\n  from, 60%, 75%, 90%, to {\r\n    -webkit-animation-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000);\r\n    animation-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000);\r\n  }\r\n\r\n  0% {\r\n    opacity: 0;\r\n    -webkit-transform: translate3d(-3000px, 0, 0);\r\n    transform: translate3d(-3000px, 0, 0);\r\n  }\r\n\r\n  60% {\r\n    opacity: 1;\r\n    -webkit-transform: translate3d(25px, 0, 0);\r\n    transform: translate3d(25px, 0, 0);\r\n  }\r\n\r\n  75% {\r\n    -webkit-transform: translate3d(-10px, 0, 0);\r\n    transform: translate3d(-10px, 0, 0);\r\n  }\r\n\r\n  90% {\r\n    -webkit-transform: translate3d(5px, 0, 0);\r\n    transform: translate3d(5px, 0, 0);\r\n  }\r\n\r\n  to {\r\n    -webkit-transform: none;\r\n    transform: none;\r\n  }\r\n}\r\n\r\n.bounceInLeft {\r\n  -webkit-animation-name: bounceInLeft;\r\n  animation-name: bounceInLeft;\r\n}\r\n\r\n@-webkit-keyframes bounceInRight {\r\n  from, 60%, 75%, 90%, to {\r\n    -webkit-animation-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000);\r\n    animation-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000);\r\n  }\r\n\r\n  from {\r\n    opacity: 0;\r\n    -webkit-transform: translate3d(3000px, 0, 0);\r\n    transform: translate3d(3000px, 0, 0);\r\n  }\r\n\r\n  60% {\r\n    opacity: 1;\r\n    -webkit-transform: translate3d(-25px, 0, 0);\r\n    transform: translate3d(-25px, 0, 0);\r\n  }\r\n\r\n  75% {\r\n    -webkit-transform: translate3d(10px, 0, 0);\r\n    transform: translate3d(10px, 0, 0);\r\n  }\r\n\r\n  90% {\r\n    -webkit-transform: translate3d(-5px, 0, 0);\r\n    transform: translate3d(-5px, 0, 0);\r\n  }\r\n\r\n  to {\r\n    -webkit-transform: none;\r\n    transform: none;\r\n  }\r\n}\r\n\r\n@keyframes bounceInRight {\r\n  from, 60%, 75%, 90%, to {\r\n    -webkit-animation-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000);\r\n    animation-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000);\r\n  }\r\n\r\n  from {\r\n    opacity: 0;\r\n    -webkit-transform: translate3d(3000px, 0, 0);\r\n    transform: translate3d(3000px, 0, 0);\r\n  }\r\n\r\n  60% {\r\n    opacity: 1;\r\n    -webkit-transform: translate3d(-25px, 0, 0);\r\n    transform: translate3d(-25px, 0, 0);\r\n  }\r\n\r\n  75% {\r\n    -webkit-transform: translate3d(10px, 0, 0);\r\n    transform: translate3d(10px, 0, 0);\r\n  }\r\n\r\n  90% {\r\n    -webkit-transform: translate3d(-5px, 0, 0);\r\n    transform: translate3d(-5px, 0, 0);\r\n  }\r\n\r\n  to {\r\n    -webkit-transform: none;\r\n    transform: none;\r\n  }\r\n}\r\n\r\n.bounceInRight {\r\n  -webkit-animation-name: bounceInRight;\r\n  animation-name: bounceInRight;\r\n}\r\n\r\n@-webkit-keyframes bounceInUp {\r\n  from, 60%, 75%, 90%, to {\r\n    -webkit-animation-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000);\r\n    animation-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000);\r\n  }\r\n\r\n  from {\r\n    opacity: 0;\r\n    -webkit-transform: translate3d(0, 3000px, 0);\r\n    transform: translate3d(0, 3000px, 0);\r\n  }\r\n\r\n  60% {\r\n    opacity: 1;\r\n    -webkit-transform: translate3d(0, -20px, 0);\r\n    transform: translate3d(0, -20px, 0);\r\n  }\r\n\r\n  75% {\r\n    -webkit-transform: translate3d(0, 10px, 0);\r\n    transform: translate3d(0, 10px, 0);\r\n  }\r\n\r\n  90% {\r\n    -webkit-transform: translate3d(0, -5px, 0);\r\n    transform: translate3d(0, -5px, 0);\r\n  }\r\n\r\n  to {\r\n    -webkit-transform: translate3d(0, 0, 0);\r\n    transform: translate3d(0, 0, 0);\r\n  }\r\n}\r\n\r\n@keyframes bounceInUp {\r\n  from, 60%, 75%, 90%, to {\r\n    -webkit-animation-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000);\r\n    animation-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000);\r\n  }\r\n\r\n  from {\r\n    opacity: 0;\r\n    -webkit-transform: translate3d(0, 3000px, 0);\r\n    transform: translate3d(0, 3000px, 0);\r\n  }\r\n\r\n  60% {\r\n    opacity: 1;\r\n    -webkit-transform: translate3d(0, -20px, 0);\r\n    transform: translate3d(0, -20px, 0);\r\n  }\r\n\r\n  75% {\r\n    -webkit-transform: translate3d(0, 10px, 0);\r\n    transform: translate3d(0, 10px, 0);\r\n  }\r\n\r\n  90% {\r\n    -webkit-transform: translate3d(0, -5px, 0);\r\n    transform: translate3d(0, -5px, 0);\r\n  }\r\n\r\n  to {\r\n    -webkit-transform: translate3d(0, 0, 0);\r\n    transform: translate3d(0, 0, 0);\r\n  }\r\n}\r\n\r\n.bounceInUp {\r\n  -webkit-animation-name: bounceInUp;\r\n  animation-name: bounceInUp;\r\n}\r\n\r\n@-webkit-keyframes bounceOut {\r\n  20% {\r\n    -webkit-transform: scale3d(.9, .9, .9);\r\n    transform: scale3d(.9, .9, .9);\r\n  }\r\n\r\n  50%, 55% {\r\n    opacity: 1;\r\n    -webkit-transform: scale3d(1.1, 1.1, 1.1);\r\n    transform: scale3d(1.1, 1.1, 1.1);\r\n  }\r\n\r\n  to {\r\n    opacity: 0;\r\n    -webkit-transform: scale3d(.3, .3, .3);\r\n    transform: scale3d(.3, .3, .3);\r\n  }\r\n}\r\n\r\n@keyframes bounceOut {\r\n  20% {\r\n    -webkit-transform: scale3d(.9, .9, .9);\r\n    transform: scale3d(.9, .9, .9);\r\n  }\r\n\r\n  50%, 55% {\r\n    opacity: 1;\r\n    -webkit-transform: scale3d(1.1, 1.1, 1.1);\r\n    transform: scale3d(1.1, 1.1, 1.1);\r\n  }\r\n\r\n  to {\r\n    opacity: 0;\r\n    -webkit-transform: scale3d(.3, .3, .3);\r\n    transform: scale3d(.3, .3, .3);\r\n  }\r\n}\r\n\r\n.bounceOut {\r\n  -webkit-animation-name: bounceOut;\r\n  animation-name: bounceOut;\r\n}\r\n\r\n@-webkit-keyframes bounceOutDown {\r\n  20% {\r\n    -webkit-transform: translate3d(0, 10px, 0);\r\n    transform: translate3d(0, 10px, 0);\r\n  }\r\n\r\n  40%, 45% {\r\n    opacity: 1;\r\n    -webkit-transform: translate3d(0, -20px, 0);\r\n    transform: translate3d(0, -20px, 0);\r\n  }\r\n\r\n  to {\r\n    opacity: 0;\r\n    -webkit-transform: translate3d(0, 2000px, 0);\r\n    transform: translate3d(0, 2000px, 0);\r\n  }\r\n}\r\n\r\n@keyframes bounceOutDown {\r\n  20% {\r\n    -webkit-transform: translate3d(0, 10px, 0);\r\n    transform: translate3d(0, 10px, 0);\r\n  }\r\n\r\n  40%, 45% {\r\n    opacity: 1;\r\n    -webkit-transform: translate3d(0, -20px, 0);\r\n    transform: translate3d(0, -20px, 0);\r\n  }\r\n\r\n  to {\r\n    opacity: 0;\r\n    -webkit-transform: translate3d(0, 2000px, 0);\r\n    transform: translate3d(0, 2000px, 0);\r\n  }\r\n}\r\n\r\n.bounceOutDown {\r\n  -webkit-animation-name: bounceOutDown;\r\n  animation-name: bounceOutDown;\r\n}\r\n\r\n@-webkit-keyframes bounceOutLeft {\r\n  20% {\r\n    opacity: 1;\r\n    -webkit-transform: translate3d(20px, 0, 0);\r\n    transform: translate3d(20px, 0, 0);\r\n  }\r\n\r\n  to {\r\n    opacity: 0;\r\n    -webkit-transform: translate3d(-2000px, 0, 0);\r\n    transform: translate3d(-2000px, 0, 0);\r\n  }\r\n}\r\n\r\n@keyframes bounceOutLeft {\r\n  20% {\r\n    opacity: 1;\r\n    -webkit-transform: translate3d(20px, 0, 0);\r\n    transform: translate3d(20px, 0, 0);\r\n  }\r\n\r\n  to {\r\n    opacity: 0;\r\n    -webkit-transform: translate3d(-2000px, 0, 0);\r\n    transform: translate3d(-2000px, 0, 0);\r\n  }\r\n}\r\n\r\n.bounceOutLeft {\r\n  -webkit-animation-name: bounceOutLeft;\r\n  animation-name: bounceOutLeft;\r\n}\r\n\r\n@-webkit-keyframes bounceOutRight {\r\n  20% {\r\n    opacity: 1;\r\n    -webkit-transform: translate3d(-20px, 0, 0);\r\n    transform: translate3d(-20px, 0, 0);\r\n  }\r\n\r\n  to {\r\n    opacity: 0;\r\n    -webkit-transform: translate3d(2000px, 0, 0);\r\n    transform: translate3d(2000px, 0, 0);\r\n  }\r\n}\r\n\r\n@keyframes bounceOutRight {\r\n  20% {\r\n    opacity: 1;\r\n    -webkit-transform: translate3d(-20px, 0, 0);\r\n    transform: translate3d(-20px, 0, 0);\r\n  }\r\n\r\n  to {\r\n    opacity: 0;\r\n    -webkit-transform: translate3d(2000px, 0, 0);\r\n    transform: translate3d(2000px, 0, 0);\r\n  }\r\n}\r\n\r\n.bounceOutRight {\r\n  -webkit-animation-name: bounceOutRight;\r\n  animation-name: bounceOutRight;\r\n}\r\n\r\n@-webkit-keyframes bounceOutUp {\r\n  20% {\r\n    -webkit-transform: translate3d(0, -10px, 0);\r\n    transform: translate3d(0, -10px, 0);\r\n  }\r\n\r\n  40%, 45% {\r\n    opacity: 1;\r\n    -webkit-transform: translate3d(0, 20px, 0);\r\n    transform: translate3d(0, 20px, 0);\r\n  }\r\n\r\n  to {\r\n    opacity: 0;\r\n    -webkit-transform: translate3d(0, -2000px, 0);\r\n    transform: translate3d(0, -2000px, 0);\r\n  }\r\n}\r\n\r\n@keyframes bounceOutUp {\r\n  20% {\r\n    -webkit-transform: translate3d(0, -10px, 0);\r\n    transform: translate3d(0, -10px, 0);\r\n  }\r\n\r\n  40%, 45% {\r\n    opacity: 1;\r\n    -webkit-transform: translate3d(0, 20px, 0);\r\n    transform: translate3d(0, 20px, 0);\r\n  }\r\n\r\n  to {\r\n    opacity: 0;\r\n    -webkit-transform: translate3d(0, -2000px, 0);\r\n    transform: translate3d(0, -2000px, 0);\r\n  }\r\n}\r\n\r\n.bounceOutUp {\r\n  -webkit-animation-name: bounceOutUp;\r\n  animation-name: bounceOutUp;\r\n}\r\n\r\n@-webkit-keyframes fadeIn {\r\n  from {\r\n    opacity: 0;\r\n  }\r\n\r\n  to {\r\n    opacity: 1;\r\n  }\r\n}\r\n\r\n@keyframes fadeIn {\r\n  from {\r\n    opacity: 0;\r\n  }\r\n\r\n  to {\r\n    opacity: 1;\r\n  }\r\n}\r\n\r\n.fadeIn {\r\n  -webkit-animation-name: fadeIn;\r\n  animation-name: fadeIn;\r\n}\r\n\r\n@-webkit-keyframes fadeInDown {\r\n  from {\r\n    opacity: 0;\r\n    -webkit-transform: translate3d(0, -100%, 0);\r\n    transform: translate3d(0, -100%, 0);\r\n  }\r\n\r\n  to {\r\n    opacity: 1;\r\n    -webkit-transform: none;\r\n    transform: none;\r\n  }\r\n}\r\n\r\n@keyframes fadeInDown {\r\n  from {\r\n    opacity: 0;\r\n    -webkit-transform: translate3d(0, -100%, 0);\r\n    transform: translate3d(0, -100%, 0);\r\n  }\r\n\r\n  to {\r\n    opacity: 1;\r\n    -webkit-transform: none;\r\n    transform: none;\r\n  }\r\n}\r\n\r\n.fadeInDown {\r\n  -webkit-animation-name: fadeInDown;\r\n  animation-name: fadeInDown;\r\n}\r\n\r\n@-webkit-keyframes fadeInDownBig {\r\n  from {\r\n    opacity: 0;\r\n    -webkit-transform: translate3d(0, -2000px, 0);\r\n    transform: translate3d(0, -2000px, 0);\r\n  }\r\n\r\n  to {\r\n    opacity: 1;\r\n    -webkit-transform: none;\r\n    transform: none;\r\n  }\r\n}\r\n\r\n@keyframes fadeInDownBig {\r\n  from {\r\n    opacity: 0;\r\n    -webkit-transform: translate3d(0, -2000px, 0);\r\n    transform: translate3d(0, -2000px, 0);\r\n  }\r\n\r\n  to {\r\n    opacity: 1;\r\n    -webkit-transform: none;\r\n    transform: none;\r\n  }\r\n}\r\n\r\n.fadeInDownBig {\r\n  -webkit-animation-name: fadeInDownBig;\r\n  animation-name: fadeInDownBig;\r\n}\r\n\r\n@-webkit-keyframes fadeInLeft {\r\n  from {\r\n    opacity: 0;\r\n    -webkit-transform: translate3d(-100%, 0, 0);\r\n    transform: translate3d(-100%, 0, 0);\r\n  }\r\n\r\n  to {\r\n    opacity: 1;\r\n    -webkit-transform: none;\r\n    transform: none;\r\n  }\r\n}\r\n\r\n@keyframes fadeInLeft {\r\n  from {\r\n    opacity: 0;\r\n    -webkit-transform: translate3d(-100%, 0, 0);\r\n    transform: translate3d(-100%, 0, 0);\r\n  }\r\n\r\n  to {\r\n    opacity: 1;\r\n    -webkit-transform: none;\r\n    transform: none;\r\n  }\r\n}\r\n\r\n.fadeInLeft {\r\n  -webkit-animation-name: fadeInLeft;\r\n  animation-name: fadeInLeft;\r\n}\r\n\r\n@-webkit-keyframes fadeInLeftBig {\r\n  from {\r\n    opacity: 0;\r\n    -webkit-transform: translate3d(-2000px, 0, 0);\r\n    transform: translate3d(-2000px, 0, 0);\r\n  }\r\n\r\n  to {\r\n    opacity: 1;\r\n    -webkit-transform: none;\r\n    transform: none;\r\n  }\r\n}\r\n\r\n@keyframes fadeInLeftBig {\r\n  from {\r\n    opacity: 0;\r\n    -webkit-transform: translate3d(-2000px, 0, 0);\r\n    transform: translate3d(-2000px, 0, 0);\r\n  }\r\n\r\n  to {\r\n    opacity: 1;\r\n    -webkit-transform: none;\r\n    transform: none;\r\n  }\r\n}\r\n\r\n.fadeInLeftBig {\r\n  -webkit-animation-name: fadeInLeftBig;\r\n  animation-name: fadeInLeftBig;\r\n}\r\n\r\n@-webkit-keyframes fadeInRight {\r\n  from {\r\n    opacity: 0;\r\n    -webkit-transform: translate3d(100%, 0, 0);\r\n    transform: translate3d(100%, 0, 0);\r\n  }\r\n\r\n  to {\r\n    opacity: 1;\r\n    -webkit-transform: none;\r\n    transform: none;\r\n  }\r\n}\r\n\r\n@keyframes fadeInRight {\r\n  from {\r\n    opacity: 0;\r\n    -webkit-transform: translate3d(100%, 0, 0);\r\n    transform: translate3d(100%, 0, 0);\r\n  }\r\n\r\n  to {\r\n    opacity: 1;\r\n    -webkit-transform: none;\r\n    transform: none;\r\n  }\r\n}\r\n\r\n.fadeInRight {\r\n  -webkit-animation-name: fadeInRight;\r\n  animation-name: fadeInRight;\r\n}\r\n\r\n@-webkit-keyframes fadeInRightBig {\r\n  from {\r\n    opacity: 0;\r\n    -webkit-transform: translate3d(2000px, 0, 0);\r\n    transform: translate3d(2000px, 0, 0);\r\n  }\r\n\r\n  to {\r\n    opacity: 1;\r\n    -webkit-transform: none;\r\n    transform: none;\r\n  }\r\n}\r\n\r\n@keyframes fadeInRightBig {\r\n  from {\r\n    opacity: 0;\r\n    -webkit-transform: translate3d(2000px, 0, 0);\r\n    transform: translate3d(2000px, 0, 0);\r\n  }\r\n\r\n  to {\r\n    opacity: 1;\r\n    -webkit-transform: none;\r\n    transform: none;\r\n  }\r\n}\r\n\r\n.fadeInRightBig {\r\n  -webkit-animation-name: fadeInRightBig;\r\n  animation-name: fadeInRightBig;\r\n}\r\n\r\n@-webkit-keyframes fadeInUp {\r\n  from {\r\n    opacity: 0;\r\n    -webkit-transform: translate3d(0, 100%, 0);\r\n    transform: translate3d(0, 100%, 0);\r\n  }\r\n\r\n  to {\r\n    opacity: 1;\r\n    -webkit-transform: none;\r\n    transform: none;\r\n  }\r\n}\r\n\r\n@keyframes fadeInUp {\r\n  from {\r\n    opacity: 0;\r\n    -webkit-transform: translate3d(0, 100%, 0);\r\n    transform: translate3d(0, 100%, 0);\r\n  }\r\n\r\n  to {\r\n    opacity: 1;\r\n    -webkit-transform: none;\r\n    transform: none;\r\n  }\r\n}\r\n\r\n.fadeInUp {\r\n  -webkit-animation-name: fadeInUp;\r\n  animation-name: fadeInUp;\r\n}\r\n\r\n@-webkit-keyframes fadeInUpBig {\r\n  from {\r\n    opacity: 0;\r\n    -webkit-transform: translate3d(0, 2000px, 0);\r\n    transform: translate3d(0, 2000px, 0);\r\n  }\r\n\r\n  to {\r\n    opacity: 1;\r\n    -webkit-transform: none;\r\n    transform: none;\r\n  }\r\n}\r\n\r\n@keyframes fadeInUpBig {\r\n  from {\r\n    opacity: 0;\r\n    -webkit-transform: translate3d(0, 2000px, 0);\r\n    transform: translate3d(0, 2000px, 0);\r\n  }\r\n\r\n  to {\r\n    opacity: 1;\r\n    -webkit-transform: none;\r\n    transform: none;\r\n  }\r\n}\r\n\r\n.fadeInUpBig {\r\n  -webkit-animation-name: fadeInUpBig;\r\n  animation-name: fadeInUpBig;\r\n}\r\n\r\n@-webkit-keyframes fadeOut {\r\n  from {\r\n    opacity: 1;\r\n  }\r\n\r\n  to {\r\n    opacity: 0;\r\n  }\r\n}\r\n\r\n@keyframes fadeOut {\r\n  from {\r\n    opacity: 1;\r\n  }\r\n\r\n  to {\r\n    opacity: 0;\r\n  }\r\n}\r\n\r\n.fadeOut {\r\n  -webkit-animation-name: fadeOut;\r\n  animation-name: fadeOut;\r\n}\r\n\r\n@-webkit-keyframes fadeOutDown {\r\n  from {\r\n    opacity: 1;\r\n  }\r\n\r\n  to {\r\n    opacity: 0;\r\n    -webkit-transform: translate3d(0, 100%, 0);\r\n    transform: translate3d(0, 100%, 0);\r\n  }\r\n}\r\n\r\n@keyframes fadeOutDown {\r\n  from {\r\n    opacity: 1;\r\n  }\r\n\r\n  to {\r\n    opacity: 0;\r\n    -webkit-transform: translate3d(0, 100%, 0);\r\n    transform: translate3d(0, 100%, 0);\r\n  }\r\n}\r\n\r\n.fadeOutDown {\r\n  -webkit-animation-name: fadeOutDown;\r\n  animation-name: fadeOutDown;\r\n}\r\n\r\n@-webkit-keyframes fadeOutDownBig {\r\n  from {\r\n    opacity: 1;\r\n  }\r\n\r\n  to {\r\n    opacity: 0;\r\n    -webkit-transform: translate3d(0, 2000px, 0);\r\n    transform: translate3d(0, 2000px, 0);\r\n  }\r\n}\r\n\r\n@keyframes fadeOutDownBig {\r\n  from {\r\n    opacity: 1;\r\n  }\r\n\r\n  to {\r\n    opacity: 0;\r\n    -webkit-transform: translate3d(0, 2000px, 0);\r\n    transform: translate3d(0, 2000px, 0);\r\n  }\r\n}\r\n\r\n.fadeOutDownBig {\r\n  -webkit-animation-name: fadeOutDownBig;\r\n  animation-name: fadeOutDownBig;\r\n}\r\n\r\n@-webkit-keyframes fadeOutLeft {\r\n  from {\r\n    opacity: 1;\r\n  }\r\n\r\n  to {\r\n    opacity: 0;\r\n    -webkit-transform: translate3d(-100%, 0, 0);\r\n    transform: translate3d(-100%, 0, 0);\r\n  }\r\n}\r\n\r\n@keyframes fadeOutLeft {\r\n  from {\r\n    opacity: 1;\r\n  }\r\n\r\n  to {\r\n    opacity: 0;\r\n    -webkit-transform: translate3d(-100%, 0, 0);\r\n    transform: translate3d(-100%, 0, 0);\r\n  }\r\n}\r\n\r\n.fadeOutLeft {\r\n  -webkit-animation-name: fadeOutLeft;\r\n  animation-name: fadeOutLeft;\r\n}\r\n\r\n@-webkit-keyframes fadeOutLeftBig {\r\n  from {\r\n    opacity: 1;\r\n  }\r\n\r\n  to {\r\n    opacity: 0;\r\n    -webkit-transform: translate3d(-2000px, 0, 0);\r\n    transform: translate3d(-2000px, 0, 0);\r\n  }\r\n}\r\n\r\n@keyframes fadeOutLeftBig {\r\n  from {\r\n    opacity: 1;\r\n  }\r\n\r\n  to {\r\n    opacity: 0;\r\n    -webkit-transform: translate3d(-2000px, 0, 0);\r\n    transform: translate3d(-2000px, 0, 0);\r\n  }\r\n}\r\n\r\n.fadeOutLeftBig {\r\n  -webkit-animation-name: fadeOutLeftBig;\r\n  animation-name: fadeOutLeftBig;\r\n}\r\n\r\n@-webkit-keyframes fadeOutRight {\r\n  from {\r\n    opacity: 1;\r\n  }\r\n\r\n  to {\r\n    opacity: 0;\r\n    -webkit-transform: translate3d(100%, 0, 0);\r\n    transform: translate3d(100%, 0, 0);\r\n  }\r\n}\r\n\r\n@keyframes fadeOutRight {\r\n  from {\r\n    opacity: 1;\r\n  }\r\n\r\n  to {\r\n    opacity: 0;\r\n    -webkit-transform: translate3d(100%, 0, 0);\r\n    transform: translate3d(100%, 0, 0);\r\n  }\r\n}\r\n\r\n.fadeOutRight {\r\n  -webkit-animation-name: fadeOutRight;\r\n  animation-name: fadeOutRight;\r\n}\r\n\r\n@-webkit-keyframes fadeOutRightBig {\r\n  from {\r\n    opacity: 1;\r\n  }\r\n\r\n  to {\r\n    opacity: 0;\r\n    -webkit-transform: translate3d(2000px, 0, 0);\r\n    transform: translate3d(2000px, 0, 0);\r\n  }\r\n}\r\n\r\n@keyframes fadeOutRightBig {\r\n  from {\r\n    opacity: 1;\r\n  }\r\n\r\n  to {\r\n    opacity: 0;\r\n    -webkit-transform: translate3d(2000px, 0, 0);\r\n    transform: translate3d(2000px, 0, 0);\r\n  }\r\n}\r\n\r\n.fadeOutRightBig {\r\n  -webkit-animation-name: fadeOutRightBig;\r\n  animation-name: fadeOutRightBig;\r\n}\r\n\r\n@-webkit-keyframes fadeOutUp {\r\n  from {\r\n    opacity: 1;\r\n  }\r\n\r\n  to {\r\n    opacity: 0;\r\n    -webkit-transform: translate3d(0, -100%, 0);\r\n    transform: translate3d(0, -100%, 0);\r\n  }\r\n}\r\n\r\n@keyframes fadeOutUp {\r\n  from {\r\n    opacity: 1;\r\n  }\r\n\r\n  to {\r\n    opacity: 0;\r\n    -webkit-transform: translate3d(0, -100%, 0);\r\n    transform: translate3d(0, -100%, 0);\r\n  }\r\n}\r\n\r\n.fadeOutUp {\r\n  -webkit-animation-name: fadeOutUp;\r\n  animation-name: fadeOutUp;\r\n}\r\n\r\n@-webkit-keyframes fadeOutUpBig {\r\n  from {\r\n    opacity: 1;\r\n  }\r\n\r\n  to {\r\n    opacity: 0;\r\n    -webkit-transform: translate3d(0, -2000px, 0);\r\n    transform: translate3d(0, -2000px, 0);\r\n  }\r\n}\r\n\r\n@keyframes fadeOutUpBig {\r\n  from {\r\n    opacity: 1;\r\n  }\r\n\r\n  to {\r\n    opacity: 0;\r\n    -webkit-transform: translate3d(0, -2000px, 0);\r\n    transform: translate3d(0, -2000px, 0);\r\n  }\r\n}\r\n\r\n.fadeOutUpBig {\r\n  -webkit-animation-name: fadeOutUpBig;\r\n  animation-name: fadeOutUpBig;\r\n}\r\n\r\n@-webkit-keyframes flip {\r\n  from {\r\n    -webkit-transform: perspective(400px) rotate3d(0, 1, 0, -360deg);\r\n    transform: perspective(400px) rotate3d(0, 1, 0, -360deg);\r\n    -webkit-animation-timing-function: ease-out;\r\n    animation-timing-function: ease-out;\r\n  }\r\n\r\n  40% {\r\n    -webkit-transform: perspective(400px) translate3d(0, 0, 150px) rotate3d(0, 1, 0, -190deg);\r\n    transform: perspective(400px) translate3d(0, 0, 150px) rotate3d(0, 1, 0, -190deg);\r\n    -webkit-animation-timing-function: ease-out;\r\n    animation-timing-function: ease-out;\r\n  }\r\n\r\n  50% {\r\n    -webkit-transform: perspective(400px) translate3d(0, 0, 150px) rotate3d(0, 1, 0, -170deg);\r\n    transform: perspective(400px) translate3d(0, 0, 150px) rotate3d(0, 1, 0, -170deg);\r\n    -webkit-animation-timing-function: ease-in;\r\n    animation-timing-function: ease-in;\r\n  }\r\n\r\n  80% {\r\n    -webkit-transform: perspective(400px) scale3d(.95, .95, .95);\r\n    transform: perspective(400px) scale3d(.95, .95, .95);\r\n    -webkit-animation-timing-function: ease-in;\r\n    animation-timing-function: ease-in;\r\n  }\r\n\r\n  to {\r\n    -webkit-transform: perspective(400px);\r\n    transform: perspective(400px);\r\n    -webkit-animation-timing-function: ease-in;\r\n    animation-timing-function: ease-in;\r\n  }\r\n}\r\n\r\n@keyframes flip {\r\n  from {\r\n    -webkit-transform: perspective(400px) rotate3d(0, 1, 0, -360deg);\r\n    transform: perspective(400px) rotate3d(0, 1, 0, -360deg);\r\n    -webkit-animation-timing-function: ease-out;\r\n    animation-timing-function: ease-out;\r\n  }\r\n\r\n  40% {\r\n    -webkit-transform: perspective(400px) translate3d(0, 0, 150px) rotate3d(0, 1, 0, -190deg);\r\n    transform: perspective(400px) translate3d(0, 0, 150px) rotate3d(0, 1, 0, -190deg);\r\n    -webkit-animation-timing-function: ease-out;\r\n    animation-timing-function: ease-out;\r\n  }\r\n\r\n  50% {\r\n    -webkit-transform: perspective(400px) translate3d(0, 0, 150px) rotate3d(0, 1, 0, -170deg);\r\n    transform: perspective(400px) translate3d(0, 0, 150px) rotate3d(0, 1, 0, -170deg);\r\n    -webkit-animation-timing-function: ease-in;\r\n    animation-timing-function: ease-in;\r\n  }\r\n\r\n  80% {\r\n    -webkit-transform: perspective(400px) scale3d(.95, .95, .95);\r\n    transform: perspective(400px) scale3d(.95, .95, .95);\r\n    -webkit-animation-timing-function: ease-in;\r\n    animation-timing-function: ease-in;\r\n  }\r\n\r\n  to {\r\n    -webkit-transform: perspective(400px);\r\n    transform: perspective(400px);\r\n    -webkit-animation-timing-function: ease-in;\r\n    animation-timing-function: ease-in;\r\n  }\r\n}\r\n\r\n.animated.flip {\r\n  -webkit-backface-visibility: visible;\r\n  backface-visibility: visible;\r\n  -webkit-animation-name: flip;\r\n  animation-name: flip;\r\n}\r\n\r\n@-webkit-keyframes flipInX {\r\n  from {\r\n    -webkit-transform: perspective(400px) rotate3d(1, 0, 0, 90deg);\r\n    transform: perspective(400px) rotate3d(1, 0, 0, 90deg);\r\n    -webkit-animation-timing-function: ease-in;\r\n    animation-timing-function: ease-in;\r\n    opacity: 0;\r\n  }\r\n\r\n  40% {\r\n    -webkit-transform: perspective(400px) rotate3d(1, 0, 0, -20deg);\r\n    transform: perspective(400px) rotate3d(1, 0, 0, -20deg);\r\n    -webkit-animation-timing-function: ease-in;\r\n    animation-timing-function: ease-in;\r\n  }\r\n\r\n  60% {\r\n    -webkit-transform: perspective(400px) rotate3d(1, 0, 0, 10deg);\r\n    transform: perspective(400px) rotate3d(1, 0, 0, 10deg);\r\n    opacity: 1;\r\n  }\r\n\r\n  80% {\r\n    -webkit-transform: perspective(400px) rotate3d(1, 0, 0, -5deg);\r\n    transform: perspective(400px) rotate3d(1, 0, 0, -5deg);\r\n  }\r\n\r\n  to {\r\n    -webkit-transform: perspective(400px);\r\n    transform: perspective(400px);\r\n  }\r\n}\r\n\r\n@keyframes flipInX {\r\n  from {\r\n    -webkit-transform: perspective(400px) rotate3d(1, 0, 0, 90deg);\r\n    transform: perspective(400px) rotate3d(1, 0, 0, 90deg);\r\n    -webkit-animation-timing-function: ease-in;\r\n    animation-timing-function: ease-in;\r\n    opacity: 0;\r\n  }\r\n\r\n  40% {\r\n    -webkit-transform: perspective(400px) rotate3d(1, 0, 0, -20deg);\r\n    transform: perspective(400px) rotate3d(1, 0, 0, -20deg);\r\n    -webkit-animation-timing-function: ease-in;\r\n    animation-timing-function: ease-in;\r\n  }\r\n\r\n  60% {\r\n    -webkit-transform: perspective(400px) rotate3d(1, 0, 0, 10deg);\r\n    transform: perspective(400px) rotate3d(1, 0, 0, 10deg);\r\n    opacity: 1;\r\n  }\r\n\r\n  80% {\r\n    -webkit-transform: perspective(400px) rotate3d(1, 0, 0, -5deg);\r\n    transform: perspective(400px) rotate3d(1, 0, 0, -5deg);\r\n  }\r\n\r\n  to {\r\n    -webkit-transform: perspective(400px);\r\n    transform: perspective(400px);\r\n  }\r\n}\r\n\r\n.flipInX {\r\n  -webkit-backface-visibility: visible !important;\r\n  backface-visibility: visible !important;\r\n  -webkit-animation-name: flipInX;\r\n  animation-name: flipInX;\r\n}\r\n\r\n@-webkit-keyframes flipInY {\r\n  from {\r\n    -webkit-transform: perspective(400px) rotate3d(0, 1, 0, 90deg);\r\n    transform: perspective(400px) rotate3d(0, 1, 0, 90deg);\r\n    -webkit-animation-timing-function: ease-in;\r\n    animation-timing-function: ease-in;\r\n    opacity: 0;\r\n  }\r\n\r\n  40% {\r\n    -webkit-transform: perspective(400px) rotate3d(0, 1, 0, -20deg);\r\n    transform: perspective(400px) rotate3d(0, 1, 0, -20deg);\r\n    -webkit-animation-timing-function: ease-in;\r\n    animation-timing-function: ease-in;\r\n  }\r\n\r\n  60% {\r\n    -webkit-transform: perspective(400px) rotate3d(0, 1, 0, 10deg);\r\n    transform: perspective(400px) rotate3d(0, 1, 0, 10deg);\r\n    opacity: 1;\r\n  }\r\n\r\n  80% {\r\n    -webkit-transform: perspective(400px) rotate3d(0, 1, 0, -5deg);\r\n    transform: perspective(400px) rotate3d(0, 1, 0, -5deg);\r\n  }\r\n\r\n  to {\r\n    -webkit-transform: perspective(400px);\r\n    transform: perspective(400px);\r\n  }\r\n}\r\n\r\n@keyframes flipInY {\r\n  from {\r\n    -webkit-transform: perspective(400px) rotate3d(0, 1, 0, 90deg);\r\n    transform: perspective(400px) rotate3d(0, 1, 0, 90deg);\r\n    -webkit-animation-timing-function: ease-in;\r\n    animation-timing-function: ease-in;\r\n    opacity: 0;\r\n  }\r\n\r\n  40% {\r\n    -webkit-transform: perspective(400px) rotate3d(0, 1, 0, -20deg);\r\n    transform: perspective(400px) rotate3d(0, 1, 0, -20deg);\r\n    -webkit-animation-timing-function: ease-in;\r\n    animation-timing-function: ease-in;\r\n  }\r\n\r\n  60% {\r\n    -webkit-transform: perspective(400px) rotate3d(0, 1, 0, 10deg);\r\n    transform: perspective(400px) rotate3d(0, 1, 0, 10deg);\r\n    opacity: 1;\r\n  }\r\n\r\n  80% {\r\n    -webkit-transform: perspective(400px) rotate3d(0, 1, 0, -5deg);\r\n    transform: perspective(400px) rotate3d(0, 1, 0, -5deg);\r\n  }\r\n\r\n  to {\r\n    -webkit-transform: perspective(400px);\r\n    transform: perspective(400px);\r\n  }\r\n}\r\n\r\n.flipInY {\r\n  -webkit-backface-visibility: visible !important;\r\n  backface-visibility: visible !important;\r\n  -webkit-animation-name: flipInY;\r\n  animation-name: flipInY;\r\n}\r\n\r\n@-webkit-keyframes flipOutX {\r\n  from {\r\n    -webkit-transform: perspective(400px);\r\n    transform: perspective(400px);\r\n  }\r\n\r\n  30% {\r\n    -webkit-transform: perspective(400px) rotate3d(1, 0, 0, -20deg);\r\n    transform: perspective(400px) rotate3d(1, 0, 0, -20deg);\r\n    opacity: 1;\r\n  }\r\n\r\n  to {\r\n    -webkit-transform: perspective(400px) rotate3d(1, 0, 0, 90deg);\r\n    transform: perspective(400px) rotate3d(1, 0, 0, 90deg);\r\n    opacity: 0;\r\n  }\r\n}\r\n\r\n@keyframes flipOutX {\r\n  from {\r\n    -webkit-transform: perspective(400px);\r\n    transform: perspective(400px);\r\n  }\r\n\r\n  30% {\r\n    -webkit-transform: perspective(400px) rotate3d(1, 0, 0, -20deg);\r\n    transform: perspective(400px) rotate3d(1, 0, 0, -20deg);\r\n    opacity: 1;\r\n  }\r\n\r\n  to {\r\n    -webkit-transform: perspective(400px) rotate3d(1, 0, 0, 90deg);\r\n    transform: perspective(400px) rotate3d(1, 0, 0, 90deg);\r\n    opacity: 0;\r\n  }\r\n}\r\n\r\n.flipOutX {\r\n  -webkit-animation-name: flipOutX;\r\n  animation-name: flipOutX;\r\n  -webkit-backface-visibility: visible !important;\r\n  backface-visibility: visible !important;\r\n}\r\n\r\n@-webkit-keyframes flipOutY {\r\n  from {\r\n    -webkit-transform: perspective(400px);\r\n    transform: perspective(400px);\r\n  }\r\n\r\n  30% {\r\n    -webkit-transform: perspective(400px) rotate3d(0, 1, 0, -15deg);\r\n    transform: perspective(400px) rotate3d(0, 1, 0, -15deg);\r\n    opacity: 1;\r\n  }\r\n\r\n  to {\r\n    -webkit-transform: perspective(400px) rotate3d(0, 1, 0, 90deg);\r\n    transform: perspective(400px) rotate3d(0, 1, 0, 90deg);\r\n    opacity: 0;\r\n  }\r\n}\r\n\r\n@keyframes flipOutY {\r\n  from {\r\n    -webkit-transform: perspective(400px);\r\n    transform: perspective(400px);\r\n  }\r\n\r\n  30% {\r\n    -webkit-transform: perspective(400px) rotate3d(0, 1, 0, -15deg);\r\n    transform: perspective(400px) rotate3d(0, 1, 0, -15deg);\r\n    opacity: 1;\r\n  }\r\n\r\n  to {\r\n    -webkit-transform: perspective(400px) rotate3d(0, 1, 0, 90deg);\r\n    transform: perspective(400px) rotate3d(0, 1, 0, 90deg);\r\n    opacity: 0;\r\n  }\r\n}\r\n\r\n.flipOutY {\r\n  -webkit-backface-visibility: visible !important;\r\n  backface-visibility: visible !important;\r\n  -webkit-animation-name: flipOutY;\r\n  animation-name: flipOutY;\r\n}\r\n\r\n@-webkit-keyframes lightSpeedIn {\r\n  from {\r\n    -webkit-transform: translate3d(100%, 0, 0) skewX(-30deg);\r\n    transform: translate3d(100%, 0, 0) skewX(-30deg);\r\n    opacity: 0;\r\n  }\r\n\r\n  60% {\r\n    -webkit-transform: skewX(20deg);\r\n    transform: skewX(20deg);\r\n    opacity: 1;\r\n  }\r\n\r\n  80% {\r\n    -webkit-transform: skewX(-5deg);\r\n    transform: skewX(-5deg);\r\n    opacity: 1;\r\n  }\r\n\r\n  to {\r\n    -webkit-transform: none;\r\n    transform: none;\r\n    opacity: 1;\r\n  }\r\n}\r\n\r\n@keyframes lightSpeedIn {\r\n  from {\r\n    -webkit-transform: translate3d(100%, 0, 0) skewX(-30deg);\r\n    transform: translate3d(100%, 0, 0) skewX(-30deg);\r\n    opacity: 0;\r\n  }\r\n\r\n  60% {\r\n    -webkit-transform: skewX(20deg);\r\n    transform: skewX(20deg);\r\n    opacity: 1;\r\n  }\r\n\r\n  80% {\r\n    -webkit-transform: skewX(-5deg);\r\n    transform: skewX(-5deg);\r\n    opacity: 1;\r\n  }\r\n\r\n  to {\r\n    -webkit-transform: none;\r\n    transform: none;\r\n    opacity: 1;\r\n  }\r\n}\r\n\r\n.lightSpeedIn {\r\n  -webkit-animation-name: lightSpeedIn;\r\n  animation-name: lightSpeedIn;\r\n  -webkit-animation-timing-function: ease-out;\r\n  animation-timing-function: ease-out;\r\n}\r\n\r\n@-webkit-keyframes lightSpeedOut {\r\n  from {\r\n    opacity: 1;\r\n  }\r\n\r\n  to {\r\n    -webkit-transform: translate3d(100%, 0, 0) skewX(30deg);\r\n    transform: translate3d(100%, 0, 0) skewX(30deg);\r\n    opacity: 0;\r\n  }\r\n}\r\n\r\n@keyframes lightSpeedOut {\r\n  from {\r\n    opacity: 1;\r\n  }\r\n\r\n  to {\r\n    -webkit-transform: translate3d(100%, 0, 0) skewX(30deg);\r\n    transform: translate3d(100%, 0, 0) skewX(30deg);\r\n    opacity: 0;\r\n  }\r\n}\r\n\r\n.lightSpeedOut {\r\n  -webkit-animation-name: lightSpeedOut;\r\n  animation-name: lightSpeedOut;\r\n  -webkit-animation-timing-function: ease-in;\r\n  animation-timing-function: ease-in;\r\n}\r\n\r\n@-webkit-keyframes rotateIn {\r\n  from {\r\n    -webkit-transform-origin: center;\r\n    transform-origin: center;\r\n    -webkit-transform: rotate3d(0, 0, 1, -200deg);\r\n    transform: rotate3d(0, 0, 1, -200deg);\r\n    opacity: 0;\r\n  }\r\n\r\n  to {\r\n    -webkit-transform-origin: center;\r\n    transform-origin: center;\r\n    -webkit-transform: none;\r\n    transform: none;\r\n    opacity: 1;\r\n  }\r\n}\r\n\r\n@keyframes rotateIn {\r\n  from {\r\n    -webkit-transform-origin: center;\r\n    transform-origin: center;\r\n    -webkit-transform: rotate3d(0, 0, 1, -200deg);\r\n    transform: rotate3d(0, 0, 1, -200deg);\r\n    opacity: 0;\r\n  }\r\n\r\n  to {\r\n    -webkit-transform-origin: center;\r\n    transform-origin: center;\r\n    -webkit-transform: none;\r\n    transform: none;\r\n    opacity: 1;\r\n  }\r\n}\r\n\r\n.rotateIn {\r\n  -webkit-animation-name: rotateIn;\r\n  animation-name: rotateIn;\r\n}\r\n\r\n@-webkit-keyframes rotateInDownLeft {\r\n  from {\r\n    -webkit-transform-origin: left bottom;\r\n    transform-origin: left bottom;\r\n    -webkit-transform: rotate3d(0, 0, 1, -45deg);\r\n    transform: rotate3d(0, 0, 1, -45deg);\r\n    opacity: 0;\r\n  }\r\n\r\n  to {\r\n    -webkit-transform-origin: left bottom;\r\n    transform-origin: left bottom;\r\n    -webkit-transform: none;\r\n    transform: none;\r\n    opacity: 1;\r\n  }\r\n}\r\n\r\n@keyframes rotateInDownLeft {\r\n  from {\r\n    -webkit-transform-origin: left bottom;\r\n    transform-origin: left bottom;\r\n    -webkit-transform: rotate3d(0, 0, 1, -45deg);\r\n    transform: rotate3d(0, 0, 1, -45deg);\r\n    opacity: 0;\r\n  }\r\n\r\n  to {\r\n    -webkit-transform-origin: left bottom;\r\n    transform-origin: left bottom;\r\n    -webkit-transform: none;\r\n    transform: none;\r\n    opacity: 1;\r\n  }\r\n}\r\n\r\n.rotateInDownLeft {\r\n  -webkit-animation-name: rotateInDownLeft;\r\n  animation-name: rotateInDownLeft;\r\n}\r\n\r\n@-webkit-keyframes rotateInDownRight {\r\n  from {\r\n    -webkit-transform-origin: right bottom;\r\n    transform-origin: right bottom;\r\n    -webkit-transform: rotate3d(0, 0, 1, 45deg);\r\n    transform: rotate3d(0, 0, 1, 45deg);\r\n    opacity: 0;\r\n  }\r\n\r\n  to {\r\n    -webkit-transform-origin: right bottom;\r\n    transform-origin: right bottom;\r\n    -webkit-transform: none;\r\n    transform: none;\r\n    opacity: 1;\r\n  }\r\n}\r\n\r\n@keyframes rotateInDownRight {\r\n  from {\r\n    -webkit-transform-origin: right bottom;\r\n    transform-origin: right bottom;\r\n    -webkit-transform: rotate3d(0, 0, 1, 45deg);\r\n    transform: rotate3d(0, 0, 1, 45deg);\r\n    opacity: 0;\r\n  }\r\n\r\n  to {\r\n    -webkit-transform-origin: right bottom;\r\n    transform-origin: right bottom;\r\n    -webkit-transform: none;\r\n    transform: none;\r\n    opacity: 1;\r\n  }\r\n}\r\n\r\n.rotateInDownRight {\r\n  -webkit-animation-name: rotateInDownRight;\r\n  animation-name: rotateInDownRight;\r\n}\r\n\r\n@-webkit-keyframes rotateInUpLeft {\r\n  from {\r\n    -webkit-transform-origin: left bottom;\r\n    transform-origin: left bottom;\r\n    -webkit-transform: rotate3d(0, 0, 1, 45deg);\r\n    transform: rotate3d(0, 0, 1, 45deg);\r\n    opacity: 0;\r\n  }\r\n\r\n  to {\r\n    -webkit-transform-origin: left bottom;\r\n    transform-origin: left bottom;\r\n    -webkit-transform: none;\r\n    transform: none;\r\n    opacity: 1;\r\n  }\r\n}\r\n\r\n@keyframes rotateInUpLeft {\r\n  from {\r\n    -webkit-transform-origin: left bottom;\r\n    transform-origin: left bottom;\r\n    -webkit-transform: rotate3d(0, 0, 1, 45deg);\r\n    transform: rotate3d(0, 0, 1, 45deg);\r\n    opacity: 0;\r\n  }\r\n\r\n  to {\r\n    -webkit-transform-origin: left bottom;\r\n    transform-origin: left bottom;\r\n    -webkit-transform: none;\r\n    transform: none;\r\n    opacity: 1;\r\n  }\r\n}\r\n\r\n.rotateInUpLeft {\r\n  -webkit-animation-name: rotateInUpLeft;\r\n  animation-name: rotateInUpLeft;\r\n}\r\n\r\n@-webkit-keyframes rotateInUpRight {\r\n  from {\r\n    -webkit-transform-origin: right bottom;\r\n    transform-origin: right bottom;\r\n    -webkit-transform: rotate3d(0, 0, 1, -90deg);\r\n    transform: rotate3d(0, 0, 1, -90deg);\r\n    opacity: 0;\r\n  }\r\n\r\n  to {\r\n    -webkit-transform-origin: right bottom;\r\n    transform-origin: right bottom;\r\n    -webkit-transform: none;\r\n    transform: none;\r\n    opacity: 1;\r\n  }\r\n}\r\n\r\n@keyframes rotateInUpRight {\r\n  from {\r\n    -webkit-transform-origin: right bottom;\r\n    transform-origin: right bottom;\r\n    -webkit-transform: rotate3d(0, 0, 1, -90deg);\r\n    transform: rotate3d(0, 0, 1, -90deg);\r\n    opacity: 0;\r\n  }\r\n\r\n  to {\r\n    -webkit-transform-origin: right bottom;\r\n    transform-origin: right bottom;\r\n    -webkit-transform: none;\r\n    transform: none;\r\n    opacity: 1;\r\n  }\r\n}\r\n\r\n.rotateInUpRight {\r\n  -webkit-animation-name: rotateInUpRight;\r\n  animation-name: rotateInUpRight;\r\n}\r\n\r\n@-webkit-keyframes rotateOut {\r\n  from {\r\n    -webkit-transform-origin: center;\r\n    transform-origin: center;\r\n    opacity: 1;\r\n  }\r\n\r\n  to {\r\n    -webkit-transform-origin: center;\r\n    transform-origin: center;\r\n    -webkit-transform: rotate3d(0, 0, 1, 200deg);\r\n    transform: rotate3d(0, 0, 1, 200deg);\r\n    opacity: 0;\r\n  }\r\n}\r\n\r\n@keyframes rotateOut {\r\n  from {\r\n    -webkit-transform-origin: center;\r\n    transform-origin: center;\r\n    opacity: 1;\r\n  }\r\n\r\n  to {\r\n    -webkit-transform-origin: center;\r\n    transform-origin: center;\r\n    -webkit-transform: rotate3d(0, 0, 1, 200deg);\r\n    transform: rotate3d(0, 0, 1, 200deg);\r\n    opacity: 0;\r\n  }\r\n}\r\n\r\n.rotateOut {\r\n  -webkit-animation-name: rotateOut;\r\n  animation-name: rotateOut;\r\n}\r\n\r\n@-webkit-keyframes rotateOutDownLeft {\r\n  from {\r\n    -webkit-transform-origin: left bottom;\r\n    transform-origin: left bottom;\r\n    opacity: 1;\r\n  }\r\n\r\n  to {\r\n    -webkit-transform-origin: left bottom;\r\n    transform-origin: left bottom;\r\n    -webkit-transform: rotate3d(0, 0, 1, 45deg);\r\n    transform: rotate3d(0, 0, 1, 45deg);\r\n    opacity: 0;\r\n  }\r\n}\r\n\r\n@keyframes rotateOutDownLeft {\r\n  from {\r\n    -webkit-transform-origin: left bottom;\r\n    transform-origin: left bottom;\r\n    opacity: 1;\r\n  }\r\n\r\n  to {\r\n    -webkit-transform-origin: left bottom;\r\n    transform-origin: left bottom;\r\n    -webkit-transform: rotate3d(0, 0, 1, 45deg);\r\n    transform: rotate3d(0, 0, 1, 45deg);\r\n    opacity: 0;\r\n  }\r\n}\r\n\r\n.rotateOutDownLeft {\r\n  -webkit-animation-name: rotateOutDownLeft;\r\n  animation-name: rotateOutDownLeft;\r\n}\r\n\r\n@-webkit-keyframes rotateOutDownRight {\r\n  from {\r\n    -webkit-transform-origin: right bottom;\r\n    transform-origin: right bottom;\r\n    opacity: 1;\r\n  }\r\n\r\n  to {\r\n    -webkit-transform-origin: right bottom;\r\n    transform-origin: right bottom;\r\n    -webkit-transform: rotate3d(0, 0, 1, -45deg);\r\n    transform: rotate3d(0, 0, 1, -45deg);\r\n    opacity: 0;\r\n  }\r\n}\r\n\r\n@keyframes rotateOutDownRight {\r\n  from {\r\n    -webkit-transform-origin: right bottom;\r\n    transform-origin: right bottom;\r\n    opacity: 1;\r\n  }\r\n\r\n  to {\r\n    -webkit-transform-origin: right bottom;\r\n    transform-origin: right bottom;\r\n    -webkit-transform: rotate3d(0, 0, 1, -45deg);\r\n    transform: rotate3d(0, 0, 1, -45deg);\r\n    opacity: 0;\r\n  }\r\n}\r\n\r\n.rotateOutDownRight {\r\n  -webkit-animation-name: rotateOutDownRight;\r\n  animation-name: rotateOutDownRight;\r\n}\r\n\r\n@-webkit-keyframes rotateOutUpLeft {\r\n  from {\r\n    -webkit-transform-origin: left bottom;\r\n    transform-origin: left bottom;\r\n    opacity: 1;\r\n  }\r\n\r\n  to {\r\n    -webkit-transform-origin: left bottom;\r\n    transform-origin: left bottom;\r\n    -webkit-transform: rotate3d(0, 0, 1, -45deg);\r\n    transform: rotate3d(0, 0, 1, -45deg);\r\n    opacity: 0;\r\n  }\r\n}\r\n\r\n@keyframes rotateOutUpLeft {\r\n  from {\r\n    -webkit-transform-origin: left bottom;\r\n    transform-origin: left bottom;\r\n    opacity: 1;\r\n  }\r\n\r\n  to {\r\n    -webkit-transform-origin: left bottom;\r\n    transform-origin: left bottom;\r\n    -webkit-transform: rotate3d(0, 0, 1, -45deg);\r\n    transform: rotate3d(0, 0, 1, -45deg);\r\n    opacity: 0;\r\n  }\r\n}\r\n\r\n.rotateOutUpLeft {\r\n  -webkit-animation-name: rotateOutUpLeft;\r\n  animation-name: rotateOutUpLeft;\r\n}\r\n\r\n@-webkit-keyframes rotateOutUpRight {\r\n  from {\r\n    -webkit-transform-origin: right bottom;\r\n    transform-origin: right bottom;\r\n    opacity: 1;\r\n  }\r\n\r\n  to {\r\n    -webkit-transform-origin: right bottom;\r\n    transform-origin: right bottom;\r\n    -webkit-transform: rotate3d(0, 0, 1, 90deg);\r\n    transform: rotate3d(0, 0, 1, 90deg);\r\n    opacity: 0;\r\n  }\r\n}\r\n\r\n@keyframes rotateOutUpRight {\r\n  from {\r\n    -webkit-transform-origin: right bottom;\r\n    transform-origin: right bottom;\r\n    opacity: 1;\r\n  }\r\n\r\n  to {\r\n    -webkit-transform-origin: right bottom;\r\n    transform-origin: right bottom;\r\n    -webkit-transform: rotate3d(0, 0, 1, 90deg);\r\n    transform: rotate3d(0, 0, 1, 90deg);\r\n    opacity: 0;\r\n  }\r\n}\r\n\r\n.rotateOutUpRight {\r\n  -webkit-animation-name: rotateOutUpRight;\r\n  animation-name: rotateOutUpRight;\r\n}\r\n\r\n@-webkit-keyframes hinge {\r\n  0% {\r\n    -webkit-transform-origin: top left;\r\n    transform-origin: top left;\r\n    -webkit-animation-timing-function: ease-in-out;\r\n    animation-timing-function: ease-in-out;\r\n  }\r\n\r\n  20%, 60% {\r\n    -webkit-transform: rotate3d(0, 0, 1, 80deg);\r\n    transform: rotate3d(0, 0, 1, 80deg);\r\n    -webkit-transform-origin: top left;\r\n    transform-origin: top left;\r\n    -webkit-animation-timing-function: ease-in-out;\r\n    animation-timing-function: ease-in-out;\r\n  }\r\n\r\n  40%, 80% {\r\n    -webkit-transform: rotate3d(0, 0, 1, 60deg);\r\n    transform: rotate3d(0, 0, 1, 60deg);\r\n    -webkit-transform-origin: top left;\r\n    transform-origin: top left;\r\n    -webkit-animation-timing-function: ease-in-out;\r\n    animation-timing-function: ease-in-out;\r\n    opacity: 1;\r\n  }\r\n\r\n  to {\r\n    -webkit-transform: translate3d(0, 700px, 0);\r\n    transform: translate3d(0, 700px, 0);\r\n    opacity: 0;\r\n  }\r\n}\r\n\r\n@keyframes hinge {\r\n  0% {\r\n    -webkit-transform-origin: top left;\r\n    transform-origin: top left;\r\n    -webkit-animation-timing-function: ease-in-out;\r\n    animation-timing-function: ease-in-out;\r\n  }\r\n\r\n  20%, 60% {\r\n    -webkit-transform: rotate3d(0, 0, 1, 80deg);\r\n    transform: rotate3d(0, 0, 1, 80deg);\r\n    -webkit-transform-origin: top left;\r\n    transform-origin: top left;\r\n    -webkit-animation-timing-function: ease-in-out;\r\n    animation-timing-function: ease-in-out;\r\n  }\r\n\r\n  40%, 80% {\r\n    -webkit-transform: rotate3d(0, 0, 1, 60deg);\r\n    transform: rotate3d(0, 0, 1, 60deg);\r\n    -webkit-transform-origin: top left;\r\n    transform-origin: top left;\r\n    -webkit-animation-timing-function: ease-in-out;\r\n    animation-timing-function: ease-in-out;\r\n    opacity: 1;\r\n  }\r\n\r\n  to {\r\n    -webkit-transform: translate3d(0, 700px, 0);\r\n    transform: translate3d(0, 700px, 0);\r\n    opacity: 0;\r\n  }\r\n}\r\n\r\n.hinge {\r\n  -webkit-animation-name: hinge;\r\n  animation-name: hinge;\r\n}\r\n\r\n/* originally authored by Nick Pettit - https://github.com/nickpettit/glide */\r\n\r\n@-webkit-keyframes rollIn {\r\n  from {\r\n    opacity: 0;\r\n    -webkit-transform: translate3d(-100%, 0, 0) rotate3d(0, 0, 1, -120deg);\r\n    transform: translate3d(-100%, 0, 0) rotate3d(0, 0, 1, -120deg);\r\n  }\r\n\r\n  to {\r\n    opacity: 1;\r\n    -webkit-transform: none;\r\n    transform: none;\r\n  }\r\n}\r\n\r\n@keyframes rollIn {\r\n  from {\r\n    opacity: 0;\r\n    -webkit-transform: translate3d(-100%, 0, 0) rotate3d(0, 0, 1, -120deg);\r\n    transform: translate3d(-100%, 0, 0) rotate3d(0, 0, 1, -120deg);\r\n  }\r\n\r\n  to {\r\n    opacity: 1;\r\n    -webkit-transform: none;\r\n    transform: none;\r\n  }\r\n}\r\n\r\n.rollIn {\r\n  -webkit-animation-name: rollIn;\r\n  animation-name: rollIn;\r\n}\r\n\r\n/* originally authored by Nick Pettit - https://github.com/nickpettit/glide */\r\n\r\n@-webkit-keyframes rollOut {\r\n  from {\r\n    opacity: 1;\r\n  }\r\n\r\n  to {\r\n    opacity: 0;\r\n    -webkit-transform: translate3d(100%, 0, 0) rotate3d(0, 0, 1, 120deg);\r\n    transform: translate3d(100%, 0, 0) rotate3d(0, 0, 1, 120deg);\r\n  }\r\n}\r\n\r\n@keyframes rollOut {\r\n  from {\r\n    opacity: 1;\r\n  }\r\n\r\n  to {\r\n    opacity: 0;\r\n    -webkit-transform: translate3d(100%, 0, 0) rotate3d(0, 0, 1, 120deg);\r\n    transform: translate3d(100%, 0, 0) rotate3d(0, 0, 1, 120deg);\r\n  }\r\n}\r\n\r\n.rollOut {\r\n  -webkit-animation-name: rollOut;\r\n  animation-name: rollOut;\r\n}\r\n\r\n@-webkit-keyframes zoomIn {\r\n  from {\r\n    opacity: 0;\r\n    -webkit-transform: scale3d(.3, .3, .3);\r\n    transform: scale3d(.3, .3, .3);\r\n  }\r\n\r\n  50% {\r\n    opacity: 1;\r\n  }\r\n}\r\n\r\n@keyframes zoomIn {\r\n  from {\r\n    opacity: 0;\r\n    -webkit-transform: scale3d(.3, .3, .3);\r\n    transform: scale3d(.3, .3, .3);\r\n  }\r\n\r\n  50% {\r\n    opacity: 1;\r\n  }\r\n}\r\n\r\n.zoomIn {\r\n  -webkit-animation-name: zoomIn;\r\n  animation-name: zoomIn;\r\n}\r\n\r\n@-webkit-keyframes zoomInDown {\r\n  from {\r\n    opacity: 0;\r\n    -webkit-transform: scale3d(.1, .1, .1) translate3d(0, -1000px, 0);\r\n    transform: scale3d(.1, .1, .1) translate3d(0, -1000px, 0);\r\n    -webkit-animation-timing-function: cubic-bezier(0.550, 0.055, 0.675, 0.190);\r\n    animation-timing-function: cubic-bezier(0.550, 0.055, 0.675, 0.190);\r\n  }\r\n\r\n  60% {\r\n    opacity: 1;\r\n    -webkit-transform: scale3d(.475, .475, .475) translate3d(0, 60px, 0);\r\n    transform: scale3d(.475, .475, .475) translate3d(0, 60px, 0);\r\n    -webkit-animation-timing-function: cubic-bezier(0.175, 0.885, 0.320, 1);\r\n    animation-timing-function: cubic-bezier(0.175, 0.885, 0.320, 1);\r\n  }\r\n}\r\n\r\n@keyframes zoomInDown {\r\n  from {\r\n    opacity: 0;\r\n    -webkit-transform: scale3d(.1, .1, .1) translate3d(0, -1000px, 0);\r\n    transform: scale3d(.1, .1, .1) translate3d(0, -1000px, 0);\r\n    -webkit-animation-timing-function: cubic-bezier(0.550, 0.055, 0.675, 0.190);\r\n    animation-timing-function: cubic-bezier(0.550, 0.055, 0.675, 0.190);\r\n  }\r\n\r\n  60% {\r\n    opacity: 1;\r\n    -webkit-transform: scale3d(.475, .475, .475) translate3d(0, 60px, 0);\r\n    transform: scale3d(.475, .475, .475) translate3d(0, 60px, 0);\r\n    -webkit-animation-timing-function: cubic-bezier(0.175, 0.885, 0.320, 1);\r\n    animation-timing-function: cubic-bezier(0.175, 0.885, 0.320, 1);\r\n  }\r\n}\r\n\r\n.zoomInDown {\r\n  -webkit-animation-name: zoomInDown;\r\n  animation-name: zoomInDown;\r\n}\r\n\r\n@-webkit-keyframes zoomInLeft {\r\n  from {\r\n    opacity: 0;\r\n    -webkit-transform: scale3d(.1, .1, .1) translate3d(-1000px, 0, 0);\r\n    transform: scale3d(.1, .1, .1) translate3d(-1000px, 0, 0);\r\n    -webkit-animation-timing-function: cubic-bezier(0.550, 0.055, 0.675, 0.190);\r\n    animation-timing-function: cubic-bezier(0.550, 0.055, 0.675, 0.190);\r\n  }\r\n\r\n  60% {\r\n    opacity: 1;\r\n    -webkit-transform: scale3d(.475, .475, .475) translate3d(10px, 0, 0);\r\n    transform: scale3d(.475, .475, .475) translate3d(10px, 0, 0);\r\n    -webkit-animation-timing-function: cubic-bezier(0.175, 0.885, 0.320, 1);\r\n    animation-timing-function: cubic-bezier(0.175, 0.885, 0.320, 1);\r\n  }\r\n}\r\n\r\n@keyframes zoomInLeft {\r\n  from {\r\n    opacity: 0;\r\n    -webkit-transform: scale3d(.1, .1, .1) translate3d(-1000px, 0, 0);\r\n    transform: scale3d(.1, .1, .1) translate3d(-1000px, 0, 0);\r\n    -webkit-animation-timing-function: cubic-bezier(0.550, 0.055, 0.675, 0.190);\r\n    animation-timing-function: cubic-bezier(0.550, 0.055, 0.675, 0.190);\r\n  }\r\n\r\n  60% {\r\n    opacity: 1;\r\n    -webkit-transform: scale3d(.475, .475, .475) translate3d(10px, 0, 0);\r\n    transform: scale3d(.475, .475, .475) translate3d(10px, 0, 0);\r\n    -webkit-animation-timing-function: cubic-bezier(0.175, 0.885, 0.320, 1);\r\n    animation-timing-function: cubic-bezier(0.175, 0.885, 0.320, 1);\r\n  }\r\n}\r\n\r\n.zoomInLeft {\r\n  -webkit-animation-name: zoomInLeft;\r\n  animation-name: zoomInLeft;\r\n}\r\n\r\n@-webkit-keyframes zoomInRight {\r\n  from {\r\n    opacity: 0;\r\n    -webkit-transform: scale3d(.1, .1, .1) translate3d(1000px, 0, 0);\r\n    transform: scale3d(.1, .1, .1) translate3d(1000px, 0, 0);\r\n    -webkit-animation-timing-function: cubic-bezier(0.550, 0.055, 0.675, 0.190);\r\n    animation-timing-function: cubic-bezier(0.550, 0.055, 0.675, 0.190);\r\n  }\r\n\r\n  60% {\r\n    opacity: 1;\r\n    -webkit-transform: scale3d(.475, .475, .475) translate3d(-10px, 0, 0);\r\n    transform: scale3d(.475, .475, .475) translate3d(-10px, 0, 0);\r\n    -webkit-animation-timing-function: cubic-bezier(0.175, 0.885, 0.320, 1);\r\n    animation-timing-function: cubic-bezier(0.175, 0.885, 0.320, 1);\r\n  }\r\n}\r\n\r\n@keyframes zoomInRight {\r\n  from {\r\n    opacity: 0;\r\n    -webkit-transform: scale3d(.1, .1, .1) translate3d(1000px, 0, 0);\r\n    transform: scale3d(.1, .1, .1) translate3d(1000px, 0, 0);\r\n    -webkit-animation-timing-function: cubic-bezier(0.550, 0.055, 0.675, 0.190);\r\n    animation-timing-function: cubic-bezier(0.550, 0.055, 0.675, 0.190);\r\n  }\r\n\r\n  60% {\r\n    opacity: 1;\r\n    -webkit-transform: scale3d(.475, .475, .475) translate3d(-10px, 0, 0);\r\n    transform: scale3d(.475, .475, .475) translate3d(-10px, 0, 0);\r\n    -webkit-animation-timing-function: cubic-bezier(0.175, 0.885, 0.320, 1);\r\n    animation-timing-function: cubic-bezier(0.175, 0.885, 0.320, 1);\r\n  }\r\n}\r\n\r\n.zoomInRight {\r\n  -webkit-animation-name: zoomInRight;\r\n  animation-name: zoomInRight;\r\n}\r\n\r\n@-webkit-keyframes zoomInUp {\r\n  from {\r\n    opacity: 0;\r\n    -webkit-transform: scale3d(.1, .1, .1) translate3d(0, 1000px, 0);\r\n    transform: scale3d(.1, .1, .1) translate3d(0, 1000px, 0);\r\n    -webkit-animation-timing-function: cubic-bezier(0.550, 0.055, 0.675, 0.190);\r\n    animation-timing-function: cubic-bezier(0.550, 0.055, 0.675, 0.190);\r\n  }\r\n\r\n  60% {\r\n    opacity: 1;\r\n    -webkit-transform: scale3d(.475, .475, .475) translate3d(0, -60px, 0);\r\n    transform: scale3d(.475, .475, .475) translate3d(0, -60px, 0);\r\n    -webkit-animation-timing-function: cubic-bezier(0.175, 0.885, 0.320, 1);\r\n    animation-timing-function: cubic-bezier(0.175, 0.885, 0.320, 1);\r\n  }\r\n}\r\n\r\n@keyframes zoomInUp {\r\n  from {\r\n    opacity: 0;\r\n    -webkit-transform: scale3d(.1, .1, .1) translate3d(0, 1000px, 0);\r\n    transform: scale3d(.1, .1, .1) translate3d(0, 1000px, 0);\r\n    -webkit-animation-timing-function: cubic-bezier(0.550, 0.055, 0.675, 0.190);\r\n    animation-timing-function: cubic-bezier(0.550, 0.055, 0.675, 0.190);\r\n  }\r\n\r\n  60% {\r\n    opacity: 1;\r\n    -webkit-transform: scale3d(.475, .475, .475) translate3d(0, -60px, 0);\r\n    transform: scale3d(.475, .475, .475) translate3d(0, -60px, 0);\r\n    -webkit-animation-timing-function: cubic-bezier(0.175, 0.885, 0.320, 1);\r\n    animation-timing-function: cubic-bezier(0.175, 0.885, 0.320, 1);\r\n  }\r\n}\r\n\r\n.zoomInUp {\r\n  -webkit-animation-name: zoomInUp;\r\n  animation-name: zoomInUp;\r\n}\r\n\r\n@-webkit-keyframes zoomOut {\r\n  from {\r\n    opacity: 1;\r\n  }\r\n\r\n  50% {\r\n    opacity: 0;\r\n    -webkit-transform: scale3d(.3, .3, .3);\r\n    transform: scale3d(.3, .3, .3);\r\n  }\r\n\r\n  to {\r\n    opacity: 0;\r\n  }\r\n}\r\n\r\n@keyframes zoomOut {\r\n  from {\r\n    opacity: 1;\r\n  }\r\n\r\n  50% {\r\n    opacity: 0;\r\n    -webkit-transform: scale3d(.3, .3, .3);\r\n    transform: scale3d(.3, .3, .3);\r\n  }\r\n\r\n  to {\r\n    opacity: 0;\r\n  }\r\n}\r\n\r\n.zoomOut {\r\n  -webkit-animation-name: zoomOut;\r\n  animation-name: zoomOut;\r\n}\r\n\r\n@-webkit-keyframes zoomOutDown {\r\n  40% {\r\n    opacity: 1;\r\n    -webkit-transform: scale3d(.475, .475, .475) translate3d(0, -60px, 0);\r\n    transform: scale3d(.475, .475, .475) translate3d(0, -60px, 0);\r\n    -webkit-animation-timing-function: cubic-bezier(0.550, 0.055, 0.675, 0.190);\r\n    animation-timing-function: cubic-bezier(0.550, 0.055, 0.675, 0.190);\r\n  }\r\n\r\n  to {\r\n    opacity: 0;\r\n    -webkit-transform: scale3d(.1, .1, .1) translate3d(0, 2000px, 0);\r\n    transform: scale3d(.1, .1, .1) translate3d(0, 2000px, 0);\r\n    -webkit-transform-origin: center bottom;\r\n    transform-origin: center bottom;\r\n    -webkit-animation-timing-function: cubic-bezier(0.175, 0.885, 0.320, 1);\r\n    animation-timing-function: cubic-bezier(0.175, 0.885, 0.320, 1);\r\n  }\r\n}\r\n\r\n@keyframes zoomOutDown {\r\n  40% {\r\n    opacity: 1;\r\n    -webkit-transform: scale3d(.475, .475, .475) translate3d(0, -60px, 0);\r\n    transform: scale3d(.475, .475, .475) translate3d(0, -60px, 0);\r\n    -webkit-animation-timing-function: cubic-bezier(0.550, 0.055, 0.675, 0.190);\r\n    animation-timing-function: cubic-bezier(0.550, 0.055, 0.675, 0.190);\r\n  }\r\n\r\n  to {\r\n    opacity: 0;\r\n    -webkit-transform: scale3d(.1, .1, .1) translate3d(0, 2000px, 0);\r\n    transform: scale3d(.1, .1, .1) translate3d(0, 2000px, 0);\r\n    -webkit-transform-origin: center bottom;\r\n    transform-origin: center bottom;\r\n    -webkit-animation-timing-function: cubic-bezier(0.175, 0.885, 0.320, 1);\r\n    animation-timing-function: cubic-bezier(0.175, 0.885, 0.320, 1);\r\n  }\r\n}\r\n\r\n.zoomOutDown {\r\n  -webkit-animation-name: zoomOutDown;\r\n  animation-name: zoomOutDown;\r\n}\r\n\r\n@-webkit-keyframes zoomOutLeft {\r\n  40% {\r\n    opacity: 1;\r\n    -webkit-transform: scale3d(.475, .475, .475) translate3d(42px, 0, 0);\r\n    transform: scale3d(.475, .475, .475) translate3d(42px, 0, 0);\r\n  }\r\n\r\n  to {\r\n    opacity: 0;\r\n    -webkit-transform: scale(.1) translate3d(-2000px, 0, 0);\r\n    transform: scale(.1) translate3d(-2000px, 0, 0);\r\n    -webkit-transform-origin: left center;\r\n    transform-origin: left center;\r\n  }\r\n}\r\n\r\n@keyframes zoomOutLeft {\r\n  40% {\r\n    opacity: 1;\r\n    -webkit-transform: scale3d(.475, .475, .475) translate3d(42px, 0, 0);\r\n    transform: scale3d(.475, .475, .475) translate3d(42px, 0, 0);\r\n  }\r\n\r\n  to {\r\n    opacity: 0;\r\n    -webkit-transform: scale(.1) translate3d(-2000px, 0, 0);\r\n    transform: scale(.1) translate3d(-2000px, 0, 0);\r\n    -webkit-transform-origin: left center;\r\n    transform-origin: left center;\r\n  }\r\n}\r\n\r\n.zoomOutLeft {\r\n  -webkit-animation-name: zoomOutLeft;\r\n  animation-name: zoomOutLeft;\r\n}\r\n\r\n@-webkit-keyframes zoomOutRight {\r\n  40% {\r\n    opacity: 1;\r\n    -webkit-transform: scale3d(.475, .475, .475) translate3d(-42px, 0, 0);\r\n    transform: scale3d(.475, .475, .475) translate3d(-42px, 0, 0);\r\n  }\r\n\r\n  to {\r\n    opacity: 0;\r\n    -webkit-transform: scale(.1) translate3d(2000px, 0, 0);\r\n    transform: scale(.1) translate3d(2000px, 0, 0);\r\n    -webkit-transform-origin: right center;\r\n    transform-origin: right center;\r\n  }\r\n}\r\n\r\n@keyframes zoomOutRight {\r\n  40% {\r\n    opacity: 1;\r\n    -webkit-transform: scale3d(.475, .475, .475) translate3d(-42px, 0, 0);\r\n    transform: scale3d(.475, .475, .475) translate3d(-42px, 0, 0);\r\n  }\r\n\r\n  to {\r\n    opacity: 0;\r\n    -webkit-transform: scale(.1) translate3d(2000px, 0, 0);\r\n    transform: scale(.1) translate3d(2000px, 0, 0);\r\n    -webkit-transform-origin: right center;\r\n    transform-origin: right center;\r\n  }\r\n}\r\n\r\n.zoomOutRight {\r\n  -webkit-animation-name: zoomOutRight;\r\n  animation-name: zoomOutRight;\r\n}\r\n\r\n@-webkit-keyframes zoomOutUp {\r\n  40% {\r\n    opacity: 1;\r\n    -webkit-transform: scale3d(.475, .475, .475) translate3d(0, 60px, 0);\r\n    transform: scale3d(.475, .475, .475) translate3d(0, 60px, 0);\r\n    -webkit-animation-timing-function: cubic-bezier(0.550, 0.055, 0.675, 0.190);\r\n    animation-timing-function: cubic-bezier(0.550, 0.055, 0.675, 0.190);\r\n  }\r\n\r\n  to {\r\n    opacity: 0;\r\n    -webkit-transform: scale3d(.1, .1, .1) translate3d(0, -2000px, 0);\r\n    transform: scale3d(.1, .1, .1) translate3d(0, -2000px, 0);\r\n    -webkit-transform-origin: center bottom;\r\n    transform-origin: center bottom;\r\n    -webkit-animation-timing-function: cubic-bezier(0.175, 0.885, 0.320, 1);\r\n    animation-timing-function: cubic-bezier(0.175, 0.885, 0.320, 1);\r\n  }\r\n}\r\n\r\n@keyframes zoomOutUp {\r\n  40% {\r\n    opacity: 1;\r\n    -webkit-transform: scale3d(.475, .475, .475) translate3d(0, 60px, 0);\r\n    transform: scale3d(.475, .475, .475) translate3d(0, 60px, 0);\r\n    -webkit-animation-timing-function: cubic-bezier(0.550, 0.055, 0.675, 0.190);\r\n    animation-timing-function: cubic-bezier(0.550, 0.055, 0.675, 0.190);\r\n  }\r\n\r\n  to {\r\n    opacity: 0;\r\n    -webkit-transform: scale3d(.1, .1, .1) translate3d(0, -2000px, 0);\r\n    transform: scale3d(.1, .1, .1) translate3d(0, -2000px, 0);\r\n    -webkit-transform-origin: center bottom;\r\n    transform-origin: center bottom;\r\n    -webkit-animation-timing-function: cubic-bezier(0.175, 0.885, 0.320, 1);\r\n    animation-timing-function: cubic-bezier(0.175, 0.885, 0.320, 1);\r\n  }\r\n}\r\n\r\n.zoomOutUp {\r\n  -webkit-animation-name: zoomOutUp;\r\n  animation-name: zoomOutUp;\r\n}\r\n\r\n@-webkit-keyframes slideInDown {\r\n  from {\r\n    -webkit-transform: translate3d(0, -100%, 0);\r\n    transform: translate3d(0, -100%, 0);\r\n    visibility: visible;\r\n  }\r\n\r\n  to {\r\n    -webkit-transform: translate3d(0, 0, 0);\r\n    transform: translate3d(0, 0, 0);\r\n  }\r\n}\r\n\r\n@keyframes slideInDown {\r\n  from {\r\n    -webkit-transform: translate3d(0, -100%, 0);\r\n    transform: translate3d(0, -100%, 0);\r\n    visibility: visible;\r\n  }\r\n\r\n  to {\r\n    -webkit-transform: translate3d(0, 0, 0);\r\n    transform: translate3d(0, 0, 0);\r\n  }\r\n}\r\n\r\n.slideInDown {\r\n  -webkit-animation-name: slideInDown;\r\n  animation-name: slideInDown;\r\n}\r\n\r\n@-webkit-keyframes slideInLeft {\r\n  from {\r\n    -webkit-transform: translate3d(-100%, 0, 0);\r\n    transform: translate3d(-100%, 0, 0);\r\n    visibility: visible;\r\n  }\r\n\r\n  to {\r\n    -webkit-transform: translate3d(0, 0, 0);\r\n    transform: translate3d(0, 0, 0);\r\n  }\r\n}\r\n\r\n@keyframes slideInLeft {\r\n  from {\r\n    -webkit-transform: translate3d(-100%, 0, 0);\r\n    transform: translate3d(-100%, 0, 0);\r\n    visibility: visible;\r\n  }\r\n\r\n  to {\r\n    -webkit-transform: translate3d(0, 0, 0);\r\n    transform: translate3d(0, 0, 0);\r\n  }\r\n}\r\n\r\n.slideInLeft {\r\n  -webkit-animation-name: slideInLeft;\r\n  animation-name: slideInLeft;\r\n}\r\n\r\n@-webkit-keyframes slideInRight {\r\n  from {\r\n    -webkit-transform: translate3d(100%, 0, 0);\r\n    transform: translate3d(100%, 0, 0);\r\n    visibility: visible;\r\n  }\r\n\r\n  to {\r\n    -webkit-transform: translate3d(0, 0, 0);\r\n    transform: translate3d(0, 0, 0);\r\n  }\r\n}\r\n\r\n@keyframes slideInRight {\r\n  from {\r\n    -webkit-transform: translate3d(100%, 0, 0);\r\n    transform: translate3d(100%, 0, 0);\r\n    visibility: visible;\r\n  }\r\n\r\n  to {\r\n    -webkit-transform: translate3d(0, 0, 0);\r\n    transform: translate3d(0, 0, 0);\r\n  }\r\n}\r\n\r\n.slideInRight {\r\n  -webkit-animation-name: slideInRight;\r\n  animation-name: slideInRight;\r\n}\r\n\r\n@-webkit-keyframes slideInUp {\r\n  from {\r\n    -webkit-transform: translate3d(0, 100%, 0);\r\n    transform: translate3d(0, 100%, 0);\r\n    visibility: visible;\r\n  }\r\n\r\n  to {\r\n    -webkit-transform: translate3d(0, 0, 0);\r\n    transform: translate3d(0, 0, 0);\r\n  }\r\n}\r\n\r\n@keyframes slideInUp {\r\n  from {\r\n    -webkit-transform: translate3d(0, 100%, 0);\r\n    transform: translate3d(0, 100%, 0);\r\n    visibility: visible;\r\n  }\r\n\r\n  to {\r\n    -webkit-transform: translate3d(0, 0, 0);\r\n    transform: translate3d(0, 0, 0);\r\n  }\r\n}\r\n\r\n.slideInUp {\r\n  -webkit-animation-name: slideInUp;\r\n  animation-name: slideInUp;\r\n}\r\n\r\n@-webkit-keyframes slideOutDown {\r\n  from {\r\n    -webkit-transform: translate3d(0, 0, 0);\r\n    transform: translate3d(0, 0, 0);\r\n  }\r\n\r\n  to {\r\n    visibility: hidden;\r\n    -webkit-transform: translate3d(0, 100%, 0);\r\n    transform: translate3d(0, 100%, 0);\r\n  }\r\n}\r\n\r\n@keyframes slideOutDown {\r\n  from {\r\n    -webkit-transform: translate3d(0, 0, 0);\r\n    transform: translate3d(0, 0, 0);\r\n  }\r\n\r\n  to {\r\n    visibility: hidden;\r\n    -webkit-transform: translate3d(0, 100%, 0);\r\n    transform: translate3d(0, 100%, 0);\r\n  }\r\n}\r\n\r\n.slideOutDown {\r\n  -webkit-animation-name: slideOutDown;\r\n  animation-name: slideOutDown;\r\n}\r\n\r\n@-webkit-keyframes slideOutLeft {\r\n  from {\r\n    -webkit-transform: translate3d(0, 0, 0);\r\n    transform: translate3d(0, 0, 0);\r\n  }\r\n\r\n  to {\r\n    visibility: hidden;\r\n    -webkit-transform: translate3d(-100%, 0, 0);\r\n    transform: translate3d(-100%, 0, 0);\r\n  }\r\n}\r\n\r\n@keyframes slideOutLeft {\r\n  from {\r\n    -webkit-transform: translate3d(0, 0, 0);\r\n    transform: translate3d(0, 0, 0);\r\n  }\r\n\r\n  to {\r\n    visibility: hidden;\r\n    -webkit-transform: translate3d(-100%, 0, 0);\r\n    transform: translate3d(-100%, 0, 0);\r\n  }\r\n}\r\n\r\n.slideOutLeft {\r\n  -webkit-animation-name: slideOutLeft;\r\n  animation-name: slideOutLeft;\r\n}\r\n\r\n@-webkit-keyframes slideOutRight {\r\n  from {\r\n    -webkit-transform: translate3d(0, 0, 0);\r\n    transform: translate3d(0, 0, 0);\r\n  }\r\n\r\n  to {\r\n    visibility: hidden;\r\n    -webkit-transform: translate3d(100%, 0, 0);\r\n    transform: translate3d(100%, 0, 0);\r\n  }\r\n}\r\n\r\n@keyframes slideOutRight {\r\n  from {\r\n    -webkit-transform: translate3d(0, 0, 0);\r\n    transform: translate3d(0, 0, 0);\r\n  }\r\n\r\n  to {\r\n    visibility: hidden;\r\n    -webkit-transform: translate3d(100%, 0, 0);\r\n    transform: translate3d(100%, 0, 0);\r\n  }\r\n}\r\n\r\n.slideOutRight {\r\n  -webkit-animation-name: slideOutRight;\r\n  animation-name: slideOutRight;\r\n}\r\n\r\n@-webkit-keyframes slideOutUp {\r\n  from {\r\n    -webkit-transform: translate3d(0, 0, 0);\r\n    transform: translate3d(0, 0, 0);\r\n  }\r\n\r\n  to {\r\n    visibility: hidden;\r\n    -webkit-transform: translate3d(0, -100%, 0);\r\n    transform: translate3d(0, -100%, 0);\r\n  }\r\n}\r\n\r\n@keyframes slideOutUp {\r\n  from {\r\n    -webkit-transform: translate3d(0, 0, 0);\r\n    transform: translate3d(0, 0, 0);\r\n  }\r\n\r\n  to {\r\n    visibility: hidden;\r\n    -webkit-transform: translate3d(0, -100%, 0);\r\n    transform: translate3d(0, -100%, 0);\r\n  }\r\n}\r\n\r\n.slideOutUp {\r\n  -webkit-animation-name: slideOutUp;\r\n  animation-name: slideOutUp;\r\n}\r\n"
  },
  {
    "path": "app_frontend/static/theme/default/css/footer-1.css",
    "content": "\r\n/*------------------------------------------------*/\r\n/*--------------[FOOTER STYLE]-----------*/\r\n/*------------------------------------------------*/\r\n\r\n.footer {\r\n    background-color: #fff;\r\n    background-size: cover;\r\n    background-repeat: no-repeat;\r\n    background-position: 50% 0;\r\n    position: relative;\r\n    padding: 60px 0 0;\r\n}\r\n\r\n.footer .widget-title {\r\n    border-color: #333333;\r\n}\r\n\r\n.footer .copyright {\r\n    border-top: 1px solid #eeeeee;\r\n    padding: 20px 0;\r\n    margin-top: 60px;\r\n}\r\n.footer * {\r\n    color: inherit;\r\n}\r\n.footer a:hover,\r\n.footer a:focus {\r\n    text-decoration: none;\r\n    color: #a0ce4e;\r\n}\r\n\r\n.footer .list-inline {\r\n    margin-left: -15px;\r\n}\r\n\r\n.footer .list-inline > li {\r\n    padding-left: 15px;\r\n    padding-right: 15px;\r\n}\r\n\r\n.footer .list-inline > li a {\r\n    text-decoration: none;\r\n}\r\n.social-icons {\r\n    list-style: outside none none;\r\n    margin: 0;\r\n    padding: 0;\r\n}\r\n.social-icons > li {\r\n    display: inline-block;\r\n}\r\n.social-icons > li > a i {\r\n    color: #fff;\r\n}\r\n.social-icons > li a:hover i{\r\n    color: #fff;\r\n}\r\n.social-icons > li > a {\r\n    background: #787878 none repeat scroll 0 0;\r\n    display: block;\r\n    height: 32px;\r\n    line-height: 32px;\r\n    margin: 15px 8px 0 0;\r\n    text-align: center;\r\n    width: 32px;\r\n    border-radius: 50%;\r\n}\r\n.social-icons > li > a:hover{\r\n  background: #a0ce4e;\r\n}\r\n"
  },
  {
    "path": "app_frontend/static/theme/default/css/header-1.css",
    "content": "/*------------------------------------------------*/\r\n/*--------------[HEADER STYLE]-----------*/\r\n/*------------------------------------------------*/\r\n\r\n.header {\r\n\tz-index: 99;\r\n\tposition: relative;\r\n}\r\n.header .navbar {\r\n\tmargin: 0;\r\n}\r\n\r\n.header .navbar-default {\r\n\tborder: none;\r\n\tbackground: #fff none repeat scroll 0 0;\r\n        border-radius: 0;\r\n}\r\n\r\n.header .navbar-header {\r\n\tmargin: 10px 0;\r\n}\r\n.header .navbar-brand { \r\n\tz-index: 1;\r\n\tposition: relative;\r\n}\r\n\r\n@media (max-width: 768px) {\r\n\t.header .navbar-brand {\r\n\t\tpadding-left: 0;\r\n\t}\r\n}\r\n\r\n@media (max-width: 991px) {\r\n\t.header .navbar-brand {\r\n\t\tmargin-top: -10px;\r\n\t}\r\n}\r\n\r\n@media (min-width: 992px) {\r\n\t.header .navbar-brand {\r\n\t\tmargin-top: -4px;\r\n                   padding: 12px 15px;\r\n\t}\r\n}\r\n.header .navbar-default .navbar-toggle {\r\n\tborder-color: #a0ce4e;\r\n}\r\n\r\n@media (max-width: 768px) {\r\n\t.header .navbar-default .navbar-toggle {\r\n\t\tmargin-right: 0;\r\n\t}\r\n}\r\n\r\n.header .navbar-default .navbar-toggle .fa {\r\n\tcolor: #fff;\r\n\tfont-size: 19px;\r\n}\r\n\r\n.header .navbar-toggle,\r\n.header .navbar-default .navbar-toggle:hover, \r\n.header .navbar-default .navbar-toggle:focus {\r\n\tbackground: #a0ce4e;\r\n\tpadding: 6px 10px 2px;\r\n}\r\n\r\n.header .navbar-toggle:hover {\r\n\tbackground: #a0ce4e !important;\r\n}\r\n\r\n.header .navbar-collapse {\r\n\tposition: relative;\r\n}\r\n\r\n@media (min-width: 992px) {\r\n\t.header .navbar-default .navbar-nav {\r\n\t\tmargin-top: -10px;\r\n\t}\r\n}\r\n\r\n.header .navbar-default .navbar-nav > li > a {\r\n\tcolor: #687074;\r\n\tfont-size: 15px;\r\n\tfont-weight: 400;\r\n\ttext-transform: uppercase;\r\n}\r\n\r\n@media (min-width: 992px) {\r\n\t.header .navbar-nav {\r\n\t\tfloat: right;\r\n\t}\t\r\n}\r\n@media (max-width: 991px) {\r\n    .header .navbar-header {\r\n        float: none;\r\n    }\r\n    \r\n    .header .navbar-toggle {\r\n        display: block;\r\n    }\r\n    \r\n    .header .navbar-collapse.collapse {\r\n        display: none !important;\r\n    }\r\n    \r\n    .header .navbar-collapse.collapse.in {\r\n        display: block !important;\r\n  \t\toverflow-y: auto !important;\r\n    }\r\n    \r\n    .header .navbar-nav {\r\n        margin: 0 0 5px;\r\n        float: none !important;\r\n    }\r\n\r\n    .header .navbar-nav > li {\r\n        float: none;\r\n    }\r\n    \r\n    .header .navbar-nav > li > a {\r\n        padding-top: 30px;\r\n        padding-bottom: 40px;\r\n    }\r\n\t.header {\r\n\t\tborder-bottom: solid 1px #eee;\r\n\t}\r\n\r\n    .header .dropdown-menu.pull-right {\r\n\t\tfloat: none !important;\r\n\t}\r\n\r\n\t.header .navbar-nav .open .dropdown-menu {\r\n\t\tborder: 0;\r\n\t\tfloat: none;\r\n\t\twidth: auto;\r\n\t\tmargin-top: 0;\r\n\t\tposition: static;\r\n\t\tbox-shadow: none;\r\n\t\tbackground-color: transparent;\r\n\t}\r\n\r\n\t.header .navbar-nav .open .dropdown-menu > li > a,\r\n\t.header .navbar-nav .open .dropdown-menu .dropdown-header {\r\n\t\tpadding: 5px 15px 5px 25px;\r\n\t}\r\n\t\r\n\t.header .navbar-nav .open .dropdown-menu > li > a {\r\n\t\tline-height: 20px;\r\n\t}\r\n\t\r\n\t.header .navbar-nav .open .dropdown-menu > li > a:hover,\r\n\t.header .navbar-nav .open .dropdown-menu > li > a:focus {\r\n\t\tbackground-image: none;\r\n\t}\r\n\r\n\t.header .navbar-default .navbar-nav .open .dropdown-menu > li > a {\r\n\t\tcolor: #687074;\r\n\t}\r\n\r\n\t.header .navbar-default .navbar-nav .open .dropdown-menu > li > a:hover,\r\n\t.header .navbar-default .navbar-nav .open .dropdown-menu > li > a:focus {\r\n\t\tcolor: #687074;\r\n\t\tbackground-color: transparent;\r\n\t}\r\n\t\r\n\t.header .navbar-default .navbar-nav .open .dropdown-menu > .active > a,\r\n\t.header .navbar-default .navbar-nav .open .dropdown-menu > .active > a:hover,\r\n\t.header .navbar-default .navbar-nav .open .dropdown-menu > .active > a:focus {\r\n\t\tcolor: #687074;\r\n\t\tbackground-color: #e7e7e7;\r\n\t}\r\n\t\r\n\t.header .navbar-default .navbar-nav .open .dropdown-menu > .disabled > a,\r\n\t.header .navbar-default .navbar-nav .open .dropdown-menu > .disabled > a:hover,\r\n\t.header .navbar-default .navbar-nav .open .dropdown-menu > .disabled > a:focus {\r\n\t\tcolor: #ccc;\r\n\t\tbackground-color: transparent;\r\n\t}\t\r\n\r\n\t.header .navbar-default .dropdown-menu.no-bottom-space {\r\n\t\tpadding-bottom: 0;\r\n\t}\r\n\r\n  \t.header .navbar-collapse,\r\n\t.header .navbar-collapse .container {\r\n\t\tpadding-left: 0 !important;\r\n\t\tpadding-right: 0 !important;\r\n\t}\r\n\r\n\t.header .navbar-default .navbar-nav > li > a {\r\n\t\tfont-size: 14px;\r\n\t\tpadding: 9px 10px;\r\n\t}\r\n\r\n\t.header .navbar-default .navbar-nav > li a {\r\n\t\tborder-bottom: solid 1px #eee;\r\n\t}\t\r\n\r\n\t.header .navbar-default .navbar-nav > li > a:focus {\r\n\t\tbackground: none;\r\n\t}\r\n\r\n\t.header .navbar-default .navbar-nav > li > a:hover {\r\n\t\tcolor: #a0ce4e;\r\n\t}\r\n\r\n\t.header .navbar-default .navbar-nav > .active > a,\r\n\t.header .navbar-default .navbar-nav > .active > a:hover,\r\n\t.header .navbar-default .navbar-nav > .active > a:focus {\r\n\t\tbackground: #a0ce4e;\r\n\t\tcolor: #fff !important;\t\r\n\t}\r\n\r\n\t.header .dropdown .dropdown-submenu > a { \r\n\t\tfont-size: 13px;\r\n\t\tcolor: #687074 !important;\r\n\t\ttext-transform: uppercase;\r\n\t}\r\n}\r\n\r\n@media (min-width: 992px) {\t\r\n\t.header .navbar-collapse {\r\n\t\tpadding: 20px 0 0;\r\n\t}\r\n\r\n\t.header .navbar {\r\n\t\tmin-height: 40px !important;\r\n\t}\r\n\r\n\t.header .navbar-nav {\r\n\t\ttop: 2px;\r\n\t\tposition: relative;\r\n\t}\r\n\r\n\t.header .navbar-default .navbar-nav > li {\r\n\t\tmargin-left: 1px;\r\n\t}\r\n\r\n\t.header .navbar-default .navbar-nav > li > a {\r\n\t\tbottom: -2px;\r\n\t\tposition: relative;\r\n\t\tpadding: 15px 30px 17px 20px;\r\n\t}\r\n\r\n\t.header .navbar-default .navbar-nav > li > a,\r\n\t.header .navbar-default .navbar-nav > li > a:hover,\r\n\t.header .navbar-default .navbar-nav > li > a:focus {\r\n\t\tbackground: none;\r\n\t}\r\n\t\r\n\t.header .navbar-default .navbar-nav > .active > a,\r\n\t.header .navbar-default .navbar-nav > li > a:hover,\r\n\t.header .navbar-default .navbar-nav > li > a:focus {\r\n\t\tcolor: #a0ce4e;\r\n\t\tbottom: -2px;\r\n\t\tposition: relative;\r\n\t}\r\n\r\n\t.header .navbar-default .navbar-nav > li:hover > a {\r\n        color: #a0ce4e;\r\n    }\r\n\r\n\t.header .dropdown-menu { \r\n\t\tpadding: 0;\r\n\t\tborder: none;\r\n\t\tmin-width: 200px;\r\n\t\tborder-radius: 0; \r\n\t\tz-index: 9999 !important;\r\n\t\tmargin-top: -2px !important;\r\n\t\tborder-top: solid 2px #a0ce4e; \r\n\t\tborder-bottom: solid 2px #a0ce4e; \r\n\t}\r\n\r\n\t.header .dropdown-menu li a { \r\n\t\tcolor: #687074; \r\n\t\tfont-size: 13px; \r\n\t\tfont-weight: 400; \r\n\t\tpadding: 6px 15px;\r\n\t\tborder-bottom: solid 1px #eee;\r\n\t}\r\n\r\n\t.header .dropdown-menu .active > a,\r\n\t.header .dropdown-menu li > a:hover {\r\n\t\tfilter: none !important;\r\n\t\tbackground: #f5f4ec none repeat scroll 0 0 !important;\r\n                color: #687074;\r\n\t\t-webkit-transition: all 0.1s ease-in-out;\r\n\t\t-moz-transition: all 0.1s ease-in-out;\r\n\t\t-o-transition: all 0.1s ease-in-out;\r\n\t\ttransition: all 0.1s ease-in-out;\r\n\t}\r\n\r\n\t.header .dropdown-menu li > a:focus {\r\n\t\tbackground: none;\r\n\t\tfilter: none !important;\r\n\t}\r\n\r\n\t.header .navbar-nav > li.dropdown:hover > .dropdown-menu {\r\n\t\tdisplay: block;\r\n\t}\t\r\n\r\n\t.header .open > .dropdown-menu {\r\n\t\tdisplay: none;\r\n\t}\r\n\t.header .navbar .search-open {\r\n\t\twidth: 330px;\r\n\t}\r\n}\r\n\r\n.header .dropdown-submenu { \r\n   position: relative; \r\n}\r\n\r\n.header .dropdown > a:after,\r\n.header .dropdown-submenu > a:after {\r\n    top: 8px;\r\n    right: 9px;\r\n    font-size: 11px;\r\n    content: \"\\f105\";\r\n    position: absolute;\r\n    font-weight: normal;\r\n    display: inline-block;\r\n    font-family: FontAwesome;\r\n}\r\n\r\n@media (max-width: 991px) {\r\n  \t.header .dropdown-submenu > a:after {\r\n      \tcontent: \" \";\r\n  \t}\r\n}\r\n\r\n.header .dropdown > a:after {\r\n    top: 16px;\r\n    right: 15px;\r\n    content: \"\\f107\";\r\n}\r\n\r\n@media (max-width: 991px) {\r\n  \t.header .dropdown > a:after {\r\n\t    top: 11px;\r\n\t}\r\n}\r\n\r\n.header .dropdown-submenu > .dropdown-menu { \r\n\ttop: 0; \r\n\tleft: 100%; \r\n\tmargin-top: -5px; \r\n\tmargin-left: 0px; \r\n}\r\n\r\n.header .dropdown-submenu > .dropdown-menu.submenu-left {\r\n\tleft: -100%;\r\n}\r\n\r\n.header .dropdown-submenu:hover > .dropdown-menu {  \r\n   \tdisplay: block;\r\n}\r\n\r\n@media (max-width: 991px) {\r\n\t.header .dropdown-submenu > .dropdown-menu {  \r\n\t\tdisplay: block;\r\n\t\tmargin-left: 15px;\r\n\t}\r\n}\r\n\r\n.header .dropdown-submenu.pull-left {\r\n\tfloat: none;\r\n}\r\n\r\n.header .dropdown-submenu.pull-left > .dropdown-menu {\r\n\tleft: -100%;\r\n\tmargin-left: 10px;\r\n}\r\n\r\n.header .dropdown-menu li [class^=\"fa-\"],\r\n.header .dropdown-menu li [class*=\" fa-\"] {\r\n\tleft: -3px;\r\n\twidth: 1.25em;\r\n\tmargin-right: 1px;\r\n\tposition: relative;\r\n\ttext-align: center;\r\n\tdisplay: inline-block;\r\n}\r\n.header .dropdown-menu li [class^=\"fa-\"].fa-lg,\r\n.header .dropdown-menu li [class*=\" fa-\"].fa-lg {\r\n\twidth: 1.5625em;\r\n}\r\n\r\n.header .navbar .nav > li > .search {\r\n\tcolor: #aaa;\r\n\tcursor: pointer;\r\n\tfont-size: 15px;\r\n\tmin-width: 30px;\r\n\tpadding: 18px 0;\r\n\ttext-align: center;\r\n\tdisplay: inline-block;\r\n}\r\n\r\n.header .navbar .nav > li > .search:hover {\r\n\tcolor: #a0ce4e;\r\n}\r\n\r\n.header .navbar .search-open {\r\n\tright: 0; \r\n\ttop: 51px; \r\n\tdisplay: none;\r\n\tpadding: 14px; \r\n\tposition: absolute;\r\n\tbackground: #fff; \r\n\tbox-shadow: 0 0 3px #ddd; \r\n}\r\n\r\n.header .navbar .search-open form {\r\n\tmargin: 0;\t\r\n}\r\n\r\n@media (min-width: 767px) and (max-width: 991px) {\r\n\t.header .navbar > .container .navbar-brand, \r\n\t.header .navbar > .container-fluid .navbar-brand {\r\n\t\tmargin-left: -10px;\r\n\t}\r\n\r\n\t.header .navbar-toggle {\r\n\t\tmargin-right: 0;\r\n\t}\r\n}\r\n\r\n@media (max-width: 991px) {\r\n\t.header .navbar .nav > li > .search {\r\n            display:none;\r\n        }\r\n}\r\n.header .mega-menu .nav,\r\n.header .mega-menu .dropup,\r\n.header .mega-menu .dropdown,\r\n.header .mega-menu .collapse {\r\n  \tposition: static;\r\n}\r\n\r\n.header .mega-menu .navbar-inner,\r\n.header .mega-menu .container {\r\n  \tposition: relative;\r\n}\r\n\r\n.header .mega-menu .dropdown-menu {\r\n  \tleft: auto;\r\n}\r\n\r\n.header .mega-menu .dropdown-menu > li {\r\n  \tdisplay: block;\r\n}\r\n\r\n.header .mega-menu .dropdown-submenu .dropdown-menu {\r\n  \tleft: 100%;\r\n}\r\n.header .mega-menu .nav.pull-right .dropdown-menu {\r\n  \tright: 0;\r\n}\r\n\r\n.header .mega-menu .menu-content {\r\n  \t*zoom: 1;\r\n  \tpadding: 0;\r\n}\r\n\r\n.header .mega-menu .menu-content:before,\r\n.header .mega-menu .menu-content:after {\r\n  \tcontent: \"\";\r\n  \tdisplay: table;\r\n  \tline-height: 0;\r\n}\r\n\r\n.header .mega-menu .menu-content:after {\r\n  \tclear: both;\r\n}\r\n\r\n.header .mega-menu.navbar .nav > li > .dropdown-menu:after,\r\n.header .mega-menu.navbar .nav > li > .dropdown-menu:before {\r\n  \tdisplay: none;\r\n}\r\n\r\n.header .mega-menu .dropdown.mega-menu-fullwidth .dropdown-menu {\r\n  \tleft: 0;\r\n  \tright: 0;\r\n  \toverflow: hidden;\r\n}\r\n\r\n@media (min-width: 992px) {\r\n\t.header .mega-menu .dropdown.mega-menu-fullwidth .dropdown-menu {\r\n  \t\tmargin-left: 15px;\r\n  \t\tmargin-right: 15px;\r\n\t}\r\n}\r\n@media (min-width: 992px) {\r\n\t.header .mega-menu .cv-menu-col-body {\r\n\t    display: -webkit-flex;\r\n\t    display: -ms-flexbox;\r\n\t    display: flex;\r\n\t}\r\n\r\n\t.header .mega-menu .cv-menu-col {\r\n\t    display: -webkit-flex;\r\n\t    display: -ms-flexbox;\r\n\t    display: flex;\r\n\t}\r\n}\r\n.header .mega-menu .cv-menu-list h3 {\r\n\tfont-size: 15px;\r\n\tpadding: 0 10px;\r\n\tfont-weight: 400;\r\n\ttext-transform: uppercase;\r\n}\r\n@media (min-width: 992px) {\r\n\t.header .mega-menu .big-screen-space {\r\n\t\tmargin-bottom: 20px;\r\n\t}\r\n}\r\n@media (min-width: 992px) {\r\n    .header .mega-menu .cv-menu-col {\r\n        padding: 20px 0;\r\n        border-left: 1px solid #eee;\r\n    }\r\n\r\n    .header .mega-menu .cv-menu-col:first-child {\r\n        border-left: none;\r\n        margin-left: -1px;\r\n    }\r\n\r\n    .header .mega-menu .cv-menu-list {\r\n    \twidth: 100%;\r\n    }\r\n\r\n    .header .mega-menu .cv-menu-list li a {\r\n        display: block;\r\n        position: relative;\r\n        border-bottom: none;\r\n        padding: 5px 10px 5px 15px;\r\n    }\r\n\r\n    .header .mega-menu .cv-menu-list a:hover {\r\n    \ttext-decoration: none;\r\n    }\r\n    \r\n    .header .mega-menu .mega-menu-fullwidth li a {\r\n    \tpadding: 5px 10px 5px 30px;\t\r\n    }\r\n\r\n    .header .mega-menu .mega-menu-fullwidth li a:after {\r\n        top: 7px;\r\n        left: 15px;\r\n        font-size: 11px;\r\n        content: \"\\f105\";\r\n        position: absolute;\r\n        font-weight: normal;\r\n        display: inline-block;\r\n        font-family: FontAwesome;\r\n    }\r\n    .header .mega-menu .mega-menu-fullwidth .icons-disable li a {\r\n    \tpadding: 5px 10px 5px 15px;\r\n    }\r\n\r\n    .header .mega-menu .mega-menu-fullwidth .icons-disable li a:after {\r\n    \tdisplay: none;\r\n    }\r\n}\r\n\r\n@media (min-width: 737px) and (max-width: 991px) {\r\n\t.header .mega-menu .menu-content .container {\r\n\t\twidth: 690px !important;\r\n\t}\r\n\r\n\t.header .mega-menu .cv-menu-col-body {\r\n\t\tmargin-right: 0;\r\n\t}\r\n\r\n\t.header .mega-menu .cv-menu-col {\r\n    \tpadding-right: 0;\r\n    \tmargin-right: -15px;\r\n    }\r\n}\r\n\r\n@media (max-width: 991px) {\r\n\t.header .mega-menu .cv-menu-col-body {\r\n\t\tmargin-right: 0;\r\n\t}\r\n\r\n\t.header .mega-menu .cv-menu-col {\r\n    \tpadding-right: 0;\r\n    }\r\n}\r\n\r\n@media (max-width: 991px) {\r\n    .header .mega-menu .dropdown.mega-menu-fullwidth .dropdown-menu {\r\n        width: auto;\r\n    }\r\n\r\n    .header .mega-menu .cv-menu-col,\r\n    .header .mega-menu .cv-menu-list {\r\n        display: block;\r\n    }\r\n\r\n    .header .mega-menu .mega-menu-fullwidth .dropdown-menu > li > ul {\r\n        display: block;\r\n    }\r\n    .header .mega-menu .cv-menu-list h3 { \r\n\t\tcolor: #687074; \r\n\t\tmargin: 0 0 5px;\r\n\t\tfont-size: 13px; \r\n\t\tfont-weight: 400; \r\n\t\tpadding: 6px 25px 5px; \r\n\t\tborder-bottom: solid 1px #eee;\r\n\t}\r\n\r\n\t.header .mega-menu .cv-menu-list li {\r\n\t\tmargin-left: 15px;\r\n\t}\r\n\r\n\t.header .mega-menu .cv-menu-list li a {\r\n\t\tcolor: #687074;\r\n\t\tdisplay: block;\r\n\t\tfont-size: 13px; \r\n\t\tfont-weight: 400; \r\n\t\tpadding: 6px 25px; \r\n\t\tborder-bottom: solid 1px #eee;\r\n\t}\r\n\r\n\t.header .mega-menu .cv-menu-list > h3.active,\r\n\t.header .mega-menu .cv-menu-list > .active > a,\r\n\t.header .mega-menu .cv-menu-list > .active > a:hover,\r\n\t.header .mega-menu .cv-menu-list > .active > a:focus {\r\n\t\tcolor: #687074;\r\n\t\tbackground-color: #e7e7e7;\r\n\t}\r\n\r\n\t.header .mega-menu .cv-menu-list li a:hover {\r\n\t\tcolor: #687074;\r\n\t\ttext-decoration: none;\r\n\t}\r\n}\r\n.search-click {\r\n    background: #a0ce4e none repeat scroll 0 0;\r\n    border: 0 none;\r\n    color: #fff;\r\n    cursor: pointer;\r\n    display: inline-block;\r\n    font-size: 14px;\r\n    font-weight: 400;\r\n    padding: 7px 13px;\r\n    position: relative;\r\n    text-decoration: none;\r\n    white-space: nowrap;\r\n}\r\n"
  },
  {
    "path": "app_frontend/static/theme/default/css/magnific-popup.css",
    "content": "/* Magnific Popup CSS */\r\n.mfp-bg {\r\n  top: 0;\r\n  left: 0;\r\n  width: 100%;\r\n  height: 100%;\r\n  z-index: 104200;\r\n  overflow: hidden;\r\n  position: fixed;\r\n  background: #0b0b0b;\r\n  opacity: 0.8;\r\n  filter: alpha(opacity=80); }\r\n\r\n.mfp-wrap {\r\n  top: 0;\r\n  left: 0;\r\n  width: 100%;\r\n  height: 100%;\r\n  z-index: 104300;\r\n  position: fixed;\r\n  outline: none !important;\r\n  -webkit-backface-visibility: hidden; }\r\n\r\n.mfp-container {\r\n  text-align: center;\r\n  position: absolute;\r\n  width: 100%;\r\n  height: 100%;\r\n  left: 0;\r\n  top: 0;\r\n  padding: 0 8px;\r\n  -webkit-box-sizing: border-box;\r\n  -moz-box-sizing: border-box;\r\n  box-sizing: border-box; }\r\n\r\n.mfp-container:before {\r\n  content: '';\r\n  display: inline-block;\r\n  height: 100%;\r\n  vertical-align: middle; }\r\n\r\n.mfp-align-top .mfp-container:before {\r\n  display: none; }\r\n\r\n.mfp-content {\r\n  position: relative;\r\n  display: inline-block;\r\n  vertical-align: middle;\r\n  margin: 0 auto;\r\n  text-align: left;\r\n  z-index: 104500; }\r\n\r\n.mfp-inline-holder .mfp-content, .mfp-ajax-holder .mfp-content {\r\n  width: 100%;\r\n  cursor: auto; }\r\n\r\n.mfp-ajax-cur {\r\n  cursor: progress; }\r\n\r\n.mfp-zoom-out-cur, .mfp-zoom-out-cur .mfp-image-holder .mfp-close {\r\n  cursor: -moz-zoom-out;\r\n  cursor: -webkit-zoom-out;\r\n  cursor: zoom-out; }\r\n\r\n.mfp-zoom {\r\n  cursor: pointer;\r\n  cursor: -webkit-zoom-in;\r\n  cursor: -moz-zoom-in;\r\n  cursor: zoom-in; }\r\n\r\n.mfp-auto-cursor .mfp-content {\r\n  cursor: auto; }\r\n\r\n.mfp-close, .mfp-arrow, .mfp-preloader, .mfp-counter {\r\n  -webkit-user-select: none;\r\n  -moz-user-select: none;\r\n  user-select: none; }\r\n\r\n.mfp-loading.mfp-figure {\r\n  display: none; }\r\n\r\n.mfp-hide {\r\n  display: none !important; }\r\n\r\n.mfp-preloader {\r\n  color: #cccccc;\r\n  position: absolute;\r\n  top: 50%;\r\n  width: auto;\r\n  text-align: center;\r\n  margin-top: -0.8em;\r\n  left: 8px;\r\n  right: 8px;\r\n  z-index: 104400; }\r\n  .mfp-preloader a {\r\n    color: #cccccc; }\r\n    .mfp-preloader a:hover {\r\n      color: white; }\r\n\r\n.mfp-s-ready .mfp-preloader {\r\n  display: none; }\r\n\r\n.mfp-s-error .mfp-content {\r\n  display: none; }\r\n\r\nbutton.mfp-close, button.mfp-arrow {\r\n  overflow: visible;\r\n  cursor: pointer;\r\n  background: transparent;\r\n  border: 0;\r\n  -webkit-appearance: none;\r\n  display: block;\r\n  outline: none;\r\n  padding: 0;\r\n  z-index: 104600;\r\n  -webkit-box-shadow: none;\r\n  box-shadow: none; }\r\nbutton::-moz-focus-inner {\r\n  padding: 0;\r\n  border: 0; }\r\n\r\n.mfp-close {\r\n  width: 44px;\r\n  height: 44px;\r\n  line-height: 44px;\r\n  position: absolute;\r\n  right: 0;\r\n  top: 0;\r\n  text-decoration: none;\r\n  text-align: center;\r\n  opacity: 0.65;\r\n  filter: alpha(opacity=65);\r\n  padding: 0 0 18px 10px;\r\n  color: white;\r\n  font-style: normal;\r\n  font-size: 28px;\r\n  font-family: Arial, Baskerville, monospace; }\r\n  .mfp-close:hover, .mfp-close:focus {\r\n    opacity: 1;\r\n    filter: alpha(opacity=100); }\r\n  .mfp-close:active {\r\n    top: 1px; }\r\n\r\n.mfp-close-btn-in .mfp-close {\r\n  color: #333333; }\r\n\r\n.mfp-image-holder .mfp-close, .mfp-iframe-holder .mfp-close {\r\n  color: white;\r\n  right: -6px;\r\n  text-align: right;\r\n  padding-right: 6px;\r\n  width: 100%; }\r\n\r\n.mfp-counter {\r\n  position: absolute;\r\n  top: 0;\r\n  right: 0;\r\n  color: #cccccc;\r\n  font-size: 12px;\r\n  line-height: 18px;\r\n  white-space: nowrap; }\r\n\r\n.mfp-arrow {\r\n  position: absolute;\r\n  opacity: 0.65;\r\n  filter: alpha(opacity=65);\r\n  margin: 0;\r\n  top: 50%;\r\n  margin-top: -55px;\r\n  padding: 0;\r\n  width: 90px;\r\n  height: 110px;\r\n  -webkit-tap-highlight-color: rgba(0, 0, 0, 0); }\r\n  .mfp-arrow:active {\r\n    margin-top: -54px; }\r\n  .mfp-arrow:hover, .mfp-arrow:focus {\r\n    opacity: 1;\r\n    filter: alpha(opacity=100); }\r\n  .mfp-arrow:before, .mfp-arrow:after, .mfp-arrow .mfp-b, .mfp-arrow .mfp-a {\r\n    content: '';\r\n    display: block;\r\n    width: 0;\r\n    height: 0;\r\n    position: absolute;\r\n    left: 0;\r\n    top: 0;\r\n    margin-top: 35px;\r\n    margin-left: 35px;\r\n    border: medium inset transparent; }\r\n  .mfp-arrow:after, .mfp-arrow .mfp-a {\r\n    border-top-width: 13px;\r\n    border-bottom-width: 13px;\r\n    top: 8px; }\r\n  .mfp-arrow:before, .mfp-arrow .mfp-b {\r\n    border-top-width: 21px;\r\n    border-bottom-width: 21px;\r\n    opacity: 0.7; }\r\n\r\n.mfp-arrow-left {\r\n  left: 0; }\r\n  .mfp-arrow-left:after, .mfp-arrow-left .mfp-a {\r\n    border-right: 17px solid white;\r\n    margin-left: 31px; }\r\n  .mfp-arrow-left:before, .mfp-arrow-left .mfp-b {\r\n    margin-left: 25px;\r\n    border-right: 27px solid #3f3f3f; }\r\n\r\n.mfp-arrow-right {\r\n  right: 0; }\r\n  .mfp-arrow-right:after, .mfp-arrow-right .mfp-a {\r\n    border-left: 17px solid white;\r\n    margin-left: 39px; }\r\n  .mfp-arrow-right:before, .mfp-arrow-right .mfp-b {\r\n    border-left: 27px solid #3f3f3f; }\r\n\r\n.mfp-iframe-holder {\r\n  padding-top: 40px;\r\n  padding-bottom: 40px; }\r\n  .mfp-iframe-holder .mfp-content {\r\n    line-height: 0;\r\n    width: 100%;\r\n    max-width: 900px; }\r\n  .mfp-iframe-holder .mfp-close {\r\n    top: -40px; }\r\n\r\n.mfp-iframe-scaler {\r\n  width: 100%;\r\n  height: 0;\r\n  overflow: hidden;\r\n  padding-top: 56.25%; }\r\n  .mfp-iframe-scaler iframe {\r\n    position: absolute;\r\n    display: block;\r\n    top: 0;\r\n    left: 0;\r\n    width: 100%;\r\n    height: 100%;\r\n    box-shadow: 0 0 8px rgba(0, 0, 0, 0.6);\r\n    background: black; }\r\n\r\n/* Main image in popup */\r\nimg.mfp-img {\r\n  width: auto;\r\n  max-width: 100%;\r\n  height: auto;\r\n  display: block;\r\n  line-height: 0;\r\n  -webkit-box-sizing: border-box;\r\n  -moz-box-sizing: border-box;\r\n  box-sizing: border-box;\r\n  padding: 40px 0 40px;\r\n  margin: 0 auto; }\r\n\r\n/* The shadow behind the image */\r\n.mfp-figure {\r\n  line-height: 0; }\r\n  .mfp-figure:after {\r\n    content: '';\r\n    position: absolute;\r\n    left: 0;\r\n    top: 40px;\r\n    bottom: 40px;\r\n    display: block;\r\n    right: 0;\r\n    width: auto;\r\n    height: auto;\r\n    z-index: -1;\r\n    box-shadow: 0 0 8px rgba(0, 0, 0, 0.6);\r\n    background: #444444; }\r\n  .mfp-figure small {\r\n    color: #bdbdbd;\r\n    display: block;\r\n    font-size: 12px;\r\n    line-height: 14px; }\r\n  .mfp-figure figure {\r\n    margin: 0; }\r\n\r\n.mfp-bottom-bar {\r\n  margin-top: -36px;\r\n  position: absolute;\r\n  top: 100%;\r\n  left: 0;\r\n  width: 100%;\r\n  cursor: auto; }\r\n\r\n.mfp-title {\r\n  text-align: left;\r\n  line-height: 18px;\r\n  color: #f3f3f3;\r\n  word-wrap: break-word;\r\n  padding-right: 36px; }\r\n\r\n.mfp-image-holder .mfp-content {\r\n  max-width: 100%; }\r\n\r\n.mfp-gallery .mfp-image-holder .mfp-figure {\r\n  cursor: pointer; }\r\n\r\n@media screen and (max-width: 800px) and (orientation: landscape), screen and (max-height: 300px) {\r\n  /**\r\n       * Remove all paddings around the image on small screen\r\n       */\r\n  .mfp-img-mobile .mfp-image-holder {\r\n    padding-left: 0;\r\n    padding-right: 0; }\r\n  .mfp-img-mobile img.mfp-img {\r\n    padding: 0; }\r\n  .mfp-img-mobile .mfp-figure:after {\r\n    top: 0;\r\n    bottom: 0; }\r\n  .mfp-img-mobile .mfp-figure small {\r\n    display: inline;\r\n    margin-left: 5px; }\r\n  .mfp-img-mobile .mfp-bottom-bar {\r\n    background: rgba(0, 0, 0, 0.6);\r\n    bottom: 0;\r\n    margin: 0;\r\n    top: auto;\r\n    padding: 3px 5px;\r\n    position: fixed;\r\n    -webkit-box-sizing: border-box;\r\n    -moz-box-sizing: border-box;\r\n    box-sizing: border-box; }\r\n    .mfp-img-mobile .mfp-bottom-bar:empty {\r\n      padding: 0; }\r\n  .mfp-img-mobile .mfp-counter {\r\n    right: 5px;\r\n    top: 3px; }\r\n  .mfp-img-mobile .mfp-close {\r\n    top: 0;\r\n    right: 0;\r\n    width: 35px;\r\n    height: 35px;\r\n    line-height: 35px;\r\n    background: rgba(0, 0, 0, 0.6);\r\n    position: fixed;\r\n    text-align: center;\r\n    padding: 0; } }\r\n\r\n@media all and (max-width: 900px) {\r\n  .mfp-arrow {\r\n    -webkit-transform: scale(0.75);\r\n    transform: scale(0.75); }\r\n  .mfp-arrow-left {\r\n    -webkit-transform-origin: 0;\r\n    transform-origin: 0; }\r\n  .mfp-arrow-right {\r\n    -webkit-transform-origin: 100%;\r\n    transform-origin: 100%; }\r\n  .mfp-container {\r\n    padding-left: 6px;\r\n    padding-right: 6px; } }\r\n\r\n.mfp-ie7 .mfp-img {\r\n  padding: 0; }\r\n.mfp-ie7 .mfp-bottom-bar {\r\n  width: 600px;\r\n  left: 50%;\r\n  margin-left: -300px;\r\n  margin-top: 5px;\r\n  padding-bottom: 5px; }\r\n.mfp-ie7 .mfp-container {\r\n  padding: 0; }\r\n.mfp-ie7 .mfp-content {\r\n  padding-top: 44px; }\r\n.mfp-ie7 .mfp-close {\r\n  top: 0;\r\n  right: 0;\r\n  padding-top: 0; }\r\n"
  },
  {
    "path": "app_frontend/static/theme/default/css/style.css",
    "content": "﻿/**\r\nTheme Name: Classify Creative Multipurpose HTML5 Template\r\nTheme URI: \r\nDescription: Classify Creative Multipurpose HTML5 Template!\r\nAuthor: CraftDzine\r\nAuthor URI: http://demo.craftdzine.com/\r\nLicense: Commercial\r\nLicense URI: http://themeforest.net/licenses/regular_extended\r\nblog, bootstrap, bootstrap HTML5 template, bootstrap responsive theme, business, clean, corporate, creative, css3, finance, html5, portfolio, responsive \r\nVersion: 1.0\r\n*/\r\n\r\n/**\r\n1. CSS RESET \r\n\r\n/*------------------------------------------------*/\r\n/*-----------------[RESET]------------------------*/\r\n/*------------------------------------------------*/\r\nhtml, body, div, span, applet, object, iframe,\r\nh1, h2, h3, h4, h5, h6, p, blockquote, pre,\r\na, abbr, acronym, address, big, cite, code,\r\ndel, dfn, em, font, img, ins, kbd, q, s, samp,\r\nsmall, strike, strong, sub, sup, tt, var,\r\nb, u, i, center,\r\ndl, dt, dd, ol, ul, li,\r\nfieldset, form, label, legend { margin: 0; padding: 0; border: 0; outline: 0; font-size: 100%; vertical-align: baseline; background: transparent; }\r\n\r\nbody { line-height: 1; }\r\nol, ul { list-style: none; }\r\nblockquote, q {\tquotes: none; }\r\n\r\nblockquote:before, blockquote:after,q:before, q:after { content: ''; content: none; }\r\n\r\n/* remember to define focus styles! */\r\n:focus { outline: 0; }\r\n\r\n/* remember to highlight inserts somehow! */\r\nins { text-decoration: none; }\r\ndel { text-decoration: line-through; }\r\n\r\n/* tables still need 'cellspacing=\"0\"' in the markup */\r\ntable { border-collapse: collapse; border-spacing: 0; }\r\n\r\narticle, aside, footer, header, hgroup, nav, section { display: block; }\r\n/*------------------------------------------------*/\r\n/*--------------[General Style]------------------*/\r\n/*------------------------------------------------*/\r\nbody {\r\n    line-height: 1.5em;\r\n    color: #787878;\r\n    font-size: 13px;\r\n    font-family: \"Open Sans\",sans-serif;\r\n    letter-spacing: 0.5px;\r\n    margin: 0 auto;\r\n    padding: 0 auto;\r\n    background: #f4f4f4;\r\n}\r\nimg {\r\n    height: auto;\r\n    max-width: 100%;\r\n    border: none;\r\n    outline: none;\r\n    transition: all 0.2s ease 0s;\r\n    -moz-transition: all 0.2s ease 0s;\r\n    -webkit-transition: all 0.2s ease 0s;\r\n    -o-transition: all 0.2s ease 0s;\r\n}\r\na, a:active, a:link, img {\r\n    outline: none;\r\n}\r\na:focus {\r\n    color: inherit;\r\n    text-decoration: none;\r\n    outline: none;\r\n}\r\na {\r\n    cursor: pointer;\r\n    text-decoration: none;\r\n    color: #787878;\r\n    transition: all 0.25s ease 0s;\r\n    -moz-transition: all 0.25s ease 0s;\r\n    -webkit-transition: all 0.25s ease 0s;\r\n    -o-transition: all 0.25s ease 0s;\r\n}\r\na:hover {\r\n    color: #a0ce4e;\r\n    text-decoration: none;\r\n    transition: all 0.25s ease 0s;\r\n    -moz-transition: all 0.25s ease 0s;\r\n    -webkit-transition: all 0.25s ease 0s;\r\n    -o-transition: all 0.25s ease 0s;\r\n}\r\n.video {\r\n    display: block;\r\n}\r\n.audio {\r\n    width: 100%;\r\n}\r\nbr {\r\n    font-size: 0;\r\n    line-height: 0;\r\n}\r\nhr {\r\n    margin-bottom: 15px;\r\n    margin-top: 15px;\r\n    border-top: 1px solid #f1f1f1;\r\n    border-bottom: none;\r\n    border-left: none;\r\n    border-right: none;\r\n}\r\nhr:last-child, .progress:last-child, .buttons p:last-child, .image-block-content:last-child {\r\n    margin: 0;\r\n}\r\nb, strong {\r\n    font-weight: 600;\r\n}\r\n\r\nsmall, small a {\r\n    font-size: 11px;\r\n    color: inherit;\r\n}\r\np {\r\n    line-height: 1.875em;\r\n    margin: 0;\r\n}\r\nh1, h2, h3, h4, h5, h6 {\r\n    color: inherit;\r\n    text-transform: uppercase;\r\n    font-family: 'Raleway', sans-serif;\r\n    margin-top: 0px;\r\n    margin-bottom: 0;\r\n    line-height: 1.5em;\r\n}\r\nh1 { font-size: 30px; letter-spacing: 1px;}\r\nh2 { font-size: 24px; letter-spacing: 1px;}\r\nh3 { font-size: 22px; letter-spacing: 1px;}\r\nh4 { font-size: 18px; letter-spacing: 1px;}\r\nh5 { font-size: 16px; letter-spacing: 1px;}\r\nh6 { font-size: 14px; letter-spacing: 1px;}\r\n\r\nlabel {\r\n    color: inherit;\r\n    font-weight: 600;\r\n    font-family: 'Raleway', sans-serif;\r\n}\r\n.overflow-h {\r\n    overflow: hidden;\r\n}\r\nul.list-inline {\r\n    margin-left: 0;\r\n}\r\n.home-main-contant-style{\r\n    padding: 80px 0;\r\n}\r\n.home-main-contant-style2{\r\n    padding-top: 80px;\r\n}\r\n.home-main-contant-style3{\r\n    padding-bottom: 80px;\r\n}\r\n.main-contain{\r\n    padding: 80px 0;\r\n}\r\n.mb30{\r\n    margin-bottom: 30px;\r\n}\r\n.mb45{\r\n    margin-bottom: 45px;\r\n}\r\n.mt30{\r\n    margin-top: 30px;\r\n}\r\n.mr15{\r\n    margin-right:15px;\r\n}\r\n.mb15{\r\n    margin-bottom: 15px;\r\n}\r\n.mb10{\r\n    margin-bottom: 10px;\r\n}\r\n.mb5{\r\n    margin-bottom: 5px;\r\n}\r\n.pbt30{\r\n    padding: 25px 0;\r\n}\r\n.bg-gray {\r\n    background: #f8f9f9;\r\n}\r\n.bg-white{\r\n    background: #fff;\r\n}\r\n.bg-black{\r\n    background-color: #222;\r\n}\r\n.bg-theme {\r\n    background-color: #a0ce4e;\r\n}\r\n.bordertop1{\r\n    border-top:1px solid #ddd;\r\n}\r\n.main-theme-color1{\r\n    background: #a0ce4e;  \r\n}\r\n.animated-img {\r\n    margin-right: 30px;\r\n}\r\n.animated-title {\r\n    font-size: 18px;\r\n    font-weight: 700;\r\n}\r\n.full-image img{\r\n    height: auto;\r\n    max-width: 100%;\r\n    vertical-align: top;\r\n}\r\n/*------------------------------------------------*/\r\n/*--------------[PAGE HEADING BREADCRUMB]-----------*/\r\n/*------------------------------------------------*/\r\n.page-heading::after {\r\n    background: rgba(0, 0, 0, 0.8) none repeat scroll 0 0;\r\n    bottom: 0;\r\n    content: \"\";\r\n    left: 0;\r\n    position: absolute;\r\n    right: 0;\r\n    top: 0;\r\n    z-index: -1;\r\n}\r\n\r\n.page-heading {\r\n    background: rgba(0, 0, 0, 0) url(\"../img/breadcrumb.jpg\") no-repeat fixed center center / cover ;\r\n    padding: 80px 0;\r\n    position: relative;\r\n    z-index: 1;\r\n}\r\n\r\n.page-heading .title {\r\n    font-family: \"Raleway\";\r\n    font-size: 54px;\r\n    font-weight: bold;\r\n    line-height: 1;\r\n    text-transform: uppercase;\r\n    color: #fff;\r\n}\r\n.page-heading .breadcrumb{\r\n    font-size: 16px;\r\n    text-transform: none;\r\n    color: #fff;\r\n    background: none;\r\n    border-radius: 0;\r\n    margin-bottom: 0;\r\n}\r\n.page-heading .breadcrumb > a {\r\n    color: #fff;\r\n}\r\n.page-heading .breadcrumb > a:hover{\r\n    text-decoration: underline;\r\n    color: #a0ce4e;\r\n}\r\n/*------------------------------------------------*/\r\n/*-------------[Buttons Style]----------------*/\r\n/*------------------------------------------------*/\r\n.btn {\r\n    transition: all 0.2s ease-in-out;\r\n    -moz-transition: all 0.2s ease-in-out;\r\n    -webkit-transition: all 0.2s ease-in-out;\r\n    -o-transition: all 0.2s ease-in-out;\r\n}\r\n\r\n.btn-custom {\r\n    width: auto;\r\n    display: inline-block;\r\n    color: #fff;\r\n    margin-right: 5px;\r\n    border:0;\r\n    border-radius: 5px;\r\n}\r\n\r\n.btn-custom:last-child {\r\n    margin-right: 0;\r\n}\r\n.btn-custom {\r\n    background-color: #a0ce4e ;\r\n}\r\n.btn-custom.border-btn:hover {\r\n    background-color: #a0ce4e ;\r\n}\r\n.btn-custom.border-btn:hover {\r\n    color: #fff;\r\n    opacity: 1;\r\n}\r\n.btn-custom.border-btn {\r\n    background-color: transparent;\r\n    border: 1px solid #a0ce4e;\r\n    box-shadow: none;\r\n    -o-box-shadow: none;\r\n    -moz-box-shadow: none;\r\n    -webkit-box-shadow: none;\r\n    color: #a0ce4e ;\r\n}\r\n.btn-custom.btn-large.border-btn.call-to-action-button {\r\n    background: #fff none repeat scroll 0 0;\r\n    border: medium none;\r\n    box-shadow: none;\r\n}\r\n\r\n.btn-custom:hover {\r\n    color: #fff;\r\n    opacity: 0.8;\r\n}\r\n\r\n.btn-custom.border-btn:hover {\r\n    opacity: 1;\r\n    color: #fff;\r\n}\r\n\r\n.btn-custom.border-btn.btn-gray:hover {\r\n    background-color: #444;\r\n    color: #fff;\r\n}\r\n\r\n.btn-custom.btn-gray {\r\n    background-color: #444;\r\n}\r\n\r\n.btn-custom.border-btn.btn-gray {\r\n    background-color: transparent;\r\n    border: 1px solid #444;\r\n    color: #444;\r\n}\r\n\r\n.cd-ext-large {\r\n    border-radius: 0;\r\n    display: inline-block;\r\n    margin-top: 20px;\r\n    text-align: center;\r\n    width: 100%;\r\n}\r\n.btn-large {\r\n    font-size: 14px;\r\n    padding: 20px 80px;\r\n}\r\n\r\n.btn-medium {\r\n    font-size: 14px;\r\n    padding: 15px 60px;\r\n}\r\n\r\n.btn-small {\r\n    padding: 10px 40px;\r\n}\r\n\r\n.btn-mini {\r\n    padding: 5px 20px;\r\n}\r\n\r\n.btn-large.border-btn {\r\n    padding: 20px 80px;\r\n}\r\n\r\n.btn-medium.border-btn {\r\n    padding: 15px 60px;\r\n}\r\n\r\n.btn-small.border-btn {\r\n    padding: 10px 40px;\r\n}\r\n\r\n.btn-mini.border-btn {\r\n    padding: 5px 20px;\r\n}\r\n\r\n.btn.btn-product {\r\n    background: #a0ce4e none repeat scroll 0 0;\r\n    border: 0 none;\r\n    border-radius: 0;\r\n    color: #fff;\r\n    cursor: pointer;\r\n    display: inline-block;\r\n    font-size: 16px;\r\n    font-weight: 400;\r\n    padding: 12px 25px;\r\n    position: relative;\r\n    text-decoration: none;\r\n    text-transform: uppercase;\r\n    white-space: nowrap;\r\n}\r\n\r\n/*------------------------------------------------*/\r\n/*-----------------[Title Style 2]---------------*/\r\n/*------------------------------------------------*/\r\n.dividerHeading,.widget_title\r\n{\r\n    text-align: center;\r\n    position: relative;\r\n}\r\n.dividerHeading h4,\r\n.widget_title h4\r\n{\r\n    font-size:18px;\r\n    position:relative;\r\n    line-height:0;\r\n    border-bottom: 1px solid #a0ce4e ;\r\n    text-transform: uppercase;\r\n}\r\n.dividerHeading h4 span{\r\n    background:white;\r\n    position:relative;\r\n    line-height: 7px;\r\n    top: 4px;\r\n    display: inline-block;\r\n\r\n}\r\n.dividerHeading h4 span:before,\r\n.dividerHeading h4 span:after,\r\n.widget_title h4 span:after,\r\n.widget_title h4 span:before\r\n{\r\n    color:#a0ce4e ;\r\n    font-size:10px;\r\n    content: \"\\f10c\";\r\n    font-family:fontawesome;\r\n    display: inline-block;\r\n\r\n}\r\n.dividerHeading h4 span:before,\r\n.widget_title h4 span:before\r\n{\r\n    margin-right:10px ;\r\n}\r\n.dividerHeading h4 span:after,\r\n.widget_title h4 span:after\r\n{\r\n    margin-left:10px ;\r\n}\r\n.widget_title {\r\n    position: relative;\r\n}\r\n.widget_title h4 {\r\n    font-size: 14px;\r\n    text-transform: uppercase;\r\n}\r\n\r\n\r\n/*------------------------------------------------*/\r\n/*-----------------[Title Style 3]---------------*/\r\n/*------------------------------------------------*/\r\n.widget-title {\r\n    height: 28px;\r\n    margin-bottom: 30px;\r\n    position: relative;\r\n    text-transform: uppercase;\r\n}\r\n.widget-title h2 {\r\n    background-color: #a0ce4e;\r\n    color: #ffffff;\r\n    display: inline-block;\r\n    font-size: 14px;\r\n    height: 28px;\r\n    line-height: 29px;\r\n    padding: 0 15px;\r\n    position: relative;\r\n}\r\n.ta-border {\r\n    background-color: #a0ce4e;\r\n    bottom: 0;\r\n    display: block;\r\n    height: 2px;\r\n    left: 0;\r\n    position: absolute;\r\n    width: 100%;\r\n}\r\n/*------------------------------------------------*/\r\n/*--------------[Title Style 4]-----------*/\r\n/*------------------------------------------------*/\r\n.cd-home-title::after {\r\n    background-color: #a0ce4e;\r\n    bottom: 0;\r\n    content: \"\";\r\n    display: block;\r\n    height: 3px;\r\n    left: 50%;\r\n    margin-left: -40px;\r\n    position: absolute;\r\n    width: 80px;\r\n}\r\n.cd-home-title {\r\n    margin-bottom: 30px;\r\n    padding-bottom: 15px;\r\n    position: relative;\r\n    text-align: center;\r\n}\r\n.cd-home-title p {\r\n    font-size: 16px;\r\n}\r\n.cd-home-title h2 {\r\n    font-family: raleway;\r\n    font-size: 30px;\r\n    font-weight: 400;\r\n    margin-bottom:15px;\r\n    text-transform: uppercase;\r\n}\r\n/*------------------------------------------------*/\r\n/*--------------[Title Style 5]-----------*/\r\n/*------------------------------------------------*/\r\n\r\n\r\n.cd-ecomm-heading h3::before, .cd-ecomm-heading h3::after {\r\n    width: 100%;\r\n}\r\n.h-style-5 h3::before, .h-style-5 h3::after {\r\n    border-bottom-style: solid;\r\n    border-top-style: solid;\r\n    height: 6px;\r\n    top: 15px;\r\n}\r\n.cd-ecomm-heading h3::before {\r\n    right: 100%;\r\n}\r\n.cd-ecomm-heading h3::before, .cd-ecomm-heading h3::after {\r\n    border-color: #bbb;\r\n    border-width: 1px;\r\n    content: \" \";\r\n    position: absolute;\r\n    width: 50%;\r\n}\r\n.cd-ecomm-heading h3::after {\r\n    left: 100%;\r\n}\r\n.cd-ecomm-heading h3 {\r\n    display: inline-block;\r\n    line-height: 34px;\r\n    padding: 0 12px;\r\n    position: relative;\r\n    font-size: 24px;\r\n    text-transform: uppercase;\r\n}\r\n.cd-ecomm-heading.h-style-5 > p {\r\n    display: inline-block;\r\n    padding: 15px 0;\r\n    text-align: center;\r\n    width: 70%;\r\n}\r\n/*------------------------------------------------*/\r\n/*--------------[ARROW STYLE]-----------*/\r\n/*------------------------------------------------*/\r\n.bg-block-style > a {\r\n    background: #222 none repeat scroll 0 0;\r\n    color: #fff;\r\n    display: block;\r\n    padding: 30px 0;\r\n    text-align: center;\r\n}\r\n.bg-block-style > a, .bg-block-style > a span i {\r\n    transition: all 0.25s ease-in-out 0s;\r\n}\r\n.bg-block-style > a span {\r\n    display: inline-block;\r\n    font-weight: 400;\r\n    position: relative;\r\n    text-decoration: underline;\r\n}\r\n.bg-block-style > a:hover {\r\n    background-color: #a0ce4e;\r\n}\r\n.bg-block-style > a:hover {\r\n    text-decoration: none;\r\n}\r\n/*------------------------------------------------*/\r\n/*--------------[PAGINATION STYLE]-----------*/\r\n/*------------------------------------------------*/\r\n.pagination {\r\n    border-radius: 0;\r\n    display: inline-block;\r\n    margin: 0;\r\n    padding-left: 0;\r\n}\r\n.pagination > li > a, .pagination > li > span{\r\n    color: #787878;\r\n}\r\n.pagination > .active > a, .pagination > .active > a:focus, .pagination > .active > a:hover, .pagination > .active > span, .pagination > .active > span:focus, .pagination > .active > span:hover{\r\n    background-color: #a0ce4e;\r\n    border-color:#ddd;\r\n}\r\n.pagination > li > a:focus, .pagination > li > a:hover, .pagination > li > span:focus, .pagination > li > span:hover{\r\n    background-color: #a0ce4e;  \r\n    color: #fff;\r\n\r\n}\r\n/*------------------------------------------------*/\r\n/*--------------[Carousel HOME STYLE]-----------*/\r\n/*------------------------------------------------*/\r\n.carousel-fade .carousel-inner .item {\r\n    opacity: 0;\r\n    -webkit-transition-property: opacity;\r\n    transition-property: opacity;\r\n}\r\n.carousel-fade .carousel-inner .active {\r\n    opacity: 1;\r\n}\r\n.color-black{\r\n    color: #687074;\r\n}\r\n.carousel-fade .carousel-inner .active.left,\r\n.carousel-fade .carousel-inner .active.right {\r\n    left: 0;\r\n    opacity: 0;\r\n    z-index: 1;\r\n}\r\n.carousel-fade .carousel-inner .next.left,\r\n.carousel-fade .carousel-inner .prev.right {\r\n    opacity: 1;\r\n}\r\n.carousel-fade .carousel-control {\r\n    z-index: 2;\r\n}\r\n.carousel-caption {\r\n    right: 15%;\r\n    left: 15%;\r\n    text-shadow: none;\r\n    padding: 0;\r\n    bottom: 50%;\r\n    -webkit-transform: translate(0, 50%);\r\n    -ms-transform: translate(0, 50%);\r\n    transform: translate(0, 50%);\r\n}\r\n.carousel-caption > h2 {\r\n    font-family: \"raleway\";\r\n    color: #fff;\r\n    font-size: 52px;\r\n    font-weight: 400;\r\n    text-transform: uppercase;\r\n    position: relative;\r\n    padding-bottom: 15px;\r\n    -webkit-transform: scale(0.8);\r\n    -ms-transform: scale(0.8);\r\n    transform: scale(0.8);\r\n    opacity: 0;\r\n    -webkit-transition: -webkit-transform 0.5s, opacity 0.5s;\r\n    transition: transform 0.5s, opacity 0.5s;\r\n    -webkit-transition-delay: 0.5s;\r\n    transition-delay: 0.5s;\r\n    -webkit-transition-timing-function: cubic-bezier(0.23, 1, 0.32, 1);\r\n    transition-timing-function: cubic-bezier(0.23, 1, 0.32, 1);\r\n}\r\n.carousel-caption > h2:after {\r\n    content: '';\r\n    display: block;\r\n    width: 120px;\r\n    height: 3px;\r\n    background-color: #a0ce4e ;\r\n    position: absolute;\r\n    bottom: 0;\r\n    left: 50%;\r\n    margin-left: -60px;\r\n    -webkit-transform: scaleX(0);\r\n    -ms-transform: scaleX(0);\r\n    transform: scaleX(0);\r\n    -webkit-transition: -webkit-transform 0.5s;\r\n    transition: transform 0.5s;\r\n    -webkit-transition-delay: 1s;\r\n    transition-delay: 1s;\r\n    -webkit-transition-timing-function: cubic-bezier(0.23, 1, 0.32, 1);\r\n    transition-timing-function: cubic-bezier(0.23, 1, 0.32, 1);\r\n}\r\n.carousel-caption > img {\r\n    opacity: 0;\r\n    margin-top: -20px;\r\n    -webkit-transition: opacity 0.5s, margin-top 0.5s;\r\n    transition: opacity 0.5s, margin-top 0.5s;\r\n    -webkit-transition-timing-function: cubic-bezier(0.23, 1, 0.32, 1);\r\n    transition-timing-function: cubic-bezier(0.23, 1, 0.32, 1);\r\n}\r\n.carousel-caption > p {\r\n    color: #fff;\r\n    font-size: 20px;\r\n    line-height: 2.500em;\r\n    font-weight: 300;\r\n    -webkit-transform: scale(1.2);\r\n    -ms-transform: scale(1.2);\r\n    transform: scale(1.2);\r\n    opacity: 0;\r\n    -webkit-transition: -webkit-transform 0.5s, opacity 0.5s;\r\n    transition: transform 0.5s, opacity 0.5s;\r\n    -webkit-transition-delay: 1.5s;\r\n    transition-delay: 1.5s;\r\n    -webkit-transition-timing-function: cubic-bezier(0.23, 1, 0.32, 1);\r\n    transition-timing-function: cubic-bezier(0.23, 1, 0.32, 1);\r\n}\r\n.header.transp + .carousel .carousel-caption {\r\n    margin-bottom: -40px;\r\n}\r\n.header.transp.center-content + .carousel .carousel-caption {\r\n    margin-bottom: -60px;\r\n}\r\n.carousel-inner .item.active .carousel-caption > h2 {\r\n    opacity: 1;\r\n    -webkit-transform: scale(1);\r\n    -ms-transform: scale(1);\r\n    transform: scale(1);\r\n}\r\n.carousel-inner .item.active .carousel-caption > h2:after {\r\n    -webkit-transform: scaleX(1);\r\n    -ms-transform: scaleX(1);\r\n    transform: scaleX(1);\r\n}\r\n.carousel-inner .item.active .carousel-caption > p {\r\n    opacity: 1;\r\n    -webkit-transform: scale(1);\r\n    -ms-transform: scale(1);\r\n    transform: scale(1);\r\n}\r\n.carousel-inner .item.active .carousel-caption > img {\r\n    opacity: 1;\r\n    margin-top: 0px;\r\n}\r\n.carousel-inner > .beactive {\r\n    display: block;\r\n}\r\n.carousel-control {\r\n    width: 80px;\r\n    height: 120px;\r\n    top: 50%;\r\n    margin-top: -60px;\r\n    background-color: rgba(255, 255, 255, 0.2);\r\n    background-image: url(../img/banner/arrow-left.png) !important;\r\n    background-position: center center !important;\r\n    background-repeat: no-repeat !important;\r\n    background-size: 33px 60px;\r\n    -webkit-transition: left 0.3s, right 0.3s;\r\n    transition: left 0.3s, right 0.3s;\r\n}\r\n.carousel-control.left {\r\n    left: -100px;\r\n}\r\n.carousel-control.right {\r\n    background-image: url(../img/banner/arrow-right.png) !important;\r\n    right: -100px;\r\n}\r\n.header.transp + .carousel .carousel-control {\r\n    margin-top: -10px !important;\r\n}\r\n.header.transp.center-content + .carousel .carousel-control {\r\n    margin-top: 22px !important;\r\n}\r\n.carousel {\r\n    overflow: hidden;\r\n}\r\n.carousel:hover .carousel-control.left {\r\n    left: 0;\r\n}\r\n.carousel:hover .carousel-control.right {\r\n    right: 0;\r\n}\r\n\r\n#mega-slider .item::before {\r\n    background: rgba(5, 5, 5, 0.5) none repeat scroll 0 0;\r\n    content: \"\";\r\n    height: 100%;\r\n    left: 0;\r\n    position: absolute;\r\n    top: 0;\r\n    width: 100%;\r\n    z-index: 1;\r\n}\r\n\r\n@media (max-width: 767px) {\r\n   .carousel-caption{\r\n       display:none;\r\n    }\r\n}\r\n/*------------------------------------------------*/\r\n/*--------------[BG-IMAGE]-----------*/\r\n/*------------------------------------------------*/\r\n.bg-image-block {\r\n  width: 100%;\r\n  height: auto;\r\n  padding: 245px 0;\r\n  position: relative;\r\n  background: url(../img/banner/slide-2.png) repeat fixed;\r\n  background-size: cover;\r\n}\r\n\r\n.bg-image-block:before {\r\n  top: 0;\r\n  left: 0;\r\n  width: 100%;\r\n  height: 100%;\r\n  content: \" \";\r\n  position: absolute;\r\n  background: rgba(0,0,0,0.5);\r\n}\r\n.headline-center {\r\n    position: relative;\r\n    text-align: center;\r\n}\r\n.headline-center h1::after {\r\n    background: #a0ce4e none repeat scroll 0 0;\r\n    bottom: -5px;\r\n    content: \" \";\r\n    height: 2px;\r\n    left: 50%;\r\n    margin-left: -15px;\r\n    position: absolute;\r\n    text-align: center;\r\n    width: 30px;\r\n    z-index: 1;\r\n}\r\n.headline-center.headline-light h1 {\r\n    color: #ffffff;\r\n}\r\n.headline-center h1 {\r\n    color: #555555;\r\n    margin-bottom: 20px;\r\n    padding-bottom: 15px;\r\n    position: relative;\r\n}\r\n.headline-center.headline-light p {\r\n    color: #eeeeee;\r\n}\r\n.headline-center p {\r\n    font-size: 14px;\r\n}\r\n.cd-btn.cd-btn-border.cd-btn-light {\r\n    border-color: #ffffff;\r\n    color: #ffffff;\r\n}\r\n.cd-btn.cd-btn-border {\r\n    background: rgba(0, 0, 0, 0) none repeat scroll 0 0;\r\n    border: 1px solid rgba(0, 0, 0, 0);\r\n    color: #555555;\r\n    padding: 5px 13px;\r\n    transition: all 0.1s ease-in-out 0s;\r\n}\r\n.cd-btn.cd-btn-border.cd-btn-dark {\r\n    border-color: #555555;\r\n}\r\n.cd-btn.cd-btn-border {\r\n    background: rgba(0, 0, 0, 0) none repeat scroll 0 0;\r\n    border: 1px solid rgba(0, 0, 0, 0);\r\n    color: #555555;\r\n    padding: 5px 13px;\r\n    transition: all 0.1s ease-in-out 0s;\r\n}\r\n.cd-btn.cd-btn-border.cd-btn-light.cd-btn-border-hover:hover {\r\n    background: #ffffff none repeat scroll 0 0;\r\n    color: #555555 !important;\r\n}\r\n.cd-btn.cd-btn-border.cd-btn-light:hover {\r\n    border-color: #ffffff;\r\n}\r\n\r\n\r\n\r\n.parallax-all-block{\r\n     box-shadow: 5px 0 5px rgba(0, 0, 0, 0.2);\r\n     position: relative;\r\n}\r\n.parallaxBg-img > img {\r\n    vertical-align: middle;\r\n    width: 100%;\r\n}\r\n.parallax-all-block-text{\r\n    background-color: #fff;\r\n    margin-top: 185px;\r\n    padding: 30px;\r\n}\r\n.parallax-block-text-info{\r\n    padding: 60px 30px;\r\n}\r\n.parallax-block-text-info > h1 span {\r\n    font-size: 80px;\r\n    font-weight: 300;\r\n    text-transform: capitalize;\r\n}\r\n@media (max-width: 767px) {\r\n    .parallax-all-block-text{\r\n     margin-top: 0;\r\n    }\r\n}\r\n/*------------------------------------------------*/\r\n/*-------------[Home About Style]----------------*/\r\n/*------------------------------------------------*/\r\n.home-about-text1{\r\n    padding: 60px 0;\r\n}\r\n.home-about-text1 .about-text {\r\n    color: inherit;\r\n    font-family: raleway;\r\n    font-size: 20px;\r\n    font-weight: 500;\r\n    margin-bottom: 15px;\r\n    text-transform: uppercase;\r\n}\r\n.color-green {\r\n    color: #a0ce4e;\r\n}\r\n\r\n/*------------------------------------------------*/\r\n/*-------------[Service Box Style]----------------*/\r\n/*------------------------------------------------*/\r\n.service-item {\r\n    position: relative;\r\n}\r\nservice-item .icon {\r\n    color: inherit;\r\n}\r\n.service-item .icon {\r\n    position: absolute;\r\n}\r\n.service-item .icon i {\r\n    font-size: 31px;\r\n}\r\n.service-item .service-desc {\r\n    padding: 0 20px 0 65px;\r\n}\r\n.service-item .service-desc h5 {\r\n    color: inherit;\r\n    font-weight: 400;\r\n    margin-bottom: 10px;\r\n    text-transform: uppercase;\r\n}\r\n\r\n@media (max-width: 991px) {\r\n    .service-item{\r\n        margin-bottom: 45px;\r\n    }\r\n}\r\n/*------------------------------------------------*/\r\n/*--------------[WHY CHOOSE US]-----------*/\r\n/*------------------------------------------------*/\r\n.headline-left .headline-brd::after {\r\n    background: #a0ce4e  none repeat scroll 0 0;\r\n    bottom: -5px;\r\n    content: \" \";\r\n    height: 2px;\r\n    left: 1px;\r\n    position: absolute;\r\n    width: 30px;\r\n    z-index: 1;\r\n}\r\n.headline-left .headline-brd {\r\n    color: #555555;\r\n    margin-bottom: 25px;\r\n    padding-bottom: 10px;\r\n    position: relative;\r\n}\r\n.lists-item li {\r\n    margin-bottom: 10px;\r\n}\r\n.lists-item i {\r\n    color: #a0ce4e ;\r\n    display: inline-block;\r\n    font-size: 13px;\r\n    margin-right: 7px;\r\n}\r\n\r\n\r\n/*------------------------------------------------*/\r\n/*--------------[ABOUT OUR COMPANY]-----------*/\r\n/*------------------------------------------------*/\r\n.no-padding {\r\n    padding: 0;\r\n}\r\n.cv-padding {\r\n    margin: 72px 0;\r\n}\r\n.image-block-content{\r\n    padding: 0 50px;\r\n    margin-bottom: 30px;\r\n}\r\n.image-block img {\r\n    width: 100%;\r\n}\r\n.image-block-content .feature-icon{\r\n    width: 60px;\r\n    height: 60px;\r\n    line-height: 2em;\r\n    color: #fff;\r\n    border-radius: 100%;\r\n    display: inline-block;\r\n    text-align: center;\r\n}\r\n\r\n.image-block-content .feature-content{\r\n    padding-left: 85px;\r\n    text-align: left;\r\n}\r\n\r\n.image-block-content .feature-content h3{\r\n    margin-bottom: 0;\r\n}\r\n\r\n.image-block-content .feature-icon{\r\n    background: #a0ce4e;\r\n}\r\n\r\n.feature-icon {\r\n    font-size: 28px;\r\n}\r\n@media (max-width: 767px) {\r\n    .image-block-content{\r\n        padding: 0;\r\n    }\r\n}\r\n\r\n/*------------------------------------------------*/\r\n/*-------------[QUALITY OF WORK]----------------*/\r\n/*------------------------------------------------*/\r\n.quality-of-work .photo-block {\r\n    padding: 22px 70px 0 0;\r\n}\r\n@media (max-width: 768px) {\r\n    .quality-of-work .photo-block {\r\n        padding-left: 3em;\r\n        padding-right: 3em;\r\n    }\r\n}\r\n@media (max-width: 480px) {\r\n    .quality-of-work .photo-block {\r\n        padding-left: 1.5em;\r\n        padding-right: 1.5em;\r\n    }\r\n}\r\n.quality-of-work .photo-block img {\r\n    margin: auto;\r\n}\r\n@media (max-width: 1100px) and (min-width: 992px) {\r\n    .quality-of-work .photo-block img {\r\n        margin-top: 2em;\r\n    }\r\n}\r\n.quality-of-work .content-block {\r\n    background: #a0ce4e;\r\n    padding: 87px 30px;\r\n    position: relative;\r\n    z-index: 1;\r\n}\r\n@media (max-width: 1199px) {\r\n    .quality-of-work .content-block {\r\n        padding-left: 28px;\r\n        padding-right: 28px;\r\n    }\r\n}\r\n@media (max-width: 992px) {\r\n    .quality-of-work .content-block {\r\n        border-top: 0;\r\n    }\r\n}\r\n@media (max-width: 768px) {\r\n    .quality-of-work .content-block {\r\n        padding-left: 3em;\r\n        padding-right: 3em;\r\n    }\r\n}\r\n@media (max-width: 480px) {\r\n    .quality-of-work .content-block {\r\n        padding-left: 1.5em;\r\n        padding-right: 1.5em;\r\n    }\r\n}\r\n@media (max-width: 1023px) {\r\n   .quality-of-work .content-block:after  {\r\n       display: none;\r\n    }\r\n}\r\n.quality-of-work .content-block:after {\r\n    background: #a0ce4e none repeat scroll 0 0;\r\n    box-sizing: content-box;\r\n    content: \"\";\r\n    height: 100%;\r\n    left: -2.5em;\r\n    position: absolute;\r\n    top: 0;\r\n    transform: skew(-7deg, 0deg);\r\n    -webkit-transform: skew(-7deg, 0deg);\r\n    -ms-transform: skew(-7deg, 0deg);\r\n    width: 5em;\r\n    z-index: -1;\r\n    \r\n}\r\n\r\n.quality-of-work .content-block .block-top-title h3 {\r\n    margin-top: 0;\r\n}\r\n.quality-of-work .content-block .features {\r\n    margin-top: 28px;\r\n    margin-bottom: 0;\r\n}\r\n.quality-of-work .content-block .features li {\r\n    margin-bottom: 28px;\r\n}\r\n.quality-of-work .content-block .features li:last-child {\r\n    margin-bottom: 0;\r\n}\r\n.quality-of-work .content-block .features li .icon-block {\r\n    width: 42px;\r\n    height: 42px;\r\n    line-height: 42px;\r\n    background: #fff;\r\n    color: #a0ce4e;\r\n    border-radius: 50%;\r\n    font-size: 17.5px;\r\n    text-align: center;\r\n    float: left;\r\n    border: 1px solid #ededed;\r\n    margin-top: 1px;\r\n    transition: .3s;\r\n}\r\n.quality-of-work .content-block .features li p {\r\n    margin-left: 4em;\r\n    margin-bottom: 0;\r\n    color: #fff;\r\n    \r\n}\r\n.quality-of-work .content-block .features li:hover .icon-block {\r\n    background: #a0ce4e;\r\n    color: #fff;\r\n}\r\n\r\n/*------------------------------------------------*/\r\n/*-------------[Parallax]----------------*/\r\n/*------------------------------------------------*/\r\n\r\n\r\n.parallax-block {\r\n    background: rgba(0, 0, 0, 0) url(\"../img/dark_wood.png\") repeat fixed 50% 0;\r\n    color: #ffffff;\r\n    padding: 80px 0;\r\n    position: relative;\r\n    text-align: center;\r\n}\r\n.parallax-block-text {\r\n    padding: 0 80px;\r\n    position: relative;\r\n    z-index: 1;\r\n}\r\n.parallax-block-text p {\r\n    color: #ffffff;\r\n    font-size: 28px;\r\n    text-transform: uppercase;\r\n}\r\n.color-green {\r\n    color: #a0ce4e;\r\n}\r\n\r\n/*------------------------------------------------*/\r\n/*-------------[Counter]----------------*/\r\n/*------------------------------------------------*/\r\n.counter-block::after {\r\n    background: rgba(0, 0, 0, 0.8) none repeat scroll 0 0;\r\n    bottom: 0;\r\n    content: \"\";\r\n    left: 0;\r\n    position: absolute;\r\n    right: 0;\r\n    top: 0;\r\n    z-index: -1;\r\n}\r\n\r\n.counter-block {\r\n    background: rgba(0, 0, 0, 0) url(\"../img/counter.jpg\") no-repeat fixed center center / cover ;\r\n    padding: 80px 0;\r\n    position: relative;\r\n    z-index: 1;\r\n}\r\n\r\n.counter-item i {\r\n    font-size: 50px;\r\n    color: #fff;\r\n}\r\n\r\n.secondary-color, .counter-item > h4{\r\n    color: #fff;\r\n    line-height:30px;\r\n    padding-top: 20px;\r\n}\r\n\r\n/*------------------------------------------------*/\r\n/*-------------[Pricing Table]----------------*/\r\n/*------------------------------------------------*/\r\n.pricingTable {\r\n    border: 1px solid #dbdbdb;\r\n    box-shadow: 0 0 10px rgba(0, 0, 0, 0.14);\r\n    margin: 0 -15px;\r\n    text-align: center;\r\n    transition: all 0.4s ease-in-out 0s;\r\n}\r\n.pricingTable .pricingTable-header{\r\n    padding-bottom: 25px;\r\n}\r\n.pricingTable .active{\r\n    background-color: #a0ce4e;\r\n    color: #fff;\r\n    position: relative;\r\n}\r\n.pricingTable .best{\r\n    width: 80px;\r\n    height: 80px;\r\n    background: #a0ce4e;\r\n    border-radius: 50%;\r\n    padding: 25px 20px 20px;\r\n    font-size: 13px ;\r\n    text-transform: capitalize;\r\n    position: absolute;\r\n    right: -20px;\r\n    top: 25px;\r\n    z-index: 1;\r\n}\r\n.pricingTable .heading{\r\n    background-color:#fff;\r\n    border-bottom: 1px solid #d0d0d0;\r\n    color: #393939;\r\n    display: block;\r\n    padding: 15px 10px;\r\n}\r\n.pricingTable .heading h3 {\r\n    font-size: 20px;\r\n    margin: 0;\r\n    text-transform: capitalize;\r\n}\r\n.pricingTable .price-value {\r\n    color: #474747;\r\n    margin: 10px auto 0;\r\n    padding: 20px 10px 0;\r\n    display: block;\r\n    font-size: 25px;\r\n    line-height: 2.188em;\r\n}\r\n.pricingTable .price-value span{\r\n    font-size: 60px;\r\n    font-weight: 100;\r\n}\r\n.pricingTable .active .price-value{\r\n    color: #fff;\r\n}\r\n.pricingTable .subtitle{\r\n    display: block;\r\n    margin-top: 15px;\r\n    font-size: 15px;\r\n}\r\n.pricingTable .pricingContent ul{\r\n    padding: 0;\r\n    list-style: none;\r\n    margin-bottom: 0;\r\n}\r\n.pricingContent ul li{\r\n    border-top: 1px solid #dbdbdb;\r\n    padding: 10px 0;\r\n    background-color: #fff;\r\n}\r\n.pricingContent ul li:nth-child(even) {\r\n    background-color: #f7f7f7;\r\n}\r\n.pricingContent ul li:last-child{\r\n    border-bottom: 1px solid #dbdbdb;\r\n}\r\n.pricingTable .pricingTable-sign-up{\r\n    padding: 25px 0;\r\n}\r\n.pricingTable .btn-block{\r\n    background: #a0ce4e;\r\n    border:0px none;\r\n    border-radius: 5px;\r\n    color:#fff;\r\n    width: 50%;\r\n    padding: 10px 5px;\r\n    margin: 0 auto;\r\n    text-transform: capitalize;\r\n    position: relative;\r\n    top:0;\r\n    transition:all 0.5s ease 0s;\r\n}\r\n.pricingTable .btn-block:after{\r\n    content: \"\\f090\";\r\n    font-family: 'FontAwesome';\r\n    padding-left: 10px;\r\n    font-size: 15px;\r\n}\r\n.pricingTable .btn-block:hover{\r\n    top: -5px;\r\n}\r\n.pricingTable .btn-block:hover:before{\r\n    content: \"\";\r\n    background:rgba(0, 0, 0, 0) radial-gradient(ellipse at center center , rgba(0, 0, 0, 0.35) 0%, rgba(0, 0, 0, 0) 80%);\r\n    height: 10px;\r\n    position: absolute;\r\n    top: 102%;\r\n    left:5%;\r\n    width: 90%;\r\n}\r\n@media screen and (max-width:990px){\r\n    .pricingTable{\r\n        margin-bottom: 30px;\r\n    }\r\n}\r\n@media screen and (max-width:767px){\r\n    .pricingTable{\r\n        margin: 0 0 30px 0;\r\n    }\r\n    .pricingTable .best{\r\n        right: -12px;\r\n    }\r\n}\r\n\r\n/*------------------------------------------------*/\r\n/*-------------[ICON LIST]----------------*/\r\n/*------------------------------------------------*/\r\n.icon_lists .fa-hover a {\r\n    border-radius: 0;\r\n    color: inherit;\r\n    display: block;\r\n    height: 32px;\r\n    line-height: 32px;\r\n    padding-left: 10px;\r\n}\r\n.icon_lists .fa-hover a .fa {\r\n    display: inline-block;\r\n    font-size: 14px;\r\n    margin-right: 10px;\r\n    text-align: right;\r\n    width: 32px;\r\n}\r\n.icon_lists .fa-hover a:hover {\r\n    background-color: #a0ce4e ;\r\n    color: #FFFFFF;\r\n    text-decoration: none;\r\n}\r\n.icon_lists .fa-hover a:hover .fa {\r\n    font-size: 24px;\r\n    vertical-align: -3px;;\r\n}\r\n.icon_lists .fa-hover a:hover .text-muted {\r\n    color: #BBE2D5;\r\n}\r\n/*------------------------------------------------*/\r\n/*-------------[Widgets]----------------*/\r\n/*------------------------------------------------*/\r\n.bottom-line {\r\n    position: relative;\r\n}\r\n\r\n.bottom-line:before {\r\n    content: \"\";\r\n    display: block;\r\n    position: absolute;\r\n    bottom: 0;\r\n    width: 100%;\r\n    border-bottom: 2px solid #eeeeee;\r\n}\r\n\r\n.bottom-line:after {\r\n    content: \"\";\r\n    display: block;\r\n    width: 35px;\r\n    border-bottom: 2px solid #a0ce4e;\r\n    margin: 20px auto 25px 0;\r\n    z-index: 1;\r\n    position: relative;\r\n}\r\n.widget .recent-posts {\r\n    list-style: none;\r\n    padding: 0;\r\n    margin: 0;\r\n}\r\n\r\n.widget .recent-posts > li {\r\n    border-top: 1px solid #eee;\r\n    padding: 10px 0;\r\n}\r\n\r\n.widget .recent-posts > li:before,\r\n.widget .recent-posts > li:after {\r\n    content: \" \";\r\n    display: table;\r\n}\r\n\r\n.widget .recent-posts > li:after {\r\n    clear: both;\r\n}\r\n\r\n.widget .recent-posts > li:first-child {\r\n    border: 0;\r\n    padding-top: 0;\r\n}\r\n\r\n.widget .recent-posts a {\r\n    text-decoration: none;\r\n    text-transform: none;\r\n}\r\n\r\n.widget .recent-posts a:hover,\r\n.widget .recent-posts a:focus {\r\n    opacity: 0.7;\r\n}\r\n\r\n.widget-posts-image {\r\n    float: left;\r\n    width: 44px;\r\n}\r\n\r\n.widget-posts-body {\r\n    margin-left: 58px;\r\n}\r\n\r\n.widget-posts-title {\r\n    margin: 2px 0;\r\n}\r\n\r\n.widget-posts-meta {\r\n    font-size: 11px;\r\n}\r\n.icons-list {\r\n    list-style: none;\r\n    padding: 0;\r\n    margin: 0;\r\n}\r\n\r\n.icons-list > li {\r\n    border-top: 1px solid #eee;\r\n    padding: 10px 0;\r\n}\r\n\r\n.icons-list > li:first-child {\r\n    border: 0;\r\n    padding-top: 0;\r\n}\r\n.icons-list > li:last-child {\r\n    padding-bottom: 0;\r\n}\r\n.icons-list a:hover,\r\n.icons-list a:focus {\r\n    color: #a0ce4e;\r\n}\r\n\r\n.icons-list a > .fa,\r\n.icons-list a > .icons {\r\n    padding-left: 5px;\r\n}\r\n/*------------------------------------------------*/\r\n/*-------------[Tags]----------------*/\r\n/*------------------------------------------------*/\r\n\r\n.tags a {\r\n    background: #f8f8f8;\r\n    display: inline-block;\r\n    border-radius: 2px;\r\n    padding: 8px 12px;\r\n    margin: 0 0 6px;\r\n    font-size: 11px;\r\n    color: #777777;\r\n}\r\n\r\n.tags a:hover,\r\n.tags a:focus {\r\n    background: #a0ce4e;\r\n    color: #ffffff;\r\n}\r\n\r\n/*------------------------------------------------*/\r\n/*-------------[Progress Bar]----------------*/\r\n/*------------------------------------------------*/\r\n.progressbar-title{\r\n    font-size: 14px;\r\n    color: #848484;\r\n    text-transform: capitalize;\r\n}\r\n.progress{\r\n    height: 5px;\r\n    overflow: visible;\r\n    background: #f0f0f0;\r\n    margin-bottom: 30px;\r\n}\r\n.progress .progress-bar{\r\n    position: relative;\r\n    animation: animate-positive 2s;\r\n}\r\n.progress .progress-icon{\r\n    width: 30px;\r\n    height: 30px;\r\n    line-height: 25px;\r\n    border-radius: 50%;\r\n    font-size: 13px;\r\n    position: absolute;\r\n    top: -14px;\r\n    right: 0;\r\n    background: #fff;\r\n    border-width: 3px;\r\n    border-style: solid;\r\n}\r\n.progress-value{\r\n    color: #848484;\r\n    position: absolute;\r\n    top: -35px;\r\n    right: 0;\r\n}\r\n@-webkit-keyframes animate-positive {\r\n    0% { width: 0%; }\r\n}\r\n@keyframes animate-positive {\r\n    0% { width: 0%; }\r\n}\r\n@media (max-width: 767px) {\r\n    .home-main-contant-style .progress{\r\n        margin-bottom: 30px;\r\n    }\r\n}\r\n/*------------------------------------------------*/\r\n/*--------------[Accordion STYLE]-----------*/\r\n/*------------------------------------------------*/\r\n#accordion .panel{\r\n    border-radius: 0px;\r\n    box-shadow: none;\r\n    border: 1px solid #d5d5d5;\r\n    margin-bottom: 6px;\r\n}\r\n#accordion .panel-heading{\r\n    border-radius: 0px;\r\n    background-color:#fff;\r\n    padding:0;\r\n}\r\n#accordion .panel-title a{\r\n    display: block;\r\n    color: inherit;\r\n    font-size: 15px;\r\n    padding:14px 28px;\r\n    font-weight: normal;\r\n    position: relative;\r\n    border-top:3px solid #a0ce4e;\r\n}\r\n#accordion .panel-title a.collapsed{\r\n    border-top:0;\r\n}\r\n#accordion .panel-title a:hover,\r\n#accordion .panel-title a:focus{\r\n    text-decoration: none;\r\n    outline: none;\r\n}\r\n#accordion .panel-title a:before,\r\n#accordion .panel-title a.collapsed:before{\r\n    content: \"\\f068\";\r\n    font-family: FontAwesome;\r\n    color:#a0ce4e;\r\n    position: absolute;\r\n    top:10px;\r\n    right:12px;\r\n    font-size: 14px;\r\n    line-height: 24px;\r\n}\r\n#accordion .panel-title a.collapsed:before{\r\n    content: \"\\f067\";\r\n}\r\n#accordion .panel-body{\r\n    color: inherit;\r\n    font-size: 14px;\r\n    line-height: 20px;\r\n    background:#fff;\r\n    padding: 5px 27px 15px;\r\n    border-top: 0px none;\r\n}\r\n\r\n/*------------------------------------------------*/\r\n/*--------------[Accordion STYLE]-----------*/\r\n/*------------------------------------------------*/\r\n.cd-background{\r\n    align-items: center;\r\n    background: rgba(0, 0, 0, 0.4) none repeat scroll 0 0;\r\n    display: flex;\r\n    height: 100vh;\r\n    justify-content: center;  \r\n}\r\n.cd-bg-1 {\r\n    background: rgba(0, 0, 0, 0) linear-gradient(to left, #02aab0, #00cdac) repeat scroll 0 0;\r\n}\r\n\r\n.cd-bg-2{\r\n    background: rgba(0, 0, 0, 0) linear-gradient(to left, #43cea2, #185a9d) repeat scroll 0 0;\r\n}\r\n.cd-bg-3 {\r\n    background: rgba(0, 0, 0, 0) linear-gradient(to left, #005c97, #363795) repeat scroll 0 0;\r\n}\r\n.cd-bg-4 {\r\n    background: rgba(0, 0, 0, 0) linear-gradient(to left, #1d4350, #a43931) repeat scroll 0 0;\r\n}\r\n.cd-bg-5 {\r\n    background: rgba(0, 0, 0, 0) linear-gradient(to left, #eecda3, #ef629f) repeat scroll 0 0;\r\n}\r\n\r\n.cd-bg-6 {\r\n    background: rgba(0, 0, 0, 0) linear-gradient(to left, #fc00ff, #00dbde) repeat scroll 0 0;\r\n}\r\n.cd-bg-7 {\r\n    background: rgba(0, 0, 0, 0) linear-gradient(to left, #1e130c, #9a8478) repeat scroll 0 0;\r\n}\r\n.cd-bg-8 {\r\n    background: rgba(0, 0, 0, 0) linear-gradient(to left, #ff512f, #dd2476) repeat scroll 0 0;\r\n}\r\n.main-title{\r\n    color: #fff;\r\n    font-size: 4.236em;\r\n    margin-bottom: 30px;\r\n    margin-top: 10px;\r\n    text-transform: uppercase;\r\n}\r\n.sub-title {\r\n    color: rgba(255, 255, 255, 0.7);\r\n    font-size: 1em;\r\n    line-height: 30px;\r\n    margin-bottom: 20px;\r\n    margin-top: 5px;\r\n    text-transform: none;\r\n}\r\n/*------------------------------------------------*/\r\n/*--------------[404 PAGE STYLE]-----------*/\r\n/*------------------------------------------------*/\r\n.error-template {text-align: center;}\r\n.error-actions {margin-top:30px;}\r\n.error-actions .btn { margin-right:10px; }\r\n\r\n/*------------------------------------------------*/\r\n/*--------------[VIDEO STYLE]-----------*/\r\n/*------------------------------------------------*/\r\n.media-block .video-block {\r\n    height: 0;\r\n    padding: 50%;\r\n    position: relative;\r\n}\r\n.video-block iframe {\r\n    height: 100%;\r\n    left: 0;\r\n    position: absolute;\r\n    top: 0;\r\n    width: 100%;\r\n}\r\n.video-home i {\r\n    margin-right: 10px;\r\n    vertical-align: middle;\r\n    font-size: 50px;\r\n    -webkit-transition: color 300ms ease-in-out;\r\n    transition: color 300ms ease-in-out;\r\n}\r\n.video-home h1 {\r\n    font-weight: 400;\r\n    font-size: 20px;\r\n}\r\n.video-home {\r\n    padding: 60px 0;\r\n    background-color: #a0ce4e;\r\n}\r\n.home-media-block{\r\n    color: #fff;\r\n}\r\n.video-home a:hover, .video-home a:focus {\r\n    text-decoration: none;\r\n    color: #fff;\r\n}\r\n\r\n/*------------------------------------------------*/\r\n/*--------------[CBP Portfolio]-----------*/\r\n/*------------------------------------------------*/\r\n.cbp-l-grid-projects-title, .cbp-l-grid-projects-desc {\r\n    font-family: inherit;\r\n    font-weight: 400;\r\n    text-align: center;\r\n}\r\n.cbp-1-title-bg {\r\n    background: #fff none repeat scroll 0 0;\r\n    border: 1px solid #ddd;\r\n    overflow: hidden;\r\n    padding: 13px;\r\n}\r\n.cbp-l-grid-blog-title{\r\n    margin-top: 0!important;\r\n}\r\n.cbp-l-caption-buttonLeft, .cbp-l-caption-buttonRight {\r\n    background-color: #ffffff!important;\r\n    color: inherit!important;\r\n}\r\n.main-contain.dip-style .cbp-mode-slider .cbp-wrapper{\r\n    cursor: auto;\r\n}\r\n.cbp-l-grid-mosaic .cbp-caption-activeWrap{\r\n    background-color: rgba(0, 0, 0, 0.9)!important;  \r\n}\r\n\r\n.standard-single-comments-list {\r\n    margin-bottom: 70px;\r\n}\r\n.media .media-object {\r\n    border-radius: 50%;\r\n}\r\n\r\n.media .media-body {\r\n    position: relative;\r\n    width: 100%;\r\n}\r\n.media .media-body .standard-comments-body {\r\n    border-bottom: 1px solid #F2F2F2;\r\n    margin-bottom: 20px;\r\n}\r\n.media .media-body .media-heading {\r\n    font-size: 17px;\r\n    line-height: 27px;\r\n    color: #687074;\r\n}\r\n.media .media-body .media-heading a {\r\n    color: #687074;\r\n}\r\n.media .media-body span {\r\n    display: block;\r\n    color: #adb9bf;\r\n    margin-bottom: 10px;\r\n}\r\n.media .media-body span a {\r\n    color: #adb9bf;\r\n}\r\n.media .media-body .btn-comment-reply {\r\n    position: absolute;\r\n    top: 0;\r\n    right: 0;\r\n    background-color: #a0ce4e;\r\n    color: #fff;\r\n   \r\n}\r\n.standard-comments-form div {\r\n    margin-bottom: 30px;\r\n}\r\n.cbp-l-filters-list .cbp-filter-item{\r\n      border-color: #a0ce4e!important;\r\n}\r\n.cbp-l-filters-list .cbp-filter-item.cbp-filter-item-active{\r\n    background-color: #a0ce4e!important;\r\n}\r\n.team-block-style{\r\n    background:#fff;\r\n    padding: 15px;\r\n    overflow: hidden;\r\n}\r\n.cbp-l-grid-slider-team-desc,.cbp-l-grid-slider-testimonials-footer, .cbp-l-grid-slider-team-position, .cbp-l-grid-blog-desc, .cbp-l-grid-blog-comments{\r\n    color: #787878!important;\r\n}\r\n\r\n/*------------------------------------------------*/\r\n/*--------------[Accordion STYLE]-----------*/\r\n/*------------------------------------------------*/\r\n.panel-group{\r\n    margin-bottom: 0;\r\n}\r\n.cd-accordion .panel:last-child {\r\n    margin-bottom: 0;\r\n}\r\n.cd-accordion .panel{\r\n    border-radius: 0px;\r\n    box-shadow: none;\r\n    border: 1px solid #d5d5d5;\r\n    margin-bottom: 6px;\r\n}\r\n.cd-accordion .panel-heading{\r\n    border-radius: 0px;\r\n    background-color:#fff;\r\n    padding:0;\r\n}\r\n.cd-accordion .panel-title a{\r\n    display: block;\r\n    color: #a0ce4e;\r\n    font-size: 15px;\r\n    padding:14px 28px;\r\n    font-weight: bold;\r\n    position: relative;\r\n    border-top:3px solid #a0ce4e;\r\n}\r\n.cd-accordion .panel-title a.collapsed{\r\n    border-top:0;\r\n}\r\n.cd-accordion .panel-title a:hover,\r\n.cd-accordion .panel-title a:focus{\r\n    text-decoration: none;\r\n    outline: none;\r\n}\r\n.cd-accordion .panel-title a:before,\r\n.cd-accordion .panel-title a.collapsed:before{\r\n    content: \"\\f068\";\r\n    font-family: FontAwesome;\r\n    color:#a0ce4e;\r\n    position: absolute;\r\n    top:20px;\r\n    right:12px;\r\n    font-size: 14px;\r\n    line-height: 24px;\r\n}\r\n.cd-accordion .panel-title a.collapsed:before{\r\n    content: \"\\f067\";\r\n}\r\n.cd-accordion .panel-body{\r\n    color: #8a8a8a;\r\n    font-size: 14px;\r\n    line-height: 25px;\r\n    background:#fff;\r\n    padding: 5px 27px 15px;\r\n    border-top: 0px none;\r\n}\r\n.alert.alert-danger:last-child {\r\n    margin: 0;\r\n}\r\n\r\n/*------------------------------------------------*/\r\n/*--------------[TABLE STYLE]-----------*/\r\n/*------------------------------------------------*/\r\ntable {\r\n    font-family: inherit;\r\n    border-collapse: collapse;\r\n    width: 100%;\r\n}\r\n\r\ntd, th {\r\n    border: 1px solid #dddddd;\r\n    text-align: left;\r\n    padding: 15px;\r\n}\r\n\r\ntr:nth-child(even) {\r\n    background-color: #dddddd;\r\n}\r\n\r\ntable, th, td {\r\n    border: 1px solid black;\r\n    border-collapse: collapse;\r\n}\r\n\r\n/*------------------------------------------------*/\r\n/*--------------[TEAM STYLE]-----------*/\r\n/*------------------------------------------------*/\r\n.our-team{\r\n    text-align: center;\r\n    position: relative;\r\n}\r\n.our-team img{\r\n    width: 100%;\r\n    height: auto;\r\n}\r\n.our-team .team-content{\r\n    width: 100%;\r\n    height: auto;\r\n    background: #222;\r\n    padding: 15px 0;\r\n    box-shadow: 0 15px 25px 0 rgba(3,7,15,0.1);\r\n    position: absolute;\r\n    bottom: 0;\r\n    right: 0;\r\n    transition: all 0.5s ease 0s;\r\n}\r\n.our-team:hover .team-content{\r\n    background: #222;\r\n}\r\n.our-team .title{\r\n    font-size: 20px;\r\n    font-weight: 700;\r\n    color: #fff;\r\n    text-transform: capitalize;\r\n    margin: 0;\r\n    transition: all 0.5s ease 0s;\r\n}\r\n.our-team:hover .title{\r\n    color: #a0ce4e;\r\n    margin-bottom: 10px;\r\n}\r\n.our-team .post{\r\n    display: block;\r\n    font-size: 15px;\r\n    font-style: italic;\r\n    color: #a0ce4e;\r\n    text-transform: capitalize;\r\n    height: 0;\r\n    opacity: 0;\r\n    transform: scale(0);\r\n    transition: all 0.5s ease 0s;\r\n}\r\n.our-team:hover .post{\r\n    height: 40px;\r\n    opacity: 1;\r\n    transform: scale(1);\r\n}\r\n.our-team .social{\r\n    list-style: none;\r\n    padding: 0;\r\n    margin: 0;\r\n    width: 100%;\r\n    position: absolute;\r\n    bottom: 0;\r\n    left: 0;\r\n    opacity: 0;\r\n    transform: translateY(-60%);\r\n    transition: all 0.5s ease 0s;\r\n}\r\n.our-team:hover .social{\r\n    transform: translateY(50%);\r\n    opacity: 1;\r\n}\r\n.our-team .social li{\r\n    display: inline-block;\r\n}\r\n.our-team .social li a{\r\n    display: block;\r\n    width: 40px;\r\n    height: 40px;\r\n    border-radius: 50%;\r\n    background: #a0ce4e;\r\n    font-size: 17px;\r\n    font-weight: 700;\r\n    line-height:40px;\r\n    color: #fff;\r\n    transition: all 0.5s ease 0s;\r\n}\r\n.our-team .social li a:hover{\r\n    color: #a0ce4e;\r\n    background: #fff;\r\n}\r\n@media only screen and (max-width: 990px){\r\n    .our-team{ margin-bottom: 30px; }\r\n}\r\n/*------------------------------------------------*/\r\n/*--------------[PARALLAX VIDEO STYLE 1]-----------*/\r\n/*------------------------------------------------*/\r\n.single-contact-option i, .single-social-icon i {\r\n    border: 3px solid transparent;\r\n    border-radius: 50%;\r\n    color: #fff;\r\n    font-size: 36px;\r\n    height: 95px;\r\n    line-height: 90px;\r\n    transition: all 0.3s ease 0s;\r\n    width: 95px;\r\n}\r\n.single-contact-option i {\r\n    background: #222 none repeat scroll 0 0;\r\n    margin-bottom: 30px;\r\n}\r\n.single-contact-option:hover i, .single-social-icon a:hover i {\r\n    background: #a0ce4e none repeat scroll 0 0;\r\n    border: 3px solid #fff;\r\n    box-shadow: 0 0 0 4px #a0ce4e;\r\n}\r\n.single-contact-option h6 {\r\n    color: inherit;\r\n    font-weight: bold;\r\n    margin-bottom: 5px;\r\n}\r\n.single-contact-option p {\r\n    color: inherit;\r\n    line-height: 26px;\r\n    margin: 0;\r\n}\r\n/*------------------------------------------------*/\r\n/*--------------[PARALLAX VIDEO STYLE 1]-----------*/\r\n/*------------------------------------------------*/\r\n.parallax_video_box .parallax_video_wrap {\r\n    display: block;\r\n}\r\n.parallax_video_wrap {\r\n    height: 750px;\r\n    left: 0;\r\n    overflow: hidden;\r\n    right: 0;\r\n    z-index: 1;\r\n}\r\n.parallax_video_wrap .parallax_video {\r\n    left: 0;\r\n    top: 0;\r\n}\r\n\r\n\r\n/*------------------------------------------------*/\r\n/*--------------[LOGIN/REGISTRE STYLE]-----------*/\r\n/*------------------------------------------------*/\r\n\r\n.login-header {\r\n    display: inline-block;\r\n    width: 100%;\r\n    background: #222;\r\n}\r\n.login-header .navbar-right {\r\n    margin-left: 0px;\r\n    float: left!important;\r\n}\r\n\r\n.login-header .nav-tabs > li.active > a,\r\n.login-header .nav-tabs > li.active > a:focus,\r\n.login-header .nav-tabs > li.active > a:hover {\r\n    background-color: transparent;\r\n    border: none;\r\n    color: #fff;\r\n}\r\n\r\n.login-header .nav-tabs > li > a {\r\n    border: medium none;\r\n    border-radius: 0;\r\n    font-size: 14px;\r\n    font-weight: 500;\r\n    line-height: 48px;\r\n    padding: 15px 30px;\r\n    color: #fff;\r\n}\r\n\r\n.login-header .nav-tabs {\r\n    border-bottom: none;\r\n}\r\n\r\n.login-header .nav-tabs > li {\r\n    margin-bottom: 0px;\r\n}\r\n\r\n.login-header .nav > li > a:focus,\r\n.login-header .nav > li > a:hover {\r\n    background: none;\r\n    text-decoration: none;\r\n}\r\n\r\n.login-header .nav-tabs > li.active {\r\n    border-bottom: 6px solid #a0ce4e;\r\n}\r\n\r\n.login-inner h1 {\r\n    color: inherit;\r\n    font-size: 35px;\r\n    font-weight: 300;\r\n    text-align: center;\r\n    margin-top: 0;\r\n}\r\n\r\n.login-inner h1 span {\r\n    color: #a0ce4e;\r\n}\r\n\r\n.login-form {\r\n    text-align: center;\r\n}\r\n\r\n.login-form input {\r\n    -moz-border-bottom-colors: none;\r\n    -moz-border-left-colors: none;\r\n    -moz-border-right-colors: none;\r\n    -moz-border-top-colors: none;\r\n    background: rgba(0, 0, 0, 0) none repeat scroll 0 0;\r\n    border-color: -moz-use-text-color -moz-use-text-color #d4d9e3;\r\n    border-image: none;\r\n    border-style: none none solid;\r\n    border-width: medium medium 1px;\r\n    font-size: 13px;\r\n    font-weight: 300;\r\n    width: 100%;\r\n    color: inherit;\r\n    padding: 15px 50px;\r\n    font-size: 17px;\r\n    max-width: 550px;\r\n}\r\n\r\n.login-form label {\r\n    margin-bottom: 30px;\r\n    width: 100%;\r\n}\r\n.form-btn {\r\n    background: #a0ce4e none repeat scroll 0 0;\r\n    border: medium none;\r\n    border-radius: 100px;\r\n    color: #ffffff;\r\n    font-weight: 400;\r\n    max-width: 250px;\r\n    padding: 10px 0;\r\n    position: relative;\r\n    width: 100%;\r\n    box-shadow: 0 2px 8px #d2d2d2;\r\n    -moz-box-shadow: 0 2px 8px #d2d2d2;\r\n    -webkit-box-shadow: 0 2px 8px #d2d2d2;\r\n}\r\n\r\n.form-btn::before {\r\n    content: \"\";\r\n    font-family: FontAwesome;\r\n    position: absolute;\r\n    right: 17px;\r\n    top: 9px;\r\n}\r\n\r\n.form-details {\r\n    padding: 35px 0;\r\n}\r\n\r\n.tab-content .tab-pane {\r\n    padding-top:30px;\r\n}\r\n@media only screen and (max-device-width: 767px) {\r\n    .login-details .nav-tabs > li {\r\n        text-align: center;\r\n        width: 50%;\r\n    }\r\n    .login-inner .login-form input {\r\n        font-size: 15px;\r\n        max-width: 100%;\r\n        padding: 15px 45px;\r\n    }\r\n    .login-inner .form-details {\r\n        padding: 25px;\r\n    }\r\n    .login-inner .login-form label {\r\n        margin-bottom: 20px;\r\n        width: 100%;\r\n    }\r\n    .login-inner .form-btn {\r\n        margin: 0;\r\n        max-width: 180px;\r\n    }\r\n    .tab-content .tab-pane {\r\n        padding: 20px 0;\r\n    }\r\n}\r\n/*------------------------------------------------*/\r\n/*--------------[subscribe STYLE]-----------*/\r\n/*------------------------------------------------*/\r\n.news-subscribe {\r\n    padding: 30px 0;\r\n    background: #a0ce4e;\r\n}\r\n\r\n.news-subscribe h3{\r\n    margin: 0;\r\n    color: #fff;\r\n    font-size: 22px;\r\n    font-weight: 200;\r\n    text-transform: uppercase;\r\n}\r\n.news-subscribe input {\r\n    border-color: #fff;\r\n    border-right: none;\r\n    background: transparent;\r\n}\r\n\r\n.news-subscribe .form-control {\r\n    color: #fff;\r\n    font-size: 14px;\r\n    font-weight: 200;\r\n}\r\n\r\n.news-subscribe .form-control:focus {\r\n    box-shadow: none;\r\n    border-color: #fff;\r\n}\r\n\r\n.news-subscribe .form-control::-moz-placeholder {\r\n    color: #fff;\r\n}\r\n.news-subscribe .form-control:-ms-input-placeholder {\r\n    color: #fff;\r\n}\r\n.news-subscribe .form-control::-webkit-input-placeholder {\r\n    color: #fff;\r\n}\r\n\r\n.news-subscribe .input-group-btn {\r\n    border-color: #fff;\r\n    background: transparent;\r\n}\r\n\r\n.news-subscribe .input-group-btn .btn {\r\n    border: 1px solid #fff;\r\n    background: transparent;\r\n}\r\n\r\n.news-subscribe .input-group-btn i {\r\n    color: #fff;\r\n    font-size: 16px;\r\n    font-weight: 200;\r\n}\r\n.news-subscribe .social-icons > li > a{\r\n    margin-top:0;\r\n     background: #fff none repeat scroll 0 0;\r\n}\r\n.news-subscribe .social-icons > li > a i {\r\n    color: #787878;\r\n}\r\n.news-subscribe .social-icons-simple{\r\n    text-align: right;\r\n}\r\n\r\n/*footer*/\r\n#footer {background-color:#323232;}\r\n#footer .about{ border-bottom: 1px solid #ccc;}\r\n#footer .about dl{ margin-top: 20px;}\r\n#footer .about dt{ line-height: 35px; height: 35px; font-size: 18px; margin-bottom: 15px; color: #fff;}\r\n#footer .about dd{ line-height: 30px; height: 30px; font-size: 14px; color: #777;}\r\n#footer .about .row-hr{ border-bottom: 1px solid #ccc; padding-bottom: 10px;}\r\n#footer .about .tel{ background: url(\"../img/tel.png\") no-repeat left; height: 55px; padding-left: 60px; margin-top: 20px;}\r\n#footer .about p{ padding: 0px;margin: 0px;}\r\n#footer .about .tel .number{ font-size: 26px;color:#fff;}\r\n#footer .about .address{ margin-top: 10px;}\r\n#footer .about .address p{ font-size: 14px; line-height: 30px;}\r\n#footer .about .weixin{ text-align: center;}\r\n#footer .about .weixin h3{ margin-top: 26px; margin-bottom: 15px;}\r\n#footer .about .weixin p{ margin-top: 10px;}\r\n#footer .links { padding: 20px 10px;}\r\n#footer .links a { margin: 0px 10px;}\r\n@media (max-width: 990px) {\r\n    .news-subscribe h3,.news-subscribe .social-icons-simple {\r\ntext-align: center;\r\n    }\r\n}\r\n@media (max-width: 990px) {\r\n    .newsletter-form-block {\r\npadding: 15px 0;\r\n    }\r\n}\r\n\r\n\r\n@media (max-width: 990px) {\r\n    .home-about-text2,.why-choose-img,.clients-block, .col-style1,.product-quantity,.single-contact-option,.single_feature, .footer .widget,.products.grid-product,.service-box1  {\r\n        margin-bottom: 30px;\r\n    }\r\n}\r\n@media (max-width: 367px) {\r\n    .content-text .btn.btn-product.mr15{\r\n           margin-bottom: 30px;\r\n    }\r\n}\r\n\r\n@media (max-width: 990px) {\r\n    .welcome-img img, .why-choose-img img, .theme-image, .clients-block img{\r\n          width: 100%;\r\n    }\r\n}"
  },
  {
    "path": "app_frontend/static/theme/default/js/cubeportfolio/blog-grid-3col.js",
    "content": "(function($, window, document, undefined) {\r\n    'use strict';\r\n        \r\n    // init cubeportfolio\r\n    $('#js-grid-blog-posts').cubeportfolio({\r\n        filters: '#js-filters-blog-posts',\r\n        search: '#js-search-blog-posts',\r\n        defaultFilter: '*',\r\n        animationType: '3dflip',\r\n        gapHorizontal: 30,\r\n        gapVertical: 30,\r\n        gridAdjustment: 'responsive',\r\n        mediaQueries: [{\r\n            width: 1500,\r\n            cols: 3\r\n        }, {\r\n            width: 1100,\r\n            cols: 3\r\n        }, {\r\n            width: 800,\r\n            cols: 3\r\n        }, {\r\n            width: 480,\r\n            cols: 1,\r\n            options: {\r\n                caption: ''\r\n            }\r\n        }, {\r\n            width: 320,\r\n            cols: 1,\r\n            options: {\r\n                caption: ''\r\n            }\r\n        }],\r\n        caption: 'revealBottom',\r\n        displayType: 'fadeIn',\r\n        displayTypeSpeed: 400,\r\n    });\r\n})(jQuery, window, document);\r\n"
  },
  {
    "path": "app_frontend/static/theme/default/js/cubeportfolio/portfolio-masonry-4col.js",
    "content": "(function($, window, document, undefined) {\r\n    'use strict';\r\n    \r\n\r\n    // init cubeportfolio\r\n    $('#js-grid-masonry').cubeportfolio({\r\n        filters: '#js-filters-masonry',\r\n        layoutMode: 'grid',\r\n        defaultFilter: '*',\r\n        animationType: 'slideDelay',\r\n        gapHorizontal: 30,\r\n        gapVertical: 30,\r\n        gridAdjustment: 'responsive',\r\n        mediaQueries: [{\r\n            width: 1500,\r\n            cols: 4\r\n        }, {\r\n            width: 1100,\r\n            cols: 4\r\n        }, {\r\n            width: 800,\r\n            cols: 3\r\n        }, {\r\n            width: 480,\r\n            cols: 2,\r\n            options: {\r\n                caption: ''\r\n            }\r\n        }, {\r\n            width: 320,\r\n            cols: 1,\r\n            options: {\r\n                caption: ''\r\n            }\r\n        }],\r\n        caption: 'overlayBottomAlong',\r\n        displayType: 'bottomToTop',\r\n        displayTypeSpeed: 100,\r\n\r\n        // lightbox\r\n        lightboxDelegate: '.cbp-lightbox',\r\n        lightboxGallery: true,\r\n        lightboxTitleSrc: 'data-title',\r\n        lightboxCounter: '<div class=\"cbp-popup-lightbox-counter\">{{current}} of {{total}}</div>',\r\n    });\r\n})(jQuery, window, document);\r\n\r\n"
  },
  {
    "path": "app_frontend/static/theme/default/js/cubeportfolio/team.js",
    "content": "(function($, window, document, undefined) {\r\n    'use strict';\r\n\r\n    // init cubeportfolio\r\n    $('#js-grid-slider-team').cubeportfolio({\r\n        layoutMode: 'slider',\r\n        drag: true,\r\n        auto: false,\r\n        autoTimeout: 5000,\r\n        autoPauseOnHover: true,\r\n        showNavigation: false,\r\n        showPagination: true,\r\n        rewindNav: true,\r\n        scrollByPage: true,\r\n        gridAdjustment: 'responsive',\r\n        mediaQueries: [{\r\n            width: 1680,\r\n            cols: 5\r\n        }, {\r\n            width: 1350,\r\n            cols: 4\r\n        }, {\r\n            width: 800,\r\n            cols: 3\r\n        }, {\r\n            width: 480,\r\n            cols: 2\r\n        }, {\r\n            width: 320,\r\n            cols: 1\r\n        }],\r\n        gapHorizontal: 0,\r\n        gapVertical: 45,\r\n        caption: '',\r\n        displayType: 'fadeIn',\r\n        displayTypeSpeed: 400,\r\n    });\r\n\t\r\n})(jQuery, window, document);\r\n\r\n\r\n"
  },
  {
    "path": "app_frontend/static/theme/default/js/cubeportfolio/testimonials.js",
    "content": "\r\n/* slider-testimonials */\r\n(function($, window, document, undefined) {\r\n    'use strict';\r\n\r\n    // init cubeportfolio\r\n    $('#js-grid-slider-testimonials').cubeportfolio({\r\n        layoutMode: 'slider',\r\n        drag: true,\r\n        auto: false,\r\n        autoTimeout: 5000,\r\n        autoPauseOnHover: true,\r\n        showNavigation: true,\r\n        showPagination: true,\r\n        rewindNav: true,\r\n        scrollByPage: false,\r\n        gridAdjustment: 'responsive',\r\n        mediaQueries: [{\r\n            width: 1,\r\n            cols: 1\r\n        }],\r\n        gapHorizontal: 0,\r\n        gapVertical: 0,\r\n        caption: '',\r\n        displayType: 'default',\r\n    });\r\n})(jQuery, window, document);\r\n"
  },
  {
    "path": "app_frontend/static/theme/default/js/custom.js",
    "content": "(function ($, window, document, undefined) {\r\n    'use strict';\r\n\r\n\r\n    /***************** Header Search ******************/\r\n    $('.search').click(function(e) {\r\n        var searchbtn = $('.search-btn');\r\n        var searchopen = $('.search-open');\r\n        if (searchbtn.hasClass('fa-search')) {\r\n            searchopen.fadeIn(500);\r\n            searchbtn.removeClass('fa-search').addClass('fa-times');\r\n        } else {\r\n            searchopen.fadeOut(500);\r\n            searchbtn.removeClass('fa-times').addClass('fa-search');\r\n        }\r\n    });\r\n\r\n    /*\r\n     /*\r\n     * Custom Data Fixed\r\n     */\r\n    $('.beactive').addClass('active');\r\n    $('.beactive').removeClass('beactive');\r\n\r\n\r\n    /*============================================\r\n     Tooltip\r\n     ==============================================*/\r\n    $('[data-toggle=\"tooltip\"]').tooltip();\r\n\r\n    /*============================================\r\n     Progress Bar\r\n     ==============================================*/\r\n    var progress = $('.progress-bars');\r\n    if (progress.length) {\r\n        $(window).bind('scroll', function (e) {\r\n            var hT = progress.offset().top,\r\n                    hH = progress.outerHeight(),\r\n                    wH = $(window).height(),\r\n                    wS = $(this).scrollTop();\r\n            if (wS > (hT + hH - wH)) {\r\n                $(function () {\r\n\r\n                    $('.progress-bars > .progress > .progress-bar').each(function () {\r\n                        var width = $(this).attr('aria-valuenow');\r\n                        $(this).css('width', width + '%');\r\n                    });\r\n\r\n                });\r\n            }\r\n        });\r\n    }\r\n\r\n    /*============================================\r\n     Brand\r\n     ==============================================*/\r\n    $('#owl-clients').owlCarousel({\r\n        items: 4,\r\n        itemsDesktop: [1199, 4],\r\n        itemsDesktopSmall: [979, 4],\r\n        itemsTablet: [768, 3],\r\n        pagination: true,\r\n        autoPlay: true\r\n    });\r\n\r\n\r\n    /*============================================\r\n     Counter\r\n     ==============================================*/\r\n    var count = $('.count');\r\n    if (count.length)\r\n    {\r\n        count.counterUp({\r\n            delay: 10,\r\n            time: 1000\r\n        });\r\n    }\r\n\r\n})(jQuery, window, document);\r\n\r\n"
  },
  {
    "path": "app_frontend/static/theme/default/js/google-map.js",
    "content": "\r\nfunction initialize() {\r\n    var styles = {\r\n        'classify': [{\r\n                \"featureType\": \"administrative\",\r\n                \"stylers\": [\r\n                    {\"visibility\": \"on\"}\r\n                ]\r\n            },\r\n            {\r\n                \"featureType\": \"road\",\r\n                \"stylers\": [\r\n                    {\"visibility\": \"on\"},\r\n                    {\"hue\": \"#6990cb\"}\r\n                ]\r\n            },\r\n            {\r\n                \"stylers\": [\r\n                    {\"visibility\": \"on\"},\r\n                    {\"hue\": \"#6990cb\"},\r\n                    {\"saturation\": -50}\r\n                ]\r\n            }\r\n        ]};\r\n\r\n    var myLatlng = new google.maps.LatLng(-34.397, 150.644);\r\n    var myOptions = {\r\n        zoom: 10,\r\n        center: myLatlng,\r\n        mapTypeId: google.maps.MapTypeId.ROADMAP,\r\n        //disableDefaultUI: true,\r\n        mapTypeId: 'classify',\r\n                draggable: true,\r\n        scrollwheel: false,\r\n    }\r\n    var map = new google.maps.Map(document.getElementById(\"map_classify\"), myOptions);\r\n    var styledMapType = new google.maps.StyledMapType(styles['classify'], {name: 'classify'});\r\n    map.mapTypes.set('classify', styledMapType);\r\n\r\n    var marker = new google.maps.Marker({\r\n        position: myLatlng,\r\n        map: map,\r\n        title: \"\"\r\n    });\r\n    }\r\n\r\ngoogle.maps.event.addDomListener(window, 'load', initialize);\r\ngoogle.maps.event.addDomListener(window, 'resize', initialize);\r\n\r\n"
  },
  {
    "path": "app_frontend/static/theme/default/js/index.js",
    "content": "$(function(){\r\n\t$('a[href*=#],area[href*=#]').click(function() {\r\n        if (location.pathname.replace(/^\\//, '') == this.pathname.replace(/^\\//, '') && location.hostname == this.hostname) {\r\n            var $target = $(this.hash);\r\n            $target = $target.length && $target || $('[name=' + this.hash.slice(1) + ']');\r\n            if ($target.length) {\r\n                var targetOffset = $target.offset().top;\r\n                $('html,body').animate({\r\n                        scrollTop: targetOffset\r\n                    },\r\n                    500);\r\n                return false;\r\n            }\r\n        }\r\n    });\r\n})"
  },
  {
    "path": "app_frontend/static/theme/default/js/navigation.js",
    "content": ""
  },
  {
    "path": "app_frontend/static/theme/default/plugins/FlexSlider/jquery.flexslider-min.js",
    "content": "/*\n * jQuery FlexSlider v2.6.1\n * Copyright 2012 WooThemes\n * Contributing Author: Tyler Smith\n */!function($){var e=!0;$.flexslider=function(t,a){var n=$(t);n.vars=$.extend({},$.flexslider.defaults,a);var i=n.vars.namespace,s=window.navigator&&window.navigator.msPointerEnabled&&window.MSGesture,r=(\"ontouchstart\"in window||s||window.DocumentTouch&&document instanceof DocumentTouch)&&n.vars.touch,o=\"click touchend MSPointerUp keyup\",l=\"\",c,d=\"vertical\"===n.vars.direction,u=n.vars.reverse,v=n.vars.itemWidth>0,p=\"fade\"===n.vars.animation,m=\"\"!==n.vars.asNavFor,f={};$.data(t,\"flexslider\",n),f={init:function(){n.animating=!1,n.currentSlide=parseInt(n.vars.startAt?n.vars.startAt:0,10),isNaN(n.currentSlide)&&(n.currentSlide=0),n.animatingTo=n.currentSlide,n.atEnd=0===n.currentSlide||n.currentSlide===n.last,n.containerSelector=n.vars.selector.substr(0,n.vars.selector.search(\" \")),n.slides=$(n.vars.selector,n),n.container=$(n.containerSelector,n),n.count=n.slides.length,n.syncExists=$(n.vars.sync).length>0,\"slide\"===n.vars.animation&&(n.vars.animation=\"swing\"),n.prop=d?\"top\":\"marginLeft\",n.args={},n.manualPause=!1,n.stopped=!1,n.started=!1,n.startTimeout=null,n.transitions=!n.vars.video&&!p&&n.vars.useCSS&&function(){var e=document.createElement(\"div\"),t=[\"perspectiveProperty\",\"WebkitPerspective\",\"MozPerspective\",\"OPerspective\",\"msPerspective\"];for(var a in t)if(void 0!==e.style[t[a]])return n.pfx=t[a].replace(\"Perspective\",\"\").toLowerCase(),n.prop=\"-\"+n.pfx+\"-transform\",!0;return!1}(),n.ensureAnimationEnd=\"\",\"\"!==n.vars.controlsContainer&&(n.controlsContainer=$(n.vars.controlsContainer).length>0&&$(n.vars.controlsContainer)),\"\"!==n.vars.manualControls&&(n.manualControls=$(n.vars.manualControls).length>0&&$(n.vars.manualControls)),\"\"!==n.vars.customDirectionNav&&(n.customDirectionNav=2===$(n.vars.customDirectionNav).length&&$(n.vars.customDirectionNav)),n.vars.randomize&&(n.slides.sort(function(){return Math.round(Math.random())-.5}),n.container.empty().append(n.slides)),n.doMath(),n.setup(\"init\"),n.vars.controlNav&&f.controlNav.setup(),n.vars.directionNav&&f.directionNav.setup(),n.vars.keyboard&&(1===$(n.containerSelector).length||n.vars.multipleKeyboard)&&$(document).bind(\"keyup\",function(e){var t=e.keyCode;if(!n.animating&&(39===t||37===t)){var a=39===t?n.getTarget(\"next\"):37===t?n.getTarget(\"prev\"):!1;n.flexAnimate(a,n.vars.pauseOnAction)}}),n.vars.mousewheel&&n.bind(\"mousewheel\",function(e,t,a,i){e.preventDefault();var s=0>t?n.getTarget(\"next\"):n.getTarget(\"prev\");n.flexAnimate(s,n.vars.pauseOnAction)}),n.vars.pausePlay&&f.pausePlay.setup(),n.vars.slideshow&&n.vars.pauseInvisible&&f.pauseInvisible.init(),n.vars.slideshow&&(n.vars.pauseOnHover&&n.hover(function(){n.manualPlay||n.manualPause||n.pause()},function(){n.manualPause||n.manualPlay||n.stopped||n.play()}),n.vars.pauseInvisible&&f.pauseInvisible.isHidden()||(n.vars.initDelay>0?n.startTimeout=setTimeout(n.play,n.vars.initDelay):n.play())),m&&f.asNav.setup(),r&&n.vars.touch&&f.touch(),(!p||p&&n.vars.smoothHeight)&&$(window).bind(\"resize orientationchange focus\",f.resize),n.find(\"img\").attr(\"draggable\",\"false\"),setTimeout(function(){n.vars.start(n)},200)},asNav:{setup:function(){n.asNav=!0,n.animatingTo=Math.floor(n.currentSlide/n.move),n.currentItem=n.currentSlide,n.slides.removeClass(i+\"active-slide\").eq(n.currentItem).addClass(i+\"active-slide\"),s?(t._slider=n,n.slides.each(function(){var e=this;e._gesture=new MSGesture,e._gesture.target=e,e.addEventListener(\"MSPointerDown\",function(e){e.preventDefault(),e.currentTarget._gesture&&e.currentTarget._gesture.addPointer(e.pointerId)},!1),e.addEventListener(\"MSGestureTap\",function(e){e.preventDefault();var t=$(this),a=t.index();$(n.vars.asNavFor).data(\"flexslider\").animating||t.hasClass(\"active\")||(n.direction=n.currentItem<a?\"next\":\"prev\",n.flexAnimate(a,n.vars.pauseOnAction,!1,!0,!0))})})):n.slides.on(o,function(e){e.preventDefault();var t=$(this),a=t.index(),s=t.offset().left-$(n).scrollLeft();0>=s&&t.hasClass(i+\"active-slide\")?n.flexAnimate(n.getTarget(\"prev\"),!0):$(n.vars.asNavFor).data(\"flexslider\").animating||t.hasClass(i+\"active-slide\")||(n.direction=n.currentItem<a?\"next\":\"prev\",n.flexAnimate(a,n.vars.pauseOnAction,!1,!0,!0))})}},controlNav:{setup:function(){n.manualControls?f.controlNav.setupManual():f.controlNav.setupPaging()},setupPaging:function(){var e=\"thumbnails\"===n.vars.controlNav?\"control-thumbs\":\"control-paging\",t=1,a,s;if(n.controlNavScaffold=$('<ol class=\"'+i+\"control-nav \"+i+e+'\"></ol>'),n.pagingCount>1)for(var r=0;r<n.pagingCount;r++){s=n.slides.eq(r),void 0===s.attr(\"data-thumb-alt\")&&s.attr(\"data-thumb-alt\",\"\");var c=\"\"!==s.attr(\"data-thumb-alt\")?c=' alt=\"'+s.attr(\"data-thumb-alt\")+'\"':\"\";if(a=\"thumbnails\"===n.vars.controlNav?'<img src=\"'+s.attr(\"data-thumb\")+'\"'+c+\"/>\":'<a href=\"#\">'+t+\"</a>\",\"thumbnails\"===n.vars.controlNav&&!0===n.vars.thumbCaptions){var d=s.attr(\"data-thumbcaption\");\"\"!==d&&void 0!==d&&(a+='<span class=\"'+i+'caption\">'+d+\"</span>\")}n.controlNavScaffold.append(\"<li>\"+a+\"</li>\"),t++}n.controlsContainer?$(n.controlsContainer).append(n.controlNavScaffold):n.append(n.controlNavScaffold),f.controlNav.set(),f.controlNav.active(),n.controlNavScaffold.delegate(\"a, img\",o,function(e){if(e.preventDefault(),\"\"===l||l===e.type){var t=$(this),a=n.controlNav.index(t);t.hasClass(i+\"active\")||(n.direction=a>n.currentSlide?\"next\":\"prev\",n.flexAnimate(a,n.vars.pauseOnAction))}\"\"===l&&(l=e.type),f.setToClearWatchedEvent()})},setupManual:function(){n.controlNav=n.manualControls,f.controlNav.active(),n.controlNav.bind(o,function(e){if(e.preventDefault(),\"\"===l||l===e.type){var t=$(this),a=n.controlNav.index(t);t.hasClass(i+\"active\")||(a>n.currentSlide?n.direction=\"next\":n.direction=\"prev\",n.flexAnimate(a,n.vars.pauseOnAction))}\"\"===l&&(l=e.type),f.setToClearWatchedEvent()})},set:function(){var e=\"thumbnails\"===n.vars.controlNav?\"img\":\"a\";n.controlNav=$(\".\"+i+\"control-nav li \"+e,n.controlsContainer?n.controlsContainer:n)},active:function(){n.controlNav.removeClass(i+\"active\").eq(n.animatingTo).addClass(i+\"active\")},update:function(e,t){n.pagingCount>1&&\"add\"===e?n.controlNavScaffold.append($('<li><a href=\"#\">'+n.count+\"</a></li>\")):1===n.pagingCount?n.controlNavScaffold.find(\"li\").remove():n.controlNav.eq(t).closest(\"li\").remove(),f.controlNav.set(),n.pagingCount>1&&n.pagingCount!==n.controlNav.length?n.update(t,e):f.controlNav.active()}},directionNav:{setup:function(){var e=$('<ul class=\"'+i+'direction-nav\"><li class=\"'+i+'nav-prev\"><a class=\"'+i+'prev\" href=\"#\">'+n.vars.prevText+'</a></li><li class=\"'+i+'nav-next\"><a class=\"'+i+'next\" href=\"#\">'+n.vars.nextText+\"</a></li></ul>\");n.customDirectionNav?n.directionNav=n.customDirectionNav:n.controlsContainer?($(n.controlsContainer).append(e),n.directionNav=$(\".\"+i+\"direction-nav li a\",n.controlsContainer)):(n.append(e),n.directionNav=$(\".\"+i+\"direction-nav li a\",n)),f.directionNav.update(),n.directionNav.bind(o,function(e){e.preventDefault();var t;(\"\"===l||l===e.type)&&(t=$(this).hasClass(i+\"next\")?n.getTarget(\"next\"):n.getTarget(\"prev\"),n.flexAnimate(t,n.vars.pauseOnAction)),\"\"===l&&(l=e.type),f.setToClearWatchedEvent()})},update:function(){var e=i+\"disabled\";1===n.pagingCount?n.directionNav.addClass(e).attr(\"tabindex\",\"-1\"):n.vars.animationLoop?n.directionNav.removeClass(e).removeAttr(\"tabindex\"):0===n.animatingTo?n.directionNav.removeClass(e).filter(\".\"+i+\"prev\").addClass(e).attr(\"tabindex\",\"-1\"):n.animatingTo===n.last?n.directionNav.removeClass(e).filter(\".\"+i+\"next\").addClass(e).attr(\"tabindex\",\"-1\"):n.directionNav.removeClass(e).removeAttr(\"tabindex\")}},pausePlay:{setup:function(){var e=$('<div class=\"'+i+'pauseplay\"><a href=\"#\"></a></div>');n.controlsContainer?(n.controlsContainer.append(e),n.pausePlay=$(\".\"+i+\"pauseplay a\",n.controlsContainer)):(n.append(e),n.pausePlay=$(\".\"+i+\"pauseplay a\",n)),f.pausePlay.update(n.vars.slideshow?i+\"pause\":i+\"play\"),n.pausePlay.bind(o,function(e){e.preventDefault(),(\"\"===l||l===e.type)&&($(this).hasClass(i+\"pause\")?(n.manualPause=!0,n.manualPlay=!1,n.pause()):(n.manualPause=!1,n.manualPlay=!0,n.play())),\"\"===l&&(l=e.type),f.setToClearWatchedEvent()})},update:function(e){\"play\"===e?n.pausePlay.removeClass(i+\"pause\").addClass(i+\"play\").html(n.vars.playText):n.pausePlay.removeClass(i+\"play\").addClass(i+\"pause\").html(n.vars.pauseText)}},touch:function(){function e(e){e.stopPropagation(),n.animating?e.preventDefault():(n.pause(),t._gesture.addPointer(e.pointerId),T=0,c=d?n.h:n.w,f=Number(new Date),l=v&&u&&n.animatingTo===n.last?0:v&&u?n.limit-(n.itemW+n.vars.itemMargin)*n.move*n.animatingTo:v&&n.currentSlide===n.last?n.limit:v?(n.itemW+n.vars.itemMargin)*n.move*n.currentSlide:u?(n.last-n.currentSlide+n.cloneOffset)*c:(n.currentSlide+n.cloneOffset)*c)}function a(e){e.stopPropagation();var a=e.target._slider;if(a){var n=-e.translationX,i=-e.translationY;return T+=d?i:n,m=T,y=d?Math.abs(T)<Math.abs(-n):Math.abs(T)<Math.abs(-i),e.detail===e.MSGESTURE_FLAG_INERTIA?void setImmediate(function(){t._gesture.stop()}):void((!y||Number(new Date)-f>500)&&(e.preventDefault(),!p&&a.transitions&&(a.vars.animationLoop||(m=T/(0===a.currentSlide&&0>T||a.currentSlide===a.last&&T>0?Math.abs(T)/c+2:1)),a.setProps(l+m,\"setTouch\"))))}}function i(e){e.stopPropagation();var t=e.target._slider;if(t){if(t.animatingTo===t.currentSlide&&!y&&null!==m){var a=u?-m:m,n=a>0?t.getTarget(\"next\"):t.getTarget(\"prev\");t.canAdvance(n)&&(Number(new Date)-f<550&&Math.abs(a)>50||Math.abs(a)>c/2)?t.flexAnimate(n,t.vars.pauseOnAction):p||t.flexAnimate(t.currentSlide,t.vars.pauseOnAction,!0)}r=null,o=null,m=null,l=null,T=0}}var r,o,l,c,m,f,g,h,S,y=!1,x=0,b=0,T=0;s?(t.style.msTouchAction=\"none\",t._gesture=new MSGesture,t._gesture.target=t,t.addEventListener(\"MSPointerDown\",e,!1),t._slider=n,t.addEventListener(\"MSGestureChange\",a,!1),t.addEventListener(\"MSGestureEnd\",i,!1)):(g=function(e){n.animating?e.preventDefault():(window.navigator.msPointerEnabled||1===e.touches.length)&&(n.pause(),c=d?n.h:n.w,f=Number(new Date),x=e.touches[0].pageX,b=e.touches[0].pageY,l=v&&u&&n.animatingTo===n.last?0:v&&u?n.limit-(n.itemW+n.vars.itemMargin)*n.move*n.animatingTo:v&&n.currentSlide===n.last?n.limit:v?(n.itemW+n.vars.itemMargin)*n.move*n.currentSlide:u?(n.last-n.currentSlide+n.cloneOffset)*c:(n.currentSlide+n.cloneOffset)*c,r=d?b:x,o=d?x:b,t.addEventListener(\"touchmove\",h,!1),t.addEventListener(\"touchend\",S,!1))},h=function(e){x=e.touches[0].pageX,b=e.touches[0].pageY,m=d?r-b:r-x,y=d?Math.abs(m)<Math.abs(x-o):Math.abs(m)<Math.abs(b-o);var t=500;(!y||Number(new Date)-f>t)&&(e.preventDefault(),!p&&n.transitions&&(n.vars.animationLoop||(m/=0===n.currentSlide&&0>m||n.currentSlide===n.last&&m>0?Math.abs(m)/c+2:1),n.setProps(l+m,\"setTouch\")))},S=function(e){if(t.removeEventListener(\"touchmove\",h,!1),n.animatingTo===n.currentSlide&&!y&&null!==m){var a=u?-m:m,i=a>0?n.getTarget(\"next\"):n.getTarget(\"prev\");n.canAdvance(i)&&(Number(new Date)-f<550&&Math.abs(a)>50||Math.abs(a)>c/2)?n.flexAnimate(i,n.vars.pauseOnAction):p||n.flexAnimate(n.currentSlide,n.vars.pauseOnAction,!0)}t.removeEventListener(\"touchend\",S,!1),r=null,o=null,m=null,l=null},t.addEventListener(\"touchstart\",g,!1))},resize:function(){!n.animating&&n.is(\":visible\")&&(v||n.doMath(),p?f.smoothHeight():v?(n.slides.width(n.computedW),n.update(n.pagingCount),n.setProps()):d?(n.viewport.height(n.h),n.setProps(n.h,\"setTotal\")):(n.vars.smoothHeight&&f.smoothHeight(),n.newSlides.width(n.computedW),n.setProps(n.computedW,\"setTotal\")))},smoothHeight:function(e){if(!d||p){var t=p?n:n.viewport;e?t.animate({height:n.slides.eq(n.animatingTo).innerHeight()},e):t.innerHeight(n.slides.eq(n.animatingTo).innerHeight())}},sync:function(e){var t=$(n.vars.sync).data(\"flexslider\"),a=n.animatingTo;switch(e){case\"animate\":t.flexAnimate(a,n.vars.pauseOnAction,!1,!0);break;case\"play\":t.playing||t.asNav||t.play();break;case\"pause\":t.pause()}},uniqueID:function(e){return e.filter(\"[id]\").add(e.find(\"[id]\")).each(function(){var e=$(this);e.attr(\"id\",e.attr(\"id\")+\"_clone\")}),e},pauseInvisible:{visProp:null,init:function(){var e=f.pauseInvisible.getHiddenProp();if(e){var t=e.replace(/[H|h]idden/,\"\")+\"visibilitychange\";document.addEventListener(t,function(){f.pauseInvisible.isHidden()?n.startTimeout?clearTimeout(n.startTimeout):n.pause():n.started?n.play():n.vars.initDelay>0?setTimeout(n.play,n.vars.initDelay):n.play()})}},isHidden:function(){var e=f.pauseInvisible.getHiddenProp();return e?document[e]:!1},getHiddenProp:function(){var e=[\"webkit\",\"moz\",\"ms\",\"o\"];if(\"hidden\"in document)return\"hidden\";for(var t=0;t<e.length;t++)if(e[t]+\"Hidden\"in document)return e[t]+\"Hidden\";return null}},setToClearWatchedEvent:function(){clearTimeout(c),c=setTimeout(function(){l=\"\"},3e3)}},n.flexAnimate=function(e,t,a,s,o){if(n.vars.animationLoop||e===n.currentSlide||(n.direction=e>n.currentSlide?\"next\":\"prev\"),m&&1===n.pagingCount&&(n.direction=n.currentItem<e?\"next\":\"prev\"),!n.animating&&(n.canAdvance(e,o)||a)&&n.is(\":visible\")){if(m&&s){var l=$(n.vars.asNavFor).data(\"flexslider\");if(n.atEnd=0===e||e===n.count-1,l.flexAnimate(e,!0,!1,!0,o),n.direction=n.currentItem<e?\"next\":\"prev\",l.direction=n.direction,Math.ceil((e+1)/n.visible)-1===n.currentSlide||0===e)return n.currentItem=e,n.slides.removeClass(i+\"active-slide\").eq(e).addClass(i+\"active-slide\"),!1;n.currentItem=e,n.slides.removeClass(i+\"active-slide\").eq(e).addClass(i+\"active-slide\"),e=Math.floor(e/n.visible)}if(n.animating=!0,n.animatingTo=e,t&&n.pause(),n.vars.before(n),n.syncExists&&!o&&f.sync(\"animate\"),n.vars.controlNav&&f.controlNav.active(),v||n.slides.removeClass(i+\"active-slide\").eq(e).addClass(i+\"active-slide\"),n.atEnd=0===e||e===n.last,n.vars.directionNav&&f.directionNav.update(),e===n.last&&(n.vars.end(n),n.vars.animationLoop||n.pause()),p)r?(n.slides.eq(n.currentSlide).css({opacity:0,zIndex:1}),n.slides.eq(e).css({opacity:1,zIndex:2}),n.wrapup(c)):(n.slides.eq(n.currentSlide).css({zIndex:1}).animate({opacity:0},n.vars.animationSpeed,n.vars.easing),n.slides.eq(e).css({zIndex:2}).animate({opacity:1},n.vars.animationSpeed,n.vars.easing,n.wrapup));else{var c=d?n.slides.filter(\":first\").height():n.computedW,g,h,S;v?(g=n.vars.itemMargin,S=(n.itemW+g)*n.move*n.animatingTo,h=S>n.limit&&1!==n.visible?n.limit:S):h=0===n.currentSlide&&e===n.count-1&&n.vars.animationLoop&&\"next\"!==n.direction?u?(n.count+n.cloneOffset)*c:0:n.currentSlide===n.last&&0===e&&n.vars.animationLoop&&\"prev\"!==n.direction?u?0:(n.count+1)*c:u?(n.count-1-e+n.cloneOffset)*c:(e+n.cloneOffset)*c,n.setProps(h,\"\",n.vars.animationSpeed),n.transitions?(n.vars.animationLoop&&n.atEnd||(n.animating=!1,n.currentSlide=n.animatingTo),n.container.unbind(\"webkitTransitionEnd transitionend\"),n.container.bind(\"webkitTransitionEnd transitionend\",function(){clearTimeout(n.ensureAnimationEnd),n.wrapup(c)}),clearTimeout(n.ensureAnimationEnd),n.ensureAnimationEnd=setTimeout(function(){n.wrapup(c)},n.vars.animationSpeed+100)):n.container.animate(n.args,n.vars.animationSpeed,n.vars.easing,function(){n.wrapup(c)})}n.vars.smoothHeight&&f.smoothHeight(n.vars.animationSpeed)}},n.wrapup=function(e){p||v||(0===n.currentSlide&&n.animatingTo===n.last&&n.vars.animationLoop?n.setProps(e,\"jumpEnd\"):n.currentSlide===n.last&&0===n.animatingTo&&n.vars.animationLoop&&n.setProps(e,\"jumpStart\")),n.animating=!1,n.currentSlide=n.animatingTo,n.vars.after(n)},n.animateSlides=function(){!n.animating&&e&&n.flexAnimate(n.getTarget(\"next\"))},n.pause=function(){clearInterval(n.animatedSlides),n.animatedSlides=null,n.playing=!1,n.vars.pausePlay&&f.pausePlay.update(\"play\"),n.syncExists&&f.sync(\"pause\")},n.play=function(){n.playing&&clearInterval(n.animatedSlides),n.animatedSlides=n.animatedSlides||setInterval(n.animateSlides,n.vars.slideshowSpeed),n.started=n.playing=!0,n.vars.pausePlay&&f.pausePlay.update(\"pause\"),n.syncExists&&f.sync(\"play\")},n.stop=function(){n.pause(),n.stopped=!0},n.canAdvance=function(e,t){var a=m?n.pagingCount-1:n.last;return t?!0:m&&n.currentItem===n.count-1&&0===e&&\"prev\"===n.direction?!0:m&&0===n.currentItem&&e===n.pagingCount-1&&\"next\"!==n.direction?!1:e!==n.currentSlide||m?n.vars.animationLoop?!0:n.atEnd&&0===n.currentSlide&&e===a&&\"next\"!==n.direction?!1:n.atEnd&&n.currentSlide===a&&0===e&&\"next\"===n.direction?!1:!0:!1},n.getTarget=function(e){return n.direction=e,\"next\"===e?n.currentSlide===n.last?0:n.currentSlide+1:0===n.currentSlide?n.last:n.currentSlide-1},n.setProps=function(e,t,a){var i=function(){var a=e?e:(n.itemW+n.vars.itemMargin)*n.move*n.animatingTo,i=function(){if(v)return\"setTouch\"===t?e:u&&n.animatingTo===n.last?0:u?n.limit-(n.itemW+n.vars.itemMargin)*n.move*n.animatingTo:n.animatingTo===n.last?n.limit:a;switch(t){case\"setTotal\":return u?(n.count-1-n.currentSlide+n.cloneOffset)*e:(n.currentSlide+n.cloneOffset)*e;case\"setTouch\":return u?e:e;case\"jumpEnd\":return u?e:n.count*e;case\"jumpStart\":return u?n.count*e:e;default:return e}}();return-1*i+\"px\"}();n.transitions&&(i=d?\"translate3d(0,\"+i+\",0)\":\"translate3d(\"+i+\",0,0)\",a=void 0!==a?a/1e3+\"s\":\"0s\",n.container.css(\"-\"+n.pfx+\"-transition-duration\",a),n.container.css(\"transition-duration\",a)),n.args[n.prop]=i,(n.transitions||void 0===a)&&n.container.css(n.args),n.container.css(\"transform\",i)},n.setup=function(e){if(p)n.slides.css({width:\"100%\",\"float\":\"left\",marginRight:\"-100%\",position:\"relative\"}),\"init\"===e&&(r?n.slides.css({opacity:0,display:\"block\",webkitTransition:\"opacity \"+n.vars.animationSpeed/1e3+\"s ease\",zIndex:1}).eq(n.currentSlide).css({opacity:1,zIndex:2}):0==n.vars.fadeFirstSlide?n.slides.css({opacity:0,display:\"block\",zIndex:1}).eq(n.currentSlide).css({zIndex:2}).css({opacity:1}):n.slides.css({opacity:0,display:\"block\",zIndex:1}).eq(n.currentSlide).css({zIndex:2}).animate({opacity:1},n.vars.animationSpeed,n.vars.easing)),n.vars.smoothHeight&&f.smoothHeight();else{var t,a;\"init\"===e&&(n.viewport=$('<div class=\"'+i+'viewport\"></div>').css({overflow:\"hidden\",position:\"relative\"}).appendTo(n).append(n.container),n.cloneCount=0,n.cloneOffset=0,u&&(a=$.makeArray(n.slides).reverse(),n.slides=$(a),n.container.empty().append(n.slides))),n.vars.animationLoop&&!v&&(n.cloneCount=2,n.cloneOffset=1,\"init\"!==e&&n.container.find(\".clone\").remove(),n.container.append(f.uniqueID(n.slides.first().clone().addClass(\"clone\")).attr(\"aria-hidden\",\"true\")).prepend(f.uniqueID(n.slides.last().clone().addClass(\"clone\")).attr(\"aria-hidden\",\"true\"))),n.newSlides=$(n.vars.selector,n),t=u?n.count-1-n.currentSlide+n.cloneOffset:n.currentSlide+n.cloneOffset,d&&!v?(n.container.height(200*(n.count+n.cloneCount)+\"%\").css(\"position\",\"absolute\").width(\"100%\"),setTimeout(function(){n.newSlides.css({display:\"block\"}),n.doMath(),n.viewport.height(n.h),n.setProps(t*n.h,\"init\")},\"init\"===e?100:0)):(n.container.width(200*(n.count+n.cloneCount)+\"%\"),n.setProps(t*n.computedW,\"init\"),setTimeout(function(){n.doMath(),n.newSlides.css({width:n.computedW,marginRight:n.computedM,\"float\":\"left\",display:\"block\"}),n.vars.smoothHeight&&f.smoothHeight()},\"init\"===e?100:0))}v||n.slides.removeClass(i+\"active-slide\").eq(n.currentSlide).addClass(i+\"active-slide\"),n.vars.init(n)},n.doMath=function(){var e=n.slides.first(),t=n.vars.itemMargin,a=n.vars.minItems,i=n.vars.maxItems;n.w=void 0===n.viewport?n.width():n.viewport.width(),n.h=e.height(),n.boxPadding=e.outerWidth()-e.width(),v?(n.itemT=n.vars.itemWidth+t,n.itemM=t,n.minW=a?a*n.itemT:n.w,n.maxW=i?i*n.itemT-t:n.w,n.itemW=n.minW>n.w?(n.w-t*(a-1))/a:n.maxW<n.w?(n.w-t*(i-1))/i:n.vars.itemWidth>n.w?n.w:n.vars.itemWidth,n.visible=Math.floor(n.w/n.itemW),n.move=n.vars.move>0&&n.vars.move<n.visible?n.vars.move:n.visible,n.pagingCount=Math.ceil((n.count-n.visible)/n.move+1),n.last=n.pagingCount-1,n.limit=1===n.pagingCount?0:n.vars.itemWidth>n.w?n.itemW*(n.count-1)+t*(n.count-1):(n.itemW+t)*n.count-n.w-t):(n.itemW=n.w,n.itemM=t,n.pagingCount=n.count,n.last=n.count-1),n.computedW=n.itemW-n.boxPadding,n.computedM=n.itemM},n.update=function(e,t){n.doMath(),v||(e<n.currentSlide?n.currentSlide+=1:e<=n.currentSlide&&0!==e&&(n.currentSlide-=1),n.animatingTo=n.currentSlide),n.vars.controlNav&&!n.manualControls&&(\"add\"===t&&!v||n.pagingCount>n.controlNav.length?f.controlNav.update(\"add\"):(\"remove\"===t&&!v||n.pagingCount<n.controlNav.length)&&(v&&n.currentSlide>n.last&&(n.currentSlide-=1,n.animatingTo-=1),f.controlNav.update(\"remove\",n.last))),n.vars.directionNav&&f.directionNav.update()},n.addSlide=function(e,t){var a=$(e);n.count+=1,n.last=n.count-1,d&&u?void 0!==t?n.slides.eq(n.count-t).after(a):n.container.prepend(a):void 0!==t?n.slides.eq(t).before(a):n.container.append(a),n.update(t,\"add\"),n.slides=$(n.vars.selector+\":not(.clone)\",n),n.setup(),n.vars.added(n)},n.removeSlide=function(e){var t=isNaN(e)?n.slides.index($(e)):e;n.count-=1,n.last=n.count-1,isNaN(e)?$(e,n.slides).remove():d&&u?n.slides.eq(n.last).remove():n.slides.eq(e).remove(),n.doMath(),n.update(t,\"remove\"),n.slides=$(n.vars.selector+\":not(.clone)\",n),n.setup(),n.vars.removed(n)},f.init()},$(window).blur(function(t){e=!1}).focus(function(t){e=!0}),$.flexslider.defaults={namespace:\"flex-\",selector:\".slides > li\",animation:\"fade\",easing:\"swing\",direction:\"horizontal\",reverse:!1,animationLoop:!0,smoothHeight:!1,startAt:0,slideshow:!0,slideshowSpeed:7e3,animationSpeed:600,initDelay:0,randomize:!1,fadeFirstSlide:!0,thumbCaptions:!1,pauseOnAction:!0,pauseOnHover:!1,pauseInvisible:!0,useCSS:!0,touch:!0,video:!1,controlNav:!0,directionNav:!0,prevText:\"Previous\",nextText:\"Next\",keyboard:!0,multipleKeyboard:!1,mousewheel:!1,pausePlay:!1,pauseText:\"Pause\",playText:\"Play\",controlsContainer:\"\",manualControls:\"\",customDirectionNav:\"\",sync:\"\",asNavFor:\"\",itemWidth:0,itemMargin:0,minItems:1,maxItems:0,move:0,allowOneSlide:!0,start:function(){},before:function(){},after:function(){},end:function(){},added:function(){},removed:function(){},init:function(){}},$.fn.flexslider=function(e){if(void 0===e&&(e={}),\"object\"==typeof e)return this.each(function(){var t=$(this),a=e.selector?e.selector:\".slides > li\",n=t.find(a);1===n.length&&e.allowOneSlide===!1||0===n.length?(n.fadeIn(400),e.start&&e.start(t)):void 0===t.data(\"flexslider\")&&new $.flexslider(this,e)});var t=$(this).data(\"flexslider\");switch(e){case\"play\":t.play();break;case\"pause\":t.pause();break;case\"stop\":t.stop();break;case\"next\":t.flexAnimate(t.getTarget(\"next\"),!0);break;case\"prev\":case\"previous\":t.flexAnimate(t.getTarget(\"prev\"),!0);break;default:\"number\"==typeof e&&t.flexAnimate(e,!0)}}}(jQuery);"
  },
  {
    "path": "app_frontend/static/theme/default/plugins/FlexSlider/jquery.flexslider.css",
    "content": "/* jQuery FlexSlider v2.2.0 | Copyright 2012 WooThemes | Tyler Smith (@mbmufffin) */\r\nbody { /* Browser Resets */ /* FlexSlider Necessary Styles */ /* Clearfix for the .slides element */ /* No JavaScript Fallback */ /* FlexSlider Default Theme */ /* Direction Nav */ /* Control Nav */ }\r\nbody .flex-container a:active, body .flexslider a:active, body .flex-container a:focus, body .flexslider a:focus { outline: none; }\r\nbody .slides, body .flex-control-nav, body .flex-direction-nav { margin: 0; padding: 0; list-style: none; }\r\nbody .flexslider { margin: 0; padding: 0; }\r\nbody .flexslider .slides > li { display: none; /* -webkit-backface-visibility: hidden; */ }\r\nbody .flexslider .slides img { width: 100%; height: auto; display: block; }\r\nbody .flex-pauseplay span { text-transform: capitalize; }\r\nbody .slides:after { content: \"\\0020\"; display: block; clear: both; visibility: hidden; line-height: 0; height: 0; }\r\nbody html[xmlns] .slides { display: block; }\r\nbody * html .slides { height: 1%; }\r\nbody .no-js .slides > li:first-child { display: block; }\r\nbody .flexslider { margin: 0 0 15px; background: #fff; position: relative; zoom: 1; }\r\nbody .flex-viewport { max-height: 2000px; -webkit-transition: all 1s ease; -moz-transition: all 1s ease; -o-transition: all 1s ease; transition: all 1s ease; }\r\nbody .loading .flex-viewport { max-height: 300px; }\r\nbody .flexslider .slides { zoom: 1; }\r\nbody .carousel li { margin-right: 5px; }\r\nbody .flex-direction-nav { *height: 0; }\r\nbody .flex-direction-nav a { display: block; width: 40px; height: 40px; background: none; text-indent: 0; border-bottom: none !important; margin: -20px 0 0; position: absolute; top: 50%; z-index: 10; overflow: hidden; opacity: 0; cursor: pointer; color: rgba(0, 0, 0, 0.8); text-shadow: 1px 1px 0 rgba(255, 255, 255, 0.3); -webkit-transition: all .3s ease; -moz-transition: all .3s ease; transition: all .3s ease; }\r\nbody .flex-direction-nav .flex-prev { left: -50px; }\r\nbody .flex-direction-nav .flex-next { right: -50px; }\r\nbody .flexslider:hover .flex-prev { opacity: 0.7; left: 10px; }\r\nbody .flexslider:hover .flex-next { opacity: 0.7; right: 10px; }\r\nbody .flexslider:hover .flex-next:hover, body .flexslider:hover .flex-prev:hover { opacity: 1; }\r\nbody .flex-direction-nav .flex-disabled { opacity: 0 !important; filter: alpha(opacity=0); cursor: default; }\r\nbody .flex-direction-nav a:before { font-size: 38px; line-height: 40px; display: inline-block; }\r\nbody .flex-control-nav { width: 100%; position: absolute; bottom: -40px; text-align: center; }\r\nbody .flex-control-nav li { margin: 0 6px; display: inline-block; zoom: 1; *display: inline; }\r\nbody .flex-control-paging li a { width: 12px; height: 12px; display: block; background: #666; background: rgba(0, 0, 0, 0.5); cursor: pointer; text-indent: -9999px; -webkit-border-radius: 12px; -moz-border-radius: 12px; -o-border-radius: 12px; border-radius: 12px; }\r\nbody .flex-control-paging li a:hover { background: #333; background: rgba(0, 0, 0, 0.7); }\r\nbody .flex-control-paging li a.flex-active { background: #000; background: rgba(0, 0, 0, 0.9); cursor: default; }\r\nbody .flex-control-thumbs { margin: 5px 0 0; position: static; overflow: hidden; }\r\nbody .flex-control-thumbs li { width: 20%; float: left; margin: 0; }\r\nbody .flex-control-thumbs img { width: 100%; display: block; opacity: .5; cursor: pointer; }\r\nbody .flex-control-thumbs img:hover { opacity: 1; }\r\nbody .flex-control-thumbs .flex-active { opacity: 1; cursor: default; }\r\n@media screen and (max-width: 860px) { body .flex-direction-nav .flex-prev { opacity: 1; left: 10px; }\r\n  body .flex-direction-nav .flex-next { opacity: 1; right: 10px; } }\r\n"
  },
  {
    "path": "app_frontend/static/theme/default/plugins/owl-carousel/owl.carousel.css",
    "content": "/* \r\n * \tCore Owl Carousel CSS File\r\n *\tv1.24\r\n */\r\n\r\n/* clearfix */\r\n.owl-carousel .owl-wrapper:after {\r\n\tcontent: \".\";\r\n\tdisplay: block;\r\n\tclear: both;\r\n\tvisibility: hidden;\r\n\tline-height: 0;\r\n\theight: 0;\r\n}\r\n/* display none until init */\r\n.owl-carousel{\r\n\tdisplay: none;\r\n\tposition: relative;\r\n\twidth: 100%;\r\n\t-ms-touch-action: pan-y;\r\n}\r\n.owl-carousel .owl-wrapper{\r\n\tdisplay: none;\r\n\tposition: relative;\r\n\t-webkit-transform: translate3d(0px, 0px, 0px);\r\n}\r\n.owl-carousel .owl-wrapper-outer{\r\n\toverflow: hidden;\r\n\tposition: relative;\r\n\twidth: 100%;\r\n}\r\n.owl-carousel .owl-wrapper-outer.autoHeight{\r\n\t-webkit-transition: height 500ms ease-in-out;\r\n\t-moz-transition: height 500ms ease-in-out;\r\n\t-ms-transition: height 500ms ease-in-out;\r\n\t-o-transition: height 500ms ease-in-out;\r\n\ttransition: height 500ms ease-in-out;\r\n}\r\n\t\r\n.owl-carousel .owl-item{\r\n\tfloat: left;\r\n}\r\n.owl-controls .owl-page,\r\n.owl-controls .owl-buttons div{\r\n\tcursor: pointer;\r\n}\r\n.owl-controls {\r\n\t-webkit-user-select: none;\r\n\t-khtml-user-select: none;\r\n\t-moz-user-select: none;\r\n\t-ms-user-select: none;\r\n\tuser-select: none;\r\n\t-webkit-tap-highlight-color: rgba(0, 0, 0, 0);\r\n}\r\n\r\n/* mouse grab icon */\r\n.grabbing { \r\n    cursor:url(grabbing.png) 8 8, move;\r\n}\r\n\r\n/* fix */\r\n.owl-carousel  .owl-wrapper,\r\n.owl-carousel  .owl-item{\r\n\t-webkit-backface-visibility: hidden;\r\n\t-moz-backface-visibility:    hidden;\r\n\t-ms-backface-visibility:     hidden;\r\n  -webkit-transform: translate3d(0,0,0);\r\n  -moz-transform: translate3d(0,0,0);\r\n  -ms-transform: translate3d(0,0,0);\r\n}\r\n\r\n/* CSS3 Transitions */\r\n\r\n.owl-origin {\r\n\t-webkit-perspective: 1200px;\r\n\t-webkit-perspective-origin-x : 50%;\r\n\t-webkit-perspective-origin-y : 50%;\r\n\t-moz-perspective : 1200px;\r\n\t-moz-perspective-origin-x : 50%;\r\n\t-moz-perspective-origin-y : 50%;\r\n\tperspective : 1200px;\r\n}\r\n/* fade */\r\n.owl-fade-out {\r\n  z-index: 10;\r\n  -webkit-animation: fadeOut .7s both ease;\r\n  -moz-animation: fadeOut .7s both ease;\r\n  animation: fadeOut .7s both ease;\r\n}\r\n.owl-fade-in {\r\n  -webkit-animation: fadeIn .7s both ease;\r\n  -moz-animation: fadeIn .7s both ease;\r\n  animation: fadeIn .7s both ease;\r\n}\r\n/* backSlide */\r\n.owl-backSlide-out {\r\n  -webkit-animation: backSlideOut 1s both ease;\r\n  -moz-animation: backSlideOut 1s both ease;\r\n  animation: backSlideOut 1s both ease;\r\n}\r\n.owl-backSlide-in {\r\n  -webkit-animation: backSlideIn 1s both ease;\r\n  -moz-animation: backSlideIn 1s both ease;\r\n  animation: backSlideIn 1s both ease;\r\n}\r\n/* goDown */\r\n.owl-goDown-out {\r\n  -webkit-animation: scaleToFade .7s ease both;\r\n  -moz-animation: scaleToFade .7s ease both;\r\n  animation: scaleToFade .7s ease both;\r\n}\r\n.owl-goDown-in {\r\n  -webkit-animation: goDown .6s ease both;\r\n  -moz-animation: goDown .6s ease both;\r\n  animation: goDown .6s ease both;\r\n}\r\n/* scaleUp */\r\n.owl-fadeUp-in {\r\n  -webkit-animation: scaleUpFrom .5s ease both;\r\n  -moz-animation: scaleUpFrom .5s ease both;\r\n  animation: scaleUpFrom .5s ease both;\r\n}\r\n\r\n.owl-fadeUp-out {\r\n  -webkit-animation: scaleUpTo .5s ease both;\r\n  -moz-animation: scaleUpTo .5s ease both;\r\n  animation: scaleUpTo .5s ease both;\r\n}\r\n/* Keyframes */\r\n/*empty*/\r\n@-webkit-keyframes empty {\r\n  0% {opacity: 1}\r\n}\r\n@-moz-keyframes empty {\r\n  0% {opacity: 1}\r\n}\r\n@keyframes empty {\r\n  0% {opacity: 1}\r\n}\r\n@-webkit-keyframes fadeIn {\r\n  0% { opacity:0; }\r\n  100% { opacity:1; }\r\n}\r\n@-moz-keyframes fadeIn {\r\n  0% { opacity:0; }\r\n  100% { opacity:1; }\r\n}\r\n@keyframes fadeIn {\r\n  0% { opacity:0; }\r\n  100% { opacity:1; }\r\n}\r\n@-webkit-keyframes fadeOut {\r\n  0% { opacity:1; }\r\n  100% { opacity:0; }\r\n}\r\n@-moz-keyframes fadeOut {\r\n  0% { opacity:1; }\r\n  100% { opacity:0; }\r\n}\r\n@keyframes fadeOut {\r\n  0% { opacity:1; }\r\n  100% { opacity:0; }\r\n}\r\n@-webkit-keyframes backSlideOut {\r\n  25% { opacity: .5; -webkit-transform: translateZ(-500px); }\r\n  75% { opacity: .5; -webkit-transform: translateZ(-500px) translateX(-200%); }\r\n  100% { opacity: .5; -webkit-transform: translateZ(-500px) translateX(-200%); }\r\n}\r\n@-moz-keyframes backSlideOut {\r\n  25% { opacity: .5; -moz-transform: translateZ(-500px); }\r\n  75% { opacity: .5; -moz-transform: translateZ(-500px) translateX(-200%); }\r\n  100% { opacity: .5; -moz-transform: translateZ(-500px) translateX(-200%); }\r\n}\r\n@keyframes backSlideOut {\r\n  25% { opacity: .5; transform: translateZ(-500px); }\r\n  75% { opacity: .5; transform: translateZ(-500px) translateX(-200%); }\r\n  100% { opacity: .5; transform: translateZ(-500px) translateX(-200%); }\r\n}\r\n@-webkit-keyframes backSlideIn {\r\n  0%, 25% { opacity: .5; -webkit-transform: translateZ(-500px) translateX(200%); }\r\n  75% { opacity: .5; -webkit-transform: translateZ(-500px); }\r\n  100% { opacity: 1; -webkit-transform: translateZ(0) translateX(0); }\r\n}\r\n@-moz-keyframes backSlideIn {\r\n  0%, 25% { opacity: .5; -moz-transform: translateZ(-500px) translateX(200%); }\r\n  75% { opacity: .5; -moz-transform: translateZ(-500px); }\r\n  100% { opacity: 1; -moz-transform: translateZ(0) translateX(0); }\r\n}\r\n@keyframes backSlideIn {\r\n  0%, 25% { opacity: .5; transform: translateZ(-500px) translateX(200%); }\r\n  75% { opacity: .5; transform: translateZ(-500px); }\r\n  100% { opacity: 1; transform: translateZ(0) translateX(0); }\r\n}\r\n@-webkit-keyframes scaleToFade {\r\n  to { opacity: 0; -webkit-transform: scale(.8); }\r\n}\r\n@-moz-keyframes scaleToFade {\r\n  to { opacity: 0; -moz-transform: scale(.8); }\r\n}\r\n@keyframes scaleToFade {\r\n  to { opacity: 0; transform: scale(.8); }\r\n}\r\n@-webkit-keyframes goDown {\r\n  from { -webkit-transform: translateY(-100%); }\r\n}\r\n@-moz-keyframes goDown {\r\n  from { -moz-transform: translateY(-100%); }\r\n}\r\n@keyframes goDown {\r\n  from { transform: translateY(-100%); }\r\n}\r\n\r\n@-webkit-keyframes scaleUpFrom {\r\n  from { opacity: 0; -webkit-transform: scale(1.5); }\r\n}\r\n@-moz-keyframes scaleUpFrom {\r\n  from { opacity: 0; -moz-transform: scale(1.5); }\r\n}\r\n@keyframes scaleUpFrom {\r\n  from { opacity: 0; transform: scale(1.5); }\r\n}\r\n\r\n@-webkit-keyframes scaleUpTo {\r\n  to { opacity: 0; -webkit-transform: scale(1.5); }\r\n}\r\n@-moz-keyframes scaleUpTo {\r\n  to { opacity: 0; -moz-transform: scale(1.5); }\r\n}\r\n@keyframes scaleUpTo {\r\n  to { opacity: 0; transform: scale(1.5); }\r\n}\r\n"
  },
  {
    "path": "app_frontend/static/theme/default/plugins/owl-carousel/owl.theme.css",
    "content": "/*\r\n* \tOwl Carousel Owl Demo Theme \r\n*\tv1.24\r\n*/\r\n\r\n.owl-theme .owl-controls{\r\n\tmargin-top: 10px;\r\n\ttext-align: center;\r\n}\r\n\r\n/* Styling Next and Prev buttons */\r\n\r\n.owl-theme .owl-controls .owl-buttons div{\r\n\tcolor: #FFF;\r\n\tdisplay: inline-block;\r\n\tzoom: 1;\r\n\t*display: inline;/*IE7 life-saver */\r\n\tmargin: 5px;\r\n\tpadding: 3px 10px;\r\n\tfont-size: 12px;\r\n\t-webkit-border-radius: 30px;\r\n\t-moz-border-radius: 30px;\r\n\tborder-radius: 30px;\r\n\tbackground: #869791;\r\n\tfilter: Alpha(Opacity=50);/*IE7 fix*/\r\n\topacity: 0.5;\r\n}\r\n/* Clickable class fix problem with hover on touch devices */\r\n/* Use it for non-touch hover action */\r\n.owl-theme .owl-controls.clickable .owl-buttons div:hover{\r\n\tfilter: Alpha(Opacity=100);/*IE7 fix*/\r\n\topacity: 1;\r\n\ttext-decoration: none;\r\n}\r\n\r\n/* Styling Pagination*/\r\n\r\n.owl-theme .owl-controls .owl-page{\r\n\tdisplay: inline-block;\r\n\tzoom: 1;\r\n\t*display: inline;/*IE7 life-saver */\r\n}\r\n.owl-theme .owl-controls .owl-page span{\r\n\tdisplay: block;\r\n\twidth: 12px;\r\n\theight: 12px;\r\n\tmargin: 5px 7px;\r\n\tfilter: Alpha(Opacity=50);/*IE7 fix*/\r\n\topacity: 0.5;\r\n\t-webkit-border-radius: 20px;\r\n\t-moz-border-radius: 20px;\r\n\tborder-radius: 20px;\r\n\tbackground: #869791;\r\n}\r\n\r\n.owl-theme .owl-controls .owl-page.active span,\r\n.owl-theme .owl-controls.clickable .owl-page:hover span{\r\n\tfilter: Alpha(Opacity=100);/*IE7 fix*/\r\n\topacity: 1;\r\n}\r\n\r\n/* If PaginationNumbers is true */\r\n\r\n.owl-theme .owl-controls .owl-page span.owl-numbers{\r\n\theight: auto;\r\n\twidth: auto;\r\n\tcolor: #FFF;\r\n\tpadding: 2px 10px;\r\n\tfont-size: 12px;\r\n\t-webkit-border-radius: 30px;\r\n\t-moz-border-radius: 30px;\r\n\tborder-radius: 30px;\r\n}\r\n\r\n/* preloading images */\r\n.owl-item.loading{\r\n\tmin-height: 150px;\r\n\tbackground: url(AjaxLoader.gif) no-repeat center center\r\n}\r\n"
  },
  {
    "path": "app_frontend/static/uploads/index.html",
    "content": ""
  },
  {
    "path": "app_frontend/tasks/README.md",
    "content": "## 短信\n\n### 用户注册，短信验证\n\n### 订单流转，短信通知\n\n### 订单支付，短信通知\n\n### 订单确认超时，系统自动确认（处理已支付未确认且超过48小时的订单）\n\n\n## 封号\n\n### 注册后未激活，系统自动封号（注册超过3天）\n注册事件：{'user_id': 0, 'reg_time': '1900-01-01 00:00:00'}\n队列性质：延时队列\n队列名称：lock_reg_not_active\n\n### 激活后未投资，系统自动封号（激活超过3天）\n注册事件：{'user_id': 0, 'active_time': '1900-01-01 00:00:00'}\n队列性质：延时队列\n队列名称：lock_active_not_put\n\n### 匹配后未支付，系统系统封号（非流转的匹配超过48小时）\n注册事件：{'user_id': 0, 'order_time': '1900-01-01 00:00:00'}\n队列性质：延时队列\n队列名称：lock_order_not_pay\n\n### 匹配后未支付，系统系统封号（经流转的匹配超过24小时）\n注册事件：{'user_id': 0, 'order_time': '1900-01-01 00:00:00'}\n队列性质：延时队列\n队列名称：lock_order_not_pay\n\n### 收款后未确认，系统系统封号（收款超过48小时）\n注册事件：{'user_id': 0, 'pay_time': '1900-01-01 00:00:00'}\n队列性质：延时队列\n队列名称：lock_pay_not_rec\n"
  },
  {
    "path": "app_frontend/tasks/__init__.py",
    "content": "#!/usr/bin/env python\n# encoding: utf-8\n\n\"\"\"\n@author: zhanghe\n@software: PyCharm\n@file: __init__.py.py\n@time: 2017/3/10 下午10:43\n\"\"\"\n\n\nfrom app_frontend.celery_worker import celery_app\n\n\n@celery_app.task\ndef add(x, y):\n    return x + y\n\n\n@celery_app.task\ndef mul(x, y):\n    return x * y\n\n\n@celery_app.task\ndef xsum(numbers):\n    return sum(numbers)\n"
  },
  {
    "path": "app_frontend/tasks/cron_send_sms.py",
    "content": "#!/usr/bin/env python\n# encoding: utf-8\n\n\"\"\"\n@author: zhanghe\n@software: PyCharm\n@file: cron_send_sms.py\n@time: 2017/4/5 下午8:59\n\"\"\"\n\n\nimport schedule\nimport time\nimport traceback\nimport sys\n\n\nfrom app_frontend.tools.send_sms import get_server_tunnel, run_send_sms\n\n\ndef schedule_send_sms():\n    \"\"\"\n    短信发送调度器 - 循环调度、定时调度\n    :return:\n    \"\"\"\n    try:\n        run_send_sms()\n\n        schedule.every(60).seconds.do(lambda: run_send_sms())\n\n        while True:\n            schedule.run_pending()\n            time.sleep(1)\n    except KeyboardInterrupt:\n        print 'Stop Schedule'\n    except Exception as e:\n        print e.message\n        traceback.print_exc()\n\n\ndef schedule_send_sms_ssh_tunnel():\n    \"\"\"\n    短信发送调度器(隧道连接) - 循环调度、定时调度\n    :return:\n    \"\"\"\n    server = get_server_tunnel()\n    server.start()  # start ssh sever\n    print 'Server connected via SSH'\n    try:\n        run_send_sms(server)\n\n        schedule.every(60).seconds.do(lambda: run_send_sms(server))\n\n        while True:\n            schedule.run_pending()\n            time.sleep(1)\n    except KeyboardInterrupt:\n        print 'Stop Schedule'\n    except Exception as e:\n        print e.message\n        traceback.print_exc()\n    finally:\n        server.close()  # stop ssh sever\n        print 'Server disconnected via SSH'\n\n\ndef run_schedule():\n    \"\"\"\n    调度器入口\n    :return:\n    \"\"\"\n    print sys.argv\n    if sys.argv.pop() == 'ssh_tunnel':\n        schedule_send_sms_ssh_tunnel()\n    else:\n        schedule_send_sms()\n\n\nif __name__ == '__main__':\n    run_schedule()\n"
  },
  {
    "path": "app_frontend/tasks/run_apply_put_interest_on_principal.py",
    "content": "#!/usr/bin/env python\n# encoding: utf-8\n\n\"\"\"\n@author: zhanghe\n@software: PyCharm\n@file: run_apply_put_interest_on_principal.py\n@time: 2017/5/22 下午3:10\n\"\"\"\n\n\nimport json\nimport time\nimport traceback\nfrom datetime import datetime\nfrom decimal import Decimal\n\nfrom app_common.maps.status_audit import *\nfrom app_common.maps.type_payment import *\nfrom app_common.maps.status_delete import *\nfrom app_common.maps.status_flow import *\nfrom app_common.maps.status_rec import *\nfrom app_common.maps.status_order import *\n\nfrom app_frontend.lib.rabbit_mq import RabbitDelayQueue\n\nfrom app_frontend.api.bonus import get_bonus_row_by_id, add_bonus, edit_bonus\nfrom app_frontend.api.bonus_item import add_bonus_item\nfrom app_frontend.api.user_config import get_user_config_row_by_id\nfrom app_frontend.api.user_profile import get_p_uid_list\nfrom app_frontend.api.wallet import get_wallet_row_by_id, add_wallet, edit_wallet\nfrom app_frontend.api.wallet_item import add_wallet_item\nfrom app_frontend.api.apply_put import get_apply_put_row_by_id\n\nfrom app_frontend.api.score_charity import increase_score_charity\nfrom app_frontend.api.score_charity_item import add_score_charity_item\n\nfrom app_frontend.api.score_digital import increase_score_digital\nfrom app_frontend.api.score_digital_item import add_score_digital_item\n\nfrom app_frontend.api.score_expense import increase_score_expense\nfrom app_frontend.api.score_expense_item import add_score_expense_item\n\nfrom app_frontend.api.apply_put import is_put\nfrom app_frontend.api.user import lock\nfrom app_frontend.api.order import get_order_lists\nfrom app_frontend import app\nfrom app_frontend.tools.config_manage import get_conf\nfrom app_frontend.tools.exception import DropException\n\nEXCHANGE_NAME = app.config['EXCHANGE_NAME']\nAPPLY_PUT_INTEREST_ON_PRINCIPAL_TTL = app.config['APPLY_PUT_INTEREST_ON_PRINCIPAL_TTL']\n\n\nINTEREST_PUT = Decimal(get_conf('INTEREST_PUT'))               # 投资利息（日息）\n\nINTEREST_PAY_AHEAD = Decimal(get_conf('INTEREST_PAY_AHEAD'))   # 提前支付奖金比例\nINTEREST_PAY_DELAY = Decimal(get_conf('INTEREST_PAY_DELAY'))   # 延迟支付罚金比例\n\nDIFF_TIME_PAY_AHEAD = int(get_conf('DIFF_TIME_PAY_AHEAD'))   # 提前支付奖金时间差\nDIFF_TIME_PAY_DELAY = int(get_conf('DIFF_TIME_PAY_DELAY'))   # 延迟支付罚金时间差\n\nINTEREST_REC_AHEAD = Decimal(get_conf('INTEREST_REC_AHEAD'))   # 提前确认奖金比例\nINTEREST_REC_DELAY = Decimal(get_conf('INTEREST_REC_DELAY'))   # 延迟确认罚金比例\n\nDIFF_TIME_REC_AHEAD = int(get_conf('DIFF_TIME_REC_AHEAD'))   # 提前支付奖金时间差\nDIFF_TIME_REC_DELAY = int(get_conf('DIFF_TIME_REC_DELAY'))   # 延迟支付罚金时间差\n\nBONUS_DIRECT = Decimal(get_conf('BONUS_DIRECT'))     # 直接推荐奖励\n\nBONUS_LEVEL_FIRST = Decimal(get_conf('BONUS_LEVEL_FIRST'))     # 一级推荐奖励\nBONUS_LEVEL_SECOND = Decimal(get_conf('BONUS_LEVEL_SECOND'))     # 二级推荐奖励\nBONUS_LEVEL_THIRD = Decimal(get_conf('BONUS_LEVEL_THIRD'))     # 三级推荐奖励\nBONUS_LEVEL = [BONUS_LEVEL_FIRST, BONUS_LEVEL_SECOND, BONUS_LEVEL_THIRD]     # 奖金等级\n\n\ndef _on_score(user_id, apply_put_id, interest, current_time):\n    \"\"\"\n    处理积分\n    :param user_id:\n    :param apply_put_id:\n    :param interest:\n    :param current_time:\n    :return:\n    \"\"\"\n    # 1、慈善积分（3%）\n    score_charity_amount = interest * Decimal('0.03')\n    app.logger.info('score_charity_amount: +%s' % score_charity_amount)\n    # 插入积分明细\n    score_charity_item_data = {\n        'user_id': user_id,\n        'type': TYPE_PAYMENT_INCOME,\n        'amount': score_charity_amount,\n        'sc_id': apply_put_id,\n        'note': '来自排单收益',\n        'status_audit': STATUS_AUDIT_SUCCESS,\n        'audit_time': current_time,\n        'create_time': current_time,\n        'update_time': current_time\n    }\n    add_score_charity_item(score_charity_item_data)\n    # 更新积分总表\n    current_score_charity_amount = increase_score_charity(user_id, score_charity_amount)\n    app.logger.info('current_score_charity_amount: %s' % current_score_charity_amount)\n\n    # 2、数字积分（7%）\n    score_digital_amount = interest * Decimal('0.07')\n    app.logger.info('score_digital_amount: +%s' % score_digital_amount)\n    # 插入积分明细\n    score_digital_item_data = {\n        'user_id': user_id,\n        'type': TYPE_PAYMENT_INCOME,\n        'amount': score_digital_amount,\n        'sc_id': apply_put_id,\n        'note': '来自排单收益',\n        'status_audit': STATUS_AUDIT_SUCCESS,\n        'audit_time': current_time,\n        'create_time': current_time,\n        'update_time': current_time\n    }\n    add_score_digital_item(score_digital_item_data)\n    # 更新积分总表\n    current_score_digital_amount = increase_score_digital(user_id, score_digital_amount)\n    app.logger.info('current_score_digital_amount: %s' % current_score_digital_amount)\n\n    # 3、消费积分（10%）\n    score_expense_amount = interest * Decimal('0.1')\n    app.logger.info('score_expense_amount: +%s' % score_expense_amount)\n    # 插入积分明细\n    score_expense_item_data = {\n        'user_id': user_id,\n        'type': TYPE_PAYMENT_INCOME,\n        'amount': score_expense_amount,\n        'sc_id': apply_put_id,\n        'note': '来自排单收益',\n        'status_audit': STATUS_AUDIT_SUCCESS,\n        'audit_time': current_time,\n        'create_time': current_time,\n        'update_time': current_time\n    }\n    add_score_expense_item(score_expense_item_data)\n    # 更新积分总表\n    current_score_expense_amount = increase_score_expense(user_id, score_expense_amount)\n    app.logger.info('current_score_expense_amount: %s' % current_score_expense_amount)\n\n\ndef _on_wallet(user_id, apply_put_id, principal_interest, current_time):\n    \"\"\"\n    处理钱包\n    :param user_id:\n    :param apply_put_id:\n    :param principal_interest:\n    :param current_time:\n    :return:\n    \"\"\"\n    # 添加钱包明细\n    wallet_item_data = {\n        'user_id': user_id,\n        'type': TYPE_PAYMENT_INCOME,\n        'sc_id': apply_put_id,\n        'note': '来自排单收益',\n        'amount': principal_interest,\n        'status_audit': STATUS_AUDIT_SUCCESS,\n        'audit_time': current_time,\n        'create_time': current_time,\n        'update_time': current_time\n    }\n    add_wallet_item(wallet_item_data)\n\n    wallet_info = get_wallet_row_by_id(user_id)\n    # 新增钱包记录，更新钱包余额\n    if not wallet_info:\n        app.logger.info('wallet_amount: 0')\n        wallet_data = {\n            'user_id': user_id,\n            'amount_initial': 0,\n            'amount_current': principal_interest,\n            'amount_lock': 0,\n            'create_time': current_time,\n            'update_time': current_time,\n        }\n        add_wallet(wallet_data)\n    # 更新钱包余额\n    else:\n        app.logger.info('wallet_amount: %s' % wallet_info.amount_current)\n        wallet_data = {\n            'user_id': user_id,\n            'amount_current': wallet_info.amount_current + principal_interest,\n            'update_time': current_time,\n        }\n        edit_wallet(user_id, wallet_data)\n    wallet_info = get_wallet_row_by_id(user_id)\n    current_wallet_amount = wallet_info.amount_current if wallet_info else 0\n    app.logger.info('current_wallet_amount: %s' % current_wallet_amount)\n\n\ndef _on_bonus(user_id, apply_put_id, interest, current_time):\n    \"\"\"\n    处理奖金\n    :param user_id:\n    :param apply_put_id:\n    :param interest:\n    :param current_time:\n    :return:\n    \"\"\"\n    p_uid_list = get_p_uid_list(user_id)\n    c = 0\n    for uid, bonus_rate in zip(p_uid_list, BONUS_LEVEL):\n        # 获取用户团队奖励优先级配置\n        user_config_row = get_user_config_row_by_id(uid)\n        bonus_user_config = [Decimal(i) for i in user_config_row.team_bonus.split(',')] if user_config_row else []\n        bonus_rate = bonus_user_config[c] if len(bonus_user_config) >= 3 else bonus_rate\n\n        # 计算上级推广奖金\n        bonus = interest * bonus_rate\n        # 添加奖金明细\n        bonus_item_data = {\n            'user_id': uid,\n            'type': TYPE_PAYMENT_INCOME,\n            'sc_id': apply_put_id,\n            'amount': bonus,\n            'status_audit': STATUS_AUDIT_SUCCESS,\n            'audit_time': current_time,\n            'create_time': current_time,\n            'update_time': current_time\n        }\n        add_bonus_item(bonus_item_data)\n\n        bonus_info = get_bonus_row_by_id(uid)\n        # 新增奖金记录，更新奖金余额\n        if not bonus_info:\n            app.logger.info('p_uid: %s, bonus_amount: %s, bonus_rate: %s' % (uid, 0, bonus_rate))\n            bonus_data = {\n                'user_id': uid,\n                'amount': bonus,\n                'create_time': current_time,\n                'update_time': current_time,\n            }\n            add_bonus(bonus_data)\n        # 更新奖金余额\n        else:\n            app.logger.info('p_uid: %s, bonus_amount: %s, bonus_rate: %s' % (uid, bonus_info.amount, bonus_rate))\n            bonus_data = {\n                'amount': bonus_info.amount + bonus,\n                'update_time': current_time,\n            }\n            edit_bonus(uid, bonus_data)\n        bonus_info = get_bonus_row_by_id(uid)\n        current_bonus_amount = bonus_info.amount if bonus_info else 0\n        app.logger.info('p_uid: %s, current_bonus_amount: %s' % (uid, current_bonus_amount))\n        c += 1\n\n\ndef on_apply_put_interest_on_principal(ch, method, properties, body):\n    \"\"\"\n    回调处理 - 投资申请本息回收\n    :return:\n    \"\"\"\n    try:\n        print \" [x]  %s Get %r\" % (time.strftime('%Y-%m-%d %H:%M:%S'), body,)\n        msg = json.loads(body)\n        user_id = msg['user_id']\n        apply_put_id = msg['apply_put_id']\n\n        # 判断排单状态\n        apply_put_info = get_apply_put_row_by_id(apply_put_id)\n        if not apply_put_info or apply_put_info.status_order != int(STATUS_ORDER_COMPLETED):\n            raise DropException('Drop apply_put_interest_on_principal uid:%s, apply_put_id: %s' % (user_id, apply_put_id))\n\n        # 获取申请投资排单的所有匹配订单\n        order_rows = get_order_lists(**{'apply_put_id': apply_put_id})\n        for order_info in order_rows:\n            # 检查订单, 只处理收款确认成功的订单\n            if not order_info or order_info.status_rec != int(STATUS_REC_SUCCESS):\n                continue\n            current_time = datetime.utcnow()\n\n            # 计算投资用户利息\n            interest = order_info.money * INTEREST_PUT * 15  # 默认计息日 15 天\n\n            # 处理积分 收益 20% 进入积分钱包（慈善3 数字7 消费10）\n            _on_score(user_id, apply_put_id, interest, current_time)\n\n            # 处理钱包 扣除积分之后的本息和加入钱包\n            principal_interest = order_info.money + interest * Decimal('0.8')\n            _on_wallet(user_id, apply_put_id, principal_interest, current_time)\n\n            # 处理奖金 计算投资方上级推广利息（三级）\n            _on_bonus(user_id, apply_put_id, interest, current_time)\n\n        ch.basic_ack(delivery_tag=method.delivery_tag)\n    except DropException:\n        # 消息丢弃\n        print traceback.print_exc()\n        ch.basic_ack(delivery_tag=method.delivery_tag)\n    except Exception as e:\n        print traceback.print_exc()\n        raise e\n\n\ndef run():\n    q = RabbitDelayQueue(\n        exchange=EXCHANGE_NAME,\n        queue_name='apply_put_interest_on_principal',\n        ttl=APPLY_PUT_INTEREST_ON_PRINCIPAL_TTL\n    )\n    q.consume(on_apply_put_interest_on_principal)\n\n\ndef test_put():\n    \"\"\"\n    测试数据推入队列\n    触发条件：投资成功申请\n    :return:\n    \"\"\"\n    q = RabbitDelayQueue(\n        exchange=EXCHANGE_NAME,\n        queue_name='apply_put_interest_on_principal',\n        ttl=APPLY_PUT_INTEREST_ON_PRINCIPAL_TTL\n    )\n    msg = {\n        'user_id': 0,\n        'apply_put_id': 0,\n        'apply_time': time.strftime('%Y-%m-%d %H:%M:%S')\n    }\n    q.put(msg)\n    q.close_conn()\n\n\ndef test_callback():\n    \"\"\"\n    测试回调\n    :return:\n    \"\"\"\n    user_id = 15\n    apply_put_id = 10\n\n    # 获取申请投资排单的所有匹配订单\n    order_rows = get_order_lists(**{'apply_put_id': apply_put_id})\n    print order_rows\n    for order_info in order_rows:\n        # 检查订单, 只处理收款确认成功的订单\n        if not order_info or order_info.status_rec != int(STATUS_REC_SUCCESS):\n            continue\n        current_time = datetime.utcnow()\n\n        # 计算投资用户利息\n        interest = order_info.money * INTEREST_PUT * 15  # 默认计息日 15 天\n        app.logger.info('interest: %s' % interest)\n\n        # 处理积分 收益 20% 进入积分钱包（慈善3 数字7 消费10）\n        _on_score(user_id, apply_put_id, interest, current_time)\n\n        # 处理钱包 扣除积分之后的本息和加入钱包\n        principal_interest = order_info.money + interest * Decimal('0.8')\n        _on_wallet(user_id, apply_put_id, principal_interest, current_time)\n\n        # 处理奖金 计算投资方上级推广利息（三级）\n        _on_bonus(user_id, apply_put_id, interest, current_time)\n\n\nif __name__ == '__main__':\n    run()\n    # test_put()\n    # test_callback()\n"
  },
  {
    "path": "app_frontend/tasks/run_lock_active_not_put.py",
    "content": "#!/usr/bin/env python\n# encoding: utf-8\n\n\"\"\"\n@author: zhanghe\n@software: PyCharm\n@file: run_lock_active_not_put.py\n@time: 2017/5/17 上午8:58\n\"\"\"\n\n\nimport json\nimport time\nimport traceback\n\n\nfrom app_frontend.lib.rabbit_mq import RabbitDelayQueue\n\nfrom app_frontend.api.apply_put import is_put\nfrom app_frontend.api.user import lock\nfrom app_frontend import app\nEXCHANGE_NAME = app.config['EXCHANGE_NAME']\nLOCK_ACTIVE_NOT_PUT_TTL = app.config['LOCK_ACTIVE_NOT_PUT_TTL']\n\n\ndef on_lock_active_not_put(ch, method, properties, body):\n    \"\"\"\n    回调处理 - 封号\n    :return:\n    \"\"\"\n    try:\n        print \" [x]  %s Get %r\" % (time.strftime('%Y-%m-%d %H:%M:%S'), body,)\n        msg = json.loads(body)\n        user_id = msg['user_id']\n        # 检查是否投资\n        if not is_put(user_id):\n            lock(user_id)\n        ch.basic_ack(delivery_tag=method.delivery_tag)\n    except Exception as e:\n        print traceback.print_exc()\n        raise e\n\n\ndef run():\n    q = RabbitDelayQueue(\n        exchange=EXCHANGE_NAME,\n        queue_name='lock_active_not_put',\n        ttl=LOCK_ACTIVE_NOT_PUT_TTL\n    )\n    q.consume(on_lock_active_not_put)\n\n\ndef test_put():\n    \"\"\"\n    测试数据推入队列\n    触发条件：用户成功激活\n    :return:\n    \"\"\"\n    q = RabbitDelayQueue(\n        exchange=EXCHANGE_NAME,\n        queue_name='lock_active_not_put',\n        ttl=LOCK_ACTIVE_NOT_PUT_TTL\n    )\n    q.put({'user_id': 0, 'active_time': time.strftime('%Y-%m-%d %H:%M:%S')})\n\n\nif __name__ == '__main__':\n    run()\n    # test_put()\n\n"
  },
  {
    "path": "app_frontend/tasks/run_lock_order_not_pay.py",
    "content": "#!/usr/bin/env python\n# encoding: utf-8\n\n\"\"\"\n@author: zhanghe\n@software: PyCharm\n@file: run_lock_order_not_pay.py\n@time: 2017/5/17 上午9:00\n\"\"\"\n\n\nimport json\nimport time\nimport traceback\n\n\nfrom app_frontend.lib.rabbit_mq import RabbitDelayQueue\n\nfrom app_frontend.api.order import get_order_row\nfrom app_frontend.api.user import lock\nfrom app_common.maps.status_pay import *\nfrom app_common.maps.status_audit import *\nfrom app_common.maps.status_delete import *\nfrom app_frontend import app\n\nEXCHANGE_NAME = app.config['EXCHANGE_NAME']\nLOCK_ORDER_NOT_PAY_TTL = app.config['LOCK_ORDER_NOT_PAY_TTL']\n\n\ndef on_lock_order_not_pay(ch, method, properties, body):\n    \"\"\"\n    回调处理 - 封号\n    :return:\n    \"\"\"\n    try:\n        print \" [x]  %s Get %r\" % (time.strftime('%Y-%m-%d %H:%M:%S'), body,)\n        msg = json.loads(body)\n        user_id = msg['user_id']\n        order_id = msg['order_id']\n        order_create_time = msg['order_create_time']\n\n        condition = {\n            'id': order_id,\n            'apply_put_uid': user_id,\n            'status_audit': int(STATUS_AUDIT_SUCCESS),\n            'status_delete': int(STATUS_DEL_NO)\n        }\n        order_info = get_order_row(**condition)\n        if order_info and order_info.status_pay != int(STATUS_PAY_SUCCESS):\n            # 订单审核通过，逾期未付款，封号\n            lock(user_id)\n\n        ch.basic_ack(delivery_tag=method.delivery_tag)\n    except Exception as e:\n        print traceback.print_exc()\n        raise e\n\n\ndef run():\n    q = RabbitDelayQueue(exchange=EXCHANGE_NAME, queue_name='lock_order_not_pay', ttl=LOCK_ORDER_NOT_PAY_TTL)\n    q.consume(on_lock_order_not_pay)\n\n\ndef test_put():\n    \"\"\"\n    测试数据推入队列\n    触发条件：订单成功创建\n    :return:\n    \"\"\"\n    q = RabbitDelayQueue(\n        exchange=EXCHANGE_NAME,\n        queue_name='lock_order_not_pay',\n        ttl=LOCK_ORDER_NOT_PAY_TTL\n    )\n    msg = {\n        'user_id': 0,\n        'order_id': 0,\n        'order_create_time': time.strftime('%Y-%m-%d %H:%M:%S')\n    }\n    q.put(msg)\n    q.close_conn()\n\n\nif __name__ == '__main__':\n    run()\n    # test_put()\n\n"
  },
  {
    "path": "app_frontend/tasks/run_lock_pay_not_rec.py",
    "content": "#!/usr/bin/env python\n# encoding: utf-8\n\n\"\"\"\n@author: zhanghe\n@software: PyCharm\n@file: run_lock_pay_not_rec.py\n@time: 2017/5/17 上午9:02\n\"\"\"\n\n\nimport json\nimport time\nimport traceback\n\n\nfrom app_frontend.lib.rabbit_mq import RabbitDelayQueue\n\nfrom app_frontend.api.order import get_order_row\nfrom app_frontend.api.user import lock\nfrom app_common.maps.status_pay import *\nfrom app_common.maps.status_rec import *\nfrom app_common.maps.status_audit import *\nfrom app_common.maps.status_delete import *\nfrom app_frontend import app\n\nEXCHANGE_NAME = app.config['EXCHANGE_NAME']\nLOCK_PAY_NOT_REC_TTL = app.config['LOCK_PAY_NOT_REC_TTL']\n\n\ndef on_lock_pay_not_rec(ch, method, properties, body):\n    \"\"\"\n    回调处理 - 封号\n    :return:\n    \"\"\"\n    try:\n        print \" [x]  %s Get %r\" % (time.strftime('%Y-%m-%d %H:%M:%S'), body,)\n        msg = json.loads(body)\n        user_id = msg['user_id']\n        order_id = msg['order_id']\n\n        condition = {\n            'id': order_id,\n            'apply_get_uid': user_id,\n            'status_pay': int(STATUS_PAY_SUCCESS),\n            'status_audit': int(STATUS_AUDIT_SUCCESS),\n            'status_delete': int(STATUS_DEL_NO)\n        }\n        order_info = get_order_row(**condition)\n        if order_info and order_info.status_rec != int(STATUS_REC_SUCCESS):\n            # 支付成功，未确认收款，封号\n            lock(user_id)\n        ch.basic_ack(delivery_tag=method.delivery_tag)\n    except Exception as e:\n        print traceback.print_exc()\n        raise e\n\n\ndef run():\n    q = RabbitDelayQueue(exchange=EXCHANGE_NAME, queue_name='lock_pay_not_rec', ttl=LOCK_PAY_NOT_REC_TTL)\n    q.consume(on_lock_pay_not_rec)\n\n\ndef test_put():\n    \"\"\"\n    测试数据推入队列\n    触发条件：订单成功支付\n    :return:\n    \"\"\"\n    q = RabbitDelayQueue(\n        exchange=EXCHANGE_NAME,\n        queue_name='lock_pay_not_rec',\n        ttl=LOCK_PAY_NOT_REC_TTL\n    )\n    msg = {\n        'user_id': 0,\n        'order_id': 0,\n        'pay_time': time.strftime('%Y-%m-%d %H:%M:%S')\n    }\n    q.put(msg)\n    q.close_conn()\n\n\nif __name__ == '__main__':\n    run()\n    # test_put()\n\n\n"
  },
  {
    "path": "app_frontend/tasks/run_lock_reg_not_active.py",
    "content": "#!/usr/bin/env python\n# encoding: utf-8\n\n\"\"\"\n@author: zhanghe\n@software: PyCharm\n@file: run_lock_reg_not_active.py\n@time: 2017/5/12 上午11:07\n\"\"\"\n\n\nimport json\nimport time\nimport traceback\n\n\nfrom app_frontend.lib.rabbit_mq import RabbitDelayQueue\n\nfrom app_frontend.api.user import lock, is_active, get_user_row_by_id\nfrom app_common.maps.status_active import *\nfrom app_frontend import app\n\nfrom app_frontend.tools.exception import DropException\n\n\nEXCHANGE_NAME = app.config['EXCHANGE_NAME']\nLOCK_REG_NOT_ACTIVE_TTL = app.config['LOCK_REG_NOT_ACTIVE_TTL']\n\n\ndef on_lock_reg_not_active(ch, method, properties, body):\n    \"\"\"\n    回调处理 - 封号\n    :return:\n    \"\"\"\n    try:\n        print \" [x]  %s Get %r\" % (time.strftime('%Y-%m-%d %H:%M:%S'), body,)\n        msg = json.loads(body)\n        user_id = msg['user_id']\n        # 检查用户是否存在\n        if not get_user_row_by_id(user_id):\n            raise DropException(u'用户[user_id: %s]不存在' % user_id)\n        # 检查是否激活\n        if is_active(user_id) == int(STATUS_ACTIVE_NO):\n            lock(user_id)\n        ch.basic_ack(delivery_tag=method.delivery_tag)\n    except DropException:\n        print traceback.print_exc()\n        ch.basic_ack(delivery_tag=method.delivery_tag)\n    except Exception as e:\n        print traceback.print_exc()\n        raise e\n\n\ndef run():\n    q = RabbitDelayQueue(\n        exchange=EXCHANGE_NAME,\n        queue_name='lock_reg_not_active',\n        ttl=LOCK_REG_NOT_ACTIVE_TTL\n    )\n    q.consume(on_lock_reg_not_active)\n\n\ndef test_put():\n    \"\"\"\n    测试数据推入队列\n    触发条件：用户成功注册\n    :return:\n    \"\"\"\n    q = RabbitDelayQueue(\n        exchange=EXCHANGE_NAME,\n        queue_name='lock_reg_not_active',\n        ttl=LOCK_REG_NOT_ACTIVE_TTL\n    )\n    msg = {\n        'user_id': 0,\n        'reg_time': time.strftime('%Y-%m-%d %H:%M:%S')\n    }\n    q.put(msg)\n    q.close_conn()\n\n\nif __name__ == '__main__':\n    run()\n    # test_put()\n"
  },
  {
    "path": "app_frontend/tasks/run_send_sms.py",
    "content": "#!/usr/bin/env python\n# encoding: utf-8\n\n\"\"\"\n@author: zhanghe\n@software: PyCharm\n@file: run_send_sms.py\n@time: 2017/5/12 上午11:07\n\"\"\"\n\n\nimport json\nimport traceback\n\nfrom app_frontend.lib.rabbit_mq import RabbitQueue\nfrom app_frontend import sms_client\nfrom app_frontend import app\nEXCHANGE_NAME = app.config['EXCHANGE_NAME']\n\n\ndef on_send_sms(ch, method, properties, body):\n    \"\"\"\n    回调处理 - 发送短信  一般是非验证码短信，通知类的信息\n    :return:\n    \"\"\"\n    try:\n        print \" [x]  Get %r\" % (body,)\n        msg = json.loads(body)\n        mobile = msg['mobile']\n        sms_content = msg['sms_content']\n\n        result = sms_client.send_international(mobile, sms_content)\n        print result\n        # 发送成功\n        if result.get('success'):\n            print u'发送成功 mobile:%s, content: %s' % (mobile, sms_content)\n        # 发送失败\n        else:\n            print u'发送失败 mobile:%s, content: %s' % (mobile, sms_content)\n        ch.basic_ack(delivery_tag=method.delivery_tag)\n    except Exception as e:\n        print traceback.print_exc()\n        raise e\n\n\ndef run():\n    q = RabbitQueue(exchange=EXCHANGE_NAME, queue_name='send_sms')\n    q.consume(on_send_sms)\n\n\ndef test_put():\n    \"\"\"\n    测试数据推入队列\n    :return:\n    \"\"\"\n    q = RabbitQueue(exchange=EXCHANGE_NAME, queue_name='send_sms')\n    q.put({'mobile': '8613800001111', 'sms_content': '1111'})\n\n\nif __name__ == '__main__':\n    run()\n    # test_put()\n"
  },
  {
    "path": "app_frontend/tasks/run_send_sms_priority.py",
    "content": "#!/usr/bin/env python\n# encoding: utf-8\n\n\"\"\"\n@author: zhanghe\n@software: PyCharm\n@file: run_send_sms_priority.py\n@time: 2017/5/12 上午11:07\n\"\"\"\n\n\nimport json\nimport traceback\n\nfrom app_frontend.lib.rabbit_mq import RabbitPriorityQueue\nfrom app_frontend import sms_client\nfrom app_frontend import app\nEXCHANGE_NAME = app.config['EXCHANGE_NAME']\n\n\ndef on_send_sms_priority(ch, method, properties, body):\n    \"\"\"\n    回调处理 - 发送短信(带优先级) 一般是带验证码短信，时效性要求高\n    :return:\n    \"\"\"\n    try:\n        print \" [x]  Get %r\" % (body,)\n        msg = json.loads(body)\n        mobile = msg['mobile']\n        sms_content = msg['sms_content']\n\n        result = sms_client.send_international(mobile, sms_content)\n        print result\n        # 发送成功\n        if result.get('success'):\n            print u'发送成功 mobile:%s, content: %s' % (mobile, sms_content)\n        # 发送失败\n        else:\n            print u'发送失败 mobile:%s, content: %s' % (mobile, sms_content)\n        ch.basic_ack(delivery_tag=method.delivery_tag)\n    except Exception as e:\n        print traceback.print_exc()\n        raise e\n\n\ndef run():\n    q = RabbitPriorityQueue(exchange=EXCHANGE_NAME, queue_name='send_sms_p')\n    q.consume(on_send_sms_priority)\n\n\ndef test_put():\n    \"\"\"\n    测试数据推入队列\n    因为消费进程没有延时，所以先执行推送，再开启消费，能看到优先级效果\n    :return:\n    \"\"\"\n    q = RabbitPriorityQueue(exchange=EXCHANGE_NAME, queue_name='send_sms_p')\n    q.put({'mobile': '8613800001111', 'sms_content': '1111'}, 20)\n    q.put({'mobile': '8613800002222', 'sms_content': '2222'}, 30)\n    q.put({'mobile': '8613800003333', 'sms_content': '3333'}, 10)\n\n\nif __name__ == '__main__':\n    run()\n    # test_put()\n"
  },
  {
    "path": "app_frontend/templates/404.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n    <meta charset=\"UTF-8\">\n    <title>404</title>\n</head>\n<body>\n\n</body>\n</html>"
  },
  {
    "path": "app_frontend/templates/500.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n    <meta charset=\"UTF-8\">\n    <title>500</title>\n</head>\n<body>\n\n</body>\n</html>"
  },
  {
    "path": "app_frontend/templates/_footer.html",
    "content": "<nav class=\"text-center panel-footer navbar-fixed-bottom\">\n{#    <div class=\"container\">#}\n    {{ \"项目名称\" | project_name }} &copy; 2017 All Rights Reserved.<br/>{{ \"沪ICP备12024750号\" | icp_code }}\n{#    </div>#}\n</nav>\n<!-- Top Link -->\n<span id=\"top-link-block\" class=\"hidden\">\n    <a href=\"\" class=\"well-sm\" id=\"top-link\">\n        <i class=\"glyphicon glyphicon-plane center-block\"></i>\n    </a>\n    <a href=\"\" class=\"well-sm\" id=\"top-link\">\n        <i class=\"glyphicon glyphicon-qrcode center-block\"></i>\n    </a>\n</span>\n"
  },
  {
    "path": "app_frontend/templates/_top.html",
    "content": "    <nav class=\"navbar navbar-default navbar-fixed-top\">\n        <div class=\"container\">\n            <div class=\"navbar-header\">\n                <button type=\"button\" class=\"navbar-toggle collapsed\" data-toggle=\"collapse\" data-target=\"#navbar\"\n                        aria-expanded=\"false\">\n                    <span class=\"sr-only\">Toggle navigation</span>\n                    <span class=\"icon-bar\"></span>\n                    <span class=\"icon-bar\"></span>\n                    <span class=\"icon-bar\"></span>\n                </button>\n                <span class=\"navbar-brand\" href=\"{{ url_for('index') }}\">{{ \"项目名称\" | project_name }}</span>\n            </div>\n            <div id=\"navbar\" class=\"navbar-collapse collapse\">\n                <ul class=\"nav navbar-nav\">\n                    <li{% if request.path == url_for('index') %} class=\"active\"{% endif %}><a href=\"{{ url_for('index') }}\"><span\n                            class=\"glyphicon glyphicon-home\"></span> 首页</a></li>\n{#                    <li{% if request.path == url_for('about') %} class=\"active\"{% endif %}><a href=\"{{ url_for('about') }}\"><span#}\n{#                            class=\"glyphicon glyphicon-list\"></span> 关于我们</a></li>#}\n{#                    <li{% if request.path == url_for('contact') %} class=\"active\"{% endif %}><a href=\"{{ url_for('contact') }}\"><span#}\n{#                            class=\"glyphicon glyphicon-envelope\"></span> 联系我们</a></li>#}\n                {% if current_user and current_user.is_authenticated %}\n                    <li class=\"dropdown{% if 'put' in request.path %} active{% endif %}\">\n                        <a href=\"#\" class=\"dropdown-toggle\" data-toggle=\"dropdown\" role=\"button\" aria-haspopup=\"true\"\n                           aria-expanded=\"false\"><span class=\"glyphicon glyphicon-paste\"></span> 投资中心 <span\n                                class=\"caret\"></span></a>\n                        <ul class=\"dropdown-menu\">\n                        {% if request.path == url_for('order.lists_put') %}\n                            <li class=\"dropdown-header\"><span class=\"glyphicon glyphicon-list-alt\"></span> 投资订单</li>\n                        {% else %}\n                            <li><a href=\"{{ url_for('order.lists_put') }}\"><span class=\"glyphicon glyphicon-list-alt\"></span> 投资订单</a></li>\n                        {% endif %}\n                        {% if request.path == url_for('apply.lists_put') %}\n                            <li class=\"dropdown-header\"><span class=\"glyphicon glyphicon-th-list\"></span> 申请记录</li>\n                        {% else %}\n                            <li><a href=\"{{ url_for('apply.lists_put') }}\"><span class=\"glyphicon glyphicon-th-list\"></span> 申请记录</a></li>\n                        {% endif %}\n                        {% if request.path == url_for('apply.add_put') %}\n                            <li class=\"dropdown-header\"><span class=\"glyphicon glyphicon-plus\"></span> 我要投资</li>\n                        {% else %}\n                            <li><a href=\"{{ url_for('apply.add_put') }}\"><span class=\"glyphicon glyphicon-plus\"></span> 我要投资</a></li>\n                        {% endif %}\n                        </ul>\n                    </li>\n                    <li class=\"dropdown{% if 'get' in request.path %} active{% endif %}\">\n                        <a href=\"#\" class=\"dropdown-toggle\" data-toggle=\"dropdown\" role=\"button\" aria-haspopup=\"true\"\n                           aria-expanded=\"false\"><span class=\"glyphicon glyphicon-copy\"></span> 提现中心 <span\n                                class=\"caret\"></span></a>\n                        <ul class=\"dropdown-menu\">\n                        {% if request.path == url_for('order.lists_get') %}\n                            <li class=\"dropdown-header\"><span class=\"glyphicon glyphicon-list-alt\"></span> 提现订单</li>\n                        {% else %}\n                            <li><a href=\"{{ url_for('order.lists_get') }}\"><span class=\"glyphicon glyphicon-list-alt\"></span> 提现订单</a></li>\n                        {% endif %}\n                        {% if request.path == url_for('apply.lists_get') %}\n                            <li class=\"dropdown-header\"><span class=\"glyphicon glyphicon-th-list\"></span> 申请记录</li>\n                        {% else %}\n                            <li><a href=\"{{ url_for('apply.lists_get') }}\"><span class=\"glyphicon glyphicon-th-list\"></span> 申请记录</a></li>\n                        {% endif %}\n                        {% if request.path == url_for('apply.add_get') %}\n                            <li class=\"dropdown-header\"><span class=\"glyphicon glyphicon-plus\"></span> 我要提现</li>\n                        {% else %}\n                            <li><a href=\"{{ url_for('apply.add_get') }}\"><span class=\"glyphicon glyphicon-plus\"></span> 我要提现</a></li>\n                        {% endif %}\n                        </ul>\n                    </li>\n                    <li class=\"dropdown{% if 'active' in request.path %} active{% endif %}\">\n                        <a href=\"#\" class=\"dropdown-toggle\" data-toggle=\"dropdown\" role=\"button\" aria-haspopup=\"true\"\n                           aria-expanded=\"false\"><span class=\"glyphicon glyphicon-flag\"></span> 激活中心 <span\n                                class=\"caret\"></span></a>\n                        <ul class=\"dropdown-menu\">\n                        {% if request.path == url_for('active.lists') %}\n                            <li class=\"dropdown-header\"><span class=\"glyphicon glyphicon-list-alt\"></span> 激活记录</li>\n                        {% else %}\n                            <li><a href=\"{{ url_for('active.lists') }}\"><span class=\"glyphicon glyphicon-list-alt\"></span> 激活记录</a></li>\n                        {% endif %}\n                        {% if request.path == url_for('active.add') %}\n                            <li class=\"dropdown-header\"><span class=\"glyphicon glyphicon-plus\"></span> 赠送激活</li>\n                        {% else %}\n                            <li><a href=\"{{ url_for('active.add') }}\"><span class=\"glyphicon glyphicon-plus\"></span> 赠送激活</a></li>\n                        {% endif %}\n                        </ul>\n                    </li>\n                    <li class=\"dropdown{% if 'score' in request.path %} active{% endif %}\">\n                        <a href=\"#\" class=\"dropdown-toggle\" data-toggle=\"dropdown\" role=\"button\" aria-haspopup=\"true\"\n                           aria-expanded=\"false\"><span class=\"glyphicon glyphicon-shopping-cart\"></span> 积分中心 <span\n                                class=\"caret\"></span></a>\n                        <ul class=\"dropdown-menu\">\n                        {% if request.path == url_for('score.charity_lists') %}\n                            <li class=\"dropdown-header\"><span class=\"glyphicon glyphicon-list-alt\"></span> 慈善积分</li>\n                        {% else %}\n                            <li><a href=\"{{ url_for('score.charity_lists') }}\"><span class=\"glyphicon glyphicon-list-alt\"></span> 慈善积分</a></li>\n                        {% endif %}\n                        {% if request.path == url_for('score.digital_lists') %}\n                            <li class=\"dropdown-header\"><span class=\"glyphicon glyphicon-list-alt\"></span> 数字积分</li>\n                        {% else %}\n                            <li><a href=\"{{ url_for('score.digital_lists') }}\"><span class=\"glyphicon glyphicon-list-alt\"></span> 数字积分</a></li>\n                        {% endif %}\n                        {% if request.path == url_for('score.expense_lists') %}\n                            <li class=\"dropdown-header\"><span class=\"glyphicon glyphicon-list-alt\"></span> 消费积分</li>\n                        {% else %}\n                            <li><a href=\"{{ url_for('score.expense_lists') }}\"><span class=\"glyphicon glyphicon-list-alt\"></span> 消费积分</a></li>\n                        {% endif %}\n                        </ul>\n                    </li>\n                {% endif %}\n                </ul>\n                {% if 1 == 2 %}\n                <form class=\"navbar-form navbar-left\" role=\"search\" action=\"{{ url_for('search') }}\">\n                    <div class=\"input-group\">\n                        <input type=\"text\" class=\"form-control\" placeholder=\"Search for...\" speech x-webkit-speech\n                               onwebkitspeechchange=\"$(this).cloest('form').submit()\">\n                        <span class=\"input-group-btn\">\n                            <button class=\"btn btn-default\" type=\"submit\"><span class=\"glyphicon glyphicon-search\"></span></button>\n                        </span>\n                    </div>\n                </form>\n                {% endif %}\n                <ul class=\"nav navbar-nav navbar-right\">\n                {% if current_user and current_user.is_authenticated %}\n                    <li class=\"dropdown\">\n                        <a href=\"#\" class=\"dropdown-toggle\" data-toggle=\"dropdown\" role=\"button\" aria-haspopup=\"true\" aria-expanded=\"false\">\n                            <span class=\"glyphicon glyphicon-envelope\"></span> 消息中心\n                            <span class=\"caret\"></span>\n                        </a>\n                        <ul class=\"dropdown-menu\">\n                            <li>\n                                <a href=\"{{ url_for('message.lists') }}\">\n                                    <span class=\"glyphicon glyphicon-folder-open\"></span> 留言记录\n                                </a>\n                            </li>\n                            <li role=\"separator\" class=\"divider\"></li>\n                            <li>\n                                <a href=\"{{ url_for('complaint.lists') }}\">\n                                    <span class=\"glyphicon glyphicon-book\"></span> 投诉记录\n                                </a>\n                            </li>\n                        </ul>\n                    </li>\n                {% endif %}\n                {% if current_user and current_user.is_authenticated %}\n                    <li class=\"dropdown{% if 'user' in request.path %} active{% endif %}\">\n                        <a href=\"#\" class=\"dropdown-toggle\" data-toggle=\"dropdown\" role=\"button\"\n                           aria-haspopup=\"true\"\n                           aria-expanded=\"false\"><span\n                                class=\"glyphicon glyphicon-user\"></span> {{ current_user.id | user_name_level }}<span\n                                class=\"caret\"></span></a>\n                        <ul class=\"dropdown-menu\">\n                            <li{% if request.path == url_for('user.profile') %} class=\"active\"{% endif %}>\n                                <a href=\"{{ url_for('user.profile') }}\">\n                                    <span class=\"glyphicon glyphicon-folder-open\"></span> 用户中心\n                                </a>\n                            </li>\n                            <li{% if request.path == url_for('user.team') %} class=\"active\"{% endif %}>\n                                <a href=\"{{ url_for('user.team') }}\">\n                                    <span class=\"glyphicon glyphicon-king\"></span> 我的团队\n                                </a>\n                            </li>\n                            <li{% if request.path == url_for('scheduling.lists') %} class=\"active\"{% endif %}>\n                                <a href=\"{{ url_for('scheduling.lists') }}\">\n                                    <span class=\"glyphicon glyphicon-list-alt\"></span> 排单明细\n                                </a>\n                            </li>\n{#                            <li><a href=\"{{ url_for('user.setting') }}\"><span class=\"glyphicon glyphicon-cog\"></span>#}\n{#                                Setting</a></li>#}\n                            <li role=\"separator\" class=\"divider\"></li>\n                            <li>\n                                <a href=\"{{ url_for('auth.logout') }}\">\n                                    <span class=\"glyphicon glyphicon-log-out\"></span> 退出登录\n                                </a>\n                            </li>\n                        </ul>\n                    </li>\n                {% else %}\n                    <li{% if title == 'reg' %} class=\"active\"{% endif %}><a href=\"{{ url_for('reg.index') }}\"><span\n                            class=\"glyphicon glyphicon-list-alt\"></span> 注册</a></li>\n                    <li{% if title == 'login' %} class=\"active\"{% endif %}><a href=\"{{ url_for('auth.index') }}\"><span\n                            class=\"glyphicon glyphicon-log-in\"></span> 登录</a></li>\n                {% endif %}\n                </ul>\n            </div><!--/.nav-collapse -->\n        </div>\n    </nav>"
  },
  {
    "path": "app_frontend/templates/about.html",
    "content": "{% extends \"layout.html\" %}\n\n{% block extra_css %}\n    <!-- LightBox -->\n    <link href=\"{{ url_for('static', filename='css/lightbox.min.css') }}\" rel=\"stylesheet\">\n{% endblock %}\n\n{% block content %}\n    <div class=\"container\">\n        <h2>about me!</h2>\n        <div class=\"row text-center\">\n            <div class=\"col-xs-6 col-md-3\">\n                <a href=\"{{ url_for('static', filename='img/cat.jpg') }}\" data-lightbox=\"img-set\" data-title=\"Big Image\">\n                    <img class=\"img-thumbnail\" src=\"{{ url_for('static', filename='img/cat.jpg') }}\">\n                </a>\n                <div class=\"caption\">\n                    <h3>Thumbnail label</h3>\n                    <p>Cras justo odio, dapibus ac facilisis in, egestas eget quam.</p>\n                    <p>\n                        <a href=\"#\" class=\"btn btn-primary\" role=\"button\">Button</a>\n                        <a href=\"#\" class=\"btn btn-default\" role=\"button\">Button</a>\n                    </p>\n                </div>\n            </div>\n            <div class=\"col-xs-6 col-md-3\">\n                <a href=\"{{ url_for('static', filename='img/cat.jpg') }}\" data-lightbox=\"img-set\" data-title=\"Big Image\">\n                    <img class=\"img-thumbnail\" src=\"{{ url_for('static', filename='img/cat.jpg') }}\">\n                </a>\n                <div class=\"caption\">\n                    <h3>Thumbnail label</h3>\n                    <p>Cras justo odio, dapibus ac facilisis in, egestas eget quam.</p>\n                    <p>\n                        <a href=\"#\" class=\"btn btn-primary\" role=\"button\">Button</a>\n                        <a href=\"#\" class=\"btn btn-default\" role=\"button\">Button</a>\n                    </p>\n                </div>\n            </div>\n            <div class=\"col-xs-6 col-md-3\">\n                <a href=\"{{ url_for('static', filename='img/cat.jpg') }}\" data-lightbox=\"img-set\" data-title=\"Big Image\">\n                    <img class=\"img-thumbnail\" src=\"{{ url_for('static', filename='img/cat.jpg') }}\">\n                </a>\n                <div class=\"caption\">\n                    <h3>Thumbnail label</h3>\n                    <p>Cras justo odio, dapibus ac facilisis in, egestas eget quam.</p>\n                    <p>\n                        <a href=\"#\" class=\"btn btn-primary\" role=\"button\">Button</a>\n                        <a href=\"#\" class=\"btn btn-default\" role=\"button\">Button</a>\n                    </p>\n                </div>\n            </div>\n            <div class=\"col-xs-6 col-md-3\">\n                <a href=\"{{ url_for('static', filename='img/cat.jpg') }}\" data-lightbox=\"img-set\" data-title=\"Big Image\">\n                    <img class=\"img-thumbnail\" src=\"{{ url_for('static', filename='img/cat.jpg') }}\">\n                </a>\n                <div class=\"caption\">\n                    <h3>Thumbnail label</h3>\n                    <p>Cras justo odio, dapibus ac facilisis in, egestas eget quam.</p>\n                    <p>\n                        <a href=\"#\" class=\"btn btn-primary\" role=\"button\">Button</a>\n                        <a href=\"#\" class=\"btn btn-default\" role=\"button\">Button</a>\n                    </p>\n                </div>\n            </div>\n        </div>\n    </div>\n{% endblock %}\n\n{% block extra_js %}\n    <!-- LightBox -->\n    <script src=\"{{ url_for('static', filename='plugin/Lightbox/lightbox.min.js') }}\"></script>\n    <script>\n        lightbox.option({\n            'alwaysShowNavOnTouchDevices': true,\n            'albumLabel': \"Image %1 of %2\",\n            'resizeDuration': 200,\n            'wrapAround': true\n        })\n    </script>\n{% endblock %}\n"
  },
  {
    "path": "app_frontend/templates/about_bak.html",
    "content": "{% extends \"layout.html\" %}\n\n{% block content %}\n    <div class=\"container\">\n        <h2>about me!</h2>\n        <div class=\"row text-center\">\n            <div class=\"col-xs-6 col-md-3\">\n                <a href=\"\" data-toggle=\"modal\" data-target=\"#img_modal\">\n                    <img class=\"img-thumbnail\" src=\"{{ url_for('static', filename='img/cat.jpg') }}\">\n                </a>\n                <div class=\"caption\">\n                    <h3>Thumbnail label</h3>\n                    <p>Cras justo odio, dapibus ac facilisis in, egestas eget quam.</p>\n                    <p>\n                        <a href=\"#\" class=\"btn btn-primary\" role=\"button\">Button</a>\n                        <a href=\"#\" class=\"btn btn-default\" role=\"button\">Button</a>\n                    </p>\n                </div>\n            </div>\n            <div class=\"col-xs-6 col-md-3\">\n                <a href=\"\" data-toggle=\"modal\" data-target=\"#img_modal\">\n                    <img class=\"img-thumbnail\" src=\"{{ url_for('static', filename='img/cat.jpg') }}\">\n                </a>\n                <div class=\"caption\">\n                    <h3>Thumbnail label</h3>\n                    <p>Cras justo odio, dapibus ac facilisis in, egestas eget quam.</p>\n                    <p>\n                        <a href=\"#\" class=\"btn btn-primary\" role=\"button\">Button</a>\n                        <a href=\"#\" class=\"btn btn-default\" role=\"button\">Button</a>\n                    </p>\n                </div>\n            </div>\n            <div class=\"col-xs-6 col-md-3\">\n                <a href=\"\" data-toggle=\"modal\" data-target=\"#img_modal\">\n                    <img class=\"img-thumbnail\" src=\"{{ url_for('static', filename='img/cat.jpg') }}\">\n                </a>\n                <div class=\"caption\">\n                    <h3>Thumbnail label</h3>\n                    <p>Cras justo odio, dapibus ac facilisis in, egestas eget quam.</p>\n                    <p>\n                        <a href=\"#\" class=\"btn btn-primary\" role=\"button\">Button</a>\n                        <a href=\"#\" class=\"btn btn-default\" role=\"button\">Button</a>\n                    </p>\n                </div>\n            </div>\n            <div class=\"col-xs-6 col-md-3\">\n                <a href=\"\" data-toggle=\"modal\" data-target=\"#img_modal\">\n                    <img class=\"img-thumbnail\" src=\"{{ url_for('static', filename='img/cat.jpg') }}\">\n                </a>\n                <div class=\"caption\">\n                    <h3>Thumbnail label</h3>\n                    <p>Cras justo odio, dapibus ac facilisis in, egestas eget quam.</p>\n                    <p>\n                        <a href=\"#\" class=\"btn btn-primary\" role=\"button\">Button</a>\n                        <a href=\"#\" class=\"btn btn-default\" role=\"button\">Button</a>\n                    </p>\n                </div>\n            </div>\n        </div>\n        <!-- Modal -->\n        <div class=\"modal fade\" id=\"img_modal\" tabindex=\"-1\" role=\"dialog\" aria-labelledby=\"img_modal_label\">\n            <div class=\"modal-dialog\" role=\"document\">\n            <div class=\"modal-content\">\n                <div class=\"modal-header\">\n                    <button type=\"button\" class=\"close\" data-dismiss=\"modal\" aria-label=\"Close\">\n                        <span aria-hidden=\"true\">&times;</span>\n                    </button>\n                    <h4 class=\"modal-title\" id=\"img_modal_label\">Big Image</h4>\n                </div>\n                <div class=\"modal-body\">\n                    <img class=\"img-responsive\" src=\"{{ url_for('static', filename='img/cat.jpg') }}\">\n                </div>\n            </div>\n            </div>\n        </div>\n    </div>\n{% endblock %}\n\n{% block extra_js %}\n<script>\n// 模态窗口垂直居中\n$(\"#img_modal\").on('shown.bs.modal', function(){\n      var $this = $(this);\n      var $modal_dialog = $this.find('.modal-dialog');\n      var m_top = ( $(window).height() - $modal_dialog.height() )/2;\n      $modal_dialog.css({'margin': m_top + 'px auto'});\n    });\n</script>\n{% endblock %}\n"
  },
  {
    "path": "app_frontend/templates/active/add.html",
    "content": "<!-- extend from base layout -->\n{% extends \"layout.html\" %}\n\n{% block content %}\n    <div class=\"container\">\n    <ol class=\"breadcrumb\">\n        <li><a href=\"/\">首页</a></li>\n        <li class=\"active\">激活中心</li>\n        <li class=\"active\">赠送激活</li>\n    </ol>\n    <div class=\"row\">\n        <div class=\"table-responsive col-lg-8 col-md-12\">\n            <form class=\"form-horizontal\" method=\"post\" action=\"\">\n                {{ form.csrf_token }}\n                <div class=\"form-group{% if form.user_name.errors %} has-error{% endif %}\">\n                    {{ form.user_name.label(class=\"col-sm-2 control-label\") }}\n                    <div class=\"col-sm-10\">\n                        {{ form.user_name(class=\"form-control\", placeholder=\"填写赠送用户名称\") }}\n                        {% for error in form.user_name.errors %}\n                            <span class=\"help-block\">{{ error }}</span>\n                        {% endfor %}\n                    </div>\n                </div>\n                <div class=\"form-group{% if form.amount.errors %} has-error{% endif %}\">\n                    {{ form.amount.label(class=\"col-sm-2 control-label\") }}\n                    <div class=\"col-sm-10\">\n                        {{ form.amount(class=\"form-control\", placeholder=\"填写赠送数量\", type=\"number\", min=\"1\") }}\n                        {% for error in form.amount.errors %}\n                            <span class=\"help-block\">{{ error }}</span>\n                        {% endfor %}\n                        <span class=\"help-block\">赠送数量必须为整数 [当前剩余激活码数量：{{ current_user.id | user_active }}]</span>\n                    </div>\n                </div>\n                <div class=\"form-group\">\n                    <div class=\"col-sm-offset-2 col-sm-10\">\n                        <button type=\"submit\" class=\"btn btn-success btn-load\" data-loading-text=\"赠送中\">赠送</button>\n                        <button type=\"reset\" class=\"btn btn-default\">重新填写</button>\n                        <button class=\"btn btn-default\" onclick=\"history.back();\">返回</button>\n                    </div>\n                </div>\n            </form>\n        </div>\n        <!-- 用户概要 -->\n        <div class=\"col-lg-4 col-md-12\">\n            <!-- 状态信息 -->\n            {% include('user/_status.html') %}\n            <!-- 推广链接 -->\n            {% include('user/_invite_link.html') %}\n            <!-- 账户信息 -->\n            {% include('user/_account_info.html') %}\n            <!-- 我的团队 -->\n            {% include('user/_team_tree.html') %}\n        </div>\n    </div>\n    </div>\n{% endblock %}\n\n{% block extra_js %}\n<script src=\"{{ url_for('static', filename='plugin/clipboard.js-1.6.1/dist/clipboard.min.js') }}\"></script>\n<script>\n    /**\n     * 用户自己激活\n     * @returns {boolean}\n     */\n    function self_active() {\n        // console.log($(form).serialize());\n        $.ajax({\n            url: \"{{ url_for('user.ajax_self_active') }}\",\n            type: 'GET',\n            dataType: 'json',\n            success: function (result) {\n                // console.log(result);\n                if(result.hasOwnProperty('error')){\n                    alert(result.error);\n                }else {\n                    alert(result.success);\n                    document.location.reload();\n                }\n            }\n        });\n        return false;\n    }\n</script>\n\n<script>\n    //推广链接复制\n    var clipboard = new Clipboard('.btn');\n\n    clipboard.on('success', function(e) {\n        // console.info('Action:', e.action);\n        // console.info('Text:', e.text);\n        // console.info('Trigger:', e.trigger);\n        e.clearSelection();\n        alert('复制成功，粘贴使用推广链接');\n    });\n\n    clipboard.on('error', function(e) {\n        // console.error('Action:', e.action);\n        // console.error('Trigger:', e.trigger);\n        alert('操作失败，重新复制推广链接');\n    });\n</script>\n{% endblock %}\n"
  },
  {
    "path": "app_frontend/templates/active/list.html",
    "content": "<!-- extend from base layout -->\n{% extends \"layout.html\" %}\n\n{% block extra_css %}\n\n{% endblock %}\n\n{% block content %}\n    <div class=\"container\">\n    <!-- header -->\n    <nav class=\"sub-header row container-fluid\">\n        <ol class=\"breadcrumb\">\n            <li><a href=\"/\">首页</a></li>\n            <li class=\"active\">激活中心</li>\n            <li class=\"active\">激活记录 <span class=\"badge\">{{ current_user.id | user_active }}</span></li>\n        </ol>\n        <div class=\"btn-group pull-right\" role=\"group\" aria-label=\"...\">\n            {% if request.query_string == 'active_status=1' %}\n            <a type=\"button\" class=\"btn btn-default\" href=\"{{ url_for('active.lists') }}\">赠送</a>\n            <a type=\"button\" class=\"btn btn-default active\">接收</a>\n            {% else %}\n            <a type=\"button\" class=\"btn btn-default active\">赠送</a>\n            <a type=\"button\" class=\"btn btn-default\" href=\"{{ url_for('active.lists', active_status=1) }}\">接收</a>\n            {% endif %}\n        </div>\n    </nav>\n\n    <hr/>\n    <!-- content -->\n    <div class=\"table-responsive\">\n        {# <table class=\"table table-striped\"> #}\n        <table class=\"table table-hover\">\n            <thead>\n            <tr>\n                <th>激活明细ID</th>\n                <th>赠送用户</th>\n                <th>接收用户</th>\n                <th>类型</th>\n                <th>数量</th>\n                <th>时间</th>\n            </tr>\n            </thead>\n            <tbody>\n            {% for active, user_profile_put, user_profile_get in pagination.items %}\n            <tr class=\"text-muted\">\n                <td>{{ active.id }}</td>\n                <td>{{ user_profile_put.nickname | default('系统赠送') }} [{{ active.user_id }}]</td>\n                <td>{{ user_profile_get.nickname }} [{{ active.sc_id }}]</td>\n                <td>{{ active.type | type_active }}</td>\n                <td>{{ active.amount }}</td>\n                <td>{{ moment(active.create_time).format('YYYY-MM-DD HH:mm:ss') }}</td>\n            </tr>\n            {% endfor %}\n            </tbody>\n        </table>\n        {# 翻页 #}\n        {% from \"macros.html\" import render_pagination %}\n        {{ render_pagination(pagination, 'active.lists') }}\n    </div>\n    </div>\n{% endblock %}\n\n{% block extra_js %}\n\n{% endblock %}\n"
  },
  {
    "path": "app_frontend/templates/apply/get_add.html",
    "content": "<!-- extend from base layout -->\n{% extends \"layout.html\" %}\n\n{% block content %}\n    <div class=\"container\">\n    <ol class=\"breadcrumb\">\n        <li><a href=\"/\">首页</a></li>\n        <li class=\"active\">提现中心</li>\n        <li class=\"active\">我要提现</li>\n    </ol>\n    <div class=\"row\">\n        <div class=\"table-responsive col-lg-8 col-md-12\">\n            <form class=\"form-horizontal\" method=\"post\" action=\"\">\n                {{ form.csrf_token }}\n                <div class=\"form-group{% if form.type_pay.errors %} has-error{% endif %}\">\n                    {{ form.type_pay.label(class=\"col-sm-2 control-label\") }}\n                    <div class=\"col-sm-10\">\n                        {{ form.type_pay(default=form.type_pay.data | int) }}\n                        {% for error in form.type_pay.errors %}\n                            <span class=\"help-block\">{{ error }}</span>\n                        {% endfor %}\n                        <span class=\"help-block\">\n                            <a target=\"_blank\" href=\"https://cshall.alipay.com/lab/help_detail.htm?help_id=212269\">《支付宝限额说明》</a>\n                            <br/>\n                            <a target=\"_blank\" href=\"http://kf.qq.com/touch/faq/151210NZzmuY151210ZRj2y2.html\">《微信支付限额说明》</a>\n                        </span>\n                    </div>\n                </div>\n                <div class=\"form-group{% if form.type_withdraw.errors %} has-error{% endif %}\">\n                    {{ form.type_withdraw.label(class=\"col-sm-2 control-label\") }}\n                    <div class=\"col-sm-10\">\n                        {{ form.type_withdraw(default=form.type_withdraw.data | int) }}\n                        {% for error in form.type_withdraw.errors %}\n                            <span class=\"help-block\">{{ error }}</span>\n                        {% endfor %}\n                        <span class=\"help-block\">当前余额，钱包余额:{{ current_user.id | user_wallet }}，数字货币:{{ current_user.id | user_bit_coin }}</span>\n                    </div>\n                </div>\n                <div class=\"form-group{% if form.money_apply.errors %} has-error{% endif %}\">\n                    {{ form.money_apply.label(class=\"col-sm-2 control-label\") }}\n                    <div class=\"col-sm-10\">\n                        {{ form.money_apply(class=\"form-control\", placeholder=\"申请金额[\"+APPLY_GET_STEP+\"的倍数]\", type=\"number\", min=APPLY_GET_MIN_EACH, max=APPLY_GET_MAX_EACH, step=APPLY_GET_STEP) }}\n                        {% for error in form.money_apply.errors %}\n                            <span class=\"help-block\">{{ error }}</span>\n                        {% endfor %}\n                        <span class=\"help-block\">申请金额 必须为{{ APPLY_GET_STEP }}的倍数，最小金额{{ APPLY_GET_MIN_EACH }}，最大金额{{ APPLY_GET_MAX_EACH }}</span>\n                    </div>\n                </div>\n                <div class=\"form-group\">\n                    <div class=\"col-sm-offset-2 col-sm-10\">\n                        <button type=\"submit\" class=\"btn btn-success btn-load\" data-loading-text=\"申请中\">申请</button>\n                        <button type=\"reset\" class=\"btn btn-default\">重新填写</button>\n                        <button class=\"btn btn-default\" onclick=\"history.back();\">返回</button>\n                    </div>\n                </div>\n            </form>\n        </div>\n        <!-- 用户概要 -->\n        <div class=\"col-lg-4 col-md-12\">\n            <!-- 状态信息 -->\n            {% include('user/_status.html') %}\n            <!-- 推广链接 -->\n            {% include('user/_invite_link.html') %}\n            <!-- 账户信息 -->\n            {% include('user/_account_info.html') %}\n            <!-- 我的团队 -->\n            {% include('user/_team_tree.html') %}\n        </div>\n    </div>\n    </div>\n{% endblock %}\n\n{% block extra_js %}\n<script src=\"{{ url_for('static', filename='plugin/clipboard.js-1.6.1/dist/clipboard.min.js') }}\"></script>\n<script>\n    /**\n     * 用户自己激活\n     * @returns {boolean}\n     */\n    function self_active() {\n        // console.log($(form).serialize());\n        $.ajax({\n            url: \"{{ url_for('user.ajax_self_active') }}\",\n            type: 'GET',\n            dataType: 'json',\n            success: function (result) {\n                // console.log(result);\n                if(result.hasOwnProperty('error')){\n                    alert(result.error);\n                }else {\n                    alert(result.success);\n                    document.location.reload();\n                }\n            }\n        });\n        return false;\n    }\n</script>\n<script>\n    //推广链接复制\n    var clipboard = new Clipboard('.btn');\n\n    clipboard.on('success', function(e) {\n        // console.info('Action:', e.action);\n        // console.info('Text:', e.text);\n        // console.info('Trigger:', e.trigger);\n        e.clearSelection();\n        alert('复制成功，粘贴使用推广链接');\n    });\n\n    clipboard.on('error', function(e) {\n        // console.error('Action:', e.action);\n        // console.error('Trigger:', e.trigger);\n        alert('操作失败，重新复制推广链接');\n    });\n</script>\n{% endblock %}\n"
  },
  {
    "path": "app_frontend/templates/apply/get_edit.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n    <meta charset=\"UTF-8\">\n    <title>Title</title>\n</head>\n<body>\n\n</body>\n</html>"
  },
  {
    "path": "app_frontend/templates/apply/get_list.html",
    "content": "<!-- extend from base layout -->\n{% extends \"layout.html\" %}\n\n{% block extra_css %}\n\n{% endblock %}\n\n{% block content %}\n    <div class=\"container\">\n    <!-- header -->\n    <nav class=\"sub-header row container-fluid\">\n        <ol class=\"breadcrumb\">\n            <li><a href=\"/\">首页</a></li>\n            <li class=\"active\">提现中心</li>\n            <li class=\"active\">申请记录</li>\n        </ol>\n        <div class=\"btn-group pull-right\" role=\"group\" aria-label=\"...\">\n            {% if request.query_string == 'status_order=2' %}\n            <a type=\"button\" class=\"btn btn-default\" href=\"{{ url_for('apply.lists_get') }}\">处理中</a>\n            <a type=\"button\" class=\"btn btn-default active\">已完成</a>\n            {% else %}\n            <a type=\"button\" class=\"btn btn-default active\">处理中</a>\n            <a type=\"button\" class=\"btn btn-default\" href=\"{{ url_for('apply.lists_get', status_order=2) }}\">已完成</a>\n            {% endif %}\n        </div>\n    </nav>\n\n    <hr/>\n    <!-- content -->\n    <div class=\"table-responsive\">\n        {# <table class=\"table table-striped\"> #}\n        <table class=\"table table-hover\">\n            <thead>\n            <tr>\n                <th>提现ID</th>\n{#                <th>用户ID</th>#}\n                <th>申请类型</th>\n                <th>申请金额</th>\n                <th>订单金额</th>\n                <th>申请状态</th>\n                <th>订单状态</th>\n                <th>删除状态</th>\n                <th>申请时间</th>\n                <th>操作</th>\n            </tr>\n            </thead>\n            <tbody>\n            {% for apply_get in pagination.items %}\n            <tr class=\"text-muted\">\n                <td>{{ apply_get.id }}</td>\n{#                <td>{{ apply_get.user_id }}</td>#}\n                <td>{{ apply_get.type_apply | type_apply }}</td>\n                <td>{{ apply_get.money_apply }}</td>\n                <td>{{ apply_get.money_order }}</td>\n                <td>{{ apply_get.status_apply | status_apply }}</td>\n                <td>{{ apply_get.status_order | status_order }}</td>\n                <td>{{ apply_get.status_delete | status_delete }}</td>\n                <td>{{ moment(apply_get.create_time).format('YYYY-MM-DD HH:mm:ss') }}</td>\n                <td>\n                    <a href=\"javascript:void(0);\" onclick=\"apply_get_delete({{ apply_get.id }});\" rel=\"tooltip\" title=\"删除\"><span class=\"glyphicon glyphicon-trash\"></span></a>\n                </td>\n            </tr>\n            {% endfor %}\n            </tbody>\n        </table>\n        {# 翻页 #}\n        {% from \"macros.html\" import render_pagination %}\n        {{ render_pagination(pagination, 'apply.lists_put') }}\n    </div>\n    </div>\n{% endblock %}\n\n{% block extra_js %}\n<script>\n    // 提现删除\n    function apply_get_delete(apply_get_id){\n        if(confirm(\"删除数据不能恢复，是否确认删除?\"))\n        {\n            // console.log(apply_get_id);\n            $.getJSON('{{ url_for('apply.ajax_delete_get') }}',\n            {\n                apply_get_id: apply_get_id\n            }, function (result) {\n                if(result.hasOwnProperty('error')){\n                    alert(result.error);\n                }else {\n                    alert(result.success);\n                    window.location.reload();\n                }\n            });\n            return false;\n        }\n    }\n</script>\n{% endblock %}\n"
  },
  {
    "path": "app_frontend/templates/apply/put_add.html",
    "content": "<!-- extend from base layout -->\n{% extends \"layout.html\" %}\n\n{% block content %}\n    <div class=\"container\">\n    <ol class=\"breadcrumb\">\n        <li><a href=\"/\">首页</a></li>\n        <li class=\"active\">投资中心</li>\n        <li class=\"active\">我要投资</li>\n    </ol>\n    <div class=\"row\">\n        <div class=\"table-responsive col-lg-8 col-md-12\">\n            <form class=\"form-horizontal\" method=\"post\" action=\"\">\n                {{ form.csrf_token }}\n                <div class=\"form-group{% if form.type_pay.errors %} has-error{% endif %}\">\n                    {{ form.type_pay.label(class=\"col-sm-2 control-label\") }}\n                    <div class=\"col-sm-10\">\n                        {{ form.type_pay(default=form.type_pay.data | int) }}\n                        {% for error in form.type_pay.errors %}\n                            <span class=\"help-block\">{{ error }}</span>\n                        {% endfor %}\n                        <span class=\"help-block\">\n                            <a target=\"_blank\" href=\"https://cshall.alipay.com/lab/help_detail.htm?help_id=212269\">《支付宝限额说明》</a>\n                            <br/>\n                            <a target=\"_blank\" href=\"http://kf.qq.com/touch/faq/151210NZzmuY151210ZRj2y2.html\">《微信支付限额说明》</a>\n                        </span>\n                    </div>\n                </div>\n                <div class=\"form-group{% if form.money_apply.errors %} has-error{% endif %}\">\n                    {{ form.money_apply.label(class=\"col-sm-2 control-label\") }}\n                    <div class=\"col-sm-10\">\n                        {{ form.money_apply(class=\"form-control\", placeholder=\"申请金额[\"+APPLY_PUT_STEP+\"的倍数]\", type=\"number\", min=APPLY_PUT_MIN_EACH, max=APPLY_PUT_MAX_EACH, step=APPLY_PUT_STEP) }}\n                        {% for error in form.money_apply.errors %}\n                            <span class=\"help-block\">{{ error }}</span>\n                        {% endfor %}\n                        <span class=\"help-block\">申请金额 必须为{{ APPLY_PUT_STEP }}的倍数，最小金额{{ APPLY_PUT_MIN_EACH }}，最大金额{{ APPLY_PUT_MAX_EACH }}</span>\n                    </div>\n                </div>\n                <div class=\"form-group\">\n                    <div class=\"col-sm-offset-2 col-sm-10\">\n                        <button type=\"submit\" class=\"btn btn-success btn-load\" data-loading-text=\"申请中\">申请</button>\n                        <button type=\"reset\" class=\"btn btn-default\">重新填写</button>\n                        <button class=\"btn btn-default\" onclick=\"history.back();\">返回</button>\n                    </div>\n                </div>\n            </form>\n        </div>\n        <!-- 用户概要 -->\n        <div class=\"col-lg-4 col-md-12\">\n            <!-- 状态信息 -->\n            {% include('user/_status.html') %}\n            <!-- 推广链接 -->\n            {% include('user/_invite_link.html') %}\n            <!-- 账户信息 -->\n            {% include('user/_account_info.html') %}\n            <!-- 我的团队 -->\n            {% include('user/_team_tree.html') %}\n        </div>\n    </div>\n    </div>\n{% endblock %}\n\n{% block extra_js %}\n<script src=\"{{ url_for('static', filename='plugin/clipboard.js-1.6.1/dist/clipboard.min.js') }}\"></script>\n<script>\n    /**\n     * 用户自己激活\n     * @returns {boolean}\n     */\n    function self_active() {\n        // console.log($(form).serialize());\n        $.ajax({\n            url: \"{{ url_for('user.ajax_self_active') }}\",\n            type: 'GET',\n            dataType: 'json',\n            success: function (result) {\n                // console.log(result);\n                if(result.hasOwnProperty('error')){\n                    alert(result.error);\n                }else {\n                    alert(result.success);\n                    document.location.reload();\n                }\n            }\n        });\n        return false;\n    }\n</script>\n<script>\n    //推广链接复制\n    var clipboard = new Clipboard('.btn');\n\n    clipboard.on('success', function(e) {\n        // console.info('Action:', e.action);\n        // console.info('Text:', e.text);\n        // console.info('Trigger:', e.trigger);\n        e.clearSelection();\n        alert('复制成功，粘贴使用推广链接');\n    });\n\n    clipboard.on('error', function(e) {\n        // console.error('Action:', e.action);\n        // console.error('Trigger:', e.trigger);\n        alert('操作失败，重新复制推广链接');\n    });\n</script>\n{% endblock %}\n"
  },
  {
    "path": "app_frontend/templates/apply/put_edit.html",
    "content": "<!-- extend from base layout -->\n{% extends \"layout.html\" %}\n\n{% block content %}\n    <div class=\"container\">\n    <h2 class=\"sub-header\">Apply Put Edit</h2>\n    <form class=\"form-horizontal\" method=\"post\" action=\"{{ url_for('blog.add', blog_id=blog_id) }}\">\n        {{ form.csrf_token }}\n        <div class=\"form-group{% if form.author.errors %} has-error{% endif %}\">\n            {{ form.author.label(class=\"col-sm-2 control-label\") }}\n            <div class=\"col-sm-10\">\n                {{ form.author(class=\"form-control\", placeholder=\"Author\") }}\n                {% for error in form.author.errors %}\n                    <span class=\"help-block\">{{ error }}</span>\n                {% endfor %}\n            </div>\n        </div>\n        <div class=\"form-group{% if form.title.errors %} has-error{% endif %}\">\n            {{ form.title.label(class=\"col-sm-2 control-label\") }}\n            <div class=\"col-sm-10\">\n                {{ form.title(class=\"form-control\", placeholder=\"Title\") }}\n                {% for error in form.title.errors %}\n                    <span class=\"help-block\">{{ error }}</span>\n                {% endfor %}\n            </div>\n        </div>\n        <div class=\"form-group{% if form.pub_date.errors %} has-error{% endif %}\">\n            {{ form.pub_date.label(class=\"col-sm-2 control-label\") }}\n            <div class=\"col-sm-10\">\n                {{ form.pub_date(class=\"form-control\", placeholder=\"Pub Date\", type='date') }}\n                {% for error in form.pub_date.errors %}\n                    <span class=\"help-block\">{{ error }}</span>\n                {% endfor %}\n            </div>\n        </div>\n        <div class=\"form-group\">\n            <div class=\"col-sm-offset-2 col-sm-10\">\n                <button type=\"submit\" class=\"btn btn-default btn-load\" data-loading-text=\"Save...\">Save</button>\n                <button type=\"reset\" class=\"btn btn-default\">Reset</button>\n                <button class=\"btn btn-default\" onclick=\"history.back();\">Back</button>\n            </div>\n        </div>\n    </form>\n    </div>\n{% endblock %}\n"
  },
  {
    "path": "app_frontend/templates/apply/put_list.html",
    "content": "<!-- extend from base layout -->\n{% extends \"layout.html\" %}\n\n{% block extra_css %}\n\n{% endblock %}\n\n{% block content %}\n    <div class=\"container\">\n    <!-- header -->\n    <nav class=\"sub-header row container-fluid\">\n        <ol class=\"breadcrumb\">\n            <li><a href=\"/\">首页</a></li>\n            <li class=\"active\">投资中心</li>\n            <li class=\"active\">申请记录</li>\n        </ol>\n        <div class=\"btn-group pull-right\" role=\"group\" aria-label=\"...\">\n            {% if request.query_string == 'status_order=2' %}\n            <a type=\"button\" class=\"btn btn-default\" href=\"{{ url_for('apply.lists_put') }}\">处理中</a>\n            <a type=\"button\" class=\"btn btn-default active\">已完成</a>\n            {% else %}\n            <a type=\"button\" class=\"btn btn-default active\">处理中</a>\n            <a type=\"button\" class=\"btn btn-default\" href=\"{{ url_for('apply.lists_put', status_order=2) }}\">已完成</a>\n            {% endif %}\n        </div>\n    </nav>\n\n    <hr/>\n    <!-- content -->\n    <div class=\"table-responsive\">\n        {# <table class=\"table table-striped\"> #}\n        <table class=\"table table-hover\">\n            <thead>\n            <tr>\n                <th>投资ID</th>\n{#                <th>用户ID</th>#}\n                <th>申请类型</th>\n                <th>申请金额</th>\n                <th>订单金额</th>\n                <th>申请状态</th>\n                <th>订单状态</th>\n                <th>删除状态</th>\n                <th>申请时间</th>\n                <th>操作</th>\n            </tr>\n            </thead>\n            <tbody>\n            {% for apply_put in pagination.items %}\n            <tr class=\"text-muted\">\n                <td>{{ apply_put.id }}</td>\n{#                <td>{{ apply_put.user_id }}</td>#}\n                <td>{{ apply_put.type_apply | type_apply }}</td>\n                <td>{{ apply_put.money_apply }}</td>\n                <td>{{ apply_put.money_order }}</td>\n                <td>{{ apply_put.status_apply | status_apply }}</td>\n                <td>{{ apply_put.status_order | status_order }}</td>\n                <td>{{ apply_put.status_delete | status_delete }}</td>\n                <td>{{ moment(apply_put.create_time).format('YYYY-MM-DD HH:mm:ss') }}</td>\n                <td>\n                    <a href=\"javascript:void(0);\" onclick=\"apply_put_delete({{ apply_put.id }});\" rel=\"tooltip\" title=\"删除\"><span class=\"glyphicon glyphicon-trash\"></span></a>\n                </td>\n            </tr>\n            {% endfor %}\n            </tbody>\n        </table>\n        {# 翻页 #}\n        {% from \"macros.html\" import render_pagination %}\n        {{ render_pagination(pagination, 'apply.lists_put') }}\n    </div>\n    </div>\n{% endblock %}\n\n{% block extra_js %}\n<script>\n    // 投资删除\n    function apply_put_delete(apply_put_id){\n        if(confirm(\"删除数据不能恢复，是否确认删除?\"))\n        {\n            // console.log(apply_put_id);\n            $.getJSON('{{ url_for('apply.ajax_delete_put') }}',\n            {\n                apply_put_id: apply_put_id\n            }, function (result) {\n                if(result.hasOwnProperty('error')){\n                    alert(result.error);\n                }else {\n                    alert(result.success);\n                    window.location.reload();\n                }\n            });\n            return false;\n        }\n    }\n</script>\n{% endblock %}\n"
  },
  {
    "path": "app_frontend/templates/auth/_forget_password.html",
    "content": "\n<div class=\"modal fade\" id=\"forget_password\" tabindex=\"-1\" role=\"dialog\" aria-labelledby=\"myModalLabel\">\n    <div class=\"modal-dialog\" role=\"document\">\n        <div class=\"modal-content\">\n            <div class=\"modal-header\">\n                <button type=\"button\" class=\"close\" data-dismiss=\"modal\" aria-label=\"Close\"><span\n                        aria-hidden=\"true\">&times;</span></button>\n                <h4 class=\"modal-title\" id=\"myModalLabel\">忘记密码</h4>\n            </div>\n            <div class=\"modal-body\">\n                <p>联系客服，找回密码</p>\n                <p>服务时间 7*24小时 不间断服务</p>\n            </div>\n            <div class=\"modal-footer\">\n                <button type=\"button\" class=\"btn btn-default\" data-dismiss=\"modal\">关闭</button>\n                <button type=\"button\" class=\"btn btn-primary\" data-dismiss=\"modal\">立刻联系</button>\n            </div>\n        </div>\n    </div>\n</div>"
  },
  {
    "path": "app_frontend/templates/auth/_login_three_part.html",
    "content": "<!-- 第三方登录 -->\n<hr/>\n<a type=\"button\" href=\"{{ url_for('auth.login_qq') }}\">QQ</a>\n<a type=\"button\" href=\"{{ url_for('auth.login_weibo') }}\">WeiBo</a>\n<a type=\"button\" href=\"{{ url_for('auth.login_github') }}\">GitHub</a>\n"
  },
  {
    "path": "app_frontend/templates/auth/email.html",
    "content": "{% extends \"layout.html\" %}\n\n{% block content %}\n    <div class=\"container\">\n    <h2>邮箱登录</h2>\n    <form class=\"form-horizontal\" method=\"post\" action=\"\">\n        {{ form.csrf_token }}\n\n        {# 标签导航 #}\n        <ul class=\"nav nav-tabs\">  {# 填充整个导航条：nav-justified #}\n            <li role=\"presentation\"><a href=\"{{ url_for('auth.index') }}\">账号登录</a></li>\n            <li role=\"presentation\"><a href=\"{{ url_for('auth.phone') }}\">手机登录</a></li>\n            <li role=\"presentation\" class=\"active\"><a href=\"{{ url_for('auth.email') }}\">邮箱登录</a></li>\n        </ul>\n        <div class=\"form-group\"></div>\n        <div class=\"form-group{% if form.email.errors %} has-error{% endif %}\">\n            {{ form.email.label(class=\"col-sm-2 control-label\") }}\n            <div class=\"col-sm-10\">\n                {{ form.email(class=\"form-control\", placeholder=\"登录邮箱[2-20位]\") }}\n                {% for error in form.email.errors %}\n                    <span class=\"help-block\">{{ error }}</span>\n                {% endfor %}\n            </div>\n        </div>\n        <div class=\"form-group{% if form.password.errors %} has-error{% endif %}\">\n            {{ form.password.label(class=\"col-sm-2 control-label\") }}\n            <div class=\"col-sm-10\">\n                {{ form.password(class=\"form-control\", placeholder=\"登录密码[6-20位]\") }}\n                {% for error in form.password.errors %}\n                    <span class=\"help-block\">{{ error }}</span>\n                {% endfor %}\n            </div>\n        </div>\n        <div class=\"form-group{% if form.remember.errors %} has-error{% endif %}\">\n            <div class=\"col-sm-offset-2 col-sm-10\">\n                <div class=\"checkbox\">\n                    <label>\n                        {{ form.remember }} 记住登录状态\n                    </label>\n                </div>\n            </div>\n        </div>\n        <div class=\"form-group\">\n            <div class=\"col-sm-offset-2 col-sm-10\">\n                <button type=\"submit\" class=\"btn btn-default btn-load\" data-loading-text=\"登录中\" autocomplete=\"off\">登录</button> <a href=\"#\">忘记密码?</a>\n            </div>\n        </div>\n    </form>\n\n    {% if SWITCH_LOGIN_THREE_PART %}\n    {% include('auth/_login_three_part.html') %}\n    {% endif %}\n\n    </div>\n{% endblock %}"
  },
  {
    "path": "app_frontend/templates/auth/index.html",
    "content": "{% extends \"layout.html\" %}\n\n{% block content %}\n    <div class=\"container\">\n    <h2>账号登录</h2>\n    <form class=\"form-horizontal\" method=\"post\" action=\"\">\n        {{ form.csrf_token }}\n\n        {# 标签导航 #}\n{#        <ul class=\"nav nav-tabs\">  {# 填充整个导航条：nav-justified #}\n{#            <li role=\"presentation\" class=\"active\"><a href=\"{{ url_for('auth.index') }}\">账号登录</a></li>#}\n{#            <li role=\"presentation\"><a href=\"{{ url_for('auth.phone') }}\">手机登录</a></li>#}\n{#            <li role=\"presentation\"><a href=\"{{ url_for('auth.email') }}\">邮箱登录</a></li>#}\n{#        </ul>#}\n        <div class=\"form-group\"></div>\n        <div class=\"form-group{% if form.account.errors %} has-error{% endif %}\">\n            {{ form.account.label(class=\"col-sm-2 control-label\") }}\n            <div class=\"col-sm-10\">\n                {{ form.account(class=\"form-control\", placeholder=\"登录账号[2-20位]\") }}\n                {% for error in form.account.errors %}\n                    <span class=\"help-block\">{{ error }}</span>\n                {% endfor %}\n            </div>\n        </div>\n        <div class=\"form-group{% if form.password.errors %} has-error{% endif %}\">\n            {{ form.password.label(class=\"col-sm-2 control-label\") }}\n            <div class=\"col-sm-10\">\n                {{ form.password(class=\"form-control\", placeholder=\"登录密码[6-20位]\") }}\n                {% for error in form.password.errors %}\n                    <span class=\"help-block\">{{ error }}</span>\n                {% endfor %}\n            </div>\n        </div>\n        <div class=\"form-group{% if form.captcha.errors %} has-error{% endif %}\">\n            {{ form.captcha.label(class=\"col-sm-2 col-xs-12 control-label\") }}\n            <div class=\"col-sm-8 col-xs-8\">\n                {{ form.captcha(class=\"form-control\", placeholder=\"图形验证码\", maxlength=4) }}\n                {% for error in form.captcha.errors %}\n                    <span class=\"help-block\">{{ error }}</span>\n                {% endfor %}\n            </div>\n            <div class=\"col-sm-2 col-xs-2\">\n                <img src=\"{{ url_for('captcha.get_code', code_type='login') }}\" rel=\"tooltip\" title=\"看不清？换一张\" id=\"captcha_img\" onclick=\"refresh_code();\">\n            </div>\n        </div>\n        <div class=\"form-group{% if form.remember.errors %} has-error{% endif %}\">\n            <div class=\"col-sm-offset-2 col-sm-10\">\n                <div class=\"checkbox\">\n                    <label>\n                        {{ form.remember }} 记住登录状态\n                    </label>\n                </div>\n            </div>\n        </div>\n        <div class=\"form-group\">\n            <div class=\"col-sm-offset-2 col-sm-10\">\n                <button type=\"submit\" class=\"btn btn-default btn-load\" data-loading-text=\"登录中\" autocomplete=\"off\">登录</button> <a href=\"#\" data-toggle=\"modal\" data-target=\"#forget_password\">忘记密码?</a>\n            </div>\n        </div>\n    </form>\n\n    {% if SWITCH_LOGIN_THREE_PART %}\n    {% include('auth/_login_three_part.html') %}\n    {% endif %}\n\n    </div>\n    <!-- 忘记密码 -->\n    {% include('auth/_forget_password.html') %}\n{% endblock %}\n\n{% block extra_js %}\n<script>\n    // 刷新验证码\n    function refresh_code() {\n        var now = new Date();\n        $('#captcha_img')[0].setAttribute(\"src\", \"{{ url_for('captcha.get_code', code_type='login') }}\" + \"?t=\" + now.getTime());\n    }\n</script>\n{% endblock %}\n"
  },
  {
    "path": "app_frontend/templates/auth/phone.html",
    "content": "{% extends \"layout.html\" %}\n\n{% block content %}\n    <div class=\"container\">\n    <h2>手机登录</h2>\n    <form class=\"form-horizontal\" method=\"post\" action=\"\">\n        {{ form.csrf_token }}\n\n        {# 标签导航 #}\n        <ul class=\"nav nav-tabs\">  {# 填充整个导航条：nav-justified #}\n            <li role=\"presentation\"><a href=\"{{ url_for('auth.index') }}\">账号登录</a></li>\n            <li role=\"presentation\" class=\"active\"><a href=\"{{ url_for('auth.phone') }}\">手机登录</a></li>\n            <li role=\"presentation\"><a href=\"{{ url_for('auth.email') }}\">邮箱登录</a></li>\n        </ul>\n        <div class=\"form-group\"></div>\n        <div class=\"form-group{% if form.area_id.errors %} has-error{% endif %}\">\n            {{ form.area_id.label(class=\"col-sm-2 control-label\") }}\n            <div class=\"col-sm-10\">\n                {{ form.area_id(data_header=\"选择手机区号\") }}\n                {% for error in form.area_id.errors %}\n                    <span class=\"help-block\">{{ error }}</span>\n                {% endfor %}\n            </div>\n        </div>\n\n        <div class=\"form-group{% if form.phone.errors %} has-error{% endif %}\">\n            {{ form.phone.label(class=\"col-sm-2 control-label\") }}\n            <div class=\"col-sm-10\">\n                {{ form.phone(class=\"form-control\", placeholder=\"登录手机[2-20位]\") }}\n                {% for error in form.phone.errors %}\n                    <span class=\"help-block\">{{ error }}</span>\n                {% endfor %}\n            </div>\n        </div>\n        <div class=\"form-group{% if form.password.errors %} has-error{% endif %}\">\n            {{ form.password.label(class=\"col-sm-2 control-label\") }}\n            <div class=\"col-sm-10\">\n                {{ form.password(class=\"form-control\", placeholder=\"登录密码[6-20位]\") }}\n                {% for error in form.password.errors %}\n                    <span class=\"help-block\">{{ error }}</span>\n                {% endfor %}\n            </div>\n        </div>\n        <div class=\"form-group{% if form.remember.errors %} has-error{% endif %}\">\n            <div class=\"col-sm-offset-2 col-sm-10\">\n                <div class=\"checkbox\">\n                    <label>\n                        {{ form.remember }} 记住登录状态\n                    </label>\n                </div>\n            </div>\n        </div>\n        <div class=\"form-group\">\n            <div class=\"col-sm-offset-2 col-sm-10\">\n                <button type=\"submit\" class=\"btn btn-default btn-load\" data-loading-text=\"登录中\" autocomplete=\"off\">登录</button> <a href=\"#\">忘记密码?</a>\n            </div>\n        </div>\n    </form>\n\n    {% if SWITCH_LOGIN_THREE_PART %}\n    {% include('auth/_login_three_part.html') %}\n    {% endif %}\n\n    </div>\n{% endblock %}\n\n{% block extra_js %}\n<script>\n    // 初始化赋值\n    var area_id = $('#area_id');\n    area_id.selectpicker('val', '{{ form.area_id.data }}');\n    // 处理选项修改\n    area_id.on('changed.bs.select', function (event, clickedIndex, newValue, oldValue) {\n        // console.log($('#area_id').val());\n        // console.log(event);\n        // console.log(clickedIndex);\n        // console.log(newValue);\n        // console.log(oldValue);\n    });\n</script>\n{% endblock %}\n"
  },
  {
    "path": "app_frontend/templates/bit_coin/list.html",
    "content": "{% extends \"layout.html\" %}\n\n{% block content %}\n    <div class=\"container\">\n    <ol class=\"breadcrumb\">\n        <li><a href=\"/\">首页</a></li>\n        <li class=\"active\">账户信息</li>\n        <li class=\"active\">数字货币</li>\n    </ol>\n\n    <div class=\"row\">\n        <div class=\"table-responsive col-lg-8 col-md-12\">\n            {# <table class=\"table table-striped\"> #}\n            <table class=\"table table-hover\">\n                <thead>\n                <tr>\n                    <th>序号</th>\n{#                    <th>数字货币编号</th>#}\n{#                    <th>用户编号</th>#}\n                    <th>收支类型</th>\n                    <th>金额</th>\n                    <th>备注</th>\n                    <th>审核状态</th>\n                    <th>时间</th>\n                </tr>\n                </thead>\n                <tbody>\n                {% for wallet in pagination.items %}\n                <tr class=\"text-muted\">\n                    <td>{{ loop.index }}</td>\n{#                    <td>{{ wallet.id }}</td>#}\n{#                    <td>{{ wallet.user_id }}</td>#}\n                    <td>{{ wallet.type | type_payment }}</td>\n                    <td>{{ wallet.amount }}</td>\n                    <td>{{ wallet.note }}</td>\n                    <td>{{ wallet.status_audit | status_audit }}</td>\n                    <td>{{ moment(wallet.create_time).format('YYYY-MM-DD HH:mm:ss') }}</td>\n                </tr>\n                {% endfor %}\n                </tbody>\n            </table>\n            {# 翻页 #}\n            {% from \"macros.html\" import render_pagination %}\n            {{ render_pagination(pagination, 'wallet.lists') }}\n        </div>\n        <!-- 用户概要 -->\n        <div class=\"col-lg-4 col-md-12\">\n            <!-- 状态信息 -->\n            {% include('user/_status.html') %}\n            <!-- 推广链接 -->\n            {% include('user/_invite_link.html') %}\n            <!-- 账户信息 -->\n            {% include('user/_account_info.html') %}\n            <!-- 我的团队 -->\n            {% include('user/_team_tree.html') %}\n        </div>\n    </div>\n\n\n    </div>\n\n{% endblock %}\n\n{% block extra_js %}\n<script src=\"{{ url_for('static', filename='plugin/clipboard.js-1.6.1/dist/clipboard.min.js') }}\"></script>\n\n<script>\n    /**\n     * 用户自己激活\n     * @returns {boolean}\n     */\n    function self_active() {\n        // console.log($(form).serialize());\n        $.ajax({\n            url: \"{{ url_for('user.ajax_self_active') }}\",\n            type: 'GET',\n            dataType: 'json',\n            success: function (result) {\n                // console.log(result);\n                if(result.hasOwnProperty('error')){\n                    alert(result.error);\n                }else {\n                    alert(result.success);\n                    document.location.reload();\n                }\n            }\n        });\n        return false;\n    }\n</script>\n\n<script>\n    //推广链接复制\n    var clipboard = new Clipboard('.btn');\n\n    clipboard.on('success', function(e) {\n        // console.info('Action:', e.action);\n        // console.info('Text:', e.text);\n        // console.info('Trigger:', e.trigger);\n        e.clearSelection();\n        alert('复制成功，粘贴使用推广链接');\n    });\n\n    clipboard.on('error', function(e) {\n        // console.error('Action:', e.action);\n        // console.error('Trigger:', e.trigger);\n        alert('操作失败，重新复制推广链接');\n    });\n</script>\n{% endblock %}\n"
  },
  {
    "path": "app_frontend/templates/blog/add.html",
    "content": "<!-- extend from base layout -->\n{% extends \"layout.html\" %}\n\n{% block content %}\n    <div class=\"container\">\n    <h2 class=\"sub-header\">Blog Add</h2>\n    <form class=\"form-horizontal\" method=\"post\" action=\"{{ url_for('blog.add', blog_id=blog_id) }}\">\n        {{ form.csrf_token }}\n        <div class=\"form-group{% if form.author.errors %} has-error{% endif %}\">\n            {{ form.author.label(class=\"col-sm-2 control-label\") }}\n            <div class=\"col-sm-10\">\n                {{ form.author(class=\"form-control\", placeholder=\"Author\") }}\n                {% for error in form.author.errors %}\n                    <span class=\"help-block\">{{ error }}</span>\n                {% endfor %}\n            </div>\n        </div>\n        <div class=\"form-group{% if form.title.errors %} has-error{% endif %}\">\n            {{ form.title.label(class=\"col-sm-2 control-label\") }}\n            <div class=\"col-sm-10\">\n                {{ form.title(class=\"form-control\", placeholder=\"Title\") }}\n                {% for error in form.title.errors %}\n                    <span class=\"help-block\">{{ error }}</span>\n                {% endfor %}\n            </div>\n        </div>\n        <div class=\"form-group{% if form.pub_date.errors %} has-error{% endif %}\">\n            {{ form.pub_date.label(class=\"col-sm-2 control-label\") }}\n            <div class=\"col-sm-10\">\n                {{ form.pub_date(class=\"form-control\", placeholder=\"Pub Date\", type='date') }}\n                {% for error in form.pub_date.errors %}\n                    <span class=\"help-block\">{{ error }}</span>\n                {% endfor %}\n            </div>\n        </div>\n        <div class=\"form-group\">\n            <div class=\"col-sm-offset-2 col-sm-10\">\n                <button type=\"submit\" class=\"btn btn-default btn-load\" data-loading-text=\"Save...\">Save</button>\n                <button type=\"reset\" class=\"btn btn-default\">Reset</button>\n                <button class=\"btn btn-default\" onclick=\"history.back();\">Back</button>\n            </div>\n        </div>\n    </form>\n    </div>\n{% endblock %}"
  },
  {
    "path": "app_frontend/templates/blog/edit.html",
    "content": "<!-- extend from base layout -->\n{% extends \"layout.html\" %}\n\n{% block content %}\n    <div class=\"container\">\n    <h2 class=\"sub-header\">Blog Edit</h2>\n    <form class=\"form-horizontal\" method=\"post\" action=\"\">\n        {{ form.csrf_token }}\n        <div class=\"form-group{% if form.author.errors %} has-error{% endif %}\">\n            {{ form.author.label(class=\"col-sm-2 control-label\") }}\n            <div class=\"col-sm-10\">\n                {{ form.author(class=\"form-control\", placeholder=\"Author\") }}\n                {% for error in form.author.errors %}\n                    <span class=\"help-block\">{{ error }}</span>\n                {% endfor %}\n            </div>\n        </div>\n        <div class=\"form-group{% if form.title.errors %} has-error{% endif %}\">\n            {{ form.title.label(class=\"col-sm-2 control-label\") }}\n            <div class=\"col-sm-10\">\n                {{ form.title(class=\"form-control\", placeholder=\"Title\") }}\n                {% for error in form.title.errors %}\n                    <span class=\"help-block\">{{ error }}</span>\n                {% endfor %}\n            </div>\n        </div>\n        <div class=\"form-group{% if form.pub_date.errors %} has-error{% endif %}\">\n            {{ form.pub_date.label(class=\"col-sm-2 control-label\") }}\n            <div class=\"col-sm-10\">\n                {{ form.pub_date(class=\"form-control\", placeholder=\"Pub Date\", type='date') }}\n                {% for error in form.pub_date.errors %}\n                    <span class=\"help-block\">{{ error }}</span>\n                {% endfor %}\n            </div>\n        </div>\n        <div class=\"form-group\">\n            <div class=\"col-sm-offset-2 col-sm-10\">\n                <button type=\"submit\" class=\"btn btn-default btn-load\" data-loading-text=\"Edit...\">Edit</button>\n                <button type=\"reset\" class=\"btn btn-default\">Reset</button>\n                <button class=\"btn btn-default\" onclick=\"history.back();\">Back</button>\n            </div>\n        </div>\n    </form>\n    </div>\n{% endblock %}"
  },
  {
    "path": "app_frontend/templates/blog/hot.html",
    "content": "<!-- extend from base layout -->\n{% extends \"layout.html\" %}\n\n{% block content %}\n    <div class=\"container\">\n    <h2 class=\"sub-header\">Blog Hot!</h2>\n    <div class=\"table-responsive\">\n        {# <table class=\"table table-striped\"> #}\n        <table class=\"table table-hover\">\n            <thead>\n            <tr>\n                <th>#</th>\n                <th>id</th>\n                <th>author</th>\n                <th>title</th>\n                <th>pub_date</th>\n                <th>action</th>\n            </tr>\n            </thead>\n            <tbody>\n            {% for item in pagination.items %}\n            <tr class=\"text-muted\">\n                <td>{{ loop.index }}</td>\n                <td>{{ item.id }}</td>\n                <td>{{ item.author }}</td>\n                <td>{{ item.title }}</td>\n                <td>{{ item.pub_date }}</td>\n                <td>\n                    {# <div class=\"pull-right\"> #}\n                    <a href=\"#\" rel=\"tooltip\" title=\"收藏\"><span class=\"glyphicon glyphicon-heart-empty\"></span>收藏</a>\n                    <a href=\"#\" rel=\"tooltip\" title=\"支持\"><span class=\"glyphicon glyphicon-thumbs-up\"></span>支持</a>\n                    <a href=\"#\" rel=\"tooltip\" title=\"举报\"><span class=\"glyphicon glyphicon-flag\"></span>举报</a>\n                    {# <a href=\"#\"><span class=\"glyphicon glyphicon-thumbs-down\"></span>反对</a> #}\n                    {# </div> #}\n                </td>\n            </tr>\n            {% endfor %}\n            </tbody>\n        </table>\n        {# 翻页 #}\n        {% from \"macros.html\" import render_pagination %}\n        {{ render_pagination(pagination, 'blog.hot') }}\n    </div>\n    </div>\n{% endblock %}"
  },
  {
    "path": "app_frontend/templates/blog/index.html",
    "content": "<!-- extend from base layout -->\n{% extends \"layout.html\" %}\n\n{% block content %}\n    <div class=\"container\">\n    <h2 class=\"sub-header\">Blog List!</h2>\n    <div class=\"table-responsive\">\n        {# <table class=\"table table-striped\"> #}\n        <table class=\"table table-hover\">\n            <thead>\n            <tr>\n                <th>#</th>\n                <th>id</th>\n                <th>author</th>\n                <th>title</th>\n                <th>pub_date</th>\n                <th>action</th>\n            </tr>\n            </thead>\n            <tbody>\n            {% for item in pagination.items %}\n            <tr class=\"text-muted\" id=\"blog_{{ item.id }}\">\n                <td>{{ loop.index }}</td>\n                <td>{{ item.id }}</td>\n                <td>{{ item.author }}</td>\n                <td>{{ item.title }}</td>\n                <td>{{ item.pub_date }}</td>\n                <td>\n                    {# <div class=\"pull-right\"> #}\n                        <a href=\"{{ url_for('blog.edit', blog_id=item.id, next=request.path) }}\" rel=\"tooltip\" title=\"编辑\"><span class=\"glyphicon glyphicon-pencil\"></span></a>\n{#                        <a href=\"{{ url_for('blog.delete', blog_id=item.id) }}\"><span class=\"glyphicon glyphicon-trash\"></span></a>#}\n                        <a href=\"javascript:void(0);\" onclick=\"blog_delete({{ item.id }});\" rel=\"tooltip\" title=\"删除\"><span class=\"glyphicon glyphicon-trash\"></span></a>\n                    {# </div> #}\n                </td>\n            </tr>\n            {% endfor %}\n            </tbody>\n        </table>\n        {# 翻页 #}\n        {% from \"macros.html\" import render_pagination %}\n        {{ render_pagination(pagination, 'blog.index') }}\n    </div>\n    </div>\n    <script type=\"text/javascript\">\n        function blog_delete(blog_id){\n            if(confirm(\"Are you sure?\"))\n            {\n                // console.log(blog_id);\n                $.getJSON('{{ url_for('blog.delete') }}',\n                {\n                    blog_id: blog_id\n                }, function (data) {\n                    var result = data.result;  // true/false\n                    // console.log(result==true);\n                    if(result==true){\n                        window.location.reload();\n                    }\n                });\n                return false;\n            }\n        }\n    </script>\n{% endblock %}"
  },
  {
    "path": "app_frontend/templates/blog/list_edit.html",
    "content": "<!-- extend from base layout -->\n{% extends \"layout.html\" %}\n\n{% block content %}\n    <div class=\"container\">\n        <h2 class=\"sub-header\">Blog List!\n        </h2>\n        <div class=\"row\">\n            <div class=\"table-responsive col-lg-9 col-md-12\">\n                {# <table class=\"table table-striped\"> #}\n                <table class=\"table table-hover\">\n                    <thead>\n                    <tr>\n                        <th>#</th>\n                        <th>id</th>\n                        <th>author</th>\n                        <th>title</th>\n                        <th>pub_date</th>\n                        <th>action</th>\n                    </tr>\n                    </thead>\n                    <tbody>\n                    {% for item in pagination.items %}\n                        <tr class=\"text-muted blog_tr\" id=\"blog_{{ item.id }}\">\n                            <td>{{ loop.index }}</td>\n                            <td>{{ item.id }}</td>\n                            <td>{{ item.author }}</td>\n                            <td>{{ item.title }}</td>\n                            <td>{{ item.pub_date }}</td>\n                            <td>\n                                {# <div class=\"pull-right\"> #}\n                                {#                        <a href=\"{{ url_for('blog.delete', blog_id=item.id) }}\"><span class=\"glyphicon glyphicon-trash\"></span></a>#}\n                                <a href=\"javascript:void(0);\" onclick=\"blog_delete({{ item.id }});\" rel=\"tooltip\"\n                                   title=\"删除\"><span class=\"glyphicon glyphicon-trash\"></span></a>\n                                {# </div> #}\n                            </td>\n                        </tr>\n                    {% endfor %}\n                    </tbody>\n                </table>\n                {# 翻页 #}\n                {% from \"macros.html\" import render_pagination %}\n                {{ render_pagination(pagination, 'blog_list') }}\n            </div>\n            <div class=\"col-lg-3 col-md-12\" id=\"blog_tr_edit\">\n                <section id=\"user_profile\">\n                    <div class=\"panel panel-default\">\n                        <div class=\"panel-heading\">\n                            <strong class=\"panel-title\">Blog Edit\n                                <span class=\"glyphicon glyphicon-list-alt pull-right\"></span>\n                            </strong>\n                        </div>\n                        <div class=\"panel-body\">\n                            <form id=\"blog_form_edit\" onsubmit=\"return edit_blog(this);\">\n                                <input type=\"hidden\" id=\"id\" name=\"id\">\n                                <fieldset class=\"form-group\">\n                                    <label for=\"author\">Author</label>\n                                    <input type=\"text\" class=\"form-control\" id=\"author\" name=\"author\" placeholder=\"Author\">\n                                </fieldset>\n\n                                <fieldset class=\"form-group\">\n                                    <label for=\"title\">Title</label>\n                                    <input type=\"text\" class=\"form-control\" id=\"title\" name=\"title\" placeholder=\"Title\">\n                                </fieldset>\n\n                                <fieldset class=\"form-group\">\n                                    <label for=\"pub_date\">Pub Date</label>\n                                    <input type=\"date\" class=\"form-control\" id=\"pub_date\" name=\"pub_date\" placeholder=\"Pub Date\">\n                                </fieldset>\n                                <button type=\"submit\" class=\"btn btn-success btn-load\" data-loading-text=\"Save...\">Save\n                                </button>\n                                <button type=\"reset\" class=\"btn btn-default\">Reset</button>\n                            </form>\n                        </div>\n                    </div>\n                </section>\n            </div>\n        </div>\n\n    </div>\n{% endblock %}\n\n{% block extra_js %}\n    <script type=\"text/javascript\">\n        function edit_blog(form) {\n            // console.log($(form).serialize());\n            $.ajax({\n                url: \"{{ url_for('blog.ajax_list_edit') }}\",\n                type: 'POST',\n                data: $(form).serialize(),\n                dataType: 'json',\n                success: function (result) {\n                    // console.log(result);\n                    if(result.hasOwnProperty('error')){\n                        alert(result.error);\n                    }\n                    alert(result.success);\n                }\n            });\n            $(form).button('reset');  // 重置表单 恢复保存按钮\n            // todo 更新 tr 数据(blog_id)\n            return false;\n        }\n        function blog_delete(blog_id) {\n            if (confirm(\"Are you sure?\")) {\n                // console.log(blog_id);\n                $.getJSON('{{ url_for('blog.delete') }}',\n                        {\n                            blog_id: blog_id\n                        }, function (data) {\n                            var result = data.result;  // true/false\n                            // console.log(result == true);\n                            if (result == true) {\n                                window.location.reload();\n                            }\n                        });\n                return false;\n            }\n        }\n\n        $(function () {\n            $(\".blog_tr\").click(function () {\n                $(\".blog_tr\").removeClass('active');\n                $(this).addClass('active');\n                $('#id').val($(this).children('td').eq(1)[0].innerText);\n                $('#author').val($(this).children('td').eq(2)[0].innerText);\n                $('#title').val($(this).children('td').eq(3)[0].innerText);\n                $('#pub_date').val($(this).children('td').eq(4)[0].innerText);\n            });\n        });\n    </script>\n{% endblock %}"
  },
  {
    "path": "app_frontend/templates/blog/new.html",
    "content": "<!-- extend from base layout -->\n{% extends \"layout.html\" %}\n\n{% block content %}\n    <div class=\"container\">\n    <h2 class=\"sub-header\">Blog New!</h2>\n    <div class=\"table-responsive\">\n        {# <table class=\"table table-striped\"> #}\n        <table class=\"table table-hover\">\n            <thead>\n            <tr>\n                <th>#</th>\n                <th>id</th>\n                <th>author</th>\n                <th>title</th>\n                <th>pub_date</th>\n                <th>action</th>\n            </tr>\n            </thead>\n            <tbody>\n            {% for item in pagination.items %}\n            <tr class=\"text-muted\">\n                <td>{{ loop.index }}</td>\n                <td>{{ item.id }}</td>\n                <td>{{ item.author }}</td>\n                <td>{{ item.title }}</td>\n                <td>{{ item.pub_date }}</td>\n                <td>\n                    {# <div class=\"pull-right\"> #}\n                    <a class=\"{% if not blog_container_status_list[loop.index0]['collect'] %}text-muted{% endif %}\" href=\"javascript:void(0);\" onclick=\"counter_blog({{ item.id }}, 'collect');\" rel=\"tooltip\" title=\"收藏\">\n                        <span class=\"glyphicon glyphicon-heart-empty\"></span>\n                        <span id=\"counter_collect_blog_{{ item.id }}\">{{ blog_counter_list[loop.index0]['collect'] }}</span>\n                    </a>\n                    <a class=\"{% if not blog_container_status_list[loop.index0]['favor'] %}text-muted{% endif %}\" href=\"javascript:void(0);\" onclick=\"counter_blog({{ item.id }}, 'favor');\" rel=\"tooltip\" title=\"支持\">\n                        <span class=\"glyphicon glyphicon-thumbs-up\"></span>\n                        <span id=\"counter_favor_blog_{{ item.id }}\">{{ blog_counter_list[loop.index0]['favor'] }}</span>\n                    </a>\n                    <a class=\"{% if not blog_container_status_list[loop.index0]['flag'] %}text-muted{% endif %}\" href=\"javascript:void(0);\" onclick=\"counter_blog({{ item.id }}, 'flag');\" rel=\"tooltip\" title=\"举报\">\n                        <span class=\"glyphicon glyphicon-flag\"></span>\n                        <span id=\"counter_flag_blog_{{ item.id }}\">{{ blog_counter_list[loop.index0]['flag'] }}</span>\n                    </a>\n                    {# <a href=\"#\"><span class=\"glyphicon glyphicon-thumbs-down\"></span>反对</a> #}\n                    {# </div> #}\n                </td>\n            </tr>\n            {% endfor %}\n            </tbody>\n        </table>\n        {# 翻页 #}\n        {% from \"macros.html\" import render_pagination %}\n        {{ render_pagination(pagination, 'blog.new') }}\n    </div>\n    </div>\n    <script type=\"text/javascript\">\n        function counter_blog(blog_id, stat_type){\n            $.getJSON('{{ url_for('blog.stat') }}',\n            {\n                blog_id: blog_id,\n                stat_type: stat_type\n            }, function (data) {\n                // console.log(data);\n                {# {\"count\": {\"collect\": \"0\", \"favor\": \"1\", \"flag\": \"0\", \"view\": \"0\"}, \"status\": {\"collect\": false, \"favor\": true, \"flag\": false}} #}\n                var counter_collect_blog = $('#counter_collect_blog_'+blog_id);\n                var counter_favor_blog = $('#counter_favor_blog_'+blog_id);\n                var counter_flag_blog = $('#counter_flag_blog_'+blog_id);\n                counter_collect_blog.text(data['count']['collect']);\n                counter_favor_blog.text(data['count']['favor']);\n                counter_flag_blog.text(data['count']['flag']);\n                if(data['status']['collect'] == true){\n                    counter_collect_blog.parents('a').removeClass('text-muted');\n                }\n                if(data['status']['favor'] == true){\n                    counter_favor_blog.parents('a').removeClass('text-muted');\n                }\n                if(data['status']['flag'] == true){\n                    counter_flag_blog.parents('a').removeClass('text-muted');\n                }\n            });\n        }\n    </script>\n{% endblock %}"
  },
  {
    "path": "app_frontend/templates/complaint/add.html",
    "content": "<!-- extend from base layout -->\n{% extends \"layout.html\" %}\n\n{% block content %}\n    <div class=\"container\">\n    <ol class=\"breadcrumb\">\n        <li><a href=\"/\">首页</a></li>\n        <li class=\"active\">消息中心</li>\n        <li class=\"active\">我要投诉</li>\n    </ol>\n    <div class=\"row\">\n        <div class=\"table-responsive col-lg-8 col-md-12\">\n            <form class=\"form-horizontal\" method=\"post\" action=\"\">\n                {{ form.csrf_token }}\n                <div class=\"form-group{% if form.user_id.errors %} has-error{% endif %}\">\n                    {{ form.user_id.label(class=\"col-sm-2 control-label\") }}\n                    <div class=\"col-sm-10\">\n                        <div class=\"form-control\">{{ form.user_id.data | nickname }}</div>\n                    </div>\n                </div>\n\n                <div class=\"form-group{% if form.content.errors %} has-error{% endif %}\">\n                    {{ form.content.label(class=\"col-sm-2 control-label\") }}\n                    <div class=\"col-sm-10\">\n                        {{ form.content(class=\"form-control\", placeholder=\"投诉内容\", rows=\"6\") }}\n                        {% for error in form.content.errors %}\n                            <span class=\"help-block\">{{ error }}</span>\n                        {% endfor %}\n                    </div>\n                </div>\n                <div class=\"form-group\">\n                    <div class=\"col-sm-offset-2 col-sm-10\">\n                        <button type=\"submit\" class=\"btn btn-success btn-load\" data-loading-text=\"投诉中\">投诉</button>\n                        <button type=\"reset\" class=\"btn btn-default\">重新填写</button>\n                        <button class=\"btn btn-default\" onclick=\"history.back();\">返回</button>\n                    </div>\n                </div>\n            </form>\n        </div>\n        <!-- 用户概要 -->\n        <div class=\"col-lg-4 col-md-12\">\n            <!-- 状态信息 -->\n            {% include('user/_status.html') %}\n            <!-- 推广链接 -->\n            {% include('user/_invite_link.html') %}\n            <!-- 账户信息 -->\n            {% include('user/_account_info.html') %}\n            <!-- 我的团队 -->\n            {% include('user/_team_tree.html') %}\n        </div>\n    </div>\n    </div>\n{% endblock %}\n\n{% block extra_js %}\n<script src=\"{{ url_for('static', filename='plugin/clipboard.js-1.6.1/dist/clipboard.min.js') }}\"></script>\n\n<script>\n    //推广链接复制\n    var clipboard = new Clipboard('.btn');\n\n    clipboard.on('success', function(e) {\n        // console.info('Action:', e.action);\n        // console.info('Text:', e.text);\n        // console.info('Trigger:', e.trigger);\n        e.clearSelection();\n        alert('复制成功，粘贴使用推广链接');\n    });\n\n    clipboard.on('error', function(e) {\n        // console.error('Action:', e.action);\n        // console.error('Trigger:', e.trigger);\n        alert('操作失败，重新复制推广链接');\n    });\n</script>\n{% endblock %}\n"
  },
  {
    "path": "app_frontend/templates/complaint/list.html",
    "content": "<!-- extend from base layout -->\n{% extends \"layout.html\" %}\n\n{% block extra_css %}\n\n{% endblock %}\n\n{% block content %}\n    <div class=\"container\">\n    <!-- header -->\n    <nav class=\"sub-header row container-fluid\">\n        <ol class=\"breadcrumb\">\n            <li><a href=\"/\">首页</a></li>\n            <li class=\"active\">消息中心</li>\n            <li class=\"active\">投诉记录</li>\n        </ol>\n        <div class=\"btn-group pull-right\" role=\"group\" aria-label=\"...\">\n        {% if request.query_string == 'status_reply=1' %}\n            <a type=\"button\" class=\"btn btn-default\" href=\"{{ url_for('complaint.lists') }}\">未处理</a>\n            <a type=\"button\" class=\"btn btn-default active\">已处理</a>\n        {% else %}\n            <a type=\"button\" class=\"btn btn-default active\">未处理</a>\n            <a type=\"button\" class=\"btn btn-default\" href=\"{{ url_for('complaint.lists', status_reply=1) }}\">已处理</a>\n        {% endif %}\n        </div>\n    </nav>\n\n    <hr/>\n    <!-- content -->\n    <div class=\"table-responsive\">\n        {# <table class=\"table table-striped\"> #}\n        <table class=\"table table-hover\">\n            <thead>\n            <tr>\n                <th>投诉明细ID</th>\n                <th>投诉用户</th>\n                <th>被投诉用户</th>\n                <th>投诉内容</th>\n                <th>投诉时间</th>\n                {% if request.query_string == 'status_reply=1' %}\n                <th>回复内容</th>\n                <th>回复时间</th>\n                {% endif %}\n            </tr>\n            </thead>\n            <tbody>\n            {% for msg, user_profile_put, user_profile_get in pagination.items %}\n            <tr class=\"text-muted\">\n                <td>{{ msg.id }}</td>\n                <td>{{ user_profile_put.nickname | default('系统消息') }} [{{ user_profile_put.user_id }}]</td>\n                <td>{{ user_profile_get.nickname }} [{{ user_profile_get.user_id }}]</td>\n                <td>{{ msg.content }}</td>\n                <td>{{ moment(msg.create_time).format('YYYY-MM-DD HH:mm:ss') }}</td>\n                {% if request.query_string == 'status_reply=1' %}\n                <td>{{ msg.content_reply }}</td>\n                <td>{{ moment(msg.reply_time).format('YYYY-MM-DD HH:mm:ss') }}</td>\n                {% endif %}\n            </tr>\n            {% endfor %}\n            </tbody>\n        </table>\n        {# 翻页 #}\n        {% from \"macros.html\" import render_pagination %}\n        {{ render_pagination(pagination, 'complaint.lists') }}\n    </div>\n    </div>\n{% endblock %}\n\n{% block extra_js %}\n\n{% endblock %}\n"
  },
  {
    "path": "app_frontend/templates/contact.html",
    "content": "{% extends \"layout.html\" %}\n\n{% block content %}\n    <div class=\"container\">\n        <h2>contact us!</h2>\n        <div class=\"row\">\n            <div class=\"col-lg-8 col-md-12\">\n\n                <form action=\"\" method=\"post\" id=\"contact-form\">\n                <div class=\"col-md-6\">\n               \t\t<fieldset class=\"form-group\">\n                        <label for=\"name\">Your Name</label>\n                        <input type=\"text\" class=\"form-control\" id=\"name\" placeholder=\"Write a full name\">\n                  \t</fieldset>\n\n                  \t<fieldset class=\"form-group\">\n                    \t<label for=\"email\">Your Email</label>\n                    \t<input type=\"email\" class=\"form-control\" id=\"email\" placeholder=\"Enter your email\">\n                  \t</fieldset>\n\n                    <fieldset class=\"form-group\">\n                    \t<label for=\"company\">Your Company</label>\n                    \t<input type=\"text\" class=\"form-control\" id=\"company\" placeholder=\"Enter your company\">\n                  \t</fieldset>\n                </div>\n                <div class=\"col-md-6\">\n\n                 \t<fieldset class=\"form-group\">\n                        <label for=\"subject\">Subject</label>\n                        <input type=\"text\" class=\"form-control\" id=\"subject\" placeholder=\"Subject\">\n                  \t</fieldset>\n\n                  \t<fieldset class=\"form-group\">\n                    \t<label for=\"message\">Your Message</label>\n                    \t<textarea class=\"form-control\" id=\"message\" rows=\"4\" placeholder=\"Write a message\"></textarea>\n                  \t</fieldset>\n\n                  \t<div class=\"checkbox\">\n                    \t<label>\n                      \t\t<input type=\"checkbox\"> I am not a robot.\n                    \t</label>\n                  \t</div>\n\n                    <button type=\"submit\" class=\"btn btn-success btn-load\" data-loading-text=\"Submit...\">Submit</button>\n                </div>\n            \t</form>\n\n            </div>\n\n\t\t\t<div class=\"col-lg-4 col-md-12\">\n        \t\t<h3>Contact Information</h3>\n                <hr/>\n                <p class=\"git_hub\">\n                <iframe src=\"https://ghbtns.com/github-btn.html?user=zhanghe06&repo=flask_project&type=star&count=true&size=large\" frameborder=\"0\" scrolling=\"0\" width=\"100%\" height=\"30px\"></iframe>\n                <iframe src=\"https://ghbtns.com/github-btn.html?user=zhanghe06&repo=flask_project&type=watch&count=true&size=large&v=2\" frameborder=\"0\" scrolling=\"0\" width=\"100%\" height=\"30px\"></iframe>\n                <iframe src=\"https://ghbtns.com/github-btn.html?user=zhanghe06&repo=flask_project&type=fork&count=true&size=large\" frameborder=\"0\" scrolling=\"0\" width=\"100%\" height=\"30px\"></iframe>\n                <iframe src=\"https://ghbtns.com/github-btn.html?user=zhanghe06&type=follow&count=true&size=large\" frameborder=\"0\" scrolling=\"0\" width=\"100%\" height=\"30px\"></iframe>\n                </p>\n                <hr/>\n                <p><span class=\"glyphicon glyphicon-map-marker\"></span> Address: Level 10, No.700, East Yanan Road, Huangpu District, ShangHai, P. R. China</p>\n          \t\t<p><span class=\"glyphicon glyphicon-envelope\"></span> Email: info@company.com</p>\n                <p><span class=\"glyphicon glyphicon-phone-alt\"></span> Phone: 021-8888-6666</p>\n                <p><span class=\"glyphicon glyphicon-phone\"></span> Mobile: 138-1873-2593</p>\n                <hr/>\n            </div>\n        </div>\n    </div>\n{% endblock %}"
  },
  {
    "path": "app_frontend/templates/credit/index.html",
    "content": "{% extends \"layout.html\" %}\n\n{% block content %}\n    <div class=\"container\">\n    <h2 class=\"sub-header\">Credit</h2>\n    <section id=\"chart_line_graphs\">\n        <div class=\"panel panel-default\">\n            <div class=\"panel-heading\">\n                <strong class=\"panel-title\">Chart Radar Graphs\n                <span class=\"glyphicon glyphicon-picture pull-right\"></span>\n                </strong>\n            </div>\n            <div class=\"panel-body text-center row\">\n                <div class=\"col-lg-12 col-md-12 col-sm-12 col-xs-12\">\n                    <canvas id=\"radar_chart\" width=\"360\" height=\"180\"></canvas>\n                </div>\n            </div>\n        </div>\n    </section>\n\n    </div>\n{% endblock %}\n\n{% block extra_js %}\n    <script>\n        var radar_data_keys = ['行为偏好', '身份特质', '人脉关系', '信用历史', '履约能力'];\n        var radar_data_values = [20, 20, 20, 20, 20]; // 仅仅显示基础分值\n\n        $(function () {\n            $.getJSON('{{ url_for('credit.ajax_get_user_data') }}',\n                {}, function (data) {\n                    var result = data.result;  // true/false\n                    // console.log(result == true);\n                    if (result == true) {\n                        var data_values = data.values;\n                        // 字符串转整数\n                        radar_data_values[0] = parseInt(data_values[0]);\n                        radar_data_values[1] = parseInt(data_values[1]);\n                        radar_data_values[2] = parseInt(data_values[2]);\n                        radar_data_values[3] = parseInt(data_values[3]);\n                        radar_data_values[4] = parseInt(data_values[4]);\n                        // console.log(radar_data_values);\n                    }\n                    var radar_data = {\n                        labels: radar_data_keys,\n                        datasets: [\n                            {\n                                fillColor: \"rgba(220,220,220,0.5)\",\n                                strokeColor: \"rgba(220,220,220,1)\",\n                                pointColor: \"rgba(220,220,220,1)\",\n                                pointStrokeColor: \"#fff\",\n                                data: radar_data_values\n                            }\n                        ]\n                    };\n                    var ctx = $(\"#radar_chart\").get(0).getContext(\"2d\");\n                    new Chart(ctx).Radar(radar_data, {responsive: true, pointLabelFontSize : 14});\n                }\n            );\n\n        });\n    </script>\n{% endblock %}\n"
  },
  {
    "path": "app_frontend/templates/email.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n    <meta charset=\"UTF-8\">\n    <title>系统邮件</title>\n</head>\n<body>\n<p>Dear Admin,</p>\n<p style=\"text-indent:2em;\">\n    This is a Bug!\nPlease Fix It!\n</p>\n\n<h3>Bug Information</h3>\n<p>\n{{ message }}\n</p>\n\n<h3>Contact Information</h3>\n<p>\nAddress: Level 10, No.700, East Yanan Road, Huangpu District, Shanghai, P. R. China<br />\nEmail: info@company.com<br />\nPhone: 021-8888-6666<br />\nMobile: 138-1873-2593\n</p>\n\n<p>Regards,</p>\n<p>The <code>flask app</code> Dev Team</p>\n</body>\n</html>"
  },
  {
    "path": "app_frontend/templates/index.html",
    "content": "{% extends \"layout.html\" %}\n\n{% block content %}\n<!-- .carousel -->\n<div id=\"myCarousel\" class=\"carousel slide\" data-ride=\"carousel\">\n    <!-- Indicators -->\n    <ol class=\"carousel-indicators\">\n        {% for i in range(6) %}\n            <li data-target=\"#myCarousel\" data-slide-to=\"{{ i }}\"{% if i==0 %} class=\"active\"{% endif %}></li>\n        {% endfor %}\n    </ol>\n\n    <div class=\"carousel-inner\">\n        {% for i in range(1,7) %}\n        <div class=\"item{% if i==1 %} active{% endif %}\">\n            <img class=\"lazy center-block img-responsive\" src=\"{{ url_for('static', filename='img/load-line.gif') }}\" data-src=\"/static/img/{{ i }}.jpg\" alt=\"{{ loop.index }} slide\">\n            <div class=\"container\">\n                <div class=\"carousel-caption\">\n                    <h1>{{ loop.index }} slide</h1>\n                    <div class=\"visible-lg\">\n                        <p><span class=\"glyphicon glyphicon-map-marker\"></span> Address: Level 10, No.700, East Yanan Road, Huangpu District, Shanghai, P. R. China</p>\n                        <p><span class=\"glyphicon glyphicon-envelope\"></span> Email: info@company.com</p>\n                        <p><span class=\"glyphicon glyphicon-phone-alt\"></span> Phone: 021-8888-6666</p>\n                        <p><span class=\"glyphicon glyphicon-phone\"></span> Mobile: 138-1873-2593</p>\n                        <p><a class=\"btn btn-lg btn-primary\" href=\"#\" role=\"button\">Enter Info</a></p>\n                    </div>\n                </div>\n            </div>\n        </div>\n        {% endfor %}\n    </div>\n    <a class=\"left carousel-control\" href=\"#myCarousel\" data-slide=\"prev\">\n        <span class=\"glyphicon glyphicon-chevron-left\"></span>\n    </a>\n    <a class=\"right carousel-control\" href=\"#myCarousel\" data-slide=\"next\">\n        <span class=\"glyphicon glyphicon-chevron-right\"></span>\n    </a>\n</div><!-- /.carousel -->\n\n{% endblock %}"
  },
  {
    "path": "app_frontend/templates/layout.html",
    "content": "<!DOCTYPE html>\n<html lang=\"zh-CN\">\n<head>\n    <meta charset=\"utf-8\">\n    <meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\">\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">\n    <meta name=\"keywords\" content=\"\">\n    <meta name=\"description\" content=\"\">\n    <meta name=\"author\" content=\"\">\n    {# <link rel=\"icon\" href=\"{{ url_for('static', _external=True, filename='img/favicon.ico') }}\"> #}\n    <link rel=\"shortcut icon\" href=\"{{ url_for('static', filename='img/favicon.ico') }}\">\n    {% if title %}\n    <title>{{ title }} - flask_project</title>\n    {% else %}\n    <title>flask_project</title>\n    {% endif %}\n    <!-- Bootstrap -->\n    <link href=\"{{ url_for('static', filename='css/bootstrap.min.css') }}\" rel=\"stylesheet\">\n    <link href=\"{{ url_for('static', filename='css/bootstrap-theme.min.css') }}\" rel=\"stylesheet\">\n    <!-- Plugin -->\n    <link href=\"{{ url_for('static', filename='css/slideout.css') }}\" rel=\"stylesheet\">\n    <link href=\"{{ url_for('static', filename='css/bootstrap-select.min.css') }}\" rel=\"stylesheet\">\n    <!-- Custom -->\n    <link href=\"{{ url_for('static', filename='css/custom.css', v='1.4.107') }}\" rel=\"stylesheet\">\n    {% block extra_css %}{% endblock %}\n    <!-- HTML5 shim and Respond.js for IE8 support of HTML5 elements and media queries -->\n    <!-- WARNING: Respond.js doesn't work if you view the page via file:// -->\n    <!--[if lt IE 9]>\n      <script src=\"https://oss.maxcdn.com/html5shiv/3.7.3/html5shiv.min.js\"></script>\n      <script src=\"https://oss.maxcdn.com/respond/1.4.2/respond.min.js\"></script>\n    <![endif]-->\n</head>\n<body data-spy=\"scroll\" data-target=\"#affix_nav\">\n    <!-- Fixed navbar -->\n    {% include '_top.html' %}\n\n{#    <div id=\"panel\" class=\"page-panel\">#}\n    <div class=\"container\">\n    {# 闪现消息 success info warning danger #}\n    {% with messages = get_flashed_messages(with_categories=true) %}\n    {% if messages %}\n    {% for category, message in messages %}\n        <div class=\"container alert alert-{{ category }} alert-fixed-top\" role=\"alert\">\n            <button type=\"button\" class=\"close\" data-dismiss=\"alert\" aria-hidden=\"true\">&times;</button>\n            {{ message }}\n        </div>\n    {% endfor %}\n    {% endif %}\n    {% endwith %}\n    </div>\n    {% block content %}{% endblock %}\n    <!-- Fixed Footer -->\n    {% include '_footer.html' %}\n{#    </div>#}\n\n    <!-- jQuery (necessary for Bootstrap's JavaScript plugins) -->\n    <script src=\"{{ url_for('static', filename='js/jquery-1.11.3.min.js') }}\"></script>\n    <!-- Include all compiled plugins (below), or include individual files as needed -->\n    <script src=\"{{ url_for('static', filename='js/bootstrap.min.js') }}\"></script>\n    <!-- Include all compiled plugins (below), or include individual files as needed -->\n    <script src=\"{{ url_for('static', filename='plugin/Chart/Chart.min.js') }}\"></script>\n    <script src=\"{{ url_for('static', filename='plugin/Slideout/slideout.min.js') }}\"></script>\n    <script src=\"{{ url_for('static', filename='js/bootstrap-select.min.js') }}\"></script>\n    <script src=\"{{ url_for('static', filename='plugin/moment-2.18.1/min/moment-with-locales.min.js') }}\"></script>\n    <script>\n        moment.locale(\"zh-cn\");\n        function flask_moment_render(elem) {\n            $(elem).text(eval('moment(\"' + $(elem).data('timestamp') + '\").' + $(elem).data('format') + ';'));\n            $(elem).removeClass('flask-moment').show();\n        }\n        function flask_moment_render_all() {\n            $('.flask-moment').each(function () {\n                flask_moment_render(this);\n                if ($(this).data('refresh')) {\n                    (function (elem, interval) {\n                        setInterval(function () {\n                            flask_moment_render(elem)\n                        }, interval);\n                    })(this, $(this).data('refresh'));\n                }\n            })\n        }\n        $(document).ready(function () {\n            flask_moment_render_all();\n        });\n    </script>\n    <!-- Custom -->\n    <script src=\"{{ url_for('static', filename='js/custom.js', v='1.4.76') }}\"></script>\n    {% block extra_js %}{% endblock %}\n</body>\n</html>"
  },
  {
    "path": "app_frontend/templates/logout.html",
    "content": "{% extends \"layout.html\" %}\n\n{% block content %}\n    Logout!\n{% endblock %}"
  },
  {
    "path": "app_frontend/templates/macros.html",
    "content": "{% macro render_pagination(pagination, endpoint) %}\n    {% if pagination.pages > 0 %}\n    <nav class=\"text-center\">\n        <ul class=\"pagination\">\n            <li>\n                {% if pagination.has_prev %}\n                    <a href=\"{{ url_for(endpoint, page=pagination.prev_num, **request.args) }}\" aria-label=\"Previous\">\n                {% else %}\n                    <a href=\"javascript:void(0);\" aria-label=\"Previous\">\n                {% endif %}\n                <span aria-hidden=\"true\">&laquo;</span>\n                </a>\n            </li>\n            {% for page in pagination.iter_pages() %}\n                {% if page %}\n                    {% if page == pagination.page %}\n                        <li class=\"active\">\n                            {% else %}\n                        <li>\n                    {% endif %}\n                <a href=\"{{ url_for(endpoint, page=page, **request.args) }}\">{{ page }}</a>\n                </li>\n                {% endif %}\n            {% endfor %}\n            <li>\n                {% if pagination.has_next %}\n                    <a href=\"{{ url_for(endpoint, page=pagination.next_num, **request.args) }}\" aria-label=\"Next\">\n                {% else %}\n                    <a href=\"javascript:void(0);\" aria-label=\"Next\">\n                {% endif %}\n                <span aria-hidden=\"true\">&raquo;</span>\n                </a>\n            </li>\n        </ul>\n    </nav>\n    {% else %}\n    <section id=\"nothing\">\n        <div class=\"well well-large text-center\">\n            记录为空\n        </div>\n    </section>\n    {% endif %}\n{% endmacro %}\n\n\n<!-- 停用 -->\n{% macro render_ground(title) %}\n    {#    <nav class=\"navbar navbar-default\">#}\n    <nav class=\"page-menu navbar-default\" id=\"menu\">\n        <div class=\"container\">\n            <div class=\"navbar-header\">\n            </div>\n            <div class=\"collapse in\" aria-expanded=\"true\">\n                <ul class=\"nav navbar-nav\">\n                    <li{% if title == 'home' %} class=\"active\"{% endif %}><a href=\"{{ url_for('index') }}\"><span\n                            class=\"glyphicon glyphicon-home\"></span> Home</a></li>\n                    <li{% if title == 'about' %} class=\"active\"{% endif %}><a href=\"{{ url_for('about') }}\"><span\n                            class=\"glyphicon glyphicon-list\"></span> About</a></li>\n                    <li{% if title == 'contact' %} class=\"active\"{% endif %}><a href=\"{{ url_for('contact') }}\"><span\n                            class=\"glyphicon glyphicon-envelope\"></span> Contact</a></li>\n                    <li class=\"dropdown\">\n                        <a href=\"#\" class=\"dropdown-toggle\" data-toggle=\"dropdown\" role=\"button\" aria-haspopup=\"true\"\n                           aria-expanded=\"false\"><span class=\"glyphicon glyphicon-book\"></span> Blog List <span\n                                class=\"caret\"></span></a>\n                        <ul class=\"dropdown-menu\">\n                            {% if title == 'blog_list' %}\n                                <li class=\"dropdown-header\">Blog List</li>{% else %}\n                                <li><a href=\"{{ url_for('blog.index') }}\">Blog List</a></li>{% endif %}\n                            {% if title == 'blog_new' %}\n                                <li class=\"dropdown-header\">Blog New</li>{% else %}\n                                <li><a href=\"{{ url_for('blog.new') }}\">Blog New</a></li>{% endif %}\n                            {% if title == 'blog_hot' %}\n                                <li class=\"dropdown-header\">Blog Hot</li>{% else %}\n                                <li><a href=\"{{ url_for('blog.hot') }}\">Blog Hot</a></li>{% endif %}\n                        </ul>\n                    </li>\n                </ul>\n                <form class=\"navbar-form navbar-left\" role=\"search\" action=\"{{ url_for('search') }}\">\n                    <div class=\"input-group\">\n                        <input type=\"text\" class=\"form-control\" placeholder=\"Search for...\" speech x-webkit-speech\n                               onwebkitspeechchange=\"$(this).cloest('form').submit()\">\n                        <span class=\"input-group-btn\">\n                            <button class=\"btn btn-default\" type=\"submit\"><span class=\"glyphicon glyphicon-search\"></span></button>\n                        </span>\n                    </div>\n                </form>\n                <ul class=\"nav navbar-nav navbar-right\">\n                    {% if current_user and current_user.is_authenticated %}\n                        <li class=\"dropdown\">\n                            <a href=\"#\" class=\"dropdown-toggle\" data-toggle=\"dropdown\" role=\"button\"\n                               aria-haspopup=\"true\"\n                               aria-expanded=\"false\"><span\n                                    class=\"glyphicon glyphicon-user\"></span> {{ current_user.id }}<span\n                                    class=\"caret\"></span></a>\n                            <ul class=\"dropdown-menu\">\n                                <li><a href=\"{{ url_for('blog.add') }}\"><span class=\"glyphicon glyphicon-edit\"></span>\n                                    Add Blog</a></li>\n                                <li><a href=\"{{ url_for('user.setting') }}\"><span class=\"glyphicon glyphicon-cog\"></span>\n                                    Setting</a></li>\n                                <li role=\"separator\" class=\"divider\"></li>\n                                <li><a href=\"{{ url_for('auth.logout') }}\"><span class=\"glyphicon glyphicon-log-out\"></span>\n                                    Logout</a></li>\n                            </ul>\n                        </li>\n                    {% else %}\n                        <li{% if title == 'reg' %} class=\"active\"{% endif %}><a href=\"{{ url_for('reg.index') }}\"><span\n                                class=\"glyphicon glyphicon-list-alt\"></span> Register</a></li>\n                        <li{% if title == 'login' %} class=\"active\"{% endif %}><a href=\"{{ url_for('auth.index') }}\"><span\n                                class=\"glyphicon glyphicon-log-in\"></span> Login</a></li>\n                    {% endif %}\n                </ul>\n            </div><!--/.nav-collapse -->\n        </div>\n    </nav>\n{% endmacro %}\n\n\n{% macro render_team_tree(team_tree) %}\n<!-- 一级 -->\n<ul>\n{% for i in team_tree %}\n    <li class=\"list-unstyled\">\n        <a href=\"javascript:void(0);\">{{ i[1] }} [{{ i[0] }}] [{{ i[2] | type_level }}]</a>\n        <!-- 二级 -->\n        <ul>\n        {% for o in team_tree[i] %}\n            <li class=\"list-unstyled\">\n                <a href=\"javascript:void(0);\">{{ o[1] }} [{{ o[0] }}] [{{ o[2] | type_level }}]</a>\n                <!-- 三级 -->\n                <ul>\n                {% for p in team_tree[i][o] %}\n                    <li class=\"list-unstyled\"><a href=\"javascript:void(0);\">{{ p[1] }} [{{ p[0] }}] [{{ p[2] | type_level }}]</a></li>\n                {% endfor %}\n                </ul>\n            </li>\n        {% endfor %}\n        </ul>\n    </li>\n{% endfor %}\n</ul>\n{% endmacro %}\n"
  },
  {
    "path": "app_frontend/templates/message/add.html",
    "content": "<!-- extend from base layout -->\n{% extends \"layout.html\" %}\n\n{% block content %}\n    <div class=\"container\">\n    <ol class=\"breadcrumb\">\n        <li><a href=\"/\">首页</a></li>\n        <li class=\"active\">消息中心</li>\n        <li class=\"active\">添加留言</li>\n    </ol>\n    <div class=\"row\">\n        <div class=\"table-responsive col-lg-8 col-md-12\">\n            <form class=\"form-horizontal\" method=\"post\" action=\"\">\n                {{ form.csrf_token }}\n                <div class=\"form-group{% if form.user_id.errors %} has-error{% endif %}\">\n                    {{ form.user_id.label(class=\"col-sm-2 control-label\") }}\n                    <div class=\"col-sm-10\">\n                        <div class=\"form-control\">{{ form.user_id.data | nickname }}</div>\n                    </div>\n                </div>\n\n                <div class=\"form-group{% if form.content.errors %} has-error{% endif %}\">\n                    {{ form.content.label(class=\"col-sm-2 control-label\") }}\n                    <div class=\"col-sm-10\">\n                        {{ form.content(class=\"form-control\", placeholder=\"留言内容\", rows=\"6\") }}\n                        {% for error in form.content.errors %}\n                            <span class=\"help-block\">{{ error }}</span>\n                        {% endfor %}\n                    </div>\n                </div>\n                <div class=\"form-group\">\n                    <div class=\"col-sm-offset-2 col-sm-10\">\n                        <button type=\"submit\" class=\"btn btn-success btn-load\" data-loading-text=\"留言中\">留言</button>\n                        <button type=\"reset\" class=\"btn btn-default\">重新填写</button>\n                        <button class=\"btn btn-default\" onclick=\"history.back();\">返回</button>\n                    </div>\n                </div>\n            </form>\n        </div>\n        <!-- 用户概要 -->\n        <div class=\"col-lg-4 col-md-12\">\n            <!-- 状态信息 -->\n            {% include('user/_status.html') %}\n            <!-- 推广链接 -->\n            {% include('user/_invite_link.html') %}\n            <!-- 账户信息 -->\n            {% include('user/_account_info.html') %}\n            <!-- 我的团队 -->\n            {% include('user/_team_tree.html') %}\n        </div>\n    </div>\n    </div>\n{% endblock %}\n\n{% block extra_js %}\n<script src=\"{{ url_for('static', filename='plugin/clipboard.js-1.6.1/dist/clipboard.min.js') }}\"></script>\n\n<script>\n    //推广链接复制\n    var clipboard = new Clipboard('.btn');\n\n    clipboard.on('success', function(e) {\n        // console.info('Action:', e.action);\n        // console.info('Text:', e.text);\n        // console.info('Trigger:', e.trigger);\n        e.clearSelection();\n        alert('复制成功，粘贴使用推广链接');\n    });\n\n    clipboard.on('error', function(e) {\n        // console.error('Action:', e.action);\n        // console.error('Trigger:', e.trigger);\n        alert('操作失败，重新复制推广链接');\n    });\n</script>\n{% endblock %}\n"
  },
  {
    "path": "app_frontend/templates/message/list.html",
    "content": "<!-- extend from base layout -->\n{% extends \"layout.html\" %}\n\n{% block extra_css %}\n\n{% endblock %}\n\n{% block content %}\n    <div class=\"container\">\n    <!-- header -->\n    <nav class=\"sub-header row container-fluid\">\n        <ol class=\"breadcrumb\">\n            <li><a href=\"/\">首页</a></li>\n            <li class=\"active\">消息中心</li>\n            <li class=\"active\">留言记录</li>\n        </ol>\n        <div class=\"btn-group pull-right\" role=\"group\" aria-label=\"...\">\n        {% if request.query_string == 'msg_type=send' %}\n            <a type=\"button\" class=\"btn btn-default\" href=\"{{ url_for('message.lists') }}\">接收</a>\n            <a type=\"button\" class=\"btn btn-default active\">发送</a>\n        {% else %}\n            <a type=\"button\" class=\"btn btn-default active\">接收</a>\n            <a type=\"button\" class=\"btn btn-default\" href=\"{{ url_for('message.lists', msg_type='send') }}\">发送</a>\n        {% endif %}\n        </div>\n    </nav>\n\n    <hr/>\n    <!-- content -->\n    <div class=\"table-responsive\">\n        {# <table class=\"table table-striped\"> #}\n        <table class=\"table table-hover\">\n            <thead>\n            <tr>\n                <th>消息明细ID</th>\n                <th>发送用户</th>\n                <th>接收用户</th>\n                <th>消息</th>\n                <th>时间</th>\n            </tr>\n            </thead>\n            <tbody>\n            {% for msg, user_profile_put, user_profile_get in pagination.items %}\n            <tr class=\"text-muted\">\n                <td>{{ msg.id }}</td>\n                <td>{{ user_profile_put.nickname | default('系统消息') }} [{{ user_profile_put.user_id }}]</td>\n                <td>{{ user_profile_get.nickname }} [{{ user_profile_get.user_id }}]</td>\n                <td>{{ msg.content }}</td>\n                <td>{{ moment(msg.create_time).format('YYYY-MM-DD HH:mm:ss') }}</td>\n            </tr>\n            {% endfor %}\n            </tbody>\n        </table>\n        {# 翻页 #}\n        {% from \"macros.html\" import render_pagination %}\n        {{ render_pagination(pagination, 'message.lists') }}\n    </div>\n    </div>\n{% endblock %}\n\n{% block extra_js %}\n\n{% endblock %}\n"
  },
  {
    "path": "app_frontend/templates/order/get_info.html",
    "content": "{% extends \"layout.html\" %}\n\n{% block extra_css %}\n    <!-- blueimp Gallery styles -->\n    <link rel=\"stylesheet\" href=\"{{ url_for('static', filename='plugin/Gallery-2.25.0/css/blueimp-gallery.min.css') }}\">\n    <!-- CSS to style the file input field as button and adjust the Bootstrap progress bars -->\n    <link rel=\"stylesheet\" href=\"{{ url_for('static', filename='plugin/jQuery-File-Upload-9.18.0/css/jquery.fileupload.css') }}\">\n    <link rel=\"stylesheet\" href=\"{{ url_for('static', filename='plugin/jQuery-File-Upload-9.18.0/css/jquery.fileupload-ui.css') }}\">\n    <!-- CSS adjustments for browsers with JavaScript disabled -->\n    <noscript><link rel=\"stylesheet\" href=\"{{ url_for('static', filename='plugin/jQuery-File-Upload-9.18.0/css/jquery.fileupload-noscript.css') }}\"></noscript>\n    <noscript><link rel=\"stylesheet\" href=\"{{ url_for('static', filename='plugin/jQuery-File-Upload-9.18.0/css/jquery.fileupload-ui-noscript.css') }}\"></noscript>\n{% endblock %}\n\n{% block content %}\n<div class=\"container\">\n    <h2 class=\"lead\">\n    {% if order_info.pay_time %}\n        <p class=\"text-warning\">\n        付款时间：[{{ moment(order_info.pay_time).format('YYYY-MM-DD HH:mm:ss') }}]\n        </p>\n    {% else %}\n        <p class=\"text-warning\">\n        等待对方付款，剩余付款时间：[{{ moment(order_info.create_time | time_delta(3600*24*2)).fromNow(refresh=True) }}]\n        </p>\n    {% endif %}\n    {% if order_info.rec_time %}\n        <p class=\"text-warning\">\n        确认收款时间：[{{ moment(order_info.rec_time).format('YYYY-MM-DD HH:mm:ss') }}]\n        </p>\n    {% elif order_info.pay_time %}\n        <p class=\"text-warning\">\n        剩余确认时间：[{{ moment(order_info.pay_time | time_delta(3600*24*2)).fromNow(refresh=True) }}]\n        </p>\n    {% endif %}\n    </h2>\n    <br>\n{#    <blockquote>#}\n{#        <p class=\"text-muted\">奖励规则：提前（1小时内）确认，奖励利息（2%）</p>#}\n{#        <p class=\"text-muted\">惩罚规则：延迟（超过24小时）确认，扣除罚息（2%）；<br/>收款后超过48小时不确认，系统自动进行确认，并立即封号，收款方需联系客服解封账户</p>#}\n{#        <footer>规则最终解释 <cite title=\"Source Title\">运营团队</cite></footer>#}\n{#    </blockquote>#}\n    <section id=\"order_info\">\n        <div class=\"panel panel-default\">\n        <div class=\"panel-heading\">\n            <strong class=\"panel-title\">订单信息\n            <span class=\"glyphicon glyphicon-cog pull-right\"></span>\n            </strong>\n        </div>\n        <table class=\"table table-hover table-responsive\">\n            <thead>\n                <tr>\n                    <th>订单ID</th>\n                    <th>用户ID</th>\n                    <th>用户名称</th>\n                    <th>订单类型</th>\n                    <th>订单金额</th>\n                    <th>审核状态</th>\n                    <th>支付状态</th>\n                    <th>收款状态</th>\n                    <th>删除状态</th>\n                    <th>订单时间</th>\n                </tr>\n            </thead>\n            <tbody>\n                <tr>\n                    <td>{{ order_info.id }}</td>\n                    <td>{{ order_info.apply_put_uid }}</td>\n                    <td>{{ order_info.apply_put_uid | nickname }}</td>\n                    <td>{{ order_info.type | type_order }}</td>\n                    <td>{{ order_info.money }}</td>\n                    <td>{{ order_info.status_audit | status_audit }}</td>\n                    <td>{{ order_info.status_pay | status_pay }}</td>\n                    <td>{{ order_info.status_rec | status_rec }}</td>\n                    <td>{{ order_info.status_delete | status_delete }}</td>\n                    <td>{{ moment(order_info.create_time).format('YYYY-MM-DD HH:mm:ss') }}</td>\n                </tr>\n            </tbody>\n        </table>\n        </div>\n    </section>\n    <section id=\"bank_info\">\n        <div class=\"panel panel-default\">\n        <div class=\"panel-heading\">\n            <strong class=\"panel-title\">收款信息\n            <span class=\"glyphicon glyphicon-cog pull-right\"></span>\n            </strong>\n        </div>\n        <table class=\"table table-hover table-responsive\">\n            <thead>\n                <tr>\n                    <th>类型名称</th>\n                    <th>账号名称</th>\n                    <th>是否支持</th>\n                </tr>\n            </thead>\n            <tbody>\n                <tr>\n                    <td>账户名称</td>\n                    <td>{{ bank_info.account_name }}</td>\n                    <td><span class=\"glyphicon glyphicon-ok\"></span></td>\n                </tr>\n                <tr>\n                    <td>银行名称</td>\n                    <td>{{ bank_info.bank_name }}</td>\n                    <td><span class=\"glyphicon glyphicon-ok\"></span></td>\n                </tr>\n                <tr>\n                    <td>支行名称</td>\n                    <td>{{ bank_info.bank_address }}</td>\n                    <td><span class=\"glyphicon glyphicon-ok\"></span></td>\n                </tr>\n                <tr>\n                    <td>银行卡号</td>\n                    <td>{{ bank_info.bank_account }}</td>\n                    <td><span class=\"glyphicon glyphicon-ok\"></span></td>\n                </tr>\n                <tr>\n                    <td>支付宝</td>\n                    <td></td>\n                    <td><span class=\"glyphicon glyphicon-remove\"></span></td>\n                </tr>\n                <tr>\n                    <td>微信支付</td>\n                    <td></td>\n                    <td><span class=\"glyphicon glyphicon-remove\"></span></td>\n                </tr>\n            </tbody>\n        </table>\n        </div>\n    </section>\n\n{% if order_bill_lists %}\n    <section id=\"bank_info\">\n        <div class=\"panel panel-default\">\n        <div class=\"panel-heading\">\n            <strong class=\"panel-title\">付款凭证\n            <span class=\"glyphicon glyphicon-cog pull-right\"></span>\n            </strong>\n        </div>\n        <table class=\"table table-hover table-responsive\">\n            <thead>\n                <tr>\n                    <th>凭证预览</th>\n                    <th>凭证名称</th>\n                    <th>状态</th>\n                </tr>\n            </thead>\n            <tbody>\n                {% for order_bill in order_bill_lists %}\n                <tr>\n                    <td>\n                        <span class=\"preview\">\n                            <a href=\"/static/uploads/{{ order_bill.bill_img }}\" title=\"{{ order_bill.bill_img }}\" download=\"{{ order_bill.bill_img }}\" data-gallery=\"\">\n                                <img src=\"/static/uploads/{{ order_bill.bill_img }}\" height=\"80\">\n                            </a>\n                        </span>\n                    </td>\n                    <td>\n                        <p class=\"name\">\n                            <a href=\"/static/uploads/{{ order_bill.bill_img }}\" title=\"{{ order_bill.bill_img }}\" download=\"{{ order_bill.bill_img }}\" data-gallery=\"\">\n                                {{ order_bill.bill_img }}\n                            </a>\n                        </p>\n                    </td>\n                    <td><span class=\"glyphicon glyphicon-ok\"></span></td>\n                </tr>\n                {% endfor %}\n            </tbody>\n        </table>\n        </div>\n    </section>\n{% endif %}\n    <br>\n{% if order_info.status_pay == 1 and order_info.status_rec != 1 %}\n    <div class=\"btn-group pull-right\" role=\"group\" aria-label=\"...\">\n        <a type=\"button\" class=\"btn btn-success\" href=\"javascript:void(0);\" onclick=\"order_rec({{ order_info.id }}, 1);\">\n            <span class=\"glyphicon glyphicon-ok\"></span> 收款成功\n        </a>\n        <a type=\"button\" class=\"btn btn-warning\" href=\"javascript:void(0);\" onclick=\"order_rec({{ order_info.id }}, 2);\">\n            <span class=\"glyphicon glyphicon-remove\"></span> 收款失败\n        </a>\n    </div>\n{% endif %}\n\n\n</div>\n<!-- The blueimp Gallery widget -->\n<div id=\"blueimp-gallery\" class=\"blueimp-gallery blueimp-gallery-controls\" data-filter=\":even\">\n    <div class=\"slides\"></div>\n    <h3 class=\"title\"></h3>\n    <a class=\"prev\">‹</a>\n    <a class=\"next\">›</a>\n    <a class=\"close\">×</a>\n    <a class=\"play-pause\"></a>\n    <ol class=\"indicator\"></ol>\n</div>\n\n{% raw %}\n<!-- The template to display files available for upload -->\n<script id=\"template-upload\" type=\"text/x-tmpl\">\n{% for (var i=0, file; file=o.files[i]; i++) { %}\n    <tr class=\"template-upload fade\">\n        <td>\n            <span class=\"preview\"></span>\n        </td>\n        <td>\n            <p class=\"name\">{%=file.name%}</p>\n            <strong class=\"error text-danger\"></strong>\n        </td>\n        <td>\n            <p class=\"size\">上传中...</p>\n            <div class=\"progress progress-striped active\" role=\"progressbar\" aria-valuemin=\"0\" aria-valuemax=\"100\" aria-valuenow=\"0\"><div class=\"progress-bar progress-bar-success\" style=\"width:0%;\"></div></div>\n        </td>\n        <td>\n            {% if (!i && !o.options.autoUpload) { %}\n                <button class=\"btn btn-primary start\" disabled>\n                    <i class=\"glyphicon glyphicon-upload\"></i>\n                    <span>上传</span>\n                </button>\n            {% } %}\n            {% if (!i) { %}\n                <button class=\"btn btn-warning cancel\">\n                    <i class=\"glyphicon glyphicon-ban-circle\"></i>\n                    <span>取消</span>\n                </button>\n            {% } %}\n        </td>\n    </tr>\n{% } %}\n</script>\n<!-- The template to display files available for download -->\n<script id=\"template-download\" type=\"text/x-tmpl\">\n{% for (var i=0, file; file=o.files[i]; i++) { %}\n    <tr class=\"template-download fade\">\n        <td>\n            <span class=\"preview\">\n                {% if (file.thumbnail_url) { %}\n                    <a href=\"{%=file.url%}\" title=\"{%=file.name%}\" download=\"{%=file.name%}\" data-gallery><img src=\"{%=file.thumbnail_url%}\" height=\"80\"></a>\n                {% } %}\n            </span>\n        </td>\n        <td>\n            <p class=\"name\">\n                {% if (file.url) { %}\n                    <a href=\"{%=file.url%}\" title=\"{%=file.name%}\" download=\"{%=file.name%}\" {%=file.thumbnail_url?'data-gallery':''%}>{%=file.name%}</a>\n                {% } else { %}\n                    <span>{%=file.name%}</span>\n                {% } %}\n            </p>\n            {% if (file.error) { %}\n                <div><span class=\"label label-danger\">上传错误</span> {%=file.error%}</div>\n            {% } %}\n        </td>\n        <td>\n            <span class=\"size\">{%=o.formatFileSize(file.size)%}</span>\n        </td>\n        <td>\n            {% if (file.delete_url) { %}\n                <button class=\"btn btn-danger delete\" data-type=\"{%=file.delete_type%}\" data-url=\"{%=file.delete_url%}\"{% if (file.deleteWithCredentials) { %} data-xhr-fields='{\"withCredentials\":true}'{% } %}>\n                    <i class=\"glyphicon glyphicon-trash\"></i>\n                    <span>删除</span>\n                </button>\n                <input type=\"checkbox\" name=\"delete\" value=\"1\" class=\"toggle\">\n            {% } else { %}\n                <button class=\"btn btn-warning cancel\">\n                    <i class=\"glyphicon glyphicon-ban-circle\"></i>\n                    <span>取消</span>\n                </button>\n            {% } %}\n        </td>\n    </tr>\n{% } %}\n</script>\n{% endraw %}\n\n{% endblock %}\n\n<!-- The XDomainRequest Transport is included for cross-domain file deletion for IE 8 and IE 9 -->\n<!--[if (gte IE 8)&(lt IE 10)]>\n<script src=\"js/cors/jquery.xdr-transport.js\"></script>\n<![endif]-->\n\n\n{% block extra_js %}\n    <!-- The jQuery UI widget factory, can be omitted if jQuery UI is already included -->\n    <script src=\"{{ url_for('static', filename='plugin/jQuery-File-Upload-9.18.0/js/vendor/jquery.ui.widget.js') }}\"></script>\n    <!-- The Templates plugin is included to render the upload/download listings -->\n    <script src=\"{{ url_for('static', filename='plugin/JavaScript-Templates-3.8.0/js/tmpl.min.js') }}\"></script>\n    <!-- The Load Image plugin is included for the preview images and image resizing functionality -->\n    <script src=\"{{ url_for('static', filename='plugin/JavaScript-Load-Image-2.12.2/js/load-image.all.min.js') }}\"></script>\n    <!-- The Canvas to Blob plugin is included for image resizing functionality -->\n    <script src=\"{{ url_for('static', filename='plugin/JavaScript-Canvas-to-Blob-3.7.0/js/canvas-to-blob.min.js') }}\"></script>\n    <!-- blueimp Gallery script -->\n    <script src=\"{{ url_for('static', filename='plugin/Gallery-2.25.0/js/jquery.blueimp-gallery.min.js') }}\"></script>\n    <!-- The Iframe Transport is required for browsers without support for XHR file uploads -->\n    <script src=\"{{ url_for('static', filename='plugin/jQuery-File-Upload-9.18.0/js/jquery.iframe-transport.js') }}\"></script>\n    <!-- The basic File Upload plugin -->\n    <script src=\"{{ url_for('static', filename='plugin/jQuery-File-Upload-9.18.0/js/jquery.fileupload.js') }}\"></script>\n    <!-- The File Upload processing plugin -->\n    <script src=\"{{ url_for('static', filename='plugin/jQuery-File-Upload-9.18.0/js/jquery.fileupload-process.js') }}\"></script>\n    <!-- The File Upload image preview & resize plugin -->\n    <script src=\"{{ url_for('static', filename='plugin/jQuery-File-Upload-9.18.0/js/jquery.fileupload-image.js') }}\"></script>\n    <!-- The File Upload audio preview plugin -->\n    <script src=\"{{ url_for('static', filename='plugin/jQuery-File-Upload-9.18.0/js/jquery.fileupload-audio.js') }}\"></script>\n    <!-- The File Upload video preview plugin -->\n    <script src=\"{{ url_for('static', filename='plugin/jQuery-File-Upload-9.18.0/js/jquery.fileupload-video.js') }}\"></script>\n    <!-- The File Upload validation plugin -->\n    <script src=\"{{ url_for('static', filename='plugin/jQuery-File-Upload-9.18.0/js/jquery.fileupload-validate.js') }}\"></script>\n    <!-- The File Upload user interface plugin -->\n    <script src=\"{{ url_for('static', filename='plugin/jQuery-File-Upload-9.18.0/js/jquery.fileupload-ui.js') }}\"></script>\n\n    <!-- The XDomainRequest Transport is included for cross-domain file deletion for IE 8 and IE 9 -->\n    <!--[if (gte IE 8)&(lt IE 10)]>\n    <script src=\"{{ url_for('static', filename='plugin/jQuery-File-Upload-9.18.0/js/cors/jquery.xdr-transport.js') }}\"></script>\n    <![endif]-->\n    <script>\n    $(function () {\n        //初始化，主要是设置上传参数，以及事件处理方法(回调函数)\n        $('#fileupload').fileupload({});\n\n        // Load existing files:\n        $('#fileupload').addClass('fileupload-processing');\n        $.ajax({\n            // Uncomment the following to send cross-domain cookies:\n            //xhrFields: {withCredentials: true},\n            url: $('#fileupload').fileupload('option', 'url'),\n            dataType: 'json',\n            context: $('#fileupload')[0]\n        }).always(function () {\n            $(this).removeClass('fileupload-processing');\n        }).done(function (result) {\n            $(this).fileupload('option', 'done')\n                .call(this, $.Event('done'), {result: result});\n        });\n    });\n    // 收款状态确认\n    function order_rec(order_id, status_rec) {\n        // console.log($(form).serialize());\n        $.ajax({\n            url: \"{{ url_for('order.ajax_rec') }}\",\n            type: 'POST',\n            data: {order_id: order_id, status_rec: status_rec},\n            dataType: 'json',\n            success: function (result) {\n                // console.log(result);\n                if(result.hasOwnProperty('error')){\n                    alert(result.error);\n                }else {\n                    alert(result.success);\n                    document.location.reload();\n                }\n            }\n        });\n        return false;\n    }\n    </script>\n{% endblock %}\n"
  },
  {
    "path": "app_frontend/templates/order/get_list.html",
    "content": "<!-- extend from base layout -->\n{% extends \"layout.html\" %}\n\n{% block extra_css %}\n\n{% endblock %}\n\n{% block content %}\n    <div class=\"container\">\n    <!-- header -->\n    <nav class=\"sub-header row container-fluid\">\n        <ol class=\"breadcrumb\">\n            <li><a href=\"/\">首页</a></li>\n            <li class=\"active\">提现中心</li>\n            <li class=\"active\">提现订单</li>\n        </ol>\n        <div class=\"btn-group pull-right\" role=\"group\" aria-label=\"...\">\n            {% if request.query_string == 'status_rec=2' %}\n            <a type=\"button\" class=\"btn btn-default\" href=\"{{ url_for('order.lists_get') }}\">等待收款</a>\n            <a type=\"button\" class=\"btn btn-default\" href=\"{{ url_for('order.lists_get', status_rec=1) }}\">收款成功</a>\n            <a type=\"button\" class=\"btn btn-default active\">收款失败</a>\n            {% elif request.query_string == 'status_rec=1' %}\n            <a type=\"button\" class=\"btn btn-default\" href=\"{{ url_for('order.lists_get') }}\">等待收款</a>\n            <a type=\"button\" class=\"btn btn-default active\">收款成功</a>\n            <a type=\"button\" class=\"btn btn-default\" href=\"{{ url_for('order.lists_get', status_rec=2) }}\">收款失败</a>\n            {% else %}\n            <a type=\"button\" class=\"btn btn-default active\">等待收款</a>\n            <a type=\"button\" class=\"btn btn-default\" href=\"{{ url_for('order.lists_get', status_rec=1) }}\">收款成功</a>\n            <a type=\"button\" class=\"btn btn-default\" href=\"{{ url_for('order.lists_get', status_rec=2) }}\">收款失败</a>\n            {% endif %}\n        </div>\n    </nav>\n\n    <hr/>\n    <!-- content -->\n    <div class=\"table-responsive\">\n        {# <table class=\"table table-striped\"> #}\n        <table class=\"table table-hover\">\n            <thead>\n            <tr>\n                <th>订单ID</th>\n                <th>投资ID</th>\n                <th>提现ID</th>\n                <th>投资用户</th>\n                <th>订单金额</th>\n                <th>认证状态</th>\n                <th>支付状态</th>\n                <th>确认状态</th>\n                <th>匹配时间</th>\n                <th>操作</th>\n            </tr>\n            </thead>\n            <tbody>\n            {% for order, user_profile in pagination.items %}\n            <tr class=\"text-muted\">\n                <td>{{ order.id }}</td>\n                <td>{{ order.apply_put_id }}</td>\n                <td>{{ order.apply_get_id }}</td>\n                <td>{{ user_profile.nickname }} [{{ order.apply_put_uid }}]</td>\n                <td>{{ order.money }}</td>\n                <td>{{ order.status_audit | status_audit }}</td>\n                <td>{{ order.status_pay | status_pay }}</td>\n                <td>{{ order.status_rec | status_rec }}</td>\n                <td>{{ moment(order.create_time).format('YYYY-MM-DD HH:mm:ss') }}</td>\n                <td>\n                    <a class=\"btn-sm btn-default\" href=\"{{ url_for('order.info_get', order_id=order.id) }}\" rel=\"tooltip\" title=\"订单详情\"><span class=\"glyphicon glyphicon-list-alt\"></span> 订单详情</a>\n                    <a class=\"btn-sm btn-default\" href=\"{{ url_for('message.add', user_id=order.apply_put_uid) }}\" rel=\"tooltip\" title=\"留言\"><span class=\"glyphicon glyphicon-list-alt\"></span> 留言</a>\n                    <a class=\"btn-sm btn-default\" href=\"{{ url_for('complaint.add', user_id=order.apply_put_uid) }}\" rel=\"tooltip\" title=\"投诉\"><span class=\"glyphicon glyphicon-list-alt\"></span> 投诉</a>\n{#                    <a href=\"javascript:void(0);\" onclick=\"order_delete({{ order.id }});\" rel=\"tooltip\" title=\"删除\"><span class=\"glyphicon glyphicon-trash\"></span></a>#}\n                </td>\n            </tr>\n            {% endfor %}\n            </tbody>\n        </table>\n        {# 翻页 #}\n        {% from \"macros.html\" import render_pagination %}\n        {{ render_pagination(pagination, 'order.lists_get') }}\n    </div>\n    </div>\n{% endblock %}\n\n{% block extra_js %}\n<script>\n\n</script>\n{% endblock %}\n"
  },
  {
    "path": "app_frontend/templates/order/pay.html",
    "content": "{% extends \"layout.html\" %}\n\n{% block extra_css %}\n    <!-- blueimp Gallery styles -->\n    <link rel=\"stylesheet\" href=\"{{ url_for('static', filename='plugin/Gallery-2.25.0/css/blueimp-gallery.min.css') }}\">\n    <!-- CSS to style the file input field as button and adjust the Bootstrap progress bars -->\n    <link rel=\"stylesheet\" href=\"{{ url_for('static', filename='plugin/jQuery-File-Upload-9.18.0/css/jquery.fileupload.css') }}\">\n    <link rel=\"stylesheet\" href=\"{{ url_for('static', filename='plugin/jQuery-File-Upload-9.18.0/css/jquery.fileupload-ui.css') }}\">\n    <!-- CSS adjustments for browsers with JavaScript disabled -->\n    <noscript><link rel=\"stylesheet\" href=\"{{ url_for('static', filename='plugin/jQuery-File-Upload-9.18.0/css/jquery.fileupload-noscript.css') }}\"></noscript>\n    <noscript><link rel=\"stylesheet\" href=\"{{ url_for('static', filename='plugin/jQuery-File-Upload-9.18.0/css/jquery.fileupload-ui-noscript.css') }}\"></noscript>\n{% endblock %}\n\n{% block content %}\n<div class=\"container\">\n    <h2 class=\"lead\">订单支付，上传付款凭证\n        {% if order_info.pay_time %}\n        <p class=\"text-warning\">\n        付款时间：[{{ moment(order_info.pay_time).format('YYYY-MM-DD HH:mm:ss') }}]\n        </p>\n        {% else %}\n        <p class=\"text-warning\">\n        剩余付款时间：[{{ moment(order_info.create_time | time_delta(3600*24*2)).fromNow(refresh=True) }}]\n        </p>\n        {% endif %}\n    </h2>\n    <br>\n    <blockquote>\n        <p class=\"text-muted\">奖励规则：提前（1小时内）打款，奖励利息（2%）</p>\n        <p class=\"text-muted\">惩罚规则：延迟（超过24小时）打款，扣除罚息（2%）；上传虚假凭证，永久封号</p>\n        <footer>规则最终解释 <cite title=\"Source Title\">运营团队</cite></footer>\n    </blockquote>\n    <section id=\"order_info\">\n        <div class=\"panel panel-default\">\n        <div class=\"panel-heading\">\n            <strong class=\"panel-title\">订单信息\n            <span class=\"glyphicon glyphicon-cog pull-right\"></span>\n            </strong>\n        </div>\n        <table class=\"table table-hover table-responsive\">\n            <thead>\n                <tr>\n                    <th>订单ID</th>\n                    <th>用户ID</th>\n                    <th>用户名称</th>\n                    <th>订单类型</th>\n                    <th>订单金额</th>\n                    <th>审核状态</th>\n                    <th>支付状态</th>\n                    <th>收款状态</th>\n                    <th>删除状态</th>\n                    <th>订单时间</th>\n                </tr>\n            </thead>\n            <tbody>\n                <tr>\n                    <td>{{ order_info.id }}</td>\n                    <td>{{ order_info.apply_get_uid }}</td>\n                    <td>{{ order_info.apply_get_uid | nickname }}</td>\n                    <td>{{ order_info.type | type_order }}</td>\n                    <td>{{ order_info.money }}</td>\n                    <td>{{ order_info.status_audit | status_audit }}</td>\n                    <td>{{ order_info.status_pay | status_pay }}</td>\n                    <td>{{ order_info.status_rec | status_rec }}</td>\n                    <td>{{ order_info.status_delete | status_delete }}</td>\n                    <td>{{ moment(order_info.create_time).format('YYYY-MM-DD HH:mm:ss') }}</td>\n                </tr>\n            </tbody>\n        </table>\n        </div>\n    </section>\n    <section id=\"bank_info\">\n        <div class=\"panel panel-default\">\n        <div class=\"panel-heading\">\n            <strong class=\"panel-title\">收款信息\n            <span class=\"glyphicon glyphicon-cog pull-right\"></span>\n            </strong>\n        </div>\n        <table class=\"table table-hover table-responsive\">\n            <thead>\n                <tr>\n                    <th>类型名称</th>\n                    <th>账号名称</th>\n                    <th>是否支持</th>\n                </tr>\n            </thead>\n            <tbody>\n                <tr>\n                    <td>账户名称</td>\n                    <td>{{ bank_info.account_name }}</td>\n                    <td><span class=\"glyphicon glyphicon-ok\"></span></td>\n                </tr>\n                <tr>\n                    <td>银行名称</td>\n                    <td>{{ bank_info.bank_name }}</td>\n                    <td><span class=\"glyphicon glyphicon-ok\"></span></td>\n                </tr>\n                <tr>\n                    <td>支行名称</td>\n                    <td>{{ bank_info.bank_address }}</td>\n                    <td><span class=\"glyphicon glyphicon-ok\"></span></td>\n                </tr>\n                <tr>\n                    <td>银行卡号</td>\n                    <td>{{ bank_info.bank_account }}</td>\n                    <td><span class=\"glyphicon glyphicon-ok\"></span></td>\n                </tr>\n                <tr>\n                    <td>支付宝</td>\n                    <td></td>\n                    <td><span class=\"glyphicon glyphicon-remove\"></span></td>\n                </tr>\n                <tr>\n                    <td>微信支付</td>\n                    <td></td>\n                    <td><span class=\"glyphicon glyphicon-remove\"></span></td>\n                </tr>\n            </tbody>\n        </table>\n        </div>\n    </section>\n\n    {% if order_bill_lists %}\n    <section id=\"bank_info\">\n        <div class=\"panel panel-default\">\n        <div class=\"panel-heading\">\n            <strong class=\"panel-title\">付款凭证\n            <span class=\"glyphicon glyphicon-cog pull-right\"></span>\n            </strong>\n        </div>\n        <table class=\"table table-hover table-responsive\">\n            <thead>\n                <tr>\n                    <th>凭证预览</th>\n                    <th>凭证名称</th>\n                    <th>状态</th>\n                </tr>\n            </thead>\n            <tbody>\n                {% for order_bill in order_bill_lists %}\n                <tr>\n                    <td>\n                        <span class=\"preview\">\n                            <a href=\"/static/uploads/{{ order_bill.bill_img }}\" title=\"{{ order_bill.bill_img }}\" download=\"{{ order_bill.bill_img }}\" data-gallery=\"\">\n                                <img src=\"/static/uploads/{{ order_bill.bill_img }}\" height=\"80\">\n                            </a>\n                        </span>\n                    </td>\n                    <td>\n                        <p class=\"name\">\n                            <a href=\"/static/uploads/{{ order_bill.bill_img }}\" title=\"{{ order_bill.bill_img }}\" download=\"{{ order_bill.bill_img }}\" data-gallery=\"\">\n                                {{ order_bill.bill_img }}\n                            </a>\n                        </p>\n                    </td>\n                    <td><span class=\"glyphicon glyphicon-ok\"></span></td>\n                </tr>\n                {% endfor %}\n            </tbody>\n        </table>\n        </div>\n    </section>\n    {% endif %}\n    <br>\n    <!-- The file upload form used as target for the file upload widget -->\n    <form id=\"fileupload\" action=\"{{ url_for('order.pay_bill_uploads', order_id=order_info.id) }}\" method=\"POST\" enctype=\"multipart/form-data\">\n        <!-- The fileupload-buttonbar contains buttons to add/delete files and start/cancel the upload -->\n        <div class=\"row fileupload-buttonbar\">\n            <div class=\"col-lg-7\">\n                <!-- The fileinput-button span is used to style the file input field as button -->\n                <span class=\"btn btn-success fileinput-button\">\n                    <i class=\"glyphicon glyphicon-plus\"></i>\n                    <span>添加凭证</span>\n                    <input type=\"file\" name=\"files[]\" multiple>\n                </span>\n                <button type=\"submit\" class=\"btn btn-primary start\">\n                    <i class=\"glyphicon glyphicon-upload\"></i>\n                    <span>开始上传</span>\n                </button>\n                <button type=\"reset\" class=\"btn btn-warning cancel\">\n                    <i class=\"glyphicon glyphicon-ban-circle\"></i>\n                    <span>取消上传</span>\n                </button>\n                <button type=\"button\" class=\"btn btn-danger delete\">\n                    <i class=\"glyphicon glyphicon-trash\"></i>\n                    <span>删除凭证</span>\n                </button>\n                <input type=\"checkbox\" class=\"toggle\">\n                <!-- The global file processing state -->\n                <span class=\"fileupload-process\"></span>\n            </div>\n            <!-- The global progress state -->\n            <div class=\"col-lg-5 fileupload-progress fade\">\n                <!-- The global progress bar -->\n                <div class=\"progress progress-striped active\" role=\"progressbar\" aria-valuemin=\"0\" aria-valuemax=\"100\">\n                    <div class=\"progress-bar progress-bar-success\" style=\"width:0%;\"></div>\n                </div>\n                <!-- The extended global progress state -->\n                <div class=\"progress-extended\">&nbsp;</div>\n            </div>\n        </div>\n        <!-- The table listing the files available for upload/download -->\n        <table role=\"presentation\" class=\"table table-striped\"><tbody class=\"files\"></tbody></table>\n    </form>\n    <br>\n\n</div>\n<!-- The blueimp Gallery widget -->\n<div id=\"blueimp-gallery\" class=\"blueimp-gallery blueimp-gallery-controls\" data-filter=\":even\">\n    <div class=\"slides\"></div>\n    <h3 class=\"title\"></h3>\n    <a class=\"prev\">‹</a>\n    <a class=\"next\">›</a>\n    <a class=\"close\">×</a>\n    <a class=\"play-pause\"></a>\n    <ol class=\"indicator\"></ol>\n</div>\n\n{% raw %}\n<!-- The template to display files available for upload -->\n<script id=\"template-upload\" type=\"text/x-tmpl\">\n{% for (var i=0, file; file=o.files[i]; i++) { %}\n    <tr class=\"template-upload fade\">\n        <td>\n            <span class=\"preview\"></span>\n        </td>\n        <td>\n            <p class=\"name\">{%=file.name%}</p>\n            <strong class=\"error text-danger\"></strong>\n        </td>\n        <td>\n            <p class=\"size\">上传中...</p>\n            <div class=\"progress progress-striped active\" role=\"progressbar\" aria-valuemin=\"0\" aria-valuemax=\"100\" aria-valuenow=\"0\"><div class=\"progress-bar progress-bar-success\" style=\"width:0%;\"></div></div>\n        </td>\n        <td>\n            {% if (!i && !o.options.autoUpload) { %}\n                <button class=\"btn btn-primary start\" disabled>\n                    <i class=\"glyphicon glyphicon-upload\"></i>\n                    <span>上传</span>\n                </button>\n            {% } %}\n            {% if (!i) { %}\n                <button class=\"btn btn-warning cancel\">\n                    <i class=\"glyphicon glyphicon-ban-circle\"></i>\n                    <span>取消</span>\n                </button>\n            {% } %}\n        </td>\n    </tr>\n{% } %}\n</script>\n<!-- The template to display files available for download -->\n<script id=\"template-download\" type=\"text/x-tmpl\">\n{% for (var i=0, file; file=o.files[i]; i++) { %}\n    <tr class=\"template-download fade\">\n        <td>\n            <span class=\"preview\">\n                {% if (file.thumbnail_url) { %}\n                    <a href=\"{%=file.url%}\" title=\"{%=file.name%}\" download=\"{%=file.name%}\" data-gallery><img src=\"{%=file.thumbnail_url%}\" height=\"80\"></a>\n                {% } %}\n            </span>\n        </td>\n        <td>\n            <p class=\"name\">\n                {% if (file.url) { %}\n                    <a href=\"{%=file.url%}\" title=\"{%=file.name%}\" download=\"{%=file.name%}\" {%=file.thumbnail_url?'data-gallery':''%}>{%=file.name%}</a>\n                {% } else { %}\n                    <span>{%=file.name%}</span>\n                {% } %}\n            </p>\n            {% if (file.error) { %}\n                <div><span class=\"label label-danger\">上传错误</span> {%=file.error%}</div>\n            {% } %}\n        </td>\n        <td>\n            <span class=\"size\">{%=o.formatFileSize(file.size)%}</span>\n        </td>\n        <td>\n            {% if (file.delete_url) { %}\n                <button class=\"btn btn-danger delete\" data-type=\"{%=file.delete_type%}\" data-url=\"{%=file.delete_url%}\"{% if (file.deleteWithCredentials) { %} data-xhr-fields='{\"withCredentials\":true}'{% } %}>\n                    <i class=\"glyphicon glyphicon-trash\"></i>\n                    <span>删除</span>\n                </button>\n                <input type=\"checkbox\" name=\"delete\" value=\"1\" class=\"toggle\">\n            {% } else { %}\n                <button class=\"btn btn-warning cancel\">\n                    <i class=\"glyphicon glyphicon-ban-circle\"></i>\n                    <span>取消</span>\n                </button>\n            {% } %}\n        </td>\n    </tr>\n{% } %}\n</script>\n{% endraw %}\n\n{% endblock %}\n\n<!-- The XDomainRequest Transport is included for cross-domain file deletion for IE 8 and IE 9 -->\n<!--[if (gte IE 8)&(lt IE 10)]>\n<script src=\"js/cors/jquery.xdr-transport.js\"></script>\n<![endif]-->\n\n\n{% block extra_js %}\n    <!-- The jQuery UI widget factory, can be omitted if jQuery UI is already included -->\n    <script src=\"{{ url_for('static', filename='plugin/jQuery-File-Upload-9.18.0/js/vendor/jquery.ui.widget.js') }}\"></script>\n    <!-- The Templates plugin is included to render the upload/download listings -->\n    <script src=\"{{ url_for('static', filename='plugin/JavaScript-Templates-3.8.0/js/tmpl.min.js') }}\"></script>\n    <!-- The Load Image plugin is included for the preview images and image resizing functionality -->\n    <script src=\"{{ url_for('static', filename='plugin/JavaScript-Load-Image-2.12.2/js/load-image.all.min.js') }}\"></script>\n    <!-- The Canvas to Blob plugin is included for image resizing functionality -->\n    <script src=\"{{ url_for('static', filename='plugin/JavaScript-Canvas-to-Blob-3.7.0/js/canvas-to-blob.min.js') }}\"></script>\n    <!-- blueimp Gallery script -->\n    <script src=\"{{ url_for('static', filename='plugin/Gallery-2.25.0/js/jquery.blueimp-gallery.min.js') }}\"></script>\n    <!-- The Iframe Transport is required for browsers without support for XHR file uploads -->\n    <script src=\"{{ url_for('static', filename='plugin/jQuery-File-Upload-9.18.0/js/jquery.iframe-transport.js') }}\"></script>\n    <!-- The basic File Upload plugin -->\n    <script src=\"{{ url_for('static', filename='plugin/jQuery-File-Upload-9.18.0/js/jquery.fileupload.js') }}\"></script>\n    <!-- The File Upload processing plugin -->\n    <script src=\"{{ url_for('static', filename='plugin/jQuery-File-Upload-9.18.0/js/jquery.fileupload-process.js') }}\"></script>\n    <!-- The File Upload image preview & resize plugin -->\n    <script src=\"{{ url_for('static', filename='plugin/jQuery-File-Upload-9.18.0/js/jquery.fileupload-image.js') }}\"></script>\n    <!-- The File Upload audio preview plugin -->\n    <script src=\"{{ url_for('static', filename='plugin/jQuery-File-Upload-9.18.0/js/jquery.fileupload-audio.js') }}\"></script>\n    <!-- The File Upload video preview plugin -->\n    <script src=\"{{ url_for('static', filename='plugin/jQuery-File-Upload-9.18.0/js/jquery.fileupload-video.js') }}\"></script>\n    <!-- The File Upload validation plugin -->\n    <script src=\"{{ url_for('static', filename='plugin/jQuery-File-Upload-9.18.0/js/jquery.fileupload-validate.js') }}\"></script>\n    <!-- The File Upload user interface plugin -->\n    <script src=\"{{ url_for('static', filename='plugin/jQuery-File-Upload-9.18.0/js/jquery.fileupload-ui.js') }}\"></script>\n\n    <!-- The XDomainRequest Transport is included for cross-domain file deletion for IE 8 and IE 9 -->\n    <!--[if (gte IE 8)&(lt IE 10)]>\n    <script src=\"{{ url_for('static', filename='plugin/jQuery-File-Upload-9.18.0/js/cors/jquery.xdr-transport.js') }}\"></script>\n    <![endif]-->\n    <script>\n    $(function () {\n        //初始化，主要是设置上传参数，以及事件处理方法(回调函数)\n        $('#fileupload').fileupload({});\n\n        // Load existing files:\n        $('#fileupload').addClass('fileupload-processing');\n        $.ajax({\n            // Uncomment the following to send cross-domain cookies:\n            //xhrFields: {withCredentials: true},\n            url: $('#fileupload').fileupload('option', 'url'),\n            dataType: 'json',\n            context: $('#fileupload')[0]\n        }).always(function () {\n            $(this).removeClass('fileupload-processing');\n        }).done(function (result) {\n            $(this).fileupload('option', 'done')\n                .call(this, $.Event('done'), {result: result});\n        });\n    });\n    </script>\n{% endblock %}\n"
  },
  {
    "path": "app_frontend/templates/order/put_info.html",
    "content": "{% extends \"layout.html\" %}\n\n{% block extra_css %}\n    <!-- blueimp Gallery styles -->\n    <link rel=\"stylesheet\" href=\"{{ url_for('static', filename='plugin/Gallery-2.25.0/css/blueimp-gallery.min.css') }}\">\n    <!-- CSS to style the file input field as button and adjust the Bootstrap progress bars -->\n    <link rel=\"stylesheet\" href=\"{{ url_for('static', filename='plugin/jQuery-File-Upload-9.18.0/css/jquery.fileupload.css') }}\">\n    <link rel=\"stylesheet\" href=\"{{ url_for('static', filename='plugin/jQuery-File-Upload-9.18.0/css/jquery.fileupload-ui.css') }}\">\n    <!-- CSS adjustments for browsers with JavaScript disabled -->\n    <noscript><link rel=\"stylesheet\" href=\"{{ url_for('static', filename='plugin/jQuery-File-Upload-9.18.0/css/jquery.fileupload-noscript.css') }}\"></noscript>\n    <noscript><link rel=\"stylesheet\" href=\"{{ url_for('static', filename='plugin/jQuery-File-Upload-9.18.0/css/jquery.fileupload-ui-noscript.css') }}\"></noscript>\n{% endblock %}\n\n{% block content %}\n<div class=\"container\">\n    <h2 class=\"lead\">\n    {% if order_info.pay_time %}\n        <p class=\"text-warning\">\n        付款时间：[{{ moment(order_info.pay_time).format('YYYY-MM-DD HH:mm:ss') }}]\n        </p>\n    {% else %}\n        <p class=\"text-warning\">\n        剩余付款时间：[{{ moment(order_info.create_time | time_delta(3600*24*2)).fromNow(refresh=True) }}]\n        </p>\n    {% endif %}\n    {% if order_info.rec_time %}\n        <p class=\"text-warning\">\n        确认收款时间：[{{ moment(order_info.rec_time).format('YYYY-MM-DD HH:mm:ss') }}]\n        </p>\n    {% elif order_info.pay_time %}\n        <p class=\"text-warning\">\n        等待对方确认，剩余确认时间：[{{ moment(order_info.pay_time | time_delta(3600*24*2)).fromNow(refresh=True) }}]\n        </p>\n    {% endif %}\n    </h2>\n    <br>\n{#    <blockquote>#}\n{#        <p class=\"text-muted\">奖励规则：提前（1小时内）打款，奖励利息（2%）</p>#}\n{#        <p class=\"text-muted\">惩罚规则：延迟（超过24小时）打款，扣除罚息（2%）；上传虚假凭证，永久封号</p>#}\n{#        <footer>规则最终解释 <cite title=\"Source Title\">运营团队</cite></footer>#}\n{#    </blockquote>#}\n    <section id=\"order_info\">\n        <div class=\"panel panel-default\">\n        <div class=\"panel-heading\">\n            <strong class=\"panel-title\">订单信息\n            <span class=\"glyphicon glyphicon-cog pull-right\"></span>\n            </strong>\n        </div>\n        <table class=\"table table-hover table-responsive\">\n            <thead>\n                <tr>\n                    <th>订单ID</th>\n                    <th>用户ID</th>\n                    <th>用户名称</th>\n                    <th>订单类型</th>\n                    <th>订单金额</th>\n                    <th>审核状态</th>\n                    <th>支付状态</th>\n                    <th>收款状态</th>\n                    <th>删除状态</th>\n                    <th>订单时间</th>\n                </tr>\n            </thead>\n            <tbody>\n                <tr>\n                    <td>{{ order_info.id }}</td>\n                    <td>{{ order_info.apply_get_uid }}</td>\n                    <td>{{ order_info.apply_get_uid | nickname }}</td>\n                    <td>{{ order_info.type | type_order }}</td>\n                    <td>{{ order_info.money }}</td>\n                    <td>{{ order_info.status_audit | status_audit }}</td>\n                    <td>{{ order_info.status_pay | status_pay }}</td>\n                    <td>{{ order_info.status_rec | status_rec }}</td>\n                    <td>{{ order_info.status_delete | status_delete }}</td>\n                    <td>{{ moment(order_info.create_time).format('YYYY-MM-DD HH:mm:ss') }}</td>\n                </tr>\n            </tbody>\n        </table>\n        </div>\n    </section>\n    <section id=\"bank_info\">\n        <div class=\"panel panel-default\">\n        <div class=\"panel-heading\">\n            <strong class=\"panel-title\">收款信息\n            <span class=\"glyphicon glyphicon-cog pull-right\"></span>\n            </strong>\n        </div>\n        <table class=\"table table-hover table-responsive\">\n            <thead>\n                <tr>\n                    <th>类型名称</th>\n                    <th>账号名称</th>\n                    <th>是否支持</th>\n                </tr>\n            </thead>\n            <tbody>\n                <tr>\n                    <td>账户名称</td>\n                    <td>{{ bank_info.account_name }}</td>\n                    <td><span class=\"glyphicon glyphicon-ok\"></span></td>\n                </tr>\n                <tr>\n                    <td>银行名称</td>\n                    <td>{{ bank_info.bank_name }}</td>\n                    <td><span class=\"glyphicon glyphicon-ok\"></span></td>\n                </tr>\n                <tr>\n                    <td>支行名称</td>\n                    <td>{{ bank_info.bank_address }}</td>\n                    <td><span class=\"glyphicon glyphicon-ok\"></span></td>\n                </tr>\n                <tr>\n                    <td>银行卡号</td>\n                    <td>{{ bank_info.bank_account }}</td>\n                    <td><span class=\"glyphicon glyphicon-ok\"></span></td>\n                </tr>\n                <tr>\n                    <td>支付宝</td>\n                    <td></td>\n                    <td><span class=\"glyphicon glyphicon-remove\"></span></td>\n                </tr>\n                <tr>\n                    <td>微信支付</td>\n                    <td></td>\n                    <td><span class=\"glyphicon glyphicon-remove\"></span></td>\n                </tr>\n            </tbody>\n        </table>\n        </div>\n    </section>\n\n{% if order_bill_lists %}\n    <section id=\"bank_info\">\n        <div class=\"panel panel-default\">\n        <div class=\"panel-heading\">\n            <strong class=\"panel-title\">付款凭证\n            <span class=\"glyphicon glyphicon-cog pull-right\"></span>\n            </strong>\n        </div>\n        <table class=\"table table-hover table-responsive\">\n            <thead>\n                <tr>\n                    <th>凭证预览</th>\n                    <th>凭证名称</th>\n                    <th>状态</th>\n                </tr>\n            </thead>\n            <tbody>\n                {% for order_bill in order_bill_lists %}\n                <tr>\n                    <td>\n                        <span class=\"preview\">\n                            <a href=\"/static/uploads/{{ order_bill.bill_img }}\" title=\"{{ order_bill.bill_img }}\" download=\"{{ order_bill.bill_img }}\" data-gallery=\"\">\n                                <img src=\"/static/uploads/{{ order_bill.bill_img }}\" height=\"80\">\n                            </a>\n                        </span>\n                    </td>\n                    <td>\n                        <p class=\"name\">\n                            <a href=\"/static/uploads/{{ order_bill.bill_img }}\" title=\"{{ order_bill.bill_img }}\" download=\"{{ order_bill.bill_img }}\" data-gallery=\"\">\n                                {{ order_bill.bill_img }}\n                            </a>\n                        </p>\n                    </td>\n                    <td><span class=\"glyphicon glyphicon-ok\"></span></td>\n                </tr>\n                {% endfor %}\n            </tbody>\n        </table>\n        </div>\n    </section>\n{% endif %}\n    <br>\n{% if order_info.status_pay == 0 %}\n    <!-- The file upload form used as target for the file upload widget -->\n    <form id=\"fileupload\" action=\"{{ url_for('order.pay_bill_uploads', order_id=order_info.id) }}\" method=\"POST\" enctype=\"multipart/form-data\">\n        <!-- The fileupload-buttonbar contains buttons to add/delete files and start/cancel the upload -->\n        <div class=\"row fileupload-buttonbar\">\n            <div class=\"col-lg-7\">\n                <!-- The fileinput-button span is used to style the file input field as button -->\n                <span class=\"btn btn-success fileinput-button\">\n                    <i class=\"glyphicon glyphicon-plus\"></i>\n                    <span>添加凭证</span>\n                    <input type=\"file\" name=\"files[]\" multiple>\n                </span>\n                <button type=\"submit\" class=\"btn btn-primary start\">\n                    <i class=\"glyphicon glyphicon-upload\"></i>\n                    <span>开始上传</span>\n                </button>\n                <button type=\"reset\" class=\"btn btn-warning cancel\">\n                    <i class=\"glyphicon glyphicon-ban-circle\"></i>\n                    <span>取消上传</span>\n                </button>\n                <button type=\"button\" class=\"btn btn-danger delete\">\n                    <i class=\"glyphicon glyphicon-trash\"></i>\n                    <span>删除凭证</span>\n                </button>\n                <input type=\"checkbox\" class=\"toggle\">\n                <!-- The global file processing state -->\n                <span class=\"fileupload-process\"></span>\n            </div>\n            <!-- The global progress state -->\n            <div class=\"col-lg-5 fileupload-progress fade\">\n                <!-- The global progress bar -->\n                <div class=\"progress progress-striped active\" role=\"progressbar\" aria-valuemin=\"0\" aria-valuemax=\"100\">\n                    <div class=\"progress-bar progress-bar-success\" style=\"width:0%;\"></div>\n                </div>\n                <!-- The extended global progress state -->\n                <div class=\"progress-extended\">&nbsp;</div>\n            </div>\n        </div>\n        <!-- The table listing the files available for upload/download -->\n        <table role=\"presentation\" class=\"table table-striped\"><tbody class=\"files\"></tbody></table>\n    </form>\n{% endif %}\n    <br>\n{% if order_info.status_pay == 0 %}\n    <div class=\"btn-group pull-right\" role=\"group\" aria-label=\"...\">\n        <a type=\"button\" class=\"btn btn-success\" href=\"javascript:void(0);\" onclick=\"order_pay({{ order_info.id }}, 1);\">\n            <span class=\"glyphicon glyphicon-ok\"></span> 支付成功\n        </a>\n{#        <a type=\"button\" class=\"btn btn-warning\" href=\"javascript:void(0);\" onclick=\"order_pay({{ order_info.id }}, 2);\">#}\n{#            <span class=\"glyphicon glyphicon-remove\"></span> 支付失败#}\n{#        </a>#}\n    </div>\n{% endif %}\n\n</div>\n    <p> </p>\n    <p> </p>\n    <p></p>\n<!-- The blueimp Gallery widget -->\n<div id=\"blueimp-gallery\" class=\"blueimp-gallery blueimp-gallery-controls\" data-filter=\":even\">\n    <div class=\"slides\"></div>\n    <h3 class=\"title\"></h3>\n    <a class=\"prev\">‹</a>\n    <a class=\"next\">›</a>\n    <a class=\"close\">×</a>\n    <a class=\"play-pause\"></a>\n    <ol class=\"indicator\"></ol>\n</div>\n\n{% raw %}\n<!-- The template to display files available for upload -->\n<script id=\"template-upload\" type=\"text/x-tmpl\">\n{% for (var i=0, file; file=o.files[i]; i++) { %}\n    <tr class=\"template-upload fade\">\n        <td>\n            <span class=\"preview\"></span>\n        </td>\n        <td>\n            <p class=\"name\">{%=file.name%}</p>\n            <strong class=\"error text-danger\"></strong>\n        </td>\n        <td>\n            <p class=\"size\">上传中...</p>\n            <div class=\"progress progress-striped active\" role=\"progressbar\" aria-valuemin=\"0\" aria-valuemax=\"100\" aria-valuenow=\"0\"><div class=\"progress-bar progress-bar-success\" style=\"width:0%;\"></div></div>\n        </td>\n        <td>\n            {% if (!i && !o.options.autoUpload) { %}\n                <button class=\"btn btn-primary start\" disabled>\n                    <i class=\"glyphicon glyphicon-upload\"></i>\n                    <span>上传</span>\n                </button>\n            {% } %}\n            {% if (!i) { %}\n                <button class=\"btn btn-warning cancel\">\n                    <i class=\"glyphicon glyphicon-ban-circle\"></i>\n                    <span>取消</span>\n                </button>\n            {% } %}\n        </td>\n    </tr>\n{% } %}\n</script>\n<!-- The template to display files available for download -->\n<script id=\"template-download\" type=\"text/x-tmpl\">\n{% for (var i=0, file; file=o.files[i]; i++) { %}\n    <tr class=\"template-download fade\">\n        <td>\n            <span class=\"preview\">\n                {% if (file.thumbnail_url) { %}\n                    <a href=\"{%=file.url%}\" title=\"{%=file.name%}\" download=\"{%=file.name%}\" data-gallery><img src=\"{%=file.thumbnail_url%}\" height=\"80\"></a>\n                {% } %}\n            </span>\n        </td>\n        <td>\n            <p class=\"name\">\n                {% if (file.url) { %}\n                    <a href=\"{%=file.url%}\" title=\"{%=file.name%}\" download=\"{%=file.name%}\" {%=file.thumbnail_url?'data-gallery':''%}>{%=file.name%}</a>\n                {% } else { %}\n                    <span>{%=file.name%}</span>\n                {% } %}\n            </p>\n            {% if (file.error) { %}\n                <div><span class=\"label label-danger\">上传错误</span> {%=file.error%}</div>\n            {% } %}\n        </td>\n        <td>\n            <span class=\"size\">{%=o.formatFileSize(file.size)%}</span>\n        </td>\n        <td>\n            {% if (file.delete_url) { %}\n                <button class=\"btn btn-danger delete\" data-type=\"{%=file.delete_type%}\" data-url=\"{%=file.delete_url%}\"{% if (file.deleteWithCredentials) { %} data-xhr-fields='{\"withCredentials\":true}'{% } %}>\n                    <i class=\"glyphicon glyphicon-trash\"></i>\n                    <span>删除</span>\n                </button>\n                <input type=\"checkbox\" name=\"delete\" value=\"1\" class=\"toggle\">\n            {% } else { %}\n                <button class=\"btn btn-warning cancel\">\n                    <i class=\"glyphicon glyphicon-ban-circle\"></i>\n                    <span>取消</span>\n                </button>\n            {% } %}\n        </td>\n    </tr>\n{% } %}\n</script>\n{% endraw %}\n\n{% endblock %}\n\n<!-- The XDomainRequest Transport is included for cross-domain file deletion for IE 8 and IE 9 -->\n<!--[if (gte IE 8)&(lt IE 10)]>\n<script src=\"js/cors/jquery.xdr-transport.js\"></script>\n<![endif]-->\n\n\n{% block extra_js %}\n    <!-- The jQuery UI widget factory, can be omitted if jQuery UI is already included -->\n    <script src=\"{{ url_for('static', filename='plugin/jQuery-File-Upload-9.18.0/js/vendor/jquery.ui.widget.js') }}\"></script>\n    <!-- The Templates plugin is included to render the upload/download listings -->\n    <script src=\"{{ url_for('static', filename='plugin/JavaScript-Templates-3.8.0/js/tmpl.min.js') }}\"></script>\n    <!-- The Load Image plugin is included for the preview images and image resizing functionality -->\n    <script src=\"{{ url_for('static', filename='plugin/JavaScript-Load-Image-2.12.2/js/load-image.all.min.js') }}\"></script>\n    <!-- The Canvas to Blob plugin is included for image resizing functionality -->\n    <script src=\"{{ url_for('static', filename='plugin/JavaScript-Canvas-to-Blob-3.7.0/js/canvas-to-blob.min.js') }}\"></script>\n    <!-- blueimp Gallery script -->\n    <script src=\"{{ url_for('static', filename='plugin/Gallery-2.25.0/js/jquery.blueimp-gallery.min.js') }}\"></script>\n    <!-- The Iframe Transport is required for browsers without support for XHR file uploads -->\n    <script src=\"{{ url_for('static', filename='plugin/jQuery-File-Upload-9.18.0/js/jquery.iframe-transport.js') }}\"></script>\n    <!-- The basic File Upload plugin -->\n    <script src=\"{{ url_for('static', filename='plugin/jQuery-File-Upload-9.18.0/js/jquery.fileupload.js') }}\"></script>\n    <!-- The File Upload processing plugin -->\n    <script src=\"{{ url_for('static', filename='plugin/jQuery-File-Upload-9.18.0/js/jquery.fileupload-process.js') }}\"></script>\n    <!-- The File Upload image preview & resize plugin -->\n    <script src=\"{{ url_for('static', filename='plugin/jQuery-File-Upload-9.18.0/js/jquery.fileupload-image.js') }}\"></script>\n    <!-- The File Upload audio preview plugin -->\n    <script src=\"{{ url_for('static', filename='plugin/jQuery-File-Upload-9.18.0/js/jquery.fileupload-audio.js') }}\"></script>\n    <!-- The File Upload video preview plugin -->\n    <script src=\"{{ url_for('static', filename='plugin/jQuery-File-Upload-9.18.0/js/jquery.fileupload-video.js') }}\"></script>\n    <!-- The File Upload validation plugin -->\n    <script src=\"{{ url_for('static', filename='plugin/jQuery-File-Upload-9.18.0/js/jquery.fileupload-validate.js') }}\"></script>\n    <!-- The File Upload user interface plugin -->\n    <script src=\"{{ url_for('static', filename='plugin/jQuery-File-Upload-9.18.0/js/jquery.fileupload-ui.js') }}\"></script>\n\n    <!-- The XDomainRequest Transport is included for cross-domain file deletion for IE 8 and IE 9 -->\n    <!--[if (gte IE 8)&(lt IE 10)]>\n    <script src=\"{{ url_for('static', filename='plugin/jQuery-File-Upload-9.18.0/js/cors/jquery.xdr-transport.js') }}\"></script>\n    <![endif]-->\n    <script>\n    $(function () {\n        //初始化，主要是设置上传参数，以及事件处理方法(回调函数)\n        $('#fileupload').fileupload({\n            change: function(e, data) {\n                if(data.files.length > 2){\n                    alert(\"最多允许上传2张图片\");\n                    return false;\n                }\n            },\n            drop: function(e, data) {\n                if(data.files.length > 2){\n                    alert(\"最多允许上传2张图片\");\n                    return false;\n                }\n            }\n        });\n\n        // Load existing files:\n        $('#fileupload').addClass('fileupload-processing');\n        $.ajax({\n            // Uncomment the following to send cross-domain cookies:\n            //xhrFields: {withCredentials: true},\n            url: $('#fileupload').fileupload('option', 'url'),\n            dataType: 'json',\n            context: $('#fileupload')[0]\n        }).always(function () {\n            $(this).removeClass('fileupload-processing');\n        }).done(function (result) {\n            $(this).fileupload('option', 'done')\n                .call(this, $.Event('done'), {result: result});\n        });\n    });\n    // 支付状态确认\n    function order_pay(order_id, status_pay) {\n        // console.log($(form).serialize());\n        $.ajax({\n            url: \"{{ url_for('order.ajax_pay') }}\",\n            type: 'POST',\n            data: {order_id: order_id, status_pay: status_pay},\n            dataType: 'json',\n            success: function (result) {\n                // console.log(result);\n                if(result.hasOwnProperty('error')){\n                    alert(result.error);\n                }else {\n                    alert(result.success);\n                    document.location.reload();\n                }\n            }\n        });\n        return false;\n    }\n    </script>\n{% endblock %}\n"
  },
  {
    "path": "app_frontend/templates/order/put_list.html",
    "content": "<!-- extend from base layout -->\n{% extends \"layout.html\" %}\n\n{% block extra_css %}\n\n{% endblock %}\n\n{% block content %}\n    <div class=\"container\">\n    <!-- header -->\n    <nav class=\"sub-header row container-fluid\">\n        <ol class=\"breadcrumb\">\n            <li><a href=\"/\">首页</a></li>\n            <li class=\"active\">投资中心</li>\n            <li class=\"active\">投资订单</li>\n        </ol>\n        <div class=\"btn-group pull-right\" role=\"group\" aria-label=\"...\">\n            {% if request.query_string == 'status_pay=2' %}\n            <a type=\"button\" class=\"btn btn-default\" href=\"{{ url_for('order.lists_put') }}\">等待支付</a>\n            <a type=\"button\" class=\"btn btn-default\" href=\"{{ url_for('order.lists_put', status_pay=1) }}\">支付成功</a>\n            <a type=\"button\" class=\"btn btn-default active\">支付失败</a>\n            {% elif request.query_string == 'status_pay=1' %}\n            <a type=\"button\" class=\"btn btn-default\" href=\"{{ url_for('order.lists_put') }}\">等待支付</a>\n            <a type=\"button\" class=\"btn btn-default active\">支付成功</a>\n            <a type=\"button\" class=\"btn btn-default\" href=\"{{ url_for('order.lists_put', status_pay=2) }}\">支付失败</a>\n            {% else %}\n            <a type=\"button\" class=\"btn btn-default active\">等待支付</a>\n            <a type=\"button\" class=\"btn btn-default\" href=\"{{ url_for('order.lists_put', status_pay=1) }}\">支付成功</a>\n            <a type=\"button\" class=\"btn btn-default\" href=\"{{ url_for('order.lists_put', status_pay=2) }}\">支付失败</a>\n            {% endif %}\n        </div>\n    </nav>\n\n    <hr/>\n    <!-- content -->\n    <div class=\"table-responsive\">\n        {# <table class=\"table table-striped\"> #}\n        <table class=\"table table-hover\">\n            <thead>\n            <tr>\n                <th>订单ID</th>\n                <th>投资ID</th>\n                <th>提现ID</th>\n                <th>提现用户</th>\n                <th>订单金额</th>\n                <th>认证状态</th>\n                <th>支付状态</th>\n                <th>确认状态</th>\n                <th>匹配时间</th>\n                <th>操作</th>\n            </tr>\n            </thead>\n            <tbody>\n            {% for order, user_profile in pagination.items %}\n            <tr class=\"text-muted\">\n                <td>{{ order.id }}</td>\n                <td>{{ order.apply_put_id }}</td>\n                <td>{{ order.apply_get_id }}</td>\n                <td>{{ user_profile.nickname }} [{{ order.apply_get_uid }}]</td>\n                <td>{{ order.money }}</td>\n                <td>{{ order.status_audit | status_audit }}</td>\n                <td>{{ order.status_pay | status_pay }}</td>\n                <td>{{ order.status_rec | status_rec }}</td>\n                <td>{{ moment(order.create_time).format('YYYY-MM-DD HH:mm:ss') }}</td>\n                <td>\n                    <a class=\"btn-sm btn-default\" href=\"{{ url_for('order.info_put', order_id=order.id) }}\" rel=\"tooltip\" title=\"订单详情\"><span class=\"glyphicon glyphicon-list-alt\"></span> 订单详情</a>\n                    <a class=\"btn-sm btn-default\" href=\"{{ url_for('message.add', user_id=order.apply_get_uid) }}\" rel=\"tooltip\" title=\"留言\"><span class=\"glyphicon glyphicon-list-alt\"></span> 留言</a>\n                    <a class=\"btn-sm btn-default\" href=\"{{ url_for('complaint.add', user_id=order.apply_get_uid) }}\" rel=\"tooltip\" title=\"投诉\"><span class=\"glyphicon glyphicon-list-alt\"></span> 投诉</a>\n{#                    <a href=\"javascript:void(0);\" onclick=\"order_delete({{ order.id }});\" rel=\"tooltip\" title=\"删除\"><span class=\"glyphicon glyphicon-trash\"></span></a>#}\n                </td>\n            </tr>\n            {% endfor %}\n            </tbody>\n        </table>\n        {# 翻页 #}\n        {% from \"macros.html\" import render_pagination %}\n        {{ render_pagination(pagination, 'order.lists_put') }}\n    </div>\n    </div>\n{% endblock %}\n\n{% block extra_js %}\n<script>\n\n</script>\n{% endblock %}\n"
  },
  {
    "path": "app_frontend/templates/reg/_agreement.html",
    "content": "\n<div class=\"modal fade\" id=\"agreement\" tabindex=\"-1\" role=\"dialog\" aria-labelledby=\"myModalLabel\">\n    <div class=\"modal-dialog\" role=\"document\">\n        <div class=\"modal-content\">\n            <div class=\"modal-header\">\n                <button type=\"button\" class=\"close\" data-dismiss=\"modal\" aria-label=\"Close\"><span\n                        aria-hidden=\"true\">&times;</span></button>\n                <h4 class=\"modal-title\" id=\"myModalLabel\">注册协议</h4>\n            </div>\n            <div class=\"modal-body\">\n                <h4>会员责任</h4>\n                <p>1、不得利用本站危害国家安全、泄露国家秘密，不得侵犯国家社会集体的和公民的合法权益，不得利用本站制作、复制和传播下列信息：<br>\n　　（1）煽动抗拒、破坏宪法和法律、行政法规实施的；<br>\n　　（2）煽动颠覆国家政权，推翻社会主义制度的；<br>\n　　（3）煽动分裂国家、破坏国家统一的；<br>\n　　（4）煽动民族仇恨、民族歧视，破坏民族团结的；<br>\n　　（5）捏造或者歪曲事实，散布谣言，扰乱社会秩序的；<br>\n　　（6）宣扬封建迷信、淫秽、色情、赌博、暴力、凶杀、恐怖、教唆犯罪的；<br>\n　　（7）公然侮辱他人或者捏造事实诽谤他人的，或者进行其他恶意攻击的；<br>\n　　（8）损害国家机关信誉的；<br>\n　　（9）其他违反宪法和法律行政法规的；<br>\n　　（10）进行商业广告行为的。</p>\n                <p>2、未经本站的授权或许可，任何会员不得借用本站的名义从事任何商业活动，也不得将本站作为从事商业活动的场所、平台或其他任何形式的媒介。禁止将本站用作从事各种非法活动的场所、平台或者其他任何形式的媒介。违反者若触犯法律，一切后果自负，本站不承担任何责任。</p>\n            </div>\n            <div class=\"modal-footer\">\n                <button type=\"button\" class=\"btn btn-default\" data-dismiss=\"modal\">关闭</button>\n                <button type=\"button\" class=\"btn btn-primary\" data-dismiss=\"modal\">我已了解</button>\n            </div>\n        </div>\n    </div>\n</div>"
  },
  {
    "path": "app_frontend/templates/reg/_agreement_en.html",
    "content": "\n<div class=\"modal fade\" id=\"agreement\" tabindex=\"-1\" role=\"dialog\" aria-labelledby=\"myModalLabel\">\n    <div class=\"modal-dialog\" role=\"document\">\n        <div class=\"modal-content\">\n            <div class=\"modal-header\">\n                <button type=\"button\" class=\"close\" data-dismiss=\"modal\" aria-label=\"Close\"><span\n                        aria-hidden=\"true\">&times;</span></button>\n                <h4 class=\"modal-title\" id=\"myModalLabel\">Agreement</h4>\n            </div>\n            <div class=\"modal-body\">\n                <h4>Tooltips in a modal</h4>\n                <p><a href=\"#\" class=\"tooltip-test\" title=\"\" data-original-title=\"Tooltip\">This link</a> and <a\n                        href=\"#\" class=\"tooltip-test\" title=\"\" data-original-title=\"Tooltip\">that link</a> should\n                    have tooltips on hover.</p>\n                <hr>\n                <h4>Overflowing text to show scroll behavior</h4>\n                <p>Cras mattis consectetur purus sit amet fermentum. Cras justo odio, dapibus ac facilisis in,\n                    egestas eget quam. Morbi leo risus, porta ac consectetur ac, vestibulum at eros.</p>\n                <p>Praesent commodo cursus magna, vel scelerisque nisl consectetur et. Vivamus sagittis lacus vel\n                    augue laoreet rutrum faucibus dolor auctor.</p>\n                <p>Aenean lacinia bibendum nulla sed consectetur. Praesent commodo cursus magna, vel scelerisque\n                    nisl consectetur et. Donec sed odio dui. Donec ullamcorper nulla non metus auctor fringilla.</p>\n                <p>Cras mattis consectetur purus sit amet fermentum. Cras justo odio, dapibus ac facilisis in,\n                    egestas eget quam. Morbi leo risus, porta ac consectetur ac, vestibulum at eros.</p>\n                <p>Praesent commodo cursus magna, vel scelerisque nisl consectetur et. Vivamus sagittis lacus vel\n                    augue laoreet rutrum faucibus dolor auctor.</p>\n                <p>Aenean lacinia bibendum nulla sed consectetur. Praesent commodo cursus magna, vel scelerisque\n                    nisl consectetur et. Donec sed odio dui. Donec ullamcorper nulla non metus auctor fringilla.</p>\n                <p>Cras mattis consectetur purus sit amet fermentum. Cras justo odio, dapibus ac facilisis in,\n                    egestas eget quam. Morbi leo risus, porta ac consectetur ac, vestibulum at eros.</p>\n                <p>Praesent commodo cursus magna, vel scelerisque nisl consectetur et. Vivamus sagittis lacus vel\n                    augue laoreet rutrum faucibus dolor auctor.</p>\n                <p>Aenean lacinia bibendum nulla sed consectetur. Praesent commodo cursus magna, vel scelerisque\n                    nisl consectetur et. Donec sed odio dui. Donec ullamcorper nulla non metus auctor fringilla.</p>\n            </div>\n            <div class=\"modal-footer\">\n                <button type=\"button\" class=\"btn btn-default\" data-dismiss=\"modal\">Close</button>\n                <button type=\"button\" class=\"btn btn-primary\" data-dismiss=\"modal\">I Known</button>\n            </div>\n        </div>\n    </div>\n</div>"
  },
  {
    "path": "app_frontend/templates/reg/email.html",
    "content": "{% extends \"layout.html\" %}\n\n{% block content %}\n    <div class=\"container\">\n    <h2>邮箱注册</h2>\n\n    {# 表单 #}\n    <form class=\"form-horizontal\" method=\"post\" action=\"{{ url_for('reg.email') }}\">\n        {{ form.csrf_token }}\n        {# 标签导航 #}\n\n        <ul class=\"nav nav-tabs\">  {# 填充整个导航条：nav-justified #}\n            <li role=\"presentation\"><a href=\"{{ url_for('reg.index') }}\">账号注册</a></li>\n            <li role=\"presentation\"><a href=\"{{ url_for('reg.phone') }}\">手机注册</a></li>\n            <li role=\"presentation\" class=\"active\"><a href=\"{{ url_for('reg.email') }}\">邮箱注册</a></li>\n        </ul>\n        <div class=\"form-group\">{{ form.user_pid }}</div>\n        <div class=\"form-group\">\n            {{ form.user_pid.label(class=\"col-sm-2 control-label\") }}\n            <div class=\"col-sm-10\">\n                <div class=\"form-control\">{{ form.user_pid.data | nickname }}</div>\n            </div>\n        </div>\n\n        <div class=\"form-group{% if form.email.errors %} has-error{% endif %}\">\n            {{ form.email.label(class=\"col-sm-2 control-label\") }}\n            <div class=\"col-sm-10\">\n                {{ form.email(class=\"form-control\", placeholder=\"登录邮箱\") }}\n                {% for error in form.email.errors %}\n                    <span class=\"help-block\">{{ error }}</span>\n                {% endfor %}\n            </div>\n        </div>\n        <div class=\"form-group{% if form.password.errors %} has-error{% endif %}\">\n            {{ form.password.label(class=\"col-sm-2 control-label\") }}\n            <div class=\"col-sm-10\">\n                {{ form.password(class=\"form-control\", placeholder=\"登录密码[6-20位]\", minlength=6, maxlength=20) }}\n                {% for error in form.password.errors %}\n                    <span class=\"help-block\">{{ error }}</span>\n                {% endfor %}\n            </div>\n        </div>\n        <div class=\"form-group{% if form.confirm.errors %} has-error{% endif %}\">\n            {{ form.confirm.label(class=\"col-sm-2 control-label\") }}\n            <div class=\"col-sm-10\">\n                {{ form.confirm(class=\"form-control\", placeholder=\"登录密码[6-20位]\", minlength=6, maxlength=20) }}\n                {% for error in form.confirm.errors %}\n                    <span class=\"help-block\">{{ error }}</span>\n                {% endfor %}\n            </div>\n        </div>\n        <div class=\"form-group{% if form.accept_agreement.errors %} has-error{% endif %}\">\n            <div class=\"col-sm-offset-2 col-sm-10\">\n                <div class=\"checkbox\">\n                    <label>\n                        {{ form.accept_agreement }} 我已阅读并同意 <a href=\"#\" data-toggle=\"modal\" data-target=\"#agreement\">《注册协议》</a>\n                    </label>\n                    {% for error in form.accept_agreement.errors %}\n                    <span class=\"help-block\">{{ error }}</span>\n                    {% endfor %}\n                </div>\n            </div>\n        </div>\n        <div class=\"form-group\">\n            <div class=\"col-sm-offset-2 col-sm-10\">\n                <button type=\"submit\" class=\"btn btn-default btn-load\" data-loading-text=\"注册中\">注册</button>\n            </div>\n        </div>\n    </form>\n    </div>\n\n    <!-- 注册协议 -->\n    {% include('reg/_agreement.html') %}\n\n{% endblock %}\n\n{% block extra_js %}\n<script>\n    // 初始化赋值\n    $('.selectpicker').selectpicker('val', 'a');\n    // 处理选项修改\n    $('#reg_type').on('changed.bs.select', function (event, clickedIndex, newValue, oldValue) {\n        // console.log($('.selectpicker').val());\n        // console.log(event);\n        // console.log(clickedIndex);\n        // console.log(newValue);\n        // console.log(oldValue);\n    });\n</script>\n{% endblock %}\n"
  },
  {
    "path": "app_frontend/templates/reg/index.html",
    "content": "{% extends \"layout.html\" %}\n\n{% block content %}\n    <div class=\"container\">\n    <h2>账号注册</h2>\n\n    {# 表单 #}\n    <form class=\"form-horizontal\" method=\"post\" action=\"{{ url_for('reg.index') }}\">\n        {{ form.csrf_token }}\n        {# 标签导航 #}\n\n{#        <ul class=\"nav nav-tabs\">  {# 填充整个导航条：nav-justified #}\n{#            <li role=\"presentation\" class=\"active\"><a href=\"{{ url_for('reg.index') }}\">账号注册</a></li>#}\n{#            <li role=\"presentation\"><a href=\"{{ url_for('reg.phone') }}\">手机注册</a></li>#}\n{#            <li role=\"presentation\"><a href=\"{{ url_for('reg.email') }}\">邮箱注册</a></li>#}\n{#        </ul>#}\n        <div class=\"form-group\">{{ form.user_pid }}</div>\n        <div class=\"form-group\">\n            {{ form.user_pid.label(class=\"col-sm-2 control-label\") }}\n            <div class=\"col-sm-10\">\n                <div class=\"form-control\">{{ form.user_pid.data | nickname }}</div>\n            </div>\n        </div>\n\n        <div class=\"form-group{% if form.account.errors %} has-error{% endif %}\">\n            {{ form.account.label(class=\"col-sm-2 control-label\") }}\n            <div class=\"col-sm-10\">\n                {{ form.account(class=\"form-control\", placeholder=\"登录账号[2-20位]\", minlength=2, maxlength=20) }}\n                {% for error in form.account.errors %}\n                    <span class=\"help-block\">{{ error }}</span>\n                {% endfor %}\n            </div>\n        </div>\n        <div class=\"form-group{% if form.password.errors %} has-error{% endif %}\">\n            {{ form.password.label(class=\"col-sm-2 control-label\") }}\n            <div class=\"col-sm-10\">\n                {{ form.password(class=\"form-control\", placeholder=\"登录密码[6-20位]\", minlength=6, maxlength=20) }}\n                {% for error in form.password.errors %}\n                    <span class=\"help-block\">{{ error }}</span>\n                {% endfor %}\n            </div>\n        </div>\n        <div class=\"form-group{% if form.confirm.errors %} has-error{% endif %}\">\n            {{ form.confirm.label(class=\"col-sm-2 control-label\") }}\n            <div class=\"col-sm-10\">\n                {{ form.confirm(class=\"form-control\", placeholder=\"登录密码[6-20位]\", minlength=6, maxlength=20) }}\n                {% for error in form.confirm.errors %}\n                    <span class=\"help-block\">{{ error }}</span>\n                {% endfor %}\n            </div>\n        </div>\n        <div class=\"form-group{% if form.captcha.errors %} has-error{% endif %}\">\n            {{ form.captcha.label(class=\"col-sm-2 col-xs-12 control-label\") }}\n            <div class=\"col-sm-8 col-xs-8\">\n                {{ form.captcha(class=\"form-control\", placeholder=\"图形验证码\", maxlength=4) }}\n                {% for error in form.captcha.errors %}\n                    <span class=\"help-block\">{{ error }}</span>\n                {% endfor %}\n            </div>\n            <div class=\"col-sm-2 col-xs-2\">\n                <img src=\"{{ url_for('captcha.get_code', code_type='reg') }}\" rel=\"tooltip\" title=\"看不清？换一张\" id=\"captcha_img\" onclick=\"refresh_code();\">\n            </div>\n        </div>\n        <div class=\"form-group{% if form.accept_agreement.errors %} has-error{% endif %}\">\n            <div class=\"col-sm-offset-2 col-sm-10\">\n                <div class=\"checkbox\">\n                    <label>\n                        {{ form.accept_agreement }} 我已阅读并同意 <a href=\"#\" data-toggle=\"modal\" data-target=\"#agreement\">《注册协议》</a>\n                    </label>\n                    {% for error in form.accept_agreement.errors %}\n                    <span class=\"help-block\">{{ error }}</span>\n                    {% endfor %}\n                </div>\n            </div>\n        </div>\n        <div class=\"form-group\">\n            <div class=\"col-sm-offset-2 col-sm-10\">\n                <button type=\"submit\" class=\"btn btn-default btn-load\" data-loading-text=\"注册中\">注册</button>\n            </div>\n        </div>\n    </form>\n    </div>\n\n    <!-- 注册协议 -->\n    {% include('reg/_agreement.html') %}\n\n{% endblock %}\n\n{% block extra_js %}\n<script>\n    // 初始化赋值\n    $('.selectpicker').selectpicker('val', 'a');\n    // 处理选项修改\n    $('#reg_type').on('changed.bs.select', function (event, clickedIndex, newValue, oldValue) {\n        // console.log($('.selectpicker').val());\n        // console.log(event);\n        // console.log(clickedIndex);\n        // console.log(newValue);\n        // console.log(oldValue);\n    });\n\n    // 刷新验证码\n    function refresh_code() {\n        var now = new Date();\n        $('#captcha_img')[0].setAttribute(\"src\", \"{{ url_for('captcha.get_code', code_type='reg') }}\" + \"?t=\" + now.getTime());\n    }\n</script>\n{% endblock %}\n"
  },
  {
    "path": "app_frontend/templates/reg/phone.html",
    "content": "{% extends \"layout.html\" %}\n\n{% block content %}\n    <div class=\"container\">\n    <h2>手机注册</h2>\n\n    {# 表单 #}\n    <form class=\"form-horizontal\" method=\"post\" action=\"{{ url_for('reg.phone') }}\">\n        {{ form.csrf_token }}\n        {# 标签导航 #}\n\n        <ul class=\"nav nav-tabs\">  {# 填充整个导航条：nav-justified #}\n            <li role=\"presentation\"><a href=\"{{ url_for('reg.index') }}\">账号注册</a></li>\n            <li role=\"presentation\" class=\"active\"><a href=\"{{ url_for('reg.phone') }}\">手机注册</a></li>\n            <li role=\"presentation\"><a href=\"{{ url_for('reg.email') }}\">邮箱注册</a></li>\n        </ul>\n        <div class=\"form-group\">{{ form.user_pid }}</div>\n        <div class=\"form-group\">\n            {{ form.user_pid.label(class=\"col-sm-2 control-label\") }}\n            <div class=\"col-sm-10\">\n                <div class=\"form-control\">{{ form.user_pid.data | nickname }}</div>\n            </div>\n        </div>\n\n        <div class=\"form-group{% if form.area_id.errors %} has-error{% endif %}\">\n            {{ form.area_id.label(class=\"col-sm-2 control-label\") }}\n            <div class=\"col-sm-10\">\n                {{ form.area_id(data_header=\"选择手机区号\") }}\n                {% for error in form.area_id.errors %}\n                    <span class=\"help-block\">{{ error }}</span>\n                {% endfor %}\n            </div>\n        </div>\n\n        <div class=\"form-group{% if form.phone.errors %} has-error{% endif %}\">\n            {{ form.phone.label(class=\"col-sm-2 control-label\") }}\n            <div class=\"col-sm-10\">\n                {{ form.phone(class=\"form-control\", placeholder=\"登录手机\", type=\"tel\", maxlength=11) }}\n                {% for error in form.phone.errors %}\n                    <span class=\"help-block\">{{ error }}</span>\n                {% endfor %}\n            </div>\n        </div>\n\n        <div class=\"form-group{% if form.captcha.errors %} has-error{% endif %}\">\n\n            {{ form.captcha.label(class=\"col-sm-2 col-xs-12 control-label\") }}\n\n            <div class=\"col-sm-8 col-xs-8\">\n                {{ form.captcha(class=\"form-control\", placeholder=\"图形验证码\", maxlength=4) }}\n                {% for error in form.captcha.errors %}\n                    <span class=\"help-block\">{{ error }}</span>\n                {% endfor %}\n            </div>\n            <div class=\"col-sm-2 col-xs-2\">\n                <img src=\"{{ url_for('captcha.get_code', code_type='reg') }}\" rel=\"tooltip\" title=\"看不清？换一张\" id=\"captcha_img\" onclick=\"refresh_code();\">\n            </div>\n        </div>\n\n        <div class=\"form-group{% if form.sms.errors %} has-error{% endif %}\">\n            {{ form.sms.label(class=\"col-sm-2 control-label\") }}\n            <div class=\"col-sm-10\">\n                <div class=\"input-group\">\n                    {{ form.sms(class=\"form-control\", placeholder=\"短信验证码\", maxlength=6) }}\n                    <span class=\"input-group-btn\">\n                        <button id=\"get_sms_btn\" class=\"btn btn-default\" type=\"button\">\n                            <span class=\"glyphicon glyphicon-envelope\"></span> <i>发送短信</i>\n                        </button>\n                    </span>\n                </div>\n                {% for error in form.sms.errors %}\n                    <span class=\"help-block\">{{ error }}</span>\n                {% endfor %}\n            </div>\n        </div>\n\n\n\n        <div class=\"form-group{% if form.password.errors %} has-error{% endif %}\">\n            {{ form.password.label(class=\"col-sm-2 control-label\") }}\n            <div class=\"col-sm-10\">\n                {{ form.password(class=\"form-control\", placeholder=\"登录密码[6-20位]\", maxlength=20) }}\n                {% for error in form.password.errors %}\n                    <span class=\"help-block\">{{ error }}</span>\n                {% endfor %}\n            </div>\n        </div>\n        <div class=\"form-group{% if form.confirm.errors %} has-error{% endif %}\">\n            {{ form.confirm.label(class=\"col-sm-2 control-label\") }}\n            <div class=\"col-sm-10\">\n                {{ form.confirm(class=\"form-control\", placeholder=\"登录密码[6-20位]\", maxlength=20) }}\n                {% for error in form.confirm.errors %}\n                    <span class=\"help-block\">{{ error }}</span>\n                {% endfor %}\n            </div>\n        </div>\n        <div class=\"form-group{% if form.accept_agreement.errors %} has-error{% endif %}\">\n            <div class=\"col-sm-offset-2 col-sm-10\">\n                <div class=\"checkbox\">\n                    <label>\n                        {{ form.accept_agreement }} 我已阅读并同意 <a href=\"#\" data-toggle=\"modal\" data-target=\"#agreement\">《注册协议》</a>\n                    </label>\n                    {% for error in form.accept_agreement.errors %}\n                    <span class=\"help-block\">{{ error }}</span>\n                    {% endfor %}\n                </div>\n            </div>\n        </div>\n        <div class=\"form-group\">\n            <div class=\"col-sm-offset-2 col-sm-10\">\n                <button type=\"submit\" class=\"btn btn-default btn-load\" data-loading-text=\"注册中\">注册</button>\n            </div>\n        </div>\n    </form>\n    </div>\n\n    <!-- 注册协议 -->\n    {% include('reg/_agreement.html') %}\n\n{% endblock %}\n\n{% block extra_js %}\n<script>\n    // 初始化赋值\n    var area_id = $('#area_id');\n    area_id.selectpicker('val', '{{ form.area_id.data }}');\n    // 处理选项修改\n    area_id.on('changed.bs.select', function (event, clickedIndex, newValue, oldValue) {\n        // console.log($('#area_id').val());\n        // console.log(event);\n        // console.log(clickedIndex);\n        // console.log(newValue);\n        // console.log(oldValue);\n    });\n    // 刷新验证码\n    function refresh_code() {\n        var now = new Date();\n        $('#captcha_img')[0].setAttribute(\"src\", \"{{ url_for('captcha.get_code', code_type='reg') }}\" + \"?t=\" + now.getTime());\n    }\n\n    // 倒计时\n    var countdown=60;\n    function set_time(val) {\n        if (countdown == 0) {\n            val.removeAttr(\"disabled\");\n            val.find(\"i\").first().html(\"发送短信\");\n            countdown = 60;\n            return;\n        } else {\n            val.attr(\"disabled\", true);\n            val.find(\"i\").first().html(\"重新发送(\" + countdown + \")\");\n            countdown--;\n        }\n        setTimeout(function () {\n            set_time(val)\n        }, 1000)\n    }\n    // 点击发送手机验证码到手机 - ajax\n    $('#get_sms_btn').click(function () {\n        var cur_obj = $(this);\n        var phone = $('#phone');\n        var captcha = $('#captcha');\n        // 校验手机号码，图形验证码\n        if(!phone.val()){\n            phone.focus();\n            return;\n        }\n        if(!captcha.val()){\n            captcha.focus();\n            return;\n        }\n        // 校验图形验证码\n        //console.log(captcha.val());\n        $.getJSON('{{ url_for('reg.ajax_get_sms_code') }}',\n            {\n                area_id: area_id.val(),\n                phone: phone.val(),\n                code_str: captcha.val()\n            }, function (data) {\n                var result = data.result;  // true/false\n                if(result==false){\n                    //console.log(result);\n                    refresh_code();\n                    captcha.focus();\n                    return false;\n                }else {\n                    $('#sms').focus();\n                    set_time(cur_obj);\n                }\n            }\n        );\n    });\n</script>\n{% endblock %}\n"
  },
  {
    "path": "app_frontend/templates/scheduling/list.html",
    "content": "<!-- extend from base layout -->\n{% extends \"layout.html\" %}\n\n{% block extra_css %}\n\n{% endblock %}\n\n{% block content %}\n    <div class=\"container\">\n    <!-- header -->\n    <nav class=\"sub-header row container-fluid\">\n        <ol class=\"breadcrumb\">\n            <li><a href=\"/\">首页</a></li>\n            <li class=\"active\">排单列表 <span class=\"badge\">{{ current_user.id | scheduling_amount }}</span></li>\n        </ol>\n        <div class=\"btn-group pull-right\" role=\"group\" aria-label=\"...\">\n            {% if not request.query_string %}\n            <a type=\"button\" class=\"btn btn-default active\">全部</a>\n            <a type=\"button\" class=\"btn btn-default\" href=\"{{ url_for('scheduling.lists', scheduling_list=1) }}\">用户排单</a>\n            <a type=\"button\" class=\"btn btn-default\" href=\"{{ url_for('scheduling.lists', scheduling_list=2) }}\">系统发送</a>\n            {% elif request.query_string==\"scheduling_list=1\" %}\n            <a type=\"button\" class=\"btn btn-default\" href=\"{{ url_for('scheduling.lists') }}\">全部</a>\n            <a type=\"button\" class=\"btn btn-default active\">用户排单</a>\n            <a type=\"button\" class=\"btn btn-default\" href=\"{{ url_for('scheduling.lists', scheduling_list=2) }}\">系统发送</a>\n            {% elif request.query_string==\"scheduling_list=2\" %}\n            <a type=\"button\" class=\"btn btn-default\" href=\"{{ url_for('scheduling.lists') }}\">全部</a>\n            <a type=\"button\" class=\"btn btn-default\" href=\"{{ url_for('scheduling.lists', scheduling_list=1) }}\">用户排单</a>\n            <a type=\"button\" class=\"btn btn-default active\">系统发送</a>\n            {% endif %}\n        </div>\n    </nav>\n\n\n    <hr/>\n    <!-- content -->\n    <div class=\"table-responsive\">\n        {# <table class=\"table table-striped\"> #}\n        <table class=\"table table-hover\">\n            <thead>\n            <tr>\n                <th>排单明细ID</th>\n                <th>用户</th>\n                <th>类型</th>\n                <th>数量</th>\n                <th>时间</th>\n            </tr>\n            </thead>\n            <tbody>\n            {% for scheduling, user_profile_put, user_profile_get in pagination.items %}\n            <tr class=\"text-muted\">\n                <td>{{ scheduling.id }}</td>\n                <td>{{ user_profile_get.nickname }} [{{ scheduling.sc_id }}]</td>\n                <td>{{ scheduling.type | type_scheduling }}</td>\n                <td>{{ scheduling.amount }}</td>\n                <td>{{ moment(scheduling.create_time).format('YYYY-MM-DD HH:mm:ss') }}</td>\n            </tr>\n            {% endfor %}\n            </tbody>\n        </table>\n        {# 翻页 #}\n        {% from \"macros.html\" import render_pagination %}\n        {{ render_pagination(pagination, 'scheduling.lists') }}\n    </div>\n    </div>\n{% endblock %}\n\n{% block extra_js %}\n\n{% endblock %}\n"
  },
  {
    "path": "app_frontend/templates/score/charity_list.html",
    "content": "<!-- extend from base layout -->\n{% extends \"layout.html\" %}\n\n{% block extra_css %}\n\n{% endblock %}\n\n{% block content %}\n    <div class=\"container\">\n    <!-- header -->\n    <nav class=\"sub-header row container-fluid\">\n        <ol class=\"breadcrumb\">\n            <li><a href=\"/\">首页</a></li>\n            <li class=\"active\">积分中心</li>\n            <li class=\"active\">慈善积分 <span class=\"badge\">{{ current_user.id | score_charity }}</span></li>\n        </ol>\n        <div class=\"btn-group pull-right\" role=\"group\" aria-label=\"...\">\n        {% if not request.query_string %}\n            <a type=\"button\" class=\"btn btn-default active\">全部</a>\n            <a type=\"button\" class=\"btn btn-default\" href=\"{{ url_for('score.charity_lists', score_type=1) }}\">获得</a>\n            <a type=\"button\" class=\"btn btn-default\" href=\"{{ url_for('score.charity_lists', score_type=2) }}\">消费</a>\n        {% elif request.query_string == 'score_type=1' %}\n            <a type=\"button\" class=\"btn btn-default\" href=\"{{ url_for('score.charity_lists') }}\">全部</a>\n            <a type=\"button\" class=\"btn btn-default active\">获得</a>\n            <a type=\"button\" class=\"btn btn-default\" href=\"{{ url_for('score.charity_lists', score_type=2) }}\">消费</a>\n        {% elif request.query_string == 'score_type=2' %}\n            <a type=\"button\" class=\"btn btn-default\" href=\"{{ url_for('score.charity_lists') }}\">全部</a>\n            <a type=\"button\" class=\"btn btn-default\" href=\"{{ url_for('score.charity_lists', score_type=1) }}\">获得</a>\n            <a type=\"button\" class=\"btn btn-default active\">消费</a>\n        {% endif %}\n        </div>\n    </nav>\n\n    <hr/>\n    <!-- content -->\n    <div class=\"table-responsive\">\n        {# <table class=\"table table-striped\"> #}\n        <table class=\"table table-hover\">\n            <thead>\n            <tr>\n                <th>积分明细ID</th>\n                <th>类型</th>\n                <th>积分</th>\n                <th>备注</th>\n                <th>时间</th>\n            </tr>\n            </thead>\n            <tbody>\n            {% for score_item in pagination.items %}\n            <tr class=\"text-muted\">\n                <td>{{ score_item.id }}</td>\n                <td>{{ score_item.type | type_score }}</td>\n                <td>{{ score_item.amount }}</td>\n                <td>{{ score_item.note }}</td>\n                <td>{{ moment(score_item.create_time).format('YYYY-MM-DD HH:mm:ss') }}</td>\n            </tr>\n            {% endfor %}\n            </tbody>\n        </table>\n        {# 翻页 #}\n        {% from \"macros.html\" import render_pagination %}\n        {{ render_pagination(pagination, 'score.charity_lists') }}\n    </div>\n    </div>\n{% endblock %}\n\n{% block extra_js %}\n\n{% endblock %}\n"
  },
  {
    "path": "app_frontend/templates/score/digital_list.html",
    "content": "<!-- extend from base layout -->\n{% extends \"layout.html\" %}\n\n{% block extra_css %}\n\n{% endblock %}\n\n{% block content %}\n    <div class=\"container\">\n    <!-- header -->\n    <nav class=\"sub-header row container-fluid\">\n        <ol class=\"breadcrumb\">\n            <li><a href=\"/\">首页</a></li>\n            <li class=\"active\">积分中心</li>\n            <li class=\"active\">数字积分 <span class=\"badge\">{{ current_user.id | score_digital }}</span></li>\n        </ol>\n        <div class=\"btn-group pull-right\" role=\"group\" aria-label=\"...\">\n        {% if not request.query_string %}\n            <a type=\"button\" class=\"btn btn-default active\">全部</a>\n            <a type=\"button\" class=\"btn btn-default\" href=\"{{ url_for('score.digital_lists', score_type=1) }}\">获得</a>\n            <a type=\"button\" class=\"btn btn-default\" href=\"{{ url_for('score.digital_lists', score_type=2) }}\">消费</a>\n        {% elif request.query_string == 'score_type=1' %}\n            <a type=\"button\" class=\"btn btn-default\" href=\"{{ url_for('score.digital_lists') }}\">全部</a>\n            <a type=\"button\" class=\"btn btn-default active\">获得</a>\n            <a type=\"button\" class=\"btn btn-default\" href=\"{{ url_for('score.digital_lists', score_type=2) }}\">消费</a>\n        {% elif request.query_string == 'score_type=2' %}\n            <a type=\"button\" class=\"btn btn-default\" href=\"{{ url_for('score.digital_lists') }}\">全部</a>\n            <a type=\"button\" class=\"btn btn-default\" href=\"{{ url_for('score.digital_lists', score_type=1) }}\">获得</a>\n            <a type=\"button\" class=\"btn btn-default active\">消费</a>\n        {% endif %}\n        </div>\n    </nav>\n\n    <hr/>\n    <!-- content -->\n    <div class=\"table-responsive\">\n        {# <table class=\"table table-striped\"> #}\n        <table class=\"table table-hover\">\n            <thead>\n            <tr>\n                <th>积分明细ID</th>\n                <th>类型</th>\n                <th>积分</th>\n                <th>备注</th>\n                <th>时间</th>\n            </tr>\n            </thead>\n            <tbody>\n            {% for score_item in pagination.items %}\n            <tr class=\"text-muted\">\n                <td>{{ score_item.id }}</td>\n                <td>{{ score_item.type | type_score }}</td>\n                <td>{{ score_item.amount }}</td>\n                <td>{{ score_item.note }}</td>\n                <td>{{ moment(score_item.create_time).format('YYYY-MM-DD HH:mm:ss') }}</td>\n            </tr>\n            {% endfor %}\n            </tbody>\n        </table>\n        {# 翻页 #}\n        {% from \"macros.html\" import render_pagination %}\n        {{ render_pagination(pagination, 'score.digital_lists') }}\n    </div>\n    </div>\n{% endblock %}\n\n{% block extra_js %}\n\n{% endblock %}\n"
  },
  {
    "path": "app_frontend/templates/score/expense_list.html",
    "content": "<!-- extend from base layout -->\n{% extends \"layout.html\" %}\n\n{% block extra_css %}\n\n{% endblock %}\n\n{% block content %}\n    <div class=\"container\">\n    <!-- header -->\n    <nav class=\"sub-header row container-fluid\">\n        <ol class=\"breadcrumb\">\n            <li><a href=\"/\">首页</a></li>\n            <li class=\"active\">积分中心</li>\n            <li class=\"active\">消费积分 <span class=\"badge\">{{ current_user.id | score_expense }}</span></li>\n        </ol>\n        <div class=\"btn-group pull-right\" role=\"group\" aria-label=\"...\">\n        {% if not request.query_string %}\n            <a type=\"button\" class=\"btn btn-default active\">全部</a>\n            <a type=\"button\" class=\"btn btn-default\" href=\"{{ url_for('score.expense_lists', score_type=1) }}\">获得</a>\n            <a type=\"button\" class=\"btn btn-default\" href=\"{{ url_for('score.expense_lists', score_type=2) }}\">消费</a>\n        {% elif request.query_string == 'score_type=1' %}\n            <a type=\"button\" class=\"btn btn-default\" href=\"{{ url_for('score.expense_lists') }}\">全部</a>\n            <a type=\"button\" class=\"btn btn-default active\">获得</a>\n            <a type=\"button\" class=\"btn btn-default\" href=\"{{ url_for('score.expense_lists', score_type=2) }}\">消费</a>\n        {% elif request.query_string == 'score_type=2' %}\n            <a type=\"button\" class=\"btn btn-default\" href=\"{{ url_for('score.expense_lists') }}\">全部</a>\n            <a type=\"button\" class=\"btn btn-default\" href=\"{{ url_for('score.expense_lists', score_type=1) }}\">获得</a>\n            <a type=\"button\" class=\"btn btn-default active\">消费</a>\n        {% endif %}\n        </div>\n    </nav>\n\n    <hr/>\n    <!-- content -->\n    <div class=\"table-responsive\">\n        {# <table class=\"table table-striped\"> #}\n        <table class=\"table table-hover\">\n            <thead>\n            <tr>\n                <th>积分明细ID</th>\n                <th>类型</th>\n                <th>积分</th>\n                <th>备注</th>\n                <th>时间</th>\n            </tr>\n            </thead>\n            <tbody>\n            {% for score_item in pagination.items %}\n            <tr class=\"text-muted\">\n                <td>{{ score_item.id }}</td>\n                <td>{{ score_item.type | type_score }}</td>\n                <td>{{ score_item.amount }}</td>\n                <td>{{ score_item.note }}</td>\n                <td>{{ moment(score_item.create_time).format('YYYY-MM-DD HH:mm:ss') }}</td>\n            </tr>\n            {% endfor %}\n            </tbody>\n        </table>\n        {# 翻页 #}\n        {% from \"macros.html\" import render_pagination %}\n        {{ render_pagination(pagination, 'score.expense_lists') }}\n    </div>\n    </div>\n{% endblock %}\n\n{% block extra_js %}\n\n{% endblock %}\n"
  },
  {
    "path": "app_frontend/templates/setting.html",
    "content": "{% extends \"layout.html\" %}\n\n{% block content %}\n    <div class=\"container\">\n    <h2 class=\"sub-header\">Setting</h2>\n\n    <div class=\"row\">\n        <div class=\"col-lg-8 col-md-12\">\n            <section id=\"chart_line_graphs\">\n                <div class=\"panel panel-default\">\n                <div class=\"panel-heading\">\n                    <div class=\"btn-group pull-right\" role=\"group\" aria-label=\"...\">\n                        <button type=\"button\" class=\"btn btn-default btn-time-bar\">Day</button>\n                        <button type=\"button\" class=\"btn btn-default btn-time-bar\">Week</button>\n                        <button type=\"button\" class=\"btn btn-default btn-time-bar\">Month</button>\n                    </div>\n                    <strong class=\"panel-title\">\n                        <span class=\"glyphicon glyphicon-picture\"></span> Chart Line Graphs\n                    </strong>\n                </div>\n                <canvas id=\"chart_line_canvas\"></canvas>\n                </div>\n            </section>\n            <section id=\"chart_bar_graphs\">\n                <div class=\"panel panel-default\">\n                <div class=\"panel-heading\">\n                    <strong class=\"panel-title\">Chart Bar Graphs\n                    <span class=\"glyphicon glyphicon-picture pull-right\"></span>\n                    </strong>\n                </div>\n                <div class=\"panel-body text-center row\">\n                    <div class=\"col-lg-6 col-md-6 col-sm-6 col-xs-12\">\n                        <canvas id=\"chart_bar_canvas_01\"></canvas>\n                        <span class=\"text-muted\">Chart Bar Graphs Example 01</span>\n                    </div>\n                    <div class=\"col-lg-6 col-md-6 col-sm-6 col-xs-12\">\n                        <canvas id=\"chart_bar_canvas_02\"></canvas>\n                        <span class=\"text-muted\">Chart Bar Graphs Example 02</span>\n                    </div>\n                </div>\n                <div class=\"panel-footer text-center text-muted\">\n                    Chart Bar Graphs Example\n                </div>\n                </div>\n            </section>\n            <section id=\"user_profile\">\n                <div class=\"panel panel-default\">\n                <div class=\"panel-heading\">\n                    <strong class=\"panel-title\">User profile\n                    <span class=\"glyphicon glyphicon-cog pull-right\"></span>\n                    </strong>\n                </div>\n                <div class=\"panel-body\">\n                    <form class=\"form-horizontal\" method=\"post\" action=\"\">\n                    {{ form.csrf_token }}\n                    <div class=\"form-group{% if form.nickname.errors %} has-error{% endif %}\">\n                        {{ form.nickname.label(class=\"col-sm-2 control-label\") }}\n                        <div class=\"col-sm-10\">\n                            {{ form.nickname(class=\"form-control\", placeholder=\"nickname\") }}\n                            {% for error in form.nickname.errors %}\n                                <span class=\"help-block\">{{ error }}</span>\n                            {% endfor %}\n                        </div>\n                    </div>\n                    <div class=\"form-group{% if form.avatar_url.errors %} has-error{% endif %}\">\n                        {{ form.avatar_url.label(class=\"col-sm-2 control-label\") }}\n                        <div class=\"col-sm-10\">\n                            {{ form.avatar_url(class=\"form-control\", placeholder=\"avatar_url\") }}\n                            {% for error in form.avatar_url.errors %}\n                                <span class=\"help-block\">{{ error }}</span>\n                            {% endfor %}\n                        </div>\n                    </div>\n                    <div class=\"form-group{% if form.email.errors %} has-error{% endif %}\">\n                        {{ form.email.label(class=\"col-sm-2 control-label\") }}\n                        <div class=\"col-sm-10\">\n                            {{ form.email(class=\"form-control\", placeholder=\"Email\") }}\n                            {% for error in form.email.errors %}\n                                <span class=\"help-block\">{{ error }}</span>\n                            {% endfor %}\n                        </div>\n                    </div>\n                    <div class=\"form-group{% if form.phone.errors %} has-error{% endif %}\">\n                        {{ form.phone.label(class=\"col-sm-2 control-label\") }}\n                        <div class=\"col-sm-10\">\n                            {{ form.phone(class=\"form-control\", placeholder=\"Phone\") }}\n                            {% for error in form.phone.errors %}\n                                <span class=\"help-block\">{{ error }}</span>\n                            {% endfor %}\n                        </div>\n                    </div>\n                    <div class=\"form-group{% if form.birthday.errors %} has-error{% endif %}\">\n                        {{ form.birthday.label(class=\"col-sm-2 control-label\") }}\n                        <div class=\"col-sm-10\">\n                            {{ form.birthday(class=\"form-control\", placeholder=\"birthday\", type='date') }}\n                            {% for error in form.birthday.errors %}\n                                <span class=\"help-block\">{{ error }}</span>\n                            {% endfor %}\n                        </div>\n                    </div>\n                    <div class=\"form-group{% if form.create_time.errors %} has-error{% endif %}\">\n                        {{ form.create_time.label(class=\"col-sm-2 control-label\") }}\n                        <div class=\"col-sm-10\">\n                            {{ form.create_time(class=\"form-control\", placeholder=\"create_time\", readonly=\"readonly\") }}\n                            {% for error in form.create_time.errors %}\n                                <span class=\"help-block\">{{ error }}</span>\n                            {% endfor %}\n                        </div>\n                    </div>\n                    <div class=\"form-group{% if form.update_time.errors %} has-error{% endif %}\">\n                        {{ form.update_time.label(class=\"col-sm-2 control-label\") }}\n                        <div class=\"col-sm-10\">\n                            {{ form.update_time(class=\"form-control\", placeholder=\"update_time\", readonly=\"readonly\") }}\n                            {% for error in form.update_time.errors %}\n                                <span class=\"help-block\">{{ error }}</span>\n                            {% endfor %}\n                        </div>\n                    </div>\n                    <div class=\"form-group\">\n                        <div class=\"col-sm-offset-2 col-sm-10\">\n                            <button type=\"submit\" class=\"btn btn-default\">Edit</button>\n                            <button type=\"reset\" class=\"btn btn-default\">Reset</button>\n                        </div>\n                    </div>\n                </form>\n                </div>\n            </div>\n            </section>\n            <section id=\"first_options\">\n                <div class=\"panel panel-default\">\n                <div class=\"panel-heading\">\n                    <strong class=\"panel-title\">First server management options\n                    <span class=\"glyphicon glyphicon-cog pull-right\"></span>\n                    </strong>\n                </div>\n                <table class=\"table\">\n                    <thead>\n                        <tr>\n                            <th>Permission Item</th>\n                            <th>Community Edition</th>\n                            <th><b>Enterprise Edition</b></th>\n                        </tr>\n                    </thead>\n                    <tbody>\n                        <tr>\n                            <td><a href=\"#\">Create and remove admins based on an LDAP group</a></td>\n                            <td><span class=\"glyphicon glyphicon-remove\"></span></td>\n                            <td><span class=\"glyphicon glyphicon-ok\"></span></td>\n                        </tr>\n                        <tr>\n                            <td><a href=\"#\">Groups consisting of multiple people with a shared namespace</a></td>\n                            <td><span class=\"glyphicon glyphicon-ok\"></span></td>\n                            <td><span class=\"glyphicon glyphicon-remove\"></span></td>\n                        </tr>\n                        <tr>\n                            <td><a href=\"#\">Close JIRA issues with GitLab commits</a></td>\n                            <td><span class=\"glyphicon glyphicon-ok\"></span></td>\n                            <td><span class=\"glyphicon glyphicon-remove\"></span></td>\n                        </tr>\n                    </tbody>\n                </table>\n                </div>\n            </section>\n            <section id=\"user_permissions\">\n                <div class=\"panel panel-default\">\n                <div class=\"panel-heading\">\n                    <strong class=\"panel-title\">User permissions\n                    <span class=\"glyphicon glyphicon-cog pull-right\"></span>\n                    </strong>\n                </div>\n                <table class=\"table\">\n                    <thead>\n                        <tr>\n                            <th>Permission Item</th>\n                            <th>Community Edition</th>\n                            <th><b>Enterprise Edition</b></th>\n                        </tr>\n                    </thead>\n                    <tbody>\n                        <tr>\n                            <td><a href=\"#\">Create and remove admins based on an LDAP group</a></td>\n                            <td><span class=\"glyphicon glyphicon-remove\"></span></td>\n                            <td><span class=\"glyphicon glyphicon-ok\"></span></td>\n                        </tr>\n                        <tr>\n                            <td><a href=\"#\">Groups consisting of multiple people with a shared namespace</a></td>\n                            <td><span class=\"glyphicon glyphicon-ok\"></span></td>\n                            <td><span class=\"glyphicon glyphicon-remove\"></span></td>\n                        </tr>\n                        <tr>\n                            <td><a href=\"#\">Close JIRA issues with GitLab commits</a></td>\n                            <td><span class=\"glyphicon glyphicon-ok\"></span></td>\n                            <td><span class=\"glyphicon glyphicon-remove\"></span></td>\n                        </tr>\n                        <tr>\n                            <td><a href=\"#\">Groups consisting of multiple people with a shared namespace</a></td>\n                            <td><span class=\"glyphicon glyphicon-ok\"></span></td>\n                            <td><span class=\"glyphicon glyphicon-remove\"></span></td>\n                        </tr>\n                        <tr>\n                            <td><a href=\"#\">Close JIRA issues with GitLab commits</a></td>\n                            <td><span class=\"glyphicon glyphicon-ok\"></span></td>\n                            <td><span class=\"glyphicon glyphicon-remove\"></span></td>\n                        </tr>\n                    </tbody>\n                </table>\n                </div>\n            </section>\n            <section id=\"additional_options\">\n                <div class=\"panel panel-default\">\n                <div class=\"panel-heading\">\n                    <strong class=\"panel-title\">Additional server management options\n                    <span class=\"glyphicon glyphicon-cog pull-right\"></span>\n                    </strong>\n                </div>\n                <table class=\"table\">\n                    <thead>\n                        <tr>\n                            <th>Permission Item</th>\n                            <th>Community Edition</th>\n                            <th><b>Enterprise Edition</b></th>\n                        </tr>\n                    </thead>\n                    <tbody>\n                        <tr>\n                            <td><a href=\"#\">Create and remove admins based on an LDAP group</a></td>\n                            <td><span class=\"glyphicon glyphicon-remove\"></span></td>\n                            <td><span class=\"glyphicon glyphicon-ok\"></span></td>\n                        </tr>\n                        <tr>\n                            <td><a href=\"#\">Groups consisting of multiple people with a shared namespace</a></td>\n                            <td><span class=\"glyphicon glyphicon-ok\"></span></td>\n                            <td><span class=\"glyphicon glyphicon-remove\"></span></td>\n                        </tr>\n                        <tr>\n                            <td><a href=\"#\">Close JIRA issues with GitLab commits</a></td>\n                            <td><span class=\"glyphicon glyphicon-ok\"></span></td>\n                            <td><span class=\"glyphicon glyphicon-remove\"></span></td>\n                        </tr>\n                        <tr>\n                            <td><a href=\"#\">Create and remove admins based on an LDAP group</a></td>\n                            <td><span class=\"glyphicon glyphicon-remove\"></span></td>\n                            <td><span class=\"glyphicon glyphicon-ok\"></span></td>\n                        </tr>\n                        <tr>\n                            <td><a href=\"#\">Groups consisting of multiple people with a shared namespace</a></td>\n                            <td><span class=\"glyphicon glyphicon-ok\"></span></td>\n                            <td><span class=\"glyphicon glyphicon-remove\"></span></td>\n                        </tr>\n                        <tr>\n                            <td><a href=\"#\">Close JIRA issues with GitLab commits</a></td>\n                            <td><span class=\"glyphicon glyphicon-ok\"></span></td>\n                            <td><span class=\"glyphicon glyphicon-remove\"></span></td>\n                        </tr>\n                        <tr>\n                            <td><a href=\"#\">Create and remove admins based on an LDAP group</a></td>\n                            <td><span class=\"glyphicon glyphicon-remove\"></span></td>\n                            <td><span class=\"glyphicon glyphicon-ok\"></span></td>\n                        </tr>\n                        <tr>\n                            <td><a href=\"#\">Groups consisting of multiple people with a shared namespace</a></td>\n                            <td><span class=\"glyphicon glyphicon-ok\"></span></td>\n                            <td><span class=\"glyphicon glyphicon-remove\"></span></td>\n                        </tr>\n                        <tr>\n                            <td><a href=\"#\">Close JIRA issues with GitLab commits</a></td>\n                            <td><span class=\"glyphicon glyphicon-ok\"></span></td>\n                            <td><span class=\"glyphicon glyphicon-remove\"></span></td>\n                        </tr>\n                    </tbody>\n                </table>\n                </div>\n            </section>\n            <section id=\"last_options\">\n                <div class=\"panel panel-default\">\n                <div class=\"panel-heading\">\n                    <strong class=\"panel-title\">Last server management options\n                    <span class=\"glyphicon glyphicon-cog pull-right\"></span>\n                    </strong>\n                </div>\n                <table class=\"table\">\n                    <thead>\n                        <tr>\n                            <th>Permission Item</th>\n                            <th>Community Edition</th>\n                            <th><b>Enterprise Edition</b></th>\n                        </tr>\n                    </thead>\n                    <tbody>\n                        <tr>\n                            <td><a href=\"#\">Create and remove admins based on an LDAP group</a></td>\n                            <td><span class=\"glyphicon glyphicon-remove\"></span></td>\n                            <td><span class=\"glyphicon glyphicon-ok\"></span></td>\n                        </tr>\n                        <tr>\n                            <td><a href=\"#\">Groups consisting of multiple people with a shared namespace</a></td>\n                            <td><span class=\"glyphicon glyphicon-ok\"></span></td>\n                            <td><span class=\"glyphicon glyphicon-remove\"></span></td>\n                        </tr>\n                        <tr>\n                            <td><a href=\"#\">Close JIRA issues with GitLab commits</a></td>\n                            <td><span class=\"glyphicon glyphicon-ok\"></span></td>\n                            <td><span class=\"glyphicon glyphicon-remove\"></span></td>\n                        </tr>\n                    </tbody>\n                </table>\n                </div>\n            </section>\n            <section id=\"contributions\">\n                <div class=\"panel panel-default\">\n                <div class=\"panel-heading\">\n                    <strong class=\"panel-title\">Contributions\n                    <span class=\"glyphicon glyphicon-stats pull-right\"></span>\n                    </strong>\n                </div>\n                <table class=\"table table-bordered text-center\">\n                    <tr>\n                        <td class=\"col-lg-4 col-md-4 col-sm-4 col-xs-4\">\n                            <span class=\"text-muted center-block\">Contributions in the last year</span>\n                            <h2 class=\"center-block\">432 total</h2>\n                            <span class=\"text-muted center-block\">Feb 20, 2015 – Feb 20, 2016</span>\n                        </td>\n                        <td class=\"col-lg-4 col-md-4 col-sm-4 col-xs-4\">\n                            <span class=\"text-muted center-block\">Longest streak</span>\n                            <h2 class=\"center-block\">48 days</h2>\n                            <span class=\"text-muted center-block\">October 23 – December 9</span>\n                        </td>\n                        <td class=\"col-lg-4 col-md-4 col-sm-4 col-xs-4\">\n                            <span class=\"text-muted center-block\">Current streak</span>\n                            <h2 class=\"center-block\">4 days</h2>\n                            <span class=\"text-muted center-block\">February 17 – February 20</span>\n                        </td>\n                    </tr>\n                </table>\n            </div>\n            </section>\n            <section id=\"nothing\">\n                <div class=\"well well-large text-center\">\n                    Nothing yet.\n                </div>\n            </section>\n        </div>\n\n        <nav class=\"col-lg-4 col-md-12\" id=\"affix_nav\">\n            <ul class=\"nav nav-pills nav-stacked\" data-spy=\"affix\" data-offset-top=\"10\" id=\"affix_nav_ul\">\n                <li class=\"active\">\n                    <a href=\"#chart_line_graphs\" class=\"list-group-item\">\n                        <span class=\"glyphicon glyphicon-chevron-right\"></span> Chart Line Graphs\n                    </a>\n                </li>\n                <li>\n                    <a href=\"#chart_bar_graphs\" class=\"list-group-item\">\n                        <span class=\"glyphicon glyphicon-chevron-right\"></span> Chart Bar Graphs\n                    </a>\n                </li>\n                <li>\n                    <a href=\"#user_profile\" class=\"list-group-item\">\n                        <span class=\"glyphicon glyphicon-chevron-right\"></span> User profile\n                    </a>\n                </li>\n                <li>\n                    <a href=\"#first_options\" class=\"list-group-item\">\n                        <span class=\"glyphicon glyphicon-chevron-right\"></span> First server management options\n                    </a>\n                </li>\n                <li>\n                    <a href=\"#user_permissions\" class=\"list-group-item\">\n                        <span class=\"glyphicon glyphicon-chevron-right\"></span> User permissions\n                    </a>\n                </li>\n                <li>\n                    <a href=\"#additional_options\" class=\"list-group-item\">\n                        <span class=\"glyphicon glyphicon-chevron-right\"></span> Additional server management options\n                    </a>\n                </li>\n                <li>\n                    <a href=\"#last_options\" class=\"list-group-item\">\n                        <span class=\"glyphicon glyphicon-chevron-right\"></span> Last server management options\n                    </a>\n                </li>\n                <li>\n                    <a href=\"#contributions\" class=\"list-group-item\">\n                        <span class=\"glyphicon glyphicon-chevron-right\"></span> Contributions\n                    </a>\n                </li>\n                <li>\n                    <a href=\"#nothing\" class=\"list-group-item\">\n                        <span class=\"glyphicon glyphicon-chevron-right\"></span> Nothing\n                    </a>\n                </li>\n            </ul>\n        </nav>\n    </div>\n    </div>\n{% endblock %}\n\n{% block extra_js %}\n<script>\n    /* 创建Line图表 */\n    var lineChartData = {\n        labels : [\"January\",\"February\",\"March\",\"April\",\"May\",\"June\",\"July\"],\n        datasets : [\n            {\n                fillColor : \"rgba(220,220,220,0.5)\",\n                strokeColor : \"rgba(220,220,220,1)\",\n                pointColor : \"rgba(220,220,220,1)\",\n                pointStrokeColor : \"#fff\",\n                data : [65,59,90,81,56,55,40]\n            },\n            {\n                fillColor : \"rgba(151,187,205,0.5)\",\n                strokeColor : \"rgba(151,187,205,1)\",\n                pointColor : \"rgba(151,187,205,1)\",\n                pointStrokeColor : \"#fff\",\n                data : [28,48,40,19,96,27,100]\n            }\n        ]\n    };\n\n    $(function() {\n        var ctx = $(\"#chart_line_canvas\").get(0).getContext(\"2d\");\n        new Chart(ctx).Line(lineChartData, {responsive: true});\n    });\n\n    /* 创建Bar图表 */\n    var randomScalingFactor = function(){ return Math.round(Math.random()*100)};\n\tvar barChartData01 = {\n\t\tlabels : [\"January\",\"February\",\"March\",\"April\",\"May\",\"June\",\"July\"],\n\t\tdatasets : [\n\t\t\t{\n\t\t\t\tfillColor : \"rgba(220,220,220,0.5)\",\n\t\t\t\tstrokeColor : \"rgba(220,220,220,0.8)\",\n\t\t\t\thighlightFill: \"rgba(220,220,220,0.75)\",\n\t\t\t\thighlightStroke: \"rgba(220,220,220,1)\",\n\t\t\t\tdata : [randomScalingFactor(),randomScalingFactor(),randomScalingFactor(),randomScalingFactor(),randomScalingFactor(),randomScalingFactor(),randomScalingFactor()]\n\t\t\t},\n\t\t\t{\n\t\t\t\tfillColor : \"rgba(151,187,205,0.5)\",\n\t\t\t\tstrokeColor : \"rgba(151,187,205,0.8)\",\n\t\t\t\thighlightFill : \"rgba(151,187,205,0.75)\",\n\t\t\t\thighlightStroke : \"rgba(151,187,205,1)\",\n\t\t\t\tdata : [randomScalingFactor(),randomScalingFactor(),randomScalingFactor(),randomScalingFactor(),randomScalingFactor(),randomScalingFactor(),randomScalingFactor()]\n\t\t\t}\n\t\t]\n\t};\n    $(function() {\n        var ctx = $(\"#chart_bar_canvas_01\").get(0).getContext(\"2d\");\n        new Chart(ctx).Bar(barChartData01, {responsive: true});\n    });\n    var barChartData02 = {\n\t\tlabels : [\"January\",\"February\",\"March\",\"April\",\"May\",\"June\",\"July\"],\n\t\tdatasets : [\n\t\t\t{\n\t\t\t\tfillColor : \"rgba(220,220,220,0.5)\",\n\t\t\t\tstrokeColor : \"rgba(220,220,220,0.8)\",\n\t\t\t\thighlightFill: \"rgba(220,220,220,0.75)\",\n\t\t\t\thighlightStroke: \"rgba(220,220,220,1)\",\n\t\t\t\tdata : [randomScalingFactor(),randomScalingFactor(),randomScalingFactor(),randomScalingFactor(),randomScalingFactor(),randomScalingFactor(),randomScalingFactor()]\n\t\t\t},\n\t\t\t{\n\t\t\t\tfillColor : \"rgba(151,187,205,0.5)\",\n\t\t\t\tstrokeColor : \"rgba(151,187,205,0.8)\",\n\t\t\t\thighlightFill : \"rgba(151,187,205,0.75)\",\n\t\t\t\thighlightStroke : \"rgba(151,187,205,1)\",\n\t\t\t\tdata : [randomScalingFactor(),randomScalingFactor(),randomScalingFactor(),randomScalingFactor(),randomScalingFactor(),randomScalingFactor(),randomScalingFactor()]\n\t\t\t}\n\t\t]\n\t};\n    $(function() {\n        var ctx = $(\"#chart_bar_canvas_02\").get(0).getContext(\"2d\");\n        new Chart(ctx).Bar(barChartData02, {responsive: true});\n    });\n</script>\n{% endblock %}\n"
  },
  {
    "path": "app_frontend/templates/site/index.html",
    "content": "{% extends \"layout.html\" %}\n\n{% block content %}\n<!-- .carousel -->\n<div id=\"myCarousel\" class=\"carousel slide\" data-ride=\"carousel\">\n    <!-- Indicators -->\n    <ol class=\"carousel-indicators\">\n        {% for i in range(6) %}\n            <li data-target=\"#myCarousel\" data-slide-to=\"{{ i }}\"{% if i==0 %} class=\"active\"{% endif %}></li>\n        {% endfor %}\n    </ol>\n\n    <div class=\"carousel-inner\">\n        {% for i in range(1,7) %}\n        <div class=\"item{% if i==1 %} active{% endif %}\">\n            <img class=\"lazy center-block img-responsive\" src=\"{{ url_for('static', filename='img/load-line.gif') }}\" data-src=\"/static/img/{{ i }}.jpg\" alt=\"{{ loop.index }} slide\">\n            <div class=\"container\">\n                <div class=\"carousel-caption\">\n                    <h1>{{ loop.index }} slide</h1>\n                    <div class=\"visible-lg\">\n                        <p><span class=\"glyphicon glyphicon-map-marker\"></span> Address: Level 10, No.700, East Yanan Road, Huangpu District, Shanghai, P. R. China</p>\n                        <p><span class=\"glyphicon glyphicon-envelope\"></span> Email: info@company.com</p>\n                        <p><span class=\"glyphicon glyphicon-phone-alt\"></span> Phone: 021-8888-6666</p>\n                        <p><span class=\"glyphicon glyphicon-phone\"></span> Mobile: 138-1873-2593</p>\n                        <p><a class=\"btn btn-lg btn-primary\" href=\"#\" role=\"button\">Enter Info</a></p>\n                    </div>\n                </div>\n            </div>\n        </div>\n        {% endfor %}\n    </div>\n    <a class=\"left carousel-control\" href=\"#myCarousel\" data-slide=\"prev\">\n        <span class=\"glyphicon glyphicon-chevron-left\"></span>\n    </a>\n    <a class=\"right carousel-control\" href=\"#myCarousel\" data-slide=\"next\">\n        <span class=\"glyphicon glyphicon-chevron-right\"></span>\n    </a>\n</div><!-- /.carousel -->\n\n{% endblock %}"
  },
  {
    "path": "app_frontend/templates/theme/default/_footer.html",
    "content": "<footer id=\"footer\">\n    <div class=\"container\">\n        <div class=\"row about\">\n            <div class=\"col-md-4 hidden-xs\">\n                <div class=\"col-md-4\">\n                    <dl>\n                        <dt>网站首页</dt>\n                        <dd><a href=\"#\">关于我们</a></dd>\n                        <dd><a href=\"#\">企业文化</a></dd>\n                        <dd><a href=\"#\">团队介绍</a></dd>\n                        <dd><a href=\"#\">产品特点</a></dd>\n                    </dl>\n                </div>\n                <div class=\"col-md-4\">\n                    <dl>\n                        <dt>投资保障</dt>\n                        <dd><a href=\"#\">全系列产品</a></dd>\n                        <dd><a href=\"#\">资产证券化</a></dd>\n                        <dd><a href=\"#\">实时大数据</a></dd>\n                    </dl>\n                </div>\n                <div class=\"col-md-4\">\n                    <dl>\n                        <dt>产品功能</dt>\n                        <dd><a href=\"#\">增强免疫</a></dd>\n                        <dd><a href=\"#\">抗氧化抗疲劳</a></dd>\n                        <dd><a href=\"#\">调节内分泌</a></dd>\n                        <dd><a href=\"#\">抗风湿</a></dd>\n                    </dl>\n                </div>\n            </div>\n            <div class=\"col-md-3 weixin\">\n                <h3>关注我们</h3>\n                <div class=\"col-xs-6\">\n                    <img src=\"{{ url_for('static', filename='theme/default/img/wx.png') }}\" class=\"img-responsive img-rounded\">\n                    <p>关注微信</p>\n                </div>\n                <div class=\"col-xs-6\">\n                    <img src=\"{{ url_for('static', filename='theme/default/img/wx.png') }}\" class=\"img-responsive img-rounded\">\n                    <p>关注微博</p>\n                </div>\n            </div>\n            <div class=\"col-md-5\">\n               <div class=\"row-hr hidden-xs\">\n                   <div class=\"tel\">\n                       <p>客服热线（工作时间 8:00-22:00）</p>\n                       <p class=\"number\">400-888-8888</p>\n                   </div>\n               </div>\n                <div class=\"address\">\n                    <p>地址：湖北省蕲春县李时珍医药工业园凯迪大道</p>\n                    <p>Copyright ©2009-2017 Edai Corporation.All Rights Reserved.</p>\n                    <p>濠源生物科技有限公司 蜀ICP备13010370号-1川 B -20120039</p>\n                </div>\n            </div>\n        </div>\n    </div>\n</footer>"
  },
  {
    "path": "app_frontend/templates/theme/default/_header.html",
    "content": "<div class=\"header sticky-header\">\n    <!-- Navbar -->\n    <div class=\"navbar navbar-default mega-menu\" role=\"navigation\">\n        <div class=\"container\">\n            <!-- Brand and toggle mobile display -->\n            <div class=\"navbar-header\">\n                <button type=\"button\" class=\"navbar-toggle\" data-toggle=\"collapse\" data-target=\".navbar-responsive-collapse\">\n                    <span class=\"sr-only\">Toggle navigation</span>\n                    <span class=\"fa fa-bars\"></span>\n                </button>\n                <a class=\"navbar-brand\" href=\"{{ url_for('index') }}\" style=\"margin-top:0px;padding-top:0px;\">\n                    <img id=\"logo-header\" src=\"{{ url_for('static', filename='theme/default/img/logo.png') }}\" alt=\"Logo\"/>\n                </a>\n            </div>\n\n            <!-- Nav links-->\n            <div class=\"collapse navbar-collapse mega-menu navbar-responsive-collapse\">\n                <ul class=\"nav navbar-nav navbar-left\">\n                    <li><a href=\"{{ url_for('index') }}\">首页</a></li>\n\n                {% if current_user and current_user.is_authenticated %}\n                    <li class=\"dropdown{% if 'put' in request.path %} active{% endif %}\">\n                        <a href=\"#\" class=\"dropdown-toggle\" data-toggle=\"dropdown\" role=\"button\" aria-haspopup=\"true\"\n                           aria-expanded=\"false\"><span class=\"glyphicon glyphicon-paste\"></span> 投资中心 <span\n                                class=\"caret\"></span></a>\n                        <ul class=\"dropdown-menu\">\n                        {% if request.path == url_for('order.lists_put') %}\n                            <li class=\"dropdown-header\"><span class=\"glyphicon glyphicon-list-alt\"></span> 投资订单</li>\n                        {% else %}\n                            <li><a href=\"{{ url_for('order.lists_put') }}\"><span class=\"glyphicon glyphicon-list-alt\"></span> 投资订单</a></li>\n                        {% endif %}\n                        {% if request.path == url_for('apply.lists_put') %}\n                            <li class=\"dropdown-header\"><span class=\"glyphicon glyphicon-th-list\"></span> 申请记录</li>\n                        {% else %}\n                            <li><a href=\"{{ url_for('apply.lists_put') }}\"><span class=\"glyphicon glyphicon-th-list\"></span> 申请记录</a></li>\n                        {% endif %}\n                        {% if request.path == url_for('apply.add_put') %}\n                            <li class=\"dropdown-header\"><span class=\"glyphicon glyphicon-plus\"></span> 我要投资</li>\n                        {% else %}\n                            <li><a href=\"{{ url_for('apply.add_put') }}\"><span class=\"glyphicon glyphicon-plus\"></span> 我要投资</a></li>\n                        {% endif %}\n                        </ul>\n                    </li>\n                    <li class=\"dropdown{% if 'get' in request.path %} active{% endif %}\">\n                        <a href=\"#\" class=\"dropdown-toggle\" data-toggle=\"dropdown\" role=\"button\" aria-haspopup=\"true\"\n                           aria-expanded=\"false\"><span class=\"glyphicon glyphicon-copy\"></span> 提现中心 <span\n                                class=\"caret\"></span></a>\n                        <ul class=\"dropdown-menu\">\n                        {% if request.path == url_for('order.lists_get') %}\n                            <li class=\"dropdown-header\"><span class=\"glyphicon glyphicon-list-alt\"></span> 提现订单</li>\n                        {% else %}\n                            <li><a href=\"{{ url_for('order.lists_get') }}\"><span class=\"glyphicon glyphicon-list-alt\"></span> 提现订单</a></li>\n                        {% endif %}\n                        {% if request.path == url_for('apply.lists_get') %}\n                            <li class=\"dropdown-header\"><span class=\"glyphicon glyphicon-th-list\"></span> 申请记录</li>\n                        {% else %}\n                            <li><a href=\"{{ url_for('apply.lists_get') }}\"><span class=\"glyphicon glyphicon-th-list\"></span> 申请记录</a></li>\n                        {% endif %}\n                        {% if request.path == url_for('apply.add_get') %}\n                            <li class=\"dropdown-header\"><span class=\"glyphicon glyphicon-plus\"></span> 我要提现</li>\n                        {% else %}\n                            <li><a href=\"{{ url_for('apply.add_get') }}\"><span class=\"glyphicon glyphicon-plus\"></span> 我要提现</a></li>\n                        {% endif %}\n                        </ul>\n                    </li>\n                    <li class=\"dropdown{% if 'active' in request.path %} active{% endif %}\">\n                        <a href=\"#\" class=\"dropdown-toggle\" data-toggle=\"dropdown\" role=\"button\" aria-haspopup=\"true\"\n                           aria-expanded=\"false\"><span class=\"glyphicon glyphicon-flag\"></span> 激活中心 <span\n                                class=\"caret\"></span></a>\n                        <ul class=\"dropdown-menu\">\n                        {% if request.path == url_for('active.lists') %}\n                            <li class=\"dropdown-header\"><span class=\"glyphicon glyphicon-list-alt\"></span> 激活记录</li>\n                        {% else %}\n                            <li><a href=\"{{ url_for('active.lists') }}\"><span class=\"glyphicon glyphicon-list-alt\"></span> 激活记录</a></li>\n                        {% endif %}\n                        {% if request.path == url_for('active.add') %}\n                            <li class=\"dropdown-header\"><span class=\"glyphicon glyphicon-plus\"></span> 赠送激活</li>\n                        {% else %}\n                            <li><a href=\"{{ url_for('active.add') }}\"><span class=\"glyphicon glyphicon-plus\"></span> 赠送激活</a></li>\n                        {% endif %}\n                        </ul>\n                    </li>\n                    <li class=\"dropdown{% if 'score' in request.path %} active{% endif %}\">\n                        <a href=\"#\" class=\"dropdown-toggle\" data-toggle=\"dropdown\" role=\"button\" aria-haspopup=\"true\"\n                           aria-expanded=\"false\"><span class=\"glyphicon glyphicon-shopping-cart\"></span> 积分中心 <span\n                                class=\"caret\"></span></a>\n                        <ul class=\"dropdown-menu\">\n                        {% if request.path == url_for('score.charity_lists') %}\n                            <li class=\"dropdown-header\"><span class=\"glyphicon glyphicon-list-alt\"></span> 慈善积分</li>\n                        {% else %}\n                            <li><a href=\"{{ url_for('score.charity_lists') }}\"><span class=\"glyphicon glyphicon-list-alt\"></span> 慈善积分</a></li>\n                        {% endif %}\n                        {% if request.path == url_for('score.digital_lists') %}\n                            <li class=\"dropdown-header\"><span class=\"glyphicon glyphicon-list-alt\"></span> 数字积分</li>\n                        {% else %}\n                            <li><a href=\"{{ url_for('score.digital_lists') }}\"><span class=\"glyphicon glyphicon-list-alt\"></span> 数字积分</a></li>\n                        {% endif %}\n                        {% if request.path == url_for('score.expense_lists') %}\n                            <li class=\"dropdown-header\"><span class=\"glyphicon glyphicon-list-alt\"></span> 消费积分</li>\n                        {% else %}\n                            <li><a href=\"{{ url_for('score.expense_lists') }}\"><span class=\"glyphicon glyphicon-list-alt\"></span> 消费积分</a></li>\n                        {% endif %}\n                        </ul>\n                    </li>\n                {% else %}\n                    <li><a href=\"#about\">关于我们</a></li>\n                    <li><a href=\"#culture\">企业文化</a></li>\n                    <li><a href=\"#product\">产品特点</a></li>\n                {% endif %}\n                </ul>\n                <ul class=\"nav navbar-nav navbar-right\">\n                {% if current_user and current_user.is_authenticated %}\n                    <li class=\"dropdown\">\n                        <a href=\"#\" class=\"dropdown-toggle\" data-toggle=\"dropdown\" role=\"button\" aria-haspopup=\"true\" aria-expanded=\"false\">\n                            <span class=\"glyphicon glyphicon-envelope\"></span> 消息中心\n                            <span class=\"caret\"></span>\n                        </a>\n                        <ul class=\"dropdown-menu\">\n                            <li>\n                                <a href=\"{{ url_for('message.lists') }}\">\n                                    <span class=\"glyphicon glyphicon-folder-open\"></span> 留言记录\n                                </a>\n                            </li>\n                            <li role=\"separator\" class=\"divider\"></li>\n                            <li>\n                                <a href=\"{{ url_for('complaint.lists') }}\">\n                                    <span class=\"glyphicon glyphicon-book\"></span> 投诉记录\n                                </a>\n                            </li>\n                        </ul>\n                    </li>\n                {% endif %}\n                {% if current_user and current_user.is_authenticated %}\n                    <li class=\"dropdown{% if 'user' in request.path %} active{% endif %}\">\n                        <a href=\"#\" class=\"dropdown-toggle\" data-toggle=\"dropdown\" role=\"button\"\n                           aria-haspopup=\"true\"\n                           aria-expanded=\"false\"><span\n                                class=\"glyphicon glyphicon-user\"></span> {{ current_user.id | user_name_level }}<span\n                                class=\"caret\"></span></a>\n                        <ul class=\"dropdown-menu\">\n                            <li{% if request.path == url_for('user.profile') %} class=\"active\"{% endif %}>\n                                <a href=\"{{ url_for('user.profile') }}\">\n                                    <span class=\"glyphicon glyphicon-folder-open\"></span> 用户中心\n                                </a>\n                            </li>\n                            <li{% if request.path == url_for('user.team') %} class=\"active\"{% endif %}>\n                                <a href=\"{{ url_for('user.team') }}\">\n                                    <span class=\"glyphicon glyphicon-king\"></span> 我的团队\n                                </a>\n                            </li>\n                            <li{% if request.path == url_for('scheduling.lists') %} class=\"active\"{% endif %}>\n                                <a href=\"{{ url_for('scheduling.lists') }}\">\n                                    <span class=\"glyphicon glyphicon-list-alt\"></span> 排单明细\n                                </a>\n                            </li>\n                            <li role=\"separator\" class=\"divider\"></li>\n                            <li>\n                                <a href=\"{{ url_for('auth.logout') }}\">\n                                    <span class=\"glyphicon glyphicon-log-out\"></span> 退出登录\n                                </a>\n                            </li>\n                        </ul>\n                    </li>\n                {% else %}\n                    <li{% if title == 'reg' %} class=\"active\"{% endif %}><a href=\"{{ url_for('reg.index') }}\"><span\n                            class=\"glyphicon glyphicon-list-alt\"></span> 注册</a></li>\n                    <li{% if title == 'login' %} class=\"active\"{% endif %}><a href=\"{{ url_for('auth.index') }}\"><span\n                            class=\"glyphicon glyphicon-log-in\"></span> 登录</a></li>\n                {% endif %}\n                </ul>\n\n            </div>\n        </div>\n    </div>\n    <!-- End Navbar -->\n</div>"
  },
  {
    "path": "app_frontend/templates/theme/default/index.html",
    "content": "{% extends \"theme/default/layout.html\" %}\n\n{% block content %}\n            <!-- START SLIDER -->\n            <section class=\"clearfix\">\n                <div  id=\"mega-slider\" class=\"carousel slide\" data-ride=\"carousel\">\n                    <ol class=\"carousel-indicators\">\n                        <li data-target=\"#mega-slider\" data-slide-to=\"0\" class=\"active\"></li>\n                        <li data-target=\"#mega-slider\" data-slide-to=\"1\"></li>\n                        <li data-target=\"#mega-slider\" data-slide-to=\"2\"></li>\n                    </ol>\n                    <div class=\"carousel-inner\" role=\"listbox\">\n                        <div class=\"item active beactive\">\n                            <img src=\"{{ url_for('static', filename='theme/default/img/banner/slide-1.jpg') }}\" alt=\"...\">\n                            <div class=\"carousel-caption\">\n                                <h2></h2>\n                                <p></p>\n                            </div>\n                        </div>\n                        <div class=\"item\">\n                            <img src=\"{{ url_for('static', filename='theme/default/img/banner/slide-2.jpg') }}\" alt=\"...\">\n                            <div class=\"carousel-caption\">\n                                <h2></h2>\n                                <p></p>\n                            </div>\n                        </div>\n                        <div class=\"item\">\n                            <img src=\"{{ url_for('static', filename='theme/default/img/banner/slide-3.jpg') }}\" alt=\"...\">\n                            <div class=\"carousel-caption\">\n                                <h2></h2>\n                                <p></p>\n                            </div>\n                        </div>\n                    </div>\n                    <!-- Controls -->\n                    <a class=\"left carousel-control\" href=\"#mega-slider\" role=\"button\" data-slide=\"prev\">\n                    </a>\n                    <a class=\"right carousel-control\" href=\"#mega-slider\" role=\"button\" data-slide=\"next\">\n                    </a>\n                </div>\n            </section>\n            <!-- END SLIDER -->\n\n\n            <!-- START ABOUT US -->\n            <section class=\"home-main-contant-style bg-white\">\n                <div class=\"container\">\n                    <div class=\"row\">\n                        <div class=\"col-md-6 welcome-img\">\n                            <img class=\"img-responsive\" src=\"{{ url_for('static', filename='theme/default/img/imac1.png') }}\" alt=\"\">\n                        </div>\n\n                        <div class=\"col-md-6\" id=\"about\">\n                            <div class=\"mb30\"></div>\n                            <h5>关于我们</h5>\n                            <!--h2 class=\"mb15\"><strong>CLASSIFY</strong></h2-->\n                            <p>湖北濠源生物科技有限公司：是一家高科技生物制品企业，主要生产无苦味大豆寡肽；</p><br>\n                            <p class=\"mb15\">国内唯一一家真正生产完全小分子量段的厂家，获得国家发明专利201110047296.9；质量管理体系认证：GB/T19001-2008 ISO9001：2008标准</p>\n\t\t\t\t\t\t\t<p class=\"mb15\">2011到2014年，通过小试、中试、工业化生产，现产大豆寡肽粉剂300吨，公司占地60亩，总建筑面积约10000平方米，现有工人120人，资产总额2亿七千万元。</p>\n                            <a class=\"btn btn-product\" href=\"#\">了解更多</a>\n                        </div>\n                    </div>\n                </div>\n            </section>\n            <!-- END ABOUT US -->\n\n\n            <!--START SERVICE-->\n            <section class=\"home-main-contant-style bg-gray\">\n                <div class=\"container\">\n                    <div class=\"row\">\n                        <div class=\"col-md-4 col-sm-6 col-xs-12\">\n                            <div class=\"service-item\">\n                                <div class=\"icon\">\n                                    <i class=\"fa fa-thumbs-o-up\" aria-hidden=\"true\"></i>\n                                </div>\n                                <div class=\"service-desc\">\n                                    <h5>来源安全</h5>\n                                    <p>非转基因大豆为原料，从大豆分离蛋白中提取</p>\n                                </div>\n                            </div>\n                        </div>\n                        <div class=\"col-md-4 col-sm-6 col-xs-12\">\n                            <div class=\"service-item\">\n                                <div class=\"icon\">\n                                    <i class=\"fa fa-gift\" aria-hidden=\"true\"></i>\n                                </div>\n                                <div class=\"service-desc\">\n                                    <h5>机理安全</h5>\n                                    <p>提供原料合成各种抗氧化剂、激素、酶等</p>\n                                </div>\n                            </div>\n                        </div>\n                        <div class=\"col-md-4 col-sm-6 col-xs-12\">\n                            <div class=\"service-item\">\n                                <div class=\"icon\">\n                                    <i class=\"fa fa-envelope-o\" aria-hidden=\"true\"></i>\n                                </div>\n                                <div class=\"service-desc\">\n                                    <h5>工业安全</h5>\n                                    <p>采用生物酶解法来提取大豆寡肽</p>\n                                </div>\n                            </div>\n                        </div>\n                    </div>\n                </div>\n            </section>\n            <!--END SERVICE-->\n\n\n            <!--START WHY CHOOSE US-->\n            <section class=\"home-main-contant-style\">\n                <div class=\"container\">\n                    <div class=\"row\">\n                        <div class=\"col-md-6 why-choose-img\">\n                            <img class=\"img-responsive\" src=\"{{ url_for('static', filename='theme/default/img/imac2.png') }}\" alt=\"\">\n                        </div>\n                        <div class=\"col-md-6\">\n                            <div class=\"headline-left mb30\" id=\"culture\">\n                                <h2 class=\"headline-brd\">企业文化</h2>\n                                <p>专业的技术，丰富的成功经验，卓越的创作思维，为您创作出一流的品牌互联网形象！</p>\n\t\t\t\t\t\t\t\t<p>全球顶尖技术优势(中国是拥有这项技术的五个国家之一，国内唯有湖北濠源生物科技有限公司),团队带头人：吴谋成教授（国家授予的农业科学家、食品化学家，享有国务院的“政府特殊津贴专家”）</p>\n                            </div>\n                            <ul class=\"lists-item mb30\">\n                                <li><i class=\"fa fa-check\"></i>愿景：打造一个受人尊重、令人向往的生产型企业，人人实现梦想的平台！</li>\n                                <li><i class=\"fa fa-check\"></i> 柏思将以诚实守信的操守、共同发展的理念，长远的眼光建立公司的品牌</li>\n                                <li><i class=\"fa fa-check\"></i> 宗旨：让寡肽服务千家万户！</li>\n                                <li><i class=\"fa fa-check\"></i> 柏思将以诚实守信的操守、共同发展的理念，长远的眼光建立公司的品牌</li>\n                                <li><i class=\"fa fa-check\"></i>文化：相互帮助，合作共赢！</li>\n                                <li><i class=\"fa fa-check\"></i> 柏思将以诚实守信的操守、共同发展的理念，长远的眼光建立公司的品牌</li>\n                            </ul>\n                            <a class=\"btn btn-product\" href=\"#\">了解更多</a>\n                        </div>\n                    </div>\n                </div>\n            </section>\n            <!--END WHY CHOOSE US-->\n\n\n            <!--START COUNTER-->\n            <section>\n                <div class=\"counter-block\">\n                    <div class=\"container\">\n                        <div class=\"row\">\n                            <div class=\"col-md-3 col-sm-6 col-xs-12\">\n                                <div class=\"counter-item text-center\">\n                                    <i class=\"fa fa-users fa-3x\" aria-hidden=\"true\"></i>\n                                    <h1 class=\"secondary-color count\">267</h1>\n                                    <h4>款新产品</h4>\n                                </div>\n                            </div>\n                            <div class=\"col-md-3 col-sm-6 col-xs-12\">\n                                <div class=\"counter-item text-center\">\n                                    <i class=\"fa fa-leaf fa-3x\" aria-hidden=\"true\"></i>\n                                    <h1 class=\"secondary-color count\">800</h1>\n                                    <h4>技术团队</h4>\n                                </div>\n                            </div>\n                            <div class=\"col-md-3 col-sm-6 col-xs-12\">\n                                <div class=\"counter-item text-center\">\n                                    <i class=\"fa fa-trophy fa-3x\" aria-hidden=\"true\"></i>\n                                    <h1 class=\"secondary-color count\">2930</h1>\n                                    <h4>家全球客户</h4>\n                                </div>\n                            </div>\n                            <div class=\"col-md-3 col-sm-6 col-xs-12\">\n                                <div class=\"counter-item text-center\">\n                                    <i class=\"fa fa-coffee fa-3x\" aria-hidden=\"true\"></i>\n                                    <h1 class=\"secondary-color count\">1100</h1>\n                                    <h4>次商业合作</h4>\n                                </div>\n                            </div>\n                        </div>\n                    </div>\n                </div>\n            </section>\n            <!--END COUNTER-->\n\n\n            <!--START SERVICE-->\n            <section class=\"home-main-contant-style bg-white\">\n                <div class=\"cd-home-title\" id=\"product\">\n                    <h2>产品功能</h2>\n                    <p>寡肽是人体的能量</p>\n                </div>\n                <div class=\"container\">\n                    <div class=\"row\">\n                        <div class=\"col-md-4 col-sm-6 col-xs-12\">\n                            <div class=\"service-item mb30\">\n                                <div class=\"icon\">\n                                    <i class=\"fa fa-thumbs-o-up\" aria-hidden=\"true\"></i>\n                                </div>\n                                <div class=\"service-desc\">\n                                    <h5>细胞的食物</h5>\n                                    <p>为细胞提供营养</p>\n                                </div>\n                            </div>\n                        </div>\n                        <div class=\"col-md-4 col-sm-6 col-xs-12\">\n                            <div class=\"service-item mb30\">\n                                <div class=\"icon\">\n                                    <i class=\"fa fa-gift\" aria-hidden=\"true\"></i>\n                                </div>\n                                <div class=\"service-desc\">\n                                    <h5>细胞的保护伞</h5>\n                                    <p>抑制细胞变性</p>\n                                </div>\n                            </div>\n                        </div>\n                        <div class=\"col-md-4 col-sm-6 col-xs-12\">\n                            <div class=\"service-item mb30\">\n                                <div class=\"icon\">\n                                    <i class=\"fa fa-envelope-o\" aria-hidden=\"true\"></i>\n                                </div>\n                                <div class=\"service-desc\">\n                                    <h5>细胞的催化剂</h5>\n                                    <p>能够激活细胞活性</p>\n                                </div>\n                            </div>\n                        </div>\n                        <div class=\"col-md-4 col-sm-6 col-xs-12\">\n                            <div class=\"service-item\">\n                                <div class=\"icon\">\n                                    <i class=\"fa fa-diamond\" aria-hidden=\"true\"></i>\n                                </div>\n                                <div class=\"service-desc\">\n                                    <h5>细胞的医生</h5>\n                                    <p>能够修复受损的细胞</p>\n                                </div>\n                            </div>\n                        </div>\n                        <div class=\"col-md-4 col-sm-6 col-xs-12\">\n                            <div class=\"service-item\">\n                                <div class=\"icon\">\n                                    <i class=\"fa fa-line-chart\" aria-hidden=\"true\"></i>\n                                </div>\n                                <div class=\"service-desc\">\n                                    <h5>细胞的搬运工</h5>\n                                    <p>能够携带其他营养物质到细胞</p>\n                                </div>\n                            </div>\n                        </div>\n                        <div class=\"col-md-4 col-sm-6 col-xs-12\">\n                            <div class=\"service-item\">\n                                <div class=\"icon\">\n                                    <i class=\"fa fa-location-arrow\" aria-hidden=\"true\"></i>\n                                </div>\n                                <div class=\"service-desc\">\n                                    <h5>细胞的清洁工</h5>\n                                    <p>排出细胞中的有害物质</p>\n                                </div>\n                            </div>\n                        </div>\n                    </div>\n                </div>\n            </section>\n            <!--END SERVICE-->\n{% endblock %}"
  },
  {
    "path": "app_frontend/templates/theme/default/layout.html",
    "content": "<!DOCTYPE html>\n<!--[if !IE]><!--> <html lang=\"en\"> <!--<![endif]-->\n    <head>\n        <title>Home</title>\n        <!-- META -->\n        <meta charset=\"utf-8\">\n        <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n        <meta name=\"description\" content=\"\">\n        <meta name=\"author\" content=\"Craftdzine\">\n\n        <!-- FAVICON -->\n        <link rel=\"shortcut icon\" href=\"favicon.ico\">\n\n        <!-- BOOTSTRAP -->\n        <link rel=\"stylesheet\" href=\"{{ url_for('static', filename='theme/default/css/bootstrap.min.css') }}\">\n        <!-- FONT AWESOME -->\n        <link rel=\"stylesheet\" href=\"{{ url_for('static', filename='theme/default/css/font-awesome.min.css') }}\">\n        <!--  STYLE -->\n        <link rel=\"stylesheet\" href=\"{{ url_for('static', filename='theme/default/css/style.css') }}\">\n        <!-- HEADER 1 -->\n        <link rel=\"stylesheet\" href=\"{{ url_for('static', filename='theme/default/css/header-1.css') }}\">\n        <!-- FOOTER 1 -->\n        <link rel=\"stylesheet\" href=\"{{ url_for('static', filename='theme/default/css/footer-1.css') }}\">\n        <!-- ANIMATE -->\n        <link rel=\"stylesheet\" href=\"{{ url_for('static', filename='theme/default/css/animate.css') }}\">\n        <!-- MAGNIFIC POPUP -->\n        <link rel=\"stylesheet\" href=\"{{ url_for('static', filename='theme/default/css/magnific-popup.css') }}\">\n        <!-- FLEXSLIDER -->\n        <link rel=\"stylesheet\" href=\"{{ url_for('static', filename='theme/default/plugins/FlexSlider/jquery.flexslider.css') }}\">\n        <!--  OWL CAROUSEL -->\n        <link rel=\"stylesheet\" href=\"{{ url_for('static', filename='theme/default/plugins/owl-carousel/owl.carousel.css') }}\">\n        <!-- OWL CAROUSEL THEME -->\n        <link rel=\"stylesheet\" href=\"{{ url_for('static', filename='theme/default/plugins/owl-carousel/owl.theme.css') }}\">\n        <!-- CUBE PORTFOLIO -->\n        <link rel=\"stylesheet\" href=\"{{ url_for('static', filename='theme/default/css/cubeportfolio.min.css') }}\">\n\n        <!-- WEB FONTS -->\n        <link href='http://fonts.googleapis.com/css?family=Open+Sans:300,400,600,700' rel='stylesheet' type='text/css'>\n        <link href=\"http://fonts.googleapis.com/css?family=Raleway:500,800\" rel=\"stylesheet\" property=\"stylesheet\" type=\"text/css\" media=\"all\" />\n    </head>\n    <body>\n\n\n\n        <!-- Site Wraper -->\n        <div class=\"wrapper\">\n\n            <!-- Start Header-->\n            {% include '_top.html' %}\n            <!-- End Header -->\n\n            {% block content %}{% endblock %}\n\n        </div>\n\n\t    {% include 'theme/default/_footer.html' %}\n\n\n\n        <!-- JQUERY LIBS -->\n        <script src=\"{{ url_for('static', filename='theme/default/js/jquery.min.js') }}\"></script>\n\t\t<!--INDEX-->\n        <script src=\"{{ url_for('static', filename='theme/default/js/index.js') }}\"></script>\n        <!-- BOOTSTRAP -->\n        <script src=\"{{ url_for('static', filename='theme/default/js/bootstrap.min.js') }}\"></script>\n        <!-- OWL CAROUSEL -->\n        <script src=\"{{ url_for('static', filename='theme/default/plugins/owl-carousel/owl.carousel.min.js') }}\"></script>\n        <!-- COUNTER UP -->\n        <script src=\"{{ url_for('static', filename='theme/default/js/jquery.counterup.min.js') }}\"></script>\n        <!-- WAYPOINTS -->\n        <script src=\"{{ url_for('static', filename='theme/default/js/waypoints.min.js') }}\"></script>\n        <!-- FLEXSLIDER -->\n        <script src=\"{{ url_for('static', filename='theme/default/plugins/FlexSlider/jquery.flexslider-min.js') }}\"></script>\n        <!-- MAGNIFIC POPUP-->\n        <script src=\"{{ url_for('static', filename='theme/default/js/jquery.magnific-popup.min.js') }}\"></script>\n        <!-- MAGNIFIC POPUP  -->\n        <script src=\"{{ url_for('static', filename='theme/default/js/magnific-popup.min.js') }}\"></script>\n        <!-- CUBE PORTFOLIO -->\n        <script src=\"{{ url_for('static', filename='theme/default/js/jquery.cubeportfolio.min.js') }}\"></script>\n        <!-- CUBE PORTFOLIO -->\n        <script src=\"{{ url_for('static', filename='theme/default/js/cubeportfolio/portfolio-masonry-4col.js') }}\"></script>\n        <!-- CUBE TESTIMONIALS -->\n        <script src=\"{{ url_for('static', filename='theme/default/js/cubeportfolio/testimonials.js') }}\"></script>\n        <!-- CUBE TEAM -->\n        <script src=\"{{ url_for('static', filename='theme/default/js/cubeportfolio/team.js') }}\"></script>\n        <!-- CUBE BLOG -->\n        <script src=\"{{ url_for('static', filename='theme/default/js/cubeportfolio/blog-grid-3col.js') }}\"></script>\n        <!-- CUSTOM-->\n        <script src=\"{{ url_for('static', filename='theme/default/js/custom.js') }}\"></script>\n\n\n        <!--[if lt IE 9]>\n        <script src=\"respond.js\"></script>\n        <script src=\"html5shiv.js\"></script>\n        <![endif]-->\n\n    </body>\n</html>\n\n"
  },
  {
    "path": "app_frontend/templates/uploads.html",
    "content": "{% extends \"layout.html\" %}\n\n{% block extra_css %}\n    <!-- blueimp Gallery styles -->\n    <link rel=\"stylesheet\" href=\"{{ url_for('static', filename='plugin/Gallery-2.25.0/css/blueimp-gallery.min.css') }}\">\n    <!-- CSS to style the file input field as button and adjust the Bootstrap progress bars -->\n    <link rel=\"stylesheet\" href=\"{{ url_for('static', filename='plugin/jQuery-File-Upload-9.17.0/css/jquery.fileupload.css') }}\">\n    <link rel=\"stylesheet\" href=\"{{ url_for('static', filename='plugin/jQuery-File-Upload-9.17.0/css/jquery.fileupload-ui.css') }}\">\n{% endblock %}\n\n{% block content %}\n<div class=\"container\">\n    <h1>jQuery File Upload Demo</h1>\n    <h2 class=\"lead\">Basic Plus UI version</h2>\n    <ul class=\"nav nav-tabs\">\n        <li><a href=\"#basic.html\">Basic</a></li>\n        <li><a href=\"#basic-plus.html\">Basic Plus</a></li>\n        <li class=\"active\"><a href=\"#index.html\">Basic Plus UI</a></li>\n        <li><a href=\"#angularjs.html\">AngularJS</a></li>\n        <li><a href=\"#jquery-ui.html\">jQuery UI</a></li>\n    </ul>\n    <br>\n    <blockquote>\n        <p>File Upload widget with multiple file selection, drag&amp;drop support, progress bars, validation and preview images, audio and video for jQuery.<br>\n        Supports cross-domain, chunked and resumable file uploads and client-side image resizing.<br>\n        Works with any server-side platform (PHP, Python, Ruby on Rails, Java, Node.js, Go etc.) that supports standard HTML form file uploads.</p>\n    </blockquote>\n    <br>\n    <!-- The file upload form used as target for the file upload widget -->\n    <form id=\"fileupload\" action=\"{{ url_for('uploads') }}\" method=\"POST\" enctype=\"multipart/form-data\">\n        <!-- The fileupload-buttonbar contains buttons to add/delete files and start/cancel the upload -->\n        <div class=\"row fileupload-buttonbar\">\n            <div class=\"col-lg-7\">\n                <!-- The fileinput-button span is used to style the file input field as button -->\n                <span class=\"btn btn-success fileinput-button\">\n                    <i class=\"glyphicon glyphicon-plus\"></i>\n                    <span>Add files...</span>\n                    <input type=\"file\" name=\"files[]\" multiple>\n                </span>\n                <button type=\"submit\" class=\"btn btn-primary start\">\n                    <i class=\"glyphicon glyphicon-upload\"></i>\n                    <span>Start upload</span>\n                </button>\n                <button type=\"reset\" class=\"btn btn-warning cancel\">\n                    <i class=\"glyphicon glyphicon-ban-circle\"></i>\n                    <span>Cancel upload</span>\n                </button>\n                <button type=\"button\" class=\"btn btn-danger delete\">\n                    <i class=\"glyphicon glyphicon-trash\"></i>\n                    <span>Delete</span>\n                </button>\n                <input type=\"checkbox\" class=\"toggle\">\n                <!-- The global file processing state -->\n                <span class=\"fileupload-process\"></span>\n            </div>\n            <!-- The global progress state -->\n{#            <div class=\"col-lg-5 fileupload-progress fade in\">#}\n            <div class=\"col-lg-5 fileupload-progress fade\">\n                <!-- The global progress bar -->\n                <div class=\"progress progress-striped active\" role=\"progressbar\" aria-valuemin=\"0\" aria-valuemax=\"100\">\n                    <div class=\"progress-bar progress-bar-success\" style=\"width:0%;\"></div>\n                </div>\n                <!-- The extended global progress state -->\n                <div class=\"progress-extended\">&nbsp;</div>\n            </div>\n        </div>\n        <!-- The table listing the files available for upload/download -->\n        <table role=\"presentation\" class=\"table table-striped\"><tbody class=\"files\"></tbody></table>\n    </form>\n    <br>\n    <div class=\"panel panel-default\">\n        <div class=\"panel-heading\">\n            <h3 class=\"panel-title\">Demo Notes</h3>\n        </div>\n        <div class=\"panel-body\">\n            <ul>\n                <li>The maximum file size for uploads in this demo is <strong>999 KB</strong> (default file size is unlimited).</li>\n                <li>Only image files (<strong>JPG, GIF, PNG</strong>) are allowed in this demo (by default there is no file type restriction).</li>\n                <li>Uploaded files will be deleted automatically after <strong>5 minutes or less</strong> (demo files are stored in memory).</li>\n                <li>You can <strong>drag &amp; drop</strong> files from your desktop on this webpage (see <a href=\"https://github.com/blueimp/jQuery-File-Upload/wiki/Browser-support\">Browser support</a>).</li>\n                <li>Please refer to the <a href=\"https://github.com/blueimp/jQuery-File-Upload\">project website</a> and <a href=\"https://github.com/blueimp/jQuery-File-Upload/wiki\">documentation</a> for more information.</li>\n                <li>Built with the <a href=\"http://getbootstrap.com/\">Bootstrap</a> CSS framework and Icons from <a href=\"http://glyphicons.com/\">Glyphicons</a>.</li>\n            </ul>\n        </div>\n    </div>\n</div>\n\n{% raw %}\n<!-- The template to display files available for upload -->\n<script id=\"template-upload\" type=\"text/x-tmpl\">\n{% for (var i=0, file; file=o.files[i]; i++) { %}\n    <tr class=\"template-upload fade\">\n        <td>\n            <span class=\"preview\"></span>\n        </td>\n        <td>\n            <p class=\"name\">{%=file.name%}</p>\n            <strong class=\"error text-danger\"></strong>\n        </td>\n        <td>\n            <p class=\"size\">Processing...</p>\n            <div class=\"progress progress-striped active\" role=\"progressbar\" aria-valuemin=\"0\" aria-valuemax=\"100\" aria-valuenow=\"0\"><div class=\"progress-bar progress-bar-success\" style=\"width:0%;\"></div></div>\n        </td>\n        <td>\n            {% if (!i && !o.options.autoUpload) { %}\n                <button class=\"btn btn-primary start\" disabled>\n                    <i class=\"glyphicon glyphicon-upload\"></i>\n                    <span>Start</span>\n                </button>\n            {% } %}\n            {% if (!i) { %}\n                <button class=\"btn btn-warning cancel\">\n                    <i class=\"glyphicon glyphicon-ban-circle\"></i>\n                    <span>Cancel</span>\n                </button>\n            {% } %}\n        </td>\n    </tr>\n{% } %}\n</script>\n<!-- The template to display files available for download -->\n<script id=\"template-download\" type=\"text/x-tmpl\">\n{% for (var i=0, file; file=o.files[i]; i++) { %}\n    <tr class=\"template-download fade\">\n        <td>\n            <span class=\"preview\">\n                {% if (file.thumbnailUrl) { %}\n                    <a href=\"{%=file.url%}\" title=\"{%=file.name%}\" download=\"{%=file.name%}\" data-gallery><img src=\"{%=file.thumbnailUrl%}\"></a>\n                {% } %}\n            </span>\n        </td>\n        <td>\n            <p class=\"name\">\n                {% if (file.url) { %}\n                    <a href=\"{%=file.url%}\" title=\"{%=file.name%}\" download=\"{%=file.name%}\" {%=file.thumbnailUrl?'data-gallery':''%}>{%=file.name%}</a>\n                {% } else { %}\n                    <span>{%=file.name%}</span>\n                {% } %}\n            </p>\n            {% if (file.error) { %}\n                <div><span class=\"label label-danger\">Error</span> {%=file.error%}</div>\n            {% } %}\n        </td>\n        <td>\n            <span class=\"size\">{%=o.formatFileSize(file.size)%}</span>\n        </td>\n        <td>\n            {% if (file.deleteUrl) { %}\n                <button class=\"btn btn-danger delete\" data-type=\"{%=file.deleteType%}\" data-url=\"{%=file.deleteUrl%}\"{% if (file.deleteWithCredentials) { %} data-xhr-fields='{\"withCredentials\":true}'{% } %}>\n                    <i class=\"glyphicon glyphicon-trash\"></i>\n                    <span>Delete</span>\n                </button>\n                <input type=\"checkbox\" name=\"delete\" value=\"1\" class=\"toggle\">\n            {% } else { %}\n                <button class=\"btn btn-warning cancel\">\n                    <i class=\"glyphicon glyphicon-ban-circle\"></i>\n                    <span>Cancel</span>\n                </button>\n            {% } %}\n        </td>\n    </tr>\n{% } %}\n</script>\n{% endraw %}\n\n{% endblock %}\n\n\n\n{% block extra_js %}\n    <!-- The jQuery UI widget factory, can be omitted if jQuery UI is already included -->\n    <script src=\"{{ url_for('static', filename='plugin/jQuery-File-Upload-9.17.0/js/vendor/jquery.ui.widget.js') }}\"></script>\n    <!-- The Templates plugin is included to render the upload/download listings -->\n    <script src=\"{{ url_for('static', filename='plugin/JavaScript-Templates-3.8.0/js/tmpl.min.js') }}\"></script>\n    <!-- The Load Image plugin is included for the preview images and image resizing functionality -->\n    <script src=\"{{ url_for('static', filename='plugin/JavaScript-Load-Image-2.12.2/js/load-image.all.min.js') }}\"></script>\n    <!-- The Canvas to Blob plugin is included for image resizing functionality -->\n    <script src=\"{{ url_for('static', filename='plugin/JavaScript-Canvas-to-Blob-3.7.0/js/canvas-to-blob.min.js') }}\"></script>\n    <!-- blueimp Gallery script -->\n    <script src=\"{{ url_for('static', filename='plugin/Gallery-2.25.0/js/jquery.blueimp-gallery.min.js') }}\"></script>\n    <!-- The Iframe Transport is required for browsers without support for XHR file uploads -->\n    <script src=\"{{ url_for('static', filename='plugin/jQuery-File-Upload-9.17.0/js/jquery.iframe-transport.js') }}\"></script>\n    <!-- The basic File Upload plugin -->\n    <script src=\"{{ url_for('static', filename='plugin/jQuery-File-Upload-9.17.0/js/jquery.fileupload.js') }}\"></script>\n    <!-- The File Upload processing plugin -->\n    <script src=\"{{ url_for('static', filename='plugin/jQuery-File-Upload-9.17.0/js/jquery.fileupload-process.js') }}\"></script>\n    <!-- The File Upload image preview & resize plugin -->\n    <script src=\"{{ url_for('static', filename='plugin/jQuery-File-Upload-9.17.0/js/jquery.fileupload-image.js') }}\"></script>\n    <!-- The File Upload audio preview plugin -->\n    <script src=\"{{ url_for('static', filename='plugin/jQuery-File-Upload-9.17.0/js/jquery.fileupload-audio.js') }}\"></script>\n    <!-- The File Upload video preview plugin -->\n    <script src=\"{{ url_for('static', filename='plugin/jQuery-File-Upload-9.17.0/js/jquery.fileupload-video.js') }}\"></script>\n    <!-- The File Upload validation plugin -->\n    <script src=\"{{ url_for('static', filename='plugin/jQuery-File-Upload-9.17.0/js/jquery.fileupload-validate.js') }}\"></script>\n    <!-- The File Upload user interface plugin -->\n    <script src=\"{{ url_for('static', filename='plugin/jQuery-File-Upload-9.17.0/js/jquery.fileupload-ui.js') }}\"></script>\n\n    <!-- The XDomainRequest Transport is included for cross-domain file deletion for IE 8 and IE 9 -->\n    <!--[if (gte IE 8)&(lt IE 10)]>\n    <script src=\"{{ url_for('static', filename='plugin/jQuery-File-Upload-9.17.0/js/cors/jquery.xdr-transport.js') }}\"></script>\n    <![endif]-->\n    <script>\n    $(function () {\n        //初始化，主要是设置上传参数，以及事件处理方法(回调函数)\n        $('#fileupload').fileupload({});\n\n        // Load existing files:\n        $('#fileupload').addClass('fileupload-processing');\n        $.ajax({\n            // Uncomment the following to send cross-domain cookies:\n            //xhrFields: {withCredentials: true},\n            url: $('#fileupload').fileupload('option', 'url'),\n            dataType: 'json',\n            context: $('#fileupload')[0]\n        }).always(function () {\n            $(this).removeClass('fileupload-processing');\n        }).done(function (result) {\n            $(this).fileupload('option', 'done')\n                .call(this, $.Event('done'), {result: result});\n        });\n    });\n    </script>\n{% endblock %}\n\n"
  },
  {
    "path": "app_frontend/templates/user/_account_info.html",
    "content": "\n<section id=\"section_account_info\">\n    <div class=\"panel panel-default\">\n    <div class=\"panel-heading\">\n        <strong class=\"panel-title\">账户信息\n        <span class=\"glyphicon glyphicon-bookmark pull-right\"></span>\n        </strong>\n    </div>\n    <table class=\"table\">\n        <thead>\n            <tr>\n                <th>账户名称</th>\n                <th>当前余额</th>\n            </tr>\n        </thead>\n        <tbody>\n            <tr>\n                <td><a href=\"{{ url_for('wallet.lists') }}\">钱包余额</a></td>\n                <td>{{ current_user.id | user_wallet }}</td>\n            </tr>\n            <tr>\n                <td><a href=\"{{ url_for('bit_coin.lists') }}\">数字货币</a></td>\n                <td>{{ current_user.id | user_bit_coin }}</td>\n            </tr>\n            <tr>\n                <td><a href=\"#\">积分余额</a></td>\n                <td>{{ current_user.id | user_score }}</td>\n            </tr>\n            <tr>\n                <td><a href=\"#\">奖金余额</a></td>\n                <td>{{ current_user.id | user_bonus }}</td>\n            </tr>\n            <tr>\n                <td><a href=\"{{ url_for('active.lists') }}\">激活码量</a></td>\n                <td>{{ current_user.id | user_active }}</td>\n            </tr>\n        </tbody>\n    </table>\n    </div>\n</section>"
  },
  {
    "path": "app_frontend/templates/user/_invite_link.html",
    "content": "\n<section id=\"section_invite_link\">\n    <div class=\"panel panel-default\">\n        <div class=\"panel-heading\">\n            <strong class=\"panel-title\">推广链接\n                <span class=\"glyphicon glyphicon-list-alt pull-right\"></span>\n            </strong>\n        </div>\n        <div class=\"panel-body\">\n\n            <label for=\"invite_link\">复制链接</label>\n            <div class=\"input-group\">\n                <!-- Target -->\n                <input class=\"form-control input-copy\" rel=\"tooltip\" title=\"推广链接地址\" id=\"invite_link\" value=\"{{ url_for('index', _external=True, i=current_user.id | user_invite_link) }}\">\n                <!-- Trigger -->\n                <span class=\"input-group-btn\">\n                    <button class=\"btn btn-default\" type=\"button\" rel=\"tooltip\" title=\"点击复制\" data-clipboard-action=\"copy\" data-clipboard-target=\"#invite_link\">\n                        <span class=\"glyphicon glyphicon-duplicate\"></span>\n                    </button>\n                </span>\n            </div>\n        </div>\n    </div>\n</section>"
  },
  {
    "path": "app_frontend/templates/user/_status.html",
    "content": "\n<section id=\"section_active\">\n    <div class=\"panel panel-default\">\n        <div class=\"panel-heading\">\n            <strong class=\"panel-title\">状态信息\n                <span class=\"glyphicon glyphicon-camera pull-right\"></span>\n            </strong>\n        </div>\n        <div class=\"panel-body row center-block\">\n            <div class=\"col-lg-4 col-md-4 col-sm-4 col-xs-4\">\n                {% if current_user.status_active == 0 %}\n                <button class=\"btn btn-default\" onclick=\"self_active()\" rel=\"tooltip\" title=\"立即激活\">还未激活</button>\n                {% else %}\n                <button class=\"btn btn-success\" onclick=\"\" rel=\"tooltip\" title=\"已经激活\">已经激活</button>\n                {% endif %}\n            </div>\n            <div class=\"col-lg-4 col-md-4 col-sm-4 col-xs-4\">\n                {% if current_user.status_real_name == 0 %}\n                <button class=\"btn btn-default\" onclick=\"\" rel=\"tooltip\" title=\"实名验证\">还未实名</button>\n                {% else %}\n                <button class=\"btn btn-success\" onclick=\"\" rel=\"tooltip\" title=\"已经实名\">已经实名</button>\n                {% endif %}\n            </div>\n            <div class=\"col-lg-4 col-md-4 col-sm-4 col-xs-4\">\n                {% if current_user.status_lock == 0 %}\n                <button class=\"btn btn-success\" onclick=\"\" rel=\"tooltip\" title=\"正常状态\">正常状态</button>\n                {% else %}\n                <button class=\"btn btn-warning\" onclick=\"\" rel=\"tooltip\" title=\"已被锁定\">已被锁定</button>\n                {% endif %}\n            </div>\n        </div>\n    </div>\n</section>"
  },
  {
    "path": "app_frontend/templates/user/_team_tree.html",
    "content": "<section id=\"section_account_info\">\n    <div class=\"panel panel-default\">\n    <div class=\"panel-heading\">\n        <strong class=\"panel-title\">我的团队\n        <span class=\"glyphicon glyphicon-king pull-right\"></span>\n        </strong>\n    </div>\n    <div class=\"panel-body\">\n        {% from \"macros.html\" import render_team_tree %}\n        {{ render_team_tree(team_tree) }}\n    </div>\n    </div>\n</section>"
  },
  {
    "path": "app_frontend/templates/user/account.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n    <meta charset=\"UTF-8\">\n    <title>Title</title>\n</head>\n<body>\n\n</body>\n</html>"
  },
  {
    "path": "app_frontend/templates/user/auth.html",
    "content": "{% extends \"layout.html\" %}\n\n{% block content %}\n    <div class=\"container\">\n    <ol class=\"breadcrumb\">\n        <li><a href=\"/\">首页</a></li>\n        <li class=\"active\">用户中心</li>\n        <li class=\"active\">登录信息</li>\n    </ol>\n\n    <div class=\"row\">\n        <div class=\"table-responsive col-lg-8 col-md-12\">\n            {# 表单 #}\n            <form class=\"form-horizontal\" method=\"post\" action=\"\">\n                {{ form.csrf_token }}\n                {# 标签导航 #}\n                <ul class=\"nav nav-tabs\">  {# 填充整个导航条：nav-justified #}\n                    <li role=\"presentation\" class=\"active\"><a class=\"selected\" href=\"{{ url_for('user.auth') }}\">登录信息</a></li>\n                    <li role=\"presentation\"><a href=\"{{ url_for('user.bank') }}\">银行信息</a></li>\n                    <li role=\"presentation\"><a href=\"{{ url_for('user.profile') }}\">基本信息</a></li>\n                </ul>\n                <div class=\"form-group\">\n                    {{ form.id() }}\n                </div>\n                <div class=\"form-group{% if form.auth_key.errors %} has-error{% endif %}\">\n                    {{ form.auth_key.label(class=\"col-sm-2 control-label\") }}\n                    <div class=\"col-sm-10\">\n                        {{ form.auth_key(class=\"form-control\", placeholder=\"登录账号[2-20位]\", disabled=\"disabled\") }}\n                        {% for error in form.auth_key.errors %}\n                            <span class=\"help-block\">{{ error }}</span>\n                        {% endfor %}\n                    </div>\n                </div>\n                <div class=\"form-group{% if form.auth_secret.errors %} has-error{% endif %}\">\n                    {{ form.auth_secret.label(class=\"col-sm-2 control-label\") }}\n                    <div class=\"col-sm-10\">\n                        {{ form.auth_secret(class=\"form-control\", placeholder=\"登录密码[6-20位]，若无需更改，请留空\", maxlength=\"20\") }}\n                        {% for error in form.auth_secret.errors %}\n                            <span class=\"help-block\">{{ error }}</span>\n                        {% endfor %}\n                    </div>\n                </div>\n                <div class=\"form-group{% if form.status_verified.errors %} has-error{% endif %}\">\n                    {{ form.status_verified.label(class=\"col-sm-2 control-label\") }}\n                    <div class=\"col-sm-10\">\n                        {{ form.status_verified(disabled=\"disabled\") }}\n                        {% for error in form.status_verified.errors %}\n                            <span class=\"help-block\">{{ error }}</span>\n                        {% endfor %}\n                    </div>\n                </div>\n                <div class=\"form-group{% if form.create_time.errors %} has-error{% endif %}\">\n                    {{ form.create_time.label(class=\"col-sm-2 control-label\") }}\n                    <div class=\"col-sm-10\">\n                        <div class=\"form-control\">\n                            {{ moment(form.create_time.data).format('YYYY-MM-DD HH:mm:ss') }}\n                        </div>\n                        {% for error in form.create_time.errors %}\n                            <span class=\"help-block\">{{ error }}</span>\n                        {% endfor %}\n                    </div>\n                </div>\n                <div class=\"form-group{% if form.update_time.errors %} has-error{% endif %}\">\n                    {{ form.update_time.label(class=\"col-sm-2 control-label\") }}\n                    <div class=\"col-sm-10\">\n                        <div class=\"form-control\">\n                            {{ moment(form.update_time.data).format('YYYY-MM-DD HH:mm:ss') }}\n                        </div>\n                        {% for error in form.update_time.errors %}\n                            <span class=\"help-block\">{{ error }}</span>\n                        {% endfor %}\n                    </div>\n                </div>\n                <div class=\"form-group\">\n                    <div class=\"col-sm-offset-2 col-sm-10\">\n                        <button type=\"submit\" class=\"btn btn-success btn-load\" data-loading-text=\"保存中\">保存</button>\n                        <button type=\"reset\" class=\"btn btn-default\">重新填写</button>\n                    </div>\n                </div>\n            </form>\n        </div>\n        <!-- 用户概要 -->\n        <div class=\"col-lg-4 col-md-12\">\n            <!-- 状态信息 -->\n            {% include('user/_status.html') %}\n            <!-- 推广链接 -->\n            {% include('user/_invite_link.html') %}\n            <!-- 账户信息 -->\n            {% include('user/_account_info.html') %}\n            <!-- 我的团队 -->\n            {% include('user/_team_tree.html') %}\n        </div>\n    </div>\n\n\n    </div>\n\n{% endblock %}\n\n{% block extra_js %}\n<script src=\"{{ url_for('static', filename='plugin/clipboard.js-1.6.1/dist/clipboard.min.js') }}\"></script>\n<script>\n    /**\n     * 用户自己激活\n     * @returns {boolean}\n     */\n    function self_active() {\n        //console.log($(form).serialize());\n        $.ajax({\n            url: \"{{ url_for('user.ajax_self_active') }}\",\n            type: 'GET',\n            dataType: 'json',\n            success: function (result) {\n                // console.log(result);\n                if(result.hasOwnProperty('error')){\n                    alert(result.error);\n                }else {\n                    alert(result.success);\n                    document.location.reload();\n                }\n            }\n        });\n        return false;\n    }\n</script>\n<script>\n    //推广链接复制\n    var clipboard = new Clipboard('.btn');\n\n    clipboard.on('success', function(e) {\n        // console.info('Action:', e.action);\n        // console.info('Text:', e.text);\n        // console.info('Trigger:', e.trigger);\n        e.clearSelection();\n        alert('复制成功，粘贴使用推广链接');\n    });\n\n    clipboard.on('error', function(e) {\n        // console.error('Action:', e.action);\n        // console.error('Trigger:', e.trigger);\n        alert('操作失败，重新复制推广链接');\n    });\n</script>\n{% endblock %}\n"
  },
  {
    "path": "app_frontend/templates/user/bank.html",
    "content": "{% extends \"layout.html\" %}\n\n{% block content %}\n    <div class=\"container\">\n    <ol class=\"breadcrumb\">\n        <li><a href=\"/\">首页</a></li>\n        <li class=\"active\">用户中心</li>\n        <li class=\"active\">银行账号</li>\n    </ol>\n\n    <div class=\"row\">\n        <div class=\"table-responsive col-lg-8 col-md-12\">\n            {# 表单 #}\n            <form class=\"form-horizontal\" method=\"post\" action=\"\">\n                {{ form.csrf_token }}\n                {# 标签导航 #}\n                <ul class=\"nav nav-tabs\">  {# 填充整个导航条：nav-justified #}\n                    <li role=\"presentation\"><a href=\"{{ url_for('user.auth') }}\">登录信息</a></li>\n                    <li role=\"presentation\" class=\"active\"><a class=\"selected\" href=\"{{ url_for('user.bank') }}\">银行信息</a></li>\n                    <li role=\"presentation\"><a href=\"{{ url_for('user.profile') }}\">基本信息</a></li>\n                </ul>\n                <div class=\"form-group\"></div>\n                <div class=\"form-group{% if form.account_name.errors %} has-error{% endif %}\">\n                    {{ form.account_name.label(class=\"col-sm-2 control-label\") }}\n                    <div class=\"col-sm-10\">\n                        {{ form.account_name(class=\"form-control\", placeholder=\"账户姓名\") }}\n                        {% for error in form.account_name.errors %}\n                            <span class=\"help-block\">{{ error }}</span>\n                        {% endfor %}\n                    </div>\n                </div>\n                <div class=\"form-group{% if form.bank_name.errors %} has-error{% endif %}\">\n                    {{ form.bank_name.label(class=\"col-sm-2 control-label\") }}\n                    <div class=\"col-sm-10\">\n                        {{ form.bank_name(class=\"form-control\", placeholder=\"银行名称\") }}\n                        {% for error in form.bank_name.errors %}\n                            <span class=\"help-block\">{{ error }}</span>\n                        {% endfor %}\n                    </div>\n                </div>\n                <div class=\"form-group{% if form.bank_address.errors %} has-error{% endif %}\">\n                    {{ form.bank_address.label(class=\"col-sm-2 control-label\") }}\n                    <div class=\"col-sm-10\">\n                        {{ form.bank_address(class=\"form-control\", placeholder=\"支行名称\") }}\n                        {% for error in form.bank_address.errors %}\n                            <span class=\"help-block\">{{ error }}</span>\n                        {% endfor %}\n                    </div>\n                </div>\n                <div class=\"form-group{% if form.bank_account.errors %} has-error{% endif %}\">\n                    {{ form.bank_account.label(class=\"col-sm-2 control-label\") }}\n                    <div class=\"col-sm-10\">\n                        {{ form.bank_account(class=\"form-control\", placeholder=\"银行卡号\") }}\n                        {% for error in form.bank_account.errors %}\n                            <span class=\"help-block\">{{ error }}</span>\n                        {% endfor %}\n                    </div>\n                </div>\n                <div class=\"form-group{% if form.status_verified.errors %} has-error{% endif %}\">\n                    {{ form.status_verified.label(class=\"col-sm-2 control-label\") }}\n                    <div class=\"col-sm-10\">\n                        {{ form.status_verified(disabled=\"disabled\") }}\n                        {% for error in form.status_verified.errors %}\n                            <span class=\"help-block\">{{ error }}</span>\n                        {% endfor %}\n                    </div>\n                </div>\n                <div class=\"form-group{% if form.create_time.errors %} has-error{% endif %}\">\n                    {{ form.create_time.label(class=\"col-sm-2 control-label\") }}\n                    <div class=\"col-sm-10\">\n                        <div class=\"form-control\">\n                            {{ moment(form.create_time.data).format('YYYY-MM-DD HH:mm:ss') }}\n                        </div>\n                        {% for error in form.create_time.errors %}\n                            <span class=\"help-block\">{{ error }}</span>\n                        {% endfor %}\n                    </div>\n                </div>\n                <div class=\"form-group{% if form.update_time.errors %} has-error{% endif %}\">\n                    {{ form.update_time.label(class=\"col-sm-2 control-label\") }}\n                    <div class=\"col-sm-10\">\n                        <div class=\"form-control\">\n                            {{ moment(form.update_time.data).format('YYYY-MM-DD HH:mm:ss') }}\n                        </div>\n                        {% for error in form.update_time.errors %}\n                            <span class=\"help-block\">{{ error }}</span>\n                        {% endfor %}\n                    </div>\n                </div>\n                <div class=\"form-group\">\n                    <div class=\"col-sm-offset-2 col-sm-10\">\n                        <button type=\"submit\" class=\"btn btn-success btn-load\" data-loading-text=\"保存中\">保存</button>\n                        <button type=\"reset\" class=\"btn btn-default\">重新填写</button>\n                    </div>\n                </div>\n            </form>\n        </div>\n        <!-- 用户概要 -->\n        <div class=\"col-lg-4 col-md-12\">\n            <!-- 状态信息 -->\n            {% include('user/_status.html') %}\n            <!-- 推广链接 -->\n            {% include('user/_invite_link.html') %}\n            <!-- 账户信息 -->\n            {% include('user/_account_info.html') %}\n            <!-- 我的团队 -->\n            {% include('user/_team_tree.html') %}\n        </div>\n    </div>\n\n\n    </div>\n\n{% endblock %}\n\n{% block extra_js %}\n<script src=\"{{ url_for('static', filename='plugin/clipboard.js-1.6.1/dist/clipboard.min.js') }}\"></script>\n<script>\n    /**\n     * 用户自己激活\n     * @returns {boolean}\n     */\n    function self_active() {\n        // console.log($(form).serialize());\n        $.ajax({\n            url: \"{{ url_for('user.ajax_self_active') }}\",\n            type: 'GET',\n            dataType: 'json',\n            success: function (result) {\n                // console.log(result);\n                if(result.hasOwnProperty('error')){\n                    alert(result.error);\n                }else {\n                    alert(result.success);\n                    document.location.reload();\n                }\n            }\n        });\n        return false;\n    }\n</script>\n<script>\n    //推广链接复制\n    var clipboard = new Clipboard('.btn');\n\n    clipboard.on('success', function(e) {\n        // console.info('Action:', e.action);\n        // console.info('Text:', e.text);\n        // console.info('Trigger:', e.trigger);\n        e.clearSelection();\n        alert('复制成功，粘贴使用推广链接');\n    });\n\n    clipboard.on('error', function(e) {\n        // console.error('Action:', e.action);\n        // console.error('Trigger:', e.trigger);\n        alert('操作失败，重新复制推广链接');\n    });\n</script>\n{% endblock %}\n"
  },
  {
    "path": "app_frontend/templates/user/notification.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n    <meta charset=\"UTF-8\">\n    <title>Title</title>\n</head>\n<body>\n\n</body>\n</html>"
  },
  {
    "path": "app_frontend/templates/user/profile.html",
    "content": "{% extends \"layout.html\" %}\n\n{% block content %}\n    <div class=\"container\">\n    <ol class=\"breadcrumb\">\n        <li><a href=\"/\">首页</a></li>\n        <li class=\"active\">用户中心</li>\n        <li class=\"active\">基本信息</li>\n    </ol>\n\n    <div class=\"row\">\n        <div class=\"table-responsive col-lg-8 col-md-12\">\n            {# 表单 #}\n            <form class=\"form-horizontal\" method=\"post\" action=\"\">\n                {{ form.csrf_token }}\n                {# 标签导航 #}\n                <ul class=\"nav nav-tabs\">  {# 填充整个导航条：nav-justified #}\n                    <li role=\"presentation\"><a href=\"{{ url_for('user.auth') }}\">登录信息</a></li>\n                    <li role=\"presentation\"><a href=\"{{ url_for('user.bank') }}\">银行信息</a></li>\n                    <li role=\"presentation\" class=\"active\"><a class=\"selected\" href=\"{{ url_for('user.profile') }}\">基本信息</a></li>\n                </ul>\n                <div class=\"form-group\"></div>\n                <div class=\"form-group{% if form.user_pid.errors %} has-error{% endif %}\">\n                    {{ form.user_pid.label(class=\"col-sm-2 control-label\") }}\n                    <div class=\"col-sm-10\">\n{#                        {{ form.user_pid(class=\"form-control\", placeholder=\"推荐会员\") }}#}\n                        <div class=\"form-control\">{{ form.user_pid.data | nickname }}</div>\n\n                        {% for error in form.user_pid.errors %}\n                            <span class=\"help-block\">{{ error }}</span>\n                        {% endfor %}\n                    </div>\n                </div>\n                <div class=\"form-group{% if form.nickname.errors %} has-error{% endif %}\">\n                    {{ form.nickname.label(class=\"col-sm-2 control-label\") }}\n                    <div class=\"col-sm-10\">\n                        {{ form.nickname(class=\"form-control\", placeholder=\"用户名称\", disabled=\"disabled\") }}\n                        {% for error in form.nickname.errors %}\n                            <span class=\"help-block\">{{ error }}</span>\n                        {% endfor %}\n                    </div>\n                </div>\n                <div class=\"form-group{% if form.email.errors %} has-error{% endif %}\">\n                    {{ form.email.label(class=\"col-sm-2 control-label\") }}\n                    <div class=\"col-sm-10\">\n                        {{ form.email(class=\"form-control\", placeholder=\"电子邮箱\") }}\n                        {% for error in form.email.errors %}\n                            <span class=\"help-block\">{{ error }}</span>\n                        {% endfor %}\n                    </div>\n                </div>\n                <div class=\"form-group{% if form.area_id.errors %} has-error{% endif %}\">\n                    {{ form.area_id.label(class=\"col-sm-2 control-label\") }}\n                    <div class=\"col-sm-10\">\n                        {{ form.area_id(data_header=\"选择手机区号\") }}\n                        {% for error in form.area_id.errors %}\n                            <span class=\"help-block\">{{ error }}</span>\n                        {% endfor %}\n                    </div>\n                </div>\n                <div class=\"form-group{% if form.phone.errors %} has-error{% endif %}\">\n                    {{ form.phone.label(class=\"col-sm-2 control-label\") }}\n                    <div class=\"col-sm-10\">\n                        {{ form.phone(class=\"form-control\", placeholder=\"手机号码\", type=\"tel\", maxlength=11) }}\n                        {% for error in form.phone.errors %}\n                            <span class=\"help-block\">{{ error }}</span>\n                        {% endfor %}\n                    </div>\n                </div>\n                <div class=\"form-group{% if form.sms.errors %} has-error{% endif %}\">\n                    {{ form.sms.label(class=\"col-sm-2 control-label\") }}\n                    <div class=\"col-sm-10\">\n                        <div class=\"input-group\">\n                            {{ form.sms(class=\"form-control\", placeholder=\"短信验证码\", maxlength=6) }}\n                            <span class=\"input-group-btn\">\n                                <button id=\"get_sms_btn\" class=\"btn btn-default\" type=\"button\">\n                                    <span class=\"glyphicon glyphicon-envelope\"></span> <i>发送短信</i>\n                                </button>\n                            </span>\n                        </div>\n                        {% for error in form.sms.errors %}\n                            <span class=\"help-block\">{{ error }}</span>\n                        {% endfor %}\n                    </div>\n                </div>\n                <div class=\"form-group{% if form.birthday.errors %} has-error{% endif %}\">\n                    {{ form.birthday.label(class=\"col-sm-2 control-label\") }}\n                    <div class=\"col-sm-10\">\n                        {{ form.birthday(class=\"form-control\", placeholder=\"Birthday\", type=\"date\") }}\n                        {% for error in form.birthday.errors %}\n                            <span class=\"help-block\">{{ error }}</span>\n                        {% endfor %}\n                    </div>\n                </div>\n                <div class=\"form-group{% if form.real_name.errors %} has-error{% endif %}\">\n                    {{ form.real_name.label(class=\"col-sm-2 control-label\") }}\n                    <div class=\"col-sm-10\">\n                        {{ form.real_name(class=\"form-control\", placeholder=\"真实姓名\") }}\n                        {% for error in form.real_name.errors %}\n                            <span class=\"help-block\">{{ error }}</span>\n                        {% endfor %}\n                    </div>\n                </div>\n                <div class=\"form-group{% if form.id_card.errors %} has-error{% endif %}\">\n                    {{ form.id_card.label(class=\"col-sm-2 control-label\") }}\n                    <div class=\"col-sm-10\">\n                        {{ form.id_card(class=\"form-control\", placeholder=\"身份证号\", maxlength=18) }}\n                        {% for error in form.id_card.errors %}\n                            <span class=\"help-block\">{{ error }}</span>\n                        {% endfor %}\n                    </div>\n                </div>\n                <div class=\"form-group{% if form.create_time.errors %} has-error{% endif %}\">\n                    {{ form.create_time.label(class=\"col-sm-2 control-label\") }}\n                    <div class=\"col-sm-10\">\n                        <div class=\"form-control\">\n                            {{ moment(form.create_time.data).format('YYYY-MM-DD HH:mm:ss') }}\n                        </div>\n                        {% for error in form.create_time.errors %}\n                            <span class=\"help-block\">{{ error }}</span>\n                        {% endfor %}\n                    </div>\n                </div>\n                <div class=\"form-group{% if form.update_time.errors %} has-error{% endif %}\">\n                    {{ form.update_time.label(class=\"col-sm-2 control-label\") }}\n                    <div class=\"col-sm-10\">\n                        <div class=\"form-control\">\n                            {{ moment(form.update_time.data).format('YYYY-MM-DD HH:mm:ss') }}\n                        </div>\n                        {% for error in form.update_time.errors %}\n                            <span class=\"help-block\">{{ error }}</span>\n                        {% endfor %}\n                    </div>\n                </div>\n                <div class=\"form-group\">\n                    <div class=\"col-sm-offset-2 col-sm-10\">\n                        <button type=\"submit\" class=\"btn btn-success btn-load\" data-loading-text=\"保存中\">保存</button>\n                        <button type=\"reset\" class=\"btn btn-default\">重新填写</button>\n                    </div>\n                </div>\n            </form>\n        </div>\n        <!-- 用户概要 -->\n        <div class=\"col-lg-4 col-md-12\">\n            <!-- 状态信息 -->\n            {% include('user/_status.html') %}\n            <!-- 推广链接 -->\n            {% include('user/_invite_link.html') %}\n            <!-- 账户信息 -->\n            {% include('user/_account_info.html') %}\n            <!-- 我的团队 -->\n            {% include('user/_team_tree.html') %}\n        </div>\n    </div>\n\n\n    </div>\n\n{% endblock %}\n\n{% block extra_js %}\n<script src=\"{{ url_for('static', filename='plugin/clipboard.js-1.6.1/dist/clipboard.min.js') }}\"></script>\n\n<script>\n    /**\n     * 用户自己激活\n     * @returns {boolean}\n     */\n    function self_active() {\n        // console.log($(form).serialize());\n        $.ajax({\n            url: \"{{ url_for('user.ajax_self_active') }}\",\n            type: 'GET',\n            dataType: 'json',\n            success: function (result) {\n                // console.log(result);\n                if(result.hasOwnProperty('error')){\n                    alert(result.error);\n                }else {\n                    alert(result.success);\n                    document.location.reload();\n                }\n            }\n        });\n        return false;\n    }\n</script>\n\n<script>\n    //推广链接复制\n    var clipboard = new Clipboard('.btn');\n\n    clipboard.on('success', function(e) {\n        // console.info('Action:', e.action);\n        // console.info('Text:', e.text);\n        // console.info('Trigger:', e.trigger);\n        e.clearSelection();\n        alert('复制成功，粘贴使用推广链接');\n    });\n\n    clipboard.on('error', function(e) {\n        // console.error('Action:', e.action);\n        // console.error('Trigger:', e.trigger);\n        alert('操作失败，重新复制推广链接');\n    });\n</script>\n<script>\n    // 初始化赋值\n    var area_id = $('#area_id');\n    area_id.selectpicker('val', '{{ form.area_id.data }}');\n    // 处理选项修改\n    area_id.on('changed.bs.select', function (event, clickedIndex, newValue, oldValue) {\n        // console.log($('#area_id').val());\n        // console.log(event);\n        // console.log(clickedIndex);\n        // console.log(newValue);\n        // console.log(oldValue);\n    });\n</script>\n\n<script>\n    // 倒计时\n    var countdown=60;\n    function set_time(val) {\n        if (countdown == 0) {\n            val.removeAttr(\"disabled\");\n            val.find(\"i\").first().html(\"发送短信\");\n            countdown = 60;\n            return;\n        } else {\n            val.attr(\"disabled\", true);\n            val.find(\"i\").first().html(\"重新发送(\" + countdown + \")\");\n            countdown--;\n        }\n        setTimeout(function () {\n            set_time(val)\n        }, 1000)\n    }\n    // 点击发送手机验证码到手机 - ajax\n    $('#get_sms_btn').click(function () {\n        var cur_obj = $(this);\n        var phone = $('#phone');\n        // 校验手机号码，图形验证码\n        if(!phone.val()){\n            phone.focus();\n            return;\n        }\n        $.getJSON('{{ url_for('user.ajax_get_sms_code') }}',\n            {\n                area_id: area_id.val(),\n                phone: phone.val()\n            }, function (data) {\n                var result = data.result;  // true/false\n                if(result==false){\n                    //console.log(result);\n                    return false;\n                }else {\n                    $('#sms').focus();\n                    set_time(cur_obj);\n                }\n            }\n        );\n    });\n</script>\n{% endblock %}\n"
  },
  {
    "path": "app_frontend/templates/user/team.html",
    "content": "<!-- extend from base layout -->\n{% extends \"layout.html\" %}\n\n{% block extra_css %}\n\n{% endblock %}\n\n{% block content %}\n    <div class=\"container\">\n    <ol class=\"breadcrumb\">\n        <li><a href=\"/\">首页</a></li>\n        <li class=\"active\">我的团队</li>\n    </ol>\n    <!-- header -->\n    <nav class=\"sub-header row container-fluid\">\n\n        <div class=\"btn-group pull-right\" role=\"group\" aria-label=\"...\">\n            {% if request.query_string == 'status_active=0' %}\n            <a type=\"button\" class=\"btn btn-default\" href=\"{{ url_for('user.team') }}\">全部团队</a>\n            <a type=\"button\" class=\"btn btn-default active\">未激活</a>\n            <a type=\"button\" class=\"btn btn-default\" href=\"{{ url_for('user.team', status_lock=1) }}\">已锁定</a>\n            {% elif request.query_string == 'status_lock=1' %}\n            <a type=\"button\" class=\"btn btn-default\" href=\"{{ url_for('user.team') }}\">全部团队</a>\n            <a type=\"button\" class=\"btn btn-default\" href=\"{{ url_for('user.team', status_active=0) }}\">未激活</a>\n            <a type=\"button\" class=\"btn btn-default active\">已锁定</a>\n            {% else %}\n            <a type=\"button\" class=\"btn btn-default active\">全部团队</a>\n            <a type=\"button\" class=\"btn btn-default\" href=\"{{ url_for('user.team', status_active=0) }}\">未激活</a>\n            <a type=\"button\" class=\"btn btn-default\" href=\"{{ url_for('user.team', status_lock=1) }}\">已锁定</a>\n            {% endif %}\n        </div>\n    </nav>\n\n    <hr/>\n    <!-- content -->\n    <div class=\"table-responsive\">\n        {# <table class=\"table table-striped\"> #}\n        <table class=\"table table-hover\">\n            <thead>\n            <tr>\n                <th>用户ID</th>\n                <th>用户名称</th>\n                <th>用户等级</th>\n                <th>激活状态</th>\n                <th>锁定状态</th>\n                <th>删除状态</th>\n                <th>操作</th>\n            </tr>\n            </thead>\n            <tbody>\n            {% for user_profile, user in pagination.items %}\n            <tr class=\"text-muted\">\n                <td>{{ user_profile.user_id }}</td>\n                <td>{{ user_profile.nickname }}</td>\n                <td>{{ user_profile.type_level | type_level }}</td>\n                <td>{{ user.status_active | status_active }}</td>\n                <td>{{ user.status_lock | status_lock }}</td>\n                <td>{{ user.status_delete | status_delete }}</td>\n                <td>\n                    {% if user.status_active == 0 %}\n                    <a type=\"button\" class=\"btn-sm btn-success\" href=\"javascript:void(0);\" onclick=\"user_active({{ user.id }});\">\n                        <span class=\"glyphicon glyphicon-star-empty\"></span> 用户激活\n                    </a>\n                    {% else %}\n{#                    <a type=\"button\" class=\"btn-sm btn-success\" href=\"javascript:void(0);\" onclick=\"add_active({{ user.id }});\">#}\n                    <a type=\"button\" class=\"btn-sm btn-success\" href=\"{{ url_for('active.add', user_name=user_profile.nickname) }}\">\n                        <span class=\"glyphicon glyphicon-star-empty\"></span> 赠送激活\n                    </a>\n                    {% endif %}\n                </td>\n            </tr>\n            {% endfor %}\n            </tbody>\n        </table>\n        {# 翻页 #}\n        {% from \"macros.html\" import render_pagination %}\n        {{ render_pagination(pagination, 'user.team') }}\n    </div>\n    </div>\n{% endblock %}\n\n{% block extra_js %}\n<script>\n// 用户激活\nfunction user_active(user_id) {\n    //console.log($(form).serialize());\n\n    if(confirm(\"为此用户激活账号，是否确认?\"))\n    {\n        $.ajax({\n            url: \"{{ url_for('user.ajax_user_active') }}\",\n            type: 'POST',\n            data: {user_id: user_id},\n            dataType: 'json',\n            success: function (result) {\n                // console.log(result);\n                if(result.hasOwnProperty('error')){\n                    alert(result.error);\n                }else {\n                    alert(result.success);\n                    document.location.reload();\n                }\n            }\n        });\n        return false;\n    }\n}\n\n// 赠送激活\nfunction add_active(user_id) {\n    //console.log($(form).serialize());\n    if(confirm(\"为此用户赠送激活码，是否确认?\"))\n    {\n        $.ajax({\n            url: \"{{ url_for('user.ajax_add_active') }}\",\n            type: 'POST',\n            data: {user_id: user_id},\n            dataType: 'json',\n            success: function (result) {\n                // console.log(result);\n                if(result.hasOwnProperty('error')){\n                    alert(result.error);\n                }else {\n                    alert(result.success);\n                    document.location.reload();\n                }\n            }\n        });\n        return false;\n    }\n}\n</script>\n{% endblock %}\n"
  },
  {
    "path": "app_frontend/templates/wallet/list.html",
    "content": "{% extends \"layout.html\" %}\n\n{% block content %}\n    <div class=\"container\">\n    <ol class=\"breadcrumb\">\n        <li><a href=\"/\">首页</a></li>\n        <li class=\"active\">账户信息</li>\n        <li class=\"active\">钱包明细</li>\n    </ol>\n\n    <div class=\"row\">\n        <div class=\"table-responsive col-lg-8 col-md-12\">\n            {# <table class=\"table table-striped\"> #}\n            <table class=\"table table-hover\">\n                <thead>\n                <tr>\n                    <th>钱包明细编号</th>\n{#                    <th>用户编号</th>#}\n                    <th>收支类型</th>\n                    <th>金额</th>\n                    <th>备注</th>\n                    <th>审核状态</th>\n                    <th>时间</th>\n                </tr>\n                </thead>\n                <tbody>\n                {% for wallet in pagination.items %}\n                <tr class=\"text-muted\">\n                    <td>{{ wallet.id }}</td>\n{#                    <td>{{ wallet.user_id }}</td>#}\n                    <td>{{ wallet.type | type_payment }}</td>\n                    <td>{{ wallet.amount }}</td>\n                    <td>{{ wallet.note }}</td>\n                    <td>{{ wallet.status_audit | status_audit }}</td>\n                    <td>{{ moment(wallet.create_time).format('YYYY-MM-DD HH:mm:ss') }}</td>\n                </tr>\n                {% endfor %}\n                </tbody>\n            </table>\n            {# 翻页 #}\n            {% from \"macros.html\" import render_pagination %}\n            {{ render_pagination(pagination, 'wallet.lists') }}\n        </div>\n        <!-- 用户概要 -->\n        <div class=\"col-lg-4 col-md-12\">\n            <!-- 状态信息 -->\n            {% include('user/_status.html') %}\n            <!-- 推广链接 -->\n            {% include('user/_invite_link.html') %}\n            <!-- 账户信息 -->\n            {% include('user/_account_info.html') %}\n            <!-- 我的团队 -->\n            {% include('user/_team_tree.html') %}\n        </div>\n    </div>\n\n\n    </div>\n\n{% endblock %}\n\n{% block extra_js %}\n<script src=\"{{ url_for('static', filename='plugin/clipboard.js-1.6.1/dist/clipboard.min.js') }}\"></script>\n\n<script>\n    /**\n     * 用户自己激活\n     * @returns {boolean}\n     */\n    function self_active() {\n        // console.log($(form).serialize());\n        $.ajax({\n            url: \"{{ url_for('user.ajax_self_active') }}\",\n            type: 'GET',\n            dataType: 'json',\n            success: function (result) {\n                // console.log(result);\n                if(result.hasOwnProperty('error')){\n                    alert(result.error);\n                }else {\n                    alert(result.success);\n                    document.location.reload();\n                }\n            }\n        });\n        return false;\n    }\n</script>\n\n<script>\n    //推广链接复制\n    var clipboard = new Clipboard('.btn');\n\n    clipboard.on('success', function(e) {\n        // console.info('Action:', e.action);\n        // console.info('Text:', e.text);\n        // console.info('Trigger:', e.trigger);\n        e.clearSelection();\n        alert('复制成功，粘贴使用推广链接');\n    });\n\n    clipboard.on('error', function(e) {\n        // console.error('Action:', e.action);\n        // console.error('Trigger:', e.trigger);\n        alert('操作失败，重新复制推广链接');\n    });\n</script>\n{% endblock %}\n"
  },
  {
    "path": "app_frontend/tools/__init__.py",
    "content": "#!/usr/bin/env python\n# encoding: utf-8\n\n\"\"\"\n@author: zhanghe\n@software: PyCharm\n@file: __init__.py\n@time: 16-2-22 下午11:05\n\"\"\"\n"
  },
  {
    "path": "app_frontend/tools/config_manage.py",
    "content": "#!/usr/bin/env python\n# encoding: utf-8\n\n\"\"\"\n@author: zhanghe\n@software: PyCharm\n@file: config_manage.py\n@time: 2017/6/4 上午11:00\n\"\"\"\n\n\nimport redis\nimport json\nimport time\nfrom app_frontend import app\nredis_client = redis.Redis(**app.config['REDIS'])\n\n\ndef get_conf(conf_name):\n    \"\"\"\n    获取配置\n    :param conf_name:\n    :return:\n    \"\"\"\n    conf_key = 'conf:%s' % conf_name\n    conf_value = redis_client.get(conf_key)\n    res = conf_value or app.config.get(conf_name)\n    return str(res)\n\n\ndef set_conf(conf_name, conf_value):\n    \"\"\"\n    设置配置\n    :param conf_name:\n    :param conf_value:\n    :return:\n    \"\"\"\n    conf_key = 'conf:%s' % conf_name\n    return redis_client.set(conf_key, conf_value)\n\n\ndef clean_conf():\n    \"\"\"\n    清除配置\n    :return:\n    \"\"\"\n    conf_key = 'conf:*'\n    conf_keys = redis_client.keys(conf_key)\n    return redis_client.delete(*conf_keys)\n\n\nif __name__ == '__main__':\n    print get_conf('INTEREST_PUT'), type(get_conf('INTEREST_PUT'))\n    # print set_conf('APPLY_PUT_MIN_EACH', 4000)\n    print clean_conf()\n"
  },
  {
    "path": "app_frontend/tools/db.py",
    "content": "#!/usr/bin/env python\n# encoding: utf-8\n\n\"\"\"\n@author: zhanghe\n@software: PyCharm\n@file: tools.py\n@time: 16-1-25 下午8:39\n\"\"\"\n\n# todo get_rows order_by\n# todo insert ignore\n\n\nfrom app_frontend.database import db\nfrom sqlalchemy.inspection import inspect\n\n\ndef get_row_by_id(model_name, pk_id):\n    \"\"\"\n    通过 id 获取信息\n    :param model_name:\n    :param pk_id:\n    :return: None/object\n    \"\"\"\n    try:\n        row = db.session.query(model_name).get(pk_id)\n        db.session.commit()\n        return row\n    except Exception as e:\n        db.session.rollback()\n        raise e\n\n\ndef get_rows_by_ids(model_name, pk_ids):\n    \"\"\"\n    通过一组 ids 获取信息列表\n    :param model_name:\n    :param pk_ids:\n    :return: list\n    \"\"\"\n    try:\n        model_pk = inspect(model_name).primary_key[0]\n        rows = db.session.query(model_name).filter(model_pk.in_(pk_ids)).all()\n        db.session.commit()\n        return rows\n    except Exception as e:\n        db.session.rollback()\n        raise e\n\n\ndef get_limit_rows_by_last_id(model_name, last_pk_id, limit_num, *args, **kwargs):\n    \"\"\"\n    通过最后一个主键 id 获取最新信息列表\n    适用场景：\n    1、动态加载\n    2、快速定位\n    :param model_name:\n    :param last_pk_id:\n    :param limit_num:\n    :param args:\n    :param kwargs:\n    :return: list\n    \"\"\"\n    try:\n        model_pk = inspect(model_name).primary_key[0]\n        rows = db.session.query(model_name).filter(model_pk > last_pk_id, *args).filter_by(**kwargs).limit(limit_num).all()\n        db.session.commit()\n        return rows\n    except Exception as e:\n        db.session.rollback()\n        raise e\n\n\ndef get_row(model_name, *args, **kwargs):\n    \"\"\"\n    获取信息\n    Usage:\n        # 方式一\n        get_row(User, User.id > 1)\n        # 方式二\n        test_condition = {\n            'name': \"Larry\"\n        }\n        get_row(User, **test_condition)\n    :param model_name:\n    :param args:\n    :param kwargs:\n    :return: None/object\n    \"\"\"\n    try:\n        row = db.session.query(model_name).filter(*args).filter_by(**kwargs).first()\n        db.session.commit()\n        return row\n    except Exception as e:\n        db.session.rollback()\n        raise e\n\n\ndef get_lists(model_name, *args, **kwargs):\n    \"\"\"\n    获取列表信息\n    Usage:\n        # 方式一\n        get_lists(User, User.id > 1)\n        # 方式二\n        test_condition = {\n            'name': \"Larry\"\n        }\n        get_lists(User, **test_condition)\n    :param model_name:\n    :param args:\n    :param kwargs:\n    :return: None/list\n    \"\"\"\n    try:\n        lists = db.session.query(model_name).filter(*args).filter_by(**kwargs).all()\n        db.session.commit()\n        return lists\n    except Exception as e:\n        db.session.rollback()\n        raise e\n\n\ndef count(model_name, *args, **kwargs):\n    \"\"\"\n    计数\n    Usage:\n        # 方式一\n        count(User, User.id > 1)\n        # 方式二\n        test_condition = {\n            'name': \"Larry\"\n        }\n        count(User, **test_condition)\n    :param model_name:\n    :param args:\n    :param kwargs:\n    :return: 0/Number（int）\n    \"\"\"\n    try:\n        result_count = db.session.query(model_name).filter(*args).filter_by(**kwargs).count()\n        db.session.commit()\n        return result_count\n    except Exception as e:\n        db.session.rollback()\n        raise e\n\n\ndef add(model_name, data):\n    \"\"\"\n    添加信息\n    :param model_name:\n    :param data:\n    :return: None/Value of model_obj.PK\n    \"\"\"\n    model_obj = model_name(**data)\n    try:\n        db.session.add(model_obj)\n        db.session.commit()\n        return inspect(model_obj).identity[0]\n    except Exception as e:\n        db.session.rollback()\n        raise e\n\n\ndef edit(model_name, pk_id, data):\n    \"\"\"\n    修改信息\n    :param model_name:\n    :param pk_id:\n    :param data:\n    :return: Number of affected rows (Example: 0/1)\n    \"\"\"\n    model_pk = inspect(model_name).primary_key[0]\n    try:\n        model_obj = db.session.query(model_name).filter(model_pk == pk_id)\n        result = model_obj.update(data)\n        db.session.commit()\n        return result\n    except Exception as e:\n        db.session.rollback()\n        raise e\n\n\ndef increase(model_name, pk_id, field, num=1, **kwargs):\n    \"\"\"\n    字段自增\n    :param model_name:\n    :param pk_id:\n    :param field:\n    :param num:\n    :param kwargs:\n    :return: Number of affected rows (Example: 0/1)\n    \"\"\"\n    model_pk = inspect(model_name).primary_key[0]\n    try:\n        model_obj = db.session.query(model_name).filter(model_pk == pk_id)\n        value = getattr(model_name, field) + num\n        data = {\n            field: value\n        }\n        data.update(**kwargs)  # 更新扩展字段\n        result = model_obj.update(data)\n        db.session.commit()\n        return result\n    except Exception as e:\n        db.session.rollback()\n        raise e\n\n\ndef merge(model_name, data):\n    \"\"\"\n    覆盖信息(没有新增，存在更新)\n    数据中必须带主键字段\n    :param model_name:\n    :param data:\n    :return: Value of PK\n    \"\"\"\n    model_obj = model_name(**data)\n    try:\n        r = db.session.merge(model_obj)\n        db.session.commit()\n        return inspect(r).identity[0]\n    except Exception as e:\n        db.session.rollback()\n        raise e\n\n\ndef delete(model_name, pk_id):\n    \"\"\"\n    删除信息\n    :param model_name:\n    :param pk_id:\n    :return: Number of affected rows (Example: 0/1)\n    \"\"\"\n    model_pk = inspect(model_name).primary_key[0]\n    try:\n        model_obj = db.session.query(model_name).filter(model_pk == pk_id)\n        result = model_obj.delete()\n        db.session.commit()\n        return result\n    except Exception as e:\n        db.session.rollback()\n        raise e\n\n\ndef get_rows(model_name, page=1, per_page=10, *args, **kwargs):\n    \"\"\"\n    获取信息列表（分页）\n    Usage:\n        items: 信息列表\n        has_next: 如果本页之后还有超过一个分页，则返回True\n        has_prev: 如果本页之前还有超过一个分页，则返回True\n        next_num: 返回下一页的页码\n        prev_num: 返回上一页的页码\n        iter_pages(): 页码列表\n        iter_pages(left_edge=2, left_current=2, right_current=5, right_edge=2) 页码列表默认参数\n    :param model_name:\n    :param page:\n    :param per_page:\n    :param args:\n    :param kwargs:\n    :return: None/object\n    \"\"\"\n    try:\n        rows = model_name.query. \\\n            filter(*args). \\\n            filter_by(**kwargs). \\\n            order_by(inspect(model_name).primary_key[0].desc()). \\\n            paginate(page, per_page, False)\n        db.session.commit()\n        return rows\n    except Exception as e:\n        db.session.rollback()\n        raise e\n\n\ndef insert_rows(model_name, data_list):\n    \"\"\"\n    批量插入数据（遇到主键/唯一索引重复，忽略报错，继续执行下一条插入任务）\n    注意：\n    Warning: Duplicate entry\n    警告有可能会提示：\n    UnicodeEncodeError: 'ascii' codec can't encode characters in position 17-20: ordinal not in range(128)\n    处理：\n    import sys\n\n    reload(sys)\n    sys.setdefaultencoding('utf8')\n\n    sql 语句大小限制\n    show VARIABLES like '%max_allowed_packet%';\n    参考：http://dev.mysql.com/doc/refman/5.7/en/packet-too-large.html\n\n    :param model_name:\n    :param data_list:\n    :return:\n    \"\"\"\n    try:\n        result = db.session.execute(model_name.__table__.insert().prefix_with('IGNORE'), data_list)\n        db.session.commit()\n        return result.rowcount\n    except Exception as e:\n        db.session.rollback()\n        raise e\n\n\ndef update_rows(model_name, data, *args, **kwargs):\n    \"\"\"\n    批量修改数据\n    :param model_name:\n    :param data:\n    :param args:\n    :param kwargs:\n    :return:\n    \"\"\"\n    try:\n        model_obj = db.session.query(model_name).filter(*args).filter_by(**kwargs)\n        result = model_obj.update(data, synchronize_session=False)\n        db.session.commit()\n        return result\n    except Exception as e:\n        db.session.rollback()\n        raise e\n\n\ndef update_rows_by_ids(model_name, pk_ids, data):\n    \"\"\"\n    根据一组主键id 批量修改数据\n    \"\"\"\n    model_pk = inspect(model_name).primary_key[0]\n    try:\n        model_obj = db.session.query(model_name).filter(model_pk.in_(pk_ids))\n        result = model_obj.update(data, synchronize_session=False)\n        db.session.commit()\n        return result\n    except Exception as e:\n        db.session.rollback()\n        raise e\n\n\ndef test_user():\n    \"\"\"\n    测试 User\n    :return:\n    \"\"\"\n    from app.models import User\n    print '\\n测试增删改查'\n    # 测试获取\n    row = get_row_by_id(User, 1)\n    print row\n    if row:\n        print row.id, row.email, row.nickname\n    # 测试添加\n    user_info = {\n        'email': 'admin@gmail.com',\n        # 'password': '123456',\n        'nickname': 'Admin',\n    }\n    # 测试计数\n    result_count = count(User, User.id > 1, **{'id': 2})\n    print result_count\n\n    result = add(User, user_info)\n    print result\n    # # 测试修改\n    # result = edit(User, 2, {'nickname': 'Emma'})\n    # print result\n    # # 测试删除\n    # result = delete(User, 2)\n    # print result\n    #\n    print '\\n测试单条信息'\n    test_condition = {\n        'nickname': \"Larry\"\n    }\n    row = get_row(User, **test_condition)\n    print row\n    if row:\n        print row.id, row.email, row.nickname\n    row = get_row(User, User.id > 0, id=3)\n    print row\n    if row:\n        print row.id, row.email, row.nickname\n\n\ndef test_blog():\n    \"\"\"\n    测试 Blog\n    :return:\n    \"\"\"\n    from app.models import Blog\n    print '测试通过上一次id获取列表信息'\n    rows = get_limit_rows_by_last_id(Blog, 1, 4, Blog.id > 2, **{'id': 7})\n    if rows:\n        for item in rows:\n            print item.id, item.author, item.title, item.pub_date\n\n    print '测试列表信息'\n    rows = get_rows(Blog, 1, 10, Blog.id > 0, Blog.id < 9, **{'id': 7})\n    if rows:\n        for item in rows.items:\n            print item.id, item.author, item.title, item.pub_date\n\n\ndef test_transaction():\n    \"\"\"\n    测试事务\n    \"\"\"\n    from app.models import User\n    from datetime import datetime\n    print '\\n测试事务'\n\n    try:\n        current_time = datetime.utcnow()\n        user_info_01 = {\n            'nickname': 'rose',\n            'avatar_url': '',\n            'email': 'rose@gmail.com',\n            'phone': '13818731111',\n            'create_time': current_time,\n            'update_time': current_time,\n            'last_ip': '0.0.0.0'\n        }\n        model_obj_01 = User(**user_info_01)\n        db.session.add(model_obj_01)\n        db.session.flush()\n        print inspect(model_obj_01).identity[0]\n\n        user_info_02 = {\n            'nickname': 'pit',\n            'avatar_url': '',\n            'email': 'pit@gmail.com',\n            'phone': '13818730000',\n            'create_time': current_time,\n            'update_time': current_time,\n            'last_ip': '0.0.0.0'\n        }\n        model_obj_02 = User(**user_info_02)\n        db.session.add(model_obj_02)\n        db.session.flush()\n        print inspect(model_obj_02).identity[0]\n\n    except Exception as e:\n        db.session.rollback()\n        raise e\n\n\ndef test_label():\n    \"\"\"\n    测试字符串截取和别名\n    SqLite substr\n    MySql left\n    :return:\n    \"\"\"\n    from app.models import User\n    from sqlalchemy import func\n    rows = db.session.query(User.id, func.substr(User.nickname, 2).label('nickname_new'),\n                            User.create_time).filter().order_by(User.nickname, User.create_time.desc()).all()\n    for row in rows:\n        print row.id, row.nickname_new, row.create_time\n\n\ndef test_join():\n    from app_frontend.models import User, UserProfile\n    # rows = db.session.query(User, UserProfile).outerjoin(UserProfile, User.id == UserProfile.user_id).order_by(User.id.desc()).all()\n    # for row in rows:\n    #     print row[0].__dict__, row[1].__dict__\n    # paginate = User.query.join(UserProfile, User.id == UserProfile.user_id).add_columns(User.id, UserProfile.nickname).order_by(User.id.desc()).paginate(1, 10, False)\n    paginate = User.query.join(UserProfile, User.id == UserProfile.user_id).add_entity(UserProfile).order_by(User.id.desc()).paginate(1, 10, False)\n    print paginate.items\n    for (a, b) in paginate.items:\n        print a.id, b.user_id\n\n\ndef test_increase():\n    from app_frontend.models import ApplyGet, Wallet, WalletItem\n\n    kwargs = {\n        'status_delete': 1\n    }\n    print increase(ApplyGet, 11, 'money_apply', num=2000, **kwargs)\n\n\nif __name__ == '__main__':\n    # test_user()\n    # test_blog()\n    # test_transaction()\n    # test_label()\n    # test_join()\n    test_increase()\n"
  },
  {
    "path": "app_frontend/tools/db_test_mysql.py",
    "content": "#!/usr/bin/env python\n# encoding: utf-8\n\n\"\"\"\n@author: zhanghe\n@software: PyCharm\n@file: db_test_mysql.py\n@time: 16-3-25 下午11:35\n\"\"\"\n\n\nimport unittest\nfrom app_frontend.tools.system import get_memory_usage\nfrom config import SQLALCHEMY_DATABASE_URI\nimport os\n\n\nclass TestDB(unittest.TestCase):\n    \"\"\"\n    数据库操作测试用例\n    \"\"\"\n    def setUp(self):\n        \"\"\"\n        测试前准备环境的搭建\n        \"\"\"\n        # 备份数据\n        cmd = os.path.join(BASE_DIR, 'etc/db_dump.sh')\n        os.system(cmd)\n        # 准备测试数据\n        cmd = os.path.join(BASE_DIR, 'etc/db_init.sh')\n        os.system(cmd)\n        print\n        pass\n\n    def test_get_row_by_id(self):\n        \"\"\"\n        测试 通过主键获取信息\n        \"\"\"\n        print self.test_get_row_by_id.__doc__.strip()\n        from app.tools.db import get_row_by_id\n        from app.models import User\n        # 测试有记录的场景\n        row = get_row_by_id(User, 1)\n        assert row.id == 1\n        assert row.email == 'admin@gmail.com'\n        assert row.nickname == 'Admin'\n        # 测试无记录的场景\n        row = get_row_by_id(User, 100)\n        assert row is None\n\n    def test_get_rows_by_ids(self):\n        \"\"\"\n        测试 通过主键列表获取信息列表\n        \"\"\"\n        print self.test_get_rows_by_ids.__doc__.strip()\n        from app.tools.db import get_rows_by_ids\n        from app.models import User\n        # # 测试有记录的场景\n        rows = get_rows_by_ids(User, [1, 2, 3])\n        assert len(rows) == 3\n        assert rows[0].id == 1\n        assert rows[0].email == 'admin@gmail.com'\n        assert rows[0].nickname == 'Admin'\n        # 测试无记录的场景\n        rows = get_rows_by_ids(User, [100])\n        assert rows == []\n\n    def test_get_row(self):\n        \"\"\"\n        测试 获取信息\n        \"\"\"\n        print self.test_get_row.__doc__.strip()\n        from app.tools.db import get_row\n        from app.models import User\n        # 测试有记录的场景一\n        row = get_row(User, User.id > 1)\n        assert row.id == 2\n        assert row.email == 'guest@gmail.com'\n        assert row.nickname == 'Guest'\n        # 测试有记录的场景二\n        row = get_row(User, nickname='Guest')\n        assert row.id == 2\n        assert row.email == 'guest@gmail.com'\n        assert row.nickname == 'Guest'\n        # 测试有记录的场景三\n        row = get_row(User, **{'nickname': 'Guest'})\n        assert row.id == 2\n        assert row.email == 'guest@gmail.com'\n        assert row.nickname == 'Guest'\n        # 测试无记录的场景\n        row = get_row(User, User.id == 100)\n        assert row is None\n\n    def test_count(self):\n        \"\"\"\n        测试 计数\n        \"\"\"\n        print self.test_count.__doc__.strip()\n        from app.tools.db import count\n        from app.models import User\n        # 测试带查询条件并结果大于0的场景\n        rows_count = count(User, User.id > 0, User.id < 100)\n        assert rows_count == 3\n        # 测试带查询条件并结果等于0的场景\n        rows_count = count(User, User.id > 100)\n        assert rows_count == 0\n        # 测试无查询条件并结果大于0的场景\n        rows_count = count(User)\n        assert rows_count == 3\n\n    def test_add(self):\n        \"\"\"\n        测试 添加信息\n        \"\"\"\n        print self.test_add.__doc__.strip()\n        from app.tools.db import add\n        from app.models import User\n        # 测试正确的场景\n        user_info = {\n            'email': 'bob@gmail.com',\n            'password': '123456',\n            'nickname': 'Bob',\n        }\n        result = add(User, user_info)\n        assert result == 4\n        # 测试错误的场景\n        user_info = {\n            'email': 'error@gmail.com',\n            'password': '123456',\n            # 'nickname': 'Error',\n        }\n        try:\n            result = add(User, user_info)\n        except Exception as e:\n            assert e.message == '(sqlite3.IntegrityError) NOT NULL constraint failed: user.nickname'\n        assert result == 4\n\n    def tearDown(self):\n        \"\"\"\n        测试后环境的还原\n        \"\"\"\n        # 恢复数据\n        cmd = os.path.join(BASE_DIR, 'etc/db_restore.sh')\n        os.system(cmd)\n        # 获取内存消耗\n        get_memory_usage()\n        pass\n\n\nif __name__ == '__main__':\n    unittest.main()\n\n\n\"\"\"\nTesting started at 上午12:59 ...\n\n测试 添加信息\n[pid:24399]内存使用28.22M\n\n测试 计数\n[pid:24399]内存使用28.63M\n\n测试 获取信息\n[pid:24399]内存使用28.69M\n\n测试 通过主键获取信息\n[pid:24399]内存使用28.69M\n\n测试 通过主键列表获取信息列表\n[pid:24399]内存使用28.72M\n\nProcess finished with exit code 0\n\"\"\""
  },
  {
    "path": "app_frontend/tools/db_test_sqlite.py",
    "content": "#!/usr/bin/env python\n# encoding: utf-8\n\n\"\"\"\n@author: zhanghe\n@software: PyCharm\n@file: db_test_sqlite.py\n@time: 16-3-25 下午11:35\n\"\"\"\n\n\nimport unittest\nfrom app_frontend.tools.system import get_memory_usage\nfrom config import BASE_DIR\nimport os\n\n\nclass TestDB(unittest.TestCase):\n    \"\"\"\n    数据库操作测试用例\n    \"\"\"\n    def setUp(self):\n        \"\"\"\n        测试前准备环境的搭建\n        \"\"\"\n        # 备份数据\n        cmd = os.path.join(BASE_DIR, 'etc/db_dump.sh')\n        os.system(cmd)\n        # 准备测试数据\n        cmd = os.path.join(BASE_DIR, 'etc/db_init.sh')\n        os.system(cmd)\n        print\n        pass\n\n    def test_get_row_by_id(self):\n        \"\"\"\n        测试 通过主键获取信息\n        \"\"\"\n        print self.test_get_row_by_id.__doc__.strip()\n        from app.tools.db import get_row_by_id\n        from app.models import User\n        # 测试有记录的场景\n        row = get_row_by_id(User, 1)\n        assert row.id == 1\n        assert row.email == 'admin@gmail.com'\n        assert row.nickname == 'Admin'\n        # 测试无记录的场景\n        row = get_row_by_id(User, 100)\n        assert row is None\n\n    def test_get_rows_by_ids(self):\n        \"\"\"\n        测试 通过主键列表获取信息列表\n        \"\"\"\n        print self.test_get_rows_by_ids.__doc__.strip()\n        from app.tools.db import get_rows_by_ids\n        from app.models import User\n        # # 测试有记录的场景\n        rows = get_rows_by_ids(User, [1, 2, 3])\n        assert len(rows) == 3\n        assert rows[0].id == 1\n        assert rows[0].email == 'admin@gmail.com'\n        assert rows[0].nickname == 'Admin'\n        # 测试无记录的场景\n        rows = get_rows_by_ids(User, [100])\n        assert rows == []\n\n    def test_get_row(self):\n        \"\"\"\n        测试 获取信息\n        \"\"\"\n        print self.test_get_row.__doc__.strip()\n        from app.tools.db import get_row\n        from app.models import User\n        # 测试有记录的场景一\n        row = get_row(User, User.id > 1)\n        assert row.id == 2\n        assert row.email == 'guest@gmail.com'\n        assert row.nickname == 'Guest'\n        # 测试有记录的场景二\n        row = get_row(User, nickname='Guest')\n        assert row.id == 2\n        assert row.email == 'guest@gmail.com'\n        assert row.nickname == 'Guest'\n        # 测试有记录的场景三\n        row = get_row(User, **{'nickname': 'Guest'})\n        assert row.id == 2\n        assert row.email == 'guest@gmail.com'\n        assert row.nickname == 'Guest'\n        # 测试无记录的场景\n        row = get_row(User, User.id == 100)\n        assert row is None\n\n    def test_count(self):\n        \"\"\"\n        测试 计数\n        \"\"\"\n        print self.test_count.__doc__.strip()\n        from app.tools.db import count\n        from app.models import User\n        # 测试带查询条件并结果大于0的场景\n        rows_count = count(User, User.id > 0, User.id < 100)\n        assert rows_count == 3\n        # 测试带查询条件并结果等于0的场景\n        rows_count = count(User, User.id > 100)\n        assert rows_count == 0\n        # 测试无查询条件并结果大于0的场景\n        rows_count = count(User)\n        assert rows_count == 3\n\n    def test_add(self):\n        \"\"\"\n        测试 添加信息\n        \"\"\"\n        print self.test_add.__doc__.strip()\n        from app.tools.db import add\n        from app.models import User\n        # 测试正确的场景\n        user_info = {\n            'email': 'bob@gmail.com',\n            'password': '123456',\n            'nickname': 'Bob',\n        }\n        result = add(User, user_info)\n        assert result == 4\n        # 测试错误的场景\n        user_info = {\n            'email': 'error@gmail.com',\n            'password': '123456',\n            # 'nickname': 'Error',\n        }\n        try:\n            result = add(User, user_info)\n        except Exception as e:\n            assert e.message == '(sqlite3.IntegrityError) NOT NULL constraint failed: user.nickname'\n        assert result == 4\n\n    def tearDown(self):\n        \"\"\"\n        测试后环境的还原\n        \"\"\"\n        # 恢复数据\n        cmd = os.path.join(BASE_DIR, 'etc/db_restore.sh')\n        os.system(cmd)\n        # 获取内存消耗\n        get_memory_usage()\n        pass\n\n\nif __name__ == '__main__':\n    unittest.main()\n\n\n\"\"\"\nTesting started at 上午12:59 ...\n\n测试 添加信息\n[pid:24399]内存使用28.22M\n\n测试 计数\n[pid:24399]内存使用28.63M\n\n测试 获取信息\n[pid:24399]内存使用28.69M\n\n测试 通过主键获取信息\n[pid:24399]内存使用28.69M\n\n测试 通过主键列表获取信息列表\n[pid:24399]内存使用28.72M\n\nProcess finished with exit code 0\n\"\"\""
  },
  {
    "path": "app_frontend/tools/decorators.py",
    "content": "#!/usr/bin/env python\n# encoding: utf-8\n\n\"\"\"\n@author: zhanghe\n@software: PyCharm\n@file: decorators.py\n@time: 16-3-11 下午3:08\n\"\"\"\n\n\nfrom threading import Thread\n\n\ndef async(f):\n    \"\"\"\n    基于线程的异步调用装饰器\n    :param f:\n    :return:\n    \"\"\"\n    def wrapper(*args, **kwargs):\n        thr = Thread(target=f, args=args, kwargs=kwargs)\n        thr.start()\n    return wrapper\n"
  },
  {
    "path": "app_frontend/tools/exception.py",
    "content": "#!/usr/bin/env python\n# encoding: utf-8\n\n\"\"\"\n@author: zhanghe\n@software: PyCharm\n@file: exception.py\n@time: 2017/6/7 下午8:31\n\"\"\"\n\n\nclass DropException(Exception):\n    \"\"\"\n    数据、消息丢弃\n    \"\"\"\n    pass\n"
  },
  {
    "path": "app_frontend/tools/file.py",
    "content": "#!/usr/bin/env python\n# encoding: utf-8\n\n\"\"\"\n@author: zhanghe\n@software: PyCharm\n@file: file.py\n@time: 16-3-29 下午2:21\n\"\"\"\n\n\nimport os\nimport glob\n\n\ndef read_files(file_dir='*', suffix='*'):\n    \"\"\"\n    读取目录下指定文件\n    :param file_dir:\n    :param suffix:\n    :return:\n    \"\"\"\n    try:\n        for file_name in glob.glob(r'%s*.%s' % (file_dir, suffix)):\n            if os.path.isfile(file_name):\n                print file_name, os.path.abspath(file_name)\n    except OSError:\n        print u'读取文件失败'\n    except Exception, e:\n        print e.message\n\n\nif __name__ == '__main__':\n    read_files()\n"
  },
  {
    "path": "app_frontend/tools/send_sms.py",
    "content": "#!/usr/bin/env python\n# encoding: utf-8\n\n\"\"\"\n@author: zhanghe\n@software: PyCharm\n@file: send_sms.py\n@time: 2017/4/5 下午1:47\n\"\"\"\n\n\nfrom sshtunnel import SSHTunnelForwarder\nfrom sqlalchemy.orm import sessionmaker\nfrom sqlalchemy import create_engine\nfrom app_frontend.lib.sms_chuanglan_iso import SmsChuangLanIsoApi\nimport time\nfrom config import SSH_CONFIG, SMS\n\n\n# 隧道配置\nSSH_IP = SSH_CONFIG['IP']\nSSH_PORT = SSH_CONFIG['PORT']\nSSH_USERNAME = SSH_CONFIG['USERNAME']\nSSH_PASSWORD = SSH_CONFIG['PASSWORD']\n\n# DB配置\nDB_MYSQL = SSH_CONFIG['DB_MYSQL']\n\n\n# 短信接口配置\nUN = SMS['UN']           # 创蓝账号\nPW = SMS['PW']           # 创蓝密码\n\n\ndef get_server_tunnel():\n    \"\"\"\n    获取连接隧道\n    :return:\n    \"\"\"\n    server_tunnel = SSHTunnelForwarder(\n        (SSH_IP, SSH_PORT),\n        ssh_password=SSH_PASSWORD,\n        ssh_username=SSH_USERNAME,\n        remote_bind_address=(DB_MYSQL['host'], DB_MYSQL['port']))\n    return server_tunnel\n\n\ndef get_db_session(server_tunnel=None):\n    \"\"\"\n    获取db_session\n    :param server_tunnel:\n    :return:\n    \"\"\"\n    if server_tunnel:\n        local_port = str(server_tunnel.local_bind_port)\n\n        sqlalchemy_database_uri_mysql = \\\n            'mysql+mysqldb://%s:%s@%s:%s/%s?charset=utf8' % \\\n            (DB_MYSQL['user'], DB_MYSQL['passwd'], DB_MYSQL['host'], local_port, DB_MYSQL['db'])\n    else:\n        sqlalchemy_database_uri_mysql = \\\n            'mysql+mysqldb://%s:%s@%s:%s/%s?charset=utf8' % \\\n            (DB_MYSQL['user'], DB_MYSQL['passwd'], DB_MYSQL['host'], DB_MYSQL['port'], DB_MYSQL['db'])\n    engine = create_engine(sqlalchemy_database_uri_mysql)\n\n    # connect to DB\n    DB_Session = sessionmaker(autocommit=True, autoflush=True, bind=engine)\n    session = DB_Session()\n    return session\n\n\ndef run_send_sms(server_tunnel=None):\n    \"\"\"\n    短信发送\n    :return:\n    \"\"\"\n    if server_tunnel and not server_tunnel.is_active:\n        server.start()  # start ssh sever\n        print 'Server reconnected via SSH'\n    session = get_db_session(server_tunnel)\n    print 'Database session created'\n\n    sms_client = SmsChuangLanIsoApi(UN, PW)\n\n    # test data retrieval\n    while 1:\n        sql_fetch = \"SELECT * FROM ot_sms WHERE sent_st=0 limit 100\"\n        sql_edit = 'UPDATE ot_sms SET sent_st=:sent_st WHERE id=:id;'\n        rows = session.execute(sql_fetch).fetchall()\n        for row in rows:\n            # 处理中\n            session.execute(sql_edit, {'id': row['id'], 'sent_st': 1})\n            # 发送信息\n            print time.strftime('%Y-%m-%d %H:%M:%S'), row['mobile'], row['msg']\n\n            result = sms_client.send_international('86%s' % row['mobile'], row['msg'])\n            print result\n            if result['success']:\n                print session.execute(sql_edit, {'id': row['id'], 'sent_st': 2}).rowcount\n            else:\n                print session.execute(sql_edit, {'id': row['id'], 'sent_st': 3}).rowcount\n    # server.stop()  # stop ssh sever\n\n\nif __name__ == '__main__':\n    # 隧道模式\n    server = get_server_tunnel()\n    server.start()\n    run_send_sms(server)\n    server.stop()\n    # 普通模式\n    run_send_sms()\n\n\n\"\"\"\n✗ pip install sshtunnel\n✗ pip install MySQL-python\n✗ pip install schedule\n\"\"\""
  },
  {
    "path": "app_frontend/tools/session_manage.py",
    "content": "#!/usr/bin/env python\n# encoding: utf-8\n\n\"\"\"\n@author: zhanghe\n@software: PyCharm\n@file: session_manage.py\n@time: 2017/4/9 上午11:16\n\"\"\"\n\n\nimport redis\nimport json\nfrom config import REDIS\n\n\nredis_client = redis.Redis(**REDIS)\n\n\ndef get_session(session_id):\n    session_key = 'session:%s' % session_id\n    print json.loads(redis_client.get(session_key))\n\n\nif __name__ == '__main__':\n    get_session('f093df3e-5f8b-432a-ab56-99e3975225f4')\n"
  },
  {
    "path": "app_frontend/tools/stat.py",
    "content": "#!/usr/bin/env python\n# encoding: utf-8\n\n\"\"\"\n@author: zhanghe\n@software: PyCharm\n@file: stat.py\n@time: 16-2-22 下午11:08\n\"\"\"\n\n\nfrom app_frontend.api.blog import get_blog_counter, set_blog_counter, add_blog_stat_item, get_blog_container_status\nfrom app_frontend.api.user import add_user_stat_item\n\n# 定义支持的统计类型\nstat_type_list = [\n    'favor',  # 支持数\n    'decry',  # 反对数\n    'follow',  # 关注数\n    'fans',  # 粉丝数\n    'view',  # 点击数\n    'collect',  # 收藏数\n    'flag'  # 举报数\n]\n\n\ndef set_blog_stat(stat_type, uid, item_id, num=1):\n    \"\"\"\n    设置 blog 统计\n    :param stat_type:\n    :param uid:\n    :param item_id:\n    :param num:\n    :return:\n    \"\"\"\n    blog_status = add_blog_stat_item(stat_type, item_id, uid)  # 更新blog容器\n    user_status = add_user_stat_item(stat_type, uid, item_id)  # 更新user容器\n    if blog_status == 1 and user_status == 1:\n        count = set_blog_counter(item_id, stat_type, num)  # 更新计数器\n    else:\n        # 如果已经更新容器，计数器不需更新\n        count = get_blog_counter(item_id)\n    status = get_blog_container_status(item_id, uid)\n    result = {\n        'count': count,\n        'status': status\n    }\n    return result\n\n\nif __name__ == '__main__':\n    pass\n"
  },
  {
    "path": "app_frontend/tools/system.py",
    "content": "#!/usr/bin/env python\n# encoding: utf-8\n\n\"\"\"\n@author: zhanghe\n@software: PyCharm\n@file: system.py\n@time: 16-4-17 下午11:59\n\"\"\"\n\n\nimport os\n\n\ndef get_memory_usage():\n    \"\"\"\n    获取当前进程内存使用情况(单位M)\n    \"\"\"\n    # 获取当前脚本的进程ID\n    pid = os.getpid()\n    # 获取当前脚本占用的内存\n    cmd = 'ps -p %s -o rss=' % pid\n    output = os.popen(cmd)\n    result = output.read()\n    if result == '':\n        memory_usage_value = 0\n    else:\n        memory_usage_value = int(result.strip())\n    memory_usage_format = memory_usage_value / 1024.0\n    print '[pid:%s]内存使用%.2fM' % (pid, memory_usage_format)\n\n\nif __name__ == '__main__':\n    get_memory_usage()\n"
  },
  {
    "path": "app_frontend/tools/url.py",
    "content": "#!/usr/bin/env python\n# encoding: utf-8\n\n\"\"\"\n@author: zhanghe\n@software: PyCharm\n@file: url.py\n@time: 16-3-25 下午3:19\n\"\"\"\n\n\nfrom urlparse import urlparse\n\n\ndef secure_url(url, netloc='', default_url='/'):\n    \"\"\"\n    获取安全 url\n    不带域名的链接，不需指定 netloc 参数\n    有域名的链接，需要指定 netloc 为授权的域名（不带协议）\n    :param url:\n    :param netloc:\n    :param default_url:\n    :return:\n    \"\"\"\n    parse_result = urlparse(url)\n    if parse_result.netloc in ['', netloc]:\n        return url\n    return default_url\n\n\ndef test():\n    \"\"\"\n    测试获取安全url\n    :return:\n    \"\"\"\n    url = '%2Fblog%2Flist%2F'\n    print secure_url(url)\n\n\nif __name__ == '__main__':\n    test()\n"
  },
  {
    "path": "app_frontend/views/__init__.py",
    "content": "#!/usr/bin/env python\n# encoding: utf-8\n\n\"\"\"\n@author: zhanghe\n@software: PyCharm\n@file: __init__.py.py\n@time: 2017/3/10 下午10:56\n\"\"\"\n\n\nimport os\nfrom datetime import datetime\n\nfrom flask import render_template, request, redirect\nfrom flask import send_from_directory, g, flash, url_for, session\nfrom flask_login import current_user, user_logged_in, user_loaded_from_cookie\nfrom itsdangerous import URLSafeSerializer, BadSignature\n\nfrom app_common.tools.ip import get_real_ip\nfrom app_frontend import app, login_manager\nfrom app_frontend.api.user import edit_user\nfrom app_frontend.tools.db import get_row_by_id\n\n# cache = SimpleCache()  # 默认最大支持500个key, 超时时间5分钟, 参数可配置\n\n\n@login_manager.user_loader\ndef load_user(user_id):\n    \"\"\"\n    如果 user_id 无效，它应该返回 None （ 而不是抛出异常 ）。\n    :param user_id:\n    :return:\n    \"\"\"\n    from app_frontend.login import LoginUser\n    # return LoginUser.query.get(int(user_id))\n    return get_row_by_id(LoginUser, int(user_id))\n\n\n# @app.before_request\n# def before_request():\n#     \"\"\"\n#     当前用户信息\n#     \"\"\"\n#     g.user = current_user\n#     return '系统维护中'\n\n\n@user_logged_in.connect_via(app)\n@user_loaded_from_cookie.connect_via(app)\ndef _track_login_s(sender, user, **extra):\n    \"\"\"\n    通过信号处理登录日志\n    :param sender:\n    :param user:\n    :param extra:\n    :return:\n    \"\"\"\n    # 用户通过验证后，记录登入IP\n    login_info = {\n        'login_ip': get_real_ip(),\n        'login_time': datetime.utcnow()\n    }\n    edit_user(user.id, login_info)\n\n\n@app.route('/favicon.ico')\ndef favicon():\n    \"\"\"\n    首页ico图标\n    \"\"\"\n    from app_frontend import app\n    return send_from_directory(os.path.join(app.root_path, 'static'),\n                               'img/favicon.ico', mimetype='image/vnd.microsoft.icon')\n\n\n@app.route('/index/')\n@app.route('/')\ndef index():\n    \"\"\"\n    网站首页\n    \"\"\"\n    import json\n    # return str(current_user.id)\n    # return \"Hello, World!\"\n    # 判断是否推广链接\n    # i = request.args.get('i', '')\n    # if i:\n    #     try:\n    #         s = URLSafeSerializer(app.config.get('USER_INVITE_LINK_SIGN_KEY', ''))\n    #         link_param = s.loads(i)\n    #         # 如果未登录，或登录用户打开的不是自己的推广链接\n    #         if not current_user.get_id() or current_user.get_id() != link_param.get('user_id'):\n    #             # 跳转注册页面\n    #             session['user_pid'] = link_param.get('user_id')\n    #             return redirect(url_for('reg.index'))\n    #     except BadSignature as e:\n    #         # flash(u'Invite Link Failed, %s' % e.message, 'warning')\n    #         flash(u'邀请注册链接错误，请重新索取链接', 'warning')\n    #     except Exception as e:\n    #         flash(e.message, 'warning')\n    # return render_template('index.html', title='home')\n    return render_template('theme/default/index.html', title='home')\n\n\n@app.route('/about/')\ndef about():\n    \"\"\"\n    关于网站\n    \"\"\"\n    # return \"Hello, World!\\nAbout!\"\n    return render_template('about.html', title='about')\n\n\n@app.route('/contact/')\ndef contact():\n    \"\"\"\n    联系方式\n    \"\"\"\n    # return \"Hello, World!\\nContact!\"\n    return render_template('contact.html', title='contact')\n\n\n@app.route('/search/', methods=['GET', 'POST'])\ndef search():\n    \"\"\"\n    搜索\n    \"\"\"\n    return 'search result!'\n\n\n@app.errorhandler(404)\ndef page_not_found(error):\n    return render_template('404.html'), 404\n\n\n@app.errorhandler(500)\ndef internal_error(error):\n    from app_frontend.database import db\n    db.session.rollback()\n    return render_template('500.html'), 500\n\n\n@app.errorhandler(413)\ndef request_entity_too_large(error):\n    return '文件超出大小限制', 413\n"
  },
  {
    "path": "app_frontend/views/active.py",
    "content": "#!/usr/bin/env python\n# encoding: utf-8\n\n\"\"\"\n@author: zhanghe\n@software: PyCharm\n@file: active.py\n@time: 2017/5/31 下午11:06\n\"\"\"\n\n\nfrom datetime import datetime\nfrom flask import redirect\nfrom flask import render_template, request, flash, g\nfrom flask import url_for\nfrom flask_login import current_user, login_required\nfrom sqlalchemy.orm import aliased\n\nfrom app_frontend import app\nfrom app_frontend.api.active import give_active\nfrom app_frontend.api.user_profile import get_team_tree\nfrom app_frontend.api.user_profile import get_user_id_by_name\nfrom app_frontend.models import User, UserProfile, ActiveItem\nfrom app_frontend.api.active_item import get_active_item_rows\nfrom app_common.maps.type_active import *\nfrom app_frontend.forms.active import ActiveAddForm\nfrom app_frontend.database import db\n\nfrom flask import Blueprint\n\nPER_PAGE_FRONTEND = app.config['PER_PAGE_FRONTEND']\n\n\nbp_active = Blueprint('active', __name__, url_prefix='/active')\n\n\n@bp_active.route('/list/')\n@bp_active.route('/list/<int:page>/')\n@login_required\ndef lists(page=1):\n    \"\"\"\n    激活列表\n    \"\"\"\n    user_id = current_user.id\n\n    # 赠送、接收 状态\n    active_status = request.args.get('active_status', 0, type=int)\n\n    # 多次连接同一张表，需要别名\n    user_profile_put = aliased(UserProfile)\n    user_profile_get = aliased(UserProfile)\n\n    # 接收\n    if active_status == 1:\n        condition = {\n            'sc_id': user_id,\n        }\n    # 赠送、激活\n    else:\n        condition = {\n            'user_id': user_id\n        }\n    try:\n        pagination = ActiveItem.query. \\\n            filter_by(**condition). \\\n            outerjoin(user_profile_put, ActiveItem.user_id == user_profile_put.user_id). \\\n            add_entity(user_profile_put). \\\n            outerjoin(user_profile_get, ActiveItem.sc_id == user_profile_get.user_id). \\\n            add_entity(user_profile_get). \\\n            order_by(ActiveItem.id.desc()). \\\n            paginate(page, PER_PAGE_FRONTEND, False)\n\n        # pagination = get_active_item_rows(page, PER_PAGE_FRONTEND, **condition)\n        db.session.commit()\n        return render_template('active/list.html', title='active_list', pagination=pagination)\n    except Exception as e:\n        db.session.rollback()\n        flash(e.message, category='warning')\n        return redirect(url_for('index'))\n\n\n@bp_active.route('/add/', methods=['GET', 'POST'])\n@login_required\ndef add():\n    \"\"\"\n    添加激活记录\n    :return:\n    \"\"\"\n    # 获取团队成员三级树形结构\n    team_tree = get_team_tree(current_user.id)\n\n    user_name = request.args.get('user_name', '')\n\n    form = ActiveAddForm(request.form)\n\n    # 初始化表单的值\n    if user_name:\n        form.user_name.data = user_name\n    if not form.amount.data:\n        form.amount.data = 1\n\n    if request.method == 'POST':\n        if form.validate_on_submit():\n            # 赠送激活数量\n            try:\n                user_id = get_user_id_by_name(form.user_name.data)\n                result = give_active(current_user.id, user_id, form.amount.data)\n                if result:\n                    flash(u'赠送激活数量操作成功', 'success')\n                return redirect(url_for('.lists'))\n            except Exception as e:\n                flash(e.message or u'赠送激活数量操作失败', 'warning')\n        # 闪现消息 success info warning danger\n        # flash(form.errors, 'warning')  # 调试打开\n    return render_template('active/add.html', title='active_add', form=form, team_tree=team_tree)\n\n\n@bp_active.route('/del/', methods=['GET', 'POST'])\n@login_required\ndef delete():\n    \"\"\"\n    删除激活\n    :return:\n    \"\"\"\n    pass\n\n\n@bp_active.route('/stats/', methods=['GET', 'POST'])\n@login_required\ndef stats():\n    \"\"\"\n    激活统计\n    :return:\n    \"\"\"\n    pass\n"
  },
  {
    "path": "app_frontend/views/apply.py",
    "content": "#!/usr/bin/env python\n# encoding: utf-8\n\n\"\"\"\n@author: zhanghe\n@software: PyCharm\n@file: apply.py\n@time: 2017/4/27 上午9:34\n\"\"\"\nimport json\nfrom datetime import datetime\n\nfrom decimal import Decimal\n\nfrom flask import abort\nfrom flask import redirect\nfrom flask import render_template, request, flash, g\nfrom flask import url_for\nfrom flask_login import current_user, login_required\n\nfrom app_frontend import app\nfrom app_frontend.lib.rabbit_mq import RabbitDelayQueue\nfrom app_frontend.models import User, ApplyGet, ApplyPut\nfrom app_frontend.api.apply_get import get_apply_get_rows, get_apply_get_row_by_id, add_apply_get, edit_apply_get, user_apply_get\nfrom app_frontend.api.apply_put import get_apply_put_rows, get_apply_put_row_by_id, add_apply_put, edit_apply_put\nfrom app_frontend.api.user_bank import user_bank_is_complete\nfrom app_frontend.api.user_profile import user_profile_is_complete, get_team_tree\nfrom app_frontend.api.scheduling import get_scheduling_row_by_id, edit_scheduling\nfrom app_frontend.api.scheduling_item import add_scheduling_item\nfrom app_common.maps.status_order import *\nfrom app_common.maps.type_apply import *\nfrom app_common.maps.status_apply import *\nfrom app_common.maps.status_delete import *\nfrom app_common.maps.status_active import *\nfrom app_common.maps.status_audit import *\nfrom app_frontend.forms.apply_get import ApplyGetAddForm\nfrom app_frontend.forms.apply_put import ApplyPutAddForm\nfrom flask import Blueprint\n\nfrom app_frontend.tools.config_manage import get_conf\n\nEXCHANGE_NAME = app.config['EXCHANGE_NAME']\nPER_PAGE_FRONTEND = app.config['PER_PAGE_FRONTEND']\nAPPLY_PUT_INTEREST_ON_PRINCIPAL_TTL = app.config['APPLY_PUT_INTEREST_ON_PRINCIPAL_TTL']\n\n\nbp_apply = Blueprint('apply', __name__, url_prefix='/apply')\n\n\n@bp_apply.route('/put/list/')\n@bp_apply.route('/put/list/<int:page>/')\n@login_required\ndef lists_put(page=1):\n    \"\"\"\n    投资申请列表\n    \"\"\"\n    user_id = current_user.id\n\n    # 判断基本信息和银行信息是否完整\n    if not user_profile_is_complete(user_id):\n        flash(u'请先完善基本信息', 'warning')\n        return redirect(url_for('user.profile'))\n    if not user_profile_is_complete(user_id):\n        flash(u'请先完善银行信息', 'warning')\n        return redirect(url_for('user.bank'))\n        # 判断是否激活\n    if current_user.status_active == int(STATUS_ACTIVE_NO):\n        flash(u'请先激活当前账号', 'warning')\n        return redirect(url_for('user.profile'))\n\n    condition = [\n        ApplyPut.user_id == user_id,\n        ApplyPut.status_delete == int(STATUS_DEL_NO)\n    ]\n    # 订单状态\n    status_order = request.args.get('status_order', 0, type=int)\n    if status_order == int(STATUS_ORDER_COMPLETED):\n        condition.append(ApplyPut.status_order == int(STATUS_ORDER_COMPLETED))\n    else:\n        condition.append(ApplyPut.status_order < int(STATUS_ORDER_COMPLETED))\n\n    pagination = get_apply_put_rows(page, PER_PAGE_FRONTEND, *condition)\n    return render_template('apply/put_list.html', title='apply_put_list', pagination=pagination)\n\n\n@bp_apply.route('/get/list/')\n@bp_apply.route('/get/list/<int:page>/')\n@login_required\ndef lists_get(page=1):\n    \"\"\"\n    提现申请列表\n    \"\"\"\n    user_id = current_user.id\n\n    # 判断基本信息和银行信息是否完整\n    if not user_profile_is_complete(user_id):\n        flash(u'请先完善基本信息', 'warning')\n        return redirect(url_for('user.profile'))\n    if not user_profile_is_complete(user_id):\n        flash(u'请先完善银行信息', 'warning')\n        return redirect(url_for('user.bank'))\n        # 判断是否激活\n    if current_user.status_active == int(STATUS_ACTIVE_NO):\n        flash(u'请先激活当前账号', 'warning')\n        return redirect(url_for('user.profile'))\n\n    condition = [\n        ApplyGet.user_id == user_id,\n        ApplyGet.status_delete == int(STATUS_DEL_NO)\n    ]\n    # 订单状态\n    status_order = request.args.get('status_order', 0, type=int)\n    if status_order == int(STATUS_ORDER_COMPLETED):\n        condition.append(ApplyGet.status_order == int(STATUS_ORDER_COMPLETED))\n    else:\n        condition.append(ApplyGet.status_order < int(STATUS_ORDER_COMPLETED))\n\n    pagination = get_apply_get_rows(page, PER_PAGE_FRONTEND, *condition)\n    return render_template('apply/get_list.html', title='apply_get_list', pagination=pagination)\n\n\n@bp_apply.route('/put/add/', methods=['GET', 'POST'])\n@login_required\ndef add_put():\n    \"\"\"\n    创建投资申请\n    :return:\n    \"\"\"\n    user_id = current_user.id\n\n    # 判断基本信息和银行信息是否完整\n    if not user_profile_is_complete(user_id):\n        flash(u'请先完善基本信息', 'warning')\n        return redirect(url_for('user.profile'))\n    if not user_profile_is_complete(user_id):\n        flash(u'请先完善银行信息', 'warning')\n        return redirect(url_for('user.bank'))\n        # 判断是否激活\n    if current_user.status_active == int(STATUS_ACTIVE_NO):\n        flash(u'请先激活当前账号', 'warning')\n        return redirect(url_for('user.profile'))\n\n    # 获取团队成员三级树形结构\n    team_tree = get_team_tree(current_user.id)\n\n    # 单次投资金额范围\n    APPLY_PUT_MIN_EACH = Decimal(get_conf('APPLY_PUT_MIN_EACH'))  # 最小值\n    APPLY_PUT_MAX_EACH = Decimal(get_conf('APPLY_PUT_MAX_EACH'))  # 最大值\n    APPLY_PUT_STEP = Decimal(get_conf('APPLY_PUT_STEP'))  # 投资金额步长（基数）\n\n    form = ApplyPutAddForm(request.form)\n    if request.method == 'POST':\n        if form.validate_on_submit():\n            current_time = datetime.utcnow()\n\n            # 新增投资申请明细\n            apply_put_info = {\n                'user_id': user_id,\n                'type_apply': TYPE_APPLY_USER,\n                'type_pay': form.type_pay.data,\n                'money_apply': form.money_apply.data,\n                'status_apply': STATUS_APPLY_SUCCESS,\n                'status_order': STATUS_ORDER_HANDING,\n                'status_delete': STATUS_DEL_NO,\n                'create_time': current_time,\n                'update_time': current_time,\n            }\n            apply_put_id = add_apply_put(apply_put_info)\n\n            # 消耗排单币\n            scheduling_cost = form.money_apply.data / 100\n\n            # 扣除排单币总表数量\n            scheduling_info = get_scheduling_row_by_id(user_id)\n\n            amount = scheduling_info.amount if scheduling_info else 0\n\n            scheduling_data = {\n                'amount': amount - scheduling_cost,\n                'create_time': current_time,\n                'update_time': current_time\n            }\n            edit_scheduling(user_id, scheduling_data)\n\n            # 新增排单币明细\n            scheduling_item_data = {\n                'user_id': user_id,\n                'type': user_id,\n                'amount': scheduling_cost,\n                'sc_id': user_id,\n                'note': u'投资申请编号：%s' % apply_put_id,\n                'status_audit': STATUS_AUDIT_SUCCESS,\n                'audit_time': current_time,\n                'create_time': current_time,\n                'update_time': current_time\n            }\n            add_scheduling_item(scheduling_item_data)\n\n            if apply_put_id:\n                # 加入投资申请本息回收队列\n                q = RabbitDelayQueue(\n                    exchange=EXCHANGE_NAME,\n                    queue_name='apply_put_interest_on_principal',\n                    ttl=APPLY_PUT_INTEREST_ON_PRINCIPAL_TTL\n                )\n                msg = {\n                    'user_id': user_id,\n                    'apply_put_id': apply_put_id,\n                    'apply_time': current_time.strftime('%Y-%m-%d %H:%M:%S')\n                }\n                q.put(msg)\n                q.close_conn()\n                flash(u'申请成功', 'success')\n            else:\n                flash(u'申请失败', 'warning')\n            return redirect(url_for('apply.lists_put'))\n    return render_template(\n        'apply/put_add.html',\n        title='apply_put_add',\n        form=form,\n        APPLY_PUT_MIN_EACH=str(APPLY_PUT_MIN_EACH),\n        APPLY_PUT_MAX_EACH=str(APPLY_PUT_MAX_EACH),\n        APPLY_PUT_STEP=str(APPLY_PUT_STEP),\n        team_tree=team_tree\n    )\n\n\n@bp_apply.route('/get/add/', methods=['GET', 'POST'])\n@login_required\ndef add_get():\n    \"\"\"\n    创建提现申请\n    :return:\n    \"\"\"\n    user_id = current_user.id\n\n    # 判断基本信息和银行信息是否完整\n    if not user_profile_is_complete(user_id):\n        flash(u'请先完善基本信息', 'warning')\n        return redirect(url_for('user.profile'))\n    if not user_profile_is_complete(user_id):\n        flash(u'请先完善银行信息', 'warning')\n        return redirect(url_for('user.bank'))\n        # 判断是否激活\n    if current_user.status_active == int(STATUS_ACTIVE_NO):\n        flash(u'请先激活当前账号', 'warning')\n        return redirect(url_for('user.profile'))\n\n    # 获取团队成员三级树形结构\n    team_tree = get_team_tree(current_user.id)\n\n    # 单次提现金额范围\n    APPLY_GET_MIN_EACH = Decimal(get_conf('APPLY_GET_MIN_EACH'))  # 最小值\n    APPLY_GET_MAX_EACH = Decimal(get_conf('APPLY_GET_MAX_EACH'))  # 最大值\n    APPLY_GET_STEP = Decimal(get_conf('APPLY_GET_STEP'))  # 投资金额步长（基数）\n\n    form = ApplyGetAddForm(request.form)\n    if request.method == 'POST':\n        if form.validate_on_submit():\n            type_pay = form.type_pay.data\n            type_withdraw = form.type_withdraw.data\n            money_apply = form.money_apply.data\n            try:\n                result = user_apply_get(user_id, type_pay, type_withdraw, money_apply)\n                if result:\n                    flash(u'申请成功', 'success')\n                    return redirect(url_for('apply.lists_get'))\n            except Exception as e:\n                flash(u'申请失败, 原因：%s' % e.message, 'warning')\n    return render_template(\n        'apply/get_add.html',\n        title='apply_get_add',\n        form=form,\n        APPLY_GET_MIN_EACH=str(APPLY_GET_MIN_EACH),\n        APPLY_GET_MAX_EACH=str(APPLY_GET_MAX_EACH),\n        APPLY_GET_STEP=str(APPLY_GET_STEP),\n        team_tree=team_tree\n    )\n\n\n@bp_apply.route('/ajax/put/del/', methods=['GET', 'POST'])\n@login_required\ndef ajax_delete_put():\n    \"\"\"\n    删除投资申请\n    :return:\n    \"\"\"\n    if request.method == 'GET' and request.is_xhr:\n        apply_put_id = request.args.get('apply_put_id', 0, type=int)\n        if not apply_put_id:\n            return json.dumps({'error': u'删除失败'})\n\n        apply_put_info = get_apply_put_row_by_id(apply_put_id)\n        # 判断权限\n        if apply_put_info.user_id != current_user.id:\n            return json.dumps({'error': u'没有权限，删除失败'})\n        # 判断投资申请是否开始匹配\n        if apply_put_info.status_order != int(STATUS_ORDER_HANDING):\n            return json.dumps({'error': u'投资处理中，不能删除'})\n        current_time = datetime.utcnow()\n        apply_put_data = {\n            'status_delete': STATUS_DEL_OK,\n            'delete_time': current_time,\n            'update_time': current_time\n        }\n        result = edit_apply_put(apply_put_id, apply_put_data)\n        if result:\n            return json.dumps({'success': u'删除成功'})\n        else:\n            return json.dumps({'error': u'删除失败'})\n    abort(404)\n\n\n@bp_apply.route('/ajax/get/del/', methods=['GET', 'POST'])\n@login_required\ndef ajax_delete_get():\n    \"\"\"\n    删除提现申请\n    :return:\n    \"\"\"\n    if request.method == 'GET' and request.is_xhr:\n        apply_get_id = request.args.get('apply_get_id', 0, type=int)\n        if not apply_get_id:\n            return json.dumps({'error': u'删除失败'})\n\n        apply_get_info = get_apply_get_row_by_id(apply_get_id)\n        # 判断权限\n        if apply_get_info.user_id != current_user.id:\n            return json.dumps({'error': u'没有权限，删除失败'})\n        # 判断提现申请是否开始匹配\n        if apply_get_info.status_order != int(STATUS_ORDER_HANDING):\n            return json.dumps({'error': u'提现处理中，不能删除'})\n        current_time = datetime.utcnow()\n        apply_get_data = {\n            'status_delete': STATUS_DEL_OK,\n            'delete_time': current_time,\n            'update_time': current_time\n        }\n        result = edit_apply_get(apply_get_id, apply_get_data)\n        if result:\n            return json.dumps({'success': u'删除成功'})\n        else:\n            return json.dumps({'error': u'删除失败'})\n    abort(404)\n\n\n@bp_apply.route('/put/stats/', methods=['GET', 'POST'])\n@login_required\ndef stats_put():\n    \"\"\"\n    投资申请统计\n    :return:\n    \"\"\"\n    pass\n\n\n@bp_apply.route('/get/stats/', methods=['GET', 'POST'])\n@login_required\ndef stats_get():\n    \"\"\"\n    提现申请统计\n    :return:\n    \"\"\"\n    pass\n"
  },
  {
    "path": "app_frontend/views/auth.py",
    "content": "#!/usr/bin/env python\n# encoding: utf-8\n\n\"\"\"\n@author: zhanghe\n@software: PyCharm\n@file: auth.py\n@time: 2017/3/10 下午11:44\n\"\"\"\n\nimport json\nfrom datetime import datetime\n\nfrom flask import Blueprint\nfrom flask import g, request, render_template, jsonify\nfrom flask import session, redirect, url_for, flash\nfrom flask_login import login_user\nfrom flask_login import logout_user\nfrom flask_login import current_user\nfrom itsdangerous import TimestampSigner, SignatureExpired, BadTimeSignature\n\nfrom app_common.maps import area_code_map\nfrom app_common.maps.type_auth import *\nfrom app_common.tools import md5\nfrom app_common.tools.ip import get_real_ip\nfrom app_frontend import app, oauth_github, oauth_qq, oauth_weibo\nfrom app_frontend.api.user import edit_user\nfrom app_frontend.api.user import get_user_row_by_id\nfrom app_frontend.api.user_auth import get_user_auth_row\nfrom app_frontend.forms.login import LoginPhoneForm\nfrom app_frontend.forms.login import LoginForm\n\n\nSWITCH_LOGIN_ACCOUNT = app.config['SWITCH_LOGIN_ACCOUNT']\nSWITCH_LOGIN_PHONE = app.config['SWITCH_LOGIN_PHONE']\nSWITCH_LOGIN_EMAIL = app.config['SWITCH_LOGIN_EMAIL']\n\nSWITCH_LOGIN_THREE_PART = app.config['SWITCH_LOGIN_THREE_PART']\n\nbp_auth = Blueprint('auth', __name__, url_prefix='/auth')\n\n\n@bp_auth.route('/index/', methods=['GET', 'POST'])\ndef index():\n    \"\"\"\n    账号登录认证\n    \"\"\"\n    if current_user and current_user.is_authenticated:\n        return redirect(url_for('index'))\n    if not SWITCH_LOGIN_ACCOUNT:\n        flash(u'账号登录功能关闭，暂不支持账号登录', 'warning')\n        return redirect(url_for('index'))\n    form = LoginForm()\n    if request.method == 'POST':\n        if form.validate_on_submit():\n            # 获取认证信息\n            condition = {\n                'type_auth': TYPE_AUTH_ACCOUNT,\n                'auth_key': form.account.data,\n                'auth_secret': md5(form.password.data)\n            }\n            user_auth_info = get_user_auth_row(**condition)\n            if user_auth_info is None:\n                flash(u'%s, 登录失败，请检查内容后重新登录' % form.account.data, 'warning')\n                return render_template('auth/index.html', title='login', form=form)\n            if user_auth_info.status_verified == 0:\n                flash(u'%s, 登录账号尚未验证，请先验证账号' % form.account.data, 'warning')\n                return render_template('auth/index.html', title='login', form=form)\n            # session['logged_in'] = True\n\n            # 用 login_user 函数来登入他们\n            login_user(get_user_row_by_id(user_auth_info.user_id), remember=form.remember.data)\n            flash(u'%s, 恭喜，您已成功登录' % form.account.data, 'success')\n            return redirect(request.args.get('next') or url_for('index'))\n        # flash(form.errors, 'warning')  # 调试打开\n    return render_template('auth/index.html', title='login', form=form, SWITCH_LOGIN_THREE_PART=SWITCH_LOGIN_THREE_PART)\n\n\n@bp_auth.route('/phone/', methods=['GET', 'POST'])\ndef phone():\n    \"\"\"\n    手机登录认证\n    \"\"\"\n    if current_user and current_user.is_authenticated:\n        return redirect(url_for('index'))\n    if not SWITCH_LOGIN_PHONE:\n        flash(u'手机登录功能关闭，暂不支持手机登录', 'warning')\n        return redirect(url_for('index'))\n    form = LoginPhoneForm()\n    if request.method == 'POST':\n        if form.validate_on_submit():\n            # 手机号码国际化\n            area_id = form.area_id.data\n            area_code = area_code_map.get(area_id, '86')\n            mobile_iso = '%s%s' % (area_code, form.phone.data)\n            # 获取认证信息\n            condition = {\n                'type_auth': TYPE_AUTH_PHONE,\n                'auth_key': mobile_iso,\n                'auth_secret': md5(form.password.data)\n            }\n            user_auth_info = get_user_auth_row(**condition)\n            if not user_auth_info:\n                flash(u'%s, 登录失败，请检查内容后重新登录' % form.phone.data, 'warning')\n                return render_template('auth/phone.html', title='login', form=form)\n            if user_auth_info.status_verified == 0:\n                flash(u'%s, 登录手机尚未验证，请先验证手机' % form.phone.data, 'warning')\n                return render_template('auth/phone.html', title='login', form=form)\n            # session['logged_in'] = True\n\n            # 用 login_user 函数来登入他们\n            login_user(get_user_row_by_id(user_auth_info.user_id), remember=form.remember.data)\n            flash(u'%s, 恭喜，您已成功登录' % form.phone.data, 'success')\n            return redirect(request.args.get('next') or url_for('index'))\n        # flash(form.errors, 'warning')  # 调试打开\n    return render_template('auth/phone.html', title='login', form=form, SWITCH_LOGIN_THREE_PART=SWITCH_LOGIN_THREE_PART)\n\n\n@bp_auth.route('/email/', methods=['GET', 'POST'])\ndef email():\n    \"\"\"\n    邮箱登录认证\n    \"\"\"\n    if current_user and current_user.is_authenticated:\n        return redirect(url_for('index'))\n    if not SWITCH_LOGIN_EMAIL:\n        flash(u'邮箱登录功能关闭，暂不支持邮箱登录', 'warning')\n        return redirect(url_for('index'))\n    from app_frontend.forms.login import LoginEmailForm\n    form = LoginEmailForm()\n    if request.method == 'POST':\n        if form.validate_on_submit():\n            # 获取认证信息\n            condition = {\n                'type_auth': TYPE_AUTH_EMAIL,\n                'auth_key': form.email.data,\n                'auth_secret': md5(form.password.data)\n            }\n            user_auth_info = get_user_auth_row(**condition)\n            if user_auth_info is None:\n                flash(u'%s, 登录失败，请检查内容后重新登录' % form.email.data, 'warning')\n                return render_template('auth/email.html', title='login', form=form)\n            if user_auth_info.status_verified == 0:\n                flash(u'%s, 登录邮箱尚未验证，请先验证邮箱' % form.email.data, 'warning')\n                return render_template('auth/email.html', title='login', form=form)\n            # session['logged_in'] = True\n\n            # 用 login_user 函数来登入他们\n            login_user(get_user_row_by_id(user_auth_info.user_id), remember=form.remember.data)\n            flash(u'%s, 恭喜，您已成功登录' % form.email.data, 'success')\n            return redirect(request.args.get('next') or url_for('index'))\n        # flash(form.errors, 'warning')  # 调试打开\n    return render_template('auth/email.html', title='login', form=form, SWITCH_LOGIN_THREE_PART=SWITCH_LOGIN_THREE_PART)\n\n\n# @app.route('/logout')\n# def logout():\n#     session.pop('logged_in', None)\n#     flash(u'You were logged out')\n#     return redirect(url_for('index'))\n\n\n@bp_auth.route('/logout/')\ndef logout():\n    \"\"\"\n    退出登录\n    \"\"\"\n    logout_user()\n    session.pop('qq_token', None)\n    session.pop('weibo_token', None)\n    session.pop('github_token', None)\n    flash(u'您已成功退出登录', 'info')\n    return redirect(url_for('index'))\n\n\n# # 第三方登录（QQ）\ndef json_to_dict(x):\n    \"\"\"\n    OAuthResponse class can't not parse the JSON data with content-type\n    text/html, so we need reload the JSON data manually\n    :param x:\n    :return:\n    \"\"\"\n    if x.find('callback') > -1:\n        pos_lb = x.find('{')\n        pos_rb = x.find('}')\n        x = x[pos_lb:pos_rb + 1]\n    try:\n        return json.loads(x, encoding='utf-8')\n    except:\n        return x\n\n\ndef update_qq_api_request_data(data={}):\n    \"\"\"\n    Update some required parameters for OAuth2.0 API calls\n    :param data:\n    :return:\n    \"\"\"\n    defaults = {\n        'openid': session.get('qq_openid'),\n        'access_token': session.get('qq_token')[0],\n        'oauth_consumer_key': app.config['consumer_key'],\n    }\n    defaults.update(data)\n    return defaults\n\n\n@bp_auth.route('/user_info')\ndef get_user_info():\n    if 'qq_token' in session:\n        data = update_qq_api_request_data()\n        resp = oauth_qq.get('/user/get_user_info', data=data)\n        return jsonify(status=resp.status, data=resp.data)\n    return redirect(url_for('login_qq'))\n\n\n@bp_auth.route('/login/qq/')\ndef login_qq():\n    return oauth_qq.authorize(callback=url_for('auth.authorized_qq', _external=True))\n\n\n@bp_auth.route('/login/authorized/qq/')\ndef authorized_qq():\n    resp = oauth_qq.authorized_response()\n    if resp is None:\n        return 'Access denied: reason=%s error=%s' % (\n            request.args['error_reason'],\n            request.args['error_description']\n        )\n    session['qq_token'] = (resp['access_token'], '')\n\n    # Get openid via access_token, openid and access_token are needed for API calls\n    resp = oauth_qq.get('/oauth2.0/me', {'access_token': session['qq_token'][0]})\n    resp = json_to_dict(resp.data)\n    if isinstance(resp, dict):\n        session['qq_openid'] = resp.get('openid')\n\n    return redirect(url_for('get_user_info'))\n\n\n@oauth_qq.tokengetter\ndef get_qq_oauth_token():\n    return session.get('qq_token')\n\n\n# 第三方登录（WeiBo）\n# @app.route('/')\n# def index():\n#     if 'oauth_token' in session:\n#         access_token = session['oauth_token'][0]\n#         resp = weibo.get('statuses/home_timeline.json')\n#         return jsonify(resp.data)\n#     return redirect(url_for('auth.index'))\n\n\n@bp_auth.route('/login/weibo/')\ndef login_weibo():\n    return oauth_weibo.authorize(callback=url_for('auth.authorized_weibo',\n                                                  next=request.args.get('next') or request.referrer or None,\n                                                  _external=True))\n\n\n@bp_auth.route('/login/authorized/weibo/')\ndef authorized_weibo():\n    resp = oauth_weibo.authorized_response()\n    if resp is None:\n        return 'Access denied: reason=%s error=%s' % (\n            request.args['error_reason'],\n            request.args['error_description']\n        )\n    session['oauth_token'] = (resp['access_token'], '')\n    return redirect(url_for('index'))\n\n\n@oauth_weibo.tokengetter\ndef get_weibo_oauth_token():\n    return session.get('oauth_token')\n\n\ndef change_weibo_header(uri, headers, body):\n    \"\"\"Since weibo is a rubbish server, it does not follow the standard,\n    we need to change the authorization header for it.\"\"\"\n    auth = headers.get('Authorization')\n    if auth:\n        auth = auth.replace('Bearer', 'OAuth2')\n        headers['Authorization'] = auth\n    return uri, headers, body\n\n\noauth_weibo.pre_request = change_weibo_header\n\n\n# 第三方登录（GitHub）\n@bp_auth.route('/login/github/')\ndef login_github():\n    return oauth_github.authorize(callback=url_for('auth.authorized_github', _external=True))\n\n\n@bp_auth.route('/login/authorized/github/')\ndef authorized_github():\n    resp = oauth_github.authorized_response()\n    if resp is None:\n        return 'Access denied: reason=%s error=%s' % (\n            request.args['error'],\n            request.args['error_description']\n        )\n    session['github_token'] = (resp['access_token'], '')\n    me = oauth_github.get('user')\n    return jsonify(me.data)\n\n\n@oauth_github.tokengetter\ndef get_github_oauth_token():\n    return session.get('github_token')\n\n\n@bp_auth.route('/admin_login/', methods=['GET', 'POST'])\ndef admin_login():\n    \"\"\"\n    管理后台登录前台账号认证\n    \"\"\"\n    # 获取签名的uid\n    uid_sign = request.args.get('uid_sign', '', type=str)\n\n    time_out = app.config.get('ADMIN_TO_USER_LOGIN_TIME_OUT')\n    sign_key = app.config.get('ADMIN_TO_USER_LOGIN_SIGN_KEY')\n    s = TimestampSigner(sign_key)\n    try:\n        # 签名解密\n        uid = s.unsign(uid_sign, max_age=time_out)\n    except SignatureExpired as e:\n        # 处理签名超时\n        # raise Exception(e.message)\n        flash(u'登录超时：%s' % e.message, 'warning')\n        return redirect(request.args.get('next') or url_for('index'))\n    except BadTimeSignature as e:\n        # 处理签名错误\n        # raise Exception(e.message)\n        flash(u'登录错误：%s' % e.message, 'warning')\n        return redirect(request.args.get('next') or url_for('index'))\n\n    # 获取认证信息\n    condition = {\n        'type_auth': TYPE_AUTH_ACCOUNT,\n        'user_id': uid\n    }\n    user_auth_info = get_user_auth_row(**condition)\n    if user_auth_info is None:\n        flash(u'登录失败，请检查内容后重新登录', 'warning')\n        return redirect(request.args.get('next') or url_for('index'))\n    if user_auth_info.status_verified == 0:\n        flash(u'%s, 登录账号尚未验证，请先验证账号' % user_auth_info.auth_key, 'warning')\n        return redirect(request.args.get('next') or url_for('index'))\n\n    login_user(get_user_row_by_id(uid))\n    flash(u'%s, 恭喜，您已成功登录' % user_auth_info.auth_key, 'success')\n    return redirect(request.args.get('next') or url_for('index'))\n"
  },
  {
    "path": "app_frontend/views/bit_coin.py",
    "content": "#!/usr/bin/env python\n# encoding: utf-8\n\n\"\"\"\n@author: zhanghe\n@software: PyCharm\n@file: bit_coin.py\n@time: 2017/4/25 下午1:25\n\"\"\"\n\n\nfrom datetime import datetime\nfrom flask import redirect\nfrom flask import render_template, request, flash, g\nfrom flask import url_for\nfrom flask_login import current_user, login_required\n\nfrom app_frontend import app\nfrom app_frontend.models import User\nfrom app_frontend.api.bit_coin import get_bit_coin_rows\nfrom app_frontend.api.bit_coin_item import get_bit_coin_item_rows\n\nPER_PAGE_FRONTEND = app.config['PER_PAGE_FRONTEND']\n\nfrom flask import Blueprint\n\n\nbp_bit_coin = Blueprint('bit_coin', __name__, url_prefix='/bit_coin')\n\n\n@bp_bit_coin.route('/list/')\n@bp_bit_coin.route('/list/<int:page>/')\n@login_required\ndef lists(page=1):\n    \"\"\"\n    数字货币列表\n    \"\"\"\n    pagination = get_bit_coin_item_rows(page, PER_PAGE_FRONTEND, **{'user_id': current_user.id})\n    return render_template('bit_coin/list.html', title='bit_coin_list', pagination=pagination)\n\n\n@bp_bit_coin.route('/add/', methods=['GET', 'POST'])\n@login_required\ndef add():\n    \"\"\"\n    创建数字货币\n    :return:\n    \"\"\"\n    pass\n\n\n@bp_bit_coin.route('/del/', methods=['GET', 'POST'])\n@login_required\ndef delete():\n    \"\"\"\n    删除数字货币\n    :return:\n    \"\"\"\n    pass\n\n\n@bp_bit_coin.route('/stats/', methods=['GET', 'POST'])\n@login_required\ndef stats():\n    \"\"\"\n    数字货币统计\n    :return:\n    \"\"\"\n    pass\n"
  },
  {
    "path": "app_frontend/views/blog.py",
    "content": "#!/usr/bin/env python\n# encoding: utf-8\n\n\"\"\"\n@author: zhanghe\n@software: PyCharm\n@file: blog.py\n@time: 2017/3/10 下午10:59\n\"\"\"\n\nimport json\nimport logging\nfrom datetime import datetime\n\nfrom flask import request, render_template, redirect, url_for, g, abort, flash, jsonify\nfrom flask_login import current_user, login_required\n\nfrom app_frontend import app\n\nfrom flask import Blueprint\n\n\nbp_blog = Blueprint('blog', __name__, url_prefix='/blog')\n\nlog = logging.getLogger(__name__)\n\n\n@bp_blog.route('/index/')\n@bp_blog.route('/index/<int:page>/')\ndef index(page=1):\n    \"\"\"\n    博客列表\n    \"\"\"\n    # return \"Hello, World!\\nBlog List!\"\n    from app_frontend.api.blog import get_blog_rows\n    per_page = 8\n    pagination = get_blog_rows(page, per_page)\n    return render_template('blog/index.html', title='blog_list', pagination=pagination)\n\n\n@bp_blog.route('/list_edit/')\n@bp_blog.route('/list_edit/<int:page>/')\n@login_required\ndef list_edit(page=1):\n    \"\"\"\n    博客列表(带编辑)\n    \"\"\"\n    # return \"Hello, World!\\nBlog List!\"\n    from app_frontend.api.blog import get_blog_rows\n    per_page = 8\n    pagination = get_blog_rows(page, per_page)\n    return render_template('blog/list_edit.html', title='blog_list', pagination=pagination)\n\n\n@bp_blog.route('/ajax/list_edit/', methods=['GET', 'POST'])\n@login_required\ndef ajax_list_edit():\n    \"\"\"\n    博客编辑\n    \"\"\"\n    if request.method == 'POST' and request.is_xhr:\n        form = request.form\n\n        blog_id = form.get('id', 0, type=int)\n        blog_info = {\n            'author': form.get('author'),\n            'title': form.get('title'),\n            'pub_date': datetime.strptime(form.get('pub_date'), \"%Y-%m-%d\").date(),\n            'edit_time': datetime.utcnow(),\n        }\n        from app_frontend.api.blog import edit_blog\n        result = edit_blog(blog_id, blog_info)\n        if result == 1:\n            return json.dumps({'success': u'Edit Success'})\n        if result == 0:\n            return json.dumps({'error': u'Edit Error'})\n    abort(404)\n\n\n@bp_blog.route('/new/')\n@bp_blog.route('/new/<int:page>/')\ndef new(page=1):\n    \"\"\"\n    最新博客\n    \"\"\"\n    # return \"Hello, World!\\nBlog New!\"\n    from app_frontend.api.blog import get_blog_rows\n    per_page = 8\n    pagination = get_blog_rows(page, per_page)\n    id_list = [item.id for item in pagination.items]\n    from app_frontend.api.blog import get_blog_list_counter\n    blog_counter_list = get_blog_list_counter(id_list)\n    # 状态设置\n    login_user_id = current_user.get_id()\n    from app_frontend.api.blog import get_blog_list_container_status\n    blog_container_status_list = get_blog_list_container_status(id_list, login_user_id)\n    return render_template(\n        'blog/new.html',\n        title='blog_new',\n        pagination=pagination,\n        blog_counter_list=blog_counter_list,\n        blog_container_status_list=blog_container_status_list\n    )\n\n\n@bp_blog.route('/hot/')\n@bp_blog.route('/hot/<int:page>/')\ndef hot(page=1):\n    \"\"\"\n    热门博客\n    \"\"\"\n    # return \"Hello, World!\\nBlog Hot!\"\n    from app_frontend.api.blog import get_blog_rows\n    per_page = 8\n    pagination = get_blog_rows(page, per_page)\n    return render_template('blog/hot.html', title='blog_hot', pagination=pagination)\n\n\n@bp_blog.route('/edit/<int:blog_id>/', methods=['GET', 'POST'])\n@login_required\ndef edit(blog_id):\n    \"\"\"\n    博客编辑\n    \"\"\"\n    # return \"Hello, World!\\nBlog Edit!\"\n    from app_frontend.forms.blog import BlogEditForm\n    form = BlogEditForm(request.form)\n    if request.method == 'GET':\n        from app_frontend.api.blog import get_blog_row_by_id\n        blog_info = get_blog_row_by_id(blog_id)\n        if blog_info:\n            form.author.data = blog_info.author\n            form.title.data = blog_info.title\n            form.pub_date.data = blog_info.pub_date\n        else:\n            return redirect(url_for('index'))\n    if request.method == 'POST':\n        if form.validate_on_submit():\n            blog_info = {\n                'author': form.author.data,\n                'title': form.title.data,\n                'pub_date': form.pub_date.data,\n                'edit_time': datetime.utcnow(),\n            }\n            from app_frontend.api.blog import edit_blog\n            result = edit_blog(blog_id, blog_info)\n            if result == 1:\n                flash(u'Edit Success', 'success')\n                return redirect(request.args.get('next') or url_for('blog.index'))\n            if result == 0:\n                flash(u'Edit Failed', 'warning')\n        flash(form.errors, 'warning')  # 调试打开\n    flash(u'Hello, %s' % current_user.email, 'info')  # 测试打开\n    return render_template('blog/edit.html', title='blog_edit', blog_id=blog_id, form=form)\n\n\n@bp_blog.route('/add/', methods=['GET', 'POST'])\n@login_required\ndef add():\n    \"\"\"\n    博客添加\n    \"\"\"\n    # return \"Hello, World!\\nBlog Add!\"\n    from app_frontend.forms.blog import BlogAddForm\n    form = BlogAddForm(request.form)\n    if request.method == 'POST':\n        if form.validate_on_submit():\n\n            current_time = datetime.utcnow()\n            blog_info = {\n                'author': form.author.data,\n                'title': form.title.data,\n                'pub_date': form.pub_date.data,\n                'add_time': current_time,\n                'edit_time': current_time,\n            }\n            from app_frontend.api.blog import add_blog\n            result = add_blog(blog_info)\n            if result is None:\n                flash(u'Add Failed', 'warning')\n            else:\n                flash(u'Add Success', 'success')\n                return redirect(url_for('blog.edit', blog_id=result))\n        flash(form.errors, 'warning')  # 调试打开\n    # flash(u'Hello, %s' % current_user.email, 'info')  # 测试打开\n    return render_template('blog/add.html', title='blog_add', form=form)\n\n\n@bp_blog.route('/del/', methods=['GET', 'POST'])\ndef delete():\n    \"\"\"\n    博客删除\n    \"\"\"\n    if request.method == 'GET':\n        login_user_id = current_user.get_id()\n        # 权限判断，只能删除自己的 blog todo\n        if login_user_id is None:\n            return jsonify(result=False)\n        blog_id = request.args.get('blog_id', 0, type=int)\n        from app_frontend.api.blog import delete_blog\n        result = delete_blog(blog_id)\n        if result == 1:\n            return jsonify(result=True)\n        else:\n            return jsonify(result=False)\n\n\n@bp_blog.route('/stat/', methods=['GET', 'POST'])\ndef stat():\n    \"\"\"\n    博客统计\n    http://localhost:5000/blog/stat/?blog_id=2&stat_type=favor&num=2\n    :return:\n    \"\"\"\n    if request.method == 'GET':\n        login_user_id = current_user.get_id()\n        if login_user_id is None:\n            return jsonify(result=False)\n        blog_id = request.args.get('blog_id', 0, type=int)\n        stat_type = request.args.get('stat_type', '', type=str)\n        # num = request.args.get('num', 0, type=int)\n        from app_frontend.tools.stat import set_blog_stat\n        result = set_blog_stat(stat_type, login_user_id, blog_id)\n        return jsonify(result)\n"
  },
  {
    "path": "app_frontend/views/captcha.py",
    "content": "#!/usr/bin/env python\n# encoding: utf-8\n\n\"\"\"\n@author: zhanghe\n@software: PyCharm\n@file: captcha.py\n@time: 16-6-10 上午1:01\n\"\"\"\n\n\nfrom flask import Blueprint, request, make_response, session, abort\nimport StringIO\nimport json\nfrom app_frontend.lib.captcha import Captcha\nfrom app_frontend import app\n\n\nbp_captcha = Blueprint('captcha', __name__, url_prefix='/captcha')\n\nparams = {\n    'size': (68, 34),\n    'fg_color': (180, 180, 180),\n    'line_color': (100, 100, 100),\n    'point_color': (100, 100, 100)\n}\n# captcha_client = Captcha(**params)\n\n\n@bp_captcha.route('/get_code/<code_type>/')\ndef get_code(code_type):\n    \"\"\"\n    http://localhost:8000/captcha/get_code/reg/?t=1234\n    \"\"\"\n    if code_type not in app.config['CAPTCHA_ENTITY']:\n        abort(404)\n    code_img, code_str = Captcha(**params).get()\n    # 保存 code_str\n    code_key = '%s:%s' % ('code_str', code_type)\n    session[code_key] = code_str\n    # 返回验证码图片\n    buf = StringIO.StringIO()\n    code_img.save(buf, 'JPEG', quality=70)\n    buf_str = buf.getvalue()\n    response = make_response(buf_str)\n    response.headers['Content-Type'] = 'image/jpeg'\n    code_img.close()\n    buf.close()\n    return response\n\n\n@bp_captcha.route('/check_code/<code_type>/')\ndef check_code(code_type):\n    \"\"\"\n    校验验证码\n    http://localhost:8000/captcha/check_code/reg/?code_str=7E6G\n    \"\"\"\n    if code_type not in app.config['CAPTCHA_ENTITY']:\n        abort(404)\n    code_str = request.args.get('code_str', '', type=str)\n    code_key = '%s:%s' % ('code_str', code_type)\n    return json.dumps({'result': code_str.upper() == session[code_key].upper()})\n\n"
  },
  {
    "path": "app_frontend/views/complaint.py",
    "content": "#!/usr/bin/env python\n# encoding: utf-8\n\n\"\"\"\n@author: zhanghe\n@software: PyCharm\n@file: complaint.py\n@time: 2017/4/29 下午2:28\n\"\"\"\n\n\nfrom datetime import datetime\nfrom flask import redirect\nfrom flask import render_template, request, flash, g\nfrom flask import url_for\nfrom flask_login import current_user, login_required\nimport flask_excel as excel\nfrom sqlalchemy.orm import aliased\n\nfrom app_frontend import app\nfrom app_frontend.database import db\nfrom app_frontend.forms.complaint import ComplaintAddForm\nfrom app_frontend.models import User, UserProfile, Complaint\nfrom app_frontend.api.complaint import get_complaint_rows, get_complaint_row, add_complaint\nfrom app_common.maps.status_reply import STATUS_REPLY_DICT\n\n\nfrom flask import Blueprint\n\nPER_PAGE_FRONTEND = app.config['PER_PAGE_FRONTEND']\n\nbp_complaint = Blueprint('complaint', __name__, url_prefix='/complaint')\n\n\n@bp_complaint.route('/list/')\n@bp_complaint.route('/list/<int:page>/')\n@login_required\ndef lists(page=1):\n    \"\"\"\n    投诉列表\n    \"\"\"\n    user_id = current_user.id\n    condition = {\n        'send_user_id': user_id,\n        'status_reply': 0,  # 默认未处理\n        'status_delete': 0\n    }\n    # 回复状态\n    status_reply = request.args.get('status_reply', 0, type=int)\n    if status_reply in STATUS_REPLY_DICT:\n        condition['status_reply'] = status_reply\n\n    # pagination = get_complaint_rows(page, **condition)\n    # return render_template('complaint/list.html', title='complaint_list', pagination=pagination)\n\n    # 多次连接同一张表，需要别名\n    user_profile_put = aliased(UserProfile)\n    user_profile_get = aliased(UserProfile)\n    try:\n        pagination = Complaint.query. \\\n            filter_by(**condition). \\\n            outerjoin(user_profile_put, Complaint.send_user_id == user_profile_put.user_id). \\\n            add_entity(user_profile_put). \\\n            outerjoin(user_profile_get, Complaint.receive_user_id == user_profile_get.user_id). \\\n            add_entity(user_profile_get). \\\n            order_by(Complaint.id.desc()). \\\n            paginate(page, PER_PAGE_FRONTEND, False)\n        db.session.commit()\n        return render_template('complaint/list.html', title='complaint_list', pagination=pagination)\n    except Exception as e:\n        db.session.rollback()\n        flash(e.message, category='warning')\n        return redirect(url_for('index'))\n\n\n@bp_complaint.route('/add/', methods=['GET', 'POST'])\n@login_required\ndef add():\n    \"\"\"\n    创建投诉\n    :return:\n    \"\"\"\n    form = ComplaintAddForm(request.form)\n    user_id = request.args.get('user_id')\n    form.user_id.data = user_id\n    if request.method == 'POST':\n        if form.validate_on_submit():\n            current_time = datetime.utcnow()\n            complaint_data = {\n                'send_user_id': current_user.id,\n                'receive_user_id': user_id,\n                'content': form.content.data,\n                'create_time': current_time,\n                'update_time': current_time,\n            }\n            result = add_complaint(complaint_data)\n            if result:\n                flash(u'投诉成功', 'success')\n                return redirect(url_for('.lists', msg_type='send'))\n            else:\n                flash(u'投诉失败', 'warning')\n        flash(u'投诉失败', 'warning')\n    return render_template('complaint/add.html', title='complaint_add', form=form)\n\n\n@bp_complaint.route('/del/', methods=['GET', 'POST'])\n@login_required\ndef delete():\n    \"\"\"\n    删除投诉\n    :return:\n    \"\"\"\n    pass\n\n\n@bp_complaint.route('/stats/', methods=['GET', 'POST'])\n@login_required\ndef stats():\n    \"\"\"\n    投诉统计\n    :return:\n    \"\"\"\n    pass\n"
  },
  {
    "path": "app_frontend/views/credit.py",
    "content": "#!/usr/bin/env python\n# encoding: utf-8\n\n\"\"\"\n@author: zhanghe\n@software: PyCharm\n@file: credit.py\n@time: 2017/4/23 下午11:47\n\"\"\"\n\n\nfrom flask import render_template, request, flash\nfrom flask_login import current_user, login_required\nimport json\nfrom app_frontend import app\nfrom app_frontend.forms.user import UserProfileForm\nfrom app_frontend.api.user_profile import get_user_profile_row_by_id, edit_user_profile\nfrom datetime import datetime\nfrom flask import Blueprint, g\nfrom app_frontend.api.credit import get_user_credit_row_by_id\nfrom app_common.tools import json_default\n\n\nbp_credit = Blueprint('credit', __name__, url_prefix='/credit')\n\n\n@bp_credit.route('/', methods=['GET', 'POST'])\n@login_required\ndef index():\n    return render_template('credit/index.html', title='credit')\n\n\n@bp_credit.route('/ajax/get_user_data/', methods=['GET', 'POST'])\ndef ajax_get_user_data():\n    \"\"\"\n    获取用户声望信息\n    :return:\n    \"\"\"\n    login_user_id = current_user.id\n    info = get_user_credit_row_by_id(login_user_id)\n    if info:\n        data = {\n            'result': True,\n            'values': [\n                info.behavior,          # 行为偏好\n                info.characteristics,   # 身份特质\n                info.connections,       # 人脉关系\n                info.history,           # 信用历史\n                info.performance        # 履约能力\n            ]\n        }\n        return json.dumps(data, default=json_default)\n"
  },
  {
    "path": "app_frontend/views/file.py",
    "content": "#!/usr/bin/env python\n# encoding: utf-8\n\n\"\"\"\n@author: zhanghe\n@software: PyCharm\n@file: file.py\n@time: 2017/3/30 下午5:53\n\"\"\"\n\n\nimport json\nimport logging\nfrom datetime import datetime\n\nfrom flask import request, render_template, redirect, url_for, g, abort, flash, jsonify\nfrom flask import send_from_directory\nfrom flask_login import current_user, login_required\n\nfrom app_frontend import app\n\nfrom flask import Blueprint\n\n\nbp_file = Blueprint('file', __name__, url_prefix='/file')\n\n\nlog = logging.getLogger(__name__)\n\n\ndef allowed_file(filename):\n    \"\"\"\n    校验文件类型\n    \"\"\"\n    return '.' in filename and filename.rsplit('.', 1)[1] in app.config['ALLOWED_EXTENSIONS']\n\n\ndef get_extend_type(filename):\n    \"\"\"\n    获取文件扩展\n    :param filename:\n    :return:\n    \"\"\"\n    if allowed_file(filename):\n        return filename.rsplit('.', 1)[1]\n    else:\n        return\n\n\ndef get_file_size(file_obj):\n    \"\"\"\n    获取文件大小\n    :param file_obj:\n    :return:\n    \"\"\"\n    file_obj.seek(0, 2)  # Seek to the end of the file\n    size = file_obj.tell()  # Get the position of EOF\n    file_obj.seek(0)  # Reset the file position to the beginning\n    return size\n\n\n@bp_file.route('/uploads', methods=['GET', 'POST'])\ndef uploads():\n    \"\"\"\n    多文件上传\n    \"\"\"\n    if request.method == 'GET':\n        return render_template('uploads.html')\n    if request.method == 'DELETE':\n        # todo\n        result = {\"files\": [\n            {\n                \"picture1.jpg\": True\n            },\n            {\n                \"picture2.jpg\": True\n            }\n        ]}\n        return json.dumps(result)\n    if request.method == 'POST':\n        files = []\n        from werkzeug.utils import secure_filename\n        file_list = request.files.getlist('files[]')\n        for file_item in file_list:\n            # file_name = secure_filename(file_item.filename)\n            extend_type = get_extend_type(file_item.filename)\n            file_name = datetime.utcnow().strftime('%Y%m%d%H%M%S%f')\n            file_name = '%s.%s' % (file_name, extend_type) if extend_type else file_item.filename\n            file_info = {\n                'name': file_name,\n                'content_type': file_item.content_type,\n                'size': get_file_size(file_item),\n                'url': url_for('static', filename='uploads/%s' % file_name),\n                'thumbnail_url': url_for('static', filename='uploads/%s' % file_name),\n                'delete_url': url_for('file.delete'),\n                'delete_type': 'POST'\n            }\n            if not extend_type:\n                file_info['thumbnail_url'] = url_for('static', filename='img/lazy-pic.png')\n                file_info.pop('url')\n                file_info.pop('delete_url')\n            if not file_item or not allowed_file(file_item.filename):\n                file_info['error'] = u'文件类型暂不支持'\n            file_item.save(app.config['UPLOAD_FOLDER'] + file_info['name'])\n            files.append(file_info)\n        return json.dumps({'files': files})\n\n\n@bp_file.route('/preview/<filename>', methods=['GET'])\ndef preview(filename):\n    \"\"\"\n    预览图\n    :return:\n    \"\"\"\n    return send_from_directory(app.config['UPLOAD_FOLDER'], filename=filename)\n\n\n@bp_file.route('/thumbnail/<filename>', methods=['GET'])\ndef thumbnail(filename):\n    \"\"\"\n    缩略图\n    :return:\n    \"\"\"\n    return send_from_directory(app.config['UPLOAD_FOLDER'], filename=filename)\n\n\n@bp_file.route('/del', methods=['GET', 'POST'])\ndef delete():\n    \"\"\"\n    删除文件\n    \"\"\"\n    if request.method == 'POST':\n        # todo\n        result = {\"files\": [\n            {\n                \"picture1.jpg\": True\n            },\n            {\n                \"picture2.jpg\": True\n            }\n        ]}\n        return json.dumps(result)\n"
  },
  {
    "path": "app_frontend/views/get.py",
    "content": "#!/usr/bin/env python\n# encoding: utf-8\n\n\"\"\"\n@author: zhanghe\n@software: PyCharm\n@file: get.py\n@time: 2017/3/30 下午6:08\n\"\"\"\n\n\ndef func():\n    pass\n\n\nclass Main(object):\n    def __init__(self):\n        pass\n\n\nif __name__ == '__main__':\n    pass\n"
  },
  {
    "path": "app_frontend/views/invite.py",
    "content": "#!/usr/bin/env python\n# encoding: utf-8\n\n\"\"\"\n@author: zhanghe\n@software: PyCharm\n@file: invite.py\n@time: 2017/4/28 上午10:53\n\"\"\"\n\n\nfrom flask import render_template, request, flash, redirect, url_for\nfrom flask_login import current_user, login_required\nfrom itsdangerous import URLSafeSerializer\nfrom app_common.tools import md5\nfrom app_frontend import app\nfrom app_frontend.forms.user import UserProfileForm, UserAuthForm, UserBankForm\nfrom app_frontend.api.user_profile import get_user_profile_row_by_id, edit_user_profile\nfrom app_frontend.api.user_bank import get_user_bank_row_by_id, add_user_bank, edit_user_bank\nfrom app_frontend.api.user_auth import get_user_auth_row_by_id, get_user_auth_row, edit_user_auth\nfrom app_frontend.api.user import edit_user\nfrom app_common.maps.type_auth import *\nfrom datetime import datetime\nfrom flask import Blueprint\n\n\nbp_invite = Blueprint('invite', __name__, url_prefix='/invite')\n\n\n@bp_invite.route('/', methods=['GET', 'POST'])\n@login_required\ndef index():\n    uid = current_user.id\n    s = URLSafeSerializer('')\n    s.dumps({'uid': uid})\n\n    return request.args.get('i')\n\n"
  },
  {
    "path": "app_frontend/views/message.py",
    "content": "#!/usr/bin/env python\n# encoding: utf-8\n\n\"\"\"\n@author: zhanghe\n@software: PyCharm\n@file: message.py\n@time: 2017/4/29 下午2:28\n\"\"\"\n\n\nfrom datetime import datetime\nfrom flask import redirect\nfrom flask import render_template, request, flash, g\nfrom flask import url_for\nfrom flask_login import current_user, login_required\nimport flask_excel as excel\nfrom sqlalchemy.orm import aliased\n\nfrom app_frontend import app\nfrom app_frontend.models import User, UserProfile, Message\nfrom app_frontend.api.message import get_message_rows, get_message_row, add_message\nfrom app_common.maps.status_reply import STATUS_REPLY_DICT\n\nfrom app_frontend.forms.message import MessageAddForm\n\nfrom flask import Blueprint\n\nfrom app_frontend.database import db\n\nPER_PAGE_FRONTEND = app.config['PER_PAGE_FRONTEND']\n\nbp_message = Blueprint('message', __name__, url_prefix='/message')\n\n\n@bp_message.route('/list/')\n@bp_message.route('/list/<int:page>/')\n@login_required\ndef lists(page=1):\n    \"\"\"\n    留言列表\n    \"\"\"\n    user_id = current_user.id\n    msg_type = request.args.get('msg_type', 'rec')\n\n    # 多次连接同一张表，需要别名\n    user_profile_put = aliased(UserProfile)\n    user_profile_get = aliased(UserProfile)\n\n    # 发送\n    if msg_type == 'send':\n        condition = {\n            'send_user_id': user_id,\n            'status_delete': 0\n        }\n    # 接收\n    else:\n        condition = {\n            'receive_user_id': user_id,\n            'status_delete': 0\n        }\n    try:\n        pagination = Message.query. \\\n            filter_by(**condition). \\\n            outerjoin(user_profile_put, Message.send_user_id == user_profile_put.user_id). \\\n            add_entity(user_profile_put). \\\n            outerjoin(user_profile_get, Message.receive_user_id == user_profile_get.user_id). \\\n            add_entity(user_profile_get). \\\n            order_by(Message.id.desc()). \\\n            paginate(page, PER_PAGE_FRONTEND, False)\n        db.session.commit()\n        return render_template('message/list.html', title='message_list', pagination=pagination)\n    except Exception as e:\n        db.session.rollback()\n        flash(e.message, category='warning')\n        return redirect(url_for('index'))\n\n\n@bp_message.route('/add/', methods=['GET', 'POST'])\n@login_required\ndef add():\n    \"\"\"\n    创建留言\n    :return:\n    \"\"\"\n    form = MessageAddForm(request.form)\n    user_id = request.args.get('user_id')\n    form.user_id.data = user_id\n    if request.method == 'POST':\n        if form.validate_on_submit():\n            current_time = datetime.utcnow()\n            msg_data = {\n                'send_user_id': current_user.id,\n                'receive_user_id': form.user_id.data,\n                'content': form.content.data,\n                'create_time': current_time,\n                'update_time': current_time,\n            }\n            result = add_message(msg_data)\n            if result:\n                flash(u'留言成功', 'success')\n                return redirect(url_for('.lists', msg_type='send'))\n            else:\n                flash(u'留言失败', 'warning')\n        flash(u'留言失败', 'warning')\n    return render_template('message/add.html', title='message_add', form=form)\n\n\n@bp_message.route('/del/', methods=['GET', 'POST'])\n@login_required\ndef delete():\n    \"\"\"\n    删除留言\n    :return:\n    \"\"\"\n    pass\n\n\n@bp_message.route('/stats/', methods=['GET', 'POST'])\n@login_required\ndef stats():\n    \"\"\"\n    留言统计\n    :return:\n    \"\"\"\n    pass\n"
  },
  {
    "path": "app_frontend/views/order.py",
    "content": "#!/usr/bin/env python\n# encoding: utf-8\n\n\"\"\"\n@author: zhanghe\n@software: PyCharm\n@file: order.py\n@time: 2017/3/30 下午6:05\n\"\"\"\n\n\nimport json\nfrom datetime import datetime\nimport traceback\nfrom decimal import Decimal\n\nfrom flask import abort\nfrom flask import redirect\nfrom flask import render_template, request, flash, g\nfrom flask import url_for\nfrom flask_login import current_user, login_required\nimport flask_excel as excel\n\nfrom app_common.maps.status_active import STATUS_ACTIVE_NO\nfrom app_frontend import app\nfrom app_frontend.api.user_profile import get_p_uid_list, user_profile_is_complete\nfrom app_frontend.models import User, UserProfile, Order\nfrom app_frontend.api.order import get_order_rows, get_order_row, get_order_row_by_id, edit_order\nfrom app_frontend.api.user_bank import get_user_bank_row_by_id, user_bank_is_complete\nfrom app_frontend.api.order_bill import get_order_bill_lists, add_order_bill, get_order_bill_count\nfrom app_frontend.api.wallet_item import add_wallet_item\nfrom app_frontend.api.wallet import get_wallet_row_by_id, add_wallet, edit_wallet\nfrom app_frontend.api.bonus_item import add_bonus_item\nfrom app_frontend.api.bonus import get_bonus_row_by_id, add_bonus, edit_bonus\nfrom app_frontend.api.user_config import get_user_config_row_by_id\nfrom app_common.maps.status_pay import *\nfrom app_common.maps.status_rec import *\nfrom app_common.maps.status_delete import *\nfrom app_common.maps.status_audit import *\nfrom app_common.maps.type_payment import *\nfrom app_frontend.database import db\n\nfrom flask import Blueprint\n\nfrom app_frontend.tools.config_manage import get_conf\nfrom decimal import Decimal\n\nPER_PAGE_FRONTEND = app.config['PER_PAGE_FRONTEND']\n\nINTEREST_PUT = Decimal(get_conf('INTEREST_PUT'))               # 投资利息（日息）\n\nINTEREST_PAY_AHEAD = Decimal(get_conf('INTEREST_PAY_AHEAD'))   # 提前支付奖金比例\nINTEREST_PAY_DELAY = Decimal(get_conf('INTEREST_PAY_DELAY'))   # 延迟支付罚金比例\n\nDIFF_TIME_PAY_AHEAD = int(get_conf('DIFF_TIME_PAY_AHEAD'))   # 提前支付奖金时间差\nDIFF_TIME_PAY_DELAY = int(get_conf('DIFF_TIME_PAY_DELAY'))   # 延迟支付罚金时间差\n\nINTEREST_REC_AHEAD = Decimal(get_conf('INTEREST_REC_AHEAD'))   # 提前确认奖金比例\nINTEREST_REC_DELAY = Decimal(get_conf('INTEREST_REC_DELAY'))   # 延迟确认罚金比例\n\nDIFF_TIME_REC_AHEAD = int(get_conf('DIFF_TIME_REC_AHEAD'))   # 提前支付奖金时间差\nDIFF_TIME_REC_DELAY = int(get_conf('DIFF_TIME_REC_DELAY'))   # 延迟支付罚金时间差\n\nBONUS_DIRECT = Decimal(get_conf('BONUS_DIRECT'))     # 直接推荐奖励\n\nBONUS_LEVEL_FIRST = Decimal(get_conf('BONUS_LEVEL_FIRST'))     # 一级推荐奖励\nBONUS_LEVEL_SECOND = Decimal(get_conf('BONUS_LEVEL_SECOND'))     # 二级推荐奖励\nBONUS_LEVEL_THIRD = Decimal(get_conf('BONUS_LEVEL_THIRD'))     # 三级推荐奖励\nBONUS_LEVEL = [BONUS_LEVEL_FIRST, BONUS_LEVEL_SECOND, BONUS_LEVEL_THIRD]     # 奖金等级\n\nbp_order = Blueprint('order', __name__, url_prefix='/order')\n\n\n@bp_order.route('/put/list/')\n@bp_order.route('/put/list/<int:page>/')\n@login_required\ndef lists_put(page=1):\n    \"\"\"\n    投资订单列表\n    \"\"\"\n    user_id = current_user.id\n\n    # 判断基本信息和银行信息是否完整\n    if not user_profile_is_complete(user_id):\n        flash(u'请先完善基本信息', 'warning')\n        return redirect(url_for('user.profile'))\n    if not user_bank_is_complete(user_id):\n        flash(u'请先完善银行信息', 'warning')\n        return redirect(url_for('user.bank'))\n        # 判断是否激活\n    if current_user.status_active == int(STATUS_ACTIVE_NO):\n        flash(u'请先激活当前账号', 'warning')\n        return redirect(url_for('user.profile'))\n\n    # 支付状态（默认未处理）\n    status_pay = request.args.get('status_pay', 0, type=int)\n\n    search_condition_order = [\n        Order.apply_put_uid == user_id,\n        Order.status_delete == STATUS_DEL_NO,  # 默认未删除\n    ]\n\n    if status_pay in STATUS_PAY_DICT:\n        search_condition_order.append(Order.status_pay == status_pay)\n\n    try:\n        pagination = Order.query. \\\n            filter(*search_condition_order). \\\n            outerjoin(UserProfile, Order.apply_get_uid == UserProfile.user_id). \\\n            add_entity(UserProfile). \\\n            order_by(Order.id.desc()). \\\n            paginate(page, PER_PAGE_FRONTEND, False)\n        db.session.commit()\n        return render_template('order/put_list.html', title='order_put_list', pagination=pagination)\n    except Exception as e:\n        db.session.rollback()\n        flash(e.message, category='warning')\n        return redirect(url_for('index'))\n\n\n@bp_order.route('/get/list/')\n@bp_order.route('/get/list/<int:page>/')\n@login_required\ndef lists_get(page=1):\n    \"\"\"\n    提现订单列表\n    \"\"\"\n    user_id = current_user.id\n\n    # 判断基本信息和银行信息是否完整\n    if not user_profile_is_complete(user_id):\n        flash(u'请先完善基本信息', 'warning')\n        return redirect(url_for('user.profile'))\n    if not user_bank_is_complete(user_id):\n        flash(u'请先完善银行信息', 'warning')\n        return redirect(url_for('user.bank'))\n        # 判断是否激活\n    if current_user.status_active == int(STATUS_ACTIVE_NO):\n        flash(u'请先激活当前账号', 'warning')\n        return redirect(url_for('user.profile'))\n\n    # 收款状态（默认未处理）\n    status_rec = request.args.get('status_rec', 0, type=int)\n\n    search_condition_order = [\n        Order.apply_get_uid == user_id,\n        Order.status_delete == STATUS_DEL_NO,  # 默认未删除\n    ]\n\n    if status_rec in STATUS_REC_DICT:\n        search_condition_order.append(Order.status_rec == status_rec)\n\n    try:\n        pagination = Order.query. \\\n            filter(*search_condition_order). \\\n            outerjoin(UserProfile, Order.apply_put_uid == UserProfile.user_id). \\\n            add_entity(UserProfile). \\\n            order_by(Order.id.desc()). \\\n            paginate(page, PER_PAGE_FRONTEND, False)\n        db.session.commit()\n        return render_template('order/get_list.html', title='order_get_list', pagination=pagination)\n    except Exception as e:\n        db.session.rollback()\n        flash(e.message, category='warning')\n        return redirect(url_for('index'))\n\n\n@bp_order.route('/put/info/<int:order_id>/', methods=['GET', 'POST'])\n@login_required\ndef info_put(order_id):\n    \"\"\"\n    投资订单详情\n    \"\"\"\n    uid = current_user.id\n    # 获取投资订单详情\n    condition = {\n        'id': order_id,\n        'apply_put_uid': uid\n    }\n    order_info = get_order_row(**condition)\n    if not order_info:\n        flash(u'订单查询失败', 'warning')\n        return redirect(url_for('order.lists_put'))\n    if order_info.status_delete == int(STATUS_DEL_OK):\n        flash(u'订单已被删除', 'warning')\n        return redirect(url_for('order.lists_put'))\n\n    # 订单信息\n    order_info = get_order_row_by_id(order_id)\n    # 收款信息\n    bank_info = get_user_bank_row_by_id(order_info.apply_get_uid)\n    # 订单凭证\n    order_bill_lists_condition = {\n        'order_id': order_id,\n        'status_delete': STATUS_DEL_NO\n    }\n    order_bill_lists = get_order_bill_lists(**order_bill_lists_condition)\n\n    return render_template(\n        'order/put_info.html',\n        title='order_put_info',\n        order_info=order_info,\n        bank_info=bank_info,\n        order_bill_lists=order_bill_lists\n    )\n\n\n@bp_order.route('/get/info/<int:order_id>/', methods=['GET', 'POST'])\n@login_required\ndef info_get(order_id):\n    \"\"\"\n    提现订单详情\n    \"\"\"\n    uid = current_user.id\n    # 获取提现订单详情\n    condition = {\n        'id': order_id,\n        'apply_get_uid': uid\n    }\n    order_info = get_order_row(**condition)\n    if not order_info:\n        flash(u'订单查询失败', 'warning')\n        return redirect(url_for('order.lists_get'))\n    if order_info.status_delete == int(STATUS_DEL_OK):\n        flash(u'订单已被删除', 'warning')\n        return redirect(url_for('order.lists_get'))\n\n    # 订单信息\n    order_info = get_order_row_by_id(order_id)\n    # 收款信息\n    bank_info = get_user_bank_row_by_id(order_info.apply_get_uid)\n    # 订单凭证\n    order_bill_lists_condition = {\n        'order_id': order_id,\n        'status_delete': STATUS_DEL_NO\n    }\n    order_bill_lists = get_order_bill_lists(**order_bill_lists_condition)\n\n    return render_template(\n        'order/get_info.html',\n        title='order_get_info',\n        order_info=order_info,\n        bank_info=bank_info,\n        order_bill_lists=order_bill_lists\n    )\n\n\n@bp_order.route('/pay/<int:order_id>/', methods=['GET', 'POST'])\n@login_required\ndef pay(order_id):\n    \"\"\"\n    订单支付\n    \"\"\"\n    uid = current_user.id\n    # 获取投资订单详情\n    condition = {\n        'id': order_id,\n        'apply_put_uid': uid\n    }\n    order_info = get_order_row(**condition)\n    if not order_info:\n        flash(u'订单查询失败', 'warning')\n        return redirect(url_for('order.lists_put'))\n    if order_info.status_delete == int(STATUS_DEL_OK):\n        flash(u'订单已被删除', 'warning')\n        return redirect(url_for('order.lists_put'))\n    if request.method == 'POST':\n        pass\n\n    # 订单信息\n    order_info = get_order_row_by_id(order_id)\n    # 收款信息\n    bank_info = get_user_bank_row_by_id(order_info.apply_get_uid)\n    # 订单凭证\n    order_bill_lists_condition = {\n        'order_id': order_id,\n        'status_delete': STATUS_DEL_NO\n    }\n    order_bill_lists = get_order_bill_lists(**order_bill_lists_condition)\n\n    return render_template(\n        'order/pay.html',\n        title='order_pay',\n        order_info=order_info,\n        bank_info=bank_info,\n        order_bill_lists=order_bill_lists\n    )\n\n\n@bp_order.route('/pay_bill_uploads/<int:order_id>/', methods=['GET', 'POST'])\n@login_required\ndef pay_bill_uploads(order_id):\n    \"\"\"\n    支付凭证上传 多文件上传\n    :param order_id:\n    :return:\n    \"\"\"\n    from app_common.tools.file import get_file_size\n    from app_common.tools.file import create_file_name\n    from app_common.tools.file import validate\n    if request.method == 'POST':\n        # 判断权限\n        uid = current_user.id\n        # 获取投资订单详情\n        condition = {\n            'id': order_id,\n            'apply_put_uid': uid\n        }\n        order_info = get_order_row(**condition)\n        if not order_info:\n            flash(u'订单查询失败', 'warning')\n            return redirect(url_for('order.lists_put'))\n        if order_info.status_delete == int(STATUS_DEL_OK):\n            flash(u'订单已被删除', 'warning')\n            return redirect(url_for('order.lists_put'))\n\n        files = []\n        file_list = request.files.getlist('files[]')\n        for file_item in file_list:\n            file_name = create_file_name(file_item)\n            file_info = {\n                'name': file_name,\n                'content_type': file_item.content_type,\n                'size': get_file_size(file_item),\n                'delete_type': 'POST'\n            }\n            try:\n                # 校验上传文件\n                validate(file_item)\n                file_info['url'] = url_for('static', filename='uploads/%s' % file_name)\n                file_info['thumbnail_url'] = url_for('static', filename='uploads/%s' % file_name)\n                file_info['delete_url'] = url_for('file.delete')\n                # 保存上传文件\n                file_item.save(app.config['UPLOAD_FOLDER'] + file_name)\n                # 添加订单付款凭证\n                current_time = datetime.utcnow()\n                order_bill_data = {\n                    'order_id': order_id,\n                    'bill_img': file_name,\n                    'status_audit': STATUS_AUDIT_SUCCESS,\n                    'audit_time': current_time,\n                    'create_time': current_time,\n                    'update_time': current_time,\n                }\n                add_order_bill(order_bill_data)\n            except Exception as e:\n                file_info['error'] = e.message\n\n            files.append(file_info)\n        # # 更新订单付款凭证\n        # current_time = datetime.utcnow()\n        # order_data = {\n        #     'status_pay': STATUS_PAY_SUCCESS,\n        #     'pay_time': current_time,\n        #     'update_time': current_time\n        # }\n        # edit_order(order_id, order_data)\n        return json.dumps({'files': files})\n        # return redirect(url_for('order.info_put', order_id=order_id))\n\n\n@bp_order.route('/ajax_pay/', methods=['GET', 'POST'])\n@login_required\ndef ajax_pay():\n    \"\"\"\n    订单支付\n    :return:\n    \"\"\"\n    if request.method == 'POST' and request.is_xhr:\n        form = request.form\n        order_id = form.get('order_id', 0, type=int)\n        status_pay = form.get('status_pay', 0, type=int)\n\n        user_id = current_user.id\n\n        try:\n            # 参数校验\n            if not order_id:\n                raise Exception(u'参数错误，操作失败')\n            if status_pay not in STATUS_PAY_DICT:\n                raise Exception(u'参数错误，操作失败')\n\n            # 检查付款凭证\n            order_bill_condition = {\n                'order_id': order_id,\n                'status_delete': STATUS_DEL_NO\n            }\n            order_bill_count = get_order_bill_count(**order_bill_condition)\n            if order_bill_count == 0:\n                raise Exception(u'请先上传付款凭证')\n\n            # 订单异常处理\n            order_info = get_order_row_by_id(order_id)\n            if not order_info:\n                raise Exception(u'异常操作，此订单不存在')\n            if order_info.apply_put_uid != current_user.id:\n                raise Exception(u'异常操作，此订单无权限')\n            if order_info.status_delete == int(STATUS_DEL_OK):\n                raise Exception(u'异常操作，此订单已删除')\n            if order_info.status_pay == status_pay:\n                raise Exception(u'异常操作，此订单已支付')\n\n            # 订单创建时间 与订单支付时间比较\n            order_time = order_info.create_time\n            current_time = datetime.utcnow()\n            diff_time = (current_time - order_time).seconds\n            # 判断是否满足奖励规则\n            if diff_time < DIFF_TIME_PAY_AHEAD:\n                interest = order_info.money * Decimal(INTEREST_PAY_AHEAD)\n                # 添加奖励明细\n                wallet_item_data = {\n                    'user_id': user_id,\n                    'type': TYPE_PAYMENT_INCOME,\n                    'sc_id': order_id,\n                    'amount': interest,\n                    'status_audit': STATUS_AUDIT_SUCCESS,\n                    'audit_time': current_time,\n                    'create_time': current_time,\n                    'update_time': current_time\n                }\n                add_wallet_item(wallet_item_data)\n\n                wallet_info = get_wallet_row_by_id(user_id)\n                # 新增钱包记录，更新钱包余额\n                if not wallet_info:\n                    wallet_data = {\n                        'user_id': user_id,\n                        'amount_initial': 0,\n                        'amount_current': interest,\n                        'amount_lock': 0,\n                        'create_time': current_time,\n                        'update_time': current_time,\n                    }\n                    add_wallet(wallet_data)\n                # 更新钱包余额\n                else:\n                    wallet_data = {\n                        'user_id': user_id,\n                        'amount_current': wallet_info.amount_current + interest,\n                        'update_time': current_time,\n                    }\n                    edit_wallet(user_id, wallet_data)\n\n            # 判断是否满足惩罚规则\n            if diff_time > DIFF_TIME_PAY_DELAY:\n                interest = order_info.money * INTEREST_PAY_DELAY\n                # 添加惩罚明细\n                wallet_item_data = {\n                    'user_id': user_id,\n                    'type': TYPE_PAYMENT_EXPENSE,\n                    'sc_id': order_id,\n                    'amount': interest,\n                    'status_audit': STATUS_AUDIT_SUCCESS,\n                    'audit_time': current_time,\n                    'create_time': current_time,\n                    'update_time': current_time\n                }\n                add_wallet_item(wallet_item_data)\n\n                wallet_info = get_wallet_row_by_id(user_id)\n                # 新增钱包记录，更新钱包余额\n                if not wallet_info:\n                    wallet_data = {\n                        'user_id': user_id,\n                        'amount_initial': 0,\n                        'amount_current': interest,\n                        'amount_lock': 0,\n                        'create_time': current_time,\n                        'update_time': current_time,\n                    }\n                    add_wallet(wallet_data)\n                # 更新钱包余额\n                else:\n                    wallet_data = {\n                        'amount_current': wallet_info.amount_current + interest,\n                        'update_time': current_time,\n                    }\n                    edit_wallet(user_id, wallet_data)\n\n            # 更新支付状态\n            current_time = datetime.utcnow()\n            order_data = {\n                'status_pay': status_pay,\n                'pay_time': current_time,\n                'update_time': current_time,\n            }\n            result = edit_order(order_id, order_data)\n            if result:\n                return json.dumps({'success': u'操作成功'})\n            else:\n                return json.dumps({'error': u'操作失败'})\n        except Exception as e:\n            print traceback.print_exc()\n            return json.dumps({'error': e.message})\n    abort(404)\n\n\n@bp_order.route('/ajax_rec/', methods=['GET', 'POST'])\n@login_required\ndef ajax_rec():\n    \"\"\"\n    订单收款\n    :return:\n    \"\"\"\n    if request.method == 'POST' and request.is_xhr:\n        form = request.form\n        order_id = form.get('order_id', 0, type=int)\n        status_rec = form.get('status_rec', 0, type=int)\n\n        user_id = current_user.id\n\n        try:\n            # 参数校验\n            if not order_id:\n                raise Exception(u'参数错误，收款确认操作失败')\n            if status_rec not in STATUS_REC_DICT:\n                raise Exception(u'参数错误，收款确认操作失败')\n\n            # 订单异常处理\n            order_info = get_order_row_by_id(order_id)\n            if not order_info:\n                raise Exception(u'异常操作，此订单不存在')\n            if order_info.apply_get_uid != user_id:\n                raise Exception(u'异常操作，此订单无权限')\n            if order_info.status_delete == int(STATUS_DEL_OK):\n                raise Exception(u'异常操作，此订单已删除')\n            if order_info.status_pay != int(STATUS_PAY_SUCCESS):\n                raise Exception(u'异常操作，此订单未支付')\n            if order_info.status_rec == status_rec:\n                raise Exception(u'异常操作，此订单已完成')\n\n            # TODO 事务 用户订单确认\n            # 订单支付时间 与订单确认时间比较\n            order_pay_time = order_info.pay_time\n            current_time = datetime.utcnow()\n            diff_time = (current_time - order_pay_time).seconds\n            # 判断是否满足奖励规则\n            if diff_time < DIFF_TIME_PAY_AHEAD:\n                interest = order_info.money * Decimal(INTEREST_PAY_AHEAD)\n                # 添加奖励明细\n                wallet_item_data = {\n                    'user_id': user_id,\n                    'type': TYPE_PAYMENT_INCOME,\n                    'sc_id': order_id,\n                    'amount': interest,\n                    'status_audit': STATUS_AUDIT_SUCCESS,\n                    'audit_time': current_time,\n                    'create_time': current_time,\n                    'update_time': current_time\n                }\n                add_wallet_item(wallet_item_data)\n\n                wallet_info = get_wallet_row_by_id(user_id)\n                # 新增钱包记录，更新钱包余额\n                if not wallet_info:\n                    wallet_data = {\n                        'user_id': user_id,\n                        'amount_initial': 0,\n                        'amount_current': interest,\n                        'amount_lock': 0,\n                        'create_time': current_time,\n                        'update_time': current_time,\n                    }\n                    add_wallet(wallet_data)\n                # 更新钱包余额\n                else:\n                    wallet_data = {\n                        'user_id': user_id,\n                        'amount_current': wallet_info.amount_current + interest,\n                        'update_time': current_time,\n                    }\n                    edit_wallet(user_id, wallet_data)\n\n            # 判断是否满足惩罚规则\n            if diff_time > DIFF_TIME_PAY_DELAY:\n                interest = order_info.money * INTEREST_PAY_DELAY\n                # 添加惩罚明细\n                wallet_item_data = {\n                    'user_id': user_id,\n                    'type': TYPE_PAYMENT_EXPENSE,\n                    'sc_id': order_id,\n                    'amount': interest,\n                    'status_audit': STATUS_AUDIT_SUCCESS,\n                    'audit_time': current_time,\n                    'create_time': current_time,\n                    'update_time': current_time\n                }\n                add_wallet_item(wallet_item_data)\n\n                wallet_info = get_wallet_row_by_id(user_id)\n                # 新增钱包记录，更新钱包余额\n                if not wallet_info:\n                    wallet_data = {\n                        'user_id': user_id,\n                        'amount_initial': 0,\n                        'amount_current': interest,\n                        'amount_lock': 0,\n                        'create_time': current_time,\n                        'update_time': current_time,\n                    }\n                    add_wallet(wallet_data)\n                # 更新钱包余额\n                else:\n                    wallet_data = {\n                        'amount_current': wallet_info.amount_current + interest,\n                        'update_time': current_time,\n                    }\n                    edit_wallet(user_id, wallet_data)\n\n            # 更新确认状态\n            order_data = {\n                'status_rec': status_rec,\n                'rec_time': current_time,\n                'update_time': current_time,\n            }\n            result = edit_order(order_id, order_data)\n\n            if result == 1:\n                return json.dumps({'success': u'收款确认操作成功'})\n            if result == 0:\n                return json.dumps({'error': u'收款确认操作失败'})\n        except Exception as e:\n            print traceback.print_exc()\n            return json.dumps({'error': e.message})\n    abort(404)\n\n\n@bp_order.route('/add/', methods=['GET', 'POST'])\n@login_required\ndef add():\n    \"\"\"\n    创建订单\n    :return:\n    \"\"\"\n    pass\n\n\n@bp_order.route('/del/', methods=['GET', 'POST'])\n@login_required\ndef delete():\n    \"\"\"\n    删除订单\n    :return:\n    \"\"\"\n    pass\n\n\n@bp_order.route('/stats/', methods=['GET', 'POST'])\n@login_required\ndef stats():\n    \"\"\"\n    订单统计\n    :return:\n    \"\"\"\n    pass\n"
  },
  {
    "path": "app_frontend/views/pay.py",
    "content": "#!/usr/bin/env python\n# encoding: utf-8\n\n\"\"\"\n@author: zhanghe\n@software: PyCharm\n@file: pay.py\n@time: 2017/3/18 上午12:29\n\"\"\"\n\n\nfrom datetime import datetime\nfrom flask import redirect\nfrom flask import render_template, request, flash, g\nfrom flask import url_for\nfrom flask_login import current_user, login_required\n\nfrom app_frontend import app\nfrom app_frontend.models import User\nfrom app_frontend.api.apply_get import get_apply_get_rows, get_apply_get_row, add_apply_get\nfrom app_frontend.api.apply_put import get_apply_put_rows, get_apply_put_row, add_apply_put\nfrom app_frontend.api.order import get_order_row_by_id\nfrom app_common.maps.status_order import *\nfrom app_common.maps.type_apply import *\nfrom app_common.maps.status_apply import *\nfrom app_common.maps.status_delete import *\nfrom app_frontend.forms.apply_get import ApplyGetAddForm\nfrom app_frontend.forms.apply_put import ApplyPutAddForm\nfrom flask import Blueprint\n\n\nbp_pay = Blueprint('pay', __name__, url_prefix='/pay')\n\n\n@bp_pay.route('/bit_coin/')\n@login_required\ndef bit_coin():\n    \"\"\"\n    支付 - 数字货币\n    \"\"\"\n    order_id = request.args.get('order_id', 0, type=int)\n    # 订单信息\n    order_row = get_order_row_by_id(order_id)\n    # 数字货币信息\n\n\n    uid = current_user.id\n    condition = {\n        'user_id': uid,\n        'status_order': 0,\n        'status_delete': 0\n    }\n    # 订单状态\n\n    if status_order in STATUS_ORDER_DICT:\n        condition['status_order'] = status_order\n\n    pagination = get_apply_put_rows(page, **condition)\n    return render_template('pay/bit_coin.html', title='pay_bit_coin', pagination=pagination)\n\n\n\n# 第三方支付（支付宝）\n@app.route('/pay/alipay/')\ndef pay_alipay():\n    return 'alipay'\n\n\n# 第三方支付（微信）\n@app.route('/pay/wechat/')\ndef pay_wechat():\n    return 'wechat'\n"
  },
  {
    "path": "app_frontend/views/penetration.py",
    "content": "#!/usr/bin/env python\n# encoding: utf-8\n\n\"\"\"\n@author: zhanghe\n@software: PyCharm\n@file: penetration.py\n@time: 2017/5/16 上午11:56\n\"\"\"\n\n\nimport json\nfrom datetime import datetime\n\nfrom flask import Blueprint\nfrom flask import request\nfrom jinja2 import Environment\n\nbp_penetration = Blueprint('penetration', __name__, url_prefix='/penetration')\n\n\n@bp_penetration.route('/')\n@bp_penetration.route('/index/')\ndef index():\n    \"\"\"\n    渗透测试，生产环境需要关掉蓝图\n    \"\"\"\n    name = request.values.get('name', 'world')\n    # 不安全的两种方式\n    output = Environment().from_string('Hello ' + name + '!').render()\n    # output = Environment().from_string('Hello %s!' % name).render()\n    # 安全方式\n    # output = Environment().from_string('Hello {{name}}!').render(name=name)\n\n    return output\n\n\"\"\"\ntplmap 环境依赖\npip install PyYAML\npip install requests\n\"\"\"\n"
  },
  {
    "path": "app_frontend/views/put.py",
    "content": "#!/usr/bin/env python\n# encoding: utf-8\n\n\"\"\"\n@author: zhanghe\n@software: PyCharm\n@file: put.py\n@time: 2017/3/30 下午6:08\n\"\"\"\n\n\ndef func():\n    pass\n\n\nclass Main(object):\n    def __init__(self):\n        pass\n\n\nif __name__ == '__main__':\n    pass\n"
  },
  {
    "path": "app_frontend/views/reg.py",
    "content": "#!/usr/bin/env python\n# encoding: utf-8\n\n\"\"\"\n@author: zhanghe\n@software: PyCharm\n@file: reg.py\n@time: 2017/3/10 下午11:00\n\"\"\"\n\nfrom datetime import datetime\n\nfrom flask import request, render_template, redirect, url_for, flash, session\n\nfrom app_common.tools import md5, get_randint\nfrom app_common.tools.ip import get_real_ip\nfrom app_frontend import app\n\nfrom flask import Blueprint\n\nfrom app_frontend.lib.rabbit_mq import RabbitDelayQueue, RabbitPriorityQueue\n# from app_frontend.lib.sms_chuanglan_iso import SmsChuangLanIsoApi\nfrom app_common.maps import area_code_map\nfrom app_common.maps.type_auth import *\n\nfrom app_frontend.api.user import add_user\nfrom app_frontend.api.user_auth import add_user_auth\nfrom app_frontend.api.user_profile import add_user_profile\n\nimport json\n\nSMS_CODE_REG = app.config['SMS_CODE_REG']\nEXCHANGE_NAME = app.config['EXCHANGE_NAME']\nLOCK_REG_NOT_ACTIVE_TTL = app.config['LOCK_REG_NOT_ACTIVE_TTL']\n\n\nbp_reg = Blueprint('reg', __name__, url_prefix='/reg')\n\n# 短信通道配置\nUN = app.config['SMS']['UN']\nPW = app.config['SMS']['PW']\n\n\n@bp_reg.route('/', methods=['GET', 'POST'])\ndef index():\n    \"\"\"\n    注册\n    \"\"\"\n    # return \"Hello, World!\\nReg!\"\n    from app_frontend.forms.reg import RegForm\n    form = RegForm()\n    # 推荐人赋值\n    user_pid = session.get('user_pid', 0)\n    if not app.config.get('TEST') and not user_pid:\n        flash(u'没有推荐人，不能注册', 'warning')\n        return redirect('index')\n    form.user_pid.data = user_pid\n    if request.method == 'POST':\n        if form.validate_on_submit():\n            current_time = datetime.utcnow()\n            # 添加用户注册信息\n            user_data = {\n                'create_time': current_time,\n                'update_time': current_time,\n                'reg_ip': get_real_ip()\n            }\n            from app_frontend.api.user import add_user\n            user_id = add_user(user_data)\n\n            # 添加用户认证信息\n            user_auth_data = {\n                'user_id': user_id,\n                'type_auth': TYPE_AUTH_ACCOUNT,\n                'auth_key': form.account.data,\n                'auth_secret': md5(form.password.data),\n                'status_verified': 1,\n                'create_time': current_time,\n                'update_time': current_time,\n            }\n            from app_frontend.api.user_auth import add_user_auth\n            add_user_auth(user_auth_data)\n\n            # 添加用户基本信息\n            user_profile_data = {\n                'user_id': user_id,\n                'user_pid': form.user_pid.data,\n                'nickname': form.account.data,\n                'create_time': current_time,\n                'update_time': current_time,\n            }\n            add_user_profile(user_profile_data)\n            if user_id:\n                # 加入用户注册自动监测锁定队列\n                q = RabbitDelayQueue(\n                    exchange=EXCHANGE_NAME,\n                    queue_name='lock_reg_not_active',\n                    ttl=LOCK_REG_NOT_ACTIVE_TTL\n                )\n                q.put({'user_id': user_id, 'reg_time': current_time.strftime('%Y-%m-%d %H:%M:%S')})\n                q.close_conn()\n\n                flash(u'%s, 恭喜您注册成功' % form.account.data, 'success')\n            else:\n                flash(u'%s, 很遗憾注册失败' % form.account.data, 'warning')\n            return redirect(url_for('auth.index'))\n        # 闪现消息 success info warning danger\n        # flash(form.errors, 'warning')  # 调试打开\n    return render_template('reg/index.html', title='reg', form=form)\n\n\n@bp_reg.route('/phone/', methods=['GET', 'POST'])\ndef phone():\n    \"\"\"\n    手机注册\n    \"\"\"\n    # return \"Hello, World!\\nReg!\"\n    from app_frontend.forms.reg import RegPhoneForm\n    form = RegPhoneForm()\n    # 推荐人赋值\n    form.user_pid.data = session.get('user_pid', 0)\n    if request.method == 'POST':\n        if form.validate_on_submit():\n            current_time = datetime.utcnow()\n            # 添加用户注册信息\n            user_data = {\n                'reg_ip': get_real_ip(),\n                'create_time': current_time,\n                'update_time': current_time,\n            }\n            user_id = add_user(user_data)\n\n            # 添加用户认证信息\n\n            # 手机号码国际化\n            area_id = form.area_id.data\n            area_code = area_code_map.get(area_id, '86')\n            mobile_iso = '%s%s' % (area_code, form.phone.data)\n\n            user_auth_data = {\n                'user_id': user_id,\n                'type_auth': TYPE_AUTH_PHONE,\n                'auth_key': mobile_iso,\n                'auth_secret': md5(form.password.data),\n                'status_verified': 1,\n                'create_time': current_time,\n                'update_time': current_time,\n            }\n            add_user_auth(user_auth_data)\n\n            # 添加用户基本信息\n            user_profile_data = {\n                'user_id': user_id,\n                'user_pid': form.user_pid.data,\n                'area_id': form.area_id.data,\n                'phone': form.phone.data,\n                'create_time': current_time,\n                'update_time': current_time,\n            }\n            add_user_profile(user_profile_data)\n\n            if user_id:\n                flash(u'%s, 恭喜您注册成功' % form.phone.data, 'success')\n            else:\n                flash(u'%s, 很遗憾注册失败' % form.phone.data, 'warning')\n            return redirect(url_for('auth.index'))\n        # 闪现消息 success info warning danger\n        # flash(form.errors, 'warning')  # 调试打开\n    return render_template('reg/phone.html', title='reg', form=form)\n\n\n@bp_reg.route('/email/', methods=['GET', 'POST'])\ndef email():\n    \"\"\"\n    邮箱注册\n    \"\"\"\n    # return \"Hello, World!\\nReg!\"\n    from app_frontend.forms.reg import RegEmailForm\n    form = RegEmailForm()\n    # 推荐人赋值\n    form.user_pid.data = session.get('user_pid', 0)\n    if request.method == 'POST':\n        if form.validate_on_submit():\n            # 添加用户注册信息\n            current_time = datetime.utcnow()\n            user_data = {\n                'create_time': current_time,\n                'update_time': current_time,\n                'reg_ip': get_real_ip()\n            }\n            from app_frontend.api.user import add_user\n            user_id = add_user(user_data)\n\n            # 添加用户认证信息\n            user_auth_data = {\n                'user_id': user_id,\n                'type_auth': TYPE_AUTH_EMAIL,\n                'auth_key': form.email.data,\n                'auth_secret': md5(form.password.data)\n            }\n            from app_frontend.api.user_auth import add_user_auth\n            add_user_auth(user_auth_data)\n\n            # 添加用户基本信息\n            user_profile_data = {\n                'user_id': user_id,\n                'user_pid': form.user_pid.data,\n                'email': form.email.data,\n                'create_time': current_time,\n                'update_time': current_time,\n            }\n            add_user_profile(user_profile_data)\n\n            if user_id:\n                flash(u'%s, 恭喜您注册成功' % form.email.data, 'success')\n                # todo 发送邮箱校验邮件\n                # email_validate_content = {\n                #     'mail_from': 'System Support<support@zhendi.me>',\n                #     'mail_to': form.email.data,\n                #     'mail_subject': 'verify reg email',\n                #     'mail_html': 'verify reg email address in mailbox'\n                # }\n                # from app_frontend import send_cloud_client\n                # send_email_result = send_cloud_client.mail_send(**email_validate_content)\n                # # 调试邮件发送结果\n                # if send_email_result.get('result') is False:\n                #     flash(send_email_result.get('message'), 'warning')\n                # else:\n                #     flash(send_email_result.get('message'), 'success')\n                # https://www.***.com/email/signup/uuid\n            else:\n                flash(u'%s, 很遗憾注册失败' % form.email.data, 'warning')\n            return redirect(url_for('auth.index'))\n        # 闪现消息 success info warning danger\n        # flash(form.errors, 'warning')  # 调试打开\n    return render_template('reg/email.html', title='reg', form=form)\n\n\n@bp_reg.route('/agreement/')\ndef agreement():\n    \"\"\"\n    注册协议\n    :return:\n    \"\"\"\n    return 'agreement'\n\n\n@bp_reg.route('/email/sign')\ndef email_sign():\n    \"\"\"\n    邮箱签名(带过期时间)\n    http://localhost:5000/email/sign?email=zhang_he06@163.com\n    \"\"\"\n    email = request.args.get('email', '')\n    from itsdangerous import TimestampSigner\n    from app_frontend import app\n    s = TimestampSigner(app.config['SECRET_KEY'])\n    return s.sign(email)\n\n\n@bp_reg.route('/email/check')\ndef email_check():\n    \"\"\"\n    校验邮箱有效性\n    http://localhost:5000/email/check?sign=zhang_he06@163.com.ChstqQ.5jODirLaRF2yU0CLtZz2EmoHt4c\n    \"\"\"\n    sign = request.args.get('sign', '')\n    from itsdangerous import TimestampSigner, SignatureExpired, BadTimeSignature\n    from app_frontend import app\n    s = TimestampSigner(app.config['SECRET_KEY'])\n    try:\n        # email = s.unsign(sign, max_age=5)  # 5秒过期\n        email = s.unsign(sign, max_age=30*24*60*60)  # １个月过期\n        # return email\n        # 校验通过，更新邮箱验证状态\n        from app_frontend.api.user_auth import update_user_auth_rows\n        result = update_user_auth_rows({'verified': 1}, **{'type_auth': TYPE_AUTH_EMAIL, 'auth_key': email})\n        if result == 1:\n            flash(u'%s, 邮箱成功激活' % email, 'success')\n            return redirect(url_for('auth.index'))\n        else:\n            flash(u'%s, 邮箱激活失败' % email, 'warning')\n    except SignatureExpired as e:\n        # 处理签名超时\n        flash(e.message, 'warning')\n    except BadTimeSignature as e:\n        # 处理签名错误\n        flash(e.message, 'warning')\n    return redirect(url_for('reg.index'))\n\n\n@bp_reg.route('/ajax/get_sms_code/', methods=['GET', 'POST'])\ndef ajax_get_sms_code():\n    \"\"\"\n    校验图形验证码，获取短信验证码\n    :return:\n    \"\"\"\n    # 校验图形验证码\n    code_str = request.args.get('code_str', '', type=str)\n    code_key = '%s:%s' % ('code_str', 'reg')\n    session_code_str = session.get(code_key, '')\n    if not session_code_str:\n        return json.dumps({'result': False, 'msg': u'图形验证码过期，请刷新后重试'})\n    result_code = code_str.upper() == session_code_str.upper()\n    if result_code is False:\n        return json.dumps({'result': False, 'msg': u'图形验证码错误，请重新提交'})\n    # 获取短信验证码\n    area_id = request.args.get('area_id', '', type=str)\n    area_code = area_code_map.get(area_id, '86')\n    mobile = request.args.get('phone', '', type=str)\n    mobile_iso = '%s%s' % (area_code, mobile)\n\n    sms_code = str(get_randint())\n    code_key = '%s:%s' % ('sms_code', 'reg')\n    session[code_key] = sms_code\n\n    sms_content = SMS_CODE_REG % sms_code\n    # sms_client = SmsChuangLanIsoApi(UN, PW)\n    # result = sms_client.send_international(mobile_iso, sms_content)\n\n    # 推送短信优先级队列\n    q = RabbitPriorityQueue(exchange=EXCHANGE_NAME, queue_name='send_sms_p')\n    q.put({'mobile': mobile_iso, 'sms_content': sms_content}, 20)\n\n    return json.dumps({'result': True})\n"
  },
  {
    "path": "app_frontend/views/scheduling.py",
    "content": "#!/usr/bin/env python\n# encoding: utf-8\n\n\"\"\"\n@author: zhanghe\n@software: PyCharm\n@file: scheduling.py\n@time: 2017/6/29 下午8:45\n\"\"\"\n\n\nfrom datetime import datetime\nfrom flask import redirect\nfrom flask import render_template, request, flash, g\nfrom flask import url_for\nfrom flask_login import current_user, login_required\nfrom sqlalchemy.orm import aliased\n\nfrom app_common.maps.type_scheduling import TYPE_SCHEDULING_USER, TYPE_SCHEDULING_GIVE\nfrom app_frontend import app\nfrom app_frontend.api.scheduling import get_scheduling_row_by_id\nfrom app_frontend.api.scheduling_item import get_scheduling_item_item_rows\n\nfrom flask import Blueprint\n\nfrom app_frontend.database import db\nfrom app_frontend.models import UserProfile, SchedulingItem\n\nPER_PAGE_FRONTEND = app.config['PER_PAGE_FRONTEND']\n\nbp_scheduling = Blueprint('scheduling', __name__, url_prefix='/scheduling')\n\n\n@bp_scheduling.route('/list/')\n@bp_scheduling.route('/list/<int:page>/')\n@login_required\ndef lists(page=1):\n    \"\"\"\n    排单列表\n    \"\"\"\n    user_id = current_user.id\n    # （1：用户排单、2：系统发送）\n    scheduling_type = request.args.get('scheduling_list', 0, int)\n\n    # 多次连接同一张表，需要别名\n    user_profile_put = aliased(UserProfile)\n    user_profile_get = aliased(UserProfile)\n\n    if scheduling_type == 1:\n        condition = [\n            SchedulingItem.type == TYPE_SCHEDULING_USER,\n            SchedulingItem.sc_id == user_id\n        ]\n    elif scheduling_type == 2:\n        condition = [\n            SchedulingItem.type == TYPE_SCHEDULING_GIVE,\n            SchedulingItem.sc_id == user_id\n        ]\n    else:\n        condition = [SchedulingItem.sc_id == user_id]\n\n    try:\n        pagination = SchedulingItem.query. \\\n            outerjoin(user_profile_put, SchedulingItem.user_id == user_profile_put.user_id). \\\n            add_entity(user_profile_put). \\\n            outerjoin(user_profile_get, SchedulingItem.sc_id == user_profile_get.user_id). \\\n            add_entity(user_profile_get). \\\n            filter(*condition). \\\n            order_by(SchedulingItem.id.desc()). \\\n            paginate(page, PER_PAGE_FRONTEND, False)\n        db.session.commit()\n        return render_template('scheduling/list.html', title='scheduling_list', pagination=pagination)\n    except Exception as e:\n        db.session.rollback()\n        flash(e.message, category='warning')\n        return redirect(url_for('index'))\n\n\n@bp_scheduling.route('/add/', methods=['GET', 'POST'])\n@login_required\ndef add():\n    \"\"\"\n    创建积分\n    :return:\n    \"\"\"\n    pass\n\n\n@bp_scheduling.route('/del/', methods=['GET', 'POST'])\n@login_required\ndef delete():\n    \"\"\"\n    删除积分\n    :return:\n    \"\"\"\n    pass\n\n\n@bp_scheduling.route('/stats/', methods=['GET', 'POST'])\n@login_required\ndef stats():\n    \"\"\"\n    积分统计\n    :return:\n    \"\"\"\n    pass\n"
  },
  {
    "path": "app_frontend/views/score.py",
    "content": "#!/usr/bin/env python\n# encoding: utf-8\n\n\"\"\"\n@author: zhanghe\n@software: PyCharm\n@file: score.py\n@time: 2017/4/25 下午1:25\n\"\"\"\n\n\nfrom datetime import datetime\nfrom flask import redirect\nfrom flask import render_template, request, flash, g\nfrom flask import url_for\nfrom flask_login import current_user, login_required\n\nfrom app_frontend import app\nfrom app_frontend.api.score import get_score_rows\n\nfrom app_frontend.api.score_charity_item import get_score_charity_item_rows\nfrom app_frontend.api.score_digital_item import get_score_digital_item_rows\nfrom app_frontend.api.score_expense_item import get_score_expense_item_rows\n\nfrom flask import Blueprint\n\n\nbp_score = Blueprint('score', __name__, url_prefix='/score')\n\n\n@bp_score.route('/list/')\n@bp_score.route('/list/<int:page>/')\n@login_required\ndef lists(page=1):\n    \"\"\"\n    积分列表\n    \"\"\"\n\n    pagination = get_score_rows(page)\n    return render_template('score/list.html', title='score_list', pagination=pagination)\n\n\n@bp_score.route('/add/', methods=['GET', 'POST'])\n@login_required\ndef add():\n    \"\"\"\n    创建积分\n    :return:\n    \"\"\"\n    pass\n\n\n@bp_score.route('/del/', methods=['GET', 'POST'])\n@login_required\ndef delete():\n    \"\"\"\n    删除积分\n    :return:\n    \"\"\"\n    pass\n\n\n@bp_score.route('/stats/', methods=['GET', 'POST'])\n@login_required\ndef stats():\n    \"\"\"\n    积分统计\n    :return:\n    \"\"\"\n    pass\n\n\n@bp_score.route('/charity/list/', methods=['GET', 'POST'])\n@bp_score.route('/charity/list/<int:page>/')\n@login_required\ndef charity_lists(page=1):\n    \"\"\"\n    慈善积分\n    :return:\n    \"\"\"\n    condition = {'user_id': current_user.id}\n\n    # 积分类型:（1：获得、2：消费）\n    score_type = request.args.get('score_type', 0, type=int)\n\n    if score_type:\n        condition['type'] = score_type\n\n    pagination = get_score_charity_item_rows(page, **condition)\n    return render_template('score/charity_list.html', title='score_charity_list', pagination=pagination)\n\n\n@bp_score.route('/digital/list/', methods=['GET', 'POST'])\n@bp_score.route('/digital/list/<int:page>/')\n@login_required\ndef digital_lists(page=1):\n    \"\"\"\n    数字积分\n    :return:\n    \"\"\"\n    condition = {'user_id': current_user.id}\n\n    # 积分类型:（1：获得、2：消费）\n    score_type = request.args.get('score_type', 0, type=int)\n\n    if score_type:\n        condition['type'] = score_type\n\n    pagination = get_score_digital_item_rows(page, **condition)\n    return render_template('score/digital_list.html', title='score_digital_list', pagination=pagination)\n\n\n@bp_score.route('/expense/list/', methods=['GET', 'POST'])\n@bp_score.route('/expense/list/<int:page>/')\n@login_required\ndef expense_lists(page=1):\n    \"\"\"\n    消费积分\n    :return:\n    \"\"\"\n    condition = {'user_id': current_user.id}\n\n    # 积分类型:（1：获得、2：消费）\n    score_type = request.args.get('score_type', 0, type=int)\n\n    if score_type:\n        condition['type'] = score_type\n\n    pagination = get_score_expense_item_rows(page, **condition)\n    return render_template('score/expense_list.html', title='score_expense_list', pagination=pagination)\n"
  },
  {
    "path": "app_frontend/views/site.py",
    "content": "#!/usr/bin/env python\n# encoding: utf-8\n\n\"\"\"\n@author: zhanghe\n@software: PyCharm\n@file: site.py\n@time: 2017/3/10 下午11:05\n\"\"\"\n\n\n\n\n"
  },
  {
    "path": "app_frontend/views/test.py",
    "content": "#!/usr/bin/env python\n# encoding: utf-8\n\n\"\"\"\n@author: zhanghe\n@software: PyCharm\n@file: test.py\n@time: 2017/3/18 上午12:30\n\"\"\"\n\n\nfrom app_frontend import app, login_manager, oauth_github, oauth_qq, oauth_weibo, send_cloud_client, qi_niu_client\nfrom flask import render_template, request, url_for, send_from_directory, session, flash, redirect, g, jsonify, Markup, abort\n# from application.forms import RegForm, LoginForm, BlogAddForm, BlogEditForm, UserForm\nfrom app_frontend.login import LoginUser\nfrom flask_login import login_user, logout_user, current_user, login_required\nimport os\nimport json\nfrom werkzeug.contrib.cache import SimpleCache\ncache = SimpleCache()  # 默认最大支持500个key, 超时时间5分钟, 参数可配置\n\n\n# log测试\n@app.route('/test_log/')\ndef test_log():\n    \"\"\"\n    log测试\n    \"\"\"\n    import logging\n    log = logging.getLogger('app')\n    log.debug('info message')\n    log.info('info message')\n    log.error('error message')\n    return 'log测试'\n\n\n# 缓存测试\n@app.route('/test_cache/')\ndef test_cache():\n    \"\"\"\n    缓存测试\n    5.01s >> 9ms\n    \"\"\"\n    import time\n    rv = cache.get('my-item')\n    if rv is None:\n        time.sleep(5)\n        rv = 'Hello, Cache!'\n        cache.set('my-item', rv, timeout=5 * 10)\n    return rv\n\n\n# 后台任务测试\n@app.route('/test_send_task/')\ndef test_send_task(x=100, y=200):\n    \"\"\"\n    后台发送任务测试\n    http://localhost:8000/test_send_task/?x=100&y=200\n    \"\"\"\n    from app_frontend.tasks import add, mul, xsum\n\n    x = int(request.args.get('x', x))\n    y = int(request.args.get('y', y))\n\n    add_res = add.delay(x, y)\n    mul_res = mul.delay(x, y)\n    xsum_res = xsum.delay([x, y])\n    result = ''\n    result += '<a href=\"http://localhost:8000/test_task_add_result/%s/\">%s</a><br/>' % (add_res.id, add_res.id)\n    result += '<a href=\"http://localhost:8000/test_task_mul_result/%s/\">%s</a><br/>' % (mul_res.id, mul_res.id)\n    result += '<a href=\"http://localhost:8000/test_task_xsum_result/%s/\">%s</a><br/>' % (xsum_res.id, xsum_res.id)\n    return result\n\n\n@app.route('/test_task_send_get/')\ndef test_task_send_get(x=100, y=200):\n    \"\"\"\n    后台发送任务并获取结果测试\n    http://localhost:8000/test_task_send_get/?x=100&y=200\n    \"\"\"\n    from app_frontend.tasks import add, mul, xsum\n\n    x = int(request.args.get('x', x))\n    y = int(request.args.get('y', y))\n\n    add_res = add.delay(x, y)\n    mul_res = mul.delay(x, y)\n    xsum_res = xsum.delay([x, y])\n    import time\n    time.sleep(0.0005)\n    result = {\n        'add_res': add_res.get(timeout=1.0) if add_res.state == 'SUCCESS' else '...',\n        'mul_res': mul_res.get(timeout=1.0) if mul_res.state == 'SUCCESS' else '...',\n        'xsum_res': xsum_res.get(timeout=1.0) if xsum_res.state == 'SUCCESS' else '...'\n    }\n    return json.dumps(result)\n\n\n@app.route('/test_task_add_result/<task_id>/')\ndef test_task_add_result(task_id):\n    \"\"\"\n    后台任务测试结果\n    http://localhost:8000/test_task_add_result/xxxxxx/\n    \"\"\"\n    from app_frontend.tasks import add, mul, xsum\n    result = add.AsyncResult(task_id).get(timeout=1.0)\n    return repr(result)\n\n\n@app.route('/test_task_mul_result/<task_id>/')\ndef test_task_mul_result(task_id):\n    \"\"\"\n    后台任务测试结果\n    http://localhost:8000/test_task_mul_result/xxxxxx/\n    \"\"\"\n    from app_frontend.tasks import add, mul, xsum\n    result = mul.AsyncResult(task_id).get(timeout=1.0)\n    return repr(result)\n\n\n@app.route('/test_task_xsum_result/<task_id>/')\ndef test_task_xsum_result(task_id):\n    \"\"\"\n    后台任务测试结果\n    http://localhost:8000/test_task_xsum_result/xxxxxx/\n    \"\"\"\n    from app_frontend.tasks import add, mul, xsum\n    result = xsum.AsyncResult(task_id).get(timeout=1.0)\n    return repr(result)\n\n\n@app.route(\"/test_exception\")\ndef test():\n    \"\"\"\n    测试\n    \"\"\"\n    try:\n        raise Exception('error test')\n    except Exception as e:\n        import logging\n        logging.error(e)\n\n\n@app.route(\"/test_client_ip\")\ndef test_client_ip():\n    \"\"\"\n    测试客户端来源ip\n    http://localhost:5000/test_client_ip\n    curl -H \"X-Forwarded-For: 1.2.3.4\" http://localhost:5000/test_client_ip\n    \"\"\"\n    if not request.headers.getlist(\"X-Forwarded-For\"):\n        ip = request.remote_addr\n    else:\n        ip = request.headers.getlist(\"X-Forwarded-For\")[0]\n        # todo 校验 Ip 格式\n    return ip\n\n\n@app.route(\"/test_down\")\ndef test_down():\n    \"\"\"\n    测试下载\n    \"\"\"\n    return send_from_directory(os.path.join(app.root_path, 'static'),\n                               'img/cat.jpg', as_attachment=True)\n\n\n@app.route(\"/test/sendcloud\")\ndef test_sendcloud():\n    \"\"\"\n    测试 sendcloud\n    http://localhost:5000/test/sendcloud\n    注意: 用户可以调用模板发送, 也可以普通发送(上传内容发送). 两种发送方式都要求最终的内容和至少一个模板匹配\n    \"\"\"\n    # 获取信息\n    result = send_cloud_client.userinfo_get()\n    # return json.dumps(result)\n\n    # 发送邮件\n    email_content = {\n        'mail_from': 'System Support<support@zhendi.me>',\n        'mail_to': 'zhanghe@wealink.com',\n        'mail_subject': '来自SendCloud的第一封邮件！',\n        'mail_html': '你太棒了！你已成功的从SendCloud发送了一封测试邮件，接下来快登录前台去完善账户信息吧！'\n    }\n    send_email_result = send_cloud_client.mail_send(**email_content)\n    # 调试邮件发送结果\n    return json.dumps(send_email_result)\n\n\n@app.route('/file/save')\ndef save():\n    \"\"\"\n    保存文件到七牛\n    \"\"\"\n    data = 'data to save'\n    filename = 'filename'\n    ret, info = qi_niu_client.save(data, filename)\n    return str(ret)\n\n\n@app.route('/file/delete')\ndef delete():\n    \"\"\"\n    删除七牛空间中的文件\n    \"\"\"\n    filename = 'filename'\n    ret, info = qi_niu_client.delete(filename)\n    return str(ret)\n\n\n@app.route('/file/url')\ndef url():\n    \"\"\"\n    根据文件名获取对应的公开URL\n    \"\"\"\n    filename = 'filename'\n    return qi_niu_client.url(filename)\n\n\n@app.route(\"/email/\")\ndef send_email():\n    \"\"\"\n    邮件发送\n    \"\"\"\n    try:\n        from app_frontend.emails import send_email\n        msg = 'This is a test email!'\n        send_email(\n            subject=u'邮件主题',\n            sender=(u'系统邮箱', 'zhang_he06@163.com'),\n            recipients=[(u'尊敬的用户', 'zhang_he06@163.com')],\n            html_body=render_template('email.html', message=msg)\n        )\n        return jsonify({'success': u'邮件发送成功'})\n    except Exception, e:\n        return jsonify({'error': e.message})\n"
  },
  {
    "path": "app_frontend/views/user.py",
    "content": "#!/usr/bin/env python\n# encoding: utf-8\n\n\"\"\"\n@author: zhanghe\n@software: PyCharm\n@file: user.py\n@time: 2017/3/17 下午11:47\n\"\"\"\n\n\nimport json\nimport traceback\n\nfrom flask import abort\nfrom flask import render_template, request, flash, redirect, url_for\nfrom flask import session\nfrom flask_login import current_user, login_required\n\nfrom app_frontend.lib.rabbit_mq import RabbitDelayQueue, RabbitPriorityQueue\n\nfrom app_common.maps import area_code_map\nfrom app_common.maps.status_delete import *\nfrom app_common.maps.status_active import *\nfrom app_common.tools import md5, get_randint\nfrom app_frontend import app\nfrom app_frontend.forms.user import UserProfileForm, UserAuthForm, UserBankForm\nfrom app_frontend.api.user_profile import get_user_profile_row_by_id, edit_user_profile, get_team_tree\nfrom app_frontend.api.user_bank import get_user_bank_row_by_id, add_user_bank, edit_user_bank\nfrom app_frontend.api.user_auth import get_user_auth_row_by_id, get_user_auth_row, edit_user_auth\nfrom app_frontend.api.user import edit_user, get_user_team_rows, get_user_row_by_id\nfrom app_frontend.api.active import get_active_row_by_id, user_active, give_active\nfrom app_common.maps.type_auth import *\nfrom datetime import datetime\nfrom flask import Blueprint\n\nPER_PAGE_FRONTEND = app.config['PER_PAGE_FRONTEND']\nSMS_CODE_EDIT = app.config['SMS_CODE_EDIT']\nEXCHANGE_NAME = app.config['EXCHANGE_NAME']\n\nbp_user = Blueprint('user', __name__, url_prefix='/user')\n\n\n@bp_user.route('/auth/', methods=['GET', 'POST'])\n@login_required\ndef auth():\n    \"\"\"\n    用户登录认证信息\n    \"\"\"\n    # 获取团队成员三级树形结构\n    team_tree = get_team_tree(current_user.id)\n\n    form = UserAuthForm(request.form)\n    condition = {\n        'user_id': current_user.id,\n        'type_auth': TYPE_AUTH_ACCOUNT,\n    }\n    user_auth_info = get_user_auth_row(**condition)\n\n    if user_auth_info:\n        form.id.data = user_auth_info.id\n        form.type_auth.data = user_auth_info.type_auth\n        form.auth_key.data = user_auth_info.auth_key\n        form.status_verified.data = user_auth_info.status_verified\n        form.create_time.data = user_auth_info.create_time\n        form.update_time.data = user_auth_info.update_time\n        if request.method == 'GET':\n            form.auth_secret.data = ''\n    if request.method == 'POST':\n        if form.validate_on_submit():\n            # 权限校验\n            condition = {\n                'id': form.id.data,\n                'user_id': current_user.id,\n                'type_auth': TYPE_AUTH_ACCOUNT,\n            }\n            op_right = get_user_auth_row(**condition)\n            if not op_right:\n                flash(u'修改失败', 'warning')\n                return redirect(url_for('index'))\n\n            current_time = datetime.utcnow()\n            user_auth_data = {\n                # 'type_auth': AUTH_TYPE_ACCOUNT,\n                # 'auth_key': form.auth_key.data,\n                # 'status_verified': form.status_verified.data,\n                'update_time': current_time,\n            }\n            if form.auth_secret.data:\n                user_auth_data['auth_secret'] = md5(form.auth_secret.data)\n                result = edit_user_auth(form.id.data, user_auth_data)\n                if result:\n                    flash(u'修改成功', 'success')\n                    return redirect(url_for('.auth'))\n                else:\n                    flash(u'信息不变', 'info')\n            else:\n                flash(u'信息不变', 'info')\n        else:\n            flash(u'修改失败', 'warning')\n        # flash(form.errors, 'warning')  # 调试打开\n\n    # flash(u'Hello, %s' % current_user.id, 'info')  # 测试打开\n    return render_template('user/auth.html', title='auth', form=form, team_tree=team_tree)\n\n\n@bp_user.route('/bank/', methods=['GET', 'POST'])\n@login_required\ndef bank():\n    \"\"\"\n    银行信息\n    :return:\n    \"\"\"\n    # 获取团队成员三级树形结构\n    team_tree = get_team_tree(current_user.id)\n\n    form = UserBankForm(request.form)\n    bank_info = get_user_bank_row_by_id(current_user.id)\n\n    if bank_info:\n        form.status_verified.data = bank_info.status_verified\n        form.create_time.data = bank_info.create_time\n        form.update_time.data = bank_info.update_time\n        if request.method == 'GET':\n            form.account_name.data = bank_info.account_name\n            form.bank_name.data = bank_info.bank_name\n            form.bank_address.data = bank_info.bank_address\n            form.bank_account.data = bank_info.bank_account\n    if request.method == 'POST':\n        if form.validate_on_submit():\n            current_time = datetime.utcnow()\n            bank_data = {\n                'user_id': current_user.id,\n                'account_name': form.account_name.data,\n                'bank_name': form.bank_name.data,\n                'bank_address': form.bank_address.data,\n                'bank_account': form.bank_account.data,\n                # 'status_verified': form.status_verified.data,\n                'update_time': current_time,\n            }\n            if bank_info:\n                result = edit_user_bank(current_user.id, bank_data)\n            else:\n                bank_data['create_time'] = current_time\n                result = add_user_bank(bank_data)\n\n            if result:\n                flash(u'修改成功', 'success')\n            else:\n                flash(u'信息不变', 'info')\n        else:\n            flash(u'修改失败', 'warning')\n        # flash(form.errors, 'warning')  # 调试打开\n\n    # flash(u'Hello, %s' % current_user.id, 'info')  # 测试打开\n    return render_template('user/bank.html', title='bank', form=form, team_tree=team_tree)\n\n\n@bp_user.route('/profile/', methods=['GET', 'POST'])\n@login_required\ndef profile():\n    \"\"\"\n    用户基本信息\n    \"\"\"\n    # 获取团队成员三级树形结构\n    team_tree = get_team_tree(current_user.id)\n\n    form = UserProfileForm(request.form)\n    user_info = get_user_profile_row_by_id(current_user.id)\n\n    if user_info:\n        form.user_pid.data = user_info.user_pid\n        form.nickname.data = user_info.nickname\n        form.avatar_url.data = user_info.avatar_url\n        form.create_time.data = user_info.create_time\n        form.update_time.data = user_info.update_time\n        if request.method == 'GET':\n            form.area_id.data = user_info.area_id\n            form.area_code.data = user_info.area_code\n            form.phone.data = user_info.phone\n            form.email.data = user_info.email\n            form.birthday.data = user_info.birthday\n            form.real_name.data = user_info.real_name\n            form.id_card.data = user_info.id_card\n    if request.method == 'POST':\n        if form.validate_on_submit():\n            current_time = datetime.utcnow()\n            # 手机号码国际化\n            area_id = form.area_id.data\n            area_code = area_code_map.get(area_id, '86')\n            user_data = {\n                'email': form.email.data,\n                'area_id': area_id,\n                'area_code': area_code,\n                'phone': form.phone.data,\n                'birthday': form.birthday.data,\n                'id_card': form.id_card.data,\n                'update_time': current_time,\n            }\n            result = edit_user_profile(current_user.id, user_data)\n\n            if result:\n                flash(u'修改成功', 'success')\n                return redirect(url_for('.profile'))\n            else:\n                flash(u'信息不变', 'info')\n        else:\n            flash(u'修改失败', 'warning')\n        # flash(form.errors, 'warning')  # 调试打开\n\n    # flash(u'Hello, %s' % current_user.id, 'info')  # 测试打开\n    return render_template('user/profile.html', title='profile', form=form, team_tree=team_tree)\n\n\n@bp_user.route('/setting/', methods=['GET', 'POST'])\n@login_required\ndef setting():\n    \"\"\"\n    设置\n    \"\"\"\n    # return \"Hello, World!\\nSetting!\"\n    form = UserProfileForm(request.form)\n    if request.method == 'GET':\n        from app_frontend.api.user_profile import get_user_profile_row_by_id\n        user_info = get_user_profile_row_by_id(current_user.id)\n        if user_info:\n            form.nickname.data = user_info.nickname\n            form.avatar_url.data = user_info.avatar_url\n            form.email.data = user_info.email\n            form.phone.data = user_info.phone\n            form.birthday.data = user_info.birthday\n            form.create_time.data = user_info.create_time\n            form.update_time.data = user_info.update_time\n            # form.last_ip.data = user_info.last_ip\n    if request.method == 'POST':\n        if form.validate_on_submit():\n            # todo 判断邮箱是否重复\n            from app_frontend.api.user import edit_user\n            from datetime import datetime\n            user_info = {\n                'nickname': form.nickname.data,\n                'avatar_url': form.avatar_url.data,\n                'email': form.email.data,\n                'phone': form.phone.data,\n                'birthday': form.birthday.data,\n                'update_time': datetime.utcnow(),\n            }\n            result = edit_user(current_user.id, user_info)\n            if result == 1:\n                flash(u'修改成功', 'success')\n            if result == 0:\n                flash(u'修改失败', 'warning')\n        flash(form.errors, 'warning')  # 调试打开\n    # flash(u'Hello, %s' % current_user.id, 'info')  # 测试打开\n    return render_template('./setting.html', title='setting', form=form)\n\n\n@bp_user.route('/team/')\n@bp_user.route('/team/<int:page>/')\n@login_required\ndef team(page=1):\n    \"\"\"\n    团队\n    :param page:\n    :return:\n    \"\"\"\n    condition = {\n        'user_pid': current_user.id\n    }\n    status_active = request.args.get('status_active', '', type=str)\n    status_lock = request.args.get('status_lock', '', type=str)\n    if status_active:\n        condition['status_active'] = status_active\n    if status_lock:\n        condition['status_lock'] = status_lock\n\n    pagination = get_user_team_rows(\n        page,\n        PER_PAGE_FRONTEND,\n        **condition)\n    return render_template('user/team.html', title='team', pagination=pagination)\n\n\n@bp_user.route('/ajax_user_active/', methods=['GET', 'POST'])\n@login_required\ndef ajax_user_active():\n    \"\"\"\n    用户激活\n    :return:\n    \"\"\"\n    if request.method == 'POST' and request.is_xhr:\n        form = request.form\n        user_id = form.get('user_id', 0, type=int)\n\n        try:\n            # 参数校验\n            if not user_id:\n                raise Exception(u'参数错误，用户激活操作失败')\n\n            # 用户异常处理\n            user_info = get_user_row_by_id(user_id)\n\n            if not user_info:\n                raise Exception(u'异常操作，此用户不存在')\n            if user_info.status_delete == int(STATUS_DEL_OK):\n                raise Exception(u'异常操作，此用户已删除')\n            if user_info.status_active == int(STATUS_ACTIVE_OK):\n                raise Exception(u'异常操作，用户已经激活')\n\n            user_profile_info = get_user_profile_row_by_id(user_id)\n            if not user_profile_info:\n                raise Exception(u'异常操作，此用户不存在')\n            if user_profile_info.user_pid != current_user.id:\n                raise Exception(u'异常操作，无此用户权限')\n\n            # 更新激活状态\n            result = user_active(current_user.id, user_id)\n\n            if result:\n                current_time = datetime.utcnow()\n                # 加入用户激活自动监测锁定队列\n                q = RabbitDelayQueue(\n                    # exchange=app.config['EXCHANGE_NAME'],\n                    exchange='amq.direct',\n                    queue_name='lock_active_not_put',\n                    ttl=app.config['LOCK_ACTIVE_NOT_PUT_TTL']\n                )\n                q.put({'user_id': user_id, 'active_time': current_time.strftime('%Y-%m-%d %H:%M:%S')})\n                q.close_conn()\n\n                return json.dumps({'success': u'用户激活操作成功'})\n            else:\n                return json.dumps({'error': u'用户激活操作失败'})\n        except Exception as e:\n            print traceback.print_exc()\n            return json.dumps({'error': e.message})\n    abort(404)\n\n\n@bp_user.route('/ajax_add_active/', methods=['GET', 'POST'])\n@login_required\ndef ajax_add_active():\n    \"\"\"\n    赠送激活\n    :return:\n    \"\"\"\n    if request.method == 'POST' and request.is_xhr:\n        form = request.form\n        user_id = form.get('user_id', 0, type=int)\n        amount = form.get('amount', 1, type=int)\n\n        try:\n            # 参数校验\n            if not user_id:\n                raise Exception(u'参数错误，赠送激活数量操作失败')\n\n            if amount <=0:\n                raise Exception(u'参数错误，赠送激活数量操作失败')\n\n            # 用户异常处理\n            user_info = get_user_row_by_id(user_id)\n\n            if not user_info:\n                raise Exception(u'异常操作，此用户不存在')\n            if user_info.status_delete == int(STATUS_DEL_OK):\n                raise Exception(u'异常操作，此用户已删除')\n\n            user_profile_info = get_user_profile_row_by_id(user_id)\n            if not user_profile_info:\n                raise Exception(u'异常操作，此用户不存在')\n            if user_profile_info.user_pid != current_user.id:\n                raise Exception(u'异常操作，无此用户权限')\n\n            # 赠送激活数量\n            result = give_active(current_user.id, user_id, amount)\n\n            if result:\n                return json.dumps({'success': u'赠送激活数量操作成功'})\n            else:\n                return json.dumps({'error': u'赠送激活数量操作失败'})\n        except Exception as e:\n            print traceback.print_exc()\n            return json.dumps({'error': e.message})\n    abort(404)\n\n\n@bp_user.route('/ajax_self_active/', methods=['GET', 'POST'])\n@login_required\ndef ajax_self_active():\n    \"\"\"\n    自己激活\n    :return:\n    \"\"\"\n    if request.method == 'GET' and request.is_xhr:\n        # form = request.form\n        # user_id = form.get('user_id', 0, type=int)\n        user_id = current_user.id\n\n        try:\n            # 用户异常处理\n            if current_user.status_delete == int(STATUS_DEL_OK):\n                raise Exception(u'异常操作，此用户已删除')\n            if current_user.status_active == int(STATUS_ACTIVE_OK):\n                raise Exception(u'异常操作，用户已经激活')\n\n            # 更新激活状态\n            result = user_active(user_id, user_id)\n\n            if result:\n                current_time = datetime.utcnow()\n                # 加入用户激活自动监测锁定队列\n                q = RabbitDelayQueue(\n                    # exchange=app.config['EXCHANGE_NAME'],\n                    exchange='amq.direct',\n                    queue_name='lock_active_not_put',\n                    ttl=app.config['LOCK_ACTIVE_NOT_PUT_TTL']\n                )\n                q.put({'user_id': user_id, 'active_time': current_time.strftime('%Y-%m-%d %H:%M:%S')})\n                q.close_conn()\n\n                return json.dumps({'success': u'用户激活操作成功'})\n            else:\n                return json.dumps({'error': u'用户激活操作失败'})\n        except Exception as e:\n            print traceback.print_exc()\n            return json.dumps({'error': e.message})\n    abort(404)\n\n\n@bp_user.route('/ajax/get_sms_code/', methods=['GET', 'POST'])\n@login_required\ndef ajax_get_sms_code():\n    \"\"\"\n    获取短信验证码\n    :return:\n    \"\"\"\n    # 获取短信验证码\n    area_id = request.args.get('area_id', '', type=str)\n    area_code = area_code_map.get(area_id, '86')\n    mobile = request.args.get('phone', '', type=str)\n    mobile_iso = '%s%s' % (area_code, mobile)\n\n    sms_code = str(get_randint())\n    code_key = '%s:%s' % ('sms_code', 'edit')\n    session[code_key] = sms_code\n\n    sms_content = SMS_CODE_EDIT % sms_code\n    # sms_client = SmsChuangLanIsoApi(UN, PW)\n    # result = sms_client.send_international(mobile_iso, sms_content)\n\n    # 推送短信优先级队列\n    q = RabbitPriorityQueue(exchange=EXCHANGE_NAME, queue_name='send_sms_p')\n    q.put({'mobile': mobile_iso, 'sms_content': sms_content}, 20)\n\n    return json.dumps({'result': True})\n"
  },
  {
    "path": "app_frontend/views/wallet.py",
    "content": "#!/usr/bin/env python\n# encoding: utf-8\n\n\"\"\"\n@author: zhanghe\n@software: PyCharm\n@file: wallet.py\n@time: 2017/4/25 下午1:25\n\"\"\"\n\n\nfrom datetime import datetime\nfrom flask import redirect\nfrom flask import render_template, request, flash, g\nfrom flask import url_for\nfrom flask_login import current_user, login_required\n\nfrom app_frontend import app\nfrom app_frontend.api.user_profile import get_team_tree\nfrom app_frontend.models import User\nfrom app_frontend.api.wallet import get_wallet_rows\nfrom app_frontend.api.wallet_item import get_wallet_item_rows\n\nfrom flask import Blueprint\n\nPER_PAGE_FRONTEND = app.config['PER_PAGE_FRONTEND']\n\nbp_wallet = Blueprint('wallet', __name__, url_prefix='/wallet')\n\n\n@bp_wallet.route('/list/')\n@bp_wallet.route('/list/<int:page>/')\n@login_required\ndef lists(page=1):\n    \"\"\"\n    钱包列表\n    \"\"\"\n    # 获取团队成员三级树形结构\n    team_tree = get_team_tree(current_user.id)\n    pagination = get_wallet_item_rows(page, PER_PAGE_FRONTEND, **{'user_id': current_user.id})\n    return render_template('wallet/list.html', title='wallet_list', pagination=pagination, team_tree=team_tree)\n\n\n@bp_wallet.route('/add/', methods=['GET', 'POST'])\n@login_required\ndef add():\n    \"\"\"\n    创建钱包\n    :return:\n    \"\"\"\n    pass\n\n\n@bp_wallet.route('/del/', methods=['GET', 'POST'])\n@login_required\ndef delete():\n    \"\"\"\n    删除钱包\n    :return:\n    \"\"\"\n    pass\n\n\n@bp_wallet.route('/stats/', methods=['GET', 'POST'])\n@login_required\ndef stats():\n    \"\"\"\n    钱包统计\n    :return:\n    \"\"\"\n    pass\n"
  },
  {
    "path": "app_frontend/views/wechat.py",
    "content": "#!/usr/bin/env python\n# encoding: utf-8\n\n\"\"\"\n@author: zhanghe\n@software: PyCharm\n@file: wechat.py\n@time: 2017/5/8 下午2:12\n\"\"\"\n\n\ndef func():\n    pass\n\n\nclass Main(object):\n    def __init__(self):\n        pass\n\n\nif __name__ == '__main__':\n    pass\n"
  },
  {
    "path": "backup/batch_import.sh",
    "content": "#!/usr/bin/env bash\n\n# 定义参数\ndb_name='database_name'     # 远程数据库名称\ndb_user='xxxxxx'            # 登录用户\ndb_pass='xxxxxx'            # 登录密码\ndb_port='3306'              # 远程数据库端口\ndb_host='127.0.0.1'         # 远程数据库IP\n\ntable_name='table_name'     # 数据表名\ncolumn_list='id,name,date'  # 批量导入字段名称列表（有序）\n\ncsv_file='/tmp/batch_export.csv'\nsql_file='/tmp/batch_import.sql'\n\nrepeat_action='IGNORE'      # 对导入唯一键重复数据的处理（REPLACE/IGNORE）\n\n# 组装sql语句\n#echo \"use ${db_name};LOAD DATA LOCAL INFILE '${csv_file}' ${repeat_action} INTO TABLE ${table_name} FIELDS TERMINATED BY '\\t' ENCLOSED BY '\\\"' LINES TERMINATED BY '\\n' (${column_list});\" > ${sql_file}\n\n# 批量导入数据\n#time mysql -h ${db_host} -P ${db_port} -u ${db_user} -p${db_pass} < ${sql_file}\n\n# 查找目录下所有指定类型的文件\nfile_list=`ls /tmp`\nfor file in ${file_list}\ndo\n    if [ ${file##*.} == 'csv' ]\n    then\n        echo ${file}\n    fi\ndone\n"
  },
  {
    "path": "backup/data_test.sql",
    "content": "-- user 测试数据\nINSERT INTO `user`(id, nickname, email, phone, create_time, update_time) VALUES('1', 'Admin', 'admin@gmail.com', '13800001111', '2016-01-11 11:01:05', '2016-01-11 11:01:05');\nINSERT INTO `user`(id, nickname, email, phone, create_time, update_time) VALUES('2', 'Guest', 'guest@gmail.com', '13800002222', '2016-01-12 12:25:34', '2016-01-12 12:25:34');\nINSERT INTO `user`(id, nickname, email, phone, create_time, update_time) VALUES('3', 'Test', 'test@gmail.com', '13800003333', '2016-01-12 01:43:42', '2016-01-12 01:43:42');\n\n-- user_auth 测试数据\nINSERT INTO `user_auth`(user_id, auth_type, auth_key, auth_secret) VALUES('1', 'email', 'admin@gmail.com', '123456');\nINSERT INTO `user_auth`(user_id, auth_type, auth_key, auth_secret) VALUES('2', 'email', 'guest@gmail.com', '123456');\nINSERT INTO `user_auth`(user_id, auth_type, auth_key, auth_secret, verified) VALUES('3', 'email', 'test@gmail.com', '123456', '1');\n\n-- author 测试数据\nINSERT INTO author(`name`, email) VALUES('Mark', 'mark@gmail.com');\nINSERT INTO author(`name`, email) VALUES('Jacob', 'jacob@gmail.com');\nINSERT INTO author(`name`, email) VALUES('Larry', 'larry@gmail.com');\nINSERT INTO author(`name`, email) VALUES('Tom', 'tom@gmail.com');\nINSERT INTO author(`name`, email) VALUES('Lily', 'lily@gmail.com');\n\n-- blog 测试数据\nINSERT INTO blog(author, title, pub_date) VALUES('Mark', 'The old man and the sea', '2016-01-11 11:01:05');\nINSERT INTO blog(author, title, pub_date) VALUES('Jacob', 'The fault in our stars', '2016-01-11 20:23:27');\nINSERT INTO blog(author, title, pub_date) VALUES('Larry', 'The Great Gatsby', '2016-01-11 23:15:18');\nINSERT INTO blog(author, title, pub_date) VALUES('Tom', 'Sense and Sensibility', '2016-01-12 12:25:34');\nINSERT INTO blog(author, title, pub_date) VALUES('Tom', 'Pride and Prejudice', '2016-01-12 13:17:25');\nINSERT INTO blog(author, title, pub_date) VALUES('Lily', 'Game of Thrones', '2016-01-12 14:53:01');\nINSERT INTO blog(author, title, pub_date) VALUES('Mark', 'Charlie and the Chocolate Factory', '2016-01-12 15:13:17');\nINSERT INTO blog(author, title, pub_date) VALUES('Larry', 'Harry Potter and the Sorcerer''s Stone', '2016-01-12 19:32:15');\nINSERT INTO blog(author, title, pub_date) VALUES('Larry', 'The house on mango street', '2016-01-12 01:43:42');\nINSERT INTO blog(author, title, pub_date) VALUES('Jacob', 'And then there were none', '2016-01-13 16:17:32');\n"
  },
  {
    "path": "backup/db_dump.sh",
    "content": "#!/usr/bin/env bash\n\n# 备份数据\n\nbase_path=`dirname $0`/../\ncd ${base_path}\nsqlite3 flask.db \".dump\" > schema.dump.sql\n"
  },
  {
    "path": "backup/db_init.sh",
    "content": "#!/usr/bin/env bash\n\n\nbase_path=`dirname $0`/../\ncd ${base_path}\n# 初始化数据库\nsqlite3 flask.db < schema.sql\n# 添加测试数据\nsqlite3 flask.db < etc/data_test.sql\n"
  },
  {
    "path": "backup/db_restore.sh",
    "content": "#!/usr/bin/env bash\n\n# 恢复数据\n\nbase_path=`dirname $0`/../\ncd ${base_path}\n# 清空历史库\nrm -f flask.db\n# 恢复数据库\nsqlite3 flask.db < schema.dump.sql\n# 重建 model\n./etc/model_create.sh\n"
  },
  {
    "path": "backup/model_create.sh",
    "content": "#!/usr/bin/env bash\n\n\nbase_path=`dirname $0`/../\ncd ${base_path}\n# 生成 model\nsqlacodegen sqlite:///flask.db --outfile app/models.py\n# 替换 model 关键内容\nsed -i \"s/from sqlalchemy.ext.declarative import declarative_base/from database import db/g\" app/models.py\nsed -i \"s/Base = declarative_base()/Base = db.Model/g\" app/models.py\n"
  },
  {
    "path": "backup/run.sh",
    "content": "#!/usr/bin/env bash\n\nbase_path=`dirname $0`/../\n\ncd ${base_path}\n\nsource .env/bin/activate\n\nsupervisord -c etc/supervisord.conf\n\nsupervisorctl -c etc/supervisord.conf reload\n\nsupervisorctl -c etc/supervisord.conf stop all\n\nsupervisorctl -c etc/supervisord.conf start all\n\nsudo ln -s -b `pwd`/etc/nginx.conf /etc/nginx/conf.d/flask_app_nginx.conf\n\nsudo /etc/init.d/nginx reload\n"
  },
  {
    "path": "backup/schema.dump.sql",
    "content": "PRAGMA foreign_keys=OFF;\nBEGIN TRANSACTION;\nCREATE TABLE user (\n  id          INTEGER PRIMARY KEY  AUTOINCREMENT,\n  nickname    VARCHAR(20),\n  avatar_url  VARCHAR(80),\n  email       VARCHAR(20),\n  phone       VARCHAR(20),\n  birthday    DATE,\n  create_time DATETIME    NOT NULL DEFAULT CURRENT_TIMESTAMP,\n  update_time DATETIME    NOT NULL DEFAULT CURRENT_TIMESTAMP,\n  last_ip     VARCHAR(15)\n);\nINSERT INTO \"user\" VALUES(1,'Admin',NULL,'admin@gmail.com','13800001111',NULL,'2016-01-11 11:01:05','2016-01-11 11:01:05',NULL);\nINSERT INTO \"user\" VALUES(2,'Guest',NULL,'guest@gmail.com','13800002222',NULL,'2016-01-12 12:25:34','2016-01-12 12:25:34',NULL);\nINSERT INTO \"user\" VALUES(3,'Test',NULL,'test@gmail.com','13800003333',NULL,'2016-01-12 01:43:42','2016-01-12 01:43:42','127.0.0.1');\nCREATE TABLE user_auth (\n  id           INTEGER PRIMARY KEY   AUTOINCREMENT,\n  user_id      INTEGER      NOT NULL,\n  auth_type    VARCHAR(20)  NOT NULL,\n  auth_key     VARCHAR(64)  NOT NULL,\n  auth_secret  VARCHAR(256) NOT NULL,\n  verified     TINYINT      DEFAULT 0\n);\nINSERT INTO \"user_auth\" VALUES(1,1,'email','admin@gmail.com','123456',0);\nINSERT INTO \"user_auth\" VALUES(2,2,'email','guest@gmail.com','123456',0);\nINSERT INTO \"user_auth\" VALUES(3,3,'email','test@gmail.com','123456',1);\nCREATE TABLE author (\n  id    INTEGER PRIMARY KEY AUTOINCREMENT,\n  name  VARCHAR(20) NOT NULL,\n  email VARCHAR(20) NOT NULL\n);\nINSERT INTO \"author\" VALUES(1,'Mark','mark@gmail.com');\nINSERT INTO \"author\" VALUES(2,'Jacob','jacob@gmail.com');\nINSERT INTO \"author\" VALUES(3,'Larry','larry@gmail.com');\nINSERT INTO \"author\" VALUES(4,'Tom','tom@gmail.com');\nINSERT INTO \"author\" VALUES(5,'Lily','lily@gmail.com');\nCREATE TABLE blog (\n  id        INTEGER PRIMARY KEY  AUTOINCREMENT,\n  author    VARCHAR(20) NOT NULL,\n  title     VARCHAR(40) NOT NULL,\n  pub_date  DATE,\n  add_time  DATETIME             DEFAULT CURRENT_TIMESTAMP,\n  edit_time DATETIME             DEFAULT CURRENT_TIMESTAMP\n);\nINSERT INTO \"blog\" VALUES(1,'Mark','The old man and the sea','2016-01-11 11:01:05','2016-05-26 05:26:08','2016-05-26 05:26:08');\nINSERT INTO \"blog\" VALUES(2,'Jacob','The fault in our stars','2016-01-11 20:23:27','2016-05-26 05:26:08','2016-05-26 05:26:08');\nINSERT INTO \"blog\" VALUES(3,'Larry','The Great Gatsby','2016-01-11 23:15:18','2016-05-26 05:26:08','2016-05-26 05:26:08');\nINSERT INTO \"blog\" VALUES(4,'Tom','Sense and Sensibility','2016-01-12 12:25:34','2016-05-26 05:26:08','2016-05-26 05:26:08');\nINSERT INTO \"blog\" VALUES(5,'Tom','Pride and Prejudice','2016-01-12 13:17:25','2016-05-26 05:26:08','2016-05-26 05:26:08');\nINSERT INTO \"blog\" VALUES(6,'Lily','Game of Thrones','2016-01-12 14:53:01','2016-05-26 05:26:08','2016-05-26 05:26:08');\nINSERT INTO \"blog\" VALUES(7,'Mark','Charlie and the Chocolate Factory','2016-01-12 15:13:17','2016-05-26 05:26:08','2016-05-26 05:26:08');\nINSERT INTO \"blog\" VALUES(8,'Larry','Harry Potter and the Sorcerer''s Stone','2016-01-12 19:32:15','2016-05-26 05:26:09','2016-05-26 05:26:09');\nINSERT INTO \"blog\" VALUES(9,'Larry','The house on mango street','2016-01-12 01:43:42','2016-05-26 05:26:09','2016-05-26 05:26:09');\nINSERT INTO \"blog\" VALUES(10,'Jacob','And then there were none','2016-01-13 16:17:32','2016-05-26 05:26:09','2016-05-26 05:26:09');\nDELETE FROM sqlite_sequence;\nINSERT INTO \"sqlite_sequence\" VALUES('user',3);\nINSERT INTO \"sqlite_sequence\" VALUES('user_auth',3);\nINSERT INTO \"sqlite_sequence\" VALUES('author',5);\nINSERT INTO \"sqlite_sequence\" VALUES('blog',10);\nCOMMIT;\n"
  },
  {
    "path": "backup/schema.sql",
    "content": "DROP TABLE IF EXISTS user;\nCREATE TABLE user (\n  id          INTEGER PRIMARY KEY  AUTOINCREMENT,\n  nickname    VARCHAR(20),\n  avatar_url  VARCHAR(80),\n  email       VARCHAR(20),\n  phone       VARCHAR(20),\n  birthday    DATE,\n  create_time DATETIME    NOT NULL DEFAULT CURRENT_TIMESTAMP,\n  update_time DATETIME    NOT NULL DEFAULT CURRENT_TIMESTAMP,\n  last_ip     VARCHAR(15)\n);\n\nDROP TABLE IF EXISTS user_auth;\nCREATE TABLE user_auth (\n  id           INTEGER PRIMARY KEY   AUTOINCREMENT,\n  user_id      INTEGER      NOT NULL,\n  auth_type    VARCHAR(20)  NOT NULL,\n  auth_key     VARCHAR(64)  NOT NULL,\n  auth_secret  VARCHAR(256) NOT NULL,\n  verified     TINYINT      DEFAULT 0\n);\n\nDROP TABLE IF EXISTS author;\nCREATE TABLE author (\n  id    INTEGER PRIMARY KEY AUTOINCREMENT,\n  name  VARCHAR(20) NOT NULL,\n  email VARCHAR(20) NOT NULL\n);\n\nDROP TABLE IF EXISTS blog;\nCREATE TABLE blog (\n  id        INTEGER PRIMARY KEY  AUTOINCREMENT,\n  author    VARCHAR(20) NOT NULL,\n  title     VARCHAR(40) NOT NULL,\n  pub_date  DATE,\n  add_time  DATETIME             DEFAULT CURRENT_TIMESTAMP,\n  edit_time DATETIME             DEFAULT CURRENT_TIMESTAMP\n);\n\nDROP TABLE IF EXISTS product;\nCREATE TABLE product (\n  id        INTEGER PRIMARY KEY  AUTOINCREMENT,\n  title     VARCHAR(40) NOT NULL,\n  stock     INTEGER NOT NULL DEFAULT 0,\n  create_time DATETIME             DEFAULT CURRENT_TIMESTAMP,\n  update_time DATETIME             DEFAULT CURRENT_TIMESTAMP\n);\n\nDROP TABLE IF EXISTS product_order;\nCREATE TABLE product_order (\n  id        INTEGER PRIMARY KEY  AUTOINCREMENT,\n  buyer_uid        INTEGER,\n  shop_id        INTEGER,\n  amount     DECIMAL(10, 2) NOT NULL DEFAULT 0.00,\n  pay_status  TINYINT(1) NOT NULL DEFAULT 0,\n  create_time DATETIME             DEFAULT CURRENT_TIMESTAMP,\n  update_time DATETIME             DEFAULT CURRENT_TIMESTAMP\n);\n"
  },
  {
    "path": "backup/test.py",
    "content": "#!/usr/bin/env python\n# encoding: utf-8\n\n\"\"\"\n@author: zhanghe\n@software: PyCharm\n@file: test.py\n@time: 2017/3/10 下午10:58\n\"\"\"\n\n\nfrom app_frontend import app, login_manager, oauth_github, oauth_qq, oauth_weibo, send_cloud_client, qi_niu_client\nfrom flask import render_template, request, url_for, send_from_directory, session, flash, redirect, g, jsonify, Markup, abort\nfrom app_frontend.forms import RegForm, LoginForm, BlogAddForm, BlogEditForm, UserForm\nfrom app_frontend.login import LoginUser\nfrom flask_login import login_user, logout_user, current_user, login_required\nimport os\nimport json\nfrom werkzeug.contrib.cache import SimpleCache\ncache = SimpleCache()  # 默认最大支持500个key, 超时时间5分钟, 参数可配置\n\n\n@login_manager.user_loader\ndef load_user(user_id):\n    \"\"\"\n    如果 user_id 无效，它应该返回 None （ 而不是抛出异常 ）。\n    :param user_id:\n    :return:\n    \"\"\"\n    return LoginUser.query.get(int(user_id))\n\n\n@app.before_request\ndef before_request():\n    \"\"\"\n    当前用户信息\n    \"\"\"\n    g.user = current_user\n\n\n@app.route('/favicon.ico')\ndef favicon():\n    \"\"\"\n    首页ico图标\n    \"\"\"\n    return send_from_directory(os.path.join(app.root_path, 'static'),\n                               'img/favicon.ico', mimetype='image/vnd.microsoft.icon')\n\n\n@app.route('/')\n@app.route('/index')\ndef index():\n    \"\"\"\n    网站首页\n    \"\"\"\n    # return \"Hello, World!\"\n    return render_template('index.html', title='home')\n\n\n@app.route('/about')\ndef about():\n    \"\"\"\n    关于网站\n    \"\"\"\n    # return \"Hello, World!\\nAbout!\"\n    return render_template('about.html', title='about')\n\n\n@app.route('/contact')\ndef contact():\n    \"\"\"\n    联系方式\n    \"\"\"\n    # return \"Hello, World!\\nContact!\"\n    return render_template('contact.html', title='contact')\n\n\n@app.route('/blog/list/')\n@app.route('/blog/list/<int:page>/')\ndef blog_list(page=1):\n    \"\"\"\n    博客列表\n    \"\"\"\n    # return \"Hello, World!\\nBlog List!\"\n    from blog import get_blog_rows\n    per_page = 8\n    pagination = get_blog_rows(page, per_page)\n    return render_template('blog/list.html', title='blog_list', pagination=pagination)\n\n\n@app.route('/blog/list_edit/')\n@app.route('/blog/list_edit/<int:page>/')\n@login_required\ndef blog_list_edit(page=1):\n    \"\"\"\n    博客列表(带编辑)\n    \"\"\"\n    # return \"Hello, World!\\nBlog List!\"\n    from blog import get_blog_rows\n    per_page = 8\n    pagination = get_blog_rows(page, per_page)\n    return render_template('blog/list_edit.html', title='blog_list', pagination=pagination)\n\n\n@app.route('/blog/ajax/list_edit/', methods=['GET', 'POST'])\n@login_required\ndef blog_ajax_list_edit():\n    \"\"\"\n    博客编辑\n    \"\"\"\n    if request.method == 'POST' and request.is_xhr:\n        form = request.form\n        from blog import edit_blog\n        from datetime import datetime\n        blog_id = form.get('id', 0, type=int)\n        blog_info = {\n            'author': form.get('author'),\n            'title': form.get('title'),\n            'pub_date': datetime.strptime(form.get('pub_date'), \"%Y-%m-%d\").date(),\n            'edit_time': datetime.utcnow(),\n        }\n        result = edit_blog(blog_id, blog_info)\n        if result == 1:\n            return json.dumps({'success': u'Edit Success'})\n        if result == 0:\n            return json.dumps({'error': u'Edit Error'})\n    abort(404)\n\n\n@app.route('/blog/new/')\n@app.route('/blog/new/<int:page>/')\ndef blog_new(page=1):\n    \"\"\"\n    最新博客\n    \"\"\"\n    # return \"Hello, World!\\nBlog New!\"\n    from blog import get_blog_rows, get_blog_list_counter, get_blog_list_container_status\n    per_page = 8\n    pagination = get_blog_rows(page, per_page)\n    id_list = [item.id for item in pagination.items]\n    blog_counter_list = get_blog_list_counter(id_list)\n    # 状态设置\n    login_user_id = g.user.get_id()\n    blog_container_status_list = get_blog_list_container_status(id_list, login_user_id)\n    return render_template(\n        'blog/new.html',\n        title='blog_new',\n        pagination=pagination,\n        blog_counter_list=blog_counter_list,\n        blog_container_status_list=blog_container_status_list\n    )\n\n\n@app.route('/blog/hot/')\n@app.route('/blog/hot/<int:page>/')\ndef blog_hot(page=1):\n    \"\"\"\n    热门博客\n    \"\"\"\n    # return \"Hello, World!\\nBlog Hot!\"\n    from blog import get_blog_rows\n    per_page = 8\n    pagination = get_blog_rows(page, per_page)\n    return render_template('blog/hot.html', title='blog_hot', pagination=pagination)\n\n\n@app.route('/blog/edit/<int:blog_id>/', methods=['GET', 'POST'])\n@login_required\ndef blog_edit(blog_id):\n    \"\"\"\n    博客编辑\n    \"\"\"\n    # return \"Hello, World!\\nBlog Edit!\"\n    form = BlogEditForm(request.form)\n    if request.method == 'GET':\n        from blog import get_blog_row_by_id\n        blog_info = get_blog_row_by_id(blog_id)\n        if blog_info:\n            form.author.data = blog_info.author\n            form.title.data = blog_info.title\n            form.pub_date.data = blog_info.pub_date\n        else:\n            return redirect(url_for('index'))\n    if request.method == 'POST':\n        if form.validate_on_submit():\n            from blog import edit_blog\n            from datetime import datetime\n            blog_info = {\n                'author': form.author.data,\n                'title': form.title.data,\n                'pub_date': form.pub_date.data,\n                'edit_time': datetime.utcnow(),\n            }\n            result = edit_blog(blog_id, blog_info)\n            if result == 1:\n                flash(u'Edit Success', 'success')\n                return redirect(request.args.get('next') or url_for('blog_list'))\n            if result == 0:\n                flash(u'Edit Failed', 'warning')\n        flash(form.errors, 'warning')  # 调试打开\n    flash(u'Hello, %s' % current_user.email, 'info')  # 测试打开\n    return render_template('blog/edit.html', title='blog_edit', blog_id=blog_id, form=form)\n\n\n@app.route('/blog/add/', methods=['GET', 'POST'])\n@login_required\ndef blog_add():\n    \"\"\"\n    博客添加\n    \"\"\"\n    # return \"Hello, World!\\nBlog Add!\"\n    form = BlogAddForm(request.form)\n    if request.method == 'POST':\n        if form.validate_on_submit():\n            from blog import add_blog\n            from datetime import datetime\n            current_time = datetime.utcnow()\n            blog_info = {\n                'author': form.author.data,\n                'title': form.title.data,\n                'pub_date': form.pub_date.data,\n                'add_time': current_time,\n                'edit_time': current_time,\n            }\n            result = add_blog(blog_info)\n            if result is None:\n                flash(u'Add Failed', 'warning')\n            else:\n                flash(u'Add Success', 'success')\n                return redirect(url_for('blog_edit', blog_id=result))\n        flash(form.errors, 'warning')  # 调试打开\n    # flash(u'Hello, %s' % current_user.email, 'info')  # 测试打开\n    return render_template('blog/add.html', title='blog_add', form=form)\n\n\n@app.route('/blog/del/', methods=['GET', 'POST'])\ndef blog_delete():\n    \"\"\"\n    博客删除\n    \"\"\"\n    if request.method == 'GET':\n        login_user_id = g.user.get_id()\n        # 权限判断，只能删除自己的 blog todo\n        if login_user_id is None:\n            return jsonify(result=False)\n        blog_id = request.args.get('blog_id', 0, type=int)\n        from blog import delete_blog\n        result = delete_blog(blog_id)\n        if result == 1:\n            return jsonify(result=True)\n        else:\n            return jsonify(result=False)\n\n\n@app.route('/blog/stat/', methods=['GET', 'POST'])\ndef blog_stat():\n    \"\"\"\n    博客统计\n    http://localhost:5000/blog/stat/?blog_id=2&stat_type=favor&num=2\n    :return:\n    \"\"\"\n    if request.method == 'GET':\n        login_user_id = g.user.get_id()\n        if login_user_id is None:\n            return jsonify(result=False)\n        blog_id = request.args.get('blog_id', 0, type=int)\n        stat_type = request.args.get('stat_type', '', type=str)\n        # num = request.args.get('num', 0, type=int)\n        from tools.stat import set_blog_stat\n        result = set_blog_stat(stat_type, login_user_id, blog_id)\n        return jsonify(result)\n\n\n@app.route('/reg/', methods=['GET', 'POST'])\ndef reg():\n    \"\"\"\n    注册\n    \"\"\"\n    # return \"Hello, World!\\nReg!\"\n    form = RegForm()\n    if request.method == 'POST':\n        if form.validate_on_submit():\n            # 添加用户信息\n            from user import add_user\n            from datetime import datetime\n            current_time = datetime.utcnow()\n            user_data = {\n                'email': form.email.data,\n                'create_time': current_time,\n                'update_time': current_time,\n                'last_ip': request.headers.get('X-Forwarded-For', request.remote_addr)\n            }\n            user_id = add_user(user_data)\n            # 添加授权信息\n            from user_auth import add_user_auth\n            user_auth_data = {\n                'user_id': user_id,\n                'auth_type': 'email',\n                'auth_key': form.email.data,\n                'auth_secret': form.password.data\n            }\n            user_auth_id = add_user_auth(user_auth_data)\n            if user_auth_id:\n                flash(u'%s, Thanks for registering' % form.email.data, 'success')\n                # todo 发送邮箱校验邮件\n                email_validate_content = {\n                    'mail_from': 'System Support<support@zhendi.me>',\n                    'mail_to': form.email.data,\n                    'mail_subject': 'verify reg email',\n                    'mail_html': 'verify reg email address in mailbox'\n                }\n                send_email_result = send_cloud_client.mail_send(**email_validate_content)\n                # 调试邮件发送结果\n                if send_email_result.get('result') is False:\n                    flash(send_email_result.get('message'), 'warning')\n                else:\n                    flash(send_email_result.get('message'), 'success')\n                # https://www.***.com/email/signup/uuid\n            else:\n                flash(u'%s, Sorry, register error' % form.email.data, 'warning')\n            return redirect(url_for('login'))\n        # 闪现消息 success info warning danger\n        flash(form.errors, 'warning')  # 调试打开\n    return render_template('reg.html', title='reg', form=form)\n\n\n@app.route('/agreement/')\ndef agreement():\n    \"\"\"\n    注册协议\n    :return:\n    \"\"\"\n    return 'agreement'\n\n\n@app.route('/email/sign')\ndef email_sign():\n    \"\"\"\n    邮箱签名(带过期时间)\n    http://localhost:5000/email/sign?email=zhang_he06@163.com\n    \"\"\"\n    email = request.args.get('email', '')\n    from itsdangerous import TimestampSigner\n    s = TimestampSigner(app.config['SECRET_KEY'])\n    return s.sign(email)\n\n\n@app.route('/email/check')\ndef email_check():\n    \"\"\"\n    校验邮箱有效性\n    http://localhost:5000/email/check?sign=zhang_he06@163.com.ChstqQ.5jODirLaRF2yU0CLtZz2EmoHt4c\n    \"\"\"\n    sign = request.args.get('sign', '')\n    from itsdangerous import TimestampSigner, SignatureExpired, BadTimeSignature\n    s = TimestampSigner(app.config['SECRET_KEY'])\n    try:\n        # email = s.unsign(sign, max_age=5)  # 5秒过期\n        email = s.unsign(sign, max_age=30*24*60*60)  # １个月过期\n        # return email\n        # 校验通过，更新邮箱验证状态\n        from user_auth import update_user_auth_rows\n        result = update_user_auth_rows({'verified': 1}, **{'auth_type': 'email', 'auth_key': email})\n        if result == 1:\n            flash(u'%s, Your mailbox has been verified' % email, 'success')\n            return redirect(url_for('login'))\n        else:\n            flash(u'%s, Sorry, Your mailbox validation failed' % email, 'warning')\n    except SignatureExpired as e:\n        # 处理签名超时\n        flash(e.message, 'warning')\n    except BadTimeSignature as e:\n        # 处理签名错误\n        flash(e.message, 'warning')\n    return redirect(url_for('reg.index'))\n\n\n@app.route('/login/', methods=['GET', 'POST'])\ndef login():\n    \"\"\"\n    登录\n    \"\"\"\n    if g.user is not None and g.user.is_authenticated:\n        return redirect(url_for('index'))\n    form = LoginForm()\n    if request.method == 'POST':\n        if form.validate_on_submit():\n            from user_auth import get_user_auth_row\n            condition = {\n                'auth_type': 'email',\n                'auth_key': form.email.data,\n                'auth_secret': form.password.data\n            }\n            user_auth_info = get_user_auth_row(**condition)\n            if user_auth_info is None:\n                flash(u'%s, You were logged failed' % form.email.data, 'warning')\n                return render_template('login.html', title='login', form=form)\n            if user_auth_info.verified == 0:\n                flash(u'%s, Please verify email address in mailbox' % form.email.data, 'warning')\n                return render_template('login.html', title='login', form=form)\n            # session['logged_in'] = True\n            # 用户通过验证后，记录登入IP\n            from user import edit_user\n            edit_user(user_auth_info.user_id, {'last_ip': request.headers.get('X-Forwarded-For', request.remote_addr)})\n            # 用 login_user 函数来登入他们\n            from user import get_user_row_by_id\n            login_user(get_user_row_by_id(user_auth_info.user_id))\n            flash(u'%s, You were logged in' % form.email.data, 'success')\n            return redirect(request.args.get('next') or url_for('index'))\n        flash(form.errors, 'warning')  # 调试打开\n    return render_template('login.html', title='login', form=form)\n\n\n# @app.route('/logout')\n# def logout():\n#     session.pop('logged_in', None)\n#     flash(u'You were logged out')\n#     return redirect(url_for('index'))\n\n@app.route('/logout/')\ndef logout():\n    \"\"\"\n    退出登录\n    \"\"\"\n    logout_user()\n    session.pop('qq_token', None)\n    session.pop('weibo_token', None)\n    session.pop('github_token', None)\n    flash(u'You were logged out', 'info')\n    return redirect(url_for('index'))\n\n\n@app.route('/setting/', methods=['GET', 'POST'])\n@login_required\ndef setting():\n    \"\"\"\n    设置\n    \"\"\"\n    # return \"Hello, World!\\nSetting!\"\n    form = UserForm(request.form)\n    if request.method == 'GET':\n        from user import get_user_row_by_id\n        user_info = get_user_row_by_id(current_user.id)\n        if user_info:\n            form.nickname.data = user_info.nickname\n            form.avatar_url.data = user_info.avatar_url\n            form.email.data = user_info.email\n            form.phone.data = user_info.phone\n            form.birthday.data = user_info.birthday\n            form.create_time.data = user_info.create_time\n            form.update_time.data = user_info.update_time\n            form.last_ip.data = user_info.last_ip\n    if request.method == 'POST':\n        if form.validate_on_submit():\n            # todo 判断邮箱是否重复\n            from user import edit_user\n            from datetime import datetime\n            user_info = {\n                'nickname': form.nickname.data,\n                'avatar_url': form.avatar_url.data,\n                'email': form.email.data,\n                'phone': form.phone.data,\n                'birthday': form.birthday.data,\n                'update_time': datetime.utcnow(),\n                'last_ip': request.headers.get('X-Forwarded-For', request.remote_addr),\n            }\n            result = edit_user(current_user.id, user_info)\n            if result == 1:\n                flash(u'Edit Success', 'success')\n            if result == 0:\n                flash(u'Edit Failed', 'warning')\n        flash(form.errors, 'warning')  # 调试打开\n    flash(u'Hello, %s' % current_user.email, 'info')  # 测试打开\n    return render_template('setting.html', title='setting', form=form)\n\n\n@app.route('/search/', methods=['GET', 'POST'])\ndef search():\n    \"\"\"\n    搜索\n    \"\"\"\n    return 'search result!'\n\n\n@app.route(\"/email/\")\ndef send_email():\n    \"\"\"\n    邮件发送\n    \"\"\"\n    try:\n        from emails import send_email\n        msg = 'This is a test email!'\n        send_email(\n            subject=u'邮件主题',\n            sender=(u'系统邮箱', 'zhang_he06@163.com'),\n            recipients=[(u'尊敬的用户', 'zhang_he06@163.com')],\n            html_body=render_template('email.html', message=msg)\n        )\n        return jsonify({'success': u'邮件发送成功'})\n    except Exception, e:\n        return jsonify({'error': e.message})\n\n\n@app.route(\"/test\")\ndef test():\n    \"\"\"\n    测试\n    \"\"\"\n    try:\n        raise Exception('error test')\n    except Exception as e:\n        import logging\n        logging.error(e)\n\n\n@app.route(\"/test_client_ip\")\ndef test_client_ip():\n    \"\"\"\n    测试客户端来源ip\n    http://localhost:5000/test_client_ip\n    curl -H \"X-Forwarded-For: 1.2.3.4\" http://localhost:5000/test_client_ip\n    \"\"\"\n    if not request.headers.getlist(\"X-Forwarded-For\"):\n        ip = request.remote_addr\n    else:\n        ip = request.headers.getlist(\"X-Forwarded-For\")[0]\n        # todo 校验 Ip 格式\n    return ip\n\n\n@app.route(\"/test_down\")\ndef test_down():\n    \"\"\"\n    测试下载\n    \"\"\"\n    return send_from_directory(os.path.join(app.root_path, 'static'),\n                               'img/cat.jpg', as_attachment=True)\n\n\n@app.route(\"/test/sendcloud\")\ndef test_sendcloud():\n    \"\"\"\n    测试 sendcloud\n    http://localhost:5000/test/sendcloud\n    注意: 用户可以调用模板发送, 也可以普通发送(上传内容发送). 两种发送方式都要求最终的内容和至少一个模板匹配\n    \"\"\"\n    # 获取信息\n    result = send_cloud_client.userinfo_get()\n    # return json.dumps(result)\n\n    # 发送邮件\n    email_content = {\n        'mail_from': 'System Support<support@zhendi.me>',\n        'mail_to': 'zhanghe@wealink.com',\n        'mail_subject': '来自SendCloud的第一封邮件！',\n        'mail_html': '你太棒了！你已成功的从SendCloud发送了一封测试邮件，接下来快登录前台去完善账户信息吧！'\n    }\n    send_email_result = send_cloud_client.mail_send(**email_content)\n    # 调试邮件发送结果\n    return json.dumps(send_email_result)\n\n\n@app.route('/save')\ndef save():\n    \"\"\"\n    保存文件到七牛\n    \"\"\"\n    data = 'data to save'\n    filename = 'filename'\n    ret, info = qi_niu_client.save(data, filename)\n    return str(ret)\n\n\n@app.route('/delete')\ndef delete():\n    \"\"\"\n    删除七牛空间中的文件\n    \"\"\"\n    filename = 'filename'\n    ret, info = qi_niu_client.delete(filename)\n    return str(ret)\n\n\n@app.route('/url')\ndef url():\n    \"\"\"\n    根据文件名获取对应的公开URL\n    \"\"\"\n    filename = 'filename'\n    return qi_niu_client.url(filename)\n\n\n# # 第三方登陆（QQ）\ndef json_to_dict(x):\n    \"\"\"\n    OAuthResponse class can't not parse the JSON data with content-type\n    text/html, so we need reload the JSON data manually\n    :param x:\n    :return:\n    \"\"\"\n    if x.find('callback') > -1:\n        pos_lb = x.find('{')\n        pos_rb = x.find('}')\n        x = x[pos_lb:pos_rb + 1]\n    try:\n        return json.loads(x, encoding='utf-8')\n    except:\n        return x\n\n\ndef update_qq_api_request_data(data={}):\n    \"\"\"\n    Update some required parameters for OAuth2.0 API calls\n    :param data:\n    :return:\n    \"\"\"\n    defaults = {\n        'openid': session.get('qq_openid'),\n        'access_token': session.get('qq_token')[0],\n        'oauth_consumer_key': app.config['consumer_key'],\n    }\n    defaults.update(data)\n    return defaults\n\n\n@app.route('/user_info')\ndef get_user_info():\n    if 'qq_token' in session:\n        data = update_qq_api_request_data()\n        resp = oauth_qq.get('/user/get_user_info', data=data)\n        return jsonify(status=resp.status, data=resp.data)\n    return redirect(url_for('login_qq'))\n\n\n@app.route('/login/qq/')\ndef login_qq():\n    return oauth_qq.authorize(callback=url_for('authorized_qq', _external=True))\n\n\n@app.route('/login/authorized/qq/')\ndef authorized_qq():\n    resp = oauth_qq.authorized_response()\n    if resp is None:\n        return 'Access denied: reason=%s error=%s' % (\n            request.args['error_reason'],\n            request.args['error_description']\n        )\n    session['qq_token'] = (resp['access_token'], '')\n\n    # Get openid via access_token, openid and access_token are needed for API calls\n    resp = oauth_qq.get('/oauth2.0/me', {'access_token': session['qq_token'][0]})\n    resp = json_to_dict(resp.data)\n    if isinstance(resp, dict):\n        session['qq_openid'] = resp.get('openid')\n\n    return redirect(url_for('get_user_info'))\n\n\n@oauth_qq.tokengetter\ndef get_qq_oauth_token():\n    return session.get('qq_token')\n\n\n# 第三方登陆（WeiBo）\n# @app.route('/')\n# def index():\n#     if 'oauth_token' in session:\n#         access_token = session['oauth_token'][0]\n#         resp = weibo.get('statuses/home_timeline.json')\n#         return jsonify(resp.data)\n#     return redirect(url_for('login'))\n\n\n@app.route('/login/weibo/')\ndef login_weibo():\n    return oauth_weibo.authorize(callback=url_for('authorized_weibo',\n        next=request.args.get('next') or request.referrer or None,\n        _external=True))\n\n\n@app.route('/login/authorized/weibo/')\ndef authorized_weibo():\n    resp = oauth_weibo.authorized_response()\n    if resp is None:\n        return 'Access denied: reason=%s error=%s' % (\n            request.args['error_reason'],\n            request.args['error_description']\n        )\n    session['oauth_token'] = (resp['access_token'], '')\n    return redirect(url_for('index'))\n\n\n@oauth_weibo.tokengetter\ndef get_weibo_oauth_token():\n    return session.get('oauth_token')\n\n\ndef change_weibo_header(uri, headers, body):\n    \"\"\"Since weibo is a rubbish server, it does not follow the standard,\n    we need to change the authorization header for it.\"\"\"\n    auth = headers.get('Authorization')\n    if auth:\n        auth = auth.replace('Bearer', 'OAuth2')\n        headers['Authorization'] = auth\n    return uri, headers, body\n\noauth_weibo.pre_request = change_weibo_header\n\n\n# 第三方登陆（GitHub）\n@app.route('/login/github/')\ndef login_github():\n    return oauth_github.authorize(callback=url_for('authorized_github', _external=True))\n\n\n@app.route('/login/authorized/github/')\ndef authorized_github():\n    resp = oauth_github.authorized_response()\n    if resp is None:\n        return 'Access denied: reason=%s error=%s' % (\n            request.args['error'],\n            request.args['error_description']\n        )\n    session['github_token'] = (resp['access_token'], '')\n    me = oauth_github.get('user')\n    return jsonify(me.data)\n\n\n@oauth_github.tokengetter\ndef get_github_oauth_token():\n    return session.get('github_token')\n\n\n# 第三方支付（支付宝）\n@app.route('/pay/alipay/')\ndef pay_alipay():\n    return 'alipay'\n\n\n# 订单\n@app.route('/order/')\ndef order():\n    return 'order'\n\n\n# log测试\n@app.route('/test_log/')\ndef test_log():\n    \"\"\"\n    log测试\n    \"\"\"\n    import logging\n    log = logging.getLogger('app')\n    log.debug('info message')\n    log.info('info message')\n    log.error('error message')\n    return 'log测试'\n\n\n# 缓存测试\n@app.route('/test_cache/')\ndef test_cache():\n    \"\"\"\n    缓存测试\n    5.01s >> 9ms\n    \"\"\"\n    import time\n    rv = cache.get('my-item')\n    if rv is None:\n        time.sleep(5)\n        rv = 'Hello, Cache!'\n        cache.set('my-item', rv, timeout=5 * 10)\n    return rv\n\n\n# 后台任务测试\n@app.route('/test_send_task/')\ndef test_send_task(x=100, y=200):\n    \"\"\"\n    后台发送任务测试\n    http://localhost:8000/test_send_task/?x=100&y=200\n    \"\"\"\n    from app.tasks import add, mul, xsum\n\n    x = int(request.args.get('x', x))\n    y = int(request.args.get('y', y))\n\n    add_res = add.delay(x, y)\n    mul_res = mul.delay(x, y)\n    xsum_res = xsum.delay([x, y])\n    result = ''\n    result += '<a href=\"http://localhost:8000/test_task_add_result/%s/\">%s</a><br/>' % (add_res.id, add_res.id)\n    result += '<a href=\"http://localhost:8000/test_task_mul_result/%s/\">%s</a><br/>' % (mul_res.id, mul_res.id)\n    result += '<a href=\"http://localhost:8000/test_task_xsum_result/%s/\">%s</a><br/>' % (xsum_res.id, xsum_res.id)\n    return result\n\n\n@app.route('/test_task_send_get/')\ndef test_task_send_get(x=100, y=200):\n    \"\"\"\n    后台发送任务并获取结果测试\n    http://localhost:8000/test_task_send_get/?x=100&y=200\n    \"\"\"\n    from app.tasks import add, mul, xsum\n\n    x = int(request.args.get('x', x))\n    y = int(request.args.get('y', y))\n\n    add_res = add.delay(x, y)\n    mul_res = mul.delay(x, y)\n    xsum_res = xsum.delay([x, y])\n    import time\n    time.sleep(0.0005)\n    result = {\n        'add_res': add_res.get(timeout=1.0) if add_res.state == 'SUCCESS' else '...',\n        'mul_res': mul_res.get(timeout=1.0) if mul_res.state == 'SUCCESS' else '...',\n        'xsum_res': xsum_res.get(timeout=1.0) if xsum_res.state == 'SUCCESS' else '...'\n    }\n    return json.dumps(result)\n\n\n@app.route('/test_task_add_result/<task_id>/')\ndef test_task_add_result(task_id):\n    \"\"\"\n    后台任务测试结果\n    http://localhost:8000/test_task_add_result/xxxxxx/\n    \"\"\"\n    from app.tasks import add, mul, xsum\n    result = add.AsyncResult(task_id).get(timeout=1.0)\n    return repr(result)\n\n\n@app.route('/test_task_mul_result/<task_id>/')\ndef test_task_mul_result(task_id):\n    \"\"\"\n    后台任务测试结果\n    http://localhost:8000/test_task_mul_result/xxxxxx/\n    \"\"\"\n    from app.tasks import add, mul, xsum\n    result = mul.AsyncResult(task_id).get(timeout=1.0)\n    return repr(result)\n\n\n@app.route('/test_task_xsum_result/<task_id>/')\ndef test_task_xsum_result(task_id):\n    \"\"\"\n    后台任务测试结果\n    http://localhost:8000/test_task_xsum_result/xxxxxx/\n    \"\"\"\n    from app.tasks import add, mul, xsum\n    result = xsum.AsyncResult(task_id).get(timeout=1.0)\n    return repr(result)\n\n\ndef allowed_file(filename):\n    \"\"\"\n    校验文件类型\n    \"\"\"\n    return '.' in filename and filename.rsplit('.', 1)[1] in app.config['ALLOWED_EXTENSIONS']\n\n\ndef get_file_size(file_obj):\n    \"\"\"\n    获取文件大小\n    :param file_obj:\n    :return:\n    \"\"\"\n    file_obj.seek(0, 2)  # Seek to the end of the file\n    size = file_obj.tell()  # Get the position of EOF\n    file_obj.seek(0)  # Reset the file position to the beginning\n    return size\n\n\n@app.route('/uploads', methods=['GET', 'POST'])\ndef uploads():\n    \"\"\"\n    多文件上传\n    \"\"\"\n    if request.method == 'GET':\n        return render_template('uploads.html')\n    if request.method == 'DELETE':\n        # todo\n        result = {\"files\": [\n            {\n                \"picture1.jpg\": True\n            },\n            {\n                \"picture2.jpg\": True\n            }\n        ]}\n        return json.dumps(result)\n    if request.method == 'POST':\n        files = []\n        from werkzeug.utils import secure_filename\n        file_list = request.files.getlist('files[]')\n        for file_item in file_list:\n            file_info = {\n                'name': secure_filename(file_item.filename),\n                'content_type': file_item.content_type,\n                'size': get_file_size(file_item),\n                'delete_url': url_for('uploads_del'),\n                'delete_type': 'POST'\n            }\n            if not file_item or not allowed_file(file_item.filename):\n                file_info['error'] = u'文件类型暂不支持'\n            file_item.save(app.config['UPLOAD_FOLDER'] + file_info['name'])\n            files.append(file_info)\n        return json.dumps({'files': files})\n\n\n@app.route('/uploads/delete', methods=['GET', 'POST'])\ndef uploads_del():\n    \"\"\"\n    多文件上传\n    \"\"\"\n    if request.method == 'POST':\n        # todo\n        result = {\"files\": [\n            {\n                \"picture1.jpg\": True\n            },\n            {\n                \"picture2.jpg\": True\n            }\n        ]}\n        return json.dumps(result)\n\n\n@app.errorhandler(404)\ndef page_not_found(error):\n    return render_template('404.html'), 404\n\n\n@app.errorhandler(500)\ndef internal_error(error):\n    from app.database import db\n    db.session.rollback()\n    return render_template('500.html'), 500\n"
  },
  {
    "path": "backup/views_bak.py",
    "content": "#!/usr/bin/env python\n# encoding: utf-8\n\n\"\"\"\n@author: zhanghe\n@software: PyCharm\n@file: views.py\n@time: 16-1-7 上午12:10\n\"\"\"\n\n\nfrom app import app, login_manager, oauth_github, oauth_qq, oauth_weibo, send_cloud_client, qi_niu_client\nfrom flask import render_template, request, url_for, send_from_directory, session, flash, redirect, g, jsonify, Markup, abort\nfrom app.forms import RegForm, LoginForm, BlogAddForm, BlogEditForm, UserForm\nfrom app.login import LoginUser\nfrom flask_login import login_user, logout_user, current_user, login_required\nimport os\nimport json\nfrom werkzeug.contrib.cache import SimpleCache\ncache = SimpleCache()  # 默认最大支持500个key, 超时时间5分钟, 参数可配置\n\n\n@login_manager.user_loader\ndef load_user(user_id):\n    \"\"\"\n    如果 user_id 无效，它应该返回 None （ 而不是抛出异常 ）。\n    :param user_id:\n    :return:\n    \"\"\"\n    return LoginUser.query.get(int(user_id))\n\n\n@app.before_request\ndef before_request():\n    \"\"\"\n    当前用户信息\n    \"\"\"\n    g.user = current_user\n\n\n@app.route('/favicon.ico')\ndef favicon():\n    \"\"\"\n    首页ico图标\n    \"\"\"\n    return send_from_directory(os.path.join(app.root_path, 'static'),\n                               'img/favicon.ico', mimetype='image/vnd.microsoft.icon')\n\n\n@app.route('/')\n@app.route('/index')\ndef index():\n    \"\"\"\n    网站首页\n    \"\"\"\n    # return \"Hello, World!\"\n    return render_template('index.html', title='home')\n\n\n@app.route('/about')\ndef about():\n    \"\"\"\n    关于网站\n    \"\"\"\n    # return \"Hello, World!\\nAbout!\"\n    return render_template('about.html', title='about')\n\n\n@app.route('/contact')\ndef contact():\n    \"\"\"\n    联系方式\n    \"\"\"\n    # return \"Hello, World!\\nContact!\"\n    return render_template('contact.html', title='contact')\n\n\n@app.route('/blog/list/')\n@app.route('/blog/list/<int:page>/')\ndef blog_list(page=1):\n    \"\"\"\n    博客列表\n    \"\"\"\n    # return \"Hello, World!\\nBlog List!\"\n    from blog import get_blog_rows\n    per_page = 8\n    pagination = get_blog_rows(page, per_page)\n    return render_template('blog/list.html', title='blog_list', pagination=pagination)\n\n\n@app.route('/blog/list_edit/')\n@app.route('/blog/list_edit/<int:page>/')\n@login_required\ndef blog_list_edit(page=1):\n    \"\"\"\n    博客列表(带编辑)\n    \"\"\"\n    # return \"Hello, World!\\nBlog List!\"\n    from blog import get_blog_rows\n    per_page = 8\n    pagination = get_blog_rows(page, per_page)\n    return render_template('blog/list_edit.html', title='blog_list', pagination=pagination)\n\n\n@app.route('/blog/ajax/list_edit/', methods=['GET', 'POST'])\n@login_required\ndef blog_ajax_list_edit():\n    \"\"\"\n    博客编辑\n    \"\"\"\n    if request.method == 'POST' and request.is_xhr:\n        form = request.form\n        from blog import edit_blog\n        from datetime import datetime\n        blog_id = form.get('id', 0, type=int)\n        blog_info = {\n            'author': form.get('author'),\n            'title': form.get('title'),\n            'pub_date': datetime.strptime(form.get('pub_date'), \"%Y-%m-%d\").date(),\n            'edit_time': datetime.utcnow(),\n        }\n        result = edit_blog(blog_id, blog_info)\n        if result == 1:\n            return json.dumps({'success': u'Edit Success'})\n        if result == 0:\n            return json.dumps({'error': u'Edit Error'})\n    abort(404)\n\n\n@app.route('/blog/new/')\n@app.route('/blog/new/<int:page>/')\ndef blog_new(page=1):\n    \"\"\"\n    最新博客\n    \"\"\"\n    # return \"Hello, World!\\nBlog New!\"\n    from blog import get_blog_rows, get_blog_list_counter, get_blog_list_container_status\n    per_page = 8\n    pagination = get_blog_rows(page, per_page)\n    id_list = [item.id for item in pagination.items]\n    blog_counter_list = get_blog_list_counter(id_list)\n    # 状态设置\n    login_user_id = g.user.get_id()\n    blog_container_status_list = get_blog_list_container_status(id_list, login_user_id)\n    return render_template(\n        'blog/new.html',\n        title='blog_new',\n        pagination=pagination,\n        blog_counter_list=blog_counter_list,\n        blog_container_status_list=blog_container_status_list\n    )\n\n\n@app.route('/blog/hot/')\n@app.route('/blog/hot/<int:page>/')\ndef blog_hot(page=1):\n    \"\"\"\n    热门博客\n    \"\"\"\n    # return \"Hello, World!\\nBlog Hot!\"\n    from blog import get_blog_rows\n    per_page = 8\n    pagination = get_blog_rows(page, per_page)\n    return render_template('blog/hot.html', title='blog_hot', pagination=pagination)\n\n\n@app.route('/blog/edit/<int:blog_id>/', methods=['GET', 'POST'])\n@login_required\ndef blog_edit(blog_id):\n    \"\"\"\n    博客编辑\n    \"\"\"\n    # return \"Hello, World!\\nBlog Edit!\"\n    form = BlogEditForm(request.form)\n    if request.method == 'GET':\n        from blog import get_blog_row_by_id\n        blog_info = get_blog_row_by_id(blog_id)\n        if blog_info:\n            form.author.data = blog_info.author\n            form.title.data = blog_info.title\n            form.pub_date.data = blog_info.pub_date\n        else:\n            return redirect(url_for('index'))\n    if request.method == 'POST':\n        if form.validate_on_submit():\n            from blog import edit_blog\n            from datetime import datetime\n            blog_info = {\n                'author': form.author.data,\n                'title': form.title.data,\n                'pub_date': form.pub_date.data,\n                'edit_time': datetime.utcnow(),\n            }\n            result = edit_blog(blog_id, blog_info)\n            if result == 1:\n                flash(u'Edit Success', 'success')\n                return redirect(request.args.get('next') or url_for('blog_list'))\n            if result == 0:\n                flash(u'Edit Failed', 'warning')\n        flash(form.errors, 'warning')  # 调试打开\n    flash(u'Hello, %s' % current_user.email, 'info')  # 测试打开\n    return render_template('blog/edit.html', title='blog_edit', blog_id=blog_id, form=form)\n\n\n@app.route('/blog/add/', methods=['GET', 'POST'])\n@login_required\ndef blog_add():\n    \"\"\"\n    博客添加\n    \"\"\"\n    # return \"Hello, World!\\nBlog Add!\"\n    form = BlogAddForm(request.form)\n    if request.method == 'POST':\n        if form.validate_on_submit():\n            from blog import add_blog\n            from datetime import datetime\n            current_time = datetime.utcnow()\n            blog_info = {\n                'author': form.author.data,\n                'title': form.title.data,\n                'pub_date': form.pub_date.data,\n                'add_time': current_time,\n                'edit_time': current_time,\n            }\n            result = add_blog(blog_info)\n            if result is None:\n                flash(u'Add Failed', 'warning')\n            else:\n                flash(u'Add Success', 'success')\n                return redirect(url_for('blog_edit', blog_id=result))\n        flash(form.errors, 'warning')  # 调试打开\n    # flash(u'Hello, %s' % current_user.email, 'info')  # 测试打开\n    return render_template('blog/add.html', title='blog_add', form=form)\n\n\n@app.route('/blog/del/', methods=['GET', 'POST'])\ndef blog_delete():\n    \"\"\"\n    博客删除\n    \"\"\"\n    if request.method == 'GET':\n        login_user_id = g.user.get_id()\n        # 权限判断，只能删除自己的 blog todo\n        if login_user_id is None:\n            return jsonify(result=False)\n        blog_id = request.args.get('blog_id', 0, type=int)\n        from blog import delete_blog\n        result = delete_blog(blog_id)\n        if result == 1:\n            return jsonify(result=True)\n        else:\n            return jsonify(result=False)\n\n\n@app.route('/blog/stat/', methods=['GET', 'POST'])\ndef blog_stat():\n    \"\"\"\n    博客统计\n    http://localhost:5000/blog/stat/?blog_id=2&stat_type=favor&num=2\n    :return:\n    \"\"\"\n    if request.method == 'GET':\n        login_user_id = g.user.get_id()\n        if login_user_id is None:\n            return jsonify(result=False)\n        blog_id = request.args.get('blog_id', 0, type=int)\n        stat_type = request.args.get('stat_type', '', type=str)\n        # num = request.args.get('num', 0, type=int)\n        from tools.stat import set_blog_stat\n        result = set_blog_stat(stat_type, login_user_id, blog_id)\n        return jsonify(result)\n\n\n@app.route('/reg/', methods=['GET', 'POST'])\ndef reg():\n    \"\"\"\n    注册\n    \"\"\"\n    # return \"Hello, World!\\nReg!\"\n    form = RegForm()\n    if request.method == 'POST':\n        if form.validate_on_submit():\n            # 添加用户信息\n            from user import add_user\n            from datetime import datetime\n            current_time = datetime.utcnow()\n            user_data = {\n                'email': form.email.data,\n                'create_time': current_time,\n                'update_time': current_time,\n                'last_ip': request.headers.get('X-Forwarded-For', request.remote_addr)\n            }\n            user_id = add_user(user_data)\n            # 添加授权信息\n            from user_auth import add_user_auth\n            user_auth_data = {\n                'user_id': user_id,\n                'auth_type': 'email',\n                'auth_key': form.email.data,\n                'auth_secret': form.password.data\n            }\n            user_auth_id = add_user_auth(user_auth_data)\n            if user_auth_id:\n                flash(u'%s, Thanks for registering' % form.email.data, 'success')\n                # todo 发送邮箱校验邮件\n                email_validate_content = {\n                    'mail_from': 'System Support<support@zhendi.me>',\n                    'mail_to': form.email.data,\n                    'mail_subject': 'verify reg email',\n                    'mail_html': 'verify reg email address in mailbox'\n                }\n                send_email_result = send_cloud_client.mail_send(**email_validate_content)\n                # 调试邮件发送结果\n                if send_email_result.get('result') is False:\n                    flash(send_email_result.get('message'), 'warning')\n                else:\n                    flash(send_email_result.get('message'), 'success')\n                # https://www.***.com/email/signup/uuid\n            else:\n                flash(u'%s, Sorry, register error' % form.email.data, 'warning')\n            return redirect(url_for('login'))\n        # 闪现消息 success info warning danger\n        flash(form.errors, 'warning')  # 调试打开\n    return render_template('reg.html', title='reg', form=form)\n\n\n@app.route('/agreement/')\ndef agreement():\n    \"\"\"\n    注册协议\n    :return:\n    \"\"\"\n    return 'agreement'\n\n\n@app.route('/email/sign')\ndef email_sign():\n    \"\"\"\n    邮箱签名(带过期时间)\n    http://localhost:5000/email/sign?email=zhang_he06@163.com\n    \"\"\"\n    email = request.args.get('email', '')\n    from itsdangerous import TimestampSigner\n    s = TimestampSigner(app.config['SECRET_KEY'])\n    return s.sign(email)\n\n\n@app.route('/email/check')\ndef email_check():\n    \"\"\"\n    校验邮箱有效性\n    http://localhost:5000/email/check?sign=zhang_he06@163.com.ChstqQ.5jODirLaRF2yU0CLtZz2EmoHt4c\n    \"\"\"\n    sign = request.args.get('sign', '')\n    from itsdangerous import TimestampSigner, SignatureExpired, BadTimeSignature\n    s = TimestampSigner(app.config['SECRET_KEY'])\n    try:\n        # email = s.unsign(sign, max_age=5)  # 5秒过期\n        email = s.unsign(sign, max_age=30*24*60*60)  # １个月过期\n        # return email\n        # 校验通过，更新邮箱验证状态\n        from user_auth import update_user_auth_rows\n        result = update_user_auth_rows({'verified': 1}, **{'auth_type': 'email', 'auth_key': email})\n        if result == 1:\n            flash(u'%s, Your mailbox has been verified' % email, 'success')\n            return redirect(url_for('login'))\n        else:\n            flash(u'%s, Sorry, Your mailbox validation failed' % email, 'warning')\n    except SignatureExpired as e:\n        # 处理签名超时\n        flash(e.message, 'warning')\n    except BadTimeSignature as e:\n        # 处理签名错误\n        flash(e.message, 'warning')\n    return redirect(url_for('reg.index'))\n\n\n@app.route('/login/', methods=['GET', 'POST'])\ndef login():\n    \"\"\"\n    登录\n    \"\"\"\n    if g.user is not None and g.user.is_authenticated:\n        return redirect(url_for('index'))\n    form = LoginForm()\n    if request.method == 'POST':\n        if form.validate_on_submit():\n            from user_auth import get_user_auth_row\n            condition = {\n                'auth_type': 'email',\n                'auth_key': form.email.data,\n                'auth_secret': form.password.data\n            }\n            user_auth_info = get_user_auth_row(**condition)\n            if user_auth_info is None:\n                flash(u'%s, You were logged failed' % form.email.data, 'warning')\n                return render_template('login.html', title='login', form=form)\n            if user_auth_info.verified == 0:\n                flash(u'%s, Please verify email address in mailbox' % form.email.data, 'warning')\n                return render_template('login.html', title='login', form=form)\n            # session['logged_in'] = True\n            # 用户通过验证后，记录登入IP\n            from user import edit_user\n            edit_user(user_auth_info.user_id, {'last_ip': request.headers.get('X-Forwarded-For', request.remote_addr)})\n            # 用 login_user 函数来登入他们\n            from user import get_user_row_by_id\n            login_user(get_user_row_by_id(user_auth_info.user_id))\n            flash(u'%s, You were logged in' % form.email.data, 'success')\n            return redirect(request.args.get('next') or url_for('index'))\n        flash(form.errors, 'warning')  # 调试打开\n    return render_template('login.html', title='login', form=form)\n\n\n# @app.route('/logout')\n# def logout():\n#     session.pop('logged_in', None)\n#     flash(u'You were logged out')\n#     return redirect(url_for('index'))\n\n@app.route('/logout/')\ndef logout():\n    \"\"\"\n    退出登录\n    \"\"\"\n    logout_user()\n    session.pop('qq_token', None)\n    session.pop('weibo_token', None)\n    session.pop('github_token', None)\n    flash(u'You were logged out', 'info')\n    return redirect(url_for('index'))\n\n\n@app.route('/setting/', methods=['GET', 'POST'])\n@login_required\ndef setting():\n    \"\"\"\n    设置\n    \"\"\"\n    # return \"Hello, World!\\nSetting!\"\n    form = UserForm(request.form)\n    if request.method == 'GET':\n        from user import get_user_row_by_id\n        user_info = get_user_row_by_id(current_user.id)\n        if user_info:\n            form.nickname.data = user_info.nickname\n            form.avatar_url.data = user_info.avatar_url\n            form.email.data = user_info.email\n            form.phone.data = user_info.phone\n            form.birthday.data = user_info.birthday\n            form.create_time.data = user_info.create_time\n            form.update_time.data = user_info.update_time\n            form.last_ip.data = user_info.last_ip\n    if request.method == 'POST':\n        if form.validate_on_submit():\n            # todo 判断邮箱是否重复\n            from user import edit_user\n            from datetime import datetime\n            user_info = {\n                'nickname': form.nickname.data,\n                'avatar_url': form.avatar_url.data,\n                'email': form.email.data,\n                'phone': form.phone.data,\n                'birthday': form.birthday.data,\n                'update_time': datetime.utcnow(),\n                'last_ip': request.headers.get('X-Forwarded-For', request.remote_addr),\n            }\n            result = edit_user(current_user.id, user_info)\n            if result == 1:\n                flash(u'Edit Success', 'success')\n            if result == 0:\n                flash(u'Edit Failed', 'warning')\n        flash(form.errors, 'warning')  # 调试打开\n    flash(u'Hello, %s' % current_user.email, 'info')  # 测试打开\n    return render_template('setting.html', title='setting', form=form)\n\n\n@app.route('/search/', methods=['GET', 'POST'])\ndef search():\n    \"\"\"\n    搜索\n    \"\"\"\n    return 'search result!'\n\n\n@app.route(\"/email/\")\ndef send_email():\n    \"\"\"\n    邮件发送\n    \"\"\"\n    try:\n        from emails import send_email\n        msg = 'This is a test email!'\n        send_email(\n            subject=u'邮件主题',\n            sender=(u'系统邮箱', 'zhang_he06@163.com'),\n            recipients=[(u'尊敬的用户', 'zhang_he06@163.com')],\n            html_body=render_template('email.html', message=msg)\n        )\n        return jsonify({'success': u'邮件发送成功'})\n    except Exception, e:\n        return jsonify({'error': e.message})\n\n\n@app.route(\"/test\")\ndef test():\n    \"\"\"\n    测试\n    \"\"\"\n    try:\n        raise Exception('error test')\n    except Exception as e:\n        import logging\n        logging.error(e)\n\n\n@app.route(\"/test_client_ip\")\ndef test_client_ip():\n    \"\"\"\n    测试客户端来源ip\n    http://localhost:5000/test_client_ip\n    curl -H \"X-Forwarded-For: 1.2.3.4\" http://localhost:5000/test_client_ip\n    \"\"\"\n    if not request.headers.getlist(\"X-Forwarded-For\"):\n        ip = request.remote_addr\n    else:\n        ip = request.headers.getlist(\"X-Forwarded-For\")[0]\n        # todo 校验 Ip 格式\n    return ip\n\n\n@app.route(\"/test_down\")\ndef test_down():\n    \"\"\"\n    测试下载\n    \"\"\"\n    return send_from_directory(os.path.join(app.root_path, 'static'),\n                               'img/cat.jpg', as_attachment=True)\n\n\n@app.route(\"/test/sendcloud\")\ndef test_sendcloud():\n    \"\"\"\n    测试 sendcloud\n    http://localhost:5000/test/sendcloud\n    注意: 用户可以调用模板发送, 也可以普通发送(上传内容发送). 两种发送方式都要求最终的内容和至少一个模板匹配\n    \"\"\"\n    # 获取信息\n    result = send_cloud_client.userinfo_get()\n    # return json.dumps(result)\n\n    # 发送邮件\n    email_content = {\n        'mail_from': 'System Support<support@zhendi.me>',\n        'mail_to': 'zhanghe@wealink.com',\n        'mail_subject': '来自SendCloud的第一封邮件！',\n        'mail_html': '你太棒了！你已成功的从SendCloud发送了一封测试邮件，接下来快登录前台去完善账户信息吧！'\n    }\n    send_email_result = send_cloud_client.mail_send(**email_content)\n    # 调试邮件发送结果\n    return json.dumps(send_email_result)\n\n\n@app.route('/save')\ndef save():\n    \"\"\"\n    保存文件到七牛\n    \"\"\"\n    data = 'data to save'\n    filename = 'filename'\n    ret, info = qi_niu_client.save(data, filename)\n    return str(ret)\n\n\n@app.route('/delete')\ndef delete():\n    \"\"\"\n    删除七牛空间中的文件\n    \"\"\"\n    filename = 'filename'\n    ret, info = qi_niu_client.delete(filename)\n    return str(ret)\n\n\n@app.route('/url')\ndef url():\n    \"\"\"\n    根据文件名获取对应的公开URL\n    \"\"\"\n    filename = 'filename'\n    return qi_niu_client.url(filename)\n\n\n# # 第三方登陆（QQ）\ndef json_to_dict(x):\n    \"\"\"\n    OAuthResponse class can't not parse the JSON data with content-type\n    text/html, so we need reload the JSON data manually\n    :param x:\n    :return:\n    \"\"\"\n    if x.find('callback') > -1:\n        pos_lb = x.find('{')\n        pos_rb = x.find('}')\n        x = x[pos_lb:pos_rb + 1]\n    try:\n        return json.loads(x, encoding='utf-8')\n    except:\n        return x\n\n\ndef update_qq_api_request_data(data={}):\n    \"\"\"\n    Update some required parameters for OAuth2.0 API calls\n    :param data:\n    :return:\n    \"\"\"\n    defaults = {\n        'openid': session.get('qq_openid'),\n        'access_token': session.get('qq_token')[0],\n        'oauth_consumer_key': app.config['consumer_key'],\n    }\n    defaults.update(data)\n    return defaults\n\n\n@app.route('/user_info')\ndef get_user_info():\n    if 'qq_token' in session:\n        data = update_qq_api_request_data()\n        resp = oauth_qq.get('/user/get_user_info', data=data)\n        return jsonify(status=resp.status, data=resp.data)\n    return redirect(url_for('login_qq'))\n\n\n@app.route('/login/qq/')\ndef login_qq():\n    return oauth_qq.authorize(callback=url_for('authorized_qq', _external=True))\n\n\n@app.route('/login/authorized/qq/')\ndef authorized_qq():\n    resp = oauth_qq.authorized_response()\n    if resp is None:\n        return 'Access denied: reason=%s error=%s' % (\n            request.args['error_reason'],\n            request.args['error_description']\n        )\n    session['qq_token'] = (resp['access_token'], '')\n\n    # Get openid via access_token, openid and access_token are needed for API calls\n    resp = oauth_qq.get('/oauth2.0/me', {'access_token': session['qq_token'][0]})\n    resp = json_to_dict(resp.data)\n    if isinstance(resp, dict):\n        session['qq_openid'] = resp.get('openid')\n\n    return redirect(url_for('get_user_info'))\n\n\n@oauth_qq.tokengetter\ndef get_qq_oauth_token():\n    return session.get('qq_token')\n\n\n# 第三方登陆（WeiBo）\n# @app.route('/')\n# def index():\n#     if 'oauth_token' in session:\n#         access_token = session['oauth_token'][0]\n#         resp = weibo.get('statuses/home_timeline.json')\n#         return jsonify(resp.data)\n#     return redirect(url_for('login'))\n\n\n@app.route('/login/weibo/')\ndef login_weibo():\n    return oauth_weibo.authorize(callback=url_for('authorized_weibo',\n        next=request.args.get('next') or request.referrer or None,\n        _external=True))\n\n\n@app.route('/login/authorized/weibo/')\ndef authorized_weibo():\n    resp = oauth_weibo.authorized_response()\n    if resp is None:\n        return 'Access denied: reason=%s error=%s' % (\n            request.args['error_reason'],\n            request.args['error_description']\n        )\n    session['oauth_token'] = (resp['access_token'], '')\n    return redirect(url_for('index'))\n\n\n@oauth_weibo.tokengetter\ndef get_weibo_oauth_token():\n    return session.get('oauth_token')\n\n\ndef change_weibo_header(uri, headers, body):\n    \"\"\"Since weibo is a rubbish server, it does not follow the standard,\n    we need to change the authorization header for it.\"\"\"\n    auth = headers.get('Authorization')\n    if auth:\n        auth = auth.replace('Bearer', 'OAuth2')\n        headers['Authorization'] = auth\n    return uri, headers, body\n\noauth_weibo.pre_request = change_weibo_header\n\n\n# 第三方登陆（GitHub）\n@app.route('/login/github/')\ndef login_github():\n    return oauth_github.authorize(callback=url_for('authorized_github', _external=True))\n\n\n@app.route('/login/authorized/github/')\ndef authorized_github():\n    resp = oauth_github.authorized_response()\n    if resp is None:\n        return 'Access denied: reason=%s error=%s' % (\n            request.args['error'],\n            request.args['error_description']\n        )\n    session['github_token'] = (resp['access_token'], '')\n    me = oauth_github.get('user')\n    return jsonify(me.data)\n\n\n@oauth_github.tokengetter\ndef get_github_oauth_token():\n    return session.get('github_token')\n\n\n# 第三方支付（支付宝）\n@app.route('/pay/alipay/')\ndef pay_alipay():\n    return 'alipay'\n\n\n# 订单\n@app.route('/order/')\ndef order():\n    return 'order'\n\n\n\n\n\ndef allowed_file(filename):\n    \"\"\"\n    校验文件类型\n    \"\"\"\n    return '.' in filename and filename.rsplit('.', 1)[1] in app.config['ALLOWED_EXTENSIONS']\n\n\ndef get_file_size(file_obj):\n    \"\"\"\n    获取文件大小\n    :param file_obj:\n    :return:\n    \"\"\"\n    file_obj.seek(0, 2)  # Seek to the end of the file\n    size = file_obj.tell()  # Get the position of EOF\n    file_obj.seek(0)  # Reset the file position to the beginning\n    return size\n\n\n@app.route('/uploads', methods=['GET', 'POST'])\ndef uploads():\n    \"\"\"\n    多文件上传\n    \"\"\"\n    if request.method == 'GET':\n        return render_template('uploads.html')\n    if request.method == 'DELETE':\n        # todo\n        result = {\"files\": [\n            {\n                \"picture1.jpg\": True\n            },\n            {\n                \"picture2.jpg\": True\n            }\n        ]}\n        return json.dumps(result)\n    if request.method == 'POST':\n        files = []\n        from werkzeug.utils import secure_filename\n        file_list = request.files.getlist('files[]')\n        for file_item in file_list:\n            file_info = {\n                'name': secure_filename(file_item.filename),\n                'content_type': file_item.content_type,\n                'size': get_file_size(file_item),\n                'delete_url': url_for('uploads_del'),\n                'delete_type': 'POST'\n            }\n            if not file_item or not allowed_file(file_item.filename):\n                file_info['error'] = u'文件类型暂不支持'\n            file_item.save(app.config['UPLOAD_FOLDER'] + file_info['name'])\n            files.append(file_info)\n        return json.dumps({'files': files})\n\n\n@app.route('/uploads/delete', methods=['GET', 'POST'])\ndef uploads_del():\n    \"\"\"\n    多文件上传\n    \"\"\"\n    if request.method == 'POST':\n        # todo\n        result = {\"files\": [\n            {\n                \"picture1.jpg\": True\n            },\n            {\n                \"picture2.jpg\": True\n            }\n        ]}\n        return json.dumps(result)\n\n\n@app.errorhandler(404)\ndef page_not_found(error):\n    return render_template('404.html'), 404\n\n\n@app.errorhandler(500)\ndef internal_error(error):\n    from app.database import db\n    db.session.rollback()\n    return render_template('500.html'), 500\n"
  },
  {
    "path": "changelog/2017-07-03/mysql.sql",
    "content": "ALTER TABLE `score_item` MODIFY `amount` DECIMAL(8, 2) NOT NULL DEFAULT '0' COMMENT '积分分值';\nALTER TABLE `score_charity_item` MODIFY `amount` DECIMAL(8, 2) NOT NULL DEFAULT '0' COMMENT '积分分值';\nALTER TABLE `score_digital_item` MODIFY `amount` DECIMAL(8, 2) NOT NULL DEFAULT '0' COMMENT '积分分值';\nALTER TABLE `score_expense_item` MODIFY `amount` DECIMAL(8, 2) NOT NULL DEFAULT '0' COMMENT '积分分值';\nALTER TABLE `bonus_item` MODIFY `amount` DECIMAL(8, 2) NOT NULL DEFAULT '0' COMMENT '奖金金额';\nALTER TABLE `scheduling_item` MODIFY `amount` DECIMAL(8, 2) NOT NULL DEFAULT '0' COMMENT '排单分值';\n"
  },
  {
    "path": "config/__init__.py",
    "content": "#!/usr/bin/env python\n# encoding: utf-8\n\n\"\"\"\n@author: zhanghe\n@software: PyCharm\n@file: __init__.py.py\n@time: 2017/8/1 下午2:59\n\"\"\"\n\n\nimport os\nfrom importlib import import_module\n\n\nMODE = os.environ.get('MODE') or 'default'\n\n\ntry:\n    current_config = import_module('config.' + MODE)\nexcept ImportError:\n    print u'[!] 配置错误，请初始化环境变量'\n    print u'source env_develop.sh  # 开发环境'\n    print u'source env_product.sh  # 生产环境'\n"
  },
  {
    "path": "config/develop/__init__.py",
    "content": "#!/usr/bin/env python\n# encoding: utf-8\n\n\"\"\"\n@author: zhanghe\n@software: PyCharm\n@file: __init__.py.py\n@time: 2017/5/19 下午11:25\n\"\"\"\n\n\nimport os\nimport socket\nfrom datetime import timedelta\n\n# 网站运营配置\nfrom settings import *\nfrom settings.apply import *\nfrom settings.interest import *\nfrom settings.order import *\nfrom settings.sms import *\nfrom settings.user import *\n\n# 测试模式开关\nTEST = True\n\n# 前端地址\nFRONTEND_URL = 'http://0.0.0.0:8000'\n\nDEBUG = True\n\nPROJECT_NAME = u'网站名称'\n\nICP_CODE = u'沪ICP备12024750号'\n\nBASE_DIR = os.path.abspath(os.path.dirname(__file__)+'/../../')\n\n# 获取服务器名称\nHOST_NAME = socket.getfqdn(socket.gethostname())\n# 获取服务器内网ip\n# HOST_IP = socket.gethostbyname(HOST_NAME)\n\nHOST_IP = '192.168.4.1'\n\n# requests 超时设置\nREQUESTS_TIME_OUT = (30, 30)\n\n\n# 数据库 MySQL\nDB_MYSQL = {\n    'host': HOST_IP,\n    'user': 'root',\n    'passwd': '123456',\n    'port': 3306,\n    'db': 'flask_project',\n    'charset': 'utf8'\n}\n\nSQLALCHEMY_DATABASE_URI_MYSQL = \\\n    'mysql+mysqldb://%s:%s@%s:%s/%s?charset=%s' % \\\n    (DB_MYSQL['user'], DB_MYSQL['passwd'], DB_MYSQL['host'], DB_MYSQL['port'], DB_MYSQL['db'], DB_MYSQL['charset'])\n\n# 数据库 PostgreSQL\nDB_PG = {\n    'host': HOST_IP,\n    'user': 'postgres',\n    'password': 'postgres',  # 可修改 \\password\n    'port': 5432,\n    'database': 'test'\n}\n\nSQLALCHEMY_DATABASE_URI_PG = \\\n    'postgresql://%s:%s@%s:%s/%s' % \\\n    (DB_PG['user'], DB_PG['password'], DB_PG['host'], DB_PG['port'], DB_PG['database'])\n\n# 数据库 SQLite\nDB_SQLITE = os.path.join(BASE_DIR, 'db/data/flask.db')\n\nSQLALCHEMY_DATABASE_URI_SQLITE = 'sqlite:///' + DB_SQLITE\n\n\nSQLALCHEMY_DATABASE_URI = SQLALCHEMY_DATABASE_URI_MYSQL\n# SQLALCHEMY_COMMIT_ON_TEARDOWN = True  # 打开自动提交 官方已经移除(http://flask-sqlalchemy.pocoo.org/2.1/changelog/#version-2-0)\nSQLALCHEMY_TRACK_MODIFICATIONS = False\nSQLALCHEMY_POOL_SIZE = 5  # 默认 pool_size=5\nSQLALCHEMY_POOL_TIMEOUT = 10  # 默认 10秒\nSQLALCHEMY_POOL_RECYCLE = 500  # 配置要小于 数据库配置 wait_timeout\nSQLALCHEMY_ECHO = True\n\n\nREDIS = {\n    'host': HOST_IP,\n    'port': 6379,\n    'db': 0,\n    'password': None\n}\n\nDB_MONGO = {\n    'host': HOST_IP,\n    'port': 27017,\n    'username': '',\n    'password': '',\n    'database': ''\n}\n\nRABBIT_MQ = {\n    'host': HOST_IP,\n    'port': 5672\n}\n\nEXCHANGE_NAME = 'amq.direct'\n\n# 验证码类型\nCAPTCHA_ENTITY = [\n    'reg',      # 注册\n    'login',    # 登录\n    'reset'     # 重置密码（找回密码）\n]\n\n\n# 短信签名（简称）\nSMS_SIGNER = u'网站签名'\n# 短信接口配置\nSMS = {\n    'UN': 'I6814767',           # 创蓝账号\n    'PW': 'UDqQ1dcvTg2052',     # 创蓝密码\n}\n\n# 隧道配置\nSSH_CONFIG = {\n    'IP': '120.76.40.92',\n    'PORT': 22,\n    'USERNAME': 'root',\n    'PASSWORD': 't3#R@r6FrTHK',\n    'DB_MYSQL': {\n        'host': '127.0.0.1',\n        'user': 'root',\n        'passwd': '..++**//520..',\n        'port': 3306,\n        'db': 'mm7w'\n    }\n}\n\n\nCSRF_ENABLED = True\nSECRET_KEY = '\\x03\\xabjR\\xbbg\\x82\\x0b{\\x96f\\xca\\xa8\\xbdM\\xb0x\\xdbK%\\xf2\\x07\\r\\x8c'\n\n# 会话配置\n# PERMANENT_SESSION_LIFETIME = timedelta(minutes=20)             # 登录状态保持，默认31天\nREMEMBER_COOKIE_DURATION = timedelta(days=14)   # 记住登录状态，默认365天\nLOGIN_MESSAGE = u'请登录后操作'\nLOGIN_MESSAGE_CATEGORY = 'warning'  # 默认'message'\n\n\n# 后台登录前台配置\nADMIN_TO_USER_LOGIN_TIME_OUT = 1200\nADMIN_TO_USER_LOGIN_SIGN_KEY = '1b106105da7e88e54d42e3f4356e41d8'\n\n# 用户推广链接配置\nUSER_INVITE_LINK_SIGN_KEY = 'ff99bae31b7bd480deee291dd55d6864'\n\n# 文件上传配置\nUPLOAD_FOLDER = os.path.join(BASE_DIR, 'app_frontend/static/uploads/')\n# ALLOWED_EXTENSIONS = {'txt', 'pdf', 'png', 'jpg', 'jpeg', 'gif'}\nALLOWED_EXTENSIONS = {'png', 'jpg', 'jpeg'}\nMAX_CONTENT_LENGTH = 2.6 * 1024 * 1024  # 2.6Mb\nMIN_CONTENT_LENGTH = 2.0 * 1024         # 2.0Kb\n\n# Celery 配置 （异步任务队列/基于分布式消息传递的作业队列）\nCELERY_BROKER_URL = 'amqp://guest:guest@localhost:5672//'\n# CELERY_BROKER_URL = 'redis://localhost:6379/0'\nCELERY_RESULT_BACKEND = 'amqp://guest:guest@localhost:5672//'\n# CELERY_RESULT_BACKEND = 'redis://localhost:6379/0'\n\n# 本地调试邮箱配置\n# $ sudo python -m smtpd -n -c DebuggingServer localhost:25\nMAIL_SERVER = 'localhost',\nMAIL_PORT = 25,\nMAIL_USERNAME = None,\nMAIL_PASSWORD = None,\nMAIL_DEFAULT_SENDER = ('no-reply', 'no-reply@localhost')\n# 后台管理人员邮件列表\nADMINS = ['455091702@qq.com']\n\n# 开发环境邮箱配置\n# MAIL_SERVER = 'smtp.163.com',\n# MAIL_PORT = 25,\n# MAIL_USERNAME = 'xxxxxx@163.com',\n# MAIL_PASSWORD = 'xxxxxx',\n# MAIL_DEFAULT_SENDER = (u'系统邮箱', 'zhang_he06@163.com')\n# # 后台管理人员邮件列表\n# ADMINS = ['455091702@qq.com']\n\n\n# sendcloud 邮件发送平台\nSENDCLOUD_API_USER = 'zhang_he_test_w6kIMK'\nSENDCLOUD_API_KEY = 'eZeC3Qwciv4o0lDH'\n\n# qiniu 云存储\nQINIU_ACCESS_KEY = 'i3Zi_VQOoeuMDnYkksWvn6TKa0_2C9Wb2NXMtrdn'\nQINIU_SECRET_KEY = 'B_0pOtxxaQX8aPqqdMqX2A5v0R99KYKgod5vbkXf'\nQINIU_BUCKET_NAME = 'zhendi-open'                       # 七牛空间名称\nQINIU_BUCKET_DOMAIN = '7xtmj9.com2.z0.glb.clouddn.com'  # 七牛空间对应域名\n\n# 第三方开放授权登陆\n\nGITHUB_OAUTH = {\n    'consumer_key': '0ccd9367a1f81288b127',\n    'consumer_secret': '711b6afcc938d760e9e57215dfbdcb115150ddc6',\n    'request_token_params': {'scope': 'user:email'},\n    'base_url': 'https://api.github.com/',\n    'request_token_url': None,\n    'access_token_method': 'POST',\n    'access_token_url': 'https://github.com/login/oauth/access_token',\n    'authorize_url': 'https://github.com/login/oauth/authorize'\n}\n\nQQ_OAUTH = {\n    'consumer_key': '101187283',  # QQ_APP_ID\n    'consumer_secret': '993983549da49e384d03adfead8b2489',  # QQ_APP_KEY\n    'base_url': 'https://graph.qq.com',\n    'request_token_url': None,\n    'request_token_params': {'scope': 'get_user_info'},\n    'access_token_url': '/oauth2.0/token',\n    'authorize_url': '/oauth2.0/authorize',\n}\n\nWEIBO_OAUTH = {\n    'consumer_key': '909122383',\n    'consumer_secret': '2cdc60e5e9e14398c1cbdf309f2ebd3a',\n    'request_token_params': {'scope': 'email,statuses_to_me_read'},\n    'base_url': 'https://api.weibo.com/2/',\n    'authorize_url': 'https://api.weibo.com/oauth2/authorize',\n    'request_token_url': None,\n    'access_token_method': 'POST',\n    'access_token_url': 'https://api.weibo.com/oauth2/access_token',\n    # since weibo's response is a shit, we need to force parse the content\n    'content_type': 'application/json',\n}\n\n\n# 日志参数配置\nLOG_CONFIG = {\n    'version': 1,\n    'formatters': {\n        'simple': {\n            'format': '%(asctime)s - %(name)s - %(levelname)s - %(message)s'\n        },\n        'detail': {\n            'format': '%(asctime)s - %(name)s - File: %(filename)s - line: %(lineno)d - %(funcName)s() - %(levelname)s - %(message)s'\n        },\n    },\n    'handlers': {\n        'console': {\n            'class': 'logging.StreamHandler',\n            'formatter': 'simple',\n            'level': 'INFO'\n        },\n        'file_app': {\n            'class': 'logging.handlers.TimedRotatingFileHandler',\n            'formatter': 'detail',\n            'level': 'DEBUG',\n            'when': 'D',\n            'filename': BASE_DIR + '/logs/app.log'\n        },\n        'file_db': {\n            'class': 'logging.handlers.TimedRotatingFileHandler',\n            'formatter': 'detail',\n            'level': 'DEBUG',\n            'when': 'D',\n            'filename': BASE_DIR + '/logs/db.log'\n        }\n    },\n    'loggers': {\n        'app': {\n            'handlers': ['console', 'file_app'],\n            'level': 'DEBUG'\n        },\n        'db': {\n            'handlers': ['file_db'],\n            'level': 'DEBUG'\n        }\n    }\n}\n\n\nif __name__ == '__main__':\n    import os\n    import binascii\n\n    sk = os.urandom(16)\n    print sk\n    print binascii.b2a_hex(sk)\n    print BASE_DIR\n    print UPLOAD_FOLDER\n    print SQLALCHEMY_DATABASE_URI\n    print HOST_IP\n"
  },
  {
    "path": "config/develop/settings/__init__.py",
    "content": "#!/usr/bin/env python\n# encoding: utf-8\n\n\"\"\"\n@author: zhanghe\n@software: PyCharm\n@file: __init__.py.py\n@time: 2017/4/27 下午6:45\n\"\"\"\n\n\n# 开关状态\nON = True\nOFF = False\n\n\n# 网站配置\nPER_PAGE_FRONTEND = 12   # 分页显示数据条数 前台\nPER_PAGE_BACKEND = 12   # 分页显示数据条数 后台\n\n# 功能开关\n\nSWITCH_EXPORT = OFF         # 导出\n\nSWITCH_REG_ACCOUNT = ON     # 用户账号注册\nSWITCH_REG_PHONE = OFF      # 用户手机注册\nSWITCH_REG_EMAIL = OFF      # 用户邮箱注册\n\nSWITCH_REG_THREE_PART = OFF     # 第三方平台注册\n\nSWITCH_LOGIN_ACCOUNT = ON   # 用户账号登录\nSWITCH_LOGIN_PHONE = ON     # 用户手机登录\nSWITCH_LOGIN_EMAIL = ON     # 用户邮箱登录\n\nSWITCH_LOGIN_THREE_PART = OFF     # 第三方平台登录\n"
  },
  {
    "path": "config/develop/settings/apply.py",
    "content": "#!/usr/bin/env python\n# encoding: utf-8\n\n\"\"\"\n@author: zhanghe\n@software: PyCharm\n@file: apply.py\n@time: 2017/4/29 下午1:11\n\"\"\"\n\n\n# [投资配置]\n# 单次投资金额范围\nAPPLY_PUT_MIN_EACH = 2000  # 最小值\nAPPLY_PUT_MAX_EACH = 20000  # 最大值\nAPPLY_PUT_STEP = 1000  # 投资金额步长（基数）\n\n# 单个用户投资限制\nAPPLY_PUT_USER_MAX_AMOUNT = 30000  # 单个用户投资最大交易中金额\nAPPLY_PUT_USER_MAX_COUNT = 1  # 单个用户投资最大交易中单数(0 表示不限制)\n\n# 每日投资限制\nAPPLY_PUT_MAX_AMOUNT_DAILY = 1000000  # 最大金额\nAPPLY_PUT_MAX_COUNT_DAILY = 1000  # 最大数量(0 表示不限制)\n\n# 每月投资限制\nAPPLY_PUT_MAX_AMOUNT_MONTHLY = 30000000  # 最大值\nAPPLY_PUT_MAX_COUNT_MONTHLY = 30000  # 最大数量(0 表示不限制)\n\n# 投资时间配置\nAPPLY_PUT_TIME_START = '00:00:00'  # 每天投资申请开始时间\nAPPLY_PUT_TIME_END = '23:59:59'  # 每天投资申请结束时间\n\n# 分红配置\nAPPLY_PUT_DAYS_BONUS = 15  # 分红计算天数\nAPPLY_PUT_DAYS_LOCK = 15  # 投资锁定天数、提现冻结天数\n\nAPPLY_PUT_INTEREST_ON_PRINCIPAL_TTL = 3600 * 24 * 15  # 投资申请后15天完成的订单执行回收本息\n\n\n# [提现配置]\n# 单次提现金额范围\nAPPLY_GET_MIN_EACH = 2000  # 最小值\nAPPLY_GET_MAX_EACH = 20000  # 最大值\nAPPLY_GET_STEP = 1000  # 投资金额步长（基数）\n\n# 单个用户提现限制\nAPPLY_GET_USER_MAX_AMOUNT = 30000  # 单个用户提现最大交易中金额\nAPPLY_GET_USER_MAX_COUNT = 1  # 单个用户提现最大交易中单数(0 表示不限制)\n\n# 每日提现限制\nAPPLY_GET_MAX_AMOUNT_DAILY = 1000000  # 最大金额\nAPPLY_GET_MAX_COUNT_DAILY = 1000  # 最大数量(0 表示不限制)\n\n# 每月提现限制\nAPPLY_GET_MAX_AMOUNT_MONTHLY = 30000000  # 最大值\nAPPLY_GET_MAX_COUNT_MONTHLY = 30000  # 最大数量(0 表示不限制)\n\n# 提现时间配置\nAPPLY_GET_TIME_START = '00:00:00'  # 每天提现申请开始时间\nAPPLY_GET_TIME_END = '23:59:59'  # 每天提现申请结束时间\n"
  },
  {
    "path": "config/develop/settings/interest.py",
    "content": "#!/usr/bin/env python\n# encoding: utf-8\n\n\"\"\"\n@author: zhanghe\n@software: PyCharm\n@file: interest.py\n@time: 2017/6/4 下午11:03\n\"\"\"\n\n\n# 利息配置\nINTEREST_PUT = 0.01  # 投资利息（日息）\n\n# 支付奖惩比例\nINTEREST_PAY_AHEAD = 0.02  # 提前支付奖金比例\nINTEREST_PAY_DELAY = 0.02  # 延迟支付罚金比例\n\n# 支付时间差\nDIFF_TIME_PAY_AHEAD = 60*60*1   # 提前支付奖金时间差\nDIFF_TIME_PAY_DELAY = 60*60*24  # 延迟支付罚金时间差\n\n# 确认奖惩比例\nINTEREST_REC_AHEAD = 0.02  # 提前确认奖金比例\nINTEREST_REC_DELAY = 0.02  # 延迟确认罚金比例\n\n# 确认时间差\nDIFF_TIME_REC_AHEAD = 60*60*1   # 提前确认奖金时间差\nDIFF_TIME_REC_DELAY = 60*60*24  # 延迟确认罚金时间差\n"
  },
  {
    "path": "config/develop/settings/order.py",
    "content": "#!/usr/bin/env python\n# encoding: utf-8\n\n\"\"\"\n@author: zhanghe\n@software: PyCharm\n@file: order.py\n@time: 2017/4/29 下午1:12\n\"\"\"\n\n\n# 订单限制\nORDER_MAX_AMOUNT = 10000  # 订单最大金额\nORDER_MAX_COUNT = 100  # 订单最大数量\n\n# 系统自动确认收款\nPAY_AUTO_REC_TTL = 60*60*48  # 系统在订单支付成功后超过48小时未确认收款，自动确认收款\n\n# 推广奖励\n\nBONUS_DIRECT = 0.03  # 直接推荐奖励\n\nBONUS_LEVEL_FIRST = 0.05        # 一级推荐奖励\nBONUS_LEVEL_SECOND = 0.05       # 二级推荐奖励\nBONUS_LEVEL_THIRD = 0.03        # 三级推荐奖励\n\n# BONUS_LEVEL = [BONUS_LEVEL_FIRST, BONUS_LEVEL_SECOND, BONUS_LEVEL_THIRD]\n"
  },
  {
    "path": "config/develop/settings/sms.py",
    "content": "#!/usr/bin/env python\n# encoding: utf-8\n\n\"\"\"\n@author: zhanghe\n@software: PyCharm\n@file: sms_msg.py\n@time: 2017/4/21 下午4:57\n\"\"\"\n\n\n# 短信验证码\nSMS_CODE_REG = u'【网站签名】%s，是您注册的验证码'\nSMS_CODE_LOGIN = u'【网站签名】%s，是您登录的验证码'\nSMS_CODE_RESET = u'【网站签名】%s，是您重置密码的验证码'\nSMS_CODE_EDIT = u'【网站签名】%s，是您修改资料的验证码'\n\n# 订单通知\nNOTICE_ORDER_CREATE = u'【网站签名】您的订单已经创建成功'\nNOTICE_ORDER_CANCEL = u'【网站签名】您的订单已经取消成功'\nNOTICE_ORDER_PAYED = u'【网站签名】您的订单已经支付成功'\nNOTICE_ORDER_CONFIRM = u'【网站签名】您的订单已经确认完成'\n\n# 事件通知\nNOTICE_EVENT_ACTIVE = u'【网站签名】您的账号已经激活成功'\nNOTICE_EVENT_LOCK = u'【网站签名】您的账号当前已经锁定'\nNOTICE_EVENT_UNLOCK = u'【网站签名】您的账号已经解除锁定'\n"
  },
  {
    "path": "config/develop/settings/user.py",
    "content": "#!/usr/bin/env python\n# encoding: utf-8\n\n\"\"\"\n@author: zhanghe\n@software: PyCharm\n@file: user.py\n@time: 2017/4/29 下午1:12\n\"\"\"\n\n\n# 用户配置\n\n# 自动封号\nLOCK_REG_NOT_ACTIVE_TTL = 60*3     # 注册后3分钟内未激活\nLOCK_ACTIVE_NOT_PUT_TTL = 60*3     # 激活后3分钟内未排单\nLOCK_ORDER_NOT_PAY_TTL = 60*3      # 匹配后超过3分钟不打款\nLOCK_PAY_NOT_REC_TTL = 60*3        # 收款后3分钟不确认\n\n"
  },
  {
    "path": "config/product/__init__.py",
    "content": "#!/usr/bin/env python\n# encoding: utf-8\n\n\"\"\"\n@author: zhanghe\n@software: PyCharm\n@file: __init__.py.py\n@time: 2017/5/19 下午11:25\n\"\"\"\n\n\nimport os\nimport socket\nfrom datetime import timedelta\n\n# 网站运营配置\nfrom settings import *\nfrom settings.apply import *\nfrom settings.interest import *\nfrom settings.order import *\nfrom settings.sms import *\nfrom settings.user import *\n\n# 测试模式开关\nTEST = True\n\n# 前端地址\nFRONTEND_URL = 'http://120.77.59.26:8000'\n\nDEBUG = False\n\nPROJECT_NAME = u'公测版'\n\nICP_CODE = u'粤ICP备16047585号'\n\nBASE_DIR = os.path.abspath(os.path.dirname(__file__)+'/../../')\n\n# 获取服务器名称\nHOST_NAME = socket.getfqdn(socket.gethostname())\n# 获取服务器内网ip\n# HOST_IP = socket.gethostbyname(HOST_NAME)\n\nHOST_IP = '10.27.186.18'\n\n# requests 超时设置\nREQUESTS_TIME_OUT = (30, 30)\n\n\n# 数据库 MySQL\nDB_MYSQL = {\n    'host': HOST_IP,\n    'user': 'www',\n    'passwd': '@9xJkaU*JWsa',\n    'port': 3306,\n    'db': 'flask_project',\n    'charset': 'utf8'\n}\n\nSQLALCHEMY_DATABASE_URI_MYSQL = \\\n    'mysql+mysqldb://%s:%s@%s:%s/%s?charset=%s' % \\\n    (DB_MYSQL['user'], DB_MYSQL['passwd'], DB_MYSQL['host'], DB_MYSQL['port'], DB_MYSQL['db'], DB_MYSQL['charset'])\n\n# 数据库 PostgreSQL\nDB_PG = {\n    'host': HOST_IP,\n    'user': 'postgres',\n    'password': 'postgres',  # 可修改 \\password\n    'port': 5432,\n    'database': 'test'\n}\n\nSQLALCHEMY_DATABASE_URI_PG = \\\n    'postgresql://%s:%s@%s:%s/%s' % \\\n    (DB_PG['user'], DB_PG['password'], DB_PG['host'], DB_PG['port'], DB_PG['database'])\n\n# 数据库 SQLite\nDB_SQLITE = os.path.join(BASE_DIR, 'db/data/flask.db')\n\nSQLALCHEMY_DATABASE_URI_SQLITE = 'sqlite:///' + DB_SQLITE\n\n\nSQLALCHEMY_DATABASE_URI = SQLALCHEMY_DATABASE_URI_MYSQL\n# SQLALCHEMY_COMMIT_ON_TEARDOWN = True  # 打开自动提交 官方已经移除(http://flask-sqlalchemy.pocoo.org/2.1/changelog/#version-2-0)\nSQLALCHEMY_TRACK_MODIFICATIONS = False\nSQLALCHEMY_POOL_SIZE = 5  # 默认 pool_size=5\nSQLALCHEMY_POOL_TIMEOUT = 10  # 默认 10秒\nSQLALCHEMY_POOL_RECYCLE = 500  # 配置要小于 数据库配置 wait_timeout\nSQLALCHEMY_ECHO = False\n\n\nREDIS = {\n    'host': HOST_IP,\n    'port': 6379,\n    'db': 0,\n    'password': None\n}\n\nDB_MONGO = {\n    'host': HOST_IP,\n    'port': 27017,\n    'username': '',\n    'password': '',\n    'database': ''\n}\n\nRABBIT_MQ = {\n    'host': HOST_IP,\n    'port': 5672\n}\n\nEXCHANGE_NAME = 'amq.direct'\n\n# 验证码类型\nCAPTCHA_ENTITY = [\n    'reg',      # 注册\n    'login',    # 登录\n    'reset'     # 重置密码（找回密码）\n]\n\n\n# 短信签名（简称）\nSMS_SIGNER = u'网站签名'\n# 短信接口配置\nSMS = {\n    'UN': 'I6814767',           # 创蓝账号\n    'PW': 'UDqQ1dcvTg2052',     # 创蓝密码\n}\n\n# 隧道配置\nSSH_CONFIG = {\n    'IP': '120.76.40.92',\n    'PORT': 22,\n    'USERNAME': 'root',\n    'PASSWORD': 't3#R@r6FrTHK',\n    'DB_MYSQL': {\n        'host': '127.0.0.1',\n        'user': 'root',\n        'passwd': '..++**//520..',\n        'port': 3306,\n        'db': 'mm7w'\n    }\n}\n\n\nCSRF_ENABLED = True\nSECRET_KEY = '\\x03\\xabjR\\xbbg\\x82\\x0b{\\x96f\\xca\\xa8\\xbdM\\xb0x\\xdbK%\\xf2\\x07\\r\\x8c'\n\n# 会话配置\n# PERMANENT_SESSION_LIFETIME = timedelta(minutes=20)             # 登录状态保持，默认31天\nREMEMBER_COOKIE_DURATION = timedelta(days=14)   # 记住登录状态，默认365天\nLOGIN_MESSAGE = u'请登录后操作'\nLOGIN_MESSAGE_CATEGORY = 'warning'  # 默认'message'\n\n\n# 后台登录前台配置\nADMIN_TO_USER_LOGIN_TIME_OUT = 1200\nADMIN_TO_USER_LOGIN_SIGN_KEY = '1b106105da7e88e54d42e3f4356e41d8'\n\n# 用户推广链接配置\nUSER_INVITE_LINK_SIGN_KEY = 'ff99bae31b7bd480deee291dd55d6864'\n\n# 文件上传配置\nUPLOAD_FOLDER = os.path.join(BASE_DIR, 'app_frontend/static/uploads/')\n# ALLOWED_EXTENSIONS = {'txt', 'pdf', 'png', 'jpg', 'jpeg', 'gif'}\nALLOWED_EXTENSIONS = {'png', 'jpg', 'jpeg'}\nMAX_CONTENT_LENGTH = 2.6 * 1024 * 1024  # 2.6Mb\nMIN_CONTENT_LENGTH = 2.0 * 1024         # 2.0Kb\n\n# Celery 配置 （异步任务队列/基于分布式消息传递的作业队列）\nCELERY_BROKER_URL = 'amqp://guest:guest@localhost:5672//'\n# CELERY_BROKER_URL = 'redis://localhost:6379/0'\nCELERY_RESULT_BACKEND = 'amqp://guest:guest@localhost:5672//'\n# CELERY_RESULT_BACKEND = 'redis://localhost:6379/0'\n\n# 本地调试邮箱配置\n# $ sudo python -m smtpd -n -c DebuggingServer localhost:25\nMAIL_SERVER = 'localhost',\nMAIL_PORT = 25,\nMAIL_USERNAME = None,\nMAIL_PASSWORD = None,\nMAIL_DEFAULT_SENDER = ('no-reply', 'no-reply@localhost')\n# 后台管理人员邮件列表\nADMINS = ['455091702@qq.com']\n\n# 开发环境邮箱配置\n# MAIL_SERVER = 'smtp.163.com',\n# MAIL_PORT = 25,\n# MAIL_USERNAME = 'xxxxxx@163.com',\n# MAIL_PASSWORD = 'xxxxxx',\n# MAIL_DEFAULT_SENDER = (u'系统邮箱', 'zhang_he06@163.com')\n# # 后台管理人员邮件列表\n# ADMINS = ['455091702@qq.com']\n\n\n# sendcloud 邮件发送平台\nSENDCLOUD_API_USER = 'zhang_he_test_w6kIMK'\nSENDCLOUD_API_KEY = 'eZeC3Qwciv4o0lDH'\n\n# qiniu 云存储\nQINIU_ACCESS_KEY = 'i3Zi_VQOoeuMDnYkksWvn6TKa0_2C9Wb2NXMtrdn'\nQINIU_SECRET_KEY = 'B_0pOtxxaQX8aPqqdMqX2A5v0R99KYKgod5vbkXf'\nQINIU_BUCKET_NAME = 'zhendi-open'                       # 七牛空间名称\nQINIU_BUCKET_DOMAIN = '7xtmj9.com2.z0.glb.clouddn.com'  # 七牛空间对应域名\n\n# 第三方开放授权登陆\n\nGITHUB_OAUTH = {\n    'consumer_key': '0ccd9367a1f81288b127',\n    'consumer_secret': '711b6afcc938d760e9e57215dfbdcb115150ddc6',\n    'request_token_params': {'scope': 'user:email'},\n    'base_url': 'https://api.github.com/',\n    'request_token_url': None,\n    'access_token_method': 'POST',\n    'access_token_url': 'https://github.com/login/oauth/access_token',\n    'authorize_url': 'https://github.com/login/oauth/authorize'\n}\n\nQQ_OAUTH = {\n    'consumer_key': '101187283',  # QQ_APP_ID\n    'consumer_secret': '993983549da49e384d03adfead8b2489',  # QQ_APP_KEY\n    'base_url': 'https://graph.qq.com',\n    'request_token_url': None,\n    'request_token_params': {'scope': 'get_user_info'},\n    'access_token_url': '/oauth2.0/token',\n    'authorize_url': '/oauth2.0/authorize',\n}\n\nWEIBO_OAUTH = {\n    'consumer_key': '909122383',\n    'consumer_secret': '2cdc60e5e9e14398c1cbdf309f2ebd3a',\n    'request_token_params': {'scope': 'email,statuses_to_me_read'},\n    'base_url': 'https://api.weibo.com/2/',\n    'authorize_url': 'https://api.weibo.com/oauth2/authorize',\n    'request_token_url': None,\n    'access_token_method': 'POST',\n    'access_token_url': 'https://api.weibo.com/oauth2/access_token',\n    # since weibo's response is a shit, we need to force parse the content\n    'content_type': 'application/json',\n}\n\n\n# 日志参数配置\nLOG_CONFIG = {\n    'version': 1,\n    'formatters': {\n        'simple': {\n            'format': '%(asctime)s - %(name)s - %(levelname)s - %(message)s'\n        },\n        'detail': {\n            'format': '%(asctime)s - %(name)s - File: %(filename)s - line: %(lineno)d - %(funcName)s() - %(levelname)s - %(message)s'\n        },\n    },\n    'handlers': {\n        'console': {\n            'class': 'logging.StreamHandler',\n            'formatter': 'simple',\n            'level': 'INFO'\n        },\n        'file_app': {\n            'class': 'logging.handlers.TimedRotatingFileHandler',\n            'formatter': 'detail',\n            'level': 'DEBUG',\n            'when': 'D',\n            'filename': BASE_DIR + '/logs/app.log'\n        },\n        'file_db': {\n            'class': 'logging.handlers.TimedRotatingFileHandler',\n            'formatter': 'detail',\n            'level': 'DEBUG',\n            'when': 'D',\n            'filename': BASE_DIR + '/logs/db.log'\n        }\n    },\n    'loggers': {\n        'app': {\n            'handlers': ['console', 'file_app'],\n            'level': 'DEBUG'\n        },\n        'db': {\n            'handlers': ['file_db'],\n            'level': 'DEBUG'\n        }\n    }\n}\n\n\nif __name__ == '__main__':\n    import os\n    import binascii\n\n    sk = os.urandom(16)\n    print sk\n    print binascii.b2a_hex(sk)\n    print BASE_DIR\n    print UPLOAD_FOLDER\n    print SQLALCHEMY_DATABASE_URI\n    print HOST_IP\n"
  },
  {
    "path": "config/product/settings/__init__.py",
    "content": "#!/usr/bin/env python\n# encoding: utf-8\n\n\"\"\"\n@author: zhanghe\n@software: PyCharm\n@file: __init__.py.py\n@time: 2017/4/27 下午6:45\n\"\"\"\n\n\n# 开关状态\nON = True\nOFF = False\n\n\n# 网站配置\nPER_PAGE_FRONTEND = 12   # 分页显示数据条数 前台\nPER_PAGE_BACKEND = 12   # 分页显示数据条数 后台\n\n# 功能开关\n\nSWITCH_EXPORT = OFF         # 导出\n\nSWITCH_REG_ACCOUNT = ON     # 用户账号注册\nSWITCH_REG_PHONE = OFF      # 用户手机注册\nSWITCH_REG_EMAIL = OFF      # 用户邮箱注册\n\nSWITCH_REG_THREE_PART = OFF     # 第三方平台注册\n\nSWITCH_LOGIN_ACCOUNT = ON   # 用户账号登录\nSWITCH_LOGIN_PHONE = ON     # 用户手机登录\nSWITCH_LOGIN_EMAIL = ON     # 用户邮箱登录\n\nSWITCH_LOGIN_THREE_PART = OFF     # 第三方平台登录\n"
  },
  {
    "path": "config/product/settings/apply.py",
    "content": "#!/usr/bin/env python\n# encoding: utf-8\n\n\"\"\"\n@author: zhanghe\n@software: PyCharm\n@file: apply.py\n@time: 2017/4/29 下午1:11\n\"\"\"\n\n\n# [投资配置]\n# 单次投资金额范围\nAPPLY_PUT_MIN_EACH = 2000  # 最小值\nAPPLY_PUT_MAX_EACH = 20000  # 最大值\nAPPLY_PUT_STEP = 1000  # 投资金额步长（基数）\n\n# 单个用户投资限制\nAPPLY_PUT_USER_MAX_AMOUNT = 30000  # 单个用户投资最大交易中金额\nAPPLY_PUT_USER_MAX_COUNT = 1  # 单个用户投资最大交易中单数(0 表示不限制)\n\n# 每日投资限制\nAPPLY_PUT_MAX_AMOUNT_DAILY = 1000000  # 最大金额\nAPPLY_PUT_MAX_COUNT_DAILY = 1000  # 最大数量(0 表示不限制)\n\n# 每月投资限制\nAPPLY_PUT_MAX_AMOUNT_MONTHLY = 30000000  # 最大值\nAPPLY_PUT_MAX_COUNT_MONTHLY = 30000  # 最大数量(0 表示不限制)\n\n# 投资时间配置\nAPPLY_PUT_TIME_START = '00:00:00'  # 每天投资申请开始时间\nAPPLY_PUT_TIME_END = '23:59:59'  # 每天投资申请结束时间\n\n# 分红配置\nAPPLY_PUT_DAYS_BONUS = 15  # 分红计算天数\nAPPLY_PUT_DAYS_LOCK = 15  # 投资锁定天数、提现冻结天数\n\nAPPLY_PUT_INTEREST_ON_PRINCIPAL_TTL = 3600 * 24 * 15  # 投资申请后15天完成的订单执行回收本息\n\n\n# [提现配置]\n# 单次提现金额范围\nAPPLY_GET_MIN_EACH = 2000  # 最小值\nAPPLY_GET_MAX_EACH = 20000  # 最大值\nAPPLY_GET_STEP = 1000  # 投资金额步长（基数）\n\n# 单个用户提现限制\nAPPLY_GET_USER_MAX_AMOUNT = 30000  # 单个用户提现最大交易中金额\nAPPLY_GET_USER_MAX_COUNT = 1  # 单个用户提现最大交易中单数(0 表示不限制)\n\n# 每日提现限制\nAPPLY_GET_MAX_AMOUNT_DAILY = 1000000  # 最大金额\nAPPLY_GET_MAX_COUNT_DAILY = 1000  # 最大数量(0 表示不限制)\n\n# 每月提现限制\nAPPLY_GET_MAX_AMOUNT_MONTHLY = 30000000  # 最大值\nAPPLY_GET_MAX_COUNT_MONTHLY = 30000  # 最大数量(0 表示不限制)\n\n# 提现时间配置\nAPPLY_GET_TIME_START = '00:00:00'  # 每天提现申请开始时间\nAPPLY_GET_TIME_END = '23:59:59'  # 每天提现申请结束时间\n"
  },
  {
    "path": "config/product/settings/interest.py",
    "content": "#!/usr/bin/env python\n# encoding: utf-8\n\n\"\"\"\n@author: zhanghe\n@software: PyCharm\n@file: interest.py\n@time: 2017/6/4 下午11:03\n\"\"\"\n\n\n# 利息配置\nINTEREST_PUT = 0.01  # 投资利息（日息）\n\n# 支付奖惩比例\nINTEREST_PAY_AHEAD = 0.02  # 提前支付奖金比例\nINTEREST_PAY_DELAY = 0.02  # 延迟支付罚金比例\n\n# 支付时间差\nDIFF_TIME_PAY_AHEAD = 60*60*1   # 提前支付奖金时间差\nDIFF_TIME_PAY_DELAY = 60*60*24  # 延迟支付罚金时间差\n\n# 确认奖惩比例\nINTEREST_REC_AHEAD = 0.02  # 提前确认奖金比例\nINTEREST_REC_DELAY = 0.02  # 延迟确认罚金比例\n\n# 确认时间差\nDIFF_TIME_REC_AHEAD = 60*60*1   # 提前确认奖金时间差\nDIFF_TIME_REC_DELAY = 60*60*24  # 延迟确认罚金时间差\n"
  },
  {
    "path": "config/product/settings/order.py",
    "content": "#!/usr/bin/env python\n# encoding: utf-8\n\n\"\"\"\n@author: zhanghe\n@software: PyCharm\n@file: order.py\n@time: 2017/4/29 下午1:12\n\"\"\"\n\n\n# 订单限制\nORDER_MAX_AMOUNT = 10000  # 订单最大金额\nORDER_MAX_COUNT = 100  # 订单最大数量\n\n# 系统自动确认收款\nPAY_AUTO_REC_TTL = 60*60*48  # 系统在订单支付成功后超过48小时未确认收款，自动确认收款\n\n# 推广奖励\n\nBONUS_DIRECT = 0.03  # 直接推荐奖励\n\nBONUS_LEVEL_FIRST = 0.05        # 一级推荐奖励\nBONUS_LEVEL_SECOND = 0.05       # 二级推荐奖励\nBONUS_LEVEL_THIRD = 0.03        # 三级推荐奖励\n\n# BONUS_LEVEL = [BONUS_LEVEL_FIRST, BONUS_LEVEL_SECOND, BONUS_LEVEL_THIRD]\n"
  },
  {
    "path": "config/product/settings/sms.py",
    "content": "#!/usr/bin/env python\n# encoding: utf-8\n\n\"\"\"\n@author: zhanghe\n@software: PyCharm\n@file: sms_msg.py\n@time: 2017/4/21 下午4:57\n\"\"\"\n\n\n# 短信验证码\nSMS_CODE_REG = u'【网站签名】%s，是您注册的验证码'\nSMS_CODE_LOGIN = u'【网站签名】%s，是您登录的验证码'\nSMS_CODE_RESET = u'【网站签名】%s，是您重置密码的验证码'\nSMS_CODE_EDIT = u'【网站签名】%s，是您修改资料的验证码'\n\n# 订单通知\nNOTICE_ORDER_CREATE = u'【网站签名】您的订单已经创建成功'\nNOTICE_ORDER_CANCEL = u'【网站签名】您的订单已经取消成功'\nNOTICE_ORDER_PAYED = u'【网站签名】您的订单已经支付成功'\nNOTICE_ORDER_CONFIRM = u'【网站签名】您的订单已经确认完成'\n\n# 事件通知\nNOTICE_EVENT_ACTIVE = u'【网站签名】您的账号已经激活成功'\nNOTICE_EVENT_LOCK = u'【网站签名】您的账号当前已经锁定'\nNOTICE_EVENT_UNLOCK = u'【网站签名】您的账号已经解除锁定'\n"
  },
  {
    "path": "config/product/settings/user.py",
    "content": "#!/usr/bin/env python\n# encoding: utf-8\n\n\"\"\"\n@author: zhanghe\n@software: PyCharm\n@file: user.py\n@time: 2017/4/29 下午1:12\n\"\"\"\n\n\n# 用户配置\n\n# 自动封号\nLOCK_REG_NOT_ACTIVE_TTL = 3600*24*3     # 注册后3天内未激活\nLOCK_ACTIVE_NOT_PUT_TTL = 3600*24*3     # 激活后3天内未排单\nLOCK_ORDER_NOT_PAY_TTL = 3600*36        # 匹配后超过36小时不打款\nLOCK_PAY_NOT_REC_TTL = 3600*36          # 收款后36小时不确认\n\n"
  },
  {
    "path": "db/data/mysql.sql",
    "content": "USE flask_project;\n\n-- 插入用户全局注册信息\nTRUNCATE TABLE `user`;\nINSERT INTO `user` VALUES (1, '1', '0', '0', '0', '2017-01-11 11:01:10', NULL, NULL, '127.0.0.1', NULL, '2017-01-11 11:01:10', '2017-01-10 23:01:05', '2017-01-11 11:01:05');\nINSERT INTO `user` VALUES (2, '1', '0', '0', '0', '2017-02-11 11:01:10', NULL, NULL, '127.0.0.1', NULL, '2017-02-11 11:01:10', '2017-01-11 01:01:05', '2017-02-11 11:01:05');\nINSERT INTO `user` VALUES (3, '1', '0', '0', '0', '2017-03-11 11:01:10', NULL, NULL, '127.0.0.1', NULL, '2017-03-11 11:01:10', '2017-01-12 11:01:05', '2017-03-11 11:01:05');\nINSERT INTO `user` VALUES (4, '1', '0', '0', '0', '2017-03-11 11:01:10', NULL, NULL, '127.0.0.1', NULL, '2017-03-11 11:01:10', '2017-01-13 11:01:05', '2017-03-11 11:01:05');\nINSERT INTO `user` VALUES (5, '1', '0', '0', '0', '2017-03-11 11:01:10', NULL, NULL, '127.0.0.1', NULL, '2017-03-11 11:01:10', '2017-01-15 11:01:05', '2017-03-11 11:01:05');\nINSERT INTO `user` VALUES (6, '1', '0', '0', '0', '2017-03-11 11:01:10', NULL, NULL, '127.0.0.1', NULL, '2017-03-11 11:01:10', '2017-01-15 12:01:05', '2017-03-11 11:01:05');\nINSERT INTO `user` VALUES (7, '1', '0', '0', '0', '2017-03-11 11:01:10', NULL, NULL, '127.0.0.1', NULL, '2017-03-11 11:01:10', '2017-01-16 11:01:05', '2017-03-11 11:01:05');\nINSERT INTO `user` VALUES (8, '1', '0', '0', '0', '2017-03-11 11:01:10', NULL, NULL, '127.0.0.1', NULL, '2017-03-11 11:01:10', '2017-01-17 11:01:05', '2017-03-11 11:01:05');\nINSERT INTO `user` VALUES (9, '1', '0', '0', '0', '2017-03-11 11:01:10', NULL, NULL, '127.0.0.1', NULL, '2017-03-11 11:01:10', '2017-01-18 11:01:05', '2017-03-11 11:01:05');\nINSERT INTO `user` VALUES (10, '1', '0', '0', '0', '2017-03-11 11:01:10', NULL, NULL, '127.0.0.1', NULL, '2017-03-11 11:01:10', '2017-01-19 11:01:05', '2017-03-11 11:01:05');\nINSERT INTO `user` VALUES (11, '1', '0', '0', '0', '2017-03-11 11:01:10', NULL, NULL, '127.0.0.1', NULL, '2017-03-11 11:01:10', '2017-02-01 04:01:05', '2017-03-11 11:01:05');\nINSERT INTO `user` VALUES (12, '1', '0', '0', '0', '2017-03-11 11:01:10', NULL, NULL, '127.0.0.1', NULL, '2017-03-11 11:01:10', '2017-02-01 09:01:05', '2017-03-11 11:01:05');\nINSERT INTO `user` VALUES (13, '1', '0', '0', '0', '2017-03-11 11:01:10', NULL, NULL, '127.0.0.1', NULL, '2017-03-11 11:01:10', '2017-02-12 11:01:05', '2017-03-11 11:01:05');\nINSERT INTO `user` VALUES (14, '1', '0', '0', '0', '2017-03-11 11:01:10', NULL, NULL, '127.0.0.1', NULL, '2017-03-11 11:01:10', '2017-03-01 11:01:05', '2017-03-11 11:01:05');\nINSERT INTO `user` VALUES (15, '1', '0', '0', '0', '2017-03-11 11:01:10', NULL, NULL, '127.0.0.1', NULL, '2017-03-11 11:01:10', '2017-03-02 11:01:05', '2017-03-11 11:01:05');\nINSERT INTO `user` VALUES (16, '1', '0', '0', '0', '2017-03-11 11:01:10', NULL, NULL, '127.0.0.1', NULL, '2017-03-11 11:01:10', '2017-03-03 11:01:05', '2017-03-11 11:01:05');\nINSERT INTO `user` VALUES (17, '1', '0', '0', '0', '2017-03-11 11:01:10', NULL, NULL, '127.0.0.1', NULL, '2017-03-11 11:01:10', '2017-03-04 11:01:05', '2017-03-11 11:01:05');\nINSERT INTO `user` VALUES (18, '1', '0', '0', '0', '2017-03-11 11:01:10', NULL, NULL, '127.0.0.1', NULL, '2017-03-11 11:01:10', '2017-03-11 11:01:05', '2017-03-11 11:01:05');\nINSERT INTO `user` VALUES (19, '1', '0', '0', '0', '2017-03-11 11:01:10', NULL, NULL, '127.0.0.1', NULL, '2017-03-11 11:01:10', '2017-03-11 11:01:05', '2017-03-11 11:01:05');\nINSERT INTO `user` VALUES (20, '1', '0', '0', '0', '2017-03-11 11:01:10', NULL, NULL, '127.0.0.1', NULL, '2017-03-11 11:01:10', '2017-03-11 11:01:05', '2017-03-11 11:01:05');\n\n-- 插入用户认证信息\nTRUNCATE TABLE `user_auth`;\nINSERT INTO `user_auth` VALUES (1, 1, 0, 'Admin', 'e10adc3949ba59abbe56e057f20f883e', '1', '2017-01-11 11:01:05', '2017-01-11 11:01:05');\nINSERT INTO `user_auth` VALUES (2, 2, 0, 'Guest', 'e10adc3949ba59abbe56e057f20f883e', '1', '2017-01-12 12:25:34', '2017-01-12 12:25:34');\nINSERT INTO `user_auth` VALUES (3, 3, 0, 'Test', 'e10adc3949ba59abbe56e057f20f883e', '1', '2017-01-12 01:43:42', '2017-01-12 01:43:42');\nINSERT INTO `user_auth` VALUES (4, 1, 1, 'admin@gmail.com', 'e10adc3949ba59abbe56e057f20f883e', '1', '2017-01-11 11:01:05', '2017-01-11 11:01:05');\nINSERT INTO `user_auth` VALUES (5, 2, 1, 'guest@gmail.com', 'e10adc3949ba59abbe56e057f20f883e', '1', '2017-01-12 12:25:34', '2017-01-12 12:25:34');\nINSERT INTO `user_auth` VALUES (6, 3, 1, 'test@gmail.com', 'e10adc3949ba59abbe56e057f20f883e', '1', '2017-01-12 01:43:42', '2017-01-12 01:43:42');\nINSERT INTO `user_auth` VALUES (7, 1, 2, '8613800001111', 'e10adc3949ba59abbe56e057f20f883e', '1', '2017-01-11 11:01:05', '2017-01-11 11:01:05');\nINSERT INTO `user_auth` VALUES (8, 2, 2, '8613800002222', 'e10adc3949ba59abbe56e057f20f883e', '1', '2017-01-12 12:25:34', '2017-01-12 12:25:34');\nINSERT INTO `user_auth` VALUES (9, 3, 2, '8613800003333', 'e10adc3949ba59abbe56e057f20f883e', '1', '2017-01-12 01:43:42', '2017-01-12 01:43:42');\nINSERT INTO `user_auth` VALUES (10, 4, 0, 'Git', 'e10adc3949ba59abbe56e057f20f883e', '1', '2017-01-12 01:43:42', '2017-01-12 01:43:42');\nINSERT INTO `user_auth` VALUES (11, 5, 0, 'Hub', 'e10adc3949ba59abbe56e057f20f883e', '1', '2017-01-12 01:43:42', '2017-01-12 01:43:42');\nINSERT INTO `user_auth` VALUES (12, 6, 0, 'Lab', 'e10adc3949ba59abbe56e057f20f883e', '1', '2017-01-12 01:43:42', '2017-01-12 01:43:42');\nINSERT INTO `user_auth` VALUES (13, 7, 0, 'Tony', 'e10adc3949ba59abbe56e057f20f883e', '1', '2017-01-12 01:43:42', '2017-01-12 01:43:42');\nINSERT INTO `user_auth` VALUES (14, 8, 0, 'Sunny', 'e10adc3949ba59abbe56e057f20f883e', '1', '2017-01-12 01:43:42', '2017-01-12 01:43:42');\nINSERT INTO `user_auth` VALUES (15, 9, 0, 'Left', 'e10adc3949ba59abbe56e057f20f883e', '1', '2017-01-12 01:43:42', '2017-01-12 01:43:42');\nINSERT INTO `user_auth` VALUES (16, 10, 0, 'Right', 'e10adc3949ba59abbe56e057f20f883e', '1', '2017-01-12 01:43:42', '2017-01-12 01:43:42');\nINSERT INTO `user_auth` VALUES (17, 11, 0, 'Height', 'e10adc3949ba59abbe56e057f20f883e', '1', '2017-01-12 01:43:42', '2017-01-12 01:43:42');\nINSERT INTO `user_auth` VALUES (18, 12, 0, 'With', 'e10adc3949ba59abbe56e057f20f883e', '1', '2017-01-12 01:43:42', '2017-01-12 01:43:42');\nINSERT INTO `user_auth` VALUES (19, 13, 0, 'Phone', 'e10adc3949ba59abbe56e057f20f883e', '1', '2017-01-12 01:43:42', '2017-01-12 01:43:42');\nINSERT INTO `user_auth` VALUES (20, 14, 0, 'Email', 'e10adc3949ba59abbe56e057f20f883e', '1', '2017-01-12 01:43:42', '2017-01-12 01:43:42');\nINSERT INTO `user_auth` VALUES (21, 15, 0, 'Desk', 'e10adc3949ba59abbe56e057f20f883e', '1', '2017-01-12 01:43:42', '2017-01-12 01:43:42');\nINSERT INTO `user_auth` VALUES (22, 16, 0, 'Car', 'e10adc3949ba59abbe56e057f20f883e', '1', '2017-01-12 01:43:42', '2017-01-12 01:43:42');\nINSERT INTO `user_auth` VALUES (23, 17, 0, 'Mart', 'e10adc3949ba59abbe56e057f20f883e', '1', '2017-01-12 01:43:42', '2017-01-12 01:43:42');\nINSERT INTO `user_auth` VALUES (24, 18, 0, 'Light', 'e10adc3949ba59abbe56e057f20f883e', '1', '2017-01-12 01:43:42', '2017-01-12 01:43:42');\nINSERT INTO `user_auth` VALUES (25, 19, 0, 'Window', 'e10adc3949ba59abbe56e057f20f883e', '1', '2017-01-12 01:43:42', '2017-01-12 01:43:42');\nINSERT INTO `user_auth` VALUES (26, 20, 0, 'Floor', 'e10adc3949ba59abbe56e057f20f883e', '1', '2017-01-12 01:43:42', '2017-01-12 01:43:42');\n\n-- 插入用户基本信息\nTRUNCATE TABLE `user_profile`;\nINSERT INTO `user_profile` VALUES (1, 0, 'Admin', 0, NULL, 'admin@gmail.com', 0, '86', '13800001111', '1900-01-01', 'Admin', '123456789098765432', '2017-01-11 11:01:05', '2017-01-11 11:01:05');\nINSERT INTO `user_profile` VALUES (2, 1, 'Guest', 0, NULL, 'guest@gmail.com', 0, '86', '13800002222', '1900-01-01', 'Guest', '123456789098765433', '2017-01-12 12:25:34', '2017-01-12 12:25:34');\nINSERT INTO `user_profile` VALUES (3, 1, 'Test', 0, NULL, 'test@gmail.com', 0, '86', '13800003333', '1900-01-01', 'Test', '123456789098765434', '2017-01-12 01:43:42', '2017-01-12 01:43:42');\nINSERT INTO `user_profile` VALUES (4, 2, 'Git', 0, NULL, 'git@gmail.com', 0, '86', '13800004444', '1900-01-01', 'Git', '123456789098765435', '2017-01-12 01:43:42', '2017-01-12 01:43:42');\nINSERT INTO `user_profile` VALUES (5, 2, 'Hub', 0, NULL, 'hub@gmail.com', 0, '86', '13800005555', '1900-01-01', 'Hub', '123456789098765436', '2017-01-12 01:43:42', '2017-01-12 01:43:42');\nINSERT INTO `user_profile` VALUES (6, 2, 'Lab', 0, NULL, 'lab@gmail.com', 0, '86', '13800006666', '1900-01-01', 'Lab', '123456789098765437', '2017-01-12 01:43:42', '2017-01-12 01:43:42');\nINSERT INTO `user_profile` VALUES (7, 3, 'Tony', 0, NULL, 'tony@gmail.com', 0, '86', '13800007777', '1900-01-01', 'Tony', '123456789098765438', '2017-01-12 01:43:42', '2017-01-12 01:43:42');\nINSERT INTO `user_profile` VALUES (8, 3, 'Sunny', 0, NULL, 'sunny@gmail.com', 0, '86', '13800008888', '1900-01-01', 'Sunny', '123456789098765439', '2017-01-12 01:43:42', '2017-01-12 01:43:42');\nINSERT INTO `user_profile` VALUES (9, 3, 'Left', 0, NULL, 'left@gmail.com', 0, '86', '13800009999', '1900-01-01', 'Left', '123456789098765440', '2017-01-12 01:43:42', '2017-01-12 01:43:42');\nINSERT INTO `user_profile` VALUES (10, 4, 'Right', 0, NULL, 'right@gmail.com', 0, '86', '13811110000', '1900-01-01', 'Right', '123456789098765441', '2017-01-12 01:43:42', '2017-01-12 01:43:42');\nINSERT INTO `user_profile` VALUES (11, 4, 'Height', 0, NULL, 'height@gmail.com', 0, '86', '13811111111', '1900-01-01', 'Height', '123456789098765442', '2017-01-12 01:43:42', '2017-01-12 01:43:42');\nINSERT INTO `user_profile` VALUES (12, 5, 'With', 0, NULL, 'with@gmail.com', 0, '86', '13811112222', '1900-01-01', 'With', '123456789098765443', '2017-01-12 01:43:42', '2017-01-12 01:43:42');\nINSERT INTO `user_profile` VALUES (13, 5, 'Phone', 0, NULL, 'phone@gmail.com', 0, '86', '13811113333', '1900-01-01', 'Phone', '123456789098765444', '2017-01-12 01:43:42', '2017-01-12 01:43:42');\nINSERT INTO `user_profile` VALUES (14, 5, 'Email', 0, NULL, 'email@gmail.com', 0, '86', '13811114444', '1900-01-01', 'Email', '123456789098765445', '2017-01-12 01:43:42', '2017-01-12 01:43:42');\nINSERT INTO `user_profile` VALUES (15, 5, 'Desk', 0, NULL, 'desk@gmail.com', 0, '86', '13811115555', '1900-01-01', 'Desk', '123456789098765446', '2017-01-12 01:43:42', '2017-01-12 01:43:42');\nINSERT INTO `user_profile` VALUES (16, 6, 'Car', 0, NULL, 'car@gmail.com', 0, '86', '13811116666', '1900-01-01', 'Car', '123456789098765447', '2017-01-12 01:43:42', '2017-01-12 01:43:42');\nINSERT INTO `user_profile` VALUES (17, 7, 'Mart', 0, NULL, 'mart@gmail.com', 0, '86', '13811117777', '1900-01-01', 'Mart', '123456789098765448', '2017-01-12 01:43:42', '2017-01-12 01:43:42');\nINSERT INTO `user_profile` VALUES (18, 8, 'Light', 0, NULL, 'light@gmail.com', 0, '86', '13811118888', '1900-01-01', 'Light', '123456789098765449', '2017-01-12 01:43:42', '2017-01-12 01:43:42');\nINSERT INTO `user_profile` VALUES (19, 9, 'Window', 0, NULL, 'window@gmail.com', 0, '86', '13811119999', '1900-01-01', 'Window', '123456789098765450', '2017-01-12 01:43:42', '2017-01-12 01:43:42');\nINSERT INTO `user_profile` VALUES (20, 9, 'Floor', 0, NULL, 'floor@gmail.com', 0, '86', '13822220000', '1900-01-01', 'Floor', '123456789098765451', '2017-01-12 01:43:42', '2017-01-12 01:43:42');\n\n-- 插入用户银行信息\nTRUNCATE TABLE `user_bank`;\nINSERT INTO `user_bank` VALUES (1, 'Admin', '建行', '上海分行', '1234567890', 0, 0, '2017-01-11 11:01:05', '2017-01-11 11:01:05');\nINSERT INTO `user_bank` VALUES (2, 'Guest', '农行', '上海分行', '1234567891', 0, 0, '2017-01-11 11:01:05', '2017-01-11 11:01:05');\nINSERT INTO `user_bank` VALUES (5, 'Hub', '农行', '上海分行', '1234567892', 0, 0, '2017-01-11 11:01:05', '2017-01-11 11:01:05');\nINSERT INTO `user_bank` VALUES (15, 'Desk', '农行', '上海分行', '1234567892', 0, 0, '2017-01-11 11:01:05', '2017-01-11 11:01:05');\nINSERT INTO `user_bank` VALUES (19, 'Window', '农行', '上海分行', '1234567892', 0, 0, '2017-01-11 11:01:05', '2017-01-11 11:01:05');\n\n-- 插入管理员基本信息\nTRUNCATE TABLE `admin`;\nINSERT INTO `admin` VALUES (1, 'admin', 'e10adc3949ba59abbe56e057f20f883e', 0, '86', '13800002222', 1, '0', NULL, NULL, NULL, '2017-01-12 12:25:34', '2017-01-12 12:25:34');\n\n-- 插入角色权限信息\nTRUNCATE TABLE `admin_role`;\nINSERT INTO `admin_role` VALUES (1, '系统', '系统角色', '会员,订单,留言,系统,权限,统计', '2017-01-12 12:25:34', '2017-01-12 12:25:34');\nINSERT INTO `admin_role` VALUES (2, '客服', '客服角色', '会员,留言,统计', '2017-01-12 12:25:34', '2017-01-12 12:25:34');\nINSERT INTO `admin_role` VALUES (3, '运营', '运营角色', '订单,留言,统计', '2017-01-12 12:25:34', '2017-01-12 12:25:34');\nINSERT INTO `admin_role` VALUES (4, '市场', '市场角色', '会员,统计', '2017-01-12 12:25:34', '2017-01-12 12:25:34');\nINSERT INTO `admin_role` VALUES (5, '销售', '销售角色', '', '2017-01-12 12:25:34', '2017-01-12 12:25:34');\nINSERT INTO `admin_role` VALUES (6, '普通', '普通角色', '', '2017-01-12 12:25:34', '2017-01-12 12:25:34');\nINSERT INTO `admin_role` VALUES (7, '高级', '高级角色', '会员,订单,留言,统计', '2017-01-12 12:25:34', '2017-01-12 12:25:34');\n\n-- 插入用户声望\nTRUNCATE TABLE `credit`;\nINSERT INTO `credit` VALUES (1, 85, 30, 62, 50, 67, 360, '2017-01-12 12:25:34', '2017-01-12 12:25:34');\nINSERT INTO `credit` VALUES (2, 75, 40, 72, 41, 66, 360, '2017-01-12 12:25:34', '2017-01-12 12:25:34');\n\n-- 插入投资申请记录\nTRUNCATE TABLE `apply_put`;\nINSERT INTO `apply_put` VALUES (1, 1, 0, 0, 1000.00, 0.00, 1, 0, 0, null, '2017-05-06 08:43:00', '2017-05-06 08:43:00');\nINSERT INTO `apply_put` VALUES (2, 1, 0, 0, 2000.00, 2000.00, 1, 2, 0, null, '2017-05-06 08:43:05', '2017-05-06 08:47:07');\nINSERT INTO `apply_put` VALUES (3, 1, 0, 0, 3000.00, 0.00, 1, 0, 0, null, '2017-05-06 08:43:10', '2017-05-06 08:43:10');\nINSERT INTO `apply_put` VALUES (4, 2, 0, 0, 1200.00, 0.00, 1, 0, 0, null, '2017-05-06 08:43:39', '2017-05-06 08:43:39');\nINSERT INTO `apply_put` VALUES (5, 2, 0, 0, 2200.00, 0.00, 1, 0, 0, null, '2017-05-06 08:43:44', '2017-05-06 08:43:44');\nINSERT INTO `apply_put` VALUES (6, 2, 0, 0, 3200.00, 0.00, 1, 0, 0, null, '2017-05-06 08:43:48', '2017-05-06 08:43:48');\nINSERT INTO `apply_put` VALUES (7, 3, 0, 0, 400.00, 400.00, 1, 2, 0, null, '2017-05-06 08:44:13', '2017-05-06 08:47:07');\nINSERT INTO `apply_put` VALUES (8, 3, 0, 0, 600.00, 0.00, 1, 0, 0, null, '2017-05-06 08:44:17', '2017-05-06 08:44:17');\nINSERT INTO `apply_put` VALUES (9, 3, 0, 0, 800.00, 800.00, 1, 2, 0, null, '2017-05-06 08:44:21', '2017-05-06 08:47:07');\nINSERT INTO `apply_put` VALUES (10, 15, 0, 0, 2000.00, 2000.00, 1, 2, 0, null, '2017-05-06 08:44:21', '2017-05-06 08:47:07');\n\n-- 插入提现申请记录\nTRUNCATE TABLE `apply_get`;\nINSERT INTO `apply_get` VALUES (1, 1, 0, 0, 0, 1000.00, 0.00, 1, 0, 0, null, '2017-05-06 08:43:15', '2017-05-06 08:43:15');\nINSERT INTO `apply_get` VALUES (2, 1, 0, 0, 0, 2000.00, 0.00, 1, 0, 0, null, '2017-05-06 08:43:22', '2017-05-06 08:43:22');\nINSERT INTO `apply_get` VALUES (3, 1, 0, 0, 0, 3000.00, 0.00, 1, 0, 0, null, '2017-05-06 08:43:27', '2017-05-06 08:43:27');\nINSERT INTO `apply_get` VALUES (4, 2, 0, 0, 0, 1200.00, 0.00, 1, 0, 0, null, '2017-05-06 08:43:53', '2017-05-06 08:43:53');\nINSERT INTO `apply_get` VALUES (5, 2, 0, 0, 0, 2200.00, 0.00, 1, 0, 0, null, '2017-05-06 08:43:58', '2017-05-06 08:43:58');\nINSERT INTO `apply_get` VALUES (6, 2, 0, 0, 0, 3200.00, 3200.00, 1, 2, 0, null, '2017-05-06 08:44:02', '2017-05-06 08:47:07');\nINSERT INTO `apply_get` VALUES (7, 3, 0, 0, 0, 400.00, 0.00, 1, 0, 0, null, '2017-05-06 08:44:25', '2017-05-06 08:44:25');\nINSERT INTO `apply_get` VALUES (8, 3, 0, 0, 0, 600.00, 0.00, 1, 0, 0, null, '2017-05-06 08:44:28', '2017-05-06 08:44:28');\nINSERT INTO `apply_get` VALUES (9, 3, 0, 0, 0, 800.00, 0.00, 1, 0, 0, null, '2017-05-06 08:44:32', '2017-05-06 08:44:32');\nINSERT INTO `apply_get` VALUES (10, 19, 0, 0, 0, 2000.00, 2000.00, 1, 2, 0, null, '2017-05-06 08:44:32', '2017-05-06 08:44:32');\n\n\n-- 插入订单记录\nTRUNCATE TABLE `order`;\nINSERT INTO `order` VALUES (1, 2, 6, 1, 2, 0, 2000.00, 1, 0, 0, 0, 0, '2017-05-06 08:47:07', null, null, null, '2017-05-06 08:47:07', '2017-05-06 08:47:07');\nINSERT INTO `order` VALUES (2, 7, 6, 3, 2, 0, 400.00, 1, 0, 0, 0, 0, '2017-05-06 08:47:07', null, null, null, '2017-05-06 08:47:07', '2017-05-06 08:47:07');\nINSERT INTO `order` VALUES (3, 9, 6, 3, 2, 0, 800.00, 1, 0, 0, 0, 0, '2017-05-06 08:47:07', null, null, null, '2017-05-06 08:47:07', '2017-05-06 08:47:07');\nINSERT INTO `order` VALUES (4, 10, 10, 15, 19, 0, 2000.00, 1, 0, 1, 1, 0, '2017-05-06 08:47:07', null, null, null, '2017-05-06 08:47:07', '2017-05-06 08:47:07');\n\n-- 插入订单凭证\nTRUNCATE TABLE `order_bill`;\n\n-- 插入钱包总表\nTRUNCATE TABLE `wallet`;\nINSERT INTO `wallet` VALUES (1, '10000.00', '24000.00', 0, '2017-01-12 12:25:34', '2017-01-12 12:25:34');\nINSERT INTO `wallet` VALUES (2, '10000.00', '24000.00', 0, '2017-01-12 12:25:34', '2017-01-12 12:25:34');\nINSERT INTO `wallet` VALUES (3, '10000.00', '24000.00', 0, '2017-01-12 12:25:34', '2017-01-12 12:25:34');\nINSERT INTO `wallet` VALUES (4, '10000.00', '24000.00', 0, '2017-01-12 12:25:34', '2017-01-12 12:25:34');\nINSERT INTO `wallet` VALUES (5, '10000.00', '24000.00', 0, '2017-01-12 12:25:34', '2017-01-12 12:25:34');\nINSERT INTO `wallet` VALUES (6, '10000.00', '24000.00', 0, '2017-01-12 12:25:34', '2017-01-12 12:25:34');\nINSERT INTO `wallet` VALUES (7, '10000.00', '24000.00', 0, '2017-01-12 12:25:34', '2017-01-12 12:25:34');\nINSERT INTO `wallet` VALUES (8, '10000.00', '24000.00', 0, '2017-01-12 12:25:34', '2017-01-12 12:25:34');\nINSERT INTO `wallet` VALUES (9, '10000.00', '24000.00', 0, '2017-01-12 12:25:34', '2017-01-12 12:25:34');\nINSERT INTO `wallet` VALUES (10, '10000.00', '24000.00', 0, '2017-01-12 12:25:34', '2017-01-12 12:25:34');\nINSERT INTO `wallet` VALUES (11, '10000.00', '24000.00', 0, '2017-01-12 12:25:34', '2017-01-12 12:25:34');\nINSERT INTO `wallet` VALUES (12, '10000.00', '24000.00', 0, '2017-01-12 12:25:34', '2017-01-12 12:25:34');\nINSERT INTO `wallet` VALUES (13, '10000.00', '24000.00', 0, '2017-01-12 12:25:34', '2017-01-12 12:25:34');\nINSERT INTO `wallet` VALUES (14, '10000.00', '24000.00', 0, '2017-01-12 12:25:34', '2017-01-12 12:25:34');\nINSERT INTO `wallet` VALUES (15, '10000.00', '24000.00', 0, '2017-01-12 12:25:34', '2017-01-12 12:25:34');\nINSERT INTO `wallet` VALUES (16, '10000.00', '24000.00', 0, '2017-01-12 12:25:34', '2017-01-12 12:25:34');\nINSERT INTO `wallet` VALUES (17, '10000.00', '24000.00', 0, '2017-01-12 12:25:34', '2017-01-12 12:25:34');\nINSERT INTO `wallet` VALUES (18, '10000.00', '24000.00', 0, '2017-01-12 12:25:34', '2017-01-12 12:25:34');\nINSERT INTO `wallet` VALUES (19, '10000.00', '24000.00', 0, '2017-01-12 12:25:34', '2017-01-12 12:25:34');\nINSERT INTO `wallet` VALUES (20, '10000.00', '24000.00', 0, '2017-01-12 12:25:34', '2017-01-12 12:25:34');\nINSERT INTO `wallet` VALUES (21, '10000.00', '24000.00', 0, '2017-01-12 12:25:34', '2017-01-12 12:25:34');\nINSERT INTO `wallet` VALUES (22, '10000.00', '24000.00', 0, '2017-01-12 12:25:34', '2017-01-12 12:25:34');\n\n-- 插入钱包明细\nTRUNCATE TABLE `wallet_item`;\n\n-- 插入积分总表\nTRUNCATE TABLE `score`;\nINSERT INTO `score` VALUES (1, '0.00', '2017-01-12 12:25:34', '2017-01-12 12:25:34');\n\n-- 插入积分明细\nTRUNCATE TABLE `score_item`;\n\n-- 插入慈善积分总表\nTRUNCATE TABLE `score_charity`;\n\n-- 插入慈善积分明细\nTRUNCATE TABLE `score_charity_item`;\nINSERT INTO `score_charity_item` VALUES (1, 1, 1, '10.00', 0, '测试获得积分', 1, 0, '2017-01-12 12:25:34', NULL, '2017-01-12 12:25:34', '2017-01-12 12:25:34');\nINSERT INTO `score_charity_item` VALUES (2, 1, 2, '5.00', 0, '测试消费积分', 1, 0, '2017-01-12 12:25:34', NULL, '2017-01-12 12:25:34', '2017-01-12 12:25:34');\n\n-- 插入数字积分总表\nTRUNCATE TABLE `score_digital`;\n\n-- 插入数字积分明细\nTRUNCATE TABLE `score_digital_item`;\n\n-- 插入消费积分总表\nTRUNCATE TABLE `score_expense`;\n\n-- 插入消费积分明细\nTRUNCATE TABLE `score_expense_item`;\n\n-- 插入奖金总表\nTRUNCATE TABLE `bonus`;\nINSERT INTO `bonus` VALUES (1, '0.00', '2017-01-12 12:25:34', '2017-01-12 12:25:34');\n\n-- 插入奖金明细\nTRUNCATE TABLE `bonus_item`;\n\n-- 插入数字货币总表\nTRUNCATE TABLE `bit_coin`;\n\n-- 插入数字货币明细\nTRUNCATE TABLE `bit_coin_item`;\n\n-- 插入激活总表\nTRUNCATE TABLE `active`;\nINSERT INTO `active` VALUES (1, 5, '2017-01-12 12:25:34', '2017-01-12 12:25:34');\n\n-- 插入激活明细\nTRUNCATE TABLE `active_item`;\nINSERT INTO `active_item` VALUES (1, 0, 2, 10, 1, '', 1, 0, '2017-01-12 12:25:34', NULL, '2017-01-12 12:25:34', '2017-01-12 12:25:34');\nINSERT INTO `active_item` VALUES (2, 1, 2, 2, 2, '', 1, 0, '2017-01-12 12:25:34', NULL, '2017-01-12 12:25:34', '2017-01-12 12:25:34');\nINSERT INTO `active_item` VALUES (3, 1, 1, 1, 3, '', 1, 0, '2017-01-12 12:25:34', NULL, '2017-01-12 12:25:34', '2017-01-12 12:25:34');\nINSERT INTO `active_item` VALUES (4, 1, 2, 1, 3, '', 1, 0, '2017-01-12 12:25:34', NULL, '2017-01-12 12:25:34', '2017-01-12 12:25:34');\nINSERT INTO `active_item` VALUES (5, 1, 2, 1, 4, '', 1, 0, '2017-01-12 12:25:34', NULL, '2017-01-12 12:25:34', '2017-01-12 12:25:34');\n\n-- 插入留言消息\nTRUNCATE TABLE `message`;\nINSERT INTO `message` VALUES (1, 1, 2, '测试消息', 0, null, '2017-06-24 13:23:27', '2017-06-24 13:23:27');\n\n-- 插入投诉消息\nTRUNCATE TABLE `complaint`;\nINSERT INTO `complaint` VALUES (1, 1, 2, 0, '测试消息', '', 0, null, 0, null, '2017-06-24 13:23:27', '2017-06-24 13:23:27');\n\n-- 插入用户配置信息\nTRUNCATE TABLE `user_config`;\nINSERT INTO `user_config` VALUES (1, '0.10,0.10,0.10', '2017-06-24 13:23:27', '2017-06-24 13:23:27');\n\n-- 插入排单币总表\nTRUNCATE TABLE `scheduling`;\nINSERT INTO `scheduling` VALUES (1, 100.00, '2017-06-29 18:27:01', '2017-06-29 18:27:01');\nINSERT INTO `scheduling` VALUES (2, 100.00, '2017-06-29 18:27:01', '2017-06-29 18:27:01');\nINSERT INTO `scheduling` VALUES (3, 100.00, '2017-06-29 18:27:01', '2017-06-29 18:27:01');\nINSERT INTO `scheduling` VALUES (4, 100.00, '2017-06-29 18:27:01', '2017-06-29 18:27:01');\nINSERT INTO `scheduling` VALUES (5, 100.00, '2017-06-29 18:27:01', '2017-06-29 18:27:01');\nINSERT INTO `scheduling` VALUES (6, 100.00, '2017-06-29 18:27:01', '2017-06-29 18:27:01');\nINSERT INTO `scheduling` VALUES (7, 100.00, '2017-06-29 18:27:01', '2017-06-29 18:27:01');\nINSERT INTO `scheduling` VALUES (8, 100.00, '2017-06-29 18:27:01', '2017-06-29 18:27:01');\nINSERT INTO `scheduling` VALUES (9, 100.00, '2017-06-29 18:27:01', '2017-06-29 18:27:01');\nINSERT INTO `scheduling` VALUES (10, 100.00, '2017-06-29 18:27:01', '2017-06-29 18:27:01');\nINSERT INTO `scheduling` VALUES (11, 100.00, '2017-06-29 18:27:01', '2017-06-29 18:27:01');\nINSERT INTO `scheduling` VALUES (12, 100.00, '2017-06-29 18:27:01', '2017-06-29 18:27:01');\nINSERT INTO `scheduling` VALUES (13, 100.00, '2017-06-29 18:27:01', '2017-06-29 18:27:01');\nINSERT INTO `scheduling` VALUES (14, 100.00, '2017-06-29 18:27:01', '2017-06-29 18:27:01');\nINSERT INTO `scheduling` VALUES (15, 100.00, '2017-06-29 18:27:01', '2017-06-29 18:27:01');\nINSERT INTO `scheduling` VALUES (16, 100.00, '2017-06-29 18:27:01', '2017-06-29 18:27:01');\nINSERT INTO `scheduling` VALUES (17, 100.00, '2017-06-29 18:27:01', '2017-06-29 18:27:01');\nINSERT INTO `scheduling` VALUES (18, 100.00, '2017-06-29 18:27:01', '2017-06-29 18:27:01');\nINSERT INTO `scheduling` VALUES (19, 100.00, '2017-06-29 18:27:01', '2017-06-29 18:27:01');\nINSERT INTO `scheduling` VALUES (20, 100.00, '2017-06-29 18:27:01', '2017-06-29 18:27:01');\nINSERT INTO `scheduling` VALUES (21, 100.00, '2017-06-29 18:27:01', '2017-06-29 18:27:01');\nINSERT INTO `scheduling` VALUES (22, 100.00, '2017-06-29 18:27:01', '2017-06-29 18:27:01');\n\n-- 插入排单币明细表\nTRUNCATE TABLE `scheduling_item`;\nINSERT INTO `scheduling_item` VALUES (1, 0, 2, 100, 1, '', 1, 0, '2017-06-29 17:24:36', null, '2017-06-29 17:24:36', '2017-06-29 17:24:36');\nINSERT INTO `scheduling_item` VALUES (2, 0, 2, 100, 2, '', 1, 0, '2017-06-29 17:24:36', null, '2017-06-29 17:24:36', '2017-06-29 17:24:36');\nINSERT INTO `scheduling_item` VALUES (3, 0, 2, 100, 3, '', 1, 0, '2017-06-29 17:24:36', null, '2017-06-29 17:24:36', '2017-06-29 17:24:36');\nINSERT INTO `scheduling_item` VALUES (4, 0, 2, 100, 4, '', 1, 0, '2017-06-29 17:24:36', null, '2017-06-29 17:24:36', '2017-06-29 17:24:36');\nINSERT INTO `scheduling_item` VALUES (5, 0, 2, 100, 5, '', 1, 0, '2017-06-29 17:24:36', null, '2017-06-29 17:24:36', '2017-06-29 17:24:36');\nINSERT INTO `scheduling_item` VALUES (6, 0, 2, 100, 6, '', 1, 0, '2017-06-29 17:24:36', null, '2017-06-29 17:24:36', '2017-06-29 17:24:36');\nINSERT INTO `scheduling_item` VALUES (7, 0, 2, 100, 7, '', 1, 0, '2017-06-29 17:24:36', null, '2017-06-29 17:24:36', '2017-06-29 17:24:36');\nINSERT INTO `scheduling_item` VALUES (8, 0, 2, 100, 8, '', 1, 0, '2017-06-29 17:24:36', null, '2017-06-29 17:24:36', '2017-06-29 17:24:36');\nINSERT INTO `scheduling_item` VALUES (9, 0, 2, 100, 9, '', 1, 0, '2017-06-29 17:24:36', null, '2017-06-29 17:24:36', '2017-06-29 17:24:36');\nINSERT INTO `scheduling_item` VALUES (10, 0, 2, 100, 10, '', 1, 0, '2017-06-29 17:24:36', null, '2017-06-29 17:24:36', '2017-06-29 17:24:36');\nINSERT INTO `scheduling_item` VALUES (11, 0, 2, 100, 11, '', 1, 0, '2017-06-29 17:24:36', null, '2017-06-29 17:24:36', '2017-06-29 17:24:36');\nINSERT INTO `scheduling_item` VALUES (12, 0, 2, 100, 12, '', 1, 0, '2017-06-29 17:24:36', null, '2017-06-29 17:24:36', '2017-06-29 17:24:36');\nINSERT INTO `scheduling_item` VALUES (13, 0, 2, 100, 13, '', 1, 0, '2017-06-29 17:24:36', null, '2017-06-29 17:24:36', '2017-06-29 17:24:36');\nINSERT INTO `scheduling_item` VALUES (14, 0, 2, 100, 14, '', 1, 0, '2017-06-29 17:24:36', null, '2017-06-29 17:24:36', '2017-06-29 17:24:36');\nINSERT INTO `scheduling_item` VALUES (15, 0, 2, 100, 15, '', 1, 0, '2017-06-29 17:24:36', null, '2017-06-29 17:24:36', '2017-06-29 17:24:36');\nINSERT INTO `scheduling_item` VALUES (16, 0, 2, 100, 16, '', 1, 0, '2017-06-29 17:24:36', null, '2017-06-29 17:24:36', '2017-06-29 17:24:36');\nINSERT INTO `scheduling_item` VALUES (17, 0, 2, 100, 17, '', 1, 0, '2017-06-29 17:24:36', null, '2017-06-29 17:24:36', '2017-06-29 17:24:36');\nINSERT INTO `scheduling_item` VALUES (18, 0, 2, 100, 18, '', 1, 0, '2017-06-29 17:24:36', null, '2017-06-29 17:24:36', '2017-06-29 17:24:36');\nINSERT INTO `scheduling_item` VALUES (19, 0, 2, 100, 19, '', 1, 0, '2017-06-29 17:24:36', null, '2017-06-29 17:24:36', '2017-06-29 17:24:36');\nINSERT INTO `scheduling_item` VALUES (20, 0, 2, 100, 20, '', 1, 0, '2017-06-29 17:24:36', null, '2017-06-29 17:24:36', '2017-06-29 17:24:36');\nINSERT INTO `scheduling_item` VALUES (21, 0, 2, 100, 21, '', 1, 0, '2017-06-29 17:24:36', null, '2017-06-29 17:24:36', '2017-06-29 17:24:36');\nINSERT INTO `scheduling_item` VALUES (22, 0, 2, 100, 22, '', 1, 0, '2017-06-29 17:24:36', null, '2017-06-29 17:24:36', '2017-06-29 17:24:36');\n"
  },
  {
    "path": "db/mysql.py",
    "content": "#!/usr/bin/env python\n# encoding: utf-8\n\n\"\"\"\n@author: zhanghe\n@software: PyCharm\n@file: mysql.py\n@time: 17-4-18 下午4:22\n\"\"\"\n\n\nimport os\nimport sys\nfrom config import BASE_DIR, DB_MYSQL as DB\n\nDB_SCHEMA_PATH = os.path.join(BASE_DIR, 'db/schema/mysql.sql')\nDUMP_FILE_PATH = os.path.join(BASE_DIR, 'db/backup/mysql.sql')\n\n\ndef create_db():\n    \"\"\"\n    建库 建表\n    \"\"\"\n    cmd = 'mysql -h%s -P%s -u%s -p%s < %s' % (DB['host'], DB['port'], DB['user'], DB['passwd'], DB_SCHEMA_PATH)\n    print cmd\n    output = os.popen(cmd)\n    result = output.read()\n    print result\n\n\ndef dump_db():\n    \"\"\"\n    备份数据\n    \"\"\"\n    cmd = 'mysqldump -h%s -P%s -u%s -p%s %s --skip-lock-tables > %s' % (DB['host'], DB['port'], DB['user'], DB['passwd'], DB['db'], DUMP_FILE_PATH)\n    print cmd\n    output = os.popen(cmd)\n    result = output.read()\n    print result\n\n\ndef run():\n    \"\"\"\n    入口\n    \"\"\"\n    # print sys.argv\n    try:\n        if len(sys.argv) > 1:\n            fun_name = eval(sys.argv[1])\n            fun_name()\n        else:\n            print '缺失参数\\n'\n            usage()\n    except NameError, e:\n        print e\n        print '未定义的方法[%s]' % sys.argv[1]\n\n\ndef usage():\n    print \"\"\"\n建库 建表（初始化数据库）\n$ python db/mysql.py create_db\n\n导出建表语句（备份数据库）\n$ python db/mysql.py dump_db\n\"\"\"\n\n\nif __name__ == '__main__':\n    run()\n"
  },
  {
    "path": "db/postgresql.py",
    "content": "#!/usr/bin/env python\n# encoding: utf-8\n\n\"\"\"\n@author: zhanghe\n@software: PyCharm\n@file: postgresql.py\n@time: 17-4-18 下午4:22\n\"\"\"\n\n\nimport os\nimport sys\nfrom config import BASE_DIR, DB_PG as DB\n\nDB_SCHEMA_PATH = os.path.join(BASE_DIR, 'db/schema/postgresql.sql')\nDUMP_FILE_PATH = os.path.join(BASE_DIR, 'db/backup/postgresql.sql')\n\n\ndef create_db():\n    \"\"\"\n    建库 建表\n    \"\"\"\n    cmd = 'psql -h%s -p%s -U%s -W -d%s -f %s' % (DB['host'], DB['port'], DB['user'], DB['database'], DB_SCHEMA_PATH)\n    print cmd\n    output = os.popen(cmd)\n    result = output.read()\n    print result\n\n\ndef dump_db():\n    \"\"\"\n    备份数据\n    如果只是导出建表结构 需要加上参数 -s\n    \"\"\"\n    cmd = 'pg_dump -h%s -p%s -U%s -W -d%s -f %s' % (DB['host'], DB['port'], DB['user'], DB['database'], DUMP_FILE_PATH)\n    print cmd\n    output = os.popen(cmd)\n    result = output.read()\n    print result\n\n\ndef run():\n    \"\"\"\n    入口\n    \"\"\"\n    # print sys.argv\n    try:\n        if len(sys.argv) > 1:\n            fun_name = eval(sys.argv[1])\n            fun_name()\n        else:\n            print '缺失参数\\n'\n            usage()\n    except NameError, e:\n        print e\n        print '未定义的方法[%s]' % sys.argv[1]\n\n\ndef usage():\n    print \"\"\"\n建库 建表（初始化数据库）\n$ python db/postgresql.py create_db\n\n导出建表语句（备份数据库）\n$ python db/postgresql.py dump_db\n\"\"\"\n\n\nif __name__ == '__main__':\n    run()\n"
  },
  {
    "path": "db/schema/mysql.sql",
    "content": "DROP DATABASE IF EXISTS `flask_project`;\nCREATE DATABASE `flask_project` /*!40100 DEFAULT CHARACTER SET utf8 */;\n\n\nuse flask_project;\n\n\nDROP TABLE IF EXISTS `user`;\nCREATE TABLE `user` (\n  `id` INT NOT NULL AUTO_INCREMENT,\n  `status_active` TINYINT NOT NULL DEFAULT '0' COMMENT '激活状态（0未激活，1已激活）',\n  `status_lock` TINYINT NOT NULL DEFAULT '0' COMMENT '锁定状态（0未锁定，1已锁定）',\n  `status_real_name` TINYINT NOT NULL DEFAULT '0' COMMENT '实名状态（0未实名，1已实名）',\n  `status_delete` TINYINT NOT NULL DEFAULT '0' COMMENT '删除状态（0未删除，1已删除）',\n  `active_time` TIMESTAMP NULL COMMENT '激活时间',\n  `lock_time` TIMESTAMP NULL COMMENT '锁定时间',\n  `delete_time` TIMESTAMP NULL COMMENT '删除时间',\n  `reg_ip` VARCHAR(20) COMMENT '注册IP',\n  `login_ip` VARCHAR(20) COMMENT '最后一次登录IP',\n  `login_time` TIMESTAMP NULL COMMENT '最后一次登录时间',\n  `create_time` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',\n  `update_time` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',\n  PRIMARY KEY (`id`)\n) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='用户全局注册表';\n\n\nDROP TABLE IF EXISTS `user_config`;\nCREATE TABLE `user_config` (\n  `user_id` INT NOT NULL COMMENT '用户Id',\n  `team_bonus` VARCHAR(100) DEFAULT '' COMMENT '团队奖金配置（暂时三级，半角逗号分隔）',\n  `create_time` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',\n  `update_time` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',\n  PRIMARY KEY (`user_id`)\n) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='用户配置表';\n\n\nDROP TABLE IF EXISTS `user_auth`;\nCREATE TABLE `user_auth` (\n  `id` INT NOT NULL AUTO_INCREMENT,\n  `user_id` INT NOT NULL DEFAULT '0' COMMENT '用户ID',\n  `type_auth` TINYINT NOT NULL DEFAULT '0' COMMENT '认证类型（0账号，1邮箱，2手机，3qq，4微信，5微博）',\n  `auth_key` VARCHAR(60) NOT NULL DEFAULT '' COMMENT '授权账号（如果是手机，国家区号+手机号码;第三方登陆，这里是openid）',\n  `auth_secret` VARCHAR(60) NOT NULL DEFAULT '' COMMENT '密码凭证（密码;token）',\n  `status_verified` TINYINT NOT NULL DEFAULT '0' COMMENT '认证状态（0未认证，1已认证）',\n  `create_time` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',\n  `update_time` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',\n  PRIMARY KEY (`id`),\n  KEY (`user_id`),\n  UNIQUE (`type_auth`, `auth_key`)\n) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='用户认证表';\n\n\nDROP TABLE IF EXISTS `user_profile`;\nCREATE TABLE `user_profile` (\n  `user_id` INT NOT NULL COMMENT '用户ID',\n  `user_pid` INT NOT NULL DEFAULT '0' COMMENT '推荐人用户ID',\n  `nickname` VARCHAR(20) NOT NULL DEFAULT '' COMMENT '用户名称',\n  `type_level` TINYINT NOT NULL DEFAULT '0' COMMENT '等级类型（0普通，1铜牌，2银牌，3金牌，4钻石）',\n  `avatar_url` VARCHAR(60) COMMENT '用户头像',\n  `email` VARCHAR(60) NOT NULL DEFAULT '' COMMENT '电子邮箱',\n  `area_id` INT(4) NOT NULL DEFAULT '0' COMMENT '国家区号id',\n  `area_code` VARCHAR(4) NOT NULL DEFAULT '' COMMENT '国家区号',\n  `phone` VARCHAR(20) NOT NULL DEFAULT '' COMMENT '手机号码',\n  `birthday` DATE NOT NULL DEFAULT '1900-01-01' COMMENT '生日',\n  `real_name` VARCHAR(20) NOT NULL DEFAULT '' COMMENT '真实姓名',\n  `id_card` VARCHAR(32) NOT NULL DEFAULT '' COMMENT '身份证号',\n  `create_time` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',\n  `update_time` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',\n  PRIMARY KEY (`user_id`),\n  KEY `ind_phone` (`area_id`, `phone`),\n  KEY `ind_id_card` (`area_id`, `id_card`)\n) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='用户基本信息表';\n\n\nDROP TABLE IF EXISTS `user_bank`;\nCREATE TABLE `user_bank` (\n  `user_id` INT NOT NULL COMMENT '用户ID',\n  `account_name` VARCHAR(60) NOT NULL DEFAULT '0' COMMENT '开户人姓名',\n  `bank_name` VARCHAR(60) NOT NULL DEFAULT '' COMMENT '开户银行',\n  `bank_address` VARCHAR(60) NOT NULL DEFAULT '' COMMENT '开户网点',\n  `bank_account` VARCHAR(32) NOT NULL DEFAULT '' COMMENT '银行账号',\n  `status_verified` TINYINT NOT NULL DEFAULT '0' COMMENT '认证状态（0未认证，1已认证）',\n  `status_delete` TINYINT NOT NULL DEFAULT '0' COMMENT '删除状态（0未删除，1已删除）',\n  `create_time` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',\n  `update_time` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',\n  PRIMARY KEY (`user_id`)\n) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='用户银行账号信息';\n\n\nDROP TABLE IF EXISTS `apply_put`;\nCREATE TABLE `apply_put` (\n  `id` INT NOT NULL AUTO_INCREMENT,\n  `user_id` INT NOT NULL COMMENT '用户Id',\n  `type_apply` TINYINT(1) NOT NULL DEFAULT '0' COMMENT '申请类型:0:自主添加，1:后台添加',\n  `type_pay` TINYINT(1) NOT NULL DEFAULT '0' COMMENT '支付方式:0:不限，1:银行转账，2:数字货币，3:支付宝，4:微信',\n  `money_apply` DECIMAL(8, 2) NOT NULL DEFAULT '0.00' COMMENT '申请金额',\n  `money_order` DECIMAL(8, 2) NOT NULL DEFAULT '0.00' COMMENT '订单金额',\n  `status_apply` TINYINT(1) NOT NULL DEFAULT '0' COMMENT '申请状态:0:待生效，1:已生效，2:取消',\n  `status_order` TINYINT(1) NOT NULL DEFAULT '0' COMMENT '订单状态:0:待匹配，1:部分匹配，2:完全匹配',\n  `status_delete` TINYINT(1) NOT NULL DEFAULT '0' COMMENT '删除状态:0:未删除，1:已删除',\n  `delete_time` TIMESTAMP NULL COMMENT '删除时间',\n  `create_time` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',\n  `update_time` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',\n  PRIMARY KEY (`id`),\n  KEY `ind_user_id` (`user_id`)\n) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='投资申请表';\n\n\nDROP TABLE IF EXISTS `apply_get`;\nCREATE TABLE `apply_get` (\n  `id` INT NOT NULL AUTO_INCREMENT,\n  `user_id` INT NOT NULL COMMENT '用户Id',\n  `type_apply` TINYINT(1) NOT NULL DEFAULT '0' COMMENT '申请类型:0:自主添加，1:后台生成',\n  `type_pay` TINYINT(1) NOT NULL DEFAULT '0' COMMENT '收款方式:0:不限，1:银行转账，2:数字货币，3:支付宝，4:微信',\n  `type_withdraw` TINYINT(1) NOT NULL DEFAULT '0' COMMENT '提现类型:0:钱包余额，1:数字货币',\n  `money_apply` DECIMAL(8, 2) NOT NULL DEFAULT '0.00' COMMENT '申请金额',\n  `money_order` DECIMAL(8, 2) NOT NULL DEFAULT '0.00' COMMENT '订单金额',\n  `status_apply` TINYINT(1) NOT NULL DEFAULT '0' COMMENT '申请状态:0:待生效，1:生效，2:取消',\n  `status_order` TINYINT(1) NOT NULL DEFAULT '0' COMMENT '匹配状态:0:待匹配，1:部分匹配，2:完全匹配',\n  `status_delete` TINYINT(1) NOT NULL DEFAULT '0' COMMENT '删除状态:0:未删除，1:已删除',\n  `delete_time` TIMESTAMP NULL COMMENT '删除时间',\n  `create_time` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',\n  `update_time` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',\n  PRIMARY KEY (`id`),\n  KEY `ind_user_id` (`user_id`)\n) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='提现申请表';\n\n\nDROP TABLE IF EXISTS `order`;\nCREATE TABLE `order` (\n  `id` INT NOT NULL AUTO_INCREMENT,\n  `apply_put_id` INT NOT NULL COMMENT '申请投资Id',\n  `apply_get_id` INT NOT NULL COMMENT '申请提现Id',\n  `apply_put_uid` INT NOT NULL COMMENT '申请投资用户Id',\n  `apply_get_uid` INT NOT NULL COMMENT '申请提现用户Id',\n  `type` TINYINT(1) NOT NULL DEFAULT '0' COMMENT '订单类型0:正常订单，1:流转订单',\n  `money` DECIMAL(8, 2) NOT NULL DEFAULT '0.00' COMMENT '订单金额',\n  `status_audit` TINYINT(1) NOT NULL DEFAULT '0' COMMENT '审核状态:0:待审核，1:审核通过，2:审核失败',\n  `status_flow` TINYINT(1) NOT NULL DEFAULT '0' COMMENT '流转状态:0:未流转，1:已流转',\n  `status_pay` TINYINT(1) NOT NULL DEFAULT '0' COMMENT '支付状态:0:待支付，1:支付成功，2:支付失败',\n  `status_rec` TINYINT(1) NOT NULL DEFAULT '0' COMMENT '收款状态:0:待收款，1:收款成功，2:收款失败',\n  `status_delete` TINYINT(1) NOT NULL DEFAULT '0' COMMENT '删除状态:0:未删除，1:已删除',\n  `audit_time` TIMESTAMP NULL COMMENT '审核时间（通过、失败）',\n  `pay_time` TIMESTAMP NULL COMMENT '支付时间（成功、失败）',\n  `rec_time` TIMESTAMP NULL COMMENT '收款时间（成功、失败）',\n  `delete_time` TIMESTAMP NULL COMMENT '删除时间',\n  `create_time` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',\n  `update_time` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',\n  PRIMARY KEY (`id`),\n  KEY `ind_apply_put_id` (`apply_put_id`),\n  KEY `ind_apply_get_id` (`apply_get_id`),\n  KEY `ind_apply_put_uid` (`apply_put_uid`),\n  KEY `ind_apply_get_uid` (`apply_get_uid`)\n) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='订单总表';\n\n\nDROP TABLE IF EXISTS `order_bill`;\nCREATE TABLE `order_bill` (\n  `id` INT NOT NULL AUTO_INCREMENT,\n  `order_id` INT NOT NULL COMMENT '订单Id',\n  `bill_img` VARCHAR(255) COMMENT '付款凭证',\n  `status_audit` TINYINT(1) NOT NULL DEFAULT '0' COMMENT '审核状态:0:待审核，1:审核通过，2:审核失败',\n  `status_delete` TINYINT(1) NOT NULL DEFAULT '0' COMMENT '删除状态:0:未删除，1:已删除',\n  `audit_time` TIMESTAMP NULL COMMENT '审核时间（通过、失败）',\n  `delete_time` TIMESTAMP NULL COMMENT '删除时间',\n  `create_time` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',\n  `update_time` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',\n  PRIMARY KEY (`id`),\n  KEY `ind_order_id` (`order_id`)\n) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='订单支付凭证';\n\n\nDROP TABLE IF EXISTS `order_flow`;\nCREATE TABLE `order_flow` (\n  `order_id` INT NOT NULL COMMENT '订单Id',\n  `flow_order_id` INT NOT NULL COMMENT '流转来源订单Id',\n  `apply_put_id` INT NOT NULL COMMENT '申请投资Id',\n  `apply_get_id` INT NOT NULL COMMENT '申请提现Id',\n  `apply_put_uid` INT NOT NULL COMMENT '申请投资用户Id',\n  `apply_get_uid` INT NOT NULL COMMENT '申请提现用户Id',\n  `create_time` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',\n  `update_time` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',\n  PRIMARY KEY (`order_id`),\n  KEY `ind_flow_order_id` (`flow_order_id`),\n  KEY `ind_apply_put_id` (`apply_put_id`),\n  KEY `ind_apply_get_id` (`apply_get_id`),\n  KEY `ind_apply_put_uid` (`apply_put_uid`),\n  KEY `ind_apply_get_uid` (`apply_get_uid`)\n) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='订单流转记录';\n\n\nDROP TABLE IF EXISTS `wallet`;\nCREATE TABLE `wallet` (\n  `user_id` INT NOT NULL COMMENT '用户Id',\n  `amount_initial` DECIMAL(10, 2) NOT NULL DEFAULT '0.00' COMMENT '初始总金额',\n  `amount_current` DECIMAL(10, 2) NOT NULL DEFAULT '0.00' COMMENT '当前总金额',\n  `amount_lock` DECIMAL(10, 2) NOT NULL DEFAULT '0.00' COMMENT '锁定的金额',\n  `create_time` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',\n  `update_time` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',\n  PRIMARY KEY (`user_id`)\n) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='钱包总表';\n\n\nDROP TABLE IF EXISTS `wallet_item`;\nCREATE TABLE `wallet_item` (\n  `id` INT NOT NULL AUTO_INCREMENT COMMENT '钱包明细id',\n  `user_id` INT NOT NULL COMMENT '用户Id',\n  `type` TINYINT(1) NOT NULL DEFAULT '0' COMMENT '钱包类型（1：收、2：支）',\n  `amount` DECIMAL(8, 2) NOT NULL DEFAULT '0.00' COMMENT '金额',\n  `sc_id` INT NOT NULL DEFAULT '0' COMMENT '关联id',\n  `note` VARCHAR(256) NOT NULL DEFAULT '' COMMENT '备注',\n  `status_audit` TINYINT(1) NOT NULL DEFAULT '0' COMMENT '审核状态:0:待审核，1:审核通过，2:审核失败',\n  `status_delete` TINYINT(1) NOT NULL DEFAULT '0' COMMENT '删除状态:0:未删除，1:已删除',\n  `audit_time` TIMESTAMP NULL COMMENT '审核时间（通过、失败）',\n  `delete_time` TIMESTAMP NULL COMMENT '删除时间',\n  `create_time` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',\n  `update_time` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',\n  PRIMARY KEY (`id`),\n  KEY `ind_user_id` (`user_id`),\n  KEY `ind_sc_id` (`sc_id`)\n) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='钱包明细表';\n\n\nDROP TABLE IF EXISTS `score`;\nCREATE TABLE `score` (\n  `user_id` INT NOT NULL COMMENT '用户Id',\n  `amount` DECIMAL(10, 2) NOT NULL DEFAULT '0' COMMENT '总积分',\n  `create_time` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',\n  `update_time` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',\n  PRIMARY KEY (`user_id`)\n) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='积分总表';\n\n\nDROP TABLE IF EXISTS `score_item`;\nCREATE TABLE `score_item` (\n  `id` INT NOT NULL AUTO_INCREMENT COMMENT '积分明细id',\n  `user_id` INT NOT NULL COMMENT '用户Id',\n  `type` TINYINT(1) NOT NULL DEFAULT '0' COMMENT '积分类型（1：加、2：减）',\n  `amount` DECIMAL(8, 2) NOT NULL DEFAULT '0' COMMENT '积分分值',\n  `sc_id` INT NOT NULL DEFAULT '0' COMMENT '关联id',\n  `note` VARCHAR(256) NOT NULL DEFAULT '' COMMENT '备注',\n  `status_audit` TINYINT(1) NOT NULL DEFAULT '0' COMMENT '审核状态:0:待审核，1:审核通过，2:审核失败',\n  `status_delete` TINYINT(1) NOT NULL DEFAULT '0' COMMENT '删除状态:0:未删除，1:已删除',\n  `audit_time` TIMESTAMP NULL COMMENT '审核时间（通过、失败）',\n  `delete_time` TIMESTAMP NULL COMMENT '删除时间',\n  `create_time` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',\n  `update_time` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',\n  PRIMARY KEY (`id`),\n  KEY `ind_user_id` (`user_id`),\n  KEY `ind_sc_id` (`sc_id`)\n) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='积分明细表';\n\n\nDROP TABLE IF EXISTS `score_charity`;\nCREATE TABLE `score_charity` (\n  `user_id` INT NOT NULL COMMENT '用户Id',\n  `amount` DECIMAL(10, 2) NOT NULL DEFAULT '0' COMMENT '总积分',\n  `create_time` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',\n  `update_time` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',\n  PRIMARY KEY (`user_id`)\n) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='慈善积分总表';\n\n\nDROP TABLE IF EXISTS `score_charity_item`;\nCREATE TABLE `score_charity_item` (\n  `id` INT NOT NULL AUTO_INCREMENT COMMENT '积分明细id',\n  `user_id` INT NOT NULL COMMENT '用户Id',\n  `type` TINYINT(1) NOT NULL DEFAULT '0' COMMENT '积分类型（1：加、2：减）',\n  `amount` DECIMAL(8, 2) NOT NULL DEFAULT '0' COMMENT '积分分值',\n  `sc_id` INT NOT NULL DEFAULT '0' COMMENT '关联id',\n  `note` VARCHAR(256) NOT NULL DEFAULT '' COMMENT '备注',\n  `status_audit` TINYINT(1) NOT NULL DEFAULT '0' COMMENT '审核状态:0:待审核，1:审核通过，2:审核失败',\n  `status_delete` TINYINT(1) NOT NULL DEFAULT '0' COMMENT '删除状态:0:未删除，1:已删除',\n  `audit_time` TIMESTAMP NULL COMMENT '审核时间（通过、失败）',\n  `delete_time` TIMESTAMP NULL COMMENT '删除时间',\n  `create_time` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',\n  `update_time` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',\n  PRIMARY KEY (`id`),\n  KEY `ind_user_id` (`user_id`),\n  KEY `ind_sc_id` (`sc_id`)\n) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='慈善积分明细表';\n\n\nDROP TABLE IF EXISTS `score_digital`;\nCREATE TABLE `score_digital` (\n  `user_id` INT NOT NULL COMMENT '用户Id',\n  `amount` DECIMAL(10, 2) NOT NULL DEFAULT '0' COMMENT '总积分',\n  `create_time` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',\n  `update_time` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',\n  PRIMARY KEY (`user_id`)\n) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='数字积分总表';\n\n\nDROP TABLE IF EXISTS `score_digital_item`;\nCREATE TABLE `score_digital_item` (\n  `id` INT NOT NULL AUTO_INCREMENT COMMENT '积分明细id',\n  `user_id` INT NOT NULL COMMENT '用户Id',\n  `type` TINYINT(1) NOT NULL DEFAULT '0' COMMENT '积分类型（1：加、2：减）',\n  `amount` DECIMAL(8, 2) NOT NULL DEFAULT '0' COMMENT '积分分值',\n  `sc_id` INT NOT NULL DEFAULT '0' COMMENT '关联id',\n  `note` VARCHAR(256) NOT NULL DEFAULT '' COMMENT '备注',\n  `status_audit` TINYINT(1) NOT NULL DEFAULT '0' COMMENT '审核状态:0:待审核，1:审核通过，2:审核失败',\n  `status_delete` TINYINT(1) NOT NULL DEFAULT '0' COMMENT '删除状态:0:未删除，1:已删除',\n  `audit_time` TIMESTAMP NULL COMMENT '审核时间（通过、失败）',\n  `delete_time` TIMESTAMP NULL COMMENT '删除时间',\n  `create_time` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',\n  `update_time` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',\n  PRIMARY KEY (`id`),\n  KEY `ind_user_id` (`user_id`),\n  KEY `ind_sc_id` (`sc_id`)\n) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='数字积分明细表';\n\n\nDROP TABLE IF EXISTS `score_expense`;\nCREATE TABLE `score_expense` (\n  `user_id` INT NOT NULL COMMENT '用户Id',\n  `amount` DECIMAL(10, 2) NOT NULL DEFAULT '0' COMMENT '总积分',\n  `create_time` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',\n  `update_time` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',\n  PRIMARY KEY (`user_id`)\n) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='消费积分总表';\n\n\nDROP TABLE IF EXISTS `score_expense_item`;\nCREATE TABLE `score_expense_item` (\n  `id` INT NOT NULL AUTO_INCREMENT COMMENT '积分明细id',\n  `user_id` INT NOT NULL COMMENT '用户Id',\n  `type` TINYINT(1) NOT NULL DEFAULT '0' COMMENT '积分类型（1：加、2：减）',\n  `amount` DECIMAL(8, 2) NOT NULL DEFAULT '0' COMMENT '积分分值',\n  `sc_id` INT NOT NULL DEFAULT '0' COMMENT '关联id',\n  `note` VARCHAR(256) NOT NULL DEFAULT '' COMMENT '备注',\n  `status_audit` TINYINT(1) NOT NULL DEFAULT '0' COMMENT '审核状态:0:待审核，1:审核通过，2:审核失败',\n  `status_delete` TINYINT(1) NOT NULL DEFAULT '0' COMMENT '删除状态:0:未删除，1:已删除',\n  `audit_time` TIMESTAMP NULL COMMENT '审核时间（通过、失败）',\n  `delete_time` TIMESTAMP NULL COMMENT '删除时间',\n  `create_time` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',\n  `update_time` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',\n  PRIMARY KEY (`id`),\n  KEY `ind_user_id` (`user_id`),\n  KEY `ind_sc_id` (`sc_id`)\n) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='消费积分明细表';\n\n\nDROP TABLE IF EXISTS `bonus`;\nCREATE TABLE `bonus` (\n  `user_id` INT NOT NULL COMMENT '用户Id',\n  `amount` DECIMAL(10, 2) NOT NULL DEFAULT '0' COMMENT '总奖金',\n  `create_time` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',\n  `update_time` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',\n  PRIMARY KEY (`user_id`)\n) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='奖金总表';\n\n\nDROP TABLE IF EXISTS `bonus_item`;\nCREATE TABLE `bonus_item` (\n  `id` INT NOT NULL AUTO_INCREMENT COMMENT '奖金明细id',\n  `user_id` INT NOT NULL COMMENT '用户Id',\n  `type` TINYINT(1) NOT NULL DEFAULT '0' COMMENT '奖金类型（1：加、2：减）',\n  `amount` DECIMAL(8, 2) NOT NULL DEFAULT '0' COMMENT '奖金金额',\n  `sc_id` INT NOT NULL DEFAULT '0' COMMENT '关联id',\n  `note` VARCHAR(256) NOT NULL DEFAULT '' COMMENT '备注',\n  `status_audit` TINYINT(1) NOT NULL DEFAULT '0' COMMENT '审核状态:0:待审核，1:审核通过，2:审核失败',\n  `status_delete` TINYINT(1) NOT NULL DEFAULT '0' COMMENT '删除状态:0:未删除，1:已删除',\n  `audit_time` TIMESTAMP NULL COMMENT '审核时间（通过、失败）',\n  `delete_time` TIMESTAMP NULL COMMENT '删除时间',\n  `create_time` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',\n  `update_time` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',\n  PRIMARY KEY (`id`),\n  KEY `ind_user_id` (`user_id`),\n  KEY `ind_sc_id` (`sc_id`)\n) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='奖金明细表';\n\n\nDROP TABLE IF EXISTS `bit_coin`;\nCREATE TABLE `bit_coin` (\n  `user_id` INT NOT NULL COMMENT '用户Id',\n  `amount` DECIMAL(10, 2) NOT NULL DEFAULT '0' COMMENT '数字货币总额',\n  `create_time` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',\n  `update_time` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',\n  PRIMARY KEY (`user_id`)\n) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='数字货币总表';\n\n\nDROP TABLE IF EXISTS `bit_coin_item`;\nCREATE TABLE `bit_coin_item` (\n  `id` INT NOT NULL AUTO_INCREMENT COMMENT '数字货币明细id',\n  `user_id` INT NOT NULL COMMENT '用户Id',\n  `type` TINYINT(1) NOT NULL DEFAULT '0' COMMENT '数字货币类型（1：加、2：减）',\n  `amount` DECIMAL(8, 2) NOT NULL DEFAULT '0' COMMENT '数字货币金额',\n  `sc_id` INT NOT NULL DEFAULT '0' COMMENT '关联id',\n  `note` VARCHAR(256) NOT NULL DEFAULT '' COMMENT '备注',\n  `status_audit` TINYINT(1) NOT NULL DEFAULT '0' COMMENT '审核状态:0:待审核，1:审核通过，2:审核失败',\n  `status_delete` TINYINT(1) NOT NULL DEFAULT '0' COMMENT '删除状态:0:未删除，1:已删除',\n  `audit_time` TIMESTAMP NULL COMMENT '审核时间（通过、失败）',\n  `delete_time` TIMESTAMP NULL COMMENT '删除时间',\n  `create_time` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',\n  `update_time` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',\n  PRIMARY KEY (`id`),\n  KEY `ind_user_id` (`user_id`),\n  KEY `ind_sc_id` (`sc_id`)\n) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='数字货币明细表';\n\n\nDROP TABLE IF EXISTS `active`;\nCREATE TABLE `active` (\n  `user_id` INT NOT NULL COMMENT '用户Id',\n  `amount` DECIMAL(10, 0) NOT NULL DEFAULT '0' COMMENT '剩余激活码数',\n  `create_time` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',\n  `update_time` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',\n  PRIMARY KEY (`user_id`)\n) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='激活总表';\n\n\nDROP TABLE IF EXISTS `active_item`;\nCREATE TABLE `active_item` (\n  `id` INT NOT NULL AUTO_INCREMENT COMMENT '激活明细id',\n  `user_id` INT NOT NULL COMMENT '用户Id',\n  `type` TINYINT(1) NOT NULL DEFAULT '0' COMMENT '激活类型（1：激活、2：赠送）',\n  `amount` DECIMAL(8, 0) NOT NULL DEFAULT '0' COMMENT '消耗激活码数',\n  `sc_id` INT NOT NULL DEFAULT '0' COMMENT '关联id(被激活/赠送的uid)',\n  `note` VARCHAR(256) NOT NULL DEFAULT '' COMMENT '备注',\n  `status_audit` TINYINT(1) NOT NULL DEFAULT '0' COMMENT '审核状态:0:待审核，1:审核通过，2:审核失败',\n  `status_delete` TINYINT(1) NOT NULL DEFAULT '0' COMMENT '删除状态:0:未删除，1:已删除',\n  `audit_time` TIMESTAMP NULL COMMENT '审核时间（通过、失败）',\n  `delete_time` TIMESTAMP NULL COMMENT '删除时间',\n  `create_time` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',\n  `update_time` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',\n  PRIMARY KEY (`id`),\n  KEY `ind_user_id` (`user_id`),\n  KEY `ind_sc_id` (`sc_id`)\n) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='激活明细表';\n\n\nDROP TABLE IF EXISTS `admin`;\nCREATE TABLE `admin` (\n  `id` INT NOT NULL AUTO_INCREMENT,\n  `username` VARCHAR(20) NOT NULL DEFAULT '' COMMENT '用户名称',\n  `password` VARCHAR(60) NOT NULL DEFAULT '' COMMENT '用户密码',\n  `area_id` INT(4) NOT NULL DEFAULT '0' COMMENT '国家区号id',\n  `area_code` VARCHAR(4) NOT NULL DEFAULT '' COMMENT '国家区号',\n  `phone` VARCHAR(20) NOT NULL DEFAULT '' COMMENT '手机号码',\n  `role_id` TINYINT(1) NOT NULL DEFAULT '1' COMMENT '角色（1:系统,2:客服,3:运营,4:市场,5:销售,6:普通,7:高级）',\n  `status_delete` TINYINT NOT NULL DEFAULT '0' COMMENT '删除状态（0未删除，1已删除）',\n  `delete_time` TIMESTAMP NULL COMMENT '删除时间',\n  `login_time` TIMESTAMP NULL COMMENT '最后一次登录时间',\n  `login_ip` VARCHAR(20) COMMENT '最后一次登录IP',\n  `create_time` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',\n  `update_time` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',\n  PRIMARY KEY (`id`),\n  UNIQUE (`username`)\n) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='后台用户信息表';\n\n\nDROP TABLE IF EXISTS `admin_role`;\nCREATE TABLE `admin_role` (\n  `id` INT NOT NULL AUTO_INCREMENT,\n  `name` VARCHAR(20) NOT NULL DEFAULT '' COMMENT '角色名称',\n  `note` VARCHAR(256) NOT NULL DEFAULT '' COMMENT '角色备注',\n  `module` VARCHAR(256) NOT NULL DEFAULT '' COMMENT '模块权限(会员，订单，留言，系统, 权限，统计)',\n  `create_time` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',\n  `update_time` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',\n  PRIMARY KEY (`id`),\n  UNIQUE (`name`)\n) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='角色权限表';\n\n\nDROP TABLE IF EXISTS `area_code`;\nCREATE TABLE `area_code` (\n  `id` INT NOT NULL AUTO_INCREMENT,\n  `short_code` VARCHAR(2) NOT NULL DEFAULT '' COMMENT '国家简称',\n  `area_code` VARCHAR(4) NOT NULL DEFAULT '' COMMENT '区号',\n  `phone_pre` VARCHAR(7) NOT NULL DEFAULT '' COMMENT '号码前缀',\n  `name_c` VARCHAR(20) NOT NULL DEFAULT '' COMMENT '国家中文名称',\n  `name_e` VARCHAR(20) NOT NULL DEFAULT '' COMMENT '国家英文名称',\n  `country_area` VARCHAR(20) NOT NULL DEFAULT '' COMMENT '国家板块',\n  `create_time` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',\n  `update_time` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',\n  PRIMARY KEY (`id`)\n) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='区号';\n\n\nDROP TABLE IF EXISTS `message`;\nCREATE TABLE `message` (\n  `id` INT NOT NULL AUTO_INCREMENT,\n  `send_user_id` INT NOT NULL COMMENT '消息发送用户Id',\n  `receive_user_id` INT NOT NULL COMMENT '消息接收用户Id',\n  `content` VARCHAR(512) NOT NULL DEFAULT '' COMMENT '留言内容',\n  `status_delete` TINYINT NOT NULL DEFAULT '0' COMMENT '删除状态（0未删除，1已删除）',\n  `delete_time` TIMESTAMP NULL COMMENT '删除时间',\n  `create_time` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '留言时间',\n  `update_time` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',\n  PRIMARY KEY (`id`),\n  KEY `ind_send_user_id` (`send_user_id`),\n  KEY `ind_receive_user_id` (`receive_user_id`)\n) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='用户留言';\n\n\nDROP TABLE IF EXISTS `complaint`;\nCREATE TABLE `complaint` (\n  `id` INT NOT NULL AUTO_INCREMENT,\n  `send_user_id` INT NOT NULL COMMENT '前台投诉人用户Id',\n  `receive_user_id` INT NOT NULL COMMENT '前台被投诉用户Id',\n  `reply_admin_id` INT NOT NULL DEFAULT '0' COMMENT '后台回复用户Id',\n  `content` VARCHAR(512) NOT NULL DEFAULT '' COMMENT '留言内容',\n  `content_reply` VARCHAR(512) NOT NULL DEFAULT '' COMMENT '回复内容',\n  `status_reply` TINYINT NOT NULL DEFAULT '0' COMMENT '回复状态（0未回复，1已回复）',\n  `reply_time` TIMESTAMP NULL COMMENT '回复时间',\n  `status_delete` TINYINT NOT NULL DEFAULT '0' COMMENT '删除状态（0未删除，1已删除）',\n  `delete_time` TIMESTAMP NULL COMMENT '删除时间',\n  `create_time` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '留言时间',\n  `update_time` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',\n  PRIMARY KEY (`id`),\n  KEY `ind_send_user_id` (`send_user_id`),\n  KEY `ind_receive_user_id` (`receive_user_id`),\n  KEY `ind_reply_admin_id` (`reply_admin_id`)\n) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='投诉';\n\n\nDROP TABLE IF EXISTS `credit`;\nCREATE TABLE `credit` (\n  `user_id` INT NOT NULL COMMENT '用户Id',\n  `behavior` DECIMAL(3, 0) NOT NULL DEFAULT '0' COMMENT '行为偏好',\n  `characteristics` DECIMAL(3, 0) NOT NULL DEFAULT '0' COMMENT '身份特质',\n  `connections` DECIMAL(3, 0) NOT NULL DEFAULT '0' COMMENT '人脉关系',\n  `history` DECIMAL(3, 0) NOT NULL DEFAULT '0' COMMENT '信用历史',\n  `performance` DECIMAL(3, 0) NOT NULL DEFAULT '0' COMMENT '履约能力',\n  `credit` DECIMAL(3, 0) NOT NULL DEFAULT '0' COMMENT '整体信用',\n  `create_time` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',\n  `update_time` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',\n  PRIMARY KEY (`user_id`)\n) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='用户声望（信用）';\n\n\nDROP TABLE IF EXISTS `scheduling`;\nCREATE TABLE `scheduling` (\n  `user_id` INT NOT NULL COMMENT '用户Id',\n  `amount` DECIMAL(10, 2) NOT NULL DEFAULT '0' COMMENT '排单总分',\n  `create_time` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',\n  `update_time` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',\n  PRIMARY KEY (`user_id`)\n) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='排单总表';\n\n\nDROP TABLE IF EXISTS `scheduling_item`;\nCREATE TABLE `scheduling_item` (\n  `id` INT NOT NULL AUTO_INCREMENT COMMENT '积分明细id',\n  `user_id` INT NOT NULL COMMENT '用户Id',\n  `type` TINYINT(1) NOT NULL DEFAULT '0' COMMENT '排单类型（1：排单、2：赠送）',\n  `amount` DECIMAL(8, 2) NOT NULL DEFAULT '0' COMMENT '排单分值',\n  `sc_id` INT NOT NULL DEFAULT '0' COMMENT '关联id',\n  `note` VARCHAR(256) NOT NULL DEFAULT '' COMMENT '备注',\n  `status_audit` TINYINT(1) NOT NULL DEFAULT '0' COMMENT '审核状态:0:待审核，1:审核通过，2:审核失败',\n  `status_delete` TINYINT(1) NOT NULL DEFAULT '0' COMMENT '删除状态:0:未删除，1:已删除',\n  `audit_time` TIMESTAMP NULL COMMENT '审核时间（通过、失败）',\n  `delete_time` TIMESTAMP NULL COMMENT '删除时间',\n  `create_time` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',\n  `update_time` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',\n  PRIMARY KEY (`id`),\n  KEY `ind_user_id` (`user_id`),\n  KEY `ind_sc_id` (`sc_id`)\n) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='排单明细表';\n"
  },
  {
    "path": "db/schema/postgresql.sql",
    "content": ""
  },
  {
    "path": "db/schema/sqlite.sql",
    "content": ""
  },
  {
    "path": "db/sqlite.py",
    "content": "#!/usr/bin/env python\n# encoding: utf-8\n\n\"\"\"\n@author: zhanghe\n@software: PyCharm\n@file: sqlite.py\n@time: 17-4-18 下午4:22\n\"\"\"\n\n\nimport os\nimport sys\nfrom config import current_config\n\nBASE_DIR = current_config['BASE_DIR']\nDB = current_config['DB_SQLITE']\n\n\nDB_SCHEMA_PATH = os.path.join(BASE_DIR, 'db/schema/sqlite.sql')\nDUMP_FILE_PATH = os.path.join(BASE_DIR, 'db/backup/sqlite.sql')\n\n\ndef create_db():\n    \"\"\"\n    建库 建表\n    $ python gen.py create_db\n    \"\"\"\n    # 初始化数据库\n    cmd = 'sqlite3 %s < %s' % (DB, DB_SCHEMA_PATH)\n    print cmd\n    output = os.popen(cmd)\n    result = output.read()\n    print result\n    # 添加测试数据\n    cmd = 'sqlite3 %s < %s' % (DB, os.path.join(BASE_DIR, 'etc/data_test.sql'))\n    print cmd\n    output = os.popen(cmd)\n    result = output.read()\n    print result\n\n\ndef dump_db():\n    \"\"\"\n    备份数据\n    $ python gen.py dump_db\n    \"\"\"\n    # 添加测试数据\n    cmd = 'sqlite3 %s \".dump\" > %s' % (os.path.join(BASE_DIR, 'flask.db'), os.path.join(BASE_DIR, 'schema.dump.sql'))\n    print cmd\n    output = os.popen(cmd)\n    result = output.read()\n    print result\n\n\ndef run():\n    \"\"\"\n    入口\n    \"\"\"\n    # print sys.argv\n    try:\n        if len(sys.argv) > 1:\n            fun_name = eval(sys.argv[1])\n            fun_name()\n        else:\n            print '缺失参数\\n'\n            usage()\n    except NameError, e:\n        print e\n        print '未定义的方法[%s]' % sys.argv[1]\n\n\ndef usage():\n    print \"\"\"\n建库 建表（初始化数据库）\n$ python db/sqlite.py create_db\n\n导出建表语句（备份数据库）\n$ python db/sqlite.py dump_db\n\"\"\"\n\n\nif __name__ == '__main__':\n    run()\n"
  },
  {
    "path": "doc/BluePrint.md",
    "content": "官方链接: [http://exploreflask.com/en/latest/blueprints.html](http://exploreflask.com/en/latest/blueprints.html)\n\n单模式（适用小规模风格统一的应用）\n```\nyourapp/\n    __init__.py\n    static/\n    templates/\n        home/\n        api/\n        admin/\n    views/\n        __init__.py\n        home.py\n        api.py\n        admin.py\n    models.py\n```\n\n多模式（适用大规模风格相对独立的应用）\n```\nyourapp/\n    __init__.py\n    home/\n        __init__.py\n        views.py\n        forms.py\n        home.py\n        static/\n        templates/\n    api/\n        __init__.py\n        views.py\n        forms.py\n        api.py\n        static/\n        templates/\n    admin/\n        __init__.py\n        views.py\n        forms.py\n        admin.py\n        static/\n        templates/\n    models.py\n```\n\n建议结构：\n前后样式不同，分离独立模块。\n```\napp/\n    __init__.py\n    frontend/\n        __init__.py\n        static/\n            img/\n            css/\n            js/\n        templates/\n            layout.html\n            api/\n        views/\n            __init__.py\n            api.py\n        forms.py\n    admin/\n        __init__.py\n        static/\n            img/\n            css/\n            js/\n        templates/\n            layout.html\n            api/\n        views/\n            __init__.py\n            api.py\n        forms.py\n    models.py\n    config/\n    logs/\nfabfile.py\nrun.py\n```\n"
  },
  {
    "path": "doc/Celery.md",
    "content": "## Celery - Distributed Task Queue\n\nhttps://github.com/celery/celery\n\nhttp://docs.celeryproject.org/en/latest/index.html\n\nhttp://www.pythondoc.com/flask/patterns/celery.html\n\nhttp://www.pythondoc.com/flask-celery/\n\n\nChoosing a Broker\n```\n$ sudo apt-get install rabbitmq-server\n```\n\nInstalling Celery\n```\n$ pip install celery\n$ pip install librabbitmq\n```\n\n\nApplication\n\ntasks.py:\n```\nfrom celery import Celery\n\napp = Celery('tasks', broker='amqp://guest@localhost//')\n\n@app.task\ndef add(x, y):\n    return x + y\n```\n\nUsing Celery in your Application\n\nhttp://docs.celeryproject.org/en/master/getting-started/next-steps.html\n\n\n## 角色说明\n\n- Broker\n负责创建任务队列，根据一些路由规则将任务分派到任务队列，然后将任务从任务队列传递给工作线程。\n\n- Consumer (Celery Workers)\n消费者是执行任务的一个或多个Celery工作程序。你可以根据你的用例启动很多工人。\n\n- Result Backend\n结果后端用于存储任务的结果。但是，它不是必需的元素，因此如果您不将其包括在设置中，则无法访问任务的结果。\n\n\n## 简单测试\n\n基于 redis\n\n启动 Web server:\n```\n$ python run.py\n```\n\n启动 Celery worker:\n```\n$ celery worker -A app.celery_worker.celery_app -l INFO\n```\n\n启动结果:\n```\ncelery@zhanghedeMBP v4.0.0 (latentcall)\n\nDarwin-16.1.0-x86_64-i386-64bit 2016-11-16 23:48:23\n\n[config]\n.> app:         app:0x10f7a8510\n.> transport:   redis://localhost:6379//\n.> results:     redis://localhost:6379/\n.> concurrency: 8 (prefork)\n.> task events: OFF (enable -E to monitor tasks in this worker)\n\n[queues]\n.> celery           exchange=celery(direct) key=celery\n\n\n[tasks]\n  . app.tasks.add\n  . app.tasks.mul\n  . app.tasks.xsum\n\n[2016-11-16 23:48:23,710: INFO/MainProcess] Connected to redis://localhost:6379//\n[2016-11-16 23:48:23,721: INFO/MainProcess] mingle: searching for neighbors\n[2016-11-16 23:48:24,741: INFO/MainProcess] mingle: all alone\n[2016-11-16 23:48:24,752: INFO/MainProcess] celery@zhanghedeMBP ready.\n```\n\n查看 redis 队列结构\n```\n127.0.0.1:6379> type \"celery-task-meta-cf11bfdb-4c02-4b0a-81f9-ee8ae929926c\"\nstring\n127.0.0.1:6379> ttl \"celery-task-meta-cf11bfdb-4c02-4b0a-81f9-ee8ae929926c\"\n85730\n127.0.0.1:6379> get \"celery-task-meta-cf11bfdb-4c02-4b0a-81f9-ee8ae929926c\"\n\"{\\\"status\\\": \\\"SUCCESS\\\", \\\"traceback\\\": null, \\\"result\\\": 300, \\\"task_id\\\": \\\"cf11bfdb-4c02-4b0a-81f9-ee8ae929926c\\\", \\\"children\\\": []}\"\n127.0.0.1:6379>\n```\n\n字符串序列化存储，默认过期时间24小时（86400秒）\n\n\n## 任务队列系统的三种角色\n\n- 任务生产者\n- 任务处理中间方（代理）\n- 任务消费者\n\n\nUsing RabbitMQ\n\nhttp://docs.celeryproject.org/en/latest/getting-started/brokers/rabbitmq.html\n\n\n## 深入探究\n\n\n启动 celery 进程\n```\n127.0.0.1:6379> keys *\n1) \"_kombu.binding.celery.pidbox\"\n2) \"_kombu.binding.celery\"\n3) \"_kombu.binding.celeryev\"\n127.0.0.1:6379> type \"_kombu.binding.celery.pidbox\"\nset\n127.0.0.1:6379> SMEMBERS \"_kombu.binding.celery.pidbox\"\n1) \"\\x06\\x16\\x06\\x16celery@zhanghedeMacBook-Pro.local.celery.pidbox\"\n127.0.0.1:6379> type \"_kombu.binding.celery\"\nset\n127.0.0.1:6379> SMEMBERS \"_kombu.binding.celery\"\n1) \"celery\\x06\\x16\\x06\\x16celery\"\n127.0.0.1:6379> type \"_kombu.binding.celeryev\"\nset\n127.0.0.1:6379> SMEMBERS \"_kombu.binding.celeryev\"\n1) \"worker.#\\x06\\x16\\x06\\x16celeryev.3389080e-158d-4c9b-a8f6-322e4776c802\"\n```\n\nweb 页面发起任务请求（broker 为 redis, backend 为 rabbit） \nhttp://localhost:8000/test_send_task/?x=100&y=200\n```\n127.0.0.1:6379> KEYS *\n1) \"7755e27bbb534c058e46037417ab4e30\\x06\\x169\"\n2) \"_kombu.binding.celeryresults\"\n3) \"_kombu.binding.celery\"\n4) \"_kombu.binding.celery.pidbox\"\n5) \"2a5e68d9b44342778b5709dd69b2f465\\x06\\x169\"\n6) \"_kombu.binding.celeryev\"\n7) \"0377bc1c0e5d4a3ca5d27a06a162ba53\\x06\\x169\"\n127.0.0.1:6379> type \"_kombu.binding.celeryresults\"\nset\n127.0.0.1:6379> SMEMBERS \"_kombu.binding.celeryresults\"\n1) \"0377bc1c0e5d4a3ca5d27a06a162ba53\\x06\\x16\\x06\\x160377bc1c0e5d4a3ca5d27a06a162ba53\"\n2) \"2a5e68d9b44342778b5709dd69b2f465\\x06\\x16\\x06\\x162a5e68d9b44342778b5709dd69b2f465\"\n3) \"7755e27bbb534c058e46037417ab4e30\\x06\\x16\\x06\\x167755e27bbb534c058e46037417ab4e30\"\n127.0.0.1:6379> type \"7755e27bbb534c058e46037417ab4e30\\x06\\x169\"\nlist\n127.0.0.1:6379> ttl \"7755e27bbb534c058e46037417ab4e30\\x06\\x169\"\n(integer) -1\n127.0.0.1:6379> LRANGE \"7755e27bbb534c058e46037417ab4e30\\x06\\x169\" 0 -1\n1) \"{\\\"body\\\": \\\"eyJzdGF0dXMiOiAiU1VDQ0VTUyIsICJ0cmFjZWJhY2siOiBudWxsLCAicmVzdWx0IjogMzAwLCAidGFza19pZCI6ICI3NzU1ZTI3Yi1iYjUzLTRjMDUtOGU0Ni0wMzc0MTdhYjRlMzAiLCAiY2hpbGRyZW4iOiBbXX0=\\\", \\\"headers\\\": {}, \\\"content-type\\\": \\\"application/json\\\", \\\"properties\\\": {\\\"priority\\\": 0, \\\"body_encoding\\\": \\\"base64\\\", \\\"correlation_id\\\": \\\"7755e27b-bb53-4c05-8e46-037417ab4e30\\\", \\\"delivery_info\\\": {\\\"routing_key\\\": \\\"7755e27bbb534c058e46037417ab4e30\\\", \\\"exchange\\\": \\\"celeryresults\\\"}, \\\"delivery_mode\\\": 2, \\\"delivery_tag\\\": \\\"a157be8b-55ca-44cd-8ebe-993ab032b067\\\"}, \\\"content-encoding\\\": \\\"utf-8\\\"}\"\n```\n\n查看记录结构\n```\nIn [1]: result = \"{\\\"body\\\": \\\"eyJzdGF0dXMiOiAiU1VDQ0VTUyIsICJ0cmFjZWJhY2siOiBudWxsLCAicmVzdWx0IjogMzAwLCAidGFza19pZCI6ICI3NzU1ZTI3Yi1iYjUzLTRjMDUtOGU0Ni0wMzc0MTdhYjRlMzAiLCAiY2hpb\n   ...: GRyZW4iOiBbXX0=\\\", \\\"headers\\\": {}, \\\"content-type\\\": \\\"application/json\\\", \\\"properties\\\": {\\\"priority\\\": 0, \\\"body_encoding\\\": \\\"base64\\\", \\\"correlation_id\\\": \\\"7755e27\n   ...: b-bb53-4c05-8e46-037417ab4e30\\\", \\\"delivery_info\\\": {\\\"routing_key\\\": \\\"7755e27bbb534c058e46037417ab4e30\\\", \\\"exchange\\\": \\\"celeryresults\\\"}, \\\"delivery_mode\\\": 2, \\\"deli\n   ...: very_tag\\\": \\\"a157be8b-55ca-44cd-8ebe-993ab032b067\\\"}, \\\"content-encoding\\\": \\\"utf-8\\\"}\"\n\nIn [2]: import json\n\nIn [3]: print json.dumps(json.loads(result), indent=4, ensure_ascii=False)\n{\n    \"body\": \"eyJzdGF0dXMiOiAiU1VDQ0VTUyIsICJ0cmFjZWJhY2siOiBudWxsLCAicmVzdWx0IjogMzAwLCAidGFza19pZCI6ICI3NzU1ZTI3Yi1iYjUzLTRjMDUtOGU0Ni0wMzc0MTdhYjRlMzAiLCAiY2hpbGRyZW4iOiBbXX0=\",\n    \"headers\": {},\n    \"content-type\": \"application/json\",\n    \"properties\": {\n        \"body_encoding\": \"base64\",\n        \"delivery_info\": {\n            \"routing_key\": \"7755e27bbb534c058e46037417ab4e30\",\n            \"exchange\": \"celeryresults\"\n        },\n        \"delivery_mode\": 2,\n        \"priority\": 0,\n        \"correlation_id\": \"7755e27b-bb53-4c05-8e46-037417ab4e30\",\n        \"delivery_tag\": \"a157be8b-55ca-44cd-8ebe-993ab032b067\"\n    },\n    \"content-encoding\": \"utf-8\"\n}\n```\n\n查看 body 内容\n```\nIn [4]: import base64\n\nIn [5]: base64.b64decode('eyJzdGF0dXMiOiAiU1VDQ0VTUyIsICJ0cmFjZWJhY2siOiBudWxsLCAicmVzdWx0IjogMzAwLCAidGFza19pZCI6ICI3NzU1ZTI3Yi1iYjUzLTRjMDUtOGU0Ni0wMzc0MTdhYjRlMzAiLCAiY2hpbGRy\n   ...: ZW4iOiBbXX0=')\nOut[5]: '{\"status\": \"SUCCESS\", \"traceback\": null, \"result\": 300, \"task_id\": \"7755e27b-bb53-4c05-8e46-037417ab4e30\", \"children\": []}'\n```\n\n取出任务id 7755e27b-bb53-4c05-8e46-037417ab4e30 的结果 \nhttp://localhost:8000/test_task_add_result/7755e27b-bb53-4c05-8e46-037417ab4e30/\n```\n127.0.0.1:6379> keys *\n1) \"_kombu.binding.celeryresults\"\n2) \"_kombu.binding.celery\"\n3) \"_kombu.binding.celery.pidbox\"\n4) \"2a5e68d9b44342778b5709dd69b2f465\\x06\\x169\"\n5) \"_kombu.binding.celeryev\"\n6) \"0377bc1c0e5d4a3ca5d27a06a162ba53\\x06\\x169\"\n127.0.0.1:6379> SMEMBERS \"_kombu.binding.celeryresults\"\n1) \"0377bc1c0e5d4a3ca5d27a06a162ba53\\x06\\x16\\x06\\x160377bc1c0e5d4a3ca5d27a06a162ba53\"\n2) \"2a5e68d9b44342778b5709dd69b2f465\\x06\\x16\\x06\\x162a5e68d9b44342778b5709dd69b2f465\"\n3) \"7755e27bbb534c058e46037417ab4e30\\x06\\x16\\x06\\x167755e27bbb534c058e46037417ab4e30\"\n```\n任务的结果被取出之后立即被删除\n\n\n方式二、web 页面发起任务请求（同时设置 broker, backend 为 redis） \nhttp://localhost:8000/test_send_task/?x=100&y=200\n```\n127.0.0.1:6379> keys *\n1) \"celery-task-meta-cce9eb23-5c6c-4852-a9fd-9100108a0b36\"\n2) \"_kombu.binding.celery\"\n3) \"celery-task-meta-7133e2f6-8d01-453f-b5ff-bd6d9d4cb90c\"\n4) \"_kombu.binding.celery.pidbox\"\n5) \"celery-task-meta-8ab29192-06fb-4438-b4d3-951765b5e10b\"\n6) \"_kombu.binding.celeryev\"\n127.0.0.1:6379> type \"celery-task-meta-cce9eb23-5c6c-4852-a9fd-9100108a0b36\"\nstring\n127.0.0.1:6379> ttl \"celery-task-meta-cce9eb23-5c6c-4852-a9fd-9100108a0b36\"\n(integer) 85943\n127.0.0.1:6379> get \"celery-task-meta-cce9eb23-5c6c-4852-a9fd-9100108a0b36\"\n\"{\\\"status\\\": \\\"SUCCESS\\\", \\\"traceback\\\": null, \\\"result\\\": 20000, \\\"task_id\\\": \\\"cce9eb23-5c6c-4852-a9fd-9100108a0b36\\\", \\\"children\\\": []}\"\n```\n任务结果字符串序列化存储，默认过期时间24小时（86400秒）\n\n取出任务id cce9eb23-5c6c-4852-a9fd-9100108a0b36 的结果 \nhttp://localhost:8000/test_task_mul_result/cce9eb23-5c6c-4852-a9fd-9100108a0b36/\n```\n127.0.0.1:6379> keys *\n1) \"celery-task-meta-cce9eb23-5c6c-4852-a9fd-9100108a0b36\"\n2) \"_kombu.binding.celery\"\n3) \"celery-task-meta-7133e2f6-8d01-453f-b5ff-bd6d9d4cb90c\"\n4) \"_kombu.binding.celery.pidbox\"\n5) \"celery-task-meta-8ab29192-06fb-4438-b4d3-951765b5e10b\"\n6) \"_kombu.binding.celeryev\"\n127.0.0.1:6379> ttl \"celery-task-meta-cce9eb23-5c6c-4852-a9fd-9100108a0b36\"\n(integer) 85789\n127.0.0.1:6379> get \"celery-task-meta-cce9eb23-5c6c-4852-a9fd-9100108a0b36\"\n\"{\\\"status\\\": \\\"SUCCESS\\\", \\\"traceback\\\": null, \\\"result\\\": 20000, \\\"task_id\\\": \\\"cce9eb23-5c6c-4852-a9fd-9100108a0b36\\\", \\\"children\\\": []}\"\n```\n任务的结果还缓存在 redis\n\n\n方式三、broker 为 rabbit, backend 为 rabbit\n\n开启 celery 实例\n```\n✗ celery worker -A app.celery_worker.celery_app -l INFO\n```\n\n查看队列情况\n```\n➜  ~ rabbitmqctl list_queues\nListing queues ...\ncelery@zhanghedeMacBook-Pro.local.celery.pidbox\t0\ncelery\t0\nceleryev.831c6f64-0e51-465a-8a32-ad8647708704\t0\n```\n\nweb 页面发起任务请求 http://localhost:8000/test_send_task/?x=100&y=200\n```\n➜  ~ rabbitmqctl list_queues\nListing queues ...\n226f45e6588840dd8cee49a539364e16\t1\ncelery@zhanghedeMacBook-Pro.local.celery.pidbox\t0\ncelery\t0\nfdf36b63accd4dffb6be7625c5cb4eca\t1\nceleryev.831c6f64-0e51-465a-8a32-ad8647708704\t0\n6401f4de1c924385b8708d36611d694d\t1\n```\n\n取出任务id 226f45e6-5888-40dd-8cee-49a539364e16 的结果 \nhttp://localhost:8000/test_task_mul_result/226f45e6-5888-40dd-8cee-49a539364e16/\n```\n➜  ~ rabbitmqctl list_queues\nListing queues ...\ncelery@zhanghedeMacBook-Pro.local.celery.pidbox\t0\ncelery\t0\nfdf36b63accd4dffb6be7625c5cb4eca\t1\nceleryev.831c6f64-0e51-465a-8a32-ad8647708704\t0\n6401f4de1c924385b8708d36611d694d\t1\n```\n\n查看队列内部消息结构\n```\n➜  ~ rabbitmqadmin get queue=celery requeue=true -f pretty_json\n[]\n➜  ~ rabbitmqadmin get queue=celery@zhanghedeMacBook-Pro.local.celery.pidbox requeue=true -f pretty_json\n[]\n➜  ~ rabbitmqadmin get queue=celeryev.831c6f64-0e51-465a-8a32-ad8647708704 requeue=true -f pretty_json\n[]\n➜  ~ rabbitmqadmin get queue=6401f4de1c924385b8708d36611d694d requeue=true\n+----------------------------------+---------------+---------------+----------------------------------------------------------------------------------------------------------------------------+---------------+------------------+-------------+\n|           routing_key            |   exchange    | message_count |                                                          payload                                                           | payload_bytes | payload_encoding | redelivered |\n+----------------------------------+---------------+---------------+----------------------------------------------------------------------------------------------------------------------------+---------------+------------------+-------------+\n| 6401f4de1c924385b8708d36611d694d | celeryresults | 0             | {\"status\": \"SUCCESS\", \"traceback\": null, \"result\": 300, \"task_id\": \"6401f4de-1c92-4385-b870-8d36611d694d\", \"children\": []} | 122           | string           | True        |\n+----------------------------------+---------------+---------------+----------------------------------------------------------------------------------------------------------------------------+---------------+------------------+-------------+\n➜  ~ rabbitmqadmin get queue=a8d21881e1254526be1077689c80988e requeue=true -f pretty_json\n[\n  {\n    \"exchange\": \"celeryresults\",\n    \"message_count\": 0,\n    \"payload\": \"{\\\"status\\\": \\\"SUCCESS\\\", \\\"traceback\\\": null, \\\"result\\\": 300, \\\"task_id\\\": \\\"a8d21881-e125-4526-be10-77689c80988e\\\", \\\"children\\\": []}\",\n    \"payload_bytes\": 122,\n    \"payload_encoding\": \"string\",\n    \"properties\": {\n      \"content_encoding\": \"utf-8\",\n      \"content_type\": \"application/json\",\n      \"correlation_id\": \"a8d21881-e125-4526-be10-77689c80988e\",\n      \"delivery_mode\": 2,\n      \"headers\": {},\n      \"priority\": 0\n    },\n    \"redelivered\": false,\n    \"routing_key\": \"a8d21881e1254526be1077689c80988e\"\n  }\n]\n```\n\n\n### 场景测试\n\n- 只设置 broker 为 redis\n- 同时设置 broker, backend 为 redis\n- broker 为 redis, backend 为 rabbit\n- 同时设置 broker, backend 为 rabbit\n"
  },
  {
    "path": "doc/Docker.md",
    "content": "## Docker\n\nhttps://yeasy.gitbooks.io/docker_practice/content/compose/\n\n\n## Docker-compose\n\nhttps://github.com/docker/compose\n\nhttps://docs.docker.com/compose/install/#install-as-a-container\n\n\n## Kubernetes\n\nhttp://kubernetes.io/\n\nKubernetes 为Google开源的容器管理框架\n\n提供了Docker容器的夸主机、集群管理、容器部署、高可用、弹性伸缩等一系列功能\n"
  },
  {
    "path": "doc/DockerHub.md",
    "content": "## 镜像地址\nhttps://hub.docker.com/r/kongpingzi/flask_project/\n\n```\n$ docker pull kongpingzi/flask_project\n```\n\n推送镜像：\n\nhttps://docs.docker.com/docker-cloud/builds/push-images/\n\n```\n$ export DOCKER_ID_USER=\"username\"\n$ docker login\nUsername: username\nPassword:\n```\n\n"
  },
  {
    "path": "doc/ElasticSearch.md",
    "content": "## ElasticSearch 2.x\n\n参考： [https://www.elastic.co/guide/en/elasticsearch/reference/current/setup-repositories.html](https://www.elastic.co/guide/en/elasticsearch/reference/current/setup-repositories.html)\n\nDownload and install the Public Signing Key:\n```\n$ wget -qO - https://packages.elastic.co/GPG-KEY-elasticsearch | sudo apt-key add -\n```\n\nSave the repository definition to /etc/apt/sources.list.d/elasticsearch-2.x.list:\n```\n$ echo \"deb http://packages.elastic.co/elasticsearch/2.x/debian stable main\" | sudo tee -a /etc/apt/sources.list.d/elasticsearch-2.x.list\n```\n\nRun apt-get update and the repository is ready for use. You can install it with:\n```\n$ sudo apt-get update && sudo apt-get install elasticsearch\n```\n\nConfigure Elasticsearch to automatically start during bootup.\nIf your distribution is using SysV init (Ubuntu 14.04 LTS), then you will need to run:\n```\n$ sudo update-rc.d elasticsearch defaults 95 10\n```\nOtherwise if your distribution is using systemd (Ubuntu 16.04 LTS):\n```\n$ sudo /bin/systemctl daemon-reload\n$ sudo /bin/systemctl enable elasticsearch.service\n```\n\nStart Elasticsearch Server\n```\n$ sudo /etc/init.d/elasticsearch start\n * Starting Elasticsearch Server             [ OK ]\n$ sudo /etc/init.d/elasticsearch status\n * elasticsearch is running\n```\n\nTest by curl\n```\n$ curl -X GET 'http://localhost:9200'\n{\n  \"name\" : \"Sub-Mariner\",\n  \"cluster_name\" : \"elasticsearch\",\n  \"version\" : {\n    \"number\" : \"2.3.1\",\n    \"build_hash\" : \"bd980929010aef404e7cb0843e61d0665269fc39\",\n    \"build_timestamp\" : \"2016-04-04T12:25:05Z\",\n    \"build_snapshot\" : false,\n    \"lucene_version\" : \"5.5.0\"\n  },\n  \"tagline\" : \"You Know, for Search\"\n}\n```\n\n[http://localhost:9200/](http://localhost:9200/)\n\n\n## Plugin\n\n### elasticsearch-head\n\nA web front end for an Elasticsearch cluster\n\nInstall elasticsearch-head for Elasticsearch 2.x\n```\n$ sudo /usr/share/elasticsearch/bin/plugin install mobz/elasticsearch-head\n```\n\n[https://github.com/mobz/elasticsearch-head](https://github.com/mobz/elasticsearch-head)\n\n[http://localhost:9200/_plugin/head/](http://localhost:9200/_plugin/head/)\n\n"
  },
  {
    "path": "doc/Flask-SQLAlchemy.md",
    "content": "## Flask-SQLAlchemy\n\n### Config\nhttp://flask-sqlalchemy.pocoo.org/2.2/config/\n\n### Changelog\nhttp://flask-sqlalchemy.pocoo.org/2.2/changelog/\n"
  },
  {
    "path": "doc/Flask-SSE.md",
    "content": "## Flask-SSE\n\nhttps://github.com/DazWorrall/flask-sse\n\n\n## 流式处理的几种方式\n\n- HTML5 Server-Sent Events\n- Flask-SSE\n\nhttp://dormousehole.readthedocs.io/en/latest/patterns/streaming.html\n\nhttp://flask.pocoo.org/snippets/118/\n\nhttp://www.python-requests.org/en/master/user/advanced/#streaming-requests\n\nhttp://flask-sse.readthedocs.io/en/latest/quickstart.html\n"
  },
  {
    "path": "doc/Flask-WTF.md",
    "content": "## Flask-WTF\n\nhttp://flask-wtf.readthedocs.io/en/stable/index.html\n\nhttp://wtforms.readthedocs.io/en/latest/\n\n"
  },
  {
    "path": "doc/Flower.md",
    "content": "Flower: Real-time Celery web-monitor\n\nhttps://flower.readthedocs.io/en/latest/\n\n\nInstall Flower\n```\n$ pip install flower\n```\n\nRunning the flower command\n```\n$ celery flower -A app.celery_worker.celery_app --port=5555\n$ celery flower -A app.celery_worker.celery_app --port=5555 --broker=redis://localhost:6379/0 --broker_api=redis://localhost:6379/0\n```\n\n```\n$ open http://localhost:5555\n```\n\nhttp://flower.readthedocs.io/en/latest/config.html#broker-api\n\n```\n$ flower -A app.celery_worker.celery_app --broker_api=http://guest:guest@rabbit@zhanghedeMacBook-Pro:15672/api/\n```\n"
  },
  {
    "path": "doc/Git.md",
    "content": "## git 开发流程\n\n以下流程的原则：本地不能直接修改 master 分支，仅仅作为主干分支\n\n注意`主干分支`与`开发分支`的区别\n\n### 开新分支\n```\n$ git checkout master\n$ git pull origin master\n$ git checkout -b dev\n```\n\n### 更新本地分支\n```\n$ git checkout dev\n$ git add .\n$ git commit -m \"更新dev分支\"\n```\n\n### 合并分支（`本地主干分支`合并到`本地开发分支`）\n\n#### merge 方式\n\n合并分支\n```\n$ git checkout master\n$ git pull origin master\n$ git checkout dev\n$ git merge master\n```\n\n解决冲突\n```\n$ git add .\n$ git commit -m \"合并dev分支\"\n```\n\n#### rebase 方式\n\n合并分支\n```\n$ git checkout master\n$ git pull --rebase origin master\n$ git checkout dev\n$ git rebase master\n```\n\n解决冲突\n```\n$ git add .\n$ git rebase --continue\n```\n\n注意：\n使用`rebase`合并，修改冲突后的提交，`rebase --continue` 替代 `commit`\n\n### 合并分支（`本地主干分支`合并到`远程主干分支`）\n```\n$ git checkout master\n$ git fetch origin master\n$ git rebase origin/master\n```\n\n### 演示流程\n\n模拟 新开分支，解决冲突，合并分支\n\n通过 graph 可以看出，主干分支不会出现交叉\n\n```\n➜  ~ cd code\n➜  code git clone git@gitee.com:v__v/test.git test_rebase\nCloning into 'test_rebase'...\nThe authenticity of host 'gitee.com (120.55.226.24)' can't be established.\nECDSA key fingerprint is SHA256:FQGC9Kn/eye1W8icdBgrQp+KkGYoFgbVr17bmjey0Wc.\nAre you sure you want to continue connecting (yes/no)? yes\nWarning: Permanently added 'gitee.com' (ECDSA) to the list of known hosts.\nremote: Counting objects: 3, done.\nremote: Total 3 (delta 0), reused 0 (delta 0)\nReceiving objects: 100% (3/3), done.\n➜  code cd test_rebase\n➜  test_rebase git:(master) git st\nOn branch master\nYour branch is up-to-date with 'origin/master'.\nnothing to commit, working tree clean\n➜  test_rebase git:(master) git br\n* master\n➜  test_rebase git:(master) git br -a\n* master\n  remotes/origin/HEAD -> origin/master\n  remotes/origin/master\n➜  test_rebase git:(master) git co -b dev\nSwitched to a new branch 'dev'\n➜  test_rebase git:(dev) git br -a\n* dev\n  master\n  remotes/origin/HEAD -> origin/master\n\n  remotes/origin/master\n➜  test_rebase git:(dev) ls\nREADME.md\n➜  test_rebase git:(dev) cat README.md\n# test\ngit 测试%\n➜  test_rebase git:(dev) echo \"git 测试 dev\" > README.md\n➜  test_rebase git:(dev) ✗ git st\nOn branch dev\nChanges not staged for commit:\n  (use \"git add <file>...\" to update what will be committed)\n  (use \"git checkout -- <file>...\" to discard changes in working directory)\n\n\tmodified:   README.md\n\nno changes added to commit (use \"git add\" and/or \"git commit -a\")\n➜  test_rebase git:(dev) ✗ git add .\n➜  test_rebase git:(dev) ✗ git ci -m 'dev更新README'\n[dev 087e069] dev更新README\n 1 file changed, 1 insertion(+), 2 deletions(-)\n➜  test_rebase git:(dev) git st\nOn branch dev\nnothing to commit, working tree clean\n➜  test_rebase git:(dev) git co master\nSwitched to branch 'master'\nYour branch is up-to-date with 'origin/master'.\n➜  test_rebase git:(master) ls\nREADME.md\n➜  test_rebase git:(master) cat README.md\n# test\ngit 测试% \n➜  test_rebase git:(master) echo \"git 测试 master\" > README.md\n➜  test_rebase git:(master) ✗ git add .\n➜  test_rebase git:(master) ✗ git ci -m 'master更新README'\n[master 030d108] master更新README\n 1 file changed, 1 insertion(+), 2 deletions(-)\n➜  test_rebase git:(master) git co dev\nSwitched to branch 'dev'\n➜  test_rebase git:(dev) git log --graph | cat\n* commit 6b2b6c49f0b56a6dd600dfa7d0e77e8088d4a7ff\n| Author: Zhang He <zhang_he06@163.com>\n| Date:   Wed Oct 11 18:20:38 2017 +0800\n|\n|     dev更新README\n|\n* commit 074cfc25cbfea99e486b57c3fdd8b2cddcd384d8\n  Author: 空ping子 <zhendime@gmail.com>\n  Date:   Wed Oct 11 18:15:28 2017 +0800\n\n      Initial commit\n➜  test_rebase git:(dev) git rebase master\nFirst, rewinding head to replay your work on top of it...\nApplying: dev更新README\nUsing index info to reconstruct a base tree...\nM\tREADME.md\nFalling back to patching base and 3-way merge...\nAuto-merging README.md\nCONFLICT (content): Merge conflict in README.md\nerror: Failed to merge in the changes.\nPatch failed at 0001 dev更新README\nThe copy of the patch that failed is found in: .git/rebase-apply/patch\n\nWhen you have resolved this problem, run \"git rebase --continue\".\nIf you prefer to skip this patch, run \"git rebase --skip\" instead.\nTo check out the original branch and stop rebasing, run \"git rebase --abort\".\n\n➜  test_rebase git:(030d108) ✗ git st\nrebase in progress; onto 030d108\nYou are currently rebasing branch 'dev' on '030d108'.\n  (fix conflicts and then run \"git rebase --continue\")\n  (use \"git rebase --skip\" to skip this patch)\n  (use \"git rebase --abort\" to check out the original branch)\n\nUnmerged paths:\n  (use \"git reset HEAD <file>...\" to unstage)\n  (use \"git add <file>...\" to mark resolution)\n\n\tboth modified:   README.md\n\nno changes added to commit (use \"git add\" and/or \"git commit -a\")\n➜  test_rebase git:(030d108) ✗ cat README.md\n<<<<<<< HEAD\ngit 测试 master\n=======\ngit 测试 dev\n>>>>>>> dev更新README\n➜  test_rebase git:(030d108) ✗ echo \"git 测试 dev merge\" > README.md\n➜  test_rebase git:(030d108) ✗ git st\nrebase in progress; onto 030d108\nYou are currently rebasing branch 'dev' on '030d108'.\n  (fix conflicts and then run \"git rebase --continue\")\n  (use \"git rebase --skip\" to skip this patch)\n  (use \"git rebase --abort\" to check out the original branch)\n\nUnmerged paths:\n\n  (use \"git reset HEAD <file>...\" to unstage)\n  (use \"git add <file>...\" to mark resolution)\n\n\tboth modified:   README.md\n\nno changes added to commit (use \"git add\" and/or \"git commit -a\")\n➜  test_rebase git:(030d108) ✗ git add .\n➜  test_rebase git:(030d108) ✗ git st\nrebase in progress; onto 030d108\nYou are currently rebasing branch 'dev' on '030d108'.\n  (all conflicts fixed: run \"git rebase --continue\")\n\nChanges to be committed:\n  (use \"git reset HEAD <file>...\" to unstage)\n\n\tmodified:   README.md\n\n➜  test_rebase git:(030d108) ✗ git rebase --continue\nApplying: dev更新README\n➜  test_rebase git:(dev) git st\nOn branch dev\nnothing to commit, working tree clean\n➜  test_rebase git:(dev) git log --graph | cat\n* commit 6b2b6c49f0b56a6dd600dfa7d0e77e8088d4a7ff\n| Author: Zhang He <zhang_he06@163.com>\n| Date:   Wed Oct 11 18:20:38 2017 +0800\n|\n|     dev更新README\n|\n* commit 030d10849d1ab4163f75fdcdf030ba3aded52404\n| Author: Zhang He <zhang_he06@163.com>\n| Date:   Wed Oct 11 18:21:33 2017 +0800\n|\n|     master更新README\n|\n* commit 074cfc25cbfea99e486b57c3fdd8b2cddcd384d8\n  Author: 空ping子 <zhendime@gmail.com>\n  Date:   Wed Oct 11 18:15:28 2017 +0800\n\n      Initial commit\n➜  test_rebase git:(dev) git diff master | cat\ndiff --git a/README.md b/README.md\nindex 297160d..6fbe460 100644\n--- a/README.md\n+++ b/README.md\n@@ -1 +1 @@\n-git 测试 master\n+git 测试 dev merge\n➜  test_rebase git:(dev) git co master\nSwitched to branch 'master'\nYour branch is ahead of 'origin/master' by 1 commit.\n  (use \"git push\" to publish your local commits)\n➜  test_rebase git:(master) git merge dev\nUpdating 030d108..6b2b6c4\nFast-forward\n README.md | 2 +-\n 1 file changed, 1 insertion(+), 1 deletion(-)\n➜  test_rebase git:(master) git log --graph | cat\n* commit 6b2b6c49f0b56a6dd600dfa7d0e77e8088d4a7ff\n| Author: Zhang He <zhang_he06@163.com>\n| Date:   Wed Oct 11 18:20:38 2017 +0800\n|\n|     dev更新README\n|\n* commit 030d10849d1ab4163f75fdcdf030ba3aded52404\n| Author: Zhang He <zhang_he06@163.com>\n| Date:   Wed Oct 11 18:21:33 2017 +0800\n|\n|     master更新README\n|\n* commit 074cfc25cbfea99e486b57c3fdd8b2cddcd384d8\n  Author: 空ping子 <zhendime@gmail.com>\n  Date:   Wed Oct 11 18:15:28 2017 +0800\n\n      Initial commit\n```\n\n\n对比一下简单粗暴的 merge 方式\n\n产生了一个无意义的 Merge\n\n```\n➜  code git clone git@gitee.com:v__v/test.git test_merge\nCloning into 'test_merge'...\nremote: Counting objects: 3, done.\nremote: Total 3 (delta 0), reused 0 (delta 0)\nReceiving objects: 100% (3/3), done.\n➜  code cd test_merge\n➜  test_merge git:(master) ls\nREADME.md\n➜  test_merge git:(master) git co -b dev\nSwitched to a new branch 'dev'\n➜  test_merge git:(dev) cat README.md\n# test\ngit 测试%                                                                                                                                                                         ➜  test_merge git:(dev) echo \"git 测试 dev\" > README.md\n➜  test_merge git:(dev) ✗ git add .\n➜  test_merge git:(dev) ✗ git ci -m 'dev更新README'\n[dev 6c85b19] dev更新README\n 1 file changed, 1 insertion(+), 2 deletions(-)\n➜  test_merge git:(dev) git co master\nSwitched to branch 'master'\nYour branch is up-to-date with 'origin/master'.\n➜  test_merge git:(master) echo \"git 测试 master\" > README.md\n➜  test_merge git:(master) ✗ git add .\n➜  test_merge git:(master) ✗ git ci -m 'master更新README'\n[master 44aa754] master更新README\n 1 file changed, 1 insertion(+), 2 deletions(-)\n➜  test_merge git:(master) git co dev\nSwitched to branch 'dev'\n➜  test_merge git:(dev) git merge master\nAuto-merging README.md\nCONFLICT (content): Merge conflict in README.md\nAutomatic merge failed; fix conflicts and then commit the result.\n➜  test_merge git:(dev) ✗ git st\nOn branch dev\nYou have unmerged paths.\n  (fix conflicts and run \"git commit\")\n  (use \"git merge --abort\" to abort the merge)\n\nUnmerged paths:\n  (use \"git add <file>...\" to mark resolution)\n\n\tboth modified:   README.md\n\nno changes added to commit (use \"git add\" and/or \"git commit -a\")\n➜  test_merge git:(dev) ✗ echo \"git 测试 dev merge\" > README.md\n➜  test_merge git:(dev) ✗ git st\nOn branch dev\nYou have unmerged paths.\n  (fix conflicts and run \"git commit\")\n  (use \"git merge --abort\" to abort the merge)\n\nUnmerged paths:\n  (use \"git add <file>...\" to mark resolution)\n\n\tboth modified:   README.md\n\nno changes added to commit (use \"git add\" and/or \"git commit -a\")\n➜  test_merge git:(dev) ✗ git add .\n➜  test_merge git:(dev) ✗ git st\nOn branch dev\nAll conflicts fixed but you are still merging.\n  (use \"git commit\" to conclude merge)\n\nChanges to be committed:\n\n\tmodified:   README.md\n\n➜  test_merge git:(dev) ✗ git ci -m 'dev Merge README'\n[dev 0e8fa0e] dev Merge README\n➜  test_merge git:(dev) git st\nOn branch dev\nnothing to commit, working tree clean\n➜  test_merge git:(dev) git log --graph | cat\n*   commit 0e8fa0ed7ce77827cec82bdda1fcca42c3a22330\n|\\  Merge: 6c85b19 44aa754\n| | Author: Zhang He <zhang_he06@163.com>\n| | Date:   Wed Oct 11 19:14:44 2017 +0800\n| |\n| |     dev Merge README\n| |\n| * commit 44aa75419691f7496d4e2d6c37c0eb6098078ed2\n| | Author: Zhang He <zhang_he06@163.com>\n| | Date:   Wed Oct 11 19:12:54 2017 +0800\n| |\n| |     master更新README\n| |\n* | commit 6c85b190593fb39e6fc3490675983f04dfb10d89\n|/  Author: Zhang He <zhang_he06@163.com>\n|   Date:   Wed Oct 11 19:12:12 2017 +0800\n|\n|       dev更新README\n|\n* commit 074cfc25cbfea99e486b57c3fdd8b2cddcd384d8\n  Author: 空ping子 <zhendime@gmail.com>\n  Date:   Wed Oct 11 18:15:28 2017 +0800\n\n      Initial commit\n```\n"
  },
  {
    "path": "doc/Gunicorn.md",
    "content": "## Gunicorn\n\nhttp://docs.gunicorn.org/en/latest/design.html#design\n\nhttp://docs.gunicorn.org/en/latest/deploy.html\n\n流式处理：\n\n开启异步模型\n关闭代理缓冲\n"
  },
  {
    "path": "doc/LightBox.md",
    "content": "## LightBox\n\n[http://lokeshdhakar.com/projects/lightbox2](http://lokeshdhakar.com/projects/lightbox2)\n\n[https://github.com/lokesh/lightbox2](https://github.com/lokesh/lightbox2)\n\nDownload the latest version as a zip file: [https://github.com/lokesh/lightbox2/archive/master.zip](https://github.com/lokesh/lightbox2/archive/master.zip)\n\n"
  },
  {
    "path": "doc/MariaDB.md",
    "content": "## MariaDB 安装及配置\n\n[官方下载地址](https://downloads.mariadb.org/mariadb/repositories/#mirror=opencas&distro=Ubuntu&distro_release=trusty--ubuntu_trusty&version=10.1)\n\n安装过程(Ubuntu 14.04 LTS \"trusty\")\n```\n$ sudo apt-get install software-properties-common\n$ sudo apt-key adv --recv-keys --keyserver hkp://keyserver.ubuntu.com:80 0xcbcb082a1bb943db\n$ sudo add-apt-repository 'deb [arch=amd64,i386] http://ftp.osuosl.org/pub/mariadb/repo/10.1/ubuntu trusty main'\n$ sudo apt-get update\n$ sudo apt-get install mariadb-server\n```\n\nMariaDB 服务\n```\n$ sudo /etc/init.d/mysql stop\n$ sudo /etc/init.d/mysql start\n$ sudo /etc/init.d/mysql restart\n```\n\n终端连接客户端\n```\n$ mysql -uroot -p\n```\n\n设置MariaDB允许远程访问\n\n使用nestat命令查看3306端口状态：\n```\n$ netstat -an | grep 3306\ntcp        0      0 127.0.0.1:3306          0.0.0.0:*               LISTEN\n```\n从结果可以看出3306端口只是在IP 127.0.0.1上监听，所以拒绝了其他IP的访问。\n\n解决方法：修改/etc/mysql/my.cnf文件。打开文件，找到下面内容：\n```\n# Instead of skip-networking the default is now to listen only on\n# localhost which is more compatible and is not less secure.\nbind-address  = 127.0.0.1\n```\n\n把上面这一行注释掉或者把127.0.0.1换成合适的IP，建议注释掉。\n\n重新启动后，重新使用netstat检测：\n```\n$ netstat -an | grep 3306\ntcp        0      0 0.0.0.0:3306            0.0.0.0:*               LISTEN\n```\n\n现在使用下面命令测试：\n```\n$ mysql -h 192.168.0.101 -u root -p\nEnter password:\nERROR 1130 (00000): Host 'Ubuntu-Fvlo.Server' is not allowed to connect to this MySQL server\n```\n结果出乎意料，还是不行。\n\n解决方法：原来还需要把用户权限分配各远程用户。\n\n登录到mysql服务器，使用grant命令分配权限\n```\n$ mysql -uroot -p\n```\n查看权限\n```\nMariaDB [(none)]> SHOW GRANTS \\G\n*************************** 1. row ***************************\nGrants for root@localhost: GRANT ALL PRIVILEGES ON *.* TO 'root'@'localhost' IDENTIFIED BY PASSWORD '*6BB4837EB74329105EE4568DDA7DC67ED2CA2AD9' WITH GRANT OPTION\n*************************** 2. row ***************************\nGrants for root@localhost: GRANT PROXY ON ''@'%' TO 'root'@'localhost' WITH GRANT OPTION\n2 rows in set (0.09 sec)\n```\n添加权限\n```\nMariaDB [(none)]> GRANT ALL PRIVILEGES ON *.* TO 'zhanghe'@'%' IDENTIFIED BY '123456' WITH GRANT OPTION;\nQuery OK, 0 rows affected (0.68 sec)\nMariaDB [(none)]> FLUSH PRIVILEGES;\nQuery OK, 0 rows affected (0.30 sec)\n```\n重启服务\n```\n$ sudo /etc/init.d/mysql restart\n```\n测试服务器本地访问\n```\n$ mysql -p123456\nMariaDB [(none)]>\n```\n测试远程访问\n```\n$ mysql -h 192.168.0.101 -u root -p\n```\n\n修改密码(先登录，后重置)\n```\n$ mysql -u root -p\nMariaDB [(none)]> SET PASSWORD FOR 'root'@'localhost' = PASSWORD('123456');\n```\n\n\n## InnoDB MyISAM 区别\n\n如果你需要事务处理或是外键，那么 InnoDB 可能是比较好的方式。\n\n如果你需要全文索引，那么通常来说 MyISAM 是好的选择，但是通常全文检索有其它的解决方案（例如ES）。\n\nCOUNT() 在 MyISAM 表中会非常快，而在 InnoDB 表下可能会很痛苦。\n\n主键查询则在 InnoDB 下会相当相当的快，但需要小心的是如果我们的主键太长了也会导致性能问题。\n\n大批的 inserts 语句在 MyISAM 下会快一些\n\nupdates 在 InnoDB 下会更快一些\n\nInnoDB 的表需要更多的内存和存储，转换100GB 的 MyISAM 表到 InnoDB 表可能会让你有非常坏的体验。\n\n所以通常采用 InnoDB 即可\n\n\n## Mac 下配置修改\n\n```\nsudo cp /usr/local/Cellar/mariadb/10.1.17/support-files/my-medium.cnf /etc/my.cnf\n\nbrew services start MariaDB\nor\nmysql.server start\n```\n\n\n## 事务隔离级别\n\n```sql\nMariaDB [(none)]> SELECT @@tx_isolation, @@global.tx_isolation, @@session.tx_isolation;\n+-----------------+-----------------------+------------------------+\n| @@tx_isolation  | @@global.tx_isolation | @@session.tx_isolation |\n+-----------------+-----------------------+------------------------+\n| REPEATABLE-READ | REPEATABLE-READ       | REPEATABLE-READ        |\n+-----------------+-----------------------+------------------------+\n1 row in set (0.00 sec)\n```\n\n"
  },
  {
    "path": "doc/MongoDB.md",
    "content": "## Python MongoDB\n\nmongo数据库安装（包含服务端/客户端）\n```\n$ sudo apt-get install mongodb\n```\n\nmongo仅客户端安装\n```\n$ sudo apt-get install mongodb-clients\n```\n\npymongo安装(虚拟环境不需要sudo)\n```\n$ sudo pip install pymongo\n```\n\n命令行简单命令：\n```\n> show dbs\n> use [db]\n> show tables\n> show collections\n> db.[table/collection].find().pretty()\n```\n\n最新版安装记录(3.0版本不支持32位系统，最后一步无法安装)\n```\n$ sudo apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv 7F0CEB10\n$ echo \"deb http://repo.mongodb.org/apt/ubuntu \"$(lsb_release -sc)\"/mongodb-org/3.0 multiverse\" | sudo tee /etc/apt/sources.list.d/mongodb-org-3.0.list\n$ sudo apt-get update\n$ sudo apt-get install -y mongodb-org\n```\n\n32位系统安装最新版（最高支持到2.6）方式：\n```\n$ sudo apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv 7F0CEB10\n$ echo 'deb http://downloads-distro.mongodb.org/repo/ubuntu-upstart dist 10gen' | sudo tee /etc/apt/sources.list.d/mongodb.list\n$ sudo apt-get update\n$ sudo apt-get install -y mongodb-org\n```\n\n服务启动关闭重启\n```\n$ sudo service mongod start\n$ sudo service mongod stop\n$ sudo service mongod restart\n```\n\n参考：\n\n[mongo最新版安装，仅支持64位](https://docs.mongodb.org/manual/tutorial/install-mongodb-on-ubuntu/)\n\n[mongo最新版安装，32位系统](https://docs.mongodb.org/v2.6/tutorial/install-mongodb-on-ubuntu/)\n\n[pymongo安装](http://api.mongodb.org/python/current/installation.html)\n\n[官网教程](http://api.mongodb.org/python/current/tutorial.html)\n\n\n## Mac 操作\n\n安装\n```\nbrew update\nbrew install mongodb --with-openssl\n```\n\n启动服务\n```\nmkdir data/db_mongo\nmongod --dbpath data/db_mongo\n或者\nmongod --config /usr/local/etc/mongod.conf\n```\n\n## \n\n创建管理员\n```\n> use admin\nswitched to db admin\n> db.createUser(\n...   {\n...     user: \"root\",\n...     pwd: \"123456\",\n...     roles: [ { role: \"userAdminAnyDatabase\", db: \"admin\" } ]\n...   }\n... )\nSuccessfully added user: {\n\t\"user\" : \"root\",\n\t\"roles\" : [\n\t\t{\n\t\t\t\"role\" : \"userAdminAnyDatabase\",\n\t\t\t\"db\" : \"admin\"\n\t\t}\n\t]\n}\n```\n\n开启权限控制\n```\nmongod --auth --port 27017 --dbpath data/db_mongo\nmongo --port 27017 -u \"root\" -p \"123456\" --authenticationDatabase \"admin\"\n```\n\n创建普通用户\n```\n> use admin\n> db.auth(\"root\", \"1234567\")\nError: Authentication failed.\n0\n> db.auth(\"root\", \"123456\")\n1\n```\n\n```\nuse test\ndb.createUser(\n  {\n    user: \"www\",\n    pwd: \"123456\",\n    roles: [ { role: \"readWrite\", db: \"flask_project\" } ]\n  }\n)\n```\n"
  },
  {
    "path": "doc/OAuth.md",
    "content": "### GitHub\n\nSetup Application：[https://github.com/settings/applications/new](https://github.com/settings/applications/new)\n\n\n### QQ\n\nQQ 互联：[http://connect.qq.com/manage/](http://connect.qq.com/manage/)\n\n\n### WeiBo\n\n微博开放平台：[http://open.weibo.com/](http://open.weibo.com/)\n\n\n## 第三方登录系统数据库设计\n\n登录方式：\nusername + password\nphone + password\nopen_id + access_token\n\n\n抽象成　用户基础信息表　和　用户授权信息表\n用户信息表和用户授权表是一对多的关系\n\n用户基础信息表 user\n```\nid\nnickname\nemail\nphone\nbirthday\ncreate_time\nupdate_time\nlast_ip\n```\n用户授权信息表 user_auth\n```\nid\nuser_id\nauth_type       登录类型（手机号 邮箱 用户名）或第三方应用名称（微信 微博等）\nauth_key        标识（手机号 邮箱 用户名或第三方应用的唯一标识）\nauth_secret     密码凭证（站内的保存密码，站外的不保存或保存token）\nauth_expires    过期时间\nverified        验证状态（手机号，邮箱是否验证　默认第三方登录都是已验证）\n```\n\n### 用户登录处理过程：\n\n判断用户登录请求类型\n```\n邮箱/用户名/手机号/第三方\n```\n\n查询用户是否存在\n```\nSELECT * FROM user_auth WHERE auth_type='登录类型' and auth_key='账号标识'\n```\n\n校验用户凭证（密码）\n```\nSELECT * FROM user_auth WHERE id='user_auth.id' and auth_secret='password_hash(密码)'\n```\n\n查询用户信息\n```\nSELECT * FROM user WHERE id='user_id'\n```\n\n\n应用场景：\n\n验证用户是否存在\n```\nSELECT * FROM user_auth WHERE auth_type='phone' and auth_key='手机号'\nSELECT * FROM user_auth WHERE auth_type='email' and auth_key='邮箱'\nSELECT * FROM user_auth WHERE auth_type='qq' and auth_key='QQ号码'\nSELECT * FROM user_auth WHERE auth_type='weixin' and auth_key='微信UserName'\n```\n如果有记录，则直接登录成功，使用新的 token 更新原 token。\n\n\n### 优点与缺点\n\n- 缺点\n    - sql 请求增加为 2 次\n    - 用户同时存在邮箱、用户名、手机号等多种站内登录方式时，改密码时必须一起改\n    - 代码量增加了，有些情况下逻辑判断增加了，难度增大了。\n\n## 本地调试\n\ngithub 直接设置本地地址调试即可\n\nqq 需要准备可访问的域名，并验证，再修改 hosts 域名指向本机\n\n\n## Web系统认证信息传递\n\n服务端可以用 session 保持用户登陆状态，代价却是内存占用高，单台服务器变成有状态，无法简单扩展成集群。仅供演示\n\n生产环境可以使用 cookie 实现\n\n但是如果需要存储大量的会话数据，将数据从cookie移动到服务器是有意义的\n\n\n## 第三方登录与本地注册、绑定流程的结合\n\n- 用户直接注册（系统自动生成 uid）\n    - 邮箱注册，验证邮件\n    - 手机注册，验证短信\n    - 校验通过，\n\n- 用户本地登录\n    - 未经校验，提示校验\n    - 校验通过，执行登录\n\n- 第三方登录，系统提示:\n    - 绑定, 与本地系统账号绑定\n    - 注册\n    - 用户离开，不处理\n\n\n## 会话管理\n\n参考：http://flask.pocoo.org/snippets/75/\n\n- 多终端同时登陆\n\n- 多终端单台登陆\n\n- 多系统共享登陆\n\nsession 在服务端存储的数据结构\n\n{\n    'session_id': {\n        'user_name': '',\n    }\n}"
  },
  {
    "path": "doc/OpenPay.md",
    "content": "## 支付宝支付\n\n[支付宝开放平台](https://open.alipay.com)\n\n[An Unofficial Alipay API for Python](https://github.com/lxneng/alipay)\n\n安装\n```\npip install alipay\n```\n\n## 微信支付\n\n[微信支付平台](https://pay.weixin.qq.com)\n"
  },
  {
    "path": "doc/Redis.md",
    "content": "## Installation\n\nhttp://redis.io/download\n\nDownload, extract and compile Redis with:\n```\n$ wget http://download.redis.io/releases/redis-3.2.4.tar.gz\n$ tar xzf redis-3.2.4.tar.gz\n$ cd redis-3.2.4\n$ make\n```\n\n```\n$ src/redis-server\n```\n\n```\n$ src/redis-cli\n```\n\n配置软链(Mac)\n```\n$ ln -s /Users/zhanghe/tools/redis-3.2.4/src/redis-server /usr/local/bin/redis-server\n$ ln -s /Users/zhanghe/tools/redis-3.2.4/src/redis-cli /usr/local/bin/redis-cli\n```\n\n\n## 配置\n\n修改配置：redis.conf\n```\nprotected-mode yes\n>>\nprotected-mode no\n\n# masterauth <master-password>\n>>\nmasterauth 123456\n\n# requirepass foobared\n>>\nrequirepass 123456\n\nbind 127.0.0.1\n>>\nbind 0.0.0.0\n```\n\n重启服务\n```\nredis-cli shutdown\nredis-server redis.conf\n```\n"
  },
  {
    "path": "doc/Siege.md",
    "content": "## Siege 压力测试\n\n\n100并发，发生2次\n```\n$ siege -c 100 -r 2 http://0.0.0.0:8010/performance/ -b\n```\n\n自带的web服务\n```\nTransactions:                200 hits\nAvailability:             100.00 %\nElapsed time:               3.21 secs\nData transferred:           0.00 MB\nResponse time:              0.95 secs\nTransaction rate:          62.31 trans/sec\nThroughput:             0.00 MB/sec\nConcurrency:               59.36\nSuccessful transactions:         200\nFailed transactions:               0\nLongest transaction:            1.55\nShortest transaction:           0.15\n```\n\nGunicorn\n```\nTransactions:               200 hits\nAvailability:             100.00 %\nElapsed time:               1.66 secs\nData transferred:           0.00 MB\nResponse time:              0.34 secs\nTransaction rate:         120.48 trans/sec\nThroughput:             0.00 MB/sec\nConcurrency:               40.89\nSuccessful transactions:         200\nFailed transactions:               0\nLongest transaction:            0.66\nShortest transaction:           0.04\n```\n\nGunicorn 性能也只是 Flask 自带服务的一倍\n\n\n\n```\nsiege -c 200 -r 100 -b http://0.0.0.0:8010/performance/\n```\n\n自带的web服务\n```\nTransactions:\t\t       19856 hits\nAvailability:\t\t       99.28 %\nElapsed time:\t\t      418.45 secs\nData transferred:\t        0.08 MB\nResponse time:\t\t        2.61 secs\nTransaction rate:\t       47.45 trans/sec\nThroughput:\t\t        0.00 MB/sec\nConcurrency:\t\t      123.84\nSuccessful transactions:       19856\nFailed transactions:\t         144\nLongest transaction:\t       83.56\nShortest transaction:\t        0.01\n```\n\nGunicorn\n```\nTransactions:\t\t       19930 hits\nAvailability:\t\t       99.65 %\nElapsed time:\t\t      187.44 secs\nData transferred:\t        0.08 MB\nResponse time:\t\t        1.08 secs\nTransaction rate:\t      106.33 trans/sec\nThroughput:\t\t        0.00 MB/sec\nConcurrency:\t\t      114.35\nSuccessful transactions:       19930\nFailed transactions:\t          70\nLongest transaction:\t      117.82\nShortest transaction:\t        0.01\n```\n"
  },
  {
    "path": "doc/SqlAlchemy.md",
    "content": "## SQLAlchemy\n\n[SQLAlchemy Documentation](http://docs.sqlalchemy.org/en/latest)\n\n\n### Conjunctions\n\n[Conjunctions](http://docs.sqlalchemy.org/en/latest/core/tutorial.html#conjunctions)\n\n- and_()\n- or_()\n- not_()\n\n\n### Common Filter Operators\n\n[Common Filter Operators](http://docs.sqlalchemy.org/en/latest/orm/tutorial.html#common-filter-operators)\n\n- User.name == 'ed'\n- User.name != 'ed'\n- User.name.like('%ed%')\n- User.name.in_(['ed', 'wendy', 'jack'])\n- ~User.name.in_(['ed', 'wendy', 'jack'])\n- User.name == None\n- User.name.is_(None)\n- User.name != None\n- User.name.isnot(None)\n\n\n### Functions\n\n[Functions](http://docs.sqlalchemy.org/en/latest/core/tutorial.html#functions)\n\nfrom sqlalchemy.sql import func\n\n- func.now()\n- func.current_timestamp()\n- func.concat('x', 'y')\n- func.substr(User.nickname, 2).label('nickname_new')  # SqLite\n- func.left(User.nickname, 2).label('nickname_new')  # MySql\n- func.date(User.create_time).label('date')\n- func.count(User.id)\n\n\n### Transtraction\n\n基本结构：\n```\ntry:\n    db.session.add(model_obj_01)\n    db.session.flush()\n    print inspect(model_obj_01).identity[0]\n    \n    db.session.add(model_obj_02)\n    db.session.flush()\n    print inspect(model_obj_02).identity[0]\n\n    db.session.commit()\nexcept Exception as e:\n    db.session.rollback()\n    raise e\n```\n\ndb.session.flush() 是将数据修改刷入内存\ndb.session.commit() 将修改存入数据库\n\n\n连接 URI 格式\n\n[支持的数据库](http://www.sqlalchemy.org/docs/core/engines.html)\n\nPostgres:\n\npostgresql://scott:tiger@localhost/mydatabase\n\nMySQL:\n\nmysql://scott:tiger@localhost/mydatabase\n\nOracle:\n\noracle://scott:tiger@127.0.0.1:1521/sidname\n\nSQLite (注意开头的四个斜线):\n\nsqlite:////absolute/path/to/foo.db\n"
  },
  {
    "path": "doc/UbuntuServer.md",
    "content": "## UbuntuServer\nubuntu-16.04.2-server-amd64\n```\n$ lsb_release -a\nNo LSB modules are available.\nDistributor ID:\tUbuntu\nDescription:\tUbuntu 16.04.2 LTS\nRelease:\t16.04\nCodename:\txenial\n$ lsb_release -c\nCodename:\txenial\n```\n\n### 服务器安装 OpenSSH 服务\nOpenSSH是SSH的替代软件，而且是免费的\n```\n$ sudo apt-get install openssh-server\n$ /etc/init.d/ssh status\n```\n\n### 生成密钥对，用户免密登录\n（执行以下命令一路回车）\n```\n$ ssh-keygen -t rsa\n```\n\n### 更换国内源\n参考：[http://wiki.ubuntu.org.cn/源列表](http://wiki.ubuntu.org.cn/源列表)\n\n```\n$ sudo cp /etc/apt/sources.list /etc/apt/sources.list_backup\n$ sudo vim /etc/apt/sources.list\n```\n替换：\n```\ndeb http://mirrors.aliyun.com/ubuntu/ xenial main restricted universe multiverse\ndeb http://mirrors.aliyun.com/ubuntu/ xenial-security main restricted universe multiverse\ndeb http://mirrors.aliyun.com/ubuntu/ xenial-updates main restricted universe multiverse\ndeb http://mirrors.aliyun.com/ubuntu/ xenial-proposed main restricted universe multiverse\ndeb http://mirrors.aliyun.com/ubuntu/ xenial-backports main restricted universe multiverse\ndeb-src http://mirrors.aliyun.com/ubuntu/ xenial main restricted universe multiverse\ndeb-src http://mirrors.aliyun.com/ubuntu/ xenial-security main restricted universe multiverse\ndeb-src http://mirrors.aliyun.com/ubuntu/ xenial-updates main restricted universe multiverse\ndeb-src http://mirrors.aliyun.com/ubuntu/ xenial-proposed main restricted universe multiverse\ndeb-src http://mirrors.aliyun.com/ubuntu/ xenial-backports main restricted universe multiverse\n```\n更新：\n```\n$ sudo apt-get update\n```\n\n### docker 安装\n\n准备 add-apt-repository\n```\n$ sudo apt-get install python-software-properties\n$ sudo apt-get install software-properties-common\n```\n\n1. Set up the repository\n```\n$ sudo apt-get -y install \\\n  apt-transport-https \\\n  ca-certificates \\\n  curl\n\n$ curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -\n\n$ sudo add-apt-repository \\\n       \"deb [arch=amd64] https://download.docker.com/linux/ubuntu \\\n       $(lsb_release -cs) \\\n       stable\"\n\n$ sudo apt-get update\n```\n\n2. Get Docker CE\n```\n$ sudo apt-get -y install docker-ce\n```\n\n```\n$ sudo docker -v\nDocker version 17.03.1-ce, build c6d412e\n```\n\n\n### Docker Compose\n\n不翻墙，下载过程极慢\n```\n$ sudo -i\n# curl -L https://github.com/docker/compose/releases/download/1.13.0/docker-compose-`uname -s`-`uname -m` > /usr/local/bin/docker-compose\n# chmod +x /usr/local/bin/docker-compose\n$ docker-compose -v\ndocker-compose version 1.13.0, build 1719ceb\n```\n\ncompose-file 参考：\nhttps://github.com/docker/docker.github.io/blob/master/compose/compose-file/index.md\n\n```\n$ docker-compose build\n$ docker-compose up\n```\n"
  },
  {
    "path": "doc/WeiXin.md",
    "content": "## 微信公众平台\n\n[https://mp.weixin.qq.com](https://mp.weixin.qq.com)\n"
  },
  {
    "path": "doc/bootstrap-select.md",
    "content": "## bootstrap-select\n\nhttps://github.com/silviomoreto/bootstrap-select\n\nhttps://silviomoreto.github.io/bootstrap-select/\n\nCDNJS\n```\n<!-- Latest compiled and minified CSS -->\n<link rel=\"stylesheet\" href=\"https://cdnjs.cloudflare.com/ajax/libs/bootstrap-select/1.12.2/css/bootstrap-select.min.css\">\n\n<!-- Latest compiled and minified JavaScript -->\n<script src=\"https://cdnjs.cloudflare.com/ajax/libs/bootstrap-select/1.12.2/js/bootstrap-select.min.js\"></script>\n\n<!-- (Optional) Latest compiled and minified JavaScript translation files -->\n<script src=\"https://cdnjs.cloudflare.com/ajax/libs/bootstrap-select/1.12.2/js/i18n/defaults-*.min.js\"></script>\n```\n\n\n## 示例\n\n```\n<div class=\"form-group\">\n    <label class=\"col-sm-2 control-label\" for=\"reg_type\">Reg Type</label>\n    <div class=\"col-sm-10\">\n        <select class=\"selectpicker\" data-live-search=\"true\" title=\"Choose one of the following...\" data-header=\"Select a condiment\" id=\"reg_type\">\n            <optgroup label=\"Picnic\">\n                <option>Mustard</option>\n                <option>Ketchup</option>\n                <option>Relish</option>\n            </optgroup>\n            <optgroup label=\"Camping\">\n                <option>Tent</option>\n                <option>Flashlight</option>\n                <option>Toilet Paper</option>\n            </optgroup>\n        </select>\n    </div>\n</div>\n```"
  },
  {
    "path": "doc/cache.md",
    "content": "# Flask 缓存\n\n参考：[http://www.pythondoc.com/flask/patterns/caching.html](http://www.pythondoc.com/flask/patterns/caching.html)\n\nFlask 本身不提供缓存，但是它的基础库之一 Werkzeug 有一些非常基本的缓存支持。\n\n- SimpleCache\n- MemcachedCache\n- RedisCache\n- FileSystemCache\n\n\n测试如下：\n\nviews.py\n\n```\nfrom werkzeug.contrib.cache import SimpleCache\ncache = SimpleCache()  # 默认最大支持500个key, 超时时间5分钟, 参数可配置\n```\n\n```\n@app.route('/test_cache/')\ndef test_cache():\n    \"\"\"\n    缓存测试\n    5.01s >> 9ms\n    \"\"\"\n    import time\n    rv = cache.get('my-item')\n    if rv is None:\n        time.sleep(5)\n        rv = 'Hello, Cache!'\n        cache.set('my-item', rv, timeout=5 * 10)\n    return rv\n```\n"
  },
  {
    "path": "doc/fabric.md",
    "content": "## fabric\n\ninstall fabric\n```\n$ pip install fabric\n```\n\n[http://www.fabfile.org/](http://www.fabfile.org/)\n\nFabric’s Tutorial [http://docs.fabfile.org/en/1.11/](http://docs.fabfile.org/en/1.11/)\n\nOverview and Tutorial [http://docs.fabfile.org/en/1.11/tutorial.html](http://docs.fabfile.org/en/1.11/tutorial.html)\n"
  },
  {
    "path": "doc/https.md",
    "content": "## 生成证书\n\n证书生成工具：\n\nhttps://certificatetools.com/\n\n\n可以通过以下步骤生成一个简单的证书：\n\n首先，进入你想创建证书和私钥的目录，例如：\n```\n$ cd ssl\n```\n\n创建服务器私钥，命令会让你输入一个口令(为了简便：123456, 强烈不推荐)：\n```\n$ openssl genrsa -des3 -out ca.key 1024\n```\n```\nGenerating RSA private key, 1024 bit long modulus\n.............................++++++\n......++++++\ne is 65537 (0x10001)\nEnter pass phrase for ca.key:\nVerifying - Enter pass phrase for ca.key:\n```\n\n创建签名请求的证书（CSR）：\n```\n$ openssl req -new -key ca.key -out server.csr\n```\n```\nEnter pass phrase for ca.key:\nYou are about to be asked to enter information that will be incorporated\ninto your certificate request.\nWhat you are about to enter is what is called a Distinguished Name or a DN.\nThere are quite a few fields but you can leave some blank\nFor some fields there will be a default value,\nIf you enter '.', the field will be left blank.\n-----\nCountry Name (2 letter code) [AU]:CN\nState or Province Name (full name) [Some-State]:Shanghai\nLocality Name (eg, city) []:HuangPu\nOrganization Name (eg, company) [Internet Widgits Pty Ltd]:Shanghai Flask Project Ltd\nOrganizational Unit Name (eg, section) []:Flask Organization\nCommon Name (e.g. server FQDN or YOUR name) []:*.app.com\nEmail Address []:admin@app.com\n\nPlease enter the following 'extra' attributes\nto be sent with your certificate request\nA challenge password []:\nAn optional company name []:Shanghai Flask App Ltd\n```\n\n在加载SSL支持的Nginx并使用上述私钥时除去必须的口令：\n```\n$ openssl rsa -in ca.key -out server.key\n```\n```\nEnter pass phrase for ca.key:\nwriting RSA key\n```\n\n最后标记证书使用上述私钥和CSR：\n```\n$ openssl x509 -req -days 365 -in server.csr -signkey server.key -extfile v3.ext -out server.crt\n```\n```\nSignature ok\nsubject=/C=CN/ST=Shanghai/L=HuangPu/O=Shanghai Flask Project Ltd/OU=Flask Organization/CN=*.app.com/emailAddress=admin@app.com\nGetting Private key\n```\n\n## 配置 Nginx\n\n修改Nginx配置文件，让其包含新标记的证书和私钥：\n```\nserver {\n    server_name www.app.com;\n    listen 443;\n    ssl on;\n    ssl_certificate /home/zhanghe/code/flask_project/ssl/server.crt;\n    ssl_certificate_key /home/zhanghe/code/flask_project/ssl/server.key;\n}\n```\n重启 nginx。\n\n这样就可以通过以下方式访问：\n[https://www.app.com](https://www.app.com)\n\n另外还可以加入如下代码实现80端口重定向到443\n```\nserver {\n    listen 80;\n    server_name www.app.com;\n    rewrite ^(.*) https://$server_name$1 permanent;\n}\n```\n\n访问页面，会出现提示：该网站的安全证书不受信任！\n\n仍然继续访问, https 标识为 X\n\n三道杠 >> 设置 >> HTTPS/SSL >> 管理证书 >> 证书管理器 >> 授权中心 >> 导入 >> 选择证书 >> 勾选信任该证书，以标识网站的身份。\n\n再次访问，图标变为绿色，心情瞬间变好了。\n"
  },
  {
    "path": "doc/jQuery-File-Upload.md",
    "content": "## jQuery File Upload\n\n> File Upload widget with multiple file selection, drag&drop support, progress bar, validation and preview images, audio and video for jQuery.\n\n[https://github.com/blueimp/jQuery-File-Upload](https://github.com/blueimp/jQuery-File-Upload)\n\n[jQuery File Upload Demo](https://blueimp.github.io/jQuery-File-Upload/)\n\n\n### Requirements\n\n#### Mandatory requirements\n\n- [jQuery](https://jquery.com/)\n- [jQuery UI widget factory](https://api.jqueryui.com/jQuery.widget/)\n- [jQuery Iframe Transport plugin](https://github.com/blueimp/jQuery-File-Upload/blob/master/js/jquery.iframe-transport.js)\n\n#### Optional requirements\n\n- [Bootstrap](http://getbootstrap.com/)\n- [Glyphicons](http://glyphicons.com/)\n- [JavaScript Templates engine](https://github.com/blueimp/JavaScript-Templates)\n\n\n### JSON Response\n\n[https://github.com/blueimp/jQuery-File-Upload/wiki/JSON-Response](https://github.com/blueimp/jQuery-File-Upload/wiki/JSON-Response)\n\n[The newer response is documented](https://github.com/blueimp/jQuery-File-Upload/wiki/Setup#using-jquery-file-upload-ui-version-with-a-custom-server-side-upload-handler)\n\n\n### Basic plugin\n\n[Basic plugin](https://github.com/blueimp/jQuery-File-Upload/wiki/Basic-plugin)\n\n\n### Server Code\n\n[server/php/UploadHandler.php](https://github.com/blueimp/jQuery-File-Upload/blob/master/server/php/UploadHandler.php)\n\n\n### Usage\n\n初始化\n```\n$('#fileupload').fileupload();\n```\n\n也可以带参数\n```\n$('#fileupload').fileupload({\n    url: '/path/to/upload/handler.json',\n    sequentialUploads: true\n});\n```\n\n也可以使用下面的方式设置参数\n```\n<input id=\"fileupload\" type=\"file\" name=\"files[]\" multiple\n    data-url=\"/path/to/upload/handler.json\"\n    data-sequential-uploads=\"true\"\n    data-form-data='{\"script\": \"true\"}'>\n```\n\n\n### Other Example\n\n不想使用模板引擎，可以如下操作：\n```\n<script>\n    $(function () {\n        //文件上传地址\n        var url = '{{ url_for('uploads') }}';\n        //初始化，主要是设置上传参数，以及事件处理方法(回调函数)\n        $('#fileupload').fileupload({\n            autoUpload: true,//是否自动上传\n            url: url,//上传地址\n            dataType: 'json',\n            done: function (e, data) {//设置文件上传完毕事件的回调函数\n                console.log(data);\n\n                $.each(data.files, function (index, file) {\n                    //$('<p/>').text(file.name).appendTo($('#upload_list'));\n                    var html_text = '<tr class=\"template-upload fade in\">';\n                    html_text += '<td><p class=\"name\">'+file.name+'</p></td>';\n                    html_text += '<td><span class=\"size\">'+file.size+'</span></td>';\n                    html_text += '<td>' +\n                            '<button class=\"btn btn-primary start\"><i class=\"glyphicon glyphicon-upload\"></i><span>Start</span></button> ' +\n                            '<button class=\"btn btn-warning cancel\"><i class=\"glyphicon glyphicon-ban-circle\"></i><span>Cancel</span></button>' +\n                            '</td>';\n                    html_text += '</tr>';\n                    $(html_text).appendTo($('tbody.files'));\n                });\n\n            },\n            progressall: function (e, data) {//设置上传进度事件的回调函数\n                var progress = parseInt(data.loaded / data.total * 100, 10);\n                $('#progress .bar').css(\n                    'width',\n                    progress + '%'\n                );\n            }\n        });\n    });\n</script>\n```\n\n\npython html页面变量替换\n\n```\nthumbnailUrl    thumbnail_url\ndeleteUrl       delete_url\ndeleteType      delete_type\n```\n"
  },
  {
    "path": "doc/mirrors.md",
    "content": "## 系统源镜像\n\nhttp://www.debian.org/mirror/list\n\nhttp://mirrors.aliyun.com/\n\n若使用阿里云服务器, 将源的域名从 mirrors.aliyun.com 改为 mirrors.aliyuncs.com 不占用公网流量。\n\n以 debian 8.x (jessie) 为例\n\n```\nsudo vim /etc/apt/sources.list\n```\n\n163源\n```\ndeb http://mirrors.163.com/debian/ jessie main non-free contrib\ndeb http://mirrors.163.com/debian/ jessie-updates main non-free contrib\ndeb http://mirrors.163.com/debian/ jessie-backports main non-free contrib\ndeb-src http://mirrors.163.com/debian/ jessie main non-free contrib\ndeb-src http://mirrors.163.com/debian/ jessie-updates main non-free contrib\ndeb-src http://mirrors.163.com/debian/ jessie-backports main non-free contrib\ndeb http://mirrors.163.com/debian-security/ jessie/updates main non-free contrib\ndeb-src http://mirrors.163.com/debian-security/ jessie/updates main non-free contrib\n```\n\n阿里源\n```\ndeb http://mirrors.aliyun.com/debian/ jessie main non-free contrib\ndeb http://mirrors.aliyun.com/debian/ jessie-proposed-updates main non-free contrib\ndeb-src http://mirrors.aliyun.com/debian/ jessie main non-free contrib\ndeb-src http://mirrors.aliyun.com/debian/ jessie-proposed-updates main non-free contrib\n```\n\n```\nsudo apt-get update\n```\n\n\n## pypi 镜像\n\n参考：\n\n阿里镜像：http://mirrors.aliyun.com/help/pypi\n\n官方镜像：https://pypi.python.org/mirrors\n\n~/.pip/pip.conf\n```\n[global]\nindex-url = http://mirrors.aliyun.com/pypi/simple/\n\n[install]\ntrusted-host=mirrors.aliyun.com\n```\n"
  },
  {
    "path": "docker/Dockerfile",
    "content": "FROM python:2.7.13\nMAINTAINER zh \"zhang_he06@163.com\"\n\nRUN echo \"deb http://mirrors.aliyun.com/debian/ jessie main non-free contrib\\n\" > /etc/apt/sources.list \\\n    && echo \"deb http://mirrors.aliyun.com/debian/ jessie-proposed-updates main non-free contrib\\n\" >> /etc/apt/sources.list \\\n    && echo \"deb-src http://mirrors.aliyun.com/debian/ jessie main non-free contrib\\n\" >> /etc/apt/sources.list \\\n    && echo \"deb-src http://mirrors.aliyun.com/debian/ jessie-proposed-updates main non-free contrib\\n\" >> /etc/apt/sources.list \\\n    && mkdir -p ~/.pip/ \\\n    && echo \"[global]\\n\" > ~/.pip/pip.conf \\\n    && echo \"index-url = http://mirrors.aliyun.com/pypi/simple/\\n\\n\" >> ~/.pip/pip.conf \\\n    && echo \"[install]\\n\" >> ~/.pip/pip.conf \\\n    && echo \"trusted-host=mirrors.aliyun.com\\n\" >> ~/.pip/pip.conf\n\nRUN apt-get update && apt-get install -qy --no-install-recommends \\\n    build-essential \\\n    apt-utils \\\n    python-dev \\\n    openssh-server \\\n    libmariadbd-dev \\\n    vim \\\n    ntpdate \\\n    net-tools\n\nADD requirements.txt /requirements.txt\nRUN pip install --no-cache-dir -r /requirements.txt && rm -f /requirements.txt\n\n#RUN pip install --no-cache-dir \\\n#    Flask \\\n#    Flask-Login \\\n#    Flask-Mail \\\n#    Flask-SQLAlchemy \\\n#    Flask-WTF \\\n#    Flask-OAuthlib \\\n#    Flask-Excel \\\n#    Flask-Moment \\\n#    Flask-Uploads \\\n#    Flask-Principal \\\n#    sqlacodegen \\\n#    gunicorn \\\n#    schedule \\\n#    supervisor \\\n#    redis \\\n#    requests \\\n#    celery \\\n#    librabbitmq \\\n#    pika \\\n#    Pillow \\\n#    sshtunnel \\\n#    MySQL-python \\\n#    pymongo\n\n\nEXPOSE 9001 8000 8010\n\nWORKDIR /flask_project\n\n#ENTRYPOINT [\"supervisord\"]\n"
  },
  {
    "path": "docker/README.md",
    "content": "## Docker\n\n### 测试环境\nubuntu-16.04.2-server-amd64\n\n### 安装\n```\n$ curl -sSL https://get.daocloud.io/docker | sh\n```\n\n### 建立 docker 用户组\n建立 docker 组：\n```\n$ sudo groupadd docker\n```\n将当前用户加入 docker 组：\n```\n$ sudo usermod -aG docker $USER\n```\n\n### 加速配置(重启服务)\nhttps://www.daocloud.io/mirror#accelerator-doc\n```\n$ curl -sSL https://get.daocloud.io/daotools/set_mirror.sh | sudo sh -s http://12248bc3.m.daocloud.io\n$ sudo systemctl restart docker.service\n```\n查看加速配置\n```\n$ sudo cat /etc/docker/daemon.json\n{\"registry-mirrors\": [\"http://12248bc3.m.daocloud.io\"]}\n```\n\n### 镜像配置\n\nPython\nhttps://hub.docker.com/_/python/\n```\n$ sudo docker pull python:2.7.13\n```\n\nNginx\nhttps://hub.docker.com/_/nginx/\n```\n$ sudo docker pull nginx:1.13.0\n```\n\nRedis\nhttps://hub.docker.com/_/redis/\n```\n$ sudo docker pull redis:3.0.7\n```\n\nMariaDB\nhttps://hub.docker.com/_/mariadb/\n```\n$ sudo docker pull mariadb:10.1.23\n```\n\nRabbitMQ\nhttps://hub.docker.com/_/rabbitmq/\n```\n$ sudo docker pull rabbitmq:3.6.9\n```\n\nMongoDB\nhttps://hub.docker.com/_/mongo/\n```\n$ sudo docker pull mongo:3.4.4\n```\n\n\n## 查看容器信息\n\n查看容器ip地址\n```\n$ sudo docker inspect --format '{{ .NetworkSettings.IPAddress }}' [容器ID]\n```\n"
  },
  {
    "path": "docker/docker_build.sh",
    "content": "#!/usr/bin/env bash\n\ndocker build \\\n        --rm=true \\\n        -t flask_project \\\n        -f Dockerfile ..\n"
  },
  {
    "path": "docker/docker_login.sh",
    "content": "#!/usr/bin/env bash\n\n\n\nPROJECT_PATH=`(cd ../;pwd)`\nCONFIG_MODE_TEXT=`cat ${PROJECT_PATH}/config/config.env`\n\n# 登录容器\ndocker exec -it flask_project_${CONFIG_MODE_TEXT} bash\n"
  },
  {
    "path": "docker/docker_run.sh",
    "content": "#!/usr/bin/env bash\n\nPROJECT_PATH=`(cd ../;pwd)`\n\n[ -d ${PROJECT_PATH}/logs ] || mkdir ${PROJECT_PATH}/logs\n\nCONFIG_MODE_TEXT=${MODE:-default}\n\n# docker rm $(docker ps -a -q)\n\n# 后台运行\ndocker run \\\n        --name flask_project_${CONFIG_MODE_TEXT} \\\n        -h flask_project_${CONFIG_MODE_TEXT} \\\n        --dns=223.5.5.5 \\\n        --dns=223.6.6.6 \\\n        --privileged \\\n        --cap-add SYS_PTRACE \\\n        --restart=always \\\n        -e TZ=Asia/Shanghai \\\n        -e PYTHONIOENCODING=utf-8 \\\n        -e PYTHONPATH=/flask_project \\\n        -v ${PROJECT_PATH}:/flask_project \\\n        -d \\\n        -p 8000:8000 \\\n        -p 8010:8010 \\\n        -p 9001:9001 \\\n        flask_project \\\n        supervisord -c etc/supervisord.conf\n"
  },
  {
    "path": "docker/mariadb/Dockerfile",
    "content": ""
  },
  {
    "path": "docker/mariadb/README.md",
    "content": "MariaDB\nhttps://hub.docker.com/_/mariadb/\n```\n$ sudo docker pull mariadb:10.1.23\n```\n\n环境变量 | 说明\n--- | ---\nMYSQL_ROOT_PASSWORD | 创建root用户密码\nMYSQL_USER | 创建用户\nMYSQL_PASSWORD | 创建用户密码\n\n\n查看环境变量\n```\n$ sh env.sh\n```\n\n客户端连接\n```\n$ sh cli.sh\n```\n\n建库建表\n```\n$ sh db_init.sh\n```\n\n备份数据\n```\n$ sh db_dump.sh\n```\n"
  },
  {
    "path": "docker/mariadb/cli.sh",
    "content": "#!/usr/bin/env bash\n\ndocker run \\\n    -it \\\n    --link mariadb:mysql \\\n    --rm \\\n    mariadb:10.1.23 \\\n    sh -c 'exec mysql \\\n    -h\"$MYSQL_PORT_3306_TCP_ADDR\" \\\n    -P\"$MYSQL_PORT_3306_TCP_PORT\" \\\n    -uroot \\\n    -p\"$MYSQL_ENV_MYSQL_ROOT_PASSWORD\" \\\n    --default-character-set=utf8 \\\n    \"$MYSQL_ENV_MYSQL_DATABASE\"'\n"
  },
  {
    "path": "docker/mariadb/db_dump.sh",
    "content": "#!/usr/bin/env bash\n\nbackup_file_name=`date '+%Y%m%d%H%M%S'`'.sql'\n\ndocker exec mariadb \\\n    sh -c 'exec mysqldump --all-databases -uroot -p\"$MYSQL_ROOT_PASSWORD\"' > backup/${backup_file_name}\n"
  },
  {
    "path": "docker/mariadb/db_init.sh",
    "content": "#!/usr/bin/env bash\n\ndocker run \\\n    -it \\\n    --link mariadb:mysql \\\n    --rm \\\n    -v ${PWD}/../../db/data/:/db/data/ \\\n    -v ${PWD}/../../db/schema/:/db/schema/ \\\n    mariadb:10.1.23 \\\n    sh -c 'exec mysql \\\n    -h\"$MYSQL_PORT_3306_TCP_ADDR\" \\\n    -P\"$MYSQL_PORT_3306_TCP_PORT\" \\\n    -uroot \\\n    -p\"$MYSQL_ENV_MYSQL_ROOT_PASSWORD\" \\\n    --default-character-set=utf8 \\\n    \"$MYSQL_ENV_MYSQL_DATABASE\" \\\n    -e \"source db/schema/mysql.sql; source db/data/mysql.sql; show databases; show tables;\"'\n"
  },
  {
    "path": "docker/mariadb/docker_run_develop.sh",
    "content": "#!/usr/bin/env bash\n\n[ -d ${PWD}/data ] || mkdir -p ${PWD}/data\n[ -d ${PWD}/backup ] || mkdir -p ${PWD}/backup\n\ndocker run \\\n    -h mariadb \\\n    --name mariadb \\\n    -v ${PWD}/data:/var/lib/mysql \\\n    -v ${PWD}/backup:/backup \\\n    -e MYSQL_ROOT_PASSWORD='123456' \\\n    -e MYSQL_DATABASE='flask_project' \\\n    -e MYSQL_USER='www' \\\n    -e MYSQL_PASSWORD='123456' \\\n    -p 3306:3306 \\\n    -d \\\n    mariadb:10.1.23\n"
  },
  {
    "path": "docker/mariadb/docker_run_product.sh",
    "content": "#!/usr/bin/env bash\n\n[ -d ${PWD}/data ] || mkdir -p ${PWD}/data\n[ -d ${PWD}/backup ] || mkdir -p ${PWD}/backup\n\ndocker run \\\n    -h mariadb \\\n    --name mariadb \\\n    -v ${PWD}/data:/var/lib/mysql \\\n    -v ${PWD}/backup:/backup \\\n    -e MYSQL_ROOT_PASSWORD='2qFG#E!SYxrw' \\\n    -e MYSQL_DATABASE='flask_project' \\\n    -e MYSQL_USER='www' \\\n    -e MYSQL_PASSWORD='@9xJkaU*JWsa' \\\n    -p 3306:3306 \\\n    -d \\\n    mariadb:10.1.23 --log-bin --binlog-format=MIXED\n\n"
  },
  {
    "path": "docker/mariadb/env.sh",
    "content": "#!/usr/bin/env bash\n\ndocker run \\\n    -it \\\n    --link mariadb:mysql \\\n    --rm \\\n    mariadb:10.1.23 \\\n    env\n"
  },
  {
    "path": "docker/mongodb/README.md",
    "content": "MongoDB\nhttps://hub.docker.com/_/mongo/\n```\n$ sudo docker pull mongo:3.4.4\n```\n"
  },
  {
    "path": "docker/mongodb/cli.sh",
    "content": "#!/usr/bin/env bash\n\ndocker run \\\n    -it \\\n    --link mongo:mongo \\\n    --rm \\\n    mongo:3.4.4 \\\n    sh -c 'exec mongo \"$MONGO_PORT_27017_TCP_ADDR:$MONGO_PORT_27017_TCP_PORT/test\"'\n"
  },
  {
    "path": "docker/mongodb/docker_run.sh",
    "content": "#!/usr/bin/env bash\n\ndocker run \\\n        -h mongo \\\n        --name mongo \\\n        -v ${PWD}/data/db:/data/db \\\n        -p 27017:27017 \\\n        -d \\\n        mongo:3.4.4\n"
  },
  {
    "path": "docker/mongodb/env.sh",
    "content": "#!/usr/bin/env bash\n\ndocker run \\\n    -it \\\n    --link mongo:mongo \\\n    --rm \\\n    mongo:3.4.4 \\\n    env\n"
  },
  {
    "path": "docker/nginx/Dockerfile",
    "content": ""
  },
  {
    "path": "docker/nginx/README.md",
    "content": "Nginx\nhttps://hub.docker.com/_/nginx/\n```\n$ sudo docker pull nginx:1.13.0\n```\n\n\nThe :ro option causes these directors to be read only inside the container.\n\n\n证书创建过程：\n\n```\nsh create_ca.sh\nsh create_csr.sh\nsh create_key.sh\nsh create_crt.sh\n```\n"
  },
  {
    "path": "docker/nginx/conf/conf.d/default.conf",
    "content": "server {\n    listen       80;\n    server_name  localhost;\n\n    #charset koi8-r;\n    #access_log  /var/log/nginx/log/host.access.log  main;\n\n    location / {\n        root   /usr/share/nginx/html;\n        index  index.html index.htm;\n    }\n\n    #error_page  404              /404.html;\n\n    # redirect server error pages to the static page /50x.html\n    #\n    error_page   500 502 503 504  /50x.html;\n    location = /50x.html {\n        root   /usr/share/nginx/html;\n    }\n\n    # proxy the PHP scripts to Apache listening on 127.0.0.1:80\n    #\n    #location ~ \\.php$ {\n    #    proxy_pass   http://127.0.0.1;\n    #}\n\n    # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000\n    #\n    #location ~ \\.php$ {\n    #    root           html;\n    #    fastcgi_pass   127.0.0.1:9000;\n    #    fastcgi_index  index.php;\n    #    fastcgi_param  SCRIPT_FILENAME  /scripts$fastcgi_script_name;\n    #    include        fastcgi_params;\n    #}\n\n    # deny access to .htaccess files, if Apache's document root\n    # concurs with nginx's one\n    #\n    #location ~ /\\.ht {\n    #    deny  all;\n    #}\n}"
  },
  {
    "path": "docker/nginx/conf/conf.d/project.conf",
    "content": "server {\n    #侦听80端口\n    listen 80;\n    #定义使用域名访问\n    server_name www.app.com;\n    client_max_body_size 10M;\n\n    #设定访问日志\n    access_log /var/log/nginx/www_access.log main;\n    #设定错误日志\n    error_log /var/log/nginx/www_error.log warn;\n\n    #配置Favicon\n    #location ~ ^/favicon\\.ico$ {\n    #    root /data/static/img/;\n    #}\n\n    #配置robots.txt\n    #location ~ ^/robots\\.txt$ {\n    #    root /data/static/;\n    #}\n\n    #配置静态文件转发\n    #location ~ ^/static/ {\n    #    root /data/;\n    #    #过期30天，静态文件不怎么更新，过期可以设大一点，如果频繁更新，则可以设置得小一点。\n    #    expires 30d;\n    #}\n\n    #默认请求\n    location / {\n        #请求转向本机ip:8000\n        proxy_pass http://192.168.4.1:8000;\n        proxy_redirect off;\n        proxy_set_header Host $host;\n        proxy_set_header X-Real-IP $remote_addr;\n        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;\n    }\n\n}\n\n"
  },
  {
    "path": "docker/nginx/conf/conf.d/project_ssl.conf",
    "content": "server {\n    listen 443;\n    server_name www.app.com;\n    ssl on;\n\n    ssl_certificate /etc/nginx/ssl/server.crt;\n    ssl_certificate_key /etc/nginx/ssl/server.key;\n\n    #设定访问日志\n    access_log /var/log/nginx/www_ssl_access.log main;\n    #设定错误日志\n    error_log /var/log/nginx/www_ssl_error.log warn;\n\n    #默认请求\n    location / {\n        #请求转向本机ip:8000\n        proxy_pass http://192.168.4.1:8000;\n        proxy_redirect off;\n        proxy_set_header Host $host;\n        proxy_set_header X-Real-IP $remote_addr;\n        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;\n    }\n}\n\nserver {\n    #80端口重定向到443\n    listen 80;\n    server_name www.app.com;\n    rewrite ^(.*) https://$server_name$1 permanent;\n}\n"
  },
  {
    "path": "docker/nginx/conf/nginx.conf",
    "content": "user  nginx;\nworker_processes  1;\n\nerror_log  /var/log/nginx/error.log warn;\npid        /var/run/nginx.pid;\n\n\nevents {\n    worker_connections  1024;\n}\n\n\nhttp {\n    include       /etc/nginx/mime.types;\n    default_type  application/octet-stream;\n\n    log_format  main  '$remote_addr - $remote_user [$time_local] \"$request\" '\n                      '$status $body_bytes_sent \"$http_referer\" '\n                      '\"$http_user_agent\" \"$http_x_forwarded_for\"';\n\n    access_log  /var/log/nginx/access.log  main;\n    #access_log syslog:server=192.168.4.1:5149,facility=local7,tag=nginx,severity=info combined;\n\n    sendfile        on;\n    #tcp_nopush     on;\n\n    keepalive_timeout  65;\n\n    #gzip  on;\n\n    include /etc/nginx/conf.d/*.conf;\n}"
  },
  {
    "path": "docker/nginx/conf/ssl/ca.key",
    "content": "-----BEGIN RSA PRIVATE KEY-----\nProc-Type: 4,ENCRYPTED\nDEK-Info: DES-EDE3-CBC,5DB0796EB6C40A40\n\nDPg8VNQ16JkS5Wvsi8glab84jfc2Vq6FWOBJat3WAwKHKcHGKkqX9CYHAuxuh4L3\nmx6UY9sUCmRP4ZtlBrwzKQRWNGn6Rt+R5wodV1tXHyaOnCyPvKUNw6hkXUrE4YKw\nUrNfi7BGxXfaG6uerExEf1CG2cScgpzzvSqL/fvClakWwgTOTLZiDN/80fKFwjU9\niSyN/dHhRYkzERA5/DVPhfG64Z8ZdfChuequ8NyZuz6/03fj8tago3kLkIP5D+fh\nqF7f6adflr1cBFl8IXaaxXQCCHii/+Pyeo9EPVo/zhpMSAWgIyM0Qc+fsMQxvUar\nDBGMRM2rjl0mKQGRas1MVUA8Ri0RDgbv81+p99fesmVEJAf/cLLKY0kKEYPG/Ouz\n6CSF+TR0IOMrckkEkCjzFU7RTDiAziEuFRI50mh0iRTgVzuVUvihdbFknZ9Q7YIH\nS0qLt+dJHvmXHd/KTbMu433ucHJ+L3UFnbaLqCI/lIfdsxLLsoGzSrvA3Y9sAT96\nSoF78/BUGfnvBQuxvusLUoRhLWTLCn6Lu05REeumL8xSQwiXhzztRzS9GH6jsTTP\n9aEjPen9eq3NB/AR79LRiF9mVzZyo+hBHrPQ8CBMBxK3KNErpEPDHEzCxCywF0Lz\n2NsaPK/YDzY7QgNMgfCGMhkk3+LUmS4tbn2oZqnJcCgMSi+NiXCrvahNRChqupet\nmfmteJwcJXGa3xtExBtEiIQyUrQlzq1txRh4/34DHeqtpXEAnLSHasPkcvFo7gNl\ngi1SjUB3oqOpHQYwm+Qpj5efqoA/pPvMtwmp+p1aw7QTiUZ69VJHxA==\n-----END RSA PRIVATE KEY-----\n"
  },
  {
    "path": "docker/nginx/conf/ssl/server.crt",
    "content": "-----BEGIN CERTIFICATE-----\nMIID0DCCAzmgAwIBAgIJAKncSbkopSPpMA0GCSqGSIb3DQEBBQUAMIGmMQswCQYD\nVQQGEwJDTjERMA8GA1UECBMIU2hhbmdoYWkxEDAOBgNVBAcTB0h1YW5nUHUxIzAh\nBgNVBAoTGlNoYW5naGFpIEZsYXNrIFByb2plY3QgTHRkMRswGQYDVQQLExJGbGFz\nayBPcmdhbml6YXRpb24xEjAQBgNVBAMUCSouYXBwLmNvbTEcMBoGCSqGSIb3DQEJ\nARYNYWRtaW5AYXBwLmNvbTAeFw0xNzA1MjQwODMwMjdaFw0xODA1MjQwODMwMjda\nMIGmMQswCQYDVQQGEwJDTjERMA8GA1UECBMIU2hhbmdoYWkxEDAOBgNVBAcTB0h1\nYW5nUHUxIzAhBgNVBAoTGlNoYW5naGFpIEZsYXNrIFByb2plY3QgTHRkMRswGQYD\nVQQLExJGbGFzayBPcmdhbml6YXRpb24xEjAQBgNVBAMUCSouYXBwLmNvbTEcMBoG\nCSqGSIb3DQEJARYNYWRtaW5AYXBwLmNvbTCBnzANBgkqhkiG9w0BAQEFAAOBjQAw\ngYkCgYEAvULL0Br5bxnyeWL4uBPCJtEWI1o4hwLbJG9TBHRmHmaI82b2KBT/KVEH\nErWi1rG29MWsQ5BBF3+VmL8cApnZy2/ELNXG2xMQuKY+2csh7wGNTerA+PjYY4JG\nWgft1Pq0/PfPiNoibI5U/+ERrP8Q9v2b9GvezwSc/NW49C5dBE8CAwEAAaOCAQIw\ngf8wgcUGA1UdIwSBvTCBuqGBrKSBqTCBpjELMAkGA1UEBhMCQ04xETAPBgNVBAgT\nCFNoYW5naGFpMRAwDgYDVQQHEwdIdWFuZ1B1MSMwIQYDVQQKExpTaGFuZ2hhaSBG\nbGFzayBQcm9qZWN0IEx0ZDEbMBkGA1UECxMSRmxhc2sgT3JnYW5pemF0aW9uMRIw\nEAYDVQQDFAkqLmFwcC5jb20xHDAaBgkqhkiG9w0BCQEWDWFkbWluQGFwcC5jb22C\nCQCp3Em5KKUj6TAJBgNVHRMEAjAAMAsGA1UdDwQEAwIE8DAdBgNVHREEFjAUggdh\ncHAuY29tggkqLmFwcC5jb20wDQYJKoZIhvcNAQEFBQADgYEAuqiF9MAnjpimgFva\nX1jOD8gmlJdSxuIHqmEiptKC3cVtZ8vf7RdRjXgZ+/g5vbNpQt3iSVUo0AJ6hsY2\nMAOworfgoGVJ8xSr12y7ha9dm5pc5q8tWh1lT/I4KSsjW/WhQIgAfwBdCEC/z2Ia\n5W+oJstSqXCUPKdBP+nUEXeB4ys=\n-----END CERTIFICATE-----\n"
  },
  {
    "path": "docker/nginx/conf/ssl/server.csr",
    "content": "-----BEGIN CERTIFICATE REQUEST-----\nMIICDjCCAXcCAQAwgaYxCzAJBgNVBAYTAkNOMREwDwYDVQQIEwhTaGFuZ2hhaTEQ\nMA4GA1UEBxMHSHVhbmdQdTEjMCEGA1UEChMaU2hhbmdoYWkgRmxhc2sgUHJvamVj\ndCBMdGQxGzAZBgNVBAsTEkZsYXNrIE9yZ2FuaXphdGlvbjESMBAGA1UEAxQJKi5h\ncHAuY29tMRwwGgYJKoZIhvcNAQkBFg1hZG1pbkBhcHAuY29tMIGfMA0GCSqGSIb3\nDQEBAQUAA4GNADCBiQKBgQC9QsvQGvlvGfJ5Yvi4E8Im0RYjWjiHAtskb1MEdGYe\nZojzZvYoFP8pUQcStaLWsbb0xaxDkEEXf5WYvxwCmdnLb8Qs1cbbExC4pj7ZyyHv\nAY1N6sD4+NhjgkZaB+3U+rT898+I2iJsjlT/4RGs/xD2/Zv0a97PBJz81bj0Ll0E\nTwIDAQABoCcwJQYJKoZIhvcNAQkCMRgTFlNoYW5naGFpIEZsYXNrIEFwcCBMdGQw\nDQYJKoZIhvcNAQEFBQADgYEAheZ1454jN19qnnoSBkge7vpZKmy7j2WyslBg3bdK\nELE12lLgQqy88p94wPAPFCXacAxGQDdlRjITxZOxVZyR1RxZ2hZst7QGDCDsDOGk\npS5QhKBPo2yq4jYq1SVpSNJSHKOsSdsMjVU0/z0ouQeNS6hvJWeF9RTpzQH5d53y\nDbY=\n-----END CERTIFICATE REQUEST-----\n"
  },
  {
    "path": "docker/nginx/conf/ssl/server.key",
    "content": "-----BEGIN RSA PRIVATE KEY-----\nMIICXQIBAAKBgQC9QsvQGvlvGfJ5Yvi4E8Im0RYjWjiHAtskb1MEdGYeZojzZvYo\nFP8pUQcStaLWsbb0xaxDkEEXf5WYvxwCmdnLb8Qs1cbbExC4pj7ZyyHvAY1N6sD4\n+NhjgkZaB+3U+rT898+I2iJsjlT/4RGs/xD2/Zv0a97PBJz81bj0Ll0ETwIDAQAB\nAoGBAJ7l6NZU/1y/DSvK44Uw2Y3bd9nAkrsPs8tYR/vyehZGAe9RX5PxZPVcWTLl\nGs1kMXY6TFIBWBURghjXQv4QC6DjyytvvRNXx7Rv4gSE8biooKSTIr6TUZGxBPRd\nMQ6oP/A/vSe9kTC4giaakXzJ+Lvs/u3iNY2AqaVzhk3tY9bBAkEA+6407fpdk+Ro\nj42ecDH66KvdFntn6vFEcIU/kUD4nUuWWEIYi4DRFqaZtIHRAytF2NYAod15AWgz\ndB+/Ki9mYQJBAMCCVx8QjE6BtdaYkjqPCqy0zrJIc9vkL360tQIgKrj43IkccrWN\nQDZ69Z6jfKn9jQzO8kMrvIlFKcvYq82jCK8CQQC8aHRdNtD41sNju8vBB9lids5C\nd02a9tSaO1YUAgRblGtPVOOVA3EDOOLV21zBt5JJOiMtCWP9pqjmJKHyDZvhAkAt\n0tjKHDZJubZ/DnJAXiw8UA2jgnuRrA9iKcGsb9u7jAFy4cKsVKMkVMCCsofKLwCU\nO+6O7qpCQqRgUYMTv+shAkB2dE17xHXmTNUF0zRw/QZ7CdntmHEwAQ3fLOOiut/r\noLBJA2eV4edo2Vep5WOnt1VF3sydq6bkRQcVgtI61uUf\n-----END RSA PRIVATE KEY-----\n"
  },
  {
    "path": "docker/nginx/conf/ssl/v3.ext",
    "content": "authorityKeyIdentifier=keyid,issuer\nbasicConstraints=CA:FALSE\nkeyUsage = digitalSignature, nonRepudiation, keyEncipherment, dataEncipherment\nsubjectAltName = @alt_names\n\n[alt_names]\nDNS.1 = app.com\nDNS.2 = *.app.com\n"
  },
  {
    "path": "docker/nginx/create_ca.sh",
    "content": "#!/usr/bin/env bash\n\nopenssl genrsa -des3 -out conf/ssl/ca.key 1024\n"
  },
  {
    "path": "docker/nginx/create_crt.sh",
    "content": "#!/usr/bin/env bash\n\nopenssl x509 -req -days 365 -in conf/ssl/server.csr -signkey conf/ssl/server.key -extfile conf/ssl/v3.ext -out conf/ssl/server.crt\n"
  },
  {
    "path": "docker/nginx/create_csr.sh",
    "content": "#!/usr/bin/env bash\n\nopenssl req -new -key conf/ssl/ca.key -out conf/ssl/server.csr\n"
  },
  {
    "path": "docker/nginx/create_key.sh",
    "content": "#!/usr/bin/env bash\n\nopenssl rsa -in conf/ssl/ca.key -out conf/ssl/server.key\n"
  },
  {
    "path": "docker/nginx/docker_run.sh",
    "content": "#!/usr/bin/env bash\n\ndocker run \\\n    -h nginx \\\n    --name nginx \\\n    -v ${PWD}/conf/nginx.conf:/etc/nginx/nginx.conf:ro \\\n    -v ${PWD}/conf/ssl:/etc/nginx/ssl:ro \\\n    -v ${PWD}/conf/conf.d:/etc/nginx/conf.d:ro \\\n    -v ${PWD}/log:/var/log/nginx \\\n    -p 80:80 \\\n    -p 443:443 \\\n    -d \\\n    nginx:1.13.0\n"
  },
  {
    "path": "docker/rabbitmq/README.md",
    "content": "RabbitMQ\nhttps://hub.docker.com/_/rabbitmq/\n```\n$ sudo docker pull rabbitmq:3.6.9\n```\n\n\nrabbitmq/docker_run_management.sh\n在\nrabbitmq/docker_run.sh\n的基础上，启用了管理插件\n"
  },
  {
    "path": "docker/rabbitmq/docker_run.sh",
    "content": "#!/usr/bin/env bash\n\ndocker run \\\n        -h rabbitmq \\\n        --name rabbitmq \\\n        -v ${PWD}/data:/var/lib/rabbitmq \\\n        -p 4369:4369 \\\n        -p 5671:5671 \\\n        -p 5672:5672 \\\n        -p 25672:25672 \\\n        -d \\\n        rabbitmq:3.6.9\n"
  },
  {
    "path": "docker/rabbitmq/docker_run_management.sh",
    "content": "#!/usr/bin/env bash\n\ndocker run \\\n        -h rabbitmq \\\n        --name rabbitmq \\\n        -v ${PWD}/data:/var/lib/rabbitmq \\\n        -p 4369:4369 \\\n        -p 5671:5671 \\\n        -p 5672:5672 \\\n        -p 25672:25672 \\\n        -p 15671:15671 \\\n        -p 15672:15672 \\\n        -d \\\n        rabbitmq:3.6.9-management\n"
  },
  {
    "path": "docker/redis/Dockerfile",
    "content": ""
  },
  {
    "path": "docker/redis/README.md",
    "content": "Redis\nhttps://hub.docker.com/_/redis/\n```\n$ sudo docker pull redis:3.2.8\n```\n\n--protected-mode no\n\n"
  },
  {
    "path": "docker/redis/cli.sh",
    "content": "#!/usr/bin/env bash\n\ndocker run \\\n    -it \\\n    --link redis:redis \\\n    --rm \\\n    redis:3.2.8 \\\n    redis-cli -h redis -p 6379\n"
  },
  {
    "path": "docker/redis/docker_run_aof.sh",
    "content": "#!/usr/bin/env bash\n\n[ -d ${PWD}/data ] || mkdir -p ${PWD}/data\n\ndocker run \\\n    -h redis \\\n    --name redis \\\n    -v ${PWD}/data:/data \\\n    -p 6379:6379 \\\n    -d \\\n    redis:3.2.8 \\\n    redis-server --appendonly yes\n"
  },
  {
    "path": "docker/redis/docker_run_rdb.sh",
    "content": "#!/usr/bin/env bash\n\n[ -d ${PWD}/data ] || mkdir -p ${PWD}/data\n\ndocker run \\\n    -h redis \\\n    --name redis \\\n    -v ${PWD}/data:/data \\\n    -p 6379:6379 \\\n    -d \\\n    redis:3.2.8 \\\n    redis-server\n"
  },
  {
    "path": "docker/requirements.txt",
    "content": "amqp==2.1.1\nappdirs==1.4.3\nasn1crypto==0.22.0\nBabel==2.3.4\nbackports.ssl-match-hostname==3.5.0.1\nbilliard==3.5.0.2\nblinker==1.4\ncelery==4.0.0\ncertifi==2016.9.26\ncffi==1.10.0\nclick==6.6\ncryptography==1.8.1\nenum34==1.1.6\nFlask==0.11.1\nFlask-Excel==0.0.5\nFlask-Login==0.3.2\nFlask-Mail==0.9.1\nFlask-Moment==0.5.1\nFlask-OAuthlib==0.9.3\nFlask-Principal==0.4.0\nFlask-SQLAlchemy==2.1\nFlask-WTF==0.13.1\nflower==0.9.1\nfluent-logger==0.5.0\nfutures==3.0.5\ngunicorn==19.6.0\nidna==2.5\ninflect==0.2.5\nipaddress==1.0.18\nitsdangerous==0.24\nJinja2==2.8\nkombu==4.0.0\nMarkupSafe==0.23\nmeld3==1.0.2\nmsgpack-python==0.4.8\nMySQL-python==1.2.5\noauthlib==2.0.0\nolefile==0.44\npackaging==16.8\nparamiko==2.1.2\npika==0.10.0\nPillow==4.1.0\npyasn1==0.2.3\npycparser==2.17\npyexcel==0.4.5\npyexcel-io==0.3.3\npyexcel-webio==0.0.11\npymongo==3.4.0\npyparsing==2.2.0\npytz==2016.7\nqiniu==7.0.9.1\nredis==2.10.5\nrequests==2.11.1\nrequests-oauthlib==0.7.0\nschedule==0.4.2\nsix==1.10.0\nsqlacodegen==1.1.6\nSQLAlchemy==1.1.2\nsshtunnel==0.1.2\nsupervisor==3.3.1\ntexttable==0.8.8\ntornado==4.2\nvine==1.1.3\nvirtualenv==15.1.0\nWerkzeug==0.11.11\nWTForms==2.1\n"
  },
  {
    "path": "docker-compose.yml",
    "content": "\nversion: '3'\nservices:\n  web:\n    build: .\n    depends_on:\n      - nginx\n      - redis\n      - mariadb\n      - rabbitmq\n      - mongo\n  nginx:\n    image: nginx:1.13.0\n  redis:\n    image: redis:3.0.7\n  mariadb:\n    image: mariadb:10.1.23\n  rabbitmq:\n    image: rabbitmq:3.6.9\n  mongo:\n    image: mongo:3.0.14\n"
  },
  {
    "path": "env_develop.sh",
    "content": "#!/usr/bin/env bash\n\nsource flask.env/bin/activate\n\nexport PYTHONIOENCODING=utf-8\nexport MODE=develop\n"
  },
  {
    "path": "env_product.sh",
    "content": "#!/usr/bin/env bash\n\nsource flask.env/bin/activate\n\nexport PYTHONIOENCODING=utf-8\nexport MODE=product\n"
  },
  {
    "path": "etc/app_backend.ini",
    "content": ";后端web\n[program:app_backend]\ncommand=gunicorn -w 4 -b 0.0.0.0:8010 app_backend:app\nstartsecs=0\nstopwaitsecs=0\nautostart=false\nautorestart=true\nstdout_logfile=logs/app_backend_out.log\nstderr_logfile=logs/app_backend_err.log\n"
  },
  {
    "path": "etc/app_frontend.ini",
    "content": ";前端web\n[program:app_frontend]\ncommand=gunicorn -w 4 -b 0.0.0.0:8000 app_frontend:app\nstartsecs=0\nstopwaitsecs=0\nautostart=false\nautorestart=true\nstdout_logfile=logs/app_frontend_out.log\nstderr_logfile=logs/app_frontend_err.log\n"
  },
  {
    "path": "etc/app_wechat.ini",
    "content": ";微信\n[program:app_wechat]\ncommand=gunicorn -w 4 -b 0.0.0.0:8020 app_wechat:app\nstartsecs=0\nstopwaitsecs=0\nautostart=false\nautorestart=true\nstdout_logfile=logs/app_wechat_out.log\nstderr_logfile=logs/app_wechat_err.log\n"
  },
  {
    "path": "etc/cron_send_sms.ini",
    "content": ";短信调度\n[program:cron_send_sms]\ncommand=python app_frontend/tasks/cron_send_sms.py ssh_tunnel\nstartsecs=0\nstopwaitsecs=0\nautostart=false\nautorestart=true\nstdout_logfile=logs/sms_out.log\nstderr_logfile=logs/sms_err.log\n"
  },
  {
    "path": "etc/nginx.conf",
    "content": "server {\n    #侦听80端口\n    listen 80;\n    #定义使用域名访问\n    server_name www.flask-app.com;\n    client_max_body_size 10M;\n\n    #设定访问日志\n    access_log /home/zhanghe/code/flask_project/logs/nginx_access.log main;\n    #设定错误日志\n    error_log /home/zhanghe/code/flask_project/logs/nginx_error.log warn;\n\n    #配置Favicon\n    #location ~ ^/favicon\\.ico$ {\n    #    root /data/static/img/;\n    #}\n\n    #配置robots.txt\n    #location ~ ^/robots\\.txt$ {\n    #    root /data/static/;\n    #}\n\n    #配置静态文件转发\n    #location ~ ^/static/ {\n    #    root /data/;\n    #    #过期30天，静态文件不怎么更新，过期可以设大一点，如果频繁更新，则可以设置得小一点。\n    #    expires 30d;\n    #}\n\n    #默认请求\n    location / {\n        #请求转向本机ip:8000\n        proxy_pass http://127.0.0.1:8000;\n        proxy_redirect off;\n        proxy_set_header Host $host;\n        proxy_set_header X-Real-IP $remote_addr;\n        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;\n    }\n\n}\n\n# $ sudo ln -s `pwd`/etc/nginx.conf /etc/nginx/conf.d/flask_app_nginx.conf\n# $ sudo nginx -s reload  # 平滑重启\n"
  },
  {
    "path": "etc/nginx_ssl.conf",
    "content": "server {\n    listen 443;\n    server_name www.flask-app.com;\n    ssl on;\n\n    #root  /home/zhanghe/code/flask_project;\n\n    ssl_certificate /home/zhanghe/code/flask_project/ssl/server.crt;\n    ssl_certificate_key /home/zhanghe/code/flask_project/ssl/server.key;\n\n    #设定访问日志\n    access_log /home/zhanghe/code/flask_project/logs/nginx_access.log main;\n    #设定错误日志\n    error_log /home/zhanghe/code/flask_project/logs/nginx_error.log warn;\n\n    #默认请求\n    location / {\n        #请求转向本机ip:8000\n        proxy_pass http://127.0.0.1:8000;\n        proxy_redirect off;\n        proxy_set_header Host $host;\n        proxy_set_header X-Real-IP $remote_addr;\n        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;\n    }\n}\n\nserver {\n    #80端口重定向到443\n    listen 80;\n    server_name www.flask-app.com;\n    rewrite ^(.*) https://$server_name$1 permanent;\n}\n\n# $ sudo ln -s `pwd`/etc/nginx_ssl.conf /etc/nginx/conf.d/flask_app_nginx.conf\n# $ sudo nginx -s reload  # 平滑重启\n"
  },
  {
    "path": "etc/supervisord.conf",
    "content": "; Sample supervisor config file.\n;\n; For more information on the config file, please see:\n; http://supervisord.org/configuration.html\n;\n; Notes:\n;  - Shell expansion (\"~\" or \"$HOME\") is not supported.  Environment\n;    variables can be expanded using this syntax: \"%(ENV_HOME)s\".\n;  - Comments must have a leading space: \"a=b ;comment\" not \"a=b;comment\".\n\n;[unix_http_server]\n;file=/tmp/supervisor.sock   ; (the path to the socket file)\n;chmod=0700                 ; socket file mode (default 0700)\n;chown=nobody:nogroup       ; socket file uid:gid owner\n;username=user              ; (default is no username (open server))\n;password=123               ; (default is no password (open server))\n\n[inet_http_server]         ; inet (TCP) server disabled by default\nport=127.0.0.1:9001        ; (ip_address:port specifier, *:port for all iface)\nusername=admin             ; (default is no username (open server))\npassword=123456            ; (default is no password (open server))\n\n[supervisord]\nlogfile=/tmp/supervisord.log ; (main log file;default $CWD/supervisord.log)\nlogfile_maxbytes=50MB        ; (max main logfile bytes b4 rotation;default 50MB)\nlogfile_backups=10           ; (num of main logfile rotation backups;default 10)\nloglevel=info                ; (log level;default info; others: debug,warn,trace)\npidfile=/tmp/supervisord.pid ; (supervisord pidfile;default supervisord.pid)\nnodaemon=true                ; (start in foreground if true;default false)\nminfds=1024                  ; (min. avail startup file descriptors;default 1024)\nminprocs=200                 ; (min. avail process descriptors;default 200)\n;umask=022                   ; (process file creation umask;default 022)\n;user=chrism                 ; (default is current user, required if root)\n;identifier=supervisor       ; (supervisord identifier, default is 'supervisor')\n;directory=/tmp              ; (default is not to cd during start)\n;nocleanup=true              ; (don't clean up tempfiles at start;default false)\n;childlogdir=/tmp            ; ('AUTO' child log dir, default $TEMP)\n;environment=KEY=\"value\"     ; (key value pairs to add to environment)\n;strip_ansi=false            ; (strip ansi escape codes in logs; def. false)\n\n; the below section must remain in the config file for RPC\n; (supervisorctl/web interface) to work, additional interfaces may be\n; added by defining them in separate rpcinterface: sections\n[rpcinterface:supervisor]\nsupervisor.rpcinterface_factory = supervisor.rpcinterface:make_main_rpcinterface\n\n[supervisorctl]\n;serverurl=unix:///tmp/supervisor.sock ; use a unix:// URL  for a unix socket\nserverurl=http://127.0.0.1:9001 ; use an http:// url to specify an inet socket\nusername=admin               ; should be same as http_username if set\npassword=123456              ; should be same as http_password if set\n;prompt=mysupervisor         ; cmd line prompt (default \"supervisor\")\n;history_file=~/.sc_history  ; use readline history if available\n\n; The below sample program section shows all possible program subsection values,\n; create one or more 'real' program: sections to be able to control them under\n; supervisor.\n\n;[program:theprogramname]\n;command=/bin/cat              ; the program (relative uses PATH, can take args)\n;process_name=%(program_name)s ; process_name expr (default %(program_name)s)\n;numprocs=1                    ; number of processes copies to start (def 1)\n;directory=/tmp                ; directory to cwd to before exec (def no cwd)\n;umask=022                     ; umask for process (default None)\n;priority=999                  ; the relative start priority (default 999)\n;autostart=true                ; start at supervisord start (default: true)\n;startsecs=1                   ; # of secs prog must stay up to be running (def. 1)\n;startretries=3                ; max # of serial start failures when starting (default 3)\n;autorestart=unexpected        ; when to restart if exited after running (def: unexpected)\n;exitcodes=0,2                 ; 'expected' exit codes used with autorestart (default 0,2)\n;stopsignal=QUIT               ; signal used to kill process (default TERM)\n;stopwaitsecs=10               ; max num secs to wait b4 SIGKILL (default 10)\n;stopasgroup=false             ; send stop signal to the UNIX process group (default false)\n;killasgroup=false             ; SIGKILL the UNIX process group (def false)\n;user=chrism                   ; setuid to this UNIX account to run the program\n;redirect_stderr=true          ; redirect proc stderr to stdout (default false)\n;stdout_logfile=/a/path        ; stdout log path, NONE for none; default AUTO\n;stdout_logfile_maxbytes=1MB   ; max # logfile bytes b4 rotation (default 50MB)\n;stdout_logfile_backups=10     ; # of stdout logfile backups (default 10)\n;stdout_capture_maxbytes=1MB   ; number of bytes in 'capturemode' (default 0)\n;stdout_events_enabled=false   ; emit events on stdout writes (default false)\n;stderr_logfile=/a/path        ; stderr log path, NONE for none; default AUTO\n;stderr_logfile_maxbytes=1MB   ; max # logfile bytes b4 rotation (default 50MB)\n;stderr_logfile_backups=10     ; # of stderr logfile backups (default 10)\n;stderr_capture_maxbytes=1MB   ; number of bytes in 'capturemode' (default 0)\n;stderr_events_enabled=false   ; emit events on stderr writes (default false)\n;environment=A=\"1\",B=\"2\"       ; process environment additions (def no adds)\n;serverurl=AUTO                ; override serverurl computation (childutils)\n\n; The below sample eventlistener section shows all possible\n; eventlistener subsection values, create one or more 'real'\n; eventlistener: sections to be able to handle event notifications\n; sent by supervisor.\n\n;[eventlistener:theeventlistenername]\n;command=/bin/eventlistener    ; the program (relative uses PATH, can take args)\n;process_name=%(program_name)s ; process_name expr (default %(program_name)s)\n;numprocs=1                    ; number of processes copies to start (def 1)\n;events=EVENT                  ; event notif. types to subscribe to (req'd)\n;buffer_size=10                ; event buffer queue size (default 10)\n;directory=/tmp                ; directory to cwd to before exec (def no cwd)\n;umask=022                     ; umask for process (default None)\n;priority=-1                   ; the relative start priority (default -1)\n;autostart=true                ; start at supervisord start (default: true)\n;startsecs=1                   ; # of secs prog must stay up to be running (def. 1)\n;startretries=3                ; max # of serial start failures when starting (default 3)\n;autorestart=unexpected        ; autorestart if exited after running (def: unexpected)\n;exitcodes=0,2                 ; 'expected' exit codes used with autorestart (default 0,2)\n;stopsignal=QUIT               ; signal used to kill process (default TERM)\n;stopwaitsecs=10               ; max num secs to wait b4 SIGKILL (default 10)\n;stopasgroup=false             ; send stop signal to the UNIX process group (default false)\n;killasgroup=false             ; SIGKILL the UNIX process group (def false)\n;user=chrism                   ; setuid to this UNIX account to run the program\n;redirect_stderr=false         ; redirect_stderr=true is not allowed for eventlisteners\n;stdout_logfile=/a/path        ; stdout log path, NONE for none; default AUTO\n;stdout_logfile_maxbytes=1MB   ; max # logfile bytes b4 rotation (default 50MB)\n;stdout_logfile_backups=10     ; # of stdout logfile backups (default 10)\n;stdout_events_enabled=false   ; emit events on stdout writes (default false)\n;stderr_logfile=/a/path        ; stderr log path, NONE for none; default AUTO\n;stderr_logfile_maxbytes=1MB   ; max # logfile bytes b4 rotation (default 50MB)\n;stderr_logfile_backups=10     ; # of stderr logfile backups (default 10)\n;stderr_events_enabled=false   ; emit events on stderr writes (default false)\n;environment=A=\"1\",B=\"2\"       ; process environment additions\n;serverurl=AUTO                ; override serverurl computation (childutils)\n\n; The below sample group section shows all possible group values,\n; create one or more 'real' group: sections to create \"heterogeneous\"\n; process groups.\n\n;[group:thegroupname]\n;programs=progname1,progname2  ; each refers to 'x' in [program:x] definitions\n;priority=999                  ; the relative start priority (default 999)\n\n; The [include] section can just contain the \"files\" setting.  This\n; setting can list multiple files (separated by whitespace or\n; newlines).  It can also contain wildcards.  The filenames are\n; interpreted as relative to this file.  Included files *cannot*\n; include files themselves.\n\n;[include]\n;files = relative/directory/*.ini\n\n;前端web\n[program:app_frontend]\ncommand=gunicorn -w 8 -b 0.0.0.0:8000 app_frontend:app\nstartsecs=0\nstopwaitsecs=0\nautostart=false\nautorestart=true\nstdout_logfile=logs/app_frontend_out.log\nstderr_logfile=logs/app_frontend_err.log\n\n\n;后端web\n[program:app_backend]\ncommand=gunicorn -w 8 -b 0.0.0.0:8010 app_backend:app\nstartsecs=0\nstopwaitsecs=0\nautostart=false\nautorestart=true\nstdout_logfile=logs/app_backend_out.log\nstderr_logfile=logs/app_backend_err.log\n\n[include]\nfiles = task_lock.ini task_sms.ini\n"
  },
  {
    "path": "etc/task_lock.ini",
    "content": "[group:lock]\nprograms=reg_not_active,active_not_put,order_not_pay,pay_not_rec\n\n;注册未激活\n[program:reg_not_active]\ncommand=python app_frontend/tasks/run_lock_reg_not_active.py\nstartsecs=0\nstopwaitsecs=0\nautostart=false\nautorestart=true\nstdout_logfile=logs/lock_reg_not_active_out.log\nstderr_logfile=logs/lock_reg_not_active_err.log\n\n;激活未投资\n[program:active_not_put]\ncommand=python app_frontend/tasks/run_lock_active_not_put.py\nstartsecs=0\nstopwaitsecs=0\nautostart=false\nautorestart=true\nstdout_logfile=logs/lock_active_not_put_out.log\nstderr_logfile=logs/lock_active_not_put_err.log\n\n;订单未支付\n[program:order_not_pay]\ncommand=python app_frontend/tasks/run_lock_order_not_pay.py\nstartsecs=0\nstopwaitsecs=0\nautostart=false\nautorestart=true\nstdout_logfile=logs/lock_order_not_pay_out.log\nstderr_logfile=logs/lock_order_not_pay_err.log\n\n;收款未确认\n[program:pay_not_rec]\ncommand=python app_frontend/tasks/run_lock_pay_not_rec.py\nstartsecs=0\nstopwaitsecs=0\nautostart=false\nautorestart=true\nstdout_logfile=logs/lock_pay_not_rec_out.log\nstderr_logfile=logs/lock_pay_not_rec_err.log\n"
  },
  {
    "path": "etc/task_sms.ini",
    "content": "[group:sms]\nprograms=send_sms,send_sms_priority\n\n;短信发送\n[program:send_sms]\ncommand=python app_frontend/tasks/run_send_sms.py\nstartsecs=0\nstopwaitsecs=0\nautostart=false\nautorestart=true\nstdout_logfile=logs/send_sms_out.log\nstderr_logfile=logs/send_sms_err.log\n\n;短信发送-优先\n[program:send_sms_priority]\ncommand=python app_frontend/tasks/run_send_sms_priority.py\nstartsecs=0\nstopwaitsecs=0\nautostart=false\nautorestart=true\nstdout_logfile=logs/send_sms_priority_out.log\nstderr_logfile=logs/send_sms_priority_err.log\n"
  },
  {
    "path": "gen.py",
    "content": "#!/usr/bin/env python\n# encoding: utf-8\n\n\"\"\"\n@author: zhanghe\n@software: PyCharm\n@file: gen.py\n@time: 16-6-19 下午7:07\n\"\"\"\n\n\nimport os\nimport sys\nfrom config import BASE_DIR, SQLALCHEMY_DATABASE_URI\nprint SQLALCHEMY_DATABASE_URI\n\n\ndef create_models(app_name='app_frontend'):\n    \"\"\"\n    创建 model\n    $ python gen.py gen_models\n    \"\"\"\n    file_path = os.path.join(BASE_DIR, '%s/models.py' % app_name)\n    print file_path\n    cmd = 'sqlacodegen %s --noinflect --outfile %s' % (SQLALCHEMY_DATABASE_URI, file_path)\n\n    output = os.popen(cmd)\n    result = output.read()\n    print result\n\n    # 更新 model 文件\n    with open(file_path, 'r') as f:\n        lines = f.readlines()\n\n    with open(file_path, 'w') as f:\n        # 替换 model 关键内容\n        lines[2] = 'from database import db\\n'\n        lines[5] = 'Base = db.Model\\n'\n        # 新增 model 转 dict 方法\n\n        lines.insert(9, 'def to_dict(self):\\n')\n        lines.insert(10, '    \"\"\"\\n')\n        lines.insert(11, '    model 对象转 字典\\n')\n        lines.insert(12, '    model_obj.to_dict()\\n')\n        lines.insert(13, '    \"\"\"\\n')\n        lines.insert(14, '    return {c.name: getattr(self, c.name, None) for c in self.__table__.columns}\\n')\n        lines.insert(15, '\\n')\n        lines.insert(16, 'Base.to_dict = to_dict\\n')\n        lines.insert(17, '\\n\\n')\n        f.write(''.join(lines))\n\n\ndef run():\n    \"\"\"\n    入口\n    \"\"\"\n    # print sys.argv\n    try:\n        if len(sys.argv) > 2:\n            fun_name = eval(sys.argv[1])\n            fun_name(sys.argv[2])\n        else:\n            print '缺失参数\\n'\n            usage()\n    except NameError, e:\n        print e\n        print '未定义的方法[%s]' % sys.argv[1]\n\n\ndef usage():\n    \"\"\"\n    使用说明\n    \"\"\"\n    print \"\"\"\n创建(更新)model\n$ python gen.py create_models app_frontend\n$ python gen.py create_models app_backend\n\"\"\"\n\n\nif __name__ == '__main__':\n    run()\n"
  },
  {
    "path": "project/doc.md",
    "content": "## 项目简介\n\n### 业务关系\n\n申请单 1:n 票据单（付款、收款） 1:1 订单\n\n\n表：user_auth\n设置联合唯一：UNIQUE (`auth_type`, `auth_key`)\n被锁定，被删除的用户不能再用此账号重复注册。\n\n\n账号绑定\n```\n会员主账号\n绑定第三方\n一个主账号只能绑定一种类型的一个三方账号\n一种类型的一个三方账号也只能绑定一个主账号\n```\n\n\n会员层级（membership）\nMongoDB 单个文档有16M的限制，内嵌不要太多，可以用引用替代\n如下，仅仅保留父节点id即可\n```\n{\n    \"user_id\": \"\",\n    \"user_pid\": \"\",\n}\n```\n\n会员登录日志（login_log_member）\n```\n{\n    \"user_id\": \"\",\n    \"time\": \"\",\n    \"ip\": \"\",\n}\n```\n\n后台登录日志（login_log_admin）\n```\n{\n    \"user_id\": \"\",\n    \"time\": \"\",\n    \"ip\": \"\",\n}\n```\n\n后台操作日志（operation_log_admin）\n```\n{\n    \"admin_id\": \"\",\n    \"op_type\": \"\",\n    \"op_content\": \"\",\n    \"time\": \"\",\n    \"ip\": \"\",\n}\n```\n\n### 用户中心\n\n用户等级\n统计条（钱包，积分）\n快捷入口\n图片上传\n邀请\n激活\n\n### 用户订单\n\n列表进入详细页面\n订单详细页面内容：\n订单信息（创建时间，金额）\n对方银行信息（收款、付款）\n\n\n### 系统配置\n\n\n### 新增单据\n\n\n## 利息配置\n\n申请类型钱包余额变化    申请成功    生成订单    订单支付    订单确认\n\n投资申请钱包余额变化    余额不变    余额不变    奖励利息    余额不变    15天后本息进入钱包（扣除锁定金额） （上一级，上两级，上三级）推广利息\n提现申请钱包余额变化    余额减少    余额不变    余额不变    奖励利息\n\n\n投资申请：推送延时队列，15天后如果订单确认成功，本息进入钱包，\napply_interest_on_principal\n{'user_id': 0, 'apply_put_id': 0, 'apply_time': ''}\n\n\n订单支付：\n\n\n订单确认逻辑：\n判断是否满足奖励规则：奖励\n判断是否满足惩罚规则：惩罚\n执行确认\n投资方计算上级推广利息（三级）\n\n\n\n打款，确认 产生的 收益变化，积分变化\n\n\n留言，投诉\n\n时间配置，修改了没有小效果，队列创建的时候就定死了\n\n\n实名认证接口\nhttp://www.apistore.cn/data/?k=%E5%AE%9E%E5%90%8D\n\n\n\n===========\n2h\n1、2\n推广 领导\n静态，动态 两个钱包提现\n\n1.\t银绸资格：[一级达5人以上] 可享一级团队5% Dr.梦想值奖励；\n2.\t金绸资格：[一级达20人以上] 可享一、二级团队5% Dr.梦想值奖励；\n\n\n===========\n4h\n匹配后超过36小时不打款\n\n连带责任，追加2级（额度，动态收益 提现总额80% 为追责额度）\n\n判断订单类型，流转订单，未付款，自动拆分（优先级加高，待实现）\n\n\n===========\n8000 12000\n\n一级，二级 动态收益 提现总额\n1、20000 == 20000 匹配单 关系拆开\n2、8000 8000 4000 一级 二级 散户 投资\n流转单未付款，重新给散户匹配\n\n\n===========\n1h\n短信提醒（到期前一小时，提醒两级）\n\nrun_notice_pay\n\nuid, order_time\n您团队成员（SAA）订单即将超时，请及时敦促，以免造成追责。\n\n\n===========\n2h\n下一级单个用户 排单 60000 以内，需要3% 的奖励，\n\n用户单独设置3级的奖励比例，\n\n奖金 20% 进入积分钱包（慈善3 数字7 积分10）\n\n\n\n静态钱包 可以扣成负数\n\n积分互转（当成交易货币）\n\n\n\n===========\n2h\n排单币（每次排单消耗）\n100比1  （2000 == 20个币）\n只能从上往下转（支持多级，转币，判断是否是被转用户上两级），不能同级转\n\n\n===========\n匹配需要自动\n随机选取3-12天，排单量的10% 进行自动匹配\n待审核状态，人工确认批量审核，（后续新增删除，重新匹配）\n"
  },
  {
    "path": "project/run_develop.md",
    "content": "## 项目配置步骤[开发环境]\n\n设置环境变量\n```\necho develop > config/config.env\n```\n\n开启 mariadb 服务\n```\ncd docker/mariadb\n\nsh docker_run_develop.sh\n\n# 建立数据库 导入测试数据(注意需要等待以上步骤数据库完全建好)\nsh db_init.sh\n```\n\n开启 redis 服务\n```\ncd docker/redis\n\nsh docker_run_rdb.sh\n```\n\n开启 rabbitmq 服务\n```\ncd docker/rabbitmq\n\nsh docker_run.sh\n```\n\n启动项目\n```\ncd docker\n\nsh docker_run.sh\n```\n\n\n## 每次更新表结构，需要更新 models\n```\npython gen.py create_models app_frontend\npython gen.py create_models app_backend\n```\n"
  },
  {
    "path": "project/run_product.md",
    "content": "## 项目配置步骤[生产环境]\n\n设置环境变量\n```\necho product > config/config.env\n```\n\n开启 mariadb 服务\n```\ncd docker/mariadb\n\nsh docker_run_product.sh\n\n# 建立数据库 导入测试数据(注意需要等待以上步骤数据库完全建好)\nsh db_init.sh\n```\n\n开启 redis 服务\n```\ncd docker/redis\n\nsh docker_run_aof.sh\n```\n\n开启 rabbitmq 服务\n```\ncd docker/rabbitmq\n\nsh docker_run.sh\n```\n\n启动项目\n```\ncd docker\n\nsh docker_run.sh\n```\n\n\n## 每次更新表结构，需要更新 models\n```\npython gen.py create_models app_frontend\npython gen.py create_models app_backend\n```\n"
  },
  {
    "path": "requirements.txt",
    "content": "amqp==2.1.1\nasn1crypto==0.22.0\nBabel==2.3.4\nbackports.ssl-match-hostname==3.5.0.1\nbilliard==3.5.0.2\nblinker==1.4\ncelery==4.0.0\ncertifi==2016.9.26\ncffi==1.10.0\nclick==6.6\ncryptography==1.8.1\nenum34==1.1.6\nFlask==0.11.1\nFlask-Excel==0.0.5\nFlask-Login==0.3.2\nFlask-Mail==0.9.1\nFlask-Moment==0.5.1\nFlask-OAuthlib==0.9.3\nFlask-Principal==0.4.0\nFlask-SQLAlchemy==2.1\nFlask-WTF==0.13.1\nflower==0.9.1\nfutures==3.0.5\ngunicorn==19.6.0\nidna==2.5\ninflect==0.2.5\nipaddress==1.0.18\nitsdangerous==0.24\nJinja2==2.8\nkombu==4.0.0\nMarkupSafe==0.23\nmeld3==1.0.2\nMySQL-python==1.2.5\noauthlib==2.0.0\nolefile==0.44\npackaging==16.8\nparamiko==2.1.2\npika==0.10.0\nPillow==4.1.0\npyasn1==0.2.3\npycparser==2.17\npyexcel==0.4.5\npyexcel-io==0.3.3\npyexcel-webio==0.0.11\npymongo==3.4.0\npyparsing==2.2.0\npytz==2016.7\nqiniu==7.0.9.1\nredis==2.10.5\nrequests==2.11.1\nrequests-oauthlib==0.7.0\nschedule==0.4.2\nsix==1.10.0\nsqlacodegen==1.1.6\nSQLAlchemy==1.1.2\nsshtunnel==0.1.2\nsupervisor==3.3.1\ntexttable==0.8.8\ntornado==4.2\nvine==1.1.3\nWerkzeug==0.11.11\nWTForms==2.1\n"
  },
  {
    "path": "run_backend.py",
    "content": "#!/usr/bin/env python\n# encoding: utf-8\n\n\"\"\"\n@author: zhanghe\n@software: PyCharm\n@file: run.py\n@time: 16-1-7 上午12:12\n\"\"\"\n\n\nfrom app_backend import app\n\nimport signal\nimport os\n\n\ndef handle_pdb(sig, frame):\n    from remote_pdb import RemotePdb\n    print sig, frame\n    RemotePdb('0.0.0.0', 48110).set_trace()\n\nsignal.signal(signal.SIGUSR1, handle_pdb)\nprint('pid:%s' % os.getpid())\n\n\nif __name__ == '__main__':\n    app.debug = app.config['DEBUG']  # 调试模式, DEBUG = True\n    app.run(host='0.0.0.0', port=8010)  # 端口号必须为整型\n"
  },
  {
    "path": "run_frontend.py",
    "content": "#!/usr/bin/env python\n# encoding: utf-8\n\n\"\"\"\n@author: zhanghe\n@software: PyCharm\n@file: run.py\n@time: 16-1-7 上午12:12\n\"\"\"\n\n\nfrom app_frontend import app\n\nimport signal\nimport os\n\n\ndef handle_pdb(sig, frame):\n    from remote_pdb import RemotePdb\n    print sig, frame\n    RemotePdb('0.0.0.0', 48110).set_trace()\n\nsignal.signal(signal.SIGUSR1, handle_pdb)\nprint('pid:%s' % os.getpid())\n\n\nif __name__ == '__main__':\n    app.debug = app.config['DEBUG']  # 调试模式, DEBUG = True\n    app.run(host='0.0.0.0', port=8000)  # 端口号必须为整型\n"
  },
  {
    "path": "service_start.md",
    "content": "## Mac\n\n前台运行\n```\nmysql.server start\nrabbitmq-server\nredis-server --dir data/db_redis/ --dbfilename dump.rdb\nmongod --dbpath data/db_mongo\n```\n"
  },
  {
    "path": "ssl/server.crt",
    "content": "-----BEGIN CERTIFICATE-----\nMIICxTCCAi4CCQDRwdlk8oNwHTANBgkqhkiG9w0BAQsFADCBpjELMAkGA1UEBhMC\nQ04xETAPBgNVBAgMCFNoYW5naGFpMREwDwYDVQQHDAhTaGFuZ2hhaTEjMCEGA1UE\nCgwaU2hhbmdoYWkgRmxhc2sgUHJvamVjdCBMdGQxDjAMBgNVBAsMBWZsYXNrMRgw\nFgYDVQQDDA8qLmZsYXNrLWFwcC5jb20xIjAgBgkqhkiG9w0BCQEWE2FkbWluQGZs\nYXNrLWFwcC5jb20wHhcNMTYwNDExMDUxODM3WhcNMTcwNDExMDUxODM3WjCBpjEL\nMAkGA1UEBhMCQ04xETAPBgNVBAgMCFNoYW5naGFpMREwDwYDVQQHDAhTaGFuZ2hh\naTEjMCEGA1UECgwaU2hhbmdoYWkgRmxhc2sgUHJvamVjdCBMdGQxDjAMBgNVBAsM\nBWZsYXNrMRgwFgYDVQQDDA8qLmZsYXNrLWFwcC5jb20xIjAgBgkqhkiG9w0BCQEW\nE2FkbWluQGZsYXNrLWFwcC5jb20wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGB\nANxLtpS+nNRCK/NGfPcfUh0kDejqWILZansIwKlcIHr7XO0MLY21vq+fCqhLEDrY\ndYbINdnWStOkt1bji57rT9ySoKR+CFsFbDUpwkNGEQD4+WwDuYrvA6vleZEyAZi5\nk0QxzR81WO3twJPrtsM33bUa9saotqQE4g0eelipqIQzAgMBAAEwDQYJKoZIhvcN\nAQELBQADgYEAmHAczigUqXT790wwgPzL4RT5t6dVET4zVMC7D5G7IXpNPtMq6W+N\nAKhF8GRlkeVQqN0t2M5U7kU+leoeKtT5b6OvIWWDNouh/6IrJPWg5pprJoot7vf+\n7VLJshBx7RWkMre3rrJtLsihiSr15uLt/dIIqVREBldoisIWxgET0Fs=\n-----END CERTIFICATE-----\n"
  },
  {
    "path": "ssl/server.csr",
    "content": "-----BEGIN CERTIFICATE REQUEST-----\nMIIB5zCCAVACAQAwgaYxCzAJBgNVBAYTAkNOMREwDwYDVQQIDAhTaGFuZ2hhaTER\nMA8GA1UEBwwIU2hhbmdoYWkxIzAhBgNVBAoMGlNoYW5naGFpIEZsYXNrIFByb2pl\nY3QgTHRkMQ4wDAYDVQQLDAVmbGFzazEYMBYGA1UEAwwPKi5mbGFzay1hcHAuY29t\nMSIwIAYJKoZIhvcNAQkBFhNhZG1pbkBmbGFzay1hcHAuY29tMIGfMA0GCSqGSIb3\nDQEBAQUAA4GNADCBiQKBgQDcS7aUvpzUQivzRnz3H1IdJA3o6liC2Wp7CMCpXCB6\n+1ztDC2Ntb6vnwqoSxA62HWGyDXZ1krTpLdW44ue60/ckqCkfghbBWw1KcJDRhEA\n+PlsA7mK7wOr5XmRMgGYuZNEMc0fNVjt7cCT67bDN921GvbGqLakBOINHnpYqaiE\nMwIDAQABoAAwDQYJKoZIhvcNAQELBQADgYEADYkLCTG9oBSEtkVy62hPH0MpGdSw\nMtf8vJkxbcT5EL6gtsKWr5oZF3KWL38WjVUJRpzxJJ2SoW1gG5SsppFNWVK76My1\nAcf8JL254mYbWgoylq9RKGsaRnAKkntbBRqa/rQmwCZAbBuM4dPanCt6B4xdEvqc\nTywUpKVEOQWG6+o=\n-----END CERTIFICATE REQUEST-----\n"
  },
  {
    "path": "ssl/server.key",
    "content": "-----BEGIN RSA PRIVATE KEY-----\nMIICXgIBAAKBgQDcS7aUvpzUQivzRnz3H1IdJA3o6liC2Wp7CMCpXCB6+1ztDC2N\ntb6vnwqoSxA62HWGyDXZ1krTpLdW44ue60/ckqCkfghbBWw1KcJDRhEA+PlsA7mK\n7wOr5XmRMgGYuZNEMc0fNVjt7cCT67bDN921GvbGqLakBOINHnpYqaiEMwIDAQAB\nAoGBANoobJ5vCZY2FZoscvKzZLkRDGldMdwa/RTsfQb7AftoVAU4KyCMHFOFF6PD\n+kWcOP8J5DJewelH1HxKiOkPNRxucvDuOqQxS9WphQYbJUPlN66nZptpSSPHojGp\n1z4BUkV7Q8GD8o4YjPY+iAKuid/ysnU0KCGKFnU+iN8H4bZpAkEA+ayFOiHNqS+x\nL0mWw4JTRB2mfEhKkAkIkV9GLfqzm5+/5EO9kebcvh6auk2gMFlpD6uunITuzkhG\nL6z32ASCbwJBAOHgooxfv4/ScepP58JajV4pJJMd8u3+1aw025yollf+NgbWx9hD\nAWhjsu2gv8K8IQwRnJBIAtbuebE3gH1ybH0CQQDkbWsW3IaFHBVH5lQBW+NClr4T\nRzCwxxMHrdtPhed9opK2DSQLsOSVLPrzKMI+eg8dPz3qBdVW9dkBFYdMJBQRAkEA\nh/aowaiM7ay2Z12L2wCY4doQKwI3Da18vvjeTNFqFjNuH/W/O90xhr2kocdGRpjp\np5MeU/cUxn2sANGw5VIwHQJAcCNUoj8J8JBxXxxCMHFtYZXcvdISPk0Ac2cydsR+\nG2OC7NFJ3DTZbwR17/4AHtzEPqaqLCEw0QIR41gptGzxAA==\n-----END RSA PRIVATE KEY-----\n"
  },
  {
    "path": "ssl/server.key.org",
    "content": "-----BEGIN RSA PRIVATE KEY-----\nProc-Type: 4,ENCRYPTED\nDEK-Info: DES-EDE3-CBC,7F17FE6D71478924\n\nL4PkrL/wFbSx2mD0AsmJOjoaFmTLRI0S1ioobkFZRpSzfdbAKJ+0kKydhXNe2XJQ\njxWmmepsI9DsHqchaYFJcFdFCpmmTd9SoUNJK89BPgLYkY7BW5SxRhoqaiFmMVsw\nbCMfHuC+UmWnypbTEsrwwumcBYoBD1ZR0psr9cGkMMqtFeBloaayk5PFdFWYRszI\nD9eaofc5xT1kHtnAB0IDBh5O6X4/IywW7BHbdD6k7K8u0lgGEjLjQ74XaBfr0h9+\nKzuSIrqz0ZVCKyChsQXjKiM8ng3Ha6rRPGLTwPqbujkxeqfONUYUhJ4OckoL9RTg\nq4uvjTcDnXXwqWqSdoZATB5rvKTbpQmAfJmIhtDFlEy5HRXxRmT0MRt3trBjIoYy\nCTYxy06hkSRaiCqh5o4hO1COElsLQfEhm+dOE62g94Wge0Qei5BGKSlg21Q3/SqM\n8q8YAlGWTYVeNmcgcgPgF7KMjAJAR9kUaxnEX7c0awt2jBQlziCCXHVCC/+GZ9KN\nO4+tQyCvHGrvbw1wfagWUfvULhJRkzLyLBLYw4ATEt5m46twdf86HkU5bhm7DRuo\nGCDasc3JUFnNgDPO8OK0ES+Y1uR0Mx4zhweNzmGqbnUdfOlAYfVXG7Y+Ef+wm+ox\nGT2xiX2nCxmjau4sXF12ElYev9Pfh/q/t1XQ5FUPvO3WapMRrVL5HHlQ+aqa5KfV\nIMezTlc2P0DWgt1t0CwHmwEHe4Sl0Hzh1fhwRp08DWd+c7CPCKwggK3ufXBQFnFw\nzPziY8tuDgYyjWChCfa3dId+MXiZSlgL9KaR1aNK/p7erIJ3+Sff8Q==\n-----END RSA PRIVATE KEY-----\n"
  }
]